summaryrefslogtreecommitdiff
path: root/hw/xnest/Window.c
blob: 14ddac082194acbedb88235bdc123946b4ba158c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
/* $Xorg: Window.c,v 1.3 2000/08/17 19:53:28 cpqbld Exp $ */
/*

Copyright 1993 by Davor Matic

Permission to use, copy, modify, distribute, and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation.  Davor Matic makes no representations about
the suitability of this software for any purpose.  It is provided "as
is" without express or implied warranty.

*/
/* $XFree86: xc/programs/Xserver/hw/xnest/Window.c,v 3.8 2003/11/16 05:05:20 dawes Exp $ */

#include "X.h"
#include "Xproto.h"
#include "gcstruct.h"
#include "window.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "colormapst.h"
#include "scrnintstr.h"
#include "region.h"

#include "mi.h"

#include "Xnest.h"

#include "Display.h"
#include "Screen.h"
#include "XNGC.h"
#include "Drawable.h"
#include "Color.h"
#include "Visual.h"
#include "Events.h"
#include "Args.h"

int xnestWindowPrivateIndex;

static int
xnestFindWindowMatch(WindowPtr pWin, pointer ptr)
{
  xnestWindowMatch *wm = (xnestWindowMatch *)ptr;
  if (wm->window == xnestWindow(pWin)) {
    wm->pWin = pWin;
    return WT_STOPWALKING;
  }
  else
    return WT_WALKCHILDREN;
}

WindowPtr
xnestWindowPtr(Window window)
{
  xnestWindowMatch wm;
  int i;

  wm.pWin = NullWindow;
  wm.window = window;

  for (i = 0; i < xnestNumScreens; i++) {
    WalkTree(screenInfo.screens[i], xnestFindWindowMatch, (pointer) &wm);
    if (wm.pWin) break;
  }
  
  return wm.pWin;
}
    
Bool
xnestCreateWindow(WindowPtr pWin)
{
  unsigned long mask;
  XSetWindowAttributes attributes;
  Visual *visual;
  ColormapPtr pCmap;

  if (pWin->drawable.class == InputOnly) {
    mask = 0L;
    visual = CopyFromParent;
  }
  else {
    mask = CWEventMask | CWBackingStore;
    attributes.event_mask = ExposureMask;
    attributes.backing_store = NotUseful;
    
    if (pWin->parent) {
      if (pWin->optional && pWin->optional->visual != wVisual(pWin->parent)) {
	visual = xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
	mask |= CWColormap;
	if (pWin->optional->colormap) {
	  pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);
	  attributes.colormap = xnestColormap(pCmap);
	}
	else
	  attributes.colormap = xnestDefaultVisualColormap(visual);
      }
      else 
	visual = CopyFromParent;
    }
    else { /* root windows have their own colormaps at creation time */
      visual = xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin));      
      pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);
      mask |= CWColormap;
      attributes.colormap = xnestColormap(pCmap);
    }
  }
  
  xnestWindowPriv(pWin)->window = XCreateWindow(xnestDisplay,
						xnestWindowParent(pWin),
						pWin->origin.x - 
						wBorderWidth(pWin),
						pWin->origin.y - 
						wBorderWidth(pWin),
						pWin->drawable.width,
						pWin->drawable.height,
						pWin->borderWidth,
						pWin->drawable.depth, 
						pWin->drawable.class,
						visual,
						mask, &attributes);
  xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
  xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
  xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
  xnestWindowPriv(pWin)->width = pWin->drawable.width;
  xnestWindowPriv(pWin)->height = pWin->drawable.height;
  xnestWindowPriv(pWin)->border_width = pWin->borderWidth;
  xnestWindowPriv(pWin)->sibling_above = None;
  if (pWin->nextSib)
    xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
#ifdef SHAPE
  xnestWindowPriv(pWin)->bounding_shape = 
    REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
  xnestWindowPriv(pWin)->clip_shape = 
    REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
#endif /* SHAPE */

  if (!pWin->parent) /* only the root window will have the right colormap */
    xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
  
  return True;
}

Bool
xnestDestroyWindow(WindowPtr pWin)
{
  if (pWin->nextSib)
    xnestWindowPriv(pWin->nextSib)->sibling_above = 
      xnestWindowPriv(pWin)->sibling_above;
#ifdef SHAPE
  REGION_DESTROY(pWin->drawable.pScreen, 
				xnestWindowPriv(pWin)->bounding_shape);
  REGION_DESTROY(pWin->drawable.pScreen, 
				xnestWindowPriv(pWin)->clip_shape);
#endif
  XDestroyWindow(xnestDisplay, xnestWindow(pWin));
  xnestWindowPriv(pWin)->window = None;

  if (pWin->optional && pWin->optional->colormap && pWin->parent)
    xnestSetInstalledColormapWindows(pWin->drawable.pScreen);

  return True;
}

Bool
xnestPositionWindow(WindowPtr pWin, int x, int y)
{
  xnestConfigureWindow(pWin, 
		       CWParent |
		       CWX | CWY | 
		       CWWidth | CWHeight | 
		       CWBorderWidth);
  
  return True;
}

void
xnestConfigureWindow(WindowPtr pWin, unsigned int mask)
{
  unsigned int valuemask;
  XWindowChanges values;

  if (mask & CWParent &&
      xnestWindowPriv(pWin)->parent != xnestWindowParent(pWin)) {
    XReparentWindow(xnestDisplay, xnestWindow(pWin), 
		    xnestWindowParent(pWin), 
		    pWin->origin.x - wBorderWidth(pWin),
		    pWin->origin.y - wBorderWidth(pWin));
    xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
    xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
    xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
    xnestWindowPriv(pWin)->sibling_above = None;
    if (pWin->nextSib)
      xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
  }
  
  valuemask = 0;
  
  if (mask & CWX &&
      xnestWindowPriv(pWin)->x != pWin->origin.x - wBorderWidth(pWin)) {
    valuemask |= CWX;
    values.x =
      xnestWindowPriv(pWin)->x = 
	pWin->origin.x - wBorderWidth(pWin);
  }

  if (mask & CWY &&
      xnestWindowPriv(pWin)->y != pWin->origin.y - wBorderWidth(pWin)) {
    valuemask |= CWY;
    values.y =
      xnestWindowPriv(pWin)->y = 
	pWin->origin.y - wBorderWidth(pWin);
  }

  if (mask & CWWidth &&
      xnestWindowPriv(pWin)->width != pWin->drawable.width) {
    valuemask |= CWWidth;
    values.width = 
      xnestWindowPriv(pWin)->width = 
	pWin->drawable.width;
  }
  
  if (mask & CWHeight &&
      xnestWindowPriv(pWin)->height != pWin->drawable.height) {
    valuemask |= CWHeight;
    values.height = 
      xnestWindowPriv(pWin)->height = 
	pWin->drawable.height;
  }
  
  if (mask & CWBorderWidth &&
      xnestWindowPriv(pWin)->border_width != pWin->borderWidth) {
    valuemask |= CWBorderWidth;
    values.border_width = 
      xnestWindowPriv(pWin)->border_width = 
	pWin->borderWidth;
  }
 
  if (valuemask)
    XConfigureWindow(xnestDisplay, xnestWindow(pWin), valuemask, &values);  
  
  if (mask & CWStackingOrder &&
      xnestWindowPriv(pWin)->sibling_above != xnestWindowSiblingAbove(pWin)) {
    WindowPtr pSib;
    
    /* find the top sibling */
    for (pSib = pWin; pSib->prevSib != NullWindow; pSib = pSib->prevSib);
    
    /* the top sibling */
    valuemask = CWStackMode;
    values.stack_mode = Above;
    XConfigureWindow(xnestDisplay, xnestWindow(pSib), valuemask, &values); 
    xnestWindowPriv(pSib)->sibling_above = None;

    /* the rest of siblings */
    for (pSib = pSib->nextSib; pSib != NullWindow; pSib = pSib->nextSib) {
      valuemask = CWSibling | CWStackMode;
      values.sibling = xnestWindowSiblingAbove(pSib);
      values.stack_mode = Below;
      XConfigureWindow(xnestDisplay, xnestWindow(pSib), valuemask, &values);
      xnestWindowPriv(pSib)->sibling_above = xnestWindowSiblingAbove(pSib);
    }
  }
}

Bool
xnestChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
{
  XSetWindowAttributes attributes;
  
  if (mask & CWBackPixmap)
    switch (pWin->backgroundState) {
    case None:
      attributes.background_pixmap = None;
      break;
      
    case ParentRelative:
      attributes.background_pixmap = ParentRelative;
      break;
      
    case BackgroundPixmap:
      attributes.background_pixmap = xnestPixmap(pWin->background.pixmap);
      break;

    case BackgroundPixel:
      mask &= ~CWBackPixmap;  
      break;
    }

  if (mask & CWBackPixel) {
    if (pWin->backgroundState == BackgroundPixel)
      attributes.background_pixel = xnestPixel(pWin->background.pixel);
    else
      mask &= ~CWBackPixel;
  }
  
  if (mask & CWBorderPixmap) {
    if (pWin->borderIsPixel)
      mask &= ~CWBorderPixmap;
    else
      attributes.border_pixmap = xnestPixmap(pWin->border.pixmap);
  }
  
  if (mask & CWBorderPixel) {
    if (pWin->borderIsPixel)
      attributes.border_pixel = xnestPixel(pWin->border.pixel);
    else
      mask &= ~CWBorderPixel;
  }
  
  if (mask & CWBitGravity) 
    attributes.bit_gravity = pWin->bitGravity;
  
  if (mask & CWWinGravity) /* dix does this for us */
    mask &= ~CWWinGravity;

  if (mask & CWBackingStore) /* this is really not useful */
    mask &= ~CWBackingStore;

  if (mask & CWBackingPlanes) /* this is really not useful */
    mask &= ~CWBackingPlanes;

  if (mask & CWBackingPixel) /* this is really not useful */ 
    mask &= ~CWBackingPixel;

  if (mask & CWOverrideRedirect)
    attributes.override_redirect = pWin->overrideRedirect;

  if (mask & CWSaveUnder) /* this is really not useful */
    mask &= ~CWSaveUnder;

  if (mask & CWEventMask) /* events are handled elsewhere */
    mask &= ~CWEventMask;

  if (mask & CWDontPropagate) /* events are handled elsewhere */
    mask &= ~CWDontPropagate; 

  if (mask & CWColormap) {
    ColormapPtr pCmap;
    
    pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);

    attributes.colormap = xnestColormap(pCmap);

    xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
  }

  if (mask & CWCursor) /* this is handeled in cursor code */
    mask &= ~CWCursor;

  if (mask)
    XChangeWindowAttributes(xnestDisplay, xnestWindow(pWin),
			    mask, &attributes);
  
  return True;
}	  

Bool
xnestRealizeWindow(WindowPtr pWin)
{
  xnestConfigureWindow(pWin, CWStackingOrder);
#ifdef SHAPE
  xnestShapeWindow(pWin);
#endif /* SHAPE */
  XMapWindow(xnestDisplay, xnestWindow(pWin));

  return True;
}

Bool
xnestUnrealizeWindow(WindowPtr pWin)
{
  XUnmapWindow(xnestDisplay, xnestWindow(pWin));

  return True;
}

void
xnestPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion, int what)
{
  int i;
  BoxPtr pBox;

  xnestConfigureWindow(pWin, CWWidth | CWHeight);

  pBox = REGION_RECTS(pRegion);
  for (i = 0; i < REGION_NUM_RECTS(pRegion); i++)
    XClearArea(xnestDisplay, xnestWindow(pWin),
	       pBox[i].x1 - pWin->drawable.x,
	       pBox[i].y1 - pWin->drawable.y,
	       pBox[i].x2 - pBox[i].x1, 
	       pBox[i].y2 - pBox[i].y1,
	       False);
}

void
xnestPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what)
{
  xnestConfigureWindow(pWin, CWBorderWidth);
}

void
xnestCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion)
{
}

void
xnestClipNotify(WindowPtr pWin, int dx, int dy)
{
  xnestConfigureWindow(pWin, CWStackingOrder); 
#ifdef SHAPE
  xnestShapeWindow(pWin);
#endif /* SHAPE */
}

static Bool
xnestWindowExposurePredicate(Display *display, XEvent *event, XPointer ptr)
{
  return (event->type == Expose && event->xexpose.window == *(Window *)ptr);
}

void
xnestWindowExposures(WindowPtr pWin, RegionPtr pRgn, RegionPtr other_exposed)
{
  XEvent event;
  Window window;
  BoxRec Box;
  
  XSync(xnestDisplay, False);
  
  window = xnestWindow(pWin);
  
  while (XCheckIfEvent(xnestDisplay, &event, 
		       xnestWindowExposurePredicate, (char *)&window)) {
    
    Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + event.xexpose.x;
    Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + event.xexpose.y;
    Box.x2 = Box.x1 + event.xexpose.width;
    Box.y2 = Box.y1 + event.xexpose.height;
	
    event.xexpose.type = ProcessedExpose;
	
    if (RECT_IN_REGION(pWin->drawable.pScreen, pRgn, &Box) != rgnIN)
      XPutBackEvent(xnestDisplay, &event);
  }
  
  miWindowExposures(pWin, pRgn, other_exposed);
}

#ifdef SHAPE
static Bool
xnestRegionEqual(RegionPtr pReg1, RegionPtr pReg2)
{
  BoxPtr pBox1, pBox2;
  unsigned int n1, n2;

  if (pReg1 == pReg2) return True;

  if (pReg1 == NullRegion || pReg2 == NullRegion) return False;

  pBox1 = REGION_RECTS(pReg1);
  n1 = REGION_NUM_RECTS(pReg1);

  pBox2 = REGION_RECTS(pReg2);
  n2 = REGION_NUM_RECTS(pReg2);

  if (n1 != n2) return False;

  if (pBox1 == pBox2) return True;

  if (memcmp(pBox1, pBox2, n1 * sizeof(BoxRec))) return False;

  return True;
}

void
xnestShapeWindow(WindowPtr pWin)
{
  Region reg;
  BoxPtr pBox;
  XRectangle rect;
  int i;

  if (!xnestRegionEqual(xnestWindowPriv(pWin)->bounding_shape,
			wBoundingShape(pWin))) {
    
    if (wBoundingShape(pWin)) {
      REGION_COPY(pWin->drawable.pScreen, 
		xnestWindowPriv(pWin)->bounding_shape, wBoundingShape(pWin));
      
      reg = XCreateRegion();
      pBox = REGION_RECTS(xnestWindowPriv(pWin)->bounding_shape);
      for (i = 0; 
	   i < REGION_NUM_RECTS(xnestWindowPriv(pWin)->bounding_shape);
	   i++) {
        rect.x = pBox[i].x1;
        rect.y = pBox[i].y1;
        rect.width = pBox[i].x2 - pBox[i].x1;
        rect.height = pBox[i].y2 - pBox[i].y1;
        XUnionRectWithRegion(&rect, reg, reg);
      }
      XShapeCombineRegion(xnestDisplay, xnestWindow(pWin),
			  ShapeBounding, 0, 0, reg, ShapeSet);
      XDestroyRegion(reg);
    }
    else {
      REGION_EMPTY(pWin->drawable.pScreen, 
				xnestWindowPriv(pWin)->bounding_shape);
      
      XShapeCombineMask(xnestDisplay, xnestWindow(pWin),
			ShapeBounding, 0, 0, None, ShapeSet);
    }
  }
  
  if (!xnestRegionEqual(xnestWindowPriv(pWin)->clip_shape,
			wClipShape(pWin))) {
    
    if (wClipShape(pWin)) {
      REGION_COPY(pWin->drawable.pScreen, 
			xnestWindowPriv(pWin)->clip_shape, wClipShape(pWin));
      
      reg = XCreateRegion();
      pBox = REGION_RECTS(xnestWindowPriv(pWin)->clip_shape);
      for (i = 0; 
	   i < REGION_NUM_RECTS(xnestWindowPriv(pWin)->clip_shape);
	   i++) {
        rect.x = pBox[i].x1;
        rect.y = pBox[i].y1;
        rect.width = pBox[i].x2 - pBox[i].x1;
        rect.height = pBox[i].y2 - pBox[i].y1;
        XUnionRectWithRegion(&rect, reg, reg);
      }
      XShapeCombineRegion(xnestDisplay, xnestWindow(pWin),
			  ShapeClip, 0, 0, reg, ShapeSet);
      XDestroyRegion(reg);
    }
    else {
      REGION_EMPTY(pWin->drawable.pScreen, 
				     xnestWindowPriv(pWin)->clip_shape);
      
      XShapeCombineMask(xnestDisplay, xnestWindow(pWin),
			ShapeClip, 0, 0, None, ShapeSet);
    }
  }
}
#endif /* SHAPE */
td> -rw-r--r--Documentation/hwmon/lis3lv02d20
-rw-r--r--Documentation/hwmon/ltc421550
-rw-r--r--Documentation/hwmon/pcf8591 (renamed from Documentation/i2c/chips/pcf8591)0
-rw-r--r--Documentation/hwmon/sysfs-interface22
-rw-r--r--Documentation/hwmon/w83627ehf29
-rw-r--r--Documentation/i2c/busses/i2c-nforce212
-rw-r--r--Documentation/i2c/busses/i2c-piix42
-rw-r--r--Documentation/i2c/instantiating-devices167
-rw-r--r--Documentation/i2c/writing-clients19
-rw-r--r--Documentation/ia64/kvm.txt2
-rw-r--r--Documentation/ioctl/ioctl-number.txt2
-rw-r--r--Documentation/kernel-parameters.txt540
-rw-r--r--Documentation/laptops/acer-wmi.txt10
-rw-r--r--Documentation/laptops/thinkpad-acpi.txt144
-rw-r--r--Documentation/lguest/lguest.c7
-rw-r--r--Documentation/md.txt37
-rw-r--r--Documentation/misc-devices/isl2900362
-rw-r--r--Documentation/networking/dccp.txt3
-rw-r--r--Documentation/networking/ip-sysctl.txt148
-rw-r--r--Documentation/networking/ixgbe.txt199
-rw-r--r--Documentation/networking/rds.txt356
-rw-r--r--Documentation/networking/timestamping.txt180
-rw-r--r--Documentation/networking/timestamping/.gitignore1
-rw-r--r--Documentation/networking/timestamping/Makefile6
-rw-r--r--Documentation/networking/timestamping/timestamping.c533
-rw-r--r--Documentation/networking/vxge.txt100
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt2
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/dma.txt34
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/esdhc.txt24
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/ssi.txt68
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/tsec.txt6
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/upm-nand.txt39
-rw-r--r--Documentation/powerpc/dts-bindings/gpio/led.txt46
-rw-r--r--Documentation/powerpc/dts-bindings/mmc-spi-slot.txt23
-rw-r--r--Documentation/scheduler/00-INDEX2
-rw-r--r--Documentation/scheduler/sched-coding.txt126
-rw-r--r--Documentation/scheduler/sched-rt-group.txt2
-rw-r--r--Documentation/scsi/aacraid.txt15
-rw-r--r--Documentation/scsi/osd.txt198
-rw-r--r--Documentation/slow-work.txt174
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt87
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt21
-rw-r--r--Documentation/sound/alsa/HD-Audio.txt47
-rw-r--r--Documentation/sound/alsa/soc/dapm.txt3
-rw-r--r--Documentation/sound/oss/CS423223
-rw-r--r--Documentation/sound/oss/Introduction2
-rw-r--r--Documentation/sysctl/00-INDEX2
-rw-r--r--Documentation/sysctl/fs.txt74
-rw-r--r--Documentation/sysctl/kernel.txt53
-rw-r--r--Documentation/sysctl/net.txt175
-rw-r--r--Documentation/sysrq.txt5
-rw-r--r--Documentation/tracepoints.txt13
-rw-r--r--Documentation/usb/usbmon.txt27
-rw-r--r--Documentation/video4linux/CARDLIST.bttv6
-rw-r--r--Documentation/video4linux/CARDLIST.cx238854
-rw-r--r--Documentation/video4linux/CARDLIST.cx881
-rw-r--r--Documentation/video4linux/CARDLIST.em28xx9
-rw-r--r--Documentation/video4linux/CARDLIST.saa71342
-rw-r--r--Documentation/video4linux/Zoran3
-rw-r--r--Documentation/video4linux/bttv/Insmod-options10
-rw-r--r--Documentation/video4linux/bttv/README4
-rw-r--r--Documentation/video4linux/cx2341x/README.hm124
-rw-r--r--Documentation/video4linux/gspca.txt4
-rw-r--r--Documentation/video4linux/si470x.txt11
-rw-r--r--Documentation/video4linux/v4l2-framework.txt187
-rw-r--r--Documentation/video4linux/v4lgrab.c4
-rw-r--r--Documentation/video4linux/zr364xx.txt1
-rw-r--r--Documentation/vm/numa_memory_policy.txt3
-rw-r--r--Documentation/vm/page_migration3
-rw-r--r--Documentation/x86/x86_64/fake-numa-for-cpusets5
-rw-r--r--MAINTAINERS175
-rw-r--r--Makefile7
-rw-r--r--arch/Kconfig2
-rw-r--r--arch/alpha/include/asm/machvec.h2
-rw-r--r--arch/alpha/include/asm/pci.h14
-rw-r--r--arch/alpha/include/asm/socket.h3
-rw-r--r--arch/alpha/include/asm/spinlock.h3
-rw-r--r--arch/alpha/include/asm/system.h547
-rw-r--r--arch/alpha/include/asm/types.h5
-rw-r--r--arch/alpha/include/asm/uaccess.h12
-rw-r--r--arch/alpha/include/asm/xchg.h258
-rw-r--r--arch/alpha/kernel/Makefile2
-rw-r--r--arch/alpha/kernel/entry.S3
-rw-r--r--arch/alpha/kernel/err_ev6.c4
-rw-r--r--arch/alpha/kernel/err_ev7.c6
-rw-r--r--arch/alpha/kernel/err_marvel.c40
-rw-r--r--arch/alpha/kernel/err_titan.c28
-rw-r--r--arch/alpha/kernel/irq.c2
-rw-r--r--arch/alpha/kernel/irq_alpha.c2
-rw-r--r--arch/alpha/kernel/osf_sys.c2
-rw-r--r--arch/alpha/kernel/pci-sysfs.c366
-rw-r--r--arch/alpha/kernel/pci.c2
-rw-r--r--arch/alpha/kernel/pci_iommu.c34
-rw-r--r--arch/alpha/kernel/process.c2
-rw-r--r--arch/alpha/kernel/proto.h16
-rw-r--r--arch/alpha/kernel/setup.c2
-rw-r--r--arch/alpha/kernel/smc37c669.c4
-rw-r--r--arch/alpha/kernel/srm_env.c5
-rw-r--r--arch/alpha/kernel/sys_jensen.c3
-rw-r--r--arch/alpha/kernel/sys_sable.c4
-rw-r--r--arch/alpha/kernel/traps.c2
-rw-r--r--arch/arm/Kconfig57
-rw-r--r--arch/arm/Kconfig.debug23
-rw-r--r--arch/arm/Makefile8
-rw-r--r--arch/arm/boot/compressed/head.S44
-rw-r--r--arch/arm/boot/compressed/misc.c20
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.in5
-rw-r--r--arch/arm/common/clkdev.c11
-rw-r--r--arch/arm/common/dmabounce.c7
-rw-r--r--arch/arm/common/scoop.c31
-rw-r--r--arch/arm/common/sharpsl_pm.c2
-rw-r--r--arch/arm/configs/acs5k_defconfig1233
-rw-r--r--arch/arm/configs/acs5k_tiny_defconfig941
-rw-r--r--arch/arm/configs/assabet_defconfig1
-rw-r--r--arch/arm/configs/badge4_defconfig1
-rw-r--r--arch/arm/configs/cerfcube_defconfig1
-rw-r--r--arch/arm/configs/cm_x2xx_defconfig (renamed from arch/arm/configs/xm_x2xx_defconfig)466
-rw-r--r--arch/arm/configs/colibri_pxa270_defconfig (renamed from arch/arm/configs/colibri_defconfig)594
-rw-r--r--arch/arm/configs/colibri_pxa300_defconfig1156
-rw-r--r--arch/arm/configs/collie_defconfig1
-rw-r--r--arch/arm/configs/em_x270_defconfig1741
-rw-r--r--arch/arm/configs/h3600_defconfig2
-rw-r--r--arch/arm/configs/hackkit_defconfig1
-rw-r--r--arch/arm/configs/jornada720_defconfig1
-rw-r--r--arch/arm/configs/kirkwood_defconfig245
-rw-r--r--arch/arm/configs/lart_defconfig1
-rw-r--r--arch/arm/configs/magician_defconfig700
-rw-r--r--arch/arm/configs/mv78xx0_defconfig1
-rw-r--r--arch/arm/configs/neponset_defconfig1
-rw-r--r--arch/arm/configs/omap_3430sdp_defconfig2061
-rw-r--r--arch/arm/configs/omap_ldp_defconfig24
-rw-r--r--arch/arm/configs/orion5x_defconfig4
-rw-r--r--arch/arm/configs/pcm037_defconfig23
-rw-r--r--arch/arm/configs/pleb_defconfig1
-rw-r--r--arch/arm/configs/pxa168_defconfig891
-rw-r--r--arch/arm/configs/pxa910_defconfig891
-rw-r--r--arch/arm/configs/realview-smp_defconfig24
-rw-r--r--arch/arm/configs/realview_defconfig24
-rw-r--r--arch/arm/configs/rx51_defconfig1821
-rw-r--r--arch/arm/configs/shannon_defconfig1
-rw-r--r--arch/arm/configs/shark_defconfig928
-rw-r--r--arch/arm/configs/simpad_defconfig1
-rw-r--r--arch/arm/include/asm/cacheflush.h16
-rw-r--r--arch/arm/include/asm/dma-mapping.h14
-rw-r--r--arch/arm/include/asm/dma.h46
-rw-r--r--arch/arm/include/asm/elf.h2
-rw-r--r--arch/arm/include/asm/fixmap.h41
-rw-r--r--arch/arm/include/asm/hardware/scoop.h2
-rw-r--r--arch/arm/include/asm/highmem.h31
-rw-r--r--arch/arm/include/asm/hwcap.h2
-rw-r--r--arch/arm/include/asm/kmap_types.h1
-rw-r--r--arch/arm/include/asm/mach/dma.h35
-rw-r--r--arch/arm/include/asm/mach/map.h1
-rw-r--r--arch/arm/include/asm/memory.h14
-rw-r--r--arch/arm/include/asm/module.h22
-rw-r--r--arch/arm/include/asm/page.h8
-rw-r--r--arch/arm/include/asm/proc-fns.h16
-rw-r--r--arch/arm/include/asm/ptrace.h2
-rw-r--r--arch/arm/include/asm/sizes.h1
-rw-r--r--arch/arm/include/asm/socket.h3
-rw-r--r--arch/arm/include/asm/spinlock.h3
-rw-r--r--arch/arm/include/asm/stacktrace.h15
-rw-r--r--arch/arm/include/asm/system.h10
-rw-r--r--arch/arm/include/asm/thread_info.h4
-rw-r--r--arch/arm/include/asm/tlbflush.h38
-rw-r--r--arch/arm/include/asm/traps.h1
-rw-r--r--arch/arm/include/asm/unwind.h69
-rw-r--r--arch/arm/include/asm/user.h9
-rw-r--r--arch/arm/kernel/Makefile2
-rw-r--r--arch/arm/kernel/debug.S27
-rw-r--r--arch/arm/kernel/dma-isa.c67
-rw-r--r--arch/arm/kernel/dma.c119
-rw-r--r--arch/arm/kernel/entry-armv.S19
-rw-r--r--arch/arm/kernel/entry-common.S4
-rw-r--r--arch/arm/kernel/irq.c2
-rw-r--r--arch/arm/kernel/module.c73
-rw-r--r--arch/arm/kernel/process.c33
-rw-r--r--arch/arm/kernel/ptrace.c58
-rw-r--r--arch/arm/kernel/setup.c5
-rw-r--r--arch/arm/kernel/smp.c2
-rw-r--r--arch/arm/kernel/stacktrace.c88
-rw-r--r--arch/arm/kernel/stacktrace.h9
-rw-r--r--arch/arm/kernel/time.c21
-rw-r--r--arch/arm/kernel/traps.c44
-rw-r--r--arch/arm/kernel/unwind.c434
-rw-r--r--arch/arm/kernel/vmlinux.lds.S20
-rw-r--r--arch/arm/mach-aaec2000/include/mach/system.h2
-rw-r--r--arch/arm/mach-at91/board-sam9g20ek.c4
-rw-r--r--arch/arm/mach-at91/generic.h3
-rw-r--r--arch/arm/mach-at91/gpio.c222
-rw-r--r--arch/arm/mach-at91/include/mach/gpio.h28
-rw-r--r--arch/arm/mach-at91/include/mach/system.h2
-rw-r--r--arch/arm/mach-at91/pm.c8
-rw-r--r--arch/arm/mach-clps711x/include/mach/system.h2
-rw-r--r--arch/arm/mach-davinci/include/mach/nand.h80
-rw-r--r--arch/arm/mach-davinci/include/mach/system.h2
-rw-r--r--arch/arm/mach-ebsa110/include/mach/system.h2
-rw-r--r--arch/arm/mach-ep93xx/Makefile2
-rw-r--r--arch/arm/mach-ep93xx/clock.c79
-rw-r--r--arch/arm/mach-ep93xx/dma-m2p.c408
-rw-r--r--arch/arm/mach-ep93xx/edb9307a.c12
-rw-r--r--arch/arm/mach-ep93xx/include/mach/dma.h52
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h3
-rw-r--r--arch/arm/mach-ep93xx/include/mach/system.h2
-rw-r--r--arch/arm/mach-footbridge/dma.c12
-rw-r--r--arch/arm/mach-footbridge/include/mach/system.h2
-rw-r--r--arch/arm/mach-gemini/Kconfig19
-rw-r--r--arch/arm/mach-gemini/Makefile10
-rw-r--r--arch/arm/mach-gemini/Makefile.boot9
-rw-r--r--arch/arm/mach-gemini/board-rut1xx.c95
-rw-r--r--arch/arm/mach-gemini/common.h28
-rw-r--r--arch/arm/mach-gemini/devices.c92
-rw-r--r--arch/arm/mach-gemini/gpio.c232
-rw-r--r--arch/arm/mach-gemini/include/mach/debug-macro.S23
-rw-r--r--arch/arm/mach-gemini/include/mach/entry-macro.S39
-rw-r--r--arch/arm/mach-gemini/include/mach/global_reg.h278
-rw-r--r--arch/arm/mach-gemini/include/mach/gpio.h25
-rw-r--r--arch/arm/mach-gemini/include/mach/hardware.h75
-rw-r--r--arch/arm/mach-gemini/include/mach/io.h18
-rw-r--r--arch/arm/mach-gemini/include/mach/irqs.h53
-rw-r--r--arch/arm/mach-gemini/include/mach/memory.h19
-rw-r--r--arch/arm/mach-gemini/include/mach/system.h37
-rw-r--r--arch/arm/mach-gemini/include/mach/timex.h13
-rw-r--r--arch/arm/mach-gemini/include/mach/uncompress.h42
-rw-r--r--arch/arm/mach-gemini/include/mach/vmalloc.h (renamed from drivers/usb/misc/phidget.h)6
-rw-r--r--arch/arm/mach-gemini/irq.c102
-rw-r--r--arch/arm/mach-gemini/mm.c82
-rw-r--r--arch/arm/mach-gemini/time.c89
-rw-r--r--arch/arm/mach-h720x/include/mach/system.h2
-rw-r--r--arch/arm/mach-imx/generic.c36
-rw-r--r--arch/arm/mach-imx/include/mach/system.h2
-rw-r--r--arch/arm/mach-integrator/include/mach/system.h2
-rw-r--r--arch/arm/mach-iop13xx/include/mach/memory.h5
-rw-r--r--arch/arm/mach-iop13xx/include/mach/system.h2
-rw-r--r--arch/arm/mach-iop13xx/pci.c5
-rw-r--r--arch/arm/mach-iop32x/include/mach/system.h2
-rw-r--r--arch/arm/mach-iop33x/include/mach/system.h2
-rw-r--r--arch/arm/mach-ixp2000/include/mach/system.h2
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/system.h2
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c25
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/cpu.h35
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h42
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/system.h2
-rw-r--r--arch/arm/mach-ixp4xx/ixp4xx_npe.c6
-rw-r--r--arch/arm/mach-kirkwood/Kconfig12
-rw-r--r--arch/arm/mach-kirkwood/Makefile4
-rw-r--r--arch/arm/mach-kirkwood/common.c101
-rw-r--r--arch/arm/mach-kirkwood/common.h7
-rw-r--r--arch/arm/mach-kirkwood/db88f6281-bp-setup.c67
-rw-r--r--arch/arm/mach-kirkwood/include/mach/kirkwood.h3
-rw-r--r--arch/arm/mach-kirkwood/include/mach/system.h2
-rw-r--r--arch/arm/mach-kirkwood/mpp.c97
-rw-r--r--arch/arm/mach-kirkwood/mpp.h303
-rw-r--r--arch/arm/mach-kirkwood/rd88f6192-nas-setup.c9
-rw-r--r--arch/arm/mach-kirkwood/rd88f6281-setup.c32
-rw-r--r--arch/arm/mach-kirkwood/sheevaplug-setup.c136
-rw-r--r--arch/arm/mach-kirkwood/ts219-setup.c220
-rw-r--r--arch/arm/mach-ks8695/Kconfig6
-rw-r--r--arch/arm/mach-ks8695/Makefile1
-rw-r--r--arch/arm/mach-ks8695/board-acs5k.c233
-rw-r--r--arch/arm/mach-ks8695/include/mach/memory.h6
-rw-r--r--arch/arm/mach-ks8695/include/mach/system.h2
-rw-r--r--arch/arm/mach-l7200/include/mach/system.h2
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/system.h2
-rw-r--r--arch/arm/mach-loki/include/mach/system.h2
-rw-r--r--arch/arm/mach-mmp/Kconfig47
-rw-r--r--arch/arm/mach-mmp/Makefile15
-rw-r--r--arch/arm/mach-mmp/Makefile.boot1
-rw-r--r--arch/arm/mach-mmp/aspenite.c117
-rw-r--r--arch/arm/mach-mmp/clock.c83
-rw-r--r--arch/arm/mach-mmp/clock.h71
-rw-r--r--arch/arm/mach-mmp/common.c37
-rw-r--r--arch/arm/mach-mmp/common.h13
-rw-r--r--arch/arm/mach-mmp/devices.c69
-rw-r--r--arch/arm/mach-mmp/include/mach/addr-map.h34
-rw-r--r--arch/arm/mach-mmp/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-mmp/include/mach/cputype.h30
-rw-r--r--arch/arm/mach-mmp/include/mach/debug-macro.S23
-rw-r--r--arch/arm/mach-mmp/include/mach/devices.h37
-rw-r--r--arch/arm/mach-mmp/include/mach/dma.h13
-rw-r--r--arch/arm/mach-mmp/include/mach/entry-macro.S25
-rw-r--r--arch/arm/mach-mmp/include/mach/gpio.h36
-rw-r--r--arch/arm/mach-mmp/include/mach/hardware.h4
-rw-r--r--arch/arm/mach-mmp/include/mach/io.h21
-rw-r--r--arch/arm/mach-mmp/include/mach/irqs.h119
-rw-r--r--arch/arm/mach-mmp/include/mach/memory.h14
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-pxa168.h258
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-pxa910.h157
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp.h37
-rw-r--r--arch/arm/mach-mmp/include/mach/pxa168.h23
-rw-r--r--arch/arm/mach-mmp/include/mach/pxa910.h23
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-apbc.h78
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-apmu.h36
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-icu.h31
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-timers.h44
-rw-r--r--arch/arm/mach-mmp/include/mach/system.h21
-rw-r--r--arch/arm/mach-mmp/include/mach/timex.h9
-rw-r--r--arch/arm/mach-mmp/include/mach/uncompress.h41
-rw-r--r--arch/arm/mach-mmp/include/mach/vmalloc.h5
-rw-r--r--arch/arm/mach-mmp/irq.c55
-rw-r--r--arch/arm/mach-mmp/pxa168.c111
-rw-r--r--arch/arm/mach-mmp/pxa910.c158
-rw-r--r--arch/arm/mach-mmp/tavorevb.c109
-rw-r--r--arch/arm/mach-mmp/time.c199
-rw-r--r--arch/arm/mach-mmp/ttc_dkb.c47
-rw-r--r--arch/arm/mach-msm/include/mach/system.h2
-rw-r--r--arch/arm/mach-mv78xx0/Kconfig6
-rw-r--r--arch/arm/mach-mv78xx0/Makefile1
-rw-r--r--arch/arm/mach-mv78xx0/common.c132
-rw-r--r--arch/arm/mach-mv78xx0/common.h3
-rw-r--r--arch/arm/mach-mv78xx0/db78x00-bp-setup.c16
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/mv78xx0.h14
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/system.h2
-rw-r--r--arch/arm/mach-mv78xx0/pcie.c6
-rw-r--r--arch/arm/mach-mv78xx0/rd78x00-masa-setup.c88
-rw-r--r--arch/arm/mach-mx1/Kconfig7
-rw-r--r--arch/arm/mach-mx1/Makefile1
-rw-r--r--arch/arm/mach-mx1/clock.c40
-rw-r--r--arch/arm/mach-mx1/devices.c3
-rw-r--r--arch/arm/mach-mx1/mx1ads.c68
-rw-r--r--arch/arm/mach-mx1/scb9328.c160
-rw-r--r--arch/arm/mach-mx2/Kconfig20
-rw-r--r--arch/arm/mach-mx2/Makefile4
-rw-r--r--arch/arm/mach-mx2/Makefile.boot10
-rw-r--r--arch/arm/mach-mx2/clock_imx21.c984
-rw-r--r--arch/arm/mach-mx2/clock_imx27.c1656
-rw-r--r--arch/arm/mach-mx2/cpu_imx27.c4
-rw-r--r--arch/arm/mach-mx2/crm_regs.h313
-rw-r--r--arch/arm/mach-mx2/devices.c194
-rw-r--r--arch/arm/mach-mx2/devices.h8
-rw-r--r--arch/arm/mach-mx2/generic.c1
-rw-r--r--arch/arm/mach-mx2/mx27ads.c19
-rw-r--r--arch/arm/mach-mx2/pcm038.c82
-rw-r--r--arch/arm/mach-mx2/pcm970-baseboard.c133
-rw-r--r--arch/arm/mach-mx2/serial.c3
-rw-r--r--arch/arm/mach-mx3/Kconfig36
-rw-r--r--arch/arm/mach-mx3/Makefile8
-rw-r--r--arch/arm/mach-mx3/clock-imx35.c487
-rw-r--r--arch/arm/mach-mx3/clock.c959
-rw-r--r--arch/arm/mach-mx3/crm_regs.h153
-rw-r--r--arch/arm/mach-mx3/devices.c193
-rw-r--r--arch/arm/mach-mx3/devices.h8
-rw-r--r--arch/arm/mach-mx3/iomux.c88
-rw-r--r--arch/arm/mach-mx3/mm.c37
-rw-r--r--arch/arm/mach-mx3/mx31ads.c328
-rw-r--r--arch/arm/mach-mx3/mx31lite.c13
-rw-r--r--arch/arm/mach-mx3/mx31moboard-devboard.c48
-rw-r--r--arch/arm/mach-mx3/mx31moboard-marxbot.c37
-rw-r--r--arch/arm/mach-mx3/mx31moboard.c74
-rw-r--r--arch/arm/mach-mx3/mx31pdk.c44
-rw-r--r--arch/arm/mach-mx3/pcm037.c161
-rw-r--r--arch/arm/mach-mx3/qong.c312
-rw-r--r--arch/arm/mach-netx/include/mach/netx-regs.h2
-rw-r--r--arch/arm/mach-netx/include/mach/system.h2
-rw-r--r--arch/arm/mach-ns9xxx/include/mach/system.h2
-rw-r--r--arch/arm/mach-ns9xxx/irq.c3
-rw-r--r--arch/arm/mach-omap1/Kconfig25
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c2
-rw-r--r--arch/arm/mach-omap1/board-fsample.c34
-rw-r--r--arch/arm/mach-omap1/board-generic.c5
-rw-r--r--arch/arm/mach-omap1/board-h2-mmc.c2
-rw-r--r--arch/arm/mach-omap1/board-h2.c7
-rw-r--r--arch/arm/mach-omap1/board-h2.h (renamed from arch/arm/plat-omap/include/mach/board-h2.h)5
-rw-r--r--arch/arm/mach-omap1/board-h3-mmc.c2
-rw-r--r--arch/arm/mach-omap1/board-h3.c7
-rw-r--r--arch/arm/mach-omap1/board-h3.h (renamed from arch/arm/plat-omap/include/mach/board-h3.h)5
-rw-r--r--arch/arm/mach-omap1/board-innovator.c8
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c9
-rw-r--r--arch/arm/mach-omap1/board-osk.c17
-rw-r--r--arch/arm/mach-omap1/board-palmte.c17
-rw-r--r--arch/arm/mach-omap1/board-palmtt.c9
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c12
-rw-r--r--arch/arm/mach-omap1/board-sx1-mmc.c1
-rw-r--r--arch/arm/mach-omap1/board-sx1.c3
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c2
-rw-r--r--arch/arm/mach-omap1/clock.c407
-rw-r--r--arch/arm/mach-omap1/clock.h412
-rw-r--r--arch/arm/mach-omap1/devices.c2
-rw-r--r--arch/arm/mach-omap1/id.c4
-rw-r--r--arch/arm/mach-omap1/io.c23
-rw-r--r--arch/arm/mach-omap1/irq.c19
-rw-r--r--arch/arm/mach-omap1/mailbox.c29
-rw-r--r--arch/arm/mach-omap1/mcbsp.c52
-rw-r--r--arch/arm/mach-omap1/mux.c24
-rw-r--r--arch/arm/mach-omap1/serial.c7
-rw-r--r--arch/arm/mach-omap2/Kconfig10
-rw-r--r--arch/arm/mach-omap2/Makefile16
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c17
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c542
-rw-r--r--arch/arm/mach-omap2/board-apollon.c5
-rw-r--r--arch/arm/mach-omap2/board-generic.c2
-rw-r--r--arch/arm/mach-omap2/board-h4.c40
-rw-r--r--arch/arm/mach-omap2/board-ldp.c59
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c7
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c11
-rw-r--r--arch/arm/mach-omap2/board-overo.c137
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c419
-rw-r--r--arch/arm/mach-omap2/board-rx51.c96
-rw-r--r--arch/arm/mach-omap2/clock.c499
-rw-r--r--arch/arm/mach-omap2/clock.h24
-rw-r--r--arch/arm/mach-omap2/clock24xx.c377
-rw-r--r--arch/arm/mach-omap2/clock24xx.h525
-rw-r--r--arch/arm/mach-omap2/clock34xx.c582
-rw-r--r--arch/arm/mach-omap2/clock34xx.h1076
-rw-r--r--arch/arm/mach-omap2/clockdomain.c76
-rw-r--r--arch/arm/mach-omap2/clockdomains.h118
-rw-r--r--arch/arm/mach-omap2/cm-regbits-24xx.h80
-rw-r--r--arch/arm/mach-omap2/cm-regbits-34xx.h121
-rw-r--r--arch/arm/mach-omap2/devices.c152
-rw-r--r--arch/arm/mach-omap2/id.c7
-rw-r--r--arch/arm/mach-omap2/io.c8
-rw-r--r--arch/arm/mach-omap2/mailbox.c195
-rw-r--r--arch/arm/mach-omap2/mcbsp.c26
-rw-r--r--arch/arm/mach-omap2/memory.h43
-rw-r--r--arch/arm/mach-omap2/mmc-twl4030.c187
-rw-r--r--arch/arm/mach-omap2/mmc-twl4030.h6
-rw-r--r--arch/arm/mach-omap2/mux.c27
-rw-r--r--arch/arm/mach-omap2/pm.c2
-rw-r--r--arch/arm/mach-omap2/powerdomains.h8
-rw-r--r--arch/arm/mach-omap2/powerdomains34xx.h68
-rw-r--r--arch/arm/mach-omap2/prcm-common.h198
-rw-r--r--arch/arm/mach-omap2/prm-regbits-34xx.h9
-rw-r--r--arch/arm/mach-omap2/prm.h24
-rw-r--r--arch/arm/mach-omap2/sdrc.c93
-rw-r--r--arch/arm/mach-omap2/sdrc2xxx.c (renamed from arch/arm/mach-omap2/memory.c)90
-rw-r--r--arch/arm/mach-omap2/usb-musb.c187
-rw-r--r--arch/arm/mach-orion5x/Kconfig1
-rw-r--r--arch/arm/mach-orion5x/common.c34
-rw-r--r--arch/arm/mach-orion5x/dns323-setup.c4
-rw-r--r--arch/arm/mach-orion5x/include/mach/system.h2
-rw-r--r--arch/arm/mach-orion5x/lsmini-setup.c2
-rw-r--r--arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c9
-rw-r--r--arch/arm/mach-orion5x/rd88f5181l-ge-setup.c10
-rw-r--r--arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c10
-rw-r--r--arch/arm/mach-orion5x/ts78xx-fpga.h35
-rw-r--r--arch/arm/mach-orion5x/ts78xx-setup.c444
-rw-r--r--arch/arm/mach-orion5x/wrt350n-v2-setup.c9
-rw-r--r--arch/arm/mach-pnx4008/include/mach/system.h2
-rw-r--r--arch/arm/mach-pxa/Kconfig58
-rw-r--r--arch/arm/mach-pxa/Makefile14
-rw-r--r--arch/arm/mach-pxa/am200epd.c2
-rw-r--r--arch/arm/mach-pxa/am300epd.c295
-rw-r--r--arch/arm/mach-pxa/clock.c4
-rw-r--r--arch/arm/mach-pxa/clock.h2
-rw-r--r--arch/arm/mach-pxa/cm-x255.c4
-rw-r--r--arch/arm/mach-pxa/cm-x270.c2
-rw-r--r--arch/arm/mach-pxa/cm-x2xx-pci.c1
-rw-r--r--arch/arm/mach-pxa/cm-x2xx.c4
-rw-r--r--arch/arm/mach-pxa/cm-x300.c6
-rw-r--r--arch/arm/mach-pxa/colibri-pxa270.c (renamed from arch/arm/mach-pxa/colibri.c)54
-rw-r--r--arch/arm/mach-pxa/colibri-pxa300.c190
-rw-r--r--arch/arm/mach-pxa/colibri-pxa320.c187
-rw-r--r--arch/arm/mach-pxa/colibri-pxa3xx.c121
-rw-r--r--arch/arm/mach-pxa/corgi.c10
-rw-r--r--arch/arm/mach-pxa/corgi_lcd.c1
-rw-r--r--arch/arm/mach-pxa/corgi_pm.c1
-rw-r--r--arch/arm/mach-pxa/corgi_ssp.c1
-rw-r--r--arch/arm/mach-pxa/cpufreq-pxa2xx.c2
-rw-r--r--arch/arm/mach-pxa/cpufreq-pxa3xx.c2
-rw-r--r--arch/arm/mach-pxa/csb701.c61
-rw-r--r--arch/arm/mach-pxa/csb726.c318
-rw-r--r--arch/arm/mach-pxa/devices.c1
-rw-r--r--arch/arm/mach-pxa/e330.c4
-rw-r--r--arch/arm/mach-pxa/e350.c4
-rw-r--r--arch/arm/mach-pxa/e400.c4
-rw-r--r--arch/arm/mach-pxa/e740.c11
-rw-r--r--arch/arm/mach-pxa/e750.c11
-rw-r--r--arch/arm/mach-pxa/e800.c6
-rw-r--r--arch/arm/mach-pxa/em-x270.c607
-rw-r--r--arch/arm/mach-pxa/eseries.c3
-rw-r--r--arch/arm/mach-pxa/ezx.c10
-rw-r--r--arch/arm/mach-pxa/generic.c33
-rw-r--r--arch/arm/mach-pxa/generic.h7
-rw-r--r--arch/arm/mach-pxa/gpio.c453
-rw-r--r--arch/arm/mach-pxa/gumstix.c12
-rw-r--r--arch/arm/mach-pxa/h5000.c14
-rw-r--r--arch/arm/mach-pxa/himalaya.c166
-rw-r--r--arch/arm/mach-pxa/idp.c3
-rw-r--r--arch/arm/mach-pxa/imote2.c5
-rw-r--r--arch/arm/mach-pxa/include/mach/colibri.h32
-rw-r--r--arch/arm/mach-pxa/include/mach/csb726.h26
-rw-r--r--arch/arm/mach-pxa/include/mach/dma.h33
-rw-r--r--arch/arm/mach-pxa/include/mach/eseries-gpio.h15
-rw-r--r--arch/arm/mach-pxa/include/mach/gpio.h126
-rw-r--r--arch/arm/mach-pxa/include/mach/gumstix.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/lubbock.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/magician.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa25x.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa27x.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa300.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa320.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h130
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa930.h1
-rw-r--r--arch/arm/mach-pxa/include/mach/mtd-xip.h4
-rw-r--r--arch/arm/mach-pxa/include/mach/palmld.h109
-rw-r--r--arch/arm/mach-pxa/include/mach/palmt5.h84
-rw-r--r--arch/arm/mach-pxa/include/mach/pm.h10
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa-regs.h263
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa25x.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa27x.h19
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa2xx-regs.h31
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa300.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa320.h9
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx-regs.h11
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx_nand.h3
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa930.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-intc.h23
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-ost.h34
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-rtc.h23
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-ssp.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/system.h3
-rw-r--r--arch/arm/mach-pxa/include/mach/uncompress.h3
-rw-r--r--arch/arm/mach-pxa/irq.c70
-rw-r--r--arch/arm/mach-pxa/leds-idp.c2
-rw-r--r--arch/arm/mach-pxa/leds-lubbock.c2
-rw-r--r--arch/arm/mach-pxa/leds-mainstone.c2
-rw-r--r--arch/arm/mach-pxa/littleton.c3
-rw-r--r--arch/arm/mach-pxa/lpd270.c5
-rw-r--r--arch/arm/mach-pxa/lubbock.c12
-rw-r--r--arch/arm/mach-pxa/magician.c102
-rw-r--r--arch/arm/mach-pxa/mainstone.c5
-rw-r--r--arch/arm/mach-pxa/mfp-pxa2xx.c5
-rw-r--r--arch/arm/mach-pxa/mfp-pxa3xx.c189
-rw-r--r--arch/arm/mach-pxa/mioa701.c53
-rw-r--r--arch/arm/mach-pxa/mp900.c4
-rw-r--r--arch/arm/mach-pxa/palmld.c565
-rw-r--r--arch/arm/mach-pxa/palmt5.c496
-rw-r--r--arch/arm/mach-pxa/palmtx.c3
-rw-r--r--arch/arm/mach-pxa/palmz72.c4
-rw-r--r--arch/arm/mach-pxa/pcm027.c5
-rw-r--r--arch/arm/mach-pxa/pcm990-baseboard.c56
-rw-r--r--arch/arm/mach-pxa/pm.c13
-rw-r--r--arch/arm/mach-pxa/poodle.c10
-rw-r--r--arch/arm/mach-pxa/pwm.c1
-rw-r--r--arch/arm/mach-pxa/pxa25x.c11
-rw-r--r--arch/arm/mach-pxa/pxa27x.c9
-rw-r--r--arch/arm/mach-pxa/pxa2xx.c1
-rw-r--r--arch/arm/mach-pxa/pxa300.c14
-rw-r--r--arch/arm/mach-pxa/pxa320.c11
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c5
-rw-r--r--arch/arm/mach-pxa/pxa930.c9
-rw-r--r--arch/arm/mach-pxa/reset.c4
-rw-r--r--arch/arm/mach-pxa/saar.c6
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c1
-rw-r--r--arch/arm/mach-pxa/sleep.S1
-rw-r--r--arch/arm/mach-pxa/spitz.c14
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c1
-rw-r--r--arch/arm/mach-pxa/ssp.c1
-rw-r--r--arch/arm/mach-pxa/standby.S1
-rw-r--r--arch/arm/mach-pxa/tavorevb.c5
-rw-r--r--arch/arm/mach-pxa/time.c3
-rw-r--r--arch/arm/mach-pxa/tosa.c10
-rw-r--r--arch/arm/mach-pxa/trizeps4.c5
-rw-r--r--arch/arm/mach-pxa/viper.c7
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa300.c4
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa320.c2
-rw-r--r--arch/arm/mach-realview/Kconfig2
-rw-r--r--arch/arm/mach-realview/core.c72
-rw-r--r--arch/arm/mach-realview/core.h2
-rw-r--r--arch/arm/mach-realview/include/mach/board-pba8.h2
-rw-r--r--arch/arm/mach-realview/include/mach/platform.h6
-rw-r--r--arch/arm/mach-realview/include/mach/system.h2
-rw-r--r--arch/arm/mach-realview/localtimer.c1
-rw-r--r--arch/arm/mach-realview/realview_eb.c16
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c15
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c25
-rw-r--r--arch/arm/mach-realview/realview_pba8.c25
-rw-r--r--arch/arm/mach-rpc/dma.c213
-rw-r--r--arch/arm/mach-rpc/include/mach/isa-dma.h2
-rw-r--r--arch/arm/mach-rpc/include/mach/system.h2
-rw-r--r--arch/arm/mach-s3c2410/dma.c2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-nrs.h23
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio.h3
-rw-r--r--arch/arm/mach-s3c2410/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-gpio.h11
-rw-r--r--arch/arm/mach-s3c2410/include/mach/system-reset.h2
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c2
-rw-r--r--arch/arm/mach-s3c2410/pm.c13
-rw-r--r--arch/arm/mach-s3c2410/usb-simtec.c3
-rw-r--r--arch/arm/mach-s3c2412/dma.c4
-rw-r--r--arch/arm/mach-s3c2412/mach-jive.c4
-rw-r--r--arch/arm/mach-s3c2412/pm.c4
-rw-r--r--arch/arm/mach-s3c2440/dma.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c2
-rw-r--r--arch/arm/mach-s3c2443/dma.c2
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-s3c6400/include/mach/map.h3
-rw-r--r--arch/arm/mach-s3c6400/include/mach/system.h2
-rw-r--r--arch/arm/mach-sa1100/Kconfig21
-rw-r--r--arch/arm/mach-sa1100/collie.c30
-rw-r--r--arch/arm/mach-sa1100/collie_pm.c12
-rw-r--r--arch/arm/mach-sa1100/h3600.c486
-rw-r--r--arch/arm/mach-sa1100/include/mach/collie.h12
-rw-r--r--arch/arm/mach-sa1100/include/mach/h3600.h73
-rw-r--r--arch/arm/mach-sa1100/include/mach/h3600_gpio.h463
-rw-r--r--arch/arm/mach-sa1100/include/mach/irqs.h22
-rw-r--r--arch/arm/mach-sa1100/include/mach/system.h2
-rw-r--r--arch/arm/mach-sa1100/jornada720.c14
-rw-r--r--arch/arm/mach-shark/core.c48
-rw-r--r--arch/arm/mach-shark/dma.c6
-rw-r--r--arch/arm/mach-shark/include/mach/debug-macro.S2
-rw-r--r--arch/arm/mach-shark/include/mach/framebuffer.h16
-rw-r--r--arch/arm/mach-shark/include/mach/hardware.h27
-rw-r--r--arch/arm/mach-shark/include/mach/io.h8
-rw-r--r--arch/arm/mach-shark/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-shark/include/mach/isa-dma.h4
-rw-r--r--arch/arm/mach-shark/include/mach/memory.h1
-rw-r--r--arch/arm/mach-shark/include/mach/system.h16
-rw-r--r--arch/arm/mach-shark/include/mach/uncompress.h2
-rw-r--r--arch/arm/mach-shark/leds.c6
-rw-r--r--arch/arm/mach-versatile/core.c16
-rw-r--r--arch/arm/mach-versatile/include/mach/system.h2
-rw-r--r--arch/arm/mach-w90x900/cpu.h39
-rw-r--r--arch/arm/mach-w90x900/include/mach/system.h2
-rw-r--r--arch/arm/mach-w90x900/mach-w90p910evb.c56
-rw-r--r--arch/arm/mach-w90x900/w90p910.c67
-rw-r--r--arch/arm/mm/Kconfig51
-rw-r--r--arch/arm/mm/Makefile6
-rw-r--r--arch/arm/mm/abort-ev6.S4
-rw-r--r--arch/arm/mm/cache-fa.S220
-rw-r--r--arch/arm/mm/cache-feroceon-l2.c59
-rw-r--r--arch/arm/mm/cache-xsc3l2.c107
-rw-r--r--arch/arm/mm/copypage-fa.c86
-rw-r--r--arch/arm/mm/dma-mapping.c72
-rw-r--r--arch/arm/mm/flush.c2
-rw-r--r--arch/arm/mm/highmem.c116
-rw-r--r--arch/arm/mm/init.c21
-rw-r--r--arch/arm/mm/mm.h3
-rw-r--r--arch/arm/mm/mmu.c43
-rw-r--r--arch/arm/mm/proc-fa526.S248
-rw-r--r--arch/arm/mm/proc-mohawk.S416
-rw-r--r--arch/arm/mm/tlb-fa.S75
-rw-r--r--arch/arm/oprofile/backtrace.c14
-rw-r--r--arch/arm/plat-mxc/Kconfig10
-rw-r--r--arch/arm/plat-mxc/Makefile3
-rw-r--r--arch/arm/plat-mxc/clock.c54
-rw-r--r--arch/arm/plat-mxc/cpu.c11
-rw-r--r--arch/arm/plat-mxc/devices.c1
-rw-r--r--arch/arm/plat-mxc/dma-mx1-mx2.c4
-rw-r--r--arch/arm/plat-mxc/gpio.c2
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx27ads.h3
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31ads.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31moboard.h45
-rw-r--r--arch/arm/plat-mxc/include/mach/board-qong.h22
-rw-r--r--arch/arm/plat-mxc/include/mach/clkdev.h7
-rw-r--r--arch/arm/plat-mxc/include/mach/clock.h6
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h10
-rw-r--r--arch/arm/plat-mxc/include/mach/debug-macro.S3
-rw-r--r--arch/arm/plat-mxc/include/mach/hardware.h8
-rw-r--r--arch/arm/plat-mxc/include/mach/imxfb.h (renamed from arch/arm/mach-imx/include/mach/imxfb.h)3
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h416
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx1.h166
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx21.h126
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx27.h207
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx2x.h237
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx3.h74
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux.h127
-rw-r--r--arch/arm/plat-mxc/include/mach/memory.h5
-rw-r--r--arch/arm/plat-mxc/include/mach/mx21.h78
-rw-r--r--arch/arm/plat-mxc/include/mach/mx27.h200
-rw-r--r--arch/arm/plat-mxc/include/mach/mx2x.h200
-rw-r--r--arch/arm/plat-mxc/include/mach/mx31.h329
-rw-r--r--arch/arm/plat-mxc/include/mach/mx35.h29
-rw-r--r--arch/arm/plat-mxc/include/mach/mx3_camera.h52
-rw-r--r--arch/arm/plat-mxc/include/mach/mx3fb.h26
-rw-r--r--arch/arm/plat-mxc/include/mach/mx3x.h290
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc.h74
-rw-r--r--arch/arm/plat-mxc/include/mach/system.h5
-rw-r--r--arch/arm/plat-mxc/iomux-mx1-mx2.c2
-rw-r--r--arch/arm/plat-mxc/pwm.c300
-rw-r--r--arch/arm/plat-mxc/system.c (renamed from arch/arm/mach-mx2/system.c)52
-rw-r--r--arch/arm/plat-mxc/time.c32
-rw-r--r--arch/arm/plat-omap/Kconfig11
-rw-r--r--arch/arm/plat-omap/clock.c198
-rw-r--r--arch/arm/plat-omap/common.c2
-rw-r--r--arch/arm/plat-omap/cpu-omap.c57
-rw-r--r--arch/arm/plat-omap/devices.c3
-rw-r--r--arch/arm/plat-omap/dma.c28
-rw-r--r--arch/arm/plat-omap/dmtimer.c26
-rw-r--r--arch/arm/plat-omap/gpio.c111
-rw-r--r--arch/arm/plat-omap/i2c.c104
-rw-r--r--arch/arm/plat-omap/include/mach/board-2430sdp.h41
-rw-r--r--arch/arm/plat-omap/include/mach/board-apollon.h46
-rw-r--r--arch/arm/plat-omap/include/mach/board-fsample.h51
-rw-r--r--arch/arm/plat-omap/include/mach/board-h4.h38
-rw-r--r--arch/arm/plat-omap/include/mach/board-innovator.h52
-rw-r--r--arch/arm/plat-omap/include/mach/board-ldp.h39
-rw-r--r--arch/arm/plat-omap/include/mach/board-nokia.h54
-rw-r--r--arch/arm/plat-omap/include/mach/board-omap3beagle.h33
-rw-r--r--arch/arm/plat-omap/include/mach/board-osk.h47
-rw-r--r--arch/arm/plat-omap/include/mach/board-overo.h26
-rw-r--r--arch/arm/plat-omap/include/mach/board-palmte.h32
-rw-r--r--arch/arm/plat-omap/include/mach/board-palmtt.h23
-rw-r--r--arch/arm/plat-omap/include/mach/board-palmz71.h26
-rw-r--r--arch/arm/plat-omap/include/mach/board-perseus2.h39
-rw-r--r--arch/arm/plat-omap/include/mach/board-voiceblue.h1
-rw-r--r--arch/arm/plat-omap/include/mach/board.h4
-rw-r--r--arch/arm/plat-omap/include/mach/clkdev.h13
-rw-r--r--arch/arm/plat-omap/include/mach/clock.h80
-rw-r--r--arch/arm/plat-omap/include/mach/clockdomain.h24
-rw-r--r--arch/arm/plat-omap/include/mach/common.h2
-rw-r--r--arch/arm/plat-omap/include/mach/cpu.h61
-rw-r--r--arch/arm/plat-omap/include/mach/gpio.h3
-rw-r--r--arch/arm/plat-omap/include/mach/gpmc.h2
-rw-r--r--arch/arm/plat-omap/include/mach/hardware.h74
-rw-r--r--arch/arm/plat-omap/include/mach/io.h4
-rw-r--r--arch/arm/plat-omap/include/mach/irqs.h83
-rw-r--r--arch/arm/plat-omap/include/mach/mailbox.h27
-rw-r--r--arch/arm/plat-omap/include/mach/mcbsp.h6
-rw-r--r--arch/arm/plat-omap/include/mach/memory.h8
-rw-r--r--arch/arm/plat-omap/include/mach/mmc.h2
-rw-r--r--arch/arm/plat-omap/include/mach/mux.h65
-rw-r--r--arch/arm/plat-omap/include/mach/omap34xx.h28
-rw-r--r--arch/arm/plat-omap/include/mach/omap850.h102
-rw-r--r--arch/arm/plat-omap/include/mach/pm.h12
-rw-r--r--arch/arm/plat-omap/include/mach/powerdomain.h5
-rw-r--r--arch/arm/plat-omap/include/mach/prcm.h5
-rw-r--r--arch/arm/plat-omap/include/mach/sdrc.h64
-rw-r--r--arch/arm/plat-omap/include/mach/system.h8
-rw-r--r--arch/arm/plat-omap/include/mach/usb.h10
-rw-r--r--arch/arm/plat-omap/mailbox.c152
-rw-r--r--arch/arm/plat-omap/mailbox.h100
-rw-r--r--arch/arm/plat-omap/mcbsp.c90
-rw-r--r--arch/arm/plat-omap/sram.c2
-rw-r--r--arch/arm/plat-omap/usb.c25
-rw-r--r--arch/arm/plat-orion/gpio.c29
-rw-r--r--arch/arm/plat-orion/include/plat/gpio.h6
-rw-r--r--arch/arm/plat-orion/include/plat/mvsdio.h21
-rw-r--r--arch/arm/plat-orion/include/plat/orion5x_wdt.h18
-rw-r--r--arch/arm/plat-pxa/Kconfig3
-rw-r--r--arch/arm/plat-pxa/Makefile9
-rw-r--r--arch/arm/plat-pxa/dma.c (renamed from arch/arm/mach-pxa/dma.c)12
-rw-r--r--arch/arm/plat-pxa/gpio.c337
-rw-r--r--arch/arm/plat-pxa/include/plat/dma.h85
-rw-r--r--arch/arm/plat-pxa/include/plat/gpio.h62
-rw-r--r--arch/arm/plat-pxa/include/plat/mfp.h399
-rw-r--r--arch/arm/plat-pxa/mfp.c278
-rw-r--r--arch/arm/plat-s3c/Makefile5
-rw-r--r--arch/arm/plat-s3c/include/plat/audio.h (renamed from arch/arm/mach-s3c2410/include/mach/audio.h)0
-rw-r--r--arch/arm/plat-s3c/include/plat/pm.h174
-rw-r--r--arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h (renamed from include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h)7
-rw-r--r--arch/arm/plat-s3c/include/plat/uncompress.h5
-rw-r--r--arch/arm/plat-s3c/include/plat/usb-control.h (renamed from arch/arm/mach-s3c2410/include/mach/usb-control.h)6
-rw-r--r--arch/arm/plat-s3c/pm-check.c242
-rw-r--r--arch/arm/plat-s3c/pm.c363
-rw-r--r--arch/arm/plat-s3c24xx/Makefile1
-rw-r--r--arch/arm/plat-s3c24xx/common-smdk.c2
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c6
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/irq.h6
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/map.h2
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/pm-core.h59
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/pm.h73
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/regs-iis.h (renamed from include/asm-arm/plat-s3c24xx/regs-iis.h)0
-rw-r--r--arch/arm/plat-s3c24xx/irq-pm.c95
-rw-r--r--arch/arm/plat-s3c24xx/irq.c152
-rw-r--r--arch/arm/plat-s3c24xx/pm-simtec.c2
-rw-r--r--arch/arm/plat-s3c24xx/pm.c503
-rw-r--r--arch/arm/plat-s3c24xx/s3c244x.c4
-rw-r--r--arch/arm/plat-s3c24xx/sleep.S43
-rw-r--r--arch/arm/plat-s3c64xx/cpu.c5
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h25
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/regs-gpio.h186
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/regs-modem.h31
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/regs-sys.h4
-rw-r--r--arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h116
-rw-r--r--arch/arm/plat-s3c64xx/irq-eint.c14
-rw-r--r--arch/arm/tools/mach-types10
-rw-r--r--arch/arm/vfp/entry.S23
-rw-r--r--arch/arm/vfp/vfp.h2
-rw-r--r--arch/arm/vfp/vfphw.S14
-rw-r--r--arch/arm/vfp/vfpmodule.c67
-rw-r--r--arch/avr32/Kconfig20
-rw-r--r--arch/avr32/Makefile1
-rw-r--r--arch/avr32/boards/atngw100/evklcd10x.c50
-rw-r--r--arch/avr32/boards/atngw100/setup.c7
-rw-r--r--arch/avr32/boards/atstk1000/atstk1002.c6
-rw-r--r--arch/avr32/boards/atstk1000/atstk1003.c6
-rw-r--r--arch/avr32/boards/atstk1000/atstk1004.c6
-rw-r--r--arch/avr32/boards/favr-32/setup.c9
-rw-r--r--arch/avr32/boards/hammerhead/flash.c1
-rw-r--r--arch/avr32/boards/hammerhead/setup.c6
-rw-r--r--arch/avr32/boards/merisc/Kconfig5
-rw-r--r--arch/avr32/boards/merisc/Makefile1
-rw-r--r--arch/avr32/boards/merisc/display.c65
-rw-r--r--arch/avr32/boards/merisc/flash.c139
-rw-r--r--arch/avr32/boards/merisc/merisc.h18
-rw-r--r--arch/avr32/boards/merisc/merisc_sysfs.c65
-rw-r--r--arch/avr32/boards/merisc/setup.c297
-rw-r--r--arch/avr32/boards/mimc200/setup.c8
-rw-r--r--arch/avr32/configs/merisc_defconfig1237
-rw-r--r--arch/avr32/include/asm/socket.h3
-rw-r--r--arch/avr32/include/asm/uaccess.h8
-rw-r--r--arch/avr32/kernel/entry-avr32b.S60
-rw-r--r--arch/avr32/kernel/irq.c2
-rw-r--r--arch/avr32/kernel/process.c2
-rw-r--r--arch/avr32/kernel/syscall-stubs.S14
-rw-r--r--arch/avr32/lib/strnlen_user.S2
-rw-r--r--arch/avr32/mach-at32ap/at32ap700x.c112
-rw-r--r--arch/avr32/mach-at32ap/include/mach/at32ap700x.h52
-rw-r--r--arch/avr32/mach-at32ap/include/mach/board.h24
-rw-r--r--arch/avr32/mm/fault.c18
-rw-r--r--arch/blackfin/Kconfig6
-rw-r--r--arch/blackfin/configs/BF518F-EZBRD_defconfig42
-rw-r--r--arch/blackfin/configs/BF526-EZBRD_defconfig140
-rw-r--r--arch/blackfin/configs/BF527-EZKIT_defconfig150
-rw-r--r--arch/blackfin/configs/BF533-EZKIT_defconfig54
-rw-r--r--arch/blackfin/configs/BF533-STAMP_defconfig100
-rw-r--r--arch/blackfin/configs/BF537-STAMP_defconfig97
-rw-r--r--arch/blackfin/configs/BF538-EZKIT_defconfig101
-rw-r--r--arch/blackfin/configs/BF548-EZKIT_defconfig163
-rw-r--r--arch/blackfin/configs/BF561-EZKIT_defconfig54
-rw-r--r--arch/blackfin/configs/BlackStamp_defconfig4
-rw-r--r--arch/blackfin/configs/CM-BF527_defconfig6
-rw-r--r--arch/blackfin/configs/CM-BF533_defconfig4
-rw-r--r--arch/blackfin/configs/CM-BF537E_defconfig4
-rw-r--r--arch/blackfin/configs/CM-BF537U_defconfig4
-rw-r--r--arch/blackfin/configs/CM-BF548_defconfig4
-rw-r--r--arch/blackfin/configs/CM-BF561_defconfig4
-rw-r--r--arch/blackfin/configs/H8606_defconfig4
-rw-r--r--arch/blackfin/configs/IP0X_defconfig4
-rw-r--r--arch/blackfin/configs/PNAV-10_defconfig39
-rw-r--r--arch/blackfin/configs/SRV1_defconfig4
-rw-r--r--arch/blackfin/configs/TCM-BF537_defconfig6
-rw-r--r--arch/blackfin/include/asm/bfin5xx_spi.h2
-rw-r--r--arch/blackfin/include/asm/bfin_sport.h9
-rw-r--r--arch/blackfin/include/asm/gpio.h7
-rw-r--r--arch/blackfin/include/asm/gptimers.h6
-rw-r--r--arch/blackfin/include/asm/socket.h3
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c78
-rw-r--r--arch/blackfin/kernel/irqchip.c2
-rw-r--r--arch/blackfin/kernel/process.c4
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S4
-rw-r--r--arch/blackfin/mach-bf518/include/mach/blackfin.h2
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF514.h67
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF516.h67
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF514.h135
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF516.h135
-rw-r--r--arch/blackfin/mach-bf527/include/mach/blackfin.h2
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c235
-rw-r--r--arch/blackfin/mach-bf548/include/mach/blackfin.h2
-rw-r--r--arch/blackfin/mach-common/pm.c2
-rw-r--r--arch/blackfin/mm/sram-alloc.c1
-rw-r--r--arch/cris/Kconfig6
-rw-r--r--arch/cris/arch-v10/kernel/irq.c2
-rw-r--r--arch/cris/arch-v10/kernel/process.c2
-rw-r--r--arch/cris/arch-v10/kernel/time.c1
-rw-r--r--arch/cris/arch-v32/Kconfig2
-rw-r--r--arch/cris/arch-v32/boot/compressed/Makefile6
-rw-r--r--arch/cris/arch-v32/drivers/Kconfig2
-rw-r--r--arch/cris/arch-v32/kernel/irq.c2
-rw-r--r--arch/cris/arch-v32/kernel/process.c2
-rw-r--r--arch/cris/arch-v32/kernel/smp.c11
-rw-r--r--arch/cris/arch-v32/kernel/time.c1
-rw-r--r--arch/cris/arch-v32/mach-fs/Kconfig2
-rw-r--r--arch/cris/arch-v32/mm/tlb.c2
-rw-r--r--arch/cris/include/arch-v32/arch/spinlock.h2
-rw-r--r--arch/cris/include/asm/socket.h3
-rw-r--r--arch/cris/kernel/irq.c2
-rw-r--r--arch/cris/kernel/process.c1
-rw-r--r--arch/cris/kernel/setup.c2
-rw-r--r--arch/cris/mm/init.c3
-rw-r--r--arch/frv/kernel/irq-mb93091.c4
-rw-r--r--arch/frv/kernel/irq-mb93093.c1
-rw-r--r--arch/frv/kernel/irq-mb93493.c2
-rw-r--r--arch/frv/kernel/irq.c2
-rw-r--r--arch/frv/kernel/process.c2
-rw-r--r--arch/frv/kernel/time.c1
-rw-r--r--arch/frv/mm/tlb-miss.S1
-rw-r--r--arch/h8300/include/asm/socket.h3
-rw-r--r--arch/h8300/kernel/irq.c4
-rw-r--r--arch/h8300/kernel/process.c2
-rw-r--r--arch/h8300/kernel/timer/itu.c1
-rw-r--r--arch/h8300/kernel/timer/timer16.c1
-rw-r--r--arch/h8300/kernel/timer/timer8.c1
-rw-r--r--arch/h8300/kernel/timer/tpu.c3
-rw-r--r--arch/ia64/configs/generic_defconfig3
-rw-r--r--arch/ia64/dig/Makefile4
-rw-r--r--arch/ia64/dig/dig_vtd_iommu.c59
-rw-r--r--arch/ia64/hp/common/hwsw_iommu.c165
-rw-r--r--arch/ia64/hp/common/sba_iommu.c79
-rw-r--r--arch/ia64/hp/sim/simserial.c49
-rw-r--r--arch/ia64/ia32/ia32_entry.S2
-rw-r--r--arch/ia64/include/asm/dma-mapping.h194
-rw-r--r--arch/ia64/include/asm/intrinsics.h6
-rw-r--r--arch/ia64/include/asm/kvm.h49
-rw-r--r--arch/ia64/include/asm/kvm_host.h18
-rw-r--r--arch/ia64/include/asm/machvec.h102
-rw-r--r--arch/ia64/include/asm/machvec_dig_vtd.h20
-rw-r--r--arch/ia64/include/asm/machvec_hpzx1.h23
-rw-r--r--arch/ia64/include/asm/machvec_hpzx1_swiotlb.h27
-rw-r--r--arch/ia64/include/asm/machvec_sn2.h27
-rw-r--r--arch/ia64/include/asm/mmu_context.h6
-rw-r--r--arch/ia64/include/asm/module.h6
-rw-r--r--arch/ia64/include/asm/msidef.h42
-rw-r--r--arch/ia64/include/asm/native/inst.h13
-rw-r--r--arch/ia64/include/asm/native/patchlist.h38
-rw-r--r--arch/ia64/include/asm/native/pvchk_inst.h8
-rw-r--r--arch/ia64/include/asm/paravirt.h65
-rw-r--r--arch/ia64/include/asm/paravirt_patch.h143
-rw-r--r--arch/ia64/include/asm/paravirt_privop.h365
-rw-r--r--arch/ia64/include/asm/smp.h3
-rw-r--r--arch/ia64/include/asm/socket.h3
-rw-r--r--arch/ia64/include/asm/spinlock.h77
-rw-r--r--arch/ia64/include/asm/timex.h1
-rw-r--r--arch/ia64/include/asm/topology.h10
-rw-r--r--arch/ia64/include/asm/uv/uv_hub.h6
-rw-r--r--arch/ia64/include/asm/uv/uv_mmrs.h158
-rw-r--r--arch/ia64/include/asm/xen/hypervisor.h39
-rw-r--r--arch/ia64/include/asm/xen/inst.h28
-rw-r--r--arch/ia64/include/asm/xen/interface.h9
-rw-r--r--arch/ia64/include/asm/xen/minstate.h11
-rw-r--r--arch/ia64/include/asm/xen/patchlist.h38
-rw-r--r--arch/ia64/include/asm/xen/privop.h8
-rw-r--r--arch/ia64/kernel/Makefile43
-rw-r--r--arch/ia64/kernel/Makefile.gate27
-rw-r--r--arch/ia64/kernel/acpi.c8
-rw-r--r--arch/ia64/kernel/asm-offsets.c2
-rw-r--r--arch/ia64/kernel/dma-mapping.c13
-rw-r--r--arch/ia64/kernel/efi.c1
-rw-r--r--arch/ia64/kernel/entry.S4
-rw-r--r--arch/ia64/kernel/fsys.S35
-rw-r--r--arch/ia64/kernel/gate.S171
-rw-r--r--arch/ia64/kernel/gate.lds.S17
-rw-r--r--arch/ia64/kernel/head.S10
-rw-r--r--arch/ia64/kernel/irq.c2
-rw-r--r--arch/ia64/kernel/irq_ia64.c31
-rw-r--r--arch/ia64/kernel/ivt.S2
-rw-r--r--arch/ia64/kernel/machvec.c8
-rw-r--r--arch/ia64/kernel/mca.c6
-rw-r--r--arch/ia64/kernel/module.c35
-rw-r--r--arch/ia64/kernel/msi_ia64.c55
-rw-r--r--arch/ia64/kernel/palinfo.c2
-rw-r--r--arch/ia64/kernel/paravirt.c539
-rw-r--r--arch/ia64/kernel/paravirt_patch.c514
-rw-r--r--arch/ia64/kernel/paravirt_patchlist.c79
-rw-r--r--arch/ia64/kernel/paravirt_patchlist.h28
-rw-r--r--arch/ia64/kernel/paravirtentry.S99
-rw-r--r--arch/ia64/kernel/patch.c40
-rw-r--r--arch/ia64/kernel/pci-dma.c46
-rw-r--r--arch/ia64/kernel/pci-swiotlb.c30
-rw-r--r--arch/ia64/kernel/perfmon.c6
-rw-r--r--arch/ia64/kernel/process.c2
-rw-r--r--arch/ia64/kernel/salinfo.c6
-rw-r--r--arch/ia64/kernel/setup.c9
-rw-r--r--arch/ia64/kernel/smp.c6
-rw-r--r--arch/ia64/kernel/smpboot.c17
-rw-r--r--arch/ia64/kernel/time.c25
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S42
-rw-r--r--arch/ia64/kvm/Kconfig4
-rw-r--r--arch/ia64/kvm/irq.h2
-rw-r--r--arch/ia64/kvm/kvm-ia64.c127
-rw-r--r--arch/ia64/kvm/kvm_fw.c151
-rw-r--r--arch/ia64/kvm/process.c71
-rw-r--r--arch/ia64/kvm/vcpu.c46
-rw-r--r--arch/ia64/kvm/vcpu.h4
-rw-r--r--arch/ia64/kvm/vtlb.c46
-rw-r--r--arch/ia64/mm/init.c12
-rw-r--r--arch/ia64/mm/tlb.c2
-rw-r--r--arch/ia64/scripts/pvcheck.sed1
-rw-r--r--arch/ia64/sn/kernel/io_common.c15
-rw-r--r--arch/ia64/sn/kernel/io_init.c12
-rw-r--r--arch/ia64/sn/kernel/setup.c5
-rw-r--r--arch/ia64/sn/kernel/sn2/prominfo_proc.c9
-rw-r--r--arch/ia64/sn/kernel/sn2/sn2_smp.c12
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c8
-rw-r--r--arch/ia64/sn/pci/pci_dma.c99
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_dma.c4
-rw-r--r--arch/ia64/xen/Makefile19
-rw-r--r--arch/ia64/xen/gate-data.S3
-rw-r--r--arch/ia64/xen/hypercall.S2
-rw-r--r--arch/ia64/xen/time.c48
-rw-r--r--arch/ia64/xen/xen_pv_ops.c800
-rw-r--r--arch/m32r/kernel/irq.c2
-rw-r--r--arch/m32r/kernel/process.c2
-rw-r--r--arch/m32r/kernel/time.c1
-rw-r--r--arch/m68k/Makefile3
-rw-r--r--arch/m68k/include/asm/bootinfo.h381
-rw-r--r--arch/m68k/include/asm/bootinfo_mm.h378
-rw-r--r--arch/m68k/include/asm/bootinfo_no.h2
-rw-r--r--arch/m68k/include/asm/bug.h31
-rw-r--r--arch/m68k/include/asm/bug_mm.h29
-rw-r--r--arch/m68k/include/asm/bug_no.h4
-rw-r--r--arch/m68k/include/asm/bugs.h21
-rw-r--r--arch/m68k/include/asm/bugs_mm.h14
-rw-r--r--arch/m68k/include/asm/bugs_no.h16
-rw-r--r--arch/m68k/include/asm/cache.h14
-rw-r--r--arch/m68k/include/asm/cache_mm.h11
-rw-r--r--arch/m68k/include/asm/cache_no.h12
-rw-r--r--arch/m68k/include/asm/current.h31
-rw-r--r--arch/m68k/include/asm/current_mm.h6
-rw-r--r--arch/m68k/include/asm/current_no.h24
-rw-r--r--arch/m68k/include/asm/div64.h37
-rw-r--r--arch/m68k/include/asm/div64_mm.h28
-rw-r--r--arch/m68k/include/asm/div64_no.h1
-rw-r--r--arch/m68k/include/asm/dma-mapping.h113
-rw-r--r--arch/m68k/include/asm/dma-mapping_mm.h112
-rw-r--r--arch/m68k/include/asm/dma-mapping_no.h6
-rw-r--r--arch/m68k/include/asm/elf.h120
-rw-r--r--arch/m68k/include/asm/elf_mm.h119
-rw-r--r--arch/m68k/include/asm/elf_no.h110
-rw-r--r--arch/m68k/include/asm/fb.h41
-rw-r--r--arch/m68k/include/asm/fb_mm.h34
-rw-r--r--arch/m68k/include/asm/fb_no.h12
-rw-r--r--arch/m68k/include/asm/fpu.h22
-rw-r--r--arch/m68k/include/asm/fpu_mm.h21
-rw-r--r--arch/m68k/include/asm/fpu_no.h21
-rw-r--r--arch/m68k/include/asm/hw_irq.h9
-rw-r--r--arch/m68k/include/asm/hw_irq_mm.h6
-rw-r--r--arch/m68k/include/asm/hw_irq_no.h4
-rw-r--r--arch/m68k/include/asm/ide.h73
-rw-r--r--arch/m68k/include/asm/irq_mm.h3
-rw-r--r--arch/m68k/include/asm/kmap_types.h26
-rw-r--r--arch/m68k/include/asm/kmap_types_mm.h21
-rw-r--r--arch/m68k/include/asm/kmap_types_no.h21
-rw-r--r--arch/m68k/include/asm/m532xsim.h1
-rw-r--r--arch/m68k/include/asm/macintosh.h7
-rw-r--r--arch/m68k/include/asm/mc146818rtc.h31
-rw-r--r--arch/m68k/include/asm/mc146818rtc_mm.h26
-rw-r--r--arch/m68k/include/asm/mc146818rtc_no.h9
-rw-r--r--arch/m68k/include/asm/mcfpci.h119
-rw-r--r--arch/m68k/include/asm/mmu.h14
-rw-r--r--arch/m68k/include/asm/mmu_context.h176
-rw-r--r--arch/m68k/include/asm/mmu_context_mm.h154
-rw-r--r--arch/m68k/include/asm/mmu_context_no.h33
-rw-r--r--arch/m68k/include/asm/mmu_mm.h7
-rw-r--r--arch/m68k/include/asm/mmu_no.h10
-rw-r--r--arch/m68k/include/asm/module.h51
-rw-r--r--arch/m68k/include/asm/module_mm.h39
-rw-r--r--arch/m68k/include/asm/module_no.h11
-rw-r--r--arch/m68k/include/asm/page_offset.h12
-rw-r--r--arch/m68k/include/asm/page_offset_mm.h8
-rw-r--r--arch/m68k/include/asm/page_offset_no.h5
-rw-r--r--arch/m68k/include/asm/param.h25
-rw-r--r--arch/m68k/include/asm/param_mm.h22
-rw-r--r--arch/m68k/include/asm/param_no.h22
-rw-r--r--arch/m68k/include/asm/pci.h17
-rw-r--r--arch/m68k/include/asm/pci_mm.h12
-rw-r--r--arch/m68k/include/asm/pci_no.h29
-rw-r--r--arch/m68k/include/asm/pgalloc.h20
-rw-r--r--arch/m68k/include/asm/pgalloc_mm.h19
-rw-r--r--arch/m68k/include/asm/pgalloc_no.h8
-rw-r--r--arch/m68k/include/asm/pgtable_no.h2
-rw-r--r--arch/m68k/include/asm/ptrace.h88
-rw-r--r--arch/m68k/include/asm/ptrace_mm.h80
-rw-r--r--arch/m68k/include/asm/ptrace_no.h87
-rw-r--r--arch/m68k/include/asm/rtc.h7
-rw-r--r--arch/m68k/include/asm/scatterlist.h26
-rw-r--r--arch/m68k/include/asm/scatterlist_mm.h23
-rw-r--r--arch/m68k/include/asm/scatterlist_no.h22
-rw-r--r--arch/m68k/include/asm/segment.h64
-rw-r--r--arch/m68k/include/asm/segment_mm.h57
-rw-r--r--arch/m68k/include/asm/segment_no.h51
-rw-r--r--arch/m68k/include/asm/setup.h377
-rw-r--r--arch/m68k/include/asm/setup_mm.h376
-rw-r--r--arch/m68k/include/asm/setup_no.h10
-rw-r--r--arch/m68k/include/asm/sigcontext.h25
-rw-r--r--arch/m68k/include/asm/sigcontext_mm.h19
-rw-r--r--arch/m68k/include/asm/sigcontext_no.h17
-rw-r--r--arch/m68k/include/asm/siginfo.h98
-rw-r--r--arch/m68k/include/asm/siginfo_mm.h92
-rw-r--r--arch/m68k/include/asm/siginfo_no.h6
-rw-r--r--arch/m68k/include/asm/signal.h216
-rw-r--r--arch/m68k/include/asm/signal_mm.h206
-rw-r--r--arch/m68k/include/asm/signal_no.h159
-rw-r--r--arch/m68k/include/asm/socket.h3
-rw-r--r--arch/m68k/include/asm/swab.h30
-rw-r--r--arch/m68k/include/asm/swab_mm.h16
-rw-r--r--arch/m68k/include/asm/swab_no.h24
-rw-r--r--arch/m68k/include/asm/timex.h21
-rw-r--r--arch/m68k/include/asm/timex_mm.h18
-rw-r--r--arch/m68k/include/asm/timex_no.h23
-rw-r--r--arch/m68k/include/asm/tlbflush.h268
-rw-r--r--arch/m68k/include/asm/tlbflush_mm.h219
-rw-r--r--arch/m68k/include/asm/tlbflush_no.h55
-rw-r--r--arch/m68k/include/asm/ucontext.h33
-rw-r--r--arch/m68k/include/asm/ucontext_mm.h30
-rw-r--r--arch/m68k/include/asm/ucontext_no.h32
-rw-r--r--arch/m68k/include/asm/unaligned.h26
-rw-r--r--arch/m68k/include/asm/unaligned_mm.h13
-rw-r--r--arch/m68k/include/asm/unaligned_no.h25
-rw-r--r--arch/m68k/include/asm/unistd.h377
-rw-r--r--arch/m68k/include/asm/unistd_mm.h372
-rw-r--r--arch/m68k/include/asm/unistd_no.h372
-rw-r--r--arch/m68k/install.sh52
-rw-r--r--arch/m68k/kernel/process.c2
-rw-r--r--arch/m68k/kernel/time.c18
-rw-r--r--arch/m68k/mac/config.c207
-rw-r--r--arch/m68k/mac/via.c9
-rw-r--r--arch/m68knommu/Makefile14
-rw-r--r--arch/m68knommu/kernel/dma.c8
-rw-r--r--arch/m68knommu/kernel/irq.c2
-rw-r--r--arch/m68knommu/kernel/process.c2
-rw-r--r--arch/m68knommu/mm/init.c6
-rw-r--r--arch/m68knommu/platform/520x/config.c56
-rw-r--r--arch/m68knommu/platform/523x/config.c51
-rw-r--r--arch/m68knommu/platform/5249/config.c11
-rw-r--r--arch/m68knommu/platform/5272/config.c48
-rw-r--r--arch/m68knommu/platform/527x/config.c113
-rw-r--r--arch/m68knommu/platform/528x/config.c58
-rw-r--r--arch/m68knommu/platform/5307/config.c8
-rw-r--r--arch/m68knommu/platform/532x/config.c49
-rw-r--r--arch/m68knommu/platform/5407/config.c8
-rw-r--r--arch/m68knommu/platform/coldfire/Makefile2
-rw-r--r--arch/m68knommu/platform/coldfire/clk.c40
-rw-r--r--arch/mips/Kconfig14
-rw-r--r--arch/mips/Makefile6
-rw-r--r--arch/mips/alchemy/Kconfig2
-rw-r--r--arch/mips/alchemy/common/gpio.c203
-rw-r--r--arch/mips/alchemy/devboards/pb1200/platform.c10
-rw-r--r--arch/mips/basler/excite/excite_iodev.c27
-rw-r--r--arch/mips/cavium-octeon/Makefile2
-rw-r--r--arch/mips/cavium-octeon/flash_setup.c2
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c2
-rw-r--r--arch/mips/cobalt/irq.c1
-rw-r--r--arch/mips/emma/markeins/irq.c51
-rw-r--r--arch/mips/emma/markeins/platform.c3
-rw-r--r--arch/mips/include/asm/cpu.h3
-rw-r--r--arch/mips/include/asm/hazards.h4
-rw-r--r--arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h49
-rw-r--r--arch/mips/include/asm/mach-au1x00/gpio.h70
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/gpio.h20
-rw-r--r--arch/mips/include/asm/mach-ip27/topology.h1
-rw-r--r--arch/mips/include/asm/mips-boards/generic.h2
-rw-r--r--arch/mips/include/asm/mipsregs.h22
-rw-r--r--arch/mips/include/asm/smp-ops.h2
-rw-r--r--arch/mips/include/asm/socket.h3
-rw-r--r--arch/mips/include/asm/spinlock.h10
-rw-r--r--arch/mips/include/asm/txx9/ndfmc.h30
-rw-r--r--arch/mips/include/asm/txx9/rbtx4939.h9
-rw-r--r--arch/mips/include/asm/txx9/tx4938.h1
-rw-r--r--arch/mips/include/asm/txx9/tx4939.h2
-rw-r--r--arch/mips/include/asm/types.h8
-rw-r--r--arch/mips/include/asm/unistd.h18
-rw-r--r--arch/mips/jazz/irq.c1
-rw-r--r--arch/mips/jazz/jazzdma.c3
-rw-r--r--arch/mips/kernel/cevt-bcm1480.c1
-rw-r--r--arch/mips/kernel/cevt-sb1250.c1
-rw-r--r--arch/mips/kernel/cpu-probe.c21
-rw-r--r--arch/mips/kernel/i8253.c2
-rw-r--r--arch/mips/kernel/i8259.c1
-rw-r--r--arch/mips/kernel/irq-msc01.c6
-rw-r--r--arch/mips/kernel/irq.c2
-rw-r--r--arch/mips/kernel/irq_cpu.c3
-rw-r--r--arch/mips/kernel/linux32.c41
-rw-r--r--arch/mips/kernel/process.c2
-rw-r--r--arch/mips/kernel/scall32-o32.S2
-rw-r--r--arch/mips/kernel/scall64-64.S2
-rw-r--r--arch/mips/kernel/scall64-n32.S4
-rw-r--r--arch/mips/kernel/scall64-o32.S4
-rw-r--r--arch/mips/kernel/setup.c3
-rw-r--r--arch/mips/kernel/smp-up.c14
-rw-r--r--arch/mips/kernel/smp.c2
-rw-r--r--arch/mips/kernel/traps.c15
-rw-r--r--arch/mips/lasat/interrupt.c1
-rw-r--r--arch/mips/lemote/lm2e/irq.c1
-rw-r--r--arch/mips/mm/c-r4k.c19
-rw-r--r--arch/mips/mm/dma-default.c2
-rw-r--r--arch/mips/mm/highmem.c11
-rw-r--r--arch/mips/mm/init.c3
-rw-r--r--arch/mips/mm/ioremap.c9
-rw-r--r--arch/mips/mm/tlbex.c8
-rw-r--r--arch/mips/mti-malta/malta-init.c2
-rw-r--r--arch/mips/sgi-ip27/ip27-berr.c2
-rw-r--r--arch/mips/sgi-ip27/ip27-nmi.c6
-rw-r--r--arch/mips/sgi-ip27/ip27-smp.c2
-rw-r--r--arch/mips/sgi-ip32/ip32-irq.c65
-rw-r--r--arch/mips/sgi-ip32/ip32-memory.c2
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c2
-rw-r--r--arch/mips/sibyte/sb1250/irq.c2
-rw-r--r--arch/mips/sni/a20r.c2
-rw-r--r--arch/mips/sni/pcimt.c2
-rw-r--r--arch/mips/sni/pcit.c4
-rw-r--r--arch/mips/sni/rm200.c5
-rw-r--r--arch/mips/txx9/Kconfig1
-rw-r--r--arch/mips/txx9/generic/setup.c21
-rw-r--r--arch/mips/txx9/generic/setup_tx4938.c21
-rw-r--r--arch/mips/txx9/generic/setup_tx4939.c17
-rw-r--r--arch/mips/txx9/rbtx4938/setup.c2
-rw-r--r--arch/mips/txx9/rbtx4939/setup.c161
-rw-r--r--arch/mips/vr41xx/common/irq.c1
-rw-r--r--arch/mn10300/kernel/irq.c2
-rw-r--r--arch/mn10300/kernel/process.c2
-rw-r--r--arch/mn10300/kernel/time.c1
-rw-r--r--arch/parisc/Kconfig12
-rw-r--r--arch/parisc/Makefile4
-rw-r--r--arch/parisc/include/asm/atomic.h18
-rw-r--r--arch/parisc/include/asm/cacheflush.h3
-rw-r--r--arch/parisc/include/asm/elf.h10
-rw-r--r--arch/parisc/include/asm/ftrace.h26
-rw-r--r--arch/parisc/include/asm/page.h13
-rw-r--r--arch/parisc/include/asm/pdc.h4
-rw-r--r--arch/parisc/include/asm/pgtable.h15
-rw-r--r--arch/parisc/include/asm/smp.h3
-rw-r--r--arch/parisc/include/asm/socket.h3
-rw-r--r--arch/parisc/include/asm/spinlock.h3
-rw-r--r--arch/parisc/kernel/Makefile15
-rw-r--r--arch/parisc/kernel/entry.S60
-rw-r--r--arch/parisc/kernel/firmware.c6
-rw-r--r--arch/parisc/kernel/ftrace.c185
-rw-r--r--arch/parisc/kernel/irq.c6
-rw-r--r--arch/parisc/kernel/module.c18
-rw-r--r--arch/parisc/kernel/parisc_ksyms.c5
-rw-r--r--arch/parisc/kernel/process.c31
-rw-r--r--arch/parisc/kernel/processor.c13
-rw-r--r--arch/parisc/kernel/smp.c21
-rw-r--r--arch/parisc/kernel/stacktrace.c63
-rw-r--r--arch/parisc/kernel/syscall.S58
-rw-r--r--arch/parisc/kernel/syscall_table.S2
-rw-r--r--arch/parisc/kernel/time.c12
-rw-r--r--arch/parisc/kernel/traps.c5
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S2
-rw-r--r--arch/parisc/mm/init.c7
-rw-r--r--arch/powerpc/Kconfig79
-rw-r--r--arch/powerpc/Kconfig.debug11
-rw-r--r--arch/powerpc/Makefile4
-rw-r--r--arch/powerpc/boot/Makefile9
-rw-r--r--arch/powerpc/boot/cuboot-amigaone.c35
-rw-r--r--arch/powerpc/boot/dts/amigaone.dts173
-rw-r--r--arch/powerpc/boot/dts/asp834x-redboot.dts82
-rw-r--r--arch/powerpc/boot/dts/canyonlands.dts35
-rw-r--r--arch/powerpc/boot/dts/cm5200.dts49
-rw-r--r--arch/powerpc/boot/dts/digsy_mtc.dts254
-rw-r--r--arch/powerpc/boot/dts/gef_ppc9a.dts367
-rw-r--r--arch/powerpc/boot/dts/gef_sbc310.dts367
-rw-r--r--arch/powerpc/boot/dts/gef_sbc610.dts41
-rw-r--r--arch/powerpc/boot/dts/kilauea.dts7
-rw-r--r--arch/powerpc/boot/dts/ksi8560.dts79
-rw-r--r--arch/powerpc/boot/dts/lite5200.dts52
-rw-r--r--arch/powerpc/boot/dts/lite5200b.dts63
-rw-r--r--arch/powerpc/boot/dts/media5200.dts318
-rw-r--r--arch/powerpc/boot/dts/motionpro.dts42
-rw-r--r--arch/powerpc/boot/dts/mpc8313erdb.dts11
-rw-r--r--arch/powerpc/boot/dts/mpc8315erdb.dts144
-rw-r--r--arch/powerpc/boot/dts/mpc832x_rdb.dts24
-rw-r--r--arch/powerpc/boot/dts/mpc8349emitx.dts69
-rw-r--r--arch/powerpc/boot/dts/mpc8349emitxgp.dts42
-rw-r--r--arch/powerpc/boot/dts/mpc834x_mds.dts81
-rw-r--r--arch/powerpc/boot/dts/mpc8377_mds.dts211
-rw-r--r--arch/powerpc/boot/dts/mpc8377_rdb.dts229
-rw-r--r--arch/powerpc/boot/dts/mpc8378_mds.dts209
-rw-r--r--arch/powerpc/boot/dts/mpc8378_rdb.dts229
-rw-r--r--arch/powerpc/boot/dts/mpc8379_mds.dts146
-rw-r--r--arch/powerpc/boot/dts/mpc8379_rdb.dts164
-rw-r--r--arch/powerpc/boot/dts/mpc8536ds.dts78
-rw-r--r--arch/powerpc/boot/dts/mpc8540ads.dts117
-rw-r--r--arch/powerpc/boot/dts/mpc8541cds.dts78
-rw-r--r--arch/powerpc/boot/dts/mpc8544ds.dts81
-rw-r--r--arch/powerpc/boot/dts/mpc8548cds.dts156
-rw-r--r--arch/powerpc/boot/dts/mpc8555cds.dts78
-rw-r--r--arch/powerpc/boot/dts/mpc8560ads.dts102
-rw-r--r--arch/powerpc/boot/dts/mpc8568mds.dts102
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds.dts160
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds_36b.dts799
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts49
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts6
-rw-r--r--arch/powerpc/boot/dts/mpc8610_hpcd.dts2
-rw-r--r--arch/powerpc/boot/dts/mpc8641_hpcn.dts157
-rw-r--r--arch/powerpc/boot/dts/pcm030.dts182
-rw-r--r--arch/powerpc/boot/dts/pcm032.dts392
-rw-r--r--arch/powerpc/boot/dts/redwood.dts244
-rw-r--r--arch/powerpc/boot/dts/sbc8349.dts80
-rw-r--r--arch/powerpc/boot/dts/sbc8548.dts78
-rw-r--r--arch/powerpc/boot/dts/sbc8560.dts100
-rw-r--r--arch/powerpc/boot/dts/sbc8641d.dts156
-rw-r--r--arch/powerpc/boot/dts/socrates.dts338
-rw-r--r--arch/powerpc/boot/dts/stx_gp3_8560.dts78
-rw-r--r--arch/powerpc/boot/dts/tqm5200.dts32
-rw-r--r--arch/powerpc/boot/dts/tqm8540.dts122
-rw-r--r--arch/powerpc/boot/dts/tqm8541.dts95
-rw-r--r--arch/powerpc/boot/dts/tqm8548-bigflash.dts184
-rw-r--r--arch/powerpc/boot/dts/tqm8548.dts184
-rw-r--r--arch/powerpc/boot/dts/tqm8555.dts95
-rw-r--r--arch/powerpc/boot/dts/tqm8560.dts99
-rw-r--r--arch/powerpc/boot/dts/virtex440-ml507.dts124
-rw-r--r--arch/powerpc/boot/serial.c3
-rwxr-xr-xarch/powerpc/boot/wrapper7
-rw-r--r--arch/powerpc/configs/44x/canyonlands_defconfig266
-rw-r--r--arch/powerpc/configs/44x/redwood_defconfig1176
-rw-r--r--arch/powerpc/configs/85xx/socrates_defconfig1410
-rw-r--r--arch/powerpc/configs/86xx/gef_ppc9a_defconfig1889
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc310_defconfig1613
-rw-r--r--arch/powerpc/configs/amigaone_defconfig1636
-rw-r--r--arch/powerpc/configs/mpc5200_defconfig71
-rw-r--r--arch/powerpc/configs/ppc64_defconfig6
-rw-r--r--arch/powerpc/include/asm/code-patching.h4
-rw-r--r--arch/powerpc/include/asm/cputable.h4
-rw-r--r--arch/powerpc/include/asm/dbell.h43
-rw-r--r--arch/powerpc/include/asm/dma-mapping.h12
-rw-r--r--arch/powerpc/include/asm/elf.h12
-rw-r--r--arch/powerpc/include/asm/fixmap.h2
-rw-r--r--arch/powerpc/include/asm/ftrace.h39
-rw-r--r--arch/powerpc/include/asm/highmem.h14
-rw-r--r--arch/powerpc/include/asm/hw_irq.h2
-rw-r--r--arch/powerpc/include/asm/io.h6
-rw-r--r--arch/powerpc/include/asm/kvm.h7
-rw-r--r--arch/powerpc/include/asm/kvm_44x.h7
-rw-r--r--arch/powerpc/include/asm/kvm_asm.h7
-rw-r--r--arch/powerpc/include/asm/kvm_e500.h67
-rw-r--r--arch/powerpc/include/asm/kvm_host.h21
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h15
-rw-r--r--arch/powerpc/include/asm/lppaca.h8
-rw-r--r--arch/powerpc/include/asm/machdep.h4
-rw-r--r--arch/powerpc/include/asm/mmu-44x.h2
-rw-r--r--arch/powerpc/include/asm/mmu-book3e.h (renamed from arch/powerpc/include/asm/mmu-fsl-booke.h)68
-rw-r--r--arch/powerpc/include/asm/mmu-hash64.h2
-rw-r--r--arch/powerpc/include/asm/mmu.h20
-rw-r--r--arch/powerpc/include/asm/mmu_context.h2
-rw-r--r--arch/powerpc/include/asm/mmzone.h1
-rw-r--r--arch/powerpc/include/asm/mpc52xx.h1
-rw-r--r--arch/powerpc/include/asm/page.h6
-rw-r--r--arch/powerpc/include/asm/page_32.h4
-rw-r--r--arch/powerpc/include/asm/pci.h4
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc32.h557
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64-4k.h (renamed from arch/powerpc/include/asm/pgtable-4k.h)55
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64-64k.h42
-rw-r--r--arch/powerpc/include/asm/pgtable-ppc64.h196
-rw-r--r--arch/powerpc/include/asm/pgtable.h134
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h73
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h6
-rw-r--r--arch/powerpc/include/asm/processor.h19
-rw-r--r--arch/powerpc/include/asm/ps3.h3
-rw-r--r--arch/powerpc/include/asm/ps3av.h2
-rw-r--r--arch/powerpc/include/asm/ps3fb.h1
-rw-r--r--arch/powerpc/include/asm/pte-40x.h64
-rw-r--r--arch/powerpc/include/asm/pte-44x.h102
-rw-r--r--arch/powerpc/include/asm/pte-8xx.h67
-rw-r--r--arch/powerpc/include/asm/pte-common.h180
-rw-r--r--arch/powerpc/include/asm/pte-fsl-booke.h48
-rw-r--r--arch/powerpc/include/asm/pte-hash32.h48
-rw-r--r--arch/powerpc/include/asm/pte-hash64-4k.h17
-rw-r--r--arch/powerpc/include/asm/pte-hash64-64k.h (renamed from arch/powerpc/include/asm/pgtable-64k.h)132
-rw-r--r--arch/powerpc/include/asm/pte-hash64.h54
-rw-r--r--arch/powerpc/include/asm/reg.h2
-rw-r--r--arch/powerpc/include/asm/reg_booke.h2
-rw-r--r--arch/powerpc/include/asm/socket.h3
-rw-r--r--arch/powerpc/include/asm/spinlock.h3
-rw-r--r--arch/powerpc/include/asm/suspend.h3
-rw-r--r--arch/powerpc/include/asm/systbl.h2
-rw-r--r--arch/powerpc/include/asm/system.h2
-rw-r--r--arch/powerpc/include/asm/thread_info.h11
-rw-r--r--arch/powerpc/include/asm/topology.h5
-rw-r--r--arch/powerpc/include/asm/udbg.h1
-rw-r--r--arch/powerpc/kernel/Makefile12
-rw-r--r--arch/powerpc/kernel/align.c2
-rw-r--r--arch/powerpc/kernel/asm-offsets.c7
-rw-r--r--arch/powerpc/kernel/cpu_setup_44x.S1
-rw-r--r--arch/powerpc/kernel/cpu_setup_6xx.S5
-rw-r--r--arch/powerpc/kernel/cpu_setup_fsl_booke.S31
-rw-r--r--arch/powerpc/kernel/cputable.c166
-rw-r--r--arch/powerpc/kernel/crash_dump.c2
-rw-r--r--arch/powerpc/kernel/dbell.c44
-rw-r--r--arch/powerpc/kernel/entry_32.S129
-rw-r--r--arch/powerpc/kernel/entry_64.S89
-rw-r--r--arch/powerpc/kernel/ftrace.c218
-rw-r--r--arch/powerpc/kernel/head_32.S110
-rw-r--r--arch/powerpc/kernel/head_64.S6
-rw-r--r--arch/powerpc/kernel/head_booke.h19
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S101
-rw-r--r--arch/powerpc/kernel/irq.c6
-rw-r--r--arch/powerpc/kernel/module_64.c2
-rw-r--r--arch/powerpc/kernel/msi.c5
-rw-r--r--arch/powerpc/kernel/pci-common.c45
-rw-r--r--arch/powerpc/kernel/pci_32.c36
-rw-r--r--arch/powerpc/kernel/pci_64.c19
-rw-r--r--arch/powerpc/kernel/process.c60
-rw-r--r--arch/powerpc/kernel/prom.c6
-rw-r--r--arch/powerpc/kernel/prom_init.c2
-rw-r--r--arch/powerpc/kernel/prom_init_check.sh2
-rw-r--r--arch/powerpc/kernel/rtas.c10
-rw-r--r--arch/powerpc/kernel/rtas_flash.c1
-rw-r--r--arch/powerpc/kernel/setup-common.c36
-rw-r--r--arch/powerpc/kernel/setup_64.c42
-rw-r--r--arch/powerpc/kernel/signal.c4
-rw-r--r--arch/powerpc/kernel/signal.h12
-rw-r--r--arch/powerpc/kernel/signal_32.c4
-rw-r--r--arch/powerpc/kernel/signal_64.c2
-rw-r--r--arch/powerpc/kernel/sysfs.c35
-rw-r--r--arch/powerpc/kernel/time.c16
-rw-r--r--arch/powerpc/kernel/traps.c79
-rw-r--r--arch/powerpc/kernel/udbg.c7
-rw-r--r--arch/powerpc/kernel/udbg_16550.c60
-rw-r--r--arch/powerpc/kernel/vio.c2
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S10
-rw-r--r--arch/powerpc/kvm/44x.c72
-rw-r--r--arch/powerpc/kvm/44x_emulate.c217
-rw-r--r--arch/powerpc/kvm/44x_tlb.c39
-rw-r--r--arch/powerpc/kvm/44x_tlb.h9
-rw-r--r--arch/powerpc/kvm/Kconfig16
-rw-r--r--arch/powerpc/kvm/Makefile10
-rw-r--r--arch/powerpc/kvm/booke.c50
-rw-r--r--arch/powerpc/kvm/booke.h35
-rw-r--r--arch/powerpc/kvm/booke_emulate.c266
-rw-r--r--arch/powerpc/kvm/booke_interrupts.S5
-rw-r--r--arch/powerpc/kvm/e500.c169
-rw-r--r--arch/powerpc/kvm/e500_emulate.c202
-rw-r--r--arch/powerpc/kvm/e500_tlb.c757
-rw-r--r--arch/powerpc/kvm/e500_tlb.h185
-rw-r--r--arch/powerpc/kvm/emulate.c93
-rw-r--r--arch/powerpc/kvm/powerpc.c31
-rw-r--r--arch/powerpc/lib/dma-noncoherent.c303
-rw-r--r--arch/powerpc/lib/feature-fixups.c4
-rw-r--r--arch/powerpc/math-emu/Makefile5
-rw-r--r--arch/powerpc/mm/Makefile4
-rw-r--r--arch/powerpc/mm/fault.c46
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c95
-rw-r--r--arch/powerpc/mm/gup.c16
-rw-r--r--arch/powerpc/mm/hash_utils_64.c51
-rw-r--r--arch/powerpc/mm/mem.c33
-rw-r--r--arch/powerpc/mm/mmap_64.c (renamed from arch/powerpc/mm/mmap.c)64
-rw-r--r--arch/powerpc/mm/mmu_context_nohash.c4
-rw-r--r--arch/powerpc/mm/numa.c174
-rw-r--r--arch/powerpc/mm/pgtable.c134
-rw-r--r--arch/powerpc/mm/pgtable_32.c18
-rw-r--r--arch/powerpc/mm/pgtable_64.c25
-rw-r--r--arch/powerpc/mm/ppc_mmu_32.c10
-rw-r--r--arch/powerpc/mm/tlb_hash64.c6
-rw-r--r--arch/powerpc/mm/tlb_nohash.c18
-rw-r--r--arch/powerpc/mm/tlb_nohash_low.S44
-rw-r--r--arch/powerpc/oprofile/op_model_7450.c21
-rw-r--r--arch/powerpc/platforms/44x/Kconfig19
-rw-r--r--arch/powerpc/platforms/44x/ppc44x_simple.c1
-rw-r--r--arch/powerpc/platforms/512x/Kconfig4
-rw-r--r--arch/powerpc/platforms/52xx/Kconfig15
-rw-r--r--arch/powerpc/platforms/52xx/Makefile3
-rw-r--r--arch/powerpc/platforms/52xx/media5200.c273
-rw-r--r--arch/powerpc/platforms/52xx/mpc5200_simple.c4
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_common.c40
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpio.c85
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c396
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pic.c170
-rw-r--r--arch/powerpc/platforms/82xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/83xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/83xx/asp834x.c1
-rw-r--r--arch/powerpc/platforms/83xx/mpc831x_rdb.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_rdb.c123
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_itx.c1
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_mds.c1
-rw-r--r--arch/powerpc/platforms/83xx/mpc837x_mds.c11
-rw-r--r--arch/powerpc/platforms/83xx/mpc837x_rdb.c3
-rw-r--r--arch/powerpc/platforms/83xx/sbc834x.c1
-rw-r--r--arch/powerpc/platforms/83xx/usb.c3
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig6
-rw-r--r--arch/powerpc/platforms/85xx/Makefile1
-rw-r--r--arch/powerpc/platforms/85xx/ksi8560.c3
-rw-r--r--arch/powerpc/platforms/85xx/mpc8536_ds.c1
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c1
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ds.c1
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c1
-rw-r--r--arch/powerpc/platforms/85xx/sbc8548.c1
-rw-r--r--arch/powerpc/platforms/85xx/sbc8560.c1
-rw-r--r--arch/powerpc/platforms/85xx/smp.c43
-rw-r--r--arch/powerpc/platforms/85xx/socrates.c133
-rw-r--r--arch/powerpc/platforms/85xx/socrates_fpga_pic.c327
-rw-r--r--arch/powerpc/platforms/85xx/socrates_fpga_pic.h16
-rw-r--r--arch/powerpc/platforms/85xx/stx_gp3.c1
-rw-r--r--arch/powerpc/platforms/85xx/tqm85xx.c1
-rw-r--r--arch/powerpc/platforms/86xx/Kconfig20
-rw-r--r--arch/powerpc/platforms/86xx/Makefile2
-rw-r--r--arch/powerpc/platforms/86xx/gef_gpio.c36
-rw-r--r--arch/powerpc/platforms/86xx/gef_ppc9a.c224
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc310.c235
-rw-r--r--arch/powerpc/platforms/86xx/gef_sbc610.c1
-rw-r--r--arch/powerpc/platforms/86xx/mpc8610_hpcd.c1
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c1
-rw-r--r--arch/powerpc/platforms/86xx/sbc8641d.c1
-rw-r--r--arch/powerpc/platforms/8xx/m8xx_setup.c1
-rw-r--r--arch/powerpc/platforms/Kconfig41
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype22
-rw-r--r--arch/powerpc/platforms/Makefile1
-rw-r--r--arch/powerpc/platforms/amigaone/Kconfig18
-rw-r--r--arch/powerpc/platforms/amigaone/Makefile1
-rw-r--r--arch/powerpc/platforms/amigaone/setup.c170
-rw-r--r--arch/powerpc/platforms/cell/Kconfig33
-rw-r--r--arch/powerpc/platforms/cell/Makefile2
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c4
-rw-r--r--arch/powerpc/platforms/cell/io-workarounds.c4
-rw-r--r--arch/powerpc/platforms/cell/iommu.c9
-rw-r--r--arch/powerpc/platforms/cell/qpace_setup.c15
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c2
-rw-r--r--arch/powerpc/platforms/cell/spu_fault.c48
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c4
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c20
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c7
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c3
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h8
-rw-r--r--arch/powerpc/platforms/chrp/Kconfig2
-rw-r--r--arch/powerpc/platforms/chrp/pegasos_eth.c72
-rw-r--r--arch/powerpc/platforms/chrp/setup.c1
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig2
-rw-r--r--arch/powerpc/platforms/iseries/Kconfig2
-rw-r--r--arch/powerpc/platforms/iseries/irq.c2
-rw-r--r--arch/powerpc/platforms/iseries/setup.c2
-rw-r--r--arch/powerpc/platforms/maple/Kconfig2
-rw-r--r--arch/powerpc/platforms/pasemi/Kconfig2
-rw-r--r--arch/powerpc/platforms/powermac/Kconfig2
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c5
-rw-r--r--arch/powerpc/platforms/powermac/pic.c2
-rw-r--r--arch/powerpc/platforms/powermac/pic.h2
-rw-r--r--arch/powerpc/platforms/powermac/setup.c3
-rw-r--r--arch/powerpc/platforms/powermac/smp.c1
-rw-r--r--arch/powerpc/platforms/prep/Kconfig2
-rw-r--r--arch/powerpc/platforms/ps3/Kconfig2
-rw-r--r--arch/powerpc/platforms/ps3/mm.c4
-rw-r--r--arch/powerpc/platforms/ps3/os-area.c2
-rw-r--r--arch/powerpc/platforms/ps3/platform.h2
-rw-r--r--arch/powerpc/platforms/ps3/setup.c2
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c4
-rw-r--r--arch/powerpc/platforms/ps3/time.c26
-rw-r--r--arch/powerpc/platforms/pseries/Kconfig17
-rw-r--r--arch/powerpc/platforms/pseries/Makefile3
-rw-r--r--arch/powerpc/platforms/pseries/dtl.c278
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c68
-rw-r--r--arch/powerpc/platforms/pseries/msi.c248
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c2
-rw-r--r--arch/powerpc/platforms/pseries/plpar_wrappers.h10
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c6
-rw-r--r--arch/powerpc/sysdev/bestcomm/Kconfig4
-rw-r--r--arch/powerpc/sysdev/cpm1.c1
-rw-r--r--arch/powerpc/sysdev/cpm2.c4
-rw-r--r--arch/powerpc/sysdev/cpm_common.c2
-rw-r--r--arch/powerpc/sysdev/fsl_lbc.c2
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c244
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c113
-rw-r--r--arch/powerpc/sysdev/fsl_soc.h7
-rw-r--r--arch/powerpc/sysdev/ipic.c6
-rw-r--r--arch/powerpc/sysdev/msi_bitmap.c6
-rw-r--r--arch/powerpc/sysdev/pmi.c2
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.c2
-rw-r--r--arch/s390/Kconfig14
-rw-r--r--arch/s390/Kconfig.debug8
-rw-r--r--arch/s390/crypto/prng.c3
-rw-r--r--arch/s390/crypto/sha.h6
-rw-r--r--arch/s390/crypto/sha1_s390.c40
-rw-r--r--arch/s390/crypto/sha256_s390.c40
-rw-r--r--arch/s390/crypto/sha512_s390.c81
-rw-r--r--arch/s390/crypto/sha_common.c20
-rw-r--r--arch/s390/hypfs/hypfs_diag.c2
-rw-r--r--arch/s390/include/asm/bitops.h14
-rw-r--r--arch/s390/include/asm/cio.h2
-rw-r--r--arch/s390/include/asm/crw.h68
-rw-r--r--arch/s390/include/asm/dasd.h10
-rw-r--r--arch/s390/include/asm/idals.h17
-rw-r--r--arch/s390/include/asm/kvm.h7
-rw-r--r--arch/s390/include/asm/kvm_host.h3
-rw-r--r--arch/s390/include/asm/lowcore.h653
-rw-r--r--arch/s390/include/asm/mmu_context.h2
-rw-r--r--arch/s390/include/asm/nmi.h66
-rw-r--r--arch/s390/include/asm/processor.h16
-rw-r--r--arch/s390/include/asm/ptrace.h4
-rw-r--r--arch/s390/include/asm/qdio.h1
-rw-r--r--arch/s390/include/asm/smp.h13
-rw-r--r--arch/s390/include/asm/socket.h3
-rw-r--r--arch/s390/include/asm/spinlock.h3
-rw-r--r--arch/s390/include/asm/string.h16
-rw-r--r--arch/s390/include/asm/sysinfo.h1
-rw-r--r--arch/s390/include/asm/tlbflush.h4
-rw-r--r--arch/s390/include/asm/topology.h1
-rw-r--r--arch/s390/include/asm/vtoc.h16
-rw-r--r--arch/s390/kernel/Makefile4
-rw-r--r--arch/s390/kernel/bitmap.S56
-rw-r--r--arch/s390/kernel/bitmap.c54
-rw-r--r--arch/s390/kernel/compat_ptrace.h3
-rw-r--r--arch/s390/kernel/compat_wrapper.S2
-rw-r--r--arch/s390/kernel/debug.c9
-rw-r--r--arch/s390/kernel/early.c23
-rw-r--r--arch/s390/kernel/head.S2
-rw-r--r--arch/s390/kernel/head31.S1
-rw-r--r--arch/s390/kernel/head64.S1
-rw-r--r--arch/s390/kernel/ipl.c74
-rw-r--r--arch/s390/kernel/module.c19
-rw-r--r--arch/s390/kernel/nmi.c (renamed from drivers/s390/s390mach.c)278
-rw-r--r--arch/s390/kernel/process.c75
-rw-r--r--arch/s390/kernel/processor.c73
-rw-r--r--arch/s390/kernel/reipl64.S11
-rw-r--r--arch/s390/kernel/s390_ksyms.c44
-rw-r--r--arch/s390/kernel/setup.c52
-rw-r--r--arch/s390/kernel/smp.c68
-rw-r--r--arch/s390/kernel/sysinfo.c (renamed from drivers/s390/sysinfo.c)69
-rw-r--r--arch/s390/kernel/time.c71
-rw-r--r--arch/s390/kernel/topology.c2
-rw-r--r--arch/s390/kernel/traps.c4
-rw-r--r--arch/s390/kernel/vdso.c2
-rw-r--r--arch/s390/kernel/vmlinux.lds.S2
-rw-r--r--arch/s390/kvm/Kconfig3
-rw-r--r--arch/s390/kvm/intercept.c2
-rw-r--r--arch/s390/kvm/interrupt.c7
-rw-r--r--arch/s390/kvm/kvm-s390.c10
-rw-r--r--arch/s390/kvm/kvm-s390.h2
-rw-r--r--arch/s390/kvm/priv.c18
-rw-r--r--arch/s390/kvm/sigp.c2
-rw-r--r--arch/s390/lib/delay.c2
-rw-r--r--arch/s390/lib/string.c8
-rw-r--r--arch/s390/mm/fault.c28
-rw-r--r--arch/s390/mm/init.c2
-rw-r--r--arch/s390/mm/pgtable.c6
-rw-r--r--arch/sh/Kconfig73
-rw-r--r--arch/sh/Kconfig.cpu3
-rw-r--r--arch/sh/Makefile1
-rw-r--r--arch/sh/boards/Kconfig27
-rw-r--r--arch/sh/boards/Makefile3
-rw-r--r--arch/sh/boards/board-ap325rxa.c67
-rw-r--r--arch/sh/boards/board-espt.c102
-rw-r--r--arch/sh/boards/board-polaris.c149
-rw-r--r--arch/sh/boards/board-sh7785lcr.c15
-rw-r--r--arch/sh/boards/board-urquell.c166
-rw-r--r--arch/sh/boards/mach-highlander/Kconfig2
-rw-r--r--arch/sh/boards/mach-hp6xx/pm_wakeup.S31
-rw-r--r--arch/sh/boards/mach-hp6xx/setup.c1
-rw-r--r--arch/sh/boards/mach-migor/setup.c12
-rw-r--r--arch/sh/boards/mach-rsk/Kconfig2
-rw-r--r--arch/sh/boards/mach-sh7763rdp/setup.c10
-rw-r--r--arch/sh/boot/Makefile20
-rw-r--r--arch/sh/cchips/hd6446x/hd64461.c30
-rw-r--r--arch/sh/configs/ap325rxa_defconfig70
-rw-r--r--arch/sh/configs/cayman_defconfig235
-rw-r--r--arch/sh/configs/dreamcast_defconfig71
-rw-r--r--arch/sh/configs/edosk7705_defconfig29
-rw-r--r--arch/sh/configs/edosk7760_defconfig78
-rw-r--r--arch/sh/configs/espt_defconfig1199
-rw-r--r--arch/sh/configs/hp6xx_defconfig54
-rw-r--r--arch/sh/configs/landisk_defconfig97
-rw-r--r--arch/sh/configs/lboxre2_defconfig69
-rw-r--r--arch/sh/configs/magicpanelr2_defconfig73
-rw-r--r--arch/sh/configs/microdev_defconfig74
-rw-r--r--arch/sh/configs/migor_defconfig82
-rw-r--r--arch/sh/configs/polaris_defconfig972
-rw-r--r--arch/sh/configs/r7780mp_defconfig91
-rw-r--r--arch/sh/configs/r7785rp_defconfig96
-rw-r--r--arch/sh/configs/rsk7201_defconfig57
-rw-r--r--arch/sh/configs/rsk7203_defconfig94
-rw-r--r--arch/sh/configs/rts7751r2d1_defconfig83
-rw-r--r--arch/sh/configs/rts7751r2dplus_defconfig83
-rw-r--r--arch/sh/configs/sdk7780_defconfig78
-rw-r--r--arch/sh/configs/se7206_defconfig82
-rw-r--r--arch/sh/configs/se7343_defconfig89
-rw-r--r--arch/sh/configs/se7619_defconfig55
-rw-r--r--arch/sh/configs/se7705_defconfig75
-rw-r--r--arch/sh/configs/se7712_defconfig79
-rw-r--r--arch/sh/configs/se7721_defconfig82
-rw-r--r--arch/sh/configs/se7722_defconfig76
-rw-r--r--arch/sh/configs/se7750_defconfig71
-rw-r--r--arch/sh/configs/se7751_defconfig74
-rw-r--r--arch/sh/configs/se7780_defconfig78
-rw-r--r--arch/sh/configs/sh03_defconfig79
-rw-r--r--arch/sh/configs/sh7710voipgw_defconfig69
-rw-r--r--arch/sh/configs/sh7763rdp_defconfig82
-rw-r--r--arch/sh/configs/sh7785lcr_32bit_defconfig1561
-rw-r--r--arch/sh/configs/sh7785lcr_defconfig90
-rw-r--r--arch/sh/configs/shmin_defconfig73
-rw-r--r--arch/sh/configs/shx3_defconfig99
-rw-r--r--arch/sh/configs/snapgear_defconfig62
-rw-r--r--arch/sh/configs/systemh_defconfig54
-rw-r--r--arch/sh/configs/titan_defconfig101
-rw-r--r--arch/sh/configs/ul2_defconfig93
-rw-r--r--arch/sh/configs/urquell_defconfig1341
-rw-r--r--arch/sh/drivers/dma/Kconfig46
-rw-r--r--arch/sh/drivers/dma/Makefile3
-rw-r--r--arch/sh/drivers/dma/dma-sh.c169
-rw-r--r--arch/sh/drivers/dma/dma-sh.h75
-rw-r--r--arch/sh/drivers/pci/ops-sh7785lcr.c9
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c16
-rw-r--r--arch/sh/include/asm/addrspace.h4
-rw-r--r--arch/sh/include/asm/atomic-irq.h16
-rw-r--r--arch/sh/include/asm/bitops-llsc.h72
-rw-r--r--arch/sh/include/asm/clock.h1
-rw-r--r--arch/sh/include/asm/cmpxchg-llsc.h38
-rw-r--r--arch/sh/include/asm/cpu-features.h1
-rw-r--r--arch/sh/include/asm/dma-sh.h118
-rw-r--r--arch/sh/include/asm/dma.h4
-rw-r--r--arch/sh/include/asm/entry-macros.S5
-rw-r--r--arch/sh/include/asm/gpio.h70
-rw-r--r--arch/sh/include/asm/hd64461.h1
-rw-r--r--arch/sh/include/asm/io.h4
-rw-r--r--arch/sh/include/asm/kprobes.h2
-rw-r--r--arch/sh/include/asm/mmu.h35
-rw-r--r--arch/sh/include/asm/mmu_context.h15
-rw-r--r--arch/sh/include/asm/mmu_context_32.h12
-rw-r--r--arch/sh/include/asm/page.h7
-rw-r--r--arch/sh/include/asm/processor.h2
-rw-r--r--arch/sh/include/asm/processor_32.h28
-rw-r--r--arch/sh/include/asm/processor_64.h14
-rw-r--r--arch/sh/include/asm/ptrace.h12
-rw-r--r--arch/sh/include/asm/sections.h1
-rw-r--r--arch/sh/include/asm/socket.h3
-rw-r--r--arch/sh/include/asm/spinlock.h3
-rw-r--r--arch/sh/include/asm/suspend.h22
-rw-r--r--arch/sh/include/asm/system.h1
-rw-r--r--arch/sh/include/asm/system_32.h170
-rw-r--r--arch/sh/include/asm/timer.h4
-rw-r--r--arch/sh/include/asm/tlb.h100
-rw-r--r--arch/sh/include/asm/topology.h1
-rw-r--r--arch/sh/include/cpu-sh3/cpu/dma.h17
-rw-r--r--arch/sh/include/cpu-sh4/cpu/dma-sh4a.h94
-rw-r--r--arch/sh/include/cpu-sh4/cpu/dma-sh7780.h39
-rw-r--r--arch/sh/include/cpu-sh4/cpu/dma.h30
-rw-r--r--arch/sh/include/cpu-sh4/cpu/freq.h4
-rw-r--r--arch/sh/include/cpu-sh4/cpu/mmu_context.h35
-rw-r--r--arch/sh/include/cpu-sh4/cpu/sh7786.h136
-rw-r--r--arch/sh/include/mach-common/mach/urquell.h68
-rw-r--r--arch/sh/kernel/Makefile_321
-rw-r--r--arch/sh/kernel/asm-offsets.c8
-rw-r--r--arch/sh/kernel/cpu/Makefile1
-rw-r--r--arch/sh/kernel/cpu/clock.c95
-rw-r--r--arch/sh/kernel/cpu/sh2/setup-sh7619.c34
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-mxg.c65
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7201.c224
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7203.c236
-rw-r--r--arch/sh/kernel/cpu/sh2a/setup-sh7206.c154
-rw-r--r--arch/sh/kernel/cpu/sh3/Makefile2
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S408
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c61
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh770x.c68
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c69
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7720.c68
-rw-r--r--arch/sh/kernel/cpu/sh3/swsusp.S147
-rw-r--r--arch/sh/kernel/cpu/sh4/Makefile1
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c12
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c87
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile3
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7786.c148
-rw-r--r--arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c843
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7343.c34
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7366.c34
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7722.c34
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7723.c34
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7763.c114
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7780.c97
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7785.c95
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7786.c490
-rw-r--r--arch/sh/kernel/cpu/shmobile/Makefile6
-rw-r--r--arch/sh/kernel/cpu/shmobile/pm.c92
-rw-r--r--arch/sh/kernel/cpu/shmobile/sleep.S125
-rw-r--r--arch/sh/kernel/gpio.c338
-rw-r--r--arch/sh/kernel/idle.c2
-rw-r--r--arch/sh/kernel/io_trapped.c13
-rw-r--r--arch/sh/kernel/irq.c4
-rw-r--r--arch/sh/kernel/machine_kexec.c74
-rw-r--r--arch/sh/kernel/process_32.c16
-rw-r--r--arch/sh/kernel/process_64.c2
-rw-r--r--arch/sh/kernel/ptrace_32.c6
-rw-r--r--arch/sh/kernel/relocate_kernel.S203
-rw-r--r--arch/sh/kernel/setup.c8
-rw-r--r--arch/sh/kernel/swsusp.c38
-rw-r--r--arch/sh/kernel/time_32.c71
-rw-r--r--arch/sh/kernel/time_64.c1
-rw-r--r--arch/sh/kernel/timers/timer-cmt.c1
-rw-r--r--arch/sh/kernel/timers/timer-mtu2.c4
-rw-r--r--arch/sh/kernel/timers/timer-tmu.c22
-rw-r--r--arch/sh/kernel/traps_32.c2
-rw-r--r--arch/sh/kernel/vmlinux_32.lds.S5
-rw-r--r--arch/sh/mm/Kconfig41
-rw-r--r--arch/sh/mm/Makefile_327
-rw-r--r--arch/sh/mm/asids-debugfs.c4
-rw-r--r--arch/sh/mm/ioremap_32.c8
-rw-r--r--arch/sh/mm/pmb-fixed.c45
-rw-r--r--arch/sh/mm/pmb.c38
-rw-r--r--arch/sh/mm/tlb-pteaex.c96
-rw-r--r--arch/sh/oprofile/common.c1
-rw-r--r--arch/sh/tools/mach-types3
-rw-r--r--arch/sparc/Kconfig3
-rw-r--r--arch/sparc/Kconfig.debug8
-rw-r--r--arch/sparc/include/asm/mmu_context_64.h8
-rw-r--r--arch/sparc/include/asm/mmzone.h2
-rw-r--r--arch/sparc/include/asm/pil.h1
-rw-r--r--arch/sparc/include/asm/smp_64.h3
-rw-r--r--arch/sparc/include/asm/socket.h3
-rw-r--r--arch/sparc/include/asm/spinlock_32.h2
-rw-r--r--arch/sparc/include/asm/spinlock_64.h2
-rw-r--r--arch/sparc/include/asm/system_32.h2
-rw-r--r--arch/sparc/include/asm/tlb_64.h4
-rw-r--r--arch/sparc/include/asm/topology_64.h12
-rw-r--r--arch/sparc/kernel/ds.c2
-rw-r--r--arch/sparc/kernel/head_64.S2
-rw-r--r--arch/sparc/kernel/irq_32.c2
-rw-r--r--arch/sparc/kernel/irq_64.c6
-rw-r--r--arch/sparc/kernel/kgdb_64.c2
-rw-r--r--arch/sparc/kernel/led.c1
-rw-r--r--arch/sparc/kernel/mdesc.c2
-rw-r--r--arch/sparc/kernel/nmi.c23
-rw-r--r--arch/sparc/kernel/pci_common.c2
-rw-r--r--arch/sparc/kernel/process_32.c2
-rw-r--r--arch/sparc/kernel/process_64.c2
-rw-r--r--arch/sparc/kernel/prom_64.c4
-rw-r--r--arch/sparc/kernel/smp_32.c36
-rw-r--r--arch/sparc/kernel/smp_64.c18
-rw-r--r--arch/sparc/kernel/sun4d_irq.c1
-rw-r--r--arch/sparc/kernel/sun4d_smp.c11
-rw-r--r--arch/sparc/kernel/sun4m_smp.c10
-rw-r--r--arch/sparc/kernel/systbls_64.S2
-rw-r--r--arch/sparc/kernel/ttable.S7
-rw-r--r--arch/sparc/mm/highmem.c1
-rw-r--r--arch/sparc/mm/init_64.c2
-rw-r--r--arch/sparc/mm/srmmu.c2
-rw-r--r--arch/sparc/mm/ultra.S24
-rw-r--r--arch/um/drivers/net_kern.c41
-rw-r--r--arch/um/drivers/pcap_user.h10
-rw-r--r--arch/um/drivers/port.h10
-rw-r--r--arch/um/drivers/ssl.h10
-rw-r--r--arch/um/drivers/stdio_console.h10
-rw-r--r--arch/um/drivers/ubd_kern.c29
-rw-r--r--arch/um/drivers/xterm.h10
-rw-r--r--arch/um/include/asm/irq_vectors.h10
-rw-r--r--arch/um/include/asm/mmu.h10
-rw-r--r--arch/um/include/asm/pda.h10
-rw-r--r--arch/um/include/asm/pgalloc.h10
-rw-r--r--arch/um/include/asm/pgtable-3level.h10
-rw-r--r--arch/um/include/shared/frame_kern.h10
-rw-r--r--arch/um/include/shared/initrd.h10
-rw-r--r--arch/um/include/shared/irq_kern.h10
-rw-r--r--arch/um/include/shared/mem_kern.h10
-rw-r--r--arch/um/include/shared/net_kern.h2
-rw-r--r--arch/um/include/shared/ubd_user.h10
-rw-r--r--arch/um/kernel/Makefile6
-rw-r--r--arch/um/kernel/config.c.in18
-rw-r--r--arch/um/kernel/irq.c2
-rw-r--r--arch/um/kernel/process.c2
-rw-r--r--arch/um/kernel/syscall.c3
-rw-r--r--arch/um/os-Linux/start_up.c8
-rw-r--r--arch/um/sys-i386/asm/archparam.h10
-rw-r--r--arch/um/sys-i386/shared/sysdep/checksum.h10
-rw-r--r--arch/um/sys-i386/sys_call_table.S11
-rw-r--r--arch/um/sys-ia64/sysdep/ptrace.h10
-rw-r--r--arch/um/sys-ia64/sysdep/sigcontext.h10
-rw-r--r--arch/um/sys-ia64/sysdep/syscalls.h10
-rw-r--r--arch/um/sys-ppc/miscthings.c11
-rw-r--r--arch/um/sys-ppc/ptrace.c10
-rw-r--r--arch/um/sys-ppc/ptrace_user.c10
-rw-r--r--arch/um/sys-ppc/shared/sysdep/ptrace.h10
-rw-r--r--arch/um/sys-ppc/shared/sysdep/sigcontext.h10
-rw-r--r--arch/um/sys-ppc/shared/sysdep/syscalls.h10
-rw-r--r--arch/um/sys-ppc/sigcontext.c10
-rw-r--r--arch/um/sys-x86_64/asm/archparam.h10
-rw-r--r--arch/um/sys-x86_64/asm/module.h10
-rw-r--r--arch/um/sys-x86_64/mem.c9
-rw-r--r--arch/x86/Kconfig19
-rw-r--r--arch/x86/Kconfig.cpu17
-rw-r--r--arch/x86/Kconfig.debug8
-rw-r--r--arch/x86/Makefile29
-rw-r--r--arch/x86/boot/Makefile33
-rw-r--r--arch/x86/boot/compressed/Makefile1
-rw-r--r--arch/x86/boot/memory.c39
-rw-r--r--arch/x86/boot/pmjump.S1
-rw-r--r--arch/x86/boot/setup.ld3
-rw-r--r--arch/x86/boot/video-vga.c22
-rw-r--r--arch/x86/crypto/Makefile3
-rw-r--r--arch/x86/crypto/aes-i586-asm_32.S18
-rw-r--r--arch/x86/crypto/aes-x86_64-asm_64.S6
-rw-r--r--arch/x86/crypto/aes_glue.c20
-rw-r--r--arch/x86/crypto/aesni-intel_asm.S896
-rw-r--r--arch/x86/crypto/aesni-intel_glue.c461
-rw-r--r--arch/x86/ia32/ia32entry.S4
-rw-r--r--arch/x86/ia32/sys_ia32.c22
-rw-r--r--arch/x86/include/asm/aes.h11
-rw-r--r--arch/x86/include/asm/apic.h38
-rw-r--r--arch/x86/include/asm/cacheflush.h3
-rwxr-xr-xarch/x86/include/asm/cpu_debug.h49
-rw-r--r--arch/x86/include/asm/cpufeature.h1
-rw-r--r--arch/x86/include/asm/cpumask.h18
-rw-r--r--arch/x86/include/asm/device.h2
-rw-r--r--arch/x86/include/asm/dma-mapping.h188
-rw-r--r--arch/x86/include/asm/dmi.h19
-rw-r--r--arch/x86/include/asm/e820.h2
-rw-r--r--arch/x86/include/asm/ia32.h7
-rw-r--r--arch/x86/include/asm/io_apic.h12
-rw-r--r--arch/x86/include/asm/iommu.h2
-rw-r--r--arch/x86/include/asm/irq_remapping.h2
-rw-r--r--arch/x86/include/asm/kvm.h24
-rw-r--r--arch/x86/include/asm/kvm_host.h61
-rw-r--r--arch/x86/include/asm/lguest_hcall.h24
-rw-r--r--arch/x86/include/asm/msidef.h1
-rw-r--r--arch/x86/include/asm/msr-index.h9
-rw-r--r--arch/x86/include/asm/page_32_types.h5
-rw-r--r--arch/x86/include/asm/paravirt.h19
-rw-r--r--arch/x86/include/asm/pci.h44
-rw-r--r--arch/x86/include/asm/pci_32.h34
-rw-r--r--arch/x86/include/asm/pci_64.h22
-rw-r--r--arch/x86/include/asm/percpu.h8
-rw-r--r--arch/x86/include/asm/pgtable-2level.h7
-rw-r--r--arch/x86/include/asm/pgtable-3level.h17
-rw-r--r--arch/x86/include/asm/pgtable.h2
-rw-r--r--arch/x86/include/asm/pgtable_32.h3
-rw-r--r--arch/x86/include/asm/processor.h8
-rw-r--r--arch/x86/include/asm/sections.h7
-rw-r--r--arch/x86/include/asm/setup.h39
-rw-r--r--arch/x86/include/asm/smp.h13
-rw-r--r--arch/x86/include/asm/socket.h3
-rw-r--r--arch/x86/include/asm/spinlock.h3
-rw-r--r--arch/x86/include/asm/suspend_32.h24
-rw-r--r--arch/x86/include/asm/svm.h4
-rw-r--r--arch/x86/include/asm/sys_ia32.h2
-rw-r--r--arch/x86/include/asm/timer.h2
-rw-r--r--arch/x86/include/asm/topology.h99
-rw-r--r--arch/x86/include/asm/unistd_32.h2
-rw-r--r--arch/x86/include/asm/unistd_64.h4
-rw-r--r--arch/x86/include/asm/uv/uv_hub.h14
-rw-r--r--arch/x86/include/asm/uv/uv_mmrs.h153
-rw-r--r--arch/x86/include/asm/virtext.h2
-rw-r--r--arch/x86/include/asm/vmx.h5
-rw-r--r--arch/x86/include/asm/xen/hypercall.h2
-rw-r--r--arch/x86/kernel/Makefile4
-rw-r--r--arch/x86/kernel/acpi/boot.c65
-rw-r--r--arch/x86/kernel/amd_iommu.c33
-rw-r--r--arch/x86/kernel/apic/apic.c82
-rw-r--r--arch/x86/kernel/apic/apic_flat_64.c18
-rw-r--r--arch/x86/kernel/apic/bigsmp_32.c16
-rw-r--r--arch/x86/kernel/apic/es7000_32.c17
-rw-r--r--arch/x86/kernel/apic/io_apic.c412
-rw-r--r--arch/x86/kernel/apic/nmi.c11
-rw-r--r--arch/x86/kernel/apic/numaq_32.c11
-rw-r--r--arch/x86/kernel/apic/probe_32.c3
-rw-r--r--arch/x86/kernel/apic/probe_64.c7
-rw-r--r--arch/x86/kernel/apic/summit_32.c21
-rw-r--r--arch/x86/kernel/apic/x2apic_cluster.c6
-rw-r--r--arch/x86/kernel/apic/x2apic_phys.c6
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c9
-rw-r--r--arch/x86/kernel/apm_32.c263
-rw-r--r--arch/x86/kernel/asm-offsets_32.c1
-rw-r--r--arch/x86/kernel/asm-offsets_64.c1
-rw-r--r--arch/x86/kernel/check.c8
-rw-r--r--arch/x86/kernel/cpu/Makefile3
-rw-r--r--arch/x86/kernel/cpu/addon_cpuid_features.c2
-rw-r--r--arch/x86/kernel/cpu/amd.c2
-rw-r--r--arch/x86/kernel/cpu/centaur.c36
-rw-r--r--arch/x86/kernel/cpu/centaur_64.c37
-rw-r--r--arch/x86/kernel/cpu/common.c399
-rw-r--r--arch/x86/kernel/cpu/cpu.h25
-rwxr-xr-xarch/x86/kernel/cpu/cpu_debug.c268
-rw-r--r--arch/x86/kernel/cpu/cpufreq/Kconfig19
-rw-r--r--arch/x86/kernel/cpu/cpufreq/Makefile8
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c48
-rw-r--r--arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c54
-rw-r--r--arch/x86/kernel/cpu/cpufreq/e_powersaver.c21
-rw-r--r--arch/x86/kernel/cpu/cpufreq/elanfreq.c6
-rw-r--r--arch/x86/kernel/cpu/cpufreq/gx-suspmod.c105
-rw-r--r--arch/x86/kernel/cpu/cpufreq/longhaul.c199
-rw-r--r--arch/x86/kernel/cpu/cpufreq/longhaul.h12
-rw-r--r--arch/x86/kernel/cpu/cpufreq/longrun.c25
-rw-r--r--arch/x86/kernel/cpu/cpufreq/p4-clockmod.c74
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k6.c44
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k7.c239
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.c399
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.h5
-rw-r--r--arch/x86/kernel/cpu/cpufreq/sc520_freq.c30
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-ich.c72
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-lib.c163
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-lib.h18
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-smi.c166
-rw-r--r--arch/x86/kernel/cpu/cyrix.c16
-rw-r--r--arch/x86/kernel/cpu/intel.c7
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c32
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_64.c10
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd_64.c46
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_intel_64.c4
-rw-r--r--arch/x86/kernel/cpu/mtrr/Makefile2
-rw-r--r--arch/x86/kernel/cpu/mtrr/cleanup.c1101
-rw-r--r--arch/x86/kernel/cpu/mtrr/generic.c199
-rw-r--r--arch/x86/kernel/cpu/mtrr/if.c10
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c1069
-rw-r--r--arch/x86/kernel/cpu/mtrr/mtrr.h4
-rw-r--r--arch/x86/kernel/cpu/proc.c6
-rw-r--r--arch/x86/kernel/cpu/transmeta.c2
-rw-r--r--arch/x86/kernel/cpu/umc.c2
-rw-r--r--arch/x86/kernel/e820.c142
-rw-r--r--arch/x86/kernel/early_printk.c20
-rw-r--r--arch/x86/kernel/head32.c5
-rw-r--r--arch/x86/kernel/head64.c2
-rw-r--r--arch/x86/kernel/head_32.S76
-rw-r--r--arch/x86/kernel/hpet.c80
-rw-r--r--arch/x86/kernel/i8253.c68
-rw-r--r--arch/x86/kernel/io_delay.c27
-rw-r--r--arch/x86/kernel/irq.c54
-rw-r--r--arch/x86/kernel/irqinit_32.c2
-rw-r--r--arch/x86/kernel/irqinit_64.c1
-rw-r--r--arch/x86/kernel/kdebugfs.c82
-rw-r--r--arch/x86/kernel/kprobes.c19
-rw-r--r--arch/x86/kernel/kvm.c7
-rw-r--r--arch/x86/kernel/mfgpt_32.c1
-rw-r--r--arch/x86/kernel/microcode_amd.c43
-rw-r--r--arch/x86/kernel/microcode_core.c160
-rw-r--r--arch/x86/kernel/microcode_intel.c83
-rw-r--r--arch/x86/kernel/mmconf-fam10h_64.c2
-rw-r--r--arch/x86/kernel/mpparse.c375
-rw-r--r--arch/x86/kernel/paravirt.c1
-rw-r--r--arch/x86/kernel/pci-calgary_64.c38
-rw-r--r--arch/x86/kernel/pci-dma.c17
-rw-r--r--arch/x86/kernel/pci-gart_64.c34
-rw-r--r--arch/x86/kernel/pci-nommu.c39
-rw-r--r--arch/x86/kernel/pci-swiotlb.c (renamed from arch/x86/kernel/pci-swiotlb_64.c)19
-rw-r--r--arch/x86/kernel/process.c25
-rw-r--r--arch/x86/kernel/process_32.c2
-rw-r--r--arch/x86/kernel/process_64.c2
-rw-r--r--arch/x86/kernel/ptrace.c5
-rw-r--r--arch/x86/kernel/quirks.c3
-rw-r--r--arch/x86/kernel/rtc.c20
-rw-r--r--arch/x86/kernel/setup.c55
-rw-r--r--arch/x86/kernel/setup_percpu.c79
-rw-r--r--arch/x86/kernel/signal.c48
-rw-r--r--arch/x86/kernel/smpboot.c70
-rw-r--r--arch/x86/kernel/syscall_table_32.S2
-rw-r--r--arch/x86/kernel/time_64.c2
-rw-r--r--arch/x86/kernel/tlb_uv.c12
-rw-r--r--arch/x86/kernel/topology.c14
-rw-r--r--arch/x86/kernel/tsc.c12
-rw-r--r--arch/x86/kernel/vmi_32.c6
-rw-r--r--arch/x86/kernel/vmiclock_32.c1
-rw-r--r--arch/x86/kernel/vmlinux_32.lds.S21
-rw-r--r--arch/x86/kernel/vmlinux_64.lds.S94
-rw-r--r--arch/x86/kernel/vsmp_64.c12
-rw-r--r--arch/x86/kvm/Kconfig4
-rw-r--r--arch/x86/kvm/i8254.c21
-rw-r--r--arch/x86/kvm/i8254.h2
-rw-r--r--arch/x86/kvm/i8259.c25
-rw-r--r--arch/x86/kvm/irq.h2
-rw-r--r--arch/x86/kvm/kvm_svm.h16
-rw-r--r--arch/x86/kvm/mmu.c237
-rw-r--r--arch/x86/kvm/mmu.h2
-rw-r--r--arch/x86/kvm/paging_tmpl.h219
-rw-r--r--arch/x86/kvm/svm.c916
-rw-r--r--arch/x86/kvm/vmx.c393
-rw-r--r--arch/x86/kvm/x86.c432
-rw-r--r--arch/x86/kvm/x86_emulate.c56
-rw-r--r--arch/x86/lguest/boot.c94
-rw-r--r--arch/x86/lguest/i386_head.S4
-rw-r--r--arch/x86/mm/Makefile2
-rw-r--r--arch/x86/mm/highmem_32.c65
-rw-r--r--arch/x86/mm/init.c6
-rw-r--r--arch/x86/mm/iomap_32.c23
-rw-r--r--arch/x86/mm/ioremap.c19
-rw-r--r--arch/x86/mm/mmio-mod.c19
-rw-r--r--arch/x86/mm/numa.c67
-rw-r--r--arch/x86/mm/numa_64.c111
-rw-r--r--arch/x86/mm/pageattr.c147
-rw-r--r--arch/x86/mm/pat.c5
-rw-r--r--arch/x86/mm/pgtable_32.c2
-rw-r--r--arch/x86/mm/srat_64.c30
-rw-r--r--arch/x86/mm/tlb.c5
-rw-r--r--arch/x86/oprofile/op_model_p4.c2
-rw-r--r--arch/x86/pci/common.c4
-rw-r--r--arch/x86/pci/early.c19
-rw-r--r--arch/x86/pci/fixup.c24
-rw-r--r--arch/x86/pci/i386.c43
-rw-r--r--arch/x86/pci/legacy.c3
-rw-r--r--arch/x86/pci/mmconfig-shared.c227
-rw-r--r--arch/x86/pci/mmconfig_64.c17
-rw-r--r--arch/x86/power/Makefile5
-rw-r--r--arch/x86/power/cpu_32.c1
-rw-r--r--arch/x86/power/cpu_64.c1
-rw-r--r--arch/x86/power/hibernate_64.c1
-rw-r--r--arch/x86/xen/mmu.c7
-rw-r--r--arch/x86/xen/smp.c6
-rw-r--r--arch/xtensa/Kconfig184
-rw-r--r--arch/xtensa/Makefile15
-rw-r--r--arch/xtensa/configs/s6105_defconfig530
-rw-r--r--arch/xtensa/include/asm/cacheflush.h10
-rw-r--r--arch/xtensa/include/asm/dma.h3
-rw-r--r--arch/xtensa/include/asm/flat.h12
-rw-r--r--arch/xtensa/include/asm/gpio.h56
-rw-r--r--arch/xtensa/include/asm/io.h9
-rw-r--r--arch/xtensa/include/asm/irq.h7
-rw-r--r--arch/xtensa/include/asm/mmu.h5
-rw-r--r--arch/xtensa/include/asm/mmu_context.h9
-rw-r--r--arch/xtensa/include/asm/nommu.h3
-rw-r--r--arch/xtensa/include/asm/nommu_context.h25
-rw-r--r--arch/xtensa/include/asm/page.h14
-rw-r--r--arch/xtensa/include/asm/pgtable.h13
-rw-r--r--arch/xtensa/include/asm/platform.h11
-rw-r--r--arch/xtensa/include/asm/processor.h8
-rw-r--r--arch/xtensa/include/asm/socket.h3
-rw-r--r--arch/xtensa/kernel/entry.S3
-rw-r--r--arch/xtensa/kernel/head.S5
-rw-r--r--arch/xtensa/kernel/irq.c16
-rw-r--r--arch/xtensa/kernel/platform.c2
-rw-r--r--arch/xtensa/kernel/process.c2
-rw-r--r--arch/xtensa/kernel/setup.c7
-rw-r--r--arch/xtensa/kernel/time.c131
-rw-r--r--arch/xtensa/kernel/traps.c16
-rw-r--r--arch/xtensa/kernel/vectors.S4
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S3
-rw-r--r--arch/xtensa/mm/Makefile3
-rw-r--r--arch/xtensa/mm/init.c78
-rw-r--r--arch/xtensa/mm/misc.S2
-rw-r--r--arch/xtensa/mm/mmu.c70
-rw-r--r--arch/xtensa/platforms/iss/console.c29
-rw-r--r--arch/xtensa/platforms/s6105/Makefile3
-rw-r--r--arch/xtensa/platforms/s6105/device.c67
-rw-r--r--arch/xtensa/platforms/s6105/include/platform/gpio.h27
-rw-r--r--arch/xtensa/platforms/s6105/include/platform/hardware.h11
-rw-r--r--arch/xtensa/platforms/s6105/include/platform/serial.h8
-rw-r--r--arch/xtensa/platforms/s6105/setup.c61
-rw-r--r--arch/xtensa/platforms/xt2000/include/platform/hardware.h1
-rw-r--r--arch/xtensa/variants/s6000/Makefile3
-rw-r--r--arch/xtensa/variants/s6000/gpio.c71
-rw-r--r--arch/xtensa/variants/s6000/include/variant/core.h431
-rw-r--r--arch/xtensa/variants/s6000/include/variant/hardware.h259
-rw-r--r--arch/xtensa/variants/s6000/include/variant/irq.h9
-rw-r--r--arch/xtensa/variants/s6000/include/variant/tie-asm.h304
-rw-r--r--arch/xtensa/variants/s6000/include/variant/tie.h191
-rw-r--r--arch/xtensa/variants/s6000/irq.c74
-rw-r--r--block/blk-core.c98
-rw-r--r--block/blk-merge.c2
-rw-r--r--block/blk-softirq.c2
-rw-r--r--block/blk-sysfs.c40
-rw-r--r--block/blk.h2
-rw-r--r--block/bsg.c12
-rw-r--r--block/cfq-iosched.c4
-rw-r--r--block/cmd-filter.c1
-rw-r--r--block/elevator.c2
-rw-r--r--block/scsi_ioctl.c21
-rw-r--r--crypto/Kconfig44
-rw-r--r--crypto/Makefile5
-rw-r--r--crypto/ablkcipher.c19
-rw-r--r--crypto/aead.c16
-rw-r--r--crypto/algboss.c20
-rw-r--r--crypto/ansi_cprng.c17
-rw-r--r--crypto/api.c17
-rw-r--r--crypto/async_tx/async_tx.c6
-rw-r--r--crypto/async_tx/async_xor.c7
-rw-r--r--crypto/blkcipher.c2
-rw-r--r--crypto/chainiv.c3
-rw-r--r--crypto/cryptd.c237
-rw-r--r--crypto/crypto_wq.c38
-rw-r--r--crypto/gf128mul.c2
-rw-r--r--crypto/internal.h6
-rw-r--r--crypto/pcompress.c97
-rw-r--r--crypto/sha256_generic.c2
-rw-r--r--crypto/shash.c23
-rw-r--r--crypto/tcrypt.c6
-rw-r--r--crypto/testmgr.c198
-rw-r--r--crypto/testmgr.h147
-rw-r--r--crypto/xor.c2
-rw-r--r--crypto/zlib.c378
-rw-r--r--drivers/Makefile5
-rw-r--r--drivers/acpi/Kconfig150
-rw-r--r--drivers/acpi/Makefile52
-rw-r--r--drivers/acpi/ac.c1
-rw-r--r--drivers/acpi/acpica/Makefile4
-rw-r--r--drivers/acpi/acpica/acglobal.h11
-rw-r--r--drivers/acpi/acpica/achware.h12
-rw-r--r--drivers/acpi/acpica/aclocal.h60
-rw-r--r--drivers/acpi/acpica/acmacros.h4
-rw-r--r--drivers/acpi/acpica/acobject.h1
-rw-r--r--drivers/acpi/acpica/acpredef.h41
-rw-r--r--drivers/acpi/acpica/actables.h9
-rw-r--r--drivers/acpi/acpica/acutils.h15
-rw-r--r--drivers/acpi/acpica/dsinit.c16
-rw-r--r--drivers/acpi/acpica/dsmthdat.c2
-rw-r--r--drivers/acpi/acpica/dsobject.c6
-rw-r--r--drivers/acpi/acpica/dsopcode.c32
-rw-r--r--drivers/acpi/acpica/dsutils.c2
-rw-r--r--drivers/acpi/acpica/dswexec.c5
-rw-r--r--drivers/acpi/acpica/evevent.c18
-rw-r--r--drivers/acpi/acpica/evgpe.c7
-rw-r--r--drivers/acpi/acpica/evgpeblk.c70
-rw-r--r--drivers/acpi/acpica/evmisc.c16
-rw-r--r--drivers/acpi/acpica/evregion.c5
-rw-r--r--drivers/acpi/acpica/evrgnini.c22
-rw-r--r--drivers/acpi/acpica/evxface.c3
-rw-r--r--drivers/acpi/acpica/evxfevnt.c24
-rw-r--r--drivers/acpi/acpica/evxfregn.c3
-rw-r--r--drivers/acpi/acpica/exconfig.c17
-rw-r--r--drivers/acpi/acpica/exconvrt.c11
-rw-r--r--drivers/acpi/acpica/exdump.c59
-rw-r--r--drivers/acpi/acpica/exfield.c29
-rw-r--r--drivers/acpi/acpica/exfldio.c14
-rw-r--r--drivers/acpi/acpica/exmisc.c14
-rw-r--r--drivers/acpi/acpica/exoparg1.c13
-rw-r--r--drivers/acpi/acpica/exoparg2.c2
-rw-r--r--drivers/acpi/acpica/exoparg3.c7
-rw-r--r--drivers/acpi/acpica/exprep.c2
-rw-r--r--drivers/acpi/acpica/exregion.c4
-rw-r--r--drivers/acpi/acpica/exresnte.c8
-rw-r--r--drivers/acpi/acpica/exresolv.c9
-rw-r--r--drivers/acpi/acpica/exresop.c23
-rw-r--r--drivers/acpi/acpica/exstore.c18
-rw-r--r--drivers/acpi/acpica/exstoren.c29
-rw-r--r--drivers/acpi/acpica/exutils.c2
-rw-r--r--drivers/acpi/acpica/hwacpi.c9
-rw-r--r--drivers/acpi/acpica/hwgpe.c21
-rw-r--r--drivers/acpi/acpica/hwregs.c322
-rw-r--r--drivers/acpi/acpica/hwsleep.c130
-rw-r--r--drivers/acpi/acpica/hwvalid.c258
-rw-r--r--drivers/acpi/acpica/hwxface.c279
-rw-r--r--drivers/acpi/acpica/nsaccess.c54
-rw-r--r--drivers/acpi/acpica/nsalloc.c24
-rw-r--r--drivers/acpi/acpica/nsdump.c24
-rw-r--r--drivers/acpi/acpica/nseval.c2
-rw-r--r--drivers/acpi/acpica/nsinit.c19
-rw-r--r--drivers/acpi/acpica/nsload.c4
-rw-r--r--drivers/acpi/acpica/nsobject.c18
-rw-r--r--drivers/acpi/acpica/nsparse.c10
-rw-r--r--drivers/acpi/acpica/nspredef.c38
-rw-r--r--drivers/acpi/acpica/nssearch.c14
-rw-r--r--drivers/acpi/acpica/nsutils.c27
-rw-r--r--drivers/acpi/acpica/nswalk.c12
-rw-r--r--drivers/acpi/acpica/nsxfeval.c36
-rw-r--r--drivers/acpi/acpica/rscalc.c7
-rw-r--r--drivers/acpi/acpica/rscreate.c15
-rw-r--r--drivers/acpi/acpica/tbfadt.c363
-rw-r--r--drivers/acpi/acpica/tbinstal.c82
-rw-r--r--drivers/acpi/acpica/tbutils.c106
-rw-r--r--drivers/acpi/acpica/tbxface.c71
-rw-r--r--drivers/acpi/acpica/tbxfroot.c4
-rw-r--r--drivers/acpi/acpica/utcopy.c30
-rw-r--r--drivers/acpi/acpica/utdelete.c6
-rw-r--r--drivers/acpi/acpica/uteval.c98
-rw-r--r--drivers/acpi/acpica/utglobal.c17
-rw-r--r--drivers/acpi/acpica/utlock.c175
-rw-r--r--drivers/acpi/acpica/utmisc.c3
-rw-r--r--drivers/acpi/acpica/utmutex.c23
-rw-r--r--drivers/acpi/acpica/utobject.c11
-rw-r--r--drivers/acpi/battery.c30
-rw-r--r--drivers/acpi/bus.c15
-rw-r--r--drivers/acpi/button.c80
-rw-r--r--drivers/acpi/debug.c19
-rw-r--r--drivers/acpi/dock.c5
-rw-r--r--drivers/acpi/ec.c39
-rw-r--r--drivers/acpi/event.c6
-rw-r--r--drivers/acpi/fan.c22
-rw-r--r--drivers/acpi/glue.c6
-rw-r--r--drivers/acpi/internal.h43
-rw-r--r--drivers/acpi/numa.c46
-rw-r--r--drivers/acpi/osl.c6
-rw-r--r--drivers/acpi/pci_irq.c18
-rw-r--r--drivers/acpi/pci_link.c147
-rw-r--r--drivers/acpi/pci_root.c180
-rw-r--r--drivers/acpi/power.c12
-rw-r--r--drivers/acpi/proc.c7
-rw-r--r--drivers/acpi/processor_core.c47
-rw-r--r--drivers/acpi/processor_idle.c124
-rw-r--r--drivers/acpi/processor_perflib.c46
-rw-r--r--drivers/acpi/processor_thermal.c22
-rw-r--r--drivers/acpi/processor_throttling.c8
-rw-r--r--drivers/acpi/sbs.c42
-rw-r--r--drivers/acpi/scan.c94
-rw-r--r--drivers/acpi/sleep.c13
-rw-r--r--drivers/acpi/system.c64
-rw-r--r--drivers/acpi/tables.c30
-rw-r--r--drivers/acpi/thermal.c543
-rw-r--r--drivers/acpi/video.c341
-rw-r--r--drivers/acpi/video_detect.c3
-rw-r--r--drivers/acpi/wakeup.c9
-rw-r--r--drivers/amba/bus.c4
-rw-r--r--drivers/ata/Kconfig2
-rw-r--r--drivers/ata/ahci.c31
-rw-r--r--drivers/ata/ata_generic.c4
-rw-r--r--drivers/ata/ata_piix.c60
-rw-r--r--drivers/ata/libata-core.c14
-rw-r--r--drivers/ata/libata-eh.c19
-rw-r--r--drivers/ata/libata-sff.c91
-rw-r--r--drivers/ata/libata.h2
-rw-r--r--drivers/ata/pata_acpi.c6
-rw-r--r--drivers/ata/pata_ali.c28
-rw-r--r--drivers/ata/pata_amd.c70
-rw-r--r--drivers/ata/pata_artop.c49
-rw-r--r--drivers/ata/pata_at32.c4
-rw-r--r--drivers/ata/pata_atiixp.c6
-rw-r--r--drivers/ata/pata_bf54x.c2
-rw-r--r--drivers/ata/pata_cmd640.c2
-rw-r--r--drivers/ata/pata_cmd64x.c24
-rw-r--r--drivers/ata/pata_cs5520.c2
-rw-r--r--drivers/ata/pata_cs5530.c8
-rw-r--r--drivers/ata/pata_cs5535.c4
-rw-r--r--drivers/ata/pata_cs5536.c4
-rw-r--r--drivers/ata/pata_cypress.c4
-rw-r--r--drivers/ata/pata_efar.c6
-rw-r--r--drivers/ata/pata_hpt366.c4
-rw-r--r--drivers/ata/pata_hpt37x.c28
-rw-r--r--drivers/ata/pata_hpt3x2n.c4
-rw-r--r--drivers/ata/pata_hpt3x3.c6
-rw-r--r--drivers/ata/pata_icside.c23
-rw-r--r--drivers/ata/pata_isapnp.c14
-rw-r--r--drivers/ata/pata_it8213.c4
-rw-r--r--drivers/ata/pata_it821x.c16
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c2
-rw-r--r--drivers/ata/pata_jmicron.c4
-rw-r--r--drivers/ata/pata_legacy.c2
-rw-r--r--drivers/ata/pata_marvell.c8
-rw-r--r--drivers/ata/pata_mpc52xx.c4
-rw-r--r--drivers/ata/pata_mpiix.c2
-rw-r--r--drivers/ata/pata_netcell.c4
-rw-r--r--drivers/ata/pata_ninja32.c2
-rw-r--r--drivers/ata/pata_ns87410.c2
-rw-r--r--drivers/ata/pata_ns87415.c8
-rw-r--r--drivers/ata/pata_octeon_cf.c4
-rw-r--r--drivers/ata/pata_oldpiix.c4
-rw-r--r--drivers/ata/pata_opti.c2
-rw-r--r--drivers/ata/pata_optidma.c10
-rw-r--r--drivers/ata/pata_pcmcia.c36
-rw-r--r--drivers/ata/pata_pdc2027x.c12
-rw-r--r--drivers/ata/pata_pdc202xx_old.c12
-rw-r--r--drivers/ata/pata_qdi.c4
-rw-r--r--drivers/ata/pata_radisys.c6
-rw-r--r--drivers/ata/pata_rb532_cf.c64
-rw-r--r--drivers/ata/pata_rz1000.c2
-rw-r--r--drivers/ata/pata_sc1200.c35
-rw-r--r--drivers/ata/pata_scc.c4
-rw-r--r--drivers/ata/pata_sch.c6
-rw-r--r--drivers/ata/pata_serverworks.c20
-rw-r--r--drivers/ata/pata_sil680.c8
-rw-r--r--drivers/ata/pata_sis.c32
-rw-r--r--drivers/ata/pata_sl82c105.c6
-rw-r--r--drivers/ata/pata_triflex.c4
-rw-r--r--drivers/ata/pata_via.c24
-rw-r--r--drivers/ata/pata_winbond.c2
-rw-r--r--drivers/ata/pdc_adma.c4
-rw-r--r--drivers/ata/sata_fsl.c4
-rw-r--r--drivers/ata/sata_inic162x.c4
-rw-r--r--drivers/ata/sata_mv.c868
-rw-r--r--drivers/ata/sata_nv.c7
-rw-r--r--drivers/ata/sata_promise.c30
-rw-r--r--drivers/ata/sata_qstor.c3
-rw-r--r--drivers/ata/sata_sil.c16
-rw-r--r--drivers/ata/sata_sil24.c18
-rw-r--r--drivers/ata/sata_sis.c4
-rw-r--r--drivers/ata/sata_svw.c16
-rw-r--r--drivers/ata/sata_sx4.c4
-rw-r--r--drivers/ata/sata_uli.c2
-rw-r--r--drivers/ata/sata_via.c16
-rw-r--r--drivers/ata/sata_vsc.c7
-rw-r--r--drivers/atm/firestream.c8
-rw-r--r--drivers/atm/iphase.c4
-rw-r--r--drivers/atm/solos-attrlist.c70
-rw-r--r--drivers/atm/solos-pci.c824
-rw-r--r--drivers/auxdisplay/Kconfig3
-rw-r--r--drivers/base/base.h31
-rw-r--r--drivers/base/bus.c44
-rw-r--r--drivers/base/core.c108
-rw-r--r--drivers/base/cpu.c2
-rw-r--r--drivers/base/dd.c40
-rw-r--r--drivers/base/driver.c15
-rw-r--r--drivers/base/firmware_class.c4
-rw-r--r--drivers/base/iommu.c9
-rw-r--r--drivers/base/node.c2
-rw-r--r--drivers/base/platform.c60
-rw-r--r--drivers/base/power/main.c64
-rw-r--r--drivers/base/power/power.h8
-rw-r--r--drivers/base/sys.c64
-rw-r--r--drivers/block/Kconfig7
-rw-r--r--drivers/block/Makefile3
-rw-r--r--drivers/block/aoe/aoecmd.c23
-rw-r--r--drivers/block/aoe/aoenet.c2
-rw-r--r--drivers/block/cciss.c7
-rw-r--r--drivers/block/cpqarray.c1
-rw-r--r--drivers/block/floppy.c11
-rw-r--r--drivers/block/hd.c2
-rw-r--r--drivers/block/loop.c78
-rw-r--r--drivers/block/nbd.c112
-rw-r--r--drivers/block/ps3vram.c2
-rw-r--r--drivers/block/swim.c995
-rw-r--r--drivers/block/swim_asm.S247
-rw-r--r--drivers/block/ub.c11
-rw-r--r--drivers/block/xsysace.c30
-rw-r--r--drivers/bluetooth/bfusb.c3
-rw-r--r--drivers/bluetooth/bt3c_cs.c4
-rw-r--r--drivers/bluetooth/btusb.c40
-rw-r--r--drivers/bluetooth/hci_h4.c3
-rw-r--r--drivers/bluetooth/hci_ll.c3
-rw-r--r--drivers/char/agp/intel-agp.c21
-rw-r--r--drivers/char/amiserial.c62
-rw-r--r--drivers/char/applicom.c1
-rw-r--r--drivers/char/bsr.c2
-rw-r--r--drivers/char/cyclades.c56
-rw-r--r--drivers/char/hpet.c22
-rw-r--r--drivers/char/hvc_iucv.c259
-rw-r--r--drivers/char/hw_random/Kconfig14
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/omap-rng.c2
-rw-r--r--drivers/char/hw_random/timeriomem-rng.c182
-rw-r--r--drivers/char/ip2/ip2main.c74
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c12
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c6
-rw-r--r--drivers/char/isicom.c1
-rw-r--r--drivers/char/istallion.c121
-rw-r--r--drivers/char/moxa.c9
-rw-r--r--drivers/char/mxser.c1
-rw-r--r--drivers/char/pcmcia/synclink_cs.c91
-rw-r--r--drivers/char/random.c9
-rw-r--r--drivers/char/raw.c1
-rw-r--r--drivers/char/rio/rio_linux.c2
-rw-r--r--drivers/char/riscom8.c2
-rw-r--r--drivers/char/sonypi.c7
-rw-r--r--drivers/char/specialix.c1
-rw-r--r--drivers/char/stallion.c126
-rw-r--r--drivers/char/synclink.c116
-rw-r--r--drivers/char/synclink_gt.c150
-rw-r--r--drivers/char/synclinkmp.c92
-rw-r--r--drivers/char/sysrq.c21
-rw-r--r--drivers/char/tpm/tpm.c530
-rw-r--r--drivers/char/tpm/tpm.h142
-rw-r--r--drivers/char/tpm/tpm_atmel.c28
-rw-r--r--drivers/char/tpm/tpm_tis.c28
-rw-r--r--drivers/char/tty_audit.c2
-rw-r--r--drivers/char/tty_io.c31
-rw-r--r--drivers/char/tty_ldisc.c1
-rw-r--r--drivers/char/vc_screen.c16
-rw-r--r--drivers/char/vt.c5
-rw-r--r--drivers/clocksource/Makefile1
-rw-r--r--drivers/clocksource/sh_cmt.c614
-rw-r--r--drivers/connector/cn_queue.c80
-rw-r--r--drivers/connector/connector.c19
-rw-r--r--drivers/cpufreq/cpufreq.c55
-rw-r--r--drivers/cpufreq/cpufreq_conservative.c404
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c74
-rw-r--r--drivers/cpufreq/cpufreq_stats.c74
-rw-r--r--drivers/cpufreq/cpufreq_userspace.c27
-rw-r--r--drivers/cpufreq/freq_table.c18
-rw-r--r--drivers/crypto/Kconfig15
-rw-r--r--drivers/crypto/Makefile1
-rw-r--r--drivers/crypto/amcc/Makefile2
-rw-r--r--drivers/crypto/amcc/crypto4xx_alg.c293
-rw-r--r--drivers/crypto/amcc/crypto4xx_core.c1310
-rw-r--r--drivers/crypto/amcc/crypto4xx_core.h177
-rw-r--r--drivers/crypto/amcc/crypto4xx_reg_def.h284
-rw-r--r--drivers/crypto/amcc/crypto4xx_sa.c108
-rw-r--r--drivers/crypto/amcc/crypto4xx_sa.h243
-rw-r--r--drivers/crypto/hifn_795x.c2
-rw-r--r--drivers/crypto/ixp4xx_crypto.c182
-rw-r--r--drivers/dca/dca-sysfs.c21
-rw-r--r--drivers/dio/dio.c4
-rw-r--r--drivers/dma/Kconfig11
-rw-r--r--drivers/dma/dmaengine.c60
-rw-r--r--drivers/dma/dmatest.c307
-rw-r--r--drivers/dma/dw_dmac.c335
-rw-r--r--drivers/dma/dw_dmac_regs.h7
-rw-r--r--drivers/dma/fsldma.c1
-rw-r--r--drivers/dma/ioat_dma.c1
-rw-r--r--drivers/dma/iop-adma.c1
-rw-r--r--drivers/dma/ipu/ipu_idmac.c373
-rw-r--r--drivers/dma/ipu/ipu_irq.c2
-rw-r--r--drivers/dma/mv_xor.c1
-rw-r--r--drivers/edac/Kconfig36
-rw-r--r--drivers/edac/Makefile2
-rw-r--r--drivers/edac/amd8111_edac.c595
-rw-r--r--drivers/edac/amd8111_edac.h130
-rw-r--r--drivers/edac/amd8131_edac.c379
-rw-r--r--drivers/edac/amd8131_edac.h119
-rw-r--r--drivers/edac/cell_edac.c2
-rw-r--r--drivers/edac/edac_core.h16
-rw-r--r--drivers/edac/edac_pci.c14
-rw-r--r--drivers/edac/mpc85xx_edac.c2
-rw-r--r--drivers/edac/mv64x60_edac.c8
-rw-r--r--drivers/edac/ppc4xx_edac.c1448
-rw-r--r--drivers/edac/ppc4xx_edac.h172
-rw-r--r--drivers/eisa/eisa-bus.c4
-rw-r--r--drivers/firewire/fw-card.c149
-rw-r--r--drivers/firewire/fw-cdev.c1044
-rw-r--r--drivers/firewire/fw-device.c203
-rw-r--r--drivers/firewire/fw-device.h23
-rw-r--r--drivers/firewire/fw-iso.c227
-rw-r--r--drivers/firewire/fw-ohci.c260
-rw-r--r--drivers/firewire/fw-sbp2.c57
-rw-r--r--drivers/firewire/fw-topology.c29
-rw-r--r--drivers/firewire/fw-topology.h19
-rw-r--r--drivers/firewire/fw-transaction.c185
-rw-r--r--drivers/firewire/fw-transaction.h138
-rw-r--r--drivers/firmware/dmi_scan.c18
-rw-r--r--drivers/gpio/Kconfig6
-rw-r--r--drivers/gpio/bt8xxgpio.c2
-rw-r--r--drivers/gpio/gpiolib.c19
-rw-r--r--drivers/gpu/drm/Makefile3
-rw-r--r--drivers/gpu/drm/ati_pcigart.c40
-rw-r--r--drivers/gpu/drm/drm_bufs.c122
-rw-r--r--drivers/gpu/drm/drm_context.c4
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c31
-rw-r--r--drivers/gpu/drm/drm_debugfs.c235
-rw-r--r--drivers/gpu/drm/drm_drv.c100
-rw-r--r--drivers/gpu/drm/drm_edid.c191
-rw-r--r--drivers/gpu/drm/drm_fops.c7
-rw-r--r--drivers/gpu/drm/drm_gem.c9
-rw-r--r--drivers/gpu/drm/drm_info.c328
-rw-r--r--drivers/gpu/drm/drm_ioc32.c4
-rw-r--r--drivers/gpu/drm/drm_memory.c6
-rw-r--r--drivers/gpu/drm/drm_proc.c720
-rw-r--r--drivers/gpu/drm/drm_stub.c108
-rw-r--r--drivers/gpu/drm/drm_sysfs.c42
-rw-r--r--drivers/gpu/drm/drm_vm.c32
-rw-r--r--drivers/gpu/drm/i810/i810_drv.h4
-rw-r--r--drivers/gpu/drm/i830/i830_drv.h4
-rw-r--r--drivers/gpu/drm/i915/Makefile2
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c134
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c46
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h30
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c937
-rw-r--r--drivers/gpu/drm/i915/i915_gem_debug.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_debugfs.c263
-rw-r--r--drivers/gpu/drm/i915/i915_gem_proc.c334
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c47
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c67
-rw-r--r--drivers/gpu/drm/i915/i915_opregion.c65
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h33
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h12
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c68
-rw-r--r--drivers/gpu/drm/i915/intel_display.c428
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c2
-rw-r--r--drivers/gpu/drm/i915/intel_modes.c1
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c193
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo_regs.h3
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c178
-rw-r--r--drivers/gpu/drm/mga/mga_dma.c17
-rw-r--r--drivers/gpu/drm/mga/mga_drv.h8
-rw-r--r--drivers/gpu/drm/r128/r128_cce.c7
-rw-r--r--drivers/gpu/drm/radeon/Makefile2
-rw-r--r--drivers/gpu/drm/radeon/r300_cmdbuf.c11
-rw-r--r--drivers/gpu/drm/radeon/r300_reg.h5
-rw-r--r--drivers/gpu/drm/radeon/r600_cp.c2253
-rw-r--r--drivers/gpu/drm/radeon/r600_microcode.h23297
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c522
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c22
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.h635
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon_state.c51
-rw-r--r--drivers/gpu/drm/savage/savage_bci.c8
-rw-r--r--drivers/gpu/drm/via/via_drv.c6
-rw-r--r--drivers/hid/Kconfig42
-rw-r--r--drivers/hid/Makefile7
-rw-r--r--drivers/hid/hid-a4tech.c2
-rw-r--r--drivers/hid/hid-apple.c26
-rw-r--r--drivers/hid/hid-belkin.c2
-rw-r--r--drivers/hid/hid-cherry.c2
-rw-r--r--drivers/hid/hid-chicony.c2
-rw-r--r--drivers/hid/hid-core.c37
-rw-r--r--drivers/hid/hid-cypress.c2
-rw-r--r--drivers/hid/hid-drff.c188
-rw-r--r--drivers/hid/hid-dummy.c78
-rw-r--r--drivers/hid/hid-ezkey.c2
-rw-r--r--drivers/hid/hid-gaff.c2
-rw-r--r--drivers/hid/hid-gyration.c2
-rw-r--r--drivers/hid/hid-ids.h10
-rw-r--r--drivers/hid/hid-kensington.c63
-rw-r--r--drivers/hid/hid-kye.c69
-rw-r--r--drivers/hid/hid-lg.c2
-rw-r--r--drivers/hid/hid-microsoft.c2
-rw-r--r--drivers/hid/hid-monterey.c2
-rw-r--r--drivers/hid/hid-ntrig.c2
-rw-r--r--drivers/hid/hid-petalynx.c2
-rw-r--r--drivers/hid/hid-pl.c52
-rw-r--r--drivers/hid/hid-samsung.c2
-rw-r--r--drivers/hid/hid-sony.c2
-rw-r--r--drivers/hid/hid-sunplus.c2
-rw-r--r--drivers/hid/hid-tmff.c2
-rw-r--r--drivers/hid/hid-topseed.c2
-rw-r--r--drivers/hid/hid-zpff.c2
-rw-r--r--drivers/hid/hidraw.c17
-rw-r--r--drivers/hid/usbhid/hid-core.c475
-rw-r--r--drivers/hid/usbhid/hiddev.c27
-rw-r--r--drivers/hid/usbhid/usbhid.h14
-rw-r--r--drivers/hwmon/Kconfig63
-rw-r--r--drivers/hwmon/Makefile4
-rw-r--r--drivers/hwmon/ds1621.c172
-rw-r--r--drivers/hwmon/f75375s.c4
-rw-r--r--drivers/hwmon/fschmd.c229
-rw-r--r--drivers/hwmon/hdaps.c66
-rw-r--r--drivers/hwmon/hp_accel.c124
-rw-r--r--drivers/hwmon/lis3lv02d.c288
-rw-r--r--drivers/hwmon/lis3lv02d.h20
-rw-r--r--drivers/hwmon/lis3lv02d_spi.c114
-rw-r--r--drivers/hwmon/lm95241.c527
-rw-r--r--drivers/hwmon/ltc4215.c364
-rw-r--r--drivers/hwmon/pcf8591.c (renamed from drivers/i2c/chips/pcf8591.c)24
-rw-r--r--drivers/hwmon/w83627ehf.c170
-rw-r--r--drivers/i2c/algos/Kconfig4
-rw-r--r--drivers/i2c/algos/Makefile1
-rw-r--r--drivers/i2c/algos/i2c-algo-bit.c4
-rw-r--r--drivers/i2c/algos/i2c-algo-pca.c250
-rw-r--r--drivers/i2c/algos/i2c-algo-pcf.c261
-rw-r--r--drivers/i2c/algos/i2c-algo-sgi.c179
-rw-r--r--drivers/i2c/busses/Kconfig9
-rw-r--r--drivers/i2c/busses/i2c-acorn.c2
-rw-r--r--drivers/i2c/busses/i2c-davinci.c8
-rw-r--r--drivers/i2c/busses/i2c-i801.c77
-rw-r--r--drivers/i2c/busses/i2c-ibm_iic.c6
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.c2
-rw-r--r--drivers/i2c/busses/i2c-mpc.c13
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c7
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c12
-rw-r--r--drivers/i2c/busses/i2c-omap.c47
-rw-r--r--drivers/i2c/busses/i2c-pca-isa.c39
-rw-r--r--drivers/i2c/busses/i2c-pca-platform.c48
-rw-r--r--drivers/i2c/busses/i2c-piix4.c77
-rw-r--r--drivers/i2c/busses/i2c-powermac.c3
-rw-r--r--drivers/i2c/busses/i2c-pxa.c9
-rw-r--r--drivers/i2c/busses/i2c-versatile.c10
-rw-r--r--drivers/i2c/chips/Kconfig13
-rw-r--r--drivers/i2c/chips/Makefile1
-rw-r--r--drivers/i2c/i2c-core.c38
-rw-r--r--drivers/ide/Kconfig41
-rw-r--r--drivers/ide/Makefile6
-rw-r--r--drivers/ide/aec62xx.c4
-rw-r--r--drivers/ide/alim15x3.c17
-rw-r--r--drivers/ide/amd74xx.c14
-rw-r--r--drivers/ide/at91_ide.c101
-rw-r--r--drivers/ide/atiixp.c3
-rw-r--r--drivers/ide/au1xxx-ide.c95
-rw-r--r--drivers/ide/buddha.c11
-rw-r--r--drivers/ide/cmd64x.c14
-rw-r--r--drivers/ide/cs5520.c3
-rw-r--r--drivers/ide/cs5530.c5
-rw-r--r--drivers/ide/cs5536.c3
-rw-r--r--drivers/ide/delkin_cb.c3
-rw-r--r--drivers/ide/dtc2278.c3
-rw-r--r--drivers/ide/falconide.c49
-rw-r--r--drivers/ide/gayle.c19
-rw-r--r--drivers/ide/hpt366.c20
-rw-r--r--drivers/ide/ht6560b.c20
-rw-r--r--drivers/ide/icside.c32
-rw-r--r--drivers/ide/ide-4drives.c3
-rw-r--r--drivers/ide/ide-acpi.c214
-rw-r--r--drivers/ide/ide-atapi.c242
-rw-r--r--drivers/ide/ide-cd.c648
-rw-r--r--drivers/ide/ide-cd.h4
-rw-r--r--drivers/ide/ide-cs.c1
-rw-r--r--drivers/ide/ide-devsets.c188
-rw-r--r--drivers/ide/ide-disk.c175
-rw-r--r--drivers/ide/ide-disk_proc.c28
-rw-r--r--drivers/ide/ide-dma-sff.c52
-rw-r--r--drivers/ide/ide-dma.c176
-rw-r--r--drivers/ide/ide-eh.c440
-rw-r--r--drivers/ide/ide-floppy.c177
-rw-r--r--drivers/ide/ide-floppy_ioctl.c5
-rw-r--r--drivers/ide/ide-gd.c10
-rw-r--r--drivers/ide/ide-gd.h4
-rw-r--r--drivers/ide/ide-generic.c88
-rw-r--r--drivers/ide/ide-h8300.c94
-rw-r--r--drivers/ide/ide-io-std.c301
-rw-r--r--drivers/ide/ide-io.c612
-rw-r--r--drivers/ide/ide-ioctls.c44
-rw-r--r--drivers/ide/ide-iops.c835
-rw-r--r--drivers/ide/ide-lib.c260
-rw-r--r--drivers/ide/ide-park.c26
-rw-r--r--drivers/ide/ide-pci-generic.c4
-rw-r--r--drivers/ide/ide-pm.c47
-rw-r--r--drivers/ide/ide-pnp.c6
-rw-r--r--drivers/ide/ide-probe.c379
-rw-r--r--drivers/ide/ide-proc.c18
-rw-r--r--drivers/ide/ide-tape.c159
-rw-r--r--drivers/ide/ide-taskfile.c508
-rw-r--r--drivers/ide/ide-timings.c12
-rw-r--r--drivers/ide/ide-xfer-mode.c249
-rw-r--r--drivers/ide/ide.c156
-rw-r--r--drivers/ide/ide_arm.c49
-rw-r--r--drivers/ide/it821x.c5
-rw-r--r--drivers/ide/macide.c7
-rw-r--r--drivers/ide/ns87415.c117
-rw-r--r--drivers/ide/palm_bk3710.c13
-rw-r--r--drivers/ide/pdc202xx_new.c4
-rw-r--r--drivers/ide/pdc202xx_old.c18
-rw-r--r--drivers/ide/piix.c13
-rw-r--r--drivers/ide/pmac.c129
-rw-r--r--drivers/ide/q40ide.c19
-rw-r--r--drivers/ide/qd65xx.c21
-rw-r--r--drivers/ide/sc1200.c9
-rw-r--r--drivers/ide/scc_pata.c161
-rw-r--r--drivers/ide/serverworks.c13
-rw-r--r--drivers/ide/setup-pci.c31
-rw-r--r--drivers/ide/sgiioc4.c50
-rw-r--r--drivers/ide/siimage.c5
-rw-r--r--drivers/ide/sis5513.c4
-rw-r--r--drivers/ide/sl82c105.c16
-rw-r--r--drivers/ide/slc90e66.c1
-rw-r--r--drivers/ide/tc86c001.c3
-rw-r--r--drivers/ide/trm290.c67
-rw-r--r--drivers/ide/tx4938ide.c103
-rw-r--r--drivers/ide/tx4939ide.c161
-rw-r--r--drivers/ide/via82cxxx.c12
-rw-r--r--drivers/ieee1394/csr.c8
-rw-r--r--drivers/ieee1394/dv1394.c8
-rw-r--r--drivers/ieee1394/eth1394.c4
-rw-r--r--drivers/ieee1394/highlevel.c2
-rw-r--r--drivers/ieee1394/nodemgr.c4
-rw-r--r--drivers/ieee1394/nodemgr.h2
-rw-r--r--drivers/ieee1394/raw1394.c14
-rw-r--r--drivers/ieee1394/sbp2.c9
-rw-r--r--drivers/ieee1394/video1394.c2
-rw-r--r--drivers/infiniband/core/cm.c15
-rw-r--r--drivers/infiniband/core/cm_msgs.h22
-rw-r--r--drivers/infiniband/core/device.c4
-rw-r--r--drivers/infiniband/core/mad.c40
-rw-r--r--drivers/infiniband/core/mad_rmpp.c2
-rw-r--r--drivers/infiniband/core/sa_query.c2
-rw-r--r--drivers/infiniband/core/sysfs.c19
-rw-r--r--drivers/infiniband/hw/amso1100/c2.c41
-rw-r--r--drivers/infiniband/hw/amso1100/c2.h2
-rw-r--r--drivers/infiniband/hw/amso1100/c2_provider.c22
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.c33
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.h5
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_wr.h6
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch.c15
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c3
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_ev.c5
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_qp.c17
-rw-r--r--drivers/infiniband/hw/ehca/ehca_sqp.c8
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c6
-rw-r--r--drivers/infiniband/hw/ipath/ipath_eeprom.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_init_chip.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mad.c95
-rw-r--r--drivers/infiniband/hw/ipath/ipath_rc.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_sdma.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_uc.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ud.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_user_pages.c8
-rw-r--r--drivers/infiniband/hw/ipath/ipath_user_sdma.c6
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.h10
-rw-r--r--drivers/infiniband/hw/mlx4/mad.c27
-rw-r--r--drivers/infiniband/hw/mlx4/main.c5
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c22
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mad.c25
-rw-r--r--drivers/infiniband/hw/nes/nes.c2
-rw-r--r--drivers/infiniband/hw/nes/nes.h2
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c586
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.h12
-rw-r--r--drivers/infiniband/hw/nes/nes_context.h2
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c19
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.h5
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c173
-rw-r--r--drivers/infiniband/hw/nes/nes_user.h2
-rw-r--r--drivers/infiniband/hw/nes/nes_utils.c2
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.c249
-rw-r--r--drivers/infiniband/hw/nes/nes_verbs.h2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c6
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c27
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c17
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h2
-rw-r--r--drivers/infiniband/ulp/iser/iser_initiator.c2
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c7
-rw-r--r--drivers/input/Kconfig2
-rw-r--r--drivers/input/evdev.c5
-rw-r--r--drivers/input/input.c2
-rw-r--r--drivers/input/joydev.c5
-rw-r--r--drivers/input/joystick/maplecontrol.c4
-rw-r--r--drivers/input/keyboard/corgikbd.c2
-rw-r--r--drivers/input/keyboard/maple_keyb.c37
-rw-r--r--drivers/input/keyboard/sh_keysc.c41
-rw-r--r--drivers/input/keyboard/spitzkbd.c2
-rw-r--r--drivers/input/mouse/gpio_mouse.c2
-rw-r--r--drivers/input/mouse/hgpk.c2
-rw-r--r--drivers/input/mouse/rpcmouse.c2
-rw-r--r--drivers/input/mousedev.c5
-rw-r--r--drivers/input/serio/rpckbd.c2
-rw-r--r--drivers/input/serio/serio_raw.c4
-rw-r--r--drivers/input/touchscreen/ads7846.c2
-rw-r--r--drivers/input/touchscreen/corgi_ts.c1
-rw-r--r--drivers/input/touchscreen/migor_ts.c23
-rw-r--r--drivers/isdn/act2000/act2000_isa.c6
-rw-r--r--drivers/isdn/capi/capi.c9
-rw-r--r--drivers/isdn/capi/kcapi_proc.c2
-rw-r--r--drivers/isdn/gigaset/Kconfig14
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c16
-rw-r--r--drivers/isdn/gigaset/ser-gigaset.c3
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c8
-rw-r--r--drivers/isdn/hardware/eicon/debug.c2
-rw-r--r--drivers/isdn/hardware/eicon/divasi.c1
-rw-r--r--drivers/isdn/hardware/eicon/message.c70
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c4
-rw-r--r--drivers/isdn/hardware/mISDN/hfcsusb.c6
-rw-r--r--drivers/isdn/hardware/mISDN/hfcsusb.h6
-rw-r--r--drivers/isdn/hisax/callc.c1
-rw-r--r--drivers/isdn/hisax/config.c6
-rw-r--r--drivers/isdn/hisax/hfcscard.c2
-rw-r--r--drivers/isdn/hisax/hisax.h9
-rw-r--r--drivers/isdn/hisax/isdnl1.c4
-rw-r--r--drivers/isdn/hisax/sedlbauer.c2
-rw-r--r--drivers/isdn/hisax/teles0.c2
-rw-r--r--drivers/isdn/hisax/teles3.c1
-rw-r--r--drivers/isdn/mISDN/Kconfig10
-rw-r--r--drivers/isdn/mISDN/clock.c10
-rw-r--r--drivers/isdn/mISDN/l1oip_codec.c2
-rw-r--r--drivers/isdn/mISDN/timerdev.c3
-rw-r--r--drivers/isdn/pcbit/layer2.c6
-rw-r--r--drivers/leds/Kconfig84
-rw-r--r--drivers/leds/Makefile7
-rw-r--r--drivers/leds/led-class.c21
-rw-r--r--drivers/leds/led-triggers.c10
-rw-r--r--drivers/leds/leds-bd2802.c765
-rw-r--r--drivers/leds/leds-dac124s085.c150
-rw-r--r--drivers/leds/leds-gpio.c225
-rw-r--r--drivers/leds/leds-h1940.c2
-rw-r--r--drivers/leds/leds-pca9532.c6
-rw-r--r--drivers/leds/leds-pwm.c153
-rw-r--r--drivers/leds/leds-rb532.c77
-rw-r--r--drivers/leds/leds-s3c24xx.c7
-rw-r--r--drivers/leds/leds.h4
-rw-r--r--drivers/leds/ledtrig-default-on.c2
-rw-r--r--drivers/leds/ledtrig-gpio.c239
-rw-r--r--drivers/leds/ledtrig-heartbeat.c4
-rw-r--r--drivers/leds/ledtrig-ide-disk.c3
-rw-r--r--drivers/leds/ledtrig-timer.c2
-rw-r--r--drivers/lguest/core.c4
-rw-r--r--drivers/lguest/interrupts_and_traps.c28
-rw-r--r--drivers/lguest/lg.h8
-rw-r--r--drivers/lguest/lguest_device.c4
-rw-r--r--drivers/lguest/page_tables.c22
-rw-r--r--drivers/lguest/segments.c2
-rw-r--r--drivers/lguest/x86/core.c62
-rw-r--r--drivers/macintosh/therm_adt746x.c4
-rw-r--r--drivers/mca/mca-bus.c4
-rw-r--r--drivers/md/Kconfig31
-rw-r--r--drivers/md/Makefile16
-rw-r--r--drivers/md/bitmap.c49
-rw-r--r--drivers/md/bitmap.h (renamed from include/linux/raid/bitmap.h)0
-rw-r--r--drivers/md/dm-bio-list.h10
-rw-r--r--drivers/md/dm-bio-record.h26
-rw-r--r--drivers/md/dm-crypt.c6
-rw-r--r--drivers/md/dm-exception-store.c252
-rw-r--r--drivers/md/dm-exception-store.h58
-rw-r--r--drivers/md/dm-io.c5
-rw-r--r--drivers/md/dm-log.c75
-rw-r--r--drivers/md/dm-path-selector.c21
-rw-r--r--drivers/md/dm-raid1.c50
-rw-r--r--drivers/md/dm-snap-persistent.c153
-rw-r--r--drivers/md/dm-snap-transient.c86
-rw-r--r--drivers/md/dm-snap.c384
-rw-r--r--drivers/md/dm-snap.h105
-rw-r--r--drivers/md/dm-table.c26
-rw-r--r--drivers/md/dm-target.c104
-rw-r--r--drivers/md/dm.c134
-rw-r--r--drivers/md/dm.h2
-rw-r--r--drivers/md/faulty.c19
-rw-r--r--drivers/md/linear.c25
-rw-r--r--drivers/md/linear.h (renamed from include/linux/raid/linear.h)2
-rw-r--r--drivers/md/md.c615
-rw-r--r--drivers/md/md.h (renamed from include/linux/raid/md_k.h)66
-rw-r--r--drivers/md/mktables.c14
-rw-r--r--drivers/md/multipath.c17
-rw-r--r--drivers/md/multipath.h (renamed from include/linux/raid/multipath.h)2
-rw-r--r--drivers/md/raid0.c66
-rw-r--r--drivers/md/raid0.h (renamed from include/linux/raid/raid0.h)2
-rw-r--r--drivers/md/raid1.c44
-rw-r--r--drivers/md/raid1.h (renamed from include/linux/raid/raid1.h)2
-rw-r--r--drivers/md/raid10.c42
-rw-r--r--drivers/md/raid10.h (renamed from include/linux/raid/raid10.h)2
-rw-r--r--drivers/md/raid5.c1494
-rw-r--r--drivers/md/raid5.h (renamed from include/linux/raid/raid5.h)110
-rw-r--r--drivers/md/raid6algos.c21
-rw-r--r--drivers/md/raid6altivec.uc4
-rw-r--r--drivers/md/raid6int.uc4
-rw-r--r--drivers/md/raid6mmx.c4
-rw-r--r--drivers/md/raid6recov.c13
-rw-r--r--drivers/md/raid6sse1.c4
-rw-r--r--drivers/md/raid6sse2.c4
-rw-r--r--drivers/md/raid6test/Makefile2
-rw-r--r--drivers/md/raid6test/test.c2
-rw-r--r--drivers/md/raid6x86.h2
-rw-r--r--drivers/media/Kconfig2
-rw-r--r--drivers/media/common/ir-keymaps.c146
-rw-r--r--drivers/media/common/saa7146_core.c15
-rw-r--r--drivers/media/common/saa7146_fops.c48
-rw-r--r--drivers/media/common/saa7146_i2c.c29
-rw-r--r--drivers/media/common/saa7146_video.c1268
-rw-r--r--drivers/media/common/tuners/Kconfig66
-rw-r--r--drivers/media/common/tuners/Makefile1
-rw-r--r--drivers/media/common/tuners/mc44s803.c371
-rw-r--r--drivers/media/common/tuners/mc44s803.h46
-rw-r--r--drivers/media/common/tuners/mc44s803_priv.h208
-rw-r--r--drivers/media/common/tuners/mt2060.c2
-rw-r--r--drivers/media/common/tuners/mt20xx.c2
-rw-r--r--drivers/media/common/tuners/mxl5005s.c7
-rw-r--r--drivers/media/common/tuners/mxl5007t.c428
-rw-r--r--drivers/media/common/tuners/tda18271-common.c6
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c37
-rw-r--r--drivers/media/common/tuners/tda18271-priv.h6
-rw-r--r--drivers/media/common/tuners/tda18271.h10
-rw-r--r--drivers/media/common/tuners/tda827x.c237
-rw-r--r--drivers/media/common/tuners/tda8290.c9
-rw-r--r--drivers/media/common/tuners/tea5761.c2
-rw-r--r--drivers/media/common/tuners/tea5767.c2
-rw-r--r--drivers/media/common/tuners/xc5000.c14
-rw-r--r--drivers/media/dvb/b2c2/Kconfig2
-rw-r--r--drivers/media/dvb/b2c2/Makefile1
-rw-r--r--drivers/media/dvb/b2c2/flexcop-common.h64
-rw-r--r--drivers/media/dvb/b2c2/flexcop-dma.c27
-rw-r--r--drivers/media/dvb/b2c2/flexcop-eeprom.c47
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c6
-rw-r--r--drivers/media/dvb/b2c2/flexcop-hw-filter.c171
-rw-r--r--drivers/media/dvb/b2c2/flexcop-i2c.c61
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c68
-rw-r--r--drivers/media/dvb/b2c2/flexcop-pci.c165
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h21
-rw-r--r--drivers/media/dvb/b2c2/flexcop-sram.c112
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.c368
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.h62
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c86
-rw-r--r--drivers/media/dvb/b2c2/flexcop.h20
-rw-r--r--drivers/media/dvb/b2c2/flexcop_ibi_value_be.h7
-rw-r--r--drivers/media/dvb/b2c2/flexcop_ibi_value_le.h7
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig2
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c14
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c2
-rw-r--r--drivers/media/dvb/dm1105/Kconfig1
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c204
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c4
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h2
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig67
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile2
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c60
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h31
-rw-r--r--drivers/media/dvb/dvb-usb/ce6230.c328
-rw-r--r--drivers/media/dvb/dvb-usb/ce6230.h69
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c10
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c164
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h11
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h2
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c12
-rw-r--r--drivers/media/dvb/frontends/Kconfig71
-rw-r--r--drivers/media/dvb/frontends/Makefile6
-rw-r--r--drivers/media/dvb/frontends/au8522.h16
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c835
-rw-r--r--drivers/media/dvb/frontends/au8522_dig.c (renamed from drivers/media/dvb/frontends/au8522.c)96
-rw-r--r--drivers/media/dvb/frontends/au8522_priv.h412
-rw-r--r--drivers/media/dvb/frontends/cx24113.c2
-rw-r--r--drivers/media/dvb/frontends/cx24116.c63
-rw-r--r--drivers/media/dvb/frontends/cx24123.c4
-rw-r--r--drivers/media/dvb/frontends/dib0070.h2
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.h36
-rw-r--r--drivers/media/dvb/frontends/dib7000m.h28
-rw-r--r--drivers/media/dvb/frontends/dib7000p.h35
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c2
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.h19
-rw-r--r--drivers/media/dvb/frontends/itd1000_priv.h2
-rw-r--r--drivers/media/dvb/frontends/lgdt3304.c1
-rw-r--r--drivers/media/dvb/frontends/lgdt3305.c1087
-rw-r--r--drivers/media/dvb/frontends/lgdt3305.h85
-rw-r--r--drivers/media/dvb/frontends/lnbh24.h55
-rw-r--r--drivers/media/dvb/frontends/lnbp21.c41
-rw-r--r--drivers/media/dvb/frontends/lnbp21.h34
-rw-r--r--drivers/media/dvb/frontends/s921_module.c1
-rw-r--r--drivers/media/dvb/frontends/stb6100_cfg.h4
-rw-r--r--drivers/media/dvb/frontends/stv0900.h62
-rw-r--r--drivers/media/dvb/frontends/stv0900_core.c1949
-rw-r--r--drivers/media/dvb/frontends/stv0900_init.h441
-rw-r--r--drivers/media/dvb/frontends/stv0900_priv.h430
-rw-r--r--drivers/media/dvb/frontends/stv0900_reg.h3787
-rw-r--r--drivers/media/dvb/frontends/stv0900_sw.c2847
-rw-r--r--drivers/media/dvb/frontends/stv6110.c456
-rw-r--r--drivers/media/dvb/frontends/stv6110.h62
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c30
-rw-r--r--drivers/media/dvb/frontends/zl10036.c519
-rw-r--r--drivers/media/dvb/frontends/zl10036.h53
-rw-r--r--drivers/media/dvb/frontends/zl10353.c8
-rw-r--r--drivers/media/dvb/frontends/zl10353.h4
-rw-r--r--drivers/media/dvb/frontends/zl10353_priv.h8
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c7
-rw-r--r--drivers/media/dvb/siano/Makefile4
-rw-r--r--drivers/media/dvb/siano/sms-cards.c92
-rw-r--r--drivers/media/dvb/siano/sms-cards.h5
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c45
-rw-r--r--drivers/media/dvb/siano/smscoreapi.h41
-rw-r--r--drivers/media/dvb/siano/smsdvb.c60
-rw-r--r--drivers/media/dvb/siano/smsusb.c73
-rw-r--r--drivers/media/dvb/ttpci/Kconfig2
-rw-r--r--drivers/media/dvb/ttpci/av7110.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c4
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c480
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c88
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c6
-rw-r--r--drivers/media/radio/dsbr100.c10
-rw-r--r--drivers/media/radio/radio-aimslab.c347
-rw-r--r--drivers/media/radio/radio-aztech.c378
-rw-r--r--drivers/media/radio/radio-cadet.c595
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c329
-rw-r--r--drivers/media/radio/radio-gemtek.c396
-rw-r--r--drivers/media/radio/radio-maestro.c337
-rw-r--r--drivers/media/radio/radio-maxiradio.c374
-rw-r--r--drivers/media/radio/radio-mr800.c221
-rw-r--r--drivers/media/radio/radio-rtrack2.c276
-rw-r--r--drivers/media/radio/radio-sf16fmi.c283
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c371
-rw-r--r--drivers/media/radio/radio-si470x.c200
-rw-r--r--drivers/media/radio/radio-tea5764.c3
-rw-r--r--drivers/media/radio/radio-terratec.c310
-rw-r--r--drivers/media/radio/radio-trust.c343
-rw-r--r--drivers/media/radio/radio-typhoon.c349
-rw-r--r--drivers/media/radio/radio-zoltrix.c378
-rw-r--r--drivers/media/video/Kconfig94
-rw-r--r--drivers/media/video/Makefile10
-rw-r--r--drivers/media/video/adv7170.c354
-rw-r--r--drivers/media/video/adv7175.c329
-rw-r--r--drivers/media/video/au0828/Kconfig10
-rw-r--r--drivers/media/video/au0828/Makefile2
-rw-r--r--drivers/media/video/au0828/au0828-cards.c127
-rw-r--r--drivers/media/video/au0828/au0828-core.c34
-rw-r--r--drivers/media/video/au0828/au0828-dvb.c2
-rw-r--r--drivers/media/video/au0828/au0828-i2c.c72
-rw-r--r--drivers/media/video/au0828/au0828-reg.h6
-rw-r--r--drivers/media/video/au0828/au0828-video.c1712
-rw-r--r--drivers/media/video/au0828/au0828.h181
-rw-r--r--drivers/media/video/bt819.c493
-rw-r--r--drivers/media/video/bt856.c291
-rw-r--r--drivers/media/video/bt866.c282
-rw-r--r--drivers/media/video/bt8xx/Kconfig2
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c1672
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c197
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c61
-rw-r--r--drivers/media/video/bt8xx/bttv-if.c18
-rw-r--r--drivers/media/video/bt8xx/bttv-risc.c4
-rw-r--r--drivers/media/video/bt8xx/bttv-vbi.c2
-rw-r--r--drivers/media/video/bt8xx/bttv.h96
-rw-r--r--drivers/media/video/bt8xx/bttvp.h30
-rw-r--r--drivers/media/video/cafe_ccic.c432
-rw-r--r--drivers/media/video/cpia.c4
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c1
-rw-r--r--drivers/media/video/cs5345.c7
-rw-r--r--drivers/media/video/cs53l32a.c12
-rw-r--r--drivers/media/video/cx18/Kconfig2
-rw-r--r--drivers/media/video/cx18/cx18-audio.c52
-rw-r--r--drivers/media/video/cx18/cx18-audio.h2
-rw-r--r--drivers/media/video/cx18/cx18-av-audio.c120
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c796
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h49
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c16
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c367
-rw-r--r--drivers/media/video/cx18/cx18-cards.c50
-rw-r--r--drivers/media/video/cx18/cx18-cards.h18
-rw-r--r--drivers/media/video/cx18/cx18-controls.c70
-rw-r--r--drivers/media/video/cx18/cx18-driver.c416
-rw-r--r--drivers/media/video/cx18/cx18-driver.h258
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c2
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c107
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c22
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c319
-rw-r--r--drivers/media/video/cx18/cx18-gpio.h10
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c296
-rw-r--r--drivers/media/video/cx18/cx18-i2c.h5
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c273
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c44
-rw-r--r--drivers/media/video/cx18/cx18-queue.c4
-rw-r--r--drivers/media/video/cx18/cx18-queue.h4
-rw-r--r--drivers/media/video/cx18/cx18-streams.c210
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c155
-rw-r--r--drivers/media/video/cx18/cx18-vbi.h2
-rw-r--r--drivers/media/video/cx18/cx18-version.h4
-rw-r--r--drivers/media/video/cx18/cx18-video.c3
-rw-r--r--drivers/media/video/cx18/cx23418.h16
-rw-r--r--drivers/media/video/cx2341x.c196
-rw-r--r--drivers/media/video/cx23885/Kconfig15
-rw-r--r--drivers/media/video/cx23885/Makefile4
-rw-r--r--drivers/media/video/cx23885/cimax2.c472
-rw-r--r--drivers/media/video/cx23885/cimax2.h47
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c49
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c94
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c43
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c166
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c68
-rw-r--r--drivers/media/video/cx23885/cx23885-reg.h2
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c51
-rw-r--r--drivers/media/video/cx23885/cx23885.h20
-rw-r--r--drivers/media/video/cx23885/netup-eeprom.c107
-rw-r--r--drivers/media/video/cx23885/netup-eeprom.h42
-rw-r--r--drivers/media/video/cx23885/netup-init.c125
-rw-r--r--drivers/media/video/cx23885/netup-init.h25
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c121
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c65
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h8
-rw-r--r--drivers/media/video/cx25840/cx25840-vbi.c314
-rw-r--r--drivers/media/video/cx88/Kconfig2
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c7
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c8
-rw-r--r--drivers/media/video/cx88/cx88-cards.c99
-rw-r--r--drivers/media/video/cx88/cx88-core.c11
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c18
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c41
-rw-r--r--drivers/media/video/cx88/cx88-input.c29
-rw-r--r--drivers/media/video/cx88/cx88-video.c52
-rw-r--r--drivers/media/video/cx88/cx88.h24
-rw-r--r--drivers/media/video/dabusb.c83
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c84
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c195
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c41
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c3
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c12
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c22
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c61
-rw-r--r--drivers/media/video/em28xx/em28xx.h24
-rw-r--r--drivers/media/video/gspca/Kconfig27
-rw-r--r--drivers/media/video/gspca/Makefile102
-rw-r--r--drivers/media/video/gspca/conex.c63
-rw-r--r--drivers/media/video/gspca/etoms.c36
-rw-r--r--drivers/media/video/gspca/finepix.c433
-rw-r--r--drivers/media/video/gspca/gspca.c166
-rw-r--r--drivers/media/video/gspca/gspca.h14
-rw-r--r--drivers/media/video/gspca/jpeg.h263
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c7
-rw-r--r--drivers/media/video/gspca/mars.c506
-rw-r--r--drivers/media/video/gspca/mr97310a.c362
-rw-r--r--drivers/media/video/gspca/ov519.c7
-rw-r--r--drivers/media/video/gspca/ov534.c820
-rw-r--r--drivers/media/video/gspca/pac207.c8
-rw-r--r--drivers/media/video/gspca/pac7311.c7
-rw-r--r--drivers/media/video/gspca/sonixb.c7
-rw-r--r--drivers/media/video/gspca/sonixj.c951
-rw-r--r--drivers/media/video/gspca/spca500.c99
-rw-r--r--drivers/media/video/gspca/spca501.c22
-rw-r--r--drivers/media/video/gspca/spca505.c525
-rw-r--r--drivers/media/video/gspca/spca506.c57
-rw-r--r--drivers/media/video/gspca/spca508.c128
-rw-r--r--drivers/media/video/gspca/spca561.c192
-rw-r--r--drivers/media/video/gspca/sq905.c456
-rw-r--r--drivers/media/video/gspca/sq905c.c328
-rw-r--r--drivers/media/video/gspca/stk014.c72
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c7
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c76
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h65
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c147
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h130
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_sensor.h8
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c123
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h58
-rw-r--r--drivers/media/video/gspca/sunplus.c124
-rw-r--r--drivers/media/video/gspca/t613.c564
-rw-r--r--drivers/media/video/gspca/tv8532.c483
-rw-r--r--drivers/media/video/gspca/vc032x.c1591
-rw-r--r--drivers/media/video/gspca/zc3xx.c884
-rw-r--r--drivers/media/video/hdpvr/Kconfig10
-rw-r--r--drivers/media/video/hdpvr/Makefile9
-rw-r--r--drivers/media/video/hdpvr/hdpvr-control.c201
-rw-r--r--drivers/media/video/hdpvr/hdpvr-core.c466
-rw-r--r--drivers/media/video/hdpvr/hdpvr-i2c.c145
-rw-r--r--drivers/media/video/hdpvr/hdpvr-video.c1248
-rw-r--r--drivers/media/video/hdpvr/hdpvr.h303
-rw-r--r--drivers/media/video/hexium_gemini.c292
-rw-r--r--drivers/media/video/hexium_orion.c103
-rw-r--r--drivers/media/video/indycam.c314
-rw-r--r--drivers/media/video/indycam.h19
-rw-r--r--drivers/media/video/ir-kbd-i2c.c84
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c93
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h26
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c10
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c14
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c20
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.c8
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.h8
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c68
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.c10
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.h4
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-version.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c6
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c6
-rw-r--r--drivers/media/video/ks0127.c677
-rw-r--r--drivers/media/video/ks0127.h2
-rw-r--r--drivers/media/video/m52790.c7
-rw-r--r--drivers/media/video/meye.c45
-rw-r--r--drivers/media/video/msp3400-driver.c142
-rw-r--r--drivers/media/video/mt9m001.c164
-rw-r--r--drivers/media/video/mt9m111.c64
-rw-r--r--drivers/media/video/mt9t031.c179
-rw-r--r--drivers/media/video/mt9v022.c205
-rw-r--r--drivers/media/video/mx3_camera.c1220
-rw-r--r--drivers/media/video/mxb.c828
-rw-r--r--drivers/media/video/omap24xxcam.c15
-rw-r--r--drivers/media/video/ov7670.c552
-rw-r--r--drivers/media/video/ov772x.c320
-rw-r--r--drivers/media/video/ovcamchip/ovcamchip_core.c197
-rw-r--r--drivers/media/video/ovcamchip/ovcamchip_priv.h7
-rw-r--r--drivers/media/video/pvrusb2/Kconfig8
-rw-r--r--drivers/media/video/pvrusb2/Makefile7
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.c142
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.h6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c95
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h (renamed from drivers/media/video/pvrusb2/pvrusb2-tuner.h)21
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c245
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.c5
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.h12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c102
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h34
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-dvb.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h50
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c648
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c113
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c322
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h50
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c417
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.h57
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-tuner.c120
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c18
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.c214
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.h7
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.c134
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.h4
-rw-r--r--drivers/media/video/pwc/Kconfig10
-rw-r--r--drivers/media/video/pwc/pwc-if.c79
-rw-r--r--drivers/media/video/pwc/pwc.h6
-rw-r--r--drivers/media/video/pxa_camera.c69
-rw-r--r--drivers/media/video/s2255drv.c41
-rw-r--r--drivers/media/video/saa5246a.c70
-rw-r--r--drivers/media/video/saa5249.c71
-rw-r--r--drivers/media/video/saa6588.c207
-rw-r--r--drivers/media/video/saa7110.c472
-rw-r--r--drivers/media/video/saa7111.c492
-rw-r--r--drivers/media/video/saa7114.c1068
-rw-r--r--drivers/media/video/saa7115.c64
-rw-r--r--drivers/media/video/saa7127.c1
-rw-r--r--drivers/media/video/saa7134/Kconfig13
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c581
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c8
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c333
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c108
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c75
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c27
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c23
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c15
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c75
-rw-r--r--drivers/media/video/saa7134/saa7134.h40
-rw-r--r--drivers/media/video/saa7146.h2
-rw-r--r--drivers/media/video/saa717x.c10
-rw-r--r--drivers/media/video/saa7185.c239
-rw-r--r--drivers/media/video/saa7191.c500
-rw-r--r--drivers/media/video/saa7191.h26
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c82
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h4
-rw-r--r--drivers/media/video/soc_camera.c135
-rw-r--r--drivers/media/video/soc_camera_platform.c9
-rw-r--r--drivers/media/video/stk-webcam.c24
-rw-r--r--drivers/media/video/tcm825x.c22
-rw-r--r--drivers/media/video/tcm825x.h2
-rw-r--r--drivers/media/video/tda7432.c22
-rw-r--r--drivers/media/video/tda9840.c82
-rw-r--r--drivers/media/video/tda9840.h14
-rw-r--r--drivers/media/video/tda9875.c19
-rw-r--r--drivers/media/video/tea6415c.c53
-rw-r--r--drivers/media/video/tea6415c.h12
-rw-r--r--drivers/media/video/tea6420.c69
-rw-r--r--drivers/media/video/tea6420.h27
-rw-r--r--drivers/media/video/tlv320aic23b.c12
-rw-r--r--drivers/media/video/tuner-core.c152
-rw-r--r--drivers/media/video/tvaudio.c173
-rw-r--r--drivers/media/video/tveeprom.c7
-rw-r--r--drivers/media/video/tvp514x.c113
-rw-r--r--drivers/media/video/tvp5150.c10
-rw-r--r--drivers/media/video/tw9910.c36
-rw-r--r--drivers/media/video/upd64031a.c7
-rw-r--r--drivers/media/video/upd64083.c7
-rw-r--r--drivers/media/video/usbvideo/vicam.c2
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c49
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c153
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c125
-rw-r--r--drivers/media/video/usbvision/usbvision.h10
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c2
-rw-r--r--drivers/media/video/uvc/uvc_driver.c45
-rw-r--r--drivers/media/video/uvc/uvc_status.c16
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c20
-rw-r--r--drivers/media/video/uvc/uvc_video.c133
-rw-r--r--drivers/media/video/uvc/uvcvideo.h8
-rw-r--r--drivers/media/video/v4l2-common.c265
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c1
-rw-r--r--drivers/media/video/v4l2-dev.c54
-rw-r--r--drivers/media/video/v4l2-device.c60
-rw-r--r--drivers/media/video/v4l2-ioctl.c192
-rw-r--r--drivers/media/video/v4l2-subdev.c18
-rw-r--r--drivers/media/video/videobuf-dma-contig.c2
-rw-r--r--drivers/media/video/videobuf-vmalloc.c2
-rw-r--r--drivers/media/video/vino.c1655
-rw-r--r--drivers/media/video/vivi.c495
-rw-r--r--drivers/media/video/vp27smpx.c7
-rw-r--r--drivers/media/video/vpx3220.c491
-rw-r--r--drivers/media/video/w9966.c2
-rw-r--r--drivers/media/video/w9968cf.c133
-rw-r--r--drivers/media/video/w9968cf.h24
-rw-r--r--drivers/media/video/wm8739.c7
-rw-r--r--drivers/media/video/wm8775.c12
-rw-r--r--drivers/media/video/zc0301/zc0301_sensor.h8
-rw-r--r--drivers/media/video/zoran/Kconfig8
-rw-r--r--drivers/media/video/zoran/videocodec.h9
-rw-r--r--drivers/media/video/zoran/zoran.h97
-rw-r--r--drivers/media/video/zoran/zoran_card.c555
-rw-r--r--drivers/media/video/zoran/zoran_card.h3
-rw-r--r--drivers/media/video/zoran/zoran_device.c529
-rw-r--r--drivers/media/video/zoran/zoran_device.h14
-rw-r--r--drivers/media/video/zoran/zoran_driver.c4385
-rw-r--r--drivers/media/video/zoran/zoran_procfs.c2
-rw-r--r--drivers/media/video/zoran/zr36016.c5
-rw-r--r--drivers/media/video/zoran/zr36050.c4
-rw-r--r--drivers/media/video/zoran/zr36060.c4
-rw-r--r--drivers/media/video/zr364xx.c17
-rw-r--r--drivers/message/fusion/mptsas.c5
-rw-r--r--drivers/message/i2o/i2o_proc.c2
-rw-r--r--drivers/mfd/Kconfig3
-rw-r--r--drivers/mfd/da903x.c2
-rw-r--r--drivers/mfd/htc-pasic3.c169
-rw-r--r--drivers/mfd/mcp-core.c2
-rw-r--r--drivers/mfd/pcf50633-core.c1
-rw-r--r--drivers/mfd/t7l66xb.c4
-rw-r--r--drivers/mfd/tc6393xb.c2
-rw-r--r--drivers/mfd/twl4030-core.c2
-rw-r--r--drivers/mfd/twl4030-irq.c2
-rw-r--r--drivers/mfd/ucb1x00-core.c2
-rw-r--r--drivers/mfd/wm8350-core.c39
-rw-r--r--drivers/misc/Kconfig20
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/eeprom/Kconfig2
-rw-r--r--drivers/misc/eeprom/at24.c67
-rw-r--r--drivers/misc/eeprom/at25.c58
-rw-r--r--drivers/misc/hpilo.c6
-rw-r--r--drivers/misc/hpilo.h6
-rw-r--r--drivers/misc/isl29003.c470
-rw-r--r--drivers/misc/sgi-gru/Makefile2
-rw-r--r--drivers/misc/sgi-gru/gru_instructions.h22
-rw-r--r--drivers/misc/sgi-gru/grufault.c130
-rw-r--r--drivers/misc/sgi-gru/grufile.c36
-rw-r--r--drivers/misc/sgi-gru/gruhandles.c183
-rw-r--r--drivers/misc/sgi-gru/gruhandles.h178
-rw-r--r--drivers/misc/sgi-gru/grukservices.c131
-rw-r--r--drivers/misc/sgi-gru/grukservices.h33
-rw-r--r--drivers/misc/sgi-gru/grumain.c84
-rw-r--r--drivers/misc/sgi-gru/gruprocfs.c45
-rw-r--r--drivers/misc/sgi-gru/grutables.h41
-rw-r--r--drivers/misc/sgi-gru/grutlbpurge.c7
-rw-r--r--drivers/misc/sgi-xp/xpc.h33
-rw-r--r--drivers/misc/sgi-xp/xpc_channel.c8
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c6
-rw-r--r--drivers/misc/sgi-xp/xpc_sn2.c20
-rw-r--r--drivers/misc/sgi-xp/xpc_uv.c229
-rw-r--r--drivers/mmc/card/block.c2
-rw-r--r--drivers/mmc/card/sdio_uart.c62
-rw-r--r--drivers/mmc/core/bus.c8
-rw-r--r--drivers/mmc/core/core.c118
-rw-r--r--drivers/mmc/core/debugfs.c67
-rw-r--r--drivers/mmc/core/sdio_cis.c8
-rw-r--r--drivers/mmc/core/sdio_ops.c8
-rw-r--r--drivers/mmc/host/Kconfig31
-rw-r--r--drivers/mmc/host/Makefile2
-rw-r--r--drivers/mmc/host/atmel-mci.c4
-rw-r--r--drivers/mmc/host/mmc_spi.c40
-rw-r--r--drivers/mmc/host/mmci.c6
-rw-r--r--drivers/mmc/host/mvsdio.c885
-rw-r--r--drivers/mmc/host/mvsdio.h190
-rw-r--r--drivers/mmc/host/mxcmmc.c4
-rw-r--r--drivers/mmc/host/of_mmc_spi.c2
-rw-r--r--drivers/mmc/host/omap.c24
-rw-r--r--drivers/mmc/host/omap_hsmmc.c359
-rw-r--r--drivers/mmc/host/pxamci.c3
-rw-r--r--drivers/mmc/host/sdhci-of.c309
-rw-r--r--drivers/mmc/host/sdhci.c317
-rw-r--r--drivers/mmc/host/sdhci.h112
-rw-r--r--drivers/mmc/host/tmio_mmc.c6
-rw-r--r--drivers/mmc/host/tmio_mmc.h3
-rw-r--r--drivers/mtd/Makefile2
-rw-r--r--drivers/mtd/ar7part.c6
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c8
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c11
-rw-r--r--drivers/mtd/chips/jedec_probe.c16
-rw-r--r--drivers/mtd/chips/map_ram.c17
-rw-r--r--drivers/mtd/chips/map_rom.c17
-rw-r--r--drivers/mtd/cmdlinepart.c6
-rw-r--r--drivers/mtd/devices/doc2000.c1
-rw-r--r--drivers/mtd/devices/doc2001.c1
-rw-r--r--drivers/mtd/devices/doc2001plus.c1
-rw-r--r--drivers/mtd/devices/docecc.c1
-rw-r--r--drivers/mtd/devices/m25p80.c19
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c18
-rw-r--r--drivers/mtd/devices/mtdram.c14
-rw-r--r--drivers/mtd/inftlmount.c1
-rw-r--r--drivers/mtd/internal.h (renamed from include/asm-frv/ide.h)23
-rw-r--r--drivers/mtd/maps/Kconfig24
-rw-r--r--drivers/mtd/maps/Makefile3
-rw-r--r--drivers/mtd/maps/integrator-flash.c2
-rw-r--r--drivers/mtd/maps/omap_nor.c2
-rw-r--r--drivers/mtd/maps/physmap.c1
-rw-r--r--drivers/mtd/maps/physmap_of.c1
-rw-r--r--drivers/mtd/maps/plat-ram.c1
-rw-r--r--drivers/mtd/maps/pxa2xx-flash.c37
-rw-r--r--drivers/mtd/maps/rbtx4939-flash.c208
-rw-r--r--drivers/mtd/maps/sa1100-flash.c4
-rw-r--r--drivers/mtd/maps/sharpsl-flash.c116
-rw-r--r--drivers/mtd/maps/vmu-flash.c832
-rw-r--r--drivers/mtd/mtd_blkdevs.c4
-rw-r--r--drivers/mtd/mtdbdi.c43
-rw-r--r--drivers/mtd/mtdchar.c111
-rw-r--r--drivers/mtd/mtdconcat.c47
-rw-r--r--drivers/mtd/mtdcore.c208
-rw-r--r--drivers/mtd/mtdoops.c16
-rw-r--r--drivers/mtd/mtdpart.c31
-rw-r--r--drivers/mtd/mtdsuper.c7
-rw-r--r--drivers/mtd/nand/Kconfig21
-rw-r--r--drivers/mtd/nand/Makefile3
-rw-r--r--drivers/mtd/nand/bf5xx_nand.c18
-rw-r--r--drivers/mtd/nand/cafe_nand.c1
-rw-r--r--drivers/mtd/nand/cmx270_nand.c3
-rw-r--r--drivers/mtd/nand/davinci_nand.c570
-rw-r--r--drivers/mtd/nand/diskonchip.c2
-rw-r--r--drivers/mtd/nand/excite_nandflash.c25
-rw-r--r--drivers/mtd/nand/fsl_upm.c119
-rw-r--r--drivers/mtd/nand/mxc_nand.c3
-rw-r--r--drivers/mtd/nand/nand_base.c129
-rw-r--r--drivers/mtd/nand/ndfc.c2
-rw-r--r--drivers/mtd/nand/plat_nand.c2
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c120
-rw-r--r--drivers/mtd/nand/sh_flctl.c18
-rw-r--r--drivers/mtd/nand/socrates_nand.c325
-rw-r--r--drivers/mtd/nand/txx9ndfmc.c428
-rw-r--r--drivers/mtd/nftlcore.c3
-rw-r--r--drivers/mtd/ofpart.c7
-rw-r--r--drivers/mtd/onenand/generic.c26
-rw-r--r--drivers/mtd/onenand/omap2.c6
-rw-r--r--drivers/mtd/onenand/onenand_base.c145
-rw-r--r--drivers/mtd/tests/mtd_oobtest.c24
-rw-r--r--drivers/mtd/tests/mtd_readtest.c2
-rw-r--r--drivers/mtd/ubi/cdev.c11
-rw-r--r--drivers/net/3c501.c17
-rw-r--r--drivers/net/3c503.c3
-rw-r--r--drivers/net/3c505.c18
-rw-r--r--drivers/net/3c507.c15
-rw-r--r--drivers/net/3c509.c25
-rw-r--r--drivers/net/3c515.c21
-rw-r--r--drivers/net/3c523.c25
-rw-r--r--drivers/net/3c527.c19
-rw-r--r--drivers/net/3c59x.c61
-rw-r--r--drivers/net/8139cp.c30
-rw-r--r--drivers/net/8139too.c32
-rw-r--r--drivers/net/82596.c17
-rw-r--r--drivers/net/Kconfig61
-rw-r--r--drivers/net/Makefile7
-rw-r--r--drivers/net/a2065.c19
-rw-r--r--drivers/net/ac3200.c22
-rw-r--r--drivers/net/acenic.c2
-rw-r--r--drivers/net/amd8111e.c6
-rw-r--r--drivers/net/appletalk/cops.c45
-rw-r--r--drivers/net/appletalk/ltpc.c38
-rw-r--r--drivers/net/arcnet/arc-rawmode.c4
-rw-r--r--drivers/net/arcnet/arcnet.c72
-rw-r--r--drivers/net/arcnet/capmode.c6
-rw-r--r--drivers/net/arcnet/com20020-isa.c2
-rw-r--r--drivers/net/arcnet/com20020-pci.c3
-rw-r--r--drivers/net/arcnet/com20020.c11
-rw-r--r--drivers/net/arcnet/rfc1051.c12
-rw-r--r--drivers/net/arcnet/rfc1201.c47
-rw-r--r--drivers/net/arm/am79c961a.c2
-rw-r--r--drivers/net/arm/ep93xx_eth.c8
-rw-r--r--drivers/net/arm/ixp4xx_eth.c32
-rw-r--r--drivers/net/arm/ks8695net.c2
-rw-r--r--drivers/net/at1700.c21
-rw-r--r--drivers/net/atl1c/atl1c.h1
-rw-r--r--drivers/net/atl1e/atl1e.h2
-rw-r--r--drivers/net/atl1e/atl1e_main.c6
-rw-r--r--drivers/net/atl1e/atl1e_param.c2
-rw-r--r--drivers/net/atlx/atl1.c2
-rw-r--r--drivers/net/atlx/atl2.c2
-rw-r--r--drivers/net/au1000_eth.c1051
-rw-r--r--drivers/net/ax88796.c31
-rw-r--r--drivers/net/b44.c8
-rw-r--r--drivers/net/benet/be.h13
-rw-r--r--drivers/net/benet/be_main.c160
-rw-r--r--drivers/net/bfin_mac.c12
-rw-r--r--drivers/net/bmac.c3
-rw-r--r--drivers/net/bnx2.c36
-rw-r--r--drivers/net/bnx2x.h186
-rw-r--r--drivers/net/bnx2x_dump.h526
-rw-r--r--drivers/net/bnx2x_fw_defs.h153
-rw-r--r--drivers/net/bnx2x_hsi.h559
-rw-r--r--drivers/net/bnx2x_init.h163
-rw-r--r--drivers/net/bnx2x_init_values.h26545
-rw-r--r--drivers/net/bnx2x_link.c1416
-rw-r--r--drivers/net/bnx2x_link.h23
-rw-r--r--drivers/net/bnx2x_main.c2640
-rw-r--r--drivers/net/bnx2x_reg.h314
-rw-r--r--drivers/net/bonding/bond_3ad.h2
-rw-r--r--drivers/net/bonding/bond_alb.c12
-rw-r--r--drivers/net/bonding/bond_main.c77
-rw-r--r--drivers/net/cassini.c8
-rw-r--r--drivers/net/chelsio/sge.c7
-rw-r--r--drivers/net/cpmac.c12
-rw-r--r--drivers/net/cs89x0.c28
-rw-r--r--drivers/net/cxgb3/adapter.h25
-rw-r--r--drivers/net/cxgb3/ael1002.c3
-rw-r--r--drivers/net/cxgb3/common.h10
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c266
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c12
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.h7
-rw-r--r--drivers/net/cxgb3/regs.h21
-rw-r--r--drivers/net/cxgb3/sge.c459
-rw-r--r--drivers/net/cxgb3/t3_hw.c244
-rw-r--r--drivers/net/cxgb3/version.h4
-rw-r--r--drivers/net/cxgb3/xgmac.c85
-rw-r--r--drivers/net/declance.c6
-rw-r--r--drivers/net/defxx.c2
-rw-r--r--drivers/net/depca.c25
-rw-r--r--drivers/net/dm9000.c8
-rw-r--r--drivers/net/dnet.c9
-rw-r--r--drivers/net/e100.c99
-rw-r--r--drivers/net/e1000/e1000.h2
-rw-r--r--drivers/net/e1000/e1000_main.c162
-rw-r--r--drivers/net/e1000e/82571.c273
-rw-r--r--drivers/net/e1000e/defines.h1
-rw-r--r--drivers/net/e1000e/e1000.h4
-rw-r--r--drivers/net/e1000e/ethtool.c3
-rw-r--r--drivers/net/e1000e/hw.h11
-rw-r--r--drivers/net/e1000e/ich8lan.c17
-rw-r--r--drivers/net/e1000e/lib.c66
-rw-r--r--drivers/net/e1000e/netdev.c261
-rw-r--r--drivers/net/e2100.c6
-rw-r--r--drivers/net/eepro.c17
-rw-r--r--drivers/net/eexpress.c17
-rw-r--r--drivers/net/ehea/ehea.h2
-rw-r--r--drivers/net/ehea/ehea_main.c189
-rw-r--r--drivers/net/ehea/ehea_qmr.c4
-rw-r--r--drivers/net/enic/enic.h3
-rw-r--r--drivers/net/enic/enic_main.c84
-rw-r--r--drivers/net/enic/vnic_dev.c33
-rw-r--r--drivers/net/enic/vnic_dev.h2
-rw-r--r--drivers/net/enic/vnic_devcmd.h8
-rw-r--r--drivers/net/enic/vnic_intr.h14
-rw-r--r--drivers/net/epic100.c6
-rw-r--r--drivers/net/eql.c2
-rw-r--r--drivers/net/eth16i.c18
-rw-r--r--drivers/net/ethoc.c1112
-rw-r--r--drivers/net/ewrk3.c19
-rw-r--r--drivers/net/fealnx.c4
-rw-r--r--drivers/net/fec.c890
-rw-r--r--drivers/net/fec.h11
-rw-r--r--drivers/net/fec_mpc52xx.c83
-rw-r--r--drivers/net/forcedeth.c750
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c4
-rw-r--r--drivers/net/fsl_pq_mdio.c (renamed from drivers/net/gianfar_mii.c)268
-rw-r--r--drivers/net/fsl_pq_mdio.h45
-rw-r--r--drivers/net/gianfar.c174
-rw-r--r--drivers/net/gianfar.h21
-rw-r--r--drivers/net/gianfar_ethtool.c1
-rw-r--r--drivers/net/gianfar_mii.h54
-rw-r--r--drivers/net/gianfar_sysfs.c33
-rw-r--r--drivers/net/hamachi.c10
-rw-r--r--drivers/net/hamradio/6pack.c20
-rw-r--r--drivers/net/hamradio/baycom_epp.c43
-rw-r--r--drivers/net/hamradio/bpqether.c47
-rw-r--r--drivers/net/hamradio/dmascc.c56
-rw-r--r--drivers/net/hamradio/hdlcdrv.c45
-rw-r--r--drivers/net/hamradio/mkiss.c55
-rw-r--r--drivers/net/hamradio/scc.c24
-rw-r--r--drivers/net/hamradio/yam.c132
-rw-r--r--drivers/net/hamradio/yam1200.h343
-rw-r--r--drivers/net/hamradio/yam9600.h343
-rw-r--r--drivers/net/ibm_newemac/core.c2
-rw-r--r--drivers/net/ibmlana.c17
-rw-r--r--drivers/net/ibmveth.c8
-rw-r--r--drivers/net/igb/Makefile4
-rw-r--r--drivers/net/igb/e1000_82575.c141
-rw-r--r--drivers/net/igb/e1000_82575.h64
-rw-r--r--drivers/net/igb/e1000_defines.h134
-rw-r--r--drivers/net/igb/e1000_hw.h202
-rw-r--r--drivers/net/igb/e1000_mac.c66
-rw-r--r--drivers/net/igb/e1000_mac.h9
-rw-r--r--drivers/net/igb/e1000_mbx.c447
-rw-r--r--drivers/net/igb/e1000_mbx.h77
-rw-r--r--drivers/net/igb/e1000_nvm.c44
-rw-r--r--drivers/net/igb/e1000_phy.c359
-rw-r--r--drivers/net/igb/e1000_phy.h3
-rw-r--r--drivers/net/igb/e1000_regs.h103
-rw-r--r--drivers/net/igb/igb.h92
-rw-r--r--drivers/net/igb/igb_ethtool.c220
-rw-r--r--drivers/net/igb/igb_main.c1945
-rw-r--r--drivers/net/irda/ali-ircc.c23
-rw-r--r--drivers/net/irda/donauboe.c12
-rw-r--r--drivers/net/irda/irda-usb.c18
-rw-r--r--drivers/net/irda/kingsun-sir.c11
-rw-r--r--drivers/net/irda/ks959-sir.c11
-rw-r--r--drivers/net/irda/ksdazzle-sir.c12
-rw-r--r--drivers/net/irda/mcs7780.c13
-rw-r--r--drivers/net/irda/nsc-ircc.c23
-rw-r--r--drivers/net/irda/pxaficp_ir.c3
-rw-r--r--drivers/net/irda/sir_dev.c17
-rw-r--r--drivers/net/irda/smsc-ircc2.c30
-rw-r--r--drivers/net/irda/stir4200.c12
-rw-r--r--drivers/net/irda/via-ircc.c22
-rw-r--r--drivers/net/irda/vlsi_ir.c21
-rw-r--r--drivers/net/irda/w83977af_ir.c13
-rw-r--r--drivers/net/ixgb/ixgb_main.c76
-rw-r--r--drivers/net/ixgbe/Makefile7
-rw-r--r--drivers/net/ixgbe/ixgbe.h66
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c337
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c1292
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c484
-rw-r--r--drivers/net/ixgbe/ixgbe_common.h24
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb.c19
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb.h56
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82598.c3
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82598.h2
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.c467
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.h127
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_nl.c209
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c257
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c1507
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.c592
-rw-r--r--drivers/net/ixgbe/ixgbe_phy.h18
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h826
-rw-r--r--drivers/net/ixp2000/ixpdev.c4
-rw-r--r--drivers/net/jazzsonic.c6
-rw-r--r--drivers/net/jme.c31
-rw-r--r--drivers/net/jme.h8
-rw-r--r--drivers/net/korina.c4
-rw-r--r--drivers/net/lance.c30
-rw-r--r--drivers/net/lp486e.c17
-rw-r--r--drivers/net/macb.c21
-rw-r--r--drivers/net/macsonic.c15
-rw-r--r--drivers/net/macvlan.c84
-rw-r--r--drivers/net/meth.c2
-rw-r--r--drivers/net/mipsnet.c26
-rw-r--r--drivers/net/mlx4/Makefile2
-rw-r--r--drivers/net/mlx4/catas.c16
-rw-r--r--drivers/net/mlx4/en_netdev.c2
-rw-r--r--drivers/net/mlx4/en_rx.c7
-rw-r--r--drivers/net/mlx4/eq.c16
-rw-r--r--drivers/net/mlx4/main.c106
-rw-r--r--drivers/net/mlx4/mlx4.h27
-rw-r--r--drivers/net/mlx4/port.c13
-rw-r--r--drivers/net/mlx4/sense.c156
-rw-r--r--drivers/net/mv643xx_eth.c412
-rw-r--r--drivers/net/myri10ge/myri10ge.c7
-rw-r--r--drivers/net/myri10ge/myri10ge_mcp_gen_header.h9
-rw-r--r--drivers/net/myri_sbus.c20
-rw-r--r--drivers/net/natsemi.c8
-rw-r--r--drivers/net/ne2k-pci.c5
-rw-r--r--drivers/net/netconsole.c10
-rw-r--r--drivers/net/netxen/Makefile9
-rw-r--r--drivers/net/netxen/netxen_nic.h171
-rw-r--r--drivers/net/netxen/netxen_nic_ctx.c201
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c181
-rw-r--r--drivers/net/netxen/netxen_nic_hdr.h21
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c595
-rw-r--r--drivers/net/netxen/netxen_nic_hw.h63
-rw-r--r--drivers/net/netxen/netxen_nic_init.c916
-rw-r--r--drivers/net/netxen/netxen_nic_main.c1162
-rw-r--r--drivers/net/netxen/netxen_nic_niu.c230
-rw-r--r--drivers/net/netxen/netxen_nic_phan_reg.h10
-rw-r--r--drivers/net/ni5010.c18
-rw-r--r--drivers/net/ni52.c21
-rw-r--r--drivers/net/ni65.c86
-rw-r--r--drivers/net/niu.c1071
-rw-r--r--drivers/net/niu.h19
-rw-r--r--drivers/net/ns83820.c5
-rw-r--r--drivers/net/pasemi_mac.c6
-rw-r--r--drivers/net/pcmcia/3c574_cs.c23
-rw-r--r--drivers/net/pcmcia/3c589_cs.c25
-rw-r--r--drivers/net/pcmcia/axnet_cs.c70
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c59
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c23
-rw-r--r--drivers/net/pcmcia/ositech.h358
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c34
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c123
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c66
-rw-r--r--drivers/net/pcnet32.c6
-rw-r--r--drivers/net/phy/mdio-gpio.c13
-rw-r--r--drivers/net/phy/mdio_bus.c56
-rw-r--r--drivers/net/phy/phy.c40
-rw-r--r--drivers/net/phy/smsc.c31
-rw-r--r--drivers/net/ppp_async.c9
-rw-r--r--drivers/net/ppp_generic.c494
-rw-r--r--drivers/net/ppp_synctty.c6
-rw-r--r--drivers/net/pppoe.c521
-rw-r--r--drivers/net/pppol2tp.c192
-rw-r--r--drivers/net/pppox.c3
-rw-r--r--drivers/net/ps3_gelic_net.c26
-rw-r--r--drivers/net/ps3_gelic_wireless.c28
-rw-r--r--drivers/net/qla3xxx.c6
-rw-r--r--drivers/net/qlge/qlge.h161
-rw-r--r--drivers/net/qlge/qlge_dbg.c9
-rw-r--r--drivers/net/qlge/qlge_ethtool.c4
-rw-r--r--drivers/net/qlge/qlge_main.c630
-rw-r--r--drivers/net/qlge/qlge_mpi.c835
-rw-r--r--drivers/net/r6040.c14
-rw-r--r--drivers/net/r8169.c11
-rw-r--r--drivers/net/rionet.c3
-rw-r--r--drivers/net/s2io.c15
-rw-r--r--drivers/net/sb1250-mac.c18
-rw-r--r--drivers/net/sc92031.c27
-rw-r--r--drivers/net/seeq8005.c17
-rw-r--r--drivers/net/sfc/Kconfig1
-rw-r--r--drivers/net/sfc/bitfield.h4
-rw-r--r--drivers/net/sfc/boards.c74
-rw-r--r--drivers/net/sfc/boards.h1
-rw-r--r--drivers/net/sfc/efx.c81
-rw-r--r--drivers/net/sfc/efx.h4
-rw-r--r--drivers/net/sfc/ethtool.c28
-rw-r--r--drivers/net/sfc/falcon.c96
-rw-r--r--drivers/net/sfc/falcon.h2
-rw-r--r--drivers/net/sfc/falcon_io.h13
-rw-r--r--drivers/net/sfc/mdio_10g.c28
-rw-r--r--drivers/net/sfc/mdio_10g.h8
-rw-r--r--drivers/net/sfc/mtd.c1
-rw-r--r--drivers/net/sfc/net_driver.h29
-rw-r--r--drivers/net/sfc/phy.h8
-rw-r--r--drivers/net/sfc/rx.c209
-rw-r--r--drivers/net/sfc/rx.h3
-rw-r--r--drivers/net/sfc/sfe4001.c21
-rw-r--r--drivers/net/sfc/tenxpress.c141
-rw-r--r--drivers/net/sfc/tx.c13
-rw-r--r--drivers/net/sfc/workarounds.h2
-rw-r--r--drivers/net/sfc/xfp_phy.c105
-rw-r--r--drivers/net/sh_eth.c20
-rw-r--r--drivers/net/sh_eth.h4
-rw-r--r--drivers/net/sis900.c4
-rw-r--r--drivers/net/skfp/h/hwmtm.h2
-rw-r--r--drivers/net/skfp/h/smc.h17
-rw-r--r--drivers/net/skfp/hwmtm.c9
-rw-r--r--drivers/net/skfp/pcmplc.c3
-rw-r--r--drivers/net/skfp/skfddi.c3
-rw-r--r--drivers/net/skfp/smt.c10
-rw-r--r--drivers/net/skge.c6
-rw-r--r--drivers/net/sky2.c267
-rw-r--r--drivers/net/smc-ultra.c5
-rw-r--r--drivers/net/smc-ultra32.c23
-rw-r--r--drivers/net/smc911x.c2
-rw-r--r--drivers/net/smc911x.h3
-rw-r--r--drivers/net/smc9194.c17
-rw-r--r--drivers/net/smc91x.c140
-rw-r--r--drivers/net/smc91x.h45
-rw-r--r--drivers/net/smsc911x.c224
-rw-r--r--drivers/net/smsc911x.h7
-rw-r--r--drivers/net/smsc9420.c10
-rw-r--r--drivers/net/spider_net.c44
-rw-r--r--drivers/net/starfire.c8
-rw-r--r--drivers/net/sunbmac.c22
-rw-r--r--drivers/net/sundance.c5
-rw-r--r--drivers/net/sungem.c15
-rw-r--r--drivers/net/sunlance.c17
-rw-r--r--drivers/net/sunqe.c17
-rw-r--r--drivers/net/sunvnet.c18
-rw-r--r--drivers/net/tc35815.c12
-rw-r--r--drivers/net/tehuti.c45
-rw-r--r--drivers/net/tehuti.h1
-rw-r--r--drivers/net/tehuti_fw.h10712
-rw-r--r--drivers/net/tg3.c782
-rw-r--r--drivers/net/tg3.h18
-rw-r--r--drivers/net/tokenring/3c359.c80
-rw-r--r--drivers/net/tokenring/3c359.h3
-rw-r--r--drivers/net/tokenring/3c359_microcode.h1581
-rw-r--r--drivers/net/tokenring/abyss.c10
-rw-r--r--drivers/net/tokenring/ibmtr.c43
-rw-r--r--drivers/net/tokenring/lanstreamer.c45
-rw-r--r--drivers/net/tokenring/lanstreamer.h1
-rw-r--r--drivers/net/tokenring/madgemc.c13
-rw-r--r--drivers/net/tokenring/olympic.c39
-rw-r--r--drivers/net/tokenring/olympic.h1
-rw-r--r--drivers/net/tokenring/proteon.c9
-rw-r--r--drivers/net/tokenring/skisa.c9
-rw-r--r--drivers/net/tokenring/smctr.c29
-rw-r--r--drivers/net/tokenring/smctr.h1
-rw-r--r--drivers/net/tokenring/tms380tr.c21
-rw-r--r--drivers/net/tokenring/tms380tr.h1
-rw-r--r--drivers/net/tokenring/tmspci.c4
-rw-r--r--drivers/net/tsi108_eth.c8
-rw-r--r--drivers/net/tulip/de4x5.c7
-rw-r--r--drivers/net/tulip/dmfe.c2
-rw-r--r--drivers/net/tulip/interrupt.c94
-rw-r--r--drivers/net/tulip/media.c8
-rw-r--r--drivers/net/tulip/tulip.h32
-rw-r--r--drivers/net/tulip/tulip_core.c45
-rw-r--r--drivers/net/tulip/uli526x.c2
-rw-r--r--drivers/net/tulip/winbond-840.c7
-rw-r--r--drivers/net/tun.c528
-rw-r--r--drivers/net/typhoon-firmware.h3778
-rw-r--r--drivers/net/typhoon.c104
-rw-r--r--drivers/net/typhoon.h234
-rw-r--r--drivers/net/ucc_geth.c129
-rw-r--r--drivers/net/ucc_geth.h21
-rw-r--r--drivers/net/ucc_geth_ethtool.c2
-rw-r--r--drivers/net/ucc_geth_mii.c295
-rw-r--r--drivers/net/ucc_geth_mii.h101
-rw-r--r--drivers/net/usb/asix.c47
-rw-r--r--drivers/net/usb/catc.c52
-rw-r--r--drivers/net/usb/dm9601.c16
-rw-r--r--drivers/net/usb/hso.c83
-rw-r--r--drivers/net/usb/kaweth.c7
-rw-r--r--drivers/net/usb/mcs7830.c16
-rw-r--r--drivers/net/usb/rndis_host.c38
-rw-r--r--drivers/net/usb/rtl8150.c48
-rw-r--r--drivers/net/usb/smsc95xx.c25
-rw-r--r--drivers/net/usb/usbnet.c40
-rw-r--r--drivers/net/veth.c45
-rw-r--r--drivers/net/via-rhine.c9
-rw-r--r--drivers/net/via-velocity.h6
-rw-r--r--drivers/net/virtio_net.c245
-rw-r--r--drivers/net/vxge/Makefile7
-rw-r--r--drivers/net/vxge/vxge-config.c5264
-rw-r--r--drivers/net/vxge/vxge-config.h2259
-rw-r--r--drivers/net/vxge/vxge-ethtool.c1148
-rw-r--r--drivers/net/vxge/vxge-ethtool.h67
-rw-r--r--drivers/net/vxge/vxge-main.c4502
-rw-r--r--drivers/net/vxge/vxge-main.h557
-rw-r--r--drivers/net/vxge/vxge-reg.h4608
-rw-r--r--drivers/net/vxge/vxge-traffic.c2528
-rw-r--r--drivers/net/vxge/vxge-traffic.h2409
-rw-r--r--drivers/net/vxge/vxge-version.h23
-rw-r--r--drivers/net/wan/c101.c12
-rw-r--r--drivers/net/wan/cosa.c21
-rw-r--r--drivers/net/wan/cycx_x25.c41
-rw-r--r--drivers/net/wan/dlci.c54
-rw-r--r--drivers/net/wan/dscc4.c18
-rw-r--r--drivers/net/wan/farsync.c20
-rw-r--r--drivers/net/wan/hd64572.c4
-rw-r--r--drivers/net/wan/hdlc.c33
-rw-r--r--drivers/net/wan/hdlc_cisco.c17
-rw-r--r--drivers/net/wan/hdlc_fr.c44
-rw-r--r--drivers/net/wan/hdlc_ppp.c6
-rw-r--r--drivers/net/wan/hdlc_raw.c5
-rw-r--r--drivers/net/wan/hdlc_raw_eth.c8
-rw-r--r--drivers/net/wan/hdlc_x25.c2
-rw-r--r--drivers/net/wan/hostess_sv11.c12
-rw-r--r--drivers/net/wan/ixp4xx_hss.c24
-rw-r--r--drivers/net/wan/lapbether.c39
-rw-r--r--drivers/net/wan/lmc/lmc_main.c19
-rw-r--r--drivers/net/wan/lmc/lmc_proto.c17
-rw-r--r--drivers/net/wan/n2.c12
-rw-r--r--drivers/net/wan/pc300too.c12
-rw-r--r--drivers/net/wan/pci200syn.c12
-rw-r--r--drivers/net/wan/sbni.c105
-rw-r--r--drivers/net/wan/sdla.c36
-rw-r--r--drivers/net/wan/sealevel.c12
-rw-r--r--drivers/net/wan/wanxl.c14
-rw-r--r--drivers/net/wan/x25_asy.c44
-rw-r--r--drivers/net/wan/x25_asy.h4
-rw-r--r--drivers/net/wan/z85230.c3
-rw-r--r--drivers/net/wimax/i2400m/Makefile1
-rw-r--r--drivers/net/wimax/i2400m/control.c147
-rw-r--r--drivers/net/wimax/i2400m/debug-levels.h1
-rw-r--r--drivers/net/wimax/i2400m/driver.c28
-rw-r--r--drivers/net/wimax/i2400m/fw.c65
-rw-r--r--drivers/net/wimax/i2400m/i2400m.h91
-rw-r--r--drivers/net/wimax/i2400m/netdev.c120
-rw-r--r--drivers/net/wimax/i2400m/rx.c749
-rw-r--r--drivers/net/wimax/i2400m/sdio.c27
-rw-r--r--drivers/net/wimax/i2400m/sysfs.c80
-rw-r--r--drivers/net/wimax/i2400m/usb-notif.c2
-rw-r--r--drivers/net/wimax/i2400m/usb.c30
-rw-r--r--drivers/net/wireless/Kconfig146
-rw-r--r--drivers/net/wireless/Makefile5
-rw-r--r--drivers/net/wireless/airo.c1209
-rw-r--r--drivers/net/wireless/airo_cs.c73
-rw-r--r--drivers/net/wireless/ar9170/Kconfig17
-rw-r--r--drivers/net/wireless/ar9170/Makefile3
-rw-r--r--drivers/net/wireless/ar9170/ar9170.h209
-rw-r--r--drivers/net/wireless/ar9170/cmd.c129
-rw-r--r--drivers/net/wireless/ar9170/cmd.h91
-rw-r--r--drivers/net/wireless/ar9170/eeprom.h179
-rw-r--r--drivers/net/wireless/ar9170/hw.h417
-rw-r--r--drivers/net/wireless/ar9170/led.c171
-rw-r--r--drivers/net/wireless/ar9170/mac.c452
-rw-r--r--drivers/net/wireless/ar9170/main.c1671
-rw-r--r--drivers/net/wireless/ar9170/phy.c1240
-rw-r--r--drivers/net/wireless/ar9170/usb.c748
-rw-r--r--drivers/net/wireless/ar9170/usb.h74
-rw-r--r--drivers/net/wireless/arlan-main.c21
-rw-r--r--drivers/net/wireless/at76c50x-usb.c2501
-rw-r--r--drivers/net/wireless/at76c50x-usb.h463
-rw-r--r--drivers/net/wireless/ath5k/Makefile1
-rw-r--r--drivers/net/wireless/ath5k/ath5k.h115
-rw-r--r--drivers/net/wireless/ath5k/attach.c33
-rw-r--r--drivers/net/wireless/ath5k/base.c364
-rw-r--r--drivers/net/wireless/ath5k/base.h6
-rw-r--r--drivers/net/wireless/ath5k/caps.c6
-rw-r--r--drivers/net/wireless/ath5k/debug.c53
-rw-r--r--drivers/net/wireless/ath5k/debug.h1
-rw-r--r--drivers/net/wireless/ath5k/desc.c4
-rw-r--r--drivers/net/wireless/ath5k/eeprom.c839
-rw-r--r--drivers/net/wireless/ath5k/eeprom.h129
-rw-r--r--drivers/net/wireless/ath5k/gpio.c10
-rw-r--r--drivers/net/wireless/ath5k/initvals.c1575
-rw-r--r--drivers/net/wireless/ath5k/led.c176
-rw-r--r--drivers/net/wireless/ath5k/pcu.c23
-rw-r--r--drivers/net/wireless/ath5k/phy.c3197
-rw-r--r--drivers/net/wireless/ath5k/qcu.c47
-rw-r--r--drivers/net/wireless/ath5k/reg.h143
-rw-r--r--drivers/net/wireless/ath5k/reset.c959
-rw-r--r--drivers/net/wireless/ath5k/rfbuffer.h1181
-rw-r--r--drivers/net/wireless/ath5k/rfgain.h516
-rw-r--r--drivers/net/wireless/ath9k/Makefile3
-rw-r--r--drivers/net/wireless/ath9k/ahb.c192
-rw-r--r--drivers/net/wireless/ath9k/ani.c290
-rw-r--r--drivers/net/wireless/ath9k/ani.h138
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h1700
-rw-r--r--drivers/net/wireless/ath9k/beacon.c814
-rw-r--r--drivers/net/wireless/ath9k/calib.c555
-rw-r--r--drivers/net/wireless/ath9k/calib.h124
-rw-r--r--drivers/net/wireless/ath9k/core.h754
-rw-r--r--drivers/net/wireless/ath9k/debug.c417
-rw-r--r--drivers/net/wireless/ath9k/debug.h165
-rw-r--r--drivers/net/wireless/ath9k/eeprom.c3325
-rw-r--r--drivers/net/wireless/ath9k/eeprom.h507
-rw-r--r--drivers/net/wireless/ath9k/hw.c1733
-rw-r--r--drivers/net/wireless/ath9k/hw.h1559
-rw-r--r--drivers/net/wireless/ath9k/initvals.h718
-rw-r--r--drivers/net/wireless/ath9k/mac.c235
-rw-r--r--drivers/net/wireless/ath9k/mac.h680
-rw-r--r--drivers/net/wireless/ath9k/main.c1945
-rw-r--r--drivers/net/wireless/ath9k/pci.c295
-rw-r--r--drivers/net/wireless/ath9k/phy.c242
-rw-r--r--drivers/net/wireless/ath9k/phy.h51
-rw-r--r--drivers/net/wireless/ath9k/rc.c350
-rw-r--r--drivers/net/wireless/ath9k/rc.h30
-rw-r--r--drivers/net/wireless/ath9k/recv.c179
-rw-r--r--drivers/net/wireless/ath9k/reg.h125
-rw-r--r--drivers/net/wireless/ath9k/regd.c1248
-rw-r--r--drivers/net/wireless/ath9k/regd.h209
-rw-r--r--drivers/net/wireless/ath9k/regd_common.h2060
-rw-r--r--drivers/net/wireless/ath9k/virtual.c662
-rw-r--r--drivers/net/wireless/ath9k/xmit.c2891
-rw-r--r--drivers/net/wireless/atmel.c483
-rw-r--r--drivers/net/wireless/b43/Kconfig14
-rw-r--r--drivers/net/wireless/b43/Makefile1
-rw-r--r--drivers/net/wireless/b43/b43.h43
-rw-r--r--drivers/net/wireless/b43/debugfs.c48
-rw-r--r--drivers/net/wireless/b43/debugfs.h5
-rw-r--r--drivers/net/wireless/b43/dma.c65
-rw-r--r--drivers/net/wireless/b43/dma.h17
-rw-r--r--drivers/net/wireless/b43/lo.c77
-rw-r--r--drivers/net/wireless/b43/main.c460
-rw-r--r--drivers/net/wireless/b43/main.h25
-rw-r--r--drivers/net/wireless/b43/phy_a.c111
-rw-r--r--drivers/net/wireless/b43/phy_g.c614
-rw-r--r--drivers/net/wireless/b43/phy_lp.c395
-rw-r--r--drivers/net/wireless/b43/phy_lp.h329
-rw-r--r--drivers/net/wireless/b43/pio.c16
-rw-r--r--drivers/net/wireless/b43/rfkill.c2
-rw-r--r--drivers/net/wireless/b43/tables_lpphy.c394
-rw-r--r--drivers/net/wireless/b43/tables_lpphy.h31
-rw-r--r--drivers/net/wireless/b43/wa.c113
-rw-r--r--drivers/net/wireless/b43/xmit.c19
-rw-r--r--drivers/net/wireless/b43legacy/leds.c8
-rw-r--r--drivers/net/wireless/b43legacy/main.c2
-rw-r--r--drivers/net/wireless/hostap/hostap.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_80211.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c111
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c51
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c146
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.h6
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c37
-rw-r--r--drivers/net/wireless/hostap/hostap_info.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c7
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c117
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h1
-rw-r--r--drivers/net/wireless/ipw2x00/Kconfig3
-rw-r--r--drivers/net/wireless/ipw2x00/ieee80211.h (renamed from include/net/ieee80211.h)112
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c76
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.h8
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c199
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.h7
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_geo.c2
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c49
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_rx.c122
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_tx.c12
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_wx.c27
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig99
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c73
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-commands.h1702
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-debug.h167
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-fh.h188
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h229
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-io.h404
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c77
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.h50
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c298
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.h206
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c1190
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h761
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c222
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000-hw.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c246
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000-hw.h (renamed from drivers/net/wireless/iwlwifi/iwl-3945-core.h)59
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c158
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c108
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c290
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h57
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c1515
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c93
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h511
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c793
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h101
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h183
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c73
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h139
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fh.h21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h54
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.h44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c104
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c60
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c184
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-spectrum.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c109
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c305
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c5586
-rw-r--r--drivers/net/wireless/libertas/Makefile2
-rw-r--r--drivers/net/wireless/libertas/cmd.c2
-rw-r--r--drivers/net/wireless/libertas/debugfs.c14
-rw-r--r--drivers/net/wireless/libertas/defs.h3
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/host.h1
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h8
-rw-r--r--drivers/net/wireless/libertas/if_cs.c4
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c20
-rw-r--r--drivers/net/wireless/libertas/if_spi.c1218
-rw-r--r--drivers/net/wireless/libertas/if_spi.h208
-rw-r--r--drivers/net/wireless/libertas/main.c74
-rw-r--r--drivers/net/wireless/libertas/radiotap.h10
-rw-r--r--drivers/net/wireless/libertas/rx.c30
-rw-r--r--drivers/net/wireless/libertas/scan.c2
-rw-r--r--drivers/net/wireless/libertas/tx.c8
-rw-r--r--drivers/net/wireless/libertas/wext.c2
-rw-r--r--drivers/net/wireless/libertas_tf/cmd.c2
-rw-r--r--drivers/net/wireless/libertas_tf/libertas_tf.h2
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c362
-rw-r--r--drivers/net/wireless/mwl8k.c3789
-rw-r--r--drivers/net/wireless/netwave_cs.c91
-rw-r--r--drivers/net/wireless/orinoco/Kconfig120
-rw-r--r--drivers/net/wireless/orinoco/Makefile3
-rw-r--r--drivers/net/wireless/orinoco/airport.c37
-rw-r--r--drivers/net/wireless/orinoco/fw.c390
-rw-r--r--drivers/net/wireless/orinoco/fw.h21
-rw-r--r--drivers/net/wireless/orinoco/hermes.c116
-rw-r--r--drivers/net/wireless/orinoco/hermes.h35
-rw-r--r--drivers/net/wireless/orinoco/hermes_dld.c132
-rw-r--r--drivers/net/wireless/orinoco/hermes_dld.h12
-rw-r--r--drivers/net/wireless/orinoco/hw.c586
-rw-r--r--drivers/net/wireless/orinoco/hw.h47
-rw-r--r--drivers/net/wireless/orinoco/main.c2667
-rw-r--r--drivers/net/wireless/orinoco/main.h63
-rw-r--r--drivers/net/wireless/orinoco/mic.c79
-rw-r--r--drivers/net/wireless/orinoco/mic.h22
-rw-r--r--drivers/net/wireless/orinoco/orinoco.c6159
-rw-r--r--drivers/net/wireless/orinoco/orinoco.h28
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c33
-rw-r--r--drivers/net/wireless/orinoco/orinoco_nortel.c7
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.c5
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.h12
-rw-r--r--drivers/net/wireless/orinoco/orinoco_plx.c3
-rw-r--r--drivers/net/wireless/orinoco/orinoco_tmd.c4
-rw-r--r--drivers/net/wireless/orinoco/scan.c233
-rw-r--r--drivers/net/wireless/orinoco/scan.h29
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c19
-rw-r--r--drivers/net/wireless/orinoco/wext.c2325
-rw-r--r--drivers/net/wireless/orinoco/wext.h13
-rw-r--r--drivers/net/wireless/p54/Kconfig47
-rw-r--r--drivers/net/wireless/p54/Makefile1
-rw-r--r--drivers/net/wireless/p54/p54.h64
-rw-r--r--drivers/net/wireless/p54/p54common.c783
-rw-r--r--drivers/net/wireless/p54/p54common.h132
-rw-r--r--drivers/net/wireless/p54/p54pci.c42
-rw-r--r--drivers/net/wireless/p54/p54spi.c765
-rw-r--r--drivers/net/wireless/p54/p54spi.h125
-rw-r--r--drivers/net/wireless/p54/p54spi_eeprom.h678
-rw-r--r--drivers/net/wireless/p54/p54usb.c94
-rw-r--r--drivers/net/wireless/p54/p54usb.h1
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c3
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c39
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h3
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c18
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.h6
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c2
-rw-r--r--drivers/net/wireless/ray_cs.c3815
-rw-r--r--drivers/net/wireless/rndis_wlan.c117
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig7
-rw-r--r--drivers/net/wireless/rt2x00/Makefile1
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c103
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c131
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c72
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.h14
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h154
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c15
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c49
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c416
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dump.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00firmware.c29
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00leds.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h106
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c471
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c77
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c216
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h17
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h22
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00rfkill.c127
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c64
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h13
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c244
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h13
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c210
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h19
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187.h4
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c86
-rw-r--r--drivers/net/wireless/strip.c28
-rw-r--r--drivers/net/wireless/wavelan.c90
-rw-r--r--drivers/net/wireless/wavelan.p.h9
-rw-r--r--drivers/net/wireless/wavelan_cs.c79
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h6
-rw-r--r--drivers/net/wireless/wl3501.h2
-rw-r--r--drivers/net/wireless/wl3501_cs.c51
-rw-r--r--drivers/net/wireless/zd1201.c54
-rw-r--r--drivers/net/wireless/zd1201.h1
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c21
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.h2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_def.h5
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c46
-rw-r--r--drivers/net/xen-netfront.c10
-rw-r--r--drivers/net/xtsonic.c2
-rw-r--r--drivers/net/yellowfin.c6
-rw-r--r--drivers/net/znet.c17
-rw-r--r--drivers/of/base.c1
-rw-r--r--drivers/oprofile/buffer_sync.c20
-rw-r--r--drivers/oprofile/buffer_sync.h4
-rw-r--r--drivers/oprofile/oprof.c9
-rw-r--r--drivers/parisc/asp.c2
-rw-r--r--drivers/parisc/ccio-dma.c16
-rw-r--r--drivers/parisc/dino.c7
-rw-r--r--drivers/parisc/eisa.c2
-rw-r--r--drivers/parisc/eisa_enumerator.c4
-rw-r--r--drivers/parisc/iosapic.c2
-rw-r--r--drivers/parisc/led.c26
-rw-r--r--drivers/parport/parport_serial.c30
-rw-r--r--drivers/pci/Kconfig10
-rw-r--r--drivers/pci/Makefile2
-rw-r--r--drivers/pci/bus.c8
-rw-r--r--drivers/pci/dmar.c361
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c58
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c3
-rw-r--r--drivers/pci/hotplug/fakephp.c444
-rw-r--r--drivers/pci/hotplug/pciehp.h13
-rw-r--r--drivers/pci/hotplug/pciehp_acpi.c21
-rw-r--r--drivers/pci/hotplug/pciehp_core.c18
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c34
-rw-r--r--drivers/pci/hotplug/shpchp.h10
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c2
-rw-r--r--drivers/pci/intel-iommu.c620
-rw-r--r--drivers/pci/intr_remapping.c192
-rw-r--r--drivers/pci/iov.c680
-rw-r--r--drivers/pci/msi.c426
-rw-r--r--drivers/pci/msi.h6
-rw-r--r--drivers/pci/pci-acpi.c219
-rw-r--r--drivers/pci/pci-driver.c261
-rw-r--r--drivers/pci/pci-sysfs.c124
-rw-r--r--drivers/pci/pci.c337
-rw-r--r--drivers/pci/pci.h66
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c28
-rw-r--r--drivers/pci/pcie/aer/aerdrv_acpi.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c10
-rw-r--r--drivers/pci/pcie/portdrv.h14
-rw-r--r--drivers/pci/pcie/portdrv_bus.c18
-rw-r--r--drivers/pci/pcie/portdrv_core.c379
-rw-r--r--drivers/pci/pcie/portdrv_pci.c50
-rw-r--r--drivers/pci/probe.c210
-rw-r--r--drivers/pci/quirks.c221
-rw-r--r--drivers/pci/remove.c4
-rw-r--r--drivers/pci/search.c2
-rw-r--r--drivers/pci/setup-bus.c7
-rw-r--r--drivers/pci/setup-res.c15
-rw-r--r--drivers/pci/slot.c18
-rw-r--r--drivers/pcmcia/au1000_generic.c37
-rw-r--r--drivers/pcmcia/i82365.c28
-rw-r--r--drivers/pcmcia/m32r_cfc.c30
-rw-r--r--drivers/pcmcia/m32r_pcc.c30
-rw-r--r--drivers/pcmcia/pxa2xx_base.c89
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x255.c3
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x270.c1
-rw-r--r--drivers/pcmcia/pxa2xx_e740.c2
-rw-r--r--drivers/pcmcia/pxa2xx_lubbock.c1
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c3
-rw-r--r--drivers/pcmcia/pxa2xx_palmld.c4
-rw-r--r--drivers/pcmcia/pxa2xx_trizeps4.c3
-rw-r--r--drivers/pcmcia/pxa2xx_viper.c1
-rw-r--r--drivers/pcmcia/rsrc_mgr.c2
-rw-r--r--drivers/pcmcia/sa1100_generic.c38
-rw-r--r--drivers/pcmcia/sa1100_h3600.c23
-rw-r--r--drivers/pcmcia/sa1111_generic.c2
-rw-r--r--drivers/pcmcia/sa11xx_base.c50
-rw-r--r--drivers/pcmcia/soc_common.c54
-rw-r--r--drivers/pcmcia/soc_common.h7
-rw-r--r--drivers/pcmcia/tcic.c30
-rw-r--r--drivers/pcmcia/vrc4171_card.c34
-rw-r--r--drivers/platform/x86/Kconfig35
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/acer-wmi.c35
-rw-r--r--drivers/platform/x86/asus_acpi.c3
-rw-r--r--drivers/platform/x86/dell-laptop.c4
-rw-r--r--drivers/platform/x86/dell-wmi.c210
-rw-r--r--drivers/platform/x86/hp-wmi.c25
-rw-r--r--drivers/platform/x86/intel_menlow.c29
-rw-r--r--drivers/platform/x86/panasonic-laptop.c9
-rw-r--r--drivers/platform/x86/sony-laptop.c538
-rw-r--r--drivers/platform/x86/tc1100-wmi.c7
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c739
-rw-r--r--drivers/platform/x86/toshiba_acpi.c3
-rw-r--r--drivers/pnp/pnpacpi/core.c23
-rw-r--r--drivers/pnp/pnpbios/core.c16
-rw-r--r--drivers/power/bq27x00_battery.c2
-rw-r--r--drivers/power/power_supply_sysfs.c2
-rw-r--r--drivers/ps3/ps3av.c16
-rw-r--r--drivers/rapidio/rio-driver.c2
-rw-r--r--drivers/regulator/Kconfig13
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/bq24022.c3
-rw-r--r--drivers/regulator/core.c386
-rw-r--r--drivers/regulator/da903x.c3
-rw-r--r--drivers/regulator/fixed.c3
-rw-r--r--drivers/regulator/pcf50633-regulator.c3
-rw-r--r--drivers/regulator/twl4030-regulator.c500
-rw-r--r--drivers/regulator/virtual.c14
-rw-r--r--drivers/regulator/wm8350-regulator.c57
-rw-r--r--drivers/regulator/wm8400-regulator.c36
-rw-r--r--drivers/rtc/Kconfig50
-rw-r--r--drivers/rtc/Makefile5
-rw-r--r--drivers/rtc/rtc-at91sam9.c4
-rw-r--r--drivers/rtc/rtc-ds1307.c189
-rw-r--r--drivers/rtc/rtc-ds1374.c6
-rw-r--r--drivers/rtc/rtc-efi.c235
-rw-r--r--drivers/rtc/rtc-generic.c84
-rw-r--r--drivers/rtc/rtc-lib.c7
-rw-r--r--drivers/rtc/rtc-m41t80.c18
-rw-r--r--drivers/rtc/rtc-mv.c11
-rw-r--r--drivers/rtc/rtc-omap.c4
-rw-r--r--drivers/rtc/rtc-parisc.c112
-rw-r--r--drivers/rtc/rtc-ppc.c69
-rw-r--r--drivers/rtc/rtc-proc.c10
-rw-r--r--drivers/rtc/rtc-ps3.c104
-rw-r--r--drivers/rtc/rtc-sa1100.c3
-rw-r--r--drivers/rtc/rtc-sh.c282
-rw-r--r--drivers/rtc/rtc-twl4030.c2
-rw-r--r--drivers/rtc/rtc-v3020.c230
-rw-r--r--drivers/rtc/rtc-wm8350.c43
-rw-r--r--drivers/s390/Makefile3
-rw-r--r--drivers/s390/block/dasd.c250
-rw-r--r--drivers/s390/block/dasd_3990_erp.c871
-rw-r--r--drivers/s390/block/dasd_alias.c35
-rw-r--r--drivers/s390/block/dasd_devmap.c43
-rw-r--r--drivers/s390/block/dasd_diag.c66
-rw-r--r--drivers/s390/block/dasd_eckd.c1297
-rw-r--r--drivers/s390/block/dasd_eckd.h49
-rw-r--r--drivers/s390/block/dasd_eer.c27
-rw-r--r--drivers/s390/block/dasd_erp.c21
-rw-r--r--drivers/s390/block/dasd_fba.c77
-rw-r--r--drivers/s390/block/dasd_genhd.c7
-rw-r--r--drivers/s390/block/dasd_int.h13
-rw-r--r--drivers/s390/block/dasd_ioctl.c46
-rw-r--r--drivers/s390/block/dasd_proc.c24
-rw-r--r--drivers/s390/char/tape.h2
-rw-r--r--drivers/s390/char/tape_34xx.c161
-rw-r--r--drivers/s390/char/tape_3590.c367
-rw-r--r--drivers/s390/char/tape_block.c18
-rw-r--r--drivers/s390/char/tape_char.c7
-rw-r--r--drivers/s390/char/tape_core.c68
-rw-r--r--drivers/s390/char/tape_proc.c3
-rw-r--r--drivers/s390/char/tape_std.c25
-rw-r--r--drivers/s390/char/zcore.c90
-rw-r--r--drivers/s390/cio/Makefile2
-rw-r--r--drivers/s390/cio/airq.c6
-rw-r--r--drivers/s390/cio/blacklist.c3
-rw-r--r--drivers/s390/cio/ccwgroup.c78
-rw-r--r--drivers/s390/cio/chp.c6
-rw-r--r--drivers/s390/cio/chsc.c7
-rw-r--r--drivers/s390/cio/chsc_sch.c4
-rw-r--r--drivers/s390/cio/cio.c21
-rw-r--r--drivers/s390/cio/crw.c159
-rw-r--r--drivers/s390/cio/css.c62
-rw-r--r--drivers/s390/cio/device.c100
-rw-r--r--drivers/s390/cio/device.h3
-rw-r--r--drivers/s390/cio/device_fsm.c39
-rw-r--r--drivers/s390/cio/device_ops.c2
-rw-r--r--drivers/s390/cio/qdio.h8
-rw-r--r--drivers/s390/cio/qdio_debug.c3
-rw-r--r--drivers/s390/cio/qdio_main.c222
-rw-r--r--drivers/s390/cio/qdio_setup.c1
-rw-r--r--drivers/s390/cio/qdio_thinint.c23
-rw-r--r--drivers/s390/crypto/zcrypt_api.c6
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c3
-rw-r--r--drivers/s390/ebcdic.c246
-rw-r--r--drivers/s390/net/Makefile2
-rw-r--r--drivers/s390/net/claw.c485
-rw-r--r--drivers/s390/net/ctcm_fsms.c5
-rw-r--r--drivers/s390/net/ctcm_main.c39
-rw-r--r--drivers/s390/net/ctcm_mpc.c17
-rw-r--r--drivers/s390/net/lcs.c33
-rw-r--r--drivers/s390/net/netiucv.c16
-rw-r--r--drivers/s390/net/qeth_core.h8
-rw-r--r--drivers/s390/net/qeth_core_main.c165
-rw-r--r--drivers/s390/net/qeth_core_offl.c699
-rw-r--r--drivers/s390/net/qeth_core_offl.h76
-rw-r--r--drivers/s390/net/qeth_core_sys.c4
-rw-r--r--drivers/s390/net/qeth_l2_main.c99
-rw-r--r--drivers/s390/net/qeth_l3_main.c129
-rw-r--r--drivers/s390/s390mach.h122
-rw-r--r--drivers/s390/scsi/zfcp_aux.c24
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c29
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c188
-rw-r--r--drivers/s390/scsi/zfcp_dbf.h3
-rw-r--r--drivers/s390/scsi/zfcp_def.h17
-rw-r--r--drivers/s390/scsi/zfcp_erp.c290
-rw-r--r--drivers/s390/scsi/zfcp_ext.h73
-rw-r--r--drivers/s390/scsi/zfcp_fc.c84
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c240
-rw-r--r--drivers/s390/scsi/zfcp_fsf.h4
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c47
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c250
-rw-r--r--drivers/s390/scsi/zfcp_sysfs.c20
-rw-r--r--drivers/sbus/char/openprom.c1
-rw-r--r--drivers/scsi/3w-9xxx.c101
-rw-r--r--drivers/scsi/3w-9xxx.h2
-rw-r--r--drivers/scsi/Kconfig39
-rw-r--r--drivers/scsi/Makefile4
-rw-r--r--drivers/scsi/a2091.c6
-rw-r--r--drivers/scsi/a2091.h3
-rw-r--r--drivers/scsi/a3000.c6
-rw-r--r--drivers/scsi/a3000.h3
-rw-r--r--drivers/scsi/a4000t.c29
-rw-r--r--drivers/scsi/aacraid/aachba.c40
-rw-r--r--drivers/scsi/aacraid/aacraid.h9
-rw-r--r--drivers/scsi/aacraid/comminit.c14
-rw-r--r--drivers/scsi/aacraid/linit.c8
-rw-r--r--drivers/scsi/advansys.c1731
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_core.c12
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_inline.h32
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h102
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_pci.c8
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_inline.h5
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h104
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_pci.c10
-rw-r--r--drivers/scsi/aic7xxx/aiclib.h4
-rw-r--r--drivers/scsi/arm/cumana_2.c5
-rw-r--r--drivers/scsi/arm/eesox.c3
-rw-r--r--drivers/scsi/arm/powertec.c3
-rw-r--r--drivers/scsi/atari_NCR5380.c2
-rw-r--r--drivers/scsi/atari_scsi.c2
-rw-r--r--drivers/scsi/bvme6000_scsi.c29
-rw-r--r--drivers/scsi/ch.c1
-rw-r--r--drivers/scsi/constants.c13
-rw-r--r--drivers/scsi/cxgb3i/Kbuild4
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i.h10
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.c280
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.h14
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_init.c31
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_iscsi.c154
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.c98
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.h12
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_pdu.c2
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c14
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c49
-rw-r--r--drivers/scsi/fcoe/Makefile8
-rw-r--r--drivers/scsi/fcoe/fc_transport_fcoe.c443
-rw-r--r--drivers/scsi/fcoe/fcoe.c1878
-rw-r--r--drivers/scsi/fcoe/fcoe.h75
-rw-r--r--drivers/scsi/fcoe/fcoe_sw.c496
-rw-r--r--drivers/scsi/fcoe/libfcoe.c2204
-rw-r--r--drivers/scsi/hosts.c3
-rw-r--r--drivers/scsi/hptiop.c3
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c188
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h16
-rw-r--r--drivers/scsi/ipr.c13
-rw-r--r--drivers/scsi/ipr.h4
-rw-r--r--drivers/scsi/ips.c3
-rw-r--r--drivers/scsi/iscsi_tcp.c73
-rw-r--r--drivers/scsi/libfc/fc_exch.c6
-rw-r--r--drivers/scsi/libfc/fc_fcp.c85
-rw-r--r--drivers/scsi/libfc/fc_lport.c16
-rw-r--r--drivers/scsi/libfc/fc_rport.c2
-rw-r--r--drivers/scsi/libiscsi.c240
-rw-r--r--drivers/scsi/libiscsi_tcp.c122
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c16
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c6
-rw-r--r--drivers/scsi/mpt2sas/Kconfig66
-rw-r--r--drivers/scsi/mpt2sas/Makefile7
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2.h1067
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h2151
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_init.h420
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_ioc.h1295
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_raid.h295
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_sas.h282
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_tool.h249
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_type.h61
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c3435
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h779
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c1873
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c2516
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.h416
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_debug.h181
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c5687
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c1211
-rw-r--r--drivers/scsi/mvme16x_scsi.c29
-rw-r--r--drivers/scsi/osd/Kbuild45
-rw-r--r--drivers/scsi/osd/Kconfig53
-rwxr-xr-xdrivers/scsi/osd/Makefile37
-rw-r--r--drivers/scsi/osd/osd_debug.h30
-rw-r--r--drivers/scsi/osd/osd_initiator.c1663
-rw-r--r--drivers/scsi/osd/osd_uld.c481
-rw-r--r--drivers/scsi/osst.c96
-rw-r--r--drivers/scsi/osst.h2
-rw-r--r--drivers/scsi/ql1040_fw.h2130
-rw-r--r--drivers/scsi/ql12160_fw.h1811
-rw-r--r--drivers/scsi/ql1280_fw.h2048
-rw-r--r--drivers/scsi/qla1280.c114
-rw-r--r--drivers/scsi/qla1280.h6
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c295
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h136
-rw-r--r--drivers/scsi/qla2xxx/qla_dfs.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h42
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h25
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c136
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c37
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c32
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c238
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c12
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c258
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c103
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h4
-rw-r--r--drivers/scsi/qlogicpti.c63
-rw-r--r--drivers/scsi/qlogicpti_asm.c1160
-rw-r--r--drivers/scsi/scsi.c108
-rw-r--r--drivers/scsi/scsi_debug.c443
-rw-r--r--drivers/scsi/scsi_devinfo.c2
-rw-r--r--drivers/scsi/scsi_error.c34
-rw-r--r--drivers/scsi/scsi_lib.c220
-rw-r--r--drivers/scsi/scsi_proc.c3
-rw-r--r--drivers/scsi/scsi_scan.c1
-rw-r--r--drivers/scsi/scsi_sysfs.c1
-rw-r--r--drivers/scsi/scsi_transport_fc.c18
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c57
-rw-r--r--drivers/scsi/sd.c355
-rw-r--r--drivers/scsi/sd.h1
-rw-r--r--drivers/scsi/ses.c35
-rw-r--r--drivers/scsi/sg.c526
-rw-r--r--drivers/scsi/sr.c9
-rw-r--r--drivers/scsi/st.c6
-rw-r--r--drivers/scsi/stex.c823
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c137
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.h6
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c66
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.h10
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_malloc.c2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_misc.h18
-rw-r--r--drivers/serial/21285.c2
-rw-r--r--drivers/serial/8250_pci.c412
-rw-r--r--drivers/serial/8250_pnp.c7
-rw-r--r--drivers/serial/Kconfig6
-rw-r--r--drivers/serial/atmel_serial.c9
-rw-r--r--drivers/serial/bfin_5xx.c15
-rw-r--r--drivers/serial/clps711x.c2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c14
-rw-r--r--drivers/serial/icom.c14
-rw-r--r--drivers/serial/imx.c2
-rw-r--r--drivers/serial/jsm/jsm_driver.c9
-rw-r--r--drivers/serial/jsm/jsm_tty.c4
-rw-r--r--drivers/serial/mcf.c2
-rw-r--r--drivers/serial/mpc52xx_uart.c40
-rw-r--r--drivers/serial/pxa.c30
-rw-r--r--drivers/serial/sa1100.c2
-rw-r--r--drivers/serial/serial_core.c76
-rw-r--r--drivers/serial/sh-sci.c12
-rw-r--r--drivers/serial/sh-sci.h15
-rw-r--r--drivers/serial/sunzilog.c4
-rw-r--r--drivers/serial/ucc_uart.c1
-rw-r--r--drivers/sh/intc.c115
-rw-r--r--drivers/sh/maple/maple.c471
-rw-r--r--drivers/sh/superhyway/superhyway.c4
-rw-r--r--drivers/spi/atmel_spi.c8
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c2
-rw-r--r--drivers/spi/omap2_mcspi.c6
-rw-r--r--drivers/spi/omap_uwire.c21
-rw-r--r--drivers/spi/orion_spi.c2
-rw-r--r--drivers/spi/pxa2xx_spi.c6
-rw-r--r--drivers/spi/spi_bfin5xx.c4
-rw-r--r--drivers/spi/spi_gpio.c21
-rw-r--r--drivers/spi/spi_imx.c5
-rw-r--r--drivers/spi/spi_mpc83xx.c368
-rw-r--r--drivers/spi/spi_txx9.c3
-rw-r--r--drivers/spi/xilinx_spi.c9
-rw-r--r--drivers/ssb/Kconfig16
-rw-r--r--drivers/ssb/Makefile1
-rw-r--r--drivers/ssb/b43_pci_bridge.c3
-rw-r--r--drivers/ssb/driver_chipcommon.c14
-rw-r--r--drivers/ssb/driver_chipcommon_pmu.c508
-rw-r--r--drivers/ssb/pci.c88
-rw-r--r--drivers/ssb/sprom.c36
-rw-r--r--drivers/ssb/ssb_private.h1
-rw-r--r--drivers/staging/Kconfig26
-rw-r--r--drivers/staging/Makefile11
-rw-r--r--drivers/staging/agnx/agnx.h14
-rw-r--r--drivers/staging/agnx/debug.h21
-rw-r--r--drivers/staging/agnx/pci.c75
-rw-r--r--drivers/staging/agnx/phy.c32
-rw-r--r--drivers/staging/agnx/rf.c23
-rw-r--r--drivers/staging/agnx/sta.c21
-rw-r--r--drivers/staging/agnx/sta.h2
-rw-r--r--drivers/staging/agnx/table.c12
-rw-r--r--drivers/staging/agnx/xmit.c216
-rw-r--r--drivers/staging/altpciechdma/altpciechdma.c80
-rw-r--r--drivers/staging/android/binder.c18
-rw-r--r--drivers/staging/android/ram_console.c8
-rw-r--r--drivers/staging/asus_oled/asus_oled.c149
-rw-r--r--drivers/staging/at76_usb/TODO9
-rw-r--r--drivers/staging/at76_usb/at76_usb.c21
-rw-r--r--drivers/staging/at76_usb/at76_usb.h87
-rw-r--r--drivers/staging/b3dfg/Kconfig9
-rw-r--r--drivers/staging/b3dfg/Makefile1
-rw-r--r--drivers/staging/b3dfg/TODO4
-rw-r--r--drivers/staging/b3dfg/b3dfg.c1119
-rw-r--r--drivers/staging/comedi/Kconfig18
-rw-r--r--drivers/staging/comedi/comedi.h83
-rw-r--r--drivers/staging/comedi/comedi_compat32.c128
-rw-r--r--drivers/staging/comedi/comedi_fops.c293
-rw-r--r--drivers/staging/comedi/comedi_fops.h1
-rw-r--r--drivers/staging/comedi/comedi_ksyms.c12
-rw-r--r--drivers/staging/comedi/comedi_rt.h9
-rw-r--r--drivers/staging/comedi/comedidev.h202
-rw-r--r--drivers/staging/comedi/comedilib.h114
-rw-r--r--drivers/staging/comedi/drivers.c187
-rw-r--r--drivers/staging/comedi/drivers/8253.h420
-rw-r--r--drivers/staging/comedi/drivers/8255.c442
-rw-r--r--drivers/staging/comedi/drivers/8255.h57
-rw-r--r--drivers/staging/comedi/drivers/Makefile113
-rw-r--r--drivers/staging/comedi/drivers/acl7225b.c149
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c1047
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h73
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c2032
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h74
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c1020
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h46
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c5363
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h271
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c861
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h47
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c3588
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h76
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c848
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h43
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c2049
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h57
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c1038
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h44
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c203
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h27
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h476
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.c3062
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.h462
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_eeprom.c1158
-rw-r--r--drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h457
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c1265
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h71
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c600
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h123
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c285
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h63
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c3045
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h165
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c542
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h64
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c1105
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h119
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c780
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h94
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c460
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h70
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c579
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h81
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c549
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h61
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c2697
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h241
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c3642
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h187
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c742
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h94
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c1691
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h62
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_035.c5
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1032.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1500.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1516.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1564.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_16xx.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1710.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2016.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2032.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2200.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3001.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3120.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3200.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3300.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3501.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3xxx.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_all.c18
-rw-r--r--drivers/staging/comedi/drivers/adl_pci6208.c391
-rw-r--r--drivers/staging/comedi/drivers/adl_pci7296.c174
-rw-r--r--drivers/staging/comedi/drivers/adl_pci7432.c202
-rw-r--r--drivers/staging/comedi/drivers/adl_pci8164.c512
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9111.c1391
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c2100
-rw-r--r--drivers/staging/comedi/drivers/adq12b.c394
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1710.c1568
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1723.c465
-rw-r--r--drivers/staging/comedi/drivers/adv_pci_dio.c1077
-rw-r--r--drivers/staging/comedi/drivers/aio_aio12_8.c226
-rw-r--r--drivers/staging/comedi/drivers/aio_iiro_16.c177
-rw-r--r--drivers/staging/comedi/drivers/am9513.h79
-rw-r--r--drivers/staging/comedi/drivers/amcc_s5933.h172
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.c1483
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236.c654
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc263.c431
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci224.c1545
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci230.c2977
-rw-r--r--drivers/staging/comedi/drivers/c6xdigio.c517
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c976
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas.c1831
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas64.c4222
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidda.c841
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidio.c294
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdas.c484
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdda.c474
-rw-r--r--drivers/staging/comedi/drivers/comedi_bond.c56
-rw-r--r--drivers/staging/comedi/drivers/comedi_fc.c14
-rw-r--r--drivers/staging/comedi/drivers/comedi_fc.h18
-rw-r--r--drivers/staging/comedi/drivers/comedi_parport.c44
-rw-r--r--drivers/staging/comedi/drivers/comedi_rt_timer.c728
-rw-r--r--drivers/staging/comedi/drivers/comedi_test.c80
-rw-r--r--drivers/staging/comedi/drivers/contec_pci_dio.c230
-rw-r--r--drivers/staging/comedi/drivers/daqboard2000.c877
-rw-r--r--drivers/staging/comedi/drivers/das08.c1068
-rw-r--r--drivers/staging/comedi/drivers/das08.h78
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c488
-rw-r--r--drivers/staging/comedi/drivers/das16.c1730
-rw-r--r--drivers/staging/comedi/drivers/das16m1.c765
-rw-r--r--drivers/staging/comedi/drivers/das1800.c1758
-rw-r--r--drivers/staging/comedi/drivers/das6402.c354
-rw-r--r--drivers/staging/comedi/drivers/das800.c894
-rw-r--r--drivers/staging/comedi/drivers/dmm32at.c1081
-rw-r--r--drivers/staging/comedi/drivers/dt2801.c697
-rw-r--r--drivers/staging/comedi/drivers/dt2811.c604
-rw-r--r--drivers/staging/comedi/drivers/dt2814.c383
-rw-r--r--drivers/staging/comedi/drivers/dt2815.c264
-rw-r--r--drivers/staging/comedi/drivers/dt2817.c178
-rw-r--r--drivers/staging/comedi/drivers/dt282x.c1471
-rw-r--r--drivers/staging/comedi/drivers/dt3000.c983
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c40
-rw-r--r--drivers/staging/comedi/drivers/fl512.c186
-rw-r--r--drivers/staging/comedi/drivers/gsc_hpdi.c1060
-rw-r--r--drivers/staging/comedi/drivers/icp_multi.c392
-rw-r--r--drivers/staging/comedi/drivers/icp_multi.h19
-rw-r--r--drivers/staging/comedi/drivers/ii_pci20kc.c612
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.c976
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.h681
-rw-r--r--drivers/staging/comedi/drivers/ke_counter.c254
-rw-r--r--drivers/staging/comedi/drivers/me4000.c296
-rw-r--r--drivers/staging/comedi/drivers/me4000.h268
-rw-r--r--drivers/staging/comedi/drivers/me_daq.c55
-rw-r--r--drivers/staging/comedi/drivers/mite.c63
-rw-r--r--drivers/staging/comedi/drivers/mite.h68
-rw-r--r--drivers/staging/comedi/drivers/mpc624.c386
-rw-r--r--drivers/staging/comedi/drivers/mpc8260cpm.c169
-rw-r--r--drivers/staging/comedi/drivers/multiq3.c333
-rw-r--r--drivers/staging/comedi/drivers/ni_6527.c489
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c809
-rw-r--r--drivers/staging/comedi/drivers/ni_660x.c1324
-rw-r--r--drivers/staging/comedi/drivers/ni_670x.c337
-rw-r--r--drivers/staging/comedi/drivers/ni_at_a2150.c909
-rw-r--r--drivers/staging/comedi/drivers/ni_at_ao.c454
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c513
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio16d.c860
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c841
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c598
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c2005
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.h85
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_cs.c573
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c5862
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c551
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c1302
-rw-r--r--drivers/staging/comedi/drivers/ni_pcimio.c1788
-rw-r--r--drivers/staging/comedi/drivers/ni_stc.h1498
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.c1691
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.h163
-rw-r--r--drivers/staging/comedi/drivers/ni_tio_internal.h774
-rw-r--r--drivers/staging/comedi/drivers/ni_tiocmd.c523
-rw-r--r--drivers/staging/comedi/drivers/pcl711.c623
-rw-r--r--drivers/staging/comedi/drivers/pcl724.c222
-rw-r--r--drivers/staging/comedi/drivers/pcl725.c111
-rw-r--r--drivers/staging/comedi/drivers/pcl726.c377
-rw-r--r--drivers/staging/comedi/drivers/pcl730.c168
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c1605
-rw-r--r--drivers/staging/comedi/drivers/pcl816.c1251
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c1988
-rw-r--r--drivers/staging/comedi/drivers/pcm3724.c307
-rw-r--r--drivers/staging/comedi/drivers/pcm3730.c152
-rw-r--r--drivers/staging/comedi/drivers/pcmad.c173
-rw-r--r--drivers/staging/comedi/drivers/pcmda12.c306
-rw-r--r--drivers/staging/comedi/drivers/pcmmio.c1333
-rw-r--r--drivers/staging/comedi/drivers/pcmuio.c1101
-rw-r--r--drivers/staging/comedi/drivers/plx9052.h86
-rw-r--r--drivers/staging/comedi/drivers/plx9080.h80
-rw-r--r--drivers/staging/comedi/drivers/poc.c247
-rw-r--r--drivers/staging/comedi/drivers/quatech_daqp_cs.c1363
-rw-r--r--drivers/staging/comedi/drivers/rtd520.c277
-rw-r--r--drivers/staging/comedi/drivers/rtd520.h676
-rw-r--r--drivers/staging/comedi/drivers/rti800.c458
-rw-r--r--drivers/staging/comedi/drivers/rti802.c151
-rw-r--r--drivers/staging/comedi/drivers/s526.c977
-rw-r--r--drivers/staging/comedi/drivers/s626.c2538
-rw-r--r--drivers/staging/comedi/drivers/s626.h1226
-rw-r--r--drivers/staging/comedi/drivers/serial2002.c870
-rw-r--r--drivers/staging/comedi/drivers/skel.c624
-rw-r--r--drivers/staging/comedi/drivers/ssv_dnp.c311
-rw-r--r--drivers/staging/comedi/drivers/unioxx5.c515
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c304
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c2028
-rw-r--r--drivers/staging/comedi/interrupt.h9
-rw-r--r--drivers/staging/comedi/kcomedilib/data.c22
-rw-r--r--drivers/staging/comedi/kcomedilib/dio.c18
-rw-r--r--drivers/staging/comedi/kcomedilib/get.c132
-rw-r--r--drivers/staging/comedi/kcomedilib/kcomedilib_main.c138
-rw-r--r--drivers/staging/comedi/kcomedilib/ksyms.c4
-rw-r--r--drivers/staging/comedi/pci_ids.h2
-rw-r--r--drivers/staging/comedi/proc.c17
-rw-r--r--drivers/staging/comedi/range.c35
-rw-r--r--drivers/staging/comedi/rt.c29
-rw-r--r--drivers/staging/comedi/rt_pend_tq.c8
-rw-r--r--drivers/staging/dst/Kconfig67
-rw-r--r--drivers/staging/dst/Makefile3
-rw-r--r--drivers/staging/dst/crypto.c731
-rw-r--r--drivers/staging/dst/dcore.c995
-rw-r--r--drivers/staging/dst/export.c657
-rw-r--r--drivers/staging/dst/state.c839
-rw-r--r--drivers/staging/dst/thread_pool.c345
-rw-r--r--drivers/staging/dst/trans.c335
-rw-r--r--drivers/staging/echo/bit_operations.h30
-rw-r--r--drivers/staging/echo/echo.c42
-rw-r--r--drivers/staging/echo/echo.h2
-rw-r--r--drivers/staging/echo/fir.h28
-rw-r--r--drivers/staging/echo/mmx.h408
-rw-r--r--drivers/staging/epl/Benchmark.h12
-rw-r--r--drivers/staging/epl/Debug.h48
-rw-r--r--drivers/staging/epl/Edrv8139.c108
-rw-r--r--drivers/staging/epl/EdrvFec.h6
-rw-r--r--drivers/staging/epl/EdrvFec5282.h340
-rw-r--r--drivers/staging/epl/EdrvSim.h4
-rw-r--r--drivers/staging/epl/Epl.h139
-rw-r--r--drivers/staging/epl/EplAmi.h121
-rw-r--r--drivers/staging/epl/EplApiGeneric.c188
-rw-r--r--drivers/staging/epl/EplApiLinuxKernel.c105
-rw-r--r--drivers/staging/epl/EplApiProcessImage.c31
-rw-r--r--drivers/staging/epl/EplDll.h50
-rw-r--r--drivers/staging/epl/EplDllCal.h2
-rw-r--r--drivers/staging/epl/EplDllk.c134
-rw-r--r--drivers/staging/epl/EplDllkCal.c14
-rw-r--r--drivers/staging/epl/EplDlluCal.c6
-rw-r--r--drivers/staging/epl/EplErrorHandlerk.c36
-rw-r--r--drivers/staging/epl/EplEvent.h8
-rw-r--r--drivers/staging/epl/EplEventk.c24
-rw-r--r--drivers/staging/epl/EplEventu.c25
-rw-r--r--drivers/staging/epl/EplFrame.h166
-rw-r--r--drivers/staging/epl/EplIdentu.c26
-rw-r--r--drivers/staging/epl/EplInc.h23
-rw-r--r--drivers/staging/epl/EplInstDef.h60
-rw-r--r--drivers/staging/epl/EplNmt.h2
-rw-r--r--drivers/staging/epl/EplNmtCnu.c39
-rw-r--r--drivers/staging/epl/EplNmtMnu.c121
-rw-r--r--drivers/staging/epl/EplNmtk.c30
-rw-r--r--drivers/staging/epl/EplNmtkCal.c2
-rw-r--r--drivers/staging/epl/EplNmtu.c22
-rw-r--r--drivers/staging/epl/EplNmtuCal.c2
-rw-r--r--drivers/staging/epl/EplObd.c444
-rw-r--r--drivers/staging/epl/EplObd.h58
-rw-r--r--drivers/staging/epl/EplObdMacro.h40
-rw-r--r--drivers/staging/epl/EplObdkCal.c1
-rw-r--r--drivers/staging/epl/EplObdu.c69
-rw-r--r--drivers/staging/epl/EplObduCal.c75
-rw-r--r--drivers/staging/epl/EplObjDef.h208
-rw-r--r--drivers/staging/epl/EplPdo.h6
-rw-r--r--drivers/staging/epl/EplPdok.c73
-rw-r--r--drivers/staging/epl/EplPdou.c34
-rw-r--r--drivers/staging/epl/EplSdo.h24
-rw-r--r--drivers/staging/epl/EplSdoAsndu.c26
-rw-r--r--drivers/staging/epl/EplSdoAsySequ.c72
-rw-r--r--drivers/staging/epl/EplSdoComu.c153
-rw-r--r--drivers/staging/epl/EplSdoUdpu.c163
-rw-r--r--drivers/staging/epl/EplStatusu.c19
-rw-r--r--drivers/staging/epl/EplTarget.h109
-rw-r--r--drivers/staging/epl/EplTimer.h3
-rw-r--r--drivers/staging/epl/EplTimeruLinuxKernel.c26
-rw-r--r--drivers/staging/epl/EplTimeruNull.c312
-rw-r--r--drivers/staging/epl/EplTimeruWin32.c513
-rw-r--r--drivers/staging/epl/SharedBuff.c111
-rw-r--r--drivers/staging/epl/SharedBuff.h17
-rw-r--r--drivers/staging/epl/ShbIpc-LinuxKernel.c48
-rw-r--r--drivers/staging/epl/ShbIpc-Win32.c1202
-rw-r--r--drivers/staging/epl/ShbIpc.h26
-rw-r--r--drivers/staging/epl/TimerHighReskX86.c34
-rw-r--r--drivers/staging/epl/VirtualEthernetLinux.c5
-rw-r--r--drivers/staging/epl/amix86.c316
-rw-r--r--drivers/staging/epl/demo_main.c84
-rw-r--r--drivers/staging/epl/edrv.h22
-rw-r--r--drivers/staging/epl/global.h1253
-rw-r--r--drivers/staging/epl/kernel/EplDllk.h24
-rw-r--r--drivers/staging/epl/kernel/EplDllkCal.h14
-rw-r--r--drivers/staging/epl/kernel/EplErrorHandlerk.h20
-rw-r--r--drivers/staging/epl/kernel/EplEventk.h28
-rw-r--r--drivers/staging/epl/kernel/EplNmtk.h25
-rw-r--r--drivers/staging/epl/kernel/EplNmtkCal.h89
-rw-r--r--drivers/staging/epl/kernel/EplObdk.h122
-rw-r--r--drivers/staging/epl/kernel/EplObdkCal.h89
-rw-r--r--drivers/staging/epl/kernel/EplPdok.h12
-rw-r--r--drivers/staging/epl/kernel/EplPdokCal.h13
-rw-r--r--drivers/staging/epl/kernel/EplTimerHighResk.h43
-rw-r--r--drivers/staging/epl/kernel/EplTimerk.h36
-rw-r--r--drivers/staging/epl/kernel/VirtualEthernet.h16
-rw-r--r--drivers/staging/epl/proc_fs.c23
-rw-r--r--drivers/staging/epl/user/EplCfgMau.h80
-rw-r--r--drivers/staging/epl/user/EplDllu.h14
-rw-r--r--drivers/staging/epl/user/EplDlluCal.h15
-rw-r--r--drivers/staging/epl/user/EplEventu.h28
-rw-r--r--drivers/staging/epl/user/EplIdentu.h34
-rw-r--r--drivers/staging/epl/user/EplLedu.h32
-rw-r--r--drivers/staging/epl/user/EplNmtCnu.h32
-rw-r--r--drivers/staging/epl/user/EplNmtMnu.h42
-rw-r--r--drivers/staging/epl/user/EplNmtu.h38
-rw-r--r--drivers/staging/epl/user/EplNmtuCal.h17
-rw-r--r--drivers/staging/epl/user/EplObdu.h83
-rw-r--r--drivers/staging/epl/user/EplObduCal.h94
-rw-r--r--drivers/staging/epl/user/EplPdou.h22
-rw-r--r--drivers/staging/epl/user/EplSdoAsndu.h33
-rw-r--r--drivers/staging/epl/user/EplSdoAsySequ.h41
-rw-r--r--drivers/staging/epl/user/EplSdoComu.h48
-rw-r--r--drivers/staging/epl/user/EplSdoUdpu.h34
-rw-r--r--drivers/staging/epl/user/EplStatusu.h32
-rw-r--r--drivers/staging/epl/user/EplTimeru.h38
-rw-r--r--drivers/staging/et131x/et1310_rx.c3
-rw-r--r--drivers/staging/frontier/README53
-rw-r--r--drivers/staging/frontier/alphatrack.c383
-rw-r--r--drivers/staging/frontier/alphatrack.h80
-rw-r--r--drivers/staging/frontier/frontier_compat.h63
-rw-r--r--drivers/staging/frontier/surface_sysfs.h100
-rw-r--r--drivers/staging/frontier/tranzport.c685
-rw-r--r--drivers/staging/go7007/Kconfig4
-rw-r--r--drivers/staging/go7007/go7007-v4l2.c1
-rw-r--r--drivers/staging/go7007/s2250-board.c7
-rw-r--r--drivers/staging/go7007/snd-go7007.c7
-rw-r--r--drivers/staging/heci/Kconfig6
-rw-r--r--drivers/staging/heci/Makefile9
-rw-r--r--drivers/staging/heci/TODO6
-rw-r--r--drivers/staging/heci/heci.h176
-rw-r--r--drivers/staging/heci/heci_data_structures.h530
-rw-r--r--drivers/staging/heci/heci_init.c1077
-rw-r--r--drivers/staging/heci/heci_interface.c485
-rw-r--r--drivers/staging/heci/heci_interface.h170
-rw-r--r--drivers/staging/heci/heci_main.c1564
-rw-r--r--drivers/staging/heci/heci_version.h54
-rw-r--r--drivers/staging/heci/interrupt.c1553
-rw-r--r--drivers/staging/heci/io_heci.c847
-rw-r--r--drivers/staging/line6/Kconfig21
-rw-r--r--drivers/staging/line6/Makefile15
-rw-r--r--drivers/staging/line6/audio.c72
-rw-r--r--drivers/staging/line6/audio.h24
-rw-r--r--drivers/staging/line6/capture.c372
-rw-r--r--drivers/staging/line6/capture.h32
-rw-r--r--drivers/staging/line6/config.h48
-rw-r--r--drivers/staging/line6/control.c840
-rw-r--r--drivers/staging/line6/control.h187
-rw-r--r--drivers/staging/line6/driver.c1102
-rw-r--r--drivers/staging/line6/driver.h204
-rw-r--r--drivers/staging/line6/dumprequest.c151
-rw-r--r--drivers/staging/line6/dumprequest.h90
-rw-r--r--drivers/staging/line6/midi.c422
-rw-r--r--drivers/staging/line6/midi.h87
-rw-r--r--drivers/staging/line6/midibuf.c262
-rw-r--r--drivers/staging/line6/midibuf.h39
-rw-r--r--drivers/staging/line6/pcm.c301
-rw-r--r--drivers/staging/line6/pcm.h222
-rw-r--r--drivers/staging/line6/playback.c427
-rw-r--r--drivers/staging/line6/playback.h30
-rw-r--r--drivers/staging/line6/pod.c1151
-rw-r--r--drivers/staging/line6/pod.h204
-rw-r--r--drivers/staging/line6/revision.h4
-rw-r--r--drivers/staging/line6/toneport.c241
-rw-r--r--drivers/staging/line6/toneport.h45
-rw-r--r--drivers/staging/line6/usbdefs.h74
-rw-r--r--drivers/staging/line6/variax.c546
-rw-r--r--drivers/staging/line6/variax.h108
-rw-r--r--drivers/staging/me4000/me4000.c193
-rw-r--r--drivers/staging/meilhaus/me0600_device.c4
-rw-r--r--drivers/staging/meilhaus/me0600_dio.c18
-rw-r--r--drivers/staging/meilhaus/me0600_ext_irq.c8
-rw-r--r--drivers/staging/meilhaus/me0600_optoi.c14
-rw-r--r--drivers/staging/meilhaus/me0600_relay.c14
-rw-r--r--drivers/staging/meilhaus/me0600_ttli.c12
-rw-r--r--drivers/staging/meilhaus/me0900_device.c4
-rw-r--r--drivers/staging/meilhaus/me0900_di.c12
-rw-r--r--drivers/staging/meilhaus/me0900_do.c14
-rw-r--r--drivers/staging/meilhaus/me1000_device.c8
-rw-r--r--drivers/staging/meilhaus/me1000_dio.c4
-rw-r--r--drivers/staging/meilhaus/me1400_device.c4
-rw-r--r--drivers/staging/meilhaus/me1400_ext_irq.c7
-rw-r--r--drivers/staging/meilhaus/me1600_ao.c70
-rw-r--r--drivers/staging/meilhaus/me1600_ao.h4
-rw-r--r--drivers/staging/meilhaus/me1600_device.c8
-rw-r--r--drivers/staging/meilhaus/me4600_ai.c157
-rw-r--r--drivers/staging/meilhaus/me4600_ai.h4
-rw-r--r--drivers/staging/meilhaus/me4600_ao.c191
-rw-r--r--drivers/staging/meilhaus/me4600_ao.h4
-rw-r--r--drivers/staging/meilhaus/me4600_device.c4
-rw-r--r--drivers/staging/meilhaus/me4600_di.c14
-rw-r--r--drivers/staging/meilhaus/me4600_dio.c16
-rw-r--r--drivers/staging/meilhaus/me4600_do.c16
-rw-r--r--drivers/staging/meilhaus/me4600_ext_irq.c21
-rw-r--r--drivers/staging/meilhaus/me6000_ao.c146
-rw-r--r--drivers/staging/meilhaus/me6000_ao.h4
-rw-r--r--drivers/staging/meilhaus/me6000_device.c4
-rw-r--r--drivers/staging/meilhaus/me6000_dio.c16
-rw-r--r--drivers/staging/meilhaus/me8100_device.c4
-rw-r--r--drivers/staging/meilhaus/me8100_di.c24
-rw-r--r--drivers/staging/meilhaus/me8100_do.c16
-rw-r--r--drivers/staging/meilhaus/me8200_device.c4
-rw-r--r--drivers/staging/meilhaus/me8200_di.c58
-rw-r--r--drivers/staging/meilhaus/me8200_dio.c16
-rw-r--r--drivers/staging/meilhaus/me8200_do.c26
-rw-r--r--drivers/staging/meilhaus/me8254.c14
-rw-r--r--drivers/staging/meilhaus/me8255.c4
-rw-r--r--drivers/staging/meilhaus/mecirc_buf.h16
-rw-r--r--drivers/staging/meilhaus/medevice.c14
-rw-r--r--drivers/staging/meilhaus/medlist.c6
-rw-r--r--drivers/staging/meilhaus/medlock.c4
-rw-r--r--drivers/staging/meilhaus/medummy.c84
-rw-r--r--drivers/staging/meilhaus/memain.c34
-rw-r--r--drivers/staging/meilhaus/meslist.c6
-rw-r--r--drivers/staging/meilhaus/meslock.c2
-rw-r--r--drivers/staging/meilhaus/mesubdevice.c12
-rw-r--r--drivers/staging/meilhaus/metempl_device.c4
-rw-r--r--drivers/staging/meilhaus/metempl_sub.c10
-rw-r--r--drivers/staging/mimio/Kconfig2
-rw-r--r--drivers/staging/otus/80211core/amsdu.c145
-rw-r--r--drivers/staging/otus/80211core/cmmsta.c5
-rw-r--r--drivers/staging/otus/80211core/coid.c8
-rw-r--r--drivers/staging/otus/80211core/cwm.c6
-rw-r--r--drivers/staging/otus/TODO9
-rw-r--r--drivers/staging/otus/hal/hpani.c46
-rw-r--r--drivers/staging/otus/hal/hpmain.c101
-rw-r--r--drivers/staging/otus/hal/hpreg.c9
-rw-r--r--drivers/staging/otus/hal/hprw.c30
-rw-r--r--drivers/staging/otus/hal/hpusb.c11
-rw-r--r--drivers/staging/otus/ioctl.c4789
-rw-r--r--drivers/staging/otus/usbdrv.c12
-rw-r--r--drivers/staging/otus/wwrap.c6
-rw-r--r--drivers/staging/otus/zdcompat.h7
-rw-r--r--drivers/staging/p9auth/Kconfig9
-rw-r--r--drivers/staging/p9auth/Makefile1
-rw-r--r--drivers/staging/p9auth/p9auth.c383
-rw-r--r--drivers/staging/panel/Kconfig2
-rw-r--r--drivers/staging/phison/Kconfig5
-rw-r--r--drivers/staging/phison/Makefile1
-rw-r--r--drivers/staging/phison/phison.c106
-rw-r--r--drivers/staging/pohmelfs/Kconfig28
-rw-r--r--drivers/staging/pohmelfs/Makefile3
-rw-r--r--drivers/staging/pohmelfs/config.c478
-rw-r--r--drivers/staging/pohmelfs/crypto.c880
-rw-r--r--drivers/staging/pohmelfs/dir.c1093
-rw-r--r--drivers/staging/pohmelfs/inode.c1976
-rw-r--r--drivers/staging/pohmelfs/lock.c182
-rw-r--r--drivers/staging/pohmelfs/mcache.c171
-rw-r--r--drivers/staging/pohmelfs/net.c1247
-rw-r--r--drivers/staging/pohmelfs/netfs.h932
-rw-r--r--drivers/staging/pohmelfs/path_entry.c114
-rw-r--r--drivers/staging/pohmelfs/trans.c715
-rw-r--r--drivers/staging/rspiusb/rspiusb.c5
-rw-r--r--drivers/staging/rt2860/2860_main_dev.c50
-rw-r--r--drivers/staging/rt2860/Makefile1
-rw-r--r--drivers/staging/rt2860/TODO4
-rw-r--r--drivers/staging/rt2860/common/cmm_data.c27
-rw-r--r--drivers/staging/rt2860/common/cmm_data_2860.c144
-rw-r--r--drivers/staging/rt2860/common/cmm_info.c6
-rw-r--r--drivers/staging/rt2860/common/cmm_sync.c2
-rw-r--r--drivers/staging/rt2860/common/cmm_wpa.c40
-rw-r--r--drivers/staging/rt2860/common/mlme.c289
-rw-r--r--drivers/staging/rt2860/common/rtmp_init.c157
-rw-r--r--drivers/staging/rt2860/common/spectrum.c2
-rw-r--r--drivers/staging/rt2860/config.mk4
-rw-r--r--drivers/staging/rt2860/oid.h2
-rw-r--r--drivers/staging/rt2860/rt2860.h22
-rw-r--r--drivers/staging/rt2860/rt28xx.h4
-rw-r--r--drivers/staging/rt2860/rt_ate.c18
-rw-r--r--drivers/staging/rt2860/rt_ate.h6
-rw-r--r--drivers/staging/rt2860/rt_config.h2
-rw-r--r--drivers/staging/rt2860/rt_linux.c29
-rw-r--r--drivers/staging/rt2860/rt_linux.h49
-rw-r--r--drivers/staging/rt2860/rt_main_dev.c149
-rw-r--r--drivers/staging/rt2860/rt_profile.c2
-rw-r--r--drivers/staging/rt2860/rtmp.h61
-rw-r--r--drivers/staging/rt2860/rtmp_def.h29
-rw-r--r--drivers/staging/rt2860/sta/assoc.c23
-rw-r--r--drivers/staging/rt2860/sta/connect.c45
-rw-r--r--drivers/staging/rt2860/sta/dls.c4
-rw-r--r--drivers/staging/rt2860/sta/rtmp_data.c29
-rw-r--r--drivers/staging/rt2860/sta/sync.c16
-rw-r--r--drivers/staging/rt2860/sta/wpa.c10
-rw-r--r--drivers/staging/rt2860/sta_ioctl.c96
-rw-r--r--drivers/staging/rt2860/wpa.h1
-rw-r--r--drivers/staging/rt2870/2870_main_dev.c67
-rw-r--r--drivers/staging/rt2870/TODO9
-rw-r--r--drivers/staging/rt2870/common/2870_rtmp_init.c35
-rw-r--r--drivers/staging/rt2870/common/cmm_data.c3
-rw-r--r--drivers/staging/rt2870/common/rtmp_init.c2
-rw-r--r--drivers/staging/rt2870/common/rtusb_io.c3
-rw-r--r--drivers/staging/rt2870/common/spectrum.c2
-rw-r--r--drivers/staging/rt2870/rt2870.h7
-rw-r--r--drivers/staging/rt2870/rt_linux.c2
-rw-r--r--drivers/staging/rt2870/rt_linux.h12
-rw-r--r--drivers/staging/rt2870/sta_ioctl.c2
-rw-r--r--drivers/staging/rt3070/2870_main_dev.c1627
-rw-r--r--drivers/staging/rt3070/Kconfig6
-rw-r--r--drivers/staging/rt3070/Makefile47
-rw-r--r--drivers/staging/rt3070/action.h68
-rw-r--r--drivers/staging/rt3070/aironet.h210
-rw-r--r--drivers/staging/rt3070/ap.h557
-rw-r--r--drivers/staging/rt3070/chlist.h1253
-rw-r--r--drivers/staging/rt3070/common/2870_rtmp_init.c1762
-rw-r--r--drivers/staging/rt3070/common/action.c1038
-rw-r--r--drivers/staging/rt3070/common/ba_action.c1810
-rw-r--r--drivers/staging/rt3070/common/cmm_data.c2827
-rw-r--r--drivers/staging/rt3070/common/cmm_data_2870.c980
-rw-r--r--drivers/staging/rt3070/common/cmm_info.c3395
-rw-r--r--drivers/staging/rt3070/common/cmm_sanity.c1669
-rw-r--r--drivers/staging/rt3070/common/cmm_sync.c711
-rw-r--r--drivers/staging/rt3070/common/cmm_wpa.c1606
-rw-r--r--drivers/staging/rt3070/common/dfs.c441
-rw-r--r--drivers/staging/rt3070/common/eeprom.c1498
-rw-r--r--drivers/staging/rt3070/common/md5.c1427
-rw-r--r--drivers/staging/rt3070/common/mlme.c9136
-rw-r--r--drivers/staging/rt3070/common/netif_block.c136
-rw-r--r--drivers/staging/rt3070/common/rtmp_init.c4197
-rw-r--r--drivers/staging/rt3070/common/rtmp_tkip.c1613
-rw-r--r--drivers/staging/rt3070/common/rtmp_wep.c508
-rw-r--r--drivers/staging/rt3070/common/rtusb_bulk.c1382
-rw-r--r--drivers/staging/rt3070/common/rtusb_data.c218
-rw-r--r--drivers/staging/rt3070/common/rtusb_io.c1908
-rw-r--r--drivers/staging/rt3070/common/spectrum.c1876
-rw-r--r--drivers/staging/rt3070/dfs.h100
-rw-r--r--drivers/staging/rt3070/firmware.h558
-rw-r--r--drivers/staging/rt3070/leap.h215
-rw-r--r--drivers/staging/rt3070/link_list.h134
-rw-r--r--drivers/staging/rt3070/md4.h42
-rw-r--r--drivers/staging/rt3070/md5.h107
-rw-r--r--drivers/staging/rt3070/mlme.h1468
-rw-r--r--drivers/staging/rt3070/netif_block.h58
-rw-r--r--drivers/staging/rt3070/oid.h1142
-rw-r--r--drivers/staging/rt3070/rt2870.h756
-rw-r--r--drivers/staging/rt3070/rt28xx.h2725
-rw-r--r--drivers/staging/rt3070/rt_ate.c6506
-rw-r--r--drivers/staging/rt3070/rt_ate.h294
-rw-r--r--drivers/staging/rt3070/rt_config.h121
-rw-r--r--drivers/staging/rt3070/rt_linux.c1063
-rw-r--r--drivers/staging/rt3070/rt_linux.h887
-rw-r--r--drivers/staging/rt3070/rt_main_dev.c1800
-rw-r--r--drivers/staging/rt3070/rt_profile.c2041
-rw-r--r--drivers/staging/rt3070/rtmp.h7728
-rw-r--r--drivers/staging/rt3070/rtmp_ckipmic.h113
-rw-r--r--drivers/staging/rt3070/rtmp_def.h1559
-rw-r--r--drivers/staging/rt3070/rtmp_type.h95
-rw-r--r--drivers/staging/rt3070/spectrum.h322
-rw-r--r--drivers/staging/rt3070/spectrum_def.h95
-rw-r--r--drivers/staging/rt3070/sta/aironet.c1312
-rw-r--r--drivers/staging/rt3070/sta/assoc.c2060
-rw-r--r--drivers/staging/rt3070/sta/auth.c475
-rw-r--r--drivers/staging/rt3070/sta/auth_rsp.c167
-rw-r--r--drivers/staging/rt3070/sta/connect.c2857
-rw-r--r--drivers/staging/rt3070/sta/dls.c2170
-rw-r--r--drivers/staging/rt3070/sta/rtmp_data.c2637
-rw-r--r--drivers/staging/rt3070/sta/sanity.c420
-rw-r--r--drivers/staging/rt3070/sta/sync.c1755
-rw-r--r--drivers/staging/rt3070/sta/wpa.c2099
-rw-r--r--drivers/staging/rt3070/sta_ioctl.c7203
-rw-r--r--drivers/staging/rt3070/wpa.h356
-rw-r--r--drivers/staging/rtl8187se/dot11d.h202
-rw-r--r--drivers/staging/rtl8187se/ieee80211/dot11d.c492
-rw-r--r--drivers/staging/rtl8187se/ieee80211/dot11d.h204
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c8
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c4
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c10
-rw-r--r--drivers/staging/rtl8187se/r8180_dm.c3450
-rw-r--r--drivers/staging/rtl8187se/r8180_dm.h82
-rw-r--r--drivers/staging/rtl8187se/r8180_wx.c12
-rw-r--r--drivers/staging/serqt_usb/Kconfig9
-rw-r--r--drivers/staging/serqt_usb/Makefile1
-rw-r--r--drivers/staging/serqt_usb/TODO8
-rw-r--r--drivers/staging/serqt_usb/serqt_usb.c2779
-rw-r--r--drivers/staging/slicoss/gbdownload.h8215
-rw-r--r--drivers/staging/slicoss/gbrcvucode.h238
-rw-r--r--drivers/staging/slicoss/oasisdbgdownload.h6850
-rw-r--r--drivers/staging/slicoss/oasisdownload.h6848
-rw-r--r--drivers/staging/slicoss/oasisrcvucode.h205
-rw-r--r--drivers/staging/slicoss/slic.h86
-rw-r--r--drivers/staging/slicoss/slic_os.h84
-rw-r--r--drivers/staging/slicoss/slicbuild.h96
-rw-r--r--drivers/staging/slicoss/slicdbg.h100
-rw-r--r--drivers/staging/slicoss/slicdump.h278
-rw-r--r--drivers/staging/slicoss/slichw.h1038
-rw-r--r--drivers/staging/slicoss/slicinc.h185
-rw-r--r--drivers/staging/slicoss/slicoss.c2913
-rw-r--r--drivers/staging/stlc45xx/Kconfig8
-rw-r--r--drivers/staging/stlc45xx/Makefile1
-rw-r--r--drivers/staging/stlc45xx/stlc45xx.c2606
-rw-r--r--drivers/staging/stlc45xx/stlc45xx.h283
-rw-r--r--drivers/staging/stlc45xx/stlc45xx_lmac.h434
-rw-r--r--drivers/staging/sxg/Kconfig2
-rw-r--r--drivers/staging/sxg/Makefile4
-rw-r--r--drivers/staging/sxg/saharadbgdownload.h4854
-rw-r--r--drivers/staging/sxg/sxg.c2885
-rw-r--r--drivers/staging/sxg/sxg.h919
-rw-r--r--drivers/staging/sxg/sxg_ethtool.c328
-rw-r--r--drivers/staging/sxg/sxg_os.h100
-rw-r--r--drivers/staging/sxg/sxgdbg.h129
-rw-r--r--drivers/staging/sxg/sxghif.h1110
-rw-r--r--drivers/staging/sxg/sxghw.h1564
-rw-r--r--drivers/staging/sxg/sxgphycode-1.2.h130
-rw-r--r--drivers/staging/sxg/sxgphycode.h349
-rw-r--r--drivers/staging/uc2322/Kconfig10
-rw-r--r--drivers/staging/uc2322/Makefile1
-rw-r--r--drivers/staging/uc2322/TODO7
-rw-r--r--drivers/staging/uc2322/aten2011.c2452
-rw-r--r--drivers/staging/usbip/stub_rx.c4
-rw-r--r--drivers/staging/usbip/vhci_sysfs.c3
-rw-r--r--drivers/staging/winbond/bss_f.h63
-rw-r--r--drivers/staging/winbond/bssdscpt.h164
-rw-r--r--drivers/staging/winbond/common.h27
-rw-r--r--drivers/staging/winbond/core.h7
-rw-r--r--drivers/staging/winbond/ds_tkip.h37
-rw-r--r--drivers/staging/winbond/gl_80211.h126
-rw-r--r--drivers/staging/winbond/ioctls.h678
-rw-r--r--drivers/staging/winbond/mds.c26
-rw-r--r--drivers/staging/winbond/mds_s.h24
-rw-r--r--drivers/staging/winbond/mlme_mib.h84
-rw-r--r--drivers/staging/winbond/mlmetxrx.c2
-rw-r--r--drivers/staging/winbond/mto.c24
-rw-r--r--drivers/staging/winbond/mto.h12
-rw-r--r--drivers/staging/winbond/mto_f.h13
-rw-r--r--drivers/staging/winbond/os_common.h2
-rw-r--r--drivers/staging/winbond/phy_calibration.c28
-rw-r--r--drivers/staging/winbond/phy_calibration.h2
-rw-r--r--drivers/staging/winbond/reg.c81
-rw-r--r--drivers/staging/winbond/sme_api.h3
-rw-r--r--drivers/staging/winbond/sme_s.h236
-rw-r--r--drivers/staging/winbond/wb35_ver.h30
-rw-r--r--drivers/staging/winbond/wb35reg.c41
-rw-r--r--drivers/staging/winbond/wb35reg_f.h70
-rw-r--r--drivers/staging/winbond/wb35rx.c43
-rw-r--r--drivers/staging/winbond/wb35rx_f.h6
-rw-r--r--drivers/staging/winbond/wb35rx_s.h8
-rw-r--r--drivers/staging/winbond/wb35tx.c54
-rw-r--r--drivers/staging/winbond/wb35tx_f.h8
-rw-r--r--drivers/staging/winbond/wb35tx_s.h6
-rw-r--r--drivers/staging/winbond/wbhal.c50
-rw-r--r--drivers/staging/winbond/wbhal_f.h94
-rw-r--r--drivers/staging/winbond/wbhal_s.h87
-rw-r--r--drivers/staging/winbond/wbusb.c20
-rw-r--r--drivers/staging/winbond/wbusb_s.h16
-rw-r--r--drivers/staging/wlan-ng/README4
-rw-r--r--drivers/staging/wlan-ng/hfa384x.h2638
-rw-r--r--drivers/staging/wlan-ng/hfa384x_usb.c2295
-rw-r--r--drivers/staging/wlan-ng/p80211conv.c377
-rw-r--r--drivers/staging/wlan-ng/p80211conv.h131
-rw-r--r--drivers/staging/wlan-ng/p80211hdr.h146
-rw-r--r--drivers/staging/wlan-ng/p80211ioctl.h46
-rw-r--r--drivers/staging/wlan-ng/p80211meta.h110
-rw-r--r--drivers/staging/wlan-ng/p80211metadef.h544
-rw-r--r--drivers/staging/wlan-ng/p80211metamib.h105
-rw-r--r--drivers/staging/wlan-ng/p80211metamsg.h105
-rw-r--r--drivers/staging/wlan-ng/p80211metastruct.h424
-rw-r--r--drivers/staging/wlan-ng/p80211mgmt.h441
-rw-r--r--drivers/staging/wlan-ng/p80211msg.h48
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.c411
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.h218
-rw-r--r--drivers/staging/wlan-ng/p80211req.c235
-rw-r--r--drivers/staging/wlan-ng/p80211req.h17
-rw-r--r--drivers/staging/wlan-ng/p80211types.h505
-rw-r--r--drivers/staging/wlan-ng/p80211wep.c24
-rw-r--r--drivers/staging/wlan-ng/p80211wext.c1214
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.c899
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.h69
-rw-r--r--drivers/staging/wlan-ng/prism2mib.c905
-rw-r--r--drivers/staging/wlan-ng/prism2sta.c1561
-rw-r--r--drivers/staging/wlan-ng/prism2usb.c158
-rw-r--r--drivers/staging/wlan-ng/wlan_compat.h193
-rw-r--r--drivers/tc/tc.c8
-rw-r--r--drivers/thermal/thermal_sys.c356
-rw-r--r--drivers/uio/Kconfig18
-rw-r--r--drivers/uio/Makefile1
-rw-r--r--drivers/uio/uio.c25
-rw-r--r--drivers/uio/uio_aec.c175
-rw-r--r--drivers/usb/Kconfig1
-rw-r--r--drivers/usb/Makefile1
-rw-r--r--drivers/usb/atm/ueagle-atm.c2
-rw-r--r--drivers/usb/class/cdc-acm.c5
-rw-r--r--drivers/usb/class/usblp.c11
-rw-r--r--drivers/usb/core/devices.c2
-rw-r--r--drivers/usb/core/devio.c21
-rw-r--r--drivers/usb/core/endpoint.c9
-rw-r--r--drivers/usb/core/hcd.c33
-rw-r--r--drivers/usb/core/hub.c34
-rw-r--r--drivers/usb/core/message.c11
-rw-r--r--drivers/usb/core/quirks.c4
-rw-r--r--drivers/usb/core/sysfs.c4
-rw-r--r--drivers/usb/core/urb.c4
-rw-r--r--drivers/usb/gadget/Kconfig3
-rw-r--r--drivers/usb/gadget/amd5536udc.c2
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c34
-rw-r--r--drivers/usb/gadget/cdc2.c8
-rw-r--r--drivers/usb/gadget/ci13xxx_udc.c3
-rw-r--r--drivers/usb/gadget/composite.c13
-rw-r--r--drivers/usb/gadget/dummy_hcd.c4
-rw-r--r--drivers/usb/gadget/epautoconf.c2
-rw-r--r--drivers/usb/gadget/ether.c8
-rw-r--r--drivers/usb/gadget/f_acm.c10
-rw-r--r--drivers/usb/gadget/f_ecm.c16
-rw-r--r--drivers/usb/gadget/f_loopback.c10
-rw-r--r--drivers/usb/gadget/f_obex.c8
-rw-r--r--drivers/usb/gadget/f_phonet.c8
-rw-r--r--drivers/usb/gadget/f_rndis.c12
-rw-r--r--drivers/usb/gadget/f_serial.c4
-rw-r--r--drivers/usb/gadget/f_sourcesink.c56
-rw-r--r--drivers/usb/gadget/f_subset.c14
-rw-r--r--drivers/usb/gadget/file_storage.c29
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.c8
-rw-r--r--drivers/usb/gadget/g_zero.h4
-rw-r--r--drivers/usb/gadget/gmidi.c23
-rw-r--r--drivers/usb/gadget/goku_udc.c8
-rw-r--r--drivers/usb/gadget/imx_udc.c248
-rw-r--r--drivers/usb/gadget/imx_udc.h49
-rw-r--r--drivers/usb/gadget/inode.c4
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c16
-rw-r--r--drivers/usb/gadget/net2280.c16
-rw-r--r--drivers/usb/gadget/printer.c18
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c272
-rw-r--r--drivers/usb/gadget/pxa27x_udc.h10
-rw-r--r--drivers/usb/gadget/rndis.c99
-rw-r--r--drivers/usb/gadget/serial.c12
-rw-r--r--drivers/usb/gadget/u_serial.c2
-rw-r--r--drivers/usb/gadget/zero.c78
-rw-r--r--drivers/usb/host/Kconfig7
-rw-r--r--drivers/usb/host/ehci-hcd.c36
-rw-r--r--drivers/usb/host/ehci-q.c32
-rw-r--r--drivers/usb/host/ehci-sched.c2
-rw-r--r--drivers/usb/host/ehci.h39
-rw-r--r--drivers/usb/host/fhci-dbg.c2
-rw-r--r--drivers/usb/host/fhci-hcd.c4
-rw-r--r--drivers/usb/host/hwa-hc.c3
-rw-r--r--drivers/usb/host/isp116x-hcd.c2
-rw-r--r--drivers/usb/host/isp116x.h8
-rw-r--r--drivers/usb/host/isp1760-hcd.c25
-rw-r--r--drivers/usb/host/isp1760-hcd.h7
-rw-r--r--drivers/usb/host/isp1760-if.c95
-rw-r--r--drivers/usb/host/ohci-ep93xx.c2
-rw-r--r--drivers/usb/host/ohci-hcd.c5
-rw-r--r--drivers/usb/host/ohci-s3c2410.c6
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c24
-rw-r--r--drivers/usb/host/oxu210hp.h8
-rw-r--r--drivers/usb/host/pci-quirks.c2
-rw-r--r--drivers/usb/host/r8a66597-hcd.c118
-rw-r--r--drivers/usb/host/r8a66597.h2
-rw-r--r--drivers/usb/host/sl811-hcd.c4
-rw-r--r--drivers/usb/host/uhci-debug.c4
-rw-r--r--drivers/usb/host/uhci-hcd.h10
-rw-r--r--drivers/usb/host/uhci-q.c21
-rw-r--r--drivers/usb/image/mdc800.c8
-rw-r--r--drivers/usb/misc/Kconfig39
-rw-r--r--drivers/usb/misc/Makefile4
-rw-r--r--drivers/usb/misc/ftdi-elan.c6
-rw-r--r--drivers/usb/misc/phidget.c43
-rw-r--r--drivers/usb/misc/phidgetkit.c740
-rw-r--r--drivers/usb/misc/phidgetmotorcontrol.c465
-rw-r--r--drivers/usb/misc/phidgetservo.c375
-rw-r--r--drivers/usb/mon/mon_bin.c142
-rw-r--r--drivers/usb/musb/Kconfig6
-rw-r--r--drivers/usb/musb/davinci.c63
-rw-r--r--drivers/usb/musb/davinci.h23
-rw-r--r--drivers/usb/musb/musb_core.c2
-rw-r--r--drivers/usb/musb/musb_core.h5
-rw-r--r--drivers/usb/musb/musb_host.c140
-rw-r--r--drivers/usb/musb/musb_virthub.c2
-rw-r--r--drivers/usb/otg/Kconfig10
-rw-r--r--drivers/usb/otg/Makefile1
-rw-r--r--drivers/usb/otg/gpio_vbus.c42
-rw-r--r--drivers/usb/otg/nop-usb-xceiv.c180
-rw-r--r--drivers/usb/otg/twl4030-usb.c73
-rw-r--r--drivers/usb/serial/ChangeLog.history2
-rw-r--r--drivers/usb/serial/Kconfig32
-rw-r--r--drivers/usb/serial/Makefile4
-rw-r--r--drivers/usb/serial/ch341.c396
-rw-r--r--drivers/usb/serial/cp210x.c (renamed from drivers/usb/serial/cp2101.c)161
-rw-r--r--drivers/usb/serial/ftdi_sio.c29
-rw-r--r--drivers/usb/serial/generic.c9
-rw-r--r--drivers/usb/serial/ipaq.c43
-rw-r--r--drivers/usb/serial/keyspan.c2
-rw-r--r--drivers/usb/serial/opticon.c215
-rw-r--r--drivers/usb/serial/option.c86
-rw-r--r--drivers/usb/serial/pl2303.c1
-rw-r--r--drivers/usb/serial/pl2303.h4
-rw-r--r--drivers/usb/serial/qcserial.c147
-rw-r--r--drivers/usb/serial/symbolserial.c332
-rw-r--r--drivers/usb/serial/usb-serial.c78
-rw-r--r--drivers/usb/storage/Kconfig48
-rw-r--r--drivers/usb/storage/Makefile41
-rw-r--r--drivers/usb/storage/alauda.c192
-rw-r--r--drivers/usb/storage/alauda.h100
-rw-r--r--drivers/usb/storage/cypress_atacb.c106
-rw-r--r--drivers/usb/storage/datafab.c104
-rw-r--r--drivers/usb/storage/datafab.h40
-rw-r--r--drivers/usb/storage/freecom.c99
-rw-r--r--drivers/usb/storage/isd200.c336
-rw-r--r--drivers/usb/storage/jumpshot.c103
-rw-r--r--drivers/usb/storage/jumpshot.h39
-rw-r--r--drivers/usb/storage/karma.c100
-rw-r--r--drivers/usb/storage/karma.h7
-rw-r--r--drivers/usb/storage/libusual.c33
-rw-r--r--drivers/usb/storage/onetouch.c94
-rw-r--r--drivers/usb/storage/onetouch.h9
-rw-r--r--drivers/usb/storage/protocol.c3
-rw-r--r--drivers/usb/storage/scsiglue.c8
-rw-r--r--drivers/usb/storage/sddr09.c147
-rw-r--r--drivers/usb/storage/sddr09.h38
-rw-r--r--drivers/usb/storage/sddr55.c99
-rw-r--r--drivers/usb/storage/shuttle_usbat.c202
-rw-r--r--drivers/usb/storage/shuttle_usbat.h123
-rw-r--r--drivers/usb/storage/transport.c12
-rw-r--r--drivers/usb/storage/unusual_alauda.h (renamed from drivers/usb/storage/freecom.h)29
-rw-r--r--drivers/usb/storage/unusual_cypress.h34
-rw-r--r--drivers/usb/storage/unusual_datafab.h98
-rw-r--r--drivers/usb/storage/unusual_devs.h307
-rw-r--r--drivers/usb/storage/unusual_freecom.h (renamed from drivers/usb/storage/cypress_atacb.h)19
-rw-r--r--drivers/usb/storage/unusual_isd200.h57
-rw-r--r--drivers/usb/storage/unusual_jumpshot.h (renamed from drivers/usb/storage/sddr55.h)23
-rw-r--r--drivers/usb/storage/unusual_karma.h (renamed from drivers/usb/storage/isd200.h)21
-rw-r--r--drivers/usb/storage/unusual_onetouch.h36
-rw-r--r--drivers/usb/storage/unusual_sddr09.h56
-rw-r--r--drivers/usb/storage/unusual_sddr55.h44
-rw-r--r--drivers/usb/storage/unusual_usbat.h43
-rw-r--r--drivers/usb/storage/usb.c344
-rw-r--r--drivers/usb/storage/usb.h21
-rw-r--r--drivers/usb/storage/usual-tables.c116
-rw-r--r--drivers/usb/usb-skeleton.c6
-rw-r--r--drivers/usb/wusbcore/cbaf.c3
-rw-r--r--drivers/usb/wusbcore/devconnect.c4
-rw-r--r--drivers/usb/wusbcore/security.c4
-rw-r--r--drivers/uwb/Kconfig4
-rw-r--r--drivers/video/68328fb.c5
-rw-r--r--drivers/video/Kconfig97
-rw-r--r--drivers/video/Makefile5
-rw-r--r--drivers/video/acornfb.c2
-rw-r--r--drivers/video/amba-clcd.c8
-rw-r--r--drivers/video/amifb.c7
-rw-r--r--drivers/video/arkfb.c4
-rw-r--r--drivers/video/asiliantfb.c26
-rw-r--r--drivers/video/aty/mach64_accel.c3
-rw-r--r--drivers/video/aty/mach64_cursor.c15
-rw-r--r--drivers/video/aty/radeon_pm.c29
-rw-r--r--drivers/video/au1100fb.c31
-rw-r--r--drivers/video/au1200fb.c25
-rw-r--r--drivers/video/backlight/Kconfig18
-rw-r--r--drivers/video/backlight/Makefile2
-rw-r--r--drivers/video/backlight/backlight.c3
-rw-r--r--drivers/video/backlight/jornada720_bl.c161
-rw-r--r--drivers/video/backlight/jornada720_lcd.c153
-rw-r--r--drivers/video/backlight/lcd.c3
-rw-r--r--drivers/video/backlight/mbp_nvidia_bl.c191
-rw-r--r--drivers/video/backlight/pwm_bl.c4
-rw-r--r--drivers/video/broadsheetfb.c568
-rw-r--r--drivers/video/cirrusfb.c1529
-rw-r--r--drivers/video/console/fbcon.c73
-rw-r--r--drivers/video/cyber2000fb.c4
-rw-r--r--drivers/video/cyblafb.c1683
-rw-r--r--drivers/video/efifb.c5
-rw-r--r--drivers/video/fb_defio.c3
-rw-r--r--drivers/video/fbmem.c22
-rw-r--r--drivers/video/imxfb.c108
-rw-r--r--drivers/video/mx3fb.c2300
-rw-r--r--drivers/video/nvidia/nv_setup.c1
-rw-r--r--drivers/video/nvidia/nv_type.h2
-rw-r--r--drivers/video/nvidia/nvidia.c7
-rw-r--r--drivers/video/omap/hwa742.c4
-rw-r--r--drivers/video/omap/omapfb_main.c8
-rw-r--r--drivers/video/pmag-ba-fb.c17
-rw-r--r--drivers/video/pmagb-b-fb.c17
-rw-r--r--drivers/video/ps3fb.c2
-rw-r--r--drivers/video/pvr2fb.c16
-rw-r--r--drivers/video/pxafb.c15
-rw-r--r--drivers/video/s1d13xxxfb.c48
-rw-r--r--drivers/video/s3c-fb.c1036
-rw-r--r--drivers/video/s3c2410fb.c4
-rw-r--r--drivers/video/sa1100fb.c23
-rw-r--r--drivers/video/sgivwfb.c2
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c68
-rw-r--r--drivers/video/skeletonfb.c9
-rw-r--r--drivers/video/sm501fb.c5
-rw-r--r--drivers/video/sstfb.c10
-rw-r--r--drivers/video/stifb.c18
-rw-r--r--drivers/video/sunxvr500.c6
-rw-r--r--drivers/video/tdfxfb.c1
-rw-r--r--drivers/video/tgafb.c4
-rw-r--r--drivers/video/tmiofb.c2
-rw-r--r--drivers/video/tridentfb.c19
-rw-r--r--drivers/video/uvesafb.c22
-rw-r--r--drivers/video/valkyriefb.c15
-rw-r--r--drivers/video/vesafb.c2
-rw-r--r--drivers/video/vfb.c1
-rw-r--r--drivers/video/via/accel.c8
-rw-r--r--drivers/video/via/viafbdev.c5
-rw-r--r--drivers/virtio/virtio_ring.c22
-rw-r--r--drivers/w1/masters/ds1wm.c58
-rw-r--r--drivers/w1/masters/mxc_w1.c2
-rw-r--r--drivers/w1/masters/omap_hdq.c4
-rw-r--r--drivers/w1/w1_io.c16
-rw-r--r--drivers/watchdog/Kconfig17
-rw-r--r--drivers/watchdog/acquirewdt.c8
-rw-r--r--drivers/watchdog/advantechwdt.c7
-rw-r--r--drivers/watchdog/alim1535_wdt.c20
-rw-r--r--drivers/watchdog/alim7101_wdt.c6
-rw-r--r--drivers/watchdog/at91sam9_wdt.c2
-rw-r--r--drivers/watchdog/cpwd.c101
-rw-r--r--drivers/watchdog/davinci_wdt.c45
-rw-r--r--drivers/watchdog/eurotechwdt.c22
-rw-r--r--drivers/watchdog/geodewdt.c11
-rw-r--r--drivers/watchdog/hpwdt.c24
-rw-r--r--drivers/watchdog/i6300esb.c101
-rw-r--r--drivers/watchdog/iTCO_vendor_support.c6
-rw-r--r--drivers/watchdog/iTCO_wdt.c15
-rw-r--r--drivers/watchdog/it87_wdt.c12
-rw-r--r--drivers/watchdog/mpc5200_wdt.c4
-rw-r--r--drivers/watchdog/mpcore_wdt.c2
-rw-r--r--drivers/watchdog/mtx-1_wdt.c2
-rw-r--r--drivers/watchdog/omap_wdt.c94
-rw-r--r--drivers/watchdog/orion5x_wdt.c76
-rw-r--r--drivers/watchdog/pc87413_wdt.c6
-rw-r--r--drivers/watchdog/pcwd.c44
-rw-r--r--drivers/watchdog/pcwd_pci.c108
-rw-r--r--drivers/watchdog/pcwd_usb.c175
-rw-r--r--drivers/watchdog/pnx4008_wdt.c18
-rw-r--r--drivers/watchdog/rc32434_wdt.c153
-rw-r--r--drivers/watchdog/riowd.c23
-rw-r--r--drivers/watchdog/rm9k_wdt.c27
-rw-r--r--drivers/watchdog/sa1100_wdt.c8
-rw-r--r--drivers/watchdog/sbc60xxwdt.c2
-rw-r--r--drivers/watchdog/sbc8360.c12
-rw-r--r--drivers/watchdog/sbc_epx_c3.c3
-rw-r--r--drivers/watchdog/sc1200wdt.c7
-rw-r--r--drivers/watchdog/sc520_wdt.c9
-rw-r--r--drivers/watchdog/smsc37b787_wdt.c30
-rw-r--r--drivers/watchdog/softdog.c5
-rw-r--r--drivers/watchdog/w83697hf_wdt.c3
-rw-r--r--drivers/watchdog/w83697ug_wdt.c23
-rw-r--r--drivers/watchdog/w83977f_wdt.c2
-rw-r--r--drivers/watchdog/wd501p.h24
-rw-r--r--drivers/watchdog/wdt.c152
-rw-r--r--drivers/watchdog/wdt977.c2
-rw-r--r--drivers/xen/Kconfig2
-rw-r--r--drivers/xen/cpu_hotplug.c4
-rw-r--r--drivers/xen/manage.c16
-rw-r--r--drivers/zorro/zorro.c4
-rw-r--r--firmware/3com/3C359.bin.ihex1573
-rw-r--r--firmware/3com/typhoon.bin.ihex2819
-rw-r--r--firmware/Makefile18
-rw-r--r--firmware/WHENCE199
-rw-r--r--firmware/advansys/3550.bin.ihex317
-rw-r--r--firmware/advansys/38C0800.bin.ihex336
-rw-r--r--firmware/advansys/38C1600.bin.ihex398
-rw-r--r--firmware/advansys/mcode.bin.ihex147
-rw-r--r--firmware/cxgb3/t3fw-7.0.0.bin.ihex1881
-rw-r--r--firmware/cxgb3/t3fw-7.1.0.bin.ihex1885
-rw-r--r--firmware/ositech/Xilinx7OD.bin.ihex177
-rw-r--r--firmware/qlogic/1040.bin.ihex2111
-rw-r--r--firmware/qlogic/12160.bin.ihex1771
-rw-r--r--firmware/qlogic/1280.bin.ihex2008
-rw-r--r--firmware/qlogic/isp1000.bin.ihex1158
-rw-r--r--firmware/slicoss/gbdownload.sys.ihex6148
-rw-r--r--firmware/slicoss/gbrcvucode.sys.ihex162
-rw-r--r--firmware/slicoss/oasisdbgdownload.sys.ihex5124
-rw-r--r--firmware/slicoss/oasisdownload.sys.ihex5124
-rw-r--r--firmware/slicoss/oasisrcvucode.sys.ihex162
-rw-r--r--firmware/sxg/saharadbgdownloadB.sys.ihex3937
-rw-r--r--firmware/sxg/saharadownloadB.sys.ihex3385
-rw-r--r--firmware/tehuti/bdx.bin.ihex2678
-rw-r--r--firmware/yam/1200.bin.ihex342
-rw-r--r--firmware/yam/9600.bin.ihex342
-rw-r--r--fs/9p/v9fs_vfs.h4
-rw-r--r--fs/9p/vfs_dentry.c4
-rw-r--r--fs/9p/vfs_super.c5
-rw-r--r--fs/Kconfig65
-rw-r--r--fs/Makefile11
-rw-r--r--fs/adfs/adfs.h2
-rw-r--r--fs/adfs/dir.c2
-rw-r--r--fs/adfs/super.c16
-rw-r--r--fs/affs/affs.h3
-rw-r--r--fs/affs/amigaffs.c8
-rw-r--r--fs/affs/namei.c4
-rw-r--r--fs/affs/super.c4
-rw-r--r--fs/afs/Kconfig8
-rw-r--r--fs/afs/Makefile3
-rw-r--r--fs/afs/cache.c503
-rw-r--r--fs/afs/cache.h15
-rw-r--r--fs/afs/cell.c16
-rw-r--r--fs/afs/dir.c2
-rw-r--r--fs/afs/file.c220
-rw-r--r--fs/afs/inode.c31
-rw-r--r--fs/afs/internal.h53
-rw-r--r--fs/afs/main.c27
-rw-r--r--fs/afs/mntpt.c4
-rw-r--r--fs/afs/proc.c1
-rw-r--r--fs/afs/vlocation.c25
-rw-r--r--fs/afs/volume.c14
-rw-r--r--fs/afs/write.c21
-rw-r--r--fs/anon_inodes.c2
-rw-r--r--fs/attr.c3
-rw-r--r--fs/autofs/root.c2
-rw-r--r--fs/autofs4/autofs_i.h2
-rw-r--r--fs/autofs4/dev-ioctl.c29
-rw-r--r--fs/autofs4/expire.c27
-rw-r--r--fs/autofs4/inode.c2
-rw-r--r--fs/autofs4/root.c45
-rw-r--r--fs/befs/debug.c1
-rw-r--r--fs/befs/linuxvfs.c3
-rw-r--r--fs/binfmt_elf.c22
-rw-r--r--fs/binfmt_elf_fdpic.c25
-rw-r--r--fs/binfmt_som.c7
-rw-r--r--fs/bio-integrity.c85
-rw-r--r--fs/bio.c90
-rw-r--r--fs/block_dev.c147
-rw-r--r--fs/btrfs/Makefile2
-rw-r--r--fs/btrfs/acl.c2
-rw-r--r--fs/btrfs/async-thread.c7
-rw-r--r--fs/btrfs/btrfs_inode.h31
-rw-r--r--fs/btrfs/ctree.c900
-rw-r--r--fs/btrfs/ctree.h155
-rw-r--r--fs/btrfs/delayed-ref.c668
-rw-r--r--fs/btrfs/delayed-ref.h193
-rw-r--r--fs/btrfs/dir-item.c3
-rw-r--r--fs/btrfs/disk-io.c91
-rw-r--r--fs/btrfs/disk-io.h1
-rw-r--r--fs/btrfs/extent-tree.c2062
-rw-r--r--fs/btrfs/extent_io.c67
-rw-r--r--fs/btrfs/extent_io.h3
-rw-r--r--fs/btrfs/extent_map.c1
-rw-r--r--fs/btrfs/file-item.c7
-rw-r--r--fs/btrfs/file.c50
-rw-r--r--fs/btrfs/free-space-cache.c530
-rw-r--r--fs/btrfs/free-space-cache.h44
-rw-r--r--fs/btrfs/inode-item.c3
-rw-r--r--fs/btrfs/inode.c211
-rw-r--r--fs/btrfs/ioctl.c2
-rw-r--r--fs/btrfs/locking.c25
-rw-r--r--fs/btrfs/ordered-data.c118
-rw-r--r--fs/btrfs/ordered-data.h4
-rw-r--r--fs/btrfs/super.c54
-rw-r--r--fs/btrfs/transaction.c158
-rw-r--r--fs/btrfs/transaction.h8
-rw-r--r--fs/btrfs/tree-defrag.c2
-rw-r--r--fs/btrfs/tree-log.c456
-rw-r--r--fs/btrfs/tree-log.h17
-rw-r--r--fs/btrfs/volumes.c41
-rw-r--r--fs/btrfs/volumes.h2
-rw-r--r--fs/buffer.c235
-rw-r--r--fs/cachefiles/Kconfig39
-rw-r--r--fs/cachefiles/Makefile18
-rw-r--r--fs/cachefiles/bind.c286
-rw-r--r--fs/cachefiles/daemon.c755
-rw-r--r--fs/cachefiles/interface.c449
-rw-r--r--fs/cachefiles/internal.h360
-rw-r--r--fs/cachefiles/key.c159
-rw-r--r--fs/cachefiles/main.c106
-rw-r--r--fs/cachefiles/namei.c771
-rw-r--r--fs/cachefiles/proc.c134
-rw-r--r--fs/cachefiles/rdwr.c879
-rw-r--r--fs/cachefiles/security.c116
-rw-r--r--fs/cachefiles/xattr.c291
-rw-r--r--fs/cifs/CHANGES11
-rw-r--r--fs/cifs/Kconfig21
-rw-r--r--fs/cifs/README22
-rw-r--r--fs/cifs/cifs_debug.c3
-rw-r--r--fs/cifs/cifs_dfs_ref.c36
-rw-r--r--fs/cifs/cifs_fs_sb.h1
-rw-r--r--fs/cifs/cifsfs.c3
-rw-r--r--fs/cifs/cifsfs.h4
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/cifspdu.h76
-rw-r--r--fs/cifs/cifsproto.h9
-rw-r--r--fs/cifs/cifssmb.c27
-rw-r--r--fs/cifs/connect.c9
-rw-r--r--fs/cifs/dir.c14
-rw-r--r--fs/cifs/file.c199
-rw-r--r--fs/cifs/inode.c7
-rw-r--r--fs/cifs/smbfsctl.h84
-rw-r--r--fs/coda/dir.c2
-rw-r--r--fs/compat.c148
-rw-r--r--fs/compat_ioctl.c10
-rw-r--r--fs/configfs/dir.c2
-rw-r--r--fs/cramfs/inode.c39
-rw-r--r--fs/cramfs/uncompress.c2
-rw-r--r--fs/dcache.c50
-rw-r--r--fs/devpts/inode.c188
-rw-r--r--fs/direct-io.c2
-rw-r--r--fs/dlm/dir.c18
-rw-r--r--fs/dlm/dlm_internal.h2
-rw-r--r--fs/dlm/lock.c60
-rw-r--r--fs/dlm/lockspace.c2
-rw-r--r--fs/dlm/lowcomms.c181
-rw-r--r--fs/dlm/user.c24
-rw-r--r--fs/drop_caches.c2
-rw-r--r--fs/ecryptfs/crypto.c49
-rw-r--r--fs/ecryptfs/dentry.c2
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h3
-rw-r--r--fs/ecryptfs/inode.c32
-rw-r--r--fs/ecryptfs/keystore.c3
-rw-r--r--fs/ecryptfs/messaging.c3
-rw-r--r--fs/efs/super.c20
-rw-r--r--fs/eventfd.c26
-rw-r--r--fs/eventpoll.c626
-rw-r--r--fs/exec.c52
-rw-r--r--fs/exofs/BUGS3
-rw-r--r--fs/exofs/Kbuild16
-rw-r--r--fs/exofs/Kconfig13
-rw-r--r--fs/exofs/common.h184
-rw-r--r--fs/exofs/dir.c672
-rw-r--r--fs/exofs/exofs.h180
-rw-r--r--fs/exofs/file.c87
-rw-r--r--fs/exofs/inode.c1303
-rw-r--r--fs/exofs/namei.c342
-rw-r--r--fs/exofs/osd.c153
-rw-r--r--fs/exofs/super.c584
-rw-r--r--fs/exofs/symlink.c57
-rw-r--r--fs/ext2/acl.c2
-rw-r--r--fs/ext2/balloc.c8
-rw-r--r--fs/ext2/ialloc.c10
-rw-r--r--fs/ext2/inode.c2
-rw-r--r--fs/ext2/super.c1
-rw-r--r--fs/ext2/xattr.c8
-rw-r--r--fs/ext3/Kconfig19
-rw-r--r--fs/ext3/acl.c2
-rw-r--r--fs/ext3/balloc.c8
-rw-r--r--fs/ext3/dir.c2
-rw-r--r--fs/ext3/file.c6
-rw-r--r--fs/ext3/ialloc.c12
-rw-r--r--fs/ext3/inode.c160
-rw-r--r--fs/ext3/ioctl.c59
-rw-r--r--fs/ext3/namei.c41
-rw-r--r--fs/ext3/super.c56
-rw-r--r--fs/ext3/xattr.c6
-rw-r--r--fs/ext4/Kconfig2
-rw-r--r--fs/ext4/acl.c2
-rw-r--r--fs/ext4/balloc.c16
-rw-r--r--fs/ext4/dir.c16
-rw-r--r--fs/ext4/ext4.h95
-rw-r--r--fs/ext4/ext4_extents.h1
-rw-r--r--fs/ext4/ext4_i.h6
-rw-r--r--fs/ext4/ext4_sb.h14
-rw-r--r--fs/ext4/extents.c127
-rw-r--r--fs/ext4/file.c7
-rw-r--r--fs/ext4/ialloc.c285
-rw-r--r--fs/ext4/inode.c467
-rw-r--r--fs/ext4/ioctl.c17
-rw-r--r--fs/ext4/mballoc.c204
-rw-r--r--fs/ext4/mballoc.h8
-rw-r--r--fs/ext4/namei.c170
-rw-r--r--fs/ext4/resize.c8
-rw-r--r--fs/ext4/super.c381
-rw-r--r--fs/ext4/xattr.c6
-rw-r--r--fs/fat/inode.c8
-rw-r--r--fs/fat/namei_msdos.c2
-rw-r--r--fs/fat/namei_vfat.c4
-rw-r--r--fs/fcntl.c37
-rw-r--r--fs/file_table.c4
-rw-r--r--fs/fs-writeback.c31
-rw-r--r--fs/fs_struct.c177
-rw-r--r--fs/fscache/Kconfig56
-rw-r--r--fs/fscache/Makefile19
-rw-r--r--fs/fscache/cache.c415
-rw-r--r--fs/fscache/cookie.c500
-rw-r--r--fs/fscache/fsdef.c144
-rw-r--r--fs/fscache/histogram.c109
-rw-r--r--fs/fscache/internal.h380
-rw-r--r--fs/fscache/main.c124
-rw-r--r--fs/fscache/netfs.c103
-rw-r--r--fs/fscache/object.c810
-rw-r--r--fs/fscache/operation.c459
-rw-r--r--fs/fscache/page.c816
-rw-r--r--fs/fscache/proc.c68
-rw-r--r--fs/fscache/stats.c212
-rw-r--r--fs/fuse/dir.c3
-rw-r--r--fs/fuse/file.c60
-rw-r--r--fs/fuse/fuse_i.h2
-rw-r--r--fs/generic_acl.c2
-rw-r--r--fs/gfs2/Kconfig17
-rw-r--r--fs/gfs2/Makefile4
-rw-r--r--fs/gfs2/acl.c3
-rw-r--r--fs/gfs2/bmap.c1
-rw-r--r--fs/gfs2/dir.c1
-rw-r--r--fs/gfs2/eaops.c1
-rw-r--r--fs/gfs2/eattr.c1
-rw-r--r--fs/gfs2/glock.c268
-rw-r--r--fs/gfs2/glock.h127
-rw-r--r--fs/gfs2/glops.c160
-rw-r--r--fs/gfs2/glops.h1
-rw-r--r--fs/gfs2/incore.h71
-rw-r--r--fs/gfs2/inode.c13
-rw-r--r--fs/gfs2/inode.h22
-rw-r--r--fs/gfs2/lock_dlm.c241
-rw-r--r--fs/gfs2/locking.c232
-rw-r--r--fs/gfs2/locking/dlm/Makefile3
-rw-r--r--fs/gfs2/locking/dlm/lock.c708
-rw-r--r--fs/gfs2/locking/dlm/lock_dlm.h166
-rw-r--r--fs/gfs2/locking/dlm/main.c48
-rw-r--r--fs/gfs2/locking/dlm/mount.c276
-rw-r--r--fs/gfs2/locking/dlm/sysfs.c226
-rw-r--r--fs/gfs2/locking/dlm/thread.c68
-rw-r--r--fs/gfs2/log.c1
-rw-r--r--fs/gfs2/lops.c1
-rw-r--r--fs/gfs2/main.c13
-rw-r--r--fs/gfs2/meta_io.c22
-rw-r--r--fs/gfs2/meta_io.h1
-rw-r--r--fs/gfs2/mount.c128
-rw-r--r--fs/gfs2/mount.h17
-rw-r--r--fs/gfs2/ops_address.c5
-rw-r--r--fs/gfs2/ops_dentry.c3
-rw-r--r--fs/gfs2/ops_export.c1
-rw-r--r--fs/gfs2/ops_file.c81
-rw-r--r--fs/gfs2/ops_fstype.c156
-rw-r--r--fs/gfs2/ops_inode.c1
-rw-r--r--fs/gfs2/ops_super.c44
-rw-r--r--fs/gfs2/quota.c203
-rw-r--r--fs/gfs2/quota.h2
-rw-r--r--fs/gfs2/recovery.c28
-rw-r--r--fs/gfs2/rgrp.c189
-rw-r--r--fs/gfs2/super.c3
-rw-r--r--fs/gfs2/super.h28
-rw-r--r--fs/gfs2/sys.c236
-rw-r--r--fs/gfs2/trans.c19
-rw-r--r--fs/gfs2/util.c11
-rw-r--r--fs/hfs/hfs_fs.h2
-rw-r--r--fs/hfs/super.c3
-rw-r--r--fs/hfs/sysdep.c2
-rw-r--r--fs/hfsplus/hfsplus_fs.h2
-rw-r--r--fs/hfsplus/inode.c2
-rw-r--r--fs/hfsplus/options.c2
-rw-r--r--fs/hfsplus/super.c3
-rw-r--r--fs/hostfs/hostfs_kern.c4
-rw-r--r--fs/hpfs/dentry.c2
-rw-r--r--fs/hpfs/super.c5
-rw-r--r--fs/hppfs/hppfs.c7
-rw-r--r--fs/hugetlbfs/inode.c21
-rw-r--r--fs/inode.c77
-rw-r--r--fs/internal.h8
-rw-r--r--fs/ioctl.c18
-rw-r--r--fs/isofs/inode.c5
-rw-r--r--fs/jbd/commit.c28
-rw-r--r--fs/jbd/journal.c34
-rw-r--r--fs/jbd/transaction.c2
-rw-r--r--fs/jbd2/commit.c16
-rw-r--r--fs/jbd2/revoke.c24
-rw-r--r--fs/jbd2/transaction.c2
-rw-r--r--fs/jffs2/acl.c6
-rw-r--r--fs/jffs2/malloc.c6
-rw-r--r--fs/jfs/Kconfig1
-rw-r--r--fs/jfs/acl.c4
-rw-r--r--fs/jfs/inode.c6
-rw-r--r--fs/jfs/jfs_debug.c1
-rw-r--r--fs/jfs/jfs_dtree.c18
-rw-r--r--fs/jfs/jfs_extent.c73
-rw-r--r--fs/jfs/jfs_imap.c10
-rw-r--r--fs/jfs/jfs_inode.c4
-rw-r--r--fs/jfs/jfs_inode.h2
-rw-r--r--fs/jfs/jfs_metapage.c18
-rw-r--r--fs/jfs/jfs_types.h29
-rw-r--r--fs/jfs/jfs_xtree.c277
-rw-r--r--fs/jfs/jfs_xtree.h2
-rw-r--r--fs/jfs/namei.c10
-rw-r--r--fs/jfs/super.c4
-rw-r--r--fs/jfs/xattr.c12
-rw-r--r--fs/libfs.c21
-rw-r--r--fs/lockd/clntlock.c51
-rw-r--r--fs/lockd/mon.c8
-rw-r--r--fs/lockd/svc.c42
-rw-r--r--fs/lockd/svclock.c13
-rw-r--r--fs/minix/inode.c13
-rw-r--r--fs/mpage.c13
-rw-r--r--fs/namei.c70
-rw-r--r--fs/namespace.c75
-rw-r--r--fs/ncpfs/dir.c4
-rw-r--r--fs/nfs/Kconfig8
-rw-r--r--fs/nfs/Makefile1
-rw-r--r--fs/nfs/callback.c31
-rw-r--r--fs/nfs/callback.h1
-rw-r--r--fs/nfs/client.c132
-rw-r--r--fs/nfs/dir.c13
-rw-r--r--fs/nfs/file.c75
-rw-r--r--fs/nfs/fscache-index.c337
-rw-r--r--fs/nfs/fscache.c523
-rw-r--r--fs/nfs/fscache.h220
-rw-r--r--fs/nfs/getroot.c4
-rw-r--r--fs/nfs/inode.c323
-rw-r--r--fs/nfs/internal.h8
-rw-r--r--fs/nfs/iostat.h18
-rw-r--r--fs/nfs/nfs2xdr.c9
-rw-r--r--fs/nfs/nfs3proc.c7
-rw-r--r--fs/nfs/nfs3xdr.c37
-rw-r--r--fs/nfs/nfs4_fs.h2
-rw-r--r--fs/nfs/nfs4proc.c49
-rw-r--r--fs/nfs/nfs4state.c10
-rw-r--r--fs/nfs/nfs4xdr.c213
-rw-r--r--fs/nfs/pagelist.c11
-rw-r--r--fs/nfs/proc.c1
-rw-r--r--fs/nfs/read.c27
-rw-r--r--fs/nfs/super.c49
-rw-r--r--fs/nfs/write.c53
-rw-r--r--fs/nfsd/Kconfig1
-rw-r--r--fs/nfsd/nfs3proc.c10
-rw-r--r--fs/nfsd/nfs4callback.c47
-rw-r--r--fs/nfsd/nfs4proc.c246
-rw-r--r--fs/nfsd/nfs4recover.c74
-rw-r--r--fs/nfsd/nfs4state.c1196
-rw-r--r--fs/nfsd/nfs4xdr.c633
-rw-r--r--fs/nfsd/nfsctl.c44
-rw-r--r--fs/nfsd/nfsproc.c3
-rw-r--r--fs/nfsd/nfssvc.c100
-rw-r--r--fs/nfsd/vfs.c46
-rw-r--r--fs/notify/inotify/inotify.c16
-rw-r--r--fs/ntfs/dir.c4
-rw-r--r--fs/ntfs/inode.c3
-rw-r--r--fs/ntfs/layout.h329
-rw-r--r--fs/ntfs/logfile.h6
-rw-r--r--fs/ntfs/mft.c2
-rw-r--r--fs/ntfs/super.c50
-rw-r--r--fs/ntfs/usnjrnl.h48
-rw-r--r--fs/ocfs2/acl.c2
-rw-r--r--fs/ocfs2/alloc.c57
-rw-r--r--fs/ocfs2/alloc.h3
-rw-r--r--fs/ocfs2/aops.c23
-rw-r--r--fs/ocfs2/cluster/heartbeat.c96
-rw-r--r--fs/ocfs2/cluster/heartbeat.h3
-rw-r--r--fs/ocfs2/cluster/nodemanager.c9
-rw-r--r--fs/ocfs2/dcache.c2
-rw-r--r--fs/ocfs2/dcache.h2
-rw-r--r--fs/ocfs2/dir.c2806
-rw-r--r--fs/ocfs2/dir.h57
-rw-r--r--fs/ocfs2/dlm/dlmcommon.h58
-rw-r--r--fs/ocfs2/dlm/dlmdebug.c87
-rw-r--r--fs/ocfs2/dlm/dlmdomain.c29
-rw-r--r--fs/ocfs2/dlm/dlmmaster.c387
-rw-r--r--fs/ocfs2/dlm/dlmthread.c20
-rw-r--r--fs/ocfs2/dlmglue.c46
-rw-r--r--fs/ocfs2/dlmglue.h2
-rw-r--r--fs/ocfs2/export.c84
-rw-r--r--fs/ocfs2/inode.c48
-rw-r--r--fs/ocfs2/inode.h5
-rw-r--r--fs/ocfs2/journal.c173
-rw-r--r--fs/ocfs2/journal.h77
-rw-r--r--fs/ocfs2/localalloc.c86
-rw-r--r--fs/ocfs2/mmap.c6
-rw-r--r--fs/ocfs2/namei.c250
-rw-r--r--fs/ocfs2/ocfs2.h76
-rw-r--r--fs/ocfs2/ocfs2_fs.h136
-rw-r--r--fs/ocfs2/ocfs2_lockid.h4
-rw-r--r--fs/ocfs2/suballoc.c254
-rw-r--r--fs/ocfs2/suballoc.h4
-rw-r--r--fs/ocfs2/super.c188
-rw-r--r--fs/ocfs2/xattr.c8
-rw-r--r--fs/ocfs2/xattr.h2
-rw-r--r--fs/omfs/inode.c7
-rw-r--r--fs/open.c3
-rw-r--r--fs/partitions/check.c10
-rw-r--r--fs/partitions/ibm.c101
-rw-r--r--fs/pipe.c23
-rw-r--r--fs/proc/base.c57
-rw-r--r--fs/proc/generic.c65
-rw-r--r--fs/proc/inode-alloc.txt14
-rw-r--r--fs/proc/inode.c21
-rw-r--r--fs/proc/internal.h1
-rw-r--r--fs/proc/meminfo.c2
-rw-r--r--fs/proc/nommu.c2
-rw-r--r--fs/proc/proc_sysctl.c4
-rw-r--r--fs/proc/proc_tty.c13
-rw-r--r--fs/proc/root.c3
-rw-r--r--fs/proc/task_mmu.c8
-rw-r--r--fs/proc/task_nommu.c7
-rw-r--r--fs/proc/uptime.c38
-rw-r--r--fs/qnx4/inode.c3
-rw-r--r--fs/quota/Kconfig59
-rw-r--r--fs/quota/Makefile14
-rw-r--r--fs/quota/dquot.c (renamed from fs/dquot.c)577
-rw-r--r--fs/quota/quota.c (renamed from fs/quota.c)37
-rw-r--r--fs/quota/quota_tree.c (renamed from fs/quota_tree.c)132
-rw-r--r--fs/quota/quota_tree.h (renamed from fs/quota_tree.h)0
-rw-r--r--fs/quota/quota_v1.c (renamed from fs/quota_v1.c)48
-rw-r--r--fs/quota/quota_v2.c (renamed from fs/quota_v2.c)3
-rw-r--r--fs/quota/quotaio_v1.h (renamed from fs/quotaio_v1.h)0
-rw-r--r--fs/quota/quotaio_v2.h (renamed from fs/quotaio_v2.h)0
-rw-r--r--fs/ramfs/file-nommu.c21
-rw-r--r--fs/ramfs/inode.c94
-rw-r--r--fs/read_write.c56
-rw-r--r--fs/reiserfs/Kconfig1
-rw-r--r--fs/reiserfs/Makefile4
-rw-r--r--fs/reiserfs/README4
-rw-r--r--fs/reiserfs/bitmap.c86
-rw-r--r--fs/reiserfs/dir.c28
-rw-r--r--fs/reiserfs/do_balan.c313
-rw-r--r--fs/reiserfs/file.c34
-rw-r--r--fs/reiserfs/fix_node.c1021
-rw-r--r--fs/reiserfs/hashes.c2
-rw-r--r--fs/reiserfs/ibalance.c22
-rw-r--r--fs/reiserfs/inode.c213
-rw-r--r--fs/reiserfs/ioctl.c2
-rw-r--r--fs/reiserfs/item_ops.c68
-rw-r--r--fs/reiserfs/journal.c1077
-rw-r--r--fs/reiserfs/lbalance.c66
-rw-r--r--fs/reiserfs/namei.c186
-rw-r--r--fs/reiserfs/objectid.c12
-rw-r--r--fs/reiserfs/prints.c134
-rw-r--r--fs/reiserfs/procfs.c16
-rw-r--r--fs/reiserfs/resize.c6
-rw-r--r--fs/reiserfs/stree.c1174
-rw-r--r--fs/reiserfs/super.c368
-rw-r--r--fs/reiserfs/tail_conversion.c96
-rw-r--r--fs/reiserfs/xattr.c1377
-rw-r--r--fs/reiserfs/xattr_acl.c259
-rw-r--r--fs/reiserfs/xattr_security.c80
-rw-r--r--fs/reiserfs/xattr_trusted.c45
-rw-r--r--fs/reiserfs/xattr_user.c31
-rw-r--r--fs/romfs/Kconfig48
-rw-r--r--fs/romfs/Makefile9
-rw-r--r--fs/romfs/inode.c665
-rw-r--r--fs/romfs/internal.h47
-rw-r--r--fs/romfs/mmap-nommu.c75
-rw-r--r--fs/romfs/storage.c261
-rw-r--r--fs/romfs/super.c648
-rw-r--r--fs/seq_file.c2
-rw-r--r--fs/smbfs/dir.c4
-rw-r--r--fs/splice.c3
-rw-r--r--fs/squashfs/export.c1
-rw-r--r--fs/squashfs/super.c3
-rw-r--r--fs/super.c29
-rw-r--r--fs/sync.c16
-rw-r--r--fs/sysfs/bin.c253
-rw-r--r--fs/sysfs/dir.c35
-rw-r--r--fs/sysfs/file.c26
-rw-r--r--fs/sysfs/inode.c17
-rw-r--r--fs/sysfs/mount.c6
-rw-r--r--fs/sysfs/sysfs.h3
-rw-r--r--fs/sysv/inode.c3
-rw-r--r--fs/sysv/namei.c2
-rw-r--r--fs/sysv/sysv.h2
-rw-r--r--fs/ubifs/Kconfig4
-rw-r--r--fs/ubifs/budget.c37
-rw-r--r--fs/ubifs/debug.c6
-rw-r--r--fs/ubifs/file.c25
-rw-r--r--fs/ubifs/find.c12
-rw-r--r--fs/ubifs/gc.c428
-rw-r--r--fs/ubifs/journal.c7
-rw-r--r--fs/ubifs/key.h6
-rw-r--r--fs/ubifs/log.c5
-rw-r--r--fs/ubifs/lpt_commit.c34
-rw-r--r--fs/ubifs/recovery.c70
-rw-r--r--fs/ubifs/replay.c2
-rw-r--r--fs/ubifs/sb.c36
-rw-r--r--fs/ubifs/shrinker.c6
-rw-r--r--fs/ubifs/super.c40
-rw-r--r--fs/ubifs/tnc.c2
-rw-r--r--fs/ubifs/ubifs-media.h30
-rw-r--r--fs/ubifs/ubifs.h13
-rw-r--r--fs/udf/balloc.c164
-rw-r--r--fs/udf/dir.c14
-rw-r--r--fs/udf/directory.c38
-rw-r--r--fs/udf/ecma_167.h416
-rw-r--r--fs/udf/ialloc.c17
-rw-r--r--fs/udf/inode.c213
-rw-r--r--fs/udf/misc.c29
-rw-r--r--fs/udf/namei.c86
-rw-r--r--fs/udf/osta_udf.h22
-rw-r--r--fs/udf/partition.c2
-rw-r--r--fs/udf/super.c605
-rw-r--r--fs/udf/truncate.c44
-rw-r--r--fs/udf/udf_i.h6
-rw-r--r--fs/udf/udf_sb.h9
-rw-r--r--fs/udf/udfdecl.h57
-rw-r--r--fs/udf/udfend.h28
-rw-r--r--fs/udf/udftime.c6
-rw-r--r--fs/udf/unicode.c62
-rw-r--r--fs/ufs/balloc.c12
-rw-r--r--fs/ufs/ialloc.c8
-rw-r--r--fs/ufs/inode.c39
-rw-r--r--fs/ufs/namei.c2
-rw-r--r--fs/ufs/super.c16
-rw-r--r--fs/ufs/ufs.h2
-rw-r--r--fs/xfs/Makefile1
-rw-r--r--fs/xfs/linux-2.6/mutex.h25
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c107
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c37
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h13
-rw-r--r--fs/xfs/linux-2.6/xfs_quotaops.c157
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c137
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h32
-rw-r--r--fs/xfs/quota/xfs_dquot.c28
-rw-r--r--fs/xfs/quota/xfs_dquot.h18
-rw-r--r--fs/xfs/quota/xfs_qm.c212
-rw-r--r--fs/xfs/quota/xfs_qm.h26
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c1
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c190
-rw-r--r--fs/xfs/quota/xfs_quota_priv.h40
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c16
-rw-r--r--fs/xfs/support/debug.c1
-rw-r--r--fs/xfs/support/uuid.c71
-rw-r--r--fs/xfs/support/uuid.h4
-rw-r--r--fs/xfs/xfs_ag.h4
-rw-r--r--fs/xfs/xfs_alloc.c26
-rw-r--r--fs/xfs/xfs_alloc.h6
-rw-r--r--fs/xfs/xfs_attr_leaf.c58
-rw-r--r--fs/xfs/xfs_bmap.c76
-rw-r--r--fs/xfs/xfs_bmap.h6
-rw-r--r--fs/xfs/xfs_btree.c4
-rw-r--r--fs/xfs/xfs_btree.h2
-rw-r--r--fs/xfs/xfs_da_btree.c2
-rw-r--r--fs/xfs/xfs_da_btree.h9
-rw-r--r--fs/xfs/xfs_dfrag.c68
-rw-r--r--fs/xfs/xfs_dinode.h4
-rw-r--r--fs/xfs/xfs_dir2.c2
-rw-r--r--fs/xfs/xfs_dir2_block.c7
-rw-r--r--fs/xfs/xfs_dir2_data.h2
-rw-r--r--fs/xfs/xfs_dir2_leaf.c17
-rw-r--r--fs/xfs/xfs_dir2_node.c2
-rw-r--r--fs/xfs/xfs_dir2_sf.c13
-rw-r--r--fs/xfs/xfs_extfree_item.h6
-rw-r--r--fs/xfs/xfs_filestream.c9
-rw-r--r--fs/xfs/xfs_fsops.c2
-rw-r--r--fs/xfs/xfs_ialloc.c12
-rw-r--r--fs/xfs/xfs_ialloc_btree.c2
-rw-r--r--fs/xfs/xfs_ialloc_btree.h22
-rw-r--r--fs/xfs/xfs_inode.h2
-rw-r--r--fs/xfs/xfs_inode_item.h2
-rw-r--r--fs/xfs/xfs_iomap.h2
-rw-r--r--fs/xfs/xfs_itable.c9
-rw-r--r--fs/xfs/xfs_log.c67
-rw-r--r--fs/xfs/xfs_log.h3
-rw-r--r--fs/xfs/xfs_log_priv.h3
-rw-r--r--fs/xfs/xfs_log_recover.c308
-rw-r--r--fs/xfs/xfs_mount.c253
-rw-r--r--fs/xfs/xfs_mount.h19
-rw-r--r--fs/xfs/xfs_qmops.c1
-rw-r--r--fs/xfs/xfs_quota.h3
-rw-r--r--fs/xfs/xfs_rtalloc.c10
-rw-r--r--fs/xfs/xfs_rtalloc.h8
-rw-r--r--fs/xfs/xfs_trans.h24
-rw-r--r--fs/xfs/xfs_trans_ail.c4
-rw-r--r--fs/xfs/xfs_trans_item.c2
-rw-r--r--fs/xfs/xfs_trans_space.h2
-rw-r--r--fs/xfs/xfs_types.h8
-rw-r--r--fs/xfs/xfs_utils.c2
-rw-r--r--fs/xfs/xfs_vnodeops.c408
-rw-r--r--fs/xfs/xfs_vnodeops.h3
-rw-r--r--include/acpi/acexcep.h6
-rw-r--r--include/acpi/acpi_bus.h18
-rw-r--r--include/acpi/acpi_drivers.h33
-rw-r--r--include/acpi/acpiosxf.h4
-rw-r--r--include/acpi/acpixf.h16
-rw-r--r--include/acpi/actbl.h74
-rw-r--r--include/acpi/actbl1.h6
-rw-r--r--include/acpi/actypes.h18
-rw-r--r--include/acpi/processor.h4
-rw-r--r--include/acpi/video.h11
-rw-r--r--include/asm-frv/highmem.h2
-rw-r--r--include/asm-frv/socket.h3
-rw-r--r--include/asm-generic/dma-mapping.h308
-rw-r--r--include/asm-generic/fcntl.h12
-rw-r--r--include/asm-generic/gpio.h5
-rw-r--r--include/asm-generic/siginfo.h14
-rw-r--r--include/asm-generic/statfs.h5
-rw-r--r--include/asm-generic/topology.h10
-rw-r--r--include/asm-generic/vmlinux.lds.h15
-rw-r--r--include/asm-m32r/socket.h3
-rw-r--r--include/asm-m32r/spinlock.h3
-rw-r--r--include/asm-mn10300/highmem.h2
-rw-r--r--include/asm-mn10300/ide.h39
-rw-r--r--include/asm-mn10300/pci.h5
-rw-r--r--include/asm-mn10300/socket.h3
-rw-r--r--include/crypto/aes.h6
-rw-r--r--include/crypto/compress.h145
-rw-r--r--include/crypto/cryptd.h27
-rw-r--r--include/crypto/crypto_wq.h7
-rw-r--r--include/crypto/hash.h5
-rw-r--r--include/crypto/internal/compress.h28
-rw-r--r--include/drm/drm.h21
-rw-r--r--include/drm/drmP.h145
-rw-r--r--include/drm/drm_crtc.h6
-rw-r--r--include/drm/drm_crtc_helper.h3
-rw-r--r--include/drm/drm_mode.h153
-rw-r--r--include/drm/drm_os_linux.h19
-rw-r--r--include/drm/drm_pciids.h115
-rw-r--r--include/drm/i915_drm.h140
-rw-r--r--include/drm/mga_drm.h18
-rw-r--r--include/drm/radeon_drm.h9
-rw-r--r--include/drm/via_drm.h42
-rw-r--r--include/linux/Kbuild4
-rw-r--r--include/linux/acpi.h35
-rw-r--r--include/linux/agpgart.h14
-rw-r--r--include/linux/arcdevice.h9
-rw-r--r--include/linux/async_tx.h9
-rw-r--r--include/linux/ata.h8
-rw-r--r--include/linux/ath9k_platform.h28
-rw-r--r--include/linux/atmlec.h5
-rw-r--r--include/linux/atmmpc.h45
-rw-r--r--include/linux/audit.h9
-rw-r--r--include/linux/auto_dev-ioctl.h7
-rw-r--r--include/linux/auto_fs.h6
-rw-r--r--include/linux/backing-dev.h12
-rw-r--r--include/linux/binfmts.h3
-rw-r--r--include/linux/bio.h37
-rw-r--r--include/linux/blkdev.h55
-rw-r--r--include/linux/bootmem.h6
-rw-r--r--include/linux/bsg.h10
-rw-r--r--include/linux/buffer_head.h21
-rw-r--r--include/linux/cgroup.h142
-rw-r--r--include/linux/clk.h17
-rw-r--r--include/linux/clocksource.h101
-rw-r--r--include/linux/cm4000_cs.h10
-rw-r--r--include/linux/cn_proc.h20
-rw-r--r--include/linux/com20020.h1
-rw-r--r--include/linux/compat.h14
-rw-r--r--include/linux/compiler-gcc4.h6
-rw-r--r--include/linux/connector.h12
-rw-r--r--include/linux/console.h4
-rw-r--r--include/linux/cpu.h16
-rw-r--r--include/linux/cpuset.h37
-rw-r--r--include/linux/crypto.h4
-rw-r--r--include/linux/cyclades.h6
-rw-r--r--include/linux/dca.h20
-rw-r--r--include/linux/dcache.h2
-rw-r--r--include/linux/dccp.h51
-rw-r--r--include/linux/device-mapper.h3
-rw-r--r--include/linux/device.h38
-rw-r--r--include/linux/dlm_netlink.h18
-rw-r--r--include/linux/dm-dirty-log.h13
-rw-r--r--include/linux/dm-ioctl.h42
-rw-r--r--include/linux/dma-debug.h174
-rw-r--r--include/linux/dma-mapping.h48
-rw-r--r--include/linux/dma_remapping.h1
-rw-r--r--include/linux/dmaengine.h30
-rw-r--r--include/linux/dmar.h63
-rw-r--r--include/linux/dmi.h7
-rw-r--r--include/linux/ds1wm.h12
-rw-r--r--include/linux/dst.h587
-rw-r--r--include/linux/dvb/audio.h2
-rw-r--r--include/linux/dvb/video.h24
-rw-r--r--include/linux/dw_dmac.h19
-rw-r--r--include/linux/dynamic_debug.h88
-rw-r--r--include/linux/dynamic_printk.h93
-rw-r--r--include/linux/errqueue.h1
-rw-r--r--include/linux/etherdevice.h21
-rw-r--r--include/linux/ethtool.h89
-rw-r--r--include/linux/eventfd.h12
-rw-r--r--include/linux/eventpoll.h1
-rw-r--r--include/linux/ext3_fs.h6
-rw-r--r--include/linux/fb.h11
-rw-r--r--include/linux/fdtable.h4
-rw-r--r--include/linux/firewire-cdev.h218
-rw-r--r--include/linux/fs.h281
-rw-r--r--include/linux/fs_struct.h7
-rw-r--r--include/linux/fscache-cache.h505
-rw-r--r--include/linux/fscache.h618
-rw-r--r--include/linux/fsl_devices.h7
-rw-r--r--include/linux/gen_stats.h2
-rw-r--r--include/linux/genhd.h5
-rw-r--r--include/linux/gfp.h1
-rw-r--r--include/linux/hdlc.h5
-rw-r--r--include/linux/hdlcdrv.h3
-rw-r--r--include/linux/hdreg.h66
-rw-r--r--include/linux/hid.h23
-rw-r--r--include/linux/highmem.h17
-rw-r--r--include/linux/hrtimer.h5
-rw-r--r--include/linux/i2c-algo-pca.h33
-rw-r--r--include/linux/i2c-algo-sgi.h26
-rw-r--r--include/linux/i2c-id.h37
-rw-r--r--include/linux/i2c-pca-platform.h2
-rw-r--r--include/linux/i2c.h4
-rw-r--r--include/linux/i2c/at24.h4
-rw-r--r--include/linux/i2c/twl4030.h47
-rw-r--r--include/linux/ibmtr.h2
-rw-r--r--include/linux/ide.h347
-rw-r--r--include/linux/idr.h1
-rw-r--r--include/linux/ieee80211.h198
-rw-r--r--include/linux/if.h1
-rw-r--r--include/linux/if_arcnet.h27
-rw-r--r--include/linux/if_ether.h9
-rw-r--r--include/linux/if_frad.h1
-rw-r--r--include/linux/if_pppol2tp.h2
-rw-r--r--include/linux/if_pppox.h20
-rw-r--r--include/linux/if_tun.h2
-rw-r--r--include/linux/if_tunnel.h16
-rw-r--r--include/linux/ima.h61
-rw-r--r--include/linux/inetdevice.h1
-rw-r--r--include/linux/init_task.h1
-rw-r--r--include/linux/input.h1
-rw-r--r--include/linux/intel-iommu.h27
-rw-r--r--include/linux/interrupt.h27
-rw-r--r--include/linux/iommu.h13
-rw-r--r--include/linux/ip_vs.h26
-rw-r--r--include/linux/ipmi_smi.h2
-rw-r--r--include/linux/irq.h19
-rw-r--r--include/linux/irqnr.h8
-rw-r--r--include/linux/irqreturn.h28
-rw-r--r--include/linux/ivtv.h10
-rw-r--r--include/linux/ivtvfb.h2
-rw-r--r--include/linux/jbd.h7
-rw-r--r--include/linux/jbd2.h6
-rw-r--r--include/linux/jffs2.h27
-rw-r--r--include/linux/kallsyms.h15
-rw-r--r--include/linux/kernel.h25
-rw-r--r--include/linux/kernel_stat.h13
-rw-r--r--include/linux/key.h1
-rw-r--r--include/linux/kmod.h11
-rw-r--r--include/linux/kobject.h3
-rw-r--r--include/linux/kvm.h115
-rw-r--r--include/linux/kvm_host.h62
-rw-r--r--include/linux/kvm_types.h13
-rw-r--r--include/linux/latencytop.h10
-rw-r--r--include/linux/leds-bd2802.h26
-rw-r--r--include/linux/leds.h4
-rw-r--r--include/linux/leds_pwm.h21
-rw-r--r--include/linux/libata.h10
-rw-r--r--include/linux/lm_interface.h277
-rw-r--r--include/linux/lockd/xdr.h12
-rw-r--r--include/linux/lockd/xdr4.h10
-rw-r--r--include/linux/lockdep.h17
-rw-r--r--include/linux/loop.h1
-rw-r--r--include/linux/major.h1
-rw-r--r--include/linux/maple.h62
-rw-r--r--include/linux/matroxfb.h2
-rw-r--r--include/linux/memcontrol.h20
-rw-r--r--include/linux/memory.h11
-rw-r--r--include/linux/mfd/ds1wm.h6
-rw-r--r--include/linux/mfd/htc-pasic3.h1
-rw-r--r--include/linux/mfd/wm8350/audio.h1
-rw-r--r--include/linux/mfd/wm8350/core.h2
-rw-r--r--include/linux/mfd/wm8400-audio.h1
-rw-r--r--include/linux/miscdevice.h1
-rw-r--r--include/linux/mlx4/cmd.h1
-rw-r--r--include/linux/mlx4/device.h6
-rw-r--r--include/linux/mm.h9
-rw-r--r--include/linux/mm_types.h4
-rw-r--r--include/linux/mmc/host.h5
-rw-r--r--include/linux/mmzone.h14
-rw-r--r--include/linux/mnt_namespace.h2
-rw-r--r--include/linux/mod_devicetable.h9
-rw-r--r--include/linux/module.h63
-rw-r--r--include/linux/moduleparam.h10
-rw-r--r--include/linux/mount.h1
-rw-r--r--include/linux/mpage.h10
-rw-r--r--include/linux/mroute.h18
-rw-r--r--include/linux/mroute6.h2
-rw-r--r--include/linux/msi.h13
-rw-r--r--include/linux/mtd/mtd.h21
-rw-r--r--include/linux/mtd/nand.h4
-rw-r--r--include/linux/mtd/partitions.h12
-rw-r--r--include/linux/ncp_fs.h2
-rw-r--r--include/linux/ncp_no.h26
-rw-r--r--include/linux/neighbour.h1
-rw-r--r--include/linux/net.h8
-rw-r--r--include/linux/net_dropmon.h56
-rw-r--r--include/linux/net_tstamp.h104
-rw-r--r--include/linux/netdevice.h130
-rw-r--r--include/linux/netfilter/Kbuild8
-rw-r--r--include/linux/netfilter/nf_conntrack_tcp.h6
-rw-r--r--include/linux/netfilter/nfnetlink.h5
-rw-r--r--include/linux/netfilter/nfnetlink_compat.h7
-rw-r--r--include/linux/netfilter/nfnetlink_log.h32
-rw-r--r--include/linux/netfilter/nfnetlink_queue.h24
-rw-r--r--include/linux/netfilter/x_tables.h68
-rw-r--r--include/linux/netfilter/xt_CLASSIFY.h4
-rw-r--r--include/linux/netfilter/xt_CONNMARK.h8
-rw-r--r--include/linux/netfilter/xt_CONNSECMARK.h4
-rw-r--r--include/linux/netfilter/xt_DSCP.h7
-rw-r--r--include/linux/netfilter/xt_LED.h13
-rw-r--r--include/linux/netfilter/xt_MARK.h6
-rw-r--r--include/linux/netfilter/xt_NFLOG.h12
-rw-r--r--include/linux/netfilter/xt_NFQUEUE.h4
-rw-r--r--include/linux/netfilter/xt_RATEEST.h6
-rw-r--r--include/linux/netfilter/xt_SECMARK.h6
-rw-r--r--include/linux/netfilter/xt_TCPMSS.h4
-rw-r--r--include/linux/netfilter/xt_cluster.h15
-rw-r--r--include/linux/netfilter/xt_connbytes.h6
-rw-r--r--include/linux/netfilter/xt_connmark.h8
-rw-r--r--include/linux/netfilter/xt_conntrack.h12
-rw-r--r--include/linux/netfilter/xt_dccp.h14
-rw-r--r--include/linux/netfilter/xt_dscp.h12
-rw-r--r--include/linux/netfilter/xt_esp.h6
-rw-r--r--include/linux/netfilter/xt_hashlimit.h32
-rw-r--r--include/linux/netfilter/xt_iprange.h4
-rw-r--r--include/linux/netfilter/xt_length.h6
-rw-r--r--include/linux/netfilter/xt_limit.h17
-rw-r--r--include/linux/netfilter/xt_mark.h8
-rw-r--r--include/linux/netfilter/xt_multiport.h18
-rw-r--r--include/linux/netfilter/xt_owner.h8
-rw-r--r--include/linux/netfilter/xt_physdev.h6
-rw-r--r--include/linux/netfilter/xt_policy.h14
-rw-r--r--include/linux/netfilter/xt_quota.h4
-rw-r--r--include/linux/netfilter/xt_rateest.h14
-rw-r--r--include/linux/netfilter/xt_realm.h8
-rw-r--r--include/linux/netfilter/xt_recent.h12
-rw-r--r--include/linux/netfilter/xt_sctp.h36
-rw-r--r--include/linux/netfilter/xt_statistic.h19
-rw-r--r--include/linux/netfilter/xt_string.h12
-rw-r--r--include/linux/netfilter/xt_tcpmss.h6
-rw-r--r--include/linux/netfilter/xt_tcpudp.h20
-rw-r--r--include/linux/netfilter_bridge.h4
-rw-r--r--include/linux/netfilter_ipv4/ipt_owner.h8
-rw-r--r--include/linux/netfilter_ipv6/Kbuild1
-rw-r--r--include/linux/netfilter_ipv6/ip6t_owner.h8
-rw-r--r--include/linux/netlink.h2
-rw-r--r--include/linux/netpoll.h13
-rw-r--r--include/linux/nfs.h1
-rw-r--r--include/linux/nfs4.h138
-rw-r--r--include/linux/nfs_fs.h19
-rw-r--r--include/linux/nfs_fs_sb.h16
-rw-r--r--include/linux/nfs_iostat.h12
-rw-r--r--include/linux/nfs_xdr.h61
-rw-r--r--include/linux/nfsd/cache.h8
-rw-r--r--include/linux/nfsd/nfsd.h225
-rw-r--r--include/linux/nfsd/nfsfh.h7
-rw-r--r--include/linux/nfsd/state.h84
-rw-r--r--include/linux/nfsd/stats.h9
-rw-r--r--include/linux/nfsd/xdr4.h129
-rw-r--r--include/linux/nl80211.h261
-rw-r--r--include/linux/nsproxy.h1
-rw-r--r--include/linux/page-debug-flags.h30
-rw-r--r--include/linux/page-flags.h60
-rw-r--r--include/linux/page_cgroup.h13
-rw-r--r--include/linux/pagemap.h17
-rw-r--r--include/linux/pagevec.h1
-rw-r--r--include/linux/pci-acpi.h67
-rw-r--r--include/linux/pci.h62
-rw-r--r--include/linux/pci_ids.h51
-rw-r--r--include/linux/pci_regs.h37
-rw-r--r--include/linux/pcieport_if.h36
-rw-r--r--include/linux/percpu.h6
-rw-r--r--include/linux/pfkeyv2.h242
-rw-r--r--include/linux/phy.h3
-rw-r--r--include/linux/pim.h4
-rw-r--r--include/linux/platform_device.h7
-rw-r--r--include/linux/plist.h9
-rw-r--r--include/linux/pm.h11
-rw-r--r--include/linux/poison.h3
-rw-r--r--include/linux/power_supply.h2
-rw-r--r--include/linux/ppp_channel.h6
-rw-r--r--include/linux/ppp_defs.h4
-rw-r--r--include/linux/proc_fs.h4
-rw-r--r--include/linux/ptrace.h1
-rw-r--r--include/linux/pwm.h2
-rw-r--r--include/linux/quota.h11
-rw-r--r--include/linux/quotaops.h119
-rw-r--r--include/linux/raid/md.h81
-rw-r--r--include/linux/raid/md_u.h35
-rw-r--r--include/linux/raid/pq.h (renamed from drivers/md/raid6.h)28
-rw-r--r--include/linux/raid/xor.h2
-rw-r--r--include/linux/rcuclassic.h16
-rw-r--r--include/linux/rcupdate.h1
-rw-r--r--include/linux/rcupreempt.h53
-rw-r--r--include/linux/rcutree.h27
-rw-r--r--include/linux/rds.h250
-rw-r--r--include/linux/regulator/bq24022.h3
-rw-r--r--include/linux/regulator/consumer.h6
-rw-r--r--include/linux/regulator/driver.h81
-rw-r--r--include/linux/regulator/fixed.h3
-rw-r--r--include/linux/regulator/machine.h12
-rw-r--r--include/linux/reiserfs_acl.h22
-rw-r--r--include/linux/reiserfs_fs.h168
-rw-r--r--include/linux/reiserfs_fs_i.h4
-rw-r--r--include/linux/reiserfs_fs_sb.h31
-rw-r--r--include/linux/reiserfs_xattr.h154
-rw-r--r--include/linux/ring_buffer.h11
-rw-r--r--include/linux/rtc-v3020.h6
-rw-r--r--include/linux/rtc.h6
-rw-r--r--include/linux/rtnetlink.h5
-rw-r--r--include/linux/sched.h96
-rw-r--r--include/linux/sctp.h92
-rw-r--r--include/linux/security.h37
-rw-r--r--include/linux/selinux_netlink.h6
-rw-r--r--include/linux/seq_file.h9
-rw-r--r--include/linux/serial_core.h2
-rw-r--r--include/linux/sh_cmt.h13
-rw-r--r--include/linux/sh_intc.h1
-rw-r--r--include/linux/skbuff.h127
-rw-r--r--include/linux/slab_def.h10
-rw-r--r--include/linux/slow-work.h95
-rw-r--r--include/linux/slub_def.h18
-rw-r--r--include/linux/smp.h7
-rw-r--r--include/linux/smsc911x.h3
-rw-r--r--include/linux/socket.h3
-rw-r--r--include/linux/sockios.h3
-rw-r--r--include/linux/sonypi.h8
-rw-r--r--include/linux/spi/eeprom.h6
-rw-r--r--include/linux/spi/libertas_spi.h32
-rw-r--r--include/linux/spi/spi_gpio.h6
-rw-r--r--include/linux/spinlock.h6
-rw-r--r--include/linux/ssb/ssb.h4
-rw-r--r--include/linux/ssb/ssb_driver_chipcommon.h224
-rw-r--r--include/linux/ssb/ssb_regs.h36
-rw-r--r--include/linux/string.h10
-rw-r--r--include/linux/sunrpc/svc.h25
-rw-r--r--include/linux/sunrpc/svc_xprt.h52
-rw-r--r--include/linux/sunrpc/xdr.h42
-rw-r--r--include/linux/sunrpc/xprt.h2
-rw-r--r--include/linux/suspend.h3
-rw-r--r--include/linux/suspend_ioctls.h11
-rw-r--r--include/linux/swap.h7
-rw-r--r--include/linux/swiotlb.h41
-rw-r--r--include/linux/synclink.h1
-rw-r--r--include/linux/syscalls.h4
-rw-r--r--include/linux/sysctl.h1
-rw-r--r--include/linux/tcp.h23
-rw-r--r--include/linux/thermal.h48
-rw-r--r--include/linux/time.h8
-rw-r--r--include/linux/timecompare.h125
-rw-r--r--include/linux/timer.h22
-rw-r--r--include/linux/timeriomem-rng.h21
-rw-r--r--include/linux/times.h8
-rw-r--r--include/linux/timex.h2
-rw-r--r--include/linux/topology.h11
-rw-r--r--include/linux/tpm.h35
-rw-r--r--include/linux/tracehook.h15
-rw-r--r--include/linux/tty_driver.h3
-rw-r--r--include/linux/types.h13
-rw-r--r--include/linux/uio_driver.h4
-rw-r--r--include/linux/usb.h184
-rw-r--r--include/linux/usb/ch9.h183
-rw-r--r--include/linux/usb/composite.h8
-rw-r--r--include/linux/usb/gadget.h6
-rw-r--r--include/linux/usb/otg.h8
-rw-r--r--include/linux/usb/quirks.h3
-rw-r--r--include/linux/usb/rndis_host.h85
-rw-r--r--include/linux/usb/serial.h3
-rw-r--r--include/linux/usb/usbnet.h5
-rw-r--r--include/linux/usb/wusb.h3
-rw-r--r--include/linux/usb_usual.h21
-rw-r--r--include/linux/utime.h4
-rw-r--r--include/linux/video_decoder.h48
-rw-r--r--include/linux/video_encoder.h23
-rw-r--r--include/linux/videodev.h18
-rw-r--r--include/linux/videodev2.h69
-rw-r--r--include/linux/virtio_net.h71
-rw-r--r--include/linux/wait.h29
-rw-r--r--include/linux/wimax/debug.h2
-rw-r--r--include/linux/wimax/i2400m.h69
-rw-r--r--include/linux/wireless.h12
-rw-r--r--include/linux/workqueue.h5
-rw-r--r--include/linux/writeback.h4
-rw-r--r--include/linux/xfrm.h2
-rw-r--r--include/media/bt819.h33
-rw-r--r--include/media/cx2341x.h6
-rw-r--r--include/media/cx25840.h12
-rw-r--r--include/media/ir-common.h3
-rw-r--r--include/media/ir-kbd-i2c.h3
-rw-r--r--include/media/ov772x.h5
-rw-r--r--include/media/saa7146.h8
-rw-r--r--include/media/saa7146_vv.h17
-rw-r--r--include/media/sh_mobile_ceu.h5
-rw-r--r--include/media/soc_camera.h24
-rw-r--r--include/media/v4l2-chip-ident.h94
-rw-r--r--include/media/v4l2-common.h24
-rw-r--r--include/media/v4l2-dev.h2
-rw-r--r--include/media/v4l2-device.h40
-rw-r--r--include/media/v4l2-ioctl.h2
-rw-r--r--include/media/v4l2-subdev.h22
-rw-r--r--include/media/videobuf-core.h1
-rw-r--r--include/mtd/inftl-user.h36
-rw-r--r--include/mtd/jffs2-user.h5
-rw-r--r--include/mtd/mtd-abi.h70
-rw-r--r--include/mtd/nftl-user.h32
-rw-r--r--include/mtd/ubi-user.h72
-rw-r--r--include/net/addrconf.h4
-rw-r--r--include/net/atmclip.h1
-rw-r--r--include/net/ax88796.h13
-rw-r--r--include/net/bluetooth/bluetooth.h12
-rw-r--r--include/net/bluetooth/hci.h8
-rw-r--r--include/net/bluetooth/hci_core.h84
-rw-r--r--include/net/bluetooth/l2cap.h13
-rw-r--r--include/net/bluetooth/rfcomm.h20
-rw-r--r--include/net/cfg80211.h417
-rw-r--r--include/net/cipso_ipv4.h17
-rw-r--r--include/net/dsa.h42
-rw-r--r--include/net/ethoc.h22
-rw-r--r--include/net/ieee80211_radiotap.h4
-rw-r--r--include/net/if_inet6.h5
-rw-r--r--include/net/inet_ecn.h4
-rw-r--r--include/net/inet_frag.h3
-rw-r--r--include/net/inet_hashtables.h4
-rw-r--r--include/net/ip.h1
-rw-r--r--include/net/ip_vs.h4
-rw-r--r--include/net/ipv6.h4
-rw-r--r--include/net/ipx.h2
-rw-r--r--include/net/mac80211.h342
-rw-r--r--include/net/netfilter/nf_conntrack.h16
-rw-r--r--include/net/netfilter/nf_conntrack_core.h3
-rw-r--r--include/net/netfilter/nf_conntrack_helper.h2
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h7
-rw-r--r--include/net/netfilter/nf_conntrack_l4proto.h17
-rw-r--r--include/net/netfilter/nf_conntrack_tuple.h6
-rw-r--r--include/net/netfilter/nf_log.h11
-rw-r--r--include/net/netlabel.h17
-rw-r--r--include/net/netlink.h1
-rw-r--r--include/net/netns/conntrack.h5
-rw-r--r--include/net/netns/ipv4.h13
-rw-r--r--include/net/netrom.h4
-rw-r--r--include/net/phonet/phonet.h1
-rw-r--r--include/net/phonet/pn_dev.h5
-rw-r--r--include/net/pkt_sched.h1
-rw-r--r--include/net/psnap.h6
-rw-r--r--include/net/sch_generic.h28
-rw-r--r--include/net/sctp/checksum.h14
-rw-r--r--include/net/sctp/command.h3
-rw-r--r--include/net/sctp/sctp.h9
-rw-r--r--include/net/sctp/structs.h7
-rw-r--r--include/net/sock.h49
-rw-r--r--include/net/tcp.h52
-rw-r--r--include/net/transp_v6.h2
-rw-r--r--include/net/udp.h2
-rw-r--r--include/net/wireless.h86
-rw-r--r--include/rdma/ib_cm.h12
-rw-r--r--include/rdma/ib_mad.h4
-rw-r--r--include/rdma/ib_smi.h34
-rw-r--r--include/rdma/ib_verbs.h2
-rw-r--r--include/scsi/fc/fc_fcoe.h7
-rw-r--r--include/scsi/fc/fc_fip.h237
-rw-r--r--include/scsi/fc_frame.h19
-rw-r--r--include/scsi/fc_transport_fcoe.h54
-rw-r--r--include/scsi/libfc.h76
-rw-r--r--include/scsi/libfcoe.h245
-rw-r--r--include/scsi/libiscsi.h19
-rw-r--r--include/scsi/osd_attributes.h327
-rw-r--r--include/scsi/osd_initiator.h433
-rw-r--r--include/scsi/osd_protocol.h579
-rw-r--r--include/scsi/osd_sec.h45
-rw-r--r--include/scsi/osd_sense.h260
-rw-r--r--include/scsi/osd_types.h40
-rw-r--r--include/scsi/scsi.h31
-rw-r--r--include/scsi/scsi_cmnd.h15
-rw-r--r--include/scsi/scsi_device.h10
-rw-r--r--include/scsi/scsi_transport_iscsi.h4
-rw-r--r--include/sound/ad1816a.h2
-rw-r--r--include/sound/asound.h194
-rw-r--r--include/sound/atmel-abdac.h23
-rw-r--r--include/sound/atmel-ac97c.h40
-rw-r--r--include/sound/control.h52
-rw-r--r--include/sound/core.h36
-rw-r--r--include/sound/emu10k1.h11
-rw-r--r--include/sound/hwdep.h38
-rw-r--r--include/sound/jack.h5
-rw-r--r--include/sound/pcm.h3
-rw-r--r--include/sound/pxa2xx-lib.h15
-rw-r--r--include/sound/rawmidi.h1
-rw-r--r--include/sound/sb.h4
-rw-r--r--include/sound/sfnt_info.h14
-rw-r--r--include/sound/soc-dai.h2
-rw-r--r--include/sound/soc-dapm.h31
-rw-r--r--include/sound/soc.h69
-rw-r--r--include/sound/tea575x-tuner.h8
-rw-r--r--include/sound/uda1341.h126
-rw-r--r--include/sound/version.h2
-rw-r--r--include/sound/wss.h1
-rw-r--r--include/trace/kmemtrace.h92
-rw-r--r--include/trace/skb.h11
-rw-r--r--include/video/aty128.h2
-rw-r--r--include/video/broadsheetfb.h59
-rw-r--r--include/video/cirrus.h2
-rw-r--r--include/video/newport.h4
-rw-r--r--include/video/radeon.h564
-rw-r--r--include/video/s1d13xxxfb.h16
-rw-r--r--init/Kconfig27
-rw-r--r--init/do_mounts.c1
-rw-r--r--init/do_mounts.h1
-rw-r--r--init/do_mounts_md.c5
-rw-r--r--init/initramfs.c78
-rw-r--r--init/main.c9
-rw-r--r--ipc/ipc_sysctl.c2
-rw-r--r--ipc/mqueue.c4
-rw-r--r--ipc/shm.c9
-rw-r--r--kernel/Makefile1
-rw-r--r--kernel/async.c18
-rw-r--r--kernel/audit.c9
-rw-r--r--kernel/audit_tree.c2
-rw-r--r--kernel/auditfilter.c16
-rw-r--r--kernel/auditsc.c34
-rw-r--r--kernel/cgroup.c435
-rw-r--r--kernel/cgroup_debug.c2
-rw-r--r--kernel/cpu.c6
-rw-r--r--kernel/cpuset.c254
-rw-r--r--kernel/exec_domain.c23
-rw-r--r--kernel/exit.c248
-rw-r--r--kernel/extable.c30
-rw-r--r--kernel/fork.c72
-rw-r--r--kernel/futex.c201
-rw-r--r--kernel/hrtimer.c55
-rw-r--r--kernel/irq/Makefile1
-rw-r--r--kernel/irq/chip.c7
-rw-r--r--kernel/irq/handle.c36
-rw-r--r--kernel/irq/internals.h3
-rw-r--r--kernel/irq/manage.c223
-rw-r--r--kernel/irq/numa_migrate.c11
-rw-r--r--kernel/irq/pm.c79
-rw-r--r--kernel/irq/spurious.c14
-rw-r--r--kernel/kallsyms.c19
-rw-r--r--kernel/kexec.c22
-rw-r--r--kernel/kmod.c12
-rw-r--r--kernel/kthread.c4
-rw-r--r--kernel/latencytop.c83
-rw-r--r--kernel/lockdep.c26
-rw-r--r--kernel/module.c299
-rw-r--r--kernel/ns_cgroup.c14
-rw-r--r--kernel/panic.c115
-rw-r--r--kernel/params.c26
-rw-r--r--kernel/pid.c33
-rw-r--r--kernel/pid_namespace.c15
-rw-r--r--kernel/posix-cpu-timers.c3
-rw-r--r--kernel/power/disk.c143
-rw-r--r--kernel/power/main.c55
-rw-r--r--kernel/power/snapshot.c9
-rw-r--r--kernel/power/swsusp.c18
-rw-r--r--kernel/printk.c26
-rw-r--r--kernel/ptrace.c103
-rw-r--r--kernel/rcuclassic.c23
-rw-r--r--kernel/rcupdate.c44
-rw-r--r--kernel/rcupreempt.c48
-rw-r--r--kernel/rcutorture.c25
-rw-r--r--kernel/rcutree.c20
-rw-r--r--kernel/rcutree.h10
-rw-r--r--kernel/rcutree_trace.c2
-rw-r--r--kernel/relay.c10
-rw-r--r--kernel/sched.c1063
-rw-r--r--kernel/sched_clock.c31
-rw-r--r--kernel/sched_cpupri.h2
-rw-r--r--kernel/sched_debug.c8
-rw-r--r--kernel/sched_fair.c59
-rw-r--r--kernel/sched_features.h3
-rw-r--r--kernel/sched_rt.c537
-rw-r--r--kernel/sched_stats.h7
-rw-r--r--kernel/signal.c71
-rw-r--r--kernel/slow-work.c640
-rw-r--r--kernel/smp.c432
-rw-r--r--kernel/softirq.c4
-rw-r--r--kernel/spinlock.c18
-rw-r--r--kernel/stop_machine.c2
-rw-r--r--kernel/sys.c5
-rw-r--r--kernel/sysctl.c28
-rw-r--r--kernel/sysctl_check.c1
-rw-r--r--kernel/time/Makefile2
-rw-r--r--kernel/time/clockevents.c20
-rw-r--r--kernel/time/clocksource.c76
-rw-r--r--kernel/time/ntp.c444
-rw-r--r--kernel/time/timecompare.c191
-rw-r--r--kernel/timer.c110
-rw-r--r--kernel/trace/Kconfig9
-rw-r--r--kernel/trace/Makefile1
-rw-r--r--kernel/trace/blktrace.c473
-rw-r--r--kernel/trace/ftrace.c13
-rw-r--r--kernel/trace/kmemtrace.c319
-rw-r--r--kernel/trace/ring_buffer.c118
-rw-r--r--kernel/trace/trace.c42
-rw-r--r--kernel/trace/trace.h82
-rw-r--r--kernel/trace/trace_events.c203
-rw-r--r--kernel/trace/trace_events_filter.c427
-rw-r--r--kernel/trace/trace_events_stage_2.h45
-rw-r--r--kernel/trace/trace_events_stage_3.h9
-rw-r--r--kernel/trace/trace_nop.c1
-rw-r--r--kernel/trace/trace_output.c19
-rw-r--r--kernel/trace/trace_output.h33
-rw-r--r--kernel/trace/trace_stat.c26
-rw-r--r--kernel/trace/trace_workqueue.c12
-rw-r--r--kernel/user.c2
-rw-r--r--kernel/utsname_sysctl.c2
-rw-r--r--kernel/workqueue.c47
-rw-r--r--lib/Kconfig12
-rw-r--r--lib/Kconfig.debug86
-rw-r--r--lib/Makefile9
-rw-r--r--lib/cpumask.c4
-rw-r--r--lib/debugobjects.c127
-rw-r--r--lib/decompress_bunzip2.c1
-rw-r--r--lib/decompress_inflate.c1
-rw-r--r--lib/decompress_unlzma.c1
-rw-r--r--lib/dma-debug.c955
-rw-r--r--lib/dynamic_debug.c769
-rw-r--r--lib/dynamic_printk.c414
-rw-r--r--lib/idr.c46
-rw-r--r--lib/kernel_lock.c2
-rw-r--r--lib/kobject.c2
-rw-r--r--lib/kobject_uevent.c12
-rw-r--r--lib/lmb.c42
-rw-r--r--lib/nlattr.c (renamed from net/netlink/attr.c)47
-rw-r--r--lib/rbtree.c14
-rw-r--r--lib/swiotlb.c88
-rw-r--r--lib/vsprintf.c14
-rw-r--r--mm/Kconfig9
-rw-r--r--mm/Kconfig.debug26
-rw-r--r--mm/Makefile1
-rw-r--r--mm/allocpercpu.c6
-rw-r--r--mm/backing-dev.c36
-rw-r--r--mm/debug-pagealloc.c129
-rw-r--r--mm/failslab.c1
-rw-r--r--mm/filemap.c23
-rw-r--r--mm/filemap_xip.c4
-rw-r--r--mm/highmem.c110
-rw-r--r--mm/hugetlb.c6
-rw-r--r--mm/internal.h8
-rw-r--r--mm/memcontrol.c687
-rw-r--r--mm/memory.c41
-rw-r--r--mm/migrate.c10
-rw-r--r--mm/mmap.c7
-rw-r--r--mm/nommu.c52
-rw-r--r--mm/oom_kill.c13
-rw-r--r--mm/page-writeback.c46
-rw-r--r--mm/page_alloc.c37
-rw-r--r--mm/page_cgroup.c37
-rw-r--r--mm/pdflush.c2
-rw-r--r--mm/percpu.c130
-rw-r--r--mm/quicklist.c2
-rw-r--r--mm/readahead.c65
-rw-r--r--mm/shmem.c5
-rw-r--r--mm/slab.c31
-rw-r--r--mm/slob.c75
-rw-r--r--mm/slub.c98
-rw-r--r--mm/sparse.c4
-rw-r--r--mm/swap.c27
-rw-r--r--mm/truncate.c10
-rw-r--r--mm/util.c46
-rw-r--r--mm/vmalloc.c19
-rw-r--r--mm/vmscan.c113
-rw-r--r--mm/vmstat.c18
-rw-r--r--net/802/psnap.c15
-rw-r--r--net/802/tr.c2
-rw-r--r--net/8021q/vlan.c4
-rw-r--r--net/8021q/vlan_core.c53
-rw-r--r--net/9p/trans_fd.c2
-rw-r--r--net/Kconfig20
-rw-r--r--net/Makefile1
-rw-r--r--net/appletalk/atalk_proc.c1
-rw-r--r--net/appletalk/ddp.c16
-rw-r--r--net/appletalk/dev.c10
-rw-r--r--net/atm/br2684.c58
-rw-r--r--net/atm/clip.c39
-rw-r--r--net/atm/lec.c66
-rw-r--r--net/atm/lec.h1
-rw-r--r--net/atm/mpc.c32
-rw-r--r--net/atm/mpc.h5
-rw-r--r--net/atm/mpoa_proc.c1
-rw-r--r--net/atm/proc.c1
-rw-r--r--net/ax25/af_ax25.c9
-rw-r--r--net/ax25/ax25_iface.c13
-rw-r--r--net/bluetooth/af_bluetooth.c17
-rw-r--r--net/bluetooth/cmtp/core.c3
-rw-r--r--net/bluetooth/hci_conn.c64
-rw-r--r--net/bluetooth/hci_core.c3
-rw-r--r--net/bluetooth/hci_event.c26
-rw-r--r--net/bluetooth/hci_sysfs.c2
-rw-r--r--net/bluetooth/l2cap.c602
-rw-r--r--net/bluetooth/rfcomm/core.c179
-rw-r--r--net/bluetooth/rfcomm/sock.c189
-rw-r--r--net/bluetooth/rfcomm/tty.c11
-rw-r--r--net/bluetooth/sco.c57
-rw-r--r--net/bridge/br_if.c1
-rw-r--r--net/bridge/br_netfilter.c2
-rw-r--r--net/bridge/br_netlink.c3
-rw-r--r--net/bridge/netfilter/ebt_log.c2
-rw-r--r--net/bridge/netfilter/ebt_ulog.c14
-rw-r--r--net/bridge/netfilter/ebtable_broute.c1
-rw-r--r--net/bridge/netfilter/ebtable_filter.c1
-rw-r--r--net/bridge/netfilter/ebtable_nat.c1
-rw-r--r--net/can/af_can.c5
-rw-r--r--net/can/bcm.c4
-rw-r--r--net/can/proc.c2
-rw-r--r--net/can/raw.c3
-rw-r--r--net/compat.c19
-rw-r--r--net/core/Makefile3
-rw-r--r--net/core/datagram.c2
-rw-r--r--net/core/dev.c269
-rw-r--r--net/core/drop_monitor.c263
-rw-r--r--net/core/ethtool.c57
-rw-r--r--net/core/fib_rules.c3
-rw-r--r--net/core/neighbour.c15
-rw-r--r--net/core/net-sysfs.c2
-rw-r--r--net/core/net-traces.c29
-rw-r--r--net/core/netpoll.c31
-rw-r--r--net/core/pktgen.c19
-rw-r--r--net/core/rtnetlink.c9
-rw-r--r--net/core/skbuff.c237
-rw-r--r--net/core/sock.c103
-rw-r--r--net/core/sysctl_net_core.c1
-rw-r--r--net/core/utils.c1
-rw-r--r--net/dccp/ackvec.h3
-rw-r--r--net/dccp/dccp.h26
-rw-r--r--net/dccp/feat.c232
-rw-r--r--net/dccp/feat.h21
-rw-r--r--net/dccp/minisocks.c11
-rw-r--r--net/dccp/options.c8
-rw-r--r--net/dccp/output.c37
-rw-r--r--net/dccp/proto.c2
-rw-r--r--net/dccp/sysctl.c43
-rw-r--r--net/decnet/af_decnet.c25
-rw-r--r--net/decnet/dn_dev.c6
-rw-r--r--net/decnet/dn_route.c8
-rw-r--r--net/decnet/dn_table.c3
-rw-r--r--net/decnet/sysctl_net_decnet.c2
-rw-r--r--net/dsa/Kconfig6
-rw-r--r--net/dsa/dsa.c177
-rw-r--r--net/dsa/dsa_priv.h97
-rw-r--r--net/dsa/mv88e6060.c12
-rw-r--r--net/dsa/mv88e6123_61_65.c92
-rw-r--r--net/dsa/mv88e6131.c98
-rw-r--r--net/dsa/slave.c34
-rw-r--r--net/dsa/tag_dsa.c34
-rw-r--r--net/dsa/tag_edsa.c34
-rw-r--r--net/dsa/tag_trailer.c14
-rw-r--r--net/econet/af_econet.c4
-rw-r--r--net/ipv4/Kconfig52
-rw-r--r--net/ipv4/af_inet.c28
-rw-r--r--net/ipv4/arp.c13
-rw-r--r--net/ipv4/cipso_ipv4.c130
-rw-r--r--net/ipv4/devinet.c12
-rw-r--r--net/ipv4/fib_frontend.c2
-rw-r--r--net/ipv4/fib_semantics.c5
-rw-r--r--net/ipv4/icmp.c2
-rw-r--r--net/ipv4/inet_connection_sock.c42
-rw-r--r--net/ipv4/inet_fragment.c1
-rw-r--r--net/ipv4/inet_hashtables.c12
-rw-r--r--net/ipv4/ip_fragment.c3
-rw-r--r--net/ipv4/ip_gre.c136
-rw-r--r--net/ipv4/ip_output.c6
-rw-r--r--net/ipv4/ipconfig.c8
-rw-r--r--net/ipv4/ipip.c7
-rw-r--r--net/ipv4/ipmr.c464
-rw-r--r--net/ipv4/netfilter/Kconfig30
-rw-r--r--net/ipv4/netfilter/Makefile2
-rw-r--r--net/ipv4/netfilter/arp_tables.c155
-rw-r--r--net/ipv4/netfilter/arptable_filter.c2
-rw-r--r--net/ipv4/netfilter/ip_queue.c2
-rw-r--r--net/ipv4/netfilter/ip_tables.c138
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c2
-rw-r--r--net/ipv4/netfilter/ipt_TTL.c97
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c2
-rw-r--r--net/ipv4/netfilter/ipt_ttl.c63
-rw-r--r--net/ipv4/netfilter/iptable_filter.c1
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c1
-rw-r--r--net/ipv4/netfilter/iptable_raw.c1
-rw-r--r--net/ipv4/netfilter/iptable_security.c1
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c10
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c63
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c6
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c1
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c4
-rw-r--r--net/ipv4/proc.c4
-rw-r--r--net/ipv4/raw.c1
-rw-r--r--net/ipv4/route.c15
-rw-r--r--net/ipv4/syncookies.c9
-rw-r--r--net/ipv4/tcp.c90
-rw-r--r--net/ipv4/tcp_bic.c11
-rw-r--r--net/ipv4/tcp_cong.c21
-rw-r--r--net/ipv4/tcp_cubic.c11
-rw-r--r--net/ipv4/tcp_htcp.c3
-rw-r--r--net/ipv4/tcp_input.c198
-rw-r--r--net/ipv4/tcp_ipv4.c18
-rw-r--r--net/ipv4/tcp_minisocks.c9
-rw-r--r--net/ipv4/tcp_output.c153
-rw-r--r--net/ipv4/tcp_probe.c5
-rw-r--r--net/ipv4/tcp_scalable.c10
-rw-r--r--net/ipv4/tcp_timer.c23
-rw-r--r--net/ipv4/tcp_veno.c7
-rw-r--r--net/ipv4/tcp_yeah.c9
-rw-r--r--net/ipv4/udp.c15
-rw-r--r--net/ipv4/xfrm4_policy.c2
-rw-r--r--net/ipv6/Kconfig18
-rw-r--r--net/ipv6/addrconf.c116
-rw-r--r--net/ipv6/af_inet6.c60
-rw-r--r--net/ipv6/ip6_input.c4
-rw-r--r--net/ipv6/ipv6_sockglue.c3
-rw-r--r--net/ipv6/ndisc.c22
-rw-r--r--net/ipv6/netfilter/Kconfig38
-rw-r--r--net/ipv6/netfilter/Makefile2
-rw-r--r--net/ipv6/netfilter/ip6_queue.c1
-rw-r--r--net/ipv6/netfilter/ip6_tables.c137
-rw-r--r--net/ipv6/netfilter/ip6t_HL.c95
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c2
-rw-r--r--net/ipv6/netfilter/ip6t_hl.c68
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c1
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c1
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c1
-rw-r--r--net/ipv6/netfilter/ip6table_security.c1
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c7
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c10
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c8
-rw-r--r--net/ipv6/reassembly.c7
-rw-r--r--net/ipv6/route.c9
-rw-r--r--net/ipv6/sit.c7
-rw-r--r--net/ipv6/tcp_ipv6.c8
-rw-r--r--net/ipv6/udp.c28
-rw-r--r--net/ipv6/xfrm6_policy.c2
-rw-r--r--net/ipv6/xfrm6_state.c2
-rw-r--r--net/ipx/af_ipx.c20
-rw-r--r--net/irda/ircomm/ircomm_tty.c256
-rw-r--r--net/irda/irda_device.c5
-rw-r--r--net/irda/irlan/irlan_eth.c19
-rw-r--r--net/irda/irmod.c4
-rw-r--r--net/irda/irproc.c1
-rw-r--r--net/iucv/af_iucv.c3
-rw-r--r--net/key/af_key.c6
-rw-r--r--net/llc/af_llc.c6
-rw-r--r--net/llc/llc_conn.c3
-rw-r--r--net/llc/llc_core.c8
-rw-r--r--net/llc/llc_proc.c1
-rw-r--r--net/mac80211/Kconfig2
-rw-r--r--net/mac80211/Makefile6
-rw-r--r--net/mac80211/aes_cmac.c135
-rw-r--r--net/mac80211/aes_cmac.h19
-rw-r--r--net/mac80211/agg-rx.c310
-rw-r--r--net/mac80211/agg-tx.c695
-rw-r--r--net/mac80211/cfg.c237
-rw-r--r--net/mac80211/debugfs.c83
-rw-r--r--net/mac80211/debugfs_key.c79
-rw-r--r--net/mac80211/debugfs_key.h10
-rw-r--r--net/mac80211/debugfs_netdev.c48
-rw-r--r--net/mac80211/debugfs_sta.c5
-rw-r--r--net/mac80211/ht.c903
-rw-r--r--net/mac80211/ibss.c908
-rw-r--r--net/mac80211/ieee80211_i.h314
-rw-r--r--net/mac80211/iface.c168
-rw-r--r--net/mac80211/key.c115
-rw-r--r--net/mac80211/key.h16
-rw-r--r--net/mac80211/main.c185
-rw-r--r--net/mac80211/mesh.c15
-rw-r--r--net/mac80211/mesh.h10
-rw-r--r--net/mac80211/mesh_hwmp.c7
-rw-r--r--net/mac80211/mesh_plink.c38
-rw-r--r--net/mac80211/mlme.c2026
-rw-r--r--net/mac80211/pm.c179
-rw-r--r--net/mac80211/rate.c6
-rw-r--r--net/mac80211/rate.h16
-rw-r--r--net/mac80211/rx.c423
-rw-r--r--net/mac80211/scan.c763
-rw-r--r--net/mac80211/spectmgmt.c103
-rw-r--r--net/mac80211/sta_info.c45
-rw-r--r--net/mac80211/sta_info.h16
-rw-r--r--net/mac80211/tx.c675
-rw-r--r--net/mac80211/util.c243
-rw-r--r--net/mac80211/wep.c21
-rw-r--r--net/mac80211/wext.c492
-rw-r--r--net/mac80211/wme.c170
-rw-r--r--net/mac80211/wme.h6
-rw-r--r--net/mac80211/wpa.c180
-rw-r--r--net/mac80211/wpa.h5
-rw-r--r--net/netfilter/Kconfig65
-rw-r--r--net/netfilter/Makefile4
-rw-r--r--net/netfilter/core.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c4
-rw-r--r--net/netfilter/nf_conntrack_amanda.c4
-rw-r--r--net/netfilter/nf_conntrack_core.c141
-rw-r--r--net/netfilter/nf_conntrack_expect.c5
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c8
-rw-r--r--net/netfilter/nf_conntrack_helper.c8
-rw-r--r--net/netfilter/nf_conntrack_irc.c15
-rw-r--r--net/netfilter/nf_conntrack_netbios_ns.c2
-rw-r--r--net/netfilter/nf_conntrack_netlink.c252
-rw-r--r--net/netfilter/nf_conntrack_pptp.c4
-rw-r--r--net/netfilter/nf_conntrack_proto.c37
-rw-r--r--net/netfilter/nf_conntrack_proto_dccp.c154
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c2
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c1
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c10
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c24
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c4
-rw-r--r--net/netfilter/nf_conntrack_proto_udplite.c1
-rw-r--r--net/netfilter/nf_conntrack_standalone.c57
-rw-r--r--net/netfilter/nf_log.c201
-rw-r--r--net/netfilter/nf_tproxy_core.c1
-rw-r--r--net/netfilter/nfnetlink.c6
-rw-r--r--net/netfilter/nfnetlink_log.c18
-rw-r--r--net/netfilter/x_tables.c26
-rw-r--r--net/netfilter/xt_HL.c171
-rw-r--r--net/netfilter/xt_LED.c161
-rw-r--r--net/netfilter/xt_cluster.c171
-rw-r--r--net/netfilter/xt_connlimit.c6
-rw-r--r--net/netfilter/xt_hashlimit.c7
-rw-r--r--net/netfilter/xt_hl.c108
-rw-r--r--net/netfilter/xt_limit.c40
-rw-r--r--net/netfilter/xt_physdev.c20
-rw-r--r--net/netfilter/xt_quota.c31
-rw-r--r--net/netfilter/xt_statistic.c28
-rw-r--r--net/netlabel/netlabel_kapi.c165
-rw-r--r--net/netlink/Makefile2
-rw-r--r--net/netlink/af_netlink.c88
-rw-r--r--net/netrom/af_netrom.c8
-rw-r--r--net/netrom/nr_dev.c26
-rw-r--r--net/packet/af_packet.c5
-rw-r--r--net/phonet/Kconfig2
-rw-r--r--net/phonet/af_phonet.c34
-rw-r--r--net/phonet/pn_dev.c119
-rw-r--r--net/phonet/pn_netlink.c29
-rw-r--r--net/rds/Kconfig14
-rw-r--r--net/rds/Makefile14
-rw-r--r--net/rds/af_rds.c586
-rw-r--r--net/rds/bind.c199
-rw-r--r--net/rds/cong.c404
-rw-r--r--net/rds/connection.c487
-rw-r--r--net/rds/ib.c324
-rw-r--r--net/rds/ib.h371
-rw-r--r--net/rds/ib_cm.c737
-rw-r--r--net/rds/ib_rdma.c640
-rw-r--r--net/rds/ib_recv.c902
-rw-r--r--net/rds/ib_ring.c168
-rw-r--r--net/rds/ib_send.c874
-rw-r--r--net/rds/ib_stats.c95
-rw-r--r--net/rds/ib_sysctl.c137
-rw-r--r--net/rds/info.c241
-rw-r--r--net/rds/info.h30
-rw-r--r--net/rds/iw.c334
-rw-r--r--net/rds/iw.h399
-rw-r--r--net/rds/iw_cm.c760
-rw-r--r--net/rds/iw_rdma.c888
-rw-r--r--net/rds/iw_recv.c902
-rw-r--r--net/rds/iw_ring.c169
-rw-r--r--net/rds/iw_send.c975
-rw-r--r--net/rds/iw_stats.c95
-rw-r--r--net/rds/iw_sysctl.c137
-rw-r--r--net/rds/loop.c188
-rw-r--r--net/rds/loop.h9
-rw-r--r--net/rds/message.c402
-rw-r--r--net/rds/page.c221
-rw-r--r--net/rds/rdma.c679
-rw-r--r--net/rds/rdma.h84
-rw-r--r--net/rds/rdma_transport.c214
-rw-r--r--net/rds/rdma_transport.h28
-rw-r--r--net/rds/rds.h690
-rw-r--r--net/rds/recv.c542
-rw-r--r--net/rds/send.c1003
-rw-r--r--net/rds/stats.c148
-rw-r--r--net/rds/sysctl.c122
-rw-r--r--net/rds/threads.c265
-rw-r--r--net/rds/transport.c117
-rw-r--r--net/rose/af_rose.c7
-rw-r--r--net/rose/rose_dev.c22
-rw-r--r--net/sched/sch_api.c11
-rw-r--r--net/sched/sch_cbq.c7
-rw-r--r--net/sched/sch_drr.c7
-rw-r--r--net/sched/sch_hfsc.c13
-rw-r--r--net/sched/sch_htb.c49
-rw-r--r--net/sched/sch_multiq.c2
-rw-r--r--net/sched/sch_tbf.c9
-rw-r--r--net/sctp/debug.c4
-rw-r--r--net/sctp/endpointola.c3
-rw-r--r--net/sctp/input.c14
-rw-r--r--net/sctp/ipv6.c36
-rw-r--r--net/sctp/output.c21
-rw-r--r--net/sctp/outqueue.c6
-rw-r--r--net/sctp/protocol.c39
-rw-r--r--net/sctp/sm_make_chunk.c37
-rw-r--r--net/sctp/sm_sideeffect.c43
-rw-r--r--net/sctp/sm_statefuns.c6
-rw-r--r--net/sctp/socket.c216
-rw-r--r--net/sctp/transport.c9
-rw-r--r--net/socket.c95
-rw-r--r--net/sunrpc/Kconfig24
-rw-r--r--net/sunrpc/cache.c4
-rw-r--r--net/sunrpc/clnt.c48
-rw-r--r--net/sunrpc/rpc_pipe.c2
-rw-r--r--net/sunrpc/rpcb_clnt.c103
-rw-r--r--net/sunrpc/stats.c10
-rw-r--r--net/sunrpc/svc.c166
-rw-r--r--net/sunrpc/svc_xprt.c158
-rw-r--r--net/sunrpc/svcsock.c75
-rw-r--r--net/sunrpc/xprt.c89
-rw-r--r--net/sunrpc/xprtrdma/rpc_rdma.c26
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_sendto.c8
-rw-r--r--net/sunrpc/xprtsock.c416
-rw-r--r--net/sysctl_net.c2
-rw-r--r--net/tipc/bcast.c4
-rw-r--r--net/tipc/bcast.h2
-rw-r--r--net/tipc/dbg.c2
-rw-r--r--net/tipc/node.c2
-rw-r--r--net/unix/af_unix.c5
-rw-r--r--net/wanrouter/wanmain.c8
-rw-r--r--net/wanrouter/wanproc.c2
-rw-r--r--net/wimax/Kconfig2
-rw-r--r--net/wimax/op-msg.c9
-rw-r--r--net/wimax/stack.c12
-rw-r--r--net/wireless/Kconfig60
-rw-r--r--net/wireless/Makefile3
-rw-r--r--net/wireless/core.c162
-rw-r--r--net/wireless/core.h64
-rw-r--r--net/wireless/lib80211_crypt_ccmp.c2
-rw-r--r--net/wireless/lib80211_crypt_tkip.c4
-rw-r--r--net/wireless/mlme.c46
-rw-r--r--net/wireless/nl80211.c1335
-rw-r--r--net/wireless/nl80211.h31
-rw-r--r--net/wireless/reg.c1255
-rw-r--r--net/wireless/reg.h45
-rw-r--r--net/wireless/scan.c891
-rw-r--r--net/wireless/sysfs.c39
-rw-r--r--net/wireless/util.c2
-rw-r--r--net/wireless/wext-compat.c108
-rw-r--r--net/x25/af_x25.c21
-rw-r--r--net/xfrm/xfrm_state.c2
-rw-r--r--samples/tracepoints/tracepoint-sample.c24
-rw-r--r--scripts/Makefile.lib2
-rw-r--r--scripts/kconfig/conf.c16
-rw-r--r--scripts/kconfig/confdata.c51
-rw-r--r--scripts/mod/file2alias.c12
-rw-r--r--scripts/mod/modpost.c4
-rw-r--r--scripts/package/buildtar4
-rw-r--r--security/Kconfig6
-rw-r--r--security/Makefile6
-rw-r--r--security/capability.c5
-rw-r--r--security/device_cgroup.c21
-rw-r--r--security/inode.c7
-rw-r--r--security/integrity/ima/Kconfig55
-rw-r--r--security/integrity/ima/Makefile9
-rw-r--r--security/integrity/ima/ima.h166
-rw-r--r--security/integrity/ima/ima_api.c190
-rw-r--r--security/integrity/ima/ima_audit.c81
-rw-r--r--security/integrity/ima/ima_crypto.c140
-rw-r--r--security/integrity/ima/ima_fs.c376
-rw-r--r--security/integrity/ima/ima_iint.c204
-rw-r--r--security/integrity/ima/ima_init.c96
-rw-r--r--security/integrity/ima/ima_main.c327
-rw-r--r--security/integrity/ima/ima_policy.c414
-rw-r--r--security/integrity/ima/ima_queue.c140
-rw-r--r--security/keys/internal.h4
-rw-r--r--security/keys/key.c11
-rw-r--r--security/keys/keyctl.c2
-rw-r--r--security/keys/keyring.c3
-rw-r--r--security/keys/permission.c5
-rw-r--r--security/keys/proc.c55
-rw-r--r--security/keys/process_keys.c2
-rw-r--r--security/keys/request_key.c2
-rw-r--r--security/security.c7
-rw-r--r--security/selinux/avc.c169
-rw-r--r--security/selinux/hooks.c515
-rw-r--r--security/selinux/include/av_perm_to_string.h2
-rw-r--r--security/selinux/include/av_permissions.h2
-rw-r--r--security/selinux/include/netlabel.h27
-rw-r--r--security/selinux/include/objsec.h2
-rw-r--r--security/selinux/include/security.h9
-rw-r--r--security/selinux/netlabel.c186
-rw-r--r--security/selinux/nlmsgtab.c2
-rw-r--r--security/selinux/selinuxfs.c70
-rw-r--r--security/selinux/ss/services.c2
-rw-r--r--security/smack/smack.h32
-rw-r--r--security/smack/smack_access.c70
-rw-r--r--security/smack/smack_lsm.c334
-rw-r--r--security/smack/smackfs.c233
-rw-r--r--security/tomoyo/Kconfig11
-rw-r--r--security/tomoyo/Makefile1
-rw-r--r--security/tomoyo/common.c2206
-rw-r--r--security/tomoyo/common.h359
-rw-r--r--security/tomoyo/domain.c878
-rw-r--r--security/tomoyo/file.c1241
-rw-r--r--security/tomoyo/realpath.c483
-rw-r--r--security/tomoyo/realpath.h66
-rw-r--r--security/tomoyo/tomoyo.c294
-rw-r--r--security/tomoyo/tomoyo.h106
-rw-r--r--sound/Kconfig2
-rw-r--r--sound/Makefile2
-rw-r--r--sound/aoa/aoa-gpio.h2
-rw-r--r--sound/aoa/core/alsa.c7
-rw-r--r--sound/aoa/core/gpio-feature.c17
-rw-r--r--sound/aoa/fabrics/layout.c81
-rw-r--r--sound/aoa/soundbus/i2sbus/core.c22
-rw-r--r--sound/arm/Kconfig11
-rw-r--r--sound/arm/Makefile3
-rw-r--r--sound/arm/aaci.c7
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c72
-rw-r--r--sound/arm/pxa2xx-ac97.c9
-rw-r--r--sound/arm/pxa2xx-pcm-lib.c3
-rw-r--r--sound/arm/sa11xx-uda1341.c983
-rw-r--r--sound/atmel/Kconfig19
-rw-r--r--sound/atmel/Makefile5
-rw-r--r--sound/atmel/abdac.c602
-rw-r--r--sound/atmel/ac97c.c932
-rw-r--r--sound/atmel/ac97c.h71
-rw-r--r--sound/core/control.c7
-rw-r--r--sound/core/hwdep.c9
-rw-r--r--sound/core/info.c31
-rw-r--r--sound/core/init.c89
-rw-r--r--sound/core/jack.c45
-rw-r--r--sound/core/misc.c10
-rw-r--r--sound/core/oss/pcm_oss.c51
-rw-r--r--sound/core/oss/pcm_plugin.h4
-rw-r--r--sound/core/pcm.c3
-rw-r--r--sound/core/pcm_lib.c155
-rw-r--r--sound/core/pcm_native.c10
-rw-r--r--sound/core/pcm_timer.c6
-rw-r--r--sound/core/rawmidi.c379
-rw-r--r--sound/core/seq/oss/seq_oss_device.h2
-rw-r--r--sound/core/seq/seq_prioq.c3
-rw-r--r--sound/core/timer.c6
-rw-r--r--sound/core/vmaster.c62
-rw-r--r--sound/drivers/dummy.c8
-rw-r--r--sound/drivers/ml403-ac97cr.c6
-rw-r--r--sound/drivers/mpu401/mpu401.c6
-rw-r--r--sound/drivers/mtpav.c18
-rw-r--r--sound/drivers/mts64.c8
-rw-r--r--sound/drivers/opl3/opl3_lib.c2
-rw-r--r--sound/drivers/opl3/opl3_midi.c30
-rw-r--r--sound/drivers/opl3/opl3_oss.c8
-rw-r--r--sound/drivers/opl3/opl3_synth.c2
-rw-r--r--sound/drivers/pcsp/pcsp.c8
-rw-r--r--sound/drivers/portman2x4.c6
-rw-r--r--sound/drivers/serial-u16550.c24
-rw-r--r--sound/drivers/virmidi.c12
-rw-r--r--sound/drivers/vx/vx_core.c3
-rw-r--r--sound/drivers/vx/vx_hwdep.c12
-rw-r--r--sound/drivers/vx/vx_uer.c2
-rw-r--r--sound/i2c/Makefile2
-rw-r--r--sound/i2c/l3/Makefile8
-rw-r--r--sound/i2c/l3/uda1341.c935
-rw-r--r--sound/i2c/other/tea575x-tuner.c302
-rw-r--r--sound/isa/Kconfig63
-rw-r--r--sound/isa/Makefile2
-rw-r--r--sound/isa/ad1816a/ad1816a.c21
-rw-r--r--sound/isa/ad1816a/ad1816a_lib.c11
-rw-r--r--sound/isa/ad1848/ad1848.c6
-rw-r--r--sound/isa/adlib.c6
-rw-r--r--sound/isa/als100.c7
-rw-r--r--sound/isa/azt2320.c7
-rw-r--r--sound/isa/cmi8330.c94
-rw-r--r--sound/isa/cs423x/Makefile8
-rw-r--r--sound/isa/cs423x/cs4231.c6
-rw-r--r--sound/isa/cs423x/cs4232.c2
-rw-r--r--sound/isa/cs423x/cs4236.c185
-rw-r--r--sound/isa/cs423x/cs4236_lib.c45
-rw-r--r--sound/isa/dt019x.c7
-rw-r--r--sound/isa/es1688/es1688.c29
-rw-r--r--sound/isa/es1688/es1688_lib.c23
-rw-r--r--sound/isa/es18xx.c24
-rw-r--r--sound/isa/gus/gus_dma.c27
-rw-r--r--sound/isa/gus/gus_irq.c6
-rw-r--r--sound/isa/gus/gus_pcm.c26
-rw-r--r--sound/isa/gus/gus_uart.c10
-rw-r--r--sound/isa/gus/gusclassic.c6
-rw-r--r--sound/isa/gus/gusextreme.c6
-rw-r--r--sound/isa/gus/gusmax.c8
-rw-r--r--sound/isa/gus/interwave.c42
-rw-r--r--sound/isa/msnd/Makefile9
-rw-r--r--sound/isa/msnd/msnd.c705
-rw-r--r--sound/isa/msnd/msnd.h308
-rw-r--r--sound/isa/msnd/msnd_classic.c3
-rw-r--r--sound/isa/msnd/msnd_classic.h129
-rw-r--r--sound/isa/msnd/msnd_midi.c180
-rw-r--r--sound/isa/msnd/msnd_pinnacle.c1238
-rw-r--r--sound/isa/msnd/msnd_pinnacle.h181
-rw-r--r--sound/isa/msnd/msnd_pinnacle_mixer.c343
-rw-r--r--sound/isa/opl3sa2.c45
-rw-r--r--sound/isa/opti9xx/miro.c7
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c65
-rw-r--r--sound/isa/sb/es968.c7
-rw-r--r--sound/isa/sb/sb16.c28
-rw-r--r--sound/isa/sb/sb8.c8
-rw-r--r--sound/isa/sb/sb_mixer.c156
-rw-r--r--sound/isa/sc6000.c10
-rw-r--r--sound/isa/sgalaxy.c6
-rw-r--r--sound/isa/sscape.c205
-rw-r--r--sound/isa/wavefront/wavefront.c30
-rw-r--r--sound/isa/wavefront/wavefront_synth.c2
-rw-r--r--sound/isa/wss/wss_lib.c160
-rw-r--r--sound/mips/au1x00.c9
-rw-r--r--sound/mips/hal2.c6
-rw-r--r--sound/mips/sgio2audio.c6
-rw-r--r--sound/oss/ad1848.c4
-rw-r--r--sound/oss/au1550_ac97.c2
-rw-r--r--sound/oss/audio.c2
-rw-r--r--sound/oss/dmabuf.c2
-rw-r--r--sound/oss/dmasound/dmasound_atari.c4
-rw-r--r--sound/oss/pas2_card.c4
-rw-r--r--sound/oss/pss.c14
-rw-r--r--sound/oss/sequencer.c3
-rw-r--r--sound/oss/sh_dac_audio.c2
-rw-r--r--sound/oss/swarm_cs4297a.c2
-rw-r--r--sound/oss/vwsnd.c2
-rw-r--r--sound/parisc/harmony.c6
-rw-r--r--sound/pci/Kconfig25
-rw-r--r--sound/pci/ac97/ac97_codec.c8
-rw-r--r--sound/pci/ac97/ac97_proc.c2
-rw-r--r--sound/pci/ad1889.c6
-rw-r--r--sound/pci/ak4531_codec.c3
-rw-r--r--sound/pci/ali5451/ali5451.c10
-rw-r--r--sound/pci/als300.c8
-rw-r--r--sound/pci/als4000.c9
-rw-r--r--sound/pci/atiixp.c6
-rw-r--r--sound/pci/atiixp_modem.c6
-rw-r--r--sound/pci/au88x0/au88x0.c6
-rw-r--r--sound/pci/au88x0/au88x0_a3d.c7
-rw-r--r--sound/pci/au88x0/au88x0_core.c21
-rw-r--r--sound/pci/au88x0/au88x0_synth.c39
-rw-r--r--sound/pci/aw2/aw2-alsa.c6
-rw-r--r--sound/pci/azt3328.c14
-rw-r--r--sound/pci/bt87x.c6
-rw-r--r--sound/pci/ca0106/ca0106_main.c105
-rw-r--r--sound/pci/cmipci.c6
-rw-r--r--sound/pci/cs4281.c12
-rw-r--r--sound/pci/cs46xx/cs46xx.c6
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c6
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.h6
-rw-r--r--sound/pci/cs5530.c6
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c8
-rw-r--r--sound/pci/echoaudio/Makefile4
-rw-r--r--sound/pci/echoaudio/echo3g_dsp.c2
-rw-r--r--sound/pci/echoaudio/echoaudio.c23
-rw-r--r--sound/pci/echoaudio/echoaudio.h3
-rw-r--r--sound/pci/echoaudio/echoaudio_3g.c3
-rw-r--r--sound/pci/echoaudio/echoaudio_dsp.c6
-rw-r--r--sound/pci/echoaudio/echoaudio_dsp.h9
-rw-r--r--sound/pci/echoaudio/gina20_dsp.c4
-rw-r--r--sound/pci/echoaudio/indigo_dsp.c12
-rw-r--r--sound/pci/echoaudio/indigo_express_dsp.c119
-rw-r--r--sound/pci/echoaudio/indigodj_dsp.c12
-rw-r--r--sound/pci/echoaudio/indigodjx.c107
-rw-r--r--sound/pci/echoaudio/indigodjx_dsp.c68
-rw-r--r--sound/pci/echoaudio/indigoio_dsp.c12
-rw-r--r--sound/pci/echoaudio/indigoiox.c109
-rw-r--r--sound/pci/echoaudio/indigoiox_dsp.c68
-rw-r--r--sound/pci/echoaudio/layla20_dsp.c4
-rw-r--r--sound/pci/echoaudio/mia_dsp.c16
-rw-r--r--sound/pci/echoaudio/midi.c4
-rw-r--r--sound/pci/emu10k1/emu10k1.c6
-rw-r--r--sound/pci/emu10k1/emu10k1_callback.c7
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c11
-rw-r--r--sound/pci/emu10k1/emu10k1x.c6
-rw-r--r--sound/pci/emu10k1/emufx.c11
-rw-r--r--sound/pci/emu10k1/emupcm.c37
-rw-r--r--sound/pci/emu10k1/io.c4
-rw-r--r--sound/pci/emu10k1/p16v.c100
-rw-r--r--sound/pci/emu10k1/voice.c12
-rw-r--r--sound/pci/ens1370.c9
-rw-r--r--sound/pci/es1938.c29
-rw-r--r--sound/pci/es1968.c6
-rw-r--r--sound/pci/fm801.c6
-rw-r--r--sound/pci/hda/hda_beep.c1
-rw-r--r--sound/pci/hda/hda_beep.h2
-rw-r--r--sound/pci/hda/hda_codec.c427
-rw-r--r--sound/pci/hda/hda_codec.h19
-rw-r--r--sound/pci/hda/hda_generic.c4
-rw-r--r--sound/pci/hda/hda_hwdep.c240
-rw-r--r--sound/pci/hda/hda_intel.c121
-rw-r--r--sound/pci/hda/hda_local.h33
-rw-r--r--sound/pci/hda/hda_proc.c21
-rw-r--r--sound/pci/hda/patch_analog.c195
-rw-r--r--sound/pci/hda/patch_cmedia.c12
-rw-r--r--sound/pci/hda/patch_conexant.c368
-rw-r--r--sound/pci/hda/patch_realtek.c1194
-rw-r--r--sound/pci/hda/patch_sigmatel.c1342
-rw-r--r--sound/pci/hda/patch_via.c17
-rw-r--r--sound/pci/ice1712/ice1712.c8
-rw-r--r--sound/pci/ice1712/ice1724.c66
-rw-r--r--sound/pci/ice1712/juli.c5
-rw-r--r--sound/pci/ice1712/prodigy192.c13
-rw-r--r--sound/pci/intel8x0.c85
-rw-r--r--sound/pci/intel8x0m.c20
-rw-r--r--sound/pci/korg1212/korg1212.c6
-rw-r--r--sound/pci/maestro3.c6
-rw-r--r--sound/pci/mixart/mixart.c6
-rw-r--r--sound/pci/mixart/mixart_hwdep.c58
-rw-r--r--sound/pci/nm256/nm256.c6
-rw-r--r--sound/pci/oxygen/hifier.c12
-rw-r--r--sound/pci/oxygen/oxygen.c114
-rw-r--r--sound/pci/oxygen/oxygen.h22
-rw-r--r--sound/pci/oxygen/oxygen_io.c31
-rw-r--r--sound/pci/oxygen/oxygen_lib.c104
-rw-r--r--sound/pci/oxygen/virtuoso.c339
-rw-r--r--sound/pci/pcxhr/pcxhr.c47
-rw-r--r--sound/pci/pcxhr/pcxhr.h5
-rw-r--r--sound/pci/pcxhr/pcxhr_core.h2
-rw-r--r--sound/pci/pcxhr/pcxhr_hwdep.c12
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.c40
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.h3
-rw-r--r--sound/pci/pcxhr/pcxhr_mixer.c8
-rw-r--r--sound/pci/riptide/riptide.c6
-rw-r--r--sound/pci/rme32.c7
-rw-r--r--sound/pci/rme96.c7
-rw-r--r--sound/pci/rme9652/hdsp.c521
-rw-r--r--sound/pci/rme9652/hdspm.c17
-rw-r--r--sound/pci/rme9652/rme9652.c8
-rw-r--r--sound/pci/sis7019.c5
-rw-r--r--sound/pci/sonicvibes.c115
-rw-r--r--sound/pci/trident/trident.c6
-rw-r--r--sound/pci/trident/trident_main.c57
-rw-r--r--sound/pci/via82xx.c29
-rw-r--r--sound/pci/via82xx_modem.c11
-rw-r--r--sound/pci/vx222/vx222.c6
-rw-r--r--sound/pci/vx222/vx222_ops.c8
-rw-r--r--sound/pci/ymfpci/ymfpci.c6
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c14
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c19
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_core.c23
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_irq.c4
-rw-r--r--sound/pcmcia/vx/vxpocket.c32
-rw-r--r--sound/ppc/Kconfig1
-rw-r--r--sound/ppc/awacs.c88
-rw-r--r--sound/ppc/burgundy.c2
-rw-r--r--sound/ppc/daca.c2
-rw-r--r--sound/ppc/pmac.c11
-rw-r--r--sound/ppc/powermac.c8
-rw-r--r--sound/ppc/snd_ps3.c6
-rw-r--r--sound/ppc/tumbler.c13
-rw-r--r--sound/sh/Kconfig1
-rw-r--r--sound/sh/aica.c10
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/atmel/atmel-pcm.c2
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c33
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c24
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c124
-rw-r--r--sound/soc/au1x/dbdma2.c2
-rw-r--r--sound/soc/au1x/psc-ac97.c10
-rw-r--r--sound/soc/au1x/psc-i2s.c12
-rw-r--r--sound/soc/blackfin/Kconfig2
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c2
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c94
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c4
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c2
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c14
-rw-r--r--sound/soc/blackfin/bf5xx-sport.c104
-rw-r--r--sound/soc/codecs/Kconfig23
-rw-r--r--sound/soc/codecs/Makefile7
-rw-r--r--sound/soc/codecs/ac97.c29
-rw-r--r--sound/soc/codecs/ad1980.c33
-rw-r--r--sound/soc/codecs/ad73311.c8
-rw-r--r--sound/soc/codecs/ad73311.h2
-rw-r--r--sound/soc/codecs/ak4104.c365
-rw-r--r--sound/soc/codecs/ak4104.h7
-rw-r--r--sound/soc/codecs/ak4535.c46
-rw-r--r--sound/soc/codecs/cs4270.c667
-rw-r--r--sound/soc/codecs/pcm3008.c12
-rw-r--r--sound/soc/codecs/ssm2602.c58
-rw-r--r--sound/soc/codecs/tlv320aic23.c57
-rw-r--r--sound/soc/codecs/tlv320aic26.c29
-rw-r--r--sound/soc/codecs/tlv320aic3x.c161
-rw-r--r--sound/soc/codecs/twl4030.c524
-rw-r--r--sound/soc/codecs/twl4030.h15
-rw-r--r--sound/soc/codecs/uda134x.c84
-rw-r--r--sound/soc/codecs/uda1380.c241
-rw-r--r--sound/soc/codecs/wm8350.c166
-rw-r--r--sound/soc/codecs/wm8350.h8
-rw-r--r--sound/soc/codecs/wm8400.c1582
-rw-r--r--sound/soc/codecs/wm8400.h62
-rw-r--r--sound/soc/codecs/wm8510.c55
-rw-r--r--sound/soc/codecs/wm8580.c381
-rw-r--r--sound/soc/codecs/wm8580.h5
-rw-r--r--sound/soc/codecs/wm8728.c50
-rw-r--r--sound/soc/codecs/wm8731.c432
-rw-r--r--sound/soc/codecs/wm8731.h6
-rw-r--r--sound/soc/codecs/wm8750.c48
-rw-r--r--sound/soc/codecs/wm8753.c542
-rw-r--r--sound/soc/codecs/wm8753.h6
-rw-r--r--sound/soc/codecs/wm8900.c51
-rw-r--r--sound/soc/codecs/wm8903.c60
-rw-r--r--sound/soc/codecs/wm8971.c46
-rw-r--r--sound/soc/codecs/wm8990.c54
-rw-r--r--sound/soc/codecs/wm9705.c415
-rw-r--r--sound/soc/codecs/wm9705.h14
-rw-r--r--sound/soc/codecs/wm9712.c57
-rw-r--r--sound/soc/codecs/wm9713.c96
-rw-r--r--sound/soc/davinci/Kconfig2
-rw-r--r--sound/soc/davinci/davinci-evm.c3
-rw-r--r--sound/soc/davinci/davinci-i2s.c14
-rw-r--r--sound/soc/davinci/davinci-pcm.c2
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c43
-rw-r--r--sound/soc/fsl/Kconfig17
-rw-r--r--sound/soc/fsl/Makefile7
-rw-r--r--sound/soc/fsl/fsl_dma.c181
-rw-r--r--sound/soc/fsl/fsl_ssi.c98
-rw-r--r--sound/soc/fsl/fsl_ssi.h2
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c20
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c5
-rw-r--r--sound/soc/omap/Kconfig14
-rw-r--r--sound/soc/omap/Makefile2
-rw-r--r--sound/soc/omap/n810.c47
-rw-r--r--sound/soc/omap/omap-mcbsp.c20
-rw-r--r--sound/soc/omap/omap-pcm.c2
-rw-r--r--sound/soc/omap/omap3pandora.c49
-rw-r--r--sound/soc/omap/osk5912.c12
-rw-r--r--sound/soc/omap/sdp3430.c115
-rw-r--r--sound/soc/pxa/Kconfig27
-rw-r--r--sound/soc/pxa/Makefile6
-rw-r--r--sound/soc/pxa/corgi.c60
-rw-r--r--sound/soc/pxa/e740_wm9705.c211
-rw-r--r--sound/soc/pxa/e750_wm9705.c187
-rw-r--r--sound/soc/pxa/e800_wm9712.c115
-rw-r--r--sound/soc/pxa/em-x270.c2
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c250
-rw-r--r--sound/soc/pxa/palm27x.c15
-rw-r--r--sound/soc/pxa/poodle.c58
-rw-r--r--sound/soc/pxa/pxa-ssp.c152
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c61
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c56
-rw-r--r--sound/soc/pxa/spitz.c16
-rw-r--r--sound/soc/pxa/tosa.c16
-rw-r--r--sound/soc/pxa/zylonite.c132
-rw-r--r--sound/soc/s3c24xx/Kconfig29
-rw-r--r--sound/soc/s3c24xx/Makefile6
-rw-r--r--sound/soc/s3c24xx/jive_wm8750.c201
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c67
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c638
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.h90
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c622
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.h17
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c20
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c71
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c49
-rw-r--r--sound/soc/s3c24xx/s3c24xx_uda134x.c2
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c222
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h31
-rw-r--r--sound/soc/sh/hac.c12
-rw-r--r--sound/soc/sh/ssi.c30
-rw-r--r--sound/soc/soc-core.c181
-rw-r--r--sound/soc/soc-dapm.c390
-rw-r--r--sound/soc/soc-jack.c267
-rw-r--r--sound/sparc/amd7930.c12
-rw-r--r--sound/sparc/cs4231.c9
-rw-r--r--sound/sparc/dbri.c8
-rw-r--r--sound/spi/at73c213.c7
-rw-r--r--sound/synth/emux/emux_hwdep.c21
-rw-r--r--sound/synth/emux/emux_oss.c2
-rw-r--r--sound/synth/emux/emux_seq.c16
-rw-r--r--sound/synth/emux/emux_synth.c6
-rw-r--r--sound/synth/emux/soundfont.c28
-rw-r--r--sound/usb/Kconfig3
-rw-r--r--sound/usb/caiaq/caiaq-audio.c15
-rw-r--r--sound/usb/caiaq/caiaq-control.c42
-rw-r--r--sound/usb/caiaq/caiaq-device.c46
-rw-r--r--sound/usb/caiaq/caiaq-device.h6
-rw-r--r--sound/usb/usbaudio.c85
-rw-r--r--sound/usb/usbmixer.c164
-rw-r--r--sound/usb/usbmixer_maps.c26
-rw-r--r--sound/usb/usbquirks.h10
-rw-r--r--sound/usb/usx2y/us122l.c59
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.c15
-rw-r--r--sound/usb/usx2y/usb_stream.c2
-rw-r--r--sound/usb/usx2y/usbusx2y.c56
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.h2
-rw-r--r--usr/Kconfig43
-rw-r--r--usr/Makefile3
-rw-r--r--virt/kvm/ioapic.c39
-rw-r--r--virt/kvm/ioapic.h2
-rw-r--r--virt/kvm/irq_comm.c297
-rw-r--r--virt/kvm/kvm_main.c141
7641 files changed, 853211 insertions, 304520 deletions
diff --git a/CREDITS b/CREDITS
index 5e0736722afd..2520ba620ff1 100644
--- a/CREDITS
+++ b/CREDITS
@@ -495,6 +495,11 @@ S: Kopmansg 2
S: 411 13 Goteborg
S: Sweden
+N: Paul Bristow
+E: paul@paulbristow.net
+W: http://paulbristow.net/linux/idefloppy.html
+D: Maintainer of IDE/ATAPI floppy driver
+
N: Dominik Brodowski
E: linux@brodo.de
W: http://www.brodo.de/
@@ -1407,8 +1412,8 @@ P: 1024D/77D4FC9B F5C5 1C20 1DFC DEC3 3107 54A4 2332 ADFC 77D4 FC9B
D: National Language Support
D: Linux Internationalization Project
D: German Localization for Linux and GNU software
-S: Kriemhildring 12a
-S: 65795 Hattersheim am Main
+S: Auf der Fittel 18
+S: 53347 Alfter
S: Germany
N: Christoph Hellwig
@@ -2642,6 +2647,10 @@ S: C/ Mieses 20, 9-B
S: Valladolid 47009
S: Spain
+N: Gadi Oxman
+E: gadio@netvision.net.il
+D: Original author and maintainer of IDE/ATAPI floppy/tape drivers
+
N: Greg Page
E: gpage@sovereign.org
D: IPX development and support
@@ -3571,6 +3580,12 @@ N: Dirk Verworner
D: Co-author of German book ``Linux-Kernel-Programmierung''
D: Co-founder of Berlin Linux User Group
+N: Riku Voipio
+E: riku.voipio@iki.fi
+D: Author of PCA9532 LED and Fintek f75375s hwmon driver
+D: Some random ARM board patches
+S: Finland
+
N: Patrick Volkerding
E: volkerdi@ftp.cdrom.com
D: Produced the Slackware distribution, updated the SVGAlib
@@ -3738,7 +3753,7 @@ S: 93149 Nittenau
S: Germany
N: Gertjan van Wingerde
-E: gwingerde@home.nl
+E: gwingerde@gmail.com
D: Ralink rt2x00 WLAN driver
D: Minix V2 file-system
D: Misc fixes
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 2a39aeba1464..d05737aaa84b 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -86,6 +86,8 @@ cachetlb.txt
- describes the cache/TLB flushing interfaces Linux uses.
cdrom/
- directory with information on the CD-ROM drivers that Linux has.
+cgroups/
+ - cgroups features, including cpusets and memory controller.
connector/
- docs on the netlink based userspace<->kernel space communication mod.
console/
@@ -98,8 +100,6 @@ cpu-load.txt
- document describing how CPU load statistics are collected.
cpuidle/
- info on CPU_IDLE, CPU idle state management subsystem.
-cpusets.txt
- - documents the cpusets feature; assign CPUs and Mem to a set of tasks.
cputopology.txt
- documentation on how CPU topology info is exported via sysfs.
cris/
diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy
new file mode 100644
index 000000000000..6434f0df012e
--- /dev/null
+++ b/Documentation/ABI/testing/ima_policy
@@ -0,0 +1,61 @@
+What: security/ima/policy
+Date: May 2008
+Contact: Mimi Zohar <zohar@us.ibm.com>
+Description:
+ The Trusted Computing Group(TCG) runtime Integrity
+ Measurement Architecture(IMA) maintains a list of hash
+ values of executables and other sensitive system files
+ loaded into the run-time of this system. At runtime,
+ the policy can be constrained based on LSM specific data.
+ Policies are loaded into the securityfs file ima/policy
+ by opening the file, writing the rules one at a time and
+ then closing the file. The new policy takes effect after
+ the file ima/policy is closed.
+
+ rule format: action [condition ...]
+
+ action: measure | dont_measure
+ condition:= base | lsm
+ base: [[func=] [mask=] [fsmagic=] [uid=]]
+ lsm: [[subj_user=] [subj_role=] [subj_type=]
+ [obj_user=] [obj_role=] [obj_type=]]
+
+ base: func:= [BPRM_CHECK][FILE_MMAP][INODE_PERMISSION]
+ mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
+ fsmagic:= hex value
+ uid:= decimal value
+ lsm: are LSM specific
+
+ default policy:
+ # PROC_SUPER_MAGIC
+ dont_measure fsmagic=0x9fa0
+ # SYSFS_MAGIC
+ dont_measure fsmagic=0x62656572
+ # DEBUGFS_MAGIC
+ dont_measure fsmagic=0x64626720
+ # TMPFS_MAGIC
+ dont_measure fsmagic=0x01021994
+ # SECURITYFS_MAGIC
+ dont_measure fsmagic=0x73636673
+
+ measure func=BPRM_CHECK
+ measure func=FILE_MMAP mask=MAY_EXEC
+ measure func=INODE_PERM mask=MAY_READ uid=0
+
+ The default policy measures all executables in bprm_check,
+ all files mmapped executable in file_mmap, and all files
+ open for read by root in inode_permission.
+
+ Examples of LSM specific definitions:
+
+ SELinux:
+ # SELINUX_MAGIC
+ dont_measure fsmagic=0xF97CFF8C
+
+ dont_measure obj_type=var_log_t
+ dont_measure obj_type=auditd_log_t
+ measure subj_user=system_u func=INODE_PERM mask=MAY_READ
+ measure subj_role=system_r func=INODE_PERM mask=MAY_READ
+
+ Smack:
+ measure subj_user=_ func=INODE_PERM mask=MAY_READ
diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci
index e638e15a8895..97ad190e13af 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci
+++ b/Documentation/ABI/testing/sysfs-bus-pci
@@ -41,6 +41,49 @@ Description:
for the device and attempt to bind to it. For example:
# echo "8086 10f5" > /sys/bus/pci/drivers/foo/new_id
+What: /sys/bus/pci/drivers/.../remove_id
+Date: February 2009
+Contact: Chris Wright <chrisw@sous-sol.org>
+Description:
+ Writing a device ID to this file will remove an ID
+ that was dynamically added via the new_id sysfs entry.
+ The format for the device ID is:
+ VVVV DDDD SVVV SDDD CCCC MMMM. That is Vendor ID, Device
+ ID, Subsystem Vendor ID, Subsystem Device ID, Class,
+ and Class Mask. The Vendor ID and Device ID fields are
+ required, the rest are optional. After successfully
+ removing an ID, the driver will no longer support the
+ device. This is useful to ensure auto probing won't
+ match the driver to the device. For example:
+ # echo "8086 10f5" > /sys/bus/pci/drivers/foo/remove_id
+
+What: /sys/bus/pci/rescan
+Date: January 2009
+Contact: Linux PCI developers <linux-pci@vger.kernel.org>
+Description:
+ Writing a non-zero value to this attribute will
+ force a rescan of all PCI buses in the system, and
+ re-discover previously removed devices.
+ Depends on CONFIG_HOTPLUG.
+
+What: /sys/bus/pci/devices/.../remove
+Date: January 2009
+Contact: Linux PCI developers <linux-pci@vger.kernel.org>
+Description:
+ Writing a non-zero value to this attribute will
+ hot-remove the PCI device and any of its children.
+ Depends on CONFIG_HOTPLUG.
+
+What: /sys/bus/pci/devices/.../rescan
+Date: January 2009
+Contact: Linux PCI developers <linux-pci@vger.kernel.org>
+Description:
+ Writing a non-zero value to this attribute will
+ force a rescan of the device's parent bus and all
+ child buses, and re-discover devices removed earlier
+ from this part of the device tree.
+ Depends on CONFIG_HOTPLUG.
+
What: /sys/bus/pci/devices/.../vpd
Date: February 2008
Contact: Ben Hutchings <bhutchings@solarflare.com>
@@ -52,3 +95,30 @@ Description:
that some devices may have malformatted data. If the
underlying VPD has a writable section then the
corresponding section of this file will be writable.
+
+What: /sys/bus/pci/devices/.../virtfnN
+Date: March 2009
+Contact: Yu Zhao <yu.zhao@intel.com>
+Description:
+ This symbolic link appears when hardware supports the SR-IOV
+ capability and the Physical Function driver has enabled it.
+ The symbolic link points to the PCI device sysfs entry of the
+ Virtual Function whose index is N (0...MaxVFs-1).
+
+What: /sys/bus/pci/devices/.../dep_link
+Date: March 2009
+Contact: Yu Zhao <yu.zhao@intel.com>
+Description:
+ This symbolic link appears when hardware supports the SR-IOV
+ capability and the Physical Function driver has enabled it,
+ and this device has vendor specific dependencies with others.
+ The symbolic link points to the PCI device sysfs entry of
+ Physical Function this device depends on.
+
+What: /sys/bus/pci/devices/.../physfn
+Date: March 2009
+Contact: Yu Zhao <yu.zhao@intel.com>
+Description:
+ This symbolic link appears when a device is a Virtual Function.
+ The symbolic link points to the PCI device sysfs entry of the
+ Physical Function this device associates with.
diff --git a/Documentation/ABI/testing/sysfs-class-regulator b/Documentation/ABI/testing/sysfs-class-regulator
index 873ef1fc1569..e091fa873792 100644
--- a/Documentation/ABI/testing/sysfs-class-regulator
+++ b/Documentation/ABI/testing/sysfs-class-regulator
@@ -4,8 +4,8 @@ KernelVersion: 2.6.26
Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description:
Some regulator directories will contain a field called
- state. This reports the regulator enable status, for
- regulators which can report that value.
+ state. This reports the regulator enable control, for
+ regulators which can report that input value.
This will be one of the following strings:
@@ -14,16 +14,54 @@ Description:
'unknown'
'enabled' means the regulator output is ON and is supplying
- power to the system.
+ power to the system (assuming no error prevents it).
'disabled' means the regulator output is OFF and is not
- supplying power to the system..
+ supplying power to the system (unless some non-Linux
+ control has enabled it).
'unknown' means software cannot determine the state, or
the reported state is invalid.
NOTE: this field can be used in conjunction with microvolts
- and microamps to determine regulator output levels.
+ or microamps to determine configured regulator output levels.
+
+
+What: /sys/class/regulator/.../status
+Description:
+ Some regulator directories will contain a field called
+ "status". This reports the current regulator status, for
+ regulators which can report that output value.
+
+ This will be one of the following strings:
+
+ off
+ on
+ error
+ fast
+ normal
+ idle
+ standby
+
+ "off" means the regulator is not supplying power to the
+ system.
+
+ "on" means the regulator is supplying power to the system,
+ and the regulator can't report a detailed operation mode.
+
+ "error" indicates an out-of-regulation status such as being
+ disabled due to thermal shutdown, or voltage being unstable
+ because of problems with the input power supply.
+
+ "fast", "normal", "idle", and "standby" are all detailed
+ regulator operation modes (described elsewhere). They
+ imply "on", but provide more detail.
+
+ Note that regulator status is a function of many inputs,
+ not limited to control inputs from Linux. For example,
+ the actual load presented may trigger "error" status; or
+ a regulator may be enabled by another user, even though
+ Linux did not enable it.
What: /sys/class/regulator/.../type
@@ -58,7 +96,7 @@ Description:
Some regulator directories will contain a field called
microvolts. This holds the regulator output voltage setting
measured in microvolts (i.e. E-6 Volts), for regulators
- which can report that voltage.
+ which can report the control input for voltage.
NOTE: This value should not be used to determine the regulator
output voltage level as this value is the same regardless of
@@ -73,7 +111,7 @@ Description:
Some regulator directories will contain a field called
microamps. This holds the regulator output current limit
setting measured in microamps (i.e. E-6 Amps), for regulators
- which can report that current.
+ which can report the control input for a current limit.
NOTE: This value should not be used to determine the regulator
output current level as this value is the same regardless of
@@ -87,7 +125,7 @@ Contact: Liam Girdwood <lrg@slimlogic.co.uk>
Description:
Some regulator directories will contain a field called
opmode. This holds the current regulator operating mode,
- for regulators which can report it.
+ for regulators which can report that control input value.
The opmode value can be one of the following strings:
@@ -101,7 +139,8 @@ Description:
NOTE: This value should not be used to determine the regulator
output operating mode as this value is the same regardless of
- whether the regulator is enabled or disabled.
+ whether the regulator is enabled or disabled. A "status"
+ attribute may be available to determine the actual mode.
What: /sys/class/regulator/.../min_microvolts
diff --git a/Documentation/ABI/testing/sysfs-fs-ext4 b/Documentation/ABI/testing/sysfs-fs-ext4
new file mode 100644
index 000000000000..4e79074de282
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-fs-ext4
@@ -0,0 +1,81 @@
+What: /sys/fs/ext4/<disk>/mb_stats
+Date: March 2008
+Contact: "Theodore Ts'o" <tytso@mit.edu>
+Description:
+ Controls whether the multiblock allocator should
+ collect statistics, which are shown during the unmount.
+ 1 means to collect statistics, 0 means not to collect
+ statistics
+
+What: /sys/fs/ext4/<disk>/mb_group_prealloc
+Date: March 2008
+Contact: "Theodore Ts'o" <tytso@mit.edu>
+Description:
+ The multiblock allocator will round up allocation
+ requests to a multiple of this tuning parameter if the
+ stripe size is not set in the ext4 superblock
+
+What: /sys/fs/ext4/<disk>/mb_max_to_scan
+Date: March 2008
+Contact: "Theodore Ts'o" <tytso@mit.edu>
+Description:
+ The maximum number of extents the multiblock allocator
+ will search to find the best extent
+
+What: /sys/fs/ext4/<disk>/mb_min_to_scan
+Date: March 2008
+Contact: "Theodore Ts'o" <tytso@mit.edu>
+Description:
+ The minimum number of extents the multiblock allocator
+ will search to find the best extent
+
+What: /sys/fs/ext4/<disk>/mb_order2_req
+Date: March 2008
+Contact: "Theodore Ts'o" <tytso@mit.edu>
+Description:
+ Tuning parameter which controls the minimum size for
+ requests (as a power of 2) where the buddy cache is
+ used
+
+What: /sys/fs/ext4/<disk>/mb_stream_req
+Date: March 2008
+Contact: "Theodore Ts'o" <tytso@mit.edu>
+Description:
+ Files which have fewer blocks than this tunable
+ parameter will have their blocks allocated out of a
+ block group specific preallocation pool, so that small
+ files are packed closely together. Each large file
+ will have its blocks allocated out of its own unique
+ preallocation pool.
+
+What: /sys/fs/ext4/<disk>/inode_readahead
+Date: March 2008
+Contact: "Theodore Ts'o" <tytso@mit.edu>
+Description:
+ Tuning parameter which controls the maximum number of
+ inode table blocks that ext4's inode table readahead
+ algorithm will pre-read into the buffer cache
+
+What: /sys/fs/ext4/<disk>/delayed_allocation_blocks
+Date: March 2008
+Contact: "Theodore Ts'o" <tytso@mit.edu>
+Description:
+ This file is read-only and shows the number of blocks
+ that are dirty in the page cache, but which do not
+ have their location in the filesystem allocated yet.
+
+What: /sys/fs/ext4/<disk>/lifetime_write_kbytes
+Date: March 2008
+Contact: "Theodore Ts'o" <tytso@mit.edu>
+Description:
+ This file is read-only and shows the number of kilobytes
+ of data that have been written to this filesystem since it was
+ created.
+
+What: /sys/fs/ext4/<disk>/session_write_kbytes
+Date: March 2008
+Contact: "Theodore Ts'o" <tytso@mit.edu>
+Description:
+ This file is read-only and shows the number of
+ kilobytes of data that have been written to this
+ filesystem since it was mounted.
diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt
index 2a3fcc55e981..d9aa43d78bcc 100644
--- a/Documentation/DMA-API.txt
+++ b/Documentation/DMA-API.txt
@@ -609,3 +609,109 @@ size is the size (and should be a page-sized multiple).
The return value will be either a pointer to the processor virtual
address of the memory, or an error (via PTR_ERR()) if any part of the
region is occupied.
+
+Part III - Debug drivers use of the DMA-API
+-------------------------------------------
+
+The DMA-API as described above as some constraints. DMA addresses must be
+released with the corresponding function with the same size for example. With
+the advent of hardware IOMMUs it becomes more and more important that drivers
+do not violate those constraints. In the worst case such a violation can
+result in data corruption up to destroyed filesystems.
+
+To debug drivers and find bugs in the usage of the DMA-API checking code can
+be compiled into the kernel which will tell the developer about those
+violations. If your architecture supports it you can select the "Enable
+debugging of DMA-API usage" option in your kernel configuration. Enabling this
+option has a performance impact. Do not enable it in production kernels.
+
+If you boot the resulting kernel will contain code which does some bookkeeping
+about what DMA memory was allocated for which device. If this code detects an
+error it prints a warning message with some details into your kernel log. An
+example warning message may look like this:
+
+------------[ cut here ]------------
+WARNING: at /data2/repos/linux-2.6-iommu/lib/dma-debug.c:448
+ check_unmap+0x203/0x490()
+Hardware name:
+forcedeth 0000:00:08.0: DMA-API: device driver frees DMA memory with wrong
+ function [device address=0x00000000640444be] [size=66 bytes] [mapped as
+single] [unmapped as page]
+Modules linked in: nfsd exportfs bridge stp llc r8169
+Pid: 0, comm: swapper Tainted: G W 2.6.28-dmatest-09289-g8bb99c0 #1
+Call Trace:
+ <IRQ> [<ffffffff80240b22>] warn_slowpath+0xf2/0x130
+ [<ffffffff80647b70>] _spin_unlock+0x10/0x30
+ [<ffffffff80537e75>] usb_hcd_link_urb_to_ep+0x75/0xc0
+ [<ffffffff80647c22>] _spin_unlock_irqrestore+0x12/0x40
+ [<ffffffff8055347f>] ohci_urb_enqueue+0x19f/0x7c0
+ [<ffffffff80252f96>] queue_work+0x56/0x60
+ [<ffffffff80237e10>] enqueue_task_fair+0x20/0x50
+ [<ffffffff80539279>] usb_hcd_submit_urb+0x379/0xbc0
+ [<ffffffff803b78c3>] cpumask_next_and+0x23/0x40
+ [<ffffffff80235177>] find_busiest_group+0x207/0x8a0
+ [<ffffffff8064784f>] _spin_lock_irqsave+0x1f/0x50
+ [<ffffffff803c7ea3>] check_unmap+0x203/0x490
+ [<ffffffff803c8259>] debug_dma_unmap_page+0x49/0x50
+ [<ffffffff80485f26>] nv_tx_done_optimized+0xc6/0x2c0
+ [<ffffffff80486c13>] nv_nic_irq_optimized+0x73/0x2b0
+ [<ffffffff8026df84>] handle_IRQ_event+0x34/0x70
+ [<ffffffff8026ffe9>] handle_edge_irq+0xc9/0x150
+ [<ffffffff8020e3ab>] do_IRQ+0xcb/0x1c0
+ [<ffffffff8020c093>] ret_from_intr+0x0/0xa
+ <EOI> <4>---[ end trace f6435a98e2a38c0e ]---
+
+The driver developer can find the driver and the device including a stacktrace
+of the DMA-API call which caused this warning.
+
+Per default only the first error will result in a warning message. All other
+errors will only silently counted. This limitation exist to prevent the code
+from flooding your kernel log. To support debugging a device driver this can
+be disabled via debugfs. See the debugfs interface documentation below for
+details.
+
+The debugfs directory for the DMA-API debugging code is called dma-api/. In
+this directory the following files can currently be found:
+
+ dma-api/all_errors This file contains a numeric value. If this
+ value is not equal to zero the debugging code
+ will print a warning for every error it finds
+ into the kernel log. Be carefull with this
+ option. It can easily flood your logs.
+
+ dma-api/disabled This read-only file contains the character 'Y'
+ if the debugging code is disabled. This can
+ happen when it runs out of memory or if it was
+ disabled at boot time
+
+ dma-api/error_count This file is read-only and shows the total
+ numbers of errors found.
+
+ dma-api/num_errors The number in this file shows how many
+ warnings will be printed to the kernel log
+ before it stops. This number is initialized to
+ one at system boot and be set by writing into
+ this file
+
+ dma-api/min_free_entries
+ This read-only file can be read to get the
+ minimum number of free dma_debug_entries the
+ allocator has ever seen. If this value goes
+ down to zero the code will disable itself
+ because it is not longer reliable.
+
+ dma-api/num_free_entries
+ The current number of free dma_debug_entries
+ in the allocator.
+
+If you have this code compiled into your kernel it will be enabled by default.
+If you want to boot without the bookkeeping anyway you can provide
+'dma_debug=off' as a boot parameter. This will disable DMA-API debugging.
+Notice that you can not enable it again at runtime. You have to reboot to do
+so.
+
+When the code disables itself at runtime this is most likely because it ran
+out of dma_debug_entries. These entries are preallocated at boot. The number
+of preallocated entries is defined per architecture. If it is too low for you
+boot with 'dma_debug_entries=<your_desired_number>' to overwrite the
+architectural default.
diff --git a/Documentation/DocBook/.gitignore b/Documentation/DocBook/.gitignore
index c102c02ecf89..c6def352fe39 100644
--- a/Documentation/DocBook/.gitignore
+++ b/Documentation/DocBook/.gitignore
@@ -4,3 +4,7 @@
*.html
*.9.gz
*.9
+*.aux
+*.dvi
+*.log
+*.out
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 1462ed86d40a..a3a83d38f96f 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -12,7 +12,8 @@ DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
- mac80211.xml debugobjects.xml sh.xml regulator.xml
+ mac80211.xml debugobjects.xml sh.xml regulator.xml \
+ alsa-driver-api.xml writing-an-alsa-driver.xml
###
# The build process is as follows (targets):
diff --git a/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl b/Documentation/DocBook/alsa-driver-api.tmpl
index 9d644f7e241e..0230a96f0564 100644
--- a/Documentation/sound/alsa/DocBook/alsa-driver-api.tmpl
+++ b/Documentation/DocBook/alsa-driver-api.tmpl
@@ -1,11 +1,11 @@
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
-
-<book>
-<?dbhtml filename="index.html">
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
<!-- ****************************************************** -->
<!-- Header -->
<!-- ****************************************************** -->
+<book id="ALSA-Driver-API">
<bookinfo>
<title>The ALSA Driver API</title>
@@ -35,6 +35,8 @@
</bookinfo>
+<toc></toc>
+
<chapter><title>Management of Cards and Devices</title>
<sect1><title>Card Management</title>
!Esound/core/init.c
@@ -71,6 +73,10 @@
!Esound/pci/ac97/ac97_codec.c
!Esound/pci/ac97/ac97_pcm.c
</sect1>
+ <sect1><title>Virtual Master Control API</title>
+!Esound/core/vmaster.c
+!Iinclude/sound/control.h
+ </sect1>
</chapter>
<chapter><title>MIDI API</title>
<sect1><title>Raw MIDI API</title>
@@ -89,6 +95,9 @@
<sect1><title>Hardware-Dependent Devices API</title>
!Esound/core/hwdep.c
</sect1>
+ <sect1><title>Jack Abstraction Layer API</title>
+!Esound/core/jack.c
+ </sect1>
<sect1><title>ISA DMA Helpers</title>
!Esound/core/isadma.c
</sect1>
diff --git a/Documentation/DocBook/genericirq.tmpl b/Documentation/DocBook/genericirq.tmpl
index 3a882d9a90a9..c671a0168096 100644
--- a/Documentation/DocBook/genericirq.tmpl
+++ b/Documentation/DocBook/genericirq.tmpl
@@ -440,6 +440,7 @@ desc->chip->end();
used in the generic IRQ layer.
</para>
!Iinclude/linux/irq.h
+!Iinclude/linux/interrupt.h
</chapter>
<chapter id="pubfunctions">
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index bc962cda6504..d6ac5d61820e 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -199,6 +199,7 @@ X!Edrivers/pci/hotplug.c
-->
!Edrivers/pci/probe.c
!Edrivers/pci/rom.c
+!Edrivers/pci/iov.c
</sect1>
<sect1><title>PCI Hotplug Support Library</title>
!Edrivers/pci/hotplug/pci_hotplug_core.c
@@ -258,7 +259,7 @@ X!Earch/x86/kernel/mca_32.c
!Eblock/blk-tag.c
!Iblock/blk-tag.c
!Eblock/blk-integrity.c
-!Iblock/blktrace.c
+!Ikernel/trace/blktrace.c
!Iblock/genhd.c
!Eblock/genhd.c
</chapter>
diff --git a/Documentation/DocBook/mac80211.tmpl b/Documentation/DocBook/mac80211.tmpl
index 77c3c202991b..fbeaffc1dcc3 100644
--- a/Documentation/DocBook/mac80211.tmpl
+++ b/Documentation/DocBook/mac80211.tmpl
@@ -17,8 +17,7 @@
</authorgroup>
<copyright>
- <year>2007</year>
- <year>2008</year>
+ <year>2007-2009</year>
<holder>Johannes Berg</holder>
</copyright>
@@ -165,8 +164,8 @@ usage should require reading the full document.
!Pinclude/net/mac80211.h Frame format
</sect1>
<sect1>
- <title>Alignment issues</title>
- <para>TBD</para>
+ <title>Packet alignment</title>
+!Pnet/mac80211/rx.c Packet alignment
</sect1>
<sect1>
<title>Calling into mac80211 from interrupts</title>
@@ -223,6 +222,17 @@ usage should require reading the full document.
!Finclude/net/mac80211.h ieee80211_key_flags
</chapter>
+ <chapter id="powersave">
+ <title>Powersave support</title>
+!Pinclude/net/mac80211.h Powersave support
+ </chapter>
+
+ <chapter id="beacon-filter">
+ <title>Beacon filter support</title>
+!Pinclude/net/mac80211.h Beacon filter support
+!Finclude/net/mac80211.h ieee80211_beacon_loss
+ </chapter>
+
<chapter id="qos">
<title>Multiple queues and QoS support</title>
<para>TBD</para>
diff --git a/Documentation/DocBook/procfs_example.c b/Documentation/DocBook/procfs_example.c
index 8c6396e4bf31..a5b11793b1e0 100644
--- a/Documentation/DocBook/procfs_example.c
+++ b/Documentation/DocBook/procfs_example.c
@@ -117,9 +117,6 @@ static int __init init_procfs_example(void)
rv = -ENOMEM;
goto out;
}
-
- example_dir->owner = THIS_MODULE;
-
/* create jiffies using convenience function */
jiffies_file = create_proc_read_entry("jiffies",
0444, example_dir,
@@ -130,8 +127,6 @@ static int __init init_procfs_example(void)
goto no_jiffies;
}
- jiffies_file->owner = THIS_MODULE;
-
/* create foo and bar files using same callback
* functions
*/
@@ -146,7 +141,6 @@ static int __init init_procfs_example(void)
foo_file->data = &foo_data;
foo_file->read_proc = proc_read_foobar;
foo_file->write_proc = proc_write_foobar;
- foo_file->owner = THIS_MODULE;
bar_file = create_proc_entry("bar", 0644, example_dir);
if(bar_file == NULL) {
@@ -159,7 +153,6 @@ static int __init init_procfs_example(void)
bar_file->data = &bar_data;
bar_file->read_proc = proc_read_foobar;
bar_file->write_proc = proc_write_foobar;
- bar_file->owner = THIS_MODULE;
/* create symlink */
symlink = proc_symlink("jiffies_too", example_dir,
@@ -169,8 +162,6 @@ static int __init init_procfs_example(void)
goto no_symlink;
}
- symlink->owner = THIS_MODULE;
-
/* everything OK */
printk(KERN_INFO "%s %s initialised\n",
MODULE_NAME, MODULE_VERS);
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
index 52e1b79ce0e6..8f6e3b2403c7 100644
--- a/Documentation/DocBook/uio-howto.tmpl
+++ b/Documentation/DocBook/uio-howto.tmpl
@@ -42,6 +42,13 @@ GPL version 2.
<revhistory>
<revision>
+ <revnumber>0.8</revnumber>
+ <date>2008-12-24</date>
+ <authorinitials>hjk</authorinitials>
+ <revremark>Added name attributes in mem and portio sysfs directories.
+ </revremark>
+ </revision>
+ <revision>
<revnumber>0.7</revnumber>
<date>2008-12-23</date>
<authorinitials>hjk</authorinitials>
@@ -303,12 +310,19 @@ interested in translating it, please email me
appear if the size of the mapping is not 0.
</para>
<para>
- Each <filename>mapX/</filename> directory contains two read-only files
- that show start address and size of the memory:
+ Each <filename>mapX/</filename> directory contains four read-only files
+ that show attributes of the memory:
</para>
<itemizedlist>
<listitem>
<para>
+ <filename>name</filename>: A string identifier for this mapping. This
+ is optional, the string can be empty. Drivers can set this to make it
+ easier for userspace to find the correct mapping.
+ </para>
+</listitem>
+<listitem>
+ <para>
<filename>addr</filename>: The address of memory that can be mapped.
</para>
</listitem>
@@ -366,12 +380,19 @@ offset = N * getpagesize();
<filename>/sys/class/uio/uioX/portio/</filename>.
</para>
<para>
- Each <filename>portX/</filename> directory contains three read-only
- files that show start, size, and type of the port region:
+ Each <filename>portX/</filename> directory contains four read-only
+ files that show name, start, size, and type of the port region:
</para>
<itemizedlist>
<listitem>
<para>
+ <filename>name</filename>: A string identifier for this port region.
+ The string is optional and can be empty. Drivers can set it to make it
+ easier for userspace to find a certain port region.
+ </para>
+</listitem>
+<listitem>
+ <para>
<filename>start</filename>: The first port of this region.
</para>
</listitem>
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl
index 87a7c07ab658..46b08fef3744 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl
@@ -1,11 +1,11 @@
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
-
-<book>
-<?dbhtml filename="index.html">
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
<!-- ****************************************************** -->
<!-- Header -->
<!-- ****************************************************** -->
+<book id="Writing-an-ALSA-Driver">
<bookinfo>
<title>Writing an ALSA Driver</title>
<author>
@@ -492,9 +492,9 @@
}
/* (2) */
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
- if (card == NULL)
- return -ENOMEM;
+ err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
+ if (err < 0)
+ return err;
/* (3) */
err = snd_mychip_create(card, pci, &chip);
@@ -590,8 +590,9 @@
<programlisting>
<![CDATA[
struct snd_card *card;
+ int err;
....
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
]]>
</programlisting>
</informalexample>
@@ -809,26 +810,28 @@
<para>
As mentioned above, to create a card instance, call
- <function>snd_card_new()</function>.
+ <function>snd_card_create()</function>.
<informalexample>
<programlisting>
<![CDATA[
struct snd_card *card;
- card = snd_card_new(index, id, module, extra_size);
+ int err;
+ err = snd_card_create(index, id, module, extra_size, &card);
]]>
</programlisting>
</informalexample>
</para>
<para>
- The function takes four arguments, the card-index number, the
+ The function takes five arguments, the card-index number, the
id string, the module pointer (usually
<constant>THIS_MODULE</constant>),
- and the size of extra-data space. The last argument is used to
+ the size of extra-data space, and the pointer to return the
+ card instance. The extra_size argument is used to
allocate card-&gt;private_data for the
chip-specific data. Note that these data
- are allocated by <function>snd_card_new()</function>.
+ are allocated by <function>snd_card_create()</function>.
</para>
</section>
@@ -915,15 +918,16 @@
</para>
<section id="card-management-chip-specific-snd-card-new">
- <title>1. Allocating via <function>snd_card_new()</function>.</title>
+ <title>1. Allocating via <function>snd_card_create()</function>.</title>
<para>
As mentioned above, you can pass the extra-data-length
- to the 4th argument of <function>snd_card_new()</function>, i.e.
+ to the 4th argument of <function>snd_card_create()</function>, i.e.
<informalexample>
<programlisting>
<![CDATA[
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct mychip));
+ err = snd_card_create(index[dev], id[dev], THIS_MODULE,
+ sizeof(struct mychip), &card);
]]>
</programlisting>
</informalexample>
@@ -952,8 +956,8 @@
<para>
After allocating a card instance via
- <function>snd_card_new()</function> (with
- <constant>NULL</constant> on the 4th arg), call
+ <function>snd_card_create()</function> (with
+ <constant>0</constant> on the 4th arg), call
<function>kzalloc()</function>.
<informalexample>
@@ -961,7 +965,7 @@
<![CDATA[
struct snd_card *card;
struct mychip *chip;
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
+ err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
.....
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
]]>
@@ -5750,8 +5754,9 @@ struct _snd_pcm_runtime {
....
struct snd_card *card;
struct mychip *chip;
+ int err;
....
- card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
+ err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
....
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
....
@@ -5763,7 +5768,7 @@ struct _snd_pcm_runtime {
</informalexample>
When you created the chip data with
- <function>snd_card_new()</function>, it's anyway accessible
+ <function>snd_card_create()</function>, it's anyway accessible
via <structfield>private_data</structfield> field.
<informalexample>
@@ -5775,9 +5780,10 @@ struct _snd_pcm_runtime {
....
struct snd_card *card;
struct mychip *chip;
+ int err;
....
- card = snd_card_new(index[dev], id[dev], THIS_MODULE,
- sizeof(struct mychip));
+ err = snd_card_create(index[dev], id[dev], THIS_MODULE,
+ sizeof(struct mychip), &card);
....
chip = card->private_data;
....
diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt
index 256defd7e174..dcf7acc720e1 100644
--- a/Documentation/PCI/MSI-HOWTO.txt
+++ b/Documentation/PCI/MSI-HOWTO.txt
@@ -4,506 +4,356 @@
Revised Feb 12, 2004 by Martine Silbermann
email: Martine.Silbermann@hp.com
Revised Jun 25, 2004 by Tom L Nguyen
+ Revised Jul 9, 2008 by Matthew Wilcox <willy@linux.intel.com>
+ Copyright 2003, 2008 Intel Corporation
1. About this guide
-This guide describes the basics of Message Signaled Interrupts (MSI),
-the advantages of using MSI over traditional interrupt mechanisms,
-and how to enable your driver to use MSI or MSI-X. Also included is
-a Frequently Asked Questions (FAQ) section.
-
-1.1 Terminology
-
-PCI devices can be single-function or multi-function. In either case,
-when this text talks about enabling or disabling MSI on a "device
-function," it is referring to one specific PCI device and function and
-not to all functions on a PCI device (unless the PCI device has only
-one function).
-
-2. Copyright 2003 Intel Corporation
-
-3. What is MSI/MSI-X?
-
-Message Signaled Interrupt (MSI), as described in the PCI Local Bus
-Specification Revision 2.3 or later, is an optional feature, and a
-required feature for PCI Express devices. MSI enables a device function
-to request service by sending an Inbound Memory Write on its PCI bus to
-the FSB as a Message Signal Interrupt transaction. Because MSI is
-generated in the form of a Memory Write, all transaction conditions,
-such as a Retry, Master-Abort, Target-Abort or normal completion, are
-supported.
-
-A PCI device that supports MSI must also support pin IRQ assertion
-interrupt mechanism to provide backward compatibility for systems that
-do not support MSI. In systems which support MSI, the bus driver is
-responsible for initializing the message address and message data of
-the device function's MSI/MSI-X capability structure during device
-initial configuration.
-
-An MSI capable device function indicates MSI support by implementing
-the MSI/MSI-X capability structure in its PCI capability list. The
-device function may implement both the MSI capability structure and
-the MSI-X capability structure; however, the bus driver should not
-enable both.
-
-The MSI capability structure contains Message Control register,
-Message Address register and Message Data register. These registers
-provide the bus driver control over MSI. The Message Control register
-indicates the MSI capability supported by the device. The Message
-Address register specifies the target address and the Message Data
-register specifies the characteristics of the message. To request
-service, the device function writes the content of the Message Data
-register to the target address. The device and its software driver
-are prohibited from writing to these registers.
-
-The MSI-X capability structure is an optional extension to MSI. It
-uses an independent and separate capability structure. There are
-some key advantages to implementing the MSI-X capability structure
-over the MSI capability structure as described below.
-
- - Support a larger maximum number of vectors per function.
-
- - Provide the ability for system software to configure
- each vector with an independent message address and message
- data, specified by a table that resides in Memory Space.
-
- - MSI and MSI-X both support per-vector masking. Per-vector
- masking is an optional extension of MSI but a required
- feature for MSI-X. Per-vector masking provides the kernel the
- ability to mask/unmask a single MSI while running its
- interrupt service routine. If per-vector masking is
- not supported, then the device driver should provide the
- hardware/software synchronization to ensure that the device
- generates MSI when the driver wants it to do so.
-
-4. Why use MSI?
-
-As a benefit to the simplification of board design, MSI allows board
-designers to remove out-of-band interrupt routing. MSI is another
-step towards a legacy-free environment.
-
-Due to increasing pressure on chipset and processor packages to
-reduce pin count, the need for interrupt pins is expected to
-diminish over time. Devices, due to pin constraints, may implement
-messages to increase performance.
-
-PCI Express endpoints uses INTx emulation (in-band messages) instead
-of IRQ pin assertion. Using INTx emulation requires interrupt
-sharing among devices connected to the same node (PCI bridge) while
-MSI is unique (non-shared) and does not require BIOS configuration
-support. As a result, the PCI Express technology requires MSI
-support for better interrupt performance.
-
-Using MSI enables the device functions to support two or more
-vectors, which can be configured to target different CPUs to
-increase scalability.
-
-5. Configuring a driver to use MSI/MSI-X
-
-By default, the kernel will not enable MSI/MSI-X on all devices that
-support this capability. The CONFIG_PCI_MSI kernel option
-must be selected to enable MSI/MSI-X support.
-
-5.1 Including MSI/MSI-X support into the kernel
-
-To allow MSI/MSI-X capable device drivers to selectively enable
-MSI/MSI-X (using pci_enable_msi()/pci_enable_msix() as described
-below), the VECTOR based scheme needs to be enabled by setting
-CONFIG_PCI_MSI during kernel config.
-
-Since the target of the inbound message is the local APIC, providing
-CONFIG_X86_LOCAL_APIC must be enabled as well as CONFIG_PCI_MSI.
-
-5.2 Configuring for MSI support
-
-Due to the non-contiguous fashion in vector assignment of the
-existing Linux kernel, this version does not support multiple
-messages regardless of a device function is capable of supporting
-more than one vector. To enable MSI on a device function's MSI
-capability structure requires a device driver to call the function
-pci_enable_msi() explicitly.
-
-5.2.1 API pci_enable_msi
+This guide describes the basics of Message Signaled Interrupts (MSIs),
+the advantages of using MSI over traditional interrupt mechanisms, how
+to change your driver to use MSI or MSI-X and some basic diagnostics to
+try if a device doesn't support MSIs.
-int pci_enable_msi(struct pci_dev *dev)
-With this new API, a device driver that wants to have MSI
-enabled on its device function must call this API to enable MSI.
-A successful call will initialize the MSI capability structure
-with ONE vector, regardless of whether a device function is
-capable of supporting multiple messages. This vector replaces the
-pre-assigned dev->irq with a new MSI vector. To avoid a conflict
-of the new assigned vector with existing pre-assigned vector requires
-a device driver to call this API before calling request_irq().
+2. What are MSIs?
-5.2.2 API pci_disable_msi
+A Message Signaled Interrupt is a write from the device to a special
+address which causes an interrupt to be received by the CPU.
-void pci_disable_msi(struct pci_dev *dev)
+The MSI capability was first specified in PCI 2.2 and was later enhanced
+in PCI 3.0 to allow each interrupt to be masked individually. The MSI-X
+capability was also introduced with PCI 3.0. It supports more interrupts
+per device than MSI and allows interrupts to be independently configured.
-This API should always be used to undo the effect of pci_enable_msi()
-when a device driver is unloading. This API restores dev->irq with
-the pre-assigned IOAPIC vector and switches a device's interrupt
-mode to PCI pin-irq assertion/INTx emulation mode.
-
-Note that a device driver should always call free_irq() on the MSI vector
-that it has done request_irq() on before calling this API. Failure to do
-so results in a BUG_ON() and a device will be left with MSI enabled and
-leaks its vector.
-
-5.2.3 MSI mode vs. legacy mode diagram
-
-The below diagram shows the events which switch the interrupt
-mode on the MSI-capable device function between MSI mode and
-PIN-IRQ assertion mode.
-
- ------------ pci_enable_msi ------------------------
- | | <=============== | |
- | MSI MODE | | PIN-IRQ ASSERTION MODE |
- | | ===============> | |
- ------------ pci_disable_msi ------------------------
-
-
-Figure 1. MSI Mode vs. Legacy Mode
-
-In Figure 1, a device operates by default in legacy mode. Legacy
-in this context means PCI pin-irq assertion or PCI-Express INTx
-emulation. A successful MSI request (using pci_enable_msi()) switches
-a device's interrupt mode to MSI mode. A pre-assigned IOAPIC vector
-stored in dev->irq will be saved by the PCI subsystem and a new
-assigned MSI vector will replace dev->irq.
-
-To return back to its default mode, a device driver should always call
-pci_disable_msi() to undo the effect of pci_enable_msi(). Note that a
-device driver should always call free_irq() on the MSI vector it has
-done request_irq() on before calling pci_disable_msi(). Failure to do
-so results in a BUG_ON() and a device will be left with MSI enabled and
-leaks its vector. Otherwise, the PCI subsystem restores a device's
-dev->irq with a pre-assigned IOAPIC vector and marks the released
-MSI vector as unused.
-
-Once being marked as unused, there is no guarantee that the PCI
-subsystem will reserve this MSI vector for a device. Depending on
-the availability of current PCI vector resources and the number of
-MSI/MSI-X requests from other drivers, this MSI may be re-assigned.
-
-For the case where the PCI subsystem re-assigns this MSI vector to
-another driver, a request to switch back to MSI mode may result
-in being assigned a different MSI vector or a failure if no more
-vectors are available.
-
-5.3 Configuring for MSI-X support
-
-Due to the ability of the system software to configure each vector of
-the MSI-X capability structure with an independent message address
-and message data, the non-contiguous fashion in vector assignment of
-the existing Linux kernel has no impact on supporting multiple
-messages on an MSI-X capable device functions. To enable MSI-X on
-a device function's MSI-X capability structure requires its device
-driver to call the function pci_enable_msix() explicitly.
-
-The function pci_enable_msix(), once invoked, enables either
-all or nothing, depending on the current availability of PCI vector
-resources. If the PCI vector resources are available for the number
-of vectors requested by a device driver, this function will configure
-the MSI-X table of the MSI-X capability structure of a device with
-requested messages. To emphasize this reason, for example, a device
-may be capable for supporting the maximum of 32 vectors while its
-software driver usually may request 4 vectors. It is recommended
-that the device driver should call this function once during the
-initialization phase of the device driver.
-
-Unlike the function pci_enable_msi(), the function pci_enable_msix()
-does not replace the pre-assigned IOAPIC dev->irq with a new MSI
-vector because the PCI subsystem writes the 1:1 vector-to-entry mapping
-into the field vector of each element contained in a second argument.
-Note that the pre-assigned IOAPIC dev->irq is valid only if the device
-operates in PIN-IRQ assertion mode. In MSI-X mode, any attempt at
-using dev->irq by the device driver to request for interrupt service
-may result in unpredictable behavior.
-
-For each MSI-X vector granted, a device driver is responsible for calling
-other functions like request_irq(), enable_irq(), etc. to enable
-this vector with its corresponding interrupt service handler. It is
-a device driver's choice to assign all vectors with the same
-interrupt service handler or each vector with a unique interrupt
-service handler.
-
-5.3.1 Handling MMIO address space of MSI-X Table
-
-The PCI 3.0 specification has implementation notes that MMIO address
-space for a device's MSI-X structure should be isolated so that the
-software system can set different pages for controlling accesses to the
-MSI-X structure. The implementation of MSI support requires the PCI
-subsystem, not a device driver, to maintain full control of the MSI-X
-table/MSI-X PBA (Pending Bit Array) and MMIO address space of the MSI-X
-table/MSI-X PBA. A device driver should not access the MMIO address
-space of the MSI-X table/MSI-X PBA.
-
-5.3.2 API pci_enable_msix
+Devices may support both MSI and MSI-X, but only one can be enabled at
+a time.
-int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
-This API enables a device driver to request the PCI subsystem
-to enable MSI-X messages on its hardware device. Depending on
-the availability of PCI vectors resources, the PCI subsystem enables
-either all or none of the requested vectors.
+3. Why use MSIs?
+
+There are three reasons why using MSIs can give an advantage over
+traditional pin-based interrupts.
+
+Pin-based PCI interrupts are often shared amongst several devices.
+To support this, the kernel must call each interrupt handler associated
+with an interrupt, which leads to reduced performance for the system as
+a whole. MSIs are never shared, so this problem cannot arise.
+
+When a device writes data to memory, then raises a pin-based interrupt,
+it is possible that the interrupt may arrive before all the data has
+arrived in memory (this becomes more likely with devices behind PCI-PCI
+bridges). In order to ensure that all the data has arrived in memory,
+the interrupt handler must read a register on the device which raised
+the interrupt. PCI transaction ordering rules require that all the data
+arrives in memory before the value can be returned from the register.
+Using MSIs avoids this problem as the interrupt-generating write cannot
+pass the data writes, so by the time the interrupt is raised, the driver
+knows that all the data has arrived in memory.
+
+PCI devices can only support a single pin-based interrupt per function.
+Often drivers have to query the device to find out what event has
+occurred, slowing down interrupt handling for the common case. With
+MSIs, a device can support more interrupts, allowing each interrupt
+to be specialised to a different purpose. One possible design gives
+infrequent conditions (such as errors) their own interrupt which allows
+the driver to handle the normal interrupt handling path more efficiently.
+Other possible designs include giving one interrupt to each packet queue
+in a network card or each port in a storage controller.
+
+
+4. How to use MSIs
+
+PCI devices are initialised to use pin-based interrupts. The device
+driver has to set up the device to use MSI or MSI-X. Not all machines
+support MSIs correctly, and for those machines, the APIs described below
+will simply fail and the device will continue to use pin-based interrupts.
+
+4.1 Include kernel support for MSIs
+
+To support MSI or MSI-X, the kernel must be built with the CONFIG_PCI_MSI
+option enabled. This option is only available on some architectures,
+and it may depend on some other options also being set. For example,
+on x86, you must also enable X86_UP_APIC or SMP in order to see the
+CONFIG_PCI_MSI option.
+
+4.2 Using MSI
+
+Most of the hard work is done for the driver in the PCI layer. It simply
+has to request that the PCI layer set up the MSI capability for this
+device.
+
+4.2.1 pci_enable_msi
+
+int pci_enable_msi(struct pci_dev *dev)
+
+A successful call will allocate ONE interrupt to the device, regardless
+of how many MSIs the device supports. The device will be switched from
+pin-based interrupt mode to MSI mode. The dev->irq number is changed
+to a new number which represents the message signaled interrupt.
+This function should be called before the driver calls request_irq()
+since enabling MSIs disables the pin-based IRQ and the driver will not
+receive interrupts on the old interrupt.
+
+4.2.2 pci_enable_msi_block
+
+int pci_enable_msi_block(struct pci_dev *dev, int count)
+
+This variation on the above call allows a device driver to request multiple
+MSIs. The MSI specification only allows interrupts to be allocated in
+powers of two, up to a maximum of 2^5 (32).
+
+If this function returns 0, it has succeeded in allocating at least as many
+interrupts as the driver requested (it may have allocated more in order
+to satisfy the power-of-two requirement). In this case, the function
+enables MSI on this device and updates dev->irq to be the lowest of
+the new interrupts assigned to it. The other interrupts assigned to
+the device are in the range dev->irq to dev->irq + count - 1.
+
+If this function returns a negative number, it indicates an error and
+the driver should not attempt to request any more MSI interrupts for
+this device. If this function returns a positive number, it will be
+less than 'count' and indicate the number of interrupts that could have
+been allocated. In neither case will the irq value have been
+updated, nor will the device have been switched into MSI mode.
+
+The device driver must decide what action to take if
+pci_enable_msi_block() returns a value less than the number asked for.
+Some devices can make use of fewer interrupts than the maximum they
+request; in this case the driver should call pci_enable_msi_block()
+again. Note that it is not guaranteed to succeed, even when the
+'count' has been reduced to the value returned from a previous call to
+pci_enable_msi_block(). This is because there are multiple constraints
+on the number of vectors that can be allocated; pci_enable_msi_block()
+will return as soon as it finds any constraint that doesn't allow the
+call to succeed.
+
+4.2.3 pci_disable_msi
+
+void pci_disable_msi(struct pci_dev *dev)
-Argument 'dev' points to the device (pci_dev) structure.
+This function should be used to undo the effect of pci_enable_msi() or
+pci_enable_msi_block(). Calling it restores dev->irq to the pin-based
+interrupt number and frees the previously allocated message signaled
+interrupt(s). The interrupt may subsequently be assigned to another
+device, so drivers should not cache the value of dev->irq.
-Argument 'entries' is a pointer to an array of msix_entry structs.
-The number of entries is indicated in argument 'nvec'.
-struct msix_entry is defined in /driver/pci/msi.h:
+A device driver must always call free_irq() on the interrupt(s)
+for which it has called request_irq() before calling this function.
+Failure to do so will result in a BUG_ON(), the device will be left with
+MSI enabled and will leak its vector.
+
+4.3 Using MSI-X
+
+The MSI-X capability is much more flexible than the MSI capability.
+It supports up to 2048 interrupts, each of which can be controlled
+independently. To support this flexibility, drivers must use an array of
+`struct msix_entry':
struct msix_entry {
u16 vector; /* kernel uses to write alloc vector */
u16 entry; /* driver uses to specify entry */
};
-A device driver is responsible for initializing the field 'entry' of
-each element with a unique entry supported by MSI-X table. Otherwise,
--EINVAL will be returned as a result. A successful return of zero
-indicates the PCI subsystem completed initializing each of the requested
-entries of the MSI-X table with message address and message data.
-Last but not least, the PCI subsystem will write the 1:1
-vector-to-entry mapping into the field 'vector' of each element. A
-device driver is responsible for keeping track of allocated MSI-X
-vectors in its internal data structure.
-
-A return of zero indicates that the number of MSI-X vectors was
-successfully allocated. A return of greater than zero indicates
-MSI-X vector shortage. Or a return of less than zero indicates
-a failure. This failure may be a result of duplicate entries
-specified in second argument, or a result of no available vector,
-or a result of failing to initialize MSI-X table entries.
-
-5.3.3 API pci_disable_msix
+This allows for the device to use these interrupts in a sparse fashion;
+for example it could use interrupts 3 and 1027 and allocate only a
+two-element array. The driver is expected to fill in the 'entry' value
+in each element of the array to indicate which entries it wants the kernel
+to assign interrupts for. It is invalid to fill in two entries with the
+same number.
+
+4.3.1 pci_enable_msix
+
+int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
+
+Calling this function asks the PCI subsystem to allocate 'nvec' MSIs.
+The 'entries' argument is a pointer to an array of msix_entry structs
+which should be at least 'nvec' entries in size. On success, the
+function will return 0 and the device will have been switched into
+MSI-X interrupt mode. The 'vector' elements in each entry will have
+been filled in with the interrupt number. The driver should then call
+request_irq() for each 'vector' that it decides to use.
+
+If this function returns a negative number, it indicates an error and
+the driver should not attempt to allocate any more MSI-X interrupts for
+this device. If it returns a positive number, it indicates the maximum
+number of interrupt vectors that could have been allocated. See example
+below.
+
+This function, in contrast with pci_enable_msi(), does not adjust
+dev->irq. The device will not generate interrupts for this interrupt
+number once MSI-X is enabled. The device driver is responsible for
+keeping track of the interrupts assigned to the MSI-X vectors so it can
+free them again later.
+
+Device drivers should normally call this function once per device
+during the initialization phase.
+
+It is ideal if drivers can cope with a variable number of MSI-X interrupts,
+there are many reasons why the platform may not be able to provide the
+exact number a driver asks for.
+
+A request loop to achieve that might look like:
+
+static int foo_driver_enable_msix(struct foo_adapter *adapter, int nvec)
+{
+ while (nvec >= FOO_DRIVER_MINIMUM_NVEC) {
+ rc = pci_enable_msix(adapter->pdev,
+ adapter->msix_entries, nvec);
+ if (rc > 0)
+ nvec = rc;
+ else
+ return rc;
+ }
+
+ return -ENOSPC;
+}
+
+4.3.2 pci_disable_msix
void pci_disable_msix(struct pci_dev *dev)
-This API should always be used to undo the effect of pci_enable_msix()
-when a device driver is unloading. Note that a device driver should
-always call free_irq() on all MSI-X vectors it has done request_irq()
-on before calling this API. Failure to do so results in a BUG_ON() and
-a device will be left with MSI-X enabled and leaks its vectors.
-
-5.3.4 MSI-X mode vs. legacy mode diagram
-
-The below diagram shows the events which switch the interrupt
-mode on the MSI-X capable device function between MSI-X mode and
-PIN-IRQ assertion mode (legacy).
-
- ------------ pci_enable_msix(,,n) ------------------------
- | | <=============== | |
- | MSI-X MODE | | PIN-IRQ ASSERTION MODE |
- | | ===============> | |
- ------------ pci_disable_msix ------------------------
-
-Figure 2. MSI-X Mode vs. Legacy Mode
-
-In Figure 2, a device operates by default in legacy mode. A
-successful MSI-X request (using pci_enable_msix()) switches a
-device's interrupt mode to MSI-X mode. A pre-assigned IOAPIC vector
-stored in dev->irq will be saved by the PCI subsystem; however,
-unlike MSI mode, the PCI subsystem will not replace dev->irq with
-assigned MSI-X vector because the PCI subsystem already writes the 1:1
-vector-to-entry mapping into the field 'vector' of each element
-specified in second argument.
-
-To return back to its default mode, a device driver should always call
-pci_disable_msix() to undo the effect of pci_enable_msix(). Note that
-a device driver should always call free_irq() on all MSI-X vectors it
-has done request_irq() on before calling pci_disable_msix(). Failure
-to do so results in a BUG_ON() and a device will be left with MSI-X
-enabled and leaks its vectors. Otherwise, the PCI subsystem switches a
-device function's interrupt mode from MSI-X mode to legacy mode and
-marks all allocated MSI-X vectors as unused.
-
-Once being marked as unused, there is no guarantee that the PCI
-subsystem will reserve these MSI-X vectors for a device. Depending on
-the availability of current PCI vector resources and the number of
-MSI/MSI-X requests from other drivers, these MSI-X vectors may be
-re-assigned.
-
-For the case where the PCI subsystem re-assigned these MSI-X vectors
-to other drivers, a request to switch back to MSI-X mode may result
-being assigned with another set of MSI-X vectors or a failure if no
-more vectors are available.
-
-5.4 Handling function implementing both MSI and MSI-X capabilities
-
-For the case where a function implements both MSI and MSI-X
-capabilities, the PCI subsystem enables a device to run either in MSI
-mode or MSI-X mode but not both. A device driver determines whether it
-wants MSI or MSI-X enabled on its hardware device. Once a device
-driver requests for MSI, for example, it is prohibited from requesting
-MSI-X; in other words, a device driver is not permitted to ping-pong
-between MSI mod MSI-X mode during a run-time.
-
-5.5 Hardware requirements for MSI/MSI-X support
-
-MSI/MSI-X support requires support from both system hardware and
-individual hardware device functions.
-
-5.5.1 Required x86 hardware support
-
-Since the target of MSI address is the local APIC CPU, enabling
-MSI/MSI-X support in the Linux kernel is dependent on whether existing
-system hardware supports local APIC. Users should verify that their
-system supports local APIC operation by testing that it runs when
-CONFIG_X86_LOCAL_APIC=y.
-
-In SMP environment, CONFIG_X86_LOCAL_APIC is automatically set;
-however, in UP environment, users must manually set
-CONFIG_X86_LOCAL_APIC. Once CONFIG_X86_LOCAL_APIC=y, setting
-CONFIG_PCI_MSI enables the VECTOR based scheme and the option for
-MSI-capable device drivers to selectively enable MSI/MSI-X.
-
-Note that CONFIG_X86_IO_APIC setting is irrelevant because MSI/MSI-X
-vector is allocated new during runtime and MSI/MSI-X support does not
-depend on BIOS support. This key independency enables MSI/MSI-X
-support on future IOxAPIC free platforms.
-
-5.5.2 Device hardware support
-
-The hardware device function supports MSI by indicating the
-MSI/MSI-X capability structure on its PCI capability list. By
-default, this capability structure will not be initialized by
-the kernel to enable MSI during the system boot. In other words,
-the device function is running on its default pin assertion mode.
-Note that in many cases the hardware supporting MSI have bugs,
-which may result in system hangs. The software driver of specific
-MSI-capable hardware is responsible for deciding whether to call
-pci_enable_msi or not. A return of zero indicates the kernel
-successfully initialized the MSI/MSI-X capability structure of the
-device function. The device function is now running on MSI/MSI-X mode.
-
-5.6 How to tell whether MSI/MSI-X is enabled on device function
-
-At the driver level, a return of zero from the function call of
-pci_enable_msi()/pci_enable_msix() indicates to a device driver that
-its device function is initialized successfully and ready to run in
-MSI/MSI-X mode.
-
-At the user level, users can use the command 'cat /proc/interrupts'
-to display the vectors allocated for devices and their interrupt
-MSI/MSI-X modes ("PCI-MSI"/"PCI-MSI-X"). Below shows MSI mode is
-enabled on a SCSI Adaptec 39320D Ultra320 controller.
-
- CPU0 CPU1
- 0: 324639 0 IO-APIC-edge timer
- 1: 1186 0 IO-APIC-edge i8042
- 2: 0 0 XT-PIC cascade
- 12: 2797 0 IO-APIC-edge i8042
- 14: 6543 0 IO-APIC-edge ide0
- 15: 1 0 IO-APIC-edge ide1
-169: 0 0 IO-APIC-level uhci-hcd
-185: 0 0 IO-APIC-level uhci-hcd
-193: 138 10 PCI-MSI aic79xx
-201: 30 0 PCI-MSI aic79xx
-225: 30 0 IO-APIC-level aic7xxx
-233: 30 0 IO-APIC-level aic7xxx
-NMI: 0 0
-LOC: 324553 325068
-ERR: 0
-MIS: 0
-
-6. MSI quirks
-
-Several PCI chipsets or devices are known to not support MSI.
-The PCI stack provides 3 possible levels of MSI disabling:
-* on a single device
-* on all devices behind a specific bridge
-* globally
-
-6.1. Disabling MSI on a single device
-
-Under some circumstances it might be required to disable MSI on a
-single device. This may be achieved by either not calling pci_enable_msi()
-or all, or setting the pci_dev->no_msi flag before (most of the time
-in a quirk).
-
-6.2. Disabling MSI below a bridge
-
-The vast majority of MSI quirks are required by PCI bridges not
-being able to route MSI between busses. In this case, MSI have to be
-disabled on all devices behind this bridge. It is achieves by setting
-the PCI_BUS_FLAGS_NO_MSI flag in the pci_bus->bus_flags of the bridge
-subordinate bus. There is no need to set the same flag on bridges that
-are below the broken bridge. When pci_enable_msi() is called to enable
-MSI on a device, pci_msi_supported() takes care of checking the NO_MSI
-flag in all parent busses of the device.
-
-Some bridges actually support dynamic MSI support enabling/disabling
-by changing some bits in their PCI configuration space (especially
-the Hypertransport chipsets such as the nVidia nForce and Serverworks
-HT2000). It may then be required to update the NO_MSI flag on the
-corresponding devices in the sysfs hierarchy. To enable MSI support
-on device "0000:00:0e", do:
-
- echo 1 > /sys/bus/pci/devices/0000:00:0e/msi_bus
-
-To disable MSI support, echo 0 instead of 1. Note that it should be
-used with caution since changing this value might break interrupts.
-
-6.3. Disabling MSI globally
-
-Some extreme cases may require to disable MSI globally on the system.
-For now, the only known case is a Serverworks PCI-X chipsets (MSI are
-not supported on several busses that are not all connected to the
-chipset in the Linux PCI hierarchy). In the vast majority of other
-cases, disabling only behind a specific bridge is enough.
-
-For debugging purpose, the user may also pass pci=nomsi on the kernel
-command-line to explicitly disable MSI globally. But, once the appro-
-priate quirks are added to the kernel, this option should not be
-required anymore.
-
-6.4. Finding why MSI cannot be enabled on a device
-
-Assuming that MSI are not enabled on a device, you should look at
-dmesg to find messages that quirks may output when disabling MSI
-on some devices, some bridges or even globally.
-Then, lspci -t gives the list of bridges above a device. Reading
-/sys/bus/pci/devices/0000:00:0e/msi_bus will tell you whether MSI
-are enabled (1) or disabled (0). In 0 is found in a single bridge
-msi_bus file above the device, MSI cannot be enabled.
-
-7. FAQ
-
-Q1. Are there any limitations on using the MSI?
-
-A1. If the PCI device supports MSI and conforms to the
-specification and the platform supports the APIC local bus,
-then using MSI should work.
-
-Q2. Will it work on all the Pentium processors (P3, P4, Xeon,
-AMD processors)? In P3 IPI's are transmitted on the APIC local
-bus and in P4 and Xeon they are transmitted on the system
-bus. Are there any implications with this?
-
-A2. MSI support enables a PCI device sending an inbound
-memory write (0xfeexxxxx as target address) on its PCI bus
-directly to the FSB. Since the message address has a
-redirection hint bit cleared, it should work.
-
-Q3. The target address 0xfeexxxxx will be translated by the
-Host Bridge into an interrupt message. Are there any
-limitations on the chipsets such as Intel 8xx, Intel e7xxx,
-or VIA?
-
-A3. If these chipsets support an inbound memory write with
-target address set as 0xfeexxxxx, as conformed to PCI
-specification 2.3 or latest, then it should work.
-
-Q4. From the driver point of view, if the MSI is lost because
-of errors occurring during inbound memory write, then it may
-wait forever. Is there a mechanism for it to recover?
-
-A4. Since the target of the transaction is an inbound memory
-write, all transaction termination conditions (Retry,
-Master-Abort, Target-Abort, or normal completion) are
-supported. A device sending an MSI must abide by all the PCI
-rules and conditions regarding that inbound memory write. So,
-if a retry is signaled it must retry, etc... We believe that
-the recommendation for Abort is also a retry (refer to PCI
-specification 2.3 or latest).
+This API should be used to undo the effect of pci_enable_msix(). It frees
+the previously allocated message signaled interrupts. The interrupts may
+subsequently be assigned to another device, so drivers should not cache
+the value of the 'vector' elements over a call to pci_disable_msix().
+
+A device driver must always call free_irq() on the interrupt(s)
+for which it has called request_irq() before calling this function.
+Failure to do so will result in a BUG_ON(), the device will be left with
+MSI enabled and will leak its vector.
+
+4.3.3 The MSI-X Table
+
+The MSI-X capability specifies a BAR and offset within that BAR for the
+MSI-X Table. This address is mapped by the PCI subsystem, and should not
+be accessed directly by the device driver. If the driver wishes to
+mask or unmask an interrupt, it should call disable_irq() / enable_irq().
+
+4.4 Handling devices implementing both MSI and MSI-X capabilities
+
+If a device implements both MSI and MSI-X capabilities, it can
+run in either MSI mode or MSI-X mode but not both simultaneously.
+This is a requirement of the PCI spec, and it is enforced by the
+PCI layer. Calling pci_enable_msi() when MSI-X is already enabled or
+pci_enable_msix() when MSI is already enabled will result in an error.
+If a device driver wishes to switch between MSI and MSI-X at runtime,
+it must first quiesce the device, then switch it back to pin-interrupt
+mode, before calling pci_enable_msi() or pci_enable_msix() and resuming
+operation. This is not expected to be a common operation but may be
+useful for debugging or testing during development.
+
+4.5 Considerations when using MSIs
+
+4.5.1 Choosing between MSI-X and MSI
+
+If your device supports both MSI-X and MSI capabilities, you should use
+the MSI-X facilities in preference to the MSI facilities. As mentioned
+above, MSI-X supports any number of interrupts between 1 and 2048.
+In constrast, MSI is restricted to a maximum of 32 interrupts (and
+must be a power of two). In addition, the MSI interrupt vectors must
+be allocated consecutively, so the system may not be able to allocate
+as many vectors for MSI as it could for MSI-X. On some platforms, MSI
+interrupts must all be targetted at the same set of CPUs whereas MSI-X
+interrupts can all be targetted at different CPUs.
+
+4.5.2 Spinlocks
+
+Most device drivers have a per-device spinlock which is taken in the
+interrupt handler. With pin-based interrupts or a single MSI, it is not
+necessary to disable interrupts (Linux guarantees the same interrupt will
+not be re-entered). If a device uses multiple interrupts, the driver
+must disable interrupts while the lock is held. If the device sends
+a different interrupt, the driver will deadlock trying to recursively
+acquire the spinlock.
+
+There are two solutions. The first is to take the lock with
+spin_lock_irqsave() or spin_lock_irq() (see
+Documentation/DocBook/kernel-locking). The second is to specify
+IRQF_DISABLED to request_irq() so that the kernel runs the entire
+interrupt routine with interrupts disabled.
+
+If your MSI interrupt routine does not hold the lock for the whole time
+it is running, the first solution may be best. The second solution is
+normally preferred as it avoids making two transitions from interrupt
+disabled to enabled and back again.
+
+4.6 How to tell whether MSI/MSI-X is enabled on a device
+
+Using 'lspci -v' (as root) may show some devices with "MSI", "Message
+Signalled Interrupts" or "MSI-X" capabilities. Each of these capabilities
+has an 'Enable' flag which will be followed with either "+" (enabled)
+or "-" (disabled).
+
+
+5. MSI quirks
+
+Several PCI chipsets or devices are known not to support MSIs.
+The PCI stack provides three ways to disable MSIs:
+
+1. globally
+2. on all devices behind a specific bridge
+3. on a single device
+
+5.1. Disabling MSIs globally
+
+Some host chipsets simply don't support MSIs properly. If we're
+lucky, the manufacturer knows this and has indicated it in the ACPI
+FADT table. In this case, Linux will automatically disable MSIs.
+Some boards don't include this information in the table and so we have
+to detect them ourselves. The complete list of these is found near the
+quirk_disable_all_msi() function in drivers/pci/quirks.c.
+
+If you have a board which has problems with MSIs, you can pass pci=nomsi
+on the kernel command line to disable MSIs on all devices. It would be
+in your best interests to report the problem to linux-pci@vger.kernel.org
+including a full 'lspci -v' so we can add the quirks to the kernel.
+
+5.2. Disabling MSIs below a bridge
+
+Some PCI bridges are not able to route MSIs between busses properly.
+In this case, MSIs must be disabled on all devices behind the bridge.
+
+Some bridges allow you to enable MSIs by changing some bits in their
+PCI configuration space (especially the Hypertransport chipsets such
+as the nVidia nForce and Serverworks HT2000). As with host chipsets,
+Linux mostly knows about them and automatically enables MSIs if it can.
+If you have a bridge which Linux doesn't yet know about, you can enable
+MSIs in configuration space using whatever method you know works, then
+enable MSIs on that bridge by doing:
+
+ echo 1 > /sys/bus/pci/devices/$bridge/msi_bus
+
+where $bridge is the PCI address of the bridge you've enabled (eg
+0000:00:0e.0).
+
+To disable MSIs, echo 0 instead of 1. Changing this value should be
+done with caution as it can break interrupt handling for all devices
+below this bridge.
+
+Again, please notify linux-pci@vger.kernel.org of any bridges that need
+special handling.
+
+5.3. Disabling MSIs on a single device
+
+Some devices are known to have faulty MSI implementations. Usually this
+is handled in the individual device driver but occasionally it's necessary
+to handle this with a quirk. Some drivers have an option to disable use
+of MSI. While this is a convenient workaround for the driver author,
+it is not good practise, and should not be emulated.
+
+5.4. Finding why MSIs are disabled on a device
+
+From the above three sections, you can see that there are many reasons
+why MSIs may not be enabled for a given device. Your first step should
+be to examine your dmesg carefully to determine whether MSIs are enabled
+for your machine. You should also check your .config to be sure you
+have enabled CONFIG_PCI_MSI.
+
+Then, 'lspci -t' gives the list of bridges above a device. Reading
+/sys/bus/pci/devices/*/msi_bus will tell you whether MSI are enabled (1)
+or disabled (0). If 0 is found in any of the msi_bus files belonging
+to bridges between the PCI root and the device, MSIs are disabled.
+
+It is also worth checking the device driver to see whether it supports MSIs.
+For example, it may contain calls to pci_enable_msi(), pci_enable_msix() or
+pci_enable_msi_block().
diff --git a/Documentation/PCI/pci-iov-howto.txt b/Documentation/PCI/pci-iov-howto.txt
new file mode 100644
index 000000000000..fc73ef5d65b8
--- /dev/null
+++ b/Documentation/PCI/pci-iov-howto.txt
@@ -0,0 +1,99 @@
+ PCI Express I/O Virtualization Howto
+ Copyright (C) 2009 Intel Corporation
+ Yu Zhao <yu.zhao@intel.com>
+
+
+1. Overview
+
+1.1 What is SR-IOV
+
+Single Root I/O Virtualization (SR-IOV) is a PCI Express Extended
+capability which makes one physical device appear as multiple virtual
+devices. The physical device is referred to as Physical Function (PF)
+while the virtual devices are referred to as Virtual Functions (VF).
+Allocation of the VF can be dynamically controlled by the PF via
+registers encapsulated in the capability. By default, this feature is
+not enabled and the PF behaves as traditional PCIe device. Once it's
+turned on, each VF's PCI configuration space can be accessed by its own
+Bus, Device and Function Number (Routing ID). And each VF also has PCI
+Memory Space, which is used to map its register set. VF device driver
+operates on the register set so it can be functional and appear as a
+real existing PCI device.
+
+2. User Guide
+
+2.1 How can I enable SR-IOV capability
+
+The device driver (PF driver) will control the enabling and disabling
+of the capability via API provided by SR-IOV core. If the hardware
+has SR-IOV capability, loading its PF driver would enable it and all
+VFs associated with the PF.
+
+2.2 How can I use the Virtual Functions
+
+The VF is treated as hot-plugged PCI devices in the kernel, so they
+should be able to work in the same way as real PCI devices. The VF
+requires device driver that is same as a normal PCI device's.
+
+3. Developer Guide
+
+3.1 SR-IOV API
+
+To enable SR-IOV capability:
+ int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
+ 'nr_virtfn' is number of VFs to be enabled.
+
+To disable SR-IOV capability:
+ void pci_disable_sriov(struct pci_dev *dev);
+
+To notify SR-IOV core of Virtual Function Migration:
+ irqreturn_t pci_sriov_migration(struct pci_dev *dev);
+
+3.2 Usage example
+
+Following piece of code illustrates the usage of the SR-IOV API.
+
+static int __devinit dev_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ pci_enable_sriov(dev, NR_VIRTFN);
+
+ ...
+
+ return 0;
+}
+
+static void __devexit dev_remove(struct pci_dev *dev)
+{
+ pci_disable_sriov(dev);
+
+ ...
+}
+
+static int dev_suspend(struct pci_dev *dev, pm_message_t state)
+{
+ ...
+
+ return 0;
+}
+
+static int dev_resume(struct pci_dev *dev)
+{
+ ...
+
+ return 0;
+}
+
+static void dev_shutdown(struct pci_dev *dev)
+{
+ ...
+}
+
+static struct pci_driver dev_driver = {
+ .name = "SR-IOV Physical Function driver",
+ .id_table = dev_id_table,
+ .probe = dev_probe,
+ .remove = __devexit_p(dev_remove),
+ .suspend = dev_suspend,
+ .resume = dev_resume,
+ .shutdown = dev_shutdown,
+};
diff --git a/Documentation/RCU/listRCU.txt b/Documentation/RCU/listRCU.txt
index 1fd175368a87..4349c1487e91 100644
--- a/Documentation/RCU/listRCU.txt
+++ b/Documentation/RCU/listRCU.txt
@@ -118,7 +118,7 @@ Following are the RCU equivalents for these two functions:
list_for_each_entry(e, list, list) {
if (!audit_compare_rule(rule, &e->rule)) {
list_del_rcu(&e->list);
- call_rcu(&e->rcu, audit_free_rule, e);
+ call_rcu(&e->rcu, audit_free_rule);
return 0;
}
}
@@ -206,7 +206,7 @@ RCU ("read-copy update") its name. The RCU code is as follows:
ne->rule.action = newaction;
ne->rule.file_count = newfield_count;
list_replace_rcu(e, ne);
- call_rcu(&e->rcu, audit_free_rule, e);
+ call_rcu(&e->rcu, audit_free_rule);
return 0;
}
}
@@ -283,7 +283,7 @@ flag under the spinlock as follows:
list_del_rcu(&e->list);
e->deleted = 1;
spin_unlock(&e->lock);
- call_rcu(&e->rcu, audit_free_rule, e);
+ call_rcu(&e->rcu, audit_free_rule);
return 0;
}
}
diff --git a/Documentation/RCU/rcu.txt b/Documentation/RCU/rcu.txt
index 95821a29ae41..7aa2002ade77 100644
--- a/Documentation/RCU/rcu.txt
+++ b/Documentation/RCU/rcu.txt
@@ -81,7 +81,7 @@ o I hear that RCU needs work in order to support realtime kernels?
This work is largely completed. Realtime-friendly RCU can be
enabled via the CONFIG_PREEMPT_RCU kernel configuration parameter.
However, work is in progress for enabling priority boosting of
- preempted RCU read-side critical sections.This is needed if you
+ preempted RCU read-side critical sections. This is needed if you
have CPU-bound realtime threads.
o Where can I find more information on RCU?
diff --git a/Documentation/RCU/rculist_nulls.txt b/Documentation/RCU/rculist_nulls.txt
index 239f542d48ba..6389dec33459 100644
--- a/Documentation/RCU/rculist_nulls.txt
+++ b/Documentation/RCU/rculist_nulls.txt
@@ -21,7 +21,7 @@ if (obj) {
/*
* Because a writer could delete object, and a writer could
* reuse these object before the RCU grace period, we
- * must check key after geting the reference on object
+ * must check key after getting the reference on object
*/
if (obj->key != key) { // not the object we expected
put_ref(obj);
@@ -117,7 +117,7 @@ a race (some writer did a delete and/or a move of an object
to another chain) checking the final 'nulls' value if
the lookup met the end of chain. If final 'nulls' value
is not the slot number, then we must restart the lookup at
-the begining. If the object was moved to same chain,
+the beginning. If the object was moved to the same chain,
then the reader doesnt care : It might eventually
scan the list again without harm.
diff --git a/Documentation/Smack.txt b/Documentation/Smack.txt
index 989c2fcd8111..629c92e99783 100644
--- a/Documentation/Smack.txt
+++ b/Documentation/Smack.txt
@@ -184,14 +184,16 @@ length. Single character labels using special characters, that being anything
other than a letter or digit, are reserved for use by the Smack development
team. Smack labels are unstructured, case sensitive, and the only operation
ever performed on them is comparison for equality. Smack labels cannot
-contain unprintable characters or the "/" (slash) character.
+contain unprintable characters or the "/" (slash) character. Smack labels
+cannot begin with a '-', which is reserved for special options.
There are some predefined labels:
- _ Pronounced "floor", a single underscore character.
- ^ Pronounced "hat", a single circumflex character.
- * Pronounced "star", a single asterisk character.
- ? Pronounced "huh", a single question mark character.
+ _ Pronounced "floor", a single underscore character.
+ ^ Pronounced "hat", a single circumflex character.
+ * Pronounced "star", a single asterisk character.
+ ? Pronounced "huh", a single question mark character.
+ @ Pronounced "Internet", a single at sign character.
Every task on a Smack system is assigned a label. System tasks, such as
init(8) and systems daemons, are run with the floor ("_") label. User tasks
@@ -412,6 +414,36 @@ sockets.
A privileged program may set this to match the label of another
task with which it hopes to communicate.
+Smack Netlabel Exceptions
+
+You will often find that your labeled application has to talk to the outside,
+unlabeled world. To do this there's a special file /smack/netlabel where you can
+add some exceptions in the form of :
+@IP1 LABEL1 or
+@IP2/MASK LABEL2
+
+It means that your application will have unlabeled access to @IP1 if it has
+write access on LABEL1, and access to the subnet @IP2/MASK if it has write
+access on LABEL2.
+
+Entries in the /smack/netlabel file are matched by longest mask first, like in
+classless IPv4 routing.
+
+A special label '@' and an option '-CIPSO' can be used there :
+@ means Internet, any application with any label has access to it
+-CIPSO means standard CIPSO networking
+
+If you don't know what CIPSO is and don't plan to use it, you can just do :
+echo 127.0.0.1 -CIPSO > /smack/netlabel
+echo 0.0.0.0/0 @ > /smack/netlabel
+
+If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled
+Internet access, you can have :
+echo 127.0.0.1 -CIPSO > /smack/netlabel
+echo 192.168.0.0/16 -CIPSO > /smack/netlabel
+echo 0.0.0.0/0 @ > /smack/netlabel
+
+
Writing Applications for Smack
There are three sorts of applications that will run on a Smack system. How an
diff --git a/Documentation/arm/Samsung-S3C24XX/Suspend.txt b/Documentation/arm/Samsung-S3C24XX/Suspend.txt
index 0dab6e32c130..a30fe510572b 100644
--- a/Documentation/arm/Samsung-S3C24XX/Suspend.txt
+++ b/Documentation/arm/Samsung-S3C24XX/Suspend.txt
@@ -40,13 +40,13 @@ Resuming
Machine Support
---------------
- The machine specific functions must call the s3c2410_pm_init() function
+ The machine specific functions must call the s3c_pm_init() function
to say that its bootloader is capable of resuming. This can be as
simple as adding the following to the machine's definition:
- INITMACHINE(s3c2410_pm_init)
+ INITMACHINE(s3c_pm_init)
- A board can do its own setup before calling s3c2410_pm_init, if it
+ A board can do its own setup before calling s3c_pm_init, if it
needs to setup anything else for power management support.
There is currently no support for over-riding the default method of
@@ -74,7 +74,7 @@ statuc void __init machine_init(void)
enable_irq_wake(IRQ_EINT0);
- s3c2410_pm_init();
+ s3c_pm_init();
}
diff --git a/Documentation/arm/memory.txt b/Documentation/arm/memory.txt
index dc6045577a8b..43cb1004d35f 100644
--- a/Documentation/arm/memory.txt
+++ b/Documentation/arm/memory.txt
@@ -29,7 +29,14 @@ ffff0000 ffff0fff CPU vector page.
CPU supports vector relocation (control
register V bit.)
-ffc00000 fffeffff DMA memory mapping region. Memory returned
+fffe0000 fffeffff XScale cache flush area. This is used
+ in proc-xscale.S to flush the whole data
+ cache. Free for other usage on non-XScale.
+
+fff00000 fffdffff Fixmap mapping region. Addresses provided
+ by fix_to_virt() will be located here.
+
+ffc00000 ffefffff DMA memory mapping region. Memory returned
by the dma_alloc_xxx functions will be
dynamically mapped here.
diff --git a/Documentation/block/switching-sched.txt b/Documentation/block/switching-sched.txt
index 634c952e1964..d5af3f630814 100644
--- a/Documentation/block/switching-sched.txt
+++ b/Documentation/block/switching-sched.txt
@@ -35,9 +35,3 @@ noop anticipatory deadline [cfq]
# echo anticipatory > /sys/block/hda/queue/scheduler
# cat /sys/block/hda/queue/scheduler
noop [anticipatory] deadline cfq
-
-Each io queue has a set of io scheduler tunables associated with it. These
-tunables control how the io scheduler works. You can find these entries
-in:
-
-/sys/block/<device>/queue/iosched
diff --git a/Documentation/cgroups/00-INDEX b/Documentation/cgroups/00-INDEX
new file mode 100644
index 000000000000..3f58fa3d6d00
--- /dev/null
+++ b/Documentation/cgroups/00-INDEX
@@ -0,0 +1,18 @@
+00-INDEX
+ - this file
+cgroups.txt
+ - Control Groups definition, implementation details, examples and API.
+cpuacct.txt
+ - CPU Accounting Controller; account CPU usage for groups of tasks.
+cpusets.txt
+ - documents the cpusets feature; assign CPUs and Mem to a set of tasks.
+devices.txt
+ - Device Whitelist Controller; description, interface and security.
+freezer-subsystem.txt
+ - checkpointing; rationale to not use signals, interface.
+memcg_test.txt
+ - Memory Resource Controller; implementation details.
+memory.txt
+ - Memory Resource Controller; design, accounting, interface, testing.
+resource_counter.txt
+ - Resource Counter API.
diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt
index 93feb8444489..6eb1a97e88ce 100644
--- a/Documentation/cgroups/cgroups.txt
+++ b/Documentation/cgroups/cgroups.txt
@@ -56,7 +56,7 @@ hierarchy, and a set of subsystems; each subsystem has system-specific
state attached to each cgroup in the hierarchy. Each hierarchy has
an instance of the cgroup virtual filesystem associated with it.
-At any one time there may be multiple active hierachies of task
+At any one time there may be multiple active hierarchies of task
cgroups. Each hierarchy is a partition of all tasks in the system.
User level code may create and destroy cgroups by name in an
@@ -124,10 +124,10 @@ following lines:
/ \
Prof (15%) students (5%)
-Browsers like firefox/lynx go into the WWW network class, while (k)nfsd go
+Browsers like Firefox/Lynx go into the WWW network class, while (k)nfsd go
into NFS network class.
-At the same time firefox/lynx will share an appropriate CPU/Memory class
+At the same time Firefox/Lynx will share an appropriate CPU/Memory class
depending on who launched it (prof/student).
With the ability to classify tasks differently for different resources
@@ -325,7 +325,7 @@ and then start a subshell 'sh' in that cgroup:
Creating, modifying, using the cgroups can be done through the cgroup
virtual filesystem.
-To mount a cgroup hierarchy will all available subsystems, type:
+To mount a cgroup hierarchy with all available subsystems, type:
# mount -t cgroup xxx /dev/cgroup
The "xxx" is not interpreted by the cgroup code, but will appear in
@@ -333,12 +333,23 @@ The "xxx" is not interpreted by the cgroup code, but will appear in
To mount a cgroup hierarchy with just the cpuset and numtasks
subsystems, type:
-# mount -t cgroup -o cpuset,numtasks hier1 /dev/cgroup
+# mount -t cgroup -o cpuset,memory hier1 /dev/cgroup
To change the set of subsystems bound to a mounted hierarchy, just
remount with different options:
+# mount -o remount,cpuset,ns hier1 /dev/cgroup
-# mount -o remount,cpuset,ns /dev/cgroup
+Now memory is removed from the hierarchy and ns is added.
+
+Note this will add ns to the hierarchy but won't remove memory or
+cpuset, because the new options are appended to the old ones:
+# mount -o remount,ns /dev/cgroup
+
+To Specify a hierarchy's release_agent:
+# mount -t cgroup -o cpuset,release_agent="/sbin/cpuset_release_agent" \
+ xxx /dev/cgroup
+
+Note that specifying 'release_agent' more than once will return failure.
Note that changing the set of subsystems is currently only supported
when the hierarchy consists of a single (root) cgroup. Supporting
@@ -349,6 +360,11 @@ Then under /dev/cgroup you can find a tree that corresponds to the
tree of the cgroups in the system. For instance, /dev/cgroup
is the cgroup that holds the whole system.
+If you want to change the value of release_agent:
+# echo "/sbin/new_release_agent" > /dev/cgroup/release_agent
+
+It can also be changed via remount.
+
If you want to create a new cgroup under /dev/cgroup:
# cd /dev/cgroup
# mkdir my_cgroup
@@ -476,11 +492,13 @@ cgroup->parent is still valid. (Note - can also be called for a
newly-created cgroup if an error occurs after this subsystem's
create() method has been called for the new cgroup).
-void pre_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
+int pre_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
Called before checking the reference count on each subsystem. This may
be useful for subsystems which have some extra references even if
-there are not tasks in the cgroup.
+there are not tasks in the cgroup. If pre_destroy() returns error code,
+rmdir() will fail with it. From this behavior, pre_destroy() can be
+called multiple times against a cgroup.
int can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
struct task_struct *task)
@@ -521,7 +539,7 @@ always handled well.
void post_clone(struct cgroup_subsys *ss, struct cgroup *cgrp)
(cgroup_mutex held by caller)
-Called at the end of cgroup_clone() to do any paramater
+Called at the end of cgroup_clone() to do any parameter
initialization which might be required before a task could attach. For
example in cpusets, no task may attach before 'cpus' and 'mems' are set
up.
diff --git a/Documentation/cgroups/cpusets.txt b/Documentation/cgroups/cpusets.txt
index 0611e9528c7c..f9ca389dddf4 100644
--- a/Documentation/cgroups/cpusets.txt
+++ b/Documentation/cgroups/cpusets.txt
@@ -131,7 +131,7 @@ Cpusets extends these two mechanisms as follows:
- The hierarchy of cpusets can be mounted at /dev/cpuset, for
browsing and manipulation from user space.
- A cpuset may be marked exclusive, which ensures that no other
- cpuset (except direct ancestors and descendents) may contain
+ cpuset (except direct ancestors and descendants) may contain
any overlapping CPUs or Memory Nodes.
- You can list all the tasks (by pid) attached to any cpuset.
@@ -226,7 +226,7 @@ nodes with memory--using the cpuset_track_online_nodes() hook.
--------------------------------
If a cpuset is cpu or mem exclusive, no other cpuset, other than
-a direct ancestor or descendent, may share any of the same CPUs or
+a direct ancestor or descendant, may share any of the same CPUs or
Memory Nodes.
A cpuset that is mem_exclusive *or* mem_hardwall is "hardwalled",
@@ -427,7 +427,7 @@ child cpusets have this flag enabled.
When doing this, you don't usually want to leave any unpinned tasks in
the top cpuset that might use non-trivial amounts of CPU, as such tasks
may be artificially constrained to some subset of CPUs, depending on
-the particulars of this flag setting in descendent cpusets. Even if
+the particulars of this flag setting in descendant cpusets. Even if
such a task could use spare CPU cycles in some other CPUs, the kernel
scheduler might not consider the possibility of load balancing that
task to that underused CPU.
@@ -531,9 +531,9 @@ be idle.
Of course it takes some searching cost to find movable tasks and/or
idle CPUs, the scheduler might not search all CPUs in the domain
-everytime. In fact, in some architectures, the searching ranges on
+every time. In fact, in some architectures, the searching ranges on
events are limited in the same socket or node where the CPU locates,
-while the load balance on tick searchs all.
+while the load balance on tick searches all.
For example, assume CPU Z is relatively far from CPU X. Even if CPU Z
is idle while CPU X and the siblings are busy, scheduler can't migrate
@@ -601,7 +601,7 @@ its new cpuset, then the task will continue to use whatever subset
of MPOL_BIND nodes are still allowed in the new cpuset. If the task
was using MPOL_BIND and now none of its MPOL_BIND nodes are allowed
in the new cpuset, then the task will be essentially treated as if it
-was MPOL_BIND bound to the new cpuset (even though its numa placement,
+was MPOL_BIND bound to the new cpuset (even though its NUMA placement,
as queried by get_mempolicy(), doesn't change). If a task is moved
from one cpuset to another, then the kernel will adjust the tasks
memory placement, as above, the next time that the kernel attempts
diff --git a/Documentation/cgroups/devices.txt b/Documentation/cgroups/devices.txt
index 7cc6e6a60672..57ca4c89fe5c 100644
--- a/Documentation/cgroups/devices.txt
+++ b/Documentation/cgroups/devices.txt
@@ -42,7 +42,7 @@ suffice, but we can decide the best way to adequately restrict
movement as people get some experience with this. We may just want
to require CAP_SYS_ADMIN, which at least is a separate bit from
CAP_MKNOD. We may want to just refuse moving to a cgroup which
-isn't a descendent of the current one. Or we may want to use
+isn't a descendant of the current one. Or we may want to use
CAP_MAC_ADMIN, since we really are trying to lock down root.
CAP_SYS_ADMIN is needed to modify the whitelist or move another
diff --git a/Documentation/cgroups/memcg_test.txt b/Documentation/cgroups/memcg_test.txt
index 523a9c16c400..72db89ed0609 100644
--- a/Documentation/cgroups/memcg_test.txt
+++ b/Documentation/cgroups/memcg_test.txt
@@ -1,5 +1,5 @@
Memory Resource Controller(Memcg) Implementation Memo.
-Last Updated: 2009/1/19
+Last Updated: 2009/1/20
Base Kernel Version: based on 2.6.29-rc2.
Because VM is getting complex (one of reasons is memcg...), memcg's behavior
@@ -356,7 +356,25 @@ Under below explanation, we assume CONFIG_MEM_RES_CTRL_SWAP=y.
(Shell-B)
# move all tasks in /cgroup/test to /cgroup
# /sbin/swapoff -a
- # rmdir /test/cgroup
+ # rmdir /cgroup/test
# kill malloc task.
Of course, tmpfs v.s. swapoff test should be tested, too.
+
+ 9.8 OOM-Killer
+ Out-of-memory caused by memcg's limit will kill tasks under
+ the memcg. When hierarchy is used, a task under hierarchy
+ will be killed by the kernel.
+ In this case, panic_on_oom shouldn't be invoked and tasks
+ in other groups shouldn't be killed.
+
+ It's not difficult to cause OOM under memcg as following.
+ Case A) when you can swapoff
+ #swapoff -a
+ #echo 50M > /memory.limit_in_bytes
+ run 51M of malloc
+
+ Case B) when you use mem+swap limitation.
+ #echo 50M > memory.limit_in_bytes
+ #echo 50M > memory.memsw.limit_in_bytes
+ run 51M of malloc
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
index e1501964df1e..a98a7fe7aabb 100644
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -302,7 +302,7 @@ will be charged as a new owner of it.
unevictable - # of pages cannot be reclaimed.(mlocked etc)
Below is depend on CONFIG_DEBUG_VM.
- inactive_ratio - VM inernal parameter. (see mm/page_alloc.c)
+ inactive_ratio - VM internal parameter. (see mm/page_alloc.c)
recent_rotated_anon - VM internal parameter. (see mm/vmscan.c)
recent_rotated_file - VM internal parameter. (see mm/vmscan.c)
recent_scanned_anon - VM internal parameter. (see mm/vmscan.c)
diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt
index 5b0cfa67aff9..ce73f3eb5ddb 100644
--- a/Documentation/cpu-freq/governors.txt
+++ b/Documentation/cpu-freq/governors.txt
@@ -117,10 +117,28 @@ accessible parameters:
sampling_rate: measured in uS (10^-6 seconds), this is how often you
want the kernel to look at the CPU usage and to make decisions on
what to do about the frequency. Typically this is set to values of
-around '10000' or more.
-
-show_sampling_rate_(min|max): the minimum and maximum sampling rates
-available that you may set 'sampling_rate' to.
+around '10000' or more. It's default value is (cmp. with users-guide.txt):
+transition_latency * 1000
+The lowest value you can set is:
+transition_latency * 100 or it may get restricted to a value where it
+makes not sense for the kernel anymore to poll that often which depends
+on your HZ config variable (HZ=1000: max=20000us, HZ=250: max=5000).
+Be aware that transition latency is in ns and sampling_rate is in us, so you
+get the same sysfs value by default.
+Sampling rate should always get adjusted considering the transition latency
+To set the sampling rate 750 times as high as the transition latency
+in the bash (as said, 1000 is default), do:
+echo `$(($(cat cpuinfo_transition_latency) * 750 / 1000)) \
+ >ondemand/sampling_rate
+
+show_sampling_rate_(min|max): THIS INTERFACE IS DEPRECATED, DON'T USE IT.
+You can use wider ranges now and the general
+cpuinfo_transition_latency variable (cmp. with user-guide.txt) can be
+used to obtain exactly the same info:
+show_sampling_rate_min = transtition_latency * 500 / 1000
+show_sampling_rate_max = transtition_latency * 500000 / 1000
+(divided by 1000 is to illustrate that sampling rate is in us and
+transition latency is exported ns).
up_threshold: defines what the average CPU usage between the samplings
of 'sampling_rate' needs to be for the kernel to make a decision on
diff --git a/Documentation/cpu-freq/user-guide.txt b/Documentation/cpu-freq/user-guide.txt
index 917918f84fc7..75f41193f3e1 100644
--- a/Documentation/cpu-freq/user-guide.txt
+++ b/Documentation/cpu-freq/user-guide.txt
@@ -152,6 +152,18 @@ cpuinfo_min_freq : this file shows the minimum operating
frequency the processor can run at(in kHz)
cpuinfo_max_freq : this file shows the maximum operating
frequency the processor can run at(in kHz)
+cpuinfo_transition_latency The time it takes on this CPU to
+ switch between two frequencies in nano
+ seconds. If unknown or known to be
+ that high that the driver does not
+ work with the ondemand governor, -1
+ (CPUFREQ_ETERNAL) will be returned.
+ Using this information can be useful
+ to choose an appropriate polling
+ frequency for a kernel governor or
+ userspace daemon. Make sure to not
+ switch the frequency too often
+ resulting in performance loss.
scaling_driver : this file shows what cpufreq driver is
used to set the frequency on this CPU
diff --git a/Documentation/devices.txt b/Documentation/devices.txt
index 2be08240ee80..4d70df63d1d3 100644
--- a/Documentation/devices.txt
+++ b/Documentation/devices.txt
@@ -1,9 +1,9 @@
LINUX ALLOCATED DEVICES (2.6+ version)
- Maintained by Torben Mathiasen <device@lanana.org>
+ Maintained by Alan Cox <device@lanana.org>
- Last revised: 29 November 2006
+ Last revised: 6th April 2009
This list is the Linux Device List, the official registry of allocated
device numbers and /dev directory nodes for the Linux operating
@@ -67,6 +67,11 @@ up to date. Due to the number of registrations I have to maintain it
in "batch mode", so there is likely additional registrations that
haven't been listed yet.
+Fourth, remember that Linux now has extensive support for dynamic allocation
+of device numbering and can use sysfs and udev to handle the naming needs.
+There are still some exceptions in the serial and boot device area. Before
+asking for a device number make sure you actually need one.
+
Finally, sometimes I have to play "namespace police." Please don't be
offended. I often get submissions for /dev names that would be bound
to cause conflicts down the road. I am trying to avoid getting in a
@@ -101,7 +106,7 @@ Your cooperation is appreciated.
0 = /dev/ram0 First RAM disk
1 = /dev/ram1 Second RAM disk
...
- 250 = /dev/initrd Initial RAM disk {2.6}
+ 250 = /dev/initrd Initial RAM disk
Older kernels had /dev/ramdisk (1, 1) here.
/dev/initrd refers to a RAM disk which was preloaded
@@ -340,7 +345,7 @@ Your cooperation is appreciated.
14 = /dev/touchscreen/ucb1x00 UCB 1x00 touchscreen
15 = /dev/touchscreen/mk712 MK712 touchscreen
128 = /dev/beep Fancy beep device
- 129 = /dev/modreq Kernel module load request {2.6}
+ 129 =
130 = /dev/watchdog Watchdog timer port
131 = /dev/temperature Machine internal temperature
132 = /dev/hwtrap Hardware fault trap
@@ -350,10 +355,10 @@ Your cooperation is appreciated.
139 = /dev/openprom SPARC OpenBoot PROM
140 = /dev/relay8 Berkshire Products Octal relay card
141 = /dev/relay16 Berkshire Products ISO-16 relay card
- 142 = /dev/msr x86 model-specific registers {2.6}
+ 142 =
143 = /dev/pciconf PCI configuration space
144 = /dev/nvram Non-volatile configuration RAM
- 145 = /dev/hfmodem Soundcard shortwave modem control {2.6}
+ 145 = /dev/hfmodem Soundcard shortwave modem control
146 = /dev/graphics Linux/SGI graphics device
147 = /dev/opengl Linux/SGI OpenGL pipe
148 = /dev/gfx Linux/SGI graphics effects device
@@ -435,6 +440,9 @@ Your cooperation is appreciated.
228 = /dev/hpet HPET driver
229 = /dev/fuse Fuse (virtual filesystem in user-space)
230 = /dev/midishare MidiShare driver
+ 231 = /dev/snapshot System memory snapshot device
+ 232 = /dev/kvm Kernel-based virtual machine (hardware virtualization extensions)
+ 233 = /dev/kmview View-OS A process with a view
240-254 Reserved for local use
255 Reserved for MISC_DYNAMIC_MINOR
@@ -466,10 +474,7 @@ Your cooperation is appreciated.
The device names specified are proposed -- if there
are "standard" names for these devices, please let me know.
- 12 block MSCDEX CD-ROM callback support {2.6}
- 0 = /dev/dos_cd0 First MSCDEX CD-ROM
- 1 = /dev/dos_cd1 Second MSCDEX CD-ROM
- ...
+ 12 block
13 char Input core
0 = /dev/input/js0 First joystick
@@ -498,7 +503,7 @@ Your cooperation is appreciated.
2 = /dev/midi00 First MIDI port
3 = /dev/dsp Digital audio
4 = /dev/audio Sun-compatible digital audio
- 6 = /dev/sndstat Sound card status information {2.6}
+ 6 =
7 = /dev/audioctl SPARC audio control device
8 = /dev/sequencer2 Sequencer -- alternate device
16 = /dev/mixer1 Second soundcard mixer control
@@ -510,14 +515,7 @@ Your cooperation is appreciated.
34 = /dev/midi02 Third MIDI port
50 = /dev/midi03 Fourth MIDI port
- 14 block BIOS harddrive callback support {2.6}
- 0 = /dev/dos_hda First BIOS harddrive whole disk
- 64 = /dev/dos_hdb Second BIOS harddrive whole disk
- 128 = /dev/dos_hdc Third BIOS harddrive whole disk
- 192 = /dev/dos_hdd Fourth BIOS harddrive whole disk
-
- Partitions are handled in the same way as IDE disks
- (see major number 3).
+ 14 block
15 char Joystick
0 = /dev/js0 First analog joystick
@@ -535,14 +533,14 @@ Your cooperation is appreciated.
16 block GoldStar CD-ROM
0 = /dev/gscd GoldStar CD-ROM
- 17 char Chase serial card
+ 17 char OBSOLETE (was Chase serial card)
0 = /dev/ttyH0 First Chase port
1 = /dev/ttyH1 Second Chase port
...
17 block Optics Storage CD-ROM
0 = /dev/optcd Optics Storage CD-ROM
- 18 char Chase serial card - alternate devices
+ 18 char OBSOLETE (was Chase serial card - alternate devices)
0 = /dev/cuh0 Callout device for ttyH0
1 = /dev/cuh1 Callout device for ttyH1
...
@@ -644,8 +642,7 @@ Your cooperation is appreciated.
2 = /dev/sbpcd2 Panasonic CD-ROM controller 0 unit 2
3 = /dev/sbpcd3 Panasonic CD-ROM controller 0 unit 3
- 26 char Quanta WinVision frame grabber {2.6}
- 0 = /dev/wvisfgrab Quanta WinVision frame grabber
+ 26 char
26 block Second Matsushita (Panasonic/SoundBlaster) CD-ROM
0 = /dev/sbpcd4 Panasonic CD-ROM controller 1 unit 0
@@ -872,7 +869,7 @@ Your cooperation is appreciated.
and "user level packet I/O." This board is also
accessible as a standard networking "eth" device.
- 38 block Reserved for Linux/AP+
+ 38 block OBSOLETE (was Linux/AP+)
39 char ML-16P experimental I/O board
0 = /dev/ml16pa-a0 First card, first analog channel
@@ -892,29 +889,16 @@ Your cooperation is appreciated.
50 = /dev/ml16pb-c1 Second card, second counter/timer
51 = /dev/ml16pb-c2 Second card, third counter/timer
...
- 39 block Reserved for Linux/AP+
+ 39 block
- 40 char Matrox Meteor frame grabber {2.6}
- 0 = /dev/mmetfgrab Matrox Meteor frame grabber
+ 40 char
- 40 block Syquest EZ135 parallel port removable drive
- 0 = /dev/eza Parallel EZ135 drive, whole disk
-
- This device is obsolete and will be removed in a
- future version of Linux. It has been replaced with
- the parallel port IDE disk driver at major number 45.
- Partitions are handled in the same way as IDE disks
- (see major number 3).
+ 40 block
41 char Yet Another Micro Monitor
0 = /dev/yamm Yet Another Micro Monitor
- 41 block MicroSolutions BackPack parallel port CD-ROM
- 0 = /dev/bpcd BackPack CD-ROM
-
- This device is obsolete and will be removed in a
- future version of Linux. It has been replaced with
- the parallel port ATAPI CD-ROM driver at major number 46.
+ 41 block
42 char Demo/sample use
@@ -1681,13 +1665,7 @@ Your cooperation is appreciated.
disks (see major number 3) except that the limit on
partitions is 15.
- 93 char IBM Smart Capture Card frame grabber {2.6}
- 0 = /dev/iscc0 First Smart Capture Card
- 1 = /dev/iscc1 Second Smart Capture Card
- ...
- 128 = /dev/isccctl0 First Smart Capture Card control
- 129 = /dev/isccctl1 Second Smart Capture Card control
- ...
+ 93 char
93 block NAND Flash Translation Layer filesystem
0 = /dev/nftla First NFTL layer
@@ -1695,10 +1673,7 @@ Your cooperation is appreciated.
...
240 = /dev/nftlp 16th NTFL layer
- 94 char miroVIDEO DC10/30 capture/playback device {2.6}
- 0 = /dev/dcxx0 First capture card
- 1 = /dev/dcxx1 Second capture card
- ...
+ 94 char
94 block IBM S/390 DASD block storage
0 = /dev/dasda First DASD device, major
@@ -1791,11 +1766,7 @@ Your cooperation is appreciated.
...
15 = /dev/amiraid/ar?p15 15th partition
-102 char Philips SAA5249 Teletext signal decoder {2.6}
- 0 = /dev/tlk0 First Teletext decoder
- 1 = /dev/tlk1 Second Teletext decoder
- 2 = /dev/tlk2 Third Teletext decoder
- 3 = /dev/tlk3 Fourth Teletext decoder
+102 char
102 block Compressed block device
0 = /dev/cbd/a First compressed block device, whole device
@@ -1916,10 +1887,7 @@ Your cooperation is appreciated.
DAC960 (see major number 48) except that the limit on
partitions is 15.
-111 char Philips SAA7146-based audio/video card {2.6}
- 0 = /dev/av0 First A/V card
- 1 = /dev/av1 Second A/V card
- ...
+111 char
111 block Compaq Next Generation Drive Array, eighth controller
0 = /dev/cciss/c7d0 First logical drive, whole disk
@@ -2079,8 +2047,8 @@ Your cooperation is appreciated.
...
119 char VMware virtual network control
- 0 = /dev/vmnet0 1st virtual network
- 1 = /dev/vmnet1 2nd virtual network
+ 0 = /dev/vnet0 1st virtual network
+ 1 = /dev/vnet1 2nd virtual network
...
120-127 char LOCAL/EXPERIMENTAL USE
@@ -2450,7 +2418,7 @@ Your cooperation is appreciated.
2 = /dev/raw/raw2 Second raw I/O device
...
-163 char UNASSIGNED (was Radio Tech BIM-XXX-RS232 radio modem - see 51)
+163 char
164 char Chase Research AT/PCI-Fast serial card
0 = /dev/ttyCH0 AT/PCI-Fast board 0, port 0
@@ -2542,6 +2510,12 @@ Your cooperation is appreciated.
1 = /dev/clanvi1 Second cLAN adapter
...
+179 block MMC block devices
+ 0 = /dev/mmcblk0 First SD/MMC card
+ 1 = /dev/mmcblk0p1 First partition on first MMC card
+ 8 = /dev/mmcblk1 Second SD/MMC card
+ ...
+
179 char CCube DVXChip-based PCI products
0 = /dev/dvxirq0 First DVX device
1 = /dev/dvxirq1 Second DVX device
@@ -2560,6 +2534,9 @@ Your cooperation is appreciated.
96 = /dev/usb/hiddev0 1st USB HID device
...
111 = /dev/usb/hiddev15 16th USB HID device
+ 112 = /dev/usb/auer0 1st auerswald ISDN device
+ ...
+ 127 = /dev/usb/auer15 16th auerswald ISDN device
128 = /dev/usb/brlvgr0 First Braille Voyager device
...
131 = /dev/usb/brlvgr3 Fourth Braille Voyager device
@@ -2810,6 +2787,16 @@ Your cooperation is appreciated.
...
190 = /dev/ttyUL3 Xilinx uartlite - port 3
191 = /dev/xvc0 Xen virtual console - port 0
+ 192 = /dev/ttyPZ0 pmac_zilog - port 0
+ ...
+ 195 = /dev/ttyPZ3 pmac_zilog - port 3
+ 196 = /dev/ttyTX0 TX39/49 serial port 0
+ ...
+ 204 = /dev/ttyTX7 TX39/49 serial port 7
+ 205 = /dev/ttySC0 SC26xx serial port 0
+ 206 = /dev/ttySC1 SC26xx serial port 1
+ 207 = /dev/ttySC2 SC26xx serial port 2
+ 208 = /dev/ttySC3 SC26xx serial port 3
205 char Low-density serial ports (alternate device)
0 = /dev/culu0 Callout device for ttyLU0
@@ -3145,6 +3132,20 @@ Your cooperation is appreciated.
1 = /dev/blockrom1 Second ROM card's translation layer interface
...
+259 block Block Extended Major
+ Used dynamically to hold additional partition minor
+ numbers and allow large numbers of partitions per device
+
+259 char FPGA configuration interfaces
+ 0 = /dev/icap0 First Xilinx internal configuration
+ 1 = /dev/icap1 Second Xilinx internal configuration
+
+260 char OSD (Object-based-device) SCSI Device
+ 0 = /dev/osd0 First OSD Device
+ 1 = /dev/osd1 Second OSD Device
+ ...
+ 255 = /dev/osd255 256th OSD Device
+
**** ADDITIONAL /dev DIRECTORY ENTRIES
This section details additional entries that should or may exist in
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 1e89a51ea49b..88519daab6e9 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -62,7 +62,6 @@ aic7*reg_print.c*
aic7*seq.h*
aicasm
aicdb.h*
-asm
asm-offsets.h
asm_offsets.h
autoconf.h*
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index f2e908d7f90d..2f21ecd4c205 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -25,7 +25,7 @@ use IO::Handle;
"tda10046lifeview", "av7110", "dec2000t", "dec2540t",
"dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
"or51211", "or51132_qam", "or51132_vsb", "bluebird",
- "opera1");
+ "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2" );
# Check args
syntax() if (scalar(@ARGV) != 1);
@@ -37,8 +37,8 @@ for ($i=0; $i < scalar(@components); $i++) {
$outfile = eval($cid);
die $@ if $@;
print STDERR <<EOF;
-Firmware $outfile extracted successfully.
-Now copy it to either /usr/lib/hotplug/firmware or /lib/firmware
+Firmware(s) $outfile extracted successfully.
+Now copy it(they) to either /usr/lib/hotplug/firmware or /lib/firmware
(depending on configuration of firmware hotplug).
EOF
exit(0);
@@ -345,6 +345,85 @@ sub or51211 {
$fwfile;
}
+sub cx231xx {
+ my $fwfile = "v4l-cx231xx-avcore-01.fw";
+ my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
+ my $hash = "7d3bb956dc9df0eafded2b56ba57cc42";
+
+ checkstandard();
+
+ wgetfile($fwfile, $url);
+ verify($fwfile, $hash);
+
+ $fwfile;
+}
+
+sub cx18 {
+ my $url = "http://linuxtv.org/downloads/firmware/";
+
+ my %files = (
+ 'v4l-cx23418-apu.fw' => '588f081b562f5c653a3db1ad8f65939a',
+ 'v4l-cx23418-cpu.fw' => 'b6c7ed64bc44b1a6e0840adaeac39d79',
+ 'v4l-cx23418-dig.fw' => '95bc688d3e7599fd5800161e9971cc55',
+ );
+
+ checkstandard();
+
+ my $allfiles;
+ foreach my $fwfile (keys %files) {
+ wgetfile($fwfile, "$url/$fwfile");
+ verify($fwfile, $files{$fwfile});
+ $allfiles .= " $fwfile";
+ }
+
+ $allfiles =~ s/^\s//;
+
+ $allfiles;
+}
+
+sub cx23885 {
+ my $url = "http://linuxtv.org/downloads/firmware/";
+
+ my %files = (
+ 'v4l-cx23885-avcore-01.fw' => 'a9f8f5d901a7fb42f552e1ee6384f3bb',
+ 'v4l-cx23885-enc.fw' => 'a9f8f5d901a7fb42f552e1ee6384f3bb',
+ );
+
+ checkstandard();
+
+ my $allfiles;
+ foreach my $fwfile (keys %files) {
+ wgetfile($fwfile, "$url/$fwfile");
+ verify($fwfile, $files{$fwfile});
+ $allfiles .= " $fwfile";
+ }
+
+ $allfiles =~ s/^\s//;
+
+ $allfiles;
+}
+
+sub pvrusb2 {
+ my $url = "http://linuxtv.org/downloads/firmware/";
+
+ my %files = (
+ 'v4l-cx25840.fw' => 'dadb79e9904fc8af96e8111d9cb59320',
+ );
+
+ checkstandard();
+
+ my $allfiles;
+ foreach my $fwfile (keys %files) {
+ wgetfile($fwfile, "$url/$fwfile");
+ verify($fwfile, $files{$fwfile});
+ $allfiles .= " $fwfile";
+ }
+
+ $allfiles =~ s/^\s//;
+
+ $allfiles;
+}
+
sub or51132_qam {
my $fwfile = "dvb-fe-or51132-qam.fw";
my $url = "http://linuxtv.org/downloads/firmware/$fwfile";
diff --git a/Documentation/dynamic-debug-howto.txt b/Documentation/dynamic-debug-howto.txt
new file mode 100644
index 000000000000..674c5663d346
--- /dev/null
+++ b/Documentation/dynamic-debug-howto.txt
@@ -0,0 +1,240 @@
+
+Introduction
+============
+
+This document describes how to use the dynamic debug (ddebug) feature.
+
+Dynamic debug is designed to allow you to dynamically enable/disable kernel
+code to obtain additional kernel information. Currently, if
+CONFIG_DYNAMIC_DEBUG is set, then all pr_debug()/dev_debug() calls can be
+dynamically enabled per-callsite.
+
+Dynamic debug has even more useful features:
+
+ * Simple query language allows turning on and off debugging statements by
+ matching any combination of:
+
+ - source filename
+ - function name
+ - line number (including ranges of line numbers)
+ - module name
+ - format string
+
+ * Provides a debugfs control file: <debugfs>/dynamic_debug/control which can be
+ read to display the complete list of known debug statements, to help guide you
+
+Controlling dynamic debug Behaviour
+===============================
+
+The behaviour of pr_debug()/dev_debug()s are controlled via writing to a
+control file in the 'debugfs' filesystem. Thus, you must first mount the debugfs
+filesystem, in order to make use of this feature. Subsequently, we refer to the
+control file as: <debugfs>/dynamic_debug/control. For example, if you want to
+enable printing from source file 'svcsock.c', line 1603 you simply do:
+
+nullarbor:~ # echo 'file svcsock.c line 1603 +p' >
+ <debugfs>/dynamic_debug/control
+
+If you make a mistake with the syntax, the write will fail thus:
+
+nullarbor:~ # echo 'file svcsock.c wtf 1 +p' >
+ <debugfs>/dynamic_debug/control
+-bash: echo: write error: Invalid argument
+
+Viewing Dynamic Debug Behaviour
+===========================
+
+You can view the currently configured behaviour of all the debug statements
+via:
+
+nullarbor:~ # cat <debugfs>/dynamic_debug/control
+# filename:lineno [module]function flags format
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:323 [svcxprt_rdma]svc_rdma_cleanup - "SVCRDMA Module Removed, deregister RPC RDMA transport\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:341 [svcxprt_rdma]svc_rdma_init - "\011max_inline : %d\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:340 [svcxprt_rdma]svc_rdma_init - "\011sq_depth : %d\012"
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:338 [svcxprt_rdma]svc_rdma_init - "\011max_requests : %d\012"
+...
+
+
+You can also apply standard Unix text manipulation filters to this
+data, e.g.
+
+nullarbor:~ # grep -i rdma <debugfs>/dynamic_debug/control | wc -l
+62
+
+nullarbor:~ # grep -i tcp <debugfs>/dynamic_debug/control | wc -l
+42
+
+Note in particular that the third column shows the enabled behaviour
+flags for each debug statement callsite (see below for definitions of the
+flags). The default value, no extra behaviour enabled, is "-". So
+you can view all the debug statement callsites with any non-default flags:
+
+nullarbor:~ # awk '$3 != "-"' <debugfs>/dynamic_debug/control
+# filename:lineno [module]function flags format
+/usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c:1603 [sunrpc]svc_send p "svc_process: st_sendto returned %d\012"
+
+
+Command Language Reference
+==========================
+
+At the lexical level, a command comprises a sequence of words separated
+by whitespace characters. Note that newlines are treated as word
+separators and do *not* end a command or allow multiple commands to
+be done together. So these are all equivalent:
+
+nullarbor:~ # echo -c 'file svcsock.c line 1603 +p' >
+ <debugfs>/dynamic_debug/control
+nullarbor:~ # echo -c ' file svcsock.c line 1603 +p ' >
+ <debugfs>/dynamic_debug/control
+nullarbor:~ # echo -c 'file svcsock.c\nline 1603 +p' >
+ <debugfs>/dynamic_debug/control
+nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
+ <debugfs>/dynamic_debug/control
+
+Commands are bounded by a write() system call. If you want to do
+multiple commands you need to do a separate "echo" for each, like:
+
+nullarbor:~ # echo 'file svcsock.c line 1603 +p' > /proc/dprintk ;\
+> echo 'file svcsock.c line 1563 +p' > /proc/dprintk
+
+or even like:
+
+nullarbor:~ # (
+> echo 'file svcsock.c line 1603 +p' ;\
+> echo 'file svcsock.c line 1563 +p' ;\
+> ) > /proc/dprintk
+
+At the syntactical level, a command comprises a sequence of match
+specifications, followed by a flags change specification.
+
+command ::= match-spec* flags-spec
+
+The match-spec's are used to choose a subset of the known dprintk()
+callsites to which to apply the flags-spec. Think of them as a query
+with implicit ANDs between each pair. Note that an empty list of
+match-specs is possible, but is not very useful because it will not
+match any debug statement callsites.
+
+A match specification comprises a keyword, which controls the attribute
+of the callsite to be compared, and a value to compare against. Possible
+keywords are:
+
+match-spec ::= 'func' string |
+ 'file' string |
+ 'module' string |
+ 'format' string |
+ 'line' line-range
+
+line-range ::= lineno |
+ '-'lineno |
+ lineno'-' |
+ lineno'-'lineno
+// Note: line-range cannot contain space, e.g.
+// "1-30" is valid range but "1 - 30" is not.
+
+lineno ::= unsigned-int
+
+The meanings of each keyword are:
+
+func
+ The given string is compared against the function name
+ of each callsite. Example:
+
+ func svc_tcp_accept
+
+file
+ The given string is compared against either the full
+ pathname or the basename of the source file of each
+ callsite. Examples:
+
+ file svcsock.c
+ file /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c
+
+module
+ The given string is compared against the module name
+ of each callsite. The module name is the string as
+ seen in "lsmod", i.e. without the directory or the .ko
+ suffix and with '-' changed to '_'. Examples:
+
+ module sunrpc
+ module nfsd
+
+format
+ The given string is searched for in the dynamic debug format
+ string. Note that the string does not need to match the
+ entire format, only some part. Whitespace and other
+ special characters can be escaped using C octal character
+ escape \ooo notation, e.g. the space character is \040.
+ Alternatively, the string can be enclosed in double quote
+ characters (") or single quote characters (').
+ Examples:
+
+ format svcrdma: // many of the NFS/RDMA server dprintks
+ format readahead // some dprintks in the readahead cache
+ format nfsd:\040SETATTR // one way to match a format with whitespace
+ format "nfsd: SETATTR" // a neater way to match a format with whitespace
+ format 'nfsd: SETATTR' // yet another way to match a format with whitespace
+
+line
+ The given line number or range of line numbers is compared
+ against the line number of each dprintk() callsite. A single
+ line number matches the callsite line number exactly. A
+ range of line numbers matches any callsite between the first
+ and last line number inclusive. An empty first number means
+ the first line in the file, an empty line number means the
+ last number in the file. Examples:
+
+ line 1603 // exactly line 1603
+ line 1600-1605 // the six lines from line 1600 to line 1605
+ line -1605 // the 1605 lines from line 1 to line 1605
+ line 1600- // all lines from line 1600 to the end of the file
+
+The flags specification comprises a change operation followed
+by one or more flag characters. The change operation is one
+of the characters:
+
+-
+ remove the given flags
+
++
+ add the given flags
+
+=
+ set the flags to the given flags
+
+The flags are:
+
+p
+ Causes a printk() message to be emitted to dmesg
+
+Note the regexp ^[-+=][scp]+$ matches a flags specification.
+Note also that there is no convenient syntax to remove all
+the flags at once, you need to use "-psc".
+
+Examples
+========
+
+// enable the message at line 1603 of file svcsock.c
+nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' >
+ <debugfs>/dynamic_debug/control
+
+// enable all the messages in file svcsock.c
+nullarbor:~ # echo -n 'file svcsock.c +p' >
+ <debugfs>/dynamic_debug/control
+
+// enable all the messages in the NFS server module
+nullarbor:~ # echo -n 'module nfsd +p' >
+ <debugfs>/dynamic_debug/control
+
+// enable all 12 messages in the function svc_process()
+nullarbor:~ # echo -n 'func svc_process +p' >
+ <debugfs>/dynamic_debug/control
+
+// disable all 12 messages in the function svc_process()
+nullarbor:~ # echo -n 'func svc_process -p' >
+ <debugfs>/dynamic_debug/control
+
+// enable messages for NFS calls READ, READLINK, READDIR and READDIR+.
+nullarbor:~ # echo -n 'format "nfsd: READ" +p' >
+ <debugfs>/dynamic_debug/control
diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX
index caabbd395e61..a618fd99c9f0 100644
--- a/Documentation/fb/00-INDEX
+++ b/Documentation/fb/00-INDEX
@@ -11,8 +11,6 @@ aty128fb.txt
- info on the ATI Rage128 frame buffer driver.
cirrusfb.txt
- info on the driver for Cirrus Logic chipsets.
-cyblafb/
- - directory with documentation files related to the cyblafb driver.
deferred_io.txt
- an introduction to deferred IO.
fbcon.txt
diff --git a/Documentation/fb/cyblafb/bugs b/Documentation/fb/cyblafb/bugs
deleted file mode 100644
index 9443a6d72cdd..000000000000
--- a/Documentation/fb/cyblafb/bugs
+++ /dev/null
@@ -1,13 +0,0 @@
-Bugs
-====
-
-I currently don't know of any bug. Please do send reports to:
- - linux-fbdev-devel@lists.sourceforge.net
- - Knut_Petersen@t-online.de.
-
-
-Untested features
-=================
-
-All LCD stuff is untested. If it worked in tridentfb, it should work in
-cyblafb. Please test and report the results to Knut_Petersen@t-online.de.
diff --git a/Documentation/fb/cyblafb/credits b/Documentation/fb/cyblafb/credits
deleted file mode 100644
index 0eb3b443dc2b..000000000000
--- a/Documentation/fb/cyblafb/credits
+++ /dev/null
@@ -1,7 +0,0 @@
-Thanks to
-=========
- * Alan Hourihane, for writing the X trident driver
- * Jani Monoses, for writing the tridentfb driver
- * Antonino A. Daplas, for review of the first published
- version of cyblafb and some code
- * Jochen Hein, for testing and a helpfull bug report
diff --git a/Documentation/fb/cyblafb/documentation b/Documentation/fb/cyblafb/documentation
deleted file mode 100644
index bb1aac048425..000000000000
--- a/Documentation/fb/cyblafb/documentation
+++ /dev/null
@@ -1,17 +0,0 @@
-Available Documentation
-=======================
-
-Apollo PLE 133 Chipset VT8601A North Bridge Datasheet, Rev. 1.82, October 22,
-2001, available from VIA:
-
- http://www.viavpsd.com/product/6/15/DS8601A182.pdf
-
-The datasheet is incomplete, some registers that need to be programmed are not
-explained at all and important bits are listed as "reserved". But you really
-need the datasheet to understand the code. "p. xxx" comments refer to page
-numbers of this document.
-
-XFree/XOrg drivers are available and of good quality, looking at the code
-there is a good idea if the datasheet does not provide enough information
-or if the datasheet seems to be wrong.
-
diff --git a/Documentation/fb/cyblafb/fb.modes b/Documentation/fb/cyblafb/fb.modes
deleted file mode 100644
index fe0e5223ba86..000000000000
--- a/Documentation/fb/cyblafb/fb.modes
+++ /dev/null
@@ -1,154 +0,0 @@
-#
-# Sample fb.modes file
-#
-# Provides an incomplete list of working modes for
-# the cyberblade/i1 graphics core.
-#
-# The value 4294967256 is used instead of -40. Of course, -40 is not
-# a really reasonable value, but chip design does not always follow
-# logic. Believe me, it's ok, and it's the way the BIOS does it.
-#
-# fbset requires 4294967256 in fb.modes and -40 as an argument to
-# the -t parameter. That's also not too reasonable, and it might change
-# in the future or might even be differt for your current version.
-#
-
-mode "640x480-50"
- geometry 640 480 2048 4096 8
- timings 47619 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-60"
- geometry 640 480 2048 4096 8
- timings 39682 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-70"
- geometry 640 480 2048 4096 8
- timings 34013 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-72"
- geometry 640 480 2048 4096 8
- timings 33068 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-75"
- geometry 640 480 2048 4096 8
- timings 31746 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-80"
- geometry 640 480 2048 4096 8
- timings 29761 4294967256 24 17 0 216 3
-endmode
-
-mode "640x480-85"
- geometry 640 480 2048 4096 8
- timings 28011 4294967256 24 17 0 216 3
-endmode
-
-mode "800x600-50"
- geometry 800 600 2048 4096 8
- timings 30303 96 24 14 0 136 11
-endmode
-
-mode "800x600-60"
- geometry 800 600 2048 4096 8
- timings 25252 96 24 14 0 136 11
-endmode
-
-mode "800x600-70"
- geometry 800 600 2048 4096 8
- timings 21645 96 24 14 0 136 11
-endmode
-
-mode "800x600-72"
- geometry 800 600 2048 4096 8
- timings 21043 96 24 14 0 136 11
-endmode
-
-mode "800x600-75"
- geometry 800 600 2048 4096 8
- timings 20202 96 24 14 0 136 11
-endmode
-
-mode "800x600-80"
- geometry 800 600 2048 4096 8
- timings 18939 96 24 14 0 136 11
-endmode
-
-mode "800x600-85"
- geometry 800 600 2048 4096 8
- timings 17825 96 24 14 0 136 11
-endmode
-
-mode "1024x768-50"
- geometry 1024 768 2048 4096 8
- timings 19054 144 24 29 0 120 3
-endmode
-
-mode "1024x768-60"
- geometry 1024 768 2048 4096 8
- timings 15880 144 24 29 0 120 3
-endmode
-
-mode "1024x768-70"
- geometry 1024 768 2048 4096 8
- timings 13610 144 24 29 0 120 3
-endmode
-
-mode "1024x768-72"
- geometry 1024 768 2048 4096 8
- timings 13232 144 24 29 0 120 3
-endmode
-
-mode "1024x768-75"
- geometry 1024 768 2048 4096 8
- timings 12703 144 24 29 0 120 3
-endmode
-
-mode "1024x768-80"
- geometry 1024 768 2048 4096 8
- timings 11910 144 24 29 0 120 3
-endmode
-
-mode "1024x768-85"
- geometry 1024 768 2048 4096 8
- timings 11209 144 24 29 0 120 3
-endmode
-
-mode "1280x1024-50"
- geometry 1280 1024 2048 4096 8
- timings 11114 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-60"
- geometry 1280 1024 2048 4096 8
- timings 9262 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-70"
- geometry 1280 1024 2048 4096 8
- timings 7939 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-72"
- geometry 1280 1024 2048 4096 8
- timings 7719 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-75"
- geometry 1280 1024 2048 4096 8
- timings 7410 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-80"
- geometry 1280 1024 2048 4096 8
- timings 6946 232 16 39 0 160 3
-endmode
-
-mode "1280x1024-85"
- geometry 1280 1024 2048 4096 8
- timings 6538 232 16 39 0 160 3
-endmode
diff --git a/Documentation/fb/cyblafb/performance b/Documentation/fb/cyblafb/performance
deleted file mode 100644
index 8d15d5dfc6b3..000000000000
--- a/Documentation/fb/cyblafb/performance
+++ /dev/null
@@ -1,79 +0,0 @@
-Speed
-=====
-
-CyBlaFB is much faster than tridentfb and vesafb. Compare the performance data
-for mode 1280x1024-[8,16,32]@61 Hz.
-
-Test 1: Cat a file with 2000 lines of 0 characters.
-Test 2: Cat a file with 2000 lines of 80 characters.
-Test 3: Cat a file with 2000 lines of 160 characters.
-
-All values show system time use in seconds, kernel 2.6.12 was used for
-the measurements. 2.6.13 is a bit slower, 2.6.14 hopefully will include a
-patch that speeds up kernel bitblitting a lot ( > 20%).
-
-+-----------+-----------------------------------------------------+
-| | not accelerated |
-| TRIDENTFB +-----------------+-----------------+-----------------+
-| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
-| | noypan | ypan | noypan | ypan | noypan | ypan |
-+-----------+--------+--------+--------+--------+--------+--------+
-| Test 1 | 4.31 | 4.33 | 6.05 | 12.81 | ---- | ---- |
-| Test 2 | 67.94 | 5.44 | 123.16 | 14.79 | ---- | ---- |
-| Test 3 | 131.36 | 6.55 | 240.12 | 16.76 | ---- | ---- |
-+-----------+--------+--------+--------+--------+--------+--------+
-| Comments | | | completely bro- |
-| | | | ken, monitor |
-| | | | switches off |
-+-----------+-----------------+-----------------+-----------------+
-
-
-+-----------+-----------------------------------------------------+
-| | accelerated |
-| TRIDENTFB +-----------------+-----------------+-----------------+
-| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
-| | noypan | ypan | noypan | ypan | noypan | ypan |
-+-----------+--------+--------+--------+--------+--------+--------+
-| Test 1 | ---- | ---- | 20.62 | 1.22 | ---- | ---- |
-| Test 2 | ---- | ---- | 22.61 | 3.19 | ---- | ---- |
-| Test 3 | ---- | ---- | 24.59 | 5.16 | ---- | ---- |
-+-----------+--------+--------+--------+--------+--------+--------+
-| Comments | broken, writing | broken, ok only | completely bro- |
-| | to wrong places | if bgcolor is | ken, monitor |
-| | on screen + bug | black, bug in | switches off |
-| | in fillrect() | fillrect() | |
-+-----------+-----------------+-----------------+-----------------+
-
-
-+-----------+-----------------------------------------------------+
-| | not accelerated |
-| VESAFB +-----------------+-----------------+-----------------+
-| of 2.6.12 | 8 bpp | 16 bpp | 32 bpp |
-| | noypan | ypan | noypan | ypan | noypan | ypan |
-+-----------+--------+--------+--------+--------+--------+--------+
-| Test 1 | 4.26 | 3.76 | 5.99 | 7.23 | ---- | ---- |
-| Test 2 | 65.65 | 4.89 | 120.88 | 9.08 | ---- | ---- |
-| Test 3 | 126.91 | 5.94 | 235.77 | 11.03 | ---- | ---- |
-+-----------+--------+--------+--------+--------+--------+--------+
-| Comments | vga=0x307 | vga=0x31a | vga=0x31b not |
-| | fh=80kHz | fh=80kHz | supported by |
-| | fv=75kHz | fv=75kHz | video BIOS and |
-| | | | hardware |
-+-----------+-----------------+-----------------+-----------------+
-
-
-+-----------+-----------------------------------------------------+
-| | accelerated |
-| CYBLAFB +-----------------+-----------------+-----------------+
-| | 8 bpp | 16 bpp | 32 bpp |
-| | noypan | ypan | noypan | ypan | noypan | ypan |
-+-----------+--------+--------+--------+--------+--------+--------+
-| Test 1 | 8.02 | 0.23 | 19.04 | 0.61 | 57.12 | 2.74 |
-| Test 2 | 8.38 | 0.55 | 19.39 | 0.92 | 57.54 | 3.13 |
-| Test 3 | 8.73 | 0.86 | 19.74 | 1.24 | 57.95 | 3.51 |
-+-----------+--------+--------+--------+--------+--------+--------+
-| Comments | | | |
-| | | | |
-| | | | |
-| | | | |
-+-----------+-----------------+-----------------+-----------------+
diff --git a/Documentation/fb/cyblafb/todo b/Documentation/fb/cyblafb/todo
deleted file mode 100644
index c5f6d0eae545..000000000000
--- a/Documentation/fb/cyblafb/todo
+++ /dev/null
@@ -1,31 +0,0 @@
-TODO / Missing features
-=======================
-
-Verify LCD stuff "stretch" and "center" options are
- completely untested ... this code needs to be
- verified. As I don't have access to such
- hardware, please contact me if you are
- willing run some tests.
-
-Interlaced video modes The reason that interleaved
- modes are disabled is that I do not know
- the meaning of the vertical interlace
- parameter. Also the datasheet mentions a
- bit d8 of a horizontal interlace parameter,
- but nowhere the lower 8 bits. Please help
- if you can.
-
-low-res double scan modes Who needs it?
-
-accelerated color blitting Who needs it? The console driver does use color
- blitting for nothing but drawing the penguine,
- everything else is done using color expanding
- blitting of 1bpp character bitmaps.
-
-ioctls Who needs it?
-
-TV-out Will be done later. Use "vga= " at boot time
- to set a suitable video mode.
-
-??? Feel free to contact me if you have any
- feature requests
diff --git a/Documentation/fb/cyblafb/usage b/Documentation/fb/cyblafb/usage
deleted file mode 100644
index a39bb3d402a2..000000000000
--- a/Documentation/fb/cyblafb/usage
+++ /dev/null
@@ -1,217 +0,0 @@
-CyBlaFB is a framebuffer driver for the Cyberblade/i1 graphics core integrated
-into the VIA Apollo PLE133 (aka vt8601) south bridge. It is developed and
-tested using a VIA EPIA 5000 board.
-
-Cyblafb - compiled into the kernel or as a module?
-==================================================
-
-You might compile cyblafb either as a module or compile it permanently into the
-kernel.
-
-Unless you have a real reason to do so you should not compile both vesafb and
-cyblafb permanently into the kernel. It's possible and it helps during the
-developement cycle, but it's useless and will at least block some otherwise
-usefull memory for ordinary users.
-
-Selecting Modes
-===============
-
- Startup Mode
- ============
-
- First of all, you might use the "vga=???" boot parameter as it is
- documented in vesafb.txt and svga.txt. Cyblafb will detect the video
- mode selected and will use the geometry and timings found by
- inspecting the hardware registers.
-
- video=cyblafb vga=0x317
-
- Alternatively you might use a combination of the mode, ref and bpp
- parameters. If you compiled the driver into the kernel, add something
- like this to the kernel command line:
-
- video=cyblafb:1280x1024,bpp=16,ref=50 ...
-
- If you compiled the driver as a module, the same mode would be
- selected by the following command:
-
- modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ...
-
- None of the modes possible to select as startup modes are affected by
- the problems described at the end of the next subsection.
-
- For all startup modes cyblafb chooses a virtual x resolution of 2048,
- the only exception is mode 1280x1024 in combination with 32 bpp. This
- allows ywrap scrolling for all those modes if rotation is 0 or 2, and
- also fast scrolling if rotation is 1 or 3. The default virtual y reso-
- lution is 4096 for bpp == 8, 2048 for bpp==16 and 1024 for bpp == 32,
- again with the only exception of 1280x1024 at 32 bpp.
-
- Please do set your video memory size to 8 Mb in the Bios setup. Other
- values will work, but performace is decreased for a lot of modes.
-
- Mode changes using fbset
- ========================
-
- You might use fbset to change the video mode, see "man fbset". Cyblafb
- generally does assume that you know what you are doing. But it does
- some checks, especially those that are needed to prevent you from
- damaging your hardware.
-
- - only 8, 16, 24 and 32 bpp video modes are accepted
- - interlaced video modes are not accepted
- - double scan video modes are not accepted
- - if a flat panel is found, cyblafb does not allow you
- to program a resolution higher than the physical
- resolution of the flat panel monitor
- - cyblafb does not allow vclk to exceed 230 MHz. As 32 bpp
- and (currently) 24 bit modes use a doubled vclk internally,
- the dotclock limit as seen by fbset is 115 MHz for those
- modes and 230 MHz for 8 and 16 bpp modes.
- - cyblafb will allow you to select very high resolutions as
- long as the hardware can be programmed to these modes. The
- documented limit 1600x1200 is not enforced, but don't expect
- perfect signal quality.
-
- Any request that violates the rules given above will be either changed
- to something the hardware supports or an error value will be returned.
-
- If you program a virtual y resolution higher than the hardware limit,
- cyblafb will silently decrease that value to the highest possible
- value. The same is true for a virtual x resolution that is not
- supported by the hardware. Cyblafb tries to adapt vyres first because
- vxres decides if ywrap scrolling is possible or not.
-
- Attempts to disable acceleration are ignored, I believe that this is
- safe.
-
- Some video modes that should work do not work as expected. If you use
- the standard fb.modes, fbset 640x480-60 will program that mode, but
- you will see a vertical area, about two characters wide, with only
- much darker characters than the other characters on the screen.
- Cyblafb does allow that mode to be set, as it does not violate the
- official specifications. It would need a lot of code to reliably sort
- out all invalid modes, playing around with the margin values will
- give a valid mode quickly. And if cyblafb would detect such an invalid
- mode, should it silently alter the requested values or should it
- report an error? Both options have some pros and cons. As stated
- above, none of the startup modes are affected, and if you set
- verbosity to 1 or higher, cyblafb will print the fbset command that
- would be needed to program that mode using fbset.
-
-
-Other Parameters
-================
-
-
-crt don't autodetect, assume monitor connected to
- standard VGA connector
-
-fp don't autodetect, assume flat panel display
- connected to flat panel monitor interface
-
-nativex inform driver about native x resolution of
- flat panel monitor connected to special
- interface (should be autodetected)
-
-stretch stretch image to adapt low resolution modes to
- higer resolutions of flat panel monitors
- connected to special interface
-
-center center image to adapt low resolution modes to
- higer resolutions of flat panel monitors
- connected to special interface
-
-memsize use if autodetected memsize is wrong ...
- should never be necessary
-
-nopcirr disable PCI read retry
-nopciwr disable PCI write retry
-nopcirb disable PCI read bursts
-nopciwb disable PCI write bursts
-
-bpp bpp for specified modes
- valid values: 8 || 16 || 24 || 32
-
-ref refresh rate for specified mode
- valid values: 50 <= ref <= 85
-
-mode 640x480 or 800x600 or 1024x768 or 1280x1024
- if not specified, the startup mode will be detected
- and used, so you might also use the vga=??? parameter
- described in vesafb.txt. If you do not specify a mode,
- bpp and ref parameters are ignored.
-
-verbosity 0 is the default, increase to at least 2 for every
- bug report!
-
-Development hints
-=================
-
-It's much faster do compile a module and to load the new version after
-unloading the old module than to compile a new kernel and to reboot. So if you
-try to work on cyblafb, it might be a good idea to use cyblafb as a module.
-In real life, fast often means dangerous, and that's also the case here. If
-you introduce a serious bug when cyblafb is compiled into the kernel, the
-kernel will lock or oops with a high probability before the file system is
-mounted, and the danger for your data is low. If you load a broken own version
-of cyblafb on a running system, the danger for the integrity of the file
-system is much higher as you might need a hard reset afterwards. Decide
-yourself.
-
-Module unloading, the vfb method
-================================
-
-If you want to unload/reload cyblafb using the virtual framebuffer, you need
-to enable vfb support in the kernel first. After that, load the modules as
-shown below:
-
- modprobe vfb vfb_enable=1
- modprobe fbcon
- modprobe cyblafb
- fbset -fb /dev/fb1 1280x1024-60 -vyres 2662
- con2fb /dev/fb1 /dev/tty1
- ...
-
-If you now made some changes to cyblafb and want to reload it, you might do it
-as show below:
-
- con2fb /dev/fb0 /dev/tty1
- ...
- rmmod cyblafb
- modprobe cyblafb
- con2fb /dev/fb1 /dev/tty1
- ...
-
-Of course, you might choose another mode, and most certainly you also want to
-map some other /dev/tty* to the real framebuffer device. You might also choose
-to compile fbcon as a kernel module or place it permanently in the kernel.
-
-I do not know of any way to unload fbcon, and fbcon will prevent the
-framebuffer device loaded first from unloading. [If there is a way, then
-please add a description here!]
-
-Module unloading, the vesafb method
-===================================
-
-Configure the kernel:
-
- <*> Support for frame buffer devices
- [*] VESA VGA graphics support
- <M> Cyberblade/i1 support
-
-Add e.g. "video=vesafb:ypan vga=0x307" to the kernel parameters. The ypan
-parameter is important, choose any vga parameter you like as long as it is
-a graphics mode.
-
-After booting, load cyblafb without any mode and bpp parameter and assign
-cyblafb to individual ttys using con2fb, e.g.:
-
- modprobe cyblafb
- con2fb /dev/fb1 /dev/tty1
-
-Unloading cyblafb works without problems after you assign vesafb to all
-ttys again, e.g.:
-
- con2fb /dev/fb0 /dev/tty1
- rmmod cyblafb
diff --git a/Documentation/fb/cyblafb/whatsnew b/Documentation/fb/cyblafb/whatsnew
deleted file mode 100644
index 76c07a26e044..000000000000
--- a/Documentation/fb/cyblafb/whatsnew
+++ /dev/null
@@ -1,29 +0,0 @@
-0.62
-====
-
- - the vesafb parameter has been removed as I decided to allow the
- feature without any special parameter.
-
- - Cyblafb does not use the vga style of panning any longer, now the
- "right view" register in the graphics engine IO space is used. Without
- that change it was impossible to use all available memory, and without
- access to all available memory it is impossible to ywrap.
-
- - The imageblit function now uses hardware acceleration for all font
- widths. Hardware blitting across pixel column 2048 is broken in the
- cyberblade/i1 graphics core, but we work around that hardware bug.
-
- - modes with vxres != xres are supported now.
-
- - ywrap scrolling is supported now and the default. This is a big
- performance gain.
-
- - default video modes use vyres > yres and vxres > xres to allow
- almost optimal scrolling speed for normal and rotated screens
-
- - some features mainly usefull for debugging the upper layers of the
- framebuffer system have been added, have a look at the code
-
- - fixed: Oops after unloading cyblafb when reading /proc/io*
-
- - we work around some bugs of the higher framebuffer layers.
diff --git a/Documentation/fb/cyblafb/whycyblafb b/Documentation/fb/cyblafb/whycyblafb
deleted file mode 100644
index a123bc11e698..000000000000
--- a/Documentation/fb/cyblafb/whycyblafb
+++ /dev/null
@@ -1,85 +0,0 @@
-I tried the following framebuffer drivers:
-
- - TRIDENTFB is full of bugs. Acceleration is broken for Blade3D
- graphics cores like the cyberblade/i1. It claims to support a great
- number of devices, but documentation for most of these devices is
- unfortunately not available. There is _no_ reason to use tridentfb
- for cyberblade/i1 + CRT users. VESAFB is faster, and the one
- advantage, mode switching, is broken in tridentfb.
-
- - VESAFB is used by many distributions as a standard. Vesafb does
- not support mode switching. VESAFB is a bit faster than the working
- configurations of TRIDENTFB, but it is still too slow, even if you
- use ypan.
-
- - EPIAFB (you'll find it on sourceforge) supports the Cyberblade/i1
- graphics core, but it still has serious bugs and developement seems
- to have stopped. This is the one driver with TV-out support. If you
- do need this feature, try epiafb.
-
-None of these drivers was a real option for me.
-
-I believe that is unreasonable to change code that announces to support 20
-devices if I only have more or less sufficient documentation for exactly one
-of these. The risk of breaking device foo while fixing device bar is too high.
-
-So I decided to start CyBlaFB as a stripped down tridentfb.
-
-All code specific to other Trident chips has been removed. After that there
-were a lot of cosmetic changes to increase the readability of the code. All
-register names were changed to those mnemonics used in the datasheet. Function
-and macro names were changed if they hindered easy understanding of the code.
-
-After that I debugged the code and implemented some new features. I'll try to
-give a little summary of the main changes:
-
- - calculation of vertical and horizontal timings was fixed
-
- - video signal quality has been improved dramatically
-
- - acceleration:
-
- - fillrect and copyarea were fixed and reenabled
-
- - color expanding imageblit was newly implemented, color
- imageblit (only used to draw the penguine) still uses the
- generic code.
-
- - init of the acceleration engine was improved and moved to a
- place where it really works ...
-
- - sync function has a timeout now and tries to reset and
- reinit the accel engine if necessary
-
- - fewer slow copyarea calls when doing ypan scrolling by using
- undocumented bit d21 of screen start address stored in
- CR2B[5]. BIOS does use it also, so this should be safe.
-
- - cyblafb rejects any attempt to set modes that would cause vclk
- values above reasonable 230 MHz. 32bit modes use a clock
- multiplicator of 2, so fbset does show the correct values for
- pixclock but not for vclk in this case. The fbset limit is 115 MHz
- for 32 bpp modes.
-
- - cyblafb rejects modes known to be broken or unimplemented (all
- interlaced modes, all doublescan modes for now)
-
- - cyblafb now works independant of the video mode in effect at startup
- time (tridentfb does not init all needed registers to reasonable
- values)
-
- - switching between video modes does work reliably now
-
- - the first video mode now is the one selected on startup using the
- vga=???? mechanism or any of
- - 640x480, 800x600, 1024x768, 1280x1024
- - 8, 16, 24 or 32 bpp
- - refresh between 50 Hz and 85 Hz, 1 Hz steps (1280x1024-32
- is limited to 63Hz)
-
- - pci retry and pci burst mode are settable (try to disable if you
- experience latency problems)
-
- - built as a module cyblafb might be unloaded and reloaded using
- the vfb module and con2vt or might be used together with vesafb
-
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 20d3b94703a4..7e2af10e8264 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -6,20 +6,47 @@ be removed from this file.
---------------------------
-What: old static regulatory information and ieee80211_regdom module parameter
-When: 2.6.29
+What: The ieee80211_regdom module parameter
+When: March 2010 / desktop catchup
+
+Why: This was inherited by the CONFIG_WIRELESS_OLD_REGULATORY code,
+ and currently serves as an option for users to define an
+ ISO / IEC 3166 alpha2 code for the country they are currently
+ present in. Although there are userspace API replacements for this
+ through nl80211 distributions haven't yet caught up with implementing
+ decent alternatives through standard GUIs. Although available as an
+ option through iw or wpa_supplicant its just a matter of time before
+ distributions pick up good GUI options for this. The ideal solution
+ would actually consist of intelligent designs which would do this for
+ the user automatically even when travelling through different countries.
+ Until then we leave this module parameter as a compromise.
+
+ When userspace improves with reasonable widely-available alternatives for
+ this we will no longer need this module parameter. This entry hopes that
+ by the super-futuristically looking date of "March 2010" we will have
+ such replacements widely available.
+
+Who: Luis R. Rodriguez <lrodriguez@atheros.com>
+
+---------------------------
+
+What: CONFIG_WIRELESS_OLD_REGULATORY - old static regulatory information
+When: March 2010 / desktop catchup
+
Why: The old regulatory infrastructure has been replaced with a new one
which does not require statically defined regulatory domains. We do
not want to keep static regulatory domains in the kernel due to the
the dynamic nature of regulatory law and localization. We kept around
the old static definitions for the regulatory domains of:
+
* US
* JP
* EU
+
and used by default the US when CONFIG_WIRELESS_OLD_REGULATORY was
- set. We also kept around the ieee80211_regdom module parameter in case
- some applications were relying on it. Changing regulatory domains
- can now be done instead by using nl80211, as is done with iw.
+ set. We will remove this option once the standard Linux desktop catches
+ up with the new userspace APIs we have implemented.
+
Who: Luis R. Rodriguez <lrodriguez@atheros.com>
---------------------------
@@ -37,10 +64,10 @@ Who: Pavel Machek <pavel@suse.cz>
---------------------------
-What: Video4Linux API 1 ioctls and video_decoder.h from Video devices.
-When: December 2008
-Files: include/linux/video_decoder.h include/linux/videodev.h
-Check: include/linux/video_decoder.h include/linux/videodev.h
+What: Video4Linux API 1 ioctls and from Video devices.
+When: July 2009
+Files: include/linux/videodev.h
+Check: include/linux/videodev.h
Why: V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6
series. The old API have lots of drawbacks and don't provide enough
means to work with all video and audio standards. The newer API is
@@ -228,8 +255,20 @@ Who: Jan Engelhardt <jengelh@computergmbh.de>
---------------------------
+What: GPIO autorequest on gpio_direction_{input,output}() in gpiolib
+When: February 2010
+Why: All callers should use explicit gpio_request()/gpio_free().
+ The autorequest mechanism in gpiolib was provided mostly as a
+ migration aid for legacy GPIO interfaces (for SOC based GPIOs).
+ Those users have now largely migrated. Platforms implementing
+ the GPIO interfaces without using gpiolib will see no changes.
+Who: David Brownell <dbrownell@users.sourceforge.net>
+---------------------------
+
What: b43 support for firmware revision < 410
-When: July 2008
+When: The schedule was July 2008, but it was decided that we are going to keep the
+ code as long as there are no major maintanance headaches.
+ So it _could_ be removed _any_ time now, if it conflicts with something new.
Why: The support code for the old firmware hurts code readability/maintainability
and slightly hurts runtime performance. Bugfixes for the old firmware
are not provided by Broadcom anymore.
@@ -244,13 +283,6 @@ Who: Glauber Costa <gcosta@redhat.com>
---------------------------
-What: remove HID compat support
-When: 2.6.29
-Why: needed only as a temporary solution until distros fix themselves up
-Who: Jiri Slaby <jirislaby@gmail.com>
-
----------------------------
-
What: print_fn_descriptor_symbol()
When: October 2009
Why: The %pF vsprintf format provides the same functionality in a
@@ -282,6 +314,18 @@ Who: Vlad Yasevich <vladislav.yasevich@hp.com>
---------------------------
+What: Ability for non root users to shm_get hugetlb pages based on mlock
+ resource limits
+When: 2.6.31
+Why: Non root users need to be part of /proc/sys/vm/hugetlb_shm_group or
+ have CAP_IPC_LOCK to be able to allocate shm segments backed by
+ huge pages. The mlock based rlimit check to allow shm hugetlb is
+ inconsistent with mmap based allocations. Hence it is being
+ deprecated.
+Who: Ravikiran Thirumalai <kiran@scalex86.org>
+
+---------------------------
+
What: CONFIG_THERMAL_HWMON
When: January 2009
Why: This option was introduced just to allow older lm-sensors userspace
@@ -310,8 +354,10 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl>
---------------------------
-What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client()
-When: 2.6.29 (ideally) or 2.6.30 (more likely)
+What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client(),
+ i2c_adapter->client_register(), i2c_adapter->client_unregister
+When: 2.6.30
+Check: i2c_attach_client i2c_detach_client
Why: Deprecated by the new (standard) device driver binding model. Use
i2c_driver->probe() and ->remove() instead.
Who: Jean Delvare <khali@linux-fr.org>
@@ -326,17 +372,6 @@ Who: Hans de Goede <hdegoede@redhat.com>
---------------------------
-What: SELinux "compat_net" functionality
-When: 2.6.30 at the earliest
-Why: In 2.6.18 the Secmark concept was introduced to replace the "compat_net"
- network access control functionality of SELinux. Secmark offers both
- better performance and greater flexibility than the "compat_net"
- mechanism. Now that the major Linux distributions have moved to
- Secmark, it is time to deprecate the older mechanism and start the
- process of removing the old code.
-Who: Paul Moore <paul.moore@hp.com>
----------------------------
-
What: sysfs ui for changing p4-clockmod parameters
When: September 2009
Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and
@@ -344,3 +379,52 @@ Why: See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and
Removal is subject to fixing any remaining bugs in ACPI which may
cause the thermal throttling not to happen at the right time.
Who: Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com>
+
+-----------------------------
+
+What: __do_IRQ all in one fits nothing interrupt handler
+When: 2.6.32
+Why: __do_IRQ was kept for easy migration to the type flow handlers.
+ More than two years of migration time is enough.
+Who: Thomas Gleixner <tglx@linutronix.de>
+
+-----------------------------
+
+What: obsolete generic irq defines and typedefs
+When: 2.6.30
+Why: The defines and typedefs (hw_interrupt_type, no_irq_type, irq_desc_t)
+ have been kept around for migration reasons. After more than two years
+ it's time to remove them finally
+Who: Thomas Gleixner <tglx@linutronix.de>
+
+---------------------------
+
+What: fakephp and associated sysfs files in /sys/bus/pci/slots/
+When: 2011
+Why: In 2.6.27, the semantics of /sys/bus/pci/slots was redefined to
+ represent a machine's physical PCI slots. The change in semantics
+ had userspace implications, as the hotplug core no longer allowed
+ drivers to create multiple sysfs files per physical slot (required
+ for multi-function devices, e.g.). fakephp was seen as a developer's
+ tool only, and its interface changed. Too late, we learned that
+ there were some users of the fakephp interface.
+
+ In 2.6.30, the original fakephp interface was restored. At the same
+ time, the PCI core gained the ability that fakephp provided, namely
+ function-level hot-remove and hot-add.
+
+ Since the PCI core now provides the same functionality, exposed in:
+
+ /sys/bus/pci/rescan
+ /sys/bus/pci/devices/.../remove
+ /sys/bus/pci/devices/.../rescan
+
+ there is no functional reason to maintain fakephp as well.
+
+ We will keep the existing module so that 'modprobe fakephp' will
+ present the old /sys/bus/pci/slots/... interface for compatibility,
+ but users are urged to migrate their applications to the API above.
+
+ After a reasonable transition period, we will remove the legacy
+ fakephp interface.
+Who: Alex Chiang <achiang@hp.com>
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index ec6a9392a173..76efe5b71d7d 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -437,8 +437,11 @@ grab BKL for cases when we close a file that had been opened r/w, but that
can and should be done using the internal locking with smaller critical areas).
Current worst offender is ext2_get_block()...
-->fasync() is a mess. This area needs a big cleanup and that will probably
-affect locking.
+->fasync() is called without BKL protection, and is responsible for
+maintaining the FASYNC bit in filp->f_flags. Most instances call
+fasync_helper(), which does that maintenance, so it's not normally
+something one needs to worry about. Return values > 0 will be mapped to
+zero in the VFS layer.
->readdir() and ->ioctl() on directories must be changed. Ideally we would
move ->readdir() to inode_operations and use a separate method for directory
@@ -502,7 +505,7 @@ prototypes:
void (*open)(struct vm_area_struct*);
void (*close)(struct vm_area_struct*);
int (*fault)(struct vm_area_struct*, struct vm_fault *);
- int (*page_mkwrite)(struct vm_area_struct *, struct page *);
+ int (*page_mkwrite)(struct vm_area_struct *, struct vm_fault *);
int (*access)(struct vm_area_struct *, unsigned long, void*, int, int);
locking rules:
diff --git a/Documentation/filesystems/caching/backend-api.txt b/Documentation/filesystems/caching/backend-api.txt
new file mode 100644
index 000000000000..382d52cdaf2d
--- /dev/null
+++ b/Documentation/filesystems/caching/backend-api.txt
@@ -0,0 +1,658 @@
+ ==========================
+ FS-CACHE CACHE BACKEND API
+ ==========================
+
+The FS-Cache system provides an API by which actual caches can be supplied to
+FS-Cache for it to then serve out to network filesystems and other interested
+parties.
+
+This API is declared in <linux/fscache-cache.h>.
+
+
+====================================
+INITIALISING AND REGISTERING A CACHE
+====================================
+
+To start off, a cache definition must be initialised and registered for each
+cache the backend wants to make available. For instance, CacheFS does this in
+the fill_super() operation on mounting.
+
+The cache definition (struct fscache_cache) should be initialised by calling:
+
+ void fscache_init_cache(struct fscache_cache *cache,
+ struct fscache_cache_ops *ops,
+ const char *idfmt,
+ ...);
+
+Where:
+
+ (*) "cache" is a pointer to the cache definition;
+
+ (*) "ops" is a pointer to the table of operations that the backend supports on
+ this cache; and
+
+ (*) "idfmt" is a format and printf-style arguments for constructing a label
+ for the cache.
+
+
+The cache should then be registered with FS-Cache by passing a pointer to the
+previously initialised cache definition to:
+
+ int fscache_add_cache(struct fscache_cache *cache,
+ struct fscache_object *fsdef,
+ const char *tagname);
+
+Two extra arguments should also be supplied:
+
+ (*) "fsdef" which should point to the object representation for the FS-Cache
+ master index in this cache. Netfs primary index entries will be created
+ here. FS-Cache keeps the caller's reference to the index object if
+ successful and will release it upon withdrawal of the cache.
+
+ (*) "tagname" which, if given, should be a text string naming this cache. If
+ this is NULL, the identifier will be used instead. For CacheFS, the
+ identifier is set to name the underlying block device and the tag can be
+ supplied by mount.
+
+This function may return -ENOMEM if it ran out of memory or -EEXIST if the tag
+is already in use. 0 will be returned on success.
+
+
+=====================
+UNREGISTERING A CACHE
+=====================
+
+A cache can be withdrawn from the system by calling this function with a
+pointer to the cache definition:
+
+ void fscache_withdraw_cache(struct fscache_cache *cache);
+
+In CacheFS's case, this is called by put_super().
+
+
+========
+SECURITY
+========
+
+The cache methods are executed one of two contexts:
+
+ (1) that of the userspace process that issued the netfs operation that caused
+ the cache method to be invoked, or
+
+ (2) that of one of the processes in the FS-Cache thread pool.
+
+In either case, this may not be an appropriate context in which to access the
+cache.
+
+The calling process's fsuid, fsgid and SELinux security identities may need to
+be masqueraded for the duration of the cache driver's access to the cache.
+This is left to the cache to handle; FS-Cache makes no effort in this regard.
+
+
+===================================
+CONTROL AND STATISTICS PRESENTATION
+===================================
+
+The cache may present data to the outside world through FS-Cache's interfaces
+in sysfs and procfs - the former for control and the latter for statistics.
+
+A sysfs directory called /sys/fs/fscache/<cachetag>/ is created if CONFIG_SYSFS
+is enabled. This is accessible through the kobject struct fscache_cache::kobj
+and is for use by the cache as it sees fit.
+
+
+========================
+RELEVANT DATA STRUCTURES
+========================
+
+ (*) Index/Data file FS-Cache representation cookie:
+
+ struct fscache_cookie {
+ struct fscache_object_def *def;
+ struct fscache_netfs *netfs;
+ void *netfs_data;
+ ...
+ };
+
+ The fields that might be of use to the backend describe the object
+ definition, the netfs definition and the netfs's data for this cookie.
+ The object definition contain functions supplied by the netfs for loading
+ and matching index entries; these are required to provide some of the
+ cache operations.
+
+
+ (*) In-cache object representation:
+
+ struct fscache_object {
+ int debug_id;
+ enum {
+ FSCACHE_OBJECT_RECYCLING,
+ ...
+ } state;
+ spinlock_t lock
+ struct fscache_cache *cache;
+ struct fscache_cookie *cookie;
+ ...
+ };
+
+ Structures of this type should be allocated by the cache backend and
+ passed to FS-Cache when requested by the appropriate cache operation. In
+ the case of CacheFS, they're embedded in CacheFS's internal object
+ structures.
+
+ The debug_id is a simple integer that can be used in debugging messages
+ that refer to a particular object. In such a case it should be printed
+ using "OBJ%x" to be consistent with FS-Cache.
+
+ Each object contains a pointer to the cookie that represents the object it
+ is backing. An object should retired when put_object() is called if it is
+ in state FSCACHE_OBJECT_RECYCLING. The fscache_object struct should be
+ initialised by calling fscache_object_init(object).
+
+
+ (*) FS-Cache operation record:
+
+ struct fscache_operation {
+ atomic_t usage;
+ struct fscache_object *object;
+ unsigned long flags;
+ #define FSCACHE_OP_EXCLUSIVE
+ void (*processor)(struct fscache_operation *op);
+ void (*release)(struct fscache_operation *op);
+ ...
+ };
+
+ FS-Cache has a pool of threads that it uses to give CPU time to the
+ various asynchronous operations that need to be done as part of driving
+ the cache. These are represented by the above structure. The processor
+ method is called to give the op CPU time, and the release method to get
+ rid of it when its usage count reaches 0.
+
+ An operation can be made exclusive upon an object by setting the
+ appropriate flag before enqueuing it with fscache_enqueue_operation(). If
+ an operation needs more processing time, it should be enqueued again.
+
+
+ (*) FS-Cache retrieval operation record:
+
+ struct fscache_retrieval {
+ struct fscache_operation op;
+ struct address_space *mapping;
+ struct list_head *to_do;
+ ...
+ };
+
+ A structure of this type is allocated by FS-Cache to record retrieval and
+ allocation requests made by the netfs. This struct is then passed to the
+ backend to do the operation. The backend may get extra refs to it by
+ calling fscache_get_retrieval() and refs may be discarded by calling
+ fscache_put_retrieval().
+
+ A retrieval operation can be used by the backend to do retrieval work. To
+ do this, the retrieval->op.processor method pointer should be set
+ appropriately by the backend and fscache_enqueue_retrieval() called to
+ submit it to the thread pool. CacheFiles, for example, uses this to queue
+ page examination when it detects PG_lock being cleared.
+
+ The to_do field is an empty list available for the cache backend to use as
+ it sees fit.
+
+
+ (*) FS-Cache storage operation record:
+
+ struct fscache_storage {
+ struct fscache_operation op;
+ pgoff_t store_limit;
+ ...
+ };
+
+ A structure of this type is allocated by FS-Cache to record outstanding
+ writes to be made. FS-Cache itself enqueues this operation and invokes
+ the write_page() method on the object at appropriate times to effect
+ storage.
+
+
+================
+CACHE OPERATIONS
+================
+
+The cache backend provides FS-Cache with a table of operations that can be
+performed on the denizens of the cache. These are held in a structure of type:
+
+ struct fscache_cache_ops
+
+ (*) Name of cache provider [mandatory]:
+
+ const char *name
+
+ This isn't strictly an operation, but should be pointed at a string naming
+ the backend.
+
+
+ (*) Allocate a new object [mandatory]:
+
+ struct fscache_object *(*alloc_object)(struct fscache_cache *cache,
+ struct fscache_cookie *cookie)
+
+ This method is used to allocate a cache object representation to back a
+ cookie in a particular cache. fscache_object_init() should be called on
+ the object to initialise it prior to returning.
+
+ This function may also be used to parse the index key to be used for
+ multiple lookup calls to turn it into a more convenient form. FS-Cache
+ will call the lookup_complete() method to allow the cache to release the
+ form once lookup is complete or aborted.
+
+
+ (*) Look up and create object [mandatory]:
+
+ void (*lookup_object)(struct fscache_object *object)
+
+ This method is used to look up an object, given that the object is already
+ allocated and attached to the cookie. This should instantiate that object
+ in the cache if it can.
+
+ The method should call fscache_object_lookup_negative() as soon as
+ possible if it determines the object doesn't exist in the cache. If the
+ object is found to exist and the netfs indicates that it is valid then
+ fscache_obtained_object() should be called once the object is in a
+ position to have data stored in it. Similarly, fscache_obtained_object()
+ should also be called once a non-present object has been created.
+
+ If a lookup error occurs, fscache_object_lookup_error() should be called
+ to abort the lookup of that object.
+
+
+ (*) Release lookup data [mandatory]:
+
+ void (*lookup_complete)(struct fscache_object *object)
+
+ This method is called to ask the cache to release any resources it was
+ using to perform a lookup.
+
+
+ (*) Increment object refcount [mandatory]:
+
+ struct fscache_object *(*grab_object)(struct fscache_object *object)
+
+ This method is called to increment the reference count on an object. It
+ may fail (for instance if the cache is being withdrawn) by returning NULL.
+ It should return the object pointer if successful.
+
+
+ (*) Lock/Unlock object [mandatory]:
+
+ void (*lock_object)(struct fscache_object *object)
+ void (*unlock_object)(struct fscache_object *object)
+
+ These methods are used to exclusively lock an object. It must be possible
+ to schedule with the lock held, so a spinlock isn't sufficient.
+
+
+ (*) Pin/Unpin object [optional]:
+
+ int (*pin_object)(struct fscache_object *object)
+ void (*unpin_object)(struct fscache_object *object)
+
+ These methods are used to pin an object into the cache. Once pinned an
+ object cannot be reclaimed to make space. Return -ENOSPC if there's not
+ enough space in the cache to permit this.
+
+
+ (*) Update object [mandatory]:
+
+ int (*update_object)(struct fscache_object *object)
+
+ This is called to update the index entry for the specified object. The
+ new information should be in object->cookie->netfs_data. This can be
+ obtained by calling object->cookie->def->get_aux()/get_attr().
+
+
+ (*) Discard object [mandatory]:
+
+ void (*drop_object)(struct fscache_object *object)
+
+ This method is called to indicate that an object has been unbound from its
+ cookie, and that the cache should release the object's resources and
+ retire it if it's in state FSCACHE_OBJECT_RECYCLING.
+
+ This method should not attempt to release any references held by the
+ caller. The caller will invoke the put_object() method as appropriate.
+
+
+ (*) Release object reference [mandatory]:
+
+ void (*put_object)(struct fscache_object *object)
+
+ This method is used to discard a reference to an object. The object may
+ be freed when all the references to it are released.
+
+
+ (*) Synchronise a cache [mandatory]:
+
+ void (*sync)(struct fscache_cache *cache)
+
+ This is called to ask the backend to synchronise a cache with its backing
+ device.
+
+
+ (*) Dissociate a cache [mandatory]:
+
+ void (*dissociate_pages)(struct fscache_cache *cache)
+
+ This is called to ask a cache to perform any page dissociations as part of
+ cache withdrawal.
+
+
+ (*) Notification that the attributes on a netfs file changed [mandatory]:
+
+ int (*attr_changed)(struct fscache_object *object);
+
+ This is called to indicate to the cache that certain attributes on a netfs
+ file have changed (for example the maximum size a file may reach). The
+ cache can read these from the netfs by calling the cookie's get_attr()
+ method.
+
+ The cache may use the file size information to reserve space on the cache.
+ It should also call fscache_set_store_limit() to indicate to FS-Cache the
+ highest byte it's willing to store for an object.
+
+ This method may return -ve if an error occurred or the cache object cannot
+ be expanded. In such a case, the object will be withdrawn from service.
+
+ This operation is run asynchronously from FS-Cache's thread pool, and
+ storage and retrieval operations from the netfs are excluded during the
+ execution of this operation.
+
+
+ (*) Reserve cache space for an object's data [optional]:
+
+ int (*reserve_space)(struct fscache_object *object, loff_t size);
+
+ This is called to request that cache space be reserved to hold the data
+ for an object and the metadata used to track it. Zero size should be
+ taken as request to cancel a reservation.
+
+ This should return 0 if successful, -ENOSPC if there isn't enough space
+ available, or -ENOMEM or -EIO on other errors.
+
+ The reservation may exceed the current size of the object, thus permitting
+ future expansion. If the amount of space consumed by an object would
+ exceed the reservation, it's permitted to refuse requests to allocate
+ pages, but not required. An object may be pruned down to its reservation
+ size if larger than that already.
+
+
+ (*) Request page be read from cache [mandatory]:
+
+ int (*read_or_alloc_page)(struct fscache_retrieval *op,
+ struct page *page,
+ gfp_t gfp)
+
+ This is called to attempt to read a netfs page from the cache, or to
+ reserve a backing block if not. FS-Cache will have done as much checking
+ as it can before calling, but most of the work belongs to the backend.
+
+ If there's no page in the cache, then -ENODATA should be returned if the
+ backend managed to reserve a backing block; -ENOBUFS or -ENOMEM if it
+ didn't.
+
+ If there is suitable data in the cache, then a read operation should be
+ queued and 0 returned. When the read finishes, fscache_end_io() should be
+ called.
+
+ The fscache_mark_pages_cached() should be called for the page if any cache
+ metadata is retained. This will indicate to the netfs that the page needs
+ explicit uncaching. This operation takes a pagevec, thus allowing several
+ pages to be marked at once.
+
+ The retrieval record pointed to by op should be retained for each page
+ queued and released when I/O on the page has been formally ended.
+ fscache_get/put_retrieval() are available for this purpose.
+
+ The retrieval record may be used to get CPU time via the FS-Cache thread
+ pool. If this is desired, the op->op.processor should be set to point to
+ the appropriate processing routine, and fscache_enqueue_retrieval() should
+ be called at an appropriate point to request CPU time. For instance, the
+ retrieval routine could be enqueued upon the completion of a disk read.
+ The to_do field in the retrieval record is provided to aid in this.
+
+ If an I/O error occurs, fscache_io_error() should be called and -ENOBUFS
+ returned if possible or fscache_end_io() called with a suitable error
+ code..
+
+
+ (*) Request pages be read from cache [mandatory]:
+
+ int (*read_or_alloc_pages)(struct fscache_retrieval *op,
+ struct list_head *pages,
+ unsigned *nr_pages,
+ gfp_t gfp)
+
+ This is like the read_or_alloc_page() method, except it is handed a list
+ of pages instead of one page. Any pages on which a read operation is
+ started must be added to the page cache for the specified mapping and also
+ to the LRU. Such pages must also be removed from the pages list and
+ *nr_pages decremented per page.
+
+ If there was an error such as -ENOMEM, then that should be returned; else
+ if one or more pages couldn't be read or allocated, then -ENOBUFS should
+ be returned; else if one or more pages couldn't be read, then -ENODATA
+ should be returned. If all the pages are dispatched then 0 should be
+ returned.
+
+
+ (*) Request page be allocated in the cache [mandatory]:
+
+ int (*allocate_page)(struct fscache_retrieval *op,
+ struct page *page,
+ gfp_t gfp)
+
+ This is like the read_or_alloc_page() method, except that it shouldn't
+ read from the cache, even if there's data there that could be retrieved.
+ It should, however, set up any internal metadata required such that
+ the write_page() method can write to the cache.
+
+ If there's no backing block available, then -ENOBUFS should be returned
+ (or -ENOMEM if there were other problems). If a block is successfully
+ allocated, then the netfs page should be marked and 0 returned.
+
+
+ (*) Request pages be allocated in the cache [mandatory]:
+
+ int (*allocate_pages)(struct fscache_retrieval *op,
+ struct list_head *pages,
+ unsigned *nr_pages,
+ gfp_t gfp)
+
+ This is an multiple page version of the allocate_page() method. pages and
+ nr_pages should be treated as for the read_or_alloc_pages() method.
+
+
+ (*) Request page be written to cache [mandatory]:
+
+ int (*write_page)(struct fscache_storage *op,
+ struct page *page);
+
+ This is called to write from a page on which there was a previously
+ successful read_or_alloc_page() call or similar. FS-Cache filters out
+ pages that don't have mappings.
+
+ This method is called asynchronously from the FS-Cache thread pool. It is
+ not required to actually store anything, provided -ENODATA is then
+ returned to the next read of this page.
+
+ If an error occurred, then a negative error code should be returned,
+ otherwise zero should be returned. FS-Cache will take appropriate action
+ in response to an error, such as withdrawing this object.
+
+ If this method returns success then FS-Cache will inform the netfs
+ appropriately.
+
+
+ (*) Discard retained per-page metadata [mandatory]:
+
+ void (*uncache_page)(struct fscache_object *object, struct page *page)
+
+ This is called when a netfs page is being evicted from the pagecache. The
+ cache backend should tear down any internal representation or tracking it
+ maintains for this page.
+
+
+==================
+FS-CACHE UTILITIES
+==================
+
+FS-Cache provides some utilities that a cache backend may make use of:
+
+ (*) Note occurrence of an I/O error in a cache:
+
+ void fscache_io_error(struct fscache_cache *cache)
+
+ This tells FS-Cache that an I/O error occurred in the cache. After this
+ has been called, only resource dissociation operations (object and page
+ release) will be passed from the netfs to the cache backend for the
+ specified cache.
+
+ This does not actually withdraw the cache. That must be done separately.
+
+
+ (*) Invoke the retrieval I/O completion function:
+
+ void fscache_end_io(struct fscache_retrieval *op, struct page *page,
+ int error);
+
+ This is called to note the end of an attempt to retrieve a page. The
+ error value should be 0 if successful and an error otherwise.
+
+
+ (*) Set highest store limit:
+
+ void fscache_set_store_limit(struct fscache_object *object,
+ loff_t i_size);
+
+ This sets the limit FS-Cache imposes on the highest byte it's willing to
+ try and store for a netfs. Any page over this limit is automatically
+ rejected by fscache_read_alloc_page() and co with -ENOBUFS.
+
+
+ (*) Mark pages as being cached:
+
+ void fscache_mark_pages_cached(struct fscache_retrieval *op,
+ struct pagevec *pagevec);
+
+ This marks a set of pages as being cached. After this has been called,
+ the netfs must call fscache_uncache_page() to unmark the pages.
+
+
+ (*) Perform coherency check on an object:
+
+ enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
+ const void *data,
+ uint16_t datalen);
+
+ This asks the netfs to perform a coherency check on an object that has
+ just been looked up. The cookie attached to the object will determine the
+ netfs to use. data and datalen should specify where the auxiliary data
+ retrieved from the cache can be found.
+
+ One of three values will be returned:
+
+ (*) FSCACHE_CHECKAUX_OKAY
+
+ The coherency data indicates the object is valid as is.
+
+ (*) FSCACHE_CHECKAUX_NEEDS_UPDATE
+
+ The coherency data needs updating, but otherwise the object is
+ valid.
+
+ (*) FSCACHE_CHECKAUX_OBSOLETE
+
+ The coherency data indicates that the object is obsolete and should
+ be discarded.
+
+
+ (*) Initialise a freshly allocated object:
+
+ void fscache_object_init(struct fscache_object *object);
+
+ This initialises all the fields in an object representation.
+
+
+ (*) Indicate the destruction of an object:
+
+ void fscache_object_destroyed(struct fscache_cache *cache);
+
+ This must be called to inform FS-Cache that an object that belonged to a
+ cache has been destroyed and deallocated. This will allow continuation
+ of the cache withdrawal process when it is stopped pending destruction of
+ all the objects.
+
+
+ (*) Indicate negative lookup on an object:
+
+ void fscache_object_lookup_negative(struct fscache_object *object);
+
+ This is called to indicate to FS-Cache that a lookup process for an object
+ found a negative result.
+
+ This changes the state of an object to permit reads pending on lookup
+ completion to go off and start fetching data from the netfs server as it's
+ known at this point that there can't be any data in the cache.
+
+ This may be called multiple times on an object. Only the first call is
+ significant - all subsequent calls are ignored.
+
+
+ (*) Indicate an object has been obtained:
+
+ void fscache_obtained_object(struct fscache_object *object);
+
+ This is called to indicate to FS-Cache that a lookup process for an object
+ produced a positive result, or that an object was created. This should
+ only be called once for any particular object.
+
+ This changes the state of an object to indicate:
+
+ (1) if no call to fscache_object_lookup_negative() has been made on
+ this object, that there may be data available, and that reads can
+ now go and look for it; and
+
+ (2) that writes may now proceed against this object.
+
+
+ (*) Indicate that object lookup failed:
+
+ void fscache_object_lookup_error(struct fscache_object *object);
+
+ This marks an object as having encountered a fatal error (usually EIO)
+ and causes it to move into a state whereby it will be withdrawn as soon
+ as possible.
+
+
+ (*) Get and release references on a retrieval record:
+
+ void fscache_get_retrieval(struct fscache_retrieval *op);
+ void fscache_put_retrieval(struct fscache_retrieval *op);
+
+ These two functions are used to retain a retrieval record whilst doing
+ asynchronous data retrieval and block allocation.
+
+
+ (*) Enqueue a retrieval record for processing.
+
+ void fscache_enqueue_retrieval(struct fscache_retrieval *op);
+
+ This enqueues a retrieval record for processing by the FS-Cache thread
+ pool. One of the threads in the pool will invoke the retrieval record's
+ op->op.processor callback function. This function may be called from
+ within the callback function.
+
+
+ (*) List of object state names:
+
+ const char *fscache_object_states[];
+
+ For debugging purposes, this may be used to turn the state that an object
+ is in into a text string for display purposes.
diff --git a/Documentation/filesystems/caching/cachefiles.txt b/Documentation/filesystems/caching/cachefiles.txt
new file mode 100644
index 000000000000..c78a49b7bba6
--- /dev/null
+++ b/Documentation/filesystems/caching/cachefiles.txt
@@ -0,0 +1,501 @@
+ ===============================================
+ CacheFiles: CACHE ON ALREADY MOUNTED FILESYSTEM
+ ===============================================
+
+Contents:
+
+ (*) Overview.
+
+ (*) Requirements.
+
+ (*) Configuration.
+
+ (*) Starting the cache.
+
+ (*) Things to avoid.
+
+ (*) Cache culling.
+
+ (*) Cache structure.
+
+ (*) Security model and SELinux.
+
+ (*) A note on security.
+
+ (*) Statistical information.
+
+ (*) Debugging.
+
+
+========
+OVERVIEW
+========
+
+CacheFiles is a caching backend that's meant to use as a cache a directory on
+an already mounted filesystem of a local type (such as Ext3).
+
+CacheFiles uses a userspace daemon to do some of the cache management - such as
+reaping stale nodes and culling. This is called cachefilesd and lives in
+/sbin.
+
+The filesystem and data integrity of the cache are only as good as those of the
+filesystem providing the backing services. Note that CacheFiles does not
+attempt to journal anything since the journalling interfaces of the various
+filesystems are very specific in nature.
+
+CacheFiles creates a misc character device - "/dev/cachefiles" - that is used
+to communication with the daemon. Only one thing may have this open at once,
+and whilst it is open, a cache is at least partially in existence. The daemon
+opens this and sends commands down it to control the cache.
+
+CacheFiles is currently limited to a single cache.
+
+CacheFiles attempts to maintain at least a certain percentage of free space on
+the filesystem, shrinking the cache by culling the objects it contains to make
+space if necessary - see the "Cache Culling" section. This means it can be
+placed on the same medium as a live set of data, and will expand to make use of
+spare space and automatically contract when the set of data requires more
+space.
+
+
+============
+REQUIREMENTS
+============
+
+The use of CacheFiles and its daemon requires the following features to be
+available in the system and in the cache filesystem:
+
+ - dnotify.
+
+ - extended attributes (xattrs).
+
+ - openat() and friends.
+
+ - bmap() support on files in the filesystem (FIBMAP ioctl).
+
+ - The use of bmap() to detect a partial page at the end of the file.
+
+It is strongly recommended that the "dir_index" option is enabled on Ext3
+filesystems being used as a cache.
+
+
+=============
+CONFIGURATION
+=============
+
+The cache is configured by a script in /etc/cachefilesd.conf. These commands
+set up cache ready for use. The following script commands are available:
+
+ (*) brun <N>%
+ (*) bcull <N>%
+ (*) bstop <N>%
+ (*) frun <N>%
+ (*) fcull <N>%
+ (*) fstop <N>%
+
+ Configure the culling limits. Optional. See the section on culling
+ The defaults are 7% (run), 5% (cull) and 1% (stop) respectively.
+
+ The commands beginning with a 'b' are file space (block) limits, those
+ beginning with an 'f' are file count limits.
+
+ (*) dir <path>
+
+ Specify the directory containing the root of the cache. Mandatory.
+
+ (*) tag <name>
+
+ Specify a tag to FS-Cache to use in distinguishing multiple caches.
+ Optional. The default is "CacheFiles".
+
+ (*) debug <mask>
+
+ Specify a numeric bitmask to control debugging in the kernel module.
+ Optional. The default is zero (all off). The following values can be
+ OR'd into the mask to collect various information:
+
+ 1 Turn on trace of function entry (_enter() macros)
+ 2 Turn on trace of function exit (_leave() macros)
+ 4 Turn on trace of internal debug points (_debug())
+
+ This mask can also be set through sysfs, eg:
+
+ echo 5 >/sys/modules/cachefiles/parameters/debug
+
+
+==================
+STARTING THE CACHE
+==================
+
+The cache is started by running the daemon. The daemon opens the cache device,
+configures the cache and tells it to begin caching. At that point the cache
+binds to fscache and the cache becomes live.
+
+The daemon is run as follows:
+
+ /sbin/cachefilesd [-d]* [-s] [-n] [-f <configfile>]
+
+The flags are:
+
+ (*) -d
+
+ Increase the debugging level. This can be specified multiple times and
+ is cumulative with itself.
+
+ (*) -s
+
+ Send messages to stderr instead of syslog.
+
+ (*) -n
+
+ Don't daemonise and go into background.
+
+ (*) -f <configfile>
+
+ Use an alternative configuration file rather than the default one.
+
+
+===============
+THINGS TO AVOID
+===============
+
+Do not mount other things within the cache as this will cause problems. The
+kernel module contains its own very cut-down path walking facility that ignores
+mountpoints, but the daemon can't avoid them.
+
+Do not create, rename or unlink files and directories in the cache whilst the
+cache is active, as this may cause the state to become uncertain.
+
+Renaming files in the cache might make objects appear to be other objects (the
+filename is part of the lookup key).
+
+Do not change or remove the extended attributes attached to cache files by the
+cache as this will cause the cache state management to get confused.
+
+Do not create files or directories in the cache, lest the cache get confused or
+serve incorrect data.
+
+Do not chmod files in the cache. The module creates things with minimal
+permissions to prevent random users being able to access them directly.
+
+
+=============
+CACHE CULLING
+=============
+
+The cache may need culling occasionally to make space. This involves
+discarding objects from the cache that have been used less recently than
+anything else. Culling is based on the access time of data objects. Empty
+directories are culled if not in use.
+
+Cache culling is done on the basis of the percentage of blocks and the
+percentage of files available in the underlying filesystem. There are six
+"limits":
+
+ (*) brun
+ (*) frun
+
+ If the amount of free space and the number of available files in the cache
+ rises above both these limits, then culling is turned off.
+
+ (*) bcull
+ (*) fcull
+
+ If the amount of available space or the number of available files in the
+ cache falls below either of these limits, then culling is started.
+
+ (*) bstop
+ (*) fstop
+
+ If the amount of available space or the number of available files in the
+ cache falls below either of these limits, then no further allocation of
+ disk space or files is permitted until culling has raised things above
+ these limits again.
+
+These must be configured thusly:
+
+ 0 <= bstop < bcull < brun < 100
+ 0 <= fstop < fcull < frun < 100
+
+Note that these are percentages of available space and available files, and do
+_not_ appear as 100 minus the percentage displayed by the "df" program.
+
+The userspace daemon scans the cache to build up a table of cullable objects.
+These are then culled in least recently used order. A new scan of the cache is
+started as soon as space is made in the table. Objects will be skipped if
+their atimes have changed or if the kernel module says it is still using them.
+
+
+===============
+CACHE STRUCTURE
+===============
+
+The CacheFiles module will create two directories in the directory it was
+given:
+
+ (*) cache/
+
+ (*) graveyard/
+
+The active cache objects all reside in the first directory. The CacheFiles
+kernel module moves any retired or culled objects that it can't simply unlink
+to the graveyard from which the daemon will actually delete them.
+
+The daemon uses dnotify to monitor the graveyard directory, and will delete
+anything that appears therein.
+
+
+The module represents index objects as directories with the filename "I..." or
+"J...". Note that the "cache/" directory is itself a special index.
+
+Data objects are represented as files if they have no children, or directories
+if they do. Their filenames all begin "D..." or "E...". If represented as a
+directory, data objects will have a file in the directory called "data" that
+actually holds the data.
+
+Special objects are similar to data objects, except their filenames begin
+"S..." or "T...".
+
+
+If an object has children, then it will be represented as a directory.
+Immediately in the representative directory are a collection of directories
+named for hash values of the child object keys with an '@' prepended. Into
+this directory, if possible, will be placed the representations of the child
+objects:
+
+ INDEX INDEX INDEX DATA FILES
+ ========= ========== ================================= ================
+ cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400
+ cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...DB1ry
+ cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...N22ry
+ cache/@4a/I03nfs/@30/Ji000000000000000--fHg8hi8400/@75/Es0g000w...FP1ry
+
+
+If the key is so long that it exceeds NAME_MAX with the decorations added on to
+it, then it will be cut into pieces, the first few of which will be used to
+make a nest of directories, and the last one of which will be the objects
+inside the last directory. The names of the intermediate directories will have
+'+' prepended:
+
+ J1223/@23/+xy...z/+kl...m/Epqr
+
+
+Note that keys are raw data, and not only may they exceed NAME_MAX in size,
+they may also contain things like '/' and NUL characters, and so they may not
+be suitable for turning directly into a filename.
+
+To handle this, CacheFiles will use a suitably printable filename directly and
+"base-64" encode ones that aren't directly suitable. The two versions of
+object filenames indicate the encoding:
+
+ OBJECT TYPE PRINTABLE ENCODED
+ =============== =============== ===============
+ Index "I..." "J..."
+ Data "D..." "E..."
+ Special "S..." "T..."
+
+Intermediate directories are always "@" or "+" as appropriate.
+
+
+Each object in the cache has an extended attribute label that holds the object
+type ID (required to distinguish special objects) and the auxiliary data from
+the netfs. The latter is used to detect stale objects in the cache and update
+or retire them.
+
+
+Note that CacheFiles will erase from the cache any file it doesn't recognise or
+any file of an incorrect type (such as a FIFO file or a device file).
+
+
+==========================
+SECURITY MODEL AND SELINUX
+==========================
+
+CacheFiles is implemented to deal properly with the LSM security features of
+the Linux kernel and the SELinux facility.
+
+One of the problems that CacheFiles faces is that it is generally acting on
+behalf of a process, and running in that process's context, and that includes a
+security context that is not appropriate for accessing the cache - either
+because the files in the cache are inaccessible to that process, or because if
+the process creates a file in the cache, that file may be inaccessible to other
+processes.
+
+The way CacheFiles works is to temporarily change the security context (fsuid,
+fsgid and actor security label) that the process acts as - without changing the
+security context of the process when it the target of an operation performed by
+some other process (so signalling and suchlike still work correctly).
+
+
+When the CacheFiles module is asked to bind to its cache, it:
+
+ (1) Finds the security label attached to the root cache directory and uses
+ that as the security label with which it will create files. By default,
+ this is:
+
+ cachefiles_var_t
+
+ (2) Finds the security label of the process which issued the bind request
+ (presumed to be the cachefilesd daemon), which by default will be:
+
+ cachefilesd_t
+
+ and asks LSM to supply a security ID as which it should act given the
+ daemon's label. By default, this will be:
+
+ cachefiles_kernel_t
+
+ SELinux transitions the daemon's security ID to the module's security ID
+ based on a rule of this form in the policy.
+
+ type_transition <daemon's-ID> kernel_t : process <module's-ID>;
+
+ For instance:
+
+ type_transition cachefilesd_t kernel_t : process cachefiles_kernel_t;
+
+
+The module's security ID gives it permission to create, move and remove files
+and directories in the cache, to find and access directories and files in the
+cache, to set and access extended attributes on cache objects, and to read and
+write files in the cache.
+
+The daemon's security ID gives it only a very restricted set of permissions: it
+may scan directories, stat files and erase files and directories. It may
+not read or write files in the cache, and so it is precluded from accessing the
+data cached therein; nor is it permitted to create new files in the cache.
+
+
+There are policy source files available in:
+
+ http://people.redhat.com/~dhowells/fscache/cachefilesd-0.8.tar.bz2
+
+and later versions. In that tarball, see the files:
+
+ cachefilesd.te
+ cachefilesd.fc
+ cachefilesd.if
+
+They are built and installed directly by the RPM.
+
+If a non-RPM based system is being used, then copy the above files to their own
+directory and run:
+
+ make -f /usr/share/selinux/devel/Makefile
+ semodule -i cachefilesd.pp
+
+You will need checkpolicy and selinux-policy-devel installed prior to the
+build.
+
+
+By default, the cache is located in /var/fscache, but if it is desirable that
+it should be elsewhere, than either the above policy files must be altered, or
+an auxiliary policy must be installed to label the alternate location of the
+cache.
+
+For instructions on how to add an auxiliary policy to enable the cache to be
+located elsewhere when SELinux is in enforcing mode, please see:
+
+ /usr/share/doc/cachefilesd-*/move-cache.txt
+
+When the cachefilesd rpm is installed; alternatively, the document can be found
+in the sources.
+
+
+==================
+A NOTE ON SECURITY
+==================
+
+CacheFiles makes use of the split security in the task_struct. It allocates
+its own task_security structure, and redirects current->act_as to point to it
+when it acts on behalf of another process, in that process's context.
+
+The reason it does this is that it calls vfs_mkdir() and suchlike rather than
+bypassing security and calling inode ops directly. Therefore the VFS and LSM
+may deny the CacheFiles access to the cache data because under some
+circumstances the caching code is running in the security context of whatever
+process issued the original syscall on the netfs.
+
+Furthermore, should CacheFiles create a file or directory, the security
+parameters with that object is created (UID, GID, security label) would be
+derived from that process that issued the system call, thus potentially
+preventing other processes from accessing the cache - including CacheFiles's
+cache management daemon (cachefilesd).
+
+What is required is to temporarily override the security of the process that
+issued the system call. We can't, however, just do an in-place change of the
+security data as that affects the process as an object, not just as a subject.
+This means it may lose signals or ptrace events for example, and affects what
+the process looks like in /proc.
+
+So CacheFiles makes use of a logical split in the security between the
+objective security (task->sec) and the subjective security (task->act_as). The
+objective security holds the intrinsic security properties of a process and is
+never overridden. This is what appears in /proc, and is what is used when a
+process is the target of an operation by some other process (SIGKILL for
+example).
+
+The subjective security holds the active security properties of a process, and
+may be overridden. This is not seen externally, and is used whan a process
+acts upon another object, for example SIGKILLing another process or opening a
+file.
+
+LSM hooks exist that allow SELinux (or Smack or whatever) to reject a request
+for CacheFiles to run in a context of a specific security label, or to create
+files and directories with another security label.
+
+
+=======================
+STATISTICAL INFORMATION
+=======================
+
+If FS-Cache is compiled with the following option enabled:
+
+ CONFIG_CACHEFILES_HISTOGRAM=y
+
+then it will gather certain statistics and display them through a proc file.
+
+ (*) /proc/fs/cachefiles/histogram
+
+ cat /proc/fs/cachefiles/histogram
+ JIFS SECS LOOKUPS MKDIRS CREATES
+ ===== ===== ========= ========= =========
+
+ This shows the breakdown of the number of times each amount of time
+ between 0 jiffies and HZ-1 jiffies a variety of tasks took to run. The
+ columns are as follows:
+
+ COLUMN TIME MEASUREMENT
+ ======= =======================================================
+ LOOKUPS Length of time to perform a lookup on the backing fs
+ MKDIRS Length of time to perform a mkdir on the backing fs
+ CREATES Length of time to perform a create on the backing fs
+
+ Each row shows the number of events that took a particular range of times.
+ Each step is 1 jiffy in size. The JIFS column indicates the particular
+ jiffy range covered, and the SECS field the equivalent number of seconds.
+
+
+=========
+DEBUGGING
+=========
+
+If CONFIG_CACHEFILES_DEBUG is enabled, the CacheFiles facility can have runtime
+debugging enabled by adjusting the value in:
+
+ /sys/module/cachefiles/parameters/debug
+
+This is a bitmask of debugging streams to enable:
+
+ BIT VALUE STREAM POINT
+ ======= ======= =============================== =======================
+ 0 1 General Function entry trace
+ 1 2 Function exit trace
+ 2 4 General
+
+The appropriate set of values should be OR'd together and the result written to
+the control file. For example:
+
+ echo $((1|4|8)) >/sys/module/cachefiles/parameters/debug
+
+will turn on all function entry debugging.
diff --git a/Documentation/filesystems/caching/fscache.txt b/Documentation/filesystems/caching/fscache.txt
new file mode 100644
index 000000000000..9e94b9491d89
--- /dev/null
+++ b/Documentation/filesystems/caching/fscache.txt
@@ -0,0 +1,333 @@
+ ==========================
+ General Filesystem Caching
+ ==========================
+
+========
+OVERVIEW
+========
+
+This facility is a general purpose cache for network filesystems, though it
+could be used for caching other things such as ISO9660 filesystems too.
+
+FS-Cache mediates between cache backends (such as CacheFS) and network
+filesystems:
+
+ +---------+
+ | | +--------------+
+ | NFS |--+ | |
+ | | | +-->| CacheFS |
+ +---------+ | +----------+ | | /dev/hda5 |
+ | | | | +--------------+
+ +---------+ +-->| | |
+ | | | |--+
+ | AFS |----->| FS-Cache |
+ | | | |--+
+ +---------+ +-->| | |
+ | | | | +--------------+
+ +---------+ | +----------+ | | |
+ | | | +-->| CacheFiles |
+ | ISOFS |--+ | /var/cache |
+ | | +--------------+
+ +---------+
+
+Or to look at it another way, FS-Cache is a module that provides a caching
+facility to a network filesystem such that the cache is transparent to the
+user:
+
+ +---------+
+ | |
+ | Server |
+ | |
+ +---------+
+ | NETWORK
+ ~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ |
+ | +----------+
+ V | |
+ +---------+ | |
+ | | | |
+ | NFS |----->| FS-Cache |
+ | | | |--+
+ +---------+ | | | +--------------+ +--------------+
+ | | | | | | | |
+ V +----------+ +-->| CacheFiles |-->| Ext3 |
+ +---------+ | /var/cache | | /dev/sda6 |
+ | | +--------------+ +--------------+
+ | VFS | ^ ^
+ | | | |
+ +---------+ +--------------+ |
+ | KERNEL SPACE | |
+ ~~~~~|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~~~~~~|~~~~
+ | USER SPACE | |
+ V | |
+ +---------+ +--------------+
+ | | | |
+ | Process | | cachefilesd |
+ | | | |
+ +---------+ +--------------+
+
+
+FS-Cache does not follow the idea of completely loading every netfs file
+opened in its entirety into a cache before permitting it to be accessed and
+then serving the pages out of that cache rather than the netfs inode because:
+
+ (1) It must be practical to operate without a cache.
+
+ (2) The size of any accessible file must not be limited to the size of the
+ cache.
+
+ (3) The combined size of all opened files (this includes mapped libraries)
+ must not be limited to the size of the cache.
+
+ (4) The user should not be forced to download an entire file just to do a
+ one-off access of a small portion of it (such as might be done with the
+ "file" program).
+
+It instead serves the cache out in PAGE_SIZE chunks as and when requested by
+the netfs('s) using it.
+
+
+FS-Cache provides the following facilities:
+
+ (1) More than one cache can be used at once. Caches can be selected
+ explicitly by use of tags.
+
+ (2) Caches can be added / removed at any time.
+
+ (3) The netfs is provided with an interface that allows either party to
+ withdraw caching facilities from a file (required for (2)).
+
+ (4) The interface to the netfs returns as few errors as possible, preferring
+ rather to let the netfs remain oblivious.
+
+ (5) Cookies are used to represent indices, files and other objects to the
+ netfs. The simplest cookie is just a NULL pointer - indicating nothing
+ cached there.
+
+ (6) The netfs is allowed to propose - dynamically - any index hierarchy it
+ desires, though it must be aware that the index search function is
+ recursive, stack space is limited, and indices can only be children of
+ indices.
+
+ (7) Data I/O is done direct to and from the netfs's pages. The netfs
+ indicates that page A is at index B of the data-file represented by cookie
+ C, and that it should be read or written. The cache backend may or may
+ not start I/O on that page, but if it does, a netfs callback will be
+ invoked to indicate completion. The I/O may be either synchronous or
+ asynchronous.
+
+ (8) Cookies can be "retired" upon release. At this point FS-Cache will mark
+ them as obsolete and the index hierarchy rooted at that point will get
+ recycled.
+
+ (9) The netfs provides a "match" function for index searches. In addition to
+ saying whether a match was made or not, this can also specify that an
+ entry should be updated or deleted.
+
+(10) As much as possible is done asynchronously.
+
+
+FS-Cache maintains a virtual indexing tree in which all indices, files, objects
+and pages are kept. Bits of this tree may actually reside in one or more
+caches.
+
+ FSDEF
+ |
+ +------------------------------------+
+ | |
+ NFS AFS
+ | |
+ +--------------------------+ +-----------+
+ | | | |
+ homedir mirror afs.org redhat.com
+ | | |
+ +------------+ +---------------+ +----------+
+ | | | | | |
+ 00001 00002 00007 00125 vol00001 vol00002
+ | | | | |
+ +---+---+ +-----+ +---+ +------+------+ +-----+----+
+ | | | | | | | | | | | | |
+PG0 PG1 PG2 PG0 XATTR PG0 PG1 DIRENT DIRENT DIRENT R/W R/O Bak
+ | |
+ PG0 +-------+
+ | |
+ 00001 00003
+ |
+ +---+---+
+ | | |
+ PG0 PG1 PG2
+
+In the example above, you can see two netfs's being backed: NFS and AFS. These
+have different index hierarchies:
+
+ (*) The NFS primary index contains per-server indices. Each server index is
+ indexed by NFS file handles to get data file objects. Each data file
+ objects can have an array of pages, but may also have further child
+ objects, such as extended attributes and directory entries. Extended
+ attribute objects themselves have page-array contents.
+
+ (*) The AFS primary index contains per-cell indices. Each cell index contains
+ per-logical-volume indices. Each of volume index contains up to three
+ indices for the read-write, read-only and backup mirrors of those volumes.
+ Each of these contains vnode data file objects, each of which contains an
+ array of pages.
+
+The very top index is the FS-Cache master index in which individual netfs's
+have entries.
+
+Any index object may reside in more than one cache, provided it only has index
+children. Any index with non-index object children will be assumed to only
+reside in one cache.
+
+
+The netfs API to FS-Cache can be found in:
+
+ Documentation/filesystems/caching/netfs-api.txt
+
+The cache backend API to FS-Cache can be found in:
+
+ Documentation/filesystems/caching/backend-api.txt
+
+A description of the internal representations and object state machine can be
+found in:
+
+ Documentation/filesystems/caching/object.txt
+
+
+=======================
+STATISTICAL INFORMATION
+=======================
+
+If FS-Cache is compiled with the following options enabled:
+
+ CONFIG_FSCACHE_STATS=y
+ CONFIG_FSCACHE_HISTOGRAM=y
+
+then it will gather certain statistics and display them through a number of
+proc files.
+
+ (*) /proc/fs/fscache/stats
+
+ This shows counts of a number of events that can happen in FS-Cache:
+
+ CLASS EVENT MEANING
+ ======= ======= =======================================================
+ Cookies idx=N Number of index cookies allocated
+ dat=N Number of data storage cookies allocated
+ spc=N Number of special cookies allocated
+ Objects alc=N Number of objects allocated
+ nal=N Number of object allocation failures
+ avl=N Number of objects that reached the available state
+ ded=N Number of objects that reached the dead state
+ ChkAux non=N Number of objects that didn't have a coherency check
+ ok=N Number of objects that passed a coherency check
+ upd=N Number of objects that needed a coherency data update
+ obs=N Number of objects that were declared obsolete
+ Pages mrk=N Number of pages marked as being cached
+ unc=N Number of uncache page requests seen
+ Acquire n=N Number of acquire cookie requests seen
+ nul=N Number of acq reqs given a NULL parent
+ noc=N Number of acq reqs rejected due to no cache available
+ ok=N Number of acq reqs succeeded
+ nbf=N Number of acq reqs rejected due to error
+ oom=N Number of acq reqs failed on ENOMEM
+ Lookups n=N Number of lookup calls made on cache backends
+ neg=N Number of negative lookups made
+ pos=N Number of positive lookups made
+ crt=N Number of objects created by lookup
+ Updates n=N Number of update cookie requests seen
+ nul=N Number of upd reqs given a NULL parent
+ run=N Number of upd reqs granted CPU time
+ Relinqs n=N Number of relinquish cookie requests seen
+ nul=N Number of rlq reqs given a NULL parent
+ wcr=N Number of rlq reqs waited on completion of creation
+ AttrChg n=N Number of attribute changed requests seen
+ ok=N Number of attr changed requests queued
+ nbf=N Number of attr changed rejected -ENOBUFS
+ oom=N Number of attr changed failed -ENOMEM
+ run=N Number of attr changed ops given CPU time
+ Allocs n=N Number of allocation requests seen
+ ok=N Number of successful alloc reqs
+ wt=N Number of alloc reqs that waited on lookup completion
+ nbf=N Number of alloc reqs rejected -ENOBUFS
+ ops=N Number of alloc reqs submitted
+ owt=N Number of alloc reqs waited for CPU time
+ Retrvls n=N Number of retrieval (read) requests seen
+ ok=N Number of successful retr reqs
+ wt=N Number of retr reqs that waited on lookup completion
+ nod=N Number of retr reqs returned -ENODATA
+ nbf=N Number of retr reqs rejected -ENOBUFS
+ int=N Number of retr reqs aborted -ERESTARTSYS
+ oom=N Number of retr reqs failed -ENOMEM
+ ops=N Number of retr reqs submitted
+ owt=N Number of retr reqs waited for CPU time
+ Stores n=N Number of storage (write) requests seen
+ ok=N Number of successful store reqs
+ agn=N Number of store reqs on a page already pending storage
+ nbf=N Number of store reqs rejected -ENOBUFS
+ oom=N Number of store reqs failed -ENOMEM
+ ops=N Number of store reqs submitted
+ run=N Number of store reqs granted CPU time
+ Ops pend=N Number of times async ops added to pending queues
+ run=N Number of times async ops given CPU time
+ enq=N Number of times async ops queued for processing
+ dfr=N Number of async ops queued for deferred release
+ rel=N Number of async ops released
+ gc=N Number of deferred-release async ops garbage collected
+
+
+ (*) /proc/fs/fscache/histogram
+
+ cat /proc/fs/fscache/histogram
+ JIFS SECS OBJ INST OP RUNS OBJ RUNS RETRV DLY RETRIEVLS
+ ===== ===== ========= ========= ========= ========= =========
+
+ This shows the breakdown of the number of times each amount of time
+ between 0 jiffies and HZ-1 jiffies a variety of tasks took to run. The
+ columns are as follows:
+
+ COLUMN TIME MEASUREMENT
+ ======= =======================================================
+ OBJ INST Length of time to instantiate an object
+ OP RUNS Length of time a call to process an operation took
+ OBJ RUNS Length of time a call to process an object event took
+ RETRV DLY Time between an requesting a read and lookup completing
+ RETRIEVLS Time between beginning and end of a retrieval
+
+ Each row shows the number of events that took a particular range of times.
+ Each step is 1 jiffy in size. The JIFS column indicates the particular
+ jiffy range covered, and the SECS field the equivalent number of seconds.
+
+
+=========
+DEBUGGING
+=========
+
+If CONFIG_FSCACHE_DEBUG is enabled, the FS-Cache facility can have runtime
+debugging enabled by adjusting the value in:
+
+ /sys/module/fscache/parameters/debug
+
+This is a bitmask of debugging streams to enable:
+
+ BIT VALUE STREAM POINT
+ ======= ======= =============================== =======================
+ 0 1 Cache management Function entry trace
+ 1 2 Function exit trace
+ 2 4 General
+ 3 8 Cookie management Function entry trace
+ 4 16 Function exit trace
+ 5 32 General
+ 6 64 Page handling Function entry trace
+ 7 128 Function exit trace
+ 8 256 General
+ 9 512 Operation management Function entry trace
+ 10 1024 Function exit trace
+ 11 2048 General
+
+The appropriate set of values should be OR'd together and the result written to
+the control file. For example:
+
+ echo $((1|8|64)) >/sys/module/fscache/parameters/debug
+
+will turn on all function entry debugging.
diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt
new file mode 100644
index 000000000000..4db125b3a5c6
--- /dev/null
+++ b/Documentation/filesystems/caching/netfs-api.txt
@@ -0,0 +1,778 @@
+ ===============================
+ FS-CACHE NETWORK FILESYSTEM API
+ ===============================
+
+There's an API by which a network filesystem can make use of the FS-Cache
+facilities. This is based around a number of principles:
+
+ (1) Caches can store a number of different object types. There are two main
+ object types: indices and files. The first is a special type used by
+ FS-Cache to make finding objects faster and to make retiring of groups of
+ objects easier.
+
+ (2) Every index, file or other object is represented by a cookie. This cookie
+ may or may not have anything associated with it, but the netfs doesn't
+ need to care.
+
+ (3) Barring the top-level index (one entry per cached netfs), the index
+ hierarchy for each netfs is structured according the whim of the netfs.
+
+This API is declared in <linux/fscache.h>.
+
+This document contains the following sections:
+
+ (1) Network filesystem definition
+ (2) Index definition
+ (3) Object definition
+ (4) Network filesystem (un)registration
+ (5) Cache tag lookup
+ (6) Index registration
+ (7) Data file registration
+ (8) Miscellaneous object registration
+ (9) Setting the data file size
+ (10) Page alloc/read/write
+ (11) Page uncaching
+ (12) Index and data file update
+ (13) Miscellaneous cookie operations
+ (14) Cookie unregistration
+ (15) Index and data file invalidation
+ (16) FS-Cache specific page flags.
+
+
+=============================
+NETWORK FILESYSTEM DEFINITION
+=============================
+
+FS-Cache needs a description of the network filesystem. This is specified
+using a record of the following structure:
+
+ struct fscache_netfs {
+ uint32_t version;
+ const char *name;
+ struct fscache_cookie *primary_index;
+ ...
+ };
+
+This first two fields should be filled in before registration, and the third
+will be filled in by the registration function; any other fields should just be
+ignored and are for internal use only.
+
+The fields are:
+
+ (1) The name of the netfs (used as the key in the toplevel index).
+
+ (2) The version of the netfs (if the name matches but the version doesn't, the
+ entire in-cache hierarchy for this netfs will be scrapped and begun
+ afresh).
+
+ (3) The cookie representing the primary index will be allocated according to
+ another parameter passed into the registration function.
+
+For example, kAFS (linux/fs/afs/) uses the following definitions to describe
+itself:
+
+ struct fscache_netfs afs_cache_netfs = {
+ .version = 0,
+ .name = "afs",
+ };
+
+
+================
+INDEX DEFINITION
+================
+
+Indices are used for two purposes:
+
+ (1) To aid the finding of a file based on a series of keys (such as AFS's
+ "cell", "volume ID", "vnode ID").
+
+ (2) To make it easier to discard a subset of all the files cached based around
+ a particular key - for instance to mirror the removal of an AFS volume.
+
+However, since it's unlikely that any two netfs's are going to want to define
+their index hierarchies in quite the same way, FS-Cache tries to impose as few
+restraints as possible on how an index is structured and where it is placed in
+the tree. The netfs can even mix indices and data files at the same level, but
+it's not recommended.
+
+Each index entry consists of a key of indeterminate length plus some auxilliary
+data, also of indeterminate length.
+
+There are some limits on indices:
+
+ (1) Any index containing non-index objects should be restricted to a single
+ cache. Any such objects created within an index will be created in the
+ first cache only. The cache in which an index is created can be
+ controlled by cache tags (see below).
+
+ (2) The entry data must be atomically journallable, so it is limited to about
+ 400 bytes at present. At least 400 bytes will be available.
+
+ (3) The depth of the index tree should be judged with care as the search
+ function is recursive. Too many layers will run the kernel out of stack.
+
+
+=================
+OBJECT DEFINITION
+=================
+
+To define an object, a structure of the following type should be filled out:
+
+ struct fscache_cookie_def
+ {
+ uint8_t name[16];
+ uint8_t type;
+
+ struct fscache_cache_tag *(*select_cache)(
+ const void *parent_netfs_data,
+ const void *cookie_netfs_data);
+
+ uint16_t (*get_key)(const void *cookie_netfs_data,
+ void *buffer,
+ uint16_t bufmax);
+
+ void (*get_attr)(const void *cookie_netfs_data,
+ uint64_t *size);
+
+ uint16_t (*get_aux)(const void *cookie_netfs_data,
+ void *buffer,
+ uint16_t bufmax);
+
+ enum fscache_checkaux (*check_aux)(void *cookie_netfs_data,
+ const void *data,
+ uint16_t datalen);
+
+ void (*get_context)(void *cookie_netfs_data, void *context);
+
+ void (*put_context)(void *cookie_netfs_data, void *context);
+
+ void (*mark_pages_cached)(void *cookie_netfs_data,
+ struct address_space *mapping,
+ struct pagevec *cached_pvec);
+
+ void (*now_uncached)(void *cookie_netfs_data);
+ };
+
+This has the following fields:
+
+ (1) The type of the object [mandatory].
+
+ This is one of the following values:
+
+ (*) FSCACHE_COOKIE_TYPE_INDEX
+
+ This defines an index, which is a special FS-Cache type.
+
+ (*) FSCACHE_COOKIE_TYPE_DATAFILE
+
+ This defines an ordinary data file.
+
+ (*) Any other value between 2 and 255
+
+ This defines an extraordinary object such as an XATTR.
+
+ (2) The name of the object type (NUL terminated unless all 16 chars are used)
+ [optional].
+
+ (3) A function to select the cache in which to store an index [optional].
+
+ This function is invoked when an index needs to be instantiated in a cache
+ during the instantiation of a non-index object. Only the immediate index
+ parent for the non-index object will be queried. Any indices above that
+ in the hierarchy may be stored in multiple caches. This function does not
+ need to be supplied for any non-index object or any index that will only
+ have index children.
+
+ If this function is not supplied or if it returns NULL then the first
+ cache in the parent's list will be chosed, or failing that, the first
+ cache in the master list.
+
+ (4) A function to retrieve an object's key from the netfs [mandatory].
+
+ This function will be called with the netfs data that was passed to the
+ cookie acquisition function and the maximum length of key data that it may
+ provide. It should write the required key data into the given buffer and
+ return the quantity it wrote.
+
+ (5) A function to retrieve attribute data from the netfs [optional].
+
+ This function will be called with the netfs data that was passed to the
+ cookie acquisition function. It should return the size of the file if
+ this is a data file. The size may be used to govern how much cache must
+ be reserved for this file in the cache.
+
+ If the function is absent, a file size of 0 is assumed.
+
+ (6) A function to retrieve auxilliary data from the netfs [optional].
+
+ This function will be called with the netfs data that was passed to the
+ cookie acquisition function and the maximum length of auxilliary data that
+ it may provide. It should write the auxilliary data into the given buffer
+ and return the quantity it wrote.
+
+ If this function is absent, the auxilliary data length will be set to 0.
+
+ The length of the auxilliary data buffer may be dependent on the key
+ length. A netfs mustn't rely on being able to provide more than 400 bytes
+ for both.
+
+ (7) A function to check the auxilliary data [optional].
+
+ This function will be called to check that a match found in the cache for
+ this object is valid. For instance with AFS it could check the auxilliary
+ data against the data version number returned by the server to determine
+ whether the index entry in a cache is still valid.
+
+ If this function is absent, it will be assumed that matching objects in a
+ cache are always valid.
+
+ If present, the function should return one of the following values:
+
+ (*) FSCACHE_CHECKAUX_OKAY - the entry is okay as is
+ (*) FSCACHE_CHECKAUX_NEEDS_UPDATE - the entry requires update
+ (*) FSCACHE_CHECKAUX_OBSOLETE - the entry should be deleted
+
+ This function can also be used to extract data from the auxilliary data in
+ the cache and copy it into the netfs's structures.
+
+ (8) A pair of functions to manage contexts for the completion callback
+ [optional].
+
+ The cache read/write functions are passed a context which is then passed
+ to the I/O completion callback function. To ensure this context remains
+ valid until after the I/O completion is called, two functions may be
+ provided: one to get an extra reference on the context, and one to drop a
+ reference to it.
+
+ If the context is not used or is a type of object that won't go out of
+ scope, then these functions are not required. These functions are not
+ required for indices as indices may not contain data. These functions may
+ be called in interrupt context and so may not sleep.
+
+ (9) A function to mark a page as retaining cache metadata [optional].
+
+ This is called by the cache to indicate that it is retaining in-memory
+ information for this page and that the netfs should uncache the page when
+ it has finished. This does not indicate whether there's data on the disk
+ or not. Note that several pages at once may be presented for marking.
+
+ The PG_fscache bit is set on the pages before this function would be
+ called, so the function need not be provided if this is sufficient.
+
+ This function is not required for indices as they're not permitted data.
+
+(10) A function to unmark all the pages retaining cache metadata [mandatory].
+
+ This is called by FS-Cache to indicate that a backing store is being
+ unbound from a cookie and that all the marks on the pages should be
+ cleared to prevent confusion. Note that the cache will have torn down all
+ its tracking information so that the pages don't need to be explicitly
+ uncached.
+
+ This function is not required for indices as they're not permitted data.
+
+
+===================================
+NETWORK FILESYSTEM (UN)REGISTRATION
+===================================
+
+The first step is to declare the network filesystem to the cache. This also
+involves specifying the layout of the primary index (for AFS, this would be the
+"cell" level).
+
+The registration function is:
+
+ int fscache_register_netfs(struct fscache_netfs *netfs);
+
+It just takes a pointer to the netfs definition. It returns 0 or an error as
+appropriate.
+
+For kAFS, registration is done as follows:
+
+ ret = fscache_register_netfs(&afs_cache_netfs);
+
+The last step is, of course, unregistration:
+
+ void fscache_unregister_netfs(struct fscache_netfs *netfs);
+
+
+================
+CACHE TAG LOOKUP
+================
+
+FS-Cache permits the use of more than one cache. To permit particular index
+subtrees to be bound to particular caches, the second step is to look up cache
+representation tags. This step is optional; it can be left entirely up to
+FS-Cache as to which cache should be used. The problem with doing that is that
+FS-Cache will always pick the first cache that was registered.
+
+To get the representation for a named tag:
+
+ struct fscache_cache_tag *fscache_lookup_cache_tag(const char *name);
+
+This takes a text string as the name and returns a representation of a tag. It
+will never return an error. It may return a dummy tag, however, if it runs out
+of memory; this will inhibit caching with this tag.
+
+Any representation so obtained must be released by passing it to this function:
+
+ void fscache_release_cache_tag(struct fscache_cache_tag *tag);
+
+The tag will be retrieved by FS-Cache when it calls the object definition
+operation select_cache().
+
+
+==================
+INDEX REGISTRATION
+==================
+
+The third step is to inform FS-Cache about part of an index hierarchy that can
+be used to locate files. This is done by requesting a cookie for each index in
+the path to the file:
+
+ struct fscache_cookie *
+ fscache_acquire_cookie(struct fscache_cookie *parent,
+ const struct fscache_object_def *def,
+ void *netfs_data);
+
+This function creates an index entry in the index represented by parent,
+filling in the index entry by calling the operations pointed to by def.
+
+Note that this function never returns an error - all errors are handled
+internally. It may, however, return NULL to indicate no cookie. It is quite
+acceptable to pass this token back to this function as the parent to another
+acquisition (or even to the relinquish cookie, read page and write page
+functions - see below).
+
+Note also that no indices are actually created in a cache until a non-index
+object needs to be created somewhere down the hierarchy. Furthermore, an index
+may be created in several different caches independently at different times.
+This is all handled transparently, and the netfs doesn't see any of it.
+
+For example, with AFS, a cell would be added to the primary index. This index
+entry would have a dependent inode containing a volume location index for the
+volume mappings within this cell:
+
+ cell->cache =
+ fscache_acquire_cookie(afs_cache_netfs.primary_index,
+ &afs_cell_cache_index_def,
+ cell);
+
+Then when a volume location was accessed, it would be entered into the cell's
+index and an inode would be allocated that acts as a volume type and hash chain
+combination:
+
+ vlocation->cache =
+ fscache_acquire_cookie(cell->cache,
+ &afs_vlocation_cache_index_def,
+ vlocation);
+
+And then a particular flavour of volume (R/O for example) could be added to
+that index, creating another index for vnodes (AFS inode equivalents):
+
+ volume->cache =
+ fscache_acquire_cookie(vlocation->cache,
+ &afs_volume_cache_index_def,
+ volume);
+
+
+======================
+DATA FILE REGISTRATION
+======================
+
+The fourth step is to request a data file be created in the cache. This is
+identical to index cookie acquisition. The only difference is that the type in
+the object definition should be something other than index type.
+
+ vnode->cache =
+ fscache_acquire_cookie(volume->cache,
+ &afs_vnode_cache_object_def,
+ vnode);
+
+
+=================================
+MISCELLANEOUS OBJECT REGISTRATION
+=================================
+
+An optional step is to request an object of miscellaneous type be created in
+the cache. This is almost identical to index cookie acquisition. The only
+difference is that the type in the object definition should be something other
+than index type. Whilst the parent object could be an index, it's more likely
+it would be some other type of object such as a data file.
+
+ xattr->cache =
+ fscache_acquire_cookie(vnode->cache,
+ &afs_xattr_cache_object_def,
+ xattr);
+
+Miscellaneous objects might be used to store extended attributes or directory
+entries for example.
+
+
+==========================
+SETTING THE DATA FILE SIZE
+==========================
+
+The fifth step is to set the physical attributes of the file, such as its size.
+This doesn't automatically reserve any space in the cache, but permits the
+cache to adjust its metadata for data tracking appropriately:
+
+ int fscache_attr_changed(struct fscache_cookie *cookie);
+
+The cache will return -ENOBUFS if there is no backing cache or if there is no
+space to allocate any extra metadata required in the cache. The attributes
+will be accessed with the get_attr() cookie definition operation.
+
+Note that attempts to read or write data pages in the cache over this size may
+be rebuffed with -ENOBUFS.
+
+This operation schedules an attribute adjustment to happen asynchronously at
+some point in the future, and as such, it may happen after the function returns
+to the caller. The attribute adjustment excludes read and write operations.
+
+
+=====================
+PAGE READ/ALLOC/WRITE
+=====================
+
+And the sixth step is to store and retrieve pages in the cache. There are
+three functions that are used to do this.
+
+Note:
+
+ (1) A page should not be re-read or re-allocated without uncaching it first.
+
+ (2) A read or allocated page must be uncached when the netfs page is released
+ from the pagecache.
+
+ (3) A page should only be written to the cache if previous read or allocated.
+
+This permits the cache to maintain its page tracking in proper order.
+
+
+PAGE READ
+---------
+
+Firstly, the netfs should ask FS-Cache to examine the caches and read the
+contents cached for a particular page of a particular file if present, or else
+allocate space to store the contents if not:
+
+ typedef
+ void (*fscache_rw_complete_t)(struct page *page,
+ void *context,
+ int error);
+
+ int fscache_read_or_alloc_page(struct fscache_cookie *cookie,
+ struct page *page,
+ fscache_rw_complete_t end_io_func,
+ void *context,
+ gfp_t gfp);
+
+The cookie argument must specify a cookie for an object that isn't an index,
+the page specified will have the data loaded into it (and is also used to
+specify the page number), and the gfp argument is used to control how any
+memory allocations made are satisfied.
+
+If the cookie indicates the inode is not cached:
+
+ (1) The function will return -ENOBUFS.
+
+Else if there's a copy of the page resident in the cache:
+
+ (1) The mark_pages_cached() cookie operation will be called on that page.
+
+ (2) The function will submit a request to read the data from the cache's
+ backing device directly into the page specified.
+
+ (3) The function will return 0.
+
+ (4) When the read is complete, end_io_func() will be invoked with:
+
+ (*) The netfs data supplied when the cookie was created.
+
+ (*) The page descriptor.
+
+ (*) The context argument passed to the above function. This will be
+ maintained with the get_context/put_context functions mentioned above.
+
+ (*) An argument that's 0 on success or negative for an error code.
+
+ If an error occurs, it should be assumed that the page contains no usable
+ data.
+
+ end_io_func() will be called in process context if the read is results in
+ an error, but it might be called in interrupt context if the read is
+ successful.
+
+Otherwise, if there's not a copy available in cache, but the cache may be able
+to store the page:
+
+ (1) The mark_pages_cached() cookie operation will be called on that page.
+
+ (2) A block may be reserved in the cache and attached to the object at the
+ appropriate place.
+
+ (3) The function will return -ENODATA.
+
+This function may also return -ENOMEM or -EINTR, in which case it won't have
+read any data from the cache.
+
+
+PAGE ALLOCATE
+-------------
+
+Alternatively, if there's not expected to be any data in the cache for a page
+because the file has been extended, a block can simply be allocated instead:
+
+ int fscache_alloc_page(struct fscache_cookie *cookie,
+ struct page *page,
+ gfp_t gfp);
+
+This is similar to the fscache_read_or_alloc_page() function, except that it
+never reads from the cache. It will return 0 if a block has been allocated,
+rather than -ENODATA as the other would. One or the other must be performed
+before writing to the cache.
+
+The mark_pages_cached() cookie operation will be called on the page if
+successful.
+
+
+PAGE WRITE
+----------
+
+Secondly, if the netfs changes the contents of the page (either due to an
+initial download or if a user performs a write), then the page should be
+written back to the cache:
+
+ int fscache_write_page(struct fscache_cookie *cookie,
+ struct page *page,
+ gfp_t gfp);
+
+The cookie argument must specify a data file cookie, the page specified should
+contain the data to be written (and is also used to specify the page number),
+and the gfp argument is used to control how any memory allocations made are
+satisfied.
+
+The page must have first been read or allocated successfully and must not have
+been uncached before writing is performed.
+
+If the cookie indicates the inode is not cached then:
+
+ (1) The function will return -ENOBUFS.
+
+Else if space can be allocated in the cache to hold this page:
+
+ (1) PG_fscache_write will be set on the page.
+
+ (2) The function will submit a request to write the data to cache's backing
+ device directly from the page specified.
+
+ (3) The function will return 0.
+
+ (4) When the write is complete PG_fscache_write is cleared on the page and
+ anyone waiting for that bit will be woken up.
+
+Else if there's no space available in the cache, -ENOBUFS will be returned. It
+is also possible for the PG_fscache_write bit to be cleared when no write took
+place if unforeseen circumstances arose (such as a disk error).
+
+Writing takes place asynchronously.
+
+
+MULTIPLE PAGE READ
+------------------
+
+A facility is provided to read several pages at once, as requested by the
+readpages() address space operation:
+
+ int fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
+ struct address_space *mapping,
+ struct list_head *pages,
+ int *nr_pages,
+ fscache_rw_complete_t end_io_func,
+ void *context,
+ gfp_t gfp);
+
+This works in a similar way to fscache_read_or_alloc_page(), except:
+
+ (1) Any page it can retrieve data for is removed from pages and nr_pages and
+ dispatched for reading to the disk. Reads of adjacent pages on disk may
+ be merged for greater efficiency.
+
+ (2) The mark_pages_cached() cookie operation will be called on several pages
+ at once if they're being read or allocated.
+
+ (3) If there was an general error, then that error will be returned.
+
+ Else if some pages couldn't be allocated or read, then -ENOBUFS will be
+ returned.
+
+ Else if some pages couldn't be read but were allocated, then -ENODATA will
+ be returned.
+
+ Otherwise, if all pages had reads dispatched, then 0 will be returned, the
+ list will be empty and *nr_pages will be 0.
+
+ (4) end_io_func will be called once for each page being read as the reads
+ complete. It will be called in process context if error != 0, but it may
+ be called in interrupt context if there is no error.
+
+Note that a return of -ENODATA, -ENOBUFS or any other error does not preclude
+some of the pages being read and some being allocated. Those pages will have
+been marked appropriately and will need uncaching.
+
+
+==============
+PAGE UNCACHING
+==============
+
+To uncache a page, this function should be called:
+
+ void fscache_uncache_page(struct fscache_cookie *cookie,
+ struct page *page);
+
+This function permits the cache to release any in-memory representation it
+might be holding for this netfs page. This function must be called once for
+each page on which the read or write page functions above have been called to
+make sure the cache's in-memory tracking information gets torn down.
+
+Note that pages can't be explicitly deleted from the a data file. The whole
+data file must be retired (see the relinquish cookie function below).
+
+Furthermore, note that this does not cancel the asynchronous read or write
+operation started by the read/alloc and write functions, so the page
+invalidation and release functions must use:
+
+ bool fscache_check_page_write(struct fscache_cookie *cookie,
+ struct page *page);
+
+to see if a page is being written to the cache, and:
+
+ void fscache_wait_on_page_write(struct fscache_cookie *cookie,
+ struct page *page);
+
+to wait for it to finish if it is.
+
+
+==========================
+INDEX AND DATA FILE UPDATE
+==========================
+
+To request an update of the index data for an index or other object, the
+following function should be called:
+
+ void fscache_update_cookie(struct fscache_cookie *cookie);
+
+This function will refer back to the netfs_data pointer stored in the cookie by
+the acquisition function to obtain the data to write into each revised index
+entry. The update method in the parent index definition will be called to
+transfer the data.
+
+Note that partial updates may happen automatically at other times, such as when
+data blocks are added to a data file object.
+
+
+===============================
+MISCELLANEOUS COOKIE OPERATIONS
+===============================
+
+There are a number of operations that can be used to control cookies:
+
+ (*) Cookie pinning:
+
+ int fscache_pin_cookie(struct fscache_cookie *cookie);
+ void fscache_unpin_cookie(struct fscache_cookie *cookie);
+
+ These operations permit data cookies to be pinned into the cache and to
+ have the pinning removed. They are not permitted on index cookies.
+
+ The pinning function will return 0 if successful, -ENOBUFS in the cookie
+ isn't backed by a cache, -EOPNOTSUPP if the cache doesn't support pinning,
+ -ENOSPC if there isn't enough space to honour the operation, -ENOMEM or
+ -EIO if there's any other problem.
+
+ (*) Data space reservation:
+
+ int fscache_reserve_space(struct fscache_cookie *cookie, loff_t size);
+
+ This permits a netfs to request cache space be reserved to store up to the
+ given amount of a file. It is permitted to ask for more than the current
+ size of the file to allow for future file expansion.
+
+ If size is given as zero then the reservation will be cancelled.
+
+ The function will return 0 if successful, -ENOBUFS in the cookie isn't
+ backed by a cache, -EOPNOTSUPP if the cache doesn't support reservations,
+ -ENOSPC if there isn't enough space to honour the operation, -ENOMEM or
+ -EIO if there's any other problem.
+
+ Note that this doesn't pin an object in a cache; it can still be culled to
+ make space if it's not in use.
+
+
+=====================
+COOKIE UNREGISTRATION
+=====================
+
+To get rid of a cookie, this function should be called.
+
+ void fscache_relinquish_cookie(struct fscache_cookie *cookie,
+ int retire);
+
+If retire is non-zero, then the object will be marked for recycling, and all
+copies of it will be removed from all active caches in which it is present.
+Not only that but all child objects will also be retired.
+
+If retire is zero, then the object may be available again when next the
+acquisition function is called. Retirement here will overrule the pinning on a
+cookie.
+
+One very important note - relinquish must NOT be called for a cookie unless all
+the cookies for "child" indices, objects and pages have been relinquished
+first.
+
+
+================================
+INDEX AND DATA FILE INVALIDATION
+================================
+
+There is no direct way to invalidate an index subtree or a data file. To do
+this, the caller should relinquish and retire the cookie they have, and then
+acquire a new one.
+
+
+===========================
+FS-CACHE SPECIFIC PAGE FLAG
+===========================
+
+FS-Cache makes use of a page flag, PG_private_2, for its own purpose. This is
+given the alternative name PG_fscache.
+
+PG_fscache is used to indicate that the page is known by the cache, and that
+the cache must be informed if the page is going to go away. It's an indication
+to the netfs that the cache has an interest in this page, where an interest may
+be a pointer to it, resources allocated or reserved for it, or I/O in progress
+upon it.
+
+The netfs can use this information in methods such as releasepage() to
+determine whether it needs to uncache a page or update it.
+
+Furthermore, if this bit is set, releasepage() and invalidatepage() operations
+will be called on a page to get rid of it, even if PG_private is not set. This
+allows caching to attempted on a page before read_cache_pages() to be called
+after fscache_read_or_alloc_pages() as the former will try and release pages it
+was given under certain circumstances.
+
+This bit does not overlap with such as PG_private. This means that FS-Cache
+can be used with a filesystem that uses the block buffering code.
+
+There are a number of operations defined on this flag:
+
+ int PageFsCache(struct page *page);
+ void SetPageFsCache(struct page *page)
+ void ClearPageFsCache(struct page *page)
+ int TestSetPageFsCache(struct page *page)
+ int TestClearPageFsCache(struct page *page)
+
+These functions are bit test, bit set, bit clear, bit test and set and bit
+test and clear operations on PG_fscache.
diff --git a/Documentation/filesystems/caching/object.txt b/Documentation/filesystems/caching/object.txt
new file mode 100644
index 000000000000..e8b0a35d8fe5
--- /dev/null
+++ b/Documentation/filesystems/caching/object.txt
@@ -0,0 +1,313 @@
+ ====================================================
+ IN-KERNEL CACHE OBJECT REPRESENTATION AND MANAGEMENT
+ ====================================================
+
+By: David Howells <dhowells@redhat.com>
+
+Contents:
+
+ (*) Representation
+
+ (*) Object management state machine.
+
+ - Provision of cpu time.
+ - Locking simplification.
+
+ (*) The set of states.
+
+ (*) The set of events.
+
+
+==============
+REPRESENTATION
+==============
+
+FS-Cache maintains an in-kernel representation of each object that a netfs is
+currently interested in. Such objects are represented by the fscache_cookie
+struct and are referred to as cookies.
+
+FS-Cache also maintains a separate in-kernel representation of the objects that
+a cache backend is currently actively caching. Such objects are represented by
+the fscache_object struct. The cache backends allocate these upon request, and
+are expected to embed them in their own representations. These are referred to
+as objects.
+
+There is a 1:N relationship between cookies and objects. A cookie may be
+represented by multiple objects - an index may exist in more than one cache -
+or even by no objects (it may not be cached).
+
+Furthermore, both cookies and objects are hierarchical. The two hierarchies
+correspond, but the cookies tree is a superset of the union of the object trees
+of multiple caches:
+
+ NETFS INDEX TREE : CACHE 1 : CACHE 2
+ : :
+ : +-----------+ :
+ +----------->| IObject | :
+ +-----------+ | : +-----------+ :
+ | ICookie |-------+ : | :
+ +-----------+ | : | : +-----------+
+ | +------------------------------>| IObject |
+ | : | : +-----------+
+ | : V : |
+ | : +-----------+ : |
+ V +----------->| IObject | : |
+ +-----------+ | : +-----------+ : |
+ | ICookie |-------+ : | : V
+ +-----------+ | : | : +-----------+
+ | +------------------------------>| IObject |
+ +-----+-----+ : | : +-----------+
+ | | : | : |
+ V | : V : |
+ +-----------+ | : +-----------+ : |
+ | ICookie |------------------------->| IObject | : |
+ +-----------+ | : +-----------+ : |
+ | V : | : V
+ | +-----------+ : | : +-----------+
+ | | ICookie |-------------------------------->| IObject |
+ | +-----------+ : | : +-----------+
+ V | : V : |
+ +-----------+ | : +-----------+ : |
+ | DCookie |------------------------->| DObject | : |
+ +-----------+ | : +-----------+ : |
+ | : : |
+ +-------+-------+ : : |
+ | | : : |
+ V V : : V
+ +-----------+ +-----------+ : : +-----------+
+ | DCookie | | DCookie |------------------------>| DObject |
+ +-----------+ +-----------+ : : +-----------+
+ : :
+
+In the above illustration, ICookie and IObject represent indices and DCookie
+and DObject represent data storage objects. Indices may have representation in
+multiple caches, but currently, non-index objects may not. Objects of any type
+may also be entirely unrepresented.
+
+As far as the netfs API goes, the netfs is only actually permitted to see
+pointers to the cookies. The cookies themselves and any objects attached to
+those cookies are hidden from it.
+
+
+===============================
+OBJECT MANAGEMENT STATE MACHINE
+===============================
+
+Within FS-Cache, each active object is managed by its own individual state
+machine. The state for an object is kept in the fscache_object struct, in
+object->state. A cookie may point to a set of objects that are in different
+states.
+
+Each state has an action associated with it that is invoked when the machine
+wakes up in that state. There are four logical sets of states:
+
+ (1) Preparation: states that wait for the parent objects to become ready. The
+ representations are hierarchical, and it is expected that an object must
+ be created or accessed with respect to its parent object.
+
+ (2) Initialisation: states that perform lookups in the cache and validate
+ what's found and that create on disk any missing metadata.
+
+ (3) Normal running: states that allow netfs operations on objects to proceed
+ and that update the state of objects.
+
+ (4) Termination: states that detach objects from their netfs cookies, that
+ delete objects from disk, that handle disk and system errors and that free
+ up in-memory resources.
+
+
+In most cases, transitioning between states is in response to signalled events.
+When a state has finished processing, it will usually set the mask of events in
+which it is interested (object->event_mask) and relinquish the worker thread.
+Then when an event is raised (by calling fscache_raise_event()), if the event
+is not masked, the object will be queued for processing (by calling
+fscache_enqueue_object()).
+
+
+PROVISION OF CPU TIME
+---------------------
+
+The work to be done by the various states is given CPU time by the threads of
+the slow work facility (see Documentation/slow-work.txt). This is used in
+preference to the workqueue facility because:
+
+ (1) Threads may be completely occupied for very long periods of time by a
+ particular work item. These state actions may be doing sequences of
+ synchronous, journalled disk accesses (lookup, mkdir, create, setxattr,
+ getxattr, truncate, unlink, rmdir, rename).
+
+ (2) Threads may do little actual work, but may rather spend a lot of time
+ sleeping on I/O. This means that single-threaded and 1-per-CPU-threaded
+ workqueues don't necessarily have the right numbers of threads.
+
+
+LOCKING SIMPLIFICATION
+----------------------
+
+Because only one worker thread may be operating on any particular object's
+state machine at once, this simplifies the locking, particularly with respect
+to disconnecting the netfs's representation of a cache object (fscache_cookie)
+from the cache backend's representation (fscache_object) - which may be
+requested from either end.
+
+
+=================
+THE SET OF STATES
+=================
+
+The object state machine has a set of states that it can be in. There are
+preparation states in which the object sets itself up and waits for its parent
+object to transit to a state that allows access to its children:
+
+ (1) State FSCACHE_OBJECT_INIT.
+
+ Initialise the object and wait for the parent object to become active. In
+ the cache, it is expected that it will not be possible to look an object
+ up from the parent object, until that parent object itself has been looked
+ up.
+
+There are initialisation states in which the object sets itself up and accesses
+disk for the object metadata:
+
+ (2) State FSCACHE_OBJECT_LOOKING_UP.
+
+ Look up the object on disk, using the parent as a starting point.
+ FS-Cache expects the cache backend to probe the cache to see whether this
+ object is represented there, and if it is, to see if it's valid (coherency
+ management).
+
+ The cache should call fscache_object_lookup_negative() to indicate lookup
+ failure for whatever reason, and should call fscache_obtained_object() to
+ indicate success.
+
+ At the completion of lookup, FS-Cache will let the netfs go ahead with
+ read operations, no matter whether the file is yet cached. If not yet
+ cached, read operations will be immediately rejected with ENODATA until
+ the first known page is uncached - as to that point there can be no data
+ to be read out of the cache for that file that isn't currently also held
+ in the pagecache.
+
+ (3) State FSCACHE_OBJECT_CREATING.
+
+ Create an object on disk, using the parent as a starting point. This
+ happens if the lookup failed to find the object, or if the object's
+ coherency data indicated what's on disk is out of date. In this state,
+ FS-Cache expects the cache to create
+
+ The cache should call fscache_obtained_object() if creation completes
+ successfully, fscache_object_lookup_negative() otherwise.
+
+ At the completion of creation, FS-Cache will start processing write
+ operations the netfs has queued for an object. If creation failed, the
+ write ops will be transparently discarded, and nothing recorded in the
+ cache.
+
+There are some normal running states in which the object spends its time
+servicing netfs requests:
+
+ (4) State FSCACHE_OBJECT_AVAILABLE.
+
+ A transient state in which pending operations are started, child objects
+ are permitted to advance from FSCACHE_OBJECT_INIT state, and temporary
+ lookup data is freed.
+
+ (5) State FSCACHE_OBJECT_ACTIVE.
+
+ The normal running state. In this state, requests the netfs makes will be
+ passed on to the cache.
+
+ (6) State FSCACHE_OBJECT_UPDATING.
+
+ The state machine comes here to update the object in the cache from the
+ netfs's records. This involves updating the auxiliary data that is used
+ to maintain coherency.
+
+And there are terminal states in which an object cleans itself up, deallocates
+memory and potentially deletes stuff from disk:
+
+ (7) State FSCACHE_OBJECT_LC_DYING.
+
+ The object comes here if it is dying because of a lookup or creation
+ error. This would be due to a disk error or system error of some sort.
+ Temporary data is cleaned up, and the parent is released.
+
+ (8) State FSCACHE_OBJECT_DYING.
+
+ The object comes here if it is dying due to an error, because its parent
+ cookie has been relinquished by the netfs or because the cache is being
+ withdrawn.
+
+ Any child objects waiting on this one are given CPU time so that they too
+ can destroy themselves. This object waits for all its children to go away
+ before advancing to the next state.
+
+ (9) State FSCACHE_OBJECT_ABORT_INIT.
+
+ The object comes to this state if it was waiting on its parent in
+ FSCACHE_OBJECT_INIT, but its parent died. The object will destroy itself
+ so that the parent may proceed from the FSCACHE_OBJECT_DYING state.
+
+(10) State FSCACHE_OBJECT_RELEASING.
+(11) State FSCACHE_OBJECT_RECYCLING.
+
+ The object comes to one of these two states when dying once it is rid of
+ all its children, if it is dying because the netfs relinquished its
+ cookie. In the first state, the cached data is expected to persist, and
+ in the second it will be deleted.
+
+(12) State FSCACHE_OBJECT_WITHDRAWING.
+
+ The object transits to this state if the cache decides it wants to
+ withdraw the object from service, perhaps to make space, but also due to
+ error or just because the whole cache is being withdrawn.
+
+(13) State FSCACHE_OBJECT_DEAD.
+
+ The object transits to this state when the in-memory object record is
+ ready to be deleted. The object processor shouldn't ever see an object in
+ this state.
+
+
+THE SET OF EVENTS
+-----------------
+
+There are a number of events that can be raised to an object state machine:
+
+ (*) FSCACHE_OBJECT_EV_UPDATE
+
+ The netfs requested that an object be updated. The state machine will ask
+ the cache backend to update the object, and the cache backend will ask the
+ netfs for details of the change through its cookie definition ops.
+
+ (*) FSCACHE_OBJECT_EV_CLEARED
+
+ This is signalled in two circumstances:
+
+ (a) when an object's last child object is dropped and
+
+ (b) when the last operation outstanding on an object is completed.
+
+ This is used to proceed from the dying state.
+
+ (*) FSCACHE_OBJECT_EV_ERROR
+
+ This is signalled when an I/O error occurs during the processing of some
+ object.
+
+ (*) FSCACHE_OBJECT_EV_RELEASE
+ (*) FSCACHE_OBJECT_EV_RETIRE
+
+ These are signalled when the netfs relinquishes a cookie it was using.
+ The event selected depends on whether the netfs asks for the backing
+ object to be retired (deleted) or retained.
+
+ (*) FSCACHE_OBJECT_EV_WITHDRAW
+
+ This is signalled when the cache backend wants to withdraw an object.
+ This means that the object will have to be detached from the netfs's
+ cookie.
+
+Because the withdrawing releasing/retiring events are all handled by the object
+state machine, it doesn't matter if there's a collision with both ends trying
+to sever the connection at the same time. The state machine can just pick
+which one it wants to honour, and that effects the other.
diff --git a/Documentation/filesystems/caching/operations.txt b/Documentation/filesystems/caching/operations.txt
new file mode 100644
index 000000000000..b6b070c57cbf
--- /dev/null
+++ b/Documentation/filesystems/caching/operations.txt
@@ -0,0 +1,213 @@
+ ================================
+ ASYNCHRONOUS OPERATIONS HANDLING
+ ================================
+
+By: David Howells <dhowells@redhat.com>
+
+Contents:
+
+ (*) Overview.
+
+ (*) Operation record initialisation.
+
+ (*) Parameters.
+
+ (*) Procedure.
+
+ (*) Asynchronous callback.
+
+
+========
+OVERVIEW
+========
+
+FS-Cache has an asynchronous operations handling facility that it uses for its
+data storage and retrieval routines. Its operations are represented by
+fscache_operation structs, though these are usually embedded into some other
+structure.
+
+This facility is available to and expected to be be used by the cache backends,
+and FS-Cache will create operations and pass them off to the appropriate cache
+backend for completion.
+
+To make use of this facility, <linux/fscache-cache.h> should be #included.
+
+
+===============================
+OPERATION RECORD INITIALISATION
+===============================
+
+An operation is recorded in an fscache_operation struct:
+
+ struct fscache_operation {
+ union {
+ struct work_struct fast_work;
+ struct slow_work slow_work;
+ };
+ unsigned long flags;
+ fscache_operation_processor_t processor;
+ ...
+ };
+
+Someone wanting to issue an operation should allocate something with this
+struct embedded in it. They should initialise it by calling:
+
+ void fscache_operation_init(struct fscache_operation *op,
+ fscache_operation_release_t release);
+
+with the operation to be initialised and the release function to use.
+
+The op->flags parameter should be set to indicate the CPU time provision and
+the exclusivity (see the Parameters section).
+
+The op->fast_work, op->slow_work and op->processor flags should be set as
+appropriate for the CPU time provision (see the Parameters section).
+
+FSCACHE_OP_WAITING may be set in op->flags prior to each submission of the
+operation and waited for afterwards.
+
+
+==========
+PARAMETERS
+==========
+
+There are a number of parameters that can be set in the operation record's flag
+parameter. There are three options for the provision of CPU time in these
+operations:
+
+ (1) The operation may be done synchronously (FSCACHE_OP_MYTHREAD). A thread
+ may decide it wants to handle an operation itself without deferring it to
+ another thread.
+
+ This is, for example, used in read operations for calling readpages() on
+ the backing filesystem in CacheFiles. Although readpages() does an
+ asynchronous data fetch, the determination of whether pages exist is done
+ synchronously - and the netfs does not proceed until this has been
+ determined.
+
+ If this option is to be used, FSCACHE_OP_WAITING must be set in op->flags
+ before submitting the operation, and the operating thread must wait for it
+ to be cleared before proceeding:
+
+ wait_on_bit(&op->flags, FSCACHE_OP_WAITING,
+ fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+
+
+ (2) The operation may be fast asynchronous (FSCACHE_OP_FAST), in which case it
+ will be given to keventd to process. Such an operation is not permitted
+ to sleep on I/O.
+
+ This is, for example, used by CacheFiles to copy data from a backing fs
+ page to a netfs page after the backing fs has read the page in.
+
+ If this option is used, op->fast_work and op->processor must be
+ initialised before submitting the operation:
+
+ INIT_WORK(&op->fast_work, do_some_work);
+
+
+ (3) The operation may be slow asynchronous (FSCACHE_OP_SLOW), in which case it
+ will be given to the slow work facility to process. Such an operation is
+ permitted to sleep on I/O.
+
+ This is, for example, used by FS-Cache to handle background writes of
+ pages that have just been fetched from a remote server.
+
+ If this option is used, op->slow_work and op->processor must be
+ initialised before submitting the operation:
+
+ fscache_operation_init_slow(op, processor)
+
+
+Furthermore, operations may be one of two types:
+
+ (1) Exclusive (FSCACHE_OP_EXCLUSIVE). Operations of this type may not run in
+ conjunction with any other operation on the object being operated upon.
+
+ An example of this is the attribute change operation, in which the file
+ being written to may need truncation.
+
+ (2) Shareable. Operations of this type may be running simultaneously. It's
+ up to the operation implementation to prevent interference between other
+ operations running at the same time.
+
+
+=========
+PROCEDURE
+=========
+
+Operations are used through the following procedure:
+
+ (1) The submitting thread must allocate the operation and initialise it
+ itself. Normally this would be part of a more specific structure with the
+ generic op embedded within.
+
+ (2) The submitting thread must then submit the operation for processing using
+ one of the following two functions:
+
+ int fscache_submit_op(struct fscache_object *object,
+ struct fscache_operation *op);
+
+ int fscache_submit_exclusive_op(struct fscache_object *object,
+ struct fscache_operation *op);
+
+ The first function should be used to submit non-exclusive ops and the
+ second to submit exclusive ones. The caller must still set the
+ FSCACHE_OP_EXCLUSIVE flag.
+
+ If successful, both functions will assign the operation to the specified
+ object and return 0. -ENOBUFS will be returned if the object specified is
+ permanently unavailable.
+
+ The operation manager will defer operations on an object that is still
+ undergoing lookup or creation. The operation will also be deferred if an
+ operation of conflicting exclusivity is in progress on the object.
+
+ If the operation is asynchronous, the manager will retain a reference to
+ it, so the caller should put their reference to it by passing it to:
+
+ void fscache_put_operation(struct fscache_operation *op);
+
+ (3) If the submitting thread wants to do the work itself, and has marked the
+ operation with FSCACHE_OP_MYTHREAD, then it should monitor
+ FSCACHE_OP_WAITING as described above and check the state of the object if
+ necessary (the object might have died whilst the thread was waiting).
+
+ When it has finished doing its processing, it should call
+ fscache_put_operation() on it.
+
+ (4) The operation holds an effective lock upon the object, preventing other
+ exclusive ops conflicting until it is released. The operation can be
+ enqueued for further immediate asynchronous processing by adjusting the
+ CPU time provisioning option if necessary, eg:
+
+ op->flags &= ~FSCACHE_OP_TYPE;
+ op->flags |= ~FSCACHE_OP_FAST;
+
+ and calling:
+
+ void fscache_enqueue_operation(struct fscache_operation *op)
+
+ This can be used to allow other things to have use of the worker thread
+ pools.
+
+
+=====================
+ASYNCHRONOUS CALLBACK
+=====================
+
+When used in asynchronous mode, the worker thread pool will invoke the
+processor method with a pointer to the operation. This should then get at the
+container struct by using container_of():
+
+ static void fscache_write_op(struct fscache_operation *_op)
+ {
+ struct fscache_storage *op =
+ container_of(_op, struct fscache_storage, op);
+ ...
+ }
+
+The caller holds a reference on the operation, and will invoke
+fscache_put_operation() when the processor function returns. The processor
+function is at liberty to call fscache_enqueue_operation() or to take extra
+references.
diff --git a/Documentation/filesystems/exofs.txt b/Documentation/filesystems/exofs.txt
new file mode 100644
index 000000000000..0ced74c2f73c
--- /dev/null
+++ b/Documentation/filesystems/exofs.txt
@@ -0,0 +1,176 @@
+===============================================================================
+WHAT IS EXOFS?
+===============================================================================
+
+exofs is a file system that uses an OSD and exports the API of a normal Linux
+file system. Users access exofs like any other local file system, and exofs
+will in turn issue commands to the local OSD initiator.
+
+OSD is a new T10 command set that views storage devices not as a large/flat
+array of sectors but as a container of objects, each having a length, quota,
+time attributes and more. Each object is addressed by a 64bit ID, and is
+contained in a 64bit ID partition. Each object has associated attributes
+attached to it, which are integral part of the object and provide metadata about
+the object. The standard defines some common obligatory attributes, but user
+attributes can be added as needed.
+
+===============================================================================
+ENVIRONMENT
+===============================================================================
+
+To use this file system, you need to have an object store to run it on. You
+may download a target from:
+http://open-osd.org
+
+See Documentation/scsi/osd.txt for how to setup a working osd environment.
+
+===============================================================================
+USAGE
+===============================================================================
+
+1. Download and compile exofs and open-osd initiator:
+ You need an external Kernel source tree or kernel headers from your
+ distribution. (anything based on 2.6.26 or later).
+
+ a. download open-osd including exofs source using:
+ [parent-directory]$ git clone git://git.open-osd.org/open-osd.git
+
+ b. Build the library module like this:
+ [parent-directory]$ make -C KSRC=$(KER_DIR) open-osd
+
+ This will build both the open-osd initiator as well as the exofs kernel
+ module. Use whatever parameters you compiled your Kernel with and
+ $(KER_DIR) above pointing to the Kernel you compile against. See the file
+ open-osd/top-level-Makefile for an example.
+
+2. Get the OSD initiator and target set up properly, and login to the target.
+ See Documentation/scsi/osd.txt for farther instructions. Also see ./do-osd
+ for example script that does all these steps.
+
+3. Insmod the exofs.ko module:
+ [exofs]$ insmod exofs.ko
+
+4. Make sure the directory where you want to mount exists. If not, create it.
+ (For example, mkdir /mnt/exofs)
+
+5. At first run you will need to invoke the mkfs.exofs application
+
+ As an example, this will create the file system on:
+ /dev/osd0 partition ID 65536
+
+ mkfs.exofs --pid=65536 --format /dev/osd0
+
+ The --format is optional if not specified no OSD_FORMAT will be
+ preformed and a clean file system will be created in the specified pid,
+ in the available space of the target. (Use --format=size_in_meg to limit
+ the total LUN space available)
+
+ If pid already exist it will be deleted and a new one will be created in it's
+ place. Be careful.
+
+ An exofs lives inside a single OSD partition. You can create multiple exofs
+ filesystems on the same device using multiple pids.
+
+ (run mkfs.exofs without any parameters for usage help message)
+
+6. Mount the file system.
+
+ For example, to mount /dev/osd0, partition ID 0x10000 on /mnt/exofs:
+
+ mount -t exofs -o pid=65536 /dev/osd0 /mnt/exofs/
+
+7. For reference (See do-exofs example script):
+ do-exofs start - an example of how to perform the above steps.
+ do-exofs stop - an example of how to unmount the file system.
+ do-exofs format - an example of how to format and mkfs a new exofs.
+
+8. Extra compilation flags (uncomment in fs/exofs/Kbuild):
+ CONFIG_EXOFS_DEBUG - for debug messages and extra checks.
+
+===============================================================================
+exofs mount options
+===============================================================================
+Similar to any mount command:
+ mount -t exofs -o exofs_options /dev/osdX mount_exofs_directory
+
+Where:
+ -t exofs: specifies the exofs file system
+
+ /dev/osdX: X is a decimal number. /dev/osdX was created after a successful
+ login into an OSD target.
+
+ mount_exofs_directory: The directory to mount the file system on
+
+ exofs specific options: Options are separated by commas (,)
+ pid=<integer> - The partition number to mount/create as
+ container of the filesystem.
+ This option is mandatory
+ to=<integer> - Timeout in ticks for a single command
+ default is (60 * HZ) [for debugging only]
+
+===============================================================================
+DESIGN
+===============================================================================
+
+* The file system control block (AKA on-disk superblock) resides in an object
+ with a special ID (defined in common.h).
+ Information included in the file system control block is used to fill the
+ in-memory superblock structure at mount time. This object is created before
+ the file system is used by mkexofs.c It contains information such as:
+ - The file system's magic number
+ - The next inode number to be allocated
+
+* Each file resides in its own object and contains the data (and it will be
+ possible to extend the file over multiple objects, though this has not been
+ implemented yet).
+
+* A directory is treated as a file, and essentially contains a list of <file
+ name, inode #> pairs for files that are found in that directory. The object
+ IDs correspond to the files' inode numbers and will be allocated according to
+ a bitmap (stored in a separate object). Now they are allocated using a
+ counter.
+
+* Each file's control block (AKA on-disk inode) is stored in its object's
+ attributes. This applies to both regular files and other types (directories,
+ device files, symlinks, etc.).
+
+* Credentials are generated per object (inode and superblock) when they is
+ created in memory (read off disk or created). The credential works for all
+ operations and is used as long as the object remains in memory.
+
+* Async OSD operations are used whenever possible, but the target may execute
+ them out of order. The operations that concern us are create, delete,
+ readpage, writepage, update_inode, and truncate. The following pairs of
+ operations should execute in the order written, and we need to prevent them
+ from executing in reverse order:
+ - The following are handled with the OBJ_CREATED and OBJ_2BCREATED
+ flags. OBJ_CREATED is set when we know the object exists on the OSD -
+ in create's callback function, and when we successfully do a read_inode.
+ OBJ_2BCREATED is set in the beginning of the create function, so we
+ know that we should wait.
+ - create/delete: delete should wait until the object is created
+ on the OSD.
+ - create/readpage: readpage should be able to return a page
+ full of zeroes in this case. If there was a write already
+ en-route (i.e. create, writepage, readpage) then the page
+ would be locked, and so it would really be the same as
+ create/writepage.
+ - create/writepage: if writepage is called for a sync write, it
+ should wait until the object is created on the OSD.
+ Otherwise, it should just return.
+ - create/truncate: truncate should wait until the object is
+ created on the OSD.
+ - create/update_inode: update_inode should wait until the
+ object is created on the OSD.
+ - Handled by VFS locks:
+ - readpage/delete: shouldn't happen because of page lock.
+ - writepage/delete: shouldn't happen because of page lock.
+ - readpage/writepage: shouldn't happen because of page lock.
+
+===============================================================================
+LICENSE/COPYRIGHT
+===============================================================================
+The exofs file system is based on ext2 v0.5b (distributed with the Linux kernel
+version 2.6.10). All files include the original copyrights, and the license
+is GPL version 2 (only version 2, as is true for the Linux kernel). The
+Linux kernel can be downloaded from www.kernel.org.
diff --git a/Documentation/filesystems/ext2.txt b/Documentation/filesystems/ext2.txt
index 23448551cabe..e055acb6b2d4 100644
--- a/Documentation/filesystems/ext2.txt
+++ b/Documentation/filesystems/ext2.txt
@@ -376,7 +376,8 @@ Implementations for:
Windows 95/98/NT/2000 http://www.chrysocome.net/explore2fs
Windows 95 (*) http://www.yipton.net/content.html#FSDEXT2
DOS client (*) ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/
-OS/2 (*) ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/
+OS/2 (+) ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/
RISC OS client http://www.esw-heim.tu-clausthal.de/~marco/smorbrod/IscaFS/
-(*) no longer actively developed/supported (as of Mar 2009)
+(*) no longer actively developed/supported (as of Apr 2001)
+(+) no longer actively developed/supported (as of Mar 2009)
diff --git a/Documentation/filesystems/ext3.txt b/Documentation/filesystems/ext3.txt
index e5f3833a6ef8..570f9bd9be2b 100644
--- a/Documentation/filesystems/ext3.txt
+++ b/Documentation/filesystems/ext3.txt
@@ -14,6 +14,11 @@ Options
When mounting an ext3 filesystem, the following option are accepted:
(*) == default
+ro Mount filesystem read only. Note that ext3 will replay
+ the journal (and thus write to the partition) even when
+ mounted "read only". Mount options "ro,noload" can be
+ used to prevent writes to the filesystem.
+
journal=update Update the ext3 file system's journal to the current
format.
@@ -27,7 +32,9 @@ journal_dev=devnum When the external journal device's major/minor numbers
identified through its new major/minor numbers encoded
in devnum.
-noload Don't load the journal on mounting.
+noload Don't load the journal on mounting. Note that this forces
+ mount of inconsistent filesystem, which can lead to
+ various problems.
data=journal All data are committed into the journal prior to being
written into the main file system.
@@ -92,9 +99,12 @@ nocheck
debug Extra debugging information is sent to syslog.
-errors=remount-ro(*) Remount the filesystem read-only on an error.
+errors=remount-ro Remount the filesystem read-only on an error.
errors=continue Keep going on a filesystem error.
errors=panic Panic and halt the machine if an error occurs.
+ (These mount options override the errors behavior
+ specified in the superblock, which can be
+ configured using tune2fs.)
data_err=ignore(*) Just print an error message if an error occurs
in a file data buffer in ordered mode.
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
index cec829bc7291..97882df04865 100644
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -85,7 +85,7 @@ Note: More extensive information for getting started with ext4 can be
* extent format more robust in face of on-disk corruption due to magics,
* internal redundancy in tree
* improved file allocation (multi-block alloc)
-* fix 32000 subdirectory limit
+* lift 32000 subdirectory limit imposed by i_links_count[1]
* nsec timestamps for mtime, atime, ctime, create time
* inode version field on disk (NFSv4, Lustre)
* reduced e2fsck time via uninit_bg feature
@@ -100,6 +100,9 @@ Note: More extensive information for getting started with ext4 can be
* efficent new ordered mode in JBD2 and ext4(avoid using buffer head to force
the ordering)
+[1] Filesystems with a block size of 1k may see a limit imposed by the
+directory hash tree having a maximum depth of two.
+
2.2 Candidate features for future inclusion
* Online defrag (patches available but not well tested)
@@ -180,8 +183,8 @@ commit=nrsec (*) Ext4 can be told to sync all its data and metadata
performance.
barrier=<0|1(*)> This enables/disables the use of write barriers in
- the jbd code. barrier=0 disables, barrier=1 enables.
- This also requires an IO stack which can support
+barrier(*) the jbd code. barrier=0 disables, barrier=1 enables.
+nobarrier This also requires an IO stack which can support
barriers, and if jbd gets an error on a barrier
write, it will disable again with a warning.
Write barriers enforce proper on-disk ordering
@@ -189,6 +192,9 @@ barrier=<0|1(*)> This enables/disables the use of write barriers in
safe to use, at some performance penalty. If
your disks are battery-backed in one way or another,
disabling barriers may safely improve performance.
+ The mount options "barrier" and "nobarrier" can
+ also be used to enable or disable barriers, for
+ consistency with other ext4 mount options.
inode_readahead=n This tuning parameter controls the maximum
number of inode table blocks that ext4's inode
@@ -310,6 +316,24 @@ journal_ioprio=prio The I/O priority (from 0 to 7, where 0 is the
a slightly higher priority than the default I/O
priority.
+auto_da_alloc(*) Many broken applications don't use fsync() when
+noauto_da_alloc replacing existing files via patterns such as
+ fd = open("foo.new")/write(fd,..)/close(fd)/
+ rename("foo.new", "foo"), or worse yet,
+ fd = open("foo", O_TRUNC)/write(fd,..)/close(fd).
+ If auto_da_alloc is enabled, ext4 will detect
+ the replace-via-rename and replace-via-truncate
+ patterns and force that any delayed allocation
+ blocks are allocated such that at the next
+ journal commit, in the default data=ordered
+ mode, the data blocks of the new file are forced
+ to disk before the rename() operation is
+ commited. This provides roughly the same level
+ of guarantees as ext3, and avoids the
+ "zero-length" problem that can happen when a
+ system crashes before the delayed allocation
+ blocks are forced to disk.
+
Data Mode
=========
There are 3 different data modes:
diff --git a/Documentation/filesystems/knfsd-stats.txt b/Documentation/filesystems/knfsd-stats.txt
new file mode 100644
index 000000000000..64ced5149d37
--- /dev/null
+++ b/Documentation/filesystems/knfsd-stats.txt
@@ -0,0 +1,159 @@
+
+Kernel NFS Server Statistics
+============================
+
+This document describes the format and semantics of the statistics
+which the kernel NFS server makes available to userspace. These
+statistics are available in several text form pseudo files, each of
+which is described separately below.
+
+In most cases you don't need to know these formats, as the nfsstat(8)
+program from the nfs-utils distribution provides a helpful command-line
+interface for extracting and printing them.
+
+All the files described here are formatted as a sequence of text lines,
+separated by newline '\n' characters. Lines beginning with a hash
+'#' character are comments intended for humans and should be ignored
+by parsing routines. All other lines contain a sequence of fields
+separated by whitespace.
+
+/proc/fs/nfsd/pool_stats
+------------------------
+
+This file is available in kernels from 2.6.30 onwards, if the
+/proc/fs/nfsd filesystem is mounted (it almost always should be).
+
+The first line is a comment which describes the fields present in
+all the other lines. The other lines present the following data as
+a sequence of unsigned decimal numeric fields. One line is shown
+for each NFS thread pool.
+
+All counters are 64 bits wide and wrap naturally. There is no way
+to zero these counters, instead applications should do their own
+rate conversion.
+
+pool
+ The id number of the NFS thread pool to which this line applies.
+ This number does not change.
+
+ Thread pool ids are a contiguous set of small integers starting
+ at zero. The maximum value depends on the thread pool mode, but
+ currently cannot be larger than the number of CPUs in the system.
+ Note that in the default case there will be a single thread pool
+ which contains all the nfsd threads and all the CPUs in the system,
+ and thus this file will have a single line with a pool id of "0".
+
+packets-arrived
+ Counts how many NFS packets have arrived. More precisely, this
+ is the number of times that the network stack has notified the
+ sunrpc server layer that new data may be available on a transport
+ (e.g. an NFS or UDP socket or an NFS/RDMA endpoint).
+
+ Depending on the NFS workload patterns and various network stack
+ effects (such as Large Receive Offload) which can combine packets
+ on the wire, this may be either more or less than the number
+ of NFS calls received (which statistic is available elsewhere).
+ However this is a more accurate and less workload-dependent measure
+ of how much CPU load is being placed on the sunrpc server layer
+ due to NFS network traffic.
+
+sockets-enqueued
+ Counts how many times an NFS transport is enqueued to wait for
+ an nfsd thread to service it, i.e. no nfsd thread was considered
+ available.
+
+ The circumstance this statistic tracks indicates that there was NFS
+ network-facing work to be done but it couldn't be done immediately,
+ thus introducing a small delay in servicing NFS calls. The ideal
+ rate of change for this counter is zero; significantly non-zero
+ values may indicate a performance limitation.
+
+ This can happen either because there are too few nfsd threads in the
+ thread pool for the NFS workload (the workload is thread-limited),
+ or because the NFS workload needs more CPU time than is available in
+ the thread pool (the workload is CPU-limited). In the former case,
+ configuring more nfsd threads will probably improve the performance
+ of the NFS workload. In the latter case, the sunrpc server layer is
+ already choosing not to wake idle nfsd threads because there are too
+ many nfsd threads which want to run but cannot, so configuring more
+ nfsd threads will make no difference whatsoever. The overloads-avoided
+ statistic (see below) can be used to distinguish these cases.
+
+threads-woken
+ Counts how many times an idle nfsd thread is woken to try to
+ receive some data from an NFS transport.
+
+ This statistic tracks the circumstance where incoming
+ network-facing NFS work is being handled quickly, which is a good
+ thing. The ideal rate of change for this counter will be close
+ to but less than the rate of change of the packets-arrived counter.
+
+overloads-avoided
+ Counts how many times the sunrpc server layer chose not to wake an
+ nfsd thread, despite the presence of idle nfsd threads, because
+ too many nfsd threads had been recently woken but could not get
+ enough CPU time to actually run.
+
+ This statistic counts a circumstance where the sunrpc layer
+ heuristically avoids overloading the CPU scheduler with too many
+ runnable nfsd threads. The ideal rate of change for this counter
+ is zero. Significant non-zero values indicate that the workload
+ is CPU limited. Usually this is associated with heavy CPU usage
+ on all the CPUs in the nfsd thread pool.
+
+ If a sustained large overloads-avoided rate is detected on a pool,
+ the top(1) utility should be used to check for the following
+ pattern of CPU usage on all the CPUs associated with the given
+ nfsd thread pool.
+
+ - %us ~= 0 (as you're *NOT* running applications on your NFS server)
+
+ - %wa ~= 0
+
+ - %id ~= 0
+
+ - %sy + %hi + %si ~= 100
+
+ If this pattern is seen, configuring more nfsd threads will *not*
+ improve the performance of the workload. If this patten is not
+ seen, then something more subtle is wrong.
+
+threads-timedout
+ Counts how many times an nfsd thread triggered an idle timeout,
+ i.e. was not woken to handle any incoming network packets for
+ some time.
+
+ This statistic counts a circumstance where there are more nfsd
+ threads configured than can be used by the NFS workload. This is
+ a clue that the number of nfsd threads can be reduced without
+ affecting performance. Unfortunately, it's only a clue and not
+ a strong indication, for a couple of reasons:
+
+ - Currently the rate at which the counter is incremented is quite
+ slow; the idle timeout is 60 minutes. Unless the NFS workload
+ remains constant for hours at a time, this counter is unlikely
+ to be providing information that is still useful.
+
+ - It is usually a wise policy to provide some slack,
+ i.e. configure a few more nfsds than are currently needed,
+ to allow for future spikes in load.
+
+
+Note that incoming packets on NFS transports will be dealt with in
+one of three ways. An nfsd thread can be woken (threads-woken counts
+this case), or the transport can be enqueued for later attention
+(sockets-enqueued counts this case), or the packet can be temporarily
+deferred because the transport is currently being used by an nfsd
+thread. This last case is not very interesting and is not explicitly
+counted, but can be inferred from the other counters thus:
+
+packets-deferred = packets-arrived - ( sockets-enqueued + threads-woken )
+
+
+More
+----
+Descriptions of the other statistics file should go here.
+
+
+Greg Banks <gnb@sgi.com>
+26 Mar 2009
diff --git a/Documentation/filesystems/nfs41-server.txt b/Documentation/filesystems/nfs41-server.txt
new file mode 100644
index 000000000000..05d81cbcb2e1
--- /dev/null
+++ b/Documentation/filesystems/nfs41-server.txt
@@ -0,0 +1,161 @@
+NFSv4.1 Server Implementation
+
+Server support for minorversion 1 can be controlled using the
+/proc/fs/nfsd/versions control file. The string output returned
+by reading this file will contain either "+4.1" or "-4.1"
+correspondingly.
+
+Currently, server support for minorversion 1 is disabled by default.
+It can be enabled at run time by writing the string "+4.1" to
+the /proc/fs/nfsd/versions control file. Note that to write this
+control file, the nfsd service must be taken down. Use your user-mode
+nfs-utils to set this up; see rpc.nfsd(8)
+
+The NFSv4 minorversion 1 (NFSv4.1) implementation in nfsd is based
+on the latest NFSv4.1 Internet Draft:
+http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-29
+
+From the many new features in NFSv4.1 the current implementation
+focuses on the mandatory-to-implement NFSv4.1 Sessions, providing
+"exactly once" semantics and better control and throttling of the
+resources allocated for each client.
+
+Other NFSv4.1 features, Parallel NFS operations in particular,
+are still under development out of tree.
+See http://wiki.linux-nfs.org/wiki/index.php/PNFS_prototype_design
+for more information.
+
+The table below, taken from the NFSv4.1 document, lists
+the operations that are mandatory to implement (REQ), optional
+(OPT), and NFSv4.0 operations that are required not to implement (MNI)
+in minor version 1. The first column indicates the operations that
+are not supported yet by the linux server implementation.
+
+The OPTIONAL features identified and their abbreviations are as follows:
+ pNFS Parallel NFS
+ FDELG File Delegations
+ DDELG Directory Delegations
+
+The following abbreviations indicate the linux server implementation status.
+ I Implemented NFSv4.1 operations.
+ NS Not Supported.
+ NS* unimplemented optional feature.
+ P pNFS features implemented out of tree.
+ PNS pNFS features that are not supported yet (out of tree).
+
+Operations
+
+ +----------------------+------------+--------------+----------------+
+ | Operation | REQ, REC, | Feature | Definition |
+ | | OPT, or | (REQ, REC, | |
+ | | MNI | or OPT) | |
+ +----------------------+------------+--------------+----------------+
+ | ACCESS | REQ | | Section 18.1 |
+NS | BACKCHANNEL_CTL | REQ | | Section 18.33 |
+NS | BIND_CONN_TO_SESSION | REQ | | Section 18.34 |
+ | CLOSE | REQ | | Section 18.2 |
+ | COMMIT | REQ | | Section 18.3 |
+ | CREATE | REQ | | Section 18.4 |
+I | CREATE_SESSION | REQ | | Section 18.36 |
+NS*| DELEGPURGE | OPT | FDELG (REQ) | Section 18.5 |
+ | DELEGRETURN | OPT | FDELG, | Section 18.6 |
+ | | | DDELG, pNFS | |
+ | | | (REQ) | |
+NS | DESTROY_CLIENTID | REQ | | Section 18.50 |
+I | DESTROY_SESSION | REQ | | Section 18.37 |
+I | EXCHANGE_ID | REQ | | Section 18.35 |
+NS | FREE_STATEID | REQ | | Section 18.38 |
+ | GETATTR | REQ | | Section 18.7 |
+P | GETDEVICEINFO | OPT | pNFS (REQ) | Section 18.40 |
+P | GETDEVICELIST | OPT | pNFS (OPT) | Section 18.41 |
+ | GETFH | REQ | | Section 18.8 |
+NS*| GET_DIR_DELEGATION | OPT | DDELG (REQ) | Section 18.39 |
+P | LAYOUTCOMMIT | OPT | pNFS (REQ) | Section 18.42 |
+P | LAYOUTGET | OPT | pNFS (REQ) | Section 18.43 |
+P | LAYOUTRETURN | OPT | pNFS (REQ) | Section 18.44 |
+ | LINK | OPT | | Section 18.9 |
+ | LOCK | REQ | | Section 18.10 |
+ | LOCKT | REQ | | Section 18.11 |
+ | LOCKU | REQ | | Section 18.12 |
+ | LOOKUP | REQ | | Section 18.13 |
+ | LOOKUPP | REQ | | Section 18.14 |
+ | NVERIFY | REQ | | Section 18.15 |
+ | OPEN | REQ | | Section 18.16 |
+NS*| OPENATTR | OPT | | Section 18.17 |
+ | OPEN_CONFIRM | MNI | | N/A |
+ | OPEN_DOWNGRADE | REQ | | Section 18.18 |
+ | PUTFH | REQ | | Section 18.19 |
+ | PUTPUBFH | REQ | | Section 18.20 |
+ | PUTROOTFH | REQ | | Section 18.21 |
+ | READ | REQ | | Section 18.22 |
+ | READDIR | REQ | | Section 18.23 |
+ | READLINK | OPT | | Section 18.24 |
+NS | RECLAIM_COMPLETE | REQ | | Section 18.51 |
+ | RELEASE_LOCKOWNER | MNI | | N/A |
+ | REMOVE | REQ | | Section 18.25 |
+ | RENAME | REQ | | Section 18.26 |
+ | RENEW | MNI | | N/A |
+ | RESTOREFH | REQ | | Section 18.27 |
+ | SAVEFH | REQ | | Section 18.28 |
+ | SECINFO | REQ | | Section 18.29 |
+NS | SECINFO_NO_NAME | REC | pNFS files | Section 18.45, |
+ | | | layout (REQ) | Section 13.12 |
+I | SEQUENCE | REQ | | Section 18.46 |
+ | SETATTR | REQ | | Section 18.30 |
+ | SETCLIENTID | MNI | | N/A |
+ | SETCLIENTID_CONFIRM | MNI | | N/A |
+NS | SET_SSV | REQ | | Section 18.47 |
+NS | TEST_STATEID | REQ | | Section 18.48 |
+ | VERIFY | REQ | | Section 18.31 |
+NS*| WANT_DELEGATION | OPT | FDELG (OPT) | Section 18.49 |
+ | WRITE | REQ | | Section 18.32 |
+
+Callback Operations
+
+ +-------------------------+-----------+-------------+---------------+
+ | Operation | REQ, REC, | Feature | Definition |
+ | | OPT, or | (REQ, REC, | |
+ | | MNI | or OPT) | |
+ +-------------------------+-----------+-------------+---------------+
+ | CB_GETATTR | OPT | FDELG (REQ) | Section 20.1 |
+P | CB_LAYOUTRECALL | OPT | pNFS (REQ) | Section 20.3 |
+NS*| CB_NOTIFY | OPT | DDELG (REQ) | Section 20.4 |
+P | CB_NOTIFY_DEVICEID | OPT | pNFS (OPT) | Section 20.12 |
+NS*| CB_NOTIFY_LOCK | OPT | | Section 20.11 |
+NS*| CB_PUSH_DELEG | OPT | FDELG (OPT) | Section 20.5 |
+ | CB_RECALL | OPT | FDELG, | Section 20.2 |
+ | | | DDELG, pNFS | |
+ | | | (REQ) | |
+NS*| CB_RECALL_ANY | OPT | FDELG, | Section 20.6 |
+ | | | DDELG, pNFS | |
+ | | | (REQ) | |
+NS | CB_RECALL_SLOT | REQ | | Section 20.8 |
+NS*| CB_RECALLABLE_OBJ_AVAIL | OPT | DDELG, pNFS | Section 20.7 |
+ | | | (REQ) | |
+I | CB_SEQUENCE | OPT | FDELG, | Section 20.9 |
+ | | | DDELG, pNFS | |
+ | | | (REQ) | |
+NS*| CB_WANTS_CANCELLED | OPT | FDELG, | Section 20.10 |
+ | | | DDELG, pNFS | |
+ | | | (REQ) | |
+ +-------------------------+-----------+-------------+---------------+
+
+Implementation notes:
+
+EXCHANGE_ID:
+* only SP4_NONE state protection supported
+* implementation ids are ignored
+
+CREATE_SESSION:
+* backchannel attributes are ignored
+* backchannel security parameters are ignored
+
+SEQUENCE:
+* no support for dynamic slot table renegotiation (optional)
+
+nfsv4.1 COMPOUND rules:
+The following cases aren't supported yet:
+* Enforcing of NFS4ERR_NOT_ONLY_OP for: BIND_CONN_TO_SESSION, CREATE_SESSION,
+ DESTROY_CLIENTID, DESTROY_SESSION, EXCHANGE_ID.
+* DESTROY_SESSION MUST be the final operation in the COMPOUND request.
+
diff --git a/Documentation/filesystems/pohmelfs/design_notes.txt b/Documentation/filesystems/pohmelfs/design_notes.txt
new file mode 100644
index 000000000000..6d6db60d567d
--- /dev/null
+++ b/Documentation/filesystems/pohmelfs/design_notes.txt
@@ -0,0 +1,70 @@
+POHMELFS: Parallel Optimized Host Message Exchange Layered File System.
+
+ Evgeniy Polyakov <zbr@ioremap.net>
+
+Homepage: http://www.ioremap.net/projects/pohmelfs
+
+POHMELFS first began as a network filesystem with coherent local data and
+metadata caches but is now evolving into a parallel distributed filesystem.
+
+Main features of this FS include:
+ * Locally coherent cache for data and metadata with (potentially) byte-range locks.
+ Since all Linux filesystems lock the whole inode during writing, algorithm
+ is very simple and does not use byte-ranges, although they are sent in
+ locking messages.
+ * Completely async processing of all events except creation of hard and symbolic
+ links, and rename events.
+ Object creation and data reading and writing are processed asynchronously.
+ * Flexible object architecture optimized for network processing.
+ Ability to create long paths to objects and remove arbitrarily huge
+ directories with a single network command.
+ (like removing the whole kernel tree via a single network command).
+ * Very high performance.
+ * Fast and scalable multithreaded userspace server. Being in userspace it works
+ with any underlying filesystem and still is much faster than async in-kernel NFS one.
+ * Client is able to switch between different servers (if one goes down, client
+ automatically reconnects to second and so on).
+ * Transactions support. Full failover for all operations.
+ Resending transactions to different servers on timeout or error.
+ * Read request (data read, directory listing, lookup requests) balancing between multiple servers.
+ * Write requests are replicated to multiple servers and completed only when all of them are acked.
+ * Ability to add and/or remove servers from the working set at run-time.
+ * Strong authentification and possible data encryption in network channel.
+ * Extended attributes support.
+
+POHMELFS is based on transactions, which are potentially long-standing objects that live
+in the client's memory. Each transaction contains all the information needed to process a given
+command (or set of commands, which is frequently used during data writing: single transactions
+can contain creation and data writing commands). Transactions are committed by all the servers
+to which they are sent and, in case of failures, are eventually resent or dropped with an error.
+For example, reading will return an error if no servers are available.
+
+POHMELFS uses a asynchronous approach to data processing. Courtesy of transactions, it is
+possible to detach replies from requests and, if the command requires data to be received, the
+caller sleeps waiting for it. Thus, it is possible to issue multiple read commands to different
+servers and async threads will pick up replies in parallel, find appropriate transactions in the
+system and put the data where it belongs (like the page or inode cache).
+
+The main feature of POHMELFS is writeback data and the metadata cache.
+Only a few non-performance critical operations use the write-through cache and
+are synchronous: hard and symbolic link creation, and object rename. Creation,
+removal of objects and data writing are asynchronous and are sent to
+the server during system writeback. Only one writer at a time is allowed for any
+given inode, which is guarded by an appropriate locking protocol.
+Because of this feature, POHMELFS is extremely fast at metadata intensive
+workloads and can fully utilize the bandwidth to the servers when doing bulk
+data transfers.
+
+POHMELFS clients operate with a working set of servers and are capable of balancing read-only
+operations (like lookups or directory listings) between them.
+Administrators can add or remove servers from the set at run-time via special commands (described
+in Documentation/pohmelfs/info.txt file). Writes are replicated to all servers.
+
+POHMELFS is capable of full data channel encryption and/or strong crypto hashing.
+One can select any kernel supported cipher, encryption mode, hash type and operation mode
+(hmac or digest). It is also possible to use both or neither (default). Crypto configuration
+is checked during mount time and, if the server does not support it, appropriate capabilities
+will be disabled or mount will fail (if 'crypto_fail_unsupported' mount option is specified).
+Crypto performance heavily depends on the number of crypto threads, which asynchronously perform
+crypto operations and send the resulting data to server or submit it up the stack. This number
+can be controlled via a mount option.
diff --git a/Documentation/filesystems/pohmelfs/info.txt b/Documentation/filesystems/pohmelfs/info.txt
new file mode 100644
index 000000000000..4e3d50157083
--- /dev/null
+++ b/Documentation/filesystems/pohmelfs/info.txt
@@ -0,0 +1,86 @@
+POHMELFS usage information.
+
+Mount options:
+idx=%u
+ Each mountpoint is associated with a special index via this option.
+ Administrator can add or remove servers from the given index, so all mounts,
+ which were attached to it, are updated.
+ Default it is 0.
+
+trans_scan_timeout=%u
+ This timeout, expressed in milliseconds, specifies time to scan transaction
+ trees looking for stale requests, which have to be resent, or if number of
+ retries exceed specified limit, dropped with error.
+ Default is 5 seconds.
+
+drop_scan_timeout=%u
+ Internal timeout, expressed in milliseconds, which specifies how frequently
+ inodes marked to be dropped are freed. It also specifies how frequently
+ the system checks that servers have to be added or removed from current working set.
+ Default is 1 second.
+
+wait_on_page_timeout=%u
+ Number of milliseconds to wait for reply from remote server for data reading command.
+ If this timeout is exceeded, reading returns an error.
+ Default is 5 seconds.
+
+trans_retries=%u
+ This is the number of times that a transaction will be resent to a server that did
+ not answer for the last @trans_scan_timeout milliseconds.
+ When the number of resends exceeds this limit, the transaction is completed with error.
+ Default is 5 resends.
+
+crypto_thread_num=%u
+ Number of crypto processing threads. Threads are used both for RX and TX traffic.
+ Default is 2, or no threads if crypto operations are not supported.
+
+trans_max_pages=%u
+ Maximum number of pages in a single transaction. This parameter also controls
+ the number of pages, allocated for crypto processing (each crypto thread has
+ pool of pages, the number of which is equal to 'trans_max_pages'.
+ Default is 100 pages.
+
+crypto_fail_unsupported
+ If specified, mount will fail if the server does not support requested crypto operations.
+ By default mount will disable non-matching crypto operations.
+
+mcache_timeout=%u
+ Maximum number of milliseconds to wait for the mcache objects to be processed.
+ Mcache includes locks (given lock should be granted by server), attributes (they should be
+ fully received in the given timeframe).
+ Default is 5 seconds.
+
+Usage examples.
+
+Add (or remove if it already exists) server server1.net:1025 into the working set with index $idx
+with appropriate hash algorithm and key file and cipher algorithm, mode and key file:
+$cfg -a server1.net -p 1025 -i $idx -K $hash_key -k $cipher_key
+
+Mount filesystem with given index $idx to /mnt mountpoint.
+Client will connect to all servers specified in the working set via previous command:
+mount -t pohmel -o idx=$idx q /mnt
+
+One can add or remove servers from working set after mounting too.
+
+
+Server installation.
+
+Creating a server, which listens at port 1025 and 0.0.0.0 address.
+Working root directory (note, that server chroots there, so you have to have appropriate permissions)
+is set to /mnt, server will negotiate hash/cipher with client, in case client requested it, there
+are appropriate key files.
+Number of working threads is set to 10.
+
+# ./fserver -a 0.0.0.0 -p 1025 -r /mnt -w 10 -K hash_key -k cipher_key
+
+ -A 6 - listen on ipv6 address. Default: Disabled.
+ -r root - path to root directory. Default: /tmp.
+ -a addr - listen address. Default: 0.0.0.0.
+ -p port - listen port. Default: 1025.
+ -w workers - number of workers per connected client. Default: 1.
+ -K file - hash key size. Default: none.
+ -k file - cipher key size. Default: none.
+ -h - this help.
+
+Number of worker threads specifies how many workers will be created for each client.
+Bulk single-client transafers usually are better handled with smaller number (like 1-3).
diff --git a/Documentation/filesystems/pohmelfs/network_protocol.txt b/Documentation/filesystems/pohmelfs/network_protocol.txt
new file mode 100644
index 000000000000..40ea6c295afb
--- /dev/null
+++ b/Documentation/filesystems/pohmelfs/network_protocol.txt
@@ -0,0 +1,227 @@
+POHMELFS network protocol.
+
+Basic structure used in network communication is following command:
+
+struct netfs_cmd
+{
+ __u16 cmd; /* Command number */
+ __u16 csize; /* Attached crypto information size */
+ __u16 cpad; /* Attached padding size */
+ __u16 ext; /* External flags */
+ __u32 size; /* Size of the attached data */
+ __u32 trans; /* Transaction id */
+ __u64 id; /* Object ID to operate on. Used for feedback.*/
+ __u64 start; /* Start of the object. */
+ __u64 iv; /* IV sequence */
+ __u8 data[0];
+};
+
+Commands can be embedded into transaction command (which in turn has own command),
+so one can extend protocol as needed without breaking backward compatibility as long
+as old commands are supported. All string lengths include tail 0 byte.
+
+All commans are transfered over the network in big-endian. CPU endianess is used at the end peers.
+
+@cmd - command number, which specifies command to be processed. Following
+ commands are used currently:
+
+ NETFS_READDIR = 1, /* Read directory for given inode number */
+ NETFS_READ_PAGE, /* Read data page from the server */
+ NETFS_WRITE_PAGE, /* Write data page to the server */
+ NETFS_CREATE, /* Create directory entry */
+ NETFS_REMOVE, /* Remove directory entry */
+ NETFS_LOOKUP, /* Lookup single object */
+ NETFS_LINK, /* Create a link */
+ NETFS_TRANS, /* Transaction */
+ NETFS_OPEN, /* Open intent */
+ NETFS_INODE_INFO, /* Metadata cache coherency synchronization message */
+ NETFS_PAGE_CACHE, /* Page cache invalidation message */
+ NETFS_READ_PAGES, /* Read multiple contiguous pages in one go */
+ NETFS_RENAME, /* Rename object */
+ NETFS_CAPABILITIES, /* Capabilities of the client, for example supported crypto */
+ NETFS_LOCK, /* Distributed lock message */
+ NETFS_XATTR_SET, /* Set extended attribute */
+ NETFS_XATTR_GET, /* Get extended attribute */
+
+@ext - external flags. Used by different commands to specify some extra arguments
+ like partial size of the embedded objects or creation flags.
+
+@size - size of the attached data. For NETFS_READ_PAGE and NETFS_READ_PAGES no data is attached,
+ but size of the requested data is incorporated here. It does not include size of the command
+ header (struct netfs_cmd) itself.
+
+@id - id of the object this command operates on. Each command can use it for own purpose.
+
+@start - start of the object this command operates on. Each command can use it for own purpose.
+
+@csize, @cpad - size and padding size of the (attached if needed) crypto information.
+
+Command specifications.
+
+@NETFS_READDIR
+This command is used to sync content of the remote dir to the client.
+
+@ext - length of the path to object.
+@size - the same.
+@id - local inode number of the directory to read.
+@start - zero.
+
+
+@NETFS_READ_PAGE
+This command is used to read data from remote server.
+Data size does not exceed local page cache size.
+
+@id - inode number.
+@start - first byte offset.
+@size - number of bytes to read plus length of the path to object.
+@ext - object path length.
+
+
+@NETFS_CREATE
+Used to create object.
+It does not require that all directories on top of the object were
+already created, it will create them automatically. Each object has
+associated @netfs_path_entry data structure, which contains creation
+mode (permissions and type) and length of the name as long as name itself.
+
+@start - 0
+@size - size of the all data structures needed to create a path
+@id - local inode number
+@ext - 0
+
+
+@NETFS_REMOVE
+Used to remove object.
+
+@ext - length of the path to object.
+@size - the same.
+@id - local inode number.
+@start - zero.
+
+
+@NETFS_LOOKUP
+Lookup information about object on server.
+
+@ext - length of the path to object.
+@size - the same.
+@id - local inode number of the directory to look object in.
+@start - local inode number of the object to look at.
+
+
+@NETFS_LINK
+Create hard of symlink.
+Command is sent as "object_path|target_path".
+
+@size - size of the above string.
+@id - parent local inode number.
+@start - 1 for symlink, 0 for hardlink.
+@ext - size of the "object_path" above.
+
+
+@NETFS_TRANS
+Transaction header.
+
+@size - incorporates all embedded command sizes including theirs header sizes.
+@start - transaction generation number - unique id used to find transaction.
+@ext - transaction flags. Unused at the moment.
+@id - 0.
+
+
+@NETFS_OPEN
+Open intent for given transaction.
+
+@id - local inode number.
+@start - 0.
+@size - path length to the object.
+@ext - open flags (O_RDWR and so on).
+
+
+@NETFS_INODE_INFO
+Metadata update command.
+It is sent to servers when attributes of the object are changed and received
+when data or metadata were updated. It operates with the following structure:
+
+struct netfs_inode_info
+{
+ unsigned int mode;
+ unsigned int nlink;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int blocksize;
+ unsigned int padding;
+ __u64 ino;
+ __u64 blocks;
+ __u64 rdev;
+ __u64 size;
+ __u64 version;
+};
+
+It effectively mirrors stat(2) returned data.
+
+
+@ext - path length to the object.
+@size - the same plus size of the netfs_inode_info structure.
+@id - local inode number.
+@start - 0.
+
+
+@NETFS_PAGE_CACHE
+Command is only received by clients. It contains information about
+page to be marked as not up-to-date.
+
+@id - client's inode number.
+@start - last byte of the page to be invalidated. If it is not equal to
+ current inode size, it will be vmtruncated().
+@size - 0
+@ext - 0
+
+
+@NETFS_READ_PAGES
+Used to read multiple contiguous pages in one go.
+
+@start - first byte of the contiguous region to read.
+@size - contains of two fields: lower 8 bits are used to represent page cache shift
+ used by client, another 3 bytes are used to get number of pages.
+@id - local inode number.
+@ext - path length to the object.
+
+
+@NETFS_RENAME
+Used to rename object.
+Attached data is formed into following string: "old_path|new_path".
+
+@id - local inode number.
+@start - parent inode number.
+@size - length of the above string.
+@ext - length of the old path part.
+
+
+@NETFS_CAPABILITIES
+Used to exchange crypto capabilities with server.
+If crypto capabilities are not supported by server, then client will disable it
+or fail (if 'crypto_fail_unsupported' mount options was specified).
+
+@id - superblock index. Used to specify crypto information for group of servers.
+@size - size of the attached capabilities structure.
+@start - 0.
+@size - 0.
+@scsize - 0.
+
+@NETFS_LOCK
+Used to send lock request/release messages. Although it sends byte range request
+and is capable of flushing pages based on that, it is not used, since all Linux
+filesystems lock the whole inode.
+
+@id - lock generation number.
+@start - start of the locked range.
+@size - size of the locked range.
+@ext - lock type: read/write. Not used actually. 15'th bit is used to determine,
+ if it is lock request (1) or release (0).
+
+@NETFS_XATTR_SET
+@NETFS_XATTR_GET
+Used to set/get extended attributes for given inode.
+@id - attribute generation number or xattr setting type
+@start - size of the attribute (request or attached)
+@size - name length, path len and data size for given attribute
+@ext - path length for given object
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index a87be42f8211..ce84cfc9eae0 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -5,6 +5,7 @@
Bodo Bauer <bb@ricochet.net>
2.4.x update Jorge Nerin <comandante@zaralinux.com> November 14 2000
+move /proc/sys Shen Feng <shen@cn.fujitsu.com> April 1 2009
------------------------------------------------------------------------------
Version 1.3 Kernel version 2.2.12
Kernel version 2.4.0-test11-pre4
@@ -26,25 +27,17 @@ Table of Contents
1.6 Parallel port info in /proc/parport
1.7 TTY info in /proc/tty
1.8 Miscellaneous kernel statistics in /proc/stat
+ 1.9 Ext4 file system parameters
2 Modifying System Parameters
- 2.1 /proc/sys/fs - File system data
- 2.2 /proc/sys/fs/binfmt_misc - Miscellaneous binary formats
- 2.3 /proc/sys/kernel - general kernel parameters
- 2.4 /proc/sys/vm - The virtual memory subsystem
- 2.5 /proc/sys/dev - Device specific parameters
- 2.6 /proc/sys/sunrpc - Remote procedure calls
- 2.7 /proc/sys/net - Networking stuff
- 2.8 /proc/sys/net/ipv4 - IPV4 settings
- 2.9 Appletalk
- 2.10 IPX
- 2.11 /proc/sys/fs/mqueue - POSIX message queues filesystem
- 2.12 /proc/<pid>/oom_adj - Adjust the oom-killer score
- 2.13 /proc/<pid>/oom_score - Display current oom-killer score
- 2.14 /proc/<pid>/io - Display the IO accounting fields
- 2.15 /proc/<pid>/coredump_filter - Core dump filtering settings
- 2.16 /proc/<pid>/mountinfo - Information about mounts
- 2.17 /proc/sys/fs/epoll - Configuration options for the epoll interface
+
+ 3 Per-Process Parameters
+ 3.1 /proc/<pid>/oom_adj - Adjust the oom-killer score
+ 3.2 /proc/<pid>/oom_score - Display current oom-killer score
+ 3.3 /proc/<pid>/io - Display the IO accounting fields
+ 3.4 /proc/<pid>/coredump_filter - Core dump filtering settings
+ 3.5 /proc/<pid>/mountinfo - Information about mounts
+
------------------------------------------------------------------------------
Preface
@@ -940,27 +933,6 @@ Table 1-10: Files in /proc/fs/ext4/<devname>
File Content
mb_groups details of multiblock allocator buddy cache of free blocks
mb_history multiblock allocation history
- stats controls whether the multiblock allocator should start
- collecting statistics, which are shown during the unmount
- group_prealloc the multiblock allocator will round up allocation
- requests to a multiple of this tuning parameter if the
- stripe size is not set in the ext4 superblock
- max_to_scan The maximum number of extents the multiblock allocator
- will search to find the best extent
- min_to_scan The minimum number of extents the multiblock allocator
- will search to find the best extent
- order2_req Tuning parameter which controls the minimum size for
- requests (as a power of 2) where the buddy cache is
- used
- stream_req Files which have fewer blocks than this tunable
- parameter will have their blocks allocated out of a
- block group specific preallocation pool, so that small
- files are packed closely together. Each large file
- will have its blocks allocated out of its own unique
- preallocation pool.
-inode_readahead Tuning parameter which controls the maximum number of
- inode table blocks that ext4's inode table readahead
- algorithm will pre-read into the buffer cache
..............................................................................
@@ -1011,1014 +983,24 @@ review the kernel documentation in the directory /usr/src/linux/Documentation.
This chapter is heavily based on the documentation included in the pre 2.2
kernels, and became part of it in version 2.2.1 of the Linux kernel.
-2.1 /proc/sys/fs - File system data
------------------------------------
-
-This subdirectory contains specific file system, file handle, inode, dentry
-and quota information.
-
-Currently, these files are in /proc/sys/fs:
-
-dentry-state
-------------
-
-Status of the directory cache. Since directory entries are dynamically
-allocated and deallocated, this file indicates the current status. It holds
-six values, in which the last two are not used and are always zero. The others
-are listed in table 2-1.
-
-
-Table 2-1: Status files of the directory cache
-..............................................................................
- File Content
- nr_dentry Almost always zero
- nr_unused Number of unused cache entries
- age_limit
- in seconds after the entry may be reclaimed, when memory is short
- want_pages internally
-..............................................................................
-
-dquot-nr and dquot-max
-----------------------
-
-The file dquot-max shows the maximum number of cached disk quota entries.
-
-The file dquot-nr shows the number of allocated disk quota entries and the
-number of free disk quota entries.
-
-If the number of available cached disk quotas is very low and you have a large
-number of simultaneous system users, you might want to raise the limit.
-
-file-nr and file-max
---------------------
-
-The kernel allocates file handles dynamically, but doesn't free them again at
-this time.
-
-The value in file-max denotes the maximum number of file handles that the
-Linux kernel will allocate. When you get a lot of error messages about running
-out of file handles, you might want to raise this limit. The default value is
-10% of RAM in kilobytes. To change it, just write the new number into the
-file:
-
- # cat /proc/sys/fs/file-max
- 4096
- # echo 8192 > /proc/sys/fs/file-max
- # cat /proc/sys/fs/file-max
- 8192
-
-
-This method of revision is useful for all customizable parameters of the
-kernel - simply echo the new value to the corresponding file.
-
-Historically, the three values in file-nr denoted the number of allocated file
-handles, the number of allocated but unused file handles, and the maximum
-number of file handles. Linux 2.6 always reports 0 as the number of free file
-handles -- this is not an error, it just means that the number of allocated
-file handles exactly matches the number of used file handles.
-
-Attempts to allocate more file descriptors than file-max are reported with
-printk, look for "VFS: file-max limit <number> reached".
-
-inode-state and inode-nr
-------------------------
-
-The file inode-nr contains the first two items from inode-state, so we'll skip
-to that file...
-
-inode-state contains two actual numbers and five dummy values. The numbers
-are nr_inodes and nr_free_inodes (in order of appearance).
-
-nr_inodes
-~~~~~~~~~
-
-Denotes the number of inodes the system has allocated. This number will
-grow and shrink dynamically.
-
-nr_open
--------
-
-Denotes the maximum number of file-handles a process can
-allocate. Default value is 1024*1024 (1048576) which should be
-enough for most machines. Actual limit depends on RLIMIT_NOFILE
-resource limit.
-
-nr_free_inodes
---------------
-
-Represents the number of free inodes. Ie. The number of inuse inodes is
-(nr_inodes - nr_free_inodes).
-
-aio-nr and aio-max-nr
----------------------
-
-aio-nr is the running total of the number of events specified on the
-io_setup system call for all currently active aio contexts. If aio-nr
-reaches aio-max-nr then io_setup will fail with EAGAIN. Note that
-raising aio-max-nr does not result in the pre-allocation or re-sizing
-of any kernel data structures.
-
-2.2 /proc/sys/fs/binfmt_misc - Miscellaneous binary formats
------------------------------------------------------------
-
-Besides these files, there is the subdirectory /proc/sys/fs/binfmt_misc. This
-handles the kernel support for miscellaneous binary formats.
-
-Binfmt_misc provides the ability to register additional binary formats to the
-Kernel without compiling an additional module/kernel. Therefore, binfmt_misc
-needs to know magic numbers at the beginning or the filename extension of the
-binary.
-
-It works by maintaining a linked list of structs that contain a description of
-a binary format, including a magic with size (or the filename extension),
-offset and mask, and the interpreter name. On request it invokes the given
-interpreter with the original program as argument, as binfmt_java and
-binfmt_em86 and binfmt_mz do. Since binfmt_misc does not define any default
-binary-formats, you have to register an additional binary-format.
-
-There are two general files in binfmt_misc and one file per registered format.
-The two general files are register and status.
-
-Registering a new binary format
--------------------------------
-
-To register a new binary format you have to issue the command
-
- echo :name:type:offset:magic:mask:interpreter: > /proc/sys/fs/binfmt_misc/register
-
-
-
-with appropriate name (the name for the /proc-dir entry), offset (defaults to
-0, if omitted), magic, mask (which can be omitted, defaults to all 0xff) and
-last but not least, the interpreter that is to be invoked (for example and
-testing /bin/echo). Type can be M for usual magic matching or E for filename
-extension matching (give extension in place of magic).
-
-Check or reset the status of the binary format handler
-------------------------------------------------------
-
-If you do a cat on the file /proc/sys/fs/binfmt_misc/status, you will get the
-current status (enabled/disabled) of binfmt_misc. Change the status by echoing
-0 (disables) or 1 (enables) or -1 (caution: this clears all previously
-registered binary formats) to status. For example echo 0 > status to disable
-binfmt_misc (temporarily).
-
-Status of a single handler
---------------------------
-
-Each registered handler has an entry in /proc/sys/fs/binfmt_misc. These files
-perform the same function as status, but their scope is limited to the actual
-binary format. By cating this file, you also receive all related information
-about the interpreter/magic of the binfmt.
-
-Example usage of binfmt_misc (emulate binfmt_java)
---------------------------------------------------
-
- cd /proc/sys/fs/binfmt_misc
- echo ':Java:M::\xca\xfe\xba\xbe::/usr/local/java/bin/javawrapper:' > register
- echo ':HTML:E::html::/usr/local/java/bin/appletviewer:' > register
- echo ':Applet:M::<!--applet::/usr/local/java/bin/appletviewer:' > register
- echo ':DEXE:M::\x0eDEX::/usr/bin/dosexec:' > register
-
-
-These four lines add support for Java executables and Java applets (like
-binfmt_java, additionally recognizing the .html extension with no need to put
-<!--applet> to every applet file). You have to install the JDK and the
-shell-script /usr/local/java/bin/javawrapper too. It works around the
-brokenness of the Java filename handling. To add a Java binary, just create a
-link to the class-file somewhere in the path.
-
-2.3 /proc/sys/kernel - general kernel parameters
-------------------------------------------------
-
-This directory reflects general kernel behaviors. As I've said before, the
-contents depend on your configuration. Here you'll find the most important
-files, along with descriptions of what they mean and how to use them.
-
-acct
-----
-
-The file contains three values; highwater, lowwater, and frequency.
-
-It exists only when BSD-style process accounting is enabled. These values
-control its behavior. If the free space on the file system where the log lives
-goes below lowwater percentage, accounting suspends. If it goes above
-highwater percentage, accounting resumes. Frequency determines how often you
-check the amount of free space (value is in seconds). Default settings are: 4,
-2, and 30. That is, suspend accounting if there is less than 2 percent free;
-resume it if we have a value of 3 or more percent; consider information about
-the amount of free space valid for 30 seconds
-
-ctrl-alt-del
-------------
-
-When the value in this file is 0, ctrl-alt-del is trapped and sent to the init
-program to handle a graceful restart. However, when the value is greater that
-zero, Linux's reaction to this key combination will be an immediate reboot,
-without syncing its dirty buffers.
-
-[NOTE]
- When a program (like dosemu) has the keyboard in raw mode, the
- ctrl-alt-del is intercepted by the program before it ever reaches the
- kernel tty layer, and it is up to the program to decide what to do with
- it.
-
-domainname and hostname
------------------------
-
-These files can be controlled to set the NIS domainname and hostname of your
-box. For the classic darkstar.frop.org a simple:
-
- # echo "darkstar" > /proc/sys/kernel/hostname
- # echo "frop.org" > /proc/sys/kernel/domainname
-
-
-would suffice to set your hostname and NIS domainname.
-
-osrelease, ostype and version
------------------------------
-
-The names make it pretty obvious what these fields contain:
-
- > cat /proc/sys/kernel/osrelease
- 2.2.12
-
- > cat /proc/sys/kernel/ostype
- Linux
-
- > cat /proc/sys/kernel/version
- #4 Fri Oct 1 12:41:14 PDT 1999
-
-
-The files osrelease and ostype should be clear enough. Version needs a little
-more clarification. The #4 means that this is the 4th kernel built from this
-source base and the date after it indicates the time the kernel was built. The
-only way to tune these values is to rebuild the kernel.
-
-panic
------
-
-The value in this file represents the number of seconds the kernel waits
-before rebooting on a panic. When you use the software watchdog, the
-recommended setting is 60. If set to 0, the auto reboot after a kernel panic
-is disabled, which is the default setting.
-
-printk
-------
-
-The four values in printk denote
-* console_loglevel,
-* default_message_loglevel,
-* minimum_console_loglevel and
-* default_console_loglevel
-respectively.
-
-These values influence printk() behavior when printing or logging error
-messages, which come from inside the kernel. See syslog(2) for more
-information on the different log levels.
-
-console_loglevel
-----------------
-
-Messages with a higher priority than this will be printed to the console.
-
-default_message_level
----------------------
-
-Messages without an explicit priority will be printed with this priority.
-
-minimum_console_loglevel
-------------------------
-
-Minimum (highest) value to which the console_loglevel can be set.
-
-default_console_loglevel
-------------------------
-
-Default value for console_loglevel.
-
-sg-big-buff
------------
-
-This file shows the size of the generic SCSI (sg) buffer. At this point, you
-can't tune it yet, but you can change it at compile time by editing
-include/scsi/sg.h and changing the value of SG_BIG_BUFF.
-
-If you use a scanner with SANE (Scanner Access Now Easy) you might want to set
-this to a higher value. Refer to the SANE documentation on this issue.
-
-modprobe
---------
-
-The location where the modprobe binary is located. The kernel uses this
-program to load modules on demand.
-
-unknown_nmi_panic
------------------
-
-The value in this file affects behavior of handling NMI. When the value is
-non-zero, unknown NMI is trapped and then panic occurs. At that time, kernel
-debugging information is displayed on console.
-
-NMI switch that most IA32 servers have fires unknown NMI up, for example.
-If a system hangs up, try pressing the NMI switch.
-
-panic_on_unrecovered_nmi
-------------------------
-
-The default Linux behaviour on an NMI of either memory or unknown is to continue
-operation. For many environments such as scientific computing it is preferable
-that the box is taken out and the error dealt with than an uncorrected
-parity/ECC error get propogated.
-
-A small number of systems do generate NMI's for bizarre random reasons such as
-power management so the default is off. That sysctl works like the existing
-panic controls already in that directory.
-
-nmi_watchdog
-------------
-
-Enables/Disables the NMI watchdog on x86 systems. When the value is non-zero
-the NMI watchdog is enabled and will continuously test all online cpus to
-determine whether or not they are still functioning properly. Currently,
-passing "nmi_watchdog=" parameter at boot time is required for this function
-to work.
-
-If LAPIC NMI watchdog method is in use (nmi_watchdog=2 kernel parameter), the
-NMI watchdog shares registers with oprofile. By disabling the NMI watchdog,
-oprofile may have more registers to utilize.
-
-msgmni
-------
-
-Maximum number of message queue ids on the system.
-This value scales to the amount of lowmem. It is automatically recomputed
-upon memory add/remove or ipc namespace creation/removal.
-When a value is written into this file, msgmni's value becomes fixed, i.e. it
-is not recomputed anymore when one of the above events occurs.
-Use auto_msgmni to change this behavior.
-
-auto_msgmni
------------
-
-Enables/Disables automatic recomputing of msgmni upon memory add/remove or
-upon ipc namespace creation/removal (see the msgmni description above).
-Echoing "1" into this file enables msgmni automatic recomputing.
-Echoing "0" turns it off.
-auto_msgmni default value is 1.
-
-
-2.4 /proc/sys/vm - The virtual memory subsystem
------------------------------------------------
-
-Please see: Documentation/sysctls/vm.txt for a description of these
+Please see: Documentation/sysctls/ directory for descriptions of these
entries.
+------------------------------------------------------------------------------
+Summary
+------------------------------------------------------------------------------
+Certain aspects of kernel behavior can be modified at runtime, without the
+need to recompile the kernel, or even to reboot the system. The files in the
+/proc/sys tree can not only be read, but also modified. You can use the echo
+command to write value into these files, thereby changing the default settings
+of the kernel.
+------------------------------------------------------------------------------
-2.5 /proc/sys/dev - Device specific parameters
-----------------------------------------------
-
-Currently there is only support for CDROM drives, and for those, there is only
-one read-only file containing information about the CD-ROM drives attached to
-the system:
-
- >cat /proc/sys/dev/cdrom/info
- CD-ROM information, Id: cdrom.c 2.55 1999/04/25
-
- drive name: sr0 hdb
- drive speed: 32 40
- drive # of slots: 1 0
- Can close tray: 1 1
- Can open tray: 1 1
- Can lock tray: 1 1
- Can change speed: 1 1
- Can select disk: 0 1
- Can read multisession: 1 1
- Can read MCN: 1 1
- Reports media changed: 1 1
- Can play audio: 1 1
-
-
-You see two drives, sr0 and hdb, along with a list of their features.
-
-2.6 /proc/sys/sunrpc - Remote procedure calls
----------------------------------------------
-
-This directory contains four files, which enable or disable debugging for the
-RPC functions NFS, NFS-daemon, RPC and NLM. The default values are 0. They can
-be set to one to turn debugging on. (The default value is 0 for each)
-
-2.7 /proc/sys/net - Networking stuff
-------------------------------------
-
-The interface to the networking parts of the kernel is located in
-/proc/sys/net. Table 2-3 shows all possible subdirectories. You may see only
-some of them, depending on your kernel's configuration.
-
-
-Table 2-3: Subdirectories in /proc/sys/net
-..............................................................................
- Directory Content Directory Content
- core General parameter appletalk Appletalk protocol
- unix Unix domain sockets netrom NET/ROM
- 802 E802 protocol ax25 AX25
- ethernet Ethernet protocol rose X.25 PLP layer
- ipv4 IP version 4 x25 X.25 protocol
- ipx IPX token-ring IBM token ring
- bridge Bridging decnet DEC net
- ipv6 IP version 6
-..............................................................................
-
-We will concentrate on IP networking here. Since AX15, X.25, and DEC Net are
-only minor players in the Linux world, we'll skip them in this chapter. You'll
-find some short info on Appletalk and IPX further on in this chapter. Review
-the online documentation and the kernel source to get a detailed view of the
-parameters for those protocols. In this section we'll discuss the
-subdirectories printed in bold letters in the table above. As default values
-are suitable for most needs, there is no need to change these values.
-
-/proc/sys/net/core - Network core options
------------------------------------------
-
-rmem_default
-------------
-
-The default setting of the socket receive buffer in bytes.
-
-rmem_max
---------
-
-The maximum receive socket buffer size in bytes.
-
-wmem_default
-------------
-
-The default setting (in bytes) of the socket send buffer.
-
-wmem_max
---------
-
-The maximum send socket buffer size in bytes.
-
-message_burst and message_cost
-------------------------------
-
-These parameters are used to limit the warning messages written to the kernel
-log from the networking code. They enforce a rate limit to make a
-denial-of-service attack impossible. A higher message_cost factor, results in
-fewer messages that will be written. Message_burst controls when messages will
-be dropped. The default settings limit warning messages to one every five
-seconds.
-
-warnings
---------
-
-This controls console messages from the networking stack that can occur because
-of problems on the network like duplicate address or bad checksums. Normally,
-this should be enabled, but if the problem persists the messages can be
-disabled.
-
-
-netdev_max_backlog
-------------------
-
-Maximum number of packets, queued on the INPUT side, when the interface
-receives packets faster than kernel can process them.
-
-optmem_max
-----------
-
-Maximum ancillary buffer size allowed per socket. Ancillary data is a sequence
-of struct cmsghdr structures with appended data.
-
-/proc/sys/net/unix - Parameters for Unix domain sockets
--------------------------------------------------------
-
-There are only two files in this subdirectory. They control the delays for
-deleting and destroying socket descriptors.
-
-2.8 /proc/sys/net/ipv4 - IPV4 settings
---------------------------------------
-
-IP version 4 is still the most used protocol in Unix networking. It will be
-replaced by IP version 6 in the next couple of years, but for the moment it's
-the de facto standard for the internet and is used in most networking
-environments around the world. Because of the importance of this protocol,
-we'll have a deeper look into the subtree controlling the behavior of the IPv4
-subsystem of the Linux kernel.
-
-Let's start with the entries in /proc/sys/net/ipv4.
-
-ICMP settings
--------------
-
-icmp_echo_ignore_all and icmp_echo_ignore_broadcasts
-----------------------------------------------------
-
-Turn on (1) or off (0), if the kernel should ignore all ICMP ECHO requests, or
-just those to broadcast and multicast addresses.
-
-Please note that if you accept ICMP echo requests with a broadcast/multi\-cast
-destination address your network may be used as an exploder for denial of
-service packet flooding attacks to other hosts.
-
-icmp_destunreach_rate, icmp_echoreply_rate, icmp_paramprob_rate and icmp_timeexeed_rate
----------------------------------------------------------------------------------------
-
-Sets limits for sending ICMP packets to specific targets. A value of zero
-disables all limiting. Any positive value sets the maximum package rate in
-hundredth of a second (on Intel systems).
-
-IP settings
------------
-
-ip_autoconfig
--------------
-
-This file contains the number one if the host received its IP configuration by
-RARP, BOOTP, DHCP or a similar mechanism. Otherwise it is zero.
-
-ip_default_ttl
---------------
-
-TTL (Time To Live) for IPv4 interfaces. This is simply the maximum number of
-hops a packet may travel.
-
-ip_dynaddr
-----------
-
-Enable dynamic socket address rewriting on interface address change. This is
-useful for dialup interface with changing IP addresses.
-
-ip_forward
-----------
-
-Enable or disable forwarding of IP packages between interfaces. Changing this
-value resets all other parameters to their default values. They differ if the
-kernel is configured as host or router.
-
-ip_local_port_range
--------------------
-
-Range of ports used by TCP and UDP to choose the local port. Contains two
-numbers, the first number is the lowest port, the second number the highest
-local port. Default is 1024-4999. Should be changed to 32768-61000 for
-high-usage systems.
-
-ip_no_pmtu_disc
----------------
-
-Global switch to turn path MTU discovery off. It can also be set on a per
-socket basis by the applications or on a per route basis.
-
-ip_masq_debug
--------------
-
-Enable/disable debugging of IP masquerading.
-
-IP fragmentation settings
--------------------------
-
-ipfrag_high_trash and ipfrag_low_trash
---------------------------------------
-
-Maximum memory used to reassemble IP fragments. When ipfrag_high_thresh bytes
-of memory is allocated for this purpose, the fragment handler will toss
-packets until ipfrag_low_thresh is reached.
-
-ipfrag_time
------------
-
-Time in seconds to keep an IP fragment in memory.
-
-TCP settings
-------------
-
-tcp_ecn
--------
-
-This file controls the use of the ECN bit in the IPv4 headers. This is a new
-feature about Explicit Congestion Notification, but some routers and firewalls
-block traffic that has this bit set, so it could be necessary to echo 0 to
-/proc/sys/net/ipv4/tcp_ecn if you want to talk to these sites. For more info
-you could read RFC2481.
-
-tcp_retrans_collapse
---------------------
-
-Bug-to-bug compatibility with some broken printers. On retransmit, try to send
-larger packets to work around bugs in certain TCP stacks. Can be turned off by
-setting it to zero.
-
-tcp_keepalive_probes
---------------------
-
-Number of keep alive probes TCP sends out, until it decides that the
-connection is broken.
-
-tcp_keepalive_time
-------------------
-
-How often TCP sends out keep alive messages, when keep alive is enabled. The
-default is 2 hours.
-
-tcp_syn_retries
----------------
-
-Number of times initial SYNs for a TCP connection attempt will be
-retransmitted. Should not be higher than 255. This is only the timeout for
-outgoing connections, for incoming connections the number of retransmits is
-defined by tcp_retries1.
-
-tcp_sack
---------
-
-Enable select acknowledgments after RFC2018.
-
-tcp_timestamps
---------------
-
-Enable timestamps as defined in RFC1323.
-
-tcp_stdurg
-----------
-
-Enable the strict RFC793 interpretation of the TCP urgent pointer field. The
-default is to use the BSD compatible interpretation of the urgent pointer
-pointing to the first byte after the urgent data. The RFC793 interpretation is
-to have it point to the last byte of urgent data. Enabling this option may
-lead to interoperability problems. Disabled by default.
-
-tcp_syncookies
---------------
-
-Only valid when the kernel was compiled with CONFIG_SYNCOOKIES. Send out
-syncookies when the syn backlog queue of a socket overflows. This is to ward
-off the common 'syn flood attack'. Disabled by default.
-
-Note that the concept of a socket backlog is abandoned. This means the peer
-may not receive reliable error messages from an over loaded server with
-syncookies enabled.
-
-tcp_window_scaling
-------------------
-
-Enable window scaling as defined in RFC1323.
-
-tcp_fin_timeout
----------------
-
-The length of time in seconds it takes to receive a final FIN before the
-socket is always closed. This is strictly a violation of the TCP
-specification, but required to prevent denial-of-service attacks.
-
-tcp_max_ka_probes
------------------
-
-Indicates how many keep alive probes are sent per slow timer run. Should not
-be set too high to prevent bursts.
-
-tcp_max_syn_backlog
--------------------
-
-Length of the per socket backlog queue. Since Linux 2.2 the backlog specified
-in listen(2) only specifies the length of the backlog queue of already
-established sockets. When more connection requests arrive Linux starts to drop
-packets. When syncookies are enabled the packets are still answered and the
-maximum queue is effectively ignored.
-
-tcp_retries1
-------------
-
-Defines how often an answer to a TCP connection request is retransmitted
-before giving up.
-
-tcp_retries2
-------------
-
-Defines how often a TCP packet is retransmitted before giving up.
-
-Interface specific settings
----------------------------
-
-In the directory /proc/sys/net/ipv4/conf you'll find one subdirectory for each
-interface the system knows about and one directory calls all. Changes in the
-all subdirectory affect all interfaces, whereas changes in the other
-subdirectories affect only one interface. All directories have the same
-entries:
-
-accept_redirects
-----------------
-
-This switch decides if the kernel accepts ICMP redirect messages or not. The
-default is 'yes' if the kernel is configured for a regular host and 'no' for a
-router configuration.
-
-accept_source_route
--------------------
-
-Should source routed packages be accepted or declined. The default is
-dependent on the kernel configuration. It's 'yes' for routers and 'no' for
-hosts.
-
-bootp_relay
-~~~~~~~~~~~
-
-Accept packets with source address 0.b.c.d with destinations not to this host
-as local ones. It is supposed that a BOOTP relay daemon will catch and forward
-such packets.
-
-The default is 0, since this feature is not implemented yet (kernel version
-2.2.12).
-
-forwarding
-----------
-
-Enable or disable IP forwarding on this interface.
-
-log_martians
-------------
-
-Log packets with source addresses with no known route to kernel log.
-
-mc_forwarding
--------------
-
-Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE and a
-multicast routing daemon is required.
-
-proxy_arp
----------
-
-Does (1) or does not (0) perform proxy ARP.
-
-rp_filter
----------
-
-Integer value determines if a source validation should be made. 1 means yes, 0
-means no. Disabled by default, but local/broadcast address spoofing is always
-on.
-
-If you set this to 1 on a router that is the only connection for a network to
-the net, it will prevent spoofing attacks against your internal networks
-(external addresses can still be spoofed), without the need for additional
-firewall rules.
-
-secure_redirects
-----------------
-
-Accept ICMP redirect messages only for gateways, listed in default gateway
-list. Enabled by default.
-
-shared_media
-------------
-
-If it is not set the kernel does not assume that different subnets on this
-device can communicate directly. Default setting is 'yes'.
-
-send_redirects
---------------
-
-Determines whether to send ICMP redirects to other hosts.
-
-Routing settings
-----------------
-
-The directory /proc/sys/net/ipv4/route contains several file to control
-routing issues.
-
-error_burst and error_cost
---------------------------
-
-These parameters are used to limit how many ICMP destination unreachable to
-send from the host in question. ICMP destination unreachable messages are
-sent when we cannot reach the next hop while trying to transmit a packet.
-It will also print some error messages to kernel logs if someone is ignoring
-our ICMP redirects. The higher the error_cost factor is, the fewer
-destination unreachable and error messages will be let through. Error_burst
-controls when destination unreachable messages and error messages will be
-dropped. The default settings limit warning messages to five every second.
-
-flush
------
-
-Writing to this file results in a flush of the routing cache.
-
-gc_elasticity, gc_interval, gc_min_interval_ms, gc_timeout, gc_thresh
----------------------------------------------------------------------
-
-Values to control the frequency and behavior of the garbage collection
-algorithm for the routing cache. gc_min_interval is deprecated and replaced
-by gc_min_interval_ms.
-
-
-max_size
---------
-
-Maximum size of the routing cache. Old entries will be purged once the cache
-reached has this size.
-
-redirect_load, redirect_number
-------------------------------
-
-Factors which determine if more ICPM redirects should be sent to a specific
-host. No redirects will be sent once the load limit or the maximum number of
-redirects has been reached.
-
-redirect_silence
-----------------
-
-Timeout for redirects. After this period redirects will be sent again, even if
-this has been stopped, because the load or number limit has been reached.
-
-Network Neighbor handling
--------------------------
-
-Settings about how to handle connections with direct neighbors (nodes attached
-to the same link) can be found in the directory /proc/sys/net/ipv4/neigh.
-
-As we saw it in the conf directory, there is a default subdirectory which
-holds the default values, and one directory for each interface. The contents
-of the directories are identical, with the single exception that the default
-settings contain additional options to set garbage collection parameters.
-
-In the interface directories you'll find the following entries:
-
-base_reachable_time, base_reachable_time_ms
--------------------------------------------
-
-A base value used for computing the random reachable time value as specified
-in RFC2461.
-
-Expression of base_reachable_time, which is deprecated, is in seconds.
-Expression of base_reachable_time_ms is in milliseconds.
-
-retrans_time, retrans_time_ms
------------------------------
-
-The time between retransmitted Neighbor Solicitation messages.
-Used for address resolution and to determine if a neighbor is
-unreachable.
-
-Expression of retrans_time, which is deprecated, is in 1/100 seconds (for
-IPv4) or in jiffies (for IPv6).
-Expression of retrans_time_ms is in milliseconds.
-
-unres_qlen
-----------
-
-Maximum queue length for a pending arp request - the number of packets which
-are accepted from other layers while the ARP address is still resolved.
-
-anycast_delay
--------------
-
-Maximum for random delay of answers to neighbor solicitation messages in
-jiffies (1/100 sec). Not yet implemented (Linux does not have anycast support
-yet).
-
-ucast_solicit
--------------
-
-Maximum number of retries for unicast solicitation.
-
-mcast_solicit
--------------
-
-Maximum number of retries for multicast solicitation.
-
-delay_first_probe_time
-----------------------
-
-Delay for the first time probe if the neighbor is reachable. (see
-gc_stale_time)
-
-locktime
---------
-
-An ARP/neighbor entry is only replaced with a new one if the old is at least
-locktime old. This prevents ARP cache thrashing.
-
-proxy_delay
------------
-
-Maximum time (real time is random [0..proxytime]) before answering to an ARP
-request for which we have an proxy ARP entry. In some cases, this is used to
-prevent network flooding.
-
-proxy_qlen
-----------
-
-Maximum queue length of the delayed proxy arp timer. (see proxy_delay).
-
-app_solicit
-----------
-
-Determines the number of requests to send to the user level ARP daemon. Use 0
-to turn off.
-
-gc_stale_time
--------------
-
-Determines how often to check for stale ARP entries. After an ARP entry is
-stale it will be resolved again (which is useful when an IP address migrates
-to another machine). When ucast_solicit is greater than 0 it first tries to
-send an ARP packet directly to the known host When that fails and
-mcast_solicit is greater than 0, an ARP request is broadcasted.
-
-2.9 Appletalk
--------------
-
-The /proc/sys/net/appletalk directory holds the Appletalk configuration data
-when Appletalk is loaded. The configurable parameters are:
-
-aarp-expiry-time
-----------------
-
-The amount of time we keep an ARP entry before expiring it. Used to age out
-old hosts.
-
-aarp-resolve-time
------------------
-
-The amount of time we will spend trying to resolve an Appletalk address.
-
-aarp-retransmit-limit
----------------------
-
-The number of times we will retransmit a query before giving up.
-
-aarp-tick-time
---------------
-
-Controls the rate at which expires are checked.
-
-The directory /proc/net/appletalk holds the list of active Appletalk sockets
-on a machine.
-
-The fields indicate the DDP type, the local address (in network:node format)
-the remote address, the size of the transmit pending queue, the size of the
-received queue (bytes waiting for applications to read) the state and the uid
-owning the socket.
-
-/proc/net/atalk_iface lists all the interfaces configured for appletalk.It
-shows the name of the interface, its Appletalk address, the network range on
-that address (or network number for phase 1 networks), and the status of the
-interface.
-
-/proc/net/atalk_route lists each known network route. It lists the target
-(network) that the route leads to, the router (may be directly connected), the
-route flags, and the device the route is using.
-
-2.10 IPX
---------
-
-The IPX protocol has no tunable values in proc/sys/net.
-
-The IPX protocol does, however, provide proc/net/ipx. This lists each IPX
-socket giving the local and remote addresses in Novell format (that is
-network:node:port). In accordance with the strange Novell tradition,
-everything but the port is in hex. Not_Connected is displayed for sockets that
-are not tied to a specific remote address. The Tx and Rx queue sizes indicate
-the number of bytes pending for transmission and reception. The state
-indicates the state the socket is in and the uid is the owning uid of the
-socket.
-
-The /proc/net/ipx_interface file lists all IPX interfaces. For each interface
-it gives the network number, the node number, and indicates if the network is
-the primary network. It also indicates which device it is bound to (or
-Internal for internal networks) and the Frame Type if appropriate. Linux
-supports 802.3, 802.2, 802.2 SNAP and DIX (Blue Book) ethernet framing for
-IPX.
-
-The /proc/net/ipx_route table holds a list of IPX routes. For each route it
-gives the destination network, the router node (or Directly) and the network
-address of the router (or Connected) for internal networks.
-
-2.11 /proc/sys/fs/mqueue - POSIX message queues filesystem
-----------------------------------------------------------
-
-The "mqueue" filesystem provides the necessary kernel features to enable the
-creation of a user space library that implements the POSIX message queues
-API (as noted by the MSG tag in the POSIX 1003.1-2001 version of the System
-Interfaces specification.)
-
-The "mqueue" filesystem contains values for determining/setting the amount of
-resources used by the file system.
-
-/proc/sys/fs/mqueue/queues_max is a read/write file for setting/getting the
-maximum number of message queues allowed on the system.
-
-/proc/sys/fs/mqueue/msg_max is a read/write file for setting/getting the
-maximum number of messages in a queue value. In fact it is the limiting value
-for another (user) limit which is set in mq_open invocation. This attribute of
-a queue must be less or equal then msg_max.
-
-/proc/sys/fs/mqueue/msgsize_max is a read/write file for setting/getting the
-maximum message size value (it is every message queue's attribute set during
-its creation).
+------------------------------------------------------------------------------
+CHAPTER 3: PER-PROCESS PARAMETERS
+------------------------------------------------------------------------------
-2.12 /proc/<pid>/oom_adj - Adjust the oom-killer score
+3.1 /proc/<pid>/oom_adj - Adjust the oom-killer score
------------------------------------------------------
This file can be used to adjust the score used to select which processes
@@ -2055,25 +1037,15 @@ The task with the highest badness score is then selected and its children
are killed, process itself will be killed in an OOM situation when it does
not have children or some of them disabled oom like described above.
-2.13 /proc/<pid>/oom_score - Display current oom-killer score
+3.2 /proc/<pid>/oom_score - Display current oom-killer score
-------------------------------------------------------------
-------------------------------------------------------------------------------
This file can be used to check the current score used by the oom-killer is for
any given <pid>. Use it together with /proc/<pid>/oom_adj to tune which
process should be killed in an out-of-memory situation.
-------------------------------------------------------------------------------
-Summary
-------------------------------------------------------------------------------
-Certain aspects of kernel behavior can be modified at runtime, without the
-need to recompile the kernel, or even to reboot the system. The files in the
-/proc/sys tree can not only be read, but also modified. You can use the echo
-command to write value into these files, thereby changing the default settings
-of the kernel.
-------------------------------------------------------------------------------
-2.14 /proc/<pid>/io - Display the IO accounting fields
+3.3 /proc/<pid>/io - Display the IO accounting fields
-------------------------------------------------------
This file contains IO statistics for each running process
@@ -2175,7 +1147,7 @@ those 64-bit counters, process A could see an intermediate result.
More information about this can be found within the taskstats documentation in
Documentation/accounting.
-2.15 /proc/<pid>/coredump_filter - Core dump filtering settings
+3.4 /proc/<pid>/coredump_filter - Core dump filtering settings
---------------------------------------------------------------
When a process is dumped, all anonymous memory is written to a core file as
long as the size of the core file isn't limited. But sometimes we don't want
@@ -2219,7 +1191,7 @@ For example:
$ echo 0x7 > /proc/self/coredump_filter
$ ./some_program
-2.16 /proc/<pid>/mountinfo - Information about mounts
+3.5 /proc/<pid>/mountinfo - Information about mounts
--------------------------------------------------------
This file contains lines of the form:
@@ -2256,30 +1228,3 @@ For more information on mount propagation see:
Documentation/filesystems/sharedsubtree.txt
-2.17 /proc/sys/fs/epoll - Configuration options for the epoll interface
---------------------------------------------------------
-
-This directory contains configuration options for the epoll(7) interface.
-
-max_user_instances
-------------------
-
-This is the maximum number of epoll file descriptors that a single user can
-have open at a given time. The default value is 128, and should be enough
-for normal users.
-
-max_user_watches
-----------------
-
-Every epoll file descriptor can store a number of files to be monitored
-for event readiness. Each one of these monitored files constitutes a "watch".
-This configuration option sets the maximum number of "watches" that are
-allowed for each user.
-Each "watch" costs roughly 90 bytes on a 32bit kernel, and roughly 160 bytes
-on a 64bit one.
-The current default value for max_user_watches is the 1/32 of the available
-low memory, divided for the "watch" cost in bytes.
-
-
-------------------------------------------------------------------------------
-
diff --git a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt
index 9f8740ca3f3b..26e4b8bc53ee 100644
--- a/Documentation/filesystems/sysfs-pci.txt
+++ b/Documentation/filesystems/sysfs-pci.txt
@@ -12,6 +12,7 @@ that support it. For example, a given bus might look like this:
| |-- enable
| |-- irq
| |-- local_cpus
+ | |-- remove
| |-- resource
| |-- resource0
| |-- resource1
@@ -36,6 +37,7 @@ files, each with their own function.
enable Whether the device is enabled (ascii, rw)
irq IRQ number (ascii, ro)
local_cpus nearby CPU mask (cpumask, ro)
+ remove remove device from kernel's list (ascii, wo)
resource PCI resource host addresses (ascii, ro)
resource0..N PCI resource N, if present (binary, mmap)
resource0_wc..N_wc PCI WC map resource N, if prefetchable (binary, mmap)
@@ -46,6 +48,7 @@ files, each with their own function.
ro - read only file
rw - file is readable and writable
+ wo - write only file
mmap - file is mmapable
ascii - file contains ascii text
binary - file contains binary data
@@ -73,6 +76,13 @@ that the device must be enabled for a rom read to return data succesfully.
In the event a driver is not bound to the device, it can be enabled using the
'enable' file, documented above.
+The 'remove' file is used to remove the PCI device, by writing a non-zero
+integer to the file. This does not involve any kind of hot-plug functionality,
+e.g. powering off the device. The device is removed from the kernel's list of
+PCI devices, the sysfs directory for it is removed, and the device will be
+removed from any drivers attached to it. Removal of PCI root buses is
+disallowed.
+
Accessing legacy resources through sysfs
----------------------------------------
diff --git a/Documentation/filesystems/udf.txt b/Documentation/filesystems/udf.txt
index fde829a756e6..902b95d0ee51 100644
--- a/Documentation/filesystems/udf.txt
+++ b/Documentation/filesystems/udf.txt
@@ -24,6 +24,8 @@ The following mount options are supported:
gid= Set the default group.
umask= Set the default umask.
+ mode= Set the default file permissions.
+ dmode= Set the default directory permissions.
uid= Set the default user.
bs= Set the block size.
unhide Show otherwise hidden files.
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
index b1b988701247..145c25a170c7 100644
--- a/Documentation/gpio.txt
+++ b/Documentation/gpio.txt
@@ -123,7 +123,10 @@ platform-specific implementation issue.
Using GPIOs
-----------
-One of the first things to do with a GPIO, often in board setup code when
+The first thing a system should do with a GPIO is allocate it, using
+the gpio_request() call; see later.
+
+One of the next things to do with a GPIO, often in board setup code when
setting up a platform_device using the GPIO, is mark its direction:
/* set as input or output, returning 0 or negative errno */
@@ -141,8 +144,8 @@ This helps avoid signal glitching during system startup.
For compatibility with legacy interfaces to GPIOs, setting the direction
of a GPIO implicitly requests that GPIO (see below) if it has not been
-requested already. That compatibility may be removed in the future;
-explicitly requesting GPIOs is strongly preferred.
+requested already. That compatibility is being removed from the optional
+gpiolib framework.
Setting the direction can fail if the GPIO number is invalid, or when
that particular GPIO can't be used in that mode. It's generally a bad
@@ -195,7 +198,7 @@ This requires sleeping, which can't be done from inside IRQ handlers.
Platforms that support this type of GPIO distinguish them from other GPIOs
by returning nonzero from this call (which requires a valid GPIO number,
-either explicitly or implicitly requested):
+which should have been previously allocated with gpio_request):
int gpio_cansleep(unsigned gpio);
@@ -212,10 +215,9 @@ for GPIOs that can't be accessed from IRQ handlers, these calls act the
same as the spinlock-safe calls.
-Claiming and Releasing GPIOs (OPTIONAL)
----------------------------------------
+Claiming and Releasing GPIOs
+----------------------------
To help catch system configuration errors, two calls are defined.
-However, many platforms don't currently support this mechanism.
/* request GPIO, returning 0 or negative errno.
* non-null labels may be useful for diagnostics.
@@ -244,13 +246,6 @@ Some platforms may also use knowledge about what GPIOs are active for
power management, such as by powering down unused chip sectors and, more
easily, gating off unused clocks.
-These two calls are optional because not not all current Linux platforms
-offer such functionality in their GPIO support; a valid implementation
-could return success for all gpio_request() calls. Unlike the other calls,
-the state they represent doesn't normally match anything from a hardware
-register; it's just a software bitmap which clearly is not necessary for
-correct operation of hardware or (bug free) drivers.
-
Note that requesting a GPIO does NOT cause it to be configured in any
way; it just marks that GPIO as in use. Separate code must handle any
pin setup (e.g. controlling which pin the GPIO uses, pullup/pulldown).
diff --git a/Documentation/hwmon/ds1621 b/Documentation/hwmon/ds1621
index 1fee6f1e6bc5..5e97f333c4df 100644
--- a/Documentation/hwmon/ds1621
+++ b/Documentation/hwmon/ds1621
@@ -49,12 +49,9 @@ of up to +/- 0.5 degrees even when compared against precise temperature
readings. Be sure to have a high vs. low temperature limit gap of al least
1.0 degree Celsius to avoid Tout "bouncing", though!
-As for alarms, you can read the alarm status of the DS1621 via the 'alarms'
-/sys file interface. The result consists mainly of bit 6 and 5 of the
-configuration register of the chip; bit 6 (0x40 or 64) is the high alarm
-bit and bit 5 (0x20 or 32) the low one. These bits are set when the high or
-low limits are met or exceeded and are reset by the module as soon as the
-respective temperature ranges are left.
+The alarm bits are set when the high or low limits are met or exceeded and
+are reset by the module as soon as the respective temperature ranges are
+left.
The alarm registers are in no way suitable to find out about the actual
status of Tout. They will only tell you about its history, whether or not
@@ -64,45 +61,3 @@ with neither of the alarms set.
Temperature conversion of the DS1621 takes up to 1000ms; internal access to
non-volatile registers may last for 10ms or below.
-
-High Accuracy Temperature Reading
----------------------------------
-
-As said before, the temperature issued via the 9-bit i2c-bus data is
-somewhat arbitrary. Internally, the temperature conversion is of a
-different kind that is explained (not so...) well in the DS1621 data sheet.
-To cut the long story short: Inside the DS1621 there are two oscillators,
-both of them biassed by a temperature coefficient.
-
-Higher resolution of the temperature reading can be achieved using the
-internal projection, which means taking account of REG_COUNT and REG_SLOPE
-(the driver manages them):
-
-Taken from Dallas Semiconductors App Note 068: 'Increasing Temperature
-Resolution on the DS1620' and App Note 105: 'High Resolution Temperature
-Measurement with Dallas Direct-to-Digital Temperature Sensors'
-
-- Read the 9-bit temperature and strip the LSB (Truncate the .5 degs)
-- The resulting value is TEMP_READ.
-- Then, read REG_COUNT.
-- And then, REG_SLOPE.
-
- TEMP = TEMP_READ - 0.25 + ((REG_SLOPE - REG_COUNT) / REG_SLOPE)
-
-Note that this is what the DONE bit in the DS1621 configuration register is
-good for: Internally, one temperature conversion takes up to 1000ms. Before
-that conversion is complete you will not be able to read valid things out
-of REG_COUNT and REG_SLOPE. The DONE bit, as you may have guessed by now,
-tells you whether the conversion is complete ("done", in plain English) and
-thus, whether the values you read are good or not.
-
-The DS1621 has two modes of operation: "Continuous" conversion, which can
-be understood as the default stand-alone mode where the chip gets the
-temperature and controls external devices via its Tout pin or tells other
-i2c's about it if they care. The other mode is called "1SHOT", that means
-that it only figures out about the temperature when it is explicitly told
-to do so; this can be seen as power saving mode.
-
-Now if you want to read REG_COUNT and REG_SLOPE, you have to either stop
-the continuous conversions until the contents of these registers are valid,
-or, in 1SHOT mode, you have to have one conversion made.
diff --git a/Documentation/hwmon/lis3lv02d b/Documentation/hwmon/lis3lv02d
index 287f8c902656..effe949a7282 100644
--- a/Documentation/hwmon/lis3lv02d
+++ b/Documentation/hwmon/lis3lv02d
@@ -1,11 +1,11 @@
Kernel driver lis3lv02d
-==================
+=======================
Supported chips:
* STMicroelectronics LIS3LV02DL and LIS3LV02DQ
-Author:
+Authors:
Yan Burman <burman.yan@gmail.com>
Eric Piel <eric.piel@tremplin-utc.net>
@@ -15,7 +15,7 @@ Description
This driver provides support for the accelerometer found in various HP
laptops sporting the feature officially called "HP Mobile Data
-Protection System 3D" or "HP 3D DriveGuard". It detect automatically
+Protection System 3D" or "HP 3D DriveGuard". It detects automatically
laptops with this sensor. Known models (for now the HP 2133, nc6420,
nc2510, nc8510, nc84x0, nw9440 and nx9420) will have their axis
automatically oriented on standard way (eg: you can directly play
@@ -27,7 +27,7 @@ position - 3D position that the accelerometer reports. Format: "(x,y,z)"
calibrate - read: values (x, y, z) that are used as the base for input
class device operation.
write: forces the base to be recalibrated with the current
- position.
+ position.
rate - reports the sampling rate of the accelerometer device in HZ
This driver also provides an absolute input class device, allowing
@@ -48,7 +48,7 @@ For better compatibility between the various laptops. The values reported by
the accelerometer are converted into a "standard" organisation of the axes
(aka "can play neverball out of the box"):
* When the laptop is horizontal the position reported is about 0 for X and Y
-and a positive value for Z
+ and a positive value for Z
* If the left side is elevated, X increases (becomes positive)
* If the front side (where the touchpad is) is elevated, Y decreases
(becomes negative)
@@ -59,3 +59,13 @@ email to the authors to add it to the database. When reporting a new
laptop, please include the output of "dmidecode" plus the value of
/sys/devices/platform/lis3lv02d/position in these four cases.
+Q&A
+---
+
+Q: How do I safely simulate freefall? I have an HP "portable
+workstation" which has about 3.5kg and a plastic case, so letting it
+fall to the ground is out of question...
+
+A: The sensor is pretty sensitive, so your hands can do it. Lift it
+into free space, follow the fall with your hands for like 10
+centimeters. That should be enough to trigger the detection.
diff --git a/Documentation/hwmon/ltc4215 b/Documentation/hwmon/ltc4215
new file mode 100644
index 000000000000..2e6a21eb656c
--- /dev/null
+++ b/Documentation/hwmon/ltc4215
@@ -0,0 +1,50 @@
+Kernel driver ltc4215
+=====================
+
+Supported chips:
+ * Linear Technology LTC4215
+ Prefix: 'ltc4215'
+ Addresses scanned: 0x44
+ Datasheet:
+ http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1163,P17572,D12697
+
+Author: Ira W. Snyder <iws@ovro.caltech.edu>
+
+
+Description
+-----------
+
+The LTC4215 controller allows a board to be safely inserted and removed
+from a live backplane.
+
+
+Usage Notes
+-----------
+
+This driver does not probe for LTC4215 devices, due to the fact that some
+of the possible addresses are unfriendly to probing. You will need to use
+the "force" parameter to tell the driver where to find the device.
+
+Example: the following will load the driver for an LTC4215 at address 0x44
+on I2C bus #0:
+$ modprobe ltc4215 force=0,0x44
+
+
+Sysfs entries
+-------------
+
+The LTC4215 has built-in limits for overvoltage, undervoltage, and
+undercurrent warnings. This makes it very likely that the reference
+circuit will be used.
+
+in1_input input voltage
+in2_input output voltage
+
+in1_min_alarm input undervoltage alarm
+in1_max_alarm input overvoltage alarm
+
+curr1_input current
+curr1_max_alarm overcurrent alarm
+
+power1_input power usage
+power1_alarm power bad alarm
diff --git a/Documentation/i2c/chips/pcf8591 b/Documentation/hwmon/pcf8591
index 5628fcf4207f..5628fcf4207f 100644
--- a/Documentation/i2c/chips/pcf8591
+++ b/Documentation/hwmon/pcf8591
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
index 6dbfd5efd991..2f10ce6a879f 100644
--- a/Documentation/hwmon/sysfs-interface
+++ b/Documentation/hwmon/sysfs-interface
@@ -365,6 +365,7 @@ energy[1-*]_input Cumulative energy use
Unit: microJoule
RO
+
**********
* Alarms *
**********
@@ -453,6 +454,27 @@ beep_mask Bitmask for beep.
RW
+***********************
+* Intrusion detection *
+***********************
+
+intrusion[0-*]_alarm
+ Chassis intrusion detection
+ 0: OK
+ 1: intrusion detected
+ RW
+ Contrary to regular alarm flags which clear themselves
+ automatically when read, this one sticks until cleared by
+ the user. This is done by writing 0 to the file. Writing
+ other values is unsupported.
+
+intrusion[0-*]_beep
+ Chassis intrusion beep
+ 0: disable
+ 1: enable
+ RW
+
+
sysfs attribute writes interpretation
-------------------------------------
diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf
index d6e1ae30fa6e..b6eb59384bb3 100644
--- a/Documentation/hwmon/w83627ehf
+++ b/Documentation/hwmon/w83627ehf
@@ -2,30 +2,40 @@ Kernel driver w83627ehf
=======================
Supported chips:
- * Winbond W83627EHF/EHG/DHG (ISA access ONLY)
+ * Winbond W83627EHF/EHG (ISA access ONLY)
Prefix: 'w83627ehf'
Addresses scanned: ISA address retrieved from Super I/O registers
Datasheet:
- http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf
- DHG datasheet confidential.
+ http://www.nuvoton.com.tw/NR/rdonlyres/A6A258F0-F0C9-4F97-81C0-C4D29E7E943E/0/W83627EHF.pdf
+ * Winbond W83627DHG
+ Prefix: 'w83627dhg'
+ Addresses scanned: ISA address retrieved from Super I/O registers
+ Datasheet:
+ http://www.nuvoton.com.tw/NR/rdonlyres/7885623D-A487-4CF9-A47F-30C5F73D6FE6/0/W83627DHG.pdf
+ * Winbond W83667HG
+ Prefix: 'w83667hg'
+ Addresses scanned: ISA address retrieved from Super I/O registers
+ Datasheet: not available
Authors:
Jean Delvare <khali@linux-fr.org>
Yuan Mu (Winbond)
Rudolf Marek <r.marek@assembler.cz>
David Hubbard <david.c.hubbard@gmail.com>
+ Gong Jun <JGong@nuvoton.com>
Description
-----------
-This driver implements support for the Winbond W83627EHF, W83627EHG, and
-W83627DHG super I/O chips. We will refer to them collectively as Winbond chips.
+This driver implements support for the Winbond W83627EHF, W83627EHG,
+W83627DHG and W83667HG super I/O chips. We will refer to them collectively
+as Winbond chips.
The chips implement three temperature sensors, five fan rotation
speed sensors, ten analog voltage sensors (only nine for the 627DHG), one
-VID (6 pins for the 627EHF/EHG, 8 pins for the 627DHG), alarms with beep
-warnings (control unimplemented), and some automatic fan regulation
-strategies (plus manual fan control mode).
+VID (6 pins for the 627EHF/EHG, 8 pins for the 627DHG and 667HG), alarms
+with beep warnings (control unimplemented), and some automatic fan
+regulation strategies (plus manual fan control mode).
Temperatures are measured in degrees Celsius and measurement resolution is 1
degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
@@ -54,7 +64,8 @@ follows:
temp1 -> pwm1
temp2 -> pwm2
temp3 -> pwm3
-prog -> pwm4 (the programmable setting is not supported by the driver)
+prog -> pwm4 (not on 667HG; the programmable setting is not supported by
+ the driver)
/sys files
----------
diff --git a/Documentation/i2c/busses/i2c-nforce2 b/Documentation/i2c/busses/i2c-nforce2
index fae3495bcbaf..9698c396b830 100644
--- a/Documentation/i2c/busses/i2c-nforce2
+++ b/Documentation/i2c/busses/i2c-nforce2
@@ -7,10 +7,14 @@ Supported adapters:
* nForce3 250Gb MCP 10de:00E4
* nForce4 MCP 10de:0052
* nForce4 MCP-04 10de:0034
- * nForce4 MCP51 10de:0264
- * nForce4 MCP55 10de:0368
- * nForce4 MCP61 10de:03EB
- * nForce4 MCP65 10de:0446
+ * nForce MCP51 10de:0264
+ * nForce MCP55 10de:0368
+ * nForce MCP61 10de:03EB
+ * nForce MCP65 10de:0446
+ * nForce MCP67 10de:0542
+ * nForce MCP73 10de:07D8
+ * nForce MCP78S 10de:0752
+ * nForce MCP79 10de:0AA2
Datasheet: not publicly available, but seems to be similar to the
AMD-8111 SMBus 2.0 adapter.
diff --git a/Documentation/i2c/busses/i2c-piix4 b/Documentation/i2c/busses/i2c-piix4
index ef1efa79b1df..f889481762b5 100644
--- a/Documentation/i2c/busses/i2c-piix4
+++ b/Documentation/i2c/busses/i2c-piix4
@@ -4,7 +4,7 @@ Supported adapters:
* Intel 82371AB PIIX4 and PIIX4E
* Intel 82443MX (440MX)
Datasheet: Publicly available at the Intel website
- * ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges
+ * ServerWorks OSB4, CSB5, CSB6, HT-1000 and HT-1100 southbridges
Datasheet: Only available via NDA from ServerWorks
* ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges
Datasheet: Not publicly available
diff --git a/Documentation/i2c/instantiating-devices b/Documentation/i2c/instantiating-devices
new file mode 100644
index 000000000000..b55ce57a84db
--- /dev/null
+++ b/Documentation/i2c/instantiating-devices
@@ -0,0 +1,167 @@
+How to instantiate I2C devices
+==============================
+
+Unlike PCI or USB devices, I2C devices are not enumerated at the hardware
+level. Instead, the software must know which devices are connected on each
+I2C bus segment, and what address these devices are using. For this
+reason, the kernel code must instantiate I2C devices explicitly. There are
+several ways to achieve this, depending on the context and requirements.
+
+
+Method 1: Declare the I2C devices by bus number
+-----------------------------------------------
+
+This method is appropriate when the I2C bus is a system bus as is the case
+for many embedded systems. On such systems, each I2C bus has a number
+which is known in advance. It is thus possible to pre-declare the I2C
+devices which live on this bus. This is done with an array of struct
+i2c_board_info which is registered by calling i2c_register_board_info().
+
+Example (from omap2 h4):
+
+static struct i2c_board_info __initdata h4_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("isp1301_omap", 0x2d),
+ .irq = OMAP_GPIO_IRQ(125),
+ },
+ { /* EEPROM on mainboard */
+ I2C_BOARD_INFO("24c01", 0x52),
+ .platform_data = &m24c01,
+ },
+ { /* EEPROM on cpu card */
+ I2C_BOARD_INFO("24c01", 0x57),
+ .platform_data = &m24c01,
+ },
+};
+
+static void __init omap_h4_init(void)
+{
+ (...)
+ i2c_register_board_info(1, h4_i2c_board_info,
+ ARRAY_SIZE(h4_i2c_board_info));
+ (...)
+}
+
+The above code declares 3 devices on I2C bus 1, including their respective
+addresses and custom data needed by their drivers. When the I2C bus in
+question is registered, the I2C devices will be instantiated automatically
+by i2c-core.
+
+The devices will be automatically unbound and destroyed when the I2C bus
+they sit on goes away (if ever.)
+
+
+Method 2: Instantiate the devices explicitly
+--------------------------------------------
+
+This method is appropriate when a larger device uses an I2C bus for
+internal communication. A typical case is TV adapters. These can have a
+tuner, a video decoder, an audio decoder, etc. usually connected to the
+main chip by the means of an I2C bus. You won't know the number of the I2C
+bus in advance, so the method 1 described above can't be used. Instead,
+you can instantiate your I2C devices explicitly. This is done by filling
+a struct i2c_board_info and calling i2c_new_device().
+
+Example (from the sfe4001 network driver):
+
+static struct i2c_board_info sfe4001_hwmon_info = {
+ I2C_BOARD_INFO("max6647", 0x4e),
+};
+
+int sfe4001_init(struct efx_nic *efx)
+{
+ (...)
+ efx->board_info.hwmon_client =
+ i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info);
+
+ (...)
+}
+
+The above code instantiates 1 I2C device on the I2C bus which is on the
+network adapter in question.
+
+A variant of this is when you don't know for sure if an I2C device is
+present or not (for example for an optional feature which is not present
+on cheap variants of a board but you have no way to tell them apart), or
+it may have different addresses from one board to the next (manufacturer
+changing its design without notice). In this case, you can call
+i2c_new_probed_device() instead of i2c_new_device().
+
+Example (from the pnx4008 OHCI driver):
+
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
+
+static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
+{
+ (...)
+ struct i2c_adapter *i2c_adap;
+ struct i2c_board_info i2c_info;
+
+ (...)
+ i2c_adap = i2c_get_adapter(2);
+ memset(&i2c_info, 0, sizeof(struct i2c_board_info));
+ strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE);
+ isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
+ normal_i2c);
+ i2c_put_adapter(i2c_adap);
+ (...)
+}
+
+The above code instantiates up to 1 I2C device on the I2C bus which is on
+the OHCI adapter in question. It first tries at address 0x2c, if nothing
+is found there it tries address 0x2d, and if still nothing is found, it
+simply gives up.
+
+The driver which instantiated the I2C device is responsible for destroying
+it on cleanup. This is done by calling i2c_unregister_device() on the
+pointer that was earlier returned by i2c_new_device() or
+i2c_new_probed_device().
+
+
+Method 3: Probe an I2C bus for certain devices
+----------------------------------------------
+
+Sometimes you do not have enough information about an I2C device, not even
+to call i2c_new_probed_device(). The typical case is hardware monitoring
+chips on PC mainboards. There are several dozen models, which can live
+at 25 different addresses. Given the huge number of mainboards out there,
+it is next to impossible to build an exhaustive list of the hardware
+monitoring chips being used. Fortunately, most of these chips have
+manufacturer and device ID registers, so they can be identified by
+probing.
+
+In that case, I2C devices are neither declared nor instantiated
+explicitly. Instead, i2c-core will probe for such devices as soon as their
+drivers are loaded, and if any is found, an I2C device will be
+instantiated automatically. In order to prevent any misbehavior of this
+mechanism, the following restrictions apply:
+* The I2C device driver must implement the detect() method, which
+ identifies a supported device by reading from arbitrary registers.
+* Only buses which are likely to have a supported device and agree to be
+ probed, will be probed. For example this avoids probing for hardware
+ monitoring chips on a TV adapter.
+
+Example:
+See lm90_driver and lm90_detect() in drivers/hwmon/lm90.c
+
+I2C devices instantiated as a result of such a successful probe will be
+destroyed automatically when the driver which detected them is removed,
+or when the underlying I2C bus is itself destroyed, whichever happens
+first.
+
+Those of you familiar with the i2c subsystem of 2.4 kernels and early 2.6
+kernels will find out that this method 3 is essentially similar to what
+was done there. Two significant differences are:
+* Probing is only one way to instantiate I2C devices now, while it was the
+ only way back then. Where possible, methods 1 and 2 should be preferred.
+ Method 3 should only be used when there is no other way, as it can have
+ undesirable side effects.
+* I2C buses must now explicitly say which I2C driver classes can probe
+ them (by the means of the class bitfield), while all I2C buses were
+ probed by default back then. The default is an empty class which means
+ that no probing happens. The purpose of the class bitfield is to limit
+ the aforementioned undesirable side effects.
+
+Once again, method 3 should be avoided wherever possible. Explicit device
+instantiation (methods 1 and 2) is much preferred for it is safer and
+faster.
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
index 6b9af7d479c2..c1a06f989cf7 100644
--- a/Documentation/i2c/writing-clients
+++ b/Documentation/i2c/writing-clients
@@ -207,15 +207,26 @@ You simply have to define a detect callback which will attempt to
identify supported devices (returning 0 for supported ones and -ENODEV
for unsupported ones), a list of addresses to probe, and a device type
(or class) so that only I2C buses which may have that type of device
-connected (and not otherwise enumerated) will be probed. The i2c
-core will then call you back as needed and will instantiate a device
-for you for every successful detection.
+connected (and not otherwise enumerated) will be probed. For example,
+a driver for a hardware monitoring chip for which auto-detection is
+needed would set its class to I2C_CLASS_HWMON, and only I2C adapters
+with a class including I2C_CLASS_HWMON would be probed by this driver.
+Note that the absence of matching classes does not prevent the use of
+a device of that type on the given I2C adapter. All it prevents is
+auto-detection; explicit instantiation of devices is still possible.
Note that this mechanism is purely optional and not suitable for all
devices. You need some reliable way to identify the supported devices
(typically using device-specific, dedicated identification registers),
otherwise misdetections are likely to occur and things can get wrong
-quickly.
+quickly. Keep in mind that the I2C protocol doesn't include any
+standard way to detect the presence of a chip at a given address, let
+alone a standard way to identify devices. Even worse is the lack of
+semantics associated to bus transfers, which means that the same
+transfer can be seen as a read operation by a chip and as a write
+operation by another chip. For these reasons, explicit device
+instantiation should always be preferred to auto-detection where
+possible.
Device Deletion
diff --git a/Documentation/ia64/kvm.txt b/Documentation/ia64/kvm.txt
index 84f7cb3d5bec..ffb5c80bec3e 100644
--- a/Documentation/ia64/kvm.txt
+++ b/Documentation/ia64/kvm.txt
@@ -42,7 +42,7 @@ Note: For step 2, please make sure that host page size == TARGET_PAGE_SIZE of qe
hg clone http://xenbits.xensource.com/ext/efi-vfirmware.hg
you can get the firmware's binary in the directory of efi-vfirmware.hg/binaries.
- (3) Rename the firware you owned to Flash.fd, and copy it to /usr/local/share/qemu
+ (3) Rename the firmware you owned to Flash.fd, and copy it to /usr/local/share/qemu
4. Boot up Linux or Windows guests:
4.1 Create or install a image for guest boot. If you have xen experience, it should be easy.
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index f1d639903325..1f779a25c703 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -122,10 +122,8 @@ Code Seq# Include File Comments
'c' 00-7F linux/coda.h conflict!
'c' 80-9F arch/s390/include/asm/chsc.h
'd' 00-FF linux/char/drm/drm/h conflict!
-'d' 00-DF linux/video_decoder.h conflict!
'd' F0-FF linux/digi1.h
'e' all linux/digi1.h conflict!
-'e' 00-1F linux/video_encoder.h conflict!
'e' 00-1F net/irda/irtty.h conflict!
'f' 00-1F linux/ext2_fs.h
'h' 00-7F Charon filesystem
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 7643483bdd6a..6172e4360f60 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -44,6 +44,7 @@ parameter is applicable:
FB The frame buffer device is enabled.
HW Appropriate hardware is enabled.
IA-64 IA-64 architecture is enabled.
+ IMA Integrity measurement architecture is enabled.
IOSCHED More than one I/O scheduler is enabled.
IP_PNP IP DHCP, BOOTP, or RARP is enabled.
ISAPNP ISA PnP code is enabled.
@@ -152,60 +153,6 @@ and is between 256 and 4096 characters. It is defined in the file
1,0: use 1st APIC table
default: 0
- acpi_sleep= [HW,ACPI] Sleep options
- Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig,
- old_ordering, s4_nonvs }
- See Documentation/power/video.txt for information on
- s3_bios and s3_mode.
- s3_beep is for debugging; it makes the PC's speaker beep
- as soon as the kernel's real-mode entry point is called.
- s4_nohwsig prevents ACPI hardware signature from being
- used during resume from hibernation.
- old_ordering causes the ACPI 1.0 ordering of the _PTS
- control method, with respect to putting devices into
- low power states, to be enforced (the ACPI 2.0 ordering
- of _PTS is used by default).
- s4_nonvs prevents the kernel from saving/restoring the
- ACPI NVS memory during hibernation.
-
- acpi_sci= [HW,ACPI] ACPI System Control Interrupt trigger mode
- Format: { level | edge | high | low }
-
- acpi_irq_balance [HW,ACPI]
- ACPI will balance active IRQs
- default in APIC mode
-
- acpi_irq_nobalance [HW,ACPI]
- ACPI will not move active IRQs (default)
- default in PIC mode
-
- acpi_irq_pci= [HW,ACPI] If irq_balance, clear listed IRQs for
- use by PCI
- Format: <irq>,<irq>...
-
- acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA
- Format: <irq>,<irq>...
-
- acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT
-
- acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS
- Format: To spoof as Windows 98: ="Microsoft Windows"
-
- acpi_osi= [HW,ACPI] Modify list of supported OS interface strings
- acpi_osi="string1" # add string1 -- only one string
- acpi_osi="!string2" # remove built-in string2
- acpi_osi= # disable all strings
-
- acpi_serialize [HW,ACPI] force serialization of AML methods
-
- acpi_skip_timer_override [HW,ACPI]
- Recognize and ignore IRQ0/pin2 Interrupt Override.
- For broken nForce2 BIOS resulting in XT-PIC timer.
- acpi_use_timer_override [HW,ACPI]
- Use timer override. For some broken Nvidia NF5 boards
- that require a timer override, but don't have
- HPET
-
acpi_backlight= [HW,ACPI]
acpi_backlight=vendor
acpi_backlight=video
@@ -213,11 +160,6 @@ and is between 256 and 4096 characters. It is defined in the file
(e.g. thinkpad_acpi, sony_acpi, etc.) instead
of the ACPI video.ko driver.
- acpi_display_output= [HW,ACPI]
- acpi_display_output=vendor
- acpi_display_output=video
- See above.
-
acpi.debug_layer= [HW,ACPI,ACPI_DEBUG]
acpi.debug_level= [HW,ACPI,ACPI_DEBUG]
Format: <int>
@@ -246,6 +188,41 @@ and is between 256 and 4096 characters. It is defined in the file
unusable. The "log_buf_len" parameter may be useful
if you need to capture more output.
+ acpi_display_output= [HW,ACPI]
+ acpi_display_output=vendor
+ acpi_display_output=video
+ See above.
+
+ acpi_irq_balance [HW,ACPI]
+ ACPI will balance active IRQs
+ default in APIC mode
+
+ acpi_irq_nobalance [HW,ACPI]
+ ACPI will not move active IRQs (default)
+ default in PIC mode
+
+ acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA
+ Format: <irq>,<irq>...
+
+ acpi_irq_pci= [HW,ACPI] If irq_balance, clear listed IRQs for
+ use by PCI
+ Format: <irq>,<irq>...
+
+ acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT
+
+ acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS
+ Format: To spoof as Windows 98: ="Microsoft Windows"
+
+ acpi_osi= [HW,ACPI] Modify list of supported OS interface strings
+ acpi_osi="string1" # add string1 -- only one string
+ acpi_osi="!string2" # remove built-in string2
+ acpi_osi= # disable all strings
+
+ acpi_pm_good [X86-32,X86-64]
+ Override the pmtimer bug detection: force the kernel
+ to assume that this machine's pmtimer latches its value
+ and always returns good values.
+
acpi.power_nocheck= [HW,ACPI]
Format: 1/0 enable/disable the check of power state.
On some bogus BIOS the _PSC object/_STA object of
@@ -254,26 +231,21 @@ and is between 256 and 4096 characters. It is defined in the file
power state again in power transition.
1 : disable the power state check
- acpi_pm_good [X86-32,X86-64]
- Override the pmtimer bug detection: force the kernel
- to assume that this machine's pmtimer latches its value
- and always returns good values.
-
- agp= [AGP]
- { off | try_unsupported }
- off: disable AGP support
- try_unsupported: try to drive unsupported chipsets
- (may crash computer or cause data corruption)
-
- enable_timer_pin_1 [i386,x86-64]
- Enable PIN 1 of APIC timer
- Can be useful to work around chipset bugs
- (in particular on some ATI chipsets).
- The kernel tries to set a reasonable default.
-
- disable_timer_pin_1 [i386,x86-64]
- Disable PIN 1 of APIC timer
- Can be useful to work around chipset bugs.
+ acpi_enforce_resources= [ACPI]
+ { strict | lax | no }
+ Check for resource conflicts between native drivers
+ and ACPI OperationRegions (SystemIO and SystemMemory
+ only). IO ports and memory declared in ACPI might be
+ used by the ACPI subsystem in arbitrary AML code and
+ can interfere with legacy drivers.
+ strict (default): access to resources claimed by ACPI
+ is denied; legacy drivers trying to access reserved
+ resources will fail to bind to device using them.
+ lax: access to resources claimed by ACPI is allowed;
+ legacy drivers trying to access reserved resources
+ will bind successfully but a warning message is logged.
+ no: ACPI OperationRegions are not marked as reserved,
+ no further checks are performed.
ad1848= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>,<type>
@@ -288,6 +260,12 @@ and is between 256 and 4096 characters. It is defined in the file
Format: <io>,<irq>,<dma>,<mss_io>,<mpu_io>,<mpu_irq>
See also header of sound/oss/aedsp16.c.
+ agp= [AGP]
+ { off | try_unsupported }
+ off: disable AGP support
+ try_unsupported: try to drive unsupported chipsets
+ (may crash computer or cause data corruption)
+
aha152x= [HW,SCSI]
See Documentation/scsi/aha152x.txt.
@@ -415,12 +393,6 @@ and is between 256 and 4096 characters. It is defined in the file
possible to determine what the correct size should be.
This option provides an override for these situations.
- security= [SECURITY] Choose a security module to enable at boot.
- If this boot parameter is not specified, only the first
- security module asking for security registration will be
- loaded. An invalid security module name will be treated
- as if no module has been chosen.
-
capability.disable=
[SECURITY] Disable capabilities. This would normally
be used only if an alternative security model is to be
@@ -492,12 +464,6 @@ and is between 256 and 4096 characters. It is defined in the file
Range: 0 - 8192
Default: 64
- hpet= [X86-32,HPET] option to control HPET usage
- Format: { enable (default) | disable | force }
- disable: disable HPET and use PIT instead
- force: allow force enabled of undocumented chips (ICH4,
- VIA, nVidia)
-
com20020= [HW,NET] ARCnet - COM20020 chipset
Format:
<io>[,<irq>[,<nodeID>[,<backplane>[,<ckp>[,<timeout>]]]]]
@@ -541,23 +507,6 @@ and is between 256 and 4096 characters. It is defined in the file
console=brl,ttyS0
For now, only VisioBraille is supported.
- earlycon= [KNL] Output early console device and options.
- uart[8250],io,<addr>[,options]
- uart[8250],mmio,<addr>[,options]
- Start an early, polled-mode console on the 8250/16550
- UART at the specified I/O port or MMIO address.
- The options are the same as for ttyS, above.
-
- no_console_suspend
- [HW] Never suspend the console
- Disable suspending of consoles during suspend and
- hibernate operations. Once disabled, debugging
- messages can reach various consoles while the rest
- of the system is being put to sleep (ie, while
- debugging driver suspend/resume hooks). This may
- not work reliably with all consoles, but is known
- to work with serial and VGA consoles.
-
coredump_filter=
[KNL] Change the default value for
/proc/<pid>/coredump_filter.
@@ -605,36 +554,22 @@ and is between 256 and 4096 characters. It is defined in the file
debug_objects [KNL] Enable object debugging
+ no_debug_objects
+ [KNL] Disable object debugging
+
debugpat [X86] Enable PAT debugging
decnet.addr= [HW,NET]
Format: <area>[,<node>]
See also Documentation/networking/decnet.txt.
- vt.default_blu= [VT]
- Format: <blue0>,<blue1>,<blue2>,...,<blue15>
- Change the default blue palette of the console.
- This is a 16-member array composed of values
- ranging from 0-255.
-
- vt.default_grn= [VT]
- Format: <green0>,<green1>,<green2>,...,<green15>
- Change the default green palette of the console.
- This is a 16-member array composed of values
- ranging from 0-255.
-
- vt.default_red= [VT]
- Format: <red0>,<red1>,<red2>,...,<red15>
- Change the default red palette of the console.
- This is a 16-member array composed of values
- ranging from 0-255.
-
- vt.default_utf8=
- [VT]
- Format=<0|1>
- Set system-wide default UTF-8 mode for all tty's.
- Default is 1, i.e. UTF-8 mode is enabled for all
- newly opened terminals.
+ default_hugepagesz=
+ [same as hugepagesz=] The size of the default
+ HugeTLB page size. This is the size represented by
+ the legacy /proc/ hugepages APIs, used for SHM, and
+ default size when mounting hugetlbfs filesystems.
+ Defaults to the default architecture's huge page size
+ if not specified.
dhash_entries= [KNL]
Set number of hash buckets for dentry cache.
@@ -647,27 +582,9 @@ and is between 256 and 4096 characters. It is defined in the file
Documentation/serial/digiepca.txt.
disable_mtrr_cleanup [X86]
- enable_mtrr_cleanup [X86]
The kernel tries to adjust MTRR layout from continuous
to discrete, to make X server driver able to add WB
- entry later. This parameter enables/disables that.
-
- mtrr_chunk_size=nn[KMG] [X86]
- used for mtrr cleanup. It is largest continous chunk
- that could hold holes aka. UC entries.
-
- mtrr_gran_size=nn[KMG] [X86]
- Used for mtrr cleanup. It is granularity of mtrr block.
- Default is 1.
- Large value could prevent small alignment from
- using up MTRRs.
-
- mtrr_spare_reg_nr=n [X86]
- Format: <integer>
- Range: 0,7 : spare reg number
- Default : 1
- Used for mtrr cleanup. It is spare mtrr entries number.
- Set to 2 or more if your graphical card needs more.
+ entry later. This parameter disables that.
disable_mtrr_trim [X86, Intel and AMD only]
By default the kernel will trim any uncacheable
@@ -675,12 +592,38 @@ and is between 256 and 4096 characters. It is defined in the file
MTRR settings. This parameter disables that behavior,
possibly causing your machine to run very slowly.
+ disable_timer_pin_1 [i386,x86-64]
+ Disable PIN 1 of APIC timer
+ Can be useful to work around chipset bugs.
+
dmasound= [HW,OSS] Sound subsystem buffers
+ dma_debug=off If the kernel is compiled with DMA_API_DEBUG support,
+ this option disables the debugging code at boot.
+
+ dma_debug_entries=<number>
+ This option allows to tune the number of preallocated
+ entries for DMA-API debugging code. One entry is
+ required per DMA-API allocation. Use this if the
+ DMA-API debugging code disables itself because the
+ architectural default is too low.
+
dscc4.setup= [NET]
dtc3181e= [HW,SCSI]
+ dynamic_printk Enables pr_debug()/dev_dbg() calls if
+ CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled.
+ These can also be switched on/off via
+ <debugfs>/dynamic_printk/modules
+
+ earlycon= [KNL] Output early console device and options.
+ uart[8250],io,<addr>[,options]
+ uart[8250],mmio,<addr>[,options]
+ Start an early, polled-mode console on the 8250/16550
+ UART at the specified I/O port or MMIO address.
+ The options are the same as for ttyS, above.
+
earlyprintk= [X86-32,X86-64,SH,BLACKFIN]
earlyprintk=vga
earlyprintk=serial[,ttySn[,baudrate]]
@@ -722,6 +665,17 @@ and is between 256 and 4096 characters. It is defined in the file
pass this option to capture kernel.
See Documentation/kdump/kdump.txt for details.
+ enable_mtrr_cleanup [X86]
+ The kernel tries to adjust MTRR layout from continuous
+ to discrete, to make X server driver able to add WB
+ entry later. This parameter enables that.
+
+ enable_timer_pin_1 [i386,x86-64]
+ Enable PIN 1 of APIC timer
+ Can be useful to work around chipset bugs
+ (in particular on some ATI chipsets).
+ The kernel tries to set a reasonable default.
+
enforcing [SELINUX] Set initial enforcing status.
Format: {"0" | "1"}
See security/selinux/Kconfig help text.
@@ -809,6 +763,16 @@ and is between 256 and 4096 characters. It is defined in the file
hisax= [HW,ISDN]
See Documentation/isdn/README.HiSax.
+ hlt [BUGS=ARM,SH]
+
+ hpet= [X86-32,HPET] option to control HPET usage
+ Format: { enable (default) | disable | force |
+ verbose }
+ disable: disable HPET and use PIT instead
+ force: allow force enabled of undocumented chips (ICH4,
+ VIA, nVidia)
+ verbose: show contents of HPET registers during setup
+
hugepages= [HW,X86-32,IA-64] HugeTLB pages to allocate at boot.
hugepagesz= [HW,IA-64,PPC,X86-64] The size of the HugeTLB pages.
On x86-64 and powerpc, this option can be specified
@@ -818,18 +782,18 @@ and is between 256 and 4096 characters. It is defined in the file
(when the CPU supports the "pdpe1gb" cpuinfo flag)
Note that 1GB pages can only be allocated at boot time
using hugepages= and not freed afterwards.
- default_hugepagesz=
- [same as hugepagesz=] The size of the default
- HugeTLB page size. This is the size represented by
- the legacy /proc/ hugepages APIs, used for SHM, and
- default size when mounting hugetlbfs filesystems.
- Defaults to the default architecture's huge page size
- if not specified.
-
- hlt [BUGS=ARM,SH]
hvc_iucv= [S390] Number of z/VM IUCV hypervisor console (HVC)
terminal devices. Valid values: 0..8
+ hvc_iucv_allow= [S390] Comma-separated list of z/VM user IDs.
+ If specified, z/VM IUCV HVC accepts connections
+ from listed z/VM user IDs only.
+
+ i2c_bus= [HW] Override the default board specific I2C bus speed
+ or register an additional I2C bus that is not
+ registered from board initialization code.
+ Format:
+ <bus_id>,<clkrate>
i8042.debug [HW] Toggle i8042 debug mode
i8042.direct [HW] Put keyboard port into non-translated mode
@@ -878,6 +842,9 @@ and is between 256 and 4096 characters. It is defined in the file
idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed
See Documentation/ide/ide.txt.
+ ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
+ Claim all unknown PCI IDE storage controllers.
+
idle= [X86]
Format: idle=poll, idle=mwait, idle=halt, idle=nomwait
Poll forces a polling idle loop that can slightly
@@ -893,9 +860,6 @@ and is between 256 and 4096 characters. It is defined in the file
In such case C2/C3 won't be used again.
idle=nomwait: Disable mwait for CPU C-states
- ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem
- Claim all unknown PCI IDE storage controllers.
-
ignore_loglevel [KNL]
Ignore loglevel setting - this will print /all/
kernel messages to the console. Useful for debugging.
@@ -903,6 +867,15 @@ and is between 256 and 4096 characters. It is defined in the file
ihash_entries= [KNL]
Set number of hash buckets for inode cache.
+ ima_audit= [IMA]
+ Format: { "0" | "1" }
+ 0 -- integrity auditing messages. (Default)
+ 1 -- enable informational integrity auditing messages.
+
+ ima_hash= [IMA]
+ Formt: { "sha1" | "md5" }
+ default: "sha1"
+
in2000= [HW,SCSI]
See header of drivers/scsi/in2000.c.
@@ -920,25 +893,6 @@ and is between 256 and 4096 characters. It is defined in the file
inport.irq= [HW] Inport (ATI XL and Microsoft) busmouse driver
Format: <irq>
- inttest= [IA64]
-
- iomem= Disable strict checking of access to MMIO memory
- strict regions from userspace.
- relaxed
-
- iommu= [x86]
- off
- force
- noforce
- biomerge
- panic
- nopanic
- merge
- nomerge
- forcesac
- soft
-
-
intel_iommu= [DMAR] Intel IOMMU driver (DMAR) option
on
Enable intel iommu driver.
@@ -962,6 +916,28 @@ and is between 256 and 4096 characters. It is defined in the file
result in a hardware IOTLB flush operation as opposed
to batching them for performance.
+ inttest= [IA64]
+
+ iomem= Disable strict checking of access to MMIO memory
+ strict regions from userspace.
+ relaxed
+
+ iommu= [x86]
+ off
+ force
+ noforce
+ biomerge
+ panic
+ nopanic
+ merge
+ nomerge
+ forcesac
+ soft
+
+ io7= [HW] IO7 for Marvel based alpha systems
+ See comment before marvel_specify_io7 in
+ arch/alpha/kernel/core_marvel.c.
+
io_delay= [X86-32,X86-64] I/O delay method
0x80
Standard port 0x80 based delay
@@ -972,10 +948,6 @@ and is between 256 and 4096 characters. It is defined in the file
none
No delay
- io7= [HW] IO7 for Marvel based alpha systems
- See comment before marvel_specify_io7 in
- arch/alpha/kernel/core_marvel.c.
-
ip= [IP_PNP]
See Documentation/filesystems/nfsroot.txt.
@@ -986,12 +958,6 @@ and is between 256 and 4096 characters. It is defined in the file
ips= [HW,SCSI] Adaptec / IBM ServeRAID controller
See header of drivers/scsi/ips.c.
- ports= [IP_VS_FTP] IPVS ftp helper module
- Default is 21.
- Up to 8 (IP_VS_APP_MAX_PORTS) ports
- may be specified.
- Format: <port>,<port>....
-
irqfixup [HW]
When an interrupt is not handled search all handlers
for it. Intended to get systems with badly broken
@@ -1032,6 +998,8 @@ and is between 256 and 4096 characters. It is defined in the file
js= [HW,JOY] Analog joystick
See Documentation/input/joystick.txt.
+ keepinitrd [HW,ARM]
+
kernelcore=nn[KMG] [KNL,X86-32,IA-64,PPC,X86-64] This parameter
specifies the amount of memory usable by the kernel
for non-movable allocations. The requested amount is
@@ -1057,21 +1025,6 @@ and is between 256 and 4096 characters. It is defined in the file
higher than default (KMEMTRACE_N_SUBBUFS in code) if
you experience buffer overruns.
- movablecore=nn[KMG] [KNL,X86-32,IA-64,PPC,X86-64] This parameter
- is similar to kernelcore except it specifies the
- amount of memory used for migratable allocations.
- If both kernelcore and movablecore is specified,
- then kernelcore will be at *least* the specified
- value but may be more. If movablecore on its own
- is specified, the administrator must be careful
- that the amount of memory usable for all allocations
- is not too small.
-
- keepinitrd [HW,ARM]
-
- kstack=N [X86-32,X86-64] Print N words from the kernel stack
- in oops dumps.
-
kgdboc= [HW] kgdb over consoles.
Requires a tty driver that supports console polling.
(only serial suported for now)
@@ -1081,6 +1034,9 @@ and is between 256 and 4096 characters. It is defined in the file
Configure the RouterBoard 532 series on-chip
Ethernet adapter MAC address.
+ kstack=N [X86-32,X86-64] Print N words from the kernel stack
+ in oops dumps.
+
l2cr= [PPC]
l3cr= [PPC]
@@ -1226,9 +1182,8 @@ and is between 256 and 4096 characters. It is defined in the file
(machvec) in a generic kernel.
Example: machvec=hpzx1_swiotlb
- max_loop= [LOOP] Maximum number of loopback devices that can
- be mounted
- Format: <1-256>
+ max_addr=nn[KMG] [KNL,BOOT,ia64] All physical memory greater
+ than or equal to this physical address is ignored.
maxcpus= [SMP] Maximum number of processors that an SMP kernel
should make use of. maxcpus=n : n >= 0 limits the
@@ -1236,8 +1191,9 @@ and is between 256 and 4096 characters. It is defined in the file
it is equivalent to "nosmp", which also disables
the IO APIC.
- max_addr=nn[KMG] [KNL,BOOT,ia64] All physical memory greater than
- or equal to this physical address is ignored.
+ max_loop= [LOOP] Maximum number of loopback devices that can
+ be mounted
+ Format: <1-256>
max_luns= [SCSI] Maximum number of LUNs to probe.
Should be between 1 and 2^32-1.
@@ -1364,6 +1320,16 @@ and is between 256 and 4096 characters. It is defined in the file
mousedev.yres= [MOUSE] Vertical screen resolution, used for devices
reporting absolute coordinates, such as tablets
+ movablecore=nn[KMG] [KNL,X86-32,IA-64,PPC,X86-64] This parameter
+ is similar to kernelcore except it specifies the
+ amount of memory used for migratable allocations.
+ If both kernelcore and movablecore is specified,
+ then kernelcore will be at *least* the specified
+ value but may be more. If movablecore on its own
+ is specified, the administrator must be careful
+ that the amount of memory usable for all allocations
+ is not too small.
+
mpu401= [HW,OSS]
Format: <io>,<irq>
@@ -1385,6 +1351,23 @@ and is between 256 and 4096 characters. It is defined in the file
[HW] Make the MicroTouch USB driver use raw coordinates
('y', default) or cooked coordinates ('n')
+ mtrr_chunk_size=nn[KMG] [X86]
+ used for mtrr cleanup. It is largest continous chunk
+ that could hold holes aka. UC entries.
+
+ mtrr_gran_size=nn[KMG] [X86]
+ Used for mtrr cleanup. It is granularity of mtrr block.
+ Default is 1.
+ Large value could prevent small alignment from
+ using up MTRRs.
+
+ mtrr_spare_reg_nr=n [X86]
+ Format: <integer>
+ Range: 0,7 : spare reg number
+ Default : 1
+ Used for mtrr cleanup. It is spare mtrr entries number.
+ Set to 2 or more if your graphical card needs more.
+
n2= [NET] SDL Inc. RISCom/N2 synchronous serial card
NCR_D700= [HW,SCSI]
@@ -1445,11 +1428,13 @@ and is between 256 and 4096 characters. It is defined in the file
0 - turn nmi_watchdog off
1 - use the IO-APIC timer for the NMI watchdog
2 - use the local APIC for the NMI watchdog using
- a performance counter. Note: This will use one performance
- counter and the local APIC's performance vector.
- When panic is specified panic when an NMI watchdog timeout occurs.
- This is useful when you use a panic=... timeout and need the box
- quickly up again.
+ a performance counter. Note: This will use one
+ performance counter and the local APIC's performance
+ vector.
+ When panic is specified, panic when an NMI watchdog
+ timeout occurs.
+ This is useful when you use a panic=... timeout and
+ need the box quickly up again.
Instead of 1 and 2 it is possible to use the following
symbolic names: lapic and ioapic
Example: nmi_watchdog=2 or nmi_watchdog=panic,lapic
@@ -1458,6 +1443,16 @@ and is between 256 and 4096 characters. It is defined in the file
emulation library even if a 387 maths coprocessor
is present.
+ no_console_suspend
+ [HW] Never suspend the console
+ Disable suspending of consoles during suspend and
+ hibernate operations. Once disabled, debugging
+ messages can reach various consoles while the rest
+ of the system is being put to sleep (ie, while
+ debugging driver suspend/resume hooks). This may
+ not work reliably with all consoles, but is known
+ to work with serial and VGA consoles.
+
noaliencache [MM, NUMA, SLAB] Disables the allocation of alien
caches in the slab allocator. Saves per-node memory,
but will impact performance.
@@ -1472,6 +1467,8 @@ and is between 256 and 4096 characters. It is defined in the file
nocache [ARM]
+ noclflush [BUGS=X86] Don't use the CLFLUSH instruction
+
nodelayacct [KNL] Disable per-task delay accounting
nodisconnect [HW,SCSI,M68K] Disables SCSI disconnects.
@@ -1500,9 +1497,9 @@ and is between 256 and 4096 characters. It is defined in the file
register save and restore. The kernel will only save
legacy floating-point registers on task switch.
- noclflush [BUGS=X86] Don't use the CLFLUSH instruction
-
- nohlt [BUGS=ARM,SH]
+ nohlt [BUGS=ARM,SH] Tells the kernel that the sleep(SH) or
+ wfi(ARM) instruction doesn't work correctly and not to
+ use it. This is also useful when using JTAG debugger.
no-hlt [BUGS=X86-32] Tells the kernel that the hlt
instruction doesn't work correctly and not to
@@ -1523,6 +1520,8 @@ and is between 256 and 4096 characters. It is defined in the file
Valid arguments: on, off
Default: on
+ noiotrap [SH] Disables trapped I/O port accesses.
+
noirqdebug [X86-32] Disables the code which attempts to detect and
disable unhandled interrupt sources.
@@ -1542,12 +1541,6 @@ and is between 256 and 4096 characters. It is defined in the file
nolapic_timer [X86-32,APIC] Do not use the local APIC timer.
- nox2apic [X86-64,APIC] Do not enable x2APIC mode.
-
- x2apic_phys [X86-64,APIC] Use x2apic physical mode instead of
- default x2apic cluster mode on platforms
- supporting x2apic.
-
noltlbs [PPC] Do not use large page/tlb entries for kernel
lowmem mapping on PPC40x.
@@ -1558,6 +1551,9 @@ and is between 256 and 4096 characters. It is defined in the file
nomfgpt [X86-32] Disable Multi-Function General Purpose
Timer usage (for AMD Geode machines).
+ norandmaps Don't use address space randomization. Equivalent to
+ echo 0 > /proc/sys/kernel/randomize_va_space
+
noreplace-paravirt [X86-32,PV_OPS] Don't patch paravirt_ops
noreplace-smp [X86-32,SMP] Don't replace SMP instructions
@@ -1582,7 +1578,7 @@ and is between 256 and 4096 characters. It is defined in the file
nosoftlockup [KNL] Disable the soft-lockup detector.
noswapaccount [KNL] Disable accounting of swap in memory resource
- controller. (See Documentation/controllers/memory.txt)
+ controller. (See Documentation/cgroups/memory.txt)
nosync [HW,M68K] Disables sync negotiation for all devices.
@@ -1596,13 +1592,13 @@ and is between 256 and 4096 characters. It is defined in the file
purges which is reported from either PAL_VM_SUMMARY or
SAL PALO.
+ nr_uarts= [SERIAL] maximum number of UARTs to be registered.
+
numa_zonelist_order= [KNL, BOOT] Select zonelist order for NUMA.
one of ['zone', 'node', 'default'] can be specified
This can be set from sysctl after boot.
See Documentation/sysctl/vm.txt for details.
- nr_uarts= [SERIAL] maximum number of UARTs to be registered.
-
ohci1394_dma=early [HW] enable debugging via the ohci1394 driver.
See Documentation/debugging-via-ohci1394.txt for more
info.
@@ -1674,6 +1670,8 @@ and is between 256 and 4096 characters. It is defined in the file
See also Documentation/blockdev/paride.txt.
pci=option[,option...] [PCI] various PCI subsystem options:
+ earlydump [X86] dump PCI config space before the kernel
+ changes anything
off [X86] don't probe for the PCI bus
bios [X86-32] force use of PCI BIOS, don't access
the hardware directly. Use this if your machine
@@ -1773,6 +1771,15 @@ and is between 256 and 4096 characters. It is defined in the file
cbmemsize=nn[KMG] The fixed amount of bus space which is
reserved for the CardBus bridge's memory
window. The default value is 64 megabytes.
+ resource_alignment=
+ Format:
+ [<order of align>@][<domain>:]<bus>:<slot>.<func>[; ...]
+ Specifies alignment and device to reassign
+ aligned memory resources.
+ If <order of align> is not specified,
+ PAGE_SIZE is used as alignment.
+ PCI-PCI bridge can be specified, if resource
+ windows need to be expanded.
pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
Management.
@@ -1831,11 +1838,6 @@ and is between 256 and 4096 characters. It is defined in the file
autoconfiguration.
Ranges are in pairs (memory base and size).
- dynamic_printk Enables pr_debug()/dev_dbg() calls if
- CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled.
- These can also be switched on/off via
- <debugfs>/dynamic_printk/modules
-
print-fatal-signals=
[KNL] debug: print fatal signals
print-fatal-signals=1: print segfault info to
@@ -1845,6 +1847,14 @@ and is between 256 and 4096 characters. It is defined in the file
printk.time= Show timing data prefixed to each printk message line
Format: <bool> (1/Y/y=enable, 0/N/n=disable)
+ processor.max_cstate= [HW,ACPI]
+ Limit processor to maximum C-state
+ max_cstate=9 overrides any DMI blacklist limit.
+
+ processor.nocst [HW,ACPI]
+ Ignore the _CST method to determine C-states,
+ instead using the legacy FADT method
+
profile= [KNL] Enable kernel profiling via /proc/profile
Format: [schedule,]<number>
Param: "schedule" - profile schedule points.
@@ -1854,14 +1864,6 @@ and is between 256 and 4096 characters. It is defined in the file
Requires CONFIG_SCHEDSTATS
Param: "kvm" - profile VM exits.
- processor.max_cstate= [HW,ACPI]
- Limit processor to maximum C-state
- max_cstate=9 overrides any DMI blacklist limit.
-
- processor.nocst [HW,ACPI]
- Ignore the _CST method to determine C-states,
- instead using the legacy FADT method
-
prompt_ramdisk= [RAM] List of RAM disks to prompt for floppy disk
before loading.
See Documentation/blockdev/ramdisk.txt.
@@ -1926,7 +1928,7 @@ and is between 256 and 4096 characters. It is defined in the file
relax_domain_level=
[KNL, SMP] Set scheduler's default relax_domain_level.
- See Documentation/cpusets.txt.
+ See Documentation/cgroups/cpusets.txt.
reserve= [KNL,BUGS] Force the kernel to ignore some iomem area
@@ -2015,7 +2017,13 @@ and is between 256 and 4096 characters. It is defined in the file
allowing boot to proceed. none ignores them, expecting
user space to do the scan.
- selinux [SELINUX] Disable or enable SELinux at boot time.
+ security= [SECURITY] Choose a security module to enable at boot.
+ If this boot parameter is not specified, only the first
+ security module asking for security registration will be
+ loaded. An invalid security module name will be treated
+ as if no module has been chosen.
+
+ selinux= [SELINUX] Disable or enable SELinux at boot time.
Format: { "0" | "1" }
See security/selinux/Kconfig help text.
0 -- disable.
@@ -2024,15 +2032,6 @@ and is between 256 and 4096 characters. It is defined in the file
If enabled at boot time, /selinux/disable can be used
later to disable prior to initial policy load.
- selinux_compat_net =
- [SELINUX] Set initial selinux_compat_net flag value.
- Format: { "0" | "1" }
- 0 -- use new secmark-based packet controls
- 1 -- use legacy packet controls
- Default value is 0 (preferred).
- Value can be changed at runtime via
- /selinux/compat_net.
-
serialnumber [BUGS=X86-32]
shapers= [NET]
@@ -2448,9 +2447,6 @@ and is between 256 and 4096 characters. It is defined in the file
medium is write-protected).
Example: quirks=0419:aaf5:rl,0421:0433:rc
- add_efi_memmap [EFI; x86-32,X86-64] Include EFI memory map in
- kernel's map of available physical RAM.
-
vdso= [X86-32,SH,x86-64]
vdso=2: enable compat VDSO (default with COMPAT_VDSO)
vdso=1: enable VDSO (default)
@@ -2489,6 +2485,31 @@ and is between 256 and 4096 characters. It is defined in the file
vmpoff= [KNL,S390] Perform z/VM CP command after power off.
Format: <command>
+ vt.default_blu= [VT]
+ Format: <blue0>,<blue1>,<blue2>,...,<blue15>
+ Change the default blue palette of the console.
+ This is a 16-member array composed of values
+ ranging from 0-255.
+
+ vt.default_grn= [VT]
+ Format: <green0>,<green1>,<green2>,...,<green15>
+ Change the default green palette of the console.
+ This is a 16-member array composed of values
+ ranging from 0-255.
+
+ vt.default_red= [VT]
+ Format: <red0>,<red1>,<red2>,...,<red15>
+ Change the default red palette of the console.
+ This is a 16-member array composed of values
+ ranging from 0-255.
+
+ vt.default_utf8=
+ [VT]
+ Format=<0|1>
+ Set system-wide default UTF-8 mode for all tty's.
+ Default is 1, i.e. UTF-8 mode is enabled for all
+ newly opened terminals.
+
waveartist= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>
@@ -2501,6 +2522,10 @@ and is between 256 and 4096 characters. It is defined in the file
wdt= [WDT] Watchdog
See Documentation/watchdog/wdt.txt.
+ x2apic_phys [X86-64,APIC] Use x2apic physical mode instead of
+ default x2apic cluster mode on platforms
+ supporting x2apic.
+
xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks.
xd_geo= See header of drivers/block/xd.c.
@@ -2508,9 +2533,6 @@ and is between 256 and 4096 characters. It is defined in the file
Format:
<irq>,<irq_mask>,<io>,<full_duplex>,<do_sound>,<lockup_hack>[,<irq2>[,<irq3>[,<irq4>]]]
- norandmaps Don't use address space randomization. Equivalent to
- echo 0 > /proc/sys/kernel/randomize_va_space
-
______________________________________________________________________
TODO:
diff --git a/Documentation/laptops/acer-wmi.txt b/Documentation/laptops/acer-wmi.txt
index 2b3a6b5260bf..5ee2a02b3b40 100644
--- a/Documentation/laptops/acer-wmi.txt
+++ b/Documentation/laptops/acer-wmi.txt
@@ -1,9 +1,9 @@
Acer Laptop WMI Extras Driver
http://code.google.com/p/aceracpi
-Version 0.2
-18th August 2008
+Version 0.3
+4th April 2009
-Copyright 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
+Copyright 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk>
acer-wmi is a driver to allow you to control various parts of your Acer laptop
hardware under Linux which are exposed via ACPI-WMI.
@@ -36,6 +36,10 @@ not possible in kernel space from a 64 bit OS.
Supported Hardware
******************
+NOTE: The Acer Aspire One is not supported hardware. It cannot work with
+acer-wmi until Acer fix their ACPI-WMI implementation on them, so has been
+blacklisted until that happens.
+
Please see the website for the current list of known working hardare:
http://code.google.com/p/aceracpi/wiki/SupportedHardware
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 41bc99fa1884..3d7650768bb5 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -20,7 +20,8 @@ moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel
kernel 2.6.29 and release 0.22.
The driver is named "thinkpad-acpi". In some places, like module
-names, "thinkpad_acpi" is used because of userspace issues.
+names and log messages, "thinkpad_acpi" is used because of userspace
+issues.
"tpacpi" is used as a shorthand where "thinkpad-acpi" would be too
long due to length limitations on some Linux kernel versions.
@@ -37,7 +38,7 @@ detailed description):
- ThinkLight on and off
- limited docking and undocking
- UltraBay eject
- - CMOS control
+ - CMOS/UCMS control
- LED control
- ACPI sounds
- temperature sensors
@@ -46,6 +47,7 @@ detailed description):
- Volume control
- Fan control and monitoring: fan speed, fan enable/disable
- WAN enable and disable
+ - UWB enable and disable
A compatibility table by model and feature is maintained on the web
site, http://ibm-acpi.sf.net/. I appreciate any success or failure
@@ -53,7 +55,7 @@ reports, especially if they add to or correct the compatibility table.
Please include the following information in your report:
- ThinkPad model name
- - a copy of your DSDT, from /proc/acpi/dsdt
+ - a copy of your ACPI tables, using the "acpidump" utility
- a copy of the output of dmidecode, with serial numbers
and UUIDs masked off
- which driver features work and which don't
@@ -66,17 +68,18 @@ Installation
------------
If you are compiling this driver as included in the Linux kernel
-sources, simply enable the CONFIG_THINKPAD_ACPI option, and optionally
-enable the CONFIG_THINKPAD_ACPI_BAY option if you want the
-thinkpad-specific bay functionality.
+sources, look for the CONFIG_THINKPAD_ACPI Kconfig option.
+It is located on the menu path: "Device Drivers" -> "X86 Platform
+Specific Device Drivers" -> "ThinkPad ACPI Laptop Extras".
+
Features
--------
The driver exports two different interfaces to userspace, which can be
used to access the features it provides. One is a legacy procfs-based
-interface, which will be removed at some time in the distant future.
-The other is a new sysfs-based interface which is not complete yet.
+interface, which will be removed at some time in the future. The other
+is a new sysfs-based interface which is not complete yet.
The procfs interface creates the /proc/acpi/ibm directory. There is a
file under that directory for each feature it supports. The procfs
@@ -111,15 +114,17 @@ The version of thinkpad-acpi's sysfs interface is exported by the driver
as a driver attribute (see below).
Sysfs driver attributes are on the driver's sysfs attribute space,
-for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and
+for 2.6.23+ this is /sys/bus/platform/drivers/thinkpad_acpi/ and
/sys/bus/platform/drivers/thinkpad_hwmon/
Sysfs device attributes are on the thinkpad_acpi device sysfs attribute
-space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/.
+space, for 2.6.23+ this is /sys/devices/platform/thinkpad_acpi/.
Sysfs device attributes for the sensors and fan are on the
thinkpad_hwmon device's sysfs attribute space, but you should locate it
-looking for a hwmon device with the name attribute of "thinkpad".
+looking for a hwmon device with the name attribute of "thinkpad", or
+better yet, through libsensors.
+
Driver version
--------------
@@ -129,6 +134,7 @@ sysfs driver attribute: version
The driver name and version. No commands can be written to this file.
+
Sysfs interface version
-----------------------
@@ -160,6 +166,7 @@ expect that an attribute might not be there, and deal with it properly
(an attribute not being there *is* a valid way to make it clear that a
feature is not available in sysfs).
+
Hot keys
--------
@@ -172,17 +179,14 @@ system. Enabling the hotkey functionality of thinkpad-acpi signals the
firmware that such a driver is present, and modifies how the ThinkPad
firmware will behave in many situations.
-The driver enables the hot key feature automatically when loaded. The
-feature can later be disabled and enabled back at runtime. The driver
-will also restore the hot key feature to its previous state and mask
-when it is unloaded.
+The driver enables the HKEY ("hot key") event reporting automatically
+when loaded, and disables it when it is removed.
-When the hotkey feature is enabled and the hot key mask is set (see
-below), the driver will report HKEY events in the following format:
+The driver will report HKEY events in the following format:
ibm/hotkey HKEY 00000080 0000xxxx
-Some of these events refer to hot key presses, but not all.
+Some of these events refer to hot key presses, but not all of them.
The driver will generate events over the input layer for hot keys and
radio switches, and over the ACPI netlink layer for other events. The
@@ -214,13 +218,17 @@ procfs notes:
The following commands can be written to the /proc/acpi/ibm/hotkey file:
- echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
- echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys
echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
... any other 8-hex-digit mask ...
echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
+The following commands have been deprecated and will cause the kernel
+to log a warning:
+
+ echo enable > /proc/acpi/ibm/hotkey -- does nothing
+ echo disable > /proc/acpi/ibm/hotkey -- returns an error
+
The procfs interface does not support NVRAM polling control. So as to
maintain maximum bug-to-bug compatibility, it does not report any masks,
nor does it allow one to manipulate the hot key mask when the firmware
@@ -229,12 +237,9 @@ does not support masks at all, even if NVRAM polling is in use.
sysfs notes:
hotkey_bios_enabled:
- Returns the status of the hot keys feature when
- thinkpad-acpi was loaded. Upon module unload, the hot
- key feature status will be restored to this value.
+ DEPRECATED, WILL BE REMOVED SOON.
- 0: hot keys were disabled
- 1: hot keys were enabled (unusual)
+ Returns 0.
hotkey_bios_mask:
Returns the hot keys mask when thinkpad-acpi was loaded.
@@ -242,13 +247,10 @@ sysfs notes:
to this value.
hotkey_enable:
- Enables/disables the hot keys feature in the ACPI
- firmware, and reports current status of the hot keys
- feature. Has no effect on the NVRAM hot key polling
- functionality.
+ DEPRECATED, WILL BE REMOVED SOON.
- 0: disables the hot keys feature / feature disabled
- 1: enables the hot keys feature / feature enabled
+ 0: returns -EPERM
+ 1: does nothing
hotkey_mask:
bit mask to enable driver-handling (and depending on
@@ -618,6 +620,7 @@ For Lenovo models *with* ACPI backlight control:
and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process
these keys on userspace somehow (e.g. by calling xbacklight).
+
Bluetooth
---------
@@ -628,6 +631,9 @@ sysfs rfkill class: switch "tpacpi_bluetooth_sw"
This feature shows the presence and current state of a ThinkPad
Bluetooth device in the internal ThinkPad CDC slot.
+If the ThinkPad supports it, the Bluetooth state is stored in NVRAM,
+so it is kept across reboots and power-off.
+
Procfs notes:
If Bluetooth is installed, the following commands can be used:
@@ -652,6 +658,7 @@ Sysfs notes:
rfkill controller switch "tpacpi_bluetooth_sw": refer to
Documentation/rfkill.txt for details.
+
Video output control -- /proc/acpi/ibm/video
--------------------------------------------
@@ -693,11 +700,8 @@ Fn-F7 from working. This also disables the video output switching
features of this driver, as it uses the same ACPI methods as
Fn-F7. Video switching on the console should still work.
-UPDATE: There's now a patch for the X.org Radeon driver which
-addresses this issue. Some people are reporting success with the patch
-while others are still having problems. For more information:
+UPDATE: refer to https://bugs.freedesktop.org/show_bug.cgi?id=2000
-https://bugs.freedesktop.org/show_bug.cgi?id=2000
ThinkLight control
------------------
@@ -720,10 +724,11 @@ The ThinkLight sysfs interface is documented by the LED class
documentation, in Documentation/leds-class.txt. The ThinkLight LED name
is "tpacpi::thinklight".
-Due to limitations in the sysfs LED class, if the status of the thinklight
+Due to limitations in the sysfs LED class, if the status of the ThinkLight
cannot be read or if it is unknown, thinkpad-acpi will report it as "off".
It is impossible to know if the status returned through sysfs is valid.
+
Docking / undocking -- /proc/acpi/ibm/dock
------------------------------------------
@@ -784,6 +789,7 @@ the only docking stations currently supported are the X-series
UltraBase docks and "dumb" port replicators like the Mini Dock (the
latter don't need any ACPI support, actually).
+
UltraBay eject -- /proc/acpi/ibm/bay
------------------------------------
@@ -847,8 +853,9 @@ supported. Use "eject2" instead of "eject" for the second bay.
Note: the UltraBay eject support on the 600e/x, A22p and A3x is
EXPERIMENTAL and may not work as expected. USE WITH CAUTION!
-CMOS control
-------------
+
+CMOS/UCMS control
+-----------------
procfs: /proc/acpi/ibm/cmos
sysfs device attribute: cmos_command
@@ -882,6 +889,7 @@ The cmos command interface is prone to firmware split-brain problems, as
in newer ThinkPads it is just a compatibility layer. Do not use it, it is
exported just as a debug tool.
+
LED control
-----------
@@ -893,6 +901,17 @@ some older ThinkPad models, it is possible to query the status of the
LED indicators as well. Newer ThinkPads cannot query the real status
of the LED indicators.
+Because misuse of the LEDs could induce an unaware user to perform
+dangerous actions (like undocking or ejecting a bay device while the
+buses are still active), or mask an important alarm (such as a nearly
+empty battery, or a broken battery), access to most LEDs is
+restricted.
+
+Unrestricted access to all LEDs requires that thinkpad-acpi be
+compiled with the CONFIG_THINKPAD_ACPI_UNSAFE_LEDS option enabled.
+Distributions must never enable this option. Individual users that
+are aware of the consequences are welcome to enabling it.
+
procfs notes:
The available commands are:
@@ -939,6 +958,7 @@ ThinkPad indicator LED should blink in hardware accelerated mode, use the
"timer" trigger, and leave the delay_on and delay_off parameters set to
zero (to request hardware acceleration autodetection).
+
ACPI sounds -- /proc/acpi/ibm/beep
----------------------------------
@@ -968,6 +988,7 @@ X40:
16 - one medium-pitched beep repeating constantly, stop with 17
17 - stop 16
+
Temperature sensors
-------------------
@@ -1115,6 +1136,7 @@ registers contain the current battery capacity, etc. If you experiment
with this, do send me your results (including some complete dumps with
a description of the conditions when they were taken.)
+
LCD brightness control
----------------------
@@ -1124,10 +1146,9 @@ sysfs backlight device "thinkpad_screen"
This feature allows software control of the LCD brightness on ThinkPad
models which don't have a hardware brightness slider.
-It has some limitations: the LCD backlight cannot be actually turned on or
-off by this interface, and in many ThinkPad models, the "dim while on
-battery" functionality will be enabled by the BIOS when this interface is
-used, and cannot be controlled.
+It has some limitations: the LCD backlight cannot be actually turned
+on or off by this interface, it just controls the backlight brightness
+level.
On IBM (and some of the earlier Lenovo) ThinkPads, the backlight control
has eight brightness levels, ranging from 0 to 7. Some of the levels
@@ -1136,10 +1157,15 @@ display backlight brightness control methods have 16 levels, ranging
from 0 to 15.
There are two interfaces to the firmware for direct brightness control,
-EC and CMOS. To select which one should be used, use the
+EC and UCMS (or CMOS). To select which one should be used, use the
brightness_mode module parameter: brightness_mode=1 selects EC mode,
-brightness_mode=2 selects CMOS mode, brightness_mode=3 selects both EC
-and CMOS. The driver tries to auto-detect which interface to use.
+brightness_mode=2 selects UCMS mode, brightness_mode=3 selects EC
+mode with NVRAM backing (so that brightness changes are remembered
+across shutdown/reboot).
+
+The driver tries to select which interface to use from a table of
+defaults for each ThinkPad model. If it makes a wrong choice, please
+report this as a bug, so that we can fix it.
When display backlight brightness controls are available through the
standard ACPI interface, it is best to use it instead of this direct
@@ -1201,6 +1227,7 @@ WARNING:
and maybe reduce the life of the backlight lamps by needlessly kicking
its level up and down at every change.
+
Volume control -- /proc/acpi/ibm/volume
---------------------------------------
@@ -1217,6 +1244,11 @@ distinct. The unmute the volume after the mute command, use either the
up or down command (the level command will not unmute the volume).
The current volume level and mute state is shown in the file.
+The ALSA mixer interface to this feature is still missing, but patches
+to add it exist. That problem should be addressed in the not so
+distant future.
+
+
Fan control and monitoring: fan speed, fan enable/disable
---------------------------------------------------------
@@ -1383,8 +1415,11 @@ procfs: /proc/acpi/ibm/wan
sysfs device attribute: wwan_enable (deprecated)
sysfs rfkill class: switch "tpacpi_wwan_sw"
-This feature shows the presence and current state of a W-WAN (Sierra
-Wireless EV-DO) device.
+This feature shows the presence and current state of the built-in
+Wireless WAN device.
+
+If the ThinkPad supports it, the WWAN state is stored in NVRAM,
+so it is kept across reboots and power-off.
It was tested on a Lenovo ThinkPad X60. It should probably work on other
ThinkPad models which come with this module installed.
@@ -1413,6 +1448,7 @@ Sysfs notes:
rfkill controller switch "tpacpi_wwan_sw": refer to
Documentation/rfkill.txt for details.
+
EXPERIMENTAL: UWB
-----------------
@@ -1431,6 +1467,7 @@ Sysfs notes:
rfkill controller switch "tpacpi_uwb_sw": refer to
Documentation/rfkill.txt for details.
+
Multiple Commands, Module Parameters
------------------------------------
@@ -1445,6 +1482,7 @@ for example:
modprobe thinkpad_acpi hotkey=enable,0xffff video=auto_disable
+
Enabling debugging output
-------------------------
@@ -1457,8 +1495,15 @@ will enable all debugging output classes. It takes a bitmask, so
to enable more than one output class, just add their values.
Debug bitmask Description
+ 0x8000 Disclose PID of userspace programs
+ accessing some functions of the driver
0x0001 Initialization and probing
0x0002 Removal
+ 0x0004 RF Transmitter control (RFKILL)
+ (bluetooth, WWAN, UWB...)
+ 0x0008 HKEY event interface, hotkeys
+ 0x0010 Fan control
+ 0x0020 Backlight brightness
There is also a kernel build option to enable more debugging
information, which may be necessary to debug driver problems.
@@ -1467,6 +1512,7 @@ The level of debugging information output by the driver can be changed
at runtime through sysfs, using the driver attribute debug_level. The
attribute takes the same bitmask as the debug module parameter above.
+
Force loading of module
-----------------------
@@ -1505,3 +1551,7 @@ Sysfs interface changelog:
0x020200: Add poll()/select() support to the following attributes:
hotkey_radio_sw, wakeup_hotunplug_complete, wakeup_reason
+
+0x020300: hotkey enable/disable support removed, attributes
+ hotkey_bios_enabled and hotkey_enable deprecated and
+ marked for removal.
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c
index f2dbbf3bdeab..d36fcc0f2715 100644
--- a/Documentation/lguest/lguest.c
+++ b/Documentation/lguest/lguest.c
@@ -1630,6 +1630,13 @@ static bool service_io(struct device *dev)
}
}
+ /* OK, so we noted that it was pretty poor to use an fdatasync as a
+ * barrier. But Christoph Hellwig points out that we need a sync
+ * *afterwards* as well: "Barriers specify no reordering to the front
+ * or the back." And Jens Axboe confirmed it, so here we are: */
+ if (out->type & VIRTIO_BLK_T_BARRIER)
+ fdatasync(vblk->fd);
+
/* We can't trigger an IRQ, because we're not the Launcher. It does
* that when we tell it we're done. */
add_used(dev->vq, head, wlen);
diff --git a/Documentation/md.txt b/Documentation/md.txt
index 1da9d1b1793f..4edd39ec7db9 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -164,15 +164,19 @@ All md devices contain:
raid_disks
a text file with a simple number indicating the number of devices
in a fully functional array. If this is not yet known, the file
- will be empty. If an array is being resized (not currently
- possible) this will contain the larger of the old and new sizes.
- Some raid level (RAID1) allow this value to be set while the
- array is active. This will reconfigure the array. Otherwise
- it can only be set while assembling an array.
+ will be empty. If an array is being resized this will contain
+ the new number of devices.
+ Some raid levels allow this value to be set while the array is
+ active. This will reconfigure the array. Otherwise it can only
+ be set while assembling an array.
+ A change to this attribute will not be permitted if it would
+ reduce the size of the array. To reduce the number of drives
+ in an e.g. raid5, the array size must first be reduced by
+ setting the 'array_size' attribute.
chunk_size
- This is the size if bytes for 'chunks' and is only relevant to
- raid levels that involve striping (1,4,5,6,10). The address space
+ This is the size in bytes for 'chunks' and is only relevant to
+ raid levels that involve striping (0,4,5,6,10). The address space
of the array is conceptually divided into chunks and consecutive
chunks are striped onto neighbouring devices.
The size should be at least PAGE_SIZE (4k) and should be a power
@@ -183,6 +187,20 @@ All md devices contain:
simply a number that is interpretted differently by different
levels. It can be written while assembling an array.
+ array_size
+ This can be used to artificially constrain the available space in
+ the array to be less than is actually available on the combined
+ devices. Writing a number (in Kilobytes) which is less than
+ the available size will set the size. Any reconfiguration of the
+ array (e.g. adding devices) will not cause the size to change.
+ Writing the word 'default' will cause the effective size of the
+ array to be whatever size is actually available based on
+ 'level', 'chunk_size' and 'component_size'.
+
+ This can be used to reduce the size of the array before reducing
+ the number of devices in a raid4/5/6, or to support external
+ metadata formats which mandate such clipping.
+
reshape_position
This is either "none" or a sector number within the devices of
the array where "reshape" is up to. If this is set, the three
@@ -207,6 +225,11 @@ All md devices contain:
about the array. It can be 0.90 (traditional format), 1.0, 1.1,
1.2 (newer format in varying locations) or "none" indicating that
the kernel isn't managing metadata at all.
+ Alternately it can be "external:" followed by a string which
+ is set by user-space. This indicates that metadata is managed
+ by a user-space program. Any device failure or other event that
+ requires a metadata update will cause array activity to be
+ suspended until the event is acknowledged.
resync_start
The point at which resync should start. If no resync is needed,
diff --git a/Documentation/misc-devices/isl29003 b/Documentation/misc-devices/isl29003
new file mode 100644
index 000000000000..c4ff5f38e010
--- /dev/null
+++ b/Documentation/misc-devices/isl29003
@@ -0,0 +1,62 @@
+Kernel driver isl29003
+=====================
+
+Supported chips:
+* Intersil ISL29003
+Prefix: 'isl29003'
+Addresses scanned: none
+Datasheet:
+http://www.intersil.com/data/fn/fn7464.pdf
+
+Author: Daniel Mack <daniel@caiaq.de>
+
+
+Description
+-----------
+The ISL29003 is an integrated light sensor with a 16-bit integrating type
+ADC, I2C user programmable lux range select for optimized counts/lux, and
+I2C multi-function control and monitoring capabilities. The internal ADC
+provides 16-bit resolution while rejecting 50Hz and 60Hz flicker caused by
+artificial light sources.
+
+The driver allows to set the lux range, the bit resolution, the operational
+mode (see below) and the power state of device and can read the current lux
+value, of course.
+
+
+Detection
+---------
+
+The ISL29003 does not have an ID register which could be used to identify
+it, so the detection routine will just try to read from the configured I2C
+addess and consider the device to be present as soon as it ACKs the
+transfer.
+
+
+Sysfs entries
+-------------
+
+range:
+ 0: 0 lux to 1000 lux (default)
+ 1: 0 lux to 4000 lux
+ 2: 0 lux to 16,000 lux
+ 3: 0 lux to 64,000 lux
+
+resolution:
+ 0: 2^16 cycles (default)
+ 1: 2^12 cycles
+ 2: 2^8 cycles
+ 3: 2^4 cycles
+
+mode:
+ 0: diode1's current (unsigned 16bit) (default)
+ 1: diode1's current (unsigned 16bit)
+ 2: difference between diodes (l1 - l2, signed 15bit)
+
+power_state:
+ 0: device is disabled (default)
+ 1: device is enabled
+
+lux (read only):
+ returns the value from the last sensor reading
+
diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt
index 7a3bb1abb830..b132e4a3cf0f 100644
--- a/Documentation/networking/dccp.txt
+++ b/Documentation/networking/dccp.txt
@@ -141,7 +141,8 @@ rx_ccid = 2
Default CCID for the receiver-sender half-connection; see tx_ccid.
seq_window = 100
- The initial sequence window (sec. 7.5.2).
+ The initial sequence window (sec. 7.5.2) of the sender. This influences
+ the local ackno validity and the remote seqno validity windows (7.5.1).
tx_qlen = 5
The size of the transmit buffer in packets. A value of 0 corresponds
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index c7712787933c..ec5de02f543f 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -2,7 +2,7 @@
ip_forward - BOOLEAN
0 - disabled (default)
- not 0 - enabled
+ not 0 - enabled
Forward Packets between interfaces.
@@ -36,49 +36,49 @@ rt_cache_rebuild_count - INTEGER
IP Fragmentation:
ipfrag_high_thresh - INTEGER
- Maximum memory used to reassemble IP fragments. When
+ Maximum memory used to reassemble IP fragments. When
ipfrag_high_thresh bytes of memory is allocated for this purpose,
the fragment handler will toss packets until ipfrag_low_thresh
is reached.
-
+
ipfrag_low_thresh - INTEGER
- See ipfrag_high_thresh
+ See ipfrag_high_thresh
ipfrag_time - INTEGER
- Time in seconds to keep an IP fragment in memory.
+ Time in seconds to keep an IP fragment in memory.
ipfrag_secret_interval - INTEGER
- Regeneration interval (in seconds) of the hash secret (or lifetime
+ Regeneration interval (in seconds) of the hash secret (or lifetime
for the hash secret) for IP fragments.
Default: 600
ipfrag_max_dist - INTEGER
- ipfrag_max_dist is a non-negative integer value which defines the
- maximum "disorder" which is allowed among fragments which share a
- common IP source address. Note that reordering of packets is
- not unusual, but if a large number of fragments arrive from a source
- IP address while a particular fragment queue remains incomplete, it
- probably indicates that one or more fragments belonging to that queue
- have been lost. When ipfrag_max_dist is positive, an additional check
- is done on fragments before they are added to a reassembly queue - if
- ipfrag_max_dist (or more) fragments have arrived from a particular IP
- address between additions to any IP fragment queue using that source
- address, it's presumed that one or more fragments in the queue are
- lost. The existing fragment queue will be dropped, and a new one
+ ipfrag_max_dist is a non-negative integer value which defines the
+ maximum "disorder" which is allowed among fragments which share a
+ common IP source address. Note that reordering of packets is
+ not unusual, but if a large number of fragments arrive from a source
+ IP address while a particular fragment queue remains incomplete, it
+ probably indicates that one or more fragments belonging to that queue
+ have been lost. When ipfrag_max_dist is positive, an additional check
+ is done on fragments before they are added to a reassembly queue - if
+ ipfrag_max_dist (or more) fragments have arrived from a particular IP
+ address between additions to any IP fragment queue using that source
+ address, it's presumed that one or more fragments in the queue are
+ lost. The existing fragment queue will be dropped, and a new one
started. An ipfrag_max_dist value of zero disables this check.
Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
result in unnecessarily dropping fragment queues when normal
- reordering of packets occurs, which could lead to poor application
- performance. Using a very large value, e.g. 50000, increases the
- likelihood of incorrectly reassembling IP fragments that originate
+ reordering of packets occurs, which could lead to poor application
+ performance. Using a very large value, e.g. 50000, increases the
+ likelihood of incorrectly reassembling IP fragments that originate
from different IP datagrams, which could result in data corruption.
Default: 64
INET peer storage:
inet_peer_threshold - INTEGER
- The approximate size of the storage. Starting from this threshold
+ The approximate size of the storage. Starting from this threshold
entries will be thrown aggressively. This threshold also determines
entries' time-to-live and time intervals between garbage collection
passes. More entries, less time-to-live, less GC interval.
@@ -105,7 +105,7 @@ inet_peer_gc_maxtime - INTEGER
in effect under low (or absent) memory pressure on the pool.
Measured in seconds.
-TCP variables:
+TCP variables:
somaxconn - INTEGER
Limit of socket listen() backlog, known in userspace as SOMAXCONN.
@@ -310,7 +310,7 @@ tcp_orphan_retries - INTEGER
tcp_reordering - INTEGER
Maximal reordering of packets in a TCP stream.
- Default: 3
+ Default: 3
tcp_retrans_collapse - BOOLEAN
Bug-to-bug compatibility with some broken printers.
@@ -521,7 +521,7 @@ IP Variables:
ip_local_port_range - 2 INTEGERS
Defines the local port range that is used by TCP and UDP to
- choose the local port. The first number is the first, the
+ choose the local port. The first number is the first, the
second the last local port number. Default value depends on
amount of memory available on the system:
> 128Mb 32768-61000
@@ -594,12 +594,12 @@ icmp_errors_use_inbound_ifaddr - BOOLEAN
If zero, icmp error messages are sent with the primary address of
the exiting interface.
-
+
If non-zero, the message will be sent with the primary address of
the interface that received the packet that caused the icmp error.
This is the behaviour network many administrators will expect from
a router. And it can make debugging complicated network layouts
- much easier.
+ much easier.
Note that if no primary address exists for the interface selected,
then the primary address of the first non-loopback interface that
@@ -611,7 +611,7 @@ igmp_max_memberships - INTEGER
Change the maximum number of multicast groups we can subscribe to.
Default: 20
-conf/interface/* changes special settings per interface (where "interface" is
+conf/interface/* changes special settings per interface (where "interface" is
the name of your network interface)
conf/all/* is special, changes the settings for all interfaces
@@ -625,11 +625,11 @@ log_martians - BOOLEAN
accept_redirects - BOOLEAN
Accept ICMP redirect messages.
accept_redirects for the interface will be enabled if:
- - both conf/{all,interface}/accept_redirects are TRUE in the case forwarding
- for the interface is enabled
+ - both conf/{all,interface}/accept_redirects are TRUE in the case
+ forwarding for the interface is enabled
or
- - at least one of conf/{all,interface}/accept_redirects is TRUE in the case
- forwarding for the interface is disabled
+ - at least one of conf/{all,interface}/accept_redirects is TRUE in the
+ case forwarding for the interface is disabled
accept_redirects for the interface will be disabled otherwise
default TRUE (host)
FALSE (router)
@@ -640,8 +640,8 @@ forwarding - BOOLEAN
mc_forwarding - BOOLEAN
Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
and a multicast routing daemon is required.
- conf/all/mc_forwarding must also be set to TRUE to enable multicast routing
- for the interface
+ conf/all/mc_forwarding must also be set to TRUE to enable multicast
+ routing for the interface
medium_id - INTEGER
Integer value used to differentiate the devices by the medium they
@@ -649,7 +649,7 @@ medium_id - INTEGER
the broadcast packets are received only on one of them.
The default value 0 means that the device is the only interface
to its medium, value of -1 means that medium is not known.
-
+
Currently, it is used to change the proxy_arp behavior:
the proxy_arp feature is enabled for packets forwarded between
two devices attached to different media.
@@ -699,16 +699,22 @@ accept_source_route - BOOLEAN
default TRUE (router)
FALSE (host)
-rp_filter - BOOLEAN
- 1 - do source validation by reversed path, as specified in RFC1812
- Recommended option for single homed hosts and stub network
- routers. Could cause troubles for complicated (not loop free)
- networks running a slow unreliable protocol (sort of RIP),
- or using static routes.
-
+rp_filter - INTEGER
0 - No source validation.
-
- conf/all/rp_filter must also be set to TRUE to do source validation
+ 1 - Strict mode as defined in RFC3704 Strict Reverse Path
+ Each incoming packet is tested against the FIB and if the interface
+ is not the best reverse path the packet check will fail.
+ By default failed packets are discarded.
+ 2 - Loose mode as defined in RFC3704 Loose Reverse Path
+ Each incoming packet's source address is also tested against the FIB
+ and if the source address is not reachable via any interface
+ the packet check will fail.
+
+ Current recommended practice in RFC3704 is to enable strict mode
+ to prevent IP spoofing from DDos attacks. If using asymmetric routing
+ or other complicated routing, then loose mode is recommended.
+
+ conf/all/rp_filter must also be set to non-zero to do source validation
on the interface
Default value is 0. Note that some distributions enable it
@@ -782,6 +788,12 @@ arp_ignore - INTEGER
The max value from conf/{all,interface}/arp_ignore is used
when ARP request is received on the {interface}
+arp_notify - BOOLEAN
+ Define mode for notification of address and device changes.
+ 0 - (default): do nothing
+ 1 - Generate gratuitous arp replies when device is brought up
+ or hardware address changes.
+
arp_accept - BOOLEAN
Define behavior when gratuitous arp replies are received:
0 - drop gratuitous arp frames
@@ -823,7 +835,7 @@ apply to IPv6 [XXX?].
bindv6only - BOOLEAN
Default value for IPV6_V6ONLY socket option,
- which restricts use of the IPv6 socket to IPv6 communication
+ which restricts use of the IPv6 socket to IPv6 communication
only.
TRUE: disable IPv4-mapped address feature
FALSE: enable IPv4-mapped address feature
@@ -833,19 +845,19 @@ bindv6only - BOOLEAN
IPv6 Fragmentation:
ip6frag_high_thresh - INTEGER
- Maximum memory used to reassemble IPv6 fragments. When
+ Maximum memory used to reassemble IPv6 fragments. When
ip6frag_high_thresh bytes of memory is allocated for this purpose,
the fragment handler will toss packets until ip6frag_low_thresh
is reached.
-
+
ip6frag_low_thresh - INTEGER
- See ip6frag_high_thresh
+ See ip6frag_high_thresh
ip6frag_time - INTEGER
Time in seconds to keep an IPv6 fragment in memory.
ip6frag_secret_interval - INTEGER
- Regeneration interval (in seconds) of the hash secret (or lifetime
+ Regeneration interval (in seconds) of the hash secret (or lifetime
for the hash secret) for IPv6 fragments.
Default: 600
@@ -854,17 +866,17 @@ conf/default/*:
conf/all/*:
- Change all the interface-specific settings.
+ Change all the interface-specific settings.
[XXX: Other special features than forwarding?]
conf/all/forwarding - BOOLEAN
- Enable global IPv6 forwarding between all interfaces.
+ Enable global IPv6 forwarding between all interfaces.
- IPv4 and IPv6 work differently here; e.g. netfilter must be used
+ IPv4 and IPv6 work differently here; e.g. netfilter must be used
to control which interfaces may forward packets and which not.
- This also sets all interfaces' Host/Router setting
+ This also sets all interfaces' Host/Router setting
'forwarding' to the specified value. See below for details.
This referred to as global forwarding.
@@ -875,12 +887,12 @@ proxy_ndp - BOOLEAN
conf/interface/*:
Change special settings per interface.
- The functional behaviour for certain settings is different
+ The functional behaviour for certain settings is different
depending on whether local forwarding is enabled or not.
accept_ra - BOOLEAN
Accept Router Advertisements; autoconfigure using them.
-
+
Functional default: enabled if local forwarding is disabled.
disabled if local forwarding is enabled.
@@ -926,7 +938,7 @@ accept_source_route - INTEGER
Default: 0
autoconf - BOOLEAN
- Autoconfigure addresses using Prefix Information in Router
+ Autoconfigure addresses using Prefix Information in Router
Advertisements.
Functional default: enabled if accept_ra_pinfo is enabled.
@@ -935,11 +947,11 @@ autoconf - BOOLEAN
dad_transmits - INTEGER
The amount of Duplicate Address Detection probes to send.
Default: 1
-
+
forwarding - BOOLEAN
- Configure interface-specific Host/Router behaviour.
+ Configure interface-specific Host/Router behaviour.
- Note: It is recommended to have the same setting on all
+ Note: It is recommended to have the same setting on all
interfaces; mixed router/host scenarios are rather uncommon.
FALSE:
@@ -948,13 +960,13 @@ forwarding - BOOLEAN
1. IsRouter flag is not set in Neighbour Advertisements.
2. Router Solicitations are being sent when necessary.
- 3. If accept_ra is TRUE (default), accept Router
+ 3. If accept_ra is TRUE (default), accept Router
Advertisements (and do autoconfiguration).
4. If accept_redirects is TRUE (default), accept Redirects.
TRUE:
- If local forwarding is enabled, Router behaviour is assumed.
+ If local forwarding is enabled, Router behaviour is assumed.
This means exactly the reverse from the above:
1. IsRouter flag is set in Neighbour Advertisements.
@@ -989,7 +1001,7 @@ router_solicitation_interval - INTEGER
Default: 4
router_solicitations - INTEGER
- Number of Router Solicitations to send until assuming no
+ Number of Router Solicitations to send until assuming no
routers are present.
Default: 3
@@ -1013,11 +1025,11 @@ temp_prefered_lft - INTEGER
max_desync_factor - INTEGER
Maximum value for DESYNC_FACTOR, which is a random value
- that ensures that clients don't synchronize with each
+ that ensures that clients don't synchronize with each
other and generate new addresses at exactly the same time.
value is in seconds.
Default: 600
-
+
regen_max_retry - INTEGER
Number of attempts before give up attempting to generate
valid temporary addresses.
@@ -1025,13 +1037,15 @@ regen_max_retry - INTEGER
max_addresses - INTEGER
Number of maximum addresses per interface. 0 disables limitation.
- It is recommended not set too large value (or 0) because it would
- be too easy way to crash kernel to allow to create too much of
+ It is recommended not set too large value (or 0) because it would
+ be too easy way to crash kernel to allow to create too much of
autoconfigured addresses.
Default: 16
disable_ipv6 - BOOLEAN
- Disable IPv6 operation.
+ Disable IPv6 operation. If accept_dad is set to 2, this value
+ will be dynamically set to TRUE if DAD fails for the link-local
+ address.
Default: FALSE (enable IPv6 operation)
accept_dad - INTEGER
diff --git a/Documentation/networking/ixgbe.txt b/Documentation/networking/ixgbe.txt
new file mode 100644
index 000000000000..eeb68685c788
--- /dev/null
+++ b/Documentation/networking/ixgbe.txt
@@ -0,0 +1,199 @@
+Linux Base Driver for 10 Gigabit PCI Express Intel(R) Network Connection
+========================================================================
+
+March 10, 2009
+
+
+Contents
+========
+
+- In This Release
+- Identifying Your Adapter
+- Building and Installation
+- Additional Configurations
+- Support
+
+
+
+In This Release
+===============
+
+This file describes the ixgbe Linux Base Driver for the 10 Gigabit PCI
+Express Intel(R) Network Connection. This driver includes support for
+Itanium(R)2-based systems.
+
+For questions related to hardware requirements, refer to the documentation
+supplied with your 10 Gigabit adapter. All hardware requirements listed apply
+to use with Linux.
+
+The following features are available in this kernel:
+ - Native VLANs
+ - Channel Bonding (teaming)
+ - SNMP
+ - Generic Receive Offload
+ - Data Center Bridging
+
+Channel Bonding documentation can be found in the Linux kernel source:
+/Documentation/networking/bonding.txt
+
+Ethtool, lspci, and ifconfig can be used to display device and driver
+specific information.
+
+
+Identifying Your Adapter
+========================
+
+This driver supports devices based on the 82598 controller and the 82599
+controller.
+
+For specific information on identifying which adapter you have, please visit:
+
+ http://support.intel.com/support/network/sb/CS-008441.htm
+
+
+Building and Installation
+=========================
+
+select m for "Intel(R) 10GbE PCI Express adapters support" located at:
+ Location:
+ -> Device Drivers
+ -> Network device support (NETDEVICES [=y])
+ -> Ethernet (10000 Mbit) (NETDEV_10000 [=y])
+
+1. make modules & make modules_install
+
+2. Load the module:
+
+# modprobe ixgbe
+
+ The insmod command can be used if the full
+ path to the driver module is specified. For example:
+
+ insmod /lib/modules/<KERNEL VERSION>/kernel/drivers/net/ixgbe/ixgbe.ko
+
+ With 2.6 based kernels also make sure that older ixgbe drivers are
+ removed from the kernel, before loading the new module:
+
+ rmmod ixgbe; modprobe ixgbe
+
+3. Assign an IP address to the interface by entering the following, where
+ x is the interface number:
+
+ ifconfig ethx <IP_address>
+
+4. Verify that the interface works. Enter the following, where <IP_address>
+ is the IP address for another machine on the same subnet as the interface
+ that is being tested:
+
+ ping <IP_address>
+
+
+Additional Configurations
+=========================
+
+ Viewing Link Messages
+ ---------------------
+ Link messages will not be displayed to the console if the distribution is
+ restricting system messages. In order to see network driver link messages on
+ your console, set dmesg to eight by entering the following:
+
+ dmesg -n 8
+
+ NOTE: This setting is not saved across reboots.
+
+
+ Jumbo Frames
+ ------------
+ The driver supports Jumbo Frames for all adapters. Jumbo Frames support is
+ enabled by changing the MTU to a value larger than the default of 1500.
+ The maximum value for the MTU is 16110. Use the ifconfig command to
+ increase the MTU size. For example:
+
+ ifconfig ethx mtu 9000 up
+
+ The maximum MTU setting for Jumbo Frames is 16110. This value coincides
+ with the maximum Jumbo Frames size of 16128.
+
+ Generic Receive Offload, aka GRO
+ --------------------------------
+ The driver supports the in-kernel software implementation of GRO. GRO has
+ shown that by coalescing Rx traffic into larger chunks of data, CPU
+ utilization can be significantly reduced when under large Rx load. GRO is an
+ evolution of the previously-used LRO interface. GRO is able to coalesce
+ other protocols besides TCP. It's also safe to use with configurations that
+ are problematic for LRO, namely bridging and iSCSI.
+
+ GRO is enabled by default in the driver. Future versions of ethtool will
+ support disabling and re-enabling GRO on the fly.
+
+
+ Data Center Bridging, aka DCB
+ -----------------------------
+
+ DCB is a configuration Quality of Service implementation in hardware.
+ It uses the VLAN priority tag (802.1p) to filter traffic. That means
+ that there are 8 different priorities that traffic can be filtered into.
+ It also enables priority flow control which can limit or eliminate the
+ number of dropped packets during network stress. Bandwidth can be
+ allocated to each of these priorities, which is enforced at the hardware
+ level.
+
+ To enable DCB support in ixgbe, you must enable the DCB netlink layer to
+ allow the userspace tools (see below) to communicate with the driver.
+ This can be found in the kernel configuration here:
+
+ -> Networking support
+ -> Networking options
+ -> Data Center Bridging support
+
+ Once this is selected, DCB support must be selected for ixgbe. This can
+ be found here:
+
+ -> Device Drivers
+ -> Network device support (NETDEVICES [=y])
+ -> Ethernet (10000 Mbit) (NETDEV_10000 [=y])
+ -> Intel(R) 10GbE PCI Express adapters support
+ -> Data Center Bridging (DCB) Support
+
+ After these options are selected, you must rebuild your kernel and your
+ modules.
+
+ In order to use DCB, userspace tools must be downloaded and installed.
+ The dcbd tools can be found at:
+
+ http://e1000.sf.net
+
+
+ Ethtool
+ -------
+ The driver utilizes the ethtool interface for driver configuration and
+ diagnostics, as well as displaying statistical information. Ethtool
+ version 3.0 or later is required for this functionality.
+
+ The latest release of ethtool can be found from
+ http://sourceforge.net/projects/gkernel.
+
+
+ NAPI
+ ----
+
+ NAPI (Rx polling mode) is supported in the ixgbe driver. NAPI is enabled
+ by default in the driver.
+
+ See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
+
+
+Support
+=======
+
+For general information, go to the Intel support website at:
+
+ http://support.intel.com
+
+or the Intel Wired Networking project hosted by Sourceforge at:
+
+ http://e1000.sourceforge.net
+
+If an issue is identified with the released source code on the supported
+kernel with a supported adapter, email the specific information related
+to the issue to e1000-devel@lists.sf.net
diff --git a/Documentation/networking/rds.txt b/Documentation/networking/rds.txt
new file mode 100644
index 000000000000..c67077cbeb80
--- /dev/null
+++ b/Documentation/networking/rds.txt
@@ -0,0 +1,356 @@
+
+Overview
+========
+
+This readme tries to provide some background on the hows and whys of RDS,
+and will hopefully help you find your way around the code.
+
+In addition, please see this email about RDS origins:
+http://oss.oracle.com/pipermail/rds-devel/2007-November/000228.html
+
+RDS Architecture
+================
+
+RDS provides reliable, ordered datagram delivery by using a single
+reliable connection between any two nodes in the cluster. This allows
+applications to use a single socket to talk to any other process in the
+cluster - so in a cluster with N processes you need N sockets, in contrast
+to N*N if you use a connection-oriented socket transport like TCP.
+
+RDS is not Infiniband-specific; it was designed to support different
+transports. The current implementation used to support RDS over TCP as well
+as IB. Work is in progress to support RDS over iWARP, and using DCE to
+guarantee no dropped packets on Ethernet, it may be possible to use RDS over
+UDP in the future.
+
+The high-level semantics of RDS from the application's point of view are
+
+ * Addressing
+ RDS uses IPv4 addresses and 16bit port numbers to identify
+ the end point of a connection. All socket operations that involve
+ passing addresses between kernel and user space generally
+ use a struct sockaddr_in.
+
+ The fact that IPv4 addresses are used does not mean the underlying
+ transport has to be IP-based. In fact, RDS over IB uses a
+ reliable IB connection; the IP address is used exclusively to
+ locate the remote node's GID (by ARPing for the given IP).
+
+ The port space is entirely independent of UDP, TCP or any other
+ protocol.
+
+ * Socket interface
+ RDS sockets work *mostly* as you would expect from a BSD
+ socket. The next section will cover the details. At any rate,
+ all I/O is performed through the standard BSD socket API.
+ Some additions like zerocopy support are implemented through
+ control messages, while other extensions use the getsockopt/
+ setsockopt calls.
+
+ Sockets must be bound before you can send or receive data.
+ This is needed because binding also selects a transport and
+ attaches it to the socket. Once bound, the transport assignment
+ does not change. RDS will tolerate IPs moving around (eg in
+ a active-active HA scenario), but only as long as the address
+ doesn't move to a different transport.
+
+ * sysctls
+ RDS supports a number of sysctls in /proc/sys/net/rds
+
+
+Socket Interface
+================
+
+ AF_RDS, PF_RDS, SOL_RDS
+ These constants haven't been assigned yet, because RDS isn't in
+ mainline yet. Currently, the kernel module assigns some constant
+ and publishes it to user space through two sysctl files
+ /proc/sys/net/rds/pf_rds
+ /proc/sys/net/rds/sol_rds
+
+ fd = socket(PF_RDS, SOCK_SEQPACKET, 0);
+ This creates a new, unbound RDS socket.
+
+ setsockopt(SOL_SOCKET): send and receive buffer size
+ RDS honors the send and receive buffer size socket options.
+ You are not allowed to queue more than SO_SNDSIZE bytes to
+ a socket. A message is queued when sendmsg is called, and
+ it leaves the queue when the remote system acknowledges
+ its arrival.
+
+ The SO_RCVSIZE option controls the maximum receive queue length.
+ This is a soft limit rather than a hard limit - RDS will
+ continue to accept and queue incoming messages, even if that
+ takes the queue length over the limit. However, it will also
+ mark the port as "congested" and send a congestion update to
+ the source node. The source node is supposed to throttle any
+ processes sending to this congested port.
+
+ bind(fd, &sockaddr_in, ...)
+ This binds the socket to a local IP address and port, and a
+ transport.
+
+ sendmsg(fd, ...)
+ Sends a message to the indicated recipient. The kernel will
+ transparently establish the underlying reliable connection
+ if it isn't up yet.
+
+ An attempt to send a message that exceeds SO_SNDSIZE will
+ return with -EMSGSIZE
+
+ An attempt to send a message that would take the total number
+ of queued bytes over the SO_SNDSIZE threshold will return
+ EAGAIN.
+
+ An attempt to send a message to a destination that is marked
+ as "congested" will return ENOBUFS.
+
+ recvmsg(fd, ...)
+ Receives a message that was queued to this socket. The sockets
+ recv queue accounting is adjusted, and if the queue length
+ drops below SO_SNDSIZE, the port is marked uncongested, and
+ a congestion update is sent to all peers.
+
+ Applications can ask the RDS kernel module to receive
+ notifications via control messages (for instance, there is a
+ notification when a congestion update arrived, or when a RDMA
+ operation completes). These notifications are received through
+ the msg.msg_control buffer of struct msghdr. The format of the
+ messages is described in manpages.
+
+ poll(fd)
+ RDS supports the poll interface to allow the application
+ to implement async I/O.
+
+ POLLIN handling is pretty straightforward. When there's an
+ incoming message queued to the socket, or a pending notification,
+ we signal POLLIN.
+
+ POLLOUT is a little harder. Since you can essentially send
+ to any destination, RDS will always signal POLLOUT as long as
+ there's room on the send queue (ie the number of bytes queued
+ is less than the sendbuf size).
+
+ However, the kernel will refuse to accept messages to
+ a destination marked congested - in this case you will loop
+ forever if you rely on poll to tell you what to do.
+ This isn't a trivial problem, but applications can deal with
+ this - by using congestion notifications, and by checking for
+ ENOBUFS errors returned by sendmsg.
+
+ setsockopt(SOL_RDS, RDS_CANCEL_SENT_TO, &sockaddr_in)
+ This allows the application to discard all messages queued to a
+ specific destination on this particular socket.
+
+ This allows the application to cancel outstanding messages if
+ it detects a timeout. For instance, if it tried to send a message,
+ and the remote host is unreachable, RDS will keep trying forever.
+ The application may decide it's not worth it, and cancel the
+ operation. In this case, it would use RDS_CANCEL_SENT_TO to
+ nuke any pending messages.
+
+
+RDMA for RDS
+============
+
+ see rds-rdma(7) manpage (available in rds-tools)
+
+
+Congestion Notifications
+========================
+
+ see rds(7) manpage
+
+
+RDS Protocol
+============
+
+ Message header
+
+ The message header is a 'struct rds_header' (see rds.h):
+ Fields:
+ h_sequence:
+ per-packet sequence number
+ h_ack:
+ piggybacked acknowledgment of last packet received
+ h_len:
+ length of data, not including header
+ h_sport:
+ source port
+ h_dport:
+ destination port
+ h_flags:
+ CONG_BITMAP - this is a congestion update bitmap
+ ACK_REQUIRED - receiver must ack this packet
+ RETRANSMITTED - packet has previously been sent
+ h_credit:
+ indicate to other end of connection that
+ it has more credits available (i.e. there is
+ more send room)
+ h_padding[4]:
+ unused, for future use
+ h_csum:
+ header checksum
+ h_exthdr:
+ optional data can be passed here. This is currently used for
+ passing RDMA-related information.
+
+ ACK and retransmit handling
+
+ One might think that with reliable IB connections you wouldn't need
+ to ack messages that have been received. The problem is that IB
+ hardware generates an ack message before it has DMAed the message
+ into memory. This creates a potential message loss if the HCA is
+ disabled for any reason between when it sends the ack and before
+ the message is DMAed and processed. This is only a potential issue
+ if another HCA is available for fail-over.
+
+ Sending an ack immediately would allow the sender to free the sent
+ message from their send queue quickly, but could cause excessive
+ traffic to be used for acks. RDS piggybacks acks on sent data
+ packets. Ack-only packets are reduced by only allowing one to be
+ in flight at a time, and by the sender only asking for acks when
+ its send buffers start to fill up. All retransmissions are also
+ acked.
+
+ Flow Control
+
+ RDS's IB transport uses a credit-based mechanism to verify that
+ there is space in the peer's receive buffers for more data. This
+ eliminates the need for hardware retries on the connection.
+
+ Congestion
+
+ Messages waiting in the receive queue on the receiving socket
+ are accounted against the sockets SO_RCVBUF option value. Only
+ the payload bytes in the message are accounted for. If the
+ number of bytes queued equals or exceeds rcvbuf then the socket
+ is congested. All sends attempted to this socket's address
+ should return block or return -EWOULDBLOCK.
+
+ Applications are expected to be reasonably tuned such that this
+ situation very rarely occurs. An application encountering this
+ "back-pressure" is considered a bug.
+
+ This is implemented by having each node maintain bitmaps which
+ indicate which ports on bound addresses are congested. As the
+ bitmap changes it is sent through all the connections which
+ terminate in the local address of the bitmap which changed.
+
+ The bitmaps are allocated as connections are brought up. This
+ avoids allocation in the interrupt handling path which queues
+ sages on sockets. The dense bitmaps let transports send the
+ entire bitmap on any bitmap change reasonably efficiently. This
+ is much easier to implement than some finer-grained
+ communication of per-port congestion. The sender does a very
+ inexpensive bit test to test if the port it's about to send to
+ is congested or not.
+
+
+RDS Transport Layer
+==================
+
+ As mentioned above, RDS is not IB-specific. Its code is divided
+ into a general RDS layer and a transport layer.
+
+ The general layer handles the socket API, congestion handling,
+ loopback, stats, usermem pinning, and the connection state machine.
+
+ The transport layer handles the details of the transport. The IB
+ transport, for example, handles all the queue pairs, work requests,
+ CM event handlers, and other Infiniband details.
+
+
+RDS Kernel Structures
+=====================
+
+ struct rds_message
+ aka possibly "rds_outgoing", the generic RDS layer copies data to
+ be sent and sets header fields as needed, based on the socket API.
+ This is then queued for the individual connection and sent by the
+ connection's transport.
+ struct rds_incoming
+ a generic struct referring to incoming data that can be handed from
+ the transport to the general code and queued by the general code
+ while the socket is awoken. It is then passed back to the transport
+ code to handle the actual copy-to-user.
+ struct rds_socket
+ per-socket information
+ struct rds_connection
+ per-connection information
+ struct rds_transport
+ pointers to transport-specific functions
+ struct rds_statistics
+ non-transport-specific statistics
+ struct rds_cong_map
+ wraps the raw congestion bitmap, contains rbnode, waitq, etc.
+
+Connection management
+=====================
+
+ Connections may be in UP, DOWN, CONNECTING, DISCONNECTING, and
+ ERROR states.
+
+ The first time an attempt is made by an RDS socket to send data to
+ a node, a connection is allocated and connected. That connection is
+ then maintained forever -- if there are transport errors, the
+ connection will be dropped and re-established.
+
+ Dropping a connection while packets are queued will cause queued or
+ partially-sent datagrams to be retransmitted when the connection is
+ re-established.
+
+
+The send path
+=============
+
+ rds_sendmsg()
+ struct rds_message built from incoming data
+ CMSGs parsed (e.g. RDMA ops)
+ transport connection alloced and connected if not already
+ rds_message placed on send queue
+ send worker awoken
+ rds_send_worker()
+ calls rds_send_xmit() until queue is empty
+ rds_send_xmit()
+ transmits congestion map if one is pending
+ may set ACK_REQUIRED
+ calls transport to send either non-RDMA or RDMA message
+ (RDMA ops never retransmitted)
+ rds_ib_xmit()
+ allocs work requests from send ring
+ adds any new send credits available to peer (h_credits)
+ maps the rds_message's sg list
+ piggybacks ack
+ populates work requests
+ post send to connection's queue pair
+
+The recv path
+=============
+
+ rds_ib_recv_cq_comp_handler()
+ looks at write completions
+ unmaps recv buffer from device
+ no errors, call rds_ib_process_recv()
+ refill recv ring
+ rds_ib_process_recv()
+ validate header checksum
+ copy header to rds_ib_incoming struct if start of a new datagram
+ add to ibinc's fraglist
+ if competed datagram:
+ update cong map if datagram was cong update
+ call rds_recv_incoming() otherwise
+ note if ack is required
+ rds_recv_incoming()
+ drop duplicate packets
+ respond to pings
+ find the sock associated with this datagram
+ add to sock queue
+ wake up sock
+ do some congestion calculations
+ rds_recvmsg
+ copy data into user iovec
+ handle CMSGs
+ return to application
+
+
diff --git a/Documentation/networking/timestamping.txt b/Documentation/networking/timestamping.txt
new file mode 100644
index 000000000000..0e58b4539176
--- /dev/null
+++ b/Documentation/networking/timestamping.txt
@@ -0,0 +1,180 @@
+The existing interfaces for getting network packages time stamped are:
+
+* SO_TIMESTAMP
+ Generate time stamp for each incoming packet using the (not necessarily
+ monotonous!) system time. Result is returned via recv_msg() in a
+ control message as timeval (usec resolution).
+
+* SO_TIMESTAMPNS
+ Same time stamping mechanism as SO_TIMESTAMP, but returns result as
+ timespec (nsec resolution).
+
+* IP_MULTICAST_LOOP + SO_TIMESTAMP[NS]
+ Only for multicasts: approximate send time stamp by receiving the looped
+ packet and using its receive time stamp.
+
+The following interface complements the existing ones: receive time
+stamps can be generated and returned for arbitrary packets and much
+closer to the point where the packet is really sent. Time stamps can
+be generated in software (as before) or in hardware (if the hardware
+has such a feature).
+
+SO_TIMESTAMPING:
+
+Instructs the socket layer which kind of information is wanted. The
+parameter is an integer with some of the following bits set. Setting
+other bits is an error and doesn't change the current state.
+
+SOF_TIMESTAMPING_TX_HARDWARE: try to obtain send time stamp in hardware
+SOF_TIMESTAMPING_TX_SOFTWARE: if SOF_TIMESTAMPING_TX_HARDWARE is off or
+ fails, then do it in software
+SOF_TIMESTAMPING_RX_HARDWARE: return the original, unmodified time stamp
+ as generated by the hardware
+SOF_TIMESTAMPING_RX_SOFTWARE: if SOF_TIMESTAMPING_RX_HARDWARE is off or
+ fails, then do it in software
+SOF_TIMESTAMPING_RAW_HARDWARE: return original raw hardware time stamp
+SOF_TIMESTAMPING_SYS_HARDWARE: return hardware time stamp transformed to
+ the system time base
+SOF_TIMESTAMPING_SOFTWARE: return system time stamp generated in
+ software
+
+SOF_TIMESTAMPING_TX/RX determine how time stamps are generated.
+SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the
+following control message:
+ struct scm_timestamping {
+ struct timespec systime;
+ struct timespec hwtimetrans;
+ struct timespec hwtimeraw;
+ };
+
+recvmsg() can be used to get this control message for regular incoming
+packets. For send time stamps the outgoing packet is looped back to
+the socket's error queue with the send time stamp(s) attached. It can
+be received with recvmsg(flags=MSG_ERRQUEUE). The call returns the
+original outgoing packet data including all headers preprended down to
+and including the link layer, the scm_timestamping control message and
+a sock_extended_err control message with ee_errno==ENOMSG and
+ee_origin==SO_EE_ORIGIN_TIMESTAMPING. A socket with such a pending
+bounced packet is ready for reading as far as select() is concerned.
+If the outgoing packet has to be fragmented, then only the first
+fragment is time stamped and returned to the sending socket.
+
+All three values correspond to the same event in time, but were
+generated in different ways. Each of these values may be empty (= all
+zero), in which case no such value was available. If the application
+is not interested in some of these values, they can be left blank to
+avoid the potential overhead of calculating them.
+
+systime is the value of the system time at that moment. This
+corresponds to the value also returned via SO_TIMESTAMP[NS]. If the
+time stamp was generated by hardware, then this field is
+empty. Otherwise it is filled in if SOF_TIMESTAMPING_SOFTWARE is
+set.
+
+hwtimeraw is the original hardware time stamp. Filled in if
+SOF_TIMESTAMPING_RAW_HARDWARE is set. No assumptions about its
+relation to system time should be made.
+
+hwtimetrans is the hardware time stamp transformed so that it
+corresponds as good as possible to system time. This correlation is
+not perfect; as a consequence, sorting packets received via different
+NICs by their hwtimetrans may differ from the order in which they were
+received. hwtimetrans may be non-monotonic even for the same NIC.
+Filled in if SOF_TIMESTAMPING_SYS_HARDWARE is set. Requires support
+by the network device and will be empty without that support.
+
+
+SIOCSHWTSTAMP:
+
+Hardware time stamping must also be initialized for each device driver
+that is expected to do hardware time stamping. The parameter is:
+
+struct hwtstamp_config {
+ int flags; /* no flags defined right now, must be zero */
+ int tx_type; /* HWTSTAMP_TX_* */
+ int rx_filter; /* HWTSTAMP_FILTER_* */
+};
+
+Desired behavior is passed into the kernel and to a specific device by
+calling ioctl(SIOCSHWTSTAMP) with a pointer to a struct ifreq whose
+ifr_data points to a struct hwtstamp_config. The tx_type and
+rx_filter are hints to the driver what it is expected to do. If
+the requested fine-grained filtering for incoming packets is not
+supported, the driver may time stamp more than just the requested types
+of packets.
+
+A driver which supports hardware time stamping shall update the struct
+with the actual, possibly more permissive configuration. If the
+requested packets cannot be time stamped, then nothing should be
+changed and ERANGE shall be returned (in contrast to EINVAL, which
+indicates that SIOCSHWTSTAMP is not supported at all).
+
+Only a processes with admin rights may change the configuration. User
+space is responsible to ensure that multiple processes don't interfere
+with each other and that the settings are reset.
+
+/* possible values for hwtstamp_config->tx_type */
+enum {
+ /*
+ * no outgoing packet will need hardware time stamping;
+ * should a packet arrive which asks for it, no hardware
+ * time stamping will be done
+ */
+ HWTSTAMP_TX_OFF,
+
+ /*
+ * enables hardware time stamping for outgoing packets;
+ * the sender of the packet decides which are to be
+ * time stamped by setting SOF_TIMESTAMPING_TX_SOFTWARE
+ * before sending the packet
+ */
+ HWTSTAMP_TX_ON,
+};
+
+/* possible values for hwtstamp_config->rx_filter */
+enum {
+ /* time stamp no incoming packet at all */
+ HWTSTAMP_FILTER_NONE,
+
+ /* time stamp any incoming packet */
+ HWTSTAMP_FILTER_ALL,
+
+ /* return value: time stamp all packets requested plus some others */
+ HWTSTAMP_FILTER_SOME,
+
+ /* PTP v1, UDP, any kind of event packet */
+ HWTSTAMP_FILTER_PTP_V1_L4_EVENT,
+
+ ...
+};
+
+
+DEVICE IMPLEMENTATION
+
+A driver which supports hardware time stamping must support the
+SIOCSHWTSTAMP ioctl. Time stamps for received packets must be stored
+in the skb with skb_hwtstamp_set().
+
+Time stamps for outgoing packets are to be generated as follows:
+- In hard_start_xmit(), check if skb_hwtstamp_check_tx_hardware()
+ returns non-zero. If yes, then the driver is expected
+ to do hardware time stamping.
+- If this is possible for the skb and requested, then declare
+ that the driver is doing the time stamping by calling
+ skb_hwtstamp_tx_in_progress(). A driver not supporting
+ hardware time stamping doesn't do that. A driver must never
+ touch sk_buff::tstamp! It is used to store how time stamping
+ for an outgoing packets is to be done.
+- As soon as the driver has sent the packet and/or obtained a
+ hardware time stamp for it, it passes the time stamp back by
+ calling skb_hwtstamp_tx() with the original skb, the raw
+ hardware time stamp and a handle to the device (necessary
+ to convert the hardware time stamp to system time). If obtaining
+ the hardware time stamp somehow fails, then the driver should
+ not fall back to software time stamping. The rationale is that
+ this would occur at a later time in the processing pipeline
+ than other software time stamping and therefore could lead
+ to unexpected deltas between time stamps.
+- If the driver did not call skb_hwtstamp_tx_in_progress(), then
+ dev_hard_start_xmit() checks whether software time stamping
+ is wanted as fallback and potentially generates the time stamp.
diff --git a/Documentation/networking/timestamping/.gitignore b/Documentation/networking/timestamping/.gitignore
new file mode 100644
index 000000000000..71e81eb2e22f
--- /dev/null
+++ b/Documentation/networking/timestamping/.gitignore
@@ -0,0 +1 @@
+timestamping
diff --git a/Documentation/networking/timestamping/Makefile b/Documentation/networking/timestamping/Makefile
new file mode 100644
index 000000000000..2a1489fdc036
--- /dev/null
+++ b/Documentation/networking/timestamping/Makefile
@@ -0,0 +1,6 @@
+CPPFLAGS = -I../../../include
+
+timestamping: timestamping.c
+
+clean:
+ rm -f timestamping
diff --git a/Documentation/networking/timestamping/timestamping.c b/Documentation/networking/timestamping/timestamping.c
new file mode 100644
index 000000000000..43d143104210
--- /dev/null
+++ b/Documentation/networking/timestamping/timestamping.c
@@ -0,0 +1,533 @@
+/*
+ * This program demonstrates how the various time stamping features in
+ * the Linux kernel work. It emulates the behavior of a PTP
+ * implementation in stand-alone master mode by sending PTPv1 Sync
+ * multicasts once every second. It looks for similar packets, but
+ * beyond that doesn't actually implement PTP.
+ *
+ * Outgoing packets are time stamped with SO_TIMESTAMPING with or
+ * without hardware support.
+ *
+ * Incoming packets are time stamped with SO_TIMESTAMPING with or
+ * without hardware support, SIOCGSTAMP[NS] (per-socket time stamp) and
+ * SO_TIMESTAMP[NS].
+ *
+ * Copyright (C) 2009 Intel Corporation.
+ * Author: Patrick Ohly <patrick.ohly@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+
+#include "asm/types.h"
+#include "linux/net_tstamp.h"
+#include "linux/errqueue.h"
+
+#ifndef SO_TIMESTAMPING
+# define SO_TIMESTAMPING 37
+# define SCM_TIMESTAMPING SO_TIMESTAMPING
+#endif
+
+#ifndef SO_TIMESTAMPNS
+# define SO_TIMESTAMPNS 35
+#endif
+
+#ifndef SIOCGSTAMPNS
+# define SIOCGSTAMPNS 0x8907
+#endif
+
+#ifndef SIOCSHWTSTAMP
+# define SIOCSHWTSTAMP 0x89b0
+#endif
+
+static void usage(const char *error)
+{
+ if (error)
+ printf("invalid option: %s\n", error);
+ printf("timestamping interface option*\n\n"
+ "Options:\n"
+ " IP_MULTICAST_LOOP - looping outgoing multicasts\n"
+ " SO_TIMESTAMP - normal software time stamping, ms resolution\n"
+ " SO_TIMESTAMPNS - more accurate software time stamping\n"
+ " SOF_TIMESTAMPING_TX_HARDWARE - hardware time stamping of outgoing packets\n"
+ " SOF_TIMESTAMPING_TX_SOFTWARE - software fallback for outgoing packets\n"
+ " SOF_TIMESTAMPING_RX_HARDWARE - hardware time stamping of incoming packets\n"
+ " SOF_TIMESTAMPING_RX_SOFTWARE - software fallback for incoming packets\n"
+ " SOF_TIMESTAMPING_SOFTWARE - request reporting of software time stamps\n"
+ " SOF_TIMESTAMPING_SYS_HARDWARE - request reporting of transformed HW time stamps\n"
+ " SOF_TIMESTAMPING_RAW_HARDWARE - request reporting of raw HW time stamps\n"
+ " SIOCGSTAMP - check last socket time stamp\n"
+ " SIOCGSTAMPNS - more accurate socket time stamp\n");
+ exit(1);
+}
+
+static void bail(const char *error)
+{
+ printf("%s: %s\n", error, strerror(errno));
+ exit(1);
+}
+
+static const unsigned char sync[] = {
+ 0x00, 0x01, 0x00, 0x01,
+ 0x5f, 0x44, 0x46, 0x4c,
+ 0x54, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x01,
+
+ /* fake uuid */
+ 0x00, 0x01,
+ 0x02, 0x03, 0x04, 0x05,
+
+ 0x00, 0x01, 0x00, 0x37,
+ 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x49, 0x05, 0xcd, 0x01,
+ 0x29, 0xb1, 0x8d, 0xb0,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01,
+
+ /* fake uuid */
+ 0x00, 0x01,
+ 0x02, 0x03, 0x04, 0x05,
+
+ 0x00, 0x00, 0x00, 0x37,
+ 0x00, 0x00, 0x00, 0x04,
+ 0x44, 0x46, 0x4c, 0x54,
+ 0x00, 0x00, 0xf0, 0x60,
+ 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0xf0, 0x60,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04,
+ 0x44, 0x46, 0x4c, 0x54,
+ 0x00, 0x01,
+
+ /* fake uuid */
+ 0x00, 0x01,
+ 0x02, 0x03, 0x04, 0x05,
+
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
+
+static void sendpacket(int sock, struct sockaddr *addr, socklen_t addr_len)
+{
+ struct timeval now;
+ int res;
+
+ res = sendto(sock, sync, sizeof(sync), 0,
+ addr, addr_len);
+ gettimeofday(&now, 0);
+ if (res < 0)
+ printf("%s: %s\n", "send", strerror(errno));
+ else
+ printf("%ld.%06ld: sent %d bytes\n",
+ (long)now.tv_sec, (long)now.tv_usec,
+ res);
+}
+
+static void printpacket(struct msghdr *msg, int res,
+ char *data,
+ int sock, int recvmsg_flags,
+ int siocgstamp, int siocgstampns)
+{
+ struct sockaddr_in *from_addr = (struct sockaddr_in *)msg->msg_name;
+ struct cmsghdr *cmsg;
+ struct timeval tv;
+ struct timespec ts;
+ struct timeval now;
+
+ gettimeofday(&now, 0);
+
+ printf("%ld.%06ld: received %s data, %d bytes from %s, %d bytes control messages\n",
+ (long)now.tv_sec, (long)now.tv_usec,
+ (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
+ res,
+ inet_ntoa(from_addr->sin_addr),
+ msg->msg_controllen);
+ for (cmsg = CMSG_FIRSTHDR(msg);
+ cmsg;
+ cmsg = CMSG_NXTHDR(msg, cmsg)) {
+ printf(" cmsg len %d: ", cmsg->cmsg_len);
+ switch (cmsg->cmsg_level) {
+ case SOL_SOCKET:
+ printf("SOL_SOCKET ");
+ switch (cmsg->cmsg_type) {
+ case SO_TIMESTAMP: {
+ struct timeval *stamp =
+ (struct timeval *)CMSG_DATA(cmsg);
+ printf("SO_TIMESTAMP %ld.%06ld",
+ (long)stamp->tv_sec,
+ (long)stamp->tv_usec);
+ break;
+ }
+ case SO_TIMESTAMPNS: {
+ struct timespec *stamp =
+ (struct timespec *)CMSG_DATA(cmsg);
+ printf("SO_TIMESTAMPNS %ld.%09ld",
+ (long)stamp->tv_sec,
+ (long)stamp->tv_nsec);
+ break;
+ }
+ case SO_TIMESTAMPING: {
+ struct timespec *stamp =
+ (struct timespec *)CMSG_DATA(cmsg);
+ printf("SO_TIMESTAMPING ");
+ printf("SW %ld.%09ld ",
+ (long)stamp->tv_sec,
+ (long)stamp->tv_nsec);
+ stamp++;
+ printf("HW transformed %ld.%09ld ",
+ (long)stamp->tv_sec,
+ (long)stamp->tv_nsec);
+ stamp++;
+ printf("HW raw %ld.%09ld",
+ (long)stamp->tv_sec,
+ (long)stamp->tv_nsec);
+ break;
+ }
+ default:
+ printf("type %d", cmsg->cmsg_type);
+ break;
+ }
+ break;
+ case IPPROTO_IP:
+ printf("IPPROTO_IP ");
+ switch (cmsg->cmsg_type) {
+ case IP_RECVERR: {
+ struct sock_extended_err *err =
+ (struct sock_extended_err *)CMSG_DATA(cmsg);
+ printf("IP_RECVERR ee_errno '%s' ee_origin %d => %s",
+ strerror(err->ee_errno),
+ err->ee_origin,
+#ifdef SO_EE_ORIGIN_TIMESTAMPING
+ err->ee_origin == SO_EE_ORIGIN_TIMESTAMPING ?
+ "bounced packet" : "unexpected origin"
+#else
+ "probably SO_EE_ORIGIN_TIMESTAMPING"
+#endif
+ );
+ if (res < sizeof(sync))
+ printf(" => truncated data?!");
+ else if (!memcmp(sync, data + res - sizeof(sync),
+ sizeof(sync)))
+ printf(" => GOT OUR DATA BACK (HURRAY!)");
+ break;
+ }
+ case IP_PKTINFO: {
+ struct in_pktinfo *pktinfo =
+ (struct in_pktinfo *)CMSG_DATA(cmsg);
+ printf("IP_PKTINFO interface index %u",
+ pktinfo->ipi_ifindex);
+ break;
+ }
+ default:
+ printf("type %d", cmsg->cmsg_type);
+ break;
+ }
+ break;
+ default:
+ printf("level %d type %d",
+ cmsg->cmsg_level,
+ cmsg->cmsg_type);
+ break;
+ }
+ printf("\n");
+ }
+
+ if (siocgstamp) {
+ if (ioctl(sock, SIOCGSTAMP, &tv))
+ printf(" %s: %s\n", "SIOCGSTAMP", strerror(errno));
+ else
+ printf("SIOCGSTAMP %ld.%06ld\n",
+ (long)tv.tv_sec,
+ (long)tv.tv_usec);
+ }
+ if (siocgstampns) {
+ if (ioctl(sock, SIOCGSTAMPNS, &ts))
+ printf(" %s: %s\n", "SIOCGSTAMPNS", strerror(errno));
+ else
+ printf("SIOCGSTAMPNS %ld.%09ld\n",
+ (long)ts.tv_sec,
+ (long)ts.tv_nsec);
+ }
+}
+
+static void recvpacket(int sock, int recvmsg_flags,
+ int siocgstamp, int siocgstampns)
+{
+ char data[256];
+ struct msghdr msg;
+ struct iovec entry;
+ struct sockaddr_in from_addr;
+ struct {
+ struct cmsghdr cm;
+ char control[512];
+ } control;
+ int res;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_iov = &entry;
+ msg.msg_iovlen = 1;
+ entry.iov_base = data;
+ entry.iov_len = sizeof(data);
+ msg.msg_name = (caddr_t)&from_addr;
+ msg.msg_namelen = sizeof(from_addr);
+ msg.msg_control = &control;
+ msg.msg_controllen = sizeof(control);
+
+ res = recvmsg(sock, &msg, recvmsg_flags|MSG_DONTWAIT);
+ if (res < 0) {
+ printf("%s %s: %s\n",
+ "recvmsg",
+ (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
+ strerror(errno));
+ } else {
+ printpacket(&msg, res, data,
+ sock, recvmsg_flags,
+ siocgstamp, siocgstampns);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int so_timestamping_flags = 0;
+ int so_timestamp = 0;
+ int so_timestampns = 0;
+ int siocgstamp = 0;
+ int siocgstampns = 0;
+ int ip_multicast_loop = 0;
+ char *interface;
+ int i;
+ int enabled = 1;
+ int sock;
+ struct ifreq device;
+ struct ifreq hwtstamp;
+ struct hwtstamp_config hwconfig, hwconfig_requested;
+ struct sockaddr_in addr;
+ struct ip_mreq imr;
+ struct in_addr iaddr;
+ int val;
+ socklen_t len;
+ struct timeval next;
+
+ if (argc < 2)
+ usage(0);
+ interface = argv[1];
+
+ for (i = 2; i < argc; i++) {
+ if (!strcasecmp(argv[i], "SO_TIMESTAMP"))
+ so_timestamp = 1;
+ else if (!strcasecmp(argv[i], "SO_TIMESTAMPNS"))
+ so_timestampns = 1;
+ else if (!strcasecmp(argv[i], "SIOCGSTAMP"))
+ siocgstamp = 1;
+ else if (!strcasecmp(argv[i], "SIOCGSTAMPNS"))
+ siocgstampns = 1;
+ else if (!strcasecmp(argv[i], "IP_MULTICAST_LOOP"))
+ ip_multicast_loop = 1;
+ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_HARDWARE"))
+ so_timestamping_flags |= SOF_TIMESTAMPING_TX_HARDWARE;
+ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_SOFTWARE"))
+ so_timestamping_flags |= SOF_TIMESTAMPING_TX_SOFTWARE;
+ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_HARDWARE"))
+ so_timestamping_flags |= SOF_TIMESTAMPING_RX_HARDWARE;
+ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_SOFTWARE"))
+ so_timestamping_flags |= SOF_TIMESTAMPING_RX_SOFTWARE;
+ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SOFTWARE"))
+ so_timestamping_flags |= SOF_TIMESTAMPING_SOFTWARE;
+ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SYS_HARDWARE"))
+ so_timestamping_flags |= SOF_TIMESTAMPING_SYS_HARDWARE;
+ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RAW_HARDWARE"))
+ so_timestamping_flags |= SOF_TIMESTAMPING_RAW_HARDWARE;
+ else
+ usage(argv[i]);
+ }
+
+ sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (socket < 0)
+ bail("socket");
+
+ memset(&device, 0, sizeof(device));
+ strncpy(device.ifr_name, interface, sizeof(device.ifr_name));
+ if (ioctl(sock, SIOCGIFADDR, &device) < 0)
+ bail("getting interface IP address");
+
+ memset(&hwtstamp, 0, sizeof(hwtstamp));
+ strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
+ hwtstamp.ifr_data = (void *)&hwconfig;
+ memset(&hwconfig, 0, sizeof(&hwconfig));
+ hwconfig.tx_type =
+ (so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ?
+ HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
+ hwconfig.rx_filter =
+ (so_timestamping_flags & SOF_TIMESTAMPING_RX_HARDWARE) ?
+ HWTSTAMP_FILTER_PTP_V1_L4_SYNC : HWTSTAMP_FILTER_NONE;
+ hwconfig_requested = hwconfig;
+ if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) {
+ if ((errno == EINVAL || errno == ENOTSUP) &&
+ hwconfig_requested.tx_type == HWTSTAMP_TX_OFF &&
+ hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE)
+ printf("SIOCSHWTSTAMP: disabling hardware time stamping not possible\n");
+ else
+ bail("SIOCSHWTSTAMP");
+ }
+ printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d requested, got %d\n",
+ hwconfig_requested.tx_type, hwconfig.tx_type,
+ hwconfig_requested.rx_filter, hwconfig.rx_filter);
+
+ /* bind to PTP port */
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_port = htons(319 /* PTP event port */);
+ if (bind(sock,
+ (struct sockaddr *)&addr,
+ sizeof(struct sockaddr_in)) < 0)
+ bail("bind");
+
+ /* set multicast group for outgoing packets */
+ inet_aton("224.0.1.130", &iaddr); /* alternate PTP domain 1 */
+ addr.sin_addr = iaddr;
+ imr.imr_multiaddr.s_addr = iaddr.s_addr;
+ imr.imr_interface.s_addr =
+ ((struct sockaddr_in *)&device.ifr_addr)->sin_addr.s_addr;
+ if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF,
+ &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0)
+ bail("set multicast");
+
+ /* join multicast group, loop our own packet */
+ if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ &imr, sizeof(struct ip_mreq)) < 0)
+ bail("join multicast group");
+
+ if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP,
+ &ip_multicast_loop, sizeof(enabled)) < 0) {
+ bail("loop multicast");
+ }
+
+ /* set socket options for time stamping */
+ if (so_timestamp &&
+ setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP,
+ &enabled, sizeof(enabled)) < 0)
+ bail("setsockopt SO_TIMESTAMP");
+
+ if (so_timestampns &&
+ setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS,
+ &enabled, sizeof(enabled)) < 0)
+ bail("setsockopt SO_TIMESTAMPNS");
+
+ if (so_timestamping_flags &&
+ setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING,
+ &so_timestamping_flags,
+ sizeof(so_timestamping_flags)) < 0)
+ bail("setsockopt SO_TIMESTAMPING");
+
+ /* request IP_PKTINFO for debugging purposes */
+ if (setsockopt(sock, SOL_IP, IP_PKTINFO,
+ &enabled, sizeof(enabled)) < 0)
+ printf("%s: %s\n", "setsockopt IP_PKTINFO", strerror(errno));
+
+ /* verify socket options */
+ len = sizeof(val);
+ if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &val, &len) < 0)
+ printf("%s: %s\n", "getsockopt SO_TIMESTAMP", strerror(errno));
+ else
+ printf("SO_TIMESTAMP %d\n", val);
+
+ if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, &val, &len) < 0)
+ printf("%s: %s\n", "getsockopt SO_TIMESTAMPNS",
+ strerror(errno));
+ else
+ printf("SO_TIMESTAMPNS %d\n", val);
+
+ if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &val, &len) < 0) {
+ printf("%s: %s\n", "getsockopt SO_TIMESTAMPING",
+ strerror(errno));
+ } else {
+ printf("SO_TIMESTAMPING %d\n", val);
+ if (val != so_timestamping_flags)
+ printf(" not the expected value %d\n",
+ so_timestamping_flags);
+ }
+
+ /* send packets forever every five seconds */
+ gettimeofday(&next, 0);
+ next.tv_sec = (next.tv_sec + 1) / 5 * 5;
+ next.tv_usec = 0;
+ while (1) {
+ struct timeval now;
+ struct timeval delta;
+ long delta_us;
+ int res;
+ fd_set readfs, errorfs;
+
+ gettimeofday(&now, 0);
+ delta_us = (long)(next.tv_sec - now.tv_sec) * 1000000 +
+ (long)(next.tv_usec - now.tv_usec);
+ if (delta_us > 0) {
+ /* continue waiting for timeout or data */
+ delta.tv_sec = delta_us / 1000000;
+ delta.tv_usec = delta_us % 1000000;
+
+ FD_ZERO(&readfs);
+ FD_ZERO(&errorfs);
+ FD_SET(sock, &readfs);
+ FD_SET(sock, &errorfs);
+ printf("%ld.%06ld: select %ldus\n",
+ (long)now.tv_sec, (long)now.tv_usec,
+ delta_us);
+ res = select(sock + 1, &readfs, 0, &errorfs, &delta);
+ gettimeofday(&now, 0);
+ printf("%ld.%06ld: select returned: %d, %s\n",
+ (long)now.tv_sec, (long)now.tv_usec,
+ res,
+ res < 0 ? strerror(errno) : "success");
+ if (res > 0) {
+ if (FD_ISSET(sock, &readfs))
+ printf("ready for reading\n");
+ if (FD_ISSET(sock, &errorfs))
+ printf("has error\n");
+ recvpacket(sock, 0,
+ siocgstamp,
+ siocgstampns);
+ recvpacket(sock, MSG_ERRQUEUE,
+ siocgstamp,
+ siocgstampns);
+ }
+ } else {
+ /* write one packet */
+ sendpacket(sock,
+ (struct sockaddr *)&addr,
+ sizeof(addr));
+ next.tv_sec += 5;
+ continue;
+ }
+ }
+
+ return 0;
+}
diff --git a/Documentation/networking/vxge.txt b/Documentation/networking/vxge.txt
new file mode 100644
index 000000000000..d2e2997e6fa0
--- /dev/null
+++ b/Documentation/networking/vxge.txt
@@ -0,0 +1,100 @@
+Neterion's (Formerly S2io) X3100 Series 10GbE PCIe Server Adapter Linux driver
+==============================================================================
+
+Contents
+--------
+
+1) Introduction
+2) Features supported
+3) Configurable driver parameters
+4) Troubleshooting
+
+1) Introduction:
+----------------
+This Linux driver supports all Neterion's X3100 series 10 GbE PCIe I/O
+Virtualized Server adapters.
+The X3100 series supports four modes of operation, configurable via
+firmware -
+ Single function mode
+ Multi function mode
+ SRIOV mode
+ MRIOV mode
+The functions share a 10GbE link and the pci-e bus, but hardly anything else
+inside the ASIC. Features like independent hw reset, statistics, bandwidth/
+priority allocation and guarantees, GRO, TSO, interrupt moderation etc are
+supported independently on each function.
+
+(See below for a complete list of features supported for both IPv4 and IPv6)
+
+2) Features supported:
+----------------------
+
+i) Single function mode (up to 17 queues)
+
+ii) Multi function mode (up to 17 functions)
+
+iii) PCI-SIG's I/O Virtualization
+ - Single Root mode: v1.0 (up to 17 functions)
+ - Multi-Root mode: v1.0 (up to 17 functions)
+
+iv) Jumbo frames
+ X3100 Series supports MTU up to 9600 bytes, modifiable using
+ ifconfig command.
+
+v) Offloads supported: (Enabled by default)
+ Checksum offload (TCP/UDP/IP) on transmit and receive paths
+ TCP Segmentation Offload (TSO) on transmit path
+ Generic Receive Offload (GRO) on receive path
+
+vi) MSI-X: (Enabled by default)
+ Resulting in noticeable performance improvement (up to 7% on certain
+ platforms).
+
+vii) NAPI: (Enabled by default)
+ For better Rx interrupt moderation.
+
+viii)RTH (Receive Traffic Hash): (Enabled by default)
+ Receive side steering for better scaling.
+
+ix) Statistics
+ Comprehensive MAC-level and software statistics displayed using
+ "ethtool -S" option.
+
+x) Multiple hardware queues: (Enabled by default)
+ Up to 17 hardware based transmit and receive data channels, with
+ multiple steering options (transmit multiqueue enabled by default).
+
+3) Configurable driver parameters:
+----------------------------------
+
+i) max_config_dev
+ Specifies maximum device functions to be enabled.
+ Valid range: 1-8
+
+ii) max_config_port
+ Specifies number of ports to be enabled.
+ Valid range: 1,2
+ Default: 1
+
+iii)max_config_vpath
+ Specifies maximum VPATH(s) configured for each device function.
+ Valid range: 1-17
+
+iv) vlan_tag_strip
+ Enables/disables vlan tag stripping from all received tagged frames that
+ are not replicated at the internal L2 switch.
+ Valid range: 0,1 (disabled, enabled respectively)
+ Default: 1
+
+v) addr_learn_en
+ Enable learning the mac address of the guest OS interface in
+ virtualization environment.
+ Valid range: 0,1 (disabled, enabled respectively)
+ Default: 0
+
+4) Troubleshooting:
+-------------------
+
+To resolve an issue with the source code or X3100 series adapter, please collect
+the statistics, register dumps using ethool, relevant logs and email them to
+support@neterion.com.
diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt
index 6c238f59b2a9..249db3a15d15 100644
--- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe/firmware.txt
@@ -1,6 +1,6 @@
* Uploaded QE firmware
- If a new firwmare has been uploaded to the QE (usually by the
+ If a new firmware has been uploaded to the QE (usually by the
boot loader), then a 'firmware' child node should be added to the QE
node. This node provides information on the uploaded firmware that
device drivers may need.
diff --git a/Documentation/powerpc/dts-bindings/fsl/dma.txt b/Documentation/powerpc/dts-bindings/fsl/dma.txt
index cc453110fc46..0732cdd05ba1 100644
--- a/Documentation/powerpc/dts-bindings/fsl/dma.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/dma.txt
@@ -35,30 +35,30 @@ Example:
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc8349-dma", "fsl,elo-dma";
- reg = <82a8 4>;
- ranges = <0 8100 1a4>;
+ reg = <0x82a8 4>;
+ ranges = <0 0x8100 0x1a4>;
interrupt-parent = <&ipic>;
- interrupts = <47 8>;
+ interrupts = <71 8>;
cell-index = <0>;
dma-channel@0 {
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
cell-index = <0>;
- reg = <0 80>;
+ reg = <0 0x80>;
};
dma-channel@80 {
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
cell-index = <1>;
- reg = <80 80>;
+ reg = <0x80 0x80>;
};
dma-channel@100 {
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
cell-index = <2>;
- reg = <100 80>;
+ reg = <0x100 0x80>;
};
dma-channel@180 {
compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
cell-index = <3>;
- reg = <180 80>;
+ reg = <0x180 0x80>;
};
};
@@ -93,36 +93,36 @@ Example:
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc8540-dma", "fsl,eloplus-dma";
- reg = <21300 4>;
- ranges = <0 21100 200>;
+ reg = <0x21300 4>;
+ ranges = <0 0x21100 0x200>;
cell-index = <0>;
dma-channel@0 {
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
- reg = <0 80>;
+ reg = <0 0x80>;
cell-index = <0>;
interrupt-parent = <&mpic>;
- interrupts = <14 2>;
+ interrupts = <20 2>;
};
dma-channel@80 {
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
- reg = <80 80>;
+ reg = <0x80 0x80>;
cell-index = <1>;
interrupt-parent = <&mpic>;
- interrupts = <15 2>;
+ interrupts = <21 2>;
};
dma-channel@100 {
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
- reg = <100 80>;
+ reg = <0x100 0x80>;
cell-index = <2>;
interrupt-parent = <&mpic>;
- interrupts = <16 2>;
+ interrupts = <22 2>;
};
dma-channel@180 {
compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
- reg = <180 80>;
+ reg = <0x180 0x80>;
cell-index = <3>;
interrupt-parent = <&mpic>;
- interrupts = <17 2>;
+ interrupts = <23 2>;
};
};
diff --git a/Documentation/powerpc/dts-bindings/fsl/esdhc.txt b/Documentation/powerpc/dts-bindings/fsl/esdhc.txt
new file mode 100644
index 000000000000..600846557763
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/fsl/esdhc.txt
@@ -0,0 +1,24 @@
+* Freescale Enhanced Secure Digital Host Controller (eSDHC)
+
+The Enhanced Secure Digital Host Controller provides an interface
+for MMC, SD, and SDIO types of memory cards.
+
+Required properties:
+ - compatible : should be
+ "fsl,<chip>-esdhc", "fsl,mpc8379-esdhc" for MPC83xx processors.
+ "fsl,<chip>-esdhc", "fsl,mpc8536-esdhc" for MPC85xx processors.
+ - reg : should contain eSDHC registers location and length.
+ - interrupts : should contain eSDHC interrupt.
+ - interrupt-parent : interrupt source phandle.
+ - clock-frequency : specifies eSDHC base clock frequency.
+
+Example:
+
+sdhci@2e000 {
+ compatible = "fsl,mpc8378-esdhc", "fsl,mpc8379-esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <42 0x8>;
+ interrupt-parent = <&ipic>;
+ /* Filled in by U-Boot */
+ clock-frequency = <0>;
+};
diff --git a/Documentation/powerpc/dts-bindings/fsl/ssi.txt b/Documentation/powerpc/dts-bindings/fsl/ssi.txt
index a2d963998a65..5ff76c9c57d2 100644
--- a/Documentation/powerpc/dts-bindings/fsl/ssi.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/ssi.txt
@@ -4,44 +4,56 @@ The SSI is a serial device that communicates with audio codecs. It can
be programmed in AC97, I2S, left-justified, or right-justified modes.
Required properties:
-- compatible : compatible list, containing "fsl,ssi"
-- cell-index : the SSI, <0> = SSI1, <1> = SSI2, and so on
-- reg : offset and length of the register set for the device
-- interrupts : <a b> where a is the interrupt number and b is a
- field that represents an encoding of the sense and
- level information for the interrupt. This should be
- encoded based on the information in section 2)
- depending on the type of interrupt controller you
- have.
-- interrupt-parent : the phandle for the interrupt controller that
- services interrupts for this device.
-- fsl,mode : the operating mode for the SSI interface
- "i2s-slave" - I2S mode, SSI is clock slave
- "i2s-master" - I2S mode, SSI is clock master
- "lj-slave" - left-justified mode, SSI is clock slave
- "lj-master" - l.j. mode, SSI is clock master
- "rj-slave" - right-justified mode, SSI is clock slave
- "rj-master" - r.j., SSI is clock master
- "ac97-slave" - AC97 mode, SSI is clock slave
- "ac97-master" - AC97 mode, SSI is clock master
-- fsl,playback-dma: phandle to a node for the DMA channel to use for
+- compatible: Compatible list, contains "fsl,ssi".
+- cell-index: The SSI, <0> = SSI1, <1> = SSI2, and so on.
+- reg: Offset and length of the register set for the device.
+- interrupts: <a b> where a is the interrupt number and b is a
+ field that represents an encoding of the sense and
+ level information for the interrupt. This should be
+ encoded based on the information in section 2)
+ depending on the type of interrupt controller you
+ have.
+- interrupt-parent: The phandle for the interrupt controller that
+ services interrupts for this device.
+- fsl,mode: The operating mode for the SSI interface.
+ "i2s-slave" - I2S mode, SSI is clock slave
+ "i2s-master" - I2S mode, SSI is clock master
+ "lj-slave" - left-justified mode, SSI is clock slave
+ "lj-master" - l.j. mode, SSI is clock master
+ "rj-slave" - right-justified mode, SSI is clock slave
+ "rj-master" - r.j., SSI is clock master
+ "ac97-slave" - AC97 mode, SSI is clock slave
+ "ac97-master" - AC97 mode, SSI is clock master
+- fsl,playback-dma: Phandle to a node for the DMA channel to use for
playback of audio. This is typically dictated by SOC
design. See the notes below.
-- fsl,capture-dma: phandle to a node for the DMA channel to use for
+- fsl,capture-dma: Phandle to a node for the DMA channel to use for
capture (recording) of audio. This is typically dictated
by SOC design. See the notes below.
+- fsl,fifo-depth: The number of elements in the transmit and receive FIFOs.
+ This number is the maximum allowed value for SFCSR[TFWM0].
+- fsl,ssi-asynchronous:
+ If specified, the SSI is to be programmed in asynchronous
+ mode. In this mode, pins SRCK, STCK, SRFS, and STFS must
+ all be connected to valid signals. In synchronous mode,
+ SRCK and SRFS are ignored. Asynchronous mode allows
+ playback and capture to use different sample sizes and
+ sample rates. Some drivers may require that SRCK and STCK
+ be connected together, and SRFS and STFS be connected
+ together. This would still allow different sample sizes,
+ but not different sample rates.
Optional properties:
-- codec-handle : phandle to a 'codec' node that defines an audio
- codec connected to this SSI. This node is typically
- a child of an I2C or other control node.
+- codec-handle: Phandle to a 'codec' node that defines an audio
+ codec connected to this SSI. This node is typically
+ a child of an I2C or other control node.
Child 'codec' node required properties:
-- compatible : compatible list, contains the name of the codec
+- compatible: Compatible list, contains the name of the codec
Child 'codec' node optional properties:
-- clock-frequency : The frequency of the input clock, which typically
- comes from an on-board dedicated oscillator.
+- clock-frequency: The frequency of the input clock, which typically comes
+ from an on-board dedicated oscillator.
Notes on fsl,playback-dma and fsl,capture-dma:
diff --git a/Documentation/powerpc/dts-bindings/fsl/tsec.txt b/Documentation/powerpc/dts-bindings/fsl/tsec.txt
index 7fa4b27574b5..edb7ae19e868 100644
--- a/Documentation/powerpc/dts-bindings/fsl/tsec.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/tsec.txt
@@ -56,6 +56,12 @@ Properties:
hardware.
- fsl,magic-packet : If present, indicates that the hardware supports
waking up via magic packet.
+ - bd-stash : If present, indicates that the hardware supports stashing
+ buffer descriptors in the L2.
+ - rx-stash-len : Denotes the number of bytes of a received buffer to stash
+ in the L2.
+ - rx-stash-idx : Denotes the index of the first byte from the received
+ buffer to stash in the L2.
Example:
ethernet@24000 {
diff --git a/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt b/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt
index 84a04d5eb8e6..a48b2cadc7f0 100644
--- a/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/upm-nand.txt
@@ -5,9 +5,21 @@ Required properties:
- reg : should specify localbus chip select and size used for the chip.
- fsl,upm-addr-offset : UPM pattern offset for the address latch.
- fsl,upm-cmd-offset : UPM pattern offset for the command latch.
-- gpios : may specify optional GPIO connected to the Ready-Not-Busy pin.
-Example:
+Optional properties:
+- fsl,upm-wait-flags : add chip-dependent short delays after running the
+ UPM pattern (0x1), after writing a data byte (0x2) or after
+ writing out a buffer (0x4).
+- fsl,upm-addr-line-cs-offsets : address offsets for multi-chip support.
+ The corresponding address lines are used to select the chip.
+- gpios : may specify optional GPIOs connected to the Ready-Not-Busy pins
+ (R/B#). For multi-chip devices, "n" GPIO definitions are required
+ according to the number of chips.
+- chip-delay : chip dependent delay for transfering data from array to
+ read registers (tR). Required if property "gpios" is not used
+ (R/B# pins not connected).
+
+Examples:
upm@1,0 {
compatible = "fsl,upm-nand";
@@ -26,3 +38,26 @@ upm@1,0 {
};
};
};
+
+upm@3,0 {
+ #address-cells = <0>;
+ #size-cells = <0>;
+ compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
+ reg = <3 0x0 0x800>;
+ fsl,upm-addr-offset = <0x10>;
+ fsl,upm-cmd-offset = <0x08>;
+ /* Multi-chip NAND device */
+ fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
+ fsl,upm-wait-flags = <0x5>;
+ chip-delay = <25>; // in micro-seconds
+
+ nand@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "fs";
+ reg = <0x00000000 0x10000000>;
+ };
+ };
+};
diff --git a/Documentation/powerpc/dts-bindings/gpio/led.txt b/Documentation/powerpc/dts-bindings/gpio/led.txt
index ff51f4c0fa9d..4fe14deedc0a 100644
--- a/Documentation/powerpc/dts-bindings/gpio/led.txt
+++ b/Documentation/powerpc/dts-bindings/gpio/led.txt
@@ -1,15 +1,43 @@
-LED connected to GPIO
+LEDs connected to GPIO lines
Required properties:
-- compatible : should be "gpio-led".
-- label : (optional) the label for this LED. If omitted, the label is
+- compatible : should be "gpio-leds".
+
+Each LED is represented as a sub-node of the gpio-leds device. Each
+node's name represents the name of the corresponding LED.
+
+LED sub-node properties:
+- gpios : Should specify the LED's GPIO, see "Specifying GPIO information
+ for devices" in Documentation/powerpc/booting-without-of.txt. Active
+ low LEDs should be indicated using flags in the GPIO specifier.
+- label : (optional) The label for this LED. If omitted, the label is
taken from the node name (excluding the unit address).
-- gpios : should specify LED GPIO.
+- linux,default-trigger : (optional) This parameter, if present, is a
+ string defining the trigger assigned to the LED. Current triggers are:
+ "backlight" - LED will act as a back-light, controlled by the framebuffer
+ system
+ "default-on" - LED will turn on
+ "heartbeat" - LED "double" flashes at a load average based rate
+ "ide-disk" - LED indicates disk activity
+ "timer" - LED flashes at a fixed, configurable rate
-Example:
+Examples:
-led@0 {
- compatible = "gpio-led";
- label = "hdd";
- gpios = <&mcu_pio 0 1>;
+leds {
+ compatible = "gpio-leds";
+ hdd {
+ label = "IDE Activity";
+ gpios = <&mcu_pio 0 1>; /* Active low */
+ linux,default-trigger = "ide-disk";
+ };
};
+
+run-control {
+ compatible = "gpio-leds";
+ red {
+ gpios = <&mpc8572 6 0>;
+ };
+ green {
+ gpios = <&mpc8572 7 0>;
+ };
+}
diff --git a/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt b/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt
new file mode 100644
index 000000000000..c39ac2891951
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/mmc-spi-slot.txt
@@ -0,0 +1,23 @@
+MMC/SD/SDIO slot directly connected to a SPI bus
+
+Required properties:
+- compatible : should be "mmc-spi-slot".
+- reg : should specify SPI address (chip-select number).
+- spi-max-frequency : maximum frequency for this device (Hz).
+- voltage-ranges : two cells are required, first cell specifies minimum
+ slot voltage (mV), second cell specifies maximum slot voltage (mV).
+ Several ranges could be specified.
+- gpios : (optional) may specify GPIOs in this order: Card-Detect GPIO,
+ Write-Protect GPIO.
+
+Example:
+
+ mmc-slot@0 {
+ compatible = "fsl,mpc8323rdb-mmc-slot",
+ "mmc-spi-slot";
+ reg = <0>;
+ gpios = <&qe_pio_d 14 1
+ &qe_pio_d 15 0>;
+ voltage-ranges = <3300 3300>;
+ spi-max-frequency = <50000000>;
+ };
diff --git a/Documentation/scheduler/00-INDEX b/Documentation/scheduler/00-INDEX
index aabcc3a089ba..3c00c9c3219e 100644
--- a/Documentation/scheduler/00-INDEX
+++ b/Documentation/scheduler/00-INDEX
@@ -2,8 +2,6 @@
- this file.
sched-arch.txt
- CPU Scheduler implementation hints for architecture specific code.
-sched-coding.txt
- - reference for various scheduler-related methods in the O(1) scheduler.
sched-design-CFS.txt
- goals, design and implementation of the Complete Fair Scheduler.
sched-domains.txt
diff --git a/Documentation/scheduler/sched-coding.txt b/Documentation/scheduler/sched-coding.txt
deleted file mode 100644
index cbd8db752acf..000000000000
--- a/Documentation/scheduler/sched-coding.txt
+++ /dev/null
@@ -1,126 +0,0 @@
- Reference for various scheduler-related methods in the O(1) scheduler
- Robert Love <rml@tech9.net>, MontaVista Software
-
-
-Note most of these methods are local to kernel/sched.c - this is by design.
-The scheduler is meant to be self-contained and abstracted away. This document
-is primarily for understanding the scheduler, not interfacing to it. Some of
-the discussed interfaces, however, are general process/scheduling methods.
-They are typically defined in include/linux/sched.h.
-
-
-Main Scheduling Methods
------------------------
-
-void load_balance(runqueue_t *this_rq, int idle)
- Attempts to pull tasks from one cpu to another to balance cpu usage,
- if needed. This method is called explicitly if the runqueues are
- imbalanced or periodically by the timer tick. Prior to calling,
- the current runqueue must be locked and interrupts disabled.
-
-void schedule()
- The main scheduling function. Upon return, the highest priority
- process will be active.
-
-
-Locking
--------
-
-Each runqueue has its own lock, rq->lock. When multiple runqueues need
-to be locked, lock acquires must be ordered by ascending &runqueue value.
-
-A specific runqueue is locked via
-
- task_rq_lock(task_t pid, unsigned long *flags)
-
-which disables preemption, disables interrupts, and locks the runqueue pid is
-running on. Likewise,
-
- task_rq_unlock(task_t pid, unsigned long *flags)
-
-unlocks the runqueue pid is running on, restores interrupts to their previous
-state, and reenables preemption.
-
-The routines
-
- double_rq_lock(runqueue_t *rq1, runqueue_t *rq2)
-
-and
-
- double_rq_unlock(runqueue_t *rq1, runqueue_t *rq2)
-
-safely lock and unlock, respectively, the two specified runqueues. They do
-not, however, disable and restore interrupts. Users are required to do so
-manually before and after calls.
-
-
-Values
-------
-
-MAX_PRIO
- The maximum priority of the system, stored in the task as task->prio.
- Lower priorities are higher. Normal (non-RT) priorities range from
- MAX_RT_PRIO to (MAX_PRIO - 1).
-MAX_RT_PRIO
- The maximum real-time priority of the system. Valid RT priorities
- range from 0 to (MAX_RT_PRIO - 1).
-MAX_USER_RT_PRIO
- The maximum real-time priority that is exported to user-space. Should
- always be equal to or less than MAX_RT_PRIO. Setting it less allows
- kernel threads to have higher priorities than any user-space task.
-MIN_TIMESLICE
-MAX_TIMESLICE
- Respectively, the minimum and maximum timeslices (quanta) of a process.
-
-Data
-----
-
-struct runqueue
- The main per-CPU runqueue data structure.
-struct task_struct
- The main per-process data structure.
-
-
-General Methods
----------------
-
-cpu_rq(cpu)
- Returns the runqueue of the specified cpu.
-this_rq()
- Returns the runqueue of the current cpu.
-task_rq(pid)
- Returns the runqueue which holds the specified pid.
-cpu_curr(cpu)
- Returns the task currently running on the given cpu.
-rt_task(pid)
- Returns true if pid is real-time, false if not.
-
-
-Process Control Methods
------------------------
-
-void set_user_nice(task_t *p, long nice)
- Sets the "nice" value of task p to the given value.
-int setscheduler(pid_t pid, int policy, struct sched_param *param)
- Sets the scheduling policy and parameters for the given pid.
-int set_cpus_allowed(task_t *p, unsigned long new_mask)
- Sets a given task's CPU affinity and migrates it to a proper cpu.
- Callers must have a valid reference to the task and assure the
- task not exit prematurely. No locks can be held during the call.
-set_task_state(tsk, state_value)
- Sets the given task's state to the given value.
-set_current_state(state_value)
- Sets the current task's state to the given value.
-void set_tsk_need_resched(struct task_struct *tsk)
- Sets need_resched in the given task.
-void clear_tsk_need_resched(struct task_struct *tsk)
- Clears need_resched in the given task.
-void set_need_resched()
- Sets need_resched in the current task.
-void clear_need_resched()
- Clears need_resched in the current task.
-int need_resched()
- Returns true if need_resched is set in the current task, false
- otherwise.
-yield()
- Place the current process at the end of the runqueue and call schedule.
diff --git a/Documentation/scheduler/sched-rt-group.txt b/Documentation/scheduler/sched-rt-group.txt
index 3ef339f491e0..5ba4d3fc625a 100644
--- a/Documentation/scheduler/sched-rt-group.txt
+++ b/Documentation/scheduler/sched-rt-group.txt
@@ -126,7 +126,7 @@ This uses the /cgroup virtual file system and "/cgroup/<cgroup>/cpu.rt_runtime_u
to control the CPU time reserved for each control group instead.
For more information on working with control groups, you should read
-Documentation/cgroups.txt as well.
+Documentation/cgroups/cgroups.txt as well.
Group settings are checked against the following limits in order to keep the configuration
schedulable:
diff --git a/Documentation/scsi/aacraid.txt b/Documentation/scsi/aacraid.txt
index ddace3afc83b..30f643f611b2 100644
--- a/Documentation/scsi/aacraid.txt
+++ b/Documentation/scsi/aacraid.txt
@@ -60,17 +60,9 @@ Supported Cards/Chipsets
9005:0285:9005:02d5 Adaptec ASR-2405 (Voodoo40 Lite)
9005:0285:9005:02d6 Adaptec ASR-2445 (Voodoo44 Lite)
9005:0285:9005:02d7 Adaptec ASR-2805 (Voodoo80 Lite)
- 9005:0285:9005:02d8 Adaptec 5405G (Voodoo40 PM)
- 9005:0285:9005:02d9 Adaptec 5445G (Voodoo44 PM)
- 9005:0285:9005:02da Adaptec 5805G (Voodoo80 PM)
- 9005:0285:9005:02db Adaptec 5085G (Voodoo08 PM)
- 9005:0285:9005:02dc Adaptec 51245G (Voodoo124 PM)
- 9005:0285:9005:02dd Adaptec 51645G (Voodoo164 PM)
- 9005:0285:9005:02de Adaptec 52445G (Voodoo244 PM)
- 9005:0285:9005:02df Adaptec ASR-2045G (Voodoo04 Lite PM)
- 9005:0285:9005:02e0 Adaptec ASR-2405G (Voodoo40 Lite PM)
- 9005:0285:9005:02e1 Adaptec ASR-2445G (Voodoo44 Lite PM)
- 9005:0285:9005:02e2 Adaptec ASR-2805G (Voodoo80 Lite PM)
+ 9005:0285:9005:02d8 Adaptec 5405Z (Voodoo40 BLBU)
+ 9005:0285:9005:02d9 Adaptec 5445Z (Voodoo44 BLBU)
+ 9005:0285:9005:02da Adaptec 5805Z (Voodoo80 BLBU)
1011:0046:9005:0364 Adaptec 5400S (Mustang)
1011:0046:9005:0365 Adaptec 5400S (Mustang)
9005:0287:9005:0800 Adaptec Themisto (Jupiter)
@@ -140,6 +132,7 @@ Deanna Bonds (non-DASD support, PAE fibs and 64 bit,
where fibs that go to the hardware are consistently called hw_fibs and
not just fibs like the name of the driver tracking structure)
Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas. Performance tuning, card failover and bug mitigations.
+Achim Leubner <Achim_Leubner@adaptec.com>
Original Driver
-------------------------
diff --git a/Documentation/scsi/osd.txt b/Documentation/scsi/osd.txt
new file mode 100644
index 000000000000..da162f7fd5f5
--- /dev/null
+++ b/Documentation/scsi/osd.txt
@@ -0,0 +1,198 @@
+The OSD Standard
+================
+OSD (Object-Based Storage Device) is a T10 SCSI command set that is designed
+to provide efficient operation of input/output logical units that manage the
+allocation, placement, and accessing of variable-size data-storage containers,
+called objects. Objects are intended to contain operating system and application
+constructs. Each object has associated attributes attached to it, which are
+integral part of the object and provide metadata about the object. The standard
+defines some common obligatory attributes, but user attributes can be added as
+needed.
+
+See: http://www.t10.org/ftp/t10/drafts/osd2/ for the latest draft for OSD 2
+or search the web for "OSD SCSI"
+
+OSD in the Linux Kernel
+=======================
+osd-initiator:
+ The main component of OSD in Kernel is the osd-initiator library. Its main
+user is intended to be the pNFS-over-objects layout driver, which uses objects
+as its back-end data storage. Other clients are the other osd parts listed below.
+
+osd-uld:
+ This is a SCSI ULD that registers for OSD type devices and provides a testing
+platform, both for the in-kernel initiator as well as connected targets. It
+currently has no useful user-mode API, though it could have if need be.
+
+exofs:
+ Is an OSD based Linux file system. It uses the osd-initiator and osd-uld,
+to export a usable file system for users.
+See Documentation/filesystems/exofs.txt for more details
+
+osd target:
+ There are no current plans for an OSD target implementation in kernel. For all
+needs, a user-mode target that is based on the scsi tgt target framework is
+available from Ohio Supercomputer Center (OSC) at:
+http://www.open-osd.org/bin/view/Main/OscOsdProject
+There are several other target implementations. See http://open-osd.org for more
+links.
+
+Files and Folders
+=================
+This is the complete list of files included in this work:
+include/scsi/
+ osd_initiator.h Main API for the initiator library
+ osd_types.h Common OSD types
+ osd_sec.h Security Manager API
+ osd_protocol.h Wire definitions of the OSD standard protocol
+ osd_attributes.h Wire definitions of OSD attributes
+
+drivers/scsi/osd/
+ osd_initiator.c OSD-Initiator library implementation
+ osd_uld.c The OSD scsi ULD
+ osd_ktest.{h,c} In-kernel test suite (called by osd_uld)
+ osd_debug.h Some printk macros
+ Makefile For both in-tree and out-of-tree compilation
+ Kconfig Enables inclusion of the different pieces
+ osd_test.c User-mode application to call the kernel tests
+
+The OSD-Initiator Library
+=========================
+osd_initiator is a low level implementation of an osd initiator encoder.
+But even though, it should be intuitive and easy to use. Perhaps over time an
+higher lever will form that automates some of the more common recipes.
+
+init/fini:
+- osd_dev_init() associates a scsi_device with an osd_dev structure
+ and initializes some global pools. This should be done once per scsi_device
+ (OSD LUN). The osd_dev structure is needed for calling osd_start_request().
+
+- osd_dev_fini() cleans up before a osd_dev/scsi_device destruction.
+
+OSD commands encoding, execution, and decoding of results:
+
+struct osd_request's is used to iteratively encode an OSD command and carry
+its state throughout execution. Each request goes through these stages:
+
+a. osd_start_request() allocates the request.
+
+b. Any of the osd_req_* methods is used to encode a request of the specified
+ type.
+
+c. osd_req_add_{get,set}_attr_* may be called to add get/set attributes to the
+ CDB. "List" or "Page" mode can be used exclusively. The attribute-list API
+ can be called multiple times on the same request. However, only one
+ attribute-page can be read, as mandated by the OSD standard.
+
+d. osd_finalize_request() computes offsets into the data-in and data-out buffers
+ and signs the request using the provided capability key and integrity-
+ check parameters.
+
+e. osd_execute_request() may be called to execute the request via the block
+ layer and wait for its completion. The request can be executed
+ asynchronously by calling the block layer API directly.
+
+f. After execution, osd_req_decode_sense() can be called to decode the request's
+ sense information.
+
+g. osd_req_decode_get_attr() may be called to retrieve osd_add_get_attr_list()
+ values.
+
+h. osd_end_request() must be called to deallocate the request and any resource
+ associated with it. Note that osd_end_request cleans up the request at any
+ stage and it must always be called after a successful osd_start_request().
+
+osd_request's structure:
+
+The OSD standard defines a complex structure of IO segments pointed to by
+members in the CDB. Up to 3 segments can be deployed in the IN-Buffer and up to
+4 in the OUT-Buffer. The ASCII illustration below depicts a secure-read with
+associated get+set of attributes-lists. Other combinations very on the same
+basic theme. From no-segments-used up to all-segments-used.
+
+|________OSD-CDB__________|
+| |
+|read_len (offset=0) -|---------\
+| | |
+|get_attrs_list_length | |
+|get_attrs_list_offset -|----\ |
+| | | |
+|retrieved_attrs_alloc_len| | |
+|retrieved_attrs_offset -|----|----|-\
+| | | | |
+|set_attrs_list_length | | | |
+|set_attrs_list_offset -|-\ | | |
+| | | | | |
+|in_data_integ_offset -|-|--|----|-|-\
+|out_data_integ_offset -|-|--|--\ | | |
+\_________________________/ | | | | | |
+ | | | | | |
+|_______OUT-BUFFER________| | | | | | |
+| Set attr list |</ | | | | |
+| | | | | | |
+|-------------------------| | | | | |
+| Get attr descriptors |<---/ | | | |
+| | | | | |
+|-------------------------| | | | |
+| Out-data integrity |<------/ | | |
+| | | | |
+\_________________________/ | | |
+ | | |
+|________IN-BUFFER________| | | |
+| In-Data read |<--------/ | |
+| | | |
+|-------------------------| | |
+| Get attr list |<----------/ |
+| | |
+|-------------------------| |
+| In-data integrity |<------------/
+| |
+\_________________________/
+
+A block device request can carry bidirectional payload by means of associating
+a bidi_read request with a main write-request. Each in/out request is described
+by a chain of BIOs associated with each request.
+The CDB is of a SCSI VARLEN CDB format, as described by OSD standard.
+The OSD standard also mandates alignment restrictions at start of each segment.
+
+In the code, in struct osd_request, there are two _osd_io_info structures to
+describe the IN/OUT buffers above, two BIOs for the data payload and up to five
+_osd_req_data_segment structures to hold the different segments allocation and
+information.
+
+Important: We have chosen to disregard the assumption that a BIO-chain (and
+the resulting sg-list) describes a linear memory buffer. Meaning only first and
+last scatter chain can be incomplete and all the middle chains are of PAGE_SIZE.
+For us, a scatter-gather-list, as its name implies and as used by the Networking
+layer, is to describe a vector of buffers that will be transferred to/from the
+wire. It works very well with current iSCSI transport. iSCSI is currently the
+only deployed OSD transport. In the future we anticipate SAS and FC attached OSD
+devices as well.
+
+The OSD Testing ULD
+===================
+TODO: More user-mode control on tests.
+
+Authors, Mailing list
+=====================
+Please communicate with us on any deployment of osd, whether using this code
+or not.
+
+Any problems, questions, bug reports, lonely OSD nights, please email:
+ OSD Dev List <osd-dev@open-osd.org>
+
+More up-to-date information can be found on:
+http://open-osd.org
+
+Boaz Harrosh <bharrosh@panasas.com>
+Benny Halevy <bhalevy@panasas.com>
+
+References
+==========
+Weber, R., "SCSI Object-Based Storage Device Commands",
+T10/1355-D ANSI/INCITS 400-2004,
+http://www.t10.org/ftp/t10/drafts/osd/osd-r10.pdf
+
+Weber, R., "SCSI Object-Based Storage Device Commands -2 (OSD-2)"
+T10/1729-D, Working Draft, rev. 3
+http://www.t10.org/ftp/t10/drafts/osd2/osd2r03.pdf
diff --git a/Documentation/slow-work.txt b/Documentation/slow-work.txt
new file mode 100644
index 000000000000..ebc50f808ea4
--- /dev/null
+++ b/Documentation/slow-work.txt
@@ -0,0 +1,174 @@
+ ====================================
+ SLOW WORK ITEM EXECUTION THREAD POOL
+ ====================================
+
+By: David Howells <dhowells@redhat.com>
+
+The slow work item execution thread pool is a pool of threads for performing
+things that take a relatively long time, such as making mkdir calls.
+Typically, when processing something, these items will spend a lot of time
+blocking a thread on I/O, thus making that thread unavailable for doing other
+work.
+
+The standard workqueue model is unsuitable for this class of work item as that
+limits the owner to a single thread or a single thread per CPU. For some
+tasks, however, more threads - or fewer - are required.
+
+There is just one pool per system. It contains no threads unless something
+wants to use it - and that something must register its interest first. When
+the pool is active, the number of threads it contains is dynamic, varying
+between a maximum and minimum setting, depending on the load.
+
+
+====================
+CLASSES OF WORK ITEM
+====================
+
+This pool support two classes of work items:
+
+ (*) Slow work items.
+
+ (*) Very slow work items.
+
+The former are expected to finish much quicker than the latter.
+
+An operation of the very slow class may do a batch combination of several
+lookups, mkdirs, and a create for instance.
+
+An operation of the ordinarily slow class may, for example, write stuff or
+expand files, provided the time taken to do so isn't too long.
+
+Operations of both types may sleep during execution, thus tying up the thread
+loaned to it.
+
+
+THREAD-TO-CLASS ALLOCATION
+--------------------------
+
+Not all the threads in the pool are available to work on very slow work items.
+The number will be between one and one fewer than the number of active threads.
+This is configurable (see the "Pool Configuration" section).
+
+All the threads are available to work on ordinarily slow work items, but a
+percentage of the threads will prefer to work on very slow work items.
+
+The configuration ensures that at least one thread will be available to work on
+very slow work items, and at least one thread will be available that won't work
+on very slow work items at all.
+
+
+=====================
+USING SLOW WORK ITEMS
+=====================
+
+Firstly, a module or subsystem wanting to make use of slow work items must
+register its interest:
+
+ int ret = slow_work_register_user();
+
+This will return 0 if successful, or a -ve error upon failure.
+
+
+Slow work items may then be set up by:
+
+ (1) Declaring a slow_work struct type variable:
+
+ #include <linux/slow-work.h>
+
+ struct slow_work myitem;
+
+ (2) Declaring the operations to be used for this item:
+
+ struct slow_work_ops myitem_ops = {
+ .get_ref = myitem_get_ref,
+ .put_ref = myitem_put_ref,
+ .execute = myitem_execute,
+ };
+
+ [*] For a description of the ops, see section "Item Operations".
+
+ (3) Initialising the item:
+
+ slow_work_init(&myitem, &myitem_ops);
+
+ or:
+
+ vslow_work_init(&myitem, &myitem_ops);
+
+ depending on its class.
+
+A suitably set up work item can then be enqueued for processing:
+
+ int ret = slow_work_enqueue(&myitem);
+
+This will return a -ve error if the thread pool is unable to gain a reference
+on the item, 0 otherwise.
+
+
+The items are reference counted, so there ought to be no need for a flush
+operation. When all a module's slow work items have been processed, and the
+module has no further interest in the facility, it should unregister its
+interest:
+
+ slow_work_unregister_user();
+
+
+===============
+ITEM OPERATIONS
+===============
+
+Each work item requires a table of operations of type struct slow_work_ops.
+All members are required:
+
+ (*) Get a reference on an item:
+
+ int (*get_ref)(struct slow_work *work);
+
+ This allows the thread pool to attempt to pin an item by getting a
+ reference on it. This function should return 0 if the reference was
+ granted, or a -ve error otherwise. If an error is returned,
+ slow_work_enqueue() will fail.
+
+ The reference is held whilst the item is queued and whilst it is being
+ executed. The item may then be requeued with the same reference held, or
+ the reference will be released.
+
+ (*) Release a reference on an item:
+
+ void (*put_ref)(struct slow_work *work);
+
+ This allows the thread pool to unpin an item by releasing the reference on
+ it. The thread pool will not touch the item again once this has been
+ called.
+
+ (*) Execute an item:
+
+ void (*execute)(struct slow_work *work);
+
+ This should perform the work required of the item. It may sleep, it may
+ perform disk I/O and it may wait for locks.
+
+
+==================
+POOL CONFIGURATION
+==================
+
+The slow-work thread pool has a number of configurables:
+
+ (*) /proc/sys/kernel/slow-work/min-threads
+
+ The minimum number of threads that should be in the pool whilst it is in
+ use. This may be anywhere between 2 and max-threads.
+
+ (*) /proc/sys/kernel/slow-work/max-threads
+
+ The maximum number of threads that should in the pool. This may be
+ anywhere between min-threads and 255 or NR_CPUS * 2, whichever is greater.
+
+ (*) /proc/sys/kernel/slow-work/vslow-percentage
+
+ The percentage of active threads in the pool that may be used to execute
+ very slow work items. This may be between 1 and 99. The resultant number
+ is bounded to between 1 and one fewer than the number of active threads.
+ This ensures there is always at least one thread that can process very
+ slow work items, and always at least one thread that won't.
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 841a9365d5fd..012858d2b119 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -346,6 +346,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
sbirq - IRQ # for CMI8330 chip (SB16)
sbdma8 - 8bit DMA # for CMI8330 chip (SB16)
sbdma16 - 16bit DMA # for CMI8330 chip (SB16)
+ fmport - (optional) OPL3 I/O port
+ mpuport - (optional) MPU401 I/O port
+ mpuirq - (optional) MPU401 irq #
This module supports multiple cards and autoprobe.
@@ -388,34 +391,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
The power-management is supported.
- Module snd-cs4232
- -----------------
-
- Module for sound cards based on CS4232/CS4232A ISA chips.
-
- isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
-
- with isapnp=0, the following options are available:
-
- port - port # for CS4232 chip (PnP setup - 0x534)
- cport - control port # for CS4232 chip (PnP setup - 0x120,0x210,0xf00)
- mpu_port - port # for MPU-401 UART (PnP setup - 0x300), -1 = disable
- fm_port - FM port # for CS4232 chip (PnP setup - 0x388), -1 = disable
- irq - IRQ # for CS4232 chip (5,7,9,11,12,15)
- mpu_irq - IRQ # for MPU-401 UART (9,11,12,15)
- dma1 - first DMA # for CS4232 chip (0,1,3)
- dma2 - second DMA # for Yamaha CS4232 chip (0,1,3), -1 = disable
-
- This module supports multiple cards. This module does not support autoprobe
- (if ISA PnP is not used) thus main port must be specified!!! Other ports are
- optional.
-
- The power-management is supported.
-
Module snd-cs4236
-----------------
- Module for sound cards based on CS4235/CS4236/CS4236B/CS4237B/
+ Module for sound cards based on CS4232/CS4232A,
+ CS4235/CS4236/CS4236B/CS4237B/
CS4238B/CS4239 ISA chips.
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
@@ -437,6 +417,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
The power-management is supported.
+ This module is aliased as snd-cs4232 since it provides the old
+ snd-cs4232 functionality, too.
+
Module snd-cs4281
-----------------
@@ -606,6 +589,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for ESS AudioDrive ES-1688 and ES-688 sound cards.
port - port # for ES-1688 chip (0x220,0x240,0x260)
+ fm_port - port # for OPL3 (option; share the same port as default)
mpu_port - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default)
irq - IRQ # for ES-1688 chip (5,7,9,10)
mpu_irq - IRQ # for MPU-401 port (5,7,9,10)
@@ -757,6 +741,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
model - force the model name
position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF)
probe_mask - Bitmask to probe codecs (default = -1, meaning all slots)
+ When the bit 8 (0x100) is set, the lower 8 bits are used
+ as the "fixed" codec slots; i.e. the driver probes the
+ slots regardless what hardware reports back
probe_only - Only probing and no codec initialization (default=off);
Useful to check the initial codec status for debugging
bdl_pos_adj - Specifies the DMA IRQ timing delay in samples.
@@ -1185,6 +1172,54 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
This module supports multiple devices and PnP.
+ Module snd-msnd-classic
+ -----------------------
+
+ Module for Turtle Beach MultiSound Classic, Tahiti or Monterey
+ soundcards.
+
+ io - Port # for msnd-classic card
+ irq - IRQ # for msnd-classic card
+ mem - Memory address (0xb0000, 0xc8000, 0xd0000, 0xd8000,
+ 0xe0000 or 0xe8000)
+ write_ndelay - enable write ndelay (default = 1)
+ calibrate_signal - calibrate signal (default = 0)
+ isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
+ digital - Digital daughterboard present (default = 0)
+ cfg - Config port (0x250, 0x260 or 0x270) default = PnP
+ reset - Reset all devices
+ mpu_io - MPU401 I/O port
+ mpu_irq - MPU401 irq#
+ ide_io0 - IDE port #0
+ ide_io1 - IDE port #1
+ ide_irq - IDE irq#
+ joystick_io - Joystick I/O port
+
+ The driver requires firmware files "turtlebeach/msndinit.bin" and
+ "turtlebeach/msndperm.bin" in the proper firmware directory.
+
+ See Documentation/sound/oss/MultiSound for important information
+ about this driver. Note that it has been discontinued, but the
+ Voyetra Turtle Beach knowledge base entry for it is still available
+ at
+ http://www.turtlebeach.com/site/kb_ftp/790.asp
+
+ Module snd-msnd-pinnacle
+ ------------------------
+
+ Module for Turtle Beach MultiSound Pinnacle/Fiji soundcards.
+
+ io - Port # for pinnacle/fiji card
+ irq - IRQ # for pinnalce/fiji card
+ mem - Memory address (0xb0000, 0xc8000, 0xd0000, 0xd8000,
+ 0xe0000 or 0xe8000)
+ write_ndelay - enable write ndelay (default = 1)
+ calibrate_signal - calibrate signal (default = 0)
+ isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
+
+ The driver requires firmware files "turtlebeach/pndspini.bin" and
+ "turtlebeach/pndsperm.bin" in the proper firmware directory.
+
Module snd-mtpav
----------------
@@ -1824,7 +1859,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
-------------------
Module for sound cards based on the Asus AV100/AV200 chips,
- i.e., Xonar D1, DX, D2, D2X and HDAV1.3 (Deluxe).
+ i.e., Xonar D1, DX, D2, D2X, HDAV1.3 (Deluxe), and Essence STX.
This module supports autoprobe and multiple cards.
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 0f5d26bea80f..8eec05bc079e 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -56,6 +56,7 @@ ALC262
sony-assamd Sony ASSAMD
toshiba-s06 Toshiba S06
toshiba-rx1 Toshiba RX1
+ tyan Tyan Thunder n6650W (S2915-E)
ultra Samsung Q1 Ultra Vista model
lenovo-3000 Lenovo 3000 y410
nec NEC Versa S9100
@@ -261,6 +262,8 @@ Conexant 5051
=============
laptop Basic Laptop config (default)
hp HP Spartan laptop
+ hp-dv6736 HP dv6736
+ lenovo-x200 Lenovo X200 laptop
STAC9200
========
@@ -278,6 +281,7 @@ STAC9200
gateway-m4 Gateway laptops with EAPD control
gateway-m4-2 Gateway laptops with EAPD control
panasonic Panasonic CF-74
+ auto BIOS setup (default)
STAC9205/9254
=============
@@ -285,6 +289,8 @@ STAC9205/9254
dell-m42 Dell (unknown)
dell-m43 Dell Precision
dell-m44 Dell Inspiron
+ eapd Keep EAPD on (e.g. Gateway T1616)
+ auto BIOS setup (default)
STAC9220/9221
=============
@@ -308,6 +314,7 @@ STAC9220/9221
dell-d82 Dell (unknown)
dell-m81 Dell (unknown)
dell-m82 Dell XPS M1210
+ auto BIOS setup (default)
STAC9202/9250/9251
==================
@@ -319,6 +326,7 @@ STAC9202/9250/9251
m3 Some Gateway MX series laptops
m5 Some Gateway MX series laptops (MP6954)
m6 Some Gateway NX series laptops
+ auto BIOS setup (default)
STAC9227/9228/9229/927x
=======================
@@ -328,6 +336,7 @@ STAC9227/9228/9229/927x
5stack D965 5stack + SPDIF
dell-3stack Dell Dimension E520
dell-bios Fixes with Dell BIOS setup
+ auto BIOS setup (default)
STAC92HD71B*
============
@@ -335,7 +344,10 @@ STAC92HD71B*
dell-m4-1 Dell desktops
dell-m4-2 Dell desktops
dell-m4-3 Dell desktops
- hp-m4 HP dv laptops
+ hp-m4 HP mini 1000
+ hp-dv5 HP dv series
+ hp-hdx HP HDX series
+ auto BIOS setup (default)
STAC92HD73*
===========
@@ -345,13 +357,16 @@ STAC92HD73*
dell-m6-dmic Dell desktops/laptops with digital mics
dell-m6 Dell desktops/laptops with both type of mics
dell-eq Dell desktops/laptops
+ auto BIOS setup (default)
STAC92HD83*
===========
ref Reference board
mic-ref Reference board with power managment for ports
+ dell-s14 Dell laptop
+ auto BIOS setup (default)
STAC9872
========
- vaio Setup for VAIO FE550G/SZ110
- vaio-ar Setup for VAIO AR
+ vaio VAIO laptop without SPDIF
+ auto BIOS setup (default)
diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt
index 8d68fff71839..c5948f2f9a25 100644
--- a/Documentation/sound/alsa/HD-Audio.txt
+++ b/Documentation/sound/alsa/HD-Audio.txt
@@ -109,6 +109,13 @@ slot, pass `probe_mask=1`. For the first and the third slots, pass
Since 2.6.29 kernel, the driver has a more robust probing method, so
this error might happen rarely, though.
+On a machine with a broken BIOS, sometimes you need to force the
+driver to probe the codec slots the hardware doesn't report for use.
+In such a case, turn the bit 8 (0x100) of `probe_mask` option on.
+Then the rest 8 bits are passed as the codec slots to probe
+unconditionally. For example, `probe_mask=0x103` will force to probe
+the codec slots 0 and 1 no matter what the hardware reports.
+
Interrupt Handling
~~~~~~~~~~~~~~~~~~
@@ -358,10 +365,26 @@ modelname::
to this file.
init_verbs::
The extra verbs to execute at initialization. You can add a verb by
- writing to this file. Pass tree numbers, nid, verb and parameter.
+ writing to this file. Pass three numbers: nid, verb and parameter
+ (separated with a space).
hints::
- Shows hint strings for codec parsers for any use. Right now it's
- not used.
+ Shows / stores hint strings for codec parsers for any use.
+ Its format is `key = value`. For example, passing `hp_detect = yes`
+ to IDT/STAC codec parser will result in the disablement of the
+ headphone detection.
+init_pin_configs::
+ Shows the initial pin default config values set by BIOS.
+driver_pin_configs::
+ Shows the pin default values set by the codec parser explicitly.
+ This doesn't show all pin values but only the changed values by
+ the parser. That is, if the parser doesn't change the pin default
+ config values by itself, this will contain nothing.
+user_pin_configs::
+ Shows the pin default config values to override the BIOS setup.
+ Writing this (with two numbers, NID and value) appends the new
+ value. The given will be used instead of the initial BIOS value at
+ the next reconfiguration time. Note that this config will override
+ even the driver pin configs, too.
reconfig::
Triggers the codec re-configuration. When any value is written to
this file, the driver re-initialize and parses the codec tree
@@ -371,6 +394,14 @@ clear::
Resets the codec, removes the mixer elements and PCM stuff of the
specified codec, and clear all init verbs and hints.
+For example, when you want to change the pin default configuration
+value of the pin widget 0x14 to 0x9993013f, and let the driver
+re-configure based on that state, run like below:
+------------------------------------------------------------------------
+ # echo 0x14 0x9993013f > /sys/class/sound/hwC0D0/user_pin_configs
+ # echo 1 > /sys/class/sound/hwC0D0/reconfig
+------------------------------------------------------------------------
+
Power-Saving
~~~~~~~~~~~~
@@ -461,6 +492,16 @@ run with `--no-upload` option, and attach the generated file.
There are some other useful options. See `--help` option output for
details.
+When a probe error occurs or when the driver obviously assigns a
+mismatched model, it'd be helpful to load the driver with
+`probe_only=1` option (at best after the cold reboot) and run
+alsa-info at this state. With this option, the driver won't configure
+the mixer and PCM but just tries to probe the codec slot. After
+probing, the proc file is available, so you can get the raw codec
+information before modified by the driver. Of course, the driver
+isn't usable with `probe_only=1`. But you can continue the
+configuration via hwdep sysfs file if hda-reconfig option is enabled.
+
hda-verb
~~~~~~~~
diff --git a/Documentation/sound/alsa/soc/dapm.txt b/Documentation/sound/alsa/soc/dapm.txt
index 46f9684d0b29..9e6763264a2e 100644
--- a/Documentation/sound/alsa/soc/dapm.txt
+++ b/Documentation/sound/alsa/soc/dapm.txt
@@ -116,6 +116,9 @@ SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls,
ARRAY_SIZE(wm8731_output_mixer_controls)),
+If you dont want the mixer elements prefixed with the name of the mixer widget,
+you can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same
+as for SND_SOC_DAPM_MIXER.
2.3 Platform/Machine domain Widgets
-----------------------------------
diff --git a/Documentation/sound/oss/CS4232 b/Documentation/sound/oss/CS4232
deleted file mode 100644
index 7d6af7a5c1c2..000000000000
--- a/Documentation/sound/oss/CS4232
+++ /dev/null
@@ -1,23 +0,0 @@
-To configure the Crystal CS423x sound chip and activate its DSP functions,
-modules may be loaded in this order:
-
- modprobe sound
- insmod ad1848
- insmod uart401
- insmod cs4232 io=* irq=* dma=* dma2=*
-
-This is the meaning of the parameters:
-
- io--I/O address of the Windows Sound System (normally 0x534)
- irq--IRQ of this device
- dma and dma2--DMA channels (DMA2 may be 0)
-
-On some cards, the board attempts to do non-PnP setup, and fails. If you
-have problems, use Linux' PnP facilities.
-
-To get MIDI facilities add
-
- insmod opl3 io=*
-
-where "io" is the I/O address of the OPL3 synthesizer. This will be shown
-in /proc/sys/pnp and is normally 0x388.
diff --git a/Documentation/sound/oss/Introduction b/Documentation/sound/oss/Introduction
index f04ba6bb7395..75d967ff9266 100644
--- a/Documentation/sound/oss/Introduction
+++ b/Documentation/sound/oss/Introduction
@@ -80,7 +80,7 @@ Notes:
additional features.
2. The commercial OSS driver may be obtained from the site:
- http://www/opensound.com. This may be used for cards that
+ http://www.opensound.com. This may be used for cards that
are unsupported by the kernel driver, or may be used
by other operating systems.
diff --git a/Documentation/sysctl/00-INDEX b/Documentation/sysctl/00-INDEX
index a20a9066dc4c..1286f455992f 100644
--- a/Documentation/sysctl/00-INDEX
+++ b/Documentation/sysctl/00-INDEX
@@ -10,6 +10,8 @@ fs.txt
- documentation for /proc/sys/fs/*.
kernel.txt
- documentation for /proc/sys/kernel/*.
+net.txt
+ - documentation for /proc/sys/net/*.
sunrpc.txt
- documentation for /proc/sys/sunrpc/*.
vm.txt
diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt
index f99254327ae5..1458448436cc 100644
--- a/Documentation/sysctl/fs.txt
+++ b/Documentation/sysctl/fs.txt
@@ -1,5 +1,6 @@
Documentation for /proc/sys/fs/* kernel version 2.2.10
(c) 1998, 1999, Rik van Riel <riel@nl.linux.org>
+ (c) 2009, Shen Feng<shen@cn.fujitsu.com>
For general info and legal blurb, please look in README.
@@ -14,7 +15,12 @@ kernel. Since some of the files _can_ be used to screw up your
system, it is advisable to read both documentation and source
before actually making adjustments.
+1. /proc/sys/fs
+----------------------------------------------------------
+
Currently, these files are in /proc/sys/fs:
+- aio-max-nr
+- aio-nr
- dentry-state
- dquot-max
- dquot-nr
@@ -30,8 +36,15 @@ Currently, these files are in /proc/sys/fs:
- super-max
- super-nr
-Documentation for the files in /proc/sys/fs/binfmt_misc is
-in Documentation/binfmt_misc.txt.
+==============================================================
+
+aio-nr & aio-max-nr:
+
+aio-nr is the running total of the number of events specified on the
+io_setup system call for all currently active aio contexts. If aio-nr
+reaches aio-max-nr then io_setup will fail with EAGAIN. Note that
+raising aio-max-nr does not result in the pre-allocation or re-sizing
+of any kernel data structures.
==============================================================
@@ -178,3 +191,60 @@ requests. aio-max-nr allows you to change the maximum value
aio-nr can grow to.
==============================================================
+
+
+2. /proc/sys/fs/binfmt_misc
+----------------------------------------------------------
+
+Documentation for the files in /proc/sys/fs/binfmt_misc is
+in Documentation/binfmt_misc.txt.
+
+
+3. /proc/sys/fs/mqueue - POSIX message queues filesystem
+----------------------------------------------------------
+
+The "mqueue" filesystem provides the necessary kernel features to enable the
+creation of a user space library that implements the POSIX message queues
+API (as noted by the MSG tag in the POSIX 1003.1-2001 version of the System
+Interfaces specification.)
+
+The "mqueue" filesystem contains values for determining/setting the amount of
+resources used by the file system.
+
+/proc/sys/fs/mqueue/queues_max is a read/write file for setting/getting the
+maximum number of message queues allowed on the system.
+
+/proc/sys/fs/mqueue/msg_max is a read/write file for setting/getting the
+maximum number of messages in a queue value. In fact it is the limiting value
+for another (user) limit which is set in mq_open invocation. This attribute of
+a queue must be less or equal then msg_max.
+
+/proc/sys/fs/mqueue/msgsize_max is a read/write file for setting/getting the
+maximum message size value (it is every message queue's attribute set during
+its creation).
+
+
+4. /proc/sys/fs/epoll - Configuration options for the epoll interface
+--------------------------------------------------------
+
+This directory contains configuration options for the epoll(7) interface.
+
+max_user_instances
+------------------
+
+This is the maximum number of epoll file descriptors that a single user can
+have open at a given time. The default value is 128, and should be enough
+for normal users.
+
+max_user_watches
+----------------
+
+Every epoll file descriptor can store a number of files to be monitored
+for event readiness. Each one of these monitored files constitutes a "watch".
+This configuration option sets the maximum number of "watches" that are
+allowed for each user.
+Each "watch" costs roughly 90 bytes on a 32bit kernel, and roughly 160 bytes
+on a 64bit one.
+The current default value for max_user_watches is the 1/32 of the available
+low memory, divided for the "watch" cost in bytes.
+
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index a4ccdd1981cf..f11ca7979fa6 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -1,5 +1,6 @@
Documentation for /proc/sys/kernel/* kernel version 2.2.10
(c) 1998, 1999, Rik van Riel <riel@nl.linux.org>
+ (c) 2009, Shen Feng<shen@cn.fujitsu.com>
For general info and legal blurb, please look in README.
@@ -18,6 +19,7 @@ Currently, these files might (depending on your configuration)
show up in /proc/sys/kernel:
- acpi_video_flags
- acct
+- auto_msgmni
- core_pattern
- core_uses_pid
- ctrl-alt-del
@@ -33,6 +35,7 @@ show up in /proc/sys/kernel:
- msgmax
- msgmnb
- msgmni
+- nmi_watchdog
- osrelease
- ostype
- overflowgid
@@ -40,6 +43,7 @@ show up in /proc/sys/kernel:
- panic
- pid_max
- powersave-nap [ PPC only ]
+- panic_on_unrecovered_nmi
- printk
- randomize_va_space
- real-root-dev ==> Documentation/initrd.txt
@@ -55,6 +59,7 @@ show up in /proc/sys/kernel:
- sysrq ==> Documentation/sysrq.txt
- tainted
- threads-max
+- unknown_nmi_panic
- version
==============================================================
@@ -381,3 +386,51 @@ can be ORed together:
512 - A kernel warning has occurred.
1024 - A module from drivers/staging was loaded.
+==============================================================
+
+auto_msgmni:
+
+Enables/Disables automatic recomputing of msgmni upon memory add/remove or
+upon ipc namespace creation/removal (see the msgmni description above).
+Echoing "1" into this file enables msgmni automatic recomputing.
+Echoing "0" turns it off.
+auto_msgmni default value is 1.
+
+==============================================================
+
+nmi_watchdog:
+
+Enables/Disables the NMI watchdog on x86 systems. When the value is non-zero
+the NMI watchdog is enabled and will continuously test all online cpus to
+determine whether or not they are still functioning properly. Currently,
+passing "nmi_watchdog=" parameter at boot time is required for this function
+to work.
+
+If LAPIC NMI watchdog method is in use (nmi_watchdog=2 kernel parameter), the
+NMI watchdog shares registers with oprofile. By disabling the NMI watchdog,
+oprofile may have more registers to utilize.
+
+==============================================================
+
+unknown_nmi_panic:
+
+The value in this file affects behavior of handling NMI. When the value is
+non-zero, unknown NMI is trapped and then panic occurs. At that time, kernel
+debugging information is displayed on console.
+
+NMI switch that most IA32 servers have fires unknown NMI up, for example.
+If a system hangs up, try pressing the NMI switch.
+
+==============================================================
+
+panic_on_unrecovered_nmi:
+
+The default Linux behaviour on an NMI of either memory or unknown is to continue
+operation. For many environments such as scientific computing it is preferable
+that the box is taken out and the error dealt with than an uncorrected
+parity/ECC error get propogated.
+
+A small number of systems do generate NMI's for bizarre random reasons such as
+power management so the default is off. That sysctl works like the existing
+panic controls already in that directory.
+
diff --git a/Documentation/sysctl/net.txt b/Documentation/sysctl/net.txt
new file mode 100644
index 000000000000..a34d55b65441
--- /dev/null
+++ b/Documentation/sysctl/net.txt
@@ -0,0 +1,175 @@
+Documentation for /proc/sys/net/* kernel version 2.4.0-test11-pre4
+ (c) 1999 Terrehon Bowden <terrehon@pacbell.net>
+ Bodo Bauer <bb@ricochet.net>
+ (c) 2000 Jorge Nerin <comandante@zaralinux.com>
+ (c) 2009 Shen Feng <shen@cn.fujitsu.com>
+
+For general info and legal blurb, please look in README.
+
+==============================================================
+
+This file contains the documentation for the sysctl files in
+/proc/sys/net and is valid for Linux kernel version 2.4.0-test11-pre4.
+
+The interface to the networking parts of the kernel is located in
+/proc/sys/net. The following table shows all possible subdirectories.You may
+see only some of them, depending on your kernel's configuration.
+
+
+Table : Subdirectories in /proc/sys/net
+..............................................................................
+ Directory Content Directory Content
+ core General parameter appletalk Appletalk protocol
+ unix Unix domain sockets netrom NET/ROM
+ 802 E802 protocol ax25 AX25
+ ethernet Ethernet protocol rose X.25 PLP layer
+ ipv4 IP version 4 x25 X.25 protocol
+ ipx IPX token-ring IBM token ring
+ bridge Bridging decnet DEC net
+ ipv6 IP version 6
+..............................................................................
+
+1. /proc/sys/net/core - Network core options
+-------------------------------------------------------
+
+rmem_default
+------------
+
+The default setting of the socket receive buffer in bytes.
+
+rmem_max
+--------
+
+The maximum receive socket buffer size in bytes.
+
+wmem_default
+------------
+
+The default setting (in bytes) of the socket send buffer.
+
+wmem_max
+--------
+
+The maximum send socket buffer size in bytes.
+
+message_burst and message_cost
+------------------------------
+
+These parameters are used to limit the warning messages written to the kernel
+log from the networking code. They enforce a rate limit to make a
+denial-of-service attack impossible. A higher message_cost factor, results in
+fewer messages that will be written. Message_burst controls when messages will
+be dropped. The default settings limit warning messages to one every five
+seconds.
+
+warnings
+--------
+
+This controls console messages from the networking stack that can occur because
+of problems on the network like duplicate address or bad checksums. Normally,
+this should be enabled, but if the problem persists the messages can be
+disabled.
+
+netdev_budget
+-------------
+
+Maximum number of packets taken from all interfaces in one polling cycle (NAPI
+poll). In one polling cycle interfaces which are registered to polling are
+probed in a round-robin manner. The limit of packets in one such probe can be
+set per-device via sysfs class/net/<device>/weight .
+
+netdev_max_backlog
+------------------
+
+Maximum number of packets, queued on the INPUT side, when the interface
+receives packets faster than kernel can process them.
+
+optmem_max
+----------
+
+Maximum ancillary buffer size allowed per socket. Ancillary data is a sequence
+of struct cmsghdr structures with appended data.
+
+2. /proc/sys/net/unix - Parameters for Unix domain sockets
+-------------------------------------------------------
+
+There is only one file in this directory.
+unix_dgram_qlen limits the max number of datagrams queued in Unix domain
+socket's buffer. It will not take effect unless PF_UNIX flag is spicified.
+
+
+3. /proc/sys/net/ipv4 - IPV4 settings
+-------------------------------------------------------
+Please see: Documentation/networking/ip-sysctl.txt and ipvs-sysctl.txt for
+descriptions of these entries.
+
+
+4. Appletalk
+-------------------------------------------------------
+
+The /proc/sys/net/appletalk directory holds the Appletalk configuration data
+when Appletalk is loaded. The configurable parameters are:
+
+aarp-expiry-time
+----------------
+
+The amount of time we keep an ARP entry before expiring it. Used to age out
+old hosts.
+
+aarp-resolve-time
+-----------------
+
+The amount of time we will spend trying to resolve an Appletalk address.
+
+aarp-retransmit-limit
+---------------------
+
+The number of times we will retransmit a query before giving up.
+
+aarp-tick-time
+--------------
+
+Controls the rate at which expires are checked.
+
+The directory /proc/net/appletalk holds the list of active Appletalk sockets
+on a machine.
+
+The fields indicate the DDP type, the local address (in network:node format)
+the remote address, the size of the transmit pending queue, the size of the
+received queue (bytes waiting for applications to read) the state and the uid
+owning the socket.
+
+/proc/net/atalk_iface lists all the interfaces configured for appletalk.It
+shows the name of the interface, its Appletalk address, the network range on
+that address (or network number for phase 1 networks), and the status of the
+interface.
+
+/proc/net/atalk_route lists each known network route. It lists the target
+(network) that the route leads to, the router (may be directly connected), the
+route flags, and the device the route is using.
+
+
+5. IPX
+-------------------------------------------------------
+
+The IPX protocol has no tunable values in proc/sys/net.
+
+The IPX protocol does, however, provide proc/net/ipx. This lists each IPX
+socket giving the local and remote addresses in Novell format (that is
+network:node:port). In accordance with the strange Novell tradition,
+everything but the port is in hex. Not_Connected is displayed for sockets that
+are not tied to a specific remote address. The Tx and Rx queue sizes indicate
+the number of bytes pending for transmission and reception. The state
+indicates the state the socket is in and the uid is the owning uid of the
+socket.
+
+The /proc/net/ipx_interface file lists all IPX interfaces. For each interface
+it gives the network number, the node number, and indicates if the network is
+the primary network. It also indicates which device it is bound to (or
+Internal for internal networks) and the Frame Type if appropriate. Linux
+supports 802.3, 802.2, 802.2 SNAP and DIX (Blue Book) ethernet framing for
+IPX.
+
+The /proc/net/ipx_route table holds a list of IPX routes. For each route it
+gives the destination network, the router node (or Directly) and the network
+address of the router (or Connected) for internal networks.
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt
index 535aeb936dbc..cf42b820ff9d 100644
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -81,6 +81,8 @@ On all - write a character to /proc/sysrq-trigger. e.g.:
'i' - Send a SIGKILL to all processes, except for init.
+'j' - Forcibly "Just thaw it" - filesystems frozen by the FIFREEZE ioctl.
+
'k' - Secure Access Key (SAK) Kills all programs on the current virtual
console. NOTE: See important comments below in SAK section.
@@ -162,6 +164,9 @@ t'E'rm and k'I'll are useful if you have some sort of runaway process you
are unable to kill any other way, especially if it's spawning other
processes.
+"'J'ust thaw it" is useful if your system becomes unresponsive due to a frozen
+(probably root) filesystem via the FIFREEZE ioctl.
+
* Sometimes SysRq seems to get 'stuck' after using it, what can I do?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
That happens to me, also. I've found that tapping shift, alt, and control
diff --git a/Documentation/tracepoints.txt b/Documentation/tracepoints.txt
index 4ff43c6de299..c0e1ceed75a4 100644
--- a/Documentation/tracepoints.txt
+++ b/Documentation/tracepoints.txt
@@ -103,13 +103,14 @@ used to export the defined tracepoints.
* Probe / tracepoint example
-See the example provided in samples/tracepoints/src
+See the example provided in samples/tracepoints
-Compile them with your kernel.
+Compile them with your kernel. They are built during 'make' (not
+'make modules') when CONFIG_SAMPLE_TRACEPOINTS=m.
Run, as root :
-modprobe tracepoint-example (insmod order is not important)
-modprobe tracepoint-probe-example
-cat /proc/tracepoint-example (returns an expected error)
-rmmod tracepoint-example tracepoint-probe-example
+modprobe tracepoint-sample (insmod order is not important)
+modprobe tracepoint-probe-sample
+cat /proc/tracepoint-sample (returns an expected error)
+rmmod tracepoint-sample tracepoint-probe-sample
dmesg
diff --git a/Documentation/usb/usbmon.txt b/Documentation/usb/usbmon.txt
index 270481906dc8..6c3c625b7f30 100644
--- a/Documentation/usb/usbmon.txt
+++ b/Documentation/usb/usbmon.txt
@@ -229,16 +229,26 @@ struct usbmon_packet {
int status; /* 28: */
unsigned int length; /* 32: Length of data (submitted or actual) */
unsigned int len_cap; /* 36: Delivered length */
- unsigned char setup[8]; /* 40: Only for Control 'S' */
-}; /* 48 bytes total */
+ union { /* 40: */
+ unsigned char setup[SETUP_LEN]; /* Only for Control S-type */
+ struct iso_rec { /* Only for ISO */
+ int error_count;
+ int numdesc;
+ } iso;
+ } s;
+ int interval; /* 48: Only for Interrupt and ISO */
+ int start_frame; /* 52: For ISO */
+ unsigned int xfer_flags; /* 56: copy of URB's transfer_flags */
+ unsigned int ndesc; /* 60: Actual number of ISO descriptors */
+}; /* 64 total length */
These events can be received from a character device by reading with read(2),
-with an ioctl(2), or by accessing the buffer with mmap.
+with an ioctl(2), or by accessing the buffer with mmap. However, read(2)
+only returns first 48 bytes for compatibility reasons.
The character device is usually called /dev/usbmonN, where N is the USB bus
number. Number zero (/dev/usbmon0) is special and means "all buses".
-However, this feature is not implemented yet. Note that specific naming
-policy is set by your Linux distribution.
+Note that specific naming policy is set by your Linux distribution.
If you create /dev/usbmon0 by hand, make sure that it is owned by root
and has mode 0600. Otherwise, unpriviledged users will be able to snoop
@@ -279,9 +289,10 @@ size is out of [unspecified] bounds for this kernel, the call fails with
This call returns the current size of the buffer in bytes.
MON_IOCX_GET, defined as _IOW(MON_IOC_MAGIC, 6, struct mon_get_arg)
+ MON_IOCX_GETX, defined as _IOW(MON_IOC_MAGIC, 10, struct mon_get_arg)
-This call waits for events to arrive if none were in the kernel buffer,
-then returns the first event. Its argument is a pointer to the following
+These calls wait for events to arrive if none were in the kernel buffer,
+then return the first event. The argument is a pointer to the following
structure:
struct mon_get_arg {
@@ -294,6 +305,8 @@ Before the call, hdr, data, and alloc should be filled. Upon return, the area
pointed by hdr contains the next event structure, and the data buffer contains
the data, if any. The event is removed from the kernel buffer.
+The MON_IOCX_GET copies 48 bytes, MON_IOCX_GETX copies 64 bytes.
+
MON_IOCX_MFETCH, defined as _IOWR(MON_IOC_MAGIC, 7, struct mon_mfetch_arg)
This ioctl is primarily used when the application accesses the buffer
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index 0d93fa1ac25e..f11c583295e9 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -135,7 +135,7 @@
134 -> Adlink RTV24
135 -> DViCO FusionHDTV 5 Lite [18ac:d500]
136 -> Acorp Y878F [9511:1540]
-137 -> Conceptronic CTVFMi v2
+137 -> Conceptronic CTVFMi v2 [036e:109e]
138 -> Prolink Pixelview PV-BT878P+ (Rev.2E)
139 -> Prolink PixelView PlayTV MPEG2 PV-M4900
140 -> Osprey 440 [0070:ff07]
@@ -154,3 +154,7 @@
153 -> PHYTEC VD-012 (bt878)
154 -> PHYTEC VD-012-X1 (bt878)
155 -> PHYTEC VD-012-X2 (bt878)
+156 -> IVCE-8784 [0000:f050,0001:f050,0002:f050,0003:f050]
+157 -> Geovision GV-800(S) (master) [800a:763d]
+158 -> Geovision GV-800(S) (slave) [800b:763d,800c:763d,800d:763d]
+159 -> ProVideo PV183 [1830:1540,1831:1540,1832:1540,1833:1540,1834:1540,1835:1540,1836:1540,1837:1540]
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 35ea130e9898..91aa3c0f0dd2 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -12,3 +12,7 @@
11 -> DViCO FusionHDTV DVB-T Dual Express [18ac:db78]
12 -> Leadtek Winfast PxDVR3200 H [107d:6681]
13 -> Compro VideoMate E650F [185b:e800]
+ 14 -> TurboSight TBS 6920 [6920:8888]
+ 15 -> TeVii S470 [d470:9022]
+ 16 -> DVBWorld DVB-S2 2005 [0001:2005]
+ 17 -> NetUP Dual DVB-S2 CI [1b55:2a2c]
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 0d08f1edcf6d..71e9db0b26f7 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -77,3 +77,4 @@
76 -> SATTRADE ST4200 DVB-S/S2 [b200:4200]
77 -> TBS 8910 DVB-S [8910:8888]
78 -> Prof 6200 DVB-S [b022:3022]
+ 79 -> Terratec Cinergy HT PCI MKII [153b:1177]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index 75bded8a4aa2..78d0a6eed571 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -7,12 +7,12 @@
6 -> Terratec Cinergy 200 USB (em2800)
7 -> Leadtek Winfast USB II (em2800) [0413:6023]
8 -> Kworld USB2800 (em2800)
- 9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a]
+ 9 -> Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker (em2820/em2840) [1b80:e302,2304:0207,2304:021a]
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
11 -> Terratec Hybrid XS (em2880) [0ccd:0042]
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
- 14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
+ 14 -> SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
15 -> V-Gear PocketTV (em2800)
16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b]
17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227]
@@ -30,7 +30,6 @@
30 -> Videology 20K14XUSB USB2.0 (em2820/em2840)
31 -> Usbgear VD204v9 (em2821)
32 -> Supercomp USB 2.0 TV (em2821)
- 33 -> SIIG AVTuner-PVR/Prolink PlayTV USB 2.0 (em2821)
34 -> Terratec Cinergy A Hybrid XS (em2860) [0ccd:004f]
35 -> Typhoon DVD Maker (em2860)
36 -> NetGMBH Cam (em2860)
@@ -58,3 +57,7 @@
58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041]
60 -> Hauppauge WinTV HVR 850 (em2883) [2040:651f]
61 -> Pixelview PlayTV Box 4 USB 2.0 (em2820/em2840)
+ 62 -> Gadmei TVR200 (em2820/em2840)
+ 63 -> Kaiomy TVnPC U2 (em2860) [eb1a:e303]
+ 64 -> Easy Cap Capture DC-60 (em2860)
+ 65 -> IO-DATA GV-MVP/SZ (em2820/em2840) [04bb:0515]
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index b8d470596b0c..6dacf2825259 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -153,3 +153,5 @@
152 -> Asus Tiger Rev:1.00 [1043:4857]
153 -> Kworld Plus TV Analog Lite PCI [17de:7128]
154 -> Avermedia AVerTV GO 007 FM Plus [1461:f31d]
+155 -> Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid [0070:6706,0070:6708]
+156 -> Hauppauge WinTV-HVR1110r3 [0070:6707,0070:6709,0070:670a]
diff --git a/Documentation/video4linux/Zoran b/Documentation/video4linux/Zoran
index 295462b2317a..0e89e7676298 100644
--- a/Documentation/video4linux/Zoran
+++ b/Documentation/video4linux/Zoran
@@ -401,8 +401,7 @@ Additional notes for software developers:
first set the correct norm. Well, it seems logically correct: TV
standard is "more constant" for current country than geometry
settings of a variety of TV capture cards which may work in ITU or
- square pixel format. Remember that users now can lock the norm to
- avoid any ambiguity.
+ square pixel format.
--
Please note that lavplay/lavrec are also included in the MJPEG-tools
(http://mjpeg.sf.net/).
diff --git a/Documentation/video4linux/bttv/Insmod-options b/Documentation/video4linux/bttv/Insmod-options
index 5ef75787f83a..bbe3ed667d91 100644
--- a/Documentation/video4linux/bttv/Insmod-options
+++ b/Documentation/video4linux/bttv/Insmod-options
@@ -81,16 +81,6 @@ tuner.o
pal=[bdgil] select PAL variant (used for some tuners
only, important for the audio carrier).
-tvmixer.o
- registers a mixer device for the TV card's volume/bass/treble
- controls (requires a i2c audio control chip like the msp3400).
-
- insmod args:
- debug=1 print some debug info to the syslog.
- devnr=n allocate device #n (0 == /dev/mixer,
- 1 = /dev/mixer1, ...), default is to
- use the first free one.
-
tvaudio.o
new, experimental module which is supported to provide a single
driver for all simple i2c audio control chips (tda/tea*).
diff --git a/Documentation/video4linux/bttv/README b/Documentation/video4linux/bttv/README
index 7ca2154c2bf5..3a367cdb664e 100644
--- a/Documentation/video4linux/bttv/README
+++ b/Documentation/video4linux/bttv/README
@@ -63,8 +63,8 @@ If you have some knowledge and spare time, please try to fix this
yourself (patches very welcome of course...) You know: The linux
slogan is "Do it yourself".
-There is a mailing list: video4linux-list@redhat.com.
-https://listman.redhat.com/mailman/listinfo/video4linux-list
+There is a mailing list: linux-media@vger.kernel.org
+http://vger.kernel.org/vger-lists.html#linux-media
If you have trouble with some specific TV card, try to ask there
instead of mailing me directly. The chance that someone with the
diff --git a/Documentation/video4linux/cx2341x/README.hm12 b/Documentation/video4linux/cx2341x/README.hm12
index 0e213ed095e6..b36148ea0750 100644
--- a/Documentation/video4linux/cx2341x/README.hm12
+++ b/Documentation/video4linux/cx2341x/README.hm12
@@ -32,6 +32,10 @@ Y, U and V planes. This code assumes frames of 720x576 (PAL) pixels.
The width of a frame is always 720 pixels, regardless of the actual specified
width.
+If the height is not a multiple of 32 lines, then the captured video is
+missing macroblocks at the end and is unusable. So the height must be a
+multiple of 32.
+
--------------------------------------------------------------------------
#include <stdio.h>
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 1c58a7630146..98529e03a46e 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -32,6 +32,7 @@ spca561 041e:403b Creative Webcam Vista (VF0010)
zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250)
ov519 041e:4052 Creative Live! VISTA IM
zc3xx 041e:4053 Creative Live!Cam Video IM
+vc032x 041e:405b Creative Live! Cam Notebook Ultra (VC0130)
ov519 041e:405f Creative Live! VISTA VF0330
ov519 041e:4060 Creative Live! VISTA VF0350
ov519 041e:4061 Creative Live! VISTA VF0400
@@ -193,6 +194,7 @@ spca500 084d:0003 D-Link DSC-350
spca500 08ca:0103 Aiptek PocketDV
sunplus 08ca:0104 Aiptek PocketDVII 1.3
sunplus 08ca:0106 Aiptek Pocket DV3100+
+mr97310a 08ca:0111 Aiptek PenCam VGA+
sunplus 08ca:2008 Aiptek Mini PenCam 2 M
sunplus 08ca:2010 Aiptek PocketCam 3M
sunplus 08ca:2016 Aiptek PocketCam 2 Mega
@@ -215,6 +217,7 @@ pac207 093a:2468 PAC207
pac207 093a:2470 Genius GF112
pac207 093a:2471 Genius VideoCam ge111
pac207 093a:2472 Genius VideoCam ge110
+pac207 093a:2474 Genius iLook 111
pac207 093a:2476 Genius e-Messenger 112
pac7311 093a:2600 PAC7311 Typhoon
pac7311 093a:2601 Philips SPC 610 NC
@@ -279,6 +282,7 @@ spca561 10fd:7e50 FlyCam Usb 100
zc3xx 10fd:8050 Typhoon Webshot II USB 300k
ov534 1415:2000 Sony HD Eye for PS3 (SLEH 00201)
pac207 145f:013a Trust WB-1300N
+vc032x 15b8:6001 HP 2.0 Megapixel
vc032x 15b8:6002 HP 2.0 Megapixel rz406aa
spca501 1776:501c Arowana 300K CMOS Camera
t613 17a1:0128 TASCORP JPEG Webcam, NGS Cyclops
diff --git a/Documentation/video4linux/si470x.txt b/Documentation/video4linux/si470x.txt
index 49679e6aaa76..3a7823e01b4d 100644
--- a/Documentation/video4linux/si470x.txt
+++ b/Documentation/video4linux/si470x.txt
@@ -1,6 +1,6 @@
Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers
-Copyright (c) 2008 Tobias Lorenz <tobias.lorenz@gmx.net>
+Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.net>
Information from Silicon Labs
@@ -41,7 +41,7 @@ chips are known to work:
- 10c4:818a: Silicon Labs USB FM Radio Reference Design
- 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF)
- 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
-- 10c5:819a: DealExtreme USB Radio
+- 10c5:819a: Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear)
Software
@@ -52,6 +52,7 @@ Testing is usually done with most application under Debian/testing:
- gradio - GTK FM radio tuner
- kradio - Comfortable Radio Application for KDE
- radio - ncurses-based radio application
+- mplayer - The Ultimate Movie Player For Linux
There is also a library libv4l, which can be used. It's going to have a function
for frequency seeking, either by using hardware functionality as in radio-si470x
@@ -69,7 +70,7 @@ Audio Listing
USB Audio is provided by the ALSA snd_usb_audio module. It is recommended to
also select SND_USB_AUDIO, as this is required to get sound from the radio. For
listing you have to redirect the sound, for example using one of the following
-commands.
+commands. Please adjust the audio devices to your needs (/dev/dsp* and hw:x,x).
If you just want to test audio (very poor quality):
cat /dev/dsp1 > /dev/dsp
@@ -80,6 +81,10 @@ sox -2 --endian little -r 96000 -t oss /dev/dsp1 -t oss /dev/dsp
If you use arts try:
arecord -D hw:1,0 -r96000 -c2 -f S16_LE | artsdsp aplay -B -
+If you use mplayer try:
+mplayer -radio adevice=hw=1.0:arate=96000 \
+ -rawaudio rate=96000 \
+ radio://<frequency>/capture
Module Parameters
=================
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index ff124374e9ba..a31177390e55 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -47,7 +47,9 @@ All drivers have the following structure:
3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX, /dev/radioX and
/dev/vtxX) and keeping track of device-node specific data.
-4) Filehandle-specific structs containing per-filehandle data.
+4) Filehandle-specific structs containing per-filehandle data;
+
+5) video buffer handling.
This is a rough schematic of how it all relates:
@@ -82,12 +84,20 @@ You must register the device instance:
v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
Registration will initialize the v4l2_device struct and link dev->driver_data
-to v4l2_dev. Registration will also set v4l2_dev->name to a value derived from
-dev (driver name followed by the bus_id, to be precise). You may change the
-name after registration if you want.
+to v4l2_dev. If v4l2_dev->name is empty then it will be set to a value derived
+from dev (driver name followed by the bus_id, to be precise). If you set it
+up before calling v4l2_device_register then it will be untouched. If dev is
+NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register.
The first 'dev' argument is normally the struct device pointer of a pci_dev,
-usb_device or platform_device.
+usb_device or platform_device. It is rare for dev to be NULL, but it happens
+with ISA devices or when one device creates multiple PCI devices, thus making
+it impossible to associate v4l2_dev with a particular parent.
+
+You can also supply a notify() callback that can be called by sub-devices to
+notify you of events. Whether you need to set this depends on the sub-device.
+Any notifications a sub-device supports must be defined in a header in
+include/media/<subdevice>.h.
You unregister with:
@@ -95,6 +105,17 @@ You unregister with:
Unregistering will also automatically unregister all subdevs from the device.
+If you have a hotpluggable device (e.g. a USB device), then when a disconnect
+happens the parent device becomes invalid. Since v4l2_device has a pointer to
+that parent device it has to be cleared as well to mark that the parent is
+gone. To do this call:
+
+ v4l2_device_disconnect(struct v4l2_device *v4l2_dev);
+
+This does *not* unregister the subdevs, so you still need to call the
+v4l2_device_unregister() function for that. If your driver is not hotpluggable,
+then there is no need to call v4l2_device_disconnect().
+
Sometimes you need to iterate over all devices registered by a specific
driver. This is usually the case if multiple device drivers use the same
hardware. E.g. the ivtvfb driver is a framebuffer driver that uses the ivtv
@@ -134,7 +155,7 @@ The recommended approach is as follows:
static atomic_t drv_instance = ATOMIC_INIT(0);
-static int __devinit drv_probe(struct pci_dev *dev,
+static int __devinit drv_probe(struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
...
@@ -218,7 +239,7 @@ to add new ops and categories.
A sub-device driver initializes the v4l2_subdev struct using:
- v4l2_subdev_init(subdev, &ops);
+ v4l2_subdev_init(sd, &ops);
Afterwards you need to initialize subdev->name with a unique name and set the
module owner. This is done for you if you use the i2c helper functions.
@@ -226,7 +247,7 @@ module owner. This is done for you if you use the i2c helper functions.
A device (bridge) driver needs to register the v4l2_subdev with the
v4l2_device:
- int err = v4l2_device_register_subdev(device, subdev);
+ int err = v4l2_device_register_subdev(v4l2_dev, sd);
This can fail if the subdev module disappeared before it could be registered.
After this function was called successfully the subdev->dev field points to
@@ -234,17 +255,17 @@ the v4l2_device.
You can unregister a sub-device using:
- v4l2_device_unregister_subdev(subdev);
+ v4l2_device_unregister_subdev(sd);
-Afterwards the subdev module can be unloaded and subdev->dev == NULL.
+Afterwards the subdev module can be unloaded and sd->dev == NULL.
You can call an ops function either directly:
- err = subdev->ops->core->g_chip_ident(subdev, &chip);
+ err = sd->ops->core->g_chip_ident(sd, &chip);
but it is better and easier to use this macro:
- err = v4l2_subdev_call(subdev, core, g_chip_ident, &chip);
+ err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
The macro will to the right NULL pointer checks and returns -ENODEV if subdev
is NULL, -ENOIOCTLCMD if either subdev->core or subdev->core->g_chip_ident is
@@ -252,19 +273,19 @@ NULL, or the actual result of the subdev->ops->core->g_chip_ident ops.
It is also possible to call all or a subset of the sub-devices:
- v4l2_device_call_all(dev, 0, core, g_chip_ident, &chip);
+ v4l2_device_call_all(v4l2_dev, 0, core, g_chip_ident, &chip);
Any subdev that does not support this ops is skipped and error results are
ignored. If you want to check for errors use this:
- err = v4l2_device_call_until_err(dev, 0, core, g_chip_ident, &chip);
+ err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_chip_ident, &chip);
Any error except -ENOIOCTLCMD will exit the loop with that error. If no
errors (except -ENOIOCTLCMD) occured, then 0 is returned.
The second argument to both calls is a group ID. If 0, then all subdevs are
called. If non-zero, then only those whose group ID match that value will
-be called. Before a bridge driver registers a subdev it can set subdev->grp_id
+be called. Before a bridge driver registers a subdev it can set sd->grp_id
to whatever value it wants (it's 0 by default). This value is owned by the
bridge driver and the sub-device driver will never modify or use it.
@@ -276,6 +297,11 @@ e.g. AUDIO_CONTROLLER and specify that as the group ID value when calling
v4l2_device_call_all(). That ensures that it will only go to the subdev
that needs it.
+If the sub-device needs to notify its v4l2_device parent of an event, then
+it can call v4l2_subdev_notify(sd, notification, arg). This macro checks
+whether there is a notify() callback defined and returns -ENODEV if not.
+Otherwise the result of the notify() call is returned.
+
The advantage of using v4l2_subdev is that it is a generic struct and does
not contain any knowledge about the underlying hardware. So a driver might
contain several subdevs that use an I2C bus, but also a subdev that is
@@ -340,6 +366,12 @@ Make sure to call v4l2_device_unregister_subdev(sd) when the remove() callback
is called. This will unregister the sub-device from the bridge driver. It is
safe to call this even if the sub-device was never registered.
+You need to do this because when the bridge driver destroys the i2c adapter
+the remove() callbacks are called of the i2c devices on that adapter.
+After that the corresponding v4l2_subdev structures are invalid, so they
+have to be unregistered first. Calling v4l2_device_unregister_subdev(sd)
+from the remove() callback ensures that this is always done correctly.
+
The bridge driver also has some helper functions it can use:
@@ -349,8 +381,8 @@ This loads the given module (can be NULL if no module needs to be loaded) and
calls i2c_new_device() with the given i2c_adapter and chip/address arguments.
If all goes well, then it registers the subdev with the v4l2_device. It gets
the v4l2_device by calling i2c_get_adapdata(adapter), so you should make sure
-that adapdata is set to v4l2_device when you setup the i2c_adapter in your
-driver.
+to call i2c_set_adapdata(adapter, v4l2_device) when you setup the i2c_adapter
+in your driver.
You can also use v4l2_i2c_new_probed_subdev() which is very similar to
v4l2_i2c_new_subdev(), except that it has an array of possible I2C addresses
@@ -358,6 +390,14 @@ that it should probe. Internally it calls i2c_new_probed_device().
Both functions return NULL if something went wrong.
+Note that the chipid you pass to v4l2_i2c_new_(probed_)subdev() is usually
+the same as the module name. It allows you to specify a chip variant, e.g.
+"saa7114" or "saa7115". In general though the i2c driver autodetects this.
+The use of chipid is something that needs to be looked at more closely at a
+later date. It differs between i2c drivers and as such can be confusing.
+To see which chip variants are supported you can look in the i2c driver code
+for the i2c_device_id table. This lists all the possibilities.
+
struct video_device
-------------------
@@ -396,6 +436,15 @@ You should also set these fields:
- ioctl_ops: if you use the v4l2_ioctl_ops to simplify ioctl maintenance
(highly recommended to use this and it might become compulsory in the
future!), then set this to your v4l2_ioctl_ops struct.
+- parent: you only set this if v4l2_device was registered with NULL as
+ the parent device struct. This only happens in cases where one hardware
+ device has multiple PCI devices that all share the same v4l2_device core.
+
+ The cx88 driver is an example of this: one core v4l2_device struct, but
+ it is used by both an raw video PCI device (cx8800) and a MPEG PCI device
+ (cx8802). Since the v4l2_device cannot be associated with a particular
+ PCI device it is setup without a parent device. But when the struct
+ video_device is setup you do know which parent PCI device to use.
If you use v4l2_ioctl_ops, then you should set either .unlocked_ioctl or
.ioctl to video_ioctl2 in your v4l2_file_operations struct.
@@ -499,8 +548,8 @@ There are a few useful helper functions:
You can set/get driver private data in the video_device struct using:
-void *video_get_drvdata(struct video_device *dev);
-void video_set_drvdata(struct video_device *dev, void *data);
+void *video_get_drvdata(struct video_device *vdev);
+void video_set_drvdata(struct video_device *vdev, void *data);
Note that you can safely call video_set_drvdata() before calling
video_register_device().
@@ -519,3 +568,103 @@ void *video_drvdata(struct file *file);
You can go from a video_device struct to the v4l2_device struct using:
struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
+
+video buffer helper functions
+-----------------------------
+
+The v4l2 core API provides a standard method for dealing with video
+buffers. Those methods allow a driver to implement read(), mmap() and
+overlay() on a consistent way.
+
+There are currently methods for using video buffers on devices that
+supports DMA with scatter/gather method (videobuf-dma-sg), DMA with
+linear access (videobuf-dma-contig), and vmalloced buffers, mostly
+used on USB drivers (videobuf-vmalloc).
+
+Any driver using videobuf should provide operations (callbacks) for
+four handlers:
+
+ops->buf_setup - calculates the size of the video buffers and avoid they
+ to waste more than some maximum limit of RAM;
+ops->buf_prepare - fills the video buffer structs and calls
+ videobuf_iolock() to alloc and prepare mmaped memory;
+ops->buf_queue - advices the driver that another buffer were
+ requested (by read() or by QBUF);
+ops->buf_release - frees any buffer that were allocated.
+
+In order to use it, the driver need to have a code (generally called at
+interrupt context) that will properly handle the buffer request lists,
+announcing that a new buffer were filled.
+
+The irq handling code should handle the videobuf task lists, in order
+to advice videobuf that a new frame were filled, in order to honor to a
+request. The code is generally like this one:
+ if (list_empty(&dma_q->active))
+ return;
+
+ buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue);
+
+ if (!waitqueue_active(&buf->vb.done))
+ return;
+
+ /* Some logic to handle the buf may be needed here */
+
+ list_del(&buf->vb.queue);
+ do_gettimeofday(&buf->vb.ts);
+ wake_up(&buf->vb.done);
+
+Those are the videobuffer functions used on drivers, implemented on
+videobuf-core:
+
+- Videobuf init functions
+ videobuf_queue_sg_init()
+ Initializes the videobuf infrastructure. This function should be
+ called before any other videobuf function on drivers that uses DMA
+ Scatter/Gather buffers.
+
+ videobuf_queue_dma_contig_init
+ Initializes the videobuf infrastructure. This function should be
+ called before any other videobuf function on drivers that need DMA
+ contiguous buffers.
+
+ videobuf_queue_vmalloc_init()
+ Initializes the videobuf infrastructure. This function should be
+ called before any other videobuf function on USB (and other drivers)
+ that need a vmalloced type of videobuf.
+
+- videobuf_iolock()
+ Prepares the videobuf memory for the proper method (read, mmap, overlay).
+
+- videobuf_queue_is_busy()
+ Checks if a videobuf is streaming.
+
+- videobuf_queue_cancel()
+ Stops video handling.
+
+- videobuf_mmap_free()
+ frees mmap buffers.
+
+- videobuf_stop()
+ Stops video handling, ends mmap and frees mmap and other buffers.
+
+- V4L2 api functions. Those functions correspond to VIDIOC_foo ioctls:
+ videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(),
+ videobuf_dqbuf(), videobuf_streamon(), videobuf_streamoff().
+
+- V4L1 api function (corresponds to VIDIOCMBUF ioctl):
+ videobuf_cgmbuf()
+ This function is used to provide backward compatibility with V4L1
+ API.
+
+- Some help functions for read()/poll() operations:
+ videobuf_read_stream()
+ For continuous stream read()
+ videobuf_read_one()
+ For snapshot read()
+ videobuf_poll_stream()
+ polling help function
+
+The better way to understand it is to take a look at vivi driver. One
+of the main reasons for vivi is to be a videobuf usage example. the
+vivi_thread_tick() does the task that the IRQ callback would do on PCI
+drivers (or the irq callback on USB).
diff --git a/Documentation/video4linux/v4lgrab.c b/Documentation/video4linux/v4lgrab.c
index d6e70bef8ad0..05769cff1009 100644
--- a/Documentation/video4linux/v4lgrab.c
+++ b/Documentation/video4linux/v4lgrab.c
@@ -105,8 +105,8 @@ int main(int argc, char ** argv)
struct video_picture vpic;
unsigned char *buffer, *src;
- int bpp = 24, r, g, b;
- unsigned int i, src_depth;
+ int bpp = 24, r = 0, g = 0, b = 0;
+ unsigned int i, src_depth = 16;
if (fd < 0) {
perror(VIDEO_DEV);
diff --git a/Documentation/video4linux/zr364xx.txt b/Documentation/video4linux/zr364xx.txt
index 5c81e3ae6458..7f3d1955d214 100644
--- a/Documentation/video4linux/zr364xx.txt
+++ b/Documentation/video4linux/zr364xx.txt
@@ -65,3 +65,4 @@ Vendor Product Distributor Model
0x06d6 0x003b Trust Powerc@m 970Z
0x0a17 0x004e Pentax Optio 50
0x041e 0x405d Creative DiVi CAM 516
+0x08ca 0x2102 Aiptek DV T300
diff --git a/Documentation/vm/numa_memory_policy.txt b/Documentation/vm/numa_memory_policy.txt
index 6aaaeb38730c..be45dbb9d7f2 100644
--- a/Documentation/vm/numa_memory_policy.txt
+++ b/Documentation/vm/numa_memory_policy.txt
@@ -8,7 +8,8 @@ The current memory policy support was added to Linux 2.6 around May 2004. This
document attempts to describe the concepts and APIs of the 2.6 memory policy
support.
-Memory policies should not be confused with cpusets (Documentation/cpusets.txt)
+Memory policies should not be confused with cpusets
+(Documentation/cgroups/cpusets.txt)
which is an administrative mechanism for restricting the nodes from which
memory may be allocated by a set of processes. Memory policies are a
programming interface that a NUMA-aware application can take advantage of. When
diff --git a/Documentation/vm/page_migration b/Documentation/vm/page_migration
index d5fdfd34bbaf..6513fe2d90b8 100644
--- a/Documentation/vm/page_migration
+++ b/Documentation/vm/page_migration
@@ -37,7 +37,8 @@ locations.
Larger installations usually partition the system using cpusets into
sections of nodes. Paul Jackson has equipped cpusets with the ability to
-move pages when a task is moved to another cpuset (See ../cpusets.txt).
+move pages when a task is moved to another cpuset (See
+Documentation/cgroups/cpusets.txt).
Cpusets allows the automation of process locality. If a task is moved to
a new cpuset then also all its pages are moved with it so that the
performance of the process does not sink dramatically. Also the pages
diff --git a/Documentation/x86/x86_64/fake-numa-for-cpusets b/Documentation/x86/x86_64/fake-numa-for-cpusets
index 33bb56655991..0f11d9becb0b 100644
--- a/Documentation/x86/x86_64/fake-numa-for-cpusets
+++ b/Documentation/x86/x86_64/fake-numa-for-cpusets
@@ -7,7 +7,8 @@ you can create fake NUMA nodes that represent contiguous chunks of memory and
assign them to cpusets and their attached tasks. This is a way of limiting the
amount of system memory that are available to a certain class of tasks.
-For more information on the features of cpusets, see Documentation/cpusets.txt.
+For more information on the features of cpusets, see
+Documentation/cgroups/cpusets.txt.
There are a number of different configurations you can use for your needs. For
more information on the numa=fake command line option and its various ways of
configuring fake nodes, see Documentation/x86/x86_64/boot-options.txt.
@@ -32,7 +33,7 @@ A machine may be split as follows with "numa=fake=4*512," as reported by dmesg:
On node 3 totalpages: 131072
Now following the instructions for mounting the cpusets filesystem from
-Documentation/cpusets.txt, you can assign fake nodes (i.e. contiguous memory
+Documentation/cgroups/cpusets.txt, you can assign fake nodes (i.e. contiguous memory
address spaces) to individual cpusets:
[root@xroads /]# mkdir exampleset
diff --git a/MAINTAINERS b/MAINTAINERS
index dd3c11c4c3d2..9673cd28a69b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -357,6 +357,7 @@ S: Odd Fixes for 2.4; Maintained for 2.6.
P: Ivan Kokshaysky
M: ink@jurassic.park.msu.ru
S: Maintained for 2.4; PCI support for 2.6.
+L: linux-alpha@vger.kernel.org
AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER
P: Thomas Dahlmann
@@ -502,6 +503,13 @@ P: Richard Purdie
M: rpurdie@rpsys.net
S: Maintained
+ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE
+P: Paulius Zaleckas
+M: paulius.zaleckas@teltonika.lt
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+T: git gitorious.org/linux-gemini/mainline.git
+S: Maintained
+
ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6)
P: Daniel Ribeiro
M: drwyrm@gmail.com
@@ -513,6 +521,12 @@ L: openezx-devel@lists.openezx.org (subscribers-only)
W: http://www.openezx.org/
S: Maintained
+ARM/FARADAY FA526 PORT
+P: Paulius Zaleckas
+M: paulius.zaleckas@teltonika.lt
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S: Maintained
+
ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
P: Sascha Hauer
M: kernel@pengutronix.de
@@ -622,7 +636,7 @@ P: Dirk Opfer
M: dirk@opfer-online.de
S: Maintained
-ARM/PALMTX SUPPORT
+ARM/PALMTX,PALMT5,PALMLD SUPPORT
P: Marek Vasut
M: marek.vasut@gmail.com
W: http://hackndev.com
@@ -765,6 +779,14 @@ L: linux-wireless@vger.kernel.org
L: ath9k-devel@lists.ath9k.org
S: Supported
+ATHEROS AR9170 WIRELESS DRIVER
+P: Christian Lamparter
+M: chunkeey@web.de
+L: linux-wireless@vger.kernel.org
+W: http://wireless.kernel.org/en/users/Drivers/ar9170
+S: Maintained
+F: drivers/net/wireless/ar9170/
+
ATI_REMOTE2 DRIVER
P: Ville Syrjala
M: syrjala@sci.fi
@@ -1011,6 +1033,8 @@ L: netdev@vger.kernel.org
S: Supported
BROADCOM TG3 GIGABIT ETHERNET DRIVER
+P: Matt Carlson
+M: mcarlson@broadcom.com
P: Michael Chan
M: mchan@broadcom.com
L: netdev@vger.kernel.org
@@ -1040,7 +1064,6 @@ BTTV VIDEO4LINUX DRIVER
P: Mauro Carvalho Chehab
M: mchehab@infradead.org
L: linux-media@vger.kernel.org
-L: video4linux-list@redhat.com
W: http://linuxtv.org
T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
@@ -1269,6 +1292,12 @@ L: linux-crypto@vger.kernel.org
T: git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
S: Maintained
+CRYPTOGRAPHIC RANDOM NUMBER GENERATOR
+P: Neil Horman
+M: nhorman@tuxdriver.com
+L: linux-crypto@vger.kernel.org
+S: Maintained
+
CS5535 Audio ALSA driver
P: Jaya Kumar
M: jayakumar.alsa@gmail.com
@@ -1393,6 +1422,11 @@ P: Doug Warzecha
M: Douglas_Warzecha@dell.com
S: Maintained
+DELL WMI EXTRAS DRIVER
+P: Matthew Garrett
+M: mjg59@srcf.ucam.org
+S: Maintained
+
DEVICE NUMBER REGISTRY
P: Torben Mathiasen
M: device@lanana.org
@@ -1734,6 +1768,12 @@ M: viro@zeniv.linux.org.uk
L: linux-fsdevel@vger.kernel.org
S: Maintained
+FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER
+P: Riku Voipio
+M: riku.vipio@iki.fi
+L: lm-sensors@lm-sensors.org
+S: Maintained
+
FIREWIRE SUBSYSTEM (drivers/firewire, <linux/firewire*.h>)
P: Kristian Hoegsberg, Stefan Richter
M: krh@redhat.com, stefanr@s5r6.in-berlin.de
@@ -1916,6 +1956,12 @@ L: lm-sensors@lm-sensors.org
W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/
S: Maintained
+HYPERVISOR VIRTUAL CONSOLE DRIVER
+L: linuxppc-dev@ozlabs.org
+L: linux-kernel@vger.kernel.org
+S: Odd Fixes
+F: drivers/char/hvc_*
+
GSPCA FINEPIX SUBDRIVER
P: Frank Zago
M: frank@zago.net
@@ -2173,25 +2219,12 @@ L: linux-ide@vger.kernel.org
T: quilt kernel.org/pub/linux/kernel/people/bart/pata-2.6/
S: Maintained
-IDE/ATAPI CDROM DRIVER
+IDE/ATAPI DRIVERS
P: Borislav Petkov
M: petkovbb@gmail.com
L: linux-ide@vger.kernel.org
S: Maintained
-IDE/ATAPI FLOPPY DRIVERS
-P: Paul Bristow
-M: Paul Bristow <paul@paulbristow.net>
-W: http://paulbristow.net/linux/idefloppy.html
-L: linux-kernel@vger.kernel.org
-S: Maintained
-
-IDE/ATAPI TAPE DRIVERS
-P: Gadi Oxman
-M: Gadi Oxman <gadio@netvision.net.il>
-L: linux-kernel@vger.kernel.org
-S: Maintained
-
IDLE-I7300
P: Andy Henroid
M: andrew.d.henroid@intel.com
@@ -2216,6 +2249,11 @@ M: stefanr@s5r6.in-berlin.de
L: linux1394-devel@lists.sourceforge.net
S: Maintained
+INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
+P: Mimi Zohar
+M: zohar@us.ibm.com
+S: Supported
+
IMS TWINTURBO FRAMEBUFFER DRIVER
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Orphan
@@ -2838,7 +2876,7 @@ P: Roman Zippel
M: zippel@linux-m68k.org
L: linux-m68k@lists.linux-m68k.org
W: http://www.linux-m68k.org/
-W: http://linux-m68k-cvs.ubb.ca/
+T: git git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git
S: Maintained
M68K ON APPLE MACINTOSH
@@ -2897,6 +2935,12 @@ M: buytenh@marvell.com
L: netdev@vger.kernel.org
S: Supported
+MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
+P: Nicolas Pitre
+M: nico@cam.org
+L: linux-kernel@vger.kernel.org
+S: Maintained
+
MARVELL YUKON / SYSKONNECT DRIVER
P: Mirko Lindner
M: mlindner@syskonnect.de
@@ -3007,8 +3051,9 @@ S: Maintained
MULTIFUNCTION DEVICES (MFD)
P: Samuel Ortiz
-M: sameo@openedhand.com
+M: sameo@linux.intel.com
L: linux-kernel@vger.kernel.org
+T: git kernel.org:/pub/scm/linux/kernel/git/sameo/mfd-2.6.git
S: Supported
MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND SDIO SUBSYSTEM
@@ -3083,7 +3128,7 @@ M: shemminger@linux-foundation.org
L: netem@lists.linux-foundation.org
S: Maintained
-NETERION (S2IO) Xframe 10GbE DRIVER
+NETERION (S2IO) 10GbE DRIVER (xframe/vxge)
P: Ramkrishna Vepa
M: ram.vepa@neterion.com
P: Rastapur Santosh
@@ -3092,8 +3137,11 @@ P: Sivakumar Subramani
M: sivakumar.subramani@neterion.com
P: Sreenivasa Honnur
M: sreenivasa.honnur@neterion.com
+P: Anil Murthy
+M: anil.murthy@neterion.com
L: netdev@vger.kernel.org
-W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/TitleIndex?anonymous
+W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/Linux?Anonymous
+W: http://trac.neterion.com/cgi-bin/trac.cgi/wiki/X3100Linux?Anonymous
S: Supported
NETFILTER/IPTABLES/IPCHAINS
@@ -3295,6 +3343,16 @@ L: orinoco-devel@lists.sourceforge.net
W: http://www.nongnu.org/orinoco/
S: Maintained
+OSD LIBRARY
+P: Boaz Harrosh
+M: bharrosh@panasas.com
+P: Benny Halevy
+M: bhalevy@panasas.com
+L: osd-dev@open-osd.org
+W: http://open-osd.org
+T: git://git.open-osd.org/open-osd.git
+S: Maintained
+
P54 WIRELESS DRIVER
P: Michael Wu
M: flamingice@sourmilk.net
@@ -3374,6 +3432,11 @@ P: Jim Cromie
M: jim.cromie@gmail.com
S: Maintained
+PCA9532 LED DRIVER
+P: Riku Voipio
+M: riku.voipio@iki.fi
+S: Maintained
+
PCI ERROR RECOVERY
P: Linas Vepstas
M: linas@austin.ibm.com
@@ -3545,6 +3608,22 @@ M: linux@arm.linux.org.uk
L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
S: Maintained
+PXA168 SUPPORT
+P: Eric Miao
+M: eric.miao@marvell.com
+P: Jason Chagas
+M: jason.chagas@marvell.com
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+T: git kernel.org:/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
+S: Supported
+
+PXA910 SUPPORT
+P: Eric Miao
+M: eric.miao@marvell.com
+L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+T: git kernel.org:/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git
+S: Supported
+
PXA MMCI DRIVER
S: Orphan
@@ -3595,7 +3674,7 @@ S: Maintained
RALINK RT2X00 WIRELESS LAN DRIVER
P: rt2x00 project
L: linux-wireless@vger.kernel.org
-L: rt2400-devel@lists.sourceforge.net
+L: users@rt2x00.serialmonkey.com
W: http://rt2x00.serialmonkey.com/
S: Maintained
T: git kernel.org:/pub/scm/linux/kernel/git/ivd/rt2x00.git
@@ -3641,6 +3720,12 @@ M: florian.fainelli@telecomint.eu
L: netdev@vger.kernel.org
S: Maintained
+RDS - RELIABLE DATAGRAM SOCKETS
+P: Andy Grover
+M: andy.grover@oracle.com
+L: rds-devel@oss.oracle.com
+S: Supported
+
READ-COPY UPDATE (RCU)
P: Dipankar Sarma
M: dipankar@in.ibm.com
@@ -3732,6 +3817,15 @@ L: linux-s390@vger.kernel.org
W: http://www.ibm.com/developerworks/linux/linux390/
S: Supported
+S390 ZCRYPT DRIVER
+P: Felix Beck
+M: felix.beck@de.ibm.com
+P: Ralph Wuerthner
+M: ralph.wuerthner@de.ibm.com
+M: linux390@de.ibm.com
+L: linux-s390@vger.kernel.org
+S: Supported
+
S390 ZFCP DRIVER
P: Christof Schmitt
M: christof.schmitt@de.ibm.com
@@ -3840,7 +3934,14 @@ S: Maintained
SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER
P: Pierre Ossman
M: drzeus-sdhci@drzeus.cx
-L: sdhci-devel@list.drzeus.cx
+L: sdhci-devel@lists.ossman.eu
+S: Maintained
+
+SECURE DIGITAL HOST CONTROLLER INTERFACE, OPEN FIRMWARE BINDINGS (SDHCI-OF)
+P: Anton Vorontsov
+M: avorontsov@ru.mvista.com
+L: linuxppc-dev@ozlabs.org
+L: sdhci-devel@lists.ossman.eu
S: Maintained
SECURITY SUBSYSTEM
@@ -3850,6 +3951,7 @@ M: jmorris@namei.org
L: linux-kernel@vger.kernel.org
L: linux-security-module@vger.kernel.org (suggested Cc:)
T: git kernel.org:pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git
+W: http://security.wiki.kernel.org/
S: Supported
SECURITY CONTACT
@@ -4291,12 +4393,22 @@ L: tlan-devel@lists.sourceforge.net (subscribers-only)
W: http://sourceforge.net/projects/tlan/
S: Maintained
-TOSHIBA ACPI EXTRAS DRIVER
-P: John Belmonte
-M: toshiba_acpi@memebeam.org
-W: http://memebeam.org/toys/ToshibaAcpiDriver
+TOMOYO SECURITY MODULE
+P: Kentaro Takeda
+M: takedakn@nttdata.co.jp
+P: Tetsuo Handa
+M: penguin-kernel@I-love.SAKURA.ne.jp
+L: linux-kernel@vger.kernel.org (kernel issues)
+L: tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for developers and users in English)
+L: tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese)
+L: tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese)
+W: http://tomoyo.sourceforge.jp/
+T: quilt http://svn.sourceforge.jp/svnroot/tomoyo/trunk/2.2.x/tomoyo-lsm/patches/
S: Maintained
+TOSHIBA ACPI EXTRAS DRIVER
+S: Orphan
+
TOSHIBA SMM DRIVER
P: Jonathan Buzzard
M: jonathan@buzzard.org.uk
@@ -4304,6 +4416,11 @@ L: tlinux-users@tce.toshiba-dme.co.jp
W: http://www.buzzard.org.uk/toshiba/
S: Maintained
+TMIO MMC DRIVER
+P: Ian Molton
+M: ian@mnementh.co.uk
+S: Maintained
+
TPM DEVICE DRIVER
P: Debora Velarde
M: debora@linux.vnet.ibm.com
@@ -4752,7 +4869,6 @@ VIDEO FOR LINUX (V4L)
P: Mauro Carvalho Chehab
M: mchehab@infradead.org
L: linux-media@vger.kernel.org
-L: video4linux-list@redhat.com
W: http://linuxtv.org
T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
S: Maintained
@@ -4769,7 +4885,7 @@ M: lrg@slimlogic.co.uk
P: Mark Brown
M: broonie@opensource.wolfsonmicro.com
W: http://opensource.wolfsonmicro.com/node/15
-W: http://www.slimlogic.co.uk/?page_id=5
+W: http://www.slimlogic.co.uk/?p=48
T: git kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git
S: Supported
@@ -4891,7 +5007,8 @@ S: Supported
XFS FILESYSTEM
P: Silicon Graphics Inc
-P: Bill O'Donnell
+P: Felix Blyakher
+M: felixb@sgi.com
M: xfs-masters@oss.sgi.com
L: xfs@oss.sgi.com
W: http://oss.sgi.com/projects/xfs
diff --git a/Makefile b/Makefile
index 828028d4a448..c6307b6d069f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 29
-EXTRAVERSION = -rc8
-NAME = Erotic Pickled Herring
+EXTRAVERSION =
+NAME = Temporary Tasmanian Devil
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
@@ -570,6 +570,9 @@ KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
# disable invalid "can't wrap" optimzations for signed / pointers
KBUILD_CFLAGS += $(call cc-option,-fwrapv)
+# revert to pre-gcc-4.4 behaviour of .eh_frame
+KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm)
+
# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
# But warn user when we do so
warn-assign = \
diff --git a/arch/Kconfig b/arch/Kconfig
index a092dc77c24d..dc81b34c5d82 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -107,3 +107,5 @@ config HAVE_CLK
The <linux/clk.h> calls support software clock gating and
thus are a key power management tool on many systems.
+config HAVE_DMA_API_DEBUG
+ bool
diff --git a/arch/alpha/include/asm/machvec.h b/arch/alpha/include/asm/machvec.h
index fea4ea75b79d..13cd42743810 100644
--- a/arch/alpha/include/asm/machvec.h
+++ b/arch/alpha/include/asm/machvec.h
@@ -80,7 +80,7 @@ struct alpha_machine_vector
void (*update_irq_hw)(unsigned long, unsigned long, int);
void (*ack_irq)(unsigned long);
void (*device_interrupt)(unsigned long vector);
- void (*machine_check)(u64 vector, u64 la);
+ void (*machine_check)(unsigned long vector, unsigned long la);
void (*smp_callin)(void);
void (*init_arch)(void);
diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h
index 2a14302c17a3..cb04eaa6ba33 100644
--- a/arch/alpha/include/asm/pci.h
+++ b/arch/alpha/include/asm/pci.h
@@ -273,4 +273,18 @@ struct pci_dev *alpha_gendev_to_pci(struct device *dev);
extern struct pci_dev *isa_bridge;
+extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
+ size_t count);
+extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
+ size_t count);
+extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
+ struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state);
+extern void pci_adjust_legacy_attr(struct pci_bus *bus,
+ enum pci_mmap_state mmap_type);
+#define HAVE_PCI_LEGACY 1
+
+extern int pci_create_resource_files(struct pci_dev *dev);
+extern void pci_remove_resource_files(struct pci_dev *dev);
+
#endif /* __ALPHA_PCI_H */
diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h
index a1057c2d95e7..3641ec1452f4 100644
--- a/arch/alpha/include/asm/socket.h
+++ b/arch/alpha/include/asm/socket.h
@@ -62,6 +62,9 @@
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
* have to define SOCK_NONBLOCK to a different value here.
*/
diff --git a/arch/alpha/include/asm/spinlock.h b/arch/alpha/include/asm/spinlock.h
index aeeb125f6851..e38fb95cb335 100644
--- a/arch/alpha/include/asm/spinlock.h
+++ b/arch/alpha/include/asm/spinlock.h
@@ -166,6 +166,9 @@ static inline void __raw_write_unlock(raw_rwlock_t * lock)
lock->lock = 0;
}
+#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
+#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+
#define _raw_spin_relax(lock) cpu_relax()
#define _raw_read_relax(lock) cpu_relax()
#define _raw_write_relax(lock) cpu_relax()
diff --git a/arch/alpha/include/asm/system.h b/arch/alpha/include/asm/system.h
index afe20fa58c99..5aa40cca4f23 100644
--- a/arch/alpha/include/asm/system.h
+++ b/arch/alpha/include/asm/system.h
@@ -309,518 +309,71 @@ extern int __min_ipl;
#define tbia() __tbi(-2, /* no second argument */)
/*
- * Atomic exchange.
- * Since it can be used to implement critical sections
- * it must clobber "memory" (also for interrupts in UP).
+ * Atomic exchange routines.
*/
-static inline unsigned long
-__xchg_u8(volatile char *m, unsigned long val)
-{
- unsigned long ret, tmp, addr64;
-
- __asm__ __volatile__(
- " andnot %4,7,%3\n"
- " insbl %1,%4,%1\n"
- "1: ldq_l %2,0(%3)\n"
- " extbl %2,%4,%0\n"
- " mskbl %2,%4,%2\n"
- " or %1,%2,%2\n"
- " stq_c %2,0(%3)\n"
- " beq %2,2f\n"
-#ifdef CONFIG_SMP
- " mb\n"
-#endif
- ".subsection 2\n"
- "2: br 1b\n"
- ".previous"
- : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
- : "r" ((long)m), "1" (val) : "memory");
-
- return ret;
-}
-
-static inline unsigned long
-__xchg_u16(volatile short *m, unsigned long val)
-{
- unsigned long ret, tmp, addr64;
-
- __asm__ __volatile__(
- " andnot %4,7,%3\n"
- " inswl %1,%4,%1\n"
- "1: ldq_l %2,0(%3)\n"
- " extwl %2,%4,%0\n"
- " mskwl %2,%4,%2\n"
- " or %1,%2,%2\n"
- " stq_c %2,0(%3)\n"
- " beq %2,2f\n"
-#ifdef CONFIG_SMP
- " mb\n"
-#endif
- ".subsection 2\n"
- "2: br 1b\n"
- ".previous"
- : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
- : "r" ((long)m), "1" (val) : "memory");
-
- return ret;
-}
-
-static inline unsigned long
-__xchg_u32(volatile int *m, unsigned long val)
-{
- unsigned long dummy;
-
- __asm__ __volatile__(
- "1: ldl_l %0,%4\n"
- " bis $31,%3,%1\n"
- " stl_c %1,%2\n"
- " beq %1,2f\n"
-#ifdef CONFIG_SMP
- " mb\n"
-#endif
- ".subsection 2\n"
- "2: br 1b\n"
- ".previous"
- : "=&r" (val), "=&r" (dummy), "=m" (*m)
- : "rI" (val), "m" (*m) : "memory");
-
- return val;
-}
-
-static inline unsigned long
-__xchg_u64(volatile long *m, unsigned long val)
-{
- unsigned long dummy;
-
- __asm__ __volatile__(
- "1: ldq_l %0,%4\n"
- " bis $31,%3,%1\n"
- " stq_c %1,%2\n"
- " beq %1,2f\n"
-#ifdef CONFIG_SMP
- " mb\n"
-#endif
- ".subsection 2\n"
- "2: br 1b\n"
- ".previous"
- : "=&r" (val), "=&r" (dummy), "=m" (*m)
- : "rI" (val), "m" (*m) : "memory");
+#define __ASM__MB
+#define ____xchg(type, args...) __xchg ## type ## _local(args)
+#define ____cmpxchg(type, args...) __cmpxchg ## type ## _local(args)
+#include <asm/xchg.h>
- return val;
-}
-
-/* This function doesn't exist, so you'll get a linker error
- if something tries to do an invalid xchg(). */
-extern void __xchg_called_with_bad_pointer(void);
-
-#define __xchg(ptr, x, size) \
-({ \
- unsigned long __xchg__res; \
- volatile void *__xchg__ptr = (ptr); \
- switch (size) { \
- case 1: __xchg__res = __xchg_u8(__xchg__ptr, x); break; \
- case 2: __xchg__res = __xchg_u16(__xchg__ptr, x); break; \
- case 4: __xchg__res = __xchg_u32(__xchg__ptr, x); break; \
- case 8: __xchg__res = __xchg_u64(__xchg__ptr, x); break; \
- default: __xchg_called_with_bad_pointer(); __xchg__res = x; \
- } \
- __xchg__res; \
-})
-
-#define xchg(ptr,x) \
- ({ \
- __typeof__(*(ptr)) _x_ = (x); \
- (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
+#define xchg_local(ptr,x) \
+ ({ \
+ __typeof__(*(ptr)) _x_ = (x); \
+ (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \
+ sizeof(*(ptr))); \
})
-static inline unsigned long
-__xchg_u8_local(volatile char *m, unsigned long val)
-{
- unsigned long ret, tmp, addr64;
-
- __asm__ __volatile__(
- " andnot %4,7,%3\n"
- " insbl %1,%4,%1\n"
- "1: ldq_l %2,0(%3)\n"
- " extbl %2,%4,%0\n"
- " mskbl %2,%4,%2\n"
- " or %1,%2,%2\n"
- " stq_c %2,0(%3)\n"
- " beq %2,2f\n"
- ".subsection 2\n"
- "2: br 1b\n"
- ".previous"
- : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
- : "r" ((long)m), "1" (val) : "memory");
-
- return ret;
-}
-
-static inline unsigned long
-__xchg_u16_local(volatile short *m, unsigned long val)
-{
- unsigned long ret, tmp, addr64;
-
- __asm__ __volatile__(
- " andnot %4,7,%3\n"
- " inswl %1,%4,%1\n"
- "1: ldq_l %2,0(%3)\n"
- " extwl %2,%4,%0\n"
- " mskwl %2,%4,%2\n"
- " or %1,%2,%2\n"
- " stq_c %2,0(%3)\n"
- " beq %2,2f\n"
- ".subsection 2\n"
- "2: br 1b\n"
- ".previous"
- : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
- : "r" ((long)m), "1" (val) : "memory");
-
- return ret;
-}
-
-static inline unsigned long
-__xchg_u32_local(volatile int *m, unsigned long val)
-{
- unsigned long dummy;
-
- __asm__ __volatile__(
- "1: ldl_l %0,%4\n"
- " bis $31,%3,%1\n"
- " stl_c %1,%2\n"
- " beq %1,2f\n"
- ".subsection 2\n"
- "2: br 1b\n"
- ".previous"
- : "=&r" (val), "=&r" (dummy), "=m" (*m)
- : "rI" (val), "m" (*m) : "memory");
-
- return val;
-}
-
-static inline unsigned long
-__xchg_u64_local(volatile long *m, unsigned long val)
-{
- unsigned long dummy;
-
- __asm__ __volatile__(
- "1: ldq_l %0,%4\n"
- " bis $31,%3,%1\n"
- " stq_c %1,%2\n"
- " beq %1,2f\n"
- ".subsection 2\n"
- "2: br 1b\n"
- ".previous"
- : "=&r" (val), "=&r" (dummy), "=m" (*m)
- : "rI" (val), "m" (*m) : "memory");
-
- return val;
-}
-
-#define __xchg_local(ptr, x, size) \
-({ \
- unsigned long __xchg__res; \
- volatile void *__xchg__ptr = (ptr); \
- switch (size) { \
- case 1: __xchg__res = __xchg_u8_local(__xchg__ptr, x); break; \
- case 2: __xchg__res = __xchg_u16_local(__xchg__ptr, x); break; \
- case 4: __xchg__res = __xchg_u32_local(__xchg__ptr, x); break; \
- case 8: __xchg__res = __xchg_u64_local(__xchg__ptr, x); break; \
- default: __xchg_called_with_bad_pointer(); __xchg__res = x; \
- } \
- __xchg__res; \
-})
-
-#define xchg_local(ptr,x) \
- ({ \
- __typeof__(*(ptr)) _x_ = (x); \
- (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_, \
- sizeof(*(ptr))); \
+#define cmpxchg_local(ptr, o, n) \
+ ({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \
+ (unsigned long)_n_, \
+ sizeof(*(ptr))); \
})
-/*
- * Atomic compare and exchange. Compare OLD with MEM, if identical,
- * store NEW in MEM. Return the initial value in MEM. Success is
- * indicated by comparing RETURN with OLD.
- *
- * The memory barrier should be placed in SMP only when we actually
- * make the change. If we don't change anything (so if the returned
- * prev is equal to old) then we aren't acquiring anything new and
- * we don't need any memory barrier as far I can tell.
- */
-
-#define __HAVE_ARCH_CMPXCHG 1
-
-static inline unsigned long
-__cmpxchg_u8(volatile char *m, long old, long new)
-{
- unsigned long prev, tmp, cmp, addr64;
-
- __asm__ __volatile__(
- " andnot %5,7,%4\n"
- " insbl %1,%5,%1\n"
- "1: ldq_l %2,0(%4)\n"
- " extbl %2,%5,%0\n"
- " cmpeq %0,%6,%3\n"
- " beq %3,2f\n"
- " mskbl %2,%5,%2\n"
- " or %1,%2,%2\n"
- " stq_c %2,0(%4)\n"
- " beq %2,3f\n"
-#ifdef CONFIG_SMP
- " mb\n"
-#endif
- "2:\n"
- ".subsection 2\n"
- "3: br 1b\n"
- ".previous"
- : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
- : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
-
- return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u16(volatile short *m, long old, long new)
-{
- unsigned long prev, tmp, cmp, addr64;
-
- __asm__ __volatile__(
- " andnot %5,7,%4\n"
- " inswl %1,%5,%1\n"
- "1: ldq_l %2,0(%4)\n"
- " extwl %2,%5,%0\n"
- " cmpeq %0,%6,%3\n"
- " beq %3,2f\n"
- " mskwl %2,%5,%2\n"
- " or %1,%2,%2\n"
- " stq_c %2,0(%4)\n"
- " beq %2,3f\n"
-#ifdef CONFIG_SMP
- " mb\n"
-#endif
- "2:\n"
- ".subsection 2\n"
- "3: br 1b\n"
- ".previous"
- : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
- : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
-
- return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u32(volatile int *m, int old, int new)
-{
- unsigned long prev, cmp;
-
- __asm__ __volatile__(
- "1: ldl_l %0,%5\n"
- " cmpeq %0,%3,%1\n"
- " beq %1,2f\n"
- " mov %4,%1\n"
- " stl_c %1,%2\n"
- " beq %1,3f\n"
-#ifdef CONFIG_SMP
- " mb\n"
-#endif
- "2:\n"
- ".subsection 2\n"
- "3: br 1b\n"
- ".previous"
- : "=&r"(prev), "=&r"(cmp), "=m"(*m)
- : "r"((long) old), "r"(new), "m"(*m) : "memory");
-
- return prev;
-}
+#define cmpxchg64_local(ptr, o, n) \
+ ({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ cmpxchg_local((ptr), (o), (n)); \
+ })
-static inline unsigned long
-__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
-{
- unsigned long prev, cmp;
-
- __asm__ __volatile__(
- "1: ldq_l %0,%5\n"
- " cmpeq %0,%3,%1\n"
- " beq %1,2f\n"
- " mov %4,%1\n"
- " stq_c %1,%2\n"
- " beq %1,3f\n"
#ifdef CONFIG_SMP
- " mb\n"
+#undef __ASM__MB
+#define __ASM__MB "\tmb\n"
#endif
- "2:\n"
- ".subsection 2\n"
- "3: br 1b\n"
- ".previous"
- : "=&r"(prev), "=&r"(cmp), "=m"(*m)
- : "r"((long) old), "r"(new), "m"(*m) : "memory");
-
- return prev;
-}
-
-/* This function doesn't exist, so you'll get a linker error
- if something tries to do an invalid cmpxchg(). */
-extern void __cmpxchg_called_with_bad_pointer(void);
-
-static __always_inline unsigned long
-__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
-{
- switch (size) {
- case 1:
- return __cmpxchg_u8(ptr, old, new);
- case 2:
- return __cmpxchg_u16(ptr, old, new);
- case 4:
- return __cmpxchg_u32(ptr, old, new);
- case 8:
- return __cmpxchg_u64(ptr, old, new);
- }
- __cmpxchg_called_with_bad_pointer();
- return old;
-}
-
-#define cmpxchg(ptr, o, n) \
- ({ \
- __typeof__(*(ptr)) _o_ = (o); \
- __typeof__(*(ptr)) _n_ = (n); \
- (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
- (unsigned long)_n_, sizeof(*(ptr))); \
+#undef ____xchg
+#undef ____cmpxchg
+#define ____xchg(type, args...) __xchg ##type(args)
+#define ____cmpxchg(type, args...) __cmpxchg ##type(args)
+#include <asm/xchg.h>
+
+#define xchg(ptr,x) \
+ ({ \
+ __typeof__(*(ptr)) _x_ = (x); \
+ (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, \
+ sizeof(*(ptr))); \
})
-#define cmpxchg64(ptr, o, n) \
- ({ \
- BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
- cmpxchg((ptr), (o), (n)); \
- })
-
-static inline unsigned long
-__cmpxchg_u8_local(volatile char *m, long old, long new)
-{
- unsigned long prev, tmp, cmp, addr64;
-
- __asm__ __volatile__(
- " andnot %5,7,%4\n"
- " insbl %1,%5,%1\n"
- "1: ldq_l %2,0(%4)\n"
- " extbl %2,%5,%0\n"
- " cmpeq %0,%6,%3\n"
- " beq %3,2f\n"
- " mskbl %2,%5,%2\n"
- " or %1,%2,%2\n"
- " stq_c %2,0(%4)\n"
- " beq %2,3f\n"
- "2:\n"
- ".subsection 2\n"
- "3: br 1b\n"
- ".previous"
- : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
- : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
-
- return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u16_local(volatile short *m, long old, long new)
-{
- unsigned long prev, tmp, cmp, addr64;
-
- __asm__ __volatile__(
- " andnot %5,7,%4\n"
- " inswl %1,%5,%1\n"
- "1: ldq_l %2,0(%4)\n"
- " extwl %2,%5,%0\n"
- " cmpeq %0,%6,%3\n"
- " beq %3,2f\n"
- " mskwl %2,%5,%2\n"
- " or %1,%2,%2\n"
- " stq_c %2,0(%4)\n"
- " beq %2,3f\n"
- "2:\n"
- ".subsection 2\n"
- "3: br 1b\n"
- ".previous"
- : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
- : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
-
- return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u32_local(volatile int *m, int old, int new)
-{
- unsigned long prev, cmp;
-
- __asm__ __volatile__(
- "1: ldl_l %0,%5\n"
- " cmpeq %0,%3,%1\n"
- " beq %1,2f\n"
- " mov %4,%1\n"
- " stl_c %1,%2\n"
- " beq %1,3f\n"
- "2:\n"
- ".subsection 2\n"
- "3: br 1b\n"
- ".previous"
- : "=&r"(prev), "=&r"(cmp), "=m"(*m)
- : "r"((long) old), "r"(new), "m"(*m) : "memory");
-
- return prev;
-}
-
-static inline unsigned long
-__cmpxchg_u64_local(volatile long *m, unsigned long old, unsigned long new)
-{
- unsigned long prev, cmp;
-
- __asm__ __volatile__(
- "1: ldq_l %0,%5\n"
- " cmpeq %0,%3,%1\n"
- " beq %1,2f\n"
- " mov %4,%1\n"
- " stq_c %1,%2\n"
- " beq %1,3f\n"
- "2:\n"
- ".subsection 2\n"
- "3: br 1b\n"
- ".previous"
- : "=&r"(prev), "=&r"(cmp), "=m"(*m)
- : "r"((long) old), "r"(new), "m"(*m) : "memory");
-
- return prev;
-}
-
-static __always_inline unsigned long
-__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
- int size)
-{
- switch (size) {
- case 1:
- return __cmpxchg_u8_local(ptr, old, new);
- case 2:
- return __cmpxchg_u16_local(ptr, old, new);
- case 4:
- return __cmpxchg_u32_local(ptr, old, new);
- case 8:
- return __cmpxchg_u64_local(ptr, old, new);
- }
- __cmpxchg_called_with_bad_pointer();
- return old;
-}
-#define cmpxchg_local(ptr, o, n) \
- ({ \
- __typeof__(*(ptr)) _o_ = (o); \
- __typeof__(*(ptr)) _n_ = (n); \
- (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_, \
- (unsigned long)_n_, sizeof(*(ptr))); \
+#define cmpxchg(ptr, o, n) \
+ ({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
+ (unsigned long)_n_, sizeof(*(ptr)));\
})
-#define cmpxchg64_local(ptr, o, n) \
- ({ \
- BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
- cmpxchg_local((ptr), (o), (n)); \
+
+#define cmpxchg64(ptr, o, n) \
+ ({ \
+ BUILD_BUG_ON(sizeof(*(ptr)) != 8); \
+ cmpxchg((ptr), (o), (n)); \
})
+#undef __ASM__MB
+#undef ____cmpxchg
+
+#define __HAVE_ARCH_CMPXCHG 1
#endif /* __ASSEMBLY__ */
diff --git a/arch/alpha/include/asm/types.h b/arch/alpha/include/asm/types.h
index c1541353ccef..f072f344497e 100644
--- a/arch/alpha/include/asm/types.h
+++ b/arch/alpha/include/asm/types.h
@@ -8,7 +8,12 @@
* not a major issue. However, for interoperability, libraries still
* need to be careful to avoid a name clashes.
*/
+
+#ifdef __KERNEL__
+#include <asm-generic/int-ll64.h>
+#else
#include <asm-generic/int-l64.h>
+#endif
#ifndef __ASSEMBLY__
diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h
index 22de3b434a22..163f3053001c 100644
--- a/arch/alpha/include/asm/uaccess.h
+++ b/arch/alpha/include/asm/uaccess.h
@@ -498,13 +498,13 @@ struct exception_table_entry
};
/* Returns the new pc */
-#define fixup_exception(map_reg, fixup, pc) \
+#define fixup_exception(map_reg, _fixup, pc) \
({ \
- if ((fixup)->fixup.bits.valreg != 31) \
- map_reg((fixup)->fixup.bits.valreg) = 0; \
- if ((fixup)->fixup.bits.errreg != 31) \
- map_reg((fixup)->fixup.bits.errreg) = -EFAULT; \
- (pc) + (fixup)->fixup.bits.nextinsn; \
+ if ((_fixup)->fixup.bits.valreg != 31) \
+ map_reg((_fixup)->fixup.bits.valreg) = 0; \
+ if ((_fixup)->fixup.bits.errreg != 31) \
+ map_reg((_fixup)->fixup.bits.errreg) = -EFAULT; \
+ (pc) + (_fixup)->fixup.bits.nextinsn; \
})
diff --git a/arch/alpha/include/asm/xchg.h b/arch/alpha/include/asm/xchg.h
new file mode 100644
index 000000000000..beba1b803e0d
--- /dev/null
+++ b/arch/alpha/include/asm/xchg.h
@@ -0,0 +1,258 @@
+#ifndef __ALPHA_SYSTEM_H
+#error Do not include xchg.h directly!
+#else
+/*
+ * xchg/xchg_local and cmpxchg/cmpxchg_local share the same code
+ * except that local version do not have the expensive memory barrier.
+ * So this file is included twice from asm/system.h.
+ */
+
+/*
+ * Atomic exchange.
+ * Since it can be used to implement critical sections
+ * it must clobber "memory" (also for interrupts in UP).
+ */
+
+static inline unsigned long
+____xchg(_u8, volatile char *m, unsigned long val)
+{
+ unsigned long ret, tmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %4,7,%3\n"
+ " insbl %1,%4,%1\n"
+ "1: ldq_l %2,0(%3)\n"
+ " extbl %2,%4,%0\n"
+ " mskbl %2,%4,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%3)\n"
+ " beq %2,2f\n"
+ __ASM__MB
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
+ : "r" ((long)m), "1" (val) : "memory");
+
+ return ret;
+}
+
+static inline unsigned long
+____xchg(_u16, volatile short *m, unsigned long val)
+{
+ unsigned long ret, tmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %4,7,%3\n"
+ " inswl %1,%4,%1\n"
+ "1: ldq_l %2,0(%3)\n"
+ " extwl %2,%4,%0\n"
+ " mskwl %2,%4,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%3)\n"
+ " beq %2,2f\n"
+ __ASM__MB
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (ret), "=&r" (val), "=&r" (tmp), "=&r" (addr64)
+ : "r" ((long)m), "1" (val) : "memory");
+
+ return ret;
+}
+
+static inline unsigned long
+____xchg(_u32, volatile int *m, unsigned long val)
+{
+ unsigned long dummy;
+
+ __asm__ __volatile__(
+ "1: ldl_l %0,%4\n"
+ " bis $31,%3,%1\n"
+ " stl_c %1,%2\n"
+ " beq %1,2f\n"
+ __ASM__MB
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (val), "=&r" (dummy), "=m" (*m)
+ : "rI" (val), "m" (*m) : "memory");
+
+ return val;
+}
+
+static inline unsigned long
+____xchg(_u64, volatile long *m, unsigned long val)
+{
+ unsigned long dummy;
+
+ __asm__ __volatile__(
+ "1: ldq_l %0,%4\n"
+ " bis $31,%3,%1\n"
+ " stq_c %1,%2\n"
+ " beq %1,2f\n"
+ __ASM__MB
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ : "=&r" (val), "=&r" (dummy), "=m" (*m)
+ : "rI" (val), "m" (*m) : "memory");
+
+ return val;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+ if something tries to do an invalid xchg(). */
+extern void __xchg_called_with_bad_pointer(void);
+
+static __always_inline unsigned long
+____xchg(, volatile void *ptr, unsigned long x, int size)
+{
+ switch (size) {
+ case 1:
+ return ____xchg(_u8, ptr, x);
+ case 2:
+ return ____xchg(_u16, ptr, x);
+ case 4:
+ return ____xchg(_u32, ptr, x);
+ case 8:
+ return ____xchg(_u64, ptr, x);
+ }
+ __xchg_called_with_bad_pointer();
+ return x;
+}
+
+/*
+ * Atomic compare and exchange. Compare OLD with MEM, if identical,
+ * store NEW in MEM. Return the initial value in MEM. Success is
+ * indicated by comparing RETURN with OLD.
+ *
+ * The memory barrier should be placed in SMP only when we actually
+ * make the change. If we don't change anything (so if the returned
+ * prev is equal to old) then we aren't acquiring anything new and
+ * we don't need any memory barrier as far I can tell.
+ */
+
+static inline unsigned long
+____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new)
+{
+ unsigned long prev, tmp, cmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %5,7,%4\n"
+ " insbl %1,%5,%1\n"
+ "1: ldq_l %2,0(%4)\n"
+ " extbl %2,%5,%0\n"
+ " cmpeq %0,%6,%3\n"
+ " beq %3,2f\n"
+ " mskbl %2,%5,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%4)\n"
+ " beq %2,3f\n"
+ __ASM__MB
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
+ : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+
+ return prev;
+}
+
+static inline unsigned long
+____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new)
+{
+ unsigned long prev, tmp, cmp, addr64;
+
+ __asm__ __volatile__(
+ " andnot %5,7,%4\n"
+ " inswl %1,%5,%1\n"
+ "1: ldq_l %2,0(%4)\n"
+ " extwl %2,%5,%0\n"
+ " cmpeq %0,%6,%3\n"
+ " beq %3,2f\n"
+ " mskwl %2,%5,%2\n"
+ " or %1,%2,%2\n"
+ " stq_c %2,0(%4)\n"
+ " beq %2,3f\n"
+ __ASM__MB
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r" (prev), "=&r" (new), "=&r" (tmp), "=&r" (cmp), "=&r" (addr64)
+ : "r" ((long)m), "Ir" (old), "1" (new) : "memory");
+
+ return prev;
+}
+
+static inline unsigned long
+____cmpxchg(_u32, volatile int *m, int old, int new)
+{
+ unsigned long prev, cmp;
+
+ __asm__ __volatile__(
+ "1: ldl_l %0,%5\n"
+ " cmpeq %0,%3,%1\n"
+ " beq %1,2f\n"
+ " mov %4,%1\n"
+ " stl_c %1,%2\n"
+ " beq %1,3f\n"
+ __ASM__MB
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r"(prev), "=&r"(cmp), "=m"(*m)
+ : "r"((long) old), "r"(new), "m"(*m) : "memory");
+
+ return prev;
+}
+
+static inline unsigned long
+____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new)
+{
+ unsigned long prev, cmp;
+
+ __asm__ __volatile__(
+ "1: ldq_l %0,%5\n"
+ " cmpeq %0,%3,%1\n"
+ " beq %1,2f\n"
+ " mov %4,%1\n"
+ " stq_c %1,%2\n"
+ " beq %1,3f\n"
+ __ASM__MB
+ "2:\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r"(prev), "=&r"(cmp), "=m"(*m)
+ : "r"((long) old), "r"(new), "m"(*m) : "memory");
+
+ return prev;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+ if something tries to do an invalid cmpxchg(). */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static __always_inline unsigned long
+____cmpxchg(, volatile void *ptr, unsigned long old, unsigned long new,
+ int size)
+{
+ switch (size) {
+ case 1:
+ return ____cmpxchg(_u8, ptr, old, new);
+ case 2:
+ return ____cmpxchg(_u16, ptr, old, new);
+ case 4:
+ return ____cmpxchg(_u32, ptr, old, new);
+ case 8:
+ return ____cmpxchg(_u64, ptr, old, new);
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
+
+#endif
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
index b4697759a123..a427538252f8 100644
--- a/arch/alpha/kernel/Makefile
+++ b/arch/alpha/kernel/Makefile
@@ -12,7 +12,7 @@ obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \
obj-$(CONFIG_VGA_HOSE) += console.o
obj-$(CONFIG_SMP) += smp.o
-obj-$(CONFIG_PCI) += pci.o pci_iommu.o
+obj-$(CONFIG_PCI) += pci.o pci_iommu.o pci-sysfs.o
obj-$(CONFIG_SRM_ENV) += srm_env.o
obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index e4a54b615894..b45d913a51c3 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -903,8 +903,9 @@ sys_alpha_pipe:
stq $26, 0($sp)
.prologue 0
+ mov $31, $17
lda $16, 8($sp)
- jsr $26, do_pipe
+ jsr $26, do_pipe_flags
ldq $26, 0($sp)
bne $0, 1f
diff --git a/arch/alpha/kernel/err_ev6.c b/arch/alpha/kernel/err_ev6.c
index 11aee012a8ae..985e5c1681ac 100644
--- a/arch/alpha/kernel/err_ev6.c
+++ b/arch/alpha/kernel/err_ev6.c
@@ -157,8 +157,8 @@ ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn,
err_print_prefix,
streamname[stream], bitsname[bits], sourcename[source]);
- printk("%s Address: 0x%016lx\n"
- " Syndrome[upper.lower]: %02lx.%02lx\n",
+ printk("%s Address: 0x%016llx\n"
+ " Syndrome[upper.lower]: %02llx.%02llx\n",
err_print_prefix,
c_addr,
c2_syn, c1_syn);
diff --git a/arch/alpha/kernel/err_ev7.c b/arch/alpha/kernel/err_ev7.c
index 68cd493f54c5..73770c6ca013 100644
--- a/arch/alpha/kernel/err_ev7.c
+++ b/arch/alpha/kernel/err_ev7.c
@@ -246,13 +246,13 @@ ev7_process_pal_subpacket(struct el_subpacket *header)
switch(header->type) {
case EL_TYPE__PAL__LOGOUT_FRAME:
- printk("%s*** MCHK occurred on LPID %ld (RBOX %lx)\n",
+ printk("%s*** MCHK occurred on LPID %ld (RBOX %llx)\n",
err_print_prefix,
packet->by_type.logout.whami,
packet->by_type.logout.rbox_whami);
el_print_timestamp(&packet->by_type.logout.timestamp);
- printk("%s EXC_ADDR: %016lx\n"
- " HALT_CODE: %lx\n",
+ printk("%s EXC_ADDR: %016llx\n"
+ " HALT_CODE: %llx\n",
err_print_prefix,
packet->by_type.logout.exc_addr,
packet->by_type.logout.halt_code);
diff --git a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c
index 413bf37eb094..6bfd243efba3 100644
--- a/arch/alpha/kernel/err_marvel.c
+++ b/arch/alpha/kernel/err_marvel.c
@@ -129,7 +129,7 @@ marvel_print_po7_crrct_sym(u64 crrct_sym)
printk("%s Correctable Error Symptoms:\n"
- "%s Syndrome: 0x%lx\n",
+ "%s Syndrome: 0x%llx\n",
err_print_prefix,
err_print_prefix, EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__SYN));
marvel_print_err_cyc(EXTRACT(crrct_sym, IO7__PO7_CRRCT_SYM__ERR_CYC));
@@ -186,7 +186,7 @@ marvel_print_po7_uncrr_sym(u64 uncrr_sym, u64 valid_mask)
uncrr_sym &= valid_mask;
if (EXTRACT(valid_mask, IO7__PO7_UNCRR_SYM__SYN))
- printk("%s Syndrome: 0x%lx\n",
+ printk("%s Syndrome: 0x%llx\n",
err_print_prefix,
EXTRACT(uncrr_sym, IO7__PO7_UNCRR_SYM__SYN));
@@ -307,7 +307,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym)
sprintf(opcode_str, "BlkIO");
break;
default:
- sprintf(opcode_str, "0x%lx\n",
+ sprintf(opcode_str, "0x%llx\n",
EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE));
break;
}
@@ -321,7 +321,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym)
opcode_str);
if (0xC5 != EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_OPCODE))
- printk("%s Packet Offset 0x%08lx\n",
+ printk("%s Packet Offset 0x%08llx\n",
err_print_prefix,
EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_PKT_OFF));
}
@@ -480,8 +480,8 @@ marvel_print_po7_err_sum(struct ev7_pal_io_subpacket *io)
printk("%s Lost Error\n", err_print_prefix);
printk("%s Failing Packet:\n"
- "%s Cycle 1: %016lx\n"
- "%s Cycle 2: %016lx\n",
+ "%s Cycle 1: %016llx\n"
+ "%s Cycle 2: %016llx\n",
err_print_prefix,
err_print_prefix, io->po7_err_pkt0,
err_print_prefix, io->po7_err_pkt1);
@@ -515,9 +515,9 @@ marvel_print_pox_tlb_err(u64 tlb_err)
if (!(tlb_err & IO7__POX_TLBERR__ERR_VALID))
return;
- printk("%s TLB Error on index 0x%lx:\n"
+ printk("%s TLB Error on index 0x%llx:\n"
"%s - %s\n"
- "%s - Addr: 0x%016lx\n",
+ "%s - Addr: 0x%016llx\n",
err_print_prefix,
EXTRACT(tlb_err, IO7__POX_TLBERR__ERR_TLB_PTR),
err_print_prefix,
@@ -579,7 +579,7 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt)
sprintf(message, "Uncorrectable Split Write Data Error");
break;
default:
- sprintf(message, "%08lx\n",
+ sprintf(message, "%08llx\n",
EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__MESSAGE));
break;
}
@@ -620,9 +620,9 @@ marvel_print_pox_trans_sum(u64 trans_sum)
return;
printk("%s Transaction Summary:\n"
- "%s Command: 0x%lx - %s\n"
- "%s Address: 0x%016lx%s\n"
- "%s PCI-X Master Slot: 0x%lx\n",
+ "%s Command: 0x%llx - %s\n"
+ "%s Address: 0x%016llx%s\n"
+ "%s PCI-X Master Slot: 0x%llx\n",
err_print_prefix,
err_print_prefix,
EXTRACT(trans_sum, IO7__POX_TRANSUM__PCIX_CMD),
@@ -964,12 +964,12 @@ marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print)
#if 0
printk("%s PORT 7 ERROR:\n"
- "%s PO7_ERROR_SUM: %016lx\n"
- "%s PO7_UNCRR_SYM: %016lx\n"
- "%s PO7_CRRCT_SYM: %016lx\n"
- "%s PO7_UGBGE_SYM: %016lx\n"
- "%s PO7_ERR_PKT0: %016lx\n"
- "%s PO7_ERR_PKT1: %016lx\n",
+ "%s PO7_ERROR_SUM: %016llx\n"
+ "%s PO7_UNCRR_SYM: %016llx\n"
+ "%s PO7_CRRCT_SYM: %016llx\n"
+ "%s PO7_UGBGE_SYM: %016llx\n"
+ "%s PO7_ERR_PKT0: %016llx\n"
+ "%s PO7_ERR_PKT1: %016llx\n",
err_print_prefix,
err_print_prefix, io->po7_error_sum,
err_print_prefix, io->po7_uncrr_sym,
@@ -987,12 +987,12 @@ marvel_process_io_error(struct ev7_lf_subpackets *lf_subpackets, int print)
if (!MARVEL_IO_ERR_VALID(io->ports[i].pox_err_sum))
continue;
- printk("%s PID %u PORT %d POx_ERR_SUM: %016lx\n",
+ printk("%s PID %u PORT %d POx_ERR_SUM: %016llx\n",
err_print_prefix,
lf_subpackets->io_pid, i, io->ports[i].pox_err_sum);
marvel_print_pox_err(io->ports[i].pox_err_sum, &io->ports[i]);
- printk("%s [ POx_FIRST_ERR: %016lx ]\n",
+ printk("%s [ POx_FIRST_ERR: %016llx ]\n",
err_print_prefix, io->ports[i].pox_first_err);
marvel_print_pox_err(io->ports[i].pox_first_err,
&io->ports[i]);
diff --git a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c
index 257449ed15ef..c7e28a88d6e3 100644
--- a/arch/alpha/kernel/err_titan.c
+++ b/arch/alpha/kernel/err_titan.c
@@ -107,12 +107,12 @@ titan_parse_p_serror(int which, u64 serror, int print)
if (!print)
return status;
- printk("%s PChip %d SERROR: %016lx\n",
+ printk("%s PChip %d SERROR: %016llx\n",
err_print_prefix, which, serror);
if (serror & TITAN__PCHIP_SERROR__ECCMASK) {
printk("%s %sorrectable ECC Error:\n"
" Source: %-6s Command: %-8s Syndrome: 0x%08x\n"
- " Address: 0x%lx\n",
+ " Address: 0x%llx\n",
err_print_prefix,
(serror & TITAN__PCHIP_SERROR__UECC) ? "Unc" : "C",
serror_src[EXTRACT(serror, TITAN__PCHIP_SERROR__SRC)],
@@ -223,7 +223,7 @@ titan_parse_p_perror(int which, int port, u64 perror, int print)
if (!print)
return status;
- printk("%s PChip %d %cPERROR: %016lx\n",
+ printk("%s PChip %d %cPERROR: %016llx\n",
err_print_prefix, which,
port ? 'A' : 'G', perror);
if (perror & TITAN__PCHIP_PERROR__IPTPW)
@@ -316,7 +316,7 @@ titan_parse_p_agperror(int which, u64 agperror, int print)
addr = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__ADDR) << 3;
len = EXTRACT(agperror, TITAN__PCHIP_AGPERROR__LEN);
- printk("%s PChip %d AGPERROR: %016lx\n", err_print_prefix,
+ printk("%s PChip %d AGPERROR: %016llx\n", err_print_prefix,
which, agperror);
if (agperror & TITAN__PCHIP_AGPERROR__NOWINDOW)
printk("%s No Window\n", err_print_prefix);
@@ -597,16 +597,16 @@ privateer_process_680_frame(struct el_common *mchk_header, int print)
return status;
/* TODO - decode instead of just dumping... */
- printk("%s Summary Flags: %016lx\n"
- " CChip DIRx: %016lx\n"
- " System Management IR: %016lx\n"
- " CPU IR: %016lx\n"
- " Power Supply IR: %016lx\n"
- " LM78 Fault Status: %016lx\n"
- " System Doors: %016lx\n"
- " Temperature Warning: %016lx\n"
- " Fan Control: %016lx\n"
- " Fatal Power Down Code: %016lx\n",
+ printk("%s Summary Flags: %016llx\n"
+ " CChip DIRx: %016llx\n"
+ " System Management IR: %016llx\n"
+ " CPU IR: %016llx\n"
+ " Power Supply IR: %016llx\n"
+ " LM78 Fault Status: %016llx\n"
+ " System Doors: %016llx\n"
+ " Temperature Warning: %016llx\n"
+ " Fan Control: %016llx\n"
+ " Fatal Power Down Code: %016llx\n",
err_print_prefix,
emchk->summary,
emchk->c_dirx,
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 7bc7489223f3..cc7834661427 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -90,7 +90,7 @@ show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%10u ", kstat_irqs(irq));
#else
for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
#endif
seq_printf(p, " %14s", irq_desc[irq].chip->typename);
seq_printf(p, " %c%s",
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
index e16aeb6e79ef..67c19f8a9944 100644
--- a/arch/alpha/kernel/irq_alpha.c
+++ b/arch/alpha/kernel/irq_alpha.c
@@ -64,7 +64,7 @@ do_entInt(unsigned long type, unsigned long vector,
smp_percpu_timer_interrupt(regs);
cpu = smp_processor_id();
if (cpu != boot_cpuid) {
- kstat_cpu(cpu).irqs[RTC_IRQ]++;
+ kstat_incr_irqs_this_cpu(RTC_IRQ, irq_to_desc(RTC_IRQ));
} else {
handle_irq(RTC_IRQ);
}
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index ae41f097864b..42ee05981e71 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -46,8 +46,6 @@
#include <asm/hwrpb.h>
#include <asm/processor.h>
-extern int do_pipe(int *);
-
/*
* Brk needs to return an error. Still support Linux's brk(0) query idiom,
* which OSF programs just shouldn't be doing. We're still not quite
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
new file mode 100644
index 000000000000..6ea822e7f724
--- /dev/null
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -0,0 +1,366 @@
+/*
+ * arch/alpha/kernel/pci-sysfs.c
+ *
+ * Copyright (C) 2009 Ivan Kokshaysky
+ *
+ * Alpha PCI resource files.
+ *
+ * Loosely based on generic HAVE_PCI_MMAP implementation in
+ * drivers/pci/pci-sysfs.c
+ */
+
+#include <linux/sched.h>
+#include <linux/pci.h>
+
+static int hose_mmap_page_range(struct pci_controller *hose,
+ struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_type, int sparse)
+{
+ unsigned long base;
+
+ if (mmap_type == pci_mmap_mem)
+ base = sparse ? hose->sparse_mem_base : hose->dense_mem_base;
+ else
+ base = sparse ? hose->sparse_io_base : hose->dense_io_base;
+
+ vma->vm_pgoff += base >> PAGE_SHIFT;
+ vma->vm_flags |= (VM_IO | VM_RESERVED);
+
+ return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
+static int __pci_mmap_fits(struct pci_dev *pdev, int num,
+ struct vm_area_struct *vma, int sparse)
+{
+ unsigned long nr, start, size;
+ int shift = sparse ? 5 : 0;
+
+ nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+ start = vma->vm_pgoff;
+ size = ((pci_resource_len(pdev, num) - 1) >> (PAGE_SHIFT - shift)) + 1;
+
+ if (start < size && size - start >= nr)
+ return 1;
+ WARN(1, "process \"%s\" tried to map%s 0x%08lx-0x%08lx on %s BAR %d "
+ "(size 0x%08lx)\n",
+ current->comm, sparse ? " sparse" : "", start, start + nr,
+ pci_name(pdev), num, size);
+ return 0;
+}
+
+/**
+ * pci_mmap_resource - map a PCI resource into user memory space
+ * @kobj: kobject for mapping
+ * @attr: struct bin_attribute for the file being mapped
+ * @vma: struct vm_area_struct passed into the mmap
+ * @sparse: address space type
+ *
+ * Use the bus mapping routines to map a PCI resource into userspace.
+ */
+static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
+ struct vm_area_struct *vma, int sparse)
+{
+ struct pci_dev *pdev = to_pci_dev(container_of(kobj,
+ struct device, kobj));
+ struct resource *res = (struct resource *)attr->private;
+ enum pci_mmap_state mmap_type;
+ struct pci_bus_region bar;
+ int i;
+
+ for (i = 0; i < PCI_ROM_RESOURCE; i++)
+ if (res == &pdev->resource[i])
+ break;
+ if (i >= PCI_ROM_RESOURCE)
+ return -ENODEV;
+
+ if (!__pci_mmap_fits(pdev, i, vma, sparse))
+ return -EINVAL;
+
+ if (iomem_is_exclusive(res->start))
+ return -EINVAL;
+
+ pcibios_resource_to_bus(pdev, &bar, res);
+ vma->vm_pgoff += bar.start >> (PAGE_SHIFT - (sparse ? 5 : 0));
+ mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
+
+ return hose_mmap_page_range(pdev->sysdata, vma, mmap_type, sparse);
+}
+
+static int pci_mmap_resource_sparse(struct kobject *kobj,
+ struct bin_attribute *attr,
+ struct vm_area_struct *vma)
+{
+ return pci_mmap_resource(kobj, attr, vma, 1);
+}
+
+static int pci_mmap_resource_dense(struct kobject *kobj,
+ struct bin_attribute *attr,
+ struct vm_area_struct *vma)
+{
+ return pci_mmap_resource(kobj, attr, vma, 0);
+}
+
+/**
+ * pci_remove_resource_files - cleanup resource files
+ * @dev: dev to cleanup
+ *
+ * If we created resource files for @dev, remove them from sysfs and
+ * free their resources.
+ */
+void pci_remove_resource_files(struct pci_dev *pdev)
+{
+ int i;
+
+ for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+ struct bin_attribute *res_attr;
+
+ res_attr = pdev->res_attr[i];
+ if (res_attr) {
+ sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
+ kfree(res_attr);
+ }
+
+ res_attr = pdev->res_attr_wc[i];
+ if (res_attr) {
+ sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
+ kfree(res_attr);
+ }
+ }
+}
+
+static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num)
+{
+ struct pci_bus_region bar;
+ struct pci_controller *hose = pdev->sysdata;
+ long dense_offset;
+ unsigned long sparse_size;
+
+ pcibios_resource_to_bus(pdev, &bar, &pdev->resource[num]);
+
+ /* All core logic chips have 4G sparse address space, except
+ CIA which has 16G (see xxx_SPARSE_MEM and xxx_DENSE_MEM
+ definitions in asm/core_xxx.h files). This corresponds
+ to 128M or 512M of the bus space. */
+ dense_offset = (long)(hose->dense_mem_base - hose->sparse_mem_base);
+ sparse_size = dense_offset >= 0x400000000UL ? 0x20000000 : 0x8000000;
+
+ return bar.end < sparse_size;
+}
+
+static int pci_create_one_attr(struct pci_dev *pdev, int num, char *name,
+ char *suffix, struct bin_attribute *res_attr,
+ unsigned long sparse)
+{
+ size_t size = pci_resource_len(pdev, num);
+
+ sprintf(name, "resource%d%s", num, suffix);
+ res_attr->mmap = sparse ? pci_mmap_resource_sparse :
+ pci_mmap_resource_dense;
+ res_attr->attr.name = name;
+ res_attr->attr.mode = S_IRUSR | S_IWUSR;
+ res_attr->size = sparse ? size << 5 : size;
+ res_attr->private = &pdev->resource[num];
+ return sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
+}
+
+static int pci_create_attr(struct pci_dev *pdev, int num)
+{
+ /* allocate attribute structure, piggyback attribute name */
+ int retval, nlen1, nlen2 = 0, res_count = 1;
+ unsigned long sparse_base, dense_base;
+ struct bin_attribute *attr;
+ struct pci_controller *hose = pdev->sysdata;
+ char *suffix, *attr_name;
+
+ suffix = ""; /* Assume bwx machine, normal resourceN files. */
+ nlen1 = 10;
+
+ if (pdev->resource[num].flags & IORESOURCE_MEM) {
+ sparse_base = hose->sparse_mem_base;
+ dense_base = hose->dense_mem_base;
+ if (sparse_base && !sparse_mem_mmap_fits(pdev, num)) {
+ sparse_base = 0;
+ suffix = "_dense";
+ nlen1 = 16; /* resourceN_dense */
+ }
+ } else {
+ sparse_base = hose->sparse_io_base;
+ dense_base = hose->dense_io_base;
+ }
+
+ if (sparse_base) {
+ suffix = "_sparse";
+ nlen1 = 17;
+ if (dense_base) {
+ nlen2 = 16; /* resourceN_dense */
+ res_count = 2;
+ }
+ }
+
+ attr = kzalloc(sizeof(*attr) * res_count + nlen1 + nlen2, GFP_ATOMIC);
+ if (!attr)
+ return -ENOMEM;
+
+ /* Create bwx, sparse or single dense file */
+ attr_name = (char *)(attr + res_count);
+ pdev->res_attr[num] = attr;
+ retval = pci_create_one_attr(pdev, num, attr_name, suffix, attr,
+ sparse_base);
+ if (retval || res_count == 1)
+ return retval;
+
+ /* Create dense file */
+ attr_name += nlen1;
+ attr++;
+ pdev->res_attr_wc[num] = attr;
+ return pci_create_one_attr(pdev, num, attr_name, "_dense", attr, 0);
+}
+
+/**
+ * pci_create_resource_files - create resource files in sysfs for @dev
+ * @dev: dev in question
+ *
+ * Walk the resources in @dev creating files for each resource available.
+ */
+int pci_create_resource_files(struct pci_dev *pdev)
+{
+ int i;
+ int retval;
+
+ /* Expose the PCI resources from this device as files */
+ for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+
+ /* skip empty resources */
+ if (!pci_resource_len(pdev, i))
+ continue;
+
+ retval = pci_create_attr(pdev, i);
+ if (retval) {
+ pci_remove_resource_files(pdev);
+ return retval;
+ }
+ }
+ return 0;
+}
+
+/* Legacy I/O bus mapping stuff. */
+
+static int __legacy_mmap_fits(struct pci_controller *hose,
+ struct vm_area_struct *vma,
+ unsigned long res_size, int sparse)
+{
+ unsigned long nr, start, size;
+
+ nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+ start = vma->vm_pgoff;
+ size = ((res_size - 1) >> PAGE_SHIFT) + 1;
+
+ if (start < size && size - start >= nr)
+ return 1;
+ WARN(1, "process \"%s\" tried to map%s 0x%08lx-0x%08lx on hose %d "
+ "(size 0x%08lx)\n",
+ current->comm, sparse ? " sparse" : "", start, start + nr,
+ hose->index, size);
+ return 0;
+}
+
+static inline int has_sparse(struct pci_controller *hose,
+ enum pci_mmap_state mmap_type)
+{
+ unsigned long base;
+
+ base = (mmap_type == pci_mmap_mem) ? hose->sparse_mem_base :
+ hose->sparse_io_base;
+
+ return base != 0;
+}
+
+int pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_type)
+{
+ struct pci_controller *hose = bus->sysdata;
+ int sparse = has_sparse(hose, mmap_type);
+ unsigned long res_size;
+
+ res_size = (mmap_type == pci_mmap_mem) ? bus->legacy_mem->size :
+ bus->legacy_io->size;
+ if (!__legacy_mmap_fits(hose, vma, res_size, sparse))
+ return -EINVAL;
+
+ return hose_mmap_page_range(hose, vma, mmap_type, sparse);
+}
+
+/**
+ * pci_adjust_legacy_attr - adjustment of legacy file attributes
+ * @b: bus to create files under
+ * @mmap_type: I/O port or memory
+ *
+ * Adjust file name and size for sparse mappings.
+ */
+void pci_adjust_legacy_attr(struct pci_bus *bus, enum pci_mmap_state mmap_type)
+{
+ struct pci_controller *hose = bus->sysdata;
+
+ if (!has_sparse(hose, mmap_type))
+ return;
+
+ if (mmap_type == pci_mmap_mem) {
+ bus->legacy_mem->attr.name = "legacy_mem_sparse";
+ bus->legacy_mem->size <<= 5;
+ } else {
+ bus->legacy_io->attr.name = "legacy_io_sparse";
+ bus->legacy_io->size <<= 5;
+ }
+ return;
+}
+
+/* Legacy I/O bus read/write functions */
+int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size)
+{
+ struct pci_controller *hose = bus->sysdata;
+
+ port += hose->io_space->start;
+
+ switch(size) {
+ case 1:
+ *((u8 *)val) = inb(port);
+ return 1;
+ case 2:
+ if (port & 1)
+ return -EINVAL;
+ *((u16 *)val) = inw(port);
+ return 2;
+ case 4:
+ if (port & 3)
+ return -EINVAL;
+ *((u32 *)val) = inl(port);
+ return 4;
+ }
+ return -EINVAL;
+}
+
+int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size)
+{
+ struct pci_controller *hose = bus->sysdata;
+
+ port += hose->io_space->start;
+
+ switch(size) {
+ case 1:
+ outb(port, val);
+ return 1;
+ case 2:
+ if (port & 1)
+ return -EINVAL;
+ outw(port, val);
+ return 2;
+ case 4:
+ if (port & 3)
+ return -EINVAL;
+ outl(port, val);
+ return 4;
+ }
+ return -EINVAL;
+}
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index a3b938811400..a91ba28999b5 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -168,7 +168,7 @@ pcibios_align_resource(void *data, struct resource *res,
*/
/* Align to multiple of size of minimum base. */
- alignto = max(0x1000UL, align);
+ alignto = max_t(resource_size_t, 0x1000, align);
start = ALIGN(start, alignto);
if (hose->sparse_mem_base && size <= 7 * 16*MB) {
if (((start / (16*MB)) & 0x7) == 0) {
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index b9094da05d7a..bfb880af959d 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -247,7 +247,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
&& paddr + size <= __direct_map_size) {
ret = paddr + __direct_map_base;
- DBGA2("pci_map_single: [%p,%lx] -> direct %lx from %p\n",
+ DBGA2("pci_map_single: [%p,%zx] -> direct %llx from %p\n",
cpu_addr, size, ret, __builtin_return_address(0));
return ret;
@@ -258,7 +258,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
if (dac_allowed) {
ret = paddr + alpha_mv.pci_dac_offset;
- DBGA2("pci_map_single: [%p,%lx] -> DAC %lx from %p\n",
+ DBGA2("pci_map_single: [%p,%zx] -> DAC %llx from %p\n",
cpu_addr, size, ret, __builtin_return_address(0));
return ret;
@@ -299,7 +299,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
ret = arena->dma_base + dma_ofs * PAGE_SIZE;
ret += (unsigned long)cpu_addr & ~PAGE_MASK;
- DBGA2("pci_map_single: [%p,%lx] np %ld -> sg %lx from %p\n",
+ DBGA2("pci_map_single: [%p,%zx] np %ld -> sg %llx from %p\n",
cpu_addr, size, npages, ret, __builtin_return_address(0));
return ret;
@@ -355,14 +355,14 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
&& dma_addr < __direct_map_base + __direct_map_size) {
/* Nothing to do. */
- DBGA2("pci_unmap_single: direct [%lx,%lx] from %p\n",
+ DBGA2("pci_unmap_single: direct [%llx,%zx] from %p\n",
dma_addr, size, __builtin_return_address(0));
return;
}
if (dma_addr > 0xffffffff) {
- DBGA2("pci64_unmap_single: DAC [%lx,%lx] from %p\n",
+ DBGA2("pci64_unmap_single: DAC [%llx,%zx] from %p\n",
dma_addr, size, __builtin_return_address(0));
return;
}
@@ -373,9 +373,9 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
dma_ofs = (dma_addr - arena->dma_base) >> PAGE_SHIFT;
if (dma_ofs * PAGE_SIZE >= arena->size) {
- printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %lx "
- " base %lx size %x\n", dma_addr, arena->dma_base,
- arena->size);
+ printk(KERN_ERR "Bogus pci_unmap_single: dma_addr %llx "
+ " base %llx size %x\n",
+ dma_addr, arena->dma_base, arena->size);
return;
BUG();
}
@@ -394,7 +394,7 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
spin_unlock_irqrestore(&arena->lock, flags);
- DBGA2("pci_unmap_single: sg [%lx,%lx] np %ld from %p\n",
+ DBGA2("pci_unmap_single: sg [%llx,%zx] np %ld from %p\n",
dma_addr, size, npages, __builtin_return_address(0));
}
EXPORT_SYMBOL(pci_unmap_single);
@@ -444,7 +444,7 @@ try_again:
goto try_again;
}
- DBGA2("pci_alloc_consistent: %lx -> [%p,%x] from %p\n",
+ DBGA2("pci_alloc_consistent: %zx -> [%p,%llx] from %p\n",
size, cpu_addr, *dma_addrp, __builtin_return_address(0));
return cpu_addr;
@@ -464,7 +464,7 @@ pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu_addr,
pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);
free_pages((unsigned long)cpu_addr, get_order(size));
- DBGA2("pci_free_consistent: [%x,%lx] from %p\n",
+ DBGA2("pci_free_consistent: [%llx,%zx] from %p\n",
dma_addr, size, __builtin_return_address(0));
}
EXPORT_SYMBOL(pci_free_consistent);
@@ -551,7 +551,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
out->dma_address = paddr + __direct_map_base;
out->dma_length = size;
- DBGA(" sg_fill: [%p,%lx] -> direct %lx\n",
+ DBGA(" sg_fill: [%p,%lx] -> direct %llx\n",
__va(paddr), size, out->dma_address);
return 0;
@@ -563,7 +563,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
out->dma_address = paddr + alpha_mv.pci_dac_offset;
out->dma_length = size;
- DBGA(" sg_fill: [%p,%lx] -> DAC %lx\n",
+ DBGA(" sg_fill: [%p,%lx] -> DAC %llx\n",
__va(paddr), size, out->dma_address);
return 0;
@@ -589,7 +589,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
out->dma_address = arena->dma_base + dma_ofs*PAGE_SIZE + paddr;
out->dma_length = size;
- DBGA(" sg_fill: [%p,%lx] -> sg %lx np %ld\n",
+ DBGA(" sg_fill: [%p,%lx] -> sg %llx np %ld\n",
__va(paddr), size, out->dma_address, npages);
/* All virtually contiguous. We need to find the length of each
@@ -752,7 +752,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
if (addr > 0xffffffff) {
/* It's a DAC address -- nothing to do. */
- DBGA(" (%ld) DAC [%lx,%lx]\n",
+ DBGA(" (%ld) DAC [%llx,%zx]\n",
sg - end + nents, addr, size);
continue;
}
@@ -760,12 +760,12 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
if (addr >= __direct_map_base
&& addr < __direct_map_base + __direct_map_size) {
/* Nothing to do. */
- DBGA(" (%ld) direct [%lx,%lx]\n",
+ DBGA(" (%ld) direct [%llx,%zx]\n",
sg - end + nents, addr, size);
continue;
}
- DBGA(" (%ld) sg [%lx,%lx]\n",
+ DBGA(" (%ld) sg [%llx,%zx]\n",
sg - end + nents, addr, size);
npages = iommu_num_pages(addr, size, PAGE_SIZE);
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 8d0097f10208..3a2fb7a02db4 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -272,7 +272,7 @@ alpha_vfork(struct pt_regs *regs)
*/
int
-copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index fe14c6747cd6..567f2598d090 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -20,7 +20,7 @@ struct pci_controller;
extern struct pci_ops apecs_pci_ops;
extern void apecs_init_arch(void);
extern void apecs_pci_clr_err(void);
-extern void apecs_machine_check(u64, u64);
+extern void apecs_machine_check(unsigned long vector, unsigned long la_ptr);
extern void apecs_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_cia.c */
@@ -29,7 +29,7 @@ extern void cia_init_pci(void);
extern void cia_init_arch(void);
extern void pyxis_init_arch(void);
extern void cia_kill_arch(int);
-extern void cia_machine_check(u64, u64);
+extern void cia_machine_check(unsigned long vector, unsigned long la_ptr);
extern void cia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_irongate.c */
@@ -42,7 +42,7 @@ extern void irongate_machine_check(u64, u64);
/* core_lca.c */
extern struct pci_ops lca_pci_ops;
extern void lca_init_arch(void);
-extern void lca_machine_check(u64, u64);
+extern void lca_machine_check(unsigned long vector, unsigned long la_ptr);
extern void lca_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_marvel.c */
@@ -64,7 +64,7 @@ void io7_clear_errors(struct io7 *io7);
extern struct pci_ops mcpcia_pci_ops;
extern void mcpcia_init_arch(void);
extern void mcpcia_init_hoses(void);
-extern void mcpcia_machine_check(u64, u64);
+extern void mcpcia_machine_check(unsigned long vector, unsigned long la_ptr);
extern void mcpcia_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_polaris.c */
@@ -72,14 +72,14 @@ extern struct pci_ops polaris_pci_ops;
extern int polaris_read_config_dword(struct pci_dev *, int, u32 *);
extern int polaris_write_config_dword(struct pci_dev *, int, u32);
extern void polaris_init_arch(void);
-extern void polaris_machine_check(u64, u64);
+extern void polaris_machine_check(unsigned long vector, unsigned long la_ptr);
#define polaris_pci_tbi ((void *)0)
/* core_t2.c */
extern struct pci_ops t2_pci_ops;
extern void t2_init_arch(void);
extern void t2_kill_arch(int);
-extern void t2_machine_check(u64, u64);
+extern void t2_machine_check(unsigned long vector, unsigned long la_ptr);
extern void t2_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_titan.c */
@@ -94,14 +94,14 @@ extern struct _alpha_agp_info *titan_agp_info(void);
extern struct pci_ops tsunami_pci_ops;
extern void tsunami_init_arch(void);
extern void tsunami_kill_arch(int);
-extern void tsunami_machine_check(u64, u64);
+extern void tsunami_machine_check(unsigned long vector, unsigned long la_ptr);
extern void tsunami_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
/* core_wildfire.c */
extern struct pci_ops wildfire_pci_ops;
extern void wildfire_init_arch(void);
extern void wildfire_kill_arch(int);
-extern void wildfire_machine_check(u64, u64);
+extern void wildfire_machine_check(unsigned long vector, unsigned long la_ptr);
extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
extern int wildfire_pa_to_nid(unsigned long);
extern int wildfire_cpuid_to_nid(int);
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 02bee6983ce2..80df86cd746b 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -1255,7 +1255,7 @@ show_cpuinfo(struct seq_file *f, void *slot)
platform_string(), nr_processors);
#ifdef CONFIG_SMP
- seq_printf(f, "cpus active\t\t: %d\n"
+ seq_printf(f, "cpus active\t\t: %u\n"
"cpu active mask\t\t: %016lx\n",
num_online_cpus(), cpus_addr(cpu_possible_map)[0]);
#endif
diff --git a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c
index fd467b207f0f..bca5bda90cde 100644
--- a/arch/alpha/kernel/smc37c669.c
+++ b/arch/alpha/kernel/smc37c669.c
@@ -2542,8 +2542,8 @@ void __init SMC669_Init ( int index )
SMC37c669_display_device_info( );
#endif
local_irq_restore(flags);
- printk( "SMC37c669 Super I/O Controller found @ 0x%lx\n",
- (unsigned long) SMC_base );
+ printk( "SMC37c669 Super I/O Controller found @ 0x%p\n",
+ SMC_base );
}
else {
local_irq_restore(flags);
diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c
index 78ad7cd1bbd6..d12af472e1c0 100644
--- a/arch/alpha/kernel/srm_env.c
+++ b/arch/alpha/kernel/srm_env.c
@@ -218,7 +218,6 @@ srm_env_init(void)
BASE_DIR);
goto cleanup;
}
- base_dir->owner = THIS_MODULE;
/*
* Create per-name subdirectory
@@ -229,7 +228,6 @@ srm_env_init(void)
BASE_DIR, NAMED_DIR);
goto cleanup;
}
- named_dir->owner = THIS_MODULE;
/*
* Create per-number subdirectory
@@ -241,7 +239,6 @@ srm_env_init(void)
goto cleanup;
}
- numbered_dir->owner = THIS_MODULE;
/*
* Create all named nodes
@@ -254,7 +251,6 @@ srm_env_init(void)
goto cleanup;
entry->proc_entry->data = (void *) entry;
- entry->proc_entry->owner = THIS_MODULE;
entry->proc_entry->read_proc = srm_env_read;
entry->proc_entry->write_proc = srm_env_write;
@@ -275,7 +271,6 @@ srm_env_init(void)
entry->id = var_num;
entry->proc_entry->data = (void *) entry;
- entry->proc_entry->owner = THIS_MODULE;
entry->proc_entry->read_proc = srm_env_read;
entry->proc_entry->write_proc = srm_env_write;
}
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
index e2516f9a8967..2b5caf3d9b15 100644
--- a/arch/alpha/kernel/sys_jensen.c
+++ b/arch/alpha/kernel/sys_jensen.c
@@ -244,12 +244,11 @@ jensen_init_arch(void)
}
static void
-jensen_machine_check (u64 vector, u64 la)
+jensen_machine_check(unsigned long vector, unsigned long la)
{
printk(KERN_CRIT "Machine check\n");
}
-
/*
* The System Vector
*/
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
index d232e42be018..9e263256a42d 100644
--- a/arch/alpha/kernel/sys_sable.c
+++ b/arch/alpha/kernel/sys_sable.c
@@ -453,7 +453,7 @@ sable_lynx_enable_irq(unsigned int irq)
sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
spin_unlock(&sable_lynx_irq_lock);
#if 0
- printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n",
+ printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
__func__, mask, bit, irq);
#endif
}
@@ -469,7 +469,7 @@ sable_lynx_disable_irq(unsigned int irq)
sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
spin_unlock(&sable_lynx_irq_lock);
#if 0
- printk("%s: mask 0x%lx bit 0x%x irq 0x%x\n",
+ printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
__func__, mask, bit, irq);
#endif
}
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index cefc5a355ef9..6ee7655b7568 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -623,7 +623,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
}
lock_kernel();
- printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n",
+ printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n",
pc, va, opcode, reg);
do_exit(SIGSEGV);
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index dbfdf87f993f..e02b893fb909 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -241,6 +241,7 @@ config ARCH_VERSATILE
config ARCH_AT91
bool "Atmel AT91"
select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
help
This enables support for systems based on the Atmel AT91RM9200,
@@ -275,6 +276,14 @@ config ARCH_EP93XX
help
This enables support for the Cirrus EP93xx series of CPUs.
+config ARCH_GEMINI
+ bool "Cortina Systems Gemini"
+ select CPU_FA526
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ Support for the Cortina Systems Gemini family SoCs
+
config ARCH_FOOTBRIDGE
bool "FootBridge"
select CPU_SA110
@@ -477,12 +486,29 @@ config ARCH_PXA
select HAVE_CLK
select COMMON_CLKDEV
select ARCH_REQUIRE_GPIOLIB
+ select HAVE_CLK
+ select COMMON_CLKDEV
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select TICK_ONESHOT
+ select PLAT_PXA
help
Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
+config ARCH_MMP
+ bool "Marvell PXA168/910"
+ depends on MMU
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select TICK_ONESHOT
+ select PLAT_PXA
+ help
+ Support for Marvell's PXA168/910 processor line.
+
config ARCH_RPC
bool "RiscPC"
select ARCH_ACORN
@@ -598,6 +624,8 @@ source "arch/arm/mach-ep93xx/Kconfig"
source "arch/arm/mach-footbridge/Kconfig"
+source "arch/arm/mach-gemini/Kconfig"
+
source "arch/arm/mach-integrator/Kconfig"
source "arch/arm/mach-iop32x/Kconfig"
@@ -617,6 +645,9 @@ source "arch/arm/mach-loki/Kconfig"
source "arch/arm/mach-mv78xx0/Kconfig"
source "arch/arm/mach-pxa/Kconfig"
+source "arch/arm/plat-pxa/Kconfig"
+
+source "arch/arm/mach-mmp/Kconfig"
source "arch/arm/mach-sa1100/Kconfig"
@@ -686,12 +717,15 @@ config PLAT_IOP
config PLAT_ORION
bool
+config PLAT_PXA
+ bool
+
source arch/arm/mm/Kconfig
config IWMMXT
bool "Enable iWMMXt support"
- depends on CPU_XSCALE || CPU_XSC3
- default y if PXA27x || PXA3xx
+ depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
+ default y if PXA27x || PXA3xx || ARCH_MMP
help
Enable support for iWMMXt context switching at run time if
running on a CPU that supports it.
@@ -915,6 +949,23 @@ config NODES_SHIFT
default "2"
depends on NEED_MULTIPLE_NODES
+config HIGHMEM
+ bool "High Memory Support (EXPERIMENTAL)"
+ depends on MMU && EXPERIMENTAL
+ help
+ The address space of ARM processors is only 4 Gigabytes large
+ and it has to accommodate user address space, kernel address
+ space as well as some memory mapped IO. That means that, if you
+ have a large amount of physical memory and/or IO, not all of the
+ memory can be "permanently mapped" by the kernel. The physical
+ memory that is not permanently mapped is called "high memory".
+
+ Depending on the selected kernel/user memory split, minimum
+ vmalloc space and actual amount of RAM, you may not need this
+ option which should result in a slightly faster kernel.
+
+ If unsure, say n.
+
source "mm/Kconfig"
config LEDS
@@ -1092,7 +1143,7 @@ source "drivers/cpufreq/Kconfig"
config CPU_FREQ_SA1100
bool
- depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
+ depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
default y
config CPU_FREQ_SA1110
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 192ee01a9ba2..a71fd941ade7 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -2,18 +2,29 @@ menu "Kernel hacking"
source "lib/Kconfig.debug"
-# RMK wants arm kernels compiled with frame pointers so hardwire this to y.
+# RMK wants arm kernels compiled with frame pointers or stack unwinding.
# If you know what you are doing and are willing to live without stack
# traces, you can get a slightly smaller kernel by setting this option to
# n, but then RMK will have to kill you ;).
config FRAME_POINTER
bool
- default y
+ default y if !ARM_UNWIND
help
If you say N here, the resulting kernel will be slightly smaller and
- faster. However, when a problem occurs with the kernel, the
- information that is reported is severely limited. Most people
- should say Y here.
+ faster. However, if neither FRAME_POINTER nor ARM_UNWIND are enabled,
+ when a problem occurs with the kernel, the information that is
+ reported is severely limited.
+
+config ARM_UNWIND
+ bool "Enable stack unwinding support"
+ depends on AEABI && EXPERIMENTAL
+ default y
+ help
+ This option enables stack unwinding support in the kernel
+ using the information automatically generated by the
+ compiler. The resulting kernel image is slightly bigger but
+ the performance is not affected. Currently, this feature
+ only works with EABI compilers. If unsure say Y.
config DEBUG_USER
bool "Verbose user fault messages"
@@ -66,7 +77,7 @@ config DEBUG_ICEDCC
Say Y here if you want the debug print routines to direct their
output to the EmbeddedICE macrocell's DCC channel using
co-processor 14. This is known to work on the ARM9 style ICE
- channel.
+ channel and on the XScale with the PEEDI.
It does include a timeout to ensure that the system does not
totally freeze when there is nothing connected to read.
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 24e0f0187697..e84729bf13d4 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -72,6 +72,7 @@ tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi
tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi
tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi
tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_FA526) :=-mtune=arm9tdmi
tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110
tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
@@ -85,6 +86,10 @@ else
CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
endif
+ifeq ($(CONFIG_ARM_UNWIND),y)
+CFLAGS_ABI +=-funwind-tables
+endif
+
# Need -Uarm for gcc < 3.x
KBUILD_CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
KBUILD_AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
@@ -105,8 +110,11 @@ ifeq ($(CONFIG_ARCH_SA1100),y)
textofs-$(CONFIG_SA1111) := 0x00208000
endif
machine-$(CONFIG_ARCH_PXA) := pxa
+ machine-$(CONFIG_ARCH_MMP) := mmp
+ plat-$(CONFIG_PLAT_PXA) := pxa
machine-$(CONFIG_ARCH_L7200) := l7200
machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
+ machine-$(CONFIG_ARCH_GEMINI) := gemini
textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
machine-$(CONFIG_ARCH_CLPS711X) := clps711x
machine-$(CONFIG_ARCH_IOP32X) := iop32x
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 77d614232d81..b371fba1b954 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -27,6 +27,12 @@
.macro writeb, ch, rb
mcr p14, 0, \ch, c0, c5, 0
.endm
+#elif defined(CONFIG_CPU_XSCALE)
+ .macro loadsp, rb
+ .endm
+ .macro writeb, ch, rb
+ mcr p14, 0, \ch, c8, c0, 0
+ .endm
#else
.macro loadsp, rb
.endm
@@ -459,6 +465,20 @@ __armv7_mmu_cache_on:
mcr p15, 0, r0, c7, c5, 4 @ ISB
mov pc, r12
+__fa526_cache_on:
+ mov r12, lr
+ bl __setup_mmu
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 @ Invalidate whole cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c8, c7, 0 @ flush UTLB
+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
+ orr r0, r0, #0x1000 @ I-cache enable
+ bl __common_mmu_cache_on
+ mov r0, #0
+ mcr p15, 0, r0, c8, c7, 0 @ flush UTLB
+ mov pc, r12
+
__arm6_mmu_cache_on:
mov r12, lr
bl __setup_mmu
@@ -630,12 +650,30 @@ proc_types:
b __armv4_mmu_cache_off
b __armv4_mmu_cache_flush
+ .word 0x56158000 @ PXA168
+ .word 0xfffff000
+ b __armv4_mmu_cache_on
+ b __armv4_mmu_cache_off
+ b __armv5tej_mmu_cache_flush
+
+ .word 0x56056930
+ .word 0xff0ffff0 @ PXA935
+ b __armv4_mmu_cache_on
+ b __armv4_mmu_cache_off
+ b __armv4_mmu_cache_flush
+
.word 0x56050000 @ Feroceon
.word 0xff0f0000
b __armv4_mmu_cache_on
b __armv4_mmu_cache_off
b __armv5tej_mmu_cache_flush
+ .word 0x66015261 @ FA526
+ .word 0xff01fff1
+ b __fa526_cache_on
+ b __armv4_mmu_cache_off
+ b __fa526_cache_flush
+
@ These match on the architecture ID
.word 0x00020000 @ ARMv4T
@@ -775,6 +813,12 @@ __armv4_mpu_cache_flush:
mcr p15, 0, ip, c7, c10, 4 @ drain WB
mov pc, lr
+__fa526_cache_flush:
+ mov r1, #0
+ mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache
+ mcr p15, 0, r1, c7, c5, 0 @ flush I cache
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mov pc, lr
__armv6_mmu_cache_flush:
mov r1, #0
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 3fc08413fff0..9e6e512f0117 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -18,7 +18,10 @@
unsigned int __machine_arch_type;
-#include <linux/string.h>
+#include <linux/compiler.h> /* for inline */
+#include <linux/types.h> /* for size_t */
+#include <linux/stddef.h> /* for NULL */
+#include <asm/string.h>
#ifdef STANDALONE_DEBUG
#define putstr printf
@@ -46,6 +49,21 @@ static void icedcc_putc(int ch)
asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
}
+#elif defined(CONFIG_CPU_XSCALE)
+
+static void icedcc_putc(int ch)
+{
+ int status, i = 0x4000000;
+
+ do {
+ if (--i < 0)
+ return;
+
+ asm volatile ("mrc p14, 0, %0, c14, c0, 0" : "=r" (status));
+ } while (status & (1 << 28));
+
+ asm("mcr p14, 0, %0, c8, c0, 0" : : "r" (ch));
+}
#else
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in
index 153a07e7222b..a5924b9b88bd 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.in
+++ b/arch/arm/boot/compressed/vmlinux.lds.in
@@ -11,6 +11,11 @@ OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
+ /DISCARD/ : {
+ *(.ARM.exidx*)
+ *(.ARM.extab*)
+ }
+
. = TEXT_START;
_text = .;
diff --git a/arch/arm/common/clkdev.c b/arch/arm/common/clkdev.c
index 1037bba18329..5589444ff437 100644
--- a/arch/arm/common/clkdev.c
+++ b/arch/arm/common/clkdev.c
@@ -62,9 +62,8 @@ static struct clk *clk_find(const char *dev_id, const char *con_id)
return clk;
}
-struct clk *clk_get(struct device *dev, const char *con_id)
+struct clk *clk_get_sys(const char *dev_id, const char *con_id)
{
- const char *dev_id = dev ? dev_name(dev) : NULL;
struct clk *clk;
mutex_lock(&clocks_mutex);
@@ -75,6 +74,14 @@ struct clk *clk_get(struct device *dev, const char *con_id)
return clk ? clk : ERR_PTR(-ENOENT);
}
+EXPORT_SYMBOL(clk_get_sys);
+
+struct clk *clk_get(struct device *dev, const char *con_id)
+{
+ const char *dev_id = dev ? dev_name(dev) : NULL;
+
+ return clk_get_sys(dev_id, con_id);
+}
EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index f030f0775be7..734ac9135998 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/page-flags.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
@@ -349,6 +350,12 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page,
BUG_ON(!valid_dma_direction(dir));
+ if (PageHighMem(page)) {
+ dev_err(dev, "DMA buffer bouncing of HIGHMEM pages "
+ "is not supported\n");
+ return ~0;
+ }
+
return map_single(dev, page_address(page) + offset, size, dir);
}
EXPORT_SYMBOL(dma_map_page);
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 697c64913990..7713a08bb10c 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -124,37 +124,6 @@ static int scoop_gpio_direction_output(struct gpio_chip *chip,
return 0;
}
-unsigned short set_scoop_gpio(struct device *dev, unsigned short bit)
-{
- unsigned short gpio_bit;
- unsigned long flag;
- struct scoop_dev *sdev = dev_get_drvdata(dev);
-
- spin_lock_irqsave(&sdev->scoop_lock, flag);
- gpio_bit = ioread16(sdev->base + SCOOP_GPWR) | bit;
- iowrite16(gpio_bit, sdev->base + SCOOP_GPWR);
- spin_unlock_irqrestore(&sdev->scoop_lock, flag);
-
- return gpio_bit;
-}
-
-unsigned short reset_scoop_gpio(struct device *dev, unsigned short bit)
-{
- unsigned short gpio_bit;
- unsigned long flag;
- struct scoop_dev *sdev = dev_get_drvdata(dev);
-
- spin_lock_irqsave(&sdev->scoop_lock, flag);
- gpio_bit = ioread16(sdev->base + SCOOP_GPWR) & ~bit;
- iowrite16(gpio_bit, sdev->base + SCOOP_GPWR);
- spin_unlock_irqrestore(&sdev->scoop_lock, flag);
-
- return gpio_bit;
-}
-
-EXPORT_SYMBOL(set_scoop_gpio);
-EXPORT_SYMBOL(reset_scoop_gpio);
-
unsigned short read_scoop_reg(struct device *dev, unsigned short reg)
{
struct scoop_dev *sdev = dev_get_drvdata(dev);
diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c
index 780bbf7cb26f..140f1d721d50 100644
--- a/arch/arm/common/sharpsl_pm.c
+++ b/arch/arm/common/sharpsl_pm.c
@@ -29,8 +29,8 @@
#include <mach/hardware.h>
#include <asm/irq.h>
#include <mach/pm.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-regs.h>
+#include <mach/regs-rtc.h>
#include <mach/sharpsl.h>
#include <asm/hardware/sharpsl_pm.h>
diff --git a/arch/arm/configs/acs5k_defconfig b/arch/arm/configs/acs5k_defconfig
new file mode 100644
index 000000000000..1cab4e79d368
--- /dev/null
+++ b/arch/arm/configs/acs5k_defconfig
@@ -0,0 +1,1233 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-simtec-micrel1
+# Tue Dec 16 13:31:34 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+CONFIG_ARCH_KS8695=y
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Kendin/Micrel KS8695 Implementations
+#
+CONFIG_MACH_KS8695=y
+CONFIG_MACH_DSM320=y
+CONFIG_MACH_ACS5K=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM922T=y
+CONFIG_CPU_32v4T=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+CONFIG_PCI_DEBUG=y
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+CONFIG_YENTA=y
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+CONFIG_PCCARD_NONSTATIC=y
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_KS8695_ETHER=y
+# CONFIG_AX88796 is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+CONFIG_PRISM54=m
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_NET_PCMCIA is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_KS8695=y
+CONFIG_SERIAL_KS8695_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_ACS5KCAN=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X=y
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_KS8695_WATCHDOG=y
+# CONFIG_ALIM7101_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+CONFIG_RTC_DRV_PCF8563=y
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/acs5k_tiny_defconfig b/arch/arm/configs/acs5k_tiny_defconfig
new file mode 100644
index 000000000000..8e3d084afd78
--- /dev/null
+++ b/arch/arm/configs/acs5k_tiny_defconfig
@@ -0,0 +1,941 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-simtec-micrel1
+# Tue Jan 6 13:23:07 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+CONFIG_ARCH_KS8695=y
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Kendin/Micrel KS8695 Implementations
+#
+# CONFIG_MACH_KS8695 is not set
+# CONFIG_MACH_DSM320 is not set
+CONFIG_MACH_ACS5K=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM922T=y
+CONFIG_CPU_32v4T=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyAM0,115200 init=/bin/sh"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_ARM_KS8695_ETHER=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+# CONFIG_LIBERTAS is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_KS8695=y
+CONFIG_SERIAL_KS8695_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_ACS5KCAN=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+CONFIG_GPIO_PCA953X=y
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_KS8695_WATCHDOG=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+CONFIG_RTC_DRV_PCF8563=y
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/assabet_defconfig b/arch/arm/configs/assabet_defconfig
index b1cd331aaecf..c66dd399e426 100644
--- a/arch/arm/configs/assabet_defconfig
+++ b/arch/arm/configs/assabet_defconfig
@@ -89,7 +89,6 @@ CONFIG_SA1100_ASSABET=y
# CONFIG_SA1100_COLLIE is not set
# CONFIG_SA1100_H3100 is not set
# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
# CONFIG_SA1100_BADGE4 is not set
# CONFIG_SA1100_JORNADA720 is not set
# CONFIG_SA1100_HACKKIT is not set
diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig
index 80222feb7dad..f264846218a2 100644
--- a/arch/arm/configs/badge4_defconfig
+++ b/arch/arm/configs/badge4_defconfig
@@ -91,7 +91,6 @@ CONFIG_ARCH_SA1100=y
# CONFIG_SA1100_COLLIE is not set
# CONFIG_SA1100_H3100 is not set
# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
CONFIG_SA1100_BADGE4=y
# CONFIG_SA1100_JORNADA720 is not set
# CONFIG_SA1100_HACKKIT is not set
diff --git a/arch/arm/configs/cerfcube_defconfig b/arch/arm/configs/cerfcube_defconfig
index ee130b528bd4..2b4c0668b1b4 100644
--- a/arch/arm/configs/cerfcube_defconfig
+++ b/arch/arm/configs/cerfcube_defconfig
@@ -93,7 +93,6 @@ CONFIG_SA1100_CERF_FLASH_16MB=y
# CONFIG_SA1100_COLLIE is not set
# CONFIG_SA1100_H3100 is not set
# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
# CONFIG_SA1100_BADGE4 is not set
# CONFIG_SA1100_JORNADA720 is not set
# CONFIG_SA1100_HACKKIT is not set
diff --git a/arch/arm/configs/xm_x2xx_defconfig b/arch/arm/configs/cm_x2xx_defconfig
index 1039f366bf8d..797b790cba78 100644
--- a/arch/arm/configs/xm_x2xx_defconfig
+++ b/arch/arm/configs/cm_x2xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc8
-# Sun Oct 5 11:05:36 2008
+# Linux kernel version: 2.6.29-rc2
+# Sun Feb 1 16:31:36 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -22,7 +22,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
CONFIG_ZONE_DMA=y
CONFIG_ARCH_MTD_XIP=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
@@ -47,12 +46,12 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -80,27 +79,21 @@ CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
+CONFIG_AIO=y
# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_PCI_QUIRKS=y
# CONFIG_SLUB_DEBUG is not set
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
CONFIG_HAVE_CLK=y
-# CONFIG_PROC_PAGE_MONITOR is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -108,11 +101,9 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -129,6 +120,11 @@ CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_FREEZER=y
#
# System Type
@@ -138,7 +134,6 @@ CONFIG_CLASSIC_RCU=y
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
@@ -165,17 +160,19 @@ CONFIG_ARCH_PXA=y
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM7X00A is not set
-CONFIG_DMABOUNCE=y
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
#
# Intel PXA2xx/PXA3xx Implementations
#
# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 is not set
# CONFIG_ARCH_LUBBOCK is not set
# CONFIG_MACH_LOGICPD_PXA270 is not set
# CONFIG_MACH_MAINSTONE is not set
@@ -185,7 +182,9 @@ CONFIG_DMABOUNCE=y
# CONFIG_ARCH_VIPER is not set
# CONFIG_ARCH_PXA_ESERIES is not set
# CONFIG_TRIZEPS_PXA is not set
-CONFIG_MACH_EM_X270=y
+# CONFIG_MACH_H5000 is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_EXEDA is not set
# CONFIG_MACH_COLIBRI is not set
# CONFIG_MACH_ZYLONITE is not set
# CONFIG_MACH_LITTLETON is not set
@@ -204,14 +203,6 @@ CONFIG_PXA_SSP=y
# CONFIG_PXA_PWM is not set
#
-# Boot options
-#
-
-#
-# Power management
-#
-
-#
# Processor Type
#
CONFIG_CPU_32=y
@@ -232,6 +223,8 @@ CONFIG_ARM_THUMB=y
# CONFIG_OUTER_CACHE is not set
CONFIG_IWMMXT=y
CONFIG_XSCALE_PMU=y
+CONFIG_DMABOUNCE=y
+CONFIG_COMMON_CLKDEV=y
#
# Bus support
@@ -242,6 +235,7 @@ CONFIG_PCI_HOST_ITE8152=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
CONFIG_PCCARD=m
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=m
@@ -287,14 +281,13 @@ CONFIG_FLATMEM_MANUAL=y
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
CONFIG_ALIGNMENT_TRAP=y
#
@@ -327,6 +320,8 @@ CONFIG_FPE_NWFPE=y
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
# CONFIG_BINFMT_AOUT is not set
# CONFIG_BINFMT_MISC is not set
@@ -345,6 +340,7 @@ CONFIG_NET=y
#
# Networking options
#
+CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -389,6 +385,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
@@ -399,6 +396,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
#
# Network testing
@@ -420,8 +418,6 @@ CONFIG_BT_HIDP=m
#
# Bluetooth device drivers
#
-CONFIG_BT_HCIUSB=m
-CONFIG_BT_HCIUSB_SCO=y
# CONFIG_BT_HCIBTUSB is not set
# CONFIG_BT_HCIBTSDIO is not set
# CONFIG_BT_HCIUART is not set
@@ -434,15 +430,15 @@ CONFIG_BT_HCIUSB_SCO=y
# CONFIG_BT_HCIBTUART is not set
# CONFIG_BT_HCIVHCI is not set
# CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=m
# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -467,6 +463,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
@@ -521,9 +518,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x400000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
CONFIG_MTD_PXA2XX=y
# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_IMPA7 is not set
@@ -535,6 +530,8 @@ CONFIG_MTD_PXA2XX=y
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -563,6 +560,12 @@ CONFIG_MTD_NAND_PLATFORM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -642,6 +645,8 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
@@ -756,26 +761,30 @@ CONFIG_MII=y
CONFIG_DM9000=y
CONFIG_DM9000_DEBUGLEVEL=1
# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set
+# CONFIG_ENC28J60 is not set
# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
-# CONFIG_EEPRO100 is not set
# CONFIG_E100 is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_8139CP is not set
-CONFIG_8139TOO=y
+CONFIG_8139TOO=m
# CONFIG_8139TOO_PIO is not set
# CONFIG_8139TOO_TUNE_TWISTER is not set
# CONFIG_8139TOO_8129 is not set
@@ -783,10 +792,12 @@ CONFIG_8139TOO=y
# CONFIG_R6040 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
@@ -797,8 +808,6 @@ CONFIG_8139TOO=y
# CONFIG_WLAN_PRE80211 is not set
CONFIG_WLAN_80211=y
# CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2200 is not set
CONFIG_LIBERTAS=m
# CONFIG_LIBERTAS_USB is not set
# CONFIG_LIBERTAS_CS is not set
@@ -811,10 +820,16 @@ CONFIG_LIBERTAS_SDIO=m
# CONFIG_PRISM54 is not set
# CONFIG_USB_ZD1201 is not set
# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
# CONFIG_IWLWIFI_LEDS is not set
# CONFIG_HOSTAP is not set
#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
@@ -879,22 +894,22 @@ CONFIG_KEYBOARD_PXA27x=m
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
# CONFIG_TOUCHSCREEN_FUJITSU is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_INEXIO is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
# CONFIG_TOUCHSCREEN_PENMOUNT is not set
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-CONFIG_TOUCHSCREEN_WM97XX=m
-# CONFIG_TOUCHSCREEN_WM9705 is not set
-CONFIG_TOUCHSCREEN_WM9712=y
-# CONFIG_TOUCHSCREEN_WM9713 is not set
-# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set
+CONFIG_TOUCHSCREEN_UCB1400=m
+# CONFIG_TOUCHSCREEN_WM97XX is not set
# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
# CONFIG_INPUT_MISC is not set
#
@@ -933,6 +948,7 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_IPMI_HANDLER is not set
@@ -1009,26 +1025,45 @@ CONFIG_I2C_PXA=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_TPS65010 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_SPI is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_PXA2XX=m
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_GPIOLIB=y
# CONFIG_DEBUG_GPIO is not set
# CONFIG_GPIO_SYSFS is not set
#
+# Memory mapped GPIO expanders:
+#
+
+#
# I2C GPIO expanders:
#
# CONFIG_GPIO_MAX732X is not set
@@ -1043,17 +1078,19 @@ CONFIG_GPIOLIB=y
#
# SPI GPIO expanders:
#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
-CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
#
@@ -1064,11 +1101,17 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_ASIC3 is not set
# CONFIG_HTC_EGPIO is not set
# CONFIG_HTC_PASIC3 is not set
-# CONFIG_UCB1400_CORE is not set
+CONFIG_UCB1400_CORE=m
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_T7L66XB is not set
# CONFIG_MFD_TC6387XB is not set
# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
#
# Multimedia devices
@@ -1077,13 +1120,117 @@ CONFIG_SSB_POSSIBLE=y
#
# Multimedia core support
#
-# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L2_COMMON=m
+# CONFIG_VIDEO_ALLOW_V4L1 is not set
+CONFIG_VIDEO_V4L1_COMPAT=y
# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
+CONFIG_VIDEO_MEDIA=m
#
# Multimedia drivers
#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=m
+CONFIG_MEDIA_TUNER_CUSTOMIZE=y
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEOBUF_GEN=m
+CONFIG_VIDEOBUF_DMA_SG=m
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TDA9875 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_M52790 is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_TVP514X is not set
+# CONFIG_VIDEO_TVP5150 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_VIDEO_SAA7134 is not set
+# CONFIG_VIDEO_HEXIUM_ORION is not set
+# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_VIDEO_CX88 is not set
+# CONFIG_VIDEO_IVTV is not set
+# CONFIG_VIDEO_CAFE_CCIC is not set
+CONFIG_SOC_CAMERA=m
+# CONFIG_SOC_CAMERA_MT9M001 is not set
+CONFIG_SOC_CAMERA_MT9M111=m
+# CONFIG_SOC_CAMERA_MT9T031 is not set
+# CONFIG_SOC_CAMERA_MT9V022 is not set
+# CONFIG_SOC_CAMERA_TW9910 is not set
+# CONFIG_SOC_CAMERA_PLATFORM is not set
+# CONFIG_SOC_CAMERA_OV772X is not set
+CONFIG_VIDEO_PXA27x=m
+# CONFIG_VIDEO_SH_MOBILE_CEU is not set
+# CONFIG_V4L_USB_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
# CONFIG_DAB is not set
#
@@ -1095,6 +1242,7 @@ CONFIG_SSB_POSSIBLE=y
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
@@ -1128,6 +1276,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
@@ -1138,13 +1287,17 @@ CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_PM3 is not set
# CONFIG_FB_CARMINE is not set
CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_OVERLAY is not set
# CONFIG_FB_PXA_SMARTPANEL is not set
CONFIG_FB_PXA_PARAMETERS=y
CONFIG_FB_MBX=m
# CONFIG_FB_W100 is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
#
# Display device support
@@ -1167,6 +1320,7 @@ CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_CLUT224=y
CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
CONFIG_SND=m
CONFIG_SND_TIMER=m
CONFIG_SND_PCM=m
@@ -1182,81 +1336,16 @@ CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_DEBUG is not set
CONFIG_SND_VMASTER=y
CONFIG_SND_AC97_CODEC=m
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-# CONFIG_SND_AC97_POWER_SAVE is not set
-CONFIG_SND_PCI=y
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ALS300 is not set
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_ATIIXP_MODEM is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AW2 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_CMIPCI is not set
-# CONFIG_SND_OXYGEN is not set
-# CONFIG_SND_CS4281 is not set
-# CONFIG_SND_CS46XX is not set
-# CONFIG_SND_DARLA20 is not set
-# CONFIG_SND_GINA20 is not set
-# CONFIG_SND_LAYLA20 is not set
-# CONFIG_SND_DARLA24 is not set
-# CONFIG_SND_GINA24 is not set
-# CONFIG_SND_LAYLA24 is not set
-# CONFIG_SND_MONA is not set
-# CONFIG_SND_MIA is not set
-# CONFIG_SND_ECHO3G is not set
-# CONFIG_SND_INDIGO is not set
-# CONFIG_SND_INDIGOIO is not set
-# CONFIG_SND_INDIGODJ is not set
-# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_FM801 is not set
-# CONFIG_SND_HDA_INTEL is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_HIFIER is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MAESTRO3 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_PCXHR is not set
-# CONFIG_SND_RIPTIDE is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VIA82XX_MODEM is not set
-# CONFIG_SND_VIRTUOSO is not set
-# CONFIG_SND_VX222 is not set
-# CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_PCI is not set
CONFIG_SND_ARM=y
CONFIG_SND_PXA2XX_PCM=m
+CONFIG_SND_PXA2XX_LIB=m
+CONFIG_SND_PXA2XX_LIB_AC97=y
CONFIG_SND_PXA2XX_AC97=m
-CONFIG_SND_USB=y
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_CAIAQ is not set
-CONFIG_SND_PCMCIA=y
-# CONFIG_SND_VXPOCKET is not set
-# CONFIG_SND_PDAUDIOCF is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+# CONFIG_SND_PCMCIA is not set
# CONFIG_SND_SOC is not set
# CONFIG_SOUND_PRIME is not set
CONFIG_AC97_BUS=m
@@ -1269,9 +1358,37 @@ CONFIG_HID_DEBUG=y
# USB Input Devices
#
CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
+# CONFIG_HID_PID is not set
# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1291,12 +1408,15 @@ CONFIG_USB_DEVICEFS=y
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
#
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
@@ -1306,6 +1426,8 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
# CONFIG_USB_MUSB_HDRC is not set
#
@@ -1314,20 +1436,20 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
#
#
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1355,6 +1477,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
@@ -1371,13 +1494,20 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_UWB is not set
CONFIG_MMC=m
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
#
-# MMC/SD Card Drivers
+# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=m
CONFIG_MMC_BLOCK_BOUNCE=y
@@ -1385,11 +1515,12 @@ CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_MMC_TEST is not set
#
-# MMC/SD Host Controller Drivers
+# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_PXA=m
# CONFIG_MMC_SDHCI is not set
# CONFIG_MMC_TIFM_SD is not set
+# CONFIG_MMC_SPI is not set
# CONFIG_MMC_SDRICOH_CS is not set
# CONFIG_MEMSTICK is not set
# CONFIG_ACCESSIBILITY is not set
@@ -1400,8 +1531,7 @@ CONFIG_LEDS_CLASS=y
# LED drivers
#
# CONFIG_LEDS_PCA9532 is not set
-# CONFIG_LEDS_GPIO is not set
-CONFIG_LEDS_CM_X270=y
+CONFIG_LEDS_GPIO=m
# CONFIG_LEDS_PCA955X is not set
#
@@ -1410,6 +1540,7 @@ CONFIG_LEDS_CM_X270=y
CONFIG_LEDS_TRIGGERS=y
# CONFIG_LEDS_TRIGGER_TIMER is not set
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
@@ -1441,37 +1572,43 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
#
# Platform RTC drivers
#
# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
CONFIG_RTC_DRV_V3020=y
#
# on-CPU RTC drivers
#
CONFIG_RTC_DRV_SA1100=y
+# CONFIG_RTC_DRV_PXA is not set
# CONFIG_DMADEVICES is not set
-
-#
-# Voltage and Current regulators
-#
# CONFIG_REGULATOR is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
#
# File systems
@@ -1483,14 +1620,16 @@ CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
CONFIG_JBD=y
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1520,15 +1659,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1548,6 +1685,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1567,6 +1705,7 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1678,19 +1817,29 @@ CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
CONFIG_FRAME_POINTER=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_HAVE_FTRACE=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-# CONFIG_FTRACE is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1705,13 +1854,16 @@ CONFIG_DEBUG_LL=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
+# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
@@ -1783,14 +1935,18 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
#
# Library routines
#
CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
-# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=m
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
diff --git a/arch/arm/configs/colibri_defconfig b/arch/arm/configs/colibri_pxa270_defconfig
index 744086fff414..4cf3bde1c522 100644
--- a/arch/arm/configs/colibri_defconfig
+++ b/arch/arm/configs/colibri_pxa270_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc3
-# Mon Dec 3 13:36:09 2007
+# Linux kernel version: 2.6.29-rc8
+# Fri Mar 13 16:18:17 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -12,6 +12,7 @@ CONFIG_MMU=y
# CONFIG_NO_IOPORT is not set
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
@@ -21,8 +22,8 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ZONE_DMA=y
CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -42,22 +43,30 @@ CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
# CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
# CONFIG_CGROUPS is not set
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -70,29 +79,38 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
+CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
CONFIG_BLOCK=y
CONFIG_LBD=y
# CONFIG_BLK_DEV_IO_TRACE is not set
-CONFIG_LSF=y
# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
#
# IO Schedulers
@@ -106,6 +124,7 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_FREEZER=y
#
# System Type
@@ -115,9 +134,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
@@ -131,41 +148,58 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
# CONFIG_ARCH_KS8695 is not set
# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
# CONFIG_ARCH_PNX4008 is not set
CONFIG_ARCH_PXA=y
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
#
# Intel PXA2xx/PXA3xx Implementations
#
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 is not set
# CONFIG_ARCH_LUBBOCK is not set
# CONFIG_MACH_LOGICPD_PXA270 is not set
# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_MACH_MP900C is not set
# CONFIG_ARCH_PXA_IDP is not set
# CONFIG_PXA_SHARPSL is not set
-# CONFIG_MACH_TRIZEPS4 is not set
+# CONFIG_ARCH_VIPER is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+# CONFIG_TRIZEPS_PXA is not set
+# CONFIG_MACH_H5000 is not set
# CONFIG_MACH_EM_X270 is not set
CONFIG_MACH_COLIBRI=y
+# CONFIG_MACH_COLIBRI300 is not set
# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_RAUMFELD_PROTO is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_CM_X300 is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
CONFIG_PXA27x=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
+# CONFIG_PXA_PWM is not set
#
# Processor Type
@@ -174,6 +208,7 @@ CONFIG_CPU_32=y
CONFIG_CPU_XSCALE=y
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_NOIFAR=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_TLB_V4WBI=y
CONFIG_CPU_CP15=y
@@ -187,6 +222,7 @@ CONFIG_ARM_THUMB=y
# CONFIG_OUTER_CACHE is not set
CONFIG_IWMMXT=y
CONFIG_XSCALE_PMU=y
+CONFIG_COMMON_CLKDEV=y
#
# Bus support
@@ -198,28 +234,33 @@ CONFIG_XSCALE_PMU=y
#
# Kernel Features
#
-# CONFIG_TICK_ONESHOT is not set
+CONFIG_TICK_ONESHOT=y
# CONFIG_NO_HZ is not set
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_PREEMPT=y
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
CONFIG_ALIGNMENT_TRAP=y
#
@@ -232,6 +273,12 @@ CONFIG_CMDLINE=""
# CONFIG_KEXEC is not set
#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
# Floating point emulation
#
@@ -246,6 +293,8 @@ CONFIG_FPE_NWFPE=y
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
# CONFIG_BINFMT_AOUT is not set
# CONFIG_BINFMT_MISC is not set
@@ -253,21 +302,18 @@ CONFIG_BINFMT_ELF=y
# Power management options
#
CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
CONFIG_PM_SLEEP=y
-CONFIG_SUSPEND_UP_POSSIBLE=y
CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
# CONFIG_APM_EMULATION is not set
-
-#
-# Networking
-#
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
#
# Networking options
#
+CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -275,6 +321,7 @@ CONFIG_XFRM=y
CONFIG_XFRM_USER=m
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
CONFIG_NET_KEY=y
# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
@@ -304,26 +351,26 @@ CONFIG_INET_TCP_DIAG=y
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
-# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
# CONFIG_NETLABEL is not set
# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
#
# Core Netfilter Configuration
#
-# CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
# CONFIG_NF_CONNTRACK is not set
# CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
#
# IP: Netfilter Configuration
#
+# CONFIG_NF_DEFRAG_IPV4 is not set
CONFIG_IP_NF_QUEUE=m
# CONFIG_IP_NF_IPTABLES is not set
# CONFIG_IP_NF_ARPTABLES is not set
@@ -332,7 +379,9 @@ CONFIG_IP_NF_QUEUE=m
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
@@ -342,12 +391,14 @@ CONFIG_VLAN_8021Q=m
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
CONFIG_IRDA=m
#
@@ -382,15 +433,6 @@ CONFIG_IRTTY_SIR=m
# CONFIG_KS959_DONGLE is not set
#
-# Old SIR device drivers
-#
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Old Serial dongle support
-#
-
-#
# FIR device drivers
#
# CONFIG_USB_IRDA is not set
@@ -410,7 +452,6 @@ CONFIG_BT_HIDP=m
#
# Bluetooth device drivers
#
-# CONFIG_BT_HCIUSB is not set
# CONFIG_BT_HCIBTUSB is not set
# CONFIG_BT_HCIBTSDIO is not set
# CONFIG_BT_HCIUART is not set
@@ -419,21 +460,20 @@ CONFIG_BT_HIDP=m
# CONFIG_BT_HCIBFUSB is not set
# CONFIG_BT_HCIVHCI is not set
# CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
CONFIG_CFG80211=y
+# CONFIG_CFG80211_REG_DEBUG is not set
CONFIG_NL80211=y
+CONFIG_WIRELESS_OLD_REGULATORY=y
CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=y
+CONFIG_LIB80211_CRYPT_WEP=y
+CONFIG_LIB80211_CRYPT_CCMP=y
+CONFIG_LIB80211_CRYPT_TKIP=y
# CONFIG_MAC80211 is not set
-CONFIG_IEEE80211=y
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=y
-CONFIG_IEEE80211_CRYPT_CCMP=m
-CONFIG_IEEE80211_CRYPT_TKIP=m
-CONFIG_IEEE80211_SOFTMAC=m
-# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -448,6 +488,8 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
@@ -457,9 +499,11 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
#
# User Modules And Translation Layers
@@ -510,9 +554,7 @@ CONFIG_MTD_CFI_UTIL=y
#
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
CONFIG_MTD_PXA2XX=y
# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_IMPA7 is not set
@@ -538,6 +580,7 @@ CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_ECC_SMC is not set
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
# CONFIG_MTD_NAND_H1900 is not set
+# CONFIG_MTD_NAND_GPIO is not set
CONFIG_MTD_NAND_IDS=y
CONFIG_MTD_NAND_DISKONCHIP=y
CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
@@ -556,6 +599,11 @@ CONFIG_MTD_ONENAND=y
# CONFIG_MTD_ONENAND_SIM is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -569,36 +617,41 @@ CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=8
CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
CONFIG_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
#
-# Please see Documentation/ide.txt for help/info on IDE drives
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_IDE_TASK_IOCTL is not set
CONFIG_IDE_PROC_FS=y
#
# IDE chipset support/bugfixes
#
-CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_PLATFORM is not set
-# CONFIG_IDE_ARM is not set
# CONFIG_BLK_DEV_IDEDMA is not set
-CONFIG_IDE_ARCH_OBSOLETE_INIT=y
-# CONFIG_BLK_DEV_HD is not set
#
# SCSI device support
@@ -610,7 +663,6 @@ CONFIG_IDE_ARCH_OBSOLETE_INIT=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -631,6 +683,10 @@ CONFIG_PHYLIB=y
# CONFIG_SMSC_PHY is not set
# CONFIG_BROADCOM_PHY is not set
# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
# CONFIG_FIXED_PHY is not set
# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
@@ -638,11 +694,17 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_SMC91X is not set
CONFIG_DM9000=y
+CONFIG_DM9000_DEBUGLEVEL=4
+# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set
# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
@@ -654,10 +716,15 @@ CONFIG_DM9000=y
CONFIG_WLAN_80211=y
# CONFIG_LIBERTAS is not set
# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_IWLWIFI_LEDS is not set
CONFIG_HOSTAP=y
CONFIG_HOSTAP_FIRMWARE=y
CONFIG_HOSTAP_FIRMWARE_NVRAM=y
-# CONFIG_ZD1211RW is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -670,7 +737,6 @@ CONFIG_HOSTAP_FIRMWARE_NVRAM=y
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
@@ -710,6 +776,7 @@ CONFIG_INPUT_MOUSE=y
# CONFIG_MOUSE_PS2 is not set
CONFIG_MOUSE_SERIAL=m
# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_MOUSE_GPIO is not set
# CONFIG_INPUT_JOYSTICK is not set
@@ -718,20 +785,25 @@ CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_FUJITSU is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
# CONFIG_TOUCHSCREEN_PENMOUNT is not set
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-CONFIG_TOUCHSCREEN_UCB1400=y
# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
CONFIG_INPUT_MISC=y
# CONFIG_INPUT_ATI_REMOTE is not set
# CONFIG_INPUT_ATI_REMOTE2 is not set
# CONFIG_INPUT_KEYSPAN_REMOTE is not set
# CONFIG_INPUT_POWERMATE is not set
# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
#
# Hardware I/O ports
@@ -746,9 +818,11 @@ CONFIG_SERIO_LIBPS2=y
# Character devices
#
CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -764,45 +838,50 @@ CONFIG_SERIAL_PXA_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
-# CONFIG_NVRAM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
#
-# I2C Algorithms
+# I2C Hardware Bus support
#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
#
-# I2C Hardware Bus support
+# I2C system bus drivers (mostly embedded / system-on-chip)
#
# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_PXA is not set
# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PXA is not set
# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
# CONFIG_I2C_TINY_USB is not set
#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
# Miscellaneous I2C Chip support
#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
@@ -811,16 +890,35 @@ CONFIG_I2C_CHARDEV=y
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
#
-# SPI support
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
@@ -828,7 +926,10 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_F71805F is not set
@@ -848,6 +949,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4245 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
@@ -856,6 +958,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_W83781D is not set
@@ -863,9 +966,12 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
@@ -879,23 +985,46 @@ CONFIG_WATCHDOG=y
# USB-based Watchdog Cards
#
# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
-CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
#
# Multifunction device drivers
#
+# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
#
# Multimedia devices
#
+
+#
+# Multimedia core support
+#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
CONFIG_DAB=y
# CONFIG_USB_DABUSB is not set
@@ -907,6 +1036,7 @@ CONFIG_DAB=y
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
@@ -914,8 +1044,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_SYS_FILLRECT is not set
# CONFIG_FB_SYS_COPYAREA is not set
# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
# CONFIG_FB_SYS_FOPS is not set
-CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
@@ -928,13 +1058,20 @@ CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_UVESA is not set
# CONFIG_FB_S1D13XXX is not set
CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_OVERLAY is not set
+# CONFIG_FB_PXA_SMARTPANEL is not set
# CONFIG_FB_PXA_PARAMETERS is not set
# CONFIG_FB_MBX is not set
+# CONFIG_FB_W100 is not set
# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=y
#
# Display device support
@@ -964,12 +1101,7 @@ CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
# CONFIG_SOUND is not set
-CONFIG_AC97_BUS=y
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
@@ -979,18 +1111,26 @@ CONFIG_HID=y
# USB Input Devices
#
# CONFIG_USB_HID is not set
+# CONFIG_HID_PID is not set
#
# USB HID Boot Protocol drivers
#
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+# CONFIG_HID_APPLE is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_USB_ARCH_HAS_EHCI is not set
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
#
# Miscellaneous USB options
@@ -999,29 +1139,40 @@ CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_PERSIST is not set
# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
#
# USB Host Controller Drivers
#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
#
# USB Device Class drivers
#
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
#
#
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
#
# CONFIG_USB_LIBUSUAL is not set
@@ -1029,19 +1180,14 @@ CONFIG_USB_DEVICEFS=y
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MON is not set
#
# USB port drivers
#
-
-#
-# USB Serial Converter support
-#
CONFIG_USB_SERIAL=m
+# CONFIG_USB_EZUSB is not set
# CONFIG_USB_SERIAL_GENERIC is not set
# CONFIG_USB_SERIAL_AIRCABLE is not set
-# CONFIG_USB_SERIAL_AIRPRIME is not set
# CONFIG_USB_SERIAL_ARK3116 is not set
# CONFIG_USB_SERIAL_BELKIN is not set
# CONFIG_USB_SERIAL_CH341 is not set
@@ -1059,6 +1205,7 @@ CONFIG_USB_SERIAL=m
# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
# CONFIG_USB_SERIAL_GARMIN is not set
# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
# CONFIG_USB_SERIAL_KEYSPAN is not set
# CONFIG_USB_SERIAL_KLSI is not set
@@ -1066,17 +1213,21 @@ CONFIG_USB_SERIAL=m
# CONFIG_USB_SERIAL_MCT_U232 is not set
# CONFIG_USB_SERIAL_MOS7720 is not set
# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
# CONFIG_USB_SERIAL_NAVMAN is not set
# CONFIG_USB_SERIAL_PL2303 is not set
# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
# CONFIG_USB_SERIAL_HP4X is not set
# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
# CONFIG_USB_SERIAL_TI is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
# CONFIG_USB_SERIAL_XIRCOM is not set
# CONFIG_USB_SERIAL_OPTION is not set
# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
# CONFIG_USB_SERIAL_DEBUG is not set
#
@@ -1085,7 +1236,7 @@ CONFIG_USB_SERIAL=m
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
@@ -1101,30 +1252,29 @@ CONFIG_USB_SERIAL=m
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
CONFIG_USB_GADGET=m
# CONFIG_USB_GADGET_DEBUG is not set
# CONFIG_USB_GADGET_DEBUG_FILES is not set
# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
CONFIG_USB_GADGET_SELECTED=y
-# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_AT91 is not set
# CONFIG_USB_GADGET_ATMEL_USBA is not set
# CONFIG_USB_GADGET_FSL_USB2 is not set
-# CONFIG_USB_GADGET_NET2280 is not set
-# CONFIG_USB_GADGET_PXA2XX is not set
-# CONFIG_USB_GADGET_M66592 is not set
-# CONFIG_USB_GADGET_GOKU is not set
# CONFIG_USB_GADGET_LH7A40X is not set
# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
# CONFIG_USB_GADGET_S3C2410 is not set
-# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
CONFIG_USB_GADGET_DUMMY_HCD=y
CONFIG_USB_DUMMY_HCD=m
CONFIG_USB_GADGET_DUALSPEED=y
@@ -1134,21 +1284,32 @@ CONFIG_USB_GADGET_DUALSPEED=y
# CONFIG_USB_FILE_STORAGE is not set
# CONFIG_USB_G_SERIAL is not set
# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
#
-# MMC/SD Card Drivers
+# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
#
-# MMC/SD Host Controller Drivers
+# MMC/SD/SDIO Host Controller Drivers
#
# CONFIG_MMC_PXA is not set
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
CONFIG_NEW_LEDS=y
# CONFIG_LEDS_CLASS is not set
@@ -1163,6 +1324,8 @@ CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_HCTOSYS is not set
@@ -1190,6 +1353,9 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_PCF8563 is not set
CONFIG_RTC_DRV_PCF8583=m
# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
@@ -1199,36 +1365,45 @@ CONFIG_RTC_DRV_PCF8583=m
# Platform RTC drivers
#
# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
# CONFIG_RTC_DRV_V3020 is not set
#
# on-CPU RTC drivers
#
# CONFIG_RTC_DRV_SA1100 is not set
+# CONFIG_RTC_DRV_PXA is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
#
# File systems
#
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y
# CONFIG_FUSE_FS is not set
@@ -1254,15 +1429,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
#
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_CONFIGFS_FS=y
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_ECRYPT_FS is not set
@@ -1283,9 +1456,13 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
@@ -1293,20 +1470,18 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
-# CONFIG_NFS_DIRECTIO is not set
+CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V3_ACL is not set
CONFIG_NFSD_V4=y
-CONFIG_NFSD_TCP=y
-CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1361,9 +1536,6 @@ CONFIG_NLS_ISO8859_15=m
# CONFIG_NLS_KOI8_U is not set
CONFIG_NLS_UTF8=m
# CONFIG_DLM is not set
-CONFIG_INSTRUMENTATION=y
-# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
#
# Kernel hacking
@@ -1371,6 +1543,7 @@ CONFIG_INSTRUMENTATION=y
CONFIG_PRINTK_TIME=y
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
@@ -1378,9 +1551,12 @@ CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
CONFIG_DEBUG_PREEMPT=y
# CONFIG_DEBUG_RT_MUTEXES is not set
@@ -1396,16 +1572,40 @@ CONFIG_DEBUG_PREEMPT=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
CONFIG_FRAME_POINTER=y
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_LL=y
# CONFIG_DEBUG_ICEDCC is not set
@@ -1415,58 +1615,114 @@ CONFIG_DEBUG_LL=y
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_NETWORK is not set
-CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY_PATH is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_SECURITY_ROOTPLUG is not set
+CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_NULL is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
-# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=y
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
#
# Library routines
#
CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=y
CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
diff --git a/arch/arm/configs/colibri_pxa300_defconfig b/arch/arm/configs/colibri_pxa300_defconfig
new file mode 100644
index 000000000000..4774a36fa740
--- /dev/null
+++ b/arch/arm/configs/colibri_pxa300_defconfig
@@ -0,0 +1,1156 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc8
+# Fri Mar 13 16:13:20 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+
+#
+# Supported PXA3xx Processor Variants
+#
+CONFIG_CPU_PXA300=y
+# CONFIG_CPU_PXA310 is not set
+# CONFIG_CPU_PXA320 is not set
+# CONFIG_CPU_PXA930 is not set
+# CONFIG_CPU_PXA935 is not set
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 is not set
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_MACH_MP900C is not set
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_ARCH_VIPER is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+# CONFIG_TRIZEPS_PXA is not set
+# CONFIG_MACH_H5000 is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_COLIBRI is not set
+CONFIG_MACH_COLIBRI300=y
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_RAUMFELD_PROTO is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
+# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_CM_X300 is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
+CONFIG_PXA3xx=y
+# CONFIG_PXA_PWM is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSC3=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+CONFIG_IO_36=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_XSC3L2=y
+CONFIG_IWMMXT=y
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="console=ttyS0,115200 rw"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_AX88796=y
+# CONFIG_AX88796_93CX6 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+# CONFIG_INPUT_UINPUT is not set
+CONFIG_INPUT_GPIO_ROTARY_ENCODER=y
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_OVERLAY is not set
+# CONFIG_FB_PXA_SMARTPANEL is not set
+# CONFIG_FB_PXA_PARAMETERS is not set
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_W100 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_PXA=y
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
index f7622e658163..1aa62249031b 100644
--- a/arch/arm/configs/collie_defconfig
+++ b/arch/arm/configs/collie_defconfig
@@ -113,7 +113,6 @@ CONFIG_ARCH_SA1100=y
CONFIG_SA1100_COLLIE=y
# CONFIG_SA1100_H3100 is not set
# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
# CONFIG_SA1100_BADGE4 is not set
# CONFIG_SA1100_JORNADA720 is not set
# CONFIG_SA1100_HACKKIT is not set
diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig
new file mode 100644
index 000000000000..e9955b786c80
--- /dev/null
+++ b/arch/arm/configs/em_x270_defconfig
@@ -0,0 +1,1741 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc2
+# Sun Feb 1 16:43:31 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 is not set
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_MACH_MP900C is not set
+# CONFIG_ARCH_PXA_IDP is not set
+# CONFIG_PXA_SHARPSL is not set
+# CONFIG_ARCH_VIPER is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+# CONFIG_TRIZEPS_PXA is not set
+# CONFIG_MACH_H5000 is not set
+CONFIG_MACH_EM_X270=y
+CONFIG_MACH_EXEDA=y
+# CONFIG_MACH_COLIBRI is not set
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
+# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_CM_X300 is not set
+# CONFIG_MACH_MAGICIAN is not set
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
+CONFIG_PXA27x=y
+CONFIG_PXA_SSP=y
+# CONFIG_PXA_PWM is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_XSCALE_PMU=y
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=1f03 mem=32M"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_APM_EMULATION=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+# CONFIG_BT_RFCOMM_TTY is not set
+CONFIG_BT_BNEP=m
+# CONFIG_BT_BNEP_MC_FILTER is not set
+# CONFIG_BT_BNEP_PROTO_FILTER is not set
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=m
+# CONFIG_BT_HCIBTSDIO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=m
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+CONFIG_MTD_PXA2XX=y
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_IMPA7 is not set
+# CONFIG_MTD_SHARP_SL is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_H1900 is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_SHARPSL is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+CONFIG_MTD_NAND_PLATFORM=y
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+CONFIG_DM9000=y
+CONFIG_DM9000_DEBUGLEVEL=1
+# CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=m
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_SDIO=m
+# CONFIG_LIBERTAS_DEBUG is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+CONFIG_INPUT_APMPOWER=y
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_PXA27x=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_DA9034 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+CONFIG_TOUCHSCREEN_WM97XX=m
+# CONFIG_TOUCHSCREEN_WM9705 is not set
+CONFIG_TOUCHSCREEN_WM9712=y
+# CONFIG_TOUCHSCREEN_WM9713 is not set
+# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_PXA2XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+CONFIG_BATTERY_DA9030=y
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+CONFIG_PMIC_DA903X=y
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L2_COMMON=m
+# CONFIG_VIDEO_ALLOW_V4L1 is not set
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=m
+CONFIG_MEDIA_TUNER_CUSTOMIZE=y
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEOBUF_GEN=m
+CONFIG_VIDEOBUF_DMA_SG=m
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TDA9875 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_M52790 is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_TVP514X is not set
+# CONFIG_VIDEO_TVP5150 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+CONFIG_SOC_CAMERA=m
+# CONFIG_SOC_CAMERA_MT9M001 is not set
+CONFIG_SOC_CAMERA_MT9M111=m
+# CONFIG_SOC_CAMERA_MT9T031 is not set
+# CONFIG_SOC_CAMERA_MT9V022 is not set
+# CONFIG_SOC_CAMERA_TW9910 is not set
+# CONFIG_SOC_CAMERA_PLATFORM is not set
+# CONFIG_SOC_CAMERA_OV772X is not set
+CONFIG_VIDEO_PXA27x=m
+# CONFIG_VIDEO_SH_MOBILE_CEU is not set
+# CONFIG_V4L_USB_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_OVERLAY is not set
+# CONFIG_FB_PXA_SMARTPANEL is not set
+CONFIG_FB_PXA_PARAMETERS=y
+CONFIG_FB_MBX=m
+# CONFIG_FB_MBX_DEBUG is not set
+# CONFIG_FB_W100 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI9320 is not set
+CONFIG_LCD_TDO24M=y
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=m
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_DA903X=m
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=m
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_DRIVERS is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_PXA2XX_LIB=m
+CONFIG_SND_PXA2XX_LIB_AC97=y
+# CONFIG_SND_PXA2XX_AC97 is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_PXA2XX_SOC=m
+CONFIG_SND_PXA2XX_SOC_AC97=m
+CONFIG_SND_PXA2XX_SOC_EM_X270=m
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_WM9712=m
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_PXA=m
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_PCA955X is not set
+CONFIG_LEDS_DA903X=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+CONFIG_RTC_DRV_V3020=y
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SA1100=y
+# CONFIG_RTC_DRV_PXA is not set
+# CONFIG_DMADEVICES is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+CONFIG_REGULATOR_DA903X=y
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=0
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
index 8f986e9f1c62..1502957db2c3 100644
--- a/arch/arm/configs/h3600_defconfig
+++ b/arch/arm/configs/h3600_defconfig
@@ -90,7 +90,6 @@ CONFIG_ARCH_SA1100=y
# CONFIG_SA1100_COLLIE is not set
# CONFIG_SA1100_H3100 is not set
CONFIG_SA1100_H3600=y
-# CONFIG_SA1100_H3800 is not set
CONFIG_SA1100_H3XXX=y
# CONFIG_SA1100_BADGE4 is not set
# CONFIG_SA1100_JORNADA720 is not set
@@ -100,7 +99,6 @@ CONFIG_SA1100_H3XXX=y
# CONFIG_SA1100_SHANNON is not set
# CONFIG_SA1100_SIMPAD is not set
# CONFIG_SA1100_SSP is not set
-# CONFIG_H3600_SLEEVE is not set
#
# Processor Type
diff --git a/arch/arm/configs/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig
index 1c8fb89a6730..db0708d5cbea 100644
--- a/arch/arm/configs/hackkit_defconfig
+++ b/arch/arm/configs/hackkit_defconfig
@@ -91,7 +91,6 @@ CONFIG_ARCH_SA1100=y
# CONFIG_SA1100_COLLIE is not set
# CONFIG_SA1100_H3100 is not set
# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
# CONFIG_SA1100_BADGE4 is not set
# CONFIG_SA1100_JORNADA720 is not set
CONFIG_SA1100_HACKKIT=y
diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig
index 81fadafae02d..f3074e49f2fa 100644
--- a/arch/arm/configs/jornada720_defconfig
+++ b/arch/arm/configs/jornada720_defconfig
@@ -178,7 +178,6 @@ CONFIG_DMABOUNCE=y
# CONFIG_SA1100_COLLIE is not set
# CONFIG_SA1100_H3100 is not set
# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
# CONFIG_SA1100_BADGE4 is not set
CONFIG_SA1100_JORNADA720=y
CONFIG_SA1100_JORNADA720_SSP=y
diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig
index 4bc38078d580..c367ae44012e 100644
--- a/arch/arm/configs/kirkwood_defconfig
+++ b/arch/arm/configs/kirkwood_defconfig
@@ -1,11 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Thu Dec 4 15:27:39 2008
+# Linux kernel version: 2.6.29-rc5
+# Tue Mar 3 21:45:57 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_MMU=y
@@ -42,10 +42,19 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
+CONFIG_LOG_BUF_SHIFT=19
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
CONFIG_NAMESPACES=y
@@ -53,6 +62,7 @@ CONFIG_NAMESPACES=y
# CONFIG_IPC_NS is not set
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
@@ -83,6 +93,7 @@ CONFIG_SLUB_DEBUG=y
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
# CONFIG_MARKERS is not set
CONFIG_OPROFILE=y
CONFIG_HAVE_OPROFILE=y
@@ -93,7 +104,6 @@ CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -101,11 +111,9 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -121,7 +129,6 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
# CONFIG_FREEZER is not set
#
@@ -132,7 +139,6 @@ CONFIG_CLASSIC_RCU=y
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
@@ -159,11 +165,13 @@ CONFIG_ARCH_KIRKWOOD=y
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
#
# Marvell Kirkwood Implementations
@@ -171,14 +179,8 @@ CONFIG_ARCH_KIRKWOOD=y
CONFIG_MACH_DB88F6281_BP=y
CONFIG_MACH_RD88F6192_NAS=y
CONFIG_MACH_RD88F6281=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
+CONFIG_MACH_SHEEVAPLUG=y
+CONFIG_MACH_TS219=y
CONFIG_PLAT_ORION=y
#
@@ -214,6 +216,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
# CONFIG_PCCARD is not set
#
@@ -242,7 +245,6 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_RESOURCES_64BIT is not set
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
@@ -291,6 +293,7 @@ CONFIG_NET=y
#
# Networking options
#
+CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -355,6 +358,7 @@ CONFIG_NET_DSA_MV88E6123_61_65=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
#
# Network testing
@@ -368,12 +372,27 @@ CONFIG_NET_PKTGEN=m
# CONFIG_AF_RXRPC is not set
# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_REG_DEBUG is not set
+# CONFIG_NL80211 is not set
CONFIG_WIRELESS_OLD_REGULATORY=y
CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+CONFIG_LIB80211=y
+CONFIG_MAC80211=y
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_LEDS is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -398,6 +417,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
@@ -451,9 +471,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_IMPA7 is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
@@ -481,6 +499,7 @@ CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_VERIFY_WRITE is not set
# CONFIG_MTD_NAND_ECC_SMC is not set
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_CAFE is not set
@@ -491,6 +510,12 @@ CONFIG_MTD_NAND_ORION=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -568,6 +593,8 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
@@ -682,6 +709,9 @@ CONFIG_MARVELL_PHY=y
# CONFIG_BROADCOM_PHY is not set
# CONFIG_ICPLUS_PHY is not set
# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
# CONFIG_FIXED_PHY is not set
# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
@@ -695,6 +725,7 @@ CONFIG_MII=y
# CONFIG_DM9000 is not set
# CONFIG_ENC28J60 is not set
# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -710,7 +741,6 @@ CONFIG_NET_PCI=y
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
-# CONFIG_EEPRO100 is not set
# CONFIG_E100 is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
@@ -720,6 +750,7 @@ CONFIG_NET_PCI=y
# CONFIG_R6040 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
@@ -754,8 +785,39 @@ CONFIG_MV643XX_ETH=y
# Wireless LAN
#
# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=y
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_SDIO=y
+# CONFIG_LIBERTAS_DEBUG is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_HERMES is not set
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8180 is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_ADM8211 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_ATH5K is not set
+# CONFIG_ATH9K is not set
+# CONFIG_IPW2100 is not set
+# CONFIG_IPW2200 is not set
+# CONFIG_IWLCORE is not set
# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_IWLAGN is not set
+# CONFIG_IWL3945 is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_ZD1211RW is not set
+# CONFIG_RT2X00 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -791,13 +853,20 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
#
# Input Device Drivers
#
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_GPIO=y
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
@@ -807,7 +876,11 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
# Hardware I/O ports
#
-# CONFIG_SERIO is not set
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
# CONFIG_GAMEPORT is not set
#
@@ -839,11 +912,11 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
-# CONFIG_NVRAM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -879,6 +952,7 @@ CONFIG_I2C_HELPER_AUTO=y
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
+# CONFIG_I2C_GPIO is not set
CONFIG_I2C_MV64XXX=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set
@@ -905,8 +979,6 @@ CONFIG_I2C_MV64XXX=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
@@ -925,12 +997,12 @@ CONFIG_SPI_MASTER=y
# SPI Master Controller Drivers
#
# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
CONFIG_SPI_ORION=y
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_W1 is not set
@@ -952,10 +1024,12 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
#
# Multimedia devices
@@ -1012,11 +1086,9 @@ CONFIG_HID_COMPAT=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
-CONFIG_HID_BRIGHT=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_CYPRESS=y
-CONFIG_HID_DELL=y
CONFIG_HID_EZKEY=y
CONFIG_HID_GYRATION=y
CONFIG_HID_LOGITECH=y
@@ -1024,12 +1096,15 @@ CONFIG_HID_LOGITECH=y
# CONFIG_LOGIRUMBLEPAD2_FF is not set
CONFIG_HID_MICROSOFT=y
CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
CONFIG_HID_SUNPLUS=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_TOPSEED=y
# CONFIG_THRUSTMASTER_FF is not set
# CONFIG_ZEROPLUS_FF is not set
CONFIG_USB_SUPPORT=y
@@ -1058,6 +1133,7 @@ CONFIG_USB_DEVICE_CLASS=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
@@ -1087,7 +1163,6 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
# CONFIG_USB_STORAGE_ISD200 is not set
-CONFIG_USB_STORAGE_DPCM=y
# CONFIG_USB_STORAGE_USBAT is not set
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
@@ -1135,21 +1210,51 @@ CONFIG_USB_STORAGE_JUMPSHOT=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
# CONFIG_UWB is not set
-# CONFIG_MMC is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=y
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_TIFM_SD is not set
+CONFIG_MMC_MVSDIO=y
+# CONFIG_MMC_SPI is not set
# CONFIG_MEMSTICK is not set
# CONFIG_ACCESSIBILITY is not set
CONFIG_NEW_LEDS=y
-# CONFIG_LEDS_CLASS is not set
+CONFIG_LEDS_CLASS=y
#
# LED drivers
#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_PCA955X is not set
#
# LED Triggers
#
-# CONFIG_LEDS_TRIGGERS is not set
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
@@ -1178,7 +1283,7 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_PCF8563 is not set
# CONFIG_RTC_DRV_PCF8583 is not set
# CONFIG_RTC_DRV_M41T80 is not set
-# CONFIG_RTC_DRV_S35390A is not set
+CONFIG_RTC_DRV_S35390A=y
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
@@ -1227,6 +1332,7 @@ CONFIG_DMA_ENGINE=y
# CONFIG_DMATEST is not set
# CONFIG_REGULATOR is not set
# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
#
# File systems
@@ -1238,16 +1344,14 @@ CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
# CONFIG_EXT4_FS is not set
CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
-CONFIG_XFS_FS=y
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_DEBUG is not set
+# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1268,9 +1372,9 @@ CONFIG_UDF_NLS=y
#
# DOS/FAT/NT Filesystems
#
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
@@ -1286,10 +1390,7 @@ CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1309,6 +1410,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1393,7 +1495,7 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
@@ -1416,6 +1518,7 @@ CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
@@ -1424,7 +1527,7 @@ CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -1435,7 +1538,10 @@ CONFIG_FRAME_POINTER=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
#
# Tracers
@@ -1446,11 +1552,14 @@ CONFIG_HAVE_FUNCTION_TRACER=y
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
# CONFIG_DEBUG_STACK_USAGE is not set
@@ -1464,19 +1573,22 @@ CONFIG_DEBUG_LL=y
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_ASYNC_CORE=y
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
# CONFIG_CRYPTO_FIPS is not set
-CONFIG_CRYPTO_ALGAPI=m
-CONFIG_CRYPTO_AEAD=m
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=m
-CONFIG_CRYPTO_RNG=m
-CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
@@ -1496,7 +1608,7 @@ CONFIG_CRYPTO_MANAGER=m
CONFIG_CRYPTO_CBC=m
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_CTS is not set
-CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_ECB=y
# CONFIG_CRYPTO_LRW is not set
CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_XTS is not set
@@ -1510,7 +1622,7 @@ CONFIG_CRYPTO_PCBC=m
#
# Digest
#
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CRC32C=y
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1527,9 +1639,9 @@ CONFIG_CRYPTO_PCBC=m
#
# Ciphers
#
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_ARC4=y
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
@@ -1560,6 +1672,7 @@ CONFIG_CRYPTO_HW=y
# Library routines
#
CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=y
CONFIG_CRC16=y
# CONFIG_CRC_T10DIF is not set
diff --git a/arch/arm/configs/lart_defconfig b/arch/arm/configs/lart_defconfig
index a1cc34f25602..56ae56899d2e 100644
--- a/arch/arm/configs/lart_defconfig
+++ b/arch/arm/configs/lart_defconfig
@@ -87,7 +87,6 @@ CONFIG_ARCH_SA1100=y
# CONFIG_SA1100_COLLIE is not set
# CONFIG_SA1100_H3100 is not set
# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
# CONFIG_SA1100_BADGE4 is not set
# CONFIG_SA1100_JORNADA720 is not set
# CONFIG_SA1100_HACKKIT is not set
diff --git a/arch/arm/configs/magician_defconfig b/arch/arm/configs/magician_defconfig
index 73ba62b71063..82428c2f234c 100644
--- a/arch/arm/configs/magician_defconfig
+++ b/arch/arm/configs/magician_defconfig
@@ -1,9 +1,10 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Sun Dec 30 13:02:54 2007
+# Linux kernel version: 2.6.29-rc3
+# Fri Jan 30 12:42:03 2009
#
CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
@@ -12,6 +13,7 @@ CONFIG_MMU=y
# CONFIG_NO_IOPORT is not set
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
@@ -21,8 +23,8 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ZONE_DMA=y
CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -41,16 +43,24 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_GROUP_SCHED is not set
# CONFIG_CGROUPS is not set
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -65,31 +75,41 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
+CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
#
# IO Schedulers
@@ -103,8 +123,7 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_FREEZER=y
#
# System Type
@@ -114,9 +133,7 @@ CONFIG_CLASSIC_RCU=y
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS7500 is not set
# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
@@ -130,41 +147,58 @@ CONFIG_CLASSIC_RCU=y
# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
# CONFIG_ARCH_KS8695 is not set
# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
# CONFIG_ARCH_PNX4008 is not set
CONFIG_ARCH_PXA=y
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
#
# Intel PXA2xx/PXA3xx Implementations
#
+# CONFIG_ARCH_GUMSTIX is not set
+# CONFIG_MACH_INTELMOTE2 is not set
# CONFIG_ARCH_LUBBOCK is not set
# CONFIG_MACH_LOGICPD_PXA270 is not set
# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_MACH_MP900C is not set
# CONFIG_ARCH_PXA_IDP is not set
# CONFIG_PXA_SHARPSL is not set
-# CONFIG_MACH_TRIZEPS4 is not set
+# CONFIG_ARCH_VIPER is not set
+# CONFIG_ARCH_PXA_ESERIES is not set
+# CONFIG_TRIZEPS_PXA is not set
+# CONFIG_MACH_H5000 is not set
# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_COLIBRI is not set
# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_LITTLETON is not set
+# CONFIG_MACH_TAVOREVB is not set
+# CONFIG_MACH_SAAR is not set
# CONFIG_MACH_ARMCORE is not set
+# CONFIG_MACH_CM_X300 is not set
CONFIG_MACH_MAGICIAN=y
+# CONFIG_MACH_MIOA701 is not set
+# CONFIG_MACH_PCM027 is not set
+# CONFIG_ARCH_PXA_PALM is not set
+# CONFIG_PXA_EZX is not set
CONFIG_PXA27x=y
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
+CONFIG_PXA_SSP=y
+CONFIG_PXA_PWM=y
+CONFIG_PXA_HAVE_BOARD_IRQS=y
#
# Processor Type
@@ -173,6 +207,7 @@ CONFIG_CPU_32=y
CONFIG_CPU_XSCALE=y
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_NOIFAR=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_TLB_V4WBI=y
CONFIG_CPU_CP15=y
@@ -186,6 +221,7 @@ CONFIG_ARM_THUMB=y
# CONFIG_OUTER_CACHE is not set
CONFIG_IWMMXT=y
CONFIG_XSCALE_PMU=y
+CONFIG_COMMON_CLKDEV=y
#
# Bus support
@@ -197,28 +233,33 @@ CONFIG_XSCALE_PMU=y
#
# Kernel Features
#
-# CONFIG_TICK_ONESHOT is not set
-# CONFIG_NO_HZ is not set
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_PREEMPT=y
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
CONFIG_ALIGNMENT_TRAP=y
#
@@ -229,9 +270,10 @@ CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="keepinitrd"
# CONFIG_XIP_KERNEL is not set
CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
#
-# CPU Frequency scaling
+# CPU Power Management
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
@@ -239,6 +281,7 @@ CONFIG_CPU_FREQ_TABLE=y
CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_STAT_DETAILS is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
@@ -247,6 +290,7 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_IDLE is not set
#
# Floating point emulation
@@ -263,6 +307,8 @@ CONFIG_FPE_NWFPE=y
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
# CONFIG_BINFMT_AOUT is not set
# CONFIG_BINFMT_MISC is not set
@@ -270,21 +316,18 @@ CONFIG_BINFMT_ELF=y
# Power management options
#
CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
# CONFIG_PM_DEBUG is not set
CONFIG_PM_SLEEP=y
-CONFIG_SUSPEND_UP_POSSIBLE=y
CONFIG_SUSPEND=y
-CONFIG_APM_EMULATION=y
-
-#
-# Networking
-#
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
#
# Networking options
#
+CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -316,33 +359,15 @@ CONFIG_IP_PNP=y
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
-# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
# CONFIG_NETWORK_SECMARK is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-# CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NF_CONNTRACK_ENABLED is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NETFILTER_XTABLES is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
@@ -353,6 +378,7 @@ CONFIG_NETFILTER=y
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
#
# Network testing
@@ -390,20 +416,17 @@ CONFIG_IRTTY_SIR=m
# Dongle support
#
# CONFIG_DONGLE is not set
-
-#
-# Old SIR device drivers
-#
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Old Serial dongle support
-#
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
#
# FIR device drivers
#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
CONFIG_PXA_FICP=m
+# CONFIG_MCS_FIR is not set
CONFIG_BT=m
CONFIG_BT_L2CAP=m
CONFIG_BT_SCO=m
@@ -417,17 +440,17 @@ CONFIG_BT_HIDP=m
#
# Bluetooth device drivers
#
+CONFIG_BT_HCIBTUSB=m
+# CONFIG_BT_HCIBTSDIO is not set
# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
# CONFIG_BT_HCIVHCI is not set
# CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -442,25 +465,28 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=0
+# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
#
# User Modules And Translation Layers
#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLKDEVS=m
-CONFIG_MTD_BLOCK=m
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
@@ -473,6 +499,7 @@ CONFIG_MTD_BLOCK=m
#
CONFIG_MTD_CFI=y
# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
@@ -487,6 +514,7 @@ CONFIG_MTD_CFI_I2=y
CONFIG_MTD_CFI_INTELEXT=y
# CONFIG_MTD_CFI_AMDSTD is not set
# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
@@ -497,9 +525,7 @@ CONFIG_MTD_CFI_INTELEXT=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x00000000
-CONFIG_MTD_PHYSMAP_LEN=0x04000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PXA2XX is not set
# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_SHARP_SL is not set
@@ -523,6 +549,12 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -531,10 +563,12 @@ CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
@@ -547,7 +581,6 @@ CONFIG_BLK_DEV=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -563,6 +596,20 @@ CONFIG_NETDEVICES=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
# CONFIG_WAN is not set
CONFIG_PPP=m
# CONFIG_PPP_MULTILINK is not set
@@ -612,7 +659,26 @@ CONFIG_KEYBOARD_GPIO=y
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
CONFIG_INPUT_UINPUT=m
#
@@ -625,9 +691,11 @@ CONFIG_INPUT_UINPUT=m
# Character devices
#
CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -642,6 +710,7 @@ CONFIG_SERIAL_PXA=y
# CONFIG_SERIAL_PXA_CONSOLE is not set
CONFIG_SERIAL_CORE=y
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
@@ -649,37 +718,45 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
-CONFIG_I2C=m
+CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
#
-# I2C Algorithms
+# I2C Hardware Bus support
#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
#
-# I2C Hardware Bus support
+# I2C system bus drivers (mostly embedded / system-on-chip)
#
# CONFIG_I2C_GPIO is not set
-CONFIG_I2C_PXA=m
-# CONFIG_I2C_PXA_SLAVE is not set
# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set
#
# Miscellaneous I2C Chip support
#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
@@ -688,19 +765,39 @@ CONFIG_I2C_PXA=m
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
#
-# SPI support
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
CONFIG_W1=y
#
# 1-wire Bus Masters
#
+# CONFIG_W1_MASTER_DS2490 is not set
# CONFIG_W1_MASTER_DS2482 is not set
CONFIG_W1_MASTER_DS1WM=y
+# CONFIG_W1_MASTER_GPIO is not set
#
# 1-wire Slaves
@@ -709,32 +806,56 @@ CONFIG_W1_MASTER_DS1WM=y
# CONFIG_W1_SLAVE_SMEM is not set
# CONFIG_W1_SLAVE_DS2433 is not set
CONFIG_W1_SLAVE_DS2760=y
+# CONFIG_W1_SLAVE_BQ27000 is not set
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
CONFIG_PDA_POWER=y
-# CONFIG_APM_POWER is not set
CONFIG_BATTERY_DS2760=y
+# CONFIG_BATTERY_BQ27x00 is not set
# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
-CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
#
# Multifunction device drivers
#
+# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
CONFIG_HTC_EGPIO=y
CONFIG_HTC_PASIC3=y
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
#
# Multimedia devices
#
+
+#
+# Multimedia core support
+#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
# CONFIG_DAB is not set
#
@@ -745,6 +866,7 @@ CONFIG_HTC_PASIC3=y
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
@@ -752,8 +874,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_SYS_FILLRECT is not set
# CONFIG_FB_SYS_COPYAREA is not set
# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
# CONFIG_FB_SYS_FOPS is not set
-CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
@@ -765,13 +887,21 @@ CONFIG_FB_DEFERRED_IO=y
#
# CONFIG_FB_S1D13XXX is not set
CONFIG_FB_PXA=y
+CONFIG_FB_PXA_OVERLAY=y
+# CONFIG_FB_PXA_SMARTPANEL is not set
# CONFIG_FB_PXA_PARAMETERS is not set
# CONFIG_FB_MBX is not set
+# CONFIG_FB_W100 is not set
# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_CORGI=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
#
# Display device support
@@ -802,15 +932,8 @@ CONFIG_FONT_MINI_4x6=y
# CONFIG_FONT_SUN12x22 is not set
# CONFIG_FONT_10x18 is not set
# CONFIG_LOGO is not set
-
-#
-# Sound
-#
CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
+CONFIG_SOUND_OSS_CORE=y
CONFIG_SND=m
CONFIG_SND_TIMER=m
CONFIG_SND_PCM=m
@@ -824,53 +947,185 @@ CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
+CONFIG_SND_DRIVERS=y
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
-
-#
-# ALSA ARM devices
-#
-# CONFIG_SND_PXA2XX_AC97 is not set
-
-#
-# System on Chip audio support
-#
+# CONFIG_SND_ARM is not set
+CONFIG_SND_PXA2XX_LIB=m
+# CONFIG_SND_USB is not set
CONFIG_SND_SOC=m
CONFIG_SND_PXA2XX_SOC=m
-
-#
-# SoC Audio support for SuperH
-#
-
-#
-# Open Sound System
-#
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
# CONFIG_SOUND_PRIME is not set
# CONFIG_HID_SUPPORT is not set
CONFIG_HID=m
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=m
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+CONFIG_USB_GADGET_PXA27X=y
+CONFIG_USB_PXA27X=y
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+# CONFIG_USB_ETH_RNDIS is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=m
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+CONFIG_USB_GPIO_VBUS=y
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
#
-# MMC/SD Card Drivers
+# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_BOUNCE=y
CONFIG_SDIO_UART=m
+# CONFIG_MMC_TEST is not set
#
-# MMC/SD Host Controller Drivers
+# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_PXA=y
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
@@ -899,6 +1154,9 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_PCF8563 is not set
# CONFIG_RTC_DRV_PCF8583 is not set
# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
@@ -908,17 +1166,26 @@ CONFIG_RTC_INTF_DEV=y
# Platform RTC drivers
#
# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
# CONFIG_RTC_DRV_V3020 is not set
#
# on-CPU RTC drivers
#
CONFIG_RTC_DRV_SA1100=y
+# CONFIG_RTC_DRV_PXA is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
#
# File systems
@@ -927,19 +1194,18 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
@@ -965,15 +1231,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -997,9 +1261,13 @@ CONFIG_JFFS2_CMODE_PRIORITY=y
# CONFIG_JFFS2_CMODE_SIZE is not set
# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
@@ -1007,14 +1275,13 @@ CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1076,6 +1343,7 @@ CONFIG_NLS_UTF8=y
CONFIG_PRINTK_TIME=y
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
# CONFIG_DEBUG_FS is not set
@@ -1083,15 +1351,18 @@ CONFIG_ENABLE_MUST_CHECK=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_LOCK_STAT is not set
@@ -1100,17 +1371,41 @@ CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
CONFIG_FRAME_POINTER=y
-CONFIG_FORCED_INLINING=y
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_LL=y
# CONFIG_DEBUG_ICEDCC is not set
@@ -1119,55 +1414,110 @@ CONFIG_DEBUG_LL=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG2=m
CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_NULL is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
CONFIG_CRYPTO_SHA1=m
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-CONFIG_CRYPTO_ECB=m
-# CONFIG_CRYPTO_CBC is not set
-CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
#
# Library routines
#
CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=y
# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig
index 83c817f31bcc..b0698722e0cb 100644
--- a/arch/arm/configs/mv78xx0_defconfig
+++ b/arch/arm/configs/mv78xx0_defconfig
@@ -165,6 +165,7 @@ CONFIG_ARCH_MV78XX0=y
# Marvell MV78xx0 Implementations
#
CONFIG_MACH_DB78X00_BP=y
+CONFIG_MACH_RD78X00_MASA=y
#
# Boot options
diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig
index d81ea219c934..36cd62edd05c 100644
--- a/arch/arm/configs/neponset_defconfig
+++ b/arch/arm/configs/neponset_defconfig
@@ -91,7 +91,6 @@ CONFIG_ASSABET_NEPONSET=y
# CONFIG_SA1100_COLLIE is not set
# CONFIG_SA1100_H3100 is not set
# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
# CONFIG_SA1100_BADGE4 is not set
# CONFIG_SA1100_JORNADA720 is not set
# CONFIG_SA1100_HACKKIT is not set
diff --git a/arch/arm/configs/omap_3430sdp_defconfig b/arch/arm/configs/omap_3430sdp_defconfig
new file mode 100644
index 000000000000..8fb918d9ba65
--- /dev/null
+++ b/arch/arm/configs/omap_3430sdp_defconfig
@@ -0,0 +1,2061 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc8
+# Fri Mar 13 14:17:01 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_OPROFILE_ARMV7=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+# CONFIG_OMAP_RESET_CLOCKS is not set
+CONFIG_OMAP_MUX=y
+CONFIG_OMAP_MUX_DEBUG=y
+CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+CONFIG_OMAP_SERIAL_WAKE=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+CONFIG_MACH_OMAP3_BEAGLE=y
+CONFIG_MACH_OMAP_LDP=y
+CONFIG_MACH_OVERO=y
+CONFIG_MACH_OMAP3_PANDORA=y
+CONFIG_MACH_OMAP_3430SDP=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_LEDS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS2,115200 root=/dev/mmcblk0p3 rootwait debug"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_LL is not set
+CONFIG_BT_HCIBCM203X=y
+CONFIG_BT_HCIBPA10X=y
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_NL80211=y
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=y
+CONFIG_LIB80211_CRYPT_WEP=m
+CONFIG_LIB80211_CRYPT_CCMP=m
+CONFIG_LIB80211_CRYPT_TKIP=m
+CONFIG_MAC80211=y
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_PID=y
+# CONFIG_MAC80211_RC_MINSTREL is not set
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
+CONFIG_MAC80211_RC_DEFAULT="pid"
+# CONFIG_MAC80211_MESH is not set
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+CONFIG_EEPROM_93CX6=m
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_DELAY=m
+# CONFIG_DM_UEVENT is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+CONFIG_SMC911X=m
+CONFIG_SMSC911X=m
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=y
+CONFIG_LIBERTAS_USB=y
+CONFIG_LIBERTAS_SDIO=y
+CONFIG_LIBERTAS_DEBUG=y
+# CONFIG_LIBERTAS_THINFIRM is not set
+CONFIG_USB_ZD1201=m
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+CONFIG_RTL8187=m
+# CONFIG_MAC80211_HWSIM is not set
+CONFIG_P54_COMMON=m
+CONFIG_P54_USB=m
+# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_ZD1211RW is not set
+# CONFIG_RT2X00 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_AX8817X=y
+CONFIG_USB_NET_CDCETHER=y
+CONFIG_USB_NET_DM9601=m
+# CONFIG_USB_NET_SMSC95XX is not set
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_NET_ZAURUS=m
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+CONFIG_GPIO_TWL4030=y
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=m
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_OMAP_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+CONFIG_TWL4030_CORE=y
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_DVB_CORE=m
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+CONFIG_MEDIA_ATTACH=y
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA827X=m
+CONFIG_MEDIA_TUNER_TDA18271=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_MT2060=m
+CONFIG_MEDIA_TUNER_MT2266=m
+CONFIG_MEDIA_TUNER_QT1010=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MEDIA_TUNER_MXL5005S=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_CX2341X=m
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_VIDEO_AU0828 is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+# CONFIG_USB_GSPCA is not set
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+CONFIG_VIDEO_PVRUSB2_DVB=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+# CONFIG_VIDEO_EM28XX is not set
+CONFIG_VIDEO_USBVISION=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+# CONFIG_USB_ET61X251 is not set
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+# CONFIG_USB_ZC0301 is not set
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+CONFIG_USB_ZR364XX=m
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_SI470X is not set
+# CONFIG_USB_MR800 is not set
+# CONFIG_RADIO_TEA5764 is not set
+# CONFIG_DVB_DYNAMIC_MINORS is not set
+CONFIG_DVB_CAPTURE_DRIVERS=y
+# CONFIG_TTPCI_EEPROM is not set
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_DIB0700=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_M920X=m
+CONFIG_DVB_USB_GL861=m
+CONFIG_DVB_USB_AU6610=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_TTUSB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_USB_OPERA1=m
+CONFIG_DVB_USB_AF9005=m
+CONFIG_DVB_USB_AF9005_REMOTE=m
+# CONFIG_DVB_USB_DW2102 is not set
+# CONFIG_DVB_USB_CINERGY_T2 is not set
+# CONFIG_DVB_USB_ANYSEE is not set
+# CONFIG_DVB_USB_DTV5100 is not set
+# CONFIG_DVB_USB_AF9015 is not set
+# CONFIG_DVB_SIANO_SMS1XXX is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+# CONFIG_DVB_FE_CUSTOMISE is not set
+
+#
+# Multistandard (satellite) frontends
+#
+# CONFIG_DVB_STB0899 is not set
+# CONFIG_DVB_STB6100 is not set
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_S5H1420=m
+# CONFIG_DVB_STV0288 is not set
+# CONFIG_DVB_STB6000 is not set
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_TDA10086=m
+# CONFIG_DVB_TDA8261 is not set
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_TUNER_ITD1000=m
+# CONFIG_DVB_TUNER_CX24113 is not set
+CONFIG_DVB_TDA826X=m
+CONFIG_DVB_TUA6100=m
+# CONFIG_DVB_CX24116 is not set
+# CONFIG_DVB_SI21XX is not set
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+# CONFIG_DVB_DRX397XD is not set
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+CONFIG_DVB_DIB7000M=m
+CONFIG_DVB_DIB7000P=m
+CONFIG_DVB_TDA10048=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_TDA10023=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+# CONFIG_DVB_OR51211 is not set
+# CONFIG_DVB_OR51132 is not set
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+# CONFIG_DVB_LGDT3304 is not set
+CONFIG_DVB_S5H1409=m
+CONFIG_DVB_AU8522=m
+CONFIG_DVB_S5H1411=m
+
+#
+# ISDB-T (terrestrial) frontends
+#
+# CONFIG_DVB_S921 is not set
+
+#
+# Digital terrestrial only tuners/PLL
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_TUNER_DIB0070=m
+
+#
+# SEC control devices for DVB-S
+#
+CONFIG_DVB_LNBP21=m
+# CONFIG_DVB_ISL6405 is not set
+CONFIG_DVB_ISL6421=m
+# CONFIG_DVB_LGS8GL5 is not set
+
+#
+# Tools to develop new frontends
+#
+# CONFIG_DVB_DUMMY_FE is not set
+# CONFIG_DVB_AF9013 is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=y
+CONFIG_SND_RAWMIDI=y
+CONFIG_SND_SEQUENCER=m
+# CONFIG_SND_SEQ_DUMMY is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DEBUG=y
+# CONFIG_SND_DEBUG_VERBOSE is not set
+# CONFIG_SND_PCM_XRUN_DEBUG is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+CONFIG_SND_OMAP_SOC_MCBSP=y
+# CONFIG_SND_OMAP_SOC_OVERO is not set
+CONFIG_SND_OMAP_SOC_SDP3430=y
+CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_TWL4030=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+# CONFIG_USB_MUSB_HOST is not set
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+CONFIG_USB_MUSB_OTG=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_MUSB_HDRC_HCD=y
+CONFIG_MUSB_PIO_ONLY=y
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+CONFIG_USB_PRINTER=y
+CONFIG_USB_WDM=y
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TWL4030_USB=y
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=y
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+CONFIG_RTC_DRV_TWL4030=y
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_XOR_BLOCKS=m
+CONFIG_ASYNC_CORE=m
+CONFIG_ASYNC_MEMCPY=m
+CONFIG_ASYNC_XOR=m
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/omap_ldp_defconfig b/arch/arm/configs/omap_ldp_defconfig
index aa9d34feddc6..679a4a3e265e 100644
--- a/arch/arm/configs/omap_ldp_defconfig
+++ b/arch/arm/configs/omap_ldp_defconfig
@@ -474,14 +474,34 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
# CONFIG_ENC28J60 is not set
-CONFIG_SMC911X=y
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index a8ee6984a09e..020e6a8a9e5c 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -481,7 +481,7 @@ CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_CAFE is not set
# CONFIG_MTD_NAND_NANDSIM is not set
-# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_NAND_PLATFORM=y
# CONFIG_MTD_ALAUDA is not set
CONFIG_MTD_NAND_ORION=y
# CONFIG_MTD_ONENAND is not set
@@ -1177,7 +1177,7 @@ CONFIG_RTC_DRV_S35390A=y
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_M48T86=y
# CONFIG_RTC_DRV_M48T59 is not set
# CONFIG_RTC_DRV_V3020 is not set
diff --git a/arch/arm/configs/pcm037_defconfig b/arch/arm/configs/pcm037_defconfig
index 627474586470..6e37c77c4760 100644
--- a/arch/arm/configs/pcm037_defconfig
+++ b/arch/arm/configs/pcm037_defconfig
@@ -465,12 +465,33 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_AX88796 is not set
CONFIG_SMC91X=y
# CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
diff --git a/arch/arm/configs/pleb_defconfig b/arch/arm/configs/pleb_defconfig
index a6b47ea8e465..f2d2dda25949 100644
--- a/arch/arm/configs/pleb_defconfig
+++ b/arch/arm/configs/pleb_defconfig
@@ -88,7 +88,6 @@ CONFIG_ARCH_SA1100=y
# CONFIG_SA1100_COLLIE is not set
# CONFIG_SA1100_H3100 is not set
# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
# CONFIG_SA1100_BADGE4 is not set
# CONFIG_SA1100_JORNADA720 is not set
# CONFIG_SA1100_HACKKIT is not set
diff --git a/arch/arm/configs/pxa168_defconfig b/arch/arm/configs/pxa168_defconfig
new file mode 100644
index 000000000000..db5faeaec96c
--- /dev/null
+++ b/arch/arm/configs/pxa168_defconfig
@@ -0,0 +1,891 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc3
+# Fri Mar 20 13:43:13 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+CONFIG_ARCH_MMP=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_MACH_TAVOREVB is not set
+
+#
+# Marvell PXA168/910 Implmentations
+#
+CONFIG_MACH_ASPENITE=y
+CONFIG_MACH_ZYLONITE2=y
+# CONFIG_MACH_TTC_DKB is not set
+CONFIG_CPU_PXA168=y
+CONFIG_PLAT_PXA=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_MOHAWK=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.2.100:/nfsroot/ ip=192.168.2.101:192.168.2.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=128M"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/pxa910_defconfig b/arch/arm/configs/pxa910_defconfig
new file mode 100644
index 000000000000..8c7e299f1d66
--- /dev/null
+++ b/arch/arm/configs/pxa910_defconfig
@@ -0,0 +1,891 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc3
+# Fri Mar 20 13:45:12 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+CONFIG_ARCH_MMP=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
+CONFIG_MACH_TAVOREVB=y
+
+#
+# Marvell PXA168/910 Implmentations
+#
+# CONFIG_MACH_ASPENITE is not set
+# CONFIG_MACH_ZYLONITE2 is not set
+CONFIG_MACH_TTC_DKB=y
+CONFIG_CPU_PXA910=y
+CONFIG_PLAT_PXA=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_MOHAWK=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_IWMMXT=y
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.2.100:/nfsroot/ ip=192.168.2.101:192.168.2.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=128M"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig
index cd29824d791c..21db4b3ec8ff 100644
--- a/arch/arm/configs/realview-smp_defconfig
+++ b/arch/arm/configs/realview-smp_defconfig
@@ -496,13 +496,33 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_AX88796 is not set
CONFIG_SMC91X=y
# CONFIG_DM9000 is not set
-CONFIG_SMC911X=y
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig
index 7e253f58ed18..9a75c30b910d 100644
--- a/arch/arm/configs/realview_defconfig
+++ b/arch/arm/configs/realview_defconfig
@@ -490,13 +490,33 @@ CONFIG_NETDEVICES=y
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
-# CONFIG_PHYLIB is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_AX88796 is not set
CONFIG_SMC91X=y
# CONFIG_DM9000 is not set
-CONFIG_SMC911X=y
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
diff --git a/arch/arm/configs/rx51_defconfig b/arch/arm/configs/rx51_defconfig
new file mode 100644
index 000000000000..593102da8cd7
--- /dev/null
+++ b/arch/arm/configs/rx51_defconfig
@@ -0,0 +1,1821 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc8
+# Fri Mar 13 15:28:56 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_KRETPROBES=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+CONFIG_OMAP_RESET_CLOCKS=y
+CONFIG_OMAP_MUX=y
+CONFIG_OMAP_MUX_DEBUG=y
+CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+CONFIG_OMAP_SERIAL_WAKE=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+# CONFIG_MACH_OMAP_LDP is not set
+# CONFIG_MACH_OVERO is not set
+# CONFIG_MACH_OMAP3_PANDORA is not set
+# CONFIG_MACH_OMAP_3430SDP is not set
+CONFIG_MACH_NOKIA_RX51=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/preinit ubi.mtd=4 root=ubi0:rootfs rootfstype=ubifs rw console=ttyMTD5"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_VERBOSE is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+CONFIG_IP_NF_FILTER=m
+# CONFIG_IP_NF_TARGET_REJECT is not set
+# CONFIG_IP_NF_TARGET_LOG is not set
+# CONFIG_IP_NF_TARGET_ULOG is not set
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_NF_RAW is not set
+# CONFIG_IP_NF_SECURITY is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_NL80211=y
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+CONFIG_MAC80211=m
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_PID=y
+# CONFIG_MAC80211_RC_MINSTREL is not set
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
+CONFIG_MAC80211_RC_DEFAULT="pid"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_LEDS is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+CONFIG_MTD_OOPS=y
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_OMAP_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+CONFIG_MTD_ONENAND=y
+# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
+# CONFIG_MTD_ONENAND_GENERIC is not set
+CONFIG_MTD_ONENAND_OMAP2=y
+# CONFIG_MTD_ONENAND_OTP is not set
+# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
+# CONFIG_MTD_ONENAND_SIM is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=m
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+# CONFIG_LIBERTAS is not set
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_P54_COMMON is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_ZD1211RW is not set
+# CONFIG_RT2X00 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+CONFIG_GPIO_TWL4030=y
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_OMAP_WATCHDOG=m
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+CONFIG_TWL4030_CORE=y
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+# CONFIG_USB_GSPCA is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_SI470X is not set
+# CONFIG_USB_MR800 is not set
+# CONFIG_RADIO_TEA5764 is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=m
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_LOGITECH=m
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_NTRIG is not set
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+CONFIG_USB_OTG_WHITELIST=y
+CONFIG_USB_OTG_BLACKLIST_HUB=y
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+# CONFIG_USB_MUSB_HOST is not set
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+CONFIG_USB_MUSB_OTG=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=m
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_DEBUG=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+# CONFIG_USB_ZERO_HNPTEST is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TWL4030_USB=y
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=m
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+CONFIG_RTC_DRV_TWL4030=m
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_LOCK_ALLOC=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_LOCKDEP=y
+CONFIG_LOCK_STAT=y
+# CONFIG_DEBUG_LOCKDEP is not set
+CONFIG_TRACE_IRQFLAGS=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_NETWORK is not set
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_ROOTPLUG is not set
+CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/shannon_defconfig b/arch/arm/configs/shannon_defconfig
index d052c8f80515..984f7096a533 100644
--- a/arch/arm/configs/shannon_defconfig
+++ b/arch/arm/configs/shannon_defconfig
@@ -87,7 +87,6 @@ CONFIG_ARCH_SA1100=y
# CONFIG_SA1100_COLLIE is not set
# CONFIG_SA1100_H3100 is not set
# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
# CONFIG_SA1100_BADGE4 is not set
# CONFIG_SA1100_JORNADA720 is not set
# CONFIG_SA1100_HACKKIT is not set
diff --git a/arch/arm/configs/shark_defconfig b/arch/arm/configs/shark_defconfig
index 9b6561d119af..90235bf7a1de 100644
--- a/arch/arm/configs/shark_defconfig
+++ b/arch/arm/configs/shark_defconfig
@@ -1,88 +1,174 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-git3
-# Sat Jul 16 15:21:47 2005
+# Linux kernel version: 2.6.28-git6
+# Thu Jan 8 17:14:47 2009
#
CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
CONFIG_MMU=y
-CONFIG_UID16=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
+# General setup
#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_FREEZER is not set
#
# System Type
#
-# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
CONFIG_ARCH_SHARK=y
# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
#
# Processor Type
@@ -91,14 +177,20 @@ CONFIG_CPU_32=y
CONFIG_CPU_SA110=y
CONFIG_CPU_32v4=y
CONFIG_CPU_ABRT_EV4=y
+CONFIG_CPU_PABRT_NOIFAR=y
CONFIG_CPU_CACHE_V4WB=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_V4WB=y
CONFIG_CPU_TLB_V4WB=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
#
# Processor Features
#
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
#
# Bus support
@@ -107,22 +199,40 @@ CONFIG_ISA=y
CONFIG_ISA_DMA=y
CONFIG_ISA_DMA_API=y
CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
CONFIG_PCI_HOST_VIA82C505=y
-CONFIG_PCI_LEGACY_PROC=y
-# CONFIG_PCI_NAMES is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
# CONFIG_PCCARD is not set
#
# Kernel Features
#
-# CONFIG_SMP is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
# CONFIG_PREEMPT is not set
-# CONFIG_DISCONTIGMEM is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
CONFIG_LEDS=y
CONFIG_LEDS_TIMER=y
# CONFIG_LEDS_CPU is not set
@@ -135,6 +245,12 @@ CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE=""
# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
#
# Floating point emulation
@@ -143,13 +259,16 @@ CONFIG_CMDLINE=""
#
# At least one emulation must be selected
#
-# CONFIG_FPE_NWFPE is not set
-CONFIG_FPE_FASTFPE=y
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
#
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
# CONFIG_BINFMT_AOUT is not set
# CONFIG_BINFMT_MISC is not set
# CONFIG_ARTHUR is not set
@@ -158,44 +277,104 @@ CONFIG_BINFMT_ELF=y
# Power management options
#
# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
#
-# Device Drivers
+# Networking options
#
+# CONFIG_NET_NS is not set
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
#
-# Generic Driver Options
+# Network testing
#
-# CONFIG_STANDALONE is not set
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
-# Memory Technology Devices (MTD)
+# Device Drivers
#
-# CONFIG_MTD is not set
#
-# Parallel port support
+# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
# CONFIG_PARPORT_SERIAL is not set
# CONFIG_PARPORT_PC_FIFO is not set
# CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_ARC is not set
# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
# CONFIG_PARPORT_1284 is not set
-
-#
-# Plug and Play support
-#
# CONFIG_PNP is not set
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
@@ -210,52 +389,78 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
#
-# Please see Documentation/ide.txt for help/info on IDE drives
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
+CONFIG_IDE_ATAPI=y
# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
CONFIG_BLK_DEV_IDECD=m
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDEFLOPPY=y
-# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
#
# IDE chipset support/bugfixes
#
-CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
CONFIG_IDE_ARM=y
-# CONFIG_IDE_CHIPSETS is not set
# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
#
# SCSI device support
#
+# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -275,17 +480,20 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
#
-# SCSI Transport Attributes
+# SCSI Transports
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_7000FASST is not set
@@ -296,12 +504,18 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
@@ -314,20 +528,15 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_PPA is not set
# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_MVSAS is not set
# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_DC395x is not set
@@ -336,123 +545,57 @@ CONFIG_SCSI_QLA2XXX=m
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
# CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
#
# IEEE 1394 (FireWire) support
#
-# CONFIG_IEEE1394 is not set
#
-# I2O device support
+# Enable only one of the two stacks, unless you know what you are doing
#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
# CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
+# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
+# CONFIG_AX88796 is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
# CONFIG_NET_VENDOR_RACAL is not set
-
-#
-# Tulip family network device support
-#
# CONFIG_NET_TULIP is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
@@ -462,56 +605,69 @@ CONFIG_NET_PCI=y
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
CONFIG_CS89x0=y
-# CONFIG_DGRS is not set
-# CONFIG_EEPRO100 is not set
+CONFIG_CS89x0_NOEEPROM=y
# CONFIG_E100 is not set
# CONFIG_FEALNX is not set
# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
# CONFIG_8139CP is not set
# CONFIG_8139TOO is not set
+# CONFIG_R6040 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
-# CONFIG_SK98LIN is not set
+# CONFIG_SKY2 is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_JME is not set
+CONFIG_NETDEV_10000=y
+# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
+# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
# CONFIG_TR is not set
#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
+# Wireless LAN
#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -519,18 +675,17 @@ CONFIG_CS89x0=y
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_ISDN is not set
#
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -540,7 +695,6 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set
@@ -553,14 +707,25 @@ CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
# CONFIG_MOUSE_INPORT is not set
# CONFIG_MOUSE_LOGIBM is not set
# CONFIG_MOUSE_PC110PAD is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
@@ -580,16 +745,22 @@ CONFIG_SERIO_LIBPS2=y
# Character devices
#
CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set
#
@@ -599,90 +770,122 @@ CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
CONFIG_PRINTER=m
# CONFIG_LP_CONSOLE is not set
# CONFIG_PPDEV is not set
-# CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
+CONFIG_HW_RANDOM=m
# CONFIG_NVRAM is not set
-CONFIG_RTC=y
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
#
-# TPM devices
+# Sonics Silicon Backplane
#
-# CONFIG_TCG_TPM is not set
+# CONFIG_SSB is not set
#
-# I2C support
+# Multifunction device drivers
#
-# CONFIG_I2C is not set
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
#
-# Misc devices
+# Multimedia devices
#
#
-# Multimedia devices
+# Multimedia core support
#
# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
#
-# Digital Video Broadcasting Devices
+# Multimedia drivers
#
-# CONFIG_DVB is not set
+# CONFIG_DAB is not set
#
# Graphics support
#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
CONFIG_FB_CYBER2000=y
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
#
# Console display driver support
@@ -691,126 +894,132 @@ CONFIG_FB_CYBER2000=y
# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
CONFIG_SOUND=m
-
-#
-# Advanced Linux Sound Architecture
-#
+CONFIG_SOUND_OSS_CORE=y
# CONFIG_SND is not set
-
-#
-# Open Sound System
-#
CONFIG_SOUND_PRIME=m
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
CONFIG_SOUND_OSS=m
# CONFIG_SOUND_TRACEINIT is not set
# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_AD1889 is not set
-# CONFIG_SOUND_SGALAXY is not set
-CONFIG_SOUND_ADLIB=m
-# CONFIG_SOUND_ACI_MIXER is not set
-# CONFIG_SOUND_CS4232 is not set
# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
# CONFIG_SOUND_VMIDI is not set
# CONFIG_SOUND_TRIX is not set
# CONFIG_SOUND_MSS is not set
# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
# CONFIG_SOUND_PAS is not set
# CONFIG_SOUND_PSS is not set
CONFIG_SOUND_SB=m
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_YMFPCI is not set
# CONFIG_SOUND_UART6850 is not set
# CONFIG_SOUND_AEDSP16 is not set
# CONFIG_SOUND_KAHLUA is not set
-# CONFIG_SOUND_ALI5455 is not set
-# CONFIG_SOUND_FORTE is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_AD1980 is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
#
-# USB support
+# Special HID drivers
#
+CONFIG_HID_COMPAT=y
+CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_USB is not set
#
-# USB Gadget Support
+# Enable Host or Gadget support to see Inventra options
#
-# CONFIG_USB_GADGET is not set
#
-# MMC/SD Card support
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
#
+# CONFIG_USB_GADGET is not set
+# CONFIG_UWB is not set
# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+CONFIG_RTC_DRV_CMOS=y
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
+# CONFIG_OCFS2_FS is not set
CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
@@ -834,14 +1043,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# Pseudo filesystems
#
CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -855,22 +1062,27 @@ CONFIG_RAMFS=y
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=m
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_LOCKD=m
+CONFIG_NFSD=m
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
-CONFIG_SUNRPC=m
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -897,11 +1109,9 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
+# CONFIG_SYSV68_PARTITION is not set
CONFIG_NLS=m
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=m
@@ -942,30 +1152,74 @@ CONFIG_NLS_ISO8859_1=m
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
+# CONFIG_DLM is not set
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
-CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_LL is not set
#
@@ -973,19 +1227,23 @@ CONFIG_DEBUG_USER=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
# CONFIG_CRYPTO is not set
#
-# Hardware crypto devices
-#
-
-#
# Library routines
#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/simpad_defconfig b/arch/arm/configs/simpad_defconfig
index 03f783e696b3..685d2b513206 100644
--- a/arch/arm/configs/simpad_defconfig
+++ b/arch/arm/configs/simpad_defconfig
@@ -89,7 +89,6 @@ CONFIG_ARCH_SA1100=y
# CONFIG_SA1100_COLLIE is not set
# CONFIG_SA1100_H3100 is not set
# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
# CONFIG_SA1100_BADGE4 is not set
# CONFIG_SA1100_JORNADA720 is not set
# CONFIG_SA1100_HACKKIT is not set
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 6cbd8fdc9f1f..bb7d695f3900 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -46,6 +46,14 @@
# define MULTI_CACHE 1
#endif
+#if defined(CONFIG_CPU_FA526)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE fa
+# endif
+#endif
+
#if defined(CONFIG_CPU_ARM926T)
# ifdef _CACHE
# define MULTI_CACHE 1
@@ -94,6 +102,14 @@
# endif
#endif
+#if defined(CONFIG_CPU_MOHAWK)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE mohawk
+# endif
+#endif
+
#if defined(CONFIG_CPU_FEROCEON)
# define MULTI_CACHE 1
#endif
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index 22cb14ec3438..ff46dfa68a97 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -15,10 +15,20 @@
* must not be used by drivers.
*/
#ifndef __arch_page_to_dma
+
+#if !defined(CONFIG_HIGHMEM)
static inline dma_addr_t page_to_dma(struct device *dev, struct page *page)
{
return (dma_addr_t)__virt_to_bus((unsigned long)page_address(page));
}
+#elif defined(__pfn_to_bus)
+static inline dma_addr_t page_to_dma(struct device *dev, struct page *page)
+{
+ return (dma_addr_t)__pfn_to_bus(page_to_pfn(page));
+}
+#else
+#error "this machine class needs to define __arch_page_to_dma to use HIGHMEM"
+#endif
static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
{
@@ -57,6 +67,8 @@ static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
* Use the driver DMA support - see dma-mapping.h (dma_sync_*)
*/
extern void dma_cache_maint(const void *kaddr, size_t size, int rw);
+extern void dma_cache_maint_page(struct page *page, unsigned long offset,
+ size_t size, int rw);
/*
* Return whether the given device DMA address mask can be supported
@@ -316,7 +328,7 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
BUG_ON(!valid_dma_direction(dir));
if (!arch_is_coherent())
- dma_cache_maint(page_address(page) + offset, size, dir);
+ dma_cache_maint_page(page, offset, size, dir);
return page_to_dma(dev, page) + offset;
}
diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h
index df5638f3643a..7edf3536df24 100644
--- a/arch/arm/include/asm/dma.h
+++ b/arch/arm/include/asm/dma.h
@@ -19,21 +19,17 @@
#include <asm/system.h>
#include <asm/scatterlist.h>
-typedef unsigned int dmach_t;
-
#include <mach/isa-dma.h>
/*
- * DMA modes
+ * The DMA modes reflect the settings for the ISA DMA controller
*/
-typedef unsigned int dmamode_t;
-
-#define DMA_MODE_MASK 3
+#define DMA_MODE_MASK 0xcc
-#define DMA_MODE_READ 0
-#define DMA_MODE_WRITE 1
-#define DMA_MODE_CASCADE 2
-#define DMA_AUTOINIT 4
+#define DMA_MODE_READ 0x44
+#define DMA_MODE_WRITE 0x48
+#define DMA_MODE_CASCADE 0xc0
+#define DMA_AUTOINIT 0x10
extern spinlock_t dma_spin_lock;
@@ -52,44 +48,44 @@ static inline void release_dma_lock(unsigned long flags)
/* Clear the 'DMA Pointer Flip Flop'.
* Write 0 for LSB/MSB, 1 for MSB/LSB access.
*/
-#define clear_dma_ff(channel)
+#define clear_dma_ff(chan)
/* Set only the page register bits of the transfer address.
*
* NOTE: This is an architecture specific function, and should
* be hidden from the drivers
*/
-extern void set_dma_page(dmach_t channel, char pagenr);
+extern void set_dma_page(unsigned int chan, char pagenr);
/* Request a DMA channel
*
* Some architectures may need to do allocate an interrupt
*/
-extern int request_dma(dmach_t channel, const char * device_id);
+extern int request_dma(unsigned int chan, const char * device_id);
/* Free a DMA channel
*
* Some architectures may need to do free an interrupt
*/
-extern void free_dma(dmach_t channel);
+extern void free_dma(unsigned int chan);
/* Enable DMA for this channel
*
* On some architectures, this may have other side effects like
* enabling an interrupt and setting the DMA registers.
*/
-extern void enable_dma(dmach_t channel);
+extern void enable_dma(unsigned int chan);
/* Disable DMA for this channel
*
* On some architectures, this may have other side effects like
* disabling an interrupt or whatever.
*/
-extern void disable_dma(dmach_t channel);
+extern void disable_dma(unsigned int chan);
/* Test whether the specified channel has an active DMA transfer
*/
-extern int dma_channel_active(dmach_t channel);
+extern int dma_channel_active(unsigned int chan);
/* Set the DMA scatter gather list for this channel
*
@@ -97,7 +93,7 @@ extern int dma_channel_active(dmach_t channel);
* especially since some DMA architectures don't update the
* DMA address immediately, but defer it to the enable_dma().
*/
-extern void set_dma_sg(dmach_t channel, struct scatterlist *sg, int nr_sg);
+extern void set_dma_sg(unsigned int chan, struct scatterlist *sg, int nr_sg);
/* Set the DMA address for this channel
*
@@ -105,9 +101,9 @@ extern void set_dma_sg(dmach_t channel, struct scatterlist *sg, int nr_sg);
* especially since some DMA architectures don't update the
* DMA address immediately, but defer it to the enable_dma().
*/
-extern void __set_dma_addr(dmach_t channel, void *addr);
-#define set_dma_addr(channel, addr) \
- __set_dma_addr(channel, bus_to_virt(addr))
+extern void __set_dma_addr(unsigned int chan, void *addr);
+#define set_dma_addr(chan, addr) \
+ __set_dma_addr(chan, bus_to_virt(addr))
/* Set the DMA byte count for this channel
*
@@ -115,7 +111,7 @@ extern void __set_dma_addr(dmach_t channel, void *addr);
* especially since some DMA architectures don't update the
* DMA count immediately, but defer it to the enable_dma().
*/
-extern void set_dma_count(dmach_t channel, unsigned long count);
+extern void set_dma_count(unsigned int chan, unsigned long count);
/* Set the transfer direction for this channel
*
@@ -124,11 +120,11 @@ extern void set_dma_count(dmach_t channel, unsigned long count);
* DMA transfer direction immediately, but defer it to the
* enable_dma().
*/
-extern void set_dma_mode(dmach_t channel, dmamode_t mode);
+extern void set_dma_mode(unsigned int chan, unsigned int mode);
/* Set the transfer speed for this channel
*/
-extern void set_dma_speed(dmach_t channel, int cycle_ns);
+extern void set_dma_speed(unsigned int chan, int cycle_ns);
/* Get DMA residue count. After a DMA transfer, this
* should return zero. Reading this while a DMA transfer is
@@ -136,7 +132,7 @@ extern void set_dma_speed(dmach_t channel, int cycle_ns);
* If called before the channel has been used, it may return 1.
* Otherwise, it returns the number of _bytes_ left to transfer.
*/
-extern int get_dma_residue(dmach_t channel);
+extern int get_dma_residue(unsigned int chan);
#ifndef NO_DMA
#define NO_DMA 255
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index a58378c343b9..d7da19bcf928 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -50,6 +50,8 @@ typedef struct user_fp elf_fpregset_t;
#define R_ARM_ABS32 2
#define R_ARM_CALL 28
#define R_ARM_JUMP24 29
+#define R_ARM_V4BX 40
+#define R_ARM_PREL31 42
/*
* These are used to set parameters in the core dumps.
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
new file mode 100644
index 000000000000..bbae919bceb4
--- /dev/null
+++ b/arch/arm/include/asm/fixmap.h
@@ -0,0 +1,41 @@
+#ifndef _ASM_FIXMAP_H
+#define _ASM_FIXMAP_H
+
+/*
+ * Nothing too fancy for now.
+ *
+ * On ARM we already have well known fixed virtual addresses imposed by
+ * the architecture such as the vector page which is located at 0xffff0000,
+ * therefore a second level page table is already allocated covering
+ * 0xfff00000 upwards.
+ *
+ * The cache flushing code in proc-xscale.S uses the virtual area between
+ * 0xfffe0000 and 0xfffeffff.
+ */
+
+#define FIXADDR_START 0xfff00000UL
+#define FIXADDR_TOP 0xfffe0000UL
+#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
+
+#define FIX_KMAP_BEGIN 0
+#define FIX_KMAP_END (FIXADDR_SIZE >> PAGE_SHIFT)
+
+#define __fix_to_virt(x) (FIXADDR_START + ((x) << PAGE_SHIFT))
+#define __virt_to_fix(x) (((x) - FIXADDR_START) >> PAGE_SHIFT)
+
+extern void __this_fixmap_does_not_exist(void);
+
+static inline unsigned long fix_to_virt(const unsigned int idx)
+{
+ if (idx >= FIX_KMAP_END)
+ __this_fixmap_does_not_exist();
+ return __fix_to_virt(idx);
+}
+
+static inline unsigned int virt_to_fix(const unsigned long vaddr)
+{
+ BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
+ return __virt_to_fix(vaddr);
+}
+
+#endif
diff --git a/arch/arm/include/asm/hardware/scoop.h b/arch/arm/include/asm/hardware/scoop.h
index dfb8330599f9..46492a63a7c4 100644
--- a/arch/arm/include/asm/hardware/scoop.h
+++ b/arch/arm/include/asm/hardware/scoop.h
@@ -63,7 +63,5 @@ struct scoop_pcmcia_config {
extern struct scoop_pcmcia_config *platform_scoop_config;
void reset_scoop(struct device *dev);
-unsigned short __deprecated set_scoop_gpio(struct device *dev, unsigned short bit);
-unsigned short __deprecated reset_scoop_gpio(struct device *dev, unsigned short bit);
unsigned short read_scoop_reg(struct device *dev, unsigned short reg);
void write_scoop_reg(struct device *dev, unsigned short reg, unsigned short data);
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
new file mode 100644
index 000000000000..7f36d00600b4
--- /dev/null
+++ b/arch/arm/include/asm/highmem.h
@@ -0,0 +1,31 @@
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#include <asm/kmap_types.h>
+
+#define PKMAP_BASE (PAGE_OFFSET - PMD_SIZE)
+#define LAST_PKMAP PTRS_PER_PTE
+#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
+#define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+#define kmap_prot PAGE_KERNEL
+
+#define flush_cache_kmaps() flush_cache_all()
+
+extern pte_t *pkmap_page_table;
+
+#define ARCH_NEEDS_KMAP_HIGH_GET
+
+extern void *kmap_high(struct page *page);
+extern void *kmap_high_get(struct page *page);
+extern void kunmap_high(struct page *page);
+
+extern void *kmap(struct page *page);
+extern void kunmap(struct page *page);
+extern void *kmap_atomic(struct page *page, enum km_type type);
+extern void kunmap_atomic(void *kvaddr, enum km_type type);
+extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
+extern struct page *kmap_atomic_to_page(const void *ptr);
+
+#endif
diff --git a/arch/arm/include/asm/hwcap.h b/arch/arm/include/asm/hwcap.h
index bda489f9f017..f7bd52b1c365 100644
--- a/arch/arm/include/asm/hwcap.h
+++ b/arch/arm/include/asm/hwcap.h
@@ -17,6 +17,8 @@
#define HWCAP_CRUNCH 1024
#define HWCAP_THUMBEE 2048
#define HWCAP_NEON 4096
+#define HWCAP_VFPv3 8192
+#define HWCAP_VFPv3D16 16384
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
/*
diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h
index 45def13ee17a..d16ec97ec9a9 100644
--- a/arch/arm/include/asm/kmap_types.h
+++ b/arch/arm/include/asm/kmap_types.h
@@ -18,6 +18,7 @@ enum km_type {
KM_IRQ1,
KM_SOFTIRQ0,
KM_SOFTIRQ1,
+ KM_L2_CACHE,
KM_TYPE_NR
};
diff --git a/arch/arm/include/asm/mach/dma.h b/arch/arm/include/asm/mach/dma.h
index fc7278ea7146..9e614a18e680 100644
--- a/arch/arm/include/asm/mach/dma.h
+++ b/arch/arm/include/asm/mach/dma.h
@@ -15,13 +15,13 @@ struct dma_struct;
typedef struct dma_struct dma_t;
struct dma_ops {
- int (*request)(dmach_t, dma_t *); /* optional */
- void (*free)(dmach_t, dma_t *); /* optional */
- void (*enable)(dmach_t, dma_t *); /* mandatory */
- void (*disable)(dmach_t, dma_t *); /* mandatory */
- int (*residue)(dmach_t, dma_t *); /* optional */
- int (*setspeed)(dmach_t, dma_t *, int); /* optional */
- char *type;
+ int (*request)(unsigned int, dma_t *); /* optional */
+ void (*free)(unsigned int, dma_t *); /* optional */
+ void (*enable)(unsigned int, dma_t *); /* mandatory */
+ void (*disable)(unsigned int, dma_t *); /* mandatory */
+ int (*residue)(unsigned int, dma_t *); /* optional */
+ int (*setspeed)(unsigned int, dma_t *, int); /* optional */
+ const char *type;
};
struct dma_struct {
@@ -34,24 +34,21 @@ struct dma_struct {
unsigned int active:1; /* Transfer active */
unsigned int invalid:1; /* Address/Count changed */
- dmamode_t dma_mode; /* DMA mode */
+ unsigned int dma_mode; /* DMA mode */
int speed; /* DMA speed */
unsigned int lock; /* Device is allocated */
const char *device_id; /* Device name */
- unsigned int dma_base; /* Controller base address */
- int dma_irq; /* Controller IRQ */
- struct scatterlist cur_sg; /* Current controller buffer */
- unsigned int state;
-
- struct dma_ops *d_ops;
+ const struct dma_ops *d_ops;
};
-/* Prototype: void arch_dma_init(dma)
- * Purpose : Initialise architecture specific DMA
- * Params : dma - pointer to array of DMA structures
+/*
+ * isa_dma_add - add an ISA-style DMA channel
*/
-extern void arch_dma_init(dma_t *dma);
+extern int isa_dma_add(unsigned int, dma_t *dma);
-extern void isa_init_dma(dma_t *dma);
+/*
+ * Add the ISA DMA controller. Always takes channels 0-7.
+ */
+extern void isa_init_dma(void);
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
index 39d949b63e80..58cf91f38e6f 100644
--- a/arch/arm/include/asm/mach/map.h
+++ b/arch/arm/include/asm/mach/map.h
@@ -26,6 +26,7 @@ struct map_desc {
#define MT_HIGH_VECTORS 8
#define MT_MEMORY 9
#define MT_ROM 10
+#define MT_MEMORY_NONCACHED 11
#ifdef CONFIG_MMU
extern void iotable_init(struct map_desc *, int);
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 0202a7c20e62..85763db87449 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -44,14 +44,21 @@
* The module space lives between the addresses given by TASK_SIZE
* and PAGE_OFFSET - it must be within 32MB of the kernel text.
*/
-#define MODULES_END (PAGE_OFFSET)
-#define MODULES_VADDR (MODULES_END - 16*1048576)
-
+#define MODULES_VADDR (PAGE_OFFSET - 16*1024*1024)
#if TASK_SIZE > MODULES_VADDR
#error Top of user space clashes with start of module space
#endif
/*
+ * The highmem pkmap virtual space shares the end of the module area.
+ */
+#ifdef CONFIG_HIGHMEM
+#define MODULES_END (PAGE_OFFSET - PMD_SIZE)
+#else
+#define MODULES_END (PAGE_OFFSET)
+#endif
+
+/*
* The XIP kernel gets mapped at the bottom of the module vm area.
* Since we use sections to map it, this macro replaces the physical address
* with its virtual address while keeping offset from the base section.
@@ -181,6 +188,7 @@ static inline void *phys_to_virt(unsigned long x)
#ifndef __virt_to_bus
#define __virt_to_bus __virt_to_phys
#define __bus_to_virt __phys_to_virt
+#define __pfn_to_bus(x) ((x) << PAGE_SHIFT)
#endif
static inline __deprecated unsigned long virt_to_bus(void *x)
diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
index 24b168dc31a3..e4dfa69abb68 100644
--- a/arch/arm/include/asm/module.h
+++ b/arch/arm/include/asm/module.h
@@ -1,15 +1,27 @@
#ifndef _ASM_ARM_MODULE_H
#define _ASM_ARM_MODULE_H
-struct mod_arch_specific
-{
- int foo;
-};
-
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Ehdr Elf32_Ehdr
+struct unwind_table;
+
+struct mod_arch_specific
+{
+#ifdef CONFIG_ARM_UNWIND
+ Elf_Shdr *unw_sec_init;
+ Elf_Shdr *unw_sec_devinit;
+ Elf_Shdr *unw_sec_core;
+ Elf_Shdr *sec_init_text;
+ Elf_Shdr *sec_devinit_text;
+ Elf_Shdr *sec_core_text;
+ struct unwind_table *unwind_init;
+ struct unwind_table *unwind_devinit;
+ struct unwind_table *unwind_core;
+#endif
+};
+
/*
* Include the ARM architecture version.
*/
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index f341c9dbd662..e6eb8a67b807 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -76,6 +76,14 @@
# endif
#endif
+#ifdef CONFIG_CPU_COPY_FA
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER fa
+# endif
+#endif
+
#ifdef CONFIG_CPU_SA1100
# ifdef _USER
# define MULTI_USER 1
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index db80203b68e0..3976412685f8 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -89,6 +89,14 @@
# define CPU_NAME cpu_arm922
# endif
# endif
+# ifdef CONFIG_CPU_FA526
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_fa526
+# endif
+# endif
# ifdef CONFIG_CPU_ARM925T
# ifdef CPU_NAME
# undef MULTI_CPU
@@ -185,6 +193,14 @@
# define CPU_NAME cpu_xsc3
# endif
# endif
+# ifdef CONFIG_CPU_MOHAWK
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_mohawk
+# endif
+# endif
# ifdef CONFIG_CPU_FEROCEON
# ifdef CPU_NAME
# undef MULTI_CPU
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 73192618f1c2..236a06b9b7ce 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -27,6 +27,8 @@
/* PTRACE_SYSCALL is 24 */
#define PTRACE_GETCRUNCHREGS 25
#define PTRACE_SETCRUNCHREGS 26
+#define PTRACE_GETVFPREGS 27
+#define PTRACE_SETVFPREGS 28
/*
* PSR bits
diff --git a/arch/arm/include/asm/sizes.h b/arch/arm/include/asm/sizes.h
index 503843db1565..c10d1aa4b487 100644
--- a/arch/arm/include/asm/sizes.h
+++ b/arch/arm/include/asm/sizes.h
@@ -43,6 +43,7 @@
#define SZ_8M 0x00800000
#define SZ_16M 0x01000000
#define SZ_32M 0x02000000
+#define SZ_48M 0x03000000
#define SZ_64M 0x04000000
#define SZ_128M 0x08000000
#define SZ_256M 0x10000000
diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h
index 6817be9573a6..537de4e0ef50 100644
--- a/arch/arm/include/asm/socket.h
+++ b/arch/arm/include/asm/socket.h
@@ -54,4 +54,7 @@
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
#endif /* _ASM_SOCKET_H */
diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h
index 2b41ebbfa7ff..c13681ac1ede 100644
--- a/arch/arm/include/asm/spinlock.h
+++ b/arch/arm/include/asm/spinlock.h
@@ -217,6 +217,9 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw)
/* read_can_lock - would read_trylock() succeed? */
#define __raw_read_can_lock(x) ((x)->lock < 0x80000000)
+#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
+#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+
#define _raw_spin_relax(lock) cpu_relax()
#define _raw_read_relax(lock) cpu_relax()
#define _raw_write_relax(lock) cpu_relax()
diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h
new file mode 100644
index 000000000000..4d0a16441b29
--- /dev/null
+++ b/arch/arm/include/asm/stacktrace.h
@@ -0,0 +1,15 @@
+#ifndef __ASM_STACKTRACE_H
+#define __ASM_STACKTRACE_H
+
+struct stackframe {
+ unsigned long fp;
+ unsigned long sp;
+ unsigned long lr;
+ unsigned long pc;
+};
+
+extern int unwind_frame(struct stackframe *frame);
+extern void walk_stackframe(struct stackframe *frame,
+ int (*fn)(struct stackframe *, void *), void *data);
+
+#endif /* __ASM_STACKTRACE_H */
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 811be55f338e..bd4dc8ed53d5 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -97,8 +97,8 @@ extern void __show_regs(struct pt_regs *);
extern int cpu_architecture(void);
extern void cpu_init(void);
-void arm_machine_restart(char mode);
-extern void (*arm_pm_restart)(char str);
+void arm_machine_restart(char mode, const char *cmd);
+extern void (*arm_pm_restart)(char str, const char *cmd);
#define UDBG_UNDEFINED (1 << 0)
#define UDBG_SYSCALL (1 << 1)
@@ -125,6 +125,12 @@ extern unsigned int user_debug;
: : "r" (0) : "memory")
#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
: : "r" (0) : "memory")
+#elif defined(CONFIG_CPU_FA526)
+#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
+ : : "r" (0) : "memory")
+#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+ : : "r" (0) : "memory")
+#define dmb() __asm__ __volatile__ ("" : : : "memory")
#else
#define isb() __asm__ __volatile__ ("" : : : "memory")
#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 68b9ec82a37f..4f8848260ee2 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -99,6 +99,8 @@ static inline struct thread_info *current_thread_info(void)
#define thread_saved_pc(tsk) \
((unsigned long)(task_thread_info(tsk)->cpu_context.pc))
+#define thread_saved_sp(tsk) \
+ ((unsigned long)(task_thread_info(tsk)->cpu_context.sp))
#define thread_saved_fp(tsk) \
((unsigned long)(task_thread_info(tsk)->cpu_context.fp))
@@ -113,6 +115,8 @@ extern void iwmmxt_task_restore(struct thread_info *, void *);
extern void iwmmxt_task_release(struct thread_info *);
extern void iwmmxt_task_switch(struct thread_info *);
+extern void vfp_sync_state(struct thread_info *thread);
+
#endif
/*
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index b543a054a17e..a62218013c78 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -39,6 +39,7 @@
#define TLB_V6_D_ASID (1 << 17)
#define TLB_V6_I_ASID (1 << 18)
+#define TLB_BTB (1 << 28)
#define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */
#define TLB_DCLEAN (1 << 30)
#define TLB_WB (1 << 31)
@@ -53,6 +54,7 @@
* v4wb - ARMv4 with write buffer without I TLB flush entry instruction
* v4wbi - ARMv4 with write buffer with I TLB flush entry instruction
* fr - Feroceon (v4wbi with non-outer-cacheable page table walks)
+ * fa - Faraday (v4 with write buffer with UTLB and branch target buffer (BTB))
* v6wbi - ARMv6 with write buffer with I TLB flush entry instruction
* v7wbi - identical to v6wbi
*/
@@ -89,6 +91,22 @@
# define v4_always_flags (-1UL)
#endif
+#define fa_tlb_flags (TLB_WB | TLB_BTB | TLB_DCLEAN | \
+ TLB_V4_U_FULL | TLB_V4_U_PAGE)
+
+#ifdef CONFIG_CPU_TLB_FA
+# define fa_possible_flags fa_tlb_flags
+# define fa_always_flags fa_tlb_flags
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB fa
+# endif
+#else
+# define fa_possible_flags 0
+# define fa_always_flags (-1UL)
+#endif
+
#define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \
TLB_V4_I_FULL | TLB_V4_D_FULL | \
TLB_V4_I_PAGE | TLB_V4_D_PAGE)
@@ -140,7 +158,7 @@
# define v4wb_always_flags (-1UL)
#endif
-#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \
+#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
TLB_V6_I_FULL | TLB_V6_D_FULL | \
TLB_V6_I_PAGE | TLB_V6_D_PAGE | \
TLB_V6_I_ASID | TLB_V6_D_ASID)
@@ -267,6 +285,7 @@ extern struct cpu_tlb_fns cpu_tlb;
v4wbi_possible_flags | \
fr_possible_flags | \
v4wb_possible_flags | \
+ fa_possible_flags | \
v6wbi_possible_flags | \
v7wbi_possible_flags)
@@ -275,6 +294,7 @@ extern struct cpu_tlb_fns cpu_tlb;
v4wbi_always_flags & \
fr_always_flags & \
v4wb_always_flags & \
+ fa_always_flags & \
v6wbi_always_flags & \
v7wbi_always_flags)
@@ -297,9 +317,7 @@ static inline void local_flush_tlb_all(void)
if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
- if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
- TLB_V6_I_PAGE | TLB_V6_D_PAGE |
- TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+ if (tlb_flag(TLB_BTB)) {
/* flush the branch target cache */
asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
dsb();
@@ -334,9 +352,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
if (tlb_flag(TLB_V6_I_ASID))
asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
- if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
- TLB_V6_I_PAGE | TLB_V6_D_PAGE |
- TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+ if (tlb_flag(TLB_BTB)) {
/* flush the branch target cache */
asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
dsb();
@@ -374,9 +390,7 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
if (tlb_flag(TLB_V6_I_PAGE))
asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
- if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
- TLB_V6_I_PAGE | TLB_V6_D_PAGE |
- TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+ if (tlb_flag(TLB_BTB)) {
/* flush the branch target cache */
asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
dsb();
@@ -411,9 +425,7 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
if (tlb_flag(TLB_V6_I_PAGE))
asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
- if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
- TLB_V6_I_PAGE | TLB_V6_D_PAGE |
- TLB_V6_I_ASID | TLB_V6_D_ASID)) {
+ if (tlb_flag(TLB_BTB)) {
/* flush the branch target cache */
asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
dsb();
diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h
index aa399aec568e..491960bf4260 100644
--- a/arch/arm/include/asm/traps.h
+++ b/arch/arm/include/asm/traps.h
@@ -25,5 +25,6 @@ static inline int in_exception_text(unsigned long ptr)
}
extern void __init early_trap_init(void);
+extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
#endif
diff --git a/arch/arm/include/asm/unwind.h b/arch/arm/include/asm/unwind.h
new file mode 100644
index 000000000000..a5edf421005c
--- /dev/null
+++ b/arch/arm/include/asm/unwind.h
@@ -0,0 +1,69 @@
+/*
+ * arch/arm/include/asm/unwind.h
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_UNWIND_H
+#define __ASM_UNWIND_H
+
+#ifndef __ASSEMBLY__
+
+/* Unwind reason code according the the ARM EABI documents */
+enum unwind_reason_code {
+ URC_OK = 0, /* operation completed successfully */
+ URC_CONTINUE_UNWIND = 8,
+ URC_FAILURE = 9 /* unspecified failure of some kind */
+};
+
+struct unwind_idx {
+ unsigned long addr;
+ unsigned long insn;
+};
+
+struct unwind_table {
+ struct list_head list;
+ struct unwind_idx *start;
+ struct unwind_idx *stop;
+ unsigned long begin_addr;
+ unsigned long end_addr;
+};
+
+extern struct unwind_table *unwind_table_add(unsigned long start,
+ unsigned long size,
+ unsigned long text_addr,
+ unsigned long text_size);
+extern void unwind_table_del(struct unwind_table *tab);
+extern void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk);
+
+#ifdef CONFIG_ARM_UNWIND
+extern int __init unwind_init(void);
+#else
+static inline int __init unwind_init(void)
+{
+ return 0;
+}
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
+#ifdef CONFIG_ARM_UNWIND
+#define UNWIND(code...) code
+#else
+#define UNWIND(code...)
+#endif
+
+#endif /* __ASM_UNWIND_H */
diff --git a/arch/arm/include/asm/user.h b/arch/arm/include/asm/user.h
index 825c1e7c582d..df95e050f9dd 100644
--- a/arch/arm/include/asm/user.h
+++ b/arch/arm/include/asm/user.h
@@ -81,4 +81,13 @@ struct user{
#define HOST_TEXT_START_ADDR (u.start_code)
#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+/*
+ * User specific VFP registers. If only VFPv2 is present, registers 16 to 31
+ * are ignored by the ptrace system call.
+ */
+struct user_vfp {
+ unsigned long long fpregs[32];
+ unsigned long fpscr;
+};
+
#endif /* _ARM_USER_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 4305345987d3..11a5197a221f 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -29,12 +29,14 @@ obj-$(CONFIG_ATAGS_PROC) += atags.o
obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
obj-$(CONFIG_KGDB) += kgdb.o
+obj-$(CONFIG_ARM_UNWIND) += unwind.o
obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o
obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
+obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o
obj-$(CONFIG_IWMMXT) += iwmmxt.o
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index f53c58290543..b121b6053cce 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -49,6 +49,33 @@
1002:
.endm
+#elif defined(CONFIG_CPU_XSCALE)
+
+ .macro addruart, rx
+ .endm
+
+ .macro senduart, rd, rx
+ mcr p14, 0, \rd, c8, c0, 0
+ .endm
+
+ .macro busyuart, rd, rx
+1001:
+ mrc p14, 0, \rx, c14, c0, 0
+ tst \rx, #0x10000000
+ beq 1001b
+ .endm
+
+ .macro waituart, rd, rx
+ mov \rd, #0x10000000
+1001:
+ subs \rd, \rd, #1
+ bmi 1002f
+ mrc p14, 0, \rx, c14, c0, 0
+ tst \rx, #0x10000000
+ bne 1001b
+1002:
+ .endm
+
#else
.macro addruart, rx
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
index 4a3a50495c60..0e88e46fc732 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -24,11 +24,6 @@
#include <asm/dma.h>
#include <asm/mach/dma.h>
-#define ISA_DMA_MODE_READ 0x44
-#define ISA_DMA_MODE_WRITE 0x48
-#define ISA_DMA_MODE_CASCADE 0xc0
-#define ISA_DMA_AUTOINIT 0x10
-
#define ISA_DMA_MASK 0
#define ISA_DMA_MODE 1
#define ISA_DMA_CLRFF 2
@@ -49,38 +44,35 @@ static unsigned int isa_dma_port[8][7] = {
{ 0xd4, 0xd6, 0xd8, 0x48a, 0x08a, 0xcc, 0xce }
};
-static int isa_get_dma_residue(dmach_t channel, dma_t *dma)
+static int isa_get_dma_residue(unsigned int chan, dma_t *dma)
{
- unsigned int io_port = isa_dma_port[channel][ISA_DMA_COUNT];
+ unsigned int io_port = isa_dma_port[chan][ISA_DMA_COUNT];
int count;
count = 1 + inb(io_port);
count |= inb(io_port) << 8;
- return channel < 4 ? count : (count << 1);
+ return chan < 4 ? count : (count << 1);
}
-static void isa_enable_dma(dmach_t channel, dma_t *dma)
+static void isa_enable_dma(unsigned int chan, dma_t *dma)
{
if (dma->invalid) {
unsigned long address, length;
unsigned int mode;
enum dma_data_direction direction;
- mode = channel & 3;
+ mode = (chan & 3) | dma->dma_mode;
switch (dma->dma_mode & DMA_MODE_MASK) {
case DMA_MODE_READ:
- mode |= ISA_DMA_MODE_READ;
direction = DMA_FROM_DEVICE;
break;
case DMA_MODE_WRITE:
- mode |= ISA_DMA_MODE_WRITE;
direction = DMA_TO_DEVICE;
break;
case DMA_MODE_CASCADE:
- mode |= ISA_DMA_MODE_CASCADE;
direction = DMA_BIDIRECTIONAL;
break;
@@ -105,34 +97,31 @@ static void isa_enable_dma(dmach_t channel, dma_t *dma)
address = dma->buf.dma_address;
length = dma->buf.length - 1;
- outb(address >> 16, isa_dma_port[channel][ISA_DMA_PGLO]);
- outb(address >> 24, isa_dma_port[channel][ISA_DMA_PGHI]);
+ outb(address >> 16, isa_dma_port[chan][ISA_DMA_PGLO]);
+ outb(address >> 24, isa_dma_port[chan][ISA_DMA_PGHI]);
- if (channel >= 4) {
+ if (chan >= 4) {
address >>= 1;
length >>= 1;
}
- outb(0, isa_dma_port[channel][ISA_DMA_CLRFF]);
-
- outb(address, isa_dma_port[channel][ISA_DMA_ADDR]);
- outb(address >> 8, isa_dma_port[channel][ISA_DMA_ADDR]);
+ outb(0, isa_dma_port[chan][ISA_DMA_CLRFF]);
- outb(length, isa_dma_port[channel][ISA_DMA_COUNT]);
- outb(length >> 8, isa_dma_port[channel][ISA_DMA_COUNT]);
+ outb(address, isa_dma_port[chan][ISA_DMA_ADDR]);
+ outb(address >> 8, isa_dma_port[chan][ISA_DMA_ADDR]);
- if (dma->dma_mode & DMA_AUTOINIT)
- mode |= ISA_DMA_AUTOINIT;
+ outb(length, isa_dma_port[chan][ISA_DMA_COUNT]);
+ outb(length >> 8, isa_dma_port[chan][ISA_DMA_COUNT]);
- outb(mode, isa_dma_port[channel][ISA_DMA_MODE]);
+ outb(mode, isa_dma_port[chan][ISA_DMA_MODE]);
dma->invalid = 0;
}
- outb(channel & 3, isa_dma_port[channel][ISA_DMA_MASK]);
+ outb(chan & 3, isa_dma_port[chan][ISA_DMA_MASK]);
}
-static void isa_disable_dma(dmach_t channel, dma_t *dma)
+static void isa_disable_dma(unsigned int chan, dma_t *dma)
{
- outb(channel | 4, isa_dma_port[channel][ISA_DMA_MASK]);
+ outb(chan | 4, isa_dma_port[chan][ISA_DMA_MASK]);
}
static struct dma_ops isa_dma_ops = {
@@ -160,7 +149,12 @@ static struct resource dma_resources[] = { {
.end = 0x048f
} };
-void __init isa_init_dma(dma_t *dma)
+static dma_t isa_dma[8];
+
+/*
+ * ISA DMA always starts at channel 0
+ */
+void __init isa_init_dma(void)
{
/*
* Try to autodetect presence of an ISA DMA controller.
@@ -178,11 +172,11 @@ void __init isa_init_dma(dma_t *dma)
outb(0xaa, 0x00);
if (inb(0) == 0x55 && inb(0) == 0xaa) {
- int channel, i;
+ unsigned int chan, i;
- for (channel = 0; channel < 8; channel++) {
- dma[channel].d_ops = &isa_dma_ops;
- isa_disable_dma(channel, NULL);
+ for (chan = 0; chan < 8; chan++) {
+ isa_dma[chan].d_ops = &isa_dma_ops;
+ isa_disable_dma(chan, NULL);
}
outb(0x40, 0x0b);
@@ -217,5 +211,12 @@ void __init isa_init_dma(dma_t *dma)
for (i = 0; i < ARRAY_SIZE(dma_resources); i++)
request_resource(&ioport_resource, dma_resources + i);
+
+ for (chan = 0; chan < 8; chan++) {
+ int ret = isa_dma_add(chan, &isa_dma[chan]);
+ if (ret)
+ printk(KERN_ERR "ISADMA%u: unable to register: %d\n",
+ chan, ret);
+ }
}
}
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
index d006085ed7e7..7d5b9fb01e71 100644
--- a/arch/arm/kernel/dma.c
+++ b/arch/arm/kernel/dma.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
+#include <linux/scatterlist.h>
#include <asm/dma.h>
@@ -23,19 +24,40 @@
DEFINE_SPINLOCK(dma_spin_lock);
EXPORT_SYMBOL(dma_spin_lock);
-static dma_t dma_chan[MAX_DMA_CHANNELS];
+static dma_t *dma_chan[MAX_DMA_CHANNELS];
+
+static inline dma_t *dma_channel(unsigned int chan)
+{
+ if (chan >= MAX_DMA_CHANNELS)
+ return NULL;
+
+ return dma_chan[chan];
+}
+
+int __init isa_dma_add(unsigned int chan, dma_t *dma)
+{
+ if (!dma->d_ops)
+ return -EINVAL;
+
+ sg_init_table(&dma->buf, 1);
+
+ if (dma_chan[chan])
+ return -EBUSY;
+ dma_chan[chan] = dma;
+ return 0;
+}
/*
* Request DMA channel
*
* On certain platforms, we have to allocate an interrupt as well...
*/
-int request_dma(dmach_t channel, const char *device_id)
+int request_dma(unsigned int chan, const char *device_id)
{
- dma_t *dma = dma_chan + channel;
+ dma_t *dma = dma_channel(chan);
int ret;
- if (channel >= MAX_DMA_CHANNELS || !dma->d_ops)
+ if (!dma)
goto bad_dma;
if (xchg(&dma->lock, 1) != 0)
@@ -47,7 +69,7 @@ int request_dma(dmach_t channel, const char *device_id)
ret = 0;
if (dma->d_ops->request)
- ret = dma->d_ops->request(channel, dma);
+ ret = dma->d_ops->request(chan, dma);
if (ret)
xchg(&dma->lock, 0);
@@ -55,7 +77,7 @@ int request_dma(dmach_t channel, const char *device_id)
return ret;
bad_dma:
- printk(KERN_ERR "dma: trying to allocate DMA%d\n", channel);
+ printk(KERN_ERR "dma: trying to allocate DMA%d\n", chan);
return -EINVAL;
busy:
@@ -68,42 +90,42 @@ EXPORT_SYMBOL(request_dma);
*
* On certain platforms, we have to free interrupt as well...
*/
-void free_dma(dmach_t channel)
+void free_dma(unsigned int chan)
{
- dma_t *dma = dma_chan + channel;
+ dma_t *dma = dma_channel(chan);
- if (channel >= MAX_DMA_CHANNELS || !dma->d_ops)
+ if (!dma)
goto bad_dma;
if (dma->active) {
- printk(KERN_ERR "dma%d: freeing active DMA\n", channel);
- dma->d_ops->disable(channel, dma);
+ printk(KERN_ERR "dma%d: freeing active DMA\n", chan);
+ dma->d_ops->disable(chan, dma);
dma->active = 0;
}
if (xchg(&dma->lock, 0) != 0) {
if (dma->d_ops->free)
- dma->d_ops->free(channel, dma);
+ dma->d_ops->free(chan, dma);
return;
}
- printk(KERN_ERR "dma%d: trying to free free DMA\n", channel);
+ printk(KERN_ERR "dma%d: trying to free free DMA\n", chan);
return;
bad_dma:
- printk(KERN_ERR "dma: trying to free DMA%d\n", channel);
+ printk(KERN_ERR "dma: trying to free DMA%d\n", chan);
}
EXPORT_SYMBOL(free_dma);
/* Set DMA Scatter-Gather list
*/
-void set_dma_sg (dmach_t channel, struct scatterlist *sg, int nr_sg)
+void set_dma_sg (unsigned int chan, struct scatterlist *sg, int nr_sg)
{
- dma_t *dma = dma_chan + channel;
+ dma_t *dma = dma_channel(chan);
if (dma->active)
printk(KERN_ERR "dma%d: altering DMA SG while "
- "DMA active\n", channel);
+ "DMA active\n", chan);
dma->sg = sg;
dma->sgcount = nr_sg;
@@ -115,13 +137,13 @@ EXPORT_SYMBOL(set_dma_sg);
*
* Copy address to the structure, and set the invalid bit
*/
-void __set_dma_addr (dmach_t channel, void *addr)
+void __set_dma_addr (unsigned int chan, void *addr)
{
- dma_t *dma = dma_chan + channel;
+ dma_t *dma = dma_channel(chan);
if (dma->active)
printk(KERN_ERR "dma%d: altering DMA address while "
- "DMA active\n", channel);
+ "DMA active\n", chan);
dma->sg = NULL;
dma->addr = addr;
@@ -133,13 +155,13 @@ EXPORT_SYMBOL(__set_dma_addr);
*
* Copy address to the structure, and set the invalid bit
*/
-void set_dma_count (dmach_t channel, unsigned long count)
+void set_dma_count (unsigned int chan, unsigned long count)
{
- dma_t *dma = dma_chan + channel;
+ dma_t *dma = dma_channel(chan);
if (dma->active)
printk(KERN_ERR "dma%d: altering DMA count while "
- "DMA active\n", channel);
+ "DMA active\n", chan);
dma->sg = NULL;
dma->count = count;
@@ -149,13 +171,13 @@ EXPORT_SYMBOL(set_dma_count);
/* Set DMA direction mode
*/
-void set_dma_mode (dmach_t channel, dmamode_t mode)
+void set_dma_mode (unsigned int chan, unsigned int mode)
{
- dma_t *dma = dma_chan + channel;
+ dma_t *dma = dma_channel(chan);
if (dma->active)
printk(KERN_ERR "dma%d: altering DMA mode while "
- "DMA active\n", channel);
+ "DMA active\n", chan);
dma->dma_mode = mode;
dma->invalid = 1;
@@ -164,42 +186,42 @@ EXPORT_SYMBOL(set_dma_mode);
/* Enable DMA channel
*/
-void enable_dma (dmach_t channel)
+void enable_dma (unsigned int chan)
{
- dma_t *dma = dma_chan + channel;
+ dma_t *dma = dma_channel(chan);
if (!dma->lock)
goto free_dma;
if (dma->active == 0) {
dma->active = 1;
- dma->d_ops->enable(channel, dma);
+ dma->d_ops->enable(chan, dma);
}
return;
free_dma:
- printk(KERN_ERR "dma%d: trying to enable free DMA\n", channel);
+ printk(KERN_ERR "dma%d: trying to enable free DMA\n", chan);
BUG();
}
EXPORT_SYMBOL(enable_dma);
/* Disable DMA channel
*/
-void disable_dma (dmach_t channel)
+void disable_dma (unsigned int chan)
{
- dma_t *dma = dma_chan + channel;
+ dma_t *dma = dma_channel(chan);
if (!dma->lock)
goto free_dma;
if (dma->active == 1) {
dma->active = 0;
- dma->d_ops->disable(channel, dma);
+ dma->d_ops->disable(chan, dma);
}
return;
free_dma:
- printk(KERN_ERR "dma%d: trying to disable free DMA\n", channel);
+ printk(KERN_ERR "dma%d: trying to disable free DMA\n", chan);
BUG();
}
EXPORT_SYMBOL(disable_dma);
@@ -207,45 +229,38 @@ EXPORT_SYMBOL(disable_dma);
/*
* Is the specified DMA channel active?
*/
-int dma_channel_active(dmach_t channel)
+int dma_channel_active(unsigned int chan)
{
- return dma_chan[channel].active;
+ dma_t *dma = dma_channel(chan);
+ return dma->active;
}
EXPORT_SYMBOL(dma_channel_active);
-void set_dma_page(dmach_t channel, char pagenr)
+void set_dma_page(unsigned int chan, char pagenr)
{
- printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel);
+ printk(KERN_ERR "dma%d: trying to set_dma_page\n", chan);
}
EXPORT_SYMBOL(set_dma_page);
-void set_dma_speed(dmach_t channel, int cycle_ns)
+void set_dma_speed(unsigned int chan, int cycle_ns)
{
- dma_t *dma = dma_chan + channel;
+ dma_t *dma = dma_channel(chan);
int ret = 0;
if (dma->d_ops->setspeed)
- ret = dma->d_ops->setspeed(channel, dma, cycle_ns);
+ ret = dma->d_ops->setspeed(chan, dma, cycle_ns);
dma->speed = ret;
}
EXPORT_SYMBOL(set_dma_speed);
-int get_dma_residue(dmach_t channel)
+int get_dma_residue(unsigned int chan)
{
- dma_t *dma = dma_chan + channel;
+ dma_t *dma = dma_channel(chan);
int ret = 0;
if (dma->d_ops->residue)
- ret = dma->d_ops->residue(channel, dma);
+ ret = dma->d_ops->residue(chan, dma);
return ret;
}
EXPORT_SYMBOL(get_dma_residue);
-
-static int __init init_dma(void)
-{
- arch_dma_init(dma_chan);
- return 0;
-}
-
-core_initcall(init_dma);
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 85040cfeb5e5..d662a2f1fd85 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -20,6 +20,7 @@
#include <asm/vfpmacros.h>
#include <mach/entry-macro.S>
#include <asm/thread_notify.h>
+#include <asm/unwind.h>
#include "entry-header.S"
@@ -123,6 +124,8 @@ ENDPROC(__und_invalid)
#endif
.macro svc_entry, stack_hole=0
+ UNWIND(.fnstart )
+ UNWIND(.save {r0 - pc} )
sub sp, sp, #(S_FRAME_SIZE + \stack_hole)
SPFIX( tst sp, #4 )
SPFIX( bicne sp, sp, #4 )
@@ -196,6 +199,7 @@ __dabt_svc:
ldr r0, [sp, #S_PSR]
msr spsr_cxsf, r0
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
+ UNWIND(.fnend )
ENDPROC(__dabt_svc)
.align 5
@@ -228,6 +232,7 @@ __irq_svc:
bleq trace_hardirqs_on
#endif
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
+ UNWIND(.fnend )
ENDPROC(__irq_svc)
.ltorg
@@ -278,6 +283,7 @@ __und_svc:
ldr lr, [sp, #S_PSR] @ Get SVC cpsr
msr spsr_cxsf, lr
ldmia sp, {r0 - pc}^ @ Restore SVC registers
+ UNWIND(.fnend )
ENDPROC(__und_svc)
.align 5
@@ -320,6 +326,7 @@ __pabt_svc:
ldr r0, [sp, #S_PSR]
msr spsr_cxsf, r0
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
+ UNWIND(.fnend )
ENDPROC(__pabt_svc)
.align 5
@@ -343,6 +350,8 @@ ENDPROC(__pabt_svc)
#endif
.macro usr_entry
+ UNWIND(.fnstart )
+ UNWIND(.cantunwind ) @ don't unwind the user space
sub sp, sp, #S_FRAME_SIZE
stmib sp, {r1 - r12}
@@ -420,6 +429,7 @@ __dabt_usr:
mov r2, sp
adr lr, ret_from_exception
b do_DataAbort
+ UNWIND(.fnend )
ENDPROC(__dabt_usr)
.align 5
@@ -450,6 +460,7 @@ __irq_usr:
mov why, #0
b ret_to_user
+ UNWIND(.fnend )
ENDPROC(__irq_usr)
.ltorg
@@ -484,6 +495,7 @@ __und_usr:
#else
b __und_usr_unknown
#endif
+ UNWIND(.fnend )
ENDPROC(__und_usr)
@
@@ -671,14 +683,18 @@ __pabt_usr:
enable_irq @ Enable interrupts
mov r1, sp @ regs
bl do_PrefetchAbort @ call abort handler
+ UNWIND(.fnend )
/* fall through */
/*
* This is the return code to user mode for abort handlers
*/
ENTRY(ret_from_exception)
+ UNWIND(.fnstart )
+ UNWIND(.cantunwind )
get_thread_info tsk
mov why, #0
b ret_to_user
+ UNWIND(.fnend )
ENDPROC(__pabt_usr)
ENDPROC(ret_from_exception)
@@ -688,6 +704,8 @@ ENDPROC(ret_from_exception)
* previous and next are guaranteed not to be the same.
*/
ENTRY(__switch_to)
+ UNWIND(.fnstart )
+ UNWIND(.cantunwind )
add ip, r1, #TI_CPU_SAVE
ldr r3, [r2, #TI_TP_VALUE]
stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack
@@ -717,6 +735,7 @@ ENTRY(__switch_to)
bl atomic_notifier_call_chain
mov r0, r5
ldmia r4, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
+ UNWIND(.fnend )
ENDPROC(__switch_to)
__INIT
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 159d0416f270..b55cb0331809 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -11,6 +11,7 @@
#include <asm/unistd.h>
#include <asm/ftrace.h>
#include <mach/entry-macro.S>
+#include <asm/unwind.h>
#include "entry-header.S"
@@ -22,6 +23,8 @@
* stack.
*/
ret_fast_syscall:
+ UNWIND(.fnstart )
+ UNWIND(.cantunwind )
disable_irq @ disable interrupts
ldr r1, [tsk, #TI_FLAGS]
tst r1, #_TIF_WORK_MASK
@@ -38,6 +41,7 @@ ret_fast_syscall:
mov r0, r0
add sp, sp, #S_FRAME_SIZE - S_PC
movs pc, lr @ return & move spsr_svc into cpsr
+ UNWIND(.fnend )
/*
* Ok, we need to do extra processing, enter the slow path.
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 45eacb5a2ecd..6874c7dca75a 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -76,7 +76,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%3d: ", i);
for_each_present_cpu(cpu)
- seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
seq_printf(p, " %s", action->name);
for (action = action->next; action; action = action->next)
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index dab48f27263f..d1731e39b496 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -22,6 +22,7 @@
#include <asm/pgtable.h>
#include <asm/sections.h>
+#include <asm/unwind.h>
#ifdef CONFIG_XIP_KERNEL
/*
@@ -66,6 +67,24 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
char *secstrings,
struct module *mod)
{
+#ifdef CONFIG_ARM_UNWIND
+ Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
+
+ for (s = sechdrs; s < sechdrs_end; s++) {
+ if (strcmp(".ARM.exidx.init.text", secstrings + s->sh_name) == 0)
+ mod->arch.unw_sec_init = s;
+ else if (strcmp(".ARM.exidx.devinit.text", secstrings + s->sh_name) == 0)
+ mod->arch.unw_sec_devinit = s;
+ else if (strcmp(".ARM.exidx", secstrings + s->sh_name) == 0)
+ mod->arch.unw_sec_core = s;
+ else if (strcmp(".init.text", secstrings + s->sh_name) == 0)
+ mod->arch.sec_init_text = s;
+ else if (strcmp(".devinit.text", secstrings + s->sh_name) == 0)
+ mod->arch.sec_devinit_text = s;
+ else if (strcmp(".text", secstrings + s->sh_name) == 0)
+ mod->arch.sec_core_text = s;
+ }
+#endif
return 0;
}
@@ -104,6 +123,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
loc = dstsec->sh_addr + rel->r_offset;
switch (ELF32_R_TYPE(rel->r_info)) {
+ case R_ARM_NONE:
+ /* ignore */
+ break;
+
case R_ARM_ABS32:
*(u32 *)loc += sym->st_value;
break;
@@ -132,6 +155,20 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
*(u32 *)loc |= offset & 0x00ffffff;
break;
+ case R_ARM_V4BX:
+ /* Preserve Rm and the condition code. Alter
+ * other bits to re-code instruction as
+ * MOV PC,Rm.
+ */
+ *(u32 *)loc &= 0xf000000f;
+ *(u32 *)loc |= 0x01a0f000;
+ break;
+
+ case R_ARM_PREL31:
+ offset = *(u32 *)loc + sym->st_value - loc;
+ *(u32 *)loc = offset & 0x7fffffff;
+ break;
+
default:
printk(KERN_ERR "%s: unknown relocation: %u\n",
module->name, ELF32_R_TYPE(rel->r_info));
@@ -150,14 +187,50 @@ apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
return -ENOEXEC;
}
+#ifdef CONFIG_ARM_UNWIND
+static void register_unwind_tables(struct module *mod)
+{
+ if (mod->arch.unw_sec_init && mod->arch.sec_init_text)
+ mod->arch.unwind_init =
+ unwind_table_add(mod->arch.unw_sec_init->sh_addr,
+ mod->arch.unw_sec_init->sh_size,
+ mod->arch.sec_init_text->sh_addr,
+ mod->arch.sec_init_text->sh_size);
+ if (mod->arch.unw_sec_devinit && mod->arch.sec_devinit_text)
+ mod->arch.unwind_devinit =
+ unwind_table_add(mod->arch.unw_sec_devinit->sh_addr,
+ mod->arch.unw_sec_devinit->sh_size,
+ mod->arch.sec_devinit_text->sh_addr,
+ mod->arch.sec_devinit_text->sh_size);
+ if (mod->arch.unw_sec_core && mod->arch.sec_core_text)
+ mod->arch.unwind_core =
+ unwind_table_add(mod->arch.unw_sec_core->sh_addr,
+ mod->arch.unw_sec_core->sh_size,
+ mod->arch.sec_core_text->sh_addr,
+ mod->arch.sec_core_text->sh_size);
+}
+
+static void unregister_unwind_tables(struct module *mod)
+{
+ unwind_table_del(mod->arch.unwind_init);
+ unwind_table_del(mod->arch.unwind_devinit);
+ unwind_table_del(mod->arch.unwind_core);
+}
+#else
+static inline void register_unwind_tables(struct module *mod) { }
+static inline void unregister_unwind_tables(struct module *mod) { }
+#endif
+
int
module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
struct module *module)
{
+ register_unwind_tables(module);
return 0;
}
void
module_arch_cleanup(struct module *mod)
{
+ unregister_unwind_tables(mod);
}
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index d3ea6fa89521..c3265a2e7cd4 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -34,6 +34,7 @@
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/thread_notify.h>
+#include <asm/stacktrace.h>
#include <asm/mach/time.h>
static const char *processor_modes[] = {
@@ -82,7 +83,7 @@ static int __init hlt_setup(char *__unused)
__setup("nohlt", nohlt_setup);
__setup("hlt", hlt_setup);
-void arm_machine_restart(char mode)
+void arm_machine_restart(char mode, const char *cmd)
{
/*
* Clean and disable cache, and turn off interrupts
@@ -99,7 +100,7 @@ void arm_machine_restart(char mode)
/*
* Now call the architecture specific reboot code.
*/
- arch_reset(mode);
+ arch_reset(mode, cmd);
/*
* Whoops - the architecture was unable to reboot.
@@ -119,7 +120,7 @@ EXPORT_SYMBOL(pm_idle);
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
-void (*arm_pm_restart)(char str) = arm_machine_restart;
+void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart;
EXPORT_SYMBOL_GPL(arm_pm_restart);
@@ -194,9 +195,9 @@ void machine_power_off(void)
pm_power_off();
}
-void machine_restart(char * __unused)
+void machine_restart(char *cmd)
{
- arm_pm_restart(reboot_mode);
+ arm_pm_restart(reboot_mode, cmd);
}
void __show_regs(struct pt_regs *regs)
@@ -300,7 +301,7 @@ void release_thread(struct task_struct *dead_task)
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
int
-copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start,
+copy_thread(unsigned long clone_flags, unsigned long stack_start,
unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs)
{
struct thread_info *thread = task_thread_info(p);
@@ -372,23 +373,21 @@ EXPORT_SYMBOL(kernel_thread);
unsigned long get_wchan(struct task_struct *p)
{
- unsigned long fp, lr;
- unsigned long stack_start, stack_end;
+ struct stackframe frame;
int count = 0;
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
- stack_start = (unsigned long)end_of_stack(p);
- stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE;
-
- fp = thread_saved_fp(p);
+ frame.fp = thread_saved_fp(p);
+ frame.sp = thread_saved_sp(p);
+ frame.lr = 0; /* recovered from the stack */
+ frame.pc = thread_saved_pc(p);
do {
- if (fp < stack_start || fp > stack_end)
+ int ret = unwind_frame(&frame);
+ if (ret < 0)
return 0;
- lr = ((unsigned long *)fp)[-1];
- if (!in_sched_functions(lr))
- return lr;
- fp = *(unsigned long *) (fp - 12);
+ if (!in_sched_functions(frame.pc))
+ return frame.pc;
} while (count ++ < 16);
return 0;
}
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index df653ea59250..89882a1d0187 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -653,6 +653,54 @@ static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp)
}
#endif
+#ifdef CONFIG_VFP
+/*
+ * Get the child VFP state.
+ */
+static int ptrace_getvfpregs(struct task_struct *tsk, void __user *data)
+{
+ struct thread_info *thread = task_thread_info(tsk);
+ union vfp_state *vfp = &thread->vfpstate;
+ struct user_vfp __user *ufp = data;
+
+ vfp_sync_state(thread);
+
+ /* copy the floating point registers */
+ if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs,
+ sizeof(vfp->hard.fpregs)))
+ return -EFAULT;
+
+ /* copy the status and control register */
+ if (put_user(vfp->hard.fpscr, &ufp->fpscr))
+ return -EFAULT;
+
+ return 0;
+}
+
+/*
+ * Set the child VFP state.
+ */
+static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data)
+{
+ struct thread_info *thread = task_thread_info(tsk);
+ union vfp_state *vfp = &thread->vfpstate;
+ struct user_vfp __user *ufp = data;
+
+ vfp_sync_state(thread);
+
+ /* copy the floating point registers */
+ if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs,
+ sizeof(vfp->hard.fpregs)))
+ return -EFAULT;
+
+ /* copy the status and control register */
+ if (get_user(vfp->hard.fpscr, &ufp->fpscr))
+ return -EFAULT;
+
+ return 0;
+}
+#endif
+
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
int ret;
@@ -775,6 +823,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
#endif
+#ifdef CONFIG_VFP
+ case PTRACE_GETVFPREGS:
+ ret = ptrace_getvfpregs(child, (void __user *)data);
+ break;
+
+ case PTRACE_SETVFPREGS:
+ ret = ptrace_setvfpregs(child, (void __user *)data);
+ break;
+#endif
+
default:
ret = ptrace_request(child, request, addr, data);
break;
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 68d6494c0389..bc5e4128f9f3 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -40,6 +40,7 @@
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
#include <asm/traps.h>
+#include <asm/unwind.h>
#include "compat.h"
#include "atags.h"
@@ -685,6 +686,8 @@ void __init setup_arch(char **cmdline_p)
struct machine_desc *mdesc;
char *from = default_command_line;
+ unwind_init();
+
setup_processor();
mdesc = setup_machine(machine_arch_type);
machine_name = mdesc->name;
@@ -780,6 +783,8 @@ static const char *hwcap_str[] = {
"crunch",
"thumbee",
"neon",
+ "vfpv3",
+ "vfpv3d16",
NULL
};
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 55fa7ff96a3e..7801aac3c043 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -93,6 +93,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
pmd = pmd_offset(pgd + pgd_index(PHYS_OFFSET), PHYS_OFFSET);
*pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) |
PMD_TYPE_SECT | PMD_SECT_AP_WRITE);
+ flush_pmd_entry(pmd);
/*
* We need to tell the secondary core where to find
@@ -130,6 +131,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
secondary_data.pgdir = 0;
*pmd = __pmd(0);
+ clean_pmd_entry(pmd);
pgd_free(&init_mm, pgd);
if (ret) {
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index fc650f64df43..9f444e5cc165 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -2,35 +2,60 @@
#include <linux/sched.h>
#include <linux/stacktrace.h>
-#include "stacktrace.h"
-
-int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high,
- int (*fn)(struct stackframe *, void *), void *data)
+#include <asm/stacktrace.h>
+
+#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
+/*
+ * Unwind the current stack frame and store the new register values in the
+ * structure passed as argument. Unwinding is equivalent to a function return,
+ * hence the new PC value rather than LR should be used for backtrace.
+ *
+ * With framepointer enabled, a simple function prologue looks like this:
+ * mov ip, sp
+ * stmdb sp!, {fp, ip, lr, pc}
+ * sub fp, ip, #4
+ *
+ * A simple function epilogue looks like this:
+ * ldm sp, {fp, sp, pc}
+ *
+ * Note that with framepointer enabled, even the leaf functions have the same
+ * prologue and epilogue, therefore we can ignore the LR value in this case.
+ */
+int unwind_frame(struct stackframe *frame)
{
- struct stackframe *frame;
-
- do {
- /*
- * Check current frame pointer is within bounds
- */
- if (fp < (low + 12) || fp + 4 >= high)
- break;
+ unsigned long high, low;
+ unsigned long fp = frame->fp;
- frame = (struct stackframe *)(fp - 12);
+ /* only go to a higher address on the stack */
+ low = frame->sp;
+ high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE;
- if (fn(frame, data))
- break;
+ /* check current frame pointer is within bounds */
+ if (fp < (low + 12) || fp + 4 >= high)
+ return -EINVAL;
- /*
- * Update the low bound - the next frame must always
- * be at a higher address than the current frame.
- */
- low = fp + 4;
- fp = frame->fp;
- } while (fp);
+ /* restore the registers from the stack frame */
+ frame->fp = *(unsigned long *)(fp - 12);
+ frame->sp = *(unsigned long *)(fp - 8);
+ frame->pc = *(unsigned long *)(fp - 4);
return 0;
}
+#endif
+
+void walk_stackframe(struct stackframe *frame,
+ int (*fn)(struct stackframe *, void *), void *data)
+{
+ while (1) {
+ int ret;
+
+ if (fn(frame, data))
+ break;
+ ret = unwind_frame(frame);
+ if (ret < 0)
+ break;
+ }
+}
EXPORT_SYMBOL(walk_stackframe);
#ifdef CONFIG_STACKTRACE
@@ -44,7 +69,7 @@ static int save_trace(struct stackframe *frame, void *d)
{
struct stack_trace_data *data = d;
struct stack_trace *trace = data->trace;
- unsigned long addr = frame->lr;
+ unsigned long addr = frame->pc;
if (data->no_sched_functions && in_sched_functions(addr))
return 0;
@@ -61,11 +86,10 @@ static int save_trace(struct stackframe *frame, void *d)
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
{
struct stack_trace_data data;
- unsigned long fp, base;
+ struct stackframe frame;
data.trace = trace;
data.skip = trace->skip;
- base = (unsigned long)task_stack_page(tsk);
if (tsk != current) {
#ifdef CONFIG_SMP
@@ -76,14 +100,22 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
BUG();
#else
data.no_sched_functions = 1;
- fp = thread_saved_fp(tsk);
+ frame.fp = thread_saved_fp(tsk);
+ frame.sp = thread_saved_sp(tsk);
+ frame.lr = 0; /* recovered from the stack */
+ frame.pc = thread_saved_pc(tsk);
#endif
} else {
+ register unsigned long current_sp asm ("sp");
+
data.no_sched_functions = 0;
- asm("mov %0, fp" : "=r" (fp));
+ frame.fp = (unsigned long)__builtin_frame_address(0);
+ frame.sp = current_sp;
+ frame.lr = (unsigned long)__builtin_return_address(0);
+ frame.pc = (unsigned long)save_stack_trace_tsk;
}
- walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data);
+ walk_stackframe(&frame, save_trace, &data);
if (trace->nr_entries < trace->max_entries)
trace->entries[trace->nr_entries++] = ULONG_MAX;
}
diff --git a/arch/arm/kernel/stacktrace.h b/arch/arm/kernel/stacktrace.h
deleted file mode 100644
index e9fd20cb5662..000000000000
--- a/arch/arm/kernel/stacktrace.h
+++ /dev/null
@@ -1,9 +0,0 @@
-struct stackframe {
- unsigned long fp;
- unsigned long sp;
- unsigned long lr;
- unsigned long pc;
-};
-
-int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high,
- int (*fn)(struct stackframe *, void *), void *data);
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index c68b44aa88d2..4cdc4a0bd02d 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -33,6 +33,7 @@
#include <asm/leds.h>
#include <asm/thread_info.h>
+#include <asm/stacktrace.h>
#include <asm/mach/time.h>
/*
@@ -55,14 +56,22 @@ EXPORT_SYMBOL(rtc_lock);
#ifdef CONFIG_SMP
unsigned long profile_pc(struct pt_regs *regs)
{
- unsigned long fp, pc = instruction_pointer(regs);
+ struct stackframe frame;
- if (in_lock_functions(pc)) {
- fp = regs->ARM_fp;
- pc = ((unsigned long *)fp)[-1];
- }
+ if (!in_lock_functions(regs->ARM_pc))
+ return regs->ARM_pc;
+
+ frame.fp = regs->ARM_fp;
+ frame.sp = regs->ARM_sp;
+ frame.lr = regs->ARM_lr;
+ frame.pc = regs->ARM_pc;
+ do {
+ int ret = unwind_frame(&frame);
+ if (ret < 0)
+ return 0;
+ } while (in_lock_functions(frame.pc));
- return pc;
+ return frame.pc;
}
EXPORT_SYMBOL(profile_pc);
#endif
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 79abc4ddc0cf..57eb0f6f6005 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -27,6 +27,7 @@
#include <asm/system.h>
#include <asm/unistd.h>
#include <asm/traps.h>
+#include <asm/unwind.h>
#include "ptrace.h"
#include "signal.h"
@@ -61,6 +62,7 @@ void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long
dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
}
+#ifndef CONFIG_ARM_UNWIND
/*
* Stack pointers should always be within the kernels view of
* physical memory. If it is not there, then we can't dump
@@ -74,6 +76,7 @@ static int verify_stack(unsigned long sp)
return 0;
}
+#endif
/*
* Dump out the contents of some memory nicely...
@@ -150,13 +153,33 @@ static void dump_instr(struct pt_regs *regs)
set_fs(fs);
}
+#ifdef CONFIG_ARM_UNWIND
+static inline void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
+{
+ unwind_backtrace(regs, tsk);
+}
+#else
static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
{
- unsigned int fp;
+ unsigned int fp, mode;
int ok = 1;
printk("Backtrace: ");
- fp = regs->ARM_fp;
+
+ if (!tsk)
+ tsk = current;
+
+ if (regs) {
+ fp = regs->ARM_fp;
+ mode = processor_mode(regs);
+ } else if (tsk != current) {
+ fp = thread_saved_fp(tsk);
+ mode = 0x10;
+ } else {
+ asm("mov %0, fp" : "=r" (fp) : : "cc");
+ mode = 0x10;
+ }
+
if (!fp) {
printk("no frame pointer");
ok = 0;
@@ -168,29 +191,20 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
printk("\n");
if (ok)
- c_backtrace(fp, processor_mode(regs));
+ c_backtrace(fp, mode);
}
+#endif
void dump_stack(void)
{
- __backtrace();
+ dump_backtrace(NULL, NULL);
}
EXPORT_SYMBOL(dump_stack);
void show_stack(struct task_struct *tsk, unsigned long *sp)
{
- unsigned long fp;
-
- if (!tsk)
- tsk = current;
-
- if (tsk != current)
- fp = thread_saved_fp(tsk);
- else
- asm("mov %0, fp" : "=r" (fp) : : "cc");
-
- c_backtrace(fp, 0x10);
+ dump_backtrace(NULL, tsk);
barrier();
}
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
new file mode 100644
index 000000000000..1dedc2c7ff49
--- /dev/null
+++ b/arch/arm/kernel/unwind.c
@@ -0,0 +1,434 @@
+/*
+ * arch/arm/kernel/unwind.c
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * Stack unwinding support for ARM
+ *
+ * An ARM EABI version of gcc is required to generate the unwind
+ * tables. For information about the structure of the unwind tables,
+ * see "Exception Handling ABI for the ARM Architecture" at:
+ *
+ * http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+
+#include <asm/stacktrace.h>
+#include <asm/traps.h>
+#include <asm/unwind.h>
+
+/* Dummy functions to avoid linker complaints */
+void __aeabi_unwind_cpp_pr0(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr0);
+
+void __aeabi_unwind_cpp_pr1(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr1);
+
+void __aeabi_unwind_cpp_pr2(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr2);
+
+struct unwind_ctrl_block {
+ unsigned long vrs[16]; /* virtual register set */
+ unsigned long *insn; /* pointer to the current instructions word */
+ int entries; /* number of entries left to interpret */
+ int byte; /* current byte number in the instructions word */
+};
+
+enum regs {
+ FP = 11,
+ SP = 13,
+ LR = 14,
+ PC = 15
+};
+
+extern struct unwind_idx __start_unwind_idx[];
+extern struct unwind_idx __stop_unwind_idx[];
+
+static DEFINE_SPINLOCK(unwind_lock);
+static LIST_HEAD(unwind_tables);
+
+/* Convert a prel31 symbol to an absolute address */
+#define prel31_to_addr(ptr) \
+({ \
+ /* sign-extend to 32 bits */ \
+ long offset = (((long)*(ptr)) << 1) >> 1; \
+ (unsigned long)(ptr) + offset; \
+})
+
+/*
+ * Binary search in the unwind index. The entries entries are
+ * guaranteed to be sorted in ascending order by the linker.
+ */
+static struct unwind_idx *search_index(unsigned long addr,
+ struct unwind_idx *first,
+ struct unwind_idx *last)
+{
+ pr_debug("%s(%08lx, %p, %p)\n", __func__, addr, first, last);
+
+ if (addr < first->addr) {
+ pr_warning("unwind: Unknown symbol address %08lx\n", addr);
+ return NULL;
+ } else if (addr >= last->addr)
+ return last;
+
+ while (first < last - 1) {
+ struct unwind_idx *mid = first + ((last - first + 1) >> 1);
+
+ if (addr < mid->addr)
+ last = mid;
+ else
+ first = mid;
+ }
+
+ return first;
+}
+
+static struct unwind_idx *unwind_find_idx(unsigned long addr)
+{
+ struct unwind_idx *idx = NULL;
+ unsigned long flags;
+
+ pr_debug("%s(%08lx)\n", __func__, addr);
+
+ if (core_kernel_text(addr))
+ /* main unwind table */
+ idx = search_index(addr, __start_unwind_idx,
+ __stop_unwind_idx - 1);
+ else {
+ /* module unwind tables */
+ struct unwind_table *table;
+
+ spin_lock_irqsave(&unwind_lock, flags);
+ list_for_each_entry(table, &unwind_tables, list) {
+ if (addr >= table->begin_addr &&
+ addr < table->end_addr) {
+ idx = search_index(addr, table->start,
+ table->stop - 1);
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&unwind_lock, flags);
+ }
+
+ pr_debug("%s: idx = %p\n", __func__, idx);
+ return idx;
+}
+
+static unsigned long unwind_get_byte(struct unwind_ctrl_block *ctrl)
+{
+ unsigned long ret;
+
+ if (ctrl->entries <= 0) {
+ pr_warning("unwind: Corrupt unwind table\n");
+ return 0;
+ }
+
+ ret = (*ctrl->insn >> (ctrl->byte * 8)) & 0xff;
+
+ if (ctrl->byte == 0) {
+ ctrl->insn++;
+ ctrl->entries--;
+ ctrl->byte = 3;
+ } else
+ ctrl->byte--;
+
+ return ret;
+}
+
+/*
+ * Execute the current unwind instruction.
+ */
+static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
+{
+ unsigned long insn = unwind_get_byte(ctrl);
+
+ pr_debug("%s: insn = %08lx\n", __func__, insn);
+
+ if ((insn & 0xc0) == 0x00)
+ ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4;
+ else if ((insn & 0xc0) == 0x40)
+ ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4;
+ else if ((insn & 0xf0) == 0x80) {
+ unsigned long mask;
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int load_sp, reg = 4;
+
+ insn = (insn << 8) | unwind_get_byte(ctrl);
+ mask = insn & 0x0fff;
+ if (mask == 0) {
+ pr_warning("unwind: 'Refuse to unwind' instruction %04lx\n",
+ insn);
+ return -URC_FAILURE;
+ }
+
+ /* pop R4-R15 according to mask */
+ load_sp = mask & (1 << (13 - 4));
+ while (mask) {
+ if (mask & 1)
+ ctrl->vrs[reg] = *vsp++;
+ mask >>= 1;
+ reg++;
+ }
+ if (!load_sp)
+ ctrl->vrs[SP] = (unsigned long)vsp;
+ } else if ((insn & 0xf0) == 0x90 &&
+ (insn & 0x0d) != 0x0d)
+ ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f];
+ else if ((insn & 0xf0) == 0xa0) {
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int reg;
+
+ /* pop R4-R[4+bbb] */
+ for (reg = 4; reg <= 4 + (insn & 7); reg++)
+ ctrl->vrs[reg] = *vsp++;
+ if (insn & 0x80)
+ ctrl->vrs[14] = *vsp++;
+ ctrl->vrs[SP] = (unsigned long)vsp;
+ } else if (insn == 0xb0) {
+ ctrl->vrs[PC] = ctrl->vrs[LR];
+ /* no further processing */
+ ctrl->entries = 0;
+ } else if (insn == 0xb1) {
+ unsigned long mask = unwind_get_byte(ctrl);
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int reg = 0;
+
+ if (mask == 0 || mask & 0xf0) {
+ pr_warning("unwind: Spare encoding %04lx\n",
+ (insn << 8) | mask);
+ return -URC_FAILURE;
+ }
+
+ /* pop R0-R3 according to mask */
+ while (mask) {
+ if (mask & 1)
+ ctrl->vrs[reg] = *vsp++;
+ mask >>= 1;
+ reg++;
+ }
+ ctrl->vrs[SP] = (unsigned long)vsp;
+ } else if (insn == 0xb2) {
+ unsigned long uleb128 = unwind_get_byte(ctrl);
+
+ ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
+ } else {
+ pr_warning("unwind: Unhandled instruction %02lx\n", insn);
+ return -URC_FAILURE;
+ }
+
+ pr_debug("%s: fp = %08lx sp = %08lx lr = %08lx pc = %08lx\n", __func__,
+ ctrl->vrs[FP], ctrl->vrs[SP], ctrl->vrs[LR], ctrl->vrs[PC]);
+
+ return URC_OK;
+}
+
+/*
+ * Unwind a single frame starting with *sp for the symbol at *pc. It
+ * updates the *pc and *sp with the new values.
+ */
+int unwind_frame(struct stackframe *frame)
+{
+ unsigned long high, low;
+ struct unwind_idx *idx;
+ struct unwind_ctrl_block ctrl;
+
+ /* only go to a higher address on the stack */
+ low = frame->sp;
+ high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE;
+
+ pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
+ frame->pc, frame->lr, frame->sp);
+
+ if (!kernel_text_address(frame->pc))
+ return -URC_FAILURE;
+
+ idx = unwind_find_idx(frame->pc);
+ if (!idx) {
+ pr_warning("unwind: Index not found %08lx\n", frame->pc);
+ return -URC_FAILURE;
+ }
+
+ ctrl.vrs[FP] = frame->fp;
+ ctrl.vrs[SP] = frame->sp;
+ ctrl.vrs[LR] = frame->lr;
+ ctrl.vrs[PC] = 0;
+
+ if (idx->insn == 1)
+ /* can't unwind */
+ return -URC_FAILURE;
+ else if ((idx->insn & 0x80000000) == 0)
+ /* prel31 to the unwind table */
+ ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn);
+ else if ((idx->insn & 0xff000000) == 0x80000000)
+ /* only personality routine 0 supported in the index */
+ ctrl.insn = &idx->insn;
+ else {
+ pr_warning("unwind: Unsupported personality routine %08lx in the index at %p\n",
+ idx->insn, idx);
+ return -URC_FAILURE;
+ }
+
+ /* check the personality routine */
+ if ((*ctrl.insn & 0xff000000) == 0x80000000) {
+ ctrl.byte = 2;
+ ctrl.entries = 1;
+ } else if ((*ctrl.insn & 0xff000000) == 0x81000000) {
+ ctrl.byte = 1;
+ ctrl.entries = 1 + ((*ctrl.insn & 0x00ff0000) >> 16);
+ } else {
+ pr_warning("unwind: Unsupported personality routine %08lx at %p\n",
+ *ctrl.insn, ctrl.insn);
+ return -URC_FAILURE;
+ }
+
+ while (ctrl.entries > 0) {
+ int urc;
+
+ if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
+ return -URC_FAILURE;
+ urc = unwind_exec_insn(&ctrl);
+ if (urc < 0)
+ return urc;
+ }
+
+ if (ctrl.vrs[PC] == 0)
+ ctrl.vrs[PC] = ctrl.vrs[LR];
+
+ frame->fp = ctrl.vrs[FP];
+ frame->sp = ctrl.vrs[SP];
+ frame->lr = ctrl.vrs[LR];
+ frame->pc = ctrl.vrs[PC];
+
+ return URC_OK;
+}
+
+void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
+{
+ struct stackframe frame;
+ unsigned long high, low;
+ register unsigned long current_sp asm ("sp");
+
+ pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
+
+ if (!tsk)
+ tsk = current;
+
+ if (regs) {
+ frame.fp = regs->ARM_fp;
+ frame.sp = regs->ARM_sp;
+ frame.lr = regs->ARM_lr;
+ frame.pc = regs->ARM_pc;
+ } else if (tsk == current) {
+ frame.fp = (unsigned long)__builtin_frame_address(0);
+ frame.sp = current_sp;
+ frame.lr = (unsigned long)__builtin_return_address(0);
+ frame.pc = (unsigned long)unwind_backtrace;
+ } else {
+ /* task blocked in __switch_to */
+ frame.fp = thread_saved_fp(tsk);
+ frame.sp = thread_saved_sp(tsk);
+ /*
+ * The function calling __switch_to cannot be a leaf function
+ * so LR is recovered from the stack.
+ */
+ frame.lr = 0;
+ frame.pc = thread_saved_pc(tsk);
+ }
+
+ low = frame.sp & ~(THREAD_SIZE - 1);
+ high = low + THREAD_SIZE;
+
+ while (1) {
+ int urc;
+ unsigned long where = frame.pc;
+
+ urc = unwind_frame(&frame);
+ if (urc < 0)
+ break;
+ dump_backtrace_entry(where, frame.pc, frame.sp - 4);
+ }
+}
+
+struct unwind_table *unwind_table_add(unsigned long start, unsigned long size,
+ unsigned long text_addr,
+ unsigned long text_size)
+{
+ unsigned long flags;
+ struct unwind_idx *idx;
+ struct unwind_table *tab = kmalloc(sizeof(*tab), GFP_KERNEL);
+
+ pr_debug("%s(%08lx, %08lx, %08lx, %08lx)\n", __func__, start, size,
+ text_addr, text_size);
+
+ if (!tab)
+ return tab;
+
+ tab->start = (struct unwind_idx *)start;
+ tab->stop = (struct unwind_idx *)(start + size);
+ tab->begin_addr = text_addr;
+ tab->end_addr = text_addr + text_size;
+
+ /* Convert the symbol addresses to absolute values */
+ for (idx = tab->start; idx < tab->stop; idx++)
+ idx->addr = prel31_to_addr(&idx->addr);
+
+ spin_lock_irqsave(&unwind_lock, flags);
+ list_add_tail(&tab->list, &unwind_tables);
+ spin_unlock_irqrestore(&unwind_lock, flags);
+
+ return tab;
+}
+
+void unwind_table_del(struct unwind_table *tab)
+{
+ unsigned long flags;
+
+ if (!tab)
+ return;
+
+ spin_lock_irqsave(&unwind_lock, flags);
+ list_del(&tab->list);
+ spin_unlock_irqrestore(&unwind_lock, flags);
+
+ kfree(tab);
+}
+
+int __init unwind_init(void)
+{
+ struct unwind_idx *idx;
+
+ /* Convert the symbol addresses to absolute values */
+ for (idx = __start_unwind_idx; idx < __stop_unwind_idx; idx++)
+ idx->addr = prel31_to_addr(&idx->addr);
+
+ pr_debug("unwind: ARM stack unwinding initialised\n");
+
+ return 0;
+}
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 85598f7da407..c90f27250ead 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -64,6 +64,7 @@ SECTIONS
__initramfs_end = .;
#endif
. = ALIGN(4096);
+ __per_cpu_load = .;
__per_cpu_start = .;
*(.data.percpu.page_aligned)
*(.data.percpu)
@@ -81,6 +82,8 @@ SECTIONS
EXIT_TEXT
EXIT_DATA
*(.exitcall.exit)
+ *(.ARM.exidx.exit.text)
+ *(.ARM.extab.exit.text)
#ifndef CONFIG_MMU
*(.fixup)
*(__ex_table)
@@ -111,6 +114,23 @@ SECTIONS
_etext = .; /* End of text and rodata section */
+#ifdef CONFIG_ARM_UNWIND
+ /*
+ * Stack unwinding tables
+ */
+ . = ALIGN(8);
+ .ARM.unwind_idx : {
+ __start_unwind_idx = .;
+ *(.ARM.exidx*)
+ __stop_unwind_idx = .;
+ }
+ .ARM.unwind_tab : {
+ __start_unwind_tab = .;
+ *(.ARM.extab*)
+ __stop_unwind_tab = .;
+ }
+#endif
+
#ifdef CONFIG_XIP_KERNEL
__data_loc = ALIGN(4); /* location in binary */
. = PAGE_OFFSET + TEXT_OFFSET;
diff --git a/arch/arm/mach-aaec2000/include/mach/system.h b/arch/arm/mach-aaec2000/include/mach/system.h
index 8f4115d734ce..fe08ca1add6f 100644
--- a/arch/arm/mach-aaec2000/include/mach/system.h
+++ b/arch/arm/mach-aaec2000/include/mach/system.h
@@ -16,7 +16,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
cpu_reset(0);
}
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index 81439fe6fb3d..438efbb17482 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -238,6 +238,10 @@ static void __init ek_board_init(void)
at91_add_device_i2c(NULL, 0);
/* LEDs */
at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ /* PCK0 provides MCLK to the WM8731 */
+ at91_set_B_periph(AT91_PIN_PC1, 0);
+ /* SSC (for WM8731) */
+ at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
}
MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK")
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 7b9ce7a336b0..b5daf7f5e011 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -47,9 +47,6 @@ extern void at91_irq_resume(void);
#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */
struct at91_gpio_bank {
- unsigned chipbase; /* bank's first GPIO number */
- void __iomem *regbase; /* base of register bank */
- struct at91_gpio_bank *next; /* bank sharing same IRQ/clock/... */
unsigned short id; /* peripheral ID */
unsigned long offset; /* offset from system peripheral base */
struct clk *clock; /* associated clock */
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 2f7d4977dce9..f2236f0e101f 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -24,19 +24,59 @@
#include <mach/at91_pio.h>
#include <mach/gpio.h>
+#include <asm/gpio.h>
+
#include "generic.h"
+struct at91_gpio_chip {
+ struct gpio_chip chip;
+ struct at91_gpio_chip *next; /* Bank sharing same clock */
+ struct at91_gpio_bank *bank; /* Bank definition */
+ void __iomem *regbase; /* Base of register bank */
+};
-static struct at91_gpio_bank *gpio;
-static int gpio_banks;
+#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip)
+
+static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip);
+static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val);
+static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset);
+static int at91_gpiolib_direction_output(struct gpio_chip *chip,
+ unsigned offset, int val);
+static int at91_gpiolib_direction_input(struct gpio_chip *chip,
+ unsigned offset);
+static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset);
+
+#define AT91_GPIO_CHIP(name, base_gpio, nr_gpio) \
+ { \
+ .chip = { \
+ .label = name, \
+ .request = at91_gpiolib_request, \
+ .direction_input = at91_gpiolib_direction_input, \
+ .direction_output = at91_gpiolib_direction_output, \
+ .get = at91_gpiolib_get, \
+ .set = at91_gpiolib_set, \
+ .dbg_show = at91_gpiolib_dbg_show, \
+ .base = base_gpio, \
+ .ngpio = nr_gpio, \
+ }, \
+ }
+
+static struct at91_gpio_chip gpio_chip[] = {
+ AT91_GPIO_CHIP("A", 0x00 + PIN_BASE, 32),
+ AT91_GPIO_CHIP("B", 0x20 + PIN_BASE, 32),
+ AT91_GPIO_CHIP("C", 0x40 + PIN_BASE, 32),
+ AT91_GPIO_CHIP("D", 0x60 + PIN_BASE, 32),
+ AT91_GPIO_CHIP("E", 0x80 + PIN_BASE, 32),
+};
+static int gpio_banks;
static inline void __iomem *pin_to_controller(unsigned pin)
{
pin -= PIN_BASE;
pin /= 32;
if (likely(pin < gpio_banks))
- return gpio[pin].regbase;
+ return gpio_chip[pin].regbase;
return NULL;
}
@@ -197,39 +237,6 @@ int __init_or_module at91_set_multi_drive(unsigned pin, int is_on)
}
EXPORT_SYMBOL(at91_set_multi_drive);
-/*--------------------------------------------------------------------------*/
-
-/* new-style GPIO calls; these expect at91_set_GPIO_periph to have been
- * called, and maybe at91_set_multi_drive() for putout pins.
- */
-
-int gpio_direction_input(unsigned pin)
-{
- void __iomem *pio = pin_to_controller(pin);
- unsigned mask = pin_to_mask(pin);
-
- if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
- return -EINVAL;
- __raw_writel(mask, pio + PIO_ODR);
- return 0;
-}
-EXPORT_SYMBOL(gpio_direction_input);
-
-int gpio_direction_output(unsigned pin, int value)
-{
- void __iomem *pio = pin_to_controller(pin);
- unsigned mask = pin_to_mask(pin);
-
- if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
- return -EINVAL;
- __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
- __raw_writel(mask, pio + PIO_OER);
- return 0;
-}
-EXPORT_SYMBOL(gpio_direction_output);
-
-/*--------------------------------------------------------------------------*/
-
/*
* assuming the pin is muxed as a gpio output, set its value.
*/
@@ -282,7 +289,7 @@ static int gpio_irq_set_wake(unsigned pin, unsigned state)
else
wakeups[bank] &= ~mask;
- set_irq_wake(gpio[bank].id, state);
+ set_irq_wake(gpio_chip[bank].bank->id, state);
return 0;
}
@@ -292,14 +299,14 @@ void at91_gpio_suspend(void)
int i;
for (i = 0; i < gpio_banks; i++) {
- void __iomem *pio = gpio[i].regbase;
+ void __iomem *pio = gpio_chip[i].regbase;
backups[i] = __raw_readl(pio + PIO_IMR);
__raw_writel(backups[i], pio + PIO_IDR);
__raw_writel(wakeups[i], pio + PIO_IER);
if (!wakeups[i])
- clk_disable(gpio[i].clock);
+ clk_disable(gpio_chip[i].bank->clock);
else {
#ifdef CONFIG_PM_DEBUG
printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]);
@@ -313,10 +320,10 @@ void at91_gpio_resume(void)
int i;
for (i = 0; i < gpio_banks; i++) {
- void __iomem *pio = gpio[i].regbase;
+ void __iomem *pio = gpio_chip[i].regbase;
if (!wakeups[i])
- clk_enable(gpio[i].clock);
+ clk_enable(gpio_chip[i].bank->clock);
__raw_writel(wakeups[i], pio + PIO_IDR);
__raw_writel(backups[i], pio + PIO_IER);
@@ -380,12 +387,12 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
unsigned pin;
struct irq_desc *gpio;
- struct at91_gpio_bank *bank;
+ struct at91_gpio_chip *at91_gpio;
void __iomem *pio;
u32 isr;
- bank = get_irq_chip_data(irq);
- pio = bank->regbase;
+ at91_gpio = get_irq_chip_data(irq);
+ pio = at91_gpio->regbase;
/* temporarily mask (level sensitive) parent IRQ */
desc->chip->ack(irq);
@@ -396,14 +403,14 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
*/
isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR);
if (!isr) {
- if (!bank->next)
+ if (!at91_gpio->next)
break;
- bank = bank->next;
- pio = bank->regbase;
+ at91_gpio = at91_gpio->next;
+ pio = at91_gpio->regbase;
continue;
}
- pin = bank->chipbase;
+ pin = at91_gpio->chip.base;
gpio = &irq_desc[pin];
while (isr) {
@@ -502,17 +509,17 @@ static struct lock_class_key gpio_lock_class;
void __init at91_gpio_irq_setup(void)
{
unsigned pioc, pin;
- struct at91_gpio_bank *this, *prev;
+ struct at91_gpio_chip *this, *prev;
- for (pioc = 0, pin = PIN_BASE, this = gpio, prev = NULL;
+ for (pioc = 0, pin = PIN_BASE, this = gpio_chip, prev = NULL;
pioc++ < gpio_banks;
prev = this, this++) {
- unsigned id = this->id;
+ unsigned id = this->bank->id;
unsigned i;
__raw_writel(~0, this->regbase + PIO_IDR);
- for (i = 0, pin = this->chipbase; i < 32; i++, pin++) {
+ for (i = 0, pin = this->chip.base; i < 32; i++, pin++) {
lockdep_set_class(&irq_desc[pin].lock, &gpio_lock_class);
/*
@@ -537,32 +544,117 @@ void __init at91_gpio_irq_setup(void)
pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks);
}
+/* gpiolib support */
+static int at91_gpiolib_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+
+ __raw_writel(mask, pio + PIO_ODR);
+ return 0;
+}
+
+static int at91_gpiolib_direction_output(struct gpio_chip *chip,
+ unsigned offset, int val)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+
+ __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR));
+ __raw_writel(mask, pio + PIO_OER);
+ return 0;
+}
+
+static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+ u32 pdsr;
+
+ pdsr = __raw_readl(pio + PIO_PDSR);
+ return (pdsr & mask) != 0;
+}
+
+static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+
+ __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR));
+}
+
+static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset)
+{
+ unsigned pin = chip->base + offset;
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ /* Cannot request GPIOs that are in alternate function mode */
+ if (!(__raw_readl(pio + PIO_PSR) & mask))
+ return -EPERM;
+
+ return 0;
+}
+
+static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+ int i;
+
+ for (i = 0; i < chip->ngpio; i++) {
+ unsigned pin = chip->base + i;
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+ const char *gpio_label;
+
+ gpio_label = gpiochip_is_requested(chip, i);
+ if (gpio_label) {
+ seq_printf(s, "[%s] GPIO%s%d: ",
+ gpio_label, chip->label, i);
+ if (__raw_readl(pio + PIO_PSR) & mask)
+ seq_printf(s, "[gpio] %s\n",
+ at91_get_gpio_value(pin) ?
+ "set" : "clear");
+ else
+ seq_printf(s, "[periph %s]\n",
+ __raw_readl(pio + PIO_ABSR) &
+ mask ? "B" : "A");
+ }
+ }
+}
+
/*
* Called from the processor-specific init to enable GPIO pin support.
*/
void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
{
unsigned i;
- struct at91_gpio_bank *last;
+ struct at91_gpio_chip *at91_gpio, *last = NULL;
BUG_ON(nr_banks > MAX_GPIO_BANKS);
- gpio = data;
gpio_banks = nr_banks;
- for (i = 0, last = NULL; i < nr_banks; i++, last = data, data++) {
- data->chipbase = PIN_BASE + i * 32;
- data->regbase = data->offset + (void __iomem *)AT91_VA_BASE_SYS;
+ for (i = 0; i < nr_banks; i++) {
+ at91_gpio = &gpio_chip[i];
+
+ at91_gpio->bank = &data[i];
+ at91_gpio->chip.base = PIN_BASE + i * 32;
+ at91_gpio->regbase = at91_gpio->bank->offset +
+ (void __iomem *)AT91_VA_BASE_SYS;
/* enable PIO controller's clock */
- clk_enable(data->clock);
+ clk_enable(at91_gpio->bank->clock);
- /*
- * Some processors share peripheral ID between multiple GPIO banks.
- * SAM9263 (PIOC, PIOD, PIOE)
- * CAP9 (PIOA, PIOB, PIOC, PIOD)
- */
- if (last && last->id == data->id)
- last->next = data;
+ /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
+ if (last && last->bank->id == at91_gpio->bank->id)
+ last->next = at91_gpio;
+ last = at91_gpio;
+
+ gpiochip_add(&at91_gpio->chip);
}
}
diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h
index bffa6741a751..04c91e31c9c5 100644
--- a/arch/arm/mach-at91/include/mach/gpio.h
+++ b/arch/arm/mach-at91/include/mach/gpio.h
@@ -213,32 +213,12 @@ extern void at91_gpio_resume(void);
*/
#include <asm/errno.h>
-
-static inline int gpio_request(unsigned gpio, const char *label)
-{
- return 0;
-}
-
-static inline void gpio_free(unsigned gpio)
-{
- might_sleep();
-}
-
-extern int gpio_direction_input(unsigned gpio);
-extern int gpio_direction_output(unsigned gpio, int value);
-
-static inline int gpio_get_value(unsigned gpio)
-{
- return at91_get_gpio_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
- at91_set_gpio_value(gpio, value);
-}
-
#include <asm-generic/gpio.h> /* cansleep wrappers */
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
static inline int gpio_to_irq(unsigned gpio)
{
return gpio;
diff --git a/arch/arm/mach-at91/include/mach/system.h b/arch/arm/mach-at91/include/mach/system.h
index e712658d966c..5268af3933c2 100644
--- a/arch/arm/mach-at91/include/mach/system.h
+++ b/arch/arm/mach-at91/include/mach/system.h
@@ -43,7 +43,7 @@ static inline void arch_idle(void)
void (*at91_arch_reset)(void);
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
/* call the CPU-specific reset function */
if (at91_arch_reset)
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 7ac812dc055a..e26c4fe61fae 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -198,17 +198,17 @@ static int at91_pm_verify_clocks(void)
/* USB must not be using PLLB */
if (cpu_is_at91rm9200()) {
if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) {
- pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+ pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
return 0;
}
} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
- pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+ pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
return 0;
}
} else if (cpu_is_at91cap9()) {
if ((scsr & AT91CAP9_PMC_UHP) != 0) {
- pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n");
+ pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
return 0;
}
}
@@ -223,7 +223,7 @@ static int at91_pm_verify_clocks(void)
css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
if (css != AT91_PMC_CSS_SLOW) {
- pr_debug("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
+ pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
return 0;
}
}
diff --git a/arch/arm/mach-clps711x/include/mach/system.h b/arch/arm/mach-clps711x/include/mach/system.h
index 24e96159e3e7..f916cd7a477d 100644
--- a/arch/arm/mach-clps711x/include/mach/system.h
+++ b/arch/arm/mach-clps711x/include/mach/system.h
@@ -32,7 +32,7 @@ static inline void arch_idle(void)
mov r0, r0");
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
cpu_reset(0);
}
diff --git a/arch/arm/mach-davinci/include/mach/nand.h b/arch/arm/mach-davinci/include/mach/nand.h
new file mode 100644
index 000000000000..aa482841270b
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/nand.h
@@ -0,0 +1,80 @@
+/*
+ * mach-davinci/nand.h
+ *
+ * Copyright © 2006 Texas Instruments.
+ *
+ * Ported to 2.6.23 Copyright © 2008 by
+ * Sander Huijsen <Shuijsen@optelecom-nkf.com>
+ * Troy Kisky <troy.kisky@boundarydevices.com>
+ * Dirk Behme <Dirk.Behme@gmail.com>
+ *
+ * --------------------------------------------------------------------------
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ARCH_ARM_DAVINCI_NAND_H
+#define __ARCH_ARM_DAVINCI_NAND_H
+
+#include <linux/mtd/nand.h>
+
+#define NRCSR_OFFSET 0x00
+#define AWCCR_OFFSET 0x04
+#define A1CR_OFFSET 0x10
+#define NANDFCR_OFFSET 0x60
+#define NANDFSR_OFFSET 0x64
+#define NANDF1ECC_OFFSET 0x70
+
+/* 4-bit ECC syndrome registers */
+#define NAND_4BIT_ECC_LOAD_OFFSET 0xbc
+#define NAND_4BIT_ECC1_OFFSET 0xc0
+#define NAND_4BIT_ECC2_OFFSET 0xc4
+#define NAND_4BIT_ECC3_OFFSET 0xc8
+#define NAND_4BIT_ECC4_OFFSET 0xcc
+#define NAND_ERR_ADD1_OFFSET 0xd0
+#define NAND_ERR_ADD2_OFFSET 0xd4
+#define NAND_ERR_ERRVAL1_OFFSET 0xd8
+#define NAND_ERR_ERRVAL2_OFFSET 0xdc
+
+/* NOTE: boards don't need to use these address bits
+ * for ALE/CLE unless they support booting from NAND.
+ * They're used unless platform data overrides them.
+ */
+#define MASK_ALE 0x08
+#define MASK_CLE 0x10
+
+struct davinci_nand_pdata { /* platform_data */
+ uint32_t mask_ale;
+ uint32_t mask_cle;
+
+ /* for packages using two chipselects */
+ uint32_t mask_chipsel;
+
+ /* board's default static partition info */
+ struct mtd_partition *parts;
+ unsigned nr_parts;
+
+ /* none == NAND_ECC_NONE (strongly *not* advised!!)
+ * soft == NAND_ECC_SOFT
+ * 1-bit == NAND_ECC_HW
+ * 4-bit == NAND_ECC_HW_SYNDROME (not on all chips)
+ */
+ nand_ecc_modes_t ecc_mode;
+
+ /* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */
+ unsigned options;
+};
+
+#endif /* __ARCH_ARM_DAVINCI_NAND_H */
diff --git a/arch/arm/mach-davinci/include/mach/system.h b/arch/arm/mach-davinci/include/mach/system.h
index 17ca41dc2c53..b7e7036674fa 100644
--- a/arch/arm/mach-davinci/include/mach/system.h
+++ b/arch/arm/mach-davinci/include/mach/system.h
@@ -21,7 +21,7 @@ static void arch_idle(void)
cpu_do_idle();
}
-static void arch_reset(char mode)
+static void arch_reset(char mode, const char *cmd)
{
davinci_watchdog_reset();
}
diff --git a/arch/arm/mach-ebsa110/include/mach/system.h b/arch/arm/mach-ebsa110/include/mach/system.h
index 350a028997ef..9a26245bf1fc 100644
--- a/arch/arm/mach-ebsa110/include/mach/system.h
+++ b/arch/arm/mach-ebsa110/include/mach/system.h
@@ -34,6 +34,6 @@ static inline void arch_idle(void)
asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc");
}
-#define arch_reset(mode) cpu_reset(0x80000000)
+#define arch_reset(mode, cmd) cpu_reset(0x80000000)
#endif
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile
index 944e42d51646..9522e205b73f 100644
--- a/arch/arm/mach-ep93xx/Makefile
+++ b/arch/arm/mach-ep93xx/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for the linux kernel.
#
-obj-y := core.o clock.o gpio.o
+obj-y := core.o clock.o dma-m2p.o gpio.o
obj-m :=
obj-n :=
obj- :=
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 96049283a10a..e8ebeaea6c48 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -41,6 +41,56 @@ static struct clk clk_usb_host = {
.enable_mask = EP93XX_SYSCON_CLOCK_USH_EN,
};
+/* DMA Clocks */
+static struct clk clk_m2p0 = {
+ .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL,
+ .enable_mask = 0x00020000,
+};
+static struct clk clk_m2p1 = {
+ .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL,
+ .enable_mask = 0x00010000,
+};
+static struct clk clk_m2p2 = {
+ .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL,
+ .enable_mask = 0x00080000,
+};
+static struct clk clk_m2p3 = {
+ .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL,
+ .enable_mask = 0x00040000,
+};
+static struct clk clk_m2p4 = {
+ .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL,
+ .enable_mask = 0x00200000,
+};
+static struct clk clk_m2p5 = {
+ .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL,
+ .enable_mask = 0x00100000,
+};
+static struct clk clk_m2p6 = {
+ .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL,
+ .enable_mask = 0x00800000,
+};
+static struct clk clk_m2p7 = {
+ .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL,
+ .enable_mask = 0x00400000,
+};
+static struct clk clk_m2p8 = {
+ .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL,
+ .enable_mask = 0x02000000,
+};
+static struct clk clk_m2p9 = {
+ .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL,
+ .enable_mask = 0x01000000,
+};
+static struct clk clk_m2m0 = {
+ .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL,
+ .enable_mask = 0x04000000,
+};
+static struct clk clk_m2m1 = {
+ .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL,
+ .enable_mask = 0x08000000,
+};
+
#define INIT_CK(dev,con,ck) \
{ .dev_id = dev, .con_id = con, .clk = ck }
@@ -54,6 +104,18 @@ static struct clk_lookup clocks[] = {
INIT_CK(NULL, "pclk", &clk_p),
INIT_CK(NULL, "pll2", &clk_pll2),
INIT_CK(NULL, "usb_host", &clk_usb_host),
+ INIT_CK(NULL, "m2p0", &clk_m2p0),
+ INIT_CK(NULL, "m2p1", &clk_m2p1),
+ INIT_CK(NULL, "m2p2", &clk_m2p2),
+ INIT_CK(NULL, "m2p3", &clk_m2p3),
+ INIT_CK(NULL, "m2p4", &clk_m2p4),
+ INIT_CK(NULL, "m2p5", &clk_m2p5),
+ INIT_CK(NULL, "m2p6", &clk_m2p6),
+ INIT_CK(NULL, "m2p7", &clk_m2p7),
+ INIT_CK(NULL, "m2p8", &clk_m2p8),
+ INIT_CK(NULL, "m2p9", &clk_m2p9),
+ INIT_CK(NULL, "m2m0", &clk_m2m0),
+ INIT_CK(NULL, "m2m1", &clk_m2m1),
};
@@ -110,6 +172,22 @@ static unsigned long calc_pll_rate(u32 config_word)
return (unsigned long)rate;
}
+static void __init ep93xx_dma_clock_init(void)
+{
+ clk_m2p0.rate = clk_h.rate;
+ clk_m2p1.rate = clk_h.rate;
+ clk_m2p2.rate = clk_h.rate;
+ clk_m2p3.rate = clk_h.rate;
+ clk_m2p4.rate = clk_h.rate;
+ clk_m2p5.rate = clk_h.rate;
+ clk_m2p6.rate = clk_h.rate;
+ clk_m2p7.rate = clk_h.rate;
+ clk_m2p8.rate = clk_h.rate;
+ clk_m2p9.rate = clk_h.rate;
+ clk_m2m0.rate = clk_h.rate;
+ clk_m2m1.rate = clk_h.rate;
+}
+
static int __init ep93xx_clock_init(void)
{
u32 value;
@@ -124,6 +202,7 @@ static int __init ep93xx_clock_init(void)
clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
+ ep93xx_dma_clock_init();
value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2);
if (!(value & 0x00080000)) { /* PLL2 bypassed? */
diff --git a/arch/arm/mach-ep93xx/dma-m2p.c b/arch/arm/mach-ep93xx/dma-m2p.c
new file mode 100644
index 000000000000..a2df5bb7dff0
--- /dev/null
+++ b/arch/arm/mach-ep93xx/dma-m2p.c
@@ -0,0 +1,408 @@
+/*
+ * arch/arm/mach-ep93xx/dma-m2p.c
+ * M2P DMA handling for Cirrus EP93xx chips.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Copyright (C) 2006 Applied Data Systems
+ *
+ * Copyright (C) 2009 Ryan Mallon <ryan@bluewatersys.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+/*
+ * On the EP93xx chip the following peripherals my be allocated to the 10
+ * Memory to Internal Peripheral (M2P) channels (5 transmit + 5 receive).
+ *
+ * I2S contains 3 Tx and 3 Rx DMA Channels
+ * AAC contains 3 Tx and 3 Rx DMA Channels
+ * UART1 contains 1 Tx and 1 Rx DMA Channels
+ * UART2 contains 1 Tx and 1 Rx DMA Channels
+ * UART3 contains 1 Tx and 1 Rx DMA Channels
+ * IrDA contains 1 Tx and 1 Rx DMA Channels
+ *
+ * SSP and IDE use the Memory to Memory (M2M) channels and are not covered
+ * with this implementation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+#include <mach/dma.h>
+#include <mach/hardware.h>
+
+#define M2P_CONTROL 0x00
+#define M2P_CONTROL_STALL_IRQ_EN (1 << 0)
+#define M2P_CONTROL_NFB_IRQ_EN (1 << 1)
+#define M2P_CONTROL_ERROR_IRQ_EN (1 << 3)
+#define M2P_CONTROL_ENABLE (1 << 4)
+#define M2P_INTERRUPT 0x04
+#define M2P_INTERRUPT_STALL (1 << 0)
+#define M2P_INTERRUPT_NFB (1 << 1)
+#define M2P_INTERRUPT_ERROR (1 << 3)
+#define M2P_PPALLOC 0x08
+#define M2P_STATUS 0x0c
+#define M2P_REMAIN 0x14
+#define M2P_MAXCNT0 0x20
+#define M2P_BASE0 0x24
+#define M2P_MAXCNT1 0x30
+#define M2P_BASE1 0x34
+
+#define STATE_IDLE 0 /* Channel is inactive. */
+#define STATE_STALL 1 /* Channel is active, no buffers pending. */
+#define STATE_ON 2 /* Channel is active, one buffer pending. */
+#define STATE_NEXT 3 /* Channel is active, two buffers pending. */
+
+struct m2p_channel {
+ char *name;
+ void __iomem *base;
+ int irq;
+
+ struct clk *clk;
+ spinlock_t lock;
+
+ void *client;
+ unsigned next_slot:1;
+ struct ep93xx_dma_buffer *buffer_xfer;
+ struct ep93xx_dma_buffer *buffer_next;
+ struct list_head buffers_pending;
+};
+
+static struct m2p_channel m2p_rx[] = {
+ {"m2p1", EP93XX_DMA_BASE + 0x0040, IRQ_EP93XX_DMAM2P1},
+ {"m2p3", EP93XX_DMA_BASE + 0x00c0, IRQ_EP93XX_DMAM2P3},
+ {"m2p5", EP93XX_DMA_BASE + 0x0200, IRQ_EP93XX_DMAM2P5},
+ {"m2p7", EP93XX_DMA_BASE + 0x0280, IRQ_EP93XX_DMAM2P7},
+ {"m2p9", EP93XX_DMA_BASE + 0x0300, IRQ_EP93XX_DMAM2P9},
+ {NULL},
+};
+
+static struct m2p_channel m2p_tx[] = {
+ {"m2p0", EP93XX_DMA_BASE + 0x0000, IRQ_EP93XX_DMAM2P0},
+ {"m2p2", EP93XX_DMA_BASE + 0x0080, IRQ_EP93XX_DMAM2P2},
+ {"m2p4", EP93XX_DMA_BASE + 0x0240, IRQ_EP93XX_DMAM2P4},
+ {"m2p6", EP93XX_DMA_BASE + 0x02c0, IRQ_EP93XX_DMAM2P6},
+ {"m2p8", EP93XX_DMA_BASE + 0x0340, IRQ_EP93XX_DMAM2P8},
+ {NULL},
+};
+
+static void feed_buf(struct m2p_channel *ch, struct ep93xx_dma_buffer *buf)
+{
+ if (ch->next_slot == 0) {
+ writel(buf->size, ch->base + M2P_MAXCNT0);
+ writel(buf->bus_addr, ch->base + M2P_BASE0);
+ } else {
+ writel(buf->size, ch->base + M2P_MAXCNT1);
+ writel(buf->bus_addr, ch->base + M2P_BASE1);
+ }
+ ch->next_slot ^= 1;
+}
+
+static void choose_buffer_xfer(struct m2p_channel *ch)
+{
+ struct ep93xx_dma_buffer *buf;
+
+ ch->buffer_xfer = NULL;
+ if (!list_empty(&ch->buffers_pending)) {
+ buf = list_entry(ch->buffers_pending.next,
+ struct ep93xx_dma_buffer, list);
+ list_del(&buf->list);
+ feed_buf(ch, buf);
+ ch->buffer_xfer = buf;
+ }
+}
+
+static void choose_buffer_next(struct m2p_channel *ch)
+{
+ struct ep93xx_dma_buffer *buf;
+
+ ch->buffer_next = NULL;
+ if (!list_empty(&ch->buffers_pending)) {
+ buf = list_entry(ch->buffers_pending.next,
+ struct ep93xx_dma_buffer, list);
+ list_del(&buf->list);
+ feed_buf(ch, buf);
+ ch->buffer_next = buf;
+ }
+}
+
+static inline void m2p_set_control(struct m2p_channel *ch, u32 v)
+{
+ /*
+ * The control register must be read immediately after being written so
+ * that the internal state machine is correctly updated. See the ep93xx
+ * users' guide for details.
+ */
+ writel(v, ch->base + M2P_CONTROL);
+ readl(ch->base + M2P_CONTROL);
+}
+
+static inline int m2p_channel_state(struct m2p_channel *ch)
+{
+ return (readl(ch->base + M2P_STATUS) >> 4) & 0x3;
+}
+
+static irqreturn_t m2p_irq(int irq, void *dev_id)
+{
+ struct m2p_channel *ch = dev_id;
+ struct ep93xx_dma_m2p_client *cl;
+ u32 irq_status, v;
+ int error = 0;
+
+ cl = ch->client;
+
+ spin_lock(&ch->lock);
+ irq_status = readl(ch->base + M2P_INTERRUPT);
+
+ if (irq_status & M2P_INTERRUPT_ERROR) {
+ writel(M2P_INTERRUPT_ERROR, ch->base + M2P_INTERRUPT);
+ error = 1;
+ }
+
+ if ((irq_status & (M2P_INTERRUPT_STALL | M2P_INTERRUPT_NFB)) == 0) {
+ spin_unlock(&ch->lock);
+ return IRQ_NONE;
+ }
+
+ switch (m2p_channel_state(ch)) {
+ case STATE_IDLE:
+ pr_crit("m2p_irq: dma interrupt without a dma buffer\n");
+ BUG();
+ break;
+
+ case STATE_STALL:
+ cl->buffer_finished(cl->cookie, ch->buffer_xfer, 0, error);
+ if (ch->buffer_next != NULL) {
+ cl->buffer_finished(cl->cookie, ch->buffer_next,
+ 0, error);
+ }
+ choose_buffer_xfer(ch);
+ choose_buffer_next(ch);
+ if (ch->buffer_xfer != NULL)
+ cl->buffer_started(cl->cookie, ch->buffer_xfer);
+ break;
+
+ case STATE_ON:
+ cl->buffer_finished(cl->cookie, ch->buffer_xfer, 0, error);
+ ch->buffer_xfer = ch->buffer_next;
+ choose_buffer_next(ch);
+ cl->buffer_started(cl->cookie, ch->buffer_xfer);
+ break;
+
+ case STATE_NEXT:
+ pr_crit("m2p_irq: dma interrupt while next\n");
+ BUG();
+ break;
+ }
+
+ v = readl(ch->base + M2P_CONTROL) & ~(M2P_CONTROL_STALL_IRQ_EN |
+ M2P_CONTROL_NFB_IRQ_EN);
+ if (ch->buffer_xfer != NULL)
+ v |= M2P_CONTROL_STALL_IRQ_EN;
+ if (ch->buffer_next != NULL)
+ v |= M2P_CONTROL_NFB_IRQ_EN;
+ m2p_set_control(ch, v);
+
+ spin_unlock(&ch->lock);
+ return IRQ_HANDLED;
+}
+
+static struct m2p_channel *find_free_channel(struct ep93xx_dma_m2p_client *cl)
+{
+ struct m2p_channel *ch;
+ int i;
+
+ if (cl->flags & EP93XX_DMA_M2P_RX)
+ ch = m2p_rx;
+ else
+ ch = m2p_tx;
+
+ for (i = 0; ch[i].base; i++) {
+ struct ep93xx_dma_m2p_client *client;
+
+ client = ch[i].client;
+ if (client != NULL) {
+ int port;
+
+ port = cl->flags & EP93XX_DMA_M2P_PORT_MASK;
+ if (port == (client->flags &
+ EP93XX_DMA_M2P_PORT_MASK)) {
+ pr_warning("DMA channel already used by %s\n",
+ cl->name ? : "unknown client");
+ return ERR_PTR(-EBUSY);
+ }
+ }
+ }
+
+ for (i = 0; ch[i].base; i++) {
+ if (ch[i].client == NULL)
+ return ch + i;
+ }
+
+ pr_warning("No free DMA channel for %s\n",
+ cl->name ? : "unknown client");
+ return ERR_PTR(-ENODEV);
+}
+
+static void channel_enable(struct m2p_channel *ch)
+{
+ struct ep93xx_dma_m2p_client *cl = ch->client;
+ u32 v;
+
+ clk_enable(ch->clk);
+
+ v = cl->flags & EP93XX_DMA_M2P_PORT_MASK;
+ writel(v, ch->base + M2P_PPALLOC);
+
+ v = cl->flags & EP93XX_DMA_M2P_ERROR_MASK;
+ v |= M2P_CONTROL_ENABLE | M2P_CONTROL_ERROR_IRQ_EN;
+ m2p_set_control(ch, v);
+}
+
+static void channel_disable(struct m2p_channel *ch)
+{
+ u32 v;
+
+ v = readl(ch->base + M2P_CONTROL);
+ v &= ~(M2P_CONTROL_STALL_IRQ_EN | M2P_CONTROL_NFB_IRQ_EN);
+ m2p_set_control(ch, v);
+
+ while (m2p_channel_state(ch) == STATE_ON)
+ cpu_relax();
+
+ m2p_set_control(ch, 0x0);
+
+ while (m2p_channel_state(ch) == STATE_STALL)
+ cpu_relax();
+
+ clk_disable(ch->clk);
+}
+
+int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *cl)
+{
+ struct m2p_channel *ch;
+ int err;
+
+ ch = find_free_channel(cl);
+ if (IS_ERR(ch))
+ return PTR_ERR(ch);
+
+ err = request_irq(ch->irq, m2p_irq, 0, cl->name ? : "dma-m2p", ch);
+ if (err)
+ return err;
+
+ ch->client = cl;
+ ch->next_slot = 0;
+ ch->buffer_xfer = NULL;
+ ch->buffer_next = NULL;
+ INIT_LIST_HEAD(&ch->buffers_pending);
+
+ cl->channel = ch;
+
+ channel_enable(ch);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_client_register);
+
+void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *cl)
+{
+ struct m2p_channel *ch = cl->channel;
+
+ channel_disable(ch);
+ free_irq(ch->irq, ch);
+ ch->client = NULL;
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_client_unregister);
+
+void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *cl,
+ struct ep93xx_dma_buffer *buf)
+{
+ struct m2p_channel *ch = cl->channel;
+ unsigned long flags;
+ u32 v;
+
+ spin_lock_irqsave(&ch->lock, flags);
+ v = readl(ch->base + M2P_CONTROL);
+ if (ch->buffer_xfer == NULL) {
+ ch->buffer_xfer = buf;
+ feed_buf(ch, buf);
+ cl->buffer_started(cl->cookie, buf);
+
+ v |= M2P_CONTROL_STALL_IRQ_EN;
+ m2p_set_control(ch, v);
+
+ } else if (ch->buffer_next == NULL) {
+ ch->buffer_next = buf;
+ feed_buf(ch, buf);
+
+ v |= M2P_CONTROL_NFB_IRQ_EN;
+ m2p_set_control(ch, v);
+ } else {
+ list_add_tail(&buf->list, &ch->buffers_pending);
+ }
+ spin_unlock_irqrestore(&ch->lock, flags);
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_submit);
+
+void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *cl,
+ struct ep93xx_dma_buffer *buf)
+{
+ struct m2p_channel *ch = cl->channel;
+
+ list_add_tail(&buf->list, &ch->buffers_pending);
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_submit_recursive);
+
+void ep93xx_dma_m2p_flush(struct ep93xx_dma_m2p_client *cl)
+{
+ struct m2p_channel *ch = cl->channel;
+
+ channel_disable(ch);
+ ch->next_slot = 0;
+ ch->buffer_xfer = NULL;
+ ch->buffer_next = NULL;
+ INIT_LIST_HEAD(&ch->buffers_pending);
+ channel_enable(ch);
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_flush);
+
+static int init_channel(struct m2p_channel *ch)
+{
+ ch->clk = clk_get(NULL, ch->name);
+ if (IS_ERR(ch->clk))
+ return PTR_ERR(ch->clk);
+
+ spin_lock_init(&ch->lock);
+ ch->client = NULL;
+
+ return 0;
+}
+
+static int __init ep93xx_dma_m2p_init(void)
+{
+ int i;
+ int ret;
+
+ for (i = 0; m2p_rx[i].base; i++) {
+ ret = init_channel(m2p_rx + i);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; m2p_tx[i].base; i++) {
+ ret = init_channel(m2p_tx + i);
+ if (ret)
+ return ret;
+ }
+
+ pr_info("M2P DMA subsystem initialized\n");
+ return 0;
+}
+arch_initcall(ep93xx_dma_m2p_init);
diff --git a/arch/arm/mach-ep93xx/edb9307a.c b/arch/arm/mach-ep93xx/edb9307a.c
index 5b5c22b681be..6171167d3315 100644
--- a/arch/arm/mach-ep93xx/edb9307a.c
+++ b/arch/arm/mach-ep93xx/edb9307a.c
@@ -48,12 +48,24 @@ static struct ep93xx_eth_data edb9307a_eth_data = {
.phy_id = 1,
};
+static struct i2c_board_info __initdata edb9307a_i2c_data[] = {
+ {
+ /* On-board battery backed RTC */
+ I2C_BOARD_INFO("isl1208", 0x6f),
+ },
+ /*
+ * The I2C signals are also routed to the Expansion Connector (J4)
+ */
+};
+
static void __init edb9307a_init_machine(void)
{
ep93xx_init_devices();
platform_device_register(&edb9307a_flash);
ep93xx_register_eth(&edb9307a_eth_data, 1);
+
+ ep93xx_init_i2c(edb9307a_i2c_data, ARRAY_SIZE(edb9307a_i2c_data));
}
MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board")
diff --git a/arch/arm/mach-ep93xx/include/mach/dma.h b/arch/arm/mach-ep93xx/include/mach/dma.h
new file mode 100644
index 000000000000..ef6bd9d13148
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/dma.h
@@ -0,0 +1,52 @@
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#include <linux/list.h>
+#include <linux/types.h>
+
+struct ep93xx_dma_buffer {
+ struct list_head list;
+ u32 bus_addr;
+ u16 size;
+};
+
+struct ep93xx_dma_m2p_client {
+ char *name;
+ u8 flags;
+ void *cookie;
+ void (*buffer_started)(void *cookie,
+ struct ep93xx_dma_buffer *buf);
+ void (*buffer_finished)(void *cookie,
+ struct ep93xx_dma_buffer *buf,
+ int bytes, int error);
+
+ /* Internal to the DMA code. */
+ void *channel;
+};
+
+#define EP93XX_DMA_M2P_PORT_I2S1 0x00
+#define EP93XX_DMA_M2P_PORT_I2S2 0x01
+#define EP93XX_DMA_M2P_PORT_AAC1 0x02
+#define EP93XX_DMA_M2P_PORT_AAC2 0x03
+#define EP93XX_DMA_M2P_PORT_AAC3 0x04
+#define EP93XX_DMA_M2P_PORT_I2S3 0x05
+#define EP93XX_DMA_M2P_PORT_UART1 0x06
+#define EP93XX_DMA_M2P_PORT_UART2 0x07
+#define EP93XX_DMA_M2P_PORT_UART3 0x08
+#define EP93XX_DMA_M2P_PORT_IRDA 0x09
+#define EP93XX_DMA_M2P_PORT_MASK 0x0f
+#define EP93XX_DMA_M2P_TX 0x00
+#define EP93XX_DMA_M2P_RX 0x10
+#define EP93XX_DMA_M2P_ABORT_ON_ERROR 0x20
+#define EP93XX_DMA_M2P_IGNORE_ERROR 0x40
+#define EP93XX_DMA_M2P_ERROR_MASK 0x60
+
+int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p);
+void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *m2p);
+void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *m2p,
+ struct ep93xx_dma_buffer *buf);
+void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *m2p,
+ struct ep93xx_dma_buffer *buf);
+void ep93xx_dma_m2p_flush(struct ep93xx_dma_m2p_client *m2p);
+
+#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
index 22d6c9a6e4ca..f66be12b856e 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -58,7 +58,8 @@
/* AHB peripherals */
-#define EP93XX_DMA_BASE (EP93XX_AHB_VIRT_BASE + 0x00000000)
+#define EP93XX_DMA_BASE ((void __iomem *) \
+ (EP93XX_AHB_VIRT_BASE + 0x00000000))
#define EP93XX_ETHERNET_BASE (EP93XX_AHB_VIRT_BASE + 0x00010000)
#define EP93XX_ETHERNET_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00010000)
diff --git a/arch/arm/mach-ep93xx/include/mach/system.h b/arch/arm/mach-ep93xx/include/mach/system.h
index 67789d0f329e..ed8f35e4f068 100644
--- a/arch/arm/mach-ep93xx/include/mach/system.h
+++ b/arch/arm/mach-ep93xx/include/mach/system.h
@@ -9,7 +9,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
u32 devicecfg;
diff --git a/arch/arm/mach-footbridge/dma.c b/arch/arm/mach-footbridge/dma.c
index 4f3506346969..e2e0df8bcee2 100644
--- a/arch/arm/mach-footbridge/dma.c
+++ b/arch/arm/mach-footbridge/dma.c
@@ -21,16 +21,16 @@
#include <asm/hardware/dec21285.h>
#if 0
-static int fb_dma_request(dmach_t channel, dma_t *dma)
+static int fb_dma_request(unsigned int chan, dma_t *dma)
{
return -EINVAL;
}
-static void fb_dma_enable(dmach_t channel, dma_t *dma)
+static void fb_dma_enable(unsigned int chan, dma_t *dma)
{
}
-static void fb_dma_disable(dmach_t channel, dma_t *dma)
+static void fb_dma_disable(unsigned int chan, dma_t *dma)
{
}
@@ -42,7 +42,7 @@ static struct dma_ops fb_dma_ops = {
};
#endif
-void __init arch_dma_init(dma_t *dma)
+static int __init fb_dma_init(void)
{
#if 0
dma[_DC21285_DMA(0)].d_ops = &fb_dma_ops;
@@ -50,6 +50,8 @@ void __init arch_dma_init(dma_t *dma)
#endif
#ifdef CONFIG_ISA_DMA
if (footbridge_cfn_mode())
- isa_init_dma(dma + _ISA_DMA(0));
+ isa_init_dma();
#endif
+ return 0;
}
+core_initcall(fb_dma_init);
diff --git a/arch/arm/mach-footbridge/include/mach/system.h b/arch/arm/mach-footbridge/include/mach/system.h
index 2db7f36bd6ca..0b2931566209 100644
--- a/arch/arm/mach-footbridge/include/mach/system.h
+++ b/arch/arm/mach-footbridge/include/mach/system.h
@@ -18,7 +18,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
if (mode == 's') {
/*
diff --git a/arch/arm/mach-gemini/Kconfig b/arch/arm/mach-gemini/Kconfig
new file mode 100644
index 000000000000..515b75cf2e8b
--- /dev/null
+++ b/arch/arm/mach-gemini/Kconfig
@@ -0,0 +1,19 @@
+if ARCH_GEMINI
+
+menu "Cortina Systems Gemini Implementations"
+
+config MACH_RUT100
+ bool "Teltonika RUT100"
+ select GEMINI_MEM_SWAP
+ help
+ Say Y here if you intend to run this kernel on a
+ Teltonika 3G Router RUT100.
+
+endmenu
+
+config GEMINI_MEM_SWAP
+ bool "Gemini memory is swapped"
+ help
+ Say Y here if Gemini memory is swapped by bootloader.
+
+endif
diff --git a/arch/arm/mach-gemini/Makefile b/arch/arm/mach-gemini/Makefile
new file mode 100644
index 000000000000..719505b81821
--- /dev/null
+++ b/arch/arm/mach-gemini/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := irq.o mm.o time.o devices.o gpio.o
+
+# Board-specific support
+obj-$(CONFIG_MACH_RUT100) += board-rut1xx.o
diff --git a/arch/arm/mach-gemini/Makefile.boot b/arch/arm/mach-gemini/Makefile.boot
new file mode 100644
index 000000000000..22a52c228d93
--- /dev/null
+++ b/arch/arm/mach-gemini/Makefile.boot
@@ -0,0 +1,9 @@
+ifeq ($(CONFIG_GEMINI_MEM_SWAP),y)
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
+else
+ zreladdr-y := 0x10008000
+params_phys-y := 0x10000100
+initrd_phys-y := 0x10800000
+endif
diff --git a/arch/arm/mach-gemini/board-rut1xx.c b/arch/arm/mach-gemini/board-rut1xx.c
new file mode 100644
index 000000000000..e0de968e32a6
--- /dev/null
+++ b/arch/arm/mach-gemini/board-rut1xx.c
@@ -0,0 +1,95 @@
+/*
+ * Support for Teltonika RUT1xx
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+
+static struct gpio_keys_button rut1xx_keys[] = {
+ {
+ .code = KEY_SETUP,
+ .gpio = 60,
+ .active_low = 1,
+ .desc = "Reset to defaults",
+ .type = EV_KEY,
+ },
+};
+
+static struct gpio_keys_platform_data rut1xx_keys_data = {
+ .buttons = rut1xx_keys,
+ .nbuttons = ARRAY_SIZE(rut1xx_keys),
+};
+
+static struct platform_device rut1xx_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &rut1xx_keys_data,
+ },
+};
+
+static struct gpio_led rut100_leds[] = {
+ {
+ .name = "Power",
+ .default_trigger = "heartbeat",
+ .gpio = 17,
+ },
+ {
+ .name = "GSM",
+ .default_trigger = "default-on",
+ .gpio = 7,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data rut100_leds_data = {
+ .num_leds = ARRAY_SIZE(rut100_leds),
+ .leds = rut100_leds,
+};
+
+static struct platform_device rut1xx_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &rut100_leds_data,
+ },
+};
+
+static struct sys_timer rut1xx_timer = {
+ .init = gemini_timer_init,
+};
+
+static void __init rut1xx_init(void)
+{
+ gemini_gpio_init();
+ platform_register_uart();
+ platform_register_pflash(SZ_8M, NULL, 0);
+ platform_device_register(&rut1xx_leds);
+ platform_device_register(&rut1xx_keys_device);
+}
+
+MACHINE_START(RUT100, "Teltonika RUT100")
+ .phys_io = 0x7fffc000,
+ .io_pg_offst = ((0xffffc000) >> 18) & 0xfffc,
+ .boot_params = 0x100,
+ .map_io = gemini_map_io,
+ .init_irq = gemini_init_irq,
+ .timer = &rut1xx_timer,
+ .init_machine = rut1xx_init,
+MACHINE_END
diff --git a/arch/arm/mach-gemini/common.h b/arch/arm/mach-gemini/common.h
new file mode 100644
index 000000000000..9392834a214f
--- /dev/null
+++ b/arch/arm/mach-gemini/common.h
@@ -0,0 +1,28 @@
+/*
+ * Common Gemini architecture functions
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __GEMINI_COMMON_H__
+#define __GEMINI_COMMON_H__
+
+struct mtd_partition;
+
+extern void gemini_map_io(void);
+extern void gemini_init_irq(void);
+extern void gemini_timer_init(void);
+extern void gemini_gpio_init(void);
+
+/* Common platform devices registration functions */
+extern int platform_register_uart(void);
+extern int platform_register_pflash(unsigned int size,
+ struct mtd_partition *parts,
+ unsigned int nr_parts);
+
+#endif /* __GEMINI_COMMON_H__ */
diff --git a/arch/arm/mach-gemini/devices.c b/arch/arm/mach-gemini/devices.c
new file mode 100644
index 000000000000..6b525253d027
--- /dev/null
+++ b/arch/arm/mach-gemini/devices.c
@@ -0,0 +1,92 @@
+/*
+ * Common devices definition for Gemini
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/global_reg.h>
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .membase = (void *)IO_ADDRESS(GEMINI_UART_BASE),
+ .mapbase = GEMINI_UART_BASE,
+ .irq = IRQ_UART,
+ .uartclk = UART_CLK,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .type = PORT_16550A,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_FIXED_TYPE,
+ },
+ {},
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+int platform_register_uart(void)
+{
+ return platform_device_register(&serial_device);
+}
+
+static struct resource flash_resource = {
+ .start = GEMINI_FLASH_BASE,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data pflash_platform_data = {};
+
+static struct platform_device pflash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &pflash_platform_data,
+ },
+ .resource = &flash_resource,
+ .num_resources = 1,
+};
+
+int platform_register_pflash(unsigned int size, struct mtd_partition *parts,
+ unsigned int nr_parts)
+{
+ unsigned int reg;
+
+ reg = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_STATUS);
+
+ if ((reg & FLASH_TYPE_MASK) != FLASH_TYPE_PARALLEL)
+ return -ENXIO;
+
+ if (reg & FLASH_WIDTH_16BIT)
+ pflash_platform_data.width = 2;
+ else
+ pflash_platform_data.width = 1;
+
+ /* enable parallel flash pins and disable others */
+ reg = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_MISC_CTRL);
+ reg &= ~PFLASH_PADS_DISABLE;
+ reg |= SFLASH_PADS_DISABLE | NAND_PADS_DISABLE;
+ __raw_writel(reg, IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_MISC_CTRL);
+
+ flash_resource.end = flash_resource.start + size - 1;
+
+ pflash_platform_data.parts = parts;
+ pflash_platform_data.nr_parts = nr_parts;
+
+ return platform_device_register(&pflash_device);
+}
diff --git a/arch/arm/mach-gemini/gpio.c b/arch/arm/mach-gemini/gpio.c
new file mode 100644
index 000000000000..e7263854bc7b
--- /dev/null
+++ b/arch/arm/mach-gemini/gpio.c
@@ -0,0 +1,232 @@
+/*
+ * Gemini gpiochip and interrupt routines
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on plat-mxc/gpio.c:
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+#define GPIO_BASE(x) IO_ADDRESS(GEMINI_GPIO_BASE(x))
+
+/* GPIO registers definition */
+#define GPIO_DATA_OUT 0x0
+#define GPIO_DATA_IN 0x4
+#define GPIO_DIR 0x8
+#define GPIO_DATA_SET 0x10
+#define GPIO_DATA_CLR 0x14
+#define GPIO_PULL_EN 0x18
+#define GPIO_PULL_TYPE 0x1C
+#define GPIO_INT_EN 0x20
+#define GPIO_INT_STAT 0x24
+#define GPIO_INT_MASK 0x2C
+#define GPIO_INT_CLR 0x30
+#define GPIO_INT_TYPE 0x34
+#define GPIO_INT_BOTH_EDGE 0x38
+#define GPIO_INT_LEVEL 0x3C
+#define GPIO_DEBOUNCE_EN 0x40
+#define GPIO_DEBOUNCE_PRESCALE 0x44
+
+#define GPIO_PORT_NUM 3
+
+static void _set_gpio_irqenable(unsigned int base, unsigned int index,
+ int enable)
+{
+ unsigned int reg;
+
+ reg = __raw_readl(base + GPIO_INT_EN);
+ reg = (reg & (~(1 << index))) | (!!enable << index);
+ __raw_writel(reg, base + GPIO_INT_EN);
+}
+
+static void gpio_ack_irq(unsigned int irq)
+{
+ unsigned int gpio = irq_to_gpio(irq);
+ unsigned int base = GPIO_BASE(gpio / 32);
+
+ __raw_writel(1 << (gpio % 32), base + GPIO_INT_CLR);
+}
+
+static void gpio_mask_irq(unsigned int irq)
+{
+ unsigned int gpio = irq_to_gpio(irq);
+ unsigned int base = GPIO_BASE(gpio / 32);
+
+ _set_gpio_irqenable(base, gpio % 32, 0);
+}
+
+static void gpio_unmask_irq(unsigned int irq)
+{
+ unsigned int gpio = irq_to_gpio(irq);
+ unsigned int base = GPIO_BASE(gpio / 32);
+
+ _set_gpio_irqenable(base, gpio % 32, 1);
+}
+
+static int gpio_set_irq_type(unsigned int irq, unsigned int type)
+{
+ unsigned int gpio = irq_to_gpio(irq);
+ unsigned int gpio_mask = 1 << (gpio % 32);
+ unsigned int base = GPIO_BASE(gpio / 32);
+ unsigned int reg_both, reg_level, reg_type;
+
+ reg_type = __raw_readl(base + GPIO_INT_TYPE);
+ reg_level = __raw_readl(base + GPIO_INT_BOTH_EDGE);
+ reg_both = __raw_readl(base + GPIO_INT_BOTH_EDGE);
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_BOTH:
+ reg_type &= ~gpio_mask;
+ reg_both |= gpio_mask;
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ reg_type &= ~gpio_mask;
+ reg_both &= ~gpio_mask;
+ reg_level &= ~gpio_mask;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ reg_type &= ~gpio_mask;
+ reg_both &= ~gpio_mask;
+ reg_level |= gpio_mask;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ reg_type |= gpio_mask;
+ reg_level &= ~gpio_mask;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ reg_type |= gpio_mask;
+ reg_level |= gpio_mask;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ __raw_writel(reg_type, base + GPIO_INT_TYPE);
+ __raw_writel(reg_level, base + GPIO_INT_BOTH_EDGE);
+ __raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE);
+
+ gpio_ack_irq(irq);
+
+ return 0;
+}
+
+static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned int gpio_irq_no, irq_stat;
+ unsigned int port = (unsigned int)get_irq_data(irq);
+
+ irq_stat = __raw_readl(GPIO_BASE(port) + GPIO_INT_STAT);
+
+ gpio_irq_no = GPIO_IRQ_BASE + port * 32;
+ for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) {
+
+ if ((irq_stat & 1) == 0)
+ continue;
+
+ BUG_ON(!(irq_desc[gpio_irq_no].handle_irq));
+ irq_desc[gpio_irq_no].handle_irq(gpio_irq_no,
+ &irq_desc[gpio_irq_no]);
+ }
+}
+
+static struct irq_chip gpio_irq_chip = {
+ .name = "GPIO",
+ .ack = gpio_ack_irq,
+ .mask = gpio_mask_irq,
+ .unmask = gpio_unmask_irq,
+ .set_type = gpio_set_irq_type,
+};
+
+static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+ int dir)
+{
+ unsigned int base = GPIO_BASE(offset / 32);
+ unsigned int reg;
+
+ reg = __raw_readl(base + GPIO_DIR);
+ if (dir)
+ reg |= 1 << (offset % 32);
+ else
+ reg &= ~(1 << (offset % 32));
+ __raw_writel(reg, base + GPIO_DIR);
+}
+
+static void gemini_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ unsigned int base = GPIO_BASE(offset / 32);
+
+ if (value)
+ __raw_writel(1 << (offset % 32), base + GPIO_DATA_SET);
+ else
+ __raw_writel(1 << (offset % 32), base + GPIO_DATA_CLR);
+}
+
+static int gemini_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ unsigned int base = GPIO_BASE(offset / 32);
+
+ return (__raw_readl(base + GPIO_DATA_IN) >> (offset % 32)) & 1;
+}
+
+static int gemini_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ _set_gpio_direction(chip, offset, 0);
+ return 0;
+}
+
+static int gemini_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ _set_gpio_direction(chip, offset, 1);
+ gemini_gpio_set(chip, offset, value);
+ return 0;
+}
+
+static struct gpio_chip gemini_gpio_chip = {
+ .label = "Gemini",
+ .direction_input = gemini_gpio_direction_input,
+ .get = gemini_gpio_get,
+ .direction_output = gemini_gpio_direction_output,
+ .set = gemini_gpio_set,
+ .base = 0,
+ .ngpio = GPIO_PORT_NUM * 32,
+};
+
+void __init gemini_gpio_init(void)
+{
+ int i, j;
+
+ for (i = 0; i < GPIO_PORT_NUM; i++) {
+ /* disable, unmask and clear all interrupts */
+ __raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_EN);
+ __raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_MASK);
+ __raw_writel(~0x0, GPIO_BASE(i) + GPIO_INT_CLR);
+
+ for (j = GPIO_IRQ_BASE + i * 32;
+ j < GPIO_IRQ_BASE + (i + 1) * 32; j++) {
+ set_irq_chip(j, &gpio_irq_chip);
+ set_irq_handler(j, handle_edge_irq);
+ set_irq_flags(j, IRQF_VALID);
+ }
+
+ set_irq_chained_handler(IRQ_GPIO(i), gpio_irq_handler);
+ set_irq_data(IRQ_GPIO(i), (void *)i);
+ }
+
+ BUG_ON(gpiochip_add(&gemini_gpio_chip));
+}
diff --git a/arch/arm/mach-gemini/include/mach/debug-macro.S b/arch/arm/mach-gemini/include/mach/debug-macro.S
new file mode 100644
index 000000000000..d04a6eaeae14
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/debug-macro.S
@@ -0,0 +1,23 @@
+/*
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <mach/hardware.h>
+
+ .macro addruart,rx
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ ldreq \rx, =GEMINI_UART_BASE @ physical
+ ldrne \rx, =IO_ADDRESS(GEMINI_UART_BASE) @ virtual
+ .endm
+
+#define UART_SHIFT 2
+#define FLOW_CONTROL
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-gemini/include/mach/entry-macro.S b/arch/arm/mach-gemini/include/mach/entry-macro.S
new file mode 100644
index 000000000000..1624f91a2b8b
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/entry-macro.S
@@ -0,0 +1,39 @@
+/*
+ * Low-level IRQ helper macros for Gemini platform.
+ *
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/hardware.h>
+
+#define IRQ_STATUS 0x14
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, =IO_ADDRESS(GEMINI_INTERRUPT_BASE + IRQ_STATUS)
+ ldr \irqnr, [\irqstat]
+ cmp \irqnr, #0
+ beq 2313f
+ mov \tmp, \irqnr
+ mov \irqnr, #0
+2312:
+ tst \tmp, #1
+ bne 2313f
+ add \irqnr, \irqnr, #1
+ mov \tmp, \tmp, lsr #1
+ cmp \irqnr, #31
+ bcc 2312b
+2313:
+ .endm
diff --git a/arch/arm/mach-gemini/include/mach/global_reg.h b/arch/arm/mach-gemini/include/mach/global_reg.h
new file mode 100644
index 000000000000..de7ff7e849fc
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/global_reg.h
@@ -0,0 +1,278 @@
+/*
+ * This file contains the hardware definitions for Gemini.
+ *
+ * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __MACH_GLOBAL_REG_H
+#define __MACH_GLOBAL_REG_H
+
+/* Global Word ID Register*/
+#define GLOBAL_ID 0x00
+
+#define CHIP_ID(reg) ((reg) >> 8)
+#define CHIP_REVISION(reg) ((reg) & 0xFF)
+
+/* Global Status Register */
+#define GLOBAL_STATUS 0x04
+
+#define CPU_BIG_ENDIAN (1 << 31)
+#define PLL_OSC_30M (1 << 30) /* else 60MHz */
+
+#define OPERATION_MODE_MASK (0xF << 26)
+#define OPM_IDDQ (0xF << 26)
+#define OPM_NAND (0xE << 26)
+#define OPM_RING (0xD << 26)
+#define OPM_DIRECT_BOOT (0xC << 26)
+#define OPM_USB1_PHY_TEST (0xB << 26)
+#define OPM_USB0_PHY_TEST (0xA << 26)
+#define OPM_SATA1_PHY_TEST (0x9 << 26)
+#define OPM_SATA0_PHY_TEST (0x8 << 26)
+#define OPM_ICE_ARM (0x7 << 26)
+#define OPM_ICE_FARADAY (0x6 << 26)
+#define OPM_PLL_BYPASS (0x5 << 26)
+#define OPM_DEBUG (0x4 << 26)
+#define OPM_BURN_IN (0x3 << 26)
+#define OPM_MBIST (0x2 << 26)
+#define OPM_SCAN (0x1 << 26)
+#define OPM_REAL (0x0 << 26)
+
+#define FLASH_TYPE_MASK (0x3 << 24)
+#define FLASH_TYPE_NAND_2K (0x3 << 24)
+#define FLASH_TYPE_NAND_512 (0x2 << 24)
+#define FLASH_TYPE_PARALLEL (0x1 << 24)
+#define FLASH_TYPE_SERIAL (0x0 << 24)
+/* if parallel */
+#define FLASH_WIDTH_16BIT (1 << 23) /* else 8 bit */
+/* if serial */
+#define FLASH_ATMEL (1 << 23) /* else STM */
+
+#define FLASH_SIZE_MASK (0x3 << 21)
+#define NAND_256M (0x3 << 21) /* and more */
+#define NAND_128M (0x2 << 21)
+#define NAND_64M (0x1 << 21)
+#define NAND_32M (0x0 << 21)
+#define ATMEL_16M (0x3 << 21) /* and more */
+#define ATMEL_8M (0x2 << 21)
+#define ATMEL_4M_2M (0x1 << 21)
+#define ATMEL_1M (0x0 << 21) /* and less */
+#define STM_32M (1 << 22) /* and more */
+#define STM_16M (0 << 22) /* and less */
+
+#define FLASH_PARALLEL_HIGH_PIN_CNT (1 << 20) /* else low pin cnt */
+
+#define CPU_AHB_RATIO_MASK (0x3 << 18)
+#define CPU_AHB_1_1 (0x0 << 18)
+#define CPU_AHB_3_2 (0x1 << 18)
+#define CPU_AHB_24_13 (0x2 << 18)
+#define CPU_AHB_2_1 (0x3 << 18)
+
+#define REG_TO_AHB_SPEED(reg) ((((reg) >> 15) & 0x7) * 10 + 130)
+#define AHB_SPEED_TO_REG(x) ((((x - 130)) / 10) << 15)
+
+/* it is posible to override some settings, use >> OVERRIDE_xxxx_SHIFT */
+#define OVERRIDE_FLASH_TYPE_SHIFT 16
+#define OVERRIDE_FLASH_WIDTH_SHIFT 16
+#define OVERRIDE_FLASH_SIZE_SHIFT 16
+#define OVERRIDE_CPU_AHB_RATIO_SHIFT 15
+#define OVERRIDE_AHB_SPEED_SHIFT 15
+
+/* Global PLL Control Register */
+#define GLOBAL_PLL_CTRL 0x08
+
+#define PLL_BYPASS (1 << 31)
+#define PLL_POWER_DOWN (1 << 8)
+#define PLL_CONTROL_Q (0x1F << 0)
+
+/* Global Soft Reset Control Register */
+#define GLOBAL_RESET 0x0C
+
+#define RESET_GLOBAL (1 << 31)
+#define RESET_CPU1 (1 << 30)
+#define RESET_TVE (1 << 28)
+#define RESET_SATA1 (1 << 27)
+#define RESET_SATA0 (1 << 26)
+#define RESET_CIR (1 << 25)
+#define RESET_EXT_DEV (1 << 24)
+#define RESET_WD (1 << 23)
+#define RESET_GPIO2 (1 << 22)
+#define RESET_GPIO1 (1 << 21)
+#define RESET_GPIO0 (1 << 20)
+#define RESET_SSP (1 << 19)
+#define RESET_UART (1 << 18)
+#define RESET_TIMER (1 << 17)
+#define RESET_RTC (1 << 16)
+#define RESET_INT1 (1 << 15)
+#define RESET_INT0 (1 << 14)
+#define RESET_LCD (1 << 13)
+#define RESET_LPC (1 << 12)
+#define RESET_APB (1 << 11)
+#define RESET_DMA (1 << 10)
+#define RESET_USB1 (1 << 9)
+#define RESET_USB0 (1 << 8)
+#define RESET_PCI (1 << 7)
+#define RESET_GMAC1 (1 << 6)
+#define RESET_GMAC0 (1 << 5)
+#define RESET_SECURITY (1 << 4)
+#define RESET_RAID (1 << 3)
+#define RESET_IDE (1 << 2)
+#define RESET_FLASH (1 << 1)
+#define RESET_DRAM (1 << 0)
+
+/* Global IO Pad Driving Capability Control Register */
+#define GLOBAL_IO_DRIVING_CTRL 0x10
+
+#define DRIVING_CURRENT_MASK 0x3
+
+/* here 00-4mA, 01-8mA, 10-12mA, 11-16mA */
+#define GPIO1_PADS_31_28_SHIFT 28
+#define GPIO0_PADS_31_16_SHIFT 26
+#define GPIO0_PADS_15_0_SHIFT 24
+#define PCI_AND_EXT_RESET_PADS_SHIFT 22
+#define IDE_PADS_SHIFT 20
+#define GMAC1_PADS_SHIFT 18
+#define GMAC0_PADS_SHIFT 16
+/* DRAM is not in mA and poorly documented */
+#define DRAM_CLOCK_PADS_SHIFT 8
+#define DRAM_DATA_PADS_SHIFT 4
+#define DRAM_CONTROL_PADS_SHIFT 0
+
+/* Global IO Pad Slew Rate Control Register */
+#define GLOBAL_IO_SLEW_RATE_CTRL 0x14
+
+#define GPIO1_PADS_31_28_SLOW (1 << 10)
+#define GPIO0_PADS_31_16_SLOW (1 << 9)
+#define GPIO0_PADS_15_0_SLOW (1 << 8)
+#define PCI_PADS_SLOW (1 << 7)
+#define IDE_PADS_SLOW (1 << 6)
+#define GMAC1_PADS_SLOW (1 << 5)
+#define GMAC0_PADS_SLOW (1 << 4)
+#define DRAM_CLOCK_PADS_SLOW (1 << 1)
+#define DRAM_IO_PADS_SLOW (1 << 0)
+
+/*
+ * General skew control defines
+ * 16 steps, each step is around 0.2ns
+ */
+#define SKEW_MASK 0xF
+
+/* Global IDE PAD Skew Control Register */
+#define GLOBAL_IDE_SKEW_CTRL 0x18
+
+#define IDE1_HOST_STROBE_DELAY_SHIFT 28
+#define IDE1_DEVICE_STROBE_DELAY_SHIFT 24
+#define IDE1_OUTPUT_IO_SKEW_SHIFT 20
+#define IDE1_INPUT_IO_SKEW_SHIFT 16
+#define IDE0_HOST_STROBE_DELAY_SHIFT 12
+#define IDE0_DEVICE_STROBE_DELAY_SHIFT 8
+#define IDE0_OUTPUT_IO_SKEW_SHIFT 4
+#define IDE0_INPUT_IO_SKEW_SHIFT 0
+
+/* Global GMAC Control Pad Skew Control Register */
+#define GLOBAL_GMAC_CTRL_SKEW_CTRL 0x1C
+
+#define GMAC1_TXC_SKEW_SHIFT 28
+#define GMAC1_TXEN_SKEW_SHIFT 24
+#define GMAC1_RXC_SKEW_SHIFT 20
+#define GMAC1_RXDV_SKEW_SHIFT 16
+#define GMAC0_TXC_SKEW_SHIFT 12
+#define GMAC0_TXEN_SKEW_SHIFT 8
+#define GMAC0_RXC_SKEW_SHIFT 4
+#define GMAC0_RXDV_SKEW_SHIFT 0
+
+/* Global GMAC0 Data PAD Skew Control Register */
+#define GLOBAL_GMAC0_DATA_SKEW_CTRL 0x20
+/* Global GMAC1 Data PAD Skew Control Register */
+#define GLOBAL_GMAC1_DATA_SKEW_CTRL 0x24
+
+#define GMAC_TXD_SKEW_SHIFT(x) (((x) * 4) + 16)
+#define GMAC_RXD_SKEW_SHIFT(x) ((x) * 4)
+
+/* CPU has two AHB busses. */
+
+/* Global Arbitration0 Control Register */
+#define GLOBAL_ARBITRATION0_CTRL 0x28
+
+#define BOOT_CONTROLLER_HIGH_PRIO (1 << 3)
+#define DMA_BUS1_HIGH_PRIO (1 << 2)
+#define CPU0_HIGH_PRIO (1 << 0)
+
+/* Global Arbitration1 Control Register */
+#define GLOBAL_ARBITRATION1_CTRL 0x2C
+
+#define TVE_HIGH_PRIO (1 << 9)
+#define PCI_HIGH_PRIO (1 << 8)
+#define USB1_HIGH_PRIO (1 << 7)
+#define USB0_HIGH_PRIO (1 << 6)
+#define GMAC1_HIGH_PRIO (1 << 5)
+#define GMAC0_HIGH_PRIO (1 << 4)
+#define SECURITY_HIGH_PRIO (1 << 3)
+#define RAID_HIGH_PRIO (1 << 2)
+#define IDE_HIGH_PRIO (1 << 1)
+#define DMA_BUS2_HIGH_PRIO (1 << 0)
+
+/* Common bits for both arbitration registers */
+#define BURST_LENGTH_SHIFT 16
+#define BURST_LENGTH_MASK (0x3F << 16)
+
+/* Miscellaneous Control Register */
+#define GLOBAL_MISC_CTRL 0x30
+
+#define MEMORY_SPACE_SWAP (1 << 31)
+#define USB1_PLUG_MINIB (1 << 30) /* else plug is mini-A */
+#define USB0_PLUG_MINIB (1 << 29)
+#define GMAC_GMII (1 << 28)
+#define GMAC_1_ENABLE (1 << 27)
+/* TODO: define ATA/SATA bits */
+#define USB1_VBUS_ON (1 << 23)
+#define USB0_VBUS_ON (1 << 22)
+#define APB_CLKOUT_ENABLE (1 << 21)
+#define TVC_CLKOUT_ENABLE (1 << 20)
+#define EXT_CLKIN_ENABLE (1 << 19)
+#define PCI_66MHZ (1 << 18) /* else 33 MHz */
+#define PCI_CLKOUT_ENABLE (1 << 17)
+#define LPC_CLKOUT_ENABLE (1 << 16)
+#define USB1_WAKEUP_ON (1 << 15)
+#define USB0_WAKEUP_ON (1 << 14)
+/* TODO: define PCI idle detect bits */
+#define TVC_PADS_ENABLE (1 << 9)
+#define SSP_PADS_ENABLE (1 << 8)
+#define LCD_PADS_ENABLE (1 << 7)
+#define LPC_PADS_ENABLE (1 << 6)
+#define PCI_PADS_ENABLE (1 << 5)
+#define IDE_PADS_ENABLE (1 << 4)
+#define DRAM_PADS_POWER_DOWN (1 << 3)
+#define NAND_PADS_DISABLE (1 << 2)
+#define PFLASH_PADS_DISABLE (1 << 1)
+#define SFLASH_PADS_DISABLE (1 << 0)
+
+/* Global Clock Control Register */
+#define GLOBAL_CLOCK_CTRL 0x34
+
+#define POWER_STATE_G0 (1 << 31)
+#define POWER_STATE_S1 (1 << 30) /* else it is S3/S4 state */
+#define SECURITY_APB_AHB (1 << 29)
+/* else Security APB clk will be 0.75xAHB */
+/* TODO: TVC clock divider */
+#define PCI_CLKRUN_ENABLE (1 << 16)
+#define BOOT_CLK_DISABLE (1 << 13)
+#define TVC_CLK_DISABLE (1 << 12)
+#define FLASH_CLK_DISABLE (1 << 11)
+#define DDR_CLK_DISABLE (1 << 10)
+#define PCI_CLK_DISABLE (1 << 9)
+#define IDE_CLK_DISABLE (1 << 8)
+#define USB1_CLK_DISABLE (1 << 7)
+#define USB0_CLK_DISABLE (1 << 6)
+#define SATA1_CLK_DISABLE (1 << 5)
+#define SATA0_CLK_DISABLE (1 << 4)
+#define GMAC1_CLK_DISABLE (1 << 3)
+#define GMAC0_CLK_DISABLE (1 << 2)
+#define SECURITY_CLK_DISABLE (1 << 1)
+
+/* TODO: other registers definitions if needed */
+
+#endif /* __MACH_GLOBAL_REG_H */
diff --git a/arch/arm/mach-gemini/include/mach/gpio.h b/arch/arm/mach-gemini/include/mach/gpio.h
new file mode 100644
index 000000000000..3bc2c70f2989
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/gpio.h
@@ -0,0 +1,25 @@
+/*
+ * Gemini gpiolib specific defines
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __MACH_GPIO_H__
+#define __MACH_GPIO_H__
+
+#include <mach/irqs.h>
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+#define gpio_to_irq(x) ((x) + GPIO_IRQ_BASE)
+#define irq_to_gpio(x) ((x) - GPIO_IRQ_BASE)
+
+#endif /* __MACH_GPIO_H__ */
diff --git a/arch/arm/mach-gemini/include/mach/hardware.h b/arch/arm/mach-gemini/include/mach/hardware.h
new file mode 100644
index 000000000000..de6752674c05
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/hardware.h
@@ -0,0 +1,75 @@
+/*
+ * This file contains the hardware definitions for Gemini.
+ *
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+/*
+ * Memory Map definitions
+ */
+/* FIXME: Does it really swap SRAM like this? */
+#ifdef CONFIG_GEMINI_MEM_SWAP
+# define GEMINI_DRAM_BASE 0x00000000
+# define GEMINI_SRAM_BASE 0x20000000
+#else
+# define GEMINI_SRAM_BASE 0x00000000
+# define GEMINI_DRAM_BASE 0x10000000
+#endif
+#define GEMINI_FLASH_BASE 0x30000000
+#define GEMINI_GLOBAL_BASE 0x40000000
+#define GEMINI_WAQTCHDOG_BASE 0x41000000
+#define GEMINI_UART_BASE 0x42000000
+#define GEMINI_TIMER_BASE 0x43000000
+#define GEMINI_LCD_BASE 0x44000000
+#define GEMINI_RTC_BASE 0x45000000
+#define GEMINI_SATA_BASE 0x46000000
+#define GEMINI_LPC_HOST_BASE 0x47000000
+#define GEMINI_LPC_IO_BASE 0x47800000
+#define GEMINI_INTERRUPT_BASE 0x48000000
+/* TODO: Different interrupt controlers when SMP
+ * #define GEMINI_INTERRUPT0_BASE 0x48000000
+ * #define GEMINI_INTERRUPT1_BASE 0x49000000
+ */
+#define GEMINI_SSP_CTRL_BASE 0x4A000000
+#define GEMINI_POWER_CTRL_BASE 0x4B000000
+#define GEMINI_CIR_BASE 0x4C000000
+#define GEMINI_GPIO_BASE(x) (0x4D000000 + (x) * 0x1000000)
+#define GEMINI_PCI_IO_BASE 0x50000000
+#define GEMINI_PCI_MEM_BASE 0x58000000
+#define GEMINI_TOE_BASE 0x60000000
+#define GEMINI_GMAC0_BASE 0x6000A000
+#define GEMINI_GMAC1_BASE 0x6000E000
+#define GEMINI_SECURITY_BASE 0x62000000
+#define GEMINI_IDE0_BASE 0x63000000
+#define GEMINI_IDE1_BASE 0x63400000
+#define GEMINI_RAID_BASE 0x64000000
+#define GEMINI_FLASH_CTRL_BASE 0x65000000
+#define GEMINI_DRAM_CTRL_BASE 0x66000000
+#define GEMINI_GENERAL_DMA_BASE 0x67000000
+#define GEMINI_USB0_BASE 0x68000000
+#define GEMINI_USB1_BASE 0x69000000
+#define GEMINI_BIG_ENDIAN_BASE 0x80000000
+
+#define GEMINI_TIMER1_BASE GEMINI_TIMER_BASE
+#define GEMINI_TIMER2_BASE (GEMINI_TIMER_BASE + 0x10)
+#define GEMINI_TIMER3_BASE (GEMINI_TIMER_BASE + 0x20)
+
+/*
+ * UART Clock when System clk is 150MHz
+ */
+#define UART_CLK 48000000
+
+/*
+ * macro to get at IO space when running virtually
+ */
+#define IO_ADDRESS(x) ((((x) & 0xFFF00000) >> 4) | ((x) & 0x000FFFFF) | 0xF0000000)
+
+#endif
diff --git a/arch/arm/mach-gemini/include/mach/io.h b/arch/arm/mach-gemini/include/mach/io.h
new file mode 100644
index 000000000000..c548056b98b2
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/io.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __MACH_IO_H
+#define __MACH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif /* __MACH_IO_H */
diff --git a/arch/arm/mach-gemini/include/mach/irqs.h b/arch/arm/mach-gemini/include/mach/irqs.h
new file mode 100644
index 000000000000..06bc47e77e8b
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/irqs.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __MACH_IRQS_H__
+#define __MACH_IRQS_H__
+
+#define IRQ_SERIRQ1 31
+#define IRQ_SERIRQ0 30
+#define IRQ_PCID 29
+#define IRQ_PCIC 28
+#define IRQ_PCIB 27
+#define IRQ_PWR 26
+#define IRQ_CIR 25
+#define IRQ_GPIO(x) (22 + (x))
+#define IRQ_SSP 21
+#define IRQ_LPC 20
+#define IRQ_LCD 19
+#define IRQ_UART 18
+#define IRQ_RTC 17
+#define IRQ_TIMER3 16
+#define IRQ_TIMER2 15
+#define IRQ_TIMER1 14
+#define IRQ_FLASH 12
+#define IRQ_USB1 11
+#define IRQ_USB0 10
+#define IRQ_DMA 9
+#define IRQ_PCI 8
+#define IRQ_IPSEC 7
+#define IRQ_RAID 6
+#define IRQ_IDE1 5
+#define IRQ_IDE0 4
+#define IRQ_WATCHDOG 3
+#define IRQ_GMAC1 2
+#define IRQ_GMAC0 1
+#define IRQ_IPI 0
+
+#define NORMAL_IRQ_NUM 32
+
+#define GPIO_IRQ_BASE NORMAL_IRQ_NUM
+#define GPIO_IRQ_NUM (3 * 32)
+
+#define ARCH_TIMER_IRQ IRQ_TIMER2
+
+#define NR_IRQS (NORMAL_IRQ_NUM + GPIO_IRQ_NUM)
+
+#endif /* __MACH_IRQS_H__ */
diff --git a/arch/arm/mach-gemini/include/mach/memory.h b/arch/arm/mach-gemini/include/mach/memory.h
new file mode 100644
index 000000000000..2d14d5bf1f9f
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/memory.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+#ifdef CONFIG_GEMINI_MEM_SWAP
+# define PHYS_OFFSET UL(0x00000000)
+#else
+# define PHYS_OFFSET UL(0x10000000)
+#endif
+
+#endif /* __MACH_MEMORY_H */
diff --git a/arch/arm/mach-gemini/include/mach/system.h b/arch/arm/mach-gemini/include/mach/system.h
new file mode 100644
index 000000000000..4d9c1f872472
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/system.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/global_reg.h>
+
+static inline void arch_idle(void)
+{
+ /*
+ * Because of broken hardware we have to enable interrupts or the CPU
+ * will never wakeup... Acctualy it is not very good to enable
+ * interrupts here since scheduler can miss a tick, but there is
+ * no other way around this. Platforms that needs it for power saving
+ * should call enable_hlt() in init code, since by default it is
+ * disabled.
+ */
+ local_irq_enable();
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ __raw_writel(RESET_GLOBAL | RESET_CPU1,
+ IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_RESET);
+}
+
+#endif /* __MACH_SYSTEM_H */
diff --git a/arch/arm/mach-gemini/include/mach/timex.h b/arch/arm/mach-gemini/include/mach/timex.h
new file mode 100644
index 000000000000..dc5690ba975c
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/timex.h
@@ -0,0 +1,13 @@
+/*
+ * Gemini timex specifications
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+/* When AHB bus frequency is 150MHz */
+#define CLOCK_TICK_RATE 38000000
diff --git a/arch/arm/mach-gemini/include/mach/uncompress.h b/arch/arm/mach-gemini/include/mach/uncompress.h
new file mode 100644
index 000000000000..59c5df7e716c
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/uncompress.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on mach-pxa/include/mach/uncompress.h:
+ * Copyright: (C) 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __MACH_UNCOMPRESS_H
+#define __MACH_UNCOMPRESS_H
+
+#include <linux/serial_reg.h>
+#include <mach/hardware.h>
+
+static volatile unsigned long *UART = (unsigned long *)GEMINI_UART_BASE;
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader. If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
+ */
+static inline void putc(char c)
+{
+ while (!(UART[UART_LSR] & UART_LSR_THRE))
+ barrier();
+ UART[UART_TX] = c;
+}
+
+#define flush() do { } while (0)
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
+
+#endif /* __MACH_UNCOMPRESS_H */
diff --git a/drivers/usb/misc/phidget.h b/arch/arm/mach-gemini/include/mach/vmalloc.h
index c4011907d431..83e536d9436c 100644
--- a/drivers/usb/misc/phidget.h
+++ b/arch/arm/mach-gemini/include/mach/vmalloc.h
@@ -1,7 +1,5 @@
/*
- * USB Phidgets class
- *
- * Copyright (C) 2006 Sean Young <sean@mess.org>
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -9,4 +7,4 @@
* (at your option) any later version.
*/
-extern struct class *phidget_class;
+#define VMALLOC_END 0xF0000000
diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c
new file mode 100644
index 000000000000..9e613ca8120d
--- /dev/null
+++ b/arch/arm/mach-gemini/irq.c
@@ -0,0 +1,102 @@
+/*
+ * Interrupt routines for Gemini
+ *
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/stddef.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+
+#define IRQ_SOURCE(base_addr) (base_addr + 0x00)
+#define IRQ_MASK(base_addr) (base_addr + 0x04)
+#define IRQ_CLEAR(base_addr) (base_addr + 0x08)
+#define IRQ_TMODE(base_addr) (base_addr + 0x0C)
+#define IRQ_TLEVEL(base_addr) (base_addr + 0x10)
+#define IRQ_STATUS(base_addr) (base_addr + 0x14)
+#define FIQ_SOURCE(base_addr) (base_addr + 0x20)
+#define FIQ_MASK(base_addr) (base_addr + 0x24)
+#define FIQ_CLEAR(base_addr) (base_addr + 0x28)
+#define FIQ_TMODE(base_addr) (base_addr + 0x2C)
+#define FIQ_LEVEL(base_addr) (base_addr + 0x30)
+#define FIQ_STATUS(base_addr) (base_addr + 0x34)
+
+static void gemini_ack_irq(unsigned int irq)
+{
+ __raw_writel(1 << irq, IRQ_CLEAR(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+}
+
+static void gemini_mask_irq(unsigned int irq)
+{
+ unsigned int mask;
+
+ mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+ mask &= ~(1 << irq);
+ __raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+}
+
+static void gemini_unmask_irq(unsigned int irq)
+{
+ unsigned int mask;
+
+ mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+ mask |= (1 << irq);
+ __raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+}
+
+static struct irq_chip gemini_irq_chip = {
+ .name = "INTC",
+ .ack = gemini_ack_irq,
+ .mask = gemini_mask_irq,
+ .unmask = gemini_unmask_irq,
+};
+
+static struct resource irq_resource = {
+ .name = "irq_handler",
+ .start = IO_ADDRESS(GEMINI_INTERRUPT_BASE),
+ .end = IO_ADDRESS(FIQ_STATUS(GEMINI_INTERRUPT_BASE)) + 4,
+};
+
+void __init gemini_init_irq(void)
+{
+ unsigned int i, mode = 0, level = 0;
+
+ /*
+ * Disable arch_idle() by default since it is buggy
+ * For more info see arch/arm/mach-gemini/include/mach/system.h
+ */
+ disable_hlt();
+
+ request_resource(&iomem_resource, &irq_resource);
+
+ for (i = 0; i < NR_IRQS; i++) {
+ set_irq_chip(i, &gemini_irq_chip);
+ if((i >= IRQ_TIMER1 && i <= IRQ_TIMER3) || (i >= IRQ_SERIRQ0 && i <= IRQ_SERIRQ1)) {
+ set_irq_handler(i, handle_edge_irq);
+ mode |= 1 << i;
+ level |= 1 << i;
+ } else {
+ set_irq_handler(i, handle_level_irq);
+ }
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ }
+
+ /* Disable all interrupts */
+ __raw_writel(0, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+ __raw_writel(0, FIQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+
+ /* Set interrupt mode */
+ __raw_writel(mode, IRQ_TMODE(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+ __raw_writel(level, IRQ_TLEVEL(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+}
diff --git a/arch/arm/mach-gemini/mm.c b/arch/arm/mach-gemini/mm.c
new file mode 100644
index 000000000000..51948242ec09
--- /dev/null
+++ b/arch/arm/mach-gemini/mm.c
@@ -0,0 +1,82 @@
+/*
+ * Static mappings for Gemini
+ *
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+
+/* Page table mapping for I/O region */
+static struct map_desc gemini_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(GEMINI_GLOBAL_BASE),
+ .pfn =__phys_to_pfn(GEMINI_GLOBAL_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_UART_BASE),
+ .pfn = __phys_to_pfn(GEMINI_UART_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_TIMER_BASE),
+ .pfn = __phys_to_pfn(GEMINI_TIMER_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_INTERRUPT_BASE),
+ .pfn = __phys_to_pfn(GEMINI_INTERRUPT_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_POWER_CTRL_BASE),
+ .pfn = __phys_to_pfn(GEMINI_POWER_CTRL_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_GPIO_BASE(0)),
+ .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(0)),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_GPIO_BASE(1)),
+ .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(1)),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_GPIO_BASE(2)),
+ .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(2)),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_FLASH_CTRL_BASE),
+ .pfn = __phys_to_pfn(GEMINI_FLASH_CTRL_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_DRAM_CTRL_BASE),
+ .pfn = __phys_to_pfn(GEMINI_DRAM_CTRL_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_GENERAL_DMA_BASE),
+ .pfn = __phys_to_pfn(GEMINI_GENERAL_DMA_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init gemini_map_io(void)
+{
+ iotable_init(gemini_io_desc, ARRAY_SIZE(gemini_io_desc));
+}
diff --git a/arch/arm/mach-gemini/time.c b/arch/arm/mach-gemini/time.c
new file mode 100644
index 000000000000..21dc5a89d1c4
--- /dev/null
+++ b/arch/arm/mach-gemini/time.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/global_reg.h>
+#include <asm/mach/time.h>
+
+/*
+ * Register definitions for the timers
+ */
+#define TIMER_COUNT(BASE_ADDR) (BASE_ADDR + 0x00)
+#define TIMER_LOAD(BASE_ADDR) (BASE_ADDR + 0x04)
+#define TIMER_MATCH1(BASE_ADDR) (BASE_ADDR + 0x08)
+#define TIMER_MATCH2(BASE_ADDR) (BASE_ADDR + 0x0C)
+#define TIMER_CR(BASE_ADDR) (BASE_ADDR + 0x30)
+
+#define TIMER_1_CR_ENABLE (1 << 0)
+#define TIMER_1_CR_CLOCK (1 << 1)
+#define TIMER_1_CR_INT (1 << 2)
+#define TIMER_2_CR_ENABLE (1 << 3)
+#define TIMER_2_CR_CLOCK (1 << 4)
+#define TIMER_2_CR_INT (1 << 5)
+#define TIMER_3_CR_ENABLE (1 << 6)
+#define TIMER_3_CR_CLOCK (1 << 7)
+#define TIMER_3_CR_INT (1 << 8)
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t gemini_timer_interrupt(int irq, void *dev_id)
+{
+ timer_tick();
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction gemini_timer_irq = {
+ .name = "Gemini Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = gemini_timer_interrupt,
+};
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+void __init gemini_timer_init(void)
+{
+ unsigned int tick_rate, reg_v;
+
+ reg_v = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS));
+ tick_rate = REG_TO_AHB_SPEED(reg_v) * 1000000;
+
+ printk(KERN_INFO "Bus: %dMHz", tick_rate / 1000000);
+
+ tick_rate /= 6; /* APB bus run AHB*(1/6) */
+
+ switch(reg_v & CPU_AHB_RATIO_MASK) {
+ case CPU_AHB_1_1:
+ printk(KERN_CONT "(1/1)\n");
+ break;
+ case CPU_AHB_3_2:
+ printk(KERN_CONT "(3/2)\n");
+ break;
+ case CPU_AHB_24_13:
+ printk(KERN_CONT "(24/13)\n");
+ break;
+ case CPU_AHB_2_1:
+ printk(KERN_CONT "(2/1)\n");
+ break;
+ }
+
+ /*
+ * Make irqs happen for the system timer
+ */
+ setup_irq(IRQ_TIMER2, &gemini_timer_irq);
+ /* Start the timer */
+ __raw_writel(tick_rate / HZ, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+ __raw_writel(tick_rate / HZ, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+ __raw_writel(TIMER_2_CR_ENABLE | TIMER_2_CR_INT, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+}
diff --git a/arch/arm/mach-h720x/include/mach/system.h b/arch/arm/mach-h720x/include/mach/system.h
index e4a7c760d52a..a708d24ee46d 100644
--- a/arch/arm/mach-h720x/include/mach/system.h
+++ b/arch/arm/mach-h720x/include/mach/system.h
@@ -25,7 +25,7 @@ static void arch_idle(void)
}
-static __inline__ void arch_reset(char mode)
+static __inline__ void arch_reset(char mode, const char *cmd)
{
CPU_REG (PMU_BASE, PMU_STAT) |= PMU_WARMRESET;
}
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
index 887cb21f75b0..05f1739ee127 100644
--- a/arch/arm/mach-imx/generic.c
+++ b/arch/arm/mach-imx/generic.c
@@ -29,7 +29,6 @@
#include <linux/string.h>
#include <asm/errno.h>
-#include <mach/imxfb.h>
#include <mach/hardware.h>
#include <mach/imx-regs.h>
@@ -245,43 +244,8 @@ void __init imx_set_mmc_info(struct imxmmc_platform_data *info)
imx_mmc_device.dev.platform_data = info;
}
-static struct imx_fb_platform_data imx_fb_info;
-
-void __init set_imx_fb_info(struct imx_fb_platform_data *hard_imx_fb_info)
-{
- memcpy(&imx_fb_info,hard_imx_fb_info,sizeof(struct imx_fb_platform_data));
-}
-
-static struct resource imxfb_resources[] = {
- [0] = {
- .start = 0x00205000,
- .end = 0x002050FF,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = LCDC_INT,
- .end = LCDC_INT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static u64 fb_dma_mask = ~(u64)0;
-
-static struct platform_device imxfb_device = {
- .name = "imx-fb",
- .id = 0,
- .dev = {
- .platform_data = &imx_fb_info,
- .dma_mask = &fb_dma_mask,
- .coherent_dma_mask = 0xffffffff,
- },
- .num_resources = ARRAY_SIZE(imxfb_resources),
- .resource = imxfb_resources,
-};
-
static struct platform_device *devices[] __initdata = {
&imx_mmc_device,
- &imxfb_device,
};
static struct map_desc imx_io_desc[] __initdata = {
diff --git a/arch/arm/mach-imx/include/mach/system.h b/arch/arm/mach-imx/include/mach/system.h
index adee7e51bab2..46d4ca91af79 100644
--- a/arch/arm/mach-imx/include/mach/system.h
+++ b/arch/arm/mach-imx/include/mach/system.h
@@ -32,7 +32,7 @@ arch_idle(void)
}
static inline void
-arch_reset(char mode)
+arch_reset(char mode, const char *cmd)
{
cpu_reset(0);
}
diff --git a/arch/arm/mach-integrator/include/mach/system.h b/arch/arm/mach-integrator/include/mach/system.h
index c485345c8c77..e1551b8dab77 100644
--- a/arch/arm/mach-integrator/include/mach/system.h
+++ b/arch/arm/mach-integrator/include/mach/system.h
@@ -32,7 +32,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
/*
* To reset, we hit the on-board reset register
diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h
index e012bf13c955..42ae29b288a1 100644
--- a/arch/arm/mach-iop13xx/include/mach/memory.h
+++ b/arch/arm/mach-iop13xx/include/mach/memory.h
@@ -59,7 +59,10 @@ static inline unsigned long __lbus_to_virt(dma_addr_t x)
})
#define __arch_page_to_dma(dev, page) \
- __arch_virt_to_dma(dev, page_address(page))
+ ({ \
+ /* __is_lbus_virt() can never be true for RAM pages */ \
+ (dma_addr_t)page_to_phys(page); \
+ })
#endif /* CONFIG_ARCH_IOP13XX */
#endif /* !ASSEMBLY */
diff --git a/arch/arm/mach-iop13xx/include/mach/system.h b/arch/arm/mach-iop13xx/include/mach/system.h
index c7127f416e1f..d0c66ef450a7 100644
--- a/arch/arm/mach-iop13xx/include/mach/system.h
+++ b/arch/arm/mach-iop13xx/include/mach/system.h
@@ -13,7 +13,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
/*
* Reset the internal bus (warning both cores are reset)
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index 673b0db22034..4873f26a42e1 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -1026,8 +1026,10 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
which_atu = 0;
}
- if (!which_atu)
+ if (!which_atu) {
+ kfree(res);
return 0;
+ }
switch(which_atu) {
case IOP13XX_INIT_ATU_ATUX:
@@ -1074,6 +1076,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
sys->map_irq = iop13xx_pcie_map_irq;
break;
default:
+ kfree(res);
return 0;
}
diff --git a/arch/arm/mach-iop32x/include/mach/system.h b/arch/arm/mach-iop32x/include/mach/system.h
index 32d9e5b0a28d..a4b808fe0d81 100644
--- a/arch/arm/mach-iop32x/include/mach/system.h
+++ b/arch/arm/mach-iop32x/include/mach/system.h
@@ -16,7 +16,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
local_irq_disable();
diff --git a/arch/arm/mach-iop33x/include/mach/system.h b/arch/arm/mach-iop33x/include/mach/system.h
index 0cb3ad862acd..f192a34be073 100644
--- a/arch/arm/mach-iop33x/include/mach/system.h
+++ b/arch/arm/mach-iop33x/include/mach/system.h
@@ -14,7 +14,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
*IOP3XX_PCSR = 0x30;
diff --git a/arch/arm/mach-ixp2000/include/mach/system.h b/arch/arm/mach-ixp2000/include/mach/system.h
index 2e9c68f95a24..de370992c848 100644
--- a/arch/arm/mach-ixp2000/include/mach/system.h
+++ b/arch/arm/mach-ixp2000/include/mach/system.h
@@ -17,7 +17,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
local_irq_disable();
diff --git a/arch/arm/mach-ixp23xx/include/mach/system.h b/arch/arm/mach-ixp23xx/include/mach/system.h
index d57c3fc10f1f..8920ff2dff1f 100644
--- a/arch/arm/mach-ixp23xx/include/mach/system.h
+++ b/arch/arm/mach-ixp23xx/include/mach/system.h
@@ -19,7 +19,7 @@ static inline void arch_idle(void)
#endif
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
/* First try machine specific support */
if (machine_is_ixdp2351()) {
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index d816c51320c7..70afcfe5b881 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -366,7 +366,7 @@ void __init ixp4xx_adjust_zones(int node, unsigned long *zone_size,
}
void __init ixp4xx_pci_preinit(void)
-{
+{
unsigned long cpuid = read_cpuid_id();
/*
@@ -386,17 +386,17 @@ void __init ixp4xx_pci_preinit(void)
pr_debug("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n");
- /*
+ /*
* We use identity AHB->PCI address translation
* in the 0x48000000 to 0x4bffffff address space
*/
*PCI_PCIMEMBASE = 0x48494A4B;
- /*
+ /*
* We also use identity PCI->AHB address translation
* in 4 16MB BARs that begin at the physical memory start
*/
- *PCI_AHBMEMBASE = (PHYS_OFFSET & 0xFF000000) +
+ *PCI_AHBMEMBASE = (PHYS_OFFSET & 0xFF000000) +
((PHYS_OFFSET & 0xFF000000) >> 8) +
((PHYS_OFFSET & 0xFF000000) >> 16) +
((PHYS_OFFSET & 0xFF000000) >> 24) +
@@ -408,18 +408,19 @@ void __init ixp4xx_pci_preinit(void)
pr_debug("setup BARs in controller\n");
/*
- * We configure the PCI inbound memory windows to be
+ * We configure the PCI inbound memory windows to be
* 1:1 mapped to SDRAM
*/
- local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET + 0x00000000);
- local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + 0x01000000);
- local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + 0x02000000);
- local_write_config(PCI_BASE_ADDRESS_3, 4, PHYS_OFFSET + 0x03000000);
+ local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET);
+ local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + SZ_16M);
+ local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + SZ_32M);
+ local_write_config(PCI_BASE_ADDRESS_3, 4, PHYS_OFFSET + SZ_48M);
/*
- * Enable CSR window at 0xff000000.
+ * Enable CSR window at 64 MiB to allow PCI masters
+ * to continue prefetching past 64 MiB boundary.
*/
- local_write_config(PCI_BASE_ADDRESS_4, 4, 0xff000008);
+ local_write_config(PCI_BASE_ADDRESS_4, 4, PHYS_OFFSET + SZ_64M);
/*
* Enable the IO window to be way up high, at 0xfffffc00
@@ -500,7 +501,7 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys)
return 1;
}
-struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys)
+struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys)
{
return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys);
}
diff --git a/arch/arm/mach-ixp4xx/include/mach/cpu.h b/arch/arm/mach-ixp4xx/include/mach/cpu.h
index 51bd69c46d94..def7773be67c 100644
--- a/arch/arm/mach-ixp4xx/include/mach/cpu.h
+++ b/arch/arm/mach-ixp4xx/include/mach/cpu.h
@@ -17,26 +17,31 @@
#include <asm/cputype.h>
/* Processor id value in CP15 Register 0 */
-#define IXP425_PROCESSOR_ID_VALUE 0x690541c0
-#define IXP435_PROCESSOR_ID_VALUE 0x69054040
-#define IXP465_PROCESSOR_ID_VALUE 0x69054200
-#define IXP4XX_PROCESSOR_ID_MASK 0xfffffff0
-
-#define cpu_is_ixp42x() ((read_cpuid_id() & IXP4XX_PROCESSOR_ID_MASK) == \
- IXP425_PROCESSOR_ID_VALUE)
-#define cpu_is_ixp43x() ((read_cpuid_id() & IXP4XX_PROCESSOR_ID_MASK) == \
- IXP435_PROCESSOR_ID_VALUE)
-#define cpu_is_ixp46x() ((read_cpuid_id() & IXP4XX_PROCESSOR_ID_MASK) == \
- IXP465_PROCESSOR_ID_VALUE)
+#define IXP42X_PROCESSOR_ID_VALUE 0x690541c0 /* including unused 0x690541Ex */
+#define IXP42X_PROCESSOR_ID_MASK 0xffffffc0
+
+#define IXP43X_PROCESSOR_ID_VALUE 0x69054040
+#define IXP43X_PROCESSOR_ID_MASK 0xfffffff0
+
+#define IXP46X_PROCESSOR_ID_VALUE 0x69054200 /* including IXP455 */
+#define IXP46X_PROCESSOR_ID_MASK 0xfffffff0
+
+#define cpu_is_ixp42x() ((read_cpuid_id() & IXP42X_PROCESSOR_ID_MASK) == \
+ IXP42X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp43x() ((read_cpuid_id() & IXP43X_PROCESSOR_ID_MASK) == \
+ IXP43X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp46x() ((read_cpuid_id() & IXP46X_PROCESSOR_ID_MASK) == \
+ IXP46X_PROCESSOR_ID_VALUE)
static inline u32 ixp4xx_read_feature_bits(void)
{
unsigned int val = ~*IXP4XX_EXP_CFG2;
- val &= ~IXP4XX_FEATURE_RESERVED;
- if (!cpu_is_ixp46x())
- val &= ~IXP4XX_FEATURE_IXP46X_ONLY;
- return val;
+ if (cpu_is_ixp42x())
+ return val & IXP42X_FEATURE_MASK;
+ if (cpu_is_ixp43x())
+ return val & IXP43X_FEATURE_MASK;
+ return val & IXP46X_FEATURE_MASK;
}
static inline void ixp4xx_write_feature_bits(u32 value)
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
index ad9c888dd850..97c530f66e78 100644
--- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
@@ -604,6 +604,7 @@
#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
/* "fuse" bits of IXP_EXP_CFG2 */
+/* All IXP4xx CPUs */
#define IXP4XX_FEATURE_RCOMP (1 << 0)
#define IXP4XX_FEATURE_USB_DEVICE (1 << 1)
#define IXP4XX_FEATURE_HASH (1 << 2)
@@ -619,20 +620,41 @@
#define IXP4XX_FEATURE_RESET_NPEB (1 << 12)
#define IXP4XX_FEATURE_RESET_NPEC (1 << 13)
#define IXP4XX_FEATURE_PCI (1 << 14)
-#define IXP4XX_FEATURE_ECC_TIMESYNC (1 << 15)
#define IXP4XX_FEATURE_UTOPIA_PHY_LIMIT (3 << 16)
+#define IXP4XX_FEATURE_XSCALE_MAX_FREQ (3 << 22)
+#define IXP42X_FEATURE_MASK (IXP4XX_FEATURE_RCOMP | \
+ IXP4XX_FEATURE_USB_DEVICE | \
+ IXP4XX_FEATURE_HASH | \
+ IXP4XX_FEATURE_AES | \
+ IXP4XX_FEATURE_DES | \
+ IXP4XX_FEATURE_HDLC | \
+ IXP4XX_FEATURE_AAL | \
+ IXP4XX_FEATURE_HSS | \
+ IXP4XX_FEATURE_UTOPIA | \
+ IXP4XX_FEATURE_NPEB_ETH0 | \
+ IXP4XX_FEATURE_NPEC_ETH | \
+ IXP4XX_FEATURE_RESET_NPEA | \
+ IXP4XX_FEATURE_RESET_NPEB | \
+ IXP4XX_FEATURE_RESET_NPEC | \
+ IXP4XX_FEATURE_PCI | \
+ IXP4XX_FEATURE_UTOPIA_PHY_LIMIT | \
+ IXP4XX_FEATURE_XSCALE_MAX_FREQ)
+
+
+/* IXP43x/46x CPUs */
+#define IXP4XX_FEATURE_ECC_TIMESYNC (1 << 15)
#define IXP4XX_FEATURE_USB_HOST (1 << 18)
#define IXP4XX_FEATURE_NPEA_ETH (1 << 19)
+#define IXP43X_FEATURE_MASK (IXP42X_FEATURE_MASK | \
+ IXP4XX_FEATURE_ECC_TIMESYNC | \
+ IXP4XX_FEATURE_USB_HOST | \
+ IXP4XX_FEATURE_NPEA_ETH)
+
+/* IXP46x CPU (including IXP455) only */
#define IXP4XX_FEATURE_NPEB_ETH_1_TO_3 (1 << 20)
#define IXP4XX_FEATURE_RSA (1 << 21)
-#define IXP4XX_FEATURE_XSCALE_MAX_FREQ (3 << 22)
-#define IXP4XX_FEATURE_RESERVED (0xFF << 24)
-
-#define IXP4XX_FEATURE_IXP46X_ONLY (IXP4XX_FEATURE_ECC_TIMESYNC | \
- IXP4XX_FEATURE_USB_HOST | \
- IXP4XX_FEATURE_NPEA_ETH | \
- IXP4XX_FEATURE_NPEB_ETH_1_TO_3 | \
- IXP4XX_FEATURE_RSA | \
- IXP4XX_FEATURE_XSCALE_MAX_FREQ)
+#define IXP46X_FEATURE_MASK (IXP43X_FEATURE_MASK | \
+ IXP4XX_FEATURE_NPEB_ETH_1_TO_3 | \
+ IXP4XX_FEATURE_RSA)
#endif
diff --git a/arch/arm/mach-ixp4xx/include/mach/system.h b/arch/arm/mach-ixp4xx/include/mach/system.h
index 92a7e8ddf69a..d2aa26f5acd7 100644
--- a/arch/arm/mach-ixp4xx/include/mach/system.h
+++ b/arch/arm/mach-ixp4xx/include/mach/system.h
@@ -20,7 +20,7 @@ static inline void arch_idle(void)
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
if ( 1 && mode == 's') {
/* Jump into ROM at address 0 */
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_npe.c b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
index c73a94d0ca2b..252310234903 100644
--- a/arch/arm/mach-ixp4xx/ixp4xx_npe.c
+++ b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
@@ -575,8 +575,8 @@ int npe_load_firmware(struct npe *npe, const char *name, struct device *dev)
for (i = 0; i < image->size; i++)
image->data[i] = swab32(image->data[i]);
- if (!cpu_is_ixp46x() && ((image->id >> 28) & 0xF /* device ID */)) {
- print_npe(KERN_INFO, npe, "IXP46x firmware ignored on "
+ if (cpu_is_ixp42x() && ((image->id >> 28) & 0xF /* device ID */)) {
+ print_npe(KERN_INFO, npe, "IXP43x/IXP46x firmware ignored on "
"IXP42x\n");
goto err;
}
@@ -596,7 +596,7 @@ int npe_load_firmware(struct npe *npe, const char *name, struct device *dev)
"revision 0x%X:%X\n", (image->id >> 16) & 0xFF,
(image->id >> 8) & 0xFF, image->id & 0xFF);
- if (!cpu_is_ixp46x()) {
+ if (cpu_is_ixp42x()) {
if (!npe->id)
instr_size = NPE_A_42X_INSTR_SIZE;
else
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index 3600cd9f0519..b5421cccd7e1 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -20,6 +20,18 @@ config MACH_RD88F6281
Say 'Y' here if you want your kernel to support the
Marvell RD-88F6281 Reference Board.
+config MACH_SHEEVAPLUG
+ bool "Marvell SheevaPlug Reference Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell SheevaPlug Reference Board.
+
+config MACH_TS219
+ bool "QNAP TS-119 and TS-219 Turbo NAS"
+ help
+ Say 'Y' here if you want your kernel to support the
+ QNAP TS-119 and TS-219 Turbo NAS devices.
+
endmenu
endif
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index b96c55dad343..8f03c9b9bdd9 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -1,5 +1,7 @@
-obj-y += common.o addr-map.o irq.o pcie.o
+obj-y += common.o addr-map.o irq.o pcie.o mpp.o
obj-$(CONFIG_MACH_DB88F6281_BP) += db88f6281-bp-setup.o
obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6192-nas-setup.o
obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o
+obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o
+obj-$(CONFIG_MACH_TS219) += ts219-setup.o
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index b3404b7775b3..3d2fae846512 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -14,6 +14,7 @@
#include <linux/serial_8250.h>
#include <linux/mbus.h>
#include <linux/mv643xx_eth.h>
+#include <linux/mv643xx_i2c.h>
#include <linux/ata_platform.h>
#include <linux/spi/orion_spi.h>
#include <net/dsa.h>
@@ -24,6 +25,7 @@
#include <mach/kirkwood.h>
#include <plat/cache-feroceon-l2.h>
#include <plat/ehci-orion.h>
+#include <plat/mvsdio.h>
#include <plat/mv_xor.h>
#include <plat/orion_nand.h>
#include <plat/time.h>
@@ -231,14 +233,17 @@ static struct platform_device kirkwood_switch_device = {
void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq)
{
+ int i;
+
if (irq != NO_IRQ) {
kirkwood_switch_resources[0].start = irq;
kirkwood_switch_resources[0].end = irq;
kirkwood_switch_device.num_resources = 1;
}
- d->mii_bus = &kirkwood_ge00_shared.dev;
d->netdev = &kirkwood_ge00.dev;
+ for (i = 0; i < d->nr_chips; i++)
+ d->chip[i].mii_bus = &kirkwood_ge00_shared.dev;
kirkwood_switch_device.dev.platform_data = d;
platform_device_register(&kirkwood_switch_device);
@@ -254,7 +259,7 @@ static struct resource kirkwood_rtc_resource = {
.flags = IORESOURCE_MEM,
};
-void __init kirkwood_rtc_init(void)
+static void __init kirkwood_rtc_init(void)
{
platform_device_register_simple("rtc-mv", -1, &kirkwood_rtc_resource, 1);
}
@@ -296,6 +301,50 @@ void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
/*****************************************************************************
+ * SD/SDIO/MMC
+ ****************************************************************************/
+static struct resource mvsdio_resources[] = {
+ [0] = {
+ .start = SDIO_PHYS_BASE,
+ .end = SDIO_PHYS_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_KIRKWOOD_SDIO,
+ .end = IRQ_KIRKWOOD_SDIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 mvsdio_dmamask = 0xffffffffUL;
+
+static struct platform_device kirkwood_sdio = {
+ .name = "mvsdio",
+ .id = -1,
+ .dev = {
+ .dma_mask = &mvsdio_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(mvsdio_resources),
+ .resource = mvsdio_resources,
+};
+
+void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
+{
+ u32 dev, rev;
+
+ kirkwood_pcie_id(&dev, &rev);
+ if (rev == 0) /* catch all Kirkwood Z0's */
+ mvsdio_data->clock = 100000000;
+ else
+ mvsdio_data->clock = 200000000;
+ mvsdio_data->dram = &kirkwood_mbus_dram_info;
+ kirkwood_sdio.dev.platform_data = mvsdio_data;
+ platform_device_register(&kirkwood_sdio);
+}
+
+
+/*****************************************************************************
* SPI
****************************************************************************/
static struct orion_spi_info kirkwood_spi_plat_data = {
@@ -326,6 +375,45 @@ void __init kirkwood_spi_init()
/*****************************************************************************
+ * I2C
+ ****************************************************************************/
+static struct mv64xxx_i2c_pdata kirkwood_i2c_pdata = {
+ .freq_m = 8, /* assumes 166 MHz TCLK */
+ .freq_n = 3,
+ .timeout = 1000, /* Default timeout of 1 second */
+};
+
+static struct resource kirkwood_i2c_resources[] = {
+ {
+ .name = "i2c",
+ .start = I2C_PHYS_BASE,
+ .end = I2C_PHYS_BASE + 0x1f,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "i2c",
+ .start = IRQ_KIRKWOOD_TWSI,
+ .end = IRQ_KIRKWOOD_TWSI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device kirkwood_i2c = {
+ .name = MV64XXX_I2C_CTLR_NAME,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(kirkwood_i2c_resources),
+ .resource = kirkwood_i2c_resources,
+ .dev = {
+ .platform_data = &kirkwood_i2c_pdata,
+ },
+};
+
+void __init kirkwood_i2c_init(void)
+{
+ platform_device_register(&kirkwood_i2c);
+}
+
+
+/*****************************************************************************
* UART0
****************************************************************************/
static struct plat_serial8250_port kirkwood_uart0_data[] = {
@@ -502,7 +590,7 @@ static struct platform_device kirkwood_xor01_channel = {
},
};
-void __init kirkwood_xor0_init(void)
+static void __init kirkwood_xor0_init(void)
{
platform_device_register(&kirkwood_xor0_shared);
@@ -600,7 +688,7 @@ static struct platform_device kirkwood_xor11_channel = {
},
};
-void __init kirkwood_xor1_init(void)
+static void __init kirkwood_xor1_init(void)
{
platform_device_register(&kirkwood_xor1_shared);
@@ -708,4 +796,9 @@ void __init kirkwood_init(void)
#ifdef CONFIG_CACHE_FEROCEON_L2
kirkwood_l2_init();
#endif
+
+ /* internal devices that every board has */
+ kirkwood_rtc_init();
+ kirkwood_xor0_init();
+ kirkwood_xor1_init();
}
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index fe367c18e722..6ee88406f381 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -14,6 +14,7 @@
struct dsa_platform_data;
struct mv643xx_eth_platform_data;
struct mv_sata_platform_data;
+struct mvsdio_platform_data;
/*
* Basic Kirkwood init functions used early by machine-setup.
@@ -33,14 +34,14 @@ void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data);
void kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data);
void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq);
void kirkwood_pcie_init(void);
-void kirkwood_rtc_init(void);
void kirkwood_sata_init(struct mv_sata_platform_data *sata_data);
+void kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data);
void kirkwood_spi_init(void);
+void kirkwood_i2c_init(void);
void kirkwood_uart0_init(void);
void kirkwood_uart1_init(void);
-void kirkwood_xor0_init(void);
-void kirkwood_xor1_init(void);
+extern int kirkwood_tclk;
extern struct sys_timer kirkwood_timer;
diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
index a14c2948c62a..5505d5837752 100644
--- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
+++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
@@ -11,18 +11,59 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/pci.h>
-#include <linux/irq.h>
-#include <linux/mtd/physmap.h>
#include <linux/mtd/nand.h>
-#include <linux/timer.h>
+#include <linux/mtd/partitions.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <asm/mach/pci.h>
#include <mach/kirkwood.h>
+#include <plat/orion_nand.h>
+#include <plat/mvsdio.h>
#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition db88f6281_nand_parts[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = SZ_1M
+ }, {
+ .name = "uImage",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_4M
+ }, {
+ .name = "root",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static struct resource db88f6281_nand_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = KIRKWOOD_NAND_MEM_PHYS_BASE,
+ .end = KIRKWOOD_NAND_MEM_PHYS_BASE +
+ KIRKWOOD_NAND_MEM_SIZE - 1,
+};
+
+static struct orion_nand_data db88f6281_nand_data = {
+ .parts = db88f6281_nand_parts,
+ .nr_parts = ARRAY_SIZE(db88f6281_nand_parts),
+ .cle = 0,
+ .ale = 1,
+ .width = 8,
+ .chip_delay = 25,
+};
+
+static struct platform_device db88f6281_nand_flash = {
+ .name = "orion_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &db88f6281_nand_data,
+ },
+ .resource = &db88f6281_nand_resource,
+ .num_resources = 1,
+};
static struct mv643xx_eth_platform_data db88f6281_ge00_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
@@ -32,18 +73,32 @@ static struct mv_sata_platform_data db88f6281_sata_data = {
.n_ports = 2,
};
+static struct mvsdio_platform_data db88f6281_mvsdio_data = {
+ .gpio_write_protect = 37,
+ .gpio_card_detect = 38,
+};
+
+static unsigned int db88f6281_mpp_config[] __initdata = {
+ MPP37_GPIO,
+ MPP38_GPIO,
+ 0
+};
+
static void __init db88f6281_init(void)
{
/*
* Basic setup. Needs to be called early.
*/
kirkwood_init();
+ kirkwood_mpp_conf(db88f6281_mpp_config);
kirkwood_ehci_init();
kirkwood_ge00_init(&db88f6281_ge00_data);
- kirkwood_rtc_init();
kirkwood_sata_init(&db88f6281_sata_data);
kirkwood_uart0_init();
+ kirkwood_sdio_init(&db88f6281_mvsdio_data);
+
+ platform_device_register(&db88f6281_nand_flash);
}
static int __init db88f6281_pci_init(void)
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index ada480c0e197..38c986853590 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -93,6 +93,7 @@
#define DEVICE_ID (DEV_BUS_VIRT_BASE | 0x0034)
#define RTC_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x0300)
#define SPI_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x0600)
+#define I2C_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x1000)
#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2000)
#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2000)
#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2100)
@@ -116,5 +117,7 @@
#define SATA_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x80000)
+#define SDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x90000)
+
#endif
diff --git a/arch/arm/mach-kirkwood/include/mach/system.h b/arch/arm/mach-kirkwood/include/mach/system.h
index 8510f6cfdabf..23a1914c1da8 100644
--- a/arch/arm/mach-kirkwood/include/mach/system.h
+++ b/arch/arm/mach-kirkwood/include/mach/system.h
@@ -17,7 +17,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
/*
* Enable soft reset to assert RSTOUTn.
diff --git a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c
new file mode 100644
index 000000000000..63c44934391a
--- /dev/null
+++ b/arch/arm/mach-kirkwood/mpp.c
@@ -0,0 +1,97 @@
+/*
+ * arch/arm/mach-kirkwood/mpp.c
+ *
+ * MPP functions for Marvell Kirkwood SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <asm/gpio.h>
+#include <mach/hardware.h>
+#include "common.h"
+#include "mpp.h"
+
+static unsigned int __init kirkwood_variant(void)
+{
+ u32 dev, rev;
+
+ kirkwood_pcie_id(&dev, &rev);
+
+ if (dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0)
+ return MPP_F6281_MASK;
+ if (dev == MV88F6192_DEV_ID && rev >= MV88F6192_REV_A0)
+ return MPP_F6192_MASK;
+ if (dev == MV88F6180_DEV_ID)
+ return MPP_F6180_MASK;
+
+ printk(KERN_ERR "MPP setup: unknown kirkwood variant "
+ "(dev %#x rev %#x)\n", dev, rev);
+ return 0;
+}
+
+#define MPP_CTRL(i) (DEV_BUS_VIRT_BASE + (i) * 4)
+#define MPP_NR_REGS (1 + MPP_MAX/8)
+
+void __init kirkwood_mpp_conf(unsigned int *mpp_list)
+{
+ u32 mpp_ctrl[MPP_NR_REGS];
+ unsigned int variant_mask;
+ int i;
+
+ variant_mask = kirkwood_variant();
+ if (!variant_mask)
+ return;
+
+ printk(KERN_DEBUG "initial MPP regs:");
+ for (i = 0; i < MPP_NR_REGS; i++) {
+ mpp_ctrl[i] = readl(MPP_CTRL(i));
+ printk(" %08x", mpp_ctrl[i]);
+ }
+ printk("\n");
+
+ while (*mpp_list) {
+ unsigned int num = MPP_NUM(*mpp_list);
+ unsigned int sel = MPP_SEL(*mpp_list);
+ int shift, gpio_mode;
+
+ if (num > MPP_MAX) {
+ printk(KERN_ERR "kirkwood_mpp_conf: invalid MPP "
+ "number (%u)\n", num);
+ continue;
+ }
+ if (!(*mpp_list & variant_mask)) {
+ printk(KERN_WARNING
+ "kirkwood_mpp_conf: requested MPP%u config "
+ "unavailable on this hardware\n", num);
+ continue;
+ }
+
+ shift = (num & 7) << 2;
+ mpp_ctrl[num / 8] &= ~(0xf << shift);
+ mpp_ctrl[num / 8] |= sel << shift;
+
+ gpio_mode = 0;
+ if (*mpp_list & MPP_INPUT_MASK)
+ gpio_mode |= GPIO_INPUT_OK;
+ if (*mpp_list & MPP_OUTPUT_MASK)
+ gpio_mode |= GPIO_OUTPUT_OK;
+ if (sel != 0)
+ gpio_mode = 0;
+ orion_gpio_set_valid(num, gpio_mode);
+
+ mpp_list++;
+ }
+
+ printk(KERN_DEBUG " final MPP regs:");
+ for (i = 0; i < MPP_NR_REGS; i++) {
+ writel(mpp_ctrl[i], MPP_CTRL(i));
+ printk(" %08x", mpp_ctrl[i]);
+ }
+ printk("\n");
+}
diff --git a/arch/arm/mach-kirkwood/mpp.h b/arch/arm/mach-kirkwood/mpp.h
new file mode 100644
index 000000000000..e021a80c2caf
--- /dev/null
+++ b/arch/arm/mach-kirkwood/mpp.h
@@ -0,0 +1,303 @@
+/*
+ * linux/arch/arm/mach-kirkwood/mpp.h -- Multi Purpose Pins
+ *
+ * Copyright 2009: Marvell Technology Group Ltd.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __KIRKWOOD_MPP_H
+#define __KIRKWOOD_MPP_H
+
+#define MPP(_num, _sel, _in, _out, _F6180, _F6190, _F6192, _F6281) ( \
+ /* MPP number */ ((_num) & 0xff) | \
+ /* MPP select value */ (((_sel) & 0xf) << 8) | \
+ /* may be input signal */ ((!!(_in)) << 12) | \
+ /* may be output signal */ ((!!(_out)) << 13) | \
+ /* available on F6180 */ ((!!(_F6180)) << 14) | \
+ /* available on F6190 */ ((!!(_F6190)) << 15) | \
+ /* available on F6192 */ ((!!(_F6192)) << 16) | \
+ /* available on F6281 */ ((!!(_F6281)) << 17))
+
+#define MPP_NUM(x) ((x) & 0xff)
+#define MPP_SEL(x) (((x) >> 8) & 0xf)
+
+ /* num sel i o 6180 6190 6192 6281 */
+
+#define MPP_INPUT_MASK MPP( 0, 0x0, 1, 0, 0, 0, 0, 0 )
+#define MPP_OUTPUT_MASK MPP( 0, 0x0, 0, 1, 0, 0, 0, 0 )
+
+#define MPP_F6180_MASK MPP( 0, 0x0, 0, 0, 1, 0, 0, 0 )
+#define MPP_F6190_MASK MPP( 0, 0x0, 0, 0, 0, 1, 0, 0 )
+#define MPP_F6192_MASK MPP( 0, 0x0, 0, 0, 0, 0, 1, 0 )
+#define MPP_F6281_MASK MPP( 0, 0x0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP0_GPIO MPP( 0, 0x0, 1, 1, 1, 1, 1, 1 )
+#define MPP0_NF_IO2 MPP( 0, 0x1, 1, 1, 1, 1, 1, 1 )
+#define MPP0_SPI_SCn MPP( 0, 0x2, 0, 1, 1, 1, 1, 1 )
+
+#define MPP1_GPO MPP( 1, 0x0, 0, 1, 1, 1, 1, 1 )
+#define MPP1_NF_IO3 MPP( 1, 0x1, 1, 1, 1, 1, 1, 1 )
+#define MPP1_SPI_MOSI MPP( 1, 0x2, 0, 1, 1, 1, 1, 1 )
+
+#define MPP2_GPO MPP( 2, 0x0, 0, 1, 1, 1, 1, 1 )
+#define MPP2_NF_IO4 MPP( 2, 0x1, 1, 1, 1, 1, 1, 1 )
+#define MPP2_SPI_SCK MPP( 2, 0x2, 0, 1, 1, 1, 1, 1 )
+
+#define MPP3_GPO MPP( 3, 0x0, 0, 1, 1, 1, 1, 1 )
+#define MPP3_NF_IO5 MPP( 3, 0x1, 1, 1, 1, 1, 1, 1 )
+#define MPP3_SPI_MISO MPP( 3, 0x2, 1, 0, 1, 1, 1, 1 )
+
+#define MPP4_GPIO MPP( 4, 0x0, 1, 1, 1, 1, 1, 1 )
+#define MPP4_NF_IO6 MPP( 4, 0x1, 1, 1, 1, 1, 1, 1 )
+#define MPP4_UART0_RXD MPP( 4, 0x2, 1, 0, 1, 1, 1, 1 )
+#define MPP4_SATA1_ACTn MPP( 4, 0x5, 0, 1, 0, 0, 1, 1 )
+#define MPP4_PTP_CLK MPP( 4, 0xd, 1, 0, 1, 1, 1, 1 )
+
+#define MPP5_GPO MPP( 5, 0x0, 0, 1, 1, 1, 1, 1 )
+#define MPP5_NF_IO7 MPP( 5, 0x1, 1, 1, 1, 1, 1, 1 )
+#define MPP5_UART0_TXD MPP( 5, 0x2, 0, 1, 1, 1, 1, 1 )
+#define MPP5_PTP_TRIG_GEN MPP( 5, 0x4, 0, 1, 1, 1, 1, 1 )
+#define MPP5_SATA0_ACTn MPP( 5, 0x5, 0, 1, 0, 1, 1, 1 )
+
+#define MPP6_SYSRST_OUTn MPP( 6, 0x1, 0, 1, 1, 1, 1, 1 )
+#define MPP6_SPI_MOSI MPP( 6, 0x2, 0, 1, 1, 1, 1, 1 )
+#define MPP6_PTP_TRIG_GEN MPP( 6, 0x3, 0, 1, 1, 1, 1, 1 )
+
+#define MPP7_GPO MPP( 7, 0x0, 0, 1, 1, 1, 1, 1 )
+#define MPP7_PEX_RST_OUTn MPP( 7, 0x1, 0, 1, 1, 1, 1, 1 )
+#define MPP7_SPI_SCn MPP( 7, 0x2, 0, 1, 1, 1, 1, 1 )
+#define MPP7_PTP_TRIG_GEN MPP( 7, 0x3, 0, 1, 1, 1, 1, 1 )
+
+#define MPP8_GPIO MPP( 8, 0x0, 1, 1, 1, 1, 1, 1 )
+#define MPP8_TW_SDA MPP( 8, 0x1, 1, 1, 1, 1, 1, 1 )
+#define MPP8_UART0_RTS MPP( 8, 0x2, 0, 1, 1, 1, 1, 1 )
+#define MPP8_UART1_RTS MPP( 8, 0x3, 0, 1, 1, 1, 1, 1 )
+#define MPP8_MII0_RXERR MPP( 8, 0x4, 1, 0, 0, 1, 1, 1 )
+#define MPP8_SATA1_PRESENTn MPP( 8, 0x5, 0, 1, 0, 0, 1, 1 )
+#define MPP8_PTP_CLK MPP( 8, 0xc, 1, 0, 1, 1, 1, 1 )
+#define MPP8_MII0_COL MPP( 8, 0xd, 1, 0, 1, 1, 1, 1 )
+
+#define MPP9_GPIO MPP( 9, 0x0, 1, 1, 1, 1, 1, 1 )
+#define MPP9_TW_SCK MPP( 9, 0x1, 1, 1, 1, 1, 1, 1 )
+#define MPP9_UART0_CTS MPP( 9, 0x2, 1, 0, 1, 1, 1, 1 )
+#define MPP9_UART1_CTS MPP( 9, 0x3, 1, 0, 1, 1, 1, 1 )
+#define MPP9_SATA0_PRESENTn MPP( 9, 0x5, 0, 1, 0, 1, 1, 1 )
+#define MPP9_PTP_EVENT_REQ MPP( 9, 0xc, 1, 0, 1, 1, 1, 1 )
+#define MPP9_MII0_CRS MPP( 9, 0xd, 1, 0, 1, 1, 1, 1 )
+
+#define MPP10_GPO MPP( 10, 0x0, 0, 1, 1, 1, 1, 1 )
+#define MPP10_SPI_SCK MPP( 10, 0x2, 0, 1, 1, 1, 1, 1 )
+#define MPP10_UART0_TXD MPP( 10, 0X3, 0, 1, 1, 1, 1, 1 )
+#define MPP10_SATA1_ACTn MPP( 10, 0x5, 0, 1, 0, 0, 1, 1 )
+#define MPP10_PTP_TRIG_GEN MPP( 10, 0xc, 0, 1, 1, 1, 1, 1 )
+
+#define MPP11_GPIO MPP( 11, 0x0, 1, 1, 1, 1, 1, 1 )
+#define MPP11_SPI_MISO MPP( 11, 0x2, 1, 0, 1, 1, 1, 1 )
+#define MPP11_UART0_RXD MPP( 11, 0x3, 1, 0, 1, 1, 1, 1 )
+#define MPP11_PTP_EVENT_REQ MPP( 11, 0x4, 1, 0, 1, 1, 1, 1 )
+#define MPP11_PTP_TRIG_GEN MPP( 11, 0xc, 0, 1, 1, 1, 1, 1 )
+#define MPP11_PTP_CLK MPP( 11, 0xd, 1, 0, 1, 1, 1, 1 )
+#define MPP11_SATA0_ACTn MPP( 11, 0x5, 0, 1, 0, 1, 1, 1 )
+
+#define MPP12_GPO MPP( 12, 0x0, 0, 1, 1, 1, 1, 1 )
+#define MPP12_SD_CLK MPP( 12, 0x1, 0, 1, 1, 1, 1, 1 )
+
+#define MPP13_GPIO MPP( 13, 0x0, 1, 1, 1, 1, 1, 1 )
+#define MPP13_SD_CMD MPP( 13, 0x1, 1, 1, 1, 1, 1, 1 )
+#define MPP13_UART1_TXD MPP( 13, 0x3, 0, 1, 1, 1, 1, 1 )
+
+#define MPP14_GPIO MPP( 14, 0x0, 1, 1, 1, 1, 1, 1 )
+#define MPP14_SD_D0 MPP( 14, 0x1, 1, 1, 1, 1, 1, 1 )
+#define MPP14_UART1_RXD MPP( 14, 0x3, 1, 0, 1, 1, 1, 1 )
+#define MPP14_SATA1_PRESENTn MPP( 14, 0x4, 0, 1, 0, 0, 1, 1 )
+#define MPP14_MII0_COL MPP( 14, 0xd, 1, 0, 1, 1, 1, 1 )
+
+#define MPP15_GPIO MPP( 15, 0x0, 1, 1, 1, 1, 1, 1 )
+#define MPP15_SD_D1 MPP( 15, 0x1, 1, 1, 1, 1, 1, 1 )
+#define MPP15_UART0_RTS MPP( 15, 0x2, 0, 1, 1, 1, 1, 1 )
+#define MPP15_UART1_TXD MPP( 15, 0x3, 0, 1, 1, 1, 1, 1 )
+#define MPP15_SATA0_ACTn MPP( 15, 0x4, 0, 1, 0, 1, 1, 1 )
+
+#define MPP16_GPIO MPP( 16, 0x0, 1, 1, 1, 1, 1, 1 )
+#define MPP16_SD_D2 MPP( 16, 0x1, 1, 1, 1, 1, 1, 1 )
+#define MPP16_UART0_CTS MPP( 16, 0x2, 1, 0, 1, 1, 1, 1 )
+#define MPP16_UART1_RXD MPP( 16, 0x3, 1, 0, 1, 1, 1, 1 )
+#define MPP16_SATA1_ACTn MPP( 16, 0x4, 0, 1, 0, 0, 1, 1 )
+#define MPP16_MII0_CRS MPP( 16, 0xd, 1, 0, 1, 1, 1, 1 )
+
+#define MPP17_GPIO MPP( 17, 0x0, 1, 1, 1, 1, 1, 1 )
+#define MPP17_SD_D3 MPP( 17, 0x1, 1, 1, 1, 1, 1, 1 )
+#define MPP17_SATA0_PRESENTn MPP( 17, 0x4, 0, 1, 0, 1, 1, 1 )
+
+#define MPP18_GPO MPP( 18, 0x0, 0, 1, 1, 1, 1, 1 )
+#define MPP18_NF_IO0 MPP( 18, 0x1, 1, 1, 1, 1, 1, 1 )
+
+#define MPP19_GPO MPP( 19, 0x0, 0, 1, 1, 1, 1, 1 )
+#define MPP19_NF_IO1 MPP( 19, 0x1, 1, 1, 1, 1, 1, 1 )
+
+#define MPP20_GPIO MPP( 20, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP20_TSMP0 MPP( 20, 0x1, 1, 1, 0, 0, 1, 1 )
+#define MPP20_TDM_CH0_TX_QL MPP( 20, 0x2, 0, 1, 0, 0, 1, 1 )
+#define MPP20_GE1_0 MPP( 20, 0x3, 0, 0, 0, 1, 1, 1 )
+#define MPP20_AUDIO_SPDIFI MPP( 20, 0x4, 1, 0, 0, 0, 1, 1 )
+#define MPP20_SATA1_ACTn MPP( 20, 0x5, 0, 1, 0, 0, 1, 1 )
+
+#define MPP21_GPIO MPP( 21, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP21_TSMP1 MPP( 21, 0x1, 1, 1, 0, 0, 1, 1 )
+#define MPP21_TDM_CH0_RX_QL MPP( 21, 0x2, 0, 1, 0, 0, 1, 1 )
+#define MPP21_GE1_1 MPP( 21, 0x3, 0, 0, 0, 1, 1, 1 )
+#define MPP21_AUDIO_SPDIFO MPP( 21, 0x4, 0, 1, 0, 0, 1, 1 )
+#define MPP21_SATA0_ACTn MPP( 21, 0x5, 0, 1, 0, 1, 1, 1 )
+
+#define MPP22_GPIO MPP( 22, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP22_TSMP2 MPP( 22, 0x1, 1, 1, 0, 0, 1, 1 )
+#define MPP22_TDM_CH2_TX_QL MPP( 22, 0x2, 0, 1, 0, 0, 1, 1 )
+#define MPP22_GE1_2 MPP( 22, 0x3, 0, 0, 0, 1, 1, 1 )
+#define MPP22_AUDIO_SPDIFRMKCLK MPP( 22, 0x4, 0, 1, 0, 0, 1, 1 )
+#define MPP22_SATA1_PRESENTn MPP( 22, 0x5, 0, 1, 0, 0, 1, 1 )
+
+#define MPP23_GPIO MPP( 23, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP23_TSMP3 MPP( 23, 0x1, 1, 1, 0, 0, 1, 1 )
+#define MPP23_TDM_CH2_RX_QL MPP( 23, 0x2, 1, 0, 0, 0, 1, 1 )
+#define MPP23_GE1_3 MPP( 23, 0x3, 0, 0, 0, 1, 1, 1 )
+#define MPP23_AUDIO_I2SBCLK MPP( 23, 0x4, 0, 1, 0, 0, 1, 1 )
+#define MPP23_SATA0_PRESENTn MPP( 23, 0x5, 0, 1, 0, 1, 1, 1 )
+
+#define MPP24_GPIO MPP( 24, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP24_TSMP4 MPP( 24, 0x1, 1, 1, 0, 0, 1, 1 )
+#define MPP24_TDM_SPI_CS0 DEV( 24, 0x2, 0, 1, 0, 0, 1, 1 )
+#define MPP24_GE1_4 MPP( 24, 0x3, 0, 0, 0, 1, 1, 1 )
+#define MPP24_AUDIO_I2SDO MPP( 24, 0x4, 0, 1, 0, 0, 1, 1 )
+
+#define MPP25_GPIO MPP( 25, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP25_TSMP5 MPP( 25, 0x1, 1, 1, 0, 0, 1, 1 )
+#define MPP25_TDM_SPI_SCK MPP( 25, 0x2, 0, 1, 0, 0, 1, 1 )
+#define MPP25_GE1_5 MPP( 25, 0x3, 0, 0, 0, 1, 1, 1 )
+#define MPP25_AUDIO_I2SLRCLK MPP( 25, 0x4, 0, 1, 0, 0, 1, 1 )
+
+#define MPP26_GPIO MPP( 26, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP26_TSMP6 MPP( 26, 0x1, 1, 1, 0, 0, 1, 1 )
+#define MPP26_TDM_SPI_MISO MPP( 26, 0x2, 1, 0, 0, 0, 1, 1 )
+#define MPP26_GE1_6 MPP( 26, 0x3, 0, 0, 0, 1, 1, 1 )
+#define MPP26_AUDIO_I2SMCLK MPP( 26, 0x4, 0, 1, 0, 0, 1, 1 )
+
+#define MPP27_GPIO MPP( 27, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP27_TSMP7 MPP( 27, 0x1, 1, 1, 0, 0, 1, 1 )
+#define MPP27_TDM_SPI_MOSI MPP( 27, 0x2, 0, 1, 0, 0, 1, 1 )
+#define MPP27_GE1_7 MPP( 27, 0x3, 0, 0, 0, 1, 1, 1 )
+#define MPP27_AUDIO_I2SDI MPP( 27, 0x4, 1, 0, 0, 0, 1, 1 )
+
+#define MPP28_GPIO MPP( 28, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP28_TSMP8 MPP( 28, 0x1, 1, 1, 0, 0, 1, 1 )
+#define MPP28_TDM_CODEC_INTn MPP( 28, 0x2, 0, 0, 0, 0, 1, 1 )
+#define MPP28_GE1_8 MPP( 28, 0x3, 0, 0, 0, 1, 1, 1 )
+#define MPP28_AUDIO_EXTCLK MPP( 28, 0x4, 1, 0, 0, 0, 1, 1 )
+
+#define MPP29_GPIO MPP( 29, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP29_TSMP9 MPP( 29, 0x1, 1, 1, 0, 0, 1, 1 )
+#define MPP29_TDM_CODEC_RSTn MPP( 29, 0x2, 0, 0, 0, 0, 1, 1 )
+#define MPP29_GE1_9 MPP( 29, 0x3, 0, 0, 0, 1, 1, 1 )
+
+#define MPP30_GPIO MPP( 30, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP30_TSMP10 MPP( 30, 0x1, 1, 1, 0, 0, 1, 1 )
+#define MPP30_TDM_PCLK MPP( 30, 0x2, 1, 1, 0, 0, 1, 1 )
+#define MPP30_GE1_10 MPP( 30, 0x3, 0, 0, 0, 1, 1, 1 )
+
+#define MPP31_GPIO MPP( 31, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP31_TSMP11 MPP( 31, 0x1, 1, 1, 0, 0, 1, 1 )
+#define MPP31_TDM_FS MPP( 31, 0x2, 1, 1, 0, 0, 1, 1 )
+#define MPP31_GE1_11 MPP( 31, 0x3, 0, 0, 0, 1, 1, 1 )
+
+#define MPP32_GPIO MPP( 32, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP32_TSMP12 MPP( 32, 0x1, 1, 1, 0, 0, 1, 1 )
+#define MPP32_TDM_DRX MPP( 32, 0x2, 1, 0, 0, 0, 1, 1 )
+#define MPP32_GE1_12 MPP( 32, 0x3, 0, 0, 0, 1, 1, 1 )
+
+#define MPP33_GPIO MPP( 33, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP33_TDM_DTX MPP( 33, 0x2, 0, 1, 0, 0, 1, 1 )
+#define MPP33_GE1_13 MPP( 33, 0x3, 0, 0, 0, 1, 1, 1 )
+
+#define MPP34_GPIO MPP( 34, 0x0, 1, 1, 0, 1, 1, 1 )
+#define MPP34_TDM_SPI_CS1 MPP( 34, 0x2, 0, 1, 0, 0, 1, 1 )
+#define MPP34_GE1_14 MPP( 34, 0x3, 0, 0, 0, 1, 1, 1 )
+
+#define MPP35_GPIO MPP( 35, 0x0, 1, 1, 1, 1, 1, 1 )
+#define MPP35_TDM_CH0_TX_QL MPP( 35, 0x2, 0, 1, 0, 0, 1, 1 )
+#define MPP35_GE1_15 MPP( 35, 0x3, 0, 0, 0, 1, 1, 1 )
+#define MPP35_SATA0_ACTn MPP( 35, 0x5, 0, 1, 0, 1, 1, 1 )
+#define MPP35_MII0_RXERR MPP( 35, 0xc, 1, 0, 1, 1, 1, 1 )
+
+#define MPP36_GPIO MPP( 36, 0x0, 1, 1, 1, 0, 0, 1 )
+#define MPP36_TSMP0 MPP( 36, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP36_TDM_SPI_CS1 MPP( 36, 0x2, 0, 1, 0, 0, 0, 1 )
+#define MPP36_AUDIO_SPDIFI MPP( 36, 0x4, 1, 0, 1, 0, 0, 1 )
+
+#define MPP37_GPIO MPP( 37, 0x0, 1, 1, 1, 0, 0, 1 )
+#define MPP37_TSMP1 MPP( 37, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP37_TDM_CH2_TX_QL MPP( 37, 0x2, 0, 1, 0, 0, 0, 1 )
+#define MPP37_AUDIO_SPDIFO MPP( 37, 0x4, 0, 1, 1, 0, 0, 1 )
+
+#define MPP38_GPIO MPP( 38, 0x0, 1, 1, 1, 0, 0, 1 )
+#define MPP38_TSMP2 MPP( 38, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP38_TDM_CH2_RX_QL MPP( 38, 0x2, 0, 1, 0, 0, 0, 1 )
+#define MPP38_AUDIO_SPDIFRMLCLK MPP( 38, 0x4, 0, 1, 1, 0, 0, 1 )
+
+#define MPP39_GPIO MPP( 39, 0x0, 1, 1, 1, 0, 0, 1 )
+#define MPP39_TSMP3 MPP( 39, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP39_TDM_SPI_CS0 MPP( 39, 0x2, 0, 1, 0, 0, 0, 1 )
+#define MPP39_AUDIO_I2SBCLK MPP( 39, 0x4, 0, 1, 1, 0, 0, 1 )
+
+#define MPP40_GPIO MPP( 40, 0x0, 1, 1, 1, 0, 0, 1 )
+#define MPP40_TSMP4 MPP( 40, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP40_TDM_SPI_SCK MPP( 40, 0x2, 0, 1, 0, 0, 0, 1 )
+#define MPP40_AUDIO_I2SDO MPP( 40, 0x4, 0, 1, 1, 0, 0, 1 )
+
+#define MPP41_GPIO MPP( 41, 0x0, 1, 1, 1, 0, 0, 1 )
+#define MPP41_TSMP5 MPP( 41, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP41_TDM_SPI_MISO MPP( 41, 0x2, 1, 0, 0, 0, 0, 1 )
+#define MPP41_AUDIO_I2SLRC MPP( 41, 0x4, 0, 1, 1, 0, 0, 1 )
+
+#define MPP42_GPIO MPP( 42, 0x0, 1, 1, 1, 0, 0, 1 )
+#define MPP42_TSMP6 MPP( 42, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP42_TDM_SPI_MOSI MPP( 42, 0x2, 0, 1, 0, 0, 0, 1 )
+#define MPP42_AUDIO_I2SMCLK MPP( 42, 0x4, 0, 1, 1, 0, 0, 1 )
+
+#define MPP43_GPIO MPP( 43, 0x0, 1, 1, 1, 0, 0, 1 )
+#define MPP43_TSMP7 MPP( 43, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP43_TDM_CODEC_INTn MPP( 43, 0x2, 0, 0, 0, 0, 0, 1 )
+#define MPP43_AUDIO_I2SDI MPP( 43, 0x4, 1, 0, 1, 0, 0, 1 )
+
+#define MPP44_GPIO MPP( 44, 0x0, 1, 1, 1, 0, 0, 1 )
+#define MPP44_TSMP8 MPP( 44, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP44_TDM_CODEC_RSTn MPP( 44, 0x2, 0, 0, 0, 0, 0, 1 )
+#define MPP44_AUDIO_EXTCLK MPP( 44, 0x4, 1, 0, 1, 0, 0, 1 )
+
+#define MPP45_GPIO MPP( 45, 0x0, 1, 1, 0, 0, 0, 1 )
+#define MPP45_TSMP9 MPP( 45, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP45_TDM_PCLK MPP( 45, 0x2, 1, 1, 0, 0, 0, 1 )
+
+#define MPP46_GPIO MPP( 46, 0x0, 1, 1, 0, 0, 0, 1 )
+#define MPP46_TSMP10 MPP( 46, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP46_TDM_FS MPP( 46, 0x2, 1, 1, 0, 0, 0, 1 )
+
+#define MPP47_GPIO MPP( 47, 0x0, 1, 1, 0, 0, 0, 1 )
+#define MPP47_TSMP11 MPP( 47, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP47_TDM_DRX MPP( 47, 0x2, 1, 0, 0, 0, 0, 1 )
+
+#define MPP48_GPIO MPP( 48, 0x0, 1, 1, 0, 0, 0, 1 )
+#define MPP48_TSMP12 MPP( 48, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP48_TDM_DTX MPP( 48. 0x2, 0, 1, 0, 0, 0, 1 )
+
+#define MPP49_GPIO MPP( 49, 0x0, 1, 1, 0, 0, 0, 1 )
+#define MPP49_TSMP9 MPP( 49, 0x1, 1, 1, 0, 0, 0, 1 )
+#define MPP49_TDM_CH0_RX_QL MPP( 49, 0x2, 0, 1, 0, 0, 0, 1 )
+#define MPP49_PTP_CLK MPP( 49, 0x5, 1, 0, 0, 0, 0, 1 )
+
+#define MPP_MAX 49
+
+void kirkwood_mpp_conf(unsigned int *mpp_list);
+
+#endif
diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
index b1d1a87a6821..2f0e4ef3db0f 100644
--- a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
@@ -11,11 +11,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/pci.h>
-#include <linux/irq.h>
-#include <linux/mtd/physmap.h>
#include <linux/mtd/nand.h>
-#include <linux/timer.h>
+#include <linux/mtd/partitions.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/spi/flash.h>
@@ -23,7 +20,6 @@
#include <linux/spi/orion_spi.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <asm/mach/pci.h>
#include <mach/kirkwood.h>
#include "common.h"
@@ -61,14 +57,11 @@ static void __init rd88f6192_init(void)
kirkwood_ehci_init();
kirkwood_ge00_init(&rd88f6192_ge00_data);
- kirkwood_rtc_init();
kirkwood_sata_init(&rd88f6192_sata_data);
spi_register_board_info(rd88F6192_spi_slave_info,
ARRAY_SIZE(rd88F6192_spi_slave_info));
kirkwood_spi_init();
kirkwood_uart0_init();
- kirkwood_xor0_init();
- kirkwood_xor1_init();
}
static int __init rd88f6192_pci_init(void)
diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c
index 9a0e905d10cd..31e996d65fc4 100644
--- a/arch/arm/mach-kirkwood/rd88f6281-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c
@@ -11,21 +11,20 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/pci.h>
#include <linux/irq.h>
-#include <linux/mtd/physmap.h>
#include <linux/mtd/nand.h>
-#include <linux/timer.h>
+#include <linux/mtd/partitions.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <asm/mach/pci.h>
#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
#include <plat/orion_nand.h>
#include "common.h"
+#include "mpp.h"
static struct mtd_partition rd88f6281_nand_parts[] = {
{
@@ -75,7 +74,7 @@ static struct mv643xx_eth_platform_data rd88f6281_ge00_data = {
.duplex = DUPLEX_FULL,
};
-static struct dsa_platform_data rd88f6281_switch_data = {
+static struct dsa_chip_data rd88f6281_switch_chip_data = {
.port_names[0] = "lan1",
.port_names[1] = "lan2",
.port_names[2] = "lan3",
@@ -83,6 +82,11 @@ static struct dsa_platform_data rd88f6281_switch_data = {
.port_names[5] = "cpu",
};
+static struct dsa_platform_data rd88f6281_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &rd88f6281_switch_chip_data,
+};
+
static struct mv643xx_eth_platform_data rd88f6281_ge01_data = {
.phy_addr = MV643XX_ETH_PHY_ADDR(11),
};
@@ -91,6 +95,15 @@ static struct mv_sata_platform_data rd88f6281_sata_data = {
.n_ports = 2,
};
+static struct mvsdio_platform_data rd88f6281_mvsdio_data = {
+ .gpio_card_detect = 28,
+};
+
+static unsigned int rd88f6281_mpp_config[] __initdata = {
+ MPP28_GPIO,
+ 0
+};
+
static void __init rd88f6281_init(void)
{
u32 dev, rev;
@@ -99,21 +112,22 @@ static void __init rd88f6281_init(void)
* Basic setup. Needs to be called early.
*/
kirkwood_init();
+ kirkwood_mpp_conf(rd88f6281_mpp_config);
kirkwood_ehci_init();
kirkwood_ge00_init(&rd88f6281_ge00_data);
kirkwood_pcie_id(&dev, &rev);
if (rev == MV88F6281_REV_A0) {
- rd88f6281_switch_data.sw_addr = 10;
+ rd88f6281_switch_chip_data.sw_addr = 10;
kirkwood_ge01_init(&rd88f6281_ge01_data);
} else {
- rd88f6281_switch_data.port_names[4] = "wan";
+ rd88f6281_switch_chip_data.port_names[4] = "wan";
}
- kirkwood_ge00_switch_init(&rd88f6281_switch_data, NO_IRQ);
+ kirkwood_ge00_switch_init(&rd88f6281_switch_plat_data, NO_IRQ);
- kirkwood_rtc_init();
kirkwood_sata_init(&rd88f6281_sata_data);
+ kirkwood_sdio_init(&rd88f6281_mvsdio_data);
kirkwood_uart0_init();
platform_device_register(&rd88f6281_nand_flash);
diff --git a/arch/arm/mach-kirkwood/sheevaplug-setup.c b/arch/arm/mach-kirkwood/sheevaplug-setup.c
new file mode 100644
index 000000000000..831e4a56cae1
--- /dev/null
+++ b/arch/arm/mach-kirkwood/sheevaplug-setup.c
@@ -0,0 +1,136 @@
+/*
+ * arch/arm/mach-kirkwood/sheevaplug-setup.c
+ *
+ * Marvell SheevaPlug Reference Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include <plat/orion_nand.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition sheevaplug_nand_parts[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = SZ_1M
+ }, {
+ .name = "uImage",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_4M
+ }, {
+ .name = "root",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static struct resource sheevaplug_nand_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = KIRKWOOD_NAND_MEM_PHYS_BASE,
+ .end = KIRKWOOD_NAND_MEM_PHYS_BASE +
+ KIRKWOOD_NAND_MEM_SIZE - 1,
+};
+
+static struct orion_nand_data sheevaplug_nand_data = {
+ .parts = sheevaplug_nand_parts,
+ .nr_parts = ARRAY_SIZE(sheevaplug_nand_parts),
+ .cle = 0,
+ .ale = 1,
+ .width = 8,
+ .chip_delay = 25,
+};
+
+static struct platform_device sheevaplug_nand_flash = {
+ .name = "orion_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &sheevaplug_nand_data,
+ },
+ .resource = &sheevaplug_nand_resource,
+ .num_resources = 1,
+};
+
+static struct mv643xx_eth_platform_data sheevaplug_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct mvsdio_platform_data sheevaplug_mvsdio_data = {
+ // unfortunately the CD signal has not been connected */
+};
+
+static struct gpio_led sheevaplug_led_pins[] = {
+ {
+ .name = "plug:green:health",
+ .default_trigger = "default-on",
+ .gpio = 49,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data sheevaplug_led_data = {
+ .leds = sheevaplug_led_pins,
+ .num_leds = ARRAY_SIZE(sheevaplug_led_pins),
+};
+
+static struct platform_device sheevaplug_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &sheevaplug_led_data,
+ }
+};
+
+static unsigned int sheevaplug_mpp_config[] __initdata = {
+ MPP29_GPIO, /* USB Power Enable */
+ MPP49_GPIO, /* LED */
+ 0
+};
+
+static void __init sheevaplug_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(sheevaplug_mpp_config);
+
+ kirkwood_uart0_init();
+
+ if (gpio_request(29, "USB Power Enable") != 0 ||
+ gpio_direction_output(29, 1) != 0)
+ printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n");
+ kirkwood_ehci_init();
+
+ kirkwood_ge00_init(&sheevaplug_ge00_data);
+ kirkwood_sdio_init(&sheevaplug_mvsdio_data);
+
+ platform_device_register(&sheevaplug_nand_flash);
+ platform_device_register(&sheevaplug_leds);
+}
+
+MACHINE_START(SHEEVAPLUG, "Marvell SheevaPlug Reference Board")
+ /* Maintainer: shadi Ammouri <shadi@marvell.com> */
+ .phys_io = KIRKWOOD_REGS_PHYS_BASE,
+ .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
+ .init_machine = sheevaplug_init,
+ .map_io = kirkwood_map_io,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c
new file mode 100644
index 000000000000..dda5743cf3e0
--- /dev/null
+++ b/arch/arm/mach-kirkwood/ts219-setup.c
@@ -0,0 +1,220 @@
+/*
+ *
+ * QNAP TS-119/TS-219 Turbo NAS Board Setup
+ *
+ * Copyright (C) 2009 Martin Michlmayr <tbm@cyrius.com>
+ * Copyright (C) 2008 Byron Bradley <byron.bbradley@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <linux/i2c.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/timex.h>
+#include <linux/serial_reg.h>
+#include <linux/pci.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include "common.h"
+#include "mpp.h"
+
+/****************************************************************************
+ * 16 MiB NOR flash. The struct mtd_partition is not in the same order as the
+ * partitions on the device because we want to keep compatability with
+ * the QNAP firmware.
+ * Layout as used by QNAP:
+ * 0x00000000-0x00080000 : "U-Boot"
+ * 0x00200000-0x00400000 : "Kernel"
+ * 0x00400000-0x00d00000 : "RootFS"
+ * 0x00d00000-0x01000000 : "RootFS2"
+ * 0x00080000-0x000c0000 : "U-Boot Config"
+ * 0x000c0000-0x00200000 : "NAS Config"
+ *
+ * We'll use "RootFS1" instead of "RootFS" to stay compatible with the layout
+ * used by the QNAP TS-109/TS-209.
+ *
+ ***************************************************************************/
+
+static struct mtd_partition qnap_ts219_partitions[] = {
+ {
+ .name = "U-Boot",
+ .size = 0x00080000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "Kernel",
+ .size = 0x00200000,
+ .offset = 0x00200000,
+ }, {
+ .name = "RootFS1",
+ .size = 0x00900000,
+ .offset = 0x00400000,
+ }, {
+ .name = "RootFS2",
+ .size = 0x00300000,
+ .offset = 0x00d00000,
+ }, {
+ .name = "U-Boot Config",
+ .size = 0x00040000,
+ .offset = 0x00080000,
+ }, {
+ .name = "NAS Config",
+ .size = 0x00140000,
+ .offset = 0x000c0000,
+ },
+};
+
+static const struct flash_platform_data qnap_ts219_flash = {
+ .type = "m25p128",
+ .name = "spi_flash",
+ .parts = qnap_ts219_partitions,
+ .nr_parts = ARRAY_SIZE(qnap_ts219_partitions),
+};
+
+static struct spi_board_info __initdata qnap_ts219_spi_slave_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &qnap_ts219_flash,
+ .irq = -1,
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+static struct i2c_board_info __initdata qnap_ts219_i2c_rtc = {
+ I2C_BOARD_INFO("s35390a", 0x30),
+};
+
+static struct mv643xx_eth_platform_data qnap_ts219_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv_sata_platform_data qnap_ts219_sata_data = {
+ .n_ports = 2,
+};
+
+static struct gpio_keys_button qnap_ts219_buttons[] = {
+ {
+ .code = KEY_COPY,
+ .gpio = 15,
+ .desc = "USB Copy",
+ .active_low = 1,
+ },
+ {
+ .code = KEY_RESTART,
+ .gpio = 16,
+ .desc = "Reset",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data qnap_ts219_button_data = {
+ .buttons = qnap_ts219_buttons,
+ .nbuttons = ARRAY_SIZE(qnap_ts219_buttons),
+};
+
+static struct platform_device qnap_ts219_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &qnap_ts219_button_data,
+ }
+};
+
+static unsigned int qnap_ts219_mpp_config[] __initdata = {
+ MPP0_SPI_SCn,
+ MPP1_SPI_MOSI,
+ MPP2_SPI_SCK,
+ MPP3_SPI_MISO,
+ MPP8_TW_SDA,
+ MPP9_TW_SCK,
+ MPP10_UART0_TXD,
+ MPP11_UART0_RXD,
+ MPP13_UART1_TXD, /* PIC controller */
+ MPP14_UART1_RXD, /* PIC controller */
+ MPP15_GPIO, /* USB Copy button */
+ MPP16_GPIO, /* Reset button */
+ MPP20_SATA1_ACTn,
+ MPP21_SATA0_ACTn,
+ MPP22_SATA1_PRESENTn,
+ MPP23_SATA0_PRESENTn,
+ 0
+};
+
+
+/*****************************************************************************
+ * QNAP TS-x19 specific power off method via UART1-attached PIC
+ ****************************************************************************/
+
+#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
+
+void qnap_ts219_power_off(void)
+{
+ /* 19200 baud divisor */
+ const unsigned divisor = ((kirkwood_tclk + (8 * 19200)) / (16 * 19200));
+
+ pr_info("%s: triggering power-off...\n", __func__);
+
+ /* hijack UART1 and reset into sane state (19200,8n1) */
+ writel(0x83, UART1_REG(LCR));
+ writel(divisor & 0xff, UART1_REG(DLL));
+ writel((divisor >> 8) & 0xff, UART1_REG(DLM));
+ writel(0x03, UART1_REG(LCR));
+ writel(0x00, UART1_REG(IER));
+ writel(0x00, UART1_REG(FCR));
+ writel(0x00, UART1_REG(MCR));
+
+ /* send the power-off command 'A' to PIC */
+ writel('A', UART1_REG(TX));
+}
+
+static void __init qnap_ts219_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(qnap_ts219_mpp_config);
+
+ kirkwood_uart0_init();
+ kirkwood_uart1_init(); /* A PIC controller is connected here. */
+ spi_register_board_info(qnap_ts219_spi_slave_info,
+ ARRAY_SIZE(qnap_ts219_spi_slave_info));
+ kirkwood_spi_init();
+ kirkwood_i2c_init();
+ i2c_register_board_info(0, &qnap_ts219_i2c_rtc, 1);
+ kirkwood_ge00_init(&qnap_ts219_ge00_data);
+ kirkwood_sata_init(&qnap_ts219_sata_data);
+ kirkwood_ehci_init();
+ platform_device_register(&qnap_ts219_button_device);
+
+ pm_power_off = qnap_ts219_power_off;
+
+}
+
+MACHINE_START(TS219, "QNAP TS-119/TS-219")
+ /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
+ .phys_io = KIRKWOOD_REGS_PHYS_BASE,
+ .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
+ .init_machine = qnap_ts219_init,
+ .map_io = kirkwood_map_io,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-ks8695/Kconfig b/arch/arm/mach-ks8695/Kconfig
index 2754daabda55..fe0c82e30b2d 100644
--- a/arch/arm/mach-ks8695/Kconfig
+++ b/arch/arm/mach-ks8695/Kconfig
@@ -14,6 +14,12 @@ config MACH_DSM320
Say 'Y' here if you want your kernel to run on the D-Link
DSM-320 Wireless Media Player.
+config MACH_ACS5K
+ bool "Brivo Systems LLC, ACS-5000 Master board"
+ help
+ say 'Y' here if you want your kernel to run on the Brivo
+ Systems LLC, ACS-5000 Master board.
+
endmenu
endif
diff --git a/arch/arm/mach-ks8695/Makefile b/arch/arm/mach-ks8695/Makefile
index f735d2cc0294..7e3e8160ed30 100644
--- a/arch/arm/mach-ks8695/Makefile
+++ b/arch/arm/mach-ks8695/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_LEDS) += leds.o
# Board-specific support
obj-$(CONFIG_MACH_KS8695) += board-micrel.o
obj-$(CONFIG_MACH_DSM320) += board-dsm320.o
+obj-$(CONFIG_MACH_ACS5K) += board-acs5k.o
diff --git a/arch/arm/mach-ks8695/board-acs5k.c b/arch/arm/mach-ks8695/board-acs5k.c
new file mode 100644
index 000000000000..9e3e5a640ad2
--- /dev/null
+++ b/arch/arm/mach-ks8695/board-acs5k.c
@@ -0,0 +1,233 @@
+/*
+ * arch/arm/mach-ks8695/board-acs5k.c
+ *
+ * Brivo Systems LLC, ACS-5000 Master Board
+ *
+ * Copyright 2008 Simtec Electronics
+ * Daniel Silverstone <dsilvers@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/i2c-gpio.h>
+#include <linux/i2c/pca953x.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/devices.h>
+#include <mach/gpio.h>
+
+#include "generic.h"
+
+static struct i2c_gpio_platform_data acs5k_i2c_device_platdata = {
+ .sda_pin = 4,
+ .scl_pin = 5,
+ .udelay = 10,
+};
+
+static struct platform_device acs5k_i2c_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .num_resources = 0,
+ .resource = NULL,
+ .dev = {
+ .platform_data = &acs5k_i2c_device_platdata,
+ },
+};
+
+static int acs5k_pca9555_setup(struct i2c_client *client,
+ unsigned gpio_base, unsigned ngpio,
+ void *context)
+{
+ static int acs5k_gpio_value[] = {
+ -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, -1, 0, 1, 0, -1, -1
+ };
+ int n;
+
+ for (n = 0; n < ARRAY_SIZE(acs5k_gpio_value); ++n) {
+ gpio_request(gpio_base + n, "ACS-5000 GPIO Expander");
+ if (acs5k_gpio_value[n] < 0)
+ gpio_direction_input(gpio_base + n);
+ else
+ gpio_direction_output(gpio_base + n,
+ acs5k_gpio_value[n]);
+ gpio_export(gpio_base + n, 0); /* Export, direction locked down */
+ }
+
+ return 0;
+}
+
+static struct pca953x_platform_data acs5k_i2c_pca9555_platdata = {
+ .gpio_base = 16, /* Start directly after the CPU's GPIO */
+ .invert = 0, /* Do not invert */
+ .setup = acs5k_pca9555_setup,
+};
+
+static struct i2c_board_info acs5k_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ },
+ {
+ I2C_BOARD_INFO("pca9555", 0x20),
+ .platform_data = &acs5k_i2c_pca9555_platdata,
+ },
+};
+
+static void __devinit acs5k_i2c_init(void)
+{
+ /* The gpio interface */
+ platform_device_register(&acs5k_i2c_device);
+ /* I2C devices */
+ i2c_register_board_info(0, acs5k_i2c_devs,
+ ARRAY_SIZE(acs5k_i2c_devs));
+}
+
+static struct mtd_partition acs5k_nor_partitions[] = {
+ [0] = {
+ .name = "Boot Agent and config",
+ .size = SZ_256K,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [1] = {
+ .name = "Kernel",
+ .size = SZ_1M,
+ .offset = SZ_256K,
+ },
+ [2] = {
+ .name = "SquashFS1",
+ .size = SZ_2M,
+ .offset = SZ_256K + SZ_1M,
+ },
+ [3] = {
+ .name = "SquashFS2",
+ .size = SZ_4M + SZ_2M,
+ .offset = SZ_256K + SZ_1M + SZ_2M,
+ },
+ [4] = {
+ .name = "Data",
+ .size = SZ_16M + SZ_4M + SZ_2M + SZ_512K, /* 22.5 MB */
+ .offset = SZ_256K + SZ_8M + SZ_1M,
+ }
+};
+
+static struct physmap_flash_data acs5k_nor_pdata = {
+ .width = 4,
+ .nr_parts = ARRAY_SIZE(acs5k_nor_partitions),
+ .parts = acs5k_nor_partitions,
+};
+
+static struct resource acs5k_nor_resource[] = {
+ [0] = {
+ .start = SZ_32M, /* We expect the bootloader to map
+ * the flash here.
+ */
+ .end = SZ_32M + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SZ_32M + SZ_16M,
+ .end = SZ_32M + SZ_32M - SZ_256K - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device acs5k_device_nor = {
+ .name = "physmap-flash",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(acs5k_nor_resource),
+ .resource = acs5k_nor_resource,
+ .dev = {
+ .platform_data = &acs5k_nor_pdata,
+ },
+};
+
+static void __init acs5k_register_nor(void)
+{
+ int ret;
+
+ if (acs5k_nor_partitions[0].mask_flags == 0)
+ printk(KERN_WARNING "Warning: Unprotecting bootloader and configuration partition\n");
+
+ ret = platform_device_register(&acs5k_device_nor);
+ if (ret < 0)
+ printk(KERN_ERR "failed to register physmap-flash device\n");
+}
+
+static int __init acs5k_protection_setup(char *s)
+{
+ /* We can't allocate anything here but we should be able
+ * to trivially parse s and decide if we can protect the
+ * bootloader partition or not
+ */
+ if (strcmp(s, "no") == 0)
+ acs5k_nor_partitions[0].mask_flags = 0;
+
+ return 1;
+}
+
+__setup("protect_bootloader=", acs5k_protection_setup);
+
+static void __init acs5k_init_gpio(void)
+{
+ int i;
+
+ ks8695_register_gpios();
+ for (i = 0; i < 4; ++i)
+ gpio_request(i, "ACS5K IRQ");
+ gpio_request(7, "ACS5K KS_FRDY");
+ for (i = 8; i < 16; ++i)
+ gpio_request(i, "ACS5K Unused");
+
+ gpio_request(3, "ACS5K CAN Control");
+ gpio_request(6, "ACS5K Heartbeat");
+ gpio_direction_output(3, 1); /* Default CAN_RESET high */
+ gpio_direction_output(6, 0); /* Default KS8695_ACTIVE low */
+ gpio_export(3, 0); /* export CAN_RESET as output only */
+ gpio_export(6, 0); /* export KS8695_ACTIVE as output only */
+}
+
+static void __init acs5k_init(void)
+{
+ acs5k_init_gpio();
+
+ /* Network device */
+ ks8695_add_device_lan(); /* eth0 = LAN */
+ ks8695_add_device_wan(); /* ethX = WAN */
+
+ /* NOR devices */
+ acs5k_register_nor();
+
+ /* I2C bus */
+ acs5k_i2c_init();
+}
+
+MACHINE_START(ACS5K, "Brivo Systems LLC ACS-5000 Master board")
+ /* Maintainer: Simtec Electronics. */
+ .phys_io = KS8695_IO_PA,
+ .io_pg_offst = (KS8695_IO_VA >> 18) & 0xfffc,
+ .boot_params = KS8695_SDRAM_PA + 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = acs5k_init,
+ .timer = &ks8695_timer,
+MACHINE_END
diff --git a/arch/arm/mach-ks8695/include/mach/memory.h b/arch/arm/mach-ks8695/include/mach/memory.h
index 6d5887cf5742..76e5308685a4 100644
--- a/arch/arm/mach-ks8695/include/mach/memory.h
+++ b/arch/arm/mach-ks8695/include/mach/memory.h
@@ -35,7 +35,11 @@ extern struct bus_type platform_bus_type;
__phys_to_virt(x) : __bus_to_virt(x)); })
#define __arch_virt_to_dma(dev, x) ({ is_lbus_device(dev) ? \
(dma_addr_t)__virt_to_phys(x) : (dma_addr_t)__virt_to_bus(x); })
-#define __arch_page_to_dma(dev, x) __arch_virt_to_dma(dev, page_address(x))
+#define __arch_page_to_dma(dev, x) \
+ ({ dma_addr_t __dma = page_to_phys(page); \
+ if (!is_lbus_device(dev)) \
+ __dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \
+ __dma; })
#endif
diff --git a/arch/arm/mach-ks8695/include/mach/system.h b/arch/arm/mach-ks8695/include/mach/system.h
index 5a9b032bdbeb..fb1dda9be2d0 100644
--- a/arch/arm/mach-ks8695/include/mach/system.h
+++ b/arch/arm/mach-ks8695/include/mach/system.h
@@ -27,7 +27,7 @@ static void arch_idle(void)
}
-static void arch_reset(char mode)
+static void arch_reset(char mode, const char *cmd)
{
unsigned int reg;
diff --git a/arch/arm/mach-l7200/include/mach/system.h b/arch/arm/mach-l7200/include/mach/system.h
index 5272abee0d0e..e0dd3b6ae4aa 100644
--- a/arch/arm/mach-l7200/include/mach/system.h
+++ b/arch/arm/mach-l7200/include/mach/system.h
@@ -19,7 +19,7 @@ static inline void arch_idle(void)
*(unsigned long *)(IO_BASE + 0x50004) = 1; /* idle mode */
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
if (mode == 's') {
cpu_reset(0);
diff --git a/arch/arm/mach-lh7a40x/include/mach/system.h b/arch/arm/mach-lh7a40x/include/mach/system.h
index fa46bb1ef07b..45a56d3b93d7 100644
--- a/arch/arm/mach-lh7a40x/include/mach/system.h
+++ b/arch/arm/mach-lh7a40x/include/mach/system.h
@@ -13,7 +13,7 @@ static inline void arch_idle(void)
cpu_do_idle ();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
cpu_reset (0);
}
diff --git a/arch/arm/mach-loki/include/mach/system.h b/arch/arm/mach-loki/include/mach/system.h
index 8db1147d4ec5..c1de36fe9b37 100644
--- a/arch/arm/mach-loki/include/mach/system.h
+++ b/arch/arm/mach-loki/include/mach/system.h
@@ -17,7 +17,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
/*
* Enable soft reset to assert RSTOUTn.
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
new file mode 100644
index 000000000000..c6a564fc4a7c
--- /dev/null
+++ b/arch/arm/mach-mmp/Kconfig
@@ -0,0 +1,47 @@
+if ARCH_MMP
+
+menu "Marvell PXA168/910 Implmentations"
+
+config MACH_ASPENITE
+ bool "Marvell's PXA168 Aspenite Development Board"
+ select CPU_PXA168
+ help
+ Say 'Y' here if you want to support the Marvell PXA168-based
+ Aspenite Development Board.
+
+config MACH_ZYLONITE2
+ bool "Marvell's PXA168 Zylonite2 Development Board"
+ select CPU_PXA168
+ help
+ Say 'Y' here if you want to support the Marvell PXA168-based
+ Zylonite2 Development Board.
+
+config MACH_TAVOREVB
+ bool "Marvell's PXA910 TavorEVB Development Board"
+ select CPU_PXA910
+ help
+ Say 'Y' here if you want to support the Marvell PXA910-based
+ TavorEVB Development Board.
+
+config MACH_TTC_DKB
+ bool "Marvell's PXA910 TavorEVB Development Board"
+ select CPU_PXA910
+ help
+ Say 'Y' here if you want to support the Marvell PXA910-based
+ TTC_DKB Development Board.
+
+endmenu
+
+config CPU_PXA168
+ bool
+ select CPU_MOHAWK
+ help
+ Select code specific to PXA168
+
+config CPU_PXA910
+ bool
+ select CPU_MOHAWK
+ help
+ Select code specific to PXA910
+
+endif
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
new file mode 100644
index 000000000000..6883e6584883
--- /dev/null
+++ b/arch/arm/mach-mmp/Makefile
@@ -0,0 +1,15 @@
+#
+# Makefile for Marvell's PXA168 processors line
+#
+
+obj-y += common.o clock.o devices.o irq.o time.o
+
+# SoC support
+obj-$(CONFIG_CPU_PXA168) += pxa168.o
+obj-$(CONFIG_CPU_PXA910) += pxa910.o
+
+# board support
+obj-$(CONFIG_MACH_ASPENITE) += aspenite.o
+obj-$(CONFIG_MACH_ZYLONITE2) += aspenite.o
+obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o
+obj-$(CONFIG_MACH_TTC_DKB) += ttc_dkb.o
diff --git a/arch/arm/mach-mmp/Makefile.boot b/arch/arm/mach-mmp/Makefile.boot
new file mode 100644
index 000000000000..574a4aa8321a
--- /dev/null
+++ b/arch/arm/mach-mmp/Makefile.boot
@@ -0,0 +1 @@
+ zreladdr-y := 0x00008000
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
new file mode 100644
index 000000000000..4562452d4074
--- /dev/null
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -0,0 +1,117 @@
+/*
+ * linux/arch/arm/mach-mmp/aspenite.c
+ *
+ * Support for the Marvell PXA168-based Aspenite and Zylonite2
+ * Development Platform.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa168.h>
+#include <mach/pxa168.h>
+#include <mach/gpio.h>
+
+#include "common.h"
+
+static unsigned long common_pin_config[] __initdata = {
+ /* Data Flash Interface */
+ GPIO0_DFI_D15,
+ GPIO1_DFI_D14,
+ GPIO2_DFI_D13,
+ GPIO3_DFI_D12,
+ GPIO4_DFI_D11,
+ GPIO5_DFI_D10,
+ GPIO6_DFI_D9,
+ GPIO7_DFI_D8,
+ GPIO8_DFI_D7,
+ GPIO9_DFI_D6,
+ GPIO10_DFI_D5,
+ GPIO11_DFI_D4,
+ GPIO12_DFI_D3,
+ GPIO13_DFI_D2,
+ GPIO14_DFI_D1,
+ GPIO15_DFI_D0,
+
+ /* Static Memory Controller */
+ GPIO18_SMC_nCS0,
+ GPIO34_SMC_nCS1,
+ GPIO23_SMC_nLUA,
+ GPIO25_SMC_nLLA,
+ GPIO28_SMC_RDY,
+ GPIO29_SMC_SCLK,
+ GPIO35_SMC_BE1,
+ GPIO36_SMC_BE2,
+ GPIO27_GPIO, /* Ethernet IRQ */
+
+ /* UART1 */
+ GPIO107_UART1_RXD,
+ GPIO108_UART1_TXD,
+};
+
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = SMC_CS1_PHYS_BASE + 0x300,
+ .end = SMC_CS1_PHYS_BASE + 0xfffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(27),
+ .end = gpio_to_irq(27),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static void __init common_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(common_pin_config));
+
+ /* on-chip devices */
+ pxa168_add_uart(1);
+
+ /* off-chip devices */
+ platform_device_register(&smc91x_device);
+}
+
+MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform")
+ .phys_io = APB_PHYS_BASE,
+ .boot_params = 0x00000100,
+ .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
+ .map_io = pxa_map_io,
+ .init_irq = pxa168_init_irq,
+ .timer = &pxa168_timer,
+ .init_machine = common_init,
+MACHINE_END
+
+MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform")
+ .phys_io = APB_PHYS_BASE,
+ .boot_params = 0x00000100,
+ .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
+ .map_io = pxa_map_io,
+ .init_irq = pxa168_init_irq,
+ .timer = &pxa168_timer,
+ .init_machine = common_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/clock.c b/arch/arm/mach-mmp/clock.c
new file mode 100644
index 000000000000..2d9cc5a7122f
--- /dev/null
+++ b/arch/arm/mach-mmp/clock.c
@@ -0,0 +1,83 @@
+/*
+ * linux/arch/arm/mach-mmp/clock.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/regs-apbc.h>
+#include "clock.h"
+
+static void apbc_clk_enable(struct clk *clk)
+{
+ uint32_t clk_rst;
+
+ clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(clk->fnclksel);
+ __raw_writel(clk_rst, clk->clk_rst);
+}
+
+static void apbc_clk_disable(struct clk *clk)
+{
+ __raw_writel(0, clk->clk_rst);
+}
+
+struct clkops apbc_clk_ops = {
+ .enable = apbc_clk_enable,
+ .disable = apbc_clk_disable,
+};
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (clk->enabled++ == 0)
+ clk->ops->enable(clk);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ WARN_ON(clk->enabled == 0);
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (--clk->enabled == 0)
+ clk->ops->disable(clk);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ unsigned long rate;
+
+ if (clk->ops->getrate)
+ rate = clk->ops->getrate(clk);
+ else
+ rate = clk->rate;
+
+ return rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void clks_register(struct clk_lookup *clks, size_t num)
+{
+ int i;
+
+ for (i = 0; i < num; i++)
+ clkdev_add(&clks[i]);
+}
diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h
new file mode 100644
index 000000000000..ed967e78e6a8
--- /dev/null
+++ b/arch/arm/mach-mmp/clock.h
@@ -0,0 +1,71 @@
+/*
+ * linux/arch/arm/mach-mmp/clock.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <asm/clkdev.h>
+
+struct clkops {
+ void (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+ unsigned long (*getrate)(struct clk *);
+};
+
+struct clk {
+ const struct clkops *ops;
+
+ void __iomem *clk_rst; /* clock reset control register */
+ int fnclksel; /* functional clock select (APBC) */
+ uint32_t enable_val; /* value for clock enable (APMU) */
+ unsigned long rate;
+ int enabled;
+};
+
+extern struct clkops apbc_clk_ops;
+
+#define APBC_CLK(_name, _reg, _fnclksel, _rate) \
+struct clk clk_##_name = { \
+ .clk_rst = (void __iomem *)APBC_##_reg, \
+ .fnclksel = _fnclksel, \
+ .rate = _rate, \
+ .ops = &apbc_clk_ops, \
+}
+
+#define APBC_CLK_OPS(_name, _reg, _fnclksel, _rate, _ops) \
+struct clk clk_##_name = { \
+ .clk_rst = (void __iomem *)APBC_##_reg, \
+ .fnclksel = _fnclksel, \
+ .rate = _rate, \
+ .ops = _ops, \
+}
+
+#define APMU_CLK(_name, _reg, _eval, _rate) \
+struct clk clk_##_name = { \
+ .clk_rst = (void __iomem *)APMU_##_reg, \
+ .enable_val = _eval, \
+ .rate = _rate, \
+ .ops = &apmu_clk_ops, \
+}
+
+#define APMU_CLK_OPS(_name, _reg, _eval, _rate, _ops) \
+struct clk clk_##_name = { \
+ .clk_rst = (void __iomem *)APMU_##_reg, \
+ .enable_val = _eval, \
+ .rate = _rate, \
+ .ops = _ops, \
+}
+
+#define INIT_CLKREG(_clk, _devname, _conname) \
+ { \
+ .clk = _clk, \
+ .dev_id = _devname, \
+ .con_id = _conname, \
+ }
+
+extern struct clk clk_pxa168_gpio;
+extern struct clk clk_pxa168_timers;
+
+extern void clks_register(struct clk_lookup *, size_t);
diff --git a/arch/arm/mach-mmp/common.c b/arch/arm/mach-mmp/common.c
new file mode 100644
index 000000000000..e1e66c18b446
--- /dev/null
+++ b/arch/arm/mach-mmp/common.c
@@ -0,0 +1,37 @@
+/*
+ * linux/arch/arm/mach-mmp/common.c
+ *
+ * Code common to PXA168 processor lines
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <asm/page.h>
+#include <asm/mach/map.h>
+#include <mach/addr-map.h>
+
+#include "common.h"
+
+static struct map_desc standard_io_desc[] __initdata = {
+ {
+ .pfn = __phys_to_pfn(APB_PHYS_BASE),
+ .virtual = APB_VIRT_BASE,
+ .length = APB_PHYS_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .pfn = __phys_to_pfn(AXI_PHYS_BASE),
+ .virtual = AXI_VIRT_BASE,
+ .length = AXI_PHYS_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init pxa_map_io(void)
+{
+ iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+}
diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
new file mode 100644
index 000000000000..c33fbbc49417
--- /dev/null
+++ b/arch/arm/mach-mmp/common.h
@@ -0,0 +1,13 @@
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+
+struct sys_timer;
+
+extern void timer_init(int irq);
+
+extern struct sys_timer pxa168_timer;
+extern struct sys_timer pxa910_timer;
+extern void __init pxa168_init_irq(void);
+extern void __init pxa910_init_irq(void);
+
+extern void __init icu_init_irq(void);
+extern void __init pxa_map_io(void);
diff --git a/arch/arm/mach-mmp/devices.c b/arch/arm/mach-mmp/devices.c
new file mode 100644
index 000000000000..191d9dea8731
--- /dev/null
+++ b/arch/arm/mach-mmp/devices.c
@@ -0,0 +1,69 @@
+/*
+ * linux/arch/arm/mach-mmp/devices.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/irq.h>
+#include <mach/devices.h>
+
+int __init pxa_register_device(struct pxa_device_desc *desc,
+ void *data, size_t size)
+{
+ struct platform_device *pdev;
+ struct resource res[2 + MAX_RESOURCE_DMA];
+ int i, ret = 0, nres = 0;
+
+ pdev = platform_device_alloc(desc->drv_name, desc->id);
+ if (pdev == NULL)
+ return -ENOMEM;
+
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+ memset(res, 0, sizeof(res));
+
+ if (desc->start != -1ul && desc->size > 0) {
+ res[nres].start = desc->start;
+ res[nres].end = desc->start + desc->size - 1;
+ res[nres].flags = IORESOURCE_MEM;
+ nres++;
+ }
+
+ if (desc->irq != NO_IRQ) {
+ res[nres].start = desc->irq;
+ res[nres].end = desc->irq;
+ res[nres].flags = IORESOURCE_IRQ;
+ nres++;
+ }
+
+ for (i = 0; i < MAX_RESOURCE_DMA; i++, nres++) {
+ if (desc->dma[i] == 0)
+ break;
+
+ res[nres].start = desc->dma[i];
+ res[nres].end = desc->dma[i];
+ res[nres].flags = IORESOURCE_DMA;
+ }
+
+ ret = platform_device_add_resources(pdev, res, nres);
+ if (ret) {
+ platform_device_put(pdev);
+ return ret;
+ }
+
+ if (data && size) {
+ ret = platform_device_add_data(pdev, data, size);
+ if (ret) {
+ platform_device_put(pdev);
+ return ret;
+ }
+ }
+
+ return platform_device_add(pdev);
+}
diff --git a/arch/arm/mach-mmp/include/mach/addr-map.h b/arch/arm/mach-mmp/include/mach/addr-map.h
new file mode 100644
index 000000000000..3254089a644d
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/addr-map.h
@@ -0,0 +1,34 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/addr-map.h
+ *
+ * Common address map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_ADDR_MAP_H
+#define __ASM_MACH_ADDR_MAP_H
+
+/* APB - Application Subsystem Peripheral Bus
+ *
+ * NOTE: the DMA controller registers are actually on the AXI fabric #1
+ * slave port to AHB/APB bridge, due to its close relationship to those
+ * peripherals on APB, let's count it into the ABP mapping area.
+ */
+#define APB_PHYS_BASE 0xd4000000
+#define APB_VIRT_BASE 0xfe000000
+#define APB_PHYS_SIZE 0x00200000
+
+#define AXI_PHYS_BASE 0xd4200000
+#define AXI_VIRT_BASE 0xfe200000
+#define AXI_PHYS_SIZE 0x00200000
+
+/* Static Memory Controller - Chip Select 0 and 1 */
+#define SMC_CS0_PHYS_BASE 0x80000000
+#define SMC_CS0_PHYS_SIZE 0x10000000
+#define SMC_CS1_PHYS_BASE 0x90000000
+#define SMC_CS1_PHYS_SIZE 0x10000000
+
+#endif /* __ASM_MACH_ADDR_MAP_H */
diff --git a/arch/arm/mach-mmp/include/mach/clkdev.h b/arch/arm/mach-mmp/include/mach/clkdev.h
new file mode 100644
index 000000000000..2fb354e54e0d
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif /* __ASM_MACH_CLKDEV_H */
diff --git a/arch/arm/mach-mmp/include/mach/cputype.h b/arch/arm/mach-mmp/include/mach/cputype.h
new file mode 100644
index 000000000000..25e797b09083
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/cputype.h
@@ -0,0 +1,30 @@
+#ifndef __ASM_MACH_CPUTYPE_H
+#define __ASM_MACH_CPUTYPE_H
+
+#include <asm/cputype.h>
+
+/*
+ * CPU Stepping OLD_ID CPU_ID CHIP_ID
+ *
+ * PXA168 A0 0x41159263 0x56158400 0x00A0A333
+ * PXA910 Y0 0x41159262 0x56158000 0x00F0C910
+ */
+
+#ifdef CONFIG_CPU_PXA168
+# define __cpu_is_pxa168(id) \
+ ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x84; })
+#else
+# define __cpu_is_pxa168(id) (0)
+#endif
+
+#ifdef CONFIG_CPU_PXA910
+# define __cpu_is_pxa910(id) \
+ ({ unsigned int _id = ((id) >> 8) & 0xff; _id == 0x80; })
+#else
+# define __cpu_is_pxa910(id) (0)
+#endif
+
+#define cpu_is_pxa168() ({ __cpu_is_pxa168(read_cpuid_id()); })
+#define cpu_is_pxa910() ({ __cpu_is_pxa910(read_cpuid_id()); })
+
+#endif /* __ASM_MACH_CPUTYPE_H */
diff --git a/arch/arm/mach-mmp/include/mach/debug-macro.S b/arch/arm/mach-mmp/include/mach/debug-macro.S
new file mode 100644
index 000000000000..a850f87de51d
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/debug-macro.S
@@ -0,0 +1,23 @@
+/* arch/arm/mach-mmp/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copied from arch/arm/mach-pxa/include/mach/debug.S
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <mach/addr-map.h>
+
+ .macro addruart,rx
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ ldreq \rx, =APB_PHYS_BASE @ physical
+ ldrne \rx, =APB_VIRT_BASE @ virtual
+ orr \rx, \rx, #0x00017000
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-mmp/include/mach/devices.h b/arch/arm/mach-mmp/include/mach/devices.h
new file mode 100644
index 000000000000..24585397217e
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/devices.h
@@ -0,0 +1,37 @@
+#include <linux/types.h>
+
+#define MAX_RESOURCE_DMA 2
+
+/* structure for describing the on-chip devices */
+struct pxa_device_desc {
+ const char *dev_name;
+ const char *drv_name;
+ int id;
+ int irq;
+ unsigned long start;
+ unsigned long size;
+ int dma[MAX_RESOURCE_DMA];
+};
+
+#define PXA168_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...) \
+struct pxa_device_desc pxa168_device_##_name __initdata = { \
+ .dev_name = "pxa168-" #_name, \
+ .drv_name = _drv, \
+ .id = _id, \
+ .irq = IRQ_PXA168_##_irq, \
+ .start = _start, \
+ .size = _size, \
+ .dma = { _dma }, \
+};
+
+#define PXA910_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...) \
+struct pxa_device_desc pxa910_device_##_name __initdata = { \
+ .dev_name = "pxa910-" #_name, \
+ .drv_name = _drv, \
+ .id = _id, \
+ .irq = IRQ_PXA910_##_irq, \
+ .start = _start, \
+ .size = _size, \
+ .dma = { _dma }, \
+};
+extern int pxa_register_device(struct pxa_device_desc *, void *, size_t);
diff --git a/arch/arm/mach-mmp/include/mach/dma.h b/arch/arm/mach-mmp/include/mach/dma.h
new file mode 100644
index 000000000000..1d6914544da4
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/dma.h
@@ -0,0 +1,13 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/dma.h
+ */
+
+#ifndef __ASM_MACH_DMA_H
+#define __ASM_MACH_DMA_H
+
+#include <mach/addr-map.h>
+
+#define DMAC_REGS_VIRT (APB_VIRT_BASE + 0x00000)
+
+#include <plat/dma.h>
+#endif /* __ASM_MACH_DMA_H */
diff --git a/arch/arm/mach-mmp/include/mach/entry-macro.S b/arch/arm/mach-mmp/include/mach/entry-macro.S
new file mode 100644
index 000000000000..6d3cd35478b5
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/entry-macro.S
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/entry-macro.S
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <mach/regs-icu.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =ICU_AP_IRQ_SEL_INT_NUM
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \tmp, [\base, #0]
+ and \irqnr, \tmp, #0x3f
+ tst \tmp, #(1 << 6)
+ .endm
diff --git a/arch/arm/mach-mmp/include/mach/gpio.h b/arch/arm/mach-mmp/include/mach/gpio.h
new file mode 100644
index 000000000000..ab26d13295c4
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/gpio.h
@@ -0,0 +1,36 @@
+#ifndef __ASM_MACH_GPIO_H
+#define __ASM_MACH_GPIO_H
+
+#include <mach/addr-map.h>
+#include <mach/irqs.h>
+#include <asm-generic/gpio.h>
+
+#define GPIO_REGS_VIRT (APB_VIRT_BASE + 0x19000)
+
+#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
+#define GPIO_REG(x) (*((volatile u32 *)(GPIO_REGS_VIRT + (x))))
+
+#define NR_BUILTIN_GPIO (128)
+
+#define gpio_to_bank(gpio) ((gpio) >> 5)
+#define gpio_to_irq(gpio) (IRQ_GPIO_START + (gpio))
+#define irq_to_gpio(irq) ((irq) - IRQ_GPIO_START)
+
+
+#define __gpio_is_inverted(gpio) (0)
+#define __gpio_is_occupied(gpio) (0)
+
+/* NOTE: these macros are defined here to make optimization of
+ * gpio_{get,set}_value() to work when 'gpio' is a constant.
+ * Usage of these macros otherwise is no longer recommended,
+ * use generic GPIO API whenever possible.
+ */
+#define GPIO_bit(gpio) (1 << ((gpio) & 0x1f))
+
+#define GPLR(x) GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x00)
+#define GPDR(x) GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x0c)
+#define GPSR(x) GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x18)
+#define GPCR(x) GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x24)
+
+#include <plat/gpio.h>
+#endif /* __ASM_MACH_GPIO_H */
diff --git a/arch/arm/mach-mmp/include/mach/hardware.h b/arch/arm/mach-mmp/include/mach/hardware.h
new file mode 100644
index 000000000000..99264a5ce5e4
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/hardware.h
@@ -0,0 +1,4 @@
+#ifndef __ASM_MACH_HARDWARE_H
+#define __ASM_MACH_HARDWARE_H
+
+#endif /* __ASM_MACH_HARDWARE_H */
diff --git a/arch/arm/mach-mmp/include/mach/io.h b/arch/arm/mach-mmp/include/mach/io.h
new file mode 100644
index 000000000000..e7adf3d012c1
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/io.h
@@ -0,0 +1,21 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/io.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_IO_H
+#define __ASM_MACH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif /* __ASM_MACH_IO_H */
diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h
new file mode 100644
index 000000000000..e83e45ebf7a4
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/irqs.h
@@ -0,0 +1,119 @@
+#ifndef __ASM_MACH_IRQS_H
+#define __ASM_MACH_IRQS_H
+
+/*
+ * Interrupt numbers for PXA168
+ */
+#define IRQ_PXA168_NONE (-1)
+#define IRQ_PXA168_SSP3 0
+#define IRQ_PXA168_SSP2 1
+#define IRQ_PXA168_SSP1 2
+#define IRQ_PXA168_SSP0 3
+#define IRQ_PXA168_PMIC_INT 4
+#define IRQ_PXA168_RTC_INT 5
+#define IRQ_PXA168_RTC_ALARM 6
+#define IRQ_PXA168_TWSI0 7
+#define IRQ_PXA168_GPU 8
+#define IRQ_PXA168_KEYPAD 9
+#define IRQ_PXA168_ONEWIRE 12
+#define IRQ_PXA168_TIMER1 13
+#define IRQ_PXA168_TIMER2 14
+#define IRQ_PXA168_TIMER3 15
+#define IRQ_PXA168_CMU 16
+#define IRQ_PXA168_SSP4 17
+#define IRQ_PXA168_MSP_WAKEUP 19
+#define IRQ_PXA168_CF_WAKEUP 20
+#define IRQ_PXA168_XD_WAKEUP 21
+#define IRQ_PXA168_MFU 22
+#define IRQ_PXA168_MSP 23
+#define IRQ_PXA168_CF 24
+#define IRQ_PXA168_XD 25
+#define IRQ_PXA168_DDR_INT 26
+#define IRQ_PXA168_UART1 27
+#define IRQ_PXA168_UART2 28
+#define IRQ_PXA168_WDT 35
+#define IRQ_PXA168_FRQ_CHANGE 38
+#define IRQ_PXA168_SDH1 39
+#define IRQ_PXA168_SDH2 40
+#define IRQ_PXA168_LCD 41
+#define IRQ_PXA168_CI 42
+#define IRQ_PXA168_USB1 44
+#define IRQ_PXA168_NAND 45
+#define IRQ_PXA168_HIFI_DMA 46
+#define IRQ_PXA168_DMA_INT0 47
+#define IRQ_PXA168_DMA_INT1 48
+#define IRQ_PXA168_GPIOX 49
+#define IRQ_PXA168_USB2 51
+#define IRQ_PXA168_AC97 57
+#define IRQ_PXA168_TWSI1 58
+#define IRQ_PXA168_PMU 60
+#define IRQ_PXA168_SM_INT 63
+
+/*
+ * Interrupt numbers for PXA910
+ */
+#define IRQ_PXA910_AIRQ 0
+#define IRQ_PXA910_SSP3 1
+#define IRQ_PXA910_SSP2 2
+#define IRQ_PXA910_SSP1 3
+#define IRQ_PXA910_PMIC_INT 4
+#define IRQ_PXA910_RTC_INT 5
+#define IRQ_PXA910_RTC_ALARM 6
+#define IRQ_PXA910_TWSI0 7
+#define IRQ_PXA910_GPU 8
+#define IRQ_PXA910_KEYPAD 9
+#define IRQ_PXA910_ROTARY 10
+#define IRQ_PXA910_TRACKBALL 11
+#define IRQ_PXA910_ONEWIRE 12
+#define IRQ_PXA910_AP1_TIMER1 13
+#define IRQ_PXA910_AP1_TIMER2 14
+#define IRQ_PXA910_AP1_TIMER3 15
+#define IRQ_PXA910_IPC_AP0 16
+#define IRQ_PXA910_IPC_AP1 17
+#define IRQ_PXA910_IPC_AP2 18
+#define IRQ_PXA910_IPC_AP3 19
+#define IRQ_PXA910_IPC_AP4 20
+#define IRQ_PXA910_IPC_CP0 21
+#define IRQ_PXA910_IPC_CP1 22
+#define IRQ_PXA910_IPC_CP2 23
+#define IRQ_PXA910_IPC_CP3 24
+#define IRQ_PXA910_IPC_CP4 25
+#define IRQ_PXA910_L2_DDR 26
+#define IRQ_PXA910_UART2 27
+#define IRQ_PXA910_UART3 28
+#define IRQ_PXA910_AP2_TIMER1 29
+#define IRQ_PXA910_AP2_TIMER2 30
+#define IRQ_PXA910_CP2_TIMER1 31
+#define IRQ_PXA910_CP2_TIMER2 32
+#define IRQ_PXA910_CP2_TIMER3 33
+#define IRQ_PXA910_GSSP 34
+#define IRQ_PXA910_CP2_WDT 35
+#define IRQ_PXA910_MAIN_PMU 36
+#define IRQ_PXA910_CP_FREQ_CHG 37
+#define IRQ_PXA910_AP_FREQ_CHG 38
+#define IRQ_PXA910_MMC 39
+#define IRQ_PXA910_AEU 40
+#define IRQ_PXA910_LCD 41
+#define IRQ_PXA910_CCIC 42
+#define IRQ_PXA910_IRE 43
+#define IRQ_PXA910_USB1 44
+#define IRQ_PXA910_NAND 45
+#define IRQ_PXA910_HIFI_DMA 46
+#define IRQ_PXA910_DMA_INT0 47
+#define IRQ_PXA910_DMA_INT1 48
+#define IRQ_PXA910_AP_GPIO 49
+#define IRQ_PXA910_AP2_TIMER3 50
+#define IRQ_PXA910_USB2 51
+#define IRQ_PXA910_TWSI1 54
+#define IRQ_PXA910_CP_GPIO 55
+#define IRQ_PXA910_UART1 59 /* Slow UART */
+#define IRQ_PXA910_AP_PMU 60
+#define IRQ_PXA910_SM_INT 63 /* from PinMux */
+
+#define IRQ_GPIO_START 64
+#define IRQ_GPIO_NUM 128
+#define IRQ_GPIO(x) (IRQ_GPIO_START + (x))
+
+#define NR_IRQS (IRQ_GPIO_START + IRQ_GPIO_NUM)
+
+#endif /* __ASM_MACH_IRQS_H */
diff --git a/arch/arm/mach-mmp/include/mach/memory.h b/arch/arm/mach-mmp/include/mach/memory.h
new file mode 100644
index 000000000000..bdb21d70714c
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/memory.h
@@ -0,0 +1,14 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/memory.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_MEMORY_H
+#define __ASM_MACH_MEMORY_H
+
+#define PHYS_OFFSET UL(0x00000000)
+
+#endif /* __ASM_MACH_MEMORY_H */
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
new file mode 100644
index 000000000000..d0bdb6e3682b
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
@@ -0,0 +1,258 @@
+#ifndef __ASM_MACH_MFP_PXA168_H
+#define __ASM_MACH_MFP_PXA168_H
+
+#include <mach/mfp.h>
+
+/* GPIO */
+#define GPIO0_GPIO MFP_CFG(GPIO0, AF5)
+#define GPIO1_GPIO MFP_CFG(GPIO1, AF5)
+#define GPIO2_GPIO MFP_CFG(GPIO2, AF5)
+#define GPIO3_GPIO MFP_CFG(GPIO3, AF5)
+#define GPIO4_GPIO MFP_CFG(GPIO4, AF5)
+#define GPIO5_GPIO MFP_CFG(GPIO5, AF5)
+#define GPIO6_GPIO MFP_CFG(GPIO6, AF5)
+#define GPIO7_GPIO MFP_CFG(GPIO7, AF5)
+#define GPIO8_GPIO MFP_CFG(GPIO8, AF5)
+#define GPIO9_GPIO MFP_CFG(GPIO9, AF5)
+#define GPIO10_GPIO MFP_CFG(GPIO10, AF5)
+#define GPIO11_GPIO MFP_CFG(GPIO11, AF5)
+#define GPIO12_GPIO MFP_CFG(GPIO12, AF5)
+#define GPIO13_GPIO MFP_CFG(GPIO13, AF5)
+#define GPIO14_GPIO MFP_CFG(GPIO14, AF5)
+#define GPIO15_GPIO MFP_CFG(GPIO15, AF5)
+#define GPIO16_GPIO MFP_CFG(GPIO16, AF0)
+#define GPIO17_GPIO MFP_CFG(GPIO17, AF5)
+#define GPIO18_GPIO MFP_CFG(GPIO18, AF0)
+#define GPIO19_GPIO MFP_CFG(GPIO19, AF5)
+#define GPIO20_GPIO MFP_CFG(GPIO20, AF0)
+#define GPIO21_GPIO MFP_CFG(GPIO21, AF5)
+#define GPIO22_GPIO MFP_CFG(GPIO22, AF5)
+#define GPIO23_GPIO MFP_CFG(GPIO23, AF5)
+#define GPIO24_GPIO MFP_CFG(GPIO24, AF5)
+#define GPIO25_GPIO MFP_CFG(GPIO25, AF5)
+#define GPIO26_GPIO MFP_CFG(GPIO26, AF0)
+#define GPIO27_GPIO MFP_CFG(GPIO27, AF5)
+#define GPIO28_GPIO MFP_CFG(GPIO28, AF5)
+#define GPIO29_GPIO MFP_CFG(GPIO29, AF5)
+#define GPIO30_GPIO MFP_CFG(GPIO30, AF5)
+#define GPIO31_GPIO MFP_CFG(GPIO31, AF5)
+#define GPIO32_GPIO MFP_CFG(GPIO32, AF5)
+#define GPIO33_GPIO MFP_CFG(GPIO33, AF5)
+#define GPIO34_GPIO MFP_CFG(GPIO34, AF0)
+#define GPIO35_GPIO MFP_CFG(GPIO35, AF0)
+#define GPIO36_GPIO MFP_CFG(GPIO36, AF0)
+#define GPIO37_GPIO MFP_CFG(GPIO37, AF0)
+#define GPIO38_GPIO MFP_CFG(GPIO38, AF0)
+#define GPIO39_GPIO MFP_CFG(GPIO39, AF0)
+#define GPIO40_GPIO MFP_CFG(GPIO40, AF0)
+#define GPIO41_GPIO MFP_CFG(GPIO41, AF0)
+#define GPIO42_GPIO MFP_CFG(GPIO42, AF0)
+#define GPIO43_GPIO MFP_CFG(GPIO43, AF0)
+#define GPIO44_GPIO MFP_CFG(GPIO44, AF0)
+#define GPIO45_GPIO MFP_CFG(GPIO45, AF0)
+#define GPIO46_GPIO MFP_CFG(GPIO46, AF0)
+#define GPIO47_GPIO MFP_CFG(GPIO47, AF0)
+#define GPIO48_GPIO MFP_CFG(GPIO48, AF0)
+#define GPIO49_GPIO MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO MFP_CFG(GPIO52, AF0)
+#define GPIO53_GPIO MFP_CFG(GPIO53, AF0)
+#define GPIO54_GPIO MFP_CFG(GPIO54, AF0)
+#define GPIO55_GPIO MFP_CFG(GPIO55, AF0)
+#define GPIO56_GPIO MFP_CFG(GPIO56, AF0)
+#define GPIO57_GPIO MFP_CFG(GPIO57, AF0)
+#define GPIO58_GPIO MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO MFP_CFG(GPIO62, AF0)
+#define GPIO63_GPIO MFP_CFG(GPIO63, AF0)
+#define GPIO64_GPIO MFP_CFG(GPIO64, AF0)
+#define GPIO65_GPIO MFP_CFG(GPIO65, AF0)
+#define GPIO66_GPIO MFP_CFG(GPIO66, AF0)
+#define GPIO67_GPIO MFP_CFG(GPIO67, AF0)
+#define GPIO68_GPIO MFP_CFG(GPIO68, AF0)
+#define GPIO69_GPIO MFP_CFG(GPIO69, AF0)
+#define GPIO70_GPIO MFP_CFG(GPIO70, AF0)
+#define GPIO71_GPIO MFP_CFG(GPIO71, AF0)
+#define GPIO72_GPIO MFP_CFG(GPIO72, AF0)
+#define GPIO73_GPIO MFP_CFG(GPIO73, AF0)
+#define GPIO74_GPIO MFP_CFG(GPIO74, AF0)
+#define GPIO75_GPIO MFP_CFG(GPIO75, AF0)
+#define GPIO76_GPIO MFP_CFG(GPIO76, AF0)
+#define GPIO77_GPIO MFP_CFG(GPIO77, AF0)
+#define GPIO78_GPIO MFP_CFG(GPIO78, AF0)
+#define GPIO79_GPIO MFP_CFG(GPIO79, AF0)
+#define GPIO80_GPIO MFP_CFG(GPIO80, AF0)
+#define GPIO81_GPIO MFP_CFG(GPIO81, AF0)
+#define GPIO82_GPIO MFP_CFG(GPIO82, AF0)
+#define GPIO83_GPIO MFP_CFG(GPIO83, AF0)
+#define GPIO84_GPIO MFP_CFG(GPIO84, AF0)
+#define GPIO85_GPIO MFP_CFG(GPIO85, AF0)
+#define GPIO86_GPIO MFP_CFG(GPIO86, AF0)
+#define GPIO87_GPIO MFP_CFG(GPIO87, AF0)
+#define GPIO88_GPIO MFP_CFG(GPIO88, AF0)
+#define GPIO89_GPIO MFP_CFG(GPIO89, AF0)
+#define GPIO90_GPIO MFP_CFG(GPIO90, AF0)
+#define GPIO91_GPIO MFP_CFG(GPIO91, AF0)
+#define GPIO92_GPIO MFP_CFG(GPIO92, AF0)
+#define GPIO93_GPIO MFP_CFG(GPIO93, AF0)
+#define GPIO94_GPIO MFP_CFG(GPIO94, AF0)
+#define GPIO95_GPIO MFP_CFG(GPIO95, AF0)
+#define GPIO96_GPIO MFP_CFG(GPIO96, AF0)
+#define GPIO97_GPIO MFP_CFG(GPIO97, AF0)
+#define GPIO98_GPIO MFP_CFG(GPIO98, AF0)
+#define GPIO99_GPIO MFP_CFG(GPIO99, AF0)
+#define GPIO100_GPIO MFP_CFG(GPIO100, AF0)
+#define GPIO101_GPIO MFP_CFG(GPIO101, AF0)
+#define GPIO102_GPIO MFP_CFG(GPIO102, AF0)
+#define GPIO103_GPIO MFP_CFG(GPIO103, AF0)
+#define GPIO104_GPIO MFP_CFG(GPIO104, AF0)
+#define GPIO105_GPIO MFP_CFG(GPIO105, AF0)
+#define GPIO106_GPIO MFP_CFG(GPIO106, AF0)
+#define GPIO107_GPIO MFP_CFG(GPIO107, AF0)
+#define GPIO108_GPIO MFP_CFG(GPIO108, AF0)
+#define GPIO109_GPIO MFP_CFG(GPIO109, AF0)
+#define GPIO110_GPIO MFP_CFG(GPIO110, AF0)
+#define GPIO111_GPIO MFP_CFG(GPIO111, AF0)
+#define GPIO112_GPIO MFP_CFG(GPIO112, AF0)
+#define GPIO113_GPIO MFP_CFG(GPIO113, AF0)
+#define GPIO114_GPIO MFP_CFG(GPIO114, AF0)
+#define GPIO115_GPIO MFP_CFG(GPIO115, AF0)
+#define GPIO116_GPIO MFP_CFG(GPIO116, AF0)
+#define GPIO117_GPIO MFP_CFG(GPIO117, AF0)
+#define GPIO118_GPIO MFP_CFG(GPIO118, AF0)
+#define GPIO119_GPIO MFP_CFG(GPIO119, AF0)
+#define GPIO120_GPIO MFP_CFG(GPIO120, AF0)
+#define GPIO121_GPIO MFP_CFG(GPIO121, AF0)
+#define GPIO122_GPIO MFP_CFG(GPIO122, AF0)
+
+/* DFI */
+#define GPIO0_DFI_D15 MFP_CFG(GPIO0, AF0)
+#define GPIO1_DFI_D14 MFP_CFG(GPIO1, AF0)
+#define GPIO2_DFI_D13 MFP_CFG(GPIO2, AF0)
+#define GPIO3_DFI_D12 MFP_CFG(GPIO3, AF0)
+#define GPIO4_DFI_D11 MFP_CFG(GPIO4, AF0)
+#define GPIO5_DFI_D10 MFP_CFG(GPIO5, AF0)
+#define GPIO6_DFI_D9 MFP_CFG(GPIO6, AF0)
+#define GPIO7_DFI_D8 MFP_CFG(GPIO7, AF0)
+#define GPIO8_DFI_D7 MFP_CFG(GPIO8, AF0)
+#define GPIO9_DFI_D6 MFP_CFG(GPIO9, AF0)
+#define GPIO10_DFI_D5 MFP_CFG(GPIO10, AF0)
+#define GPIO11_DFI_D4 MFP_CFG(GPIO11, AF0)
+#define GPIO12_DFI_D3 MFP_CFG(GPIO12, AF0)
+#define GPIO13_DFI_D2 MFP_CFG(GPIO13, AF0)
+#define GPIO14_DFI_D1 MFP_CFG(GPIO14, AF0)
+#define GPIO15_DFI_D0 MFP_CFG(GPIO15, AF0)
+
+#define GPIO30_DFI_ADDR0 MFP_CFG(GPIO30, AF0)
+#define GPIO31_DFI_ADDR1 MFP_CFG(GPIO31, AF0)
+#define GPIO32_DFI_ADDR2 MFP_CFG(GPIO32, AF0)
+#define GPIO33_DFI_ADDR3 MFP_CFG(GPIO33, AF0)
+
+/* NAND */
+#define GPIO16_ND_nCS0 MFP_CFG(GPIO16, AF1)
+#define GPIO17_ND_nWE MFP_CFG(GPIO17, AF0)
+#define GPIO21_ND_ALE MFP_CFG(GPIO21, AF0)
+#define GPIO22_ND_CLE MFP_CFG(GPIO22, AF0)
+#define GPIO24_ND_nRE MFP_CFG(GPIO24, AF0)
+#define GPIO26_ND_RnB1 MFP_CFG(GPIO26, AF1)
+#define GPIO27_ND_RnB2 MFP_CFG(GPIO27, AF1)
+
+/* Static Memory Controller */
+#define GPIO18_SMC_nCS0 MFP_CFG(GPIO18, AF3)
+#define GPIO18_SMC_nCS1 MFP_CFG(GPIO18, AF2)
+#define GPIO16_SMC_nCS0 MFP_CFG(GPIO16, AF2)
+#define GPIO16_SMC_nCS1 MFP_CFG(GPIO16, AF3)
+#define GPIO19_SMC_nCS0 MFP_CFG(GPIO19, AF0)
+#define GPIO20_SMC_nCS1 MFP_CFG(GPIO20, AF2)
+#define GPIO23_SMC_nLUA MFP_CFG(GPIO23, AF0)
+#define GPIO25_SMC_nLLA MFP_CFG(GPIO25, AF0)
+#define GPIO27_SMC_IRQ MFP_CFG(GPIO27, AF0)
+#define GPIO28_SMC_RDY MFP_CFG(GPIO28, AF0)
+#define GPIO29_SMC_SCLK MFP_CFG(GPIO29, AF0)
+#define GPIO34_SMC_nCS1 MFP_CFG(GPIO34, AF2)
+#define GPIO35_SMC_BE1 MFP_CFG(GPIO35, AF2)
+#define GPIO36_SMC_BE2 MFP_CFG(GPIO36, AF2)
+
+/* Compact Flash */
+#define GPIO19_CF_nCE1 MFP_CFG(GPIO19, AF3)
+#define GPIO20_CF_nCE2 MFP_CFG(GPIO20, AF3)
+#define GPIO23_CF_nALE MFP_CFG(GPIO23, AF3)
+#define GPIO25_CF_nRESET MFP_CFG(GPIO25, AF3)
+#define GPIO28_CF_RDY MFP_CFG(GPIO28, AF3)
+#define GPIO29_CF_STSCH MFP_CFG(GPIO29, AF3)
+#define GPIO30_CF_nREG MFP_CFG(GPIO30, AF3)
+#define GPIO31_CF_nIOIS16 MFP_CFG(GPIO31, AF3)
+#define GPIO32_CF_nCD1 MFP_CFG(GPIO32, AF3)
+#define GPIO33_CF_nCD2 MFP_CFG(GPIO33, AF3)
+
+/* UART1 */
+#define GPIO107_UART1_TXD MFP_CFG_DRV(GPIO107, AF1, FAST)
+#define GPIO107_UART1_RXD MFP_CFG_DRV(GPIO107, AF2, FAST)
+#define GPIO108_UART1_RXD MFP_CFG_DRV(GPIO108, AF1, FAST)
+#define GPIO108_UART1_TXD MFP_CFG_DRV(GPIO108, AF2, FAST)
+#define GPIO109_UART1_CTS MFP_CFG(GPIO109, AF1)
+#define GPIO109_UART1_RTS MFP_CFG(GPIO109, AF2)
+#define GPIO110_UART1_RTS MFP_CFG(GPIO110, AF1)
+#define GPIO110_UART1_CTS MFP_CFG(GPIO110, AF2)
+#define GPIO111_UART1_RI MFP_CFG(GPIO111, AF1)
+#define GPIO111_UART1_DSR MFP_CFG(GPIO111, AF2)
+#define GPIO112_UART1_DTR MFP_CFG(GPIO111, AF1)
+#define GPIO112_UART1_DCD MFP_CFG(GPIO112, AF2)
+
+/* MMC1 */
+#define GPIO37_MMC1_DAT7 MFP_CFG(GPIO37, AF1)
+#define GPIO38_MMC1_DAT6 MFP_CFG(GPIO38, AF1)
+#define GPIO54_MMC1_DAT5 MFP_CFG(GPIO54, AF1)
+#define GPIO48_MMC1_DAT4 MFP_CFG(GPIO48, AF1)
+#define GPIO51_MMC1_DAT3 MFP_CFG(GPIO51, AF1)
+#define GPIO52_MMC1_DAT2 MFP_CFG(GPIO52, AF1)
+#define GPIO40_MMC1_DAT1 MFP_CFG(GPIO40, AF1)
+#define GPIO41_MMC1_DAT0 MFP_CFG(GPIO41, AF1)
+#define GPIO49_MMC1_CMD MFP_CFG(GPIO49, AF1)
+#define GPIO43_MMC1_CLK MFP_CFG(GPIO43, AF1)
+#define GPIO53_MMC1_CD MFP_CFG(GPIO53, AF1)
+#define GPIO46_MMC1_WP MFP_CFG(GPIO46, AF1)
+
+/* LCD */
+#define GPIO84_LCD_CS MFP_CFG(GPIO84, AF1)
+#define GPIO60_LCD_DD0 MFP_CFG(GPIO60, AF1)
+#define GPIO61_LCD_DD1 MFP_CFG(GPIO61, AF1)
+#define GPIO70_LCD_DD10 MFP_CFG(GPIO70, AF1)
+#define GPIO71_LCD_DD11 MFP_CFG(GPIO71, AF1)
+#define GPIO72_LCD_DD12 MFP_CFG(GPIO72, AF1)
+#define GPIO73_LCD_DD13 MFP_CFG(GPIO73, AF1)
+#define GPIO74_LCD_DD14 MFP_CFG(GPIO74, AF1)
+#define GPIO75_LCD_DD15 MFP_CFG(GPIO75, AF1)
+#define GPIO76_LCD_DD16 MFP_CFG(GPIO76, AF1)
+#define GPIO77_LCD_DD17 MFP_CFG(GPIO77, AF1)
+#define GPIO78_LCD_DD18 MFP_CFG(GPIO78, AF1)
+#define GPIO79_LCD_DD19 MFP_CFG(GPIO79, AF1)
+#define GPIO62_LCD_DD2 MFP_CFG(GPIO62, AF1)
+#define GPIO80_LCD_DD20 MFP_CFG(GPIO80, AF1)
+#define GPIO81_LCD_DD21 MFP_CFG(GPIO81, AF1)
+#define GPIO82_LCD_DD22 MFP_CFG(GPIO82, AF1)
+#define GPIO83_LCD_DD23 MFP_CFG(GPIO83, AF1)
+#define GPIO63_LCD_DD3 MFP_CFG(GPIO63, AF1)
+#define GPIO64_LCD_DD4 MFP_CFG(GPIO64, AF1)
+#define GPIO65_LCD_DD5 MFP_CFG(GPIO65, AF1)
+#define GPIO66_LCD_DD6 MFP_CFG(GPIO66, AF1)
+#define GPIO67_LCD_DD7 MFP_CFG(GPIO67, AF1)
+#define GPIO68_LCD_DD8 MFP_CFG(GPIO68, AF1)
+#define GPIO69_LCD_DD9 MFP_CFG(GPIO69, AF1)
+#define GPIO59_LCD_DENA_BIAS MFP_CFG(GPIO59, AF1)
+#define GPIO56_LCD_FCLK_RD MFP_CFG(GPIO56, AF1)
+#define GPIO57_LCD_LCLK_A0 MFP_CFG(GPIO57, AF1)
+#define GPIO58_LCD_PCLK_WR MFP_CFG(GPIO58, AF1)
+#define GPIO85_LCD_VSYNC MFP_CFG(GPIO85, AF1)
+
+/* I2S */
+#define GPIO113_I2S_MCLK MFP_CFG(GPIO113,AF6)
+#define GPIO114_I2S_FRM MFP_CFG(GPIO114,AF1)
+#define GPIO115_I2S_BCLK MFP_CFG(GPIO115,AF1)
+#define GPIO116_I2S_RXD MFP_CFG(GPIO116,AF2)
+#define GPIO117_I2S_TXD MFP_CFG(GPIO117,AF2)
+
+#endif /* __ASM_MACH_MFP_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa910.h b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
new file mode 100644
index 000000000000..48a1cbc7c56b
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
@@ -0,0 +1,157 @@
+#ifndef __ASM_MACH_MFP_PXA910_H
+#define __ASM_MACH_MFP_PXA910_H
+
+#include <mach/mfp.h>
+
+/* UART2 */
+#define GPIO47_UART2_RXD MFP_CFG(GPIO47, AF6)
+#define GPIO48_UART2_TXD MFP_CFG(GPIO48, AF6)
+
+/* UART3 */
+#define GPIO31_UART3_RXD MFP_CFG(GPIO31, AF4)
+#define GPIO32_UART3_TXD MFP_CFG(GPIO32, AF4)
+
+/*IRDA*/
+#define GPIO51_IRDA_SHDN MFP_CFG(GPIO51, AF0)
+
+/* SMC */
+#define SM_nCS0_nCS0 MFP_CFG(SM_nCS0, AF0)
+#define SM_ADV_SM_ADV MFP_CFG(SM_ADV, AF0)
+#define SM_SCLK_SM_SCLK MFP_CFG(SM_SCLK, AF0)
+#define SM_SCLK_SM_SCLK MFP_CFG(SM_SCLK, AF0)
+#define SM_BE0_SM_BE0 MFP_CFG(SM_BE0, AF1)
+#define SM_BE1_SM_BE1 MFP_CFG(SM_BE1, AF1)
+
+/* I2C */
+#define GPIO53_CI2C_SCL MFP_CFG(GPIO53, AF2)
+#define GPIO54_CI2C_SDA MFP_CFG(GPIO54, AF2)
+
+/* SSP1 (I2S) */
+#define GPIO24_SSP1_SDATA_IN MFP_CFG_DRV(GPIO24, AF1, MEDIUM)
+#define GPIO21_SSP1_BITCLK MFP_CFG_DRV(GPIO21, AF1, MEDIUM)
+#define GPIO20_SSP1_SYSCLK MFP_CFG_DRV(GPIO20, AF1, MEDIUM)
+#define GPIO22_SSP1_SYNC MFP_CFG_DRV(GPIO22, AF1, MEDIUM)
+#define GPIO23_SSP1_DATA_OUT MFP_CFG_DRV(GPIO23, AF1, MEDIUM)
+#define GPIO124_MN_CLK_OUT MFP_CFG_DRV(GPIO124, AF1, MEDIUM)
+#define GPIO123_CLK_REQ MFP_CFG_DRV(GPIO123, AF0, MEDIUM)
+
+/* DFI */
+#define DF_IO0_ND_IO0 MFP_CFG(DF_IO0, AF0)
+#define DF_IO1_ND_IO1 MFP_CFG(DF_IO1, AF0)
+#define DF_IO2_ND_IO2 MFP_CFG(DF_IO2, AF0)
+#define DF_IO3_ND_IO3 MFP_CFG(DF_IO3, AF0)
+#define DF_IO4_ND_IO4 MFP_CFG(DF_IO4, AF0)
+#define DF_IO5_ND_IO5 MFP_CFG(DF_IO5, AF0)
+#define DF_IO6_ND_IO6 MFP_CFG(DF_IO6, AF0)
+#define DF_IO7_ND_IO7 MFP_CFG(DF_IO7, AF0)
+#define DF_IO8_ND_IO8 MFP_CFG(DF_IO8, AF0)
+#define DF_IO9_ND_IO9 MFP_CFG(DF_IO9, AF0)
+#define DF_IO10_ND_IO10 MFP_CFG(DF_IO10, AF0)
+#define DF_IO11_ND_IO11 MFP_CFG(DF_IO11, AF0)
+#define DF_IO12_ND_IO12 MFP_CFG(DF_IO12, AF0)
+#define DF_IO13_ND_IO13 MFP_CFG(DF_IO13, AF0)
+#define DF_IO14_ND_IO14 MFP_CFG(DF_IO14, AF0)
+#define DF_IO15_ND_IO15 MFP_CFG(DF_IO15, AF0)
+#define DF_nCS0_SM_nCS2_nCS0 MFP_CFG(DF_nCS0_SM_nCS2, AF0)
+#define DF_ALE_SM_WEn_ND_ALE MFP_CFG(DF_ALE_SM_WEn, AF1)
+#define DF_CLE_SM_OEn_ND_CLE MFP_CFG(DF_CLE_SM_OEn, AF0)
+#define DF_WEn_DF_WEn MFP_CFG(DF_WEn, AF1)
+#define DF_REn_DF_REn MFP_CFG(DF_REn, AF1)
+#define DF_RDY0_DF_RDY0 MFP_CFG(DF_RDY0, AF0)
+
+/*keypad*/
+#define GPIO00_KP_MKIN0 MFP_CFG(GPIO0, AF1)
+#define GPIO01_KP_MKOUT0 MFP_CFG(GPIO1, AF1)
+#define GPIO02_KP_MKIN1 MFP_CFG(GPIO2, AF1)
+#define GPIO03_KP_MKOUT1 MFP_CFG(GPIO3, AF1)
+#define GPIO04_KP_MKIN2 MFP_CFG(GPIO4, AF1)
+#define GPIO05_KP_MKOUT2 MFP_CFG(GPIO5, AF1)
+#define GPIO06_KP_MKIN3 MFP_CFG(GPIO6, AF1)
+#define GPIO07_KP_MKOUT3 MFP_CFG(GPIO7, AF1)
+#define GPIO08_KP_MKIN4 MFP_CFG(GPIO8, AF1)
+#define GPIO09_KP_MKOUT4 MFP_CFG(GPIO9, AF1)
+#define GPIO10_KP_MKIN5 MFP_CFG(GPIO10, AF1)
+#define GPIO11_KP_MKOUT5 MFP_CFG(GPIO11, AF1)
+#define GPIO12_KP_MKIN6 MFP_CFG(GPIO12, AF1)
+#define GPIO13_KP_MKOUT6 MFP_CFG(GPIO13, AF1)
+#define GPIO14_KP_MKIN7 MFP_CFG(GPIO14, AF1)
+#define GPIO15_KP_MKOUT7 MFP_CFG(GPIO15, AF1)
+#define GPIO16_KP_DKIN0 MFP_CFG(GPIO16, AF1)
+#define GPIO17_KP_DKIN1 MFP_CFG(GPIO17, AF1)
+#define GPIO18_KP_DKIN2 MFP_CFG(GPIO18, AF1)
+#define GPIO19_KP_DKIN3 MFP_CFG(GPIO19, AF1)
+
+/* LCD */
+#define GPIO81_LCD_FCLK MFP_CFG(GPIO81, AF1)
+#define GPIO82_LCD_LCLK MFP_CFG(GPIO82, AF1)
+#define GPIO83_LCD_PCLK MFP_CFG(GPIO83, AF1)
+#define GPIO84_LCD_DENA MFP_CFG(GPIO84, AF1)
+#define GPIO85_LCD_DD0 MFP_CFG(GPIO85, AF1)
+#define GPIO86_LCD_DD1 MFP_CFG(GPIO86, AF1)
+#define GPIO87_LCD_DD2 MFP_CFG(GPIO87, AF1)
+#define GPIO88_LCD_DD3 MFP_CFG(GPIO88, AF1)
+#define GPIO89_LCD_DD4 MFP_CFG(GPIO89, AF1)
+#define GPIO90_LCD_DD5 MFP_CFG(GPIO90, AF1)
+#define GPIO91_LCD_DD6 MFP_CFG(GPIO91, AF1)
+#define GPIO92_LCD_DD7 MFP_CFG(GPIO92, AF1)
+#define GPIO93_LCD_DD8 MFP_CFG(GPIO93, AF1)
+#define GPIO94_LCD_DD9 MFP_CFG(GPIO94, AF1)
+#define GPIO95_LCD_DD10 MFP_CFG(GPIO95, AF1)
+#define GPIO96_LCD_DD11 MFP_CFG(GPIO96, AF1)
+#define GPIO97_LCD_DD12 MFP_CFG(GPIO97, AF1)
+#define GPIO98_LCD_DD13 MFP_CFG(GPIO98, AF1)
+#define GPIO100_LCD_DD14 MFP_CFG(GPIO100, AF1)
+#define GPIO101_LCD_DD15 MFP_CFG(GPIO101, AF1)
+#define GPIO102_LCD_DD16 MFP_CFG(GPIO102, AF1)
+#define GPIO103_LCD_DD17 MFP_CFG(GPIO103, AF1)
+#define GPIO104_LCD_DD18 MFP_CFG(GPIO104, AF1)
+#define GPIO105_LCD_DD19 MFP_CFG(GPIO105, AF1)
+#define GPIO106_LCD_DD20 MFP_CFG(GPIO106, AF1)
+#define GPIO107_LCD_DD21 MFP_CFG(GPIO107, AF1)
+#define GPIO108_LCD_DD22 MFP_CFG(GPIO108, AF1)
+#define GPIO109_LCD_DD23 MFP_CFG(GPIO109, AF1)
+
+#define GPIO104_LCD_SPIDOUT MFP_CFG(GPIO104, AF3)
+#define GPIO105_LCD_SPIDIN MFP_CFG(GPIO105, AF3)
+#define GPIO107_LCD_CS1 MFP_CFG(GPIO107, AF3)
+#define GPIO108_LCD_DCLK MFP_CFG(GPIO108, AF3)
+
+#define GPIO106_LCD_RESET MFP_CFG(GPIO106, AF0)
+
+/*smart panel*/
+#define GPIO82_LCD_A0 MFP_CFG(GPIO82, AF0)
+#define GPIO83_LCD_WR MFP_CFG(GPIO83, AF0)
+#define GPIO103_LCD_CS MFP_CFG(GPIO103, AF0)
+
+/*1wire*/
+#define GPIO106_1WIRE MFP_CFG(GPIO106, AF3)
+
+/*CCIC*/
+#define GPIO67_CCIC_IN7 MFP_CFG_DRV(GPIO67, AF1, MEDIUM)
+#define GPIO68_CCIC_IN6 MFP_CFG_DRV(GPIO68, AF1, MEDIUM)
+#define GPIO69_CCIC_IN5 MFP_CFG_DRV(GPIO69, AF1, MEDIUM)
+#define GPIO70_CCIC_IN4 MFP_CFG_DRV(GPIO70, AF1, MEDIUM)
+#define GPIO71_CCIC_IN3 MFP_CFG_DRV(GPIO71, AF1, MEDIUM)
+#define GPIO72_CCIC_IN2 MFP_CFG_DRV(GPIO72, AF1, MEDIUM)
+#define GPIO73_CCIC_IN1 MFP_CFG_DRV(GPIO73, AF1, MEDIUM)
+#define GPIO74_CCIC_IN0 MFP_CFG_DRV(GPIO74, AF1, MEDIUM)
+#define GPIO75_CAM_HSYNC MFP_CFG_DRV(GPIO75, AF1, MEDIUM)
+#define GPIO76_CAM_VSYNC MFP_CFG_DRV(GPIO76, AF1, MEDIUM)
+#define GPIO77_CAM_MCLK MFP_CFG_DRV(GPIO77, AF1, MEDIUM)
+#define GPIO78_CAM_PCLK MFP_CFG_DRV(GPIO78, AF1, MEDIUM)
+
+/* MMC1 */
+#define MMC1_DAT7_MMC1_DAT7 MFP_CFG_DRV(MMC1_DAT7, AF0, MEDIUM)
+#define MMC1_DAT6_MMC1_DAT6 MFP_CFG_DRV(MMC1_DAT6, AF0, MEDIUM)
+#define MMC1_DAT5_MMC1_DAT5 MFP_CFG_DRV(MMC1_DAT5, AF0, MEDIUM)
+#define MMC1_DAT4_MMC1_DAT4 MFP_CFG_DRV(MMC1_DAT4, AF0, MEDIUM)
+#define MMC1_DAT3_MMC1_DAT3 MFP_CFG_DRV(MMC1_DAT3, AF0, MEDIUM)
+#define MMC1_DAT2_MMC1_DAT2 MFP_CFG_DRV(MMC1_DAT2, AF0, MEDIUM)
+#define MMC1_DAT1_MMC1_DAT1 MFP_CFG_DRV(MMC1_DAT1, AF0, MEDIUM)
+#define MMC1_DAT0_MMC1_DAT0 MFP_CFG_DRV(MMC1_DAT0, AF0, MEDIUM)
+#define MMC1_CMD_MMC1_CMD MFP_CFG_DRV(MMC1_CMD, AF0, MEDIUM)
+#define MMC1_CLK_MMC1_CLK MFP_CFG_DRV(MMC1_CLK, AF0, MEDIUM)
+#define MMC1_CD_MMC1_CD MFP_CFG_DRV(MMC1_CD, AF0, MEDIUM)
+#define MMC1_WP_MMC1_WP MFP_CFG_DRV(MMC1_WP, AF0, MEDIUM)
+
+#endif /* __ASM_MACH MFP_PXA910_H */
diff --git a/arch/arm/mach-mmp/include/mach/mfp.h b/arch/arm/mach-mmp/include/mach/mfp.h
new file mode 100644
index 000000000000..277ea4cd0f9f
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mfp.h
@@ -0,0 +1,37 @@
+#ifndef __ASM_MACH_MFP_H
+#define __ASM_MACH_MFP_H
+
+#include <plat/mfp.h>
+
+/*
+ * NOTE: the MFPR register bit definitions on PXA168 processor lines are a
+ * bit different from those on PXA3xx. Bit [7:10] are now reserved, which
+ * were SLEEP_OE_N, SLEEP_DATA, SLEEP_SEL and the LSB of DRIVE bits.
+ *
+ * To cope with this difference and re-use the pxa3xx mfp code as much as
+ * possible, we make the following compromise:
+ *
+ * 1. SLEEP_OE_N will always be programmed to '1' (by MFP_LPM_FLOAT)
+ * 2. DRIVE strength definitions redefined to include the reserved bit10
+ * 3. Override MFP_CFG() and MFP_CFG_DRV()
+ * 4. Drop the use of MFP_CFG_LPM() and MFP_CFG_X()
+ */
+
+#define MFP_DRIVE_VERY_SLOW (0x0 << 13)
+#define MFP_DRIVE_SLOW (0x2 << 13)
+#define MFP_DRIVE_MEDIUM (0x4 << 13)
+#define MFP_DRIVE_FAST (0x8 << 13)
+
+#undef MFP_CFG
+#undef MFP_CFG_DRV
+#undef MFP_CFG_LPM
+#undef MFP_CFG_X
+#undef MFP_CFG_DEFAULT
+
+#define MFP_CFG(pin, af) \
+ (MFP_LPM_FLOAT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_MEDIUM)
+
+#define MFP_CFG_DRV(pin, af, drv) \
+ (MFP_LPM_FLOAT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_##drv)
+
+#endif /* __ASM_MACH_MFP_H */
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h
new file mode 100644
index 000000000000..ef0a8a2076e9
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_PXA168_H
+#define __ASM_MACH_PXA168_H
+
+#include <mach/devices.h>
+
+extern struct pxa_device_desc pxa168_device_uart1;
+extern struct pxa_device_desc pxa168_device_uart2;
+
+static inline int pxa168_add_uart(int id)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 1: d = &pxa168_device_uart1; break;
+ case 2: d = &pxa168_device_uart2; break;
+ }
+
+ if (d == NULL)
+ return -EINVAL;
+
+ return pxa_register_device(d, NULL, 0);
+}
+#endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/pxa910.h b/arch/arm/mach-mmp/include/mach/pxa910.h
new file mode 100644
index 000000000000..b7aeaf574c36
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/pxa910.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_PXA910_H
+#define __ASM_MACH_PXA910_H
+
+#include <mach/devices.h>
+
+extern struct pxa_device_desc pxa910_device_uart1;
+extern struct pxa_device_desc pxa910_device_uart2;
+
+static inline int pxa910_add_uart(int id)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 1: d = &pxa910_device_uart1; break;
+ case 2: d = &pxa910_device_uart2; break;
+ }
+
+ if (d == NULL)
+ return -EINVAL;
+
+ return pxa_register_device(d, NULL, 0);
+}
+#endif /* __ASM_MACH_PXA910_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apbc.h b/arch/arm/mach-mmp/include/mach/regs-apbc.h
new file mode 100644
index 000000000000..c6b8c9dc2026
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-apbc.h
@@ -0,0 +1,78 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-apbc.h
+ *
+ * Application Peripheral Bus Clock Unit
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_REGS_APBC_H
+#define __ASM_MACH_REGS_APBC_H
+
+#include <mach/addr-map.h>
+
+#define APBC_VIRT_BASE (APB_VIRT_BASE + 0x015000)
+#define APBC_REG(x) (APBC_VIRT_BASE + (x))
+
+/*
+ * APB clock register offsets for PXA168
+ */
+#define APBC_PXA168_UART1 APBC_REG(0x000)
+#define APBC_PXA168_UART2 APBC_REG(0x004)
+#define APBC_PXA168_GPIO APBC_REG(0x008)
+#define APBC_PXA168_PWM0 APBC_REG(0x00c)
+#define APBC_PXA168_PWM1 APBC_REG(0x010)
+#define APBC_PXA168_SSP1 APBC_REG(0x01c)
+#define APBC_PXA168_SSP2 APBC_REG(0x020)
+#define APBC_PXA168_RTC APBC_REG(0x028)
+#define APBC_PXA168_TWSI0 APBC_REG(0x02c)
+#define APBC_PXA168_KPC APBC_REG(0x030)
+#define APBC_PXA168_TIMERS APBC_REG(0x034)
+#define APBC_PXA168_AIB APBC_REG(0x03c)
+#define APBC_PXA168_SW_JTAG APBC_REG(0x040)
+#define APBC_PXA168_ONEWIRE APBC_REG(0x048)
+#define APBC_PXA168_SSP3 APBC_REG(0x04c)
+#define APBC_PXA168_ASFAR APBC_REG(0x050)
+#define APBC_PXA168_ASSAR APBC_REG(0x054)
+#define APBC_PXA168_SSP4 APBC_REG(0x058)
+#define APBC_PXA168_SSP5 APBC_REG(0x05c)
+#define APBC_PXA168_TWSI1 APBC_REG(0x06c)
+#define APBC_PXA168_UART3 APBC_REG(0x070)
+#define APBC_PXA168_AC97 APBC_REG(0x084)
+
+/*
+ * APB Clock register offsets for PXA910
+ */
+#define APBC_PXA910_UART0 APBC_REG(0x000)
+#define APBC_PXA910_UART1 APBC_REG(0x004)
+#define APBC_PXA910_GPIO APBC_REG(0x008)
+#define APBC_PXA910_PWM0 APBC_REG(0x00c)
+#define APBC_PXA910_PWM1 APBC_REG(0x010)
+#define APBC_PXA910_PWM2 APBC_REG(0x014)
+#define APBC_PXA910_PWM3 APBC_REG(0x018)
+#define APBC_PXA910_SSP1 APBC_REG(0x01c)
+#define APBC_PXA910_SSP2 APBC_REG(0x020)
+#define APBC_PXA910_IPC APBC_REG(0x024)
+#define APBC_PXA910_TWSI0 APBC_REG(0x02c)
+#define APBC_PXA910_KPC APBC_REG(0x030)
+#define APBC_PXA910_TIMERS APBC_REG(0x034)
+#define APBC_PXA910_TBROT APBC_REG(0x038)
+#define APBC_PXA910_AIB APBC_REG(0x03c)
+#define APBC_PXA910_SW_JTAG APBC_REG(0x040)
+#define APBC_PXA910_TIMERS1 APBC_REG(0x044)
+#define APBC_PXA910_ONEWIRE APBC_REG(0x048)
+#define APBC_PXA910_SSP3 APBC_REG(0x04c)
+#define APBC_PXA910_ASFAR APBC_REG(0x050)
+#define APBC_PXA910_ASSAR APBC_REG(0x054)
+
+/* Common APB clock register bit definitions */
+#define APBC_APBCLK (1 << 0) /* APB Bus Clock Enable */
+#define APBC_FNCLK (1 << 1) /* Functional Clock Enable */
+#define APBC_RST (1 << 2) /* Reset Generation */
+
+/* Functional Clock Selection Mask */
+#define APBC_FNCLKSEL(x) (((x) & 0xf) << 4)
+
+#endif /* __ASM_MACH_REGS_APBC_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h b/arch/arm/mach-mmp/include/mach/regs-apmu.h
new file mode 100644
index 000000000000..919030514120
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-apmu.h
+ *
+ * Application Subsystem Power Management Unit
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_REGS_APMU_H
+#define __ASM_MACH_REGS_APMU_H
+
+#include <mach/addr-map.h>
+
+#define APMU_VIRT_BASE (AXI_VIRT_BASE + 0x82800)
+#define APMU_REG(x) (APMU_VIRT_BASE + (x))
+
+/* Clock Reset Control */
+#define APMU_IRE APMU_REG(0x048)
+#define APMU_LCD APMU_REG(0x04c)
+#define APMU_CCIC APMU_REG(0x050)
+#define APMU_SDH0 APMU_REG(0x054)
+#define APMU_SDH1 APMU_REG(0x058)
+#define APMU_USB APMU_REG(0x05c)
+#define APMU_NAND APMU_REG(0x060)
+#define APMU_DMA APMU_REG(0x064)
+#define APMU_GEU APMU_REG(0x068)
+#define APMU_BUS APMU_REG(0x06c)
+
+#define APMU_FNCLK_EN (1 << 4)
+#define APMU_AXICLK_EN (1 << 3)
+#define APMU_FNRST_DIS (1 << 1)
+#define APMU_AXIRST_DIS (1 << 0)
+
+#endif /* __ASM_MACH_REGS_APMU_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-icu.h b/arch/arm/mach-mmp/include/mach/regs-icu.h
new file mode 100644
index 000000000000..e5f08723e0cc
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-icu.h
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-icu.h
+ *
+ * Interrupt Control Unit
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_ICU_H
+#define __ASM_MACH_ICU_H
+
+#include <mach/addr-map.h>
+
+#define ICU_VIRT_BASE (AXI_VIRT_BASE + 0x82000)
+#define ICU_REG(x) (ICU_VIRT_BASE + (x))
+
+#define ICU_INT_CONF(n) ICU_REG((n) << 2)
+#define ICU_INT_CONF_AP_INT (1 << 6)
+#define ICU_INT_CONF_CP_INT (1 << 5)
+#define ICU_INT_CONF_IRQ (1 << 4)
+#define ICU_INT_CONF_MASK (0xf)
+
+#define ICU_AP_FIQ_SEL_INT_NUM ICU_REG(0x108) /* AP FIQ Selected Interrupt */
+#define ICU_AP_IRQ_SEL_INT_NUM ICU_REG(0x10C) /* AP IRQ Selected Interrupt */
+#define ICU_AP_GBL_IRQ_MSK ICU_REG(0x114) /* AP Global Interrupt Mask */
+#define ICU_INT_STATUS_0 ICU_REG(0x128) /* Interrupt Stuats 0 */
+#define ICU_INT_STATUS_1 ICU_REG(0x12C) /* Interrupt Status 1 */
+
+#endif /* __ASM_MACH_ICU_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-timers.h b/arch/arm/mach-mmp/include/mach/regs-timers.h
new file mode 100644
index 000000000000..45589fec9fc7
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-timers.h
@@ -0,0 +1,44 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-timers.h
+ *
+ * Timers Module
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_REGS_TIMERS_H
+#define __ASM_MACH_REGS_TIMERS_H
+
+#include <mach/addr-map.h>
+
+#define TIMERS1_VIRT_BASE (APB_VIRT_BASE + 0x14000)
+#define TIMERS2_VIRT_BASE (APB_VIRT_BASE + 0x16000)
+
+#define TMR_CCR (0x0000)
+#define TMR_TN_MM(n, m) (0x0004 + ((n) << 3) + (((n) + (m)) << 2))
+#define TMR_CR(n) (0x0028 + ((n) << 2))
+#define TMR_SR(n) (0x0034 + ((n) << 2))
+#define TMR_IER(n) (0x0040 + ((n) << 2))
+#define TMR_PLVR(n) (0x004c + ((n) << 2))
+#define TMR_PLCR(n) (0x0058 + ((n) << 2))
+#define TMR_WMER (0x0064)
+#define TMR_WMR (0x0068)
+#define TMR_WVR (0x006c)
+#define TMR_WSR (0x0070)
+#define TMR_ICR(n) (0x0074 + ((n) << 2))
+#define TMR_WICR (0x0080)
+#define TMR_CER (0x0084)
+#define TMR_CMR (0x0088)
+#define TMR_ILR(n) (0x008c + ((n) << 2))
+#define TMR_WCR (0x0098)
+#define TMR_WFAR (0x009c)
+#define TMR_WSAR (0x00A0)
+#define TMR_CVWR(n) (0x00A4 + ((n) << 2))
+
+#define TMR_CCR_CS_0(x) (((x) & 0x3) << 0)
+#define TMR_CCR_CS_1(x) (((x) & 0x7) << 2)
+#define TMR_CCR_CS_2(x) (((x) & 0x3) << 5)
+
+#endif /* __ASM_MACH_REGS_TIMERS_H */
diff --git a/arch/arm/mach-mmp/include/mach/system.h b/arch/arm/mach-mmp/include/mach/system.h
new file mode 100644
index 000000000000..4f5b0e0ce6cf
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/system.h
@@ -0,0 +1,21 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/system.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_SYSTEM_H
+#define __ASM_MACH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ cpu_reset(0);
+}
+#endif /* __ASM_MACH_SYSTEM_H */
diff --git a/arch/arm/mach-mmp/include/mach/timex.h b/arch/arm/mach-mmp/include/mach/timex.h
new file mode 100644
index 000000000000..6cebbd0ca8f4
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/timex.h
@@ -0,0 +1,9 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/timex.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define CLOCK_TICK_RATE 3250000
diff --git a/arch/arm/mach-mmp/include/mach/uncompress.h b/arch/arm/mach-mmp/include/mach/uncompress.h
new file mode 100644
index 000000000000..c93d5fa5865c
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/uncompress.h
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-mmp/include/mach/uncompress.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/serial_reg.h>
+#include <mach/addr-map.h>
+
+#define UART1_BASE (APB_PHYS_BASE + 0x36000)
+#define UART2_BASE (APB_PHYS_BASE + 0x17000)
+#define UART3_BASE (APB_PHYS_BASE + 0x18000)
+
+static inline void putc(char c)
+{
+ volatile unsigned long *UART = (unsigned long *)UART2_BASE;
+
+ /* UART enabled? */
+ if (!(UART[UART_IER] & UART_IER_UUE))
+ return;
+
+ while (!(UART[UART_LSR] & UART_LSR_THRE))
+ barrier();
+
+ UART[UART_TX] = c;
+}
+
+/*
+ * This does not append a newline
+ */
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-mmp/include/mach/vmalloc.h b/arch/arm/mach-mmp/include/mach/vmalloc.h
new file mode 100644
index 000000000000..b60ccaf9fee7
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END 0xfe000000
diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq.c
new file mode 100644
index 000000000000..52ff2f065eba
--- /dev/null
+++ b/arch/arm/mach-mmp/irq.c
@@ -0,0 +1,55 @@
+/*
+ * linux/arch/arm/mach-mmp/irq.c
+ *
+ * Generic IRQ handling, GPIO IRQ demultiplexing, etc.
+ *
+ * Author: Bin Yang <bin.yang@marvell.com>
+ * Created: Sep 30, 2008
+ * Copyright: Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/regs-icu.h>
+
+#include "common.h"
+
+#define IRQ_ROUTE_TO_AP (ICU_INT_CONF_AP_INT | ICU_INT_CONF_IRQ)
+
+#define PRIORITY_DEFAULT 0x1
+#define PRIORITY_NONE 0x0 /* means IRQ disabled */
+
+static void icu_mask_irq(unsigned int irq)
+{
+ __raw_writel(PRIORITY_NONE, ICU_INT_CONF(irq));
+}
+
+static void icu_unmask_irq(unsigned int irq)
+{
+ __raw_writel(IRQ_ROUTE_TO_AP | PRIORITY_DEFAULT, ICU_INT_CONF(irq));
+}
+
+static struct irq_chip icu_irq_chip = {
+ .name = "icu_irq",
+ .ack = icu_mask_irq,
+ .mask = icu_mask_irq,
+ .unmask = icu_unmask_irq,
+};
+
+void __init icu_init_irq(void)
+{
+ int irq;
+
+ for (irq = 0; irq < 64; irq++) {
+ icu_mask_irq(irq);
+ set_irq_chip(irq, &icu_irq_chip);
+ set_irq_handler(irq, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
new file mode 100644
index 000000000000..ae924468658c
--- /dev/null
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -0,0 +1,111 @@
+/*
+ * linux/arch/arm/mach-mmp/pxa168.c
+ *
+ * Code specific to PXA168
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+
+#include <asm/mach/time.h>
+#include <mach/addr-map.h>
+#include <mach/cputype.h>
+#include <mach/regs-apbc.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+#include <mach/dma.h>
+#include <mach/devices.h>
+#include <mach/mfp.h>
+
+#include "common.h"
+#include "clock.h"
+
+#define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000)
+
+static struct mfp_addr_map pxa168_mfp_addr_map[] __initdata =
+{
+ MFP_ADDR_X(GPIO0, GPIO36, 0x04c),
+ MFP_ADDR_X(GPIO37, GPIO55, 0x000),
+ MFP_ADDR_X(GPIO56, GPIO123, 0x0e0),
+ MFP_ADDR_X(GPIO124, GPIO127, 0x0f4),
+
+ MFP_ADDR_END,
+};
+
+#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c)
+
+static void __init pxa168_init_gpio(void)
+{
+ int i;
+
+ /* enable GPIO clock */
+ __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA168_GPIO);
+
+ /* unmask GPIO edge detection for all 4 banks - APMASKx */
+ for (i = 0; i < 4; i++)
+ __raw_writel(0xffffffff, APMASK(i));
+
+ pxa_init_gpio(IRQ_PXA168_GPIOX, 0, 127, NULL);
+}
+
+void __init pxa168_init_irq(void)
+{
+ icu_init_irq();
+ pxa168_init_gpio();
+}
+
+/* APB peripheral clocks */
+static APBC_CLK(uart1, PXA168_UART1, 1, 14745600);
+static APBC_CLK(uart2, PXA168_UART2, 1, 14745600);
+
+/* device and clock bindings */
+static struct clk_lookup pxa168_clkregs[] = {
+ INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
+ INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
+};
+
+static int __init pxa168_init(void)
+{
+ if (cpu_is_pxa168()) {
+ mfp_init_base(MFPR_VIRT_BASE);
+ mfp_init_addr(pxa168_mfp_addr_map);
+ pxa_init_dma(IRQ_PXA168_DMA_INT0, 32);
+ clks_register(ARRAY_AND_SIZE(pxa168_clkregs));
+ }
+
+ return 0;
+}
+postcore_initcall(pxa168_init);
+
+/* system timer - clock enabled, 3.25MHz */
+#define TIMER_CLK_RST (APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3))
+
+static void __init pxa168_timer_init(void)
+{
+ /* this is early, we have to initialize the CCU registers by
+ * ourselves instead of using clk_* API. Clock rate is defined
+ * by APBC_TIMERS_CLK_RST (3.25MHz) and enabled free-running
+ */
+ __raw_writel(APBC_APBCLK | APBC_RST, APBC_PXA168_TIMERS);
+
+ /* 3.25MHz, bus/functional clock enabled, release reset */
+ __raw_writel(TIMER_CLK_RST, APBC_PXA168_TIMERS);
+
+ timer_init(IRQ_PXA168_TIMER1);
+}
+
+struct sys_timer pxa168_timer = {
+ .init = pxa168_timer_init,
+};
+
+/* on-chip devices */
+PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22);
+PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24);
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
new file mode 100644
index 000000000000..453f8f7758bf
--- /dev/null
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -0,0 +1,158 @@
+/*
+ * linux/arch/arm/mach-mmp/pxa910.c
+ *
+ * Code specific to PXA910
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+
+#include <asm/mach/time.h>
+#include <mach/addr-map.h>
+#include <mach/regs-apbc.h>
+#include <mach/regs-apmu.h>
+#include <mach/cputype.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+#include <mach/dma.h>
+#include <mach/mfp.h>
+#include <mach/devices.h>
+
+#include "common.h"
+#include "clock.h"
+
+#define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000)
+
+static struct mfp_addr_map pxa910_mfp_addr_map[] __initdata =
+{
+ MFP_ADDR_X(GPIO0, GPIO54, 0xdc),
+ MFP_ADDR_X(GPIO67, GPIO98, 0x1b8),
+ MFP_ADDR_X(GPIO100, GPIO109, 0x238),
+
+ MFP_ADDR(GPIO123, 0xcc),
+ MFP_ADDR(GPIO124, 0xd0),
+
+ MFP_ADDR(DF_IO0, 0x40),
+ MFP_ADDR(DF_IO1, 0x3c),
+ MFP_ADDR(DF_IO2, 0x38),
+ MFP_ADDR(DF_IO3, 0x34),
+ MFP_ADDR(DF_IO4, 0x30),
+ MFP_ADDR(DF_IO5, 0x2c),
+ MFP_ADDR(DF_IO6, 0x28),
+ MFP_ADDR(DF_IO7, 0x24),
+ MFP_ADDR(DF_IO8, 0x20),
+ MFP_ADDR(DF_IO9, 0x1c),
+ MFP_ADDR(DF_IO10, 0x18),
+ MFP_ADDR(DF_IO11, 0x14),
+ MFP_ADDR(DF_IO12, 0x10),
+ MFP_ADDR(DF_IO13, 0xc),
+ MFP_ADDR(DF_IO14, 0x8),
+ MFP_ADDR(DF_IO15, 0x4),
+
+ MFP_ADDR(DF_nCS0_SM_nCS2, 0x44),
+ MFP_ADDR(DF_nCS1_SM_nCS3, 0x48),
+ MFP_ADDR(SM_nCS0, 0x4c),
+ MFP_ADDR(SM_nCS1, 0x50),
+ MFP_ADDR(DF_WEn, 0x54),
+ MFP_ADDR(DF_REn, 0x58),
+ MFP_ADDR(DF_CLE_SM_OEn, 0x5c),
+ MFP_ADDR(DF_ALE_SM_WEn, 0x60),
+ MFP_ADDR(SM_SCLK, 0x64),
+ MFP_ADDR(DF_RDY0, 0x68),
+ MFP_ADDR(SM_BE0, 0x6c),
+ MFP_ADDR(SM_BE1, 0x70),
+ MFP_ADDR(SM_ADV, 0x74),
+ MFP_ADDR(DF_RDY1, 0x78),
+ MFP_ADDR(SM_ADVMUX, 0x7c),
+ MFP_ADDR(SM_RDY, 0x80),
+
+ MFP_ADDR_X(MMC1_DAT7, MMC1_WP, 0x84),
+
+ MFP_ADDR_END,
+};
+
+#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c)
+
+static void __init pxa910_init_gpio(void)
+{
+ int i;
+
+ /* enable GPIO clock */
+ __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA910_GPIO);
+
+ /* unmask GPIO edge detection for all 4 banks - APMASKx */
+ for (i = 0; i < 4; i++)
+ __raw_writel(0xffffffff, APMASK(i));
+
+ pxa_init_gpio(IRQ_PXA910_AP_GPIO, 0, 127, NULL);
+}
+
+void __init pxa910_init_irq(void)
+{
+ icu_init_irq();
+ pxa910_init_gpio();
+}
+
+/* APB peripheral clocks */
+static APBC_CLK(uart1, PXA910_UART0, 1, 14745600);
+static APBC_CLK(uart2, PXA910_UART1, 1, 14745600);
+
+/* device and clock bindings */
+static struct clk_lookup pxa910_clkregs[] = {
+ INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
+ INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
+};
+
+static int __init pxa910_init(void)
+{
+ if (cpu_is_pxa910()) {
+ mfp_init_base(MFPR_VIRT_BASE);
+ mfp_init_addr(pxa910_mfp_addr_map);
+ pxa_init_dma(IRQ_PXA910_DMA_INT0, 32);
+ clks_register(ARRAY_AND_SIZE(pxa910_clkregs));
+ }
+
+ return 0;
+}
+postcore_initcall(pxa910_init);
+
+/* system timer - clock enabled, 3.25MHz */
+#define TIMER_CLK_RST (APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3))
+
+static void __init pxa910_timer_init(void)
+{
+ /* reset and configure */
+ __raw_writel(APBC_APBCLK | APBC_RST, APBC_PXA910_TIMERS);
+ __raw_writel(TIMER_CLK_RST, APBC_PXA910_TIMERS);
+
+ timer_init(IRQ_PXA910_AP1_TIMER1);
+}
+
+struct sys_timer pxa910_timer = {
+ .init = pxa910_timer_init,
+};
+
+/* on-chip devices */
+
+/* NOTE: there are totally 3 UARTs on PXA910:
+ *
+ * UART1 - Slow UART (can be used both by AP and CP)
+ * UART2/3 - Fast UART
+ *
+ * To be backward compatible with the legacy FFUART/BTUART/STUART sequence,
+ * they are re-ordered as:
+ *
+ * pxa910_device_uart1 - UART2 as FFUART
+ * pxa910_device_uart2 - UART3 as BTUART
+ *
+ * UART1 is not used by AP for the moment.
+ */
+PXA910_DEVICE(uart1, "pxa2xx-uart", 0, UART2, 0xd4017000, 0x30, 21, 22);
+PXA910_DEVICE(uart2, "pxa2xx-uart", 1, UART3, 0xd4018000, 0x30, 23, 24);
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
new file mode 100644
index 000000000000..0e0c9220eaba
--- /dev/null
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -0,0 +1,109 @@
+/*
+ * linux/arch/arm/mach-mmp/tavorevb.c
+ *
+ * Support for the Marvell PXA910-based TavorEVB Development Platform.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa910.h>
+#include <mach/pxa910.h>
+#include <mach/gpio.h>
+
+#include "common.h"
+
+static unsigned long tavorevb_pin_config[] __initdata = {
+ /* UART2 */
+ GPIO47_UART2_RXD,
+ GPIO48_UART2_TXD,
+
+ /* SMC */
+ SM_nCS0_nCS0,
+ SM_ADV_SM_ADV,
+ SM_SCLK_SM_SCLK,
+ SM_SCLK_SM_SCLK,
+ SM_BE0_SM_BE0,
+ SM_BE1_SM_BE1,
+
+ /* DFI */
+ DF_IO0_ND_IO0,
+ DF_IO1_ND_IO1,
+ DF_IO2_ND_IO2,
+ DF_IO3_ND_IO3,
+ DF_IO4_ND_IO4,
+ DF_IO5_ND_IO5,
+ DF_IO6_ND_IO6,
+ DF_IO7_ND_IO7,
+ DF_IO8_ND_IO8,
+ DF_IO9_ND_IO9,
+ DF_IO10_ND_IO10,
+ DF_IO11_ND_IO11,
+ DF_IO12_ND_IO12,
+ DF_IO13_ND_IO13,
+ DF_IO14_ND_IO14,
+ DF_IO15_ND_IO15,
+ DF_nCS0_SM_nCS2_nCS0,
+ DF_ALE_SM_WEn_ND_ALE,
+ DF_CLE_SM_OEn_ND_CLE,
+ DF_WEn_DF_WEn,
+ DF_REn_DF_REn,
+ DF_RDY0_DF_RDY0,
+};
+
+static struct smc91x_platdata tavorevb_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = SMC_CS1_PHYS_BASE + 0x300,
+ .end = SMC_CS1_PHYS_BASE + 0xfffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(80),
+ .end = gpio_to_irq(80),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .platform_data = &tavorevb_smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static void __init tavorevb_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(tavorevb_pin_config));
+
+ /* on-chip devices */
+ pxa910_add_uart(1);
+
+ /* off-chip devices */
+ platform_device_register(&smc91x_device);
+}
+
+MACHINE_START(TAVOREVB, "PXA910 Evaluation Board (aka TavorEVB)")
+ .phys_io = APB_PHYS_BASE,
+ .boot_params = 0x00000100,
+ .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
+ .map_io = pxa_map_io,
+ .init_irq = pxa910_init_irq,
+ .timer = &pxa910_timer,
+ .init_machine = tavorevb_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
new file mode 100644
index 000000000000..b03a6eda7419
--- /dev/null
+++ b/arch/arm/mach-mmp/time.c
@@ -0,0 +1,199 @@
+/*
+ * linux/arch/arm/mach-mmp/time.c
+ *
+ * Support for clocksource and clockevents
+ *
+ * Copyright (C) 2008 Marvell International Ltd.
+ * All rights reserved.
+ *
+ * 2008-04-11: Jason Chagas <Jason.chagas@marvell.com>
+ * 2008-10-08: Bin Yang <bin.yang@marvell.com>
+ *
+ * The timers module actually includes three timers, each timer with upto
+ * three match comparators. Timer #0 is used here in free-running mode as
+ * the clock source, and match comparator #1 used as clock event device.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/cnt32_to_63.h>
+
+#include <mach/addr-map.h>
+#include <mach/regs-timers.h>
+#include <mach/irqs.h>
+
+#include "clock.h"
+
+#define TIMERS_VIRT_BASE TIMERS1_VIRT_BASE
+
+#define MAX_DELTA (0xfffffffe)
+#define MIN_DELTA (16)
+
+#define TCR2NS_SCALE_FACTOR 10
+
+static unsigned long tcr2ns_scale;
+
+static void __init set_tcr2ns_scale(unsigned long tcr_rate)
+{
+ unsigned long long v = 1000000000ULL << TCR2NS_SCALE_FACTOR;
+ do_div(v, tcr_rate);
+ tcr2ns_scale = v;
+ /*
+ * We want an even value to automatically clear the top bit
+ * returned by cnt32_to_63() without an additional run time
+ * instruction. So if the LSB is 1 then round it up.
+ */
+ if (tcr2ns_scale & 1)
+ tcr2ns_scale++;
+}
+
+/*
+ * FIXME: the timer needs some delay to stablize the counter capture
+ */
+static inline uint32_t timer_read(void)
+{
+ int delay = 100;
+
+ __raw_writel(1, TIMERS_VIRT_BASE + TMR_CVWR(0));
+
+ while (delay--)
+ cpu_relax();
+
+ return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(0));
+}
+
+unsigned long long sched_clock(void)
+{
+ unsigned long long v = cnt32_to_63(timer_read());
+ return (v * tcr2ns_scale) >> TCR2NS_SCALE_FACTOR;
+}
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *c = dev_id;
+
+ /* disable and clear pending interrupt status */
+ __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0));
+ __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_ICR(0));
+ c->event_handler(c);
+ return IRQ_HANDLED;
+}
+
+static int timer_set_next_event(unsigned long delta,
+ struct clock_event_device *dev)
+{
+ unsigned long flags, next;
+
+ local_irq_save(flags);
+
+ /* clear pending interrupt status and enable */
+ __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0));
+ __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_IER(0));
+
+ next = timer_read() + delta;
+ __raw_writel(next, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0));
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+static void timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *dev)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ switch (mode) {
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ /* disable the matching interrupt */
+ __raw_writel(0x00, TIMERS_VIRT_BASE + TMR_IER(0));
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ case CLOCK_EVT_MODE_PERIODIC:
+ break;
+ }
+ local_irq_restore(flags);
+}
+
+static struct clock_event_device ckevt = {
+ .name = "clockevent",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .rating = 200,
+ .set_next_event = timer_set_next_event,
+ .set_mode = timer_set_mode,
+};
+
+static cycle_t clksrc_read(void)
+{
+ return timer_read();
+}
+
+static struct clocksource cksrc = {
+ .name = "clocksource",
+ .shift = 20,
+ .rating = 200,
+ .read = clksrc_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init timer_config(void)
+{
+ uint32_t ccr = __raw_readl(TIMERS_VIRT_BASE + TMR_CCR);
+ uint32_t cer = __raw_readl(TIMERS_VIRT_BASE + TMR_CER);
+ uint32_t cmr = __raw_readl(TIMERS_VIRT_BASE + TMR_CMR);
+
+ __raw_writel(cer & ~0x1, TIMERS_VIRT_BASE + TMR_CER); /* disable */
+
+ ccr &= TMR_CCR_CS_0(0x3);
+ __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR);
+
+ /* free-running mode */
+ __raw_writel(cmr | 0x01, TIMERS_VIRT_BASE + TMR_CMR);
+
+ __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* free-running */
+ __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(0)); /* clear status */
+ __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0));
+
+ /* enable timer counter */
+ __raw_writel(cer | 0x01, TIMERS_VIRT_BASE + TMR_CER);
+}
+
+static struct irqaction timer_irq = {
+ .name = "timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = timer_interrupt,
+ .dev_id = &ckevt,
+};
+
+void __init timer_init(int irq)
+{
+ timer_config();
+
+ set_tcr2ns_scale(CLOCK_TICK_RATE);
+
+ ckevt.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt.shift);
+ ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt);
+ ckevt.min_delta_ns = clockevent_delta2ns(MIN_DELTA, &ckevt);
+ ckevt.cpumask = cpumask_of(0);
+
+ cksrc.mult = clocksource_hz2mult(CLOCK_TICK_RATE, cksrc.shift);
+
+ setup_irq(irq, &timer_irq);
+
+ clocksource_register(&cksrc);
+ clockevents_register_device(&ckevt);
+}
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
new file mode 100644
index 000000000000..08cfef6c92a2
--- /dev/null
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/arm/mach-mmp/ttc_dkb.c
+ *
+ * Support for the Marvell PXA910-based TTC_DKB Development Platform.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa910.h>
+#include <mach/pxa910.h>
+
+#include "common.h"
+
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+
+static unsigned long ttc_dkb_pin_config[] __initdata = {
+ /* UART2 */
+ GPIO47_UART2_RXD,
+ GPIO48_UART2_TXD,
+};
+
+static void __init ttc_dkb_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(ttc_dkb_pin_config));
+
+ /* on-chip devices */
+ pxa910_add_uart(1);
+}
+
+MACHINE_START(TTC_DKB, "PXA910-based TTC_DKB Development Platform")
+ .phys_io = APB_PHYS_BASE,
+ .boot_params = 0x00000100,
+ .io_pg_offst = (APB_VIRT_BASE >> 18) & 0xfffc,
+ .map_io = pxa_map_io,
+ .init_irq = pxa910_init_irq,
+ .timer = &pxa910_timer,
+ .init_machine = ttc_dkb_init,
+MACHINE_END
diff --git a/arch/arm/mach-msm/include/mach/system.h b/arch/arm/mach-msm/include/mach/system.h
index f05ad2e0f235..574ccc493daf 100644
--- a/arch/arm/mach-msm/include/mach/system.h
+++ b/arch/arm/mach-msm/include/mach/system.h
@@ -17,7 +17,7 @@
void arch_idle(void);
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
for (;;) ; /* depends on IPC w/ other core */
}
diff --git a/arch/arm/mach-mv78xx0/Kconfig b/arch/arm/mach-mv78xx0/Kconfig
index d83cb86837db..6fbe68fe4412 100644
--- a/arch/arm/mach-mv78xx0/Kconfig
+++ b/arch/arm/mach-mv78xx0/Kconfig
@@ -8,6 +8,12 @@ config MACH_DB78X00_BP
Say 'Y' here if you want your kernel to support the
Marvell DB-78x00-BP Development Board.
+config MACH_RD78X00_MASA
+ bool "Marvell RD-78x00-mASA Reference Design"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell RD-78x00-mASA Reference Design.
+
endmenu
endif
diff --git a/arch/arm/mach-mv78xx0/Makefile b/arch/arm/mach-mv78xx0/Makefile
index ec16c05c3b1b..da628b7f3bb6 100644
--- a/arch/arm/mach-mv78xx0/Makefile
+++ b/arch/arm/mach-mv78xx0/Makefile
@@ -1,2 +1,3 @@
obj-y += common.o addr-map.o irq.o pcie.o
obj-$(CONFIG_MACH_DB78X00_BP) += db78x00-bp-setup.o
+obj-$(CONFIG_MACH_RD78X00_MASA) += rd78x00-masa-setup.o
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
index b0e4e0d8f506..a575daaa62d1 100644
--- a/arch/arm/mach-mv78xx0/common.c
+++ b/arch/arm/mach-mv78xx0/common.c
@@ -14,7 +14,9 @@
#include <linux/serial_8250.h>
#include <linux/mbus.h>
#include <linux/mv643xx_eth.h>
+#include <linux/mv643xx_i2c.h>
#include <linux/ata_platform.h>
+#include <linux/ethtool.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <mach/mv78xx0.h>
@@ -430,9 +432,22 @@ static struct platform_device mv78xx0_ge10 = {
void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
{
+ u32 dev, rev;
+
eth_data->shared = &mv78xx0_ge10_shared;
mv78xx0_ge10.dev.platform_data = eth_data;
+ /*
+ * On the Z0, ge10 and ge11 are internally connected back
+ * to back, and not brought out.
+ */
+ mv78xx0_pcie_id(&dev, &rev);
+ if (dev == MV78X00_Z0_DEV_ID) {
+ eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
+ eth_data->speed = SPEED_1000;
+ eth_data->duplex = DUPLEX_FULL;
+ }
+
platform_device_register(&mv78xx0_ge10_shared);
platform_device_register(&mv78xx0_ge10);
}
@@ -484,13 +499,101 @@ static struct platform_device mv78xx0_ge11 = {
void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
{
+ u32 dev, rev;
+
eth_data->shared = &mv78xx0_ge11_shared;
mv78xx0_ge11.dev.platform_data = eth_data;
+ /*
+ * On the Z0, ge10 and ge11 are internally connected back
+ * to back, and not brought out.
+ */
+ mv78xx0_pcie_id(&dev, &rev);
+ if (dev == MV78X00_Z0_DEV_ID) {
+ eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
+ eth_data->speed = SPEED_1000;
+ eth_data->duplex = DUPLEX_FULL;
+ }
+
platform_device_register(&mv78xx0_ge11_shared);
platform_device_register(&mv78xx0_ge11);
}
+/*****************************************************************************
+ * I2C bus 0
+ ****************************************************************************/
+
+static struct mv64xxx_i2c_pdata mv78xx0_i2c_0_pdata = {
+ .freq_m = 8, /* assumes 166 MHz TCLK */
+ .freq_n = 3,
+ .timeout = 1000, /* Default timeout of 1 second */
+};
+
+static struct resource mv78xx0_i2c_0_resources[] = {
+ {
+ .name = "i2c 0 base",
+ .start = I2C_0_PHYS_BASE,
+ .end = I2C_0_PHYS_BASE + 0x1f,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "i2c 0 irq",
+ .start = IRQ_MV78XX0_I2C_0,
+ .end = IRQ_MV78XX0_I2C_0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static struct platform_device mv78xx0_i2c_0 = {
+ .name = MV64XXX_I2C_CTLR_NAME,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mv78xx0_i2c_0_resources),
+ .resource = mv78xx0_i2c_0_resources,
+ .dev = {
+ .platform_data = &mv78xx0_i2c_0_pdata,
+ },
+};
+
+/*****************************************************************************
+ * I2C bus 1
+ ****************************************************************************/
+
+static struct mv64xxx_i2c_pdata mv78xx0_i2c_1_pdata = {
+ .freq_m = 8, /* assumes 166 MHz TCLK */
+ .freq_n = 3,
+ .timeout = 1000, /* Default timeout of 1 second */
+};
+
+static struct resource mv78xx0_i2c_1_resources[] = {
+ {
+ .name = "i2c 1 base",
+ .start = I2C_1_PHYS_BASE,
+ .end = I2C_1_PHYS_BASE + 0x1f,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "i2c 1 irq",
+ .start = IRQ_MV78XX0_I2C_1,
+ .end = IRQ_MV78XX0_I2C_1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static struct platform_device mv78xx0_i2c_1 = {
+ .name = MV64XXX_I2C_CTLR_NAME,
+ .id = 1,
+ .num_resources = ARRAY_SIZE(mv78xx0_i2c_1_resources),
+ .resource = mv78xx0_i2c_1_resources,
+ .dev = {
+ .platform_data = &mv78xx0_i2c_1_pdata,
+ },
+};
+
+void __init mv78xx0_i2c_init(void)
+{
+ platform_device_register(&mv78xx0_i2c_0);
+ platform_device_register(&mv78xx0_i2c_1);
+}
/*****************************************************************************
* SATA
@@ -719,6 +822,32 @@ struct sys_timer mv78xx0_timer = {
/*****************************************************************************
* General
****************************************************************************/
+static char * __init mv78xx0_id(void)
+{
+ u32 dev, rev;
+
+ mv78xx0_pcie_id(&dev, &rev);
+
+ if (dev == MV78X00_Z0_DEV_ID) {
+ if (rev == MV78X00_REV_Z0)
+ return "MV78X00-Z0";
+ else
+ return "MV78X00-Rev-Unsupported";
+ } else if (dev == MV78100_DEV_ID) {
+ if (rev == MV78100_REV_A0)
+ return "MV78100-A0";
+ else
+ return "MV78100-Rev-Unsupported";
+ } else if (dev == MV78200_DEV_ID) {
+ if (rev == MV78100_REV_A0)
+ return "MV78200-A0";
+ else
+ return "MV78200-Rev-Unsupported";
+ } else {
+ return "Device-Unknown";
+ }
+}
+
static int __init is_l2_writethrough(void)
{
return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH);
@@ -737,7 +866,8 @@ void __init mv78xx0_init(void)
get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
tclk = get_tclk();
- printk(KERN_INFO "MV78xx0 core #%d, ", core_index);
+ printk(KERN_INFO "%s ", mv78xx0_id());
+ printk("core #%d, ", core_index);
printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
diff --git a/arch/arm/mach-mv78xx0/common.h b/arch/arm/mach-mv78xx0/common.h
index 78af5de319dd..befc22475469 100644
--- a/arch/arm/mach-mv78xx0/common.h
+++ b/arch/arm/mach-mv78xx0/common.h
@@ -29,6 +29,8 @@ void mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
void mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
int maj, int min);
+void mv78xx0_pcie_id(u32 *dev, u32 *rev);
+
void mv78xx0_ehci0_init(void);
void mv78xx0_ehci1_init(void);
void mv78xx0_ehci2_init(void);
@@ -42,6 +44,7 @@ void mv78xx0_uart0_init(void);
void mv78xx0_uart1_init(void);
void mv78xx0_uart2_init(void);
void mv78xx0_uart3_init(void);
+void mv78xx0_i2c_init(void);
extern struct sys_timer mv78xx0_timer;
diff --git a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
index 2e285bbb7bbd..efdabe04c69e 100644
--- a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
+++ b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
@@ -14,6 +14,7 @@
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
+#include <linux/i2c.h>
#include <mach/mv78xx0.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -28,21 +29,22 @@ static struct mv643xx_eth_platform_data db78x00_ge01_data = {
};
static struct mv643xx_eth_platform_data db78x00_ge10_data = {
- .phy_addr = MV643XX_ETH_PHY_NONE,
- .speed = SPEED_1000,
- .duplex = DUPLEX_FULL,
+ .phy_addr = MV643XX_ETH_PHY_ADDR(10),
};
static struct mv643xx_eth_platform_data db78x00_ge11_data = {
- .phy_addr = MV643XX_ETH_PHY_NONE,
- .speed = SPEED_1000,
- .duplex = DUPLEX_FULL,
+ .phy_addr = MV643XX_ETH_PHY_ADDR(11),
};
static struct mv_sata_platform_data db78x00_sata_data = {
.n_ports = 2,
};
+static struct i2c_board_info __initdata db78x00_i2c_rtc = {
+ I2C_BOARD_INFO("ds1338", 0x68),
+};
+
+
static void __init db78x00_init(void)
{
/*
@@ -64,6 +66,8 @@ static void __init db78x00_init(void)
mv78xx0_sata_init(&db78x00_sata_data);
mv78xx0_uart0_init();
mv78xx0_uart2_init();
+ mv78xx0_i2c_init();
+ i2c_register_board_info(0, &db78x00_i2c_rtc, 1);
} else {
mv78xx0_uart1_init();
mv78xx0_uart3_init();
diff --git a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
index e930ea5330a2..582cffc733ad 100644
--- a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
+++ b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
@@ -80,6 +80,18 @@
#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300)
/*
+ * Supported devices and revisions.
+ */
+#define MV78X00_Z0_DEV_ID 0x6381
+#define MV78X00_REV_Z0 1
+
+#define MV78100_DEV_ID 0x7810
+#define MV78100_REV_A0 1
+
+#define MV78200_DEV_ID 0x7820
+#define MV78200_REV_A0 1
+
+/*
* Register Map
*/
#define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x00000)
@@ -90,6 +102,8 @@
#define DEV_BUS_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x10000)
#define SAMPLE_AT_RESET_LOW (DEV_BUS_VIRT_BASE | 0x0030)
#define SAMPLE_AT_RESET_HIGH (DEV_BUS_VIRT_BASE | 0x0034)
+#define I2C_0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x1000)
+#define I2C_1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x1100)
#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2000)
#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2000)
#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2100)
diff --git a/arch/arm/mach-mv78xx0/include/mach/system.h b/arch/arm/mach-mv78xx0/include/mach/system.h
index 7d5179408832..1d6350b22d0b 100644
--- a/arch/arm/mach-mv78xx0/include/mach/system.h
+++ b/arch/arm/mach-mv78xx0/include/mach/system.h
@@ -17,7 +17,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
/*
* Enable soft reset to assert RSTOUTn.
diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c
index aad3a7a2f830..a560439dcc3c 100644
--- a/arch/arm/mach-mv78xx0/pcie.c
+++ b/arch/arm/mach-mv78xx0/pcie.c
@@ -33,6 +33,12 @@ static struct resource pcie_io_space;
static struct resource pcie_mem_space;
+void __init mv78xx0_pcie_id(u32 *dev, u32 *rev)
+{
+ *dev = orion_pcie_dev_id((void __iomem *)PCIE00_VIRT_BASE);
+ *rev = orion_pcie_rev((void __iomem *)PCIE00_VIRT_BASE);
+}
+
static void __init mv78xx0_pcie_preinit(void)
{
int i;
diff --git a/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c b/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
new file mode 100644
index 000000000000..e136b7a03355
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-mv78x00/rd78x00-masa-setup.c
+ *
+ * Marvell RD-78x00-mASA Development Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <mach/mv78xx0.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include "common.h"
+
+static struct mv643xx_eth_platform_data rd78x00_masa_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv643xx_eth_platform_data rd78x00_masa_ge01_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(9),
+};
+
+static struct mv643xx_eth_platform_data rd78x00_masa_ge10_data = {
+};
+
+static struct mv643xx_eth_platform_data rd78x00_masa_ge11_data = {
+};
+
+static struct mv_sata_platform_data rd78x00_masa_sata_data = {
+ .n_ports = 2,
+};
+
+static void __init rd78x00_masa_init(void)
+{
+ /*
+ * Basic MV78x00 setup. Needs to be called early.
+ */
+ mv78xx0_init();
+
+ /*
+ * Partition on-chip peripherals between the two CPU cores.
+ */
+ if (mv78xx0_core_index() == 0) {
+ mv78xx0_ehci0_init();
+ mv78xx0_ehci1_init();
+ mv78xx0_ge00_init(&rd78x00_masa_ge00_data);
+ mv78xx0_ge10_init(&rd78x00_masa_ge10_data);
+ mv78xx0_sata_init(&rd78x00_masa_sata_data);
+ mv78xx0_uart0_init();
+ mv78xx0_uart2_init();
+ } else {
+ mv78xx0_ehci2_init();
+ mv78xx0_ge01_init(&rd78x00_masa_ge01_data);
+ mv78xx0_ge11_init(&rd78x00_masa_ge11_data);
+ mv78xx0_uart1_init();
+ mv78xx0_uart3_init();
+ }
+}
+
+static int __init rd78x00_pci_init(void)
+{
+ /*
+ * Assign all PCIe devices to CPU core #0.
+ */
+ if (machine_is_rd78x00_masa() && mv78xx0_core_index() == 0)
+ mv78xx0_pcie_init(1, 1);
+
+ return 0;
+}
+subsys_initcall(rd78x00_pci_init);
+
+MACHINE_START(RD78X00_MASA, "Marvell RD-78x00-MASA Development Board")
+ /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+ .phys_io = MV78XX0_REGS_PHYS_BASE,
+ .io_pg_offst = ((MV78XX0_REGS_VIRT_BASE) >> 18) & 0xfffc,
+ .boot_params = 0x00000100,
+ .init_machine = rd78x00_masa_init,
+ .map_io = mv78xx0_map_io,
+ .init_irq = mv78xx0_init_irq,
+ .timer = &mv78xx0_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx1/Kconfig b/arch/arm/mach-mx1/Kconfig
index 2b59fc74784f..eb7660f5d4b7 100644
--- a/arch/arm/mach-mx1/Kconfig
+++ b/arch/arm/mach-mx1/Kconfig
@@ -1,6 +1,6 @@
if ARCH_MX1
-comment "MX1 Platforms"
+comment "MX1 platforms:"
config MACH_MXLADS
bool
@@ -11,4 +11,9 @@ config ARCH_MX1ADS
help
Say Y here if you are using Motorola MX1ADS/MXLADS boards
+config MACH_SCB9328
+ bool "Synertronixx scb9328"
+ help
+ Say Y here if you are using a Synertronixx scb9328 board
+
endif
diff --git a/arch/arm/mach-mx1/Makefile b/arch/arm/mach-mx1/Makefile
index b969719011fa..82f1309568ef 100644
--- a/arch/arm/mach-mx1/Makefile
+++ b/arch/arm/mach-mx1/Makefile
@@ -8,3 +8,4 @@ obj-y += generic.o clock.o devices.o
# Specific board support
obj-$(CONFIG_ARCH_MX1ADS) += mx1ads.o
+obj-$(CONFIG_MACH_SCB9328) += scb9328.o \ No newline at end of file
diff --git a/arch/arm/mach-mx1/clock.c b/arch/arm/mach-mx1/clock.c
index 4bcd1ece55f5..0d0f306851d0 100644
--- a/arch/arm/mach-mx1/clock.c
+++ b/arch/arm/mach-mx1/clock.c
@@ -25,6 +25,7 @@
#include <mach/clock.h>
#include <mach/hardware.h>
+#include <mach/common.h>
#include "crm_regs.h"
static int _clk_enable(struct clk *clk)
@@ -87,33 +88,6 @@ static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
return clk->parent->set_rate(clk->parent, rate);
}
-/*
- * get the system pll clock in Hz
- *
- * mfi + mfn / (mfd +1)
- * f = 2 * f_ref * --------------------
- * pd + 1
- */
-static unsigned long mx1_decode_pll(unsigned int pll, u32 f_ref)
-{
- unsigned long long ll;
- unsigned long quot;
-
- u32 mfi = (pll >> 10) & 0xf;
- u32 mfn = pll & 0x3ff;
- u32 mfd = (pll >> 16) & 0x3ff;
- u32 pd = (pll >> 26) & 0xf;
-
- mfi = mfi <= 5 ? 5 : mfi;
-
- ll = 2 * (unsigned long long)f_ref *
- ((mfi << 16) + (mfn << 16) / (mfd + 1));
- quot = (pd + 1) * (1 << 16);
- ll += quot / 2;
- do_div(ll, quot);
- return (unsigned long)ll;
-}
-
static unsigned long clk16m_get_rate(struct clk *clk)
{
return 16000000;
@@ -188,7 +162,7 @@ static struct clk prem_clk = {
static unsigned long system_clk_get_rate(struct clk *clk)
{
- return mx1_decode_pll(__raw_readl(CCM_SPCTL0),
+ return mxc_decode_pll(__raw_readl(CCM_SPCTL0),
clk_get_rate(clk->parent));
}
@@ -200,7 +174,7 @@ static struct clk system_clk = {
static unsigned long mcu_clk_get_rate(struct clk *clk)
{
- return mx1_decode_pll(__raw_readl(CCM_MPCTL0),
+ return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
clk_get_rate(clk->parent));
}
@@ -488,7 +462,7 @@ static struct clk clko_clk = {
};
static struct clk dma_clk = {
- .name = "dma_clk",
+ .name = "dma",
.parent = &hclk,
.round_rate = _clk_parent_round_rate,
.set_rate = _clk_parent_set_rate,
@@ -539,7 +513,7 @@ static struct clk gpt_clk = {
};
static struct clk uart_clk = {
- .name = "uart_clk",
+ .name = "uart",
.parent = &perclk[0],
.round_rate = _clk_parent_round_rate,
.set_rate = _clk_parent_set_rate,
@@ -621,7 +595,7 @@ static struct clk *mxc_clks[] = {
&rtc_clk,
};
-int __init mxc_clocks_init(unsigned long fref)
+int __init mx1_clocks_init(unsigned long fref)
{
struct clk **clkp;
unsigned int reg;
@@ -652,5 +626,7 @@ int __init mxc_clocks_init(unsigned long fref)
clk_enable(&hclk);
clk_enable(&fclk);
+ mxc_timer_init(&gpt_clk);
+
return 0;
}
diff --git a/arch/arm/mach-mx1/devices.c b/arch/arm/mach-mx1/devices.c
index a95644193f3f..97f42d96d7a1 100644
--- a/arch/arm/mach-mx1/devices.c
+++ b/arch/arm/mach-mx1/devices.c
@@ -23,10 +23,11 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
-
#include <mach/irqs.h>
#include <mach/hardware.h>
+#include "devices.h"
+
static struct resource imx_csi_resources[] = {
[0] = {
.start = 0x00224000,
diff --git a/arch/arm/mach-mx1/mx1ads.c b/arch/arm/mach-mx1/mx1ads.c
index 3200cf60e384..7ae229bc1b79 100644
--- a/arch/arm/mach-mx1/mx1ads.c
+++ b/arch/arm/mach-mx1/mx1ads.c
@@ -16,6 +16,8 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -25,7 +27,11 @@
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/imx-uart.h>
-#include <mach/iomux-mx1-mx2.h>
+#include <mach/irqs.h>
+#ifdef CONFIG_I2C_IMX
+#include <mach/i2c.h>
+#endif
+#include <mach/iomux.h>
#include "devices.h"
/*
@@ -105,6 +111,55 @@ static struct platform_device flash_device = {
};
/*
+ * I2C
+ */
+
+#ifdef CONFIG_I2C_IMX
+static int i2c_pins[] = {
+ PA15_PF_I2C_SDA,
+ PA16_PF_I2C_SCL,
+};
+
+static int i2c_init(struct device *dev)
+{
+ return mxc_gpio_setup_multiple_pins(i2c_pins,
+ ARRAY_SIZE(i2c_pins), "I2C");
+}
+
+static void i2c_exit(struct device *dev)
+{
+ mxc_gpio_release_multiple_pins(i2c_pins,
+ ARRAY_SIZE(i2c_pins));
+}
+
+static struct pcf857x_platform_data pcf857x_data[] = {
+ {
+ .gpio_base = 4 * 32,
+ }, {
+ .gpio_base = 4 * 32 + 16,
+ }
+};
+
+static struct imxi2c_platform_data mx1ads_i2c_data = {
+ .bitrate = 100000,
+ .init = i2c_init,
+ .exit = i2c_exit,
+};
+
+static struct i2c_board_info mx1ads_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf857x", 0x22),
+ .type = "pcf8575",
+ .platform_data = &pcf857x_data[0],
+ }, {
+ I2C_BOARD_INFO("pcf857x", 0x24),
+ .type = "pcf8575",
+ .platform_data = &pcf857x_data[1],
+ },
+};
+#endif
+
+/*
* Board init
*/
static void __init mx1ads_init(void)
@@ -115,12 +170,19 @@ static void __init mx1ads_init(void)
/* Physmap flash */
mxc_register_device(&flash_device, &mx1ads_flash_data);
+
+ /* I2C */
+#ifdef CONFIG_I2C_IMX
+ i2c_register_board_info(0, mx1ads_i2c_devices,
+ ARRAY_SIZE(mx1ads_i2c_devices));
+
+ mxc_register_device(&imx_i2c_device, &mx1ads_i2c_data);
+#endif
}
static void __init mx1ads_timer_init(void)
{
- mxc_clocks_init(32000);
- mxc_timer_init("gpt_clk");
+ mx1_clocks_init(32000);
}
struct sys_timer mx1ads_timer = {
diff --git a/arch/arm/mach-mx1/scb9328.c b/arch/arm/mach-mx1/scb9328.c
new file mode 100644
index 000000000000..0e71f3fa28bf
--- /dev/null
+++ b/arch/arm/mach-mx1/scb9328.c
@@ -0,0 +1,160 @@
+/*
+ * linux/arch/arm/mach-mx1/scb9328.c
+ *
+ * Copyright (c) 2004 Sascha Hauer <saschahauer@web.de>
+ * Copyright (c) 2006-2008 Juergen Beisert <jbeisert@netscape.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/interrupt.h>
+#include <linux/dm9000.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux.h>
+
+#include "devices.h"
+
+/*
+ * This scb9328 has a 32MiB flash
+ */
+static struct resource flash_resource = {
+ .start = IMX_CS0_PHYS,
+ .end = IMX_CS0_PHYS + (32 * 1024 * 1024) - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data scb_flash_data = {
+ .width = 2,
+};
+
+static struct platform_device scb_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &scb_flash_data,
+ },
+ .resource = &flash_resource,
+ .num_resources = 1,
+};
+
+/*
+ * scb9328 has a DM9000 network controller
+ * connected to CS5, with 16 bit data path
+ * and interrupt connected to GPIO 3
+ */
+
+/*
+ * internal datapath is fixed 16 bit
+ */
+static struct dm9000_plat_data dm9000_platdata = {
+ .flags = DM9000_PLATF_16BITONLY,
+};
+
+/*
+ * the DM9000 drivers wants two defined address spaces
+ * to gain access to address latch registers and the data path.
+ */
+static struct resource dm9000x_resources[] = {
+ [0] = {
+ .name = "address area",
+ .start = IMX_CS5_PHYS,
+ .end = IMX_CS5_PHYS + 1,
+ .flags = IORESOURCE_MEM /* address access */
+ },
+ [1] = {
+ .name = "data area",
+ .start = IMX_CS5_PHYS + 4,
+ .end = IMX_CS5_PHYS + 5,
+ .flags = IORESOURCE_MEM /* data access */
+ },
+ [2] = {
+ .start = IRQ_GPIOC(3),
+ .end = IRQ_GPIOC(3),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL
+ },
+};
+
+static struct platform_device dm9000x_device = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm9000x_resources),
+ .resource = dm9000x_resources,
+ .dev = {
+ .platform_data = &dm9000_platdata,
+ }
+};
+
+static int mxc_uart1_pins[] = {
+ PC9_PF_UART1_CTS,
+ PC10_PF_UART1_RTS,
+ PC11_PF_UART1_TXD,
+ PC12_PF_UART1_RXD,
+};
+
+static int uart1_mxc_init(struct platform_device *pdev)
+{
+ return mxc_gpio_setup_multiple_pins(mxc_uart1_pins,
+ ARRAY_SIZE(mxc_uart1_pins), "UART1");
+}
+
+static int uart1_mxc_exit(struct platform_device *pdev)
+{
+ mxc_gpio_release_multiple_pins(mxc_uart1_pins,
+ ARRAY_SIZE(mxc_uart1_pins));
+ return 0;
+}
+
+static struct imxuart_platform_data uart_pdata = {
+ .init = uart1_mxc_init,
+ .exit = uart1_mxc_exit,
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &scb_flash_device,
+ &dm9000x_device,
+};
+
+/*
+ * scb9328_init - Init the CPU card itself
+ */
+static void __init scb9328_init(void)
+{
+ mxc_register_device(&imx_uart1_device, &uart_pdata);
+
+ printk(KERN_INFO"Scb9328: Adding devices\n");
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init scb9328_timer_init(void)
+{
+ mx1_clocks_init(32000);
+}
+
+static struct sys_timer scb9328_timer = {
+ .init = scb9328_timer_init,
+};
+
+MACHINE_START(SCB9328, "Synertronixx scb9328")
+ /* Sascha Hauer */
+ .phys_io = 0x00200000,
+ .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc,
+ .boot_params = 0x08000100,
+ .map_io = mxc_map_io,
+ .init_irq = mxc_init_irq,
+ .timer = &scb9328_timer,
+ .init_machine = scb9328_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig
index 1eaa97cb716d..42a788842f49 100644
--- a/arch/arm/mach-mx2/Kconfig
+++ b/arch/arm/mach-mx2/Kconfig
@@ -1,14 +1,22 @@
-comment "MX2 family CPU support"
- depends on ARCH_MX2
+if ARCH_MX2
+
+choice
+ prompt "CPUs:"
+ default MACH_MX21
+
+config MACH_MX21
+ bool "i.MX21 support"
+ help
+ This enables support for Freescale's MX2 based i.MX21 processor.
config MACH_MX27
bool "i.MX27 support"
- depends on ARCH_MX2
help
This enables support for Freescale's MX2 based i.MX27 processor.
-comment "MX2 Platforms"
- depends on ARCH_MX2
+endchoice
+
+comment "MX2 platforms:"
config MACH_MX27ADS
bool "MX27ADS platform"
@@ -37,3 +45,5 @@ config MACH_PCM970_BASEBOARD
PCM970 evaluation board.
endchoice
+
+endif
diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile
index 382d86080e86..950649a91540 100644
--- a/arch/arm/mach-mx2/Makefile
+++ b/arch/arm/mach-mx2/Makefile
@@ -4,7 +4,9 @@
# Object file lists.
-obj-y := system.o generic.o devices.o serial.o
+obj-y := generic.o devices.o serial.o
+
+obj-$(CONFIG_MACH_MX21) += clock_imx21.o
obj-$(CONFIG_MACH_MX27) += cpu_imx27.o
obj-$(CONFIG_MACH_MX27) += clock_imx27.o
diff --git a/arch/arm/mach-mx2/Makefile.boot b/arch/arm/mach-mx2/Makefile.boot
index 696831dcd485..e867398a8fdb 100644
--- a/arch/arm/mach-mx2/Makefile.boot
+++ b/arch/arm/mach-mx2/Makefile.boot
@@ -1,3 +1,7 @@
- zreladdr-y := 0xA0008000
-params_phys-y := 0xA0000100
-initrd_phys-y := 0xA0800000
+zreladdr-$(CONFIG_MACH_MX21) := 0xC0008000
+params_phys-$(CONFIG_MACH_MX21) := 0xC0000100
+initrd_phys-$(CONFIG_MACH_MX21) := 0xC0800000
+
+zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000
+params_phys-$(CONFIG_MACH_MX27) := 0xA0000100
+initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000
diff --git a/arch/arm/mach-mx2/clock_imx21.c b/arch/arm/mach-mx2/clock_imx21.c
new file mode 100644
index 000000000000..2dee5c87614c
--- /dev/null
+++ b/arch/arm/mach-mx2/clock_imx21.c
@@ -0,0 +1,984 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+
+#include <mach/clock.h>
+#include <mach/common.h>
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include "crm_regs.h"
+
+static int _clk_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+ return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static int _clk_spll_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(CCM_CSCR);
+ reg |= CCM_CSCR_SPEN;
+ __raw_writel(reg, CCM_CSCR);
+
+ while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
+ ;
+ return 0;
+}
+
+static void _clk_spll_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(CCM_CSCR);
+ reg &= ~CCM_CSCR_SPEN;
+ __raw_writel(reg, CCM_CSCR);
+}
+
+
+#define CSCR() (__raw_readl(CCM_CSCR))
+#define PCDR0() (__raw_readl(CCM_PCDR0))
+#define PCDR1() (__raw_readl(CCM_PCDR1))
+
+static unsigned long _clk_perclkx_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ if (div > 64)
+ div = 64;
+
+ return parent_rate / div;
+}
+
+static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (clk->id < 0 || clk->id > 3)
+ return -EINVAL;
+
+ div = parent_rate / rate;
+ if (div > 64 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+ div--;
+
+ reg =
+ __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
+ (clk->id << 3));
+ reg |= div << (clk->id << 3);
+ __raw_writel(reg, CCM_PCDR1);
+
+ return 0;
+}
+
+static unsigned long _clk_usb_recalc(struct clk *clk)
+{
+ unsigned long usb_pdf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
+
+ return parent_rate / (usb_pdf + 1U);
+}
+
+static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf)
+{
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
+
+ return 2UL * parent_rate / pdf;
+}
+
+static unsigned long _clk_ssi1_recalc(struct clk *clk)
+{
+ return _clk_ssix_recalc(clk,
+ (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK)
+ >> CCM_PCDR0_SSI1BAUDDIV_OFFSET);
+}
+
+static unsigned long _clk_ssi2_recalc(struct clk *clk)
+{
+ return _clk_ssix_recalc(clk,
+ (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
+ CCM_PCDR0_SSI2BAUDDIV_OFFSET);
+}
+
+static unsigned long _clk_nfc_recalc(struct clk *clk)
+{
+ unsigned long nfc_pdf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK)
+ >> CCM_PCDR0_NFCDIV_OFFSET;
+
+ return parent_rate / (nfc_pdf + 1);
+}
+
+static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
+{
+ return clk->parent->round_rate(clk->parent, rate);
+}
+
+static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
+{
+ return clk->parent->set_rate(clk->parent, rate);
+}
+
+static unsigned long external_high_reference; /* in Hz */
+
+static unsigned long get_high_reference_clock_rate(struct clk *clk)
+{
+ return external_high_reference;
+}
+
+/*
+ * the high frequency external clock reference
+ * Default case is 26MHz.
+ */
+static struct clk ckih_clk = {
+ .get_rate = get_high_reference_clock_rate,
+};
+
+static unsigned long external_low_reference; /* in Hz */
+
+static unsigned long get_low_reference_clock_rate(struct clk *clk)
+{
+ return external_low_reference;
+}
+
+/*
+ * the low frequency external clock reference
+ * Default case is 32.768kHz.
+ */
+static struct clk ckil_clk = {
+ .get_rate = get_low_reference_clock_rate,
+};
+
+
+static unsigned long _clk_fpm_recalc(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) * 512;
+}
+
+/* Output of frequency pre multiplier */
+static struct clk fpm_clk = {
+ .parent = &ckil_clk,
+ .get_rate = _clk_fpm_recalc,
+};
+
+static unsigned long get_mpll_clk(struct clk *clk)
+{
+ uint32_t reg;
+ unsigned long ref_clk;
+ unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
+ unsigned long long temp;
+
+ ref_clk = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(CCM_MPCTL0);
+ pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
+ mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
+ mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
+ mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
+
+ mfi = (mfi <= 5) ? 5 : mfi;
+ temp = 2LL * ref_clk * mfn;
+ do_div(temp, mfd + 1);
+ temp = 2LL * ref_clk * mfi + temp;
+ do_div(temp, pdf + 1);
+
+ return (unsigned long)temp;
+}
+
+static struct clk mpll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = get_mpll_clk,
+};
+
+static unsigned long _clk_fclk_get_rate(struct clk *clk)
+{
+ unsigned long parent_rate;
+ u32 div;
+
+ div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
+ parent_rate = clk_get_rate(clk->parent);
+
+ return parent_rate / (div+1);
+}
+
+static struct clk fclk_clk = {
+ .parent = &mpll_clk,
+ .get_rate = _clk_fclk_get_rate
+};
+
+static unsigned long get_spll_clk(struct clk *clk)
+{
+ uint32_t reg;
+ unsigned long ref_clk;
+ unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
+ unsigned long long temp;
+
+ ref_clk = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(CCM_SPCTL0);
+ pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
+ mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
+ mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
+ mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
+
+ mfi = (mfi <= 5) ? 5 : mfi;
+ temp = 2LL * ref_clk * mfn;
+ do_div(temp, mfd + 1);
+ temp = 2LL * ref_clk * mfi + temp;
+ do_div(temp, pdf + 1);
+
+ return (unsigned long)temp;
+}
+
+static struct clk spll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = get_spll_clk,
+ .enable = _clk_spll_enable,
+ .disable = _clk_spll_disable,
+};
+
+static unsigned long get_hclk_clk(struct clk *clk)
+{
+ unsigned long rate;
+ unsigned long bclk_pdf;
+
+ bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
+ >> CCM_CSCR_BCLK_OFFSET;
+
+ rate = clk_get_rate(clk->parent);
+ return rate / (bclk_pdf + 1);
+}
+
+static struct clk hclk_clk = {
+ .parent = &fclk_clk,
+ .get_rate = get_hclk_clk,
+};
+
+static unsigned long get_ipg_clk(struct clk *clk)
+{
+ unsigned long rate;
+ unsigned long ipg_pdf;
+
+ ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
+
+ rate = clk_get_rate(clk->parent);
+ return rate / (ipg_pdf + 1);
+}
+
+static struct clk ipg_clk = {
+ .parent = &hclk_clk,
+ .get_rate = get_ipg_clk,
+};
+
+static unsigned long _clk_perclkx_recalc(struct clk *clk)
+{
+ unsigned long perclk_pdf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (clk->id < 0 || clk->id > 3)
+ return 0;
+
+ perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
+
+ return parent_rate / (perclk_pdf + 1);
+}
+
+static struct clk per_clk[] = {
+ {
+ .id = 0,
+ .parent = &mpll_clk,
+ .get_rate = _clk_perclkx_recalc,
+ }, {
+ .id = 1,
+ .parent = &mpll_clk,
+ .get_rate = _clk_perclkx_recalc,
+ }, {
+ .id = 2,
+ .parent = &mpll_clk,
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .get_rate = _clk_perclkx_recalc,
+ /* Enable/Disable done via lcd_clkc[1] */
+ }, {
+ .id = 3,
+ .parent = &mpll_clk,
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .get_rate = _clk_perclkx_recalc,
+ /* Enable/Disable done via csi_clk[1] */
+ },
+};
+
+static struct clk uart_ipg_clk[];
+
+static struct clk uart_clk[] = {
+ {
+ .id = 0,
+ .parent = &per_clk[0],
+ .secondary = &uart_ipg_clk[0],
+ }, {
+ .id = 1,
+ .parent = &per_clk[0],
+ .secondary = &uart_ipg_clk[1],
+ }, {
+ .id = 2,
+ .parent = &per_clk[0],
+ .secondary = &uart_ipg_clk[2],
+ }, {
+ .id = 3,
+ .parent = &per_clk[0],
+ .secondary = &uart_ipg_clk[3],
+ },
+};
+
+static struct clk uart_ipg_clk[] = {
+ {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_UART1_REG,
+ .enable_shift = CCM_PCCR_UART1_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_UART2_REG,
+ .enable_shift = CCM_PCCR_UART2_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_UART3_REG,
+ .enable_shift = CCM_PCCR_UART3_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 3,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_UART4_REG,
+ .enable_shift = CCM_PCCR_UART4_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk gpt_ipg_clk[];
+
+static struct clk gpt_clk[] = {
+ {
+ .id = 0,
+ .parent = &per_clk[0],
+ .secondary = &gpt_ipg_clk[0],
+ }, {
+ .id = 1,
+ .parent = &per_clk[0],
+ .secondary = &gpt_ipg_clk[1],
+ }, {
+ .id = 2,
+ .parent = &per_clk[0],
+ .secondary = &gpt_ipg_clk[2],
+ },
+};
+
+static struct clk gpt_ipg_clk[] = {
+ {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_GPT1_REG,
+ .enable_shift = CCM_PCCR_GPT1_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_GPT2_REG,
+ .enable_shift = CCM_PCCR_GPT2_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_GPT3_REG,
+ .enable_shift = CCM_PCCR_GPT3_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk pwm_clk[] = {
+ {
+ .parent = &per_clk[0],
+ .secondary = &pwm_clk[1],
+ }, {
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_PWM_REG,
+ .enable_shift = CCM_PCCR_PWM_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk sdhc_ipg_clk[];
+
+static struct clk sdhc_clk[] = {
+ {
+ .id = 0,
+ .parent = &per_clk[1],
+ .secondary = &sdhc_ipg_clk[0],
+ }, {
+ .id = 1,
+ .parent = &per_clk[1],
+ .secondary = &sdhc_ipg_clk[1],
+ },
+};
+
+static struct clk sdhc_ipg_clk[] = {
+ {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SDHC1_REG,
+ .enable_shift = CCM_PCCR_SDHC1_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SDHC2_REG,
+ .enable_shift = CCM_PCCR_SDHC2_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk cspi_ipg_clk[];
+
+static struct clk cspi_clk[] = {
+ {
+ .id = 0,
+ .parent = &per_clk[1],
+ .secondary = &cspi_ipg_clk[0],
+ }, {
+ .id = 1,
+ .parent = &per_clk[1],
+ .secondary = &cspi_ipg_clk[1],
+ }, {
+ .id = 2,
+ .parent = &per_clk[1],
+ .secondary = &cspi_ipg_clk[2],
+ },
+};
+
+static struct clk cspi_ipg_clk[] = {
+ {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_CSPI1_REG,
+ .enable_shift = CCM_PCCR_CSPI1_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_CSPI2_REG,
+ .enable_shift = CCM_PCCR_CSPI2_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 3,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_CSPI3_REG,
+ .enable_shift = CCM_PCCR_CSPI3_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk lcdc_clk[] = {
+ {
+ .parent = &per_clk[2],
+ .secondary = &lcdc_clk[1],
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+ }, {
+ .parent = &ipg_clk,
+ .secondary = &lcdc_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_LCDC_REG,
+ .enable_shift = CCM_PCCR_LCDC_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_LCDC_REG,
+ .enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk csi_clk[] = {
+ {
+ .parent = &per_clk[3],
+ .secondary = &csi_clk[1],
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+ }, {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_CSI_REG,
+ .enable_shift = CCM_PCCR_HCLK_CSI_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk usb_clk[] = {
+ {
+ .parent = &spll_clk,
+ .get_rate = _clk_usb_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_USBOTG_REG,
+ .enable_shift = CCM_PCCR_USBOTG_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_USBOTG_REG,
+ .enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET,
+ .disable = _clk_disable,
+ }
+};
+
+static struct clk ssi_ipg_clk[];
+
+static struct clk ssi_clk[] = {
+ {
+ .id = 0,
+ .parent = &mpll_clk,
+ .secondary = &ssi_ipg_clk[0],
+ .get_rate = _clk_ssi1_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SSI1_BAUD_REG,
+ .enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 1,
+ .parent = &mpll_clk,
+ .secondary = &ssi_ipg_clk[1],
+ .get_rate = _clk_ssi2_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SSI2_BAUD_REG,
+ .enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk ssi_ipg_clk[] = {
+ {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SSI1_REG,
+ .enable_shift = CCM_PCCR_SSI1_IPG_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SSI2_REG,
+ .enable_shift = CCM_PCCR_SSI2_IPG_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+
+static struct clk nfc_clk = {
+ .parent = &fclk_clk,
+ .get_rate = _clk_nfc_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_NFC_REG,
+ .enable_shift = CCM_PCCR_NFC_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk dma_clk[] = {
+ {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_DMA_REG,
+ .enable_shift = CCM_PCCR_DMA_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &dma_clk[1],
+ }, {
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_DMA_REG,
+ .enable_shift = CCM_PCCR_HCLK_DMA_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk brom_clk = {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_BROM_REG,
+ .enable_shift = CCM_PCCR_HCLK_BROM_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk emma_clk[] = {
+ {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_EMMA_REG,
+ .enable_shift = CCM_PCCR_EMMA_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &emma_clk[1],
+ }, {
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_EMMA_REG,
+ .enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET,
+ .disable = _clk_disable,
+ }
+};
+
+static struct clk slcdc_clk[] = {
+ {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SLCDC_REG,
+ .enable_shift = CCM_PCCR_SLCDC_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &slcdc_clk[1],
+ }, {
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_SLCDC_REG,
+ .enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET,
+ .disable = _clk_disable,
+ }
+};
+
+static struct clk wdog_clk = {
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_WDT_REG,
+ .enable_shift = CCM_PCCR_WDT_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk gpio_clk = {
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_GPIO_REG,
+ .enable_shift = CCM_PCCR_GPIO_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk i2c_clk = {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_I2C1_REG,
+ .enable_shift = CCM_PCCR_I2C1_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk kpp_clk = {
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_KPP_REG,
+ .enable_shift = CCM_PCCR_KPP_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk owire_clk = {
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_OWIRE_REG,
+ .enable_shift = CCM_PCCR_OWIRE_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk rtc_clk = {
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_RTC_REG,
+ .enable_shift = CCM_PCCR_RTC_OFFSET,
+ .disable = _clk_disable,
+};
+
+static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+ div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if (div > 8 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+ div--;
+
+ reg = __raw_readl(CCM_PCDR0);
+
+ if (clk->parent == &usb_clk[0]) {
+ reg &= ~CCM_PCDR0_48MDIV_MASK;
+ reg |= div << CCM_PCDR0_48MDIV_OFFSET;
+ }
+ __raw_writel(reg, CCM_PCDR0);
+
+ return 0;
+}
+
+static unsigned long _clk_clko_recalc(struct clk *clk)
+{
+ u32 div = 0;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (clk->parent == &usb_clk[0]) /* 48M */
+ div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK
+ >> CCM_PCDR0_48MDIV_OFFSET;
+ div++;
+
+ return parent_rate / div;
+}
+
+static struct clk clko_clk;
+
+static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
+
+ if (parent == &ckil_clk)
+ reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &fpm_clk)
+ reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &ckih_clk)
+ reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == mpll_clk.parent)
+ reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == spll_clk.parent)
+ reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &mpll_clk)
+ reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &spll_clk)
+ reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &fclk_clk)
+ reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &hclk_clk)
+ reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &ipg_clk)
+ reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &per_clk[0])
+ reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &per_clk[1])
+ reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &per_clk[2])
+ reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &per_clk[3])
+ reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &ssi_clk[0])
+ reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &ssi_clk[1])
+ reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &nfc_clk)
+ reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &usb_clk[0])
+ reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &clko_clk)
+ reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
+ else
+ return -EINVAL;
+
+ __raw_writel(reg, CCM_CCSR);
+
+ return 0;
+}
+
+static struct clk clko_clk = {
+ .get_rate = _clk_clko_recalc,
+ .set_rate = _clk_clko_set_rate,
+ .round_rate = _clk_clko_round_rate,
+ .set_parent = _clk_clko_set_parent,
+};
+
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+static struct clk_lookup lookups[] __initdata = {
+/* It's unlikely that any driver wants one of them directly:
+ _REGISTER_CLOCK(NULL, "ckih", ckih_clk)
+ _REGISTER_CLOCK(NULL, "ckil", ckil_clk)
+ _REGISTER_CLOCK(NULL, "fpm", fpm_clk)
+ _REGISTER_CLOCK(NULL, "mpll", mpll_clk)
+ _REGISTER_CLOCK(NULL, "spll", spll_clk)
+ _REGISTER_CLOCK(NULL, "fclk", fclk_clk)
+ _REGISTER_CLOCK(NULL, "hclk", hclk_clk)
+ _REGISTER_CLOCK(NULL, "ipg", ipg_clk)
+*/
+ _REGISTER_CLOCK(NULL, "perclk1", per_clk[0])
+ _REGISTER_CLOCK(NULL, "perclk2", per_clk[1])
+ _REGISTER_CLOCK(NULL, "perclk3", per_clk[2])
+ _REGISTER_CLOCK(NULL, "perclk4", per_clk[3])
+ _REGISTER_CLOCK(NULL, "clko", clko_clk)
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0])
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1])
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2])
+ _REGISTER_CLOCK("imx-uart.3", NULL, uart_clk[3])
+ _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0])
+ _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1])
+ _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2])
+ _REGISTER_CLOCK(NULL, "pwm", pwm_clk[0])
+ _REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0])
+ _REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1])
+ _REGISTER_CLOCK(NULL, "cspi1", cspi_clk[0])
+ _REGISTER_CLOCK(NULL, "cspi2", cspi_clk[1])
+ _REGISTER_CLOCK(NULL, "cspi3", cspi_clk[2])
+ _REGISTER_CLOCK(NULL, "lcdc", lcdc_clk[0])
+ _REGISTER_CLOCK(NULL, "csi", csi_clk[0])
+ _REGISTER_CLOCK(NULL, "usb", usb_clk[0])
+ _REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0])
+ _REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1])
+ _REGISTER_CLOCK(NULL, "nfc", nfc_clk)
+ _REGISTER_CLOCK(NULL, "dma", dma_clk[0])
+ _REGISTER_CLOCK(NULL, "brom", brom_clk)
+ _REGISTER_CLOCK(NULL, "emma", emma_clk[0])
+ _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0])
+ _REGISTER_CLOCK(NULL, "wdog", wdog_clk)
+ _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
+ _REGISTER_CLOCK(NULL, "i2c", i2c_clk)
+ _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
+ _REGISTER_CLOCK(NULL, "owire", owire_clk)
+ _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+};
+
+/*
+ * must be called very early to get information about the
+ * available clock rate when the timer framework starts
+ */
+int __init mx21_clocks_init(unsigned long lref, unsigned long href)
+{
+ int i;
+ u32 cscr;
+
+ external_low_reference = lref;
+ external_high_reference = href;
+
+ /* detect clock reference for both system PLL */
+ cscr = CSCR();
+ if (cscr & CCM_CSCR_MCU)
+ mpll_clk.parent = &ckih_clk;
+ else
+ mpll_clk.parent = &fpm_clk;
+
+ if (cscr & CCM_CSCR_SP)
+ spll_clk.parent = &ckih_clk;
+ else
+ spll_clk.parent = &fpm_clk;
+
+ for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ clkdev_add(&lookups[i]);
+
+ /* Turn off all clock gates */
+ __raw_writel(0, CCM_PCCR0);
+ __raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1);
+
+ /* This turns of the serial PLL as well */
+ spll_clk.disable(&spll_clk);
+
+ /* This will propagate to all children and init all the clock rates. */
+ clk_enable(&per_clk[0]);
+ clk_enable(&gpio_clk);
+
+#ifdef CONFIG_DEBUG_LL_CONSOLE
+ clk_enable(&uart_clk[0]);
+#endif
+
+ mxc_timer_init(&gpt_clk[0]);
+ return 0;
+}
diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c
index c69896d011a1..3f7280c490f0 100644
--- a/arch/arm/mach-mx2/clock_imx27.c
+++ b/arch/arm/mach-mx2/clock_imx27.c
@@ -1,6 +1,7 @@
/*
* Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -20,23 +21,60 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <mach/clock.h>
-#include <mach/common.h>
+#include <asm/clkdev.h>
#include <asm/div64.h>
-#include "crm_regs.h"
-
-static struct clk ckil_clk;
-static struct clk mpll_clk;
-static struct clk mpll_main_clk[];
-static struct clk spll_clk;
-
-static int _clk_enable(struct clk *clk)
+#include <mach/clock.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+
+/* Register offsets */
+#define CCM_CSCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x0)
+#define CCM_MPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4)
+#define CCM_MPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x8)
+#define CCM_SPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0xC)
+#define CCM_SPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10)
+#define CCM_OSC26MCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x14)
+#define CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18)
+#define CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1c)
+#define CCM_PCCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20)
+#define CCM_PCCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24)
+#define CCM_CCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28)
+#define CCM_PMCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x2c)
+#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30)
+#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34)
+
+#define CCM_CSCR_UPDATE_DIS (1 << 31)
+#define CCM_CSCR_SSI2 (1 << 23)
+#define CCM_CSCR_SSI1 (1 << 22)
+#define CCM_CSCR_VPU (1 << 21)
+#define CCM_CSCR_MSHC (1 << 20)
+#define CCM_CSCR_SPLLRES (1 << 19)
+#define CCM_CSCR_MPLLRES (1 << 18)
+#define CCM_CSCR_SP (1 << 17)
+#define CCM_CSCR_MCU (1 << 16)
+#define CCM_CSCR_OSC26MDIV (1 << 4)
+#define CCM_CSCR_OSC26M (1 << 3)
+#define CCM_CSCR_FPM (1 << 2)
+#define CCM_CSCR_SPEN (1 << 1)
+#define CCM_CSCR_MPEN (1 << 0)
+
+/* i.MX27 TO 2+ */
+#define CCM_CSCR_ARM_SRC (1 << 15)
+
+#define CCM_SPCTL1_LF (1 << 15)
+#define CCM_SPCTL1_BRMO (1 << 6)
+
+static struct clk mpll_main1_clk, mpll_main2_clk;
+
+static int clk_pccr_enable(struct clk *clk)
{
unsigned long reg;
+ if (!clk->enable_reg)
+ return 0;
+
reg = __raw_readl(clk->enable_reg);
reg |= 1 << clk->enable_shift;
__raw_writel(reg, clk->enable_reg);
@@ -44,16 +82,19 @@ static int _clk_enable(struct clk *clk)
return 0;
}
-static void _clk_disable(struct clk *clk)
+static void clk_pccr_disable(struct clk *clk)
{
unsigned long reg;
+ if (!clk->enable_reg)
+ return;
+
reg = __raw_readl(clk->enable_reg);
reg &= ~(1 << clk->enable_shift);
__raw_writel(reg, clk->enable_reg);
}
-static int _clk_spll_enable(struct clk *clk)
+static int clk_spll_enable(struct clk *clk)
{
unsigned long reg;
@@ -61,13 +102,12 @@ static int _clk_spll_enable(struct clk *clk)
reg |= CCM_CSCR_SPEN;
__raw_writel(reg, CCM_CSCR);
- while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
- ;
+ while (!(__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF));
return 0;
}
-static void _clk_spll_disable(struct clk *clk)
+static void clk_spll_disable(struct clk *clk)
{
unsigned long reg;
@@ -76,192 +116,30 @@ static void _clk_spll_disable(struct clk *clk)
__raw_writel(reg, CCM_CSCR);
}
-static void _clk_pccr01_enable(unsigned long mask0, unsigned long mask1)
-{
- unsigned long reg;
-
- reg = __raw_readl(CCM_PCCR0);
- reg |= mask0;
- __raw_writel(reg, CCM_PCCR0);
-
- reg = __raw_readl(CCM_PCCR1);
- reg |= mask1;
- __raw_writel(reg, CCM_PCCR1);
-
-}
-
-static void _clk_pccr01_disable(unsigned long mask0, unsigned long mask1)
-{
- unsigned long reg;
-
- reg = __raw_readl(CCM_PCCR0);
- reg &= ~mask0;
- __raw_writel(reg, CCM_PCCR0);
-
- reg = __raw_readl(CCM_PCCR1);
- reg &= ~mask1;
- __raw_writel(reg, CCM_PCCR1);
-}
-
-static void _clk_pccr10_enable(unsigned long mask1, unsigned long mask0)
-{
- unsigned long reg;
-
- reg = __raw_readl(CCM_PCCR1);
- reg |= mask1;
- __raw_writel(reg, CCM_PCCR1);
-
- reg = __raw_readl(CCM_PCCR0);
- reg |= mask0;
- __raw_writel(reg, CCM_PCCR0);
-}
-
-static void _clk_pccr10_disable(unsigned long mask1, unsigned long mask0)
-{
- unsigned long reg;
-
- reg = __raw_readl(CCM_PCCR1);
- reg &= ~mask1;
- __raw_writel(reg, CCM_PCCR1);
-
- reg = __raw_readl(CCM_PCCR0);
- reg &= ~mask0;
- __raw_writel(reg, CCM_PCCR0);
-}
-
-static int _clk_dma_enable(struct clk *clk)
-{
- _clk_pccr01_enable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
-
- return 0;
-}
-
-static void _clk_dma_disable(struct clk *clk)
-{
- _clk_pccr01_disable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
-}
-
-static int _clk_rtic_enable(struct clk *clk)
-{
- _clk_pccr01_enable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
-
- return 0;
-}
-
-static void _clk_rtic_disable(struct clk *clk)
-{
- _clk_pccr01_disable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
-}
-
-static int _clk_emma_enable(struct clk *clk)
-{
- _clk_pccr01_enable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
-
- return 0;
-}
-
-static void _clk_emma_disable(struct clk *clk)
-{
- _clk_pccr01_disable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
-}
-
-static int _clk_slcdc_enable(struct clk *clk)
-{
- _clk_pccr01_enable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
-
- return 0;
-}
-
-static void _clk_slcdc_disable(struct clk *clk)
-{
- _clk_pccr01_disable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
-}
-
-static int _clk_fec_enable(struct clk *clk)
-{
- _clk_pccr01_enable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
-
- return 0;
-}
-
-static void _clk_fec_disable(struct clk *clk)
-{
- _clk_pccr01_disable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
-}
-
-static int _clk_vpu_enable(struct clk *clk)
-{
- unsigned long reg;
-
- reg = __raw_readl(CCM_PCCR1);
- reg |= CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK;
- __raw_writel(reg, CCM_PCCR1);
-
- return 0;
-}
-
-static void _clk_vpu_disable(struct clk *clk)
+static int clk_cpu_set_parent(struct clk *clk, struct clk *parent)
{
- unsigned long reg;
-
- reg = __raw_readl(CCM_PCCR1);
- reg &= ~(CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK);
- __raw_writel(reg, CCM_PCCR1);
-}
-
-static int _clk_sahara2_enable(struct clk *clk)
-{
- _clk_pccr01_enable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
-
- return 0;
-}
-
-static void _clk_sahara2_disable(struct clk *clk)
-{
- _clk_pccr01_disable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
-}
-
-static int _clk_mstick1_enable(struct clk *clk)
-{
- _clk_pccr10_enable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
-
- return 0;
-}
-
-static void _clk_mstick1_disable(struct clk *clk)
-{
- _clk_pccr10_disable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
-}
-
-#define CSCR() (__raw_readl(CCM_CSCR))
-#define PCDR0() (__raw_readl(CCM_PCDR0))
-#define PCDR1() (__raw_readl(CCM_PCDR1))
-
-static int _clk_cpu_set_parent(struct clk *clk, struct clk *parent)
-{
- int cscr = CSCR();
+ int cscr = __raw_readl(CCM_CSCR);
if (clk->parent == parent)
return 0;
if (mx27_revision() >= CHIP_REV_2_0) {
- if (parent == &mpll_main_clk[0]) {
+ if (parent == &mpll_main1_clk) {
cscr |= CCM_CSCR_ARM_SRC;
} else {
- if (parent == &mpll_main_clk[1])
+ if (parent == &mpll_main2_clk)
cscr &= ~CCM_CSCR_ARM_SRC;
else
return -EINVAL;
}
__raw_writel(cscr, CCM_CSCR);
- } else
- return -ENODEV;
-
- clk->parent = parent;
- return 0;
+ clk->parent = parent;
+ return 0;
+ }
+ return -ENODEV;
}
-static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate)
+static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate)
{
int div;
unsigned long parent_rate;
@@ -278,7 +156,7 @@ static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate)
return parent_rate / div;
}
-static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+static int set_rate_cpu(struct clk *clk, unsigned long rate)
{
unsigned int div;
uint32_t reg;
@@ -295,19 +173,18 @@ static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
reg = __raw_readl(CCM_CSCR);
if (mx27_revision() >= CHIP_REV_2_0) {
- reg &= ~CCM_CSCR_ARM_MASK;
- reg |= div << CCM_CSCR_ARM_OFFSET;
- reg &= ~0x06;
- __raw_writel(reg | 0x80000000, CCM_CSCR);
+ reg &= ~(3 << 12);
+ reg |= div << 12;
+ reg &= ~(CCM_CSCR_FPM | CCM_CSCR_SPEN);
+ __raw_writel(reg | CCM_CSCR_UPDATE_DIS, CCM_CSCR);
} else {
- printk(KERN_ERR "Cant set CPU frequency!\n");
+ printk(KERN_ERR "Can't set CPU frequency!\n");
}
return 0;
}
-static unsigned long _clk_perclkx_round_rate(struct clk *clk,
- unsigned long rate)
+static unsigned long round_rate_per(struct clk *clk, unsigned long rate)
{
u32 div;
unsigned long parent_rate;
@@ -324,7 +201,7 @@ static unsigned long _clk_perclkx_round_rate(struct clk *clk,
return parent_rate / div;
}
-static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
+static int set_rate_per(struct clk *clk, unsigned long rate)
{
u32 reg;
u32 div;
@@ -340,84 +217,65 @@ static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
return -EINVAL;
div--;
- reg =
- __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
- (clk->id << 3));
+ reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk->id << 3));
reg |= div << (clk->id << 3);
__raw_writel(reg, CCM_PCDR1);
return 0;
}
-static unsigned long _clk_usb_recalc(struct clk *clk)
+static unsigned long get_rate_usb(struct clk *clk)
{
unsigned long usb_pdf;
unsigned long parent_rate;
parent_rate = clk_get_rate(clk->parent);
- usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
+ usb_pdf = (__raw_readl(CCM_CSCR) >> 28) & 0x7;
return parent_rate / (usb_pdf + 1U);
}
-static unsigned long _clk_ssi1_recalc(struct clk *clk)
+static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf)
{
- unsigned long ssi1_pdf;
unsigned long parent_rate;
parent_rate = clk_get_rate(clk->parent);
- ssi1_pdf = (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) >>
- CCM_PCDR0_SSI1BAUDDIV_OFFSET;
-
if (mx27_revision() >= CHIP_REV_2_0)
- ssi1_pdf += 4;
+ pdf += 4; /* MX27 TO2+ */
else
- ssi1_pdf = (ssi1_pdf < 2) ? 124UL : ssi1_pdf;
+ pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
- return 2UL * parent_rate / ssi1_pdf;
+ return 2UL * parent_rate / pdf;
}
-static unsigned long _clk_ssi2_recalc(struct clk *clk)
+static unsigned long get_rate_ssi1(struct clk *clk)
{
- unsigned long ssi2_pdf;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- ssi2_pdf = (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
- CCM_PCDR0_SSI2BAUDDIV_OFFSET;
-
- if (mx27_revision() >= CHIP_REV_2_0)
- ssi2_pdf += 4;
- else
- ssi2_pdf = (ssi2_pdf < 2) ? 124UL : ssi2_pdf;
+ return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f);
+}
- return 2UL * parent_rate / ssi2_pdf;
+static unsigned long get_rate_ssi2(struct clk *clk)
+{
+ return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f);
}
-static unsigned long _clk_nfc_recalc(struct clk *clk)
+static unsigned long get_rate_nfc(struct clk *clk)
{
unsigned long nfc_pdf;
unsigned long parent_rate;
parent_rate = clk_get_rate(clk->parent);
- if (mx27_revision() >= CHIP_REV_2_0) {
- nfc_pdf =
- (PCDR0() & CCM_PCDR0_NFCDIV2_MASK) >>
- CCM_PCDR0_NFCDIV2_OFFSET;
- } else {
- nfc_pdf =
- (PCDR0() & CCM_PCDR0_NFCDIV_MASK) >>
- CCM_PCDR0_NFCDIV_OFFSET;
- }
+ if (mx27_revision() >= CHIP_REV_2_0)
+ nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf;
+ else
+ nfc_pdf = (__raw_readl(CCM_PCDR0) >> 12) & 0xf;
return parent_rate / (nfc_pdf + 1);
}
-static unsigned long _clk_vpu_recalc(struct clk *clk)
+static unsigned long get_rate_vpu(struct clk *clk)
{
unsigned long vpu_pdf;
unsigned long parent_rate;
@@ -425,25 +283,27 @@ static unsigned long _clk_vpu_recalc(struct clk *clk)
parent_rate = clk_get_rate(clk->parent);
if (mx27_revision() >= CHIP_REV_2_0) {
- vpu_pdf =
- (PCDR0() & CCM_PCDR0_VPUDIV2_MASK) >>
- CCM_PCDR0_VPUDIV2_OFFSET;
+ vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f;
vpu_pdf += 4;
} else {
- vpu_pdf =
- (PCDR0() & CCM_PCDR0_VPUDIV_MASK) >>
- CCM_PCDR0_VPUDIV_OFFSET;
+ vpu_pdf = (__raw_readl(CCM_PCDR0) >> 8) & 0xf;
vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf;
}
+
return 2UL * parent_rate / vpu_pdf;
}
-static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
+static unsigned long round_rate_parent(struct clk *clk, unsigned long rate)
{
return clk->parent->round_rate(clk->parent, rate);
}
-static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
+static unsigned long get_rate_parent(struct clk *clk)
+{
+ return clk_get_rate(clk->parent);
+}
+
+static int set_rate_parent(struct clk *clk, unsigned long rate)
{
return clk->parent->set_rate(clk->parent, rate);
}
@@ -451,1112 +311,380 @@ static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
/* in Hz */
static unsigned long external_high_reference = 26000000;
-static unsigned long get_high_reference_clock_rate(struct clk *clk)
+static unsigned long get_rate_high_reference(struct clk *clk)
{
return external_high_reference;
}
-/*
- * the high frequency external clock reference
- * Default case is 26MHz. Could be changed at runtime
- * with a call to change_external_high_reference()
- */
-static struct clk ckih_clk = {
- .name = "ckih",
- .get_rate = get_high_reference_clock_rate,
-};
-
/* in Hz */
static unsigned long external_low_reference = 32768;
-static unsigned long get_low_reference_clock_rate(struct clk *clk)
+static unsigned long get_rate_low_reference(struct clk *clk)
{
return external_low_reference;
}
-/*
- * the low frequency external clock reference
- * Default case is 32.768kHz Could be changed at runtime
- * with a call to change_external_low_reference()
- */
-static struct clk ckil_clk = {
- .name = "ckil",
- .get_rate = get_low_reference_clock_rate,
-};
-
-static unsigned long get_mpll_clk(struct clk *clk)
+static unsigned long get_rate_fpm(struct clk *clk)
{
- uint32_t reg;
- unsigned long ref_clk;
- unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
- unsigned long long temp;
-
- ref_clk = clk_get_rate(clk->parent);
-
- reg = __raw_readl(CCM_MPCTL0);
- pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
- mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
- mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
- mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
-
- mfi = (mfi <= 5) ? 5 : mfi;
- temp = 2LL * ref_clk * mfn;
- do_div(temp, mfd + 1);
- temp = 2LL * ref_clk * mfi + temp;
- do_div(temp, pdf + 1);
-
- return (unsigned long)temp;
+ return clk_get_rate(clk->parent) * 1024;
}
-static struct clk mpll_clk = {
- .name = "mpll",
- .parent = &ckih_clk,
- .get_rate = get_mpll_clk,
-};
+static unsigned long get_rate_mpll(struct clk *clk)
+{
+ return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
+ clk_get_rate(clk->parent));
+}
-static unsigned long _clk_mpll_main_get_rate(struct clk *clk)
+static unsigned long get_rate_mpll_main(struct clk *clk)
{
unsigned long parent_rate;
parent_rate = clk_get_rate(clk->parent);
/* i.MX27 TO2:
- * clk->id == 0: arm clock source path 1 which is from 2*MPLL/DIV_2
- * clk->id == 1: arm clock source path 2 which is from 2*MPLL/DIV_3
+ * clk->id == 0: arm clock source path 1 which is from 2 * MPLL / 2
+ * clk->id == 1: arm clock source path 2 which is from 2 * MPLL / 3
*/
-
if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1)
return 2UL * parent_rate / 3UL;
return parent_rate;
}
-static struct clk mpll_main_clk[] = {
- {
- /* For i.MX27 TO2, it is the MPLL path 1 of ARM core
- * It provide the clock source whose rate is same as MPLL
- */
- .name = "mpll_main",
- .id = 0,
- .parent = &mpll_clk,
- .get_rate = _clk_mpll_main_get_rate
- }, {
- /* For i.MX27 TO2, it is the MPLL path 2 of ARM core
- * It provide the clock source whose rate is same MPLL * 2/3
- */
- .name = "mpll_main",
- .id = 1,
- .parent = &mpll_clk,
- .get_rate = _clk_mpll_main_get_rate
- }
-};
-
-static unsigned long get_spll_clk(struct clk *clk)
+static unsigned long get_rate_spll(struct clk *clk)
{
uint32_t reg;
- unsigned long ref_clk;
- unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
- unsigned long long temp;
+ unsigned long rate;
- ref_clk = clk_get_rate(clk->parent);
+ rate = clk_get_rate(clk->parent);
reg = __raw_readl(CCM_SPCTL0);
- /*TODO: This is TO2 Bug */
+
+ /* On TO2 we have to write the value back. Otherwise we
+ * read 0 from this register the next time.
+ */
if (mx27_revision() >= CHIP_REV_2_0)
__raw_writel(reg, CCM_SPCTL0);
- pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
- mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
- mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
- mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
-
- mfi = (mfi <= 5) ? 5 : mfi;
- temp = 2LL * ref_clk * mfn;
- do_div(temp, mfd + 1);
- temp = 2LL * ref_clk * mfi + temp;
- do_div(temp, pdf + 1);
-
- return (unsigned long)temp;
+ return mxc_decode_pll(reg, rate);
}
-static struct clk spll_clk = {
- .name = "spll",
- .parent = &ckih_clk,
- .get_rate = get_spll_clk,
- .enable = _clk_spll_enable,
- .disable = _clk_spll_disable,
-};
-
-static unsigned long get_cpu_clk(struct clk *clk)
+static unsigned long get_rate_cpu(struct clk *clk)
{
u32 div;
unsigned long rate;
if (mx27_revision() >= CHIP_REV_2_0)
- div = (CSCR() & CCM_CSCR_ARM_MASK) >> CCM_CSCR_ARM_OFFSET;
+ div = (__raw_readl(CCM_CSCR) >> 12) & 0x3;
else
- div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
+ div = (__raw_readl(CCM_CSCR) >> 13) & 0x7;
rate = clk_get_rate(clk->parent);
return rate / (div + 1);
}
-static struct clk cpu_clk = {
- .name = "cpu_clk",
- .parent = &mpll_main_clk[1],
- .set_parent = _clk_cpu_set_parent,
- .round_rate = _clk_cpu_round_rate,
- .get_rate = get_cpu_clk,
- .set_rate = _clk_cpu_set_rate,
-};
-
-static unsigned long get_ahb_clk(struct clk *clk)
+static unsigned long get_rate_ahb(struct clk *clk)
{
- unsigned long rate;
- unsigned long bclk_pdf;
+ unsigned long rate, bclk_pdf;
if (mx27_revision() >= CHIP_REV_2_0)
- bclk_pdf = (CSCR() & CCM_CSCR_AHB_MASK)
- >> CCM_CSCR_AHB_OFFSET;
+ bclk_pdf = (__raw_readl(CCM_CSCR) >> 8) & 0x3;
else
- bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
- >> CCM_CSCR_BCLK_OFFSET;
+ bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf;
rate = clk_get_rate(clk->parent);
return rate / (bclk_pdf + 1);
}
-static struct clk ahb_clk = {
- .name = "ahb_clk",
- .parent = &mpll_main_clk[1],
- .get_rate = get_ahb_clk,
-};
-
-static unsigned long get_ipg_clk(struct clk *clk)
+static unsigned long get_rate_ipg(struct clk *clk)
{
- unsigned long rate;
- unsigned long ipg_pdf;
+ unsigned long rate, ipg_pdf;
if (mx27_revision() >= CHIP_REV_2_0)
return clk_get_rate(clk->parent);
else
- ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
+ ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1;
rate = clk_get_rate(clk->parent);
return rate / (ipg_pdf + 1);
}
-static struct clk ipg_clk = {
- .name = "ipg_clk",
- .parent = &ahb_clk,
- .get_rate = get_ipg_clk,
-};
-
-static unsigned long _clk_perclkx_recalc(struct clk *clk)
+static unsigned long get_rate_per(struct clk *clk)
{
- unsigned long perclk_pdf;
- unsigned long parent_rate;
+ unsigned long perclk_pdf, parent_rate;
parent_rate = clk_get_rate(clk->parent);
if (clk->id < 0 || clk->id > 3)
return 0;
- perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
+ perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk->id << 3)) & 0x3f;
return parent_rate / (perclk_pdf + 1);
}
-static struct clk per_clk[] = {
- {
- .name = "per_clk",
- .id = 0,
- .parent = &mpll_main_clk[1],
- .get_rate = _clk_perclkx_recalc,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_PERCLK1_OFFSET,
- .disable = _clk_disable,
- }, {
- .name = "per_clk",
- .id = 1,
- .parent = &mpll_main_clk[1],
- .get_rate = _clk_perclkx_recalc,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_PERCLK2_OFFSET,
- .disable = _clk_disable,
- }, {
- .name = "per_clk",
- .id = 2,
- .parent = &mpll_main_clk[1],
- .round_rate = _clk_perclkx_round_rate,
- .set_rate = _clk_perclkx_set_rate,
- .get_rate = _clk_perclkx_recalc,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_PERCLK3_OFFSET,
- .disable = _clk_disable,
- }, {
- .name = "per_clk",
- .id = 3,
- .parent = &mpll_main_clk[1],
- .round_rate = _clk_perclkx_round_rate,
- .set_rate = _clk_perclkx_set_rate,
- .get_rate = _clk_perclkx_recalc,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_PERCLK4_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-struct clk uart1_clk[] = {
- {
- .name = "uart_clk",
- .id = 0,
- .parent = &per_clk[0],
- .secondary = &uart1_clk[1],
- }, {
- .name = "uart_ipg_clk",
- .id = 0,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_UART1_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-struct clk uart2_clk[] = {
- {
- .name = "uart_clk",
- .id = 1,
- .parent = &per_clk[0],
- .secondary = &uart2_clk[1],
- }, {
- .name = "uart_ipg_clk",
- .id = 1,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_UART2_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-struct clk uart3_clk[] = {
- {
- .name = "uart_clk",
- .id = 2,
- .parent = &per_clk[0],
- .secondary = &uart3_clk[1],
- }, {
- .name = "uart_ipg_clk",
- .id = 2,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_UART3_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-struct clk uart4_clk[] = {
- {
- .name = "uart_clk",
- .id = 3,
- .parent = &per_clk[0],
- .secondary = &uart4_clk[1],
- }, {
- .name = "uart_ipg_clk",
- .id = 3,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_UART4_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-struct clk uart5_clk[] = {
- {
- .name = "uart_clk",
- .id = 4,
- .parent = &per_clk[0],
- .secondary = &uart5_clk[1],
- }, {
- .name = "uart_ipg_clk",
- .id = 4,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_UART5_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-struct clk uart6_clk[] = {
- {
- .name = "uart_clk",
- .id = 5,
- .parent = &per_clk[0],
- .secondary = &uart6_clk[1],
- }, {
- .name = "uart_ipg_clk",
- .id = 5,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_UART6_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk gpt1_clk[] = {
- {
- .name = "gpt_clk",
- .id = 0,
- .parent = &per_clk[0],
- .secondary = &gpt1_clk[1],
- }, {
- .name = "gpt_ipg_clk",
- .id = 0,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_GPT1_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk gpt2_clk[] = {
- {
- .name = "gpt_clk",
- .id = 1,
- .parent = &per_clk[0],
- .secondary = &gpt2_clk[1],
- }, {
- .name = "gpt_ipg_clk",
- .id = 1,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_GPT2_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk gpt3_clk[] = {
- {
- .name = "gpt_clk",
- .id = 2,
- .parent = &per_clk[0],
- .secondary = &gpt3_clk[1],
- }, {
- .name = "gpt_ipg_clk",
- .id = 2,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_GPT3_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk gpt4_clk[] = {
- {
- .name = "gpt_clk",
- .id = 3,
- .parent = &per_clk[0],
- .secondary = &gpt4_clk[1],
- }, {
- .name = "gpt_ipg_clk",
- .id = 3,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_GPT4_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk gpt5_clk[] = {
- {
- .name = "gpt_clk",
- .id = 4,
- .parent = &per_clk[0],
- .secondary = &gpt5_clk[1],
- }, {
- .name = "gpt_ipg_clk",
- .id = 4,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_GPT5_OFFSET,
- .disable = _clk_disable,
- },
+/*
+ * the high frequency external clock reference
+ * Default case is 26MHz. Could be changed at runtime
+ * with a call to change_external_high_reference()
+ */
+static struct clk ckih_clk = {
+ .get_rate = get_rate_high_reference,
};
-static struct clk gpt6_clk[] = {
- {
- .name = "gpt_clk",
- .id = 5,
- .parent = &per_clk[0],
- .secondary = &gpt6_clk[1],
- }, {
- .name = "gpt_ipg_clk",
- .id = 5,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_GPT6_OFFSET,
- .disable = _clk_disable,
- },
+static struct clk mpll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = get_rate_mpll,
};
-static struct clk pwm_clk[] = {
- {
- .name = "pwm_clk",
- .parent = &per_clk[0],
- .secondary = &pwm_clk[1],
- }, {
- .name = "pwm_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_PWM_OFFSET,
- .disable = _clk_disable,
- },
+/* For i.MX27 TO2, it is the MPLL path 1 of ARM core
+ * It provides the clock source whose rate is same as MPLL
+ */
+static struct clk mpll_main1_clk = {
+ .id = 0,
+ .parent = &mpll_clk,
+ .get_rate = get_rate_mpll_main,
};
-static struct clk sdhc1_clk[] = {
- {
- .name = "sdhc_clk",
- .id = 0,
- .parent = &per_clk[1],
- .secondary = &sdhc1_clk[1],
- }, {
- .name = "sdhc_ipg_clk",
- .id = 0,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_SDHC1_OFFSET,
- .disable = _clk_disable,
- },
+/* For i.MX27 TO2, it is the MPLL path 2 of ARM core
+ * It provides the clock source whose rate is same MPLL * 2 / 3
+ */
+static struct clk mpll_main2_clk = {
+ .id = 1,
+ .parent = &mpll_clk,
+ .get_rate = get_rate_mpll_main,
};
-static struct clk sdhc2_clk[] = {
- {
- .name = "sdhc_clk",
- .id = 1,
- .parent = &per_clk[1],
- .secondary = &sdhc2_clk[1],
- }, {
- .name = "sdhc_ipg_clk",
- .id = 1,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_SDHC2_OFFSET,
- .disable = _clk_disable,
- },
+static struct clk ahb_clk = {
+ .parent = &mpll_main2_clk,
+ .get_rate = get_rate_ahb,
};
-static struct clk sdhc3_clk[] = {
- {
- .name = "sdhc_clk",
- .id = 2,
- .parent = &per_clk[1],
- .secondary = &sdhc3_clk[1],
- }, {
- .name = "sdhc_ipg_clk",
- .id = 2,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_SDHC3_OFFSET,
- .disable = _clk_disable,
- },
+static struct clk ipg_clk = {
+ .parent = &ahb_clk,
+ .get_rate = get_rate_ipg,
};
-static struct clk cspi1_clk[] = {
- {
- .name = "cspi_clk",
- .id = 0,
- .parent = &per_clk[1],
- .secondary = &cspi1_clk[1],
- }, {
- .name = "cspi_ipg_clk",
- .id = 0,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_CSPI1_OFFSET,
- .disable = _clk_disable,
- },
+static struct clk cpu_clk = {
+ .parent = &mpll_main2_clk,
+ .set_parent = clk_cpu_set_parent,
+ .round_rate = round_rate_cpu,
+ .get_rate = get_rate_cpu,
+ .set_rate = set_rate_cpu,
};
-static struct clk cspi2_clk[] = {
- {
- .name = "cspi_clk",
- .id = 1,
- .parent = &per_clk[1],
- .secondary = &cspi2_clk[1],
- }, {
- .name = "cspi_ipg_clk",
- .id = 1,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_CSPI2_OFFSET,
- .disable = _clk_disable,
- },
+static struct clk spll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = get_rate_spll,
+ .enable = clk_spll_enable,
+ .disable = clk_spll_disable,
};
-static struct clk cspi3_clk[] = {
- {
- .name = "cspi_clk",
- .id = 2,
- .parent = &per_clk[1],
- .secondary = &cspi3_clk[1],
- }, {
- .name = "cspi_ipg_clk",
- .id = 2,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_CSPI3_OFFSET,
- .disable = _clk_disable,
- },
+/*
+ * the low frequency external clock reference
+ * Default case is 32.768kHz.
+ */
+static struct clk ckil_clk = {
+ .get_rate = get_rate_low_reference,
};
-static struct clk lcdc_clk[] = {
- {
- .name = "lcdc_clk",
- .parent = &per_clk[2],
- .secondary = &lcdc_clk[1],
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
- }, {
- .name = "lcdc_ipg_clk",
- .parent = &ipg_clk,
- .secondary = &lcdc_clk[2],
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_LCDC_OFFSET,
- .disable = _clk_disable,
- }, {
- .name = "lcdc_ahb_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_HCLK_LCDC_OFFSET,
- .disable = _clk_disable,
- },
+/* Output of frequency pre multiplier */
+static struct clk fpm_clk = {
+ .parent = &ckil_clk,
+ .get_rate = get_rate_fpm,
};
-static struct clk csi_clk[] = {
- {
- .name = "csi_perclk",
- .parent = &per_clk[3],
- .secondary = &csi_clk[1],
- .round_rate = _clk_parent_round_rate,
- .set_rate = _clk_parent_set_rate,
- }, {
- .name = "csi_ahb_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_HCLK_CSI_OFFSET,
- .disable = _clk_disable,
- },
-};
+#define PCCR0 CCM_PCCR0
+#define PCCR1 CCM_PCCR1
-static struct clk usb_clk[] = {
- {
- .name = "usb_clk",
- .parent = &spll_clk,
- .get_rate = _clk_usb_recalc,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_USBOTG_OFFSET,
- .disable = _clk_disable,
- }, {
- .name = "usb_ahb_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_HCLK_USBOTG_OFFSET,
- .disable = _clk_disable,
+#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = gr, \
+ .enable = clk_pccr_enable, \
+ .disable = clk_pccr_disable, \
+ .secondary = s, \
+ .parent = p, \
}
-};
-static struct clk ssi1_clk[] = {
- {
- .name = "ssi_clk",
- .id = 0,
- .parent = &mpll_main_clk[1],
- .secondary = &ssi1_clk[1],
- .get_rate = _clk_ssi1_recalc,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_SSI1_BAUD_OFFSET,
- .disable = _clk_disable,
- }, {
- .name = "ssi_ipg_clk",
- .id = 0,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_SSI1_IPG_OFFSET,
- .disable = _clk_disable,
- },
-};
+#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = get_rate_##getsetround, \
+ .set_rate = set_rate_##getsetround, \
+ .round_rate = round_rate_##getsetround, \
+ .enable = clk_pccr_enable, \
+ .disable = clk_pccr_disable, \
+ .secondary = s, \
+ .parent = p, \
+ }
-static struct clk ssi2_clk[] = {
- {
- .name = "ssi_clk",
- .id = 1,
- .parent = &mpll_main_clk[1],
- .secondary = &ssi2_clk[1],
- .get_rate = _clk_ssi2_recalc,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_SSI2_BAUD_OFFSET,
- .disable = _clk_disable,
- }, {
- .name = "ssi_ipg_clk",
- .id = 1,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_SSI2_IPG_OFFSET,
- .disable = _clk_disable,
+/* Forward declaration to keep the following list in order */
+static struct clk slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1,
+ dma_clk1, lcdc_clk2, vpu_clk1;
+
+/* All clocks we can gate through PCCRx in the order of PCCRx bits */
+DEFINE_CLOCK(ssi2_clk1, 1, PCCR0, 0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ssi1_clk1, 0, PCCR0, 1, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(slcdc_clk, 0, PCCR0, 2, NULL, &slcdc_clk1, &ahb_clk);
+DEFINE_CLOCK(sdhc3_clk1, 0, PCCR0, 3, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(sdhc2_clk1, 0, PCCR0, 4, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(sdhc1_clk1, 0, PCCR0, 5, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(scc_clk, 0, PCCR0, 6, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(sahara2_clk, 0, PCCR0, 7, NULL, &sahara2_clk1, &ahb_clk);
+DEFINE_CLOCK(rtic_clk, 0, PCCR0, 8, NULL, &rtic_clk1, &ahb_clk);
+DEFINE_CLOCK(rtc_clk, 0, PCCR0, 9, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(pwm_clk1, 0, PCCR0, 11, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(owire_clk, 0, PCCR0, 12, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(mstick_clk1, 0, PCCR0, 13, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(lcdc_clk1, 0, PCCR0, 14, NULL, &lcdc_clk2, &ipg_clk);
+DEFINE_CLOCK(kpp_clk, 0, PCCR0, 15, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(iim_clk, 0, PCCR0, 16, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(i2c2_clk, 1, PCCR0, 17, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(i2c1_clk, 0, PCCR0, 18, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt6_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt5_clk1, 0, PCCR0, 20, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt4_clk1, 0, PCCR0, 21, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt3_clk1, 0, PCCR0, 22, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt2_clk1, 0, PCCR0, 23, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt1_clk1, 0, PCCR0, 24, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpio_clk, 0, PCCR0, 25, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(fec_clk, 0, PCCR0, 26, NULL, &fec_clk1, &ahb_clk);
+DEFINE_CLOCK(emma_clk, 0, PCCR0, 27, NULL, &emma_clk1, &ahb_clk);
+DEFINE_CLOCK(dma_clk, 0, PCCR0, 28, NULL, &dma_clk1, &ahb_clk);
+DEFINE_CLOCK(cspi13_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(cspi2_clk1, 0, PCCR0, 30, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(cspi1_clk1, 0, PCCR0, 31, NULL, NULL, &ipg_clk);
+
+DEFINE_CLOCK(mstick_clk, 0, PCCR1, 2, NULL, &mstick_clk1, &ipg_clk);
+DEFINE_CLOCK(nfc_clk, 0, PCCR1, 3, get_rate_nfc, NULL, &cpu_clk);
+DEFINE_CLOCK(ssi2_clk, 1, PCCR1, 4, get_rate_ssi2, &ssi2_clk1, &mpll_main2_clk);
+DEFINE_CLOCK(ssi1_clk, 0, PCCR1, 5, get_rate_ssi1, &ssi1_clk1, &mpll_main2_clk);
+DEFINE_CLOCK(vpu_clk, 0, PCCR1, 6, get_rate_vpu, &vpu_clk1, &mpll_main2_clk);
+DEFINE_CLOCK1(per4_clk, 3, PCCR1, 7, per, NULL, &mpll_main2_clk);
+DEFINE_CLOCK1(per3_clk, 2, PCCR1, 8, per, NULL, &mpll_main2_clk);
+DEFINE_CLOCK1(per2_clk, 1, PCCR1, 9, per, NULL, &mpll_main2_clk);
+DEFINE_CLOCK1(per1_clk, 0, PCCR1, 10, per, NULL, &mpll_main2_clk);
+DEFINE_CLOCK(usb_clk1, 0, PCCR1, 11, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(slcdc_clk1, 0, PCCR1, 12, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(sahara2_clk1, 0, PCCR1, 13, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(rtic_clk1, 0, PCCR1, 14, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(lcdc_clk2, 0, PCCR1, 15, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(vpu_clk1, 0, PCCR1, 16, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(fec_clk1, 0, PCCR1, 17, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(emma_clk1, 0, PCCR1, 18, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(emi_clk, 0, PCCR1, 19, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(dma_clk1, 0, PCCR1, 20, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(csi_clk1, 0, PCCR1, 21, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(brom_clk, 0, PCCR1, 22, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(ata_clk, 0, PCCR1, 23, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(wdog_clk, 0, PCCR1, 24, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(usb_clk, 0, PCCR1, 25, get_rate_usb, &usb_clk1, &spll_clk);
+DEFINE_CLOCK(uart6_clk1, 0, PCCR1, 26, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart5_clk1, 0, PCCR1, 27, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart4_clk1, 0, PCCR1, 28, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart3_clk1, 0, PCCR1, 29, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart2_clk1, 0, PCCR1, 30, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk);
+
+/* Clocks we cannot directly gate, but drivers need their rates */
+DEFINE_CLOCK(cspi1_clk, 0, 0, 0, NULL, &cspi1_clk1, &per2_clk);
+DEFINE_CLOCK(cspi2_clk, 1, 0, 0, NULL, &cspi2_clk1, &per2_clk);
+DEFINE_CLOCK(cspi3_clk, 2, 0, 0, NULL, &cspi13_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc1_clk, 0, 0, 0, NULL, &sdhc1_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc2_clk, 1, 0, 0, NULL, &sdhc2_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc3_clk, 2, 0, 0, NULL, &sdhc3_clk1, &per2_clk);
+DEFINE_CLOCK(pwm_clk, 0, 0, 0, NULL, &pwm_clk1, &per1_clk);
+DEFINE_CLOCK(gpt1_clk, 0, 0, 0, NULL, &gpt1_clk1, &per1_clk);
+DEFINE_CLOCK(gpt2_clk, 1, 0, 0, NULL, &gpt2_clk1, &per1_clk);
+DEFINE_CLOCK(gpt3_clk, 2, 0, 0, NULL, &gpt3_clk1, &per1_clk);
+DEFINE_CLOCK(gpt4_clk, 3, 0, 0, NULL, &gpt4_clk1, &per1_clk);
+DEFINE_CLOCK(gpt5_clk, 4, 0, 0, NULL, &gpt5_clk1, &per1_clk);
+DEFINE_CLOCK(gpt6_clk, 5, 0, 0, NULL, &gpt6_clk1, &per1_clk);
+DEFINE_CLOCK(uart1_clk, 0, 0, 0, NULL, &uart1_clk1, &per1_clk);
+DEFINE_CLOCK(uart2_clk, 1, 0, 0, NULL, &uart2_clk1, &per1_clk);
+DEFINE_CLOCK(uart3_clk, 2, 0, 0, NULL, &uart3_clk1, &per1_clk);
+DEFINE_CLOCK(uart4_clk, 3, 0, 0, NULL, &uart4_clk1, &per1_clk);
+DEFINE_CLOCK(uart5_clk, 4, 0, 0, NULL, &uart5_clk1, &per1_clk);
+DEFINE_CLOCK(uart6_clk, 5, 0, 0, NULL, &uart6_clk1, &per1_clk);
+DEFINE_CLOCK1(lcdc_clk, 0, 0, 0, parent, &lcdc_clk1, &per3_clk);
+DEFINE_CLOCK1(csi_clk, 0, 0, 0, parent, &csi_clk1, &per4_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
},
-};
-
-static struct clk nfc_clk = {
- .name = "nfc_clk",
- .parent = &cpu_clk,
- .get_rate = _clk_nfc_recalc,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_NFC_BAUD_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk vpu_clk = {
- .name = "vpu_clk",
- .parent = &mpll_main_clk[1],
- .get_rate = _clk_vpu_recalc,
- .enable = _clk_vpu_enable,
- .disable = _clk_vpu_disable,
-};
-
-static struct clk dma_clk = {
- .name = "dma_clk",
- .parent = &ahb_clk,
- .enable = _clk_dma_enable,
- .disable = _clk_dma_disable,
-};
-
-static struct clk rtic_clk = {
- .name = "rtic_clk",
- .parent = &ahb_clk,
- .enable = _clk_rtic_enable,
- .disable = _clk_rtic_disable,
-};
-static struct clk brom_clk = {
- .name = "brom_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_HCLK_BROM_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk emma_clk = {
- .name = "emma_clk",
- .parent = &ahb_clk,
- .enable = _clk_emma_enable,
- .disable = _clk_emma_disable,
-};
-
-static struct clk slcdc_clk = {
- .name = "slcdc_clk",
- .parent = &ahb_clk,
- .enable = _clk_slcdc_enable,
- .disable = _clk_slcdc_disable,
-};
-
-static struct clk fec_clk = {
- .name = "fec_clk",
- .parent = &ahb_clk,
- .enable = _clk_fec_enable,
- .disable = _clk_fec_disable,
-};
-
-static struct clk emi_clk = {
- .name = "emi_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_HCLK_EMI_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk sahara2_clk = {
- .name = "sahara_clk",
- .parent = &ahb_clk,
- .enable = _clk_sahara2_enable,
- .disable = _clk_sahara2_disable,
-};
-
-static struct clk ata_clk = {
- .name = "ata_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_HCLK_ATA_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk mstick1_clk = {
- .name = "mstick1_clk",
- .parent = &ipg_clk,
- .enable = _clk_mstick1_enable,
- .disable = _clk_mstick1_disable,
-};
-
-static struct clk wdog_clk = {
- .name = "wdog_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR1_WDT_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk gpio_clk = {
- .name = "gpio_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR1,
- .enable_shift = CCM_PCCR0_GPIO_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk i2c_clk[] = {
- {
- .name = "i2c_clk",
- .id = 0,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_I2C1_OFFSET,
- .disable = _clk_disable,
- }, {
- .name = "i2c_clk",
- .id = 1,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_I2C2_OFFSET,
- .disable = _clk_disable,
- },
-};
-
-static struct clk iim_clk = {
- .name = "iim_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_IIM_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk kpp_clk = {
- .name = "kpp_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_KPP_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk owire_clk = {
- .name = "owire_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_OWIRE_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk rtc_clk = {
- .name = "rtc_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_RTC_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk scc_clk = {
- .name = "scc_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = CCM_PCCR0,
- .enable_shift = CCM_PCCR0_SCC_OFFSET,
- .disable = _clk_disable,
-};
-
-static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
-{
- u32 div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
- div = parent_rate / rate;
- if (parent_rate % rate)
- div++;
-
- if (div > 8)
- div = 8;
-
- return parent_rate / div;
-}
-
-static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg;
- u32 div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = parent_rate / rate;
-
- if (div > 8 || div < 1 || ((parent_rate / div) != rate))
- return -EINVAL;
- div--;
-
- reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKODIV_MASK;
- reg |= div << CCM_PCDR0_CLKODIV_OFFSET;
- __raw_writel(reg, CCM_PCDR0);
-
- return 0;
-}
-
-static unsigned long _clk_clko_recalc(struct clk *clk)
-{
- u32 div;
- unsigned long parent_rate;
-
- parent_rate = clk_get_rate(clk->parent);
-
- div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_CLKODIV_MASK >>
- CCM_PCDR0_CLKODIV_OFFSET;
- div++;
-
- return parent_rate / div;
-}
-
-static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg;
-
- reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
-
- if (parent == &ckil_clk)
- reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &ckih_clk)
- reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == mpll_clk.parent)
- reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == spll_clk.parent)
- reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &mpll_clk)
- reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &spll_clk)
- reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &cpu_clk)
- reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &ahb_clk)
- reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &ipg_clk)
- reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &per_clk[0])
- reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &per_clk[1])
- reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &per_clk[2])
- reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &per_clk[3])
- reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &ssi1_clk[0])
- reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &ssi2_clk[0])
- reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &nfc_clk)
- reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &mstick1_clk)
- reg |= 0x11 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &vpu_clk)
- reg |= 0x12 << CCM_CCSR_CLKOSEL_OFFSET;
- else if (parent == &usb_clk[0])
- reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
- else
- return -EINVAL;
-
- __raw_writel(reg, CCM_CCSR);
-
- return 0;
-}
-
-static int _clk_clko_enable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(CCM_PCDR0) | CCM_PCDR0_CLKO_EN;
- __raw_writel(reg, CCM_PCDR0);
-
- return 0;
-}
-
-static void _clk_clko_disable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKO_EN;
- __raw_writel(reg, CCM_PCDR0);
-}
-
-static struct clk clko_clk = {
- .name = "clko_clk",
- .get_rate = _clk_clko_recalc,
- .set_rate = _clk_clko_set_rate,
- .round_rate = _clk_clko_round_rate,
- .set_parent = _clk_clko_set_parent,
- .enable = _clk_clko_enable,
- .disable = _clk_clko_disable,
-};
-
-static struct clk *mxc_clks[] = {
- &ckih_clk,
- &ckil_clk,
- &mpll_clk,
- &mpll_main_clk[0],
- &mpll_main_clk[1],
- &spll_clk,
- &cpu_clk,
- &ahb_clk,
- &ipg_clk,
- &per_clk[0],
- &per_clk[1],
- &per_clk[2],
- &per_clk[3],
- &clko_clk,
- &uart1_clk[0],
- &uart1_clk[1],
- &uart2_clk[0],
- &uart2_clk[1],
- &uart3_clk[0],
- &uart3_clk[1],
- &uart4_clk[0],
- &uart4_clk[1],
- &uart5_clk[0],
- &uart5_clk[1],
- &uart6_clk[0],
- &uart6_clk[1],
- &gpt1_clk[0],
- &gpt1_clk[1],
- &gpt2_clk[0],
- &gpt2_clk[1],
- &gpt3_clk[0],
- &gpt3_clk[1],
- &gpt4_clk[0],
- &gpt4_clk[1],
- &gpt5_clk[0],
- &gpt5_clk[1],
- &gpt6_clk[0],
- &gpt6_clk[1],
- &pwm_clk[0],
- &pwm_clk[1],
- &sdhc1_clk[0],
- &sdhc1_clk[1],
- &sdhc2_clk[0],
- &sdhc2_clk[1],
- &sdhc3_clk[0],
- &sdhc3_clk[1],
- &cspi1_clk[0],
- &cspi1_clk[1],
- &cspi2_clk[0],
- &cspi2_clk[1],
- &cspi3_clk[0],
- &cspi3_clk[1],
- &lcdc_clk[0],
- &lcdc_clk[1],
- &lcdc_clk[2],
- &csi_clk[0],
- &csi_clk[1],
- &usb_clk[0],
- &usb_clk[1],
- &ssi1_clk[0],
- &ssi1_clk[1],
- &ssi2_clk[0],
- &ssi2_clk[1],
- &nfc_clk,
- &vpu_clk,
- &dma_clk,
- &rtic_clk,
- &brom_clk,
- &emma_clk,
- &slcdc_clk,
- &fec_clk,
- &emi_clk,
- &sahara2_clk,
- &ata_clk,
- &mstick1_clk,
- &wdog_clk,
- &gpio_clk,
- &i2c_clk[0],
- &i2c_clk[1],
- &iim_clk,
- &kpp_clk,
- &owire_clk,
- &rtc_clk,
- &scc_clk,
-};
-
-void __init change_external_low_reference(unsigned long new_ref)
-{
- external_low_reference = new_ref;
-}
-
-unsigned long __init clk_early_get_timer_rate(void)
-{
- return clk_get_rate(&per_clk[0]);
-}
-
-static void __init probe_mxc_clocks(void)
-{
- int i;
+static struct clk_lookup lookups[] __initdata = {
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
+ _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+ _REGISTER_CLOCK("imx-uart.5", NULL, uart6_clk)
+ _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk)
+ _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk)
+ _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk)
+ _REGISTER_CLOCK(NULL, "gpt4", gpt4_clk)
+ _REGISTER_CLOCK(NULL, "gpt5", gpt5_clk)
+ _REGISTER_CLOCK(NULL, "gpt6", gpt6_clk)
+ _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk)
+ _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
+ _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
+ _REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk)
+ _REGISTER_CLOCK(NULL, "cspi1", cspi1_clk)
+ _REGISTER_CLOCK(NULL, "cspi2", cspi2_clk)
+ _REGISTER_CLOCK(NULL, "cspi3", cspi3_clk)
+ _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
+ _REGISTER_CLOCK(NULL, "csi", csi_clk)
+ _REGISTER_CLOCK(NULL, "usb", usb_clk)
+ _REGISTER_CLOCK(NULL, "ssi1", ssi1_clk)
+ _REGISTER_CLOCK(NULL, "ssi2", ssi2_clk)
+ _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+ _REGISTER_CLOCK(NULL, "vpu", vpu_clk)
+ _REGISTER_CLOCK(NULL, "dma", dma_clk)
+ _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
+ _REGISTER_CLOCK(NULL, "brom", brom_clk)
+ _REGISTER_CLOCK(NULL, "emma", emma_clk)
+ _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK(NULL, "emi", emi_clk)
+ _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
+ _REGISTER_CLOCK(NULL, "ata", ata_clk)
+ _REGISTER_CLOCK(NULL, "mstick", mstick_clk)
+ _REGISTER_CLOCK(NULL, "wdog", wdog_clk)
+ _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+ _REGISTER_CLOCK(NULL, "iim", iim_clk)
+ _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
+ _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
+ _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+ _REGISTER_CLOCK(NULL, "scc", scc_clk)
+};
+
+/* Adjust the clock path for TO2 and later */
+static void __init to2_adjust_clocks(void)
+{
+ unsigned long cscr = __raw_readl(CCM_CSCR);
if (mx27_revision() >= CHIP_REV_2_0) {
- if (CSCR() & 0x8000)
- cpu_clk.parent = &mpll_main_clk[0];
+ if (cscr & CCM_CSCR_ARM_SRC)
+ cpu_clk.parent = &mpll_main1_clk;
- if (!(CSCR() & 0x00800000))
- ssi2_clk[0].parent = &spll_clk;
+ if (!(cscr & CCM_CSCR_SSI2))
+ ssi1_clk.parent = &spll_clk;
- if (!(CSCR() & 0x00400000))
- ssi1_clk[0].parent = &spll_clk;
+ if (!(cscr & CCM_CSCR_SSI1))
+ ssi1_clk.parent = &spll_clk;
- if (!(CSCR() & 0x00200000))
+ if (!(cscr & CCM_CSCR_VPU))
vpu_clk.parent = &spll_clk;
} else {
cpu_clk.parent = &mpll_clk;
@@ -1565,11 +693,13 @@ static void __init probe_mxc_clocks(void)
cpu_clk.set_rate = NULL;
ahb_clk.parent = &mpll_clk;
- for (i = 0; i < sizeof(per_clk) / sizeof(per_clk[0]); i++)
- per_clk[i].parent = &mpll_clk;
+ per1_clk.parent = &mpll_clk;
+ per2_clk.parent = &mpll_clk;
+ per3_clk.parent = &mpll_clk;
+ per4_clk.parent = &mpll_clk;
- ssi1_clk[0].parent = &mpll_clk;
- ssi2_clk[0].parent = &mpll_clk;
+ ssi1_clk.parent = &mpll_clk;
+ ssi2_clk.parent = &mpll_clk;
vpu_clk.parent = &mpll_clk;
}
@@ -1579,47 +709,47 @@ static void __init probe_mxc_clocks(void)
* must be called very early to get information about the
* available clock rate when the timer framework starts
*/
-int __init mxc_clocks_init(unsigned long fref)
+int __init mx27_clocks_init(unsigned long fref)
{
- u32 cscr;
- struct clk **clkp;
+ u32 cscr = __raw_readl(CCM_CSCR);
+ int i;
external_high_reference = fref;
- /* detect clock reference for both system PLL */
- cscr = CSCR();
+ /* detect clock reference for both system PLLs */
if (cscr & CCM_CSCR_MCU)
mpll_clk.parent = &ckih_clk;
else
- mpll_clk.parent = &ckil_clk;
+ mpll_clk.parent = &fpm_clk;
if (cscr & CCM_CSCR_SP)
spll_clk.parent = &ckih_clk;
else
- spll_clk.parent = &ckil_clk;
+ spll_clk.parent = &fpm_clk;
- probe_mxc_clocks();
+ to2_adjust_clocks();
- per_clk[0].enable(&per_clk[0]);
- gpt1_clk[1].enable(&gpt1_clk[1]);
+ for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ clkdev_add(&lookups[i]);
- for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
- clk_register(*clkp);
+ /* Turn off all clocks we do not need */
+ __raw_writel(0, CCM_PCCR0);
+ __raw_writel((1 << 10) | (1 << 19), CCM_PCCR1);
- /* Turn off all possible clocks */
- __raw_writel(CCM_PCCR0_GPT1_MASK, CCM_PCCR0);
- __raw_writel(CCM_PCCR1_PERCLK1_MASK | CCM_PCCR1_HCLK_EMI_MASK,
- CCM_PCCR1);
spll_clk.disable(&spll_clk);
- /* This will propagate to all children and init all the clock rates */
-
- clk_enable(&emi_clk);
+ /* enable basic clocks */
+ clk_enable(&per1_clk);
clk_enable(&gpio_clk);
+ clk_enable(&emi_clk);
clk_enable(&iim_clk);
- clk_enable(&gpt1_clk[0]);
+
#ifdef CONFIG_DEBUG_LL_CONSOLE
- clk_enable(&uart1_clk[0]);
+ clk_enable(&uart1_clk);
#endif
+
+ mxc_timer_init(&gpt1_clk);
+
return 0;
}
+
diff --git a/arch/arm/mach-mx2/cpu_imx27.c b/arch/arm/mach-mx2/cpu_imx27.c
index 239308fe6652..d9e3bf9644c9 100644
--- a/arch/arm/mach-mx2/cpu_imx27.c
+++ b/arch/arm/mach-mx2/cpu_imx27.c
@@ -26,11 +26,11 @@
#include <mach/hardware.h>
-#include "crm_regs.h"
-
static int cpu_silicon_rev = -1;
static int cpu_partnumber;
+#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
+
static void query_silicon_parameter(void)
{
u32 val;
diff --git a/arch/arm/mach-mx2/crm_regs.h b/arch/arm/mach-mx2/crm_regs.h
index 94644cd0a0fc..749de76b3f95 100644
--- a/arch/arm/mach-mx2/crm_regs.h
+++ b/arch/arm/mach-mx2/crm_regs.h
@@ -38,42 +38,36 @@
#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30)
#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34)
-#define CCM_CSCR_USB_OFFSET 28
-#define CCM_CSCR_USB_MASK (0x7 << 28)
+#define CCM_CSCR_PRESC_OFFSET 29
+#define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET)
+
+#define CCM_CSCR_USB_OFFSET 26
+#define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET)
#define CCM_CSCR_SD_OFFSET 24
-#define CCM_CSCR_SD_MASK (0x3 << 24)
-#define CCM_CSCR_SSI2 (1 << 23)
-#define CCM_CSCR_SSI2_OFFSET 23
-#define CCM_CSCR_SSI1 (1 << 22)
-#define CCM_CSCR_SSI1_OFFSET 22
-#define CCM_CSCR_VPU (1 << 21)
-#define CCM_CSCR_VPU_OFFSET 21
-#define CCM_CSCR_MSHC (1 << 20)
-#define CCM_CSCR_SPLLRES (1 << 19)
-#define CCM_CSCR_MPLLRES (1 << 18)
+#define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET)
+#define CCM_CSCR_SPLLRES (1 << 22)
+#define CCM_CSCR_MPLLRES (1 << 21)
+#define CCM_CSCR_SSI2_OFFSET 20
+#define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET)
+#define CCM_CSCR_SSI1_OFFSET 19
+#define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET)
+#define CCM_CSCR_FIR_OFFSET 18
+#define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET)
#define CCM_CSCR_SP (1 << 17)
#define CCM_CSCR_MCU (1 << 16)
-/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/
-#define CCM_CSCR_ARM_SRC (1 << 15)
-#define CCM_CSCR_ARM_OFFSET 12
-#define CCM_CSCR_ARM_MASK (0x3 << 12)
-/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/
-#define CCM_CSCR_PRESC_OFFSET 13
-#define CCM_CSCR_PRESC_MASK (0x7 << 13)
-#define CCM_CSCR_BCLK_OFFSET 9
-#define CCM_CSCR_BCLK_MASK (0xf << 9)
-#define CCM_CSCR_IPDIV_OFFSET 8
-#define CCM_CSCR_IPDIV (1 << 8)
-/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/
-#define CCM_CSCR_AHB_OFFSET 8
-#define CCM_CSCR_AHB_MASK (0x3 << 8)
-/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/
+#define CCM_CSCR_BCLK_OFFSET 10
+#define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET)
+#define CCM_CSCR_IPDIV_OFFSET 9
+#define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET)
+
#define CCM_CSCR_OSC26MDIV (1 << 4)
#define CCM_CSCR_OSC26M (1 << 3)
#define CCM_CSCR_FPM (1 << 2)
#define CCM_CSCR_SPEN (1 << 1)
#define CCM_CSCR_MPEN 1
+
+
#define CCM_MPCTL0_CPLM (1 << 31)
#define CCM_MPCTL0_PD_OFFSET 26
#define CCM_MPCTL0_PD_MASK (0xf << 26)
@@ -109,25 +103,14 @@
#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26
#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26)
-#define CCM_PCDR0_CLKO_EN 25
-#define CCM_PCDR0_CLKODIV_OFFSET 22
-#define CCM_PCDR0_CLKODIV_MASK (0x7 << 22)
#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16
#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16)
-/*The difinition for i.MX27 TO2*/
-#define CCM_PCDR0_VPUDIV2_OFFSET 10
-#define CCM_PCDR0_VPUDIV2_MASK (0x3f << 10)
-#define CCM_PCDR0_NFCDIV2_OFFSET 6
-#define CCM_PCDR0_NFCDIV2_MASK (0xf << 6)
-#define CCM_PCDR0_MSHCDIV2_MASK 0x3f
-/*The difinition for i.MX27 TO2*/
#define CCM_PCDR0_NFCDIV_OFFSET 12
#define CCM_PCDR0_NFCDIV_MASK (0xf << 12)
-#define CCM_PCDR0_VPUDIV_OFFSET 8
-#define CCM_PCDR0_VPUDIV_MASK (0xf << 8)
-#define CCM_PCDR0_MSHCDIV_OFFSET 0
-#define CCM_PCDR0_MSHCDIV_MASK 0x1f
-
+#define CCM_PCDR0_48MDIV_OFFSET 5
+#define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET)
+#define CCM_PCDR0_FIRIDIV_OFFSET 0
+#define CCM_PCDR0_FIRIDIV_MASK 0x1f
#define CCM_PCDR1_PERDIV4_OFFSET 24
#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24)
#define CCM_PCDR1_PERDIV3_OFFSET 16
@@ -137,133 +120,135 @@
#define CCM_PCDR1_PERDIV1_OFFSET 0
#define CCM_PCDR1_PERDIV1_MASK 0x3f
-#define CCM_PCCR0_CSPI1_OFFSET 31
-#define CCM_PCCR0_CSPI1_MASK (1 << 31)
-#define CCM_PCCR0_CSPI2_OFFSET 30
-#define CCM_PCCR0_CSPI2_MASK (1 << 30)
-#define CCM_PCCR0_CSPI3_OFFSET 29
-#define CCM_PCCR0_CSPI3_MASK (1 << 29)
-#define CCM_PCCR0_DMA_OFFSET 28
-#define CCM_PCCR0_DMA_MASK (1 << 28)
-#define CCM_PCCR0_EMMA_OFFSET 27
-#define CCM_PCCR0_EMMA_MASK (1 << 27)
-#define CCM_PCCR0_FEC_OFFSET 26
-#define CCM_PCCR0_FEC_MASK (1 << 26)
-#define CCM_PCCR0_GPIO_OFFSET 25
-#define CCM_PCCR0_GPIO_MASK (1 << 25)
-#define CCM_PCCR0_GPT1_OFFSET 24
-#define CCM_PCCR0_GPT1_MASK (1 << 24)
-#define CCM_PCCR0_GPT2_OFFSET 23
-#define CCM_PCCR0_GPT2_MASK (1 << 23)
-#define CCM_PCCR0_GPT3_OFFSET 22
-#define CCM_PCCR0_GPT3_MASK (1 << 22)
-#define CCM_PCCR0_GPT4_OFFSET 21
-#define CCM_PCCR0_GPT4_MASK (1 << 21)
-#define CCM_PCCR0_GPT5_OFFSET 20
-#define CCM_PCCR0_GPT5_MASK (1 << 20)
-#define CCM_PCCR0_GPT6_OFFSET 19
-#define CCM_PCCR0_GPT6_MASK (1 << 19)
-#define CCM_PCCR0_I2C1_OFFSET 18
-#define CCM_PCCR0_I2C1_MASK (1 << 18)
-#define CCM_PCCR0_I2C2_OFFSET 17
-#define CCM_PCCR0_I2C2_MASK (1 << 17)
-#define CCM_PCCR0_IIM_OFFSET 16
-#define CCM_PCCR0_IIM_MASK (1 << 16)
-#define CCM_PCCR0_KPP_OFFSET 15
-#define CCM_PCCR0_KPP_MASK (1 << 15)
-#define CCM_PCCR0_LCDC_OFFSET 14
-#define CCM_PCCR0_LCDC_MASK (1 << 14)
-#define CCM_PCCR0_MSHC_OFFSET 13
-#define CCM_PCCR0_MSHC_MASK (1 << 13)
-#define CCM_PCCR0_OWIRE_OFFSET 12
-#define CCM_PCCR0_OWIRE_MASK (1 << 12)
-#define CCM_PCCR0_PWM_OFFSET 11
-#define CCM_PCCR0_PWM_MASK (1 << 11)
-#define CCM_PCCR0_RTC_OFFSET 9
-#define CCM_PCCR0_RTC_MASK (1 << 9)
-#define CCM_PCCR0_RTIC_OFFSET 8
-#define CCM_PCCR0_RTIC_MASK (1 << 8)
-#define CCM_PCCR0_SAHARA_OFFSET 7
-#define CCM_PCCR0_SAHARA_MASK (1 << 7)
-#define CCM_PCCR0_SCC_OFFSET 6
-#define CCM_PCCR0_SCC_MASK (1 << 6)
-#define CCM_PCCR0_SDHC1_OFFSET 5
-#define CCM_PCCR0_SDHC1_MASK (1 << 5)
-#define CCM_PCCR0_SDHC2_OFFSET 4
-#define CCM_PCCR0_SDHC2_MASK (1 << 4)
-#define CCM_PCCR0_SDHC3_OFFSET 3
-#define CCM_PCCR0_SDHC3_MASK (1 << 3)
-#define CCM_PCCR0_SLCDC_OFFSET 2
-#define CCM_PCCR0_SLCDC_MASK (1 << 2)
-#define CCM_PCCR0_SSI1_IPG_OFFSET 1
-#define CCM_PCCR0_SSI1_IPG_MASK (1 << 1)
-#define CCM_PCCR0_SSI2_IPG_OFFSET 0
-#define CCM_PCCR0_SSI2_IPG_MASK (1 << 0)
+#define CCM_PCCR_HCLK_CSI_OFFSET 31
+#define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_DMA_OFFSET 30
+#define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_BROM_OFFSET 28
+#define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_EMMA_OFFSET 27
+#define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_LCDC_OFFSET 26
+#define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_SLCDC_OFFSET 25
+#define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_USBOTG_OFFSET 24
+#define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_BMI_OFFSET 23
+#define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK)
+#define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0
+#define CCM_PCCR_PERCLK4_OFFSET 22
+#define CCM_PCCR_PERCLK4_REG CCM_PCCR0
+#define CCM_PCCR_SLCDC_OFFSET 21
+#define CCM_PCCR_SLCDC_REG CCM_PCCR0
+#define CCM_PCCR_FIRI_BAUD_OFFSET 20
+#define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK)
+#define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0
+#define CCM_PCCR_NFC_OFFSET 19
+#define CCM_PCCR_NFC_REG CCM_PCCR0
+#define CCM_PCCR_LCDC_OFFSET 18
+#define CCM_PCCR_LCDC_REG CCM_PCCR0
+#define CCM_PCCR_SSI1_BAUD_OFFSET 17
+#define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0
+#define CCM_PCCR_SSI2_BAUD_OFFSET 16
+#define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0
+#define CCM_PCCR_EMMA_OFFSET 15
+#define CCM_PCCR_EMMA_REG CCM_PCCR0
+#define CCM_PCCR_USBOTG_OFFSET 14
+#define CCM_PCCR_USBOTG_REG CCM_PCCR0
+#define CCM_PCCR_DMA_OFFSET 13
+#define CCM_PCCR_DMA_REG CCM_PCCR0
+#define CCM_PCCR_I2C1_OFFSET 12
+#define CCM_PCCR_I2C1_REG CCM_PCCR0
+#define CCM_PCCR_GPIO_OFFSET 11
+#define CCM_PCCR_GPIO_REG CCM_PCCR0
+#define CCM_PCCR_SDHC2_OFFSET 10
+#define CCM_PCCR_SDHC2_REG CCM_PCCR0
+#define CCM_PCCR_SDHC1_OFFSET 9
+#define CCM_PCCR_SDHC1_REG CCM_PCCR0
+#define CCM_PCCR_FIRI_OFFSET 8
+#define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK)
+#define CCM_PCCR_FIRI_REG CCM_PCCR0
+#define CCM_PCCR_SSI2_IPG_OFFSET 7
+#define CCM_PCCR_SSI2_REG CCM_PCCR0
+#define CCM_PCCR_SSI1_IPG_OFFSET 6
+#define CCM_PCCR_SSI1_REG CCM_PCCR0
+#define CCM_PCCR_CSPI2_OFFSET 5
+#define CCM_PCCR_CSPI2_REG CCM_PCCR0
+#define CCM_PCCR_CSPI1_OFFSET 4
+#define CCM_PCCR_CSPI1_REG CCM_PCCR0
+#define CCM_PCCR_UART4_OFFSET 3
+#define CCM_PCCR_UART4_REG CCM_PCCR0
+#define CCM_PCCR_UART3_OFFSET 2
+#define CCM_PCCR_UART3_REG CCM_PCCR0
+#define CCM_PCCR_UART2_OFFSET 1
+#define CCM_PCCR_UART2_REG CCM_PCCR0
+#define CCM_PCCR_UART1_OFFSET 0
+#define CCM_PCCR_UART1_REG CCM_PCCR0
+
+#define CCM_PCCR_OWIRE_OFFSET 31
+#define CCM_PCCR_OWIRE_REG CCM_PCCR1
+#define CCM_PCCR_KPP_OFFSET 30
+#define CCM_PCCR_KPP_REG CCM_PCCR1
+#define CCM_PCCR_RTC_OFFSET 29
+#define CCM_PCCR_RTC_REG CCM_PCCR1
+#define CCM_PCCR_PWM_OFFSET 28
+#define CCM_PCCR_PWM_REG CCM_PCCR1
+#define CCM_PCCR_GPT3_OFFSET 27
+#define CCM_PCCR_GPT3_REG CCM_PCCR1
+#define CCM_PCCR_GPT2_OFFSET 26
+#define CCM_PCCR_GPT2_REG CCM_PCCR1
+#define CCM_PCCR_GPT1_OFFSET 25
+#define CCM_PCCR_GPT1_REG CCM_PCCR1
+#define CCM_PCCR_WDT_OFFSET 24
+#define CCM_PCCR_WDT_REG CCM_PCCR1
+#define CCM_PCCR_CSPI3_OFFSET 23
+#define CCM_PCCR_CSPI3_REG CCM_PCCR1
+
+#define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET)
+#define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET)
+#define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET)
+#define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET)
+#define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET)
+#define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET)
+#define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET)
+#define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET)
+#define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET)
+#define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET)
+#define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET)
+#define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET)
+#define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET)
+#define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET)
+#define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET)
+#define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET)
+#define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET)
+#define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET)
+#define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET)
+#define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET)
+#define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET)
+#define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET)
+#define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET)
+#define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET)
+#define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET)
+#define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET)
+#define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET)
+#define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET)
+#define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET)
+#define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET)
+#define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET)
+#define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET)
+#define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET)
+#define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET)
+#define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET)
+#define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET)
+#define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET)
-#define CCM_PCCR1_UART1_OFFSET 31
-#define CCM_PCCR1_UART1_MASK (1 << 31)
-#define CCM_PCCR1_UART2_OFFSET 30
-#define CCM_PCCR1_UART2_MASK (1 << 30)
-#define CCM_PCCR1_UART3_OFFSET 29
-#define CCM_PCCR1_UART3_MASK (1 << 29)
-#define CCM_PCCR1_UART4_OFFSET 28
-#define CCM_PCCR1_UART4_MASK (1 << 28)
-#define CCM_PCCR1_UART5_OFFSET 27
-#define CCM_PCCR1_UART5_MASK (1 << 27)
-#define CCM_PCCR1_UART6_OFFSET 26
-#define CCM_PCCR1_UART6_MASK (1 << 26)
-#define CCM_PCCR1_USBOTG_OFFSET 25
-#define CCM_PCCR1_USBOTG_MASK (1 << 25)
-#define CCM_PCCR1_WDT_OFFSET 24
-#define CCM_PCCR1_WDT_MASK (1 << 24)
-#define CCM_PCCR1_HCLK_ATA_OFFSET 23
-#define CCM_PCCR1_HCLK_ATA_MASK (1 << 23)
-#define CCM_PCCR1_HCLK_BROM_OFFSET 22
-#define CCM_PCCR1_HCLK_BROM_MASK (1 << 22)
-#define CCM_PCCR1_HCLK_CSI_OFFSET 21
-#define CCM_PCCR1_HCLK_CSI_MASK (1 << 21)
-#define CCM_PCCR1_HCLK_DMA_OFFSET 20
-#define CCM_PCCR1_HCLK_DMA_MASK (1 << 20)
-#define CCM_PCCR1_HCLK_EMI_OFFSET 19
-#define CCM_PCCR1_HCLK_EMI_MASK (1 << 19)
-#define CCM_PCCR1_HCLK_EMMA_OFFSET 18
-#define CCM_PCCR1_HCLK_EMMA_MASK (1 << 18)
-#define CCM_PCCR1_HCLK_FEC_OFFSET 17
-#define CCM_PCCR1_HCLK_FEC_MASK (1 << 17)
-#define CCM_PCCR1_HCLK_VPU_OFFSET 16
-#define CCM_PCCR1_HCLK_VPU_MASK (1 << 16)
-#define CCM_PCCR1_HCLK_LCDC_OFFSET 15
-#define CCM_PCCR1_HCLK_LCDC_MASK (1 << 15)
-#define CCM_PCCR1_HCLK_RTIC_OFFSET 14
-#define CCM_PCCR1_HCLK_RTIC_MASK (1 << 14)
-#define CCM_PCCR1_HCLK_SAHARA_OFFSET 13
-#define CCM_PCCR1_HCLK_SAHARA_MASK (1 << 13)
-#define CCM_PCCR1_HCLK_SLCDC_OFFSET 12
-#define CCM_PCCR1_HCLK_SLCDC_MASK (1 << 12)
-#define CCM_PCCR1_HCLK_USBOTG_OFFSET 11
-#define CCM_PCCR1_HCLK_USBOTG_MASK (1 << 11)
-#define CCM_PCCR1_PERCLK1_OFFSET 10
-#define CCM_PCCR1_PERCLK1_MASK (1 << 10)
-#define CCM_PCCR1_PERCLK2_OFFSET 9
-#define CCM_PCCR1_PERCLK2_MASK (1 << 9)
-#define CCM_PCCR1_PERCLK3_OFFSET 8
-#define CCM_PCCR1_PERCLK3_MASK (1 << 8)
-#define CCM_PCCR1_PERCLK4_OFFSET 7
-#define CCM_PCCR1_PERCLK4_MASK (1 << 7)
-#define CCM_PCCR1_VPU_BAUD_OFFSET 6
-#define CCM_PCCR1_VPU_BAUD_MASK (1 << 6)
-#define CCM_PCCR1_SSI1_BAUD_OFFSET 5
-#define CCM_PCCR1_SSI1_BAUD_MASK (1 << 5)
-#define CCM_PCCR1_SSI2_BAUD_OFFSET 4
-#define CCM_PCCR1_SSI2_BAUD_MASK (1 << 4)
-#define CCM_PCCR1_NFC_BAUD_OFFSET 3
-#define CCM_PCCR1_NFC_BAUD_MASK (1 << 3)
-#define CCM_PCCR1_MSHC_BAUD_OFFSET 2
-#define CCM_PCCR1_MSHC_BAUD_MASK (1 << 2)
#define CCM_CCSR_32KSR (1 << 15)
+
#define CCM_CCSR_CLKMODE1 (1 << 9)
#define CCM_CCSR_CLKMODE0 (1 << 8)
+
#define CCM_CCSR_CLKOSEL_OFFSET 0
#define CCM_CCSR_CLKOSEL_MASK 0x1f
diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c
index 2f9240be1c76..a0f1b3674327 100644
--- a/arch/arm/mach-mx2/devices.c
+++ b/arch/arm/mach-mx2/devices.c
@@ -34,6 +34,10 @@
#include <mach/irqs.h>
#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/mmc.h>
+
+#include "devices.h"
/*
* Resource definition for the MXC IrDA
@@ -225,37 +229,215 @@ struct platform_device mxc_nand_device = {
.resource = mxc_nand_resources,
};
+/*
+ * lcdc:
+ * - i.MX1: the basic controller
+ * - i.MX21: to be checked
+ * - i.MX27: like i.MX1, with slightly variations
+ */
+static struct resource mxc_fb[] = {
+ {
+ .start = LCDC_BASE_ADDR,
+ .end = LCDC_BASE_ADDR + 0xFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_LCDC,
+ .end = MXC_INT_LCDC,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+/* mxc lcd driver */
+struct platform_device mxc_fb_device = {
+ .name = "imx-fb",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_fb),
+ .resource = mxc_fb,
+ .dev = {
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+};
+
+#ifdef CONFIG_MACH_MX27
+static struct resource mxc_fec_resources[] = {
+ {
+ .start = FEC_BASE_ADDR,
+ .end = FEC_BASE_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM
+ }, {
+ .start = MXC_INT_FEC,
+ .end = MXC_INT_FEC,
+ .flags = IORESOURCE_IRQ
+ },
+};
+
+struct platform_device mxc_fec_device = {
+ .name = "fec",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_fec_resources),
+ .resource = mxc_fec_resources,
+};
+#endif
+
+static struct resource mxc_i2c_1_resources[] = {
+ [0] = {
+ .start = I2C_BASE_ADDR,
+ .end = I2C_BASE_ADDR + 0x0fff,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = MXC_INT_I2C,
+ .end = MXC_INT_I2C,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+struct platform_device mxc_i2c_device0 = {
+ .name = "imx-i2c",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
+ .resource = mxc_i2c_1_resources
+};
+
+#ifdef CONFIG_MACH_MX27
+static struct resource mxc_i2c_2_resources[] = {
+ [0] = {
+ .start = I2C2_BASE_ADDR,
+ .end = I2C2_BASE_ADDR + 0x0fff,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = MXC_INT_I2C2,
+ .end = MXC_INT_I2C2,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+struct platform_device mxc_i2c_device1 = {
+ .name = "imx-i2c",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(mxc_i2c_2_resources),
+ .resource = mxc_i2c_2_resources
+};
+#endif
+
+static struct resource mxc_pwm_resources[] = {
+ [0] = {
+ .start = PWM_BASE_ADDR,
+ .end = PWM_BASE_ADDR + 0x0fff,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = MXC_INT_PWM,
+ .end = MXC_INT_PWM,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device mxc_pwm_device = {
+ .name = "mxc_pwm",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_pwm_resources),
+ .resource = mxc_pwm_resources
+};
+
+/*
+ * Resource definition for the MXC SDHC
+ */
+static struct resource mxc_sdhc1_resources[] = {
+ [0] = {
+ .start = SDHC1_BASE_ADDR,
+ .end = SDHC1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_SDHC1,
+ .end = MXC_INT_SDHC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DMA_REQ_SDHC1,
+ .end = DMA_REQ_SDHC1,
+ .flags = IORESOURCE_DMA
+ },
+};
+
+static u64 mxc_sdhc1_dmamask = 0xffffffffUL;
+
+struct platform_device mxc_sdhc_device0 = {
+ .name = "mxc-mmc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &mxc_sdhc1_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(mxc_sdhc1_resources),
+ .resource = mxc_sdhc1_resources,
+};
+
+static struct resource mxc_sdhc2_resources[] = {
+ [0] = {
+ .start = SDHC2_BASE_ADDR,
+ .end = SDHC2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_SDHC2,
+ .end = MXC_INT_SDHC2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DMA_REQ_SDHC2,
+ .end = DMA_REQ_SDHC2,
+ .flags = IORESOURCE_DMA
+ },
+};
+
+static u64 mxc_sdhc2_dmamask = 0xffffffffUL;
+
+struct platform_device mxc_sdhc_device1 = {
+ .name = "mxc-mmc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &mxc_sdhc2_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(mxc_sdhc2_resources),
+ .resource = mxc_sdhc2_resources,
+};
+
/* GPIO port description */
static struct mxc_gpio_port imx_gpio_ports[] = {
[0] = {
.chip.label = "gpio-0",
.irq = MXC_INT_GPIO,
- .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 0),
+ .base = IO_ADDRESS(GPIO_BASE_ADDR),
.virtual_irq_start = MXC_GPIO_IRQ_START,
},
[1] = {
.chip.label = "gpio-1",
- .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 1),
+ .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100),
.virtual_irq_start = MXC_GPIO_IRQ_START + 32,
},
[2] = {
.chip.label = "gpio-2",
- .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 2),
+ .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200),
.virtual_irq_start = MXC_GPIO_IRQ_START + 64,
},
[3] = {
.chip.label = "gpio-3",
- .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 3),
+ .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300),
.virtual_irq_start = MXC_GPIO_IRQ_START + 96,
},
[4] = {
.chip.label = "gpio-4",
- .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 4),
+ .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400),
.virtual_irq_start = MXC_GPIO_IRQ_START + 128,
},
[5] = {
.chip.label = "gpio-5",
- .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 5),
+ .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500),
.virtual_irq_start = MXC_GPIO_IRQ_START + 160,
}
};
diff --git a/arch/arm/mach-mx2/devices.h b/arch/arm/mach-mx2/devices.h
index 1e8cb577a642..049005bb6aa9 100644
--- a/arch/arm/mach-mx2/devices.h
+++ b/arch/arm/mach-mx2/devices.h
@@ -1,4 +1,3 @@
-
extern struct platform_device mxc_gpt1;
extern struct platform_device mxc_gpt2;
extern struct platform_device mxc_gpt3;
@@ -14,3 +13,10 @@ extern struct platform_device mxc_uart_device4;
extern struct platform_device mxc_uart_device5;
extern struct platform_device mxc_w1_master_device;
extern struct platform_device mxc_nand_device;
+extern struct platform_device mxc_fb_device;
+extern struct platform_device mxc_fec_device;
+extern struct platform_device mxc_pwm_device;
+extern struct platform_device mxc_i2c_device0;
+extern struct platform_device mxc_i2c_device1;
+extern struct platform_device mxc_sdhc_device0;
+extern struct platform_device mxc_sdhc_device1;
diff --git a/arch/arm/mach-mx2/generic.c b/arch/arm/mach-mx2/generic.c
index dea6521d4d5c..bd51dd04948e 100644
--- a/arch/arm/mach-mx2/generic.c
+++ b/arch/arm/mach-mx2/generic.c
@@ -21,6 +21,7 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <mach/hardware.h>
+#include <mach/common.h>
#include <asm/pgtable.h>
#include <asm/mach/map.h>
diff --git a/arch/arm/mach-mx2/mx27ads.c b/arch/arm/mach-mx2/mx27ads.c
index 2b5c67f54571..4a3b097adc12 100644
--- a/arch/arm/mach-mx2/mx27ads.c
+++ b/arch/arm/mach-mx2/mx27ads.c
@@ -31,7 +31,7 @@
#include <asm/mach/map.h>
#include <mach/gpio.h>
#include <mach/imx-uart.h>
-#include <mach/iomux-mx1-mx2.h>
+#include <mach/iomux.h>
#include <mach/board-mx27ads.h>
#include "devices.h"
@@ -135,6 +135,7 @@ static int uart_mxc_port3_exit(struct platform_device *pdev)
{
mxc_gpio_release_multiple_pins(mxc_uart3_pins,
ARRAY_SIZE(mxc_uart3_pins));
+ return 0;
}
static int mxc_uart4_pins[] = {
@@ -179,6 +180,7 @@ static int uart_mxc_port5_exit(struct platform_device *pdev)
static struct platform_device *platform_devices[] __initdata = {
&mx27ads_nor_mtd_device,
+ &mxc_fec_device,
};
static int mxc_fec_pins[] = {
@@ -196,7 +198,7 @@ static int mxc_fec_pins[] = {
PD11_AOUT_FEC_TX_CLK,
PD12_AOUT_FEC_RXD0,
PD13_AOUT_FEC_RX_DV,
- PD14_AOUT_FEC_CLR,
+ PD14_AOUT_FEC_RX_CLK,
PD15_AOUT_FEC_COL,
PD16_AIN_FEC_TX_ER,
PF23_AIN_FEC_TX_EN
@@ -208,12 +210,6 @@ static void gpio_fec_active(void)
ARRAY_SIZE(mxc_fec_pins), "FEC");
}
-static void gpio_fec_inactive(void)
-{
- mxc_gpio_release_multiple_pins(mxc_fec_pins,
- ARRAY_SIZE(mxc_fec_pins));
-}
-
static struct imxuart_platform_data uart_pdata[] = {
{
.init = uart_mxc_port0_init,
@@ -263,11 +259,10 @@ static void __init mx27ads_timer_init(void)
if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0)
fref = 27000000;
- mxc_clocks_init(fref);
- mxc_timer_init("gpt_clk.0");
+ mx27_clocks_init(fref);
}
-struct sys_timer mx27ads_timer = {
+static struct sys_timer mx27ads_timer = {
.init = mx27ads_timer_init,
};
@@ -280,7 +275,7 @@ static struct map_desc mx27ads_io_desc[] __initdata = {
},
};
-void __init mx27ads_map_io(void)
+static void __init mx27ads_map_io(void)
{
mxc_map_io();
iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc));
diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c
index dfd4156da7d5..aa4eaa61d1b5 100644
--- a/arch/arm/mach-mx2/pcm038.c
+++ b/arch/arm/mach-mx2/pcm038.c
@@ -20,11 +20,18 @@
#include <linux/platform_device.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/plat-ram.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
#include <mach/common.h>
#include <mach/hardware.h>
-#include <mach/iomux-mx1-mx2.h>
+#include <mach/iomux.h>
+#ifdef CONFIG_I2C_IMX
+#include <mach/i2c.h>
+#endif
#include <asm/mach/time.h>
#include <mach/imx-uart.h>
#include <mach/board-pcm038.h>
@@ -121,10 +128,10 @@ static int uart_mxc_port1_exit(struct platform_device *pdev)
return 0;
}
-static int mxc_uart2_pins[] = { PE10_PF_UART3_CTS,
+static int mxc_uart2_pins[] = { PE8_PF_UART3_TXD,
PE9_PF_UART3_RXD,
PE10_PF_UART3_CTS,
- PE9_PF_UART3_RXD };
+ PE11_PF_UART3_RTS };
static int uart_mxc_port2_init(struct platform_device *pdev)
{
@@ -170,7 +177,7 @@ static int mxc_fec_pins[] = {
PD11_AOUT_FEC_TX_CLK,
PD12_AOUT_FEC_RXD0,
PD13_AOUT_FEC_RX_DV,
- PD14_AOUT_FEC_CLR,
+ PD14_AOUT_FEC_RX_CLK,
PD15_AOUT_FEC_COL,
PD16_AIN_FEC_TX_ER,
PF23_AIN_FEC_TX_EN
@@ -182,12 +189,6 @@ static void gpio_fec_active(void)
ARRAY_SIZE(mxc_fec_pins), "FEC");
}
-static void gpio_fec_inactive(void)
-{
- mxc_gpio_release_multiple_pins(mxc_fec_pins,
- ARRAY_SIZE(mxc_fec_pins));
-}
-
static struct mxc_nand_platform_data pcm038_nand_board_info = {
.width = 1,
.hw_ecc = 1,
@@ -196,6 +197,7 @@ static struct mxc_nand_platform_data pcm038_nand_board_info = {
static struct platform_device *platform_devices[] __initdata = {
&pcm038_nor_mtd_device,
&mxc_w1_master_device,
+ &mxc_fec_device,
&pcm038_sram_mtd_device,
};
@@ -208,6 +210,51 @@ static void __init pcm038_init_sram(void)
__raw_writel(0x22220a00, CSCR_A(1));
}
+#ifdef CONFIG_I2C_IMX
+static int mxc_i2c1_pins[] = {
+ PC5_PF_I2C2_SDA,
+ PC6_PF_I2C2_SCL
+};
+
+static int pcm038_i2c_1_init(struct device *dev)
+{
+ return mxc_gpio_setup_multiple_pins(mxc_i2c1_pins, ARRAY_SIZE(mxc_i2c1_pins),
+ "I2C1");
+}
+
+static void pcm038_i2c_1_exit(struct device *dev)
+{
+ mxc_gpio_release_multiple_pins(mxc_i2c1_pins, ARRAY_SIZE(mxc_i2c1_pins));
+}
+
+static struct imxi2c_platform_data pcm038_i2c_1_data = {
+ .bitrate = 100000,
+ .init = pcm038_i2c_1_init,
+ .exit = pcm038_i2c_1_exit,
+};
+
+static struct at24_platform_data board_eeprom = {
+ .byte_len = 4096,
+ .page_size = 32,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pcm038_i2c_devices[] = {
+ [0] = {
+ I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+ .platform_data = &board_eeprom,
+ },
+ [1] = {
+ I2C_BOARD_INFO("rtc-pcf8563", 0x51),
+ .type = "pcf8563"
+ },
+ [2] = {
+ I2C_BOARD_INFO("lm75", 0x4a),
+ .type = "lm75"
+ }
+};
+#endif
+
static void __init pcm038_init(void)
{
gpio_fec_active();
@@ -217,9 +264,17 @@ static void __init pcm038_init(void)
mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
- mxc_gpio_mode(PE16_AF_RTCK); /* OWIRE */
+ mxc_gpio_mode(PE16_AF_OWIRE);
mxc_register_device(&mxc_nand_device, &pcm038_nand_board_info);
+#ifdef CONFIG_I2C_IMX
+ /* only the i2c master 1 is used on this CPU card */
+ i2c_register_board_info(1, pcm038_i2c_devices,
+ ARRAY_SIZE(pcm038_i2c_devices));
+
+ mxc_register_device(&mxc_i2c_device1, &pcm038_i2c_1_data);
+#endif
+
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
#ifdef CONFIG_MACH_PCM970_BASEBOARD
@@ -229,11 +284,10 @@ static void __init pcm038_init(void)
static void __init pcm038_timer_init(void)
{
- mxc_clocks_init(26000000);
- mxc_timer_init("gpt_clk.0");
+ mx27_clocks_init(26000000);
}
-struct sys_timer pcm038_timer = {
+static struct sys_timer pcm038_timer = {
.init = pcm038_timer_init,
};
diff --git a/arch/arm/mach-mx2/pcm970-baseboard.c b/arch/arm/mach-mx2/pcm970-baseboard.c
index a560cd6ad23d..bf4e520bc1bc 100644
--- a/arch/arm/mach-mx2/pcm970-baseboard.c
+++ b/arch/arm/mach-mx2/pcm970-baseboard.c
@@ -17,9 +17,138 @@
*/
#include <linux/platform_device.h>
-#include <mach/hardware.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
#include <asm/mach/arch.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/mmc.h>
+#include <mach/imxfb.h>
+#include <mach/iomux.h>
+
+#include "devices.h"
+
+static int pcm970_sdhc2_get_ro(struct device *dev)
+{
+ return gpio_get_value(GPIO_PORTC + 28);
+}
+
+static int pcm970_sdhc2_pins[] = {
+ PB4_PF_SD2_D0,
+ PB5_PF_SD2_D1,
+ PB6_PF_SD2_D2,
+ PB7_PF_SD2_D3,
+ PB8_PF_SD2_CMD,
+ PB9_PF_SD2_CLK,
+};
+
+static int pcm970_sdhc2_init(struct device *dev, irq_handler_t detect_irq, void *data)
+{
+ int ret;
+
+ ret = mxc_gpio_setup_multiple_pins(pcm970_sdhc2_pins,
+ ARRAY_SIZE(pcm970_sdhc2_pins), "sdhc2");
+ if(ret)
+ return ret;
+
+ ret = request_irq(IRQ_GPIOC(29), detect_irq, 0,
+ "imx-mmc-detect", data);
+ if (ret)
+ goto out_release_gpio;
+
+ set_irq_type(IRQ_GPIOC(29), IRQF_TRIGGER_FALLING);
+
+ ret = gpio_request(GPIO_PORTC + 28, "imx-mmc-ro");
+ if (ret)
+ goto out_release_gpio;
+
+ mxc_gpio_mode((GPIO_PORTC | 28) | GPIO_GPIO | GPIO_IN);
+ gpio_direction_input(GPIO_PORTC + 28);
+
+ return 0;
+
+out_release_gpio:
+ mxc_gpio_release_multiple_pins(pcm970_sdhc2_pins,
+ ARRAY_SIZE(pcm970_sdhc2_pins));
+ return ret;
+}
+
+static void pcm970_sdhc2_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOC(29), data);
+ gpio_free(GPIO_PORTC + 28);
+ mxc_gpio_release_multiple_pins(pcm970_sdhc2_pins,
+ ARRAY_SIZE(pcm970_sdhc2_pins));
+}
+
+static struct imxmmc_platform_data sdhc_pdata = {
+ .get_ro = pcm970_sdhc2_get_ro,
+ .init = pcm970_sdhc2_init,
+ .exit = pcm970_sdhc2_exit,
+};
+
+static int mxc_fb_pins[] = {
+ PA5_PF_LSCLK, PA6_PF_LD0, PA7_PF_LD1, PA8_PF_LD2,
+ PA9_PF_LD3, PA10_PF_LD4, PA11_PF_LD5, PA12_PF_LD6,
+ PA13_PF_LD7, PA14_PF_LD8, PA15_PF_LD9, PA16_PF_LD10,
+ PA17_PF_LD11, PA18_PF_LD12, PA19_PF_LD13, PA20_PF_LD14,
+ PA21_PF_LD15, PA22_PF_LD16, PA23_PF_LD17, PA24_PF_REV,
+ PA25_PF_CLS, PA26_PF_PS, PA27_PF_SPL_SPR, PA28_PF_HSYNC,
+ PA29_PF_VSYNC, PA30_PF_CONTRAST, PA31_PF_OE_ACD
+};
+
+static int pcm038_fb_init(struct platform_device *pdev)
+{
+ return mxc_gpio_setup_multiple_pins(mxc_fb_pins,
+ ARRAY_SIZE(mxc_fb_pins), "FB");
+}
+
+static int pcm038_fb_exit(struct platform_device *pdev)
+{
+ mxc_gpio_release_multiple_pins(mxc_fb_pins, ARRAY_SIZE(mxc_fb_pins));
+
+ return 0;
+}
+
+/*
+ * Connected is a portrait Sharp-QVGA display
+ * of type: LQ035Q7DH06
+ */
+static struct imx_fb_platform_data pcm038_fb_data = {
+ .pixclock = 188679, /* in ps (5.3MHz) */
+ .xres = 240,
+ .yres = 320,
+
+ .bpp = 16,
+ .hsync_len = 7,
+ .left_margin = 5,
+ .right_margin = 16,
+
+ .vsync_len = 1,
+ .upper_margin = 7,
+ .lower_margin = 9,
+ .fixed_screen_cpu = 0,
+
+ /*
+ * - HSYNC active high
+ * - VSYNC active high
+ * - clk notenabled while idle
+ * - clock not inverted
+ * - data not inverted
+ * - data enable low active
+ * - enable sharp mode
+ */
+ .pcr = 0xFA0080C0,
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020010,
+
+ .init = pcm038_fb_init,
+ .exit = pcm038_fb_exit,
+};
+
/*
* system init for baseboard usage. Will be called by pcm038 init.
*
@@ -28,4 +157,6 @@
*/
void __init pcm970_baseboard_init(void)
{
+ mxc_register_device(&mxc_fb_device, &pcm038_fb_data);
+ mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
}
diff --git a/arch/arm/mach-mx2/serial.c b/arch/arm/mach-mx2/serial.c
index 16debc296dad..40a485cdc10e 100644
--- a/arch/arm/mach-mx2/serial.c
+++ b/arch/arm/mach-mx2/serial.c
@@ -22,6 +22,7 @@
#include <linux/serial.h>
#include <mach/hardware.h>
#include <mach/imx-uart.h>
+#include "devices.h"
static struct resource uart0[] = {
{
@@ -99,6 +100,7 @@ struct platform_device mxc_uart_device3 = {
.num_resources = ARRAY_SIZE(uart3),
};
+#ifdef CONFIG_MACH_MX27
static struct resource uart4[] = {
{
.start = UART5_BASE_ADDR,
@@ -136,3 +138,4 @@ struct platform_device mxc_uart_device5 = {
.resource = uart5,
.num_resources = ARRAY_SIZE(uart5),
};
+#endif
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
index e79659e8176e..d6235583e979 100644
--- a/arch/arm/mach-mx3/Kconfig
+++ b/arch/arm/mach-mx3/Kconfig
@@ -1,21 +1,40 @@
-menu "MX3 Options"
- depends on ARCH_MX3
+if ARCH_MX3
+
+config ARCH_MX31
+ bool
+
+config ARCH_MX35
+ bool
+
+comment "MX3 platforms:"
config MACH_MX31ADS
bool "Support MX31ADS platforms"
+ select ARCH_MX31
default y
help
Include support for MX31ADS platform. This includes specific
configurations for the board and its peripherals.
+config MACH_MX31ADS_WM1133_EV1
+ bool "Support Wolfson Microelectronics 1133-EV1 module"
+ depends on MACH_MX31ADS
+ select MFD_WM8350_CONFIG_MODE_0
+ select MFD_WM8352_CONFIG_MODE_0
+ help
+ Include support for the Wolfson Microelectronics 1133-EV1 PMU
+ and audio module for the MX31ADS platform.
+
config MACH_PCM037
- bool "Support Phytec pcm037 platforms"
+ bool "Support Phytec pcm037 (i.MX31) platforms"
+ select ARCH_MX31
help
Include support for Phytec pcm037 platform. This includes
specific configurations for the board and its peripherals.
config MACH_MX31LITE
bool "Support MX31 LITEKIT (LogicPD)"
+ select ARCH_MX31
default n
help
Include support for MX31 LITEKIT platform. This includes specific
@@ -23,6 +42,7 @@ config MACH_MX31LITE
config MACH_MX31_3DS
bool "Support MX31PDK (3DS)"
+ select ARCH_MX31
default n
help
Include support for MX31PDK (3DS) platform. This includes specific
@@ -30,10 +50,18 @@ config MACH_MX31_3DS
config MACH_MX31MOBOARD
bool "Support mx31moboard platforms (EPFL Mobots group)"
+ select ARCH_MX31
default n
help
Include support for mx31moboard platform. This includes specific
configurations for the board and its peripherals.
-endmenu
+config MACH_QONG
+ bool "Support Dave/DENX QongEVB-LITE platform"
+ select ARCH_MX31
+ default n
+ help
+ Include support for Dave/DENX QongEVB-LITE platform. This includes
+ specific configurations for the board and its peripherals.
+endif
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
index 5a151540fe83..272c8a953b30 100644
--- a/arch/arm/mach-mx3/Makefile
+++ b/arch/arm/mach-mx3/Makefile
@@ -4,9 +4,13 @@
# Object file lists.
-obj-y := mm.o clock.o devices.o iomux.o
+obj-y := mm.o devices.o
+obj-$(CONFIG_ARCH_MX31) += clock.o iomux.o
+obj-$(CONFIG_ARCH_MX35) += clock-imx35.o
obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o
obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o
obj-$(CONFIG_MACH_PCM037) += pcm037.o
obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o
-obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o
+obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o mx31moboard-devboard.o \
+ mx31moboard-marxbot.o
+obj-$(CONFIG_MACH_QONG) += qong.o
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c
new file mode 100644
index 000000000000..53a112d4e04a
--- /dev/null
+++ b/arch/arm/mach-mx3/clock-imx35.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define CCM_BASE IO_ADDRESS(CCM_BASE_ADDR)
+
+#define CCM_CCMR 0x00
+#define CCM_PDR0 0x04
+#define CCM_PDR1 0x08
+#define CCM_PDR2 0x0C
+#define CCM_PDR3 0x10
+#define CCM_PDR4 0x14
+#define CCM_RCSR 0x18
+#define CCM_MPCTL 0x1C
+#define CCM_PPCTL 0x20
+#define CCM_ACMR 0x24
+#define CCM_COSR 0x28
+#define CCM_CGR0 0x2C
+#define CCM_CGR1 0x30
+#define CCM_CGR2 0x34
+#define CCM_CGR3 0x38
+
+#ifdef HAVE_SET_RATE_SUPPORT
+static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost)
+{
+ u32 min_pre, temp_pre, old_err, err;
+
+ min_pre = (div - 1) / maxpost + 1;
+ old_err = 8;
+
+ for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+ if (div > (temp_pre * maxpost))
+ break;
+
+ if (div < (temp_pre * temp_pre))
+ continue;
+
+ err = div % temp_pre;
+
+ if (err == 0) {
+ *pre = temp_pre;
+ break;
+ }
+
+ err = temp_pre - err;
+
+ if (err < old_err) {
+ old_err = err;
+ *pre = temp_pre;
+ }
+ }
+
+ *post = (div + *pre - 1) / *pre;
+}
+
+/* get the best values for a 3-bit divider combined with a 6-bit divider */
+static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post)
+{
+ if (div >= 512) {
+ *pre = 8;
+ *post = 64;
+ } else if (div >= 64) {
+ calc_dividers(div, pre, post, 64);
+ } else if (div <= 8) {
+ *pre = div;
+ *post = 1;
+ } else {
+ *pre = 1;
+ *post = div;
+ }
+}
+
+/* get the best values for two cascaded 3-bit dividers */
+static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post)
+{
+ if (div >= 64) {
+ *pre = *post = 8;
+ } else if (div > 8) {
+ calc_dividers(div, pre, post, 8);
+ } else {
+ *pre = 1;
+ *post = div;
+ }
+}
+#endif
+
+static unsigned long get_rate_mpll(void)
+{
+ ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL);
+
+ return mxc_decode_pll(mpctl, 24000000);
+}
+
+static unsigned long get_rate_ppll(void)
+{
+ ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL);
+
+ return mxc_decode_pll(ppctl, 24000000);
+}
+
+struct arm_ahb_div {
+ unsigned char arm, ahb, sel;
+};
+
+static struct arm_ahb_div clk_consumer[] = {
+ { .arm = 1, .ahb = 4, .sel = 0},
+ { .arm = 1, .ahb = 3, .sel = 1},
+ { .arm = 2, .ahb = 2, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 4, .ahb = 1, .sel = 0},
+ { .arm = 1, .ahb = 5, .sel = 0},
+ { .arm = 1, .ahb = 8, .sel = 0},
+ { .arm = 1, .ahb = 6, .sel = 1},
+ { .arm = 2, .ahb = 4, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 4, .ahb = 2, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+};
+
+static struct arm_ahb_div clk_automotive[] = {
+ { .arm = 1, .ahb = 3, .sel = 0},
+ { .arm = 1, .ahb = 2, .sel = 1},
+ { .arm = 2, .ahb = 1, .sel = 1},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 1, .ahb = 6, .sel = 0},
+ { .arm = 1, .ahb = 4, .sel = 1},
+ { .arm = 2, .ahb = 2, .sel = 1},
+ { .arm = 0, .ahb = 0, .sel = 0},
+};
+
+static unsigned long get_rate_arm(void)
+{
+ unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+ struct arm_ahb_div *aad;
+ unsigned long fref = get_rate_mpll();
+
+ if (pdr0 & 1) {
+ /* consumer path */
+ aad = &clk_consumer[(pdr0 >> 16) & 0xf];
+ if (aad->sel)
+ fref = fref * 2 / 3;
+ } else {
+ /* auto path */
+ aad = &clk_automotive[(pdr0 >> 9) & 0x7];
+ if (aad->sel)
+ fref = fref * 3 / 4;
+ }
+ return fref / aad->arm;
+}
+
+static unsigned long get_rate_ahb(struct clk *clk)
+{
+ unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+ struct arm_ahb_div *aad;
+ unsigned long fref = get_rate_mpll();
+
+ if (pdr0 & 1)
+ /* consumer path */
+ aad = &clk_consumer[(pdr0 >> 16) & 0xf];
+ else
+ /* auto path */
+ aad = &clk_automotive[(pdr0 >> 9) & 0x7];
+
+ return fref / aad->ahb;
+}
+
+static unsigned long get_rate_ipg(struct clk *clk)
+{
+ return get_rate_ahb(NULL) >> 1;
+}
+
+static unsigned long get_3_3_div(unsigned long in)
+{
+ return (((in >> 3) & 0x7) + 1) * ((in & 0x7) + 1);
+}
+
+static unsigned long get_rate_uart(struct clk *clk)
+{
+ unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
+ unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+ unsigned long div = get_3_3_div(pdr4 >> 10);
+
+ if (pdr3 & (1 << 14))
+ return get_rate_arm() / div;
+ else
+ return get_rate_ppll() / div;
+}
+
+static unsigned long get_rate_sdhc(struct clk *clk)
+{
+ unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
+ unsigned long div, rate;
+
+ if (pdr3 & (1 << 6))
+ rate = get_rate_arm();
+ else
+ rate = get_rate_ppll();
+
+ switch (clk->id) {
+ default:
+ case 0:
+ div = pdr3 & 0x3f;
+ break;
+ case 1:
+ div = (pdr3 >> 8) & 0x3f;
+ break;
+ case 2:
+ div = (pdr3 >> 16) & 0x3f;
+ break;
+ }
+
+ return rate / get_3_3_div(div);
+}
+
+static unsigned long get_rate_mshc(struct clk *clk)
+{
+ unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1);
+ unsigned long div1, div2, rate;
+
+ if (pdr1 & (1 << 7))
+ rate = get_rate_arm();
+ else
+ rate = get_rate_ppll();
+
+ div1 = (pdr1 >> 29) & 0x7;
+ div2 = (pdr1 >> 22) & 0x3f;
+
+ return rate / ((div1 + 1) * (div2 + 1));
+}
+
+static unsigned long get_rate_ssi(struct clk *clk)
+{
+ unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
+ unsigned long div1, div2, rate;
+
+ if (pdr2 & (1 << 6))
+ rate = get_rate_arm();
+ else
+ rate = get_rate_ppll();
+
+ switch (clk->id) {
+ default:
+ case 0:
+ div1 = pdr2 & 0x3f;
+ div2 = (pdr2 >> 24) & 0x7;
+ break;
+ case 1:
+ div1 = (pdr2 >> 8) & 0x3f;
+ div2 = (pdr2 >> 27) & 0x7;
+ break;
+ }
+
+ return rate / ((div1 + 1) * (div2 + 1));
+}
+
+static unsigned long get_rate_csi(struct clk *clk)
+{
+ unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
+ unsigned long rate;
+
+ if (pdr2 & (1 << 7))
+ rate = get_rate_arm();
+ else
+ rate = get_rate_ppll();
+
+ return rate / get_3_3_div((pdr2 >> 16) & 0x3f);
+}
+
+static unsigned long get_rate_ipg_per(struct clk *clk)
+{
+ unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+ unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+ unsigned long div1, div2;
+
+ if (pdr0 & (1 << 26)) {
+ div1 = (pdr4 >> 19) & 0x7;
+ div2 = (pdr4 >> 16) & 0x7;
+ return get_rate_arm() / ((div1 + 1) * (div2 + 1));
+ } else {
+ div1 = (pdr0 >> 12) & 0x7;
+ return get_rate_ahb(NULL) / div1;
+ }
+}
+
+static int clk_cgr_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 3 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void clk_cgr_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(3 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = CCM_BASE + er, \
+ .enable_shift = es, \
+ .get_rate = gr, \
+ .set_rate = sr, \
+ .enable = clk_cgr_enable, \
+ .disable = clk_cgr_disable, \
+ }
+
+DEFINE_CLOCK(asrc_clk, 0, CCM_CGR0, 0, NULL, NULL);
+DEFINE_CLOCK(ata_clk, 0, CCM_CGR0, 2, get_rate_ipg, NULL);
+DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0, 4, NULL, NULL);
+DEFINE_CLOCK(can1_clk, 0, CCM_CGR0, 6, get_rate_ipg, NULL);
+DEFINE_CLOCK(can2_clk, 1, CCM_CGR0, 8, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi1_clk, 0, CCM_CGR0, 10, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi2_clk, 1, CCM_CGR0, 12, get_rate_ipg, NULL);
+DEFINE_CLOCK(ect_clk, 0, CCM_CGR0, 14, get_rate_ipg, NULL);
+DEFINE_CLOCK(edio_clk, 0, CCM_CGR0, 16, NULL, NULL);
+DEFINE_CLOCK(emi_clk, 0, CCM_CGR0, 18, get_rate_ipg, NULL);
+DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(esai_clk, 0, CCM_CGR0, 24, NULL, NULL);
+DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL);
+DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL);
+DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL);
+
+DEFINE_CLOCK(fec_clk, 0, CCM_CGR1, 0, get_rate_ipg, NULL);
+DEFINE_CLOCK(gpio1_clk, 0, CCM_CGR1, 2, NULL, NULL);
+DEFINE_CLOCK(gpio2_clk, 1, CCM_CGR1, 4, NULL, NULL);
+DEFINE_CLOCK(gpio3_clk, 2, CCM_CGR1, 6, NULL, NULL);
+DEFINE_CLOCK(gpt_clk, 0, CCM_CGR1, 8, get_rate_ipg, NULL);
+DEFINE_CLOCK(i2c1_clk, 0, CCM_CGR1, 10, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(i2c2_clk, 1, CCM_CGR1, 12, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(i2c3_clk, 2, CCM_CGR1, 14, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL);
+DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, NULL, NULL);
+DEFINE_CLOCK(kpp_clk, 0, CCM_CGR1, 20, get_rate_ipg, NULL);
+DEFINE_CLOCK(mlb_clk, 0, CCM_CGR1, 22, get_rate_ahb, NULL);
+DEFINE_CLOCK(mshc_clk, 0, CCM_CGR1, 24, get_rate_mshc, NULL);
+DEFINE_CLOCK(owire_clk, 0, CCM_CGR1, 26, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(pwm_clk, 0, CCM_CGR1, 28, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(rngc_clk, 0, CCM_CGR1, 30, get_rate_ipg, NULL);
+
+DEFINE_CLOCK(rtc_clk, 0, CCM_CGR2, 0, get_rate_ipg, NULL);
+DEFINE_CLOCK(rtic_clk, 0, CCM_CGR2, 2, get_rate_ahb, NULL);
+DEFINE_CLOCK(scc_clk, 0, CCM_CGR2, 4, get_rate_ipg, NULL);
+DEFINE_CLOCK(sdma_clk, 0, CCM_CGR2, 6, NULL, NULL);
+DEFINE_CLOCK(spba_clk, 0, CCM_CGR2, 8, get_rate_ipg, NULL);
+DEFINE_CLOCK(spdif_clk, 0, CCM_CGR2, 10, NULL, NULL);
+DEFINE_CLOCK(ssi1_clk, 0, CCM_CGR2, 12, get_rate_ssi, NULL);
+DEFINE_CLOCK(ssi2_clk, 1, CCM_CGR2, 14, get_rate_ssi, NULL);
+DEFINE_CLOCK(uart1_clk, 0, CCM_CGR2, 16, get_rate_uart, NULL);
+DEFINE_CLOCK(uart2_clk, 1, CCM_CGR2, 18, get_rate_uart, NULL);
+DEFINE_CLOCK(uart3_clk, 2, CCM_CGR2, 20, get_rate_uart, NULL);
+DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, NULL, NULL);
+DEFINE_CLOCK(wdog_clk, 0, CCM_CGR2, 24, NULL, NULL);
+DEFINE_CLOCK(max_clk, 0, CCM_CGR2, 26, NULL, NULL);
+DEFINE_CLOCK(admux_clk, 0, CCM_CGR2, 30, NULL, NULL);
+
+DEFINE_CLOCK(csi_clk, 0, CCM_CGR3, 0, get_rate_csi, NULL);
+DEFINE_CLOCK(iim_clk, 0, CCM_CGR3, 2, NULL, NULL);
+DEFINE_CLOCK(gpu2d_clk, 0, CCM_CGR3, 4, NULL, NULL);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] __initdata = {
+ _REGISTER_CLOCK(NULL, "asrc", asrc_clk)
+ _REGISTER_CLOCK(NULL, "ata", ata_clk)
+ _REGISTER_CLOCK(NULL, "audmux", audmux_clk)
+ _REGISTER_CLOCK(NULL, "can", can1_clk)
+ _REGISTER_CLOCK(NULL, "can", can2_clk)
+ _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK(NULL, "ect", ect_clk)
+ _REGISTER_CLOCK(NULL, "edio", edio_clk)
+ _REGISTER_CLOCK(NULL, "emi", emi_clk)
+ _REGISTER_CLOCK(NULL, "epit", epit1_clk)
+ _REGISTER_CLOCK(NULL, "epit", epit2_clk)
+ _REGISTER_CLOCK(NULL, "esai", esai_clk)
+ _REGISTER_CLOCK(NULL, "sdhc", esdhc1_clk)
+ _REGISTER_CLOCK(NULL, "sdhc", esdhc2_clk)
+ _REGISTER_CLOCK(NULL, "sdhc", esdhc3_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
+ _REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
+ _REGISTER_CLOCK(NULL, "gpio", gpio3_clk)
+ _REGISTER_CLOCK("gpt.0", NULL, gpt_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
+ _REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk)
+ _REGISTER_CLOCK(NULL, "ipu", ipu_clk)
+ _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
+ _REGISTER_CLOCK(NULL, "mlb", mlb_clk)
+ _REGISTER_CLOCK(NULL, "mshc", mshc_clk)
+ _REGISTER_CLOCK("mxc_w1", NULL, owire_clk)
+ _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+ _REGISTER_CLOCK(NULL, "rngc", rngc_clk)
+ _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+ _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
+ _REGISTER_CLOCK(NULL, "scc", scc_clk)
+ _REGISTER_CLOCK(NULL, "sdma", sdma_clk)
+ _REGISTER_CLOCK(NULL, "spba", spba_clk)
+ _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
+ _REGISTER_CLOCK(NULL, "ssi", ssi1_clk)
+ _REGISTER_CLOCK(NULL, "ssi", ssi2_clk)
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ _REGISTER_CLOCK(NULL, "usbotg", usbotg_clk)
+ _REGISTER_CLOCK("mxc_wdt.0", NULL, wdog_clk)
+ _REGISTER_CLOCK(NULL, "max", max_clk)
+ _REGISTER_CLOCK(NULL, "admux", admux_clk)
+ _REGISTER_CLOCK(NULL, "csi", csi_clk)
+ _REGISTER_CLOCK(NULL, "iim", iim_clk)
+ _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk)
+};
+
+int __init mx35_clocks_init()
+{
+ int i;
+ unsigned int ll = 0;
+
+ mxc_set_cpu_type(MXC_CPU_MX35);
+
+#ifdef CONFIG_DEBUG_LL_CONSOLE
+ ll = (3 << 16);
+#endif
+
+ for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ clkdev_add(&lookups[i]);
+
+ /* Turn off all clocks except the ones we need to survive, namely:
+ * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart
+ */
+ __raw_writel((3 << 18), CCM_BASE + CCM_CGR0);
+ __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16),
+ CCM_BASE + CCM_CGR1);
+ __raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2);
+ __raw_writel(0, CCM_BASE + CCM_CGR3);
+
+ mxc_timer_init(&gpt_clk);
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c
index b1746aae1f89..ca46f4801c3d 100644
--- a/arch/arm/mach-mx3/clock.c
+++ b/arch/arm/mach-mx3/clock.c
@@ -23,9 +23,13 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
#include <mach/clock.h>
#include <mach/hardware.h>
-#include <asm/div64.h>
+#include <mach/common.h>
#include "crm_regs.h"
@@ -64,17 +68,17 @@ static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
}
static struct clk mcu_pll_clk;
-static struct clk mcu_main_clk;
-static struct clk usb_pll_clk;
static struct clk serial_pll_clk;
static struct clk ipg_clk;
static struct clk ckih_clk;
-static struct clk ahb_clk;
-static int _clk_enable(struct clk *clk)
+static int cgr_enable(struct clk *clk)
{
u32 reg;
+ if (!clk->enable_reg)
+ return 0;
+
reg = __raw_readl(clk->enable_reg);
reg |= 3 << clk->enable_shift;
__raw_writel(reg, clk->enable_reg);
@@ -82,133 +86,69 @@ static int _clk_enable(struct clk *clk)
return 0;
}
-static void _clk_disable(struct clk *clk)
+static void cgr_disable(struct clk *clk)
{
u32 reg;
+ if (!clk->enable_reg)
+ return;
+
reg = __raw_readl(clk->enable_reg);
reg &= ~(3 << clk->enable_shift);
+
+ /* special case for EMI clock */
+ if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8)
+ reg |= (1 << clk->enable_shift);
+
__raw_writel(reg, clk->enable_reg);
}
-static void _clk_emi_disable(struct clk *clk)
+static unsigned long pll_ref_get_rate(void)
{
- u32 reg;
+ unsigned long ccmr;
+ unsigned int prcs;
- reg = __raw_readl(clk->enable_reg);
- reg &= ~(3 << clk->enable_shift);
- reg |= (1 << clk->enable_shift);
- __raw_writel(reg, clk->enable_reg);
+ ccmr = __raw_readl(MXC_CCM_CCMR);
+ prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET;
+ if (prcs == 0x1)
+ return CKIL_CLK_FREQ * 1024;
+ else
+ return clk_get_rate(&ckih_clk);
}
-static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
+static unsigned long usb_pll_get_rate(struct clk *clk)
{
- u32 reg;
- signed long pd = 1; /* Pre-divider */
- signed long mfi; /* Multiplication Factor (Integer part) */
- signed long mfn; /* Multiplication Factor (Integer part) */
- signed long mfd; /* Multiplication Factor (Denominator Part) */
- signed long tmp;
- u32 ref_freq = clk_get_rate(clk->parent);
+ unsigned long reg;
- while (((ref_freq / pd) * 10) > rate)
- pd++;
+ reg = __raw_readl(MXC_CCM_UPCTL);
- if ((ref_freq / pd) < PRE_DIV_MIN_FREQ)
- return -EINVAL;
+ return mxc_decode_pll(reg, pll_ref_get_rate());
+}
- /* the ref_freq/2 in the following is to round up */
- mfi = (((rate / 2) * pd) + (ref_freq / 2)) / ref_freq;
- if (mfi < 5 || mfi > 15)
- return -EINVAL;
+static unsigned long serial_pll_get_rate(struct clk *clk)
+{
+ unsigned long reg;
- /* pick a mfd value that will work
- * then solve for mfn */
- mfd = ref_freq / 50000;
-
- /*
- * pll_freq * pd * mfd
- * mfn = -------------------- - (mfi * mfd)
- * 2 * ref_freq
- */
- /* the tmp/2 is for rounding */
- tmp = ref_freq / 10000;
- mfn =
- ((((((rate / 2) + (tmp / 2)) / tmp) * pd) * mfd) / 10000) -
- (mfi * mfd);
-
- mfn = mfn & 0x3ff;
- pd--;
- mfd--;
-
- /* Change the Pll value */
- reg = (mfi << MXC_CCM_PCTL_MFI_OFFSET) |
- (mfn << MXC_CCM_PCTL_MFN_OFFSET) |
- (mfd << MXC_CCM_PCTL_MFD_OFFSET) | (pd << MXC_CCM_PCTL_PD_OFFSET);
-
- if (clk == &mcu_pll_clk)
- __raw_writel(reg, MXC_CCM_MPCTL);
- else if (clk == &usb_pll_clk)
- __raw_writel(reg, MXC_CCM_UPCTL);
- else if (clk == &serial_pll_clk)
- __raw_writel(reg, MXC_CCM_SRPCTL);
+ reg = __raw_readl(MXC_CCM_SRPCTL);
- return 0;
+ return mxc_decode_pll(reg, pll_ref_get_rate());
}
-static unsigned long _clk_pll_get_rate(struct clk *clk)
+static unsigned long mcu_pll_get_rate(struct clk *clk)
{
- long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
unsigned long reg, ccmr;
- s64 temp;
- unsigned int prcs;
ccmr = __raw_readl(MXC_CCM_CCMR);
- prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET;
- if (prcs == 0x1)
- ref_clk = CKIL_CLK_FREQ * 1024;
- else
- ref_clk = clk_get_rate(&ckih_clk);
-
- if (clk == &mcu_pll_clk) {
- if ((ccmr & MXC_CCM_CCMR_MPE) == 0)
- return ref_clk;
- if ((ccmr & MXC_CCM_CCMR_MDS) != 0)
- return ref_clk;
- reg = __raw_readl(MXC_CCM_MPCTL);
- } else if (clk == &usb_pll_clk)
- reg = __raw_readl(MXC_CCM_UPCTL);
- else if (clk == &serial_pll_clk)
- reg = __raw_readl(MXC_CCM_SRPCTL);
- else {
- BUG();
- return 0;
- }
-
- pdf = (reg & MXC_CCM_PCTL_PD_MASK) >> MXC_CCM_PCTL_PD_OFFSET;
- mfd = (reg & MXC_CCM_PCTL_MFD_MASK) >> MXC_CCM_PCTL_MFD_OFFSET;
- mfi = (reg & MXC_CCM_PCTL_MFI_MASK) >> MXC_CCM_PCTL_MFI_OFFSET;
- mfi = (mfi <= 5) ? 5 : mfi;
- mfn = mfn_abs = reg & MXC_CCM_PCTL_MFN_MASK;
- if (mfn >= 0x200) {
- mfn |= 0xFFFFFE00;
- mfn_abs = -mfn;
- }
-
- ref_clk *= 2;
- ref_clk /= pdf + 1;
+ if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS))
+ return clk_get_rate(&ckih_clk);
- temp = (u64) ref_clk * mfn_abs;
- do_div(temp, mfd + 1);
- if (mfn < 0)
- temp = -temp;
- temp = (ref_clk * mfi) + temp;
+ reg = __raw_readl(MXC_CCM_MPCTL);
- return temp;
+ return mxc_decode_pll(reg, pll_ref_get_rate());
}
-static int _clk_usb_pll_enable(struct clk *clk)
+static int usb_pll_enable(struct clk *clk)
{
u32 reg;
@@ -222,7 +162,7 @@ static int _clk_usb_pll_enable(struct clk *clk)
return 0;
}
-static void _clk_usb_pll_disable(struct clk *clk)
+static void usb_pll_disable(struct clk *clk)
{
u32 reg;
@@ -231,7 +171,7 @@ static void _clk_usb_pll_disable(struct clk *clk)
__raw_writel(reg, MXC_CCM_CCMR);
}
-static int _clk_serial_pll_enable(struct clk *clk)
+static int serial_pll_enable(struct clk *clk)
{
u32 reg;
@@ -245,7 +185,7 @@ static int _clk_serial_pll_enable(struct clk *clk)
return 0;
}
-static void _clk_serial_pll_disable(struct clk *clk)
+static void serial_pll_disable(struct clk *clk)
{
u32 reg;
@@ -258,7 +198,7 @@ static void _clk_serial_pll_disable(struct clk *clk)
#define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
#define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
-static unsigned long _clk_mcu_main_get_rate(struct clk *clk)
+static unsigned long mcu_main_get_rate(struct clk *clk)
{
u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
@@ -268,7 +208,7 @@ static unsigned long _clk_mcu_main_get_rate(struct clk *clk)
return clk_get_rate(&mcu_pll_clk);
}
-static unsigned long _clk_hclk_get_rate(struct clk *clk)
+static unsigned long ahb_get_rate(struct clk *clk)
{
unsigned long max_pdf;
@@ -277,7 +217,7 @@ static unsigned long _clk_hclk_get_rate(struct clk *clk)
return clk_get_rate(clk->parent) / (max_pdf + 1);
}
-static unsigned long _clk_ipg_get_rate(struct clk *clk)
+static unsigned long ipg_get_rate(struct clk *clk)
{
unsigned long ipg_pdf;
@@ -286,7 +226,7 @@ static unsigned long _clk_ipg_get_rate(struct clk *clk)
return clk_get_rate(clk->parent) / (ipg_pdf + 1);
}
-static unsigned long _clk_nfc_get_rate(struct clk *clk)
+static unsigned long nfc_get_rate(struct clk *clk)
{
unsigned long nfc_pdf;
@@ -295,7 +235,7 @@ static unsigned long _clk_nfc_get_rate(struct clk *clk)
return clk_get_rate(clk->parent) / (nfc_pdf + 1);
}
-static unsigned long _clk_hsp_get_rate(struct clk *clk)
+static unsigned long hsp_get_rate(struct clk *clk)
{
unsigned long hsp_pdf;
@@ -304,7 +244,7 @@ static unsigned long _clk_hsp_get_rate(struct clk *clk)
return clk_get_rate(clk->parent) / (hsp_pdf + 1);
}
-static unsigned long _clk_usb_get_rate(struct clk *clk)
+static unsigned long usb_get_rate(struct clk *clk)
{
unsigned long usb_pdf, usb_prepdf;
@@ -315,7 +255,7 @@ static unsigned long _clk_usb_get_rate(struct clk *clk)
return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1);
}
-static unsigned long _clk_csi_get_rate(struct clk *clk)
+static unsigned long csi_get_rate(struct clk *clk)
{
u32 reg, pre, post;
@@ -329,7 +269,7 @@ static unsigned long _clk_csi_get_rate(struct clk *clk)
return clk_get_rate(clk->parent) / (pre * post);
}
-static unsigned long _clk_csi_round_rate(struct clk *clk, unsigned long rate)
+static unsigned long csi_round_rate(struct clk *clk, unsigned long rate)
{
u32 pre, post, parent = clk_get_rate(clk->parent);
u32 div = parent / rate;
@@ -342,7 +282,7 @@ static unsigned long _clk_csi_round_rate(struct clk *clk, unsigned long rate)
return parent / (pre * post);
}
-static int _clk_csi_set_rate(struct clk *clk, unsigned long rate)
+static int csi_set_rate(struct clk *clk, unsigned long rate)
{
u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
@@ -363,16 +303,7 @@ static int _clk_csi_set_rate(struct clk *clk, unsigned long rate)
return 0;
}
-static unsigned long _clk_per_get_rate(struct clk *clk)
-{
- unsigned long per_pdf;
-
- per_pdf = PDR0(MXC_CCM_PDR0_PER_PODF_MASK,
- MXC_CCM_PDR0_PER_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (per_pdf + 1);
-}
-
-static unsigned long _clk_ssi1_get_rate(struct clk *clk)
+static unsigned long ssi1_get_rate(struct clk *clk)
{
unsigned long ssi1_pdf, ssi1_prepdf;
@@ -383,7 +314,7 @@ static unsigned long _clk_ssi1_get_rate(struct clk *clk)
return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
}
-static unsigned long _clk_ssi2_get_rate(struct clk *clk)
+static unsigned long ssi2_get_rate(struct clk *clk)
{
unsigned long ssi2_pdf, ssi2_prepdf;
@@ -394,7 +325,7 @@ static unsigned long _clk_ssi2_get_rate(struct clk *clk)
return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
}
-static unsigned long _clk_firi_get_rate(struct clk *clk)
+static unsigned long firi_get_rate(struct clk *clk)
{
unsigned long firi_pdf, firi_prepdf;
@@ -405,7 +336,7 @@ static unsigned long _clk_firi_get_rate(struct clk *clk)
return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1);
}
-static unsigned long _clk_firi_round_rate(struct clk *clk, unsigned long rate)
+static unsigned long firi_round_rate(struct clk *clk, unsigned long rate)
{
u32 pre, post;
u32 parent = clk_get_rate(clk->parent);
@@ -420,7 +351,7 @@ static unsigned long _clk_firi_round_rate(struct clk *clk, unsigned long rate)
}
-static int _clk_firi_set_rate(struct clk *clk, unsigned long rate)
+static int firi_set_rate(struct clk *clk, unsigned long rate)
{
u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
@@ -441,12 +372,12 @@ static int _clk_firi_set_rate(struct clk *clk, unsigned long rate)
return 0;
}
-static unsigned long _clk_mbx_get_rate(struct clk *clk)
+static unsigned long mbx_get_rate(struct clk *clk)
{
return clk_get_rate(clk->parent) / 2;
}
-static unsigned long _clk_mstick1_get_rate(struct clk *clk)
+static unsigned long mstick1_get_rate(struct clk *clk)
{
unsigned long msti_pdf;
@@ -455,7 +386,7 @@ static unsigned long _clk_mstick1_get_rate(struct clk *clk)
return clk_get_rate(clk->parent) / (msti_pdf + 1);
}
-static unsigned long _clk_mstick2_get_rate(struct clk *clk)
+static unsigned long mstick2_get_rate(struct clk *clk)
{
unsigned long msti_pdf;
@@ -472,661 +403,185 @@ static unsigned long clk_ckih_get_rate(struct clk *clk)
}
static struct clk ckih_clk = {
- .name = "ckih",
.get_rate = clk_ckih_get_rate,
};
-static unsigned long clk_ckil_get_rate(struct clk *clk)
-{
- return CKIL_CLK_FREQ;
-}
-
-static struct clk ckil_clk = {
- .name = "ckil",
- .get_rate = clk_ckil_get_rate,
-};
-
static struct clk mcu_pll_clk = {
- .name = "mcu_pll",
.parent = &ckih_clk,
- .set_rate = _clk_pll_set_rate,
- .get_rate = _clk_pll_get_rate,
+ .get_rate = mcu_pll_get_rate,
};
static struct clk mcu_main_clk = {
- .name = "mcu_main_clk",
.parent = &mcu_pll_clk,
- .get_rate = _clk_mcu_main_get_rate,
+ .get_rate = mcu_main_get_rate,
};
static struct clk serial_pll_clk = {
- .name = "serial_pll",
.parent = &ckih_clk,
- .set_rate = _clk_pll_set_rate,
- .get_rate = _clk_pll_get_rate,
- .enable = _clk_serial_pll_enable,
- .disable = _clk_serial_pll_disable,
+ .get_rate = serial_pll_get_rate,
+ .enable = serial_pll_enable,
+ .disable = serial_pll_disable,
};
static struct clk usb_pll_clk = {
- .name = "usb_pll",
.parent = &ckih_clk,
- .set_rate = _clk_pll_set_rate,
- .get_rate = _clk_pll_get_rate,
- .enable = _clk_usb_pll_enable,
- .disable = _clk_usb_pll_disable,
+ .get_rate = usb_pll_get_rate,
+ .enable = usb_pll_enable,
+ .disable = usb_pll_disable,
};
static struct clk ahb_clk = {
- .name = "ahb_clk",
.parent = &mcu_main_clk,
- .get_rate = _clk_hclk_get_rate,
-};
-
-static struct clk per_clk = {
- .name = "per_clk",
- .parent = &usb_pll_clk,
- .get_rate = _clk_per_get_rate,
-};
-
-static struct clk perclk_clk = {
- .name = "perclk_clk",
- .parent = &ipg_clk,
-};
-
-static struct clk cspi_clk[] = {
- {
- .name = "cspi_clk",
- .id = 0,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR2,
- .enable_shift = MXC_CCM_CGR2_CSPI1_OFFSET,
- .disable = _clk_disable,},
- {
- .name = "cspi_clk",
- .id = 1,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR2,
- .enable_shift = MXC_CCM_CGR2_CSPI2_OFFSET,
- .disable = _clk_disable,},
- {
- .name = "cspi_clk",
- .id = 2,
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_CSPI3_OFFSET,
- .disable = _clk_disable,},
-};
-
-static struct clk ipg_clk = {
- .name = "ipg_clk",
- .parent = &ahb_clk,
- .get_rate = _clk_ipg_get_rate,
-};
-
-static struct clk emi_clk = {
- .name = "emi_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR2,
- .enable_shift = MXC_CCM_CGR2_EMI_OFFSET,
- .disable = _clk_emi_disable,
-};
-
-static struct clk gpt_clk = {
- .name = "gpt_clk",
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_GPT_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk pwm_clk = {
- .name = "pwm_clk",
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR1_PWM_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk epit_clk[] = {
- {
- .name = "epit_clk",
- .id = 0,
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_EPIT1_OFFSET,
- .disable = _clk_disable,},
- {
- .name = "epit_clk",
- .id = 1,
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_EPIT2_OFFSET,
- .disable = _clk_disable,},
-};
-
-static struct clk nfc_clk = {
- .name = "nfc_clk",
- .parent = &ahb_clk,
- .get_rate = _clk_nfc_get_rate,
-};
-
-static struct clk scc_clk = {
- .name = "scc_clk",
- .parent = &ipg_clk,
-};
-
-static struct clk ipu_clk = {
- .name = "ipu_clk",
- .parent = &mcu_main_clk,
- .get_rate = _clk_hsp_get_rate,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_IPU_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk kpp_clk = {
- .name = "kpp_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_KPP_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk wdog_clk = {
- .name = "wdog_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_WDOG_OFFSET,
- .disable = _clk_disable,
-};
-static struct clk rtc_clk = {
- .name = "rtc_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_RTC_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk usb_clk[] = {
- {
- .name = "usb_clk",
- .parent = &usb_pll_clk,
- .get_rate = _clk_usb_get_rate,},
- {
- .name = "usb_ahb_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_USBOTG_OFFSET,
- .disable = _clk_disable,},
-};
-
-static struct clk csi_clk = {
- .name = "csi_clk",
- .parent = &serial_pll_clk,
- .get_rate = _clk_csi_get_rate,
- .round_rate = _clk_csi_round_rate,
- .set_rate = _clk_csi_set_rate,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_CSI_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk uart_clk[] = {
- {
- .name = "uart_clk",
- .id = 0,
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_UART1_OFFSET,
- .disable = _clk_disable,},
- {
- .name = "uart_clk",
- .id = 1,
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_UART2_OFFSET,
- .disable = _clk_disable,},
- {
- .name = "uart_clk",
- .id = 2,
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_UART3_OFFSET,
- .disable = _clk_disable,},
- {
- .name = "uart_clk",
- .id = 3,
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_UART4_OFFSET,
- .disable = _clk_disable,},
- {
- .name = "uart_clk",
- .id = 4,
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_UART5_OFFSET,
- .disable = _clk_disable,},
-};
-
-static struct clk i2c_clk[] = {
- {
- .name = "i2c_clk",
- .id = 0,
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_I2C1_OFFSET,
- .disable = _clk_disable,},
- {
- .name = "i2c_clk",
- .id = 1,
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_I2C2_OFFSET,
- .disable = _clk_disable,},
- {
- .name = "i2c_clk",
- .id = 2,
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_I2C3_OFFSET,
- .disable = _clk_disable,},
-};
-
-static struct clk owire_clk = {
- .name = "owire_clk",
- .parent = &perclk_clk,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_OWIRE_OFFSET,
- .enable = _clk_enable,
- .disable = _clk_disable,
-};
-
-static struct clk sdhc_clk[] = {
- {
- .name = "sdhc_clk",
- .id = 0,
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_SD_MMC1_OFFSET,
- .disable = _clk_disable,},
- {
- .name = "sdhc_clk",
- .id = 1,
- .parent = &perclk_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_SD_MMC2_OFFSET,
- .disable = _clk_disable,},
-};
-
-static struct clk ssi_clk[] = {
- {
- .name = "ssi_clk",
- .parent = &serial_pll_clk,
- .get_rate = _clk_ssi1_get_rate,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_SSI1_OFFSET,
- .disable = _clk_disable,},
- {
- .name = "ssi_clk",
- .id = 1,
- .parent = &serial_pll_clk,
- .get_rate = _clk_ssi2_get_rate,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR2,
- .enable_shift = MXC_CCM_CGR2_SSI2_OFFSET,
- .disable = _clk_disable,},
-};
-
-static struct clk firi_clk = {
- .name = "firi_clk",
- .parent = &usb_pll_clk,
- .round_rate = _clk_firi_round_rate,
- .set_rate = _clk_firi_set_rate,
- .get_rate = _clk_firi_get_rate,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR2,
- .enable_shift = MXC_CCM_CGR2_FIRI_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk ata_clk = {
- .name = "ata_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_ATA_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk mbx_clk = {
- .name = "mbx_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR2,
- .enable_shift = MXC_CCM_CGR2_GACC_OFFSET,
- .get_rate = _clk_mbx_get_rate,
-};
-
-static struct clk vpu_clk = {
- .name = "vpu_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR2,
- .enable_shift = MXC_CCM_CGR2_GACC_OFFSET,
- .get_rate = _clk_mbx_get_rate,
-};
-
-static struct clk rtic_clk = {
- .name = "rtic_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR2,
- .enable_shift = MXC_CCM_CGR2_RTIC_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk rng_clk = {
- .name = "rng_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_RNG_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk sdma_clk[] = {
- {
- .name = "sdma_ahb_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_SDMA_OFFSET,
- .disable = _clk_disable,},
- {
- .name = "sdma_ipg_clk",
- .parent = &ipg_clk,}
-};
-
-static struct clk mpeg4_clk = {
- .name = "mpeg4_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk vl2cc_clk = {
- .name = "vl2cc_clk",
- .parent = &ahb_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET,
- .disable = _clk_disable,
-};
-
-static struct clk mstick_clk[] = {
- {
- .name = "mstick_clk",
- .id = 0,
- .parent = &usb_pll_clk,
- .get_rate = _clk_mstick1_get_rate,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_MEMSTICK1_OFFSET,
- .disable = _clk_disable,},
- {
- .name = "mstick_clk",
- .id = 1,
- .parent = &usb_pll_clk,
- .get_rate = _clk_mstick2_get_rate,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR1,
- .enable_shift = MXC_CCM_CGR1_MEMSTICK2_OFFSET,
- .disable = _clk_disable,},
-};
-
-static struct clk iim_clk = {
- .name = "iim_clk",
- .parent = &ipg_clk,
- .enable = _clk_enable,
- .enable_reg = MXC_CCM_CGR0,
- .enable_shift = MXC_CCM_CGR0_IIM_OFFSET,
- .disable = _clk_disable,
-};
-
-static unsigned long _clk_cko1_round_rate(struct clk *clk, unsigned long rate)
-{
- u32 div, parent = clk_get_rate(clk->parent);
-
- div = parent / rate;
- if (parent % rate)
- div++;
-
- if (div > 8)
- div = 16;
- else if (div > 4)
- div = 8;
- else if (div > 2)
- div = 4;
-
- return parent / div;
-}
-
-static int _clk_cko1_set_rate(struct clk *clk, unsigned long rate)
-{
- u32 reg, div, parent = clk_get_rate(clk->parent);
-
- div = parent / rate;
-
- if (div == 16)
- div = 4;
- else if (div == 8)
- div = 3;
- else if (div == 4)
- div = 2;
- else if (div == 2)
- div = 1;
- else if (div == 1)
- div = 0;
- else
- return -EINVAL;
-
- reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOUTDIV_MASK;
- reg |= div << MXC_CCM_COSR_CLKOUTDIV_OFFSET;
- __raw_writel(reg, MXC_CCM_COSR);
-
- return 0;
-}
-
-static unsigned long _clk_cko1_get_rate(struct clk *clk)
-{
- u32 div;
-
- div = __raw_readl(MXC_CCM_COSR) & MXC_CCM_COSR_CLKOUTDIV_MASK >>
- MXC_CCM_COSR_CLKOUTDIV_OFFSET;
-
- return clk_get_rate(clk->parent) / (1 << div);
-}
-
-static int _clk_cko1_set_parent(struct clk *clk, struct clk *parent)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOSEL_MASK;
-
- if (parent == &mcu_main_clk)
- reg |= 0 << MXC_CCM_COSR_CLKOSEL_OFFSET;
- else if (parent == &ipg_clk)
- reg |= 1 << MXC_CCM_COSR_CLKOSEL_OFFSET;
- else if (parent == &usb_pll_clk)
- reg |= 2 << MXC_CCM_COSR_CLKOSEL_OFFSET;
- else if (parent == mcu_main_clk.parent)
- reg |= 3 << MXC_CCM_COSR_CLKOSEL_OFFSET;
- else if (parent == &ahb_clk)
- reg |= 5 << MXC_CCM_COSR_CLKOSEL_OFFSET;
- else if (parent == &serial_pll_clk)
- reg |= 7 << MXC_CCM_COSR_CLKOSEL_OFFSET;
- else if (parent == &ckih_clk)
- reg |= 8 << MXC_CCM_COSR_CLKOSEL_OFFSET;
- else if (parent == &emi_clk)
- reg |= 9 << MXC_CCM_COSR_CLKOSEL_OFFSET;
- else if (parent == &ipu_clk)
- reg |= 0xA << MXC_CCM_COSR_CLKOSEL_OFFSET;
- else if (parent == &nfc_clk)
- reg |= 0xB << MXC_CCM_COSR_CLKOSEL_OFFSET;
- else if (parent == &uart_clk[0])
- reg |= 0xC << MXC_CCM_COSR_CLKOSEL_OFFSET;
- else
- return -EINVAL;
-
- __raw_writel(reg, MXC_CCM_COSR);
-
- return 0;
-}
-
-static int _clk_cko1_enable(struct clk *clk)
-{
- u32 reg;
-
- reg = __raw_readl(MXC_CCM_COSR) | MXC_CCM_COSR_CLKOEN;
- __raw_writel(reg, MXC_CCM_COSR);
+ .get_rate = ahb_get_rate,
+};
+
+#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = gr, \
+ .enable = cgr_enable, \
+ .disable = cgr_disable, \
+ .secondary = s, \
+ .parent = p, \
+ }
- return 0;
-}
+#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = getsetround##_get_rate, \
+ .set_rate = getsetround##_set_rate, \
+ .round_rate = getsetround##_round_rate, \
+ .enable = cgr_enable, \
+ .disable = cgr_disable, \
+ .secondary = s, \
+ .parent = p, \
+ }
-static void _clk_cko1_disable(struct clk *clk)
+DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
+
+DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CGR0, 4, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, &sdma_clk1, &ahb_clk);
+DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk);
+DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk);
+
+DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk);
+DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk);
+DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &ahb_clk);
+DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
+DEFINE_CLOCK(kpp_clk, 0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ipu_clk, 0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk);
+DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(owire_clk, 0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk);
+
+DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CGR2, 0, ssi2_get_rate, NULL, &serial_pll_clk);
+DEFINE_CLOCK(cspi1_clk, 0, MXC_CCM_CGR2, 2, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(cspi2_clk, 1, MXC_CCM_CGR2, 4, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(mbx_clk, 0, MXC_CCM_CGR2, 6, mbx_get_rate, NULL, &ahb_clk);
+DEFINE_CLOCK(emi_clk, 0, MXC_CCM_CGR2, 8, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(rtic_clk, 0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK1(firi_clk, 0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk);
+
+DEFINE_CLOCK(sdma_clk2, 0, NULL, 0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk);
+DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk);
+DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] __initdata = {
+ _REGISTER_CLOCK(NULL, "emi", emi_clk)
+ _REGISTER_CLOCK(NULL, "cspi", cspi1_clk)
+ _REGISTER_CLOCK(NULL, "cspi", cspi2_clk)
+ _REGISTER_CLOCK(NULL, "cspi", cspi3_clk)
+ _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
+ _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+ _REGISTER_CLOCK(NULL, "wdog", wdog_clk)
+ _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+ _REGISTER_CLOCK(NULL, "epit", epit1_clk)
+ _REGISTER_CLOCK(NULL, "epit", epit2_clk)
+ _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+ _REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
+ _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
+ _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
+ _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1)
+ _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2)
+ _REGISTER_CLOCK("mx3-camera.0", "csi", csi_clk)
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
+ _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
+ _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
+ _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
+ _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
+ _REGISTER_CLOCK(NULL, "ssi", ssi1_clk)
+ _REGISTER_CLOCK(NULL, "ssi", ssi2_clk)
+ _REGISTER_CLOCK(NULL, "firi", firi_clk)
+ _REGISTER_CLOCK(NULL, "ata", ata_clk)
+ _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
+ _REGISTER_CLOCK(NULL, "rng", rng_clk)
+ _REGISTER_CLOCK(NULL, "sdma_ahb", sdma_clk1)
+ _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2)
+ _REGISTER_CLOCK(NULL, "mstick", mstick1_clk)
+ _REGISTER_CLOCK(NULL, "mstick", mstick2_clk)
+ _REGISTER_CLOCK(NULL, "scc", scc_clk)
+ _REGISTER_CLOCK(NULL, "iim", iim_clk)
+ _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
+ _REGISTER_CLOCK(NULL, "mbx", mbx_clk)
+};
+
+int __init mx31_clocks_init(unsigned long fref)
{
u32 reg;
+ int i;
- reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOEN;
- __raw_writel(reg, MXC_CCM_COSR);
-}
-
-static struct clk cko1_clk = {
- .name = "cko1_clk",
- .get_rate = _clk_cko1_get_rate,
- .set_rate = _clk_cko1_set_rate,
- .round_rate = _clk_cko1_round_rate,
- .set_parent = _clk_cko1_set_parent,
- .enable = _clk_cko1_enable,
- .disable = _clk_cko1_disable,
-};
-
-static struct clk *mxc_clks[] = {
- &ckih_clk,
- &ckil_clk,
- &mcu_pll_clk,
- &usb_pll_clk,
- &serial_pll_clk,
- &mcu_main_clk,
- &ahb_clk,
- &per_clk,
- &perclk_clk,
- &cko1_clk,
- &emi_clk,
- &cspi_clk[0],
- &cspi_clk[1],
- &cspi_clk[2],
- &ipg_clk,
- &gpt_clk,
- &pwm_clk,
- &wdog_clk,
- &rtc_clk,
- &epit_clk[0],
- &epit_clk[1],
- &nfc_clk,
- &ipu_clk,
- &kpp_clk,
- &usb_clk[0],
- &usb_clk[1],
- &csi_clk,
- &uart_clk[0],
- &uart_clk[1],
- &uart_clk[2],
- &uart_clk[3],
- &uart_clk[4],
- &i2c_clk[0],
- &i2c_clk[1],
- &i2c_clk[2],
- &owire_clk,
- &sdhc_clk[0],
- &sdhc_clk[1],
- &ssi_clk[0],
- &ssi_clk[1],
- &firi_clk,
- &ata_clk,
- &rtic_clk,
- &rng_clk,
- &sdma_clk[0],
- &sdma_clk[1],
- &mstick_clk[0],
- &mstick_clk[1],
- &scc_clk,
- &iim_clk,
-};
-
-int __init mxc_clocks_init(unsigned long fref)
-{
- u32 reg;
- struct clk **clkp;
+ mxc_set_cpu_type(MXC_CPU_MX31);
ckih_rate = fref;
- for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
- clk_register(*clkp);
-
- if (cpu_is_mx31()) {
- clk_register(&mpeg4_clk);
- clk_register(&mbx_clk);
- } else {
- clk_register(&vpu_clk);
- clk_register(&vl2cc_clk);
- }
+ for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ clkdev_add(&lookups[i]);
/* Turn off all possible clocks */
- __raw_writel(MXC_CCM_CGR0_GPT_MASK, MXC_CCM_CGR0);
+ __raw_writel((3 << 4), MXC_CCM_CGR0);
__raw_writel(0, MXC_CCM_CGR1);
-
- __raw_writel(MXC_CCM_CGR2_EMI_MASK |
- MXC_CCM_CGR2_IPMUX1_MASK |
- MXC_CCM_CGR2_IPMUX2_MASK |
- MXC_CCM_CGR2_MXCCLKENSEL_MASK | /* for MX32 */
- MXC_CCM_CGR2_CHIKCAMPEN_MASK | /* for MX32 */
- MXC_CCM_CGR2_OVRVPUBUSY_MASK | /* for MX32 */
+ __raw_writel((3 << 8) | (3 << 14) | (3 << 16)|
1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for
MX32, but still required to be set */
MXC_CCM_CGR2);
- clk_disable(&cko1_clk);
- clk_disable(&usb_pll_clk);
+ usb_pll_disable(&usb_pll_clk);
pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk));
@@ -1143,6 +598,8 @@ int __init mxc_clocks_init(unsigned long fref)
__raw_writel(reg, MXC_CCM_PMCR1);
}
+ mxc_timer_init(&ipg_clk);
+
return 0;
}
diff --git a/arch/arm/mach-mx3/crm_regs.h b/arch/arm/mach-mx3/crm_regs.h
index 4a0e0ede23bb..adfa3627ad84 100644
--- a/arch/arm/mach-mx3/crm_regs.h
+++ b/arch/arm/mach-mx3/crm_regs.h
@@ -91,47 +91,6 @@
#define MXC_CCM_PDR0_MCU_PODF_OFFSET 0
#define MXC_CCM_PDR0_MCU_PODF_MASK 0x7
-#define MXC_CCM_PDR0_HSP_DIV_1 (0x0 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_2 (0x1 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_3 (0x2 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_4 (0x3 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_5 (0x4 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_6 (0x5 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_7 (0x6 << 11)
-#define MXC_CCM_PDR0_HSP_DIV_8 (0x7 << 11)
-
-#define MXC_CCM_PDR0_IPG_DIV_1 (0x0 << 6)
-#define MXC_CCM_PDR0_IPG_DIV_2 (0x1 << 6)
-#define MXC_CCM_PDR0_IPG_DIV_3 (0x2 << 6)
-#define MXC_CCM_PDR0_IPG_DIV_4 (0x3 << 6)
-
-#define MXC_CCM_PDR0_MAX_DIV_1 (0x0 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_2 (0x1 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_3 (0x2 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_4 (0x3 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_5 (0x4 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_6 (0x5 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_7 (0x6 << 3)
-#define MXC_CCM_PDR0_MAX_DIV_8 (0x7 << 3)
-
-#define MXC_CCM_PDR0_NFC_DIV_1 (0x0 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_2 (0x1 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_3 (0x2 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_4 (0x3 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_5 (0x4 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_6 (0x5 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_7 (0x6 << 8)
-#define MXC_CCM_PDR0_NFC_DIV_8 (0x7 << 8)
-
-#define MXC_CCM_PDR0_MCU_DIV_1 0x0
-#define MXC_CCM_PDR0_MCU_DIV_2 0x1
-#define MXC_CCM_PDR0_MCU_DIV_3 0x2
-#define MXC_CCM_PDR0_MCU_DIV_4 0x3
-#define MXC_CCM_PDR0_MCU_DIV_5 0x4
-#define MXC_CCM_PDR0_MCU_DIV_6 0x5
-#define MXC_CCM_PDR0_MCU_DIV_7 0x6
-#define MXC_CCM_PDR0_MCU_DIV_8 0x7
-
#define MXC_CCM_PDR1_USB_PRDF_OFFSET 30
#define MXC_CCM_PDR1_USB_PRDF_MASK (0x3 << 30)
#define MXC_CCM_PDR1_USB_PODF_OFFSET 27
@@ -152,118 +111,6 @@
/* Bit definitions for RCSR */
#define MXC_CCM_RCSR_NF16B 0x80000000
-/* Bit definitions for both MCU, USB and SR PLL control registers */
-#define MXC_CCM_PCTL_BRM 0x80000000
-#define MXC_CCM_PCTL_PD_OFFSET 26
-#define MXC_CCM_PCTL_PD_MASK (0xF << 26)
-#define MXC_CCM_PCTL_MFD_OFFSET 16
-#define MXC_CCM_PCTL_MFD_MASK (0x3FF << 16)
-#define MXC_CCM_PCTL_MFI_OFFSET 10
-#define MXC_CCM_PCTL_MFI_MASK (0xF << 10)
-#define MXC_CCM_PCTL_MFN_OFFSET 0
-#define MXC_CCM_PCTL_MFN_MASK 0x3FF
-
-#define MXC_CCM_CGR0_SD_MMC1_OFFSET 0
-#define MXC_CCM_CGR0_SD_MMC1_MASK (0x3 << 0)
-#define MXC_CCM_CGR0_SD_MMC2_OFFSET 2
-#define MXC_CCM_CGR0_SD_MMC2_MASK (0x3 << 2)
-#define MXC_CCM_CGR0_GPT_OFFSET 4
-#define MXC_CCM_CGR0_GPT_MASK (0x3 << 4)
-#define MXC_CCM_CGR0_EPIT1_OFFSET 6
-#define MXC_CCM_CGR0_EPIT1_MASK (0x3 << 6)
-#define MXC_CCM_CGR0_EPIT2_OFFSET 8
-#define MXC_CCM_CGR0_EPIT2_MASK (0x3 << 8)
-#define MXC_CCM_CGR0_IIM_OFFSET 10
-#define MXC_CCM_CGR0_IIM_MASK (0x3 << 10)
-#define MXC_CCM_CGR0_ATA_OFFSET 12
-#define MXC_CCM_CGR0_ATA_MASK (0x3 << 12)
-#define MXC_CCM_CGR0_SDMA_OFFSET 14
-#define MXC_CCM_CGR0_SDMA_MASK (0x3 << 14)
-#define MXC_CCM_CGR0_CSPI3_OFFSET 16
-#define MXC_CCM_CGR0_CSPI3_MASK (0x3 << 16)
-#define MXC_CCM_CGR0_RNG_OFFSET 18
-#define MXC_CCM_CGR0_RNG_MASK (0x3 << 18)
-#define MXC_CCM_CGR0_UART1_OFFSET 20
-#define MXC_CCM_CGR0_UART1_MASK (0x3 << 20)
-#define MXC_CCM_CGR0_UART2_OFFSET 22
-#define MXC_CCM_CGR0_UART2_MASK (0x3 << 22)
-#define MXC_CCM_CGR0_SSI1_OFFSET 24
-#define MXC_CCM_CGR0_SSI1_MASK (0x3 << 24)
-#define MXC_CCM_CGR0_I2C1_OFFSET 26
-#define MXC_CCM_CGR0_I2C1_MASK (0x3 << 26)
-#define MXC_CCM_CGR0_I2C2_OFFSET 28
-#define MXC_CCM_CGR0_I2C2_MASK (0x3 << 28)
-#define MXC_CCM_CGR0_I2C3_OFFSET 30
-#define MXC_CCM_CGR0_I2C3_MASK (0x3 << 30)
-
-#define MXC_CCM_CGR1_HANTRO_OFFSET 0
-#define MXC_CCM_CGR1_HANTRO_MASK (0x3 << 0)
-#define MXC_CCM_CGR1_MEMSTICK1_OFFSET 2
-#define MXC_CCM_CGR1_MEMSTICK1_MASK (0x3 << 2)
-#define MXC_CCM_CGR1_MEMSTICK2_OFFSET 4
-#define MXC_CCM_CGR1_MEMSTICK2_MASK (0x3 << 4)
-#define MXC_CCM_CGR1_CSI_OFFSET 6
-#define MXC_CCM_CGR1_CSI_MASK (0x3 << 6)
-#define MXC_CCM_CGR1_RTC_OFFSET 8
-#define MXC_CCM_CGR1_RTC_MASK (0x3 << 8)
-#define MXC_CCM_CGR1_WDOG_OFFSET 10
-#define MXC_CCM_CGR1_WDOG_MASK (0x3 << 10)
-#define MXC_CCM_CGR1_PWM_OFFSET 12
-#define MXC_CCM_CGR1_PWM_MASK (0x3 << 12)
-#define MXC_CCM_CGR1_SIM_OFFSET 14
-#define MXC_CCM_CGR1_SIM_MASK (0x3 << 14)
-#define MXC_CCM_CGR1_ECT_OFFSET 16
-#define MXC_CCM_CGR1_ECT_MASK (0x3 << 16)
-#define MXC_CCM_CGR1_USBOTG_OFFSET 18
-#define MXC_CCM_CGR1_USBOTG_MASK (0x3 << 18)
-#define MXC_CCM_CGR1_KPP_OFFSET 20
-#define MXC_CCM_CGR1_KPP_MASK (0x3 << 20)
-#define MXC_CCM_CGR1_IPU_OFFSET 22
-#define MXC_CCM_CGR1_IPU_MASK (0x3 << 22)
-#define MXC_CCM_CGR1_UART3_OFFSET 24
-#define MXC_CCM_CGR1_UART3_MASK (0x3 << 24)
-#define MXC_CCM_CGR1_UART4_OFFSET 26
-#define MXC_CCM_CGR1_UART4_MASK (0x3 << 26)
-#define MXC_CCM_CGR1_UART5_OFFSET 28
-#define MXC_CCM_CGR1_UART5_MASK (0x3 << 28)
-#define MXC_CCM_CGR1_OWIRE_OFFSET 30
-#define MXC_CCM_CGR1_OWIRE_MASK (0x3 << 30)
-
-#define MXC_CCM_CGR2_SSI2_OFFSET 0
-#define MXC_CCM_CGR2_SSI2_MASK (0x3 << 0)
-#define MXC_CCM_CGR2_CSPI1_OFFSET 2
-#define MXC_CCM_CGR2_CSPI1_MASK (0x3 << 2)
-#define MXC_CCM_CGR2_CSPI2_OFFSET 4
-#define MXC_CCM_CGR2_CSPI2_MASK (0x3 << 4)
-#define MXC_CCM_CGR2_GACC_OFFSET 6
-#define MXC_CCM_CGR2_GACC_MASK (0x3 << 6)
-#define MXC_CCM_CGR2_EMI_OFFSET 8
-#define MXC_CCM_CGR2_EMI_MASK (0x3 << 8)
-#define MXC_CCM_CGR2_RTIC_OFFSET 10
-#define MXC_CCM_CGR2_RTIC_MASK (0x3 << 10)
-#define MXC_CCM_CGR2_FIRI_OFFSET 12
-#define MXC_CCM_CGR2_FIRI_MASK (0x3 << 12)
-#define MXC_CCM_CGR2_IPMUX1_OFFSET 14
-#define MXC_CCM_CGR2_IPMUX1_MASK (0x3 << 14)
-#define MXC_CCM_CGR2_IPMUX2_OFFSET 16
-#define MXC_CCM_CGR2_IPMUX2_MASK (0x3 << 16)
-
-/* These new CGR2 bits are added in MX32 */
-#define MXC_CCM_CGR2_APMSYSCLKSEL_OFFSET 18
-#define MXC_CCM_CGR2_APMSYSCLKSEL_MASK (0x3 << 18)
-#define MXC_CCM_CGR2_APMSSICLKSEL_OFFSET 20
-#define MXC_CCM_CGR2_APMSSICLKSEL_MASK (0x3 << 20)
-#define MXC_CCM_CGR2_APMPERCLKSEL_OFFSET 22
-#define MXC_CCM_CGR2_APMPERCLKSEL_MASK (0x3 << 22)
-#define MXC_CCM_CGR2_MXCCLKENSEL_OFFSET 24
-#define MXC_CCM_CGR2_MXCCLKENSEL_MASK (0x1 << 24)
-#define MXC_CCM_CGR2_CHIKCAMPEN_OFFSET 25
-#define MXC_CCM_CGR2_CHIKCAMPEN_MASK (0x1 << 25)
-#define MXC_CCM_CGR2_OVRVPUBUSY_OFFSET 26
-#define MXC_CCM_CGR2_OVRVPUBUSY_MASK (0x1 << 26)
-#define MXC_CCM_CGR2_APMENA_OFFSET 30
-#define MXC_CCM_CGR2_AOMENA_MASK (0x1 << 30)
-
/*
* LTR0 register offsets
*/
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c
index f8428800f286..380be0c9b213 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -25,6 +25,8 @@
#include <mach/irqs.h>
#include <mach/imx-uart.h>
+#include "devices.h"
+
static struct resource uart0[] = {
{
.start = UART1_BASE_ADDR,
@@ -82,6 +84,7 @@ struct platform_device mxc_uart_device2 = {
.num_resources = ARRAY_SIZE(uart2),
};
+#ifdef CONFIG_ARCH_MX31
static struct resource uart3[] = {
{
.start = UART4_BASE_ADDR,
@@ -119,6 +122,7 @@ struct platform_device mxc_uart_device4 = {
.resource = uart4,
.num_resources = ARRAY_SIZE(uart4),
};
+#endif /* CONFIG_ARCH_MX31 */
/* GPIO port description */
static struct mxc_gpio_port imx_gpio_ports[] = {
@@ -164,8 +168,8 @@ struct platform_device mxc_w1_master_device = {
static struct resource mxc_nand_resources[] = {
{
- .start = NFC_BASE_ADDR,
- .end = NFC_BASE_ADDR + 0xfff,
+ .start = 0, /* runtime dependent */
+ .end = 0,
.flags = IORESOURCE_MEM
}, {
.start = MXC_INT_NANDFC,
@@ -180,3 +184,188 @@ struct platform_device mxc_nand_device = {
.num_resources = ARRAY_SIZE(mxc_nand_resources),
.resource = mxc_nand_resources,
};
+
+static struct resource mxc_i2c0_resources[] = {
+ {
+ .start = I2C_BASE_ADDR,
+ .end = I2C_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_I2C,
+ .end = MXC_INT_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_i2c_device0 = {
+ .name = "imx-i2c",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_i2c0_resources),
+ .resource = mxc_i2c0_resources,
+};
+
+static struct resource mxc_i2c1_resources[] = {
+ {
+ .start = I2C2_BASE_ADDR,
+ .end = I2C2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_I2C2,
+ .end = MXC_INT_I2C2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_i2c_device1 = {
+ .name = "imx-i2c",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(mxc_i2c1_resources),
+ .resource = mxc_i2c1_resources,
+};
+
+static struct resource mxc_i2c2_resources[] = {
+ {
+ .start = I2C3_BASE_ADDR,
+ .end = I2C3_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_I2C3,
+ .end = MXC_INT_I2C3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_i2c_device2 = {
+ .name = "imx-i2c",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(mxc_i2c2_resources),
+ .resource = mxc_i2c2_resources,
+};
+
+#ifdef CONFIG_ARCH_MX31
+static struct resource mxcsdhc0_resources[] = {
+ {
+ .start = MMC_SDHC1_BASE_ADDR,
+ .end = MMC_SDHC1_BASE_ADDR + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MXC_INT_MMC_SDHC1,
+ .end = MXC_INT_MMC_SDHC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource mxcsdhc1_resources[] = {
+ {
+ .start = MMC_SDHC2_BASE_ADDR,
+ .end = MMC_SDHC2_BASE_ADDR + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MXC_INT_MMC_SDHC2,
+ .end = MXC_INT_MMC_SDHC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxcsdhc_device0 = {
+ .name = "mxc-mmc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxcsdhc0_resources),
+ .resource = mxcsdhc0_resources,
+};
+
+struct platform_device mxcsdhc_device1 = {
+ .name = "mxc-mmc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(mxcsdhc1_resources),
+ .resource = mxcsdhc1_resources,
+};
+#endif /* CONFIG_ARCH_MX31 */
+
+/* i.MX31 Image Processing Unit */
+
+/* The resource order is important! */
+static struct resource mx3_ipu_rsrc[] = {
+ {
+ .start = IPU_CTRL_BASE_ADDR,
+ .end = IPU_CTRL_BASE_ADDR + 0x5F,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IPU_CTRL_BASE_ADDR + 0x88,
+ .end = IPU_CTRL_BASE_ADDR + 0xB3,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MXC_INT_IPU_SYN,
+ .end = MXC_INT_IPU_SYN,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = MXC_INT_IPU_ERR,
+ .end = MXC_INT_IPU_ERR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mx3_ipu = {
+ .name = "ipu-core",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mx3_ipu_rsrc),
+ .resource = mx3_ipu_rsrc,
+};
+
+static struct resource fb_resources[] = {
+ {
+ .start = IPU_CTRL_BASE_ADDR + 0xB4,
+ .end = IPU_CTRL_BASE_ADDR + 0x1BF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device mx3_fb = {
+ .name = "mx3_sdc_fb",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(fb_resources),
+ .resource = fb_resources,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+#ifdef CONFIG_ARCH_MX35
+static struct resource mxc_fec_resources[] = {
+ {
+ .start = MXC_FEC_BASE_ADDR,
+ .end = MXC_FEC_BASE_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM
+ }, {
+ .start = MXC_INT_FEC,
+ .end = MXC_INT_FEC,
+ .flags = IORESOURCE_IRQ
+ },
+};
+
+struct platform_device mxc_fec_device = {
+ .name = "fec",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_fec_resources),
+ .resource = mxc_fec_resources,
+};
+#endif
+
+static int mx3_devices_init(void)
+{
+ if (cpu_is_mx31()) {
+ mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR;
+ mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff;
+ }
+ if (cpu_is_mx35()) {
+ mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR;
+ mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0xfff;
+ }
+
+ return 0;
+}
+
+subsys_initcall(mx3_devices_init);
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h
index 9949ef4e0694..88c04b296fab 100644
--- a/arch/arm/mach-mx3/devices.h
+++ b/arch/arm/mach-mx3/devices.h
@@ -6,3 +6,11 @@ extern struct platform_device mxc_uart_device3;
extern struct platform_device mxc_uart_device4;
extern struct platform_device mxc_w1_master_device;
extern struct platform_device mxc_nand_device;
+extern struct platform_device mxc_i2c_device0;
+extern struct platform_device mxc_i2c_device1;
+extern struct platform_device mxc_i2c_device2;
+extern struct platform_device mx3_ipu;
+extern struct platform_device mx3_fb;
+extern struct platform_device mxc_fec_device;
+extern struct platform_device mxcsdhc_device0;
+extern struct platform_device mxcsdhc_device1;
diff --git a/arch/arm/mach-mx3/iomux.c b/arch/arm/mach-mx3/iomux.c
index 7a5088b519a8..40ffc5a664d9 100644
--- a/arch/arm/mach-mx3/iomux.c
+++ b/arch/arm/mach-mx3/iomux.c
@@ -1,6 +1,7 @@
/*
* Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -21,6 +22,7 @@
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/kernel.h>
#include <mach/hardware.h>
#include <mach/gpio.h>
#include <mach/iomux-mx3.h>
@@ -38,6 +40,8 @@
static DEFINE_SPINLOCK(gpio_mux_lock);
#define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3)
+
+unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
/*
* set the mode for a IOMUX pin.
*/
@@ -50,9 +54,6 @@ int mxc_iomux_mode(unsigned int pin_mode)
field = pin_mode & 0x3;
mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT;
- pr_debug("%s: reg offset = 0x%x field = %d mode = 0x%02x\n",
- __func__, (pin_mode & IOMUX_REG_MASK), field, mode);
-
spin_lock(&gpio_mux_lock);
l = __raw_readl(reg);
@@ -93,6 +94,86 @@ void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
EXPORT_SYMBOL(mxc_iomux_set_pad);
/*
+ * setups a single pin:
+ * - reserves the pin so that it is not claimed by another driver
+ * - setups the iomux according to the configuration
+ * - if the pin is configured as a GPIO, we claim it through kernel gpiolib
+ */
+int mxc_iomux_setup_pin(const unsigned int pin, const char *label)
+{
+ unsigned pad = pin & IOMUX_PADNUM_MASK;
+ unsigned gpio;
+
+ if (pad >= (PIN_MAX + 1)) {
+ printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n",
+ pad, label ? label : "?");
+ return -EINVAL;
+ }
+
+ if (test_and_set_bit(pad, mxc_pin_alloc_map)) {
+ printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n",
+ pad, label ? label : "?");
+ return -EINVAL;
+ }
+ mxc_iomux_mode(pin);
+
+ /* if we have a gpio, we can allocate it */
+ gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT;
+ if (gpio < (GPIO_PORT_MAX + 1) * 32)
+ if (gpio_request(gpio, label))
+ return -EINVAL;
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_setup_pin);
+
+int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
+ const char *label)
+{
+ unsigned int *p = pin_list;
+ int i;
+ int ret = -EINVAL;
+
+ for (i = 0; i < count; i++) {
+ if (mxc_iomux_setup_pin(*p, label))
+ goto setup_error;
+ p++;
+ }
+ return 0;
+
+setup_error:
+ mxc_iomux_release_multiple_pins(pin_list, i);
+ return ret;
+}
+EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins);
+
+void mxc_iomux_release_pin(const unsigned int pin)
+{
+ unsigned pad = pin & IOMUX_PADNUM_MASK;
+ unsigned gpio;
+
+ if (pad < (PIN_MAX + 1))
+ clear_bit(pad, mxc_pin_alloc_map);
+
+ gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT;
+ if (gpio < (GPIO_PORT_MAX + 1) * 32)
+ gpio_free(gpio);
+}
+EXPORT_SYMBOL(mxc_iomux_release_pin);
+
+void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count)
+{
+ unsigned int *p = pin_list;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ mxc_iomux_release_pin(*p);
+ p++;
+ }
+}
+EXPORT_SYMBOL(mxc_iomux_release_multiple_pins);
+
+/*
* This function enables/disables the general purpose function for a particular
* signal.
*/
@@ -111,4 +192,3 @@ void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en)
spin_unlock(&gpio_mux_lock);
}
EXPORT_SYMBOL(mxc_iomux_set_gpr);
-
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c
index 0589b5cd33c7..9e1459cb4b74 100644
--- a/arch/arm/mach-mx3/mm.c
+++ b/arch/arm/mach-mx3/mm.c
@@ -22,10 +22,14 @@
#include <linux/mm.h>
#include <linux/init.h>
-#include <mach/hardware.h>
+#include <linux/err.h>
+
#include <asm/pgtable.h>
#include <asm/mach/map.h>
+#include <asm/hardware/cache-l2x0.h>
+
#include <mach/common.h>
+#include <mach/hardware.h>
/*!
* @file mm.c
@@ -50,6 +54,16 @@ static struct map_desc mxc_io_desc[] __initdata = {
.pfn = __phys_to_pfn(AVIC_BASE_ADDR),
.length = AVIC_SIZE,
.type = MT_DEVICE_NONSHARED
+ }, {
+ .virtual = AIPS1_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
+ .length = AIPS1_SIZE,
+ .type = MT_DEVICE_NONSHARED
+ }, {
+ .virtual = AIPS2_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
+ .length = AIPS2_SIZE,
+ .type = MT_DEVICE_NONSHARED
},
};
@@ -62,3 +76,24 @@ void __init mxc_map_io(void)
{
iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
}
+
+#ifdef CONFIG_CACHE_L2X0
+static int mxc_init_l2x0(void)
+{
+ void __iomem *l2x0_base;
+
+ l2x0_base = ioremap(L2CC_BASE_ADDR, 4096);
+ if (IS_ERR(l2x0_base)) {
+ printk(KERN_ERR "remapping L2 cache area failed with %ld\n",
+ PTR_ERR(l2x0_base));
+ return 0;
+ }
+
+ l2x0_init(l2x0_base, 0x00030024, 0x00000000);
+
+ return 0;
+}
+
+arch_initcall(mxc_init_l2x0);
+#endif
+
diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c
index f902a7c37c31..83e5e8e1276f 100644
--- a/arch/arm/mach-mx3/mx31ads.c
+++ b/arch/arm/mach-mx3/mx31ads.c
@@ -22,6 +22,8 @@
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/serial_8250.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
#include <linux/irq.h>
#include <mach/hardware.h>
@@ -35,6 +37,12 @@
#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+#include <linux/mfd/wm8350/audio.h>
+#include <linux/mfd/wm8350/core.h>
+#include <linux/mfd/wm8350/pmic.h>
+#endif
+
#include "devices.h"
/*!
@@ -94,13 +102,16 @@ static struct imxuart_platform_data uart_pdata = {
.flags = IMXUART_HAVE_RTSCTS,
};
+static int uart_pins[] = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1
+};
+
static inline void mxc_init_imx_uart(void)
{
- mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
- mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
- mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
- mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
-
+ mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0");
mxc_register_device(&mxc_uart_device0, &uart_pdata);
}
#else /* !SERIAL_IMX */
@@ -176,7 +187,7 @@ static void __init mx31ads_init_expio(void)
/*
* Configure INT line as GPIO input
*/
- mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO));
+ mxc_iomux_setup_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio");
/* disable the interrupt and clear the status */
__raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG);
@@ -191,26 +202,301 @@ static void __init mx31ads_init_expio(void)
set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler);
}
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+/* This section defines setup for the Wolfson Microelectronics
+ * 1133-EV1 PMU/audio board. When other PMU boards are supported the
+ * regulator definitions may be shared with them, but for now they can
+ * only be used with this board so would generate warnings about
+ * unused statics and some of the configuration is specific to this
+ * module.
+ */
+
+/* CPU */
+static struct regulator_consumer_supply sw1a_consumers[] = {
+ {
+ .supply = "cpu_vcc",
+ }
+};
+
+static struct regulator_init_data sw1a_data = {
+ .constraints = {
+ .name = "SW1A",
+ .min_uV = 1275000,
+ .max_uV = 1600000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_FAST,
+ .state_mem = {
+ .uV = 1400000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .initial_state = PM_SUSPEND_MEM,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1a_consumers),
+ .consumer_supplies = sw1a_consumers,
+};
+
+/* System IO - High */
+static struct regulator_init_data viohi_data = {
+ .constraints = {
+ .name = "VIOHO",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .state_mem = {
+ .uV = 2800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .initial_state = PM_SUSPEND_MEM,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+/* System IO - Low */
+static struct regulator_init_data violo_data = {
+ .constraints = {
+ .name = "VIOLO",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .state_mem = {
+ .uV = 1800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .initial_state = PM_SUSPEND_MEM,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+/* DDR RAM */
+static struct regulator_init_data sw2a_data = {
+ .constraints = {
+ .name = "SW2A",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .state_mem = {
+ .uV = 1800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .state_disk = {
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 0,
+ },
+ .always_on = 1,
+ .boot_on = 1,
+ .initial_state = PM_SUSPEND_MEM,
+ },
+};
+
+static struct regulator_init_data ldo1_data = {
+ .constraints = {
+ .name = "VCAM/VMMC1/VMMC2",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_consumer_supply ldo2_consumers[] = {
+ {
+ .supply = "AVDD",
+ },
+ {
+ .supply = "HPVDD",
+ },
+};
+
+/* CODEC and SIM */
+static struct regulator_init_data ldo2_data = {
+ .constraints = {
+ .name = "VESIM/VSIM/AVDD",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo2_consumers),
+ .consumer_supplies = ldo2_consumers,
+};
+
+/* General */
+static struct regulator_init_data vdig_data = {
+ .constraints = {
+ .name = "VDIG",
+ .min_uV = 1500000,
+ .max_uV = 1500000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+/* Tranceivers */
+static struct regulator_init_data ldo4_data = {
+ .constraints = {
+ .name = "VRF1/CVDD_2.775",
+ .min_uV = 2500000,
+ .max_uV = 2500000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct wm8350_led_platform_data wm8350_led_data = {
+ .name = "wm8350:white",
+ .default_trigger = "heartbeat",
+ .max_uA = 27899,
+};
+
+static struct wm8350_audio_platform_data imx32ads_wm8350_setup = {
+ .vmid_discharge_msecs = 1000,
+ .drain_msecs = 30,
+ .cap_discharge_msecs = 700,
+ .vmid_charge_msecs = 700,
+ .vmid_s_curve = WM8350_S_CURVE_SLOW,
+ .dis_out4 = WM8350_DISCHARGE_SLOW,
+ .dis_out3 = WM8350_DISCHARGE_SLOW,
+ .dis_out2 = WM8350_DISCHARGE_SLOW,
+ .dis_out1 = WM8350_DISCHARGE_SLOW,
+ .vroi_out4 = WM8350_TIE_OFF_500R,
+ .vroi_out3 = WM8350_TIE_OFF_500R,
+ .vroi_out2 = WM8350_TIE_OFF_500R,
+ .vroi_out1 = WM8350_TIE_OFF_500R,
+ .vroi_enable = 0,
+ .codec_current_on = WM8350_CODEC_ISEL_1_0,
+ .codec_current_standby = WM8350_CODEC_ISEL_0_5,
+ .codec_current_charge = WM8350_CODEC_ISEL_1_5,
+};
+
+static int mx31_wm8350_init(struct wm8350 *wm8350)
+{
+ int i;
+
+ wm8350_gpio_config(wm8350, 0, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO0_PWR_ON_IN, WM8350_GPIO_ACTIVE_LOW,
+ WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_ON);
+
+ wm8350_gpio_config(wm8350, 3, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO3_PWR_OFF_IN, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_ON);
+
+ wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO7_HIBERNATE_IN, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_gpio_config(wm8350, 6, WM8350_GPIO_DIR_OUT,
+ WM8350_GPIO6_SDOUT_OUT, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_gpio_config(wm8350, 8, WM8350_GPIO_DIR_OUT,
+ WM8350_GPIO8_VCC_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
+ WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_gpio_config(wm8350, 9, WM8350_GPIO_DIR_OUT,
+ WM8350_GPIO9_BATT_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
+ WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ /* Fix up for our own supplies. */
+ for (i = 0; i < ARRAY_SIZE(ldo2_consumers); i++)
+ ldo2_consumers[i].dev = wm8350->dev;
+
+ wm8350_register_regulator(wm8350, WM8350_DCDC_1, &sw1a_data);
+ wm8350_register_regulator(wm8350, WM8350_DCDC_3, &viohi_data);
+ wm8350_register_regulator(wm8350, WM8350_DCDC_4, &violo_data);
+ wm8350_register_regulator(wm8350, WM8350_DCDC_6, &sw2a_data);
+ wm8350_register_regulator(wm8350, WM8350_LDO_1, &ldo1_data);
+ wm8350_register_regulator(wm8350, WM8350_LDO_2, &ldo2_data);
+ wm8350_register_regulator(wm8350, WM8350_LDO_3, &vdig_data);
+ wm8350_register_regulator(wm8350, WM8350_LDO_4, &ldo4_data);
+
+ /* LEDs */
+ wm8350_dcdc_set_slot(wm8350, WM8350_DCDC_5, 1, 1,
+ WM8350_DC5_ERRACT_SHUTDOWN_CONV);
+ wm8350_isink_set_flash(wm8350, WM8350_ISINK_A,
+ WM8350_ISINK_FLASH_DISABLE,
+ WM8350_ISINK_FLASH_TRIG_BIT,
+ WM8350_ISINK_FLASH_DUR_32MS,
+ WM8350_ISINK_FLASH_ON_INSTANT,
+ WM8350_ISINK_FLASH_OFF_INSTANT,
+ WM8350_ISINK_FLASH_MODE_EN);
+ wm8350_dcdc25_set_mode(wm8350, WM8350_DCDC_5,
+ WM8350_ISINK_MODE_BOOST,
+ WM8350_ISINK_ILIM_NORMAL,
+ WM8350_DC5_RMP_20V,
+ WM8350_DC5_FBSRC_ISINKA);
+ wm8350_register_led(wm8350, 0, WM8350_DCDC_5, WM8350_ISINK_A,
+ &wm8350_led_data);
+
+ wm8350->codec.platform_data = &imx32ads_wm8350_setup;
+
+ return 0;
+}
+
+static struct wm8350_platform_data __initdata mx31_wm8350_pdata = {
+ .init = mx31_wm8350_init,
+};
+#endif
+
+#if defined(CONFIG_I2C_IMX) || defined(CONFIG_I2C_IMX_MODULE)
+static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = {
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+ {
+ I2C_BOARD_INFO("wm8350", 0x1a),
+ .platform_data = &mx31_wm8350_pdata,
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+ },
+#endif
+};
+
+static void mxc_init_i2c(void)
+{
+ i2c_register_board_info(1, mx31ads_i2c1_devices,
+ ARRAY_SIZE(mx31ads_i2c1_devices));
+
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1));
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1));
+
+ mxc_register_device(&mxc_i2c_device1, NULL);
+}
+#else
+static void mxc_init_i2c(void)
+{
+}
+#endif
+
/*!
* This structure defines static mappings for the i.MX31ADS board.
*/
static struct map_desc mx31ads_io_desc[] __initdata = {
{
- .virtual = AIPS1_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
- .length = AIPS1_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
.virtual = SPBA0_BASE_ADDR_VIRT,
.pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
.length = SPBA0_SIZE,
.type = MT_DEVICE_NONSHARED
}, {
- .virtual = AIPS2_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
- .length = AIPS2_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
.virtual = CS4_BASE_ADDR_VIRT,
.pfn = __phys_to_pfn(CS4_BASE_ADDR),
.length = CS4_SIZE / 2,
@@ -221,13 +507,13 @@ static struct map_desc mx31ads_io_desc[] __initdata = {
/*!
* Set up static virtual mappings.
*/
-void __init mx31ads_map_io(void)
+static void __init mx31ads_map_io(void)
{
mxc_map_io();
iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
}
-void __init mx31ads_init_irq(void)
+static void __init mx31ads_init_irq(void)
{
mxc_init_irq();
mx31ads_init_expio();
@@ -240,15 +526,15 @@ static void __init mxc_board_init(void)
{
mxc_init_extuart();
mxc_init_imx_uart();
+ mxc_init_i2c();
}
static void __init mx31ads_timer_init(void)
{
- mxc_clocks_init(26000000);
- mxc_timer_init("ipg_clk.0");
+ mx31_clocks_init(26000000);
}
-struct sys_timer mx31ads_timer = {
+static struct sys_timer mx31ads_timer = {
.init = mx31ads_timer_init,
};
diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c
index c43440070143..894d98cd9941 100644
--- a/arch/arm/mach-mx3/mx31lite.c
+++ b/arch/arm/mach-mx3/mx31lite.c
@@ -42,21 +42,11 @@
*/
static struct map_desc mx31lite_io_desc[] __initdata = {
{
- .virtual = AIPS1_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
- .length = AIPS1_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
.virtual = SPBA0_BASE_ADDR_VIRT,
.pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
.length = SPBA0_SIZE,
.type = MT_DEVICE_NONSHARED
}, {
- .virtual = AIPS2_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
- .length = AIPS2_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
.virtual = CS4_BASE_ADDR_VIRT,
.pfn = __phys_to_pfn(CS4_BASE_ADDR),
.length = CS4_SIZE,
@@ -82,8 +72,7 @@ static void __init mxc_board_init(void)
static void __init mx31lite_timer_init(void)
{
- mxc_clocks_init(26000000);
- mxc_timer_init("ipg_clk.0");
+ mx31_clocks_init(26000000);
}
struct sys_timer mx31lite_timer = {
diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c
new file mode 100644
index 000000000000..d080b4add79c
--- /dev/null
+++ b/arch/arm/mach-mx3/mx31moboard-devboard.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+
+#include "devices.h"
+
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static int mxc_uart1_pins[] = {
+ MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2,
+ MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2,
+};
+
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_devboard_init(void)
+{
+ printk(KERN_INFO "Initializing mx31devboard peripherals\n");
+ mxc_iomux_setup_multiple_pins(mxc_uart1_pins, ARRAY_SIZE(mxc_uart1_pins), "uart1");
+ mxc_register_device(&mxc_uart_device1, &uart_pdata);
+}
diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c
new file mode 100644
index 000000000000..9ef9566823fb
--- /dev/null
+++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+
+#include "devices.h"
+
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_marxbot_init(void)
+{
+ printk(KERN_INFO "Initializing mx31marxbot peripherals\n");
+}
diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c
index c29098af7394..34c2a1b99d4f 100644
--- a/arch/arm/mach-mx3/mx31moboard.c
+++ b/arch/arm/mach-mx3/mx31moboard.c
@@ -32,6 +32,7 @@
#include <mach/common.h>
#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
+#include <mach/board-mx31moboard.h>
#include "devices.h"
@@ -63,6 +64,18 @@ static struct platform_device *devices[] __initdata = {
&mx31moboard_flash,
};
+static int mxc_uart0_pins[] = {
+ MX31_PIN_CTS1__CTS1, MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1,
+};
+static int mxc_uart4_pins[] = {
+ MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5,
+ MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5,
+};
+
+static int mx31moboard_baseboard;
+core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
+
/*
* Board specific initialization.
*/
@@ -70,58 +83,29 @@ static void __init mxc_board_init(void)
{
platform_add_devices(devices, ARRAY_SIZE(devices));
- mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
- mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
- mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
- mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
-
+ mxc_iomux_setup_multiple_pins(mxc_uart0_pins, ARRAY_SIZE(mxc_uart0_pins), "uart0");
mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mxc_iomux_mode(MX31_PIN_CTS2__CTS2);
- mxc_iomux_mode(MX31_PIN_RTS2__RTS2);
- mxc_iomux_mode(MX31_PIN_TXD2__TXD2);
- mxc_iomux_mode(MX31_PIN_RXD2__RXD2);
-
- mxc_register_device(&mxc_uart_device1, &uart_pdata);
-
- mxc_iomux_mode(MX31_PIN_PC_RST__CTS5);
- mxc_iomux_mode(MX31_PIN_PC_VS2__RTS5);
- mxc_iomux_mode(MX31_PIN_PC_BVD2__TXD5);
- mxc_iomux_mode(MX31_PIN_PC_BVD1__RXD5);
-
+ mxc_iomux_setup_multiple_pins(mxc_uart4_pins, ARRAY_SIZE(mxc_uart4_pins), "uart4");
mxc_register_device(&mxc_uart_device4, &uart_pdata);
-}
-/*
- * This structure defines static mappings for the mx31moboard.
- */
-static struct map_desc mx31moboard_io_desc[] __initdata = {
- {
- .virtual = AIPS1_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
- .length = AIPS1_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
- .virtual = AIPS2_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
- .length = AIPS2_SIZE,
- .type = MT_DEVICE_NONSHARED
- },
-};
-
-/*
- * Set up static virtual mappings.
- */
-void __init mx31moboard_map_io(void)
-{
- mxc_map_io();
- iotable_init(mx31moboard_io_desc, ARRAY_SIZE(mx31moboard_io_desc));
+ switch (mx31moboard_baseboard) {
+ case MX31NOBOARD:
+ break;
+ case MX31DEVBOARD:
+ mx31moboard_devboard_init();
+ break;
+ case MX31MARXBOT:
+ mx31moboard_marxbot_init();
+ break;
+ default:
+ printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n", mx31moboard_baseboard);
+ }
}
static void __init mx31moboard_timer_init(void)
{
- mxc_clocks_init(26000000);
- mxc_timer_init("ipg_clk.0");
+ mx31_clocks_init(26000000);
}
struct sys_timer mx31moboard_timer = {
@@ -133,7 +117,7 @@ MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
.phys_io = AIPS1_BASE_ADDR,
.io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx31moboard_map_io,
+ .map_io = mxc_map_io,
.init_irq = mxc_init_irq,
.init_machine = mxc_board_init,
.timer = &mx31moboard_timer,
diff --git a/arch/arm/mach-mx3/mx31pdk.c b/arch/arm/mach-mx3/mx31pdk.c
index d464d068a4a6..bc63f1785691 100644
--- a/arch/arm/mach-mx3/mx31pdk.c
+++ b/arch/arm/mach-mx3/mx31pdk.c
@@ -45,40 +45,17 @@ static struct imxuart_platform_data uart_pdata = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static inline void mxc_init_imx_uart(void)
-{
- mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
- mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
- mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
- mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
-
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
-}
-
-/*!
- * This structure defines static mappings for the i.MX31PDK board.
- */
-static struct map_desc mx31pdk_io_desc[] __initdata = {
- {
- .virtual = AIPS1_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
- .length = AIPS1_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
- .virtual = AIPS2_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
- .length = AIPS2_SIZE,
- .type = MT_DEVICE_NONSHARED
- },
+static int uart_pins[] = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1
};
-/*!
- * Set up static virtual mappings.
- */
-static void __init mx31pdk_map_io(void)
+static inline void mxc_init_imx_uart(void)
{
- mxc_map_io();
- iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc));
+ mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0");
+ mxc_register_device(&mxc_uart_device0, &uart_pdata);
}
/*!
@@ -91,8 +68,7 @@ static void __init mxc_board_init(void)
static void __init mx31pdk_timer_init(void)
{
- mxc_clocks_init(26000000);
- mxc_timer_init("ipg_clk.0");
+ mx31_clocks_init(26000000);
}
static struct sys_timer mx31pdk_timer = {
@@ -108,7 +84,7 @@ MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
.phys_io = AIPS1_BASE_ADDR,
.io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx31pdk_map_io,
+ .map_io = mxc_map_io,
.init_irq = mxc_init_irq,
.init_machine = mxc_board_init,
.timer = &mx31pdk_timer,
diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c
index 8cea82587222..c3648eff5137 100644
--- a/arch/arm/mach-mx3/pcm037.c
+++ b/arch/arm/mach-mx3/pcm037.c
@@ -24,8 +24,10 @@
#include <linux/mtd/plat-ram.h>
#include <linux/memory.h>
#include <linux/gpio.h>
-#include <linux/smc911x.h>
+#include <linux/smsc911x.h>
#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -37,6 +39,10 @@
#include <mach/iomux-mx3.h>
#include <mach/board-pcm037.h>
#include <mach/mxc_nand.h>
+#include <mach/mmc.h>
+#ifdef CONFIG_I2C_IMX
+#include <mach/i2c.h>
+#endif
#include "devices.h"
@@ -64,7 +70,7 @@ static struct imxuart_platform_data uart_pdata = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct resource smc911x_resources[] = {
+static struct resource smsc911x_resources[] = {
[0] = {
.start = CS1_BASE_ADDR + 0x300,
.end = CS1_BASE_ADDR + 0x300 + SZ_64K - 1,
@@ -73,22 +79,25 @@ static struct resource smc911x_resources[] = {
[1] = {
.start = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
.end = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
- .flags = IORESOURCE_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
},
};
-static struct smc911x_platdata smc911x_info = {
- .flags = SMC911X_USE_32BIT,
- .irq_flags = IRQF_SHARED | IRQF_TRIGGER_LOW,
+static struct smsc911x_platform_config smsc911x_info = {
+ .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY |
+ SMSC911X_SAVE_MAC_ADDRESS,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
};
static struct platform_device pcm037_eth = {
- .name = "smc911x",
+ .name = "smsc911x",
.id = -1,
- .num_resources = ARRAY_SIZE(smc911x_resources),
- .resource = smc911x_resources,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
.dev = {
- .platform_data = &smc911x_info,
+ .platform_data = &smsc911x_info,
},
};
@@ -117,12 +126,90 @@ static struct mxc_nand_platform_data pcm037_nand_board_info = {
.hw_ecc = 1,
};
+#ifdef CONFIG_I2C_IMX
+static int i2c_1_pins[] = {
+ MX31_PIN_CSPI2_MOSI__SCL,
+ MX31_PIN_CSPI2_MISO__SDA,
+};
+
+static int pcm037_i2c_1_init(struct device *dev)
+{
+ return mxc_iomux_setup_multiple_pins(i2c_1_pins, ARRAY_SIZE(i2c_1_pins),
+ "i2c-1");
+}
+
+static void pcm037_i2c_1_exit(struct device *dev)
+{
+ mxc_iomux_release_multiple_pins(i2c_1_pins, ARRAY_SIZE(i2c_1_pins));
+}
+
+static struct imxi2c_platform_data pcm037_i2c_1_data = {
+ .bitrate = 100000,
+ .init = pcm037_i2c_1_init,
+ .exit = pcm037_i2c_1_exit,
+};
+
+static struct at24_platform_data board_eeprom = {
+ .byte_len = 4096,
+ .page_size = 32,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pcm037_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+ .platform_data = &board_eeprom,
+ }, {
+ I2C_BOARD_INFO("rtc-pcf8563", 0x51),
+ .type = "pcf8563",
+ }
+};
+#endif
+
+static int sdhc1_pins[] = {
+ MX31_PIN_SD1_DATA3__SD1_DATA3,
+ MX31_PIN_SD1_DATA2__SD1_DATA2,
+ MX31_PIN_SD1_DATA1__SD1_DATA1,
+ MX31_PIN_SD1_DATA0__SD1_DATA0,
+ MX31_PIN_SD1_CLK__SD1_CLK,
+ MX31_PIN_SD1_CMD__SD1_CMD,
+};
+
+static int pcm970_sdhc1_init(struct device *dev, irq_handler_t h, void *data)
+{
+ return mxc_iomux_setup_multiple_pins(sdhc1_pins, ARRAY_SIZE(sdhc1_pins),
+ "sdhc-1");
+}
+
+static void pcm970_sdhc1_exit(struct device *dev, void *data)
+{
+ mxc_iomux_release_multiple_pins(sdhc1_pins, ARRAY_SIZE(sdhc1_pins));
+}
+
+/* No card and rw detection at the moment */
+static struct imxmmc_platform_data sdhc_pdata = {
+ .init = pcm970_sdhc1_init,
+ .exit = pcm970_sdhc1_exit,
+};
+
static struct platform_device *devices[] __initdata = {
&pcm037_flash,
&pcm037_eth,
&pcm037_sram_device,
};
+static int uart0_pins[] = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1
+};
+
+static int uart2_pins[] = {
+ MX31_PIN_CSPI3_MOSI__RXD3,
+ MX31_PIN_CSPI3_MISO__TXD3
+};
+
/*
* Board specific initialization.
*/
@@ -130,59 +217,33 @@ static void __init mxc_board_init(void)
{
platform_add_devices(devices, ARRAY_SIZE(devices));
- mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
- mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
- mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
- mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
-
+ mxc_iomux_setup_multiple_pins(uart0_pins, ARRAY_SIZE(uart0_pins), "uart-0");
mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mxc_iomux_mode(MX31_PIN_CSPI3_MOSI__RXD3);
- mxc_iomux_mode(MX31_PIN_CSPI3_MISO__TXD3);
-
+ mxc_iomux_setup_multiple_pins(uart2_pins, ARRAY_SIZE(uart2_pins), "uart-2");
mxc_register_device(&mxc_uart_device2, &uart_pdata);
- mxc_iomux_mode(MX31_PIN_BATT_LINE__OWIRE);
+ mxc_iomux_setup_pin(MX31_PIN_BATT_LINE__OWIRE, "batt-0wire");
mxc_register_device(&mxc_w1_master_device, NULL);
/* SMSC9215 IRQ pin */
- mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO));
- if (!gpio_request(MX31_PIN_GPIO3_1, "pcm037-eth"))
+ if (!mxc_iomux_setup_pin(IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO),
+ "pcm037-eth"))
gpio_direction_input(MX31_PIN_GPIO3_1);
- mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
-}
+#ifdef CONFIG_I2C_IMX
+ i2c_register_board_info(1, pcm037_i2c_devices,
+ ARRAY_SIZE(pcm037_i2c_devices));
-/*
- * This structure defines static mappings for the pcm037 board.
- */
-static struct map_desc pcm037_io_desc[] __initdata = {
- {
- .virtual = AIPS1_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
- .length = AIPS1_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
- .virtual = AIPS2_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
- .length = AIPS2_SIZE,
- .type = MT_DEVICE_NONSHARED
- },
-};
-
-/*
- * Set up static virtual mappings.
- */
-void __init pcm037_map_io(void)
-{
- mxc_map_io();
- iotable_init(pcm037_io_desc, ARRAY_SIZE(pcm037_io_desc));
+ mxc_register_device(&mxc_i2c_device1, &pcm037_i2c_1_data);
+#endif
+ mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
+ mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
}
static void __init pcm037_timer_init(void)
{
- mxc_clocks_init(26000000);
- mxc_timer_init("ipg_clk.0");
+ mx31_clocks_init(26000000);
}
struct sys_timer pcm037_timer = {
@@ -194,7 +255,7 @@ MACHINE_START(PCM037, "Phytec Phycore pcm037")
.phys_io = AIPS1_BASE_ADDR,
.io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
.boot_params = PHYS_OFFSET + 0x100,
- .map_io = pcm037_map_io,
+ .map_io = mxc_map_io,
.init_irq = mxc_init_irq,
.init_machine = mxc_board_init,
.timer = &pcm037_timer,
diff --git a/arch/arm/mach-mx3/qong.c b/arch/arm/mach-mx3/qong.c
new file mode 100644
index 000000000000..6c4283cec6f4
--- /dev/null
+++ b/arch/arm/mach-mx3/qong.c
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <mach/board-qong.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx3.h>
+#include "devices.h"
+
+/* FPGA defines */
+#define QONG_FPGA_VERSION(major, minor, rev) \
+ (((major & 0xF) << 12) | ((minor & 0xF) << 8) | (rev & 0xFF))
+
+#define QONG_FPGA_BASEADDR CS1_BASE_ADDR
+#define QONG_FPGA_PERIPH_SIZE (1 << 24)
+
+#define QONG_FPGA_CTRL_BASEADDR QONG_FPGA_BASEADDR
+#define QONG_FPGA_CTRL_SIZE 0x10
+/* FPGA control registers */
+#define QONG_FPGA_CTRL_VERSION 0x00
+
+#define QONG_DNET_ID 1
+#define QONG_DNET_BASEADDR \
+ (QONG_FPGA_BASEADDR + QONG_DNET_ID * QONG_FPGA_PERIPH_SIZE)
+#define QONG_DNET_SIZE 0x00001000
+
+#define QONG_FPGA_IRQ IOMUX_TO_IRQ(MX31_PIN_DTR_DCE1)
+
+/*
+ * This file contains the board-specific initialization routines.
+ */
+
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static int uart_pins[] = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1
+};
+
+static inline void mxc_init_imx_uart(void)
+{
+ mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins),
+ "uart-0");
+ mxc_register_device(&mxc_uart_device0, &uart_pdata);
+}
+
+static struct resource dnet_resources[] = {
+ [0] = {
+ .name = "dnet-memory",
+ .start = QONG_DNET_BASEADDR,
+ .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = QONG_FPGA_IRQ,
+ .end = QONG_FPGA_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dnet_device = {
+ .name = "dnet",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dnet_resources),
+ .resource = dnet_resources,
+};
+
+static int __init qong_init_dnet(void)
+{
+ int ret;
+
+ ret = platform_device_register(&dnet_device);
+ return ret;
+}
+
+/* MTD NOR flash */
+
+static struct physmap_flash_data qong_flash_data = {
+ .width = 2,
+};
+
+static struct resource qong_flash_resource = {
+ .start = CS0_BASE_ADDR,
+ .end = CS0_BASE_ADDR + QONG_NOR_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device qong_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &qong_flash_data,
+ },
+ .resource = &qong_flash_resource,
+ .num_resources = 1,
+};
+
+static void qong_init_nor_mtd(void)
+{
+ (void)platform_device_register(&qong_nor_mtd_device);
+}
+
+/*
+ * Hardware specific access to control-lines
+ */
+static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ if (ctrl & NAND_CLE)
+ writeb(cmd, nand_chip->IO_ADDR_W + (1 << 24));
+ else
+ writeb(cmd, nand_chip->IO_ADDR_W + (1 << 23));
+}
+
+/*
+ * Read the Device Ready pin.
+ */
+static int qong_nand_device_ready(struct mtd_info *mtd)
+{
+ return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB));
+}
+
+static void qong_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+ if (chip >= 0)
+ gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
+ else
+ gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1);
+}
+
+static struct platform_nand_data qong_nand_data = {
+ .chip = {
+ .chip_delay = 20,
+ .options = 0,
+ },
+ .ctrl = {
+ .cmd_ctrl = qong_nand_cmd_ctrl,
+ .dev_ready = qong_nand_device_ready,
+ .select_chip = qong_nand_select_chip,
+ }
+};
+
+static struct resource qong_nand_resource = {
+ .start = CS3_BASE_ADDR,
+ .end = CS3_BASE_ADDR + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device qong_nand_device = {
+ .name = "gen_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &qong_nand_data,
+ },
+ .num_resources = 1,
+ .resource = &qong_nand_resource,
+};
+
+static void __init qong_init_nand_mtd(void)
+{
+ /* init CS */
+ __raw_writel(0x00004f00, CSCR_U(3));
+ __raw_writel(0x20013b31, CSCR_L(3));
+ __raw_writel(0x00020800, CSCR_A(3));
+ mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true);
+
+ /* enable pin */
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFCE_B, IOMUX_CONFIG_GPIO));
+ if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), "nand_enable"))
+ gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
+
+ /* ready/busy pin */
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFRB, IOMUX_CONFIG_GPIO));
+ if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFRB), "nand_rdy"))
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFRB));
+
+ /* write protect pin */
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFWP_B, IOMUX_CONFIG_GPIO));
+ if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFWP_B), "nand_wp"))
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFWP_B));
+
+ platform_device_register(&qong_nand_device);
+}
+
+static void __init qong_init_fpga(void)
+{
+ void __iomem *regs;
+ u32 fpga_ver;
+
+ regs = ioremap(QONG_FPGA_CTRL_BASEADDR, QONG_FPGA_CTRL_SIZE);
+ if (!regs) {
+ printk(KERN_ERR "%s: failed to map registers, aborting.\n",
+ __func__);
+ return;
+ }
+
+ fpga_ver = readl(regs + QONG_FPGA_CTRL_VERSION);
+ iounmap(regs);
+ printk(KERN_INFO "Qong FPGA version %d.%d.%d\n",
+ (fpga_ver & 0xF000) >> 12,
+ (fpga_ver & 0x0F00) >> 8, fpga_ver & 0x00FF);
+ if (fpga_ver < QONG_FPGA_VERSION(0, 8, 7)) {
+ printk(KERN_ERR "qong: Unexpected FPGA version, FPGA-based "
+ "devices won't be registered!\n");
+ return;
+ }
+
+ /* register FPGA-based devices */
+ qong_init_nand_mtd();
+ qong_init_dnet();
+}
+
+/*
+ * This structure defines the MX31 memory map.
+ */
+static struct map_desc qong_io_desc[] __initdata = {
+ {
+ .virtual = AIPS1_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
+ .length = AIPS1_SIZE,
+ .type = MT_DEVICE_NONSHARED
+ }, {
+ .virtual = AIPS2_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
+ .length = AIPS2_SIZE,
+ .type = MT_DEVICE_NONSHARED
+ }
+};
+
+/*
+ * Set up static virtual mappings.
+ */
+static void __init qong_map_io(void)
+{
+ mxc_map_io();
+ iotable_init(qong_io_desc, ARRAY_SIZE(qong_io_desc));
+}
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_init_imx_uart();
+ qong_init_nor_mtd();
+ qong_init_fpga();
+}
+
+static void __init qong_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer qong_timer = {
+ .init = qong_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros defined in arch.h in order to
+ * initialize __mach_desc_QONG data structure.
+ */
+
+MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
+ /* Maintainer: DENX Software Engineering GmbH */
+ .phys_io = AIPS1_BASE_ADDR,
+ .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x100,
+ .map_io = qong_map_io,
+ .init_irq = mxc_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &qong_timer,
+MACHINE_END
diff --git a/arch/arm/mach-netx/include/mach/netx-regs.h b/arch/arm/mach-netx/include/mach/netx-regs.h
index 08c60ff227be..5a03e7ccb01a 100644
--- a/arch/arm/mach-netx/include/mach/netx-regs.h
+++ b/arch/arm/mach-netx/include/mach/netx-regs.h
@@ -80,7 +80,7 @@
#define NETX_PA_XPEC(no) (NETX_IO_PHYS + NETX_OFS_XPEC(no))
#define NETX_PA_VIC (NETX_IO_PHYS + NETX_OFS_VIC)
-/* virual addresses */
+/* virtual addresses */
#define NETX_VA_SYSTEM (NETX_IO_VIRT + NETX_OFS_SYSTEM)
#define NETX_VA_MEMCR (NETX_IO_VIRT + NETX_OFS_MEMCR)
#define NETX_VA_DPMAS (NETX_IO_VIRT + NETX_OFS_DPMAS)
diff --git a/arch/arm/mach-netx/include/mach/system.h b/arch/arm/mach-netx/include/mach/system.h
index 6c1023b8a9ab..dc7b4bc003c5 100644
--- a/arch/arm/mach-netx/include/mach/system.h
+++ b/arch/arm/mach-netx/include/mach/system.h
@@ -28,7 +28,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
writel(NETX_SYSTEM_RES_CR_FIRMW_RES_EN | NETX_SYSTEM_RES_CR_FIRMW_RES,
NETX_SYSTEM_RES_CR);
diff --git a/arch/arm/mach-ns9xxx/include/mach/system.h b/arch/arm/mach-ns9xxx/include/mach/system.h
index e2068c57415f..1561588ca364 100644
--- a/arch/arm/mach-ns9xxx/include/mach/system.h
+++ b/arch/arm/mach-ns9xxx/include/mach/system.h
@@ -20,7 +20,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
#ifdef CONFIG_PROCESSOR_NS9360
if (processor_is_ns9360())
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
index 22e0eb6e9ec4..feb0e54a91de 100644
--- a/arch/arm/mach-ns9xxx/irq.c
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -63,7 +63,6 @@ static struct irq_chip ns9xxx_chip = {
#else
static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
{
- unsigned int cpu = smp_processor_id();
struct irqaction *action;
irqreturn_t action_ret;
@@ -72,7 +71,7 @@ static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
BUG_ON(desc->status & IRQ_INPROGRESS);
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
- kstat_cpu(cpu).irqs[irq]++;
+ kstat_incr_irqs_this_cpu(irq, desc);
action = desc->action;
if (unlikely(!action || (desc->status & IRQ_DISABLED)))
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index 10a301e32434..cd8de89c5fad 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -7,6 +7,11 @@ config ARCH_OMAP730
select CPU_ARM926T
select ARCH_OMAP_OTG
+config ARCH_OMAP850
+ depends on ARCH_OMAP1
+ bool "OMAP850 Based System"
+ select CPU_ARM926T
+
config ARCH_OMAP15XX
depends on ARCH_OMAP1
default y
@@ -46,6 +51,12 @@ config MACH_OMAP_H3
TI OMAP 1710 H3 board support. Say Y here if you have such
a board.
+config MACH_OMAP_HTCWIZARD
+ bool "HTC Wizard"
+ depends on ARCH_OMAP850
+ help
+ HTC Wizard smartphone support (AKA QTEK 9100, ...)
+
config MACH_OMAP_OSK
bool "TI OSK Support"
depends on ARCH_OMAP1 && ARCH_OMAP16XX
@@ -98,7 +109,7 @@ config MACH_OMAP_PALMZ71
help
Support for the Palm Zire71 PDA. To boot the kernel,
you'll need a PalmOS compatible bootloader; check out
- http://hackndev.com/palm/z71 for more informations.
+ http://hackndev.com/palm/z71 for more information.
Say Y here if you have such a PDA, say N otherwise.
config MACH_OMAP_PALMTT
@@ -163,7 +174,7 @@ config OMAP_ARM_216MHZ
config OMAP_ARM_195MHZ
bool "OMAP ARM 195 MHz CPU"
- depends on ARCH_OMAP1 && ARCH_OMAP730
+ depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850)
help
Enable 195MHz clock for OMAP CPU. If unsure, say N.
@@ -175,13 +186,13 @@ config OMAP_ARM_192MHZ
config OMAP_ARM_182MHZ
bool "OMAP ARM 182 MHz CPU"
- depends on ARCH_OMAP1 && ARCH_OMAP730
+ depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850)
help
Enable 182MHz clock for OMAP CPU. If unsure, say N.
config OMAP_ARM_168MHZ
bool "OMAP ARM 168 MHz CPU"
- depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
help
Enable 168MHz clock for OMAP CPU. If unsure, say N.
@@ -193,20 +204,20 @@ config OMAP_ARM_150MHZ
config OMAP_ARM_120MHZ
bool "OMAP ARM 120 MHz CPU"
- depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
help
Enable 120MHz clock for OMAP CPU. If unsure, say N.
config OMAP_ARM_60MHZ
bool "OMAP ARM 60 MHz CPU"
- depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
default y
help
Enable 60MHz clock for OMAP CPU. If unsure, say Y.
config OMAP_ARM_30MHZ
bool "OMAP ARM 30 MHz CPU"
- depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
help
Enable 30MHz clock for OMAP CPU. If unsure, say N.
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 2e618391cc51..8b40aace9db4 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -175,7 +175,6 @@ static struct omap_usb_config ams_delta_usb_config __initdata = {
static struct omap_board_config_kernel ams_delta_config[] = {
{ OMAP_TAG_LCD, &ams_delta_lcd_config },
{ OMAP_TAG_UART, &ams_delta_uart_config },
- { OMAP_TAG_USB, &ams_delta_usb_config },
};
static struct resource ams_delta_kp_resources[] = {
@@ -232,6 +231,7 @@ static void __init ams_delta_init(void)
/* Clear latch2 (NAND, LCD, modem enable) */
ams_delta_latch2_write(~0, 0);
+ omap_usb_init(&ams_delta_usb_config);
platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
}
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 30308294e7c1..19e0e9232336 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -34,7 +34,39 @@
#include <mach/keypad.h>
#include <mach/common.h>
#include <mach/board.h>
-#include <mach/board-fsample.h>
+
+/* fsample is pretty close to p2-sample */
+
+#define fsample_cpld_read(reg) __raw_readb(reg)
+#define fsample_cpld_write(val, reg) __raw_writeb(val, reg)
+
+#define FSAMPLE_CPLD_BASE 0xE8100000
+#define FSAMPLE_CPLD_SIZE SZ_4K
+#define FSAMPLE_CPLD_START 0x05080000
+
+#define FSAMPLE_CPLD_REG_A (FSAMPLE_CPLD_BASE + 0x00)
+#define FSAMPLE_CPLD_SWITCH (FSAMPLE_CPLD_BASE + 0x02)
+#define FSAMPLE_CPLD_UART (FSAMPLE_CPLD_BASE + 0x02)
+#define FSAMPLE_CPLD_REG_B (FSAMPLE_CPLD_BASE + 0x04)
+#define FSAMPLE_CPLD_VERSION (FSAMPLE_CPLD_BASE + 0x06)
+#define FSAMPLE_CPLD_SET_CLR (FSAMPLE_CPLD_BASE + 0x06)
+
+#define FSAMPLE_CPLD_BIT_BT_RESET 0
+#define FSAMPLE_CPLD_BIT_LCD_RESET 1
+#define FSAMPLE_CPLD_BIT_CAM_PWDN 2
+#define FSAMPLE_CPLD_BIT_CHARGER_ENABLE 3
+#define FSAMPLE_CPLD_BIT_SD_MMC_EN 4
+#define FSAMPLE_CPLD_BIT_aGPS_PWREN 5
+#define FSAMPLE_CPLD_BIT_BACKLIGHT 6
+#define FSAMPLE_CPLD_BIT_aGPS_EN_RESET 7
+#define FSAMPLE_CPLD_BIT_aGPS_SLEEPx_N 8
+#define FSAMPLE_CPLD_BIT_OTG_RESET 9
+
+#define fsample_cpld_set(bit) \
+ fsample_cpld_write((((bit) & 15) << 4) | 0x0f, FSAMPLE_CPLD_SET_CLR)
+
+#define fsample_cpld_clear(bit) \
+ fsample_cpld_write(0xf0 | ((bit) & 15), FSAMPLE_CPLD_SET_CLR)
static int fsample_keymap[] = {
KEY(0,0,KEY_UP),
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index 7d2670205373..e724940e86f2 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -62,7 +62,6 @@ static struct omap_uart_config generic_uart_config __initdata = {
};
static struct omap_board_config_kernel generic_config[] __initdata = {
- { OMAP_TAG_USB, NULL },
{ OMAP_TAG_UART, &generic_uart_config },
};
@@ -70,12 +69,12 @@ static void __init omap_generic_init(void)
{
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap15xx()) {
- generic_config[0].data = &generic1510_usb_config;
+ omap_usb_init(&generic1510_usb_config);
}
#endif
#if defined(CONFIG_ARCH_OMAP16XX)
if (!cpu_is_omap1510()) {
- generic_config[0].data = &generic1610_usb_config;
+ omap_usb_init(&generic1610_usb_config);
}
#endif
diff --git a/arch/arm/mach-omap1/board-h2-mmc.c b/arch/arm/mach-omap1/board-h2-mmc.c
index 409fa56d0a87..44d4a966bed9 100644
--- a/arch/arm/mach-omap1/board-h2-mmc.c
+++ b/arch/arm/mach-omap1/board-h2-mmc.c
@@ -19,6 +19,8 @@
#include <mach/mmc.h>
#include <mach/gpio.h>
+#include "board-h2.h"
+
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
static int mmc_set_power(struct device *dev, int slot, int power_on,
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index 0d784a795092..f695aa053ac8 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -46,6 +46,11 @@
#include <mach/keypad.h>
#include <mach/common.h>
+#include "board-h2.h"
+
+/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
+#define OMAP1610_ETHR_START 0x04000300
+
static int h2_keymap[] = {
KEY(0, 0, KEY_LEFT),
KEY(0, 1, KEY_RIGHT),
@@ -364,7 +369,6 @@ static struct omap_lcd_config h2_lcd_config __initdata = {
};
static struct omap_board_config_kernel h2_config[] __initdata = {
- { OMAP_TAG_USB, &h2_usb_config },
{ OMAP_TAG_UART, &h2_uart_config },
{ OMAP_TAG_LCD, &h2_lcd_config },
};
@@ -413,6 +417,7 @@ static void __init h2_init(void)
omap_serial_init();
omap_register_i2c_bus(1, 100, h2_i2c_board_info,
ARRAY_SIZE(h2_i2c_board_info));
+ omap_usb_init(&h2_usb_config);
h2_mmc_init();
}
diff --git a/arch/arm/plat-omap/include/mach/board-h2.h b/arch/arm/mach-omap1/board-h2.h
index 15531c8dc0e6..315e2662547e 100644
--- a/arch/arm/plat-omap/include/mach/board-h2.h
+++ b/arch/arm/mach-omap1/board-h2.h
@@ -1,5 +1,5 @@
/*
- * arch/arm/plat-omap/include/mach/board-h2.h
+ * arch/arm/mach-omap1/board-h2.h
*
* Hardware definitions for TI OMAP1610 H2 board.
*
@@ -29,9 +29,6 @@
#ifndef __ASM_ARCH_OMAP_H2_H
#define __ASM_ARCH_OMAP_H2_H
-/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
-#define OMAP1610_ETHR_START 0x04000300
-
#define H2_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
# define H2_TPS_GPIO_MMC_PWR_EN (H2_TPS_GPIO_BASE + 3)
diff --git a/arch/arm/mach-omap1/board-h3-mmc.c b/arch/arm/mach-omap1/board-h3-mmc.c
index fdfe793d56f2..0d8a3c195e2e 100644
--- a/arch/arm/mach-omap1/board-h3-mmc.c
+++ b/arch/arm/mach-omap1/board-h3-mmc.c
@@ -19,6 +19,8 @@
#include <mach/mmc.h>
#include <mach/gpio.h>
+#include "board-h3.h"
+
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
static int mmc_set_power(struct device *dev, int slot, int power_on,
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index bf08b6ad22ee..4695965114c4 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -50,6 +50,11 @@
#include <mach/dma.h>
#include <mach/common.h>
+#include "board-h3.h"
+
+/* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
+#define OMAP1710_ETHR_START 0x04000300
+
#define H3_TS_GPIO 48
static int h3_keymap[] = {
@@ -418,7 +423,6 @@ static struct omap_lcd_config h3_lcd_config __initdata = {
};
static struct omap_board_config_kernel h3_config[] __initdata = {
- { OMAP_TAG_USB, &h3_usb_config },
{ OMAP_TAG_UART, &h3_uart_config },
{ OMAP_TAG_LCD, &h3_lcd_config },
};
@@ -472,6 +476,7 @@ static void __init h3_init(void)
omap_serial_init();
omap_register_i2c_bus(1, 100, h3_i2c_board_info,
ARRAY_SIZE(h3_i2c_board_info));
+ omap_usb_init(&h3_usb_config);
h3_mmc_init();
}
diff --git a/arch/arm/plat-omap/include/mach/board-h3.h b/arch/arm/mach-omap1/board-h3.h
index 1888326da7ea..78de535be3c5 100644
--- a/arch/arm/plat-omap/include/mach/board-h3.h
+++ b/arch/arm/mach-omap1/board-h3.h
@@ -1,5 +1,5 @@
/*
- * arch/arm/plat-omap/include/mach/board-h3.h
+ * arch/arm/mach-omap1/board-h3.h
*
* Copyright (C) 2001 RidgeRun, Inc.
* Copyright (C) 2004 Texas Instruments, Inc.
@@ -27,9 +27,6 @@
#ifndef __ASM_ARCH_OMAP_H3_H
#define __ASM_ARCH_OMAP_H3_H
-/* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
-#define OMAP1710_ETHR_START 0x04000300
-
#define H3_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
# define H3_TPS_GPIO_MMC_PWR_EN (H3_TPS_GPIO_BASE + 4)
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 071cd02a734e..2fd98260ea49 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -39,6 +39,9 @@
#include <mach/common.h>
#include <mach/mmc.h>
+/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
+#define INNOVATOR1610_ETHR_START 0x04000300
+
static int innovator_keymap[] = {
KEY(0, 0, KEY_F1),
KEY(0, 3, KEY_DOWN),
@@ -370,7 +373,6 @@ static struct omap_uart_config innovator_uart_config __initdata = {
};
static struct omap_board_config_kernel innovator_config[] = {
- { OMAP_TAG_USB, NULL },
{ OMAP_TAG_LCD, NULL },
{ OMAP_TAG_UART, &innovator_uart_config },
};
@@ -392,13 +394,13 @@ static void __init innovator_init(void)
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
- innovator_config[0].data = &innovator1510_usb_config;
+ omap_usb_init(&innovator1510_usb_config);
innovator_config[1].data = &innovator1510_lcd_config;
}
#endif
#ifdef CONFIG_ARCH_OMAP16XX
if (cpu_is_omap1610()) {
- innovator_config[0].data = &h2_usb_config;
+ omap_usb_init(&h2_usb_config);
innovator_config[1].data = &innovator1610_lcd_config;
}
#endif
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index af51e0b180f2..7bc7a3cb9c51 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -233,10 +233,6 @@ static inline void nokia770_mmc_init(void)
}
#endif
-static struct omap_board_config_kernel nokia770_config[] __initdata = {
- { OMAP_TAG_USB, NULL },
-};
-
#if defined(CONFIG_OMAP_DSP)
/*
* audio power control
@@ -371,19 +367,16 @@ static __init int omap_dsp_init(void)
static void __init omap_nokia770_init(void)
{
- nokia770_config[0].data = &nokia770_usb_config;
-
platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
spi_register_board_info(nokia770_spi_board_info,
ARRAY_SIZE(nokia770_spi_board_info));
- omap_board_config = nokia770_config;
- omap_board_config_size = ARRAY_SIZE(nokia770_config);
omap_gpio_init();
omap_serial_init();
omap_register_i2c_bus(1, 100, NULL, 0);
omap_dsp_init();
ads7846_dev_init();
mipid_dev_init();
+ omap_usb_init(&nokia770_usb_config);
nokia770_mmc_init();
}
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 1a16ecb2ccc8..cf3247b15f87 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -52,6 +52,20 @@
#include <mach/tc.h>
#include <mach/common.h>
+/* At OMAP5912 OSK the Ethernet is directly connected to CS1 */
+#define OMAP_OSK_ETHR_START 0x04800300
+
+/* TPS65010 has four GPIOs. nPG and LED2 can be treated like GPIOs with
+ * alternate pin configurations for hardware-controlled blinking.
+ */
+#define OSK_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
+# define OSK_TPS_GPIO_USB_PWR_EN (OSK_TPS_GPIO_BASE + 0)
+# define OSK_TPS_GPIO_LED_D3 (OSK_TPS_GPIO_BASE + 1)
+# define OSK_TPS_GPIO_LAN_RESET (OSK_TPS_GPIO_BASE + 2)
+# define OSK_TPS_GPIO_DSP_PWR_EN (OSK_TPS_GPIO_BASE + 3)
+# define OSK_TPS_GPIO_LED_D9 (OSK_TPS_GPIO_BASE + 4)
+# define OSK_TPS_GPIO_LED_D2 (OSK_TPS_GPIO_BASE + 5)
+
static struct mtd_partition osk_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -290,7 +304,6 @@ static struct omap_lcd_config osk_lcd_config __initdata = {
#endif
static struct omap_board_config_kernel osk_config[] __initdata = {
- { OMAP_TAG_USB, &osk_usb_config },
{ OMAP_TAG_UART, &osk_uart_config },
#ifdef CONFIG_OMAP_OSK_MISTRAL
{ OMAP_TAG_LCD, &osk_lcd_config },
@@ -541,6 +554,8 @@ static void __init osk_init(void)
l |= (3 << 1);
omap_writel(l, USB_TRANSCEIVER_CTRL);
+ omap_usb_init(&osk_usb_config);
+
/* irq for tps65010 chip */
/* bootloader effectively does: omap_cfg_reg(U19_1610_MPUIO1); */
if (gpio_request(OMAP_MPUIO(1), "tps65010") == 0)
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 99f2b43f2541..886b4c0569bd 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -43,6 +43,21 @@
#include <mach/keypad.h>
#include <mach/common.h>
+#define PALMTE_USBDETECT_GPIO 0
+#define PALMTE_USB_OR_DC_GPIO 1
+#define PALMTE_TSC_GPIO 4
+#define PALMTE_PINTDAV_GPIO 6
+#define PALMTE_MMC_WP_GPIO 8
+#define PALMTE_MMC_POWER_GPIO 9
+#define PALMTE_HDQ_GPIO 11
+#define PALMTE_HEADPHONES_GPIO 14
+#define PALMTE_SPEAKER_GPIO 15
+#define PALMTE_DC_GPIO OMAP_MPUIO(2)
+#define PALMTE_MMC_SWITCH_GPIO OMAP_MPUIO(4)
+#define PALMTE_MMC1_GPIO OMAP_MPUIO(6)
+#define PALMTE_MMC2_GPIO OMAP_MPUIO(7)
+#define PALMTE_MMC3_GPIO OMAP_MPUIO(11)
+
static void __init omap_palmte_init_irq(void)
{
omap1_init_common_hw();
@@ -286,7 +301,6 @@ static void palmte_get_power_status(struct apm_power_info *info, int *battery)
#endif
static struct omap_board_config_kernel palmte_config[] __initdata = {
- { OMAP_TAG_USB, &palmte_usb_config },
{ OMAP_TAG_LCD, &palmte_lcd_config },
{ OMAP_TAG_UART, &palmte_uart_config },
};
@@ -341,6 +355,7 @@ static void __init omap_palmte_init(void)
spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
palmte_misc_gpio_setup();
omap_serial_init();
+ omap_usb_init(&palmte_usb_config);
omap_register_i2c_bus(1, 100, NULL, 0);
}
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index 1cbc1275c95f..4f1b44831d37 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -43,6 +43,13 @@
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
+#define PALMTT_USBDETECT_GPIO 0
+#define PALMTT_CABLE_GPIO 1
+#define PALMTT_LED_GPIO 3
+#define PALMTT_PENIRQ_GPIO 6
+#define PALMTT_MMC_WP_GPIO 8
+#define PALMTT_HDQ_GPIO 11
+
static int palmtt_keymap[] = {
KEY(0, 0, KEY_ESC),
KEY(0, 1, KEY_SPACE),
@@ -272,7 +279,6 @@ static struct omap_uart_config palmtt_uart_config __initdata = {
};
static struct omap_board_config_kernel palmtt_config[] __initdata = {
- { OMAP_TAG_USB, &palmtt_usb_config },
{ OMAP_TAG_LCD, &palmtt_lcd_config },
{ OMAP_TAG_UART, &palmtt_uart_config },
};
@@ -297,6 +303,7 @@ static void __init omap_palmtt_init(void)
spi_register_board_info(palmtt_boardinfo,ARRAY_SIZE(palmtt_boardinfo));
omap_serial_init();
+ omap_usb_init(&palmtt_usb_config);
omap_register_i2c_bus(1, 100, NULL, 0);
}
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index baf5efbfe3e8..9a55c3c58218 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -46,6 +46,16 @@
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
+#define PALMZ71_USBDETECT_GPIO 0
+#define PALMZ71_PENIRQ_GPIO 6
+#define PALMZ71_MMC_WP_GPIO 8
+#define PALMZ71_HDQ_GPIO 11
+
+#define PALMZ71_HOTSYNC_GPIO OMAP_MPUIO(1)
+#define PALMZ71_CABLE_GPIO OMAP_MPUIO(2)
+#define PALMZ71_SLIDER_GPIO OMAP_MPUIO(3)
+#define PALMZ71_MMC_IN_GPIO OMAP_MPUIO(4)
+
static void __init
omap_palmz71_init_irq(void)
{
@@ -239,7 +249,6 @@ static struct omap_uart_config palmz71_uart_config __initdata = {
};
static struct omap_board_config_kernel palmz71_config[] __initdata = {
- {OMAP_TAG_USB, &palmz71_usb_config},
{OMAP_TAG_LCD, &palmz71_lcd_config},
{OMAP_TAG_UART, &palmz71_uart_config},
};
@@ -313,6 +322,7 @@ omap_palmz71_init(void)
spi_register_board_info(palmz71_boardinfo,
ARRAY_SIZE(palmz71_boardinfo));
+ omap_usb_init(&palmz71_usb_config);
omap_serial_init();
omap_register_i2c_bus(1, 100, NULL, 0);
palmz71_gpio_setup(0);
diff --git a/arch/arm/mach-omap1/board-sx1-mmc.c b/arch/arm/mach-omap1/board-sx1-mmc.c
index 66a4d7d5255d..58a46e4e45c3 100644
--- a/arch/arm/mach-omap1/board-sx1-mmc.c
+++ b/arch/arm/mach-omap1/board-sx1-mmc.c
@@ -17,6 +17,7 @@
#include <mach/hardware.h>
#include <mach/mmc.h>
#include <mach/gpio.h>
+#include <mach/board-sx1.h>
#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 28c76a1e71c0..c096577695fe 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -41,6 +41,7 @@
#include <mach/board.h>
#include <mach/common.h>
#include <mach/keypad.h>
+#include <mach/board-sx1.h>
/* Write to I2C device */
int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value)
@@ -373,7 +374,6 @@ static struct omap_uart_config sx1_uart_config __initdata = {
};
static struct omap_board_config_kernel sx1_config[] __initdata = {
- { OMAP_TAG_USB, &sx1_usb_config },
{ OMAP_TAG_LCD, &sx1_lcd_config },
{ OMAP_TAG_UART, &sx1_uart_config },
};
@@ -388,6 +388,7 @@ static void __init omap_sx1_init(void)
omap_board_config_size = ARRAY_SIZE(sx1_config);
omap_serial_init();
omap_register_i2c_bus(1, 100, NULL, 0);
+ omap_usb_init(&sx1_usb_config);
sx1_mmc_init();
/* turn on USB power */
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index a7653542a2b0..98275e03dad1 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -145,7 +145,6 @@ static struct omap_uart_config voiceblue_uart_config __initdata = {
};
static struct omap_board_config_kernel voiceblue_config[] = {
- { OMAP_TAG_USB, &voiceblue_usb_config },
{ OMAP_TAG_UART, &voiceblue_uart_config },
};
@@ -185,6 +184,7 @@ static void __init voiceblue_init(void)
omap_board_config = voiceblue_config;
omap_board_config_size = ARRAY_SIZE(voiceblue_config);
omap_serial_init();
+ omap_usb_init(&voiceblue_usb_config);
omap_register_i2c_bus(1, 100, NULL, 0);
/* There is a good chance board is going up, so enable power LED
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 5fba20731710..dafe4f71d15f 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -20,41 +20,161 @@
#include <linux/io.h>
#include <asm/mach-types.h>
+#include <asm/clkdev.h>
#include <mach/cpu.h>
#include <mach/usb.h>
#include <mach/clock.h>
#include <mach/sram.h>
+static const struct clkops clkops_generic;
+static const struct clkops clkops_uart;
+static const struct clkops clkops_dspck;
+
#include "clock.h"
+static int clk_omap1_dummy_enable(struct clk *clk)
+{
+ return 0;
+}
+
+static void clk_omap1_dummy_disable(struct clk *clk)
+{
+}
+
+static const struct clkops clkops_dummy = {
+ .enable = clk_omap1_dummy_enable,
+ .disable = clk_omap1_dummy_disable,
+};
+
+static struct clk dummy_ck = {
+ .name = "dummy",
+ .ops = &clkops_dummy,
+ .flags = RATE_FIXED,
+};
+
+struct omap_clk {
+ u32 cpu;
+ struct clk_lookup lk;
+};
+
+#define CLK(dev, con, ck, cp) \
+ { \
+ .cpu = cp, \
+ .lk = { \
+ .dev_id = dev, \
+ .con_id = con, \
+ .clk = ck, \
+ }, \
+ }
+
+#define CK_310 (1 << 0)
+#define CK_730 (1 << 1)
+#define CK_1510 (1 << 2)
+#define CK_16XX (1 << 3)
+
+static struct omap_clk omap_clks[] = {
+ /* non-ULPD clocks */
+ CLK(NULL, "ck_ref", &ck_ref, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "ck_dpll1", &ck_dpll1, CK_16XX | CK_1510 | CK_310),
+ /* CK_GEN1 clocks */
+ CLK(NULL, "ck_dpll1out", &ck_dpll1out.clk, CK_16XX),
+ CLK(NULL, "ck_sossi", &sossi_ck, CK_16XX),
+ CLK(NULL, "arm_ck", &arm_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "armper_ck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "arm_gpio_ck", &arm_gpio_ck, CK_1510 | CK_310),
+ CLK(NULL, "armxor_ck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "armtim_ck", &armtim_ck.clk, CK_16XX | CK_1510 | CK_310),
+ CLK("omap_wdt", "fck", &armwdt_ck.clk, CK_16XX | CK_1510 | CK_310),
+ CLK("omap_wdt", "ick", &armper_ck.clk, CK_16XX),
+ CLK("omap_wdt", "ick", &dummy_ck, CK_1510 | CK_310),
+ CLK(NULL, "arminth_ck", &arminth_ck1510, CK_1510 | CK_310),
+ CLK(NULL, "arminth_ck", &arminth_ck16xx, CK_16XX),
+ /* CK_GEN2 clocks */
+ CLK(NULL, "dsp_ck", &dsp_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "dspmmu_ck", &dspmmu_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "dspper_ck", &dspper_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "dspxor_ck", &dspxor_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "dsptim_ck", &dsptim_ck, CK_16XX | CK_1510 | CK_310),
+ /* CK_GEN3 clocks */
+ CLK(NULL, "tc_ck", &tc_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_730),
+ CLK(NULL, "tipb_ck", &tipb_ck, CK_1510 | CK_310),
+ CLK(NULL, "l3_ocpi_ck", &l3_ocpi_ck, CK_16XX),
+ CLK(NULL, "tc1_ck", &tc1_ck, CK_16XX),
+ CLK(NULL, "tc2_ck", &tc2_ck, CK_16XX),
+ CLK(NULL, "dma_ck", &dma_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "dma_lcdfree_ck", &dma_lcdfree_ck, CK_16XX),
+ CLK(NULL, "api_ck", &api_ck.clk, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "lb_ck", &lb_ck.clk, CK_1510 | CK_310),
+ CLK(NULL, "rhea1_ck", &rhea1_ck, CK_16XX),
+ CLK(NULL, "rhea2_ck", &rhea2_ck, CK_16XX),
+ CLK(NULL, "lcd_ck", &lcd_ck_16xx, CK_16XX | CK_730),
+ CLK(NULL, "lcd_ck", &lcd_ck_1510.clk, CK_1510 | CK_310),
+ /* ULPD clocks */
+ CLK(NULL, "uart1_ck", &uart1_1510, CK_1510 | CK_310),
+ CLK(NULL, "uart1_ck", &uart1_16xx.clk, CK_16XX),
+ CLK(NULL, "uart2_ck", &uart2_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "uart3_ck", &uart3_1510, CK_1510 | CK_310),
+ CLK(NULL, "uart3_ck", &uart3_16xx.clk, CK_16XX),
+ CLK(NULL, "usb_clko", &usb_clko, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "usb_hhc_ck", &usb_hhc_ck1510, CK_1510 | CK_310),
+ CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx, CK_16XX),
+ CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX),
+ CLK(NULL, "mclk", &mclk_1510, CK_1510 | CK_310),
+ CLK(NULL, "mclk", &mclk_16xx, CK_16XX),
+ CLK(NULL, "bclk", &bclk_1510, CK_1510 | CK_310),
+ CLK(NULL, "bclk", &bclk_16xx, CK_16XX),
+ CLK("mmci-omap.0", "fck", &mmc1_ck, CK_16XX | CK_1510 | CK_310),
+ CLK("mmci-omap.0", "ick", &armper_ck.clk, CK_16XX | CK_1510 | CK_310),
+ CLK("mmci-omap.1", "fck", &mmc2_ck, CK_16XX),
+ CLK("mmci-omap.1", "ick", &armper_ck.clk, CK_16XX),
+ /* Virtual clocks */
+ CLK(NULL, "mpu", &virtual_ck_mpu, CK_16XX | CK_1510 | CK_310),
+ CLK("i2c_omap.1", "fck", &i2c_fck, CK_16XX | CK_1510 | CK_310),
+ CLK("i2c_omap.1", "ick", &i2c_ick, CK_16XX),
+ CLK("i2c_omap.1", "ick", &dummy_ck, CK_1510 | CK_310),
+ CLK("omap_uwire", "fck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310),
+ CLK("omap-mcbsp.1", "ick", &dspper_ck, CK_16XX),
+ CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_1510 | CK_310),
+ CLK("omap-mcbsp.2", "ick", &armper_ck.clk, CK_16XX),
+ CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_1510 | CK_310),
+ CLK("omap-mcbsp.3", "ick", &dspper_ck, CK_16XX),
+ CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_1510 | CK_310),
+ CLK("omap-mcbsp.1", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310),
+ CLK("omap-mcbsp.2", "fck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310),
+ CLK("omap-mcbsp.3", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310),
+};
+
+static int omap1_clk_enable_generic(struct clk * clk);
+static int omap1_clk_enable(struct clk *clk);
+static void omap1_clk_disable_generic(struct clk * clk);
+static void omap1_clk_disable(struct clk *clk);
+
__u32 arm_idlect1_mask;
/*-------------------------------------------------------------------------
* Omap1 specific clock functions
*-------------------------------------------------------------------------*/
-static void omap1_watchdog_recalc(struct clk * clk)
+static unsigned long omap1_watchdog_recalc(struct clk *clk)
{
- clk->rate = clk->parent->rate / 14;
+ return clk->parent->rate / 14;
}
-static void omap1_uart_recalc(struct clk * clk)
+static unsigned long omap1_uart_recalc(struct clk *clk)
{
- unsigned int val = omap_readl(clk->enable_reg);
- if (val & clk->enable_bit)
- clk->rate = 48000000;
- else
- clk->rate = 12000000;
+ unsigned int val = __raw_readl(clk->enable_reg);
+ return val & clk->enable_bit ? 48000000 : 12000000;
}
-static void omap1_sossi_recalc(struct clk *clk)
+static unsigned long omap1_sossi_recalc(struct clk *clk)
{
u32 div = omap_readl(MOD_CONF_CTRL_1);
div = (div >> 17) & 0x7;
div++;
- clk->rate = clk->parent->rate / div;
+
+ return clk->parent->rate / div;
}
static int omap1_clk_enable_dsp_domain(struct clk *clk)
@@ -78,6 +198,11 @@ static void omap1_clk_disable_dsp_domain(struct clk *clk)
}
}
+static const struct clkops clkops_dspck = {
+ .enable = &omap1_clk_enable_dsp_domain,
+ .disable = &omap1_clk_disable_dsp_domain,
+};
+
static int omap1_clk_enable_uart_functional(struct clk *clk)
{
int ret;
@@ -105,6 +230,11 @@ static void omap1_clk_disable_uart_functional(struct clk *clk)
omap1_clk_disable_generic(clk);
}
+static const struct clkops clkops_uart = {
+ .enable = &omap1_clk_enable_uart_functional,
+ .disable = &omap1_clk_disable_uart_functional,
+};
+
static void omap1_clk_allow_idle(struct clk *clk)
{
struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
@@ -197,9 +327,6 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
struct clk * parent;
unsigned dsor_exp;
- if (unlikely(!(clk->flags & RATE_CKCTL)))
- return -EINVAL;
-
parent = clk->parent;
if (unlikely(parent == NULL))
return -EIO;
@@ -215,22 +342,15 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
return dsor_exp;
}
-static void omap1_ckctl_recalc(struct clk * clk)
+static unsigned long omap1_ckctl_recalc(struct clk *clk)
{
- int dsor;
-
/* Calculate divisor encoded as 2-bit exponent */
- dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
+ int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
- if (unlikely(clk->rate == clk->parent->rate / dsor))
- return; /* No change, quick exit */
- clk->rate = clk->parent->rate / dsor;
-
- if (unlikely(clk->flags & RATE_PROPAGATES))
- propagate_rate(clk);
+ return clk->parent->rate / dsor;
}
-static void omap1_ckctl_recalc_dsp_domain(struct clk * clk)
+static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk)
{
int dsor;
@@ -245,12 +365,7 @@ static void omap1_ckctl_recalc_dsp_domain(struct clk * clk)
dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
omap1_clk_disable(&api_ck.clk);
- if (unlikely(clk->rate == clk->parent->rate / dsor))
- return; /* No change, quick exit */
- clk->rate = clk->parent->rate / dsor;
-
- if (unlikely(clk->flags & RATE_PROPAGATES))
- propagate_rate(clk);
+ return clk->parent->rate / dsor;
}
/* MPU virtual clock functions */
@@ -289,35 +404,57 @@ static int omap1_select_table_rate(struct clk * clk, unsigned long rate)
omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
ck_dpll1.rate = ptr->pll_rate;
- propagate_rate(&ck_dpll1);
return 0;
}
static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
{
- int ret = -EINVAL;
- int dsor_exp;
- __u16 regval;
-
- if (clk->flags & RATE_CKCTL) {
- dsor_exp = calc_dsor_exp(clk, rate);
- if (dsor_exp > 3)
- dsor_exp = -EINVAL;
- if (dsor_exp < 0)
- return dsor_exp;
-
- regval = __raw_readw(DSP_CKCTL);
- regval &= ~(3 << clk->rate_offset);
- regval |= dsor_exp << clk->rate_offset;
- __raw_writew(regval, DSP_CKCTL);
- clk->rate = clk->parent->rate / (1 << dsor_exp);
- ret = 0;
- }
+ int dsor_exp;
+ u16 regval;
- if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
- propagate_rate(clk);
+ dsor_exp = calc_dsor_exp(clk, rate);
+ if (dsor_exp > 3)
+ dsor_exp = -EINVAL;
+ if (dsor_exp < 0)
+ return dsor_exp;
- return ret;
+ regval = __raw_readw(DSP_CKCTL);
+ regval &= ~(3 << clk->rate_offset);
+ regval |= dsor_exp << clk->rate_offset;
+ __raw_writew(regval, DSP_CKCTL);
+ clk->rate = clk->parent->rate / (1 << dsor_exp);
+
+ return 0;
+}
+
+static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate)
+{
+ int dsor_exp = calc_dsor_exp(clk, rate);
+ if (dsor_exp < 0)
+ return dsor_exp;
+ if (dsor_exp > 3)
+ dsor_exp = 3;
+ return clk->parent->rate / (1 << dsor_exp);
+}
+
+static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate)
+{
+ int dsor_exp;
+ u16 regval;
+
+ dsor_exp = calc_dsor_exp(clk, rate);
+ if (dsor_exp > 3)
+ dsor_exp = -EINVAL;
+ if (dsor_exp < 0)
+ return dsor_exp;
+
+ regval = omap_readw(ARM_CKCTL);
+ regval &= ~(3 << clk->rate_offset);
+ regval |= dsor_exp << clk->rate_offset;
+ regval = verify_ckctl_value(regval);
+ omap_writew(regval, ARM_CKCTL);
+ clk->rate = clk->parent->rate / (1 << dsor_exp);
+ return 0;
}
static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate)
@@ -372,14 +509,14 @@ static int omap1_set_uart_rate(struct clk * clk, unsigned long rate)
{
unsigned int val;
- val = omap_readl(clk->enable_reg);
+ val = __raw_readl(clk->enable_reg);
if (rate == 12000000)
val &= ~(1 << clk->enable_bit);
else if (rate == 48000000)
val |= (1 << clk->enable_bit);
else
return -EINVAL;
- omap_writel(val, clk->enable_reg);
+ __raw_writel(val, clk->enable_reg);
clk->rate = rate;
return 0;
@@ -398,8 +535,8 @@ static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate)
else
ratio_bits = (dsor - 2) << 2;
- ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd;
- omap_writew(ratio_bits, clk->enable_reg);
+ ratio_bits |= __raw_readw(clk->enable_reg) & ~0xfd;
+ __raw_writew(ratio_bits, clk->enable_reg);
return 0;
}
@@ -423,8 +560,6 @@ static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate)
omap_writel(l, MOD_CONF_CTRL_1);
clk->rate = p_rate / (div + 1);
- if (unlikely(clk->flags & RATE_PROPAGATES))
- propagate_rate(clk);
return 0;
}
@@ -440,8 +575,8 @@ static void omap1_init_ext_clk(struct clk * clk)
__u16 ratio_bits;
/* Determine current rate and ensure clock is based on 96MHz APLL */
- ratio_bits = omap_readw(clk->enable_reg) & ~1;
- omap_writew(ratio_bits, clk->enable_reg);
+ ratio_bits = __raw_readw(clk->enable_reg) & ~1;
+ __raw_writew(ratio_bits, clk->enable_reg);
ratio_bits = (ratio_bits & 0xfc) >> 2;
if (ratio_bits > 6)
@@ -468,7 +603,7 @@ static int omap1_clk_enable(struct clk *clk)
omap1_clk_deny_idle(clk->parent);
}
- ret = clk->enable(clk);
+ ret = clk->ops->enable(clk);
if (unlikely(ret != 0) && clk->parent) {
omap1_clk_disable(clk->parent);
@@ -482,7 +617,7 @@ static int omap1_clk_enable(struct clk *clk)
static void omap1_clk_disable(struct clk *clk)
{
if (clk->usecount > 0 && !(--clk->usecount)) {
- clk->disable(clk);
+ clk->ops->disable(clk);
if (likely(clk->parent)) {
omap1_clk_disable(clk->parent);
if (clk->flags & CLOCK_NO_IDLE_PARENT)
@@ -496,9 +631,6 @@ static int omap1_clk_enable_generic(struct clk *clk)
__u16 regval16;
__u32 regval32;
- if (clk->flags & ALWAYS_ENABLED)
- return 0;
-
if (unlikely(clk->enable_reg == NULL)) {
printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
clk->name);
@@ -506,25 +638,13 @@ static int omap1_clk_enable_generic(struct clk *clk)
}
if (clk->flags & ENABLE_REG_32BIT) {
- if (clk->flags & VIRTUAL_IO_ADDRESS) {
- regval32 = __raw_readl(clk->enable_reg);
- regval32 |= (1 << clk->enable_bit);
- __raw_writel(regval32, clk->enable_reg);
- } else {
- regval32 = omap_readl(clk->enable_reg);
- regval32 |= (1 << clk->enable_bit);
- omap_writel(regval32, clk->enable_reg);
- }
+ regval32 = __raw_readl(clk->enable_reg);
+ regval32 |= (1 << clk->enable_bit);
+ __raw_writel(regval32, clk->enable_reg);
} else {
- if (clk->flags & VIRTUAL_IO_ADDRESS) {
- regval16 = __raw_readw(clk->enable_reg);
- regval16 |= (1 << clk->enable_bit);
- __raw_writew(regval16, clk->enable_reg);
- } else {
- regval16 = omap_readw(clk->enable_reg);
- regval16 |= (1 << clk->enable_bit);
- omap_writew(regval16, clk->enable_reg);
- }
+ regval16 = __raw_readw(clk->enable_reg);
+ regval16 |= (1 << clk->enable_bit);
+ __raw_writew(regval16, clk->enable_reg);
}
return 0;
@@ -539,44 +659,26 @@ static void omap1_clk_disable_generic(struct clk *clk)
return;
if (clk->flags & ENABLE_REG_32BIT) {
- if (clk->flags & VIRTUAL_IO_ADDRESS) {
- regval32 = __raw_readl(clk->enable_reg);
- regval32 &= ~(1 << clk->enable_bit);
- __raw_writel(regval32, clk->enable_reg);
- } else {
- regval32 = omap_readl(clk->enable_reg);
- regval32 &= ~(1 << clk->enable_bit);
- omap_writel(regval32, clk->enable_reg);
- }
+ regval32 = __raw_readl(clk->enable_reg);
+ regval32 &= ~(1 << clk->enable_bit);
+ __raw_writel(regval32, clk->enable_reg);
} else {
- if (clk->flags & VIRTUAL_IO_ADDRESS) {
- regval16 = __raw_readw(clk->enable_reg);
- regval16 &= ~(1 << clk->enable_bit);
- __raw_writew(regval16, clk->enable_reg);
- } else {
- regval16 = omap_readw(clk->enable_reg);
- regval16 &= ~(1 << clk->enable_bit);
- omap_writew(regval16, clk->enable_reg);
- }
+ regval16 = __raw_readw(clk->enable_reg);
+ regval16 &= ~(1 << clk->enable_bit);
+ __raw_writew(regval16, clk->enable_reg);
}
}
+static const struct clkops clkops_generic = {
+ .enable = &omap1_clk_enable_generic,
+ .disable = &omap1_clk_disable_generic,
+};
+
static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
{
- int dsor_exp;
-
if (clk->flags & RATE_FIXED)
return clk->rate;
- if (clk->flags & RATE_CKCTL) {
- dsor_exp = calc_dsor_exp(clk, rate);
- if (dsor_exp < 0)
- return dsor_exp;
- if (dsor_exp > 3)
- dsor_exp = 3;
- return clk->parent->rate / (1 << dsor_exp);
- }
-
if (clk->round_rate != NULL)
return clk->round_rate(clk, rate);
@@ -586,30 +688,9 @@ static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
static int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
{
int ret = -EINVAL;
- int dsor_exp;
- __u16 regval;
if (clk->set_rate)
ret = clk->set_rate(clk, rate);
- else if (clk->flags & RATE_CKCTL) {
- dsor_exp = calc_dsor_exp(clk, rate);
- if (dsor_exp > 3)
- dsor_exp = -EINVAL;
- if (dsor_exp < 0)
- return dsor_exp;
-
- regval = omap_readw(ARM_CKCTL);
- regval &= ~(3 << clk->rate_offset);
- regval |= dsor_exp << clk->rate_offset;
- regval = verify_ckctl_value(regval);
- omap_writew(regval, ARM_CKCTL);
- clk->rate = clk->parent->rate / (1 << dsor_exp);
- ret = 0;
- }
-
- if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
- propagate_rate(clk);
-
return ret;
}
@@ -632,17 +713,10 @@ static void __init omap1_clk_disable_unused(struct clk *clk)
}
/* Is the clock already disabled? */
- if (clk->flags & ENABLE_REG_32BIT) {
- if (clk->flags & VIRTUAL_IO_ADDRESS)
- regval32 = __raw_readl(clk->enable_reg);
- else
- regval32 = omap_readl(clk->enable_reg);
- } else {
- if (clk->flags & VIRTUAL_IO_ADDRESS)
- regval32 = __raw_readw(clk->enable_reg);
- else
- regval32 = omap_readw(clk->enable_reg);
- }
+ if (clk->flags & ENABLE_REG_32BIT)
+ regval32 = __raw_readl(clk->enable_reg);
+ else
+ regval32 = __raw_readw(clk->enable_reg);
if ((regval32 & (1 << clk->enable_bit)) == 0)
return;
@@ -659,7 +733,7 @@ static void __init omap1_clk_disable_unused(struct clk *clk)
}
printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name);
- clk->disable(clk);
+ clk->ops->disable(clk);
printk(" done\n");
}
@@ -677,10 +751,10 @@ static struct clk_functions omap1_clk_functions = {
int __init omap1_clk_init(void)
{
- struct clk ** clkp;
+ struct omap_clk *c;
const struct omap_clock_config *info;
int crystal_type = 0; /* Default 12 MHz */
- u32 reg;
+ u32 reg, cpu_mask;
#ifdef CONFIG_DEBUG_LL
/* Resets some clocks that may be left on from bootloader,
@@ -700,27 +774,24 @@ int __init omap1_clk_init(void)
/* By default all idlect1 clocks are allowed to idle */
arm_idlect1_mask = ~0;
- for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
- if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
- clk_register(*clkp);
- continue;
- }
-
- if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
- clk_register(*clkp);
- continue;
- }
-
- if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) {
- clk_register(*clkp);
- continue;
- }
+ for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
+ clk_init_one(c->lk.clk);
- if (((*clkp)->flags &CLOCK_IN_OMAP310) && cpu_is_omap310()) {
- clk_register(*clkp);
- continue;
+ cpu_mask = 0;
+ if (cpu_is_omap16xx())
+ cpu_mask |= CK_16XX;
+ if (cpu_is_omap1510())
+ cpu_mask |= CK_1510;
+ if (cpu_is_omap730())
+ cpu_mask |= CK_730;
+ if (cpu_is_omap310())
+ cpu_mask |= CK_310;
+
+ for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
+ if (c->cpu & cpu_mask) {
+ clkdev_add(&c->lk);
+ clk_register(c->lk.clk);
}
- }
info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
if (info != NULL) {
@@ -769,7 +840,6 @@ int __init omap1_clk_init(void)
}
}
}
- propagate_rate(&ck_dpll1);
#else
/* Find the highest supported frequency and enable it */
if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
@@ -778,9 +848,9 @@ int __init omap1_clk_init(void)
omap_writew(0x2290, DPLL_CTL);
omap_writew(cpu_is_omap730() ? 0x3005 : 0x1005, ARM_CKCTL);
ck_dpll1.rate = 60000000;
- propagate_rate(&ck_dpll1);
}
#endif
+ propagate_rate(&ck_dpll1);
/* Cache rates for clocks connected to ck_ref (not dpll1) */
propagate_rate(&ck_ref);
printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
@@ -832,4 +902,3 @@ int __init omap1_clk_init(void)
return 0;
}
-
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index c1dcdf18d8dd..17f874271255 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -13,27 +13,22 @@
#ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H
#define __ARCH_ARM_MACH_OMAP1_CLOCK_H
-static int omap1_clk_enable_generic(struct clk * clk);
-static void omap1_clk_disable_generic(struct clk * clk);
-static void omap1_ckctl_recalc(struct clk * clk);
-static void omap1_watchdog_recalc(struct clk * clk);
+static unsigned long omap1_ckctl_recalc(struct clk *clk);
+static unsigned long omap1_watchdog_recalc(struct clk *clk);
static int omap1_set_sossi_rate(struct clk *clk, unsigned long rate);
-static void omap1_sossi_recalc(struct clk *clk);
-static void omap1_ckctl_recalc_dsp_domain(struct clk * clk);
-static int omap1_clk_enable_dsp_domain(struct clk * clk);
+static unsigned long omap1_sossi_recalc(struct clk *clk);
+static unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk);
static int omap1_clk_set_rate_dsp_domain(struct clk * clk, unsigned long rate);
-static void omap1_clk_disable_dsp_domain(struct clk * clk);
static int omap1_set_uart_rate(struct clk * clk, unsigned long rate);
-static void omap1_uart_recalc(struct clk * clk);
-static int omap1_clk_enable_uart_functional(struct clk * clk);
-static void omap1_clk_disable_uart_functional(struct clk * clk);
+static unsigned long omap1_uart_recalc(struct clk *clk);
static int omap1_set_ext_clk_rate(struct clk * clk, unsigned long rate);
static long omap1_round_ext_clk_rate(struct clk * clk, unsigned long rate);
static void omap1_init_ext_clk(struct clk * clk);
static int omap1_select_table_rate(struct clk * clk, unsigned long rate);
static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate);
-static int omap1_clk_enable(struct clk *clk);
-static void omap1_clk_disable(struct clk *clk);
+
+static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate);
+static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate);
struct mpu_rate {
unsigned long rate;
@@ -152,101 +147,84 @@ static struct mpu_rate rate_table[] = {
static struct clk ck_ref = {
.name = "ck_ref",
+ .ops = &clkops_null,
.rate = 12000000,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk ck_dpll1 = {
.name = "ck_dpll1",
+ .ops = &clkops_null,
.parent = &ck_ref,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP310 | RATE_PROPAGATES | ALWAYS_ENABLED,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct arm_idlect1_clk ck_dpll1out = {
.clk = {
.name = "ck_dpll1out",
+ .ops = &clkops_generic,
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP16XX | CLOCK_IDLE_CONTROL |
- ENABLE_REG_32BIT | RATE_PROPAGATES,
- .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .flags = CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_CKOUT_ARM,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
},
.idlect_shift = 12,
};
static struct clk sossi_ck = {
.name = "ck_sossi",
+ .ops = &clkops_generic,
.parent = &ck_dpll1out.clk,
- .flags = CLOCK_IN_OMAP16XX | CLOCK_NO_IDLE_PARENT |
- ENABLE_REG_32BIT,
- .enable_reg = (void __iomem *)MOD_CONF_CTRL_1,
+ .flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
.enable_bit = 16,
.recalc = &omap1_sossi_recalc,
.set_rate = &omap1_set_sossi_rate,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk arm_ck = {
.name = "arm_ck",
+ .ops = &clkops_null,
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP310 | RATE_CKCTL | RATE_PROPAGATES |
- ALWAYS_ENABLED,
.rate_offset = CKCTL_ARMDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
};
static struct arm_idlect1_clk armper_ck = {
.clk = {
.name = "armper_ck",
+ .ops = &clkops_generic,
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP310 | RATE_CKCTL |
- CLOCK_IDLE_CONTROL,
- .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_PERCK,
.rate_offset = CKCTL_PERDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
},
.idlect_shift = 2,
};
static struct clk arm_gpio_ck = {
.name = "arm_gpio_ck",
+ .ops = &clkops_generic,
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310,
- .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_GPIOCK,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct arm_idlect1_clk armxor_ck = {
.clk = {
.name = "armxor_ck",
+ .ops = &clkops_generic,
.parent = &ck_ref,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
- .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_XORPCK,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
},
.idlect_shift = 1,
};
@@ -254,14 +232,12 @@ static struct arm_idlect1_clk armxor_ck = {
static struct arm_idlect1_clk armtim_ck = {
.clk = {
.name = "armtim_ck",
+ .ops = &clkops_generic,
.parent = &ck_ref,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
- .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_TIMCK,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
},
.idlect_shift = 9,
};
@@ -269,201 +245,166 @@ static struct arm_idlect1_clk armtim_ck = {
static struct arm_idlect1_clk armwdt_ck = {
.clk = {
.name = "armwdt_ck",
+ .ops = &clkops_generic,
.parent = &ck_ref,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
- .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_WDTCK,
.recalc = &omap1_watchdog_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
},
.idlect_shift = 0,
};
static struct clk arminth_ck16xx = {
.name = "arminth_ck",
+ .ops = &clkops_null,
.parent = &arm_ck,
- .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
.recalc = &followparent_recalc,
/* Note: On 16xx the frequency can be divided by 2 by programming
* ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
*
* 1510 version is in TC clocks.
*/
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk dsp_ck = {
.name = "dsp_ck",
+ .ops = &clkops_generic,
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- RATE_CKCTL,
- .enable_reg = (void __iomem *)ARM_CKCTL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_CKCTL),
.enable_bit = EN_DSPCK,
.rate_offset = CKCTL_DSPDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
};
static struct clk dspmmu_ck = {
.name = "dspmmu_ck",
+ .ops = &clkops_null,
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- RATE_CKCTL | ALWAYS_ENABLED,
.rate_offset = CKCTL_DSPMMUDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
};
static struct clk dspper_ck = {
.name = "dspper_ck",
+ .ops = &clkops_dspck,
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- RATE_CKCTL | VIRTUAL_IO_ADDRESS,
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_PERCK,
.rate_offset = CKCTL_PERDIV_OFFSET,
.recalc = &omap1_ckctl_recalc_dsp_domain,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = &omap1_clk_set_rate_dsp_domain,
- .enable = &omap1_clk_enable_dsp_domain,
- .disable = &omap1_clk_disable_dsp_domain,
};
static struct clk dspxor_ck = {
.name = "dspxor_ck",
+ .ops = &clkops_dspck,
.parent = &ck_ref,
- .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- VIRTUAL_IO_ADDRESS,
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_XORPCK,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_dsp_domain,
- .disable = &omap1_clk_disable_dsp_domain,
};
static struct clk dsptim_ck = {
.name = "dsptim_ck",
+ .ops = &clkops_dspck,
.parent = &ck_ref,
- .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- VIRTUAL_IO_ADDRESS,
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_DSPTIMCK,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_dsp_domain,
- .disable = &omap1_clk_disable_dsp_domain,
};
/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */
static struct arm_idlect1_clk tc_ck = {
.clk = {
.name = "tc_ck",
+ .ops = &clkops_null,
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
- RATE_CKCTL | RATE_PROPAGATES |
- ALWAYS_ENABLED | CLOCK_IDLE_CONTROL,
+ .flags = CLOCK_IDLE_CONTROL,
.rate_offset = CKCTL_TCDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
},
.idlect_shift = 6,
};
static struct clk arminth_ck1510 = {
.name = "arminth_ck",
+ .ops = &clkops_null,
.parent = &tc_ck.clk,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
- ALWAYS_ENABLED,
.recalc = &followparent_recalc,
/* Note: On 1510 the frequency follows TC_CK
*
* 16xx version is in MPU clocks.
*/
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk tipb_ck = {
/* No-idle controlled by "tc_ck" */
.name = "tipb_ck",
+ .ops = &clkops_null,
.parent = &tc_ck.clk,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
- ALWAYS_ENABLED,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk l3_ocpi_ck = {
/* No-idle controlled by "tc_ck" */
.name = "l3_ocpi_ck",
+ .ops = &clkops_generic,
.parent = &tc_ck.clk,
- .flags = CLOCK_IN_OMAP16XX,
- .enable_reg = (void __iomem *)ARM_IDLECT3,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_OCPI_CK,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk tc1_ck = {
.name = "tc1_ck",
+ .ops = &clkops_generic,
.parent = &tc_ck.clk,
- .flags = CLOCK_IN_OMAP16XX,
- .enable_reg = (void __iomem *)ARM_IDLECT3,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_TC1_CK,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk tc2_ck = {
.name = "tc2_ck",
+ .ops = &clkops_generic,
.parent = &tc_ck.clk,
- .flags = CLOCK_IN_OMAP16XX,
- .enable_reg = (void __iomem *)ARM_IDLECT3,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_TC2_CK,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk dma_ck = {
/* No-idle controlled by "tc_ck" */
.name = "dma_ck",
+ .ops = &clkops_null,
.parent = &tc_ck.clk,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP310 | ALWAYS_ENABLED,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk dma_lcdfree_ck = {
.name = "dma_lcdfree_ck",
+ .ops = &clkops_null,
.parent = &tc_ck.clk,
- .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct arm_idlect1_clk api_ck = {
.clk = {
.name = "api_ck",
+ .ops = &clkops_generic,
.parent = &tc_ck.clk,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
- .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_APICK,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
},
.idlect_shift = 8,
};
@@ -471,276 +412,238 @@ static struct arm_idlect1_clk api_ck = {
static struct arm_idlect1_clk lb_ck = {
.clk = {
.name = "lb_ck",
+ .ops = &clkops_generic,
.parent = &tc_ck.clk,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
- CLOCK_IDLE_CONTROL,
- .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LBCK,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
},
.idlect_shift = 4,
};
static struct clk rhea1_ck = {
.name = "rhea1_ck",
+ .ops = &clkops_null,
.parent = &tc_ck.clk,
- .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk rhea2_ck = {
.name = "rhea2_ck",
+ .ops = &clkops_null,
.parent = &tc_ck.clk,
- .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk lcd_ck_16xx = {
.name = "lcd_ck",
+ .ops = &clkops_generic,
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | RATE_CKCTL,
- .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LCDCK,
.rate_offset = CKCTL_LCDDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
};
static struct arm_idlect1_clk lcd_ck_1510 = {
.clk = {
.name = "lcd_ck",
+ .ops = &clkops_generic,
.parent = &ck_dpll1,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
- RATE_CKCTL | CLOCK_IDLE_CONTROL,
- .enable_reg = (void __iomem *)ARM_IDLECT2,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LCDCK,
.rate_offset = CKCTL_LCDDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
},
.idlect_shift = 3,
};
static struct clk uart1_1510 = {
.name = "uart1_ck",
+ .ops = &clkops_null,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 12000000,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
- ENABLE_REG_32BIT | ALWAYS_ENABLED |
- CLOCK_NO_IDLE_PARENT,
- .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 29, /* Chooses between 12MHz and 48MHz */
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct uart_clk uart1_16xx = {
.clk = {
.name = "uart1_ck",
+ .ops = &clkops_uart,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 48000000,
- .flags = CLOCK_IN_OMAP16XX | RATE_FIXED |
- ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
- .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .flags = RATE_FIXED | ENABLE_REG_32BIT |
+ CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 29,
- .enable = &omap1_clk_enable_uart_functional,
- .disable = &omap1_clk_disable_uart_functional,
},
.sysc_addr = 0xfffb0054,
};
static struct clk uart2_ck = {
.name = "uart2_ck",
+ .ops = &clkops_null,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 12000000,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP310 | ENABLE_REG_32BIT |
- ALWAYS_ENABLED | CLOCK_NO_IDLE_PARENT,
- .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 30, /* Chooses between 12MHz and 48MHz */
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk uart3_1510 = {
.name = "uart3_ck",
+ .ops = &clkops_null,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 12000000,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
- ENABLE_REG_32BIT | ALWAYS_ENABLED |
- CLOCK_NO_IDLE_PARENT,
- .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 31, /* Chooses between 12MHz and 48MHz */
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct uart_clk uart3_16xx = {
.clk = {
.name = "uart3_ck",
+ .ops = &clkops_uart,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 48000000,
- .flags = CLOCK_IN_OMAP16XX | RATE_FIXED |
- ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
- .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .flags = RATE_FIXED | ENABLE_REG_32BIT |
+ CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 31,
- .enable = &omap1_clk_enable_uart_functional,
- .disable = &omap1_clk_disable_uart_functional,
},
.sysc_addr = 0xfffb9854,
};
static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
.name = "usb_clko",
+ .ops = &clkops_generic,
/* Direct from ULPD, no parent */
.rate = 6000000,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT,
- .enable_reg = (void __iomem *)ULPD_CLOCK_CTRL,
+ .flags = RATE_FIXED | ENABLE_REG_32BIT,
+ .enable_reg = OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL),
.enable_bit = USB_MCLK_EN_BIT,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk usb_hhc_ck1510 = {
.name = "usb_hhc_ck",
+ .ops = &clkops_generic,
/* Direct from ULPD, no parent */
.rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
- RATE_FIXED | ENABLE_REG_32BIT,
- .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .flags = RATE_FIXED | ENABLE_REG_32BIT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = USB_HOST_HHC_UHOST_EN,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk usb_hhc_ck16xx = {
.name = "usb_hhc_ck",
+ .ops = &clkops_generic,
/* Direct from ULPD, no parent */
.rate = 48000000,
/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
- .flags = CLOCK_IN_OMAP16XX |
- RATE_FIXED | ENABLE_REG_32BIT,
- .enable_reg = (void __iomem *)OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
+ .flags = RATE_FIXED | ENABLE_REG_32BIT,
+ .enable_reg = OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */
.enable_bit = 8 /* UHOST_EN */,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk usb_dc_ck = {
.name = "usb_dc_ck",
+ .ops = &clkops_generic,
/* Direct from ULPD, no parent */
.rate = 48000000,
- .flags = CLOCK_IN_OMAP16XX | RATE_FIXED,
- .enable_reg = (void __iomem *)SOFT_REQ_REG,
+ .flags = RATE_FIXED,
+ .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 4,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk mclk_1510 = {
.name = "mclk",
+ .ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.rate = 12000000,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
- .enable_reg = (void __iomem *)SOFT_REQ_REG,
- .enable_bit = 6,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
+ .flags = RATE_FIXED,
+ .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
+ .enable_bit = 6,
};
static struct clk mclk_16xx = {
.name = "mclk",
+ .ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
- .flags = CLOCK_IN_OMAP16XX,
- .enable_reg = (void __iomem *)COM_CLK_DIV_CTRL_SEL,
+ .enable_reg = OMAP1_IO_ADDRESS(COM_CLK_DIV_CTRL_SEL),
.enable_bit = COM_ULPD_PLL_CLK_REQ,
.set_rate = &omap1_set_ext_clk_rate,
.round_rate = &omap1_round_ext_clk_rate,
.init = &omap1_init_ext_clk,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk bclk_1510 = {
.name = "bclk",
+ .ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.rate = 12000000,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | RATE_FIXED,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
+ .flags = RATE_FIXED,
};
static struct clk bclk_16xx = {
.name = "bclk",
+ .ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
- .flags = CLOCK_IN_OMAP16XX,
- .enable_reg = (void __iomem *)SWD_CLK_DIV_CTRL_SEL,
+ .enable_reg = OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL),
.enable_bit = SWD_ULPD_PLL_CLK_REQ,
.set_rate = &omap1_set_ext_clk_rate,
.round_rate = &omap1_round_ext_clk_rate,
.init = &omap1_init_ext_clk,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk mmc1_ck = {
.name = "mmc_ck",
+ .ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
.parent = &armper_ck.clk,
.rate = 48000000,
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP310 | RATE_FIXED | ENABLE_REG_32BIT |
- CLOCK_NO_IDLE_PARENT,
- .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .flags = RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 23,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk mmc2_ck = {
.name = "mmc_ck",
.id = 1,
+ .ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
.parent = &armper_ck.clk,
.rate = 48000000,
- .flags = CLOCK_IN_OMAP16XX |
- RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
- .enable_reg = (void __iomem *)MOD_CONF_CTRL_0,
+ .flags = RATE_FIXED | ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 20,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk virtual_ck_mpu = {
.name = "mpu",
- .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- CLOCK_IN_OMAP310 | VIRTUAL_CLOCK | ALWAYS_ENABLED,
+ .ops = &clkops_null,
.parent = &arm_ck, /* Is smarter alias for */
.recalc = &followparent_recalc,
.set_rate = &omap1_select_table_rate,
.round_rate = &omap1_round_to_table_rate,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
@@ -748,78 +651,19 @@ remains active during MPU idle whenever this is enabled */
static struct clk i2c_fck = {
.name = "i2c_fck",
.id = 1,
- .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
- VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
- ALWAYS_ENABLED,
+ .ops = &clkops_null,
+ .flags = CLOCK_NO_IDLE_PARENT,
.parent = &armxor_ck.clk,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
};
static struct clk i2c_ick = {
.name = "i2c_ick",
.id = 1,
- .flags = CLOCK_IN_OMAP16XX |
- VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT |
- ALWAYS_ENABLED,
+ .ops = &clkops_null,
+ .flags = CLOCK_NO_IDLE_PARENT,
.parent = &armper_ck.clk,
.recalc = &followparent_recalc,
- .enable = &omap1_clk_enable_generic,
- .disable = &omap1_clk_disable_generic,
-};
-
-static struct clk * onchip_clks[] = {
- /* non-ULPD clocks */
- &ck_ref,
- &ck_dpll1,
- /* CK_GEN1 clocks */
- &ck_dpll1out.clk,
- &sossi_ck,
- &arm_ck,
- &armper_ck.clk,
- &arm_gpio_ck,
- &armxor_ck.clk,
- &armtim_ck.clk,
- &armwdt_ck.clk,
- &arminth_ck1510, &arminth_ck16xx,
- /* CK_GEN2 clocks */
- &dsp_ck,
- &dspmmu_ck,
- &dspper_ck,
- &dspxor_ck,
- &dsptim_ck,
- /* CK_GEN3 clocks */
- &tc_ck.clk,
- &tipb_ck,
- &l3_ocpi_ck,
- &tc1_ck,
- &tc2_ck,
- &dma_ck,
- &dma_lcdfree_ck,
- &api_ck.clk,
- &lb_ck.clk,
- &rhea1_ck,
- &rhea2_ck,
- &lcd_ck_16xx,
- &lcd_ck_1510.clk,
- /* ULPD clocks */
- &uart1_1510,
- &uart1_16xx.clk,
- &uart2_ck,
- &uart3_1510,
- &uart3_16xx.clk,
- &usb_clko,
- &usb_hhc_ck1510, &usb_hhc_ck16xx,
- &usb_dc_ck,
- &mclk_1510, &mclk_16xx,
- &bclk_1510, &bclk_16xx,
- &mmc1_ck,
- &mmc2_ck,
- /* Virtual clocks */
- &virtual_ck_mpu,
- &i2c_fck,
- &i2c_ick,
};
#endif
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index ba5d7c08dc17..bbbaeb0abcd3 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -86,7 +86,7 @@ static struct resource mbox_resources[] = {
};
static struct platform_device mbox_device = {
- .name = "mailbox",
+ .name = "omap1-mailbox",
.id = -1,
.num_resources = ARRAY_SIZE(mbox_resources),
.resource = mbox_resources,
diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c
index 89bb8756f450..4ef26faf083e 100644
--- a/arch/arm/mach-omap1/id.c
+++ b/arch/arm/mach-omap1/id.c
@@ -38,6 +38,7 @@ static struct omap_id omap_ids[] __initdata = {
{ .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000},
{ .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
{ .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
+ { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320500, .type = 0x08500000},
{ .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
{ .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000},
{ .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000},
@@ -77,7 +78,7 @@ static u16 __init omap_get_jtag_id(void)
prod_id = omap_readl(OMAP_PRODUCTION_ID_1);
omap_id = omap_readl(OMAP32_ID_1);
- /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */
+ /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730/850 */
if (((prod_id >> 20) == 0) || (prod_id == omap_id))
prod_id = 0;
else
@@ -178,6 +179,7 @@ void __init omap_check_revision(void)
switch (cpu_type) {
case 0x07:
+ case 0x08:
omap_revision |= 0x07;
break;
case 0x03:
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index 4c3e582f3d3c..3afe540149f7 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -52,6 +52,22 @@ static struct map_desc omap730_io_desc[] __initdata = {
};
#endif
+#ifdef CONFIG_ARCH_OMAP850
+static struct map_desc omap850_io_desc[] __initdata = {
+ {
+ .virtual = OMAP850_DSP_BASE,
+ .pfn = __phys_to_pfn(OMAP850_DSP_START),
+ .length = OMAP850_DSP_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = OMAP850_DSPREG_BASE,
+ .pfn = __phys_to_pfn(OMAP850_DSPREG_START),
+ .length = OMAP850_DSPREG_SIZE,
+ .type = MT_DEVICE
+ }
+};
+#endif
+
#ifdef CONFIG_ARCH_OMAP15XX
static struct map_desc omap1510_io_desc[] __initdata = {
{
@@ -109,6 +125,13 @@ void __init omap1_map_common_io(void)
iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc));
}
#endif
+
+#ifdef CONFIG_ARCH_OMAP850
+ if (cpu_is_omap850()) {
+ iotable_init(omap850_io_desc, ARRAY_SIZE(omap850_io_desc));
+ }
+#endif
+
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap15xx()) {
iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index 9ad5197075ff..de03c8448994 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -145,6 +145,14 @@ static struct omap_irq_bank omap730_irq_banks[] = {
};
#endif
+#ifdef CONFIG_ARCH_OMAP850
+static struct omap_irq_bank omap850_irq_banks[] = {
+ { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f },
+ { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 },
+ { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0x800040f3 },
+};
+#endif
+
#ifdef CONFIG_ARCH_OMAP15XX
static struct omap_irq_bank omap1510_irq_banks[] = {
{ .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff },
@@ -184,6 +192,12 @@ void __init omap_init_irq(void)
irq_bank_count = ARRAY_SIZE(omap730_irq_banks);
}
#endif
+#ifdef CONFIG_ARCH_OMAP850
+ if (cpu_is_omap850()) {
+ irq_banks = omap850_irq_banks;
+ irq_bank_count = ARRAY_SIZE(omap850_irq_banks);
+ }
+#endif
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
irq_banks = omap1510_irq_banks;
@@ -214,9 +228,8 @@ void __init omap_init_irq(void)
irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET);
/* Enable interrupts in global mask */
- if (cpu_is_omap730()) {
+ if (cpu_is_omap7xx())
irq_bank_writel(0x0, 0, IRQ_GMR_REG_OFFSET);
- }
/* Install the interrupt handlers for each bank */
for (i = 0; i < irq_bank_count; i++) {
@@ -236,6 +249,8 @@ void __init omap_init_irq(void)
if (cpu_is_omap730())
omap_unmask_irq(INT_730_IH2_IRQ);
+ else if (cpu_is_omap850())
+ omap_unmask_irq(INT_850_IH2_IRQ);
else if (cpu_is_omap15xx())
omap_unmask_irq(INT_1510_IH2_IRQ);
else if (cpu_is_omap16xx())
diff --git a/arch/arm/mach-omap1/mailbox.c b/arch/arm/mach-omap1/mailbox.c
index 59abbf331a96..0af4d6c85b47 100644
--- a/arch/arm/mach-omap1/mailbox.c
+++ b/arch/arm/mach-omap1/mailbox.c
@@ -1,7 +1,7 @@
/*
* Mailbox reservation modules for DSP
*
- * Copyright (C) 2006 Nokia Corporation
+ * Copyright (C) 2006-2009 Nokia Corporation
* Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -27,7 +27,7 @@
#define MAILBOX_DSP2ARM1_Flag 0x1c
#define MAILBOX_DSP2ARM2_Flag 0x20
-unsigned long mbox_base;
+static void __iomem *mbox_base;
struct omap_mbox1_fifo {
unsigned long cmd;
@@ -40,14 +40,14 @@ struct omap_mbox1_priv {
struct omap_mbox1_fifo rx_fifo;
};
-static inline int mbox_read_reg(unsigned int reg)
+static inline int mbox_read_reg(size_t ofs)
{
- return __raw_readw(mbox_base + reg);
+ return __raw_readw(mbox_base + ofs);
}
-static inline void mbox_write_reg(unsigned int val, unsigned int reg)
+static inline void mbox_write_reg(u32 val, size_t ofs)
{
- __raw_writew(val, mbox_base + reg);
+ __raw_writew(val, mbox_base + ofs);
}
/* msg */
@@ -143,7 +143,7 @@ struct omap_mbox mbox_dsp_info = {
};
EXPORT_SYMBOL(mbox_dsp_info);
-static int __init omap1_mbox_probe(struct platform_device *pdev)
+static int __devinit omap1_mbox_probe(struct platform_device *pdev)
{
struct resource *res;
int ret = 0;
@@ -170,12 +170,10 @@ static int __init omap1_mbox_probe(struct platform_device *pdev)
}
mbox_dsp_info.irq = res->start;
- ret = omap_mbox_register(&mbox_dsp_info);
-
- return ret;
+ return omap_mbox_register(&pdev->dev, &mbox_dsp_info);
}
-static int omap1_mbox_remove(struct platform_device *pdev)
+static int __devexit omap1_mbox_remove(struct platform_device *pdev)
{
omap_mbox_unregister(&mbox_dsp_info);
@@ -184,9 +182,9 @@ static int omap1_mbox_remove(struct platform_device *pdev)
static struct platform_driver omap1_mbox_driver = {
.probe = omap1_mbox_probe,
- .remove = omap1_mbox_remove,
+ .remove = __devexit_p(omap1_mbox_remove),
.driver = {
- .name = "mailbox",
+ .name = "omap1-mailbox",
},
};
@@ -203,4 +201,7 @@ static void __exit omap1_mbox_exit(void)
module_init(omap1_mbox_init);
module_exit(omap1_mbox_exit);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("omap mailbox: omap1 architecture specific functions");
+MODULE_AUTHOR("Hiroshi DOYU" <Hiroshi.DOYU@nokia.com>);
+MODULE_ALIAS("platform:omap1-mailbox");
diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
index 575ba31295cf..d040c3f1027f 100644
--- a/arch/arm/mach-omap1/mcbsp.c
+++ b/arch/arm/mach-omap1/mcbsp.c
@@ -28,9 +28,9 @@
#define DPS_RSTCT2_PER_EN (1 << 0)
#define DSP_RSTCT2_WD_PER_EN (1 << 1)
-#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
-const char *clk_names[] = { "dsp_ck", "api_ck", "dspxor_ck" };
-#endif
+static int dsp_use;
+static struct clk *api_clk;
+static struct clk *dsp_clk;
static void omap1_mcbsp_request(unsigned int id)
{
@@ -39,20 +39,40 @@ static void omap1_mcbsp_request(unsigned int id)
* are DSP public peripherals.
*/
if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
- omap_dsp_request_mem();
- /*
- * DSP external peripheral reset
- * FIXME: This should be moved to dsp code
- */
- __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
- DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
+ if (dsp_use++ == 0) {
+ api_clk = clk_get(NULL, "api_clk");
+ dsp_clk = clk_get(NULL, "dsp_clk");
+ if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
+ clk_enable(api_clk);
+ clk_enable(dsp_clk);
+
+ omap_dsp_request_mem();
+ /*
+ * DSP external peripheral reset
+ * FIXME: This should be moved to dsp code
+ */
+ __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
+ DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
+ }
+ }
}
}
static void omap1_mcbsp_free(unsigned int id)
{
- if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
- omap_dsp_release_mem();
+ if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
+ if (--dsp_use == 0) {
+ omap_dsp_release_mem();
+ if (!IS_ERR(api_clk)) {
+ clk_disable(api_clk);
+ clk_put(api_clk);
+ }
+ if (!IS_ERR(dsp_clk)) {
+ clk_disable(dsp_clk);
+ clk_put(dsp_clk);
+ }
+ }
+ }
}
static struct omap_mcbsp_ops omap1_mcbsp_ops = {
@@ -94,8 +114,6 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
.rx_irq = INT_McBSP1RX,
.tx_irq = INT_McBSP1TX,
.ops = &omap1_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 3,
},
{
.phys_base = OMAP1510_MCBSP2_BASE,
@@ -112,8 +130,6 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
.rx_irq = INT_McBSP3RX,
.tx_irq = INT_McBSP3TX,
.ops = &omap1_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 3,
},
};
#define OMAP15XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap15xx_mcbsp_pdata)
@@ -131,8 +147,6 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
.rx_irq = INT_McBSP1RX,
.tx_irq = INT_McBSP1TX,
.ops = &omap1_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 3,
},
{
.phys_base = OMAP1610_MCBSP2_BASE,
@@ -149,8 +163,6 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
.rx_irq = INT_McBSP3RX,
.tx_irq = INT_McBSP3TX,
.ops = &omap1_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 3,
},
};
#define OMAP16XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap16xx_mcbsp_pdata)
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
index 062c905c2ba6..721e0d9d8b1d 100644
--- a/arch/arm/mach-omap1/mux.c
+++ b/arch/arm/mach-omap1/mux.c
@@ -58,6 +58,25 @@ MUX_CFG_730("W17_730_USB_VBUSI", 2, 29, 0, 28, 0, 0)
#define OMAP730_PINS_SZ 0
#endif /* CONFIG_ARCH_OMAP730 */
+#ifdef CONFIG_ARCH_OMAP850
+struct pin_config __initdata_or_module omap850_pins[] = {
+MUX_CFG_850("E2_850_KBR0", 12, 21, 0, 20, 1, 0)
+MUX_CFG_850("J7_850_KBR1", 12, 25, 0, 24, 1, 0)
+MUX_CFG_850("E1_850_KBR2", 12, 29, 0, 28, 1, 0)
+MUX_CFG_850("F3_850_KBR3", 13, 1, 0, 0, 1, 0)
+MUX_CFG_850("D2_850_KBR4", 13, 5, 0, 4, 1, 0)
+MUX_CFG_850("C2_850_KBC0", 13, 9, 0, 8, 1, 0)
+MUX_CFG_850("D3_850_KBC1", 13, 13, 0, 12, 1, 0)
+MUX_CFG_850("E4_850_KBC2", 13, 17, 0, 16, 1, 0)
+MUX_CFG_850("F4_850_KBC3", 13, 21, 0, 20, 1, 0)
+MUX_CFG_850("E3_850_KBC4", 13, 25, 0, 24, 1, 0)
+
+MUX_CFG_850("AA17_850_USB_DM", 2, 21, 0, 20, 0, 0)
+MUX_CFG_850("W16_850_USB_PU_EN", 2, 25, 0, 24, 0, 0)
+MUX_CFG_850("W17_850_USB_VBUSI", 2, 29, 0, 28, 0, 0)
+};
+#endif
+
#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
static struct pin_config __initdata_or_module omap1xxx_pins[] = {
/*
@@ -419,6 +438,11 @@ int __init_or_module omap1_cfg_reg(const struct pin_config *cfg)
printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n",
cfg->pull_name, cfg->pull_reg, pull_orig, pull);
}
+
+#ifdef CONFIG_ARCH_OMAP850
+ omap_mux_register(omap850_pins, ARRAY_SIZE(omap850_pins));
+#endif
+
#endif
#ifdef CONFIG_OMAP_MUX_ERRORS
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index 0002084e0655..842090b148f1 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -121,6 +121,13 @@ void __init omap_serial_init(void)
serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2;
}
+ if (cpu_is_omap850()) {
+ serial_platform_data[0].regshift = 0;
+ serial_platform_data[1].regshift = 0;
+ serial_platform_data[0].irq = INT_850_UART_MODEM_1;
+ serial_platform_data[1].irq = INT_850_UART_MODEM_IRDA_2;
+ }
+
if (cpu_is_omap15xx()) {
serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16;
serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16;
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 3754b79092ab..64ab386a65c7 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -58,4 +58,12 @@ config MACH_OVERO
config MACH_OMAP3_PANDORA
bool "OMAP3 Pandora"
- depends on ARCH_OMAP3 && ARCH_OMAP34XX \ No newline at end of file
+ depends on ARCH_OMAP3 && ARCH_OMAP34XX
+
+config MACH_OMAP_3430SDP
+ bool "OMAP 3430 SDP board"
+ depends on ARCH_OMAP3 && ARCH_OMAP34XX
+
+config MACH_NOKIA_RX51
+ bool "Nokia RX-51 board"
+ depends on ARCH_OMAP3 && ARCH_OMAP34XX
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index bbd12bc10fdc..c49d9bfa3abd 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -3,7 +3,7 @@
#
# Common support
-obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \
+obj-y := irq.o id.o io.o sdrc.o control.o prcm.o clock.o mux.o \
devices.o serial.o gpmc.o timer-gp.o powerdomain.o \
clockdomain.o
@@ -14,6 +14,10 @@ obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o
obj-$(CONFIG_ARCH_OMAP2430) += sram243x.o
obj-$(CONFIG_ARCH_OMAP3) += sram34xx.o
+# SMS/SDRC
+obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
+# obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o
+
# Power Management
ifeq ($(CONFIG_PM),y)
obj-y += pm.o
@@ -38,4 +42,14 @@ obj-$(CONFIG_MACH_OVERO) += board-overo.o \
mmc-twl4030.o
obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \
mmc-twl4030.o
+obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \
+ mmc-twl4030.o
+obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \
+ board-rx51-peripherals.o \
+ mmc-twl4030.o
+
+# Platform specific device init code
+ifeq ($(CONFIG_USB_MUSB_SOC),y)
+obj-y += usb-musb.o
+endif
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 83fa37211d77..22143651037e 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -35,12 +35,16 @@
#include <mach/board.h>
#include <mach/common.h>
#include <mach/gpmc.h>
+#include <mach/usb.h>
#include "mmc-twl4030.h"
+#define SDP2430_CS0_BASE 0x04000000
#define SDP2430_FLASH_CS 0
#define SDP2430_SMC91X_CS 5
+#define SDP2430_ETHR_GPIO_IRQ 149
+
static struct mtd_partition sdp2430_partitions[] = {
/* bootloader (U-Boot, etc) in first sector */
{
@@ -102,8 +106,8 @@ static struct resource sdp2430_smc91x_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
- .end = OMAP_GPIO_IRQ(OMAP24XX_ETHR_GPIO_IRQ),
+ .start = OMAP_GPIO_IRQ(SDP2430_ETHR_GPIO_IRQ),
+ .end = OMAP_GPIO_IRQ(SDP2430_ETHR_GPIO_IRQ),
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
},
};
@@ -170,13 +174,13 @@ static inline void __init sdp2430_init_smc91x(void)
sdp2430_smc91x_resources[0].end = cs_mem_base + 0x30f;
udelay(100);
- if (gpio_request(OMAP24XX_ETHR_GPIO_IRQ, "SMC91x irq") < 0) {
+ if (gpio_request(SDP2430_ETHR_GPIO_IRQ, "SMC91x irq") < 0) {
printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
- OMAP24XX_ETHR_GPIO_IRQ);
+ SDP2430_ETHR_GPIO_IRQ);
gpmc_cs_free(eth_cs);
goto out;
}
- gpio_direction_input(OMAP24XX_ETHR_GPIO_IRQ);
+ gpio_direction_input(SDP2430_ETHR_GPIO_IRQ);
out:
clk_disable(gpmc_fck);
@@ -185,7 +189,7 @@ out:
static void __init omap_2430sdp_init_irq(void)
{
- omap2_init_common_hw();
+ omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
sdp2430_init_smc91x();
@@ -251,6 +255,7 @@ static void __init omap_2430sdp_init(void)
omap_board_config_size = ARRAY_SIZE(sdp2430_config);
omap_serial_init();
twl4030_mmc_init(mmc);
+ usb_musb_init();
}
static void __init omap_2430sdp_map_io(void)
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
new file mode 100644
index 000000000000..ed9274972122
--- /dev/null
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -0,0 +1,542 @@
+/*
+ * linux/arch/arm/mach-omap2/board-3430sdp.c
+ *
+ * Copyright (C) 2007 Texas Instruments
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/i2c/twl4030.h>
+#include <linux/regulator/machine.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/mcspi.h>
+#include <mach/mux.h>
+#include <mach/board.h>
+#include <mach/usb.h>
+#include <mach/common.h>
+#include <mach/dma.h>
+#include <mach/gpmc.h>
+
+#include <mach/control.h>
+#include <mach/keypad.h>
+
+#include "mmc-twl4030.h"
+
+#define CONFIG_DISABLE_HFCLK 1
+
+#define SDP3430_ETHR_GPIO_IRQ_SDPV1 29
+#define SDP3430_ETHR_GPIO_IRQ_SDPV2 6
+#define SDP3430_SMC91X_CS 3
+
+#define SDP3430_TS_GPIO_IRQ_SDPV1 3
+#define SDP3430_TS_GPIO_IRQ_SDPV2 2
+
+#define ENABLE_VAUX3_DEDICATED 0x03
+#define ENABLE_VAUX3_DEV_GRP 0x20
+
+#define TWL4030_MSECURE_GPIO 22
+
+static struct resource sdp3430_smc91x_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct platform_device sdp3430_smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(sdp3430_smc91x_resources),
+ .resource = sdp3430_smc91x_resources,
+};
+
+static int sdp3430_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_A),
+ KEY(0, 3, KEY_B),
+ KEY(0, 4, KEY_C),
+ KEY(1, 0, KEY_DOWN),
+ KEY(1, 1, KEY_UP),
+ KEY(1, 2, KEY_E),
+ KEY(1, 3, KEY_F),
+ KEY(1, 4, KEY_G),
+ KEY(2, 0, KEY_ENTER),
+ KEY(2, 1, KEY_I),
+ KEY(2, 2, KEY_J),
+ KEY(2, 3, KEY_K),
+ KEY(2, 4, KEY_3),
+ KEY(3, 0, KEY_M),
+ KEY(3, 1, KEY_N),
+ KEY(3, 2, KEY_O),
+ KEY(3, 3, KEY_P),
+ KEY(3, 4, KEY_Q),
+ KEY(4, 0, KEY_R),
+ KEY(4, 1, KEY_4),
+ KEY(4, 2, KEY_T),
+ KEY(4, 3, KEY_U),
+ KEY(4, 4, KEY_D),
+ KEY(5, 0, KEY_V),
+ KEY(5, 1, KEY_W),
+ KEY(5, 2, KEY_L),
+ KEY(5, 3, KEY_S),
+ KEY(5, 4, KEY_H),
+ 0
+};
+
+static struct twl4030_keypad_data sdp3430_kp_data = {
+ .rows = 5,
+ .cols = 6,
+ .keymap = sdp3430_keymap,
+ .keymapsize = ARRAY_SIZE(sdp3430_keymap),
+ .rep = 1,
+};
+
+static int ts_gpio; /* Needed for ads7846_get_pendown_state */
+
+/**
+ * @brief ads7846_dev_init : Requests & sets GPIO line for pen-irq
+ *
+ * @return - void. If request gpio fails then Flag KERN_ERR.
+ */
+static void ads7846_dev_init(void)
+{
+ if (gpio_request(ts_gpio, "ADS7846 pendown") < 0) {
+ printk(KERN_ERR "can't get ads746 pen down GPIO\n");
+ return;
+ }
+
+ gpio_direction_input(ts_gpio);
+
+ omap_set_gpio_debounce(ts_gpio, 1);
+ omap_set_gpio_debounce_time(ts_gpio, 0xa);
+}
+
+static int ads7846_get_pendown_state(void)
+{
+ return !gpio_get_value(ts_gpio);
+}
+
+static struct ads7846_platform_data tsc2046_config __initdata = {
+ .get_pendown_state = ads7846_get_pendown_state,
+ .keep_vref_on = 1,
+};
+
+
+static struct omap2_mcspi_device_config tsc2046_mcspi_config = {
+ .turbo_mode = 0,
+ .single_channel = 1, /* 0: slave, 1: master */
+};
+
+static struct spi_board_info sdp3430_spi_board_info[] __initdata = {
+ [0] = {
+ /*
+ * TSC2046 operates at a max freqency of 2MHz, so
+ * operate slightly below at 1.5MHz
+ */
+ .modalias = "ads7846",
+ .bus_num = 1,
+ .chip_select = 0,
+ .max_speed_hz = 1500000,
+ .controller_data = &tsc2046_mcspi_config,
+ .irq = 0,
+ .platform_data = &tsc2046_config,
+ },
+};
+
+static struct platform_device sdp3430_lcd_device = {
+ .name = "sdp2430_lcd",
+ .id = -1,
+};
+
+static struct regulator_consumer_supply sdp3430_vdac_supply = {
+ .supply = "vdac",
+ .dev = &sdp3430_lcd_device.dev,
+};
+
+static struct regulator_consumer_supply sdp3430_vdvi_supply = {
+ .supply = "vdvi",
+ .dev = &sdp3430_lcd_device.dev,
+};
+
+static struct platform_device *sdp3430_devices[] __initdata = {
+ &sdp3430_smc91x_device,
+ &sdp3430_lcd_device,
+};
+
+static inline void __init sdp3430_init_smc91x(void)
+{
+ int eth_cs;
+ unsigned long cs_mem_base;
+ int eth_gpio = 0;
+
+ eth_cs = SDP3430_SMC91X_CS;
+
+ if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
+ printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
+ return;
+ }
+
+ sdp3430_smc91x_resources[0].start = cs_mem_base + 0x300;
+ sdp3430_smc91x_resources[0].end = cs_mem_base + 0x30f;
+ udelay(100);
+
+ if (omap_rev() > OMAP3430_REV_ES1_0)
+ eth_gpio = SDP3430_ETHR_GPIO_IRQ_SDPV2;
+ else
+ eth_gpio = SDP3430_ETHR_GPIO_IRQ_SDPV1;
+
+ sdp3430_smc91x_resources[1].start = gpio_to_irq(eth_gpio);
+
+ if (gpio_request(eth_gpio, "SMC91x irq") < 0) {
+ printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
+ eth_gpio);
+ return;
+ }
+ gpio_direction_input(eth_gpio);
+}
+
+static void __init omap_3430sdp_init_irq(void)
+{
+ omap2_init_common_hw(NULL);
+ omap_init_irq();
+ omap_gpio_init();
+ sdp3430_init_smc91x();
+}
+
+static struct omap_uart_config sdp3430_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_lcd_config sdp3430_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel sdp3430_config[] __initdata = {
+ { OMAP_TAG_UART, &sdp3430_uart_config },
+ { OMAP_TAG_LCD, &sdp3430_lcd_config },
+};
+
+static int sdp3430_batt_table[] = {
+/* 0 C*/
+30800, 29500, 28300, 27100,
+26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900,
+17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100,
+11600, 11200, 10800, 10400, 10000, 9630, 9280, 8950, 8620, 8310,
+8020, 7730, 7460, 7200, 6950, 6710, 6470, 6250, 6040, 5830,
+5640, 5450, 5260, 5090, 4920, 4760, 4600, 4450, 4310, 4170,
+4040, 3910, 3790, 3670, 3550
+};
+
+static struct twl4030_bci_platform_data sdp3430_bci_data = {
+ .battery_tmp_tbl = sdp3430_batt_table,
+ .tblsize = ARRAY_SIZE(sdp3430_batt_table),
+};
+
+static struct twl4030_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ /* 8 bits (default) requires S6.3 == ON,
+ * so the SIM card isn't used; else 4 bits.
+ */
+ .wires = 8,
+ .gpio_wp = 4,
+ },
+ {
+ .mmc = 2,
+ .wires = 8,
+ .gpio_wp = 7,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply sdp3430_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+static struct regulator_consumer_supply sdp3430_vsim_supply = {
+ .supply = "vmmc_aux",
+};
+
+static struct regulator_consumer_supply sdp3430_vmmc2_supply = {
+ .supply = "vmmc",
+};
+
+static int sdp3430_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ /* gpio + 0 is "mmc0_cd" (input/IRQ),
+ * gpio + 1 is "mmc1_cd" (input/IRQ)
+ */
+ mmc[0].gpio_cd = gpio + 0;
+ mmc[1].gpio_cd = gpio + 1;
+ twl4030_mmc_init(mmc);
+
+ /* link regulators to MMC adapters ... we "know" the
+ * regulators will be set up only *after* we return.
+ */
+ sdp3430_vmmc1_supply.dev = mmc[0].dev;
+ sdp3430_vsim_supply.dev = mmc[0].dev;
+ sdp3430_vmmc2_supply.dev = mmc[1].dev;
+
+ /* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */
+ gpio_request(gpio + 7, "sub_lcd_en_bkl");
+ gpio_direction_output(gpio + 7, 0);
+
+ /* gpio + 15 is "sub_lcd_nRST" (output) */
+ gpio_request(gpio + 15, "sub_lcd_nRST");
+ gpio_direction_output(gpio + 15, 0);
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data sdp3430_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .pulldowns = BIT(2) | BIT(6) | BIT(8) | BIT(13)
+ | BIT(16) | BIT(17),
+ .setup = sdp3430_twl_gpio_setup,
+};
+
+static struct twl4030_usb_data sdp3430_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_madc_platform_data sdp3430_madc_data = {
+ .irq_line = 1,
+};
+
+/*
+ * Apply all the fixed voltages since most versions of U-Boot
+ * don't bother with that initialization.
+ */
+
+/* VAUX1 for mainboard (irda and sub-lcd) */
+static struct regulator_init_data sdp3430_vaux1 = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VAUX2 for camera module */
+static struct regulator_init_data sdp3430_vaux2 = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VAUX3 for LCD board */
+static struct regulator_init_data sdp3430_vaux3 = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VAUX4 for OMAP VDD_CSI2 (camera) */
+static struct regulator_init_data sdp3430_vaux4 = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data sdp3430_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sdp3430_vmmc1_supply,
+};
+
+/* VMMC2 for MMC2 card */
+static struct regulator_init_data sdp3430_vmmc2 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 1850000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sdp3430_vmmc2_supply,
+};
+
+/* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */
+static struct regulator_init_data sdp3430_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sdp3430_vsim_supply,
+};
+
+/* VDAC for DSS driving S-Video */
+static struct regulator_init_data sdp3430_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sdp3430_vdac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data sdp3430_vpll2 = {
+ .constraints = {
+ .name = "VDVI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sdp3430_vdvi_supply,
+};
+
+static struct twl4030_platform_data sdp3430_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .bci = &sdp3430_bci_data,
+ .gpio = &sdp3430_gpio_data,
+ .madc = &sdp3430_madc_data,
+ .keypad = &sdp3430_kp_data,
+ .usb = &sdp3430_usb_data,
+
+ .vaux1 = &sdp3430_vaux1,
+ .vaux2 = &sdp3430_vaux2,
+ .vaux3 = &sdp3430_vaux3,
+ .vaux4 = &sdp3430_vaux4,
+ .vmmc1 = &sdp3430_vmmc1,
+ .vmmc2 = &sdp3430_vmmc2,
+ .vsim = &sdp3430_vsim,
+ .vdac = &sdp3430_vdac,
+ .vpll2 = &sdp3430_vpll2,
+};
+
+static struct i2c_board_info __initdata sdp3430_i2c_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("twl4030", 0x48),
+ .flags = I2C_CLIENT_WAKE,
+ .irq = INT_34XX_SYS_NIRQ,
+ .platform_data = &sdp3430_twldata,
+ },
+};
+
+static int __init omap3430_i2c_init(void)
+{
+ /* i2c1 for PMIC only */
+ omap_register_i2c_bus(1, 2600, sdp3430_i2c_boardinfo,
+ ARRAY_SIZE(sdp3430_i2c_boardinfo));
+ /* i2c2 on camera connector (for sensor control) and optional isp1301 */
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ /* i2c3 on display connector (for DVI, tfp410) */
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static void __init omap_3430sdp_init(void)
+{
+ omap3430_i2c_init();
+ platform_add_devices(sdp3430_devices, ARRAY_SIZE(sdp3430_devices));
+ omap_board_config = sdp3430_config;
+ omap_board_config_size = ARRAY_SIZE(sdp3430_config);
+ if (omap_rev() > OMAP3430_REV_ES1_0)
+ ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV2;
+ else
+ ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV1;
+ sdp3430_spi_board_info[0].irq = gpio_to_irq(ts_gpio);
+ spi_register_board_info(sdp3430_spi_board_info,
+ ARRAY_SIZE(sdp3430_spi_board_info));
+ ads7846_dev_init();
+ omap_serial_init();
+ usb_musb_init();
+}
+
+static void __init omap_3430sdp_map_io(void)
+{
+ omap2_set_globals_343x();
+ omap2_map_common_io();
+}
+
+MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
+ /* Maintainer: Syed Khasim - Texas Instruments Inc */
+ .phys_io = 0x48000000,
+ .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
+ .boot_params = 0x80000100,
+ .map_io = omap_3430sdp_map_io,
+ .init_irq = omap_3430sdp_init_irq,
+ .init_machine = omap_3430sdp_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 0a7b24ba1652..06dfba888b0c 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -51,6 +51,7 @@
#define APOLLON_FLASH_CS 0
#define APOLLON_ETH_CS 1
+#define APOLLON_ETHR_GPIO_IRQ 74
static struct mtd_partition apollon_partitions[] = {
{
@@ -249,7 +250,7 @@ out:
static void __init omap_apollon_init_irq(void)
{
- omap2_init_common_hw();
+ omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
apollon_init_smc91x();
@@ -272,7 +273,6 @@ static struct omap_lcd_config apollon_lcd_config __initdata = {
static struct omap_board_config_kernel apollon_config[] = {
{ OMAP_TAG_UART, &apollon_uart_config },
- { OMAP_TAG_USB, &apollon_usb_config },
{ OMAP_TAG_LCD, &apollon_lcd_config },
};
@@ -299,6 +299,7 @@ static void __init apollon_usb_init(void)
omap_cfg_reg(P21_242X_GPIO12);
gpio_request(12, "USB suspend");
gpio_direction_output(12, 0);
+ omap_usb_init(&apollon_usb_config);
}
static void __init omap_apollon_init(void)
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 3b34c20d1df4..3492162a65c3 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -33,7 +33,7 @@
static void __init omap_generic_init_irq(void)
{
- omap2_init_common_hw();
+ omap2_init_common_hw(NULL);
omap_init_irq();
}
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 5e9b14675b1e..a0267a9ab466 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -47,6 +47,8 @@
#define H4_FLASH_CS 0
#define H4_SMC91X_CS 1
+#define H4_ETHR_GPIO_IRQ 92
+
static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 };
static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 };
@@ -341,7 +343,7 @@ static inline void __init h4_init_debug(void)
udelay(100);
omap_cfg_reg(M15_24XX_GPIO92);
- if (debug_card_init(cs_mem_base, OMAP24XX_ETHR_GPIO_IRQ) < 0)
+ if (debug_card_init(cs_mem_base, H4_ETHR_GPIO_IRQ) < 0)
gpmc_cs_free(eth_cs);
out:
@@ -363,7 +365,7 @@ static void __init h4_init_flash(void)
static void __init omap_h4_init_irq(void)
{
- omap2_init_common_hw();
+ omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
h4_init_flash();
@@ -377,6 +379,39 @@ static struct omap_lcd_config h4_lcd_config __initdata = {
.ctrl_name = "internal",
};
+static struct omap_usb_config h4_usb_config __initdata = {
+#ifdef CONFIG_MACH_OMAP2_H4_USB1
+ /* NOTE: usb1 could also be used with 3 wire signaling */
+ .pins[1] = 4,
+#endif
+
+#ifdef CONFIG_MACH_OMAP_H4_OTG
+ /* S1.10 ON -- USB OTG port
+ * usb0 switched to Mini-AB port and isp1301 transceiver;
+ * S2.POS3 = OFF, S2.POS4 = ON ... to allow battery charging
+ */
+ .otg = 1,
+ .pins[0] = 4,
+#ifdef CONFIG_USB_GADGET_OMAP
+ /* use OTG cable, or standard A-to-MiniB */
+ .hmc_mode = 0x14, /* 0:dev/otg 1:host 2:disable */
+#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ /* use OTG cable, or NONSTANDARD (B-to-MiniB) */
+ .hmc_mode = 0x11, /* 0:host 1:host 2:disable */
+#endif /* XX */
+
+#else
+ /* S1.10 OFF -- usb "download port"
+ * usb0 switched to Mini-B port and isp1105 transceiver;
+ * S2.POS3 = ON, S2.POS4 = OFF ... to enable battery charging
+ */
+ .register_dev = 1,
+ .pins[0] = 3,
+/* .hmc_mode = 0x14,*/ /* 0:dev 1:host 2:disable */
+ .hmc_mode = 0x00, /* 0:dev|otg 1:disable 2:disable */
+#endif
+};
+
static struct omap_board_config_kernel h4_config[] = {
{ OMAP_TAG_UART, &h4_uart_config },
{ OMAP_TAG_LCD, &h4_lcd_config },
@@ -428,6 +463,7 @@ static void __init omap_h4_init(void)
platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
omap_board_config = h4_config;
omap_board_config_size = ARRAY_SIZE(h4_config);
+ omap_usb_init(&h4_usb_config);
omap_serial_init();
}
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 6031e179926b..da57b0fcda14 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -22,31 +22,35 @@
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/i2c/twl4030.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/board-ldp.h>
#include <mach/mcspi.h>
#include <mach/gpio.h>
#include <mach/board.h>
#include <mach/common.h>
#include <mach/gpmc.h>
-#include <asm/io.h>
#include <asm/delay.h>
#include <mach/control.h>
+#include <mach/usb.h>
#include "mmc-twl4030.h"
-#define SDP3430_SMC91X_CS 3
+#define LDP_SMSC911X_CS 1
+#define LDP_SMSC911X_GPIO 152
+#define DEBUG_BASE 0x08000000
+#define LDP_ETHR_START DEBUG_BASE
-static struct resource ldp_smc911x_resources[] = {
+static struct resource ldp_smsc911x_resources[] = {
[0] = {
- .start = OMAP34XX_ETHR_START,
- .end = OMAP34XX_ETHR_START + SZ_4K,
+ .start = LDP_ETHR_START,
+ .end = LDP_ETHR_START + SZ_4K,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -56,40 +60,50 @@ static struct resource ldp_smc911x_resources[] = {
},
};
-static struct platform_device ldp_smc911x_device = {
- .name = "smc911x",
+static struct smsc911x_platform_config ldp_smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device ldp_smsc911x_device = {
+ .name = "smsc911x",
.id = -1,
- .num_resources = ARRAY_SIZE(ldp_smc911x_resources),
- .resource = ldp_smc911x_resources,
+ .num_resources = ARRAY_SIZE(ldp_smsc911x_resources),
+ .resource = ldp_smsc911x_resources,
+ .dev = {
+ .platform_data = &ldp_smsc911x_config,
+ },
};
static struct platform_device *ldp_devices[] __initdata = {
- &ldp_smc911x_device,
+ &ldp_smsc911x_device,
};
-static inline void __init ldp_init_smc911x(void)
+static inline void __init ldp_init_smsc911x(void)
{
int eth_cs;
unsigned long cs_mem_base;
int eth_gpio = 0;
- eth_cs = LDP_SMC911X_CS;
+ eth_cs = LDP_SMSC911X_CS;
if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
- printk(KERN_ERR "Failed to request GPMC mem for smc911x\n");
+ printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n");
return;
}
- ldp_smc911x_resources[0].start = cs_mem_base + 0x0;
- ldp_smc911x_resources[0].end = cs_mem_base + 0xff;
+ ldp_smsc911x_resources[0].start = cs_mem_base + 0x0;
+ ldp_smsc911x_resources[0].end = cs_mem_base + 0xff;
udelay(100);
- eth_gpio = LDP_SMC911X_GPIO;
+ eth_gpio = LDP_SMSC911X_GPIO;
- ldp_smc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
+ ldp_smsc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
- if (gpio_request(eth_gpio, "smc911x irq") < 0) {
- printk(KERN_ERR "Failed to request GPIO%d for smc911x IRQ\n",
+ if (gpio_request(eth_gpio, "smsc911x irq") < 0) {
+ printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
eth_gpio);
return;
}
@@ -98,10 +112,10 @@ static inline void __init ldp_init_smc911x(void)
static void __init omap_ldp_init_irq(void)
{
- omap2_init_common_hw();
+ omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
- ldp_init_smc911x();
+ ldp_init_smsc911x();
}
static struct omap_uart_config ldp_uart_config __initdata = {
@@ -162,6 +176,7 @@ static void __init omap_ldp_init(void)
omap_board_config_size = ARRAY_SIZE(ldp_config);
omap_serial_init();
twl4030_mmc_init(mmc);
+ usb_musb_init();
}
static void __init omap_ldp_map_io(void)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index e39cd2c46cfa..744740ae1b9c 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -41,6 +41,7 @@
#include <mach/gpmc.h>
#include <mach/nand.h>
#include <mach/mux.h>
+#include <mach/usb.h>
#include "mmc-twl4030.h"
@@ -175,9 +176,6 @@ static int __init omap3_beagle_i2c_init(void)
{
omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
ARRAY_SIZE(beagle_i2c_boardinfo));
-#ifdef CONFIG_I2C2_OMAP_BEAGLE
- omap_register_i2c_bus(2, 400, NULL, 0);
-#endif
/* Bus 3 is attached to the DVI port where devices like the pico DLP
* projector don't work reliably with 400kHz */
omap_register_i2c_bus(3, 100, NULL, 0);
@@ -186,7 +184,7 @@ static int __init omap3_beagle_i2c_init(void)
static void __init omap3_beagle_init_irq(void)
{
- omap2_init_common_hw();
+ omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
}
@@ -316,6 +314,7 @@ static void __init omap3_beagle_init(void)
/* REVISIT leave DVI powered down until it's needed ... */
gpio_direction_output(170, true);
+ usb_musb_init();
omap3beagle_flash_init();
}
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index b3196107afdb..402f09c6cf10 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -34,6 +34,7 @@
#include <mach/gpio.h>
#include <mach/hardware.h>
#include <mach/mcspi.h>
+#include <mach/usb.h>
#include "mmc-twl4030.h"
@@ -53,6 +54,13 @@ static struct twl4030_hsmmc_info omap3pandora_mmc[] = {
.gpio_cd = -EINVAL,
.gpio_wp = 127,
.ext_clock = 1,
+ .transceiver = true,
+ },
+ {
+ .mmc = 3,
+ .wires = 4,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
},
{} /* Terminator */
};
@@ -110,7 +118,7 @@ static int __init omap3pandora_i2c_init(void)
static void __init omap3pandora_init_irq(void)
{
- omap2_init_common_hw();
+ omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
}
@@ -193,6 +201,7 @@ static void __init omap3pandora_init(void)
spi_register_board_info(omap3pandora_spi_board_info,
ARRAY_SIZE(omap3pandora_spi_board_info));
omap3pandora_ads7846_init();
+ usb_musb_init();
}
static void __init omap3pandora_map_io(void)
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 82b3dc557c96..b1f23bea863f 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -37,20 +37,149 @@
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
-#include <mach/board-overo.h>
#include <mach/board.h>
#include <mach/common.h>
#include <mach/gpio.h>
#include <mach/gpmc.h>
#include <mach/hardware.h>
#include <mach/nand.h>
+#include <mach/usb.h>
#include "mmc-twl4030.h"
+#define OVERO_GPIO_BT_XGATE 15
+#define OVERO_GPIO_W2W_NRESET 16
+#define OVERO_GPIO_BT_NRESET 164
+#define OVERO_GPIO_USBH_CPEN 168
+#define OVERO_GPIO_USBH_NRESET 183
+
#define NAND_BLOCK_SIZE SZ_128K
#define GPMC_CS0_BASE 0x60
#define GPMC_CS_SIZE 0x30
+#define OVERO_SMSC911X_CS 5
+#define OVERO_SMSC911X_GPIO 176
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
+ defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+
+#include <mach/mcspi.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+static struct omap2_mcspi_device_config ads7846_mcspi_config = {
+ .turbo_mode = 0,
+ .single_channel = 1, /* 0: slave, 1: master */
+};
+
+static int ads7846_get_pendown_state(void)
+{
+ return !gpio_get_value(OVERO_GPIO_PENDOWN);
+}
+
+static struct ads7846_platform_data ads7846_config = {
+ .x_max = 0x0fff,
+ .y_max = 0x0fff,
+ .x_plate_ohms = 180,
+ .pressure_max = 255,
+ .debounce_max = 10,
+ .debounce_tol = 3,
+ .debounce_rep = 1,
+ .get_pendown_state = ads7846_get_pendown_state,
+ .keep_vref_on = 1,
+};
+
+static struct spi_board_info overo_spi_board_info[] __initdata = {
+ {
+ .modalias = "ads7846",
+ .bus_num = 1,
+ .chip_select = 0,
+ .max_speed_hz = 1500000,
+ .controller_data = &ads7846_mcspi_config,
+ .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN),
+ .platform_data = &ads7846_config,
+ }
+};
+
+static void __init overo_ads7846_init(void)
+{
+ if ((gpio_request(OVERO_GPIO_PENDOWN, "ADS7846_PENDOWN") == 0) &&
+ (gpio_direction_input(OVERO_GPIO_PENDOWN) == 0)) {
+ gpio_export(OVERO_GPIO_PENDOWN, 0);
+ } else {
+ printk(KERN_ERR "could not obtain gpio for ADS7846_PENDOWN\n");
+ return;
+ }
+
+ spi_register_board_info(overo_spi_board_info,
+ ARRAY_SIZE(overo_spi_board_info));
+}
+
+#else
+static inline void __init overo_ads7846_init(void) { return; }
+#endif
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+
+#include <linux/smsc911x.h>
+
+static struct resource overo_smsc911x_resources[] = {
+ {
+ .name = "smsc911x-memory",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct smsc911x_platform_config overo_smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT ,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device overo_smsc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(overo_smsc911x_resources),
+ .resource = &overo_smsc911x_resources,
+ .dev = {
+ .platform_data = &overo_smsc911x_config,
+ },
+};
+
+static inline void __init overo_init_smsc911x(void)
+{
+ unsigned long cs_mem_base;
+
+ if (gpmc_cs_request(OVERO_SMSC911X_CS, SZ_16M, &cs_mem_base) < 0) {
+ printk(KERN_ERR "Failed request for GPMC mem for smsc911x\n");
+ return;
+ }
+
+ overo_smsc911x_resources[0].start = cs_mem_base + 0x0;
+ overo_smsc911x_resources[0].end = cs_mem_base + 0xff;
+
+ if ((gpio_request(OVERO_SMSC911X_GPIO, "SMSC911X IRQ") == 0) &&
+ (gpio_direction_input(OVERO_SMSC911X_GPIO) == 0)) {
+ gpio_export(OVERO_SMSC911X_GPIO, 0);
+ } else {
+ printk(KERN_ERR "could not obtain gpio for SMSC911X IRQ\n");
+ return;
+ }
+
+ overo_smsc911x_resources[1].start = OMAP_GPIO_IRQ(OVERO_SMSC911X_GPIO);
+ overo_smsc911x_resources[1].end = 0;
+
+ platform_device_register(&overo_smsc911x_device);
+}
+
+#else
+static inline void __init overo_init_smsc911x(void) { return; }
+#endif
+
static struct mtd_partition overo_nand_partitions[] = {
{
.name = "xloader",
@@ -174,7 +303,7 @@ static int __init overo_i2c_init(void)
static void __init overo_init_irq(void)
{
- omap2_init_common_hw();
+ omap2_init_common_hw(NULL);
omap_init_irq();
omap_gpio_init();
}
@@ -209,6 +338,7 @@ static struct twl4030_hsmmc_info mmc[] __initdata = {
.wires = 4,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
+ .transceiver = true,
},
{} /* Terminator */
};
@@ -222,6 +352,9 @@ static void __init overo_init(void)
omap_serial_init();
twl4030_mmc_init(mmc);
overo_flash_init();
+ usb_musb_init();
+ overo_ads7846_init();
+ overo_init_smsc911x();
if ((gpio_request(OVERO_GPIO_W2W_NRESET,
"OVERO_GPIO_W2W_NRESET") == 0) &&
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
new file mode 100644
index 000000000000..a7381729645c
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -0,0 +1,419 @@
+/*
+ * linux/arch/arm/mach-omap2/board-rx51-flash.c
+ *
+ * Copyright (C) 2008-2009 Nokia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/i2c/twl4030.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/regulator/machine.h>
+#include <linux/gpio.h>
+
+#include <mach/mcspi.h>
+#include <mach/mux.h>
+#include <mach/board.h>
+#include <mach/common.h>
+#include <mach/dma.h>
+#include <mach/gpmc.h>
+#include <mach/keypad.h>
+
+#include "mmc-twl4030.h"
+
+
+#define SMC91X_CS 1
+#define SMC91X_GPIO_IRQ 54
+#define SMC91X_GPIO_RESET 164
+#define SMC91X_GPIO_PWRDWN 86
+
+static struct resource rx51_smc91x_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+static struct platform_device rx51_smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(rx51_smc91x_resources),
+ .resource = rx51_smc91x_resources,
+};
+
+static int rx51_keymap[] = {
+ KEY(0, 0, KEY_Q),
+ KEY(0, 1, KEY_W),
+ KEY(0, 2, KEY_E),
+ KEY(0, 3, KEY_R),
+ KEY(0, 4, KEY_T),
+ KEY(0, 5, KEY_Y),
+ KEY(0, 6, KEY_U),
+ KEY(0, 7, KEY_I),
+ KEY(1, 0, KEY_O),
+ KEY(1, 1, KEY_D),
+ KEY(1, 2, KEY_DOT),
+ KEY(1, 3, KEY_V),
+ KEY(1, 4, KEY_DOWN),
+ KEY(2, 0, KEY_P),
+ KEY(2, 1, KEY_F),
+ KEY(2, 2, KEY_UP),
+ KEY(2, 3, KEY_B),
+ KEY(2, 4, KEY_RIGHT),
+ KEY(3, 0, KEY_COMMA),
+ KEY(3, 1, KEY_G),
+ KEY(3, 2, KEY_ENTER),
+ KEY(3, 3, KEY_N),
+ KEY(4, 0, KEY_BACKSPACE),
+ KEY(4, 1, KEY_H),
+ KEY(4, 3, KEY_M),
+ KEY(4, 4, KEY_LEFTCTRL),
+ KEY(5, 1, KEY_J),
+ KEY(5, 2, KEY_Z),
+ KEY(5, 3, KEY_SPACE),
+ KEY(5, 4, KEY_LEFTSHIFT),
+ KEY(6, 0, KEY_A),
+ KEY(6, 1, KEY_K),
+ KEY(6, 2, KEY_X),
+ KEY(6, 3, KEY_SPACE),
+ KEY(6, 4, KEY_FN),
+ KEY(7, 0, KEY_S),
+ KEY(7, 1, KEY_L),
+ KEY(7, 2, KEY_C),
+ KEY(7, 3, KEY_LEFT),
+ KEY(0xff, 0, KEY_F6),
+ KEY(0xff, 1, KEY_F7),
+ KEY(0xff, 2, KEY_F8),
+ KEY(0xff, 4, KEY_F9),
+ KEY(0xff, 5, KEY_F10),
+};
+
+static struct twl4030_keypad_data rx51_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap = rx51_keymap,
+ .keymapsize = ARRAY_SIZE(rx51_keymap),
+ .rep = 1,
+};
+
+static struct platform_device *rx51_peripherals_devices[] = {
+ &rx51_smc91x_device,
+};
+
+/*
+ * Timings are taken from smsc-lan91c96-ms.pdf
+ */
+static int smc91x_init_gpmc(int cs)
+{
+ struct gpmc_timings t;
+ const int t2_r = 45; /* t2 in Figure 12.10 */
+ const int t2_w = 30; /* t2 in Figure 12.11 */
+ const int t3 = 15; /* t3 in Figure 12.10 */
+ const int t5_r = 0; /* t5 in Figure 12.10 */
+ const int t6_r = 45; /* t6 in Figure 12.10 */
+ const int t6_w = 0; /* t6 in Figure 12.11 */
+ const int t7_w = 15; /* t7 in Figure 12.11 */
+ const int t15 = 12; /* t15 in Figure 12.2 */
+ const int t20 = 185; /* t20 in Figure 12.2 */
+
+ memset(&t, 0, sizeof(t));
+
+ t.cs_on = t15;
+ t.cs_rd_off = t3 + t2_r + t5_r; /* Figure 12.10 */
+ t.cs_wr_off = t3 + t2_w + t6_w; /* Figure 12.11 */
+ t.adv_on = t3; /* Figure 12.10 */
+ t.adv_rd_off = t3 + t2_r; /* Figure 12.10 */
+ t.adv_wr_off = t3 + t2_w; /* Figure 12.11 */
+ t.oe_off = t3 + t2_r + t5_r; /* Figure 12.10 */
+ t.oe_on = t.oe_off - t6_r; /* Figure 12.10 */
+ t.we_off = t3 + t2_w + t6_w; /* Figure 12.11 */
+ t.we_on = t.we_off - t7_w; /* Figure 12.11 */
+ t.rd_cycle = t20; /* Figure 12.2 */
+ t.wr_cycle = t20; /* Figure 12.4 */
+ t.access = t3 + t2_r + t5_r; /* Figure 12.10 */
+ t.wr_access = t3 + t2_w + t6_w; /* Figure 12.11 */
+
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, GPMC_CONFIG1_DEVICESIZE_16);
+
+ return gpmc_cs_set_timings(cs, &t);
+}
+
+static void __init rx51_init_smc91x(void)
+{
+ unsigned long cs_mem_base;
+ int ret;
+
+ omap_cfg_reg(U8_34XX_GPIO54_DOWN);
+ omap_cfg_reg(G25_34XX_GPIO86_OUT);
+ omap_cfg_reg(H19_34XX_GPIO164_OUT);
+
+ if (gpmc_cs_request(SMC91X_CS, SZ_16M, &cs_mem_base) < 0) {
+ printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
+ return;
+ }
+
+ rx51_smc91x_resources[0].start = cs_mem_base + 0x300;
+ rx51_smc91x_resources[0].end = cs_mem_base + 0x30f;
+
+ smc91x_init_gpmc(SMC91X_CS);
+
+ if (gpio_request(SMC91X_GPIO_IRQ, "SMC91X irq") < 0)
+ goto free1;
+
+ gpio_direction_input(SMC91X_GPIO_IRQ);
+ rx51_smc91x_resources[1].start = gpio_to_irq(SMC91X_GPIO_IRQ);
+
+ ret = gpio_request(SMC91X_GPIO_PWRDWN, "SMC91X powerdown");
+ if (ret)
+ goto free2;
+ gpio_direction_output(SMC91X_GPIO_PWRDWN, 0);
+
+ ret = gpio_request(SMC91X_GPIO_RESET, "SMC91X reset");
+ if (ret)
+ goto free3;
+ gpio_direction_output(SMC91X_GPIO_RESET, 0);
+ gpio_set_value(SMC91X_GPIO_RESET, 1);
+ msleep(100);
+ gpio_set_value(SMC91X_GPIO_RESET, 0);
+
+ return;
+
+free3:
+ gpio_free(SMC91X_GPIO_PWRDWN);
+free2:
+ gpio_free(SMC91X_GPIO_IRQ);
+free1:
+ gpmc_cs_free(SMC91X_CS);
+
+ printk(KERN_ERR "Could not initialize smc91x\n");
+}
+
+static struct twl4030_madc_platform_data rx51_madc_data = {
+ .irq_line = 1,
+};
+
+static struct twl4030_hsmmc_info mmc[] = {
+ {
+ .name = "external",
+ .mmc = 1,
+ .wires = 4,
+ .cover_only = true,
+ .gpio_cd = 160,
+ .gpio_wp = -EINVAL,
+ },
+ {
+ .name = "internal",
+ .mmc = 2,
+ .wires = 8,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply rx51_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+static struct regulator_consumer_supply rx51_vmmc2_supply = {
+ .supply = "vmmc",
+};
+
+static struct regulator_consumer_supply rx51_vsim_supply = {
+ .supply = "vmmc_aux",
+};
+
+static struct regulator_init_data rx51_vaux1 = {
+ .constraints = {
+ .name = "V28",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data rx51_vaux2 = {
+ .constraints = {
+ .name = "VCSI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VAUX3 - adds more power to VIO_18 rail */
+static struct regulator_init_data rx51_vaux3 = {
+ .constraints = {
+ .name = "VCAM_DIG_18",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data rx51_vaux4 = {
+ .constraints = {
+ .name = "VCAM_ANA_28",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data rx51_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &rx51_vmmc1_supply,
+};
+
+static struct regulator_init_data rx51_vmmc2 = {
+ .constraints = {
+ .name = "VMMC2_30",
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &rx51_vmmc2_supply,
+};
+
+static struct regulator_init_data rx51_vsim = {
+ .constraints = {
+ .name = "VMMC2_IO_18",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &rx51_vsim_supply,
+};
+
+static struct regulator_init_data rx51_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n)
+{
+ /* FIXME this gpio setup is just a placeholder for now */
+ gpio_request(gpio + 6, "backlight_pwm");
+ gpio_direction_output(gpio + 6, 0);
+ gpio_request(gpio + 7, "speaker_en");
+ gpio_direction_output(gpio + 7, 1);
+
+ /* set up MMC adapters, linking their regulators to them */
+ twl4030_mmc_init(mmc);
+ rx51_vmmc1_supply.dev = mmc[0].dev;
+ rx51_vmmc2_supply.dev = mmc[1].dev;
+ rx51_vsim_supply.dev = mmc[1].dev;
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data rx51_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .pulldowns = BIT(0) | BIT(1) | BIT(2) | BIT(3)
+ | BIT(4) | BIT(5)
+ | BIT(8) | BIT(9) | BIT(10) | BIT(11)
+ | BIT(12) | BIT(13) | BIT(14) | BIT(15)
+ | BIT(16) | BIT(17) ,
+ .setup = rx51_twlgpio_setup,
+};
+
+static struct twl4030_platform_data rx51_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .gpio = &rx51_gpio_data,
+ .keypad = &rx51_kp_data,
+ .madc = &rx51_madc_data,
+
+ .vaux1 = &rx51_vaux1,
+ .vaux2 = &rx51_vaux2,
+ .vaux3 = &rx51_vaux3,
+ .vaux4 = &rx51_vaux4,
+ .vmmc1 = &rx51_vmmc1,
+ .vmmc2 = &rx51_vmmc2,
+ .vsim = &rx51_vsim,
+ .vdac = &rx51_vdac,
+};
+
+static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = {
+ {
+ I2C_BOARD_INFO("twl5030", 0x48),
+ .flags = I2C_CLIENT_WAKE,
+ .irq = INT_34XX_SYS_NIRQ,
+ .platform_data = &rx51_twldata,
+ },
+};
+
+static int __init rx51_i2c_init(void)
+{
+ omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1,
+ ARRAY_SIZE(rx51_peripherals_i2c_board_info_1));
+ omap_register_i2c_bus(2, 100, NULL, 0);
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+
+void __init rx51_peripherals_init(void)
+{
+ platform_add_devices(rx51_peripherals_devices,
+ ARRAY_SIZE(rx51_peripherals_devices));
+ rx51_i2c_init();
+ rx51_init_smc91x();
+}
+
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
new file mode 100644
index 000000000000..3a0daac6c839
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -0,0 +1,96 @@
+/*
+ * linux/arch/arm/mach-omap2/board-rx51.c
+ *
+ * Copyright (C) 2007, 2008 Nokia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/mcspi.h>
+#include <mach/mux.h>
+#include <mach/board.h>
+#include <mach/common.h>
+#include <mach/keypad.h>
+#include <mach/dma.h>
+#include <mach/gpmc.h>
+#include <mach/usb.h>
+
+static struct omap_uart_config rx51_uart_config = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_lcd_config rx51_lcd_config = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_fbmem_config rx51_fbmem0_config = {
+ .size = 752 * 1024,
+};
+
+static struct omap_fbmem_config rx51_fbmem1_config = {
+ .size = 752 * 1024,
+};
+
+static struct omap_fbmem_config rx51_fbmem2_config = {
+ .size = 752 * 1024,
+};
+
+static struct omap_board_config_kernel rx51_config[] = {
+ { OMAP_TAG_UART, &rx51_uart_config },
+ { OMAP_TAG_FBMEM, &rx51_fbmem0_config },
+ { OMAP_TAG_FBMEM, &rx51_fbmem1_config },
+ { OMAP_TAG_FBMEM, &rx51_fbmem2_config },
+ { OMAP_TAG_LCD, &rx51_lcd_config },
+};
+
+static void __init rx51_init_irq(void)
+{
+ omap2_init_common_hw(NULL);
+ omap_init_irq();
+ omap_gpio_init();
+}
+
+extern void __init rx51_peripherals_init(void);
+
+static void __init rx51_init(void)
+{
+ omap_board_config = rx51_config;
+ omap_board_config_size = ARRAY_SIZE(rx51_config);
+ omap_serial_init();
+ usb_musb_init();
+ rx51_peripherals_init();
+}
+
+static void __init rx51_map_io(void)
+{
+ omap2_set_globals_343x();
+ omap2_map_common_io();
+}
+
+MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
+ /* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */
+ .phys_io = 0x48000000,
+ .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
+ .boot_params = 0x80000100,
+ .map_io = rx51_map_io,
+ .init_irq = rx51_init_irq,
+ .init_machine = rx51_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index ce4d46a4a838..4247a1534411 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -26,11 +26,10 @@
#include <mach/clock.h>
#include <mach/clockdomain.h>
-#include <mach/sram.h>
#include <mach/cpu.h>
#include <asm/div64.h>
-#include "memory.h"
+#include <mach/sdrc.h>
#include "sdrc.h"
#include "clock.h"
#include "prm.h"
@@ -46,7 +45,7 @@
#define DPLL_MIN_DIVIDER 1
/* Possible error results from _dpll_test_mult */
-#define DPLL_MULT_UNDERFLOW (1 << 0)
+#define DPLL_MULT_UNDERFLOW -1
/*
* Scale factor to mitigate roundoff errors in DPLL rate rounding.
@@ -59,6 +58,16 @@
#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
(DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
+/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
+#define DPLL_FINT_BAND1_MIN 750000
+#define DPLL_FINT_BAND1_MAX 2100000
+#define DPLL_FINT_BAND2_MIN 7500000
+#define DPLL_FINT_BAND2_MAX 21000000
+
+/* _dpll_test_fint() return codes */
+#define DPLL_FINT_UNDERFLOW -1
+#define DPLL_FINT_INVALID -2
+
u8 cpu_mask;
/*-------------------------------------------------------------------------
@@ -66,6 +75,74 @@ u8 cpu_mask;
*-------------------------------------------------------------------------*/
/**
+ * _omap2xxx_clk_commit - commit clock parent/rate changes in hardware
+ * @clk: struct clk *
+ *
+ * If @clk has the DELAYED_APP flag set, meaning that parent/rate changes
+ * don't take effect until the VALID_CONFIG bit is written, write the
+ * VALID_CONFIG bit and wait for the write to complete. No return value.
+ */
+static void _omap2xxx_clk_commit(struct clk *clk)
+{
+ if (!cpu_is_omap24xx())
+ return;
+
+ if (!(clk->flags & DELAYED_APP))
+ return;
+
+ prm_write_mod_reg(OMAP24XX_VALID_CONFIG, OMAP24XX_GR_MOD,
+ OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET);
+ /* OCP barrier */
+ prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET);
+}
+
+/*
+ * _dpll_test_fint - test whether an Fint value is valid for the DPLL
+ * @clk: DPLL struct clk to test
+ * @n: divider value (N) to test
+ *
+ * Tests whether a particular divider @n will result in a valid DPLL
+ * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
+ * Correction". Returns 0 if OK, -1 if the enclosing loop can terminate
+ * (assuming that it is counting N upwards), or -2 if the enclosing loop
+ * should skip to the next iteration (again assuming N is increasing).
+ */
+static int _dpll_test_fint(struct clk *clk, u8 n)
+{
+ struct dpll_data *dd;
+ long fint;
+ int ret = 0;
+
+ dd = clk->dpll_data;
+
+ /* DPLL divider must result in a valid jitter correction val */
+ fint = clk->parent->rate / (n + 1);
+ if (fint < DPLL_FINT_BAND1_MIN) {
+
+ pr_debug("rejecting n=%d due to Fint failure, "
+ "lowering max_divider\n", n);
+ dd->max_divider = n;
+ ret = DPLL_FINT_UNDERFLOW;
+
+ } else if (fint > DPLL_FINT_BAND1_MAX &&
+ fint < DPLL_FINT_BAND2_MIN) {
+
+ pr_debug("rejecting n=%d due to Fint failure\n", n);
+ ret = DPLL_FINT_INVALID;
+
+ } else if (fint > DPLL_FINT_BAND2_MAX) {
+
+ pr_debug("rejecting n=%d due to Fint failure, "
+ "boosting min_divider\n", n);
+ dd->min_divider = n;
+ ret = DPLL_FINT_INVALID;
+
+ }
+
+ return ret;
+}
+
+/**
* omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
* @clk: OMAP clock struct ptr to use
*
@@ -120,7 +197,7 @@ void omap2_init_clksel_parent(struct clk *clk)
clk->name, clks->parent->name,
((clk->parent) ?
clk->parent->name : "NULL"));
- clk->parent = clks->parent;
+ clk_reparent(clk, clks->parent);
};
found = 1;
}
@@ -134,25 +211,52 @@ void omap2_init_clksel_parent(struct clk *clk)
return;
}
-/* Returns the DPLL rate */
+/**
+ * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
+ * @clk: struct clk * of a DPLL
+ *
+ * DPLLs can be locked or bypassed - basically, enabled or disabled.
+ * When locked, the DPLL output depends on the M and N values. When
+ * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
+ * or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
+ * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
+ * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
+ * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
+ * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
+ * if the clock @clk is not a DPLL.
+ */
u32 omap2_get_dpll_rate(struct clk *clk)
{
long long dpll_clk;
- u32 dpll_mult, dpll_div, dpll;
+ u32 dpll_mult, dpll_div, v;
struct dpll_data *dd;
dd = clk->dpll_data;
- /* REVISIT: What do we return on error? */
if (!dd)
return 0;
- dpll = __raw_readl(dd->mult_div1_reg);
- dpll_mult = dpll & dd->mult_mask;
+ /* Return bypass rate if DPLL is bypassed */
+ v = __raw_readl(dd->control_reg);
+ v &= dd->enable_mask;
+ v >>= __ffs(dd->enable_mask);
+
+ if (cpu_is_omap24xx()) {
+ if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP2XXX_EN_DPLL_FRBYPASS)
+ return dd->clk_bypass->rate;
+ } else if (cpu_is_omap34xx()) {
+ if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP3XXX_EN_DPLL_FRBYPASS)
+ return dd->clk_bypass->rate;
+ }
+
+ v = __raw_readl(dd->mult_div1_reg);
+ dpll_mult = v & dd->mult_mask;
dpll_mult >>= __ffs(dd->mult_mask);
- dpll_div = dpll & dd->div1_mask;
+ dpll_div = v & dd->div1_mask;
dpll_div >>= __ffs(dd->div1_mask);
- dpll_clk = (long long)clk->parent->rate * dpll_mult;
+ dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
do_div(dpll_clk, dpll_div + 1);
return dpll_clk;
@@ -162,14 +266,11 @@ u32 omap2_get_dpll_rate(struct clk *clk)
* Used for clocks that have the same value as the parent clock,
* divided by some factor
*/
-void omap2_fixed_divisor_recalc(struct clk *clk)
+unsigned long omap2_fixed_divisor_recalc(struct clk *clk)
{
WARN_ON(!clk->fixed_div);
- clk->rate = clk->parent->rate / clk->fixed_div;
-
- if (clk->flags & RATE_PROPAGATES)
- propagate_rate(clk);
+ return clk->parent->rate / clk->fixed_div;
}
/**
@@ -190,11 +291,10 @@ int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name)
* 24xx uses 0 to indicate not ready, and 1 to indicate ready.
* 34xx reverses this, just to keep us on our toes
*/
- if (cpu_mask & (RATE_IN_242X | RATE_IN_243X)) {
+ if (cpu_mask & (RATE_IN_242X | RATE_IN_243X))
ena = mask;
- } else if (cpu_mask & RATE_IN_343X) {
+ else if (cpu_mask & RATE_IN_343X)
ena = 0;
- }
/* Wait for lock */
while (((__raw_readl(reg) & mask) != ena) &&
@@ -228,31 +328,12 @@ static void omap2_clk_wait_ready(struct clk *clk)
* it and pull it into struct clk itself somehow.
*/
reg = clk->enable_reg;
- if ((((u32)reg & 0xff) >= CM_FCLKEN1) &&
- (((u32)reg & 0xff) <= OMAP24XX_CM_FCLKEN2))
- other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x10); /* CM_ICLKEN* */
- else if ((((u32)reg & 0xff) >= CM_ICLKEN1) &&
- (((u32)reg & 0xff) <= OMAP24XX_CM_ICLKEN4))
- other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x00); /* CM_FCLKEN* */
- else
- return;
- /* REVISIT: What are the appropriate exclusions for 34XX? */
- /* No check for DSS or cam clocks */
- if (cpu_is_omap24xx() && ((u32)reg & 0x0f) == 0) { /* CM_{F,I}CLKEN1 */
- if (clk->enable_bit == OMAP24XX_EN_DSS2_SHIFT ||
- clk->enable_bit == OMAP24XX_EN_DSS1_SHIFT ||
- clk->enable_bit == OMAP24XX_EN_CAM_SHIFT)
- return;
- }
-
- /* REVISIT: What are the appropriate exclusions for 34XX? */
- /* OMAP3: ignore DSS-mod clocks */
- if (cpu_is_omap34xx() &&
- (((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(OMAP3430_DSS_MOD, 0) ||
- ((((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(CORE_MOD, 0)) &&
- clk->enable_bit == OMAP3430_EN_SSI_SHIFT)))
- return;
+ /*
+ * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes
+ * it's just a matter of XORing the bits.
+ */
+ other_reg = (void __iomem *)((u32)reg ^ (CM_FCLKEN ^ CM_ICLKEN));
/* Check if both functional and interface clocks
* are running. */
@@ -264,18 +345,9 @@ static void omap2_clk_wait_ready(struct clk *clk)
omap2_wait_clock_ready(st_reg, bit, clk->name);
}
-/* Enables clock without considering parent dependencies or use count
- * REVISIT: Maybe change this to use clk->enable like on omap1?
- */
-int _omap2_clk_enable(struct clk *clk)
+static int omap2_dflt_clk_enable(struct clk *clk)
{
- u32 regval32;
-
- if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK))
- return 0;
-
- if (clk->enable)
- return clk->enable(clk);
+ u32 v;
if (unlikely(clk->enable_reg == NULL)) {
printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
@@ -283,33 +355,38 @@ int _omap2_clk_enable(struct clk *clk)
return 0; /* REVISIT: -EINVAL */
}
- regval32 = __raw_readl(clk->enable_reg);
+ v = __raw_readl(clk->enable_reg);
if (clk->flags & INVERT_ENABLE)
- regval32 &= ~(1 << clk->enable_bit);
+ v &= ~(1 << clk->enable_bit);
else
- regval32 |= (1 << clk->enable_bit);
- __raw_writel(regval32, clk->enable_reg);
- wmb();
-
- omap2_clk_wait_ready(clk);
+ v |= (1 << clk->enable_bit);
+ __raw_writel(v, clk->enable_reg);
+ v = __raw_readl(clk->enable_reg); /* OCP barrier */
return 0;
}
-/* Disables clock without considering parent dependencies or use count */
-void _omap2_clk_disable(struct clk *clk)
+static int omap2_dflt_clk_enable_wait(struct clk *clk)
{
- u32 regval32;
-
- if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK))
- return;
+ int ret;
- if (clk->disable) {
- clk->disable(clk);
- return;
+ if (!clk->enable_reg) {
+ printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
+ clk->name);
+ return 0; /* REVISIT: -EINVAL */
}
- if (clk->enable_reg == NULL) {
+ ret = omap2_dflt_clk_enable(clk);
+ if (ret == 0)
+ omap2_clk_wait_ready(clk);
+ return ret;
+}
+
+static void omap2_dflt_clk_disable(struct clk *clk)
+{
+ u32 v;
+
+ if (!clk->enable_reg) {
/*
* 'Independent' here refers to a clock which is not
* controlled by its parent.
@@ -319,20 +396,44 @@ void _omap2_clk_disable(struct clk *clk)
return;
}
- regval32 = __raw_readl(clk->enable_reg);
+ v = __raw_readl(clk->enable_reg);
if (clk->flags & INVERT_ENABLE)
- regval32 |= (1 << clk->enable_bit);
+ v |= (1 << clk->enable_bit);
else
- regval32 &= ~(1 << clk->enable_bit);
- __raw_writel(regval32, clk->enable_reg);
- wmb();
+ v &= ~(1 << clk->enable_bit);
+ __raw_writel(v, clk->enable_reg);
+ /* No OCP barrier needed here since it is a disable operation */
+}
+
+const struct clkops clkops_omap2_dflt_wait = {
+ .enable = omap2_dflt_clk_enable_wait,
+ .disable = omap2_dflt_clk_disable,
+};
+
+const struct clkops clkops_omap2_dflt = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+};
+
+/* Enables clock without considering parent dependencies or use count
+ * REVISIT: Maybe change this to use clk->enable like on omap1?
+ */
+static int _omap2_clk_enable(struct clk *clk)
+{
+ return clk->ops->enable(clk);
+}
+
+/* Disables clock without considering parent dependencies or use count */
+static void _omap2_clk_disable(struct clk *clk)
+{
+ clk->ops->disable(clk);
}
void omap2_clk_disable(struct clk *clk)
{
if (clk->usecount > 0 && !(--clk->usecount)) {
_omap2_clk_disable(clk);
- if (likely((u32)clk->parent))
+ if (clk->parent)
omap2_clk_disable(clk->parent);
if (clk->clkdm)
omap2_clkdm_clk_disable(clk->clkdm, clk);
@@ -345,30 +446,29 @@ int omap2_clk_enable(struct clk *clk)
int ret = 0;
if (clk->usecount++ == 0) {
- if (likely((u32)clk->parent))
- ret = omap2_clk_enable(clk->parent);
-
- if (unlikely(ret != 0)) {
- clk->usecount--;
- return ret;
- }
-
if (clk->clkdm)
omap2_clkdm_clk_enable(clk->clkdm, clk);
- ret = _omap2_clk_enable(clk);
-
- if (unlikely(ret != 0)) {
- if (clk->clkdm)
- omap2_clkdm_clk_disable(clk->clkdm, clk);
+ if (clk->parent) {
+ ret = omap2_clk_enable(clk->parent);
+ if (ret)
+ goto err;
+ }
- if (clk->parent) {
+ ret = _omap2_clk_enable(clk);
+ if (ret) {
+ if (clk->parent)
omap2_clk_disable(clk->parent);
- clk->usecount--;
- }
+
+ goto err;
}
}
+ return ret;
+err:
+ if (clk->clkdm)
+ omap2_clkdm_clk_disable(clk->clkdm, clk);
+ clk->usecount--;
return ret;
}
@@ -376,24 +476,22 @@ int omap2_clk_enable(struct clk *clk)
* Used for clocks that are part of CLKSEL_xyz governed clocks.
* REVISIT: Maybe change to use clk->enable() functions like on omap1?
*/
-void omap2_clksel_recalc(struct clk *clk)
+unsigned long omap2_clksel_recalc(struct clk *clk)
{
+ unsigned long rate;
u32 div = 0;
pr_debug("clock: recalc'ing clksel clk %s\n", clk->name);
div = omap2_clksel_get_divisor(clk);
if (div == 0)
- return;
+ return clk->rate;
- if (unlikely(clk->rate == clk->parent->rate / div))
- return;
- clk->rate = clk->parent->rate / div;
+ rate = clk->parent->rate / div;
- pr_debug("clock: new clock rate is %ld (div %d)\n", clk->rate, div);
+ pr_debug("clock: new clock rate is %ld (div %d)\n", rate, div);
- if (unlikely(clk->flags & RATE_PROPAGATES))
- propagate_rate(clk);
+ return rate;
}
/**
@@ -405,8 +503,8 @@ void omap2_clksel_recalc(struct clk *clk)
* the element associated with the supplied parent clock address.
* Returns a pointer to the struct clksel on success or NULL on error.
*/
-const struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
- struct clk *src_clk)
+static const struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
+ struct clk *src_clk)
{
const struct clksel *clks;
@@ -455,7 +553,7 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
*new_div = 1;
clks = omap2_get_clksel_by_parent(clk, clk->parent);
- if (clks == NULL)
+ if (!clks)
return ~0;
for (clkr = clks->rates; clkr->div; clkr++) {
@@ -514,7 +612,7 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
/* Given a clock and a rate apply a clock specific rounding function */
long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
{
- if (clk->round_rate != NULL)
+ if (clk->round_rate)
return clk->round_rate(clk, rate);
if (clk->flags & RATE_FIXED)
@@ -540,7 +638,7 @@ u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
const struct clksel_rate *clkr;
clks = omap2_get_clksel_by_parent(clk, clk->parent);
- if (clks == NULL)
+ if (!clks)
return 0;
for (clkr = clks->rates; clkr->div; clkr++) {
@@ -576,7 +674,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
WARN_ON(div == 0);
clks = omap2_get_clksel_by_parent(clk, clk->parent);
- if (clks == NULL)
+ if (!clks)
return ~0;
for (clkr = clks->rates; clkr->div; clkr++) {
@@ -595,23 +693,6 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
}
/**
- * omap2_get_clksel - find clksel register addr & field mask for a clk
- * @clk: struct clk to use
- * @field_mask: ptr to u32 to store the register field mask
- *
- * Returns the address of the clksel register upon success or NULL on error.
- */
-void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask)
-{
- if (unlikely((clk->clksel_reg == NULL) || (clk->clksel_mask == NULL)))
- return NULL;
-
- *field_mask = clk->clksel_mask;
-
- return clk->clksel_reg;
-}
-
-/**
* omap2_clksel_get_divisor - get current divider applied to parent clock.
* @clk: OMAP struct clk to use.
*
@@ -619,49 +700,41 @@ void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask)
*/
u32 omap2_clksel_get_divisor(struct clk *clk)
{
- u32 field_mask, field_val;
- void __iomem *div_addr;
+ u32 v;
- div_addr = omap2_get_clksel(clk, &field_mask);
- if (div_addr == NULL)
+ if (!clk->clksel_mask)
return 0;
- field_val = __raw_readl(div_addr) & field_mask;
- field_val >>= __ffs(field_mask);
+ v = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
+ v >>= __ffs(clk->clksel_mask);
- return omap2_clksel_to_divisor(clk, field_val);
+ return omap2_clksel_to_divisor(clk, v);
}
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
{
- u32 field_mask, field_val, reg_val, validrate, new_div = 0;
- void __iomem *div_addr;
+ u32 v, field_val, validrate, new_div = 0;
- validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
- if (validrate != rate)
+ if (!clk->clksel_mask)
return -EINVAL;
- div_addr = omap2_get_clksel(clk, &field_mask);
- if (div_addr == NULL)
+ validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
+ if (validrate != rate)
return -EINVAL;
field_val = omap2_divisor_to_clksel(clk, new_div);
if (field_val == ~0)
return -EINVAL;
- reg_val = __raw_readl(div_addr);
- reg_val &= ~field_mask;
- reg_val |= (field_val << __ffs(field_mask));
- __raw_writel(reg_val, div_addr);
- wmb();
+ v = __raw_readl(clk->clksel_reg);
+ v &= ~clk->clksel_mask;
+ v |= field_val << __ffs(clk->clksel_mask);
+ __raw_writel(v, clk->clksel_reg);
+ v = __raw_readl(clk->clksel_reg); /* OCP barrier */
clk->rate = clk->parent->rate / new_div;
- if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) {
- prm_write_mod_reg(OMAP24XX_VALID_CONFIG,
- OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET);
- wmb();
- }
+ _omap2xxx_clk_commit(clk);
return 0;
}
@@ -680,31 +753,24 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
return -EINVAL;
/* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
- if (clk->set_rate != NULL)
+ if (clk->set_rate)
ret = clk->set_rate(clk, rate);
- if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
- propagate_rate(clk);
-
return ret;
}
/*
* Converts encoded control register address into a full address
- * On error, *src_addr will be returned as 0.
+ * On error, the return value (parent_div) will be 0.
*/
-static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
- struct clk *src_clk, u32 *field_mask,
- struct clk *clk, u32 *parent_div)
+static u32 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk,
+ u32 *field_val)
{
const struct clksel *clks;
const struct clksel_rate *clkr;
- *parent_div = 0;
- *src_addr = NULL;
-
clks = omap2_get_clksel_by_parent(clk, src_clk);
- if (clks == NULL)
+ if (!clks)
return 0;
for (clkr = clks->rates; clkr->div; clkr++) {
@@ -722,47 +788,35 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
/* Should never happen. Add a clksel mask to the struct clk. */
WARN_ON(clk->clksel_mask == 0);
- *field_mask = clk->clksel_mask;
- *src_addr = clk->clksel_reg;
- *parent_div = clkr->div;
+ *field_val = clkr->val;
- return clkr->val;
+ return clkr->div;
}
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
{
- void __iomem *src_addr;
- u32 field_val, field_mask, reg_val, parent_div;
+ u32 field_val, v, parent_div;
- if (unlikely(clk->flags & CONFIG_PARTICIPANT))
+ if (clk->flags & CONFIG_PARTICIPANT)
return -EINVAL;
if (!clk->clksel)
return -EINVAL;
- field_val = omap2_clksel_get_src_field(&src_addr, new_parent,
- &field_mask, clk, &parent_div);
- if (src_addr == NULL)
+ parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val);
+ if (!parent_div)
return -EINVAL;
- if (clk->usecount > 0)
- omap2_clk_disable(clk);
-
/* Set new source value (previous dividers if any in effect) */
- reg_val = __raw_readl(src_addr) & ~field_mask;
- reg_val |= (field_val << __ffs(field_mask));
- __raw_writel(reg_val, src_addr);
- wmb();
-
- if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) {
- __raw_writel(OMAP24XX_VALID_CONFIG, OMAP24XX_PRCM_CLKCFG_CTRL);
- wmb();
- }
+ v = __raw_readl(clk->clksel_reg);
+ v &= ~clk->clksel_mask;
+ v |= field_val << __ffs(clk->clksel_mask);
+ __raw_writel(v, clk->clksel_reg);
+ v = __raw_readl(clk->clksel_reg); /* OCP barrier */
- clk->parent = new_parent;
+ _omap2xxx_clk_commit(clk);
- if (clk->usecount > 0)
- omap2_clk_enable(clk);
+ clk_reparent(clk, new_parent);
/* CLKSEL clocks follow their parents' rates, divided by a divisor */
clk->rate = new_parent->rate;
@@ -773,9 +827,6 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
clk->name, clk->parent->name, clk->rate);
- if (unlikely(clk->flags & RATE_PROPAGATES))
- propagate_rate(clk);
-
return 0;
}
@@ -805,7 +856,8 @@ int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
return 0;
}
-static unsigned long _dpll_compute_new_rate(unsigned long parent_rate, unsigned int m, unsigned int n)
+static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
+ unsigned int m, unsigned int n)
{
unsigned long long num;
@@ -838,7 +890,7 @@ static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
unsigned long target_rate,
unsigned long parent_rate)
{
- int flags = 0, carry = 0;
+ int r = 0, carry = 0;
/* Unscale m and round if necessary */
if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
@@ -859,13 +911,13 @@ static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
if (*m < DPLL_MIN_MULTIPLIER) {
*m = DPLL_MIN_MULTIPLIER;
*new_rate = 0;
- flags = DPLL_MULT_UNDERFLOW;
+ r = DPLL_MULT_UNDERFLOW;
}
if (*new_rate == 0)
*new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
- return flags;
+ return r;
}
/**
@@ -889,54 +941,65 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
int m, n, r, e, scaled_max_m;
unsigned long scaled_rt_rp, new_rate;
int min_e = -1, min_e_m = -1, min_e_n = -1;
+ struct dpll_data *dd;
if (!clk || !clk->dpll_data)
return ~0;
+ dd = clk->dpll_data;
+
pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
"%ld\n", clk->name, target_rate);
- scaled_rt_rp = target_rate / (clk->parent->rate / DPLL_SCALE_FACTOR);
- scaled_max_m = clk->dpll_data->max_multiplier * DPLL_SCALE_FACTOR;
+ scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
+ scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
- clk->dpll_data->last_rounded_rate = 0;
+ dd->last_rounded_rate = 0;
- for (n = clk->dpll_data->max_divider; n >= DPLL_MIN_DIVIDER; n--) {
+ for (n = dd->min_divider; n <= dd->max_divider; n++) {
+
+ /* Is the (input clk, divider) pair valid for the DPLL? */
+ r = _dpll_test_fint(clk, n);
+ if (r == DPLL_FINT_UNDERFLOW)
+ break;
+ else if (r == DPLL_FINT_INVALID)
+ continue;
/* Compute the scaled DPLL multiplier, based on the divider */
m = scaled_rt_rp * n;
/*
- * Since we're counting n down, a m overflow means we can
- * can immediately skip to the next n
+ * Since we're counting n up, a m overflow means we
+ * can bail out completely (since as n increases in
+ * the next iteration, there's no way that m can
+ * increase beyond the current m)
*/
if (m > scaled_max_m)
- continue;
+ break;
r = _dpll_test_mult(&m, n, &new_rate, target_rate,
- clk->parent->rate);
+ dd->clk_ref->rate);
+
+ /* m can't be set low enough for this n - try with a larger n */
+ if (r == DPLL_MULT_UNDERFLOW)
+ continue;
e = target_rate - new_rate;
pr_debug("clock: n = %d: m = %d: rate error is %d "
"(new_rate = %ld)\n", n, m, e, new_rate);
if (min_e == -1 ||
- min_e >= (int)(abs(e) - clk->dpll_data->rate_tolerance)) {
+ min_e >= (int)(abs(e) - dd->rate_tolerance)) {
min_e = e;
min_e_m = m;
min_e_n = n;
pr_debug("clock: found new least error %d\n", min_e);
- }
- /*
- * Since we're counting n down, a m underflow means we
- * can bail out completely (since as n decreases in
- * the next iteration, there's no way that m can
- * increase beyond the current m)
- */
- if (r & DPLL_MULT_UNDERFLOW)
- break;
+ /* We found good settings -- bail out now */
+ if (min_e <= dd->rate_tolerance)
+ break;
+ }
}
if (min_e < 0) {
@@ -944,17 +1007,17 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
return ~0;
}
- clk->dpll_data->last_rounded_m = min_e_m;
- clk->dpll_data->last_rounded_n = min_e_n;
- clk->dpll_data->last_rounded_rate =
- _dpll_compute_new_rate(clk->parent->rate, min_e_m, min_e_n);
+ dd->last_rounded_m = min_e_m;
+ dd->last_rounded_n = min_e_n;
+ dd->last_rounded_rate = _dpll_compute_new_rate(dd->clk_ref->rate,
+ min_e_m, min_e_n);
pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
min_e, min_e_m, min_e_n);
pr_debug("clock: final rate: %ld (target rate: %ld)\n",
- clk->dpll_data->last_rounded_rate, target_rate);
+ dd->last_rounded_rate, target_rate);
- return clk->dpll_data->last_rounded_rate;
+ return dd->last_rounded_rate;
}
/*-------------------------------------------------------------------------
@@ -973,6 +1036,10 @@ void omap2_clk_disable_unused(struct clk *clk)
return;
printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name);
- _omap2_clk_disable(clk);
+ if (cpu_is_omap34xx()) {
+ omap2_clk_enable(clk);
+ omap2_clk_disable(clk);
+ } else
+ _omap2_clk_disable(clk);
}
#endif
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 1fb330e0847d..2679ddfa6424 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -21,13 +21,28 @@
/* The maximum error between a target DPLL rate and the rounded rate in Hz */
#define DEFAULT_DPLL_RATE_TOLERANCE 50000
+/* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
+#define CORE_CLK_SRC_32K 0x0
+#define CORE_CLK_SRC_DPLL 0x1
+#define CORE_CLK_SRC_DPLL_X2 0x2
+
+/* OMAP2xxx CM_CLKEN_PLL.EN_DPLL bits - for omap2_get_dpll_rate() */
+#define OMAP2XXX_EN_DPLL_LPBYPASS 0x1
+#define OMAP2XXX_EN_DPLL_FRBYPASS 0x2
+#define OMAP2XXX_EN_DPLL_LOCKED 0x3
+
+/* OMAP3xxx CM_CLKEN_PLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */
+#define OMAP3XXX_EN_DPLL_LPBYPASS 0x5
+#define OMAP3XXX_EN_DPLL_FRBYPASS 0x6
+#define OMAP3XXX_EN_DPLL_LOCKED 0x7
+
int omap2_clk_init(void);
int omap2_clk_enable(struct clk *clk);
void omap2_clk_disable(struct clk *clk);
long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
-int omap2_dpll_rate_tolerance_set(struct clk *clk, unsigned int tolerance);
+int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance);
long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
#ifdef CONFIG_OMAP_RESET_CLOCKS
@@ -36,7 +51,7 @@ void omap2_clk_disable_unused(struct clk *clk);
#define omap2_clk_disable_unused NULL
#endif
-void omap2_clksel_recalc(struct clk *clk);
+unsigned long omap2_clksel_recalc(struct clk *clk);
void omap2_init_clk_clkdm(struct clk *clk);
void omap2_init_clksel_parent(struct clk *clk);
u32 omap2_clksel_get_divisor(struct clk *clk);
@@ -44,13 +59,16 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
u32 *new_div);
u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val);
u32 omap2_divisor_to_clksel(struct clk *clk, u32 div);
-void omap2_fixed_divisor_recalc(struct clk *clk);
+unsigned long omap2_fixed_divisor_recalc(struct clk *clk);
long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate);
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
u32 omap2_get_dpll_rate(struct clk *clk);
int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
void omap2_clk_prepare_for_reboot(void);
+extern const struct clkops clkops_omap2_dflt_wait;
+extern const struct clkops clkops_omap2_dflt;
+
extern u8 cpu_mask;
/* clksel_rate data common to 24xx/343x */
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
index d382eb0184ac..1e839c5a28c5 100644
--- a/arch/arm/mach-omap2/clock24xx.c
+++ b/arch/arm/mach-omap2/clock24xx.c
@@ -31,15 +31,192 @@
#include <mach/clock.h>
#include <mach/sram.h>
#include <asm/div64.h>
+#include <asm/clkdev.h>
-#include "memory.h"
+#include <mach/sdrc.h>
#include "clock.h"
-#include "clock24xx.h"
#include "prm.h"
#include "prm-regbits-24xx.h"
#include "cm.h"
#include "cm-regbits-24xx.h"
+static const struct clkops clkops_oscck;
+static const struct clkops clkops_fixed;
+
+#include "clock24xx.h"
+
+struct omap_clk {
+ u32 cpu;
+ struct clk_lookup lk;
+};
+
+#define CLK(dev, con, ck, cp) \
+ { \
+ .cpu = cp, \
+ .lk = { \
+ .dev_id = dev, \
+ .con_id = con, \
+ .clk = ck, \
+ }, \
+ }
+
+#define CK_243X (1 << 0)
+#define CK_242X (1 << 1)
+
+static struct omap_clk omap24xx_clks[] = {
+ /* external root sources */
+ CLK(NULL, "func_32k_ck", &func_32k_ck, CK_243X | CK_242X),
+ CLK(NULL, "osc_ck", &osc_ck, CK_243X | CK_242X),
+ CLK(NULL, "sys_ck", &sys_ck, CK_243X | CK_242X),
+ CLK(NULL, "alt_ck", &alt_ck, CK_243X | CK_242X),
+ /* internal analog sources */
+ CLK(NULL, "dpll_ck", &dpll_ck, CK_243X | CK_242X),
+ CLK(NULL, "apll96_ck", &apll96_ck, CK_243X | CK_242X),
+ CLK(NULL, "apll54_ck", &apll54_ck, CK_243X | CK_242X),
+ /* internal prcm root sources */
+ CLK(NULL, "func_54m_ck", &func_54m_ck, CK_243X | CK_242X),
+ CLK(NULL, "core_ck", &core_ck, CK_243X | CK_242X),
+ CLK(NULL, "func_96m_ck", &func_96m_ck, CK_243X | CK_242X),
+ CLK(NULL, "func_48m_ck", &func_48m_ck, CK_243X | CK_242X),
+ CLK(NULL, "func_12m_ck", &func_12m_ck, CK_243X | CK_242X),
+ CLK(NULL, "ck_wdt1_osc", &wdt1_osc_ck, CK_243X | CK_242X),
+ CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_243X | CK_242X),
+ CLK(NULL, "sys_clkout", &sys_clkout, CK_243X | CK_242X),
+ CLK(NULL, "sys_clkout2_src", &sys_clkout2_src, CK_242X),
+ CLK(NULL, "sys_clkout2", &sys_clkout2, CK_242X),
+ CLK(NULL, "emul_ck", &emul_ck, CK_242X),
+ /* mpu domain clocks */
+ CLK(NULL, "mpu_ck", &mpu_ck, CK_243X | CK_242X),
+ /* dsp domain clocks */
+ CLK(NULL, "dsp_fck", &dsp_fck, CK_243X | CK_242X),
+ CLK(NULL, "dsp_irate_ick", &dsp_irate_ick, CK_243X | CK_242X),
+ CLK(NULL, "dsp_ick", &dsp_ick, CK_242X),
+ CLK(NULL, "iva2_1_ick", &iva2_1_ick, CK_243X),
+ CLK(NULL, "iva1_ifck", &iva1_ifck, CK_242X),
+ CLK(NULL, "iva1_mpu_int_ifck", &iva1_mpu_int_ifck, CK_242X),
+ /* GFX domain clocks */
+ CLK(NULL, "gfx_3d_fck", &gfx_3d_fck, CK_243X | CK_242X),
+ CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_243X | CK_242X),
+ CLK(NULL, "gfx_ick", &gfx_ick, CK_243X | CK_242X),
+ /* Modem domain clocks */
+ CLK(NULL, "mdm_ick", &mdm_ick, CK_243X),
+ CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X),
+ /* DSS domain clocks */
+ CLK(NULL, "dss_ick", &dss_ick, CK_243X | CK_242X),
+ CLK(NULL, "dss1_fck", &dss1_fck, CK_243X | CK_242X),
+ CLK(NULL, "dss2_fck", &dss2_fck, CK_243X | CK_242X),
+ CLK(NULL, "dss_54m_fck", &dss_54m_fck, CK_243X | CK_242X),
+ /* L3 domain clocks */
+ CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X | CK_242X),
+ CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X | CK_242X),
+ CLK(NULL, "usb_l4_ick", &usb_l4_ick, CK_243X | CK_242X),
+ /* L4 domain clocks */
+ CLK(NULL, "l4_ck", &l4_ck, CK_243X | CK_242X),
+ CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_243X | CK_242X),
+ /* virtual meta-group clock */
+ CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_243X | CK_242X),
+ /* general l4 interface ck, multi-parent functional clk */
+ CLK(NULL, "gpt1_ick", &gpt1_ick, CK_243X | CK_242X),
+ CLK(NULL, "gpt1_fck", &gpt1_fck, CK_243X | CK_242X),
+ CLK(NULL, "gpt2_ick", &gpt2_ick, CK_243X | CK_242X),
+ CLK(NULL, "gpt2_fck", &gpt2_fck, CK_243X | CK_242X),
+ CLK(NULL, "gpt3_ick", &gpt3_ick, CK_243X | CK_242X),
+ CLK(NULL, "gpt3_fck", &gpt3_fck, CK_243X | CK_242X),
+ CLK(NULL, "gpt4_ick", &gpt4_ick, CK_243X | CK_242X),
+ CLK(NULL, "gpt4_fck", &gpt4_fck, CK_243X | CK_242X),
+ CLK(NULL, "gpt5_ick", &gpt5_ick, CK_243X | CK_242X),
+ CLK(NULL, "gpt5_fck", &gpt5_fck, CK_243X | CK_242X),
+ CLK(NULL, "gpt6_ick", &gpt6_ick, CK_243X | CK_242X),
+ CLK(NULL, "gpt6_fck", &gpt6_fck, CK_243X | CK_242X),
+ CLK(NULL, "gpt7_ick", &gpt7_ick, CK_243X | CK_242X),
+ CLK(NULL, "gpt7_fck", &gpt7_fck, CK_243X | CK_242X),
+ CLK(NULL, "gpt8_ick", &gpt8_ick, CK_243X | CK_242X),
+ CLK(NULL, "gpt8_fck", &gpt8_fck, CK_243X | CK_242X),
+ CLK(NULL, "gpt9_ick", &gpt9_ick, CK_243X | CK_242X),
+ CLK(NULL, "gpt9_fck", &gpt9_fck, CK_243X | CK_242X),
+ CLK(NULL, "gpt10_ick", &gpt10_ick, CK_243X | CK_242X),
+ CLK(NULL, "gpt10_fck", &gpt10_fck, CK_243X | CK_242X),
+ CLK(NULL, "gpt11_ick", &gpt11_ick, CK_243X | CK_242X),
+ CLK(NULL, "gpt11_fck", &gpt11_fck, CK_243X | CK_242X),
+ CLK(NULL, "gpt12_ick", &gpt12_ick, CK_243X | CK_242X),
+ CLK(NULL, "gpt12_fck", &gpt12_fck, CK_243X | CK_242X),
+ CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_243X | CK_242X),
+ CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_243X | CK_242X),
+ CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_243X | CK_242X),
+ CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_243X | CK_242X),
+ CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_243X),
+ CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_243X),
+ CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_243X),
+ CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_243X),
+ CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_243X),
+ CLK("omap-mcbsp.5", "fck", &mcbsp5_fck, CK_243X),
+ CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_243X | CK_242X),
+ CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_243X | CK_242X),
+ CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_243X | CK_242X),
+ CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_243X | CK_242X),
+ CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_243X),
+ CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_243X),
+ CLK(NULL, "uart1_ick", &uart1_ick, CK_243X | CK_242X),
+ CLK(NULL, "uart1_fck", &uart1_fck, CK_243X | CK_242X),
+ CLK(NULL, "uart2_ick", &uart2_ick, CK_243X | CK_242X),
+ CLK(NULL, "uart2_fck", &uart2_fck, CK_243X | CK_242X),
+ CLK(NULL, "uart3_ick", &uart3_ick, CK_243X | CK_242X),
+ CLK(NULL, "uart3_fck", &uart3_fck, CK_243X | CK_242X),
+ CLK(NULL, "gpios_ick", &gpios_ick, CK_243X | CK_242X),
+ CLK(NULL, "gpios_fck", &gpios_fck, CK_243X | CK_242X),
+ CLK("omap_wdt", "ick", &mpu_wdt_ick, CK_243X | CK_242X),
+ CLK("omap_wdt", "fck", &mpu_wdt_fck, CK_243X | CK_242X),
+ CLK(NULL, "sync_32k_ick", &sync_32k_ick, CK_243X | CK_242X),
+ CLK(NULL, "wdt1_ick", &wdt1_ick, CK_243X | CK_242X),
+ CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_243X | CK_242X),
+ CLK(NULL, "icr_ick", &icr_ick, CK_243X),
+ CLK("omap24xxcam", "fck", &cam_fck, CK_243X | CK_242X),
+ CLK("omap24xxcam", "ick", &cam_ick, CK_243X | CK_242X),
+ CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_243X | CK_242X),
+ CLK(NULL, "wdt4_ick", &wdt4_ick, CK_243X | CK_242X),
+ CLK(NULL, "wdt4_fck", &wdt4_fck, CK_243X | CK_242X),
+ CLK(NULL, "wdt3_ick", &wdt3_ick, CK_242X),
+ CLK(NULL, "wdt3_fck", &wdt3_fck, CK_242X),
+ CLK(NULL, "mspro_ick", &mspro_ick, CK_243X | CK_242X),
+ CLK(NULL, "mspro_fck", &mspro_fck, CK_243X | CK_242X),
+ CLK("mmci-omap.0", "ick", &mmc_ick, CK_242X),
+ CLK("mmci-omap.0", "fck", &mmc_fck, CK_242X),
+ CLK(NULL, "fac_ick", &fac_ick, CK_243X | CK_242X),
+ CLK(NULL, "fac_fck", &fac_fck, CK_243X | CK_242X),
+ CLK(NULL, "eac_ick", &eac_ick, CK_242X),
+ CLK(NULL, "eac_fck", &eac_fck, CK_242X),
+ CLK("omap_hdq.0", "ick", &hdq_ick, CK_243X | CK_242X),
+ CLK("omap_hdq.1", "fck", &hdq_fck, CK_243X | CK_242X),
+ CLK("i2c_omap.1", "ick", &i2c1_ick, CK_243X | CK_242X),
+ CLK("i2c_omap.1", "fck", &i2c1_fck, CK_242X),
+ CLK("i2c_omap.1", "fck", &i2chs1_fck, CK_243X),
+ CLK("i2c_omap.2", "ick", &i2c2_ick, CK_243X | CK_242X),
+ CLK("i2c_omap.2", "fck", &i2c2_fck, CK_242X),
+ CLK("i2c_omap.2", "fck", &i2chs2_fck, CK_243X),
+ CLK(NULL, "gpmc_fck", &gpmc_fck, CK_243X | CK_242X),
+ CLK(NULL, "sdma_fck", &sdma_fck, CK_243X | CK_242X),
+ CLK(NULL, "sdma_ick", &sdma_ick, CK_243X | CK_242X),
+ CLK(NULL, "vlynq_ick", &vlynq_ick, CK_242X),
+ CLK(NULL, "vlynq_fck", &vlynq_fck, CK_242X),
+ CLK(NULL, "sdrc_ick", &sdrc_ick, CK_243X),
+ CLK(NULL, "des_ick", &des_ick, CK_243X | CK_242X),
+ CLK(NULL, "sha_ick", &sha_ick, CK_243X | CK_242X),
+ CLK("omap_rng", "ick", &rng_ick, CK_243X | CK_242X),
+ CLK(NULL, "aes_ick", &aes_ick, CK_243X | CK_242X),
+ CLK(NULL, "pka_ick", &pka_ick, CK_243X | CK_242X),
+ CLK(NULL, "usb_fck", &usb_fck, CK_243X | CK_242X),
+ CLK(NULL, "usbhs_ick", &usbhs_ick, CK_243X),
+ CLK("mmci-omap-hs.0", "ick", &mmchs1_ick, CK_243X),
+ CLK("mmci-omap-hs.0", "fck", &mmchs1_fck, CK_243X),
+ CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_243X),
+ CLK("mmci-omap-hs.1", "fck", &mmchs2_fck, CK_243X),
+ CLK(NULL, "gpio5_ick", &gpio5_ick, CK_243X),
+ CLK(NULL, "gpio5_fck", &gpio5_fck, CK_243X),
+ CLK(NULL, "mdm_intc_ick", &mdm_intc_ick, CK_243X),
+ CLK("mmci-omap-hs.0", "mmchsdb_fck", &mmchsdb1_fck, CK_243X),
+ CLK("mmci-omap-hs.1", "mmchsdb_fck", &mmchsdb2_fck, CK_243X),
+};
+
/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
#define EN_APLL_STOPPED 0
#define EN_APLL_LOCKED 3
@@ -59,19 +236,32 @@ static struct clk *sclk;
* Omap24xx specific clock functions
*-------------------------------------------------------------------------*/
-/* This actually returns the rate of core_ck, not dpll_ck. */
-static u32 omap2_get_dpll_rate_24xx(struct clk *tclk)
+/**
+ * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
+ * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
+ *
+ * Returns the CORE_CLK rate. CORE_CLK can have one of three rate
+ * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
+ * (the latter is unusual). This currently should be called with
+ * struct clk *dpll_ck, which is a composite clock of dpll_ck and
+ * core_ck.
+ */
+static unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
{
- long long dpll_clk;
- u8 amult;
+ long long core_clk;
+ u32 v;
+
+ core_clk = omap2_get_dpll_rate(clk);
- dpll_clk = omap2_get_dpll_rate(tclk);
+ v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ v &= OMAP24XX_CORE_CLK_SRC_MASK;
- amult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
- amult &= OMAP24XX_CORE_CLK_SRC_MASK;
- dpll_clk *= amult;
+ if (v == CORE_CLK_SRC_32K)
+ core_clk = 32768;
+ else
+ core_clk *= v;
- return dpll_clk;
+ return core_clk;
}
static int omap2_enable_osc_ck(struct clk *clk)
@@ -96,6 +286,11 @@ static void omap2_disable_osc_ck(struct clk *clk)
OMAP24XX_PRCM_CLKSRC_CTRL);
}
+static const struct clkops clkops_oscck = {
+ .enable = &omap2_enable_osc_ck,
+ .disable = &omap2_disable_osc_ck,
+};
+
#ifdef OLD_CK
/* Recalculate SYST_CLK */
static void omap2_sys_clk_recalc(struct clk * clk)
@@ -149,11 +344,16 @@ static void omap2_clk_fixed_disable(struct clk *clk)
cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
}
+static const struct clkops clkops_fixed = {
+ .enable = &omap2_clk_fixed_enable,
+ .disable = &omap2_clk_fixed_disable,
+};
+
/*
* Uses the current prcm set to tell if a rate is valid.
* You can go slower, but not faster within a given rate set.
*/
-long omap2_dpllcore_round_rate(unsigned long target_rate)
+static long omap2_dpllcore_round_rate(unsigned long target_rate)
{
u32 high, low, core_clk_src;
@@ -182,11 +382,9 @@ long omap2_dpllcore_round_rate(unsigned long target_rate)
}
-static void omap2_dpllcore_recalc(struct clk *clk)
+static unsigned long omap2_dpllcore_recalc(struct clk *clk)
{
- clk->rate = omap2_get_dpll_rate_24xx(clk);
-
- propagate_rate(clk);
+ return omap2xxx_clk_get_core_rate(clk);
}
static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
@@ -195,22 +393,19 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
u32 bypass = 0;
struct prcm_config tmpset;
const struct dpll_data *dd;
- unsigned long flags;
- int ret = -EINVAL;
- local_irq_save(flags);
- cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck);
+ cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck);
mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
mult &= OMAP24XX_CORE_CLK_SRC_MASK;
if ((rate == (cur_rate / 2)) && (mult == 2)) {
- omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL, 1);
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
} else if ((rate == (cur_rate * 2)) && (mult == 1)) {
- omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1);
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
} else if (rate != cur_rate) {
valid_rate = omap2_dpllcore_round_rate(rate);
if (valid_rate != rate)
- goto dpll_exit;
+ return -EINVAL;
if (mult == 1)
low = curr_prcm_set->dpll_speed;
@@ -219,7 +414,7 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
dd = clk->dpll_data;
if (!dd)
- goto dpll_exit;
+ return -EINVAL;
tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
@@ -245,22 +440,19 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */
bypass = 1;
- omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); /* For init_mem */
+ /* For omap2xxx_sdrc_init_params() */
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
/* Force dll lock mode */
omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
bypass);
/* Errata: ret dll entry state */
- omap2_init_memory_params(omap2_dll_force_needed());
- omap2_reprogram_sdrc(done_rate, 0);
+ omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+ omap2xxx_sdrc_reprogram(done_rate, 0);
}
- omap2_dpllcore_recalc(&dpll_ck);
- ret = 0;
-dpll_exit:
- local_irq_restore(flags);
- return(ret);
+ return 0;
}
/**
@@ -269,9 +461,9 @@ dpll_exit:
*
* Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
*/
-static void omap2_table_mpu_recalc(struct clk *clk)
+static unsigned long omap2_table_mpu_recalc(struct clk *clk)
{
- clk->rate = curr_prcm_set->mpu_speed;
+ return curr_prcm_set->mpu_speed;
}
/*
@@ -337,12 +529,12 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate)
}
curr_prcm_set = prcm;
- cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck);
+ cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck);
if (prcm->dpll_speed == cur_rate / 2) {
- omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL, 1);
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
} else if (prcm->dpll_speed == cur_rate * 2) {
- omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1);
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
} else if (prcm->dpll_speed != cur_rate) {
local_irq_save(flags);
@@ -366,27 +558,67 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate)
/* Major subsystem dividers */
tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
- cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD, CM_CLKSEL1);
+ cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
+ CM_CLKSEL1);
+
if (cpu_is_omap2430())
cm_write_mod_reg(prcm->cm_clksel_mdm,
OMAP2430_MDM_MOD, CM_CLKSEL);
- /* x2 to enter init_mem */
- omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1);
+ /* x2 to enter omap2xxx_sdrc_init_params() */
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
bypass);
- omap2_init_memory_params(omap2_dll_force_needed());
- omap2_reprogram_sdrc(done_rate, 0);
+ omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+ omap2xxx_sdrc_reprogram(done_rate, 0);
local_irq_restore(flags);
}
- omap2_dpllcore_recalc(&dpll_ck);
return 0;
}
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Walk PRCM rate table and fillout cpufreq freq_table
+ */
+static struct cpufreq_frequency_table freq_table[ARRAY_SIZE(rate_table)];
+
+void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+ struct prcm_config *prcm;
+ int i = 0;
+
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+ if (prcm->xtal_speed != sys_ck.rate)
+ continue;
+
+ /* don't put bypass rates in table */
+ if (prcm->dpll_speed == prcm->xtal_speed)
+ continue;
+
+ freq_table[i].index = i;
+ freq_table[i].frequency = prcm->mpu_speed / 1000;
+ i++;
+ }
+
+ if (i == 0) {
+ printk(KERN_WARNING "%s: failed to initialize frequency "
+ "table\n", __func__);
+ return;
+ }
+
+ freq_table[i].index = i;
+ freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+ *table = &freq_table[0];
+}
+#endif
+
static struct clk_functions omap2_clk_functions = {
.clk_enable = omap2_clk_enable,
.clk_disable = omap2_clk_disable,
@@ -394,24 +626,27 @@ static struct clk_functions omap2_clk_functions = {
.clk_set_rate = omap2_clk_set_rate,
.clk_set_parent = omap2_clk_set_parent,
.clk_disable_unused = omap2_clk_disable_unused,
+#ifdef CONFIG_CPU_FREQ
+ .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
+#endif
};
static u32 omap2_get_apll_clkin(void)
{
- u32 aplls, sclk = 0;
+ u32 aplls, srate = 0;
aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
aplls &= OMAP24XX_APLLS_CLKIN_MASK;
aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
if (aplls == APLLS_CLKIN_19_2MHZ)
- sclk = 19200000;
+ srate = 19200000;
else if (aplls == APLLS_CLKIN_13MHZ)
- sclk = 13000000;
+ srate = 13000000;
else if (aplls == APLLS_CLKIN_12MHZ)
- sclk = 12000000;
+ srate = 12000000;
- return sclk;
+ return srate;
}
static u32 omap2_get_sysclkdiv(void)
@@ -425,16 +660,14 @@ static u32 omap2_get_sysclkdiv(void)
return div;
}
-static void omap2_osc_clk_recalc(struct clk *clk)
+static unsigned long omap2_osc_clk_recalc(struct clk *clk)
{
- clk->rate = omap2_get_apll_clkin() * omap2_get_sysclkdiv();
- propagate_rate(clk);
+ return omap2_get_apll_clkin() * omap2_get_sysclkdiv();
}
-static void omap2_sys_clk_recalc(struct clk *clk)
+static unsigned long omap2_sys_clk_recalc(struct clk *clk)
{
- clk->rate = clk->parent->rate / omap2_get_sysclkdiv();
- propagate_rate(clk);
+ return clk->parent->rate / omap2_get_sysclkdiv();
}
/*
@@ -460,7 +693,7 @@ static int __init omap2_clk_arch_init(void)
if (!mpurate)
return -EINVAL;
- if (omap2_select_table_rate(&virt_prcm_set, mpurate))
+ if (clk_set_rate(&virt_prcm_set, mpurate))
printk(KERN_ERR "Could not find matching MPU rate\n");
recalculate_root_clocks();
@@ -477,8 +710,8 @@ arch_initcall(omap2_clk_arch_init);
int __init omap2_clk_init(void)
{
struct prcm_config *prcm;
- struct clk **clkp;
- u32 clkrate;
+ struct omap_clk *c;
+ u32 clkrate, cpu_mask;
if (cpu_is_omap242x())
cpu_mask = RATE_IN_242X;
@@ -487,26 +720,28 @@ int __init omap2_clk_init(void)
clk_init(&omap2_clk_functions);
- omap2_osc_clk_recalc(&osc_ck);
- omap2_sys_clk_recalc(&sys_ck);
+ osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
+ propagate_rate(&osc_ck);
+ sys_ck.rate = omap2_sys_clk_recalc(&sys_ck);
+ propagate_rate(&sys_ck);
- for (clkp = onchip_24xx_clks;
- clkp < onchip_24xx_clks + ARRAY_SIZE(onchip_24xx_clks);
- clkp++) {
+ for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
+ clk_init_one(c->lk.clk);
- if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) {
- clk_register(*clkp);
- continue;
- }
+ cpu_mask = 0;
+ if (cpu_is_omap2420())
+ cpu_mask |= CK_242X;
+ if (cpu_is_omap2430())
+ cpu_mask |= CK_243X;
- if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) {
- clk_register(*clkp);
- continue;
+ for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++)
+ if (c->cpu & cpu_mask) {
+ clkdev_add(&c->lk);
+ clk_register(c->lk.clk);
}
- }
/* Check the MPU rate set by bootloader */
- clkrate = omap2_get_dpll_rate_24xx(&dpll_ck);
+ clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
for (prcm = rate_table; prcm->mpu_speed; prcm++) {
if (!(prcm->flags & cpu_mask))
continue;
diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h
index ad6d98d177c5..33c3e5b14323 100644
--- a/arch/arm/mach-omap2/clock24xx.h
+++ b/arch/arm/mach-omap2/clock24xx.h
@@ -24,17 +24,13 @@
#include "cm-regbits-24xx.h"
#include "sdrc.h"
-static void omap2_table_mpu_recalc(struct clk *clk);
+static unsigned long omap2_table_mpu_recalc(struct clk *clk);
static int omap2_select_table_rate(struct clk *clk, unsigned long rate);
static long omap2_round_to_table_rate(struct clk *clk, unsigned long rate);
-static void omap2_sys_clk_recalc(struct clk *clk);
-static void omap2_osc_clk_recalc(struct clk *clk);
-static void omap2_sys_clk_recalc(struct clk *clk);
-static void omap2_dpllcore_recalc(struct clk *clk);
-static int omap2_clk_fixed_enable(struct clk *clk);
-static void omap2_clk_fixed_disable(struct clk *clk);
-static int omap2_enable_osc_ck(struct clk *clk);
-static void omap2_disable_osc_ck(struct clk *clk);
+static unsigned long omap2_sys_clk_recalc(struct clk *clk);
+static unsigned long omap2_osc_clk_recalc(struct clk *clk);
+static unsigned long omap2_sys_clk_recalc(struct clk *clk);
+static unsigned long omap2_dpllcore_recalc(struct clk *clk);
static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
/* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
@@ -623,41 +619,35 @@ static struct prcm_config rate_table[] = {
/* Base external input clocks */
static struct clk func_32k_ck = {
.name = "func_32k_ck",
+ .ops = &clkops_null,
.rate = 32000,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+ .flags = RATE_FIXED,
.clkdm_name = "wkup_clkdm",
- .recalc = &propagate_rate,
};
/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */
.name = "osc_ck",
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- RATE_PROPAGATES,
+ .ops = &clkops_oscck,
.clkdm_name = "wkup_clkdm",
- .enable = &omap2_enable_osc_ck,
- .disable = &omap2_disable_osc_ck,
.recalc = &omap2_osc_clk_recalc,
};
/* Without modem likely 12MHz, with modem likely 13MHz */
static struct clk sys_ck = { /* (*12, *13, 19.2, 26, 38.4)MHz */
.name = "sys_ck", /* ~ ref_clk also */
+ .ops = &clkops_null,
.parent = &osc_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- ALWAYS_ENABLED | RATE_PROPAGATES,
.clkdm_name = "wkup_clkdm",
.recalc = &omap2_sys_clk_recalc,
};
static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */
.name = "alt_ck",
+ .ops = &clkops_null,
.rate = 54000000,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+ .flags = RATE_FIXED,
.clkdm_name = "wkup_clkdm",
- .recalc = &propagate_rate,
};
/*
@@ -673,7 +663,12 @@ static struct dpll_data dpll_dd = {
.mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
.mult_mask = OMAP24XX_DPLL_MULT_MASK,
.div1_mask = OMAP24XX_DPLL_DIV_MASK,
+ .clk_bypass = &sys_ck,
+ .clk_ref = &sys_ck,
+ .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_mask = OMAP24XX_EN_DPLL_MASK,
.max_multiplier = 1024,
+ .min_divider = 1,
.max_divider = 16,
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
};
@@ -684,10 +679,9 @@ static struct dpll_data dpll_dd = {
*/
static struct clk dpll_ck = {
.name = "dpll_ck",
+ .ops = &clkops_null,
.parent = &sys_ck, /* Can be func_32k also */
.dpll_data = &dpll_dd,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- RATE_PROPAGATES | ALWAYS_ENABLED,
.clkdm_name = "wkup_clkdm",
.recalc = &omap2_dpllcore_recalc,
.set_rate = &omap2_reprogram_dpllcore,
@@ -695,30 +689,24 @@ static struct clk dpll_ck = {
static struct clk apll96_ck = {
.name = "apll96_ck",
+ .ops = &clkops_fixed,
.parent = &sys_ck,
.rate = 96000000,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- RATE_FIXED | RATE_PROPAGATES | ENABLE_ON_INIT,
+ .flags = RATE_FIXED | ENABLE_ON_INIT,
.clkdm_name = "wkup_clkdm",
.enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
.enable_bit = OMAP24XX_EN_96M_PLL_SHIFT,
- .enable = &omap2_clk_fixed_enable,
- .disable = &omap2_clk_fixed_disable,
- .recalc = &propagate_rate,
};
static struct clk apll54_ck = {
.name = "apll54_ck",
+ .ops = &clkops_fixed,
.parent = &sys_ck,
.rate = 54000000,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- RATE_FIXED | RATE_PROPAGATES | ENABLE_ON_INIT,
+ .flags = RATE_FIXED | ENABLE_ON_INIT,
.clkdm_name = "wkup_clkdm",
.enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
.enable_bit = OMAP24XX_EN_54M_PLL_SHIFT,
- .enable = &omap2_clk_fixed_enable,
- .disable = &omap2_clk_fixed_disable,
- .recalc = &propagate_rate,
};
/*
@@ -745,9 +733,8 @@ static const struct clksel func_54m_clksel[] = {
static struct clk func_54m_ck = {
.name = "func_54m_ck",
+ .ops = &clkops_null,
.parent = &apll54_ck, /* can also be alt_clk */
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
.clkdm_name = "wkup_clkdm",
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
@@ -758,9 +745,8 @@ static struct clk func_54m_ck = {
static struct clk core_ck = {
.name = "core_ck",
+ .ops = &clkops_null,
.parent = &dpll_ck, /* can also be 32k */
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- ALWAYS_ENABLED | RATE_PROPAGATES,
.clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -785,9 +771,8 @@ static const struct clksel func_96m_clksel[] = {
/* The parent of this clock is not selectable on 2420. */
static struct clk func_96m_ck = {
.name = "func_96m_ck",
+ .ops = &clkops_null,
.parent = &apll96_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
.clkdm_name = "wkup_clkdm",
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
@@ -818,9 +803,8 @@ static const struct clksel func_48m_clksel[] = {
static struct clk func_48m_ck = {
.name = "func_48m_ck",
+ .ops = &clkops_null,
.parent = &apll96_ck, /* 96M or Alt */
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
.clkdm_name = "wkup_clkdm",
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
@@ -833,10 +817,9 @@ static struct clk func_48m_ck = {
static struct clk func_12m_ck = {
.name = "func_12m_ck",
+ .ops = &clkops_null,
.parent = &func_48m_ck,
.fixed_div = 4,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
.clkdm_name = "wkup_clkdm",
.recalc = &omap2_fixed_divisor_recalc,
};
@@ -844,8 +827,8 @@ static struct clk func_12m_ck = {
/* Secure timer, only available in secure mode */
static struct clk wdt1_osc_ck = {
.name = "ck_wdt1_osc",
+ .ops = &clkops_null, /* RMK: missing? */
.parent = &osc_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.recalc = &followparent_recalc,
};
@@ -887,9 +870,8 @@ static const struct clksel common_clkout_src_clksel[] = {
static struct clk sys_clkout_src = {
.name = "sys_clkout_src",
+ .ops = &clkops_omap2_dflt,
.parent = &func_54m_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- RATE_PROPAGATES,
.clkdm_name = "wkup_clkdm",
.enable_reg = OMAP24XX_PRCM_CLKOUT_CTRL,
.enable_bit = OMAP24XX_CLKOUT_EN_SHIFT,
@@ -918,9 +900,8 @@ static const struct clksel sys_clkout_clksel[] = {
static struct clk sys_clkout = {
.name = "sys_clkout",
+ .ops = &clkops_null,
.parent = &sys_clkout_src,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "wkup_clkdm",
.clksel_reg = OMAP24XX_PRCM_CLKOUT_CTRL,
.clksel_mask = OMAP24XX_CLKOUT_DIV_MASK,
@@ -933,8 +914,8 @@ static struct clk sys_clkout = {
/* In 2430, new in 2420 ES2 */
static struct clk sys_clkout2_src = {
.name = "sys_clkout2_src",
+ .ops = &clkops_omap2_dflt,
.parent = &func_54m_ck,
- .flags = CLOCK_IN_OMAP242X | RATE_PROPAGATES,
.clkdm_name = "wkup_clkdm",
.enable_reg = OMAP24XX_PRCM_CLKOUT_CTRL,
.enable_bit = OMAP2420_CLKOUT2_EN_SHIFT,
@@ -955,8 +936,8 @@ static const struct clksel sys_clkout2_clksel[] = {
/* In 2430, new in 2420 ES2 */
static struct clk sys_clkout2 = {
.name = "sys_clkout2",
+ .ops = &clkops_null,
.parent = &sys_clkout2_src,
- .flags = CLOCK_IN_OMAP242X | PARENT_CONTROLS_CLOCK,
.clkdm_name = "wkup_clkdm",
.clksel_reg = OMAP24XX_PRCM_CLKOUT_CTRL,
.clksel_mask = OMAP2420_CLKOUT2_DIV_MASK,
@@ -968,8 +949,8 @@ static struct clk sys_clkout2 = {
static struct clk emul_ck = {
.name = "emul_ck",
+ .ops = &clkops_omap2_dflt,
.parent = &func_54m_ck,
- .flags = CLOCK_IN_OMAP242X,
.clkdm_name = "wkup_clkdm",
.enable_reg = OMAP24XX_PRCM_CLKEMUL_CTRL,
.enable_bit = OMAP24XX_EMULATION_EN_SHIFT,
@@ -1003,10 +984,9 @@ static const struct clksel mpu_clksel[] = {
static struct clk mpu_ck = { /* Control cpu */
.name = "mpu_ck",
+ .ops = &clkops_null,
.parent = &core_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- ALWAYS_ENABLED | DELAYED_APP |
- CONFIG_PARTICIPANT | RATE_PROPAGATES,
+ .flags = DELAYED_APP | CONFIG_PARTICIPANT,
.clkdm_name = "mpu_clkdm",
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
@@ -1046,9 +1026,9 @@ static const struct clksel dsp_fck_clksel[] = {
static struct clk dsp_fck = {
.name = "dsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | DELAYED_APP |
- CONFIG_PARTICIPANT | RATE_PROPAGATES,
+ .flags = DELAYED_APP | CONFIG_PARTICIPANT,
.clkdm_name = "dsp_clkdm",
.enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
@@ -1076,9 +1056,9 @@ static const struct clksel dsp_irate_ick_clksel[] = {
/* This clock does not exist as such in the TRM. */
static struct clk dsp_irate_ick = {
.name = "dsp_irate_ick",
+ .ops = &clkops_null,
.parent = &dsp_fck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | DELAYED_APP |
- CONFIG_PARTICIPANT | PARENT_CONTROLS_CLOCK,
+ .flags = DELAYED_APP | CONFIG_PARTICIPANT,
.clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
.clksel_mask = OMAP24XX_CLKSEL_DSP_IF_MASK,
.clksel = dsp_irate_ick_clksel,
@@ -1090,8 +1070,9 @@ static struct clk dsp_irate_ick = {
/* 2420 only */
static struct clk dsp_ick = {
.name = "dsp_ick", /* apparently ipi and isp */
+ .ops = &clkops_omap2_dflt_wait,
.parent = &dsp_irate_ick,
- .flags = CLOCK_IN_OMAP242X | DELAYED_APP | CONFIG_PARTICIPANT,
+ .flags = DELAYED_APP | CONFIG_PARTICIPANT,
.enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN),
.enable_bit = OMAP2420_EN_DSP_IPI_SHIFT, /* for ipi */
};
@@ -1099,8 +1080,9 @@ static struct clk dsp_ick = {
/* 2430 only - EN_DSP controls both dsp fclk and iclk on 2430 */
static struct clk iva2_1_ick = {
.name = "iva2_1_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &dsp_irate_ick,
- .flags = CLOCK_IN_OMAP243X | DELAYED_APP | CONFIG_PARTICIPANT,
+ .flags = DELAYED_APP | CONFIG_PARTICIPANT,
.enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
};
@@ -1112,9 +1094,9 @@ static struct clk iva2_1_ick = {
*/
static struct clk iva1_ifck = {
.name = "iva1_ifck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_ck,
- .flags = CLOCK_IN_OMAP242X | CONFIG_PARTICIPANT |
- RATE_PROPAGATES | DELAYED_APP,
+ .flags = CONFIG_PARTICIPANT | DELAYED_APP,
.clkdm_name = "iva1_clkdm",
.enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
.enable_bit = OMAP2420_EN_IVA_COP_SHIFT,
@@ -1129,8 +1111,8 @@ static struct clk iva1_ifck = {
/* IVA1 mpu/int/i/f clocks are /2 of parent */
static struct clk iva1_mpu_int_ifck = {
.name = "iva1_mpu_int_ifck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &iva1_ifck,
- .flags = CLOCK_IN_OMAP242X,
.clkdm_name = "iva1_clkdm",
.enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
.enable_bit = OMAP2420_EN_IVA_MPU_SHIFT,
@@ -1175,10 +1157,9 @@ static const struct clksel core_l3_clksel[] = {
static struct clk core_l3_ck = { /* Used for ick and fck, interconnect */
.name = "core_l3_ck",
+ .ops = &clkops_null,
.parent = &core_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- ALWAYS_ENABLED | DELAYED_APP |
- CONFIG_PARTICIPANT | RATE_PROPAGATES,
+ .flags = DELAYED_APP | CONFIG_PARTICIPANT,
.clkdm_name = "core_l3_clkdm",
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
.clksel_mask = OMAP24XX_CLKSEL_L3_MASK,
@@ -1204,9 +1185,9 @@ static const struct clksel usb_l4_ick_clksel[] = {
/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
static struct clk usb_l4_ick = { /* FS-USB interface clock */
.name = "usb_l4_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l3_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- DELAYED_APP | CONFIG_PARTICIPANT,
+ .flags = DELAYED_APP | CONFIG_PARTICIPANT,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP24XX_EN_USB_SHIFT,
@@ -1238,9 +1219,9 @@ static const struct clksel l4_clksel[] = {
static struct clk l4_ck = { /* used both as an ick and fck */
.name = "l4_ck",
+ .ops = &clkops_null,
.parent = &core_l3_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- ALWAYS_ENABLED | DELAYED_APP | RATE_PROPAGATES,
+ .flags = DELAYED_APP,
.clkdm_name = "core_l4_clkdm",
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
.clksel_mask = OMAP24XX_CLKSEL_L4_MASK,
@@ -1276,9 +1257,9 @@ static const struct clksel ssi_ssr_sst_fck_clksel[] = {
static struct clk ssi_ssr_sst_fck = {
.name = "ssi_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- DELAYED_APP,
+ .flags = DELAYED_APP,
.clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP24XX_EN_SSI_SHIFT,
@@ -1290,6 +1271,20 @@ static struct clk ssi_ssr_sst_fck = {
.set_rate = &omap2_clksel_set_rate
};
+/*
+ * Presumably this is the same as SSI_ICLK.
+ * TRM contradicts itself on what clockdomain SSI_ICLK is in
+ */
+static struct clk ssi_l4_ick = {
+ .name = "ssi_l4_ick",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP24XX_EN_SSI_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
/*
* GFX clock domain
@@ -1312,8 +1307,8 @@ static const struct clksel gfx_fck_clksel[] = {
static struct clk gfx_3d_fck = {
.name = "gfx_3d_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l3_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "gfx_clkdm",
.enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_EN_3D_SHIFT,
@@ -1327,8 +1322,8 @@ static struct clk gfx_3d_fck = {
static struct clk gfx_2d_fck = {
.name = "gfx_2d_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l3_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "gfx_clkdm",
.enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_EN_2D_SHIFT,
@@ -1342,8 +1337,8 @@ static struct clk gfx_2d_fck = {
static struct clk gfx_ick = {
.name = "gfx_ick", /* From l3 */
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l3_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "gfx_clkdm",
.enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
.enable_bit = OMAP_EN_GFX_SHIFT,
@@ -1372,8 +1367,9 @@ static const struct clksel mdm_ick_clksel[] = {
static struct clk mdm_ick = { /* used both as a ick and fck */
.name = "mdm_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_ck,
- .flags = CLOCK_IN_OMAP243X | DELAYED_APP | CONFIG_PARTICIPANT,
+ .flags = DELAYED_APP | CONFIG_PARTICIPANT,
.clkdm_name = "mdm_clkdm",
.enable_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN),
.enable_bit = OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT,
@@ -1387,8 +1383,8 @@ static struct clk mdm_ick = { /* used both as a ick and fck */
static struct clk mdm_osc_ck = {
.name = "mdm_osc_ck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &osc_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "mdm_clkdm",
.enable_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN),
.enable_bit = OMAP2430_EN_OSC_SHIFT,
@@ -1432,8 +1428,8 @@ static const struct clksel dss1_fck_clksel[] = {
static struct clk dss_ick = { /* Enables both L3,L4 ICLK's */
.name = "dss_ick",
+ .ops = &clkops_omap2_dflt,
.parent = &l4_ck, /* really both l3 and l4 */
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "dss_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_DSS1_SHIFT,
@@ -1442,9 +1438,9 @@ static struct clk dss_ick = { /* Enables both L3,L4 ICLK's */
static struct clk dss1_fck = {
.name = "dss1_fck",
+ .ops = &clkops_omap2_dflt,
.parent = &core_ck, /* Core or sys */
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- DELAYED_APP,
+ .flags = DELAYED_APP,
.clkdm_name = "dss_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_DSS1_SHIFT,
@@ -1475,9 +1471,9 @@ static const struct clksel dss2_fck_clksel[] = {
static struct clk dss2_fck = { /* Alt clk used in power management */
.name = "dss2_fck",
+ .ops = &clkops_omap2_dflt,
.parent = &sys_ck, /* fixed at sys_ck or 48MHz */
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- DELAYED_APP,
+ .flags = DELAYED_APP,
.clkdm_name = "dss_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_DSS2_SHIFT,
@@ -1490,8 +1486,8 @@ static struct clk dss2_fck = { /* Alt clk used in power management */
static struct clk dss_54m_fck = { /* Alt clk used in power management */
.name = "dss_54m_fck", /* 54m tv clk */
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_54m_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "dss_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_TV_SHIFT,
@@ -1518,8 +1514,8 @@ static const struct clksel omap24xx_gpt_clksel[] = {
static struct clk gpt1_ick = {
.name = "gpt1_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP24XX_EN_GPT1_SHIFT,
@@ -1528,8 +1524,8 @@ static struct clk gpt1_ick = {
static struct clk gpt1_fck = {
.name = "gpt1_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_EN_GPT1_SHIFT,
@@ -1544,8 +1540,8 @@ static struct clk gpt1_fck = {
static struct clk gpt2_ick = {
.name = "gpt2_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT2_SHIFT,
@@ -1554,8 +1550,8 @@ static struct clk gpt2_ick = {
static struct clk gpt2_fck = {
.name = "gpt2_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT2_SHIFT,
@@ -1568,8 +1564,8 @@ static struct clk gpt2_fck = {
static struct clk gpt3_ick = {
.name = "gpt3_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT3_SHIFT,
@@ -1578,8 +1574,8 @@ static struct clk gpt3_ick = {
static struct clk gpt3_fck = {
.name = "gpt3_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT3_SHIFT,
@@ -1592,8 +1588,8 @@ static struct clk gpt3_fck = {
static struct clk gpt4_ick = {
.name = "gpt4_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT4_SHIFT,
@@ -1602,8 +1598,8 @@ static struct clk gpt4_ick = {
static struct clk gpt4_fck = {
.name = "gpt4_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT4_SHIFT,
@@ -1616,8 +1612,8 @@ static struct clk gpt4_fck = {
static struct clk gpt5_ick = {
.name = "gpt5_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT5_SHIFT,
@@ -1626,8 +1622,8 @@ static struct clk gpt5_ick = {
static struct clk gpt5_fck = {
.name = "gpt5_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT5_SHIFT,
@@ -1640,8 +1636,8 @@ static struct clk gpt5_fck = {
static struct clk gpt6_ick = {
.name = "gpt6_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT6_SHIFT,
@@ -1650,8 +1646,8 @@ static struct clk gpt6_ick = {
static struct clk gpt6_fck = {
.name = "gpt6_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT6_SHIFT,
@@ -1664,8 +1660,8 @@ static struct clk gpt6_fck = {
static struct clk gpt7_ick = {
.name = "gpt7_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT7_SHIFT,
.recalc = &followparent_recalc,
@@ -1673,8 +1669,8 @@ static struct clk gpt7_ick = {
static struct clk gpt7_fck = {
.name = "gpt7_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT7_SHIFT,
@@ -1687,8 +1683,8 @@ static struct clk gpt7_fck = {
static struct clk gpt8_ick = {
.name = "gpt8_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT8_SHIFT,
@@ -1697,8 +1693,8 @@ static struct clk gpt8_ick = {
static struct clk gpt8_fck = {
.name = "gpt8_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT8_SHIFT,
@@ -1711,8 +1707,8 @@ static struct clk gpt8_fck = {
static struct clk gpt9_ick = {
.name = "gpt9_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT9_SHIFT,
@@ -1721,8 +1717,8 @@ static struct clk gpt9_ick = {
static struct clk gpt9_fck = {
.name = "gpt9_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT9_SHIFT,
@@ -1735,8 +1731,8 @@ static struct clk gpt9_fck = {
static struct clk gpt10_ick = {
.name = "gpt10_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT10_SHIFT,
@@ -1745,8 +1741,8 @@ static struct clk gpt10_ick = {
static struct clk gpt10_fck = {
.name = "gpt10_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT10_SHIFT,
@@ -1759,8 +1755,8 @@ static struct clk gpt10_fck = {
static struct clk gpt11_ick = {
.name = "gpt11_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT11_SHIFT,
@@ -1769,8 +1765,8 @@ static struct clk gpt11_ick = {
static struct clk gpt11_fck = {
.name = "gpt11_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT11_SHIFT,
@@ -1783,8 +1779,8 @@ static struct clk gpt11_fck = {
static struct clk gpt12_ick = {
.name = "gpt12_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT12_SHIFT,
@@ -1793,8 +1789,8 @@ static struct clk gpt12_ick = {
static struct clk gpt12_fck = {
.name = "gpt12_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT12_SHIFT,
@@ -1807,9 +1803,9 @@ static struct clk gpt12_fck = {
static struct clk mcbsp1_ick = {
.name = "mcbsp_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_MCBSP1_SHIFT,
@@ -1818,9 +1814,9 @@ static struct clk mcbsp1_ick = {
static struct clk mcbsp1_fck = {
.name = "mcbsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MCBSP1_SHIFT,
@@ -1829,9 +1825,9 @@ static struct clk mcbsp1_fck = {
static struct clk mcbsp2_ick = {
.name = "mcbsp_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_MCBSP2_SHIFT,
@@ -1840,9 +1836,9 @@ static struct clk mcbsp2_ick = {
static struct clk mcbsp2_fck = {
.name = "mcbsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MCBSP2_SHIFT,
@@ -1851,9 +1847,9 @@ static struct clk mcbsp2_fck = {
static struct clk mcbsp3_ick = {
.name = "mcbsp_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 3,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MCBSP3_SHIFT,
@@ -1862,9 +1858,9 @@ static struct clk mcbsp3_ick = {
static struct clk mcbsp3_fck = {
.name = "mcbsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 3,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MCBSP3_SHIFT,
@@ -1873,9 +1869,9 @@ static struct clk mcbsp3_fck = {
static struct clk mcbsp4_ick = {
.name = "mcbsp_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 4,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MCBSP4_SHIFT,
@@ -1884,9 +1880,9 @@ static struct clk mcbsp4_ick = {
static struct clk mcbsp4_fck = {
.name = "mcbsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 4,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MCBSP4_SHIFT,
@@ -1895,9 +1891,9 @@ static struct clk mcbsp4_fck = {
static struct clk mcbsp5_ick = {
.name = "mcbsp_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 5,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MCBSP5_SHIFT,
@@ -1906,9 +1902,9 @@ static struct clk mcbsp5_ick = {
static struct clk mcbsp5_fck = {
.name = "mcbsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 5,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MCBSP5_SHIFT,
@@ -1917,10 +1913,10 @@ static struct clk mcbsp5_fck = {
static struct clk mcspi1_ick = {
.name = "mcspi_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &l4_ck,
.clkdm_name = "core_l4_clkdm",
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_MCSPI1_SHIFT,
.recalc = &followparent_recalc,
@@ -1928,9 +1924,9 @@ static struct clk mcspi1_ick = {
static struct clk mcspi1_fck = {
.name = "mcspi_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &func_48m_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MCSPI1_SHIFT,
@@ -1939,9 +1935,9 @@ static struct clk mcspi1_fck = {
static struct clk mcspi2_ick = {
.name = "mcspi_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_MCSPI2_SHIFT,
@@ -1950,9 +1946,9 @@ static struct clk mcspi2_ick = {
static struct clk mcspi2_fck = {
.name = "mcspi_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &func_48m_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MCSPI2_SHIFT,
@@ -1961,9 +1957,9 @@ static struct clk mcspi2_fck = {
static struct clk mcspi3_ick = {
.name = "mcspi_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 3,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MCSPI3_SHIFT,
@@ -1972,9 +1968,9 @@ static struct clk mcspi3_ick = {
static struct clk mcspi3_fck = {
.name = "mcspi_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 3,
.parent = &func_48m_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MCSPI3_SHIFT,
@@ -1983,8 +1979,8 @@ static struct clk mcspi3_fck = {
static struct clk uart1_ick = {
.name = "uart1_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_UART1_SHIFT,
@@ -1993,8 +1989,8 @@ static struct clk uart1_ick = {
static struct clk uart1_fck = {
.name = "uart1_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_48m_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_UART1_SHIFT,
@@ -2003,8 +1999,8 @@ static struct clk uart1_fck = {
static struct clk uart2_ick = {
.name = "uart2_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_UART2_SHIFT,
@@ -2013,8 +2009,8 @@ static struct clk uart2_ick = {
static struct clk uart2_fck = {
.name = "uart2_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_48m_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_UART2_SHIFT,
@@ -2023,8 +2019,8 @@ static struct clk uart2_fck = {
static struct clk uart3_ick = {
.name = "uart3_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP24XX_EN_UART3_SHIFT,
@@ -2033,8 +2029,8 @@ static struct clk uart3_ick = {
static struct clk uart3_fck = {
.name = "uart3_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_48m_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP24XX_EN_UART3_SHIFT,
@@ -2043,8 +2039,8 @@ static struct clk uart3_fck = {
static struct clk gpios_ick = {
.name = "gpios_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP24XX_EN_GPIOS_SHIFT,
@@ -2053,8 +2049,8 @@ static struct clk gpios_ick = {
static struct clk gpios_fck = {
.name = "gpios_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "wkup_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_EN_GPIOS_SHIFT,
@@ -2063,8 +2059,8 @@ static struct clk gpios_fck = {
static struct clk mpu_wdt_ick = {
.name = "mpu_wdt_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT,
@@ -2073,8 +2069,8 @@ static struct clk mpu_wdt_ick = {
static struct clk mpu_wdt_fck = {
.name = "mpu_wdt_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "wkup_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT,
@@ -2083,9 +2079,9 @@ static struct clk mpu_wdt_fck = {
static struct clk sync_32k_ick = {
.name = "sync_32k_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- ENABLE_ON_INIT,
+ .flags = ENABLE_ON_INIT,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP24XX_EN_32KSYNC_SHIFT,
@@ -2094,8 +2090,8 @@ static struct clk sync_32k_ick = {
static struct clk wdt1_ick = {
.name = "wdt1_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP24XX_EN_WDT1_SHIFT,
@@ -2104,9 +2100,9 @@ static struct clk wdt1_ick = {
static struct clk omapctrl_ick = {
.name = "omapctrl_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- ENABLE_ON_INIT,
+ .flags = ENABLE_ON_INIT,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP24XX_EN_OMAPCTRL_SHIFT,
@@ -2115,8 +2111,8 @@ static struct clk omapctrl_ick = {
static struct clk icr_ick = {
.name = "icr_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP2430_EN_ICR_SHIFT,
@@ -2125,8 +2121,8 @@ static struct clk icr_ick = {
static struct clk cam_ick = {
.name = "cam_ick",
+ .ops = &clkops_omap2_dflt,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_CAM_SHIFT,
@@ -2140,8 +2136,8 @@ static struct clk cam_ick = {
*/
static struct clk cam_fck = {
.name = "cam_fck",
+ .ops = &clkops_omap2_dflt,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_CAM_SHIFT,
@@ -2150,8 +2146,8 @@ static struct clk cam_fck = {
static struct clk mailboxes_ick = {
.name = "mailboxes_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_MAILBOXES_SHIFT,
@@ -2160,8 +2156,8 @@ static struct clk mailboxes_ick = {
static struct clk wdt4_ick = {
.name = "wdt4_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_WDT4_SHIFT,
@@ -2170,8 +2166,8 @@ static struct clk wdt4_ick = {
static struct clk wdt4_fck = {
.name = "wdt4_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_WDT4_SHIFT,
@@ -2180,8 +2176,8 @@ static struct clk wdt4_fck = {
static struct clk wdt3_ick = {
.name = "wdt3_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP2420_EN_WDT3_SHIFT,
@@ -2190,8 +2186,8 @@ static struct clk wdt3_ick = {
static struct clk wdt3_fck = {
.name = "wdt3_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP242X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP2420_EN_WDT3_SHIFT,
@@ -2200,8 +2196,8 @@ static struct clk wdt3_fck = {
static struct clk mspro_ick = {
.name = "mspro_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_MSPRO_SHIFT,
@@ -2210,8 +2206,8 @@ static struct clk mspro_ick = {
static struct clk mspro_fck = {
.name = "mspro_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MSPRO_SHIFT,
@@ -2220,8 +2216,8 @@ static struct clk mspro_fck = {
static struct clk mmc_ick = {
.name = "mmc_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP2420_EN_MMC_SHIFT,
@@ -2230,8 +2226,8 @@ static struct clk mmc_ick = {
static struct clk mmc_fck = {
.name = "mmc_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP242X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP2420_EN_MMC_SHIFT,
@@ -2240,8 +2236,8 @@ static struct clk mmc_fck = {
static struct clk fac_ick = {
.name = "fac_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_FAC_SHIFT,
@@ -2250,8 +2246,8 @@ static struct clk fac_ick = {
static struct clk fac_fck = {
.name = "fac_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_12m_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_FAC_SHIFT,
@@ -2260,8 +2256,8 @@ static struct clk fac_fck = {
static struct clk eac_ick = {
.name = "eac_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP2420_EN_EAC_SHIFT,
@@ -2270,8 +2266,8 @@ static struct clk eac_ick = {
static struct clk eac_fck = {
.name = "eac_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP242X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP2420_EN_EAC_SHIFT,
@@ -2280,8 +2276,8 @@ static struct clk eac_fck = {
static struct clk hdq_ick = {
.name = "hdq_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_HDQ_SHIFT,
@@ -2290,8 +2286,8 @@ static struct clk hdq_ick = {
static struct clk hdq_fck = {
.name = "hdq_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_12m_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_HDQ_SHIFT,
@@ -2300,9 +2296,9 @@ static struct clk hdq_fck = {
static struct clk i2c2_ick = {
.name = "i2c_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP2420_EN_I2C2_SHIFT,
@@ -2311,9 +2307,9 @@ static struct clk i2c2_ick = {
static struct clk i2c2_fck = {
.name = "i2c_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &func_12m_ck,
- .flags = CLOCK_IN_OMAP242X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP2420_EN_I2C2_SHIFT,
@@ -2322,9 +2318,9 @@ static struct clk i2c2_fck = {
static struct clk i2chs2_fck = {
.name = "i2c_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_I2CHS2_SHIFT,
@@ -2333,9 +2329,9 @@ static struct clk i2chs2_fck = {
static struct clk i2c1_ick = {
.name = "i2c_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP2420_EN_I2C1_SHIFT,
@@ -2344,9 +2340,9 @@ static struct clk i2c1_ick = {
static struct clk i2c1_fck = {
.name = "i2c_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &func_12m_ck,
- .flags = CLOCK_IN_OMAP242X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP2420_EN_I2C1_SHIFT,
@@ -2355,9 +2351,9 @@ static struct clk i2c1_fck = {
static struct clk i2chs1_fck = {
.name = "i2c_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_I2CHS1_SHIFT,
@@ -2366,33 +2362,33 @@ static struct clk i2chs1_fck = {
static struct clk gpmc_fck = {
.name = "gpmc_fck",
+ .ops = &clkops_null, /* RMK: missing? */
.parent = &core_l3_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- ENABLE_ON_INIT,
+ .flags = ENABLE_ON_INIT,
.clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
static struct clk sdma_fck = {
.name = "sdma_fck",
+ .ops = &clkops_null, /* RMK: missing? */
.parent = &core_l3_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
static struct clk sdma_ick = {
.name = "sdma_ick",
+ .ops = &clkops_null, /* RMK: missing? */
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
static struct clk vlynq_ick = {
.name = "vlynq_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l3_ck,
- .flags = CLOCK_IN_OMAP242X,
.clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP2420_EN_VLYNQ_SHIFT,
@@ -2426,8 +2422,9 @@ static const struct clksel vlynq_fck_clksel[] = {
static struct clk vlynq_fck = {
.name = "vlynq_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP242X | DELAYED_APP,
+ .flags = DELAYED_APP,
.clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP2420_EN_VLYNQ_SHIFT,
@@ -2442,8 +2439,9 @@ static struct clk vlynq_fck = {
static struct clk sdrc_ick = {
.name = "sdrc_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X | ENABLE_ON_INIT,
+ .flags = ENABLE_ON_INIT,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
.enable_bit = OMAP2430_EN_SDRC_SHIFT,
@@ -2452,8 +2450,8 @@ static struct clk sdrc_ick = {
static struct clk des_ick = {
.name = "des_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
.enable_bit = OMAP24XX_EN_DES_SHIFT,
@@ -2462,8 +2460,8 @@ static struct clk des_ick = {
static struct clk sha_ick = {
.name = "sha_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
.enable_bit = OMAP24XX_EN_SHA_SHIFT,
@@ -2472,8 +2470,8 @@ static struct clk sha_ick = {
static struct clk rng_ick = {
.name = "rng_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
.enable_bit = OMAP24XX_EN_RNG_SHIFT,
@@ -2482,8 +2480,8 @@ static struct clk rng_ick = {
static struct clk aes_ick = {
.name = "aes_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
.enable_bit = OMAP24XX_EN_AES_SHIFT,
@@ -2492,8 +2490,8 @@ static struct clk aes_ick = {
static struct clk pka_ick = {
.name = "pka_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
.enable_bit = OMAP24XX_EN_PKA_SHIFT,
@@ -2502,8 +2500,8 @@ static struct clk pka_ick = {
static struct clk usb_fck = {
.name = "usb_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_48m_ck,
- .flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
.clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP24XX_EN_USB_SHIFT,
@@ -2512,8 +2510,8 @@ static struct clk usb_fck = {
static struct clk usbhs_ick = {
.name = "usbhs_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l3_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_USBHS_SHIFT,
@@ -2522,8 +2520,8 @@ static struct clk usbhs_ick = {
static struct clk mmchs1_ick = {
.name = "mmchs_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MMCHS1_SHIFT,
@@ -2532,8 +2530,8 @@ static struct clk mmchs1_ick = {
static struct clk mmchs1_fck = {
.name = "mmchs_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MMCHS1_SHIFT,
@@ -2542,9 +2540,9 @@ static struct clk mmchs1_fck = {
static struct clk mmchs2_ick = {
.name = "mmchs_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MMCHS2_SHIFT,
@@ -2553,9 +2551,9 @@ static struct clk mmchs2_ick = {
static struct clk mmchs2_fck = {
.name = "mmchs_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &func_96m_ck,
- .flags = CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MMCHS2_SHIFT,
.recalc = &followparent_recalc,
@@ -2563,8 +2561,8 @@ static struct clk mmchs2_fck = {
static struct clk gpio5_ick = {
.name = "gpio5_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_GPIO5_SHIFT,
@@ -2573,8 +2571,8 @@ static struct clk gpio5_ick = {
static struct clk gpio5_fck = {
.name = "gpio5_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_GPIO5_SHIFT,
@@ -2583,8 +2581,8 @@ static struct clk gpio5_fck = {
static struct clk mdm_intc_ick = {
.name = "mdm_intc_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MDM_INTC_SHIFT,
@@ -2593,8 +2591,8 @@ static struct clk mdm_intc_ick = {
static struct clk mmchsdb1_fck = {
.name = "mmchsdb_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MMCHSDB1_SHIFT,
@@ -2603,9 +2601,9 @@ static struct clk mmchsdb1_fck = {
static struct clk mmchsdb2_fck = {
.name = "mmchsdb_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &func_32k_ck,
- .flags = CLOCK_IN_OMAP243X,
.clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MMCHSDB2_SHIFT,
@@ -2628,166 +2626,13 @@ static struct clk mmchsdb2_fck = {
*/
static struct clk virt_prcm_set = {
.name = "virt_prcm_set",
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- VIRTUAL_CLOCK | ALWAYS_ENABLED | DELAYED_APP,
+ .ops = &clkops_null,
+ .flags = DELAYED_APP,
.parent = &mpu_ck, /* Indexed by mpu speed, no parent */
.recalc = &omap2_table_mpu_recalc, /* sets are keyed on mpu rate */
.set_rate = &omap2_select_table_rate,
.round_rate = &omap2_round_to_table_rate,
};
-static struct clk *onchip_24xx_clks[] __initdata = {
- /* external root sources */
- &func_32k_ck,
- &osc_ck,
- &sys_ck,
- &alt_ck,
- /* internal analog sources */
- &dpll_ck,
- &apll96_ck,
- &apll54_ck,
- /* internal prcm root sources */
- &func_54m_ck,
- &core_ck,
- &func_96m_ck,
- &func_48m_ck,
- &func_12m_ck,
- &wdt1_osc_ck,
- &sys_clkout_src,
- &sys_clkout,
- &sys_clkout2_src,
- &sys_clkout2,
- &emul_ck,
- /* mpu domain clocks */
- &mpu_ck,
- /* dsp domain clocks */
- &dsp_fck,
- &dsp_irate_ick,
- &dsp_ick, /* 242x */
- &iva2_1_ick, /* 243x */
- &iva1_ifck, /* 242x */
- &iva1_mpu_int_ifck, /* 242x */
- /* GFX domain clocks */
- &gfx_3d_fck,
- &gfx_2d_fck,
- &gfx_ick,
- /* Modem domain clocks */
- &mdm_ick,
- &mdm_osc_ck,
- /* DSS domain clocks */
- &dss_ick,
- &dss1_fck,
- &dss2_fck,
- &dss_54m_fck,
- /* L3 domain clocks */
- &core_l3_ck,
- &ssi_ssr_sst_fck,
- &usb_l4_ick,
- /* L4 domain clocks */
- &l4_ck, /* used as both core_l4 and wu_l4 */
- /* virtual meta-group clock */
- &virt_prcm_set,
- /* general l4 interface ck, multi-parent functional clk */
- &gpt1_ick,
- &gpt1_fck,
- &gpt2_ick,
- &gpt2_fck,
- &gpt3_ick,
- &gpt3_fck,
- &gpt4_ick,
- &gpt4_fck,
- &gpt5_ick,
- &gpt5_fck,
- &gpt6_ick,
- &gpt6_fck,
- &gpt7_ick,
- &gpt7_fck,
- &gpt8_ick,
- &gpt8_fck,
- &gpt9_ick,
- &gpt9_fck,
- &gpt10_ick,
- &gpt10_fck,
- &gpt11_ick,
- &gpt11_fck,
- &gpt12_ick,
- &gpt12_fck,
- &mcbsp1_ick,
- &mcbsp1_fck,
- &mcbsp2_ick,
- &mcbsp2_fck,
- &mcbsp3_ick,
- &mcbsp3_fck,
- &mcbsp4_ick,
- &mcbsp4_fck,
- &mcbsp5_ick,
- &mcbsp5_fck,
- &mcspi1_ick,
- &mcspi1_fck,
- &mcspi2_ick,
- &mcspi2_fck,
- &mcspi3_ick,
- &mcspi3_fck,
- &uart1_ick,
- &uart1_fck,
- &uart2_ick,
- &uart2_fck,
- &uart3_ick,
- &uart3_fck,
- &gpios_ick,
- &gpios_fck,
- &mpu_wdt_ick,
- &mpu_wdt_fck,
- &sync_32k_ick,
- &wdt1_ick,
- &omapctrl_ick,
- &icr_ick,
- &cam_fck,
- &cam_ick,
- &mailboxes_ick,
- &wdt4_ick,
- &wdt4_fck,
- &wdt3_ick,
- &wdt3_fck,
- &mspro_ick,
- &mspro_fck,
- &mmc_ick,
- &mmc_fck,
- &fac_ick,
- &fac_fck,
- &eac_ick,
- &eac_fck,
- &hdq_ick,
- &hdq_fck,
- &i2c1_ick,
- &i2c1_fck,
- &i2chs1_fck,
- &i2c2_ick,
- &i2c2_fck,
- &i2chs2_fck,
- &gpmc_fck,
- &sdma_fck,
- &sdma_ick,
- &vlynq_ick,
- &vlynq_fck,
- &sdrc_ick,
- &des_ick,
- &sha_ick,
- &rng_ick,
- &aes_ick,
- &pka_ick,
- &usb_fck,
- &usbhs_ick,
- &mmchs1_ick,
- &mmchs1_fck,
- &mmchs2_ick,
- &mmchs2_fck,
- &gpio5_ick,
- &gpio5_fck,
- &mdm_intc_ick,
- &mmchsdb1_fck,
- &mmchsdb2_fck,
-};
-
#endif
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index 31bb7010bd48..0a14dca31e30 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -30,15 +30,251 @@
#include <mach/clock.h>
#include <mach/sram.h>
#include <asm/div64.h>
+#include <asm/clkdev.h>
-#include "memory.h"
+#include <mach/sdrc.h>
#include "clock.h"
-#include "clock34xx.h"
#include "prm.h"
#include "prm-regbits-34xx.h"
#include "cm.h"
#include "cm-regbits-34xx.h"
+static const struct clkops clkops_noncore_dpll_ops;
+
+#include "clock34xx.h"
+
+struct omap_clk {
+ u32 cpu;
+ struct clk_lookup lk;
+};
+
+#define CLK(dev, con, ck, cp) \
+ { \
+ .cpu = cp, \
+ .lk = { \
+ .dev_id = dev, \
+ .con_id = con, \
+ .clk = ck, \
+ }, \
+ }
+
+#define CK_343X (1 << 0)
+#define CK_3430ES1 (1 << 1)
+#define CK_3430ES2 (1 << 2)
+
+static struct omap_clk omap34xx_clks[] = {
+ CLK(NULL, "omap_32k_fck", &omap_32k_fck, CK_343X),
+ CLK(NULL, "virt_12m_ck", &virt_12m_ck, CK_343X),
+ CLK(NULL, "virt_13m_ck", &virt_13m_ck, CK_343X),
+ CLK(NULL, "virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2),
+ CLK(NULL, "virt_19_2m_ck", &virt_19_2m_ck, CK_343X),
+ CLK(NULL, "virt_26m_ck", &virt_26m_ck, CK_343X),
+ CLK(NULL, "virt_38_4m_ck", &virt_38_4m_ck, CK_343X),
+ CLK(NULL, "osc_sys_ck", &osc_sys_ck, CK_343X),
+ CLK(NULL, "sys_ck", &sys_ck, CK_343X),
+ CLK(NULL, "sys_altclk", &sys_altclk, CK_343X),
+ CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_343X),
+ CLK(NULL, "sys_clkout1", &sys_clkout1, CK_343X),
+ CLK(NULL, "dpll1_ck", &dpll1_ck, CK_343X),
+ CLK(NULL, "dpll1_x2_ck", &dpll1_x2_ck, CK_343X),
+ CLK(NULL, "dpll1_x2m2_ck", &dpll1_x2m2_ck, CK_343X),
+ CLK(NULL, "dpll2_ck", &dpll2_ck, CK_343X),
+ CLK(NULL, "dpll2_m2_ck", &dpll2_m2_ck, CK_343X),
+ CLK(NULL, "dpll3_ck", &dpll3_ck, CK_343X),
+ CLK(NULL, "core_ck", &core_ck, CK_343X),
+ CLK(NULL, "dpll3_x2_ck", &dpll3_x2_ck, CK_343X),
+ CLK(NULL, "dpll3_m2_ck", &dpll3_m2_ck, CK_343X),
+ CLK(NULL, "dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_343X),
+ CLK(NULL, "dpll3_m3_ck", &dpll3_m3_ck, CK_343X),
+ CLK(NULL, "dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_343X),
+ CLK(NULL, "emu_core_alwon_ck", &emu_core_alwon_ck, CK_343X),
+ CLK(NULL, "dpll4_ck", &dpll4_ck, CK_343X),
+ CLK(NULL, "dpll4_x2_ck", &dpll4_x2_ck, CK_343X),
+ CLK(NULL, "omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_343X),
+ CLK(NULL, "omap_96m_fck", &omap_96m_fck, CK_343X),
+ CLK(NULL, "cm_96m_fck", &cm_96m_fck, CK_343X),
+ CLK(NULL, "omap_54m_fck", &omap_54m_fck, CK_343X),
+ CLK(NULL, "omap_48m_fck", &omap_48m_fck, CK_343X),
+ CLK(NULL, "omap_12m_fck", &omap_12m_fck, CK_343X),
+ CLK(NULL, "dpll4_m2_ck", &dpll4_m2_ck, CK_343X),
+ CLK(NULL, "dpll4_m2x2_ck", &dpll4_m2x2_ck, CK_343X),
+ CLK(NULL, "dpll4_m3_ck", &dpll4_m3_ck, CK_343X),
+ CLK(NULL, "dpll4_m3x2_ck", &dpll4_m3x2_ck, CK_343X),
+ CLK(NULL, "dpll4_m4_ck", &dpll4_m4_ck, CK_343X),
+ CLK(NULL, "dpll4_m4x2_ck", &dpll4_m4x2_ck, CK_343X),
+ CLK(NULL, "dpll4_m5_ck", &dpll4_m5_ck, CK_343X),
+ CLK(NULL, "dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_343X),
+ CLK(NULL, "dpll4_m6_ck", &dpll4_m6_ck, CK_343X),
+ CLK(NULL, "dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_343X),
+ CLK(NULL, "emu_per_alwon_ck", &emu_per_alwon_ck, CK_343X),
+ CLK(NULL, "dpll5_ck", &dpll5_ck, CK_3430ES2),
+ CLK(NULL, "dpll5_m2_ck", &dpll5_m2_ck, CK_3430ES2),
+ CLK(NULL, "clkout2_src_ck", &clkout2_src_ck, CK_343X),
+ CLK(NULL, "sys_clkout2", &sys_clkout2, CK_343X),
+ CLK(NULL, "corex2_fck", &corex2_fck, CK_343X),
+ CLK(NULL, "dpll1_fck", &dpll1_fck, CK_343X),
+ CLK(NULL, "mpu_ck", &mpu_ck, CK_343X),
+ CLK(NULL, "arm_fck", &arm_fck, CK_343X),
+ CLK(NULL, "emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_343X),
+ CLK(NULL, "dpll2_fck", &dpll2_fck, CK_343X),
+ CLK(NULL, "iva2_ck", &iva2_ck, CK_343X),
+ CLK(NULL, "l3_ick", &l3_ick, CK_343X),
+ CLK(NULL, "l4_ick", &l4_ick, CK_343X),
+ CLK(NULL, "rm_ick", &rm_ick, CK_343X),
+ CLK(NULL, "gfx_l3_ck", &gfx_l3_ck, CK_3430ES1),
+ CLK(NULL, "gfx_l3_fck", &gfx_l3_fck, CK_3430ES1),
+ CLK(NULL, "gfx_l3_ick", &gfx_l3_ick, CK_3430ES1),
+ CLK(NULL, "gfx_cg1_ck", &gfx_cg1_ck, CK_3430ES1),
+ CLK(NULL, "gfx_cg2_ck", &gfx_cg2_ck, CK_3430ES1),
+ CLK(NULL, "sgx_fck", &sgx_fck, CK_3430ES2),
+ CLK(NULL, "sgx_ick", &sgx_ick, CK_3430ES2),
+ CLK(NULL, "d2d_26m_fck", &d2d_26m_fck, CK_3430ES1),
+ CLK(NULL, "gpt10_fck", &gpt10_fck, CK_343X),
+ CLK(NULL, "gpt11_fck", &gpt11_fck, CK_343X),
+ CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2),
+ CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2),
+ CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2),
+ CLK(NULL, "core_96m_fck", &core_96m_fck, CK_343X),
+ CLK("mmci-omap-hs.2", "fck", &mmchs3_fck, CK_3430ES2),
+ CLK("mmci-omap-hs.1", "fck", &mmchs2_fck, CK_343X),
+ CLK(NULL, "mspro_fck", &mspro_fck, CK_343X),
+ CLK("mmci-omap-hs.0", "fck", &mmchs1_fck, CK_343X),
+ CLK("i2c_omap.3", "fck", &i2c3_fck, CK_343X),
+ CLK("i2c_omap.2", "fck", &i2c2_fck, CK_343X),
+ CLK("i2c_omap.1", "fck", &i2c1_fck, CK_343X),
+ CLK("omap-mcbsp.5", "fck", &mcbsp5_fck, CK_343X),
+ CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_343X),
+ CLK(NULL, "core_48m_fck", &core_48m_fck, CK_343X),
+ CLK("omap2_mcspi.4", "fck", &mcspi4_fck, CK_343X),
+ CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_343X),
+ CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_343X),
+ CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_343X),
+ CLK(NULL, "uart2_fck", &uart2_fck, CK_343X),
+ CLK(NULL, "uart1_fck", &uart1_fck, CK_343X),
+ CLK(NULL, "fshostusb_fck", &fshostusb_fck, CK_3430ES1),
+ CLK(NULL, "core_12m_fck", &core_12m_fck, CK_343X),
+ CLK("omap_hdq.0", "fck", &hdq_fck, CK_343X),
+ CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck, CK_343X),
+ CLK(NULL, "ssi_sst_fck", &ssi_sst_fck, CK_343X),
+ CLK(NULL, "core_l3_ick", &core_l3_ick, CK_343X),
+ CLK(NULL, "hsotgusb_ick", &hsotgusb_ick, CK_343X),
+ CLK(NULL, "sdrc_ick", &sdrc_ick, CK_343X),
+ CLK(NULL, "gpmc_fck", &gpmc_fck, CK_343X),
+ CLK(NULL, "security_l3_ick", &security_l3_ick, CK_343X),
+ CLK(NULL, "pka_ick", &pka_ick, CK_343X),
+ CLK(NULL, "core_l4_ick", &core_l4_ick, CK_343X),
+ CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2),
+ CLK("mmci-omap-hs.2", "ick", &mmchs3_ick, CK_3430ES2),
+ CLK(NULL, "icr_ick", &icr_ick, CK_343X),
+ CLK(NULL, "aes2_ick", &aes2_ick, CK_343X),
+ CLK(NULL, "sha12_ick", &sha12_ick, CK_343X),
+ CLK(NULL, "des2_ick", &des2_ick, CK_343X),
+ CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_343X),
+ CLK("mmci-omap-hs.0", "ick", &mmchs1_ick, CK_343X),
+ CLK(NULL, "mspro_ick", &mspro_ick, CK_343X),
+ CLK("omap_hdq.0", "ick", &hdq_ick, CK_343X),
+ CLK("omap2_mcspi.4", "ick", &mcspi4_ick, CK_343X),
+ CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_343X),
+ CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_343X),
+ CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_343X),
+ CLK("i2c_omap.3", "ick", &i2c3_ick, CK_343X),
+ CLK("i2c_omap.2", "ick", &i2c2_ick, CK_343X),
+ CLK("i2c_omap.1", "ick", &i2c1_ick, CK_343X),
+ CLK(NULL, "uart2_ick", &uart2_ick, CK_343X),
+ CLK(NULL, "uart1_ick", &uart1_ick, CK_343X),
+ CLK(NULL, "gpt11_ick", &gpt11_ick, CK_343X),
+ CLK(NULL, "gpt10_ick", &gpt10_ick, CK_343X),
+ CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_343X),
+ CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_343X),
+ CLK(NULL, "fac_ick", &fac_ick, CK_3430ES1),
+ CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_343X),
+ CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_343X),
+ CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_343X),
+ CLK(NULL, "ssi_ick", &ssi_ick, CK_343X),
+ CLK(NULL, "usb_l4_ick", &usb_l4_ick, CK_3430ES1),
+ CLK(NULL, "security_l4_ick2", &security_l4_ick2, CK_343X),
+ CLK(NULL, "aes1_ick", &aes1_ick, CK_343X),
+ CLK("omap_rng", "ick", &rng_ick, CK_343X),
+ CLK(NULL, "sha11_ick", &sha11_ick, CK_343X),
+ CLK(NULL, "des1_ick", &des1_ick, CK_343X),
+ CLK(NULL, "dss1_alwon_fck", &dss1_alwon_fck, CK_343X),
+ CLK(NULL, "dss_tv_fck", &dss_tv_fck, CK_343X),
+ CLK(NULL, "dss_96m_fck", &dss_96m_fck, CK_343X),
+ CLK(NULL, "dss2_alwon_fck", &dss2_alwon_fck, CK_343X),
+ CLK(NULL, "dss_ick", &dss_ick, CK_343X),
+ CLK(NULL, "cam_mclk", &cam_mclk, CK_343X),
+ CLK(NULL, "cam_ick", &cam_ick, CK_343X),
+ CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X),
+ CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2),
+ CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2),
+ CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2),
+ CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2),
+ CLK(NULL, "gpt1_fck", &gpt1_fck, CK_343X),
+ CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_343X),
+ CLK(NULL, "gpio1_dbck", &gpio1_dbck, CK_343X),
+ CLK("omap_wdt", "fck", &wdt2_fck, CK_343X),
+ CLK(NULL, "wkup_l4_ick", &wkup_l4_ick, CK_343X),
+ CLK(NULL, "usim_ick", &usim_ick, CK_3430ES2),
+ CLK("omap_wdt", "ick", &wdt2_ick, CK_343X),
+ CLK(NULL, "wdt1_ick", &wdt1_ick, CK_343X),
+ CLK(NULL, "gpio1_ick", &gpio1_ick, CK_343X),
+ CLK(NULL, "omap_32ksync_ick", &omap_32ksync_ick, CK_343X),
+ CLK(NULL, "gpt12_ick", &gpt12_ick, CK_343X),
+ CLK(NULL, "gpt1_ick", &gpt1_ick, CK_343X),
+ CLK(NULL, "per_96m_fck", &per_96m_fck, CK_343X),
+ CLK(NULL, "per_48m_fck", &per_48m_fck, CK_343X),
+ CLK(NULL, "uart3_fck", &uart3_fck, CK_343X),
+ CLK(NULL, "gpt2_fck", &gpt2_fck, CK_343X),
+ CLK(NULL, "gpt3_fck", &gpt3_fck, CK_343X),
+ CLK(NULL, "gpt4_fck", &gpt4_fck, CK_343X),
+ CLK(NULL, "gpt5_fck", &gpt5_fck, CK_343X),
+ CLK(NULL, "gpt6_fck", &gpt6_fck, CK_343X),
+ CLK(NULL, "gpt7_fck", &gpt7_fck, CK_343X),
+ CLK(NULL, "gpt8_fck", &gpt8_fck, CK_343X),
+ CLK(NULL, "gpt9_fck", &gpt9_fck, CK_343X),
+ CLK(NULL, "per_32k_alwon_fck", &per_32k_alwon_fck, CK_343X),
+ CLK(NULL, "gpio6_dbck", &gpio6_dbck, CK_343X),
+ CLK(NULL, "gpio5_dbck", &gpio5_dbck, CK_343X),
+ CLK(NULL, "gpio4_dbck", &gpio4_dbck, CK_343X),
+ CLK(NULL, "gpio3_dbck", &gpio3_dbck, CK_343X),
+ CLK(NULL, "gpio2_dbck", &gpio2_dbck, CK_343X),
+ CLK(NULL, "wdt3_fck", &wdt3_fck, CK_343X),
+ CLK(NULL, "per_l4_ick", &per_l4_ick, CK_343X),
+ CLK(NULL, "gpio6_ick", &gpio6_ick, CK_343X),
+ CLK(NULL, "gpio5_ick", &gpio5_ick, CK_343X),
+ CLK(NULL, "gpio4_ick", &gpio4_ick, CK_343X),
+ CLK(NULL, "gpio3_ick", &gpio3_ick, CK_343X),
+ CLK(NULL, "gpio2_ick", &gpio2_ick, CK_343X),
+ CLK(NULL, "wdt3_ick", &wdt3_ick, CK_343X),
+ CLK(NULL, "uart3_ick", &uart3_ick, CK_343X),
+ CLK(NULL, "gpt9_ick", &gpt9_ick, CK_343X),
+ CLK(NULL, "gpt8_ick", &gpt8_ick, CK_343X),
+ CLK(NULL, "gpt7_ick", &gpt7_ick, CK_343X),
+ CLK(NULL, "gpt6_ick", &gpt6_ick, CK_343X),
+ CLK(NULL, "gpt5_ick", &gpt5_ick, CK_343X),
+ CLK(NULL, "gpt4_ick", &gpt4_ick, CK_343X),
+ CLK(NULL, "gpt3_ick", &gpt3_ick, CK_343X),
+ CLK(NULL, "gpt2_ick", &gpt2_ick, CK_343X),
+ CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_343X),
+ CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_343X),
+ CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_343X),
+ CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_343X),
+ CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_343X),
+ CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_343X),
+ CLK(NULL, "emu_src_ck", &emu_src_ck, CK_343X),
+ CLK(NULL, "pclk_fck", &pclk_fck, CK_343X),
+ CLK(NULL, "pclkx2_fck", &pclkx2_fck, CK_343X),
+ CLK(NULL, "atclk_fck", &atclk_fck, CK_343X),
+ CLK(NULL, "traceclk_src_fck", &traceclk_src_fck, CK_343X),
+ CLK(NULL, "traceclk_fck", &traceclk_fck, CK_343X),
+ CLK(NULL, "sr1_fck", &sr1_fck, CK_343X),
+ CLK(NULL, "sr2_fck", &sr2_fck, CK_343X),
+ CLK(NULL, "sr_l4_ick", &sr_l4_ick, CK_343X),
+ CLK(NULL, "secure_32k_fck", &secure_32k_fck, CK_343X),
+ CLK(NULL, "gpt12_fck", &gpt12_fck, CK_343X),
+ CLK(NULL, "wdt1_fck", &wdt1_fck, CK_343X),
+};
+
/* CM_AUTOIDLE_PLL*.AUTO_* bit values */
#define DPLL_AUTOIDLE_DISABLE 0x0
#define DPLL_AUTOIDLE_LOW_POWER_STOP 0x1
@@ -51,11 +287,9 @@
*
* Recalculate and propagate the DPLL rate.
*/
-static void omap3_dpll_recalc(struct clk *clk)
+static unsigned long omap3_dpll_recalc(struct clk *clk)
{
- clk->rate = omap2_get_dpll_rate(clk);
-
- propagate_rate(clk);
+ return omap2_get_dpll_rate(clk);
}
/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
@@ -78,14 +312,12 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
const struct dpll_data *dd;
int i = 0;
int ret = -EINVAL;
- u32 idlest_mask;
dd = clk->dpll_data;
- state <<= dd->idlest_bit;
- idlest_mask = 1 << dd->idlest_bit;
+ state <<= __ffs(dd->idlest_mask);
- while (((__raw_readl(dd->idlest_reg) & idlest_mask) != state) &&
+ while (((__raw_readl(dd->idlest_reg) & dd->idlest_mask) != state) &&
i < MAX_DPLL_WAIT_TRIES) {
i++;
udelay(1);
@@ -104,6 +336,42 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
return ret;
}
+/* From 3430 TRM ES2 4.7.6.2 */
+static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
+{
+ unsigned long fint;
+ u16 f = 0;
+
+ fint = clk->dpll_data->clk_ref->rate / (n + 1);
+
+ pr_debug("clock: fint is %lu\n", fint);
+
+ if (fint >= 750000 && fint <= 1000000)
+ f = 0x3;
+ else if (fint > 1000000 && fint <= 1250000)
+ f = 0x4;
+ else if (fint > 1250000 && fint <= 1500000)
+ f = 0x5;
+ else if (fint > 1500000 && fint <= 1750000)
+ f = 0x6;
+ else if (fint > 1750000 && fint <= 2100000)
+ f = 0x7;
+ else if (fint > 7500000 && fint <= 10000000)
+ f = 0xB;
+ else if (fint > 10000000 && fint <= 12500000)
+ f = 0xC;
+ else if (fint > 12500000 && fint <= 15000000)
+ f = 0xD;
+ else if (fint > 15000000 && fint <= 17500000)
+ f = 0xE;
+ else if (fint > 17500000 && fint <= 21000000)
+ f = 0xF;
+ else
+ pr_debug("clock: unknown freqsel setting for %d\n", n);
+
+ return f;
+}
+
/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
/*
@@ -128,25 +396,20 @@ static int _omap3_noncore_dpll_lock(struct clk *clk)
ai = omap3_dpll_autoidle_read(clk);
+ omap3_dpll_deny_idle(clk);
+
_omap3_dpll_write_clken(clk, DPLL_LOCKED);
- if (ai) {
- /*
- * If no downstream clocks are enabled, CM_IDLEST bit
- * may never become active, so don't wait for DPLL to lock.
- */
- r = 0;
+ r = _omap3_wait_dpll_status(clk, 1);
+
+ if (ai)
omap3_dpll_allow_idle(clk);
- } else {
- r = _omap3_wait_dpll_status(clk, 1);
- omap3_dpll_deny_idle(clk);
- };
return r;
}
/*
- * omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
+ * _omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
* @clk: pointer to a DPLL struct clk
*
* Instructs a non-CORE DPLL to enter low-power bypass mode. In
@@ -236,14 +499,25 @@ static int _omap3_noncore_dpll_stop(struct clk *clk)
static int omap3_noncore_dpll_enable(struct clk *clk)
{
int r;
+ struct dpll_data *dd;
if (clk == &dpll3_ck)
return -EINVAL;
- if (clk->parent->rate == clk_get_rate(clk))
+ dd = clk->dpll_data;
+ if (!dd)
+ return -EINVAL;
+
+ if (clk->rate == dd->clk_bypass->rate) {
+ WARN_ON(clk->parent != dd->clk_bypass);
r = _omap3_noncore_dpll_bypass(clk);
- else
+ } else {
+ WARN_ON(clk->parent != dd->clk_ref);
r = _omap3_noncore_dpll_lock(clk);
+ }
+ /* FIXME: this is dubious - if clk->rate has changed, what about propagating? */
+ if (!r)
+ clk->rate = omap2_get_dpll_rate(clk);
return r;
}
@@ -270,6 +544,215 @@ static void omap3_noncore_dpll_disable(struct clk *clk)
_omap3_noncore_dpll_stop(clk);
}
+
+/* Non-CORE DPLL rate set code */
+
+/*
+ * omap3_noncore_dpll_program - set non-core DPLL M,N values directly
+ * @clk: struct clk * of DPLL to set
+ * @m: DPLL multiplier to set
+ * @n: DPLL divider to set
+ * @freqsel: FREQSEL value to set
+ *
+ * Program the DPLL with the supplied M, N values, and wait for the DPLL to
+ * lock.. Returns -EINVAL upon error, or 0 upon success.
+ */
+static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
+{
+ struct dpll_data *dd = clk->dpll_data;
+ u32 v;
+
+ /* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
+ _omap3_noncore_dpll_bypass(clk);
+
+ /* Set jitter correction */
+ v = __raw_readl(dd->control_reg);
+ v &= ~dd->freqsel_mask;
+ v |= freqsel << __ffs(dd->freqsel_mask);
+ __raw_writel(v, dd->control_reg);
+
+ /* Set DPLL multiplier, divider */
+ v = __raw_readl(dd->mult_div1_reg);
+ v &= ~(dd->mult_mask | dd->div1_mask);
+ v |= m << __ffs(dd->mult_mask);
+ v |= (n - 1) << __ffs(dd->div1_mask);
+ __raw_writel(v, dd->mult_div1_reg);
+
+ /* We let the clock framework set the other output dividers later */
+
+ /* REVISIT: Set ramp-up delay? */
+
+ _omap3_noncore_dpll_lock(clk);
+
+ return 0;
+}
+
+/**
+ * omap3_noncore_dpll_set_rate - set non-core DPLL rate
+ * @clk: struct clk * of DPLL to set
+ * @rate: rounded target rate
+ *
+ * Set the DPLL CLKOUT to the target rate. If the DPLL can enter
+ * low-power bypass, and the target rate is the bypass source clock
+ * rate, then configure the DPLL for bypass. Otherwise, round the
+ * target rate if it hasn't been done already, then program and lock
+ * the DPLL. Returns -EINVAL upon error, or 0 upon success.
+ */
+static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct clk *new_parent = NULL;
+ u16 freqsel;
+ struct dpll_data *dd;
+ int ret;
+
+ if (!clk || !rate)
+ return -EINVAL;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return -EINVAL;
+
+ if (rate == omap2_get_dpll_rate(clk))
+ return 0;
+
+ /*
+ * Ensure both the bypass and ref clocks are enabled prior to
+ * doing anything; we need the bypass clock running to reprogram
+ * the DPLL.
+ */
+ omap2_clk_enable(dd->clk_bypass);
+ omap2_clk_enable(dd->clk_ref);
+
+ if (dd->clk_bypass->rate == rate &&
+ (clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
+ pr_debug("clock: %s: set rate: entering bypass.\n", clk->name);
+
+ ret = _omap3_noncore_dpll_bypass(clk);
+ if (!ret)
+ new_parent = dd->clk_bypass;
+ } else {
+ if (dd->last_rounded_rate != rate)
+ omap2_dpll_round_rate(clk, rate);
+
+ if (dd->last_rounded_rate == 0)
+ return -EINVAL;
+
+ freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n);
+ if (!freqsel)
+ WARN_ON(1);
+
+ pr_debug("clock: %s: set rate: locking rate to %lu.\n",
+ clk->name, rate);
+
+ ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
+ dd->last_rounded_n, freqsel);
+ if (!ret)
+ new_parent = dd->clk_ref;
+ }
+ if (!ret) {
+ /*
+ * Switch the parent clock in the heirarchy, and make sure
+ * that the new parent's usecount is correct. Note: we
+ * enable the new parent before disabling the old to avoid
+ * any unnecessary hardware disable->enable transitions.
+ */
+ if (clk->usecount) {
+ omap2_clk_enable(new_parent);
+ omap2_clk_disable(clk->parent);
+ }
+ clk_reparent(clk, new_parent);
+ clk->rate = rate;
+ }
+ omap2_clk_disable(dd->clk_ref);
+ omap2_clk_disable(dd->clk_bypass);
+
+ return 0;
+}
+
+static int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
+{
+ /*
+ * According to the 12-5 CDP code from TI, "Limitation 2.5"
+ * on 3430ES1 prevents us from changing DPLL multipliers or dividers
+ * on DPLL4.
+ */
+ if (omap_rev() == OMAP3430_REV_ES1_0) {
+ printk(KERN_ERR "clock: DPLL4 cannot change rate due to "
+ "silicon 'Limitation 2.5' on 3430ES1.\n");
+ return -EINVAL;
+ }
+ return omap3_noncore_dpll_set_rate(clk, rate);
+}
+
+
+/*
+ * CORE DPLL (DPLL3) rate programming functions
+ *
+ * These call into SRAM code to do the actual CM writes, since the SDRAM
+ * is clocked from DPLL3.
+ */
+
+/**
+ * omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
+ * @clk: struct clk * of DPLL to set
+ * @rate: rounded target rate
+ *
+ * Program the DPLL M2 divider with the rounded target rate. Returns
+ * -EINVAL upon error, or 0 upon success.
+ */
+static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 new_div = 0;
+ unsigned long validrate, sdrcrate;
+ struct omap_sdrc_params *sp;
+
+ if (!clk || !rate)
+ return -EINVAL;
+
+ if (clk != &dpll3_m2_ck)
+ return -EINVAL;
+
+ if (rate == clk->rate)
+ return 0;
+
+ validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
+ if (validrate != rate)
+ return -EINVAL;
+
+ sdrcrate = sdrc_ick.rate;
+ if (rate > clk->rate)
+ sdrcrate <<= ((rate / clk->rate) - 1);
+ else
+ sdrcrate >>= ((clk->rate / rate) - 1);
+
+ sp = omap2_sdrc_get_params(sdrcrate);
+ if (!sp)
+ return -EINVAL;
+
+ pr_info("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
+ validrate);
+ pr_info("clock: SDRC timing params used: %08x %08x %08x\n",
+ sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb);
+
+ /* REVISIT: SRAM code doesn't support other M2 divisors yet */
+ WARN_ON(new_div != 1 && new_div != 2);
+
+ /* REVISIT: Add SDRC_MR changing to this code also */
+ omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla,
+ sp->actim_ctrlb, new_div);
+
+ return 0;
+}
+
+
+static const struct clkops clkops_noncore_dpll_ops = {
+ .enable = &omap3_noncore_dpll_enable,
+ .disable = &omap3_noncore_dpll_disable,
+};
+
+/* DPLL autoidle read/set code */
+
+
/**
* omap3_dpll_autoidle_read - read a DPLL's autoidle bits
* @clk: struct clk * of the DPLL to read
@@ -356,9 +839,10 @@ static void omap3_dpll_deny_idle(struct clk *clk)
* Using parent clock DPLL data, look up DPLL state. If locked, set our
* rate to the dpll_clk * 2; otherwise, just use dpll_clk.
*/
-static void omap3_clkoutx2_recalc(struct clk *clk)
+static unsigned long omap3_clkoutx2_recalc(struct clk *clk)
{
const struct dpll_data *dd;
+ unsigned long rate;
u32 v;
struct clk *pclk;
@@ -372,17 +856,15 @@ static void omap3_clkoutx2_recalc(struct clk *clk)
dd = pclk->dpll_data;
- WARN_ON(!dd->control_reg || !dd->enable_mask);
+ WARN_ON(!dd->enable_mask);
v = __raw_readl(dd->control_reg) & dd->enable_mask;
v >>= __ffs(dd->enable_mask);
- if (v != DPLL_LOCKED)
- clk->rate = clk->parent->rate;
+ if (v != OMAP3XXX_EN_DPLL_LOCKED)
+ rate = clk->parent->rate;
else
- clk->rate = clk->parent->rate * 2;
-
- if (clk->flags & RATE_PROPAGATES)
- propagate_rate(clk);
+ rate = clk->parent->rate * 2;
+ return rate;
}
/* Common clock code */
@@ -432,7 +914,7 @@ static int __init omap2_clk_arch_init(void)
/* REVISIT: not yet ready for 343x */
#if 0
- if (omap2_select_table_rate(&virt_prcm_set, mpurate))
+ if (clk_set_rate(&virt_prcm_set, mpurate))
printk(KERN_ERR "Could not find matching MPU rate\n");
#endif
@@ -450,26 +932,13 @@ arch_initcall(omap2_clk_arch_init);
int __init omap2_clk_init(void)
{
/* struct prcm_config *prcm; */
- struct clk **clkp;
+ struct omap_clk *c;
/* u32 clkrate; */
u32 cpu_clkflg;
- /* REVISIT: Ultimately this will be used for multiboot */
-#if 0
- if (cpu_is_omap242x()) {
- cpu_mask = RATE_IN_242X;
- cpu_clkflg = CLOCK_IN_OMAP242X;
- clkp = onchip_24xx_clks;
- } else if (cpu_is_omap2430()) {
- cpu_mask = RATE_IN_243X;
- cpu_clkflg = CLOCK_IN_OMAP243X;
- clkp = onchip_24xx_clks;
- }
-#endif
if (cpu_is_omap34xx()) {
cpu_mask = RATE_IN_343X;
- cpu_clkflg = CLOCK_IN_OMAP343X;
- clkp = onchip_34xx_clks;
+ cpu_clkflg = CK_343X;
/*
* Update this if there are further clock changes between ES2
@@ -477,23 +946,24 @@ int __init omap2_clk_init(void)
*/
if (omap_rev() == OMAP3430_REV_ES1_0) {
/* No 3430ES1-only rates exist, so no RATE_IN_3430ES1 */
- cpu_clkflg |= CLOCK_IN_OMAP3430ES1;
+ cpu_clkflg |= CK_3430ES1;
} else {
cpu_mask |= RATE_IN_3430ES2;
- cpu_clkflg |= CLOCK_IN_OMAP3430ES2;
+ cpu_clkflg |= CK_3430ES2;
}
}
clk_init(&omap2_clk_functions);
- for (clkp = onchip_34xx_clks;
- clkp < onchip_34xx_clks + ARRAY_SIZE(onchip_34xx_clks);
- clkp++) {
- if ((*clkp)->flags & cpu_clkflg) {
- clk_register(*clkp);
- omap2_init_clk_clkdm(*clkp);
+ for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
+ clk_init_one(c->lk.clk);
+
+ for (c = omap34xx_clks; c < omap34xx_clks + ARRAY_SIZE(omap34xx_clks); c++)
+ if (c->cpu & cpu_clkflg) {
+ clkdev_add(&c->lk);
+ clk_register(c->lk.clk);
+ omap2_init_clk_clkdm(c->lk.clk);
}
- }
/* REVISIT: Not yet ready for OMAP3 */
#if 0
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index a826094d89b5..70ec10deb654 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -27,13 +27,14 @@
#include "prm.h"
#include "prm-regbits-34xx.h"
-static void omap3_dpll_recalc(struct clk *clk);
-static void omap3_clkoutx2_recalc(struct clk *clk);
+static unsigned long omap3_dpll_recalc(struct clk *clk);
+static unsigned long omap3_clkoutx2_recalc(struct clk *clk);
static void omap3_dpll_allow_idle(struct clk *clk);
static void omap3_dpll_deny_idle(struct clk *clk);
static u32 omap3_dpll_autoidle_read(struct clk *clk);
-static int omap3_noncore_dpll_enable(struct clk *clk);
-static void omap3_noncore_dpll_disable(struct clk *clk);
+static int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate);
+static int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
+static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
/* Maximum DPLL multiplier, divider values for OMAP3 */
#define OMAP3_MAX_DPLL_MULT 2048
@@ -47,6 +48,10 @@ static void omap3_noncore_dpll_disable(struct clk *clk);
* DPLL5 supplies other peripheral clocks (USBHOST, USIM).
*/
+/* Forward declarations for DPLL bypass clocks */
+static struct clk dpll1_fck;
+static struct clk dpll2_fck;
+
/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */
#define DPLL_LOW_POWER_STOP 0x1
#define DPLL_LOW_POWER_BYPASS 0x5
@@ -57,67 +62,59 @@ static void omap3_noncore_dpll_disable(struct clk *clk);
/* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */
static struct clk omap_32k_fck = {
.name = "omap_32k_fck",
+ .ops = &clkops_null,
.rate = 32768,
- .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
- ALWAYS_ENABLED,
- .recalc = &propagate_rate,
+ .flags = RATE_FIXED,
};
static struct clk secure_32k_fck = {
.name = "secure_32k_fck",
+ .ops = &clkops_null,
.rate = 32768,
- .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
- ALWAYS_ENABLED,
- .recalc = &propagate_rate,
+ .flags = RATE_FIXED,
};
/* Virtual source clocks for osc_sys_ck */
static struct clk virt_12m_ck = {
.name = "virt_12m_ck",
+ .ops = &clkops_null,
.rate = 12000000,
- .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
- ALWAYS_ENABLED,
- .recalc = &propagate_rate,
+ .flags = RATE_FIXED,
};
static struct clk virt_13m_ck = {
.name = "virt_13m_ck",
+ .ops = &clkops_null,
.rate = 13000000,
- .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
- ALWAYS_ENABLED,
- .recalc = &propagate_rate,
+ .flags = RATE_FIXED,
};
static struct clk virt_16_8m_ck = {
.name = "virt_16_8m_ck",
+ .ops = &clkops_null,
.rate = 16800000,
- .flags = CLOCK_IN_OMAP3430ES2 | RATE_FIXED | RATE_PROPAGATES |
- ALWAYS_ENABLED,
- .recalc = &propagate_rate,
+ .flags = RATE_FIXED,
};
static struct clk virt_19_2m_ck = {
.name = "virt_19_2m_ck",
+ .ops = &clkops_null,
.rate = 19200000,
- .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
- ALWAYS_ENABLED,
- .recalc = &propagate_rate,
+ .flags = RATE_FIXED,
};
static struct clk virt_26m_ck = {
.name = "virt_26m_ck",
+ .ops = &clkops_null,
.rate = 26000000,
- .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
- ALWAYS_ENABLED,
- .recalc = &propagate_rate,
+ .flags = RATE_FIXED,
};
static struct clk virt_38_4m_ck = {
.name = "virt_38_4m_ck",
+ .ops = &clkops_null,
.rate = 38400000,
- .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
- ALWAYS_ENABLED,
- .recalc = &propagate_rate,
+ .flags = RATE_FIXED,
};
static const struct clksel_rate osc_sys_12m_rates[] = {
@@ -164,13 +161,13 @@ static const struct clksel osc_sys_clksel[] = {
/* 12, 13, 16.8, 19.2, 26, or 38.4 MHz */
static struct clk osc_sys_ck = {
.name = "osc_sys_ck",
+ .ops = &clkops_null,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP3430_PRM_CLKSEL,
.clksel_mask = OMAP3430_SYS_CLKIN_SEL_MASK,
.clksel = osc_sys_clksel,
/* REVISIT: deal with autoextclkmode? */
- .flags = CLOCK_IN_OMAP343X | RATE_FIXED | RATE_PROPAGATES |
- ALWAYS_ENABLED,
+ .flags = RATE_FIXED,
.recalc = &omap2_clksel_recalc,
};
@@ -189,36 +186,34 @@ static const struct clksel sys_clksel[] = {
/* Feeds DPLLs - divided first by PRM_CLKSRC_CTRL.SYSCLKDIV? */
static struct clk sys_ck = {
.name = "sys_ck",
+ .ops = &clkops_null,
.parent = &osc_sys_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP3430_PRM_CLKSRC_CTRL,
.clksel_mask = OMAP_SYSCLKDIV_MASK,
.clksel = sys_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
.recalc = &omap2_clksel_recalc,
};
static struct clk sys_altclk = {
.name = "sys_altclk",
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
- .recalc = &propagate_rate,
+ .ops = &clkops_null,
};
/* Optional external clock input for some McBSPs */
static struct clk mcbsp_clks = {
.name = "mcbsp_clks",
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
- .recalc = &propagate_rate,
+ .ops = &clkops_null,
};
/* PRM EXTERNAL CLOCK OUTPUT */
static struct clk sys_clkout1 = {
.name = "sys_clkout1",
+ .ops = &clkops_omap2_dflt,
.parent = &osc_sys_ck,
.enable_reg = OMAP3430_PRM_CLKOUT_CTRL,
.enable_bit = OMAP3430_CLKOUT_EN_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.recalc = &followparent_recalc,
};
@@ -226,16 +221,6 @@ static struct clk sys_clkout1 = {
/* CM CLOCKS */
-static const struct clksel_rate dpll_bypass_rates[] = {
- { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
- { .div = 0 }
-};
-
-static const struct clksel_rate dpll_locked_rates[] = {
- { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
- { .div = 0 }
-};
-
static const struct clksel_rate div16_dpll_rates[] = {
{ .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
{ .div = 2, .val = 2, .flags = RATE_IN_343X },
@@ -263,6 +248,9 @@ static struct dpll_data dpll1_dd = {
.mult_div1_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
.mult_mask = OMAP3430_MPU_DPLL_MULT_MASK,
.div1_mask = OMAP3430_MPU_DPLL_DIV_MASK,
+ .clk_bypass = &dpll1_fck,
+ .clk_ref = &sys_ck,
+ .freqsel_mask = OMAP3430_MPU_DPLL_FREQSEL_MASK,
.control_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL),
.enable_mask = OMAP3430_EN_MPU_DPLL_MASK,
.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
@@ -272,18 +260,21 @@ static struct dpll_data dpll1_dd = {
.autoidle_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL),
.autoidle_mask = OMAP3430_AUTO_MPU_DPLL_MASK,
.idlest_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
- .idlest_bit = OMAP3430_ST_MPU_CLK_SHIFT,
+ .idlest_mask = OMAP3430_ST_MPU_CLK_MASK,
.max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .min_divider = 1,
.max_divider = OMAP3_MAX_DPLL_DIV,
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
};
static struct clk dpll1_ck = {
.name = "dpll1_ck",
+ .ops = &clkops_null,
.parent = &sys_ck,
.dpll_data = &dpll1_dd,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
.round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_noncore_dpll_set_rate,
+ .clkdm_name = "dpll1_clkdm",
.recalc = &omap3_dpll_recalc,
};
@@ -293,9 +284,9 @@ static struct clk dpll1_ck = {
*/
static struct clk dpll1_x2_ck = {
.name = "dpll1_x2_ck",
+ .ops = &clkops_null,
.parent = &dpll1_ck,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll1_clkdm",
.recalc = &omap3_clkoutx2_recalc,
};
@@ -311,13 +302,13 @@ static const struct clksel div16_dpll1_x2m2_clksel[] = {
*/
static struct clk dpll1_x2m2_ck = {
.name = "dpll1_x2m2_ck",
+ .ops = &clkops_null,
.parent = &dpll1_x2_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL),
.clksel_mask = OMAP3430_MPU_DPLL_CLKOUT_DIV_MASK,
.clksel = div16_dpll1_x2m2_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll1_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -329,6 +320,9 @@ static struct dpll_data dpll2_dd = {
.mult_div1_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
.mult_mask = OMAP3430_IVA2_DPLL_MULT_MASK,
.div1_mask = OMAP3430_IVA2_DPLL_DIV_MASK,
+ .clk_bypass = &dpll2_fck,
+ .clk_ref = &sys_ck,
+ .freqsel_mask = OMAP3430_IVA2_DPLL_FREQSEL_MASK,
.control_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL),
.enable_mask = OMAP3430_EN_IVA2_DPLL_MASK,
.modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) |
@@ -339,20 +333,21 @@ static struct dpll_data dpll2_dd = {
.autoidle_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL),
.autoidle_mask = OMAP3430_AUTO_IVA2_DPLL_MASK,
.idlest_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL),
- .idlest_bit = OMAP3430_ST_IVA2_CLK_SHIFT,
+ .idlest_mask = OMAP3430_ST_IVA2_CLK_MASK,
.max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .min_divider = 1,
.max_divider = OMAP3_MAX_DPLL_DIV,
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
};
static struct clk dpll2_ck = {
.name = "dpll2_ck",
+ .ops = &clkops_noncore_dpll_ops,
.parent = &sys_ck,
.dpll_data = &dpll2_dd,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
- .enable = &omap3_noncore_dpll_enable,
- .disable = &omap3_noncore_dpll_disable,
.round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_noncore_dpll_set_rate,
+ .clkdm_name = "dpll2_clkdm",
.recalc = &omap3_dpll_recalc,
};
@@ -367,14 +362,14 @@ static const struct clksel div16_dpll2_m2x2_clksel[] = {
*/
static struct clk dpll2_m2_ck = {
.name = "dpll2_m2_ck",
+ .ops = &clkops_null,
.parent = &dpll2_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD,
OMAP3430_CM_CLKSEL2_PLL),
.clksel_mask = OMAP3430_IVA2_DPLL_CLKOUT_DIV_MASK,
.clksel = div16_dpll2_m2x2_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll2_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -387,6 +382,9 @@ static struct dpll_data dpll3_dd = {
.mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
.mult_mask = OMAP3430_CORE_DPLL_MULT_MASK,
.div1_mask = OMAP3430_CORE_DPLL_DIV_MASK,
+ .clk_bypass = &sys_ck,
+ .clk_ref = &sys_ck,
+ .freqsel_mask = OMAP3430_CORE_DPLL_FREQSEL_MASK,
.control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
.enable_mask = OMAP3430_EN_CORE_DPLL_MASK,
.auto_recal_bit = OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT,
@@ -394,17 +392,21 @@ static struct dpll_data dpll3_dd = {
.recal_st_bit = OMAP3430_CORE_DPLL_ST_SHIFT,
.autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
.autoidle_mask = OMAP3430_AUTO_CORE_DPLL_MASK,
+ .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
+ .idlest_mask = OMAP3430_ST_CORE_CLK_MASK,
.max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .min_divider = 1,
.max_divider = OMAP3_MAX_DPLL_DIV,
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
};
static struct clk dpll3_ck = {
.name = "dpll3_ck",
+ .ops = &clkops_null,
.parent = &sys_ck,
.dpll_data = &dpll3_dd,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
.round_rate = &omap2_dpll_round_rate,
+ .clkdm_name = "dpll3_clkdm",
.recalc = &omap3_dpll_recalc,
};
@@ -414,9 +416,9 @@ static struct clk dpll3_ck = {
*/
static struct clk dpll3_x2_ck = {
.name = "dpll3_x2_ck",
+ .ops = &clkops_null,
.parent = &dpll3_ck,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll3_clkdm",
.recalc = &omap3_clkoutx2_recalc,
};
@@ -460,55 +462,34 @@ static const struct clksel div31_dpll3m2_clksel[] = {
{ .parent = NULL }
};
-/*
- * DPLL3 output M2
- * REVISIT: This DPLL output divider must be changed in SRAM, so until
- * that code is ready, this should remain a 'read-only' clksel clock.
- */
+/* DPLL3 output M2 - primary control point for CORE speed */
static struct clk dpll3_m2_ck = {
.name = "dpll3_m2_ck",
+ .ops = &clkops_null,
.parent = &dpll3_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
.clksel_mask = OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK,
.clksel = div31_dpll3m2_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll3_clkdm",
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap3_core_dpll_m2_set_rate,
.recalc = &omap2_clksel_recalc,
};
-static const struct clksel core_ck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
- { .parent = &dpll3_m2_ck, .rates = dpll_locked_rates },
- { .parent = NULL }
-};
-
static struct clk core_ck = {
.name = "core_ck",
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_CORE_CLK_MASK,
- .clksel = core_ck_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
- .recalc = &omap2_clksel_recalc,
-};
-
-static const struct clksel dpll3_m2x2_ck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
- { .parent = &dpll3_x2_ck, .rates = dpll_locked_rates },
- { .parent = NULL }
+ .ops = &clkops_null,
+ .parent = &dpll3_m2_ck,
+ .recalc = &followparent_recalc,
};
static struct clk dpll3_m2x2_ck = {
.name = "dpll3_m2x2_ck",
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_CORE_CLK_MASK,
- .clksel = dpll3_m2x2_ck_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
- .recalc = &omap2_clksel_recalc,
+ .ops = &clkops_null,
+ .parent = &dpll3_x2_ck,
+ .clkdm_name = "dpll3_clkdm",
+ .recalc = &followparent_recalc,
};
/* The PWRDN bit is apparently only available on 3430ES2 and above */
@@ -520,42 +501,34 @@ static const struct clksel div16_dpll3_clksel[] = {
/* This virtual clock is the source for dpll3_m3x2_ck */
static struct clk dpll3_m3_ck = {
.name = "dpll3_m3_ck",
+ .ops = &clkops_null,
.parent = &dpll3_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
.clksel_mask = OMAP3430_DIV_DPLL3_MASK,
.clksel = div16_dpll3_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll3_clkdm",
.recalc = &omap2_clksel_recalc,
};
/* The PWRDN bit is apparently only available on 3430ES2 and above */
static struct clk dpll3_m3x2_ck = {
.name = "dpll3_m3x2_ck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &dpll3_m3_ck,
.enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
.enable_bit = OMAP3430_PWRDN_EMU_CORE_SHIFT,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE,
+ .flags = INVERT_ENABLE,
+ .clkdm_name = "dpll3_clkdm",
.recalc = &omap3_clkoutx2_recalc,
};
-static const struct clksel emu_core_alwon_ck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
- { .parent = &dpll3_m3x2_ck, .rates = dpll_locked_rates },
- { .parent = NULL }
-};
-
static struct clk emu_core_alwon_ck = {
.name = "emu_core_alwon_ck",
+ .ops = &clkops_null,
.parent = &dpll3_m3x2_ck,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_CORE_CLK_MASK,
- .clksel = emu_core_alwon_ck_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
- .recalc = &omap2_clksel_recalc,
+ .clkdm_name = "dpll3_clkdm",
+ .recalc = &followparent_recalc,
};
/* DPLL4 */
@@ -565,6 +538,9 @@ static struct dpll_data dpll4_dd = {
.mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
.mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK,
.div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK,
+ .clk_bypass = &sys_ck,
+ .clk_ref = &sys_ck,
+ .freqsel_mask = OMAP3430_PERIPH_DPLL_FREQSEL_MASK,
.control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
.enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK,
.modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
@@ -574,20 +550,21 @@ static struct dpll_data dpll4_dd = {
.autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
.autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK,
.idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .idlest_bit = OMAP3430_ST_PERIPH_CLK_SHIFT,
+ .idlest_mask = OMAP3430_ST_PERIPH_CLK_MASK,
.max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .min_divider = 1,
.max_divider = OMAP3_MAX_DPLL_DIV,
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
};
static struct clk dpll4_ck = {
.name = "dpll4_ck",
+ .ops = &clkops_noncore_dpll_ops,
.parent = &sys_ck,
.dpll_data = &dpll4_dd,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
- .enable = &omap3_noncore_dpll_enable,
- .disable = &omap3_noncore_dpll_disable,
.round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_dpll4_set_rate,
+ .clkdm_name = "dpll4_clkdm",
.recalc = &omap3_dpll_recalc,
};
@@ -598,9 +575,9 @@ static struct clk dpll4_ck = {
*/
static struct clk dpll4_x2_ck = {
.name = "dpll4_x2_ck",
+ .ops = &clkops_null,
.parent = &dpll4_ck,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll4_clkdm",
.recalc = &omap3_clkoutx2_recalc,
};
@@ -612,112 +589,101 @@ static const struct clksel div16_dpll4_clksel[] = {
/* This virtual clock is the source for dpll4_m2x2_ck */
static struct clk dpll4_m2_ck = {
.name = "dpll4_m2_ck",
+ .ops = &clkops_null,
.parent = &dpll4_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3),
.clksel_mask = OMAP3430_DIV_96M_MASK,
.clksel = div16_dpll4_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll4_clkdm",
.recalc = &omap2_clksel_recalc,
};
/* The PWRDN bit is apparently only available on 3430ES2 and above */
static struct clk dpll4_m2x2_ck = {
.name = "dpll4_m2x2_ck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &dpll4_m2_ck,
.enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
.enable_bit = OMAP3430_PWRDN_96M_SHIFT,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE,
+ .flags = INVERT_ENABLE,
+ .clkdm_name = "dpll4_clkdm",
.recalc = &omap3_clkoutx2_recalc,
};
-static const struct clksel omap_96m_alwon_fck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
- { .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates },
- { .parent = NULL }
-};
-
+/*
+ * DPLL4 generates DPLL4_M2X2_CLK which is then routed into the PRM as
+ * PRM_96M_ALWON_(F)CLK. Two clocks then emerge from the PRM:
+ * 96M_ALWON_FCLK (called "omap_96m_alwon_fck" below) and
+ * CM_96K_(F)CLK.
+ */
static struct clk omap_96m_alwon_fck = {
.name = "omap_96m_alwon_fck",
+ .ops = &clkops_null,
.parent = &dpll4_m2x2_ck,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
- .clksel = omap_96m_alwon_fck_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &followparent_recalc,
};
-static struct clk omap_96m_fck = {
- .name = "omap_96m_fck",
+static struct clk cm_96m_fck = {
+ .name = "cm_96m_fck",
+ .ops = &clkops_null,
.parent = &omap_96m_alwon_fck,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.recalc = &followparent_recalc,
};
-static const struct clksel cm_96m_fck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
- { .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates },
+static const struct clksel_rate omap_96m_dpll_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
+ { .div = 0 }
+};
+
+static const struct clksel_rate omap_96m_sys_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+ { .div = 0 }
+};
+
+static const struct clksel omap_96m_fck_clksel[] = {
+ { .parent = &cm_96m_fck, .rates = omap_96m_dpll_rates },
+ { .parent = &sys_ck, .rates = omap_96m_sys_rates },
{ .parent = NULL }
};
-static struct clk cm_96m_fck = {
- .name = "cm_96m_fck",
- .parent = &dpll4_m2x2_ck,
+static struct clk omap_96m_fck = {
+ .name = "omap_96m_fck",
+ .ops = &clkops_null,
+ .parent = &sys_ck,
.init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
- .clksel = cm_96m_fck_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP3430_SOURCE_96M_MASK,
+ .clksel = omap_96m_fck_clksel,
.recalc = &omap2_clksel_recalc,
};
/* This virtual clock is the source for dpll4_m3x2_ck */
static struct clk dpll4_m3_ck = {
.name = "dpll4_m3_ck",
+ .ops = &clkops_null,
.parent = &dpll4_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_TV_MASK,
.clksel = div16_dpll4_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll4_clkdm",
.recalc = &omap2_clksel_recalc,
};
/* The PWRDN bit is apparently only available on 3430ES2 and above */
static struct clk dpll4_m3x2_ck = {
.name = "dpll4_m3x2_ck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &dpll4_m3_ck,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
.enable_bit = OMAP3430_PWRDN_TV_SHIFT,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE,
+ .flags = INVERT_ENABLE,
+ .clkdm_name = "dpll4_clkdm",
.recalc = &omap3_clkoutx2_recalc,
};
-static const struct clksel virt_omap_54m_fck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
- { .parent = &dpll4_m3x2_ck, .rates = dpll_locked_rates },
- { .parent = NULL }
-};
-
-static struct clk virt_omap_54m_fck = {
- .name = "virt_omap_54m_fck",
- .parent = &dpll4_m3x2_ck,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
- .clksel = virt_omap_54m_fck_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
- .recalc = &omap2_clksel_recalc,
-};
-
static const struct clksel_rate omap_54m_d4m3x2_rates[] = {
{ .div = 1, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
{ .div = 0 }
@@ -729,23 +695,22 @@ static const struct clksel_rate omap_54m_alt_rates[] = {
};
static const struct clksel omap_54m_clksel[] = {
- { .parent = &virt_omap_54m_fck, .rates = omap_54m_d4m3x2_rates },
+ { .parent = &dpll4_m3x2_ck, .rates = omap_54m_d4m3x2_rates },
{ .parent = &sys_altclk, .rates = omap_54m_alt_rates },
{ .parent = NULL }
};
static struct clk omap_54m_fck = {
.name = "omap_54m_fck",
+ .ops = &clkops_null,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
- .clksel_mask = OMAP3430_SOURCE_54M,
+ .clksel_mask = OMAP3430_SOURCE_54M_MASK,
.clksel = omap_54m_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.recalc = &omap2_clksel_recalc,
};
-static const struct clksel_rate omap_48m_96md2_rates[] = {
+static const struct clksel_rate omap_48m_cm96m_rates[] = {
{ .div = 2, .val = 0, .flags = RATE_IN_343X | DEFAULT_RATE },
{ .div = 0 }
};
@@ -756,106 +721,112 @@ static const struct clksel_rate omap_48m_alt_rates[] = {
};
static const struct clksel omap_48m_clksel[] = {
- { .parent = &cm_96m_fck, .rates = omap_48m_96md2_rates },
+ { .parent = &cm_96m_fck, .rates = omap_48m_cm96m_rates },
{ .parent = &sys_altclk, .rates = omap_48m_alt_rates },
{ .parent = NULL }
};
static struct clk omap_48m_fck = {
.name = "omap_48m_fck",
+ .ops = &clkops_null,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
- .clksel_mask = OMAP3430_SOURCE_48M,
+ .clksel_mask = OMAP3430_SOURCE_48M_MASK,
.clksel = omap_48m_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.recalc = &omap2_clksel_recalc,
};
static struct clk omap_12m_fck = {
.name = "omap_12m_fck",
+ .ops = &clkops_null,
.parent = &omap_48m_fck,
.fixed_div = 4,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.recalc = &omap2_fixed_divisor_recalc,
};
/* This virstual clock is the source for dpll4_m4x2_ck */
static struct clk dpll4_m4_ck = {
.name = "dpll4_m4_ck",
+ .ops = &clkops_null,
.parent = &dpll4_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_DSS1_MASK,
.clksel = div16_dpll4_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll4_clkdm",
.recalc = &omap2_clksel_recalc,
+ .set_rate = &omap2_clksel_set_rate,
+ .round_rate = &omap2_clksel_round_rate,
};
/* The PWRDN bit is apparently only available on 3430ES2 and above */
static struct clk dpll4_m4x2_ck = {
.name = "dpll4_m4x2_ck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &dpll4_m4_ck,
.enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
.enable_bit = OMAP3430_PWRDN_CAM_SHIFT,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE,
+ .flags = INVERT_ENABLE,
+ .clkdm_name = "dpll4_clkdm",
.recalc = &omap3_clkoutx2_recalc,
};
/* This virtual clock is the source for dpll4_m5x2_ck */
static struct clk dpll4_m5_ck = {
.name = "dpll4_m5_ck",
+ .ops = &clkops_null,
.parent = &dpll4_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_CAM_MASK,
.clksel = div16_dpll4_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll4_clkdm",
.recalc = &omap2_clksel_recalc,
};
/* The PWRDN bit is apparently only available on 3430ES2 and above */
static struct clk dpll4_m5x2_ck = {
.name = "dpll4_m5x2_ck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &dpll4_m5_ck,
.enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
.enable_bit = OMAP3430_PWRDN_CAM_SHIFT,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE,
+ .flags = INVERT_ENABLE,
+ .clkdm_name = "dpll4_clkdm",
.recalc = &omap3_clkoutx2_recalc,
};
/* This virtual clock is the source for dpll4_m6x2_ck */
static struct clk dpll4_m6_ck = {
.name = "dpll4_m6_ck",
+ .ops = &clkops_null,
.parent = &dpll4_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
.clksel_mask = OMAP3430_DIV_DPLL4_MASK,
.clksel = div16_dpll4_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll4_clkdm",
.recalc = &omap2_clksel_recalc,
};
/* The PWRDN bit is apparently only available on 3430ES2 and above */
static struct clk dpll4_m6x2_ck = {
.name = "dpll4_m6x2_ck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &dpll4_m6_ck,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
.enable_bit = OMAP3430_PWRDN_EMU_PERIPH_SHIFT,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | INVERT_ENABLE,
+ .flags = INVERT_ENABLE,
+ .clkdm_name = "dpll4_clkdm",
.recalc = &omap3_clkoutx2_recalc,
};
static struct clk emu_per_alwon_ck = {
.name = "emu_per_alwon_ck",
+ .ops = &clkops_null,
.parent = &dpll4_m6x2_ck,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll4_clkdm",
.recalc = &followparent_recalc,
};
@@ -867,6 +838,9 @@ static struct dpll_data dpll5_dd = {
.mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4),
.mult_mask = OMAP3430ES2_PERIPH2_DPLL_MULT_MASK,
.div1_mask = OMAP3430ES2_PERIPH2_DPLL_DIV_MASK,
+ .clk_bypass = &sys_ck,
+ .clk_ref = &sys_ck,
+ .freqsel_mask = OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK,
.control_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2),
.enable_mask = OMAP3430ES2_EN_PERIPH2_DPLL_MASK,
.modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
@@ -876,20 +850,21 @@ static struct dpll_data dpll5_dd = {
.autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL),
.autoidle_mask = OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK,
.idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
- .idlest_bit = OMAP3430ES2_ST_PERIPH2_CLK_SHIFT,
+ .idlest_mask = OMAP3430ES2_ST_PERIPH2_CLK_MASK,
.max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .min_divider = 1,
.max_divider = OMAP3_MAX_DPLL_DIV,
.rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
};
static struct clk dpll5_ck = {
.name = "dpll5_ck",
+ .ops = &clkops_noncore_dpll_ops,
.parent = &sys_ck,
.dpll_data = &dpll5_dd,
- .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES,
- .enable = &omap3_noncore_dpll_enable,
- .disable = &omap3_noncore_dpll_disable,
.round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_noncore_dpll_set_rate,
+ .clkdm_name = "dpll5_clkdm",
.recalc = &omap3_dpll_recalc,
};
@@ -900,31 +875,13 @@ static const struct clksel div16_dpll5_clksel[] = {
static struct clk dpll5_m2_ck = {
.name = "dpll5_m2_ck",
+ .ops = &clkops_null,
.parent = &dpll5_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL5),
.clksel_mask = OMAP3430ES2_DIV_120M_MASK,
.clksel = div16_dpll5_clksel,
- .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
- .recalc = &omap2_clksel_recalc,
-};
-
-static const struct clksel omap_120m_fck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
- { .parent = &dpll5_m2_ck, .rates = dpll_locked_rates },
- { .parent = NULL }
-};
-
-static struct clk omap_120m_fck = {
- .name = "omap_120m_fck",
- .parent = &dpll5_m2_ck,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
- .clksel_mask = OMAP3430ES2_ST_PERIPH2_CLK_MASK,
- .clksel = omap_120m_fck_clksel,
- .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "dpll5_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -951,22 +908,23 @@ static const struct clksel_rate clkout2_src_54m_rates[] = {
};
static const struct clksel clkout2_src_clksel[] = {
- { .parent = &core_ck, .rates = clkout2_src_core_rates },
- { .parent = &sys_ck, .rates = clkout2_src_sys_rates },
- { .parent = &omap_96m_alwon_fck, .rates = clkout2_src_96m_rates },
- { .parent = &omap_54m_fck, .rates = clkout2_src_54m_rates },
+ { .parent = &core_ck, .rates = clkout2_src_core_rates },
+ { .parent = &sys_ck, .rates = clkout2_src_sys_rates },
+ { .parent = &cm_96m_fck, .rates = clkout2_src_96m_rates },
+ { .parent = &omap_54m_fck, .rates = clkout2_src_54m_rates },
{ .parent = NULL }
};
static struct clk clkout2_src_ck = {
.name = "clkout2_src_ck",
+ .ops = &clkops_omap2_dflt,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP3430_CM_CLKOUT_CTRL,
.enable_bit = OMAP3430_CLKOUT2_EN_SHIFT,
.clksel_reg = OMAP3430_CM_CLKOUT_CTRL,
.clksel_mask = OMAP3430_CLKOUT2SOURCE_MASK,
.clksel = clkout2_src_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
+ .clkdm_name = "core_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -986,11 +944,11 @@ static const struct clksel sys_clkout2_clksel[] = {
static struct clk sys_clkout2 = {
.name = "sys_clkout2",
+ .ops = &clkops_null,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP3430_CM_CLKOUT_CTRL,
.clksel_mask = OMAP3430_CLKOUT2_DIV_MASK,
.clksel = sys_clkout2_clksel,
- .flags = CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK,
.recalc = &omap2_clksel_recalc,
};
@@ -998,16 +956,22 @@ static struct clk sys_clkout2 = {
static struct clk corex2_fck = {
.name = "corex2_fck",
+ .ops = &clkops_null,
.parent = &dpll3_m2x2_ck,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.recalc = &followparent_recalc,
};
/* DPLL power domain clock controls */
-static const struct clksel div2_core_clksel[] = {
- { .parent = &core_ck, .rates = div2_rates },
+static const struct clksel_rate div4_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_343X | DEFAULT_RATE },
+ { .div = 2, .val = 2, .flags = RATE_IN_343X },
+ { .div = 4, .val = 4, .flags = RATE_IN_343X },
+ { .div = 0 }
+};
+
+static const struct clksel div4_core_clksel[] = {
+ { .parent = &core_ck, .rates = div4_rates },
{ .parent = NULL }
};
@@ -1017,39 +981,21 @@ static const struct clksel div2_core_clksel[] = {
*/
static struct clk dpll1_fck = {
.name = "dpll1_fck",
+ .ops = &clkops_null,
.parent = &core_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
.clksel_mask = OMAP3430_MPU_CLK_SRC_MASK,
- .clksel = div2_core_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clksel = div4_core_clksel,
.recalc = &omap2_clksel_recalc,
};
-/*
- * MPU clksel:
- * If DPLL1 is locked, mpu_ck derives from DPLL1; otherwise, mpu_ck
- * derives from the high-frequency bypass clock originating from DPLL3,
- * called 'dpll1_fck'
- */
-static const struct clksel mpu_clksel[] = {
- { .parent = &dpll1_fck, .rates = dpll_bypass_rates },
- { .parent = &dpll1_x2m2_ck, .rates = dpll_locked_rates },
- { .parent = NULL }
-};
-
static struct clk mpu_ck = {
.name = "mpu_ck",
+ .ops = &clkops_null,
.parent = &dpll1_x2m2_ck,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
- .clksel_mask = OMAP3430_ST_MPU_CLK_MASK,
- .clksel = mpu_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "mpu_clkdm",
- .recalc = &omap2_clksel_recalc,
+ .recalc = &followparent_recalc,
};
/* arm_fck is divided by two when DPLL1 locked; otherwise, passthrough mpu_ck */
@@ -1066,13 +1012,12 @@ static const struct clksel arm_fck_clksel[] = {
static struct clk arm_fck = {
.name = "arm_fck",
+ .ops = &clkops_null,
.parent = &mpu_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
.clksel_mask = OMAP3430_ST_MPU_CLK_MASK,
.clksel = arm_fck_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.recalc = &omap2_clksel_recalc,
};
@@ -1084,63 +1029,48 @@ static struct clk arm_fck = {
*/
static struct clk emu_mpu_alwon_ck = {
.name = "emu_mpu_alwon_ck",
+ .ops = &clkops_null,
.parent = &mpu_ck,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.recalc = &followparent_recalc,
};
static struct clk dpll2_fck = {
.name = "dpll2_fck",
+ .ops = &clkops_null,
.parent = &core_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
.clksel_mask = OMAP3430_IVA2_CLK_SRC_MASK,
- .clksel = div2_core_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
+ .clksel = div4_core_clksel,
.recalc = &omap2_clksel_recalc,
};
-/*
- * IVA2 clksel:
- * If DPLL2 is locked, iva2_ck derives from DPLL2; otherwise, iva2_ck
- * derives from the high-frequency bypass clock originating from DPLL3,
- * called 'dpll2_fck'
- */
-
-static const struct clksel iva2_clksel[] = {
- { .parent = &dpll2_fck, .rates = dpll_bypass_rates },
- { .parent = &dpll2_m2_ck, .rates = dpll_locked_rates },
- { .parent = NULL }
-};
-
static struct clk iva2_ck = {
.name = "iva2_ck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &dpll2_m2_ck,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
- .clksel_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD,
- OMAP3430_CM_IDLEST_PLL),
- .clksel_mask = OMAP3430_ST_IVA2_CLK_MASK,
- .clksel = iva2_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
.clkdm_name = "iva2_clkdm",
- .recalc = &omap2_clksel_recalc,
+ .recalc = &followparent_recalc,
};
/* Common interface clocks */
+static const struct clksel div2_core_clksel[] = {
+ { .parent = &core_ck, .rates = div2_rates },
+ { .parent = NULL }
+};
+
static struct clk l3_ick = {
.name = "l3_ick",
+ .ops = &clkops_null,
.parent = &core_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_L3_MASK,
.clksel = div2_core_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "core_l3_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -1152,13 +1082,12 @@ static const struct clksel div2_l3_clksel[] = {
static struct clk l4_ick = {
.name = "l4_ick",
+ .ops = &clkops_null,
.parent = &l3_ick,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_L4_MASK,
.clksel = div2_l3_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "core_l4_clkdm",
.recalc = &omap2_clksel_recalc,
@@ -1171,12 +1100,12 @@ static const struct clksel div2_l4_clksel[] = {
static struct clk rm_ick = {
.name = "rm_ick",
+ .ops = &clkops_null,
.parent = &l4_ick,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_RM_MASK,
.clksel = div2_l4_clksel,
- .flags = CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK,
.recalc = &omap2_clksel_recalc,
};
@@ -1192,53 +1121,52 @@ static const struct clksel gfx_l3_clksel[] = {
/* Virtual parent clock for gfx_l3_ick and gfx_l3_fck */
static struct clk gfx_l3_ck = {
.name = "gfx_l3_ck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l3_ick,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
.enable_bit = OMAP_EN_GFX_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES1,
.recalc = &followparent_recalc,
};
static struct clk gfx_l3_fck = {
.name = "gfx_l3_fck",
+ .ops = &clkops_null,
.parent = &gfx_l3_ck,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
.clksel_mask = OMAP_CLKSEL_GFX_MASK,
.clksel = gfx_l3_clksel,
- .flags = CLOCK_IN_OMAP3430ES1 | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "gfx_3430es1_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk gfx_l3_ick = {
.name = "gfx_l3_ick",
+ .ops = &clkops_null,
.parent = &gfx_l3_ck,
- .flags = CLOCK_IN_OMAP3430ES1 | PARENT_CONTROLS_CLOCK,
.clkdm_name = "gfx_3430es1_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gfx_cg1_ck = {
.name = "gfx_cg1_ck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &gfx_l3_fck, /* REVISIT: correct? */
.init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
.enable_bit = OMAP3430ES1_EN_2D_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES1,
.clkdm_name = "gfx_3430es1_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gfx_cg2_ck = {
.name = "gfx_cg2_ck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &gfx_l3_fck, /* REVISIT: correct? */
.init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
.enable_bit = OMAP3430ES1_EN_3D_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES1,
.clkdm_name = "gfx_3430es1_clkdm",
.recalc = &followparent_recalc,
};
@@ -1265,24 +1193,24 @@ static const struct clksel sgx_clksel[] = {
static struct clk sgx_fck = {
.name = "sgx_fck",
+ .ops = &clkops_omap2_dflt_wait,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_FCLKEN),
- .enable_bit = OMAP3430ES2_EN_SGX_SHIFT,
+ .enable_bit = OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430ES2_CLKSEL_SGX_MASK,
.clksel = sgx_clksel,
- .flags = CLOCK_IN_OMAP3430ES2,
.clkdm_name = "sgx_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk sgx_ick = {
.name = "sgx_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l3_ick,
.init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
- .enable_bit = OMAP3430ES2_EN_SGX_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
+ .enable_bit = OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT,
.clkdm_name = "sgx_clkdm",
.recalc = &followparent_recalc,
};
@@ -1291,11 +1219,11 @@ static struct clk sgx_ick = {
static struct clk d2d_26m_fck = {
.name = "d2d_26m_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &sys_ck,
.init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430ES1_EN_D2D_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES1,
.clkdm_name = "d2d_clkdm",
.recalc = &followparent_recalc,
};
@@ -1308,6 +1236,7 @@ static const struct clksel omap343x_gpt_clksel[] = {
static struct clk gpt10_fck = {
.name = "gpt10_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &sys_ck,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
@@ -1315,13 +1244,13 @@ static struct clk gpt10_fck = {
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_GPT10_MASK,
.clksel = omap343x_gpt_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk gpt11_fck = {
.name = "gpt11_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &sys_ck,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
@@ -1329,35 +1258,34 @@ static struct clk gpt11_fck = {
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_GPT11_MASK,
.clksel = omap343x_gpt_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk cpefuse_fck = {
.name = "cpefuse_fck",
+ .ops = &clkops_omap2_dflt,
.parent = &sys_ck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
.enable_bit = OMAP3430ES2_EN_CPEFUSE_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
.recalc = &followparent_recalc,
};
static struct clk ts_fck = {
.name = "ts_fck",
+ .ops = &clkops_omap2_dflt,
.parent = &omap_32k_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
.enable_bit = OMAP3430ES2_EN_TS_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
.recalc = &followparent_recalc,
};
static struct clk usbtll_fck = {
.name = "usbtll_fck",
- .parent = &omap_120m_fck,
+ .ops = &clkops_omap2_dflt,
+ .parent = &dpll5_m2_ck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
.enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
.recalc = &followparent_recalc,
};
@@ -1365,84 +1293,83 @@ static struct clk usbtll_fck = {
static struct clk core_96m_fck = {
.name = "core_96m_fck",
+ .ops = &clkops_null,
.parent = &omap_96m_fck,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mmchs3_fck = {
.name = "mmchs_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &core_96m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430ES2_EN_MMC3_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mmchs2_fck = {
.name = "mmchs_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &core_96m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MMC2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mspro_fck = {
.name = "mspro_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_96m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MSPRO_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mmchs1_fck = {
.name = "mmchs_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_96m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MMC1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk i2c3_fck = {
.name = "i2c_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 3,
.parent = &core_96m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_I2C3_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk i2c2_fck = {
.name = "i2c_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &core_96m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_I2C2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk i2c1_fck = {
.name = "i2c_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &core_96m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_I2C1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1469,6 +1396,7 @@ static const struct clksel mcbsp_15_clksel[] = {
static struct clk mcbsp5_fck = {
.name = "mcbsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 5,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
@@ -1476,13 +1404,13 @@ static struct clk mcbsp5_fck = {
.clksel_reg = OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
.clksel_mask = OMAP2_MCBSP5_CLKS_MASK,
.clksel = mcbsp_15_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk mcbsp1_fck = {
.name = "mcbsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
@@ -1490,7 +1418,6 @@ static struct clk mcbsp1_fck = {
.clksel_reg = OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
.clksel_mask = OMAP2_MCBSP1_CLKS_MASK,
.clksel = mcbsp_15_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -1499,77 +1426,76 @@ static struct clk mcbsp1_fck = {
static struct clk core_48m_fck = {
.name = "core_48m_fck",
+ .ops = &clkops_null,
.parent = &omap_48m_fck,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mcspi4_fck = {
.name = "mcspi_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 4,
.parent = &core_48m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MCSPI4_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.recalc = &followparent_recalc,
};
static struct clk mcspi3_fck = {
.name = "mcspi_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 3,
.parent = &core_48m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MCSPI3_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.recalc = &followparent_recalc,
};
static struct clk mcspi2_fck = {
.name = "mcspi_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &core_48m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MCSPI2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.recalc = &followparent_recalc,
};
static struct clk mcspi1_fck = {
.name = "mcspi_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &core_48m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MCSPI1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.recalc = &followparent_recalc,
};
static struct clk uart2_fck = {
.name = "uart2_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_48m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_UART2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.recalc = &followparent_recalc,
};
static struct clk uart1_fck = {
.name = "uart1_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_48m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_UART1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.recalc = &followparent_recalc,
};
static struct clk fshostusb_fck = {
.name = "fshostusb_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_48m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES1,
.recalc = &followparent_recalc,
};
@@ -1577,19 +1503,18 @@ static struct clk fshostusb_fck = {
static struct clk core_12m_fck = {
.name = "core_12m_fck",
+ .ops = &clkops_null,
.parent = &omap_12m_fck,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk hdq_fck = {
.name = "hdq_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_12m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_HDQ_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.recalc = &followparent_recalc,
};
@@ -1612,22 +1537,22 @@ static const struct clksel ssi_ssr_clksel[] = {
static struct clk ssi_ssr_fck = {
.name = "ssi_ssr_fck",
+ .ops = &clkops_omap2_dflt,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_SSI_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_SSI_MASK,
.clksel = ssi_ssr_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
.clkdm_name = "core_l4_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk ssi_sst_fck = {
.name = "ssi_sst_fck",
+ .ops = &clkops_null,
.parent = &ssi_ssr_fck,
.fixed_div = 2,
- .flags = CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK,
.recalc = &omap2_fixed_divisor_recalc,
};
@@ -1641,39 +1566,39 @@ static struct clk ssi_sst_fck = {
*/
static struct clk core_l3_ick = {
.name = "core_l3_ick",
+ .ops = &clkops_null,
.parent = &l3_ick,
.init = &omap2_init_clk_clkdm,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
static struct clk hsotgusb_ick = {
.name = "hsotgusb_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l3_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_HSOTGUSB_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
static struct clk sdrc_ick = {
.name = "sdrc_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l3_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_SDRC_SHIFT,
- .flags = CLOCK_IN_OMAP343X | ENABLE_ON_INIT,
+ .flags = ENABLE_ON_INIT,
.clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpmc_fck = {
.name = "gpmc_fck",
+ .ops = &clkops_null,
.parent = &core_l3_ick,
- .flags = CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK |
- ENABLE_ON_INIT,
+ .flags = ENABLE_ON_INIT, /* huh? */
.clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
@@ -1682,18 +1607,17 @@ static struct clk gpmc_fck = {
static struct clk security_l3_ick = {
.name = "security_l3_ick",
+ .ops = &clkops_null,
.parent = &l3_ick,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.recalc = &followparent_recalc,
};
static struct clk pka_ick = {
.name = "pka_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &security_l3_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP3430_EN_PKA_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.recalc = &followparent_recalc,
};
@@ -1701,31 +1625,30 @@ static struct clk pka_ick = {
static struct clk core_l4_ick = {
.name = "core_l4_ick",
+ .ops = &clkops_null,
.parent = &l4_ick,
.init = &omap2_init_clk_clkdm,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk usbtll_ick = {
.name = "usbtll_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
.enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mmchs3_ick = {
.name = "mmchs_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430ES2_EN_MMC3_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1733,250 +1656,251 @@ static struct clk mmchs3_ick = {
/* Intersystem Communication Registers - chassis mode only */
static struct clk icr_ick = {
.name = "icr_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_ICR_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk aes2_ick = {
.name = "aes2_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_AES2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk sha12_ick = {
.name = "sha12_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_SHA12_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk des2_ick = {
.name = "des2_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_DES2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mmchs2_ick = {
.name = "mmchs_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MMC2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mmchs1_ick = {
.name = "mmchs_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MMC1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mspro_ick = {
.name = "mspro_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MSPRO_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk hdq_ick = {
.name = "hdq_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_HDQ_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mcspi4_ick = {
.name = "mcspi_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 4,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCSPI4_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mcspi3_ick = {
.name = "mcspi_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 3,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCSPI3_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mcspi2_ick = {
.name = "mcspi_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCSPI2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mcspi1_ick = {
.name = "mcspi_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCSPI1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk i2c3_ick = {
.name = "i2c_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 3,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_I2C3_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk i2c2_ick = {
.name = "i2c_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_I2C2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk i2c1_ick = {
.name = "i2c_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_I2C1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk uart2_ick = {
.name = "uart2_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_UART2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk uart1_ick = {
.name = "uart1_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_UART1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpt11_ick = {
.name = "gpt11_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_GPT11_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpt10_ick = {
.name = "gpt10_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_GPT10_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mcbsp5_ick = {
.name = "mcbsp_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 5,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCBSP5_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mcbsp1_ick = {
.name = "mcbsp_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 1,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCBSP1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk fac_ick = {
.name = "fac_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430ES1_EN_FAC_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES1,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mailboxes_ick = {
.name = "mailboxes_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MAILBOXES_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk omapctrl_ick = {
.name = "omapctrl_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &core_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_OMAPCTRL_SHIFT,
- .flags = CLOCK_IN_OMAP343X | ENABLE_ON_INIT,
+ .flags = ENABLE_ON_INIT,
.recalc = &followparent_recalc,
};
@@ -1984,19 +1908,18 @@ static struct clk omapctrl_ick = {
static struct clk ssi_l4_ick = {
.name = "ssi_l4_ick",
+ .ops = &clkops_null,
.parent = &l4_ick,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk ssi_ick = {
.name = "ssi_ick",
+ .ops = &clkops_omap2_dflt,
.parent = &ssi_l4_ick,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_SSI_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -2011,6 +1934,7 @@ static const struct clksel usb_l4_clksel[] = {
static struct clk usb_l4_ick = {
.name = "usb_l4_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ick,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
@@ -2018,7 +1942,6 @@ static struct clk usb_l4_ick = {
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK,
.clksel = usb_l4_clksel,
- .flags = CLOCK_IN_OMAP3430ES1,
.recalc = &omap2_clksel_recalc,
};
@@ -2028,98 +1951,87 @@ static struct clk usb_l4_ick = {
static struct clk security_l4_ick2 = {
.name = "security_l4_ick2",
+ .ops = &clkops_null,
.parent = &l4_ick,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.recalc = &followparent_recalc,
};
static struct clk aes1_ick = {
.name = "aes1_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &security_l4_ick2,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP3430_EN_AES1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.recalc = &followparent_recalc,
};
static struct clk rng_ick = {
.name = "rng_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &security_l4_ick2,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP3430_EN_RNG_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.recalc = &followparent_recalc,
};
static struct clk sha11_ick = {
.name = "sha11_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &security_l4_ick2,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP3430_EN_SHA11_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.recalc = &followparent_recalc,
};
static struct clk des1_ick = {
.name = "des1_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &security_l4_ick2,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP3430_EN_DES1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.recalc = &followparent_recalc,
};
/* DSS */
-static const struct clksel dss1_alwon_fck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
- { .parent = &dpll4_m4x2_ck, .rates = dpll_locked_rates },
- { .parent = NULL }
-};
-
static struct clk dss1_alwon_fck = {
.name = "dss1_alwon_fck",
+ .ops = &clkops_omap2_dflt,
.parent = &dpll4_m4x2_ck,
- .init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_DSS1_SHIFT,
- .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
- .clksel = dss1_alwon_fck_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "dss_clkdm",
- .recalc = &omap2_clksel_recalc,
+ .recalc = &followparent_recalc,
};
static struct clk dss_tv_fck = {
.name = "dss_tv_fck",
+ .ops = &clkops_omap2_dflt,
.parent = &omap_54m_fck,
.init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_TV_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "dss_clkdm",
.recalc = &followparent_recalc,
};
static struct clk dss_96m_fck = {
.name = "dss_96m_fck",
+ .ops = &clkops_omap2_dflt,
.parent = &omap_96m_fck,
.init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_TV_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "dss_clkdm",
.recalc = &followparent_recalc,
};
static struct clk dss2_alwon_fck = {
.name = "dss2_alwon_fck",
+ .ops = &clkops_omap2_dflt,
.parent = &sys_ck,
.init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_DSS2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "dss_clkdm",
.recalc = &followparent_recalc,
};
@@ -2127,45 +2039,46 @@ static struct clk dss2_alwon_fck = {
static struct clk dss_ick = {
/* Handles both L3 and L4 clocks */
.name = "dss_ick",
+ .ops = &clkops_omap2_dflt,
.parent = &l4_ick,
.init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "dss_clkdm",
.recalc = &followparent_recalc,
};
/* CAM */
-static const struct clksel cam_mclk_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
- { .parent = &dpll4_m5x2_ck, .rates = dpll_locked_rates },
- { .parent = NULL }
-};
-
static struct clk cam_mclk = {
.name = "cam_mclk",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &dpll4_m5x2_ck,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
- .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
- .clksel = cam_mclk_clksel,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_CAM_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "cam_clkdm",
- .recalc = &omap2_clksel_recalc,
+ .recalc = &followparent_recalc,
};
static struct clk cam_ick = {
/* Handles both L3 and L4 clocks */
.name = "cam_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ick,
.init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_CAM_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "cam_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk csi2_96m_fck = {
+ .name = "csi2_96m_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_96m_fck,
+ .init = &omap2_init_clk_clkdm,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_CSI2_SHIFT,
.clkdm_name = "cam_clkdm",
.recalc = &followparent_recalc,
};
@@ -2174,22 +2087,22 @@ static struct clk cam_ick = {
static struct clk usbhost_120m_fck = {
.name = "usbhost_120m_fck",
- .parent = &omap_120m_fck,
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &dpll5_m2_ck,
.init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
.enable_bit = OMAP3430ES2_EN_USBHOST2_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
.clkdm_name = "usbhost_clkdm",
.recalc = &followparent_recalc,
};
static struct clk usbhost_48m_fck = {
.name = "usbhost_48m_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &omap_48m_fck,
.init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
.enable_bit = OMAP3430ES2_EN_USBHOST1_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
.clkdm_name = "usbhost_clkdm",
.recalc = &followparent_recalc,
};
@@ -2197,22 +2110,11 @@ static struct clk usbhost_48m_fck = {
static struct clk usbhost_ick = {
/* Handles both L3 and L4 clocks */
.name = "usbhost_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &l4_ick,
.init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
.enable_bit = OMAP3430ES2_EN_USBHOST_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
- .clkdm_name = "usbhost_clkdm",
- .recalc = &followparent_recalc,
-};
-
-static struct clk usbhost_sar_fck = {
- .name = "usbhost_sar_fck",
- .parent = &osc_sys_ck,
- .init = &omap2_init_clk_clkdm,
- .enable_reg = OMAP_PRM_REGADDR(OMAP3430ES2_USBHOST_MOD, PM_PWSTCTRL),
- .enable_bit = OMAP3430ES2_SAVEANDRESTORE_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
.clkdm_name = "usbhost_clkdm",
.recalc = &followparent_recalc,
};
@@ -2237,7 +2139,7 @@ static const struct clksel_rate usim_120m_rates[] = {
static const struct clksel usim_clksel[] = {
{ .parent = &omap_96m_fck, .rates = usim_96m_rates },
- { .parent = &omap_120m_fck, .rates = usim_120m_rates },
+ { .parent = &dpll5_m2_ck, .rates = usim_120m_rates },
{ .parent = &sys_ck, .rates = div2_rates },
{ .parent = NULL },
};
@@ -2245,63 +2147,63 @@ static const struct clksel usim_clksel[] = {
/* 3430ES2 only */
static struct clk usim_fck = {
.name = "usim_fck",
+ .ops = &clkops_omap2_dflt_wait,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP3430ES2_EN_USIMOCP_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430ES2_CLKSEL_USIMOCP_MASK,
.clksel = usim_clksel,
- .flags = CLOCK_IN_OMAP3430ES2,
.recalc = &omap2_clksel_recalc,
};
/* XXX should gpt1's clksel have wkup_32k_fck as the 32k opt? */
static struct clk gpt1_fck = {
.name = "gpt1_fck",
+ .ops = &clkops_omap2_dflt_wait,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPT1_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_GPT1_MASK,
.clksel = omap343x_gpt_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "wkup_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk wkup_32k_fck = {
.name = "wkup_32k_fck",
+ .ops = &clkops_null,
.init = &omap2_init_clk_clkdm,
.parent = &omap_32k_fck,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
.clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpio1_dbck = {
.name = "gpio1_dbck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &wkup_32k_fck,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPIO1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
static struct clk wdt2_fck = {
.name = "wdt2_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &wkup_32k_fck,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_WDT2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
static struct clk wkup_l4_ick = {
.name = "wkup_l4_ick",
+ .ops = &clkops_null,
.parent = &sys_ck,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
.clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -2310,50 +2212,50 @@ static struct clk wkup_l4_ick = {
/* Never specifically named in the TRM, so we have to infer a likely name */
static struct clk usim_ick = {
.name = "usim_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &wkup_l4_ick,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430ES2_EN_USIMOCP_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
.clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
static struct clk wdt2_ick = {
.name = "wdt2_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &wkup_l4_ick,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_WDT2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
static struct clk wdt1_ick = {
.name = "wdt1_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &wkup_l4_ick,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_WDT1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpio1_ick = {
.name = "gpio1_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &wkup_l4_ick,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPIO1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
static struct clk omap_32ksync_ick = {
.name = "omap_32ksync_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &wkup_l4_ick,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_32KSYNC_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -2361,20 +2263,20 @@ static struct clk omap_32ksync_ick = {
/* XXX This clock no longer exists in 3430 TRM rev F */
static struct clk gpt12_ick = {
.name = "gpt12_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &wkup_l4_ick,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT12_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpt1_ick = {
.name = "gpt1_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &wkup_l4_ick,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT1_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -2385,406 +2287,404 @@ static struct clk gpt1_ick = {
static struct clk per_96m_fck = {
.name = "per_96m_fck",
+ .ops = &clkops_null,
.parent = &omap_96m_alwon_fck,
.init = &omap2_init_clk_clkdm,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk per_48m_fck = {
.name = "per_48m_fck",
+ .ops = &clkops_null,
.parent = &omap_48m_fck,
.init = &omap2_init_clk_clkdm,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk uart3_fck = {
.name = "uart3_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_48m_fck,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_UART3_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpt2_fck = {
.name = "gpt2_fck",
+ .ops = &clkops_omap2_dflt_wait,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPT2_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_GPT2_MASK,
.clksel = omap343x_gpt_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk gpt3_fck = {
.name = "gpt3_fck",
+ .ops = &clkops_omap2_dflt_wait,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPT3_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_GPT3_MASK,
.clksel = omap343x_gpt_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk gpt4_fck = {
.name = "gpt4_fck",
+ .ops = &clkops_omap2_dflt_wait,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPT4_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_GPT4_MASK,
.clksel = omap343x_gpt_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk gpt5_fck = {
.name = "gpt5_fck",
+ .ops = &clkops_omap2_dflt_wait,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPT5_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_GPT5_MASK,
.clksel = omap343x_gpt_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk gpt6_fck = {
.name = "gpt6_fck",
+ .ops = &clkops_omap2_dflt_wait,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPT6_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_GPT6_MASK,
.clksel = omap343x_gpt_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk gpt7_fck = {
.name = "gpt7_fck",
+ .ops = &clkops_omap2_dflt_wait,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPT7_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_GPT7_MASK,
.clksel = omap343x_gpt_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk gpt8_fck = {
.name = "gpt8_fck",
+ .ops = &clkops_omap2_dflt_wait,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPT8_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_GPT8_MASK,
.clksel = omap343x_gpt_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk gpt9_fck = {
.name = "gpt9_fck",
+ .ops = &clkops_omap2_dflt_wait,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPT9_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
.clksel_mask = OMAP3430_CLKSEL_GPT9_MASK,
.clksel = omap343x_gpt_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk per_32k_alwon_fck = {
.name = "per_32k_alwon_fck",
+ .ops = &clkops_null,
.parent = &omap_32k_fck,
.clkdm_name = "per_clkdm",
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
.recalc = &followparent_recalc,
};
static struct clk gpio6_dbck = {
.name = "gpio6_dbck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_32k_alwon_fck,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPIO6_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpio5_dbck = {
.name = "gpio5_dbck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_32k_alwon_fck,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPIO5_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpio4_dbck = {
.name = "gpio4_dbck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_32k_alwon_fck,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPIO4_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpio3_dbck = {
.name = "gpio3_dbck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_32k_alwon_fck,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPIO3_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpio2_dbck = {
.name = "gpio2_dbck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_32k_alwon_fck,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPIO2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk wdt3_fck = {
.name = "wdt3_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_32k_alwon_fck,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_WDT3_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk per_l4_ick = {
.name = "per_l4_ick",
+ .ops = &clkops_null,
.parent = &l4_ick,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
- PARENT_CONTROLS_CLOCK,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpio6_ick = {
.name = "gpio6_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPIO6_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpio5_ick = {
.name = "gpio5_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPIO5_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpio4_ick = {
.name = "gpio4_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPIO4_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpio3_ick = {
.name = "gpio3_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPIO3_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpio2_ick = {
.name = "gpio2_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPIO2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk wdt3_ick = {
.name = "wdt3_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_WDT3_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk uart3_ick = {
.name = "uart3_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_UART3_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpt9_ick = {
.name = "gpt9_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT9_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpt8_ick = {
.name = "gpt8_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT8_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpt7_ick = {
.name = "gpt7_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT7_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpt6_ick = {
.name = "gpt6_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT6_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpt5_ick = {
.name = "gpt5_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT5_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpt4_ick = {
.name = "gpt4_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT4_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpt3_ick = {
.name = "gpt3_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT3_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gpt2_ick = {
.name = "gpt2_ick",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mcbsp2_ick = {
.name = "mcbsp_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_MCBSP2_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mcbsp3_ick = {
.name = "mcbsp_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 3,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_MCBSP3_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk mcbsp4_ick = {
.name = "mcbsp_ick",
+ .ops = &clkops_omap2_dflt_wait,
.id = 4,
.parent = &per_l4_ick,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_MCBSP4_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static const struct clksel mcbsp_234_clksel[] = {
- { .parent = &per_96m_fck, .rates = common_mcbsp_96m_rates },
- { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
+ { .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates },
+ { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
{ .parent = NULL }
};
static struct clk mcbsp2_fck = {
.name = "mcbsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 2,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
@@ -2792,13 +2692,13 @@ static struct clk mcbsp2_fck = {
.clksel_reg = OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
.clksel_mask = OMAP2_MCBSP2_CLKS_MASK,
.clksel = mcbsp_234_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk mcbsp3_fck = {
.name = "mcbsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 3,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
@@ -2806,13 +2706,13 @@ static struct clk mcbsp3_fck = {
.clksel_reg = OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
.clksel_mask = OMAP2_MCBSP3_CLKS_MASK,
.clksel = mcbsp_234_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk mcbsp4_fck = {
.name = "mcbsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
.id = 4,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
@@ -2820,7 +2720,6 @@ static struct clk mcbsp4_fck = {
.clksel_reg = OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
.clksel_mask = OMAP2_MCBSP4_CLKS_MASK,
.clksel = mcbsp_234_clksel,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2864,11 +2763,11 @@ static const struct clksel emu_src_clksel[] = {
*/
static struct clk emu_src_ck = {
.name = "emu_src_ck",
+ .ops = &clkops_null,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
.clksel_mask = OMAP3430_MUX_CTRL_MASK,
.clksel = emu_src_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
.clkdm_name = "emu_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2888,11 +2787,11 @@ static const struct clksel pclk_emu_clksel[] = {
static struct clk pclk_fck = {
.name = "pclk_fck",
+ .ops = &clkops_null,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
.clksel_mask = OMAP3430_CLKSEL_PCLK_MASK,
.clksel = pclk_emu_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
.clkdm_name = "emu_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2911,11 +2810,11 @@ static const struct clksel pclkx2_emu_clksel[] = {
static struct clk pclkx2_fck = {
.name = "pclkx2_fck",
+ .ops = &clkops_null,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
.clksel_mask = OMAP3430_CLKSEL_PCLKX2_MASK,
.clksel = pclkx2_emu_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
.clkdm_name = "emu_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2927,22 +2826,22 @@ static const struct clksel atclk_emu_clksel[] = {
static struct clk atclk_fck = {
.name = "atclk_fck",
+ .ops = &clkops_null,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
.clksel_mask = OMAP3430_CLKSEL_ATCLK_MASK,
.clksel = atclk_emu_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
.clkdm_name = "emu_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk traceclk_src_fck = {
.name = "traceclk_src_fck",
+ .ops = &clkops_null,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
.clksel_mask = OMAP3430_TRACE_MUX_CTRL_MASK,
.clksel = emu_src_clksel,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
.clkdm_name = "emu_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2961,11 +2860,11 @@ static const struct clksel traceclk_clksel[] = {
static struct clk traceclk_fck = {
.name = "traceclk_fck",
+ .ops = &clkops_null,
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
.clksel_mask = OMAP3430_CLKSEL_TRACECLK_MASK,
.clksel = traceclk_clksel,
- .flags = CLOCK_IN_OMAP343X | ALWAYS_ENABLED,
.clkdm_name = "emu_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2975,27 +2874,27 @@ static struct clk traceclk_fck = {
/* SmartReflex fclk (VDD1) */
static struct clk sr1_fck = {
.name = "sr1_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &sys_ck,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_SR1_SHIFT,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
.recalc = &followparent_recalc,
};
/* SmartReflex fclk (VDD2) */
static struct clk sr2_fck = {
.name = "sr2_fck",
+ .ops = &clkops_omap2_dflt_wait,
.parent = &sys_ck,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_SR2_SHIFT,
- .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
.recalc = &followparent_recalc,
};
static struct clk sr_l4_ick = {
.name = "sr_l4_ick",
+ .ops = &clkops_null, /* RMK: missing? */
.parent = &l4_ick,
- .flags = CLOCK_IN_OMAP343X,
.clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -3005,231 +2904,16 @@ static struct clk sr_l4_ick = {
/* XXX This clock no longer exists in 3430 TRM rev F */
static struct clk gpt12_fck = {
.name = "gpt12_fck",
+ .ops = &clkops_null,
.parent = &secure_32k_fck,
- .flags = CLOCK_IN_OMAP343X | ALWAYS_ENABLED,
.recalc = &followparent_recalc,
};
static struct clk wdt1_fck = {
.name = "wdt1_fck",
+ .ops = &clkops_null,
.parent = &secure_32k_fck,
- .flags = CLOCK_IN_OMAP343X | ALWAYS_ENABLED,
- .recalc = &followparent_recalc,
-};
-
-static struct clk *onchip_34xx_clks[] __initdata = {
- &omap_32k_fck,
- &virt_12m_ck,
- &virt_13m_ck,
- &virt_16_8m_ck,
- &virt_19_2m_ck,
- &virt_26m_ck,
- &virt_38_4m_ck,
- &osc_sys_ck,
- &sys_ck,
- &sys_altclk,
- &mcbsp_clks,
- &sys_clkout1,
- &dpll1_ck,
- &dpll1_x2_ck,
- &dpll1_x2m2_ck,
- &dpll2_ck,
- &dpll2_m2_ck,
- &dpll3_ck,
- &core_ck,
- &dpll3_x2_ck,
- &dpll3_m2_ck,
- &dpll3_m2x2_ck,
- &dpll3_m3_ck,
- &dpll3_m3x2_ck,
- &emu_core_alwon_ck,
- &dpll4_ck,
- &dpll4_x2_ck,
- &omap_96m_alwon_fck,
- &omap_96m_fck,
- &cm_96m_fck,
- &virt_omap_54m_fck,
- &omap_54m_fck,
- &omap_48m_fck,
- &omap_12m_fck,
- &dpll4_m2_ck,
- &dpll4_m2x2_ck,
- &dpll4_m3_ck,
- &dpll4_m3x2_ck,
- &dpll4_m4_ck,
- &dpll4_m4x2_ck,
- &dpll4_m5_ck,
- &dpll4_m5x2_ck,
- &dpll4_m6_ck,
- &dpll4_m6x2_ck,
- &emu_per_alwon_ck,
- &dpll5_ck,
- &dpll5_m2_ck,
- &omap_120m_fck,
- &clkout2_src_ck,
- &sys_clkout2,
- &corex2_fck,
- &dpll1_fck,
- &mpu_ck,
- &arm_fck,
- &emu_mpu_alwon_ck,
- &dpll2_fck,
- &iva2_ck,
- &l3_ick,
- &l4_ick,
- &rm_ick,
- &gfx_l3_ck,
- &gfx_l3_fck,
- &gfx_l3_ick,
- &gfx_cg1_ck,
- &gfx_cg2_ck,
- &sgx_fck,
- &sgx_ick,
- &d2d_26m_fck,
- &gpt10_fck,
- &gpt11_fck,
- &cpefuse_fck,
- &ts_fck,
- &usbtll_fck,
- &core_96m_fck,
- &mmchs3_fck,
- &mmchs2_fck,
- &mspro_fck,
- &mmchs1_fck,
- &i2c3_fck,
- &i2c2_fck,
- &i2c1_fck,
- &mcbsp5_fck,
- &mcbsp1_fck,
- &core_48m_fck,
- &mcspi4_fck,
- &mcspi3_fck,
- &mcspi2_fck,
- &mcspi1_fck,
- &uart2_fck,
- &uart1_fck,
- &fshostusb_fck,
- &core_12m_fck,
- &hdq_fck,
- &ssi_ssr_fck,
- &ssi_sst_fck,
- &core_l3_ick,
- &hsotgusb_ick,
- &sdrc_ick,
- &gpmc_fck,
- &security_l3_ick,
- &pka_ick,
- &core_l4_ick,
- &usbtll_ick,
- &mmchs3_ick,
- &icr_ick,
- &aes2_ick,
- &sha12_ick,
- &des2_ick,
- &mmchs2_ick,
- &mmchs1_ick,
- &mspro_ick,
- &hdq_ick,
- &mcspi4_ick,
- &mcspi3_ick,
- &mcspi2_ick,
- &mcspi1_ick,
- &i2c3_ick,
- &i2c2_ick,
- &i2c1_ick,
- &uart2_ick,
- &uart1_ick,
- &gpt11_ick,
- &gpt10_ick,
- &mcbsp5_ick,
- &mcbsp1_ick,
- &fac_ick,
- &mailboxes_ick,
- &omapctrl_ick,
- &ssi_l4_ick,
- &ssi_ick,
- &usb_l4_ick,
- &security_l4_ick2,
- &aes1_ick,
- &rng_ick,
- &sha11_ick,
- &des1_ick,
- &dss1_alwon_fck,
- &dss_tv_fck,
- &dss_96m_fck,
- &dss2_alwon_fck,
- &dss_ick,
- &cam_mclk,
- &cam_ick,
- &usbhost_120m_fck,
- &usbhost_48m_fck,
- &usbhost_ick,
- &usbhost_sar_fck,
- &usim_fck,
- &gpt1_fck,
- &wkup_32k_fck,
- &gpio1_dbck,
- &wdt2_fck,
- &wkup_l4_ick,
- &usim_ick,
- &wdt2_ick,
- &wdt1_ick,
- &gpio1_ick,
- &omap_32ksync_ick,
- &gpt12_ick,
- &gpt1_ick,
- &per_96m_fck,
- &per_48m_fck,
- &uart3_fck,
- &gpt2_fck,
- &gpt3_fck,
- &gpt4_fck,
- &gpt5_fck,
- &gpt6_fck,
- &gpt7_fck,
- &gpt8_fck,
- &gpt9_fck,
- &per_32k_alwon_fck,
- &gpio6_dbck,
- &gpio5_dbck,
- &gpio4_dbck,
- &gpio3_dbck,
- &gpio2_dbck,
- &wdt3_fck,
- &per_l4_ick,
- &gpio6_ick,
- &gpio5_ick,
- &gpio4_ick,
- &gpio3_ick,
- &gpio2_ick,
- &wdt3_ick,
- &uart3_ick,
- &gpt9_ick,
- &gpt8_ick,
- &gpt7_ick,
- &gpt6_ick,
- &gpt5_ick,
- &gpt4_ick,
- &gpt3_ick,
- &gpt2_ick,
- &mcbsp2_ick,
- &mcbsp3_ick,
- &mcbsp4_ick,
- &mcbsp2_fck,
- &mcbsp3_fck,
- &mcbsp4_fck,
- &emu_src_ck,
- &pclk_fck,
- &pclkx2_fck,
- &atclk_fck,
- &traceclk_src_fck,
- &traceclk_fck,
- &sr1_fck,
- &sr2_fck,
- &sr_l4_ick,
- &secure_32k_fck,
- &gpt12_fck,
- &wdt1_fck,
+ .recalc = &followparent_recalc,
};
#endif
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 4c3ce9cfd948..0e7d501865b6 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/limits.h>
+#include <linux/err.h>
#include <linux/io.h>
@@ -71,16 +72,13 @@ static void _autodep_lookup(struct clkdm_pwrdm_autodep *autodep)
if (!omap_chip_is(autodep->omap_chip))
return;
- pwrdm = pwrdm_lookup(autodep->pwrdm_name);
+ pwrdm = pwrdm_lookup(autodep->pwrdm.name);
if (!pwrdm) {
- pr_debug("clockdomain: _autodep_lookup: powerdomain %s "
- "does not exist\n", autodep->pwrdm_name);
- WARN_ON(1);
- return;
+ pr_err("clockdomain: autodeps: powerdomain %s does not exist\n",
+ autodep->pwrdm.name);
+ pwrdm = ERR_PTR(-ENOENT);
}
- autodep->pwrdm = pwrdm;
-
- return;
+ autodep->pwrdm.ptr = pwrdm;
}
/*
@@ -95,16 +93,19 @@ static void _clkdm_add_autodeps(struct clockdomain *clkdm)
{
struct clkdm_pwrdm_autodep *autodep;
- for (autodep = autodeps; autodep->pwrdm_name; autodep++) {
- if (!autodep->pwrdm)
+ for (autodep = autodeps; autodep->pwrdm.ptr; autodep++) {
+ if (IS_ERR(autodep->pwrdm.ptr))
+ continue;
+
+ if (!omap_chip_is(autodep->omap_chip))
continue;
pr_debug("clockdomain: adding %s sleepdep/wkdep for "
- "pwrdm %s\n", autodep->pwrdm_name,
- clkdm->pwrdm->name);
+ "pwrdm %s\n", autodep->pwrdm.ptr->name,
+ clkdm->pwrdm.ptr->name);
- pwrdm_add_sleepdep(clkdm->pwrdm, autodep->pwrdm);
- pwrdm_add_wkdep(clkdm->pwrdm, autodep->pwrdm);
+ pwrdm_add_sleepdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
+ pwrdm_add_wkdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
}
}
@@ -120,16 +121,19 @@ static void _clkdm_del_autodeps(struct clockdomain *clkdm)
{
struct clkdm_pwrdm_autodep *autodep;
- for (autodep = autodeps; autodep->pwrdm_name; autodep++) {
- if (!autodep->pwrdm)
+ for (autodep = autodeps; autodep->pwrdm.ptr; autodep++) {
+ if (IS_ERR(autodep->pwrdm.ptr))
+ continue;
+
+ if (!omap_chip_is(autodep->omap_chip))
continue;
pr_debug("clockdomain: removing %s sleepdep/wkdep for "
- "pwrdm %s\n", autodep->pwrdm_name,
- clkdm->pwrdm->name);
+ "pwrdm %s\n", autodep->pwrdm.ptr->name,
+ clkdm->pwrdm.ptr->name);
- pwrdm_del_sleepdep(clkdm->pwrdm, autodep->pwrdm);
- pwrdm_del_wkdep(clkdm->pwrdm, autodep->pwrdm);
+ pwrdm_del_sleepdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
+ pwrdm_del_wkdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);
}
}
@@ -179,7 +183,7 @@ void clkdm_init(struct clockdomain **clkdms,
autodeps = init_autodeps;
if (autodeps)
- for (autodep = autodeps; autodep->pwrdm_name; autodep++)
+ for (autodep = autodeps; autodep->pwrdm.ptr; autodep++)
_autodep_lookup(autodep);
}
@@ -202,20 +206,20 @@ int clkdm_register(struct clockdomain *clkdm)
if (!omap_chip_is(clkdm->omap_chip))
return -EINVAL;
- pwrdm = pwrdm_lookup(clkdm->pwrdm_name);
+ pwrdm = pwrdm_lookup(clkdm->pwrdm.name);
if (!pwrdm) {
- pr_debug("clockdomain: clkdm_register %s: powerdomain %s "
- "does not exist\n", clkdm->name, clkdm->pwrdm_name);
+ pr_err("clockdomain: %s: powerdomain %s does not exist\n",
+ clkdm->name, clkdm->pwrdm.name);
return -EINVAL;
}
- clkdm->pwrdm = pwrdm;
+ clkdm->pwrdm.ptr = pwrdm;
mutex_lock(&clkdm_mutex);
/* Verify that the clockdomain is not already registered */
if (_clkdm_lookup(clkdm->name)) {
ret = -EEXIST;
goto cr_unlock;
- };
+ }
list_add(&clkdm->node, &clkdm_list);
@@ -242,7 +246,7 @@ int clkdm_unregister(struct clockdomain *clkdm)
if (!clkdm)
return -EINVAL;
- pwrdm_del_clkdm(clkdm->pwrdm, clkdm);
+ pwrdm_del_clkdm(clkdm->pwrdm.ptr, clkdm);
mutex_lock(&clkdm_mutex);
list_del(&clkdm->node);
@@ -327,7 +331,7 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)
if (!clkdm)
return NULL;
- return clkdm->pwrdm;
+ return clkdm->pwrdm.ptr;
}
@@ -348,7 +352,7 @@ static int omap2_clkdm_clktrctrl_read(struct clockdomain *clkdm)
if (!clkdm)
return -EINVAL;
- v = cm_read_mod_reg(clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+ v = cm_read_mod_reg(clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
v &= clkdm->clktrctrl_mask;
v >>= __ffs(clkdm->clktrctrl_mask);
@@ -380,7 +384,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)
if (cpu_is_omap24xx()) {
cm_set_mod_reg_bits(OMAP24XX_FORCESTATE,
- clkdm->pwrdm->prcm_offs, PM_PWSTCTRL);
+ clkdm->pwrdm.ptr->prcm_offs, PM_PWSTCTRL);
} else if (cpu_is_omap34xx()) {
@@ -388,7 +392,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)
__ffs(clkdm->clktrctrl_mask));
cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v,
- clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+ clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
} else {
BUG();
@@ -422,7 +426,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
if (cpu_is_omap24xx()) {
cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE,
- clkdm->pwrdm->prcm_offs, PM_PWSTCTRL);
+ clkdm->pwrdm.ptr->prcm_offs, PM_PWSTCTRL);
} else if (cpu_is_omap34xx()) {
@@ -430,7 +434,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
__ffs(clkdm->clktrctrl_mask));
cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v,
- clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+ clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
} else {
BUG();
@@ -478,7 +482,7 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
v << __ffs(clkdm->clktrctrl_mask),
- clkdm->pwrdm->prcm_offs,
+ clkdm->pwrdm.ptr->prcm_offs,
CM_CLKSTCTRL);
}
@@ -516,7 +520,7 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
v << __ffs(clkdm->clktrctrl_mask),
- clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+ clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
if (atomic_read(&clkdm->usecount) > 0)
_clkdm_del_autodeps(clkdm);
@@ -567,6 +571,8 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
else
omap2_clkdm_wakeup(clkdm);
+ pwrdm_wait_transition(clkdm->pwrdm.ptr);
+
return 0;
}
diff --git a/arch/arm/mach-omap2/clockdomains.h b/arch/arm/mach-omap2/clockdomains.h
index cd86dcc7b424..281d5da19188 100644
--- a/arch/arm/mach-omap2/clockdomains.h
+++ b/arch/arm/mach-omap2/clockdomains.h
@@ -14,12 +14,29 @@
/*
* OMAP2/3-common clockdomains
+ *
+ * Even though the 2420 has a single PRCM module from the
+ * interconnect's perspective, internally it does appear to have
+ * separate PRM and CM clockdomains. The usual test case is
+ * sys_clkout/sys_clkout2.
*/
/* This is an implicit clockdomain - it is never defined as such in TRM */
static struct clockdomain wkup_clkdm = {
.name = "wkup_clkdm",
- .pwrdm_name = "wkup_pwrdm",
+ .pwrdm = { .name = "wkup_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain prm_clkdm = {
+ .name = "prm_clkdm",
+ .pwrdm = { .name = "wkup_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain cm_clkdm = {
+ .name = "cm_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
};
@@ -31,7 +48,7 @@ static struct clockdomain wkup_clkdm = {
static struct clockdomain mpu_2420_clkdm = {
.name = "mpu_clkdm",
- .pwrdm_name = "mpu_pwrdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
@@ -39,7 +56,7 @@ static struct clockdomain mpu_2420_clkdm = {
static struct clockdomain iva1_2420_clkdm = {
.name = "iva1_clkdm",
- .pwrdm_name = "dsp_pwrdm",
+ .pwrdm = { .name = "dsp_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
@@ -56,7 +73,7 @@ static struct clockdomain iva1_2420_clkdm = {
static struct clockdomain mpu_2430_clkdm = {
.name = "mpu_clkdm",
- .pwrdm_name = "mpu_pwrdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
@@ -64,7 +81,7 @@ static struct clockdomain mpu_2430_clkdm = {
static struct clockdomain mdm_clkdm = {
.name = "mdm_clkdm",
- .pwrdm_name = "mdm_pwrdm",
+ .pwrdm = { .name = "mdm_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
@@ -81,7 +98,7 @@ static struct clockdomain mdm_clkdm = {
static struct clockdomain dsp_clkdm = {
.name = "dsp_clkdm",
- .pwrdm_name = "dsp_pwrdm",
+ .pwrdm = { .name = "dsp_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@@ -89,7 +106,7 @@ static struct clockdomain dsp_clkdm = {
static struct clockdomain gfx_24xx_clkdm = {
.name = "gfx_clkdm",
- .pwrdm_name = "gfx_pwrdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@@ -97,7 +114,7 @@ static struct clockdomain gfx_24xx_clkdm = {
static struct clockdomain core_l3_24xx_clkdm = {
.name = "core_l3_clkdm",
- .pwrdm_name = "core_pwrdm",
+ .pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@@ -105,7 +122,7 @@ static struct clockdomain core_l3_24xx_clkdm = {
static struct clockdomain core_l4_24xx_clkdm = {
.name = "core_l4_clkdm",
- .pwrdm_name = "core_pwrdm",
+ .pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@@ -113,7 +130,7 @@ static struct clockdomain core_l4_24xx_clkdm = {
static struct clockdomain dss_24xx_clkdm = {
.name = "dss_clkdm",
- .pwrdm_name = "core_pwrdm",
+ .pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
@@ -130,7 +147,7 @@ static struct clockdomain dss_24xx_clkdm = {
static struct clockdomain mpu_34xx_clkdm = {
.name = "mpu_clkdm",
- .pwrdm_name = "mpu_pwrdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
.flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -138,7 +155,7 @@ static struct clockdomain mpu_34xx_clkdm = {
static struct clockdomain neon_clkdm = {
.name = "neon_clkdm",
- .pwrdm_name = "neon_pwrdm",
+ .pwrdm = { .name = "neon_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -146,7 +163,7 @@ static struct clockdomain neon_clkdm = {
static struct clockdomain iva2_clkdm = {
.name = "iva2_clkdm",
- .pwrdm_name = "iva2_pwrdm",
+ .pwrdm = { .name = "iva2_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -154,7 +171,7 @@ static struct clockdomain iva2_clkdm = {
static struct clockdomain gfx_3430es1_clkdm = {
.name = "gfx_clkdm",
- .pwrdm_name = "gfx_pwrdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1),
@@ -162,10 +179,10 @@ static struct clockdomain gfx_3430es1_clkdm = {
static struct clockdomain sgx_clkdm = {
.name = "sgx_clkdm",
- .pwrdm_name = "sgx_pwrdm",
+ .pwrdm = { .name = "sgx_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
};
/*
@@ -177,7 +194,7 @@ static struct clockdomain sgx_clkdm = {
*/
static struct clockdomain d2d_clkdm = {
.name = "d2d_clkdm",
- .pwrdm_name = "core_pwrdm",
+ .pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -185,7 +202,7 @@ static struct clockdomain d2d_clkdm = {
static struct clockdomain core_l3_34xx_clkdm = {
.name = "core_l3_clkdm",
- .pwrdm_name = "core_pwrdm",
+ .pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -193,7 +210,7 @@ static struct clockdomain core_l3_34xx_clkdm = {
static struct clockdomain core_l4_34xx_clkdm = {
.name = "core_l4_clkdm",
- .pwrdm_name = "core_pwrdm",
+ .pwrdm = { .name = "core_pwrdm" },
.flags = CLKDM_CAN_HWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -201,7 +218,7 @@ static struct clockdomain core_l4_34xx_clkdm = {
static struct clockdomain dss_34xx_clkdm = {
.name = "dss_clkdm",
- .pwrdm_name = "dss_pwrdm",
+ .pwrdm = { .name = "dss_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -209,7 +226,7 @@ static struct clockdomain dss_34xx_clkdm = {
static struct clockdomain cam_clkdm = {
.name = "cam_clkdm",
- .pwrdm_name = "cam_pwrdm",
+ .pwrdm = { .name = "cam_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -217,28 +234,62 @@ static struct clockdomain cam_clkdm = {
static struct clockdomain usbhost_clkdm = {
.name = "usbhost_clkdm",
- .pwrdm_name = "usbhost_pwrdm",
+ .pwrdm = { .name = "usbhost_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
};
static struct clockdomain per_clkdm = {
.name = "per_clkdm",
- .pwrdm_name = "per_pwrdm",
+ .pwrdm = { .name = "per_pwrdm" },
.flags = CLKDM_CAN_HWSUP_SWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
+/*
+ * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is
+ * switched of even if sdti is in use
+ */
static struct clockdomain emu_clkdm = {
.name = "emu_clkdm",
- .pwrdm_name = "emu_pwrdm",
- .flags = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP,
+ .pwrdm = { .name = "emu_pwrdm" },
+ .flags = /* CLKDM_CAN_ENABLE_AUTO | */CLKDM_CAN_SWSUP,
.clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
+static struct clockdomain dpll1_clkdm = {
+ .name = "dpll1_clkdm",
+ .pwrdm = { .name = "dpll1_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dpll2_clkdm = {
+ .name = "dpll2_clkdm",
+ .pwrdm = { .name = "dpll2_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dpll3_clkdm = {
+ .name = "dpll3_clkdm",
+ .pwrdm = { .name = "dpll3_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dpll4_clkdm = {
+ .name = "dpll4_clkdm",
+ .pwrdm = { .name = "dpll4_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dpll5_clkdm = {
+ .name = "dpll5_clkdm",
+ .pwrdm = { .name = "dpll5_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
+};
+
#endif /* CONFIG_ARCH_OMAP34XX */
/*
@@ -247,14 +298,16 @@ static struct clockdomain emu_clkdm = {
static struct clkdm_pwrdm_autodep clkdm_pwrdm_autodeps[] = {
{
- .pwrdm_name = "mpu_pwrdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
},
{
- .pwrdm_name = "iva2_pwrdm",
+ .pwrdm = { .name = "iva2_pwrdm" },
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
},
- { NULL }
+ {
+ .pwrdm = { .name = NULL },
+ }
};
/*
@@ -264,6 +317,8 @@ static struct clkdm_pwrdm_autodep clkdm_pwrdm_autodeps[] = {
static struct clockdomain *clockdomains_omap[] = {
&wkup_clkdm,
+ &cm_clkdm,
+ &prm_clkdm,
#ifdef CONFIG_ARCH_OMAP2420
&mpu_2420_clkdm,
@@ -297,6 +352,11 @@ static struct clockdomain *clockdomains_omap[] = {
&usbhost_clkdm,
&per_clkdm,
&emu_clkdm,
+ &dpll1_clkdm,
+ &dpll2_clkdm,
+ &dpll3_clkdm,
+ &dpll4_clkdm,
+ &dpll5_clkdm,
#endif
NULL,
diff --git a/arch/arm/mach-omap2/cm-regbits-24xx.h b/arch/arm/mach-omap2/cm-regbits-24xx.h
index 1098ecfab861..297a2fe634ea 100644
--- a/arch/arm/mach-omap2/cm-regbits-24xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-24xx.h
@@ -110,35 +110,56 @@
#define OMAP24XX_EN_DES (1 << 0)
/* CM_IDLEST1_CORE specific bits */
-#define OMAP24XX_ST_MAILBOXES (1 << 30)
-#define OMAP24XX_ST_WDT4 (1 << 29)
-#define OMAP2420_ST_WDT3 (1 << 28)
-#define OMAP24XX_ST_MSPRO (1 << 27)
-#define OMAP24XX_ST_FAC (1 << 25)
-#define OMAP2420_ST_EAC (1 << 24)
-#define OMAP24XX_ST_HDQ (1 << 23)
-#define OMAP24XX_ST_I2C2 (1 << 20)
-#define OMAP24XX_ST_I2C1 (1 << 19)
-#define OMAP24XX_ST_MCBSP2 (1 << 16)
-#define OMAP24XX_ST_MCBSP1 (1 << 15)
-#define OMAP24XX_ST_DSS (1 << 0)
+#define OMAP24XX_ST_MAILBOXES_SHIFT 30
+#define OMAP24XX_ST_MAILBOXES_MASK (1 << 30)
+#define OMAP24XX_ST_WDT4_SHIFT 29
+#define OMAP24XX_ST_WDT4_MASK (1 << 29)
+#define OMAP2420_ST_WDT3_SHIFT 28
+#define OMAP2420_ST_WDT3_MASK (1 << 28)
+#define OMAP24XX_ST_MSPRO_SHIFT 27
+#define OMAP24XX_ST_MSPRO_MASK (1 << 27)
+#define OMAP24XX_ST_FAC_SHIFT 25
+#define OMAP24XX_ST_FAC_MASK (1 << 25)
+#define OMAP2420_ST_EAC_SHIFT 24
+#define OMAP2420_ST_EAC_MASK (1 << 24)
+#define OMAP24XX_ST_HDQ_SHIFT 23
+#define OMAP24XX_ST_HDQ_MASK (1 << 23)
+#define OMAP2420_ST_I2C2_SHIFT 20
+#define OMAP2420_ST_I2C2_MASK (1 << 20)
+#define OMAP2420_ST_I2C1_SHIFT 19
+#define OMAP2420_ST_I2C1_MASK (1 << 19)
+#define OMAP24XX_ST_MCBSP2_SHIFT 16
+#define OMAP24XX_ST_MCBSP2_MASK (1 << 16)
+#define OMAP24XX_ST_MCBSP1_SHIFT 15
+#define OMAP24XX_ST_MCBSP1_MASK (1 << 15)
+#define OMAP24XX_ST_DSS_SHIFT 0
+#define OMAP24XX_ST_DSS_MASK (1 << 0)
/* CM_IDLEST2_CORE */
-#define OMAP2430_ST_MCBSP5 (1 << 5)
-#define OMAP2430_ST_MCBSP4 (1 << 4)
-#define OMAP2430_ST_MCBSP3 (1 << 3)
-#define OMAP24XX_ST_SSI (1 << 1)
+#define OMAP2430_ST_MCBSP5_SHIFT 5
+#define OMAP2430_ST_MCBSP5_MASK (1 << 5)
+#define OMAP2430_ST_MCBSP4_SHIFT 4
+#define OMAP2430_ST_MCBSP4_MASK (1 << 4)
+#define OMAP2430_ST_MCBSP3_SHIFT 3
+#define OMAP2430_ST_MCBSP3_MASK (1 << 3)
+#define OMAP24XX_ST_SSI_SHIFT 1
+#define OMAP24XX_ST_SSI_MASK (1 << 1)
/* CM_IDLEST3_CORE */
/* 2430 only */
-#define OMAP2430_ST_SDRC (1 << 2)
+#define OMAP2430_ST_SDRC_MASK (1 << 2)
/* CM_IDLEST4_CORE */
-#define OMAP24XX_ST_PKA (1 << 4)
-#define OMAP24XX_ST_AES (1 << 3)
-#define OMAP24XX_ST_RNG (1 << 2)
-#define OMAP24XX_ST_SHA (1 << 1)
-#define OMAP24XX_ST_DES (1 << 0)
+#define OMAP24XX_ST_PKA_SHIFT 4
+#define OMAP24XX_ST_PKA_MASK (1 << 4)
+#define OMAP24XX_ST_AES_SHIFT 3
+#define OMAP24XX_ST_AES_MASK (1 << 3)
+#define OMAP24XX_ST_RNG_SHIFT 2
+#define OMAP24XX_ST_RNG_MASK (1 << 2)
+#define OMAP24XX_ST_SHA_SHIFT 1
+#define OMAP24XX_ST_SHA_MASK (1 << 1)
+#define OMAP24XX_ST_DES_SHIFT 0
+#define OMAP24XX_ST_DES_MASK (1 << 0)
/* CM_AUTOIDLE1_CORE */
#define OMAP24XX_AUTO_CAM (1 << 31)
@@ -275,11 +296,16 @@
#define OMAP24XX_EN_32KSYNC (1 << 1)
/* CM_IDLEST_WKUP specific bits */
-#define OMAP2430_ST_ICR (1 << 6)
-#define OMAP24XX_ST_OMAPCTRL (1 << 5)
-#define OMAP24XX_ST_WDT1 (1 << 4)
-#define OMAP24XX_ST_MPU_WDT (1 << 3)
-#define OMAP24XX_ST_32KSYNC (1 << 1)
+#define OMAP2430_ST_ICR_SHIFT 6
+#define OMAP2430_ST_ICR_MASK (1 << 6)
+#define OMAP24XX_ST_OMAPCTRL_SHIFT 5
+#define OMAP24XX_ST_OMAPCTRL_MASK (1 << 5)
+#define OMAP24XX_ST_WDT1_SHIFT 4
+#define OMAP24XX_ST_WDT1_MASK (1 << 4)
+#define OMAP24XX_ST_MPU_WDT_SHIFT 3
+#define OMAP24XX_ST_MPU_WDT_MASK (1 << 3)
+#define OMAP24XX_ST_32KSYNC_SHIFT 1
+#define OMAP24XX_ST_32KSYNC_MASK (1 << 1)
/* CM_AUTOIDLE_WKUP */
#define OMAP24XX_AUTO_OMAPCTRL (1 << 5)
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
index 219f5c8d9659..6f3f5a36aae6 100644
--- a/arch/arm/mach-omap2/cm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -183,31 +183,58 @@
#define OMAP3430ES2_EN_CPEFUSE_MASK (1 << 0)
/* CM_IDLEST1_CORE specific bits */
-#define OMAP3430_ST_ICR (1 << 29)
-#define OMAP3430_ST_AES2 (1 << 28)
-#define OMAP3430_ST_SHA12 (1 << 27)
-#define OMAP3430_ST_DES2 (1 << 26)
-#define OMAP3430_ST_MSPRO (1 << 23)
-#define OMAP3430_ST_HDQ (1 << 22)
-#define OMAP3430ES1_ST_FAC (1 << 8)
-#define OMAP3430ES1_ST_MAILBOXES (1 << 7)
-#define OMAP3430_ST_OMAPCTRL (1 << 6)
-#define OMAP3430_ST_SDMA (1 << 2)
-#define OMAP3430_ST_SDRC (1 << 1)
-#define OMAP3430_ST_SSI (1 << 0)
+#define OMAP3430ES2_ST_MMC3_SHIFT 30
+#define OMAP3430ES2_ST_MMC3_MASK (1 << 30)
+#define OMAP3430_ST_ICR_SHIFT 29
+#define OMAP3430_ST_ICR_MASK (1 << 29)
+#define OMAP3430_ST_AES2_SHIFT 28
+#define OMAP3430_ST_AES2_MASK (1 << 28)
+#define OMAP3430_ST_SHA12_SHIFT 27
+#define OMAP3430_ST_SHA12_MASK (1 << 27)
+#define OMAP3430_ST_DES2_SHIFT 26
+#define OMAP3430_ST_DES2_MASK (1 << 26)
+#define OMAP3430_ST_MSPRO_SHIFT 23
+#define OMAP3430_ST_MSPRO_MASK (1 << 23)
+#define OMAP3430_ST_HDQ_SHIFT 22
+#define OMAP3430_ST_HDQ_MASK (1 << 22)
+#define OMAP3430ES1_ST_FAC_SHIFT 8
+#define OMAP3430ES1_ST_FAC_MASK (1 << 8)
+#define OMAP3430ES2_ST_SSI_IDLE_SHIFT 8
+#define OMAP3430ES2_ST_SSI_IDLE_MASK (1 << 8)
+#define OMAP3430_ST_MAILBOXES_SHIFT 7
+#define OMAP3430_ST_MAILBOXES_MASK (1 << 7)
+#define OMAP3430_ST_OMAPCTRL_SHIFT 6
+#define OMAP3430_ST_OMAPCTRL_MASK (1 << 6)
+#define OMAP3430_ST_SDMA_SHIFT 2
+#define OMAP3430_ST_SDMA_MASK (1 << 2)
+#define OMAP3430_ST_SDRC_SHIFT 1
+#define OMAP3430_ST_SDRC_MASK (1 << 1)
+#define OMAP3430_ST_SSI_STDBY_SHIFT 0
+#define OMAP3430_ST_SSI_STDBY_MASK (1 << 0)
/* CM_IDLEST2_CORE */
-#define OMAP3430_ST_PKA (1 << 4)
-#define OMAP3430_ST_AES1 (1 << 3)
-#define OMAP3430_ST_RNG (1 << 2)
-#define OMAP3430_ST_SHA11 (1 << 1)
-#define OMAP3430_ST_DES1 (1 << 0)
+#define OMAP3430_ST_PKA_SHIFT 4
+#define OMAP3430_ST_PKA_MASK (1 << 4)
+#define OMAP3430_ST_AES1_SHIFT 3
+#define OMAP3430_ST_AES1_MASK (1 << 3)
+#define OMAP3430_ST_RNG_SHIFT 2
+#define OMAP3430_ST_RNG_MASK (1 << 2)
+#define OMAP3430_ST_SHA11_SHIFT 1
+#define OMAP3430_ST_SHA11_MASK (1 << 1)
+#define OMAP3430_ST_DES1_SHIFT 0
+#define OMAP3430_ST_DES1_MASK (1 << 0)
/* CM_IDLEST3_CORE */
#define OMAP3430ES2_ST_USBTLL_SHIFT 2
#define OMAP3430ES2_ST_USBTLL_MASK (1 << 2)
+#define OMAP3430ES2_ST_CPEFUSE_SHIFT 0
+#define OMAP3430ES2_ST_CPEFUSE_MASK (1 << 0)
/* CM_AUTOIDLE1_CORE */
+#define OMAP3430ES2_AUTO_MMC3 (1 << 30)
+#define OMAP3430ES2_AUTO_MMC3_SHIFT 30
+#define OMAP3430ES2_AUTO_ICR (1 << 29)
+#define OMAP3430ES2_AUTO_ICR_SHIFT 29
#define OMAP3430_AUTO_AES2 (1 << 28)
#define OMAP3430_AUTO_AES2_SHIFT 28
#define OMAP3430_AUTO_SHA12 (1 << 27)
@@ -276,6 +303,9 @@
#define OMAP3430_AUTO_DES1_SHIFT 0
/* CM_AUTOIDLE3_CORE */
+#define OMAP3430ES2_AUTO_USBHOST (1 << 0)
+#define OMAP3430ES2_AUTO_USBHOST_SHIFT 0
+#define OMAP3430ES2_AUTO_USBTLL (1 << 2)
#define OMAP3430ES2_AUTO_USBTLL_SHIFT 2
#define OMAP3430ES2_AUTO_USBTLL_MASK (1 << 2)
@@ -332,8 +362,12 @@
#define OMAP3430ES1_CLKACTIVITY_GFX_MASK (1 << 0)
/* CM_FCLKEN_SGX */
-#define OMAP3430ES2_EN_SGX_SHIFT 1
-#define OMAP3430ES2_EN_SGX_MASK (1 << 1)
+#define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT 1
+#define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_MASK (1 << 1)
+
+/* CM_ICLKEN_SGX */
+#define OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT 0
+#define OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_MASK (1 << 0)
/* CM_CLKSEL_SGX */
#define OMAP3430ES2_CLKSEL_SGX_SHIFT 0
@@ -349,6 +383,7 @@
/* CM_FCLKEN_WKUP specific bits */
#define OMAP3430ES2_EN_USIMOCP_SHIFT 9
+#define OMAP3430ES2_EN_USIMOCP_MASK (1 << 9)
/* CM_ICLKEN_WKUP specific bits */
#define OMAP3430_EN_WDT1 (1 << 4)
@@ -357,11 +392,18 @@
#define OMAP3430_EN_32KSYNC_SHIFT 2
/* CM_IDLEST_WKUP specific bits */
-#define OMAP3430_ST_WDT2 (1 << 5)
-#define OMAP3430_ST_WDT1 (1 << 4)
-#define OMAP3430_ST_32KSYNC (1 << 2)
+#define OMAP3430ES2_ST_USIMOCP_SHIFT 9
+#define OMAP3430ES2_ST_USIMOCP_MASK (1 << 9)
+#define OMAP3430_ST_WDT2_SHIFT 5
+#define OMAP3430_ST_WDT2_MASK (1 << 5)
+#define OMAP3430_ST_WDT1_SHIFT 4
+#define OMAP3430_ST_WDT1_MASK (1 << 4)
+#define OMAP3430_ST_32KSYNC_SHIFT 2
+#define OMAP3430_ST_32KSYNC_MASK (1 << 2)
/* CM_AUTOIDLE_WKUP */
+#define OMAP3430ES2_AUTO_USIMOCP (1 << 9)
+#define OMAP3430ES2_AUTO_USIMOCP_SHIFT 9
#define OMAP3430_AUTO_WDT2 (1 << 5)
#define OMAP3430_AUTO_WDT2_SHIFT 5
#define OMAP3430_AUTO_WDT1 (1 << 4)
@@ -426,6 +468,8 @@
#define OMAP3430_ST_CORE_CLK_MASK (1 << 0)
/* CM_IDLEST2_CKGEN */
+#define OMAP3430ES2_ST_USIM_CLK_SHIFT 2
+#define OMAP3430ES2_ST_USIM_CLK_MASK (1 << 2)
#define OMAP3430ES2_ST_120M_CLK_SHIFT 1
#define OMAP3430ES2_ST_120M_CLK_MASK (1 << 1)
#define OMAP3430ES2_ST_PERIPH2_CLK_SHIFT 0
@@ -449,8 +493,12 @@
#define OMAP3430_CORE_DPLL_MULT_MASK (0x7ff << 16)
#define OMAP3430_CORE_DPLL_DIV_SHIFT 8
#define OMAP3430_CORE_DPLL_DIV_MASK (0x7f << 8)
-#define OMAP3430_SOURCE_54M (1 << 5)
-#define OMAP3430_SOURCE_48M (1 << 3)
+#define OMAP3430_SOURCE_96M_SHIFT 6
+#define OMAP3430_SOURCE_96M_MASK (1 << 6)
+#define OMAP3430_SOURCE_54M_SHIFT 5
+#define OMAP3430_SOURCE_54M_MASK (1 << 5)
+#define OMAP3430_SOURCE_48M_SHIFT 3
+#define OMAP3430_SOURCE_48M_MASK (1 << 3)
/* CM_CLKSEL2_PLL */
#define OMAP3430_PERIPH_DPLL_MULT_SHIFT 8
@@ -493,7 +541,12 @@
#define OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT 0
/* CM_IDLEST_DSS */
-#define OMAP3430_ST_DSS (1 << 0)
+#define OMAP3430ES2_ST_DSS_IDLE_SHIFT 1
+#define OMAP3430ES2_ST_DSS_IDLE_MASK (1 << 1)
+#define OMAP3430ES2_ST_DSS_STDBY_SHIFT 0
+#define OMAP3430ES2_ST_DSS_STDBY_MASK (1 << 0)
+#define OMAP3430ES1_ST_DSS_SHIFT 0
+#define OMAP3430ES1_ST_DSS_MASK (1 << 0)
/* CM_AUTOIDLE_DSS */
#define OMAP3430_AUTO_DSS (1 << 0)
@@ -516,6 +569,8 @@
#define OMAP3430_CLKACTIVITY_DSS_MASK (1 << 0)
/* CM_FCLKEN_CAM specific bits */
+#define OMAP3430_EN_CSI2 (1 << 1)
+#define OMAP3430_EN_CSI2_SHIFT 1
/* CM_ICLKEN_CAM specific bits */
@@ -545,10 +600,14 @@
/* CM_ICLKEN_PER specific bits */
/* CM_IDLEST_PER */
-#define OMAP3430_ST_WDT3 (1 << 12)
-#define OMAP3430_ST_MCBSP4 (1 << 2)
-#define OMAP3430_ST_MCBSP3 (1 << 1)
-#define OMAP3430_ST_MCBSP2 (1 << 0)
+#define OMAP3430_ST_WDT3_SHIFT 12
+#define OMAP3430_ST_WDT3_MASK (1 << 12)
+#define OMAP3430_ST_MCBSP4_SHIFT 2
+#define OMAP3430_ST_MCBSP4_MASK (1 << 2)
+#define OMAP3430_ST_MCBSP3_SHIFT 1
+#define OMAP3430_ST_MCBSP3_MASK (1 << 1)
+#define OMAP3430_ST_MCBSP2_SHIFT 0
+#define OMAP3430_ST_MCBSP2_MASK (1 << 0)
/* CM_AUTOIDLE_PER */
#define OMAP3430_AUTO_GPIO6 (1 << 17)
@@ -676,6 +735,10 @@
#define OMAP3430ES2_EN_USBHOST_MASK (1 << 0)
/* CM_IDLEST_USBHOST */
+#define OMAP3430ES2_ST_USBHOST_IDLE_SHIFT 1
+#define OMAP3430ES2_ST_USBHOST_IDLE_MASK (1 << 1)
+#define OMAP3430ES2_ST_USBHOST_STDBY_SHIFT 0
+#define OMAP3430ES2_ST_USBHOST_STDBY_MASK (1 << 0)
/* CM_AUTOIDLE_USBHOST */
#define OMAP3430ES2_AUTO_USBHOST_SHIFT 0
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index ce03fa750775..d6b4b2f8722f 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -28,13 +28,121 @@
#include <mach/eac.h>
#include <mach/mmc.h>
-#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
-#define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE)
+#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
-static struct resource mbox_resources[] = {
+static struct resource cam_resources[] = {
{
- .start = OMAP2_MBOX_BASE,
- .end = OMAP2_MBOX_BASE + 0x11f,
+ .start = OMAP24XX_CAMERA_BASE,
+ .end = OMAP24XX_CAMERA_BASE + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_24XX_CAM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device omap_cam_device = {
+ .name = "omap24xxcam",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cam_resources),
+ .resource = cam_resources,
+};
+
+static inline void omap_init_camera(void)
+{
+ platform_device_register(&omap_cam_device);
+}
+
+#elif defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
+
+static struct resource omap3isp_resources[] = {
+ {
+ .start = OMAP3430_ISP_BASE,
+ .end = OMAP3430_ISP_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CBUFF_BASE,
+ .end = OMAP3430_ISP_CBUFF_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CCP2_BASE,
+ .end = OMAP3430_ISP_CCP2_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CCDC_BASE,
+ .end = OMAP3430_ISP_CCDC_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_HIST_BASE,
+ .end = OMAP3430_ISP_HIST_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_H3A_BASE,
+ .end = OMAP3430_ISP_H3A_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_PREV_BASE,
+ .end = OMAP3430_ISP_PREV_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_RESZ_BASE,
+ .end = OMAP3430_ISP_RESZ_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_SBL_BASE,
+ .end = OMAP3430_ISP_SBL_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CSI2A_BASE,
+ .end = OMAP3430_ISP_CSI2A_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CSI2PHY_BASE,
+ .end = OMAP3430_ISP_CSI2PHY_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_34XX_CAM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device omap3isp_device = {
+ .name = "omap3isp",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(omap3isp_resources),
+ .resource = omap3isp_resources,
+};
+
+static inline void omap_init_camera(void)
+{
+ platform_device_register(&omap3isp_device);
+}
+#else
+static inline void omap_init_camera(void)
+{
+}
+#endif
+
+#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
+
+#define MBOX_REG_SIZE 0x120
+
+static struct resource omap2_mbox_resources[] = {
+ {
+ .start = OMAP24XX_MAILBOX_BASE,
+ .end = OMAP24XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
@@ -47,20 +155,40 @@ static struct resource mbox_resources[] = {
},
};
+static struct resource omap3_mbox_resources[] = {
+ {
+ .start = OMAP34XX_MAILBOX_BASE,
+ .end = OMAP34XX_MAILBOX_BASE + MBOX_REG_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_24XX_MAIL_U0_MPU,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
static struct platform_device mbox_device = {
- .name = "mailbox",
+ .name = "omap2-mailbox",
.id = -1,
- .num_resources = ARRAY_SIZE(mbox_resources),
- .resource = mbox_resources,
};
static inline void omap_init_mbox(void)
{
+ if (cpu_is_omap2420()) {
+ mbox_device.num_resources = ARRAY_SIZE(omap2_mbox_resources);
+ mbox_device.resource = omap2_mbox_resources;
+ } else if (cpu_is_omap3430()) {
+ mbox_device.num_resources = ARRAY_SIZE(omap3_mbox_resources);
+ mbox_device.resource = omap3_mbox_resources;
+ } else {
+ pr_err("%s: platform not supported\n", __func__);
+ return;
+ }
platform_device_register(&mbox_device);
}
#else
static inline void omap_init_mbox(void) { }
-#endif
+#endif /* CONFIG_OMAP_MBOX_FWK */
#if defined(CONFIG_OMAP_STI)
@@ -348,11 +476,12 @@ static void __init omap_hsmmc_reset(void)
}
dummy_pdev.id = i;
- iclk = clk_get(dev, "mmchs_ick");
+ dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i);
+ iclk = clk_get(dev, "ick");
if (iclk && clk_enable(iclk))
iclk = NULL;
- fclk = clk_get(dev, "mmchs_fck");
+ fclk = clk_get(dev, "fck");
if (fclk && clk_enable(fclk))
fclk = NULL;
@@ -506,6 +635,7 @@ static int __init omap2_init_devices(void)
* in alphabetical order so they're easier to sort through.
*/
omap_hsmmc_reset();
+ omap_init_camera();
omap_init_mbox();
omap_init_mcspi();
omap_hdq_init();
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index b52a02fc7cd6..34b5914e0f8b 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -217,8 +217,13 @@ void __init omap2_check_revision(void)
omap_chip.oc = CHIP_IS_OMAP3430;
if (omap_rev() == OMAP3430_REV_ES1_0)
omap_chip.oc |= CHIP_IS_OMAP3430ES1;
- else if (omap_rev() > OMAP3430_REV_ES1_0)
+ else if (omap_rev() >= OMAP3430_REV_ES2_0 &&
+ omap_rev() <= OMAP3430_REV_ES2_1)
omap_chip.oc |= CHIP_IS_OMAP3430ES2;
+ else if (omap_rev() == OMAP3430_REV_ES3_0)
+ omap_chip.oc |= CHIP_IS_OMAP3430ES3_0;
+ else if (omap_rev() == OMAP3430_REV_ES3_1)
+ omap_chip.oc |= CHIP_IS_OMAP3430ES3_1;
} else {
pr_err("Uninitialized omap_chip, please fix!\n");
}
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 5ea64f926ed5..916fcd3a2328 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -27,8 +27,8 @@
#include <mach/mux.h>
#include <mach/omapfb.h>
#include <mach/sram.h>
-
-#include "memory.h"
+#include <mach/sdrc.h>
+#include <mach/gpmc.h>
#include "clock.h"
@@ -195,12 +195,12 @@ void __init omap2_map_common_io(void)
omapfb_reserve_sdram();
}
-void __init omap2_init_common_hw(void)
+void __init omap2_init_common_hw(struct omap_sdrc_params *sp)
{
omap2_mux_init();
pwrdm_init(powerdomains_omap);
clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
omap2_clk_init();
- omap2_init_memory();
+ omap2_sdrc_init(sp);
gpmc_init();
}
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
index 32b7af3c610b..fd5b8a5925cc 100644
--- a/arch/arm/mach-omap2/mailbox.c
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -1,9 +1,9 @@
/*
- * Mailbox reservation modules for OMAP2
+ * Mailbox reservation modules for OMAP2/3
*
- * Copyright (C) 2006 Nokia Corporation
+ * Copyright (C) 2006-2009 Nokia Corporation
* Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
- * and Paul Mundt <paul.mundt@nokia.com>
+ * and Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -18,40 +18,22 @@
#include <mach/mailbox.h>
#include <mach/irqs.h>
-#define MAILBOX_REVISION 0x00
-#define MAILBOX_SYSCONFIG 0x10
-#define MAILBOX_SYSSTATUS 0x14
-#define MAILBOX_MESSAGE_0 0x40
-#define MAILBOX_MESSAGE_1 0x44
-#define MAILBOX_MESSAGE_2 0x48
-#define MAILBOX_MESSAGE_3 0x4c
-#define MAILBOX_MESSAGE_4 0x50
-#define MAILBOX_MESSAGE_5 0x54
-#define MAILBOX_FIFOSTATUS_0 0x80
-#define MAILBOX_FIFOSTATUS_1 0x84
-#define MAILBOX_FIFOSTATUS_2 0x88
-#define MAILBOX_FIFOSTATUS_3 0x8c
-#define MAILBOX_FIFOSTATUS_4 0x90
-#define MAILBOX_FIFOSTATUS_5 0x94
-#define MAILBOX_MSGSTATUS_0 0xc0
-#define MAILBOX_MSGSTATUS_1 0xc4
-#define MAILBOX_MSGSTATUS_2 0xc8
-#define MAILBOX_MSGSTATUS_3 0xcc
-#define MAILBOX_MSGSTATUS_4 0xd0
-#define MAILBOX_MSGSTATUS_5 0xd4
-#define MAILBOX_IRQSTATUS_0 0x100
-#define MAILBOX_IRQENABLE_0 0x104
-#define MAILBOX_IRQSTATUS_1 0x108
-#define MAILBOX_IRQENABLE_1 0x10c
-#define MAILBOX_IRQSTATUS_2 0x110
-#define MAILBOX_IRQENABLE_2 0x114
-#define MAILBOX_IRQSTATUS_3 0x118
-#define MAILBOX_IRQENABLE_3 0x11c
-
-static unsigned long mbox_base;
-
-#define MAILBOX_IRQ_NOTFULL(n) (1 << (2 * (n) + 1))
-#define MAILBOX_IRQ_NEWMSG(n) (1 << (2 * (n)))
+#define MAILBOX_REVISION 0x000
+#define MAILBOX_SYSCONFIG 0x010
+#define MAILBOX_SYSSTATUS 0x014
+#define MAILBOX_MESSAGE(m) (0x040 + 4 * (m))
+#define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m))
+#define MAILBOX_MSGSTATUS(m) (0x0c0 + 4 * (m))
+#define MAILBOX_IRQSTATUS(u) (0x100 + 8 * (u))
+#define MAILBOX_IRQENABLE(u) (0x104 + 8 * (u))
+
+#define MAILBOX_IRQ_NEWMSG(u) (1 << (2 * (u)))
+#define MAILBOX_IRQ_NOTFULL(u) (1 << (2 * (u) + 1))
+
+#define MBOX_REG_SIZE 0x120
+#define MBOX_NR_REGS (MBOX_REG_SIZE / sizeof(u32))
+
+static void __iomem *mbox_base;
struct omap_mbox2_fifo {
unsigned long msg;
@@ -66,6 +48,7 @@ struct omap_mbox2_priv {
unsigned long irqstatus;
u32 newmsg_bit;
u32 notfull_bit;
+ u32 ctx[MBOX_NR_REGS];
};
static struct clk *mbox_ick_handle;
@@ -73,14 +56,14 @@ static struct clk *mbox_ick_handle;
static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
omap_mbox_type_t irq);
-static inline unsigned int mbox_read_reg(unsigned int reg)
+static inline unsigned int mbox_read_reg(size_t ofs)
{
- return __raw_readl(mbox_base + reg);
+ return __raw_readl(mbox_base + ofs);
}
-static inline void mbox_write_reg(unsigned int val, unsigned int reg)
+static inline void mbox_write_reg(u32 val, size_t ofs)
{
- __raw_writel(val, mbox_base + reg);
+ __raw_writel(val, mbox_base + ofs);
}
/* Mailbox H/W preparations */
@@ -95,6 +78,9 @@ static int omap2_mbox_startup(struct omap_mbox *mbox)
}
clk_enable(mbox_ick_handle);
+ l = mbox_read_reg(MAILBOX_REVISION);
+ pr_info("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f));
+
/* set smart-idle & autoidle */
l = mbox_read_reg(MAILBOX_SYSCONFIG);
l |= 0x00000011;
@@ -183,6 +169,32 @@ static int omap2_mbox_is_irq(struct omap_mbox *mbox,
return (enable & status & bit);
}
+static void omap2_mbox_save_ctx(struct omap_mbox *mbox)
+{
+ int i;
+ struct omap_mbox2_priv *p = mbox->priv;
+
+ for (i = 0; i < MBOX_NR_REGS; i++) {
+ p->ctx[i] = mbox_read_reg(i * sizeof(u32));
+
+ dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
+ i, p->ctx[i]);
+ }
+}
+
+static void omap2_mbox_restore_ctx(struct omap_mbox *mbox)
+{
+ int i;
+ struct omap_mbox2_priv *p = mbox->priv;
+
+ for (i = 0; i < MBOX_NR_REGS; i++) {
+ mbox_write_reg(p->ctx[i], i * sizeof(u32));
+
+ dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
+ i, p->ctx[i]);
+ }
+}
+
static struct omap_mbox_ops omap2_mbox_ops = {
.type = OMAP_MBOX_TYPE2,
.startup = omap2_mbox_startup,
@@ -195,6 +207,8 @@ static struct omap_mbox_ops omap2_mbox_ops = {
.disable_irq = omap2_mbox_disable_irq,
.ack_irq = omap2_mbox_ack_irq,
.is_irq = omap2_mbox_is_irq,
+ .save_ctx = omap2_mbox_save_ctx,
+ .restore_ctx = omap2_mbox_restore_ctx,
};
/*
@@ -209,15 +223,15 @@ static struct omap_mbox_ops omap2_mbox_ops = {
/* DSP */
static struct omap_mbox2_priv omap2_mbox_dsp_priv = {
.tx_fifo = {
- .msg = MAILBOX_MESSAGE_0,
- .fifo_stat = MAILBOX_FIFOSTATUS_0,
+ .msg = MAILBOX_MESSAGE(0),
+ .fifo_stat = MAILBOX_FIFOSTATUS(0),
},
.rx_fifo = {
- .msg = MAILBOX_MESSAGE_1,
- .msg_stat = MAILBOX_MSGSTATUS_1,
+ .msg = MAILBOX_MESSAGE(1),
+ .msg_stat = MAILBOX_MSGSTATUS(1),
},
- .irqenable = MAILBOX_IRQENABLE_0,
- .irqstatus = MAILBOX_IRQSTATUS_0,
+ .irqenable = MAILBOX_IRQENABLE(0),
+ .irqstatus = MAILBOX_IRQSTATUS(0),
.notfull_bit = MAILBOX_IRQ_NOTFULL(0),
.newmsg_bit = MAILBOX_IRQ_NEWMSG(1),
};
@@ -229,18 +243,18 @@ struct omap_mbox mbox_dsp_info = {
};
EXPORT_SYMBOL(mbox_dsp_info);
-/* IVA */
+#if defined(CONFIG_ARCH_OMAP2420) /* IVA */
static struct omap_mbox2_priv omap2_mbox_iva_priv = {
.tx_fifo = {
- .msg = MAILBOX_MESSAGE_2,
- .fifo_stat = MAILBOX_FIFOSTATUS_2,
+ .msg = MAILBOX_MESSAGE(2),
+ .fifo_stat = MAILBOX_FIFOSTATUS(2),
},
.rx_fifo = {
- .msg = MAILBOX_MESSAGE_3,
- .msg_stat = MAILBOX_MSGSTATUS_3,
+ .msg = MAILBOX_MESSAGE(3),
+ .msg_stat = MAILBOX_MSGSTATUS(3),
},
- .irqenable = MAILBOX_IRQENABLE_3,
- .irqstatus = MAILBOX_IRQSTATUS_3,
+ .irqenable = MAILBOX_IRQENABLE(3),
+ .irqstatus = MAILBOX_IRQSTATUS(3),
.notfull_bit = MAILBOX_IRQ_NOTFULL(2),
.newmsg_bit = MAILBOX_IRQ_NEWMSG(3),
};
@@ -250,17 +264,12 @@ static struct omap_mbox mbox_iva_info = {
.ops = &omap2_mbox_ops,
.priv = &omap2_mbox_iva_priv,
};
+#endif
-static int __init omap2_mbox_probe(struct platform_device *pdev)
+static int __devinit omap2_mbox_probe(struct platform_device *pdev)
{
struct resource *res;
- int ret = 0;
-
- if (pdev->num_resources != 3) {
- dev_err(&pdev->dev, "invalid number of resources: %d\n",
- pdev->num_resources);
- return -ENODEV;
- }
+ int ret;
/* MBOX base */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -268,42 +277,61 @@ static int __init omap2_mbox_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "invalid mem resource\n");
return -ENODEV;
}
- mbox_base = res->start;
+ mbox_base = ioremap(res->start, res->end - res->start);
+ if (!mbox_base)
+ return -ENOMEM;
- /* DSP IRQ */
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (unlikely(!res)) {
+ /* DSP or IVA2 IRQ */
+ mbox_dsp_info.irq = platform_get_irq(pdev, 0);
+ if (mbox_dsp_info.irq < 0) {
dev_err(&pdev->dev, "invalid irq resource\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_dsp;
}
- mbox_dsp_info.irq = res->start;
- ret = omap_mbox_register(&mbox_dsp_info);
-
- /* IVA IRQ */
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
- if (unlikely(!res)) {
- dev_err(&pdev->dev, "invalid irq resource\n");
- return -ENODEV;
+ ret = omap_mbox_register(&pdev->dev, &mbox_dsp_info);
+ if (ret)
+ goto err_dsp;
+
+#if defined(CONFIG_ARCH_OMAP2420) /* IVA */
+ if (cpu_is_omap2420()) {
+ /* IVA IRQ */
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+ if (unlikely(!res)) {
+ dev_err(&pdev->dev, "invalid irq resource\n");
+ ret = -ENODEV;
+ goto err_iva1;
+ }
+ mbox_iva_info.irq = res->start;
+ ret = omap_mbox_register(&pdev->dev, &mbox_iva_info);
+ if (ret)
+ goto err_iva1;
}
- mbox_iva_info.irq = res->start;
-
- ret = omap_mbox_register(&mbox_iva_info);
+#endif
+ return 0;
+err_iva1:
+ omap_mbox_unregister(&mbox_dsp_info);
+err_dsp:
+ iounmap(mbox_base);
return ret;
}
-static int omap2_mbox_remove(struct platform_device *pdev)
+static int __devexit omap2_mbox_remove(struct platform_device *pdev)
{
+#if defined(CONFIG_ARCH_OMAP2420)
+ omap_mbox_unregister(&mbox_iva_info);
+#endif
omap_mbox_unregister(&mbox_dsp_info);
+ iounmap(mbox_base);
return 0;
}
static struct platform_driver omap2_mbox_driver = {
.probe = omap2_mbox_probe,
- .remove = omap2_mbox_remove,
+ .remove = __devexit_p(omap2_mbox_remove),
.driver = {
- .name = "mailbox",
+ .name = "omap2-mailbox",
},
};
@@ -320,4 +348,7 @@ static void __exit omap2_mbox_exit(void)
module_init(omap2_mbox_init);
module_exit(omap2_mbox_exit);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("omap mailbox: omap2/3 architecture specific functions");
+MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>, Paul Mundt");
+MODULE_ALIAS("platform:omap2-mailbox");
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index a9e631fc1134..a5c0f0435cd6 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -24,8 +24,6 @@
#include <mach/cpu.h>
#include <mach/mcbsp.h>
-const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" };
-
static void omap2_mcbsp2_mux_setup(void)
{
omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
@@ -57,8 +55,6 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
.tx_irq = INT_24XX_MCBSP1_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 2,
},
{
.phys_base = OMAP24XX_MCBSP2_BASE,
@@ -67,8 +63,6 @@ static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
.tx_irq = INT_24XX_MCBSP2_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 2,
},
};
#define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata)
@@ -86,8 +80,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
.tx_irq = INT_24XX_MCBSP1_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 2,
},
{
.phys_base = OMAP24XX_MCBSP2_BASE,
@@ -96,8 +88,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
.tx_irq = INT_24XX_MCBSP2_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 2,
},
{
.phys_base = OMAP2430_MCBSP3_BASE,
@@ -106,8 +96,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP3_IRQ_RX,
.tx_irq = INT_24XX_MCBSP3_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 2,
},
{
.phys_base = OMAP2430_MCBSP4_BASE,
@@ -116,8 +104,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP4_IRQ_RX,
.tx_irq = INT_24XX_MCBSP4_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 2,
},
{
.phys_base = OMAP2430_MCBSP5_BASE,
@@ -126,8 +112,6 @@ static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP5_IRQ_RX,
.tx_irq = INT_24XX_MCBSP5_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 2,
},
};
#define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata)
@@ -145,8 +129,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
.tx_irq = INT_24XX_MCBSP1_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 2,
},
{
.phys_base = OMAP34XX_MCBSP2_BASE,
@@ -155,8 +137,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
.tx_irq = INT_24XX_MCBSP2_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 2,
},
{
.phys_base = OMAP34XX_MCBSP3_BASE,
@@ -165,8 +145,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP3_IRQ_RX,
.tx_irq = INT_24XX_MCBSP3_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 2,
},
{
.phys_base = OMAP34XX_MCBSP4_BASE,
@@ -175,8 +153,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP4_IRQ_RX,
.tx_irq = INT_24XX_MCBSP4_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 2,
},
{
.phys_base = OMAP34XX_MCBSP5_BASE,
@@ -185,8 +161,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.rx_irq = INT_24XX_MCBSP5_IRQ_RX,
.tx_irq = INT_24XX_MCBSP5_IRQ_TX,
.ops = &omap2_mcbsp_ops,
- .clk_names = clk_names,
- .num_clks = 2,
},
};
#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata)
diff --git a/arch/arm/mach-omap2/memory.h b/arch/arm/mach-omap2/memory.h
deleted file mode 100644
index bb3db80a7c46..000000000000
--- a/arch/arm/mach-omap2/memory.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/memory.h
- *
- * Interface for memory timing related functions for OMAP24XX
- *
- * Copyright (C) 2005 Texas Instruments Inc.
- * Richard Woodruff <r-woodruff2@ti.com>
- *
- * Copyright (C) 2005 Nokia Corporation
- * Tony Lindgren <tony@atomide.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef ARCH_ARM_MACH_OMAP2_MEMORY_H
-#define ARCH_ARM_MACH_OMAP2_MEMORY_H
-
-/* Memory timings */
-#define M_DDR 1
-#define M_LOCK_CTRL (1 << 2)
-#define M_UNLOCK 0
-#define M_LOCK 1
-
-struct memory_timings {
- u32 m_type; /* ddr = 1, sdr = 0 */
- u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */
- u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */
- u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */
- u32 base_cs; /* base chip select to use for calculations */
-};
-
-extern void omap2_init_memory_params(u32 force_lock_to_unlock_mode);
-extern u32 omap2_memory_get_slow_dll_ctrl(void);
-extern u32 omap2_memory_get_fast_dll_ctrl(void);
-extern u32 omap2_memory_get_type(void);
-u32 omap2_dll_force_needed(void);
-u32 omap2_reprogram_sdrc(u32 level, u32 force);
-void __init omap2_init_memory(void);
-void __init gpmc_init(void);
-
-#endif
diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c
index 437f52073f6e..dc40b3e72206 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.c
+++ b/arch/arm/mach-omap2/mmc-twl4030.c
@@ -17,6 +17,7 @@
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/i2c/twl4030.h>
+#include <linux/regulator/machine.h>
#include <mach/hardware.h>
#include <mach/control.h>
@@ -44,6 +45,7 @@
#define VMMC2_315V 0x0c
#define VMMC2_300V 0x0b
#define VMMC2_285V 0x0a
+#define VMMC2_280V 0x09
#define VMMC2_260V 0x08
#define VMMC2_185V 0x06
#define VMMC2_DEDICATED 0x2E
@@ -59,8 +61,8 @@ static struct twl_mmc_controller {
struct omap_mmc_platform_data *mmc;
u8 twl_vmmc_dev_grp;
u8 twl_mmc_dedicated;
- char name[HSMMC_NAME_LEN];
-} hsmmc[] = {
+ char name[HSMMC_NAME_LEN + 1];
+} hsmmc[OMAP34XX_NR_MMC] = {
{
.twl_vmmc_dev_grp = VMMC1_DEV_GRP,
.twl_mmc_dedicated = VMMC1_DEDICATED,
@@ -98,6 +100,14 @@ static int twl_mmc_get_ro(struct device *dev, int slot)
return gpio_get_value_cansleep(mmc->slots[0].gpio_wp);
}
+static int twl_mmc_get_cover_state(struct device *dev, int slot)
+{
+ struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+ /* NOTE: assumes card detect signal is active-low */
+ return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
+}
+
/*
* MMC Slot Initialization.
*/
@@ -166,66 +176,85 @@ static int twl_mmc_resume(struct device *dev, int slot)
/*
* Sets the MMC voltage in twl4030
*/
+
+#define MMC1_OCR (MMC_VDD_165_195 \
+ |MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32)
+#define MMC2_OCR (MMC_VDD_165_195 \
+ |MMC_VDD_25_26|MMC_VDD_26_27|MMC_VDD_27_28 \
+ |MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32)
+
static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd)
{
int ret;
- u8 vmmc, dev_grp_val;
-
- switch (1 << vdd) {
- case MMC_VDD_35_36:
- case MMC_VDD_34_35:
- case MMC_VDD_33_34:
- case MMC_VDD_32_33:
- case MMC_VDD_31_32:
- case MMC_VDD_30_31:
- if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
- vmmc = VMMC1_315V;
- else
- vmmc = VMMC2_315V;
- break;
- case MMC_VDD_29_30:
- if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
- vmmc = VMMC1_315V;
- else
- vmmc = VMMC2_300V;
- break;
- case MMC_VDD_27_28:
- case MMC_VDD_26_27:
- if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
- vmmc = VMMC1_285V;
- else
- vmmc = VMMC2_285V;
- break;
- case MMC_VDD_25_26:
- case MMC_VDD_24_25:
- case MMC_VDD_23_24:
- case MMC_VDD_22_23:
- case MMC_VDD_21_22:
- case MMC_VDD_20_21:
- if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
- vmmc = VMMC1_285V;
- else
- vmmc = VMMC2_260V;
- break;
- case MMC_VDD_165_195:
- if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
+ u8 vmmc = 0, dev_grp_val;
+
+ if (!vdd)
+ goto doit;
+
+ if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) {
+ /* VMMC1: max 220 mA. And for 8-bit mode,
+ * VSIM: max 50 mA
+ */
+ switch (1 << vdd) {
+ case MMC_VDD_165_195:
vmmc = VMMC1_185V;
- else
+ /* and VSIM_180V */
+ break;
+ case MMC_VDD_28_29:
+ vmmc = VMMC1_285V;
+ /* and VSIM_280V */
+ break;
+ case MMC_VDD_29_30:
+ case MMC_VDD_30_31:
+ vmmc = VMMC1_300V;
+ /* and VSIM_300V */
+ break;
+ case MMC_VDD_31_32:
+ vmmc = VMMC1_315V;
+ /* error if VSIM needed */
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else if (c->twl_vmmc_dev_grp == VMMC2_DEV_GRP) {
+ /* VMMC2: max 100 mA */
+ switch (1 << vdd) {
+ case MMC_VDD_165_195:
vmmc = VMMC2_185V;
- break;
- default:
- vmmc = 0;
- break;
+ break;
+ case MMC_VDD_25_26:
+ case MMC_VDD_26_27:
+ vmmc = VMMC2_260V;
+ break;
+ case MMC_VDD_27_28:
+ vmmc = VMMC2_280V;
+ break;
+ case MMC_VDD_28_29:
+ vmmc = VMMC2_285V;
+ break;
+ case MMC_VDD_29_30:
+ case MMC_VDD_30_31:
+ vmmc = VMMC2_300V;
+ break;
+ case MMC_VDD_31_32:
+ vmmc = VMMC2_315V;
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ return -EINVAL;
}
- if (vmmc)
+doit:
+ if (vdd)
dev_grp_val = VMMC_DEV_GRP_P1; /* Power up */
else
dev_grp_val = LDO_CLR; /* Power down */
ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
dev_grp_val, c->twl_vmmc_dev_grp);
- if (ret)
+ if (ret || !vdd)
return ret;
ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
@@ -242,6 +271,14 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
struct twl_mmc_controller *c = &hsmmc[0];
struct omap_mmc_platform_data *mmc = dev->platform_data;
+ /*
+ * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
+ * card using the same TWL VMMC1 supply (hsmmc[0]); OMAP has both
+ * 1.8V and 3.0V modes, controlled by the PBIAS register.
+ *
+ * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
+ * is most naturally TWL VSIM; those pins also use PBIAS.
+ */
if (power_on) {
if (cpu_is_omap2430()) {
reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1);
@@ -298,6 +335,12 @@ static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vd
struct twl_mmc_controller *c = &hsmmc[1];
struct omap_mmc_platform_data *mmc = dev->platform_data;
+ /*
+ * Assume TWL VMMC2 (hsmmc[1]) is used only to power the card ... OMAP
+ * VDDS is used to power the pins, optionally with a transceiver to
+ * support cards using voltages other than VDDS (1.8V nominal). When a
+ * transceiver is used, DAT3..7 are muxed as transceiver control pins.
+ */
if (power_on) {
if (mmc->slots[0].internal_clock) {
u32 reg;
@@ -314,6 +357,16 @@ static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vd
return ret;
}
+static int twl_mmc3_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+{
+ /*
+ * Assume MMC3 has self-powered device connected, for example on-board
+ * chip with external power source.
+ */
+ return 0;
+}
+
static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
@@ -349,13 +402,13 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
return;
}
- sprintf(twl->name, "mmc%islot%i", c->mmc, 1);
+ if (c->name)
+ strncpy(twl->name, c->name, HSMMC_NAME_LEN);
+ else
+ snprintf(twl->name, ARRAY_SIZE(twl->name),
+ "mmc%islot%i", c->mmc, 1);
mmc->slots[0].name = twl->name;
mmc->nr_slots = 1;
- mmc->slots[0].ocr_mask = MMC_VDD_165_195 |
- MMC_VDD_26_27 | MMC_VDD_27_28 |
- MMC_VDD_29_30 |
- MMC_VDD_30_31 | MMC_VDD_31_32;
mmc->slots[0].wires = c->wires;
mmc->slots[0].internal_clock = !c->ext_clock;
mmc->dma_mask = 0xffffffff;
@@ -369,7 +422,10 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
mmc->slots[0].switch_pin = c->gpio_cd;
mmc->slots[0].card_detect_irq = gpio_to_irq(c->gpio_cd);
- mmc->slots[0].card_detect = twl_mmc_card_detect;
+ if (c->cover_only)
+ mmc->slots[0].get_cover_state = twl_mmc_get_cover_state;
+ else
+ mmc->slots[0].card_detect = twl_mmc_card_detect;
} else
mmc->slots[0].switch_pin = -EINVAL;
@@ -385,24 +441,43 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
/* NOTE: we assume OMAP's MMC1 and MMC2 use
* the TWL4030's VMMC1 and VMMC2, respectively;
- * and that OMAP's MMC3 isn't used.
+ * and that MMC3 device has it's own power source.
*/
switch (c->mmc) {
case 1:
mmc->slots[0].set_power = twl_mmc1_set_power;
+ mmc->slots[0].ocr_mask = MMC1_OCR;
break;
case 2:
mmc->slots[0].set_power = twl_mmc2_set_power;
+ if (c->transceiver)
+ mmc->slots[0].ocr_mask = MMC2_OCR;
+ else
+ mmc->slots[0].ocr_mask = MMC_VDD_165_195;
+ break;
+ case 3:
+ mmc->slots[0].set_power = twl_mmc3_set_power;
+ mmc->slots[0].ocr_mask = MMC_VDD_165_195;
break;
default:
pr_err("MMC%d configuration not supported!\n", c->mmc);
+ kfree(mmc);
continue;
}
hsmmc_data[c->mmc - 1] = mmc;
}
omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC);
+
+ /* pass the device nodes back to board setup code */
+ for (c = controllers; c->mmc; c++) {
+ struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1];
+
+ if (!c->mmc || c->mmc > nr_hsmmc)
+ continue;
+ c->dev = mmc->dev;
+ }
}
#endif
diff --git a/arch/arm/mach-omap2/mmc-twl4030.h b/arch/arm/mach-omap2/mmc-twl4030.h
index e1c8076400ca..ea59e8624290 100644
--- a/arch/arm/mach-omap2/mmc-twl4030.h
+++ b/arch/arm/mach-omap2/mmc-twl4030.h
@@ -9,9 +9,13 @@
struct twl4030_hsmmc_info {
u8 mmc; /* controller 1/2/3 */
u8 wires; /* 1/4/8 wires */
+ bool transceiver; /* MMC-2 option */
+ bool ext_clock; /* use external pin for input clock */
+ bool cover_only; /* No card detect - just cover switch */
int gpio_cd; /* or -EINVAL */
int gpio_wp; /* or -EINVAL */
- int ext_clock:1; /* use external pin for input clock */
+ char *name; /* or NULL for default */
+ struct device *dev; /* returned: pointer to mmc adapter */
};
#if defined(CONFIG_TWL4030_CORE) && \
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index dacb41f130c0..026c4fc883a7 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -453,10 +453,37 @@ MUX_CFG_34XX("AC1_3430_USB3FS_PHY_MM3_TXEN_N", 0x18a,
/* 34XX GPIO - bidirectional, unless the name has an "_OUT" suffix.
+ * (Always specify PIN_INPUT, except for names suffixed by "_OUT".)
* No internal pullup/pulldown without "_UP" or "_DOWN" suffix.
*/
+MUX_CFG_34XX("AF26_34XX_GPIO0", 0x1e0,
+ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
+MUX_CFG_34XX("AF22_34XX_GPIO9", 0xa18,
+ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
MUX_CFG_34XX("AH8_34XX_GPIO29", 0x5fa,
OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
+MUX_CFG_34XX("U8_34XX_GPIO54_OUT", 0x0b4,
+ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
+MUX_CFG_34XX("U8_34XX_GPIO54_DOWN", 0x0b4,
+ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("L8_34XX_GPIO63", 0x0ce,
+ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
+MUX_CFG_34XX("G25_34XX_GPIO86_OUT", 0x0fc,
+ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
+MUX_CFG_34XX("AG4_34XX_GPIO134_OUT", 0x160,
+ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
+MUX_CFG_34XX("AE4_34XX_GPIO136_OUT", 0x164,
+ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
+MUX_CFG_34XX("AF6_34XX_GPIO140_UP", 0x16c,
+ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AE6_34XX_GPIO141", 0x16e,
+ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
+MUX_CFG_34XX("AF5_34XX_GPIO142", 0x170,
+ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
+MUX_CFG_34XX("AE5_34XX_GPIO143", 0x172,
+ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
+MUX_CFG_34XX("H19_34XX_GPIO164_OUT", 0x19c,
+ OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
MUX_CFG_34XX("J25_34XX_GPIO170", 0x1c6,
OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
};
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 55361c16c9d9..ea8ceaed09cb 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -103,7 +103,7 @@ static struct platform_suspend_ops omap_pm_ops = {
.valid = suspend_valid_only_mem,
};
-int __init omap2_pm_init(void)
+static int __init omap2_pm_init(void)
{
return 0;
}
diff --git a/arch/arm/mach-omap2/powerdomains.h b/arch/arm/mach-omap2/powerdomains.h
index 1e151faebbd3..691470ea4c6a 100644
--- a/arch/arm/mach-omap2/powerdomains.h
+++ b/arch/arm/mach-omap2/powerdomains.h
@@ -171,13 +171,19 @@ static struct powerdomain *powerdomains_omap[] __initdata = {
&iva2_pwrdm,
&mpu_34xx_pwrdm,
&neon_pwrdm,
- &core_34xx_pwrdm,
+ &core_34xx_pre_es3_1_pwrdm,
+ &core_34xx_es3_1_pwrdm,
&cam_pwrdm,
&dss_pwrdm,
&per_pwrdm,
&emu_pwrdm,
&sgx_pwrdm,
&usbhost_pwrdm,
+ &dpll1_pwrdm,
+ &dpll2_pwrdm,
+ &dpll3_pwrdm,
+ &dpll4_pwrdm,
+ &dpll5_pwrdm,
#endif
NULL
diff --git a/arch/arm/mach-omap2/powerdomains34xx.h b/arch/arm/mach-omap2/powerdomains34xx.h
index f573f7108398..4dcf94b800ab 100644
--- a/arch/arm/mach-omap2/powerdomains34xx.h
+++ b/arch/arm/mach-omap2/powerdomains34xx.h
@@ -200,12 +200,33 @@ static struct powerdomain mpu_34xx_pwrdm = {
};
/* No wkdeps or sleepdeps for 34xx core apparently */
-static struct powerdomain core_34xx_pwrdm = {
+static struct powerdomain core_34xx_pre_es3_1_pwrdm = {
.name = "core_pwrdm",
.prcm_offs = CORE_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
+ CHIP_IS_OMAP3430ES2 |
+ CHIP_IS_OMAP3430ES3_0),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .dep_bit = OMAP3430_EN_CORE_SHIFT,
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
+ [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
+ [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
+ },
+};
+
+/* No wkdeps or sleepdeps for 34xx core apparently */
+static struct powerdomain core_34xx_es3_1_pwrdm = {
+ .name = "core_pwrdm",
+ .prcm_offs = CORE_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES3_1),
.pwrsts = PWRSTS_OFF_RET_ON,
.dep_bit = OMAP3430_EN_CORE_SHIFT,
+ .flags = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
.banks = 2,
.pwrsts_mem_ret = {
[0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
@@ -236,14 +257,19 @@ static struct powerdomain dss_pwrdm = {
},
};
+/*
+ * Although the 34XX TRM Rev K Table 4-371 notes that retention is a
+ * possible SGX powerstate, the SGX device itself does not support
+ * retention.
+ */
static struct powerdomain sgx_pwrdm = {
.name = "sgx_pwrdm",
.prcm_offs = OMAP3430ES2_SGX_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
.wkdep_srcs = gfx_sgx_wkdeps,
.sleepdep_srcs = cam_gfx_sleepdeps,
/* XXX This is accurate for 3430 SGX, but what about GFX? */
- .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts = PWRSTS_OFF_ON,
.pwrsts_logic_ret = PWRDM_POWER_RET,
.banks = 1,
.pwrsts_mem_ret = {
@@ -307,11 +333,12 @@ static struct powerdomain neon_pwrdm = {
static struct powerdomain usbhost_pwrdm = {
.name = "usbhost_pwrdm",
.prcm_offs = OMAP3430ES2_USBHOST_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
.wkdep_srcs = per_usbhost_wkdeps,
.sleepdep_srcs = dss_per_usbhost_sleepdeps,
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRDM_POWER_RET,
+ .flags = PWRDM_HAS_HDWR_SAR, /* for USBHOST ctrlr only */
.banks = 1,
.pwrsts_mem_ret = {
[0] = PWRDM_POWER_RET, /* MEMRETSTATE */
@@ -321,6 +348,37 @@ static struct powerdomain usbhost_pwrdm = {
},
};
+static struct powerdomain dpll1_pwrdm = {
+ .name = "dpll1_pwrdm",
+ .prcm_offs = MPU_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain dpll2_pwrdm = {
+ .name = "dpll2_pwrdm",
+ .prcm_offs = OMAP3430_IVA2_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain dpll3_pwrdm = {
+ .name = "dpll3_pwrdm",
+ .prcm_offs = PLL_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain dpll4_pwrdm = {
+ .name = "dpll4_pwrdm",
+ .prcm_offs = PLL_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain dpll5_pwrdm = {
+ .name = "dpll5_pwrdm",
+ .prcm_offs = PLL_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
+};
+
+
#endif /* CONFIG_ARCH_OMAP34XX */
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 4a32822ff3fc..812d50ee495d 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -113,33 +113,58 @@
#define OMAP2430_EN_USBHS (1 << 6)
/* CM_IDLEST1_CORE, PM_WKST1_CORE shared bits */
-#define OMAP2420_ST_MMC (1 << 26)
-#define OMAP24XX_ST_UART2 (1 << 22)
-#define OMAP24XX_ST_UART1 (1 << 21)
-#define OMAP24XX_ST_MCSPI2 (1 << 18)
-#define OMAP24XX_ST_MCSPI1 (1 << 17)
-#define OMAP24XX_ST_GPT12 (1 << 14)
-#define OMAP24XX_ST_GPT11 (1 << 13)
-#define OMAP24XX_ST_GPT10 (1 << 12)
-#define OMAP24XX_ST_GPT9 (1 << 11)
-#define OMAP24XX_ST_GPT8 (1 << 10)
-#define OMAP24XX_ST_GPT7 (1 << 9)
-#define OMAP24XX_ST_GPT6 (1 << 8)
-#define OMAP24XX_ST_GPT5 (1 << 7)
-#define OMAP24XX_ST_GPT4 (1 << 6)
-#define OMAP24XX_ST_GPT3 (1 << 5)
-#define OMAP24XX_ST_GPT2 (1 << 4)
-#define OMAP2420_ST_VLYNQ (1 << 3)
+#define OMAP2420_ST_MMC_SHIFT 26
+#define OMAP2420_ST_MMC_MASK (1 << 26)
+#define OMAP24XX_ST_UART2_SHIFT 22
+#define OMAP24XX_ST_UART2_MASK (1 << 22)
+#define OMAP24XX_ST_UART1_SHIFT 21
+#define OMAP24XX_ST_UART1_MASK (1 << 21)
+#define OMAP24XX_ST_MCSPI2_SHIFT 18
+#define OMAP24XX_ST_MCSPI2_MASK (1 << 18)
+#define OMAP24XX_ST_MCSPI1_SHIFT 17
+#define OMAP24XX_ST_MCSPI1_MASK (1 << 17)
+#define OMAP24XX_ST_GPT12_SHIFT 14
+#define OMAP24XX_ST_GPT12_MASK (1 << 14)
+#define OMAP24XX_ST_GPT11_SHIFT 13
+#define OMAP24XX_ST_GPT11_MASK (1 << 13)
+#define OMAP24XX_ST_GPT10_SHIFT 12
+#define OMAP24XX_ST_GPT10_MASK (1 << 12)
+#define OMAP24XX_ST_GPT9_SHIFT 11
+#define OMAP24XX_ST_GPT9_MASK (1 << 11)
+#define OMAP24XX_ST_GPT8_SHIFT 10
+#define OMAP24XX_ST_GPT8_MASK (1 << 10)
+#define OMAP24XX_ST_GPT7_SHIFT 9
+#define OMAP24XX_ST_GPT7_MASK (1 << 9)
+#define OMAP24XX_ST_GPT6_SHIFT 8
+#define OMAP24XX_ST_GPT6_MASK (1 << 8)
+#define OMAP24XX_ST_GPT5_SHIFT 7
+#define OMAP24XX_ST_GPT5_MASK (1 << 7)
+#define OMAP24XX_ST_GPT4_SHIFT 6
+#define OMAP24XX_ST_GPT4_MASK (1 << 6)
+#define OMAP24XX_ST_GPT3_SHIFT 5
+#define OMAP24XX_ST_GPT3_MASK (1 << 5)
+#define OMAP24XX_ST_GPT2_SHIFT 4
+#define OMAP24XX_ST_GPT2_MASK (1 << 4)
+#define OMAP2420_ST_VLYNQ_SHIFT 3
+#define OMAP2420_ST_VLYNQ_MASK (1 << 3)
/* CM_IDLEST2_CORE, PM_WKST2_CORE shared bits */
-#define OMAP2430_ST_MDM_INTC (1 << 11)
-#define OMAP2430_ST_GPIO5 (1 << 10)
-#define OMAP2430_ST_MCSPI3 (1 << 9)
-#define OMAP2430_ST_MMCHS2 (1 << 8)
-#define OMAP2430_ST_MMCHS1 (1 << 7)
-#define OMAP2430_ST_USBHS (1 << 6)
-#define OMAP24XX_ST_UART3 (1 << 2)
-#define OMAP24XX_ST_USB (1 << 0)
+#define OMAP2430_ST_MDM_INTC_SHIFT 11
+#define OMAP2430_ST_MDM_INTC_MASK (1 << 11)
+#define OMAP2430_ST_GPIO5_SHIFT 10
+#define OMAP2430_ST_GPIO5_MASK (1 << 10)
+#define OMAP2430_ST_MCSPI3_SHIFT 9
+#define OMAP2430_ST_MCSPI3_MASK (1 << 9)
+#define OMAP2430_ST_MMCHS2_SHIFT 8
+#define OMAP2430_ST_MMCHS2_MASK (1 << 8)
+#define OMAP2430_ST_MMCHS1_SHIFT 7
+#define OMAP2430_ST_MMCHS1_MASK (1 << 7)
+#define OMAP2430_ST_USBHS_SHIFT 6
+#define OMAP2430_ST_USBHS_MASK (1 << 6)
+#define OMAP24XX_ST_UART3_SHIFT 2
+#define OMAP24XX_ST_UART3_MASK (1 << 2)
+#define OMAP24XX_ST_USB_SHIFT 0
+#define OMAP24XX_ST_USB_MASK (1 << 0)
/* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */
#define OMAP24XX_EN_GPIOS_SHIFT 2
@@ -148,11 +173,13 @@
#define OMAP24XX_EN_GPT1 (1 << 0)
/* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */
-#define OMAP24XX_ST_GPIOS (1 << 2)
-#define OMAP24XX_ST_GPT1 (1 << 0)
+#define OMAP24XX_ST_GPIOS_SHIFT (1 << 2)
+#define OMAP24XX_ST_GPIOS_MASK 2
+#define OMAP24XX_ST_GPT1_SHIFT (1 << 0)
+#define OMAP24XX_ST_GPT1_MASK 0
/* CM_IDLEST_MDM and PM_WKST_MDM shared bits */
-#define OMAP2430_ST_MDM (1 << 0)
+#define OMAP2430_ST_MDM_SHIFT (1 << 0)
/* 3430 register bits shared between CM & PRM registers */
@@ -205,24 +232,46 @@
#define OMAP3430_EN_HSOTGUSB_SHIFT 4
/* PM_WKST1_CORE, CM_IDLEST1_CORE shared bits */
-#define OMAP3430_ST_MMC2 (1 << 25)
-#define OMAP3430_ST_MMC1 (1 << 24)
-#define OMAP3430_ST_MCSPI4 (1 << 21)
-#define OMAP3430_ST_MCSPI3 (1 << 20)
-#define OMAP3430_ST_MCSPI2 (1 << 19)
-#define OMAP3430_ST_MCSPI1 (1 << 18)
-#define OMAP3430_ST_I2C3 (1 << 17)
-#define OMAP3430_ST_I2C2 (1 << 16)
-#define OMAP3430_ST_I2C1 (1 << 15)
-#define OMAP3430_ST_UART2 (1 << 14)
-#define OMAP3430_ST_UART1 (1 << 13)
-#define OMAP3430_ST_GPT11 (1 << 12)
-#define OMAP3430_ST_GPT10 (1 << 11)
-#define OMAP3430_ST_MCBSP5 (1 << 10)
-#define OMAP3430_ST_MCBSP1 (1 << 9)
-#define OMAP3430_ST_FSHOSTUSB (1 << 5)
-#define OMAP3430_ST_HSOTGUSB (1 << 4)
-#define OMAP3430_ST_D2D (1 << 3)
+#define OMAP3430_ST_MMC2_SHIFT 25
+#define OMAP3430_ST_MMC2_MASK (1 << 25)
+#define OMAP3430_ST_MMC1_SHIFT 24
+#define OMAP3430_ST_MMC1_MASK (1 << 24)
+#define OMAP3430_ST_MCSPI4_SHIFT 21
+#define OMAP3430_ST_MCSPI4_MASK (1 << 21)
+#define OMAP3430_ST_MCSPI3_SHIFT 20
+#define OMAP3430_ST_MCSPI3_MASK (1 << 20)
+#define OMAP3430_ST_MCSPI2_SHIFT 19
+#define OMAP3430_ST_MCSPI2_MASK (1 << 19)
+#define OMAP3430_ST_MCSPI1_SHIFT 18
+#define OMAP3430_ST_MCSPI1_MASK (1 << 18)
+#define OMAP3430_ST_I2C3_SHIFT 17
+#define OMAP3430_ST_I2C3_MASK (1 << 17)
+#define OMAP3430_ST_I2C2_SHIFT 16
+#define OMAP3430_ST_I2C2_MASK (1 << 16)
+#define OMAP3430_ST_I2C1_SHIFT 15
+#define OMAP3430_ST_I2C1_MASK (1 << 15)
+#define OMAP3430_ST_UART2_SHIFT 14
+#define OMAP3430_ST_UART2_MASK (1 << 14)
+#define OMAP3430_ST_UART1_SHIFT 13
+#define OMAP3430_ST_UART1_MASK (1 << 13)
+#define OMAP3430_ST_GPT11_SHIFT 12
+#define OMAP3430_ST_GPT11_MASK (1 << 12)
+#define OMAP3430_ST_GPT10_SHIFT 11
+#define OMAP3430_ST_GPT10_MASK (1 << 11)
+#define OMAP3430_ST_MCBSP5_SHIFT 10
+#define OMAP3430_ST_MCBSP5_MASK (1 << 10)
+#define OMAP3430_ST_MCBSP1_SHIFT 9
+#define OMAP3430_ST_MCBSP1_MASK (1 << 9)
+#define OMAP3430ES1_ST_FSHOSTUSB_SHIFT 5
+#define OMAP3430ES1_ST_FSHOSTUSB_MASK (1 << 5)
+#define OMAP3430ES1_ST_HSOTGUSB_SHIFT 4
+#define OMAP3430ES1_ST_HSOTGUSB_MASK (1 << 4)
+#define OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT 5
+#define OMAP3430ES2_ST_HSOTGUSB_IDLE_MASK (1 << 5)
+#define OMAP3430ES2_ST_HSOTGUSB_STDBY_SHIFT 4
+#define OMAP3430ES2_ST_HSOTGUSB_STDBY_MASK (1 << 4)
+#define OMAP3430_ST_D2D_SHIFT 3
+#define OMAP3430_ST_D2D_MASK (1 << 3)
/* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */
#define OMAP3430_EN_GPIO1 (1 << 3)
@@ -241,11 +290,16 @@
#define OMAP3430_EN_GPT12_SHIFT 1
/* CM_IDLEST_WKUP, PM_WKST_WKUP shared bits */
-#define OMAP3430_ST_SR2 (1 << 7)
-#define OMAP3430_ST_SR1 (1 << 6)
-#define OMAP3430_ST_GPIO1 (1 << 3)
-#define OMAP3430_ST_GPT12 (1 << 1)
-#define OMAP3430_ST_GPT1 (1 << 0)
+#define OMAP3430_ST_SR2_SHIFT 7
+#define OMAP3430_ST_SR2_MASK (1 << 7)
+#define OMAP3430_ST_SR1_SHIFT 6
+#define OMAP3430_ST_SR1_MASK (1 << 6)
+#define OMAP3430_ST_GPIO1_SHIFT 3
+#define OMAP3430_ST_GPIO1_MASK (1 << 3)
+#define OMAP3430_ST_GPT12_SHIFT 1
+#define OMAP3430_ST_GPT12_MASK (1 << 1)
+#define OMAP3430_ST_GPT1_SHIFT 0
+#define OMAP3430_ST_GPT1_MASK (1 << 0)
/*
* CM_SLEEPDEP_GFX, CM_SLEEPDEP_DSS, CM_SLEEPDEP_CAM,
@@ -296,20 +350,34 @@
#define OMAP3430_EN_MCBSP2_SHIFT 0
/* CM_IDLEST_PER, PM_WKST_PER shared bits */
-#define OMAP3430_ST_GPIO6 (1 << 17)
-#define OMAP3430_ST_GPIO5 (1 << 16)
-#define OMAP3430_ST_GPIO4 (1 << 15)
-#define OMAP3430_ST_GPIO3 (1 << 14)
-#define OMAP3430_ST_GPIO2 (1 << 13)
-#define OMAP3430_ST_UART3 (1 << 11)
-#define OMAP3430_ST_GPT9 (1 << 10)
-#define OMAP3430_ST_GPT8 (1 << 9)
-#define OMAP3430_ST_GPT7 (1 << 8)
-#define OMAP3430_ST_GPT6 (1 << 7)
-#define OMAP3430_ST_GPT5 (1 << 6)
-#define OMAP3430_ST_GPT4 (1 << 5)
-#define OMAP3430_ST_GPT3 (1 << 4)
-#define OMAP3430_ST_GPT2 (1 << 3)
+#define OMAP3430_ST_GPIO6_SHIFT 17
+#define OMAP3430_ST_GPIO6_MASK (1 << 17)
+#define OMAP3430_ST_GPIO5_SHIFT 16
+#define OMAP3430_ST_GPIO5_MASK (1 << 16)
+#define OMAP3430_ST_GPIO4_SHIFT 15
+#define OMAP3430_ST_GPIO4_MASK (1 << 15)
+#define OMAP3430_ST_GPIO3_SHIFT 14
+#define OMAP3430_ST_GPIO3_MASK (1 << 14)
+#define OMAP3430_ST_GPIO2_SHIFT 13
+#define OMAP3430_ST_GPIO2_MASK (1 << 13)
+#define OMAP3430_ST_UART3_SHIFT 11
+#define OMAP3430_ST_UART3_MASK (1 << 11)
+#define OMAP3430_ST_GPT9_SHIFT 10
+#define OMAP3430_ST_GPT9_MASK (1 << 10)
+#define OMAP3430_ST_GPT8_SHIFT 9
+#define OMAP3430_ST_GPT8_MASK (1 << 9)
+#define OMAP3430_ST_GPT7_SHIFT 8
+#define OMAP3430_ST_GPT7_MASK (1 << 8)
+#define OMAP3430_ST_GPT6_SHIFT 7
+#define OMAP3430_ST_GPT6_MASK (1 << 7)
+#define OMAP3430_ST_GPT5_SHIFT 6
+#define OMAP3430_ST_GPT5_MASK (1 << 6)
+#define OMAP3430_ST_GPT4_SHIFT 5
+#define OMAP3430_ST_GPT4_MASK (1 << 5)
+#define OMAP3430_ST_GPT3_SHIFT 4
+#define OMAP3430_ST_GPT3_MASK (1 << 4)
+#define OMAP3430_ST_GPT2_SHIFT 3
+#define OMAP3430_ST_GPT2_MASK (1 << 3)
/* CM_SLEEPDEP_PER, PM_WKDEP_IVA2, PM_WKDEP_MPU, PM_WKDEP_PER shared bits */
#define OMAP3430_EN_CORE_SHIFT 0
diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
index 5b5ecfe6c999..c6a7940f4287 100644
--- a/arch/arm/mach-omap2/prm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
@@ -366,6 +366,7 @@
/* PM_WKEN_WKUP specific bits */
#define OMAP3430_EN_IO (1 << 8)
+#define OMAP3430_EN_GPIO1 (1 << 3)
/* PM_MPUGRPSEL_WKUP specific bits */
@@ -452,6 +453,14 @@
#define OMAP3430_CMDRA0_MASK (0xff << 0)
/* PRM_VC_CMD_VAL_0 specific bits */
+#define OMAP3430_VC_CMD_ON_SHIFT 24
+#define OMAP3430_VC_CMD_ON_MASK (0xFF << 24)
+#define OMAP3430_VC_CMD_ONLP_SHIFT 16
+#define OMAP3430_VC_CMD_ONLP_MASK (0xFF << 16)
+#define OMAP3430_VC_CMD_RET_SHIFT 8
+#define OMAP3430_VC_CMD_RET_MASK (0xFF << 8)
+#define OMAP3430_VC_CMD_OFF_SHIFT 0
+#define OMAP3430_VC_CMD_OFF_MASK (0xFF << 0)
/* PRM_VC_CMD_VAL_1 specific bits */
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index e4dc4b17881d..826d326b8062 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -141,6 +141,19 @@
#define PM_PWSTCTRL 0x00e0
#define PM_PWSTST 0x00e4
+/* Omap2 specific registers */
+#define OMAP24XX_PM_WKEN2 0x00a4
+#define OMAP24XX_PM_WKST2 0x00b4
+
+#define OMAP24XX_PRCM_IRQSTATUS_DSP 0x00f0 /* IVA mod */
+#define OMAP24XX_PRCM_IRQENABLE_DSP 0x00f4 /* IVA mod */
+#define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8
+#define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc
+
+/* Omap3 specific registers */
+#define OMAP3430ES2_PM_WKEN3 0x00f0
+#define OMAP3430ES2_PM_WKST3 0x00b8
+
#define OMAP3430_PM_MPUGRPSEL 0x00a4
#define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL
@@ -153,16 +166,6 @@
#define OMAP3430_PRM_IRQENABLE_IVA2 0x00fc
-/* Architecture-specific registers */
-
-#define OMAP24XX_PM_WKEN2 0x00a4
-#define OMAP24XX_PM_WKST2 0x00b4
-
-#define OMAP24XX_PRCM_IRQSTATUS_DSP 0x00f0 /* IVA mod */
-#define OMAP24XX_PRCM_IRQENABLE_DSP 0x00f4 /* IVA mod */
-#define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8
-#define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc
-
#ifndef __ASSEMBLER__
/* Power/reset management domain register get/set */
@@ -228,7 +231,6 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
#define OMAP_RSTTIME1_SHIFT 0
#define OMAP_RSTTIME1_MASK (0xff << 0)
-
/* PRM_RSTCTRL */
/* Named RM_RSTCTRL_WKUP on the 24xx */
/* 2420 calls RST_DPLL3 'RST_DPLL' */
diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c
new file mode 100644
index 000000000000..2a30060cb4b7
--- /dev/null
+++ b/arch/arm/mach-omap2/sdrc.c
@@ -0,0 +1,93 @@
+/*
+ * SMS/SDRC (SDRAM controller) common code for OMAP2/3
+ *
+ * Copyright (C) 2005, 2008 Texas Instruments Inc.
+ * Copyright (C) 2005, 2008 Nokia Corporation
+ *
+ * Tony Lindgren <tony@atomide.com>
+ * Paul Walmsley
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/common.h>
+#include <mach/clock.h>
+#include <mach/sram.h>
+
+#include "prm.h"
+
+#include <mach/sdrc.h>
+#include "sdrc.h"
+
+static struct omap_sdrc_params *sdrc_init_params;
+
+void __iomem *omap2_sdrc_base;
+void __iomem *omap2_sms_base;
+
+
+/**
+ * omap2_sdrc_get_params - return SDRC register values for a given clock rate
+ * @r: SDRC clock rate (in Hz)
+ *
+ * Return pre-calculated values for the SDRC_ACTIM_CTRLA,
+ * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL, and SDRC_MR registers, for a given
+ * SDRC clock rate 'r'. These parameters control various timing
+ * delays in the SDRAM controller that are expressed in terms of the
+ * number of SDRC clock cycles to wait; hence the clock rate
+ * dependency. Note that sdrc_init_params must be sorted rate
+ * descending. Also assumes that both chip-selects use the same
+ * timing parameters. Returns a struct omap_sdrc_params * upon
+ * success, or NULL upon failure.
+ */
+struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r)
+{
+ struct omap_sdrc_params *sp;
+
+ sp = sdrc_init_params;
+
+ while (sp->rate != r)
+ sp++;
+
+ if (!sp->rate)
+ return NULL;
+
+ return sp;
+}
+
+
+void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals)
+{
+ omap2_sdrc_base = omap2_globals->sdrc;
+ omap2_sms_base = omap2_globals->sms;
+}
+
+/* turn on smart idle modes for SDRAM scheduler and controller */
+void __init omap2_sdrc_init(struct omap_sdrc_params *sp)
+{
+ u32 l;
+
+ l = sms_read_reg(SMS_SYSCONFIG);
+ l &= ~(0x3 << 3);
+ l |= (0x2 << 3);
+ sms_write_reg(l, SMS_SYSCONFIG);
+
+ l = sdrc_read_reg(SDRC_SYSCONFIG);
+ l &= ~(0x3 << 3);
+ l |= (0x2 << 3);
+ sdrc_write_reg(l, SDRC_SYSCONFIG);
+
+ sdrc_init_params = sp;
+}
diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/sdrc2xxx.c
index 882c70224292..0afdad5ae9fb 100644
--- a/arch/arm/mach-omap2/memory.c
+++ b/arch/arm/mach-omap2/sdrc2xxx.c
@@ -1,13 +1,14 @@
/*
- * linux/arch/arm/mach-omap2/memory.c
+ * linux/arch/arm/mach-omap2/sdrc2xxx.c
*
- * Memory timing related functions for OMAP24XX
+ * SDRAM timing related functions for OMAP2xxx
*
- * Copyright (C) 2005 Texas Instruments Inc.
- * Richard Woodruff <r-woodruff2@ti.com>
+ * Copyright (C) 2005, 2008 Texas Instruments Inc.
+ * Copyright (C) 2005, 2008 Nokia Corporation
*
- * Copyright (C) 2005 Nokia Corporation
* Tony Lindgren <tony@atomide.com>
+ * Paul Walmsley
+ * Richard Woodruff <r-woodruff2@ti.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -28,27 +29,31 @@
#include <mach/sram.h>
#include "prm.h"
-
-#include "memory.h"
+#include "clock.h"
+#include <mach/sdrc.h>
#include "sdrc.h"
-void __iomem *omap2_sdrc_base;
-void __iomem *omap2_sms_base;
+/* Memory timing, DLL mode flags */
+#define M_DDR 1
+#define M_LOCK_CTRL (1 << 2)
+#define M_UNLOCK 0
+#define M_LOCK 1
+
static struct memory_timings mem_timings;
static u32 curr_perf_level = CORE_CLK_SRC_DPLL_X2;
-u32 omap2_memory_get_slow_dll_ctrl(void)
+static u32 omap2xxx_sdrc_get_slow_dll_ctrl(void)
{
return mem_timings.slow_dll_ctrl;
}
-u32 omap2_memory_get_fast_dll_ctrl(void)
+static u32 omap2xxx_sdrc_get_fast_dll_ctrl(void)
{
return mem_timings.fast_dll_ctrl;
}
-u32 omap2_memory_get_type(void)
+static u32 omap2xxx_sdrc_get_type(void)
{
return mem_timings.m_type;
}
@@ -57,7 +62,7 @@ u32 omap2_memory_get_type(void)
* Check the DLL lock state, and return tue if running in unlock mode.
* This is needed to compensate for the shifted DLL value in unlock mode.
*/
-u32 omap2_dll_force_needed(void)
+u32 omap2xxx_sdrc_dll_is_unlocked(void)
{
/* dlla and dllb are a set */
u32 dll_state = sdrc_read_reg(SDRC_DLLA_CTRL);
@@ -72,8 +77,10 @@ u32 omap2_dll_force_needed(void)
* 'level' is the value to store to CM_CLKSEL2_PLL.CORE_CLK_SRC.
* Practical values are CORE_CLK_SRC_DPLL (for CORE_CLK = DPLL_CLK) or
* CORE_CLK_SRC_DPLL_X2 (for CORE_CLK = * DPLL_CLK * 2)
+ *
+ * Used by the clock framework during CORE DPLL changes
*/
-u32 omap2_reprogram_sdrc(u32 level, u32 force)
+u32 omap2xxx_sdrc_reprogram(u32 level, u32 force)
{
u32 dll_ctrl, m_type;
u32 prev = curr_perf_level;
@@ -82,15 +89,14 @@ u32 omap2_reprogram_sdrc(u32 level, u32 force)
if ((curr_perf_level == level) && !force)
return prev;
- if (level == CORE_CLK_SRC_DPLL) {
- dll_ctrl = omap2_memory_get_slow_dll_ctrl();
- } else if (level == CORE_CLK_SRC_DPLL_X2) {
- dll_ctrl = omap2_memory_get_fast_dll_ctrl();
- } else {
+ if (level == CORE_CLK_SRC_DPLL)
+ dll_ctrl = omap2xxx_sdrc_get_slow_dll_ctrl();
+ else if (level == CORE_CLK_SRC_DPLL_X2)
+ dll_ctrl = omap2xxx_sdrc_get_fast_dll_ctrl();
+ else
return prev;
- }
- m_type = omap2_memory_get_type();
+ m_type = omap2xxx_sdrc_get_type();
local_irq_save(flags);
__raw_writel(0xffff, OMAP24XX_PRCM_VOLTSETUP);
@@ -101,23 +107,14 @@ u32 omap2_reprogram_sdrc(u32 level, u32 force)
return prev;
}
-#if !defined(CONFIG_ARCH_OMAP2)
-void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
- u32 base_cs, u32 force_unlock)
-{
-}
-void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
- u32 mem_type)
-{
-}
-#endif
-
-void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
+/* Used by the clock framework during CORE DPLL changes */
+void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode)
{
unsigned long dll_cnt;
u32 fast_dll = 0;
- mem_timings.m_type = !((sdrc_read_reg(SDRC_MR_0) & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
+ /* DDR = 1, SDR = 0 */
+ mem_timings.m_type = !((sdrc_read_reg(SDRC_MR_0) & 0x3) == 0x1);
/* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
* In the case of 2422, its ok to use CS1 instead of CS0.
@@ -164,28 +161,3 @@ void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
/* 90 degree phase for anything below 133Mhz + disable DLL filter */
mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
}
-
-void __init omap2_set_globals_memory(struct omap_globals *omap2_globals)
-{
- omap2_sdrc_base = omap2_globals->sdrc;
- omap2_sms_base = omap2_globals->sms;
-}
-
-/* turn on smart idle modes for SDRAM scheduler and controller */
-void __init omap2_init_memory(void)
-{
- u32 l;
-
- if (!cpu_is_omap2420())
- return;
-
- l = sms_read_reg(SMS_SYSCONFIG);
- l &= ~(0x3 << 3);
- l |= (0x2 << 3);
- sms_write_reg(l, SMS_SYSCONFIG);
-
- l = sdrc_read_reg(SDRC_SYSCONFIG);
- l &= ~(0x3 << 3);
- l |= (0x2 << 3);
- sdrc_write_reg(l, SDRC_SYSCONFIG);
-}
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
new file mode 100644
index 000000000000..fc74e913c415
--- /dev/null
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -0,0 +1,187 @@
+/*
+ * linux/arch/arm/mach-omap2/usb-musb.c
+ *
+ * This file will contain the board specific details for the
+ * MENTOR USB OTG controller on OMAP3430
+ *
+ * Copyright (C) 2007-2008 Texas Instruments
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Vikram Pandita
+ *
+ * Generalization by:
+ * Felipe Balbi <felipe.balbi@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+
+#include <linux/usb/musb.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/pm.h>
+#include <mach/mux.h>
+#include <mach/usb.h>
+
+static struct resource musb_resources[] = {
+ [0] = { /* start and end set dynamically */
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* general IRQ */
+ .start = INT_243X_HS_USB_MC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = { /* DMA IRQ */
+ .start = INT_243X_HS_USB_DMA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static int clk_on;
+
+static int musb_set_clock(struct clk *clk, int state)
+{
+ if (state) {
+ if (clk_on > 0)
+ return -ENODEV;
+
+ clk_enable(clk);
+ clk_on = 1;
+ } else {
+ if (clk_on == 0)
+ return -ENODEV;
+
+ clk_disable(clk);
+ clk_on = 0;
+ }
+
+ return 0;
+}
+
+static struct musb_hdrc_eps_bits musb_eps[] = {
+ { "ep1_tx", 10, },
+ { "ep1_rx", 10, },
+ { "ep2_tx", 9, },
+ { "ep2_rx", 9, },
+ { "ep3_tx", 3, },
+ { "ep3_rx", 3, },
+ { "ep4_tx", 3, },
+ { "ep4_rx", 3, },
+ { "ep5_tx", 3, },
+ { "ep5_rx", 3, },
+ { "ep6_tx", 3, },
+ { "ep6_rx", 3, },
+ { "ep7_tx", 3, },
+ { "ep7_rx", 3, },
+ { "ep8_tx", 2, },
+ { "ep8_rx", 2, },
+ { "ep9_tx", 2, },
+ { "ep9_rx", 2, },
+ { "ep10_tx", 2, },
+ { "ep10_rx", 2, },
+ { "ep11_tx", 2, },
+ { "ep11_rx", 2, },
+ { "ep12_tx", 2, },
+ { "ep12_rx", 2, },
+ { "ep13_tx", 2, },
+ { "ep13_rx", 2, },
+ { "ep14_tx", 2, },
+ { "ep14_rx", 2, },
+ { "ep15_tx", 2, },
+ { "ep15_rx", 2, },
+};
+
+static struct musb_hdrc_config musb_config = {
+ .multipoint = 1,
+ .dyn_fifo = 1,
+ .soft_con = 1,
+ .dma = 1,
+ .num_eps = 16,
+ .dma_channels = 7,
+ .dma_req_chan = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3),
+ .ram_bits = 12,
+ .eps_bits = musb_eps,
+};
+
+static struct musb_hdrc_platform_data musb_plat = {
+#ifdef CONFIG_USB_MUSB_OTG
+ .mode = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
+ .mode = MUSB_HOST,
+#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
+ .mode = MUSB_PERIPHERAL,
+#endif
+ /* .clock is set dynamically */
+ .set_clock = musb_set_clock,
+ .config = &musb_config,
+
+ /* REVISIT charge pump on TWL4030 can supply up to
+ * 100 mA ... but this value is board-specific, like
+ * "mode", and should be passed to usb_musb_init().
+ */
+ .power = 50, /* up to 100 mA */
+};
+
+static u64 musb_dmamask = DMA_32BIT_MASK;
+
+static struct platform_device musb_device = {
+ .name = "musb_hdrc",
+ .id = -1,
+ .dev = {
+ .dma_mask = &musb_dmamask,
+ .coherent_dma_mask = DMA_32BIT_MASK,
+ .platform_data = &musb_plat,
+ },
+ .num_resources = ARRAY_SIZE(musb_resources),
+ .resource = musb_resources,
+};
+
+#ifdef CONFIG_NOP_USB_XCEIV
+static u64 nop_xceiv_dmamask = DMA_32BIT_MASK;
+
+static struct platform_device nop_xceiv_device = {
+ .name = "nop_usb_xceiv",
+ .id = -1,
+ .dev = {
+ .dma_mask = &nop_xceiv_dmamask,
+ .coherent_dma_mask = DMA_32BIT_MASK,
+ .platform_data = NULL,
+ },
+};
+#endif
+
+void __init usb_musb_init(void)
+{
+ if (cpu_is_omap243x())
+ musb_resources[0].start = OMAP243X_HS_BASE;
+ else
+ musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;
+ musb_resources[0].end = musb_resources[0].start + SZ_8K - 1;
+
+ /*
+ * REVISIT: This line can be removed once all the platforms using
+ * musb_core.c have been converted to use use clkdev.
+ */
+ musb_plat.clock = "ick";
+
+#ifdef CONFIG_NOP_USB_XCEIV
+ if (platform_device_register(&nop_xceiv_device) < 0) {
+ printk(KERN_ERR "Unable to register NOP-XCEIV device\n");
+ return;
+ }
+#endif
+
+ if (platform_device_register(&musb_device) < 0) {
+ printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n");
+ return;
+ }
+}
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index f59a8d0e0824..2c7035d8dcbf 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -71,6 +71,7 @@ config MACH_WRT350N_V2
config MACH_TS78XX
bool "Technologic Systems TS-78xx"
+ select PM
help
Say 'Y' here if you want your kernel to support the
Technologic Systems TS-78xx platform.
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 8a0e49d84256..68cc3efae567 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -31,6 +31,7 @@
#include <plat/ehci-orion.h>
#include <plat/mv_xor.h>
#include <plat/orion_nand.h>
+#include <plat/orion5x_wdt.h>
#include <plat/time.h>
#include "common.h"
@@ -219,14 +220,17 @@ static struct platform_device orion5x_switch_device = {
void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq)
{
+ int i;
+
if (irq != NO_IRQ) {
orion5x_switch_resources[0].start = irq;
orion5x_switch_resources[0].end = irq;
orion5x_switch_device.num_resources = 1;
}
- d->mii_bus = &orion5x_eth_shared.dev;
d->netdev = &orion5x_eth.dev;
+ for (i = 0; i < d->nr_chips; i++)
+ d->chip[i].mii_bus = &orion5x_eth_shared.dev;
orion5x_switch_device.dev.platform_data = d;
platform_device_register(&orion5x_switch_device);
@@ -533,6 +537,29 @@ void __init orion5x_xor_init(void)
/*****************************************************************************
+ * Watchdog
+ ****************************************************************************/
+static struct orion5x_wdt_platform_data orion5x_wdt_data = {
+ .tclk = 0,
+};
+
+static struct platform_device orion5x_wdt_device = {
+ .name = "orion5x_wdt",
+ .id = -1,
+ .dev = {
+ .platform_data = &orion5x_wdt_data,
+ },
+ .num_resources = 0,
+};
+
+void __init orion5x_wdt_init(void)
+{
+ orion5x_wdt_data.tclk = orion5x_tclk;
+ platform_device_register(&orion5x_wdt_device);
+}
+
+
+/*****************************************************************************
* Time handling
****************************************************************************/
int orion5x_tclk;
@@ -631,6 +658,11 @@ void __init orion5x_init(void)
printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
disable_hlt();
}
+
+ /*
+ * Register watchdog driver
+ */
+ orion5x_wdt_init();
}
/*
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
index 0722d6510df1..b31ca4cef365 100644
--- a/arch/arm/mach-orion5x/dns323-setup.c
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -76,7 +76,7 @@ static int __init dns323_dev_id(void)
static int __init dns323_pci_init(void)
{
- /* The 5182 doesn't really use it's PCI bus, and initialising PCI
+ /* The 5182 doesn't really use its PCI bus, and initialising PCI
* gets in the way of initialising the SATA controller.
*/
if (machine_is_dns323() && dns323_dev_id() != MV88F5182_DEV_ID)
@@ -418,7 +418,7 @@ static void __init dns323_init(void)
orion5x_i2c_init();
orion5x_uart0_init();
- /* The 5182 has it's SATA controller on-chip, and needs it's own little
+ /* The 5182 has its SATA controller on-chip, and needs its own little
* init routine.
*/
if (dns323_dev_id() == MV88F5182_DEV_ID)
diff --git a/arch/arm/mach-orion5x/include/mach/system.h b/arch/arm/mach-orion5x/include/mach/system.h
index 08e430757890..9b8db1dcfa83 100644
--- a/arch/arm/mach-orion5x/include/mach/system.h
+++ b/arch/arm/mach-orion5x/include/mach/system.h
@@ -19,7 +19,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
/*
* Enable and issue soft reset
diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c
index e0c43b8beb72..c9bf6b81a80d 100644
--- a/arch/arm/mach-orion5x/lsmini-setup.c
+++ b/arch/arm/mach-orion5x/lsmini-setup.c
@@ -186,7 +186,7 @@ static struct mv_sata_platform_data lsmini_sata_data = {
static void lsmini_power_off(void)
{
- arch_reset(0);
+ arch_reset(0, NULL);
}
diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
index 15f53235ee30..9c1ca41730ba 100644
--- a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
@@ -94,7 +94,7 @@ static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = {
.duplex = DUPLEX_FULL,
};
-static struct dsa_platform_data rd88f5181l_fxo_switch_data = {
+static struct dsa_chip_data rd88f5181l_fxo_switch_chip_data = {
.port_names[0] = "lan2",
.port_names[1] = "lan1",
.port_names[2] = "wan",
@@ -103,6 +103,11 @@ static struct dsa_platform_data rd88f5181l_fxo_switch_data = {
.port_names[7] = "lan3",
};
+static struct dsa_platform_data rd88f5181l_fxo_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &rd88f5181l_fxo_switch_chip_data,
+};
+
static void __init rd88f5181l_fxo_init(void)
{
/*
@@ -117,7 +122,7 @@ static void __init rd88f5181l_fxo_init(void)
*/
orion5x_ehci0_init();
orion5x_eth_init(&rd88f5181l_fxo_eth_data);
- orion5x_eth_switch_init(&rd88f5181l_fxo_switch_data, NO_IRQ);
+ orion5x_eth_switch_init(&rd88f5181l_fxo_switch_plat_data, NO_IRQ);
orion5x_uart0_init();
orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE,
diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
index 8ad3934399d4..ee1399ff0ced 100644
--- a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
@@ -95,7 +95,7 @@ static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = {
.duplex = DUPLEX_FULL,
};
-static struct dsa_platform_data rd88f5181l_ge_switch_data = {
+static struct dsa_chip_data rd88f5181l_ge_switch_chip_data = {
.port_names[0] = "lan2",
.port_names[1] = "lan1",
.port_names[2] = "wan",
@@ -104,6 +104,11 @@ static struct dsa_platform_data rd88f5181l_ge_switch_data = {
.port_names[7] = "lan3",
};
+static struct dsa_platform_data rd88f5181l_ge_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &rd88f5181l_ge_switch_chip_data,
+};
+
static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {
I2C_BOARD_INFO("ds1338", 0x68),
};
@@ -122,7 +127,8 @@ static void __init rd88f5181l_ge_init(void)
*/
orion5x_ehci0_init();
orion5x_eth_init(&rd88f5181l_ge_eth_data);
- orion5x_eth_switch_init(&rd88f5181l_ge_switch_data, gpio_to_irq(8));
+ orion5x_eth_switch_init(&rd88f5181l_ge_switch_plat_data,
+ gpio_to_irq(8));
orion5x_i2c_init();
orion5x_uart0_init();
diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
index 262e25e4dace..7737cf9a8f50 100644
--- a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
+++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
@@ -35,7 +35,7 @@ static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = {
.duplex = DUPLEX_FULL,
};
-static struct dsa_platform_data rd88f6183ap_ge_switch_data = {
+static struct dsa_chip_data rd88f6183ap_ge_switch_chip_data = {
.port_names[0] = "lan1",
.port_names[1] = "lan2",
.port_names[2] = "lan3",
@@ -44,6 +44,11 @@ static struct dsa_platform_data rd88f6183ap_ge_switch_data = {
.port_names[5] = "cpu",
};
+static struct dsa_platform_data rd88f6183ap_ge_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &rd88f6183ap_ge_switch_chip_data,
+};
+
static struct mtd_partition rd88f6183ap_ge_partitions[] = {
{
.name = "kernel",
@@ -89,7 +94,8 @@ static void __init rd88f6183ap_ge_init(void)
*/
orion5x_ehci0_init();
orion5x_eth_init(&rd88f6183ap_ge_eth_data);
- orion5x_eth_switch_init(&rd88f6183ap_ge_switch_data, gpio_to_irq(3));
+ orion5x_eth_switch_init(&rd88f6183ap_ge_switch_plat_data,
+ gpio_to_irq(3));
spi_register_board_info(rd88f6183ap_ge_spi_slave_info,
ARRAY_SIZE(rd88f6183ap_ge_spi_slave_info));
orion5x_spi_init();
diff --git a/arch/arm/mach-orion5x/ts78xx-fpga.h b/arch/arm/mach-orion5x/ts78xx-fpga.h
new file mode 100644
index 000000000000..0f9cdf458952
--- /dev/null
+++ b/arch/arm/mach-orion5x/ts78xx-fpga.h
@@ -0,0 +1,35 @@
+#define FPGAID(_magic, _rev) ((_magic << 8) + _rev)
+
+/*
+ * get yer id's from http://ts78xx.digriz.org.uk/
+ * do *not* make up your own or 'borrow' any!
+ */
+enum fpga_ids {
+ /* Technologic Systems */
+ TS7800_REV_1 = FPGAID(0x00b480, 0x01),
+ TS7800_REV_2 = FPGAID(0x00b480, 0x02),
+ TS7800_REV_3 = FPGAID(0x00b480, 0x03),
+ TS7800_REV_4 = FPGAID(0x00b480, 0x04),
+ TS7800_REV_5 = FPGAID(0x00b480, 0x05),
+
+ /* Unaffordable & Expensive */
+ UAE_DUMMY = FPGAID(0xffffff, 0x01),
+};
+
+struct fpga_device {
+ unsigned present:1;
+ unsigned init:1;
+};
+
+struct fpga_devices {
+ /* Technologic Systems */
+ struct fpga_device ts_rtc;
+ struct fpga_device ts_nand;
+};
+
+struct ts78xx_fpga_data {
+ unsigned int id;
+ int state;
+
+ struct fpga_devices supports;
+};
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c
index 1368e9fd1a06..9a6b397f972d 100644
--- a/arch/arm/mach-orion5x/ts78xx-setup.c
+++ b/arch/arm/mach-orion5x/ts78xx-setup.c
@@ -10,17 +10,20 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/sysfs.h>
#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/ata_platform.h>
#include <linux/m48t86.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/orion5x.h>
#include "common.h"
#include "mpp.h"
+#include "ts78xx-fpga.h"
/*****************************************************************************
* TS-78xx Info
@@ -33,18 +36,11 @@
#define TS78XX_FPGA_REGS_VIRT_BASE 0xff900000
#define TS78XX_FPGA_REGS_SIZE SZ_1M
-#define TS78XX_FPGA_REGS_SYSCON_ID (TS78XX_FPGA_REGS_VIRT_BASE | 0x000)
-#define TS78XX_FPGA_REGS_SYSCON_LCDI (TS78XX_FPGA_REGS_VIRT_BASE | 0x004)
-#define TS78XX_FPGA_REGS_SYSCON_LCDO (TS78XX_FPGA_REGS_VIRT_BASE | 0x008)
-
-#define TS78XX_FPGA_REGS_RTC_CTRL (TS78XX_FPGA_REGS_VIRT_BASE | 0x808)
-#define TS78XX_FPGA_REGS_RTC_DATA (TS78XX_FPGA_REGS_VIRT_BASE | 0x80c)
-
-/*
- * 512kB NOR flash Device
- */
-#define TS78XX_NOR_BOOT_BASE 0xff800000
-#define TS78XX_NOR_BOOT_SIZE SZ_512K
+static struct ts78xx_fpga_data ts78xx_fpga = {
+ .id = 0,
+ .state = 1,
+/* .supports = ... - populated by ts78xx_fpga_supports() */
+};
/*****************************************************************************
* I/O Address Mapping
@@ -65,73 +61,47 @@ void __init ts78xx_map_io(void)
}
/*****************************************************************************
- * 512kB NOR Boot Flash - the chip is a M25P40
+ * Ethernet
****************************************************************************/
-static struct mtd_partition ts78xx_nor_boot_flash_resources[] = {
- {
- .name = "ts-bootrom",
- .offset = 0,
- /* only the first 256kB is used */
- .size = SZ_256K,
- .mask_flags = MTD_WRITEABLE,
- },
-};
-
-static struct physmap_flash_data ts78xx_nor_boot_flash_data = {
- .width = 1,
- .parts = ts78xx_nor_boot_flash_resources,
- .nr_parts = ARRAY_SIZE(ts78xx_nor_boot_flash_resources),
-};
-
-static struct resource ts78xx_nor_boot_flash_resource = {
- .flags = IORESOURCE_MEM,
- .start = TS78XX_NOR_BOOT_BASE,
- .end = TS78XX_NOR_BOOT_BASE + TS78XX_NOR_BOOT_SIZE - 1,
-};
-
-static struct platform_device ts78xx_nor_boot_flash = {
- .name = "physmap-flash",
- .id = -1,
- .dev = {
- .platform_data = &ts78xx_nor_boot_flash_data,
- },
- .num_resources = 1,
- .resource = &ts78xx_nor_boot_flash_resource,
+static struct mv643xx_eth_platform_data ts78xx_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
};
/*****************************************************************************
- * Ethernet
+ * SATA
****************************************************************************/
-static struct mv643xx_eth_platform_data ts78xx_eth_data = {
- .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+static struct mv_sata_platform_data ts78xx_sata_data = {
+ .n_ports = 2,
};
/*****************************************************************************
* RTC M48T86 - nicked^Wborrowed from arch/arm/mach-ep93xx/ts72xx.c
****************************************************************************/
-#ifdef CONFIG_RTC_DRV_M48T86
-static unsigned char ts78xx_rtc_readbyte(unsigned long addr)
+#define TS_RTC_CTRL (TS78XX_FPGA_REGS_VIRT_BASE | 0x808)
+#define TS_RTC_DATA (TS78XX_FPGA_REGS_VIRT_BASE | 0x80c)
+
+static unsigned char ts78xx_ts_rtc_readbyte(unsigned long addr)
{
- writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL);
- return readb(TS78XX_FPGA_REGS_RTC_DATA);
+ writeb(addr, TS_RTC_CTRL);
+ return readb(TS_RTC_DATA);
}
-static void ts78xx_rtc_writebyte(unsigned char value, unsigned long addr)
+static void ts78xx_ts_rtc_writebyte(unsigned char value, unsigned long addr)
{
- writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL);
- writeb(value, TS78XX_FPGA_REGS_RTC_DATA);
+ writeb(addr, TS_RTC_CTRL);
+ writeb(value, TS_RTC_DATA);
}
-static struct m48t86_ops ts78xx_rtc_ops = {
- .readbyte = ts78xx_rtc_readbyte,
- .writebyte = ts78xx_rtc_writebyte,
+static struct m48t86_ops ts78xx_ts_rtc_ops = {
+ .readbyte = ts78xx_ts_rtc_readbyte,
+ .writebyte = ts78xx_ts_rtc_writebyte,
};
-static struct platform_device ts78xx_rtc_device = {
+static struct platform_device ts78xx_ts_rtc_device = {
.name = "rtc-m48t86",
.id = -1,
.dev = {
- .platform_data = &ts78xx_rtc_ops,
+ .platform_data = &ts78xx_ts_rtc_ops,
},
.num_resources = 0,
};
@@ -146,59 +116,314 @@ static struct platform_device ts78xx_rtc_device = {
* TODO: track down a guinea pig without an RTC to see if we can work out a
* better RTC detection routine
*/
-static int __init ts78xx_rtc_init(void)
+static int ts78xx_ts_rtc_load(void)
{
+ int rc;
unsigned char tmp_rtc0, tmp_rtc1;
- tmp_rtc0 = ts78xx_rtc_readbyte(126);
- tmp_rtc1 = ts78xx_rtc_readbyte(127);
-
- ts78xx_rtc_writebyte(0x00, 126);
- ts78xx_rtc_writebyte(0x55, 127);
- if (ts78xx_rtc_readbyte(127) == 0x55) {
- ts78xx_rtc_writebyte(0xaa, 127);
- if (ts78xx_rtc_readbyte(127) == 0xaa
- && ts78xx_rtc_readbyte(126) == 0x00) {
- ts78xx_rtc_writebyte(tmp_rtc0, 126);
- ts78xx_rtc_writebyte(tmp_rtc1, 127);
- platform_device_register(&ts78xx_rtc_device);
- return 1;
+ tmp_rtc0 = ts78xx_ts_rtc_readbyte(126);
+ tmp_rtc1 = ts78xx_ts_rtc_readbyte(127);
+
+ ts78xx_ts_rtc_writebyte(0x00, 126);
+ ts78xx_ts_rtc_writebyte(0x55, 127);
+ if (ts78xx_ts_rtc_readbyte(127) == 0x55) {
+ ts78xx_ts_rtc_writebyte(0xaa, 127);
+ if (ts78xx_ts_rtc_readbyte(127) == 0xaa
+ && ts78xx_ts_rtc_readbyte(126) == 0x00) {
+ ts78xx_ts_rtc_writebyte(tmp_rtc0, 126);
+ ts78xx_ts_rtc_writebyte(tmp_rtc1, 127);
+
+ if (ts78xx_fpga.supports.ts_rtc.init == 0) {
+ rc = platform_device_register(&ts78xx_ts_rtc_device);
+ if (!rc)
+ ts78xx_fpga.supports.ts_rtc.init = 1;
+ } else
+ rc = platform_device_add(&ts78xx_ts_rtc_device);
+
+ return rc;
}
}
- return 0;
+ return -ENODEV;
};
-#else
-static int __init ts78xx_rtc_init(void)
+
+static void ts78xx_ts_rtc_unload(void)
{
- return 0;
+ platform_device_del(&ts78xx_ts_rtc_device);
}
-#endif
/*****************************************************************************
- * SATA
+ * NAND Flash
****************************************************************************/
-static struct mv_sata_platform_data ts78xx_sata_data = {
- .n_ports = 2,
+#define TS_NAND_CTRL (TS78XX_FPGA_REGS_VIRT_BASE | 0x800) /* VIRT */
+#define TS_NAND_DATA (TS78XX_FPGA_REGS_PHYS_BASE | 0x804) /* PHYS */
+
+/*
+ * hardware specific access to control-lines
+ *
+ * ctrl:
+ * NAND_NCE: bit 0 -> bit 2
+ * NAND_CLE: bit 1 -> bit 1
+ * NAND_ALE: bit 2 -> bit 0
+ */
+static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ unsigned char bits;
+
+ bits = (ctrl & NAND_NCE) << 2;
+ bits |= ctrl & NAND_CLE;
+ bits |= (ctrl & NAND_ALE) >> 2;
+
+ writeb((readb(TS_NAND_CTRL) & ~0x7) | bits, TS_NAND_CTRL);
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ writeb(cmd, this->IO_ADDR_W);
+}
+
+static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd)
+{
+ return readb(TS_NAND_CTRL) & 0x20;
+}
+
+const char *ts_nand_part_probes[] = { "cmdlinepart", NULL };
+
+static struct mtd_partition ts78xx_ts_nand_parts[] = {
+ {
+ .name = "mbr",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ }, {
+ .name = "initrd",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ }, {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ }
};
+static struct platform_nand_data ts78xx_ts_nand_data = {
+ .chip = {
+ .part_probe_types = ts_nand_part_probes,
+ .partitions = ts78xx_ts_nand_parts,
+ .nr_partitions = ARRAY_SIZE(ts78xx_ts_nand_parts),
+ .chip_delay = 15,
+ .options = NAND_USE_FLASH_BBT,
+ },
+ .ctrl = {
+ /*
+ * The HW ECC offloading functions, used to give about a 9%
+ * performance increase for 'dd if=/dev/mtdblockX' and 5% for
+ * nanddump. This all however was changed by git commit
+ * e6cf5df1838c28bb060ac45b5585e48e71bbc740 so now there is
+ * no performance advantage to be had so we no longer bother
+ */
+ .cmd_ctrl = ts78xx_ts_nand_cmd_ctrl,
+ .dev_ready = ts78xx_ts_nand_dev_ready,
+ },
+};
+
+static struct resource ts78xx_ts_nand_resources = {
+ .start = TS_NAND_DATA,
+ .end = TS_NAND_DATA + 4,
+ .flags = IORESOURCE_IO,
+};
+
+static struct platform_device ts78xx_ts_nand_device = {
+ .name = "gen_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &ts78xx_ts_nand_data,
+ },
+ .resource = &ts78xx_ts_nand_resources,
+ .num_resources = 1,
+};
+
+static int ts78xx_ts_nand_load(void)
+{
+ int rc;
+
+ if (ts78xx_fpga.supports.ts_nand.init == 0) {
+ rc = platform_device_register(&ts78xx_ts_nand_device);
+ if (!rc)
+ ts78xx_fpga.supports.ts_nand.init = 1;
+ } else
+ rc = platform_device_add(&ts78xx_ts_nand_device);
+
+ return rc;
+};
+
+static void ts78xx_ts_nand_unload(void)
+{
+ platform_device_del(&ts78xx_ts_nand_device);
+}
+
/*****************************************************************************
- * print some information regarding the board
+ * FPGA 'hotplug' support code
****************************************************************************/
-static void __init ts78xx_print_board_id(void)
+static void ts78xx_fpga_devices_zero_init(void)
{
- unsigned int board_info;
-
- board_info = readl(TS78XX_FPGA_REGS_SYSCON_ID);
- printk(KERN_INFO "TS-78xx Info: FPGA rev=%.2x, Board Magic=%.6x, ",
- board_info & 0xff,
- (board_info >> 8) & 0xffffff);
- board_info = readl(TS78XX_FPGA_REGS_SYSCON_LCDI);
- printk("JP1=%d, JP2=%d\n",
- (board_info >> 30) & 0x1,
- (board_info >> 31) & 0x1);
+ ts78xx_fpga.supports.ts_rtc.init = 0;
+ ts78xx_fpga.supports.ts_nand.init = 0;
+}
+
+static void ts78xx_fpga_supports(void)
+{
+ /* TODO: put this 'table' into ts78xx-fpga.h */
+ switch (ts78xx_fpga.id) {
+ case TS7800_REV_1:
+ case TS7800_REV_2:
+ case TS7800_REV_3:
+ case TS7800_REV_4:
+ case TS7800_REV_5:
+ ts78xx_fpga.supports.ts_rtc.present = 1;
+ ts78xx_fpga.supports.ts_nand.present = 1;
+ break;
+ default:
+ ts78xx_fpga.supports.ts_rtc.present = 0;
+ ts78xx_fpga.supports.ts_nand.present = 0;
+ }
+}
+
+static int ts78xx_fpga_load_devices(void)
+{
+ int tmp, ret = 0;
+
+ if (ts78xx_fpga.supports.ts_rtc.present == 1) {
+ tmp = ts78xx_ts_rtc_load();
+ if (tmp) {
+ printk(KERN_INFO "TS-78xx: RTC not registered\n");
+ ts78xx_fpga.supports.ts_rtc.present = 0;
+ }
+ ret |= tmp;
+ }
+ if (ts78xx_fpga.supports.ts_nand.present == 1) {
+ tmp = ts78xx_ts_nand_load();
+ if (tmp) {
+ printk(KERN_INFO "TS-78xx: NAND not registered\n");
+ ts78xx_fpga.supports.ts_nand.present = 0;
+ }
+ ret |= tmp;
+ }
+
+ return ret;
+}
+
+static int ts78xx_fpga_unload_devices(void)
+{
+ int ret = 0;
+
+ if (ts78xx_fpga.supports.ts_rtc.present == 1)
+ ts78xx_ts_rtc_unload();
+ if (ts78xx_fpga.supports.ts_nand.present == 1)
+ ts78xx_ts_nand_unload();
+
+ return ret;
+}
+
+static int ts78xx_fpga_load(void)
+{
+ ts78xx_fpga.id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
+
+ printk(KERN_INFO "TS-78xx FPGA: magic=0x%.6x, rev=0x%.2x\n",
+ (ts78xx_fpga.id >> 8) & 0xffffff,
+ ts78xx_fpga.id & 0xff);
+
+ ts78xx_fpga_supports();
+
+ if (ts78xx_fpga_load_devices()) {
+ ts78xx_fpga.state = -1;
+ return -EBUSY;
+ }
+
+ return 0;
};
+static int ts78xx_fpga_unload(void)
+{
+ unsigned int fpga_id;
+
+ fpga_id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
+
+ /*
+ * There does not seem to be a feasible way to block access to the GPIO
+ * pins from userspace (/dev/mem). This if clause should hopefully warn
+ * those foolish enough not to follow 'policy' :)
+ *
+ * UrJTAG SVN since r1381 can be used to reprogram the FPGA
+ */
+ if (ts78xx_fpga.id != fpga_id) {
+ printk(KERN_ERR "TS-78xx FPGA: magic/rev mismatch\n"
+ "TS-78xx FPGA: was 0x%.6x/%.2x but now 0x%.6x/%.2x\n",
+ (ts78xx_fpga.id >> 8) & 0xffffff, ts78xx_fpga.id & 0xff,
+ (fpga_id >> 8) & 0xffffff, fpga_id & 0xff);
+ ts78xx_fpga.state = -1;
+ return -EBUSY;
+ }
+
+ if (ts78xx_fpga_unload_devices()) {
+ ts78xx_fpga.state = -1;
+ return -EBUSY;
+ }
+
+ return 0;
+};
+
+static ssize_t ts78xx_fpga_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ if (ts78xx_fpga.state < 0)
+ return sprintf(buf, "borked\n");
+
+ return sprintf(buf, "%s\n", (ts78xx_fpga.state) ? "online" : "offline");
+}
+
+static ssize_t ts78xx_fpga_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t n)
+{
+ int value, ret;
+
+ if (ts78xx_fpga.state < 0) {
+ printk(KERN_ERR "TS-78xx FPGA: borked, you must powercycle asap\n");
+ return -EBUSY;
+ }
+
+ if (strncmp(buf, "online", sizeof("online") - 1) == 0)
+ value = 1;
+ else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
+ value = 0;
+ else {
+ printk(KERN_ERR "ts78xx_fpga_store: Invalid value\n");
+ return -EINVAL;
+ }
+
+ if (ts78xx_fpga.state == value)
+ return n;
+
+ ret = (ts78xx_fpga.state == 0)
+ ? ts78xx_fpga_load()
+ : ts78xx_fpga_unload();
+
+ if (!(ret < 0))
+ ts78xx_fpga.state = value;
+
+ return n;
+}
+
+static struct kobj_attribute ts78xx_fpga_attr =
+ __ATTR(ts78xx_fpga, 0644, ts78xx_fpga_show, ts78xx_fpga_store);
+
/*****************************************************************************
* General Setup
****************************************************************************/
@@ -223,30 +448,29 @@ static struct orion5x_mpp_mode ts78xx_mpp_modes[] __initdata = {
{ 17, MPP_UART },
{ 18, MPP_UART },
{ 19, MPP_UART },
+ /*
+ * MPP[20] PCI Clock Out 1
+ * MPP[21] PCI Clock Out 0
+ * MPP[22] Unused
+ * MPP[23] Unused
+ * MPP[24] Unused
+ * MPP[25] Unused
+ */
{ -1 },
};
static void __init ts78xx_init(void)
{
+ int ret;
+
/*
* Setup basic Orion functions. Need to be called early.
*/
orion5x_init();
- ts78xx_print_board_id();
-
orion5x_mpp_conf(ts78xx_mpp_modes);
/*
- * MPP[20] PCI Clock Out 1
- * MPP[21] PCI Clock Out 0
- * MPP[22] Unused
- * MPP[23] Unused
- * MPP[24] Unused
- * MPP[25] Unused
- */
-
- /*
* Configure peripherals.
*/
orion5x_ehci0_init();
@@ -257,12 +481,12 @@ static void __init ts78xx_init(void)
orion5x_uart1_init();
orion5x_xor_init();
- orion5x_setup_dev_boot_win(TS78XX_NOR_BOOT_BASE,
- TS78XX_NOR_BOOT_SIZE);
- platform_device_register(&ts78xx_nor_boot_flash);
-
- if (!ts78xx_rtc_init())
- printk(KERN_INFO "TS-78xx RTC not detected or enabled\n");
+ /* FPGA init */
+ ts78xx_fpga_devices_zero_init();
+ ret = ts78xx_fpga_load();
+ ret = sysfs_create_file(power_kobj, &ts78xx_fpga_attr.attr);
+ if (ret)
+ printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
}
MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
index cc8f89200865..1b4ad9d5e2eb 100644
--- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c
+++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
@@ -106,7 +106,7 @@ static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = {
.duplex = DUPLEX_FULL,
};
-static struct dsa_platform_data wrt350n_v2_switch_data = {
+static struct dsa_chip_data wrt350n_v2_switch_chip_data = {
.port_names[0] = "lan2",
.port_names[1] = "lan1",
.port_names[2] = "wan",
@@ -115,6 +115,11 @@ static struct dsa_platform_data wrt350n_v2_switch_data = {
.port_names[7] = "lan4",
};
+static struct dsa_platform_data wrt350n_v2_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &wrt350n_v2_switch_chip_data,
+};
+
static void __init wrt350n_v2_init(void)
{
/*
@@ -129,7 +134,7 @@ static void __init wrt350n_v2_init(void)
*/
orion5x_ehci0_init();
orion5x_eth_init(&wrt350n_v2_eth_data);
- orion5x_eth_switch_init(&wrt350n_v2_switch_data, NO_IRQ);
+ orion5x_eth_switch_init(&wrt350n_v2_switch_plat_data, NO_IRQ);
orion5x_uart0_init();
orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE,
diff --git a/arch/arm/mach-pnx4008/include/mach/system.h b/arch/arm/mach-pnx4008/include/mach/system.h
index e12e7abfcbcf..5dda2bb55f8d 100644
--- a/arch/arm/mach-pnx4008/include/mach/system.h
+++ b/arch/arm/mach-pnx4008/include/mach/system.h
@@ -30,7 +30,7 @@ static void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
cpu_reset(0);
}
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 8eea7306f29b..96a2006cb597 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -40,6 +40,9 @@ choice
config GUMSTIX_AM200EPD
bool "Enable AM200EPD board support"
+config GUMSTIX_AM300EPD
+ bool "Enable AM300EPD board support"
+
endchoice
config MACH_INTELMOTE2
@@ -254,10 +257,24 @@ config MACH_EM_X270
bool "CompuLab EM-x270 platform"
select PXA27x
+config MACH_EXEDA
+ bool "CompuLab eXeda platform"
+ select PXA27x
+
config MACH_COLIBRI
- bool "Toradex Colibri PX27x"
+ bool "Toradex Colibri PXA270"
select PXA27x
+config MACH_COLIBRI300
+ bool "Toradex Colibri PXA300/310"
+ select PXA3xx
+ select CPU_PXA300
+
+config MACH_COLIBRI320
+ bool "Toradex Colibri PXA320"
+ select PXA3xx
+ select CPU_PXA320
+
config MACH_ZYLONITE
bool "PXA3xx Development Platform (aka Zylonite)"
select PXA3xx
@@ -295,8 +312,15 @@ config MACH_MAGICIAN
bool "Enable HTC Magician Support"
select PXA27x
select IWMMXT
+ select PXA_SSP
+ select HAVE_PWM
select PXA_HAVE_BOARD_IRQS
+config MACH_HIMALAYA
+ bool "HTC Himalaya Support"
+ select CPU_PXA26x
+ select FB_W100
+
config MACH_MIOA701
bool "Mitac Mio A701 Support"
select PXA27x
@@ -319,6 +343,16 @@ config ARCH_PXA_PALM
bool "PXA based Palm PDAs"
select HAVE_PWM
+config MACH_PALMT5
+ bool "Palm Tungsten|T5"
+ default y
+ depends on ARCH_PXA_PALM
+ select PXA27x
+ select IWMMXT
+ help
+ Say Y here if you intend to run this kernel on a Palm Tungsten|T5
+ handheld computer.
+
config MACH_PALMTX
bool "Palm T|X"
default y
@@ -339,6 +373,16 @@ config MACH_PALMZ72
Say Y here if you intend to run this kernel on Palm Zire 72
handheld computer.
+config MACH_PALMLD
+ bool "Palm LifeDrive"
+ default y
+ depends on ARCH_PXA_PALM
+ select PXA27x
+ select IWMMXT
+ help
+ Say Y here if you intend to run this kernel on a Palm LifeDrive
+ handheld computer.
+
config MACH_PCM990_BASEBOARD
bool "PHYTEC PCM-990 development board"
select HAVE_PWM
@@ -359,6 +403,18 @@ config PCM990_DISPLAY_NONE
endchoice
+config MACH_CSB726
+ bool "Enable Cogent CSB726 System On a Module"
+ select PXA27x
+ select IWMMXT
+ help
+ Say Y here if you intend to run this kernel on a Cogent
+ CSB726 System On Module.
+
+config CSB726_CSB701
+ bool "Enable supprot for CSB701 baseboard"
+ depends on MACH_CSB726
+
config PXA_EZX
bool "Motorola EZX Platform"
select PXA27x
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 7b28bb561d63..c80e1bac4945 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -3,8 +3,8 @@
#
# Common support (must be linked before board specific support)
-obj-y += clock.o devices.o generic.o irq.o dma.o \
- time.o gpio.o reset.o
+obj-y += clock.o devices.o generic.o irq.o \
+ time.o reset.o
obj-$(CONFIG_PM) += pm.o sleep.o standby.o
ifeq ($(CONFIG_CPU_FREQ),y)
@@ -28,13 +28,16 @@ obj-$(CONFIG_CPU_PXA930) += pxa930.o
# Specific board support
obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o
obj-$(CONFIG_GUMSTIX_AM200EPD) += am200epd.o
+obj-$(CONFIG_GUMSTIX_AM300EPD) += am300epd.o
obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
obj-$(CONFIG_MACH_MP900C) += mp900.o
obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o
-obj-$(CONFIG_MACH_COLIBRI) += colibri.o
+obj-$(CONFIG_MACH_COLIBRI) += colibri-pxa270.o
+obj-$(CONFIG_MACH_COLIBRI300) += colibri-pxa3xx.o colibri-pxa300.o
+obj-$(CONFIG_MACH_COLIBRI320) += colibri-pxa3xx.o colibri-pxa320.o
obj-$(CONFIG_MACH_H5000) += h5000.o
obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o sharpsl_pm.o corgi_pm.o
obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o sharpsl_pm.o spitz_pm.o
@@ -45,6 +48,7 @@ obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o
obj-$(CONFIG_MACH_TOSA) += tosa.o
obj-$(CONFIG_MACH_EM_X270) += em-x270.o
obj-$(CONFIG_MACH_MAGICIAN) += magician.o
+obj-$(CONFIG_MACH_HIMALAYA) += himalaya.o
obj-$(CONFIG_MACH_MIOA701) += mioa701.o mioa701_bootresume.o
obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o
obj-$(CONFIG_MACH_E330) += e330.o
@@ -53,7 +57,9 @@ obj-$(CONFIG_MACH_E740) += e740.o
obj-$(CONFIG_MACH_E750) += e750.o
obj-$(CONFIG_MACH_E400) += e400.o
obj-$(CONFIG_MACH_E800) += e800.o
+obj-$(CONFIG_MACH_PALMT5) += palmt5.o
obj-$(CONFIG_MACH_PALMTX) += palmtx.o
+obj-$(CONFIG_MACH_PALMLD) += palmld.o
obj-$(CONFIG_MACH_PALMZ72) += palmz72.o
obj-$(CONFIG_ARCH_VIPER) += viper.o
@@ -71,6 +77,8 @@ obj-$(CONFIG_MACH_CM_X300) += cm-x300.o
obj-$(CONFIG_PXA_EZX) += ezx.o
obj-$(CONFIG_MACH_INTELMOTE2) += imote2.o
+obj-$(CONFIG_MACH_CSB726) += csb726.o
+obj-$(CONFIG_CSB726_CSB701) += csb701.o
# Support for blinky lights
led-y := leds.o
diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c
index 77ee80e5e47b..3499fada73ae 100644
--- a/arch/arm/mach-pxa/am200epd.c
+++ b/arch/arm/mach-pxa/am200epd.c
@@ -30,8 +30,8 @@
#include <linux/irq.h>
#include <linux/gpio.h>
+#include <mach/pxa25x.h>
#include <mach/gumstix.h>
-#include <mach/mfp-pxa25x.h>
#include <mach/pxafb.h>
#include "generic.h"
diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c
new file mode 100644
index 000000000000..4bd10a17332e
--- /dev/null
+++ b/arch/arm/mach-pxa/am300epd.c
@@ -0,0 +1,295 @@
+/*
+ * am300epd.c -- Platform device for AM300 EPD kit
+ *
+ * Copyright (C) 2008, Jaya Kumar
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * This work was made possible by help and equipment support from E-Ink
+ * Corporation. http://support.eink.com/community
+ *
+ * This driver is written to be used with the Broadsheet display controller.
+ * on the AM300 EPD prototype kit/development kit with an E-Ink 800x600
+ * Vizplex EPD on a Gumstix board using the Broadsheet interface board.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include <mach/gumstix.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/pxafb.h>
+
+#include "generic.h"
+
+#include <video/broadsheetfb.h>
+
+static unsigned int panel_type = 6;
+static struct platform_device *am300_device;
+static struct broadsheet_board am300_board;
+
+static unsigned long am300_pin_config[] __initdata = {
+ GPIO16_GPIO,
+ GPIO17_GPIO,
+ GPIO32_GPIO,
+ GPIO48_GPIO,
+ GPIO49_GPIO,
+ GPIO51_GPIO,
+ GPIO74_GPIO,
+ GPIO75_GPIO,
+ GPIO76_GPIO,
+ GPIO77_GPIO,
+
+ /* this is the 16-bit hdb bus 58-73 */
+ GPIO58_GPIO,
+ GPIO59_GPIO,
+ GPIO60_GPIO,
+ GPIO61_GPIO,
+
+ GPIO62_GPIO,
+ GPIO63_GPIO,
+ GPIO64_GPIO,
+ GPIO65_GPIO,
+
+ GPIO66_GPIO,
+ GPIO67_GPIO,
+ GPIO68_GPIO,
+ GPIO69_GPIO,
+
+ GPIO70_GPIO,
+ GPIO71_GPIO,
+ GPIO72_GPIO,
+ GPIO73_GPIO,
+};
+
+/* register offsets for gpio control */
+#define PWR_GPIO_PIN 16
+#define CFG_GPIO_PIN 17
+#define RDY_GPIO_PIN 32
+#define DC_GPIO_PIN 48
+#define RST_GPIO_PIN 49
+#define LED_GPIO_PIN 51
+#define RD_GPIO_PIN 74
+#define WR_GPIO_PIN 75
+#define CS_GPIO_PIN 76
+#define IRQ_GPIO_PIN 77
+
+/* hdb bus */
+#define DB0_GPIO_PIN 58
+#define DB15_GPIO_PIN 73
+
+static int gpios[] = { PWR_GPIO_PIN, CFG_GPIO_PIN, RDY_GPIO_PIN, DC_GPIO_PIN,
+ RST_GPIO_PIN, RD_GPIO_PIN, WR_GPIO_PIN, CS_GPIO_PIN,
+ IRQ_GPIO_PIN, LED_GPIO_PIN };
+static char *gpio_names[] = { "PWR", "CFG", "RDY", "DC", "RST", "RD", "WR",
+ "CS", "IRQ", "LED" };
+
+static int am300_wait_event(struct broadsheetfb_par *par)
+{
+ /* todo: improve err recovery */
+ wait_event(par->waitq, gpio_get_value(RDY_GPIO_PIN));
+ return 0;
+}
+
+static int am300_init_gpio_regs(struct broadsheetfb_par *par)
+{
+ int i;
+ int err;
+ char dbname[8];
+
+ for (i = 0; i < ARRAY_SIZE(gpios); i++) {
+ err = gpio_request(gpios[i], gpio_names[i]);
+ if (err) {
+ dev_err(&am300_device->dev, "failed requesting "
+ "gpio %s, err=%d\n", gpio_names[i], err);
+ goto err_req_gpio;
+ }
+ }
+
+ /* we also need to take care of the hdb bus */
+ for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++) {
+ sprintf(dbname, "DB%d", i);
+ err = gpio_request(i, dbname);
+ if (err) {
+ dev_err(&am300_device->dev, "failed requesting "
+ "gpio %d, err=%d\n", i, err);
+ while (i >= DB0_GPIO_PIN)
+ gpio_free(i--);
+ i = ARRAY_SIZE(gpios) - 1;
+ goto err_req_gpio;
+ }
+ }
+
+ /* setup the outputs and init values */
+ gpio_direction_output(PWR_GPIO_PIN, 0);
+ gpio_direction_output(CFG_GPIO_PIN, 1);
+ gpio_direction_output(DC_GPIO_PIN, 0);
+ gpio_direction_output(RD_GPIO_PIN, 1);
+ gpio_direction_output(WR_GPIO_PIN, 1);
+ gpio_direction_output(CS_GPIO_PIN, 1);
+ gpio_direction_output(RST_GPIO_PIN, 0);
+
+ /* setup the inputs */
+ gpio_direction_input(RDY_GPIO_PIN);
+ gpio_direction_input(IRQ_GPIO_PIN);
+
+ /* start the hdb bus as an input */
+ for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++)
+ gpio_direction_output(i, 0);
+
+ /* go into command mode */
+ gpio_set_value(CFG_GPIO_PIN, 1);
+ gpio_set_value(RST_GPIO_PIN, 0);
+ msleep(10);
+ gpio_set_value(RST_GPIO_PIN, 1);
+ msleep(10);
+ am300_wait_event(par);
+
+ return 0;
+
+err_req_gpio:
+ while (i > 0)
+ gpio_free(gpios[i--]);
+
+ return err;
+}
+
+static int am300_init_board(struct broadsheetfb_par *par)
+{
+ return am300_init_gpio_regs(par);
+}
+
+static void am300_cleanup(struct broadsheetfb_par *par)
+{
+ int i;
+
+ free_irq(IRQ_GPIO(RDY_GPIO_PIN), par);
+
+ for (i = 0; i < ARRAY_SIZE(gpios); i++)
+ gpio_free(gpios[i]);
+
+ for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++)
+ gpio_free(i);
+
+}
+
+static u16 am300_get_hdb(struct broadsheetfb_par *par)
+{
+ u16 res = 0;
+ int i;
+
+ for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++)
+ res |= (gpio_get_value(DB0_GPIO_PIN + i)) ? (1 << i) : 0;
+
+ return res;
+}
+
+static void am300_set_hdb(struct broadsheetfb_par *par, u16 data)
+{
+ int i;
+
+ for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++)
+ gpio_set_value(DB0_GPIO_PIN + i, (data >> i) & 0x01);
+}
+
+
+static void am300_set_ctl(struct broadsheetfb_par *par, unsigned char bit,
+ u8 state)
+{
+ switch (bit) {
+ case BS_CS:
+ gpio_set_value(CS_GPIO_PIN, state);
+ break;
+ case BS_DC:
+ gpio_set_value(DC_GPIO_PIN, state);
+ break;
+ case BS_WR:
+ gpio_set_value(WR_GPIO_PIN, state);
+ break;
+ }
+}
+
+static int am300_get_panel_type(void)
+{
+ return panel_type;
+}
+
+static irqreturn_t am300_handle_irq(int irq, void *dev_id)
+{
+ struct broadsheetfb_par *par = dev_id;
+
+ wake_up(&par->waitq);
+ return IRQ_HANDLED;
+}
+
+static int am300_setup_irq(struct fb_info *info)
+{
+ int ret;
+ struct broadsheetfb_par *par = info->par;
+
+ ret = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am300_handle_irq,
+ IRQF_DISABLED|IRQF_TRIGGER_RISING,
+ "AM300", par);
+ if (ret)
+ dev_err(&am300_device->dev, "request_irq failed: %d\n", ret);
+
+ return ret;
+}
+
+static struct broadsheet_board am300_board = {
+ .owner = THIS_MODULE,
+ .init = am300_init_board,
+ .cleanup = am300_cleanup,
+ .set_hdb = am300_set_hdb,
+ .get_hdb = am300_get_hdb,
+ .set_ctl = am300_set_ctl,
+ .wait_for_rdy = am300_wait_event,
+ .get_panel_type = am300_get_panel_type,
+ .setup_irq = am300_setup_irq,
+};
+
+int __init am300_init(void)
+{
+ int ret;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(am300_pin_config));
+
+ /* request our platform independent driver */
+ request_module("broadsheetfb");
+
+ am300_device = platform_device_alloc("broadsheetfb", -1);
+ if (!am300_device)
+ return -ENOMEM;
+
+ /* the am300_board that will be seen by broadsheetfb is a copy */
+ platform_device_add_data(am300_device, &am300_board,
+ sizeof(am300_board));
+
+ ret = platform_device_add(am300_device);
+
+ if (ret) {
+ platform_device_put(am300_device);
+ return ret;
+ }
+
+ return 0;
+}
+
+module_param(panel_type, uint, 0);
+MODULE_PARM_DESC(panel_type, "Select the panel type: 6, 8, 97");
+
+MODULE_DESCRIPTION("board driver for am300 epd kit");
+MODULE_AUTHOR("Jaya Kumar");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
index 40b774084514..db52d2c4791d 100644
--- a/arch/arm/mach-pxa/clock.c
+++ b/arch/arm/mach-pxa/clock.c
@@ -87,7 +87,7 @@ void clks_register(struct clk_lookup *clks, size_t num)
clkdev_add(&clks[i]);
}
-int clk_add_alias(char *alias, struct device *alias_dev, char *id,
+int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
struct device *dev)
{
struct clk *r = clk_get(dev, id);
@@ -96,7 +96,7 @@ int clk_add_alias(char *alias, struct device *alias_dev, char *id,
if (!r)
return -ENODEV;
- l = clkdev_alloc(r, alias, alias_dev ? dev_name(alias_dev) : NULL);
+ l = clkdev_alloc(r, alias, alias_dev_name);
clk_put(r);
if (!l)
return -ENODEV;
diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
index 4e9c613c6767..5599bceff738 100644
--- a/arch/arm/mach-pxa/clock.h
+++ b/arch/arm/mach-pxa/clock.h
@@ -69,6 +69,6 @@ extern void clk_pxa3xx_cken_disable(struct clk *);
#endif
void clks_register(struct clk_lookup *clks, size_t num);
-int clk_add_alias(char *alias, struct device *alias_dev, char *id,
+int clk_add_alias(const char *alias, const char *alias_name, char *id,
struct device *dev);
diff --git a/arch/arm/mach-pxa/cm-x255.c b/arch/arm/mach-pxa/cm-x255.c
index 83a4cdf08176..253fd76142d6 100644
--- a/arch/arm/mach-pxa/cm-x255.c
+++ b/arch/arm/mach-pxa/cm-x255.c
@@ -22,10 +22,8 @@
#include <asm/mach-types.h>
#include <asm/mach/map.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include <mach/pxa25x.h>
#include <mach/pxa2xx_spi.h>
-#include <mach/bitfield.h>
#include "generic.h"
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
index df83b97f303f..34576ba5f5fd 100644
--- a/arch/arm/mach-pxa/cm-x270.c
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -17,7 +17,7 @@
#include <linux/rtc-v3020.h>
#include <video/mbxfb.h>
-#include <mach/mfp-pxa27x.h>
+#include <mach/pxa27x.h>
#include <mach/ohci.h>
#include <mach/mmc.h>
diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.c b/arch/arm/mach-pxa/cm-x2xx-pci.c
index 3156b25f6e9d..7873fa3d8fa4 100644
--- a/arch/arm/mach-pxa/cm-x2xx-pci.c
+++ b/arch/arm/mach-pxa/cm-x2xx-pci.c
@@ -22,7 +22,6 @@
#include <linux/gpio.h>
#include <asm/mach/pci.h>
-#include <mach/pxa-regs.h>
#include <asm/mach-types.h>
#include <asm/hardware/it8152.h>
diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c
index d99fd9e4d888..117b5435f8d5 100644
--- a/arch/arm/mach-pxa/cm-x2xx.c
+++ b/arch/arm/mach-pxa/cm-x2xx.c
@@ -22,8 +22,6 @@
#include <asm/mach/map.h>
#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
-#include <mach/pxa-regs.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
@@ -96,7 +94,7 @@ static struct resource cmx270_dm9000_resource[] = {
};
static struct dm9000_plat_data cmx270_dm9000_platdata = {
- .flags = DM9000_PLATF_32BITONLY,
+ .flags = DM9000_PLATF_32BITONLY | DM9000_PLATF_NO_EEPROM,
};
static struct platform_device cmx2xx_dm9000_device = {
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index ff0c577cd1ac..a9f48b1cb54a 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -28,9 +28,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/mfp-pxa300.h>
-
-#include <mach/hardware.h>
+#include <mach/pxa300.h>
#include <mach/pxafb.h>
#include <mach/mmc.h>
#include <mach/ohci.h>
@@ -162,7 +160,7 @@ static struct resource dm9000_resources[] = {
};
static struct dm9000_plat_data cm_x300_dm9000_platdata = {
- .flags = DM9000_PLATF_16BITONLY,
+ .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM,
};
static struct platform_device dm9000_device = {
diff --git a/arch/arm/mach-pxa/colibri.c b/arch/arm/mach-pxa/colibri-pxa270.c
index e8473624427e..01bcfaae75bc 100644
--- a/arch/arm/mach-pxa/colibri.c
+++ b/arch/arm/mach-pxa/colibri-pxa270.c
@@ -1,7 +1,7 @@
/*
- * linux/arch/arm/mach-pxa/colibri.c
+ * linux/arch/arm/mach-pxa/colibri-pxa270.c
*
- * Support for Toradex PXA27x based Colibri module
+ * Support for Toradex PXA270 based Colibri module
* Daniel Mack <daniel@caiaq.de>
*
* This program is free software; you can redistribute it and/or modify
@@ -20,6 +20,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <asm/irq.h>
@@ -28,20 +29,23 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
-#include <mach/pxa-regs.h>
-#include <mach/mfp-pxa27x.h>
+
+#include <mach/pxa27x.h>
#include <mach/colibri.h>
#include "generic.h"
#include "devices.h"
-static unsigned long colibri_pin_config[] __initdata = {
+/*
+ * GPIO configuration
+ */
+static mfp_cfg_t colibri_pxa270_pin_config[] __initdata = {
GPIO78_nCS_2, /* Ethernet CS */
GPIO114_GPIO, /* Ethernet IRQ */
};
/*
- * Flash
+ * NOR flash
*/
static struct mtd_partition colibri_partitions[] = {
{
@@ -70,39 +74,40 @@ static struct physmap_flash_data colibri_flash_data[] = {
}
};
-static struct resource flash_resource = {
+static struct resource colibri_pxa270_flash_resource = {
.start = PXA_CS0_PHYS,
.end = PXA_CS0_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM,
};
-static struct platform_device flash_device = {
+static struct platform_device colibri_pxa270_flash_device = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = colibri_flash_data,
},
- .resource = &flash_resource,
+ .resource = &colibri_pxa270_flash_resource,
.num_resources = 1,
};
/*
* DM9000 Ethernet
*/
+#if defined(CONFIG_DM9000)
static struct resource dm9000_resources[] = {
[0] = {
- .start = COLIBRI_ETH_PHYS,
- .end = COLIBRI_ETH_PHYS + 3,
+ .start = COLIBRI_PXA270_ETH_PHYS,
+ .end = COLIBRI_PXA270_ETH_PHYS + 3,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = COLIBRI_ETH_PHYS + 4,
- .end = COLIBRI_ETH_PHYS + 4 + 500,
+ .start = COLIBRI_PXA270_ETH_PHYS + 4,
+ .end = COLIBRI_PXA270_ETH_PHYS + 4 + 500,
.flags = IORESOURCE_MEM,
},
[2] = {
- .start = COLIBRI_ETH_IRQ,
- .end = COLIBRI_ETH_IRQ,
+ .start = COLIBRI_PXA270_ETH_IRQ,
+ .end = COLIBRI_PXA270_ETH_IRQ,
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING,
},
};
@@ -113,25 +118,28 @@ static struct platform_device dm9000_device = {
.num_resources = ARRAY_SIZE(dm9000_resources),
.resource = dm9000_resources,
};
+#endif /* CONFIG_DM9000 */
-static struct platform_device *colibri_devices[] __initdata = {
- &flash_device,
+static struct platform_device *colibri_pxa270_devices[] __initdata = {
+ &colibri_pxa270_flash_device,
+#if defined(CONFIG_DM9000)
&dm9000_device,
+#endif
};
-static void __init colibri_init(void)
+static void __init colibri_pxa270_init(void)
{
- pxa2xx_mfp_config(ARRAY_AND_SIZE(colibri_pin_config));
-
- platform_add_devices(colibri_devices, ARRAY_SIZE(colibri_devices));
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa270_pin_config));
+ platform_add_devices(ARRAY_AND_SIZE(colibri_pxa270_devices));
}
-MACHINE_START(COLIBRI, "Toradex Colibri PXA27x")
+MACHINE_START(COLIBRI, "Toradex Colibri PXA270")
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = COLIBRI_SDRAM_BASE + 0x100,
- .init_machine = colibri_init,
+ .init_machine = colibri_pxa270_init,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
MACHINE_END
+
diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c
new file mode 100644
index 000000000000..10c2eaf93230
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-pxa300.c
@@ -0,0 +1,190 @@
+/*
+ * arch/arm/mach-pxa/colibri-pxa300.c
+ *
+ * Support for Toradex PXA300/310 based Colibri module
+ *
+ * Daniel Mack <daniel@caiaq.de>
+ * Matthias Meier <matthias.j.meier@gmx.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <net/ax88796.h>
+
+#include <asm/mach-types.h>
+#include <asm/sizes.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+
+#include <mach/pxa300.h>
+#include <mach/colibri.h>
+#include <mach/ohci.h>
+#include <mach/pxafb.h>
+
+#include "generic.h"
+#include "devices.h"
+
+#if defined(CONFIG_AX88796)
+#define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO26_GPIO)
+/*
+ * Asix AX88796 Ethernet
+ */
+static struct ax_plat_data colibri_asix_platdata = {
+ .flags = AXFLG_MAC_FROMDEV,
+ .wordlength = 2
+};
+
+static struct resource colibri_asix_resource[] = {
+ [0] = {
+ .start = PXA3xx_CS2_PHYS,
+ .end = PXA3xx_CS2_PHYS + (0x20 * 2) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
+ .end = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device asix_device = {
+ .name = "ax88796",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(colibri_asix_resource),
+ .resource = colibri_asix_resource,
+ .dev = {
+ .platform_data = &colibri_asix_platdata
+ }
+};
+
+static mfp_cfg_t colibri_pxa300_eth_pin_config[] __initdata = {
+ GPIO1_nCS2, /* AX88796 chip select */
+ GPIO26_GPIO | MFP_PULL_HIGH /* AX88796 IRQ */
+};
+
+static void __init colibri_pxa300_init_eth(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_eth_pin_config));
+ set_irq_type(gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), IRQ_TYPE_EDGE_FALLING);
+ platform_device_register(&asix_device);
+}
+#else
+static inline void __init colibri_pxa300_init_eth(void) {}
+#endif /* CONFIG_AX88796 */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static mfp_cfg_t colibri_pxa300_usb_pin_config[] __initdata = {
+ GPIO0_2_USBH_PEN,
+ GPIO1_2_USBH_PWR,
+};
+
+static struct pxaohci_platform_data colibri_pxa300_ohci_info = {
+ .port_mode = PMM_GLOBAL_MODE,
+ .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+};
+
+void __init colibri_pxa300_init_ohci(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_usb_pin_config));
+ pxa_set_ohci_info(&colibri_pxa300_ohci_info);
+}
+#else
+static inline void colibri_pxa300_init_ohci(void) {}
+#endif /* CONFIG_USB_OHCI_HCD || CONFIG_USB_OHCI_HCD_MODULE */
+
+static mfp_cfg_t colibri_pxa300_mmc_pin_config[] __initdata = {
+ GPIO7_MMC1_CLK,
+ GPIO14_MMC1_CMD,
+ GPIO3_MMC1_DAT0,
+ GPIO4_MMC1_DAT1,
+ GPIO5_MMC1_DAT2,
+ GPIO6_MMC1_DAT3,
+};
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static mfp_cfg_t colibri_pxa300_lcd_pin_config[] __initdata = {
+ GPIO54_LCD_LDD_0,
+ GPIO55_LCD_LDD_1,
+ GPIO56_LCD_LDD_2,
+ GPIO57_LCD_LDD_3,
+ GPIO58_LCD_LDD_4,
+ GPIO59_LCD_LDD_5,
+ GPIO60_LCD_LDD_6,
+ GPIO61_LCD_LDD_7,
+ GPIO62_LCD_LDD_8,
+ GPIO63_LCD_LDD_9,
+ GPIO64_LCD_LDD_10,
+ GPIO65_LCD_LDD_11,
+ GPIO66_LCD_LDD_12,
+ GPIO67_LCD_LDD_13,
+ GPIO68_LCD_LDD_14,
+ GPIO69_LCD_LDD_15,
+ GPIO70_LCD_LDD_16,
+ GPIO71_LCD_LDD_17,
+ GPIO62_LCD_CS_N,
+ GPIO72_LCD_FCLK,
+ GPIO73_LCD_LCLK,
+ GPIO74_LCD_PCLK,
+ GPIO75_LCD_BIAS,
+ GPIO76_LCD_VSYNC,
+};
+
+static void __init colibri_pxa300_init_lcd(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_lcd_pin_config));
+}
+
+#else
+static inline void colibri_pxa300_init_lcd(void) {}
+#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */
+
+#if defined(SND_AC97_CODEC) || defined(SND_AC97_CODEC_MODULE)
+static mfp_cfg_t colibri_pxa310_ac97_pin_config[] __initdata = {
+ GPIO24_AC97_SYSCLK,
+ GPIO23_AC97_nACRESET,
+ GPIO25_AC97_SDATA_IN_0,
+ GPIO27_AC97_SDATA_OUT,
+ GPIO28_AC97_SYNC,
+ GPIO29_AC97_BITCLK
+};
+
+static inline void __init colibri_pxa310_init_ac97(void)
+{
+ /* no AC97 codec on Colibri PXA300 */
+ if (!cpu_is_pxa310())
+ return;
+
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa310_ac97_pin_config));
+ pxa_set_ac97_info(NULL);
+}
+#else
+static inline void colibri_pxa310_init_ac97(void) {}
+#endif
+
+void __init colibri_pxa300_init(void)
+{
+ colibri_pxa300_init_eth();
+ colibri_pxa300_init_ohci();
+ colibri_pxa300_init_lcd();
+ colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO39_GPIO));
+ colibri_pxa310_init_ac97();
+ colibri_pxa3xx_init_mmc(ARRAY_AND_SIZE(colibri_pxa300_mmc_pin_config),
+ mfp_to_gpio(MFP_PIN_GPIO13));
+}
+
+MACHINE_START(COLIBRI300, "Toradex Colibri PXA300")
+ .phys_io = 0x40000000,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .boot_params = COLIBRI_SDRAM_BASE + 0x100,
+ .init_machine = colibri_pxa300_init,
+ .map_io = pxa_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c
new file mode 100644
index 000000000000..55b74a7a6151
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-pxa320.c
@@ -0,0 +1,187 @@
+/*
+ * arch/arm/mach-pxa/colibri-pxa320.c
+ *
+ * Support for Toradex PXA320/310 based Colibri module
+ *
+ * Daniel Mack <daniel@caiaq.de>
+ * Matthias Meier <matthias.j.meier@gmx.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <net/ax88796.h>
+
+#include <asm/mach-types.h>
+#include <asm/sizes.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa320.h>
+#include <mach/colibri.h>
+#include <mach/pxafb.h>
+#include <mach/ohci.h>
+
+#include "generic.h"
+#include "devices.h"
+
+#if defined(CONFIG_AX88796)
+#define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO36_GPIO)
+
+/*
+ * Asix AX88796 Ethernet
+ */
+static struct ax_plat_data colibri_asix_platdata = {
+ .flags = AXFLG_MAC_FROMDEV,
+ .wordlength = 2
+};
+
+static struct resource colibri_asix_resource[] = {
+ [0] = {
+ .start = PXA3xx_CS2_PHYS,
+ .end = PXA3xx_CS2_PHYS + (0x20 * 2) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
+ .end = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device asix_device = {
+ .name = "ax88796",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(colibri_asix_resource),
+ .resource = colibri_asix_resource,
+ .dev = {
+ .platform_data = &colibri_asix_platdata
+ }
+};
+
+static mfp_cfg_t colibri_pxa320_eth_pin_config[] __initdata = {
+ GPIO3_nCS2, /* AX88796 chip select */
+ GPIO36_GPIO | MFP_PULL_HIGH /* AX88796 IRQ */
+};
+
+static void __init colibri_pxa320_init_eth(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_eth_pin_config));
+ set_irq_type(gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), IRQ_TYPE_EDGE_FALLING);
+ platform_device_register(&asix_device);
+}
+#else
+static inline void __init colibri_pxa320_init_eth(void) {}
+#endif /* CONFIG_AX88796 */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static mfp_cfg_t colibri_pxa320_usb_pin_config[] __initdata = {
+ GPIO2_2_USBH_PEN,
+ GPIO3_2_USBH_PWR,
+};
+
+static struct pxaohci_platform_data colibri_pxa320_ohci_info = {
+ .port_mode = PMM_GLOBAL_MODE,
+ .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+};
+
+void __init colibri_pxa320_init_ohci(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_usb_pin_config));
+ pxa_set_ohci_info(&colibri_pxa320_ohci_info);
+}
+#else
+static inline void colibri_pxa320_init_ohci(void) {}
+#endif /* CONFIG_USB_OHCI_HCD || CONFIG_USB_OHCI_HCD_MODULE */
+
+static mfp_cfg_t colibri_pxa320_mmc_pin_config[] __initdata = {
+ GPIO22_MMC1_CLK,
+ GPIO23_MMC1_CMD,
+ GPIO18_MMC1_DAT0,
+ GPIO19_MMC1_DAT1,
+ GPIO20_MMC1_DAT2,
+ GPIO21_MMC1_DAT3
+};
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static mfp_cfg_t colibri_pxa320_lcd_pin_config[] __initdata = {
+ GPIO6_2_LCD_LDD_0,
+ GPIO7_2_LCD_LDD_1,
+ GPIO8_2_LCD_LDD_2,
+ GPIO9_2_LCD_LDD_3,
+ GPIO10_2_LCD_LDD_4,
+ GPIO11_2_LCD_LDD_5,
+ GPIO12_2_LCD_LDD_6,
+ GPIO13_2_LCD_LDD_7,
+ GPIO63_LCD_LDD_8,
+ GPIO64_LCD_LDD_9,
+ GPIO65_LCD_LDD_10,
+ GPIO66_LCD_LDD_11,
+ GPIO67_LCD_LDD_12,
+ GPIO68_LCD_LDD_13,
+ GPIO69_LCD_LDD_14,
+ GPIO70_LCD_LDD_15,
+ GPIO71_LCD_LDD_16,
+ GPIO72_LCD_LDD_17,
+ GPIO73_LCD_CS_N,
+ GPIO74_LCD_VSYNC,
+ GPIO14_2_LCD_FCLK,
+ GPIO15_2_LCD_LCLK,
+ GPIO16_2_LCD_PCLK,
+ GPIO17_2_LCD_BIAS,
+};
+
+static void __init colibri_pxa320_init_lcd(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_lcd_pin_config));
+}
+#else
+static inline void colibri_pxa320_init_lcd(void) {}
+#endif
+
+#if defined(SND_AC97_CODEC) || defined(SND_AC97_CODEC_MODULE)
+static mfp_cfg_t colibri_pxa320_ac97_pin_config[] __initdata = {
+ GPIO34_AC97_SYSCLK,
+ GPIO35_AC97_SDATA_IN_0,
+ GPIO37_AC97_SDATA_OUT,
+ GPIO38_AC97_SYNC,
+ GPIO39_AC97_BITCLK,
+ GPIO40_AC97_nACRESET
+};
+
+static inline void __init colibri_pxa320_init_ac97(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_ac97_pin_config));
+ pxa_set_ac97_info(NULL);
+}
+#else
+static inline void colibri_pxa320_init_ac97(void) {}
+#endif
+
+void __init colibri_pxa320_init(void)
+{
+ colibri_pxa320_init_eth();
+ colibri_pxa320_init_ohci();
+ colibri_pxa320_init_lcd();
+ colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO49_GPIO));
+ colibri_pxa320_init_ac97();
+ colibri_pxa3xx_init_mmc(ARRAY_AND_SIZE(colibri_pxa320_mmc_pin_config),
+ mfp_to_gpio(MFP_PIN_GPIO28));
+}
+
+MACHINE_START(COLIBRI320, "Toradex Colibri PXA320")
+ .phys_io = 0x40000000,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .boot_params = COLIBRI_SDRAM_BASE + 0x100,
+ .init_machine = colibri_pxa320_init,
+ .map_io = pxa_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c
new file mode 100644
index 000000000000..12d0afc54aa5
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-pxa3xx.c
@@ -0,0 +1,121 @@
+/*
+ * arch/arm/mach-pxa/colibri-pxa3xx.c
+ *
+ * Common functions for all Toradex PXA3xx modules
+ *
+ * Daniel Mack <daniel@caiaq.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/sizes.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa300.h>
+#include <mach/colibri.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+
+#include "generic.h"
+#include "devices.h"
+
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static int mmc_detect_pin;
+
+static int colibri_pxa3xx_mci_init(struct device *dev,
+ irq_handler_t colibri_mmc_detect_int,
+ void *data)
+{
+ int ret;
+
+ ret = gpio_request(mmc_detect_pin, "mmc card detect");
+ if (ret)
+ return ret;
+
+ gpio_direction_input(mmc_detect_pin);
+ ret = request_irq(gpio_to_irq(mmc_detect_pin), colibri_mmc_detect_int,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "MMC card detect", data);
+ if (ret) {
+ gpio_free(mmc_detect_pin);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void colibri_pxa3xx_mci_exit(struct device *dev, void *data)
+{
+ free_irq(mmc_detect_pin, data);
+ gpio_free(gpio_to_irq(mmc_detect_pin));
+}
+
+static struct pxamci_platform_data colibri_pxa3xx_mci_platform_data = {
+ .detect_delay = 20,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .init = colibri_pxa3xx_mci_init,
+ .exit = colibri_pxa3xx_mci_exit,
+};
+
+void __init colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin)
+{
+ pxa3xx_mfp_config(pins, len);
+ mmc_detect_pin = detect_pin;
+ pxa_set_mci_info(&colibri_pxa3xx_mci_platform_data);
+}
+#endif /* CONFIG_MMC_PXA || CONFIG_MMC_PXA_MODULE */
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static int lcd_bl_pin;
+
+/*
+ * LCD panel (Sharp LQ043T3DX02)
+ */
+static void colibri_lcd_backlight(int on)
+{
+ gpio_set_value(lcd_bl_pin, !!on);
+}
+
+static struct pxafb_mode_info sharp_lq43_mode = {
+ .pixclock = 101936,
+ .xres = 480,
+ .yres = 272,
+ .bpp = 32,
+ .depth = 18,
+ .hsync_len = 41,
+ .left_margin = 2,
+ .right_margin = 2,
+ .vsync_len = 10,
+ .upper_margin = 2,
+ .lower_margin = 2,
+ .sync = 0,
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info sharp_lq43_info = {
+ .modes = &sharp_lq43_mode,
+ .num_modes = 1,
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+ .lcd_conn = LCD_COLOR_TFT_18BPP,
+ .pxafb_backlight_power = colibri_lcd_backlight,
+};
+
+void __init colibri_pxa3xx_init_lcd(int bl_pin)
+{
+ lcd_bl_pin = bl_pin;
+ gpio_request(bl_pin, "lcd backlight");
+ gpio_direction_output(bl_pin, 0);
+ set_pxa_fb_info(&sharp_lq43_info);
+}
+#endif
+
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index a8d91b6c136b..cdf21dd135b4 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -41,9 +41,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include <mach/pxa25x.h>
#include <mach/i2c.h>
#include <mach/irda.h>
#include <mach/mmc.h>
@@ -637,16 +635,16 @@ static void corgi_poweroff(void)
/* Green LED off tells the bootloader to halt */
gpio_set_value(CORGI_GPIO_LED_GREEN, 0);
- arm_machine_restart('h');
+ arm_machine_restart('h', NULL);
}
-static void corgi_restart(char mode)
+static void corgi_restart(char mode, const char *cmd)
{
if (!machine_is_corgi())
/* Green LED on tells the bootloader to reboot */
gpio_set_value(CORGI_GPIO_LED_GREEN, 1);
- arm_machine_restart('h');
+ arm_machine_restart('h', cmd);
}
static void __init corgi_init(void)
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
index 411607bc1fc2..d9b96319d498 100644
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -22,7 +22,6 @@
#include <linux/string.h>
#include <mach/corgi.h>
#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/sharpsl.h>
#include <mach/spitz.h>
#include <asm/hardware/scoop.h>
diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
index e35259032813..7f04b3a761d1 100644
--- a/arch/arm/mach-pxa/corgi_pm.c
+++ b/arch/arm/mach-pxa/corgi_pm.c
@@ -24,7 +24,6 @@
#include <mach/sharpsl.h>
#include <mach/corgi.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-regs.h>
#include <mach/pxa2xx-gpio.h>
#include "sharpsl.h"
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index 8e2f2215c4ba..a5ee70735e04 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -20,7 +20,6 @@
#include <asm/mach-types.h>
#include <mach/ssp.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-gpio.h>
#include <mach/regs-ssp.h>
#include "sharpsl.h"
diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
index 771dd4eac935..083a1d851d49 100644
--- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c
+++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
@@ -37,8 +37,6 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-regs.h>
#ifdef DEBUG
diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
index 968c8309ec37..67f34a8d8e60 100644
--- a/arch/arm/mach-pxa/cpufreq-pxa3xx.c
+++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
@@ -15,8 +15,6 @@
#include <linux/init.h>
#include <linux/cpufreq.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa3xx-regs.h>
#include "generic.h"
diff --git a/arch/arm/mach-pxa/csb701.c b/arch/arm/mach-pxa/csb701.c
new file mode 100644
index 000000000000..4a2a2952c374
--- /dev/null
+++ b/arch/arm/mach-pxa/csb701.c
@@ -0,0 +1,61 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+
+static struct gpio_keys_button csb701_buttons[] = {
+ {
+ .code = 0x7,
+ .gpio = 1,
+ .active_low = 1,
+ .desc = "SW2",
+ .type = EV_SW,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data csb701_gpio_keys_data = {
+ .buttons = csb701_buttons,
+ .nbuttons = ARRAY_SIZE(csb701_buttons),
+};
+
+static struct gpio_led csb701_leds[] = {
+ {
+ .name = "csb701:yellow:heartbeat",
+ .default_trigger = "heartbeat",
+ .gpio = 11,
+ .active_low = 1,
+ },
+};
+
+static struct platform_device csb701_gpio_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev.platform_data = &csb701_gpio_keys_data,
+};
+
+static struct gpio_led_platform_data csb701_leds_gpio_data = {
+ .leds = csb701_leds,
+ .num_leds = ARRAY_SIZE(csb701_leds),
+};
+
+static struct platform_device csb701_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &csb701_leds_gpio_data,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &csb701_gpio_keys,
+ &csb701_leds_gpio,
+};
+
+static int __init csb701_init(void)
+{
+ return platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+module_init(csb701_init);
+
diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c
new file mode 100644
index 000000000000..2b289f83a61a
--- /dev/null
+++ b/arch/arm/mach-pxa/csb726.c
@@ -0,0 +1,318 @@
+/*
+ * Support for Cogent CSB726
+ *
+ * Copyright (c) 2008 Dmitry Eremin-Solenikov
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <linux/sm501.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/csb726.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/i2c.h>
+#include <mach/mmc.h>
+#include <mach/ohci.h>
+#include <mach/pxa2xx-regs.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/*
+ * n/a: 2, 5, 6, 7, 8, 23, 24, 25, 26, 27, 87, 88, 89,
+ * nu: 58 -- 77, 90, 91, 93, 102, 105-108, 114-116,
+ * XXX: 21,
+ * XXX: 79 CS_3 for LAN9215 or PSKTSEL on R2, R3
+ * XXX: 33 CS_5 for LAN9215 on R1
+ */
+
+static unsigned long csb726_pin_config[] = {
+ GPIO78_nCS_2, /* EXP_CS */
+ GPIO79_nCS_3, /* SMSC9215 */
+ GPIO80_nCS_4, /* SM501 */
+
+ GPIO52_GPIO, /* #SMSC9251 int */
+ GPIO53_GPIO, /* SM501 int */
+
+ GPIO1_GPIO, /* GPIO0 */
+ GPIO11_GPIO, /* GPIO1 */
+ GPIO9_GPIO, /* GPIO2 */
+ GPIO10_GPIO, /* GPIO3 */
+ GPIO16_PWM0_OUT, /* or GPIO4 */
+ GPIO17_PWM1_OUT, /* or GPIO5 */
+ GPIO94_GPIO, /* GPIO6 */
+ GPIO95_GPIO, /* GPIO7 */
+ GPIO96_GPIO, /* GPIO8 */
+ GPIO97_GPIO, /* GPIO9 */
+ GPIO15_GPIO, /* EXP_IRQ */
+ GPIO18_RDY, /* EXP_WAIT */
+
+ GPIO0_GPIO, /* PWR_INT */
+ GPIO104_GPIO, /* PWR_OFF */
+
+ GPIO12_GPIO, /* touch irq */
+
+ GPIO13_SSP2_TXD,
+ GPIO14_SSP2_SFRM,
+ MFP_CFG_OUT(GPIO19, AF1, DRIVE_LOW),/* SSP2_SYSCLK */
+ GPIO22_SSP2_SCLK,
+
+ GPIO81_SSP3_TXD,
+ GPIO82_SSP3_RXD,
+ GPIO83_SSP3_SFRM,
+ GPIO84_SSP3_SCLK,
+
+ GPIO20_GPIO, /* SDIO int */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO100_GPIO, /* SD CD */
+ GPIO101_GPIO, /* SD WP */
+
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO113_AC97_nRESET,
+
+ GPIO34_FFUART_RXD,
+ GPIO35_FFUART_CTS,
+ GPIO36_FFUART_DCD,
+ GPIO37_FFUART_DSR,
+ GPIO38_FFUART_RI,
+ GPIO39_FFUART_TXD,
+ GPIO40_FFUART_DTR,
+ GPIO41_FFUART_RTS,
+
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO54_nPCE_2,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16, /* maybe unused */
+ GPIO85_nPCE_1,
+ GPIO98_GPIO, /* CF IRQ */
+ GPIO99_GPIO, /* CF CD */
+ GPIO103_GPIO, /* Reset */
+
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+};
+
+static struct pxamci_platform_data csb726_mci_data;
+
+static int csb726_mci_init(struct device *dev,
+ irq_handler_t detect, void *data)
+{
+ int err;
+
+ csb726_mci_data.detect_delay = msecs_to_jiffies(500);
+
+ err = gpio_request(CSB726_GPIO_MMC_DETECT, "MMC detect");
+ if (err)
+ goto err_det_req;
+
+ err = gpio_direction_input(CSB726_GPIO_MMC_DETECT);
+ if (err)
+ goto err_det_dir;
+
+ err = gpio_request(CSB726_GPIO_MMC_RO, "MMC ro");
+ if (err)
+ goto err_ro_req;
+
+ err = gpio_direction_input(CSB726_GPIO_MMC_RO);
+ if (err)
+ goto err_ro_dir;
+
+ err = request_irq(gpio_to_irq(CSB726_GPIO_MMC_DETECT), detect,
+ IRQF_DISABLED, "MMC card detect", data);
+ if (err)
+ goto err_irq;
+
+ return 0;
+
+err_irq:
+err_ro_dir:
+ gpio_free(CSB726_GPIO_MMC_RO);
+err_ro_req:
+err_det_dir:
+ gpio_free(CSB726_GPIO_MMC_DETECT);
+err_det_req:
+ return err;
+}
+
+static int csb726_mci_get_ro(struct device *dev)
+{
+ return gpio_get_value(CSB726_GPIO_MMC_RO);
+}
+
+static void csb726_mci_exit(struct device *dev, void *data)
+{
+ free_irq(gpio_to_irq(CSB726_GPIO_MMC_DETECT), data);
+ gpio_free(CSB726_GPIO_MMC_RO);
+ gpio_free(CSB726_GPIO_MMC_DETECT);
+}
+
+static struct pxamci_platform_data csb726_mci = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .init = csb726_mci_init,
+ .get_ro = csb726_mci_get_ro,
+ /* FIXME setpower */
+ .exit = csb726_mci_exit,
+};
+
+static struct pxaohci_platform_data csb726_ohci_platform_data = {
+ .port_mode = PMM_NPS_MODE,
+ .flags = ENABLE_PORT1 | NO_OC_PROTECTION,
+};
+
+static struct mtd_partition csb726_flash_partitions[] = {
+ {
+ .name = "Bootloader",
+ .offset = 0,
+ .size = CSB726_FLASH_uMON,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "root",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct physmap_flash_data csb726_flash_data = {
+ .width = 2,
+ .parts = csb726_flash_partitions,
+ .nr_parts = ARRAY_SIZE(csb726_flash_partitions),
+};
+
+static struct resource csb726_flash_resources[] = {
+ {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + CSB726_FLASH_SIZE - 1 ,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device csb726_flash = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &csb726_flash_data,
+ },
+ .resource = csb726_flash_resources,
+ .num_resources = ARRAY_SIZE(csb726_flash_resources),
+};
+
+static struct resource csb726_sm501_resources[] = {
+ {
+ .start = PXA_CS4_PHYS,
+ .end = PXA_CS4_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "sm501-localmem",
+ },
+ {
+ .start = PXA_CS4_PHYS + SZ_64M - SZ_2M,
+ .end = PXA_CS4_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "sm501-regs",
+ },
+ {
+ .start = CSB726_IRQ_SM501,
+ .end = CSB726_IRQ_SM501,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sm501_initdata csb726_sm501_initdata = {
+/* .devices = SM501_USE_USB_HOST, */
+ .devices = SM501_USE_USB_HOST | SM501_USE_UART0 | SM501_USE_UART1,
+};
+
+static struct sm501_platdata csb726_sm501_platdata = {
+ .init = &csb726_sm501_initdata,
+};
+
+static struct platform_device csb726_sm501 = {
+ .name = "sm501",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(csb726_sm501_resources),
+ .resource = csb726_sm501_resources,
+ .dev = {
+ .platform_data = &csb726_sm501_platdata,
+ },
+};
+
+static struct resource csb726_lan_resources[] = {
+ {
+ .start = PXA_CS3_PHYS,
+ .end = PXA_CS3_PHYS + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = CSB726_IRQ_LAN,
+ .end = CSB726_IRQ_LAN,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device csb726_lan = {
+ .name = "smc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(csb726_lan_resources),
+ .resource = csb726_lan_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &csb726_flash,
+ &csb726_sm501,
+ &csb726_lan,
+};
+
+static void __init csb726_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(csb726_pin_config));
+/* MSC1 = 0x7ffc3ffc; *//* LAN9215/EXP_CS */
+/* MSC2 = 0x06697ff4; *//* none/SM501 */
+ MSC2 = (MSC2 & ~0xffff) | 0x7ff4; /* SM501 */
+
+ pxa_set_i2c_info(NULL);
+ pxa27x_set_i2c_power_info(NULL);
+ pxa_set_mci_info(&csb726_mci);
+ pxa_set_ohci_info(&csb726_ohci_platform_data);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(CSB726, "Cogent CSB726")
+ .phys_io = 0x40000000,
+ .boot_params = 0xa0000100,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .map_io = pxa_map_io,
+ .init_irq = pxa27x_init_irq,
+ .init_machine = csb726_init,
+ .timer = &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index e16f8e3d58d3..d245e59c51b1 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -4,7 +4,6 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <mach/pxa-regs.h>
#include <mach/udc.h>
#include <mach/pxafb.h>
#include <mach/mmc.h>
diff --git a/arch/arm/mach-pxa/e330.c b/arch/arm/mach-pxa/e330.c
index 1bd7f740427c..74d3f8987c5c 100644
--- a/arch/arm/mach-pxa/e330.c
+++ b/arch/arm/mach-pxa/e330.c
@@ -20,9 +20,7 @@
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
-#include <mach/mfp-pxa25x.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa25x.h>
#include <mach/eseries-gpio.h>
#include <mach/udc.h>
diff --git a/arch/arm/mach-pxa/e350.c b/arch/arm/mach-pxa/e350.c
index edcd9d5ce545..080036272131 100644
--- a/arch/arm/mach-pxa/e350.c
+++ b/arch/arm/mach-pxa/e350.c
@@ -21,9 +21,7 @@
#include <asm/mach-types.h>
#include <mach/irqs.h>
-#include <mach/mfp-pxa25x.h>
-#include <mach/pxa-regs.h>
-#include <mach/hardware.h>
+#include <mach/pxa25x.h>
#include <mach/eseries-gpio.h>
#include <mach/udc.h>
diff --git a/arch/arm/mach-pxa/e400.c b/arch/arm/mach-pxa/e400.c
index 77bb8e2c48c0..ed9c0c3f64a2 100644
--- a/arch/arm/mach-pxa/e400.c
+++ b/arch/arm/mach-pxa/e400.c
@@ -22,9 +22,7 @@
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
-#include <mach/mfp-pxa25x.h>
-#include <mach/pxa-regs.h>
-#include <mach/hardware.h>
+#include <mach/pxa25x.h>
#include <mach/eseries-gpio.h>
#include <mach/pxafb.h>
#include <mach/udc.h>
diff --git a/arch/arm/mach-pxa/e740.c b/arch/arm/mach-pxa/e740.c
index 6d48e00f4f0b..07500a04fd8c 100644
--- a/arch/arm/mach-pxa/e740.c
+++ b/arch/arm/mach-pxa/e740.c
@@ -24,9 +24,7 @@
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
-#include <mach/mfp-pxa25x.h>
-#include <mach/pxa-regs.h>
-#include <mach/hardware.h>
+#include <mach/pxa25x.h>
#include <mach/eseries-gpio.h>
#include <mach/udc.h>
#include <mach/irda.h>
@@ -135,6 +133,11 @@ static unsigned long e740_pin_config[] __initdata = {
/* IrDA */
GPIO38_GPIO | MFP_LPM_DRIVE_HIGH,
+ /* Audio power control */
+ GPIO16_GPIO, /* AC97 codec AVDD2 supply (analogue power) */
+ GPIO40_GPIO, /* Mic amp power */
+ GPIO41_GPIO, /* Headphone amp power */
+
/* PC Card */
GPIO8_GPIO, /* CD0 */
GPIO44_GPIO, /* CD1 */
@@ -189,7 +192,7 @@ static void __init e740_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(e740_pin_config));
eseries_register_clks();
- clk_add_alias("CLK_CK48M", &e740_t7l66xb_device.dev,
+ clk_add_alias("CLK_CK48M", e740_t7l66xb_device.name,
"UDCCLK", &pxa25x_device_udc.dev),
eseries_get_tmio_gpios();
platform_add_devices(devices, ARRAY_SIZE(devices));
diff --git a/arch/arm/mach-pxa/e750.c b/arch/arm/mach-pxa/e750.c
index be1ab8edb973..6126c04e02bc 100644
--- a/arch/arm/mach-pxa/e750.c
+++ b/arch/arm/mach-pxa/e750.c
@@ -23,9 +23,7 @@
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
-#include <mach/mfp-pxa25x.h>
-#include <mach/pxa-regs.h>
-#include <mach/hardware.h>
+#include <mach/pxa25x.h>
#include <mach/eseries-gpio.h>
#include <mach/udc.h>
#include <mach/irda.h>
@@ -133,6 +131,11 @@ static unsigned long e750_pin_config[] __initdata = {
/* IrDA */
GPIO38_GPIO | MFP_LPM_DRIVE_HIGH,
+ /* Audio power control */
+ GPIO4_GPIO, /* Headphone amp power */
+ GPIO7_GPIO, /* Speaker amp power */
+ GPIO37_GPIO, /* Headphone detect */
+
/* PC Card */
GPIO8_GPIO, /* CD0 */
GPIO44_GPIO, /* CD1 */
@@ -190,7 +193,7 @@ static struct platform_device *devices[] __initdata = {
static void __init e750_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(e750_pin_config));
- clk_add_alias("CLK_CK3P6MI", &e750_tc6393xb_device.dev,
+ clk_add_alias("CLK_CK3P6MI", e750_tc6393xb_device.name,
"GPIO11_CLK", NULL),
eseries_get_tmio_gpios();
platform_add_devices(devices, ARRAY_SIZE(devices));
diff --git a/arch/arm/mach-pxa/e800.c b/arch/arm/mach-pxa/e800.c
index cc9b1293e866..74ab09812a72 100644
--- a/arch/arm/mach-pxa/e800.c
+++ b/arch/arm/mach-pxa/e800.c
@@ -23,9 +23,7 @@
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
-#include <mach/mfp-pxa25x.h>
-#include <mach/pxa-regs.h>
-#include <mach/hardware.h>
+#include <mach/pxa25x.h>
#include <mach/eseries-gpio.h>
#include <mach/udc.h>
#include <mach/irqs.h>
@@ -196,7 +194,7 @@ static struct platform_device *devices[] __initdata = {
static void __init e800_init(void)
{
- clk_add_alias("CLK_CK3P6MI", &e800_tc6393xb_device.dev,
+ clk_add_alias("CLK_CK3P6MI", e800_tc6393xb_device.name,
"GPIO11_CLK", NULL),
eseries_get_tmio_gpios();
platform_add_devices(devices, ARRAY_SIZE(devices));
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index f5ed8038ede5..920dfb8d36da 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -11,40 +11,63 @@
#include <linux/irq.h>
#include <linux/platform_device.h>
+#include <linux/delay.h>
#include <linux/dm9000.h>
#include <linux/rtc-v3020.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/gpio.h>
+#include <linux/mfd/da903x.h>
+#include <linux/regulator/machine.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/tdo24m.h>
+#include <linux/power_supply.h>
+#include <linux/apm-emulation.h>
+
+#include <media/soc_camera.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/mfp-pxa27x.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa27x.h>
#include <mach/pxa27x-udc.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
#include <mach/ohci.h>
#include <mach/mmc.h>
#include <mach/pxa27x_keypad.h>
+#include <mach/i2c.h>
+#include <mach/camera.h>
+#include <mach/pxa2xx_spi.h>
#include "generic.h"
+#include "devices.h"
-/* GPIO IRQ usage */
-#define GPIO41_ETHIRQ (41)
+/* EM-X270 specific GPIOs */
#define GPIO13_MMC_CD (13)
+#define GPIO95_MMC_WP (95)
+#define GPIO56_NAND_RB (56)
+
+/* eXeda specific GPIOs */
+#define GPIO114_MMC_CD (114)
+#define GPIO20_NAND_RB (20)
+#define GPIO38_SD_PWEN (38)
+
+/* common GPIOs */
+#define GPIO11_NAND_CS (11)
+#define GPIO93_CAM_RESET (93)
+#define GPIO41_ETHIRQ (41)
#define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ)
-#define EM_X270_MMC_CD IRQ_GPIO(GPIO13_MMC_CD)
-/* NAND control GPIOs */
-#define GPIO11_NAND_CS (11)
-#define GPIO56_NAND_RB (56)
+static int mmc_cd;
+static int nand_rb;
+static int dm9000_flags;
-static unsigned long em_x270_pin_config[] = {
+static unsigned long common_pin_config[] = {
/* AC'97 */
GPIO28_AC97_BITCLK,
GPIO29_AC97_SDATA_IN_0,
@@ -150,21 +173,32 @@ static unsigned long em_x270_pin_config[] = {
GPIO18_RDY,
/* GPIO */
- GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
+ GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, /* sleep/resume button */
/* power controls */
GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */
+ GPIO93_GPIO | MFP_LPM_DRIVE_LOW, /* Camera reset */
GPIO115_GPIO | MFP_LPM_DRIVE_LOW, /* WLAN_PWEN */
/* NAND controls */
GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */
- GPIO56_GPIO, /* NAND Ready/Busy */
/* interrupts */
- GPIO13_GPIO, /* MMC card detect */
GPIO41_GPIO, /* DM9000 interrupt */
};
+static unsigned long em_x270_pin_config[] = {
+ GPIO13_GPIO, /* MMC card detect */
+ GPIO56_GPIO, /* NAND Ready/Busy */
+ GPIO95_GPIO, /* MMC Write protect */
+};
+
+static unsigned long exeda_pin_config[] = {
+ GPIO20_GPIO, /* NAND Ready/Busy */
+ GPIO38_GPIO | MFP_LPM_DRIVE_LOW, /* SD slot power */
+ GPIO114_GPIO, /* MMC card detect */
+};
+
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
static struct resource em_x270_dm9000_resource[] = {
[0] = {
@@ -185,7 +219,7 @@ static struct resource em_x270_dm9000_resource[] = {
};
static struct dm9000_plat_data em_x270_dm9000_platdata = {
- .flags = DM9000_PLATF_32BITONLY,
+ .flags = DM9000_PLATF_NO_EEPROM,
};
static struct platform_device em_x270_dm9000 = {
@@ -200,6 +234,7 @@ static struct platform_device em_x270_dm9000 = {
static void __init em_x270_init_dm9000(void)
{
+ em_x270_dm9000_platdata.flags |= dm9000_flags;
platform_device_register(&em_x270_dm9000);
}
#else
@@ -289,7 +324,7 @@ static int em_x270_nand_device_ready(struct mtd_info *mtd)
{
dsb();
- return gpio_get_value(GPIO56_NAND_RB);
+ return gpio_get_value(nand_rb);
}
static struct mtd_partition em_x270_partition_info[] = {
@@ -354,14 +389,14 @@ static void __init em_x270_init_nand(void)
gpio_direction_output(GPIO11_NAND_CS, 1);
- err = gpio_request(GPIO56_NAND_RB, "NAND R/B");
+ err = gpio_request(nand_rb, "NAND R/B");
if (err) {
pr_warning("EM-X270: failed to request NAND R/B gpio\n");
gpio_free(GPIO11_NAND_CS);
return;
}
- gpio_direction_input(GPIO56_NAND_RB);
+ gpio_direction_input(nand_rb);
platform_device_register(&em_x270_nand);
}
@@ -369,6 +404,61 @@ static void __init em_x270_init_nand(void)
static inline void em_x270_init_nand(void) {}
#endif
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition em_x270_nor_parts[] = {
+ {
+ .name = "Bootloader",
+ .offset = 0x00000000,
+ .size = 0x00050000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ }, {
+ .name = "Environment",
+ .offset = 0x00050000,
+ .size = 0x00010000,
+ }, {
+ .name = "Reserved",
+ .offset = 0x00060000,
+ .size = 0x00050000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ }, {
+ .name = "Splashscreen",
+ .offset = 0x000b0000,
+ .size = 0x00050000,
+ }
+};
+
+static struct physmap_flash_data em_x270_nor_data[] = {
+ [0] = {
+ .width = 2,
+ .parts = em_x270_nor_parts,
+ .nr_parts = ARRAY_SIZE(em_x270_nor_parts),
+ },
+};
+
+static struct resource em_x270_nor_flash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device em_x270_physmap_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .num_resources = 1,
+ .resource = &em_x270_nor_flash_resource,
+ .dev = {
+ .platform_data = &em_x270_nor_data,
+ },
+};
+
+static void __init em_x270_init_nor(void)
+{
+ platform_device_register(&em_x270_physmap_flash);
+}
+#else
+static inline void em_x270_init_nor(void) {}
+#endif
+
/* PXA27x OHCI controller setup */
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
static int em_x270_ohci_init(struct device *dev)
@@ -395,40 +485,93 @@ static inline void em_x270_init_ohci(void) {}
/* MCI controller setup */
#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
+static struct regulator *em_x270_sdio_ldo;
+
static int em_x270_mci_init(struct device *dev,
irq_handler_t em_x270_detect_int,
void *data)
{
- int err = request_irq(EM_X270_MMC_CD, em_x270_detect_int,
- IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ int err;
+
+ em_x270_sdio_ldo = regulator_get(dev, "vcc sdio");
+ if (IS_ERR(em_x270_sdio_ldo)) {
+ dev_err(dev, "can't request SDIO power supply: %ld\n",
+ PTR_ERR(em_x270_sdio_ldo));
+ return PTR_ERR(em_x270_sdio_ldo);
+ }
+
+ err = request_irq(gpio_to_irq(mmc_cd), em_x270_detect_int,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING,
"MMC card detect", data);
if (err) {
- printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n",
- __func__, err);
- return err;
+ dev_err(dev, "can't request MMC card detect IRQ: %d\n", err);
+ goto err_irq;
+ }
+
+ if (machine_is_em_x270()) {
+ err = gpio_request(GPIO95_MMC_WP, "MMC WP");
+ if (err) {
+ dev_err(dev, "can't request MMC write protect: %d\n",
+ err);
+ goto err_gpio_wp;
+ }
+ gpio_direction_input(GPIO95_MMC_WP);
+ } else {
+ err = gpio_request(GPIO38_SD_PWEN, "sdio power");
+ if (err) {
+ dev_err(dev, "can't request MMC power control : %d\n",
+ err);
+ goto err_gpio_wp;
+ }
+ gpio_direction_output(GPIO38_SD_PWEN, 1);
}
return 0;
+
+err_gpio_wp:
+ free_irq(gpio_to_irq(mmc_cd), data);
+err_irq:
+ regulator_put(em_x270_sdio_ldo);
+
+ return err;
}
static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
{
- /*
- FIXME: current hardware implementation does not allow to
- enable/disable MMC power. This will be fixed in next HW releases,
- and we'll need to add implmentation here.
- */
- return;
+ struct pxamci_platform_data* p_d = dev->platform_data;
+
+ if ((1 << vdd) & p_d->ocr_mask) {
+ int vdd_uV = (2000 + (vdd - __ffs(MMC_VDD_20_21)) * 100) * 1000;
+
+ regulator_set_voltage(em_x270_sdio_ldo, vdd_uV, vdd_uV);
+ regulator_enable(em_x270_sdio_ldo);
+ } else {
+ regulator_disable(em_x270_sdio_ldo);
+ }
}
static void em_x270_mci_exit(struct device *dev, void *data)
{
- int irq = gpio_to_irq(GPIO13_MMC_CD);
- free_irq(irq, data);
+ free_irq(gpio_to_irq(mmc_cd), data);
+ regulator_put(em_x270_sdio_ldo);
+
+ if (machine_is_em_x270())
+ gpio_free(GPIO95_MMC_WP);
+ else
+ gpio_free(GPIO38_SD_PWEN);
+}
+
+static int em_x270_mci_get_ro(struct device *dev)
+{
+ return gpio_get_value(GPIO95_MMC_WP);
}
static struct pxamci_platform_data em_x270_mci_platform_data = {
- .ocr_mask = MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31,
+ .ocr_mask = MMC_VDD_20_21|MMC_VDD_21_22|MMC_VDD_22_23|
+ MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27|
+ MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
+ MMC_VDD_30_31|MMC_VDD_31_32,
.init = em_x270_mci_init,
.setpower = em_x270_mci_setpower,
.exit = em_x270_mci_exit,
@@ -436,33 +579,53 @@ static struct pxamci_platform_data em_x270_mci_platform_data = {
static void __init em_x270_init_mmc(void)
{
+ if (machine_is_em_x270())
+ em_x270_mci_platform_data.get_ro = em_x270_mci_get_ro;
+
+ em_x270_mci_platform_data.detect_delay = msecs_to_jiffies(250);
pxa_set_mci_info(&em_x270_mci_platform_data);
}
#else
static inline void em_x270_init_mmc(void) {}
#endif
-/* LCD 480x640 */
+/* LCD */
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
-static struct pxafb_mode_info em_x270_lcd_mode = {
- .pixclock = 50000,
- .bpp = 16,
- .xres = 480,
- .yres = 640,
- .hsync_len = 8,
- .vsync_len = 2,
- .left_margin = 8,
- .upper_margin = 0,
- .right_margin = 24,
- .lower_margin = 4,
- .cmap_greyscale = 0,
+static struct pxafb_mode_info em_x270_lcd_modes[] = {
+ [0] = {
+ .pixclock = 38250,
+ .bpp = 16,
+ .xres = 480,
+ .yres = 640,
+ .hsync_len = 8,
+ .vsync_len = 2,
+ .left_margin = 8,
+ .upper_margin = 2,
+ .right_margin = 24,
+ .lower_margin = 4,
+ .sync = 0,
+ },
+ [1] = {
+ .pixclock = 153800,
+ .bpp = 16,
+ .xres = 240,
+ .yres = 320,
+ .hsync_len = 8,
+ .vsync_len = 2,
+ .left_margin = 8,
+ .upper_margin = 2,
+ .right_margin = 88,
+ .lower_margin = 2,
+ .sync = 0,
+ },
};
static struct pxafb_mach_info em_x270_lcd = {
- .modes = &em_x270_lcd_mode,
- .num_modes = 1,
+ .modes = em_x270_lcd_modes,
+ .num_modes = 2,
.lcd_conn = LCD_COLOR_TFT_16BPP,
};
+
static void __init em_x270_init_lcd(void)
{
set_pxa_fb_info(&em_x270_lcd);
@@ -471,6 +634,40 @@ static void __init em_x270_init_lcd(void)
static inline void em_x270_init_lcd(void) {}
#endif
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
+static struct pxa2xx_spi_master em_x270_spi_info = {
+ .num_chipselect = 1,
+};
+
+static struct pxa2xx_spi_chip em_x270_tdo24m_chip = {
+ .rx_threshold = 1,
+ .tx_threshold = 1,
+};
+
+static struct tdo24m_platform_data em_x270_tdo24m_pdata = {
+ .model = TDO35S,
+};
+
+static struct spi_board_info em_x270_spi_devices[] __initdata = {
+ {
+ .modalias = "tdo24m",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .controller_data = &em_x270_tdo24m_chip,
+ .platform_data = &em_x270_tdo24m_pdata,
+ },
+};
+
+static void __init em_x270_init_spi(void)
+{
+ pxa2xx_set_spi_info(1, &em_x270_spi_info);
+ spi_register_board_info(ARRAY_AND_SIZE(em_x270_spi_devices));
+}
+#else
+static inline void em_x270_init_spi(void) {}
+#endif
+
#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE)
static void __init em_x270_init_ac97(void)
{
@@ -481,23 +678,76 @@ static inline void em_x270_init_ac97(void) {}
#endif
#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
-static unsigned int em_x270_matrix_keys[] = {
+static unsigned int em_x270_module_matrix_keys[] = {
KEY(0, 0, KEY_A), KEY(1, 0, KEY_UP), KEY(2, 1, KEY_B),
KEY(0, 2, KEY_LEFT), KEY(1, 1, KEY_ENTER), KEY(2, 0, KEY_RIGHT),
KEY(0, 1, KEY_C), KEY(1, 2, KEY_DOWN), KEY(2, 2, KEY_D),
};
-struct pxa27x_keypad_platform_data em_x270_keypad_info = {
+struct pxa27x_keypad_platform_data em_x270_module_keypad_info = {
/* code map for the matrix keys */
.matrix_key_rows = 3,
.matrix_key_cols = 3,
- .matrix_key_map = em_x270_matrix_keys,
- .matrix_key_map_size = ARRAY_SIZE(em_x270_matrix_keys),
+ .matrix_key_map = em_x270_module_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(em_x270_module_matrix_keys),
+};
+
+static unsigned int em_x270_exeda_matrix_keys[] = {
+ KEY(0, 0, KEY_RIGHTSHIFT), KEY(0, 1, KEY_RIGHTCTRL),
+ KEY(0, 2, KEY_RIGHTALT), KEY(0, 3, KEY_SPACE),
+ KEY(0, 4, KEY_LEFTALT), KEY(0, 5, KEY_LEFTCTRL),
+ KEY(0, 6, KEY_ENTER), KEY(0, 7, KEY_SLASH),
+
+ KEY(1, 0, KEY_DOT), KEY(1, 1, KEY_M),
+ KEY(1, 2, KEY_N), KEY(1, 3, KEY_B),
+ KEY(1, 4, KEY_V), KEY(1, 5, KEY_C),
+ KEY(1, 6, KEY_X), KEY(1, 7, KEY_Z),
+
+ KEY(2, 0, KEY_LEFTSHIFT), KEY(2, 1, KEY_SEMICOLON),
+ KEY(2, 2, KEY_L), KEY(2, 3, KEY_K),
+ KEY(2, 4, KEY_J), KEY(2, 5, KEY_H),
+ KEY(2, 6, KEY_G), KEY(2, 7, KEY_F),
+
+ KEY(3, 0, KEY_D), KEY(3, 1, KEY_S),
+ KEY(3, 2, KEY_A), KEY(3, 3, KEY_TAB),
+ KEY(3, 4, KEY_BACKSPACE), KEY(3, 5, KEY_P),
+ KEY(3, 6, KEY_O), KEY(3, 7, KEY_I),
+
+ KEY(4, 0, KEY_U), KEY(4, 1, KEY_Y),
+ KEY(4, 2, KEY_T), KEY(4, 3, KEY_R),
+ KEY(4, 4, KEY_E), KEY(4, 5, KEY_W),
+ KEY(4, 6, KEY_Q), KEY(4, 7, KEY_MINUS),
+
+ KEY(5, 0, KEY_0), KEY(5, 1, KEY_9),
+ KEY(5, 2, KEY_8), KEY(5, 3, KEY_7),
+ KEY(5, 4, KEY_6), KEY(5, 5, KEY_5),
+ KEY(5, 6, KEY_4), KEY(5, 7, KEY_3),
+
+ KEY(6, 0, KEY_2), KEY(6, 1, KEY_1),
+ KEY(6, 2, KEY_ENTER), KEY(6, 3, KEY_END),
+ KEY(6, 4, KEY_DOWN), KEY(6, 5, KEY_UP),
+ KEY(6, 6, KEY_MENU), KEY(6, 7, KEY_F1),
+
+ KEY(7, 0, KEY_LEFT), KEY(7, 1, KEY_RIGHT),
+ KEY(7, 2, KEY_BACK), KEY(7, 3, KEY_HOME),
+ KEY(7, 4, 0), KEY(7, 5, 0),
+ KEY(7, 6, 0), KEY(7, 7, 0),
+};
+
+struct pxa27x_keypad_platform_data em_x270_exeda_keypad_info = {
+ /* code map for the matrix keys */
+ .matrix_key_rows = 8,
+ .matrix_key_cols = 8,
+ .matrix_key_map = em_x270_exeda_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(em_x270_exeda_matrix_keys),
};
static void __init em_x270_init_keypad(void)
{
- pxa_set_keypad_info(&em_x270_keypad_info);
+ if (machine_is_em_x270())
+ pxa_set_keypad_info(&em_x270_module_keypad_info);
+ else
+ pxa_set_keypad_info(&em_x270_exeda_keypad_info);
}
#else
static inline void em_x270_init_keypad(void) {}
@@ -535,19 +785,264 @@ static void __init em_x270_init_gpio_keys(void)
static inline void em_x270_init_gpio_keys(void) {}
#endif
-static void __init em_x270_init(void)
+/* Quick Capture Interface and sensor setup */
+#if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
+static struct regulator *em_x270_camera_ldo;
+
+static int em_x270_sensor_init(struct device *dev)
{
+ int ret;
+
+ ret = gpio_request(GPIO93_CAM_RESET, "camera reset");
+ if (ret)
+ return ret;
+
+ gpio_direction_output(GPIO93_CAM_RESET, 0);
+
+ em_x270_camera_ldo = regulator_get(NULL, "vcc cam");
+ if (em_x270_camera_ldo == NULL) {
+ gpio_free(GPIO93_CAM_RESET);
+ return -ENODEV;
+ }
+
+ ret = regulator_enable(em_x270_camera_ldo);
+ if (ret) {
+ regulator_put(em_x270_camera_ldo);
+ gpio_free(GPIO93_CAM_RESET);
+ return ret;
+ }
+
+ gpio_set_value(GPIO93_CAM_RESET, 1);
+
+ return 0;
+}
+
+struct pxacamera_platform_data em_x270_camera_platform_data = {
+ .init = em_x270_sensor_init,
+ .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+ PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+ .mclk_10khz = 2600,
+};
+
+static int em_x270_sensor_power(struct device *dev, int on)
+{
+ int ret;
+ int is_on = regulator_is_enabled(em_x270_camera_ldo);
+
+ if (on == is_on)
+ return 0;
+
+ gpio_set_value(GPIO93_CAM_RESET, !on);
+
+ if (on)
+ ret = regulator_enable(em_x270_camera_ldo);
+ else
+ ret = regulator_disable(em_x270_camera_ldo);
+
+ if (ret)
+ return ret;
+
+ gpio_set_value(GPIO93_CAM_RESET, on);
+
+ return 0;
+}
+
+static struct soc_camera_link iclink = {
+ .bus_id = 0,
+ .power = em_x270_sensor_power,
+};
+
+static struct i2c_board_info em_x270_i2c_cam_info[] = {
+ {
+ I2C_BOARD_INFO("mt9m111", 0x48),
+ .platform_data = &iclink,
+ },
+};
+
+static struct i2c_pxa_platform_data em_x270_i2c_info = {
+ .fast_mode = 1,
+};
+
+static void __init em_x270_init_camera(void)
+{
+ pxa_set_i2c_info(&em_x270_i2c_info);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(em_x270_i2c_cam_info));
+ pxa_set_camera_info(&em_x270_camera_platform_data);
+}
+#else
+static inline void em_x270_init_camera(void) {}
+#endif
+
+/* DA9030 related initializations */
+#define REGULATOR_CONSUMER(_name, _dev, _supply) \
+ static struct regulator_consumer_supply _name##_consumers[] = { \
+ { \
+ .dev = _dev, \
+ .supply = _supply, \
+ }, \
+ }
+
+REGULATOR_CONSUMER(ldo3, NULL, "vcc gps");
+REGULATOR_CONSUMER(ldo5, NULL, "vcc cam");
+REGULATOR_CONSUMER(ldo10, &pxa_device_mci.dev, "vcc sdio");
+REGULATOR_CONSUMER(ldo12, NULL, "vcc usb");
+REGULATOR_CONSUMER(ldo19, NULL, "vcc gprs");
+
+#define REGULATOR_INIT(_ldo, _min_uV, _max_uV, _ops_mask) \
+ static struct regulator_init_data _ldo##_data = { \
+ .constraints = { \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .state_mem = { \
+ .enabled = 0, \
+ }, \
+ .valid_ops_mask = _ops_mask, \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_consumers), \
+ .consumer_supplies = _ldo##_consumers, \
+ };
+
+REGULATOR_INIT(ldo3, 3200000, 3200000, REGULATOR_CHANGE_STATUS);
+REGULATOR_INIT(ldo5, 3000000, 3000000, REGULATOR_CHANGE_STATUS);
+REGULATOR_INIT(ldo10, 2000000, 3200000,
+ REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE);
+REGULATOR_INIT(ldo12, 3000000, 3000000, REGULATOR_CHANGE_STATUS);
+REGULATOR_INIT(ldo19, 3200000, 3200000, REGULATOR_CHANGE_STATUS);
+
+struct led_info em_x270_led_info = {
+ .name = "em-x270:orange",
+ .default_trigger = "battery-charging-or-full",
+};
+
+struct power_supply_info em_x270_psy_info = {
+ .name = "LP555597P6H-FPS",
+ .technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
+ .voltage_max_design = 4200000,
+ .voltage_min_design = 3000000,
+ .use_for_apm = 1,
+};
+
+static void em_x270_battery_low(void)
+{
+ apm_queue_event(APM_LOW_BATTERY);
+}
+
+static void em_x270_battery_critical(void)
+{
+ apm_queue_event(APM_CRITICAL_SUSPEND);
+}
+
+struct da9030_battery_info em_x270_batterty_info = {
+ .battery_info = &em_x270_psy_info,
+
+ .charge_milliamp = 1000,
+ .charge_millivolt = 4200,
+
+ .vbat_low = 3600,
+ .vbat_crit = 3400,
+ .vbat_charge_start = 4100,
+ .vbat_charge_stop = 4200,
+ .vbat_charge_restart = 4000,
+
+ .vcharge_min = 3200,
+ .vcharge_max = 5500,
+
+ .tbat_low = 197,
+ .tbat_high = 78,
+ .tbat_restart = 100,
+
+ .batmon_interval = 0,
+
+ .battery_low = em_x270_battery_low,
+ .battery_critical = em_x270_battery_critical,
+};
+
+#define DA9030_SUBDEV(_name, _id, _pdata) \
+ { \
+ .name = "da903x-" #_name, \
+ .id = DA9030_ID_##_id, \
+ .platform_data = _pdata, \
+ }
+
+#define DA9030_LDO(num) DA9030_SUBDEV(regulator, LDO##num, &ldo##num##_data)
+
+struct da903x_subdev_info em_x270_da9030_subdevs[] = {
+ DA9030_LDO(3),
+ DA9030_LDO(5),
+ DA9030_LDO(10),
+ DA9030_LDO(12),
+ DA9030_LDO(19),
+
+ DA9030_SUBDEV(led, LED_PC, &em_x270_led_info),
+ DA9030_SUBDEV(backlight, WLED, &em_x270_led_info),
+ DA9030_SUBDEV(battery, BAT, &em_x270_batterty_info),
+};
+
+static struct da903x_platform_data em_x270_da9030_info = {
+ .num_subdevs = ARRAY_SIZE(em_x270_da9030_subdevs),
+ .subdevs = em_x270_da9030_subdevs,
+};
+
+static struct i2c_board_info em_x270_i2c_pmic_info = {
+ I2C_BOARD_INFO("da9030", 0x49),
+ .irq = IRQ_GPIO(0),
+ .platform_data = &em_x270_da9030_info,
+};
+
+static struct i2c_pxa_platform_data em_x270_pwr_i2c_info = {
+ .use_pio = 1,
+};
+
+static void __init em_x270_init_da9030(void)
+{
+ pxa27x_set_i2c_power_info(&em_x270_pwr_i2c_info);
+ i2c_register_board_info(1, &em_x270_i2c_pmic_info, 1);
+}
+
+static void __init em_x270_module_init(void)
+{
+ pr_info("%s\n", __func__);
pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config));
+ mmc_cd = GPIO13_MMC_CD;
+ nand_rb = GPIO56_NAND_RB;
+ dm9000_flags = DM9000_PLATF_32BITONLY;
+}
+
+static void __init em_x270_exeda_init(void)
+{
+ pr_info("%s\n", __func__);
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(exeda_pin_config));
+
+ mmc_cd = GPIO114_MMC_CD;
+ nand_rb = GPIO20_NAND_RB;
+ dm9000_flags = DM9000_PLATF_16BITONLY;
+}
+
+static void __init em_x270_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(common_pin_config));
+
+ if (machine_is_em_x270())
+ em_x270_module_init();
+ else if (machine_is_exeda())
+ em_x270_exeda_init();
+ else
+ panic("Unsupported machine: %d\n", machine_arch_type);
+
+ em_x270_init_da9030();
em_x270_init_dm9000();
em_x270_init_rtc();
em_x270_init_nand();
+ em_x270_init_nor();
em_x270_init_lcd();
em_x270_init_mmc();
em_x270_init_ohci();
em_x270_init_keypad();
em_x270_init_gpio_keys();
em_x270_init_ac97();
+ em_x270_init_camera();
+ em_x270_init_spi();
}
MACHINE_START(EM_X270, "Compulab EM-X270")
@@ -559,3 +1054,13 @@ MACHINE_START(EM_X270, "Compulab EM-X270")
.timer = &pxa_timer,
.init_machine = em_x270_init,
MACHINE_END
+
+MACHINE_START(EXEDA, "Compulab eXeda")
+ .boot_params = 0xa0000100,
+ .phys_io = 0x40000000,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .map_io = pxa_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = em_x270_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index dfce7d5b659e..c60dadf847a6 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -20,8 +20,7 @@
#include <asm/mach/arch.h>
#include <asm/mach-types.h>
-#include <mach/mfp-pxa25x.h>
-#include <mach/hardware.h>
+#include <mach/pxa25x.h>
#include <mach/eseries-gpio.h>
#include <mach/udc.h>
#include <mach/irda.h>
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c
index df5f822f3b6c..92ba16e1b6fc 100644
--- a/arch/arm/mach-pxa/ezx.c
+++ b/arch/arm/mach-pxa/ezx.c
@@ -19,18 +19,16 @@
#include <linux/input.h>
#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
#include <mach/pxafb.h>
#include <mach/ohci.h>
#include <mach/i2c.h>
#include <mach/hardware.h>
#include <mach/pxa27x_keypad.h>
-#include <mach/mfp-pxa27x.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
#include "devices.h"
#include "generic.h"
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 0ccc91c92c44..3126a35aa002 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -26,8 +26,9 @@
#include <asm/mach/map.h>
#include <asm/mach-types.h>
-#include <mach/pxa-regs.h>
#include <mach/reset.h>
+#include <mach/gpio.h>
+#include <mach/pxa2xx-gpio.h>
#include "generic.h"
@@ -127,3 +128,33 @@ void __init pxa_map_io(void)
iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
get_clk_frequency_khz(1);
}
+
+/*
+ * Configure pins for GPIO or other functions
+ */
+int pxa_gpio_mode(int gpio_mode)
+{
+ unsigned long flags;
+ int gpio = gpio_mode & GPIO_MD_MASK_NR;
+ int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
+ int gafr;
+
+ if (gpio > pxa_last_gpio)
+ return -EINVAL;
+
+ local_irq_save(flags);
+ if (gpio_mode & GPIO_DFLT_LOW)
+ GPCR(gpio) = GPIO_bit(gpio);
+ else if (gpio_mode & GPIO_DFLT_HIGH)
+ GPSR(gpio) = GPIO_bit(gpio);
+ if (gpio_mode & GPIO_MD_MASK_DIR)
+ GPDR(gpio) |= GPIO_bit(gpio);
+ else
+ GPDR(gpio) &= ~GPIO_bit(gpio);
+ gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
+ GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
+ local_irq_restore(flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(pxa_gpio_mode);
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index dc876a8e6668..3465268ca716 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -9,20 +9,17 @@
* published by the Free Software Foundation.
*/
-typedef int (*set_wake_t)(unsigned int, unsigned int);
-
struct sys_timer;
extern struct sys_timer pxa_timer;
-extern void __init pxa_init_irq(int irq_nr, set_wake_t fn);
-extern void __init pxa_init_gpio(int gpio_nr, set_wake_t fn);
+extern void __init pxa_init_irq(int irq_nr,
+ int (*set_wake)(unsigned int, unsigned int));
extern void __init pxa25x_init_irq(void);
extern void __init pxa27x_init_irq(void);
extern void __init pxa3xx_init_irq(void);
extern void __init pxa_map_io(void);
extern unsigned int get_clk_frequency_khz(int info);
-extern int pxa_last_gpio;
#define SET_BANK(__nr,__start,__size) \
mi->bank[__nr].start = (__start), \
diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c
deleted file mode 100644
index 5fec1e479cb3..000000000000
--- a/arch/arm/mach-pxa/gpio.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/gpio.c
- *
- * Generic PXA GPIO handling
- *
- * Author: Nicolas Pitre
- * Created: Jun 15, 2001
- * Copyright: MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/irq.h>
-#include <linux/sysdev.h>
-#include <linux/io.h>
-
-#include <asm/gpio.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-gpio.h>
-
-#include "generic.h"
-
-#define GPIO0_BASE ((void __iomem *)io_p2v(0x40E00000))
-#define GPIO1_BASE ((void __iomem *)io_p2v(0x40E00004))
-#define GPIO2_BASE ((void __iomem *)io_p2v(0x40E00008))
-#define GPIO3_BASE ((void __iomem *)io_p2v(0x40E00100))
-
-#define GPLR_OFFSET 0x00
-#define GPDR_OFFSET 0x0C
-#define GPSR_OFFSET 0x18
-#define GPCR_OFFSET 0x24
-#define GRER_OFFSET 0x30
-#define GFER_OFFSET 0x3C
-#define GEDR_OFFSET 0x48
-
-struct pxa_gpio_chip {
- struct gpio_chip chip;
- void __iomem *regbase;
-};
-
-int pxa_last_gpio;
-
-#ifdef CONFIG_CPU_PXA26x
-/* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted,
- * as well as their Alternate Function value being '1' for GPIO in GAFRx.
- */
-static int __gpio_is_inverted(unsigned gpio)
-{
- return cpu_is_pxa25x() && gpio > 85;
-}
-#else
-#define __gpio_is_inverted(gpio) (0)
-#endif
-
-/*
- * Configure pins for GPIO or other functions
- */
-int pxa_gpio_mode(int gpio_mode)
-{
- unsigned long flags;
- int gpio = gpio_mode & GPIO_MD_MASK_NR;
- int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
- int gafr;
-
- if (gpio > pxa_last_gpio)
- return -EINVAL;
-
- local_irq_save(flags);
- if (gpio_mode & GPIO_DFLT_LOW)
- GPCR(gpio) = GPIO_bit(gpio);
- else if (gpio_mode & GPIO_DFLT_HIGH)
- GPSR(gpio) = GPIO_bit(gpio);
- if (gpio_mode & GPIO_MD_MASK_DIR)
- GPDR(gpio) |= GPIO_bit(gpio);
- else
- GPDR(gpio) &= ~GPIO_bit(gpio);
- gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
- GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
- local_irq_restore(flags);
-
- return 0;
-}
-EXPORT_SYMBOL(pxa_gpio_mode);
-
-static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
- unsigned long flags;
- u32 mask = 1 << offset;
- u32 value;
- struct pxa_gpio_chip *pxa;
- void __iomem *gpdr;
-
- pxa = container_of(chip, struct pxa_gpio_chip, chip);
- gpdr = pxa->regbase + GPDR_OFFSET;
- local_irq_save(flags);
- value = __raw_readl(gpdr);
- if (__gpio_is_inverted(chip->base + offset))
- value |= mask;
- else
- value &= ~mask;
- __raw_writel(value, gpdr);
- local_irq_restore(flags);
-
- return 0;
-}
-
-static int pxa_gpio_direction_output(struct gpio_chip *chip,
- unsigned offset, int value)
-{
- unsigned long flags;
- u32 mask = 1 << offset;
- u32 tmp;
- struct pxa_gpio_chip *pxa;
- void __iomem *gpdr;
-
- pxa = container_of(chip, struct pxa_gpio_chip, chip);
- __raw_writel(mask,
- pxa->regbase + (value ? GPSR_OFFSET : GPCR_OFFSET));
- gpdr = pxa->regbase + GPDR_OFFSET;
- local_irq_save(flags);
- tmp = __raw_readl(gpdr);
- if (__gpio_is_inverted(chip->base + offset))
- tmp &= ~mask;
- else
- tmp |= mask;
- __raw_writel(tmp, gpdr);
- local_irq_restore(flags);
-
- return 0;
-}
-
-/*
- * Return GPIO level
- */
-static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- u32 mask = 1 << offset;
- struct pxa_gpio_chip *pxa;
-
- pxa = container_of(chip, struct pxa_gpio_chip, chip);
- return __raw_readl(pxa->regbase + GPLR_OFFSET) & mask;
-}
-
-/*
- * Set output GPIO level
- */
-static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
- u32 mask = 1 << offset;
- struct pxa_gpio_chip *pxa;
-
- pxa = container_of(chip, struct pxa_gpio_chip, chip);
-
- if (value)
- __raw_writel(mask, pxa->regbase + GPSR_OFFSET);
- else
- __raw_writel(mask, pxa->regbase + GPCR_OFFSET);
-}
-
-#define GPIO_CHIP(_n) \
- [_n] = { \
- .regbase = GPIO##_n##_BASE, \
- .chip = { \
- .label = "gpio-" #_n, \
- .direction_input = pxa_gpio_direction_input, \
- .direction_output = pxa_gpio_direction_output, \
- .get = pxa_gpio_get, \
- .set = pxa_gpio_set, \
- .base = (_n) * 32, \
- .ngpio = 32, \
- }, \
- }
-
-static struct pxa_gpio_chip pxa_gpio_chip[] = {
- GPIO_CHIP(0),
- GPIO_CHIP(1),
- GPIO_CHIP(2),
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
- GPIO_CHIP(3),
-#endif
-};
-
-/*
- * PXA GPIO edge detection for IRQs:
- * IRQs are generated on Falling-Edge, Rising-Edge, or both.
- * Use this instead of directly setting GRER/GFER.
- */
-
-static unsigned long GPIO_IRQ_rising_edge[4];
-static unsigned long GPIO_IRQ_falling_edge[4];
-static unsigned long GPIO_IRQ_mask[4];
-
-/*
- * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate
- * function of a GPIO, and GPDRx cannot be altered once configured. It
- * is attributed as "occupied" here (I know this terminology isn't
- * accurate, you are welcome to propose a better one :-)
- */
-static int __gpio_is_occupied(unsigned gpio)
-{
- if (cpu_is_pxa27x() || cpu_is_pxa25x()) {
- int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3;
- int dir = GPDR(gpio) & GPIO_bit(gpio);
-
- if (__gpio_is_inverted(gpio))
- return af != 1 || dir == 0;
- else
- return af != 0 || dir != 0;
- }
-
- return 0;
-}
-
-static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
-{
- int gpio, idx;
-
- gpio = IRQ_TO_GPIO(irq);
- idx = gpio >> 5;
-
- if (type == IRQ_TYPE_PROBE) {
- /* Don't mess with enabled GPIOs using preconfigured edges or
- * GPIOs set to alternate function or to output during probe
- */
- if ((GPIO_IRQ_rising_edge[idx] & GPIO_bit(gpio)) ||
- (GPIO_IRQ_falling_edge[idx] & GPIO_bit(gpio)))
- return 0;
-
- if (__gpio_is_occupied(gpio))
- return 0;
-
- type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
- }
-
- if (__gpio_is_inverted(gpio))
- GPDR(gpio) |= GPIO_bit(gpio);
- else
- GPDR(gpio) &= ~GPIO_bit(gpio);
-
- if (type & IRQ_TYPE_EDGE_RISING)
- __set_bit(gpio, GPIO_IRQ_rising_edge);
- else
- __clear_bit(gpio, GPIO_IRQ_rising_edge);
-
- if (type & IRQ_TYPE_EDGE_FALLING)
- __set_bit(gpio, GPIO_IRQ_falling_edge);
- else
- __clear_bit(gpio, GPIO_IRQ_falling_edge);
-
- GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
- GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];
-
- pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__, irq, gpio,
- ((type & IRQ_TYPE_EDGE_RISING) ? " rising" : ""),
- ((type & IRQ_TYPE_EDGE_FALLING) ? " falling" : ""));
- return 0;
-}
-
-/*
- * GPIO IRQs must be acknowledged. This is for GPIO 0 and 1.
- */
-
-static void pxa_ack_low_gpio(unsigned int irq)
-{
- GEDR0 = (1 << (irq - IRQ_GPIO0));
-}
-
-static void pxa_mask_low_gpio(unsigned int irq)
-{
- ICMR &= ~(1 << (irq - PXA_IRQ(0)));
-}
-
-static void pxa_unmask_low_gpio(unsigned int irq)
-{
- ICMR |= 1 << (irq - PXA_IRQ(0));
-}
-
-static struct irq_chip pxa_low_gpio_chip = {
- .name = "GPIO-l",
- .ack = pxa_ack_low_gpio,
- .mask = pxa_mask_low_gpio,
- .unmask = pxa_unmask_low_gpio,
- .set_type = pxa_gpio_irq_type,
-};
-
-/*
- * Demux handler for GPIO>=2 edge detect interrupts
- */
-
-#define GEDR_BITS (sizeof(gedr) * BITS_PER_BYTE)
-
-static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
-{
- int loop, bit, n;
- unsigned long gedr[4];
-
- do {
- gedr[0] = GEDR0 & GPIO_IRQ_mask[0] & ~3;
- gedr[1] = GEDR1 & GPIO_IRQ_mask[1];
- gedr[2] = GEDR2 & GPIO_IRQ_mask[2];
- gedr[3] = GEDR3 & GPIO_IRQ_mask[3];
-
- GEDR0 = gedr[0]; GEDR1 = gedr[1];
- GEDR2 = gedr[2]; GEDR3 = gedr[3];
-
- loop = 0;
- bit = find_first_bit(gedr, GEDR_BITS);
- while (bit < GEDR_BITS) {
- loop = 1;
-
- n = PXA_GPIO_IRQ_BASE + bit;
- generic_handle_irq(n);
-
- bit = find_next_bit(gedr, GEDR_BITS, bit + 1);
- }
- } while (loop);
-}
-
-static void pxa_ack_muxed_gpio(unsigned int irq)
-{
- int gpio = irq - IRQ_GPIO(2) + 2;
- GEDR(gpio) = GPIO_bit(gpio);
-}
-
-static void pxa_mask_muxed_gpio(unsigned int irq)
-{
- int gpio = irq - IRQ_GPIO(2) + 2;
- __clear_bit(gpio, GPIO_IRQ_mask);
- GRER(gpio) &= ~GPIO_bit(gpio);
- GFER(gpio) &= ~GPIO_bit(gpio);
-}
-
-static void pxa_unmask_muxed_gpio(unsigned int irq)
-{
- int gpio = irq - IRQ_GPIO(2) + 2;
- int idx = gpio >> 5;
- __set_bit(gpio, GPIO_IRQ_mask);
- GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
- GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];
-}
-
-static struct irq_chip pxa_muxed_gpio_chip = {
- .name = "GPIO",
- .ack = pxa_ack_muxed_gpio,
- .mask = pxa_mask_muxed_gpio,
- .unmask = pxa_unmask_muxed_gpio,
- .set_type = pxa_gpio_irq_type,
-};
-
-void __init pxa_init_gpio(int gpio_nr, set_wake_t fn)
-{
- int irq, i, gpio;
-
- pxa_last_gpio = gpio_nr - 1;
-
- /* clear all GPIO edge detects */
- for (i = 0; i < gpio_nr; i += 32) {
- GFER(i) = 0;
- GRER(i) = 0;
- GEDR(i) = GEDR(i);
- }
-
- /* GPIO 0 and 1 must have their mask bit always set */
- GPIO_IRQ_mask[0] = 3;
-
- for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
- set_irq_chip(irq, &pxa_low_gpio_chip);
- set_irq_handler(irq, handle_edge_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
- }
-
- for (irq = IRQ_GPIO(2); irq < IRQ_GPIO(gpio_nr); irq++) {
- set_irq_chip(irq, &pxa_muxed_gpio_chip);
- set_irq_handler(irq, handle_edge_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
- }
-
- /* Install handler for GPIO>=2 edge detect interrupts */
- set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);
-
- pxa_low_gpio_chip.set_wake = fn;
- pxa_muxed_gpio_chip.set_wake = fn;
-
- /* add a GPIO chip for each register bank.
- * the last PXA25x register only contains 21 GPIOs
- */
- for (gpio = 0, i = 0; gpio < gpio_nr; gpio += 32, i++) {
- if (gpio + 32 > gpio_nr)
- pxa_gpio_chip[i].chip.ngpio = gpio_nr - gpio;
- gpiochip_add(&pxa_gpio_chip[i].chip);
- }
-}
-
-#ifdef CONFIG_PM
-
-static unsigned long saved_gplr[4];
-static unsigned long saved_gpdr[4];
-static unsigned long saved_grer[4];
-static unsigned long saved_gfer[4];
-
-static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state)
-{
- int i, gpio;
-
- for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) {
- saved_gplr[i] = GPLR(gpio);
- saved_gpdr[i] = GPDR(gpio);
- saved_grer[i] = GRER(gpio);
- saved_gfer[i] = GFER(gpio);
-
- /* Clear GPIO transition detect bits */
- GEDR(gpio) = GEDR(gpio);
- }
- return 0;
-}
-
-static int pxa_gpio_resume(struct sys_device *dev)
-{
- int i, gpio;
-
- for (gpio = 0, i = 0; gpio < pxa_last_gpio; gpio += 32, i++) {
- /* restore level with set/clear */
- GPSR(gpio) = saved_gplr[i];
- GPCR(gpio) = ~saved_gplr[i];
-
- GRER(gpio) = saved_grer[i];
- GFER(gpio) = saved_gfer[i];
- GPDR(gpio) = saved_gpdr[i];
- }
- return 0;
-}
-#else
-#define pxa_gpio_suspend NULL
-#define pxa_gpio_resume NULL
-#endif
-
-struct sysdev_class pxa_gpio_sysclass = {
- .name = "gpio",
- .suspend = pxa_gpio_suspend,
- .resume = pxa_gpio_resume,
-};
-
-static int __init pxa_gpio_init(void)
-{
- return sysdev_class_register(&pxa_gpio_sysclass);
-}
-
-core_initcall(pxa_gpio_init);
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
index e296ce11658c..ca9912ea78d9 100644
--- a/arch/arm/mach-pxa/gumstix.c
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -38,14 +38,12 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
+
+#include <mach/pxa25x.h>
#include <mach/mmc.h>
#include <mach/udc.h>
#include <mach/gumstix.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
-
#include "generic.h"
static struct resource flash_resource = {
@@ -191,6 +189,11 @@ int __attribute__((weak)) am200_init(void)
return 0;
}
+int __attribute__((weak)) am300_init(void)
+{
+ return 0;
+}
+
static void __init carrier_board_init(void)
{
/*
@@ -198,6 +201,7 @@ static void __init carrier_board_init(void)
* they cannot be detected programatically
*/
am200_init();
+ am300_init();
}
static void __init gumstix_init(void)
diff --git a/arch/arm/mach-pxa/h5000.c b/arch/arm/mach-pxa/h5000.c
index da6e4422c0f3..f3d220c32e07 100644
--- a/arch/arm/mach-pxa/h5000.c
+++ b/arch/arm/mach-pxa/h5000.c
@@ -24,14 +24,15 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
+
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+
+#include <mach/pxa25x.h>
#include <mach/h5000.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
#include <mach/udc.h>
+
#include "generic.h"
/*
@@ -153,6 +154,13 @@ static unsigned long h5000_pin_config[] __initdata = {
GPIO23_SSP1_SCLK,
GPIO25_SSP1_TXD,
GPIO26_SSP1_RXD,
+
+ /* I2S */
+ GPIO28_I2S_BITCLK_OUT,
+ GPIO29_I2S_SDATA_IN,
+ GPIO30_I2S_SDATA_OUT,
+ GPIO31_I2S_SYNC,
+ GPIO32_I2S_SYSCLK,
};
/*
diff --git a/arch/arm/mach-pxa/himalaya.c b/arch/arm/mach-pxa/himalaya.c
new file mode 100644
index 000000000000..cea99fe65b97
--- /dev/null
+++ b/arch/arm/mach-pxa/himalaya.c
@@ -0,0 +1,166 @@
+/*
+ * linux/arch/arm/mach-pxa/himalaya.c
+ *
+ * Hardware definitions for the HTC Himalaya
+ *
+ * Based on 2.6.21-hh20's himalaya.c and himalaya_lcd.c
+ *
+ * Copyright (c) 2008 Zbynek Michl <Zbynek.Michl@seznam.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/platform_device.h>
+
+#include <video/w100fb.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/mfp-pxa25x.h>
+#include <mach/hardware.h>
+
+#include "generic.h"
+
+/* ---------------------- Himalaya LCD definitions -------------------- */
+
+static struct w100_gen_regs himalaya_lcd_regs = {
+ .lcd_format = 0x00000003,
+ .lcdd_cntl1 = 0x00000000,
+ .lcdd_cntl2 = 0x0003ffff,
+ .genlcd_cntl1 = 0x00fff003,
+ .genlcd_cntl2 = 0x00000003,
+ .genlcd_cntl3 = 0x000102aa,
+};
+
+static struct w100_mode himalaya4_lcd_mode = {
+ .xres = 240,
+ .yres = 320,
+ .left_margin = 0,
+ .right_margin = 31,
+ .upper_margin = 15,
+ .lower_margin = 0,
+ .crtc_ss = 0x80150014,
+ .crtc_ls = 0xa0fb00f7,
+ .crtc_gs = 0xc0080007,
+ .crtc_vpos_gs = 0x00080007,
+ .crtc_rev = 0x0000000a,
+ .crtc_dclk = 0x81700030,
+ .crtc_gclk = 0x8015010f,
+ .crtc_goe = 0x00000000,
+ .pll_freq = 80,
+ .pixclk_divider = 15,
+ .pixclk_divider_rotated = 15,
+ .pixclk_src = CLK_SRC_PLL,
+ .sysclk_divider = 0,
+ .sysclk_src = CLK_SRC_PLL,
+};
+
+static struct w100_mode himalaya6_lcd_mode = {
+ .xres = 240,
+ .yres = 320,
+ .left_margin = 9,
+ .right_margin = 8,
+ .upper_margin = 5,
+ .lower_margin = 4,
+ .crtc_ss = 0x80150014,
+ .crtc_ls = 0xa0fb00f7,
+ .crtc_gs = 0xc0080007,
+ .crtc_vpos_gs = 0x00080007,
+ .crtc_rev = 0x0000000a,
+ .crtc_dclk = 0xa1700030,
+ .crtc_gclk = 0x8015010f,
+ .crtc_goe = 0x00000000,
+ .pll_freq = 95,
+ .pixclk_divider = 0xb,
+ .pixclk_divider_rotated = 4,
+ .pixclk_src = CLK_SRC_PLL,
+ .sysclk_divider = 1,
+ .sysclk_src = CLK_SRC_PLL,
+};
+
+static struct w100_gpio_regs himalaya_w100_gpio_info = {
+ .init_data1 = 0xffff0000, /* GPIO_DATA */
+ .gpio_dir1 = 0x00000000, /* GPIO_CNTL1 */
+ .gpio_oe1 = 0x003c0000, /* GPIO_CNTL2 */
+ .init_data2 = 0x00000000, /* GPIO_DATA2 */
+ .gpio_dir2 = 0x00000000, /* GPIO_CNTL3 */
+ .gpio_oe2 = 0x00000000, /* GPIO_CNTL4 */
+};
+
+static struct w100fb_mach_info himalaya_fb_info = {
+ .num_modes = 1,
+ .regs = &himalaya_lcd_regs,
+ .gpio = &himalaya_w100_gpio_info,
+ .xtal_freq = 16000000,
+};
+
+static struct resource himalaya_fb_resources[] = {
+ [0] = {
+ .start = 0x08000000,
+ .end = 0x08ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device himalaya_fb_device = {
+ .name = "w100fb",
+ .id = -1,
+ .dev = {
+ .platform_data = &himalaya_fb_info,
+ },
+ .num_resources = ARRAY_SIZE(himalaya_fb_resources),
+ .resource = himalaya_fb_resources,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct platform_device *devices[] __initdata = {
+ &himalaya_fb_device,
+};
+
+static void __init himalaya_lcd_init(void)
+{
+ int himalaya_boardid;
+
+ himalaya_boardid = 0x4; /* hardcoded (detection needs ASIC3 functions) */
+ printk(KERN_INFO "himalaya LCD Driver init. boardid=%d\n",
+ himalaya_boardid);
+
+ switch (himalaya_boardid) {
+ case 0x4:
+ himalaya_fb_info.modelist = &himalaya4_lcd_mode;
+ break;
+ case 0x6:
+ himalaya_fb_info.modelist = &himalaya6_lcd_mode;
+ break;
+ default:
+ printk(KERN_INFO "himalaya lcd_init: unknown boardid=%d. Using 0x4\n",
+ himalaya_boardid);
+ himalaya_fb_info.modelist = &himalaya4_lcd_mode;
+ }
+}
+
+static void __init himalaya_init(void)
+{
+ himalaya_lcd_init();
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+
+MACHINE_START(HIMALAYA, "HTC Himalaya")
+ .phys_io = 0x40000000,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .boot_params = 0xa0000100,
+ .map_io = pxa_map_io,
+ .init_irq = pxa25x_init_irq,
+ .init_machine = himalaya_init,
+ .timer = &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 013b15baa034..b6243b59d9be 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -31,8 +31,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
-#include <mach/pxa-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include <mach/pxa25x.h>
#include <mach/idp.h>
#include <mach/pxafb.h>
#include <mach/bitfield.h>
diff --git a/arch/arm/mach-pxa/imote2.c b/arch/arm/mach-pxa/imote2.c
index 364c5e271330..2121309b2474 100644
--- a/arch/arm/mach-pxa/imote2.c
+++ b/arch/arm/mach-pxa/imote2.c
@@ -28,11 +28,8 @@
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
+#include <mach/pxa27x.h>
#include <mach/i2c.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
-#include <mach/regs-ssp.h>
#include <mach/udc.h>
#include <mach/mmc.h>
#include <mach/pxa2xx_spi.h>
diff --git a/arch/arm/mach-pxa/include/mach/colibri.h b/arch/arm/mach-pxa/include/mach/colibri.h
index 2ae373fb5675..3f2a01d6a03c 100644
--- a/arch/arm/mach-pxa/include/mach/colibri.h
+++ b/arch/arm/mach-pxa/include/mach/colibri.h
@@ -1,19 +1,31 @@
#ifndef _COLIBRI_H_
#define _COLIBRI_H_
+/*
+ * common settings for all modules
+ */
+
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+extern void colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin);
+#else
+static inline void colibri_pxa3xx_init_mmc(mfp_cfg_t *, int, int) {}
+#endif
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+extern void colibri_pxa3xx_init_lcd(int bl_pin);
+#else
+static inline void colibri_pxa3xx_init_lcd(int) {}
+#endif
/* physical memory regions */
-#define COLIBRI_FLASH_PHYS (PXA_CS0_PHYS) /* Flash region */
-#define COLIBRI_ETH_PHYS (PXA_CS2_PHYS) /* Ethernet DM9000 region */
#define COLIBRI_SDRAM_BASE 0xa0000000 /* SDRAM region */
-/* virtual memory regions */
-#define COLIBRI_DISK_VIRT 0xF0000000 /* Disk On Chip region */
+/* definitions for Colibri PXA270 */
-/* size of flash */
-#define COLIBRI_FLASH_SIZE 0x02000000 /* Flash size 32 MB */
-
-/* Ethernet Controller Davicom DM9000 */
-#define GPIO_DM9000 114
-#define COLIBRI_ETH_IRQ IRQ_GPIO(GPIO_DM9000)
+#define COLIBRI_PXA270_FLASH_PHYS (PXA_CS0_PHYS) /* Flash region */
+#define COLIBRI_PXA270_ETH_PHYS (PXA_CS2_PHYS) /* Ethernet */
+#define COLIBRI_PXA270_ETH_IRQ_GPIO 114
+#define COLIBRI_PXA270_ETH_IRQ \
+ gpio_to_irq(mfp_to_gpio(COLIBRI_PXA270_ETH_IRQ_GPIO))
#endif /* _COLIBRI_H_ */
+
diff --git a/arch/arm/mach-pxa/include/mach/csb726.h b/arch/arm/mach-pxa/include/mach/csb726.h
new file mode 100644
index 000000000000..747ab1a71f2f
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/csb726.h
@@ -0,0 +1,26 @@
+/*
+ * Support for Cogent CSB726
+ *
+ * Copyright (c) 2008 Dmitry Baryshkov
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef CSB726_H
+#define CSB726_H
+
+#define CSB726_GPIO_IRQ_LAN 52
+#define CSB726_GPIO_IRQ_SM501 53
+#define CSB726_GPIO_MMC_DETECT 100
+#define CSB726_GPIO_MMC_RO 101
+
+#define CSB726_FLASH_SIZE (64 * 1024 * 1024)
+#define CSB726_FLASH_uMON (8 * 1024 * 1024)
+
+#define CSB726_IRQ_LAN gpio_to_irq(CSB726_GPIO_IRQ_LAN)
+#define CSB726_IRQ_SM501 gpio_to_irq(CSB726_GPIO_IRQ_SM501)
+
+#endif
+
diff --git a/arch/arm/mach-pxa/include/mach/dma.h b/arch/arm/mach-pxa/include/mach/dma.h
index 7804637a6df3..5bd55894a48d 100644
--- a/arch/arm/mach-pxa/include/mach/dma.h
+++ b/arch/arm/mach-pxa/include/mach/dma.h
@@ -12,35 +12,10 @@
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H
-/*
- * Descriptor structure for PXA's DMA engine
- * Note: this structure must always be aligned to a 16-byte boundary.
- */
-
-typedef struct pxa_dma_desc {
- volatile u32 ddadr; /* Points to the next descriptor + flags */
- volatile u32 dsadr; /* DSADR value for the current transfer */
- volatile u32 dtadr; /* DTADR value for the current transfer */
- volatile u32 dcmd; /* DCMD value for the current transfer */
-} pxa_dma_desc;
-
-typedef enum {
- DMA_PRIO_HIGH = 0,
- DMA_PRIO_MEDIUM = 1,
- DMA_PRIO_LOW = 2
-} pxa_dma_prio;
-
-/*
- * DMA registration
- */
-
-int __init pxa_init_dma(int num_ch);
-
-int pxa_request_dma (char *name,
- pxa_dma_prio prio,
- void (*irq_handler)(int, void *),
- void *data);
+#include <mach/hardware.h>
-void pxa_free_dma (int dma_ch);
+/* DMA Controller Registers Definitions */
+#define DMAC_REGS_VIRT io_p2v(0x40000000)
+#include <plat/dma.h>
#endif /* _ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-pxa/include/mach/eseries-gpio.h b/arch/arm/mach-pxa/include/mach/eseries-gpio.h
index efbd2aa9ecec..f3e5509820d7 100644
--- a/arch/arm/mach-pxa/include/mach/eseries-gpio.h
+++ b/arch/arm/mach-pxa/include/mach/eseries-gpio.h
@@ -45,6 +45,21 @@
/* e7xx IrDA power control */
#define GPIO_E7XX_IR_OFF 38
+/* e740 audio control GPIOs */
+#define GPIO_E740_WM9705_nAVDD2 16
+#define GPIO_E740_MIC_ON 40
+#define GPIO_E740_AMP_ON 41
+
+/* e750 audio control GPIOs */
+#define GPIO_E750_HP_AMP_OFF 4
+#define GPIO_E750_SPK_AMP_OFF 7
+#define GPIO_E750_HP_DETECT 37
+
+/* e800 audio control GPIOs */
+#define GPIO_E800_HP_DETECT 81
+#define GPIO_E800_HP_AMP_OFF 82
+#define GPIO_E800_SPK_AMP_ON 83
+
/* ASIC related GPIOs */
#define GPIO_ESERIES_TMIO_IRQ 5
#define GPIO_ESERIES_TMIO_PCLR 19
diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h
index 2c538d8c362d..b024a8b37439 100644
--- a/arch/arm/mach-pxa/include/mach/gpio.h
+++ b/arch/arm/mach-pxa/include/mach/gpio.h
@@ -24,42 +24,118 @@
#ifndef __ASM_ARCH_PXA_GPIO_H
#define __ASM_ARCH_PXA_GPIO_H
-#include <mach/pxa-regs.h>
-#include <asm/irq.h>
+#include <mach/irqs.h>
#include <mach/hardware.h>
-
#include <asm-generic/gpio.h>
+#define GPIO_REGS_VIRT io_p2v(0x40E00000)
+
+#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
+#define GPIO_REG(x) (*(volatile u32 *)(GPIO_REGS_VIRT + (x)))
+
+/* GPIO Pin Level Registers */
+#define GPLR0 GPIO_REG(BANK_OFF(0) + 0x00)
+#define GPLR1 GPIO_REG(BANK_OFF(1) + 0x00)
+#define GPLR2 GPIO_REG(BANK_OFF(2) + 0x00)
+#define GPLR3 GPIO_REG(BANK_OFF(3) + 0x00)
+
+/* GPIO Pin Direction Registers */
+#define GPDR0 GPIO_REG(BANK_OFF(0) + 0x0c)
+#define GPDR1 GPIO_REG(BANK_OFF(1) + 0x0c)
+#define GPDR2 GPIO_REG(BANK_OFF(2) + 0x0c)
+#define GPDR3 GPIO_REG(BANK_OFF(3) + 0x0c)
+
+/* GPIO Pin Output Set Registers */
+#define GPSR0 GPIO_REG(BANK_OFF(0) + 0x18)
+#define GPSR1 GPIO_REG(BANK_OFF(1) + 0x18)
+#define GPSR2 GPIO_REG(BANK_OFF(2) + 0x18)
+#define GPSR3 GPIO_REG(BANK_OFF(3) + 0x18)
+
+/* GPIO Pin Output Clear Registers */
+#define GPCR0 GPIO_REG(BANK_OFF(0) + 0x24)
+#define GPCR1 GPIO_REG(BANK_OFF(1) + 0x24)
+#define GPCR2 GPIO_REG(BANK_OFF(2) + 0x24)
+#define GPCR3 GPIO_REG(BANK_OFF(3) + 0x24)
+
+/* GPIO Rising Edge Detect Registers */
+#define GRER0 GPIO_REG(BANK_OFF(0) + 0x30)
+#define GRER1 GPIO_REG(BANK_OFF(1) + 0x30)
+#define GRER2 GPIO_REG(BANK_OFF(2) + 0x30)
+#define GRER3 GPIO_REG(BANK_OFF(3) + 0x30)
+
+/* GPIO Falling Edge Detect Registers */
+#define GFER0 GPIO_REG(BANK_OFF(0) + 0x3c)
+#define GFER1 GPIO_REG(BANK_OFF(1) + 0x3c)
+#define GFER2 GPIO_REG(BANK_OFF(2) + 0x3c)
+#define GFER3 GPIO_REG(BANK_OFF(3) + 0x3c)
+
+/* GPIO Edge Detect Status Registers */
+#define GEDR0 GPIO_REG(BANK_OFF(0) + 0x48)
+#define GEDR1 GPIO_REG(BANK_OFF(1) + 0x48)
+#define GEDR2 GPIO_REG(BANK_OFF(2) + 0x48)
+#define GEDR3 GPIO_REG(BANK_OFF(3) + 0x48)
+
+/* GPIO Alternate Function Select Registers */
+#define GAFR0_L GPIO_REG(0x0054)
+#define GAFR0_U GPIO_REG(0x0058)
+#define GAFR1_L GPIO_REG(0x005C)
+#define GAFR1_U GPIO_REG(0x0060)
+#define GAFR2_L GPIO_REG(0x0064)
+#define GAFR2_U GPIO_REG(0x0068)
+#define GAFR3_L GPIO_REG(0x006C)
+#define GAFR3_U GPIO_REG(0x0070)
+
+/* More handy macros. The argument is a literal GPIO number. */
+
+#define GPIO_bit(x) (1 << ((x) & 0x1f))
+
+#define GPLR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x00)
+#define GPDR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x0c)
+#define GPSR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x18)
+#define GPCR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x24)
+#define GRER(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x30)
+#define GFER(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x3c)
+#define GEDR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x48)
+#define GAFR(x) GPIO_REG(0x54 + (((x) & 0x70) >> 2))
+
-/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85).
- * Those cases currently cause holes in the GPIO number space.
- */
#define NR_BUILTIN_GPIO 128
-static inline int gpio_get_value(unsigned gpio)
+#define gpio_to_bank(gpio) ((gpio) >> 5)
+#define gpio_to_irq(gpio) IRQ_GPIO(gpio)
+#define irq_to_gpio(irq) IRQ_TO_GPIO(irq)
+
+#ifdef CONFIG_CPU_PXA26x
+/* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted,
+ * as well as their Alternate Function value being '1' for GPIO in GAFRx.
+ */
+static inline int __gpio_is_inverted(unsigned gpio)
{
- if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO))
- return GPLR(gpio) & GPIO_bit(gpio);
- else
- return __gpio_get_value(gpio);
+ return cpu_is_pxa25x() && gpio > 85;
}
+#else
+static inline int __gpio_is_inverted(unsigned gpio) { return 0; }
+#endif
-static inline void gpio_set_value(unsigned gpio, int value)
+/*
+ * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate
+ * function of a GPIO, and GPDRx cannot be altered once configured. It
+ * is attributed as "occupied" here (I know this terminology isn't
+ * accurate, you are welcome to propose a better one :-)
+ */
+static inline int __gpio_is_occupied(unsigned gpio)
{
- if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) {
- if (value)
- GPSR(gpio) = GPIO_bit(gpio);
+ if (cpu_is_pxa27x() || cpu_is_pxa25x()) {
+ int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3;
+ int dir = GPDR(gpio) & GPIO_bit(gpio);
+
+ if (__gpio_is_inverted(gpio))
+ return af != 1 || dir == 0;
else
- GPCR(gpio) = GPIO_bit(gpio);
- } else {
- __gpio_set_value(gpio, value);
- }
+ return af != 0 || dir != 0;
+ } else
+ return GPDR(gpio) & GPIO_bit(gpio);
}
-#define gpio_cansleep __gpio_cansleep
-
-#define gpio_to_irq(gpio) IRQ_GPIO(gpio)
-#define irq_to_gpio(irq) IRQ_TO_GPIO(irq)
-
-
+#include <plat/gpio.h>
#endif
diff --git a/arch/arm/mach-pxa/include/mach/gumstix.h b/arch/arm/mach-pxa/include/mach/gumstix.h
index 099f54a41de4..06abd4160607 100644
--- a/arch/arm/mach-pxa/include/mach/gumstix.h
+++ b/arch/arm/mach-pxa/include/mach/gumstix.h
@@ -97,4 +97,5 @@ has detected a cable insertion; driven low otherwise. */
/* for expansion boards that can't be programatically detected */
extern int am200_init(void);
+extern int am300_init(void);
diff --git a/arch/arm/mach-pxa/include/mach/lubbock.h b/arch/arm/mach-pxa/include/mach/lubbock.h
index 4cb24154a5a8..751b74811d0f 100644
--- a/arch/arm/mach-pxa/include/mach/lubbock.h
+++ b/arch/arm/mach-pxa/include/mach/lubbock.h
@@ -25,7 +25,6 @@
/* FPGA register virtual addresses */
#define LUB_WHOAMI __LUB_REG(LUBBOCK_FPGA_PHYS + 0x000)
-#define LUB_HEXLED __LUB_REG(LUBBOCK_FPGA_PHYS + 0x010)
#define LUB_DISC_BLNK_LED __LUB_REG(LUBBOCK_FPGA_PHYS + 0x040)
#define LUB_CONF_SWITCHES __LUB_REG(LUBBOCK_FPGA_PHYS + 0x050)
#define LUB_USER_SWITCHES __LUB_REG(LUBBOCK_FPGA_PHYS + 0x060)
diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h
index 38d68d99f585..82a399f3f9f2 100644
--- a/arch/arm/mach-pxa/include/mach/magician.h
+++ b/arch/arm/mach-pxa/include/mach/magician.h
@@ -69,7 +69,7 @@
#define IRQ_MAGICIAN_SD (IRQ_BOARD_START + 0)
#define IRQ_MAGICIAN_EP (IRQ_BOARD_START + 1)
#define IRQ_MAGICIAN_BT (IRQ_BOARD_START + 2)
-#define IRQ_MAGICIAN_AC (IRQ_BOARD_START + 3)
+#define IRQ_MAGICIAN_VBUS (IRQ_BOARD_START + 3)
/*
* CPLD EGPIOs
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
index a72869b73ee3..b13dc0269a6d 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
@@ -1,7 +1,6 @@
#ifndef __ASM_ARCH_MFP_PXA25X_H
#define __ASM_ARCH_MFP_PXA25X_H
-#include <mach/mfp.h>
#include <mach/mfp-pxa2xx.h>
/* GPIO */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
index da4f85a4f990..6543c05f47ed 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
@@ -8,7 +8,6 @@
* specific controller, and this should work in most cases.
*/
-#include <mach/mfp.h>
#include <mach/mfp-pxa2xx.h>
/* Note: GPIO3/GPIO4 will be driven by Power I2C when PCFR/PI2C_EN
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
index 3e9211591e20..658b28ed129b 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
@@ -1,7 +1,7 @@
#ifndef __ASM_ARCH_MFP_PXA2XX_H
#define __ASM_ARCH_MFP_PXA2XX_H
-#include <mach/mfp.h>
+#include <plat/mfp.h>
/*
* the following MFP_xxx bit definitions in mfp.h are re-used for pxa2xx:
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h
index bc1fb33a6e70..ae8441192ef0 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h
@@ -15,7 +15,6 @@
#ifndef __ASM_ARCH_MFP_PXA300_H
#define __ASM_ARCH_MFP_PXA300_H
-#include <mach/mfp.h>
#include <mach/mfp-pxa3xx.h>
/* GPIO */
@@ -41,6 +40,7 @@
#endif
/* Chip Select */
+#define GPIO1_nCS2 MFP_CFG(GPIO1, AF1)
#define GPIO2_nCS3 MFP_CFG(GPIO2, AF1)
/* AC97 */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa320.h b/arch/arm/mach-pxa/include/mach/mfp-pxa320.h
index 67f8385ea548..07897e61d05a 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa320.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa320.h
@@ -15,7 +15,6 @@
#ifndef __ASM_ARCH_MFP_PXA320_H
#define __ASM_ARCH_MFP_PXA320_H
-#include <mach/mfp.h>
#include <mach/mfp-pxa3xx.h>
/* GPIO */
@@ -38,6 +37,7 @@
#define GPIO17_2_GPIO MFP_CFG(GPIO17_2, AF0)
/* Chip Select */
+#define GPIO3_nCS2 MFP_CFG(GPIO3, AF1)
#define GPIO4_nCS3 MFP_CFG(GPIO4, AF1)
/* AC97 */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h b/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h
index 1f6b35c015d0..d375195d982b 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h
@@ -1,68 +1,9 @@
#ifndef __ASM_ARCH_MFP_PXA3XX_H
#define __ASM_ARCH_MFP_PXA3XX_H
-#define MFPR_BASE (0x40e10000)
-#define MFPR_SIZE (PAGE_SIZE)
-
-/* MFPR register bit definitions */
-#define MFPR_PULL_SEL (0x1 << 15)
-#define MFPR_PULLUP_EN (0x1 << 14)
-#define MFPR_PULLDOWN_EN (0x1 << 13)
-#define MFPR_SLEEP_SEL (0x1 << 9)
-#define MFPR_SLEEP_OE_N (0x1 << 7)
-#define MFPR_EDGE_CLEAR (0x1 << 6)
-#define MFPR_EDGE_FALL_EN (0x1 << 5)
-#define MFPR_EDGE_RISE_EN (0x1 << 4)
-
-#define MFPR_SLEEP_DATA(x) ((x) << 8)
-#define MFPR_DRIVE(x) (((x) & 0x7) << 10)
-#define MFPR_AF_SEL(x) (((x) & 0x7) << 0)
+#include <plat/mfp.h>
-#define MFPR_EDGE_NONE (0)
-#define MFPR_EDGE_RISE (MFPR_EDGE_RISE_EN)
-#define MFPR_EDGE_FALL (MFPR_EDGE_FALL_EN)
-#define MFPR_EDGE_BOTH (MFPR_EDGE_RISE | MFPR_EDGE_FALL)
-
-/*
- * Table that determines the low power modes outputs, with actual settings
- * used in parentheses for don't-care values. Except for the float output,
- * the configured driven and pulled levels match, so if there is a need for
- * non-LPM pulled output, the same configuration could probably be used.
- *
- * Output value sleep_oe_n sleep_data pullup_en pulldown_en pull_sel
- * (bit 7) (bit 8) (bit 14) (bit 13) (bit 15)
- *
- * Input 0 X(0) X(0) X(0) 0
- * Drive 0 0 0 0 X(1) 0
- * Drive 1 0 1 X(1) 0 0
- * Pull hi (1) 1 X(1) 1 0 0
- * Pull lo (0) 1 X(0) 0 1 0
- * Z (float) 1 X(0) 0 0 0
- */
-#define MFPR_LPM_INPUT (0)
-#define MFPR_LPM_DRIVE_LOW (MFPR_SLEEP_DATA(0) | MFPR_PULLDOWN_EN)
-#define MFPR_LPM_DRIVE_HIGH (MFPR_SLEEP_DATA(1) | MFPR_PULLUP_EN)
-#define MFPR_LPM_PULL_LOW (MFPR_LPM_DRIVE_LOW | MFPR_SLEEP_OE_N)
-#define MFPR_LPM_PULL_HIGH (MFPR_LPM_DRIVE_HIGH | MFPR_SLEEP_OE_N)
-#define MFPR_LPM_FLOAT (MFPR_SLEEP_OE_N)
-#define MFPR_LPM_MASK (0xe080)
-
-/*
- * The pullup and pulldown state of the MFP pin at run mode is by default
- * determined by the selected alternate function. In case that some buggy
- * devices need to override this default behavior, the definitions below
- * indicates the setting of corresponding MFPR bits
- *
- * Definition pull_sel pullup_en pulldown_en
- * MFPR_PULL_NONE 0 0 0
- * MFPR_PULL_LOW 1 0 1
- * MFPR_PULL_HIGH 1 1 0
- * MFPR_PULL_BOTH 1 1 1
- */
-#define MFPR_PULL_NONE (0)
-#define MFPR_PULL_LOW (MFPR_PULL_SEL | MFPR_PULLDOWN_EN)
-#define MFPR_PULL_BOTH (MFPR_PULL_LOW | MFPR_PULLUP_EN)
-#define MFPR_PULL_HIGH (MFPR_PULL_SEL | MFPR_PULLUP_EN)
+#define MFPR_BASE (0x40e10000)
/* PXA3xx common MFP configurations - processor specific ones defined
* in mfp-pxa300.h and mfp-pxa320.h
@@ -197,56 +138,21 @@
#define GPIO5_2_GPIO MFP_CFG(GPIO5_2, AF0)
#define GPIO6_2_GPIO MFP_CFG(GPIO6_2, AF0)
-/*
- * each MFP pin will have a MFPR register, since the offset of the
- * register varies between processors, the processor specific code
- * should initialize the pin offsets by pxa3xx_mfp_init_addr()
- *
- * pxa3xx_mfp_init_addr - accepts a table of "pxa3xx_mfp_addr_map"
- * structure, which represents a range of MFP pins from "start" to
- * "end", with the offset begining at "offset", to define a single
- * pin, let "end" = -1
- *
- * use
- *
- * MFP_ADDR_X() to define a range of pins
- * MFP_ADDR() to define a single pin
- * MFP_ADDR_END to signal the end of pin offset definitions
- */
-struct pxa3xx_mfp_addr_map {
- unsigned int start;
- unsigned int end;
- unsigned long offset;
-};
-
-#define MFP_ADDR_X(start, end, offset) \
- { MFP_PIN_##start, MFP_PIN_##end, offset }
-
-#define MFP_ADDR(pin, offset) \
- { MFP_PIN_##pin, -1, offset }
-
-#define MFP_ADDR_END { MFP_PIN_INVALID, 0 }
-
-/*
- * pxa3xx_mfp_read()/pxa3xx_mfp_write() - for direct read/write access
- * to the MFPR register
- */
-unsigned long pxa3xx_mfp_read(int mfp);
-void pxa3xx_mfp_write(int mfp, unsigned long mfpr_val);
-
-/*
- * pxa3xx_mfp_config - configure the MFPR registers
- *
- * used by board specific initialization code
- */
-void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num);
-
-/*
- * pxa3xx_mfp_init_addr() - initialize the mapping between mfp pin
- * index and MFPR register offset
- *
- * used by processor specific code
+/* NOTE: usage of these two functions is not recommended,
+ * use pxa3xx_mfp_config() instead.
*/
-void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *);
-void __init pxa3xx_init_mfp(void);
+static inline unsigned long pxa3xx_mfp_read(int mfp)
+{
+ return mfp_read(mfp);
+}
+
+static inline void pxa3xx_mfp_write(int mfp, unsigned long val)
+{
+ mfp_write(mfp, val);
+}
+
+static inline void pxa3xx_mfp_config(unsigned long *mfp_cfg, int num)
+{
+ mfp_config(mfp_cfg, num);
+}
#endif /* __ASM_ARCH_MFP_PXA3XX_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa930.h b/arch/arm/mach-pxa/include/mach/mfp-pxa930.h
index fa73f56a1372..0d119d3b9221 100644
--- a/arch/arm/mach-pxa/include/mach/mfp-pxa930.h
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa930.h
@@ -13,7 +13,6 @@
#ifndef __ASM_ARCH_MFP_PXA9xx_H
#define __ASM_ARCH_MFP_PXA9xx_H
-#include <mach/mfp.h>
#include <mach/mfp-pxa3xx.h>
/* GPIO */
diff --git a/arch/arm/mach-pxa/include/mach/mtd-xip.h b/arch/arm/mach-pxa/include/mach/mtd-xip.h
index cfca8155be72..297387ec3618 100644
--- a/arch/arm/mach-pxa/include/mach/mtd-xip.h
+++ b/arch/arm/mach-pxa/include/mach/mtd-xip.h
@@ -15,8 +15,8 @@
#ifndef __ARCH_PXA_MTD_XIP_H__
#define __ARCH_PXA_MTD_XIP_H__
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/regs-ost.h>
+#include <mach/regs-intc.h>
#define xip_irqpending() (ICIP & ICMR)
diff --git a/arch/arm/mach-pxa/include/mach/palmld.h b/arch/arm/mach-pxa/include/mach/palmld.h
new file mode 100644
index 000000000000..7c295a48d784
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmld.h
@@ -0,0 +1,109 @@
+/*
+ * GPIOs and interrupts for Palm LifeDrive Handheld Computer
+ *
+ * Authors: Alex Osborne <ato@meshy.org>
+ * Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _INCLUDE_PALMLD_H_
+#define _INCLUDE_PALMLD_H_
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMLD_GPIO_RESET 1
+#define GPIO_NR_PALMLD_POWER_DETECT 4
+#define GPIO_NR_PALMLD_HOTSYNC_BUTTON_N 10
+#define GPIO_NR_PALMLD_POWER_SWITCH 12
+#define GPIO_NR_PALMLD_EARPHONE_DETECT 13
+#define GPIO_NR_PALMLD_LOCK_SWITCH 15
+
+/* SD/MMC */
+#define GPIO_NR_PALMLD_SD_DETECT_N 14
+#define GPIO_NR_PALMLD_SD_POWER 114
+#define GPIO_NR_PALMLD_SD_READONLY 116
+
+/* TOUCHSCREEN */
+#define GPIO_NR_PALMLD_WM9712_IRQ 27
+
+/* IRDA */
+#define GPIO_NR_PALMLD_IR_DISABLE 108
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMLD_BL_POWER 19
+#define GPIO_NR_PALMLD_LCD_POWER 96
+
+/* LCD BORDER */
+#define GPIO_NR_PALMLD_BORDER_SWITCH 21
+#define GPIO_NR_PALMLD_BORDER_SELECT 22
+
+/* BLUETOOTH */
+#define GPIO_NR_PALMLD_BT_POWER 17
+#define GPIO_NR_PALMLD_BT_RESET 83
+
+/* PCMCIA (WiFi) */
+#define GPIO_NR_PALMLD_PCMCIA_READY 38
+#define GPIO_NR_PALMLD_PCMCIA_POWER 36
+#define GPIO_NR_PALMLD_PCMCIA_RESET 81
+
+/* LEDs */
+#define GPIO_NR_PALMLD_LED_GREEN 52
+#define GPIO_NR_PALMLD_LED_AMBER 94
+
+/* IDE */
+#define GPIO_NR_PALMLD_IDE_IRQ 95
+#define GPIO_NR_PALMLD_IDE_RESET 98
+#define GPIO_NR_PALMLD_IDE_PWEN 115
+
+/* USB */
+#define GPIO_NR_PALMLD_USB_DETECT_N 3
+#define GPIO_NR_PALMLD_USB_READY 86
+#define GPIO_NR_PALMLD_USB_RESET 88
+#define GPIO_NR_PALMLD_USB_INT 106
+#define GPIO_NR_PALMLD_USB_POWER 118
+/* 20, 53 and 86 are usb related too */
+
+/* INTERRUPTS */
+#define IRQ_GPIO_PALMLD_GPIO_RESET IRQ_GPIO(GPIO_NR_PALMLD_GPIO_RESET)
+#define IRQ_GPIO_PALMLD_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMLD_SD_DETECT_N)
+#define IRQ_GPIO_PALMLD_WM9712_IRQ IRQ_GPIO(GPIO_NR_PALMLD_WM9712_IRQ)
+#define IRQ_GPIO_PALMLD_IDE_IRQ IRQ_GPIO(GPIO_NR_PALMLD_IDE_IRQ)
+
+
+/** HERE ARE INIT VALUES **/
+
+/* IO mappings */
+#define PALMLD_USB_PHYS PXA_CS2_PHYS
+#define PALMLD_USB_VIRT 0xf0000000
+#define PALMLD_USB_SIZE 0x00100000
+
+#define PALMLD_IDE_PHYS 0x20000000
+#define PALMLD_IDE_VIRT 0xf1000000
+#define PALMLD_IDE_SIZE 0x00100000
+
+#define PALMLD_PHYS_IO_START 0x40000000
+
+/* BATTERY */
+#define PALMLD_BAT_MAX_VOLTAGE 4000 /* 4.00V maximum voltage */
+#define PALMLD_BAT_MIN_VOLTAGE 3550 /* 3.55V critical voltage */
+#define PALMLD_BAT_MAX_CURRENT 0 /* unknokn */
+#define PALMLD_BAT_MIN_CURRENT 0 /* unknown */
+#define PALMLD_BAT_MAX_CHARGE 1 /* unknown */
+#define PALMLD_BAT_MIN_CHARGE 1 /* unknown */
+#define PALMLD_MAX_LIFE_MINS 240 /* on-life in minutes */
+
+#define PALMLD_BAT_MEASURE_DELAY (HZ * 1)
+
+/* BACKLIGHT */
+#define PALMLD_MAX_INTENSITY 0xFE
+#define PALMLD_DEFAULT_INTENSITY 0x7E
+#define PALMLD_LIMIT_MASK 0x7F
+#define PALMLD_PRESCALER 0x3F
+#define PALMLD_PERIOD_NS 3500
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/palmt5.h b/arch/arm/mach-pxa/include/mach/palmt5.h
new file mode 100644
index 000000000000..94db2881f048
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmt5.h
@@ -0,0 +1,84 @@
+/*
+ * GPIOs and interrupts for Palm Tungsten|T5 Handheld Computer
+ *
+ * Authors: Ales Snuparek <snuparek@atlas.cz>
+ * Marek Vasut <marek.vasut@gmail.com>
+ * Justin Kendrick <twilightsentry@gmail.com>
+ * RichardT5 <richard_t5@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _INCLUDE_PALMT5_H_
+#define _INCLUDE_PALMT5_H_
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMT5_GPIO_RESET 1
+
+#define GPIO_NR_PALMT5_POWER_DETECT 90
+#define GPIO_NR_PALMT5_HOTSYNC_BUTTON_N 10
+#define GPIO_NR_PALMT5_EARPHONE_DETECT 107
+
+/* SD/MMC */
+#define GPIO_NR_PALMT5_SD_DETECT_N 14
+#define GPIO_NR_PALMT5_SD_POWER 114
+#define GPIO_NR_PALMT5_SD_READONLY 115
+
+/* TOUCHSCREEN */
+#define GPIO_NR_PALMT5_WM9712_IRQ 27
+
+/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
+#define GPIO_NR_PALMT5_IR_DISABLE 40
+
+/* USB */
+#define GPIO_NR_PALMT5_USB_DETECT_N 15
+#define GPIO_NR_PALMT5_USB_POWER 95
+#define GPIO_NR_PALMT5_USB_PULLUP 93
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMT5_BL_POWER 84
+#define GPIO_NR_PALMT5_LCD_POWER 96
+
+/* BLUETOOTH */
+#define GPIO_NR_PALMT5_BT_POWER 17
+#define GPIO_NR_PALMT5_BT_RESET 83
+
+/* INTERRUPTS */
+#define IRQ_GPIO_PALMT5_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMT5_SD_DETECT_N)
+#define IRQ_GPIO_PALMT5_WM9712_IRQ IRQ_GPIO(GPIO_NR_PALMT5_WM9712_IRQ)
+#define IRQ_GPIO_PALMT5_USB_DETECT IRQ_GPIO(GPIO_NR_PALMT5_USB_DETECT)
+#define IRQ_GPIO_PALMT5_GPIO_RESET IRQ_GPIO(GPIO_NR_PALMT5_GPIO_RESET)
+
+/** HERE ARE INIT VALUES **/
+
+/* Various addresses */
+#define PALMT5_PHYS_RAM_START 0xa0000000
+#define PALMT5_PHYS_IO_START 0x40000000
+
+/* TOUCHSCREEN */
+#define AC97_LINK_FRAME 21
+
+/* BATTERY */
+#define PALMT5_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */
+#define PALMT5_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */
+#define PALMT5_BAT_MAX_CURRENT 0 /* unknokn */
+#define PALMT5_BAT_MIN_CURRENT 0 /* unknown */
+#define PALMT5_BAT_MAX_CHARGE 1 /* unknown */
+#define PALMT5_BAT_MIN_CHARGE 1 /* unknown */
+#define PALMT5_MAX_LIFE_MINS 360 /* on-life in minutes */
+
+#define PALMT5_BAT_MEASURE_DELAY (HZ * 1)
+
+/* BACKLIGHT */
+#define PALMT5_MAX_INTENSITY 0xFE
+#define PALMT5_DEFAULT_INTENSITY 0x7E
+#define PALMT5_LIMIT_MASK 0x7F
+#define PALMT5_PRESCALER 0x3F
+#define PALMT5_PERIOD_NS 3500
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/pm.h b/arch/arm/mach-pxa/include/mach/pm.h
index 83342469acac..a6eeef8a075f 100644
--- a/arch/arm/mach-pxa/include/mach/pm.h
+++ b/arch/arm/mach-pxa/include/mach/pm.h
@@ -27,3 +27,13 @@ extern void pxa27x_cpu_suspend(unsigned int);
extern void pxa_cpu_resume(void);
extern int pxa_pm_enter(suspend_state_t state);
+
+/* NOTE: this is for PM debugging on Lubbock, it's really a big
+ * ugly, but let's keep the crap minimum here, instead of direct
+ * accessing the LUBBOCK CPLD registers in arch/arm/mach-pxa/pm.c
+ */
+#ifdef CONFIG_ARCH_LUBBOCK
+extern void lubbock_set_hexled(uint32_t value);
+#else
+#define lubbock_set_hexled(x)
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/pxa-regs.h b/arch/arm/mach-pxa/include/mach/pxa-regs.h
deleted file mode 100644
index 31d615aa7723..000000000000
--- a/arch/arm/mach-pxa/include/mach/pxa-regs.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * arch/arm/mach-pxa/include/mach/pxa-regs.h
- *
- * Author: Nicolas Pitre
- * Created: Jun 15, 2001
- * Copyright: MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __PXA_REGS_H
-#define __PXA_REGS_H
-
-#include <mach/hardware.h>
-
-/*
- * PXA Chip selects
- */
-
-#define PXA_CS0_PHYS 0x00000000
-#define PXA_CS1_PHYS 0x04000000
-#define PXA_CS2_PHYS 0x08000000
-#define PXA_CS3_PHYS 0x0C000000
-#define PXA_CS4_PHYS 0x10000000
-#define PXA_CS5_PHYS 0x14000000
-
-
-/*
- * Personal Computer Memory Card International Association (PCMCIA) sockets
- */
-
-#define PCMCIAPrtSp 0x04000000 /* PCMCIA Partition Space [byte] */
-#define PCMCIASp (4*PCMCIAPrtSp) /* PCMCIA Space [byte] */
-#define PCMCIAIOSp PCMCIAPrtSp /* PCMCIA I/O Space [byte] */
-#define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */
-#define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */
-
-#define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */
-#define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */
-#define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */
-#define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */
-
-#define PCMCIA1Sp PCMCIASp /* PCMCIA 1 Space [byte] */
-#define PCMCIA1IOSp PCMCIAIOSp /* PCMCIA 1 I/O Space [byte] */
-#define PCMCIA1AttrSp PCMCIAAttrSp /* PCMCIA 1 Attribute Space [byte] */
-#define PCMCIA1MemSp PCMCIAMemSp /* PCMCIA 1 Memory Space [byte] */
-
-#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \
- (0x20000000 + (Nb)*PCMCIASp)
-#define _PCMCIAIO(Nb) _PCMCIA (Nb) /* PCMCIA I/O [0..1] */
-#define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \
- (_PCMCIA (Nb) + 2*PCMCIAPrtSp)
-#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \
- (_PCMCIA (Nb) + 3*PCMCIAPrtSp)
-
-#define _PCMCIA0 _PCMCIA (0) /* PCMCIA 0 */
-#define _PCMCIA0IO _PCMCIAIO (0) /* PCMCIA 0 I/O */
-#define _PCMCIA0Attr _PCMCIAAttr (0) /* PCMCIA 0 Attribute */
-#define _PCMCIA0Mem _PCMCIAMem (0) /* PCMCIA 0 Memory */
-
-#define _PCMCIA1 _PCMCIA (1) /* PCMCIA 1 */
-#define _PCMCIA1IO _PCMCIAIO (1) /* PCMCIA 1 I/O */
-#define _PCMCIA1Attr _PCMCIAAttr (1) /* PCMCIA 1 Attribute */
-#define _PCMCIA1Mem _PCMCIAMem (1) /* PCMCIA 1 Memory */
-
-
-
-/*
- * DMA Controller
- */
-#define DCSR(x) __REG2(0x40000000, (x) << 2)
-
-#define DCSR_RUN (1 << 31) /* Run Bit (read / write) */
-#define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch (read / write) */
-#define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */
-#define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */
-#define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */
-#define DCSR_ENDINTR (1 << 2) /* End Interrupt (read / write) */
-#define DCSR_STARTINTR (1 << 1) /* Start Interrupt (read / write) */
-#define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt (read / write) */
-
-#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
-#define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable (R/W) */
-#define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */
-#define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */
-#define DCSR_SETCMPST (1 << 25) /* Set Descriptor Compare Status */
-#define DCSR_CLRCMPST (1 << 24) /* Clear Descriptor Compare Status */
-#define DCSR_CMPST (1 << 10) /* The Descriptor Compare Status */
-#define DCSR_EORINTR (1 << 9) /* The end of Receive */
-#endif
-
-#define DALGN __REG(0x400000a0) /* DMA Alignment Register */
-#define DINT __REG(0x400000f0) /* DMA Interrupt Register */
-
-#define DRCMR(n) (*(((n) < 64) ? \
- &__REG2(0x40000100, ((n) & 0x3f) << 2) : \
- &__REG2(0x40001100, ((n) & 0x3f) << 2)))
-
-#define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */
-#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */
-
-#define DDADR(x) __REG2(0x40000200, (x) << 4)
-#define DSADR(x) __REG2(0x40000204, (x) << 4)
-#define DTADR(x) __REG2(0x40000208, (x) << 4)
-#define DCMD(x) __REG2(0x4000020c, (x) << 4)
-
-#define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor (mask) */
-#define DDADR_STOP (1 << 0) /* Stop (read / write) */
-
-#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */
-#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */
-#define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */
-#define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */
-#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */
-#define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */
-#define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */
-#define DCMD_BURST8 (1 << 16) /* 8 byte burst */
-#define DCMD_BURST16 (2 << 16) /* 16 byte burst */
-#define DCMD_BURST32 (3 << 16) /* 32 byte burst */
-#define DCMD_WIDTH1 (1 << 14) /* 1 byte width */
-#define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */
-#define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */
-#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
-
-/*
- * Real Time Clock
- */
-
-#define RCNR __REG(0x40900000) /* RTC Count Register */
-#define RTAR __REG(0x40900004) /* RTC Alarm Register */
-#define RTSR __REG(0x40900008) /* RTC Status Register */
-#define RTTR __REG(0x4090000C) /* RTC Timer Trim Register */
-#define PIAR __REG(0x40900038) /* Periodic Interrupt Alarm Register */
-
-#define RTSR_PICE (1 << 15) /* Periodic interrupt count enable */
-#define RTSR_PIALE (1 << 14) /* Periodic interrupt Alarm enable */
-#define RTSR_HZE (1 << 3) /* HZ interrupt enable */
-#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */
-#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */
-#define RTSR_AL (1 << 0) /* RTC alarm detected */
-
-
-/*
- * OS Timer & Match Registers
- */
-
-#define OSMR0 __REG(0x40A00000) /* */
-#define OSMR1 __REG(0x40A00004) /* */
-#define OSMR2 __REG(0x40A00008) /* */
-#define OSMR3 __REG(0x40A0000C) /* */
-#define OSMR4 __REG(0x40A00080) /* */
-#define OSCR __REG(0x40A00010) /* OS Timer Counter Register */
-#define OSCR4 __REG(0x40A00040) /* OS Timer Counter Register */
-#define OMCR4 __REG(0x40A000C0) /* */
-#define OSSR __REG(0x40A00014) /* OS Timer Status Register */
-#define OWER __REG(0x40A00018) /* OS Timer Watchdog Enable Register */
-#define OIER __REG(0x40A0001C) /* OS Timer Interrupt Enable Register */
-
-#define OSSR_M3 (1 << 3) /* Match status channel 3 */
-#define OSSR_M2 (1 << 2) /* Match status channel 2 */
-#define OSSR_M1 (1 << 1) /* Match status channel 1 */
-#define OSSR_M0 (1 << 0) /* Match status channel 0 */
-
-#define OWER_WME (1 << 0) /* Watchdog Match Enable */
-
-#define OIER_E3 (1 << 3) /* Interrupt enable channel 3 */
-#define OIER_E2 (1 << 2) /* Interrupt enable channel 2 */
-#define OIER_E1 (1 << 1) /* Interrupt enable channel 1 */
-#define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */
-
-
-/*
- * Interrupt Controller
- */
-
-#define ICIP __REG(0x40D00000) /* Interrupt Controller IRQ Pending Register */
-#define ICMR __REG(0x40D00004) /* Interrupt Controller Mask Register */
-#define ICLR __REG(0x40D00008) /* Interrupt Controller Level Register */
-#define ICFP __REG(0x40D0000C) /* Interrupt Controller FIQ Pending Register */
-#define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */
-#define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */
-
-#define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */
-#define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */
-#define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */
-#define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */
-#define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */
-
-/*
- * General Purpose I/O
- */
-
-#define GPLR0 __REG(0x40E00000) /* GPIO Pin-Level Register GPIO<31:0> */
-#define GPLR1 __REG(0x40E00004) /* GPIO Pin-Level Register GPIO<63:32> */
-#define GPLR2 __REG(0x40E00008) /* GPIO Pin-Level Register GPIO<80:64> */
-
-#define GPDR0 __REG(0x40E0000C) /* GPIO Pin Direction Register GPIO<31:0> */
-#define GPDR1 __REG(0x40E00010) /* GPIO Pin Direction Register GPIO<63:32> */
-#define GPDR2 __REG(0x40E00014) /* GPIO Pin Direction Register GPIO<80:64> */
-
-#define GPSR0 __REG(0x40E00018) /* GPIO Pin Output Set Register GPIO<31:0> */
-#define GPSR1 __REG(0x40E0001C) /* GPIO Pin Output Set Register GPIO<63:32> */
-#define GPSR2 __REG(0x40E00020) /* GPIO Pin Output Set Register GPIO<80:64> */
-
-#define GPCR0 __REG(0x40E00024) /* GPIO Pin Output Clear Register GPIO<31:0> */
-#define GPCR1 __REG(0x40E00028) /* GPIO Pin Output Clear Register GPIO <63:32> */
-#define GPCR2 __REG(0x40E0002C) /* GPIO Pin Output Clear Register GPIO <80:64> */
-
-#define GRER0 __REG(0x40E00030) /* GPIO Rising-Edge Detect Register GPIO<31:0> */
-#define GRER1 __REG(0x40E00034) /* GPIO Rising-Edge Detect Register GPIO<63:32> */
-#define GRER2 __REG(0x40E00038) /* GPIO Rising-Edge Detect Register GPIO<80:64> */
-
-#define GFER0 __REG(0x40E0003C) /* GPIO Falling-Edge Detect Register GPIO<31:0> */
-#define GFER1 __REG(0x40E00040) /* GPIO Falling-Edge Detect Register GPIO<63:32> */
-#define GFER2 __REG(0x40E00044) /* GPIO Falling-Edge Detect Register GPIO<80:64> */
-
-#define GEDR0 __REG(0x40E00048) /* GPIO Edge Detect Status Register GPIO<31:0> */
-#define GEDR1 __REG(0x40E0004C) /* GPIO Edge Detect Status Register GPIO<63:32> */
-#define GEDR2 __REG(0x40E00050) /* GPIO Edge Detect Status Register GPIO<80:64> */
-
-#define GAFR0_L __REG(0x40E00054) /* GPIO Alternate Function Select Register GPIO<15:0> */
-#define GAFR0_U __REG(0x40E00058) /* GPIO Alternate Function Select Register GPIO<31:16> */
-#define GAFR1_L __REG(0x40E0005C) /* GPIO Alternate Function Select Register GPIO<47:32> */
-#define GAFR1_U __REG(0x40E00060) /* GPIO Alternate Function Select Register GPIO<63:48> */
-#define GAFR2_L __REG(0x40E00064) /* GPIO Alternate Function Select Register GPIO<79:64> */
-#define GAFR2_U __REG(0x40E00068) /* GPIO Alternate Function Select Register GPIO<95-80> */
-#define GAFR3_L __REG(0x40E0006C) /* GPIO Alternate Function Select Register GPIO<111:96> */
-#define GAFR3_U __REG(0x40E00070) /* GPIO Alternate Function Select Register GPIO<127:112> */
-
-#define GPLR3 __REG(0x40E00100) /* GPIO Pin-Level Register GPIO<127:96> */
-#define GPDR3 __REG(0x40E0010C) /* GPIO Pin Direction Register GPIO<127:96> */
-#define GPSR3 __REG(0x40E00118) /* GPIO Pin Output Set Register GPIO<127:96> */
-#define GPCR3 __REG(0x40E00124) /* GPIO Pin Output Clear Register GPIO<127:96> */
-#define GRER3 __REG(0x40E00130) /* GPIO Rising-Edge Detect Register GPIO<127:96> */
-#define GFER3 __REG(0x40E0013C) /* GPIO Falling-Edge Detect Register GPIO<127:96> */
-#define GEDR3 __REG(0x40E00148) /* GPIO Edge Detect Status Register GPIO<127:96> */
-
-/* More handy macros. The argument is a literal GPIO number. */
-
-#define GPIO_bit(x) (1 << ((x) & 0x1f))
-
-#define _GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3)
-#define _GPDR(x) __REG2(0x40E0000C, ((x) & 0x60) >> 3)
-#define _GPSR(x) __REG2(0x40E00018, ((x) & 0x60) >> 3)
-#define _GPCR(x) __REG2(0x40E00024, ((x) & 0x60) >> 3)
-#define _GRER(x) __REG2(0x40E00030, ((x) & 0x60) >> 3)
-#define _GFER(x) __REG2(0x40E0003C, ((x) & 0x60) >> 3)
-#define _GEDR(x) __REG2(0x40E00048, ((x) & 0x60) >> 3)
-#define _GAFR(x) __REG2(0x40E00054, ((x) & 0x70) >> 2)
-
-#define GPLR(x) (*((((x) & 0x7f) < 96) ? &_GPLR(x) : &GPLR3))
-#define GPDR(x) (*((((x) & 0x7f) < 96) ? &_GPDR(x) : &GPDR3))
-#define GPSR(x) (*((((x) & 0x7f) < 96) ? &_GPSR(x) : &GPSR3))
-#define GPCR(x) (*((((x) & 0x7f) < 96) ? &_GPCR(x) : &GPCR3))
-#define GRER(x) (*((((x) & 0x7f) < 96) ? &_GRER(x) : &GRER3))
-#define GFER(x) (*((((x) & 0x7f) < 96) ? &_GFER(x) : &GFER3))
-#define GEDR(x) (*((((x) & 0x7f) < 96) ? &_GEDR(x) : &GEDR3))
-#define GAFR(x) (*((((x) & 0x7f) < 96) ? &_GAFR(x) : \
- ((((x) & 0x7f) < 112) ? &GAFR3_L : &GAFR3_U)))
-
-#endif
diff --git a/arch/arm/mach-pxa/include/mach/pxa25x.h b/arch/arm/mach-pxa/include/mach/pxa25x.h
new file mode 100644
index 000000000000..508c3ba1f4d0
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa25x.h
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA25x_H
+#define __MACH_PXA25x_H
+
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa25x.h>
+
+#endif /* __MACH_PXA25x_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa27x.h b/arch/arm/mach-pxa/include/mach/pxa27x.h
new file mode 100644
index 000000000000..6876e16c2970
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa27x.h
@@ -0,0 +1,19 @@
+#ifndef __MACH_PXA27x_H
+#define __MACH_PXA27x_H
+
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa27x.h>
+
+#define ARB_CNTRL __REG(0x48000048) /* Arbiter Control Register */
+
+#define ARB_DMA_SLV_PARK (1<<31) /* Be parked with DMA slave when idle */
+#define ARB_CI_PARK (1<<30) /* Be parked with Camera Interface when idle */
+#define ARB_EX_MEM_PARK (1<<29) /* Be parked with external MEMC when idle */
+#define ARB_INT_MEM_PARK (1<<28) /* Be parked with internal MEMC when idle */
+#define ARB_USB_PARK (1<<27) /* Be parked with USB when idle */
+#define ARB_LCD_PARK (1<<26) /* Be parked with LCD when idle */
+#define ARB_DMA_PARK (1<<25) /* Be parked with DMA when idle */
+#define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */
+#define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */
+#endif /* __MACH_PXA27x_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h b/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h
index d83393e25273..1209c44aa6f1 100644
--- a/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h
+++ b/arch/arm/mach-pxa/include/mach/pxa2xx-gpio.h
@@ -3,6 +3,8 @@
#warning Please use mfp-pxa2[57]x.h instead of pxa2xx-gpio.h
+#include <mach/gpio.h>
+
/* GPIO alternate function assignments */
#define GPIO1_RST 1 /* reset */
diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
index 77102d695cc7..4fcddd9cab76 100644
--- a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
+++ b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
@@ -14,6 +14,19 @@
#ifndef __PXA2XX_REGS_H
#define __PXA2XX_REGS_H
+#include <mach/hardware.h>
+
+/*
+ * PXA Chip selects
+ */
+
+#define PXA_CS0_PHYS 0x00000000
+#define PXA_CS1_PHYS 0x04000000
+#define PXA_CS2_PHYS 0x08000000
+#define PXA_CS3_PHYS 0x0C000000
+#define PXA_CS4_PHYS 0x10000000
+#define PXA_CS5_PHYS 0x14000000
+
/*
* Memory controller
*/
@@ -69,24 +82,6 @@
#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */
#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */
-
-#ifdef CONFIG_PXA27x
-
-#define ARB_CNTRL __REG(0x48000048) /* Arbiter Control Register */
-
-#define ARB_DMA_SLV_PARK (1<<31) /* Be parked with DMA slave when idle */
-#define ARB_CI_PARK (1<<30) /* Be parked with Camera Interface when idle */
-#define ARB_EX_MEM_PARK (1<<29) /* Be parked with external MEMC when idle */
-#define ARB_INT_MEM_PARK (1<<28) /* Be parked with internal MEMC when idle */
-#define ARB_USB_PARK (1<<27) /* Be parked with USB when idle */
-#define ARB_LCD_PARK (1<<26) /* Be parked with LCD when idle */
-#define ARB_DMA_PARK (1<<25) /* Be parked with DMA when idle */
-#define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */
-#define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */
-
-#endif
-
-
/*
* Power Manager
*/
diff --git a/arch/arm/mach-pxa/include/mach/pxa300.h b/arch/arm/mach-pxa/include/mach/pxa300.h
new file mode 100644
index 000000000000..2f33076c9e48
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa300.h
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA300_H
+#define __MACH_PXA300_H
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa300.h>
+
+#endif /* __MACH_PXA300_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa320.h b/arch/arm/mach-pxa/include/mach/pxa320.h
new file mode 100644
index 000000000000..cab78e903273
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa320.h
@@ -0,0 +1,9 @@
+#ifndef __MACH_PXA320_H
+#define __MACH_PXA320_H
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa320.h>
+
+#endif /* __MACH_PXA320_H */
+
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
index bcf3fb2c4b3a..7d1a059b3d43 100644
--- a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
@@ -13,6 +13,17 @@
#ifndef __ASM_ARCH_PXA3XX_REGS_H
#define __ASM_ARCH_PXA3XX_REGS_H
+#include <mach/hardware.h>
+
+/*
+ * Static Chip Selects
+ */
+
+#define PXA300_CS0_PHYS (0x00000000) /* PXA300/PXA310 _only_ */
+#define PXA300_CS1_PHYS (0x30000000) /* PXA300/PXA310 _only_ */
+#define PXA3xx_CS2_PHYS (0x10000000)
+#define PXA3xx_CS3_PHYS (0x14000000)
+
/*
* Oscillator Configuration Register (OSCC)
*/
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h b/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
index eb35fca9aea5..3478eae32d8a 100644
--- a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
@@ -49,6 +49,9 @@ struct pxa3xx_nand_platform_data {
*/
int enable_arbiter;
+ /* allow platform code to keep OBM/bootloader defined NFC config */
+ int keep_config;
+
const struct mtd_partition *parts;
unsigned int nr_parts;
diff --git a/arch/arm/mach-pxa/include/mach/pxa930.h b/arch/arm/mach-pxa/include/mach/pxa930.h
new file mode 100644
index 000000000000..d45f76a9b54d
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa930.h
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA930_H
+#define __MACH_PXA930_H
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa930.h>
+
+#endif /* __MACH_PXA930_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-intc.h b/arch/arm/mach-pxa/include/mach/regs-intc.h
new file mode 100644
index 000000000000..ad23e74b762f
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/regs-intc.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_REGS_INTC_H
+#define __ASM_MACH_REGS_INTC_H
+
+#include <mach/hardware.h>
+
+/*
+ * Interrupt Controller
+ */
+
+#define ICIP __REG(0x40D00000) /* Interrupt Controller IRQ Pending Register */
+#define ICMR __REG(0x40D00004) /* Interrupt Controller Mask Register */
+#define ICLR __REG(0x40D00008) /* Interrupt Controller Level Register */
+#define ICFP __REG(0x40D0000C) /* Interrupt Controller FIQ Pending Register */
+#define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */
+#define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */
+
+#define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */
+#define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */
+#define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */
+#define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */
+#define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */
+
+#endif /* __ASM_MACH_REGS_INTC_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-ost.h b/arch/arm/mach-pxa/include/mach/regs-ost.h
new file mode 100644
index 000000000000..a3e5f86ef67e
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/regs-ost.h
@@ -0,0 +1,34 @@
+#ifndef __ASM_MACH_REGS_OST_H
+#define __ASM_MACH_REGS_OST_H
+
+#include <mach/hardware.h>
+
+/*
+ * OS Timer & Match Registers
+ */
+
+#define OSMR0 __REG(0x40A00000) /* */
+#define OSMR1 __REG(0x40A00004) /* */
+#define OSMR2 __REG(0x40A00008) /* */
+#define OSMR3 __REG(0x40A0000C) /* */
+#define OSMR4 __REG(0x40A00080) /* */
+#define OSCR __REG(0x40A00010) /* OS Timer Counter Register */
+#define OSCR4 __REG(0x40A00040) /* OS Timer Counter Register */
+#define OMCR4 __REG(0x40A000C0) /* */
+#define OSSR __REG(0x40A00014) /* OS Timer Status Register */
+#define OWER __REG(0x40A00018) /* OS Timer Watchdog Enable Register */
+#define OIER __REG(0x40A0001C) /* OS Timer Interrupt Enable Register */
+
+#define OSSR_M3 (1 << 3) /* Match status channel 3 */
+#define OSSR_M2 (1 << 2) /* Match status channel 2 */
+#define OSSR_M1 (1 << 1) /* Match status channel 1 */
+#define OSSR_M0 (1 << 0) /* Match status channel 0 */
+
+#define OWER_WME (1 << 0) /* Watchdog Match Enable */
+
+#define OIER_E3 (1 << 3) /* Interrupt enable channel 3 */
+#define OIER_E2 (1 << 2) /* Interrupt enable channel 2 */
+#define OIER_E1 (1 << 1) /* Interrupt enable channel 1 */
+#define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */
+
+#endif /* __ASM_MACH_REGS_OST_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-rtc.h b/arch/arm/mach-pxa/include/mach/regs-rtc.h
new file mode 100644
index 000000000000..f0e4a589bbe1
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/regs-rtc.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_REGS_RTC_H
+#define __ASM_MACH_REGS_RTC_H
+
+#include <mach/hardware.h>
+
+/*
+ * Real Time Clock
+ */
+
+#define RCNR __REG(0x40900000) /* RTC Count Register */
+#define RTAR __REG(0x40900004) /* RTC Alarm Register */
+#define RTSR __REG(0x40900008) /* RTC Status Register */
+#define RTTR __REG(0x4090000C) /* RTC Timer Trim Register */
+#define PIAR __REG(0x40900038) /* Periodic Interrupt Alarm Register */
+
+#define RTSR_PICE (1 << 15) /* Periodic interrupt count enable */
+#define RTSR_PIALE (1 << 14) /* Periodic interrupt Alarm enable */
+#define RTSR_HZE (1 << 3) /* HZ interrupt enable */
+#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */
+#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */
+#define RTSR_AL (1 << 0) /* RTC alarm detected */
+
+#endif /* __ASM_MACH_REGS_RTC_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-ssp.h b/arch/arm/mach-pxa/include/mach/regs-ssp.h
index cf31986f6f05..6a2ed35acd59 100644
--- a/arch/arm/mach-pxa/include/mach/regs-ssp.h
+++ b/arch/arm/mach-pxa/include/mach/regs-ssp.h
@@ -37,7 +37,6 @@
#if defined(CONFIG_PXA25x)
#define SSCR0_SCR (0x0000ff00) /* Serial Clock Rate (mask) */
#define SSCR0_SerClkDiv(x) ((((x) - 2)/2) << 8) /* Divisor [2..512] */
-
#elif defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
#define SSCR0_SCR (0x000fff00) /* Serial Clock Rate (mask) */
#define SSCR0_SerClkDiv(x) (((x) - 1) << 8) /* Divisor [1..4096] */
@@ -50,7 +49,7 @@
#define SSCR0_TUM (1 << 23) /* Transmit FIFO underrun interrupt mask */
#define SSCR0_FRDC (0x07000000) /* Frame rate divider control (mask) */
#define SSCR0_SlotsPerFrm(x) (((x) - 1) << 24) /* Time slots per frame [1..8] */
-#define SSCR0_ADC (1 << 30) /* Audio clock select */
+#define SSCR0_ACS (1 << 30) /* Audio clock select */
#define SSCR0_MOD (1 << 31) /* Mode (normal or network) */
#endif
@@ -109,6 +108,11 @@
#define SSSR_TINT (1 << 19) /* Receiver Time-out Interrupt */
#define SSSR_PINT (1 << 18) /* Peripheral Trailing Byte Interrupt */
+#if defined(CONFIG_PXA3xx)
+#define SSPSP_EDMYSTOP(x) ((x) << 28) /* Extended Dummy Stop */
+#define SSPSP_EDMYSTRT(x) ((x) << 26) /* Extended Dummy Start */
+#endif
+
#define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */
#define SSPSP_DMYSTOP(x) ((x) << 23) /* Dummy Stop */
#define SSPSP_SFRMWDTH(x) ((x) << 16) /* Serial Frame Width */
diff --git a/arch/arm/mach-pxa/include/mach/system.h b/arch/arm/mach-pxa/include/mach/system.h
index 0f381e692999..d1fce8b6d105 100644
--- a/arch/arm/mach-pxa/include/mach/system.h
+++ b/arch/arm/mach-pxa/include/mach/system.h
@@ -13,7 +13,6 @@
#include <asm/proc-fns.h>
#include "hardware.h"
#include "pxa2xx-regs.h"
-#include "pxa-regs.h"
static inline void arch_idle(void)
{
@@ -21,4 +20,4 @@ static inline void arch_idle(void)
}
-void arch_reset(char mode);
+void arch_reset(char mode, const char *cmd);
diff --git a/arch/arm/mach-pxa/include/mach/uncompress.h b/arch/arm/mach-pxa/include/mach/uncompress.h
index f4b029c03957..5706cea95d11 100644
--- a/arch/arm/mach-pxa/include/mach/uncompress.h
+++ b/arch/arm/mach-pxa/include/mach/uncompress.h
@@ -35,7 +35,8 @@ static inline void flush(void)
static inline void arch_decomp_setup(void)
{
- if (machine_is_littleton() || machine_is_intelmote2())
+ if (machine_is_littleton() || machine_is_intelmote2()
+ || machine_is_csb726())
UART = STUART;
}
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index fa69c3a6a38e..f6e0300e4f64 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -20,7 +20,8 @@
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
-#include <mach/pxa-regs.h>
+#include <mach/gpio.h>
+#include <mach/regs-intc.h>
#include "generic.h"
@@ -51,6 +52,72 @@ static struct irq_chip pxa_internal_irq_chip = {
.unmask = pxa_unmask_irq,
};
+/*
+ * GPIO IRQs for GPIO 0 and 1
+ */
+static int pxa_set_low_gpio_type(unsigned int irq, unsigned int type)
+{
+ int gpio = irq - IRQ_GPIO0;
+
+ if (__gpio_is_occupied(gpio)) {
+ pr_err("%s failed: GPIO is configured\n", __func__);
+ return -EINVAL;
+ }
+
+ if (type & IRQ_TYPE_EDGE_RISING)
+ GRER0 |= GPIO_bit(gpio);
+ else
+ GRER0 &= ~GPIO_bit(gpio);
+
+ if (type & IRQ_TYPE_EDGE_FALLING)
+ GFER0 |= GPIO_bit(gpio);
+ else
+ GFER0 &= ~GPIO_bit(gpio);
+
+ return 0;
+}
+
+static void pxa_ack_low_gpio(unsigned int irq)
+{
+ GEDR0 = (1 << (irq - IRQ_GPIO0));
+}
+
+static void pxa_mask_low_gpio(unsigned int irq)
+{
+ ICMR &= ~(1 << (irq - PXA_IRQ(0)));
+}
+
+static void pxa_unmask_low_gpio(unsigned int irq)
+{
+ ICMR |= 1 << (irq - PXA_IRQ(0));
+}
+
+static struct irq_chip pxa_low_gpio_chip = {
+ .name = "GPIO-l",
+ .ack = pxa_ack_low_gpio,
+ .mask = pxa_mask_low_gpio,
+ .unmask = pxa_unmask_low_gpio,
+ .set_type = pxa_set_low_gpio_type,
+};
+
+static void __init pxa_init_low_gpio_irq(set_wake_t fn)
+{
+ int irq;
+
+ /* clear edge detection on GPIO 0 and 1 */
+ GFER0 &= ~0x3;
+ GRER0 &= ~0x3;
+ GEDR0 = 0x3;
+
+ for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
+ set_irq_chip(irq, &pxa_low_gpio_chip);
+ set_irq_handler(irq, handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ pxa_low_gpio_chip.set_wake = fn;
+}
+
void __init pxa_init_irq(int irq_nr, set_wake_t fn)
{
int irq;
@@ -72,6 +139,7 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
}
pxa_internal_irq_chip.set_wake = fn;
+ pxa_init_low_gpio_irq(fn);
}
#ifdef CONFIG_PM
diff --git a/arch/arm/mach-pxa/leds-idp.c b/arch/arm/mach-pxa/leds-idp.c
index 18b20d469410..8b9c17142d5a 100644
--- a/arch/arm/mach-pxa/leds-idp.c
+++ b/arch/arm/mach-pxa/leds-idp.c
@@ -18,7 +18,7 @@
#include <asm/leds.h>
#include <asm/system.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa25x.h>
#include <mach/idp.h>
#include "leds.h"
diff --git a/arch/arm/mach-pxa/leds-lubbock.c b/arch/arm/mach-pxa/leds-lubbock.c
index 1a258029c33c..e26d5efe1969 100644
--- a/arch/arm/mach-pxa/leds-lubbock.c
+++ b/arch/arm/mach-pxa/leds-lubbock.c
@@ -16,7 +16,7 @@
#include <mach/hardware.h>
#include <asm/leds.h>
#include <asm/system.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa25x.h>
#include <mach/lubbock.h>
#include "leds.h"
diff --git a/arch/arm/mach-pxa/leds-mainstone.c b/arch/arm/mach-pxa/leds-mainstone.c
index 95e06b849634..db4af5eee8b2 100644
--- a/arch/arm/mach-pxa/leds-mainstone.c
+++ b/arch/arm/mach-pxa/leds-mainstone.c
@@ -16,7 +16,7 @@
#include <asm/leds.h>
#include <asm/system.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa27x.h>
#include <mach/mainstone.h>
#include "leds.h"
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index 31da7f3c06f6..e13f6a81c223 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -39,8 +39,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-#include <mach/pxa-regs.h>
-#include <mach/mfp-pxa300.h>
+#include <mach/pxa300.h>
#include <mach/pxafb.h>
#include <mach/ssp.h>
#include <mach/pxa2xx_spi.h>
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index de3f67daaacf..d64395f26a3e 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -38,9 +38,8 @@
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
+#include <mach/pxa27x.h>
+#include <mach/gpio.h>
#include <mach/lpd270.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index bff704354c1a..f04c8333dff7 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -41,15 +41,15 @@
#include <asm/hardware/sa1111.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include <mach/pxa25x.h>
+#include <mach/gpio.h>
#include <mach/audio.h>
#include <mach/lubbock.h>
#include <mach/udc.h>
#include <mach/irda.h>
#include <mach/pxafb.h>
#include <mach/mmc.h>
+#include <mach/pm.h>
#include "generic.h"
#include "clock.h"
@@ -113,8 +113,14 @@ static unsigned long lubbock_pin_config[] __initdata = {
GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,
};
+#define LUB_HEXLED __LUB_REG(LUBBOCK_FPGA_PHYS + 0x010)
#define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
+void lubbock_set_hexled(uint32_t value)
+{
+ LUB_HEXLED = value;
+}
+
void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
{
unsigned long flags;
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 21b821e1a60d..deeea1c2782b 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -25,14 +25,14 @@
#include <linux/mtd/physmap.h>
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
+#include <linux/usb/gpio_vbus.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
#include <mach/magician.h>
-#include <mach/mfp-pxa27x.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
#include <mach/pxafb.h>
#include <mach/i2c.h>
#include <mach/mmc.h>
@@ -66,6 +66,11 @@ static unsigned long magician_pin_config[] __initdata = {
GPIO31_I2S_SYNC,
GPIO113_I2S_SYSCLK,
+ /* SSP 1 */
+ GPIO23_SSP1_SCLK,
+ GPIO24_SSP1_SFRM,
+ GPIO25_SSP1_TXD,
+
/* SSP 2 */
GPIO19_SSP2_SCLK,
GPIO14_SSP2_SFRM,
@@ -148,22 +153,31 @@ static struct pxaficp_platform_data magician_ficp_info = {
* GPIO Keys
*/
+#define INIT_KEY(_code, _gpio, _desc) \
+ { \
+ .code = KEY_##_code, \
+ .gpio = _gpio, \
+ .desc = _desc, \
+ .type = EV_KEY, \
+ .wakeup = 1, \
+ }
+
static struct gpio_keys_button magician_button_table[] = {
- {KEY_POWER, GPIO0_MAGICIAN_KEY_POWER, 0, "Power button"},
- {KEY_ESC, GPIO37_MAGICIAN_KEY_HANGUP, 0, "Hangup button"},
- {KEY_F10, GPIO38_MAGICIAN_KEY_CONTACTS, 0, "Contacts button"},
- {KEY_CALENDAR, GPIO90_MAGICIAN_KEY_CALENDAR, 0, "Calendar button"},
- {KEY_CAMERA, GPIO91_MAGICIAN_KEY_CAMERA, 0, "Camera button"},
- {KEY_UP, GPIO93_MAGICIAN_KEY_UP, 0, "Up button"},
- {KEY_DOWN, GPIO94_MAGICIAN_KEY_DOWN, 0, "Down button"},
- {KEY_LEFT, GPIO95_MAGICIAN_KEY_LEFT, 0, "Left button"},
- {KEY_RIGHT, GPIO96_MAGICIAN_KEY_RIGHT, 0, "Right button"},
- {KEY_KPENTER, GPIO97_MAGICIAN_KEY_ENTER, 0, "Action button"},
- {KEY_RECORD, GPIO98_MAGICIAN_KEY_RECORD, 0, "Record button"},
- {KEY_VOLUMEUP, GPIO100_MAGICIAN_KEY_VOL_UP, 0, "Volume up"},
- {KEY_VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, 0, "Volume down"},
- {KEY_PHONE, GPIO102_MAGICIAN_KEY_PHONE, 0, "Phone button"},
- {KEY_PLAY, GPIO99_MAGICIAN_HEADPHONE_IN, 0, "Headset button"},
+ INIT_KEY(POWER, GPIO0_MAGICIAN_KEY_POWER, "Power button"),
+ INIT_KEY(ESC, GPIO37_MAGICIAN_KEY_HANGUP, "Hangup button"),
+ INIT_KEY(F10, GPIO38_MAGICIAN_KEY_CONTACTS, "Contacts button"),
+ INIT_KEY(CALENDAR, GPIO90_MAGICIAN_KEY_CALENDAR, "Calendar button"),
+ INIT_KEY(CAMERA, GPIO91_MAGICIAN_KEY_CAMERA, "Camera button"),
+ INIT_KEY(UP, GPIO93_MAGICIAN_KEY_UP, "Up button"),
+ INIT_KEY(DOWN, GPIO94_MAGICIAN_KEY_DOWN, "Down button"),
+ INIT_KEY(LEFT, GPIO95_MAGICIAN_KEY_LEFT, "Left button"),
+ INIT_KEY(RIGHT, GPIO96_MAGICIAN_KEY_RIGHT, "Right button"),
+ INIT_KEY(KPENTER, GPIO97_MAGICIAN_KEY_ENTER, "Action button"),
+ INIT_KEY(RECORD, GPIO98_MAGICIAN_KEY_RECORD, "Record button"),
+ INIT_KEY(VOLUMEUP, GPIO100_MAGICIAN_KEY_VOL_UP, "Volume up"),
+ INIT_KEY(VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, "Volume down"),
+ INIT_KEY(PHONE, GPIO102_MAGICIAN_KEY_PHONE, "Phone button"),
+ INIT_KEY(PLAY, GPIO99_MAGICIAN_HEADPHONE_IN, "Headset button"),
};
static struct gpio_keys_platform_data gpio_keys_data = {
@@ -189,7 +203,7 @@ static struct platform_device gpio_keys = {
static struct resource egpio_resources[] = {
[0] = {
.start = PXA_CS3_PHYS,
- .end = PXA_CS3_PHYS + 0x20,
+ .end = PXA_CS3_PHYS + 0x20 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -420,7 +434,7 @@ static struct gpio_led gpio_leds[] = {
},
{
.name = "magician::phone_bl",
- .default_trigger = "none",
+ .default_trigger = "backlight",
.gpio = GPIO103_MAGICIAN_LED_KP,
},
};
@@ -468,8 +482,6 @@ static struct pasic3_led pasic3_leds[] = {
},
};
-static struct platform_device pasic3;
-
static struct pasic3_leds_machinfo pasic3_leds_info = {
.num_leds = ARRAY_SIZE(pasic3_leds),
.power_gpio = EGPIO_MAGICIAN_LED_POWER,
@@ -495,7 +507,6 @@ static struct resource pasic3_resources[] = {
};
static struct pasic3_platform_data pasic3_platform_data = {
- .bus_shift = 2,
.led_pdata = &pasic3_leds_info,
.clock_rate = 4000000,
};
@@ -511,6 +522,31 @@ static struct platform_device pasic3 = {
};
/*
+ * USB "Transceiver"
+ */
+
+static struct resource gpio_vbus_resource = {
+ .flags = IORESOURCE_IRQ,
+ .start = IRQ_MAGICIAN_VBUS,
+ .end = IRQ_MAGICIAN_VBUS,
+};
+
+static struct gpio_vbus_mach_info gpio_vbus_info = {
+ .gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
+ .gpio_vbus = EGPIO_MAGICIAN_CABLE_STATE_USB,
+};
+
+static struct platform_device gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &gpio_vbus_resource,
+ .dev = {
+ .platform_data = &gpio_vbus_info,
+ },
+};
+
+/*
* External power
*/
@@ -586,15 +622,17 @@ static struct pda_power_pdata power_supply_info = {
static struct resource power_supply_resources[] = {
[0] = {
.name = "ac",
- .flags = IORESOURCE_IRQ,
- .start = IRQ_MAGICIAN_AC,
- .end = IRQ_MAGICIAN_AC,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+ IORESOURCE_IRQ_LOWEDGE,
+ .start = IRQ_MAGICIAN_VBUS,
+ .end = IRQ_MAGICIAN_VBUS,
},
[1] = {
.name = "usb",
- .flags = IORESOURCE_IRQ,
- .start = IRQ_MAGICIAN_AC,
- .end = IRQ_MAGICIAN_AC,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+ IORESOURCE_IRQ_LOWEDGE,
+ .start = IRQ_MAGICIAN_VBUS,
+ .end = IRQ_MAGICIAN_VBUS,
},
};
@@ -688,11 +726,9 @@ static void magician_set_vpp(struct map_info *map, int vpp)
gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
}
-#define PXA_CS_SIZE 0x04000000
-
static struct resource strataflash_resource = {
.start = PXA_CS0_PHYS,
- .end = PXA_CS0_PHYS + PXA_CS_SIZE - 1,
+ .end = PXA_CS0_PHYS + SZ_64M - 1,
.flags = IORESOURCE_MEM,
};
@@ -720,6 +756,7 @@ static struct platform_device *devices[] __initdata = {
&egpio,
&backlight,
&pasic3,
+ &gpio_vbus,
&power_supply,
&strataflash,
&leds_gpio,
@@ -743,6 +780,7 @@ static void __init magician_init(void)
gpio_direction_output(GPIO83_MAGICIAN_nIR_EN, 1);
pxa_set_ficp_info(&magician_ficp_info);
}
+ pxa27x_set_i2c_power_info(NULL);
pxa_set_i2c_info(NULL);
pxa_set_mci_info(&magician_mci_info);
pxa_set_ohci_info(&magician_ohci_info);
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 5f224968043c..a6c8429e975f 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -41,9 +41,8 @@
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
+#include <mach/pxa27x.h>
+#include <mach/gpio.h>
#include <mach/mainstone.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
index 33626de8cbf6..7ffb91d64c39 100644
--- a/arch/arm/mach-pxa/mfp-pxa2xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -18,15 +18,12 @@
#include <linux/init.h>
#include <linux/sysdev.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/gpio.h>
#include <mach/pxa2xx-regs.h>
#include <mach/mfp-pxa2xx.h>
#include "generic.h"
-#define gpio_to_bank(gpio) ((gpio) >> 5)
-
#define PGSR(x) __REG2(0x40F00020, (x) << 2)
#define __GAFR(u, x) __REG2((u) ? 0x40E00058 : 0x40E00054, (x) << 3)
#define GAFR_L(x) __GAFR(0, x)
diff --git a/arch/arm/mach-pxa/mfp-pxa3xx.c b/arch/arm/mach-pxa/mfp-pxa3xx.c
index eb197a6e8e94..7a270eecd480 100644
--- a/arch/arm/mach-pxa/mfp-pxa3xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa3xx.c
@@ -20,183 +20,9 @@
#include <linux/sysdev.h>
#include <mach/hardware.h>
-#include <mach/mfp.h>
#include <mach/mfp-pxa3xx.h>
#include <mach/pxa3xx-regs.h>
-/* mfp_spin_lock is used to ensure that MFP register configuration
- * (most likely a read-modify-write operation) is atomic, and that
- * mfp_table[] is consistent
- */
-static DEFINE_SPINLOCK(mfp_spin_lock);
-
-static void __iomem *mfpr_mmio_base = (void __iomem *)&__REG(MFPR_BASE);
-
-struct pxa3xx_mfp_pin {
- unsigned long config; /* -1 for not configured */
- unsigned long mfpr_off; /* MFPRxx Register offset */
- unsigned long mfpr_run; /* Run-Mode Register Value */
- unsigned long mfpr_lpm; /* Low Power Mode Register Value */
-};
-
-static struct pxa3xx_mfp_pin mfp_table[MFP_PIN_MAX];
-
-/* mapping of MFP_LPM_* definitions to MFPR_LPM_* register bits */
-static const unsigned long mfpr_lpm[] = {
- MFPR_LPM_INPUT,
- MFPR_LPM_DRIVE_LOW,
- MFPR_LPM_DRIVE_HIGH,
- MFPR_LPM_PULL_LOW,
- MFPR_LPM_PULL_HIGH,
- MFPR_LPM_FLOAT,
-};
-
-/* mapping of MFP_PULL_* definitions to MFPR_PULL_* register bits */
-static const unsigned long mfpr_pull[] = {
- MFPR_PULL_NONE,
- MFPR_PULL_LOW,
- MFPR_PULL_HIGH,
- MFPR_PULL_BOTH,
-};
-
-/* mapping of MFP_LPM_EDGE_* definitions to MFPR_EDGE_* register bits */
-static const unsigned long mfpr_edge[] = {
- MFPR_EDGE_NONE,
- MFPR_EDGE_RISE,
- MFPR_EDGE_FALL,
- MFPR_EDGE_BOTH,
-};
-
-#define mfpr_readl(off) \
- __raw_readl(mfpr_mmio_base + (off))
-
-#define mfpr_writel(off, val) \
- __raw_writel(val, mfpr_mmio_base + (off))
-
-#define mfp_configured(p) ((p)->config != -1)
-
-/*
- * perform a read-back of any MFPR register to make sure the
- * previous writings are finished
- */
-#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0)
-
-static inline void __mfp_config_run(struct pxa3xx_mfp_pin *p)
-{
- if (mfp_configured(p))
- mfpr_writel(p->mfpr_off, p->mfpr_run);
-}
-
-static inline void __mfp_config_lpm(struct pxa3xx_mfp_pin *p)
-{
- if (mfp_configured(p)) {
- unsigned long mfpr_clr = (p->mfpr_run & ~MFPR_EDGE_BOTH) | MFPR_EDGE_CLEAR;
- if (mfpr_clr != p->mfpr_run)
- mfpr_writel(p->mfpr_off, mfpr_clr);
- if (p->mfpr_lpm != mfpr_clr)
- mfpr_writel(p->mfpr_off, p->mfpr_lpm);
- }
-}
-
-void pxa3xx_mfp_config(unsigned long *mfp_cfgs, int num)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&mfp_spin_lock, flags);
-
- for (i = 0; i < num; i++, mfp_cfgs++) {
- unsigned long tmp, c = *mfp_cfgs;
- struct pxa3xx_mfp_pin *p;
- int pin, af, drv, lpm, edge, pull;
-
- pin = MFP_PIN(c);
- BUG_ON(pin >= MFP_PIN_MAX);
- p = &mfp_table[pin];
-
- af = MFP_AF(c);
- drv = MFP_DS(c);
- lpm = MFP_LPM_STATE(c);
- edge = MFP_LPM_EDGE(c);
- pull = MFP_PULL(c);
-
- /* run-mode pull settings will conflict with MFPR bits of
- * low power mode state, calculate mfpr_run and mfpr_lpm
- * individually if pull != MFP_PULL_NONE
- */
- tmp = MFPR_AF_SEL(af) | MFPR_DRIVE(drv);
-
- if (likely(pull == MFP_PULL_NONE)) {
- p->mfpr_run = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
- p->mfpr_lpm = p->mfpr_run;
- } else {
- p->mfpr_lpm = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
- p->mfpr_run = tmp | mfpr_pull[pull];
- }
-
- p->config = c; __mfp_config_run(p);
- }
-
- mfpr_sync();
- spin_unlock_irqrestore(&mfp_spin_lock, flags);
-}
-
-unsigned long pxa3xx_mfp_read(int mfp)
-{
- unsigned long val, flags;
-
- BUG_ON(mfp >= MFP_PIN_MAX);
-
- spin_lock_irqsave(&mfp_spin_lock, flags);
- val = mfpr_readl(mfp_table[mfp].mfpr_off);
- spin_unlock_irqrestore(&mfp_spin_lock, flags);
-
- return val;
-}
-
-void pxa3xx_mfp_write(int mfp, unsigned long val)
-{
- unsigned long flags;
-
- BUG_ON(mfp >= MFP_PIN_MAX);
-
- spin_lock_irqsave(&mfp_spin_lock, flags);
- mfpr_writel(mfp_table[mfp].mfpr_off, val);
- mfpr_sync();
- spin_unlock_irqrestore(&mfp_spin_lock, flags);
-}
-
-void __init pxa3xx_mfp_init_addr(struct pxa3xx_mfp_addr_map *map)
-{
- struct pxa3xx_mfp_addr_map *p;
- unsigned long offset, flags;
- int i;
-
- spin_lock_irqsave(&mfp_spin_lock, flags);
-
- for (p = map; p->start != MFP_PIN_INVALID; p++) {
- offset = p->offset;
- i = p->start;
-
- do {
- mfp_table[i].mfpr_off = offset;
- mfp_table[i].mfpr_run = 0;
- mfp_table[i].mfpr_lpm = 0;
- offset += 4; i++;
- } while ((i <= p->end) && (p->end != -1));
- }
-
- spin_unlock_irqrestore(&mfp_spin_lock, flags);
-}
-
-void __init pxa3xx_init_mfp(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(mfp_table); i++)
- mfp_table[i].config = -1;
-}
-
#ifdef CONFIG_PM
/*
* Configure the MFPs appropriately for suspend/resume.
@@ -207,23 +33,13 @@ void __init pxa3xx_init_mfp(void)
*/
static int pxa3xx_mfp_suspend(struct sys_device *d, pm_message_t state)
{
- int pin;
-
- for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) {
- struct pxa3xx_mfp_pin *p = &mfp_table[pin];
- __mfp_config_lpm(p);
- }
+ mfp_config_lpm();
return 0;
}
static int pxa3xx_mfp_resume(struct sys_device *d)
{
- int pin;
-
- for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++) {
- struct pxa3xx_mfp_pin *p = &mfp_table[pin];
- __mfp_config_run(p);
- }
+ mfp_config_run();
/* clear RDH bit when MFP settings are restored
*
@@ -231,7 +47,6 @@ static int pxa3xx_mfp_resume(struct sys_device *d)
* preserve them here in case they will be referenced later
*/
ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
-
return 0;
}
#else
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index 2b427e015b6f..97c93a7a285c 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -36,13 +36,15 @@
#include <linux/power_supply.h>
#include <linux/wm97xx_batt.h>
#include <linux/mtd/physmap.h>
+#include <linux/usb/gpio_vbus.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/mfp-pxa27x.h>
+
+#include <mach/pxa27x.h>
+#include <mach/regs-rtc.h>
#include <mach/pxa27x_keypad.h>
#include <mach/pxafb.h>
-#include <mach/pxa2xx-regs.h>
#include <mach/mmc.h>
#include <mach/udc.h>
#include <mach/pxa27x-udc.h>
@@ -411,21 +413,6 @@ static void gsm_exit(void)
/*
* USB UDC
*/
-static void udc_power_command(int cmd)
-{
- switch (cmd) {
- case PXA2XX_UDC_CMD_DISCONNECT:
- gpio_set_value(GPIO22_USB_ENABLE, 0);
- break;
- case PXA2XX_UDC_CMD_CONNECT:
- gpio_set_value(GPIO22_USB_ENABLE, 1);
- break;
- default:
- printk(KERN_INFO "udc_control: unknown command (0x%x)!\n", cmd);
- break;
- }
-}
-
static int is_usb_connected(void)
{
return !gpio_get_value(GPIO13_nUSB_DETECT);
@@ -433,24 +420,15 @@ static int is_usb_connected(void)
static struct pxa2xx_udc_mach_info mioa701_udc_info = {
.udc_is_connected = is_usb_connected,
- .udc_command = udc_power_command,
+ .gpio_pullup = GPIO22_USB_ENABLE,
};
-struct gpio_ress udc_gpios[] = {
- MIO_GPIO_OUT(GPIO22_USB_ENABLE, 0, "USB Vbus enable")
+struct gpio_vbus_mach_info gpio_vbus_data = {
+ .gpio_vbus = GPIO13_nUSB_DETECT,
+ .gpio_vbus_inverted = 1,
+ .gpio_pullup = -1,
};
-static int __init udc_init(void)
-{
- pxa_set_udc_info(&mioa701_udc_info);
- return mio_gpio_request(ARRAY_AND_SIZE(udc_gpios));
-}
-
-static void udc_exit(void)
-{
- mio_gpio_free(ARRAY_AND_SIZE(udc_gpios));
-}
-
/*
* SDIO/MMC Card controller
*/
@@ -789,6 +767,7 @@ MIO_SIMPLE_DEV(pxa2xx_ac97, "pxa2xx-ac97", NULL)
MIO_PARENT_DEV(mio_wm9713_codec, "wm9713-codec", &pxa2xx_ac97.dev, NULL)
MIO_SIMPLE_DEV(mioa701_sound, "mioa701-wm9713", NULL)
MIO_SIMPLE_DEV(mioa701_board, "mioa701-board", NULL)
+MIO_SIMPLE_DEV(gpio_vbus, "gpio-vbus", &gpio_vbus_data);
static struct platform_device *devices[] __initdata = {
&mioa701_gpio_keys,
@@ -800,7 +779,8 @@ static struct platform_device *devices[] __initdata = {
&mioa701_sound,
&power_dev,
&strataflash,
- &mioa701_board
+ &gpio_vbus,
+ &mioa701_board,
};
static void mioa701_machine_exit(void);
@@ -808,13 +788,13 @@ static void mioa701_machine_exit(void);
static void mioa701_poweroff(void)
{
mioa701_machine_exit();
- arm_machine_restart('s');
+ arm_machine_restart('s', NULL);
}
-static void mioa701_restart(char c)
+static void mioa701_restart(char c, const char *cmd)
{
mioa701_machine_exit();
- arm_machine_restart('s');
+ arm_machine_restart('s', cmd);
}
struct gpio_ress global_gpios[] = {
@@ -837,7 +817,7 @@ static void __init mioa701_machine_init(void)
pxa_set_mci_info(&mioa701_mci_info);
pxa_set_keypad_info(&mioa701_keypad_info);
wm97xx_bat_set_pdata(&mioa701_battery_data);
- udc_init();
+ pxa_set_udc_info(&mioa701_udc_info);
pm_power_off = mioa701_poweroff;
arm_pm_restart = mioa701_restart;
platform_add_devices(devices, ARRAY_SIZE(devices));
@@ -850,7 +830,6 @@ static void __init mioa701_machine_init(void)
static void mioa701_machine_exit(void)
{
- udc_exit();
bootstrap_exit();
gsm_exit();
}
diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c
index 8a73814126b1..a65713ce019e 100644
--- a/arch/arm/mach-pxa/mp900.c
+++ b/arch/arm/mach-pxa/mp900.c
@@ -19,10 +19,10 @@
#include <linux/types.h>
#include <linux/usb/isp116x.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+
+#include <mach/pxa25x.h>
#include "generic.h"
static void isp116x_pfm_delay(struct device *dev, int delay)
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c
new file mode 100644
index 000000000000..8587477a9bb7
--- /dev/null
+++ b/arch/arm/mach-pxa/palmld.c
@@ -0,0 +1,565 @@
+/*
+ * Hardware definitions for Palm LifeDrive
+ *
+ * Author: Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on work of:
+ * Alex Osborne <ato@meshy.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (find more info at www.hackndev.com)
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+#include <linux/wm97xx_batt.h>
+#include <linux/power_supply.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/palmld.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/irda.h>
+#include <mach/pxa27x_keypad.h>
+#include <mach/palmasoc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmld_pin_config[] __initdata = {
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO14_GPIO, /* SD detect */
+ GPIO114_GPIO, /* SD power */
+ GPIO116_GPIO, /* SD r/o switch */
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
+ /* IrDA */
+ GPIO108_GPIO, /* ir disable */
+ GPIO46_FICP_RXD,
+ GPIO47_FICP_TXD,
+
+ /* MATRIX KEYPAD */
+ GPIO100_KP_MKIN_0,
+ GPIO101_KP_MKIN_1,
+ GPIO102_KP_MKIN_2,
+ GPIO97_KP_MKIN_3,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+
+ /* LCD */
+ GPIO58_LCD_LDD_0,
+ GPIO59_LCD_LDD_1,
+ GPIO60_LCD_LDD_2,
+ GPIO61_LCD_LDD_3,
+ GPIO62_LCD_LDD_4,
+ GPIO63_LCD_LDD_5,
+ GPIO64_LCD_LDD_6,
+ GPIO65_LCD_LDD_7,
+ GPIO66_LCD_LDD_8,
+ GPIO67_LCD_LDD_9,
+ GPIO68_LCD_LDD_10,
+ GPIO69_LCD_LDD_11,
+ GPIO70_LCD_LDD_12,
+ GPIO71_LCD_LDD_13,
+ GPIO72_LCD_LDD_14,
+ GPIO73_LCD_LDD_15,
+ GPIO74_LCD_FCLK,
+ GPIO75_LCD_LCLK,
+ GPIO76_LCD_PCLK,
+ GPIO77_LCD_BIAS,
+
+ /* PWM */
+ GPIO16_PWM0_OUT,
+
+ /* GPIO KEYS */
+ GPIO10_GPIO, /* hotsync button */
+ GPIO12_GPIO, /* power switch */
+ GPIO15_GPIO, /* lock switch */
+
+ /* LEDs */
+ GPIO52_GPIO, /* green led */
+ GPIO94_GPIO, /* orange led */
+
+ /* PCMCIA */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO79_PSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+ GPIO36_GPIO, /* wifi power */
+ GPIO38_GPIO, /* wifi ready */
+ GPIO81_GPIO, /* wifi reset */
+
+ /* HDD */
+ GPIO95_GPIO, /* HDD irq */
+ GPIO115_GPIO, /* HDD power */
+
+ /* MISC */
+ GPIO13_GPIO, /* earphone detect */
+};
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+static int palmld_mci_init(struct device *dev, irq_handler_t palmld_detect_int,
+ void *data)
+{
+ int err = 0;
+
+ /* Setup an interrupt for detecting card insert/remove events */
+ err = gpio_request(GPIO_NR_PALMLD_SD_DETECT_N, "SD IRQ");
+ if (err)
+ goto err;
+ err = gpio_direction_input(GPIO_NR_PALMLD_SD_DETECT_N);
+ if (err)
+ goto err2;
+ err = request_irq(gpio_to_irq(GPIO_NR_PALMLD_SD_DETECT_N),
+ palmld_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "SD/MMC card detect", data);
+ if (err) {
+ printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
+ __func__);
+ goto err2;
+ }
+
+ err = gpio_request(GPIO_NR_PALMLD_SD_POWER, "SD_POWER");
+ if (err)
+ goto err3;
+ err = gpio_direction_output(GPIO_NR_PALMLD_SD_POWER, 0);
+ if (err)
+ goto err4;
+
+ err = gpio_request(GPIO_NR_PALMLD_SD_READONLY, "SD_READONLY");
+ if (err)
+ goto err4;
+ err = gpio_direction_input(GPIO_NR_PALMLD_SD_READONLY);
+ if (err)
+ goto err5;
+
+ printk(KERN_DEBUG "%s: irq registered\n", __func__);
+
+ return 0;
+
+err5:
+ gpio_free(GPIO_NR_PALMLD_SD_READONLY);
+err4:
+ gpio_free(GPIO_NR_PALMLD_SD_POWER);
+err3:
+ free_irq(gpio_to_irq(GPIO_NR_PALMLD_SD_DETECT_N), data);
+err2:
+ gpio_free(GPIO_NR_PALMLD_SD_DETECT_N);
+err:
+ return err;
+}
+
+static void palmld_mci_exit(struct device *dev, void *data)
+{
+ gpio_free(GPIO_NR_PALMLD_SD_READONLY);
+ gpio_free(GPIO_NR_PALMLD_SD_POWER);
+ free_irq(gpio_to_irq(GPIO_NR_PALMLD_SD_DETECT_N), data);
+ gpio_free(GPIO_NR_PALMLD_SD_DETECT_N);
+}
+
+static void palmld_mci_power(struct device *dev, unsigned int vdd)
+{
+ struct pxamci_platform_data *p_d = dev->platform_data;
+ gpio_set_value(GPIO_NR_PALMLD_SD_POWER, p_d->ocr_mask & (1 << vdd));
+}
+
+static int palmld_mci_get_ro(struct device *dev)
+{
+ return gpio_get_value(GPIO_NR_PALMLD_SD_READONLY);
+}
+
+static struct pxamci_platform_data palmld_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .setpower = palmld_mci_power,
+ .get_ro = palmld_mci_get_ro,
+ .init = palmld_mci_init,
+ .exit = palmld_mci_exit,
+};
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+static unsigned int palmld_matrix_keys[] = {
+ KEY(0, 1, KEY_F2),
+ KEY(0, 2, KEY_UP),
+
+ KEY(1, 0, KEY_F3),
+ KEY(1, 1, KEY_F4),
+ KEY(1, 2, KEY_RIGHT),
+
+ KEY(2, 0, KEY_F1),
+ KEY(2, 1, KEY_F5),
+ KEY(2, 2, KEY_DOWN),
+
+ KEY(3, 0, KEY_F6),
+ KEY(3, 1, KEY_ENTER),
+ KEY(3, 2, KEY_LEFT),
+};
+
+static struct pxa27x_keypad_platform_data palmld_keypad_platform_data = {
+ .matrix_key_rows = 4,
+ .matrix_key_cols = 3,
+ .matrix_key_map = palmld_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(palmld_matrix_keys),
+
+ .debounce_interval = 30,
+};
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+static struct gpio_keys_button palmld_pxa_buttons[] = {
+ {KEY_F8, GPIO_NR_PALMLD_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
+ {KEY_F9, GPIO_NR_PALMLD_LOCK_SWITCH, 0, "Lock Switch" },
+ {KEY_POWER, GPIO_NR_PALMLD_POWER_SWITCH, 0, "Power Switch" },
+};
+
+static struct gpio_keys_platform_data palmld_pxa_keys_data = {
+ .buttons = palmld_pxa_buttons,
+ .nbuttons = ARRAY_SIZE(palmld_pxa_buttons),
+};
+
+static struct platform_device palmld_pxa_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmld_pxa_keys_data,
+ },
+};
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+static int palmld_backlight_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_NR_PALMLD_BL_POWER, "BL POWER");
+ if (ret)
+ goto err;
+ ret = gpio_direction_output(GPIO_NR_PALMLD_BL_POWER, 0);
+ if (ret)
+ goto err2;
+ ret = gpio_request(GPIO_NR_PALMLD_LCD_POWER, "LCD POWER");
+ if (ret)
+ goto err2;
+ ret = gpio_direction_output(GPIO_NR_PALMLD_LCD_POWER, 0);
+ if (ret)
+ goto err3;
+
+ return 0;
+err3:
+ gpio_free(GPIO_NR_PALMLD_LCD_POWER);
+err2:
+ gpio_free(GPIO_NR_PALMLD_BL_POWER);
+err:
+ return ret;
+}
+
+static int palmld_backlight_notify(int brightness)
+{
+ gpio_set_value(GPIO_NR_PALMLD_BL_POWER, brightness);
+ gpio_set_value(GPIO_NR_PALMLD_LCD_POWER, brightness);
+ return brightness;
+}
+
+static void palmld_backlight_exit(struct device *dev)
+{
+ gpio_free(GPIO_NR_PALMLD_BL_POWER);
+ gpio_free(GPIO_NR_PALMLD_LCD_POWER);
+}
+
+static struct platform_pwm_backlight_data palmld_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = PALMLD_MAX_INTENSITY,
+ .dft_brightness = PALMLD_MAX_INTENSITY,
+ .pwm_period_ns = PALMLD_PERIOD_NS,
+ .init = palmld_backlight_init,
+ .notify = palmld_backlight_notify,
+ .exit = palmld_backlight_exit,
+};
+
+static struct platform_device palmld_backlight = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa27x_device_pwm0.dev,
+ .platform_data = &palmld_backlight_data,
+ },
+};
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+static int palmld_irda_startup(struct device *dev)
+{
+ int err;
+ err = gpio_request(GPIO_NR_PALMLD_IR_DISABLE, "IR DISABLE");
+ if (err)
+ goto err;
+ err = gpio_direction_output(GPIO_NR_PALMLD_IR_DISABLE, 1);
+ if (err)
+ gpio_free(GPIO_NR_PALMLD_IR_DISABLE);
+err:
+ return err;
+}
+
+static void palmld_irda_shutdown(struct device *dev)
+{
+ gpio_free(GPIO_NR_PALMLD_IR_DISABLE);
+}
+
+static void palmld_irda_transceiver_mode(struct device *dev, int mode)
+{
+ gpio_set_value(GPIO_NR_PALMLD_IR_DISABLE, mode & IR_OFF);
+ pxa2xx_transceiver_mode(dev, mode);
+}
+
+static struct pxaficp_platform_data palmld_ficp_platform_data = {
+ .startup = palmld_irda_startup,
+ .shutdown = palmld_irda_shutdown,
+ .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF,
+ .transceiver_mode = palmld_irda_transceiver_mode,
+};
+
+/******************************************************************************
+ * LEDs
+ ******************************************************************************/
+struct gpio_led gpio_leds[] = {
+{
+ .name = "palmld:green:led",
+ .default_trigger = "none",
+ .gpio = GPIO_NR_PALMLD_LED_GREEN,
+}, {
+ .name = "palmld:amber:led",
+ .default_trigger = "none",
+ .gpio = GPIO_NR_PALMLD_LED_AMBER,
+},
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device palmld_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ }
+};
+
+/******************************************************************************
+ * Power supply
+ ******************************************************************************/
+static int power_supply_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_NR_PALMLD_POWER_DETECT, "CABLE_STATE_AC");
+ if (ret)
+ goto err1;
+ ret = gpio_direction_input(GPIO_NR_PALMLD_POWER_DETECT);
+ if (ret)
+ goto err2;
+
+ ret = gpio_request(GPIO_NR_PALMLD_USB_DETECT_N, "CABLE_STATE_USB");
+ if (ret)
+ goto err2;
+ ret = gpio_direction_input(GPIO_NR_PALMLD_USB_DETECT_N);
+ if (ret)
+ goto err3;
+
+ return 0;
+
+err3:
+ gpio_free(GPIO_NR_PALMLD_USB_DETECT_N);
+err2:
+ gpio_free(GPIO_NR_PALMLD_POWER_DETECT);
+err1:
+ return ret;
+}
+
+static int palmld_is_ac_online(void)
+{
+ return gpio_get_value(GPIO_NR_PALMLD_POWER_DETECT);
+}
+
+static int palmld_is_usb_online(void)
+{
+ return !gpio_get_value(GPIO_NR_PALMLD_USB_DETECT_N);
+}
+
+static void power_supply_exit(struct device *dev)
+{
+ gpio_free(GPIO_NR_PALMLD_USB_DETECT_N);
+ gpio_free(GPIO_NR_PALMLD_POWER_DETECT);
+}
+
+static char *palmld_supplicants[] = {
+ "main-battery",
+};
+
+static struct pda_power_pdata power_supply_info = {
+ .init = power_supply_init,
+ .is_ac_online = palmld_is_ac_online,
+ .is_usb_online = palmld_is_usb_online,
+ .exit = power_supply_exit,
+ .supplied_to = palmld_supplicants,
+ .num_supplicants = ARRAY_SIZE(palmld_supplicants),
+};
+
+static struct platform_device power_supply = {
+ .name = "pda-power",
+ .id = -1,
+ .dev = {
+ .platform_data = &power_supply_info,
+ },
+};
+
+/******************************************************************************
+ * WM97xx battery
+ ******************************************************************************/
+static struct wm97xx_batt_info wm97xx_batt_pdata = {
+ .batt_aux = WM97XX_AUX_ID3,
+ .temp_aux = WM97XX_AUX_ID2,
+ .charge_gpio = -1,
+ .max_voltage = PALMLD_BAT_MAX_VOLTAGE,
+ .min_voltage = PALMLD_BAT_MIN_VOLTAGE,
+ .batt_mult = 1000,
+ .batt_div = 414,
+ .temp_mult = 1,
+ .temp_div = 1,
+ .batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO,
+ .batt_name = "main-batt",
+};
+
+/******************************************************************************
+ * aSoC audio
+ ******************************************************************************/
+static struct palm27x_asoc_info palm27x_asoc_pdata = {
+ .jack_gpio = GPIO_NR_PALMLD_EARPHONE_DETECT,
+};
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+static struct pxafb_mode_info palmld_lcd_modes[] = {
+{
+ .pixclock = 57692,
+ .xres = 320,
+ .yres = 480,
+ .bpp = 16,
+
+ .left_margin = 32,
+ .right_margin = 1,
+ .upper_margin = 7,
+ .lower_margin = 1,
+
+ .hsync_len = 4,
+ .vsync_len = 1,
+},
+};
+
+static struct pxafb_mach_info palmld_lcd_screen = {
+ .modes = palmld_lcd_modes,
+ .num_modes = ARRAY_SIZE(palmld_lcd_modes),
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static struct platform_device *devices[] __initdata = {
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+ &palmld_pxa_keys,
+#endif
+ &palmld_backlight,
+ &palmld_leds,
+ &power_supply,
+};
+
+static struct map_desc palmld_io_desc[] __initdata = {
+{
+ .virtual = PALMLD_IDE_VIRT,
+ .pfn = __phys_to_pfn(PALMLD_IDE_PHYS),
+ .length = PALMLD_IDE_SIZE,
+ .type = MT_DEVICE
+},
+{
+ .virtual = PALMLD_USB_VIRT,
+ .pfn = __phys_to_pfn(PALMLD_USB_PHYS),
+ .length = PALMLD_USB_SIZE,
+ .type = MT_DEVICE
+},
+};
+
+static void __init palmld_map_io(void)
+{
+ pxa_map_io();
+ iotable_init(palmld_io_desc, ARRAY_SIZE(palmld_io_desc));
+}
+
+static void __init palmld_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(palmld_pin_config));
+
+ set_pxa_fb_info(&palmld_lcd_screen);
+ pxa_set_mci_info(&palmld_mci_platform_data);
+ pxa_set_ac97_info(NULL);
+ pxa_set_ficp_info(&palmld_ficp_platform_data);
+ pxa_set_keypad_info(&palmld_keypad_platform_data);
+ wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
+ palm27x_asoc_set_pdata(&palm27x_asoc_pdata);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(PALMLD, "Palm LifeDrive")
+ .phys_io = PALMLD_PHYS_IO_START,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .boot_params = 0xa0000100,
+ .map_io = palmld_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = palmld_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
new file mode 100644
index 000000000000..9521c7b33492
--- /dev/null
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -0,0 +1,496 @@
+/*
+ * Hardware definitions for Palm Tungsten|T5
+ *
+ * Author: Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on work of:
+ * Ales Snuparek <snuparek@atlas.cz>
+ * Justin Kendrick <twilightsentry@gmail.com>
+ * RichardT5 <richard_t5@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (find more info at www.hackndev.com)
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+#include <linux/wm97xx_batt.h>
+#include <linux/power_supply.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/palmt5.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/irda.h>
+#include <mach/pxa27x_keypad.h>
+#include <mach/udc.h>
+#include <mach/palmasoc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmt5_pin_config[] __initdata = {
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO14_GPIO, /* SD detect */
+ GPIO114_GPIO, /* SD power */
+ GPIO115_GPIO, /* SD r/o switch */
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
+ /* IrDA */
+ GPIO40_GPIO, /* ir disable */
+ GPIO46_FICP_RXD,
+ GPIO47_FICP_TXD,
+
+ /* USB */
+ GPIO15_GPIO, /* usb detect */
+ GPIO95_GPIO, /* usb power */
+
+ /* MATRIX KEYPAD */
+ GPIO100_KP_MKIN_0,
+ GPIO101_KP_MKIN_1,
+ GPIO102_KP_MKIN_2,
+ GPIO97_KP_MKIN_3,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+
+ /* LCD */
+ GPIO58_LCD_LDD_0,
+ GPIO59_LCD_LDD_1,
+ GPIO60_LCD_LDD_2,
+ GPIO61_LCD_LDD_3,
+ GPIO62_LCD_LDD_4,
+ GPIO63_LCD_LDD_5,
+ GPIO64_LCD_LDD_6,
+ GPIO65_LCD_LDD_7,
+ GPIO66_LCD_LDD_8,
+ GPIO67_LCD_LDD_9,
+ GPIO68_LCD_LDD_10,
+ GPIO69_LCD_LDD_11,
+ GPIO70_LCD_LDD_12,
+ GPIO71_LCD_LDD_13,
+ GPIO72_LCD_LDD_14,
+ GPIO73_LCD_LDD_15,
+ GPIO74_LCD_FCLK,
+ GPIO75_LCD_LCLK,
+ GPIO76_LCD_PCLK,
+ GPIO77_LCD_BIAS,
+
+ /* PWM */
+ GPIO16_PWM0_OUT,
+
+ /* MISC */
+ GPIO10_GPIO, /* hotsync button */
+ GPIO90_GPIO, /* power detect */
+ GPIO107_GPIO, /* earphone detect */
+};
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+static int palmt5_mci_init(struct device *dev, irq_handler_t palmt5_detect_int,
+ void *data)
+{
+ int err = 0;
+
+ /* Setup an interrupt for detecting card insert/remove events */
+ err = gpio_request(GPIO_NR_PALMT5_SD_DETECT_N, "SD IRQ");
+ if (err)
+ goto err;
+ err = gpio_direction_input(GPIO_NR_PALMT5_SD_DETECT_N);
+ if (err)
+ goto err2;
+ err = request_irq(gpio_to_irq(GPIO_NR_PALMT5_SD_DETECT_N),
+ palmt5_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "SD/MMC card detect", data);
+ if (err) {
+ printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
+ __func__);
+ goto err2;
+ }
+
+ err = gpio_request(GPIO_NR_PALMT5_SD_POWER, "SD_POWER");
+ if (err)
+ goto err3;
+ err = gpio_direction_output(GPIO_NR_PALMT5_SD_POWER, 0);
+ if (err)
+ goto err4;
+
+ err = gpio_request(GPIO_NR_PALMT5_SD_READONLY, "SD_READONLY");
+ if (err)
+ goto err4;
+ err = gpio_direction_input(GPIO_NR_PALMT5_SD_READONLY);
+ if (err)
+ goto err5;
+
+ printk(KERN_DEBUG "%s: irq registered\n", __func__);
+
+ return 0;
+
+err5:
+ gpio_free(GPIO_NR_PALMT5_SD_READONLY);
+err4:
+ gpio_free(GPIO_NR_PALMT5_SD_POWER);
+err3:
+ free_irq(gpio_to_irq(GPIO_NR_PALMT5_SD_DETECT_N), data);
+err2:
+ gpio_free(GPIO_NR_PALMT5_SD_DETECT_N);
+err:
+ return err;
+}
+
+static void palmt5_mci_exit(struct device *dev, void *data)
+{
+ gpio_free(GPIO_NR_PALMT5_SD_READONLY);
+ gpio_free(GPIO_NR_PALMT5_SD_POWER);
+ free_irq(IRQ_GPIO_PALMT5_SD_DETECT_N, data);
+ gpio_free(GPIO_NR_PALMT5_SD_DETECT_N);
+}
+
+static void palmt5_mci_power(struct device *dev, unsigned int vdd)
+{
+ struct pxamci_platform_data *p_d = dev->platform_data;
+ gpio_set_value(GPIO_NR_PALMT5_SD_POWER, p_d->ocr_mask & (1 << vdd));
+}
+
+static int palmt5_mci_get_ro(struct device *dev)
+{
+ return gpio_get_value(GPIO_NR_PALMT5_SD_READONLY);
+}
+
+static struct pxamci_platform_data palmt5_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .setpower = palmt5_mci_power,
+ .get_ro = palmt5_mci_get_ro,
+ .init = palmt5_mci_init,
+ .exit = palmt5_mci_exit,
+};
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+static unsigned int palmt5_matrix_keys[] = {
+ KEY(0, 0, KEY_POWER),
+ KEY(0, 1, KEY_F1),
+ KEY(0, 2, KEY_ENTER),
+
+ KEY(1, 0, KEY_F2),
+ KEY(1, 1, KEY_F3),
+ KEY(1, 2, KEY_F4),
+
+ KEY(2, 0, KEY_UP),
+ KEY(2, 2, KEY_DOWN),
+
+ KEY(3, 0, KEY_RIGHT),
+ KEY(3, 2, KEY_LEFT),
+};
+
+static struct pxa27x_keypad_platform_data palmt5_keypad_platform_data = {
+ .matrix_key_rows = 4,
+ .matrix_key_cols = 3,
+ .matrix_key_map = palmt5_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(palmt5_matrix_keys),
+
+ .debounce_interval = 30,
+};
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+static struct gpio_keys_button palmt5_pxa_buttons[] = {
+ {KEY_F8, GPIO_NR_PALMT5_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
+};
+
+static struct gpio_keys_platform_data palmt5_pxa_keys_data = {
+ .buttons = palmt5_pxa_buttons,
+ .nbuttons = ARRAY_SIZE(palmt5_pxa_buttons),
+};
+
+static struct platform_device palmt5_pxa_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmt5_pxa_keys_data,
+ },
+};
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+static int palmt5_backlight_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_NR_PALMT5_BL_POWER, "BL POWER");
+ if (ret)
+ goto err;
+ ret = gpio_direction_output(GPIO_NR_PALMT5_BL_POWER, 0);
+ if (ret)
+ goto err2;
+ ret = gpio_request(GPIO_NR_PALMT5_LCD_POWER, "LCD POWER");
+ if (ret)
+ goto err2;
+ ret = gpio_direction_output(GPIO_NR_PALMT5_LCD_POWER, 0);
+ if (ret)
+ goto err3;
+
+ return 0;
+err3:
+ gpio_free(GPIO_NR_PALMT5_LCD_POWER);
+err2:
+ gpio_free(GPIO_NR_PALMT5_BL_POWER);
+err:
+ return ret;
+}
+
+static int palmt5_backlight_notify(int brightness)
+{
+ gpio_set_value(GPIO_NR_PALMT5_BL_POWER, brightness);
+ gpio_set_value(GPIO_NR_PALMT5_LCD_POWER, brightness);
+ return brightness;
+}
+
+static void palmt5_backlight_exit(struct device *dev)
+{
+ gpio_free(GPIO_NR_PALMT5_BL_POWER);
+ gpio_free(GPIO_NR_PALMT5_LCD_POWER);
+}
+
+static struct platform_pwm_backlight_data palmt5_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = PALMT5_MAX_INTENSITY,
+ .dft_brightness = PALMT5_MAX_INTENSITY,
+ .pwm_period_ns = PALMT5_PERIOD_NS,
+ .init = palmt5_backlight_init,
+ .notify = palmt5_backlight_notify,
+ .exit = palmt5_backlight_exit,
+};
+
+static struct platform_device palmt5_backlight = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa27x_device_pwm0.dev,
+ .platform_data = &palmt5_backlight_data,
+ },
+};
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+static int palmt5_irda_startup(struct device *dev)
+{
+ int err;
+ err = gpio_request(GPIO_NR_PALMT5_IR_DISABLE, "IR DISABLE");
+ if (err)
+ goto err;
+ err = gpio_direction_output(GPIO_NR_PALMT5_IR_DISABLE, 1);
+ if (err)
+ gpio_free(GPIO_NR_PALMT5_IR_DISABLE);
+err:
+ return err;
+}
+
+static void palmt5_irda_shutdown(struct device *dev)
+{
+ gpio_free(GPIO_NR_PALMT5_IR_DISABLE);
+}
+
+static void palmt5_irda_transceiver_mode(struct device *dev, int mode)
+{
+ gpio_set_value(GPIO_NR_PALMT5_IR_DISABLE, mode & IR_OFF);
+ pxa2xx_transceiver_mode(dev, mode);
+}
+
+static struct pxaficp_platform_data palmt5_ficp_platform_data = {
+ .startup = palmt5_irda_startup,
+ .shutdown = palmt5_irda_shutdown,
+ .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF,
+ .transceiver_mode = palmt5_irda_transceiver_mode,
+};
+
+/******************************************************************************
+ * UDC
+ ******************************************************************************/
+static struct pxa2xx_udc_mach_info palmt5_udc_info __initdata = {
+ .gpio_vbus = GPIO_NR_PALMT5_USB_DETECT_N,
+ .gpio_vbus_inverted = 1,
+ .gpio_pullup = GPIO_NR_PALMT5_USB_POWER,
+ .gpio_pullup_inverted = 0,
+};
+
+/******************************************************************************
+ * Power supply
+ ******************************************************************************/
+static int power_supply_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_NR_PALMT5_POWER_DETECT, "CABLE_STATE_AC");
+ if (ret)
+ goto err1;
+ ret = gpio_direction_input(GPIO_NR_PALMT5_POWER_DETECT);
+ if (ret)
+ goto err2;
+
+ return 0;
+err2:
+ gpio_free(GPIO_NR_PALMT5_POWER_DETECT);
+err1:
+ return ret;
+}
+
+static int palmt5_is_ac_online(void)
+{
+ return gpio_get_value(GPIO_NR_PALMT5_POWER_DETECT);
+}
+
+static void power_supply_exit(struct device *dev)
+{
+ gpio_free(GPIO_NR_PALMT5_POWER_DETECT);
+}
+
+static char *palmt5_supplicants[] = {
+ "main-battery",
+};
+
+static struct pda_power_pdata power_supply_info = {
+ .init = power_supply_init,
+ .is_ac_online = palmt5_is_ac_online,
+ .exit = power_supply_exit,
+ .supplied_to = palmt5_supplicants,
+ .num_supplicants = ARRAY_SIZE(palmt5_supplicants),
+};
+
+static struct platform_device power_supply = {
+ .name = "pda-power",
+ .id = -1,
+ .dev = {
+ .platform_data = &power_supply_info,
+ },
+};
+
+/******************************************************************************
+ * WM97xx battery
+ ******************************************************************************/
+static struct wm97xx_batt_info wm97xx_batt_pdata = {
+ .batt_aux = WM97XX_AUX_ID3,
+ .temp_aux = WM97XX_AUX_ID2,
+ .charge_gpio = -1,
+ .max_voltage = PALMT5_BAT_MAX_VOLTAGE,
+ .min_voltage = PALMT5_BAT_MIN_VOLTAGE,
+ .batt_mult = 1000,
+ .batt_div = 414,
+ .temp_mult = 1,
+ .temp_div = 1,
+ .batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO,
+ .batt_name = "main-batt",
+};
+
+/******************************************************************************
+ * aSoC audio
+ ******************************************************************************/
+static struct palm27x_asoc_info palm27x_asoc_pdata = {
+ .jack_gpio = GPIO_NR_PALMT5_EARPHONE_DETECT,
+};
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+static struct pxafb_mode_info palmt5_lcd_modes[] = {
+{
+ .pixclock = 57692,
+ .xres = 320,
+ .yres = 480,
+ .bpp = 16,
+
+ .left_margin = 32,
+ .right_margin = 1,
+ .upper_margin = 7,
+ .lower_margin = 1,
+
+ .hsync_len = 4,
+ .vsync_len = 1,
+},
+};
+
+static struct pxafb_mach_info palmt5_lcd_screen = {
+ .modes = palmt5_lcd_modes,
+ .num_modes = ARRAY_SIZE(palmt5_lcd_modes),
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static struct platform_device *devices[] __initdata = {
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+ &palmt5_pxa_keys,
+#endif
+ &palmt5_backlight,
+ &power_supply,
+};
+
+/* setup udc GPIOs initial state */
+static void __init palmt5_udc_init(void)
+{
+ if (!gpio_request(GPIO_NR_PALMT5_USB_POWER, "UDC Vbus")) {
+ gpio_direction_output(GPIO_NR_PALMT5_USB_POWER, 1);
+ gpio_free(GPIO_NR_PALMT5_USB_POWER);
+ }
+}
+
+static void __init palmt5_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config));
+
+ set_pxa_fb_info(&palmt5_lcd_screen);
+ pxa_set_mci_info(&palmt5_mci_platform_data);
+ palmt5_udc_init();
+ pxa_set_udc_info(&palmt5_udc_info);
+ pxa_set_ac97_info(NULL);
+ pxa_set_ficp_info(&palmt5_ficp_platform_data);
+ pxa_set_keypad_info(&palmt5_keypad_platform_data);
+ wm97xx_bat_set_pdata(&wm97xx_batt_pdata);
+ palm27x_asoc_set_pdata(&palm27x_asoc_pdata);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(PALMT5, "Palm Tungsten|T5")
+ .phys_io = PALMT5_PHYS_IO_START,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .boot_params = 0xa0000100,
+ .map_io = pxa_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = palmt5_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
index a9d94f5dbec4..b490c0924619 100644
--- a/arch/arm/mach-pxa/palmtx.c
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -32,12 +32,11 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <mach/pxa27x.h>
#include <mach/audio.h>
#include <mach/palmtx.h>
#include <mach/mmc.h>
#include <mach/pxafb.h>
-#include <mach/pxa-regs.h>
-#include <mach/mfp-pxa27x.h>
#include <mach/irda.h>
#include <mach/pxa27x_keypad.h>
#include <mach/udc.h>
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
index 2f730da3bba8..b88eb4dd2c84 100644
--- a/arch/arm/mach-pxa/palmz72.c
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -33,13 +33,11 @@
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <mach/pxa27x.h>
#include <mach/audio.h>
#include <mach/palmz72.h>
#include <mach/mmc.h>
#include <mach/pxafb.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
#include <mach/irda.h>
#include <mach/pxa27x_keypad.h>
#include <mach/udc.h>
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c
index 36135a02fdc7..6abfa2979c61 100644
--- a/arch/arm/mach-pxa/pcm027.c
+++ b/arch/arm/mach-pxa/pcm027.c
@@ -29,10 +29,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
-#include <mach/mfp-pxa27x.h>
-#include <mach/pxa2xx-regs.h>
+#include <mach/pxa27x.h>
#include <mach/pxa2xx_spi.h>
#include <mach/pcm027.h>
#include "generic.h"
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index 34841c72815f..6112740b4ae9 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -31,13 +31,12 @@
#include <mach/i2c.h>
#include <mach/camera.h>
#include <asm/mach/map.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa27x.h>
#include <mach/audio.h>
#include <mach/mmc.h>
#include <mach/ohci.h>
#include <mach/pcm990_baseboard.h>
#include <mach/pxafb.h>
-#include <mach/mfp-pxa27x.h>
#include "devices.h"
#include "generic.h"
@@ -381,14 +380,49 @@ static struct pca953x_platform_data pca9536_data = {
.gpio_base = NR_BUILTIN_GPIO + 1,
};
-static struct soc_camera_link iclink[] = {
- {
- .bus_id = 0, /* Must match with the camera ID above */
- .gpio = NR_BUILTIN_GPIO + 1,
- }, {
- .bus_id = 0, /* Must match with the camera ID above */
- .gpio = -ENXIO,
+static int gpio_bus_switch;
+
+static int pcm990_camera_set_bus_param(struct soc_camera_link *link,
+ unsigned long flags)
+{
+ if (gpio_bus_switch <= 0) {
+ if (flags == SOCAM_DATAWIDTH_10)
+ return 0;
+ else
+ return -EINVAL;
+ }
+
+ if (flags & SOCAM_DATAWIDTH_8)
+ gpio_set_value(gpio_bus_switch, 1);
+ else
+ gpio_set_value(gpio_bus_switch, 0);
+
+ return 0;
+}
+
+static unsigned long pcm990_camera_query_bus_param(struct soc_camera_link *link)
+{
+ int ret;
+
+ if (!gpio_bus_switch) {
+ ret = gpio_request(NR_BUILTIN_GPIO + 1, "camera");
+ if (!ret) {
+ gpio_bus_switch = NR_BUILTIN_GPIO + 1;
+ gpio_direction_output(gpio_bus_switch, 0);
+ } else
+ gpio_bus_switch = -EINVAL;
}
+
+ if (gpio_bus_switch > 0)
+ return SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_10;
+ else
+ return SOCAM_DATAWIDTH_10;
+}
+
+static struct soc_camera_link iclink = {
+ .bus_id = 0, /* Must match with the camera ID above */
+ .query_bus_param = pcm990_camera_query_bus_param,
+ .set_bus_param = pcm990_camera_set_bus_param,
};
/* Board I2C devices. */
@@ -399,10 +433,10 @@ static struct i2c_board_info __initdata pcm990_i2c_devices[] = {
.platform_data = &pca9536_data,
}, {
I2C_BOARD_INFO("mt9v022", 0x48),
- .platform_data = &iclink[0], /* With extender */
+ .platform_data = &iclink, /* With extender */
}, {
I2C_BOARD_INFO("mt9m001", 0x5d),
- .platform_data = &iclink[0], /* With extender */
+ .platform_data = &iclink, /* With extender */
},
};
#endif /* CONFIG_VIDEO_PXA27x ||CONFIG_VIDEO_PXA27x_MODULE */
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index 164eb0bb6321..884b174c8ead 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -14,15 +14,8 @@
#include <linux/module.h>
#include <linux/suspend.h>
#include <linux/errno.h>
-#include <linux/time.h>
-#include <mach/hardware.h>
-#include <asm/memory.h>
-#include <asm/system.h>
#include <mach/pm.h>
-#include <mach/pxa-regs.h>
-#include <mach/lubbock.h>
-#include <asm/mach/time.h>
struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
static unsigned long *sleep_save;
@@ -57,9 +50,9 @@ int pxa_pm_enter(suspend_state_t state)
/* if invalid, display message and wait for a hardware reset */
if (checksum != sleep_save_checksum) {
-#ifdef CONFIG_ARCH_LUBBOCK
- LUB_HEXLED = 0xbadbadc5;
-#endif
+
+ lubbock_set_hexled(0xbadbadc5);
+
while (1)
pxa_cpu_pm_fns->enter(state);
}
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index f9093beba752..036bbde4d221 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -36,9 +36,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include <mach/pxa25x.h>
#include <mach/mmc.h>
#include <mach/udc.h>
#include <mach/i2c.h>
@@ -503,12 +501,12 @@ static struct platform_device *devices[] __initdata = {
static void poodle_poweroff(void)
{
- arm_machine_restart('h');
+ arm_machine_restart('h', NULL);
}
-static void poodle_restart(char mode)
+static void poodle_restart(char mode, const char *cmd)
{
- arm_machine_restart('h');
+ arm_machine_restart('h', cmd);
}
static void __init poodle_init(void)
diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c
index 3ca7ffc6904b..fcdd374437a8 100644
--- a/arch/arm/mach-pxa/pwm.c
+++ b/arch/arm/mach-pxa/pwm.c
@@ -20,7 +20,6 @@
#include <linux/pwm.h>
#include <asm/div64.h>
-#include <mach/pxa-regs.h>
/* PWM registers and bits definitions */
#define PWMCR (0x00)
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 6c57522e2469..77c2693cfeef 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -25,9 +25,8 @@
#include <mach/hardware.h>
#include <mach/irqs.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+#include <mach/gpio.h>
+#include <mach/pxa25x.h>
#include <mach/reset.h>
#include <mach/pm.h>
#include <mach/dma.h>
@@ -310,14 +309,14 @@ set_pwer:
void __init pxa25x_init_irq(void)
{
pxa_init_irq(32, pxa25x_set_wake);
- pxa_init_gpio(85, pxa25x_set_wake);
+ pxa_init_gpio(IRQ_GPIO_2_x, 2, 84, pxa25x_set_wake);
}
#ifdef CONFIG_CPU_PXA26x
void __init pxa26x_init_irq(void)
{
pxa_init_irq(32, pxa25x_set_wake);
- pxa_init_gpio(90, pxa25x_set_wake);
+ pxa_init_gpio(IRQ_GPIO_2_x, 2, 89, pxa25x_set_wake);
}
#endif
@@ -355,7 +354,7 @@ static int __init pxa25x_init(void)
clks_register(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs));
- if ((ret = pxa_init_dma(16)))
+ if ((ret = pxa_init_dma(IRQ_DMA, 16)))
return ret;
pxa25x_init_pm();
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 411bec54fdc4..a425ec71e657 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -21,9 +21,8 @@
#include <mach/hardware.h>
#include <asm/irq.h>
#include <mach/irqs.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
+#include <mach/gpio.h>
+#include <mach/pxa27x.h>
#include <mach/reset.h>
#include <mach/ohci.h>
#include <mach/pm.h>
@@ -332,7 +331,7 @@ static int pxa27x_set_wake(unsigned int irq, unsigned int on)
void __init pxa27x_init_irq(void)
{
pxa_init_irq(34, pxa27x_set_wake);
- pxa_init_gpio(121, pxa27x_set_wake);
+ pxa_init_gpio(IRQ_GPIO_2_x, 2, 120, pxa27x_set_wake);
}
/*
@@ -381,7 +380,7 @@ static int __init pxa27x_init(void)
clks_register(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs));
- if ((ret = pxa_init_dma(32)))
+ if ((ret = pxa_init_dma(IRQ_DMA, 32)))
return ret;
pxa27x_init_pm();
diff --git a/arch/arm/mach-pxa/pxa2xx.c b/arch/arm/mach-pxa/pxa2xx.c
index 73d04d81c75a..2f3394f85917 100644
--- a/arch/arm/mach-pxa/pxa2xx.c
+++ b/arch/arm/mach-pxa/pxa2xx.c
@@ -16,7 +16,6 @@
#include <mach/hardware.h>
#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa2xx.h>
#include <mach/mfp-pxa25x.h>
#include <mach/reset.h>
#include <mach/irda.h>
diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c
index 83fb609b6eb7..4ba6d21f851c 100644
--- a/arch/arm/mach-pxa/pxa300.c
+++ b/arch/arm/mach-pxa/pxa300.c
@@ -17,15 +17,13 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
-#include <mach/hardware.h>
-#include <mach/pxa3xx-regs.h>
-#include <mach/mfp-pxa300.h>
+#include <mach/pxa300.h>
#include "generic.h"
#include "devices.h"
#include "clock.h"
-static struct pxa3xx_mfp_addr_map pxa300_mfp_addr_map[] __initdata = {
+static struct mfp_addr_map pxa300_mfp_addr_map[] __initdata = {
MFP_ADDR_X(GPIO0, GPIO2, 0x00b4),
MFP_ADDR_X(GPIO3, GPIO26, 0x027c),
@@ -74,7 +72,7 @@ static struct pxa3xx_mfp_addr_map pxa300_mfp_addr_map[] __initdata = {
};
/* override pxa300 MFP register addresses */
-static struct pxa3xx_mfp_addr_map pxa310_mfp_addr_map[] __initdata = {
+static struct mfp_addr_map pxa310_mfp_addr_map[] __initdata = {
MFP_ADDR_X(GPIO30, GPIO98, 0x0418),
MFP_ADDR_X(GPIO7_2, GPIO12_2, 0x052C),
@@ -100,13 +98,13 @@ static struct clk_lookup pxa310_clkregs[] = {
static int __init pxa300_init(void)
{
if (cpu_is_pxa300() || cpu_is_pxa310()) {
- pxa3xx_init_mfp();
- pxa3xx_mfp_init_addr(pxa300_mfp_addr_map);
+ mfp_init_base(io_p2v(MFPR_BASE));
+ mfp_init_addr(pxa300_mfp_addr_map);
clks_register(ARRAY_AND_SIZE(common_clkregs));
}
if (cpu_is_pxa310()) {
- pxa3xx_mfp_init_addr(pxa310_mfp_addr_map);
+ mfp_init_addr(pxa310_mfp_addr_map);
clks_register(ARRAY_AND_SIZE(pxa310_clkregs));
}
diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c
index 36f066196fa2..8b3d97efadab 100644
--- a/arch/arm/mach-pxa/pxa320.c
+++ b/arch/arm/mach-pxa/pxa320.c
@@ -17,16 +17,13 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
-#include <mach/hardware.h>
-#include <mach/mfp.h>
-#include <mach/pxa3xx-regs.h>
-#include <mach/mfp-pxa320.h>
+#include <mach/pxa320.h>
#include "generic.h"
#include "devices.h"
#include "clock.h"
-static struct pxa3xx_mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
+static struct mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
MFP_ADDR_X(GPIO0, GPIO4, 0x0124),
MFP_ADDR_X(GPIO5, GPIO9, 0x028C),
@@ -89,8 +86,8 @@ static struct clk_lookup pxa320_clkregs[] = {
static int __init pxa320_init(void)
{
if (cpu_is_pxa320()) {
- pxa3xx_init_mfp();
- pxa3xx_mfp_init_addr(pxa320_mfp_addr_map);
+ mfp_init_base(io_p2v(MFPR_BASE));
+ mfp_init_addr(pxa320_mfp_addr_map);
clks_register(ARRAY_AND_SIZE(pxa320_clkregs));
}
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 490893824e78..b02d4544dc95 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -23,6 +23,7 @@
#include <linux/sysdev.h>
#include <mach/hardware.h>
+#include <mach/gpio.h>
#include <mach/pxa3xx-regs.h>
#include <mach/reset.h>
#include <mach/ohci.h>
@@ -538,7 +539,7 @@ void __init pxa3xx_init_irq(void)
__asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
pxa_init_irq(56, pxa3xx_set_wake);
- pxa_init_gpio(128, NULL);
+ pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
}
/*
@@ -594,7 +595,7 @@ static int __init pxa3xx_init(void)
clks_register(pxa3xx_clkregs, ARRAY_SIZE(pxa3xx_clkregs));
- if ((ret = pxa_init_dma(32)))
+ if ((ret = pxa_init_dma(IRQ_DMA, 32)))
return ret;
pxa3xx_init_pm();
diff --git a/arch/arm/mach-pxa/pxa930.c b/arch/arm/mach-pxa/pxa930.c
index 13e6bfdfff60..71131742fffd 100644
--- a/arch/arm/mach-pxa/pxa930.c
+++ b/arch/arm/mach-pxa/pxa930.c
@@ -16,10 +16,9 @@
#include <linux/irq.h>
#include <linux/dma-mapping.h>
-#include <mach/hardware.h>
-#include <mach/mfp-pxa930.h>
+#include <mach/pxa930.h>
-static struct pxa3xx_mfp_addr_map pxa930_mfp_addr_map[] __initdata = {
+static struct mfp_addr_map pxa930_mfp_addr_map[] __initdata = {
MFP_ADDR(GPIO0, 0x02e0),
MFP_ADDR(GPIO1, 0x02dc),
@@ -180,8 +179,8 @@ static struct pxa3xx_mfp_addr_map pxa930_mfp_addr_map[] __initdata = {
static int __init pxa930_init(void)
{
if (cpu_is_pxa930()) {
- pxa3xx_init_mfp();
- pxa3xx_mfp_init_addr(pxa930_mfp_addr_map);
+ mfp_init_base(io_p2v(MFPR_BASE));
+ mfp_init_addr(pxa930_mfp_addr_map);
}
return 0;
diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c
index 00b2dc2a1074..df29d45fb4e7 100644
--- a/arch/arm/mach-pxa/reset.c
+++ b/arch/arm/mach-pxa/reset.c
@@ -10,7 +10,7 @@
#include <linux/io.h>
#include <asm/proc-fns.h>
-#include <mach/pxa-regs.h>
+#include <mach/regs-ost.h>
#include <mach/reset.h>
unsigned int reset_status;
@@ -81,7 +81,7 @@ static void do_hw_reset(void)
OSMR3 = OSCR + 368640; /* ... in 100 ms */
}
-void arch_reset(char mode)
+void arch_reset(char mode, const char *cmd)
{
clear_reset_status(RESET_STATUS_ALL);
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c
index 5d02a7325586..ff8239991430 100644
--- a/arch/arm/mach-pxa/saar.c
+++ b/arch/arm/mach-pxa/saar.c
@@ -25,11 +25,9 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/hardware.h>
-#include <mach/pxa3xx-regs.h>
-#include <mach/mfp-pxa930.h>
+
+#include <mach/pxa930.h>
#include <mach/i2c.h>
-#include <mach/regs-lcd.h>
#include <mach/pxafb.h>
#include "devices.h"
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index f0845c1b001c..16b4ec67e3b6 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -25,7 +25,6 @@
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <mach/pm.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-gpio.h>
#include <mach/sharpsl.h>
#include "sharpsl.h"
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index a62c8375eb53..2ed95f369cfc 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -15,7 +15,6 @@
#include <asm/assembler.h>
#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-regs.h>
#define MDREFR_KDIV 0x200a4000 // all banks
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 6d447c9ce8ab..8c61ddac119e 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -44,9 +44,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
+#include <mach/pxa27x.h>
#include <mach/pxa27x-udc.h>
#include <mach/reset.h>
#include <mach/i2c.h>
@@ -105,6 +103,12 @@ static unsigned long spitz_pin_config[] __initdata = {
GPIO57_nIOIS16,
GPIO104_PSKTSEL,
+ /* I2S */
+ GPIO28_I2S_BITCLK_OUT,
+ GPIO29_I2S_SDATA_IN,
+ GPIO30_I2S_SDATA_OUT,
+ GPIO31_I2S_SYNC,
+
/* MMC */
GPIO32_MMC_CLK,
GPIO112_MMC_CMD,
@@ -703,10 +707,10 @@ static struct platform_device *devices[] __initdata = {
static void spitz_poweroff(void)
{
- arm_machine_restart('g');
+ arm_machine_restart('g', NULL);
}
-static void spitz_restart(char mode)
+static void spitz_restart(char mode, const char *cmd)
{
/* Bootloader magic for a reboot */
if((MSC0 & 0xffff0000) == 0x7ff00000)
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 072e77cfe5a3..2e4490562c9e 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -24,7 +24,6 @@
#include <mach/sharpsl.h>
#include <mach/spitz.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-regs.h>
#include <mach/pxa2xx-gpio.h>
#include "sharpsl.h"
diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c
index 6f42004db3ed..965e38c6bafe 100644
--- a/arch/arm/mach-pxa/ssp.c
+++ b/arch/arm/mach-pxa/ssp.c
@@ -33,7 +33,6 @@
#include <asm/irq.h>
#include <mach/hardware.h>
#include <mach/ssp.h>
-#include <mach/pxa-regs.h>
#include <mach/regs-ssp.h>
#define TIMEOUT 100000
diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S
index f3821cfda72f..29f5f5c180b7 100644
--- a/arch/arm/mach-pxa/standby.S
+++ b/arch/arm/mach-pxa/standby.S
@@ -13,7 +13,6 @@
#include <asm/assembler.h>
#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-regs.h>
.text
diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c
index 58ef08a5224b..b75353a2ec75 100644
--- a/arch/arm/mach-pxa/tavorevb.c
+++ b/arch/arm/mach-pxa/tavorevb.c
@@ -22,9 +22,8 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <mach/hardware.h>
-#include <mach/pxa3xx-regs.h>
-#include <mach/mfp-pxa930.h>
+
+#include <mach/pxa930.h>
#include <mach/pxafb.h>
#include <mach/pxa27x_keypad.h>
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 95656a72268d..8eb3830fbb0b 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -22,8 +22,7 @@
#include <asm/div64.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/regs-ost.h>
/*
* This is PXA's sched_clock implementation. This has a resolution
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 3332e5d0356c..6e8ade6ae339 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -36,8 +36,8 @@
#include <asm/setup.h>
#include <asm/mach-types.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa25x.h>
+
+#include <mach/pxa25x.h>
#include <mach/reset.h>
#include <mach/irda.h>
#include <mach/i2c.h>
@@ -876,10 +876,10 @@ static struct platform_device *devices[] __initdata = {
static void tosa_poweroff(void)
{
- arm_machine_restart('g');
+ arm_machine_restart('g', NULL);
}
-static void tosa_restart(char mode)
+static void tosa_restart(char mode, const char *cmd)
{
/* Bootloader magic for a reboot */
if((MSC0 & 0xffff0000) == 0x7ff00000)
@@ -919,7 +919,7 @@ static void __init tosa_init(void)
pxa2xx_set_spi_info(2, &pxa_ssp_master_info);
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
- clk_add_alias("CLK_CK3P6MI", &tc6393xb_device.dev, "GPIO11_CLK", NULL);
+ clk_add_alias("CLK_CK3P6MI", tc6393xb_device.name, "GPIO11_CLK", NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));
}
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index a72e3add743c..f79c9cb70ae4 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -39,10 +39,7 @@
#include <asm/mach/irq.h>
#include <asm/mach/flash.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/mfp-pxa27x.h>
+#include <mach/pxa27x.h>
#include <mach/pxa2xx_spi.h>
#include <mach/trizeps4.h>
#include <mach/audio.h>
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index 4b3120dbc049..0e65344e9f53 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -42,12 +42,9 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h>
-#include <mach/bitfield.h>
+#include <mach/pxa25x.h>
#include <mach/audio.h>
#include <mach/pxafb.h>
-#include <mach/mfp-pxa25x.h>
#include <mach/i2c.h>
#include <mach/viper.h>
@@ -956,7 +953,7 @@ static struct map_desc viper_io_desc[] __initdata = {
},
{
.virtual = VIPER_PC104IO_BASE,
- .pfn = __phys_to_pfn(_PCMCIA1IO),
+ .pfn = __phys_to_pfn(0x30000000),
.length = 0x00800000,
.type = MT_DEVICE,
},
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c
index 46538885a58a..c1f73205d078 100644
--- a/arch/arm/mach-pxa/zylonite_pxa300.c
+++ b/arch/arm/mach-pxa/zylonite_pxa300.c
@@ -18,9 +18,9 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/i2c/pca953x.h>
+#include <linux/gpio.h>
-#include <asm/gpio.h>
-#include <mach/mfp-pxa300.h>
+#include <mach/pxa300.h>
#include <mach/i2c.h>
#include <mach/zylonite.h>
diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c
index 28e4e623780b..4e1c488c6906 100644
--- a/arch/arm/mach-pxa/zylonite_pxa320.c
+++ b/arch/arm/mach-pxa/zylonite_pxa320.c
@@ -18,7 +18,7 @@
#include <linux/init.h>
#include <linux/gpio.h>
-#include <mach/mfp-pxa320.h>
+#include <mach/pxa320.h>
#include <mach/zylonite.h>
#include "generic.h"
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index ad911854eb4c..b6ec10627776 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -35,6 +35,7 @@ config MACH_REALVIEW_PB11MP
bool "Support RealView/PB11MPCore platform"
select CPU_V6
select ARM_GIC
+ select HAVE_PATA_PLATFORM
help
Include support for the ARM(R) RealView MPCore Platform Baseboard.
PB11MPCore is a platform with an on-board ARM11MPCore and has
@@ -51,6 +52,7 @@ config MACH_REALVIEW_PBA8
bool "Support RealView/PB-A8 platform"
select CPU_V7
select ARM_GIC
+ select HAVE_PATA_PLATFORM
help
Include support for the ARM(R) RealView Cortex-A8 Platform Baseboard.
PB-A8 is a platform with an on-board Cortex-A8 and has support for
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index bd2aa4f16141..9ab947c14f26 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -28,7 +28,8 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/io.h>
-#include <linux/smc911x.h>
+#include <linux/smsc911x.h>
+#include <linux/ata_platform.h>
#include <asm/clkdev.h>
#include <asm/system.h>
@@ -127,14 +128,15 @@ int realview_flash_register(struct resource *res, u32 num)
return platform_device_register(&realview_flash_device);
}
-static struct smc911x_platdata realview_smc911x_platdata = {
- .flags = SMC911X_USE_32BIT,
- .irq_flags = IRQF_SHARED,
- .irq_polarity = 1,
+static struct smsc911x_platform_config smsc911x_config = {
+ .flags = SMSC911X_USE_32BIT,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
};
static struct platform_device realview_eth_device = {
- .name = "smc911x",
+ .name = "smsc911x",
.id = 0,
.num_resources = 2,
};
@@ -144,12 +146,50 @@ int realview_eth_register(const char *name, struct resource *res)
if (name)
realview_eth_device.name = name;
realview_eth_device.resource = res;
- if (strcmp(realview_eth_device.name, "smc911x") == 0)
- realview_eth_device.dev.platform_data = &realview_smc911x_platdata;
+ if (strcmp(realview_eth_device.name, "smsc911x") == 0)
+ realview_eth_device.dev.platform_data = &smsc911x_config;
return platform_device_register(&realview_eth_device);
}
+struct platform_device realview_usb_device = {
+ .name = "isp1760",
+ .num_resources = 2,
+};
+
+int realview_usb_register(struct resource *res)
+{
+ realview_usb_device.resource = res;
+ return platform_device_register(&realview_usb_device);
+}
+
+static struct pata_platform_info pata_platform_data = {
+ .ioport_shift = 1,
+};
+
+static struct resource pata_resources[] = {
+ [0] = {
+ .start = REALVIEW_CF_BASE,
+ .end = REALVIEW_CF_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = REALVIEW_CF_BASE + 0x100,
+ .end = REALVIEW_CF_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device realview_cf_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pata_resources),
+ .resource = pata_resources,
+ .dev = {
+ .platform_data = &pata_platform_data,
+ },
+};
+
static struct resource realview_i2c_resource = {
.start = REALVIEW_I2C_BASE,
.end = REALVIEW_I2C_BASE + SZ_4K - 1,
@@ -158,11 +198,25 @@ static struct resource realview_i2c_resource = {
struct platform_device realview_i2c_device = {
.name = "versatile-i2c",
- .id = -1,
+ .id = 0,
.num_resources = 1,
.resource = &realview_i2c_resource,
};
+static struct i2c_board_info realview_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("rtc-ds1307", 0xd0 >> 1),
+ .type = "ds1338",
+ },
+};
+
+static int __init realview_i2c_init(void)
+{
+ return i2c_register_board_info(0, realview_i2c_board_info,
+ ARRAY_SIZE(realview_i2c_board_info));
+}
+arch_initcall(realview_i2c_init);
+
#define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
static unsigned int realview_mmc_status(struct device *dev)
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index 44269b162d49..21c08637683b 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -45,6 +45,7 @@ static struct amba_device name##_device = { \
}
extern struct platform_device realview_flash_device;
+extern struct platform_device realview_cf_device;
extern struct platform_device realview_i2c_device;
extern struct mmc_platform_data realview_mmc0_plat_data;
extern struct mmc_platform_data realview_mmc1_plat_data;
@@ -62,5 +63,6 @@ extern void realview_leds_event(led_event_t ledevt);
extern void realview_timer_init(unsigned int timer_irq);
extern int realview_flash_register(struct resource *res, u32 num);
extern int realview_eth_register(const char *name, struct resource *res);
+extern int realview_usb_register(struct resource *res);
#endif
diff --git a/arch/arm/mach-realview/include/mach/board-pba8.h b/arch/arm/mach-realview/include/mach/board-pba8.h
index c8bed8f58bab..307f97b16e5b 100644
--- a/arch/arm/mach-realview/include/mach/board-pba8.h
+++ b/arch/arm/mach-realview/include/mach/board-pba8.h
@@ -45,8 +45,6 @@
#define REALVIEW_PBA8_DMC_BASE 0x100E0000 /* DMC configuration */
#define REALVIEW_PBA8_SMC_BASE 0x100E1000 /* SMC configuration */
#define REALVIEW_PBA8_CAN_BASE 0x100E2000 /* CAN bus */
-#define REALVIEW_PBA8_CF_BASE 0x18000000 /* Compact flash */
-#define REALVIEW_PBA8_CF_MEM_BASE 0x18003000 /* SMC for Compact flash */
#define REALVIEW_PBA8_GIC_CPU_BASE 0x1E000000 /* Generic interrupt controller CPU interface */
#define REALVIEW_PBA8_FLASH0_BASE 0x40000000
#define REALVIEW_PBA8_FLASH0_SIZE SZ_64M
diff --git a/arch/arm/mach-realview/include/mach/platform.h b/arch/arm/mach-realview/include/mach/platform.h
index 793a3a332712..c8f50835fed2 100644
--- a/arch/arm/mach-realview/include/mach/platform.h
+++ b/arch/arm/mach-realview/include/mach/platform.h
@@ -204,6 +204,12 @@
#define REALVIEW_LT_BASE 0x80000000 /* Logic Tile expansion */
/*
+ * CompactFlash
+ */
+#define REALVIEW_CF_BASE 0x18000000 /* CompactFlash */
+#define REALVIEW_CF_MEM_BASE 0x18003000 /* SMC for CompactFlash */
+
+/*
* Disk on Chip
*/
#define REALVIEW_DOC_BASE 0x2C000000
diff --git a/arch/arm/mach-realview/include/mach/system.h b/arch/arm/mach-realview/include/mach/system.h
index a2f61c78adbf..1a15a441e027 100644
--- a/arch/arm/mach-realview/include/mach/system.h
+++ b/arch/arm/mach-realview/include/mach/system.h
@@ -34,7 +34,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_RESETCTL_OFFSET;
unsigned int val;
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c
index 67d6d9cc68b2..d0d39adf6407 100644
--- a/arch/arm/mach-realview/localtimer.c
+++ b/arch/arm/mach-realview/localtimer.c
@@ -191,6 +191,7 @@ void __cpuinit local_timer_setup(void)
clk->name = "dummy_timer";
clk->features = CLOCK_EVT_FEAT_DUMMY;
clk->rating = 200;
+ clk->mult = 1;
clk->set_mode = dummy_timer_set_mode;
clk->broadcast = smp_timer_broadcast;
clk->cpumask = cpumask_of(cpu);
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index bed39ed97613..c20fbef122b3 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -264,6 +264,19 @@ static int eth_device_register(void)
return realview_eth_register(name, realview_eb_eth_resources);
}
+static struct resource realview_eb_isp1761_resources[] = {
+ [0] = {
+ .start = REALVIEW_EB_USB_BASE,
+ .end = REALVIEW_EB_USB_BASE + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EB_USB,
+ .end = IRQ_EB_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
static void __init gic_init_irq(void)
{
if (core_tile_eb11mp() || core_tile_a9mp()) {
@@ -323,6 +336,8 @@ static void realview_eb11mp_fixup(void)
/* platform devices */
realview_eb_eth_resources[1].start = IRQ_EB11MP_ETH;
realview_eb_eth_resources[1].end = IRQ_EB11MP_ETH;
+ realview_eb_isp1761_resources[1].start = IRQ_EB11MP_USB;
+ realview_eb_isp1761_resources[1].end = IRQ_EB11MP_USB;
}
static void __init realview_eb_timer_init(void)
@@ -366,6 +381,7 @@ static void __init realview_eb_init(void)
realview_flash_register(&realview_eb_flash_resource, 1);
platform_device_register(&realview_i2c_device);
eth_device_register();
+ realview_usb_register(realview_eb_isp1761_resources);
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index 8f0683c22140..a64b84a7a3df 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -222,6 +222,19 @@ static struct resource realview_pb1176_smsc911x_resources[] = {
},
};
+static struct resource realview_pb1176_isp1761_resources[] = {
+ [0] = {
+ .start = REALVIEW_PB1176_USB_BASE,
+ .end = REALVIEW_PB1176_USB_BASE + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PB1176_USB,
+ .end = IRQ_PB1176_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
static void __init gic_init_irq(void)
{
/* ARM1176 DevChip GIC, primary */
@@ -260,6 +273,8 @@ static void __init realview_pb1176_init(void)
realview_flash_register(&realview_pb1176_flash_resource, 1);
realview_eth_register(NULL, realview_pb1176_smsc911x_resources);
+ platform_device_register(&realview_i2c_device);
+ realview_usb_register(realview_pb1176_isp1761_resources);
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 3ebdb2dadd6f..ea1e60eca359 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -230,31 +230,19 @@ static struct resource realview_pb11mp_smsc911x_resources[] = {
},
};
-struct resource realview_pb11mp_cf_resources[] = {
+static struct resource realview_pb11mp_isp1761_resources[] = {
[0] = {
- .start = REALVIEW_PB11MP_CF_BASE,
- .end = REALVIEW_PB11MP_CF_BASE + SZ_4K - 1,
+ .start = REALVIEW_PB11MP_USB_BASE,
+ .end = REALVIEW_PB11MP_USB_BASE + SZ_128K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = REALVIEW_PB11MP_CF_MEM_BASE,
- .end = REALVIEW_PB11MP_CF_MEM_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- [2] = {
- .start = -1, /* FIXME: Find correct irq */
- .end = -1,
+ .start = IRQ_TC11MP_USB,
+ .end = IRQ_TC11MP_USB,
.flags = IORESOURCE_IRQ,
},
};
-struct platform_device realview_pb11mp_cf_device = {
- .name = "compactflash",
- .id = 0,
- .num_resources = ARRAY_SIZE(realview_pb11mp_cf_resources),
- .resource = realview_pb11mp_cf_resources,
-};
-
static void __init gic_init_irq(void)
{
unsigned int pldctrl;
@@ -308,7 +296,8 @@ static void __init realview_pb11mp_init(void)
ARRAY_SIZE(realview_pb11mp_flash_resource));
realview_eth_register(NULL, realview_pb11mp_smsc911x_resources);
platform_device_register(&realview_i2c_device);
- platform_device_register(&realview_pb11mp_cf_device);
+ platform_device_register(&realview_cf_device);
+ realview_usb_register(realview_pb11mp_isp1761_resources);
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 34c94435d2d8..d6ac1eb86576 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -221,31 +221,19 @@ static struct resource realview_pba8_smsc911x_resources[] = {
},
};
-struct resource realview_pba8_cf_resources[] = {
+static struct resource realview_pba8_isp1761_resources[] = {
[0] = {
- .start = REALVIEW_PBA8_CF_BASE,
- .end = REALVIEW_PBA8_CF_BASE + SZ_4K - 1,
+ .start = REALVIEW_PBA8_USB_BASE,
+ .end = REALVIEW_PBA8_USB_BASE + SZ_128K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = REALVIEW_PBA8_CF_MEM_BASE,
- .end = REALVIEW_PBA8_CF_MEM_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- [2] = {
- .start = -1, /* FIXME: Find correct irq */
- .end = -1,
+ .start = IRQ_PBA8_USB,
+ .end = IRQ_PBA8_USB,
.flags = IORESOURCE_IRQ,
},
};
-struct platform_device realview_pba8_cf_device = {
- .name = "compactflash",
- .id = 0,
- .num_resources = ARRAY_SIZE(realview_pba8_cf_resources),
- .resource = realview_pba8_cf_resources,
-};
-
static void __init gic_init_irq(void)
{
/* ARM PB-A8 on-board GIC */
@@ -276,7 +264,8 @@ static void __init realview_pba8_init(void)
ARRAY_SIZE(realview_pba8_flash_resource));
realview_eth_register(NULL, realview_pba8_smsc911x_resources);
platform_device_register(&realview_i2c_device);
- platform_device_register(&realview_pba8_cf_device);
+ platform_device_register(&realview_cf_device);
+ realview_usb_register(realview_pba8_isp1761_resources);
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs[i];
diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c
index 7958a30f8932..c47d974d52bd 100644
--- a/arch/arm/mach-rpc/dma.c
+++ b/arch/arm/mach-rpc/dma.c
@@ -26,6 +26,16 @@
#include <asm/mach/dma.h>
#include <asm/hardware/iomd.h>
+struct iomd_dma {
+ struct dma_struct dma;
+ unsigned int state;
+ unsigned long base; /* Controller base address */
+ int irq; /* Controller IRQ */
+ struct scatterlist cur_sg; /* Current controller buffer */
+ dma_addr_t dma_addr;
+ unsigned int dma_len;
+};
+
#if 0
typedef enum {
dma_size_8 = 1,
@@ -44,15 +54,15 @@ typedef enum {
#define CR (IOMD_IO0CR - IOMD_IO0CURA)
#define ST (IOMD_IO0ST - IOMD_IO0CURA)
-static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma)
+static void iomd_get_next_sg(struct scatterlist *sg, struct iomd_dma *idma)
{
unsigned long end, offset, flags = 0;
- if (dma->sg) {
- sg->dma_address = dma->sg->dma_address;
+ if (idma->dma.sg) {
+ sg->dma_address = idma->dma_addr;
offset = sg->dma_address & ~PAGE_MASK;
- end = offset + dma->sg->length;
+ end = offset + idma->dma_len;
if (end > PAGE_SIZE)
end = PAGE_SIZE;
@@ -62,15 +72,17 @@ static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma)
sg->length = end - TRANSFER_SIZE;
- dma->sg->length -= end - offset;
- dma->sg->dma_address += end - offset;
+ idma->dma_len -= end - offset;
+ idma->dma_addr += end - offset;
- if (dma->sg->length == 0) {
- if (dma->sgcount > 1) {
- dma->sg++;
- dma->sgcount--;
+ if (idma->dma_len == 0) {
+ if (idma->dma.sgcount > 1) {
+ idma->dma.sg = sg_next(idma->dma.sg);
+ idma->dma_addr = idma->dma.sg->dma_address;
+ idma->dma_len = idma->dma.sg->length;
+ idma->dma.sgcount--;
} else {
- dma->sg = NULL;
+ idma->dma.sg = NULL;
flags |= DMA_END_S;
}
}
@@ -85,8 +97,8 @@ static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma)
static irqreturn_t iomd_dma_handle(int irq, void *dev_id)
{
- dma_t *dma = (dma_t *)dev_id;
- unsigned long base = dma->dma_base;
+ struct iomd_dma *idma = dev_id;
+ unsigned long base = idma->base;
do {
unsigned int status;
@@ -95,93 +107,99 @@ static irqreturn_t iomd_dma_handle(int irq, void *dev_id)
if (!(status & DMA_ST_INT))
return IRQ_HANDLED;
- if ((dma->state ^ status) & DMA_ST_AB)
- iomd_get_next_sg(&dma->cur_sg, dma);
+ if ((idma->state ^ status) & DMA_ST_AB)
+ iomd_get_next_sg(&idma->cur_sg, idma);
switch (status & (DMA_ST_OFL | DMA_ST_AB)) {
case DMA_ST_OFL: /* OIA */
case DMA_ST_AB: /* .IB */
- iomd_writel(dma->cur_sg.dma_address, base + CURA);
- iomd_writel(dma->cur_sg.length, base + ENDA);
- dma->state = DMA_ST_AB;
+ iomd_writel(idma->cur_sg.dma_address, base + CURA);
+ iomd_writel(idma->cur_sg.length, base + ENDA);
+ idma->state = DMA_ST_AB;
break;
case DMA_ST_OFL | DMA_ST_AB: /* OIB */
case 0: /* .IA */
- iomd_writel(dma->cur_sg.dma_address, base + CURB);
- iomd_writel(dma->cur_sg.length, base + ENDB);
- dma->state = 0;
+ iomd_writel(idma->cur_sg.dma_address, base + CURB);
+ iomd_writel(idma->cur_sg.length, base + ENDB);
+ idma->state = 0;
break;
}
if (status & DMA_ST_OFL &&
- dma->cur_sg.length == (DMA_END_S|DMA_END_L))
+ idma->cur_sg.length == (DMA_END_S|DMA_END_L))
break;
} while (1);
- dma->state = ~DMA_ST_AB;
+ idma->state = ~DMA_ST_AB;
disable_irq(irq);
return IRQ_HANDLED;
}
-static int iomd_request_dma(dmach_t channel, dma_t *dma)
+static int iomd_request_dma(unsigned int chan, dma_t *dma)
{
- return request_irq(dma->dma_irq, iomd_dma_handle,
- IRQF_DISABLED, dma->device_id, dma);
+ struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
+
+ return request_irq(idma->irq, iomd_dma_handle,
+ IRQF_DISABLED, idma->dma.device_id, idma);
}
-static void iomd_free_dma(dmach_t channel, dma_t *dma)
+static void iomd_free_dma(unsigned int chan, dma_t *dma)
{
- free_irq(dma->dma_irq, dma);
+ struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
+
+ free_irq(idma->irq, idma);
}
-static void iomd_enable_dma(dmach_t channel, dma_t *dma)
+static void iomd_enable_dma(unsigned int chan, dma_t *dma)
{
- unsigned long dma_base = dma->dma_base;
+ struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
+ unsigned long dma_base = idma->base;
unsigned int ctrl = TRANSFER_SIZE | DMA_CR_E;
- if (dma->invalid) {
- dma->invalid = 0;
+ if (idma->dma.invalid) {
+ idma->dma.invalid = 0;
/*
* Cope with ISA-style drivers which expect cache
* coherence.
*/
- if (!dma->sg) {
- dma->sg = &dma->buf;
- dma->sgcount = 1;
- dma->buf.length = dma->count;
- dma->buf.dma_address = dma_map_single(NULL,
- dma->addr, dma->count,
- dma->dma_mode == DMA_MODE_READ ?
+ if (!idma->dma.sg) {
+ idma->dma.sg = &idma->dma.buf;
+ idma->dma.sgcount = 1;
+ idma->dma.buf.length = idma->dma.count;
+ idma->dma.buf.dma_address = dma_map_single(NULL,
+ idma->dma.addr, idma->dma.count,
+ idma->dma.dma_mode == DMA_MODE_READ ?
DMA_FROM_DEVICE : DMA_TO_DEVICE);
}
iomd_writeb(DMA_CR_C, dma_base + CR);
- dma->state = DMA_ST_AB;
+ idma->state = DMA_ST_AB;
}
-
- if (dma->dma_mode == DMA_MODE_READ)
+
+ if (idma->dma.dma_mode == DMA_MODE_READ)
ctrl |= DMA_CR_D;
iomd_writeb(ctrl, dma_base + CR);
- enable_irq(dma->dma_irq);
+ enable_irq(idma->irq);
}
-static void iomd_disable_dma(dmach_t channel, dma_t *dma)
+static void iomd_disable_dma(unsigned int chan, dma_t *dma)
{
- unsigned long dma_base = dma->dma_base;
+ struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
+ unsigned long dma_base = idma->base;
unsigned long flags;
local_irq_save(flags);
- if (dma->state != ~DMA_ST_AB)
- disable_irq(dma->dma_irq);
+ if (idma->state != ~DMA_ST_AB)
+ disable_irq(idma->irq);
iomd_writeb(0, dma_base + CR);
local_irq_restore(flags);
}
-static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
+static int iomd_set_dma_speed(unsigned int chan, dma_t *dma, int cycle)
{
int tcr, speed;
@@ -197,7 +215,7 @@ static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
tcr = iomd_readb(IOMD_DMATCR);
speed &= 3;
- switch (channel) {
+ switch (chan) {
case DMA_0:
tcr = (tcr & ~0x03) | speed;
break;
@@ -236,16 +254,22 @@ static struct fiq_handler fh = {
.name = "floppydma"
};
-static void floppy_enable_dma(dmach_t channel, dma_t *dma)
+struct floppy_dma {
+ struct dma_struct dma;
+ unsigned int fiq;
+};
+
+static void floppy_enable_dma(unsigned int chan, dma_t *dma)
{
+ struct floppy_dma *fdma = container_of(dma, struct floppy_dma, dma);
void *fiqhandler_start;
unsigned int fiqhandler_length;
struct pt_regs regs;
- if (dma->sg)
+ if (fdma->dma.sg)
BUG();
- if (dma->dma_mode == DMA_MODE_READ) {
+ if (fdma->dma.dma_mode == DMA_MODE_READ) {
extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
fiqhandler_start = &floppy_fiqin_start;
fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
@@ -255,8 +279,8 @@ static void floppy_enable_dma(dmach_t channel, dma_t *dma)
fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
}
- regs.ARM_r9 = dma->count;
- regs.ARM_r10 = (unsigned long)dma->addr;
+ regs.ARM_r9 = fdma->dma.count;
+ regs.ARM_r10 = (unsigned long)fdma->dma.addr;
regs.ARM_fp = (unsigned long)FLOPPYDMA_BASE;
if (claim_fiq(&fh)) {
@@ -266,16 +290,17 @@ static void floppy_enable_dma(dmach_t channel, dma_t *dma)
set_fiq_handler(fiqhandler_start, fiqhandler_length);
set_fiq_regs(&regs);
- enable_fiq(dma->dma_irq);
+ enable_fiq(fdma->fiq);
}
-static void floppy_disable_dma(dmach_t channel, dma_t *dma)
+static void floppy_disable_dma(unsigned int chan, dma_t *dma)
{
- disable_fiq(dma->dma_irq);
+ struct floppy_dma *fdma = container_of(dma, struct floppy_dma, dma);
+ disable_fiq(fdma->fiq);
release_fiq(&fh);
}
-static int floppy_get_residue(dmach_t channel, dma_t *dma)
+static int floppy_get_residue(unsigned int chan, dma_t *dma)
{
struct pt_regs regs;
get_fiq_regs(&regs);
@@ -292,7 +317,7 @@ static struct dma_ops floppy_dma_ops = {
/*
* This is virtual DMA - we don't need anything here.
*/
-static void sound_enable_disable_dma(dmach_t channel, dma_t *dma)
+static void sound_enable_disable_dma(unsigned int chan, dma_t *dma)
{
}
@@ -302,8 +327,24 @@ static struct dma_ops sound_dma_ops = {
.disable = sound_enable_disable_dma,
};
-void __init arch_dma_init(dma_t *dma)
+static struct iomd_dma iomd_dma[6];
+
+static struct floppy_dma floppy_dma = {
+ .dma = {
+ .d_ops = &floppy_dma_ops,
+ },
+ .fiq = FIQ_FLOPPYDATA,
+};
+
+static dma_t sound_dma = {
+ .d_ops = &sound_dma_ops,
+};
+
+static int __init rpc_dma_init(void)
{
+ unsigned int i;
+ int ret;
+
iomd_writeb(0, IOMD_IO0CR);
iomd_writeb(0, IOMD_IO1CR);
iomd_writeb(0, IOMD_IO2CR);
@@ -311,31 +352,39 @@ void __init arch_dma_init(dma_t *dma)
iomd_writeb(0xa0, IOMD_DMATCR);
- dma[DMA_0].dma_base = IOMD_IO0CURA;
- dma[DMA_0].dma_irq = IRQ_DMA0;
- dma[DMA_0].d_ops = &iomd_dma_ops;
- dma[DMA_1].dma_base = IOMD_IO1CURA;
- dma[DMA_1].dma_irq = IRQ_DMA1;
- dma[DMA_1].d_ops = &iomd_dma_ops;
- dma[DMA_2].dma_base = IOMD_IO2CURA;
- dma[DMA_2].dma_irq = IRQ_DMA2;
- dma[DMA_2].d_ops = &iomd_dma_ops;
- dma[DMA_3].dma_base = IOMD_IO3CURA;
- dma[DMA_3].dma_irq = IRQ_DMA3;
- dma[DMA_3].d_ops = &iomd_dma_ops;
- dma[DMA_S0].dma_base = IOMD_SD0CURA;
- dma[DMA_S0].dma_irq = IRQ_DMAS0;
- dma[DMA_S0].d_ops = &iomd_dma_ops;
- dma[DMA_S1].dma_base = IOMD_SD1CURA;
- dma[DMA_S1].dma_irq = IRQ_DMAS1;
- dma[DMA_S1].d_ops = &iomd_dma_ops;
- dma[DMA_VIRTUAL_FLOPPY].dma_irq = FIQ_FLOPPYDATA;
- dma[DMA_VIRTUAL_FLOPPY].d_ops = &floppy_dma_ops;
- dma[DMA_VIRTUAL_SOUND].d_ops = &sound_dma_ops;
-
/*
* Setup DMA channels 2,3 to be for podules
* and channels 0,1 for internal devices
*/
iomd_writeb(DMA_EXT_IO3|DMA_EXT_IO2, IOMD_DMAEXT);
+
+ iomd_dma[DMA_0].base = IOMD_IO0CURA;
+ iomd_dma[DMA_0].irq = IRQ_DMA0;
+ iomd_dma[DMA_1].base = IOMD_IO1CURA;
+ iomd_dma[DMA_1].irq = IRQ_DMA1;
+ iomd_dma[DMA_2].base = IOMD_IO2CURA;
+ iomd_dma[DMA_2].irq = IRQ_DMA2;
+ iomd_dma[DMA_3].base = IOMD_IO3CURA;
+ iomd_dma[DMA_3].irq = IRQ_DMA3;
+ iomd_dma[DMA_S0].base = IOMD_SD0CURA;
+ iomd_dma[DMA_S0].irq = IRQ_DMAS0;
+ iomd_dma[DMA_S1].base = IOMD_SD1CURA;
+ iomd_dma[DMA_S1].irq = IRQ_DMAS1;
+
+ for (i = DMA_0; i <= DMA_S1; i++) {
+ iomd_dma[i].dma.d_ops = &iomd_dma_ops;
+
+ ret = isa_dma_add(i, &iomd_dma[i].dma);
+ if (ret)
+ printk("IOMDDMA%u: unable to register: %d\n", i, ret);
+ }
+
+ ret = isa_dma_add(DMA_VIRTUAL_FLOPPY, &floppy_dma.dma);
+ if (ret)
+ printk("IOMDFLOPPY: unable to register: %d\n", ret);
+ ret = isa_dma_add(DMA_VIRTUAL_SOUND, &sound_dma);
+ if (ret)
+ printk("IOMDSOUND: unable to register: %d\n", ret);
+ return 0;
}
+core_initcall(rpc_dma_init);
diff --git a/arch/arm/mach-rpc/include/mach/isa-dma.h b/arch/arm/mach-rpc/include/mach/isa-dma.h
index bad720548587..67bfc6719c34 100644
--- a/arch/arm/mach-rpc/include/mach/isa-dma.h
+++ b/arch/arm/mach-rpc/include/mach/isa-dma.h
@@ -23,5 +23,7 @@
#define DMA_FLOPPY DMA_VIRTUAL_FLOPPY
+#define IOMD_DMA_BOUNDARY (PAGE_SIZE - 1)
+
#endif /* _ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-rpc/include/mach/system.h b/arch/arm/mach-rpc/include/mach/system.h
index bd7268ba17e2..45c7b935dc45 100644
--- a/arch/arm/mach-rpc/include/mach/system.h
+++ b/arch/arm/mach-rpc/include/mach/system.h
@@ -16,7 +16,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
iomd_writeb(0, IOMD_ROMCR0);
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index 552b4c778fdc..440c014e24b3 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -28,7 +28,7 @@
#include <mach/regs-mem.h>
#include <mach/regs-lcd.h>
#include <mach/regs-sdi.h>
-#include <asm/plat-s3c24xx/regs-iis.h>
+#include <plat/regs-iis.h>
#include <plat/regs-spi.h>
static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
new file mode 100644
index 000000000000..ce1ec69806a1
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
@@ -0,0 +1,23 @@
+/* arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - GPIO bank numbering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C2410_GPIONO(bank,offset) ((bank) + (offset))
+
+#define S3C2410_GPIO_BANKA (32*0)
+#define S3C2410_GPIO_BANKB (32*1)
+#define S3C2410_GPIO_BANKC (32*2)
+#define S3C2410_GPIO_BANKD (32*3)
+#define S3C2410_GPIO_BANKE (32*4)
+#define S3C2410_GPIO_BANKF (32*5)
+#define S3C2410_GPIO_BANKG (32*6)
+#define S3C2410_GPIO_BANKH (32*7)
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio.h b/arch/arm/mach-s3c2410/include/mach/gpio.h
index 00476a573bbe..51a88cf9526b 100644
--- a/arch/arm/mach-s3c2410/include/mach/gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/gpio.h
@@ -23,3 +23,6 @@
#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA)
#include <asm-generic/gpio.h>
+#include <mach/gpio-nrs.h>
+
+#define S3C_GPIO_END (S3C2410_GPIO_BANKH + 32)
diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h
index 49efce8cd4a7..2a2384ffa7b1 100644
--- a/arch/arm/mach-s3c2410/include/mach/irqs.h
+++ b/arch/arm/mach-s3c2410/include/mach/irqs.h
@@ -80,7 +80,7 @@
#define IRQ_EINT22 S3C2410_IRQ(50)
#define IRQ_EINT23 S3C2410_IRQ(51)
-
+#define IRQ_EINT_BIT(x) ((x) - IRQ_EINT4 + 4)
#define IRQ_EINT(x) (((x) >= 4) ? (IRQ_EINT4 + (x) - 4) : (IRQ_EINT0 + (x)))
#define IRQ_LCD_FIFO S3C2410_IRQ(52)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
index 321077613067..35a03df473fc 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
@@ -14,16 +14,7 @@
#ifndef __ASM_ARCH_REGS_GPIO_H
#define __ASM_ARCH_REGS_GPIO_H
-#define S3C2410_GPIONO(bank,offset) ((bank) + (offset))
-
-#define S3C2410_GPIO_BANKA (32*0)
-#define S3C2410_GPIO_BANKB (32*1)
-#define S3C2410_GPIO_BANKC (32*2)
-#define S3C2410_GPIO_BANKD (32*3)
-#define S3C2410_GPIO_BANKE (32*4)
-#define S3C2410_GPIO_BANKF (32*5)
-#define S3C2410_GPIO_BANKG (32*6)
-#define S3C2410_GPIO_BANKH (32*7)
+#include <mach/gpio-nrs.h>
#ifdef CONFIG_CPU_S3C2400
#define S3C24XX_GPIO_BASE(x) S3C2400_GPIO_BASE(x)
diff --git a/arch/arm/mach-s3c2410/include/mach/system-reset.h b/arch/arm/mach-s3c2410/include/mach/system-reset.h
index 7613d0a384ba..b8687f71c304 100644
--- a/arch/arm/mach-s3c2410/include/mach/system-reset.h
+++ b/arch/arm/mach-s3c2410/include/mach/system-reset.h
@@ -22,7 +22,7 @@
extern void (*s3c24xx_reset_hook)(void);
static void
-arch_reset(char mode)
+arch_reset(char mode, const char *cmd)
{
struct clk *wdtclk;
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 821a1668c3ac..7a7c4da4c256 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -203,7 +203,7 @@ static void __init h1940_map_io(void)
#ifdef CONFIG_PM_H1940
memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
#endif
- s3c2410_pm_init();
+ s3c_pm_init();
}
static void __init h1940_init_irq(void)
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index 9678a53ceeb1..9f1ba9b63f70 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -355,7 +355,7 @@ static void __init qt2410_machine_init(void)
s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPIO_OUTPUT);
platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
- s3c2410_pm_init();
+ s3c_pm_init();
}
MACHINE_START(QT2410, "QT2410")
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
index a6970f613192..87fc481d92d4 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -37,21 +37,14 @@
#include <plat/cpu.h>
#include <plat/pm.h>
-#ifdef CONFIG_S3C2410_PM_DEBUG
-extern void pm_dbg(const char *fmt, ...);
-#define DBG(fmt...) pm_dbg(fmt)
-#else
-#define DBG(fmt...) printk(KERN_DEBUG fmt)
-#endif
-
static void s3c2410_pm_prepare(void)
{
/* ensure at least GSTATUS3 has the resume address */
- __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
+ __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2410_GSTATUS3);
- DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
- DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
+ S3C_PMDBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
+ S3C_PMDBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
if (machine_is_h1940()) {
void *base = phys_to_virt(H1940_SUSPEND_CHECK);
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
index 6078f09b7df5..8331e8d97e20 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -29,13 +29,14 @@
#include <mach/bast-map.h>
#include <mach/bast-irq.h>
-#include <mach/usb-control.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <asm/irq.h>
+#include <plat/usb-control.h>
#include <plat/devs.h>
+
#include "usb-simtec.h"
/* control power and monitor over-current events on various Simtec
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
index 919856c9433f..9e3478506c6f 100644
--- a/arch/arm/mach-s3c2412/dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -29,8 +29,8 @@
#include <mach/regs-mem.h>
#include <mach/regs-lcd.h>
#include <mach/regs-sdi.h>
-#include <asm/plat-s3c24xx/regs-s3c2412-iis.h>
-#include <asm/plat-s3c24xx/regs-iis.h>
+#include <plat/regs-s3c2412-iis.h>
+#include <plat/regs-iis.h>
#include <plat/regs-spi.h>
#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c
index ecddbbb34832..72c266aee141 100644
--- a/arch/arm/mach-s3c2412/mach-jive.c
+++ b/arch/arm/mach-s3c2412/mach-jive.c
@@ -494,7 +494,7 @@ static int jive_pm_suspend(struct sys_device *sd, pm_message_t state)
* correct address to resume from. */
__raw_writel(0x2BED, S3C2412_INFORM0);
- __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2412_INFORM1);
+ __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
return 0;
}
@@ -630,7 +630,7 @@ static void __init jive_machine_init(void)
/* initialise the power management now we've setup everything. */
- s3c2410_pm_init();
+ s3c_pm_init();
s3c_device_nand.dev.platform_data = &jive_nand_info;
diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c
index 217e9e4ed45f..c9cfe40e21f6 100644
--- a/arch/arm/mach-s3c2412/pm.c
+++ b/arch/arm/mach-s3c2412/pm.c
@@ -85,7 +85,7 @@ static struct sleep_save s3c2412_sleep[] = {
static int s3c2412_pm_suspend(struct sys_device *dev, pm_message_t state)
{
- s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+ s3c_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
return 0;
}
@@ -98,7 +98,7 @@ static int s3c2412_pm_resume(struct sys_device *dev)
tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
__raw_writel(tmp, S3C2412_PWRCFG);
- s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+ s3c_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
return 0;
}
diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c
index 5b5ee0b8f4e0..69b6cf34df47 100644
--- a/arch/arm/mach-s3c2440/dma.c
+++ b/arch/arm/mach-s3c2440/dma.c
@@ -28,7 +28,7 @@
#include <mach/regs-mem.h>
#include <mach/regs-lcd.h>
#include <mach/regs-sdi.h>
-#include <asm/plat-s3c24xx/regs-iis.h>
+#include <plat/regs-iis.h>
#include <plat/regs-spi.h>
static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index 12d378f84ad2..bc8d8d1ebd1a 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -203,7 +203,7 @@ static void __init rx3715_init_machine(void)
#ifdef CONFIG_PM_H1940
memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
#endif
- s3c2410_pm_init();
+ s3c_pm_init();
s3c24xx_fb_set_platdata(&rx3715_fb_info);
platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices));
diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c
index 2a58a4d5aa5a..8430e5829186 100644
--- a/arch/arm/mach-s3c2443/dma.c
+++ b/arch/arm/mach-s3c2443/dma.c
@@ -29,7 +29,7 @@
#include <mach/regs-mem.h>
#include <mach/regs-lcd.h>
#include <mach/regs-sdi.h>
-#include <asm/plat-s3c24xx/regs-iis.h>
+#include <plat/regs-iis.h>
#include <plat/regs-spi.h>
#define MAP(x) { \
diff --git a/arch/arm/mach-s3c24a0/include/mach/irqs.h b/arch/arm/mach-s3c24a0/include/mach/irqs.h
index ae8c0e359783..83ce2a7a9dae 100644
--- a/arch/arm/mach-s3c24a0/include/mach/irqs.h
+++ b/arch/arm/mach-s3c24a0/include/mach/irqs.h
@@ -70,6 +70,8 @@
#define IRQ_EINT17 S3C2410_IRQ(49)
#define IRQ_EINT18 S3C2410_IRQ(50)
+#define IRQ_EINT_BIT(x) ((x) - IRQ_EINT00)
+
/* SUB IRQS */
#define IRQ_S3CUART_RX0 S3C2410_IRQ(51) /* 67 */
#define IRQ_S3CUART_TX0 S3C2410_IRQ(52)
diff --git a/arch/arm/mach-s3c6400/include/mach/map.h b/arch/arm/mach-s3c6400/include/mach/map.h
index cff27d813fc6..baf1c0f1ea5a 100644
--- a/arch/arm/mach-s3c6400/include/mach/map.h
+++ b/arch/arm/mach-s3c6400/include/mach/map.h
@@ -52,6 +52,9 @@
#define S3C64XX_PA_VIC0 (0x71200000)
#define S3C64XX_PA_VIC1 (0x71300000)
+#define S3C64XX_PA_MODEM (0x74108000)
+#define S3C64XX_VA_MODEM S3C_ADDR(0x00600000)
+
/* place VICs close together */
#define S3C_VA_VIC0 (S3C_VA_IRQ + 0x00)
#define S3C_VA_VIC1 (S3C_VA_IRQ + 0x10000)
diff --git a/arch/arm/mach-s3c6400/include/mach/system.h b/arch/arm/mach-s3c6400/include/mach/system.h
index 652bbc403f0b..090cfd969bc7 100644
--- a/arch/arm/mach-s3c6400/include/mach/system.h
+++ b/arch/arm/mach-s3c6400/include/mach/system.h
@@ -16,7 +16,7 @@ static void arch_idle(void)
/* nothing here yet */
}
-static void arch_reset(char mode)
+static void arch_reset(char mode, const char *cmd)
{
/* nothing here yet */
}
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index f99d9013905f..81ffff7ed498 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -71,19 +71,9 @@ config SA1100_H3600
<http://www.handhelds.org/Compaq/index.html#iPAQ_H3600>
<http://www.compaq.com/products/handhelds/pocketpc/>
-config SA1100_H3800
- bool "Compaq iPAQ H3800"
- help
- Say Y here if you intend to run this kernel on the Compaq iPAQ H3800
- series handheld computer. Information about this machine and the
- Linux port to this machine can be found at:
-
- <http://www.handhelds.org/Compaq/index.html#iPAQ_H3800>
- <http://www.compaq.com/products/handhelds/pocketpc/>
-
config SA1100_H3XXX
bool
- depends on SA1100_H3100 || SA1100_H3600 || SA1100_H3800
+ depends on SA1100_H3100 || SA1100_H3600
default y
config SA1100_BADGE4
@@ -157,15 +147,6 @@ config SA1100_SSP
This isn't for audio support, but for attached sensors and
other devices, eg for BadgePAD 4 sensor support.
-config H3600_SLEEVE
- tristate "Compaq iPAQ Handheld sleeve support"
- depends on SA1100_H3100 || SA1100_H3600
- help
- Choose this option to enable support for extension packs (sleeves)
- for the Compaq iPAQ H3XXX series of handheld computers. This option
- is required for the CF, PCMCIA, Bluetooth and GSM/GPRS extension
- packs.
-
endmenu
endif
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 2052eb88c961..bbf2ebcc3066 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -25,6 +25,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/timer.h>
+#include <linux/gpio.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -145,7 +146,8 @@ static struct locomo_driver collie_uart_driver = {
.remove = collie_uart_remove,
};
-static int __init collie_uart_init(void) {
+static int __init collie_uart_init(void)
+{
return locomo_driver_register(&collie_uart_driver);
}
device_initcall(collie_uart_init);
@@ -195,18 +197,34 @@ static struct mtd_partition collie_partitions[] = {
}
};
+static int collie_flash_init(void)
+{
+ int rc = gpio_request(COLLIE_GPIO_VPEN, "flash Vpp enable");
+ if (rc)
+ return rc;
+
+ rc = gpio_direction_output(COLLIE_GPIO_VPEN, 1);
+ if (rc)
+ gpio_free(COLLIE_GPIO_VPEN);
+
+ return rc;
+}
+
static void collie_set_vpp(int vpp)
{
- write_scoop_reg(&colliescoop_device.dev, SCOOP_GPCR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPCR) | COLLIE_SCP_VPEN);
- if (vpp)
- write_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR) | COLLIE_SCP_VPEN);
- else
- write_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR, read_scoop_reg(&colliescoop_device.dev, SCOOP_GPWR) & ~COLLIE_SCP_VPEN);
+ gpio_set_value(COLLIE_GPIO_VPEN, vpp);
+}
+
+static void collie_flash_exit(void)
+{
+ gpio_free(COLLIE_GPIO_VPEN);
}
static struct flash_platform_data collie_flash_data = {
.map_name = "cfi_probe",
+ .init = collie_flash_init,
.set_vpp = collie_set_vpp,
+ .exit = collie_flash_exit,
.parts = collie_partitions,
.nr_parts = ARRAY_SIZE(collie_partitions),
};
diff --git a/arch/arm/mach-sa1100/collie_pm.c b/arch/arm/mach-sa1100/collie_pm.c
index b39307f26b52..444f266ecc06 100644
--- a/arch/arm/mach-sa1100/collie_pm.c
+++ b/arch/arm/mach-sa1100/collie_pm.c
@@ -22,6 +22,7 @@
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/platform_device.h>
+#include <linux/gpio.h>
#include <asm/irq.h>
#include <mach/hardware.h>
@@ -58,6 +59,9 @@ static void collie_charger_init(void)
return;
}
+ gpio_request(COLLIE_GPIO_CHARGE_ON, "charge on");
+ gpio_direction_output(COLLIE_GPIO_CHARGE_ON, 1);
+
ucb1x00_io_set_dir(ucb, 0, COLLIE_TC35143_GPIO_MBAT_ON | COLLIE_TC35143_GPIO_TMP_ON |
COLLIE_TC35143_GPIO_BBAT_ON);
return;
@@ -73,17 +77,11 @@ static void collie_measure_temp(int on)
static void collie_charge(int on)
{
- extern struct platform_device colliescoop_device;
-
/* Zaurus seems to contain LTC1731; it should know when to
* stop charging itself, so setting charge on should be
* relatively harmless (as long as it is not done too often).
*/
- if (on) {
- set_scoop_gpio(&colliescoop_device.dev, COLLIE_SCP_CHARGE_ON);
- } else {
- reset_scoop_gpio(&colliescoop_device.dev, COLLIE_SCP_CHARGE_ON);
- }
+ gpio_set_value(COLLIE_GPIO_CHARGE_ON, on);
}
static void collie_discharge(int on)
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index af25a78d705d..0eb2f159578b 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -42,19 +42,12 @@
#include <asm/mach/serial_sa1100.h>
#include <mach/h3600.h>
-
-#if defined (CONFIG_SA1100_H3600) || defined (CONFIG_SA1100_H3100)
#include <mach/h3600_gpio.h>
-#endif
-
-#ifdef CONFIG_SA1100_H3800
-#include <mach/h3600_asic.h>
-#endif
#include "generic.h"
-struct ipaq_model_ops ipaq_model_ops;
-EXPORT_SYMBOL(ipaq_model_ops);
+void (*assign_h3600_egpio)(enum ipaq_egpio_type x, int level);
+EXPORT_SYMBOL(assign_h3600_egpio);
static struct mtd_partition h3xxx_partitions[] = {
{
@@ -63,41 +56,9 @@ static struct mtd_partition h3xxx_partitions[] = {
.offset = 0,
.mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
-#ifdef CONFIG_MTD_2PARTS_IPAQ
- .name = "H3XXX root jffs2",
+ .name = "H3XXX rootfs",
.size = MTDPART_SIZ_FULL,
.offset = 0x00040000,
-#else
- .name = "H3XXX kernel",
- .size = 0x00080000,
- .offset = 0x00040000,
- }, {
- .name = "H3XXX params",
- .size = 0x00040000,
- .offset = 0x000C0000,
- }, {
-#ifdef CONFIG_JFFS2_FS
- .name = "H3XXX root jffs2",
- .size = MTDPART_SIZ_FULL,
- .offset = 0x00100000,
-#else
- .name = "H3XXX initrd",
- .size = 0x00100000,
- .offset = 0x00100000,
- }, {
- .name = "H3XXX root cramfs",
- .size = 0x00300000,
- .offset = 0x00200000,
- }, {
- .name = "H3XXX usr cramfs",
- .size = 0x00800000,
- .offset = 0x00500000,
- }, {
- .name = "H3XXX usr local",
- .size = MTDPART_SIZ_FULL,
- .offset = 0x00d00000,
-#endif
-#endif
}
};
@@ -131,11 +92,7 @@ static int h3600_irda_set_power(struct device *dev, unsigned int state)
static void h3600_irda_set_speed(struct device *dev, unsigned int speed)
{
- if (speed < 4000000) {
- clr_h3600_egpio(IPAQ_EGPIO_IR_FSEL);
- } else {
- set_h3600_egpio(IPAQ_EGPIO_IR_FSEL);
- }
+ assign_h3600_egpio(IPAQ_EGPIO_IR_FSEL, !(speed < 4000000));
}
static struct irda_platform_data h3600_irda_data = {
@@ -266,12 +223,6 @@ static void __init h3xxx_map_io(void)
sa1100fb_lcd_power = h3xxx_lcd_power;
}
-static __inline__ void do_blank(int setp)
-{
- if (ipaq_model_ops.blank_callback)
- ipaq_model_ops.blank_callback(1-setp);
-}
-
/************************* H3100 *************************/
#ifdef CONFIG_SA1100_H3100
@@ -289,7 +240,6 @@ static void h3100_control_egpio(enum ipaq_egpio_type x, int setp)
case IPAQ_EGPIO_LCD_POWER:
egpio |= EGPIO_H3600_LCD_ON;
gpio |= GPIO_H3100_LCD_3V_ON;
- do_blank(setp);
break;
case IPAQ_EGPIO_LCD_ENABLE:
break;
@@ -343,25 +293,6 @@ static void h3100_control_egpio(enum ipaq_egpio_type x, int setp)
}
}
-static unsigned long h3100_read_egpio(void)
-{
- return h3100_egpio;
-}
-
-static int h3100_pm_callback(int req)
-{
- if (ipaq_model_ops.pm_callback_aux)
- return ipaq_model_ops.pm_callback_aux(req);
- return 0;
-}
-
-static struct ipaq_model_ops h3100_model_ops __initdata = {
- .generic_name = "3100",
- .control = h3100_control_egpio,
- .read = h3100_read_egpio,
- .pm_callback = h3100_pm_callback
-};
-
#define H3100_DIRECT_EGPIO (GPIO_H3100_BT_ON \
| GPIO_H3100_GPIO3 \
| GPIO_H3100_QMUTE \
@@ -387,7 +318,7 @@ static void __init h3100_map_io(void)
GAFR &= ~H3100_DIRECT_EGPIO;
H3100_EGPIO = h3100_egpio;
- ipaq_model_ops = h3100_model_ops;
+ assign_h3600_egpio = h3100_control_egpio;
}
MACHINE_START(H3100, "Compaq iPAQ H3100")
@@ -420,7 +351,6 @@ static void h3600_control_egpio(enum ipaq_egpio_type x, int setp)
EGPIO_H3600_LCD_PCI |
EGPIO_H3600_LCD_5V_ON |
EGPIO_H3600_LVDD_ON;
- do_blank(setp);
break;
case IPAQ_EGPIO_LCD_ENABLE:
break;
@@ -471,25 +401,6 @@ static void h3600_control_egpio(enum ipaq_egpio_type x, int setp)
}
}
-static unsigned long h3600_read_egpio(void)
-{
- return h3600_egpio;
-}
-
-static int h3600_pm_callback(int req)
-{
- if (ipaq_model_ops.pm_callback_aux)
- return ipaq_model_ops.pm_callback_aux(req);
- return 0;
-}
-
-static struct ipaq_model_ops h3600_model_ops __initdata = {
- .generic_name = "3600",
- .control = h3600_control_egpio,
- .read = h3600_read_egpio,
- .pm_callback = h3600_pm_callback
-};
-
static void __init h3600_map_io(void)
{
h3xxx_map_io();
@@ -504,7 +415,7 @@ static void __init h3600_map_io(void)
GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8;
H3600_EGPIO = h3600_egpio; /* Maintains across sleep? */
- ipaq_model_ops = h3600_model_ops;
+ assign_h3600_egpio = h3600_control_egpio;
}
MACHINE_START(H3600, "Compaq iPAQ H3600")
@@ -519,388 +430,3 @@ MACHINE_END
#endif /* CONFIG_SA1100_H3600 */
-#ifdef CONFIG_SA1100_H3800
-
-#define SET_ASIC1(x) \
- do {if (setp) { H3800_ASIC1_GPIO_OUT |= (x); } else { H3800_ASIC1_GPIO_OUT &= ~(x); }} while(0)
-
-#define SET_ASIC2(x) \
- do {if (setp) { H3800_ASIC2_GPIOPIOD |= (x); } else { H3800_ASIC2_GPIOPIOD &= ~(x); }} while(0)
-
-#define CLEAR_ASIC1(x) \
- do {if (setp) { H3800_ASIC1_GPIO_OUT &= ~(x); } else { H3800_ASIC1_GPIO_OUT |= (x); }} while(0)
-
-#define CLEAR_ASIC2(x) \
- do {if (setp) { H3800_ASIC2_GPIOPIOD &= ~(x); } else { H3800_ASIC2_GPIOPIOD |= (x); }} while(0)
-
-
-/*
- On screen enable, we get
-
- h3800_video_power_on(1)
- LCD controller starts
- h3800_video_lcd_enable(1)
-
- On screen disable, we get
-
- h3800_video_lcd_enable(0)
- LCD controller stops
- h3800_video_power_on(0)
-*/
-
-
-static void h3800_video_power_on(int setp)
-{
- if (setp) {
- H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_ON;
- msleep(30);
- H3800_ASIC1_GPIO_OUT |= GPIO1_VGL_ON;
- msleep(5);
- H3800_ASIC1_GPIO_OUT |= GPIO1_VGH_ON;
- msleep(50);
- H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_5V_ON;
- msleep(5);
- } else {
- msleep(5);
- H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_5V_ON;
- msleep(50);
- H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGL_ON;
- msleep(5);
- H3800_ASIC1_GPIO_OUT &= ~GPIO1_VGH_ON;
- msleep(100);
- H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_ON;
- }
-}
-
-static void h3800_video_lcd_enable(int setp)
-{
- if (setp) {
- msleep(17); // Wait one from before turning on
- H3800_ASIC1_GPIO_OUT |= GPIO1_LCD_PCI;
- } else {
- H3800_ASIC1_GPIO_OUT &= ~GPIO1_LCD_PCI;
- msleep(30); // Wait before turning off
- }
-}
-
-
-static void h3800_control_egpio(enum ipaq_egpio_type x, int setp)
-{
- switch (x) {
- case IPAQ_EGPIO_LCD_POWER:
- h3800_video_power_on(setp);
- break;
- case IPAQ_EGPIO_LCD_ENABLE:
- h3800_video_lcd_enable(setp);
- break;
- case IPAQ_EGPIO_CODEC_NRESET:
- case IPAQ_EGPIO_AUDIO_ON:
- case IPAQ_EGPIO_QMUTE:
- printk("%s: error - should not be called\n", __func__);
- break;
- case IPAQ_EGPIO_OPT_NVRAM_ON:
- SET_ASIC2(GPIO2_OPT_ON_NVRAM);
- break;
- case IPAQ_EGPIO_OPT_ON:
- SET_ASIC2(GPIO2_OPT_ON);
- break;
- case IPAQ_EGPIO_CARD_RESET:
- SET_ASIC2(GPIO2_OPT_PCM_RESET);
- break;
- case IPAQ_EGPIO_OPT_RESET:
- SET_ASIC2(GPIO2_OPT_RESET);
- break;
- case IPAQ_EGPIO_IR_ON:
- CLEAR_ASIC1(GPIO1_IR_ON_N);
- break;
- case IPAQ_EGPIO_IR_FSEL:
- break;
- case IPAQ_EGPIO_RS232_ON:
- SET_ASIC1(GPIO1_RS232_ON);
- break;
- case IPAQ_EGPIO_VPP_ON:
- H3800_ASIC2_FlashWP_VPP_ON = setp;
- break;
- }
-}
-
-static unsigned long h3800_read_egpio(void)
-{
- return H3800_ASIC1_GPIO_OUT | (H3800_ASIC2_GPIOPIOD << 16);
-}
-
-/* We need to fix ASIC2 GPIO over suspend/resume. At the moment,
- it doesn't appear that ASIC1 GPIO has the same problem */
-
-static int h3800_pm_callback(int req)
-{
- static u16 asic1_data;
- static u16 asic2_data;
- int result = 0;
-
- printk("%s %d\n", __func__, req);
-
- switch (req) {
- case PM_RESUME:
- MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000; /* Set MSC2 correctly */
-
- H3800_ASIC2_GPIOPIOD = asic2_data;
- H3800_ASIC2_GPIODIR = GPIO2_PEN_IRQ
- | GPIO2_SD_DETECT
- | GPIO2_EAR_IN_N
- | GPIO2_USB_DETECT_N
- | GPIO2_SD_CON_SLT;
-
- H3800_ASIC1_GPIO_OUT = asic1_data;
-
- if (ipaq_model_ops.pm_callback_aux)
- result = ipaq_model_ops.pm_callback_aux(req);
- break;
-
- case PM_SUSPEND:
- if (ipaq_model_ops.pm_callback_aux &&
- ((result = ipaq_model_ops.pm_callback_aux(req)) != 0))
- return result;
-
- asic1_data = H3800_ASIC1_GPIO_OUT;
- asic2_data = H3800_ASIC2_GPIOPIOD;
- break;
- default:
- printk("%s: unrecognized PM callback\n", __func__);
- break;
- }
- return result;
-}
-
-static struct ipaq_model_ops h3800_model_ops __initdata = {
- .generic_name = "3800",
- .control = h3800_control_egpio,
- .read = h3800_read_egpio,
- .pm_callback = h3800_pm_callback
-};
-
-#define MAX_ASIC_ISR_LOOPS 20
-
-/* The order of these is important - see #include <mach/irqs.h> */
-static u32 kpio_irq_mask[] = {
- KPIO_KEY_ALL,
- KPIO_SPI_INT,
- KPIO_OWM_INT,
- KPIO_ADC_INT,
- KPIO_UART_0_INT,
- KPIO_UART_1_INT,
- KPIO_TIMER_0_INT,
- KPIO_TIMER_1_INT,
- KPIO_TIMER_2_INT
-};
-
-static u32 gpio_irq_mask[] = {
- GPIO2_PEN_IRQ,
- GPIO2_SD_DETECT,
- GPIO2_EAR_IN_N,
- GPIO2_USB_DETECT_N,
- GPIO2_SD_CON_SLT,
-};
-
-static void h3800_IRQ_demux(unsigned int irq, struct irq_desc *desc)
-{
- int i;
-
- if (0) printk("%s: interrupt received\n", __func__);
-
- desc->chip->ack(irq);
-
- for (i = 0; i < MAX_ASIC_ISR_LOOPS && (GPLR & GPIO_H3800_ASIC); i++) {
- u32 irq;
- int j;
-
- /* KPIO */
- irq = H3800_ASIC2_KPIINTFLAG;
- if (0) printk("%s KPIO 0x%08X\n", __func__, irq);
- for (j = 0; j < H3800_KPIO_IRQ_COUNT; j++)
- if (irq & kpio_irq_mask[j])
- handle_edge_irq(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j);
-
- /* GPIO2 */
- irq = H3800_ASIC2_GPIINTFLAG;
- if (0) printk("%s GPIO 0x%08X\n", __func__, irq);
- for (j = 0; j < H3800_GPIO_IRQ_COUNT; j++)
- if (irq & gpio_irq_mask[j])
- handle_edge_irq(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j);
- }
-
- if (i >= MAX_ASIC_ISR_LOOPS)
- printk("%s: interrupt processing overrun\n", __func__);
-
- /* For level-based interrupts */
- desc->chip->unmask(irq);
-
-}
-
-static struct irqaction h3800_irq = {
- .name = "h3800_asic",
- .handler = h3800_IRQ_demux,
- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-};
-
-u32 kpio_int_shadow = 0;
-
-
-/* mask_ack <- IRQ is first serviced.
- mask <- IRQ is disabled.
- unmask <- IRQ is enabled
-
- The INTCLR registers are poorly documented. I believe that writing
- a "1" to the register clears the specific interrupt, but the documentation
- indicates writing a "0" clears the interrupt. In any case, they shouldn't
- be read (that's the INTFLAG register)
- */
-
-static void h3800_mask_ack_kpio_irq(unsigned int irq)
-{
- u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
- kpio_int_shadow &= ~mask;
- H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
- H3800_ASIC2_KPIINTCLR = mask;
-}
-
-static void h3800_mask_kpio_irq(unsigned int irq)
-{
- u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
- kpio_int_shadow &= ~mask;
- H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
-}
-
-static void h3800_unmask_kpio_irq(unsigned int irq)
-{
- u32 mask = kpio_irq_mask[irq - H3800_KPIO_IRQ_START];
- kpio_int_shadow |= mask;
- H3800_ASIC2_KPIINTSTAT = kpio_int_shadow;
-}
-
-static void h3800_mask_ack_gpio_irq(unsigned int irq)
-{
- u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
- H3800_ASIC2_GPIINTSTAT &= ~mask;
- H3800_ASIC2_GPIINTCLR = mask;
-}
-
-static void h3800_mask_gpio_irq(unsigned int irq)
-{
- u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
- H3800_ASIC2_GPIINTSTAT &= ~mask;
- }
-
-static void h3800_unmask_gpio_irq(unsigned int irq)
-{
- u32 mask = gpio_irq_mask[irq - H3800_GPIO_IRQ_START];
- H3800_ASIC2_GPIINTSTAT |= mask;
-}
-
-static void __init h3800_init_irq(void)
-{
- int i;
-
- /* Initialize standard IRQs */
- sa1100_init_irq();
-
- /* Disable all IRQs and set up clock */
- H3800_ASIC2_KPIINTSTAT = 0; /* Disable all interrupts */
- H3800_ASIC2_GPIINTSTAT = 0;
-
- H3800_ASIC2_KPIINTCLR = 0; /* Clear all KPIO interrupts */
- H3800_ASIC2_GPIINTCLR = 0; /* Clear all GPIO interrupts */
-
-// H3800_ASIC2_KPIINTCLR = 0xffff; /* Clear all KPIO interrupts */
-// H3800_ASIC2_GPIINTCLR = 0xffff; /* Clear all GPIO interrupts */
-
- H3800_ASIC2_CLOCK_Enable |= ASIC2_CLOCK_EX0; /* 32 kHZ crystal on */
- H3800_ASIC2_INTR_ClockPrescale |= ASIC2_INTCPS_SET;
- H3800_ASIC2_INTR_ClockPrescale = ASIC2_INTCPS_CPS(0x0e) | ASIC2_INTCPS_SET;
- H3800_ASIC2_INTR_TimerSet = 1;
-
-#if 0
- for (i = 0; i < H3800_KPIO_IRQ_COUNT; i++) {
- int irq = i + H3800_KPIO_IRQ_START;
- irq_desc[irq].valid = 1;
- irq_desc[irq].probe_ok = 1;
- set_irq_chip(irq, &h3800_kpio_irqchip);
- }
-
- for (i = 0; i < H3800_GPIO_IRQ_COUNT; i++) {
- int irq = i + H3800_GPIO_IRQ_START;
- irq_desc[irq].valid = 1;
- irq_desc[irq].probe_ok = 1;
- set_irq_chip(irq, &h3800_gpio_irqchip);
- }
-#endif
- set_irq_type(IRQ_GPIO_H3800_ASIC, IRQ_TYPE_EDGE_RISING);
- set_irq_chained_handler(IRQ_GPIO_H3800_ASIC, h3800_IRQ_demux);
-}
-
-
-#define ASIC1_OUTPUTS 0x7fff /* First 15 bits are used */
-
-static void __init h3800_map_io(void)
-{
- h3xxx_map_io();
-
- /* Add wakeup on AC plug/unplug */
- PWER |= PWER_GPIO12;
-
- /* Initialize h3800-specific values here */
- GPCR = 0x0fffffff; /* All outputs are set low by default */
- GAFR = GPIO_H3800_CLK_OUT |
- GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
- GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8;
- GPDR = GPIO_H3800_CLK_OUT |
- GPIO_H3600_COM_RTS | GPIO_H3600_L3_CLOCK |
- GPIO_H3600_L3_MODE | GPIO_H3600_L3_DATA |
- GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
- GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8;
- TUCR = TUCR_3_6864MHz; /* Seems to be used only for the Bluetooth UART */
-
- /* Fix the memory bus */
- MSC2 = (MSC2 & 0x0000ffff) | 0xE4510000;
-
- /* Set up ASIC #1 */
- H3800_ASIC1_GPIO_DIR = ASIC1_OUTPUTS; /* All outputs */
- H3800_ASIC1_GPIO_MASK = ASIC1_OUTPUTS; /* No interrupts */
- H3800_ASIC1_GPIO_SLEEP_MASK = ASIC1_OUTPUTS;
- H3800_ASIC1_GPIO_SLEEP_DIR = ASIC1_OUTPUTS;
- H3800_ASIC1_GPIO_SLEEP_OUT = GPIO1_EAR_ON_N;
- H3800_ASIC1_GPIO_BATT_FAULT_DIR = ASIC1_OUTPUTS;
- H3800_ASIC1_GPIO_BATT_FAULT_OUT = GPIO1_EAR_ON_N;
-
- H3800_ASIC1_GPIO_OUT = GPIO1_IR_ON_N
- | GPIO1_RS232_ON
- | GPIO1_EAR_ON_N;
-
- /* Set up ASIC #2 */
- H3800_ASIC2_GPIOPIOD = GPIO2_IN_Y1_N | GPIO2_IN_X1_N;
- H3800_ASIC2_GPOBFSTAT = GPIO2_IN_Y1_N | GPIO2_IN_X1_N;
-
- H3800_ASIC2_GPIODIR = GPIO2_PEN_IRQ
- | GPIO2_SD_DETECT
- | GPIO2_EAR_IN_N
- | GPIO2_USB_DETECT_N
- | GPIO2_SD_CON_SLT;
-
- /* TODO : Set sleep states & battery fault states */
-
- /* Clear VPP Enable */
- H3800_ASIC2_FlashWP_VPP_ON = 0;
- ipaq_model_ops = h3800_model_ops;
-}
-
-MACHINE_START(H3800, "Compaq iPAQ H3800")
- .phys_io = 0x80000000,
- .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
- .boot_params = 0xc0000100,
- .map_io = h3800_map_io,
- .init_irq = h3800_init_irq,
- .timer = &sa1100_timer,
- .init_machine = h3xxx_mach_init,
-MACHINE_END
-
-#endif /* CONFIG_SA1100_H3800 */
diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h
index 69e962416e3f..9efb569cdb60 100644
--- a/arch/arm/mach-sa1100/include/mach/collie.h
+++ b/arch/arm/mach-sa1100/include/mach/collie.h
@@ -14,21 +14,21 @@
#define __ASM_ARCH_COLLIE_H
-#define COLLIE_SCP_CHARGE_ON SCOOP_GPCR_PA11
+#define COLLIE_SCOOP_GPIO_BASE (GPIO_MAX + 1)
+#define COLLIE_GPIO_CHARGE_ON (COLLIE_SCOOP_GPIO_BASE + 0)
#define COLLIE_SCP_DIAG_BOOT1 SCOOP_GPCR_PA12
#define COLLIE_SCP_DIAG_BOOT2 SCOOP_GPCR_PA13
#define COLLIE_SCP_MUTE_L SCOOP_GPCR_PA14
#define COLLIE_SCP_MUTE_R SCOOP_GPCR_PA15
#define COLLIE_SCP_5VON SCOOP_GPCR_PA16
#define COLLIE_SCP_AMP_ON SCOOP_GPCR_PA17
-#define COLLIE_SCP_VPEN SCOOP_GPCR_PA18
+#define COLLIE_GPIO_VPEN (COLLIE_SCOOP_GPIO_BASE + 7)
#define COLLIE_SCP_LB_VOL_CHG SCOOP_GPCR_PA19
-#define COLLIE_SCOOP_IO_DIR ( COLLIE_SCP_CHARGE_ON | COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
- COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | COLLIE_SCP_VPEN | \
+#define COLLIE_SCOOP_IO_DIR ( COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
+ COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | \
COLLIE_SCP_LB_VOL_CHG )
-#define COLLIE_SCOOP_IO_OUT ( COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | COLLIE_SCP_VPEN | \
- COLLIE_SCP_CHARGE_ON )
+#define COLLIE_SCOOP_IO_OUT ( COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R )
/* GPIOs for which the generic definition doesn't say much */
diff --git a/arch/arm/mach-sa1100/include/mach/h3600.h b/arch/arm/mach-sa1100/include/mach/h3600.h
index 9cc47fddb335..2827faa47421 100644
--- a/arch/arm/mach-sa1100/include/mach/h3600.h
+++ b/arch/arm/mach-sa1100/include/mach/h3600.h
@@ -29,7 +29,7 @@ typedef int __bitwise pm_request_t;
#define PM_RESUME ((__force pm_request_t) 2) /* enter D0 */
/* generalized support for H3xxx series Compaq Pocket PC's */
-#define machine_is_h3xxx() (machine_is_h3100() || machine_is_h3600() || machine_is_h3800())
+#define machine_is_h3xxx() (machine_is_h3100() || machine_is_h3600())
/* Physical memory regions corresponding to chip selects */
#define H3600_EGPIO_PHYS (SA1100_CS5_PHYS + 0x01000000)
@@ -93,76 +93,7 @@ enum ipaq_egpio_type {
IPAQ_EGPIO_LCD_ENABLE, /* Enable/disable LCD controller */
};
-struct ipaq_model_ops {
- const char *generic_name;
- void (*control)(enum ipaq_egpio_type, int);
- unsigned long (*read)(void);
- void (*blank_callback)(int blank);
- int (*pm_callback)(int req); /* Primary model callback */
- int (*pm_callback_aux)(int req); /* Secondary callback (used by HAL modules) */
-};
-
-extern struct ipaq_model_ops ipaq_model_ops;
-
-static __inline__ const char * h3600_generic_name(void)
-{
- return ipaq_model_ops.generic_name;
-}
-
-static __inline__ void assign_h3600_egpio(enum ipaq_egpio_type x, int level)
-{
- if (ipaq_model_ops.control)
- ipaq_model_ops.control(x,level);
-}
-
-static __inline__ void clr_h3600_egpio(enum ipaq_egpio_type x)
-{
- if (ipaq_model_ops.control)
- ipaq_model_ops.control(x,0);
-}
-
-static __inline__ void set_h3600_egpio(enum ipaq_egpio_type x)
-{
- if (ipaq_model_ops.control)
- ipaq_model_ops.control(x,1);
-}
-
-static __inline__ unsigned long read_h3600_egpio(void)
-{
- if (ipaq_model_ops.read)
- return ipaq_model_ops.read();
- return 0;
-}
-
-static __inline__ int h3600_register_blank_callback(void (*f)(int))
-{
- ipaq_model_ops.blank_callback = f;
- return 0;
-}
-
-static __inline__ void h3600_unregister_blank_callback(void (*f)(int))
-{
- ipaq_model_ops.blank_callback = NULL;
-}
-
-
-static __inline__ int h3600_register_pm_callback(int (*f)(int))
-{
- ipaq_model_ops.pm_callback_aux = f;
- return 0;
-}
-
-static __inline__ void h3600_unregister_pm_callback(int (*f)(int))
-{
- ipaq_model_ops.pm_callback_aux = NULL;
-}
-
-static __inline__ int h3600_power_management(int req)
-{
- if (ipaq_model_ops.pm_callback)
- return ipaq_model_ops.pm_callback(req);
- return 0;
-}
+extern void (*assign_h3600_egpio)(enum ipaq_egpio_type x, int level);
#endif /* ASSEMBLY */
diff --git a/arch/arm/mach-sa1100/include/mach/h3600_gpio.h b/arch/arm/mach-sa1100/include/mach/h3600_gpio.h
index 62b0b7879685..a36ca76d018b 100644
--- a/arch/arm/mach-sa1100/include/mach/h3600_gpio.h
+++ b/arch/arm/mach-sa1100/include/mach/h3600_gpio.h
@@ -48,22 +48,11 @@
#define GPIO_H3600_OPT_LOCK GPIO_GPIO (22)
#define GPIO_H3600_OPT_DET GPIO_GPIO (27)
-/* H3800 specific pins */
-#define GPIO_H3800_AC_IN GPIO_GPIO (12)
-#define GPIO_H3800_COM_DSR GPIO_GPIO (13)
-#define GPIO_H3800_MMC_INT GPIO_GPIO (18)
-#define GPIO_H3800_NOPT_IND GPIO_GPIO (20) /* Almost exactly the same as GPIO_H3600_OPT_DET */
-#define GPIO_H3800_OPT_BAT_FAULT GPIO_GPIO (22)
-#define GPIO_H3800_CLK_OUT GPIO_GPIO (27)
-
/****************************************************/
#define IRQ_GPIO_H3600_ACTION_BUTTON IRQ_GPIO18
#define IRQ_GPIO_H3600_OPT_DET IRQ_GPIO27
-#define IRQ_GPIO_H3800_MMC_INT IRQ_GPIO18
-#define IRQ_GPIO_H3800_NOPT_IND IRQ_GPIO20 /* almost same as OPT_DET */
-
/* H3100 / 3600 EGPIO pins */
#define EGPIO_H3600_VPP_ON (1 << 0)
#define EGPIO_H3600_CARD_RESET (1 << 1) /* reset the attached pcmcia/compactflash card. active high. */
@@ -84,457 +73,5 @@
#define EGPIO_H3600_LCD_5V_ON (1 << 14) /* enable 5V to LCD. active high. */
#define EGPIO_H3600_LVDD_ON (1 << 15) /* enable 9V and -6.5V to LCD. */
-/********************* H3800, ASIC #2 ********************/
-
-#define _H3800_ASIC2_Base (H3600_EGPIO_VIRT)
-#define H3800_ASIC2_OFFSET(s,x,y) \
- (*((volatile s *) (_H3800_ASIC2_Base + _H3800_ASIC2_ ## x ## _Base + _H3800_ASIC2_ ## x ## _ ## y)))
-#define H3800_ASIC2_NOFFSET(s,x,n,y) \
- (*((volatile s *) (_H3800_ASIC2_Base + _H3800_ASIC2_ ## x ## _ ## n ## _Base + _H3800_ASIC2_ ## x ## _ ## y)))
-
-#define _H3800_ASIC2_GPIO_Base 0x0000
-#define _H3800_ASIC2_GPIO_Direction 0x0000 /* R/W, 16 bits 1:input, 0:output */
-#define _H3800_ASIC2_GPIO_InterruptType 0x0004 /* R/W, 12 bits 1:edge, 0:level */
-#define _H3800_ASIC2_GPIO_InterruptEdgeType 0x0008 /* R/W, 12 bits 1:rising, 0:falling */
-#define _H3800_ASIC2_GPIO_InterruptLevelType 0x000C /* R/W, 12 bits 1:high, 0:low */
-#define _H3800_ASIC2_GPIO_InterruptClear 0x0010 /* W, 12 bits */
-#define _H3800_ASIC2_GPIO_InterruptFlag 0x0010 /* R, 12 bits - reads int status */
-#define _H3800_ASIC2_GPIO_Data 0x0014 /* R/W, 16 bits */
-#define _H3800_ASIC2_GPIO_BattFaultOut 0x0018 /* R/W, 16 bit - sets level on batt fault */
-#define _H3800_ASIC2_GPIO_InterruptEnable 0x001c /* R/W, 12 bits 1:enable interrupt */
-#define _H3800_ASIC2_GPIO_Alternate 0x003c /* R/W, 12+1 bits - set alternate functions */
-
-#define H3800_ASIC2_GPIO_Direction H3800_ASIC2_OFFSET( u16, GPIO, Direction )
-#define H3800_ASIC2_GPIO_InterruptType H3800_ASIC2_OFFSET( u16, GPIO, InterruptType )
-#define H3800_ASIC2_GPIO_InterruptEdgeType H3800_ASIC2_OFFSET( u16, GPIO, InterruptEdgeType )
-#define H3800_ASIC2_GPIO_InterruptLevelType H3800_ASIC2_OFFSET( u16, GPIO, InterruptLevelType )
-#define H3800_ASIC2_GPIO_InterruptClear H3800_ASIC2_OFFSET( u16, GPIO, InterruptClear )
-#define H3800_ASIC2_GPIO_InterruptFlag H3800_ASIC2_OFFSET( u16, GPIO, InterruptFlag )
-#define H3800_ASIC2_GPIO_Data H3800_ASIC2_OFFSET( u16, GPIO, Data )
-#define H3800_ASIC2_GPIO_BattFaultOut H3800_ASIC2_OFFSET( u16, GPIO, BattFaultOut )
-#define H3800_ASIC2_GPIO_InterruptEnable H3800_ASIC2_OFFSET( u16, GPIO, InterruptEnable )
-#define H3800_ASIC2_GPIO_Alternate H3800_ASIC2_OFFSET( u16, GPIO, Alternate )
-
-#define GPIO_H3800_ASIC2_IN_Y1_N (1 << 0) /* Output: Touchscreen Y1 */
-#define GPIO_H3800_ASIC2_IN_X0 (1 << 1) /* Output: Touchscreen X0 */
-#define GPIO_H3800_ASIC2_IN_Y0 (1 << 2) /* Output: Touchscreen Y0 */
-#define GPIO_H3800_ASIC2_IN_X1_N (1 << 3) /* Output: Touchscreen X1 */
-#define GPIO_H3800_ASIC2_BT_RST (1 << 4) /* Output: Bluetooth reset */
-#define GPIO_H3800_ASIC2_PEN_IRQ (1 << 5) /* Input : Pen down */
-#define GPIO_H3800_ASIC2_SD_DETECT (1 << 6) /* Input : SD detect */
-#define GPIO_H3800_ASIC2_EAR_IN_N (1 << 7) /* Input : Audio jack plug inserted */
-#define GPIO_H3800_ASIC2_OPT_PCM_RESET (1 << 8) /* Output: */
-#define GPIO_H3800_ASIC2_OPT_RESET (1 << 9) /* Output: */
-#define GPIO_H3800_ASIC2_USB_DETECT_N (1 << 10) /* Input : */
-#define GPIO_H3800_ASIC2_SD_CON_SLT (1 << 11) /* Input : */
-
-#define _H3800_ASIC2_KPIO_Base 0x0200
-#define _H3800_ASIC2_KPIO_Direction 0x0000 /* R/W, 12 bits 1:input, 0:output */
-#define _H3800_ASIC2_KPIO_InterruptType 0x0004 /* R/W, 12 bits 1:edge, 0:level */
-#define _H3800_ASIC2_KPIO_InterruptEdgeType 0x0008 /* R/W, 12 bits 1:rising, 0:falling */
-#define _H3800_ASIC2_KPIO_InterruptLevelType 0x000C /* R/W, 12 bits 1:high, 0:low */
-#define _H3800_ASIC2_KPIO_InterruptClear 0x0010 /* W, 20 bits - 8 special */
-#define _H3800_ASIC2_KPIO_InterruptFlag 0x0010 /* R, 20 bits - 8 special - reads int status */
-#define _H3800_ASIC2_KPIO_Data 0x0014 /* R/W, 16 bits */
-#define _H3800_ASIC2_KPIO_BattFaultOut 0x0018 /* R/W, 16 bit - sets level on batt fault */
-#define _H3800_ASIC2_KPIO_InterruptEnable 0x001c /* R/W, 20 bits - 8 special */
-#define _H3800_ASIC2_KPIO_Alternate 0x003c /* R/W, 6 bits */
-
-#define H3800_ASIC2_KPIO_Direction H3800_ASIC2_OFFSET( u16, KPIO, Direction )
-#define H3800_ASIC2_KPIO_InterruptType H3800_ASIC2_OFFSET( u16, KPIO, InterruptType )
-#define H3800_ASIC2_KPIO_InterruptEdgeType H3800_ASIC2_OFFSET( u16, KPIO, InterruptEdgeType )
-#define H3800_ASIC2_KPIO_InterruptLevelType H3800_ASIC2_OFFSET( u16, KPIO, InterruptLevelType )
-#define H3800_ASIC2_KPIO_InterruptClear H3800_ASIC2_OFFSET( u32, KPIO, InterruptClear )
-#define H3800_ASIC2_KPIO_InterruptFlag H3800_ASIC2_OFFSET( u32, KPIO, InterruptFlag )
-#define H3800_ASIC2_KPIO_Data H3800_ASIC2_OFFSET( u16, KPIO, Data )
-#define H3800_ASIC2_KPIO_BattFaultOut H3800_ASIC2_OFFSET( u16, KPIO, BattFaultOut )
-#define H3800_ASIC2_KPIO_InterruptEnable H3800_ASIC2_OFFSET( u32, KPIO, InterruptEnable )
-#define H3800_ASIC2_KPIO_Alternate H3800_ASIC2_OFFSET( u16, KPIO, Alternate )
-
-#define H3800_ASIC2_KPIO_SPI_INT ( 1 << 16 )
-#define H3800_ASIC2_KPIO_OWM_INT ( 1 << 17 )
-#define H3800_ASIC2_KPIO_ADC_INT ( 1 << 18 )
-#define H3800_ASIC2_KPIO_UART_0_INT ( 1 << 19 )
-#define H3800_ASIC2_KPIO_UART_1_INT ( 1 << 20 )
-#define H3800_ASIC2_KPIO_TIMER_0_INT ( 1 << 21 )
-#define H3800_ASIC2_KPIO_TIMER_1_INT ( 1 << 22 )
-#define H3800_ASIC2_KPIO_TIMER_2_INT ( 1 << 23 )
-
-#define KPIO_H3800_ASIC2_RECORD_BTN_N (1 << 0) /* Record button */
-#define KPIO_H3800_ASIC2_KEY_5W1_N (1 << 1) /* Keypad */
-#define KPIO_H3800_ASIC2_KEY_5W2_N (1 << 2) /* */
-#define KPIO_H3800_ASIC2_KEY_5W3_N (1 << 3) /* */
-#define KPIO_H3800_ASIC2_KEY_5W4_N (1 << 4) /* */
-#define KPIO_H3800_ASIC2_KEY_5W5_N (1 << 5) /* */
-#define KPIO_H3800_ASIC2_KEY_LEFT_N (1 << 6) /* */
-#define KPIO_H3800_ASIC2_KEY_RIGHT_N (1 << 7) /* */
-#define KPIO_H3800_ASIC2_KEY_AP1_N (1 << 8) /* Old "Calendar" */
-#define KPIO_H3800_ASIC2_KEY_AP2_N (1 << 9) /* Old "Schedule" */
-#define KPIO_H3800_ASIC2_KEY_AP3_N (1 << 10) /* Old "Q" */
-#define KPIO_H3800_ASIC2_KEY_AP4_N (1 << 11) /* Old "Undo" */
-
-/* Alternate KPIO functions (set by default) */
-#define KPIO_ALT_H3800_ASIC2_KEY_5W1_N (1 << 1) /* Action key */
-#define KPIO_ALT_H3800_ASIC2_KEY_5W2_N (1 << 2) /* J1 of keypad input */
-#define KPIO_ALT_H3800_ASIC2_KEY_5W3_N (1 << 3) /* J2 of keypad input */
-#define KPIO_ALT_H3800_ASIC2_KEY_5W4_N (1 << 4) /* J3 of keypad input */
-#define KPIO_ALT_H3800_ASIC2_KEY_5W5_N (1 << 5) /* J4 of keypad input */
-
-#define _H3800_ASIC2_SPI_Base 0x0400
-#define _H3800_ASIC2_SPI_Control 0x0000 /* R/W 8 bits */
-#define _H3800_ASIC2_SPI_Data 0x0004 /* R/W 8 bits */
-#define _H3800_ASIC2_SPI_ChipSelectDisabled 0x0008 /* W 8 bits */
-
-#define H3800_ASIC2_SPI_Control H3800_ASIC2_OFFSET( u8, SPI, Control )
-#define H3800_ASIC2_SPI_Data H3800_ASIC2_OFFSET( u8, SPI, Data )
-#define H3800_ASIC2_SPI_ChipSelectDisabled H3800_ASIC2_OFFSET( u8, SPI, ChipSelectDisabled )
-
-#define _H3800_ASIC2_PWM_0_Base 0x0600
-#define _H3800_ASIC2_PWM_1_Base 0x0700
-#define _H3800_ASIC2_PWM_TimeBase 0x0000 /* R/W 6 bits */
-#define _H3800_ASIC2_PWM_PeriodTime 0x0004 /* R/W 12 bits */
-#define _H3800_ASIC2_PWM_DutyTime 0x0008 /* R/W 12 bits */
-
-#define H3800_ASIC2_PWM_0_TimeBase H3800_ASIC2_NOFFSET( u8, PWM, 0, TimeBase )
-#define H3800_ASIC2_PWM_0_PeriodTime H3800_ASIC2_NOFFSET( u16, PWM, 0, PeriodTime )
-#define H3800_ASIC2_PWM_0_DutyTime H3800_ASIC2_NOFFSET( u16, PWM, 0, DutyTime )
-
-#define H3800_ASIC2_PWM_1_TimeBase H3800_ASIC2_NOFFSET( u8, PWM, 1, TimeBase )
-#define H3800_ASIC2_PWM_1_PeriodTime H3800_ASIC2_NOFFSET( u16, PWM, 1, PeriodTime )
-#define H3800_ASIC2_PWM_1_DutyTime H3800_ASIC2_NOFFSET( u16, PWM, 1, DutyTime )
-
-#define H3800_ASIC2_PWM_TIMEBASE_MASK 0xf /* Low 4 bits sets time base, max = 8 */
-#define H3800_ASIC2_PWM_TIMEBASE_ENABLE ( 1 << 4 ) /* Enable clock */
-#define H3800_ASIC2_PWM_TIMEBASE_CLEAR ( 1 << 5 ) /* Clear the PWM */
-
-#define _H3800_ASIC2_LED_0_Base 0x0800
-#define _H3800_ASIC2_LED_1_Base 0x0880
-#define _H3800_ASIC2_LED_2_Base 0x0900
-#define _H3800_ASIC2_LED_TimeBase 0x0000 /* R/W 7 bits */
-#define _H3800_ASIC2_LED_PeriodTime 0x0004 /* R/W 12 bits */
-#define _H3800_ASIC2_LED_DutyTime 0x0008 /* R/W 12 bits */
-#define _H3800_ASIC2_LED_AutoStopCount 0x000c /* R/W 16 bits */
-
-#define H3800_ASIC2_LED_0_TimeBase H3800_ASIC2_NOFFSET( u8, LED, 0, TimeBase )
-#define H3800_ASIC2_LED_0_PeriodTime H3800_ASIC2_NOFFSET( u16, LED, 0, PeriodTime )
-#define H3800_ASIC2_LED_0_DutyTime H3800_ASIC2_NOFFSET( u16, LED, 0, DutyTime )
-#define H3800_ASIC2_LED_0_AutoStopClock H3800_ASIC2_NOFFSET( u16, LED, 0, AutoStopClock )
-
-#define H3800_ASIC2_LED_1_TimeBase H3800_ASIC2_NOFFSET( u8, LED, 1, TimeBase )
-#define H3800_ASIC2_LED_1_PeriodTime H3800_ASIC2_NOFFSET( u16, LED, 1, PeriodTime )
-#define H3800_ASIC2_LED_1_DutyTime H3800_ASIC2_NOFFSET( u16, LED, 1, DutyTime )
-#define H3800_ASIC2_LED_1_AutoStopClock H3800_ASIC2_NOFFSET( u16, LED, 1, AutoStopClock )
-
-#define H3800_ASIC2_LED_2_TimeBase H3800_ASIC2_NOFFSET( u8, LED, 2, TimeBase )
-#define H3800_ASIC2_LED_2_PeriodTime H3800_ASIC2_NOFFSET( u16, LED, 2, PeriodTime )
-#define H3800_ASIC2_LED_2_DutyTime H3800_ASIC2_NOFFSET( u16, LED, 2, DutyTime )
-#define H3800_ASIC2_LED_2_AutoStopClock H3800_ASIC2_NOFFSET( u16, LED, 2, AutoStopClock )
-
-#define H3800_ASIC2_LED_TIMEBASE_MASK 0x0f /* Low 4 bits sets time base, max = 13 */
-#define H3800_ASIC2_LED_TIMEBASE_BLINK ( 1 << 4 ) /* Enable blinking */
-#define H3800_ASIC2_LED_TIMEBASE_AUTOSTOP ( 1 << 5 )
-#define H3800_ASIC2_LED_TIMEBASE_ALWAYS ( 1 << 6 ) /* Enable blink always */
-
-#define _H3800_ASIC2_UART_0_Base 0x0A00
-#define _H3800_ASIC2_UART_1_Base 0x0C00
-#define _H3800_ASIC2_UART_Receive 0x0000 /* R 8 bits */
-#define _H3800_ASIC2_UART_Transmit 0x0000 /* W 8 bits */
-#define _H3800_ASIC2_UART_IntEnable 0x0004 /* R/W 8 bits */
-#define _H3800_ASIC2_UART_IntVerify 0x0008 /* R/W 8 bits */
-#define _H3800_ASIC2_UART_FIFOControl 0x000c /* R/W 8 bits */
-#define _H3800_ASIC2_UART_LineControl 0x0010 /* R/W 8 bits */
-#define _H3800_ASIC2_UART_ModemStatus 0x0014 /* R/W 8 bits */
-#define _H3800_ASIC2_UART_LineStatus 0x0018 /* R/W 8 bits */
-#define _H3800_ASIC2_UART_ScratchPad 0x001c /* R/W 8 bits */
-#define _H3800_ASIC2_UART_DivisorLatchL 0x0020 /* R/W 8 bits */
-#define _H3800_ASIC2_UART_DivisorLatchH 0x0024 /* R/W 8 bits */
-
-#define H3800_ASIC2_UART_0_Receive H3800_ASIC2_NOFFSET( u8, UART, 0, Receive )
-#define H3800_ASIC2_UART_0_Transmit H3800_ASIC2_NOFFSET( u8, UART, 0, Transmit )
-#define H3800_ASIC2_UART_0_IntEnable H3800_ASIC2_NOFFSET( u8, UART, 0, IntEnable )
-#define H3800_ASIC2_UART_0_IntVerify H3800_ASIC2_NOFFSET( u8, UART, 0, IntVerify )
-#define H3800_ASIC2_UART_0_FIFOControl H3800_ASIC2_NOFFSET( u8, UART, 0, FIFOControl )
-#define H3800_ASIC2_UART_0_LineControl H3800_ASIC2_NOFFSET( u8, UART, 0, LineControl )
-#define H3800_ASIC2_UART_0_ModemStatus H3800_ASIC2_NOFFSET( u8, UART, 0, ModemStatus )
-#define H3800_ASIC2_UART_0_LineStatus H3800_ASIC2_NOFFSET( u8, UART, 0, LineStatus )
-#define H3800_ASIC2_UART_0_ScratchPad H3800_ASIC2_NOFFSET( u8, UART, 0, ScratchPad )
-#define H3800_ASIC2_UART_0_DivisorLatchL H3800_ASIC2_NOFFSET( u8, UART, 0, DivisorLatchL )
-#define H3800_ASIC2_UART_0_DivisorLatchH H3800_ASIC2_NOFFSET( u8, UART, 0, DivisorLatchH )
-
-#define H3800_ASIC2_UART_1_Receive H3800_ASIC2_NOFFSET( u8, UART, 1, Receive )
-#define H3800_ASIC2_UART_1_Transmit H3800_ASIC2_NOFFSET( u8, UART, 1, Transmit )
-#define H3800_ASIC2_UART_1_IntEnable H3800_ASIC2_NOFFSET( u8, UART, 1, IntEnable )
-#define H3800_ASIC2_UART_1_IntVerify H3800_ASIC2_NOFFSET( u8, UART, 1, IntVerify )
-#define H3800_ASIC2_UART_1_FIFOControl H3800_ASIC2_NOFFSET( u8, UART, 1, FIFOControl )
-#define H3800_ASIC2_UART_1_LineControl H3800_ASIC2_NOFFSET( u8, UART, 1, LineControl )
-#define H3800_ASIC2_UART_1_ModemStatus H3800_ASIC2_NOFFSET( u8, UART, 1, ModemStatus )
-#define H3800_ASIC2_UART_1_LineStatus H3800_ASIC2_NOFFSET( u8, UART, 1, LineStatus )
-#define H3800_ASIC2_UART_1_ScratchPad H3800_ASIC2_NOFFSET( u8, UART, 1, ScratchPad )
-#define H3800_ASIC2_UART_1_DivisorLatchL H3800_ASIC2_NOFFSET( u8, UART, 1, DivisorLatchL )
-#define H3800_ASIC2_UART_1_DivisorLatchH H3800_ASIC2_NOFFSET( u8, UART, 1, DivisorLatchH )
-
-#define _H3800_ASIC2_TIMER_Base 0x0E00
-#define _H3800_ASIC2_TIMER_Command 0x0000 /* R/W 8 bits */
-
-#define H3800_ASIC2_TIMER_Command H3800_ASIC2_OFFSET( u8, Timer, Command )
-
-#define H3800_ASIC2_TIMER_GAT_0 ( 1 << 0 ) /* Gate enable, counter 0 */
-#define H3800_ASIC2_TIMER_GAT_1 ( 1 << 1 ) /* Gate enable, counter 1 */
-#define H3800_ASIC2_TIMER_GAT_2 ( 1 << 2 ) /* Gate enable, counter 2 */
-#define H3800_ASIC2_TIMER_CLK_0 ( 1 << 3 ) /* Clock enable, counter 0 */
-#define H3800_ASIC2_TIMER_CLK_1 ( 1 << 4 ) /* Clock enable, counter 1 */
-#define H3800_ASIC2_TIMER_CLK_2 ( 1 << 5 ) /* Clock enable, counter 2 */
-#define H3800_ASIC2_TIMER_MODE_0 ( 1 << 6 ) /* Mode 0 enable, counter 0 */
-#define H3800_ASIC2_TIMER_MODE_1 ( 1 << 7 ) /* Mode 0 enable, counter 1 */
-
-#define _H3800_ASIC2_CLOCK_Base 0x1000
-#define _H3800_ASIC2_CLOCK_Enable 0x0000 /* R/W 18 bits */
-
-#define H3800_ASIC2_CLOCK_Enable H3800_ASIC2_OFFSET( u32, CLOCK, Enable )
-
-#define H3800_ASIC2_CLOCK_AUDIO_1 0x0001 /* Enable 4.1 MHz clock for 8Khz and 4khz sample rate */
-#define H3800_ASIC2_CLOCK_AUDIO_2 0x0002 /* Enable 12.3 MHz clock for 48Khz and 32khz sample rate */
-#define H3800_ASIC2_CLOCK_AUDIO_3 0x0004 /* Enable 5.6 MHz clock for 11 kHZ sample rate */
-#define H3800_ASIC2_CLOCK_AUDIO_4 0x0008 /* Enable 11.289 MHz clock for 44 and 22 kHz sample rate */
-#define H3800_ASIC2_CLOCK_ADC ( 1 << 4 ) /* 1.024 MHz clock to ADC */
-#define H3800_ASIC2_CLOCK_SPI ( 1 << 5 ) /* 4.096 MHz clock to SPI */
-#define H3800_ASIC2_CLOCK_OWM ( 1 << 6 ) /* 4.096 MHz clock to OWM */
-#define H3800_ASIC2_CLOCK_PWM ( 1 << 7 ) /* 2.048 MHz clock to PWM */
-#define H3800_ASIC2_CLOCK_UART_1 ( 1 << 8 ) /* 24.576 MHz clock to UART1 (turn off bit 16) */
-#define H3800_ASIC2_CLOCK_UART_0 ( 1 << 9 ) /* 24.576 MHz clock to UART0 (turn off bit 17) */
-#define H3800_ASIC2_CLOCK_SD_1 ( 1 << 10 ) /* 16.934 MHz to SD */
-#define H3800_ASIC2_CLOCK_SD_2 ( 2 << 10 ) /* 24.576 MHz to SD */
-#define H3800_ASIC2_CLOCK_SD_3 ( 3 << 10 ) /* 33.869 MHz to SD */
-#define H3800_ASIC2_CLOCK_SD_4 ( 4 << 10 ) /* 49.152 MHz to SD */
-#define H3800_ASIC2_CLOCK_EX0 ( 1 << 13 ) /* Enable 32.768 kHz crystal */
-#define H3800_ASIC2_CLOCK_EX1 ( 1 << 14 ) /* Enable 24.576 MHz crystal */
-#define H3800_ASIC2_CLOCK_EX2 ( 1 << 15 ) /* Enable 33.869 MHz crystal */
-#define H3800_ASIC2_CLOCK_SLOW_UART_1 ( 1 << 16 ) /* Enable 3.686 MHz to UART1 (turn off bit 8) */
-#define H3800_ASIC2_CLOCK_SLOW_UART_0 ( 1 << 17 ) /* Enable 3.686 MHz to UART0 (turn off bit 9) */
-
-#define _H3800_ASIC2_ADC_Base 0x1200
-#define _H3800_ASIC2_ADC_Multiplexer 0x0000 /* R/W 4 bits - low 3 bits set channel */
-#define _H3800_ASIC2_ADC_ControlStatus 0x0004 /* R/W 8 bits */
-#define _H3800_ASIC2_ADC_Data 0x0008 /* R 10 bits */
-
-#define H3800_ASIC2_ADC_Multiplexer H3800_ASIC2_OFFSET( u8, ADC, Multiplexer )
-#define H3800_ASIC2_ADC_ControlStatus H3800_ASIC2_OFFSET( u8, ADC, ControlStatus )
-#define H3800_ASIC2_ADC_Data H3800_ASIC2_OFFSET( u16, ADC, Data )
-
-#define H3600_ASIC2_ADC_MUX_CHANNEL_MASK 0x07 /* Low 3 bits sets channel. max = 4 */
-#define H3600_ASIC2_ADC_MUX_CLKEN ( 1 << 3 ) /* Enable clock */
-
-#define H3600_ASIC2_ADC_CSR_ADPS_MASK 0x0f /* Low 4 bits sets prescale, max = 8 */
-#define H3600_ASIC2_ADC_CSR_FREE_RUN ( 1 << 4 )
-#define H3600_ASIC2_ADC_CSR_INT_ENABLE ( 1 << 5 )
-#define H3600_ASIC2_ADC_CSR_START ( 1 << 6 ) /* Set to start conversion. Goes to 0 when done */
-#define H3600_ASIC2_ADC_CSR_ENABLE ( 1 << 7 ) /* 1:power up ADC, 0:power down */
-
-
-#define _H3800_ASIC2_INTR_Base 0x1600
-#define _H3800_ASIC2_INTR_MaskAndFlag 0x0000 /* R/(W) 8bits */
-#define _H3800_ASIC2_INTR_ClockPrescale 0x0004 /* R/(W) 5bits */
-#define _H3800_ASIC2_INTR_TimerSet 0x0008 /* R/(W) 8bits */
-
-#define H3800_ASIC2_INTR_MaskAndFlag H3800_ASIC2_OFFSET( u8, INTR, MaskAndFlag )
-#define H3800_ASIC2_INTR_ClockPrescale H3800_ASIC2_OFFSET( u8, INTR, ClockPrescale )
-#define H3800_ASIC2_INTR_TimerSet H3800_ASIC2_OFFSET( u8, INTR, TimerSet )
-
-#define H3800_ASIC2_INTR_GLOBAL_MASK ( 1 << 0 ) /* Global interrupt mask */
-#define H3800_ASIC2_INTR_POWER_ON_RESET ( 1 << 1 ) /* 01: Power on reset (bits 1 & 2 ) */
-#define H3800_ASIC2_INTR_EXTERNAL_RESET ( 2 << 1 ) /* 10: External reset (bits 1 & 2 ) */
-#define H3800_ASIC2_INTR_MASK_UART_0 ( 1 << 4 )
-#define H3800_ASIC2_INTR_MASK_UART_1 ( 1 << 5 )
-#define H3800_ASIC2_INTR_MASK_TIMER ( 1 << 6 )
-#define H3800_ASIC2_INTR_MASK_OWM ( 1 << 7 )
-
-#define H3800_ASIC2_INTR_CLOCK_PRESCALE 0x0f /* 4 bits, max 14 */
-#define H3800_ASIC2_INTR_SET ( 1 << 4 ) /* Time base enable */
-
-
-#define _H3800_ASIC2_OWM_Base 0x1800
-#define _H3800_ASIC2_OWM_Command 0x0000 /* R/W 4 bits command register */
-#define _H3800_ASIC2_OWM_Data 0x0004 /* R/W 8 bits, transmit / receive buffer */
-#define _H3800_ASIC2_OWM_Interrupt 0x0008 /* R/W Command register */
-#define _H3800_ASIC2_OWM_InterruptEnable 0x000c /* R/W Command register */
-#define _H3800_ASIC2_OWM_ClockDivisor 0x0010 /* R/W 5 bits of divisor and pre-scale */
-
-#define H3800_ASIC2_OWM_Command H3800_ASIC2_OFFSET( u8, OWM, Command )
-#define H3800_ASIC2_OWM_Data H3800_ASIC2_OFFSET( u8, OWM, Data )
-#define H3800_ASIC2_OWM_Interrupt H3800_ASIC2_OFFSET( u8, OWM, Interrupt )
-#define H3800_ASIC2_OWM_InterruptEnable H3800_ASIC2_OFFSET( u8, OWM, InterruptEnable )
-#define H3800_ASIC2_OWM_ClockDivisor H3800_ASIC2_OFFSET( u8, OWM, ClockDivisor )
-
-#define H3800_ASIC2_OWM_CMD_ONE_WIRE_RESET ( 1 << 0 ) /* Set to force reset on 1-wire bus */
-#define H3800_ASIC2_OWM_CMD_SRA ( 1 << 1 ) /* Set to switch to Search ROM accelerator mode */
-#define H3800_ASIC2_OWM_CMD_DQ_OUTPUT ( 1 << 2 ) /* Write only - forces bus low */
-#define H3800_ASIC2_OWM_CMD_DQ_INPUT ( 1 << 3 ) /* Read only - reflects state of bus */
-
-#define H3800_ASIC2_OWM_INT_PD ( 1 << 0 ) /* Presence detect */
-#define H3800_ASIC2_OWM_INT_PDR ( 1 << 1 ) /* Presence detect result */
-#define H3800_ASIC2_OWM_INT_TBE ( 1 << 2 ) /* Transmit buffer empty */
-#define H3800_ASIC2_OWM_INT_TEMT ( 1 << 3 ) /* Transmit shift register empty */
-#define H3800_ASIC2_OWM_INT_RBF ( 1 << 4 ) /* Receive buffer full */
-
-#define H3800_ASIC2_OWM_INTEN_EPD ( 1 << 0 ) /* Enable receive buffer full interrupt */
-#define H3800_ASIC2_OWM_INTEN_IAS ( 1 << 1 ) /* Enable transmit shift register empty interrupt */
-#define H3800_ASIC2_OWM_INTEN_ETBE ( 1 << 2 ) /* Enable transmit buffer empty interrupt */
-#define H3800_ASIC2_OWM_INTEN_ETMT ( 1 << 3 ) /* INTR active state */
-#define H3800_ASIC2_OWM_INTEN_ERBF ( 1 << 4 ) /* Enable presence detect interrupt */
-
-#define _H3800_ASIC2_FlashCtl_Base 0x1A00
-
-/****************************************************/
-/* H3800, ASIC #1
- * This ASIC is accesed through ASIC #2, and
- * mapped into the 1c00 - 1f00 region
- */
-
-#define H3800_ASIC1_OFFSET(s,x,y) \
- (*((volatile s *) (_H3800_ASIC2_Base + _H3800_ASIC1_ ## x ## _Base + (_H3800_ASIC1_ ## x ## _ ## y << 1))))
-
-#define _H3800_ASIC1_MMC_Base 0x1c00
-
-#define _H3800_ASIC1_MMC_StartStopClock 0x00 /* R/W 8bit */
-#define _H3800_ASIC1_MMC_Status 0x02 /* R See below, default 0x0040 */
-#define _H3800_ASIC1_MMC_ClockRate 0x04 /* R/W 8bit, low 3 bits are clock divisor */
-#define _H3800_ASIC1_MMC_SPIRegister 0x08 /* R/W 8bit, see below */
-#define _H3800_ASIC1_MMC_CmdDataCont 0x0a /* R/W 8bit, write to start MMC adapter */
-#define _H3800_ASIC1_MMC_ResponseTimeout 0x0c /* R/W 8bit, clocks before response timeout */
-#define _H3800_ASIC1_MMC_ReadTimeout 0x0e /* R/W 16bit, clocks before received data timeout */
-#define _H3800_ASIC1_MMC_BlockLength 0x10 /* R/W 10bit */
-#define _H3800_ASIC1_MMC_NumOfBlocks 0x12 /* R/W 16bit, in block mode, number of blocks */
-#define _H3800_ASIC1_MMC_InterruptMask 0x1a /* R/W 8bit */
-#define _H3800_ASIC1_MMC_CommandNumber 0x1c /* R/W 6 bits */
-#define _H3800_ASIC1_MMC_ArgumentH 0x1e /* R/W 16 bits */
-#define _H3800_ASIC1_MMC_ArgumentL 0x20 /* R/W 16 bits */
-#define _H3800_ASIC1_MMC_ResFifo 0x22 /* R 8 x 16 bits - contains response FIFO */
-#define _H3800_ASIC1_MMC_BufferPartFull 0x28 /* R/W 8 bits */
-
-#define H3800_ASIC1_MMC_StartStopClock H3800_ASIC1_OFFSET( u8, MMC, StartStopClock )
-#define H3800_ASIC1_MMC_Status H3800_ASIC1_OFFSET( u16, MMC, Status )
-#define H3800_ASIC1_MMC_ClockRate H3800_ASIC1_OFFSET( u8, MMC, ClockRate )
-#define H3800_ASIC1_MMC_SPIRegister H3800_ASIC1_OFFSET( u8, MMC, SPIRegister )
-#define H3800_ASIC1_MMC_CmdDataCont H3800_ASIC1_OFFSET( u8, MMC, CmdDataCont )
-#define H3800_ASIC1_MMC_ResponseTimeout H3800_ASIC1_OFFSET( u8, MMC, ResponseTimeout )
-#define H3800_ASIC1_MMC_ReadTimeout H3800_ASIC1_OFFSET( u16, MMC, ReadTimeout )
-#define H3800_ASIC1_MMC_BlockLength H3800_ASIC1_OFFSET( u16, MMC, BlockLength )
-#define H3800_ASIC1_MMC_NumOfBlocks H3800_ASIC1_OFFSET( u16, MMC, NumOfBlocks )
-#define H3800_ASIC1_MMC_InterruptMask H3800_ASIC1_OFFSET( u8, MMC, InterruptMask )
-#define H3800_ASIC1_MMC_CommandNumber H3800_ASIC1_OFFSET( u8, MMC, CommandNumber )
-#define H3800_ASIC1_MMC_ArgumentH H3800_ASIC1_OFFSET( u16, MMC, ArgumentH )
-#define H3800_ASIC1_MMC_ArgumentL H3800_ASIC1_OFFSET( u16, MMC, ArgumentL )
-#define H3800_ASIC1_MMC_ResFifo H3800_ASIC1_OFFSET( u16, MMC, ResFifo )
-#define H3800_ASIC1_MMC_BufferPartFull H3800_ASIC1_OFFSET( u8, MMC, BufferPartFull )
-
-#define H3800_ASIC1_MMC_STOP_CLOCK (1 << 0) /* Write to "StartStopClock" register */
-#define H3800_ASIC1_MMC_START_CLOCK (1 << 1)
-
-#define H3800_ASIC1_MMC_STATUS_READ_TIMEOUT (1 << 0)
-#define H3800_ASIC1_MMC_STATUS_RESPONSE_TIMEOUT (1 << 1)
-#define H3800_ASIC1_MMC_STATUS_CRC_WRITE_ERROR (1 << 2)
-#define H3800_ASIC1_MMC_STATUS_CRC_READ_ERROR (1 << 3)
-#define H3800_ASIC1_MMC_STATUS_SPI_READ_ERROR (1 << 4) /* SPI data token error received */
-#define H3800_ASIC1_MMC_STATUS_CRC_RESPONSE_ERROR (1 << 5)
-#define H3800_ASIC1_MMC_STATUS_FIFO_EMPTY (1 << 6)
-#define H3800_ASIC1_MMC_STATUS_FIFO_FULL (1 << 7)
-#define H3800_ASIC1_MMC_STATUS_CLOCK_ENABLE (1 << 8) /* MultiMediaCard clock stopped */
-#define H3800_ASIC1_MMC_STATUS_DATA_TRANSFER_DONE (1 << 11) /* Write operation, indicates transfer finished */
-#define H3800_ASIC1_MMC_STATUS_END_PROGRAM (1 << 12) /* End write and read operations */
-#define H3800_ASIC1_MMC_STATUS_END_COMMAND_RESPONSE (1 << 13) /* End command response */
-
-#define H3800_ASIC1_MMC_SPI_REG_SPI_ENABLE (1 << 0) /* Enables SPI mode */
-#define H3800_ASIC1_MMC_SPI_REG_CRC_ON (1 << 1) /* 1:turn on CRC */
-#define H3800_ASIC1_MMC_SPI_REG_SPI_CS_ENABLE (1 << 2) /* 1:turn on SPI CS */
-#define H3800_ASIC1_MMC_SPI_REG_CS_ADDRESS_MASK 0x38 /* Bits 3,4,5 are the SPI CS relative address */
-
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_FORMAT_NO_RESPONSE 0x00
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_FORMAT_R1 0x01
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_FORMAT_R2 0x02
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_FORMAT_R3 0x03
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_DATA_ENABLE (1 << 2) /* This command contains a data transfer */
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_WRITE (1 << 3) /* This data transfer is a write */
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_STREAM_MODE (1 << 4) /* This data transfer is in stream mode */
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_BUSY_BIT (1 << 5) /* Busy signal expected after current cmd */
-#define H3800_ASIC1_MMC_CMD_DATA_CONT_INITIALIZE (1 << 6) /* Enables the 80 bits for initializing card */
-
-#define H3800_ASIC1_MMC_INT_MASK_DATA_TRANSFER_DONE (1 << 0)
-#define H3800_ASIC1_MMC_INT_MASK_PROGRAM_DONE (1 << 1)
-#define H3800_ASIC1_MMC_INT_MASK_END_COMMAND_RESPONSE (1 << 2)
-#define H3800_ASIC1_MMC_INT_MASK_BUFFER_READY (1 << 3)
-
-#define H3800_ASIC1_MMC_BUFFER_PART_FULL (1 << 0)
-
-/********* GPIO **********/
-
-#define _H3800_ASIC1_GPIO_Base 0x1e00
-
-#define _H3800_ASIC1_GPIO_Mask 0x30 /* R/W 0:don't mask, 1:mask interrupt */
-#define _H3800_ASIC1_GPIO_Direction 0x32 /* R/W 0:input, 1:output */
-#define _H3800_ASIC1_GPIO_Out 0x34 /* R/W 0:output low, 1:output high */
-#define _H3800_ASIC1_GPIO_TriggerType 0x36 /* R/W 0:level, 1:edge */
-#define _H3800_ASIC1_GPIO_EdgeTrigger 0x38 /* R/W 0:falling, 1:rising */
-#define _H3800_ASIC1_GPIO_LevelTrigger 0x3A /* R/W 0:low, 1:high level detect */
-#define _H3800_ASIC1_GPIO_LevelStatus 0x3C /* R/W 0:none, 1:detect */
-#define _H3800_ASIC1_GPIO_EdgeStatus 0x3E /* R/W 0:none, 1:detect */
-#define _H3800_ASIC1_GPIO_State 0x40 /* R See masks below (default 0) */
-#define _H3800_ASIC1_GPIO_Reset 0x42 /* R/W See masks below (default 0x04) */
-#define _H3800_ASIC1_GPIO_SleepMask 0x44 /* R/W 0:don't mask, 1:mask trigger in sleep mode */
-#define _H3800_ASIC1_GPIO_SleepDir 0x46 /* R/W direction 0:input, 1:output in sleep mode */
-#define _H3800_ASIC1_GPIO_SleepOut 0x48 /* R/W level 0:low, 1:high in sleep mode */
-#define _H3800_ASIC1_GPIO_Status 0x4A /* R Pin status */
-#define _H3800_ASIC1_GPIO_BattFaultDir 0x4C /* R/W direction 0:input, 1:output in batt_fault */
-#define _H3800_ASIC1_GPIO_BattFaultOut 0x4E /* R/W level 0:low, 1:high in batt_fault */
-
-#define H3800_ASIC1_GPIO_Mask H3800_ASIC1_OFFSET( u16, GPIO, Mask )
-#define H3800_ASIC1_GPIO_Direction H3800_ASIC1_OFFSET( u16, GPIO, Direction )
-#define H3800_ASIC1_GPIO_Out H3800_ASIC1_OFFSET( u16, GPIO, Out )
-#define H3800_ASIC1_GPIO_TriggerType H3800_ASIC1_OFFSET( u16, GPIO, TriggerType )
-#define H3800_ASIC1_GPIO_EdgeTrigger H3800_ASIC1_OFFSET( u16, GPIO, EdgeTrigger )
-#define H3800_ASIC1_GPIO_LevelTrigger H3800_ASIC1_OFFSET( u16, GPIO, LevelTrigger )
-#define H3800_ASIC1_GPIO_LevelStatus H3800_ASIC1_OFFSET( u16, GPIO, LevelStatus )
-#define H3800_ASIC1_GPIO_EdgeStatus H3800_ASIC1_OFFSET( u16, GPIO, EdgeStatus )
-#define H3800_ASIC1_GPIO_State H3800_ASIC1_OFFSET( u8, GPIO, State )
-#define H3800_ASIC1_GPIO_Reset H3800_ASIC1_OFFSET( u8, GPIO, Reset )
-#define H3800_ASIC1_GPIO_SleepMask H3800_ASIC1_OFFSET( u16, GPIO, SleepMask )
-#define H3800_ASIC1_GPIO_SleepDir H3800_ASIC1_OFFSET( u16, GPIO, SleepDir )
-#define H3800_ASIC1_GPIO_SleepOut H3800_ASIC1_OFFSET( u16, GPIO, SleepOut )
-#define H3800_ASIC1_GPIO_Status H3800_ASIC1_OFFSET( u16, GPIO, Status )
-#define H3800_ASIC1_GPIO_BattFaultDir H3800_ASIC1_OFFSET( u16, GPIO, BattFaultDir )
-#define H3800_ASIC1_GPIO_BattFaultOut H3800_ASIC1_OFFSET( u16, GPIO, BattFaultOut )
-
-#define H3800_ASIC1_GPIO_STATE_MASK (1 << 0)
-#define H3800_ASIC1_GPIO_STATE_DIRECTION (1 << 1)
-#define H3800_ASIC1_GPIO_STATE_OUT (1 << 2)
-#define H3800_ASIC1_GPIO_STATE_TRIGGER_TYPE (1 << 3)
-#define H3800_ASIC1_GPIO_STATE_EDGE_TRIGGER (1 << 4)
-#define H3800_ASIC1_GPIO_STATE_LEVEL_TRIGGER (1 << 5)
-
-#define H3800_ASIC1_GPIO_RESET_SOFTWARE (1 << 0)
-#define H3800_ASIC1_GPIO_RESET_AUTO_SLEEP (1 << 1)
-#define H3800_ASIC1_GPIO_RESET_FIRST_PWR_ON (1 << 2)
-
-/* These are all outputs */
-#define GPIO_H3800_ASIC1_IR_ON_N (1 << 0) /* Apply power to the IR Module */
-#define GPIO_H3800_ASIC1_SD_PWR_ON (1 << 1) /* Secure Digital power on */
-#define GPIO_H3800_ASIC1_RS232_ON (1 << 2) /* Turn on power to the RS232 chip ? */
-#define GPIO_H3800_ASIC1_PULSE_GEN (1 << 3) /* Goes to speaker / earphone */
-#define GPIO_H3800_ASIC1_CH_TIMER (1 << 4) /* */
-#define GPIO_H3800_ASIC1_LCD_5V_ON (1 << 5) /* Enables LCD_5V */
-#define GPIO_H3800_ASIC1_LCD_ON (1 << 6) /* Enables LCD_3V */
-#define GPIO_H3800_ASIC1_LCD_PCI (1 << 7) /* Connects to PDWN on LCD controller */
-#define GPIO_H3800_ASIC1_VGH_ON (1 << 8) /* Drives VGH on the LCD (+9??) */
-#define GPIO_H3800_ASIC1_VGL_ON (1 << 9) /* Drivers VGL on the LCD (-6??) */
-#define GPIO_H3800_ASIC1_FL_PWR_ON (1 << 10) /* Frontlight power on */
-#define GPIO_H3800_ASIC1_BT_PWR_ON (1 << 11) /* Bluetooth power on */
-#define GPIO_H3800_ASIC1_SPK_ON (1 << 12) /* */
-#define GPIO_H3800_ASIC1_EAR_ON_N (1 << 13) /* */
-#define GPIO_H3800_ASIC1_AUD_PWR_ON (1 << 14) /* */
-
-/* Write enable for the flash */
-
-#define _H3800_ASIC1_FlashWP_Base 0x1F00
-#define _H3800_ASIC1_FlashWP_VPP_ON 0x00 /* R 1: write, 0: protect */
-#define H3800_ASIC1_FlashWP_VPP_ON H3800_ASIC1_OFFSET( u8, FlashWP, VPP_ON )
#endif /* _INCLUDE_H3600_GPIO_H_ */
diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h
index 0cb36609b3ac..ae81f80b0cf9 100644
--- a/arch/arm/mach-sa1100/include/mach/irqs.h
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -153,8 +153,6 @@
*/
#ifdef CONFIG_SA1111
#define NR_IRQS (IRQ_S1_BVD1_STSCHG + 1)
-#elif defined(CONFIG_SA1100_H3800)
-#define NR_IRQS (IRQ_BOARD_END)
#elif defined(CONFIG_SHARP_LOCOMO)
#define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1)
#else
@@ -175,23 +173,3 @@
#define IRQ_LOCOMO_LT_BASE (IRQ_BOARD_START + 2)
#define IRQ_LOCOMO_SPI_BASE (IRQ_BOARD_START + 3)
-/* H3800-specific IRQs (CONFIG_SA1100_H3800) */
-#define H3800_KPIO_IRQ_START (IRQ_BOARD_START)
-#define IRQ_H3800_KEY (IRQ_BOARD_START + 0)
-#define IRQ_H3800_SPI (IRQ_BOARD_START + 1)
-#define IRQ_H3800_OWM (IRQ_BOARD_START + 2)
-#define IRQ_H3800_ADC (IRQ_BOARD_START + 3)
-#define IRQ_H3800_UART_0 (IRQ_BOARD_START + 4)
-#define IRQ_H3800_UART_1 (IRQ_BOARD_START + 5)
-#define IRQ_H3800_TIMER_0 (IRQ_BOARD_START + 6)
-#define IRQ_H3800_TIMER_1 (IRQ_BOARD_START + 7)
-#define IRQ_H3800_TIMER_2 (IRQ_BOARD_START + 8)
-#define H3800_KPIO_IRQ_COUNT 9
-
-#define H3800_GPIO_IRQ_START (IRQ_BOARD_START + 9)
-#define IRQ_H3800_PEN (IRQ_BOARD_START + 9)
-#define IRQ_H3800_SD_DETECT (IRQ_BOARD_START + 10)
-#define IRQ_H3800_EAR_IN (IRQ_BOARD_START + 11)
-#define IRQ_H3800_USB_DETECT (IRQ_BOARD_START + 12)
-#define IRQ_H3800_SD_CON_SLT (IRQ_BOARD_START + 13)
-#define H3800_GPIO_IRQ_COUNT 5
diff --git a/arch/arm/mach-sa1100/include/mach/system.h b/arch/arm/mach-sa1100/include/mach/system.h
index 63755ca5b1b4..942b153e251d 100644
--- a/arch/arm/mach-sa1100/include/mach/system.h
+++ b/arch/arm/mach-sa1100/include/mach/system.h
@@ -10,7 +10,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
if (mode == 's') {
/* Jump into ROM at address 0 */
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 81848aa96424..fd776bb666cd 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -226,12 +226,22 @@ static struct platform_device jornada_ssp_device = {
.id = -1,
};
+static struct platform_device jornada_kbd_device = {
+ .name = "jornada720_kbd",
+ .id = -1,
+};
+
+static struct platform_device jornada_ts_device = {
+ .name = "jornada_ts",
+ .id = -1,
+};
+
static struct platform_device *devices[] __initdata = {
&sa1111_device,
-#ifdef CONFIG_SA1100_JORNADA720_SSP
&jornada_ssp_device,
-#endif
&s1d13xxxfb_device,
+ &jornada_kbd_device,
+ &jornada_ts_device,
};
static int __init jornada720_init(void)
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index a23fd3d0163a..358d875ace14 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -16,12 +16,28 @@
#include <asm/leds.h>
#include <asm/param.h>
-#include <mach/hardware.h>
-
#include <asm/mach/map.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
+#define IO_BASE 0xe0000000
+#define IO_SIZE 0x08000000
+#define IO_START 0x40000000
+#define ROMCARD_SIZE 0x08000000
+#define ROMCARD_START 0x10000000
+
+void arch_reset(char mode, const char *cmd)
+{
+ short temp;
+ local_irq_disable();
+ /* Reset the Machine via pc[3] of the sequoia chipset */
+ outw(0x09,0x24);
+ temp=inw(0x26);
+ temp = temp | (1<<3) | (1<<10);
+ outw(0x09,0x24);
+ outw(temp,0x26);
+}
+
static struct plat_serial8250_port serial_platform_data[] = {
{
.iobase = 0x3f8,
@@ -50,14 +66,38 @@ static struct platform_device serial_device = {
},
};
+static struct resource rtc_resources[] = {
+ [0] = {
+ .start = 0x70,
+ .end = 0x73,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = IRQ_ISA_RTC_ALARM,
+ .end = IRQ_ISA_RTC_ALARM,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device rtc_device = {
+ .name = "rtc_cmos",
+ .id = -1,
+ .resource = rtc_resources,
+ .num_resources = ARRAY_SIZE(rtc_resources),
+};
+
static int __init shark_init(void)
{
int ret;
if (machine_is_shark())
+ {
+ ret = platform_device_register(&rtc_device);
+ if (ret) printk(KERN_ERR "Unable to register RTC device: %d\n", ret);
ret = platform_device_register(&serial_device);
-
- return ret;
+ if (ret) printk(KERN_ERR "Unable to register Serial device: %d\n", ret);
+ }
+ return 0;
}
arch_initcall(shark_init);
diff --git a/arch/arm/mach-shark/dma.c b/arch/arm/mach-shark/dma.c
index 6774b8d5d13d..10b5b8b3272a 100644
--- a/arch/arm/mach-shark/dma.c
+++ b/arch/arm/mach-shark/dma.c
@@ -13,9 +13,11 @@
#include <asm/dma.h>
#include <asm/mach/dma.h>
-void __init arch_dma_init(dma_t *dma)
+static int __init shark_dma_init(void)
{
#ifdef CONFIG_ISA_DMA
- isa_init_dma(dma);
+ isa_init_dma();
#endif
+ return 0;
}
+core_initcall(shark_dma_init);
diff --git a/arch/arm/mach-shark/include/mach/debug-macro.S b/arch/arm/mach-shark/include/mach/debug-macro.S
index 0836cb78b29a..f97a7626bd58 100644
--- a/arch/arm/mach-shark/include/mach/debug-macro.S
+++ b/arch/arm/mach-shark/include/mach/debug-macro.S
@@ -27,5 +27,3 @@
bne 1001b
.endm
- .macro waituart,rd,rx
- .endm
diff --git a/arch/arm/mach-shark/include/mach/framebuffer.h b/arch/arm/mach-shark/include/mach/framebuffer.h
new file mode 100644
index 000000000000..84a5bf6e5ba3
--- /dev/null
+++ b/arch/arm/mach-shark/include/mach/framebuffer.h
@@ -0,0 +1,16 @@
+/*
+ * arch/arm/mach-shark/include/mach/framebuffer.h
+ *
+ * by Alexander Schulz
+ *
+ */
+
+#ifndef __ASM_ARCH_FRAMEBUFFER_H
+#define __ASM_ARCH_FRAMEBUFFER_H
+
+/* defines for the Framebuffer */
+#define FB_START 0x06000000
+#define FB_SIZE 0x01000000
+
+#endif
+
diff --git a/arch/arm/mach-shark/include/mach/hardware.h b/arch/arm/mach-shark/include/mach/hardware.h
index 01bf76099ce5..94d84b27a0cb 100644
--- a/arch/arm/mach-shark/include/mach/hardware.h
+++ b/arch/arm/mach-shark/include/mach/hardware.h
@@ -10,35 +10,8 @@
#ifndef __ASM_ARCH_HARDWARE_H
#define __ASM_ARCH_HARDWARE_H
-#ifndef __ASSEMBLY__
-
-/*
- * Mapping areas
- */
-#define IO_BASE 0xe0000000
-
-#else
-
-#define IO_BASE 0
-
-#endif
-
-#define IO_SIZE 0x08000000
-#define IO_START 0x40000000
-#define ROMCARD_SIZE 0x08000000
-#define ROMCARD_START 0x10000000
-
-
-/* defines for the Framebuffer */
-#define FB_START 0x06000000
-#define FB_SIZE 0x01000000
-
#define UNCACHEABLE_ADDR 0xdf010000
-#define SEQUOIA_LED_GREEN (1<<6)
-#define SEQUOIA_LED_AMBER (1<<5)
-#define SEQUOIA_LED_BACK (1<<7)
-
#define pcibios_assign_all_busses() 1
#define PCIBIOS_MIN_IO 0x6000
diff --git a/arch/arm/mach-shark/include/mach/io.h b/arch/arm/mach-shark/include/mach/io.h
index c5cee829fc87..9ccbcecc430b 100644
--- a/arch/arm/mach-shark/include/mach/io.h
+++ b/arch/arm/mach-shark/include/mach/io.h
@@ -11,10 +11,10 @@
#ifndef __ASM_ARM_ARCH_IO_H
#define __ASM_ARM_ARCH_IO_H
-#define PCIO_BASE 0xe0000000
-#define IO_SPACE_LIMIT 0xffffffff
+#define IO_SPACE_LIMIT 0xffffffff
-#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
-#define __mem_pci(addr) (addr)
+#define __io(a) ((void __iomem *)(0xe0000000 + (a)))
+
+#define __mem_pci(addr) (addr)
#endif
diff --git a/arch/arm/mach-shark/include/mach/irqs.h b/arch/arm/mach-shark/include/mach/irqs.h
index 0586acd7cdd5..c8e8a4e1f61a 100644
--- a/arch/arm/mach-shark/include/mach/irqs.h
+++ b/arch/arm/mach-shark/include/mach/irqs.h
@@ -7,7 +7,7 @@
#define NR_IRQS 16
#define IRQ_ISA_KEYBOARD 1
-#define RTC_IRQ 8
+#define IRQ_ISA_RTC_ALARM 8
#define I8042_KBD_IRQ 1
#define I8042_AUX_IRQ 12
#define IRQ_HARDDISK 14
diff --git a/arch/arm/mach-shark/include/mach/isa-dma.h b/arch/arm/mach-shark/include/mach/isa-dma.h
index 864298ff3927..96c43b8f8dda 100644
--- a/arch/arm/mach-shark/include/mach/isa-dma.h
+++ b/arch/arm/mach-shark/include/mach/isa-dma.h
@@ -6,10 +6,6 @@
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H
-/* Use only the lowest 4MB, nothing else works.
- * The rest is not DMAable. See dev / .properties
- * in OpenFirmware.
- */
#define MAX_DMA_CHANNELS 8
#define DMA_ISA_CASCADE 4
diff --git a/arch/arm/mach-shark/include/mach/memory.h b/arch/arm/mach-shark/include/mach/memory.h
index c5ab038925d6..3053e5b7f168 100644
--- a/arch/arm/mach-shark/include/mach/memory.h
+++ b/arch/arm/mach-shark/include/mach/memory.h
@@ -23,6 +23,7 @@ static inline void __arch_adjust_zones(int node, unsigned long *zone_size, unsig
{
if (node != 0) return;
/* Only the first 4 MB (=1024 Pages) are usable for DMA */
+ /* See dev / -> .properties in OpenFirmware. */
zone_size[1] = zone_size[0] - 1024;
zone_size[0] = 1024;
zhole_size[1] = zhole_size[0];
diff --git a/arch/arm/mach-shark/include/mach/system.h b/arch/arm/mach-shark/include/mach/system.h
index e45bd734a03e..21c373b30bbc 100644
--- a/arch/arm/mach-shark/include/mach/system.h
+++ b/arch/arm/mach-shark/include/mach/system.h
@@ -6,20 +6,8 @@
#ifndef __ASM_ARCH_SYSTEM_H
#define __ASM_ARCH_SYSTEM_H
-#include <linux/io.h>
-
-static void arch_reset(char mode)
-{
- short temp;
- local_irq_disable();
- /* Reset the Machine via pc[3] of the sequoia chipset */
- outw(0x09,0x24);
- temp=inw(0x26);
- temp = temp | (1<<3) | (1<<10);
- outw(0x09,0x24);
- outw(temp,0x26);
-
-}
+/* Found in arch/mach-shark/core.c */
+extern void arch_reset(char mode, const char *cmd);
static inline void arch_idle(void)
{
diff --git a/arch/arm/mach-shark/include/mach/uncompress.h b/arch/arm/mach-shark/include/mach/uncompress.h
index 3725e1633418..22ccab4c3c5e 100644
--- a/arch/arm/mach-shark/include/mach/uncompress.h
+++ b/arch/arm/mach-shark/include/mach/uncompress.h
@@ -11,7 +11,7 @@
static inline void putc(int c)
{
- int t;
+ volatile int t;
SERIAL_BASE[0] = c;
t=0x10000;
diff --git a/arch/arm/mach-shark/leds.c b/arch/arm/mach-shark/leds.c
index 8bd8d6bb4d92..c9e32de4adf9 100644
--- a/arch/arm/mach-shark/leds.c
+++ b/arch/arm/mach-shark/leds.c
@@ -22,12 +22,16 @@
#include <linux/ioport.h>
#include <linux/io.h>
-#include <mach/hardware.h>
#include <asm/leds.h>
#include <asm/system.h>
#define LED_STATE_ENABLED 1
#define LED_STATE_CLAIMED 2
+
+#define SEQUOIA_LED_GREEN (1<<6)
+#define SEQUOIA_LED_AMBER (1<<5)
+#define SEQUOIA_LED_BACK (1<<7)
+
static char led_state;
static short hw_led_state;
static short saved_state;
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 1c43494f5c42..565776680d8c 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -335,11 +335,25 @@ static struct resource versatile_i2c_resource = {
static struct platform_device versatile_i2c_device = {
.name = "versatile-i2c",
- .id = -1,
+ .id = 0,
.num_resources = 1,
.resource = &versatile_i2c_resource,
};
+static struct i2c_board_info versatile_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("rtc-ds1307", 0xd0 >> 1),
+ .type = "ds1338",
+ },
+};
+
+static int __init versatile_i2c_init(void)
+{
+ return i2c_register_board_info(0, versatile_i2c_board_info,
+ ARRAY_SIZE(versatile_i2c_board_info));
+}
+arch_initcall(versatile_i2c_init);
+
#define VERSATILE_SYSMCI (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
unsigned int mmc_status(struct device *dev)
diff --git a/arch/arm/mach-versatile/include/mach/system.h b/arch/arm/mach-versatile/include/mach/system.h
index c59e6100c7e3..8ffc12a7cb25 100644
--- a/arch/arm/mach-versatile/include/mach/system.h
+++ b/arch/arm/mach-versatile/include/mach/system.h
@@ -34,7 +34,7 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
u32 val;
diff --git a/arch/arm/mach-w90x900/cpu.h b/arch/arm/mach-w90x900/cpu.h
index 40ff40845df0..de29ddcb9459 100644
--- a/arch/arm/mach-w90x900/cpu.h
+++ b/arch/arm/mach-w90x900/cpu.h
@@ -43,35 +43,16 @@ extern void w90p910_init_io(struct map_desc *mach_desc, int size);
extern void w90p910_init_uarts(struct w90x900_uartcfg *cfg, int no);
extern void w90p910_init_clocks(int xtal);
extern void w90p910_map_io(struct map_desc *mach_desc, int size);
+extern struct platform_device w90p910_serial_device;
extern struct sys_timer w90x900_timer;
-#define W90X900_RES(name) \
-struct resource w90x900_##name##_resource[] = { \
- [0] = { \
- .start = name##_PA, \
- .end = name##_PA + 0x0ff, \
- .flags = IORESOURCE_MEM, \
- }, \
- [1] = { \
- .start = IRQ_##name, \
- .end = IRQ_##name, \
- .flags = IORESOURCE_IRQ, \
- } \
-}
-
-#define W90X900_DEVICE(devname, regname, devid, platdevname) \
-struct platform_device w90x900_##devname = { \
- .name = platdevname, \
- .id = devid, \
- .num_resources = ARRAY_SIZE(w90x900_##regname##_resource), \
- .resource = w90x900_##regname##_resource, \
-}
-
-#define W90X900_UARTCFG(port, flag, uc, ulc, ufc) \
-{ \
- .hwport = port, \
- .flags = flag, \
- .ucon = uc, \
- .ulcon = ulc, \
- .ufcon = ufc, \
+#define W90X900_8250PORT(name) \
+{ \
+ .membase = name##_BA, \
+ .mapbase = name##_PA, \
+ .irq = IRQ_##name, \
+ .uartclk = 11313600, \
+ .regshift = 2, \
+ .iotype = UPIO_MEM, \
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
}
diff --git a/arch/arm/mach-w90x900/include/mach/system.h b/arch/arm/mach-w90x900/include/mach/system.h
index 93753f922618..940640066857 100644
--- a/arch/arm/mach-w90x900/include/mach/system.h
+++ b/arch/arm/mach-w90x900/include/mach/system.h
@@ -21,7 +21,7 @@ static void arch_idle(void)
{
}
-static void arch_reset(char mode)
+static void arch_reset(char mode, const char *cmd)
{
cpu_reset(0);
}
diff --git a/arch/arm/mach-w90x900/mach-w90p910evb.c b/arch/arm/mach-w90x900/mach-w90p910evb.c
index 9ebc93f48530..726ff6798a56 100644
--- a/arch/arm/mach-w90x900/mach-w90p910evb.c
+++ b/arch/arm/mach-w90x900/mach-w90p910evb.c
@@ -22,6 +22,7 @@
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -32,28 +33,67 @@
#include <mach/map.h>
#include "cpu.h"
+/*w90p910 evb norflash driver data */
-static struct map_desc w90p910_iodesc[] __initdata = {
+#define W90P910_FLASH_BASE 0xA0000000
+#define W90P910_FLASH_SIZE 0x400000
+
+static struct mtd_partition w90p910_flash_partitions[] = {
+ {
+ .name = "NOR Partition 1 for kernel (960K)",
+ .size = 0xF0000,
+ .offset = 0x10000,
+ },
+ {
+ .name = "NOR Partition 2 for image (1M)",
+ .size = 0x100000,
+ .offset = 0x100000,
+ },
+ {
+ .name = "NOR Partition 3 for user (2M)",
+ .size = 0x200000,
+ .offset = 0x00200000,
+ }
};
-static struct w90x900_uartcfg w90p910_uartcfgs[] = {
- W90X900_UARTCFG(0, 0, 0, 0, 0),
- W90X900_UARTCFG(1, 0, 0, 0, 0),
- W90X900_UARTCFG(2, 0, 0, 0, 0),
- W90X900_UARTCFG(3, 0, 0, 0, 0),
- W90X900_UARTCFG(4, 0, 0, 0, 0),
+static struct physmap_flash_data w90p910_flash_data = {
+ .width = 2,
+ .parts = w90p910_flash_partitions,
+ .nr_parts = ARRAY_SIZE(w90p910_flash_partitions),
+};
+
+static struct resource w90p910_flash_resources[] = {
+ {
+ .start = W90P910_FLASH_BASE,
+ .end = W90P910_FLASH_BASE + W90P910_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device w90p910_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &w90p910_flash_data,
+ },
+ .resource = w90p910_flash_resources,
+ .num_resources = ARRAY_SIZE(w90p910_flash_resources),
+};
+
+static struct map_desc w90p910_iodesc[] __initdata = {
};
/*Here should be your evb resourse,such as LCD*/
static struct platform_device *w90p910evb_dev[] __initdata = {
+ &w90p910_serial_device,
+ &w90p910_flash_device,
};
static void __init w90p910evb_map_io(void)
{
w90p910_map_io(w90p910_iodesc, ARRAY_SIZE(w90p910_iodesc));
w90p910_init_clocks(0);
- w90p910_init_uarts(w90p910_uartcfgs, ARRAY_SIZE(w90p910_uartcfgs));
}
static void __init w90p910evb_init(void)
diff --git a/arch/arm/mach-w90x900/w90p910.c b/arch/arm/mach-w90x900/w90p910.c
index aa783bc94310..2bcbaa681b99 100644
--- a/arch/arm/mach-w90x900/w90p910.c
+++ b/arch/arm/mach-w90x900/w90p910.c
@@ -25,6 +25,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/serial_8250.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -36,12 +37,6 @@
#include "cpu.h"
-/*W90P910 has five uarts*/
-
-#define MAX_UART_COUNT 5
-static int uart_count;
-static struct platform_device *uart_devs[MAX_UART_COUNT-1];
-
/* Initial IO mappings */
static struct map_desc w90p910_iodesc[] __initdata = {
@@ -53,48 +48,19 @@ static struct map_desc w90p910_iodesc[] __initdata = {
/*IODESC_ENT(LCD),*/
};
-/*Init the dev resource*/
-
-static W90X900_RES(UART0);
-static W90X900_RES(UART1);
-static W90X900_RES(UART2);
-static W90X900_RES(UART3);
-static W90X900_RES(UART4);
-static W90X900_DEVICE(uart0, UART0, 0, "w90x900-uart");
-static W90X900_DEVICE(uart1, UART1, 1, "w90x900-uart");
-static W90X900_DEVICE(uart2, UART2, 2, "w90x900-uart");
-static W90X900_DEVICE(uart3, UART3, 3, "w90x900-uart");
-static W90X900_DEVICE(uart4, UART4, 4, "w90x900-uart");
-
-static struct platform_device *uart_devices[] __initdata = {
- &w90x900_uart0,
- &w90x900_uart1,
- &w90x900_uart2,
- &w90x900_uart3,
- &w90x900_uart4
-};
+/* Initial serial platform data */
-/*Init W90P910 uart device*/
+struct plat_serial8250_port w90p910_uart_data[] = {
+ W90X900_8250PORT(UART0),
+};
-void __init w90p910_init_uarts(struct w90x900_uartcfg *cfg, int no)
-{
- struct platform_device *platdev;
- int uart, uartdev;
-
- /*By min() to judge count of uart be used indeed*/
-
- uartdev = ARRAY_SIZE(uart_devices);
- no = min(uartdev, no);
-
- for (uart = 0; uart < no; uart++, cfg++) {
- if (cfg->hwport != uart)
- printk(KERN_ERR "w90x900_uartcfg[%d] error\n", uart);
- platdev = uart_devices[cfg->hwport];
- uart_devs[uart] = platdev;
- platdev->dev.platform_data = cfg;
- }
- uart_count = uart;
-}
+struct platform_device w90p910_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = w90p910_uart_data,
+ },
+};
/*Init W90P910 evb io*/
@@ -122,13 +88,6 @@ static int __init w90p910_init_cpu(void)
static int __init w90x900_arch_init(void)
{
- int ret;
-
- ret = w90p910_init_cpu();
- if (ret != 0)
- return ret;
-
- return platform_add_devices(uart_devs, uart_count);
-
+ return w90p910_init_cpu();
}
arch_initcall(w90x900_arch_init);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index d490f3773c01..20979564e7ee 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -186,6 +186,24 @@ config CPU_ARM926T
Say Y if you want support for the ARM926T processor.
Otherwise, say N.
+# FA526
+config CPU_FA526
+ bool
+ select CPU_32v4
+ select CPU_ABRT_EV4
+ select CPU_PABRT_NOIFAR
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_CACHE_FA
+ select CPU_COPY_FA if MMU
+ select CPU_TLB_FA if MMU
+ help
+ The FA526 is a version of the ARMv4 compatible processor with
+ Branch Target Buffer, Unified TLB and cache line size 16.
+
+ Say Y if you want support for the FA526 processor.
+ Otherwise, say N.
+
# ARM940T
config CPU_ARM940T
bool "Support ARM940T processor" if ARCH_INTEGRATOR
@@ -340,6 +358,17 @@ config CPU_XSC3
select CPU_TLB_V4WBI if MMU
select IO_36
+# Marvell PJ1 (Mohawk)
+config CPU_MOHAWK
+ bool
+ select CPU_32v5
+ select CPU_ABRT_EV5T
+ select CPU_PABRT_NOIFAR
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_TLB_V4WBI if MMU
+ select CPU_COPY_V4WB if MMU
+
# Feroceon
config CPU_FEROCEON
bool
@@ -484,6 +513,9 @@ config CPU_CACHE_VIVT
config CPU_CACHE_VIPT
bool
+config CPU_CACHE_FA
+ bool
+
if MMU
# The copy-page model
config CPU_COPY_V3
@@ -498,6 +530,9 @@ config CPU_COPY_V4WB
config CPU_COPY_FEROCEON
bool
+config CPU_COPY_FA
+ bool
+
config CPU_COPY_V6
bool
@@ -528,6 +563,13 @@ config CPU_TLB_FEROCEON
help
Feroceon TLB (v4wbi with non-outer-cachable page table walks).
+config CPU_TLB_FA
+ bool
+ help
+ Faraday ARM FA526 architecture, unified TLB with writeback cache
+ and invalidate instruction cache entry. Branch target buffer is
+ also supported.
+
config CPU_TLB_V6
bool
@@ -569,7 +611,7 @@ comment "Processor Features"
config ARM_THUMB
bool "Support Thumb user binaries"
- depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 || CPU_V7 || CPU_FEROCEON
+ depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V7 || CPU_FEROCEON
default y
help
Say Y if you want to include kernel support for running user space
@@ -638,7 +680,7 @@ config CPU_DCACHE_SIZE
config CPU_DCACHE_WRITETHROUGH
bool "Force write through D-cache"
- depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020) && !CPU_DCACHE_DISABLE
+ depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_FA526) && !CPU_DCACHE_DISABLE
default y if CPU_ARM925T
help
Say Y here to use the data cache in writethrough mode. Unless you
@@ -653,7 +695,7 @@ config CPU_CACHE_ROUND_ROBIN
config CPU_BPREDICT_DISABLE
bool "Disable branch prediction"
- depends on CPU_ARM1020 || CPU_V6 || CPU_XSC3 || CPU_V7
+ depends on CPU_ARM1020 || CPU_V6 || CPU_MOHAWK || CPU_XSC3 || CPU_V7 || CPU_FA526
help
Say Y here to disable branch prediction. If unsure, say N.
@@ -704,7 +746,8 @@ config CACHE_FEROCEON_L2_WRITETHROUGH
config CACHE_L2X0
bool "Enable the L2x0 outer cache controller"
- depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || REALVIEW_EB_A9MP
+ depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
+ REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31
default y
select OUTER_CACHE
help
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 480f78a3611a..63e3f6dd0e21 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_MODULES) += proc-syms.o
obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
obj-$(CONFIG_DISCONTIGMEM) += discontig.o
+obj-$(CONFIG_HIGHMEM) += highmem.o
obj-$(CONFIG_CPU_ABRT_NOMMU) += abort-nommu.o
obj-$(CONFIG_CPU_ABRT_EV4) += abort-ev4.o
@@ -32,6 +33,7 @@ obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o
obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o
obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o
obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o
+obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o
obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o
obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o
@@ -41,6 +43,7 @@ obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o context.o
obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o
obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o
obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o
+obj-$(CONFIG_CPU_COPY_FA) += copypage-fa.o
obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o
obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o
@@ -49,6 +52,7 @@ obj-$(CONFIG_CPU_TLB_V4WBI) += tlb-v4wbi.o
obj-$(CONFIG_CPU_TLB_FEROCEON) += tlb-v4wbi.o # reuse v4wbi TLB functions
obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o
obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o
+obj-$(CONFIG_CPU_TLB_FA) += tlb-fa.o
obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o
obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o
@@ -62,6 +66,7 @@ obj-$(CONFIG_CPU_ARM925T) += proc-arm925.o
obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o
obj-$(CONFIG_CPU_ARM940T) += proc-arm940.o
obj-$(CONFIG_CPU_ARM946E) += proc-arm946.o
+obj-$(CONFIG_CPU_FA526) += proc-fa526.o
obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o
obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o
obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o
@@ -70,6 +75,7 @@ obj-$(CONFIG_CPU_SA110) += proc-sa110.o
obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o
obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o
obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o
+obj-$(CONFIG_CPU_MOHAWK) += proc-mohawk.o
obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o
obj-$(CONFIG_CPU_V6) += proc-v6.o
obj-$(CONFIG_CPU_V7) += proc-v7.o
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
index 94077fbd96b7..6f7e70907e44 100644
--- a/arch/arm/mm/abort-ev6.S
+++ b/arch/arm/mm/abort-ev6.S
@@ -29,10 +29,10 @@ ENTRY(v6_early_abort)
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
/*
- * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR.
+ * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR (erratum 326103).
* The test below covers all the write situations, including Java bytecodes
*/
- bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
+ bic r1, r1, #1 << 11 @ clear bit 11 of FSR
tst r3, #PSR_J_BIT @ Java?
movne pc, lr
do_thumb_abort
diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S
new file mode 100644
index 000000000000..b63a8f7b95cf
--- /dev/null
+++ b/arch/arm/mm/cache-fa.S
@@ -0,0 +1,220 @@
+/*
+ * linux/arch/arm/mm/cache-fa.S
+ *
+ * Copyright (C) 2005 Faraday Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on cache-v4wb.S:
+ * Copyright (C) 1997-2002 Russell king
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Processors: FA520 FA526 FA626
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/memory.h>
+#include <asm/page.h>
+
+#include "proc-macros.S"
+
+/*
+ * The size of one data cache line.
+ */
+#define CACHE_DLINESIZE 16
+
+/*
+ * The total size of the data cache.
+ */
+#ifdef CONFIG_ARCH_GEMINI
+#define CACHE_DSIZE 8192
+#else
+#define CACHE_DSIZE 16384
+#endif
+
+/* FIXME: put optimal value here. Current one is just estimation */
+#define CACHE_DLIMIT (CACHE_DSIZE * 2)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Clean and invalidate all cache entries in a particular address
+ * space.
+ */
+ENTRY(fa_flush_user_cache_all)
+ /* FALLTHROUGH */
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(fa_flush_kern_cache_all)
+ mov ip, #0
+ mov r2, #VM_EXEC
+__flush_whole_cache:
+ mcr p15, 0, ip, c7, c14, 0 @ clean/invalidate D cache
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB
+ mcrne p15, 0, ip, c7, c10, 4 @ drain write buffer
+ mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Invalidate a range of cache entries in the specified
+ * address space.
+ *
+ * - start - start address (inclusive, page aligned)
+ * - end - end address (exclusive, page aligned)
+ * - flags - vma_area_struct flags describing address space
+ */
+ENTRY(fa_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT @ total size >= limit?
+ bhs __flush_whole_cache @ flush whole D cache
+
+1: tst r2, #VM_EXEC
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I line
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB
+ mcrne p15, 0, ip, c7, c10, 4 @ data write barrier
+ mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(fa_coherent_kern_range)
+ /* fall through */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(fa_coherent_user_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_page(kaddr)
+ *
+ * Ensure that the data held in the page kaddr is written back
+ * to the page in question.
+ *
+ * - kaddr - kernel address (guaranteed to be page aligned)
+ */
+ENTRY(fa_flush_kern_dcache_page)
+ add r1, r0, #PAGE_SZ
+1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(fa_dma_inv_range)
+ tst r0, #CACHE_DLINESIZE - 1
+ bic r0, r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ bic r1, r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D entry
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean (write back) the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(fa_dma_clean_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+/*
+ * dma_flush_range(start,end)
+ * - start - virtual start address of region
+ * - end - virtual end address of region
+ */
+ENTRY(fa_dma_flush_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+ __INITDATA
+
+ .type fa_cache_fns, #object
+ENTRY(fa_cache_fns)
+ .long fa_flush_kern_cache_all
+ .long fa_flush_user_cache_all
+ .long fa_flush_user_cache_range
+ .long fa_coherent_kern_range
+ .long fa_coherent_user_range
+ .long fa_flush_kern_dcache_page
+ .long fa_dma_inv_range
+ .long fa_dma_clean_range
+ .long fa_dma_flush_range
+ .size fa_cache_fns, . - fa_cache_fns
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index 80cd207cbaea..6e77c042d8e9 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -14,8 +14,12 @@
#include <linux/init.h>
#include <asm/cacheflush.h>
+#include <asm/kmap_types.h>
+#include <asm/fixmap.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
#include <plat/cache-feroceon-l2.h>
-
+#include "mm.h"
/*
* Low-level cache maintenance operations.
@@ -34,14 +38,36 @@
* The range operations require two successive cp15 writes, in
* between which we don't want to be preempted.
*/
+
+static inline unsigned long l2_start_va(unsigned long paddr)
+{
+#ifdef CONFIG_HIGHMEM
+ /*
+ * Let's do our own fixmap stuff in a minimal way here.
+ * Because range ops can't be done on physical addresses,
+ * we simply install a virtual mapping for it only for the
+ * TLB lookup to occur, hence no need to flush the untouched
+ * memory mapping. This is protected with the disabling of
+ * interrupts by the caller.
+ */
+ unsigned long idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id();
+ unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ set_pte_ext(TOP_PTE(vaddr), pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL), 0);
+ local_flush_tlb_kernel_page(vaddr);
+ return vaddr + (paddr & ~PAGE_MASK);
+#else
+ return __phys_to_virt(paddr);
+#endif
+}
+
static inline void l2_clean_pa(unsigned long addr)
{
__asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr));
}
-static inline void l2_clean_mva_range(unsigned long start, unsigned long end)
+static inline void l2_clean_pa_range(unsigned long start, unsigned long end)
{
- unsigned long flags;
+ unsigned long va_start, va_end, flags;
/*
* Make sure 'start' and 'end' reference the same page, as
@@ -51,17 +77,14 @@ static inline void l2_clean_mva_range(unsigned long start, unsigned long end)
BUG_ON((start ^ end) >> PAGE_SHIFT);
raw_local_irq_save(flags);
+ va_start = l2_start_va(start);
+ va_end = va_start + (end - start);
__asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
"mcr p15, 1, %1, c15, c9, 5"
- : : "r" (start), "r" (end));
+ : : "r" (va_start), "r" (va_end));
raw_local_irq_restore(flags);
}
-static inline void l2_clean_pa_range(unsigned long start, unsigned long end)
-{
- l2_clean_mva_range(__phys_to_virt(start), __phys_to_virt(end));
-}
-
static inline void l2_clean_inv_pa(unsigned long addr)
{
__asm__("mcr p15, 1, %0, c15, c10, 3" : : "r" (addr));
@@ -72,9 +95,9 @@ static inline void l2_inv_pa(unsigned long addr)
__asm__("mcr p15, 1, %0, c15, c11, 3" : : "r" (addr));
}
-static inline void l2_inv_mva_range(unsigned long start, unsigned long end)
+static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
{
- unsigned long flags;
+ unsigned long va_start, va_end, flags;
/*
* Make sure 'start' and 'end' reference the same page, as
@@ -84,18 +107,19 @@ static inline void l2_inv_mva_range(unsigned long start, unsigned long end)
BUG_ON((start ^ end) >> PAGE_SHIFT);
raw_local_irq_save(flags);
+ va_start = l2_start_va(start);
+ va_end = va_start + (end - start);
__asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
"mcr p15, 1, %1, c15, c11, 5"
- : : "r" (start), "r" (end));
+ : : "r" (va_start), "r" (va_end));
raw_local_irq_restore(flags);
}
-static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
+static inline void l2_inv_all(void)
{
- l2_inv_mva_range(__phys_to_virt(start), __phys_to_virt(end));
+ __asm__("mcr p15, 1, %0, c15, c11, 0" : : "r" (0));
}
-
/*
* Linux primitives.
*
@@ -234,9 +258,7 @@ static void __init enable_dcache(void)
static void __init __invalidate_icache(void)
{
- int dummy;
-
- __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : "=r" (dummy));
+ __asm__("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
}
static int __init invalidate_and_disable_icache(void)
@@ -301,6 +323,7 @@ static void __init enable_l2(void)
d = flush_and_disable_dcache();
i = invalidate_and_disable_icache();
+ l2_inv_all();
write_extra_features(u | 0x00400000);
if (i)
enable_icache();
diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c
index 464de893a988..5d180cb0bd94 100644
--- a/arch/arm/mm/cache-xsc3l2.c
+++ b/arch/arm/mm/cache-xsc3l2.c
@@ -17,12 +17,14 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-
#include <asm/system.h>
#include <asm/cputype.h>
#include <asm/cacheflush.h>
+#include <asm/kmap_types.h>
+#include <asm/fixmap.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include "mm.h"
#define CR_L2 (1 << 26)
@@ -47,21 +49,11 @@ static inline void xsc3_l2_clean_mva(unsigned long addr)
__asm__("mcr p15, 1, %0, c7, c11, 1" : : "r" (addr));
}
-static inline void xsc3_l2_clean_pa(unsigned long addr)
-{
- xsc3_l2_clean_mva(__phys_to_virt(addr));
-}
-
static inline void xsc3_l2_inv_mva(unsigned long addr)
{
__asm__("mcr p15, 1, %0, c7, c7, 1" : : "r" (addr));
}
-static inline void xsc3_l2_inv_pa(unsigned long addr)
-{
- xsc3_l2_inv_mva(__phys_to_virt(addr));
-}
-
static inline void xsc3_l2_inv_all(void)
{
unsigned long l2ctype, set_way;
@@ -79,50 +71,103 @@ static inline void xsc3_l2_inv_all(void)
dsb();
}
+#ifdef CONFIG_HIGHMEM
+#define l2_map_save_flags(x) raw_local_save_flags(x)
+#define l2_map_restore_flags(x) raw_local_irq_restore(x)
+#else
+#define l2_map_save_flags(x) ((x) = 0)
+#define l2_map_restore_flags(x) ((void)(x))
+#endif
+
+static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va,
+ unsigned long flags)
+{
+#ifdef CONFIG_HIGHMEM
+ unsigned long va = prev_va & PAGE_MASK;
+ unsigned long pa_offset = pa << (32 - PAGE_SHIFT);
+ if (unlikely(pa_offset < (prev_va << (32 - PAGE_SHIFT)))) {
+ /*
+ * Switching to a new page. Because cache ops are
+ * using virtual addresses only, we must put a mapping
+ * in place for it. We also enable interrupts for a
+ * short while and disable them again to protect this
+ * mapping.
+ */
+ unsigned long idx;
+ raw_local_irq_restore(flags);
+ idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id();
+ va = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ raw_local_irq_restore(flags | PSR_I_BIT);
+ set_pte_ext(TOP_PTE(va), pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL), 0);
+ local_flush_tlb_kernel_page(va);
+ }
+ return va + (pa_offset >> (32 - PAGE_SHIFT));
+#else
+ return __phys_to_virt(pa);
+#endif
+}
+
static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
{
+ unsigned long vaddr, flags;
+
if (start == 0 && end == -1ul) {
xsc3_l2_inv_all();
return;
}
+ vaddr = -1; /* to force the first mapping */
+ l2_map_save_flags(flags);
+
/*
* Clean and invalidate partial first cache line.
*/
if (start & (CACHE_LINE_SIZE - 1)) {
- xsc3_l2_clean_pa(start & ~(CACHE_LINE_SIZE - 1));
- xsc3_l2_inv_pa(start & ~(CACHE_LINE_SIZE - 1));
+ vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr, flags);
+ xsc3_l2_clean_mva(vaddr);
+ xsc3_l2_inv_mva(vaddr);
start = (start | (CACHE_LINE_SIZE - 1)) + 1;
}
/*
- * Clean and invalidate partial last cache line.
+ * Invalidate all full cache lines between 'start' and 'end'.
*/
- if (start < end && (end & (CACHE_LINE_SIZE - 1))) {
- xsc3_l2_clean_pa(end & ~(CACHE_LINE_SIZE - 1));
- xsc3_l2_inv_pa(end & ~(CACHE_LINE_SIZE - 1));
- end &= ~(CACHE_LINE_SIZE - 1);
+ while (start < (end & ~(CACHE_LINE_SIZE - 1))) {
+ vaddr = l2_map_va(start, vaddr, flags);
+ xsc3_l2_inv_mva(vaddr);
+ start += CACHE_LINE_SIZE;
}
/*
- * Invalidate all full cache lines between 'start' and 'end'.
+ * Clean and invalidate partial last cache line.
*/
- while (start < end) {
- xsc3_l2_inv_pa(start);
- start += CACHE_LINE_SIZE;
+ if (start < end) {
+ vaddr = l2_map_va(start, vaddr, flags);
+ xsc3_l2_clean_mva(vaddr);
+ xsc3_l2_inv_mva(vaddr);
}
+ l2_map_restore_flags(flags);
+
dsb();
}
static void xsc3_l2_clean_range(unsigned long start, unsigned long end)
{
+ unsigned long vaddr, flags;
+
+ vaddr = -1; /* to force the first mapping */
+ l2_map_save_flags(flags);
+
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
- xsc3_l2_clean_pa(start);
+ vaddr = l2_map_va(start, vaddr, flags);
+ xsc3_l2_clean_mva(vaddr);
start += CACHE_LINE_SIZE;
}
+ l2_map_restore_flags(flags);
+
dsb();
}
@@ -148,18 +193,26 @@ static inline void xsc3_l2_flush_all(void)
static void xsc3_l2_flush_range(unsigned long start, unsigned long end)
{
+ unsigned long vaddr, flags;
+
if (start == 0 && end == -1ul) {
xsc3_l2_flush_all();
return;
}
+ vaddr = -1; /* to force the first mapping */
+ l2_map_save_flags(flags);
+
start &= ~(CACHE_LINE_SIZE - 1);
while (start < end) {
- xsc3_l2_clean_pa(start);
- xsc3_l2_inv_pa(start);
+ vaddr = l2_map_va(start, vaddr, flags);
+ xsc3_l2_clean_mva(vaddr);
+ xsc3_l2_inv_mva(vaddr);
start += CACHE_LINE_SIZE;
}
+ l2_map_restore_flags(flags);
+
dsb();
}
diff --git a/arch/arm/mm/copypage-fa.c b/arch/arm/mm/copypage-fa.c
new file mode 100644
index 000000000000..b2a6008b0111
--- /dev/null
+++ b/arch/arm/mm/copypage-fa.c
@@ -0,0 +1,86 @@
+/*
+ * linux/arch/arm/lib/copypage-fa.S
+ *
+ * Copyright (C) 2005 Faraday Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on copypage-v4wb.S:
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/highmem.h>
+
+/*
+ * Faraday optimised copy_user_page
+ */
+static void __naked
+fa_copy_user_page(void *kto, const void *kfrom)
+{
+ asm("\
+ stmfd sp!, {r4, lr} @ 2\n\
+ mov r2, %0 @ 1\n\
+1: ldmia r1!, {r3, r4, ip, lr} @ 4\n\
+ stmia r0, {r3, r4, ip, lr} @ 4\n\
+ mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\
+ add r0, r0, #16 @ 1\n\
+ ldmia r1!, {r3, r4, ip, lr} @ 4\n\
+ stmia r0, {r3, r4, ip, lr} @ 4\n\
+ mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\
+ add r0, r0, #16 @ 1\n\
+ subs r2, r2, #1 @ 1\n\
+ bne 1b @ 1\n\
+ mcr p15, 0, r2, c7, c10, 4 @ 1 drain WB\n\
+ ldmfd sp!, {r4, pc} @ 3"
+ :
+ : "I" (PAGE_SIZE / 32));
+}
+
+void fa_copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr)
+{
+ void *kto, *kfrom;
+
+ kto = kmap_atomic(to, KM_USER0);
+ kfrom = kmap_atomic(from, KM_USER1);
+ fa_copy_user_page(kto, kfrom);
+ kunmap_atomic(kfrom, KM_USER1);
+ kunmap_atomic(kto, KM_USER0);
+}
+
+/*
+ * Faraday optimised clear_user_page
+ *
+ * Same story as above.
+ */
+void fa_clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+ void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+ asm volatile("\
+ mov r1, %2 @ 1\n\
+ mov r2, #0 @ 1\n\
+ mov r3, #0 @ 1\n\
+ mov ip, #0 @ 1\n\
+ mov lr, #0 @ 1\n\
+1: stmia %0, {r2, r3, ip, lr} @ 4\n\
+ mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
+ add %0, %0, #16 @ 1\n\
+ stmia %0, {r2, r3, ip, lr} @ 4\n\
+ mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
+ add %0, %0, #16 @ 1\n\
+ subs r1, r1, #1 @ 1\n\
+ bne 1b @ 1\n\
+ mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB"
+ : "=r" (ptr)
+ : "0" (kaddr), "I" (PAGE_SIZE / 32)
+ : "r1", "r2", "r3", "ip", "lr");
+ kunmap_atomic(kaddr, KM_USER0);
+}
+
+struct cpu_user_fns fa_user_fns __initdata = {
+ .cpu_clear_user_highpage = fa_clear_user_highpage,
+ .cpu_copy_user_highpage = fa_copy_user_highpage,
+};
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index f1ef5613ccd4..510c179b0ac8 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -19,6 +19,7 @@
#include <linux/dma-mapping.h>
#include <asm/memory.h>
+#include <asm/highmem.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm/sizes.h>
@@ -517,6 +518,74 @@ void dma_cache_maint(const void *start, size_t size, int direction)
}
EXPORT_SYMBOL(dma_cache_maint);
+static void dma_cache_maint_contiguous(struct page *page, unsigned long offset,
+ size_t size, int direction)
+{
+ void *vaddr;
+ unsigned long paddr;
+ void (*inner_op)(const void *, const void *);
+ void (*outer_op)(unsigned long, unsigned long);
+
+ switch (direction) {
+ case DMA_FROM_DEVICE: /* invalidate only */
+ inner_op = dmac_inv_range;
+ outer_op = outer_inv_range;
+ break;
+ case DMA_TO_DEVICE: /* writeback only */
+ inner_op = dmac_clean_range;
+ outer_op = outer_clean_range;
+ break;
+ case DMA_BIDIRECTIONAL: /* writeback and invalidate */
+ inner_op = dmac_flush_range;
+ outer_op = outer_flush_range;
+ break;
+ default:
+ BUG();
+ }
+
+ if (!PageHighMem(page)) {
+ vaddr = page_address(page) + offset;
+ inner_op(vaddr, vaddr + size);
+ } else {
+ vaddr = kmap_high_get(page);
+ if (vaddr) {
+ vaddr += offset;
+ inner_op(vaddr, vaddr + size);
+ kunmap_high(page);
+ }
+ }
+
+ paddr = page_to_phys(page) + offset;
+ outer_op(paddr, paddr + size);
+}
+
+void dma_cache_maint_page(struct page *page, unsigned long offset,
+ size_t size, int dir)
+{
+ /*
+ * A single sg entry may refer to multiple physically contiguous
+ * pages. But we still need to process highmem pages individually.
+ * If highmem is not configured then the bulk of this loop gets
+ * optimized out.
+ */
+ size_t left = size;
+ do {
+ size_t len = left;
+ if (PageHighMem(page) && len + offset > PAGE_SIZE) {
+ if (offset >= PAGE_SIZE) {
+ page += offset / PAGE_SIZE;
+ offset %= PAGE_SIZE;
+ }
+ len = PAGE_SIZE - offset;
+ }
+ dma_cache_maint_contiguous(page, offset, len, dir);
+ offset = 0;
+ page++;
+ left -= len;
+ } while (left);
+}
+EXPORT_SYMBOL(dma_cache_maint_page);
+
/**
* dma_map_sg - map a set of SG buffers for streaming mode DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
@@ -614,7 +683,8 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
continue;
if (!arch_is_coherent())
- dma_cache_maint(sg_virt(s), s->length, dir);
+ dma_cache_maint_page(sg_page(s), s->offset,
+ s->length, dir);
}
}
EXPORT_SYMBOL(dma_sync_sg_for_device);
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 0fa9bf388f0b..4e283481cee1 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -192,7 +192,7 @@ void flush_dcache_page(struct page *page)
struct address_space *mapping = page_mapping(page);
#ifndef CONFIG_SMP
- if (mapping && !mapping_mapped(mapping))
+ if (!PageHighMem(page) && mapping && !mapping_mapped(mapping))
set_bit(PG_dcache_dirty, &page->flags);
else
#endif
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
new file mode 100644
index 000000000000..a34954d9df7d
--- /dev/null
+++ b/arch/arm/mm/highmem.c
@@ -0,0 +1,116 @@
+/*
+ * arch/arm/mm/highmem.c -- ARM highmem support
+ *
+ * Author: Nicolas Pitre
+ * Created: september 8, 2008
+ * Copyright: Marvell Semiconductors Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/highmem.h>
+#include <linux/interrupt.h>
+#include <asm/fixmap.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include "mm.h"
+
+void *kmap(struct page *page)
+{
+ might_sleep();
+ if (!PageHighMem(page))
+ return page_address(page);
+ return kmap_high(page);
+}
+EXPORT_SYMBOL(kmap);
+
+void kunmap(struct page *page)
+{
+ BUG_ON(in_interrupt());
+ if (!PageHighMem(page))
+ return;
+ kunmap_high(page);
+}
+EXPORT_SYMBOL(kunmap);
+
+void *kmap_atomic(struct page *page, enum km_type type)
+{
+ unsigned int idx;
+ unsigned long vaddr;
+
+ pagefault_disable();
+ if (!PageHighMem(page))
+ return page_address(page);
+
+ idx = type + KM_TYPE_NR * smp_processor_id();
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+#ifdef CONFIG_DEBUG_HIGHMEM
+ /*
+ * With debugging enabled, kunmap_atomic forces that entry to 0.
+ * Make sure it was indeed properly unmapped.
+ */
+ BUG_ON(!pte_none(*(TOP_PTE(vaddr))));
+#endif
+ set_pte_ext(TOP_PTE(vaddr), mk_pte(page, kmap_prot), 0);
+ /*
+ * When debugging is off, kunmap_atomic leaves the previous mapping
+ * in place, so this TLB flush ensures the TLB is updated with the
+ * new mapping.
+ */
+ local_flush_tlb_kernel_page(vaddr);
+
+ return (void *)vaddr;
+}
+EXPORT_SYMBOL(kmap_atomic);
+
+void kunmap_atomic(void *kvaddr, enum km_type type)
+{
+ unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
+ unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
+
+ if (kvaddr >= (void *)FIXADDR_START) {
+ __cpuc_flush_dcache_page((void *)vaddr);
+#ifdef CONFIG_DEBUG_HIGHMEM
+ BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+ set_pte_ext(TOP_PTE(vaddr), __pte(0), 0);
+ local_flush_tlb_kernel_page(vaddr);
+#else
+ (void) idx; /* to kill a warning */
+#endif
+ }
+ pagefault_enable();
+}
+EXPORT_SYMBOL(kunmap_atomic);
+
+void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
+{
+ unsigned int idx;
+ unsigned long vaddr;
+
+ pagefault_disable();
+
+ idx = type + KM_TYPE_NR * smp_processor_id();
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+#ifdef CONFIG_DEBUG_HIGHMEM
+ BUG_ON(!pte_none(*(TOP_PTE(vaddr))));
+#endif
+ set_pte_ext(TOP_PTE(vaddr), pfn_pte(pfn, kmap_prot), 0);
+ local_flush_tlb_kernel_page(vaddr);
+
+ return (void *)vaddr;
+}
+
+struct page *kmap_atomic_to_page(const void *ptr)
+{
+ unsigned long vaddr = (unsigned long)ptr;
+ pte_t *pte;
+
+ if (vaddr < FIXADDR_START)
+ return virt_to_page(ptr);
+
+ pte = TOP_PTE(vaddr);
+ return pte_page(*pte);
+}
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 80fd3b69ae1f..8277802ec859 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -15,6 +15,7 @@
#include <linux/mman.h>
#include <linux/nodemask.h>
#include <linux/initrd.h>
+#include <linux/highmem.h>
#include <asm/mach-types.h>
#include <asm/sections.h>
@@ -485,7 +486,7 @@ void __init mem_init(void)
int i, node;
#ifndef CONFIG_DISCONTIGMEM
- max_mapnr = virt_to_page(high_memory) - mem_map;
+ max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
#endif
/* this will put all unused low memory onto the freelists */
@@ -504,6 +505,19 @@ void __init mem_init(void)
__phys_to_pfn(__pa(swapper_pg_dir)), NULL);
#endif
+#ifdef CONFIG_HIGHMEM
+ /* set highmem page free */
+ for_each_online_node(node) {
+ for_each_nodebank (i, &meminfo, node) {
+ unsigned long start = bank_pfn_start(&meminfo.bank[i]);
+ unsigned long end = bank_pfn_end(&meminfo.bank[i]);
+ if (start >= max_low_pfn + PHYS_PFN_OFFSET)
+ totalhigh_pages += free_area(start, end, NULL);
+ }
+ }
+ totalram_pages += totalhigh_pages;
+#endif
+
/*
* Since our memory may not be contiguous, calculate the
* real number of pages we have in this system
@@ -521,9 +535,10 @@ void __init mem_init(void)
initsize = __init_end - __init_begin;
printk(KERN_NOTICE "Memory: %luKB available (%dK code, "
- "%dK data, %dK init)\n",
+ "%dK data, %dK init, %luK highmem)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
- codesize >> 10, datasize >> 10, initsize >> 10);
+ codesize >> 10, datasize >> 10, initsize >> 10,
+ (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
extern int sysctl_overcommit_memory;
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 95bbe112965e..c4f6f05198e0 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -1,7 +1,6 @@
-/* the upper-most page table pointer */
-
#ifdef CONFIG_MMU
+/* the upper-most page table pointer */
extern pmd_t *top_pmd;
#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index d4d082c5c2d4..b438fc4fb77b 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -18,9 +18,11 @@
#include <asm/cputype.h>
#include <asm/mach-types.h>
#include <asm/sections.h>
+#include <asm/cachetype.h>
#include <asm/setup.h>
#include <asm/sizes.h>
#include <asm/tlb.h>
+#include <asm/highmem.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -243,6 +245,10 @@ static struct mem_type mem_types[] = {
.prot_sect = PMD_TYPE_SECT,
.domain = DOMAIN_KERNEL,
},
+ [MT_MEMORY_NONCACHED] = {
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+ .domain = DOMAIN_KERNEL,
+ },
};
const struct mem_type *get_mem_type(unsigned int type)
@@ -406,9 +412,28 @@ static void __init build_mem_type_table(void)
kern_pgprot |= L_PTE_SHARED;
vecs_pgprot |= L_PTE_SHARED;
mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
#endif
}
+ /*
+ * Non-cacheable Normal - intended for memory areas that must
+ * not cause dirty cache line writebacks when used
+ */
+ if (cpu_arch >= CPU_ARCH_ARMv6) {
+ if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
+ /* Non-cacheable Normal is XCB = 001 */
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |=
+ PMD_SECT_BUFFERED;
+ } else {
+ /* For both ARMv6 and non-TEX-remapping ARMv7 */
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |=
+ PMD_SECT_TEX(1);
+ }
+ } else {
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
+ }
+
for (i = 0; i < 16; i++) {
unsigned long v = pgprot_val(protection_map[i]);
protection_map[i] = __pgprot(v | user_pgprot);
@@ -677,6 +702,10 @@ static void __init sanity_check_meminfo(void)
if (meminfo.nr_banks >= NR_BANKS) {
printk(KERN_CRIT "NR_BANKS too low, "
"ignoring high memory\n");
+ } else if (cache_is_vipt_aliasing()) {
+ printk(KERN_CRIT "HIGHMEM is not yet supported "
+ "with VIPT aliasing cache, "
+ "ignoring high memory\n");
} else {
memmove(bank + 1, bank,
(meminfo.nr_banks - i) * sizeof(*bank));
@@ -694,7 +723,7 @@ static void __init sanity_check_meminfo(void)
* the vmalloc area.
*/
if (__va(bank->start) >= VMALLOC_MIN ||
- __va(bank->start) < PAGE_OFFSET) {
+ __va(bank->start) < (void *)PAGE_OFFSET) {
printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
"(vmalloc region overlap).\n",
bank->start, bank->start + bank->size - 1);
@@ -895,6 +924,17 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
flush_cache_all();
}
+static void __init kmap_init(void)
+{
+#ifdef CONFIG_HIGHMEM
+ pmd_t *pmd = pmd_off_k(PKMAP_BASE);
+ pte_t *pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
+ BUG_ON(!pmd_none(*pmd) || !pte);
+ __pmd_populate(pmd, __pa(pte) | _PAGE_KERNEL_TABLE);
+ pkmap_page_table = pte + PTRS_PER_PTE;
+#endif
+}
+
/*
* paging_init() sets up the page tables, initialises the zone memory
* maps, and sets up the zero page, bad page and bad page tables.
@@ -908,6 +948,7 @@ void __init paging_init(struct machine_desc *mdesc)
prepare_page_table();
bootmem_init();
devicemaps_init(mdesc);
+ kmap_init();
top_pmd = pmd_off_k(0xffff0000);
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
new file mode 100644
index 000000000000..08b8a955d5d7
--- /dev/null
+++ b/arch/arm/mm/proc-fa526.S
@@ -0,0 +1,248 @@
+/*
+ * linux/arch/arm/mm/proc-fa526.S: MMU functions for FA526
+ *
+ * Written by : Luke Lee
+ * Copyright (C) 2005 Faraday Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the fa526.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+
+#include "proc-macros.S"
+
+#define CACHE_DLINESIZE 16
+
+ .text
+/*
+ * cpu_fa526_proc_init()
+ */
+ENTRY(cpu_fa526_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_fa526_proc_fin()
+ */
+ENTRY(cpu_fa526_proc_fin)
+ stmfd sp!, {lr}
+ mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
+ msr cpsr_c, ip
+ bl fa_flush_kern_cache_all
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ nop
+ nop
+ ldmfd sp!, {pc}
+
+/*
+ * cpu_fa526_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 4
+ENTRY(cpu_fa526_reset)
+/* TODO: Use CP8 if possible... */
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ bic ip, ip, #0x0800 @ BTB off
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ nop
+ nop
+ mov pc, r0
+
+/*
+ * cpu_fa526_do_idle()
+ */
+ .align 4
+ENTRY(cpu_fa526_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ mov pc, lr
+
+
+ENTRY(cpu_fa526_dcache_clean_area)
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_fa526_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 4
+ENTRY(cpu_fa526_switch_mm)
+#ifdef CONFIG_MMU
+ mov ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+#else
+ mcr p15, 0, ip, c7, c14, 0 @ clean and invalidate whole D cache
+#endif
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c5, 6 @ invalidate BTB since mm changed
+ mcr p15, 0, ip, c7, c10, 4 @ data write barrier
+ mcr p15, 0, ip, c7, c5, 4 @ prefetch flush
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate UTLB
+#endif
+ mov pc, lr
+
+/*
+ * cpu_fa526_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 4
+ENTRY(cpu_fa526_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext
+ mov r0, r0
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+#endif
+ mov pc, lr
+
+ __INIT
+
+ .type __fa526_setup, #function
+__fa526_setup:
+ /* On return of this routine, r0 must carry correct flags for CFG register */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+#endif
+ mcr p15, 0, r0, c7, c5, 5 @ invalidate IScratchpad RAM
+
+ mov r0, #1
+ mcr p15, 0, r0, c1, c1, 0 @ turn-on ECR
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB All
+ mcr p15, 0, r0, c7, c10, 4 @ data write barrier
+ mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
+
+ mov r0, #0x1f @ Domains 0, 1 = manager, 2 = client
+ mcr p15, 0, r0, c3, c0 @ load domain access register
+
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ ldr r5, fa526_cr1_clear
+ bic r0, r0, r5
+ ldr r5, fa526_cr1_set
+ orr r0, r0, r5
+ mov pc, lr
+ .size __fa526_setup, . - __fa526_setup
+
+ /*
+ * .RVI ZFRS BLDP WCAM
+ * ..11 1001 .111 1101
+ *
+ */
+ .type fa526_cr1_clear, #object
+ .type fa526_cr1_set, #object
+fa526_cr1_clear:
+ .word 0x3f3f
+fa526_cr1_set:
+ .word 0x397D
+
+ __INITDATA
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ * come through these
+ */
+ .type fa526_processor_functions, #object
+fa526_processor_functions:
+ .word v4_early_abort
+ .word pabort_noifar
+ .word cpu_fa526_proc_init
+ .word cpu_fa526_proc_fin
+ .word cpu_fa526_reset
+ .word cpu_fa526_do_idle
+ .word cpu_fa526_dcache_clean_area
+ .word cpu_fa526_switch_mm
+ .word cpu_fa526_set_pte_ext
+ .size fa526_processor_functions, . - fa526_processor_functions
+
+ .section ".rodata"
+
+ .type cpu_arch_name, #object
+cpu_arch_name:
+ .asciz "armv4"
+ .size cpu_arch_name, . - cpu_arch_name
+
+ .type cpu_elf_name, #object
+cpu_elf_name:
+ .asciz "v4"
+ .size cpu_elf_name, . - cpu_elf_name
+
+ .type cpu_fa526_name, #object
+cpu_fa526_name:
+ .asciz "FA526"
+ .size cpu_fa526_name, . - cpu_fa526_name
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __fa526_proc_info,#object
+__fa526_proc_info:
+ .long 0x66015261
+ .long 0xff01fff1
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | \
+ PMD_BIT4 | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ .long PMD_TYPE_SECT | \
+ PMD_BIT4 | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ b __fa526_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF
+ .long cpu_fa526_name
+ .long fa526_processor_functions
+ .long fa_tlb_fns
+ .long fa_user_fns
+ .long fa_cache_fns
+ .size __fa526_proc_info, . - __fa526_proc_info
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
new file mode 100644
index 000000000000..540f5078496b
--- /dev/null
+++ b/arch/arm/mm/proc-mohawk.S
@@ -0,0 +1,416 @@
+/*
+ * linux/arch/arm/mm/proc-mohawk.S: MMU functions for Marvell PJ1 core
+ *
+ * PJ1 (codename Mohawk) is a hybrid of the xscale3 and Marvell's own core.
+ *
+ * Heavily based on proc-arm926.S and proc-xsc3.S
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be flushed. If the
+ * area is larger than this, then we flush the whole cache.
+ */
+#define CACHE_DLIMIT 32768
+
+/*
+ * The cache line size of the L1 D cache.
+ */
+#define CACHE_DLINESIZE 32
+
+/*
+ * cpu_mohawk_proc_init()
+ */
+ENTRY(cpu_mohawk_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_mohawk_proc_fin()
+ */
+ENTRY(cpu_mohawk_proc_fin)
+ stmfd sp!, {lr}
+ mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
+ msr cpsr_c, ip
+ bl mohawk_flush_kern_cache_all
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1800 @ ...iz...........
+ bic r0, r0, #0x0006 @ .............ca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ ldmfd sp!, {pc}
+
+/*
+ * cpu_mohawk_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ *
+ * (same as arm926)
+ */
+ .align 5
+ENTRY(cpu_mohawk_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x0007 @ .............cam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_mohawk_do_idle()
+ *
+ * Called with IRQs disabled
+ */
+ .align 5
+ENTRY(cpu_mohawk_do_idle)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
+ mov pc, lr
+
+/*
+ * flush_user_cache_all()
+ *
+ * Clean and invalidate all cache entries in a particular
+ * address space.
+ */
+ENTRY(mohawk_flush_user_cache_all)
+ /* FALLTHROUGH */
+
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(mohawk_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+ mcr p15, 0, ip, c7, c14, 0 @ clean & invalidate all D cache
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcrne p15, 0, ip, c7, c10, 0 @ drain write buffer
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Clean and invalidate a range of cache entries in the
+ * specified address range.
+ *
+ * - start - start address (inclusive)
+ * - end - end address (exclusive)
+ * - flags - vm_flags describing address space
+ *
+ * (same as arm926)
+ */
+ENTRY(mohawk_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT
+ bgt __flush_whole_cache
+1: tst r2, #VM_EXEC
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(mohawk_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as arm926)
+ */
+ENTRY(mohawk_coherent_user_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_page(void *page)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - page aligned address
+ */
+ENTRY(mohawk_flush_kern_dcache_page)
+ add r1, r0, #PAGE_SZ
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+ENTRY(mohawk_dma_inv_range)
+ tst r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+ENTRY(mohawk_dma_clean_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(mohawk_dma_flush_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1:
+ mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+ENTRY(mohawk_cache_fns)
+ .long mohawk_flush_kern_cache_all
+ .long mohawk_flush_user_cache_all
+ .long mohawk_flush_user_cache_range
+ .long mohawk_coherent_kern_range
+ .long mohawk_coherent_user_range
+ .long mohawk_flush_kern_dcache_page
+ .long mohawk_dma_inv_range
+ .long mohawk_dma_clean_range
+ .long mohawk_dma_flush_range
+
+ENTRY(cpu_mohawk_dcache_clean_area)
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * cpu_mohawk_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_mohawk_switch_mm)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c14, 0 @ clean & invalidate all D cache
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ orr r0, r0, #0x18 @ cache the page table in L2
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mov pc, lr
+
+/*
+ * cpu_mohawk_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_mohawk_set_pte_ext)
+ armv3_set_pte_ext
+ mov r0, r0
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+ __INIT
+
+ .type __mohawk_setup, #function
+__mohawk_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs
+ orr r4, r4, #0x18 @ cache the page table in L2
+ mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
+
+ mov r0, #0 @ don't allow CP access
+ mcr p15, 0, r0, c15, c1, 0 @ write CP access register
+
+ adr r5, mohawk_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register
+ bic r0, r0, r5
+ orr r0, r0, r6
+ mov pc, lr
+
+ .size __mohawk_setup, . - __mohawk_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * .011 1001 ..00 0101
+ *
+ */
+ .type mohawk_crval, #object
+mohawk_crval:
+ crval clear=0x00007f3f, mmuset=0x00003905, ucset=0x00001134
+
+ __INITDATA
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ * come through these
+ */
+ .type mohawk_processor_functions, #object
+mohawk_processor_functions:
+ .word v5t_early_abort
+ .word pabort_noifar
+ .word cpu_mohawk_proc_init
+ .word cpu_mohawk_proc_fin
+ .word cpu_mohawk_reset
+ .word cpu_mohawk_do_idle
+ .word cpu_mohawk_dcache_clean_area
+ .word cpu_mohawk_switch_mm
+ .word cpu_mohawk_set_pte_ext
+ .size mohawk_processor_functions, . - mohawk_processor_functions
+
+ .section ".rodata"
+
+ .type cpu_arch_name, #object
+cpu_arch_name:
+ .asciz "armv5te"
+ .size cpu_arch_name, . - cpu_arch_name
+
+ .type cpu_elf_name, #object
+cpu_elf_name:
+ .asciz "v5"
+ .size cpu_elf_name, . - cpu_elf_name
+
+ .type cpu_mohawk_name, #object
+cpu_mohawk_name:
+ .asciz "Marvell 88SV331x"
+ .size cpu_mohawk_name, . - cpu_mohawk_name
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __88sv331x_proc_info,#object
+__88sv331x_proc_info:
+ .long 0x56158000 @ Marvell 88SV331x (MOHAWK)
+ .long 0xfffff000
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | \
+ PMD_BIT4 | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ .long PMD_TYPE_SECT | \
+ PMD_BIT4 | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ b __mohawk_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+ .long cpu_mohawk_name
+ .long mohawk_processor_functions
+ .long v4wbi_tlb_fns
+ .long v4wb_user_fns
+ .long mohawk_cache_fns
+ .size __88sv331x_proc_info, . - __88sv331x_proc_info
diff --git a/arch/arm/mm/tlb-fa.S b/arch/arm/mm/tlb-fa.S
new file mode 100644
index 000000000000..9694f1f6f485
--- /dev/null
+++ b/arch/arm/mm/tlb-fa.S
@@ -0,0 +1,75 @@
+/*
+ * linux/arch/arm/mm/tlb-fa.S
+ *
+ * Copyright (C) 2005 Faraday Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on tlb-v4wbi.S:
+ * Copyright (C) 1997-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ARM architecture version 4, Faraday variation.
+ * This assume an unified TLBs, with a write buffer, and branch target buffer (BTB)
+ *
+ * Processors: FA520 FA526 FA626
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+#include <asm/tlbflush.h>
+#include "proc-macros.S"
+
+
+/*
+ * flush_user_tlb_range(start, end, mm)
+ *
+ * Invalidate a range of TLB entries in the specified address space.
+ *
+ * - start - range start address
+ * - end - range end address
+ * - mm - mm_struct describing address space
+ */
+ .align 4
+ENTRY(fa_flush_user_tlb_range)
+ vma_vm_mm ip, r2
+ act_mm r3 @ get current->active_mm
+ eors r3, ip, r3 @ == mm ?
+ movne pc, lr @ no, we dont do anything
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+ bic r0, r0, #0x0ff
+ bic r0, r0, #0xf00
+1: mcr p15, 0, r0, c8, c7, 1 @ invalidate UTLB entry
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB
+ mcr p15, 0, r3, c7, c10, 4 @ data write barrier
+ mov pc, lr
+
+
+ENTRY(fa_flush_kern_tlb_range)
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+ bic r0, r0, #0x0ff
+ bic r0, r0, #0xf00
+1: mcr p15, 0, r0, c8, c7, 1 @ invalidate UTLB entry
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB
+ mcr p15, 0, r3, c7, c10, 4 @ data write barrier
+ mcr p15, 0, r3, c7, c5, 4 @ prefetch flush
+ mov pc, lr
+
+ __INITDATA
+
+ .type fa_tlb_fns, #object
+ENTRY(fa_tlb_fns)
+ .long fa_flush_user_tlb_range
+ .long fa_flush_kern_tlb_range
+ .long fa_tlb_flags
+ .size fa_tlb_fns, . - fa_tlb_fns
diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c
index cefc21c2eee4..d805a52b5032 100644
--- a/arch/arm/oprofile/backtrace.c
+++ b/arch/arm/oprofile/backtrace.c
@@ -18,15 +18,14 @@
#include <linux/mm.h>
#include <linux/uaccess.h>
#include <asm/ptrace.h>
-
-#include "../kernel/stacktrace.h"
+#include <asm/stacktrace.h>
static int report_trace(struct stackframe *frame, void *d)
{
unsigned int *depth = d;
if (*depth) {
- oprofile_add_trace(frame->lr);
+ oprofile_add_trace(frame->pc);
(*depth)--;
}
@@ -70,9 +69,12 @@ void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1;
if (!user_mode(regs)) {
- unsigned long base = ((unsigned long)regs) & ~(THREAD_SIZE - 1);
- walk_stackframe(regs->ARM_fp, base, base + THREAD_SIZE,
- report_trace, &depth);
+ struct stackframe frame;
+ frame.fp = regs->ARM_fp;
+ frame.sp = regs->ARM_sp;
+ frame.lr = regs->ARM_lr;
+ frame.pc = regs->ARM_pc;
+ walk_stackframe(&frame, report_trace, &depth);
return;
}
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 9cc2b16fdf79..17d0e9906d5f 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -3,7 +3,7 @@ if ARCH_MXC
menu "Freescale MXC Implementations"
choice
- prompt "MXC/iMX Base Type"
+ prompt "Freescale CPU family:"
default ARCH_MX3
config ARCH_MX1
@@ -15,12 +15,14 @@ config ARCH_MX1
config ARCH_MX2
bool "MX2-based"
select CPU_ARM926T
+ select COMMON_CLKDEV
help
This enables support for systems based on the Freescale i.MX2 family
config ARCH_MX3
bool "MX3-based"
select CPU_V6
+ select COMMON_CLKDEV
help
This enables support for systems based on the Freescale i.MX3 family
@@ -43,4 +45,10 @@ config MXC_IRQ_PRIOR
requirements for timing.
Say N here, unless you have a specialized requirement.
+config MXC_PWM
+ tristate "Enable PWM driver"
+ depends on ARCH_MXC
+ help
+ Enable support for the i.MX PWM controller(s).
+
endif
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index db74a929179d..055406312b69 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -3,7 +3,8 @@
#
# Common support
-obj-y := irq.o clock.o gpio.o time.o devices.o
+obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o
obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o
obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
+obj-$(CONFIG_MXC_PWM) += pwm.o
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 0a38f0b396eb..92e13566cd4f 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -48,6 +48,11 @@ static DEFINE_MUTEX(clocks_mutex);
*-------------------------------------------------------------------------*/
/*
+ * All the code inside #ifndef CONFIG_COMMON_CLKDEV can be removed once all
+ * MXC architectures have switched to using clkdev.
+ */
+#ifndef CONFIG_COMMON_CLKDEV
+/*
* Retrieve a clock by name.
*
* Note that we first try to use device id on the bus
@@ -110,6 +115,7 @@ found:
return clk;
}
EXPORT_SYMBOL(clk_get);
+#endif
static void __clk_disable(struct clk *clk)
{
@@ -187,6 +193,7 @@ unsigned long clk_get_rate(struct clk *clk)
}
EXPORT_SYMBOL(clk_get_rate);
+#ifndef CONFIG_COMMON_CLKDEV
/* Decrement the clock's module reference count */
void clk_put(struct clk *clk)
{
@@ -194,6 +201,7 @@ void clk_put(struct clk *clk)
module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
+#endif
/* Round the requested clock rate to the nearest supported
* rate that is less than or equal to the requested rate.
@@ -257,6 +265,7 @@ struct clk *clk_get_parent(struct clk *clk)
}
EXPORT_SYMBOL(clk_get_parent);
+#ifndef CONFIG_COMMON_CLKDEV
/*
* Add a new clock to the clock tree.
*/
@@ -327,4 +336,49 @@ static int __init mxc_setup_proc_entry(void)
}
late_initcall(mxc_setup_proc_entry);
+#endif /* CONFIG_PROC_FS */
+#endif
+
+/*
+ * Get the resulting clock rate from a PLL register value and the input
+ * frequency. PLLs with this register layout can at least be found on
+ * MX1, MX21, MX27 and MX31
+ *
+ * mfi + mfn / (mfd + 1)
+ * f = 2 * f_ref * --------------------
+ * pd + 1
+ */
+unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq)
+{
+ long long ll;
+ int mfn_abs;
+ unsigned int mfi, mfn, mfd, pd;
+
+ mfi = (reg_val >> 10) & 0xf;
+ mfn = reg_val & 0x3ff;
+ mfd = (reg_val >> 16) & 0x3ff;
+ pd = (reg_val >> 26) & 0xf;
+
+ mfi = mfi <= 5 ? 5 : mfi;
+
+ mfn_abs = mfn;
+
+#if !defined CONFIG_ARCH_MX1 && !defined CONFIG_ARCH_MX21
+ if (mfn >= 0x200) {
+ mfn |= 0xFFFFFE00;
+ mfn_abs = -mfn;
+ }
#endif
+
+ freq *= 2;
+ freq /= pd + 1;
+
+ ll = (unsigned long long)freq * mfn_abs;
+
+ do_div(ll, mfd + 1);
+ if (mfn < 0)
+ ll = -ll;
+ ll = (freq * mfi) + ll;
+
+ return ll;
+}
diff --git a/arch/arm/plat-mxc/cpu.c b/arch/arm/plat-mxc/cpu.c
new file mode 100644
index 000000000000..386e0d52cf58
--- /dev/null
+++ b/arch/arm/plat-mxc/cpu.c
@@ -0,0 +1,11 @@
+
+#include <linux/module.h>
+
+unsigned int __mxc_cpu_type;
+EXPORT_SYMBOL(__mxc_cpu_type);
+
+void mxc_set_cpu_type(unsigned int type)
+{
+ __mxc_cpu_type = type;
+}
+
diff --git a/arch/arm/plat-mxc/devices.c b/arch/arm/plat-mxc/devices.c
index c66748267c45..56f2fb5cc456 100644
--- a/arch/arm/plat-mxc/devices.c
+++ b/arch/arm/plat-mxc/devices.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <mach/common.h>
int __init mxc_register_device(struct platform_device *pdev, void *data)
{
diff --git a/arch/arm/plat-mxc/dma-mx1-mx2.c b/arch/arm/plat-mxc/dma-mx1-mx2.c
index 2905ec758758..e364a5ed10f1 100644
--- a/arch/arm/plat-mxc/dma-mx1-mx2.c
+++ b/arch/arm/plat-mxc/dma-mx1-mx2.c
@@ -113,7 +113,7 @@ struct imx_dma_channel {
void (*err_handler) (int, void *, int errcode);
void (*prog_handler) (int, void *, struct scatterlist *);
void *data;
- unsigned int dma_mode;
+ unsigned int dma_mode;
struct scatterlist *sg;
unsigned int resbytes;
int dma_num;
@@ -802,7 +802,7 @@ static int __init imx_dma_init(void)
int ret = 0;
int i;
- dma_clk = clk_get(NULL, "dma_clk");
+ dma_clk = clk_get(NULL, "dma");
clk_enable(dma_clk);
/* reset DMA module */
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index ccbd94adc668..c6483bad8a26 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -200,8 +200,8 @@ static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
static int mxc_gpio_direction_output(struct gpio_chip *chip,
unsigned offset, int value)
{
- _set_gpio_direction(chip, offset, 1);
mxc_gpio_set(chip, offset, value);
+ _set_gpio_direction(chip, offset, 1);
return 0;
}
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27ads.h b/arch/arm/plat-mxc/include/mach/board-mx27ads.h
index 8f34a05afc87..1cac9d1135cd 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx27ads.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx27ads.h
@@ -48,7 +48,8 @@
* Base address of PBC controller, CS4
*/
#define PBC_BASE_ADDRESS 0xEB000000
-#define PBC_REG_ADDR(offset) (PBC_BASE_ADDRESS + (offset))
+#define PBC_REG_ADDR(offset) (void __force __iomem *) \
+ (PBC_BASE_ADDRESS + (offset))
/*
* PBC Interupt name definitions
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
index 451d510d08c3..318c72ada13d 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31ads.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
@@ -11,6 +11,8 @@
#ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__
#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__
+#include <mach/hardware.h>
+
/* Base address of PBC controller */
#define PBC_BASE_ADDRESS IO_ADDRESS(CS4_BASE_ADDR)
/* Offsets for the PBC Controller register */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
new file mode 100644
index 000000000000..f8aef1babb75
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__
+#define __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__
+
+/* mandatory for CONFIG_LL_DEBUG */
+
+#define MXC_LL_UART_PADDR UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR (AIPI_BASE_ADDR_VIRT + 0x0A000)
+
+#ifndef __ASSEMBLY__
+
+enum mx31moboard_boards {
+ MX31NOBOARD = 0,
+ MX31DEVBOARD = 1,
+ MX31MARXBOT = 2,
+};
+
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls baseboard's init function.
+ */
+
+extern void mx31moboard_devboard_init(void);
+extern void mx31moboard_marxbot_init(void);
+
+#endif
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-qong.h b/arch/arm/plat-mxc/include/mach/board-qong.h
new file mode 100644
index 000000000000..4ff762dd45cf
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-qong.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_QONG_H__
+#define __ASM_ARCH_MXC_BOARD_QONG_H__
+
+/* mandatory for CONFIG_LL_DEBUG */
+
+#define MXC_LL_UART_PADDR UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+
+/* NOR FLASH */
+#define QONG_NOR_SIZE (128*1024*1024)
+
+#endif /* __ASM_ARCH_MXC_BOARD_QONG_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/clkdev.h b/arch/arm/plat-mxc/include/mach/clkdev.h
new file mode 100644
index 000000000000..04b37a89801c
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h
index d21f78e78819..43a82d0c534d 100644
--- a/arch/arm/plat-mxc/include/mach/clock.h
+++ b/arch/arm/plat-mxc/include/mach/clock.h
@@ -26,9 +26,13 @@
struct module;
struct clk {
+#ifndef CONFIG_COMMON_CLKDEV
+ /* As soon as i.MX1 and i.MX31 switched to clkdev, this
+ * block can go away */
struct list_head node;
struct module *owner;
const char *name;
+#endif
int id;
/* Source clock this clk depends on */
struct clk *parent;
@@ -63,5 +67,7 @@ struct clk {
int clk_register(struct clk *clk);
void clk_unregister(struct clk *clk);
+unsigned long mxc_decode_pll(unsigned int pll, u32 f_ref);
+
#endif /* __ASSEMBLY__ */
#endif /* __ASM_ARCH_MXC_CLOCK_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 6350287a59b9..b2f9b72644db 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -12,12 +12,18 @@
#define __ASM_ARCH_MXC_COMMON_H__
struct platform_device;
+struct clk;
extern void mxc_map_io(void);
extern void mxc_init_irq(void);
-extern void mxc_timer_init(const char *clk_timer);
-extern int mxc_clocks_init(unsigned long fref);
+extern void mxc_timer_init(struct clk *timer_clk);
+extern int mx1_clocks_init(unsigned long fref);
+extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
+extern int mx27_clocks_init(unsigned long fref);
+extern int mx31_clocks_init(unsigned long fref);
+extern int mx35_clocks_init(void);
extern int mxc_register_gpios(void);
extern int mxc_register_device(struct platform_device *pdev, void *data);
+extern void mxc_set_cpu_type(unsigned int type);
#endif
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index 602768b427e2..4f773148bc20 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -31,6 +31,9 @@
#ifdef CONFIG_MACH_MX31_3DS
#include <mach/board-mx31pdk.h>
#endif
+#ifdef CONFIG_MACH_QONG
+#include <mach/board-qong.h>
+#endif
.macro addruart,rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
index a612d8bb73c8..42e4ee37ca1f 100644
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -23,10 +23,16 @@
#include <asm/sizes.h>
#ifdef CONFIG_ARCH_MX3
-# include <mach/mx31.h>
+#include <mach/mx3x.h>
+#include <mach/mx31.h>
+#include <mach/mx35.h>
#endif
#ifdef CONFIG_ARCH_MX2
+# include <mach/mx2x.h>
+# ifdef CONFIG_MACH_MX21
+# include <mach/mx21.h>
+# endif
# ifdef CONFIG_MACH_MX27
# include <mach/mx27.h>
# endif
diff --git a/arch/arm/mach-imx/include/mach/imxfb.h b/arch/arm/plat-mxc/include/mach/imxfb.h
index 870d0d939616..762a7b0430e2 100644
--- a/arch/arm/mach-imx/include/mach/imxfb.h
+++ b/arch/arm/plat-mxc/include/mach/imxfb.h
@@ -76,6 +76,9 @@ struct imx_fb_platform_data {
u_char * fixed_screen_cpu;
dma_addr_t fixed_screen_dma;
+ int (*init)(struct platform_device*);
+ int (*exit)(struct platform_device*);
+
void (*lcd_power)(int);
void (*backlight_power)(int);
};
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h b/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h
deleted file mode 100644
index 95a383be628e..000000000000
--- a/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef _MXC_GPIO_MX1_MX2_H
-#define _MXC_GPIO_MX1_MX2_H
-
-#include <linux/io.h>
-
-/*
- * GPIO Module and I/O Multiplexer
- * x = 0..3 for reg_A, reg_B, reg_C, reg_D
- */
-#define VA_GPIO_BASE IO_ADDRESS(GPIO_BASE_ADDR)
-#define MXC_DDIR(x) (0x00 + ((x) << 8))
-#define MXC_OCR1(x) (0x04 + ((x) << 8))
-#define MXC_OCR2(x) (0x08 + ((x) << 8))
-#define MXC_ICONFA1(x) (0x0c + ((x) << 8))
-#define MXC_ICONFA2(x) (0x10 + ((x) << 8))
-#define MXC_ICONFB1(x) (0x14 + ((x) << 8))
-#define MXC_ICONFB2(x) (0x18 + ((x) << 8))
-#define MXC_DR(x) (0x1c + ((x) << 8))
-#define MXC_GIUS(x) (0x20 + ((x) << 8))
-#define MXC_SSR(x) (0x24 + ((x) << 8))
-#define MXC_ICR1(x) (0x28 + ((x) << 8))
-#define MXC_ICR2(x) (0x2c + ((x) << 8))
-#define MXC_IMR(x) (0x30 + ((x) << 8))
-#define MXC_ISR(x) (0x34 + ((x) << 8))
-#define MXC_GPR(x) (0x38 + ((x) << 8))
-#define MXC_SWR(x) (0x3c + ((x) << 8))
-#define MXC_PUEN(x) (0x40 + ((x) << 8))
-
-#ifdef CONFIG_ARCH_MX1
-# define GPIO_PORT_MAX 3
-#endif
-#ifdef CONFIG_ARCH_MX2
-# define GPIO_PORT_MAX 5
-#endif
-
-#ifndef GPIO_PORT_MAX
-# error "GPIO config port count unknown!"
-#endif
-
-#define GPIO_PIN_MASK 0x1f
-
-#define GPIO_PORT_SHIFT 5
-#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT)
-
-#define GPIO_PORTA (0 << GPIO_PORT_SHIFT)
-#define GPIO_PORTB (1 << GPIO_PORT_SHIFT)
-#define GPIO_PORTC (2 << GPIO_PORT_SHIFT)
-#define GPIO_PORTD (3 << GPIO_PORT_SHIFT)
-#define GPIO_PORTE (4 << GPIO_PORT_SHIFT)
-#define GPIO_PORTF (5 << GPIO_PORT_SHIFT)
-
-#define GPIO_OUT (1 << 8)
-#define GPIO_IN (0 << 8)
-#define GPIO_PUEN (1 << 9)
-
-#define GPIO_PF (1 << 10)
-#define GPIO_AF (1 << 11)
-
-#define GPIO_OCR_SHIFT 12
-#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT)
-#define GPIO_AIN (0 << GPIO_OCR_SHIFT)
-#define GPIO_BIN (1 << GPIO_OCR_SHIFT)
-#define GPIO_CIN (2 << GPIO_OCR_SHIFT)
-#define GPIO_GPIO (3 << GPIO_OCR_SHIFT)
-
-#define GPIO_AOUT_SHIFT 14
-#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT)
-#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT)
-#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT)
-#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT)
-#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT)
-
-#define GPIO_BOUT_SHIFT 16
-#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT)
-#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT)
-#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT)
-#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT)
-#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT)
-
-extern void mxc_gpio_mode(int gpio_mode);
-extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
- const char *label);
-extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count);
-
-/*-------------------------------------------------------------------------*/
-
-/* assignements for GPIO alternate/primary functions */
-
-/* FIXME: This list is not completed. The correct directions are
- * missing on some (many) pins
- */
-#ifdef CONFIG_ARCH_MX1
-#define PA0_AIN_SPI2_CLK (GPIO_PORTA | GPIO_OUT | 0)
-#define PA0_AF_ETMTRACESYNC (GPIO_PORTA | GPIO_AF | 0)
-#define PA1_AOUT_SPI2_RXD (GPIO_PORTA | GPIO_IN | 1)
-#define PA1_PF_TIN (GPIO_PORTA | GPIO_PF | 1)
-#define PA2_PF_PWM0 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 2)
-#define PA3_PF_CSI_MCLK (GPIO_PORTA | GPIO_PF | 3)
-#define PA4_PF_CSI_D0 (GPIO_PORTA | GPIO_PF | 4)
-#define PA5_PF_CSI_D1 (GPIO_PORTA | GPIO_PF | 5)
-#define PA6_PF_CSI_D2 (GPIO_PORTA | GPIO_PF | 6)
-#define PA7_PF_CSI_D3 (GPIO_PORTA | GPIO_PF | 7)
-#define PA8_PF_CSI_D4 (GPIO_PORTA | GPIO_PF | 8)
-#define PA9_PF_CSI_D5 (GPIO_PORTA | GPIO_PF | 9)
-#define PA10_PF_CSI_D6 (GPIO_PORTA | GPIO_PF | 10)
-#define PA11_PF_CSI_D7 (GPIO_PORTA | GPIO_PF | 11)
-#define PA12_PF_CSI_VSYNC (GPIO_PORTA | GPIO_PF | 12)
-#define PA13_PF_CSI_HSYNC (GPIO_PORTA | GPIO_PF | 13)
-#define PA14_PF_CSI_PIXCLK (GPIO_PORTA | GPIO_PF | 14)
-#define PA15_PF_I2C_SDA (GPIO_PORTA | GPIO_OUT | GPIO_PF | 15)
-#define PA16_PF_I2C_SCL (GPIO_PORTA | GPIO_OUT | GPIO_PF | 16)
-#define PA17_AF_ETMTRACEPKT4 (GPIO_PORTA | GPIO_AF | 17)
-#define PA17_AIN_SPI2_SS (GPIO_PORTA | GPIO_OUT | 17)
-#define PA18_AF_ETMTRACEPKT5 (GPIO_PORTA | GPIO_AF | 18)
-#define PA19_AF_ETMTRACEPKT6 (GPIO_PORTA | GPIO_AF | 19)
-#define PA20_AF_ETMTRACEPKT7 (GPIO_PORTA | GPIO_AF | 20)
-#define PA21_PF_A0 (GPIO_PORTA | GPIO_PF | 21)
-#define PA22_PF_CS4 (GPIO_PORTA | GPIO_PF | 22)
-#define PA23_PF_CS5 (GPIO_PORTA | GPIO_PF | 23)
-#define PA24_PF_A16 (GPIO_PORTA | GPIO_PF | 24)
-#define PA24_AF_ETMTRACEPKT0 (GPIO_PORTA | GPIO_AF | 24)
-#define PA25_PF_A17 (GPIO_PORTA | GPIO_PF | 25)
-#define PA25_AF_ETMTRACEPKT1 (GPIO_PORTA | GPIO_AF | 25)
-#define PA26_PF_A18 (GPIO_PORTA | GPIO_PF | 26)
-#define PA26_AF_ETMTRACEPKT2 (GPIO_PORTA | GPIO_AF | 26)
-#define PA27_PF_A19 (GPIO_PORTA | GPIO_PF | 27)
-#define PA27_AF_ETMTRACEPKT3 (GPIO_PORTA | GPIO_AF | 27)
-#define PA28_PF_A20 (GPIO_PORTA | GPIO_PF | 28)
-#define PA28_AF_ETMPIPESTAT0 (GPIO_PORTA | GPIO_AF | 28)
-#define PA29_PF_A21 (GPIO_PORTA | GPIO_PF | 29)
-#define PA29_AF_ETMPIPESTAT1 (GPIO_PORTA | GPIO_AF | 29)
-#define PA30_PF_A22 (GPIO_PORTA | GPIO_PF | 30)
-#define PA30_AF_ETMPIPESTAT2 (GPIO_PORTA | GPIO_AF | 30)
-#define PA31_PF_A23 (GPIO_PORTA | GPIO_PF | 31)
-#define PA31_AF_ETMTRACECLK (GPIO_PORTA | GPIO_AF | 31)
-#define PB8_PF_SD_DAT0 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8)
-#define PB8_AF_MS_PIO (GPIO_PORTB | GPIO_AF | 8)
-#define PB9_PF_SD_DAT1 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 9)
-#define PB9_AF_MS_PI1 (GPIO_PORTB | GPIO_AF | 9)
-#define PB10_PF_SD_DAT2 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 10)
-#define PB10_AF_MS_SCLKI (GPIO_PORTB | GPIO_AF | 10)
-#define PB11_PF_SD_DAT3 (GPIO_PORTB | GPIO_PF | 11)
-#define PB11_AF_MS_SDIO (GPIO_PORTB | GPIO_AF | 11)
-#define PB12_PF_SD_CLK (GPIO_PORTB | GPIO_PF | 12)
-#define PB12_AF_MS_SCLK0 (GPIO_PORTB | GPIO_AF | 12)
-#define PB13_PF_SD_CMD (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 13)
-#define PB13_AF_MS_BS (GPIO_PORTB | GPIO_AF | 13)
-#define PB14_AF_SSI_RXFS (GPIO_PORTB | GPIO_AF | 14)
-#define PB15_AF_SSI_RXCLK (GPIO_PORTB | GPIO_AF | 15)
-#define PB16_AF_SSI_RXDAT (GPIO_PORTB | GPIO_IN | GPIO_AF | 16)
-#define PB17_AF_SSI_TXDAT (GPIO_PORTB | GPIO_OUT | GPIO_AF | 17)
-#define PB18_AF_SSI_TXFS (GPIO_PORTB | GPIO_AF | 18)
-#define PB19_AF_SSI_TXCLK (GPIO_PORTB | GPIO_AF | 19)
-#define PB20_PF_USBD_AFE (GPIO_PORTB | GPIO_PF | 20)
-#define PB21_PF_USBD_OE (GPIO_PORTB | GPIO_PF | 21)
-#define PB22_PFUSBD_RCV (GPIO_PORTB | GPIO_PF | 22)
-#define PB23_PF_USBD_SUSPND (GPIO_PORTB | GPIO_PF | 23)
-#define PB24_PF_USBD_VP (GPIO_PORTB | GPIO_PF | 24)
-#define PB25_PF_USBD_VM (GPIO_PORTB | GPIO_PF | 25)
-#define PB26_PF_USBD_VPO (GPIO_PORTB | GPIO_PF | 26)
-#define PB27_PF_USBD_VMO (GPIO_PORTB | GPIO_PF | 27)
-#define PB28_PF_UART2_CTS (GPIO_PORTB | GPIO_OUT | GPIO_PF | 28)
-#define PB29_PF_UART2_RTS (GPIO_PORTB | GPIO_IN | GPIO_PF | 29)
-#define PB30_PF_UART2_TXD (GPIO_PORTB | GPIO_OUT | GPIO_PF | 30)
-#define PB31_PF_UART2_RXD (GPIO_PORTB | GPIO_IN | GPIO_PF | 31)
-#define PC3_PF_SSI_RXFS (GPIO_PORTC | GPIO_PF | 3)
-#define PC4_PF_SSI_RXCLK (GPIO_PORTC | GPIO_PF | 4)
-#define PC5_PF_SSI_RXDAT (GPIO_PORTC | GPIO_IN | GPIO_PF | 5)
-#define PC6_PF_SSI_TXDAT (GPIO_PORTC | GPIO_OUT | GPIO_PF | 6)
-#define PC7_PF_SSI_TXFS (GPIO_PORTC | GPIO_PF | 7)
-#define PC8_PF_SSI_TXCLK (GPIO_PORTC | GPIO_PF | 8)
-#define PC9_PF_UART1_CTS (GPIO_PORTC | GPIO_OUT | GPIO_PF | 9)
-#define PC10_PF_UART1_RTS (GPIO_PORTC | GPIO_IN | GPIO_PF | 10)
-#define PC11_PF_UART1_TXD (GPIO_PORTC | GPIO_OUT | GPIO_PF | 11)
-#define PC12_PF_UART1_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 12)
-#define PC13_PF_SPI1_SPI_RDY (GPIO_PORTC | GPIO_PF | 13)
-#define PC14_PF_SPI1_SCLK (GPIO_PORTC | GPIO_PF | 14)
-#define PC15_PF_SPI1_SS (GPIO_PORTC | GPIO_PF | 15)
-#define PC16_PF_SPI1_MISO (GPIO_PORTC | GPIO_PF | 16)
-#define PC17_PF_SPI1_MOSI (GPIO_PORTC | GPIO_PF | 17)
-#define PC24_BIN_UART3_RI (GPIO_PORTC | GPIO_OUT | GPIO_BIN | 24)
-#define PC25_BIN_UART3_DSR (GPIO_PORTC | GPIO_OUT | GPIO_BIN | 25)
-#define PC26_AOUT_UART3_DTR (GPIO_PORTC | GPIO_IN | 26)
-#define PC27_BIN_UART3_DCD (GPIO_PORTC | GPIO_OUT | GPIO_BIN | 27)
-#define PC28_BIN_UART3_CTS (GPIO_PORTC | GPIO_OUT | GPIO_BIN | 28)
-#define PC29_AOUT_UART3_RTS (GPIO_PORTC | GPIO_IN | 29)
-#define PC30_BIN_UART3_TX (GPIO_PORTC | GPIO_BIN | 30)
-#define PC31_AOUT_UART3_RX (GPIO_PORTC | GPIO_IN | 31)
-#define PD6_PF_LSCLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 6)
-#define PD7_PF_REV (GPIO_PORTD | GPIO_PF | 7)
-#define PD7_AF_UART2_DTR (GPIO_PORTD | GPIO_IN | GPIO_AF | 7)
-#define PD7_AIN_SPI2_SCLK (GPIO_PORTD | GPIO_AIN | 7)
-#define PD8_PF_CLS (GPIO_PORTD | GPIO_PF | 8)
-#define PD8_AF_UART2_DCD (GPIO_PORTD | GPIO_OUT | GPIO_AF | 8)
-#define PD8_AIN_SPI2_SS (GPIO_PORTD | GPIO_AIN | 8)
-#define PD9_PF_PS (GPIO_PORTD | GPIO_PF | 9)
-#define PD9_AF_UART2_RI (GPIO_PORTD | GPIO_OUT | GPIO_AF | 9)
-#define PD9_AOUT_SPI2_RXD (GPIO_PORTD | GPIO_IN | 9)
-#define PD10_PF_SPL_SPR (GPIO_PORTD | GPIO_OUT | GPIO_PF | 10)
-#define PD10_AF_UART2_DSR (GPIO_PORTD | GPIO_OUT | GPIO_AF | 10)
-#define PD10_AIN_SPI2_TXD (GPIO_PORTD | GPIO_OUT | 10)
-#define PD11_PF_CONTRAST (GPIO_PORTD | GPIO_OUT | GPIO_PF | 11)
-#define PD12_PF_ACD_OE (GPIO_PORTD | GPIO_OUT | GPIO_PF | 12)
-#define PD13_PF_LP_HSYNC (GPIO_PORTD | GPIO_OUT | GPIO_PF | 13)
-#define PD14_PF_FLM_VSYNC (GPIO_PORTD | GPIO_OUT | GPIO_PF | 14)
-#define PD15_PF_LD0 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 15)
-#define PD16_PF_LD1 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 16)
-#define PD17_PF_LD2 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 17)
-#define PD18_PF_LD3 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 18)
-#define PD19_PF_LD4 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 19)
-#define PD20_PF_LD5 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 20)
-#define PD21_PF_LD6 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 21)
-#define PD22_PF_LD7 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 22)
-#define PD23_PF_LD8 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 23)
-#define PD24_PF_LD9 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 24)
-#define PD25_PF_LD10 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 25)
-#define PD26_PF_LD11 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 26)
-#define PD27_PF_LD12 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 27)
-#define PD28_PF_LD13 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 28)
-#define PD29_PF_LD14 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 29)
-#define PD30_PF_LD15 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 30)
-#define PD31_PF_TMR2OUT (GPIO_PORTD | GPIO_PF | 31)
-#define PD31_BIN_SPI2_TXD (GPIO_PORTD | GPIO_BIN | 31)
-#endif
-
-#ifdef CONFIG_ARCH_MX2
-#define PA0_PF_USBH2_CLK (GPIO_PORTA | GPIO_PF | 0)
-#define PA1_PF_USBH2_DIR (GPIO_PORTA | GPIO_PF | 1)
-#define PA2_PF_USBH2_DATA7 (GPIO_PORTA | GPIO_PF | 2)
-#define PA3_PF_USBH2_NXT (GPIO_PORTA | GPIO_PF | 3)
-#define PA4_PF_USBH2_STP (GPIO_PORTA | GPIO_PF | 4)
-#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_OUT | GPIO_PF | 5)
-#define PA6_PF_LD0 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 6)
-#define PA7_PF_LD1 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 7)
-#define PA8_PF_LD2 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 8)
-#define PA9_PF_LD3 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 9)
-#define PA10_PF_LD4 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 10)
-#define PA11_PF_LD5 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 11)
-#define PA12_PF_LD6 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 12)
-#define PA13_PF_LD7 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 13)
-#define PA14_PF_LD8 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 14)
-#define PA15_PF_LD9 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 15)
-#define PA16_PF_LD10 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 16)
-#define PA17_PF_LD11 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 17)
-#define PA18_PF_LD12 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 18)
-#define PA19_PF_LD13 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 19)
-#define PA20_PF_LD14 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 20)
-#define PA21_PF_LD15 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 21)
-#define PA22_PF_LD16 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 22)
-#define PA23_PF_LD17 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 23)
-#define PA24_PF_REV (GPIO_PORTA | GPIO_OUT | GPIO_PF | 24)
-#define PA25_PF_CLS (GPIO_PORTA | GPIO_OUT | GPIO_PF | 25)
-#define PA26_PF_PS (GPIO_PORTA | GPIO_OUT | GPIO_PF | 26)
-#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_OUT | GPIO_PF | 27)
-#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_OUT | GPIO_PF | 28)
-#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_OUT | GPIO_PF | 29)
-#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_OUT | GPIO_PF | 30)
-#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_OUT | GPIO_PF | 31)
-#define PB4_PF_SD2_D0 (GPIO_PORTB | GPIO_PF | 4)
-#define PB5_PF_SD2_D1 (GPIO_PORTB | GPIO_PF | 5)
-#define PB6_PF_SD2_D2 (GPIO_PORTB | GPIO_PF | 6)
-#define PB7_PF_SD2_D3 (GPIO_PORTB | GPIO_PF | 7)
-#define PB8_PF_SD2_CMD (GPIO_PORTB | GPIO_PF | 8)
-#define PB9_PF_SD2_CLK (GPIO_PORTB | GPIO_PF | 9)
-#define PB10_PF_CSI_D0 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 10)
-#define PB10_AF_UART6_TXD (GPIO_PORTB | GPIO_OUT | GPIO_AF | 10)
-#define PB11_PF_CSI_D1 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 11)
-#define PB11_AF_UART6_RXD (GPIO_PORTB | GPIO_IN | GPIO_AF | 11)
-#define PB12_PF_CSI_D2 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 12)
-#define PB12_AF_UART6_CTS (GPIO_PORTB | GPIO_OUT | GPIO_AF | 12)
-#define PB13_PF_CSI_D3 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 13)
-#define PB13_AF_UART6_RTS (GPIO_PORTB | GPIO_IN | GPIO_AF | 13)
-#define PB14_PF_CSI_D4 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 14)
-#define PB15_PF_CSI_MCLK (GPIO_PORTB | GPIO_OUT | GPIO_PF | 15)
-#define PB16_PF_CSI_PIXCLK (GPIO_PORTB | GPIO_OUT | GPIO_PF | 16)
-#define PB17_PF_CSI_D5 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 17)
-#define PB18_PF_CSI_D6 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 18)
-#define PB18_AF_UART5_TXD (GPIO_PORTB | GPIO_OUT | GPIO_AF | 18)
-#define PB19_PF_CSI_D7 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 19)
-#define PB19_AF_UART5_RXD (GPIO_PORTB | GPIO_IN | GPIO_AF | 19)
-#define PB20_PF_CSI_VSYNC (GPIO_PORTB | GPIO_OUT | GPIO_PF | 20)
-#define PB20_AF_UART5_CTS (GPIO_PORTB | GPIO_OUT | GPIO_AF | 20)
-#define PB21_PF_CSI_HSYNC (GPIO_PORTB | GPIO_OUT | GPIO_PF | 21)
-#define PB21_AF_UART5_RTS (GPIO_PORTB | GPIO_IN | GPIO_AF | 21)
-#define PB22_PF_USBH1_SUSP (GPIO_PORTB | GPIO_PF | 22)
-#define PB23_PF_USB_PWR (GPIO_PORTB | GPIO_PF | 23)
-#define PB24_PF_USB_OC_B (GPIO_PORTB | GPIO_PF | 24)
-#define PB25_PF_USBH1_RCV (GPIO_PORTB | GPIO_PF | 25)
-#define PB26_PF_USBH1_FS (GPIO_PORTB | GPIO_PF | 26)
-#define PB27_PF_USBH1_OE_B (GPIO_PORTB | GPIO_PF | 27)
-#define PB28_PF_USBH1_TXDM (GPIO_PORTB | GPIO_PF | 28)
-#define PB29_PF_USBH1_TXDP (GPIO_PORTB | GPIO_PF | 29)
-#define PB30_PF_USBH1_RXDM (GPIO_PORTB | GPIO_PF | 30)
-#define PB31_PF_USBH1_RXDP (GPIO_PORTB | GPIO_PF | 31)
-#define PB26_AF_UART4_RTS (GPIO_PORTB | GPIO_IN | GPIO_PF | 26)
-#define PB28_AF_UART4_TXD (GPIO_PORTB | GPIO_OUT | GPIO_AF | 28)
-#define PB29_AF_UART4_CTS (GPIO_PORTB | GPIO_OUT | GPIO_AF | 29)
-#define PB31_AF_UART4_RXD (GPIO_PORTB | GPIO_IN | GPIO_AF | 31)
-#define PC5_PF_I2C2_SDA (GPIO_PORTC | GPIO_IN | GPIO_PF | 5)
-#define PC6_PF_I2C2_SCL (GPIO_PORTC | GPIO_IN | GPIO_PF | 6)
-#define PC7_PF_USBOTG_DATA5 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 7)
-#define PC8_PF_USBOTG_DATA6 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 8)
-#define PC9_PF_USBOTG_DATA0 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 9)
-#define PC10_PF_USBOTG_DATA2 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 10)
-#define PC11_PF_USBOTG_DATA1 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 11)
-#define PC12_PF_USBOTG_DATA4 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 12)
-#define PC13_PF_USBOTG_DATA3 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 13)
-#define PC16_PF_SSI4_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 16)
-#define PC17_PF_SSI4_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 17)
-#define PC18_PF_SSI4_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 18)
-#define PC19_PF_SSI4_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 19)
-#define PC20_PF_SSI1_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 20)
-#define PC21_PF_SSI1_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 21)
-#define PC22_PF_SSI1_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 22)
-#define PC23_PF_SSI1_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 23)
-#define PC24_PF_SSI2_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 24)
-#define PC25_PF_SSI2_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 25)
-#define PC26_PF_SSI2_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 26)
-#define PC27_PF_SSI2_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 27)
-#define PC28_PF_SSI3_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 28)
-#define PC29_PF_SSI3_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 29)
-#define PC30_PF_SSI3_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 30)
-#define PC31_PF_SSI3_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 31)
-#define PD0_AIN_FEC_TXD0 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 0)
-#define PD1_AIN_FEC_TXD1 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 1)
-#define PD2_AIN_FEC_TXD2 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 2)
-#define PD3_AIN_FEC_TXD3 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 3)
-#define PD4_AOUT_FEC_RX_ER (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 4)
-#define PD5_AOUT_FEC_RXD1 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 5)
-#define PD6_AOUT_FEC_RXD2 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 6)
-#define PD7_AOUT_FEC_RXD3 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 7)
-#define PD8_AF_FEC_MDIO (GPIO_PORTD | GPIO_IN | GPIO_AF | 8)
-#define PD9_AIN_FEC_MDC (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 9)
-#define PD10_AOUT_FEC_CRS (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 10)
-#define PD11_AOUT_FEC_TX_CLK (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 11)
-#define PD12_AOUT_FEC_RXD0 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 12)
-#define PD13_AOUT_FEC_RX_DV (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 13)
-#define PD14_AOUT_FEC_CLR (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 14)
-#define PD15_AOUT_FEC_COL (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 15)
-#define PD16_AIN_FEC_TX_ER (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 16)
-#define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_OUT | GPIO_PF | 17)
-#define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 18)
-#define PD19_AF_USBH2_DATA4 (GPIO_PORTD | GPIO_AF | 19)
-#define PD20_AF_USBH2_DATA3 (GPIO_PORTD | GPIO_AF | 20)
-#define PD21_AF_USBH2_DATA6 (GPIO_PORTD | GPIO_AF | 21)
-#define PD22_AF_USBH2_DATA0 (GPIO_PORTD | GPIO_AF | 22)
-#define PD23_AF_USBH2_DATA2 (GPIO_PORTD | GPIO_AF | 23)
-#define PD24_AF_USBH2_DATA1 (GPIO_PORTD | GPIO_AF | 24)
-#define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_OUT | GPIO_PF | 25)
-#define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 26)
-#define PD26_AF_USBH2_DATA5 (GPIO_PORTD | GPIO_AF | 26)
-#define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 27)
-#define PD28_PF_CSPI1_SS0 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 28)
-#define PD29_PF_CSPI1_SCLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 29)
-#define PD30_PF_CSPI1_MISO (GPIO_PORTD | GPIO_IN | GPIO_PF | 30)
-#define PD31_PF_CSPI1_MOSI (GPIO_PORTD | GPIO_OUT | GPIO_PF | 31)
-#define PF23_AIN_FEC_TX_EN (GPIO_PORTF | GPIO_OUT | GPIO_AIN | 23)
-#define PE0_PF_USBOTG_NXT (GPIO_PORTE | GPIO_OUT | GPIO_PF | 0)
-#define PE1_PF_USBOTG_STP (GPIO_PORTE | GPIO_OUT | GPIO_PF | 1)
-#define PE2_PF_USBOTG_DIR (GPIO_PORTE | GPIO_OUT | GPIO_PF | 2)
-#define PE3_PF_UART2_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 3)
-#define PE4_PF_UART2_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 4)
-#define PE6_PF_UART2_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 6)
-#define PE7_PF_UART2_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 7)
-#define PE8_PF_UART3_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 8)
-#define PE9_PF_UART3_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 9)
-#define PE10_PF_UART3_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 10)
-#define PE11_PF_UART3_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 11)
-#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 12)
-#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 13)
-#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 14)
-#define PE15_PF_UART1_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 15)
-#define PE16_AF_RTCK (GPIO_PORTE | GPIO_OUT | GPIO_AF | 16)
-#define PE16_PF_RTCK (GPIO_PORTE | GPIO_OUT | GPIO_PF | 16)
-#define PE18_PF_SDHC1_D0 (GPIO_PORTE | GPIO_PF | 18)
-#define PE18_AF_CSPI3_MISO (GPIO_PORTE | GPIO_IN | GPIO_AF | 18)
-#define PE19_PF_SDHC1_D1 (GPIO_PORTE | GPIO_PF | 19)
-#define PE20_PF_SDHC1_D2 (GPIO_PORTE | GPIO_PF | 20)
-#define PE21_PF_SDHC1_D3 (GPIO_PORTE | GPIO_PF | 21)
-#define PE21_AF_CSPI3_SS (GPIO_PORTE | GPIO_OUT | GPIO_AF | 21)
-#define PE22_PF_SDHC1_CMD (GPIO_PORTE | GPIO_PF | 22)
-#define PE22_AF_CSPI3_MOSI (GPIO_PORTE | GPIO_OUT | GPIO_AF | 22)
-#define PE22_PF_SDHC1_CLK (GPIO_PORTE | GPIO_PF | 23)
-#define PE23_AF_CSPI3_SCLK (GPIO_PORTE | GPIO_OUT | GPIO_AF | 23)
-#define PE24_PF_USBOTG_CLK (GPIO_PORTE | GPIO_OUT | GPIO_PF | 24)
-#define PE25_PF_USBOTG_DATA7 (GPIO_PORTE | GPIO_OUT | GPIO_PF | 25)
-#endif
-
-/* decode irq number to use with IMR(x), ISR(x) and friends */
-#define IRQ_TO_REG(irq) ((irq - MXC_INTERNAL_IRQS) >> 5)
-
-#define IRQ_GPIOA(x) (MXC_GPIO_IRQ_START + x)
-#define IRQ_GPIOB(x) (IRQ_GPIOA(32) + x)
-#define IRQ_GPIOC(x) (IRQ_GPIOB(32) + x)
-#define IRQ_GPIOD(x) (IRQ_GPIOC(32) + x)
-#define IRQ_GPIOE(x) (IRQ_GPIOD(32) + x)
-
-#endif /* _MXC_GPIO_MX1_MX2_H */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx1.h b/arch/arm/plat-mxc/include/mach/iomux-mx1.h
new file mode 100644
index 000000000000..bf23305c19cc
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx1.h
@@ -0,0 +1,166 @@
+/*
+* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301, USA.
+*/
+
+#ifndef _MXC_IOMUX_MX1_H
+#define _MXC_IOMUX_MX1_H
+
+#ifndef GPIO_PORTA
+#error Please include mach/iomux.h
+#endif
+
+/* FIXME: This list is not completed. The correct directions are
+* missing on some (many) pins
+*/
+
+
+/* Primary GPIO pin functions */
+
+#define PA0_AIN_SPI2_CLK (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0)
+#define PA0_AF_ETMTRACESYNC (GPIO_PORTA | GPIO_AF | 0)
+#define PA1_AOUT_SPI2_RXD (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 1)
+#define PA1_PF_TIN (GPIO_PORTA | GPIO_PF | 1)
+#define PA2_PF_PWM0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 2)
+#define PA3_PF_CSI_MCLK (GPIO_PORTA | GPIO_PF | 3)
+#define PA4_PF_CSI_D0 (GPIO_PORTA | GPIO_PF | 4)
+#define PA5_PF_CSI_D1 (GPIO_PORTA | GPIO_PF | 5)
+#define PA6_PF_CSI_D2 (GPIO_PORTA | GPIO_PF | 6)
+#define PA7_PF_CSI_D3 (GPIO_PORTA | GPIO_PF | 7)
+#define PA8_PF_CSI_D4 (GPIO_PORTA | GPIO_PF | 8)
+#define PA9_PF_CSI_D5 (GPIO_PORTA | GPIO_PF | 9)
+#define PA10_PF_CSI_D6 (GPIO_PORTA | GPIO_PF | 10)
+#define PA11_PF_CSI_D7 (GPIO_PORTA | GPIO_PF | 11)
+#define PA12_PF_CSI_VSYNC (GPIO_PORTA | GPIO_PF | 12)
+#define PA13_PF_CSI_HSYNC (GPIO_PORTA | GPIO_PF | 13)
+#define PA14_PF_CSI_PIXCLK (GPIO_PORTA | GPIO_PF | 14)
+#define PA15_PF_I2C_SDA (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15)
+#define PA16_PF_I2C_SCL (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16)
+#define PA17_AF_ETMTRACEPKT4 (GPIO_PORTA | GPIO_AF | 17)
+#define PA17_AIN_SPI2_SS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17)
+#define PA18_AF_ETMTRACEPKT5 (GPIO_PORTA | GPIO_AF | 18)
+#define PA19_AF_ETMTRACEPKT6 (GPIO_PORTA | GPIO_AF | 19)
+#define PA20_AF_ETMTRACEPKT7 (GPIO_PORTA | GPIO_AF | 20)
+#define PA21_PF_A0 (GPIO_PORTA | GPIO_PF | 21)
+#define PA22_PF_CS4 (GPIO_PORTA | GPIO_PF | 22)
+#define PA23_PF_CS5 (GPIO_PORTA | GPIO_PF | 23)
+#define PA24_PF_A16 (GPIO_PORTA | GPIO_PF | 24)
+#define PA24_AF_ETMTRACEPKT0 (GPIO_PORTA | GPIO_AF | 24)
+#define PA25_PF_A17 (GPIO_PORTA | GPIO_PF | 25)
+#define PA25_AF_ETMTRACEPKT1 (GPIO_PORTA | GPIO_AF | 25)
+#define PA26_PF_A18 (GPIO_PORTA | GPIO_PF | 26)
+#define PA26_AF_ETMTRACEPKT2 (GPIO_PORTA | GPIO_AF | 26)
+#define PA27_PF_A19 (GPIO_PORTA | GPIO_PF | 27)
+#define PA27_AF_ETMTRACEPKT3 (GPIO_PORTA | GPIO_AF | 27)
+#define PA28_PF_A20 (GPIO_PORTA | GPIO_PF | 28)
+#define PA28_AF_ETMPIPESTAT0 (GPIO_PORTA | GPIO_AF | 28)
+#define PA29_PF_A21 (GPIO_PORTA | GPIO_PF | 29)
+#define PA29_AF_ETMPIPESTAT1 (GPIO_PORTA | GPIO_AF | 29)
+#define PA30_PF_A22 (GPIO_PORTA | GPIO_PF | 30)
+#define PA30_AF_ETMPIPESTAT2 (GPIO_PORTA | GPIO_AF | 30)
+#define PA31_PF_A23 (GPIO_PORTA | GPIO_PF | 31)
+#define PA31_AF_ETMTRACECLK (GPIO_PORTA | GPIO_AF | 31)
+#define PB8_PF_SD_DAT0 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8)
+#define PB8_AF_MS_PIO (GPIO_PORTB | GPIO_AF | 8)
+#define PB9_PF_SD_DAT1 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 9)
+#define PB9_AF_MS_PI1 (GPIO_PORTB | GPIO_AF | 9)
+#define PB10_PF_SD_DAT2 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 10)
+#define PB10_AF_MS_SCLKI (GPIO_PORTB | GPIO_AF | 10)
+#define PB11_PF_SD_DAT3 (GPIO_PORTB | GPIO_PF | 11)
+#define PB11_AF_MS_SDIO (GPIO_PORTB | GPIO_AF | 11)
+#define PB12_PF_SD_CLK (GPIO_PORTB | GPIO_PF | 12)
+#define PB12_AF_MS_SCLK0 (GPIO_PORTB | GPIO_AF | 12)
+#define PB13_PF_SD_CMD (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 13)
+#define PB13_AF_MS_BS (GPIO_PORTB | GPIO_AF | 13)
+#define PB14_AF_SSI_RXFS (GPIO_PORTB | GPIO_AF | 14)
+#define PB15_AF_SSI_RXCLK (GPIO_PORTB | GPIO_AF | 15)
+#define PB16_AF_SSI_RXDAT (GPIO_PORTB | GPIO_AF | GPIO_IN | 16)
+#define PB17_AF_SSI_TXDAT (GPIO_PORTB | GPIO_AF | GPIO_OUT | 17)
+#define PB18_AF_SSI_TXFS (GPIO_PORTB | GPIO_AF | 18)
+#define PB19_AF_SSI_TXCLK (GPIO_PORTB | GPIO_AF | 19)
+#define PB20_PF_USBD_AFE (GPIO_PORTB | GPIO_PF | 20)
+#define PB21_PF_USBD_OE (GPIO_PORTB | GPIO_PF | 21)
+#define PB22_PF_USBD_RCV (GPIO_PORTB | GPIO_PF | 22)
+#define PB23_PF_USBD_SUSPND (GPIO_PORTB | GPIO_PF | 23)
+#define PB24_PF_USBD_VP (GPIO_PORTB | GPIO_PF | 24)
+#define PB25_PF_USBD_VM (GPIO_PORTB | GPIO_PF | 25)
+#define PB26_PF_USBD_VPO (GPIO_PORTB | GPIO_PF | 26)
+#define PB27_PF_USBD_VMO (GPIO_PORTB | GPIO_PF | 27)
+#define PB28_PF_UART2_CTS (GPIO_PORTB | GPIO_PF | GPIO_OUT | 28)
+#define PB29_PF_UART2_RTS (GPIO_PORTB | GPIO_PF | GPIO_IN | 29)
+#define PB30_PF_UART2_TXD (GPIO_PORTB | GPIO_PF | GPIO_OUT | 30)
+#define PB31_PF_UART2_RXD (GPIO_PORTB | GPIO_PF | GPIO_IN | 31)
+#define PC3_PF_SSI_RXFS (GPIO_PORTC | GPIO_PF | 3)
+#define PC4_PF_SSI_RXCLK (GPIO_PORTC | GPIO_PF | 4)
+#define PC5_PF_SSI_RXDAT (GPIO_PORTC | GPIO_PF | GPIO_IN | 5)
+#define PC6_PF_SSI_TXDAT (GPIO_PORTC | GPIO_PF | GPIO_OUT | 6)
+#define PC7_PF_SSI_TXFS (GPIO_PORTC | GPIO_PF | 7)
+#define PC8_PF_SSI_TXCLK (GPIO_PORTC | GPIO_PF | 8)
+#define PC9_PF_UART1_CTS (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9)
+#define PC10_PF_UART1_RTS (GPIO_PORTC | GPIO_PF | GPIO_IN | 10)
+#define PC11_PF_UART1_TXD (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11)
+#define PC12_PF_UART1_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 12)
+#define PC13_PF_SPI1_SPI_RDY (GPIO_PORTC | GPIO_PF | 13)
+#define PC14_PF_SPI1_SCLK (GPIO_PORTC | GPIO_PF | 14)
+#define PC15_PF_SPI1_SS (GPIO_PORTC | GPIO_PF | 15)
+#define PC16_PF_SPI1_MISO (GPIO_PORTC | GPIO_PF | 16)
+#define PC17_PF_SPI1_MOSI (GPIO_PORTC | GPIO_PF | 17)
+#define PC24_BIN_UART3_RI (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 24)
+#define PC25_BIN_UART3_DSR (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 25)
+#define PC26_AOUT_UART3_DTR (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 26)
+#define PC27_BIN_UART3_DCD (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 27)
+#define PC28_BIN_UART3_CTS (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 28)
+#define PC29_AOUT_UART3_RTS (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 29)
+#define PC30_BIN_UART3_TX (GPIO_PORTC | GPIO_BIN | 30)
+#define PC31_AOUT_UART3_RX (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 31)
+#define PD6_PF_LSCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 6)
+#define PD7_PF_REV (GPIO_PORTD | GPIO_PF | 7)
+#define PD7_AF_UART2_DTR (GPIO_PORTD | GPIO_AF | GPIO_IN | 7)
+#define PD7_AIN_SPI2_SCLK (GPIO_PORTD | GPIO_AIN | 7)
+#define PD8_PF_CLS (GPIO_PORTD | GPIO_PF | 8)
+#define PD8_AF_UART2_DCD (GPIO_PORTD | GPIO_AF | GPIO_OUT | 8)
+#define PD8_AIN_SPI2_SS (GPIO_PORTD | GPIO_AIN | 8)
+#define PD9_PF_PS (GPIO_PORTD | GPIO_PF | 9)
+#define PD9_AF_UART2_RI (GPIO_PORTD | GPIO_AF | GPIO_OUT | 9)
+#define PD9_AOUT_SPI2_RXD (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 9)
+#define PD10_PF_SPL_SPR (GPIO_PORTD | GPIO_PF | GPIO_OUT | 10)
+#define PD10_AF_UART2_DSR (GPIO_PORTD | GPIO_AF | GPIO_OUT | 10)
+#define PD10_AIN_SPI2_TXD (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 10)
+#define PD11_PF_CONTRAST (GPIO_PORTD | GPIO_PF | GPIO_OUT | 11)
+#define PD12_PF_ACD_OE (GPIO_PORTD | GPIO_PF | GPIO_OUT | 12)
+#define PD13_PF_LP_HSYNC (GPIO_PORTD | GPIO_PF | GPIO_OUT | 13)
+#define PD14_PF_FLM_VSYNC (GPIO_PORTD | GPIO_PF | GPIO_OUT | 14)
+#define PD15_PF_LD0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 15)
+#define PD16_PF_LD1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 16)
+#define PD17_PF_LD2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
+#define PD18_PF_LD3 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
+#define PD19_PF_LD4 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 19)
+#define PD20_PF_LD5 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 20)
+#define PD21_PF_LD6 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 21)
+#define PD22_PF_LD7 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 22)
+#define PD23_PF_LD8 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 23)
+#define PD24_PF_LD9 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 24)
+#define PD25_PF_LD10 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
+#define PD26_PF_LD11 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
+#define PD27_PF_LD12 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)
+#define PD28_PF_LD13 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28)
+#define PD29_PF_LD14 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29)
+#define PD30_PF_LD15 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 30)
+#define PD31_PF_TMR2OUT (GPIO_PORTD | GPIO_PF | 31)
+#define PD31_BIN_SPI2_TXD (GPIO_PORTD | GPIO_BIN | 31)
+
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx21.h b/arch/arm/plat-mxc/include/mach/iomux-mx21.h
new file mode 100644
index 000000000000..63aaa972e275
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx21.h
@@ -0,0 +1,126 @@
+/*
+* Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.de>
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301, USA.
+*/
+
+#ifndef _MXC_IOMUX_MX21_H
+#define _MXC_IOMUX_MX21_H
+
+#ifndef GPIO_PORTA
+#error Please include mach/iomux.h
+#endif
+
+
+/* Primary GPIO pin functions */
+
+#define PB22_PF_USBH1_BYP (GPIO_PORTB | GPIO_PF | 22)
+#define PB25_PF_USBH1_ON (GPIO_PORTB | GPIO_PF | 25)
+#define PC5_PF_USBOTG_SDA (GPIO_PORTC | GPIO_PF | 5)
+#define PC6_PF_USBOTG_SCL (GPIO_PORTC | GPIO_PF | 6)
+#define PC7_PF_USBOTG_ON (GPIO_PORTC | GPIO_PF | 7)
+#define PC8_PF_USBOTG_FS (GPIO_PORTC | GPIO_PF | 8)
+#define PC9_PF_USBOTG_OE (GPIO_PORTC | GPIO_PF | 9)
+#define PC10_PF_USBOTG_TXDM (GPIO_PORTC | GPIO_PF | 10)
+#define PC11_PF_USBOTG_TXDP (GPIO_PORTC | GPIO_PF | 11)
+#define PC12_PF_USBOTG_RXDM (GPIO_PORTC | GPIO_PF | 12)
+#define PC13_PF_USBOTG_RXDP (GPIO_PORTC | GPIO_PF | 13)
+#define PC16_PF_SAP_FS (GPIO_PORTC | GPIO_PF | 16)
+#define PC17_PF_SAP_RXD (GPIO_PORTC | GPIO_PF | 17)
+#define PC18_PF_SAP_TXD (GPIO_PORTC | GPIO_PF | 18)
+#define PC19_PF_SAP_CLK (GPIO_PORTC | GPIO_PF | 19)
+#define PE0_PF_TEST_WB2 (GPIO_PORTE | GPIO_PF | 0)
+#define PE1_PF_TEST_WB1 (GPIO_PORTE | GPIO_PF | 1)
+#define PE2_PF_TEST_WB0 (GPIO_PORTE | GPIO_PF | 2)
+#define PF1_PF_NFCE (GPIO_PORTF | GPIO_PF | 1)
+#define PF3_PF_NFCLE (GPIO_PORTF | GPIO_PF | 3)
+#define PF7_PF_NFIO0 (GPIO_PORTF | GPIO_PF | 7)
+#define PF8_PF_NFIO1 (GPIO_PORTF | GPIO_PF | 8)
+#define PF9_PF_NFIO2 (GPIO_PORTF | GPIO_PF | 9)
+#define PF10_PF_NFIO3 (GPIO_PORTF | GPIO_PF | 10)
+#define PF11_PF_NFIO4 (GPIO_PORTF | GPIO_PF | 11)
+#define PF12_PF_NFIO5 (GPIO_PORTF | GPIO_PF | 12)
+#define PF13_PF_NFIO6 (GPIO_PORTF | GPIO_PF | 13)
+#define PF14_PF_NFIO7 (GPIO_PORTF | GPIO_PF | 14)
+#define PF16_PF_RES (GPIO_PORTF | GPIO_PF | 16)
+
+/* Alternate GPIO pin functions */
+
+#define PA5_AF_BMI_CLK_CS (GPIO_PORTA | GPIO_AF | 5)
+#define PA6_AF_BMI_D0 (GPIO_PORTA | GPIO_AF | 6)
+#define PA7_AF_BMI_D1 (GPIO_PORTA | GPIO_AF | 7)
+#define PA8_AF_BMI_D2 (GPIO_PORTA | GPIO_AF | 8)
+#define PA9_AF_BMI_D3 (GPIO_PORTA | GPIO_AF | 9)
+#define PA10_AF_BMI_D4 (GPIO_PORTA | GPIO_AF | 10)
+#define PA11_AF_BMI_D5 (GPIO_PORTA | GPIO_AF | 11)
+#define PA12_AF_BMI_D6 (GPIO_PORTA | GPIO_AF | 12)
+#define PA13_AF_BMI_D7 (GPIO_PORTA | GPIO_AF | 13)
+#define PA14_AF_BMI_D8 (GPIO_PORTA | GPIO_AF | 14)
+#define PA15_AF_BMI_D9 (GPIO_PORTA | GPIO_AF | 15)
+#define PA16_AF_BMI_D10 (GPIO_PORTA | GPIO_AF | 16)
+#define PA17_AF_BMI_D11 (GPIO_PORTA | GPIO_AF | 17)
+#define PA18_AF_BMI_D12 (GPIO_PORTA | GPIO_AF | 18)
+#define PA19_AF_BMI_D13 (GPIO_PORTA | GPIO_AF | 19)
+#define PA20_AF_BMI_D14 (GPIO_PORTA | GPIO_AF | 20)
+#define PA21_AF_BMI_D15 (GPIO_PORTA | GPIO_AF | 21)
+#define PA22_AF_BMI_READ_REQ (GPIO_PORTA | GPIO_AF | 22)
+#define PA23_AF_BMI_WRITE (GPIO_PORTA | GPIO_AF | 23)
+#define PA29_AF_BMI_RX_FULL (GPIO_PORTA | GPIO_AF | 29)
+#define PA30_AF_BMI_READ (GPIO_PORTA | GPIO_AF | 30)
+
+/* AIN GPIO pin functions */
+
+#define PC14_AIN_SYS_CLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14)
+#define PD21_AIN_USBH2_FS (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 21)
+#define PD22_AIN_USBH2_OE (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 22)
+#define PD23_AIN_USBH2_TXDM (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 23)
+#define PD24_AIN_USBH2_TXDP (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 24)
+#define PE8_AIN_IR_TXD (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 8)
+#define PF0_AIN_PC_RST (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 0)
+#define PF1_AIN_PC_CE1 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 1)
+#define PF2_AIN_PC_CE2 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 2)
+#define PF3_AIN_PC_POE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 3)
+#define PF4_AIN_PC_OE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 4)
+#define PF5_AIN_PC_RW (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 5)
+
+/* BIN GPIO pin functions */
+
+#define PC14_BIN_SYS_CLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14)
+#define PD27_BIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_BIN | GPIO_OUT | 27)
+
+/* CIN GPIO pin functions */
+
+#define PB26_CIN_USBH1_RXDAT (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 26)
+
+/* AOUT GPIO pin functions */
+
+#define PA29_AOUT_BMI_WAIT (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 29)
+#define PD19_AOUT_USBH2_RXDM (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 19)
+#define PD20_AOUT_USBH2_RXDP (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 20)
+#define PD25_AOUT_EXT_DMAREQ (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 25)
+#define PD26_AOUT_USBOTG_RXDAT (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 26)
+#define PE9_AOUT_IR_RXD (GPIO_PORTE | GPIO_AOUT | GPIO_IN | 9)
+#define PF6_AOUT_PC_BVD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 6)
+#define PF7_AOUT_PC_BVD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 7)
+#define PF8_AOUT_PC_VS2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 8)
+#define PF9_AOUT_PC_VS1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 9)
+#define PF10_AOUT_PC_WP (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 10)
+#define PF11_AOUT_PC_READY (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 11)
+#define PF12_AOUT_PC_WAIT (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 12)
+#define PF13_AOUT_PC_CD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 13)
+#define PF14_AOUT_PC_CD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 14)
+
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx27.h b/arch/arm/plat-mxc/include/mach/iomux-mx27.h
new file mode 100644
index 000000000000..5ac158b70f61
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx27.h
@@ -0,0 +1,207 @@
+/*
+* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+* Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.de>
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301, USA.
+*/
+
+#ifndef _MXC_IOMUX_MX27_H
+#define _MXC_IOMUX_MX27_H
+
+#ifndef GPIO_PORTA
+#error Please include mach/iomux.h
+#endif
+
+
+/* Primary GPIO pin functions */
+
+#define PA0_PF_USBH2_CLK (GPIO_PORTA | GPIO_PF | 0)
+#define PA1_PF_USBH2_DIR (GPIO_PORTA | GPIO_PF | 1)
+#define PA2_PF_USBH2_DATA7 (GPIO_PORTA | GPIO_PF | 2)
+#define PA3_PF_USBH2_NXT (GPIO_PORTA | GPIO_PF | 3)
+#define PA4_PF_USBH2_STP (GPIO_PORTA | GPIO_PF | 4)
+#define PB22_PF_USBH1_SUSP (GPIO_PORTB | GPIO_PF | 22)
+#define PB25_PF_USBH1_RCV (GPIO_PORTB | GPIO_PF | 25)
+#define PC5_PF_I2C2_SDA (GPIO_PORTC | GPIO_PF | GPIO_IN | 5)
+#define PC6_PF_I2C2_SCL (GPIO_PORTC | GPIO_PF | GPIO_IN | 6)
+#define PC7_PF_USBOTG_DATA5 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 7)
+#define PC8_PF_USBOTG_DATA6 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 8)
+#define PC9_PF_USBOTG_DATA0 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9)
+#define PC10_PF_USBOTG_DATA2 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 10)
+#define PC11_PF_USBOTG_DATA1 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11)
+#define PC12_PF_USBOTG_DATA4 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 12)
+#define PC13_PF_USBOTG_DATA3 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 13)
+#define PC16_PF_SSI4_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 16)
+#define PC17_PF_SSI4_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 17)
+#define PC18_PF_SSI4_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 18)
+#define PC19_PF_SSI4_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 19)
+#define PC25_AF_GPT5_TIN (GPIO_PORTC | GPIO_AF | 25)
+#define PC27_AF_GPT4_TIN (GPIO_PORTC | GPIO_AF | 27)
+#define PD0_PF_SD3_CMD (GPIO_PORTD | GPIO_PF | 0)
+#define PD1_PF_SD3_CLK (GPIO_PORTD | GPIO_PF | 1)
+#define PD2_PF_ATA_DATA0 (GPIO_PORTD | GPIO_PF | 2)
+#define PD3_PF_ATA_DATA1 (GPIO_PORTD | GPIO_PF | 3)
+#define PD4_PF_ATA_DATA2 (GPIO_PORTD | GPIO_PF | 4)
+#define PD5_PF_ATA_DATA3 (GPIO_PORTD | GPIO_PF | 5)
+#define PD6_PF_ATA_DATA4 (GPIO_PORTD | GPIO_PF | 6)
+#define PD7_PF_ATA_DATA5 (GPIO_PORTD | GPIO_PF | 7)
+#define PD8_PF_ATA_DATA6 (GPIO_PORTD | GPIO_PF | 8)
+#define PD9_PF_ATA_DATA7 (GPIO_PORTD | GPIO_PF | 9)
+#define PD10_PF_ATA_DATA8 (GPIO_PORTD | GPIO_PF | 10)
+#define PD11_PF_ATA_DATA9 (GPIO_PORTD | GPIO_PF | 11)
+#define PD12_PF_ATA_DATA10 (GPIO_PORTD | GPIO_PF | 12)
+#define PD13_PF_ATA_DATA11 (GPIO_PORTD | GPIO_PF | 13)
+#define PD14_PF_ATA_DATA12 (GPIO_PORTD | GPIO_PF | 14)
+#define PD15_PF_ATA_DATA13 (GPIO_PORTD | GPIO_PF | 15)
+#define PD16_PF_ATA_DATA14 (GPIO_PORTD | GPIO_PF | 16)
+#define PE0_PF_USBOTG_NXT (GPIO_PORTE | GPIO_PF | GPIO_OUT | 0)
+#define PE1_PF_USBOTG_STP (GPIO_PORTE | GPIO_PF | GPIO_OUT | 1)
+#define PE2_PF_USBOTG_DIR (GPIO_PORTE | GPIO_PF | GPIO_OUT | 2)
+#define PE24_PF_USBOTG_CLK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 24)
+#define PE25_PF_USBOTG_DATA7 (GPIO_PORTE | GPIO_PF | GPIO_OUT | 25)
+#define PF1_PF_NFCLE (GPIO_PORTF | GPIO_PF | 1)
+#define PF3_PF_NFCE (GPIO_PORTF | GPIO_PF | 3)
+#define PF7_PF_PC_POE (GPIO_PORTF | GPIO_PF | 7)
+#define PF8_PF_PC_RW (GPIO_PORTF | GPIO_PF | 8)
+#define PF9_PF_PC_IOIS16 (GPIO_PORTF | GPIO_PF | 9)
+#define PF10_PF_PC_RST (GPIO_PORTF | GPIO_PF | 10)
+#define PF11_PF_PC_BVD2 (GPIO_PORTF | GPIO_PF | 11)
+#define PF12_PF_PC_BVD1 (GPIO_PORTF | GPIO_PF | 12)
+#define PF13_PF_PC_VS2 (GPIO_PORTF | GPIO_PF | 13)
+#define PF14_PF_PC_VS1 (GPIO_PORTF | GPIO_PF | 14)
+#define PF16_PF_PC_PWRON (GPIO_PORTF | GPIO_PF | 16)
+#define PF17_PF_PC_READY (GPIO_PORTF | GPIO_PF | 17)
+#define PF18_PF_PC_WAIT (GPIO_PORTF | GPIO_PF | 18)
+#define PF19_PF_PC_CD2 (GPIO_PORTF | GPIO_PF | 19)
+#define PF20_PF_PC_CD1 (GPIO_PORTF | GPIO_PF | 20)
+#define PF23_PF_ATA_DATA15 (GPIO_PORTF | GPIO_PF | 23)
+
+/* Alternate GPIO pin functions */
+
+#define PB4_AF_MSHC_DATA0 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 4)
+#define PB5_AF_MSHC_DATA1 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 5)
+#define PB6_AF_MSHC_DATA2 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 6)
+#define PB7_AF_MSHC_DATA4 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 7)
+#define PB8_AF_MSHC_BS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 8)
+#define PB9_AF_MSHC_SCLK (GPIO_PORTB | GPIO_AF | GPIO_OUT | 9)
+#define PB10_AF_UART6_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 10)
+#define PB11_AF_UART6_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 11)
+#define PB12_AF_UART6_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 12)
+#define PB13_AF_UART6_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 13)
+#define PB18_AF_UART5_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 18)
+#define PB19_AF_UART5_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 19)
+#define PB20_AF_UART5_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 20)
+#define PB21_AF_UART5_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 21)
+#define PC8_AF_FEC_MDIO (GPIO_PORTC | GPIO_AF | GPIO_IN | 8)
+#define PC24_AF_GPT5_TOUT (GPIO_PORTC | GPIO_AF | 24)
+#define PC26_AF_GPT4_TOUT (GPIO_PORTC | GPIO_AF | 26)
+#define PD1_AF_ETMTRACE_PKT15 (GPIO_PORTD | GPIO_AF | 1)
+#define PD6_AF_ETMTRACE_PKT14 (GPIO_PORTD | GPIO_AF | 6)
+#define PD7_AF_ETMTRACE_PKT13 (GPIO_PORTD | GPIO_AF | 7)
+#define PD9_AF_ETMTRACE_PKT12 (GPIO_PORTD | GPIO_AF | 9)
+#define PD2_AF_SD3_D0 (GPIO_PORTD | GPIO_AF | 2)
+#define PD3_AF_SD3_D1 (GPIO_PORTD | GPIO_AF | 3)
+#define PD4_AF_SD3_D2 (GPIO_PORTD | GPIO_AF | 4)
+#define PD5_AF_SD3_D3 (GPIO_PORTD | GPIO_AF | 5)
+#define PD8_AF_FEC_MDIO (GPIO_PORTD | GPIO_AF | GPIO_IN | 8)
+#define PD10_AF_ETMTRACE_PKT11 (GPIO_PORTD | GPIO_AF | 10)
+#define PD11_AF_ETMTRACE_PKT10 (GPIO_PORTD | GPIO_AF | 11)
+#define PD12_AF_ETMTRACE_PKT9 (GPIO_PORTD | GPIO_AF | 12)
+#define PD13_AF_ETMTRACE_PKT8 (GPIO_PORTD | GPIO_AF | 13)
+#define PD14_AF_ETMTRACE_PKT7 (GPIO_PORTD | GPIO_AF | 14)
+#define PD15_AF_ETMTRACE_PKT6 (GPIO_PORTD | GPIO_AF | 15)
+#define PD16_AF_ETMTRACE_PKT5 (GPIO_PORTD | GPIO_AF | 16)
+#define PF1_AF_ETMTRACE_PKT0 (GPIO_PORTF | GPIO_AF | 1)
+#define PF3_AF_ETMTRACE_PKT2 (GPIO_PORTF | GPIO_AF | 3)
+#define PF5_AF_ETMPIPESTAT11 (GPIO_PORTF | GPIO_AF | 5)
+#define PF7_AF_ATA_BUFFER_EN (GPIO_PORTF | GPIO_AF | 7)
+#define PF8_AF_ATA_IORDY (GPIO_PORTF | GPIO_AF | 8)
+#define PF9_AF_ATA_INTRQ (GPIO_PORTF | GPIO_AF | 9)
+#define PF10_AF_ATA_RESET (GPIO_PORTF | GPIO_AF | 10)
+#define PF11_AF_ATA_DMACK (GPIO_PORTF | GPIO_AF | 11)
+#define PF12_AF_ATA_DMAREQ (GPIO_PORTF | GPIO_AF | 12)
+#define PF13_AF_ATA_DA0 (GPIO_PORTF | GPIO_AF | 13)
+#define PF14_AF_ATA_DA1 (GPIO_PORTF | GPIO_AF | 14)
+#define PF15_AF_ETMTRACE_SYNC (GPIO_PORTF | GPIO_AF | 15)
+#define PF16_AF_ATA_DA2 (GPIO_PORTF | GPIO_AF | 16)
+#define PF17_AF_ATA_CS0 (GPIO_PORTF | GPIO_AF | 17)
+#define PF18_AF_ATA_CS1 (GPIO_PORTF | GPIO_AF | 18)
+#define PF19_AF_ATA_DIOW (GPIO_PORTF | GPIO_AF | 19)
+#define PF20_AF_ATA_DIOR (GPIO_PORTF | GPIO_AF | 20)
+#define PF22_AF_ETMTRACE_CLK (GPIO_PORTF | GPIO_AF | 22)
+#define PF23_AF_ETMTRACE_PKT4 (GPIO_PORTF | GPIO_AF | 23)
+
+/* AIN GPIO pin functions */
+
+#define PC14_AIN_SSI1_MCLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14)
+#define PC15_AIN_GPT6_TOUT (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 15)
+#define PD0_AIN_FEC_TXD0 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 0)
+#define PD1_AIN_FEC_TXD1 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 1)
+#define PD2_AIN_FEC_TXD2 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 2)
+#define PD3_AIN_FEC_TXD3 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 3)
+#define PD9_AIN_FEC_MDC (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 9)
+#define PD16_AIN_FEC_TX_ER (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 16)
+#define PD27_AIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 27)
+#define PF23_AIN_FEC_TX_EN (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 23)
+
+/* BIN GPIO pin functions */
+
+#define PC14_BIN_SSI2_MCLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14)
+
+/* CIN GPIO pin functions */
+
+#define PD2_CIN_SLCDC1_DAT0 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 2)
+#define PD3_CIN_SLCDC1_DAT1 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 3)
+#define PD4_CIN_SLCDC1_DAT2 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 4)
+#define PD5_CIN_SLCDC1_DAT3 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 5)
+#define PD6_CIN_SLCDC1_DAT4 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 6)
+#define PD7_CIN_SLCDC1_DAT5 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 7)
+#define PD8_CIN_SLCDC1_DAT6 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 8)
+#define PD9_CIN_SLCDC1_DAT7 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 9)
+#define PD10_CIN_SLCDC1_DAT8 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 10)
+#define PD11_CIN_SLCDC1_DAT9 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 11)
+#define PD12_CIN_SLCDC1_DAT10 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 12)
+#define PD13_CIN_SLCDC1_DAT11 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 13)
+#define PD14_CIN_SLCDC1_DAT12 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 14)
+#define PD15_CIN_SLCDC1_DAT13 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 15)
+#define PD16_CIN_SLCDC1_DAT14 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 16)
+#define PD23_CIN_SLCDC1_DAT15 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 23)
+#define PF27_CIN_EXT_DMA_GRANT (GPIO_PORTF | GPIO_CIN | GPIO_OUT | 27)
+/* LCDC_TESTx on PBxx omitted, because it's not clear what they do */
+
+/* AOUT GPIO pin functions */
+
+#define PC14_AOUT_GPT6_TIN (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 14)
+#define PD4_AOUT_FEC_RX_ER (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 4)
+#define PD5_AOUT_FEC_RXD1 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 5)
+#define PD6_AOUT_FEC_RXD2 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 6)
+#define PD7_AOUT_FEC_RXD3 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 7)
+#define PD10_AOUT_FEC_CRS (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 10)
+#define PD11_AOUT_FEC_TX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 11)
+#define PD12_AOUT_FEC_RXD0 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 12)
+#define PD13_AOUT_FEC_RX_DV (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 13)
+#define PD14_AOUT_FEC_RX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 14)
+#define PD15_AOUT_FEC_COL (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 15)
+
+#define PC17_BOUT_PC_IOIS16 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 17)
+#define PC18_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 18)
+#define PC19_BOUT_PC_BVD1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 19)
+#define PC28_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 28)
+#define PC29_BOUT_PC_VS1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 29)
+#define PC30_BOUT_PC_READY (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 30)
+#define PC31_BOUT_PC_WAIT (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 31)
+
+
+#endif /* _MXC_GPIO_MX1_MX2_H */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h
new file mode 100644
index 000000000000..fb5ae638e79f
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h
@@ -0,0 +1,237 @@
+/*
+* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+* Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.de>
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301, USA.
+*/
+
+#ifndef _MXC_IOMUX_MX2x_H
+#define _MXC_IOMUX_MX2x_H
+
+#ifndef GPIO_PORTA
+#error Please include mach/iomux.h
+#endif
+
+
+/* Primary GPIO pin functions */
+
+#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_PF | GPIO_OUT | 5)
+#define PA6_PF_LD0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 6)
+#define PA7_PF_LD1 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 7)
+#define PA8_PF_LD2 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 8)
+#define PA9_PF_LD3 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 9)
+#define PA10_PF_LD4 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 10)
+#define PA11_PF_LD5 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 11)
+#define PA12_PF_LD6 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 12)
+#define PA13_PF_LD7 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 13)
+#define PA14_PF_LD8 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 14)
+#define PA15_PF_LD9 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15)
+#define PA16_PF_LD10 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16)
+#define PA17_PF_LD11 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 17)
+#define PA18_PF_LD12 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 18)
+#define PA19_PF_LD13 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 19)
+#define PA20_PF_LD14 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 20)
+#define PA21_PF_LD15 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 21)
+#define PA22_PF_LD16 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 22)
+#define PA23_PF_LD17 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 23)
+#define PA24_PF_REV (GPIO_PORTA | GPIO_PF | GPIO_OUT | 24)
+#define PA25_PF_CLS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 25)
+#define PA26_PF_PS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 26)
+#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_PF | GPIO_OUT | 27)
+#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 28)
+#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 29)
+#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_PF | GPIO_OUT | 30)
+#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_PF | GPIO_OUT | 31)
+#define PB4_PF_SD2_D0 (GPIO_PORTB | GPIO_PF | 4)
+#define PB5_PF_SD2_D1 (GPIO_PORTB | GPIO_PF | 5)
+#define PB6_PF_SD2_D2 (GPIO_PORTB | GPIO_PF | 6)
+#define PB7_PF_SD2_D3 (GPIO_PORTB | GPIO_PF | 7)
+#define PB8_PF_SD2_CMD (GPIO_PORTB | GPIO_PF | 8)
+#define PB9_PF_SD2_CLK (GPIO_PORTB | GPIO_PF | 9)
+#define PB10_PF_CSI_D0 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 10)
+#define PB11_PF_CSI_D1 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 11)
+#define PB12_PF_CSI_D2 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 12)
+#define PB13_PF_CSI_D3 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 13)
+#define PB14_PF_CSI_D4 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 14)
+#define PB15_PF_CSI_MCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 15)
+#define PB16_PF_CSI_PIXCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 16)
+#define PB17_PF_CSI_D5 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 17)
+#define PB18_PF_CSI_D6 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 18)
+#define PB19_PF_CSI_D7 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 19)
+#define PB20_PF_CSI_VSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 20)
+#define PB21_PF_CSI_HSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 21)
+#define PB23_PF_USB_PWR (GPIO_PORTB | GPIO_PF | 23)
+#define PB24_PF_USB_OC (GPIO_PORTB | GPIO_PF | 24)
+#define PB26_PF_USBH1_FS (GPIO_PORTB | GPIO_PF | 26)
+#define PB27_PF_USBH1_OE (GPIO_PORTB | GPIO_PF | 27)
+#define PB28_PF_USBH1_TXDM (GPIO_PORTB | GPIO_PF | 28)
+#define PB29_PF_USBH1_TXDP (GPIO_PORTB | GPIO_PF | 29)
+#define PB30_PF_USBH1_RXDM (GPIO_PORTB | GPIO_PF | 30)
+#define PB31_PF_USBH1_RXDP (GPIO_PORTB | GPIO_PF | 31)
+#define PC14_PF_TOUT (GPIO_PORTC | GPIO_PF | 14)
+#define PC15_PF_TIN (GPIO_PORTC | GPIO_PF | 15)
+#define PC20_PF_SSI1_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 20)
+#define PC21_PF_SSI1_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 21)
+#define PC22_PF_SSI1_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 22)
+#define PC23_PF_SSI1_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 23)
+#define PC24_PF_SSI2_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 24)
+#define PC25_PF_SSI2_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 25)
+#define PC26_PF_SSI2_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 26)
+#define PC27_PF_SSI2_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 27)
+#define PC28_PF_SSI3_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 28)
+#define PC29_PF_SSI3_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 29)
+#define PC30_PF_SSI3_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 30)
+#define PC31_PF_SSI3_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 31)
+#define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
+#define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
+#define PD19_PF_CSPI2_SS2 (GPIO_PORTD | GPIO_PF | 19)
+#define PD20_PF_CSPI2_SS1 (GPIO_PORTD | GPIO_PF | 20)
+#define PD21_PF_CSPI2_SS0 (GPIO_PORTD | GPIO_PF | 21)
+#define PD22_PF_CSPI2_SCLK (GPIO_PORTD | GPIO_PF | 22)
+#define PD23_PF_CSPI2_MISO (GPIO_PORTD | GPIO_PF | 23)
+#define PD24_PF_CSPI2_MOSI (GPIO_PORTD | GPIO_PF | 24)
+#define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
+#define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
+#define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)
+#define PD28_PF_CSPI1_SS0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28)
+#define PD29_PF_CSPI1_SCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29)
+#define PD30_PF_CSPI1_MISO (GPIO_PORTD | GPIO_PF | GPIO_IN | 30)
+#define PD31_PF_CSPI1_MOSI (GPIO_PORTD | GPIO_PF | GPIO_OUT | 31)
+#define PE3_PF_UART2_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 3)
+#define PE4_PF_UART2_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 4)
+#define PE5_PF_PWMO (GPIO_PORTE | GPIO_PF | 5)
+#define PE6_PF_UART2_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 6)
+#define PE7_PF_UART2_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 7)
+#define PE8_PF_UART3_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 8)
+#define PE9_PF_UART3_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 9)
+#define PE10_PF_UART3_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 10)
+#define PE11_PF_UART3_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 11)
+#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 12)
+#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 13)
+#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 14)
+#define PE15_PF_UART1_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 15)
+#define PE16_PF_RTCK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 16)
+#define PE17_PF_RESET_OUT (GPIO_PORTE | GPIO_PF | 17)
+#define PE18_PF_SD1_D0 (GPIO_PORTE | GPIO_PF | 18)
+#define PE19_PF_SD1_D1 (GPIO_PORTE | GPIO_PF | 19)
+#define PE20_PF_SD1_D2 (GPIO_PORTE | GPIO_PF | 20)
+#define PE21_PF_SD1_D3 (GPIO_PORTE | GPIO_PF | 21)
+#define PE22_PF_SD1_CMD (GPIO_PORTE | GPIO_PF | 22)
+#define PE23_PF_SD1_CLK (GPIO_PORTE | GPIO_PF | 23)
+#define PF0_PF_NRFB (GPIO_PORTF | GPIO_PF | 0)
+#define PF2_PF_NFWP (GPIO_PORTF | GPIO_PF | 2)
+#define PF4_PF_NFALE (GPIO_PORTF | GPIO_PF | 4)
+#define PF5_PF_NFRE (GPIO_PORTF | GPIO_PF | 5)
+#define PF6_PF_NFWE (GPIO_PORTF | GPIO_PF | 6)
+#define PF15_PF_CLKO (GPIO_PORTF | GPIO_PF | 15)
+#define PF21_PF_CS4 (GPIO_PORTF | GPIO_PF | 21)
+#define PF22_PF_CS5 (GPIO_PORTF | GPIO_PF | 22)
+
+/* Alternate GPIO pin functions */
+
+#define PB26_AF_UART4_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 26)
+#define PB28_AF_UART4_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 28)
+#define PB29_AF_UART4_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 29)
+#define PB31_AF_UART4_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 31)
+#define PC28_AF_SLCDC2_D0 (GPIO_PORTC | GPIO_AF | 28)
+#define PC29_AF_SLCDC2_RS (GPIO_PORTC | GPIO_AF | 29)
+#define PC30_AF_SLCDC2_CS (GPIO_PORTC | GPIO_AF | 30)
+#define PC31_AF_SLCDC2_CLK (GPIO_PORTC | GPIO_AF | 31)
+#define PD19_AF_USBH2_DATA4 (GPIO_PORTD | GPIO_AF | 19)
+#define PD20_AF_USBH2_DATA3 (GPIO_PORTD | GPIO_AF | 20)
+#define PD21_AF_USBH2_DATA6 (GPIO_PORTD | GPIO_AF | 21)
+#define PD22_AF_USBH2_DATA0 (GPIO_PORTD | GPIO_AF | 22)
+#define PD23_AF_USBH2_DATA2 (GPIO_PORTD | GPIO_AF | 23)
+#define PD24_AF_USBH2_DATA1 (GPIO_PORTD | GPIO_AF | 24)
+#define PD26_AF_USBH2_DATA5 (GPIO_PORTD | GPIO_AF | 26)
+#define PE0_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 0)
+#define PE1_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 1)
+#define PE2_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 2)
+#define PE3_AF_KP_COL7 (GPIO_PORTE | GPIO_AF | 3)
+#define PE4_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 4)
+#define PE6_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 6)
+#define PE7_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 7)
+#define PE16_AF_OWIRE (GPIO_PORTE | GPIO_AF | 16)
+#define PE18_AF_CSPI3_MISO (GPIO_PORTE | GPIO_AF | GPIO_IN | 18)
+#define PE21_AF_CSPI3_SS (GPIO_PORTE | GPIO_AF | GPIO_OUT | 21)
+#define PE22_AF_CSPI3_MOSI (GPIO_PORTE | GPIO_AF | GPIO_OUT | 22)
+#define PE23_AF_CSPI3_SCLK (GPIO_PORTE | GPIO_AF | GPIO_OUT | 23)
+
+/* AIN GPIO pin functions */
+
+#define PA6_AIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 6)
+#define PA7_AIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 7)
+#define PA8_AIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 8)
+#define PA0_AIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0)
+#define PA11_AIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 11)
+#define PA13_AIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 13)
+#define PA15_AIN_SLCDC1_DAT9 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 15)
+#define PA17_AIN_SLCDC1_DAT11 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17)
+#define PA19_AIN_SLCDC1_DAT13 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 19)
+#define PA21_AIN_SLCDC1_DAT15 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 21)
+#define PA22_AIN_EXT_DMAGRANT (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 22)
+#define PA24_AIN_SLCDC1_D0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 24)
+#define PA25_AIN_SLCDC1_RS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 25)
+#define PA26_AIN_SLCDC1_CS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 26)
+#define PA27_AIN_SLCDC1_CLK (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 27)
+#define PB6_AIN_SLCDC1_D0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 6)
+#define PB7_AIN_SLCDC1_RS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 7)
+#define PB8_AIN_SLCDC1_CS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 8)
+#define PB9_AIN_SLCDC1_CLK (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 9)
+#define PB25_AIN_SLCDC1_DAT0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 25)
+#define PB26_AIN_SLCDC1_DAT1 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 26)
+#define PB27_AIN_SLCDC1_DAT2 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 27)
+#define PB28_AIN_SLCDC1_DAT3 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 28)
+#define PB29_AIN_SLCDC1_DAT4 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 29)
+#define PB30_AIN_SLCDC1_DAT5 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 30)
+#define PB31_AIN_SLCDC1_DAT6 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 31)
+#define PC5_AIN_SLCDC1_DAT7 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 5)
+#define PC6_AIN_SLCDC1_DAT8 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 6)
+#define PC7_AIN_SLCDC1_DAT9 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 7)
+#define PC8_AIN_SLCDC1_DAT10 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 8)
+#define PC9_AIN_SLCDC1_DAT11 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 9)
+#define PC10_AIN_SLCDC1_DAT12 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 10)
+#define PC11_AIN_SLCDC1_DAT13 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 11)
+#define PC12_AIN_SLCDC1_DAT14 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 12)
+#define PC13_AIN_SLCDC1_DAT15 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 13)
+#define PE5_AIN_PC_SPKOUT (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 5)
+
+/* BIN GPIO pin functions */
+
+#define PE5_BIN_TOUT2 (GPIO_PORTE | GPIO_BIN | GPIO_OUT | 5)
+
+/* CIN GPIO pin functions */
+
+#define PA14_CIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 14)
+#define PA15_CIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 15)
+#define PA16_CIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 16)
+#define PA17_CIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 17)
+#define PA18_CIN_SLCDC1_DAT4 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 18)
+#define PA19_CIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 19)
+#define PA20_CIN_SLCDC1_DAT6 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 20)
+#define PA21_CIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 21)
+#define PB30_CIN_UART4_CTS (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 30)
+#define PE5_CIN_TOUT3 (GPIO_PORTE | GPIO_CIN | GPIO_OUT | 5)
+
+/* AOUT GPIO pin functions */
+
+#define PB29_AOUT_UART4_RXD (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 29)
+#define PB31_AOUT_UART4_RTS (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 31)
+#define PC8_AOUT_USBOTG_TXR_INT (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 8)
+#define PC15_AOUT_WKGD (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 15)
+#define PF21_AOUT_DTACK (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 21)
+
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
index c9198c0aea18..ab838cfe94f9 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
@@ -92,7 +92,7 @@ enum iomux_gp_func {
MUX_EXTDMAREQ2_MBX_SEL = 1 << 15,
MUX_TAMPER_DETECT_EN = 1 << 16,
MUX_PGP_USB_4WIRE = 1 << 17,
- MUX_PGB_USB_COMMON = 1 << 18,
+ MUX_PGP_USB_COMMON = 1 << 18,
MUX_SDHC_MEMSTICK1 = 1 << 19,
MUX_SDHC_MEMSTICK2 = 1 << 20,
MUX_PGP_SPLL_BYP = 1 << 21,
@@ -109,21 +109,44 @@ enum iomux_gp_func {
};
/*
- * This function enables/disables the general purpose function for a particular
- * signal.
+ * setups a single pin:
+ * - reserves the pin so that it is not claimed by another driver
+ * - setups the iomux according to the configuration
+ * - if the pin is configured as a GPIO, we claim it throug kernel gpiolib
+ */
+int mxc_iomux_setup_pin(const unsigned int pin, const char *label);
+/*
+ * setups mutliple pins
+ * convenient way to call the above function with tables
*/
-void iomux_config_gpr(enum iomux_gp_func , bool);
+int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
+ const char *label);
/*
- * set the mode for a IOMUX pin.
+ * releases a single pin:
+ * - make it available for a future use by another driver
+ * - frees the GPIO if the pin was configured as GPIO
+ * - DOES NOT reconfigure the IOMUX in its reset state
*/
-int mxc_iomux_mode(unsigned int);
+void mxc_iomux_release_pin(const unsigned int pin);
+/*
+ * releases multiple pins
+ * convenvient way to call the above function with tables
+ */
+void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count);
/*
* This function enables/disables the general purpose function for a particular
* signal.
*/
-void mxc_iomux_set_gpr(enum iomux_gp_func, bool);
+void mxc_iomux_set_gpr(enum iomux_gp_func, bool en);
+
+/*
+ * This function only configures the iomux hardware.
+ * It is called by the setup functions and should not be called directly anymore.
+ * It is here visible for backward compatibility
+ */
+int mxc_iomux_mode(unsigned int pin_mode);
#define IOMUX_PADNUM_MASK 0x1ff
#define IOMUX_GPIONUM_SHIFT 9
@@ -144,6 +167,11 @@ void mxc_iomux_set_gpr(enum iomux_gp_func, bool);
MXC_GPIO_IRQ_START)
/*
+ * The number of gpio devices among the pads
+ */
+#define GPIO_PORT_MAX 3
+
+/*
* This enumeration is constructed based on the Section
* "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated
* value is constructed based on the rules described above.
@@ -480,6 +508,9 @@ enum iomux_pins {
MX31_PIN_CAPTURE = IOMUX_PIN( 7, 327),
};
+#define PIN_MAX 327
+#define NB_PORTS 12 /* NB_PINS/32, we chose 32 pins per "PORT" */
+
/*
* Convenience values for use with mxc_iomux_mode()
*
@@ -507,7 +538,9 @@ enum iomux_pins {
#define MX31_PIN_CSPI1_SS1__SS1 IOMUX_MODE(MX31_PIN_CSPI1_SS1, IOMUX_CONFIG_FUNC)
#define MX31_PIN_CSPI1_SS2__SS2 IOMUX_MODE(MX31_PIN_CSPI1_SS2, IOMUX_CONFIG_FUNC)
#define MX31_PIN_CSPI2_MOSI__MOSI IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_MOSI__SCL IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1)
#define MX31_PIN_CSPI2_MISO__MISO IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_MISO__SDA IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1)
#define MX31_PIN_CSPI2_SCLK__SCLK IOMUX_MODE(MX31_PIN_CSPI2_SCLK, IOMUX_CONFIG_FUNC)
#define MX31_PIN_CSPI2_SPI_RDY__SPI_RDY IOMUX_MODE(MX31_PIN_CSPI2_SPI_RDY, IOMUX_CONFIG_FUNC)
#define MX31_PIN_CSPI2_SS0__SS0 IOMUX_MODE(MX31_PIN_CSPI2_SS0, IOMUX_CONFIG_FUNC)
@@ -525,6 +558,33 @@ enum iomux_pins {
#define MX31_PIN_SD1_DATA0__SD1_DATA0 IOMUX_MODE(MX31_PIN_SD1_DATA0, IOMUX_CONFIG_FUNC)
#define MX31_PIN_SD1_CLK__SD1_CLK IOMUX_MODE(MX31_PIN_SD1_CLK, IOMUX_CONFIG_FUNC)
#define MX31_PIN_SD1_CMD__SD1_CMD IOMUX_MODE(MX31_PIN_SD1_CMD, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD0__LD0 IOMUX_MODE(MX31_PIN_LD0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD1__LD1 IOMUX_MODE(MX31_PIN_LD1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD2__LD2 IOMUX_MODE(MX31_PIN_LD2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD3__LD3 IOMUX_MODE(MX31_PIN_LD3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD4__LD4 IOMUX_MODE(MX31_PIN_LD4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD5__LD5 IOMUX_MODE(MX31_PIN_LD5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD6__LD6 IOMUX_MODE(MX31_PIN_LD6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD7__LD7 IOMUX_MODE(MX31_PIN_LD7, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD8__LD8 IOMUX_MODE(MX31_PIN_LD8, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD9__LD9 IOMUX_MODE(MX31_PIN_LD9, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD10__LD10 IOMUX_MODE(MX31_PIN_LD10, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD11__LD11 IOMUX_MODE(MX31_PIN_LD11, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD12__LD12 IOMUX_MODE(MX31_PIN_LD12, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD13__LD13 IOMUX_MODE(MX31_PIN_LD13, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD14__LD14 IOMUX_MODE(MX31_PIN_LD14, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD15__LD15 IOMUX_MODE(MX31_PIN_LD15, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD16__LD16 IOMUX_MODE(MX31_PIN_LD16, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD17__LD17 IOMUX_MODE(MX31_PIN_LD17, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_VSYNC3__VSYNC3 IOMUX_MODE(MX31_PIN_VSYNC3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_HSYNC__HSYNC IOMUX_MODE(MX31_PIN_HSYNC, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_FPSHIFT__FPSHIFT IOMUX_MODE(MX31_PIN_FPSHIFT, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DRDY0__DRDY0 IOMUX_MODE(MX31_PIN_DRDY0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_D3_REV__D3_REV IOMUX_MODE(MX31_PIN_D3_REV, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CONTRAST__CONTRAST IOMUX_MODE(MX31_PIN_CONTRAST, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_D3_SPL__D3_SPL IOMUX_MODE(MX31_PIN_D3_SPL, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_D3_CLS__D3_CLS IOMUX_MODE(MX31_PIN_D3_CLS, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LCS0__GPI03_23 IOMUX_MODE(MX31_PIN_LCS0, IOMUX_CONFIG_GPIO)
/*XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed by cspi2_ss0, cspi2_ss1, cspi1_ss0
* cspi1_ss1*/
diff --git a/arch/arm/plat-mxc/include/mach/iomux.h b/arch/arm/plat-mxc/include/mach/iomux.h
new file mode 100644
index 000000000000..171f8adc1109
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux.h
@@ -0,0 +1,127 @@
+/*
+* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+* Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.de>
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+* MA 02110-1301, USA.
+*/
+
+#ifndef _MXC_IOMUX_H
+#define _MXC_IOMUX_H
+
+/*
+* GPIO Module and I/O Multiplexer
+* x = 0..3 for reg_A, reg_B, reg_C, reg_D
+*/
+#define VA_GPIO_BASE IO_ADDRESS(GPIO_BASE_ADDR)
+#define MXC_DDIR(x) (0x00 + ((x) << 8))
+#define MXC_OCR1(x) (0x04 + ((x) << 8))
+#define MXC_OCR2(x) (0x08 + ((x) << 8))
+#define MXC_ICONFA1(x) (0x0c + ((x) << 8))
+#define MXC_ICONFA2(x) (0x10 + ((x) << 8))
+#define MXC_ICONFB1(x) (0x14 + ((x) << 8))
+#define MXC_ICONFB2(x) (0x18 + ((x) << 8))
+#define MXC_DR(x) (0x1c + ((x) << 8))
+#define MXC_GIUS(x) (0x20 + ((x) << 8))
+#define MXC_SSR(x) (0x24 + ((x) << 8))
+#define MXC_ICR1(x) (0x28 + ((x) << 8))
+#define MXC_ICR2(x) (0x2c + ((x) << 8))
+#define MXC_IMR(x) (0x30 + ((x) << 8))
+#define MXC_ISR(x) (0x34 + ((x) << 8))
+#define MXC_GPR(x) (0x38 + ((x) << 8))
+#define MXC_SWR(x) (0x3c + ((x) << 8))
+#define MXC_PUEN(x) (0x40 + ((x) << 8))
+
+#ifdef CONFIG_ARCH_MX1
+# define GPIO_PORT_MAX 3
+#endif
+#ifdef CONFIG_ARCH_MX2
+# define GPIO_PORT_MAX 5
+#endif
+
+#ifndef GPIO_PORT_MAX
+# error "GPIO config port count unknown!"
+#endif
+
+#define GPIO_PIN_MASK 0x1f
+
+#define GPIO_PORT_SHIFT 5
+#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT)
+
+#define GPIO_PORTA (0 << GPIO_PORT_SHIFT)
+#define GPIO_PORTB (1 << GPIO_PORT_SHIFT)
+#define GPIO_PORTC (2 << GPIO_PORT_SHIFT)
+#define GPIO_PORTD (3 << GPIO_PORT_SHIFT)
+#define GPIO_PORTE (4 << GPIO_PORT_SHIFT)
+#define GPIO_PORTF (5 << GPIO_PORT_SHIFT)
+
+#define GPIO_OUT (1 << 8)
+#define GPIO_IN (0 << 8)
+#define GPIO_PUEN (1 << 9)
+
+#define GPIO_PF (1 << 10)
+#define GPIO_AF (1 << 11)
+
+#define GPIO_OCR_SHIFT 12
+#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT)
+#define GPIO_AIN (0 << GPIO_OCR_SHIFT)
+#define GPIO_BIN (1 << GPIO_OCR_SHIFT)
+#define GPIO_CIN (2 << GPIO_OCR_SHIFT)
+#define GPIO_GPIO (3 << GPIO_OCR_SHIFT)
+
+#define GPIO_AOUT_SHIFT 14
+#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT)
+
+#define GPIO_BOUT_SHIFT 16
+#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT)
+
+
+#ifdef CONFIG_ARCH_MX1
+#include <mach/iomux-mx1.h>
+#endif
+#ifdef CONFIG_ARCH_MX2
+#include <mach/iomux-mx2x.h>
+#ifdef CONFIG_MACH_MX21
+#include <mach/iomux-mx21.h>
+#endif
+#ifdef CONFIG_MACH_MX27
+#include <mach/iomux-mx27.h>
+#endif
+#endif
+
+
+/* decode irq number to use with IMR(x), ISR(x) and friends */
+#define IRQ_TO_REG(irq) ((irq - MXC_INTERNAL_IRQS) >> 5)
+
+#define IRQ_GPIOA(x) (MXC_GPIO_IRQ_START + x)
+#define IRQ_GPIOB(x) (IRQ_GPIOA(32) + x)
+#define IRQ_GPIOC(x) (IRQ_GPIOB(32) + x)
+#define IRQ_GPIOD(x) (IRQ_GPIOC(32) + x)
+#define IRQ_GPIOE(x) (IRQ_GPIOD(32) + x)
+
+
+extern void mxc_gpio_mode(int gpio_mode);
+extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
+ const char *label);
+extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count);
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
index 0b808399097f..e0783e619580 100644
--- a/arch/arm/plat-mxc/include/mach/memory.h
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -14,7 +14,12 @@
#if defined CONFIG_ARCH_MX1
#define PHYS_OFFSET UL(0x08000000)
#elif defined CONFIG_ARCH_MX2
+#ifdef CONFIG_MACH_MX21
+#define PHYS_OFFSET UL(0xC0000000)
+#endif
+#ifdef CONFIG_MACH_MX27
#define PHYS_OFFSET UL(0xA0000000)
+#endif
#elif defined CONFIG_ARCH_MX3
#define PHYS_OFFSET UL(0x80000000)
#endif
diff --git a/arch/arm/plat-mxc/include/mach/mx21.h b/arch/arm/plat-mxc/include/mach/mx21.h
new file mode 100644
index 000000000000..e8c4cf56c24e
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx21.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2009 Holger Schurig, hs4233@mail.mn-solutions.de
+ *
+ * This contains i.MX21-specific hardware definitions. For those
+ * hardware pieces that are common between i.MX21 and i.MX27, have a
+ * look at mx2x.h.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_MX21_H__
+#define __ASM_ARCH_MXC_MX21_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+
+/* Memory regions and CS */
+#define SDRAM_BASE_ADDR 0xC0000000
+#define CSD1_BASE_ADDR 0xC4000000
+
+#define CS0_BASE_ADDR 0xC8000000
+#define CS1_BASE_ADDR 0xCC000000
+#define CS2_BASE_ADDR 0xD0000000
+#define CS3_BASE_ADDR 0xD1000000
+#define CS4_BASE_ADDR 0xD2000000
+#define CS5_BASE_ADDR 0xDD000000
+#define PCMCIA_MEM_BASE_ADDR 0xD4000000
+
+/* NAND, SDRAM, WEIM etc controllers */
+#define X_MEMC_BASE_ADDR 0xDF000000
+#define X_MEMC_BASE_ADDR_VIRT 0xF4200000
+#define X_MEMC_SIZE SZ_256K
+
+#define SDRAMC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x0000)
+#define EIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000)
+#define PCMCIA_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000)
+#define NFC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000)
+
+#define IRAM_BASE_ADDR 0xFFFFE800 /* internal ram */
+
+/* this CPU supports up to 192 GPIOs (don't forget the baseboard!) */
+#define ARCH_NR_GPIOS (6*32 + 16)
+
+/* fixed interrupt numbers */
+#define MXC_INT_USBCTRL 58
+#define MXC_INT_USBCTRL 58
+#define MXC_INT_USBMNP 57
+#define MXC_INT_USBFUNC 56
+#define MXC_INT_USBHOST 55
+#define MXC_INT_USBDMA 54
+#define MXC_INT_USBWKUP 53
+#define MXC_INT_EMMADEC 50
+#define MXC_INT_EMMAENC 49
+#define MXC_INT_BMI 30
+#define MXC_INT_FIRI 9
+
+/* fixed DMA request numbers */
+#define DMA_REQ_BMI_RX 29
+#define DMA_REQ_BMI_TX 28
+#define DMA_REQ_FIRI_RX 4
+
+#endif /* __ASM_ARCH_MXC_MX21_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h
index 0313be720552..6e93f2c0b7bb 100644
--- a/arch/arm/plat-mxc/include/mach/mx27.h
+++ b/arch/arm/plat-mxc/include/mach/mx27.h
@@ -2,6 +2,10 @@
* Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
*
+ * This contains i.MX27-specific hardware definitions. For those
+ * hardware pieces that are common between i.MX21 and i.MX27, have a
+ * look at mx2x.h.
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@@ -27,35 +31,6 @@
/* IRAM */
#define IRAM_BASE_ADDR 0xFFFF4C00 /* internal ram */
-/* Register offests */
-#define AIPI_BASE_ADDR 0x10000000
-#define AIPI_BASE_ADDR_VIRT 0xF4000000
-#define AIPI_SIZE SZ_1M
-
-#define DMA_BASE_ADDR (AIPI_BASE_ADDR + 0x01000)
-#define WDOG_BASE_ADDR (AIPI_BASE_ADDR + 0x02000)
-#define GPT1_BASE_ADDR (AIPI_BASE_ADDR + 0x03000)
-#define GPT2_BASE_ADDR (AIPI_BASE_ADDR + 0x04000)
-#define GPT3_BASE_ADDR (AIPI_BASE_ADDR + 0x05000)
-#define PWM_BASE_ADDR (AIPI_BASE_ADDR + 0x06000)
-#define RTC_BASE_ADDR (AIPI_BASE_ADDR + 0x07000)
-#define KPP_BASE_ADDR (AIPI_BASE_ADDR + 0x08000)
-#define OWIRE_BASE_ADDR (AIPI_BASE_ADDR + 0x09000)
-#define UART1_BASE_ADDR (AIPI_BASE_ADDR + 0x0A000)
-#define UART2_BASE_ADDR (AIPI_BASE_ADDR + 0x0B000)
-#define UART3_BASE_ADDR (AIPI_BASE_ADDR + 0x0C000)
-#define UART4_BASE_ADDR (AIPI_BASE_ADDR + 0x0D000)
-#define CSPI1_BASE_ADDR (AIPI_BASE_ADDR + 0x0E000)
-#define CSPI2_BASE_ADDR (AIPI_BASE_ADDR + 0x0F000)
-#define SSI1_BASE_ADDR (AIPI_BASE_ADDR + 0x10000)
-#define SSI2_BASE_ADDR (AIPI_BASE_ADDR + 0x11000)
-#define I2C_BASE_ADDR (AIPI_BASE_ADDR + 0x12000)
-#define SDHC1_BASE_ADDR (AIPI_BASE_ADDR + 0x13000)
-#define SDHC2_BASE_ADDR (AIPI_BASE_ADDR + 0x14000)
-#define GPIO_BASE_ADDR (AIPI_BASE_ADDR + 0x15000)
-#define AUDMUX_BASE_ADDR (AIPI_BASE_ADDR + 0x16000)
-
-#define CSPI3_BASE_ADDR (AIPI_BASE_ADDR + 0x17000)
#define MSHC_BASE_ADDR (AIPI_BASE_ADDR + 0x18000)
#define GPT5_BASE_ADDR (AIPI_BASE_ADDR + 0x19000)
#define GPT4_BASE_ADDR (AIPI_BASE_ADDR + 0x1A000)
@@ -64,55 +39,24 @@
#define I2C2_BASE_ADDR (AIPI_BASE_ADDR + 0x1D000)
#define SDHC3_BASE_ADDR (AIPI_BASE_ADDR + 0x1E000)
#define GPT6_BASE_ADDR (AIPI_BASE_ADDR + 0x1F000)
-
-#define LCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x21000)
-#define SLCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x22000)
#define VPU_BASE_ADDR (AIPI_BASE_ADDR + 0x23000)
-#define USBOTG_BASE_ADDR (AIPI_BASE_ADDR + 0x24000)
-/* for mx27*/
#define OTG_BASE_ADDR USBOTG_BASE_ADDR
#define SAHARA_BASE_ADDR (AIPI_BASE_ADDR + 0x25000)
-#define EMMA_PP_BASE_ADDR (AIPI_BASE_ADDR + 0x26000)
-#define EMMA_PRP_BASE_ADDR (AIPI_BASE_ADDR + 0x26400)
-#define CCM_BASE_ADDR (AIPI_BASE_ADDR + 0x27000)
-#define SYSCTRL_BASE_ADDR (AIPI_BASE_ADDR + 0x27800)
#define IIM_BASE_ADDR (AIPI_BASE_ADDR + 0x28000)
-
#define RTIC_BASE_ADDR (AIPI_BASE_ADDR + 0x2A000)
#define FEC_BASE_ADDR (AIPI_BASE_ADDR + 0x2B000)
#define SCC_BASE_ADDR (AIPI_BASE_ADDR + 0x2C000)
#define ETB_BASE_ADDR (AIPI_BASE_ADDR + 0x3B000)
#define ETB_RAM_BASE_ADDR (AIPI_BASE_ADDR + 0x3C000)
-#define JAM_BASE_ADDR (AIPI_BASE_ADDR + 0x3E000)
-#define MAX_BASE_ADDR (AIPI_BASE_ADDR + 0x3F000)
-
-/* ROMP and AVIC */
+/* ROM patch */
#define ROMP_BASE_ADDR 0x10041000
-#define AVIC_BASE_ADDR 0x10040000
-
-#define SAHB1_BASE_ADDR 0x80000000
-#define SAHB1_BASE_ADDR_VIRT 0xF4100000
-#define SAHB1_SIZE SZ_1M
-
-#define CSI_BASE_ADDR (SAHB1_BASE_ADDR + 0x0000)
#define ATA_BASE_ADDR (SAHB1_BASE_ADDR + 0x1000)
-/* NAND, SDRAM, WEIM, M3IF, EMI controllers */
-#define X_MEMC_BASE_ADDR 0xD8000000
-#define X_MEMC_BASE_ADDR_VIRT 0xF4200000
-#define X_MEMC_SIZE SZ_1M
-
-#define NFC_BASE_ADDR (X_MEMC_BASE_ADDR)
-#define SDRAMC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000)
-#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000)
-#define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000)
-#define PCMCIA_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000)
-
/* Memory regions and CS */
-#define SDRAM_BASE_ADDR 0xA0000000
-#define CSD1_BASE_ADDR 0xB0000000
+#define SDRAM_BASE_ADDR 0xA0000000
+#define CSD1_BASE_ADDR 0xB0000000
#define CS0_BASE_ADDR 0xC0000000
#define CS1_BASE_ADDR 0xC8000000
@@ -122,44 +66,20 @@
#define CS5_BASE_ADDR 0xD6000000
#define PCMCIA_MEM_BASE_ADDR 0xDC000000
-/*
- * This macro defines the physical to virtual address mapping for all the
- * peripheral modules. It is used by passing in the physical address as x
- * and returning the virtual address. If the physical address is not mapped,
- * it returns 0xDEADBEEF
- */
-#define IO_ADDRESS(x) \
- (void __iomem *) \
- (((x >= AIPI_BASE_ADDR) && (x < (AIPI_BASE_ADDR + AIPI_SIZE))) ? \
- AIPI_IO_ADDRESS(x) : \
- ((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? \
- SAHB1_IO_ADDRESS(x) : \
- ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? \
- X_MEMC_IO_ADDRESS(x) : 0xDEADBEEF)
-
-/* define the address mapping macros: in physical address order */
-#define AIPI_IO_ADDRESS(x) \
- (((x) - AIPI_BASE_ADDR) + AIPI_BASE_ADDR_VIRT)
-
-#define AVIC_IO_ADDRESS(x) AIPI_IO_ADDRESS(x)
-
-#define SAHB1_IO_ADDRESS(x) \
- (((x) - SAHB1_BASE_ADDR) + SAHB1_BASE_ADDR_VIRT)
-
-#define CS4_IO_ADDRESS(x) \
- (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT)
-
-#define X_MEMC_IO_ADDRESS(x) \
- (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+/* NAND, SDRAM, WEIM, M3IF, EMI controllers */
+#define X_MEMC_BASE_ADDR 0xD8000000
+#define X_MEMC_BASE_ADDR_VIRT 0xF4200000
+#define X_MEMC_SIZE SZ_1M
-#define PCMCIA_IO_ADDRESS(x) \
- (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+#define NFC_BASE_ADDR (X_MEMC_BASE_ADDR)
+#define SDRAMC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000)
+#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000)
+#define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000)
+#define PCMCIA_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000)
-/* fixed interrput numbers */
+/* fixed interrupt numbers */
#define MXC_INT_CCM 63
#define MXC_INT_IIM 62
-#define MXC_INT_LCDC 61
-#define MXC_INT_SLCDC 60
#define MXC_INT_SAHARA 59
#define MXC_INT_SCC_SCM 58
#define MXC_INT_SCC_SMN 57
@@ -167,54 +87,12 @@
#define MXC_INT_USB2 55
#define MXC_INT_USB1 54
#define MXC_INT_VPU 53
-#define MXC_INT_EMMAPP 52
-#define MXC_INT_EMMAPRP 51
#define MXC_INT_FEC 50
#define MXC_INT_UART5 49
#define MXC_INT_UART6 48
-#define MXC_INT_DMACH15 47
-#define MXC_INT_DMACH14 46
-#define MXC_INT_DMACH13 45
-#define MXC_INT_DMACH12 44
-#define MXC_INT_DMACH11 43
-#define MXC_INT_DMACH10 42
-#define MXC_INT_DMACH9 41
-#define MXC_INT_DMACH8 40
-#define MXC_INT_DMACH7 39
-#define MXC_INT_DMACH6 38
-#define MXC_INT_DMACH5 37
-#define MXC_INT_DMACH4 36
-#define MXC_INT_DMACH3 35
-#define MXC_INT_DMACH2 34
-#define MXC_INT_DMACH1 33
-#define MXC_INT_DMACH0 32
-#define MXC_INT_CSI 31
#define MXC_INT_ATA 30
-#define MXC_INT_NANDFC 29
-#define MXC_INT_PCMCIA 28
-#define MXC_INT_WDOG 27
-#define MXC_INT_GPT1 26
-#define MXC_INT_GPT2 25
-#define MXC_INT_GPT3 24
-#define MXC_INT_GPT INT_GPT1
-#define MXC_INT_PWM 23
-#define MXC_INT_RTC 22
-#define MXC_INT_KPP 21
-#define MXC_INT_UART1 20
-#define MXC_INT_UART2 19
-#define MXC_INT_UART3 18
-#define MXC_INT_UART4 17
-#define MXC_INT_CSPI1 16
-#define MXC_INT_CSPI2 15
-#define MXC_INT_SSI1 14
-#define MXC_INT_SSI2 13
-#define MXC_INT_I2C 12
-#define MXC_INT_SDHC1 11
-#define MXC_INT_SDHC2 10
#define MXC_INT_SDHC3 9
-#define MXC_INT_GPIO 8
#define MXC_INT_SDHC 7
-#define MXC_INT_CSPI3 6
#define MXC_INT_RTIC 5
#define MXC_INT_GPT4 4
#define MXC_INT_GPT5 3
@@ -228,36 +106,9 @@
#define DMA_REQ_UART6_TX 34
#define DMA_REQ_UART5_RX 33
#define DMA_REQ_UART5_TX 32
-#define DMA_REQ_CSI_RX 31
-#define DMA_REQ_CSI_STAT 30
#define DMA_REQ_ATA_RCV 29
#define DMA_REQ_ATA_TX 28
-#define DMA_REQ_UART1_TX 27
-#define DMA_REQ_UART1_RX 26
-#define DMA_REQ_UART2_TX 25
-#define DMA_REQ_UART2_RX 24
-#define DMA_REQ_UART3_TX 23
-#define DMA_REQ_UART3_RX 22
-#define DMA_REQ_UART4_TX 21
-#define DMA_REQ_UART4_RX 20
-#define DMA_REQ_CSPI1_TX 19
-#define DMA_REQ_CSPI1_RX 18
-#define DMA_REQ_CSPI2_TX 17
-#define DMA_REQ_CSPI2_RX 16
-#define DMA_REQ_SSI1_TX1 15
-#define DMA_REQ_SSI1_RX1 14
-#define DMA_REQ_SSI1_TX0 13
-#define DMA_REQ_SSI1_RX0 12
-#define DMA_REQ_SSI2_TX1 11
-#define DMA_REQ_SSI2_RX1 10
-#define DMA_REQ_SSI2_TX0 9
-#define DMA_REQ_SSI2_RX0 8
-#define DMA_REQ_SDHC1 7
-#define DMA_REQ_SDHC2 6
#define DMA_REQ_MSHC 4
-#define DMA_REQ_EXT 3
-#define DMA_REQ_CSPI3_TX 2
-#define DMA_REQ_CSPI3_RX 1
/* silicon revisions specific to i.MX27 */
#define CHIP_REV_1_0 0x00
@@ -267,25 +118,8 @@
extern int mx27_revision(void);
#endif
-/* gpio and gpio based interrupt handling */
-#define GPIO_DR 0x1C
-#define GPIO_GDIR 0x00
-#define GPIO_PSR 0x24
-#define GPIO_ICR1 0x28
-#define GPIO_ICR2 0x2C
-#define GPIO_IMR 0x30
-#define GPIO_ISR 0x34
-#define GPIO_INT_LOW_LEV 0x3
-#define GPIO_INT_HIGH_LEV 0x2
-#define GPIO_INT_RISE_EDGE 0x0
-#define GPIO_INT_FALL_EDGE 0x1
-#define GPIO_INT_NONE 0x4
-
/* Mandatory defines used globally */
-/* this is an i.MX27 CPU */
-#define cpu_is_mx27() (1)
-
/* this CPU supports up to 192 GPIOs (don't forget the baseboard!) */
#define ARCH_NR_GPIOS (192 + 16)
diff --git a/arch/arm/plat-mxc/include/mach/mx2x.h b/arch/arm/plat-mxc/include/mach/mx2x.h
new file mode 100644
index 000000000000..fc40d3ab8c5b
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx2x.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This contains hardware definitions that are common between i.MX21 and
+ * i.MX27.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_MX2x_H__
+#define __ASM_ARCH_MXC_MX2x_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+/* The following addresses are common between i.MX21 and i.MX27 */
+
+/* Register offests */
+#define AIPI_BASE_ADDR 0x10000000
+#define AIPI_BASE_ADDR_VIRT 0xF4000000
+#define AIPI_SIZE SZ_1M
+
+#define DMA_BASE_ADDR (AIPI_BASE_ADDR + 0x01000)
+#define WDOG_BASE_ADDR (AIPI_BASE_ADDR + 0x02000)
+#define GPT1_BASE_ADDR (AIPI_BASE_ADDR + 0x03000)
+#define GPT2_BASE_ADDR (AIPI_BASE_ADDR + 0x04000)
+#define GPT3_BASE_ADDR (AIPI_BASE_ADDR + 0x05000)
+#define PWM_BASE_ADDR (AIPI_BASE_ADDR + 0x06000)
+#define RTC_BASE_ADDR (AIPI_BASE_ADDR + 0x07000)
+#define KPP_BASE_ADDR (AIPI_BASE_ADDR + 0x08000)
+#define OWIRE_BASE_ADDR (AIPI_BASE_ADDR + 0x09000)
+#define UART1_BASE_ADDR (AIPI_BASE_ADDR + 0x0A000)
+#define UART2_BASE_ADDR (AIPI_BASE_ADDR + 0x0B000)
+#define UART3_BASE_ADDR (AIPI_BASE_ADDR + 0x0C000)
+#define UART4_BASE_ADDR (AIPI_BASE_ADDR + 0x0D000)
+#define CSPI1_BASE_ADDR (AIPI_BASE_ADDR + 0x0E000)
+#define CSPI2_BASE_ADDR (AIPI_BASE_ADDR + 0x0F000)
+#define SSI1_BASE_ADDR (AIPI_BASE_ADDR + 0x10000)
+#define SSI2_BASE_ADDR (AIPI_BASE_ADDR + 0x11000)
+#define I2C_BASE_ADDR (AIPI_BASE_ADDR + 0x12000)
+#define SDHC1_BASE_ADDR (AIPI_BASE_ADDR + 0x13000)
+#define SDHC2_BASE_ADDR (AIPI_BASE_ADDR + 0x14000)
+#define GPIO_BASE_ADDR (AIPI_BASE_ADDR + 0x15000)
+#define AUDMUX_BASE_ADDR (AIPI_BASE_ADDR + 0x16000)
+#define CSPI3_BASE_ADDR (AIPI_BASE_ADDR + 0x17000)
+#define LCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x21000)
+#define SLCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x22000)
+#define USBOTG_BASE_ADDR (AIPI_BASE_ADDR + 0x24000)
+#define EMMA_PP_BASE_ADDR (AIPI_BASE_ADDR + 0x26000)
+#define EMMA_PRP_BASE_ADDR (AIPI_BASE_ADDR + 0x26400)
+#define CCM_BASE_ADDR (AIPI_BASE_ADDR + 0x27000)
+#define SYSCTRL_BASE_ADDR (AIPI_BASE_ADDR + 0x27800)
+#define JAM_BASE_ADDR (AIPI_BASE_ADDR + 0x3E000)
+#define MAX_BASE_ADDR (AIPI_BASE_ADDR + 0x3F000)
+
+#define AVIC_BASE_ADDR 0x10040000
+
+#define SAHB1_BASE_ADDR 0x80000000
+#define SAHB1_BASE_ADDR_VIRT 0xF4100000
+#define SAHB1_SIZE SZ_1M
+
+#define CSI_BASE_ADDR (SAHB1_BASE_ADDR + 0x0000)
+
+/*
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+#define IO_ADDRESS(x) \
+ (void __force __iomem *) \
+ (((x >= AIPI_BASE_ADDR) && (x < (AIPI_BASE_ADDR + AIPI_SIZE))) ? \
+ AIPI_IO_ADDRESS(x) : \
+ ((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? \
+ SAHB1_IO_ADDRESS(x) : \
+ ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? \
+ X_MEMC_IO_ADDRESS(x) : 0xDEADBEEF)
+
+/* define the address mapping macros: in physical address order */
+#define AIPI_IO_ADDRESS(x) \
+ (((x) - AIPI_BASE_ADDR) + AIPI_BASE_ADDR_VIRT)
+
+#define AVIC_IO_ADDRESS(x) AIPI_IO_ADDRESS(x)
+
+#define SAHB1_IO_ADDRESS(x) \
+ (((x) - SAHB1_BASE_ADDR) + SAHB1_BASE_ADDR_VIRT)
+
+#define CS4_IO_ADDRESS(x) \
+ (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT)
+
+#define X_MEMC_IO_ADDRESS(x) \
+ (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+#define PCMCIA_IO_ADDRESS(x) \
+ (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+/* fixed interrupt numbers */
+#define MXC_INT_LCDC 61
+#define MXC_INT_SLCDC 60
+#define MXC_INT_EMMAPP 52
+#define MXC_INT_EMMAPRP 51
+#define MXC_INT_DMACH15 47
+#define MXC_INT_DMACH14 46
+#define MXC_INT_DMACH13 45
+#define MXC_INT_DMACH12 44
+#define MXC_INT_DMACH11 43
+#define MXC_INT_DMACH10 42
+#define MXC_INT_DMACH9 41
+#define MXC_INT_DMACH8 40
+#define MXC_INT_DMACH7 39
+#define MXC_INT_DMACH6 38
+#define MXC_INT_DMACH5 37
+#define MXC_INT_DMACH4 36
+#define MXC_INT_DMACH3 35
+#define MXC_INT_DMACH2 34
+#define MXC_INT_DMACH1 33
+#define MXC_INT_DMACH0 32
+#define MXC_INT_CSI 31
+#define MXC_INT_NANDFC 29
+#define MXC_INT_PCMCIA 28
+#define MXC_INT_WDOG 27
+#define MXC_INT_GPT1 26
+#define MXC_INT_GPT2 25
+#define MXC_INT_GPT3 24
+#define MXC_INT_GPT INT_GPT1
+#define MXC_INT_PWM 23
+#define MXC_INT_RTC 22
+#define MXC_INT_KPP 21
+#define MXC_INT_UART1 20
+#define MXC_INT_UART2 19
+#define MXC_INT_UART3 18
+#define MXC_INT_UART4 17
+#define MXC_INT_CSPI1 16
+#define MXC_INT_CSPI2 15
+#define MXC_INT_SSI1 14
+#define MXC_INT_SSI2 13
+#define MXC_INT_I2C 12
+#define MXC_INT_SDHC1 11
+#define MXC_INT_SDHC2 10
+#define MXC_INT_GPIO 8
+#define MXC_INT_CSPI3 6
+
+/* gpio and gpio based interrupt handling */
+#define GPIO_DR 0x1C
+#define GPIO_GDIR 0x00
+#define GPIO_PSR 0x24
+#define GPIO_ICR1 0x28
+#define GPIO_ICR2 0x2C
+#define GPIO_IMR 0x30
+#define GPIO_ISR 0x34
+#define GPIO_INT_LOW_LEV 0x3
+#define GPIO_INT_HIGH_LEV 0x2
+#define GPIO_INT_RISE_EDGE 0x0
+#define GPIO_INT_FALL_EDGE 0x1
+#define GPIO_INT_NONE 0x4
+
+/* fixed DMA request numbers */
+#define DMA_REQ_CSI_RX 31
+#define DMA_REQ_CSI_STAT 30
+#define DMA_REQ_UART1_TX 27
+#define DMA_REQ_UART1_RX 26
+#define DMA_REQ_UART2_TX 25
+#define DMA_REQ_UART2_RX 24
+#define DMA_REQ_UART3_TX 23
+#define DMA_REQ_UART3_RX 22
+#define DMA_REQ_UART4_TX 21
+#define DMA_REQ_UART4_RX 20
+#define DMA_REQ_CSPI1_TX 19
+#define DMA_REQ_CSPI1_RX 18
+#define DMA_REQ_CSPI2_TX 17
+#define DMA_REQ_CSPI2_RX 16
+#define DMA_REQ_SSI1_TX1 15
+#define DMA_REQ_SSI1_RX1 14
+#define DMA_REQ_SSI1_TX0 13
+#define DMA_REQ_SSI1_RX0 12
+#define DMA_REQ_SSI2_TX1 11
+#define DMA_REQ_SSI2_RX1 10
+#define DMA_REQ_SSI2_TX0 9
+#define DMA_REQ_SSI2_RX0 8
+#define DMA_REQ_SDHC1 7
+#define DMA_REQ_SDHC2 6
+#define DMA_REQ_EXT 3
+#define DMA_REQ_CSPI3_TX 2
+#define DMA_REQ_CSPI3_RX 1
+
+#endif /* __ASM_ARCH_MXC_MX2x_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/plat-mxc/include/mach/mx31.h
index de026654b00e..0b06941b6139 100644
--- a/arch/arm/plat-mxc/include/mach/mx31.h
+++ b/arch/arm/plat-mxc/include/mach/mx31.h
@@ -1,360 +1,45 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_MXC_MX31_H__
-#define __ASM_ARCH_MXC_MX31_H__
-
-#ifndef __ASM_ARCH_MXC_HARDWARE_H__
-#error "Do not include directly."
-#endif
-
-/*
- * MX31 memory map:
- *
- * Virt Phys Size What
- * ---------------------------------------------------------------------------
- * F8000000 1FFC0000 16K IRAM
- * F9000000 30000000 256M L2CC
- * FC000000 43F00000 1M AIPS 1
- * FC100000 50000000 1M SPBA
- * FC200000 53F00000 1M AIPS 2
- * FC500000 60000000 128M ROMPATCH
- * FC400000 68000000 128M AVIC
- * 70000000 256M IPU (MAX M2)
- * 80000000 256M CSD0 SDRAM/DDR
- * 90000000 256M CSD1 SDRAM/DDR
- * A0000000 128M CS0 Flash
- * A8000000 128M CS1 Flash
- * B0000000 32M CS2
- * B2000000 32M CS3
- * F4000000 B4000000 32M CS4
- * B6000000 32M CS5
- * FC320000 B8000000 64K NAND, SDRAM, WEIM, M3IF, EMI controllers
- * C0000000 64M PCMCIA/CF
- */
-
-#define CS0_BASE_ADDR 0xA0000000
-#define CS1_BASE_ADDR 0xA8000000
-#define CS2_BASE_ADDR 0xB0000000
-#define CS3_BASE_ADDR 0xB2000000
-
-#define CS4_BASE_ADDR 0xB4000000
-#define CS4_BASE_ADDR_VIRT 0xF4000000
-#define CS4_SIZE SZ_32M
-
-#define CS5_BASE_ADDR 0xB6000000
-#define PCMCIA_MEM_BASE_ADDR 0xBC000000
-
-/*
* IRAM
*/
-#define IRAM_BASE_ADDR 0x1FFC0000 /* internal ram */
-#define IRAM_BASE_ADDR_VIRT 0xF8000000
-#define IRAM_SIZE SZ_16K
-
-/*
- * L2CC
- */
-#define L2CC_BASE_ADDR 0x30000000
-#define L2CC_BASE_ADDR_VIRT 0xF9000000
-#define L2CC_SIZE SZ_1M
-
-/*
- * AIPS 1
- */
-#define AIPS1_BASE_ADDR 0x43F00000
-#define AIPS1_BASE_ADDR_VIRT 0xFC000000
-#define AIPS1_SIZE SZ_1M
+#define MX31_IRAM_BASE_ADDR 0x1FFC0000 /* internal ram */
+#define MX31_IRAM_SIZE SZ_16K
-#define MAX_BASE_ADDR (AIPS1_BASE_ADDR + 0x00004000)
-#define EVTMON_BASE_ADDR (AIPS1_BASE_ADDR + 0x00008000)
-#define CLKCTL_BASE_ADDR (AIPS1_BASE_ADDR + 0x0000C000)
-#define ETB_SLOT4_BASE_ADDR (AIPS1_BASE_ADDR + 0x00010000)
-#define ETB_SLOT5_BASE_ADDR (AIPS1_BASE_ADDR + 0x00014000)
-#define ECT_CTIO_BASE_ADDR (AIPS1_BASE_ADDR + 0x00018000)
-#define I2C_BASE_ADDR (AIPS1_BASE_ADDR + 0x00080000)
-#define I2C3_BASE_ADDR (AIPS1_BASE_ADDR + 0x00084000)
#define OTG_BASE_ADDR (AIPS1_BASE_ADDR + 0x00088000)
#define ATA_BASE_ADDR (AIPS1_BASE_ADDR + 0x0008C000)
-#define UART1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00090000)
-#define UART2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00094000)
-#define I2C2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00098000)
-#define OWIRE_BASE_ADDR (AIPS1_BASE_ADDR + 0x0009C000)
-#define SSI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A0000)
-#define CSPI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A4000)
-#define KPP_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A8000)
-#define IOMUXC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000AC000)
#define UART4_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B0000)
#define UART5_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B4000)
-#define ECT_IP1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B8000)
-#define ECT_IP2_BASE_ADDR (AIPS1_BASE_ADDR + 0x000BC000)
-
-/*
- * SPBA global module enabled #0
- */
-#define SPBA0_BASE_ADDR 0x50000000
-#define SPBA0_BASE_ADDR_VIRT 0xFC100000
-#define SPBA0_SIZE SZ_1M
#define MMC_SDHC1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00004000)
#define MMC_SDHC2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00008000)
-#define UART3_BASE_ADDR (SPBA0_BASE_ADDR + 0x0000C000)
-#define CSPI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00010000)
-#define SSI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00014000)
#define SIM1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00018000)
#define IIM_BASE_ADDR (SPBA0_BASE_ADDR + 0x0001C000)
-#define ATA_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00020000)
-#define MSHC1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000)
-#define MSHC2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000)
-#define SPBA_CTRL_BASE_ADDR (SPBA0_BASE_ADDR + 0x0003C000)
-/*
- * AIPS 2
- */
-#define AIPS2_BASE_ADDR 0x53F00000
-#define AIPS2_BASE_ADDR_VIRT 0xFC200000
-#define AIPS2_SIZE SZ_1M
-#define CCM_BASE_ADDR (AIPS2_BASE_ADDR + 0x00080000)
#define CSPI3_BASE_ADDR (AIPS2_BASE_ADDR + 0x00084000)
#define FIRI_BASE_ADDR (AIPS2_BASE_ADDR + 0x0008C000)
-#define GPT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00090000)
-#define EPIT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00094000)
-#define EPIT2_BASE_ADDR (AIPS2_BASE_ADDR + 0x00098000)
-#define GPIO3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A4000)
-#define SCC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AC000)
#define SCM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AE000)
#define SMN_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AF000)
-#define RNGA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B0000)
-#define IPU_CTRL_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C0000)
-#define AUDMUX_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C4000)
#define MPEG4_ENC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C8000)
-#define GPIO1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000CC000)
-#define GPIO2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D0000)
-#define SDMA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D4000)
-#define RTC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D8000)
-#define WDOG_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DC000)
-#define PWM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E0000)
-#define RTIC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000EC000)
-
-/*
- * ROMP and AVIC
- */
-#define ROMP_BASE_ADDR 0x60000000
-#define ROMP_BASE_ADDR_VIRT 0xFC500000
-#define ROMP_SIZE SZ_1M
-
-#define AVIC_BASE_ADDR 0x68000000
-#define AVIC_BASE_ADDR_VIRT 0xFC400000
-#define AVIC_SIZE SZ_1M
-
-/*
- * NAND, SDRAM, WEIM, M3IF, EMI controllers
- */
-#define X_MEMC_BASE_ADDR 0xB8000000
-#define X_MEMC_BASE_ADDR_VIRT 0xFC320000
-#define X_MEMC_SIZE SZ_64K
-#define NFC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x0000)
-#define ESDCTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000)
-#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000)
-#define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000)
-#define EMI_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000)
-#define PCMCIA_CTL_BASE_ADDR EMI_CTL_BASE_ADDR
+#define MX31_NFC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x0000)
-/*
- * Memory regions and CS
- */
-#define IPU_MEM_BASE_ADDR 0x70000000
-#define CSD0_BASE_ADDR 0x80000000
-#define CSD1_BASE_ADDR 0x90000000
-#define CS0_BASE_ADDR 0xA0000000
-#define CS1_BASE_ADDR 0xA8000000
-#define CS2_BASE_ADDR 0xB0000000
-#define CS3_BASE_ADDR 0xB2000000
-
-#define CS4_BASE_ADDR 0xB4000000
-#define CS4_BASE_ADDR_VIRT 0xF4000000
-#define CS4_SIZE SZ_32M
-
-#define CS5_BASE_ADDR 0xB6000000
-#define PCMCIA_MEM_BASE_ADDR 0xBC000000
-
-/*!
- * This macro defines the physical to virtual address mapping for all the
- * peripheral modules. It is used by passing in the physical address as x
- * and returning the virtual address. If the physical address is not mapped,
- * it returns 0xDEADBEEF
- */
-#define IO_ADDRESS(x) \
- (void __iomem *) \
- (((x >= IRAM_BASE_ADDR) && (x < (IRAM_BASE_ADDR + IRAM_SIZE))) ? IRAM_IO_ADDRESS(x):\
- ((x >= L2CC_BASE_ADDR) && (x < (L2CC_BASE_ADDR + L2CC_SIZE))) ? L2CC_IO_ADDRESS(x):\
- ((x >= AIPS1_BASE_ADDR) && (x < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x):\
- ((x >= SPBA0_BASE_ADDR) && (x < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x):\
- ((x >= AIPS2_BASE_ADDR) && (x < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x):\
- ((x >= ROMP_BASE_ADDR) && (x < (ROMP_BASE_ADDR + ROMP_SIZE))) ? ROMP_IO_ADDRESS(x):\
- ((x >= AVIC_BASE_ADDR) && (x < (AVIC_BASE_ADDR + AVIC_SIZE))) ? AVIC_IO_ADDRESS(x):\
- ((x >= CS4_BASE_ADDR) && (x < (CS4_BASE_ADDR + CS4_SIZE))) ? CS4_IO_ADDRESS(x):\
- ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x):\
- 0xDEADBEEF)
-
-/*
- * define the address mapping macros: in physical address order
- */
-
-#define IRAM_IO_ADDRESS(x) \
- (((x) - IRAM_BASE_ADDR) + IRAM_BASE_ADDR_VIRT)
-
-#define L2CC_IO_ADDRESS(x) \
- (((x) - L2CC_BASE_ADDR) + L2CC_BASE_ADDR_VIRT)
-
-#define AIPS1_IO_ADDRESS(x) \
- (((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT)
-
-#define SPBA0_IO_ADDRESS(x) \
- (((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT)
-
-#define AIPS2_IO_ADDRESS(x) \
- (((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT)
-
-#define ROMP_IO_ADDRESS(x) \
- (((x) - ROMP_BASE_ADDR) + ROMP_BASE_ADDR_VIRT)
-
-#define AVIC_IO_ADDRESS(x) \
- (((x) - AVIC_BASE_ADDR) + AVIC_BASE_ADDR_VIRT)
-
-#define CS4_IO_ADDRESS(x) \
- (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT)
-
-#define X_MEMC_IO_ADDRESS(x) \
- (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
-
-#define PCMCIA_IO_ADDRESS(x) \
- (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
-
-/*
- * Interrupt numbers
- */
-#define MXC_INT_PEN_ADS7843 0
-#define MXC_INT_RESV1 1
-#define MXC_INT_CS8900A 2
-#define MXC_INT_I2C3 3
-#define MXC_INT_I2C2 4
#define MXC_INT_MPEG4_ENCODER 5
-#define MXC_INT_RTIC 6
#define MXC_INT_FIRI 7
-#define MXC_INT_MMC_SDHC2 8
+#define MX31_INT_MMC_SDHC2 8
#define MXC_INT_MMC_SDHC1 9
-#define MXC_INT_I2C 10
-#define MXC_INT_SSI2 11
-#define MXC_INT_SSI1 12
-#define MXC_INT_CSPI2 13
-#define MXC_INT_CSPI1 14
-#define MXC_INT_ATA 15
+#define MX31_INT_SSI2 11
+#define MX31_INT_SSI1 12
#define MXC_INT_MBX 16
#define MXC_INT_CSPI3 17
-#define MXC_INT_UART3 18
-#define MXC_INT_IIM 19
#define MXC_INT_SIM2 20
#define MXC_INT_SIM1 21
-#define MXC_INT_RNGA 22
-#define MXC_INT_EVTMON 23
-#define MXC_INT_KPP 24
-#define MXC_INT_RTC 25
-#define MXC_INT_PWM 26
-#define MXC_INT_EPIT2 27
-#define MXC_INT_EPIT1 28
-#define MXC_INT_GPT 29
-#define MXC_INT_RESV30 30
-#define MXC_INT_RESV31 31
-#define MXC_INT_UART2 32
-#define MXC_INT_NANDFC 33
-#define MXC_INT_SDMA 34
+#define MXC_INT_CCM_DVFS 31
#define MXC_INT_USB1 35
#define MXC_INT_USB2 36
#define MXC_INT_USB3 37
#define MXC_INT_USB4 38
-#define MXC_INT_MSHC1 39
#define MXC_INT_MSHC2 40
-#define MXC_INT_IPU_ERR 41
-#define MXC_INT_IPU_SYN 42
-#define MXC_INT_RESV43 43
-#define MXC_INT_RESV44 44
-#define MXC_INT_UART1 45
#define MXC_INT_UART4 46
#define MXC_INT_UART5 47
-#define MXC_INT_ECT 48
-#define MXC_INT_SCC_SCM 49
-#define MXC_INT_SCC_SMN 50
-#define MXC_INT_GPIO2 51
-#define MXC_INT_GPIO1 52
#define MXC_INT_CCM 53
#define MXC_INT_PCMCIA 54
-#define MXC_INT_WDOG 55
-#define MXC_INT_GPIO3 56
-#define MXC_INT_RESV57 57
-#define MXC_INT_EXT_POWER 58
-#define MXC_INT_EXT_TEMPER 59
-#define MXC_INT_EXT_SENSOR60 60
-#define MXC_INT_EXT_SENSOR61 61
-#define MXC_INT_EXT_WDOG 62
-#define MXC_INT_EXT_TV 63
-
-#define PROD_SIGNATURE 0x1 /* For MX31 */
-
-/* silicon revisions specific to i.MX31 */
-#define CHIP_REV_1_0 0x10
-#define CHIP_REV_1_1 0x11
-#define CHIP_REV_1_2 0x12
-#define CHIP_REV_1_3 0x13
-#define CHIP_REV_2_0 0x20
-#define CHIP_REV_2_1 0x21
-#define CHIP_REV_2_2 0x22
-#define CHIP_REV_2_3 0x23
-#define CHIP_REV_3_0 0x30
-#define CHIP_REV_3_1 0x31
-#define CHIP_REV_3_2 0x32
-
-#define SYSTEM_REV_MIN CHIP_REV_1_0
-#define SYSTEM_REV_NUM 3
-
-/* gpio and gpio based interrupt handling */
-#define GPIO_DR 0x00
-#define GPIO_GDIR 0x04
-#define GPIO_PSR 0x08
-#define GPIO_ICR1 0x0C
-#define GPIO_ICR2 0x10
-#define GPIO_IMR 0x14
-#define GPIO_ISR 0x18
-#define GPIO_INT_LOW_LEV 0x0
-#define GPIO_INT_HIGH_LEV 0x1
-#define GPIO_INT_RISE_EDGE 0x2
-#define GPIO_INT_FALL_EDGE 0x3
-#define GPIO_INT_NONE 0x4
-
-/* Mandatory defines used globally */
-
-/* this CPU supports up to 96 GPIOs */
-#define ARCH_NR_GPIOS 96
-
-#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
-
-/* this is a i.MX31 CPU */
-#define cpu_is_mx31() (1)
-
-extern unsigned int system_rev;
-
-static inline int mx31_revision(void)
-{
- return system_rev;
-}
-#endif
-#endif /* __ASM_ARCH_MXC_MX31_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/plat-mxc/include/mach/mx35.h
new file mode 100644
index 000000000000..6465fefb42e3
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx35.h
@@ -0,0 +1,29 @@
+/*
+ * IRAM
+ */
+#define MX35_IRAM_BASE_ADDR 0x10000000 /* internal ram */
+#define MX35_IRAM_SIZE SZ_128K
+
+#define MXC_FEC_BASE_ADDR 0x50038000
+#define MX35_NFC_BASE_ADDR 0xBB000000
+
+/*
+ * Interrupt numbers
+ */
+#define MXC_INT_OWIRE 2
+#define MX35_INT_MMC_SDHC1 7
+#define MXC_INT_MMC_SDHC2 8
+#define MXC_INT_MMC_SDHC3 9
+#define MX35_INT_SSI1 11
+#define MX35_INT_SSI2 12
+#define MXC_INT_GPU2D 16
+#define MXC_INT_ASRC 17
+#define MXC_INT_USBHS 35
+#define MXC_INT_USBOTG 37
+#define MXC_INT_ESAI 40
+#define MXC_INT_CAN1 43
+#define MXC_INT_CAN2 44
+#define MXC_INT_MLB 46
+#define MXC_INT_SPDIF 47
+#define MXC_INT_FEC 57
+
diff --git a/arch/arm/plat-mxc/include/mach/mx3_camera.h b/arch/arm/plat-mxc/include/mach/mx3_camera.h
new file mode 100644
index 000000000000..36d7ff27b5e2
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx3_camera.h
@@ -0,0 +1,52 @@
+/*
+ * mx3_camera.h - i.MX3x camera driver header file
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _MX3_CAMERA_H_
+#define _MX3_CAMERA_H_
+
+#include <linux/device.h>
+
+#define MX3_CAMERA_CLK_SRC 1
+#define MX3_CAMERA_EXT_VSYNC 2
+#define MX3_CAMERA_DP 4
+#define MX3_CAMERA_PCP 8
+#define MX3_CAMERA_HSP 0x10
+#define MX3_CAMERA_VSP 0x20
+#define MX3_CAMERA_DATAWIDTH_4 0x40
+#define MX3_CAMERA_DATAWIDTH_8 0x80
+#define MX3_CAMERA_DATAWIDTH_10 0x100
+#define MX3_CAMERA_DATAWIDTH_15 0x200
+
+#define MX3_CAMERA_DATAWIDTH_MASK (MX3_CAMERA_DATAWIDTH_4 | MX3_CAMERA_DATAWIDTH_8 | \
+ MX3_CAMERA_DATAWIDTH_10 | MX3_CAMERA_DATAWIDTH_15)
+
+/**
+ * struct mx3_camera_pdata - i.MX3x camera platform data
+ * @flags: MX3_CAMERA_* flags
+ * @mclk_10khz: master clock frequency in 10kHz units
+ * @dma_dev: IPU DMA device to match against in channel allocation
+ */
+struct mx3_camera_pdata {
+ unsigned long flags;
+ unsigned long mclk_10khz;
+ struct device *dma_dev;
+};
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mx3fb.h b/arch/arm/plat-mxc/include/mach/mx3fb.h
index e391a76ca87d..ac24c5c4bc83 100644
--- a/arch/arm/plat-mxc/include/mach/mx3fb.h
+++ b/arch/arm/plat-mxc/include/mach/mx3fb.h
@@ -14,25 +14,25 @@
#include <linux/fb.h>
/* Proprietary FB_SYNC_ flags */
-#define FB_SYNC_OE_ACT_HIGH 0x80000000
-#define FB_SYNC_CLK_INVERT 0x40000000
-#define FB_SYNC_DATA_INVERT 0x20000000
-#define FB_SYNC_CLK_IDLE_EN 0x10000000
-#define FB_SYNC_SHARP_MODE 0x08000000
-#define FB_SYNC_SWAP_RGB 0x04000000
-#define FB_SYNC_CLK_SEL_EN 0x02000000
+#define FB_SYNC_OE_ACT_HIGH 0x80000000
+#define FB_SYNC_CLK_INVERT 0x40000000
+#define FB_SYNC_DATA_INVERT 0x20000000
+#define FB_SYNC_CLK_IDLE_EN 0x10000000
+#define FB_SYNC_SHARP_MODE 0x08000000
+#define FB_SYNC_SWAP_RGB 0x04000000
+#define FB_SYNC_CLK_SEL_EN 0x02000000
/**
* struct mx3fb_platform_data - mx3fb platform data
*
- * @dma_dev: pointer to the dma-device, used for dma-slave connection
- * @mode: pointer to a platform-provided per mxc_register_fb() videomode
+ * @dma_dev: pointer to the dma-device, used for dma-slave connection
+ * @mode: pointer to a platform-provided per mxc_register_fb() videomode
*/
struct mx3fb_platform_data {
- struct device *dma_dev;
- const char *name;
- const struct fb_videomode *mode;
- int num_modes;
+ struct device *dma_dev;
+ const char *name;
+ const struct fb_videomode *mode;
+ int num_modes;
};
#endif
diff --git a/arch/arm/plat-mxc/include/mach/mx3x.h b/arch/arm/plat-mxc/include/mach/mx3x.h
new file mode 100644
index 000000000000..3878c6085d5c
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx3x.h
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_MX31_H__
+#define __ASM_ARCH_MXC_MX31_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+/*
+ * MX31 memory map:
+ *
+ * Virt Phys Size What
+ * ---------------------------------------------------------------------------
+ * FC000000 43F00000 1M AIPS 1
+ * FC100000 50000000 1M SPBA
+ * FC200000 53F00000 1M AIPS 2
+ * FC500000 60000000 128M ROMPATCH
+ * FC400000 68000000 128M AVIC
+ * 70000000 256M IPU (MAX M2)
+ * 80000000 256M CSD0 SDRAM/DDR
+ * 90000000 256M CSD1 SDRAM/DDR
+ * A0000000 128M CS0 Flash
+ * A8000000 128M CS1 Flash
+ * B0000000 32M CS2
+ * B2000000 32M CS3
+ * F4000000 B4000000 32M CS4
+ * B6000000 32M CS5
+ * FC320000 B8000000 64K NAND, SDRAM, WEIM, M3IF, EMI controllers
+ * C0000000 64M PCMCIA/CF
+ */
+
+#define CS0_BASE_ADDR 0xA0000000
+#define CS1_BASE_ADDR 0xA8000000
+#define CS2_BASE_ADDR 0xB0000000
+#define CS3_BASE_ADDR 0xB2000000
+
+#define CS4_BASE_ADDR 0xB4000000
+#define CS4_BASE_ADDR_VIRT 0xF4000000
+#define CS4_SIZE SZ_32M
+
+#define CS5_BASE_ADDR 0xB6000000
+#define PCMCIA_MEM_BASE_ADDR 0xBC000000
+
+/*
+ * L2CC
+ */
+#define L2CC_BASE_ADDR 0x30000000
+#define L2CC_SIZE SZ_1M
+
+/*
+ * AIPS 1
+ */
+#define AIPS1_BASE_ADDR 0x43F00000
+#define AIPS1_BASE_ADDR_VIRT 0xFC000000
+#define AIPS1_SIZE SZ_1M
+
+#define MAX_BASE_ADDR (AIPS1_BASE_ADDR + 0x00004000)
+#define EVTMON_BASE_ADDR (AIPS1_BASE_ADDR + 0x00008000)
+#define CLKCTL_BASE_ADDR (AIPS1_BASE_ADDR + 0x0000C000)
+#define ETB_SLOT4_BASE_ADDR (AIPS1_BASE_ADDR + 0x00010000)
+#define ETB_SLOT5_BASE_ADDR (AIPS1_BASE_ADDR + 0x00014000)
+#define ECT_CTIO_BASE_ADDR (AIPS1_BASE_ADDR + 0x00018000)
+#define I2C_BASE_ADDR (AIPS1_BASE_ADDR + 0x00080000)
+#define I2C3_BASE_ADDR (AIPS1_BASE_ADDR + 0x00084000)
+#define UART1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00090000)
+#define UART2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00094000)
+#define I2C2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00098000)
+#define OWIRE_BASE_ADDR (AIPS1_BASE_ADDR + 0x0009C000)
+#define SSI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A0000)
+#define CSPI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A4000)
+#define KPP_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A8000)
+#define IOMUXC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000AC000)
+#define ECT_IP1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B8000)
+#define ECT_IP2_BASE_ADDR (AIPS1_BASE_ADDR + 0x000BC000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define SPBA0_BASE_ADDR 0x50000000
+#define SPBA0_BASE_ADDR_VIRT 0xFC100000
+#define SPBA0_SIZE SZ_1M
+
+#define UART3_BASE_ADDR (SPBA0_BASE_ADDR + 0x0000C000)
+#define CSPI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00010000)
+#define SSI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00014000)
+#define ATA_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00020000)
+#define MSHC1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000)
+#define SPBA_CTRL_BASE_ADDR (SPBA0_BASE_ADDR + 0x0003C000)
+
+/*
+ * AIPS 2
+ */
+#define AIPS2_BASE_ADDR 0x53F00000
+#define AIPS2_BASE_ADDR_VIRT 0xFC200000
+#define AIPS2_SIZE SZ_1M
+#define CCM_BASE_ADDR (AIPS2_BASE_ADDR + 0x00080000)
+#define GPT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00090000)
+#define EPIT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00094000)
+#define EPIT2_BASE_ADDR (AIPS2_BASE_ADDR + 0x00098000)
+#define GPIO3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A4000)
+#define SCC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AC000)
+#define RNGA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B0000)
+#define IPU_CTRL_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C0000)
+#define AUDMUX_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C4000)
+#define GPIO1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000CC000)
+#define GPIO2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D0000)
+#define SDMA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D4000)
+#define RTC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D8000)
+#define WDOG_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DC000)
+#define PWM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E0000)
+#define RTIC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000EC000)
+
+/*
+ * ROMP and AVIC
+ */
+#define ROMP_BASE_ADDR 0x60000000
+#define ROMP_BASE_ADDR_VIRT 0xFC500000
+#define ROMP_SIZE SZ_1M
+
+#define AVIC_BASE_ADDR 0x68000000
+#define AVIC_BASE_ADDR_VIRT 0xFC400000
+#define AVIC_SIZE SZ_1M
+
+/*
+ * NAND, SDRAM, WEIM, M3IF, EMI controllers
+ */
+#define X_MEMC_BASE_ADDR 0xB8000000
+#define X_MEMC_BASE_ADDR_VIRT 0xFC320000
+#define X_MEMC_SIZE SZ_64K
+
+#define ESDCTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000)
+#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000)
+#define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000)
+#define EMI_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000)
+#define PCMCIA_CTL_BASE_ADDR EMI_CTL_BASE_ADDR
+
+/*
+ * Memory regions and CS
+ */
+#define IPU_MEM_BASE_ADDR 0x70000000
+#define CSD0_BASE_ADDR 0x80000000
+#define CSD1_BASE_ADDR 0x90000000
+
+/*!
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+#define IO_ADDRESS(x) \
+ (void __force __iomem *) \
+ (((x >= AIPS1_BASE_ADDR) && (x < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x):\
+ ((x >= SPBA0_BASE_ADDR) && (x < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x):\
+ ((x >= AIPS2_BASE_ADDR) && (x < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x):\
+ ((x >= ROMP_BASE_ADDR) && (x < (ROMP_BASE_ADDR + ROMP_SIZE))) ? ROMP_IO_ADDRESS(x):\
+ ((x >= AVIC_BASE_ADDR) && (x < (AVIC_BASE_ADDR + AVIC_SIZE))) ? AVIC_IO_ADDRESS(x):\
+ ((x >= CS4_BASE_ADDR) && (x < (CS4_BASE_ADDR + CS4_SIZE))) ? CS4_IO_ADDRESS(x):\
+ ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x):\
+ 0xDEADBEEF)
+
+/*
+ * define the address mapping macros: in physical address order
+ */
+#define L2CC_IO_ADDRESS(x) \
+ (((x) - L2CC_BASE_ADDR) + L2CC_BASE_ADDR_VIRT)
+
+#define AIPS1_IO_ADDRESS(x) \
+ (((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT)
+
+#define SPBA0_IO_ADDRESS(x) \
+ (((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT)
+
+#define AIPS2_IO_ADDRESS(x) \
+ (((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT)
+
+#define ROMP_IO_ADDRESS(x) \
+ (((x) - ROMP_BASE_ADDR) + ROMP_BASE_ADDR_VIRT)
+
+#define AVIC_IO_ADDRESS(x) \
+ (((x) - AVIC_BASE_ADDR) + AVIC_BASE_ADDR_VIRT)
+
+#define CS4_IO_ADDRESS(x) \
+ (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT)
+
+#define X_MEMC_IO_ADDRESS(x) \
+ (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+#define PCMCIA_IO_ADDRESS(x) \
+ (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+/*
+ * Interrupt numbers
+ */
+#define MXC_INT_I2C3 3
+#define MXC_INT_I2C2 4
+#define MXC_INT_RTIC 6
+#define MXC_INT_I2C 10
+#define MXC_INT_CSPI2 13
+#define MXC_INT_CSPI1 14
+#define MXC_INT_ATA 15
+#define MXC_INT_UART3 18
+#define MXC_INT_IIM 19
+#define MXC_INT_RNGA 22
+#define MXC_INT_EVTMON 23
+#define MXC_INT_KPP 24
+#define MXC_INT_RTC 25
+#define MXC_INT_PWM 26
+#define MXC_INT_EPIT2 27
+#define MXC_INT_EPIT1 28
+#define MXC_INT_GPT 29
+#define MXC_INT_POWER_FAIL 30
+#define MXC_INT_UART2 32
+#define MXC_INT_NANDFC 33
+#define MXC_INT_SDMA 34
+#define MXC_INT_MSHC1 39
+#define MXC_INT_IPU_ERR 41
+#define MXC_INT_IPU_SYN 42
+#define MXC_INT_UART1 45
+#define MXC_INT_ECT 48
+#define MXC_INT_SCC_SCM 49
+#define MXC_INT_SCC_SMN 50
+#define MXC_INT_GPIO2 51
+#define MXC_INT_GPIO1 52
+#define MXC_INT_WDOG 55
+#define MXC_INT_GPIO3 56
+#define MXC_INT_EXT_POWER 58
+#define MXC_INT_EXT_TEMPER 59
+#define MXC_INT_EXT_SENSOR60 60
+#define MXC_INT_EXT_SENSOR61 61
+#define MXC_INT_EXT_WDOG 62
+#define MXC_INT_EXT_TV 63
+
+#define PROD_SIGNATURE 0x1 /* For MX31 */
+
+/* silicon revisions specific to i.MX31 */
+#define CHIP_REV_1_0 0x10
+#define CHIP_REV_1_1 0x11
+#define CHIP_REV_1_2 0x12
+#define CHIP_REV_1_3 0x13
+#define CHIP_REV_2_0 0x20
+#define CHIP_REV_2_1 0x21
+#define CHIP_REV_2_2 0x22
+#define CHIP_REV_2_3 0x23
+#define CHIP_REV_3_0 0x30
+#define CHIP_REV_3_1 0x31
+#define CHIP_REV_3_2 0x32
+
+#define SYSTEM_REV_MIN CHIP_REV_1_0
+#define SYSTEM_REV_NUM 3
+
+/* gpio and gpio based interrupt handling */
+#define GPIO_DR 0x00
+#define GPIO_GDIR 0x04
+#define GPIO_PSR 0x08
+#define GPIO_ICR1 0x0C
+#define GPIO_ICR2 0x10
+#define GPIO_IMR 0x14
+#define GPIO_ISR 0x18
+#define GPIO_INT_LOW_LEV 0x0
+#define GPIO_INT_HIGH_LEV 0x1
+#define GPIO_INT_RISE_EDGE 0x2
+#define GPIO_INT_FALL_EDGE 0x3
+#define GPIO_INT_NONE 0x4
+
+/* Mandatory defines used globally */
+
+/* this CPU supports up to 96 GPIOs */
+#define ARCH_NR_GPIOS 96
+
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+
+extern unsigned int system_rev;
+
+static inline int mx31_revision(void)
+{
+ return system_rev;
+}
+#endif
+
+#endif /* __ASM_ARCH_MXC_MX31_H__ */
+
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index f6caab062131..5fa2a07f4eaf 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -24,13 +24,74 @@
#error "Do not include directly."
#endif
-/* clean up all things that are not used */
-#ifndef CONFIG_ARCH_MX3
-# define cpu_is_mx31() (0)
+#define MXC_CPU_MX1 1
+#define MXC_CPU_MX21 21
+#define MXC_CPU_MX27 27
+#define MXC_CPU_MX31 31
+#define MXC_CPU_MX35 35
+
+#ifndef __ASSEMBLY__
+extern unsigned int __mxc_cpu_type;
+#endif
+
+#ifdef CONFIG_ARCH_MX1
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX1
+# endif
+# define cpu_is_mx1() (mxc_cpu_type == MXC_CPU_MX1)
+#else
+# define cpu_is_mx1() (0)
+#endif
+
+#ifdef CONFIG_MACH_MX21
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX21
+# endif
+# define cpu_is_mx21() (mxc_cpu_type == MXC_CPU_MX21)
+#else
+# define cpu_is_mx21() (0)
#endif
-#ifndef CONFIG_MACH_MX27
-# define cpu_is_mx27() (0)
+#ifdef CONFIG_MACH_MX27
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX27
+# endif
+# define cpu_is_mx27() (mxc_cpu_type == MXC_CPU_MX27)
+#else
+# define cpu_is_mx27() (0)
+#endif
+
+#ifdef CONFIG_ARCH_MX31
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX31
+# endif
+# define cpu_is_mx31() (mxc_cpu_type == MXC_CPU_MX31)
+#else
+# define cpu_is_mx31() (0)
+#endif
+
+#ifdef CONFIG_ARCH_MX35
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX35
+# endif
+# define cpu_is_mx35() (mxc_cpu_type == MXC_CPU_MX35)
+#else
+# define cpu_is_mx35() (0)
#endif
#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
@@ -39,4 +100,7 @@
#define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x8)
#endif
+#define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35())
+#define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27())
+
#endif /* __ASM_ARCH_MXC_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h
index bbfc37465fc5..e56241af870e 100644
--- a/arch/arm/plat-mxc/include/mach/system.h
+++ b/arch/arm/plat-mxc/include/mach/system.h
@@ -26,9 +26,6 @@ static inline void arch_idle(void)
cpu_do_idle();
}
-static inline void arch_reset(char mode)
-{
- cpu_reset(0);
-}
+void arch_reset(char mode, const char *cmd);
#endif /* __ASM_ARCH_MXC_SYSTEM_H__ */
diff --git a/arch/arm/plat-mxc/iomux-mx1-mx2.c b/arch/arm/plat-mxc/iomux-mx1-mx2.c
index df6f18395686..a37163ce280b 100644
--- a/arch/arm/plat-mxc/iomux-mx1-mx2.c
+++ b/arch/arm/plat-mxc/iomux-mx1-mx2.c
@@ -32,7 +32,7 @@
#include <mach/hardware.h>
#include <asm/mach/map.h>
-#include <mach/iomux-mx1-mx2.h>
+#include <mach/iomux.h>
void mxc_gpio_mode(int gpio_mode)
{
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c
new file mode 100644
index 000000000000..9bffbc507cc2
--- /dev/null
+++ b/arch/arm/plat-mxc/pwm.c
@@ -0,0 +1,300 @@
+/*
+ * simple driver for PWM (Pulse Width Modulator) controller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Derived from pxa PWM driver by eric miao <eric.miao@marvell.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+
+#if defined CONFIG_ARCH_MX1 || defined CONFIG_ARCH_MX21
+#define PWM_VER_1
+
+#define PWMCR 0x00 /* PWM Control Register */
+#define PWMSR 0x04 /* PWM Sample Register */
+#define PWMPR 0x08 /* PWM Period Register */
+#define PWMCNR 0x0C /* PWM Counter Register */
+
+#define PWMCR_HCTR (1 << 18) /* Halfword FIFO Data Swapping */
+#define PWMCR_BCTR (1 << 17) /* Byte FIFO Data Swapping */
+#define PWMCR_SWR (1 << 16) /* Software Reset */
+#define PWMCR_CLKSRC_PERCLK (0 << 15) /* PERCLK Clock Source */
+#define PWMCR_CLKSRC_CLK32 (1 << 15) /* 32KHz Clock Source */
+#define PWMCR_PRESCALER(x) (((x - 1) & 0x7F) << 8) /* PRESCALER */
+#define PWMCR_IRQ (1 << 7) /* Interrupt Request */
+#define PWMCR_IRQEN (1 << 6) /* Interrupt Request Enable */
+#define PWMCR_FIFOAV (1 << 5) /* FIFO Available */
+#define PWMCR_EN (1 << 4) /* Enables/Disables the PWM */
+#define PWMCR_REPEAT(x) (((x) & 0x03) << 2) /* Sample Repeats */
+#define PWMCR_DIV(x) (((x) & 0x03) << 0) /* Clock divider 2/4/8/16 */
+
+#define MAX_DIV (128 * 16)
+#endif
+
+#if defined CONFIG_MACH_MX27 || defined CONFIG_ARCH_MX31
+#define PWM_VER_2
+
+#define PWMCR 0x00 /* PWM Control Register */
+#define PWMSR 0x04 /* PWM Status Register */
+#define PWMIR 0x08 /* PWM Interrupt Register */
+#define PWMSAR 0x0C /* PWM Sample Register */
+#define PWMPR 0x10 /* PWM Period Register */
+#define PWMCNR 0x14 /* PWM Counter Register */
+
+#define PWMCR_EN (1 << 0) /* Enables/Disables the PWM */
+#define PWMCR_REPEAT(x) (((x) & 0x03) << 1) /* Sample Repeats */
+#define PWMCR_SWR (1 << 3) /* Software Reset */
+#define PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4)/* PRESCALER */
+#define PWMCR_CLKSRC(x) (((x) & 0x3) << 16)
+#define PWMCR_CLKSRC_OFF (0 << 16)
+#define PWMCR_CLKSRC_IPG (1 << 16)
+#define PWMCR_CLKSRC_IPG_HIGH (2 << 16)
+#define PWMCR_CLKSRC_CLK32 (3 << 16)
+#define PWMCR_POUTC
+#define PWMCR_HCTR (1 << 20) /* Halfword FIFO Data Swapping */
+#define PWMCR_BCTR (1 << 21) /* Byte FIFO Data Swapping */
+#define PWMCR_DBGEN (1 << 22) /* Debug Mode */
+#define PWMCR_WAITEN (1 << 23) /* Wait Mode */
+#define PWMCR_DOZEN (1 << 24) /* Doze Mode */
+#define PWMCR_STOPEN (1 << 25) /* Stop Mode */
+#define PWMCR_FWM(x) (((x) & 0x3) << 26) /* FIFO Water Mark */
+
+#define MAX_DIV 4096
+#endif
+
+#define PWMS_SAMPLE(x) ((x) & 0xFFFF) /* Contains a two-sample word */
+#define PWMP_PERIOD(x) ((x) & 0xFFFF) /* Represents the PWM's period */
+#define PWMC_COUNTER(x) ((x) & 0xFFFF) /* Represents the current count value */
+
+struct pwm_device {
+ struct list_head node;
+ struct platform_device *pdev;
+
+ const char *label;
+ struct clk *clk;
+
+ int clk_enabled;
+ void __iomem *mmio_base;
+
+ unsigned int use_count;
+ unsigned int pwm_id;
+};
+
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+ unsigned long long c;
+ unsigned long period_cycles, duty_cycles, prescale;
+
+ if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
+ return -EINVAL;
+
+ c = clk_get_rate(pwm->clk);
+ c = c * period_ns;
+ do_div(c, 1000000000);
+ period_cycles = c;
+
+ prescale = period_cycles / 0x10000 + 1;
+
+ period_cycles /= prescale;
+ c = (unsigned long long)period_cycles * duty_ns;
+ do_div(c, period_ns);
+ duty_cycles = c;
+
+#ifdef PWM_VER_2
+ writel(duty_cycles, pwm->mmio_base + PWMSAR);
+ writel(period_cycles, pwm->mmio_base + PWMPR);
+ writel(PWMCR_PRESCALER(prescale - 1) | PWMCR_CLKSRC_IPG_HIGH | PWMCR_EN,
+ pwm->mmio_base + PWMCR);
+#elif defined PWM_VER_1
+#error PWM not yet working on MX1 / MX21
+#endif
+
+ return 0;
+}
+EXPORT_SYMBOL(pwm_config);
+
+int pwm_enable(struct pwm_device *pwm)
+{
+ int rc = 0;
+
+ if (!pwm->clk_enabled) {
+ rc = clk_enable(pwm->clk);
+ if (!rc)
+ pwm->clk_enabled = 1;
+ }
+ return rc;
+}
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwm)
+{
+ if (pwm->clk_enabled) {
+ clk_disable(pwm->clk);
+ pwm->clk_enabled = 0;
+ }
+}
+EXPORT_SYMBOL(pwm_disable);
+
+static DEFINE_MUTEX(pwm_lock);
+static LIST_HEAD(pwm_list);
+
+struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+ struct pwm_device *pwm;
+ int found = 0;
+
+ mutex_lock(&pwm_lock);
+
+ list_for_each_entry(pwm, &pwm_list, node) {
+ if (pwm->pwm_id == pwm_id) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ if (pwm->use_count == 0) {
+ pwm->use_count++;
+ pwm->label = label;
+ } else
+ pwm = ERR_PTR(-EBUSY);
+ } else
+ pwm = ERR_PTR(-ENOENT);
+
+ mutex_unlock(&pwm_lock);
+ return pwm;
+}
+EXPORT_SYMBOL(pwm_request);
+
+void pwm_free(struct pwm_device *pwm)
+{
+ mutex_lock(&pwm_lock);
+
+ if (pwm->use_count) {
+ pwm->use_count--;
+ pwm->label = NULL;
+ } else
+ pr_warning("PWM device already freed\n");
+
+ mutex_unlock(&pwm_lock);
+}
+EXPORT_SYMBOL(pwm_free);
+
+static int __devinit mxc_pwm_probe(struct platform_device *pdev)
+{
+ struct pwm_device *pwm;
+ struct resource *r;
+ int ret = 0;
+
+ pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
+ if (pwm == NULL) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ pwm->clk = clk_get(&pdev->dev, "pwm");
+
+ if (IS_ERR(pwm->clk)) {
+ ret = PTR_ERR(pwm->clk);
+ goto err_free;
+ }
+
+ pwm->clk_enabled = 0;
+
+ pwm->use_count = 0;
+ pwm->pwm_id = pdev->id;
+ pwm->pdev = pdev;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (r == NULL) {
+ dev_err(&pdev->dev, "no memory resource defined\n");
+ ret = -ENODEV;
+ goto err_free_clk;
+ }
+
+ r = request_mem_region(r->start, r->end - r->start + 1, pdev->name);
+ if (r == NULL) {
+ dev_err(&pdev->dev, "failed to request memory resource\n");
+ ret = -EBUSY;
+ goto err_free_clk;
+ }
+
+ pwm->mmio_base = ioremap(r->start, r->end - r->start + 1);
+ if (pwm->mmio_base == NULL) {
+ dev_err(&pdev->dev, "failed to ioremap() registers\n");
+ ret = -ENODEV;
+ goto err_free_mem;
+ }
+
+ mutex_lock(&pwm_lock);
+ list_add_tail(&pwm->node, &pwm_list);
+ mutex_unlock(&pwm_lock);
+
+ platform_set_drvdata(pdev, pwm);
+ return 0;
+
+err_free_mem:
+ release_mem_region(r->start, r->end - r->start + 1);
+err_free_clk:
+ clk_put(pwm->clk);
+err_free:
+ kfree(pwm);
+ return ret;
+}
+
+static int __devexit mxc_pwm_remove(struct platform_device *pdev)
+{
+ struct pwm_device *pwm;
+ struct resource *r;
+
+ pwm = platform_get_drvdata(pdev);
+ if (pwm == NULL)
+ return -ENODEV;
+
+ mutex_lock(&pwm_lock);
+ list_del(&pwm->node);
+ mutex_unlock(&pwm_lock);
+
+ iounmap(pwm->mmio_base);
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(r->start, r->end - r->start + 1);
+
+ clk_put(pwm->clk);
+
+ kfree(pwm);
+ return 0;
+}
+
+static struct platform_driver mxc_pwm_driver = {
+ .driver = {
+ .name = "mxc_pwm",
+ },
+ .probe = mxc_pwm_probe,
+ .remove = __devexit_p(mxc_pwm_remove),
+};
+
+static int __init mxc_pwm_init(void)
+{
+ return platform_driver_register(&mxc_pwm_driver);
+}
+arch_initcall(mxc_pwm_init);
+
+static void __exit mxc_pwm_exit(void)
+{
+ platform_driver_unregister(&mxc_pwm_driver);
+}
+module_exit(mxc_pwm_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+
diff --git a/arch/arm/mach-mx2/system.c b/arch/arm/plat-mxc/system.c
index 7b8269719d11..79c37577c916 100644
--- a/arch/arm/mach-mx2/system.c
+++ b/arch/arm/plat-mxc/system.c
@@ -3,6 +3,7 @@
* Copyright (C) 2000 Deep Blue Solutions Ltd
* Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok@emcraft.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,42 +23,45 @@
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
#include <mach/hardware.h>
#include <asm/proc-fns.h>
#include <asm/system.h>
-/*
- * Put the CPU into idle mode. It is called by default_idle()
- * in process.c file.
- */
-void arch_idle(void)
-{
- /*
- * This should do all the clock switching
- * and wait for interrupt tricks.
- */
- cpu_do_idle();
-}
-
-#define WDOG_WCR_REG IO_ADDRESS(WDOG_BASE_ADDR)
-#define WDOG_WCR_SRS (1 << 4)
+#ifdef CONFIG_ARCH_MX1
+#define WDOG_WCR_REG IO_ADDRESS(WDT_BASE_ADDR)
+#define WDOG_WCR_ENABLE (1 << 0)
+#else
+#define WDOG_WCR_REG IO_ADDRESS(WDOG_BASE_ADDR)
+#define WDOG_WCR_ENABLE (1 << 2)
+#endif
/*
* Reset the system. It is called by machine_restart().
*/
-void arch_reset(char mode)
+void arch_reset(char mode, const char *cmd)
{
- struct clk *clk;
+ if (!cpu_is_mx1()) {
+ struct clk *clk;
- clk = clk_get(NULL, "wdog_clk");
- if (!clk) {
- printk(KERN_ERR"Cannot activate the watchdog. Giving up\n");
- return;
+ clk = clk_get_sys("imx-wdt.0", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
}
- clk_enable(clk);
-
/* Assert SRS signal */
- __raw_writew(__raw_readw(WDOG_WCR_REG) & ~WDOG_WCR_SRS, WDOG_WCR_REG);
+ __raw_writew(WDOG_WCR_ENABLE, WDOG_WCR_REG);
+
+ /* wait for reset to assert... */
+ mdelay(500);
+
+ printk(KERN_ERR "Watchdog reset failed to assert reset\n");
+
+ /* delay to allow the serial port to show the message */
+ mdelay(50);
+
+ /* we'll take a jump through zero as a poor second */
+ cpu_reset(0);
}
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 758a1293bcfa..ef1b3cd85bd3 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -34,9 +34,6 @@
static struct clock_event_device clockevent_mxc;
static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
-/* clock source for the timer */
-static struct clk *timer_clk;
-
/* clock source */
static cycle_t mxc_get_cycles(void)
@@ -53,13 +50,11 @@ static struct clocksource clocksource_mxc = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static int __init mxc_clocksource_init(void)
+static int __init mxc_clocksource_init(struct clk *timer_clk)
{
- unsigned int clock;
-
- clock = clk_get_rate(timer_clk);
+ unsigned int c = clk_get_rate(timer_clk);
- clocksource_mxc.mult = clocksource_hz2mult(clock,
+ clocksource_mxc.mult = clocksource_hz2mult(c,
clocksource_mxc.shift);
clocksource_register(&clocksource_mxc);
@@ -177,13 +172,11 @@ static struct clock_event_device clockevent_mxc = {
.rating = 200,
};
-static int __init mxc_clockevent_init(void)
+static int __init mxc_clockevent_init(struct clk *timer_clk)
{
- unsigned int clock;
-
- clock = clk_get_rate(timer_clk);
+ unsigned int c = clk_get_rate(timer_clk);
- clockevent_mxc.mult = div_sc(clock, NSEC_PER_SEC,
+ clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC,
clockevent_mxc.shift);
clockevent_mxc.max_delta_ns =
clockevent_delta2ns(0xfffffffe, &clockevent_mxc);
@@ -197,14 +190,8 @@ static int __init mxc_clockevent_init(void)
return 0;
}
-void __init mxc_timer_init(const char *clk_timer)
+void __init mxc_timer_init(struct clk *timer_clk)
{
- timer_clk = clk_get(NULL, clk_timer);
- if (!timer_clk) {
- printk(KERN_ERR"Cannot determine timer clock. Giving up.\n");
- return;
- }
-
clk_enable(timer_clk);
/*
@@ -219,10 +206,9 @@ void __init mxc_timer_init(const char *clk_timer)
TIMER_BASE + MXC_TCTL);
/* init and register the timer to the framework */
- mxc_clocksource_init();
- mxc_clockevent_init();
+ mxc_clocksource_init(timer_clk);
+ mxc_clockevent_init(timer_clk);
/* Make irqs happen */
setup_irq(TIMER_INTERRUPT, &mxc_timer_irq);
}
-
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 46d3b0b9ce69..9dd68fafb374 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -11,14 +11,17 @@ choice
config ARCH_OMAP1
bool "TI OMAP1"
+ select COMMON_CLKDEV
config ARCH_OMAP2
bool "TI OMAP2"
select CPU_V6
+ select COMMON_CLKDEV
config ARCH_OMAP3
bool "TI OMAP3"
select CPU_V7
+ select COMMON_CLKDEV
endchoice
@@ -104,6 +107,14 @@ config OMAP_MCBSP
Say Y here if you want support for the OMAP Multichannel
Buffered Serial Port.
+config OMAP_MBOX_FWK
+ tristate "Mailbox framework support"
+ depends on ARCH_OMAP
+ default n
+ help
+ Say Y here if you want to use OMAP Mailbox framework support for
+ DSP, IVA1.0 and IVA2 in OMAP1/2/3.
+
choice
prompt "System timer"
default OMAP_MPU_TIMER
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index be6aab9c6834..2e0614552ac8 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -36,44 +36,6 @@ static struct clk_functions *arch_clock;
* Standard clock functions defined in include/linux/clk.h
*-------------------------------------------------------------------------*/
-/*
- * Returns a clock. Note that we first try to use device id on the bus
- * and clock name. If this fails, we try to use clock name only.
- */
-struct clk * clk_get(struct device *dev, const char *id)
-{
- struct clk *p, *clk = ERR_PTR(-ENOENT);
- int idno;
-
- if (dev == NULL || dev->bus != &platform_bus_type)
- idno = -1;
- else
- idno = to_platform_device(dev)->id;
-
- mutex_lock(&clocks_mutex);
-
- list_for_each_entry(p, &clocks, node) {
- if (p->id == idno &&
- strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
- clk = p;
- goto found;
- }
- }
-
- list_for_each_entry(p, &clocks, node) {
- if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
- clk = p;
- break;
- }
- }
-
-found:
- mutex_unlock(&clocks_mutex);
-
- return clk;
-}
-EXPORT_SYMBOL(clk_get);
-
int clk_enable(struct clk *clk)
{
unsigned long flags;
@@ -114,22 +76,6 @@ out:
}
EXPORT_SYMBOL(clk_disable);
-int clk_get_usecount(struct clk *clk)
-{
- unsigned long flags;
- int ret = 0;
-
- if (clk == NULL || IS_ERR(clk))
- return 0;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- ret = clk->usecount;
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return ret;
-}
-EXPORT_SYMBOL(clk_get_usecount);
-
unsigned long clk_get_rate(struct clk *clk)
{
unsigned long flags;
@@ -146,13 +92,6 @@ unsigned long clk_get_rate(struct clk *clk)
}
EXPORT_SYMBOL(clk_get_rate);
-void clk_put(struct clk *clk)
-{
- if (clk && !IS_ERR(clk))
- module_put(clk->owner);
-}
-EXPORT_SYMBOL(clk_put);
-
/*-------------------------------------------------------------------------
* Optional clock functions defined in include/linux/clk.h
*-------------------------------------------------------------------------*/
@@ -185,6 +124,11 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
spin_lock_irqsave(&clockfw_lock, flags);
if (arch_clock->clk_set_rate)
ret = arch_clock->clk_set_rate(clk, rate);
+ if (ret == 0) {
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+ propagate_rate(clk);
+ }
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
@@ -200,8 +144,16 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
return ret;
spin_lock_irqsave(&clockfw_lock, flags);
- if (arch_clock->clk_set_parent)
- ret = arch_clock->clk_set_parent(clk, parent);
+ if (clk->usecount == 0) {
+ if (arch_clock->clk_set_parent)
+ ret = arch_clock->clk_set_parent(clk, parent);
+ if (ret == 0) {
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+ propagate_rate(clk);
+ }
+ } else
+ ret = -EBUSY;
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
@@ -210,18 +162,7 @@ EXPORT_SYMBOL(clk_set_parent);
struct clk *clk_get_parent(struct clk *clk)
{
- unsigned long flags;
- struct clk * ret = NULL;
-
- if (clk == NULL || IS_ERR(clk))
- return ret;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- if (arch_clock->clk_get_parent)
- ret = arch_clock->clk_get_parent(clk);
- spin_unlock_irqrestore(&clockfw_lock, flags);
-
- return ret;
+ return clk->parent;
}
EXPORT_SYMBOL(clk_get_parent);
@@ -250,14 +191,20 @@ static int __init omap_clk_setup(char *str)
__setup("mpurate=", omap_clk_setup);
/* Used for clocks that always have same value as the parent clock */
-void followparent_recalc(struct clk *clk)
+unsigned long followparent_recalc(struct clk *clk)
{
- if (clk == NULL || IS_ERR(clk))
- return;
+ return clk->parent->rate;
+}
- clk->rate = clk->parent->rate;
- if (unlikely(clk->flags & RATE_PROPAGATES))
- propagate_rate(clk);
+void clk_reparent(struct clk *child, struct clk *parent)
+{
+ list_del_init(&child->sibling);
+ if (parent)
+ list_add(&child->sibling, &parent->children);
+ child->parent = parent;
+
+ /* now do the debugfs renaming to reattach the child
+ to the proper parent */
}
/* Propagate rate to children */
@@ -265,17 +212,15 @@ void propagate_rate(struct clk * tclk)
{
struct clk *clkp;
- if (tclk == NULL || IS_ERR(tclk))
- return;
-
- list_for_each_entry(clkp, &clocks, node) {
- if (likely(clkp->parent != tclk))
- continue;
- if (likely((u32)clkp->recalc))
- clkp->recalc(clkp);
+ list_for_each_entry(clkp, &tclk->children, sibling) {
+ if (clkp->recalc)
+ clkp->rate = clkp->recalc(clkp);
+ propagate_rate(clkp);
}
}
+static LIST_HEAD(root_clks);
+
/**
* recalculate_root_clocks - recalculate and propagate all root clocks
*
@@ -287,18 +232,35 @@ void recalculate_root_clocks(void)
{
struct clk *clkp;
- list_for_each_entry(clkp, &clocks, node) {
- if (unlikely(!clkp->parent) && likely((u32)clkp->recalc))
- clkp->recalc(clkp);
+ list_for_each_entry(clkp, &root_clks, sibling) {
+ if (clkp->recalc)
+ clkp->rate = clkp->recalc(clkp);
+ propagate_rate(clkp);
}
}
+void clk_init_one(struct clk *clk)
+{
+ INIT_LIST_HEAD(&clk->children);
+}
+
int clk_register(struct clk *clk)
{
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
+ /*
+ * trap out already registered clocks
+ */
+ if (clk->node.next || clk->node.prev)
+ return 0;
+
mutex_lock(&clocks_mutex);
+ if (clk->parent)
+ list_add(&clk->sibling, &clk->parent->children);
+ else
+ list_add(&clk->sibling, &root_clks);
+
list_add(&clk->node, &clocks);
if (clk->init)
clk->init(clk);
@@ -314,39 +276,12 @@ void clk_unregister(struct clk *clk)
return;
mutex_lock(&clocks_mutex);
+ list_del(&clk->sibling);
list_del(&clk->node);
mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);
-void clk_deny_idle(struct clk *clk)
-{
- unsigned long flags;
-
- if (clk == NULL || IS_ERR(clk))
- return;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- if (arch_clock->clk_deny_idle)
- arch_clock->clk_deny_idle(clk);
- spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-EXPORT_SYMBOL(clk_deny_idle);
-
-void clk_allow_idle(struct clk *clk)
-{
- unsigned long flags;
-
- if (clk == NULL || IS_ERR(clk))
- return;
-
- spin_lock_irqsave(&clockfw_lock, flags);
- if (arch_clock->clk_allow_idle)
- arch_clock->clk_allow_idle(clk);
- spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-EXPORT_SYMBOL(clk_allow_idle);
-
void clk_enable_init_clocks(void)
{
struct clk *clkp;
@@ -358,6 +293,23 @@ void clk_enable_init_clocks(void)
}
EXPORT_SYMBOL(clk_enable_init_clocks);
+/*
+ * Low level helpers
+ */
+static int clkll_enable_null(struct clk *clk)
+{
+ return 0;
+}
+
+static void clkll_disable_null(struct clk *clk)
+{
+}
+
+const struct clkops clkops_null = {
+ .enable = clkll_enable_null,
+ .disable = clkll_disable_null,
+};
+
#ifdef CONFIG_CPU_FREQ
void clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
{
@@ -383,8 +335,10 @@ static int __init clk_disable_unused(void)
unsigned long flags;
list_for_each_entry(ck, &clocks, node) {
- if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) ||
- ck->enable_reg == 0)
+ if (ck->ops == &clkops_null)
+ continue;
+
+ if (ck->usecount > 0 || ck->enable_reg == 0)
continue;
spin_lock_irqsave(&clockfw_lock, flags);
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 6825fbb5a056..d1797147732f 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -245,7 +245,7 @@ static struct omap_globals *omap2_globals;
static void __init __omap2_set_globals(void)
{
omap2_set_globals_tap(omap2_globals);
- omap2_set_globals_memory(omap2_globals);
+ omap2_set_globals_sdrc(omap2_globals);
omap2_set_globals_control(omap2_globals);
omap2_set_globals_prcm(omap2_globals);
}
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index b2690242a390..843e8af64066 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -23,10 +23,13 @@
#include <linux/io.h>
#include <mach/hardware.h>
+#include <mach/clock.h>
#include <asm/system.h>
#define VERY_HI_RATE 900000000
+static struct cpufreq_frequency_table *freq_table;
+
#ifdef CONFIG_ARCH_OMAP1
#define MPU_CLK "mpu"
#else
@@ -39,6 +42,9 @@ static struct clk *mpu_clk;
int omap_verify_speed(struct cpufreq_policy *policy)
{
+ if (freq_table)
+ return cpufreq_frequency_table_verify(policy, freq_table);
+
if (policy->cpu)
return -EINVAL;
@@ -70,12 +76,26 @@ static int omap_target(struct cpufreq_policy *policy,
struct cpufreq_freqs freqs;
int ret = 0;
+ /* Ensure desired rate is within allowed range. Some govenors
+ * (ondemand) will just pass target_freq=0 to get the minimum. */
+ if (target_freq < policy->cpuinfo.min_freq)
+ target_freq = policy->cpuinfo.min_freq;
+ if (target_freq > policy->cpuinfo.max_freq)
+ target_freq = policy->cpuinfo.max_freq;
+
freqs.old = omap_getspeed(0);
freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
freqs.cpu = 0;
+ if (freqs.old == freqs.new)
+ return ret;
+
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- ret = clk_set_rate(mpu_clk, target_freq * 1000);
+#ifdef CONFIG_CPU_FREQ_DEBUG
+ printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
+ freqs.old, freqs.new);
+#endif
+ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
return ret;
@@ -83,16 +103,31 @@ static int omap_target(struct cpufreq_policy *policy,
static int __init omap_cpu_init(struct cpufreq_policy *policy)
{
+ int result = 0;
+
mpu_clk = clk_get(NULL, MPU_CLK);
if (IS_ERR(mpu_clk))
return PTR_ERR(mpu_clk);
if (policy->cpu != 0)
return -EINVAL;
+
policy->cur = policy->min = policy->max = omap_getspeed(0);
- policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
- policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, VERY_HI_RATE) / 1000;
- policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+
+ clk_init_cpufreq_table(&freq_table);
+ if (freq_table) {
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (!result)
+ cpufreq_frequency_table_get_attr(freq_table,
+ policy->cpu);
+ } else {
+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
+ VERY_HI_RATE) / 1000;
+ }
+
+ /* FIXME: what's the actual transition time? */
+ policy->cpuinfo.transition_latency = 10 * 1000 * 1000;
return 0;
}
@@ -103,6 +138,11 @@ static int omap_cpu_exit(struct cpufreq_policy *policy)
return 0;
}
+static struct freq_attr *omap_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
static struct cpufreq_driver omap_driver = {
.flags = CPUFREQ_STICKY,
.verify = omap_verify_speed,
@@ -111,6 +151,7 @@ static struct cpufreq_driver omap_driver = {
.init = omap_cpu_init,
.exit = omap_cpu_exit,
.name = "omap",
+ .attr = omap_cpufreq_attr,
};
static int __init omap_cpufreq_init(void)
@@ -119,3 +160,11 @@ static int __init omap_cpufreq_init(void)
}
arch_initcall(omap_cpufreq_init);
+
+/*
+ * if ever we want to remove this, upon cleanup call:
+ *
+ * cpufreq_unregister_driver()
+ * cpufreq_frequency_table_put_attr()
+ */
+
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 208dbb121f47..87fb7ff41794 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -228,6 +228,9 @@ int __init omap_mmc_add(const char *name, int id, unsigned long base,
ret = platform_device_add(pdev);
if (ret)
goto fail;
+
+ /* return device handle to board setup code */
+ data->dev = &pdev->dev;
return 0;
fail:
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 47ec77af4ccb..21cc0142b97a 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -123,6 +123,7 @@ static struct dma_link_info *dma_linked_lch;
static int dma_lch_count;
static int dma_chan_count;
+static int omap_dma_reserve_channels;
static spinlock_t dma_chan_lock;
static struct omap_dma_lch *dma_chan;
@@ -737,7 +738,7 @@ int omap_request_dma(int dev_id, const char *dev_name,
* id.
*/
dma_write(dev_id | (1 << 10), CCR(free_ch));
- } else if (cpu_is_omap730() || cpu_is_omap15xx()) {
+ } else if (cpu_is_omap7xx() || cpu_is_omap15xx()) {
dma_write(dev_id, CCR(free_ch));
}
@@ -1900,7 +1901,7 @@ static int omap2_dma_handle_ch(int ch)
/* STATUS register count is from 1-32 while our is 0-31 */
static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
{
- u32 val;
+ u32 val, enable_reg;
int i;
val = dma_read(IRQSTATUS_L0);
@@ -1909,6 +1910,8 @@ static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
printk(KERN_WARNING "Spurious DMA IRQ\n");
return IRQ_HANDLED;
}
+ enable_reg = dma_read(IRQENABLE_L0);
+ val &= enable_reg; /* Dispatch only relevant interrupts */
for (i = 0; i < dma_lch_count && val != 0; i++) {
if (val & 1)
omap2_dma_handle_ch(i);
@@ -2321,6 +2324,10 @@ static int __init omap_init_dma(void)
return -ENODEV;
}
+ if (cpu_class_is_omap2() && omap_dma_reserve_channels
+ && (omap_dma_reserve_channels <= dma_lch_count))
+ dma_lch_count = omap_dma_reserve_channels;
+
dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count,
GFP_KERNEL);
if (!dma_chan)
@@ -2339,7 +2346,7 @@ static int __init omap_init_dma(void)
printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
dma_chan_count = 9;
enable_1510_mode = 1;
- } else if (cpu_is_omap16xx() || cpu_is_omap730()) {
+ } else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
printk(KERN_INFO "OMAP DMA hardware version %d\n",
dma_read(HW_ID));
printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
@@ -2371,7 +2378,7 @@ static int __init omap_init_dma(void)
u8 revision = dma_read(REVISION) & 0xff;
printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
revision >> 4, revision & 0xf);
- dma_chan_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
+ dma_chan_count = dma_lch_count;
} else {
dma_chan_count = 0;
return 0;
@@ -2437,4 +2444,17 @@ static int __init omap_init_dma(void)
arch_initcall(omap_init_dma);
+/*
+ * Reserve the omap SDMA channels using cmdline bootarg
+ * "omap_dma_reserve_ch=". The valid range is 1 to 32
+ */
+static int __init omap_dma_cmdline_reserve_ch(char *str)
+{
+ if (get_option(&str, &omap_dma_reserve_channels) != 1)
+ omap_dma_reserve_channels = 0;
+ return 1;
+}
+
+__setup("omap_dma_reserve_ch=", omap_dma_cmdline_reserve_ch);
+
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index e4f0ce04ba92..bfd47570cc91 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -33,6 +33,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/module.h>
#include <mach/hardware.h>
#include <mach/dmtimer.h>
#include <mach/irqs.h>
@@ -362,6 +363,7 @@ struct omap_dm_timer *omap_dm_timer_request(void)
return timer;
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_request);
struct omap_dm_timer *omap_dm_timer_request_specific(int id)
{
@@ -385,6 +387,7 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
return timer;
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
void omap_dm_timer_free(struct omap_dm_timer *timer)
{
@@ -395,6 +398,7 @@ void omap_dm_timer_free(struct omap_dm_timer *timer)
WARN_ON(!timer->reserved);
timer->reserved = 0;
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_free);
void omap_dm_timer_enable(struct omap_dm_timer *timer)
{
@@ -406,6 +410,7 @@ void omap_dm_timer_enable(struct omap_dm_timer *timer)
timer->enabled = 1;
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
void omap_dm_timer_disable(struct omap_dm_timer *timer)
{
@@ -417,11 +422,13 @@ void omap_dm_timer_disable(struct omap_dm_timer *timer)
timer->enabled = 0;
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_disable);
int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
{
return timer->irq;
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
#if defined(CONFIG_ARCH_OMAP1)
@@ -452,6 +459,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
return inputmask;
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
#elif defined(CONFIG_ARCH_OMAP2) || defined (CONFIG_ARCH_OMAP3)
@@ -459,6 +467,7 @@ struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
{
return timer->fclk;
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_get_fclk);
__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
{
@@ -466,6 +475,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
return 0;
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
#endif
@@ -473,6 +483,7 @@ void omap_dm_timer_trigger(struct omap_dm_timer *timer)
{
omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_trigger);
void omap_dm_timer_start(struct omap_dm_timer *timer)
{
@@ -484,6 +495,7 @@ void omap_dm_timer_start(struct omap_dm_timer *timer)
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_start);
void omap_dm_timer_stop(struct omap_dm_timer *timer)
{
@@ -495,6 +507,7 @@ void omap_dm_timer_stop(struct omap_dm_timer *timer)
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
#ifdef CONFIG_ARCH_OMAP1
@@ -507,6 +520,7 @@ void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
l |= source << n;
omap_writel(l, MOD_CONF_CTRL_1);
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
#else
@@ -523,6 +537,7 @@ void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
* cause an abort. */
__delay(150000);
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
#endif
@@ -541,6 +556,7 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_load);
/* Optimized set_load which removes costly spin wait in timer_start */
void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
@@ -560,6 +576,7 @@ void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, load);
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
unsigned int match)
@@ -574,6 +591,7 @@ void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_match);
void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
int toggle, int trigger)
@@ -590,6 +608,7 @@ void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
l |= trigger << 10;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_pwm);
void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
{
@@ -603,6 +622,7 @@ void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
}
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler);
void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
unsigned int value)
@@ -610,6 +630,7 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value);
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
{
@@ -619,11 +640,13 @@ unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
return l;
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_read_status);
void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
{
omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value);
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
{
@@ -633,11 +656,13 @@ unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
return l;
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter);
void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
{
omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
}
+EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter);
int omap_dm_timers_active(void)
{
@@ -658,6 +683,7 @@ int omap_dm_timers_active(void)
}
return 0;
}
+EXPORT_SYMBOL_GPL(omap_dm_timers_active);
int __init omap_dm_timer_init(void)
{
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index f856a90b264e..d3fa41e3d8c5 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -81,6 +81,22 @@
#define OMAP730_GPIO_INT_STATUS 0x14
/*
+ * OMAP850 specific GPIO registers
+ */
+#define OMAP850_GPIO1_BASE IO_ADDRESS(0xfffbc000)
+#define OMAP850_GPIO2_BASE IO_ADDRESS(0xfffbc800)
+#define OMAP850_GPIO3_BASE IO_ADDRESS(0xfffbd000)
+#define OMAP850_GPIO4_BASE IO_ADDRESS(0xfffbd800)
+#define OMAP850_GPIO5_BASE IO_ADDRESS(0xfffbe000)
+#define OMAP850_GPIO6_BASE IO_ADDRESS(0xfffbe800)
+#define OMAP850_GPIO_DATA_INPUT 0x00
+#define OMAP850_GPIO_DATA_OUTPUT 0x04
+#define OMAP850_GPIO_DIR_CONTROL 0x08
+#define OMAP850_GPIO_INT_CONTROL 0x0c
+#define OMAP850_GPIO_INT_MASK 0x10
+#define OMAP850_GPIO_INT_STATUS 0x14
+
+/*
* omap24xx specific GPIO registers
*/
#define OMAP242X_GPIO1_BASE IO_ADDRESS(0x48018000)
@@ -159,7 +175,8 @@ struct gpio_bank {
#define METHOD_GPIO_1510 1
#define METHOD_GPIO_1610 2
#define METHOD_GPIO_730 3
-#define METHOD_GPIO_24XX 4
+#define METHOD_GPIO_850 4
+#define METHOD_GPIO_24XX 5
#ifdef CONFIG_ARCH_OMAP16XX
static struct gpio_bank gpio_bank_1610[5] = {
@@ -190,6 +207,19 @@ static struct gpio_bank gpio_bank_730[7] = {
};
#endif
+#ifdef CONFIG_ARCH_OMAP850
+static struct gpio_bank gpio_bank_850[7] = {
+ { OMAP_MPUIO_BASE, INT_850_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
+ { OMAP850_GPIO1_BASE, INT_850_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_850 },
+ { OMAP850_GPIO2_BASE, INT_850_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_850 },
+ { OMAP850_GPIO3_BASE, INT_850_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_850 },
+ { OMAP850_GPIO4_BASE, INT_850_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_850 },
+ { OMAP850_GPIO5_BASE, INT_850_GPIO_BANK5, IH_GPIO_BASE + 128, METHOD_GPIO_850 },
+ { OMAP850_GPIO6_BASE, INT_850_GPIO_BANK6, IH_GPIO_BASE + 160, METHOD_GPIO_850 },
+};
+#endif
+
+
#ifdef CONFIG_ARCH_OMAP24XX
static struct gpio_bank gpio_bank_242x[4] = {
@@ -236,7 +266,7 @@ static inline struct gpio_bank *get_gpio_bank(int gpio)
return &gpio_bank[0];
return &gpio_bank[1 + (gpio >> 4)];
}
- if (cpu_is_omap730()) {
+ if (cpu_is_omap7xx()) {
if (OMAP_GPIO_IS_MPUIO(gpio))
return &gpio_bank[0];
return &gpio_bank[1 + (gpio >> 5)];
@@ -251,7 +281,7 @@ static inline struct gpio_bank *get_gpio_bank(int gpio)
static inline int get_gpio_index(int gpio)
{
- if (cpu_is_omap730())
+ if (cpu_is_omap7xx())
return gpio & 0x1f;
if (cpu_is_omap24xx())
return gpio & 0x1f;
@@ -273,7 +303,7 @@ static inline int gpio_valid(int gpio)
return 0;
if ((cpu_is_omap16xx()) && gpio < 64)
return 0;
- if (cpu_is_omap730() && gpio < 192)
+ if (cpu_is_omap7xx() && gpio < 192)
return 0;
if (cpu_is_omap24xx() && gpio < 128)
return 0;
@@ -318,6 +348,11 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
reg += OMAP730_GPIO_DIR_CONTROL;
break;
#endif
+#ifdef CONFIG_ARCH_OMAP850
+ case METHOD_GPIO_850:
+ reg += OMAP850_GPIO_DIR_CONTROL;
+ break;
+#endif
#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_OE;
@@ -380,6 +415,16 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
l &= ~(1 << gpio);
break;
#endif
+#ifdef CONFIG_ARCH_OMAP850
+ case METHOD_GPIO_850:
+ reg += OMAP850_GPIO_DATA_OUTPUT;
+ l = __raw_readl(reg);
+ if (enable)
+ l |= 1 << gpio;
+ else
+ l &= ~(1 << gpio);
+ break;
+#endif
#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
if (enable)
@@ -426,6 +471,11 @@ static int __omap_get_gpio_datain(int gpio)
reg += OMAP730_GPIO_DATA_INPUT;
break;
#endif
+#ifdef CONFIG_ARCH_OMAP850
+ case METHOD_GPIO_850:
+ reg += OMAP850_GPIO_DATA_INPUT;
+ break;
+#endif
#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_DATAIN;
@@ -598,6 +648,18 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
goto bad;
break;
#endif
+#ifdef CONFIG_ARCH_OMAP850
+ case METHOD_GPIO_850:
+ reg += OMAP850_GPIO_INT_CONTROL;
+ l = __raw_readl(reg);
+ if (trigger & IRQ_TYPE_EDGE_RISING)
+ l |= 1 << gpio;
+ else if (trigger & IRQ_TYPE_EDGE_FALLING)
+ l &= ~(1 << gpio);
+ else
+ goto bad;
+ break;
+#endif
#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
set_24xx_gpio_triggering(bank, gpio, trigger);
@@ -678,6 +740,11 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
reg += OMAP730_GPIO_INT_STATUS;
break;
#endif
+#ifdef CONFIG_ARCH_OMAP850
+ case METHOD_GPIO_850:
+ reg += OMAP850_GPIO_INT_STATUS;
+ break;
+#endif
#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_IRQSTATUS1;
@@ -736,6 +803,13 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
inv = 1;
break;
#endif
+#ifdef CONFIG_ARCH_OMAP850
+ case METHOD_GPIO_850:
+ reg += OMAP850_GPIO_INT_MASK;
+ mask = 0xffffffff;
+ inv = 1;
+ break;
+#endif
#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_IRQENABLE1;
@@ -799,6 +873,16 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
l |= gpio_mask;
break;
#endif
+#ifdef CONFIG_ARCH_OMAP850
+ case METHOD_GPIO_850:
+ reg += OMAP850_GPIO_INT_MASK;
+ l = __raw_readl(reg);
+ if (enable)
+ l &= ~(gpio_mask);
+ else
+ l |= gpio_mask;
+ break;
+#endif
#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
case METHOD_GPIO_24XX:
if (enable)
@@ -983,6 +1067,10 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
if (bank->method == METHOD_GPIO_730)
isr_reg = bank->base + OMAP730_GPIO_INT_STATUS;
#endif
+#ifdef CONFIG_ARCH_OMAP850
+ if (bank->method == METHOD_GPIO_850)
+ isr_reg = bank->base + OMAP850_GPIO_INT_STATUS;
+#endif
#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
if (bank->method == METHOD_GPIO_24XX)
isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
@@ -1372,6 +1460,13 @@ static int __init _omap_gpio_init(void)
gpio_bank = gpio_bank_730;
}
#endif
+#ifdef CONFIG_ARCH_OMAP850
+ if (cpu_is_omap850()) {
+ printk(KERN_INFO "OMAP850 GPIO hardware\n");
+ gpio_bank_count = 7;
+ gpio_bank = gpio_bank_850;
+ }
+#endif
#ifdef CONFIG_ARCH_OMAP24XX
if (cpu_is_omap242x()) {
@@ -1420,7 +1515,7 @@ static int __init _omap_gpio_init(void)
__raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
__raw_writew(0x0014, bank->base + OMAP1610_GPIO_SYSCONFIG);
}
- if (cpu_is_omap730() && bank->method == METHOD_GPIO_730) {
+ if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_730) {
__raw_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK);
__raw_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS);
@@ -1743,6 +1838,9 @@ static int gpio_is_input(struct gpio_bank *bank, int mask)
case METHOD_GPIO_730:
reg += OMAP730_GPIO_DIR_CONTROL;
break;
+ case METHOD_GPIO_850:
+ reg += OMAP850_GPIO_DIR_CONTROL;
+ break;
case METHOD_GPIO_24XX:
reg += OMAP24XX_GPIO_OE;
break;
@@ -1762,7 +1860,8 @@ static int dbg_gpio_show(struct seq_file *s, void *unused)
if (bank_is_mpuio(bank))
gpio = OMAP_MPUIO(0);
- else if (cpu_class_is_omap2() || cpu_is_omap730())
+ else if (cpu_class_is_omap2() || cpu_is_omap730() ||
+ cpu_is_omap850())
bankwidth = 32;
for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) {
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index 467531edefd3..a303071d5e36 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -98,6 +98,8 @@ static const int omap34xx_pins[][2] = {
static const int omap34xx_pins[][2] = {};
#endif
+#define OMAP_I2C_CMDLINE_SETUP (BIT(31))
+
static void __init omap_i2c_mux_pins(int bus)
{
int scl, sda;
@@ -119,14 +121,9 @@ static void __init omap_i2c_mux_pins(int bus)
omap_cfg_reg(scl);
}
-int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
- struct i2c_board_info const *info,
- unsigned len)
+static int __init omap_i2c_nr_ports(void)
{
- int ports, err;
- struct platform_device *pdev;
- struct resource *res;
- resource_size_t base, irq;
+ int ports = 0;
if (cpu_class_is_omap1())
ports = 1;
@@ -135,17 +132,16 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
else if (cpu_is_omap34xx())
ports = 3;
- BUG_ON(bus_id < 1 || bus_id > ports);
+ return ports;
+}
- if (info) {
- err = i2c_register_board_info(bus_id, info, len);
- if (err)
- return err;
- }
+static int __init omap_i2c_add_bus(int bus_id)
+{
+ struct platform_device *pdev;
+ struct resource *res;
+ resource_size_t base, irq;
pdev = &omap_i2c_devices[bus_id - 1];
- *(u32 *)pdev->dev.platform_data = clkrate;
-
if (bus_id == 1) {
res = pdev->resource;
if (cpu_class_is_omap1()) {
@@ -163,3 +159,81 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
omap_i2c_mux_pins(bus_id - 1);
return platform_device_register(pdev);
}
+
+/**
+ * omap_i2c_bus_setup - Process command line options for the I2C bus speed
+ * @str: String of options
+ *
+ * This function allow to override the default I2C bus speed for given I2C
+ * bus with a command line option.
+ *
+ * Format: i2c_bus=bus_id,clkrate (in kHz)
+ *
+ * Returns 1 on success, 0 otherwise.
+ */
+static int __init omap_i2c_bus_setup(char *str)
+{
+ int ports;
+ int ints[3];
+
+ ports = omap_i2c_nr_ports();
+ get_options(str, 3, ints);
+ if (ints[0] < 2 || ints[1] < 1 || ints[1] > ports)
+ return 0;
+ i2c_rate[ints[1] - 1] = ints[2];
+ i2c_rate[ints[1] - 1] |= OMAP_I2C_CMDLINE_SETUP;
+
+ return 1;
+}
+__setup("i2c_bus=", omap_i2c_bus_setup);
+
+/*
+ * Register busses defined in command line but that are not registered with
+ * omap_register_i2c_bus from board initialization code.
+ */
+static int __init omap_register_i2c_bus_cmdline(void)
+{
+ int i, err = 0;
+
+ for (i = 0; i < ARRAY_SIZE(i2c_rate); i++)
+ if (i2c_rate[i] & OMAP_I2C_CMDLINE_SETUP) {
+ i2c_rate[i] &= ~OMAP_I2C_CMDLINE_SETUP;
+ err = omap_i2c_add_bus(i + 1);
+ if (err)
+ goto out;
+ }
+
+out:
+ return err;
+}
+subsys_initcall(omap_register_i2c_bus_cmdline);
+
+/**
+ * omap_register_i2c_bus - register I2C bus with device descriptors
+ * @bus_id: bus id counting from number 1
+ * @clkrate: clock rate of the bus in kHz
+ * @info: pointer into I2C device descriptor table or NULL
+ * @len: number of descriptors in the table
+ *
+ * Returns 0 on success or an error code.
+ */
+int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
+ struct i2c_board_info const *info,
+ unsigned len)
+{
+ int err;
+
+ BUG_ON(bus_id < 1 || bus_id > omap_i2c_nr_ports());
+
+ if (info) {
+ err = i2c_register_board_info(bus_id, info, len);
+ if (err)
+ return err;
+ }
+
+ if (!i2c_rate[bus_id - 1])
+ i2c_rate[bus_id - 1] = clkrate;
+ i2c_rate[bus_id - 1] &= ~OMAP_I2C_CMDLINE_SETUP;
+
+ return omap_i2c_add_bus(bus_id);
+}
diff --git a/arch/arm/plat-omap/include/mach/board-2430sdp.h b/arch/arm/plat-omap/include/mach/board-2430sdp.h
deleted file mode 100644
index 10d449ea7ed0..000000000000
--- a/arch/arm/plat-omap/include/mach/board-2430sdp.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-2430sdp.h
- *
- * Hardware definitions for TI OMAP2430 SDP board.
- *
- * Based on board-h4.h by Dirk Behme <dirk.behme@de.bosch.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ASM_ARCH_OMAP_2430SDP_H
-#define __ASM_ARCH_OMAP_2430SDP_H
-
-/* Placeholder for 2430SDP specific defines */
-#define OMAP24XX_ETHR_START 0x08000300
-#define OMAP24XX_ETHR_GPIO_IRQ 149
-#define SDP2430_CS0_BASE 0x04000000
-
-/* Function prototypes */
-extern void sdp2430_flash_init(void);
-extern void sdp2430_usb_init(void);
-
-#endif /* __ASM_ARCH_OMAP_2430SDP_H */
diff --git a/arch/arm/plat-omap/include/mach/board-apollon.h b/arch/arm/plat-omap/include/mach/board-apollon.h
deleted file mode 100644
index 61bd5e8f09b1..000000000000
--- a/arch/arm/plat-omap/include/mach/board-apollon.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-apollon.h
- *
- * Hardware definitions for Samsung OMAP24XX Apollon board.
- *
- * Initial creation by Kyungmin Park <kyungmin.park@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ASM_ARCH_OMAP_APOLLON_H
-#define __ASM_ARCH_OMAP_APOLLON_H
-
-#include <mach/cpu.h>
-
-extern void apollon_mmc_init(void);
-
-static inline int apollon_plus(void)
-{
- /* The apollon plus has IDCODE revision 5 */
- return omap_rev() & 0xc0;
-}
-
-/* Placeholder for APOLLON specific defines */
-#define APOLLON_ETHR_GPIO_IRQ 74
-
-#endif /* __ASM_ARCH_OMAP_APOLLON_H */
-
diff --git a/arch/arm/plat-omap/include/mach/board-fsample.h b/arch/arm/plat-omap/include/mach/board-fsample.h
deleted file mode 100644
index cb3c5ae12776..000000000000
--- a/arch/arm/plat-omap/include/mach/board-fsample.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-fsample.h
- *
- * Board-specific goodies for TI F-Sample.
- *
- * Copyright (C) 2006 Google, Inc.
- * Author: Brian Swetland <swetland@google.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_OMAP_FSAMPLE_H
-#define __ASM_ARCH_OMAP_FSAMPLE_H
-
-/* fsample is pretty close to p2-sample */
-#include <mach/board-perseus2.h>
-
-#define fsample_cpld_read(reg) __raw_readb(reg)
-#define fsample_cpld_write(val, reg) __raw_writeb(val, reg)
-
-#define FSAMPLE_CPLD_BASE 0xE8100000
-#define FSAMPLE_CPLD_SIZE SZ_4K
-#define FSAMPLE_CPLD_START 0x05080000
-
-#define FSAMPLE_CPLD_REG_A (FSAMPLE_CPLD_BASE + 0x00)
-#define FSAMPLE_CPLD_SWITCH (FSAMPLE_CPLD_BASE + 0x02)
-#define FSAMPLE_CPLD_UART (FSAMPLE_CPLD_BASE + 0x02)
-#define FSAMPLE_CPLD_REG_B (FSAMPLE_CPLD_BASE + 0x04)
-#define FSAMPLE_CPLD_VERSION (FSAMPLE_CPLD_BASE + 0x06)
-#define FSAMPLE_CPLD_SET_CLR (FSAMPLE_CPLD_BASE + 0x06)
-
-#define FSAMPLE_CPLD_BIT_BT_RESET 0
-#define FSAMPLE_CPLD_BIT_LCD_RESET 1
-#define FSAMPLE_CPLD_BIT_CAM_PWDN 2
-#define FSAMPLE_CPLD_BIT_CHARGER_ENABLE 3
-#define FSAMPLE_CPLD_BIT_SD_MMC_EN 4
-#define FSAMPLE_CPLD_BIT_aGPS_PWREN 5
-#define FSAMPLE_CPLD_BIT_BACKLIGHT 6
-#define FSAMPLE_CPLD_BIT_aGPS_EN_RESET 7
-#define FSAMPLE_CPLD_BIT_aGPS_SLEEPx_N 8
-#define FSAMPLE_CPLD_BIT_OTG_RESET 9
-
-#define fsample_cpld_set(bit) \
- fsample_cpld_write((((bit) & 15) << 4) | 0x0f, FSAMPLE_CPLD_SET_CLR)
-
-#define fsample_cpld_clear(bit) \
- fsample_cpld_write(0xf0 | ((bit) & 15), FSAMPLE_CPLD_SET_CLR)
-
-#endif
diff --git a/arch/arm/plat-omap/include/mach/board-h4.h b/arch/arm/plat-omap/include/mach/board-h4.h
deleted file mode 100644
index 7c3fa0f0a65e..000000000000
--- a/arch/arm/plat-omap/include/mach/board-h4.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-h4.h
- *
- * Hardware definitions for TI OMAP2420 H4 board.
- *
- * Initial creation by Dirk Behme <dirk.behme@de.bosch.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ASM_ARCH_OMAP_H4_H
-#define __ASM_ARCH_OMAP_H4_H
-
-/* MMC Prototypes */
-extern void h4_mmc_init(void);
-
-/* Placeholder for H4 specific defines */
-#define OMAP24XX_ETHR_GPIO_IRQ 92
-#endif /* __ASM_ARCH_OMAP_H4_H */
-
diff --git a/arch/arm/plat-omap/include/mach/board-innovator.h b/arch/arm/plat-omap/include/mach/board-innovator.h
deleted file mode 100644
index 5ae3e79b9f9c..000000000000
--- a/arch/arm/plat-omap/include/mach/board-innovator.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-innovator.h
- *
- * Copyright (C) 2001 RidgeRun, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#ifndef __ASM_ARCH_OMAP_INNOVATOR_H
-#define __ASM_ARCH_OMAP_INNOVATOR_H
-
-#if defined (CONFIG_ARCH_OMAP15XX)
-
-#ifndef OMAP_SDRAM_DEVICE
-#define OMAP_SDRAM_DEVICE D256M_1X16_4B
-#endif
-
-#define OMAP1510P1_IMIF_PRI_VALUE 0x00
-#define OMAP1510P1_EMIFS_PRI_VALUE 0x00
-#define OMAP1510P1_EMIFF_PRI_VALUE 0x00
-
-#ifndef __ASSEMBLY__
-void fpga_write(unsigned char val, int reg);
-unsigned char fpga_read(int reg);
-#endif
-
-#endif /* CONFIG_ARCH_OMAP15XX */
-
-#if defined (CONFIG_ARCH_OMAP16XX)
-
-/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
-#define INNOVATOR1610_ETHR_START 0x04000300
-
-#endif /* CONFIG_ARCH_OMAP1610 */
-#endif /* __ASM_ARCH_OMAP_INNOVATOR_H */
diff --git a/arch/arm/plat-omap/include/mach/board-ldp.h b/arch/arm/plat-omap/include/mach/board-ldp.h
deleted file mode 100644
index f23399665212..000000000000
--- a/arch/arm/plat-omap/include/mach/board-ldp.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-ldp.h
- *
- * Hardware definitions for TI OMAP3 LDP.
- *
- * Copyright (C) 2008 Texas Instruments Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ASM_ARCH_OMAP_LDP_H
-#define __ASM_ARCH_OMAP_LDP_H
-
-extern void twl4030_bci_battery_init(void);
-
-#define TWL4030_IRQNUM INT_34XX_SYS_NIRQ
-#define LDP_SMC911X_CS 1
-#define LDP_SMC911X_GPIO 152
-#define DEBUG_BASE 0x08000000
-#define OMAP34XX_ETHR_START DEBUG_BASE
-#endif /* __ASM_ARCH_OMAP_LDP_H */
diff --git a/arch/arm/plat-omap/include/mach/board-nokia.h b/arch/arm/plat-omap/include/mach/board-nokia.h
deleted file mode 100644
index 2abbe001af8c..000000000000
--- a/arch/arm/plat-omap/include/mach/board-nokia.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-nokia.h
- *
- * Information structures for Nokia-specific board config data
- *
- * Copyright (C) 2005 Nokia Corporation
- */
-
-#ifndef _OMAP_BOARD_NOKIA_H
-#define _OMAP_BOARD_NOKIA_H
-
-#include <linux/types.h>
-
-#define OMAP_TAG_NOKIA_BT 0x4e01
-#define OMAP_TAG_WLAN_CX3110X 0x4e02
-#define OMAP_TAG_CBUS 0x4e03
-#define OMAP_TAG_EM_ASIC_BB5 0x4e04
-
-
-#define BT_CHIP_CSR 1
-#define BT_CHIP_TI 2
-
-#define BT_SYSCLK_12 1
-#define BT_SYSCLK_38_4 2
-
-struct omap_bluetooth_config {
- u8 chip_type;
- u8 bt_wakeup_gpio;
- u8 host_wakeup_gpio;
- u8 reset_gpio;
- u8 bt_uart;
- u8 bd_addr[6];
- u8 bt_sysclk;
-};
-
-struct omap_wlan_cx3110x_config {
- u8 chip_type;
- s16 power_gpio;
- s16 irq_gpio;
- s16 spi_cs_gpio;
-};
-
-struct omap_cbus_config {
- s16 clk_gpio;
- s16 dat_gpio;
- s16 sel_gpio;
-};
-
-struct omap_em_asic_bb5_config {
- s16 retu_irq_gpio;
- s16 tahvo_irq_gpio;
-};
-
-#endif
diff --git a/arch/arm/plat-omap/include/mach/board-omap3beagle.h b/arch/arm/plat-omap/include/mach/board-omap3beagle.h
deleted file mode 100644
index 3080d52d877a..000000000000
--- a/arch/arm/plat-omap/include/mach/board-omap3beagle.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-omap3beagle.h
- *
- * Hardware definitions for TI OMAP3 BEAGLE.
- *
- * Initial creation by Syed Mohammed Khasim <khasim@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ASM_ARCH_OMAP3_BEAGLE_H
-#define __ASM_ARCH_OMAP3_BEAGLE_H
-
-#endif /* __ASM_ARCH_OMAP3_BEAGLE_H */
-
diff --git a/arch/arm/plat-omap/include/mach/board-osk.h b/arch/arm/plat-omap/include/mach/board-osk.h
deleted file mode 100644
index 3850cb1f220a..000000000000
--- a/arch/arm/plat-omap/include/mach/board-osk.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-osk.h
- *
- * Hardware definitions for TI OMAP5912 OSK board.
- *
- * Written by Dirk Behme <dirk.behme@de.bosch.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ASM_ARCH_OMAP_OSK_H
-#define __ASM_ARCH_OMAP_OSK_H
-
-/* At OMAP5912 OSK the Ethernet is directly connected to CS1 */
-#define OMAP_OSK_ETHR_START 0x04800300
-
-/* TPS65010 has four GPIOs. nPG and LED2 can be treated like GPIOs with
- * alternate pin configurations for hardware-controlled blinking.
- */
-#define OSK_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
-# define OSK_TPS_GPIO_USB_PWR_EN (OSK_TPS_GPIO_BASE + 0)
-# define OSK_TPS_GPIO_LED_D3 (OSK_TPS_GPIO_BASE + 1)
-# define OSK_TPS_GPIO_LAN_RESET (OSK_TPS_GPIO_BASE + 2)
-# define OSK_TPS_GPIO_DSP_PWR_EN (OSK_TPS_GPIO_BASE + 3)
-# define OSK_TPS_GPIO_LED_D9 (OSK_TPS_GPIO_BASE + 4)
-# define OSK_TPS_GPIO_LED_D2 (OSK_TPS_GPIO_BASE + 5)
-
-#endif /* __ASM_ARCH_OMAP_OSK_H */
-
diff --git a/arch/arm/plat-omap/include/mach/board-overo.h b/arch/arm/plat-omap/include/mach/board-overo.h
deleted file mode 100644
index 7ecae66966d1..000000000000
--- a/arch/arm/plat-omap/include/mach/board-overo.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * board-overo.h (Gumstix Overo)
- *
- * Initial code: Steve Sakoman <steve@sakoman.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ASM_ARCH_OVERO_H
-#define __ASM_ARCH_OVERO_H
-
-#define OVERO_GPIO_BT_XGATE 15
-#define OVERO_GPIO_W2W_NRESET 16
-#define OVERO_GPIO_BT_NRESET 164
-#define OVERO_GPIO_USBH_CPEN 168
-#define OVERO_GPIO_USBH_NRESET 183
-
-#endif /* ____ASM_ARCH_OVERO_H */
-
diff --git a/arch/arm/plat-omap/include/mach/board-palmte.h b/arch/arm/plat-omap/include/mach/board-palmte.h
deleted file mode 100644
index 6906cdebbcfb..000000000000
--- a/arch/arm/plat-omap/include/mach/board-palmte.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-palmte.h
- *
- * Hardware definitions for the Palm Tungsten E device.
- *
- * Maintainters : http://palmtelinux.sf.net
- * palmtelinux-developpers@lists.sf.net
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __OMAP_BOARD_PALMTE_H
-#define __OMAP_BOARD_PALMTE_H
-
-#define PALMTE_USBDETECT_GPIO 0
-#define PALMTE_USB_OR_DC_GPIO 1
-#define PALMTE_TSC_GPIO 4
-#define PALMTE_PINTDAV_GPIO 6
-#define PALMTE_MMC_WP_GPIO 8
-#define PALMTE_MMC_POWER_GPIO 9
-#define PALMTE_HDQ_GPIO 11
-#define PALMTE_HEADPHONES_GPIO 14
-#define PALMTE_SPEAKER_GPIO 15
-#define PALMTE_DC_GPIO OMAP_MPUIO(2)
-#define PALMTE_MMC_SWITCH_GPIO OMAP_MPUIO(4)
-#define PALMTE_MMC1_GPIO OMAP_MPUIO(6)
-#define PALMTE_MMC2_GPIO OMAP_MPUIO(7)
-#define PALMTE_MMC3_GPIO OMAP_MPUIO(11)
-
-#endif /* __OMAP_BOARD_PALMTE_H */
diff --git a/arch/arm/plat-omap/include/mach/board-palmtt.h b/arch/arm/plat-omap/include/mach/board-palmtt.h
deleted file mode 100644
index e79f382b5931..000000000000
--- a/arch/arm/plat-omap/include/mach/board-palmtt.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-palmte.h
- *
- * Hardware definitions for the Palm Tungsten|T device.
- *
- * Maintainters : Marek Vasut <marek.vasut@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __OMAP_BOARD_PALMTT_H
-#define __OMAP_BOARD_PALMTT_H
-
-#define PALMTT_USBDETECT_GPIO 0
-#define PALMTT_CABLE_GPIO 1
-#define PALMTT_LED_GPIO 3
-#define PALMTT_PENIRQ_GPIO 6
-#define PALMTT_MMC_WP_GPIO 8
-#define PALMTT_HDQ_GPIO 11
-
-#endif /* __OMAP_BOARD_PALMTT_H */
diff --git a/arch/arm/plat-omap/include/mach/board-palmz71.h b/arch/arm/plat-omap/include/mach/board-palmz71.h
deleted file mode 100644
index b1d7d579b313..000000000000
--- a/arch/arm/plat-omap/include/mach/board-palmz71.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-palmz71.h
- *
- * Hardware definitions for the Palm Zire71 device.
- *
- * Maintainters : Marek Vasut <marek.vasut@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __OMAP_BOARD_PALMZ71_H
-#define __OMAP_BOARD_PALMZ71_H
-
-#define PALMZ71_USBDETECT_GPIO 0
-#define PALMZ71_PENIRQ_GPIO 6
-#define PALMZ71_MMC_WP_GPIO 8
-#define PALMZ71_HDQ_GPIO 11
-
-#define PALMZ71_HOTSYNC_GPIO OMAP_MPUIO(1)
-#define PALMZ71_CABLE_GPIO OMAP_MPUIO(2)
-#define PALMZ71_SLIDER_GPIO OMAP_MPUIO(3)
-#define PALMZ71_MMC_IN_GPIO OMAP_MPUIO(4)
-
-#endif /* __OMAP_BOARD_PALMZ71_H */
diff --git a/arch/arm/plat-omap/include/mach/board-perseus2.h b/arch/arm/plat-omap/include/mach/board-perseus2.h
deleted file mode 100644
index c06c3d717d57..000000000000
--- a/arch/arm/plat-omap/include/mach/board-perseus2.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * arch/arm/plat-omap/include/mach/board-perseus2.h
- *
- * Copyright 2003 by Texas Instruments Incorporated
- * OMAP730 / Perseus2 support by Jean Pihet
- *
- * Copyright (C) 2001 RidgeRun, Inc. (http://www.ridgerun.com)
- * Author: RidgeRun, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-#ifndef __ASM_ARCH_OMAP_PERSEUS2_H
-#define __ASM_ARCH_OMAP_PERSEUS2_H
-
-#include <mach/fpga.h>
-
-#ifndef OMAP_SDRAM_DEVICE
-#define OMAP_SDRAM_DEVICE D256M_1X16_4B
-#endif
-
-#endif
diff --git a/arch/arm/plat-omap/include/mach/board-voiceblue.h b/arch/arm/plat-omap/include/mach/board-voiceblue.h
index ed6d346ee123..27916b210f57 100644
--- a/arch/arm/plat-omap/include/mach/board-voiceblue.h
+++ b/arch/arm/plat-omap/include/mach/board-voiceblue.h
@@ -14,7 +14,6 @@
extern void voiceblue_wdt_enable(void);
extern void voiceblue_wdt_disable(void);
extern void voiceblue_wdt_ping(void);
-extern void voiceblue_reset(void);
#endif /* __ASM_ARCH_VOICEBLUE_H */
diff --git a/arch/arm/plat-omap/include/mach/board.h b/arch/arm/plat-omap/include/mach/board.h
index 9466772fc7c8..50ea79a0efa2 100644
--- a/arch/arm/plat-omap/include/mach/board.h
+++ b/arch/arm/plat-omap/include/mach/board.h
@@ -17,7 +17,6 @@
/* Different peripheral ids */
#define OMAP_TAG_CLOCK 0x4f01
#define OMAP_TAG_SERIAL_CONSOLE 0x4f03
-#define OMAP_TAG_USB 0x4f04
#define OMAP_TAG_LCD 0x4f05
#define OMAP_TAG_GPIO_SWITCH 0x4f06
#define OMAP_TAG_UART 0x4f07
@@ -133,9 +132,6 @@ struct omap_version_config {
char version[12];
};
-
-#include <mach/board-nokia.h>
-
struct omap_board_config_entry {
u16 tag;
u16 len;
diff --git a/arch/arm/plat-omap/include/mach/clkdev.h b/arch/arm/plat-omap/include/mach/clkdev.h
new file mode 100644
index 000000000000..730c49d1ebd8
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/clkdev.h
@@ -0,0 +1,13 @@
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+static inline int __clk_get(struct clk *clk)
+{
+ return 1;
+}
+
+static inline void __clk_put(struct clk *clk)
+{
+}
+
+#endif
diff --git a/arch/arm/plat-omap/include/mach/clock.h b/arch/arm/plat-omap/include/mach/clock.h
index 719298554ed7..073a2c5569f0 100644
--- a/arch/arm/plat-omap/include/mach/clock.h
+++ b/arch/arm/plat-omap/include/mach/clock.h
@@ -17,11 +17,16 @@ struct module;
struct clk;
struct clockdomain;
+struct clkops {
+ int (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+};
+
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
struct clksel_rate {
- u8 div;
u32 val;
+ u8 div;
u8 flags;
};
@@ -34,24 +39,28 @@ struct dpll_data {
void __iomem *mult_div1_reg;
u32 mult_mask;
u32 div1_mask;
+ struct clk *clk_bypass;
+ struct clk *clk_ref;
+ void __iomem *control_reg;
+ u32 enable_mask;
+ unsigned int rate_tolerance;
+ unsigned long last_rounded_rate;
u16 last_rounded_m;
u8 last_rounded_n;
- unsigned long last_rounded_rate;
- unsigned int rate_tolerance;
- u16 max_multiplier;
+ u8 min_divider;
u8 max_divider;
u32 max_tolerance;
+ u16 max_multiplier;
# if defined(CONFIG_ARCH_OMAP3)
u8 modes;
- void __iomem *control_reg;
- u32 enable_mask;
+ void __iomem *autoidle_reg;
+ void __iomem *idlest_reg;
+ u32 autoidle_mask;
+ u32 freqsel_mask;
+ u32 idlest_mask;
u8 auto_recal_bit;
u8 recal_en_bit;
u8 recal_st_bit;
- void __iomem *autoidle_reg;
- u32 autoidle_mask;
- void __iomem *idlest_reg;
- u8 idlest_bit;
# endif
};
@@ -59,21 +68,21 @@ struct dpll_data {
struct clk {
struct list_head node;
- struct module *owner;
+ const struct clkops *ops;
const char *name;
int id;
struct clk *parent;
+ struct list_head children;
+ struct list_head sibling; /* node for children */
unsigned long rate;
__u32 flags;
void __iomem *enable_reg;
- __u8 enable_bit;
- __s8 usecount;
- void (*recalc)(struct clk *);
+ unsigned long (*recalc)(struct clk *);
int (*set_rate)(struct clk *, unsigned long);
long (*round_rate)(struct clk *, unsigned long);
void (*init)(struct clk *);
- int (*enable)(struct clk *);
- void (*disable)(struct clk *);
+ __u8 enable_bit;
+ __s8 usecount;
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
u8 fixed_div;
void __iomem *clksel_reg;
@@ -99,7 +108,6 @@ struct clk_functions {
long (*clk_round_rate)(struct clk *clk, unsigned long rate);
int (*clk_set_rate)(struct clk *clk, unsigned long rate);
int (*clk_set_parent)(struct clk *clk, struct clk *parent);
- struct clk * (*clk_get_parent)(struct clk *clk);
void (*clk_allow_idle)(struct clk *clk);
void (*clk_deny_idle)(struct clk *clk);
void (*clk_disable_unused)(struct clk *clk);
@@ -110,42 +118,33 @@ struct clk_functions {
extern unsigned int mpurate;
-extern int clk_init(struct clk_functions * custom_clocks);
+extern int clk_init(struct clk_functions *custom_clocks);
+extern void clk_init_one(struct clk *clk);
extern int clk_register(struct clk *clk);
+extern void clk_reparent(struct clk *child, struct clk *parent);
extern void clk_unregister(struct clk *clk);
extern void propagate_rate(struct clk *clk);
extern void recalculate_root_clocks(void);
-extern void followparent_recalc(struct clk * clk);
-extern void clk_allow_idle(struct clk *clk);
-extern void clk_deny_idle(struct clk *clk);
-extern int clk_get_usecount(struct clk *clk);
+extern unsigned long followparent_recalc(struct clk *clk);
extern void clk_enable_init_clocks(void);
+#ifdef CONFIG_CPU_FREQ
+extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
+#endif
+
+extern const struct clkops clkops_null;
/* Clock flags */
-#define RATE_CKCTL (1 << 0) /* Main fixed ratio clocks */
+/* bit 0 is free */
#define RATE_FIXED (1 << 1) /* Fixed clock rate */
-#define RATE_PROPAGATES (1 << 2) /* Program children too */
-#define VIRTUAL_CLOCK (1 << 3) /* Composite clock from table */
-#define ALWAYS_ENABLED (1 << 4) /* Clock cannot be disabled */
+/* bits 2-4 are free */
#define ENABLE_REG_32BIT (1 << 5) /* Use 32-bit access */
-#define VIRTUAL_IO_ADDRESS (1 << 6) /* Clock in virtual address */
#define CLOCK_IDLE_CONTROL (1 << 7)
#define CLOCK_NO_IDLE_PARENT (1 << 8)
#define DELAYED_APP (1 << 9) /* Delay application of clock */
#define CONFIG_PARTICIPANT (1 << 10) /* Fundamental clock */
#define ENABLE_ON_INIT (1 << 11) /* Enable upon framework init */
#define INVERT_ENABLE (1 << 12) /* 0 enables, 1 disables */
-/* bits 13-20 are currently free */
-#define CLOCK_IN_OMAP310 (1 << 21)
-#define CLOCK_IN_OMAP730 (1 << 22)
-#define CLOCK_IN_OMAP1510 (1 << 23)
-#define CLOCK_IN_OMAP16XX (1 << 24)
-#define CLOCK_IN_OMAP242X (1 << 25)
-#define CLOCK_IN_OMAP243X (1 << 26)
-#define CLOCK_IN_OMAP343X (1 << 27) /* clocks common to all 343X */
-#define PARENT_CONTROLS_CLOCK (1 << 28)
-#define CLOCK_IN_OMAP3430ES1 (1 << 29) /* 3430ES1 clocks only */
-#define CLOCK_IN_OMAP3430ES2 (1 << 30) /* 3430ES2 clocks only */
+/* bits 13-31 are currently free */
/* Clksel_rate flags */
#define DEFAULT_RATE (1 << 0)
@@ -157,9 +156,4 @@ extern void clk_enable_init_clocks(void);
#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
-/* CM_CLKSEL2_PLL.CORE_CLK_SRC options (24XX) */
-#define CORE_CLK_SRC_32K 0
-#define CORE_CLK_SRC_DPLL 1
-#define CORE_CLK_SRC_DPLL_X2 2
-
#endif
diff --git a/arch/arm/plat-omap/include/mach/clockdomain.h b/arch/arm/plat-omap/include/mach/clockdomain.h
index 1f51f0173784..b9d0dd2da89b 100644
--- a/arch/arm/plat-omap/include/mach/clockdomain.h
+++ b/arch/arm/plat-omap/include/mach/clockdomain.h
@@ -1,5 +1,5 @@
/*
- * linux/include/asm-arm/arch-omap/clockdomain.h
+ * arch/arm/plat-omap/include/mach/clockdomain.h
*
* OMAP2/3 clockdomain framework functions
*
@@ -48,11 +48,13 @@
*/
struct clkdm_pwrdm_autodep {
- /* Name of the powerdomain to add a wkdep/sleepdep on */
- const char *pwrdm_name;
+ union {
+ /* Name of the powerdomain to add a wkdep/sleepdep on */
+ const char *name;
- /* Powerdomain pointer (looked up at clkdm_init() time) */
- struct powerdomain *pwrdm;
+ /* Powerdomain pointer (looked up at clkdm_init() time) */
+ struct powerdomain *ptr;
+ } pwrdm;
/* OMAP chip types that this clockdomain dep is valid on */
const struct omap_chip_id omap_chip;
@@ -64,8 +66,13 @@ struct clockdomain {
/* Clockdomain name */
const char *name;
- /* Powerdomain enclosing this clockdomain */
- const char *pwrdm_name;
+ union {
+ /* Powerdomain enclosing this clockdomain */
+ const char *name;
+
+ /* Powerdomain pointer assigned at clkdm_register() */
+ struct powerdomain *ptr;
+ } pwrdm;
/* CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg */
const u16 clktrctrl_mask;
@@ -79,9 +86,6 @@ struct clockdomain {
/* Usecount tracking */
atomic_t usecount;
- /* Powerdomain pointer assigned at clkdm_register() */
- struct powerdomain *pwrdm;
-
struct list_head node;
};
diff --git a/arch/arm/plat-omap/include/mach/common.h b/arch/arm/plat-omap/include/mach/common.h
index e746ec7e785e..0ecf36deb17b 100644
--- a/arch/arm/plat-omap/include/mach/common.h
+++ b/arch/arm/plat-omap/include/mach/common.h
@@ -65,7 +65,7 @@ void omap2_set_globals_343x(void);
/* These get called from omap2_set_globals_xxxx(), do not call these */
void omap2_set_globals_tap(struct omap_globals *);
-void omap2_set_globals_memory(struct omap_globals *);
+void omap2_set_globals_sdrc(struct omap_globals *);
void omap2_set_globals_control(struct omap_globals *);
void omap2_set_globals_prcm(struct omap_globals *);
diff --git a/arch/arm/plat-omap/include/mach/cpu.h b/arch/arm/plat-omap/include/mach/cpu.h
index a8e1178a9468..98b144252364 100644
--- a/arch/arm/plat-omap/include/mach/cpu.h
+++ b/arch/arm/plat-omap/include/mach/cpu.h
@@ -56,6 +56,14 @@ unsigned int omap_rev(void);
# define OMAP_NAME omap730
# endif
#endif
+#ifdef CONFIG_ARCH_OMAP850
+# ifdef OMAP_NAME
+# undef MULTI_OMAP1
+# define MULTI_OMAP1
+# else
+# define OMAP_NAME omap850
+# endif
+#endif
#ifdef CONFIG_ARCH_OMAP15XX
# ifdef OMAP_NAME
# undef MULTI_OMAP1
@@ -105,7 +113,7 @@ unsigned int omap_rev(void);
/*
* Macros to group OMAP into cpu classes.
* These can be used in most places.
- * cpu_is_omap7xx(): True for OMAP730
+ * cpu_is_omap7xx(): True for OMAP730, OMAP850
* cpu_is_omap15xx(): True for OMAP1510, OMAP5910 and OMAP310
* cpu_is_omap16xx(): True for OMAP1610, OMAP5912 and OMAP1710
* cpu_is_omap24xx(): True for OMAP2420, OMAP2422, OMAP2423, OMAP2430
@@ -153,6 +161,10 @@ IS_OMAP_SUBCLASS(343x, 0x343)
# undef cpu_is_omap7xx
# define cpu_is_omap7xx() is_omap7xx()
# endif
+# if defined(CONFIG_ARCH_OMAP850)
+# undef cpu_is_omap7xx
+# define cpu_is_omap7xx() is_omap7xx()
+# endif
# if defined(CONFIG_ARCH_OMAP15XX)
# undef cpu_is_omap15xx
# define cpu_is_omap15xx() is_omap15xx()
@@ -166,6 +178,10 @@ IS_OMAP_SUBCLASS(343x, 0x343)
# undef cpu_is_omap7xx
# define cpu_is_omap7xx() 1
# endif
+# if defined(CONFIG_ARCH_OMAP850)
+# undef cpu_is_omap7xx
+# define cpu_is_omap7xx() 1
+# endif
# if defined(CONFIG_ARCH_OMAP15XX)
# undef cpu_is_omap15xx
# define cpu_is_omap15xx() 1
@@ -219,6 +235,7 @@ IS_OMAP_SUBCLASS(343x, 0x343)
* These are only rarely needed.
* cpu_is_omap330(): True for OMAP330
* cpu_is_omap730(): True for OMAP730
+ * cpu_is_omap850(): True for OMAP850
* cpu_is_omap1510(): True for OMAP1510
* cpu_is_omap1610(): True for OMAP1610
* cpu_is_omap1611(): True for OMAP1611
@@ -241,6 +258,7 @@ static inline int is_omap ##type (void) \
IS_OMAP_TYPE(310, 0x0310)
IS_OMAP_TYPE(730, 0x0730)
+IS_OMAP_TYPE(850, 0x0850)
IS_OMAP_TYPE(1510, 0x1510)
IS_OMAP_TYPE(1610, 0x1610)
IS_OMAP_TYPE(1611, 0x1611)
@@ -255,6 +273,7 @@ IS_OMAP_TYPE(3430, 0x3430)
#define cpu_is_omap310() 0
#define cpu_is_omap730() 0
+#define cpu_is_omap850() 0
#define cpu_is_omap1510() 0
#define cpu_is_omap1610() 0
#define cpu_is_omap5912() 0
@@ -272,12 +291,22 @@ IS_OMAP_TYPE(3430, 0x3430)
# undef cpu_is_omap730
# define cpu_is_omap730() is_omap730()
# endif
+# if defined(CONFIG_ARCH_OMAP850)
+# undef cpu_is_omap850
+# define cpu_is_omap850() is_omap850()
+# endif
#else
# if defined(CONFIG_ARCH_OMAP730)
# undef cpu_is_omap730
# define cpu_is_omap730() 1
# endif
#endif
+#else
+# if defined(CONFIG_ARCH_OMAP850)
+# undef cpu_is_omap850
+# define cpu_is_omap850() 1
+# endif
+#endif
/*
* Whether we have MULTI_OMAP1 or not, we still need to distinguish
@@ -320,7 +349,7 @@ IS_OMAP_TYPE(3430, 0x3430)
#endif
/* Macros to detect if we have OMAP1 or OMAP2 */
-#define cpu_class_is_omap1() (cpu_is_omap730() || cpu_is_omap15xx() || \
+#define cpu_class_is_omap1() (cpu_is_omap7xx() || cpu_is_omap15xx() || \
cpu_is_omap16xx())
#define cpu_class_is_omap2() (cpu_is_omap24xx() || cpu_is_omap34xx())
@@ -355,13 +384,27 @@ IS_OMAP_TYPE(3430, 0x3430)
* use omap_chip_is().
*
*/
-#define CHIP_IS_OMAP2420 (1 << 0)
-#define CHIP_IS_OMAP2430 (1 << 1)
-#define CHIP_IS_OMAP3430 (1 << 2)
-#define CHIP_IS_OMAP3430ES1 (1 << 3)
-#define CHIP_IS_OMAP3430ES2 (1 << 4)
+#define CHIP_IS_OMAP2420 (1 << 0)
+#define CHIP_IS_OMAP2430 (1 << 1)
+#define CHIP_IS_OMAP3430 (1 << 2)
+#define CHIP_IS_OMAP3430ES1 (1 << 3)
+#define CHIP_IS_OMAP3430ES2 (1 << 4)
+#define CHIP_IS_OMAP3430ES3_0 (1 << 5)
+#define CHIP_IS_OMAP3430ES3_1 (1 << 6)
+
+#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
+
+/*
+ * "GE" here represents "greater than or equal to" in terms of ES
+ * levels. So CHIP_GE_OMAP3430ES2 is intended to match all OMAP3430
+ * chips at ES2 and beyond, but not, for example, any OMAP lines after
+ * OMAP3.
+ */
+#define CHIP_GE_OMAP3430ES2 (CHIP_IS_OMAP3430ES2 | \
+ CHIP_IS_OMAP3430ES3_0 | \
+ CHIP_IS_OMAP3430ES3_1)
+#define CHIP_GE_OMAP3430ES3_1 (CHIP_IS_OMAP3430ES3_1)
-#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
int omap_chip_is(struct omap_chip_id oci);
int omap_type(void);
@@ -378,5 +421,3 @@ int omap_type(void);
void omap2_check_revision(void);
#endif /* defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) */
-
-#endif
diff --git a/arch/arm/plat-omap/include/mach/gpio.h b/arch/arm/plat-omap/include/mach/gpio.h
index 8d9dfe314387..2b22a8799bc6 100644
--- a/arch/arm/plat-omap/include/mach/gpio.h
+++ b/arch/arm/plat-omap/include/mach/gpio.h
@@ -31,7 +31,8 @@
#define OMAP_MPUIO_BASE 0xfffb5000
-#ifdef CONFIG_ARCH_OMAP730
+#if (defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850))
+
#define OMAP_MPUIO_INPUT_LATCH 0x00
#define OMAP_MPUIO_OUTPUT 0x02
#define OMAP_MPUIO_IO_CNTL 0x04
diff --git a/arch/arm/plat-omap/include/mach/gpmc.h b/arch/arm/plat-omap/include/mach/gpmc.h
index 45b678439bb7..921b16532ff5 100644
--- a/arch/arm/plat-omap/include/mach/gpmc.h
+++ b/arch/arm/plat-omap/include/mach/gpmc.h
@@ -103,6 +103,6 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
extern void gpmc_cs_free(int cs);
extern int gpmc_cs_set_reserved(int cs, int reserved);
extern int gpmc_cs_reserved(int cs);
-extern void gpmc_init(void);
+extern void __init gpmc_init(void);
#endif
diff --git a/arch/arm/plat-omap/include/mach/hardware.h b/arch/arm/plat-omap/include/mach/hardware.h
index 6589ddbb63b2..3dc423ed3e80 100644
--- a/arch/arm/plat-omap/include/mach/hardware.h
+++ b/arch/arm/plat-omap/include/mach/hardware.h
@@ -286,78 +286,4 @@
#include "omap24xx.h"
#include "omap34xx.h"
-#ifndef __ASSEMBLER__
-
-/*
- * ---------------------------------------------------------------------------
- * Board specific defines
- * ---------------------------------------------------------------------------
- */
-
-#ifdef CONFIG_MACH_OMAP_INNOVATOR
-#include "board-innovator.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_H2
-#include "board-h2.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_PERSEUS2
-#include "board-perseus2.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_FSAMPLE
-#include "board-fsample.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_H3
-#include "board-h3.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_H4
-#include "board-h4.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_2430SDP
-#include "board-2430sdp.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP3_BEAGLE
-#include "board-omap3beagle.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_LDP
-#include "board-ldp.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_APOLLON
-#include "board-apollon.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_OSK
-#include "board-osk.h"
-#endif
-
-#ifdef CONFIG_MACH_VOICEBLUE
-#include "board-voiceblue.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_PALMTE
-#include "board-palmte.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_PALMZ71
-#include "board-palmz71.h"
-#endif
-
-#ifdef CONFIG_MACH_OMAP_PALMTT
-#include "board-palmtt.h"
-#endif
-
-#ifdef CONFIG_MACH_SX1
-#include "board-sx1.h"
-#endif
-
-#endif /* !__ASSEMBLER__ */
-
#endif /* __ASM_ARCH_OMAP_HARDWARE_H */
diff --git a/arch/arm/plat-omap/include/mach/io.h b/arch/arm/plat-omap/include/mach/io.h
index d92bf7964481..0610d7e2b3d7 100644
--- a/arch/arm/plat-omap/include/mach/io.h
+++ b/arch/arm/plat-omap/include/mach/io.h
@@ -185,11 +185,13 @@
#define omap_writew(v,a) __raw_writew(v, IO_ADDRESS(a))
#define omap_writel(v,a) __raw_writel(v, IO_ADDRESS(a))
+struct omap_sdrc_params;
+
extern void omap1_map_common_io(void);
extern void omap1_init_common_hw(void);
extern void omap2_map_common_io(void);
-extern void omap2_init_common_hw(void);
+extern void omap2_init_common_hw(struct omap_sdrc_params *sp);
#define __arch_ioremap(p,s,t) omap_ioremap(p,s,t)
#define __arch_iounmap(v) omap_iounmap(v)
diff --git a/arch/arm/plat-omap/include/mach/irqs.h b/arch/arm/plat-omap/include/mach/irqs.h
index bed5274c910a..7f57ee66f364 100644
--- a/arch/arm/plat-omap/include/mach/irqs.h
+++ b/arch/arm/plat-omap/include/mach/irqs.h
@@ -105,6 +105,29 @@
#define INT_730_SPGIO_WR 29
/*
+ * OMAP-850 specific IRQ numbers for interrupt handler 1
+ */
+#define INT_850_IH2_FIQ 0
+#define INT_850_IH2_IRQ 1
+#define INT_850_USB_NON_ISO 2
+#define INT_850_USB_ISO 3
+#define INT_850_ICR 4
+#define INT_850_EAC 5
+#define INT_850_GPIO_BANK1 6
+#define INT_850_GPIO_BANK2 7
+#define INT_850_GPIO_BANK3 8
+#define INT_850_McBSP2TX 10
+#define INT_850_McBSP2RX 11
+#define INT_850_McBSP2RX_OVF 12
+#define INT_850_LCD_LINE 14
+#define INT_850_GSM_PROTECT 15
+#define INT_850_TIMER3 16
+#define INT_850_GPIO_BANK5 17
+#define INT_850_GPIO_BANK6 18
+#define INT_850_SPGIO_WR 29
+
+
+/*
* IRQ numbers for interrupt handler 2
*
* NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
@@ -237,6 +260,64 @@
#define INT_730_DMA_CH15 (62 + IH2_BASE)
#define INT_730_NAND (63 + IH2_BASE)
+/*
+ * OMAP-850 specific IRQ numbers for interrupt handler 2
+ */
+#define INT_850_HW_ERRORS (0 + IH2_BASE)
+#define INT_850_NFIQ_PWR_FAIL (1 + IH2_BASE)
+#define INT_850_CFCD (2 + IH2_BASE)
+#define INT_850_CFIREQ (3 + IH2_BASE)
+#define INT_850_I2C (4 + IH2_BASE)
+#define INT_850_PCC (5 + IH2_BASE)
+#define INT_850_MPU_EXT_NIRQ (6 + IH2_BASE)
+#define INT_850_SPI_100K_1 (7 + IH2_BASE)
+#define INT_850_SYREN_SPI (8 + IH2_BASE)
+#define INT_850_VLYNQ (9 + IH2_BASE)
+#define INT_850_GPIO_BANK4 (10 + IH2_BASE)
+#define INT_850_McBSP1TX (11 + IH2_BASE)
+#define INT_850_McBSP1RX (12 + IH2_BASE)
+#define INT_850_McBSP1RX_OF (13 + IH2_BASE)
+#define INT_850_UART_MODEM_IRDA_2 (14 + IH2_BASE)
+#define INT_850_UART_MODEM_1 (15 + IH2_BASE)
+#define INT_850_MCSI (16 + IH2_BASE)
+#define INT_850_uWireTX (17 + IH2_BASE)
+#define INT_850_uWireRX (18 + IH2_BASE)
+#define INT_850_SMC_CD (19 + IH2_BASE)
+#define INT_850_SMC_IREQ (20 + IH2_BASE)
+#define INT_850_HDQ_1WIRE (21 + IH2_BASE)
+#define INT_850_TIMER32K (22 + IH2_BASE)
+#define INT_850_MMC_SDIO (23 + IH2_BASE)
+#define INT_850_UPLD (24 + IH2_BASE)
+#define INT_850_USB_HHC_1 (27 + IH2_BASE)
+#define INT_850_USB_HHC_2 (28 + IH2_BASE)
+#define INT_850_USB_GENI (29 + IH2_BASE)
+#define INT_850_USB_OTG (30 + IH2_BASE)
+#define INT_850_CAMERA_IF (31 + IH2_BASE)
+#define INT_850_RNG (32 + IH2_BASE)
+#define INT_850_DUAL_MODE_TIMER (33 + IH2_BASE)
+#define INT_850_DBB_RF_EN (34 + IH2_BASE)
+#define INT_850_MPUIO_KEYPAD (35 + IH2_BASE)
+#define INT_850_SHA1_MD5 (36 + IH2_BASE)
+#define INT_850_SPI_100K_2 (37 + IH2_BASE)
+#define INT_850_RNG_IDLE (38 + IH2_BASE)
+#define INT_850_MPUIO (39 + IH2_BASE)
+#define INT_850_LLPC_LCD_CTRL_CAN_BE_OFF (40 + IH2_BASE)
+#define INT_850_LLPC_OE_FALLING (41 + IH2_BASE)
+#define INT_850_LLPC_OE_RISING (42 + IH2_BASE)
+#define INT_850_LLPC_VSYNC (43 + IH2_BASE)
+#define INT_850_WAKE_UP_REQ (46 + IH2_BASE)
+#define INT_850_DMA_CH6 (53 + IH2_BASE)
+#define INT_850_DMA_CH7 (54 + IH2_BASE)
+#define INT_850_DMA_CH8 (55 + IH2_BASE)
+#define INT_850_DMA_CH9 (56 + IH2_BASE)
+#define INT_850_DMA_CH10 (57 + IH2_BASE)
+#define INT_850_DMA_CH11 (58 + IH2_BASE)
+#define INT_850_DMA_CH12 (59 + IH2_BASE)
+#define INT_850_DMA_CH13 (60 + IH2_BASE)
+#define INT_850_DMA_CH14 (61 + IH2_BASE)
+#define INT_850_DMA_CH15 (62 + IH2_BASE)
+#define INT_850_NAND (63 + IH2_BASE)
+
#define INT_24XX_SYS_NIRQ 7
#define INT_24XX_SDMA_IRQ0 12
#define INT_24XX_SDMA_IRQ1 13
@@ -341,7 +422,7 @@
#define INT_34XX_BENCH_MPU_EMUL 3
-/* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730) and
+/* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and
* 16 MPUIO lines */
#define OMAP_MAX_GPIO_LINES 192
#define IH_GPIO_BASE (128 + IH2_BASE)
diff --git a/arch/arm/plat-omap/include/mach/mailbox.h b/arch/arm/plat-omap/include/mach/mailbox.h
index 7cbed9332e16..b7a6991814ec 100644
--- a/arch/arm/plat-omap/include/mach/mailbox.h
+++ b/arch/arm/plat-omap/include/mach/mailbox.h
@@ -33,6 +33,9 @@ struct omap_mbox_ops {
void (*disable_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
void (*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
int (*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
+ /* ctx */
+ void (*save_ctx)(struct omap_mbox *mbox);
+ void (*restore_ctx)(struct omap_mbox *mbox);
};
struct omap_mbox_queue {
@@ -53,7 +56,7 @@ struct omap_mbox {
mbox_msg_t seq_snd, seq_rcv;
- struct device dev;
+ struct device *dev;
struct omap_mbox *next;
void *priv;
@@ -67,7 +70,27 @@ void omap_mbox_init_seq(struct omap_mbox *);
struct omap_mbox *omap_mbox_get(const char *);
void omap_mbox_put(struct omap_mbox *);
-int omap_mbox_register(struct omap_mbox *);
+int omap_mbox_register(struct device *parent, struct omap_mbox *);
int omap_mbox_unregister(struct omap_mbox *);
+static inline void omap_mbox_save_ctx(struct omap_mbox *mbox)
+{
+ if (!mbox->ops->save_ctx) {
+ dev_err(mbox->dev, "%s:\tno save\n", __func__);
+ return;
+ }
+
+ mbox->ops->save_ctx(mbox);
+}
+
+static inline void omap_mbox_restore_ctx(struct omap_mbox *mbox)
+{
+ if (!mbox->ops->restore_ctx) {
+ dev_err(mbox->dev, "%s:\tno restore\n", __func__);
+ return;
+ }
+
+ mbox->ops->restore_ctx(mbox);
+}
+
#endif /* MAILBOX_H */
diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h
index 113c2466c86a..bb154ea76769 100644
--- a/arch/arm/plat-omap/include/mach/mcbsp.h
+++ b/arch/arm/plat-omap/include/mach/mcbsp.h
@@ -344,8 +344,6 @@ struct omap_mcbsp_platform_data {
u8 dma_rx_sync, dma_tx_sync;
u16 rx_irq, tx_irq;
struct omap_mcbsp_ops *ops;
- char const **clk_names;
- int num_clks;
};
struct omap_mcbsp {
@@ -377,8 +375,8 @@ struct omap_mcbsp {
/* Protect the field .free, while checking if the mcbsp is in use */
spinlock_t lock;
struct omap_mcbsp_platform_data *pdata;
- struct clk **clks;
- int num_clks;
+ struct clk *iclk;
+ struct clk *fclk;
};
extern struct omap_mcbsp **mcbsp_ptr;
extern int omap_mcbsp_count;
diff --git a/arch/arm/plat-omap/include/mach/memory.h b/arch/arm/plat-omap/include/mach/memory.h
index d6b5ca6c7da2..99ed564d9277 100644
--- a/arch/arm/plat-omap/include/mach/memory.h
+++ b/arch/arm/plat-omap/include/mach/memory.h
@@ -61,9 +61,11 @@
#define lbus_to_virt(x) ((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET)
#define is_lbus_device(dev) (cpu_is_omap15xx() && dev && (strncmp(dev_name(dev), "ohci", 4) == 0))
-#define __arch_page_to_dma(dev, page) ({is_lbus_device(dev) ? \
- (dma_addr_t)virt_to_lbus(page_address(page)) : \
- (dma_addr_t)__virt_to_phys(page_address(page));})
+#define __arch_page_to_dma(dev, page) \
+ ({ dma_addr_t __dma = page_to_phys(page); \
+ if (is_lbus_device(dev)) \
+ __dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \
+ __dma; })
#define __arch_dma_to_virt(dev, addr) ({ (void *) (is_lbus_device(dev) ? \
lbus_to_virt(addr) : \
diff --git a/arch/arm/plat-omap/include/mach/mmc.h b/arch/arm/plat-omap/include/mach/mmc.h
index 73a9e15031b1..4435bd434e17 100644
--- a/arch/arm/plat-omap/include/mach/mmc.h
+++ b/arch/arm/plat-omap/include/mach/mmc.h
@@ -37,6 +37,8 @@
#define OMAP_MMC_MAX_SLOTS 2
struct omap_mmc_platform_data {
+ /* back-link to device */
+ struct device *dev;
/* number of slots per controller */
unsigned nr_slots:2;
diff --git a/arch/arm/plat-omap/include/mach/mux.h b/arch/arm/plat-omap/include/mach/mux.h
index f4362b8682c7..85a621705766 100644
--- a/arch/arm/plat-omap/include/mach/mux.h
+++ b/arch/arm/plat-omap/include/mach/mux.h
@@ -61,6 +61,16 @@
.pull_bit = bit, \
.pull_val = status,
+#define MUX_REG_850(reg, mode_offset, mode) .mux_reg_name = "OMAP850_IO_CONF_"#reg, \
+ .mux_reg = OMAP850_IO_CONF_##reg, \
+ .mask_offset = mode_offset, \
+ .mask = mode,
+
+#define PULL_REG_850(reg, bit, status) .pull_name = "OMAP850_IO_CONF_"#reg, \
+ .pull_reg = OMAP850_IO_CONF_##reg, \
+ .pull_bit = bit, \
+ .pull_val = status,
+
#else
#define MUX_REG(reg, mode_offset, mode) .mux_reg = FUNC_MUX_CTRL_##reg, \
@@ -83,6 +93,15 @@
.pull_bit = bit, \
.pull_val = status,
+#define MUX_REG_850(reg, mode_offset, mode) \
+ .mux_reg = OMAP850_IO_CONF_##reg, \
+ .mask_offset = mode_offset, \
+ .mask = mode,
+
+#define PULL_REG_850(reg, bit, status) .pull_reg = OMAP850_IO_CONF_##reg, \
+ .pull_bit = bit, \
+ .pull_val = status,
+
#endif /* CONFIG_OMAP_MUX_DEBUG */
#define MUX_CFG(desc, mux_reg, mode_offset, mode, \
@@ -98,7 +117,7 @@
/*
- * OMAP730 has a slightly different config for the pin mux.
+ * OMAP730/850 has a slightly different config for the pin mux.
* - config regs are the OMAP730_IO_CONF_x regs (see omap730.h) regs and
* not the FUNC_MUX_CTRL_x regs from hardware.h
* - for pull-up/down, only has one enable bit which is is in the same register
@@ -114,6 +133,17 @@
PU_PD_REG(NA, 0) \
},
+#define MUX_CFG_850(desc, mux_reg, mode_offset, mode, \
+ pull_bit, pull_status, debug_status)\
+{ \
+ .name = desc, \
+ .debug = debug_status, \
+ MUX_REG_850(mux_reg, mode_offset, mode) \
+ PULL_REG_850(mux_reg, pull_bit, pull_status) \
+ PU_PD_REG(NA, 0) \
+},
+
+
#define MUX_CFG_24XX(desc, reg_offset, mode, \
pull_en, pull_mode, dbg) \
{ \
@@ -221,6 +251,26 @@ enum omap730_index {
W17_730_USB_VBUSI,
};
+enum omap850_index {
+ /* OMAP 850 keyboard */
+ E2_850_KBR0,
+ J7_850_KBR1,
+ E1_850_KBR2,
+ F3_850_KBR3,
+ D2_850_KBR4,
+ C2_850_KBC0,
+ D3_850_KBC1,
+ E4_850_KBC2,
+ F4_850_KBC3,
+ E3_850_KBC4,
+
+ /* USB */
+ AA17_850_USB_DM,
+ W16_850_USB_PU_EN,
+ W17_850_USB_VBUSI,
+};
+
+
enum omap1xxx_index {
/* UART1 (BT_UART_GATING)*/
UART1_TX = 0,
@@ -788,7 +838,20 @@ enum omap34xx_index {
* - "_DOWN" suffix (GPIO3_DOWN) with internal pulldown
* - "_OUT" suffix (GPIO3_OUT) for output-only pins (unlike 24xx)
*/
+ AF26_34XX_GPIO0,
+ AF22_34XX_GPIO9,
AH8_34XX_GPIO29,
+ U8_34XX_GPIO54_OUT,
+ U8_34XX_GPIO54_DOWN,
+ L8_34XX_GPIO63,
+ G25_34XX_GPIO86_OUT,
+ AG4_34XX_GPIO134_OUT,
+ AE4_34XX_GPIO136_OUT,
+ AF6_34XX_GPIO140_UP,
+ AE6_34XX_GPIO141,
+ AF5_34XX_GPIO142,
+ AE5_34XX_GPIO143,
+ H19_34XX_GPIO164_OUT,
J25_34XX_GPIO170,
};
diff --git a/arch/arm/plat-omap/include/mach/omap34xx.h b/arch/arm/plat-omap/include/mach/omap34xx.h
index 8e0479fff05a..ab640151d3ec 100644
--- a/arch/arm/plat-omap/include/mach/omap34xx.h
+++ b/arch/arm/plat-omap/include/mach/omap34xx.h
@@ -49,11 +49,39 @@
#define OMAP343X_CTRL_BASE OMAP343X_SCM_BASE
#define OMAP34XX_IC_BASE 0x48200000
+
+#define OMAP3430_ISP_BASE (L4_34XX_BASE + 0xBC000)
+#define OMAP3430_ISP_CBUFF_BASE (OMAP3430_ISP_BASE + 0x0100)
+#define OMAP3430_ISP_CCP2_BASE (OMAP3430_ISP_BASE + 0x0400)
+#define OMAP3430_ISP_CCDC_BASE (OMAP3430_ISP_BASE + 0x0600)
+#define OMAP3430_ISP_HIST_BASE (OMAP3430_ISP_BASE + 0x0A00)
+#define OMAP3430_ISP_H3A_BASE (OMAP3430_ISP_BASE + 0x0C00)
+#define OMAP3430_ISP_PREV_BASE (OMAP3430_ISP_BASE + 0x0E00)
+#define OMAP3430_ISP_RESZ_BASE (OMAP3430_ISP_BASE + 0x1000)
+#define OMAP3430_ISP_SBL_BASE (OMAP3430_ISP_BASE + 0x1200)
+#define OMAP3430_ISP_MMU_BASE (OMAP3430_ISP_BASE + 0x1400)
+#define OMAP3430_ISP_CSI2A_BASE (OMAP3430_ISP_BASE + 0x1800)
+#define OMAP3430_ISP_CSI2PHY_BASE (OMAP3430_ISP_BASE + 0x1970)
+
+#define OMAP3430_ISP_END (OMAP3430_ISP_BASE + 0x06F)
+#define OMAP3430_ISP_CBUFF_END (OMAP3430_ISP_CBUFF_BASE + 0x077)
+#define OMAP3430_ISP_CCP2_END (OMAP3430_ISP_CCP2_BASE + 0x1EF)
+#define OMAP3430_ISP_CCDC_END (OMAP3430_ISP_CCDC_BASE + 0x0A7)
+#define OMAP3430_ISP_HIST_END (OMAP3430_ISP_HIST_BASE + 0x047)
+#define OMAP3430_ISP_H3A_END (OMAP3430_ISP_H3A_BASE + 0x05F)
+#define OMAP3430_ISP_PREV_END (OMAP3430_ISP_PREV_BASE + 0x09F)
+#define OMAP3430_ISP_RESZ_END (OMAP3430_ISP_RESZ_BASE + 0x0AB)
+#define OMAP3430_ISP_SBL_END (OMAP3430_ISP_SBL_BASE + 0x0FB)
+#define OMAP3430_ISP_MMU_END (OMAP3430_ISP_MMU_BASE + 0x06F)
+#define OMAP3430_ISP_CSI2A_END (OMAP3430_ISP_CSI2A_BASE + 0x16F)
+#define OMAP3430_ISP_CSI2PHY_END (OMAP3430_ISP_CSI2PHY_BASE + 0x007)
+
#define OMAP34XX_IVA_INTC_BASE 0x40000000
#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000)
#define OMAP34XX_HSUSB_HOST_BASE (L4_34XX_BASE + 0x64000)
#define OMAP34XX_USBTLL_BASE (L4_34XX_BASE + 0x62000)
+#define OMAP34XX_MAILBOX_BASE (L4_34XX_BASE + 0x94000)
#if defined(CONFIG_ARCH_OMAP3430)
diff --git a/arch/arm/plat-omap/include/mach/omap850.h b/arch/arm/plat-omap/include/mach/omap850.h
new file mode 100644
index 000000000000..c33f67981712
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/omap850.h
@@ -0,0 +1,102 @@
+/* arch/arm/plat-omap/include/mach/omap850.h
+ *
+ * Hardware definitions for TI OMAP850 processor.
+ *
+ * Derived from omap730.h by Zebediah C. McClure <zmc@lurian.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OMAP850_H
+#define __ASM_ARCH_OMAP850_H
+
+/*
+ * ----------------------------------------------------------------------------
+ * Base addresses
+ * ----------------------------------------------------------------------------
+ */
+
+/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
+
+#define OMAP850_DSP_BASE 0xE0000000
+#define OMAP850_DSP_SIZE 0x50000
+#define OMAP850_DSP_START 0xE0000000
+
+#define OMAP850_DSPREG_BASE 0xE1000000
+#define OMAP850_DSPREG_SIZE SZ_128K
+#define OMAP850_DSPREG_START 0xE1000000
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP850 specific configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP850_CONFIG_BASE 0xfffe1000
+#define OMAP850_IO_CONF_0 0xfffe1070
+#define OMAP850_IO_CONF_1 0xfffe1074
+#define OMAP850_IO_CONF_2 0xfffe1078
+#define OMAP850_IO_CONF_3 0xfffe107c
+#define OMAP850_IO_CONF_4 0xfffe1080
+#define OMAP850_IO_CONF_5 0xfffe1084
+#define OMAP850_IO_CONF_6 0xfffe1088
+#define OMAP850_IO_CONF_7 0xfffe108c
+#define OMAP850_IO_CONF_8 0xfffe1090
+#define OMAP850_IO_CONF_9 0xfffe1094
+#define OMAP850_IO_CONF_10 0xfffe1098
+#define OMAP850_IO_CONF_11 0xfffe109c
+#define OMAP850_IO_CONF_12 0xfffe10a0
+#define OMAP850_IO_CONF_13 0xfffe10a4
+
+#define OMAP850_MODE_1 0xfffe1010
+#define OMAP850_MODE_2 0xfffe1014
+
+/* CSMI specials: in terms of base + offset */
+#define OMAP850_MODE2_OFFSET 0x14
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP850 traffic controller configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP850_FLASH_CFG_0 0xfffecc10
+#define OMAP850_FLASH_ACFG_0 0xfffecc50
+#define OMAP850_FLASH_CFG_1 0xfffecc14
+#define OMAP850_FLASH_ACFG_1 0xfffecc54
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP850 DSP control registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP850_ICR_BASE 0xfffbb800
+#define OMAP850_DSP_M_CTL 0xfffbb804
+#define OMAP850_DSP_MMU_BASE 0xfffed200
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP850 PCC_UPLD configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP850_PCC_UPLD_CTRL_BASE (0xfffe0900)
+#define OMAP850_PCC_UPLD_CTRL (OMAP850_PCC_UPLD_CTRL_BASE + 0x00)
+
+#endif /* __ASM_ARCH_OMAP850_H */
+
diff --git a/arch/arm/plat-omap/include/mach/pm.h b/arch/arm/plat-omap/include/mach/pm.h
index 37e2f0f38b46..ce6ee7927537 100644
--- a/arch/arm/plat-omap/include/mach/pm.h
+++ b/arch/arm/plat-omap/include/mach/pm.h
@@ -118,18 +118,6 @@
extern void prevent_idle_sleep(void);
extern void allow_idle_sleep(void);
-/**
- * clk_deny_idle - Prevents the clock from being idled during MPU idle
- * @clk: clock signal handle
- */
-void clk_deny_idle(struct clk *clk);
-
-/**
- * clk_allow_idle - Counters previous clk_deny_idle
- * @clk: clock signal handle
- */
-void clk_allow_idle(struct clk *clk);
-
extern void omap_pm_idle(void);
extern void omap_pm_suspend(void);
extern void omap730_cpu_suspend(unsigned short, unsigned short);
diff --git a/arch/arm/plat-omap/include/mach/powerdomain.h b/arch/arm/plat-omap/include/mach/powerdomain.h
index 2806a9c8e4d7..69c9e675d8ee 100644
--- a/arch/arm/plat-omap/include/mach/powerdomain.h
+++ b/arch/arm/plat-omap/include/mach/powerdomain.h
@@ -50,9 +50,9 @@
/*
* Maximum number of clockdomains that can be associated with a powerdomain.
- * CORE powerdomain is probably the worst case.
+ * CORE powerdomain on OMAP3 is the worst case
*/
-#define PWRDM_MAX_CLKDMS 3
+#define PWRDM_MAX_CLKDMS 4
/* XXX A completely arbitrary number. What is reasonable here? */
#define PWRDM_TRANSITION_BAILOUT 100000
@@ -145,6 +145,7 @@ int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_pwrst(struct powerdomain *pwrdm);
int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm);
int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm);
diff --git a/arch/arm/plat-omap/include/mach/prcm.h b/arch/arm/plat-omap/include/mach/prcm.h
index 56eba0fd6f6a..24ac3c715912 100644
--- a/arch/arm/plat-omap/include/mach/prcm.h
+++ b/arch/arm/plat-omap/include/mach/prcm.h
@@ -20,10 +20,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef __ASM_ARM_ARCH_DPM_PRCM_H
-#define __ASM_ARM_ARCH_DPM_PRCM_H
+#ifndef __ASM_ARM_ARCH_OMAP_PRCM_H
+#define __ASM_ARM_ARCH_OMAP_PRCM_H
u32 omap_prcm_get_reset_sources(void);
+void omap_prcm_arch_reset(char mode);
#endif
diff --git a/arch/arm/plat-omap/include/mach/sdrc.h b/arch/arm/plat-omap/include/mach/sdrc.h
index a98c6c3beb2c..adc73522491f 100644
--- a/arch/arm/plat-omap/include/mach/sdrc.h
+++ b/arch/arm/plat-omap/include/mach/sdrc.h
@@ -4,10 +4,12 @@
/*
* OMAP2/3 SDRC/SMS register definitions
*
- * Copyright (C) 2007 Texas Instruments, Inc.
- * Copyright (C) 2007 Nokia Corporation
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
*
- * Written by Paul Walmsley
+ * Tony Lindgren
+ * Paul Walmsley
+ * Richard Woodruff
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -64,14 +66,62 @@
* SMS register access
*/
-
-#define OMAP242X_SMS_REGADDR(reg) IO_ADDRESS(OMAP2420_SMS_BASE + reg)
-#define OMAP243X_SMS_REGADDR(reg) IO_ADDRESS(OMAP243X_SMS_BASE + reg)
-#define OMAP343X_SMS_REGADDR(reg) IO_ADDRESS(OMAP343X_SMS_BASE + reg)
+#define OMAP242X_SMS_REGADDR(reg) \
+ (void __iomem *)IO_ADDRESS(OMAP2420_SMS_BASE + reg)
+#define OMAP243X_SMS_REGADDR(reg) \
+ (void __iomem *)IO_ADDRESS(OMAP243X_SMS_BASE + reg)
+#define OMAP343X_SMS_REGADDR(reg) \
+ (void __iomem *)IO_ADDRESS(OMAP343X_SMS_BASE + reg)
/* SMS register offsets - read/write with sms_{read,write}_reg() */
#define SMS_SYSCONFIG 0x010
/* REVISIT: fill in other SMS registers here */
+
+#ifndef __ASSEMBLER__
+
+/**
+ * struct omap_sdrc_params - SDRC parameters for a given SDRC clock rate
+ * @rate: SDRC clock rate (in Hz)
+ * @actim_ctrla: Value to program to SDRC_ACTIM_CTRLA for this rate
+ * @actim_ctrlb: Value to program to SDRC_ACTIM_CTRLB for this rate
+ * @rfr_ctrl: Value to program to SDRC_RFR_CTRL for this rate
+ * @mr: Value to program to SDRC_MR for this rate
+ *
+ * This structure holds a pre-computed set of register values for the
+ * SDRC for a given SDRC clock rate and SDRAM chip. These are
+ * intended to be pre-computed and specified in an array in the board-*.c
+ * files. The structure is keyed off the 'rate' field.
+ */
+struct omap_sdrc_params {
+ unsigned long rate;
+ u32 actim_ctrla;
+ u32 actim_ctrlb;
+ u32 rfr_ctrl;
+ u32 mr;
+};
+
+void __init omap2_sdrc_init(struct omap_sdrc_params *sp);
+struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r);
+
+#ifdef CONFIG_ARCH_OMAP2
+
+struct memory_timings {
+ u32 m_type; /* ddr = 1, sdr = 0 */
+ u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */
+ u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */
+ u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */
+ u32 base_cs; /* base chip select to use for calculations */
+};
+
+extern void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode);
+
+u32 omap2xxx_sdrc_dll_is_unlocked(void);
+u32 omap2xxx_sdrc_reprogram(u32 level, u32 force);
+
+#endif /* CONFIG_ARCH_OMAP2 */
+
+#endif /* __ASSEMBLER__ */
+
#endif
diff --git a/arch/arm/plat-omap/include/mach/system.h b/arch/arm/plat-omap/include/mach/system.h
index 06923f261545..1060e345423b 100644
--- a/arch/arm/plat-omap/include/mach/system.h
+++ b/arch/arm/plat-omap/include/mach/system.h
@@ -9,12 +9,14 @@
#include <asm/mach-types.h>
#include <mach/hardware.h>
+#include <mach/prcm.h>
+
#ifndef CONFIG_MACH_VOICEBLUE
#define voiceblue_reset() do {} while (0)
+#else
+extern void voiceblue_reset(void);
#endif
-extern void omap_prcm_arch_reset(char mode);
-
static inline void arch_idle(void)
{
cpu_do_idle();
@@ -38,7 +40,7 @@ static inline void omap1_arch_reset(char mode)
omap_writew(1, ARM_RSTCT1);
}
-static inline void arch_reset(char mode)
+static inline void arch_reset(char mode, const char *cmd)
{
if (!cpu_class_is_omap2())
omap1_arch_reset(mode);
diff --git a/arch/arm/plat-omap/include/mach/usb.h b/arch/arm/plat-omap/include/mach/usb.h
index a56a610950c2..69f0ceed500b 100644
--- a/arch/arm/plat-omap/include/mach/usb.h
+++ b/arch/arm/plat-omap/include/mach/usb.h
@@ -27,8 +27,18 @@
#define UDC_BASE OMAP2_UDC_BASE
#define OMAP_OHCI_BASE OMAP2_OHCI_BASE
+#ifdef CONFIG_USB_MUSB_SOC
+extern void usb_musb_init(void);
+#else
+static inline void usb_musb_init(void)
+{
+}
+#endif
+
#endif
+void omap_usb_init(struct omap_usb_config *pdata);
+
/*-------------------------------------------------------------------------*/
/*
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index b52ce053e6f2..0abfbaa59871 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -1,10 +1,9 @@
/*
* OMAP mailbox driver
*
- * Copyright (C) 2006 Nokia Corporation. All rights reserved.
+ * Copyright (C) 2006-2009 Nokia Corporation. All rights reserved.
*
- * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
- * Restructured by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -22,21 +21,98 @@
*
*/
-#include <linux/init.h>
#include <linux/module.h>
-#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/device.h>
-#include <linux/blkdev.h>
-#include <linux/err.h>
#include <linux/delay.h>
-#include <linux/io.h>
+
#include <mach/mailbox.h>
-#include "mailbox.h"
+
+static int enable_seq_bit;
+module_param(enable_seq_bit, bool, 0);
+MODULE_PARM_DESC(enable_seq_bit, "Enable sequence bit checking.");
static struct omap_mbox *mboxes;
static DEFINE_RWLOCK(mboxes_lock);
+/*
+ * Mailbox sequence bit API
+ */
+
+/* seq_rcv should be initialized with any value other than
+ * 0 and 1 << 31, to allow either value for the first
+ * message. */
+static inline void mbox_seq_init(struct omap_mbox *mbox)
+{
+ if (!enable_seq_bit)
+ return;
+
+ /* any value other than 0 and 1 << 31 */
+ mbox->seq_rcv = 0xffffffff;
+}
+
+static inline void mbox_seq_toggle(struct omap_mbox *mbox, mbox_msg_t * msg)
+{
+ if (!enable_seq_bit)
+ return;
+
+ /* add seq_snd to msg */
+ *msg = (*msg & 0x7fffffff) | mbox->seq_snd;
+ /* flip seq_snd */
+ mbox->seq_snd ^= 1 << 31;
+}
+
+static inline int mbox_seq_test(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+ mbox_msg_t seq;
+
+ if (!enable_seq_bit)
+ return 0;
+
+ seq = msg & (1 << 31);
+ if (seq == mbox->seq_rcv)
+ return -1;
+ mbox->seq_rcv = seq;
+ return 0;
+}
+
+/* Mailbox FIFO handle functions */
+static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
+{
+ return mbox->ops->fifo_read(mbox);
+}
+static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+ mbox->ops->fifo_write(mbox, msg);
+}
+static inline int mbox_fifo_empty(struct omap_mbox *mbox)
+{
+ return mbox->ops->fifo_empty(mbox);
+}
+static inline int mbox_fifo_full(struct omap_mbox *mbox)
+{
+ return mbox->ops->fifo_full(mbox);
+}
+
+/* Mailbox IRQ handle functions */
+static inline void enable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+ mbox->ops->enable_irq(mbox, irq);
+}
+static inline void disable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+ mbox->ops->disable_irq(mbox, irq);
+}
+static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+ if (mbox->ops->ack_irq)
+ mbox->ops->ack_irq(mbox, irq);
+}
+static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+ return mbox->ops->is_irq(mbox, irq);
+}
+
/* Mailbox Sequence Bit function */
void omap_mbox_init_seq(struct omap_mbox *mbox)
{
@@ -136,7 +212,7 @@ static void mbox_rx_work(struct work_struct *work)
unsigned long flags;
if (mbox->rxq->callback == NULL) {
- sysfs_notify(&mbox->dev.kobj, NULL, "mbox");
+ sysfs_notify(&mbox->dev->kobj, NULL, "mbox");
return;
}
@@ -204,7 +280,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox)
/* no more messages in the fifo. clear IRQ source. */
ack_mbox_irq(mbox, IRQ_RX);
enable_mbox_irq(mbox, IRQ_RX);
- nomem:
+nomem:
schedule_work(&mbox->rxq->work);
}
@@ -286,7 +362,7 @@ static ssize_t mbox_show(struct class *class, char *buf)
static CLASS_ATTR(mbox, S_IRUGO, mbox_show, NULL);
static struct class omap_mbox_class = {
- .name = "omap_mbox",
+ .name = "omap-mailbox",
};
static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
@@ -333,21 +409,6 @@ static int omap_mbox_init(struct omap_mbox *mbox)
return ret;
}
- mbox->dev.class = &omap_mbox_class;
- dev_set_name(&mbox->dev, "%s", mbox->name);
- dev_set_drvdata(&mbox->dev, mbox);
-
- ret = device_register(&mbox->dev);
- if (unlikely(ret))
- goto fail_device_reg;
-
- ret = device_create_file(&mbox->dev, &dev_attr_mbox);
- if (unlikely(ret)) {
- printk(KERN_ERR
- "device_create_file failed: %d\n", ret);
- goto fail_create_mbox;
- }
-
ret = request_irq(mbox->irq, mbox_interrupt, IRQF_DISABLED,
mbox->name, mbox);
if (unlikely(ret)) {
@@ -377,10 +438,6 @@ static int omap_mbox_init(struct omap_mbox *mbox)
fail_alloc_txq:
free_irq(mbox->irq, mbox);
fail_request_irq:
- device_remove_file(&mbox->dev, &dev_attr_mbox);
- fail_create_mbox:
- device_unregister(&mbox->dev);
- fail_device_reg:
if (unlikely(mbox->ops->shutdown))
mbox->ops->shutdown(mbox);
@@ -393,8 +450,6 @@ static void omap_mbox_fini(struct omap_mbox *mbox)
mbox_queue_free(mbox->rxq);
free_irq(mbox->irq, mbox);
- device_remove_file(&mbox->dev, &dev_attr_mbox);
- class_unregister(&omap_mbox_class);
if (unlikely(mbox->ops->shutdown))
mbox->ops->shutdown(mbox);
@@ -440,7 +495,7 @@ void omap_mbox_put(struct omap_mbox *mbox)
}
EXPORT_SYMBOL(omap_mbox_put);
-int omap_mbox_register(struct omap_mbox *mbox)
+int omap_mbox_register(struct device *parent, struct omap_mbox *mbox)
{
int ret = 0;
struct omap_mbox **tmp;
@@ -450,14 +505,31 @@ int omap_mbox_register(struct omap_mbox *mbox)
if (mbox->next)
return -EBUSY;
+ mbox->dev = device_create(&omap_mbox_class,
+ parent, 0, mbox, "%s", mbox->name);
+ if (IS_ERR(mbox->dev))
+ return PTR_ERR(mbox->dev);
+
+ ret = device_create_file(mbox->dev, &dev_attr_mbox);
+ if (ret)
+ goto err_sysfs;
+
write_lock(&mboxes_lock);
tmp = find_mboxes(mbox->name);
- if (*tmp)
+ if (*tmp) {
ret = -EBUSY;
- else
- *tmp = mbox;
+ write_unlock(&mboxes_lock);
+ goto err_find;
+ }
+ *tmp = mbox;
write_unlock(&mboxes_lock);
+ return 0;
+
+err_find:
+ device_remove_file(mbox->dev, &dev_attr_mbox);
+err_sysfs:
+ device_unregister(mbox->dev);
return ret;
}
EXPORT_SYMBOL(omap_mbox_register);
@@ -473,6 +545,8 @@ int omap_mbox_unregister(struct omap_mbox *mbox)
*tmp = mbox->next;
mbox->next = NULL;
write_unlock(&mboxes_lock);
+ device_remove_file(mbox->dev, &dev_attr_mbox);
+ device_unregister(mbox->dev);
return 0;
}
tmp = &(*tmp)->next;
@@ -501,4 +575,6 @@ static void __exit omap_mbox_class_exit(void)
subsys_initcall(omap_mbox_class_init);
module_exit(omap_mbox_class_exit);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging");
+MODULE_AUTHOR("Toshihiro Kobayashi and Hiroshi DOYU");
diff --git a/arch/arm/plat-omap/mailbox.h b/arch/arm/plat-omap/mailbox.h
deleted file mode 100644
index 67c6740b8ad5..000000000000
--- a/arch/arm/plat-omap/mailbox.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Mailbox internal functions
- *
- * Copyright (C) 2006 Nokia Corporation
- * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef __ARCH_ARM_PLAT_MAILBOX_H
-#define __ARCH_ARM_PLAT_MAILBOX_H
-
-/*
- * Mailbox sequence bit API
- */
-#if defined(CONFIG_ARCH_OMAP1)
-# define MBOX_USE_SEQ_BIT
-#elif defined(CONFIG_ARCH_OMAP2)
-# define MBOX_USE_SEQ_BIT
-#endif
-
-#ifdef MBOX_USE_SEQ_BIT
-/* seq_rcv should be initialized with any value other than
- * 0 and 1 << 31, to allow either value for the first
- * message. */
-static inline void mbox_seq_init(struct omap_mbox *mbox)
-{
- /* any value other than 0 and 1 << 31 */
- mbox->seq_rcv = 0xffffffff;
-}
-
-static inline void mbox_seq_toggle(struct omap_mbox *mbox, mbox_msg_t * msg)
-{
- /* add seq_snd to msg */
- *msg = (*msg & 0x7fffffff) | mbox->seq_snd;
- /* flip seq_snd */
- mbox->seq_snd ^= 1 << 31;
-}
-
-static inline int mbox_seq_test(struct omap_mbox *mbox, mbox_msg_t msg)
-{
- mbox_msg_t seq = msg & (1 << 31);
- if (seq == mbox->seq_rcv)
- return -1;
- mbox->seq_rcv = seq;
- return 0;
-}
-#else
-static inline void mbox_seq_init(struct omap_mbox *mbox)
-{
-}
-static inline void mbox_seq_toggle(struct omap_mbox *mbox, mbox_msg_t * msg)
-{
-}
-static inline int mbox_seq_test(struct omap_mbox *mbox, mbox_msg_t msg)
-{
- return 0;
-}
-#endif
-
-/* Mailbox FIFO handle functions */
-static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
-{
- return mbox->ops->fifo_read(mbox);
-}
-static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
-{
- mbox->ops->fifo_write(mbox, msg);
-}
-static inline int mbox_fifo_empty(struct omap_mbox *mbox)
-{
- return mbox->ops->fifo_empty(mbox);
-}
-static inline int mbox_fifo_full(struct omap_mbox *mbox)
-{
- return mbox->ops->fifo_full(mbox);
-}
-
-/* Mailbox IRQ handle functions */
-static inline void enable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
-{
- mbox->ops->enable_irq(mbox, irq);
-}
-static inline void disable_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
-{
- mbox->ops->disable_irq(mbox, irq);
-}
-static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
-{
- if (mbox->ops->ack_irq)
- mbox->ops->ack_irq(mbox, irq);
-}
-static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
-{
- return mbox->ops->is_irq(mbox, irq);
-}
-
-#endif /* __ARCH_ARM_PLAT_MAILBOX_H */
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index e5842e30e534..28b0a824b8cf 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -214,7 +214,6 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type);
int omap_mcbsp_request(unsigned int id)
{
struct omap_mcbsp *mcbsp;
- int i;
int err;
if (!omap_mcbsp_check_valid_id(id)) {
@@ -223,23 +222,23 @@ int omap_mcbsp_request(unsigned int id)
}
mcbsp = id_to_mcbsp_ptr(id);
- if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
- mcbsp->pdata->ops->request(id);
-
- for (i = 0; i < mcbsp->num_clks; i++)
- clk_enable(mcbsp->clks[i]);
-
spin_lock(&mcbsp->lock);
if (!mcbsp->free) {
dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
mcbsp->id);
spin_unlock(&mcbsp->lock);
- return -1;
+ return -EBUSY;
}
mcbsp->free = 0;
spin_unlock(&mcbsp->lock);
+ if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
+ mcbsp->pdata->ops->request(id);
+
+ clk_enable(mcbsp->iclk);
+ clk_enable(mcbsp->fclk);
+
/*
* Make sure that transmitter, receiver and sample-rate generator are
* not running before activating IRQs.
@@ -278,7 +277,6 @@ EXPORT_SYMBOL(omap_mcbsp_request);
void omap_mcbsp_free(unsigned int id)
{
struct omap_mcbsp *mcbsp;
- int i;
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
@@ -289,8 +287,14 @@ void omap_mcbsp_free(unsigned int id)
if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
mcbsp->pdata->ops->free(id);
- for (i = mcbsp->num_clks - 1; i >= 0; i--)
- clk_disable(mcbsp->clks[i]);
+ clk_disable(mcbsp->fclk);
+ clk_disable(mcbsp->iclk);
+
+ if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
+ /* Free IRQs */
+ free_irq(mcbsp->rx_irq, (void *)mcbsp);
+ free_irq(mcbsp->tx_irq, (void *)mcbsp);
+ }
spin_lock(&mcbsp->lock);
if (mcbsp->free) {
@@ -302,12 +306,6 @@ void omap_mcbsp_free(unsigned int id)
mcbsp->free = 1;
spin_unlock(&mcbsp->lock);
-
- if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
- /* Free IRQs */
- free_irq(mcbsp->rx_irq, (void *)mcbsp);
- free_irq(mcbsp->tx_irq, (void *)mcbsp);
- }
}
EXPORT_SYMBOL(omap_mcbsp_free);
@@ -876,7 +874,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
struct omap_mcbsp *mcbsp;
int id = pdev->id - 1;
- int i;
int ret = 0;
if (!pdata) {
@@ -899,7 +896,6 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
ret = -ENOMEM;
goto exit;
}
- mcbsp_ptr[id] = mcbsp;
spin_lock_init(&mcbsp->lock);
mcbsp->id = id + 1;
@@ -921,39 +917,32 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
mcbsp->dma_rx_sync = pdata->dma_rx_sync;
mcbsp->dma_tx_sync = pdata->dma_tx_sync;
- if (pdata->num_clks) {
- mcbsp->num_clks = pdata->num_clks;
- mcbsp->clks = kzalloc(mcbsp->num_clks * sizeof(struct clk *),
- GFP_KERNEL);
- if (!mcbsp->clks) {
- ret = -ENOMEM;
- goto exit;
- }
- for (i = 0; i < mcbsp->num_clks; i++) {
- mcbsp->clks[i] = clk_get(&pdev->dev, pdata->clk_names[i]);
- if (IS_ERR(mcbsp->clks[i])) {
- dev_err(&pdev->dev,
- "Invalid %s configuration for McBSP%d.\n",
- pdata->clk_names[i], mcbsp->id);
- ret = PTR_ERR(mcbsp->clks[i]);
- goto err_clk;
- }
- }
+ mcbsp->iclk = clk_get(&pdev->dev, "ick");
+ if (IS_ERR(mcbsp->iclk)) {
+ ret = PTR_ERR(mcbsp->iclk);
+ dev_err(&pdev->dev, "unable to get ick: %d\n", ret);
+ goto err_iclk;
+ }
+ mcbsp->fclk = clk_get(&pdev->dev, "fck");
+ if (IS_ERR(mcbsp->fclk)) {
+ ret = PTR_ERR(mcbsp->fclk);
+ dev_err(&pdev->dev, "unable to get fck: %d\n", ret);
+ goto err_fclk;
}
mcbsp->pdata = pdata;
mcbsp->dev = &pdev->dev;
+ mcbsp_ptr[id] = mcbsp;
platform_set_drvdata(pdev, mcbsp);
return 0;
-err_clk:
- while (i--)
- clk_put(mcbsp->clks[i]);
- kfree(mcbsp->clks);
+err_fclk:
+ clk_put(mcbsp->iclk);
+err_iclk:
iounmap(mcbsp->io_base);
err_ioremap:
- mcbsp->free = 0;
+ kfree(mcbsp);
exit:
return ret;
}
@@ -961,7 +950,6 @@ exit:
static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
{
struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
- int i;
platform_set_drvdata(pdev, NULL);
if (mcbsp) {
@@ -970,18 +958,15 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
mcbsp->pdata->ops->free)
mcbsp->pdata->ops->free(mcbsp->id);
- for (i = mcbsp->num_clks - 1; i >= 0; i--) {
- clk_disable(mcbsp->clks[i]);
- clk_put(mcbsp->clks[i]);
- }
+ clk_disable(mcbsp->fclk);
+ clk_disable(mcbsp->iclk);
+ clk_put(mcbsp->fclk);
+ clk_put(mcbsp->iclk);
iounmap(mcbsp->io_base);
- if (mcbsp->num_clks) {
- kfree(mcbsp->clks);
- mcbsp->clks = NULL;
- mcbsp->num_clks = 0;
- }
+ mcbsp->fclk = NULL;
+ mcbsp->iclk = NULL;
mcbsp->free = 0;
mcbsp->dev = NULL;
}
@@ -1002,4 +987,3 @@ int __init omap_mcbsp_init(void)
/* Register the McBSP driver */
return platform_driver_register(&omap_mcbsp_driver);
}
-
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index be7bcaf2b832..fa5297d643d3 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -148,7 +148,7 @@ void __init omap_detect_sram(void)
omap_sram_base = OMAP1_SRAM_VA;
omap_sram_start = OMAP1_SRAM_PA;
- if (cpu_is_omap730())
+ if (cpu_is_omap7xx())
omap_sram_size = 0x32000; /* 200K */
else if (cpu_is_omap15xx())
omap_sram_size = 0x30000; /* 192K */
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
index e278de6862ae..509f2ed99e21 100644
--- a/arch/arm/plat-omap/usb.c
+++ b/arch/arm/plat-omap/usb.c
@@ -729,30 +729,13 @@ static inline void omap_1510_usb_init(struct omap_usb_config *config) {}
/*-------------------------------------------------------------------------*/
-static struct omap_usb_config platform_data;
-
-static int __init
-omap_usb_init(void)
+void __init omap_usb_init(struct omap_usb_config *pdata)
{
- const struct omap_usb_config *config;
-
- config = omap_get_config(OMAP_TAG_USB, struct omap_usb_config);
- if (config == NULL) {
- printk(KERN_ERR "USB: No board-specific "
- "platform config found\n");
- return -ENODEV;
- }
- platform_data = *config;
-
if (cpu_is_omap730() || cpu_is_omap16xx() || cpu_is_omap24xx())
- omap_otg_init(&platform_data);
+ omap_otg_init(pdata);
else if (cpu_is_omap15xx())
- omap_1510_usb_init(&platform_data);
- else {
+ omap_1510_usb_init(pdata);
+ else
printk(KERN_ERR "USB: No init for your chip yet\n");
- return -ENODEV;
- }
- return 0;
}
-subsys_initcall(omap_usb_init);
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index 0d12c2164766..32eb9e33bebb 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -19,7 +19,8 @@
static DEFINE_SPINLOCK(gpio_lock);
static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */
-static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)];
+static unsigned long gpio_valid_input[BITS_TO_LONGS(GPIO_MAX)];
+static unsigned long gpio_valid_output[BITS_TO_LONGS(GPIO_MAX)];
static inline void __set_direction(unsigned pin, int input)
{
@@ -53,7 +54,7 @@ int gpio_direction_input(unsigned pin)
{
unsigned long flags;
- if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+ if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_input)) {
pr_debug("%s: invalid GPIO %d\n", __func__, pin);
return -EINVAL;
}
@@ -83,7 +84,7 @@ int gpio_direction_output(unsigned pin, int value)
unsigned long flags;
u32 u;
- if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+ if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid_output)) {
pr_debug("%s: invalid GPIO %d\n", __func__, pin);
return -EINVAL;
}
@@ -161,7 +162,9 @@ int gpio_request(unsigned pin, const char *label)
unsigned long flags;
int ret;
- if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+ if (pin >= GPIO_MAX ||
+ !(test_bit(pin, gpio_valid_input) ||
+ test_bit(pin, gpio_valid_output))) {
pr_debug("%s: invalid GPIO %d\n", __func__, pin);
return -EINVAL;
}
@@ -183,7 +186,9 @@ EXPORT_SYMBOL(gpio_request);
void gpio_free(unsigned pin)
{
- if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
+ if (pin >= GPIO_MAX ||
+ !(test_bit(pin, gpio_valid_input) ||
+ test_bit(pin, gpio_valid_output))) {
pr_debug("%s: invalid GPIO %d\n", __func__, pin);
return;
}
@@ -208,12 +213,18 @@ void __init orion_gpio_set_unused(unsigned pin)
__set_direction(pin, 0);
}
-void __init orion_gpio_set_valid(unsigned pin, int valid)
+void __init orion_gpio_set_valid(unsigned pin, int mode)
{
- if (valid)
- __set_bit(pin, gpio_valid);
+ if (mode == 1)
+ mode = GPIO_INPUT_OK | GPIO_OUTPUT_OK;
+ if (mode & GPIO_INPUT_OK)
+ __set_bit(pin, gpio_valid_input);
else
- __clear_bit(pin, gpio_valid);
+ __clear_bit(pin, gpio_valid_input);
+ if (mode & GPIO_OUTPUT_OK)
+ __set_bit(pin, gpio_valid_output);
+ else
+ __clear_bit(pin, gpio_valid_output);
}
void orion_gpio_set_blink(unsigned pin, int blink)
diff --git a/arch/arm/plat-orion/include/plat/gpio.h b/arch/arm/plat-orion/include/plat/gpio.h
index ec743e82c876..33f6c6aec185 100644
--- a/arch/arm/plat-orion/include/plat/gpio.h
+++ b/arch/arm/plat-orion/include/plat/gpio.h
@@ -25,9 +25,13 @@ void gpio_set_value(unsigned pin, int value);
* Orion-specific GPIO API extensions.
*/
void orion_gpio_set_unused(unsigned pin);
-void orion_gpio_set_valid(unsigned pin, int valid);
void orion_gpio_set_blink(unsigned pin, int blink);
+#define GPIO_BIDI_OK (1 << 0)
+#define GPIO_INPUT_OK (1 << 1)
+#define GPIO_OUTPUT_OK (1 << 2)
+void orion_gpio_set_valid(unsigned pin, int mode);
+
/*
* GPIO interrupt handling.
*/
diff --git a/arch/arm/plat-orion/include/plat/mvsdio.h b/arch/arm/plat-orion/include/plat/mvsdio.h
new file mode 100644
index 000000000000..14ca88676002
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/mvsdio.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/plat-orion/include/plat/mvsdio.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_MVSDIO_H
+#define __MACH_MVSDIO_H
+
+#include <linux/mbus.h>
+
+struct mvsdio_platform_data {
+ struct mbus_dram_target_info *dram;
+ unsigned int clock;
+ int gpio_card_detect;
+ int gpio_write_protect;
+};
+
+#endif
diff --git a/arch/arm/plat-orion/include/plat/orion5x_wdt.h b/arch/arm/plat-orion/include/plat/orion5x_wdt.h
new file mode 100644
index 000000000000..3c9cf6a305ef
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/orion5x_wdt.h
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/plat-orion/include/plat/orion5x_wdt.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_ORION5X_WDT_H
+#define __PLAT_ORION5X_WDT_H
+
+struct orion5x_wdt_platform_data {
+ u32 tclk; /* no <linux/clk.h> support yet */
+};
+
+
+#endif
+
diff --git a/arch/arm/plat-pxa/Kconfig b/arch/arm/plat-pxa/Kconfig
new file mode 100644
index 000000000000..b158e98038ed
--- /dev/null
+++ b/arch/arm/plat-pxa/Kconfig
@@ -0,0 +1,3 @@
+if PLAT_PXA
+
+endif
diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile
new file mode 100644
index 000000000000..8f2c4c7fbd48
--- /dev/null
+++ b/arch/arm/plat-pxa/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for code common across different PXA processor families
+#
+
+obj-y := dma.o
+
+obj-$(CONFIG_GENERIC_GPIO) += gpio.o
+obj-$(CONFIG_PXA3xx) += mfp.o
+obj-$(CONFIG_ARCH_MMP) += mfp.o
diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/plat-pxa/dma.c
index 7de17fc5d54b..70aeee407f7d 100644
--- a/arch/arm/mach-pxa/dma.c
+++ b/arch/arm/plat-pxa/dma.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mach-pxa/dma.c
+ * linux/arch/arm/plat-pxa/dma.c
*
* PXA DMA registration and IRQ dispatching
*
@@ -23,8 +23,6 @@
#include <mach/hardware.h>
#include <mach/dma.h>
-#include <mach/pxa-regs.h>
-
struct dma_channel {
char *name;
pxa_dma_prio prio;
@@ -36,8 +34,8 @@ static struct dma_channel *dma_channels;
static int num_dma_channels;
int pxa_request_dma (char *name, pxa_dma_prio prio,
- void (*irq_handler)(int, void *),
- void *data)
+ void (*irq_handler)(int, void *),
+ void *data)
{
unsigned long flags;
int i, found = 0;
@@ -113,7 +111,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-int __init pxa_init_dma(int num_ch)
+int __init pxa_init_dma(int irq, int num_ch)
{
int i, ret;
@@ -131,7 +129,7 @@ int __init pxa_init_dma(int num_ch)
dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW);
}
- ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL);
+ ret = request_irq(irq, dma_irq_handler, IRQF_DISABLED, "DMA", NULL);
if (ret) {
printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n");
kfree(dma_channels);
diff --git a/arch/arm/plat-pxa/gpio.c b/arch/arm/plat-pxa/gpio.c
new file mode 100644
index 000000000000..af819bf21b63
--- /dev/null
+++ b/arch/arm/plat-pxa/gpio.c
@@ -0,0 +1,337 @@
+/*
+ * linux/arch/arm/plat-pxa/gpio.c
+ *
+ * Generic PXA GPIO handling
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/bootmem.h>
+
+#include <mach/gpio.h>
+
+int pxa_last_gpio;
+
+struct pxa_gpio_chip {
+ struct gpio_chip chip;
+ void __iomem *regbase;
+ char label[10];
+
+ unsigned long irq_mask;
+ unsigned long irq_edge_rise;
+ unsigned long irq_edge_fall;
+
+#ifdef CONFIG_PM
+ unsigned long saved_gplr;
+ unsigned long saved_gpdr;
+ unsigned long saved_grer;
+ unsigned long saved_gfer;
+#endif
+};
+
+static DEFINE_SPINLOCK(gpio_lock);
+static struct pxa_gpio_chip *pxa_gpio_chips;
+
+#define for_each_gpio_chip(i, c) \
+ for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++)
+
+static inline void __iomem *gpio_chip_base(struct gpio_chip *c)
+{
+ return container_of(c, struct pxa_gpio_chip, chip)->regbase;
+}
+
+static inline struct pxa_gpio_chip *gpio_to_chip(unsigned gpio)
+{
+ return &pxa_gpio_chips[gpio_to_bank(gpio)];
+}
+
+static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ void __iomem *base = gpio_chip_base(chip);
+ uint32_t value, mask = 1 << offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ value = __raw_readl(base + GPDR_OFFSET);
+ if (__gpio_is_inverted(chip->base + offset))
+ value |= mask;
+ else
+ value &= ~mask;
+ __raw_writel(value, base + GPDR_OFFSET);
+
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ return 0;
+}
+
+static int pxa_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ void __iomem *base = gpio_chip_base(chip);
+ uint32_t tmp, mask = 1 << offset;
+ unsigned long flags;
+
+ __raw_writel(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET));
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ tmp = __raw_readl(base + GPDR_OFFSET);
+ if (__gpio_is_inverted(chip->base + offset))
+ tmp &= ~mask;
+ else
+ tmp |= mask;
+ __raw_writel(tmp, base + GPDR_OFFSET);
+
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ return 0;
+}
+
+static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ return __raw_readl(gpio_chip_base(chip) + GPLR_OFFSET) & (1 << offset);
+}
+
+static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ __raw_writel(1 << offset, gpio_chip_base(chip) +
+ (value ? GPSR_OFFSET : GPCR_OFFSET));
+}
+
+static int __init pxa_init_gpio_chip(int gpio_end)
+{
+ int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
+ struct pxa_gpio_chip *chips;
+
+ /* this is early, we have to use bootmem allocator, and we really
+ * want this to be allocated dynamically for different 'gpio_end'
+ */
+ chips = alloc_bootmem_low(nbanks * sizeof(struct pxa_gpio_chip));
+ if (chips == NULL) {
+ pr_err("%s: failed to allocate GPIO chips\n", __func__);
+ return -ENOMEM;
+ }
+
+ for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
+ struct gpio_chip *c = &chips[i].chip;
+
+ sprintf(chips[i].label, "gpio-%d", i);
+ chips[i].regbase = (void __iomem *)GPIO_BANK(i);
+
+ c->base = gpio;
+ c->label = chips[i].label;
+
+ c->direction_input = pxa_gpio_direction_input;
+ c->direction_output = pxa_gpio_direction_output;
+ c->get = pxa_gpio_get;
+ c->set = pxa_gpio_set;
+
+ /* number of GPIOs on last bank may be less than 32 */
+ c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
+ gpiochip_add(c);
+ }
+ pxa_gpio_chips = chips;
+ return 0;
+}
+
+static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
+{
+ struct pxa_gpio_chip *c;
+ int gpio = irq_to_gpio(irq);
+ unsigned long gpdr, mask = GPIO_bit(gpio);
+
+ c = gpio_to_chip(gpio);
+
+ if (type == IRQ_TYPE_PROBE) {
+ /* Don't mess with enabled GPIOs using preconfigured edges or
+ * GPIOs set to alternate function or to output during probe
+ */
+ if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio))
+ return 0;
+
+ if (__gpio_is_occupied(gpio))
+ return 0;
+
+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+ }
+
+ gpdr = __raw_readl(c->regbase + GPDR_OFFSET);
+
+ if (__gpio_is_inverted(gpio))
+ __raw_writel(gpdr | mask, c->regbase + GPDR_OFFSET);
+ else
+ __raw_writel(gpdr & ~mask, c->regbase + GPDR_OFFSET);
+
+ if (type & IRQ_TYPE_EDGE_RISING)
+ c->irq_edge_rise |= mask;
+ else
+ c->irq_edge_rise &= ~mask;
+
+ if (type & IRQ_TYPE_EDGE_FALLING)
+ c->irq_edge_fall |= mask;
+ else
+ c->irq_edge_fall &= ~mask;
+
+ __raw_writel(c->irq_edge_rise & c->irq_mask, c->regbase + GRER_OFFSET);
+ __raw_writel(c->irq_edge_fall & c->irq_mask, c->regbase + GFER_OFFSET);
+
+ pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__, irq, gpio,
+ ((type & IRQ_TYPE_EDGE_RISING) ? " rising" : ""),
+ ((type & IRQ_TYPE_EDGE_FALLING) ? " falling" : ""));
+ return 0;
+}
+
+static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
+{
+ struct pxa_gpio_chip *c;
+ int loop, gpio, gpio_base, n;
+ unsigned long gedr;
+
+ do {
+ loop = 0;
+ for_each_gpio_chip(gpio, c) {
+ gpio_base = c->chip.base;
+
+ gedr = __raw_readl(c->regbase + GEDR_OFFSET);
+ gedr = gedr & c->irq_mask;
+ __raw_writel(gedr, c->regbase + GEDR_OFFSET);
+
+ n = find_first_bit(&gedr, BITS_PER_LONG);
+ while (n < BITS_PER_LONG) {
+ loop = 1;
+
+ generic_handle_irq(gpio_to_irq(gpio_base + n));
+ n = find_next_bit(&gedr, BITS_PER_LONG, n + 1);
+ }
+ }
+ } while (loop);
+}
+
+static void pxa_ack_muxed_gpio(unsigned int irq)
+{
+ int gpio = irq_to_gpio(irq);
+ struct pxa_gpio_chip *c = gpio_to_chip(gpio);
+
+ __raw_writel(GPIO_bit(gpio), c->regbase + GEDR_OFFSET);
+}
+
+static void pxa_mask_muxed_gpio(unsigned int irq)
+{
+ int gpio = irq_to_gpio(irq);
+ struct pxa_gpio_chip *c = gpio_to_chip(gpio);
+ uint32_t grer, gfer;
+
+ c->irq_mask &= ~GPIO_bit(gpio);
+
+ grer = __raw_readl(c->regbase + GRER_OFFSET) & ~GPIO_bit(gpio);
+ gfer = __raw_readl(c->regbase + GFER_OFFSET) & ~GPIO_bit(gpio);
+ __raw_writel(grer, c->regbase + GRER_OFFSET);
+ __raw_writel(gfer, c->regbase + GFER_OFFSET);
+}
+
+static void pxa_unmask_muxed_gpio(unsigned int irq)
+{
+ int gpio = irq_to_gpio(irq);
+ struct pxa_gpio_chip *c = gpio_to_chip(gpio);
+
+ c->irq_mask |= GPIO_bit(gpio);
+ __raw_writel(c->irq_edge_rise & c->irq_mask, c->regbase + GRER_OFFSET);
+ __raw_writel(c->irq_edge_fall & c->irq_mask, c->regbase + GFER_OFFSET);
+}
+
+static struct irq_chip pxa_muxed_gpio_chip = {
+ .name = "GPIO",
+ .ack = pxa_ack_muxed_gpio,
+ .mask = pxa_mask_muxed_gpio,
+ .unmask = pxa_unmask_muxed_gpio,
+ .set_type = pxa_gpio_irq_type,
+};
+
+void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn)
+{
+ struct pxa_gpio_chip *c;
+ int gpio, irq;
+
+ pxa_last_gpio = end;
+
+ /* Initialize GPIO chips */
+ pxa_init_gpio_chip(end);
+
+ /* clear all GPIO edge detects */
+ for_each_gpio_chip(gpio, c) {
+ __raw_writel(0, c->regbase + GFER_OFFSET);
+ __raw_writel(0, c->regbase + GRER_OFFSET);
+ __raw_writel(~0,c->regbase + GEDR_OFFSET);
+ }
+
+ for (irq = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) {
+ set_irq_chip(irq, &pxa_muxed_gpio_chip);
+ set_irq_handler(irq, handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ /* Install handler for GPIO>=2 edge detect interrupts */
+ set_irq_chained_handler(mux_irq, pxa_gpio_demux_handler);
+ pxa_muxed_gpio_chip.set_wake = fn;
+}
+
+#ifdef CONFIG_PM
+static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state)
+{
+ struct pxa_gpio_chip *c;
+ int gpio;
+
+ for_each_gpio_chip(gpio, c) {
+ c->saved_gplr = __raw_readl(c->regbase + GPLR_OFFSET);
+ c->saved_gpdr = __raw_readl(c->regbase + GPDR_OFFSET);
+ c->saved_grer = __raw_readl(c->regbase + GRER_OFFSET);
+ c->saved_gfer = __raw_readl(c->regbase + GFER_OFFSET);
+
+ /* Clear GPIO transition detect bits */
+ __raw_writel(0xffffffff, c->regbase + GEDR_OFFSET);
+ }
+ return 0;
+}
+
+static int pxa_gpio_resume(struct sys_device *dev)
+{
+ struct pxa_gpio_chip *c;
+ int gpio;
+
+ for_each_gpio_chip(gpio, c) {
+ /* restore level with set/clear */
+ __raw_writel( c->saved_gplr, c->regbase + GPSR_OFFSET);
+ __raw_writel(~c->saved_gplr, c->regbase + GPCR_OFFSET);
+
+ __raw_writel(c->saved_grer, c->regbase + GRER_OFFSET);
+ __raw_writel(c->saved_gfer, c->regbase + GFER_OFFSET);
+ __raw_writel(c->saved_gpdr, c->regbase + GPDR_OFFSET);
+ }
+ return 0;
+}
+#else
+#define pxa_gpio_suspend NULL
+#define pxa_gpio_resume NULL
+#endif
+
+struct sysdev_class pxa_gpio_sysclass = {
+ .name = "gpio",
+ .suspend = pxa_gpio_suspend,
+ .resume = pxa_gpio_resume,
+};
+
+static int __init pxa_gpio_init(void)
+{
+ return sysdev_class_register(&pxa_gpio_sysclass);
+}
+
+core_initcall(pxa_gpio_init);
diff --git a/arch/arm/plat-pxa/include/plat/dma.h b/arch/arm/plat-pxa/include/plat/dma.h
new file mode 100644
index 000000000000..a7b91dc06852
--- /dev/null
+++ b/arch/arm/plat-pxa/include/plat/dma.h
@@ -0,0 +1,85 @@
+#ifndef __PLAT_DMA_H
+#define __PLAT_DMA_H
+
+#define DMAC_REG(x) (*((volatile u32 *)(DMAC_REGS_VIRT + (x))))
+
+#define DCSR(n) DMAC_REG((n) << 2)
+#define DALGN DMAC_REG(0x00a0) /* DMA Alignment Register */
+#define DINT DMAC_REG(0x00f0) /* DMA Interrupt Register */
+#define DDADR(n) DMAC_REG(0x0200 + ((n) << 4))
+#define DSADR(n) DMAC_REG(0x0204 + ((n) << 4))
+#define DTADR(n) DMAC_REG(0x0208 + ((n) << 4))
+#define DCMD(n) DMAC_REG(0x020c + ((n) << 4))
+#define DRCMR(n) DMAC_REG((((n) < 64) ? 0x0100 : 0x1100) + \
+ (((n) & 0x3f) << 2))
+
+#define DCSR_RUN (1 << 31) /* Run Bit (read / write) */
+#define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch (read / write) */
+#define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */
+#define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */
+#define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */
+#define DCSR_ENDINTR (1 << 2) /* End Interrupt (read / write) */
+#define DCSR_STARTINTR (1 << 1) /* Start Interrupt (read / write) */
+#define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt (read / write) */
+
+#define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable (R/W) */
+#define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */
+#define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */
+#define DCSR_SETCMPST (1 << 25) /* Set Descriptor Compare Status */
+#define DCSR_CLRCMPST (1 << 24) /* Clear Descriptor Compare Status */
+#define DCSR_CMPST (1 << 10) /* The Descriptor Compare Status */
+#define DCSR_EORINTR (1 << 9) /* The end of Receive */
+
+#define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */
+#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */
+
+#define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor (mask) */
+#define DDADR_STOP (1 << 0) /* Stop (read / write) */
+
+#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */
+#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */
+#define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */
+#define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */
+#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */
+#define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */
+#define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */
+#define DCMD_BURST8 (1 << 16) /* 8 byte burst */
+#define DCMD_BURST16 (2 << 16) /* 16 byte burst */
+#define DCMD_BURST32 (3 << 16) /* 32 byte burst */
+#define DCMD_WIDTH1 (1 << 14) /* 1 byte width */
+#define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */
+#define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */
+#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
+
+/*
+ * Descriptor structure for PXA's DMA engine
+ * Note: this structure must always be aligned to a 16-byte boundary.
+ */
+
+typedef struct pxa_dma_desc {
+ volatile u32 ddadr; /* Points to the next descriptor + flags */
+ volatile u32 dsadr; /* DSADR value for the current transfer */
+ volatile u32 dtadr; /* DTADR value for the current transfer */
+ volatile u32 dcmd; /* DCMD value for the current transfer */
+} pxa_dma_desc;
+
+typedef enum {
+ DMA_PRIO_HIGH = 0,
+ DMA_PRIO_MEDIUM = 1,
+ DMA_PRIO_LOW = 2
+} pxa_dma_prio;
+
+/*
+ * DMA registration
+ */
+
+int __init pxa_init_dma(int irq, int num_ch);
+
+int pxa_request_dma (char *name,
+ pxa_dma_prio prio,
+ void (*irq_handler)(int, void *),
+ void *data);
+
+void pxa_free_dma (int dma_ch);
+
+#endif /* __PLAT_DMA_H */
diff --git a/arch/arm/plat-pxa/include/plat/gpio.h b/arch/arm/plat-pxa/include/plat/gpio.h
new file mode 100644
index 000000000000..44248cb926a5
--- /dev/null
+++ b/arch/arm/plat-pxa/include/plat/gpio.h
@@ -0,0 +1,62 @@
+#ifndef __PLAT_GPIO_H
+#define __PLAT_GPIO_H
+
+/*
+ * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with
+ * one set of registers. The register offsets are organized below:
+ *
+ * GPLR GPDR GPSR GPCR GRER GFER GEDR
+ * BANK 0 - 0x0000 0x000C 0x0018 0x0024 0x0030 0x003C 0x0048
+ * BANK 1 - 0x0004 0x0010 0x001C 0x0028 0x0034 0x0040 0x004C
+ * BANK 2 - 0x0008 0x0014 0x0020 0x002C 0x0038 0x0044 0x0050
+ *
+ * BANK 3 - 0x0100 0x010C 0x0118 0x0124 0x0130 0x013C 0x0148
+ * BANK 4 - 0x0104 0x0110 0x011C 0x0128 0x0134 0x0140 0x014C
+ * BANK 5 - 0x0108 0x0114 0x0120 0x012C 0x0138 0x0144 0x0150
+ *
+ * NOTE:
+ * BANK 3 is only available on PXA27x and later processors.
+ * BANK 4 and 5 are only available on PXA935
+ */
+
+#define GPIO_BANK(n) (GPIO_REGS_VIRT + BANK_OFF(n))
+
+#define GPLR_OFFSET 0x00
+#define GPDR_OFFSET 0x0C
+#define GPSR_OFFSET 0x18
+#define GPCR_OFFSET 0x24
+#define GRER_OFFSET 0x30
+#define GFER_OFFSET 0x3C
+#define GEDR_OFFSET 0x48
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO))
+ return GPLR(gpio) & GPIO_bit(gpio);
+ else
+ return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) {
+ if (value)
+ GPSR(gpio) = GPIO_bit(gpio);
+ else
+ GPCR(gpio) = GPIO_bit(gpio);
+ } else
+ __gpio_set_value(gpio, value);
+}
+
+#define gpio_cansleep __gpio_cansleep
+
+/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85).
+ * Those cases currently cause holes in the GPIO number space, the
+ * actual number of the last GPIO is recorded by 'pxa_last_gpio'.
+ */
+extern int pxa_last_gpio;
+
+typedef int (*set_wake_t)(unsigned int irq, unsigned int on);
+
+extern void pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn);
+#endif /* __PLAT_GPIO_H */
diff --git a/arch/arm/plat-pxa/include/plat/mfp.h b/arch/arm/plat-pxa/include/plat/mfp.h
new file mode 100644
index 000000000000..64019464c8db
--- /dev/null
+++ b/arch/arm/plat-pxa/include/plat/mfp.h
@@ -0,0 +1,399 @@
+/*
+ * arch/arm/plat-pxa/include/plat/mfp.h
+ *
+ * Common Multi-Function Pin Definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ *
+ * 2007-8-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_PLAT_MFP_H
+#define __ASM_PLAT_MFP_H
+
+#define mfp_to_gpio(m) ((m) % 128)
+
+/* list of all the configurable MFP pins */
+enum {
+ MFP_PIN_INVALID = -1,
+
+ MFP_PIN_GPIO0 = 0,
+ MFP_PIN_GPIO1,
+ MFP_PIN_GPIO2,
+ MFP_PIN_GPIO3,
+ MFP_PIN_GPIO4,
+ MFP_PIN_GPIO5,
+ MFP_PIN_GPIO6,
+ MFP_PIN_GPIO7,
+ MFP_PIN_GPIO8,
+ MFP_PIN_GPIO9,
+ MFP_PIN_GPIO10,
+ MFP_PIN_GPIO11,
+ MFP_PIN_GPIO12,
+ MFP_PIN_GPIO13,
+ MFP_PIN_GPIO14,
+ MFP_PIN_GPIO15,
+ MFP_PIN_GPIO16,
+ MFP_PIN_GPIO17,
+ MFP_PIN_GPIO18,
+ MFP_PIN_GPIO19,
+ MFP_PIN_GPIO20,
+ MFP_PIN_GPIO21,
+ MFP_PIN_GPIO22,
+ MFP_PIN_GPIO23,
+ MFP_PIN_GPIO24,
+ MFP_PIN_GPIO25,
+ MFP_PIN_GPIO26,
+ MFP_PIN_GPIO27,
+ MFP_PIN_GPIO28,
+ MFP_PIN_GPIO29,
+ MFP_PIN_GPIO30,
+ MFP_PIN_GPIO31,
+ MFP_PIN_GPIO32,
+ MFP_PIN_GPIO33,
+ MFP_PIN_GPIO34,
+ MFP_PIN_GPIO35,
+ MFP_PIN_GPIO36,
+ MFP_PIN_GPIO37,
+ MFP_PIN_GPIO38,
+ MFP_PIN_GPIO39,
+ MFP_PIN_GPIO40,
+ MFP_PIN_GPIO41,
+ MFP_PIN_GPIO42,
+ MFP_PIN_GPIO43,
+ MFP_PIN_GPIO44,
+ MFP_PIN_GPIO45,
+ MFP_PIN_GPIO46,
+ MFP_PIN_GPIO47,
+ MFP_PIN_GPIO48,
+ MFP_PIN_GPIO49,
+ MFP_PIN_GPIO50,
+ MFP_PIN_GPIO51,
+ MFP_PIN_GPIO52,
+ MFP_PIN_GPIO53,
+ MFP_PIN_GPIO54,
+ MFP_PIN_GPIO55,
+ MFP_PIN_GPIO56,
+ MFP_PIN_GPIO57,
+ MFP_PIN_GPIO58,
+ MFP_PIN_GPIO59,
+ MFP_PIN_GPIO60,
+ MFP_PIN_GPIO61,
+ MFP_PIN_GPIO62,
+ MFP_PIN_GPIO63,
+ MFP_PIN_GPIO64,
+ MFP_PIN_GPIO65,
+ MFP_PIN_GPIO66,
+ MFP_PIN_GPIO67,
+ MFP_PIN_GPIO68,
+ MFP_PIN_GPIO69,
+ MFP_PIN_GPIO70,
+ MFP_PIN_GPIO71,
+ MFP_PIN_GPIO72,
+ MFP_PIN_GPIO73,
+ MFP_PIN_GPIO74,
+ MFP_PIN_GPIO75,
+ MFP_PIN_GPIO76,
+ MFP_PIN_GPIO77,
+ MFP_PIN_GPIO78,
+ MFP_PIN_GPIO79,
+ MFP_PIN_GPIO80,
+ MFP_PIN_GPIO81,
+ MFP_PIN_GPIO82,
+ MFP_PIN_GPIO83,
+ MFP_PIN_GPIO84,
+ MFP_PIN_GPIO85,
+ MFP_PIN_GPIO86,
+ MFP_PIN_GPIO87,
+ MFP_PIN_GPIO88,
+ MFP_PIN_GPIO89,
+ MFP_PIN_GPIO90,
+ MFP_PIN_GPIO91,
+ MFP_PIN_GPIO92,
+ MFP_PIN_GPIO93,
+ MFP_PIN_GPIO94,
+ MFP_PIN_GPIO95,
+ MFP_PIN_GPIO96,
+ MFP_PIN_GPIO97,
+ MFP_PIN_GPIO98,
+ MFP_PIN_GPIO99,
+ MFP_PIN_GPIO100,
+ MFP_PIN_GPIO101,
+ MFP_PIN_GPIO102,
+ MFP_PIN_GPIO103,
+ MFP_PIN_GPIO104,
+ MFP_PIN_GPIO105,
+ MFP_PIN_GPIO106,
+ MFP_PIN_GPIO107,
+ MFP_PIN_GPIO108,
+ MFP_PIN_GPIO109,
+ MFP_PIN_GPIO110,
+ MFP_PIN_GPIO111,
+ MFP_PIN_GPIO112,
+ MFP_PIN_GPIO113,
+ MFP_PIN_GPIO114,
+ MFP_PIN_GPIO115,
+ MFP_PIN_GPIO116,
+ MFP_PIN_GPIO117,
+ MFP_PIN_GPIO118,
+ MFP_PIN_GPIO119,
+ MFP_PIN_GPIO120,
+ MFP_PIN_GPIO121,
+ MFP_PIN_GPIO122,
+ MFP_PIN_GPIO123,
+ MFP_PIN_GPIO124,
+ MFP_PIN_GPIO125,
+ MFP_PIN_GPIO126,
+ MFP_PIN_GPIO127,
+ MFP_PIN_GPIO0_2,
+ MFP_PIN_GPIO1_2,
+ MFP_PIN_GPIO2_2,
+ MFP_PIN_GPIO3_2,
+ MFP_PIN_GPIO4_2,
+ MFP_PIN_GPIO5_2,
+ MFP_PIN_GPIO6_2,
+ MFP_PIN_GPIO7_2,
+ MFP_PIN_GPIO8_2,
+ MFP_PIN_GPIO9_2,
+ MFP_PIN_GPIO10_2,
+ MFP_PIN_GPIO11_2,
+ MFP_PIN_GPIO12_2,
+ MFP_PIN_GPIO13_2,
+ MFP_PIN_GPIO14_2,
+ MFP_PIN_GPIO15_2,
+ MFP_PIN_GPIO16_2,
+ MFP_PIN_GPIO17_2,
+
+ MFP_PIN_ULPI_STP,
+ MFP_PIN_ULPI_NXT,
+ MFP_PIN_ULPI_DIR,
+
+ MFP_PIN_nXCVREN,
+ MFP_PIN_DF_CLE_nOE,
+ MFP_PIN_DF_nADV1_ALE,
+ MFP_PIN_DF_SCLK_E,
+ MFP_PIN_DF_SCLK_S,
+ MFP_PIN_nBE0,
+ MFP_PIN_nBE1,
+ MFP_PIN_DF_nADV2_ALE,
+ MFP_PIN_DF_INT_RnB,
+ MFP_PIN_DF_nCS0,
+ MFP_PIN_DF_nCS1,
+ MFP_PIN_nLUA,
+ MFP_PIN_nLLA,
+ MFP_PIN_DF_nWE,
+ MFP_PIN_DF_ALE_nWE,
+ MFP_PIN_DF_nRE_nOE,
+ MFP_PIN_DF_ADDR0,
+ MFP_PIN_DF_ADDR1,
+ MFP_PIN_DF_ADDR2,
+ MFP_PIN_DF_ADDR3,
+ MFP_PIN_DF_IO0,
+ MFP_PIN_DF_IO1,
+ MFP_PIN_DF_IO2,
+ MFP_PIN_DF_IO3,
+ MFP_PIN_DF_IO4,
+ MFP_PIN_DF_IO5,
+ MFP_PIN_DF_IO6,
+ MFP_PIN_DF_IO7,
+ MFP_PIN_DF_IO8,
+ MFP_PIN_DF_IO9,
+ MFP_PIN_DF_IO10,
+ MFP_PIN_DF_IO11,
+ MFP_PIN_DF_IO12,
+ MFP_PIN_DF_IO13,
+ MFP_PIN_DF_IO14,
+ MFP_PIN_DF_IO15,
+ MFP_PIN_DF_nCS0_SM_nCS2,
+ MFP_PIN_DF_nCS1_SM_nCS3,
+ MFP_PIN_SM_nCS0,
+ MFP_PIN_SM_nCS1,
+ MFP_PIN_DF_WEn,
+ MFP_PIN_DF_REn,
+ MFP_PIN_DF_CLE_SM_OEn,
+ MFP_PIN_DF_ALE_SM_WEn,
+ MFP_PIN_DF_RDY0,
+ MFP_PIN_DF_RDY1,
+
+ MFP_PIN_SM_SCLK,
+ MFP_PIN_SM_BE0,
+ MFP_PIN_SM_BE1,
+ MFP_PIN_SM_ADV,
+ MFP_PIN_SM_ADVMUX,
+ MFP_PIN_SM_RDY,
+
+ MFP_PIN_MMC1_DAT7,
+ MFP_PIN_MMC1_DAT6,
+ MFP_PIN_MMC1_DAT5,
+ MFP_PIN_MMC1_DAT4,
+ MFP_PIN_MMC1_DAT3,
+ MFP_PIN_MMC1_DAT2,
+ MFP_PIN_MMC1_DAT1,
+ MFP_PIN_MMC1_DAT0,
+ MFP_PIN_MMC1_CMD,
+ MFP_PIN_MMC1_CLK,
+ MFP_PIN_MMC1_CD,
+ MFP_PIN_MMC1_WP,
+
+ /* additional pins on PXA930 */
+ MFP_PIN_GSIM_UIO,
+ MFP_PIN_GSIM_UCLK,
+ MFP_PIN_GSIM_UDET,
+ MFP_PIN_GSIM_nURST,
+ MFP_PIN_PMIC_INT,
+ MFP_PIN_RDY,
+
+ MFP_PIN_MAX,
+};
+
+/*
+ * a possible MFP configuration is represented by a 32-bit integer
+ *
+ * bit 0.. 9 - MFP Pin Number (1024 Pins Maximum)
+ * bit 10..12 - Alternate Function Selection
+ * bit 13..15 - Drive Strength
+ * bit 16..18 - Low Power Mode State
+ * bit 19..20 - Low Power Mode Edge Detection
+ * bit 21..22 - Run Mode Pull State
+ *
+ * to facilitate the definition, the following macros are provided
+ *
+ * MFP_CFG_DEFAULT - default MFP configuration value, with
+ * alternate function = 0,
+ * drive strength = fast 3mA (MFP_DS03X)
+ * low power mode = default
+ * edge detection = none
+ *
+ * MFP_CFG - default MFPR value with alternate function
+ * MFP_CFG_DRV - default MFPR value with alternate function and
+ * pin drive strength
+ * MFP_CFG_LPM - default MFPR value with alternate function and
+ * low power mode
+ * MFP_CFG_X - default MFPR value with alternate function,
+ * pin drive strength and low power mode
+ */
+
+typedef unsigned long mfp_cfg_t;
+
+#define MFP_PIN(x) ((x) & 0x3ff)
+
+#define MFP_AF0 (0x0 << 10)
+#define MFP_AF1 (0x1 << 10)
+#define MFP_AF2 (0x2 << 10)
+#define MFP_AF3 (0x3 << 10)
+#define MFP_AF4 (0x4 << 10)
+#define MFP_AF5 (0x5 << 10)
+#define MFP_AF6 (0x6 << 10)
+#define MFP_AF7 (0x7 << 10)
+#define MFP_AF_MASK (0x7 << 10)
+#define MFP_AF(x) (((x) >> 10) & 0x7)
+
+#define MFP_DS01X (0x0 << 13)
+#define MFP_DS02X (0x1 << 13)
+#define MFP_DS03X (0x2 << 13)
+#define MFP_DS04X (0x3 << 13)
+#define MFP_DS06X (0x4 << 13)
+#define MFP_DS08X (0x5 << 13)
+#define MFP_DS10X (0x6 << 13)
+#define MFP_DS13X (0x7 << 13)
+#define MFP_DS_MASK (0x7 << 13)
+#define MFP_DS(x) (((x) >> 13) & 0x7)
+
+#define MFP_LPM_DEFAULT (0x0 << 16)
+#define MFP_LPM_DRIVE_LOW (0x1 << 16)
+#define MFP_LPM_DRIVE_HIGH (0x2 << 16)
+#define MFP_LPM_PULL_LOW (0x3 << 16)
+#define MFP_LPM_PULL_HIGH (0x4 << 16)
+#define MFP_LPM_FLOAT (0x5 << 16)
+#define MFP_LPM_INPUT (0x6 << 16)
+#define MFP_LPM_STATE_MASK (0x7 << 16)
+#define MFP_LPM_STATE(x) (((x) >> 16) & 0x7)
+
+#define MFP_LPM_EDGE_NONE (0x0 << 19)
+#define MFP_LPM_EDGE_RISE (0x1 << 19)
+#define MFP_LPM_EDGE_FALL (0x2 << 19)
+#define MFP_LPM_EDGE_BOTH (0x3 << 19)
+#define MFP_LPM_EDGE_MASK (0x3 << 19)
+#define MFP_LPM_EDGE(x) (((x) >> 19) & 0x3)
+
+#define MFP_PULL_NONE (0x0 << 21)
+#define MFP_PULL_LOW (0x1 << 21)
+#define MFP_PULL_HIGH (0x2 << 21)
+#define MFP_PULL_BOTH (0x3 << 21)
+#define MFP_PULL_MASK (0x3 << 21)
+#define MFP_PULL(x) (((x) >> 21) & 0x3)
+
+#define MFP_CFG_DEFAULT (MFP_AF0 | MFP_DS03X | MFP_LPM_DEFAULT |\
+ MFP_LPM_EDGE_NONE | MFP_PULL_NONE)
+
+#define MFP_CFG(pin, af) \
+ ((MFP_CFG_DEFAULT & ~MFP_AF_MASK) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af))
+
+#define MFP_CFG_DRV(pin, af, drv) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv))
+
+#define MFP_CFG_LPM(pin, af, lpm) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_LPM_STATE_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_LPM_##lpm))
+
+#define MFP_CFG_X(pin, af, drv, lpm) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK | MFP_LPM_STATE_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv | MFP_LPM_##lpm))
+
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_ARCH_MMP)
+/*
+ * each MFP pin will have a MFPR register, since the offset of the
+ * register varies between processors, the processor specific code
+ * should initialize the pin offsets by mfp_init()
+ *
+ * mfp_init_base() - accepts a virtual base for all MFPR registers and
+ * initialize the MFP table to a default state
+ *
+ * mfp_init_addr() - accepts a table of "mfp_addr_map" structure, which
+ * represents a range of MFP pins from "start" to "end", with the offset
+ * begining at "offset", to define a single pin, let "end" = -1.
+ *
+ * use
+ *
+ * MFP_ADDR_X() to define a range of pins
+ * MFP_ADDR() to define a single pin
+ * MFP_ADDR_END to signal the end of pin offset definitions
+ */
+struct mfp_addr_map {
+ unsigned int start;
+ unsigned int end;
+ unsigned long offset;
+};
+
+#define MFP_ADDR_X(start, end, offset) \
+ { MFP_PIN_##start, MFP_PIN_##end, offset }
+
+#define MFP_ADDR(pin, offset) \
+ { MFP_PIN_##pin, -1, offset }
+
+#define MFP_ADDR_END { MFP_PIN_INVALID, 0 }
+
+void __init mfp_init_base(unsigned long mfpr_base);
+void __init mfp_init_addr(struct mfp_addr_map *map);
+
+/*
+ * mfp_{read, write}() - for direct read/write access to the MFPR register
+ * mfp_config() - for configuring a group of MFPR registers
+ * mfp_config_lpm() - configuring all low power MFPR registers for suspend
+ * mfp_config_run() - configuring all run time MFPR registers after resume
+ */
+unsigned long mfp_read(int mfp);
+void mfp_write(int mfp, unsigned long mfpr_val);
+void mfp_config(unsigned long *mfp_cfgs, int num);
+void mfp_config_run(void);
+void mfp_config_lpm(void);
+#endif /* CONFIG_PXA3xx || CONFIG_ARCH_MMP */
+
+#endif /* __ASM_PLAT_MFP_H */
diff --git a/arch/arm/plat-pxa/mfp.c b/arch/arm/plat-pxa/mfp.c
new file mode 100644
index 000000000000..e716c622a17c
--- /dev/null
+++ b/arch/arm/plat-pxa/mfp.c
@@ -0,0 +1,278 @@
+/*
+ * linux/arch/arm/plat-pxa/mfp.c
+ *
+ * Multi-Function Pin Support
+ *
+ * Copyright (C) 2007 Marvell Internation Ltd.
+ *
+ * 2007-08-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+
+#include <plat/mfp.h>
+
+#define MFPR_SIZE (PAGE_SIZE)
+
+/* MFPR register bit definitions */
+#define MFPR_PULL_SEL (0x1 << 15)
+#define MFPR_PULLUP_EN (0x1 << 14)
+#define MFPR_PULLDOWN_EN (0x1 << 13)
+#define MFPR_SLEEP_SEL (0x1 << 9)
+#define MFPR_SLEEP_OE_N (0x1 << 7)
+#define MFPR_EDGE_CLEAR (0x1 << 6)
+#define MFPR_EDGE_FALL_EN (0x1 << 5)
+#define MFPR_EDGE_RISE_EN (0x1 << 4)
+
+#define MFPR_SLEEP_DATA(x) ((x) << 8)
+#define MFPR_DRIVE(x) (((x) & 0x7) << 10)
+#define MFPR_AF_SEL(x) (((x) & 0x7) << 0)
+
+#define MFPR_EDGE_NONE (0)
+#define MFPR_EDGE_RISE (MFPR_EDGE_RISE_EN)
+#define MFPR_EDGE_FALL (MFPR_EDGE_FALL_EN)
+#define MFPR_EDGE_BOTH (MFPR_EDGE_RISE | MFPR_EDGE_FALL)
+
+/*
+ * Table that determines the low power modes outputs, with actual settings
+ * used in parentheses for don't-care values. Except for the float output,
+ * the configured driven and pulled levels match, so if there is a need for
+ * non-LPM pulled output, the same configuration could probably be used.
+ *
+ * Output value sleep_oe_n sleep_data pullup_en pulldown_en pull_sel
+ * (bit 7) (bit 8) (bit 14) (bit 13) (bit 15)
+ *
+ * Input 0 X(0) X(0) X(0) 0
+ * Drive 0 0 0 0 X(1) 0
+ * Drive 1 0 1 X(1) 0 0
+ * Pull hi (1) 1 X(1) 1 0 0
+ * Pull lo (0) 1 X(0) 0 1 0
+ * Z (float) 1 X(0) 0 0 0
+ */
+#define MFPR_LPM_INPUT (0)
+#define MFPR_LPM_DRIVE_LOW (MFPR_SLEEP_DATA(0) | MFPR_PULLDOWN_EN)
+#define MFPR_LPM_DRIVE_HIGH (MFPR_SLEEP_DATA(1) | MFPR_PULLUP_EN)
+#define MFPR_LPM_PULL_LOW (MFPR_LPM_DRIVE_LOW | MFPR_SLEEP_OE_N)
+#define MFPR_LPM_PULL_HIGH (MFPR_LPM_DRIVE_HIGH | MFPR_SLEEP_OE_N)
+#define MFPR_LPM_FLOAT (MFPR_SLEEP_OE_N)
+#define MFPR_LPM_MASK (0xe080)
+
+/*
+ * The pullup and pulldown state of the MFP pin at run mode is by default
+ * determined by the selected alternate function. In case that some buggy
+ * devices need to override this default behavior, the definitions below
+ * indicates the setting of corresponding MFPR bits
+ *
+ * Definition pull_sel pullup_en pulldown_en
+ * MFPR_PULL_NONE 0 0 0
+ * MFPR_PULL_LOW 1 0 1
+ * MFPR_PULL_HIGH 1 1 0
+ * MFPR_PULL_BOTH 1 1 1
+ */
+#define MFPR_PULL_NONE (0)
+#define MFPR_PULL_LOW (MFPR_PULL_SEL | MFPR_PULLDOWN_EN)
+#define MFPR_PULL_BOTH (MFPR_PULL_LOW | MFPR_PULLUP_EN)
+#define MFPR_PULL_HIGH (MFPR_PULL_SEL | MFPR_PULLUP_EN)
+
+/* mfp_spin_lock is used to ensure that MFP register configuration
+ * (most likely a read-modify-write operation) is atomic, and that
+ * mfp_table[] is consistent
+ */
+static DEFINE_SPINLOCK(mfp_spin_lock);
+
+static void __iomem *mfpr_mmio_base;
+
+struct mfp_pin {
+ unsigned long config; /* -1 for not configured */
+ unsigned long mfpr_off; /* MFPRxx Register offset */
+ unsigned long mfpr_run; /* Run-Mode Register Value */
+ unsigned long mfpr_lpm; /* Low Power Mode Register Value */
+};
+
+static struct mfp_pin mfp_table[MFP_PIN_MAX];
+
+/* mapping of MFP_LPM_* definitions to MFPR_LPM_* register bits */
+static const unsigned long mfpr_lpm[] = {
+ MFPR_LPM_INPUT,
+ MFPR_LPM_DRIVE_LOW,
+ MFPR_LPM_DRIVE_HIGH,
+ MFPR_LPM_PULL_LOW,
+ MFPR_LPM_PULL_HIGH,
+ MFPR_LPM_FLOAT,
+};
+
+/* mapping of MFP_PULL_* definitions to MFPR_PULL_* register bits */
+static const unsigned long mfpr_pull[] = {
+ MFPR_PULL_NONE,
+ MFPR_PULL_LOW,
+ MFPR_PULL_HIGH,
+ MFPR_PULL_BOTH,
+};
+
+/* mapping of MFP_LPM_EDGE_* definitions to MFPR_EDGE_* register bits */
+static const unsigned long mfpr_edge[] = {
+ MFPR_EDGE_NONE,
+ MFPR_EDGE_RISE,
+ MFPR_EDGE_FALL,
+ MFPR_EDGE_BOTH,
+};
+
+#define mfpr_readl(off) \
+ __raw_readl(mfpr_mmio_base + (off))
+
+#define mfpr_writel(off, val) \
+ __raw_writel(val, mfpr_mmio_base + (off))
+
+#define mfp_configured(p) ((p)->config != -1)
+
+/*
+ * perform a read-back of any MFPR register to make sure the
+ * previous writings are finished
+ */
+#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0)
+
+static inline void __mfp_config_run(struct mfp_pin *p)
+{
+ if (mfp_configured(p))
+ mfpr_writel(p->mfpr_off, p->mfpr_run);
+}
+
+static inline void __mfp_config_lpm(struct mfp_pin *p)
+{
+ if (mfp_configured(p)) {
+ unsigned long mfpr_clr = (p->mfpr_run & ~MFPR_EDGE_BOTH) | MFPR_EDGE_CLEAR;
+ if (mfpr_clr != p->mfpr_run)
+ mfpr_writel(p->mfpr_off, mfpr_clr);
+ if (p->mfpr_lpm != mfpr_clr)
+ mfpr_writel(p->mfpr_off, p->mfpr_lpm);
+ }
+}
+
+void mfp_config(unsigned long *mfp_cfgs, int num)
+{
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+
+ for (i = 0; i < num; i++, mfp_cfgs++) {
+ unsigned long tmp, c = *mfp_cfgs;
+ struct mfp_pin *p;
+ int pin, af, drv, lpm, edge, pull;
+
+ pin = MFP_PIN(c);
+ BUG_ON(pin >= MFP_PIN_MAX);
+ p = &mfp_table[pin];
+
+ af = MFP_AF(c);
+ drv = MFP_DS(c);
+ lpm = MFP_LPM_STATE(c);
+ edge = MFP_LPM_EDGE(c);
+ pull = MFP_PULL(c);
+
+ /* run-mode pull settings will conflict with MFPR bits of
+ * low power mode state, calculate mfpr_run and mfpr_lpm
+ * individually if pull != MFP_PULL_NONE
+ */
+ tmp = MFPR_AF_SEL(af) | MFPR_DRIVE(drv);
+
+ if (likely(pull == MFP_PULL_NONE)) {
+ p->mfpr_run = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
+ p->mfpr_lpm = p->mfpr_run;
+ } else {
+ p->mfpr_lpm = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
+ p->mfpr_run = tmp | mfpr_pull[pull];
+ }
+
+ p->config = c; __mfp_config_run(p);
+ }
+
+ mfpr_sync();
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+unsigned long mfp_read(int mfp)
+{
+ unsigned long val, flags;
+
+ BUG_ON(mfp >= MFP_PIN_MAX);
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+ val = mfpr_readl(mfp_table[mfp].mfpr_off);
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+
+ return val;
+}
+
+void mfp_write(int mfp, unsigned long val)
+{
+ unsigned long flags;
+
+ BUG_ON(mfp >= MFP_PIN_MAX);
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+ mfpr_writel(mfp_table[mfp].mfpr_off, val);
+ mfpr_sync();
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+void __init mfp_init_base(unsigned long mfpr_base)
+{
+ int i;
+
+ /* initialize the table with default - unconfigured */
+ for (i = 0; i < ARRAY_SIZE(mfp_table); i++)
+ mfp_table[i].config = -1;
+
+ mfpr_mmio_base = (void __iomem *)mfpr_base;
+}
+
+void __init mfp_init_addr(struct mfp_addr_map *map)
+{
+ struct mfp_addr_map *p;
+ unsigned long offset, flags;
+ int i;
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+
+ for (p = map; p->start != MFP_PIN_INVALID; p++) {
+ offset = p->offset;
+ i = p->start;
+
+ do {
+ mfp_table[i].mfpr_off = offset;
+ mfp_table[i].mfpr_run = 0;
+ mfp_table[i].mfpr_lpm = 0;
+ offset += 4; i++;
+ } while ((i <= p->end) && (p->end != -1));
+ }
+
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+void mfp_config_lpm(void)
+{
+ struct mfp_pin *p = &mfp_table[0];
+ int pin;
+
+ for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++, p++)
+ __mfp_config_lpm(p);
+}
+
+void mfp_config_run(void)
+{
+ struct mfp_pin *p = &mfp_table[0];
+ int pin;
+
+ for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++, p++)
+ __mfp_config_run(p);
+}
diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile
index 39195f972d5e..8d7815d25a51 100644
--- a/arch/arm/plat-s3c/Makefile
+++ b/arch/arm/plat-s3c/Makefile
@@ -18,6 +18,11 @@ obj-y += pwm-clock.o
obj-y += gpio.o
obj-y += gpio-config.o
+# PM support
+
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_S3C2410_PM_CHECK) += pm-check.o
+
# devices
obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o
diff --git a/arch/arm/mach-s3c2410/include/mach/audio.h b/arch/arm/plat-s3c/include/plat/audio.h
index de0e8da48bc3..de0e8da48bc3 100644
--- a/arch/arm/mach-s3c2410/include/mach/audio.h
+++ b/arch/arm/plat-s3c/include/plat/audio.h
diff --git a/arch/arm/plat-s3c/include/plat/pm.h b/arch/arm/plat-s3c/include/plat/pm.h
new file mode 100644
index 000000000000..3779775133a9
--- /dev/null
+++ b/arch/arm/plat-s3c/include/plat/pm.h
@@ -0,0 +1,174 @@
+/* linux/include/asm-arm/plat-s3c24xx/pm.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Written by Ben Dooks, <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* s3c_pm_init
+ *
+ * called from board at initialisation time to setup the power
+ * management
+*/
+
+#ifdef CONFIG_PM
+
+extern __init int s3c_pm_init(void);
+
+#else
+
+static inline int s3c_pm_init(void)
+{
+ return 0;
+}
+#endif
+
+/* configuration for the IRQ mask over sleep */
+extern unsigned long s3c_irqwake_intmask;
+extern unsigned long s3c_irqwake_eintmask;
+
+/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */
+extern unsigned long s3c_irqwake_intallow;
+extern unsigned long s3c_irqwake_eintallow;
+
+/* per-cpu sleep functions */
+
+extern void (*pm_cpu_prep)(void);
+extern void (*pm_cpu_sleep)(void);
+
+/* Flags for PM Control */
+
+extern unsigned long s3c_pm_flags;
+
+/* from sleep.S */
+
+extern int s3c_cpu_save(unsigned long *saveblk);
+extern void s3c_cpu_resume(void);
+
+extern void s3c2410_cpu_suspend(void);
+
+extern unsigned long s3c_sleep_save_phys;
+
+/* sleep save info */
+
+/**
+ * struct sleep_save - save information for shared peripherals.
+ * @reg: Pointer to the register to save.
+ * @val: Holder for the value saved from reg.
+ *
+ * This describes a list of registers which is used by the pm core and
+ * other subsystem to save and restore register values over suspend.
+ */
+struct sleep_save {
+ void __iomem *reg;
+ unsigned long val;
+};
+
+#define SAVE_ITEM(x) \
+ { .reg = (x) }
+
+/**
+ * struct pm_uart_save - save block for core UART
+ * @ulcon: Save value for S3C2410_ULCON
+ * @ucon: Save value for S3C2410_UCON
+ * @ufcon: Save value for S3C2410_UFCON
+ * @umcon: Save value for S3C2410_UMCON
+ * @ubrdiv: Save value for S3C2410_UBRDIV
+ *
+ * Save block for UART registers to be held over sleep and restored if they
+ * are needed (say by debug).
+*/
+struct pm_uart_save {
+ u32 ulcon;
+ u32 ucon;
+ u32 ufcon;
+ u32 umcon;
+ u32 ubrdiv;
+};
+
+/* helper functions to save/restore lists of registers. */
+
+extern void s3c_pm_do_save(struct sleep_save *ptr, int count);
+extern void s3c_pm_do_restore(struct sleep_save *ptr, int count);
+extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
+
+#ifdef CONFIG_PM
+extern int s3c_irqext_wake(unsigned int irqno, unsigned int state);
+extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
+extern int s3c24xx_irq_resume(struct sys_device *dev);
+#else
+#define s3c_irqext_wake NULL
+#define s3c24xx_irq_suspend NULL
+#define s3c24xx_irq_resume NULL
+#endif
+
+/* PM debug functions */
+
+#ifdef CONFIG_S3C2410_PM_DEBUG
+/**
+ * s3c_pm_dbg() - low level debug function for use in suspend/resume.
+ * @msg: The message to print.
+ *
+ * This function is used mainly to debug the resume process before the system
+ * can rely on printk/console output. It uses the low-level debugging output
+ * routine printascii() to do its work.
+ */
+extern void s3c_pm_dbg(const char *msg, ...);
+
+#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt)
+#else
+#define S3C_PMDBG(fmt...) printk(KERN_DEBUG fmt)
+#endif
+
+/* suspend memory checking */
+
+#ifdef CONFIG_S3C2410_PM_CHECK
+extern void s3c_pm_check_prepare(void);
+extern void s3c_pm_check_restore(void);
+extern void s3c_pm_check_cleanup(void);
+extern void s3c_pm_check_store(void);
+#else
+#define s3c_pm_check_prepare() do { } while(0)
+#define s3c_pm_check_restore() do { } while(0)
+#define s3c_pm_check_cleanup() do { } while(0)
+#define s3c_pm_check_store() do { } while(0)
+#endif
+
+/**
+ * s3c_pm_configure_extint() - ensure pins are correctly set for IRQ
+ *
+ * Setup all the necessary GPIO pins for waking the system on external
+ * interrupt.
+ */
+extern void s3c_pm_configure_extint(void);
+
+/**
+ * s3c_pm_restore_gpios() - restore the state of the gpios after sleep.
+ *
+ * Restore the state of the GPIO pins after sleep, which may involve ensuring
+ * that we do not glitch the state of the pins from that the bootloader's
+ * resume code has done.
+*/
+extern void s3c_pm_restore_gpios(void);
+
+/**
+ * s3c_pm_save_gpios() - save the state of the GPIOs for restoring after sleep.
+ *
+ * Save the GPIO states for resotration on resume. See s3c_pm_restore_gpios().
+ */
+extern void s3c_pm_save_gpios(void);
+
+/**
+ * s3c_pm_cb_flushcache - callback for assembly code
+ *
+ * Callback to issue flush_cache_all() as this call is
+ * not a directly callable object.
+ */
+extern void s3c_pm_cb_flushcache(void);
+
+extern void s3c_pm_save_core(void);
+extern void s3c_pm_restore_core(void);
diff --git a/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h b/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h
index 25d4058bcfed..0fad7571030e 100644
--- a/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h
+++ b/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h
@@ -33,6 +33,9 @@
#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1)
#define S3C2412_IISCON_IIS_ACTIVE (1 << 0)
+#define S3C64XX_IISMOD_IMS_PCLK (0 << 10)
+#define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10)
+
#define S3C2412_IISMOD_MASTER_INTERNAL (0 << 10)
#define S3C2412_IISMOD_MASTER_EXTERNAL (1 << 10)
#define S3C2412_IISMOD_SLAVE (2 << 10)
@@ -44,8 +47,8 @@
#define S3C2412_IISMOD_LR_LLOW (0 << 7)
#define S3C2412_IISMOD_LR_RLOW (1 << 7)
#define S3C2412_IISMOD_SDF_IIS (0 << 5)
-#define S3C2412_IISMOD_SDF_MSB (0 << 5)
-#define S3C2412_IISMOD_SDF_LSB (0 << 5)
+#define S3C2412_IISMOD_SDF_MSB (1 << 5)
+#define S3C2412_IISMOD_SDF_LSB (2 << 5)
#define S3C2412_IISMOD_SDF_MASK (3 << 5)
#define S3C2412_IISMOD_RCLK_256FS (0 << 3)
#define S3C2412_IISMOD_RCLK_512FS (1 << 3)
diff --git a/arch/arm/plat-s3c/include/plat/uncompress.h b/arch/arm/plat-s3c/include/plat/uncompress.h
index 6061de87f225..dc66a477f62e 100644
--- a/arch/arm/plat-s3c/include/plat/uncompress.h
+++ b/arch/arm/plat-s3c/include/plat/uncompress.h
@@ -90,7 +90,10 @@ static inline void flush(void)
{
}
-#define __raw_writel(d,ad) do { *((volatile unsigned int *)(ad)) = (d); } while(0)
+#define __raw_writel(d, ad) \
+ do { \
+ *((volatile unsigned int __force *)(ad)) = (d); \
+ } while (0)
/* CONFIG_S3C_BOOT_WATCHDOG
*
diff --git a/arch/arm/mach-s3c2410/include/mach/usb-control.h b/arch/arm/plat-s3c/include/plat/usb-control.h
index cd91d1591f31..822c87fe948e 100644
--- a/arch/arm/mach-s3c2410/include/mach/usb-control.h
+++ b/arch/arm/plat-s3c/include/plat/usb-control.h
@@ -1,9 +1,9 @@
-/* arch/arm/mach-s3c2410/include/mach/usb-control.h
+/* arch/arm/plat-s3c/include/plat/usb-control.h
*
* Copyright (c) 2004 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
- * S3C2410 - usb port information
+ * S3C - USB host port information
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -11,7 +11,7 @@
*/
#ifndef __ASM_ARCH_USBCONTROL_H
-#define __ASM_ARCH_USBCONTROL_H "arch/arm/mach-s3c2410/include/mach/usb-control.h"
+#define __ASM_ARCH_USBCONTROL_H
#define S3C_HCDFLG_USED (1)
diff --git a/arch/arm/plat-s3c/pm-check.c b/arch/arm/plat-s3c/pm-check.c
new file mode 100644
index 000000000000..39f2555564da
--- /dev/null
+++ b/arch/arm/plat-s3c/pm-check.c
@@ -0,0 +1,242 @@
+/* linux/arch/arm/plat-s3c/pm-check.c
+ * originally in linux/arch/arm/plat-s3c24xx/pm.c
+ *
+ * Copyright (c) 2004,2006,2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Power Mangament - suspend/resume memory corruptiuon check.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/init.h>
+#include <linux/crc32.h>
+#include <linux/ioport.h>
+
+#include <plat/pm.h>
+
+#if CONFIG_S3C2410_PM_CHECK_CHUNKSIZE < 1
+#error CONFIG_S3C2410_PM_CHECK_CHUNKSIZE must be a positive non-zero value
+#endif
+
+/* suspend checking code...
+ *
+ * this next area does a set of crc checks over all the installed
+ * memory, so the system can verify if the resume was ok.
+ *
+ * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
+ * increasing it will mean that the area corrupted will be less easy to spot,
+ * and reducing the size will cause the CRC save area to grow
+*/
+
+#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024)
+
+static u32 crc_size; /* size needed for the crc block */
+static u32 *crcs; /* allocated over suspend/resume */
+
+typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
+
+/* s3c_pm_run_res
+ *
+ * go through the given resource list, and look for system ram
+*/
+
+static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
+{
+ while (ptr != NULL) {
+ if (ptr->child != NULL)
+ s3c_pm_run_res(ptr->child, fn, arg);
+
+ if ((ptr->flags & IORESOURCE_MEM) &&
+ strcmp(ptr->name, "System RAM") == 0) {
+ S3C_PMDBG("Found system RAM at %08lx..%08lx\n",
+ (unsigned long)ptr->start,
+ (unsigned long)ptr->end);
+ arg = (fn)(ptr, arg);
+ }
+
+ ptr = ptr->sibling;
+ }
+}
+
+static void s3c_pm_run_sysram(run_fn_t fn, u32 *arg)
+{
+ s3c_pm_run_res(&iomem_resource, fn, arg);
+}
+
+static u32 *s3c_pm_countram(struct resource *res, u32 *val)
+{
+ u32 size = (u32)(res->end - res->start)+1;
+
+ size += CHECK_CHUNKSIZE-1;
+ size /= CHECK_CHUNKSIZE;
+
+ S3C_PMDBG("Area %08lx..%08lx, %d blocks\n",
+ (unsigned long)res->start, (unsigned long)res->end, size);
+
+ *val += size * sizeof(u32);
+ return val;
+}
+
+/* s3c_pm_prepare_check
+ *
+ * prepare the necessary information for creating the CRCs. This
+ * must be done before the final save, as it will require memory
+ * allocating, and thus touching bits of the kernel we do not
+ * know about.
+*/
+
+void s3c_pm_check_prepare(void)
+{
+ crc_size = 0;
+
+ s3c_pm_run_sysram(s3c_pm_countram, &crc_size);
+
+ S3C_PMDBG("s3c_pm_prepare_check: %u checks needed\n", crc_size);
+
+ crcs = kmalloc(crc_size+4, GFP_KERNEL);
+ if (crcs == NULL)
+ printk(KERN_ERR "Cannot allocated CRC save area\n");
+}
+
+static u32 *s3c_pm_makecheck(struct resource *res, u32 *val)
+{
+ unsigned long addr, left;
+
+ for (addr = res->start; addr < res->end;
+ addr += CHECK_CHUNKSIZE) {
+ left = res->end - addr;
+
+ if (left > CHECK_CHUNKSIZE)
+ left = CHECK_CHUNKSIZE;
+
+ *val = crc32_le(~0, phys_to_virt(addr), left);
+ val++;
+ }
+
+ return val;
+}
+
+/* s3c_pm_check_store
+ *
+ * compute the CRC values for the memory blocks before the final
+ * sleep.
+*/
+
+void s3c_pm_check_store(void)
+{
+ if (crcs != NULL)
+ s3c_pm_run_sysram(s3c_pm_makecheck, crcs);
+}
+
+/* in_region
+ *
+ * return TRUE if the area defined by ptr..ptr+size contains the
+ * what..what+whatsz
+*/
+
+static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
+{
+ if ((what+whatsz) < ptr)
+ return 0;
+
+ if (what > (ptr+size))
+ return 0;
+
+ return 1;
+}
+
+/**
+ * s3c_pm_runcheck() - helper to check a resource on restore.
+ * @res: The resource to check
+ * @vak: Pointer to list of CRC32 values to check.
+ *
+ * Called from the s3c_pm_check_restore() via s3c_pm_run_sysram(), this
+ * function runs the given memory resource checking it against the stored
+ * CRC to ensure that memory is restored. The function tries to skip as
+ * many of the areas used during the suspend process.
+ */
+static u32 *s3c_pm_runcheck(struct resource *res, u32 *val)
+{
+ void *save_at = phys_to_virt(s3c_sleep_save_phys);
+ unsigned long addr;
+ unsigned long left;
+ void *stkpage;
+ void *ptr;
+ u32 calc;
+
+ stkpage = (void *)((u32)&calc & ~PAGE_MASK);
+
+ for (addr = res->start; addr < res->end;
+ addr += CHECK_CHUNKSIZE) {
+ left = res->end - addr;
+
+ if (left > CHECK_CHUNKSIZE)
+ left = CHECK_CHUNKSIZE;
+
+ ptr = phys_to_virt(addr);
+
+ if (in_region(ptr, left, stkpage, 4096)) {
+ S3C_PMDBG("skipping %08lx, has stack in\n", addr);
+ goto skip_check;
+ }
+
+ if (in_region(ptr, left, crcs, crc_size)) {
+ S3C_PMDBG("skipping %08lx, has crc block in\n", addr);
+ goto skip_check;
+ }
+
+ if (in_region(ptr, left, save_at, 32*4 )) {
+ S3C_PMDBG("skipping %08lx, has save block in\n", addr);
+ goto skip_check;
+ }
+
+ /* calculate and check the checksum */
+
+ calc = crc32_le(~0, ptr, left);
+ if (calc != *val) {
+ printk(KERN_ERR "Restore CRC error at "
+ "%08lx (%08x vs %08x)\n", addr, calc, *val);
+
+ S3C_PMDBG("Restore CRC error at %08lx (%08x vs %08x)\n",
+ addr, calc, *val);
+ }
+
+ skip_check:
+ val++;
+ }
+
+ return val;
+}
+
+/**
+ * s3c_pm_check_restore() - memory check called on resume
+ *
+ * check the CRCs after the restore event and free the memory used
+ * to hold them
+*/
+void s3c_pm_check_restore(void)
+{
+ if (crcs != NULL)
+ s3c_pm_run_sysram(s3c_pm_runcheck, crcs);
+}
+
+/**
+ * s3c_pm_check_cleanup() - free memory resources
+ *
+ * Free the resources that where allocated by the suspend
+ * memory check code. We do this separately from the
+ * s3c_pm_check_restore() function as we cannot call any
+ * functions that might sleep during that resume.
+ */
+void s3c_pm_check_cleanup(void)
+{
+ kfree(crcs);
+ crcs = NULL;
+}
+
diff --git a/arch/arm/plat-s3c/pm.c b/arch/arm/plat-s3c/pm.c
new file mode 100644
index 000000000000..061182ca66e3
--- /dev/null
+++ b/arch/arm/plat-s3c/pm.c
@@ -0,0 +1,363 @@
+/* linux/arch/arm/plat-s3c/pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2004,2006,2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C common power management (suspend to ram) support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <mach/hardware.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-irq.h>
+#include <asm/irq.h>
+
+#include <plat/pm.h>
+#include <plat/pm-core.h>
+
+/* for external use */
+
+unsigned long s3c_pm_flags;
+
+/* Debug code:
+ *
+ * This code supports debug output to the low level UARTs for use on
+ * resume before the console layer is available.
+*/
+
+#ifdef CONFIG_S3C2410_PM_DEBUG
+extern void printascii(const char *);
+
+void s3c_pm_dbg(const char *fmt, ...)
+{
+ va_list va;
+ char buff[256];
+
+ va_start(va, fmt);
+ vsprintf(buff, fmt, va);
+ va_end(va);
+
+ printascii(buff);
+}
+
+static inline void s3c_pm_debug_init(void)
+{
+ /* restart uart clocks so we can use them to output */
+ s3c_pm_debug_init_uart();
+}
+
+#else
+#define s3c_pm_debug_init() do { } while(0)
+
+#endif /* CONFIG_S3C2410_PM_DEBUG */
+
+/* Save the UART configurations if we are configured for debug. */
+
+#ifdef CONFIG_S3C2410_PM_DEBUG
+
+struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS];
+
+static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save)
+{
+ void __iomem *regs = S3C_VA_UARTx(uart);
+
+ save->ulcon = __raw_readl(regs + S3C2410_ULCON);
+ save->ucon = __raw_readl(regs + S3C2410_UCON);
+ save->ufcon = __raw_readl(regs + S3C2410_UFCON);
+ save->umcon = __raw_readl(regs + S3C2410_UMCON);
+ save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV);
+}
+
+static void s3c_pm_save_uarts(void)
+{
+ struct pm_uart_save *save = uart_save;
+ unsigned int uart;
+
+ for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
+ s3c_pm_save_uart(uart, save);
+}
+
+static void s3c_pm_restore_uart(unsigned int uart, struct pm_uart_save *save)
+{
+ void __iomem *regs = S3C_VA_UARTx(uart);
+
+ __raw_writel(save->ulcon, regs + S3C2410_ULCON);
+ __raw_writel(save->ucon, regs + S3C2410_UCON);
+ __raw_writel(save->ufcon, regs + S3C2410_UFCON);
+ __raw_writel(save->umcon, regs + S3C2410_UMCON);
+ __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV);
+}
+
+static void s3c_pm_restore_uarts(void)
+{
+ struct pm_uart_save *save = uart_save;
+ unsigned int uart;
+
+ for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
+ s3c_pm_restore_uart(uart, save);
+}
+#else
+static void s3c_pm_save_uarts(void) { }
+static void s3c_pm_restore_uarts(void) { }
+#endif
+
+/* The IRQ ext-int code goes here, it is too small to currently bother
+ * with its own file. */
+
+unsigned long s3c_irqwake_intmask = 0xffffffffL;
+unsigned long s3c_irqwake_eintmask = 0xffffffffL;
+
+int s3c_irqext_wake(unsigned int irqno, unsigned int state)
+{
+ unsigned long bit = 1L << IRQ_EINT_BIT(irqno);
+
+ if (!(s3c_irqwake_eintallow & bit))
+ return -ENOENT;
+
+ printk(KERN_INFO "wake %s for irq %d\n",
+ state ? "enabled" : "disabled", irqno);
+
+ if (!state)
+ s3c_irqwake_eintmask |= bit;
+ else
+ s3c_irqwake_eintmask &= ~bit;
+
+ return 0;
+}
+
+/* helper functions to save and restore register state */
+
+/**
+ * s3c_pm_do_save() - save a set of registers for restoration on resume.
+ * @ptr: Pointer to an array of registers.
+ * @count: Size of the ptr array.
+ *
+ * Run through the list of registers given, saving their contents in the
+ * array for later restoration when we wakeup.
+ */
+void s3c_pm_do_save(struct sleep_save *ptr, int count)
+{
+ for (; count > 0; count--, ptr++) {
+ ptr->val = __raw_readl(ptr->reg);
+ S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val);
+ }
+}
+
+/**
+ * s3c_pm_do_restore() - restore register values from the save list.
+ * @ptr: Pointer to an array of registers.
+ * @count: Size of the ptr array.
+ *
+ * Restore the register values saved from s3c_pm_do_save().
+ *
+ * Note, we do not use S3C_PMDBG() in here, as the system may not have
+ * restore the UARTs state yet
+*/
+
+void s3c_pm_do_restore(struct sleep_save *ptr, int count)
+{
+ for (; count > 0; count--, ptr++) {
+ printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
+ ptr->reg, ptr->val, __raw_readl(ptr->reg));
+
+ __raw_writel(ptr->val, ptr->reg);
+ }
+}
+
+/**
+ * s3c_pm_do_restore_core() - early restore register values from save list.
+ *
+ * This is similar to s3c_pm_do_restore() except we try and minimise the
+ * side effects of the function in case registers that hardware might need
+ * to work has been restored.
+ *
+ * WARNING: Do not put any debug in here that may effect memory or use
+ * peripherals, as things may be changing!
+*/
+
+void s3c_pm_do_restore_core(struct sleep_save *ptr, int count)
+{
+ for (; count > 0; count--, ptr++)
+ __raw_writel(ptr->val, ptr->reg);
+}
+
+/* s3c2410_pm_show_resume_irqs
+ *
+ * print any IRQs asserted at resume time (ie, we woke from)
+*/
+static void s3c_pm_show_resume_irqs(int start, unsigned long which,
+ unsigned long mask)
+{
+ int i;
+
+ which &= ~mask;
+
+ for (i = 0; i <= 31; i++) {
+ if (which & (1L<<i)) {
+ S3C_PMDBG("IRQ %d asserted at resume\n", start+i);
+ }
+ }
+}
+
+
+void (*pm_cpu_prep)(void);
+void (*pm_cpu_sleep)(void);
+
+#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
+
+/* s3c_pm_enter
+ *
+ * central control for sleep/resume process
+*/
+
+static int s3c_pm_enter(suspend_state_t state)
+{
+ static unsigned long regs_save[16];
+
+ /* ensure the debug is initialised (if enabled) */
+
+ s3c_pm_debug_init();
+
+ S3C_PMDBG("%s(%d)\n", __func__, state);
+
+ if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
+ printk(KERN_ERR "%s: error: no cpu sleep function\n", __func__);
+ return -EINVAL;
+ }
+
+ /* check if we have anything to wake-up with... bad things seem
+ * to happen if you suspend with no wakeup (system will often
+ * require a full power-cycle)
+ */
+
+ if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
+ !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
+ printk(KERN_ERR "%s: No wake-up sources!\n", __func__);
+ printk(KERN_ERR "%s: Aborting sleep\n", __func__);
+ return -EINVAL;
+ }
+
+ /* store the physical address of the register recovery block */
+
+ s3c_sleep_save_phys = virt_to_phys(regs_save);
+
+ S3C_PMDBG("s3c_sleep_save_phys=0x%08lx\n", s3c_sleep_save_phys);
+
+ /* save all necessary core registers not covered by the drivers */
+
+ s3c_pm_save_gpios();
+ s3c_pm_save_uarts();
+ s3c_pm_save_core();
+
+ /* set the irq configuration for wake */
+
+ s3c_pm_configure_extint();
+
+ S3C_PMDBG("sleep: irq wakeup masks: %08lx,%08lx\n",
+ s3c_irqwake_intmask, s3c_irqwake_eintmask);
+
+ s3c_pm_arch_prepare_irqs();
+
+ /* call cpu specific preparation */
+
+ pm_cpu_prep();
+
+ /* flush cache back to ram */
+
+ flush_cache_all();
+
+ s3c_pm_check_store();
+
+ /* send the cpu to sleep... */
+
+ s3c_pm_arch_stop_clocks();
+
+ /* s3c_cpu_save will also act as our return point from when
+ * we resume as it saves its own register state and restores it
+ * during the resume. */
+
+ s3c_cpu_save(regs_save);
+
+ /* restore the cpu state using the kernel's cpu init code. */
+
+ cpu_init();
+
+ /* restore the system state */
+
+ s3c_pm_restore_core();
+ s3c_pm_restore_uarts();
+ s3c_pm_restore_gpios();
+
+ s3c_pm_debug_init();
+
+ /* check what irq (if any) restored the system */
+
+ s3c_pm_arch_show_resume_irqs();
+
+ S3C_PMDBG("%s: post sleep, preparing to return\n", __func__);
+
+ s3c_pm_check_restore();
+
+ /* ok, let's return from sleep */
+
+ S3C_PMDBG("S3C PM Resume (post-restore)\n");
+ return 0;
+}
+
+/* callback from assembly code */
+void s3c_pm_cb_flushcache(void)
+{
+ flush_cache_all();
+}
+
+static int s3c_pm_prepare(void)
+{
+ /* prepare check area if configured */
+
+ s3c_pm_check_prepare();
+ return 0;
+}
+
+static void s3c_pm_finish(void)
+{
+ s3c_pm_check_cleanup();
+}
+
+static struct platform_suspend_ops s3c_pm_ops = {
+ .enter = s3c_pm_enter,
+ .prepare = s3c_pm_prepare,
+ .finish = s3c_pm_finish,
+ .valid = suspend_valid_only_mem,
+};
+
+/* s3c_pm_init
+ *
+ * Attach the power management functions. This should be called
+ * from the board specific initialisation if the board supports
+ * it.
+*/
+
+int __init s3c_pm_init(void)
+{
+ printk("S3C Power Management, Copyright 2004 Simtec Electronics\n");
+
+ suspend_set_ops(&s3c_pm_ops);
+ return 0;
+}
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index 1e0767b266b8..636cb12711df 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o
obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM) += irq-pm.o
obj-$(CONFIG_PM) += sleep.o
obj-$(CONFIG_HAVE_PWM) += pwm.o
obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
index 3d4837021ac7..1a8347cec20a 100644
--- a/arch/arm/plat-s3c24xx/common-smdk.c
+++ b/arch/arm/plat-s3c24xx/common-smdk.c
@@ -201,5 +201,5 @@ void __init smdk_machine_init(void)
platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));
- s3c2410_pm_init();
+ s3c_pm_init();
}
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 542062f8cbc1..1932b7e0da15 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -182,7 +182,7 @@ static unsigned long s3c24xx_read_idcode_v4(void)
* with the caches enabled. It seems at least the S3C2440 has a problem
* resetting if there is bus activity interrupted by the reset.
*/
-static void s3c24xx_pm_restart(char mode)
+static void s3c24xx_pm_restart(char mode, const char *cmd)
{
if (mode != 's') {
unsigned long flags;
@@ -191,12 +191,12 @@ static void s3c24xx_pm_restart(char mode)
__cpuc_flush_kern_all();
__cpuc_flush_user_all();
- arch_reset(mode);
+ arch_reset(mode, cmd);
local_irq_restore(flags);
}
/* fallback, or unhandled */
- arm_machine_restart(mode);
+ arm_machine_restart(mode, cmd);
}
void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
diff --git a/arch/arm/plat-s3c24xx/include/plat/irq.h b/arch/arm/plat-s3c24xx/include/plat/irq.h
index 45746a995343..69e1be8bec35 100644
--- a/arch/arm/plat-s3c24xx/include/plat/irq.h
+++ b/arch/arm/plat-s3c24xx/include/plat/irq.h
@@ -10,6 +10,12 @@
* published by the Free Software Foundation.
*/
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
#define irqdbf(x...)
#define irqdbf2(x...)
diff --git a/arch/arm/plat-s3c24xx/include/plat/map.h b/arch/arm/plat-s3c24xx/include/plat/map.h
index fef8ea8b8e1e..eed8f78e7593 100644
--- a/arch/arm/plat-s3c24xx/include/plat/map.h
+++ b/arch/arm/plat-s3c24xx/include/plat/map.h
@@ -31,6 +31,8 @@
#define S3C24XX_SZ_UART SZ_1M
#define S3C_UART_OFFSET (0x4000)
+#define S3C_VA_UARTx(uart) (S3C_VA_UART + ((uart * S3C_UART_OFFSET)))
+
/* Timers */
#define S3C24XX_VA_TIMER S3C_VA_TIMER
#define S3C2410_PA_TIMER (0x51000000)
diff --git a/arch/arm/plat-s3c24xx/include/plat/pm-core.h b/arch/arm/plat-s3c24xx/include/plat/pm-core.h
new file mode 100644
index 000000000000..c75882113e04
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/pm-core.h
@@ -0,0 +1,59 @@
+/* linux/arch/arm/plat-s3c24xx/include/plat/pll.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C24xx - PM core support for arch/arm/plat-s3c/pm.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+ unsigned long tmp = __raw_readl(S3C2410_CLKCON);
+
+ /* re-start uart clocks */
+ tmp |= S3C2410_CLKCON_UART0;
+ tmp |= S3C2410_CLKCON_UART1;
+ tmp |= S3C2410_CLKCON_UART2;
+
+ __raw_writel(tmp, S3C2410_CLKCON);
+ udelay(10);
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+ __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
+ __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
+
+ /* ack any outstanding external interrupts before we go to sleep */
+
+ __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
+ __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
+ __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
+
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+ __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */
+}
+
+static void s3c_pm_show_resume_irqs(int start, unsigned long which,
+ unsigned long mask);
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+ S3C_PMDBG("post sleep: IRQs 0x%08x, 0x%08x\n",
+ __raw_readl(S3C2410_SRCPND),
+ __raw_readl(S3C2410_EINTPEND));
+
+ s3c_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
+ s3c_irqwake_intmask);
+
+ s3c_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
+ s3c_irqwake_eintmask);
+}
diff --git a/arch/arm/plat-s3c24xx/include/plat/pm.h b/arch/arm/plat-s3c24xx/include/plat/pm.h
deleted file mode 100644
index cc623667e48a..000000000000
--- a/arch/arm/plat-s3c24xx/include/plat/pm.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* linux/include/asm-arm/plat-s3c24xx/pm.h
- *
- * Copyright (c) 2004 Simtec Electronics
- * Written by Ben Dooks, <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* s3c2410_pm_init
- *
- * called from board at initialisation time to setup the power
- * management
-*/
-
-#ifdef CONFIG_PM
-
-extern __init int s3c2410_pm_init(void);
-
-#else
-
-static inline int s3c2410_pm_init(void)
-{
- return 0;
-}
-#endif
-
-/* configuration for the IRQ mask over sleep */
-extern unsigned long s3c_irqwake_intmask;
-extern unsigned long s3c_irqwake_eintmask;
-
-/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */
-extern unsigned long s3c_irqwake_intallow;
-extern unsigned long s3c_irqwake_eintallow;
-
-/* per-cpu sleep functions */
-
-extern void (*pm_cpu_prep)(void);
-extern void (*pm_cpu_sleep)(void);
-
-/* Flags for PM Control */
-
-extern unsigned long s3c_pm_flags;
-
-/* from sleep.S */
-
-extern int s3c2410_cpu_save(unsigned long *saveblk);
-extern void s3c2410_cpu_suspend(void);
-extern void s3c2410_cpu_resume(void);
-
-extern unsigned long s3c2410_sleep_save_phys;
-
-/* sleep save info */
-
-struct sleep_save {
- void __iomem *reg;
- unsigned long val;
-};
-
-#define SAVE_ITEM(x) \
- { .reg = (x) }
-
-extern void s3c2410_pm_do_save(struct sleep_save *ptr, int count);
-extern void s3c2410_pm_do_restore(struct sleep_save *ptr, int count);
-
-#ifdef CONFIG_PM
-extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
-extern int s3c24xx_irq_resume(struct sys_device *dev);
-#else
-#define s3c24xx_irq_suspend NULL
-#define s3c24xx_irq_resume NULL
-#endif
diff --git a/include/asm-arm/plat-s3c24xx/regs-iis.h b/arch/arm/plat-s3c24xx/include/plat/regs-iis.h
index a6f1d5df13b4..a6f1d5df13b4 100644
--- a/include/asm-arm/plat-s3c24xx/regs-iis.h
+++ b/arch/arm/plat-s3c24xx/include/plat/regs-iis.h
diff --git a/arch/arm/plat-s3c24xx/irq-pm.c b/arch/arm/plat-s3c24xx/irq-pm.c
new file mode 100644
index 000000000000..b7acf1a8ecd2
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/irq-pm.c
@@ -0,0 +1,95 @@
+/* linux/arch/arm/plat-s3c24xx/irq-om.c
+ *
+ * Copyright (c) 2003,2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C24XX - IRQ PM code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+
+unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
+unsigned long s3c_irqwake_eintallow = 0x0000fff0L;
+
+int s3c_irq_wake(unsigned int irqno, unsigned int state)
+{
+ unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
+
+ if (!(s3c_irqwake_intallow & irqbit))
+ return -ENOENT;
+
+ printk(KERN_INFO "wake %s for irq %d\n",
+ state ? "enabled" : "disabled", irqno);
+
+ if (!state)
+ s3c_irqwake_intmask |= irqbit;
+ else
+ s3c_irqwake_intmask &= ~irqbit;
+
+ return 0;
+}
+
+static struct sleep_save irq_save[] = {
+ SAVE_ITEM(S3C2410_INTMSK),
+ SAVE_ITEM(S3C2410_INTSUBMSK),
+};
+
+/* the extint values move between the s3c2410/s3c2440 and the s3c2412
+ * so we use an array to hold them, and to calculate the address of
+ * the register at run-time
+*/
+
+static unsigned long save_extint[3];
+static unsigned long save_eintflt[4];
+static unsigned long save_eintmask;
+
+int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+ save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
+
+ for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+ save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
+
+ s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+ save_eintmask = __raw_readl(S3C24XX_EINTMASK);
+
+ return 0;
+}
+
+int s3c24xx_irq_resume(struct sys_device *dev)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+ __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
+
+ for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+ __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
+
+ s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+ __raw_writel(save_eintmask, S3C24XX_EINTMASK);
+
+ return 0;
+}
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 0192ecdc1442..958737775ad2 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -1,6 +1,6 @@
/* linux/arch/arm/plat-s3c24xx/irq.c
*
- * Copyright (c) 2003,2004 Simtec Electronics
+ * Copyright (c) 2003,2004 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* This program is free software; you can redistribute it and/or modify
@@ -16,38 +16,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Changelog:
- *
- * 22-Jul-2004 Ben Dooks <ben@simtec.co.uk>
- * Fixed compile warnings
- *
- * 22-Jul-2004 Roc Wu <cooloney@yahoo.com.cn>
- * Fixed s3c_extirq_type
- *
- * 21-Jul-2004 Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
- * Addition of ADC/TC demux
- *
- * 04-Oct-2004 Klaus Fetscher <k.fetscher@fetron.de>
- * Fix for set_irq_type() on low EINT numbers
- *
- * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk>
- * Tidy up KF's patch and sort out new release
- *
- * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk>
- * Add support for power management controls
- *
- * 04-Nov-2004 Ben Dooks
- * Fix standard IRQ wake for EINT0..4 and RTC
- *
- * 22-Feb-2005 Ben Dooks
- * Fixed edge-triggering on ADC IRQ
- *
- * 28-Jun-2005 Ben Dooks
- * Mark IRQ_LCD valid
- *
- * 25-Jul-2005 Ben Dooks
- * Split the S3C2440 IRQ code to separate file
*/
#include <linux/init.h>
@@ -55,81 +23,16 @@
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/sysdev.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
#include <asm/irq.h>
-
#include <asm/mach/irq.h>
#include <plat/regs-irqtype.h>
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
#include <plat/cpu.h>
#include <plat/pm.h>
#include <plat/irq.h>
-/* wakeup irq control */
-
-#ifdef CONFIG_PM
-
-/* state for IRQs over sleep */
-
-/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
- *
- * set bit to 1 in allow bitfield to enable the wakeup settings on it
-*/
-
-unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
-unsigned long s3c_irqwake_intmask = 0xffffffffL;
-unsigned long s3c_irqwake_eintallow = 0x0000fff0L;
-unsigned long s3c_irqwake_eintmask = 0xffffffffL;
-
-int
-s3c_irq_wake(unsigned int irqno, unsigned int state)
-{
- unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
-
- if (!(s3c_irqwake_intallow & irqbit))
- return -ENOENT;
-
- printk(KERN_INFO "wake %s for irq %d\n",
- state ? "enabled" : "disabled", irqno);
-
- if (!state)
- s3c_irqwake_intmask |= irqbit;
- else
- s3c_irqwake_intmask &= ~irqbit;
-
- return 0;
-}
-
-static int
-s3c_irqext_wake(unsigned int irqno, unsigned int state)
-{
- unsigned long bit = 1L << (irqno - EXTINT_OFF);
-
- if (!(s3c_irqwake_eintallow & bit))
- return -ENOENT;
-
- printk(KERN_INFO "wake %s for irq %d\n",
- state ? "enabled" : "disabled", irqno);
-
- if (!state)
- s3c_irqwake_eintmask |= bit;
- else
- s3c_irqwake_eintmask &= ~bit;
-
- return 0;
-}
-
-#else
-#define s3c_irqext_wake NULL
-#define s3c_irq_wake NULL
-#endif
-
-
static void
s3c_irq_mask(unsigned int irqno)
{
@@ -590,59 +493,6 @@ s3c_irq_demux_extint4t7(unsigned int irq,
}
}
-#ifdef CONFIG_PM
-
-static struct sleep_save irq_save[] = {
- SAVE_ITEM(S3C2410_INTMSK),
- SAVE_ITEM(S3C2410_INTSUBMSK),
-};
-
-/* the extint values move between the s3c2410/s3c2440 and the s3c2412
- * so we use an array to hold them, and to calculate the address of
- * the register at run-time
-*/
-
-static unsigned long save_extint[3];
-static unsigned long save_eintflt[4];
-static unsigned long save_eintmask;
-
-int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(save_extint); i++)
- save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
-
- for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
- save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
-
- s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
- save_eintmask = __raw_readl(S3C24XX_EINTMASK);
-
- return 0;
-}
-
-int s3c24xx_irq_resume(struct sys_device *dev)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(save_extint); i++)
- __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
-
- for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
- __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
-
- s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
- __raw_writel(save_eintmask, S3C24XX_EINTMASK);
-
- return 0;
-}
-
-#else
-#define s3c24xx_irq_suspend NULL
-#define s3c24xx_irq_resume NULL
-#endif
-
/* s3c24xx_init_irq
*
* Initialise S3C2410 IRQ system
diff --git a/arch/arm/plat-s3c24xx/pm-simtec.c b/arch/arm/plat-s3c24xx/pm-simtec.c
index 21dfa74773d1..da0d3217d3e3 100644
--- a/arch/arm/plat-s3c24xx/pm-simtec.c
+++ b/arch/arm/plat-s3c24xx/pm-simtec.c
@@ -61,7 +61,7 @@ static __init int pm_simtec_init(void)
__raw_writel(gstatus4, S3C2410_GSTATUS4);
- return s3c2410_pm_init();
+ return s3c_pm_init();
}
arch_initcall(pm_simtec_init);
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
index 34ef18e5b2a1..062a29339a91 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -31,14 +31,9 @@
#include <linux/errno.h>
#include <linux/time.h>
#include <linux/interrupt.h>
-#include <linux/crc32.h>
-#include <linux/ioport.h>
#include <linux/serial_core.h>
#include <linux/io.h>
-#include <asm/cacheflush.h>
-#include <mach/hardware.h>
-
#include <plat/regs-serial.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
@@ -49,10 +44,6 @@
#include <plat/pm.h>
-/* for external use */
-
-unsigned long s3c_pm_flags;
-
#define PFX "s3c24xx-pm: "
static struct sleep_save core_save[] = {
@@ -120,328 +111,14 @@ static struct sleep_save misc_save[] = {
SAVE_ITEM(S3C2410_DCLKCON),
};
-#ifdef CONFIG_S3C2410_PM_DEBUG
-
-#define SAVE_UART(va) \
- SAVE_ITEM((va) + S3C2410_ULCON), \
- SAVE_ITEM((va) + S3C2410_UCON), \
- SAVE_ITEM((va) + S3C2410_UFCON), \
- SAVE_ITEM((va) + S3C2410_UMCON), \
- SAVE_ITEM((va) + S3C2410_UBRDIV)
-
-static struct sleep_save uart_save[] = {
- SAVE_UART(S3C24XX_VA_UART0),
- SAVE_UART(S3C24XX_VA_UART1),
-#ifndef CONFIG_CPU_S3C2400
- SAVE_UART(S3C24XX_VA_UART2),
-#endif
-};
-
-/* debug
- *
- * we send the debug to printascii() to allow it to be seen if the
- * system never wakes up from the sleep
-*/
-
-extern void printascii(const char *);
-
-void pm_dbg(const char *fmt, ...)
-{
- va_list va;
- char buff[256];
-
- va_start(va, fmt);
- vsprintf(buff, fmt, va);
- va_end(va);
-
- printascii(buff);
-}
-
-static void s3c2410_pm_debug_init(void)
-{
- unsigned long tmp = __raw_readl(S3C2410_CLKCON);
-
- /* re-start uart clocks */
- tmp |= S3C2410_CLKCON_UART0;
- tmp |= S3C2410_CLKCON_UART1;
- tmp |= S3C2410_CLKCON_UART2;
-
- __raw_writel(tmp, S3C2410_CLKCON);
- udelay(10);
-}
-
-#define DBG(fmt...) pm_dbg(fmt)
-#else
-#define DBG(fmt...) printk(KERN_DEBUG fmt)
-
-#define s3c2410_pm_debug_init() do { } while(0)
-
-static struct sleep_save uart_save[] = {};
-#endif
-
-#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0
-
-/* suspend checking code...
- *
- * this next area does a set of crc checks over all the installed
- * memory, so the system can verify if the resume was ok.
- *
- * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
- * increasing it will mean that the area corrupted will be less easy to spot,
- * and reducing the size will cause the CRC save area to grow
-*/
-
-#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024)
-
-static u32 crc_size; /* size needed for the crc block */
-static u32 *crcs; /* allocated over suspend/resume */
-
-typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
-
-/* s3c2410_pm_run_res
- *
- * go thorugh the given resource list, and look for system ram
-*/
-
-static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
-{
- while (ptr != NULL) {
- if (ptr->child != NULL)
- s3c2410_pm_run_res(ptr->child, fn, arg);
-
- if ((ptr->flags & IORESOURCE_MEM) &&
- strcmp(ptr->name, "System RAM") == 0) {
- DBG("Found system RAM at %08lx..%08lx\n",
- ptr->start, ptr->end);
- arg = (fn)(ptr, arg);
- }
-
- ptr = ptr->sibling;
- }
-}
-
-static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg)
-{
- s3c2410_pm_run_res(&iomem_resource, fn, arg);
-}
-
-static u32 *s3c2410_pm_countram(struct resource *res, u32 *val)
-{
- u32 size = (u32)(res->end - res->start)+1;
-
- size += CHECK_CHUNKSIZE-1;
- size /= CHECK_CHUNKSIZE;
-
- DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size);
-
- *val += size * sizeof(u32);
- return val;
-}
-
-/* s3c2410_pm_prepare_check
- *
- * prepare the necessary information for creating the CRCs. This
- * must be done before the final save, as it will require memory
- * allocating, and thus touching bits of the kernel we do not
- * know about.
-*/
-
-static void s3c2410_pm_check_prepare(void)
-{
- crc_size = 0;
-
- s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size);
-
- DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size);
-
- crcs = kmalloc(crc_size+4, GFP_KERNEL);
- if (crcs == NULL)
- printk(KERN_ERR "Cannot allocated CRC save area\n");
-}
-
-static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val)
-{
- unsigned long addr, left;
-
- for (addr = res->start; addr < res->end;
- addr += CHECK_CHUNKSIZE) {
- left = res->end - addr;
-
- if (left > CHECK_CHUNKSIZE)
- left = CHECK_CHUNKSIZE;
-
- *val = crc32_le(~0, phys_to_virt(addr), left);
- val++;
- }
-
- return val;
-}
-
-/* s3c2410_pm_check_store
- *
- * compute the CRC values for the memory blocks before the final
- * sleep.
-*/
-
-static void s3c2410_pm_check_store(void)
-{
- if (crcs != NULL)
- s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs);
-}
-
-/* in_region
- *
- * return TRUE if the area defined by ptr..ptr+size contatins the
- * what..what+whatsz
-*/
-
-static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
-{
- if ((what+whatsz) < ptr)
- return 0;
-
- if (what > (ptr+size))
- return 0;
-
- return 1;
-}
-
-static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val)
-{
- void *save_at = phys_to_virt(s3c2410_sleep_save_phys);
- unsigned long addr;
- unsigned long left;
- void *ptr;
- u32 calc;
-
- for (addr = res->start; addr < res->end;
- addr += CHECK_CHUNKSIZE) {
- left = res->end - addr;
-
- if (left > CHECK_CHUNKSIZE)
- left = CHECK_CHUNKSIZE;
-
- ptr = phys_to_virt(addr);
-
- if (in_region(ptr, left, crcs, crc_size)) {
- DBG("skipping %08lx, has crc block in\n", addr);
- goto skip_check;
- }
-
- if (in_region(ptr, left, save_at, 32*4 )) {
- DBG("skipping %08lx, has save block in\n", addr);
- goto skip_check;
- }
-
- /* calculate and check the checksum */
-
- calc = crc32_le(~0, ptr, left);
- if (calc != *val) {
- printk(KERN_ERR PFX "Restore CRC error at "
- "%08lx (%08x vs %08x)\n", addr, calc, *val);
-
- DBG("Restore CRC error at %08lx (%08x vs %08x)\n",
- addr, calc, *val);
- }
-
- skip_check:
- val++;
- }
-
- return val;
-}
-
-/* s3c2410_pm_check_restore
- *
- * check the CRCs after the restore event and free the memory used
- * to hold them
-*/
-
-static void s3c2410_pm_check_restore(void)
-{
- if (crcs != NULL) {
- s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs);
- kfree(crcs);
- crcs = NULL;
- }
-}
-
-#else
-
-#define s3c2410_pm_check_prepare() do { } while(0)
-#define s3c2410_pm_check_restore() do { } while(0)
-#define s3c2410_pm_check_store() do { } while(0)
-#endif
-
-/* helper functions to save and restore register state */
-
-void s3c2410_pm_do_save(struct sleep_save *ptr, int count)
-{
- for (; count > 0; count--, ptr++) {
- ptr->val = __raw_readl(ptr->reg);
- DBG("saved %p value %08lx\n", ptr->reg, ptr->val);
- }
-}
-
-/* s3c2410_pm_do_restore
- *
- * restore the system from the given list of saved registers
- *
- * Note, we do not use DBG() in here, as the system may not have
- * restore the UARTs state yet
-*/
-
-void s3c2410_pm_do_restore(struct sleep_save *ptr, int count)
-{
- for (; count > 0; count--, ptr++) {
- printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
- ptr->reg, ptr->val, __raw_readl(ptr->reg));
-
- __raw_writel(ptr->val, ptr->reg);
- }
-}
-
-/* s3c2410_pm_do_restore_core
- *
- * similar to s3c2410_pm_do_restore_core
- *
- * WARNING: Do not put any debug in here that may effect memory or use
- * peripherals, as things may be changing!
-*/
-
-static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count)
-{
- for (; count > 0; count--, ptr++) {
- __raw_writel(ptr->val, ptr->reg);
- }
-}
-/* s3c2410_pm_show_resume_irqs
- *
- * print any IRQs asserted at resume time (ie, we woke from)
-*/
-
-static void s3c2410_pm_show_resume_irqs(int start, unsigned long which,
- unsigned long mask)
-{
- int i;
-
- which &= ~mask;
-
- for (i = 0; i <= 31; i++) {
- if ((which) & (1L<<i)) {
- DBG("IRQ %d asserted at resume\n", start+i);
- }
- }
-}
-
-/* s3c2410_pm_check_resume_pin
+/* s3c_pm_check_resume_pin
*
* check to see if the pin is configured correctly for sleep mode, and
* make any necessary adjustments if it is not
*/
-static void s3c2410_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
+static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
{
unsigned long irqstate;
unsigned long pinstate;
@@ -456,21 +133,21 @@ static void s3c2410_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
if (!irqstate) {
if (pinstate == S3C2410_GPIO_IRQ)
- DBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
+ S3C_PMDBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
} else {
if (pinstate == S3C2410_GPIO_IRQ) {
- DBG("Disabling IRQ %d (pin %d)\n", irq, pin);
+ S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin);
s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
}
}
}
-/* s3c2410_pm_configure_extint
+/* s3c_pm_configure_extint
*
* configure all external interrupt pins
*/
-static void s3c2410_pm_configure_extint(void)
+void s3c_pm_configure_extint(void)
{
int pin;
@@ -480,11 +157,11 @@ static void s3c2410_pm_configure_extint(void)
*/
for (pin = S3C2410_GPF0; pin <= S3C2410_GPF7; pin++) {
- s3c2410_pm_check_resume_pin(pin, pin - S3C2410_GPF0);
+ s3c_pm_check_resume_pin(pin, pin - S3C2410_GPF0);
}
for (pin = S3C2410_GPG0; pin <= S3C2410_GPG7; pin++) {
- s3c2410_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8);
+ s3c_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8);
}
}
@@ -494,12 +171,12 @@ static void s3c2410_pm_configure_extint(void)
#define OFFS_DAT (S3C2410_GPADAT - S3C2410_GPACON)
#define OFFS_UP (S3C2410_GPBUP - S3C2410_GPBCON)
-/* s3c2410_pm_save_gpios()
+/* s3c_pm_save_gpios()
*
* Save the state of the GPIOs
*/
-static void s3c2410_pm_save_gpios(void)
+void s3c_pm_save_gpios(void)
{
struct gpio_sleep *gps = gpio_save;
unsigned int gpio;
@@ -538,7 +215,10 @@ static inline int is_out(unsigned long con)
return con == 1;
}
-/* s3c2410_pm_restore_gpio()
+/**
+ * s3c2410_pm_restore_gpio() - restore the given GPIO bank
+ * @index: The number of the GPIO bank being resumed.
+ * @gps: The sleep confgiuration for the bank.
*
* Restore one of the GPIO banks that was saved during suspend. This is
* not as simple as once thought, due to the possibility of glitches
@@ -646,8 +326,8 @@ static void s3c2410_pm_restore_gpio(int index, struct gpio_sleep *gps)
__raw_writel(gps->gpup, base + OFFS_UP);
}
- DBG("GPIO[%d] CON %08lx => %08lx, DAT %08lx => %08lx\n",
- index, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
+ S3C_PMDBG("GPIO[%d] CON %08lx => %08lx, DAT %08lx => %08lx\n",
+ index, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
}
@@ -656,7 +336,7 @@ static void s3c2410_pm_restore_gpio(int index, struct gpio_sleep *gps)
* Restore the state of the GPIOs
*/
-static void s3c2410_pm_restore_gpios(void)
+void s3c_pm_restore_gpios(void)
{
struct gpio_sleep *gps = gpio_save;
int gpio;
@@ -666,150 +346,15 @@ static void s3c2410_pm_restore_gpios(void)
}
}
-void (*pm_cpu_prep)(void);
-void (*pm_cpu_sleep)(void);
-
-#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
-
-/* s3c2410_pm_enter
- *
- * central control for sleep/resume process
-*/
-
-static int s3c2410_pm_enter(suspend_state_t state)
+void s3c_pm_restore_core(void)
{
- unsigned long regs_save[16];
-
- /* ensure the debug is initialised (if enabled) */
-
- s3c2410_pm_debug_init();
-
- DBG("s3c2410_pm_enter(%d)\n", state);
-
- if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
- printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
- return -EINVAL;
- }
-
- /* check if we have anything to wake-up with... bad things seem
- * to happen if you suspend with no wakeup (system will often
- * require a full power-cycle)
- */
-
- if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
- !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
- printk(KERN_ERR PFX "No sources enabled for wake-up!\n");
- printk(KERN_ERR PFX "Aborting sleep\n");
- return -EINVAL;
- }
-
- /* prepare check area if configured */
-
- s3c2410_pm_check_prepare();
-
- /* store the physical address of the register recovery block */
-
- s3c2410_sleep_save_phys = virt_to_phys(regs_save);
-
- DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys);
-
- /* save all necessary core registers not covered by the drivers */
-
- s3c2410_pm_save_gpios();
- s3c2410_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
- s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
- s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
-
- /* set the irq configuration for wake */
-
- s3c2410_pm_configure_extint();
-
- DBG("sleep: irq wakeup masks: %08lx,%08lx\n",
- s3c_irqwake_intmask, s3c_irqwake_eintmask);
-
- __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
- __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
-
- /* ack any outstanding external interrupts before we go to sleep */
-
- __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
- __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
- __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
-
- /* call cpu specific preparation */
-
- pm_cpu_prep();
-
- /* flush cache back to ram */
-
- flush_cache_all();
-
- s3c2410_pm_check_store();
-
- /* send the cpu to sleep... */
-
- __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */
-
- /* s3c2410_cpu_save will also act as our return point from when
- * we resume as it saves its own register state, so use the return
- * code to differentiate return from save and return from sleep */
-
- if (s3c2410_cpu_save(regs_save) == 0) {
- flush_cache_all();
- pm_cpu_sleep();
- }
-
- /* restore the cpu state */
-
- cpu_init();
-
- /* restore the system state */
-
- s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
- s3c2410_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
- s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
- s3c2410_pm_restore_gpios();
-
- s3c2410_pm_debug_init();
-
- /* check what irq (if any) restored the system */
-
- DBG("post sleep: IRQs 0x%08x, 0x%08x\n",
- __raw_readl(S3C2410_SRCPND),
- __raw_readl(S3C2410_EINTPEND));
-
- s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
- s3c_irqwake_intmask);
-
- s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
- s3c_irqwake_eintmask);
-
- DBG("post sleep, preparing to return\n");
-
- s3c2410_pm_check_restore();
-
- /* ok, let's return from sleep */
-
- DBG("S3C2410 PM Resume (post-restore)\n");
- return 0;
+ s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+ s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
}
-static struct platform_suspend_ops s3c2410_pm_ops = {
- .enter = s3c2410_pm_enter,
- .valid = suspend_valid_only_mem,
-};
-
-/* s3c2410_pm_init
- *
- * Attach the power management functions. This should be called
- * from the board specific initialisation if the board supports
- * it.
-*/
-
-int __init s3c2410_pm_init(void)
+void s3c_pm_save_core(void)
{
- printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n");
-
- suspend_set_ops(&s3c2410_pm_ops);
- return 0;
+ s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
+ s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
}
+
diff --git a/arch/arm/plat-s3c24xx/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c
index c1de6bb0101b..1364317d421e 100644
--- a/arch/arm/plat-s3c24xx/s3c244x.c
+++ b/arch/arm/plat-s3c24xx/s3c244x.c
@@ -145,13 +145,13 @@ static struct sleep_save s3c244x_sleep[] = {
static int s3c244x_suspend(struct sys_device *dev, pm_message_t state)
{
- s3c2410_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+ s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
return 0;
}
static int s3c244x_resume(struct sys_device *dev)
{
- s3c2410_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+ s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
return 0;
}
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S
index 76594b212802..e73e3b6e88d2 100644
--- a/arch/arm/plat-s3c24xx/sleep.S
+++ b/arch/arm/plat-s3c24xx/sleep.S
@@ -41,25 +41,13 @@
.text
- /* s3c2410_cpu_save
- *
- * save enough of the CPU state to allow us to re-start
- * pm.c code. as we store items like the sp/lr, we will
- * end up returning from this function when the cpu resumes
- * so the return value is set to mark this.
- *
- * This arangement means we avoid having to flush the cache
- * from this code.
+ /* s3c_cpu_save
*
* entry:
- * r0 = pointer to save block
- *
- * exit:
- * r0 = 0 => we stored everything
- * 1 => resumed from sleep
+ * r0 = save address (virtual addr of s3c_sleep_save_phys)
*/
-ENTRY(s3c2410_cpu_save)
+ENTRY(s3c_cpu_save)
stmfd sp!, { r4 - r12, lr }
@@ store co-processor registers
@@ -71,20 +59,25 @@ ENTRY(s3c2410_cpu_save)
stmia r0, { r4 - r13 }
- mov r0, #0
- ldmfd sp, { r4 - r12, pc }
+ @@ write our state back to RAM
+ bl s3c_pm_cb_flushcache
+ @@ jump to final code to send system to sleep
+ ldr r0, =pm_cpu_sleep
+ @@ldr pc, [ r0 ]
+ ldr r0, [ r0 ]
+ mov pc, r0
+
@@ return to the caller, after having the MMU
@@ turned on, this restores the last bits from the
@@ stack
resume_with_mmu:
- mov r0, #1
ldmfd sp!, { r4 - r12, pc }
.ltorg
@@ the next bits sit in the .data segment, even though they
- @@ happen to be code... the s3c2410_sleep_save_phys needs to be
+ @@ happen to be code... the s3c_sleep_save_phys needs to be
@@ accessed by the resume code before it can restore the MMU.
@@ This means that the variable has to be close enough for the
@@ code to read it... since the .text segment needs to be RO,
@@ -92,19 +85,19 @@ resume_with_mmu:
.data
- .global s3c2410_sleep_save_phys
-s3c2410_sleep_save_phys:
+ .global s3c_sleep_save_phys
+s3c_sleep_save_phys:
.word 0
/* sleep magic, to allow the bootloader to check for an valid
* image to resume to. Must be the first word before the
- * s3c2410_cpu_resume entry.
+ * s3c_cpu_resume entry.
*/
.word 0x2bedf00d
- /* s3c2410_cpu_resume
+ /* s3c_cpu_resume
*
* resume code entry for bootloader to call
*
@@ -113,7 +106,7 @@ s3c2410_sleep_save_phys:
* must not write to the code segment (code is read-only)
*/
-ENTRY(s3c2410_cpu_resume)
+ENTRY(s3c_cpu_resume)
mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
msr cpsr_c, r0
@@ -145,7 +138,7 @@ ENTRY(s3c2410_cpu_resume)
mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs
mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches
- ldr r0, s3c2410_sleep_save_phys @ address of restore block
+ ldr r0, s3c_sleep_save_phys @ address of restore block
ldmia r0, { r4 - r13 }
mcr p15, 0, r4, c13, c0, 0 @ PID
diff --git a/arch/arm/plat-s3c64xx/cpu.c b/arch/arm/plat-s3c64xx/cpu.c
index fbde183a4560..91f49a3a665d 100644
--- a/arch/arm/plat-s3c64xx/cpu.c
+++ b/arch/arm/plat-s3c64xx/cpu.c
@@ -96,6 +96,11 @@ static struct map_desc s3c_iodesc[] __initdata = {
.pfn = __phys_to_pfn(S3C64XX_PA_GPIO),
.length = SZ_4K,
.type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C64XX_VA_MODEM,
+ .pfn = __phys_to_pfn(S3C64XX_PA_MODEM),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
},
};
diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h b/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h
new file mode 100644
index 000000000000..82342f6fd27d
--- /dev/null
+++ b/arch/arm/plat-s3c64xx/include/plat/regs-gpio-memport.h
@@ -0,0 +1,25 @@
+/* linux/arch/arm/plat-s3c64xx/include/mach/regs-gpio-memport.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - GPIO memory port register definitions
+ */
+
+#ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H
+#define __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H __FILE__
+
+#define S3C64XX_MEM0CONSTOP S3C64XX_GPIOREG(0x1B0)
+#define S3C64XX_MEM1CONSTOP S3C64XX_GPIOREG(0x1B4)
+
+#define S3C64XX_MEM0CONSLP0 S3C64XX_GPIOREG(0x1C0)
+#define S3C64XX_MEM0CONSLP1 S3C64XX_GPIOREG(0x1C4)
+#define S3C64XX_MEM1CONSLP S3C64XX_GPIOREG(0x1C8)
+
+#define S3C64XX_MEM0DRVCON S3C64XX_GPIOREG(0x1D0)
+#define S3C64XX_MEM1DRVCON S3C64XX_GPIOREG(0x1D4)
+
+#endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H */
+
diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h b/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h
index 75b873d82808..81f7f6e6832e 100644
--- a/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h
+++ b/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h
@@ -13,23 +13,175 @@
/* Base addresses for each of the banks */
-#define S3C64XX_GPA_BASE (S3C64XX_VA_GPIO + 0x0000)
-#define S3C64XX_GPB_BASE (S3C64XX_VA_GPIO + 0x0020)
-#define S3C64XX_GPC_BASE (S3C64XX_VA_GPIO + 0x0040)
-#define S3C64XX_GPD_BASE (S3C64XX_VA_GPIO + 0x0060)
-#define S3C64XX_GPE_BASE (S3C64XX_VA_GPIO + 0x0080)
-#define S3C64XX_GPF_BASE (S3C64XX_VA_GPIO + 0x00A0)
-#define S3C64XX_GPG_BASE (S3C64XX_VA_GPIO + 0x00C0)
-#define S3C64XX_GPH_BASE (S3C64XX_VA_GPIO + 0x00E0)
-#define S3C64XX_GPI_BASE (S3C64XX_VA_GPIO + 0x0100)
-#define S3C64XX_GPJ_BASE (S3C64XX_VA_GPIO + 0x0120)
-#define S3C64XX_GPK_BASE (S3C64XX_VA_GPIO + 0x0800)
-#define S3C64XX_GPL_BASE (S3C64XX_VA_GPIO + 0x0810)
-#define S3C64XX_GPM_BASE (S3C64XX_VA_GPIO + 0x0820)
-#define S3C64XX_GPN_BASE (S3C64XX_VA_GPIO + 0x0830)
-#define S3C64XX_GPO_BASE (S3C64XX_VA_GPIO + 0x0140)
-#define S3C64XX_GPP_BASE (S3C64XX_VA_GPIO + 0x0160)
-#define S3C64XX_GPQ_BASE (S3C64XX_VA_GPIO + 0x0180)
+#define S3C64XX_GPIOREG(reg) (S3C64XX_VA_GPIO + (reg))
+
+#define S3C64XX_GPA_BASE S3C64XX_GPIOREG(0x0000)
+#define S3C64XX_GPB_BASE S3C64XX_GPIOREG(0x0020)
+#define S3C64XX_GPC_BASE S3C64XX_GPIOREG(0x0040)
+#define S3C64XX_GPD_BASE S3C64XX_GPIOREG(0x0060)
+#define S3C64XX_GPE_BASE S3C64XX_GPIOREG(0x0080)
+#define S3C64XX_GPF_BASE S3C64XX_GPIOREG(0x00A0)
+#define S3C64XX_GPG_BASE S3C64XX_GPIOREG(0x00C0)
+#define S3C64XX_GPH_BASE S3C64XX_GPIOREG(0x00E0)
+#define S3C64XX_GPI_BASE S3C64XX_GPIOREG(0x0100)
+#define S3C64XX_GPJ_BASE S3C64XX_GPIOREG(0x0120)
+#define S3C64XX_GPK_BASE S3C64XX_GPIOREG(0x0800)
+#define S3C64XX_GPL_BASE S3C64XX_GPIOREG(0x0810)
+#define S3C64XX_GPM_BASE S3C64XX_GPIOREG(0x0820)
+#define S3C64XX_GPN_BASE S3C64XX_GPIOREG(0x0830)
+#define S3C64XX_GPO_BASE S3C64XX_GPIOREG(0x0140)
+#define S3C64XX_GPP_BASE S3C64XX_GPIOREG(0x0160)
+#define S3C64XX_GPQ_BASE S3C64XX_GPIOREG(0x0180)
+
+/* SPCON */
+
+#define S3C64XX_SPCON S3C64XX_GPIOREG(0x1A0)
+
+#define S3C64XX_SPCON_DRVCON_CAM_MASK (0x3 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_SHIFT (30)
+#define S3C64XX_SPCON_DRVCON_CAM_2mA (0x0 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_4mA (0x1 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_7mA (0x2 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_9mA (0x3 << 30)
+
+#define S3C64XX_SPCON_DRVCON_HSSPI_MASK (0x3 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_SHIFT (28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_2mA (0x0 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_4mA (0x1 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_7mA (0x2 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_9mA (0x3 << 28)
+
+#define S3C64XX_SPCON_DRVCON_HSMMC_MASK (0x3 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_SHIFT (26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_2mA (0x0 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_4mA (0x1 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_7mA (0x2 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_9mA (0x3 << 26)
+
+#define S3C64XX_SPCON_DRVCON_LCD_MASK (0x3 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_SHIFT (24)
+#define S3C64XX_SPCON_DRVCON_LCD_2mA (0x0 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_4mA (0x1 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_7mA (0x2 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_9mA (0x3 << 24)
+
+#define S3C64XX_SPCON_DRVCON_MODEM_MASK (0x3 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_SHIFT (22)
+#define S3C64XX_SPCON_DRVCON_MODEM_2mA (0x0 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_4mA (0x1 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_7mA (0x2 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_9mA (0x3 << 22)
+
+#define S3C64XX_SPCON_nRSTOUT_OEN (1 << 21)
+
+#define S3C64XX_SPCON_DRVCON_SPICLK1_MASK (0x3 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_SHIFT (18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_2mA (0x0 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_4mA (0x1 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_7mA (0x2 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_9mA (0x3 << 18)
+
+#define S3C64XX_SPCON_MEM1_DQS_PUD_MASK (0x3 << 16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_SHIFT (16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_DISABLED (0x0 << 16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_DOWN (0x1 << 16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_UP (0x2 << 16)
+
+#define S3C64XX_SPCON_MEM1_D_PUD1_MASK (0x3 << 14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_SHIFT (14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_DISABLED (0x0 << 14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_DOWN (0x1 << 14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_UP (0x2 << 14)
+
+#define S3C64XX_SPCON_MEM1_D_PUD0_MASK (0x3 << 12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_SHIFT (12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_DISABLED (0x0 << 12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_DOWN (0x1 << 12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_UP (0x2 << 12)
+
+#define S3C64XX_SPCON_MEM0_D_PUD_MASK (0x3 << 8)
+#define S3C64XX_SPCON_MEM0_D_PUD_SHIFT (8)
+#define S3C64XX_SPCON_MEM0_D_PUD_DISABLED (0x0 << 8)
+#define S3C64XX_SPCON_MEM0_D_PUD_DOWN (0x1 << 8)
+#define S3C64XX_SPCON_MEM0_D_PUD_UP (0x2 << 8)
+
+#define S3C64XX_SPCON_USBH_DMPD (1 << 7)
+#define S3C64XX_SPCON_USBH_DPPD (1 << 6)
+#define S3C64XX_SPCON_USBH_PUSW2 (1 << 5)
+#define S3C64XX_SPCON_USBH_PUSW1 (1 << 4)
+#define S3C64XX_SPCON_USBH_SUSPND (1 << 3)
+
+#define S3C64XX_SPCON_LCD_SEL_MASK (0x3 << 0)
+#define S3C64XX_SPCON_LCD_SEL_SHIFT (0)
+#define S3C64XX_SPCON_LCD_SEL_HOST (0x0 << 0)
+#define S3C64XX_SPCON_LCD_SEL_RGB (0x1 << 0)
+#define S3C64XX_SPCON_LCD_SEL_606_656 (0x2 << 0)
+
+
+/* External interrupt registers */
+
+#define S3C64XX_EINT12CON S3C64XX_GPIOREG(0x200)
+#define S3C64XX_EINT34CON S3C64XX_GPIOREG(0x204)
+#define S3C64XX_EINT56CON S3C64XX_GPIOREG(0x208)
+#define S3C64XX_EINT78CON S3C64XX_GPIOREG(0x20C)
+#define S3C64XX_EINT9CON S3C64XX_GPIOREG(0x210)
+
+#define S3C64XX_EINT12FLTCON S3C64XX_GPIOREG(0x220)
+#define S3C64XX_EINT34FLTCON S3C64XX_GPIOREG(0x224)
+#define S3C64XX_EINT56FLTCON S3C64XX_GPIOREG(0x228)
+#define S3C64XX_EINT78FLTCON S3C64XX_GPIOREG(0x22C)
+#define S3C64XX_EINT9FLTCON S3C64XX_GPIOREG(0x230)
+
+#define S3C64XX_EINT12MASK S3C64XX_GPIOREG(0x240)
+#define S3C64XX_EINT34MASK S3C64XX_GPIOREG(0x244)
+#define S3C64XX_EINT56MASK S3C64XX_GPIOREG(0x248)
+#define S3C64XX_EINT78MASK S3C64XX_GPIOREG(0x24C)
+#define S3C64XX_EINT9MASK S3C64XX_GPIOREG(0x250)
+
+#define S3C64XX_EINT12PEND S3C64XX_GPIOREG(0x260)
+#define S3C64XX_EINT34PEND S3C64XX_GPIOREG(0x264)
+#define S3C64XX_EINT56PEND S3C64XX_GPIOREG(0x268)
+#define S3C64XX_EINT78PEND S3C64XX_GPIOREG(0x26C)
+#define S3C64XX_EINT9PEND S3C64XX_GPIOREG(0x270)
+
+#define S3C64XX_PRIORITY S3C64XX_GPIOREG(0x280)
+#define S3C64XX_PRIORITY_ARB(x) (1 << (x))
+
+#define S3C64XX_SERVICE S3C64XX_GPIOREG(0x284)
+#define S3C64XX_SERVICEPEND S3C64XX_GPIOREG(0x288)
+
+#define S3C64XX_EINT0CON0 S3C64XX_GPIOREG(0x900)
+#define S3C64XX_EINT0CON1 S3C64XX_GPIOREG(0x904)
+#define S3C64XX_EINT0FLTCON0 S3C64XX_GPIOREG(0x910)
+#define S3C64XX_EINT0FLTCON1 S3C64XX_GPIOREG(0x914)
+#define S3C64XX_EINT0FLTCON2 S3C64XX_GPIOREG(0x918)
+#define S3C64XX_EINT0FLTCON3 S3C64XX_GPIOREG(0x91C)
+
+#define S3C64XX_EINT0MASK S3C64XX_GPIOREG(0x920)
+#define S3C64XX_EINT0PEND S3C64XX_GPIOREG(0x924)
+
+/* GPIO sleep configuration */
+
+#define S3C64XX_SPCONSLP S3C64XX_GPIOREG(0x880)
+
+#define S3C64XX_SPCONSLP_TDO_PULLDOWN (1 << 14)
+#define S3C64XX_SPCONSLP_CKE1INIT (1 << 5)
+
+#define S3C64XX_SPCONSLP_RSTOUT_MASK (0x3 << 12)
+#define S3C64XX_SPCONSLP_RSTOUT_OUT0 (0x0 << 12)
+#define S3C64XX_SPCONSLP_RSTOUT_OUT1 (0x1 << 12)
+#define S3C64XX_SPCONSLP_RSTOUT_HIZ (0x2 << 12)
+
+#define S3C64XX_SPCONSLP_KPCOL_MASK (0x3 << 0)
+#define S3C64XX_SPCONSLP_KPCOL_OUT0 (0x0 << 0)
+#define S3C64XX_SPCONSLP_KPCOL_OUT1 (0x1 << 0)
+#define S3C64XX_SPCONSLP_KPCOL_INP (0x2 << 0)
+
+
+#define S3C64XX_SLPEN S3C64XX_GPIOREG(0x930)
+
+#define S3C64XX_SLPEN_USE_xSLP (1 << 0)
+#define S3C64XX_SLPEN_CFG_BYSLPEN (1 << 1)
#endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_H */
diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-modem.h b/arch/arm/plat-s3c64xx/include/plat/regs-modem.h
new file mode 100644
index 000000000000..49f7759dedfa
--- /dev/null
+++ b/arch/arm/plat-s3c64xx/include/plat/regs-modem.h
@@ -0,0 +1,31 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-modem.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - modem block registers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_S3C64XX_REGS_MODEM_H
+#define __PLAT_S3C64XX_REGS_MODEM_H __FILE__
+
+#define S3C64XX_MODEMREG(x) (S3C64XX_VA_MODEM + (x))
+
+#define S3C64XX_MODEM_INT2AP S3C64XX_MODEMREG(0x0)
+#define S3C64XX_MODEM_INT2MODEM S3C64XX_MODEMREG(0x4)
+#define S3C64XX_MODEM_MIFCON S3C64XX_MODEMREG(0x8)
+#define S3C64XX_MODEM_MIFPCON S3C64XX_MODEMREG(0xC)
+#define S3C64XX_MODEM_INTCLR S3C64XX_MODEMREG(0x10)
+#define S3C64XX_MODEM_DMA_TXADDR S3C64XX_MODEMREG(0x14)
+#define S3C64XX_MODEM_DMA_RXADDR S3C64XX_MODEMREG(0x18)
+
+#define MIFPCON_INT2M_LEVEL (1 << 4)
+#define MIFPCON_LCD_BYPASS (1 << 3)
+
+#endif /* __PLAT_S3C64XX_REGS_MODEM_H */
diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-sys.h b/arch/arm/plat-s3c64xx/include/plat/regs-sys.h
index d8ed82917096..69b78d9f83b8 100644
--- a/arch/arm/plat-s3c64xx/include/plat/regs-sys.h
+++ b/arch/arm/plat-s3c64xx/include/plat/regs-sys.h
@@ -17,6 +17,10 @@
#define S3C_SYSREG(x) (S3C_VA_SYS + (x))
+#define S3C64XX_AHB_CON0 S3C_SYSREG(0x100)
+#define S3C64XX_AHB_CON1 S3C_SYSREG(0x104)
+#define S3C64XX_AHB_CON2 S3C_SYSREG(0x108)
+
#define S3C64XX_OTHERS S3C_SYSREG(0x900)
#define S3C64XX_OTHERS_USBMASK (1 << 16)
diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h b/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h
new file mode 100644
index 000000000000..270d96ac9705
--- /dev/null
+++ b/arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h
@@ -0,0 +1,116 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - syscon power and sleep control registers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __PLAT_S3C64XX_REGS_SYSCON_POWER_H
+#define __PLAT_S3C64XX_REGS_SYSCON_POWER_H __FILE__
+
+#define S3C64XX_PWR_CFG S3C_SYSREG(0x804)
+
+#define S3C64XX_PWRCFG_OSC_OTG_DISABLE (1 << 17)
+#define S3C64XX_PWRCFG_MMC2_DISABLE (1 << 16)
+#define S3C64XX_PWRCFG_MMC1_DISABLE (1 << 15)
+#define S3C64XX_PWRCFG_MMC0_DISABLE (1 << 14)
+#define S3C64XX_PWRCFG_HSI_DISABLE (1 << 13)
+#define S3C64XX_PWRCFG_TS_DISABLE (1 << 12)
+#define S3C64XX_PWRCFG_RTC_TICK_DISABLE (1 << 11)
+#define S3C64XX_PWRCFG_RTC_ALARM_DISABLE (1 << 10)
+#define S3C64XX_PWRCFG_MSM_DISABLE (1 << 9)
+#define S3C64XX_PWRCFG_KEY_DISABLE (1 << 8)
+#define S3C64XX_PWRCFG_BATF_DISABLE (1 << 7)
+
+#define S3C64XX_PWRCFG_CFG_WFI_MASK (0x3 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_SHIFT (5)
+#define S3C64XX_PWRCFG_CFG_WFI_IGNORE (0x0 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_IDLE (0x1 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_STOP (0x2 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_SLEEP (0x3 << 5)
+
+#define S3C64XX_PWRCFG_CFG_BATFLT_MASK (0x3 << 3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_SHIFT (3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_IGNORE (0x0 << 3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_IRQ (0x1 << 3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_SLEEP (0x3 << 3)
+
+#define S3C64XX_PWRCFG_CFG_BAT_WAKE (1 << 2)
+#define S3C64XX_PWRCFG_OSC27_EN (1 << 0)
+
+#define S3C64XX_EINT_MASK S3C_SYSREG(0x808)
+
+#define S3C64XX_NORMAL_CFG S3C_SYSREG(0x810)
+
+#define S3C64XX_NORMALCFG_IROM_ON (1 << 30)
+#define S3C64XX_NORMALCFG_DOMAIN_ETM_ON (1 << 16)
+#define S3C64XX_NORMALCFG_DOMAIN_S_ON (1 << 15)
+#define S3C64XX_NORMALCFG_DOMAIN_F_ON (1 << 14)
+#define S3C64XX_NORMALCFG_DOMAIN_P_ON (1 << 13)
+#define S3C64XX_NORMALCFG_DOMAIN_I_ON (1 << 12)
+#define S3C64XX_NORMALCFG_DOMAIN_G_ON (1 << 10)
+#define S3C64XX_NORMALCFG_DOMAIN_V_ON (1 << 9)
+
+#define S3C64XX_STOP_CFG S3C_SYSREG(0x814)
+
+#define S3C64XX_STOPCFG_MEMORY_ARM_ON (1 << 29)
+#define S3C64XX_STOPCFG_TOP_MEMORY_ON (1 << 20)
+#define S3C64XX_STOPCFG_ARM_LOGIC_ON (1 << 17)
+#define S3C64XX_STOPCFG_TOP_LOGIC_ON (1 << 8)
+#define S3C64XX_STOPCFG_OSC_EN (1 << 0)
+
+#define S3C64XX_SLEEP_CFG S3C_SYSREG(0x818)
+
+#define S3C64XX_SLEEPCFG_OSC_EN (1 << 0)
+
+#define S3C64XX_STOP_MEM_CFG S3C_SYSREG(0x81c)
+
+#define S3C64XX_STOPMEMCFG_MODEMIF_RETAIN (1 << 6)
+#define S3C64XX_STOPMEMCFG_HOSTIF_RETAIN (1 << 5)
+#define S3C64XX_STOPMEMCFG_OTG_RETAIN (1 << 4)
+#define S3C64XX_STOPMEMCFG_HSMCC_RETAIN (1 << 3)
+#define S3C64XX_STOPMEMCFG_IROM_RETAIN (1 << 2)
+#define S3C64XX_STOPMEMCFG_IRDA_RETAIN (1 << 1)
+#define S3C64XX_STOPMEMCFG_NFCON_RETAIN (1 << 0)
+
+#define S3C64XX_OSC_STABLE S3C_SYSREG(0x824)
+#define S3C64XX_PWR_STABLE S3C_SYSREG(0x828)
+
+#define S3C64XX_WAKEUP_STAT S3C_SYSREG(0x908)
+
+#define S3C64XX_WAKEUPSTAT_MMC2 (1 << 11)
+#define S3C64XX_WAKEUPSTAT_MMC1 (1 << 10)
+#define S3C64XX_WAKEUPSTAT_MMC0 (1 << 9)
+#define S3C64XX_WAKEUPSTAT_HSI (1 << 8)
+#define S3C64XX_WAKEUPSTAT_BATFLT (1 << 6)
+#define S3C64XX_WAKEUPSTAT_MSM (1 << 5)
+#define S3C64XX_WAKEUPSTAT_KEY (1 << 4)
+#define S3C64XX_WAKEUPSTAT_TS (1 << 3)
+#define S3C64XX_WAKEUPSTAT_RTC_TICK (1 << 2)
+#define S3C64XX_WAKEUPSTAT_RTC_ALARM (1 << 1)
+#define S3C64XX_WAKEUPSTAT_EINT (1 << 0)
+
+#define S3C64XX_BLK_PWR_STAT S3C_SYSREG(0x90c)
+
+#define S3C64XX_BLKPWRSTAT_G (1 << 7)
+#define S3C64XX_BLKPWRSTAT_ETM (1 << 6)
+#define S3C64XX_BLKPWRSTAT_S (1 << 5)
+#define S3C64XX_BLKPWRSTAT_F (1 << 4)
+#define S3C64XX_BLKPWRSTAT_P (1 << 3)
+#define S3C64XX_BLKPWRSTAT_I (1 << 2)
+#define S3C64XX_BLKPWRSTAT_V (1 << 1)
+#define S3C64XX_BLKPWRSTAT_TOP (1 << 0)
+
+#define S3C64XX_INFORM0 S3C_SYSREG(0xA00)
+#define S3C64XX_INFORM1 S3C_SYSREG(0xA04)
+#define S3C64XX_INFORM2 S3C_SYSREG(0xA08)
+#define S3C64XX_INFORM3 S3C_SYSREG(0xA0C)
+
+#endif /* __PLAT_S3C64XX_REGS_SYSCON_POWER_H */
diff --git a/arch/arm/plat-s3c64xx/irq-eint.c b/arch/arm/plat-s3c64xx/irq-eint.c
index cf524826c93a..47e5155bb13e 100644
--- a/arch/arm/plat-s3c64xx/irq-eint.c
+++ b/arch/arm/plat-s3c64xx/irq-eint.c
@@ -27,20 +27,6 @@
#include <mach/map.h>
#include <plat/cpu.h>
-/* GPIO is 0x7F008xxx, */
-#define S3C64XX_GPIOREG(x) (S3C64XX_VA_GPIO + (x))
-
-#define S3C64XX_EINT0CON0 S3C64XX_GPIOREG(0x900)
-#define S3C64XX_EINT0CON1 S3C64XX_GPIOREG(0x904)
-#define S3C64XX_EINT0FLTCON0 S3C64XX_GPIOREG(0x910)
-#define S3C64XX_EINT0FLTCON1 S3C64XX_GPIOREG(0x914)
-#define S3C64XX_EINT0FLTCON2 S3C64XX_GPIOREG(0x918)
-#define S3C64XX_EINT0FLTCON3 S3C64XX_GPIOREG(0x91C)
-
-#define S3C64XX_EINT0MASK S3C64XX_GPIOREG(0x920)
-#define S3C64XX_EINT0PEND S3C64XX_GPIOREG(0x924)
-
-
#define eint_offset(irq) ((irq) - IRQ_EINT(0))
#define eint_irq_to_bit(irq) (1 << eint_offset(irq))
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index b4211d8b2ac7..945e0d237a1d 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
#
# http://www.arm.linux.org.uk/developer/machines/?action=new
#
-# Last update: Thu Mar 12 18:01:45 2009
+# Last update: Mon Mar 23 20:09:01 2009
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -2124,3 +2124,11 @@ mx27wallace MACH_MX27WALLACE MX27WALLACE 2133
fmzwebmodul MACH_FMZWEBMODUL FMZWEBMODUL 2134
rd78x00_masa MACH_RD78X00_MASA RD78X00_MASA 2135
smallogger MACH_SMALLOGGER SMALLOGGER 2136
+ccw9p9215 MACH_CCW9P9215 CCW9P9215 2137
+dm355_leopard MACH_DM355_LEOPARD DM355_LEOPARD 2138
+ts219 MACH_TS219 TS219 2139
+tny_a9263 MACH_TNY_A9263 TNY_A9263 2140
+apollo MACH_APOLLO APOLLO 2141
+at91cap9stk MACH_AT91CAP9STK AT91CAP9STK 2142
+spc300 MACH_SPC300 SPC300 2143
+eko MACH_EKO EKO 2144
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
index ba592a9e6fb3..a2bed62aec21 100644
--- a/arch/arm/vfp/entry.S
+++ b/arch/arm/vfp/entry.S
@@ -15,13 +15,16 @@
* r10 = thread_info structure
* lr = failure return
*/
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <asm/asm-offsets.h>
-#include <asm/assembler.h>
+#include <asm/thread_info.h>
#include <asm/vfpmacros.h>
+#include "../kernel/entry-header.S"
ENTRY(do_vfp)
+#ifdef CONFIG_PREEMPT
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ add r11, r4, #1 @ increment it
+ str r11, [r10, #TI_PREEMPT]
+#endif
enable_irq
ldr r4, .LCvfp
ldr r11, [r10, #TI_CPU] @ CPU number
@@ -30,6 +33,12 @@ ENTRY(do_vfp)
ENDPROC(do_vfp)
ENTRY(vfp_null_entry)
+#ifdef CONFIG_PREEMPT
+ get_thread_info r10
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ sub r11, r4, #1 @ decrement it
+ str r11, [r10, #TI_PREEMPT]
+#endif
mov pc, lr
ENDPROC(vfp_null_entry)
@@ -41,6 +50,12 @@ ENDPROC(vfp_null_entry)
__INIT
ENTRY(vfp_testing_entry)
+#ifdef CONFIG_PREEMPT
+ get_thread_info r10
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ sub r11, r4, #1 @ decrement it
+ str r11, [r10, #TI_PREEMPT]
+#endif
ldr r0, VFP_arch_address
str r5, [r0] @ known non-zero value
mov pc, r9 @ we have handled the fault
diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h
index 8de86e4feada..c8c98dd44ad4 100644
--- a/arch/arm/vfp/vfp.h
+++ b/arch/arm/vfp/vfp.h
@@ -377,6 +377,4 @@ struct op {
u32 flags;
};
-#if defined(CONFIG_SMP) || defined(CONFIG_PM)
extern void vfp_save_state(void *location, u32 fpexc);
-#endif
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index c92a08bd6a86..83c4e384b16d 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -137,6 +137,12 @@ check_for_exception:
VFPFMXR FPEXC, r1 @ restore FPEXC last
sub r2, r2, #4
str r2, [sp, #S_PC] @ retry the instruction
+#ifdef CONFIG_PREEMPT
+ get_thread_info r10
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ sub r11, r4, #1 @ decrement it
+ str r11, [r10, #TI_PREEMPT]
+#endif
mov pc, r9 @ we think we have handled things
@@ -155,6 +161,12 @@ look_for_VFP_exceptions:
@ not recognised by VFP
DBGSTR "not VFP"
+#ifdef CONFIG_PREEMPT
+ get_thread_info r10
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ sub r11, r4, #1 @ decrement it
+ str r11, [r10, #TI_PREEMPT]
+#endif
mov pc, lr
process_exception:
@@ -172,7 +184,6 @@ process_exception:
@ retry the faulted instruction
ENDPROC(vfp_support_entry)
-#if defined(CONFIG_SMP) || defined(CONFIG_PM)
ENTRY(vfp_save_state)
@ Save the current VFP state
@ r0 - save location
@@ -190,7 +201,6 @@ ENTRY(vfp_save_state)
stmia r0, {r1, r2, r3, r12} @ save FPEXC, FPSCR, FPINST, FPINST2
mov pc, lr
ENDPROC(vfp_save_state)
-#endif
last_VFP_context_address:
.word last_VFP_context
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 9f476a1be2ca..01599c4ef726 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -266,7 +266,7 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
* on VFP subarch 1.
*/
vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr, regs);
- return;
+ goto exit;
}
/*
@@ -297,7 +297,7 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
* the FPEXC.FP2V bit is valid only if FPEXC.EX is 1.
*/
if (fpexc ^ (FPEXC_EX | FPEXC_FP2V))
- return;
+ goto exit;
/*
* The barrier() here prevents fpinst2 being read
@@ -310,6 +310,8 @@ void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
exceptions = vfp_emulate_instruction(trigger, orig_fpscr, regs);
if (exceptions)
vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
+ exit:
+ preempt_enable();
}
static void vfp_enable(void *unused)
@@ -377,6 +379,55 @@ static void vfp_pm_init(void)
static inline void vfp_pm_init(void) { }
#endif /* CONFIG_PM */
+/*
+ * Synchronise the hardware VFP state of a thread other than current with the
+ * saved one. This function is used by the ptrace mechanism.
+ */
+#ifdef CONFIG_SMP
+void vfp_sync_state(struct thread_info *thread)
+{
+ /*
+ * On SMP systems, the VFP state is automatically saved at every
+ * context switch. We mark the thread VFP state as belonging to a
+ * non-existent CPU so that the saved one will be reloaded when
+ * needed.
+ */
+ thread->vfpstate.hard.cpu = NR_CPUS;
+}
+#else
+void vfp_sync_state(struct thread_info *thread)
+{
+ unsigned int cpu = get_cpu();
+ u32 fpexc = fmrx(FPEXC);
+
+ /*
+ * If VFP is enabled, the previous state was already saved and
+ * last_VFP_context updated.
+ */
+ if (fpexc & FPEXC_EN)
+ goto out;
+
+ if (!last_VFP_context[cpu])
+ goto out;
+
+ /*
+ * Save the last VFP state on this CPU.
+ */
+ fmxr(FPEXC, fpexc | FPEXC_EN);
+ vfp_save_state(last_VFP_context[cpu], fpexc);
+ fmxr(FPEXC, fpexc);
+
+ /*
+ * Set the context to NULL to force a reload the next time the thread
+ * uses the VFP.
+ */
+ last_VFP_context[cpu] = NULL;
+
+out:
+ put_cpu();
+}
+#endif
+
#include <linux/smp.h>
/*
@@ -427,6 +478,18 @@ static int __init vfp_init(void)
* in place; report VFP support to userspace.
*/
elf_hwcap |= HWCAP_VFP;
+#ifdef CONFIG_VFPv3
+ if (VFP_arch >= 3) {
+ elf_hwcap |= HWCAP_VFPv3;
+
+ /*
+ * Check for VFPv3 D16. CPUs in this configuration
+ * only have 16 x 64bit registers.
+ */
+ if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1)
+ elf_hwcap |= HWCAP_VFPv3D16;
+ }
+#endif
#ifdef CONFIG_NEON
/*
* Check for the presence of the Advanced SIMD
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index 05fe3053dcae..35e3bd9858df 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -127,13 +127,13 @@ config BOARD_HAMMERHEAD
select CPU_AT32AP7000
select USB_ARCH_HAS_HCD
help
- The Hammerhead platform is built around a AVR32 32-bit microcontroller from Atmel.
+ The Hammerhead platform is built around an AVR32 32-bit microcontroller from Atmel.
It offers versatile peripherals, such as ethernet, usb device, usb host etc.
- The board also incooperates a power supply and is a Power over Ethernet (PoE) Powered
+ The board also incorporates a power supply and is a Power over Ethernet (PoE) Powered
Device (PD).
- Additonally, a Cyclone III FPGA from Altera is integrated on the board. The FPGA is
+ Additionally, a Cyclone III FPGA from Altera is integrated on the board. The FPGA is
mapped into the 32-bit AVR memory bus. The FPGA offers two DDR2 SDRAM interfaces, which
will cover even the most exceptional need of memory bandwidth. Together with the onboard
video decoder the board is ready for video processing.
@@ -144,6 +144,19 @@ config BOARD_FAVR_32
bool "Favr-32 LCD-board"
select CPU_AT32AP7000
+config BOARD_MERISC
+ bool "Merisc board"
+ select CPU_AT32AP7000
+ help
+ Merisc is the family name for a range of AVR32-based boards.
+
+ The boards are designed to be used in a man-machine
+ interfacing environment, utilizing a touch-based graphical
+ user interface. They host a vast range of I/O peripherals as
+ well as a large SDRAM & Flash memory bank.
+
+ For more information see: http://www.martinsson.se/merisc
+
config BOARD_MIMC200
bool "MIMC200 CPU board"
select CPU_AT32AP7000
@@ -153,6 +166,7 @@ source "arch/avr32/boards/atstk1000/Kconfig"
source "arch/avr32/boards/atngw100/Kconfig"
source "arch/avr32/boards/hammerhead/Kconfig"
source "arch/avr32/boards/favr-32/Kconfig"
+source "arch/avr32/boards/merisc/Kconfig"
choice
prompt "Boot loader type"
diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile
index f3ef3bbf797c..0b97e14f73f6 100644
--- a/arch/avr32/Makefile
+++ b/arch/avr32/Makefile
@@ -35,6 +35,7 @@ core-$(CONFIG_BOARD_ATSTK1000) += arch/avr32/boards/atstk1000/
core-$(CONFIG_BOARD_ATNGW100) += arch/avr32/boards/atngw100/
core-$(CONFIG_BOARD_HAMMERHEAD) += arch/avr32/boards/hammerhead/
core-$(CONFIG_BOARD_FAVR_32) += arch/avr32/boards/favr-32/
+core-$(CONFIG_BOARD_MERISC) += arch/avr32/boards/merisc/
core-$(CONFIG_BOARD_MIMC200) += arch/avr32/boards/mimc200/
core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/
core-y += arch/avr32/kernel/
diff --git a/arch/avr32/boards/atngw100/evklcd10x.c b/arch/avr32/boards/atngw100/evklcd10x.c
index 8140b22b3461..00337112c5ac 100644
--- a/arch/avr32/boards/atngw100/evklcd10x.c
+++ b/arch/avr32/boards/atngw100/evklcd10x.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/linkage.h>
+#include <linux/gpio.h>
#include <linux/fb.h>
#include <linux/platform_device.h>
@@ -19,26 +20,26 @@
#include <asm/setup.h>
#include <mach/at32ap700x.h>
+#include <mach/portmux.h>
#include <mach/board.h>
+#include <sound/atmel-ac97c.h>
+
static struct ac97c_platform_data __initdata ac97c0_data = {
- .dma_rx_periph_id = 3,
- .dma_tx_periph_id = 4,
- .dma_controller_id = 0,
- .reset_pin = GPIO_PIN_PB(19),
+ .reset_pin = GPIO_PIN_PB(19),
};
#ifdef CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA
static struct fb_videomode __initdata tcg057vglad_modes[] = {
{
- .name = "640x480 @ 60",
- .refresh = 60,
+ .name = "640x480 @ 50",
+ .refresh = 50,
.xres = 640, .yres = 480,
.pixclock = KHZ2PICOS(25180),
- .left_margin = 64, .right_margin = 31,
- .upper_margin = 34, .lower_margin = 2,
- .hsync_len = 96, .vsync_len = 4,
+ .left_margin = 64, .right_margin = 96,
+ .upper_margin = 34, .lower_margin = 11,
+ .hsync_len = 64, .vsync_len = 15,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
@@ -69,14 +70,14 @@ static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = {
#elif CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA
static struct fb_videomode __initdata tcg057qvlad_modes[] = {
{
- .name = "320x240 @ 60",
- .refresh = 60,
+ .name = "320x240 @ 50",
+ .refresh = 50,
.xres = 320, .yres = 240,
.pixclock = KHZ2PICOS(6300),
- .left_margin = 52, .right_margin = 28,
- .upper_margin = 7, .lower_margin = 2,
- .hsync_len = 96, .vsync_len = 4,
+ .left_margin = 34, .right_margin = 46,
+ .upper_margin = 7, .lower_margin = 15,
+ .hsync_len = 64, .vsync_len = 12,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
@@ -144,12 +145,29 @@ static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = {
};
#endif
+static void atevklcd10x_lcdc_power_control(int on)
+{
+ gpio_set_value(GPIO_PIN_PB(15), on);
+}
+
static int __init atevklcd10x_init(void)
{
- at32_add_device_ac97c(0, &ac97c0_data);
+ /* PB15 is connected to the enable line on the boost regulator
+ * controlling the backlight for the LCD panel.
+ */
+ at32_select_gpio(GPIO_PIN_PB(15), AT32_GPIOF_OUTPUT);
+ gpio_request(GPIO_PIN_PB(15), "backlight");
+ gpio_direction_output(GPIO_PIN_PB(15), 0);
+
+ atevklcd10x_lcdc_data.atmel_lcdfb_power_control =
+ atevklcd10x_lcdc_power_control;
at32_add_device_lcdc(0, &atevklcd10x_lcdc_data,
- fbmem_start, fbmem_size, 1);
+ fbmem_start, fbmem_size,
+ ATMEL_LCDC_ALT_18BIT | ATMEL_LCDC_PE_DVAL);
+
+ at32_add_device_ac97c(0, &ac97c0_data, AC97C_BOTH);
+
return 0;
}
postcore_initcall(atevklcd10x_init);
diff --git a/arch/avr32/boards/atngw100/setup.c b/arch/avr32/boards/atngw100/setup.c
index 05d3722fff18..5b022aad4bd9 100644
--- a/arch/avr32/boards/atngw100/setup.c
+++ b/arch/avr32/boards/atngw100/setup.c
@@ -56,13 +56,8 @@ static struct spi_board_info spi0_board_info[] __initdata = {
static struct mci_platform_data __initdata mci0_data = {
.slot[0] = {
.bus_width = 4,
-#ifndef CONFIG_BOARD_ATNGW100_EVKLCD10X
.detect_pin = GPIO_PIN_PC(25),
.wp_pin = GPIO_PIN_PE(0),
-#else
- .detect_pin = GPIO_PIN_NONE,
- .wp_pin = GPIO_PIN_NONE,
-#endif
},
};
@@ -123,7 +118,7 @@ static void __init set_hw_addr(struct platform_device *pdev)
void __init setup_board(void)
{
- at32_map_usart(1, 0); /* USART 1: /dev/ttyS0, DB9 */
+ at32_map_usart(1, 0, 0); /* USART 1: /dev/ttyS0, DB9 */
at32_setup_serial_console(0);
}
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index 1f33a106905c..2adc261c9e3d 100644
--- a/arch/avr32/boards/atstk1000/atstk1002.c
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -252,12 +252,12 @@ static void __init atstk1002_setup_extdac(void)
void __init setup_board(void)
{
#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
- at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */
+ at32_map_usart(0, 1, 0); /* USART 0/B: /dev/ttyS1, IRDA */
#else
- at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */
+ at32_map_usart(1, 0, 0); /* USART 1/A: /dev/ttyS0, DB9 */
#endif
/* USART 2/unused: expansion connector */
- at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */
+ at32_map_usart(3, 2, 0); /* USART 3/C: /dev/ttyS2, DB9 */
at32_setup_serial_console(0);
}
diff --git a/arch/avr32/boards/atstk1000/atstk1003.c b/arch/avr32/boards/atstk1000/atstk1003.c
index b3a23c88bcfe..ff7e23298827 100644
--- a/arch/avr32/boards/atstk1000/atstk1003.c
+++ b/arch/avr32/boards/atstk1000/atstk1003.c
@@ -115,12 +115,12 @@ static void __init atstk1003_setup_extdac(void)
void __init setup_board(void)
{
#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
- at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */
+ at32_map_usart(0, 1, 0); /* USART 0/B: /dev/ttyS1, IRDA */
#else
- at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */
+ at32_map_usart(1, 0, 0); /* USART 1/A: /dev/ttyS0, DB9 */
#endif
/* USART 2/unused: expansion connector */
- at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */
+ at32_map_usart(3, 2, 0); /* USART 3/C: /dev/ttyS2, DB9 */
at32_setup_serial_console(0);
}
diff --git a/arch/avr32/boards/atstk1000/atstk1004.c b/arch/avr32/boards/atstk1000/atstk1004.c
index 29b35aca96cd..69a9f0f08c6e 100644
--- a/arch/avr32/boards/atstk1000/atstk1004.c
+++ b/arch/avr32/boards/atstk1000/atstk1004.c
@@ -120,12 +120,12 @@ static void __init atstk1004_setup_extdac(void)
void __init setup_board(void)
{
#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
- at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */
+ at32_map_usart(0, 1, 0); /* USART 0/B: /dev/ttyS1, IRDA */
#else
- at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */
+ at32_map_usart(1, 0, 0); /* USART 1/A: /dev/ttyS0, DB9 */
#endif
/* USART 2/unused: expansion connector */
- at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */
+ at32_map_usart(3, 2, 0); /* USART 3/C: /dev/ttyS2, DB9 */
at32_setup_serial_console(0);
}
diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c
index 745c408c2ac5..46c9b0a224cf 100644
--- a/arch/avr32/boards/favr-32/setup.c
+++ b/arch/avr32/boards/favr-32/setup.c
@@ -22,6 +22,8 @@
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
+#include <sound/atmel-abdac.h>
+
#include <video/atmel_lcdc.h>
#include <asm/setup.h>
@@ -41,6 +43,9 @@ unsigned long at32_board_osc_rates[3] = {
/* Initialized by bootloader-specific startup code. */
struct tag *bootloader_tags __initdata;
+static struct atmel_abdac_pdata __initdata abdac0_data = {
+};
+
struct eth_addr {
u8 addr[6];
};
@@ -245,7 +250,7 @@ static void __init favr32_setup_atmel_pwm_bl(void)
void __init setup_board(void)
{
- at32_map_usart(3, 0); /* USART 3 => /dev/ttyS0 */
+ at32_map_usart(3, 0, 0); /* USART 3 => /dev/ttyS0 */
at32_setup_serial_console(0);
}
@@ -326,7 +331,7 @@ static int __init favr32_init(void)
spi1_board_info[0].irq = gpio_to_irq(GPIO_PIN_PB(3));
- set_abdac_rate(at32_add_device_abdac(0));
+ set_abdac_rate(at32_add_device_abdac(0, &abdac0_data));
at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel);
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
diff --git a/arch/avr32/boards/hammerhead/flash.c b/arch/avr32/boards/hammerhead/flash.c
index a98c6dd3a028..559bbcb03f9b 100644
--- a/arch/avr32/boards/hammerhead/flash.c
+++ b/arch/avr32/boards/hammerhead/flash.c
@@ -15,7 +15,6 @@
#include <linux/mtd/physmap.h>
#include <linux/usb/isp116x.h>
#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
#include <linux/delay.h>
#include <mach/portmux.h>
diff --git a/arch/avr32/boards/hammerhead/setup.c b/arch/avr32/boards/hammerhead/setup.c
index 4d2fe82b2029..dd009875a405 100644
--- a/arch/avr32/boards/hammerhead/setup.c
+++ b/arch/avr32/boards/hammerhead/setup.c
@@ -29,6 +29,8 @@
#include <mach/init.h>
#include <mach/portmux.h>
+#include <sound/atmel-ac97c.h>
+
#include "../../mach-at32ap/clock.h"
#include "flash.h"
@@ -163,7 +165,7 @@ static void __init set_hw_addr(struct platform_device *pdev)
void __init setup_board(void)
{
- at32_map_usart(1, 0); /* USART 1: /dev/ttyS0, DB9 */
+ at32_map_usart(1, 0, 0); /* USART 1: /dev/ttyS0, DB9 */
at32_setup_serial_console(0);
}
@@ -233,7 +235,7 @@ static int __init hammerhead_init(void)
i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));
#ifdef CONFIG_BOARD_HAMMERHEAD_SND
- at32_add_device_ac97c(0, &ac97c_data);
+ at32_add_device_ac97c(0, &ac97c_data, AC97C_BOTH);
#endif
/* Select the Touchscreen interrupt pin mode */
diff --git a/arch/avr32/boards/merisc/Kconfig b/arch/avr32/boards/merisc/Kconfig
new file mode 100644
index 000000000000..7e043275d5a9
--- /dev/null
+++ b/arch/avr32/boards/merisc/Kconfig
@@ -0,0 +1,5 @@
+# Merisc customization
+
+if BOARD_MERISC
+
+endif # BOARD_MERISC
diff --git a/arch/avr32/boards/merisc/Makefile b/arch/avr32/boards/merisc/Makefile
new file mode 100644
index 000000000000..d24c78729bd1
--- /dev/null
+++ b/arch/avr32/boards/merisc/Makefile
@@ -0,0 +1 @@
+obj-y += setup.o flash.o display.o merisc_sysfs.o
diff --git a/arch/avr32/boards/merisc/display.c b/arch/avr32/boards/merisc/display.c
new file mode 100644
index 000000000000..85a543cd4abc
--- /dev/null
+++ b/arch/avr32/boards/merisc/display.c
@@ -0,0 +1,65 @@
+/*
+ * Display setup code for the Merisc board
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <video/atmel_lcdc.h>
+#include <asm/setup.h>
+#include <mach/board.h>
+#include "merisc.h"
+
+static struct fb_videomode merisc_fb_videomode[] = {
+ {
+ .refresh = 44,
+ .xres = 640,
+ .yres = 480,
+ .left_margin = 96,
+ .right_margin = 96,
+ .upper_margin = 34,
+ .lower_margin = 8,
+ .hsync_len = 64,
+ .vsync_len = 64,
+ .name = "640x480 @ 44",
+ .pixclock = KHZ2PICOS(25180),
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+};
+
+static struct fb_monspecs merisc_fb_monspecs = {
+ .manufacturer = "Kyo",
+ .monitor = "TCG075VG2AD",
+ .modedb = merisc_fb_videomode,
+ .modedb_len = ARRAY_SIZE(merisc_fb_videomode),
+ .hfmin = 30000,
+ .hfmax = 33333,
+ .vfmin = 60,
+ .vfmax = 90,
+ .dclkmax = 30000000,
+};
+
+struct atmel_lcdfb_info merisc_lcdc_data = {
+ .default_bpp = 24,
+ .default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
+ .default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT
+ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
+ | ATMEL_LCDC_MEMOR_BIG),
+ .default_monspecs = &merisc_fb_monspecs,
+ .guard_time = 2,
+};
+
+static int __init merisc_display_init(void)
+{
+ at32_add_device_lcdc(0, &merisc_lcdc_data, fbmem_start,
+ fbmem_size, 0);
+
+ return 0;
+}
+device_initcall(merisc_display_init);
diff --git a/arch/avr32/boards/merisc/flash.c b/arch/avr32/boards/merisc/flash.c
new file mode 100644
index 000000000000..8e856fd6f013
--- /dev/null
+++ b/arch/avr32/boards/merisc/flash.c
@@ -0,0 +1,139 @@
+/*
+ * Merisc board-specific flash initialization
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <mach/smc.h>
+
+/* Will be translated to units of 14.3 ns, rounded up */
+static struct smc_timing flash_timing __initdata = {
+ .ncs_read_setup = 1 * 14,
+ .nrd_setup = 5 * 14,
+ .ncs_write_setup = 1 * 14,
+ .nwe_setup = 2 * 14,
+
+ .ncs_read_pulse = 12 * 14,
+ .nrd_pulse = 7 * 14,
+ .ncs_write_pulse = 8 * 14,
+ .nwe_pulse = 4 * 14,
+
+ .read_cycle = 14 * 14,
+ .write_cycle = 10 * 14,
+};
+
+static struct smc_config flash_config __initdata = {
+ .bus_width = 2,
+ .nrd_controlled = 1,
+ .nwe_controlled = 1,
+ .byte_write = 1,
+ .tdf_cycles = 3,
+};
+
+static struct mtd_partition flash_0_parts[] = {
+ {
+ .name = "boot",
+ .offset = 0x00000000,
+ .size = 0x00060000,
+ .mask_flags = 0,
+ },
+ {
+ .name = "kernel",
+ .offset = 0x00060000,
+ .size = 0x00200000,
+ .mask_flags = 0,
+ },
+ {
+ .name = "root",
+ .offset = 0x00260000,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct mtd_partition flash_1_parts[] = {
+ {
+ .name = "2ndflash",
+ .offset = 0x00000000,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct physmap_flash_data flash_data[] = {
+ {
+ .width = 2,
+ .nr_parts = ARRAY_SIZE(flash_0_parts),
+ .parts = flash_0_parts,
+ },
+ {
+ .width = 2,
+ .nr_parts = ARRAY_SIZE(flash_1_parts),
+ .parts = flash_1_parts,
+ }
+};
+
+static struct resource flash_resource[] = {
+ {
+ .start = 0x00000000,
+ .end = 0x03ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x04000000,
+ .end = 0x07ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device flash_device[] = {
+ {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = &flash_resource[0],
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &flash_data[0],
+ },
+ },
+ {
+ .name = "physmap-flash",
+ .id = 1,
+ .resource = &flash_resource[1],
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &flash_data[1],
+ },
+ },
+};
+
+static int __init merisc_flash_init(void)
+{
+ int ret;
+ smc_set_timing(&flash_config, &flash_timing);
+
+ ret = smc_set_configuration(0, &flash_config);
+ if (ret < 0) {
+ printk(KERN_ERR "Merisc: failed to set NOR flash timing #0\n");
+ return ret;
+ }
+
+ ret = smc_set_configuration(4, &flash_config);
+ if (ret < 0) {
+ printk(KERN_ERR "Merisc: failed to set NOR flash timing #1\n");
+ return ret;
+ }
+
+ platform_device_register(&flash_device[0]);
+ platform_device_register(&flash_device[1]);
+ return 0;
+}
+device_initcall(merisc_flash_init);
diff --git a/arch/avr32/boards/merisc/merisc.h b/arch/avr32/boards/merisc/merisc.h
new file mode 100644
index 000000000000..50ffb2f3fcbf
--- /dev/null
+++ b/arch/avr32/boards/merisc/merisc.h
@@ -0,0 +1,18 @@
+/*
+ * Merisc exports
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ARCH_AVR32_BOARDS_MERISC_MERISC_H
+#define __ARCH_AVR32_BOARDS_MERISC_MERISC_H
+
+const char *merisc_revision(void);
+const char *merisc_model(void);
+
+extern struct class merisc_class;
+
+#endif /* __ARCH_AVR32_BOARDS_MERISC_MERISC_H */
diff --git a/arch/avr32/boards/merisc/merisc_sysfs.c b/arch/avr32/boards/merisc/merisc_sysfs.c
new file mode 100644
index 000000000000..df431fdba9ad
--- /dev/null
+++ b/arch/avr32/boards/merisc/merisc_sysfs.c
@@ -0,0 +1,65 @@
+/*
+ * Merisc sysfs exports
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/timer.h>
+#include <linux/err.h>
+#include <linux/ctype.h>
+#include "merisc.h"
+
+static ssize_t merisc_model_show(struct class *class, char *buf)
+{
+ ssize_t ret = 0;
+
+ sprintf(buf, "%s\n", merisc_model());
+ ret = strlen(buf) + 1;
+
+ return ret;
+}
+
+static ssize_t merisc_revision_show(struct class *class, char *buf)
+{
+ ssize_t ret = 0;
+
+ sprintf(buf, "%s\n", merisc_revision());
+ ret = strlen(buf) + 1;
+
+ return ret;
+}
+
+static struct class_attribute merisc_class_attrs[] = {
+ __ATTR(model, S_IRUGO, merisc_model_show, NULL),
+ __ATTR(revision, S_IRUGO, merisc_revision_show, NULL),
+ __ATTR_NULL,
+};
+
+struct class merisc_class = {
+ .name = "merisc",
+ .owner = THIS_MODULE,
+ .class_attrs = merisc_class_attrs,
+};
+
+static int __init merisc_sysfs_init(void)
+{
+ int status;
+
+ status = class_register(&merisc_class);
+ if (status < 0)
+ return status;
+
+ return 0;
+}
+
+postcore_initcall(merisc_sysfs_init);
diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c
new file mode 100644
index 000000000000..20b300cf105a
--- /dev/null
+++ b/arch/avr32/boards/merisc/setup.c
@@ -0,0 +1,297 @@
+/*
+ * Board-specific setup code for the Merisc
+ *
+ * Copyright (C) 2008 Martinsson Elektronik AB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/leds.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/irq.h>
+#include <linux/fb.h>
+#include <linux/atmel-mci.h>
+
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/gpio.h>
+
+#include <mach/at32ap700x.h>
+#include <mach/board.h>
+#include <mach/init.h>
+#include <mach/portmux.h>
+
+#include "merisc.h"
+
+/* Holds the autodetected board model and revision */
+static int merisc_board_id;
+
+/* Initialized by bootloader-specific startup code. */
+struct tag *bootloader_tags __initdata;
+
+/* Oscillator frequencies. These are board specific */
+unsigned long at32_board_osc_rates[3] = {
+ [0] = 32768, /* 32.768 kHz on RTC osc */
+ [1] = 20000000, /* 20 MHz on osc0 */
+ [2] = 12000000, /* 12 MHz on osc1 */
+};
+
+struct eth_addr {
+ u8 addr[6];
+};
+
+static struct eth_addr __initdata hw_addr[2];
+static struct eth_platform_data __initdata eth_data[2];
+
+static int ads7846_get_pendown_state_PB26(void)
+{
+ return !gpio_get_value(GPIO_PIN_PB(26));
+}
+
+static int ads7846_get_pendown_state_PB28(void)
+{
+ return !gpio_get_value(GPIO_PIN_PB(28));
+}
+
+static struct ads7846_platform_data __initdata ads7846_data = {
+ .model = 7846,
+ .vref_delay_usecs = 100,
+ .vref_mv = 0,
+ .keep_vref_on = 0,
+ .settle_delay_usecs = 150,
+ .penirq_recheck_delay_usecs = 1,
+ .x_plate_ohms = 800,
+ .debounce_rep = 4,
+ .debounce_max = 10,
+ .debounce_tol = 50,
+ .get_pendown_state = ads7846_get_pendown_state_PB26,
+ .filter_init = NULL,
+ .filter = NULL,
+ .filter_cleanup = NULL,
+};
+
+static struct spi_board_info __initdata spi0_board_info[] = {
+ {
+ .modalias = "ads7846",
+ .max_speed_hz = 3250000,
+ .chip_select = 0,
+ .bus_num = 0,
+ .platform_data = &ads7846_data,
+ .mode = SPI_MODE_0,
+ },
+};
+
+static struct mci_platform_data __initdata mci0_data = {
+ .slot[0] = {
+ .bus_width = 4,
+ .detect_pin = GPIO_PIN_PE(19),
+ .wp_pin = GPIO_PIN_PE(20),
+ },
+};
+
+static int __init parse_tag_ethernet(struct tag *tag)
+{
+ int i;
+
+ i = tag->u.ethernet.mac_index;
+ if (i < ARRAY_SIZE(hw_addr)) {
+ memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
+ sizeof(hw_addr[i].addr));
+ }
+
+ return 0;
+}
+__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
+
+static void __init set_hw_addr(struct platform_device *pdev)
+{
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ const u8 *addr;
+ void __iomem *regs;
+ struct clk *pclk;
+
+ if (!res)
+ return;
+
+ if (pdev->id >= ARRAY_SIZE(hw_addr))
+ return;
+
+ addr = hw_addr[pdev->id].addr;
+ if (!is_valid_ether_addr(addr))
+ return;
+
+ regs = (void __iomem __force *)res->start;
+ pclk = clk_get(&pdev->dev, "pclk");
+ if (!pclk)
+ return;
+
+ clk_enable(pclk);
+ __raw_writel((addr[3] << 24) | (addr[2] << 16)
+ | (addr[1] << 8) | addr[0], regs + 0x98);
+ __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
+ clk_disable(pclk);
+ clk_put(pclk);
+}
+
+static struct i2c_gpio_platform_data i2c_gpio_data = {
+ .sda_pin = GPIO_PIN_PA(6),
+ .scl_pin = GPIO_PIN_PA(7),
+ .sda_is_open_drain = 1,
+ .scl_is_open_drain = 1,
+ .udelay = 2,
+};
+
+static struct platform_device i2c_gpio_device = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &i2c_gpio_data,
+ },
+};
+
+static struct i2c_board_info __initdata i2c_info[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51)
+ },
+};
+
+#ifdef CONFIG_LEDS_ATMEL_PWM
+static struct gpio_led stk_pwm_led[] = {
+ {
+ .name = "backlight",
+ .gpio = 0, /* PWM channel 0 (LCD backlight) */
+ },
+};
+
+static struct gpio_led_platform_data stk_pwm_led_data = {
+ .num_leds = ARRAY_SIZE(stk_pwm_led),
+ .leds = stk_pwm_led,
+};
+
+static struct platform_device stk_pwm_led_dev = {
+ .name = "leds-atmel-pwm",
+ .id = -1,
+ .dev = {
+ .platform_data = &stk_pwm_led_data,
+ },
+};
+#endif
+
+const char *merisc_model(void)
+{
+ switch (merisc_board_id) {
+ case 0:
+ case 1:
+ return "500-01";
+ case 2:
+ return "BT";
+ default:
+ return "Unknown";
+ }
+}
+
+const char *merisc_revision(void)
+{
+ switch (merisc_board_id) {
+ case 0:
+ return "B";
+ case 1:
+ return "D";
+ case 2:
+ return "A";
+ default:
+ return "Unknown";
+ }
+}
+
+static void detect_merisc_board_id(void)
+{
+ /* Board ID pins MUST be set as input or the board may be damaged */
+ at32_select_gpio(GPIO_PIN_PA(24), AT32_GPIOF_PULLUP);
+ at32_select_gpio(GPIO_PIN_PA(25), AT32_GPIOF_PULLUP);
+ at32_select_gpio(GPIO_PIN_PA(26), AT32_GPIOF_PULLUP);
+ at32_select_gpio(GPIO_PIN_PA(27), AT32_GPIOF_PULLUP);
+
+ merisc_board_id = !gpio_get_value(GPIO_PIN_PA(24)) +
+ !gpio_get_value(GPIO_PIN_PA(25)) * 2 +
+ !gpio_get_value(GPIO_PIN_PA(26)) * 4 +
+ !gpio_get_value(GPIO_PIN_PA(27)) * 8;
+}
+
+void __init setup_board(void)
+{
+ at32_map_usart(0, 0, 0);
+ at32_map_usart(1, 1, 0);
+ at32_map_usart(3, 3, 0);
+ at32_setup_serial_console(1);
+}
+
+static int __init merisc_init(void)
+{
+ detect_merisc_board_id();
+
+ printk(KERN_NOTICE "BOARD: Merisc %s revision %s\n", merisc_model(),
+ merisc_revision());
+
+ /* Reserve pins for SDRAM */
+ at32_reserve_pin(GPIO_PIOE_BASE, ATMEL_EBI_PE_DATA_ALL | (1 << 26));
+
+ if (merisc_board_id >= 1)
+ at32_map_usart(2, 2, 0);
+
+ at32_add_device_usart(0);
+ at32_add_device_usart(1);
+ if (merisc_board_id >= 1)
+ at32_add_device_usart(2);
+ at32_add_device_usart(3);
+ set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
+
+ /* ADS7846 PENIRQ */
+ if (merisc_board_id == 0) {
+ ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB26;
+ at32_select_periph(GPIO_PIOB_BASE, 1 << 26,
+ GPIO_PERIPH_A, AT32_GPIOF_PULLUP);
+ spi0_board_info[0].irq = AT32_EXTINT(1);
+ } else {
+ ads7846_data.get_pendown_state = ads7846_get_pendown_state_PB28;
+ at32_select_periph(GPIO_PIOB_BASE, 1 << 28, GPIO_PERIPH_A,
+ AT32_GPIOF_PULLUP);
+ spi0_board_info[0].irq = AT32_EXTINT(3);
+ }
+
+ /* ADS7846 busy pin */
+ at32_select_gpio(GPIO_PIN_PA(4), AT32_GPIOF_PULLUP);
+
+ at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
+
+ at32_add_device_mci(0, &mci0_data);
+
+#ifdef CONFIG_LEDS_ATMEL_PWM
+ at32_add_device_pwm((1 << 0) | (1 << 2));
+ platform_device_register(&stk_pwm_led_dev);
+#else
+ at32_add_device_pwm((1 << 2));
+#endif
+
+ at32_select_gpio(i2c_gpio_data.sda_pin,
+ AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
+ at32_select_gpio(i2c_gpio_data.scl_pin,
+ AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
+ platform_device_register(&i2c_gpio_device);
+
+ i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info));
+
+ return 0;
+}
+postcore_initcall(merisc_init);
diff --git a/arch/avr32/boards/mimc200/setup.c b/arch/avr32/boards/mimc200/setup.c
index 2b58d61f0afc..c1b2175b4fea 100644
--- a/arch/avr32/boards/mimc200/setup.c
+++ b/arch/avr32/boards/mimc200/setup.c
@@ -175,10 +175,10 @@ static void __init set_hw_addr(struct platform_device *pdev)
void __init setup_board(void)
{
- at32_map_usart(0, 0); /* USART 0: /dev/ttyS0 (TTL --> Altera) */
- at32_map_usart(1, 1); /* USART 1: /dev/ttyS1 (RS232) */
- at32_map_usart(2, 2); /* USART 2: /dev/ttyS2 (RS485) */
- at32_map_usart(3, 3); /* USART 3: /dev/ttyS3 (RS422 Multidrop) */
+ at32_map_usart(0, 0, 0); /* USART 0: /dev/ttyS0 (TTL --> Altera) */
+ at32_map_usart(1, 1, 0); /* USART 1: /dev/ttyS1 (RS232) */
+ at32_map_usart(2, 2, 0); /* USART 2: /dev/ttyS2 (RS485) */
+ at32_map_usart(3, 3, 0); /* USART 3: /dev/ttyS3 (RS422 Multidrop) */
}
static struct i2c_gpio_platform_data i2c_gpio_data = {
diff --git a/arch/avr32/configs/merisc_defconfig b/arch/avr32/configs/merisc_defconfig
new file mode 100644
index 000000000000..41554db4877f
--- /dev/null
+++ b/arch/avr32/configs/merisc_defconfig
@@ -0,0 +1,1237 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc1
+# Wed Mar 25 14:06:15 2009
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_CLK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=1
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP700X=y
+CONFIG_CPU_AT32AP7000=y
+# CONFIG_BOARD_ATSTK1000 is not set
+# CONFIG_BOARD_ATNGW100 is not set
+# CONFIG_BOARD_HAMMERHEAD is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MIMC200 is not set
+CONFIG_BOARD_MERISC=y
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+CONFIG_AP700X_32_BIT_SMC=y
+# CONFIG_AP700X_16_BIT_SMC is not set
+# CONFIG_AP700X_8_BIT_SMC is not set
+CONFIG_LOAD_ADDRESS=0x10000000
+CONFIG_ENTRY_ADDRESS=0x90000000
+CONFIG_PHYS_OFFSET=0x10000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_QUICKLIST=y
+# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
+# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+# CONFIG_OWNERSHIP_TRACE is not set
+# CONFIG_NMI_DEBUGGING is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_CMDLINE=""
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+# CONFIG_IP_PIMSM_V2 is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+# CONFIG_CAN_DEBUG_DEVICES is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+CONFIG_MTD_ABSENT=y
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+CONFIG_MTD_BLOCK2MTD=y
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_PWM=y
+# CONFIG_ATMEL_TCLIB is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+CONFIG_ATMEL_SSC=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+CONFIG_SPI_SPIDEV=y
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_AT32AP700X_WDT is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_ATMEL=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_USB_SUPPORT=y
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_ATMELMCI=y
+CONFIG_MMC_ATMELMCI_DMA=y
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_ATMEL_PWM=y
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+CONFIG_RTC_DRV_PCF8563=y
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_AT32AP700X is not set
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_DMATEST is not set
+CONFIG_UIO=y
+# CONFIG_UIO_PDRV is not set
+# CONFIG_UIO_PDRV_GENIRQ is not set
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/avr32/include/asm/socket.h b/arch/avr32/include/asm/socket.h
index 35863f260929..04c860619700 100644
--- a/arch/avr32/include/asm/socket.h
+++ b/arch/avr32/include/asm/socket.h
@@ -54,4 +54,7 @@
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
#endif /* __ASM_AVR32_SOCKET_H */
diff --git a/arch/avr32/include/asm/uaccess.h b/arch/avr32/include/asm/uaccess.h
index ed092395215e..245b2ee213c9 100644
--- a/arch/avr32/include/asm/uaccess.h
+++ b/arch/avr32/include/asm/uaccess.h
@@ -230,10 +230,10 @@ extern int __put_user_bad(void);
asm volatile( \
"1: ld." suffix " %1, %3 \n" \
"2: \n" \
- " .section .fixup, \"ax\" \n" \
+ " .subsection 1 \n" \
"3: mov %0, %4 \n" \
" rjmp 2b \n" \
- " .previous \n" \
+ " .subsection 0 \n" \
" .section __ex_table, \"a\" \n" \
" .long 1b, 3b \n" \
" .previous \n" \
@@ -295,10 +295,10 @@ extern int __put_user_bad(void);
asm volatile( \
"1: st." suffix " %1, %3 \n" \
"2: \n" \
- " .section .fixup, \"ax\" \n" \
+ " .subsection 1 \n" \
"3: mov %0, %4 \n" \
" rjmp 2b \n" \
- " .previous \n" \
+ " .subsection 0 \n" \
" .section __ex_table, \"a\" \n" \
" .long 1b, 3b \n" \
" .previous \n" \
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S
index 33d49377b8be..009a80155d67 100644
--- a/arch/avr32/kernel/entry-avr32b.S
+++ b/arch/avr32/kernel/entry-avr32b.S
@@ -150,10 +150,10 @@ page_not_present:
tlbmiss_restore
sub sp, 4
stmts --sp, r0-lr
- rcall save_full_context_ex
+ call save_full_context_ex
mfsr r12, SYSREG_ECR
mov r11, sp
- rcall do_page_fault
+ call do_page_fault
rjmp ret_from_exception
.align 2
@@ -250,7 +250,7 @@ syscall_badsys:
.global ret_from_fork
ret_from_fork:
- rcall schedule_tail
+ call schedule_tail
/* check for syscall tracing */
get_thread_info r0
@@ -261,7 +261,7 @@ ret_from_fork:
syscall_trace_enter:
pushm r8-r12
- rcall syscall_trace
+ call syscall_trace
popm r8-r12
rjmp syscall_trace_cont
@@ -269,14 +269,14 @@ syscall_exit_work:
bld r1, TIF_SYSCALL_TRACE
brcc 1f
unmask_interrupts
- rcall syscall_trace
+ call syscall_trace
mask_interrupts
ld.w r1, r0[TI_flags]
1: bld r1, TIF_NEED_RESCHED
brcc 2f
unmask_interrupts
- rcall schedule
+ call schedule
mask_interrupts
ld.w r1, r0[TI_flags]
rjmp 1b
@@ -287,7 +287,7 @@ syscall_exit_work:
unmask_interrupts
mov r12, sp
mov r11, r0
- rcall do_notify_resume
+ call do_notify_resume
mask_interrupts
ld.w r1, r0[TI_flags]
rjmp 1b
@@ -394,7 +394,7 @@ handle_critical:
mfsr r12, SYSREG_ECR
mov r11, sp
- rcall do_critical_exception
+ call do_critical_exception
/* We should never get here... */
bad_return:
@@ -407,18 +407,18 @@ bad_return:
do_bus_error_write:
sub sp, 4
stmts --sp, r0-lr
- rcall save_full_context_ex
+ call save_full_context_ex
mov r11, 1
rjmp 1f
do_bus_error_read:
sub sp, 4
stmts --sp, r0-lr
- rcall save_full_context_ex
+ call save_full_context_ex
mov r11, 0
1: mfsr r12, SYSREG_BEAR
mov r10, sp
- rcall do_bus_error
+ call do_bus_error
rjmp ret_from_exception
.align 1
@@ -433,7 +433,7 @@ do_nmi_ll:
1: pushm r8, r9 /* PC and SR */
mfsr r12, SYSREG_ECR
mov r11, sp
- rcall do_nmi
+ call do_nmi
popm r8-r9
mtsr SYSREG_RAR_NMI, r8
tst r0, r0
@@ -457,29 +457,29 @@ do_nmi_ll:
handle_address_fault:
sub sp, 4
stmts --sp, r0-lr
- rcall save_full_context_ex
+ call save_full_context_ex
mfsr r12, SYSREG_ECR
mov r11, sp
- rcall do_address_exception
+ call do_address_exception
rjmp ret_from_exception
handle_protection_fault:
sub sp, 4
stmts --sp, r0-lr
- rcall save_full_context_ex
+ call save_full_context_ex
mfsr r12, SYSREG_ECR
mov r11, sp
- rcall do_page_fault
+ call do_page_fault
rjmp ret_from_exception
.align 1
do_illegal_opcode_ll:
sub sp, 4
stmts --sp, r0-lr
- rcall save_full_context_ex
+ call save_full_context_ex
mfsr r12, SYSREG_ECR
mov r11, sp
- rcall do_illegal_opcode
+ call do_illegal_opcode
rjmp ret_from_exception
do_dtlb_modified:
@@ -513,11 +513,11 @@ do_dtlb_modified:
do_fpe_ll:
sub sp, 4
stmts --sp, r0-lr
- rcall save_full_context_ex
+ call save_full_context_ex
unmask_interrupts
mov r12, 26
mov r11, sp
- rcall do_fpe
+ call do_fpe
rjmp ret_from_exception
ret_from_exception:
@@ -553,7 +553,7 @@ fault_resume_kernel:
lddsp r4, sp[REG_SR]
bld r4, SYSREG_GM_OFFSET
brcs 1f
- rcall preempt_schedule_irq
+ call preempt_schedule_irq
1:
#endif
@@ -582,7 +582,7 @@ fault_exit_work:
bld r1, TIF_NEED_RESCHED
brcc 1f
unmask_interrupts
- rcall schedule
+ call schedule
mask_interrupts
ld.w r1, r0[TI_flags]
rjmp fault_exit_work
@@ -593,7 +593,7 @@ fault_exit_work:
unmask_interrupts
mov r12, sp
mov r11, r0
- rcall do_notify_resume
+ call do_notify_resume
mask_interrupts
ld.w r1, r0[TI_flags]
rjmp fault_exit_work
@@ -616,10 +616,10 @@ handle_debug:
.Ldebug_fixup_cont:
#ifdef CONFIG_TRACE_IRQFLAGS
- rcall trace_hardirqs_off
+ call trace_hardirqs_off
#endif
mov r12, sp
- rcall do_debug
+ call do_debug
mov sp, r12
lddsp r2, sp[REG_SR]
@@ -643,7 +643,7 @@ handle_debug:
mtsr SYSREG_RSR_DBG, r11
mtsr SYSREG_RAR_DBG, r10
#ifdef CONFIG_TRACE_IRQFLAGS
- rcall trace_hardirqs_on
+ call trace_hardirqs_on
1:
#endif
ldmts sp++, r0-lr
@@ -676,7 +676,7 @@ debug_resume_kernel:
#ifdef CONFIG_TRACE_IRQFLAGS
bld r11, SYSREG_GM_OFFSET
brcc 1f
- rcall trace_hardirqs_on
+ call trace_hardirqs_on
1:
#endif
mfsr r2, SYSREG_SR
@@ -747,7 +747,7 @@ irq_level\level:
mov r11, sp
mov r12, \level
- rcall do_IRQ
+ call do_IRQ
lddsp r4, sp[REG_SR]
bfextu r4, r4, SYSREG_M0_OFFSET, 3
@@ -767,7 +767,7 @@ irq_level\level:
1:
#ifdef CONFIG_TRACE_IRQFLAGS
- rcall trace_hardirqs_on
+ call trace_hardirqs_on
#endif
popm r8-r9
mtsr rar_int\level, r8
@@ -807,7 +807,7 @@ irq_level\level:
lddsp r4, sp[REG_SR]
bld r4, SYSREG_GM_OFFSET
brcs 1b
- rcall preempt_schedule_irq
+ call preempt_schedule_irq
#endif
rjmp 1b
.endm
diff --git a/arch/avr32/kernel/irq.c b/arch/avr32/kernel/irq.c
index a8e767d836aa..9f572229d318 100644
--- a/arch/avr32/kernel/irq.c
+++ b/arch/avr32/kernel/irq.c
@@ -58,7 +58,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%3d: ", i);
for_each_online_cpu(cpu)
- seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-");
seq_printf(p, " %s", action->name);
for (action = action->next; action; action = action->next)
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c
index 43ae555ecb33..1bbe1da54869 100644
--- a/arch/avr32/kernel/process.c
+++ b/arch/avr32/kernel/process.c
@@ -332,7 +332,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
asmlinkage void ret_from_fork(void);
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S
index 673178e235f3..f7244cd02fbb 100644
--- a/arch/avr32/kernel/syscall-stubs.S
+++ b/arch/avr32/kernel/syscall-stubs.S
@@ -61,7 +61,7 @@ __sys_execve:
__sys_mmap2:
pushm lr
st.w --sp, ARG6
- rcall sys_mmap2
+ call sys_mmap2
sub sp, -4
popm pc
@@ -70,7 +70,7 @@ __sys_mmap2:
__sys_sendto:
pushm lr
st.w --sp, ARG6
- rcall sys_sendto
+ call sys_sendto
sub sp, -4
popm pc
@@ -79,7 +79,7 @@ __sys_sendto:
__sys_recvfrom:
pushm lr
st.w --sp, ARG6
- rcall sys_recvfrom
+ call sys_recvfrom
sub sp, -4
popm pc
@@ -88,7 +88,7 @@ __sys_recvfrom:
__sys_pselect6:
pushm lr
st.w --sp, ARG6
- rcall sys_pselect6
+ call sys_pselect6
sub sp, -4
popm pc
@@ -97,7 +97,7 @@ __sys_pselect6:
__sys_splice:
pushm lr
st.w --sp, ARG6
- rcall sys_splice
+ call sys_splice
sub sp, -4
popm pc
@@ -106,7 +106,7 @@ __sys_splice:
__sys_epoll_pwait:
pushm lr
st.w --sp, ARG6
- rcall sys_epoll_pwait
+ call sys_epoll_pwait
sub sp, -4
popm pc
@@ -115,6 +115,6 @@ __sys_epoll_pwait:
__sys_sync_file_range:
pushm lr
st.w --sp, ARG6
- rcall sys_sync_file_range
+ call sys_sync_file_range
sub sp, -4
popm pc
diff --git a/arch/avr32/lib/strnlen_user.S b/arch/avr32/lib/strnlen_user.S
index 65ce11afa66a..e46f4724962b 100644
--- a/arch/avr32/lib/strnlen_user.S
+++ b/arch/avr32/lib/strnlen_user.S
@@ -48,7 +48,7 @@ adjust_length:
lddpc lr, _task_size
sub r11, lr, r12
mov r9, r11
- rcall __strnlen_user
+ call __strnlen_user
cp.w r12, r9
brgt 1f
popm pc
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index 3fbfd1e32a9e..7cc653798327 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -26,6 +26,9 @@
#include <mach/portmux.h>
#include <mach/sram.h>
+#include <sound/atmel-abdac.h>
+#include <sound/atmel-ac97c.h>
+
#include <video/atmel_lcdc.h>
#include "clock.h"
@@ -963,56 +966,68 @@ static struct resource atmel_usart3_resource[] = {
DEFINE_DEV_DATA(atmel_usart, 3);
DEV_CLK(usart, atmel_usart3, pba, 6);
-static inline void configure_usart0_pins(void)
+static inline void configure_usart0_pins(int flags)
{
u32 pin_mask = (1 << 8) | (1 << 9); /* RXD & TXD */
+ if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 6);
+ if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 7);
+ if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 10);
select_peripheral(PIOA, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);
}
-static inline void configure_usart1_pins(void)
+static inline void configure_usart1_pins(int flags)
{
u32 pin_mask = (1 << 17) | (1 << 18); /* RXD & TXD */
+ if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 19);
+ if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 20);
+ if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 16);
select_peripheral(PIOA, pin_mask, PERIPH_A, AT32_GPIOF_PULLUP);
}
-static inline void configure_usart2_pins(void)
+static inline void configure_usart2_pins(int flags)
{
u32 pin_mask = (1 << 26) | (1 << 27); /* RXD & TXD */
+ if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 30);
+ if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 29);
+ if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 28);
select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);
}
-static inline void configure_usart3_pins(void)
+static inline void configure_usart3_pins(int flags)
{
u32 pin_mask = (1 << 18) | (1 << 17); /* RXD & TXD */
+ if (flags & ATMEL_USART_RTS) pin_mask |= (1 << 16);
+ if (flags & ATMEL_USART_CTS) pin_mask |= (1 << 15);
+ if (flags & ATMEL_USART_CLK) pin_mask |= (1 << 19);
select_peripheral(PIOB, pin_mask, PERIPH_B, AT32_GPIOF_PULLUP);
}
static struct platform_device *__initdata at32_usarts[4];
-void __init at32_map_usart(unsigned int hw_id, unsigned int line)
+void __init at32_map_usart(unsigned int hw_id, unsigned int line, int flags)
{
struct platform_device *pdev;
switch (hw_id) {
case 0:
pdev = &atmel_usart0_device;
- configure_usart0_pins();
+ configure_usart0_pins(flags);
break;
case 1:
pdev = &atmel_usart1_device;
- configure_usart1_pins();
+ configure_usart1_pins(flags);
break;
case 2:
pdev = &atmel_usart2_device;
- configure_usart2_pins();
+ configure_usart2_pins(flags);
break;
case 3:
pdev = &atmel_usart3_device;
- configure_usart3_pins();
+ configure_usart3_pins(flags);
break;
default:
return;
@@ -1753,7 +1768,7 @@ at32_add_device_usba(unsigned int id, struct usba_platform_data *data)
if (platform_device_add_data(pdev, data, sizeof(usba_data)))
goto out_free_pdev;
- if (data->vbus_pin >= 0)
+ if (gpio_is_valid(data->vbus_pin))
at32_select_gpio(data->vbus_pin, 0);
usba0_pclk.dev = &pdev->dev;
@@ -1980,11 +1995,14 @@ static struct clk atmel_ac97c0_pclk = {
};
struct platform_device *__init
-at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data)
+at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,
+ unsigned int flags)
{
- struct platform_device *pdev;
- struct ac97c_platform_data _data;
- u32 pin_mask;
+ struct platform_device *pdev;
+ struct dw_dma_slave *rx_dws;
+ struct dw_dma_slave *tx_dws;
+ struct ac97c_platform_data _data;
+ u32 pin_mask;
if (id != 0)
return NULL;
@@ -1995,37 +2013,52 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data)
if (platform_device_add_resources(pdev, atmel_ac97c0_resource,
ARRAY_SIZE(atmel_ac97c0_resource)))
- goto fail;
+ goto out_free_resources;
if (!data) {
data = &_data;
memset(data, 0, sizeof(struct ac97c_platform_data));
- data->reset_pin = GPIO_PIN_NONE;
+ data->reset_pin = -ENODEV;
}
- data->dma_rx_periph_id = 3;
- data->dma_tx_periph_id = 4;
- data->dma_controller_id = 0;
+ rx_dws = &data->rx_dws;
+ tx_dws = &data->tx_dws;
+
+ /* Check if DMA slave interface for capture should be configured. */
+ if (flags & AC97C_CAPTURE) {
+ rx_dws->dma_dev = &dw_dmac0_device.dev;
+ rx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;
+ rx_dws->cfg_hi = DWC_CFGH_SRC_PER(3);
+ rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+ }
+
+ /* Check if DMA slave interface for playback should be configured. */
+ if (flags & AC97C_PLAYBACK) {
+ tx_dws->dma_dev = &dw_dmac0_device.dev;
+ tx_dws->reg_width = DW_DMA_SLAVE_WIDTH_16BIT;
+ tx_dws->cfg_hi = DWC_CFGH_DST_PER(4);
+ tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+ }
if (platform_device_add_data(pdev, data,
sizeof(struct ac97c_platform_data)))
- goto fail;
+ goto out_free_resources;
- pin_mask = (1 << 20) | (1 << 21); /* SDO & SYNC */
- pin_mask |= (1 << 22) | (1 << 23); /* SCLK & SDI */
+ /* SDO | SYNC | SCLK | SDI */
+ pin_mask = (1 << 20) | (1 << 21) | (1 << 22) | (1 << 23);
select_peripheral(PIOB, pin_mask, PERIPH_B, 0);
- /* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */
- if (data->reset_pin != GPIO_PIN_NONE)
- at32_select_gpio(data->reset_pin, 0);
+ if (gpio_is_valid(data->reset_pin))
+ at32_select_gpio(data->reset_pin, AT32_GPIOF_OUTPUT
+ | AT32_GPIOF_HIGH);
atmel_ac97c0_pclk.dev = &pdev->dev;
platform_device_add(pdev);
return pdev;
-fail:
+out_free_resources:
platform_device_put(pdev);
return NULL;
}
@@ -2053,21 +2086,34 @@ static struct clk abdac0_sample_clk = {
.index = 6,
};
-struct platform_device *__init at32_add_device_abdac(unsigned int id)
+struct platform_device *__init
+at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data)
{
- struct platform_device *pdev;
- u32 pin_mask;
+ struct platform_device *pdev;
+ struct dw_dma_slave *dws;
+ u32 pin_mask;
- if (id != 0)
+ if (id != 0 || !data)
return NULL;
- pdev = platform_device_alloc("abdac", id);
+ pdev = platform_device_alloc("atmel_abdac", id);
if (!pdev)
return NULL;
if (platform_device_add_resources(pdev, abdac0_resource,
ARRAY_SIZE(abdac0_resource)))
- goto err_add_resources;
+ goto out_free_resources;
+
+ dws = &data->dws;
+
+ dws->dma_dev = &dw_dmac0_device.dev;
+ dws->reg_width = DW_DMA_SLAVE_WIDTH_32BIT;
+ dws->cfg_hi = DWC_CFGH_DST_PER(2);
+ dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL);
+
+ if (platform_device_add_data(pdev, data,
+ sizeof(struct atmel_abdac_pdata)))
+ goto out_free_resources;
pin_mask = (1 << 20) | (1 << 22); /* DATA1 & DATAN1 */
pin_mask |= (1 << 21) | (1 << 23); /* DATA0 & DATAN0 */
@@ -2080,7 +2126,7 @@ struct platform_device *__init at32_add_device_abdac(unsigned int id)
platform_device_add(pdev);
return pdev;
-err_add_resources:
+out_free_resources:
platform_device_put(pdev);
return NULL;
}
diff --git a/arch/avr32/mach-at32ap/include/mach/at32ap700x.h b/arch/avr32/mach-at32ap/include/mach/at32ap700x.h
index 5c4c971eed8e..b9222bf895bc 100644
--- a/arch/avr32/mach-at32ap/include/mach/at32ap700x.h
+++ b/arch/avr32/mach-at32ap/include/mach/at32ap700x.h
@@ -171,25 +171,49 @@
ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) | \
ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
-#define ATMEL_LCDC_PRI_15B_DATA ( \
- ATMEL_LCDC(PC, DATA0) | ATMEL_LCDC(PC, DATA1) | \
+#define ATMEL_LCDC_PRI_18B_DATA ( \
ATMEL_LCDC(PC, DATA2) | ATMEL_LCDC(PC, DATA3) | \
ATMEL_LCDC(PC, DATA4) | ATMEL_LCDC(PC, DATA5) | \
- ATMEL_LCDC(PD, DATA8) | ATMEL_LCDC(PD, DATA9) | \
+ ATMEL_LCDC(PD, DATA6) | ATMEL_LCDC(PD, DATA7) | \
ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) | \
- ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA16) | \
- ATMEL_LCDC(PD, DATA17) | ATMEL_LCDC(PD, DATA18) | \
- ATMEL_LCDC(PD, DATA19) | ATMEL_LCDC(PD, DATA20))
+ ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA13) | \
+ ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) | \
+ ATMEL_LCDC(PD, DATA18) | ATMEL_LCDC(PD, DATA19) | \
+ ATMEL_LCDC(PD, DATA20) | ATMEL_LCDC(PD, DATA21) | \
+ ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
-#define ATMEL_LCDC_ALT_15B_DATA ( \
- ATMEL_LCDC(PE, DATA0) | ATMEL_LCDC(PE, DATA1) | \
+#define ATMEL_LCDC_ALT_18B_DATA ( \
ATMEL_LCDC(PE, DATA2) | ATMEL_LCDC(PE, DATA3) | \
ATMEL_LCDC(PE, DATA4) | ATMEL_LCDC(PC, DATA5) | \
- ATMEL_LCDC(PE, DATA8) | ATMEL_LCDC(PE, DATA9) | \
+ ATMEL_LCDC(PD, DATA6) | ATMEL_LCDC(PD, DATA7) | \
ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) | \
- ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PE, DATA16) | \
- ATMEL_LCDC(PE, DATA17) | ATMEL_LCDC(PE, DATA18) | \
- ATMEL_LCDC(PE, DATA19) | ATMEL_LCDC(PE, DATA20))
+ ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PD, DATA13) | \
+ ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) | \
+ ATMEL_LCDC(PE, DATA18) | ATMEL_LCDC(PE, DATA19) | \
+ ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) | \
+ ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
+
+#define ATMEL_LCDC_PRI_15B_DATA ( \
+ ATMEL_LCDC(PC, DATA3) | ATMEL_LCDC(PC, DATA4) | \
+ ATMEL_LCDC(PC, DATA5) | ATMEL_LCDC(PD, DATA6) | \
+ ATMEL_LCDC(PD, DATA7) | \
+ ATMEL_LCDC(PD, DATA11) | ATMEL_LCDC(PD, DATA12) | \
+ ATMEL_LCDC(PD, DATA13) | ATMEL_LCDC(PD, DATA14) | \
+ ATMEL_LCDC(PD, DATA15) | \
+ ATMEL_LCDC(PD, DATA19) | ATMEL_LCDC(PD, DATA20) | \
+ ATMEL_LCDC(PD, DATA21) | ATMEL_LCDC(PD, DATA22) | \
+ ATMEL_LCDC(PD, DATA23))
+
+#define ATMEL_LCDC_ALT_15B_DATA ( \
+ ATMEL_LCDC(PE, DATA3) | ATMEL_LCDC(PE, DATA4) | \
+ ATMEL_LCDC(PC, DATA5) | ATMEL_LCDC(PD, DATA6) | \
+ ATMEL_LCDC(PD, DATA7) | \
+ ATMEL_LCDC(PE, DATA11) | ATMEL_LCDC(PE, DATA12) | \
+ ATMEL_LCDC(PD, DATA13) | ATMEL_LCDC(PD, DATA14) | \
+ ATMEL_LCDC(PD, DATA15) | \
+ ATMEL_LCDC(PE, DATA19) | ATMEL_LCDC(PE, DATA20) | \
+ ATMEL_LCDC(PE, DATA21) | ATMEL_LCDC(PD, DATA22) | \
+ ATMEL_LCDC(PD, DATA23))
#define ATMEL_LCDC_PRI_CONTROL ( \
ATMEL_LCDC(PC, CC) | ATMEL_LCDC(PC, DVAL) | \
@@ -207,6 +231,10 @@
#define ATMEL_LCDC_ALT_24BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_24B_DATA)
+#define ATMEL_LCDC_PRI_18BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_18B_DATA)
+
+#define ATMEL_LCDC_ALT_18BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_18B_DATA)
+
#define ATMEL_LCDC_PRI_15BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_15B_DATA)
#define ATMEL_LCDC_ALT_15BIT (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_15B_DATA)
diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h
index cff8e84f78f2..0b8164281899 100644
--- a/arch/avr32/mach-at32ap/include/mach/board.h
+++ b/arch/avr32/mach-at32ap/include/mach/board.h
@@ -13,7 +13,7 @@
* in this array is chip-dependent.
*/
extern unsigned long at32_board_osc_rates[];
-
+
/*
* This used to add essential system devices, but this is now done
* automatically. Please don't use it in new board code.
@@ -26,12 +26,17 @@ static inline void __deprecated at32_add_system_devices(void)
#define ATMEL_MAX_UART 4
extern struct platform_device *atmel_default_console_device;
+/* Flags for selecting USART extra pins */
+#define ATMEL_USART_RTS 0x01
+#define ATMEL_USART_CTS 0x02
+#define ATMEL_USART_CLK 0x03
+
struct atmel_uart_data {
short use_dma_tx; /* use transmit DMA? */
short use_dma_rx; /* use receive DMA? */
void __iomem *regs; /* virtual base address, if any */
};
-void at32_map_usart(unsigned int hw_id, unsigned int line);
+void at32_map_usart(unsigned int hw_id, unsigned int line, int flags);
struct platform_device *at32_add_device_usart(unsigned int id);
struct eth_platform_data {
@@ -88,16 +93,15 @@ struct mci_platform_data;
struct platform_device *
at32_add_device_mci(unsigned int id, struct mci_platform_data *data);
-struct ac97c_platform_data {
- unsigned short dma_rx_periph_id;
- unsigned short dma_tx_periph_id;
- unsigned short dma_controller_id;
- int reset_pin;
-};
+struct ac97c_platform_data;
+struct platform_device *
+at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data,
+ unsigned int flags);
+
+struct atmel_abdac_pdata;
struct platform_device *
-at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data);
+at32_add_device_abdac(unsigned int id, struct atmel_abdac_pdata *data);
-struct platform_device *at32_add_device_abdac(unsigned int id);
struct platform_device *at32_add_device_psif(unsigned int id);
struct cf_platform_data {
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index ce4e4296b954..62d4abbaa654 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -250,21 +250,3 @@ asmlinkage void do_bus_error(unsigned long addr, int write_access,
dump_dtlb();
die("Bus Error", regs, SIGKILL);
}
-
-/*
- * This functionality is currently not possible to implement because
- * we're using segmentation to ensure a fixed mapping of the kernel
- * virtual address space.
- *
- * It would be possible to implement this, but it would require us to
- * disable segmentation at startup and load the kernel mappings into
- * the TLB like any other pages. There will be lots of trickery to
- * avoid recursive invocation of the TLB miss handler, though...
- */
-#ifdef CONFIG_DEBUG_PAGEALLOC
-void kernel_map_pages(struct page *page, int numpages, int enable)
-{
-
-}
-EXPORT_SYMBOL(kernel_map_pages);
-#endif
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 0c1f86e3e44a..3640cdc38aac 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -777,7 +777,7 @@ config CACHELINE_ALIGNED_L1
default n if BF54x
depends on !BF531
help
- If enabled, cacheline_anligned data is linked
+ If enabled, cacheline_aligned data is linked
into L1 data memory. (less latency)
config SYSCALL_TAB_L1
@@ -957,7 +957,7 @@ config MPU
memory they do not own. This comes at a performance penalty
and is recommended only for debugging.
-comment "Asynchonous Memory Configuration"
+comment "Asynchronous Memory Configuration"
menu "EBIU_AMGCTL Global Control"
config C_AMCKEN
@@ -989,7 +989,7 @@ config C_B3PEN
default n
choice
- prompt"Enable Asynchonous Memory Banks"
+ prompt "Enable Asynchronous Memory Banks"
default C_AMBEN_ALL
config C_AMBEN
diff --git a/arch/blackfin/configs/BF518F-EZBRD_defconfig b/arch/blackfin/configs/BF518F-EZBRD_defconfig
index 281f4b60e603..c121d6e6e2b8 100644
--- a/arch/blackfin/configs/BF518F-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF518F-EZBRD_defconfig
@@ -1,7 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Feb 20 10:01:44 2009
+# Linux kernel version: 2.6.28.7
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -43,7 +42,7 @@ CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +55,13 @@ CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
-CONFIG_AIO=y
+# CONFIG_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
@@ -314,7 +313,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
-CONFIG_BFIN_GPTIMERS=y
+CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
@@ -375,7 +374,6 @@ CONFIG_BINFMT_ZFLAT=y
#
# CONFIG_PM is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# CPU Frequency scaling
@@ -634,6 +632,7 @@ CONFIG_BFIN_RX_DESC_NUM=20
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
@@ -793,6 +792,7 @@ CONFIG_SPI_MASTER=y
#
CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
#
@@ -816,6 +816,12 @@ CONFIG_WATCHDOG=y
#
# CONFIG_SOFT_WATCHDOG is not set
CONFIG_BFIN_WDT=y
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -865,7 +871,26 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_SDH_BFIN=m
+CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND=y
+CONFIG_SDH_BFIN_ENABLE_SDIO_IRQ=y
+# CONFIG_MMC_SPI is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
@@ -1121,7 +1146,6 @@ CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_KGDB_TESTCASE is not set
CONFIG_DEBUG_VERBOSE=y
CONFIG_DEBUG_MMRS=y
# CONFIG_DEBUG_HWERR is not set
diff --git a/arch/blackfin/configs/BF526-EZBRD_defconfig b/arch/blackfin/configs/BF526-EZBRD_defconfig
index 8e2b855b8db7..3e562b2775d4 100644
--- a/arch/blackfin/configs/BF526-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF526-EZBRD_defconfig
@@ -1,6 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -42,7 +42,7 @@ CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -55,13 +55,13 @@ CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
-CONFIG_AIO=y
+# CONFIG_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
@@ -132,15 +132,20 @@ CONFIG_BF526=y
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
# CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
# CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
# CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
# CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
# CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=0
CONFIG_BF_REV_MAX=2
-CONFIG_BF_REV_0_0=y
-# CONFIG_BF_REV_0_1 is not set
+# CONFIG_BF_REV_0_0 is not set
+CONFIG_BF_REV_0_1=y
# CONFIG_BF_REV_0_2 is not set
# CONFIG_BF_REV_0_3 is not set
# CONFIG_BF_REV_0_4 is not set
@@ -313,7 +318,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
-CONFIG_BFIN_GPTIMERS=y
+CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
@@ -374,7 +379,6 @@ CONFIG_BINFMT_ZFLAT=y
#
# CONFIG_PM is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# CPU Frequency scaling
@@ -583,7 +587,9 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -637,6 +643,7 @@ CONFIG_BFIN_MAC_RMII=y
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
CONFIG_NETDEV_1000=y
# CONFIG_AX88180 is not set
CONFIG_NETDEV_10000=y
@@ -815,6 +822,7 @@ CONFIG_SPI_MASTER=y
#
CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
#
@@ -838,6 +846,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ATXP1 is not set
@@ -896,6 +905,12 @@ CONFIG_BFIN_WDT=y
# USB-based Watchdog Cards
#
# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -904,8 +919,10 @@ CONFIG_BFIN_WDT=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
#
# Multimedia devices
@@ -940,55 +957,7 @@ CONFIG_BFIN_WDT=y
# Console display driver support
#
CONFIG_DUMMY_CONSOLE=y
-CONFIG_SOUND=m
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-# CONFIG_SND_SEQUENCER is not set
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_PCM_OSS_PLUGINS=y
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-CONFIG_SND_SPI=y
-
-#
-# ALSA Blackfin devices
-#
-# CONFIG_SND_BLACKFIN_AD1836 is not set
-# CONFIG_SND_BFIN_AD73322 is not set
-CONFIG_SND_USB=y
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_CAIAQ is not set
-CONFIG_SND_SOC=m
-CONFIG_SND_SOC_AC97_BUS=y
-CONFIG_SND_BF5XX_I2S=m
-CONFIG_SND_BF5XX_SOC_SSM2602=m
-# CONFIG_SND_BF5XX_SOC_AD73311 is not set
-CONFIG_SND_BF5XX_AC97=m
-CONFIG_SND_BF5XX_MMAP_SUPPORT=y
-# CONFIG_SND_BF5XX_MULTICHAN_SUPPORT is not set
-CONFIG_SND_BF5XX_SOC_SPORT=m
-CONFIG_SND_BF5XX_SOC_I2S=m
-CONFIG_SND_BF5XX_SOC_AC97=m
-CONFIG_SND_BF5XX_SOC_AD1980=m
-CONFIG_SND_BF5XX_SPORT_NUM=0
-# CONFIG_SND_BF5XX_HAVE_COLD_RESET is not set
-# CONFIG_SND_SOC_ALL_CODECS is not set
-CONFIG_SND_SOC_AD1980=m
-CONFIG_SND_SOC_SSM2602=m
-# CONFIG_SOUND_PRIME is not set
-CONFIG_AC97_BUS=m
+# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
@@ -1063,13 +1032,15 @@ CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_MUSB_SOC=y
#
-# Blackfin high speed USB support
+# Blackfin high speed USB Support
#
CONFIG_USB_MUSB_HOST=y
# CONFIG_USB_MUSB_PERIPHERAL is not set
# CONFIG_USB_MUSB_OTG is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
CONFIG_USB_MUSB_HDRC_HCD=y
CONFIG_MUSB_PIO_ONLY=y
+CONFIG_MUSB_DMA_POLL=y
# CONFIG_USB_MUSB_DEBUG is not set
#
@@ -1081,18 +1052,33 @@ CONFIG_MUSB_PIO_ONLY=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
#
#
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
# CONFIG_USB_LIBUSUAL is not set
#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
#
# USB port drivers
@@ -1124,6 +1110,30 @@ CONFIG_MUSB_PIO_ONLY=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_NET2272 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -1158,12 +1168,14 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
#
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
@@ -1384,6 +1396,13 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
@@ -1423,6 +1442,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
index a50050f17706..911b5dba1dbc 100644
--- a/arch/blackfin/configs/BF527-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -1,6 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -36,14 +36,13 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
-# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +55,13 @@ CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
-CONFIG_AIO=y
+# CONFIG_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
@@ -133,15 +132,20 @@ CONFIG_BF527=y
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
# CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
# CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
# CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
# CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
# CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=0
CONFIG_BF_REV_MAX=2
-CONFIG_BF_REV_0_0=y
-# CONFIG_BF_REV_0_1 is not set
+# CONFIG_BF_REV_0_0 is not set
+CONFIG_BF_REV_0_1=y
# CONFIG_BF_REV_0_2 is not set
# CONFIG_BF_REV_0_3 is not set
# CONFIG_BF_REV_0_4 is not set
@@ -314,7 +318,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
-CONFIG_BFIN_GPTIMERS=y
+CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
@@ -375,7 +379,6 @@ CONFIG_BINFMT_ZFLAT=y
#
# CONFIG_PM is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# CPU Frequency scaling
@@ -626,7 +629,9 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -681,6 +686,7 @@ CONFIG_BFIN_MAC_RMII=y
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
CONFIG_NETDEV_1000=y
# CONFIG_AX88180 is not set
CONFIG_NETDEV_10000=y
@@ -755,8 +761,8 @@ CONFIG_INPUT_MISC=y
# CONFIG_SPI_ADC_BF533 is not set
# CONFIG_BF5xx_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
-# CONFIG_BFIN_SPORT is not set
+CONFIG_BF5xx_PPI=m
+CONFIG_BFIN_SPORT=m
# CONFIG_BFIN_TIMER_LATENCY is not set
# CONFIG_TWI_LCD is not set
CONFIG_BFIN_DMA_INTERFACE=m
@@ -859,6 +865,7 @@ CONFIG_SPI_MASTER=y
#
CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
#
@@ -871,60 +878,7 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_AD7414 is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_F75375S is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_LM93 is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_DME1737 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_ADS7828 is not set
-# CONFIG_SENSORS_THMC50 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83L786NG is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
@@ -940,6 +894,12 @@ CONFIG_BFIN_WDT=y
# USB-based Watchdog Cards
#
# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -948,8 +908,10 @@ CONFIG_BFIN_WDT=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
#
# Multimedia devices
@@ -1000,6 +962,7 @@ CONFIG_FB_BFIN_T350MCQB=y
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=m
CONFIG_LCD_LTV350QV=m
@@ -1152,13 +1115,15 @@ CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_MUSB_SOC=y
#
-# Blackfin high speed USB support
+# Blackfin high speed USB Support
#
CONFIG_USB_MUSB_HOST=y
# CONFIG_USB_MUSB_PERIPHERAL is not set
# CONFIG_USB_MUSB_OTG is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
CONFIG_USB_MUSB_HDRC_HCD=y
CONFIG_MUSB_PIO_ONLY=y
+CONFIG_MUSB_DMA_POLL=y
# CONFIG_USB_MUSB_DEBUG is not set
#
@@ -1170,18 +1135,33 @@ CONFIG_MUSB_PIO_ONLY=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
#
#
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
# CONFIG_USB_LIBUSUAL is not set
#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
#
# USB port drivers
@@ -1213,6 +1193,30 @@ CONFIG_MUSB_PIO_ONLY=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_NET2272 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -1247,12 +1251,14 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
#
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
@@ -1473,6 +1479,13 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
@@ -1512,6 +1525,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig
index 0a2a00d63887..4c41e03efe0f 100644
--- a/arch/blackfin/configs/BF533-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF533-EZKIT_defconfig
@@ -1,6 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -36,14 +36,13 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
-# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +55,13 @@ CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
-CONFIG_AIO=y
+# CONFIG_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
@@ -133,10 +132,15 @@ CONFIG_BF533=y
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
# CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
# CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
# CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
# CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
# CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=3
CONFIG_BF_REV_MAX=6
@@ -157,7 +161,6 @@ CONFIG_BFIN533_EZKIT=y
# CONFIG_BFIN533_BLUETECHNIX_CM is not set
# CONFIG_H8606_HVSISTEMAS is not set
# CONFIG_BFIN532_IP0X is not set
-# CONFIG_GENERIC_BF533_BOARD is not set
#
# BF533/2/1 Specific Configuration
@@ -277,7 +280,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
-# CONFIG_BFIN_GPTIMERS is not set
+CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
@@ -575,6 +578,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -608,6 +612,7 @@ CONFIG_SMC91X=y
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
CONFIG_NETDEV_1000=y
# CONFIG_AX88180 is not set
CONFIG_NETDEV_10000=y
@@ -714,6 +719,7 @@ CONFIG_SPI_MASTER=y
#
CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
#
@@ -726,22 +732,7 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
@@ -752,6 +743,12 @@ CONFIG_WATCHDOG=y
#
# CONFIG_SOFT_WATCHDOG is not set
CONFIG_BFIN_WDT=y
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -760,7 +757,7 @@ CONFIG_BFIN_WDT=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_WM8400 is not set
+# CONFIG_REGULATOR is not set
#
# Multimedia devices
@@ -826,6 +823,7 @@ CONFIG_RTC_INTF_DEV=y
#
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
@@ -1046,6 +1044,13 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
@@ -1084,6 +1089,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig
index eb027587a355..9c482cd1b343 100644
--- a/arch/blackfin/configs/BF533-STAMP_defconfig
+++ b/arch/blackfin/configs/BF533-STAMP_defconfig
@@ -1,6 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -36,14 +36,13 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
-# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +55,13 @@ CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
-CONFIG_AIO=y
+# CONFIG_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
@@ -133,10 +132,15 @@ CONFIG_BF533=y
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
# CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
# CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
# CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
# CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
# CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=3
CONFIG_BF_REV_MAX=6
@@ -157,7 +161,6 @@ CONFIG_BFIN533_STAMP=y
# CONFIG_BFIN533_BLUETECHNIX_CM is not set
# CONFIG_H8606_HVSISTEMAS is not set
# CONFIG_BFIN532_IP0X is not set
-# CONFIG_GENERIC_BF533_BOARD is not set
#
# BF533/2/1 Specific Configuration
@@ -277,7 +280,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
-# CONFIG_BFIN_GPTIMERS is not set
+CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
@@ -578,7 +581,9 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -612,6 +617,7 @@ CONFIG_SMC91X=y
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
CONFIG_NETDEV_1000=y
# CONFIG_AX88180 is not set
CONFIG_NETDEV_10000=y
@@ -671,10 +677,10 @@ CONFIG_CONFIG_INPUT_PCF8574=m
# CONFIG_SPI_ADC_BF533 is not set
# CONFIG_BF5xx_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
-CONFIG_BFIN_SPORT=y
+CONFIG_BF5xx_PPI=m
+CONFIG_BFIN_SPORT=m
# CONFIG_BFIN_TIMER_LATENCY is not set
-CONFIG_TWI_LCD=m
+# CONFIG_TWI_LCD is not set
CONFIG_BFIN_DMA_INTERFACE=m
CONFIG_SIMPLE_GPIO=m
# CONFIG_VT is not set
@@ -765,6 +771,7 @@ CONFIG_SPI_MASTER=y
#
CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
#
@@ -777,60 +784,7 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_AD7414 is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_F75375S is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_LM93 is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_DME1737 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_ADS7828 is not set
-# CONFIG_SENSORS_THMC50 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83L786NG is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
@@ -841,6 +795,12 @@ CONFIG_WATCHDOG=y
#
# CONFIG_SOFT_WATCHDOG is not set
CONFIG_BFIN_WDT=y
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -851,6 +811,7 @@ CONFIG_BFIN_WDT=y
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
#
# Multimedia devices
@@ -909,6 +870,7 @@ CONFIG_ADV7393_1XMEM=y
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -1018,12 +980,14 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
#
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
@@ -1244,6 +1208,13 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
@@ -1282,6 +1253,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig
index 9e62b9f40eb1..591f6edda4f7 100644
--- a/arch/blackfin/configs/BF537-STAMP_defconfig
+++ b/arch/blackfin/configs/BF537-STAMP_defconfig
@@ -1,7 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
-# Tue Dec 30 17:24:37 2008
+# Linux kernel version: 2.6.28.7
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -37,14 +36,13 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
-# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -57,13 +55,13 @@ CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
-CONFIG_AIO=y
+# CONFIG_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
@@ -134,10 +132,15 @@ CONFIG_BF537=y
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
# CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
# CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
# CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
# CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
# CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=2
CONFIG_BF_REV_MAX=3
@@ -184,7 +187,6 @@ CONFIG_BFIN537_STAMP=y
# CONFIG_BFIN537_BLUETECHNIX_TCM is not set
# CONFIG_PNAV10 is not set
# CONFIG_CAMSIG_MINOTAUR is not set
-# CONFIG_GENERIC_BF537_BOARD is not set
#
# BF537 Specific Configuration
@@ -589,7 +591,9 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -644,6 +648,7 @@ CONFIG_BFIN_RX_DESC_NUM=20
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
CONFIG_NETDEV_1000=y
# CONFIG_AX88180 is not set
CONFIG_NETDEV_10000=y
@@ -706,10 +711,10 @@ CONFIG_SERIO_LIBPS2=y
# CONFIG_SPI_ADC_BF533 is not set
# CONFIG_BF5xx_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
+CONFIG_BF5xx_PPI=m
CONFIG_BFIN_SPORT=m
# CONFIG_BFIN_TIMER_LATENCY is not set
-CONFIG_TWI_LCD=m
+# CONFIG_TWI_LCD is not set
CONFIG_BFIN_DMA_INTERFACE=m
CONFIG_SIMPLE_GPIO=m
# CONFIG_VT is not set
@@ -808,6 +813,7 @@ CONFIG_SPI_MASTER=y
#
CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
#
@@ -820,60 +826,7 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_AD7414 is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_F75375S is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_LM93 is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_DME1737 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_ADS7828 is not set
-# CONFIG_SENSORS_THMC50 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83L786NG is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
@@ -884,6 +837,12 @@ CONFIG_WATCHDOG=y
#
# CONFIG_SOFT_WATCHDOG is not set
CONFIG_BFIN_WDT=y
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -894,6 +853,7 @@ CONFIG_BFIN_WDT=y
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
#
# Multimedia devices
@@ -957,6 +917,7 @@ CONFIG_ADV7393_1XMEM=y
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=m
# CONFIG_LCD_LTV350QV is not set
@@ -1074,12 +1035,14 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
#
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
@@ -1300,6 +1263,13 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
@@ -1338,6 +1308,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/blackfin/configs/BF538-EZKIT_defconfig b/arch/blackfin/configs/BF538-EZKIT_defconfig
index dd6ad6be1c87..1a8e8c3adf98 100644
--- a/arch/blackfin/configs/BF538-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF538-EZKIT_defconfig
@@ -1,6 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -42,7 +42,7 @@ CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -55,13 +55,13 @@ CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
-CONFIG_AIO=y
+# CONFIG_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
@@ -132,10 +132,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_BF538=y
# CONFIG_BF539 is not set
# CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
# CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
# CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
# CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
# CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=4
CONFIG_BF_REV_MAX=5
@@ -293,7 +298,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
-CONFIG_BFIN_GPTIMERS=y
+CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
@@ -354,7 +359,6 @@ CONFIG_BINFMT_ZFLAT=y
#
# CONFIG_PM is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# CPU Frequency scaling
@@ -645,6 +649,7 @@ CONFIG_SMC91X=y
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
@@ -690,7 +695,7 @@ CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_AD7877 is not set
# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
CONFIG_TOUCHSCREEN_AD7879_SPI=y
-CONFIG_TOUCHSCREEN_AD7879=m
+CONFIG_TOUCHSCREEN_AD7879=y
# CONFIG_TOUCHSCREEN_FUJITSU is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_TOUCHSCREEN_ELO is not set
@@ -718,8 +723,8 @@ CONFIG_INPUT_MISC=y
# CONFIG_SPI_ADC_BF533 is not set
# CONFIG_BF5xx_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
-CONFIG_BFIN_SPORT=y
+CONFIG_BF5xx_PPI=m
+CONFIG_BFIN_SPORT=m
# CONFIG_BFIN_TIMER_LATENCY is not set
# CONFIG_TWI_LCD is not set
CONFIG_BFIN_DMA_INTERFACE=m
@@ -762,7 +767,7 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
-CONFIG_I2C=y
+CONFIG_I2C=m
CONFIG_I2C_BOARDINFO=y
# CONFIG_I2C_CHARDEV is not set
CONFIG_I2C_HELPER_AUTO=y
@@ -774,7 +779,7 @@ CONFIG_I2C_HELPER_AUTO=y
#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
-CONFIG_I2C_BLACKFIN_TWI=y
+CONFIG_I2C_BLACKFIN_TWI=m
CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
# CONFIG_I2C_GPIO is not set
# CONFIG_I2C_OCORES is not set
@@ -818,6 +823,7 @@ CONFIG_SPI_MASTER=y
#
CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
#
@@ -830,60 +836,7 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_AD7414 is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_F75375S is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_LM93 is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_DME1737 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_ADS7828 is not set
-# CONFIG_SENSORS_THMC50 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83L786NG is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
@@ -894,6 +847,12 @@ CONFIG_WATCHDOG=y
#
# CONFIG_SOFT_WATCHDOG is not set
CONFIG_BFIN_WDT=y
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -904,6 +863,7 @@ CONFIG_BFIN_WDT=y
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
#
# Multimedia devices
@@ -954,6 +914,7 @@ CONFIG_FB_BFIN_LQ035Q1=m
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -1007,12 +968,14 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
#
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
@@ -1233,6 +1196,13 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
@@ -1271,6 +1241,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
index 6bc2fb1b2a70..2cd1c2b218d7 100644
--- a/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -1,6 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -36,14 +36,13 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
-# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +55,13 @@ CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
-CONFIG_AIO=y
+# CONFIG_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
@@ -133,16 +132,21 @@ CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
# CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
# CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
# CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
CONFIG_BF548=y
+# CONFIG_BF548M is not set
# CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=0
CONFIG_BF_REV_MAX=2
-CONFIG_BF_REV_0_0=y
+# CONFIG_BF_REV_0_0 is not set
# CONFIG_BF_REV_0_1 is not set
-# CONFIG_BF_REV_0_2 is not set
+CONFIG_BF_REV_0_2=y
# CONFIG_BF_REV_0_3 is not set
# CONFIG_BF_REV_0_4 is not set
# CONFIG_BF_REV_0_5 is not set
@@ -348,7 +352,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
-# CONFIG_BFIN_GPTIMERS is not set
+CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
CONFIG_DMA_UNCACHED_2M=y
# CONFIG_DMA_UNCACHED_1M is not set
@@ -413,7 +417,6 @@ CONFIG_BINFMT_ZFLAT=y
#
# CONFIG_PM is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# CPU Frequency scaling
@@ -512,9 +515,9 @@ CONFIG_IRCOMM=m
#
CONFIG_IRTTY_SIR=m
CONFIG_BFIN_SIR=m
-CONFIG_BFIN_SIR3=y
# CONFIG_BFIN_SIR0 is not set
# CONFIG_BFIN_SIR2 is not set
+CONFIG_BFIN_SIR3=y
CONFIG_SIR_BFIN_DMA=y
# CONFIG_SIR_BFIN_PIO is not set
@@ -538,7 +541,8 @@ CONFIG_SIR_BFIN_DMA=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
# CONFIG_RFKILL is not set
@@ -554,7 +558,9 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
@@ -668,7 +674,9 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -743,6 +751,7 @@ CONFIG_SMSC911X=y
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
CONFIG_NETDEV_1000=y
# CONFIG_AX88180 is not set
CONFIG_NETDEV_10000=y
@@ -751,8 +760,16 @@ CONFIG_NETDEV_10000=y
# Wireless LAN
#
# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=m
+# CONFIG_LIBERTAS_USB is not set
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_POWEROF2_BLOCKSIZE_ONLY=y
+# CONFIG_LIBERTAS_DEBUG is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_HOSTAP is not set
#
# USB Network Adapters
@@ -844,8 +861,8 @@ CONFIG_INPUT_MISC=y
# CONFIG_SPI_ADC_BF533 is not set
# CONFIG_BF5xx_PPIFCD is not set
# CONFIG_BFIN_SIMPLE_TIMER is not set
-# CONFIG_BF5xx_PPI is not set
-# CONFIG_BFIN_SPORT is not set
+CONFIG_BF5xx_PPI=m
+CONFIG_BFIN_SPORT=m
# CONFIG_BFIN_TIMER_LATENCY is not set
# CONFIG_TWI_LCD is not set
CONFIG_BFIN_DMA_INTERFACE=m
@@ -950,6 +967,7 @@ CONFIG_SPI_MASTER=y
#
CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
#
@@ -962,60 +980,7 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_AD7414 is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_F75375S is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_LM93 is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_DME1737 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_ADS7828 is not set
-# CONFIG_SENSORS_THMC50 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83L786NG is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
@@ -1031,6 +996,12 @@ CONFIG_BFIN_WDT=y
# USB-based Watchdog Cards
#
# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -1039,8 +1010,10 @@ CONFIG_BFIN_WDT=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
#
# Multimedia devices
@@ -1092,6 +1065,7 @@ CONFIG_FB_BF54X_LQ043=y
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -1243,15 +1217,15 @@ CONFIG_USB_MUSB_HDRC=y
CONFIG_USB_MUSB_SOC=y
#
-# Blackfin high speed USB support
+# Blackfin high speed USB Support
#
CONFIG_USB_MUSB_HOST=y
# CONFIG_USB_MUSB_PERIPHERAL is not set
# CONFIG_USB_MUSB_OTG is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
CONFIG_USB_MUSB_HDRC_HCD=y
-# CONFIG_MUSB_PIO_ONLY is not set
-CONFIG_USB_INVENTRA_DMA=y
-# CONFIG_USB_TI_CPPI_DMA is not set
+CONFIG_MUSB_PIO_ONLY=y
+CONFIG_MUSB_DMA_POLL=y
# CONFIG_USB_MUSB_DEBUG is not set
#
@@ -1263,11 +1237,11 @@ CONFIG_USB_INVENTRA_DMA=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
#
#
-# may also be needed; see USB_STORAGE Help for more information
+# see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
@@ -1321,7 +1295,31 @@ CONFIG_USB_STORAGE=m
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
-CONFIG_MMC=m
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_NET2272 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
@@ -1337,8 +1335,9 @@ CONFIG_MMC_BLOCK_BOUNCE=y
# MMC/SD/SDIO Host Controller Drivers
#
# CONFIG_MMC_SDHCI is not set
-CONFIG_SDH_BFIN=m
+CONFIG_SDH_BFIN=y
# CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND is not set
+# CONFIG_SDH_BFIN_ENABLE_SDIO_IRQ is not set
# CONFIG_MMC_SPI is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -1373,12 +1372,14 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
#
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
@@ -1641,6 +1642,13 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
@@ -1680,6 +1688,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig
index 69714fb3e608..4a6ea8e31df7 100644
--- a/arch/blackfin/configs/BF561-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF561-EZKIT_defconfig
@@ -1,6 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -36,14 +36,13 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
-# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +55,13 @@ CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
-CONFIG_AIO=y
+# CONFIG_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
@@ -133,10 +132,15 @@ CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
# CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
# CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
# CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
# CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
# CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
CONFIG_BF561=y
# CONFIG_SMP is not set
CONFIG_BF_REV_MIN=3
@@ -166,7 +170,6 @@ CONFIG_IRQ_SPI_ERROR=7
CONFIG_BFIN561_EZKIT=y
# CONFIG_BFIN561_TEPLA is not set
# CONFIG_BFIN561_BLUETECHNIX_CM is not set
-# CONFIG_GENERIC_BF561_BOARD is not set
#
# BF561 Specific Configuration
@@ -316,7 +319,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_VIRT_TO_BUS=y
-# CONFIG_BFIN_GPTIMERS is not set
+CONFIG_BFIN_GPTIMERS=m
# CONFIG_DMA_UNCACHED_4M is not set
# CONFIG_DMA_UNCACHED_2M is not set
CONFIG_DMA_UNCACHED_1M=y
@@ -382,7 +385,6 @@ CONFIG_BINFMT_ZFLAT=y
#
# CONFIG_PM is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# CPU Frequency scaling
@@ -612,6 +614,7 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -645,6 +648,7 @@ CONFIG_SMC91X=y
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
CONFIG_NETDEV_1000=y
# CONFIG_AX88180 is not set
CONFIG_NETDEV_10000=y
@@ -751,6 +755,7 @@ CONFIG_SPI_MASTER=y
#
CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
#
@@ -763,22 +768,7 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
@@ -789,6 +779,12 @@ CONFIG_WATCHDOG=y
#
# CONFIG_SOFT_WATCHDOG is not set
CONFIG_BFIN_WDT=y
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -797,7 +793,7 @@ CONFIG_BFIN_WDT=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_WM8400 is not set
+# CONFIG_REGULATOR is not set
#
# Multimedia devices
@@ -1041,6 +1037,13 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
@@ -1079,6 +1082,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/blackfin/configs/BlackStamp_defconfig b/arch/blackfin/configs/BlackStamp_defconfig
index 017c6ea071b5..ef1a2c84ace1 100644
--- a/arch/blackfin/configs/BlackStamp_defconfig
+++ b/arch/blackfin/configs/BlackStamp_defconfig
@@ -43,7 +43,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -56,7 +56,7 @@ CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
diff --git a/arch/blackfin/configs/CM-BF527_defconfig b/arch/blackfin/configs/CM-BF527_defconfig
index d880ef786770..e2fc588e4336 100644
--- a/arch/blackfin/configs/CM-BF527_defconfig
+++ b/arch/blackfin/configs/CM-BF527_defconfig
@@ -43,7 +43,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -56,13 +56,13 @@ CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
-CONFIG_AIO=y
+# CONFIG_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
diff --git a/arch/blackfin/configs/CM-BF533_defconfig b/arch/blackfin/configs/CM-BF533_defconfig
index 085211b9e4e4..65a8bbb8d647 100644
--- a/arch/blackfin/configs/CM-BF533_defconfig
+++ b/arch/blackfin/configs/CM-BF533_defconfig
@@ -46,7 +46,7 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_RELAY is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
CONFIG_SYSCTL_SYSCALL=y
@@ -57,7 +57,7 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
diff --git a/arch/blackfin/configs/CM-BF537E_defconfig b/arch/blackfin/configs/CM-BF537E_defconfig
index 750203e27a46..9b7e9d781145 100644
--- a/arch/blackfin/configs/CM-BF537E_defconfig
+++ b/arch/blackfin/configs/CM-BF537E_defconfig
@@ -46,7 +46,7 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_RELAY is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
CONFIG_SYSCTL_SYSCALL=y
@@ -57,7 +57,7 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
diff --git a/arch/blackfin/configs/CM-BF537U_defconfig b/arch/blackfin/configs/CM-BF537U_defconfig
index dec8a7d5cc0e..569523c1c034 100644
--- a/arch/blackfin/configs/CM-BF537U_defconfig
+++ b/arch/blackfin/configs/CM-BF537U_defconfig
@@ -46,7 +46,7 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_RELAY is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
CONFIG_SYSCTL_SYSCALL=y
@@ -57,7 +57,7 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
diff --git a/arch/blackfin/configs/CM-BF548_defconfig b/arch/blackfin/configs/CM-BF548_defconfig
index f410430b4e3d..035b635e599c 100644
--- a/arch/blackfin/configs/CM-BF548_defconfig
+++ b/arch/blackfin/configs/CM-BF548_defconfig
@@ -46,7 +46,7 @@ CONFIG_FAIR_USER_SCHED=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -57,7 +57,7 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
diff --git a/arch/blackfin/configs/CM-BF561_defconfig b/arch/blackfin/configs/CM-BF561_defconfig
index 346bc7af8f42..7015e42ccce5 100644
--- a/arch/blackfin/configs/CM-BF561_defconfig
+++ b/arch/blackfin/configs/CM-BF561_defconfig
@@ -46,7 +46,7 @@ CONFIG_FAIR_USER_SCHED=y
# CONFIG_RELAY is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
CONFIG_SYSCTL_SYSCALL=y
@@ -57,7 +57,7 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
diff --git a/arch/blackfin/configs/H8606_defconfig b/arch/blackfin/configs/H8606_defconfig
index bd553da15db8..dfc8e1ddd77a 100644
--- a/arch/blackfin/configs/H8606_defconfig
+++ b/arch/blackfin/configs/H8606_defconfig
@@ -45,7 +45,7 @@ CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -56,7 +56,7 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
diff --git a/arch/blackfin/configs/IP0X_defconfig b/arch/blackfin/configs/IP0X_defconfig
index 7db93874c987..95a5f91aebaa 100644
--- a/arch/blackfin/configs/IP0X_defconfig
+++ b/arch/blackfin/configs/IP0X_defconfig
@@ -46,7 +46,7 @@ CONFIG_SYSFS_DEPRECATED=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -57,7 +57,7 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
diff --git a/arch/blackfin/configs/PNAV-10_defconfig b/arch/blackfin/configs/PNAV-10_defconfig
index ad096702ac16..78e24080e7f1 100644
--- a/arch/blackfin/configs/PNAV-10_defconfig
+++ b/arch/blackfin/configs/PNAV-10_defconfig
@@ -1,6 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
+# Linux kernel version: 2.6.28.7
#
# CONFIG_MMU is not set
# CONFIG_FPU is not set
@@ -35,13 +35,12 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
-# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -53,13 +52,13 @@ CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
-CONFIG_AIO=y
+# CONFIG_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
@@ -130,10 +129,15 @@ CONFIG_BF537=y
# CONFIG_BF538 is not set
# CONFIG_BF539 is not set
# CONFIG_BF542 is not set
+# CONFIG_BF542M is not set
# CONFIG_BF544 is not set
+# CONFIG_BF544M is not set
# CONFIG_BF547 is not set
+# CONFIG_BF547M is not set
# CONFIG_BF548 is not set
+# CONFIG_BF548M is not set
# CONFIG_BF549 is not set
+# CONFIG_BF549M is not set
# CONFIG_BF561 is not set
CONFIG_BF_REV_MIN=2
CONFIG_BF_REV_MAX=3
@@ -180,7 +184,6 @@ CONFIG_IRQ_SPI=10
# CONFIG_BFIN537_BLUETECHNIX_TCM is not set
CONFIG_PNAV10=y
# CONFIG_CAMSIG_MINOTAUR is not set
-# CONFIG_GENERIC_BF537_BOARD is not set
#
# BF537 Specific Configuration
@@ -341,7 +344,6 @@ CONFIG_BINFMT_ZFLAT=y
#
# CONFIG_PM is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_PM_WAKEUP_BY_GPIO is not set
#
# CPU Frequency scaling
@@ -538,7 +540,9 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -593,6 +597,7 @@ CONFIG_BFIN_MAC_RMII=y
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
CONFIG_NETDEV_1000=y
# CONFIG_AX88180 is not set
CONFIG_NETDEV_10000=y
@@ -776,6 +781,7 @@ CONFIG_SPI_MASTER=y
#
CONFIG_SPI_BFIN=y
# CONFIG_SPI_BFIN_LOCK is not set
+# CONFIG_SPI_BFIN_SPORT is not set
# CONFIG_SPI_BITBANG is not set
#
@@ -799,6 +805,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ATXP1 is not set
@@ -845,6 +852,12 @@ CONFIG_HWMON=y
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
#
# Multifunction device drivers
@@ -853,8 +866,10 @@ CONFIG_HWMON=y
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
#
# Multimedia devices
@@ -910,6 +925,7 @@ CONFIG_FB_BFIN_LANDSCAPE=y
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
# CONFIG_LCD_LTV350QV is not set
@@ -966,7 +982,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
#
# CONFIG_USB_GADGET is not set
# CONFIG_MMC is not set
@@ -1003,12 +1019,14 @@ CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_DRV_M41T80 is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
#
# SPI RTC drivers
#
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
# CONFIG_RTC_DRV_MAX6902 is not set
# CONFIG_RTC_DRV_R9701 is not set
# CONFIG_RTC_DRV_RS5C348 is not set
@@ -1196,6 +1214,10 @@ CONFIG_FRAME_WARN=1024
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+
+#
+# Tracers
+#
# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
@@ -1230,6 +1252,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
diff --git a/arch/blackfin/configs/SRV1_defconfig b/arch/blackfin/configs/SRV1_defconfig
index a46529c6ade3..2bc0779d22ea 100644
--- a/arch/blackfin/configs/SRV1_defconfig
+++ b/arch/blackfin/configs/SRV1_defconfig
@@ -49,7 +49,7 @@ CONFIG_SYSFS_DEPRECATED=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -61,7 +61,7 @@ CONFIG_PRINTK=y
CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
diff --git a/arch/blackfin/configs/TCM-BF537_defconfig b/arch/blackfin/configs/TCM-BF537_defconfig
index 97a1f1d20dcf..e65b3a49214f 100644
--- a/arch/blackfin/configs/TCM-BF537_defconfig
+++ b/arch/blackfin/configs/TCM-BF537_defconfig
@@ -39,7 +39,7 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
+# CONFIG_SYSCTL is not set
CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
CONFIG_SYSCTL_SYSCALL=y
@@ -51,13 +51,13 @@ CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
+# CONFIG_FUTEX is not set
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
-CONFIG_AIO=y
+# CONFIG_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
diff --git a/arch/blackfin/include/asm/bfin5xx_spi.h b/arch/blackfin/include/asm/bfin5xx_spi.h
index 1306e6b22946..0292d58f9362 100644
--- a/arch/blackfin/include/asm/bfin5xx_spi.h
+++ b/arch/blackfin/include/asm/bfin5xx_spi.h
@@ -110,7 +110,7 @@
struct bfin5xx_spi_master {
u16 num_chipselect;
u8 enable_dma;
- u16 pin_req[4];
+ u16 pin_req[7];
};
/* spi_board_info.controller_data for SPI slave devices,
diff --git a/arch/blackfin/include/asm/bfin_sport.h b/arch/blackfin/include/asm/bfin_sport.h
index 65a651db5b07..b558908e1c79 100644
--- a/arch/blackfin/include/asm/bfin_sport.h
+++ b/arch/blackfin/include/asm/bfin_sport.h
@@ -9,6 +9,13 @@
#ifndef __BFIN_SPORT_H__
#define __BFIN_SPORT_H__
+#ifdef __KERNEL__
+#include <linux/cdev.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#endif
+
#define SPORT_MAJOR 237
#define SPORT_NR_DEVS 2
@@ -119,7 +126,7 @@ struct sport_dev {
int tx_len;
int tx_sent;
- int sport_err_irq;
+ int err_irq;
struct mutex mutex; /* mutual exclusion semaphore */
struct task_struct *task;
diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h
index d4a082ef75b4..fe139619351f 100644
--- a/arch/blackfin/include/asm/gpio.h
+++ b/arch/blackfin/include/asm/gpio.h
@@ -110,7 +110,7 @@
* MODIFICATION HISTORY :
**************************************************************/
-#ifndef BF548_FAMILY
+#ifndef CONFIG_BF54x
void set_gpio_dir(unsigned, unsigned short);
void set_gpio_inen(unsigned, unsigned short);
void set_gpio_polar(unsigned, unsigned short);
@@ -303,7 +303,10 @@ static inline void gpio_set_value(unsigned gpio, int value)
static inline int gpio_to_irq(unsigned gpio)
{
- return (gpio + GPIO_IRQ_BASE);
+ if (likely(gpio < MAX_BLACKFIN_GPIOS))
+ return gpio + GPIO_IRQ_BASE;
+
+ return -EINVAL;
}
static inline int irq_to_gpio(unsigned irq)
diff --git a/arch/blackfin/include/asm/gptimers.h b/arch/blackfin/include/asm/gptimers.h
index 0520d2aac8f3..b0f847ae4bf4 100644
--- a/arch/blackfin/include/asm/gptimers.h
+++ b/arch/blackfin/include/asm/gptimers.h
@@ -15,16 +15,16 @@
#include <asm/blackfin.h>
/*
- * BF537/BF527: 8 timers:
+ * BF51x/BF52x/BF537: 8 timers:
*/
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
+#if defined(CONFIG_BF51x) || defined(CONFIG_BF52x) || defined(BF537_FAMILY)
# define MAX_BLACKFIN_GPTIMERS 8
# define TIMER0_GROUP_REG TIMER_ENABLE
#endif
/*
* BF54x: 11 timers (BF542: 8 timers):
*/
-#if defined(BF548_FAMILY)
+#if defined(CONFIG_BF54x)
# ifdef CONFIG_BF542
# define MAX_BLACKFIN_GPTIMERS 8
# else
diff --git a/arch/blackfin/include/asm/socket.h b/arch/blackfin/include/asm/socket.h
index 2ca702e44d47..fac7fe9e1f8a 100644
--- a/arch/blackfin/include/asm/socket.h
+++ b/arch/blackfin/include/asm/socket.h
@@ -53,4 +53,7 @@
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
#endif /* _ASM_SOCKET_H */
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index 51dac55c524a..a0678da40532 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -69,7 +69,7 @@ enum {
static struct gpio_port_t * const gpio_array[] = {
#if defined(BF533_FAMILY) || defined(BF538_FAMILY)
(struct gpio_port_t *) FIO_FLAG_D,
-#elif defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#elif defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
(struct gpio_port_t *) PORTFIO,
(struct gpio_port_t *) PORTGIO,
(struct gpio_port_t *) PORTHIO,
@@ -77,7 +77,7 @@ static struct gpio_port_t * const gpio_array[] = {
(struct gpio_port_t *) FIO0_FLAG_D,
(struct gpio_port_t *) FIO1_FLAG_D,
(struct gpio_port_t *) FIO2_FLAG_D,
-#elif defined(BF548_FAMILY)
+#elif defined(CONFIG_BF54x)
(struct gpio_port_t *)PORTA_FER,
(struct gpio_port_t *)PORTB_FER,
(struct gpio_port_t *)PORTC_FER,
@@ -93,7 +93,7 @@ static struct gpio_port_t * const gpio_array[] = {
#endif
};
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
static unsigned short * const port_fer[] = {
(unsigned short *) PORTF_FER,
(unsigned short *) PORTG_FER,
@@ -109,11 +109,11 @@ static unsigned short * const port_mux[] = {
static const
u8 pmux_offset[][16] = {
-# if defined(BF527_FAMILY)
+# if defined(CONFIG_BF52x)
{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */
{ 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */
{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */
-# elif defined(BF518_FAMILY)
+# elif defined(CONFIG_BF51x)
{ 0, 2, 2, 2, 2, 2, 2, 4, 6, 6, 6, 8, 8, 8, 8, 10 }, /* PORTF */
{ 0, 0, 0, 2, 4, 6, 6, 6, 8, 10, 10, 12, 14, 14, 14, 14 }, /* PORTG */
{ 0, 0, 0, 0, 2, 2, 4, 6, 10, 10, 10, 10, 10, 10, 10, 10 }, /* PORTH */
@@ -139,7 +139,7 @@ static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM];
inline int check_gpio(unsigned gpio)
{
-#if defined(BF548_FAMILY)
+#if defined(CONFIG_BF54x)
if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
|| gpio == GPIO_PH14 || gpio == GPIO_PH15
|| gpio == GPIO_PJ14 || gpio == GPIO_PJ15)
@@ -187,13 +187,13 @@ static void port_setup(unsigned gpio, unsigned short usage)
if (check_gpio(gpio))
return;
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
if (usage == GPIO_USAGE)
*port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
else
*port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
SSYNC();
-#elif defined(BF548_FAMILY)
+#elif defined(CONFIG_BF54x)
if (usage == GPIO_USAGE)
gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
else
@@ -273,7 +273,7 @@ static void portmux_setup(unsigned short per)
}
}
}
-#elif defined(BF548_FAMILY)
+#elif defined(CONFIG_BF54x)
inline void portmux_setup(unsigned short per)
{
u32 pmux;
@@ -297,7 +297,7 @@ inline u16 get_portmux(unsigned short per)
return (pmux >> (2 * gpio_sub_n(ident)) & 0x3);
}
-#elif defined(BF527_FAMILY) || defined(BF518_FAMILY)
+#elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
inline void portmux_setup(unsigned short per)
{
u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per);
@@ -322,7 +322,7 @@ static int __init bfin_gpio_init(void)
arch_initcall(bfin_gpio_init);
-#ifndef BF548_FAMILY
+#ifndef CONFIG_BF54x
/***********************************************************
*
* FUNCTIONS: Blackfin General Purpose Ports Access Functions
@@ -489,7 +489,7 @@ static const unsigned int sic_iwr_irqs[] = {
IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX
#elif defined(BF538_FAMILY)
IRQ_PORTF_INTB
-#elif defined(BF527_FAMILY) || defined(BF518_FAMILY)
+#elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB
#elif defined(BF561_FAMILY)
IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB
@@ -586,7 +586,7 @@ u32 bfin_pm_standby_setup(void)
gpio_array[bank]->maskb = 0;
if (mask) {
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
gpio_bank_saved[bank].fer = *port_fer[bank];
#endif
gpio_bank_saved[bank].inen = gpio_array[bank]->inen;
@@ -631,7 +631,7 @@ void bfin_pm_standby_restore(void)
bank = gpio_bank(i);
if (mask) {
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
*port_fer[bank] = gpio_bank_saved[bank].fer;
#endif
gpio_array[bank]->inen = gpio_bank_saved[bank].inen;
@@ -657,9 +657,9 @@ void bfin_gpio_pm_hibernate_suspend(void)
for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
bank = gpio_bank(i);
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
gpio_bank_saved[bank].fer = *port_fer[bank];
-#if defined(BF527_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
gpio_bank_saved[bank].mux = *port_mux[bank];
#else
if (bank == 0)
@@ -685,8 +685,8 @@ void bfin_gpio_pm_hibernate_restore(void)
for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
bank = gpio_bank(i);
-#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY)
-#if defined(BF527_FAMILY) || defined(BF518_FAMILY)
+#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
+#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
*port_mux[bank] = gpio_bank_saved[bank].mux;
#else
if (bank == 0)
@@ -710,7 +710,7 @@ void bfin_gpio_pm_hibernate_restore(void)
#endif
-#else /* BF548_FAMILY */
+#else /* CONFIG_BF54x */
#ifdef CONFIG_PM
u32 bfin_pm_standby_setup(void)
@@ -762,7 +762,7 @@ unsigned short get_gpio_dir(unsigned gpio)
}
EXPORT_SYMBOL(get_gpio_dir);
-#endif /* BF548_FAMILY */
+#endif /* CONFIG_BF54x */
/***********************************************************
*
@@ -802,7 +802,8 @@ int peripheral_request(unsigned short per, const char *label)
*/
if (unlikely(!check_gpio(ident) &&
reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) {
- dump_stack();
+ if (system_state == SYSTEM_BOOTING)
+ dump_stack();
printk(KERN_ERR
"%s: Peripheral %d is already reserved as GPIO by %s !\n",
__func__, ident, get_label(ident));
@@ -817,7 +818,7 @@ int peripheral_request(unsigned short per, const char *label)
* be requested and used by several drivers
*/
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) {
#else
if (!(per & P_MAYSHARE)) {
@@ -830,7 +831,8 @@ int peripheral_request(unsigned short per, const char *label)
if (cmp_label(ident, label) == 0)
goto anyway;
- dump_stack();
+ if (system_state == SYSTEM_BOOTING)
+ dump_stack();
printk(KERN_ERR
"%s: Peripheral %d function %d is already reserved by %s !\n",
__func__, ident, P_FUNCT2MUX(per), get_label(ident));
@@ -946,14 +948,16 @@ int bfin_gpio_request(unsigned gpio, const char *label)
}
if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
- dump_stack();
+ if (system_state == SYSTEM_BOOTING)
+ dump_stack();
printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
gpio, get_label(gpio));
local_irq_restore_hw(flags);
return -EBUSY;
}
if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
- dump_stack();
+ if (system_state == SYSTEM_BOOTING)
+ dump_stack();
printk(KERN_ERR
"bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
gpio, get_label(gpio));
@@ -964,7 +968,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!"
" (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio);
}
-#ifndef BF548_FAMILY
+#ifndef CONFIG_BF54x
else { /* Reset POLAR setting when acquiring a gpio for the first time */
set_gpio_polar(gpio, 0);
}
@@ -993,7 +997,8 @@ void bfin_gpio_free(unsigned gpio)
local_irq_save_hw(flags);
if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
- dump_stack();
+ if (system_state == SYSTEM_BOOTING)
+ dump_stack();
gpio_error(gpio);
local_irq_restore_hw(flags);
return;
@@ -1017,7 +1022,8 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label)
local_irq_save_hw(flags);
if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
- dump_stack();
+ if (system_state == SYSTEM_BOOTING)
+ dump_stack();
printk(KERN_ERR
"bfin-gpio: GPIO %d is already reserved as gpio-irq !\n",
gpio);
@@ -1025,7 +1031,8 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label)
return -EBUSY;
}
if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
- dump_stack();
+ if (system_state == SYSTEM_BOOTING)
+ dump_stack();
printk(KERN_ERR
"bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
gpio, get_label(gpio));
@@ -1057,7 +1064,8 @@ void bfin_gpio_irq_free(unsigned gpio)
local_irq_save_hw(flags);
if (unlikely(!(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
- dump_stack();
+ if (system_state == SYSTEM_BOOTING)
+ dump_stack();
gpio_error(gpio);
local_irq_restore_hw(flags);
return;
@@ -1072,7 +1080,7 @@ void bfin_gpio_irq_free(unsigned gpio)
static inline void __bfin_gpio_direction_input(unsigned gpio)
{
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio);
#else
gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
@@ -1100,13 +1108,13 @@ EXPORT_SYMBOL(bfin_gpio_direction_input);
void bfin_gpio_irq_prepare(unsigned gpio)
{
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
unsigned long flags;
#endif
port_setup(gpio, GPIO_USAGE);
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
local_irq_save_hw(flags);
__bfin_gpio_direction_input(gpio);
local_irq_restore_hw(flags);
@@ -1135,7 +1143,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value)
gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
gpio_set_value(gpio, value);
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio);
#else
gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
@@ -1150,7 +1158,7 @@ EXPORT_SYMBOL(bfin_gpio_direction_output);
int bfin_gpio_get_value(unsigned gpio)
{
-#ifdef BF548_FAMILY
+#ifdef CONFIG_BF54x
return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)));
#else
unsigned long flags;
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 1ab5b532ec72..401bd32aa499 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -88,7 +88,7 @@ int show_interrupts(struct seq_file *p, void *v)
goto skip;
seq_printf(p, "%3d: ", i);
for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
seq_printf(p, " %8s", irq_desc[i].chip->name);
seq_printf(p, " %s", action->name);
for (action = action->next; action; action = action->next)
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 33e2e8993f7f..e040e03335ea 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -193,7 +193,7 @@ asmlinkage int bfin_clone(struct pt_regs *regs)
}
int
-copy_thread(int nr, unsigned long clone_flags,
+copy_thread(unsigned long clone_flags,
unsigned long usp, unsigned long topstk,
struct task_struct *p, struct pt_regs *regs)
{
@@ -337,7 +337,7 @@ int _access_ok(unsigned long addr, unsigned long size)
if (addr >= memory_mtd_end && (addr + size) <= physical_mem_end)
return 1;
-#ifdef CONFIG_ROMFS_MTD_FS
+#ifdef CONFIG_ROMFS_ON_MTD
/* For XIP, allow user space to use pointers within the ROMFS. */
if (addr >= memory_mtd_start && (addr + size) <= memory_mtd_end)
return 1;
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index 4b4341da0585..27952ae047d8 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -183,6 +183,7 @@ SECTIONS
. = ALIGN(4);
__etext_l1 = .;
}
+ ASSERT (SIZEOF(.text_l1) <= L1_CODE_LENGTH, "L1 text overflow!")
.data_l1 L1_DATA_A_START : AT(LOADADDR(.text_l1) + SIZEOF(.text_l1))
{
@@ -200,6 +201,7 @@ SECTIONS
. = ALIGN(4);
__ebss_l1 = .;
}
+ ASSERT (SIZEOF(.data_a_l1) <= L1_DATA_A_LENGTH, "L1 data A overflow!")
.data_b_l1 L1_DATA_B_START : AT(LOADADDR(.data_l1) + SIZEOF(.data_l1))
{
@@ -214,6 +216,7 @@ SECTIONS
. = ALIGN(4);
__ebss_b_l1 = .;
}
+ ASSERT (SIZEOF(.data_b_l1) <= L1_DATA_B_LENGTH, "L1 data B overflow!")
__l2_lma_start = LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1);
@@ -239,6 +242,7 @@ SECTIONS
. = ALIGN(4);
__ebss_l2 = .;
}
+ ASSERT (SIZEOF(.text_data_l1) <= L2_LENGTH, "L2 overflow!")
/* Force trailing alignment of our init section so that when we
* free our init memory, we don't leave behind a partial page.
diff --git a/arch/blackfin/mach-bf518/include/mach/blackfin.h b/arch/blackfin/mach-bf518/include/mach/blackfin.h
index d1a2b9ca6227..267bb7c8bfb5 100644
--- a/arch/blackfin/mach-bf518/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf518/include/mach/blackfin.h
@@ -32,8 +32,6 @@
#ifndef _MACH_BLACKFIN_H_
#define _MACH_BLACKFIN_H_
-#define BF518_FAMILY
-
#include "bf518.h"
#include "mem_map.h"
#include "defBF512.h"
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF514.h b/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
index 9521e178fb28..dfe492dfe54e 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
@@ -45,4 +45,71 @@
/* The following are the #defines needed by ADSP-BF514 that are not in the common header */
+/* Removable Storage Interface Registers */
+
+#define bfin_read_RSI_PWR_CTL() bfin_read16(RSI_PWR_CONTROL)
+#define bfin_write_RSI_PWR_CTL(val) bfin_write16(RSI_PWR_CONTROL, val)
+#define bfin_read_RSI_CLK_CTL() bfin_read16(RSI_CLK_CONTROL)
+#define bfin_write_RSI_CLK_CTL(val) bfin_write16(RSI_CLK_CONTROL, val)
+#define bfin_read_RSI_ARGUMENT() bfin_read32(RSI_ARGUMENT)
+#define bfin_write_RSI_ARGUMENT(val) bfin_write32(RSI_ARGUMENT, val)
+#define bfin_read_RSI_COMMAND() bfin_read16(RSI_COMMAND)
+#define bfin_write_RSI_COMMAND(val) bfin_write16(RSI_COMMAND, val)
+#define bfin_read_RSI_RESP_CMD() bfin_read16(RSI_RESP_CMD)
+#define bfin_write_RSI_RESP_CMD(val) bfin_write16(RSI_RESP_CMD, val)
+#define bfin_read_RSI_RESPONSE0() bfin_read32(RSI_RESPONSE0)
+#define bfin_write_RSI_RESPONSE0(val) bfin_write32(RSI_RESPONSE0, val)
+#define bfin_read_RSI_RESPONSE1() bfin_read32(RSI_RESPONSE1)
+#define bfin_write_RSI_RESPONSE1(val) bfin_write32(RSI_RESPONSE1, val)
+#define bfin_read_RSI_RESPONSE2() bfin_read32(RSI_RESPONSE2)
+#define bfin_write_RSI_RESPONSE2(val) bfin_write32(RSI_RESPONSE2, val)
+#define bfin_read_RSI_RESPONSE3() bfin_read32(RSI_RESPONSE3)
+#define bfin_write_RSI_RESPONSE3(val) bfin_write32(RSI_RESPONSE3, val)
+#define bfin_read_RSI_DATA_TIMER() bfin_read32(RSI_DATA_TIMER)
+#define bfin_write_RSI_DATA_TIMER(val) bfin_write32(RSI_DATA_TIMER, val)
+#define bfin_read_RSI_DATA_LGTH() bfin_read16(RSI_DATA_LGTH)
+#define bfin_write_RSI_DATA_LGTH(val) bfin_write16(RSI_DATA_LGTH, val)
+#define bfin_read_RSI_DATA_CTL() bfin_read16(RSI_DATA_CONTROL)
+#define bfin_write_RSI_DATA_CTL(val) bfin_write16(RSI_DATA_CONTROL, val)
+#define bfin_read_RSI_DATA_CNT() bfin_read16(RSI_DATA_CNT)
+#define bfin_write_RSI_DATA_CNT(val) bfin_write16(RSI_DATA_CNT, val)
+#define bfin_read_RSI_STATUS() bfin_read32(RSI_STATUS)
+#define bfin_write_RSI_STATUS(val) bfin_write32(RSI_STATUS, val)
+#define bfin_read_RSI_STATUS_CLR() bfin_read16(RSI_STATUSCL)
+#define bfin_write_RSI_STATUS_CLR(val) bfin_write16(RSI_STATUSCL, val)
+#define bfin_read_RSI_MASK0() bfin_read32(RSI_MASK0)
+#define bfin_write_RSI_MASK0(val) bfin_write32(RSI_MASK0, val)
+#define bfin_read_RSI_MASK1() bfin_read32(RSI_MASK1)
+#define bfin_write_RSI_MASK1(val) bfin_write32(RSI_MASK1, val)
+#define bfin_read_RSI_FIFO_CNT() bfin_read16(RSI_FIFO_CNT)
+#define bfin_write_RSI_FIFO_CNT(val) bfin_write16(RSI_FIFO_CNT, val)
+#define bfin_read_RSI_CEATA_CTL() bfin_read16(RSI_CEATA_CONTROL)
+#define bfin_write_RSI_CEATA_CTL(val) bfin_write16(RSI_CEATA_CONTROL, val)
+#define bfin_read_RSI_FIFO() bfin_read32(RSI_FIFO)
+#define bfin_write_RSI_FIFO(val) bfin_write32(RSI_FIFO, val)
+#define bfin_read_RSI_E_STATUS() bfin_read16(RSI_ESTAT)
+#define bfin_write_RSI_E_STATUS(val) bfin_write16(RSI_ESTAT, val)
+#define bfin_read_RSI_E_MASK() bfin_read16(RSI_EMASK)
+#define bfin_write_RSI_E_MASK(val) bfin_write16(RSI_EMASK, val)
+#define bfin_read_RSI_CFG() bfin_read16(RSI_CONFIG)
+#define bfin_write_RSI_CFG(val) bfin_write16(RSI_CONFIG, val)
+#define bfin_read_RSI_RD_WAIT_EN() bfin_read16(RSI_RD_WAIT_EN)
+#define bfin_write_RSI_RD_WAIT_EN(val) bfin_write16(RSI_RD_WAIT_EN, val)
+#define bfin_read_RSI_PID0() bfin_read16(RSI_PID0)
+#define bfin_write_RSI_PID0(val) bfin_write16(RSI_PID0, val)
+#define bfin_read_RSI_PID1() bfin_read16(RSI_PID1)
+#define bfin_write_RSI_PID1(val) bfin_write16(RSI_PID1, val)
+#define bfin_read_RSI_PID2() bfin_read16(RSI_PID2)
+#define bfin_write_RSI_PID2(val) bfin_write16(RSI_PID2, val)
+#define bfin_read_RSI_PID3() bfin_read16(RSI_PID3)
+#define bfin_write_RSI_PID3(val) bfin_write16(RSI_PID3, val)
+#define bfin_read_RSI_PID4() bfin_read16(RSI_PID4)
+#define bfin_write_RSI_PID4(val) bfin_write16(RSI_PID4, val)
+#define bfin_read_RSI_PID5() bfin_read16(RSI_PID5)
+#define bfin_write_RSI_PID5(val) bfin_write16(RSI_PID5, val)
+#define bfin_read_RSI_PID6() bfin_read16(RSI_PID6)
+#define bfin_write_RSI_PID6(val) bfin_write16(RSI_PID6, val)
+#define bfin_read_RSI_PID7() bfin_read16(RSI_PID7)
+#define bfin_write_RSI_PID7(val) bfin_write16(RSI_PID7, val)
+
#endif /* _CDEF_BF514_H */
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF516.h b/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
index 4e26ccfcef97..14df43d4677a 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
@@ -210,4 +210,71 @@
#define bfin_read_EMAC_TXC_ABORT() bfin_read32(EMAC_TXC_ABORT)
#define bfin_write_EMAC_TXC_ABORT(val) bfin_write32(EMAC_TXC_ABORT, val)
+/* Removable Storage Interface Registers */
+
+#define bfin_read_RSI_PWR_CTL() bfin_read16(RSI_PWR_CONTROL)
+#define bfin_write_RSI_PWR_CTL(val) bfin_write16(RSI_PWR_CONTROL, val)
+#define bfin_read_RSI_CLK_CTL() bfin_read16(RSI_CLK_CONTROL)
+#define bfin_write_RSI_CLK_CTL(val) bfin_write16(RSI_CLK_CONTROL, val)
+#define bfin_read_RSI_ARGUMENT() bfin_read32(RSI_ARGUMENT)
+#define bfin_write_RSI_ARGUMENT(val) bfin_write32(RSI_ARGUMENT, val)
+#define bfin_read_RSI_COMMAND() bfin_read16(RSI_COMMAND)
+#define bfin_write_RSI_COMMAND(val) bfin_write16(RSI_COMMAND, val)
+#define bfin_read_RSI_RESP_CMD() bfin_read16(RSI_RESP_CMD)
+#define bfin_write_RSI_RESP_CMD(val) bfin_write16(RSI_RESP_CMD, val)
+#define bfin_read_RSI_RESPONSE0() bfin_read32(RSI_RESPONSE0)
+#define bfin_write_RSI_RESPONSE0(val) bfin_write32(RSI_RESPONSE0, val)
+#define bfin_read_RSI_RESPONSE1() bfin_read32(RSI_RESPONSE1)
+#define bfin_write_RSI_RESPONSE1(val) bfin_write32(RSI_RESPONSE1, val)
+#define bfin_read_RSI_RESPONSE2() bfin_read32(RSI_RESPONSE2)
+#define bfin_write_RSI_RESPONSE2(val) bfin_write32(RSI_RESPONSE2, val)
+#define bfin_read_RSI_RESPONSE3() bfin_read32(RSI_RESPONSE3)
+#define bfin_write_RSI_RESPONSE3(val) bfin_write32(RSI_RESPONSE3, val)
+#define bfin_read_RSI_DATA_TIMER() bfin_read32(RSI_DATA_TIMER)
+#define bfin_write_RSI_DATA_TIMER(val) bfin_write32(RSI_DATA_TIMER, val)
+#define bfin_read_RSI_DATA_LGTH() bfin_read16(RSI_DATA_LGTH)
+#define bfin_write_RSI_DATA_LGTH(val) bfin_write16(RSI_DATA_LGTH, val)
+#define bfin_read_RSI_DATA_CTL() bfin_read16(RSI_DATA_CONTROL)
+#define bfin_write_RSI_DATA_CTL(val) bfin_write16(RSI_DATA_CONTROL, val)
+#define bfin_read_RSI_DATA_CNT() bfin_read16(RSI_DATA_CNT)
+#define bfin_write_RSI_DATA_CNT(val) bfin_write16(RSI_DATA_CNT, val)
+#define bfin_read_RSI_STATUS() bfin_read32(RSI_STATUS)
+#define bfin_write_RSI_STATUS(val) bfin_write32(RSI_STATUS, val)
+#define bfin_read_RSI_STATUS_CLR() bfin_read16(RSI_STATUSCL)
+#define bfin_write_RSI_STATUS_CLR(val) bfin_write16(RSI_STATUSCL, val)
+#define bfin_read_RSI_MASK0() bfin_read32(RSI_MASK0)
+#define bfin_write_RSI_MASK0(val) bfin_write32(RSI_MASK0, val)
+#define bfin_read_RSI_MASK1() bfin_read32(RSI_MASK1)
+#define bfin_write_RSI_MASK1(val) bfin_write32(RSI_MASK1, val)
+#define bfin_read_RSI_FIFO_CNT() bfin_read16(RSI_FIFO_CNT)
+#define bfin_write_RSI_FIFO_CNT(val) bfin_write16(RSI_FIFO_CNT, val)
+#define bfin_read_RSI_CEATA_CTL() bfin_read16(RSI_CEATA_CONTROL)
+#define bfin_write_RSI_CEATA_CTL(val) bfin_write16(RSI_CEATA_CONTROL, val)
+#define bfin_read_RSI_FIFO() bfin_read32(RSI_FIFO)
+#define bfin_write_RSI_FIFO(val) bfin_write32(RSI_FIFO, val)
+#define bfin_read_RSI_E_STATUS() bfin_read16(RSI_ESTAT)
+#define bfin_write_RSI_E_STATUS(val) bfin_write16(RSI_ESTAT, val)
+#define bfin_read_RSI_E_MASK() bfin_read16(RSI_EMASK)
+#define bfin_write_RSI_E_MASK(val) bfin_write16(RSI_EMASK, val)
+#define bfin_read_RSI_CFG() bfin_read16(RSI_CONFIG)
+#define bfin_write_RSI_CFG(val) bfin_write16(RSI_CONFIG, val)
+#define bfin_read_RSI_RD_WAIT_EN() bfin_read16(RSI_RD_WAIT_EN)
+#define bfin_write_RSI_RD_WAIT_EN(val) bfin_write16(RSI_RD_WAIT_EN, val)
+#define bfin_read_RSI_PID0() bfin_read16(RSI_PID0)
+#define bfin_write_RSI_PID0(val) bfin_write16(RSI_PID0, val)
+#define bfin_read_RSI_PID1() bfin_read16(RSI_PID1)
+#define bfin_write_RSI_PID1(val) bfin_write16(RSI_PID1, val)
+#define bfin_read_RSI_PID2() bfin_read16(RSI_PID2)
+#define bfin_write_RSI_PID2(val) bfin_write16(RSI_PID2, val)
+#define bfin_read_RSI_PID3() bfin_read16(RSI_PID3)
+#define bfin_write_RSI_PID3(val) bfin_write16(RSI_PID3, val)
+#define bfin_read_RSI_PID4() bfin_read16(RSI_PID4)
+#define bfin_write_RSI_PID4(val) bfin_write16(RSI_PID4, val)
+#define bfin_read_RSI_PID5() bfin_read16(RSI_PID5)
+#define bfin_write_RSI_PID5(val) bfin_write16(RSI_PID5, val)
+#define bfin_read_RSI_PID6() bfin_read16(RSI_PID6)
+#define bfin_write_RSI_PID6(val) bfin_write16(RSI_PID6, val)
+#define bfin_read_RSI_PID7() bfin_read16(RSI_PID7)
+#define bfin_write_RSI_PID7(val) bfin_write16(RSI_PID7, val)
+
#endif /* _CDEF_BF516_H */
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF514.h b/arch/blackfin/mach-bf518/include/mach/defBF514.h
index 543f2913b3f5..56ee5a7c2007 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF514.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF514.h
@@ -110,4 +110,139 @@
#define RSI_PID6 0xFFC03FF8 /* RSI Peripheral ID Register 6 */
#define RSI_PID7 0xFFC03FFC /* RSI Peripheral ID Register 7 */
+/* ********************************************************** */
+/* SINGLE BIT MACRO PAIRS (bit mask and negated one) */
+/* and MULTI BIT READ MACROS */
+/* ********************************************************** */
+
+/* Bit masks for SDH_COMMAND */
+
+#define CMD_IDX 0x3f /* Command Index */
+#define CMD_RSP 0x40 /* Response */
+#define CMD_L_RSP 0x80 /* Long Response */
+#define CMD_INT_E 0x100 /* Command Interrupt */
+#define CMD_PEND_E 0x200 /* Command Pending */
+#define CMD_E 0x400 /* Command Enable */
+
+/* Bit masks for SDH_PWR_CTL */
+
+#define PWR_ON 0x3 /* Power On */
+#if 0
+#define TBD 0x3c /* TBD */
+#endif
+#define SD_CMD_OD 0x40 /* Open Drain Output */
+#define ROD_CTL 0x80 /* Rod Control */
+
+/* Bit masks for SDH_CLK_CTL */
+
+#define CLKDIV 0xff /* MC_CLK Divisor */
+#define CLK_E 0x100 /* MC_CLK Bus Clock Enable */
+#define PWR_SV_E 0x200 /* Power Save Enable */
+#define CLKDIV_BYPASS 0x400 /* Bypass Divisor */
+#define WIDE_BUS 0x800 /* Wide Bus Mode Enable */
+
+/* Bit masks for SDH_RESP_CMD */
+
+#define RESP_CMD 0x3f /* Response Command */
+
+/* Bit masks for SDH_DATA_CTL */
+
+#define DTX_E 0x1 /* Data Transfer Enable */
+#define DTX_DIR 0x2 /* Data Transfer Direction */
+#define DTX_MODE 0x4 /* Data Transfer Mode */
+#define DTX_DMA_E 0x8 /* Data Transfer DMA Enable */
+#define DTX_BLK_LGTH 0xf0 /* Data Transfer Block Length */
+
+/* Bit masks for SDH_STATUS */
+
+#define CMD_CRC_FAIL 0x1 /* CMD CRC Fail */
+#define DAT_CRC_FAIL 0x2 /* Data CRC Fail */
+#define CMD_TIME_OUT 0x4 /* CMD Time Out */
+#define DAT_TIME_OUT 0x8 /* Data Time Out */
+#define TX_UNDERRUN 0x10 /* Transmit Underrun */
+#define RX_OVERRUN 0x20 /* Receive Overrun */
+#define CMD_RESP_END 0x40 /* CMD Response End */
+#define CMD_SENT 0x80 /* CMD Sent */
+#define DAT_END 0x100 /* Data End */
+#define START_BIT_ERR 0x200 /* Start Bit Error */
+#define DAT_BLK_END 0x400 /* Data Block End */
+#define CMD_ACT 0x800 /* CMD Active */
+#define TX_ACT 0x1000 /* Transmit Active */
+#define RX_ACT 0x2000 /* Receive Active */
+#define TX_FIFO_STAT 0x4000 /* Transmit FIFO Status */
+#define RX_FIFO_STAT 0x8000 /* Receive FIFO Status */
+#define TX_FIFO_FULL 0x10000 /* Transmit FIFO Full */
+#define RX_FIFO_FULL 0x20000 /* Receive FIFO Full */
+#define TX_FIFO_ZERO 0x40000 /* Transmit FIFO Empty */
+#define RX_DAT_ZERO 0x80000 /* Receive FIFO Empty */
+#define TX_DAT_RDY 0x100000 /* Transmit Data Available */
+#define RX_FIFO_RDY 0x200000 /* Receive Data Available */
+
+/* Bit masks for SDH_STATUS_CLR */
+
+#define CMD_CRC_FAIL_STAT 0x1 /* CMD CRC Fail Status */
+#define DAT_CRC_FAIL_STAT 0x2 /* Data CRC Fail Status */
+#define CMD_TIMEOUT_STAT 0x4 /* CMD Time Out Status */
+#define DAT_TIMEOUT_STAT 0x8 /* Data Time Out status */
+#define TX_UNDERRUN_STAT 0x10 /* Transmit Underrun Status */
+#define RX_OVERRUN_STAT 0x20 /* Receive Overrun Status */
+#define CMD_RESP_END_STAT 0x40 /* CMD Response End Status */
+#define CMD_SENT_STAT 0x80 /* CMD Sent Status */
+#define DAT_END_STAT 0x100 /* Data End Status */
+#define START_BIT_ERR_STAT 0x200 /* Start Bit Error Status */
+#define DAT_BLK_END_STAT 0x400 /* Data Block End Status */
+
+/* Bit masks for SDH_MASK0 */
+
+#define CMD_CRC_FAIL_MASK 0x1 /* CMD CRC Fail Mask */
+#define DAT_CRC_FAIL_MASK 0x2 /* Data CRC Fail Mask */
+#define CMD_TIMEOUT_MASK 0x4 /* CMD Time Out Mask */
+#define DAT_TIMEOUT_MASK 0x8 /* Data Time Out Mask */
+#define TX_UNDERRUN_MASK 0x10 /* Transmit Underrun Mask */
+#define RX_OVERRUN_MASK 0x20 /* Receive Overrun Mask */
+#define CMD_RESP_END_MASK 0x40 /* CMD Response End Mask */
+#define CMD_SENT_MASK 0x80 /* CMD Sent Mask */
+#define DAT_END_MASK 0x100 /* Data End Mask */
+#define START_BIT_ERR_MASK 0x200 /* Start Bit Error Mask */
+#define DAT_BLK_END_MASK 0x400 /* Data Block End Mask */
+#define CMD_ACT_MASK 0x800 /* CMD Active Mask */
+#define TX_ACT_MASK 0x1000 /* Transmit Active Mask */
+#define RX_ACT_MASK 0x2000 /* Receive Active Mask */
+#define TX_FIFO_STAT_MASK 0x4000 /* Transmit FIFO Status Mask */
+#define RX_FIFO_STAT_MASK 0x8000 /* Receive FIFO Status Mask */
+#define TX_FIFO_FULL_MASK 0x10000 /* Transmit FIFO Full Mask */
+#define RX_FIFO_FULL_MASK 0x20000 /* Receive FIFO Full Mask */
+#define TX_FIFO_ZERO_MASK 0x40000 /* Transmit FIFO Empty Mask */
+#define RX_DAT_ZERO_MASK 0x80000 /* Receive FIFO Empty Mask */
+#define TX_DAT_RDY_MASK 0x100000 /* Transmit Data Available Mask */
+#define RX_FIFO_RDY_MASK 0x200000 /* Receive Data Available Mask */
+
+/* Bit masks for SDH_FIFO_CNT */
+
+#define FIFO_COUNT 0x7fff /* FIFO Count */
+
+/* Bit masks for SDH_E_STATUS */
+
+#define SDIO_INT_DET 0x2 /* SDIO Int Detected */
+#define SD_CARD_DET 0x10 /* SD Card Detect */
+
+/* Bit masks for SDH_E_MASK */
+
+#define SDIO_MSK 0x2 /* Mask SDIO Int Detected */
+#define SCD_MSK 0x40 /* Mask Card Detect */
+
+/* Bit masks for SDH_CFG */
+
+#define CLKS_EN 0x1 /* Clocks Enable */
+#define SD4E 0x4 /* SDIO 4-Bit Enable */
+#define MWE 0x8 /* Moving Window Enable */
+#define SD_RST 0x10 /* SDMMC Reset */
+#define PUP_SDDAT 0x20 /* Pull-up SD_DAT */
+#define PUP_SDDAT3 0x40 /* Pull-up SD_DAT3 */
+#define PD_SDDAT3 0x80 /* Pull-down SD_DAT3 */
+
+/* Bit masks for SDH_RD_WAIT_EN */
+
+#define RWR 0x1 /* Read Wait Request */
+
#endif /* _DEF_BF514_H */
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF516.h b/arch/blackfin/mach-bf518/include/mach/defBF516.h
index 149a269306c5..dfc93843517d 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF516.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF516.h
@@ -487,4 +487,139 @@
#define RSI_PID6 0xFFC03FF8 /* RSI Peripheral ID Register 6 */
#define RSI_PID7 0xFFC03FFC /* RSI Peripheral ID Register 7 */
+/* ********************************************************** */
+/* SINGLE BIT MACRO PAIRS (bit mask and negated one) */
+/* and MULTI BIT READ MACROS */
+/* ********************************************************** */
+
+/* Bit masks for SDH_COMMAND */
+
+#define CMD_IDX 0x3f /* Command Index */
+#define CMD_RSP 0x40 /* Response */
+#define CMD_L_RSP 0x80 /* Long Response */
+#define CMD_INT_E 0x100 /* Command Interrupt */
+#define CMD_PEND_E 0x200 /* Command Pending */
+#define CMD_E 0x400 /* Command Enable */
+
+/* Bit masks for SDH_PWR_CTL */
+
+#define PWR_ON 0x3 /* Power On */
+#if 0
+#define TBD 0x3c /* TBD */
+#endif
+#define SD_CMD_OD 0x40 /* Open Drain Output */
+#define ROD_CTL 0x80 /* Rod Control */
+
+/* Bit masks for SDH_CLK_CTL */
+
+#define CLKDIV 0xff /* MC_CLK Divisor */
+#define CLK_E 0x100 /* MC_CLK Bus Clock Enable */
+#define PWR_SV_E 0x200 /* Power Save Enable */
+#define CLKDIV_BYPASS 0x400 /* Bypass Divisor */
+#define WIDE_BUS 0x800 /* Wide Bus Mode Enable */
+
+/* Bit masks for SDH_RESP_CMD */
+
+#define RESP_CMD 0x3f /* Response Command */
+
+/* Bit masks for SDH_DATA_CTL */
+
+#define DTX_E 0x1 /* Data Transfer Enable */
+#define DTX_DIR 0x2 /* Data Transfer Direction */
+#define DTX_MODE 0x4 /* Data Transfer Mode */
+#define DTX_DMA_E 0x8 /* Data Transfer DMA Enable */
+#define DTX_BLK_LGTH 0xf0 /* Data Transfer Block Length */
+
+/* Bit masks for SDH_STATUS */
+
+#define CMD_CRC_FAIL 0x1 /* CMD CRC Fail */
+#define DAT_CRC_FAIL 0x2 /* Data CRC Fail */
+#define CMD_TIME_OUT 0x4 /* CMD Time Out */
+#define DAT_TIME_OUT 0x8 /* Data Time Out */
+#define TX_UNDERRUN 0x10 /* Transmit Underrun */
+#define RX_OVERRUN 0x20 /* Receive Overrun */
+#define CMD_RESP_END 0x40 /* CMD Response End */
+#define CMD_SENT 0x80 /* CMD Sent */
+#define DAT_END 0x100 /* Data End */
+#define START_BIT_ERR 0x200 /* Start Bit Error */
+#define DAT_BLK_END 0x400 /* Data Block End */
+#define CMD_ACT 0x800 /* CMD Active */
+#define TX_ACT 0x1000 /* Transmit Active */
+#define RX_ACT 0x2000 /* Receive Active */
+#define TX_FIFO_STAT 0x4000 /* Transmit FIFO Status */
+#define RX_FIFO_STAT 0x8000 /* Receive FIFO Status */
+#define TX_FIFO_FULL 0x10000 /* Transmit FIFO Full */
+#define RX_FIFO_FULL 0x20000 /* Receive FIFO Full */
+#define TX_FIFO_ZERO 0x40000 /* Transmit FIFO Empty */
+#define RX_DAT_ZERO 0x80000 /* Receive FIFO Empty */
+#define TX_DAT_RDY 0x100000 /* Transmit Data Available */
+#define RX_FIFO_RDY 0x200000 /* Receive Data Available */
+
+/* Bit masks for SDH_STATUS_CLR */
+
+#define CMD_CRC_FAIL_STAT 0x1 /* CMD CRC Fail Status */
+#define DAT_CRC_FAIL_STAT 0x2 /* Data CRC Fail Status */
+#define CMD_TIMEOUT_STAT 0x4 /* CMD Time Out Status */
+#define DAT_TIMEOUT_STAT 0x8 /* Data Time Out status */
+#define TX_UNDERRUN_STAT 0x10 /* Transmit Underrun Status */
+#define RX_OVERRUN_STAT 0x20 /* Receive Overrun Status */
+#define CMD_RESP_END_STAT 0x40 /* CMD Response End Status */
+#define CMD_SENT_STAT 0x80 /* CMD Sent Status */
+#define DAT_END_STAT 0x100 /* Data End Status */
+#define START_BIT_ERR_STAT 0x200 /* Start Bit Error Status */
+#define DAT_BLK_END_STAT 0x400 /* Data Block End Status */
+
+/* Bit masks for SDH_MASK0 */
+
+#define CMD_CRC_FAIL_MASK 0x1 /* CMD CRC Fail Mask */
+#define DAT_CRC_FAIL_MASK 0x2 /* Data CRC Fail Mask */
+#define CMD_TIMEOUT_MASK 0x4 /* CMD Time Out Mask */
+#define DAT_TIMEOUT_MASK 0x8 /* Data Time Out Mask */
+#define TX_UNDERRUN_MASK 0x10 /* Transmit Underrun Mask */
+#define RX_OVERRUN_MASK 0x20 /* Receive Overrun Mask */
+#define CMD_RESP_END_MASK 0x40 /* CMD Response End Mask */
+#define CMD_SENT_MASK 0x80 /* CMD Sent Mask */
+#define DAT_END_MASK 0x100 /* Data End Mask */
+#define START_BIT_ERR_MASK 0x200 /* Start Bit Error Mask */
+#define DAT_BLK_END_MASK 0x400 /* Data Block End Mask */
+#define CMD_ACT_MASK 0x800 /* CMD Active Mask */
+#define TX_ACT_MASK 0x1000 /* Transmit Active Mask */
+#define RX_ACT_MASK 0x2000 /* Receive Active Mask */
+#define TX_FIFO_STAT_MASK 0x4000 /* Transmit FIFO Status Mask */
+#define RX_FIFO_STAT_MASK 0x8000 /* Receive FIFO Status Mask */
+#define TX_FIFO_FULL_MASK 0x10000 /* Transmit FIFO Full Mask */
+#define RX_FIFO_FULL_MASK 0x20000 /* Receive FIFO Full Mask */
+#define TX_FIFO_ZERO_MASK 0x40000 /* Transmit FIFO Empty Mask */
+#define RX_DAT_ZERO_MASK 0x80000 /* Receive FIFO Empty Mask */
+#define TX_DAT_RDY_MASK 0x100000 /* Transmit Data Available Mask */
+#define RX_FIFO_RDY_MASK 0x200000 /* Receive Data Available Mask */
+
+/* Bit masks for SDH_FIFO_CNT */
+
+#define FIFO_COUNT 0x7fff /* FIFO Count */
+
+/* Bit masks for SDH_E_STATUS */
+
+#define SDIO_INT_DET 0x2 /* SDIO Int Detected */
+#define SD_CARD_DET 0x10 /* SD Card Detect */
+
+/* Bit masks for SDH_E_MASK */
+
+#define SDIO_MSK 0x2 /* Mask SDIO Int Detected */
+#define SCD_MSK 0x40 /* Mask Card Detect */
+
+/* Bit masks for SDH_CFG */
+
+#define CLKS_EN 0x1 /* Clocks Enable */
+#define SD4E 0x4 /* SDIO 4-Bit Enable */
+#define MWE 0x8 /* Moving Window Enable */
+#define SD_RST 0x10 /* SDMMC Reset */
+#define PUP_SDDAT 0x20 /* Pull-up SD_DAT */
+#define PUP_SDDAT3 0x40 /* Pull-up SD_DAT3 */
+#define PD_SDDAT3 0x80 /* Pull-down SD_DAT3 */
+
+/* Bit masks for SDH_RD_WAIT_EN */
+
+#define RWR 0x1 /* Read Wait Request */
+
#endif /* _DEF_BF516_H */
diff --git a/arch/blackfin/mach-bf527/include/mach/blackfin.h b/arch/blackfin/mach-bf527/include/mach/blackfin.h
index 297821e2d79a..417abcd61f4d 100644
--- a/arch/blackfin/mach-bf527/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf527/include/mach/blackfin.h
@@ -32,8 +32,6 @@
#ifndef _MACH_BLACKFIN_H_
#define _MACH_BLACKFIN_H_
-#define BF527_FAMILY
-
#include "bf527.h"
#include "mem_map.h"
#include "defBF522.h"
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index cd04c5e44878..0572926da23f 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -843,6 +843,71 @@ static struct platform_device bfin_spi0_device = {
};
#endif /* spi master and devices */
+#if defined(CONFIG_SPI_BFIN_SPORT) || defined(CONFIG_SPI_BFIN_SPORT_MODULE)
+
+/* SPORT SPI controller data */
+static struct bfin5xx_spi_master bfin_sport_spi0_info = {
+ .num_chipselect = 1, /* master only supports one device */
+ .enable_dma = 0, /* master don't support DMA */
+ .pin_req = {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_DRPRI,
+ P_SPORT0_RSCLK, P_SPORT0_TFS, P_SPORT0_RFS, 0},
+};
+
+static struct resource bfin_sport_spi0_resource[] = {
+ [0] = {
+ .start = SPORT0_TCR1,
+ .end = SPORT0_TCR1 + 0xFF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SPORT0_ERROR,
+ .end = IRQ_SPORT0_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_sport_spi0_device = {
+ .name = "bfin-sport-spi",
+ .id = 1, /* Bus number */
+ .num_resources = ARRAY_SIZE(bfin_sport_spi0_resource),
+ .resource = bfin_sport_spi0_resource,
+ .dev = {
+ .platform_data = &bfin_sport_spi0_info, /* Passed to driver */
+ },
+};
+
+static struct bfin5xx_spi_master bfin_sport_spi1_info = {
+ .num_chipselect = 1, /* master only supports one device */
+ .enable_dma = 0, /* master don't support DMA */
+ .pin_req = {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_DRPRI,
+ P_SPORT1_RSCLK, P_SPORT1_TFS, P_SPORT1_RFS, 0},
+};
+
+static struct resource bfin_sport_spi1_resource[] = {
+ [0] = {
+ .start = SPORT1_TCR1,
+ .end = SPORT1_TCR1 + 0xFF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SPORT1_ERROR,
+ .end = IRQ_SPORT1_ERROR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_sport_spi1_device = {
+ .name = "bfin-sport-spi",
+ .id = 2, /* Bus number */
+ .num_resources = ARRAY_SIZE(bfin_sport_spi1_resource),
+ .resource = bfin_sport_spi1_resource,
+ .dev = {
+ .platform_data = &bfin_sport_spi1_info, /* Passed to driver */
+ },
+};
+
+#endif /* sport spi master and devices */
+
#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
static struct platform_device bfin_fb_device = {
.name = "bf537-lq035",
@@ -1073,6 +1138,141 @@ static struct adp5588_kpad_platform_data adp5588_kpad_data = {
};
#endif
+#if defined(CONFIG_PMIC_ADP5520) || defined(CONFIG_PMIC_ADP5520_MODULE)
+#include <linux/mfd/adp5520.h>
+
+ /*
+ * ADP5520/5501 Backlight Data
+ */
+
+static struct adp5520_backlight_platfrom_data adp5520_backlight_data = {
+ .fade_in = FADE_T_1200ms,
+ .fade_out = FADE_T_1200ms,
+ .fade_led_law = BL_LAW_LINEAR,
+ .en_ambl_sens = 1,
+ .abml_filt = BL_AMBL_FILT_640ms,
+ .l1_daylight_max = BL_CUR_mA(15),
+ .l1_daylight_dim = BL_CUR_mA(0),
+ .l2_office_max = BL_CUR_mA(7),
+ .l2_office_dim = BL_CUR_mA(0),
+ .l3_dark_max = BL_CUR_mA(3),
+ .l3_dark_dim = BL_CUR_mA(0),
+ .l2_trip = L2_COMP_CURR_uA(700),
+ .l2_hyst = L2_COMP_CURR_uA(50),
+ .l3_trip = L3_COMP_CURR_uA(80),
+ .l3_hyst = L3_COMP_CURR_uA(20),
+};
+
+ /*
+ * ADP5520/5501 LEDs Data
+ */
+
+#include <linux/leds.h>
+
+static struct led_info adp5520_leds[] = {
+ {
+ .name = "adp5520-led1",
+ .default_trigger = "none",
+ .flags = FLAG_ID_ADP5520_LED1_ADP5501_LED0 | LED_OFFT_600ms,
+ },
+#ifdef ADP5520_EN_ALL_LEDS
+ {
+ .name = "adp5520-led2",
+ .default_trigger = "none",
+ .flags = FLAG_ID_ADP5520_LED2_ADP5501_LED1,
+ },
+ {
+ .name = "adp5520-led3",
+ .default_trigger = "none",
+ .flags = FLAG_ID_ADP5520_LED3_ADP5501_LED2,
+ },
+#endif
+};
+
+static struct adp5520_leds_platfrom_data adp5520_leds_data = {
+ .num_leds = ARRAY_SIZE(adp5520_leds),
+ .leds = adp5520_leds,
+ .fade_in = FADE_T_600ms,
+ .fade_out = FADE_T_600ms,
+ .led_on_time = LED_ONT_600ms,
+};
+
+ /*
+ * ADP5520 GPIO Data
+ */
+
+static struct adp5520_gpio_platfrom_data adp5520_gpio_data = {
+ .gpio_start = 50,
+ .gpio_en_mask = GPIO_C1 | GPIO_C2 | GPIO_R2,
+ .gpio_pullup_mask = GPIO_C1 | GPIO_C2 | GPIO_R2,
+};
+
+ /*
+ * ADP5520 Keypad Data
+ */
+
+#include <linux/input.h>
+static const unsigned short adp5520_keymap[ADP5520_KEYMAPSIZE] = {
+ [KEY(0, 0)] = KEY_GRAVE,
+ [KEY(0, 1)] = KEY_1,
+ [KEY(0, 2)] = KEY_2,
+ [KEY(0, 3)] = KEY_3,
+ [KEY(1, 0)] = KEY_4,
+ [KEY(1, 1)] = KEY_5,
+ [KEY(1, 2)] = KEY_6,
+ [KEY(1, 3)] = KEY_7,
+ [KEY(2, 0)] = KEY_8,
+ [KEY(2, 1)] = KEY_9,
+ [KEY(2, 2)] = KEY_0,
+ [KEY(2, 3)] = KEY_MINUS,
+ [KEY(3, 0)] = KEY_EQUAL,
+ [KEY(3, 1)] = KEY_BACKSLASH,
+ [KEY(3, 2)] = KEY_BACKSPACE,
+ [KEY(3, 3)] = KEY_ENTER,
+};
+
+static struct adp5520_keys_platfrom_data adp5520_keys_data = {
+ .rows_en_mask = ROW_R3 | ROW_R2 | ROW_R1 | ROW_R0,
+ .cols_en_mask = COL_C3 | COL_C2 | COL_C1 | COL_C0,
+ .keymap = adp5520_keymap,
+ .keymapsize = ARRAY_SIZE(adp5520_keymap),
+ .repeat = 0,
+};
+
+ /*
+ * ADP5520/5501 Multifuction Device Init Data
+ */
+
+static struct adp5520_subdev_info adp5520_subdevs[] = {
+ {
+ .name = "adp5520-backlight",
+ .id = ID_ADP5520,
+ .platform_data = &adp5520_backlight_data,
+ },
+ {
+ .name = "adp5520-led",
+ .id = ID_ADP5520,
+ .platform_data = &adp5520_leds_data,
+ },
+ {
+ .name = "adp5520-gpio",
+ .id = ID_ADP5520,
+ .platform_data = &adp5520_gpio_data,
+ },
+ {
+ .name = "adp5520-keys",
+ .id = ID_ADP5520,
+ .platform_data = &adp5520_keys_data,
+ },
+};
+
+static struct adp5520_platform_data adp5520_pdev_data = {
+ .num_subdevs = ARRAY_SIZE(adp5520_subdevs),
+ .subdevs = adp5520_subdevs,
+};
+
+#endif
+
static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
#if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE)
{
@@ -1105,6 +1305,13 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
.platform_data = (void *)&adp5588_kpad_data,
},
#endif
+#if defined(CONFIG_PMIC_ADP5520) || defined(CONFIG_PMIC_ADP5520_MODULE)
+ {
+ I2C_BOARD_INFO("pmic-adp5520", 0x32),
+ .irq = IRQ_PF7,
+ .platform_data = (void *)&adp5520_pdev_data,
+ },
+#endif
};
#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
@@ -1120,8 +1327,11 @@ static struct platform_device bfin_sport1_uart_device = {
#endif
#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
-#define PATA_INT IRQ_PF5
+#define CF_IDE_NAND_CARD_USE_HDD_INTERFACE
+/* #define CF_IDE_NAND_CARD_USE_CF_IN_COMMON_MEMORY_MODE */
+#ifdef CF_IDE_NAND_CARD_USE_HDD_INTERFACE
+#define PATA_INT IRQ_PF5
static struct pata_platform_info bfin_pata_platform_data = {
.ioport_shift = 1,
.irq_flags = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
@@ -1144,6 +1354,24 @@ static struct resource bfin_pata_resources[] = {
.flags = IORESOURCE_IRQ,
},
};
+#elif defined(CF_IDE_NAND_CARD_USE_CF_IN_COMMON_MEMORY_MODE)
+static struct pata_platform_info bfin_pata_platform_data = {
+ .ioport_shift = 0,
+};
+
+static struct resource bfin_pata_resources[] = {
+ {
+ .start = 0x20211820,
+ .end = 0x2021183F,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x2021181C,
+ .end = 0x2021181F,
+ .flags = IORESOURCE_MEM,
+ },
+};
+#endif
static struct platform_device bfin_pata_device = {
.name = "pata_platform",
@@ -1232,6 +1460,11 @@ static struct platform_device *stamp_devices[] __initdata = {
&bfin_spi0_device,
#endif
+#if defined(CONFIG_SPI_BFIN_SPORT) || defined(CONFIG_SPI_BFIN_SPORT_MODULE)
+ &bfin_sport_spi0_device,
+ &bfin_sport_spi1_device,
+#endif
+
#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
&bfin_fb_device,
#endif
diff --git a/arch/blackfin/mach-bf548/include/mach/blackfin.h b/arch/blackfin/mach-bf548/include/mach/blackfin.h
index 0c0e3e2c3c21..cf6c1500222a 100644
--- a/arch/blackfin/mach-bf548/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf548/include/mach/blackfin.h
@@ -32,8 +32,6 @@
#ifndef _MACH_BLACKFIN_H_
#define _MACH_BLACKFIN_H_
-#define BF548_FAMILY
-
#include "bf548.h"
#include "mem_map.h"
#include "anomaly.h"
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index f48a6aebb49b..bce5a84be49f 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -287,7 +287,7 @@ int bfin_pm_suspend_mem_enter(void)
static int bfin_pm_valid(suspend_state_t state)
{
return (state == PM_SUSPEND_STANDBY
-#ifndef BF533_FAMILY
+#if !(defined(BF533_FAMILY) || defined(CONFIG_BF561))
/*
* On BF533/2/1:
* If we enter Hibernate the SCKE Pin is driven Low,
diff --git a/arch/blackfin/mm/sram-alloc.c b/arch/blackfin/mm/sram-alloc.c
index 834cab7438a8..530d1393a232 100644
--- a/arch/blackfin/mm/sram-alloc.c
+++ b/arch/blackfin/mm/sram-alloc.c
@@ -854,7 +854,6 @@ static int __init sram_proc_init(void)
printk(KERN_WARNING "unable to create /proc/sram\n");
return -1;
}
- ptr->owner = THIS_MODULE;
ptr->read_proc = sram_proc_read;
return 0;
}
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 3462245fe9fb..7adac388a771 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -438,7 +438,7 @@ config ETRAX_SERIAL_PORT0_DMA1_IN
help
Enables the DMA1 input channel for ser0 (ttyS0).
If you do not enable DMA, an interrupt for each character will be
- used when receiveing data.
+ used when receiving data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
@@ -565,7 +565,7 @@ config ETRAX_SERIAL_PORT2_DMA7_IN
help
Enables the DMA7 input channel for ser2 (ttyS2).
If you do not enable DMA, an interrupt for each character will be
- used when receiveing data.
+ used when receiving data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
@@ -604,7 +604,7 @@ config ETRAX_SERIAL_PORT3_DMA3_IN
help
Enables the DMA3 input channel for ser3 (ttyS3).
If you do not enable DMA, an interrupt for each character will be
- used when receiveing data.
+ used when receiving data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c
index 65ed803dae6f..5d75f77f9c73 100644
--- a/arch/cris/arch-v10/kernel/irq.c
+++ b/arch/cris/arch-v10/kernel/irq.c
@@ -132,7 +132,7 @@ static void end_crisv10_irq(unsigned int irq)
{
}
-static struct hw_interrupt_type crisv10_irq_type = {
+static struct irq_chip crisv10_irq_type = {
.typename = "CRISv10",
.startup = startup_crisv10_irq,
.shutdown = shutdown_crisv10_irq,
diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c
index bd9b3ff63f6c..c4c69cf721e5 100644
--- a/arch/cris/arch-v10/kernel/process.c
+++ b/arch/cris/arch-v10/kernel/process.c
@@ -115,7 +115,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
*/
asmlinkage void ret_from_fork(void);
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c
index c685ba4c3387..2b73c7a5b649 100644
--- a/arch/cris/arch-v10/kernel/time.c
+++ b/arch/cris/arch-v10/kernel/time.c
@@ -261,7 +261,6 @@ timer_interrupt(int irq, void *dev_id)
static struct irqaction irq2 = {
.handler = timer_interrupt,
.flags = IRQF_SHARED | IRQF_DISABLED,
- .mask = CPU_MASK_NONE,
.name = "timer",
};
diff --git a/arch/cris/arch-v32/Kconfig b/arch/cris/arch-v32/Kconfig
index 005ed2b3f7f4..21bbd93be34f 100644
--- a/arch/cris/arch-v32/Kconfig
+++ b/arch/cris/arch-v32/Kconfig
@@ -28,7 +28,7 @@ config ETRAX_NBR_LED_GRP_ONE
help
Select this if you want one Ethernet LED group. This LED group
can be used for one or more Ethernet interfaces. However, it is
- recomended that each Ethernet interface use a dedicated LED group.
+ recommended that each Ethernet interface use a dedicated LED group.
config ETRAX_NBR_LED_GRP_TWO
bool "Use two LED groups"
diff --git a/arch/cris/arch-v32/boot/compressed/Makefile b/arch/cris/arch-v32/boot/compressed/Makefile
index 5a1b31c99eaa..e176b8b69d92 100644
--- a/arch/cris/arch-v32/boot/compressed/Makefile
+++ b/arch/cris/arch-v32/boot/compressed/Makefile
@@ -2,9 +2,9 @@
# arch/cris/arch-v32/boot/compressed/Makefile
#
-asflags-y += -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
-ccflags-y += -O2 -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
-ldflags-y += -T $(srctree)/$(src)/decompress.lds
+asflags-y += -I$(srctree)/include/asm/mach/ -I$(srctree)/include/asm/arch
+ccflags-y += -O2 -I$(srctree)/include/asm/mach/ -I$(srctree)/include/asm/arch
+ldflags-y += -T$(srctree)/$(src)/decompress.lds
OBJECTS = $(obj)/head.o $(obj)/misc.o
OBJCOPYFLAGS = -O binary --remove-section=.bss
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig
index 7a64fcef9d07..b9e328e688be 100644
--- a/arch/cris/arch-v32/drivers/Kconfig
+++ b/arch/cris/arch-v32/drivers/Kconfig
@@ -342,7 +342,7 @@ config ETRAX_SERIAL_PORT4_DMA9_IN
help
Enables the DMA9 input channel for ser4 (ttyS4).
If you do not enable DMA, an interrupt for each character will be
- used when receiveing data.
+ used when receiving data.
Normally you want to use DMA, unless you use the DMA channel for
something else.
diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c
index 295131fee710..df3925cb1c7f 100644
--- a/arch/cris/arch-v32/kernel/irq.c
+++ b/arch/cris/arch-v32/kernel/irq.c
@@ -333,7 +333,7 @@ void set_affinity_crisv32_irq(unsigned int irq, const struct cpumask *dest)
spin_unlock_irqrestore(&irq_lock, flags);
}
-static struct hw_interrupt_type crisv32_irq_type = {
+static struct irq_chip crisv32_irq_type = {
.typename = "CRISv32",
.startup = startup_crisv32_irq,
.shutdown = shutdown_crisv32_irq,
diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c
index ced5b725d9bd..120e7f796fea 100644
--- a/arch/cris/arch-v32/kernel/process.c
+++ b/arch/cris/arch-v32/kernel/process.c
@@ -131,7 +131,7 @@ kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
extern asmlinkage void ret_from_fork(void);
int
-copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 9dac17334640..d2a3ff8c4d37 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -65,7 +65,6 @@ static int send_ipi(int vector, int wait, cpumask_t cpu_mask);
static struct irqaction irq_ipi = {
.handler = crisv32_ipi_interrupt,
.flags = IRQF_DISABLED,
- .mask = CPU_MASK_NONE,
.name = "ipi",
};
@@ -98,9 +97,9 @@ void __devinit smp_prepare_boot_cpu(void)
SUPP_BANK_SEL(2);
SUPP_REG_WR(RW_MM_TLB_PGD, pgd);
- cpu_set(0, cpu_online_map);
+ set_cpu_online(0, true);
cpu_set(0, phys_cpu_present_map);
- cpu_set(0, cpu_possible_map);
+ set_cpu_possible(0, true);
}
void __init smp_cpus_done(unsigned int max_cpus)
@@ -232,7 +231,7 @@ void flush_tlb_common(struct mm_struct* mm, struct vm_area_struct* vma, unsigned
cpumask_t cpu_mask;
spin_lock_irqsave(&tlbstate_lock, flags);
- cpu_mask = (mm == FLUSH_ALL ? CPU_MASK_ALL : mm->cpu_vm_mask);
+ cpu_mask = (mm == FLUSH_ALL ? cpu_all_mask : *mm_cpumask(mm));
cpu_clear(smp_processor_id(), cpu_mask);
flush_mm = mm;
flush_vma = vma;
@@ -252,8 +251,8 @@ void flush_tlb_mm(struct mm_struct *mm)
__flush_tlb_mm(mm);
flush_tlb_common(mm, FLUSH_ALL, 0);
/* No more mappings in other CPUs */
- cpus_clear(mm->cpu_vm_mask);
- cpu_set(smp_processor_id(), mm->cpu_vm_mask);
+ cpumask_clear(mm_cpumask(mm));
+ cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
}
void flush_tlb_page(struct vm_area_struct *vma,
diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c
index 3a13dd6e0a9a..65633d0dab86 100644
--- a/arch/cris/arch-v32/kernel/time.c
+++ b/arch/cris/arch-v32/kernel/time.c
@@ -267,7 +267,6 @@ timer_interrupt(int irq, void *dev_id)
static struct irqaction irq_timer = {
.handler = timer_interrupt,
.flags = IRQF_SHARED | IRQF_DISABLED,
- .mask = CPU_MASK_NONE,
.name = "timer"
};
diff --git a/arch/cris/arch-v32/mach-fs/Kconfig b/arch/cris/arch-v32/mach-fs/Kconfig
index f6d74475f1c6..774de82abef6 100644
--- a/arch/cris/arch-v32/mach-fs/Kconfig
+++ b/arch/cris/arch-v32/mach-fs/Kconfig
@@ -59,7 +59,7 @@ config ETRAX_SDRAM_GRP1_CONFIG
depends on ETRAX_ARCH_V32
default "0"
help
- SDRAM configuration for group 1. The defult value is 0
+ SDRAM configuration for group 1. The default value is 0
because group 1 is not used in the default configuration,
described in the help for SDRAM_GRP0_CONFIG.
diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c
index 55ade36fe8a8..6779bcb28ab0 100644
--- a/arch/cris/arch-v32/mm/tlb.c
+++ b/arch/cris/arch-v32/mm/tlb.c
@@ -185,7 +185,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
/* Make sure there is a MMU context. */
spin_lock(&mmu_context_lock);
get_mmu_context(next);
- cpu_set(cpu, next->cpu_vm_mask);
+ cpumask_set_cpu(cpu, mm_cpumask(next));
spin_unlock(&mmu_context_lock);
/*
diff --git a/arch/cris/include/arch-v32/arch/spinlock.h b/arch/cris/include/arch-v32/arch/spinlock.h
index 0d5709b983a1..129756b96661 100644
--- a/arch/cris/include/arch-v32/arch/spinlock.h
+++ b/arch/cris/include/arch-v32/arch/spinlock.h
@@ -121,6 +121,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
return 1;
}
+#define _raw_read_lock_flags(lock, flags) _raw_read_lock(lock)
+#define _raw_write_lock_flags(lock, flags) _raw_write_lock(lock)
#define _raw_spin_relax(lock) cpu_relax()
#define _raw_read_relax(lock) cpu_relax()
diff --git a/arch/cris/include/asm/socket.h b/arch/cris/include/asm/socket.h
index 9df0ca82f5de..d5cf74005408 100644
--- a/arch/cris/include/asm/socket.h
+++ b/arch/cris/include/asm/socket.h
@@ -56,6 +56,9 @@
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
#endif /* _ASM_SOCKET_H */
diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
index 2dfac8c79090..7f642fcffbfc 100644
--- a/arch/cris/kernel/irq.c
+++ b/arch/cris/kernel/irq.c
@@ -66,7 +66,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%10u ", kstat_irqs(i));
#else
for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#endif
seq_printf(p, " %14s", irq_desc[i].chip->typename);
seq_printf(p, " %s", action->name);
diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c
index 60816e876455..4df0b320d524 100644
--- a/arch/cris/kernel/process.c
+++ b/arch/cris/kernel/process.c
@@ -19,7 +19,6 @@
#include <asm/system.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <linux/fs_struct.h>
#include <linux/init_task.h>
#include <linux/sched.h>
#include <linux/fs.h>
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c
index 04d48dd91ddf..b712f4934c4b 100644
--- a/arch/cris/kernel/setup.c
+++ b/arch/cris/kernel/setup.c
@@ -166,7 +166,7 @@ void __init setup_arch(char **cmdline_p)
static void *c_start(struct seq_file *m, loff_t *pos)
{
- return *pos < NR_CPUS ? (void *)(int)(*pos + 1): NULL;
+ return *pos < nr_cpu_ids ? (void *)(int)(*pos + 1) : NULL;
}
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c
index 2fdd212eb250..514f46a4b230 100644
--- a/arch/cris/mm/init.c
+++ b/arch/cris/mm/init.c
@@ -25,8 +25,7 @@ mem_init(void)
int codesize, reservedpages, datasize, initsize;
unsigned long tmp;
- if(!mem_map)
- BUG();
+ BUG_ON(!mem_map);
/* max/min_low_pfn was set by setup.c
* now we just copy it to some other necessary places...
diff --git a/arch/frv/kernel/irq-mb93091.c b/arch/frv/kernel/irq-mb93091.c
index 9e38f99bbab8..4dd9adaf115a 100644
--- a/arch/frv/kernel/irq-mb93091.c
+++ b/arch/frv/kernel/irq-mb93091.c
@@ -109,28 +109,24 @@ static struct irqaction fpga_irq[4] = {
[0] = {
.handler = fpga_interrupt,
.flags = IRQF_DISABLED | IRQF_SHARED,
- .mask = CPU_MASK_NONE,
.name = "fpga.0",
.dev_id = (void *) 0x0028UL,
},
[1] = {
.handler = fpga_interrupt,
.flags = IRQF_DISABLED | IRQF_SHARED,
- .mask = CPU_MASK_NONE,
.name = "fpga.1",
.dev_id = (void *) 0x0050UL,
},
[2] = {
.handler = fpga_interrupt,
.flags = IRQF_DISABLED | IRQF_SHARED,
- .mask = CPU_MASK_NONE,
.name = "fpga.2",
.dev_id = (void *) 0x1c00UL,
},
[3] = {
.handler = fpga_interrupt,
.flags = IRQF_DISABLED | IRQF_SHARED,
- .mask = CPU_MASK_NONE,
.name = "fpga.3",
.dev_id = (void *) 0x6386UL,
}
diff --git a/arch/frv/kernel/irq-mb93093.c b/arch/frv/kernel/irq-mb93093.c
index 3c2752ca9775..e45209031873 100644
--- a/arch/frv/kernel/irq-mb93093.c
+++ b/arch/frv/kernel/irq-mb93093.c
@@ -108,7 +108,6 @@ static struct irqaction fpga_irq[1] = {
[0] = {
.handler = fpga_interrupt,
.flags = IRQF_DISABLED,
- .mask = CPU_MASK_NONE,
.name = "fpga.0",
.dev_id = (void *) 0x0700UL,
}
diff --git a/arch/frv/kernel/irq-mb93493.c b/arch/frv/kernel/irq-mb93493.c
index 7754c7338e4b..ba55ecdfb245 100644
--- a/arch/frv/kernel/irq-mb93493.c
+++ b/arch/frv/kernel/irq-mb93493.c
@@ -120,14 +120,12 @@ static struct irqaction mb93493_irq[2] = {
[0] = {
.handler = mb93493_interrupt,
.flags = IRQF_DISABLED | IRQF_SHARED,
- .mask = CPU_MASK_NONE,
.name = "mb93493.0",
.dev_id = (void *) __addr_MB93493_IQSR(0),
},
[1] = {
.handler = mb93493_interrupt,
.flags = IRQF_DISABLED | IRQF_SHARED,
- .mask = CPU_MASK_NONE,
.name = "mb93493.1",
.dev_id = (void *) __addr_MB93493_IQSR(1),
}
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 73abae767fdc..af3e824b91b3 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -74,7 +74,7 @@ int show_interrupts(struct seq_file *p, void *v)
if (action) {
seq_printf(p, "%3d: ", i);
for_each_present_cpu(cpu)
- seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
seq_printf(p, " %s", action->name);
for (action = action->next;
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index 9583a338e9d6..0de50df74970 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -204,7 +204,7 @@ void prepare_to_copy(struct task_struct *tsk)
/*
* set up the kernel stack and exception frames for a new process
*/
-int copy_thread(int nr, unsigned long clone_flags,
+int copy_thread(unsigned long clone_flags,
unsigned long usp, unsigned long topstk,
struct task_struct *p, struct pt_regs *regs)
{
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index 69f6a4ef5d61..fb0ce7577225 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -45,7 +45,6 @@ static irqreturn_t timer_interrupt(int irq, void *dummy);
static struct irqaction timer_irq = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED,
- .mask = CPU_MASK_NONE,
.name = "timer",
};
diff --git a/arch/frv/mm/tlb-miss.S b/arch/frv/mm/tlb-miss.S
index 07643482cad2..7f392bc651a3 100644
--- a/arch/frv/mm/tlb-miss.S
+++ b/arch/frv/mm/tlb-miss.S
@@ -13,7 +13,6 @@
#include <linux/linkage.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/highmem.h>
#include <asm/spr-regs.h>
.section .text.tlbmiss
diff --git a/arch/h8300/include/asm/socket.h b/arch/h8300/include/asm/socket.h
index da2520dbf254..602518a70a1a 100644
--- a/arch/h8300/include/asm/socket.h
+++ b/arch/h8300/include/asm/socket.h
@@ -54,4 +54,7 @@
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
#endif /* _ASM_SOCKET_H */
diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c
index ef4f0047067d..74f8dd7b34d2 100644
--- a/arch/h8300/kernel/irq.c
+++ b/arch/h8300/kernel/irq.c
@@ -183,7 +183,7 @@ asmlinkage void do_IRQ(int irq)
#if defined(CONFIG_PROC_FS)
int show_interrupts(struct seq_file *p, void *v)
{
- int i = *(loff_t *) v, j;
+ int i = *(loff_t *) v;
struct irqaction * action;
unsigned long flags;
@@ -196,7 +196,7 @@ int show_interrupts(struct seq_file *p, void *v)
if (!action)
goto unlock;
seq_printf(p, "%3d: ",i);
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs(i));
seq_printf(p, " %14s", irq_desc[i].chip->name);
seq_printf(p, "-%-8s", irq_desc[i].name);
seq_printf(p, " %s", action->name);
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
index a8ef654a5a0b..e2f33d0f9969 100644
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -191,7 +191,7 @@ asmlinkage int h8300_clone(struct pt_regs *regs)
}
-int copy_thread(int nr, unsigned long clone_flags,
+int copy_thread(unsigned long clone_flags,
unsigned long usp, unsigned long topstk,
struct task_struct * p, struct pt_regs * regs)
{
diff --git a/arch/h8300/kernel/timer/itu.c b/arch/h8300/kernel/timer/itu.c
index d1c926596b08..4883ba7103a8 100644
--- a/arch/h8300/kernel/timer/itu.c
+++ b/arch/h8300/kernel/timer/itu.c
@@ -60,7 +60,6 @@ static struct irqaction itu_irq = {
.name = "itu",
.handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER,
- .mask = CPU_MASK_NONE,
};
static const int __initdata divide_rate[] = {1, 2, 4, 8};
diff --git a/arch/h8300/kernel/timer/timer16.c b/arch/h8300/kernel/timer/timer16.c
index e14271b72119..042dbb53f3fb 100644
--- a/arch/h8300/kernel/timer/timer16.c
+++ b/arch/h8300/kernel/timer/timer16.c
@@ -55,7 +55,6 @@ static struct irqaction timer16_irq = {
.name = "timer-16",
.handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER,
- .mask = CPU_MASK_NONE,
};
static const int __initdata divide_rate[] = {1, 2, 4, 8};
diff --git a/arch/h8300/kernel/timer/timer8.c b/arch/h8300/kernel/timer/timer8.c
index 0556d7c7bea6..38be0cabef0d 100644
--- a/arch/h8300/kernel/timer/timer8.c
+++ b/arch/h8300/kernel/timer/timer8.c
@@ -75,7 +75,6 @@ static struct irqaction timer8_irq = {
.name = "timer-8",
.handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER,
- .mask = CPU_MASK_NONE,
};
static const int __initdata divide_rate[] = {8, 64, 8192};
diff --git a/arch/h8300/kernel/timer/tpu.c b/arch/h8300/kernel/timer/tpu.c
index df7f453a9673..e7c6e614a758 100644
--- a/arch/h8300/kernel/timer/tpu.c
+++ b/arch/h8300/kernel/timer/tpu.c
@@ -65,10 +65,9 @@ static struct irqaction tpu_irq = {
.name = "tpu",
.handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER,
- .mask = CPU_MASK_NONE,
};
-const static int __initdata divide_rate[] = {
+static const int __initdata divide_rate[] = {
#if CONFIG_H8300_TPU_CH == 0
1,4,16,64,0,0,0,0,
#elif (CONFIG_H8300_TPU_CH == 1) || (CONFIG_H8300_TPU_CH == 5)
diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig
index a109db30ce55..75645495c2dd 100644
--- a/arch/ia64/configs/generic_defconfig
+++ b/arch/ia64/configs/generic_defconfig
@@ -193,7 +193,6 @@ CONFIG_BOUNCE=y
CONFIG_NR_QUICK=1
CONFIG_VIRT_TO_BUS=y
CONFIG_UNEVICTABLE_LRU=y
-CONFIG_MMU_NOTIFIER=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
@@ -416,8 +415,6 @@ CONFIG_SGI_IOC4=y
# CONFIG_ENCLOSURE_SERVICES is not set
CONFIG_SGI_XP=m
# CONFIG_HP_ILO is not set
-CONFIG_SGI_GRU=m
-# CONFIG_SGI_GRU_DEBUG is not set
# CONFIG_C2PORT is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
diff --git a/arch/ia64/dig/Makefile b/arch/ia64/dig/Makefile
index 5c0283830bd6..2f7caddf093e 100644
--- a/arch/ia64/dig/Makefile
+++ b/arch/ia64/dig/Makefile
@@ -7,8 +7,8 @@
obj-y := setup.o
ifeq ($(CONFIG_DMAR), y)
-obj-$(CONFIG_IA64_GENERIC) += machvec.o machvec_vtd.o dig_vtd_iommu.o
+obj-$(CONFIG_IA64_GENERIC) += machvec.o machvec_vtd.o
else
obj-$(CONFIG_IA64_GENERIC) += machvec.o
endif
-obj-$(CONFIG_IA64_DIG_VTD) += dig_vtd_iommu.o
+
diff --git a/arch/ia64/dig/dig_vtd_iommu.c b/arch/ia64/dig/dig_vtd_iommu.c
deleted file mode 100644
index 1c8a079017a3..000000000000
--- a/arch/ia64/dig/dig_vtd_iommu.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/intel-iommu.h>
-
-void *
-vtd_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- gfp_t flags)
-{
- return intel_alloc_coherent(dev, size, dma_handle, flags);
-}
-EXPORT_SYMBOL_GPL(vtd_alloc_coherent);
-
-void
-vtd_free_coherent(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_handle)
-{
- intel_free_coherent(dev, size, vaddr, dma_handle);
-}
-EXPORT_SYMBOL_GPL(vtd_free_coherent);
-
-dma_addr_t
-vtd_map_single_attrs(struct device *dev, void *addr, size_t size,
- int dir, struct dma_attrs *attrs)
-{
- return intel_map_single(dev, (phys_addr_t)addr, size, dir);
-}
-EXPORT_SYMBOL_GPL(vtd_map_single_attrs);
-
-void
-vtd_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size,
- int dir, struct dma_attrs *attrs)
-{
- intel_unmap_single(dev, iova, size, dir);
-}
-EXPORT_SYMBOL_GPL(vtd_unmap_single_attrs);
-
-int
-vtd_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents,
- int dir, struct dma_attrs *attrs)
-{
- return intel_map_sg(dev, sglist, nents, dir);
-}
-EXPORT_SYMBOL_GPL(vtd_map_sg_attrs);
-
-void
-vtd_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist,
- int nents, int dir, struct dma_attrs *attrs)
-{
- intel_unmap_sg(dev, sglist, nents, dir);
-}
-EXPORT_SYMBOL_GPL(vtd_unmap_sg_attrs);
-
-int
-vtd_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
- return 0;
-}
-EXPORT_SYMBOL_GPL(vtd_dma_mapping_error);
diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c
index 2769dbfd03bf..e4a80d82e3d8 100644
--- a/arch/ia64/hp/common/hwsw_iommu.c
+++ b/arch/ia64/hp/common/hwsw_iommu.c
@@ -13,49 +13,34 @@
*/
#include <linux/device.h>
+#include <linux/dma-mapping.h>
#include <linux/swiotlb.h>
-
#include <asm/machvec.h>
+extern struct dma_map_ops sba_dma_ops, swiotlb_dma_ops;
+
/* swiotlb declarations & definitions: */
extern int swiotlb_late_init_with_default_size (size_t size);
-/* hwiommu declarations & definitions: */
-
-extern ia64_mv_dma_alloc_coherent sba_alloc_coherent;
-extern ia64_mv_dma_free_coherent sba_free_coherent;
-extern ia64_mv_dma_map_single_attrs sba_map_single_attrs;
-extern ia64_mv_dma_unmap_single_attrs sba_unmap_single_attrs;
-extern ia64_mv_dma_map_sg_attrs sba_map_sg_attrs;
-extern ia64_mv_dma_unmap_sg_attrs sba_unmap_sg_attrs;
-extern ia64_mv_dma_supported sba_dma_supported;
-extern ia64_mv_dma_mapping_error sba_dma_mapping_error;
-
-#define hwiommu_alloc_coherent sba_alloc_coherent
-#define hwiommu_free_coherent sba_free_coherent
-#define hwiommu_map_single_attrs sba_map_single_attrs
-#define hwiommu_unmap_single_attrs sba_unmap_single_attrs
-#define hwiommu_map_sg_attrs sba_map_sg_attrs
-#define hwiommu_unmap_sg_attrs sba_unmap_sg_attrs
-#define hwiommu_dma_supported sba_dma_supported
-#define hwiommu_dma_mapping_error sba_dma_mapping_error
-#define hwiommu_sync_single_for_cpu machvec_dma_sync_single
-#define hwiommu_sync_sg_for_cpu machvec_dma_sync_sg
-#define hwiommu_sync_single_for_device machvec_dma_sync_single
-#define hwiommu_sync_sg_for_device machvec_dma_sync_sg
-
-
/*
* Note: we need to make the determination of whether or not to use
* the sw I/O TLB based purely on the device structure. Anything else
* would be unreliable or would be too intrusive.
*/
-static inline int
-use_swiotlb (struct device *dev)
+static inline int use_swiotlb(struct device *dev)
{
- return dev && dev->dma_mask && !hwiommu_dma_supported(dev, *dev->dma_mask);
+ return dev && dev->dma_mask &&
+ !sba_dma_ops.dma_supported(dev, *dev->dma_mask);
}
+struct dma_map_ops *hwsw_dma_get_ops(struct device *dev)
+{
+ if (use_swiotlb(dev))
+ return &swiotlb_dma_ops;
+ return &sba_dma_ops;
+}
+EXPORT_SYMBOL(hwsw_dma_get_ops);
+
void __init
hwsw_init (void)
{
@@ -71,125 +56,3 @@ hwsw_init (void)
#endif
}
}
-
-void *
-hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
-{
- if (use_swiotlb(dev))
- return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
- else
- return hwiommu_alloc_coherent(dev, size, dma_handle, flags);
-}
-
-void
-hwsw_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
-{
- if (use_swiotlb(dev))
- swiotlb_free_coherent(dev, size, vaddr, dma_handle);
- else
- hwiommu_free_coherent(dev, size, vaddr, dma_handle);
-}
-
-dma_addr_t
-hwsw_map_single_attrs(struct device *dev, void *addr, size_t size, int dir,
- struct dma_attrs *attrs)
-{
- if (use_swiotlb(dev))
- return swiotlb_map_single_attrs(dev, addr, size, dir, attrs);
- else
- return hwiommu_map_single_attrs(dev, addr, size, dir, attrs);
-}
-EXPORT_SYMBOL(hwsw_map_single_attrs);
-
-void
-hwsw_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size,
- int dir, struct dma_attrs *attrs)
-{
- if (use_swiotlb(dev))
- return swiotlb_unmap_single_attrs(dev, iova, size, dir, attrs);
- else
- return hwiommu_unmap_single_attrs(dev, iova, size, dir, attrs);
-}
-EXPORT_SYMBOL(hwsw_unmap_single_attrs);
-
-int
-hwsw_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents,
- int dir, struct dma_attrs *attrs)
-{
- if (use_swiotlb(dev))
- return swiotlb_map_sg_attrs(dev, sglist, nents, dir, attrs);
- else
- return hwiommu_map_sg_attrs(dev, sglist, nents, dir, attrs);
-}
-EXPORT_SYMBOL(hwsw_map_sg_attrs);
-
-void
-hwsw_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents,
- int dir, struct dma_attrs *attrs)
-{
- if (use_swiotlb(dev))
- return swiotlb_unmap_sg_attrs(dev, sglist, nents, dir, attrs);
- else
- return hwiommu_unmap_sg_attrs(dev, sglist, nents, dir, attrs);
-}
-EXPORT_SYMBOL(hwsw_unmap_sg_attrs);
-
-void
-hwsw_sync_single_for_cpu (struct device *dev, dma_addr_t addr, size_t size, int dir)
-{
- if (use_swiotlb(dev))
- swiotlb_sync_single_for_cpu(dev, addr, size, dir);
- else
- hwiommu_sync_single_for_cpu(dev, addr, size, dir);
-}
-
-void
-hwsw_sync_sg_for_cpu (struct device *dev, struct scatterlist *sg, int nelems, int dir)
-{
- if (use_swiotlb(dev))
- swiotlb_sync_sg_for_cpu(dev, sg, nelems, dir);
- else
- hwiommu_sync_sg_for_cpu(dev, sg, nelems, dir);
-}
-
-void
-hwsw_sync_single_for_device (struct device *dev, dma_addr_t addr, size_t size, int dir)
-{
- if (use_swiotlb(dev))
- swiotlb_sync_single_for_device(dev, addr, size, dir);
- else
- hwiommu_sync_single_for_device(dev, addr, size, dir);
-}
-
-void
-hwsw_sync_sg_for_device (struct device *dev, struct scatterlist *sg, int nelems, int dir)
-{
- if (use_swiotlb(dev))
- swiotlb_sync_sg_for_device(dev, sg, nelems, dir);
- else
- hwiommu_sync_sg_for_device(dev, sg, nelems, dir);
-}
-
-int
-hwsw_dma_supported (struct device *dev, u64 mask)
-{
- if (hwiommu_dma_supported(dev, mask))
- return 1;
- return swiotlb_dma_supported(dev, mask);
-}
-
-int
-hwsw_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
- return hwiommu_dma_mapping_error(dev, dma_addr) ||
- swiotlb_dma_mapping_error(dev, dma_addr);
-}
-
-EXPORT_SYMBOL(hwsw_dma_mapping_error);
-EXPORT_SYMBOL(hwsw_dma_supported);
-EXPORT_SYMBOL(hwsw_alloc_coherent);
-EXPORT_SYMBOL(hwsw_free_coherent);
-EXPORT_SYMBOL(hwsw_sync_single_for_cpu);
-EXPORT_SYMBOL(hwsw_sync_single_for_device);
-EXPORT_SYMBOL(hwsw_sync_sg_for_cpu);
-EXPORT_SYMBOL(hwsw_sync_sg_for_device);
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 6d5e6c5630e3..56ceb68eb99d 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -36,6 +36,7 @@
#include <linux/bitops.h> /* hweight64() */
#include <linux/crash_dump.h>
#include <linux/iommu-helper.h>
+#include <linux/dma-mapping.h>
#include <asm/delay.h> /* ia64_get_itc() */
#include <asm/io.h>
@@ -908,11 +909,13 @@ sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt)
*
* See Documentation/PCI/PCI-DMA-mapping.txt
*/
-dma_addr_t
-sba_map_single_attrs(struct device *dev, void *addr, size_t size, int dir,
- struct dma_attrs *attrs)
+static dma_addr_t sba_map_page(struct device *dev, struct page *page,
+ unsigned long poff, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
struct ioc *ioc;
+ void *addr = page_address(page) + poff;
dma_addr_t iovp;
dma_addr_t offset;
u64 *pdir_start;
@@ -990,7 +993,14 @@ sba_map_single_attrs(struct device *dev, void *addr, size_t size, int dir,
#endif
return SBA_IOVA(ioc, iovp, offset);
}
-EXPORT_SYMBOL(sba_map_single_attrs);
+
+static dma_addr_t sba_map_single_attrs(struct device *dev, void *addr,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ return sba_map_page(dev, virt_to_page(addr),
+ (unsigned long)addr & ~PAGE_MASK, size, dir, attrs);
+}
#ifdef ENABLE_MARK_CLEAN
static SBA_INLINE void
@@ -1026,8 +1036,8 @@ sba_mark_clean(struct ioc *ioc, dma_addr_t iova, size_t size)
*
* See Documentation/PCI/PCI-DMA-mapping.txt
*/
-void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size,
- int dir, struct dma_attrs *attrs)
+static void sba_unmap_page(struct device *dev, dma_addr_t iova, size_t size,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
{
struct ioc *ioc;
#if DELAYED_RESOURCE_CNT > 0
@@ -1094,7 +1104,12 @@ void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size,
spin_unlock_irqrestore(&ioc->res_lock, flags);
#endif /* DELAYED_RESOURCE_CNT == 0 */
}
-EXPORT_SYMBOL(sba_unmap_single_attrs);
+
+void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+ sba_unmap_page(dev, iova, size, dir, attrs);
+}
/**
* sba_alloc_coherent - allocate/map shared mem for DMA
@@ -1104,7 +1119,7 @@ EXPORT_SYMBOL(sba_unmap_single_attrs);
*
* See Documentation/PCI/PCI-DMA-mapping.txt
*/
-void *
+static void *
sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags)
{
struct ioc *ioc;
@@ -1167,7 +1182,8 @@ sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp
*
* See Documentation/PCI/PCI-DMA-mapping.txt
*/
-void sba_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
+static void sba_free_coherent (struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle)
{
sba_unmap_single_attrs(dev, dma_handle, size, 0, NULL);
free_pages((unsigned long) vaddr, get_order(size));
@@ -1422,8 +1438,9 @@ sba_coalesce_chunks(struct ioc *ioc, struct device *dev,
*
* See Documentation/PCI/PCI-DMA-mapping.txt
*/
-int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents,
- int dir, struct dma_attrs *attrs)
+static int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
struct ioc *ioc;
int coalesced, filled = 0;
@@ -1502,7 +1519,6 @@ int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents,
return filled;
}
-EXPORT_SYMBOL(sba_map_sg_attrs);
/**
* sba_unmap_sg_attrs - unmap Scatter/Gather list
@@ -1514,8 +1530,9 @@ EXPORT_SYMBOL(sba_map_sg_attrs);
*
* See Documentation/PCI/PCI-DMA-mapping.txt
*/
-void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist,
- int nents, int dir, struct dma_attrs *attrs)
+static void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
#ifdef ASSERT_PDIR_SANITY
struct ioc *ioc;
@@ -1551,7 +1568,6 @@ void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist,
#endif
}
-EXPORT_SYMBOL(sba_unmap_sg_attrs);
/**************************************************************
*
@@ -2064,6 +2080,8 @@ static struct acpi_driver acpi_sba_ioc_driver = {
},
};
+extern struct dma_map_ops swiotlb_dma_ops;
+
static int __init
sba_init(void)
{
@@ -2077,6 +2095,7 @@ sba_init(void)
* a successful kdump kernel boot is to use the swiotlb.
*/
if (is_kdump_kernel()) {
+ dma_ops = &swiotlb_dma_ops;
if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
panic("Unable to initialize software I/O TLB:"
" Try machvec=dig boot option");
@@ -2092,6 +2111,7 @@ sba_init(void)
* If we didn't find something sba_iommu can claim, we
* need to setup the swiotlb and switch to the dig machvec.
*/
+ dma_ops = &swiotlb_dma_ops;
if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
panic("Unable to find SBA IOMMU or initialize "
"software I/O TLB: Try machvec=dig boot option");
@@ -2138,15 +2158,13 @@ nosbagart(char *str)
return 1;
}
-int
-sba_dma_supported (struct device *dev, u64 mask)
+static int sba_dma_supported (struct device *dev, u64 mask)
{
/* make sure it's at least 32bit capable */
return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL);
}
-int
-sba_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+static int sba_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
return 0;
}
@@ -2176,7 +2194,22 @@ sba_page_override(char *str)
__setup("sbapagesize=",sba_page_override);
-EXPORT_SYMBOL(sba_dma_mapping_error);
-EXPORT_SYMBOL(sba_dma_supported);
-EXPORT_SYMBOL(sba_alloc_coherent);
-EXPORT_SYMBOL(sba_free_coherent);
+struct dma_map_ops sba_dma_ops = {
+ .alloc_coherent = sba_alloc_coherent,
+ .free_coherent = sba_free_coherent,
+ .map_page = sba_map_page,
+ .unmap_page = sba_unmap_page,
+ .map_sg = sba_map_sg_attrs,
+ .unmap_sg = sba_unmap_sg_attrs,
+ .sync_single_for_cpu = machvec_dma_sync_single,
+ .sync_sg_for_cpu = machvec_dma_sync_sg,
+ .sync_single_for_device = machvec_dma_sync_single,
+ .sync_sg_for_device = machvec_dma_sync_sg,
+ .dma_supported = sba_dma_supported,
+ .mapping_error = sba_dma_mapping_error,
+};
+
+void sba_dma_init(void)
+{
+ dma_ops = &sba_dma_ops;
+}
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index 24b1ad5334cb..2bef5261d96d 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -24,6 +24,7 @@
#include <linux/major.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/capability.h>
#include <linux/console.h>
@@ -848,38 +849,36 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
* /proc fs routines....
*/
-static inline int line_info(char *buf, struct serial_state *state)
+static inline void line_info(struct seq_file *m, struct serial_state *state)
{
- return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n",
+ seq_printf(m, "%d: uart:%s port:%lX irq:%d\n",
state->line, uart_config[state->type].name,
state->port, state->irq);
}
-static int rs_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int rs_proc_show(struct seq_file *m, void *v)
{
- int i, len = 0, l;
- off_t begin = 0;
-
- len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version);
- for (i = 0; i < NR_PORTS && len < 4000; i++) {
- l = line_info(page + len, &rs_table[i]);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
- }
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (begin-off);
- return ((count < begin+len-off) ? count : begin+len-off);
+ int i;
+
+ seq_printf(m, "simserinfo:1.0 driver:%s\n", serial_version);
+ for (i = 0; i < NR_PORTS; i++)
+ line_info(m, &rs_table[i]);
+ return 0;
}
+static int rs_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, rs_proc_show, NULL);
+}
+
+static const struct file_operations rs_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = rs_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*
* ---------------------------------------------------------------------
* rs_init() and friends
@@ -917,7 +916,7 @@ static const struct tty_operations hp_ops = {
.start = rs_start,
.hangup = rs_hangup,
.wait_until_sent = rs_wait_until_sent,
- .read_proc = rs_read_proc,
+ .proc_fops = &rs_proc_fops,
};
/*
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
index a46f8395e9a5..af9405cd70e5 100644
--- a/arch/ia64/ia32/ia32_entry.S
+++ b/arch/ia64/ia32/ia32_entry.S
@@ -240,7 +240,7 @@ ia32_syscall_table:
data8 sys_ni_syscall
data8 sys_umask /* 60 */
data8 sys_chroot
- data8 sys_ustat
+ data8 compat_sys_ustat
data8 sys_dup2
data8 sys_getppid
data8 sys_getpgrp /* 65 */
diff --git a/arch/ia64/include/asm/dma-mapping.h b/arch/ia64/include/asm/dma-mapping.h
index 1f912d927585..36c0009dbece 100644
--- a/arch/ia64/include/asm/dma-mapping.h
+++ b/arch/ia64/include/asm/dma-mapping.h
@@ -11,99 +11,128 @@
#define ARCH_HAS_DMA_GET_REQUIRED_MASK
-struct dma_mapping_ops {
- int (*mapping_error)(struct device *dev,
- dma_addr_t dma_addr);
- void* (*alloc_coherent)(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp);
- void (*free_coherent)(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
- dma_addr_t (*map_single)(struct device *hwdev, unsigned long ptr,
- size_t size, int direction);
- void (*unmap_single)(struct device *dev, dma_addr_t addr,
- size_t size, int direction);
- void (*sync_single_for_cpu)(struct device *hwdev,
- dma_addr_t dma_handle, size_t size,
- int direction);
- void (*sync_single_for_device)(struct device *hwdev,
- dma_addr_t dma_handle, size_t size,
- int direction);
- void (*sync_single_range_for_cpu)(struct device *hwdev,
- dma_addr_t dma_handle, unsigned long offset,
- size_t size, int direction);
- void (*sync_single_range_for_device)(struct device *hwdev,
- dma_addr_t dma_handle, unsigned long offset,
- size_t size, int direction);
- void (*sync_sg_for_cpu)(struct device *hwdev,
- struct scatterlist *sg, int nelems,
- int direction);
- void (*sync_sg_for_device)(struct device *hwdev,
- struct scatterlist *sg, int nelems,
- int direction);
- int (*map_sg)(struct device *hwdev, struct scatterlist *sg,
- int nents, int direction);
- void (*unmap_sg)(struct device *hwdev,
- struct scatterlist *sg, int nents,
- int direction);
- int (*dma_supported_op)(struct device *hwdev, u64 mask);
- int is_phys;
-};
-
-extern struct dma_mapping_ops *dma_ops;
+extern struct dma_map_ops *dma_ops;
extern struct ia64_machine_vector ia64_mv;
extern void set_iommu_machvec(void);
-#define dma_alloc_coherent(dev, size, handle, gfp) \
- platform_dma_alloc_coherent(dev, size, handle, (gfp) | GFP_DMA)
+extern void machvec_dma_sync_single(struct device *, dma_addr_t, size_t,
+ enum dma_data_direction);
+extern void machvec_dma_sync_sg(struct device *, struct scatterlist *, int,
+ enum dma_data_direction);
-/* coherent mem. is cheap */
-static inline void *
-dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
- gfp_t flag)
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *daddr, gfp_t gfp)
{
- return dma_alloc_coherent(dev, size, dma_handle, flag);
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
+ return ops->alloc_coherent(dev, size, daddr, gfp);
}
-#define dma_free_coherent platform_dma_free_coherent
-static inline void
-dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t dma_handle)
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+ void *caddr, dma_addr_t daddr)
+{
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
+ ops->free_coherent(dev, size, caddr, daddr);
+}
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+
+static inline dma_addr_t dma_map_single_attrs(struct device *dev,
+ void *caddr, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
+ return ops->map_page(dev, virt_to_page(caddr),
+ (unsigned long)caddr & ~PAGE_MASK, size,
+ dir, attrs);
+}
+
+static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t daddr,
+ size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
+ ops->unmap_page(dev, daddr, size, dir, attrs);
+}
+
+#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL)
+#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
+
+static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
+ return ops->map_sg(dev, sgl, nents, dir, attrs);
+}
+
+static inline void dma_unmap_sg_attrs(struct device *dev,
+ struct scatterlist *sgl, int nents,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
+{
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
+ ops->unmap_sg(dev, sgl, nents, dir, attrs);
+}
+
+#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
+#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
+
+static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t daddr,
+ size_t size,
+ enum dma_data_direction dir)
{
- dma_free_coherent(dev, size, cpu_addr, dma_handle);
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
+ ops->sync_single_for_cpu(dev, daddr, size, dir);
}
-#define dma_map_single_attrs platform_dma_map_single_attrs
-static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
- size_t size, int dir)
+
+static inline void dma_sync_sg_for_cpu(struct device *dev,
+ struct scatterlist *sgl,
+ int nents, enum dma_data_direction dir)
{
- return dma_map_single_attrs(dev, cpu_addr, size, dir, NULL);
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
+ ops->sync_sg_for_cpu(dev, sgl, nents, dir);
}
-#define dma_map_sg_attrs platform_dma_map_sg_attrs
-static inline int dma_map_sg(struct device *dev, struct scatterlist *sgl,
- int nents, int dir)
+
+static inline void dma_sync_single_for_device(struct device *dev,
+ dma_addr_t daddr,
+ size_t size,
+ enum dma_data_direction dir)
{
- return dma_map_sg_attrs(dev, sgl, nents, dir, NULL);
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
+ ops->sync_single_for_device(dev, daddr, size, dir);
}
-#define dma_unmap_single_attrs platform_dma_unmap_single_attrs
-static inline void dma_unmap_single(struct device *dev, dma_addr_t cpu_addr,
- size_t size, int dir)
+
+static inline void dma_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sgl,
+ int nents,
+ enum dma_data_direction dir)
{
- return dma_unmap_single_attrs(dev, cpu_addr, size, dir, NULL);
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
+ ops->sync_sg_for_device(dev, sgl, nents, dir);
}
-#define dma_unmap_sg_attrs platform_dma_unmap_sg_attrs
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
- int nents, int dir)
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t daddr)
+{
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
+ return ops->mapping_error(dev, daddr);
+}
+
+static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
+ size_t offset, size_t size,
+ enum dma_data_direction dir)
{
- return dma_unmap_sg_attrs(dev, sgl, nents, dir, NULL);
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
+ return ops->map_page(dev, page, offset, size, dir, NULL);
}
-#define dma_sync_single_for_cpu platform_dma_sync_single_for_cpu
-#define dma_sync_sg_for_cpu platform_dma_sync_sg_for_cpu
-#define dma_sync_single_for_device platform_dma_sync_single_for_device
-#define dma_sync_sg_for_device platform_dma_sync_sg_for_device
-#define dma_mapping_error platform_dma_mapping_error
-#define dma_map_page(dev, pg, off, size, dir) \
- dma_map_single(dev, page_address(pg) + (off), (size), (dir))
-#define dma_unmap_page(dev, dma_addr, size, dir) \
- dma_unmap_single(dev, dma_addr, size, dir)
+static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
+ size_t size, enum dma_data_direction dir)
+{
+ dma_unmap_single(dev, addr, size, dir);
+}
/*
* Rest of this file is part of the "Advanced DMA API". Use at your own risk.
@@ -115,7 +144,11 @@ static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
#define dma_sync_single_range_for_device(dev, dma_handle, offset, size, dir) \
dma_sync_single_for_device(dev, dma_handle, size, dir)
-#define dma_supported platform_dma_supported
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
+ return ops->dma_supported(dev, mask);
+}
static inline int
dma_set_mask (struct device *dev, u64 mask)
@@ -141,11 +174,4 @@ dma_cache_sync (struct device *dev, void *vaddr, size_t size,
#define dma_is_consistent(d, h) (1) /* all we do is coherent memory... */
-static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
-{
- return dma_ops;
-}
-
-
-
#endif /* _ASM_IA64_DMA_MAPPING_H */
diff --git a/arch/ia64/include/asm/intrinsics.h b/arch/ia64/include/asm/intrinsics.h
index c47830e26cb7..111ed5222892 100644
--- a/arch/ia64/include/asm/intrinsics.h
+++ b/arch/ia64/include/asm/intrinsics.h
@@ -202,7 +202,11 @@ extern long ia64_cmpxchg_called_with_bad_pointer (void);
#ifndef __ASSEMBLY__
#if defined(CONFIG_PARAVIRT) && defined(__KERNEL__)
-#define IA64_INTRINSIC_API(name) pv_cpu_ops.name
+#ifdef ASM_SUPPORTED
+# define IA64_INTRINSIC_API(name) paravirt_ ## name
+#else
+# define IA64_INTRINSIC_API(name) pv_cpu_ops.name
+#endif
#define IA64_INTRINSIC_MACRO(name) paravirt_ ## name
#else
#define IA64_INTRINSIC_API(name) ia64_native_ ## name
diff --git a/arch/ia64/include/asm/kvm.h b/arch/ia64/include/asm/kvm.h
index 2b0a38e84705..18a7e49abbc5 100644
--- a/arch/ia64/include/asm/kvm.h
+++ b/arch/ia64/include/asm/kvm.h
@@ -165,7 +165,40 @@ struct saved_vpd {
unsigned long vcpuid[5];
unsigned long vpsr;
unsigned long vpr;
- unsigned long vcr[128];
+ union {
+ unsigned long vcr[128];
+ struct {
+ unsigned long dcr;
+ unsigned long itm;
+ unsigned long iva;
+ unsigned long rsv1[5];
+ unsigned long pta;
+ unsigned long rsv2[7];
+ unsigned long ipsr;
+ unsigned long isr;
+ unsigned long rsv3;
+ unsigned long iip;
+ unsigned long ifa;
+ unsigned long itir;
+ unsigned long iipa;
+ unsigned long ifs;
+ unsigned long iim;
+ unsigned long iha;
+ unsigned long rsv4[38];
+ unsigned long lid;
+ unsigned long ivr;
+ unsigned long tpr;
+ unsigned long eoi;
+ unsigned long irr[4];
+ unsigned long itv;
+ unsigned long pmv;
+ unsigned long cmcv;
+ unsigned long rsv5[5];
+ unsigned long lrr0;
+ unsigned long lrr1;
+ unsigned long rsv6[46];
+ };
+ };
};
struct kvm_regs {
@@ -213,4 +246,18 @@ struct kvm_sregs {
struct kvm_fpu {
};
+#define KVM_IA64_VCPU_STACK_SHIFT 16
+#define KVM_IA64_VCPU_STACK_SIZE (1UL << KVM_IA64_VCPU_STACK_SHIFT)
+
+struct kvm_ia64_vcpu_stack {
+ unsigned char stack[KVM_IA64_VCPU_STACK_SIZE];
+};
+
+struct kvm_debug_exit_arch {
+};
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+};
+
#endif
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h
index 348663661659..4542651e6acb 100644
--- a/arch/ia64/include/asm/kvm_host.h
+++ b/arch/ia64/include/asm/kvm_host.h
@@ -112,7 +112,11 @@
#define VCPU_STRUCT_SHIFT 16
#define VCPU_STRUCT_SIZE (__IA64_UL_CONST(1) << VCPU_STRUCT_SHIFT)
-#define KVM_STK_OFFSET VCPU_STRUCT_SIZE
+/*
+ * This must match KVM_IA64_VCPU_STACK_{SHIFT,SIZE} arch/ia64/include/asm/kvm.h
+ */
+#define KVM_STK_SHIFT 16
+#define KVM_STK_OFFSET (__IA64_UL_CONST(1)<< KVM_STK_SHIFT)
#define KVM_VM_STRUCT_SHIFT 19
#define KVM_VM_STRUCT_SIZE (__IA64_UL_CONST(1) << KVM_VM_STRUCT_SHIFT)
@@ -153,10 +157,10 @@ struct kvm_vm_data {
struct kvm_vcpu_data vcpu_data[KVM_MAX_VCPUS];
};
-#define VCPU_BASE(n) KVM_VM_DATA_BASE + \
- offsetof(struct kvm_vm_data, vcpu_data[n])
-#define VM_BASE KVM_VM_DATA_BASE + \
- offsetof(struct kvm_vm_data, kvm_vm_struct)
+#define VCPU_BASE(n) (KVM_VM_DATA_BASE + \
+ offsetof(struct kvm_vm_data, vcpu_data[n]))
+#define KVM_VM_BASE (KVM_VM_DATA_BASE + \
+ offsetof(struct kvm_vm_data, kvm_vm_struct))
#define KVM_MEM_DIRTY_LOG_BASE KVM_VM_DATA_BASE + \
offsetof(struct kvm_vm_data, kvm_mem_dirty_log)
@@ -235,8 +239,6 @@ struct kvm_vm_data {
struct kvm;
struct kvm_vcpu;
-struct kvm_guest_debug{
-};
struct kvm_mmio_req {
uint64_t addr; /* physical address */
@@ -462,6 +464,8 @@ struct kvm_arch {
unsigned long metaphysical_rr4;
unsigned long vmm_init_rr;
+ int online_vcpus;
+
struct kvm_ioapic *vioapic;
struct kvm_vm_stat stat;
struct kvm_sal_data rdv_sal_data;
diff --git a/arch/ia64/include/asm/machvec.h b/arch/ia64/include/asm/machvec.h
index fe87b2121707..367d299d9938 100644
--- a/arch/ia64/include/asm/machvec.h
+++ b/arch/ia64/include/asm/machvec.h
@@ -11,7 +11,6 @@
#define _ASM_IA64_MACHVEC_H
#include <linux/types.h>
-#include <linux/swiotlb.h>
/* forward declarations: */
struct device;
@@ -45,24 +44,8 @@ typedef void ia64_mv_kernel_launch_event_t(void);
/* DMA-mapping interface: */
typedef void ia64_mv_dma_init (void);
-typedef void *ia64_mv_dma_alloc_coherent (struct device *, size_t, dma_addr_t *, gfp_t);
-typedef void ia64_mv_dma_free_coherent (struct device *, size_t, void *, dma_addr_t);
-typedef dma_addr_t ia64_mv_dma_map_single (struct device *, void *, size_t, int);
-typedef void ia64_mv_dma_unmap_single (struct device *, dma_addr_t, size_t, int);
-typedef int ia64_mv_dma_map_sg (struct device *, struct scatterlist *, int, int);
-typedef void ia64_mv_dma_unmap_sg (struct device *, struct scatterlist *, int, int);
-typedef void ia64_mv_dma_sync_single_for_cpu (struct device *, dma_addr_t, size_t, int);
-typedef void ia64_mv_dma_sync_sg_for_cpu (struct device *, struct scatterlist *, int, int);
-typedef void ia64_mv_dma_sync_single_for_device (struct device *, dma_addr_t, size_t, int);
-typedef void ia64_mv_dma_sync_sg_for_device (struct device *, struct scatterlist *, int, int);
-typedef int ia64_mv_dma_mapping_error(struct device *, dma_addr_t dma_addr);
-typedef int ia64_mv_dma_supported (struct device *, u64);
-
-typedef dma_addr_t ia64_mv_dma_map_single_attrs (struct device *, void *, size_t, int, struct dma_attrs *);
-typedef void ia64_mv_dma_unmap_single_attrs (struct device *, dma_addr_t, size_t, int, struct dma_attrs *);
-typedef int ia64_mv_dma_map_sg_attrs (struct device *, struct scatterlist *, int, int, struct dma_attrs *);
-typedef void ia64_mv_dma_unmap_sg_attrs (struct device *, struct scatterlist *, int, int, struct dma_attrs *);
typedef u64 ia64_mv_dma_get_required_mask (struct device *);
+typedef struct dma_map_ops *ia64_mv_dma_get_ops(struct device *);
/*
* WARNING: The legacy I/O space is _architected_. Platforms are
@@ -114,8 +97,6 @@ machvec_noop_bus (struct pci_bus *bus)
extern void machvec_setup (char **);
extern void machvec_timer_interrupt (int, void *);
-extern void machvec_dma_sync_single (struct device *, dma_addr_t, size_t, int);
-extern void machvec_dma_sync_sg (struct device *, struct scatterlist *, int, int);
extern void machvec_tlb_migrate_finish (struct mm_struct *);
# if defined (CONFIG_IA64_HP_SIM)
@@ -148,19 +129,8 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *);
# define platform_global_tlb_purge ia64_mv.global_tlb_purge
# define platform_tlb_migrate_finish ia64_mv.tlb_migrate_finish
# define platform_dma_init ia64_mv.dma_init
-# define platform_dma_alloc_coherent ia64_mv.dma_alloc_coherent
-# define platform_dma_free_coherent ia64_mv.dma_free_coherent
-# define platform_dma_map_single_attrs ia64_mv.dma_map_single_attrs
-# define platform_dma_unmap_single_attrs ia64_mv.dma_unmap_single_attrs
-# define platform_dma_map_sg_attrs ia64_mv.dma_map_sg_attrs
-# define platform_dma_unmap_sg_attrs ia64_mv.dma_unmap_sg_attrs
-# define platform_dma_sync_single_for_cpu ia64_mv.dma_sync_single_for_cpu
-# define platform_dma_sync_sg_for_cpu ia64_mv.dma_sync_sg_for_cpu
-# define platform_dma_sync_single_for_device ia64_mv.dma_sync_single_for_device
-# define platform_dma_sync_sg_for_device ia64_mv.dma_sync_sg_for_device
-# define platform_dma_mapping_error ia64_mv.dma_mapping_error
-# define platform_dma_supported ia64_mv.dma_supported
# define platform_dma_get_required_mask ia64_mv.dma_get_required_mask
+# define platform_dma_get_ops ia64_mv.dma_get_ops
# define platform_irq_to_vector ia64_mv.irq_to_vector
# define platform_local_vector_to_irq ia64_mv.local_vector_to_irq
# define platform_pci_get_legacy_mem ia64_mv.pci_get_legacy_mem
@@ -203,19 +173,8 @@ struct ia64_machine_vector {
ia64_mv_global_tlb_purge_t *global_tlb_purge;
ia64_mv_tlb_migrate_finish_t *tlb_migrate_finish;
ia64_mv_dma_init *dma_init;
- ia64_mv_dma_alloc_coherent *dma_alloc_coherent;
- ia64_mv_dma_free_coherent *dma_free_coherent;
- ia64_mv_dma_map_single_attrs *dma_map_single_attrs;
- ia64_mv_dma_unmap_single_attrs *dma_unmap_single_attrs;
- ia64_mv_dma_map_sg_attrs *dma_map_sg_attrs;
- ia64_mv_dma_unmap_sg_attrs *dma_unmap_sg_attrs;
- ia64_mv_dma_sync_single_for_cpu *dma_sync_single_for_cpu;
- ia64_mv_dma_sync_sg_for_cpu *dma_sync_sg_for_cpu;
- ia64_mv_dma_sync_single_for_device *dma_sync_single_for_device;
- ia64_mv_dma_sync_sg_for_device *dma_sync_sg_for_device;
- ia64_mv_dma_mapping_error *dma_mapping_error;
- ia64_mv_dma_supported *dma_supported;
ia64_mv_dma_get_required_mask *dma_get_required_mask;
+ ia64_mv_dma_get_ops *dma_get_ops;
ia64_mv_irq_to_vector *irq_to_vector;
ia64_mv_local_vector_to_irq *local_vector_to_irq;
ia64_mv_pci_get_legacy_mem_t *pci_get_legacy_mem;
@@ -254,19 +213,8 @@ struct ia64_machine_vector {
platform_global_tlb_purge, \
platform_tlb_migrate_finish, \
platform_dma_init, \
- platform_dma_alloc_coherent, \
- platform_dma_free_coherent, \
- platform_dma_map_single_attrs, \
- platform_dma_unmap_single_attrs, \
- platform_dma_map_sg_attrs, \
- platform_dma_unmap_sg_attrs, \
- platform_dma_sync_single_for_cpu, \
- platform_dma_sync_sg_for_cpu, \
- platform_dma_sync_single_for_device, \
- platform_dma_sync_sg_for_device, \
- platform_dma_mapping_error, \
- platform_dma_supported, \
platform_dma_get_required_mask, \
+ platform_dma_get_ops, \
platform_irq_to_vector, \
platform_local_vector_to_irq, \
platform_pci_get_legacy_mem, \
@@ -302,6 +250,9 @@ extern void machvec_init_from_cmdline(const char *cmdline);
# error Unknown configuration. Update arch/ia64/include/asm/machvec.h.
# endif /* CONFIG_IA64_GENERIC */
+extern void swiotlb_dma_init(void);
+extern struct dma_map_ops *dma_get_ops(struct device *);
+
/*
* Define default versions so we can extend machvec for new platforms without having
* to update the machvec files for all existing platforms.
@@ -332,43 +283,10 @@ extern void machvec_init_from_cmdline(const char *cmdline);
# define platform_kernel_launch_event machvec_noop
#endif
#ifndef platform_dma_init
-# define platform_dma_init swiotlb_init
-#endif
-#ifndef platform_dma_alloc_coherent
-# define platform_dma_alloc_coherent swiotlb_alloc_coherent
-#endif
-#ifndef platform_dma_free_coherent
-# define platform_dma_free_coherent swiotlb_free_coherent
-#endif
-#ifndef platform_dma_map_single_attrs
-# define platform_dma_map_single_attrs swiotlb_map_single_attrs
-#endif
-#ifndef platform_dma_unmap_single_attrs
-# define platform_dma_unmap_single_attrs swiotlb_unmap_single_attrs
-#endif
-#ifndef platform_dma_map_sg_attrs
-# define platform_dma_map_sg_attrs swiotlb_map_sg_attrs
-#endif
-#ifndef platform_dma_unmap_sg_attrs
-# define platform_dma_unmap_sg_attrs swiotlb_unmap_sg_attrs
-#endif
-#ifndef platform_dma_sync_single_for_cpu
-# define platform_dma_sync_single_for_cpu swiotlb_sync_single_for_cpu
-#endif
-#ifndef platform_dma_sync_sg_for_cpu
-# define platform_dma_sync_sg_for_cpu swiotlb_sync_sg_for_cpu
-#endif
-#ifndef platform_dma_sync_single_for_device
-# define platform_dma_sync_single_for_device swiotlb_sync_single_for_device
-#endif
-#ifndef platform_dma_sync_sg_for_device
-# define platform_dma_sync_sg_for_device swiotlb_sync_sg_for_device
-#endif
-#ifndef platform_dma_mapping_error
-# define platform_dma_mapping_error swiotlb_dma_mapping_error
+# define platform_dma_init swiotlb_dma_init
#endif
-#ifndef platform_dma_supported
-# define platform_dma_supported swiotlb_dma_supported
+#ifndef platform_dma_get_ops
+# define platform_dma_get_ops dma_get_ops
#endif
#ifndef platform_dma_get_required_mask
# define platform_dma_get_required_mask ia64_dma_get_required_mask
diff --git a/arch/ia64/include/asm/machvec_dig_vtd.h b/arch/ia64/include/asm/machvec_dig_vtd.h
index 3400b561e711..6ab1de5c45ef 100644
--- a/arch/ia64/include/asm/machvec_dig_vtd.h
+++ b/arch/ia64/include/asm/machvec_dig_vtd.h
@@ -2,14 +2,6 @@
#define _ASM_IA64_MACHVEC_DIG_VTD_h
extern ia64_mv_setup_t dig_setup;
-extern ia64_mv_dma_alloc_coherent vtd_alloc_coherent;
-extern ia64_mv_dma_free_coherent vtd_free_coherent;
-extern ia64_mv_dma_map_single_attrs vtd_map_single_attrs;
-extern ia64_mv_dma_unmap_single_attrs vtd_unmap_single_attrs;
-extern ia64_mv_dma_map_sg_attrs vtd_map_sg_attrs;
-extern ia64_mv_dma_unmap_sg_attrs vtd_unmap_sg_attrs;
-extern ia64_mv_dma_supported iommu_dma_supported;
-extern ia64_mv_dma_mapping_error vtd_dma_mapping_error;
extern ia64_mv_dma_init pci_iommu_alloc;
/*
@@ -22,17 +14,5 @@ extern ia64_mv_dma_init pci_iommu_alloc;
#define platform_name "dig_vtd"
#define platform_setup dig_setup
#define platform_dma_init pci_iommu_alloc
-#define platform_dma_alloc_coherent vtd_alloc_coherent
-#define platform_dma_free_coherent vtd_free_coherent
-#define platform_dma_map_single_attrs vtd_map_single_attrs
-#define platform_dma_unmap_single_attrs vtd_unmap_single_attrs
-#define platform_dma_map_sg_attrs vtd_map_sg_attrs
-#define platform_dma_unmap_sg_attrs vtd_unmap_sg_attrs
-#define platform_dma_sync_single_for_cpu machvec_dma_sync_single
-#define platform_dma_sync_sg_for_cpu machvec_dma_sync_sg
-#define platform_dma_sync_single_for_device machvec_dma_sync_single
-#define platform_dma_sync_sg_for_device machvec_dma_sync_sg
-#define platform_dma_supported iommu_dma_supported
-#define platform_dma_mapping_error vtd_dma_mapping_error
#endif /* _ASM_IA64_MACHVEC_DIG_VTD_h */
diff --git a/arch/ia64/include/asm/machvec_hpzx1.h b/arch/ia64/include/asm/machvec_hpzx1.h
index 2f57f5144b9f..3bd83d78a412 100644
--- a/arch/ia64/include/asm/machvec_hpzx1.h
+++ b/arch/ia64/include/asm/machvec_hpzx1.h
@@ -2,14 +2,7 @@
#define _ASM_IA64_MACHVEC_HPZX1_h
extern ia64_mv_setup_t dig_setup;
-extern ia64_mv_dma_alloc_coherent sba_alloc_coherent;
-extern ia64_mv_dma_free_coherent sba_free_coherent;
-extern ia64_mv_dma_map_single_attrs sba_map_single_attrs;
-extern ia64_mv_dma_unmap_single_attrs sba_unmap_single_attrs;
-extern ia64_mv_dma_map_sg_attrs sba_map_sg_attrs;
-extern ia64_mv_dma_unmap_sg_attrs sba_unmap_sg_attrs;
-extern ia64_mv_dma_supported sba_dma_supported;
-extern ia64_mv_dma_mapping_error sba_dma_mapping_error;
+extern ia64_mv_dma_init sba_dma_init;
/*
* This stuff has dual use!
@@ -20,18 +13,6 @@ extern ia64_mv_dma_mapping_error sba_dma_mapping_error;
*/
#define platform_name "hpzx1"
#define platform_setup dig_setup
-#define platform_dma_init machvec_noop
-#define platform_dma_alloc_coherent sba_alloc_coherent
-#define platform_dma_free_coherent sba_free_coherent
-#define platform_dma_map_single_attrs sba_map_single_attrs
-#define platform_dma_unmap_single_attrs sba_unmap_single_attrs
-#define platform_dma_map_sg_attrs sba_map_sg_attrs
-#define platform_dma_unmap_sg_attrs sba_unmap_sg_attrs
-#define platform_dma_sync_single_for_cpu machvec_dma_sync_single
-#define platform_dma_sync_sg_for_cpu machvec_dma_sync_sg
-#define platform_dma_sync_single_for_device machvec_dma_sync_single
-#define platform_dma_sync_sg_for_device machvec_dma_sync_sg
-#define platform_dma_supported sba_dma_supported
-#define platform_dma_mapping_error sba_dma_mapping_error
+#define platform_dma_init sba_dma_init
#endif /* _ASM_IA64_MACHVEC_HPZX1_h */
diff --git a/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h b/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h
index a842cdda827b..1091ac39740c 100644
--- a/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h
+++ b/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h
@@ -2,18 +2,7 @@
#define _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h
extern ia64_mv_setup_t dig_setup;
-extern ia64_mv_dma_alloc_coherent hwsw_alloc_coherent;
-extern ia64_mv_dma_free_coherent hwsw_free_coherent;
-extern ia64_mv_dma_map_single_attrs hwsw_map_single_attrs;
-extern ia64_mv_dma_unmap_single_attrs hwsw_unmap_single_attrs;
-extern ia64_mv_dma_map_sg_attrs hwsw_map_sg_attrs;
-extern ia64_mv_dma_unmap_sg_attrs hwsw_unmap_sg_attrs;
-extern ia64_mv_dma_supported hwsw_dma_supported;
-extern ia64_mv_dma_mapping_error hwsw_dma_mapping_error;
-extern ia64_mv_dma_sync_single_for_cpu hwsw_sync_single_for_cpu;
-extern ia64_mv_dma_sync_sg_for_cpu hwsw_sync_sg_for_cpu;
-extern ia64_mv_dma_sync_single_for_device hwsw_sync_single_for_device;
-extern ia64_mv_dma_sync_sg_for_device hwsw_sync_sg_for_device;
+extern ia64_mv_dma_get_ops hwsw_dma_get_ops;
/*
* This stuff has dual use!
@@ -23,20 +12,8 @@ extern ia64_mv_dma_sync_sg_for_device hwsw_sync_sg_for_device;
* the macros are used directly.
*/
#define platform_name "hpzx1_swiotlb"
-
#define platform_setup dig_setup
#define platform_dma_init machvec_noop
-#define platform_dma_alloc_coherent hwsw_alloc_coherent
-#define platform_dma_free_coherent hwsw_free_coherent
-#define platform_dma_map_single_attrs hwsw_map_single_attrs
-#define platform_dma_unmap_single_attrs hwsw_unmap_single_attrs
-#define platform_dma_map_sg_attrs hwsw_map_sg_attrs
-#define platform_dma_unmap_sg_attrs hwsw_unmap_sg_attrs
-#define platform_dma_supported hwsw_dma_supported
-#define platform_dma_mapping_error hwsw_dma_mapping_error
-#define platform_dma_sync_single_for_cpu hwsw_sync_single_for_cpu
-#define platform_dma_sync_sg_for_cpu hwsw_sync_sg_for_cpu
-#define platform_dma_sync_single_for_device hwsw_sync_single_for_device
-#define platform_dma_sync_sg_for_device hwsw_sync_sg_for_device
+#define platform_dma_get_ops hwsw_dma_get_ops
#endif /* _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h */
diff --git a/arch/ia64/include/asm/machvec_sn2.h b/arch/ia64/include/asm/machvec_sn2.h
index f1a6e0d6dfa5..f061a30aac42 100644
--- a/arch/ia64/include/asm/machvec_sn2.h
+++ b/arch/ia64/include/asm/machvec_sn2.h
@@ -55,19 +55,8 @@ extern ia64_mv_readb_t __sn_readb_relaxed;
extern ia64_mv_readw_t __sn_readw_relaxed;
extern ia64_mv_readl_t __sn_readl_relaxed;
extern ia64_mv_readq_t __sn_readq_relaxed;
-extern ia64_mv_dma_alloc_coherent sn_dma_alloc_coherent;
-extern ia64_mv_dma_free_coherent sn_dma_free_coherent;
-extern ia64_mv_dma_map_single_attrs sn_dma_map_single_attrs;
-extern ia64_mv_dma_unmap_single_attrs sn_dma_unmap_single_attrs;
-extern ia64_mv_dma_map_sg_attrs sn_dma_map_sg_attrs;
-extern ia64_mv_dma_unmap_sg_attrs sn_dma_unmap_sg_attrs;
-extern ia64_mv_dma_sync_single_for_cpu sn_dma_sync_single_for_cpu;
-extern ia64_mv_dma_sync_sg_for_cpu sn_dma_sync_sg_for_cpu;
-extern ia64_mv_dma_sync_single_for_device sn_dma_sync_single_for_device;
-extern ia64_mv_dma_sync_sg_for_device sn_dma_sync_sg_for_device;
-extern ia64_mv_dma_mapping_error sn_dma_mapping_error;
-extern ia64_mv_dma_supported sn_dma_supported;
extern ia64_mv_dma_get_required_mask sn_dma_get_required_mask;
+extern ia64_mv_dma_init sn_dma_init;
extern ia64_mv_migrate_t sn_migrate;
extern ia64_mv_kernel_launch_event_t sn_kernel_launch_event;
extern ia64_mv_setup_msi_irq_t sn_setup_msi_irq;
@@ -111,20 +100,8 @@ extern ia64_mv_pci_fixup_bus_t sn_pci_fixup_bus;
#define platform_pci_get_legacy_mem sn_pci_get_legacy_mem
#define platform_pci_legacy_read sn_pci_legacy_read
#define platform_pci_legacy_write sn_pci_legacy_write
-#define platform_dma_init machvec_noop
-#define platform_dma_alloc_coherent sn_dma_alloc_coherent
-#define platform_dma_free_coherent sn_dma_free_coherent
-#define platform_dma_map_single_attrs sn_dma_map_single_attrs
-#define platform_dma_unmap_single_attrs sn_dma_unmap_single_attrs
-#define platform_dma_map_sg_attrs sn_dma_map_sg_attrs
-#define platform_dma_unmap_sg_attrs sn_dma_unmap_sg_attrs
-#define platform_dma_sync_single_for_cpu sn_dma_sync_single_for_cpu
-#define platform_dma_sync_sg_for_cpu sn_dma_sync_sg_for_cpu
-#define platform_dma_sync_single_for_device sn_dma_sync_single_for_device
-#define platform_dma_sync_sg_for_device sn_dma_sync_sg_for_device
-#define platform_dma_mapping_error sn_dma_mapping_error
-#define platform_dma_supported sn_dma_supported
#define platform_dma_get_required_mask sn_dma_get_required_mask
+#define platform_dma_init sn_dma_init
#define platform_migrate sn_migrate
#define platform_kernel_launch_event sn_kernel_launch_event
#ifdef CONFIG_PCI_MSI
diff --git a/arch/ia64/include/asm/mmu_context.h b/arch/ia64/include/asm/mmu_context.h
index 040bc87db930..7f2a456603cb 100644
--- a/arch/ia64/include/asm/mmu_context.h
+++ b/arch/ia64/include/asm/mmu_context.h
@@ -87,7 +87,7 @@ get_mmu_context (struct mm_struct *mm)
/* re-check, now that we've got the lock: */
context = mm->context;
if (context == 0) {
- cpus_clear(mm->cpu_vm_mask);
+ cpumask_clear(mm_cpumask(mm));
if (ia64_ctx.next >= ia64_ctx.limit) {
ia64_ctx.next = find_next_zero_bit(ia64_ctx.bitmap,
ia64_ctx.max_ctx, ia64_ctx.next);
@@ -166,8 +166,8 @@ activate_context (struct mm_struct *mm)
do {
context = get_mmu_context(mm);
- if (!cpu_isset(smp_processor_id(), mm->cpu_vm_mask))
- cpu_set(smp_processor_id(), mm->cpu_vm_mask);
+ if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
+ cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
reload_context(context);
/*
* in the unlikely event of a TLB-flush by another thread,
diff --git a/arch/ia64/include/asm/module.h b/arch/ia64/include/asm/module.h
index d2da61e4c49b..908eaef42a08 100644
--- a/arch/ia64/include/asm/module.h
+++ b/arch/ia64/include/asm/module.h
@@ -16,6 +16,12 @@ struct mod_arch_specific {
struct elf64_shdr *got; /* global offset table */
struct elf64_shdr *opd; /* official procedure descriptors */
struct elf64_shdr *unwind; /* unwind-table section */
+#ifdef CONFIG_PARAVIRT
+ struct elf64_shdr *paravirt_bundles;
+ /* paravirt_alt_bundle_patch table */
+ struct elf64_shdr *paravirt_insts;
+ /* paravirt_alt_inst_patch table */
+#endif
unsigned long gp; /* global-pointer for module */
void *core_unw_table; /* core unwind-table cookie returned by unwinder */
diff --git a/arch/ia64/include/asm/msidef.h b/arch/ia64/include/asm/msidef.h
new file mode 100644
index 000000000000..592c1047a0c5
--- /dev/null
+++ b/arch/ia64/include/asm/msidef.h
@@ -0,0 +1,42 @@
+#ifndef _IA64_MSI_DEF_H
+#define _IA64_MSI_DEF_H
+
+/*
+ * Shifts for APIC-based data
+ */
+
+#define MSI_DATA_VECTOR_SHIFT 0
+#define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT)
+#define MSI_DATA_VECTOR_MASK 0xffffff00
+
+#define MSI_DATA_DELIVERY_MODE_SHIFT 8
+#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_MODE_SHIFT)
+#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_MODE_SHIFT)
+
+#define MSI_DATA_LEVEL_SHIFT 14
+#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT)
+#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT)
+
+#define MSI_DATA_TRIGGER_SHIFT 15
+#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT)
+#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT)
+
+/*
+ * Shift/mask fields for APIC-based bus address
+ */
+
+#define MSI_ADDR_DEST_ID_SHIFT 4
+#define MSI_ADDR_HEADER 0xfee00000
+
+#define MSI_ADDR_DEST_ID_MASK 0xfff0000f
+#define MSI_ADDR_DEST_ID_CPU(cpu) ((cpu) << MSI_ADDR_DEST_ID_SHIFT)
+
+#define MSI_ADDR_DEST_MODE_SHIFT 2
+#define MSI_ADDR_DEST_MODE_PHYS (0 << MSI_ADDR_DEST_MODE_SHIFT)
+#define MSI_ADDR_DEST_MODE_LOGIC (1 << MSI_ADDR_DEST_MODE_SHIFT)
+
+#define MSI_ADDR_REDIRECTION_SHIFT 3
+#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT)
+#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT)
+
+#endif/* _IA64_MSI_DEF_H */
diff --git a/arch/ia64/include/asm/native/inst.h b/arch/ia64/include/asm/native/inst.h
index 0a1026cca4fa..d2d46efb3e6e 100644
--- a/arch/ia64/include/asm/native/inst.h
+++ b/arch/ia64/include/asm/native/inst.h
@@ -30,6 +30,9 @@
#define __paravirt_work_processed_syscall_target \
ia64_work_processed_syscall
+#define paravirt_fsyscall_table ia64_native_fsyscall_table
+#define paravirt_fsys_bubble_down ia64_native_fsys_bubble_down
+
#ifdef CONFIG_PARAVIRT_GUEST_ASM_CLOBBER_CHECK
# define PARAVIRT_POISON 0xdeadbeefbaadf00d
# define CLOBBER(clob) \
@@ -74,6 +77,11 @@
(pred) mov reg = psr \
CLOBBER(clob)
+#define MOV_FROM_ITC(pred, pred_clob, reg, clob) \
+(pred) mov reg = ar.itc \
+ CLOBBER(clob) \
+ CLOBBER_PRED(pred_clob)
+
#define MOV_TO_IFA(reg, clob) \
mov cr.ifa = reg \
CLOBBER(clob)
@@ -158,6 +166,11 @@
#define RSM_PSR_DT \
rsm psr.dt
+#define RSM_PSR_BE_I(clob0, clob1) \
+ rsm psr.be | psr.i \
+ CLOBBER(clob0) \
+ CLOBBER(clob1)
+
#define SSM_PSR_DT_AND_SRLZ_I \
ssm psr.dt \
;; \
diff --git a/arch/ia64/include/asm/native/patchlist.h b/arch/ia64/include/asm/native/patchlist.h
new file mode 100644
index 000000000000..be16ca9311bf
--- /dev/null
+++ b/arch/ia64/include/asm/native/patchlist.h
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * arch/ia64/include/asm/native/inst.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#define __paravirt_start_gate_fsyscall_patchlist \
+ __ia64_native_start_gate_fsyscall_patchlist
+#define __paravirt_end_gate_fsyscall_patchlist \
+ __ia64_native_end_gate_fsyscall_patchlist
+#define __paravirt_start_gate_brl_fsys_bubble_down_patchlist \
+ __ia64_native_start_gate_brl_fsys_bubble_down_patchlist
+#define __paravirt_end_gate_brl_fsys_bubble_down_patchlist \
+ __ia64_native_end_gate_brl_fsys_bubble_down_patchlist
+#define __paravirt_start_gate_vtop_patchlist \
+ __ia64_native_start_gate_vtop_patchlist
+#define __paravirt_end_gate_vtop_patchlist \
+ __ia64_native_end_gate_vtop_patchlist
+#define __paravirt_start_gate_mckinley_e9_patchlist \
+ __ia64_native_start_gate_mckinley_e9_patchlist
+#define __paravirt_end_gate_mckinley_e9_patchlist \
+ __ia64_native_end_gate_mckinley_e9_patchlist
diff --git a/arch/ia64/include/asm/native/pvchk_inst.h b/arch/ia64/include/asm/native/pvchk_inst.h
index b8e6eb1090d7..8d72962ec838 100644
--- a/arch/ia64/include/asm/native/pvchk_inst.h
+++ b/arch/ia64/include/asm/native/pvchk_inst.h
@@ -180,6 +180,11 @@
IS_PRED_IN(pred) \
IS_RREG_OUT(reg) \
IS_RREG_CLOB(clob)
+#define MOV_FROM_ITC(pred, pred_clob, reg, clob) \
+ IS_PRED_IN(pred) \
+ IS_PRED_CLOB(pred_clob) \
+ IS_RREG_OUT(reg) \
+ IS_RREG_CLOB(clob)
#define MOV_TO_IFA(reg, clob) \
IS_RREG_IN(reg) \
IS_RREG_CLOB(clob)
@@ -246,6 +251,9 @@
IS_RREG_CLOB(clob2)
#define RSM_PSR_DT \
nop 0
+#define RSM_PSR_BE_I(clob0, clob1) \
+ IS_RREG_CLOB(clob0) \
+ IS_RREG_CLOB(clob1)
#define SSM_PSR_DT_AND_SRLZ_I \
nop 0
#define BSW_0(clob0, clob1, clob2) \
diff --git a/arch/ia64/include/asm/paravirt.h b/arch/ia64/include/asm/paravirt.h
index 2bf3636473fe..2eb0a981a09a 100644
--- a/arch/ia64/include/asm/paravirt.h
+++ b/arch/ia64/include/asm/paravirt.h
@@ -22,6 +22,56 @@
#ifndef __ASM_PARAVIRT_H
#define __ASM_PARAVIRT_H
+#ifndef __ASSEMBLY__
+/******************************************************************************
+ * fsys related addresses
+ */
+struct pv_fsys_data {
+ unsigned long *fsyscall_table;
+ void *fsys_bubble_down;
+};
+
+extern struct pv_fsys_data pv_fsys_data;
+
+unsigned long *paravirt_get_fsyscall_table(void);
+char *paravirt_get_fsys_bubble_down(void);
+
+/******************************************************************************
+ * patchlist addresses for gate page
+ */
+enum pv_gate_patchlist {
+ PV_GATE_START_FSYSCALL,
+ PV_GATE_END_FSYSCALL,
+
+ PV_GATE_START_BRL_FSYS_BUBBLE_DOWN,
+ PV_GATE_END_BRL_FSYS_BUBBLE_DOWN,
+
+ PV_GATE_START_VTOP,
+ PV_GATE_END_VTOP,
+
+ PV_GATE_START_MCKINLEY_E9,
+ PV_GATE_END_MCKINLEY_E9,
+};
+
+struct pv_patchdata {
+ unsigned long start_fsyscall_patchlist;
+ unsigned long end_fsyscall_patchlist;
+ unsigned long start_brl_fsys_bubble_down_patchlist;
+ unsigned long end_brl_fsys_bubble_down_patchlist;
+ unsigned long start_vtop_patchlist;
+ unsigned long end_vtop_patchlist;
+ unsigned long start_mckinley_e9_patchlist;
+ unsigned long end_mckinley_e9_patchlist;
+
+ void *gate_section;
+};
+
+extern struct pv_patchdata pv_patchdata;
+
+unsigned long paravirt_get_gate_patchlist(enum pv_gate_patchlist type);
+void *paravirt_get_gate_section(void);
+#endif
+
#ifdef CONFIG_PARAVIRT_GUEST
#define PARAVIRT_HYPERVISOR_TYPE_DEFAULT 0
@@ -68,6 +118,14 @@ struct pv_init_ops {
int (*arch_setup_nomca)(void);
void (*post_smp_prepare_boot_cpu)(void);
+
+#ifdef ASM_SUPPORTED
+ unsigned long (*patch_bundle)(void *sbundle, void *ebundle,
+ unsigned long type);
+ unsigned long (*patch_inst)(unsigned long stag, unsigned long etag,
+ unsigned long type);
+#endif
+ void (*patch_branch)(unsigned long tag, unsigned long type);
};
extern struct pv_init_ops pv_init_ops;
@@ -210,6 +268,8 @@ struct pv_time_ops {
int (*do_steal_accounting)(unsigned long *new_itm);
void (*clocksource_resume)(void);
+
+ unsigned long long (*sched_clock)(void);
};
extern struct pv_time_ops pv_time_ops;
@@ -227,6 +287,11 @@ paravirt_do_steal_accounting(unsigned long *new_itm)
return pv_time_ops.do_steal_accounting(new_itm);
}
+static inline unsigned long long paravirt_sched_clock(void)
+{
+ return pv_time_ops.sched_clock();
+}
+
#endif /* !__ASSEMBLY__ */
#else
diff --git a/arch/ia64/include/asm/paravirt_patch.h b/arch/ia64/include/asm/paravirt_patch.h
new file mode 100644
index 000000000000..128ff5db6e67
--- /dev/null
+++ b/arch/ia64/include/asm/paravirt_patch.h
@@ -0,0 +1,143 @@
+/******************************************************************************
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_PARAVIRT_PATCH_H
+#define __ASM_PARAVIRT_PATCH_H
+
+#ifdef __ASSEMBLY__
+
+ .section .paravirt_branches, "a"
+ .previous
+#define PARAVIRT_PATCH_SITE_BR(type) \
+ { \
+ [1:] ; \
+ br.cond.sptk.many 2f ; \
+ nop.b 0 ; \
+ nop.b 0;; ; \
+ } ; \
+ 2: \
+ .xdata8 ".paravirt_branches", 1b, type
+
+#else
+
+#include <linux/stringify.h>
+#include <asm/intrinsics.h>
+
+/* for binary patch */
+struct paravirt_patch_site_bundle {
+ void *sbundle;
+ void *ebundle;
+ unsigned long type;
+};
+
+/* label means the beginning of new bundle */
+#define paravirt_alt_bundle(instr, privop) \
+ "\t998:\n" \
+ "\t" instr "\n" \
+ "\t999:\n" \
+ "\t.pushsection .paravirt_bundles, \"a\"\n" \
+ "\t.popsection\n" \
+ "\t.xdata8 \".paravirt_bundles\", 998b, 999b, " \
+ __stringify(privop) "\n"
+
+
+struct paravirt_patch_bundle_elem {
+ const void *sbundle;
+ const void *ebundle;
+ unsigned long type;
+};
+
+
+struct paravirt_patch_site_inst {
+ unsigned long stag;
+ unsigned long etag;
+ unsigned long type;
+};
+
+#define paravirt_alt_inst(instr, privop) \
+ "\t[998:]\n" \
+ "\t" instr "\n" \
+ "\t[999:]\n" \
+ "\t.pushsection .paravirt_insts, \"a\"\n" \
+ "\t.popsection\n" \
+ "\t.xdata8 \".paravirt_insts\", 998b, 999b, " \
+ __stringify(privop) "\n"
+
+struct paravirt_patch_site_branch {
+ unsigned long tag;
+ unsigned long type;
+};
+
+struct paravirt_patch_branch_target {
+ const void *entry;
+ unsigned long type;
+};
+
+void
+__paravirt_patch_apply_branch(
+ unsigned long tag, unsigned long type,
+ const struct paravirt_patch_branch_target *entries,
+ unsigned int nr_entries);
+
+void
+paravirt_patch_reloc_br(unsigned long tag, const void *target);
+
+void
+paravirt_patch_reloc_brl(unsigned long tag, const void *target);
+
+
+#if defined(ASM_SUPPORTED) && defined(CONFIG_PARAVIRT)
+unsigned long
+ia64_native_patch_bundle(void *sbundle, void *ebundle, unsigned long type);
+
+unsigned long
+__paravirt_patch_apply_bundle(void *sbundle, void *ebundle, unsigned long type,
+ const struct paravirt_patch_bundle_elem *elems,
+ unsigned long nelems,
+ const struct paravirt_patch_bundle_elem **found);
+
+void
+paravirt_patch_apply_bundle(const struct paravirt_patch_site_bundle *start,
+ const struct paravirt_patch_site_bundle *end);
+
+void
+paravirt_patch_apply_inst(const struct paravirt_patch_site_inst *start,
+ const struct paravirt_patch_site_inst *end);
+
+void paravirt_patch_apply(void);
+#else
+#define paravirt_patch_apply_bundle(start, end) do { } while (0)
+#define paravirt_patch_apply_inst(start, end) do { } while (0)
+#define paravirt_patch_apply() do { } while (0)
+#endif
+
+#endif /* !__ASSEMBLEY__ */
+
+#endif /* __ASM_PARAVIRT_PATCH_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "linux"
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ */
diff --git a/arch/ia64/include/asm/paravirt_privop.h b/arch/ia64/include/asm/paravirt_privop.h
index 33c8e55f5775..3d2951130b5f 100644
--- a/arch/ia64/include/asm/paravirt_privop.h
+++ b/arch/ia64/include/asm/paravirt_privop.h
@@ -33,7 +33,7 @@
*/
struct pv_cpu_ops {
- void (*fc)(unsigned long addr);
+ void (*fc)(void *addr);
unsigned long (*thash)(unsigned long addr);
unsigned long (*get_cpuid)(int index);
unsigned long (*get_pmd)(int index);
@@ -60,12 +60,18 @@ extern unsigned long ia64_native_getreg_func(int regnum);
/* Instructions paravirtualized for performance */
/************************************************/
+#ifndef ASM_SUPPORTED
+#define paravirt_ssm_i() pv_cpu_ops.ssm_i()
+#define paravirt_rsm_i() pv_cpu_ops.rsm_i()
+#define __paravirt_getreg() pv_cpu_ops.getreg()
+#endif
+
/* mask for ia64_native_ssm/rsm() must be constant.("i" constraing).
* static inline function doesn't satisfy it. */
#define paravirt_ssm(mask) \
do { \
if ((mask) == IA64_PSR_I) \
- pv_cpu_ops.ssm_i(); \
+ paravirt_ssm_i(); \
else \
ia64_native_ssm(mask); \
} while (0)
@@ -73,7 +79,7 @@ extern unsigned long ia64_native_getreg_func(int regnum);
#define paravirt_rsm(mask) \
do { \
if ((mask) == IA64_PSR_I) \
- pv_cpu_ops.rsm_i(); \
+ paravirt_rsm_i(); \
else \
ia64_native_rsm(mask); \
} while (0)
@@ -86,7 +92,7 @@ extern unsigned long ia64_native_getreg_func(int regnum);
if ((reg) == _IA64_REG_IP) \
res = ia64_native_getreg(_IA64_REG_IP); \
else \
- res = pv_cpu_ops.getreg(reg); \
+ res = __paravirt_getreg(reg); \
res; \
})
@@ -112,6 +118,12 @@ void paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch);
#endif /* CONFIG_PARAVIRT */
+#if defined(CONFIG_PARAVIRT) && defined(ASM_SUPPORTED)
+#define paravirt_dv_serialize_data() ia64_dv_serialize_data()
+#else
+#define paravirt_dv_serialize_data() /* nothing */
+#endif
+
/* these routines utilize privilege-sensitive or performance-sensitive
* privileged instructions so the code must be replaced with
* paravirtualized versions */
@@ -121,4 +133,349 @@ void paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch);
IA64_PARAVIRT_ASM_FUNC(work_processed_syscall)
#define ia64_leave_kernel IA64_PARAVIRT_ASM_FUNC(leave_kernel)
+
+#if defined(CONFIG_PARAVIRT)
+/******************************************************************************
+ * binary patching infrastructure
+ */
+#define PARAVIRT_PATCH_TYPE_FC 1
+#define PARAVIRT_PATCH_TYPE_THASH 2
+#define PARAVIRT_PATCH_TYPE_GET_CPUID 3
+#define PARAVIRT_PATCH_TYPE_GET_PMD 4
+#define PARAVIRT_PATCH_TYPE_PTCGA 5
+#define PARAVIRT_PATCH_TYPE_GET_RR 6
+#define PARAVIRT_PATCH_TYPE_SET_RR 7
+#define PARAVIRT_PATCH_TYPE_SET_RR0_TO_RR4 8
+#define PARAVIRT_PATCH_TYPE_SSM_I 9
+#define PARAVIRT_PATCH_TYPE_RSM_I 10
+#define PARAVIRT_PATCH_TYPE_GET_PSR_I 11
+#define PARAVIRT_PATCH_TYPE_INTRIN_LOCAL_IRQ_RESTORE 12
+
+/* PARAVIRT_PATY_TYPE_[GS]ETREG + _IA64_REG_xxx */
+#define PARAVIRT_PATCH_TYPE_GETREG 0x10000000
+#define PARAVIRT_PATCH_TYPE_SETREG 0x20000000
+
+/*
+ * struct task_struct* (*ia64_switch_to)(void* next_task);
+ * void *ia64_leave_syscall;
+ * void *ia64_work_processed_syscall
+ * void *ia64_leave_kernel;
+ */
+
+#define PARAVIRT_PATCH_TYPE_BR_START 0x30000000
+#define PARAVIRT_PATCH_TYPE_BR_SWITCH_TO \
+ (PARAVIRT_PATCH_TYPE_BR_START + 0)
+#define PARAVIRT_PATCH_TYPE_BR_LEAVE_SYSCALL \
+ (PARAVIRT_PATCH_TYPE_BR_START + 1)
+#define PARAVIRT_PATCH_TYPE_BR_WORK_PROCESSED_SYSCALL \
+ (PARAVIRT_PATCH_TYPE_BR_START + 2)
+#define PARAVIRT_PATCH_TYPE_BR_LEAVE_KERNEL \
+ (PARAVIRT_PATCH_TYPE_BR_START + 3)
+
+#ifdef ASM_SUPPORTED
+#include <asm/paravirt_patch.h>
+
+/*
+ * pv_cpu_ops calling stub.
+ * normal function call convension can't be written by gcc
+ * inline assembly.
+ *
+ * from the caller's point of view,
+ * the following registers will be clobbered.
+ * r2, r3
+ * r8-r15
+ * r16, r17
+ * b6, b7
+ * p6-p15
+ * ar.ccv
+ *
+ * from the callee's point of view ,
+ * the following registers can be used.
+ * r2, r3: scratch
+ * r8: scratch, input argument0 and return value
+ * r0-r15: scratch, input argument1-5
+ * b6: return pointer
+ * b7: scratch
+ * p6-p15: scratch
+ * ar.ccv: scratch
+ *
+ * other registers must not be changed. especially
+ * b0: rp: preserved. gcc ignores b0 in clobbered register.
+ * r16: saved gp
+ */
+/* 5 bundles */
+#define __PARAVIRT_BR \
+ ";;\n" \
+ "{ .mlx\n" \
+ "nop 0\n" \
+ "movl r2 = %[op_addr]\n"/* get function pointer address */ \
+ ";;\n" \
+ "}\n" \
+ "1:\n" \
+ "{ .mii\n" \
+ "ld8 r2 = [r2]\n" /* load function descriptor address */ \
+ "mov r17 = ip\n" /* get ip to calc return address */ \
+ "mov r16 = gp\n" /* save gp */ \
+ ";;\n" \
+ "}\n" \
+ "{ .mii\n" \
+ "ld8 r3 = [r2], 8\n" /* load entry address */ \
+ "adds r17 = 1f - 1b, r17\n" /* calculate return address */ \
+ ";;\n" \
+ "mov b7 = r3\n" /* set entry address */ \
+ "}\n" \
+ "{ .mib\n" \
+ "ld8 gp = [r2]\n" /* load gp value */ \
+ "mov b6 = r17\n" /* set return address */ \
+ "br.cond.sptk.few b7\n" /* intrinsics are very short isns */ \
+ "}\n" \
+ "1:\n" \
+ "{ .mii\n" \
+ "mov gp = r16\n" /* restore gp value */ \
+ "nop 0\n" \
+ "nop 0\n" \
+ ";;\n" \
+ "}\n"
+
+#define PARAVIRT_OP(op) \
+ [op_addr] "i"(&pv_cpu_ops.op)
+
+#define PARAVIRT_TYPE(type) \
+ PARAVIRT_PATCH_TYPE_ ## type
+
+#define PARAVIRT_REG_CLOBBERS0 \
+ "r2", "r3", /*"r8",*/ "r9", "r10", "r11", "r14", \
+ "r15", "r16", "r17"
+
+#define PARAVIRT_REG_CLOBBERS1 \
+ "r2","r3", /*"r8",*/ "r9", "r10", "r11", "r14", \
+ "r15", "r16", "r17"
+
+#define PARAVIRT_REG_CLOBBERS2 \
+ "r2", "r3", /*"r8", "r9",*/ "r10", "r11", "r14", \
+ "r15", "r16", "r17"
+
+#define PARAVIRT_REG_CLOBBERS5 \
+ "r2", "r3", /*"r8", "r9", "r10", "r11", "r14",*/ \
+ "r15", "r16", "r17"
+
+#define PARAVIRT_BR_CLOBBERS \
+ "b6", "b7"
+
+#define PARAVIRT_PR_CLOBBERS \
+ "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15"
+
+#define PARAVIRT_AR_CLOBBERS \
+ "ar.ccv"
+
+#define PARAVIRT_CLOBBERS0 \
+ PARAVIRT_REG_CLOBBERS0, \
+ PARAVIRT_BR_CLOBBERS, \
+ PARAVIRT_PR_CLOBBERS, \
+ PARAVIRT_AR_CLOBBERS, \
+ "memory"
+
+#define PARAVIRT_CLOBBERS1 \
+ PARAVIRT_REG_CLOBBERS1, \
+ PARAVIRT_BR_CLOBBERS, \
+ PARAVIRT_PR_CLOBBERS, \
+ PARAVIRT_AR_CLOBBERS, \
+ "memory"
+
+#define PARAVIRT_CLOBBERS2 \
+ PARAVIRT_REG_CLOBBERS2, \
+ PARAVIRT_BR_CLOBBERS, \
+ PARAVIRT_PR_CLOBBERS, \
+ PARAVIRT_AR_CLOBBERS, \
+ "memory"
+
+#define PARAVIRT_CLOBBERS5 \
+ PARAVIRT_REG_CLOBBERS5, \
+ PARAVIRT_BR_CLOBBERS, \
+ PARAVIRT_PR_CLOBBERS, \
+ PARAVIRT_AR_CLOBBERS, \
+ "memory"
+
+#define PARAVIRT_BR0(op, type) \
+ register unsigned long ia64_clobber asm ("r8"); \
+ asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
+ PARAVIRT_TYPE(type)) \
+ : "=r"(ia64_clobber) \
+ : PARAVIRT_OP(op) \
+ : PARAVIRT_CLOBBERS0)
+
+#define PARAVIRT_BR0_RET(op, type) \
+ register unsigned long ia64_intri_res asm ("r8"); \
+ asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
+ PARAVIRT_TYPE(type)) \
+ : "=r"(ia64_intri_res) \
+ : PARAVIRT_OP(op) \
+ : PARAVIRT_CLOBBERS0)
+
+#define PARAVIRT_BR1(op, type, arg1) \
+ register unsigned long __##arg1 asm ("r8") = arg1; \
+ register unsigned long ia64_clobber asm ("r8"); \
+ asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
+ PARAVIRT_TYPE(type)) \
+ : "=r"(ia64_clobber) \
+ : PARAVIRT_OP(op), "0"(__##arg1) \
+ : PARAVIRT_CLOBBERS1)
+
+#define PARAVIRT_BR1_RET(op, type, arg1) \
+ register unsigned long ia64_intri_res asm ("r8"); \
+ register unsigned long __##arg1 asm ("r8") = arg1; \
+ asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
+ PARAVIRT_TYPE(type)) \
+ : "=r"(ia64_intri_res) \
+ : PARAVIRT_OP(op), "0"(__##arg1) \
+ : PARAVIRT_CLOBBERS1)
+
+#define PARAVIRT_BR1_VOID(op, type, arg1) \
+ register void *__##arg1 asm ("r8") = arg1; \
+ register unsigned long ia64_clobber asm ("r8"); \
+ asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
+ PARAVIRT_TYPE(type)) \
+ : "=r"(ia64_clobber) \
+ : PARAVIRT_OP(op), "0"(__##arg1) \
+ : PARAVIRT_CLOBBERS1)
+
+#define PARAVIRT_BR2(op, type, arg1, arg2) \
+ register unsigned long __##arg1 asm ("r8") = arg1; \
+ register unsigned long __##arg2 asm ("r9") = arg2; \
+ register unsigned long ia64_clobber1 asm ("r8"); \
+ register unsigned long ia64_clobber2 asm ("r9"); \
+ asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
+ PARAVIRT_TYPE(type)) \
+ : "=r"(ia64_clobber1), "=r"(ia64_clobber2) \
+ : PARAVIRT_OP(op), "0"(__##arg1), "1"(__##arg2) \
+ : PARAVIRT_CLOBBERS2)
+
+
+#define PARAVIRT_DEFINE_CPU_OP0(op, type) \
+ static inline void \
+ paravirt_ ## op (void) \
+ { \
+ PARAVIRT_BR0(op, type); \
+ }
+
+#define PARAVIRT_DEFINE_CPU_OP0_RET(op, type) \
+ static inline unsigned long \
+ paravirt_ ## op (void) \
+ { \
+ PARAVIRT_BR0_RET(op, type); \
+ return ia64_intri_res; \
+ }
+
+#define PARAVIRT_DEFINE_CPU_OP1_VOID(op, type) \
+ static inline void \
+ paravirt_ ## op (void *arg1) \
+ { \
+ PARAVIRT_BR1_VOID(op, type, arg1); \
+ }
+
+#define PARAVIRT_DEFINE_CPU_OP1(op, type) \
+ static inline void \
+ paravirt_ ## op (unsigned long arg1) \
+ { \
+ PARAVIRT_BR1(op, type, arg1); \
+ }
+
+#define PARAVIRT_DEFINE_CPU_OP1_RET(op, type) \
+ static inline unsigned long \
+ paravirt_ ## op (unsigned long arg1) \
+ { \
+ PARAVIRT_BR1_RET(op, type, arg1); \
+ return ia64_intri_res; \
+ }
+
+#define PARAVIRT_DEFINE_CPU_OP2(op, type) \
+ static inline void \
+ paravirt_ ## op (unsigned long arg1, \
+ unsigned long arg2) \
+ { \
+ PARAVIRT_BR2(op, type, arg1, arg2); \
+ }
+
+
+PARAVIRT_DEFINE_CPU_OP1_VOID(fc, FC);
+PARAVIRT_DEFINE_CPU_OP1_RET(thash, THASH)
+PARAVIRT_DEFINE_CPU_OP1_RET(get_cpuid, GET_CPUID)
+PARAVIRT_DEFINE_CPU_OP1_RET(get_pmd, GET_PMD)
+PARAVIRT_DEFINE_CPU_OP2(ptcga, PTCGA)
+PARAVIRT_DEFINE_CPU_OP1_RET(get_rr, GET_RR)
+PARAVIRT_DEFINE_CPU_OP2(set_rr, SET_RR)
+PARAVIRT_DEFINE_CPU_OP0(ssm_i, SSM_I)
+PARAVIRT_DEFINE_CPU_OP0(rsm_i, RSM_I)
+PARAVIRT_DEFINE_CPU_OP0_RET(get_psr_i, GET_PSR_I)
+PARAVIRT_DEFINE_CPU_OP1(intrin_local_irq_restore, INTRIN_LOCAL_IRQ_RESTORE)
+
+static inline void
+paravirt_set_rr0_to_rr4(unsigned long val0, unsigned long val1,
+ unsigned long val2, unsigned long val3,
+ unsigned long val4)
+{
+ register unsigned long __val0 asm ("r8") = val0;
+ register unsigned long __val1 asm ("r9") = val1;
+ register unsigned long __val2 asm ("r10") = val2;
+ register unsigned long __val3 asm ("r11") = val3;
+ register unsigned long __val4 asm ("r14") = val4;
+
+ register unsigned long ia64_clobber0 asm ("r8");
+ register unsigned long ia64_clobber1 asm ("r9");
+ register unsigned long ia64_clobber2 asm ("r10");
+ register unsigned long ia64_clobber3 asm ("r11");
+ register unsigned long ia64_clobber4 asm ("r14");
+
+ asm volatile (paravirt_alt_bundle(__PARAVIRT_BR,
+ PARAVIRT_TYPE(SET_RR0_TO_RR4))
+ : "=r"(ia64_clobber0),
+ "=r"(ia64_clobber1),
+ "=r"(ia64_clobber2),
+ "=r"(ia64_clobber3),
+ "=r"(ia64_clobber4)
+ : PARAVIRT_OP(set_rr0_to_rr4),
+ "0"(__val0), "1"(__val1), "2"(__val2),
+ "3"(__val3), "4"(__val4)
+ : PARAVIRT_CLOBBERS5);
+}
+
+/* unsigned long paravirt_getreg(int reg) */
+#define __paravirt_getreg(reg) \
+ ({ \
+ register unsigned long ia64_intri_res asm ("r8"); \
+ register unsigned long __reg asm ("r8") = (reg); \
+ \
+ BUILD_BUG_ON(!__builtin_constant_p(reg)); \
+ asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
+ PARAVIRT_TYPE(GETREG) \
+ + (reg)) \
+ : "=r"(ia64_intri_res) \
+ : PARAVIRT_OP(getreg), "0"(__reg) \
+ : PARAVIRT_CLOBBERS1); \
+ \
+ ia64_intri_res; \
+ })
+
+/* void paravirt_setreg(int reg, unsigned long val) */
+#define paravirt_setreg(reg, val) \
+ do { \
+ register unsigned long __val asm ("r8") = val; \
+ register unsigned long __reg asm ("r9") = reg; \
+ register unsigned long ia64_clobber1 asm ("r8"); \
+ register unsigned long ia64_clobber2 asm ("r9"); \
+ \
+ BUILD_BUG_ON(!__builtin_constant_p(reg)); \
+ asm volatile (paravirt_alt_bundle(__PARAVIRT_BR, \
+ PARAVIRT_TYPE(SETREG) \
+ + (reg)) \
+ : "=r"(ia64_clobber1), \
+ "=r"(ia64_clobber2) \
+ : PARAVIRT_OP(setreg), \
+ "1"(__reg), "0"(__val) \
+ : PARAVIRT_CLOBBERS2); \
+ } while (0)
+
+#endif /* ASM_SUPPORTED */
+#endif /* CONFIG_PARAVIRT && ASM_SUPPOTED */
+
#endif /* _ASM_IA64_PARAVIRT_PRIVOP_H */
diff --git a/arch/ia64/include/asm/smp.h b/arch/ia64/include/asm/smp.h
index 21c402365d0e..598408336251 100644
--- a/arch/ia64/include/asm/smp.h
+++ b/arch/ia64/include/asm/smp.h
@@ -126,7 +126,8 @@ extern void identify_siblings (struct cpuinfo_ia64 *);
extern int is_multithreading_enabled(void);
extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi(cpumask_t mask);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
#else /* CONFIG_SMP */
diff --git a/arch/ia64/include/asm/socket.h b/arch/ia64/include/asm/socket.h
index d5ef0aa3e312..745421225ec6 100644
--- a/arch/ia64/include/asm/socket.h
+++ b/arch/ia64/include/asm/socket.h
@@ -63,4 +63,7 @@
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
#endif /* _ASM_IA64_SOCKET_H */
diff --git a/arch/ia64/include/asm/spinlock.h b/arch/ia64/include/asm/spinlock.h
index 0229fb95fb38..13ab71576bc7 100644
--- a/arch/ia64/include/asm/spinlock.h
+++ b/arch/ia64/include/asm/spinlock.h
@@ -120,6 +120,38 @@ do { \
#define __raw_read_can_lock(rw) (*(volatile int *)(rw) >= 0)
#define __raw_write_can_lock(rw) (*(volatile int *)(rw) == 0)
+#ifdef ASM_SUPPORTED
+
+static __always_inline void
+__raw_read_lock_flags(raw_rwlock_t *lock, unsigned long flags)
+{
+ __asm__ __volatile__ (
+ "tbit.nz p6, p0 = %1,%2\n"
+ "br.few 3f\n"
+ "1:\n"
+ "fetchadd4.rel r2 = [%0], -1;;\n"
+ "(p6) ssm psr.i\n"
+ "2:\n"
+ "hint @pause\n"
+ "ld4 r2 = [%0];;\n"
+ "cmp4.lt p7,p0 = r2, r0\n"
+ "(p7) br.cond.spnt.few 2b\n"
+ "(p6) rsm psr.i\n"
+ ";;\n"
+ "3:\n"
+ "fetchadd4.acq r2 = [%0], 1;;\n"
+ "cmp4.lt p7,p0 = r2, r0\n"
+ "(p7) br.cond.spnt.few 1b\n"
+ : : "r"(lock), "r"(flags), "i"(IA64_PSR_I_BIT)
+ : "p6", "p7", "r2", "memory");
+}
+
+#define __raw_read_lock(lock) __raw_read_lock_flags(lock, 0)
+
+#else /* !ASM_SUPPORTED */
+
+#define __raw_read_lock_flags(rw, flags) __raw_read_lock(rw)
+
#define __raw_read_lock(rw) \
do { \
raw_rwlock_t *__read_lock_ptr = (rw); \
@@ -131,6 +163,8 @@ do { \
} \
} while (0)
+#endif /* !ASM_SUPPORTED */
+
#define __raw_read_unlock(rw) \
do { \
raw_rwlock_t *__read_lock_ptr = (rw); \
@@ -138,20 +172,33 @@ do { \
} while (0)
#ifdef ASM_SUPPORTED
-#define __raw_write_lock(rw) \
-do { \
- __asm__ __volatile__ ( \
- "mov ar.ccv = r0\n" \
- "dep r29 = -1, r0, 31, 1;;\n" \
- "1:\n" \
- "ld4 r2 = [%0];;\n" \
- "cmp4.eq p0,p7 = r0,r2\n" \
- "(p7) br.cond.spnt.few 1b \n" \
- "cmpxchg4.acq r2 = [%0], r29, ar.ccv;;\n" \
- "cmp4.eq p0,p7 = r0, r2\n" \
- "(p7) br.cond.spnt.few 1b;;\n" \
- :: "r"(rw) : "ar.ccv", "p7", "r2", "r29", "memory"); \
-} while(0)
+
+static __always_inline void
+__raw_write_lock_flags(raw_rwlock_t *lock, unsigned long flags)
+{
+ __asm__ __volatile__ (
+ "tbit.nz p6, p0 = %1, %2\n"
+ "mov ar.ccv = r0\n"
+ "dep r29 = -1, r0, 31, 1\n"
+ "br.few 3f;;\n"
+ "1:\n"
+ "(p6) ssm psr.i\n"
+ "2:\n"
+ "hint @pause\n"
+ "ld4 r2 = [%0];;\n"
+ "cmp4.eq p0,p7 = r0, r2\n"
+ "(p7) br.cond.spnt.few 2b\n"
+ "(p6) rsm psr.i\n"
+ ";;\n"
+ "3:\n"
+ "cmpxchg4.acq r2 = [%0], r29, ar.ccv;;\n"
+ "cmp4.eq p0,p7 = r0, r2\n"
+ "(p7) br.cond.spnt.few 1b;;\n"
+ : : "r"(lock), "r"(flags), "i"(IA64_PSR_I_BIT)
+ : "ar.ccv", "p6", "p7", "r2", "r29", "memory");
+}
+
+#define __raw_write_lock(rw) __raw_write_lock_flags(rw, 0)
#define __raw_write_trylock(rw) \
({ \
@@ -174,6 +221,8 @@ static inline void __raw_write_unlock(raw_rwlock_t *x)
#else /* !ASM_SUPPORTED */
+#define __raw_write_lock_flags(l, flags) __raw_write_lock(l)
+
#define __raw_write_lock(l) \
({ \
__u64 ia64_val, ia64_set_val = ia64_dep_mi(-1, 0, 31, 1); \
diff --git a/arch/ia64/include/asm/timex.h b/arch/ia64/include/asm/timex.h
index 4e03cfe74a0c..86c7db861180 100644
--- a/arch/ia64/include/asm/timex.h
+++ b/arch/ia64/include/asm/timex.h
@@ -40,5 +40,6 @@ get_cycles (void)
}
extern void ia64_cpu_local_tick (void);
+extern unsigned long long ia64_native_sched_clock (void);
#endif /* _ASM_IA64_TIMEX_H */
diff --git a/arch/ia64/include/asm/topology.h b/arch/ia64/include/asm/topology.h
index 3193f4417e16..7b4c8c70b2d1 100644
--- a/arch/ia64/include/asm/topology.h
+++ b/arch/ia64/include/asm/topology.h
@@ -44,11 +44,6 @@
#define parent_node(nid) (nid)
/*
- * Returns the number of the first CPU on Node 'node'.
- */
-#define node_to_first_cpu(node) (cpumask_first(cpumask_of_node(node)))
-
-/*
* Determines the node for a given pci bus
*/
#define pcibus_to_node(bus) PCI_CONTROLLER(bus)->node
@@ -117,11 +112,6 @@ void build_cpu_to_node_map(void);
extern void arch_fix_phys_package_id(int num, u32 slot);
-#define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \
- CPU_MASK_ALL : \
- node_to_cpumask(pcibus_to_node(bus)) \
- )
-
#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \
cpu_all_mask : \
cpumask_of_node(pcibus_to_node(bus)))
diff --git a/arch/ia64/include/asm/uv/uv_hub.h b/arch/ia64/include/asm/uv/uv_hub.h
index f607018af4a1..53e9dfacd073 100644
--- a/arch/ia64/include/asm/uv/uv_hub.h
+++ b/arch/ia64/include/asm/uv/uv_hub.h
@@ -305,5 +305,11 @@ static inline int uv_num_possible_blades(void)
return 1;
}
+static inline void uv_hub_send_ipi(int pnode, int apicid, int vector)
+{
+ /* not currently needed on ia64 */
+}
+
+
#endif /* __ASM_IA64_UV_HUB__ */
diff --git a/arch/ia64/include/asm/uv/uv_mmrs.h b/arch/ia64/include/asm/uv/uv_mmrs.h
index c149ef085437..fe0b8f05e1a8 100644
--- a/arch/ia64/include/asm/uv/uv_mmrs.h
+++ b/arch/ia64/include/asm/uv/uv_mmrs.h
@@ -8,8 +8,8 @@
* Copyright (C) 2007-2008 Silicon Graphics, Inc. All rights reserved.
*/
-#ifndef __ASM_IA64_UV_MMRS__
-#define __ASM_IA64_UV_MMRS__
+#ifndef _ASM_IA64_UV_UV_MMRS_H
+#define _ASM_IA64_UV_UV_MMRS_H
#define UV_MMR_ENABLE (1UL << 63)
@@ -243,6 +243,158 @@ union uvh_event_occurred0_u {
#define UVH_EVENT_OCCURRED0_ALIAS_32 0x005f0
/* ========================================================================= */
+/* UVH_GR0_TLB_INT0_CONFIG */
+/* ========================================================================= */
+#define UVH_GR0_TLB_INT0_CONFIG 0x61b00UL
+
+#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_SHFT 0
+#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR0_TLB_INT0_CONFIG_DM_SHFT 8
+#define UVH_GR0_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR0_TLB_INT0_CONFIG_STATUS_SHFT 12
+#define UVH_GR0_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR0_TLB_INT0_CONFIG_P_SHFT 13
+#define UVH_GR0_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR0_TLB_INT0_CONFIG_T_SHFT 15
+#define UVH_GR0_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR0_TLB_INT0_CONFIG_M_SHFT 16
+#define UVH_GR0_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr0_tlb_int0_config_u {
+ unsigned long v;
+ struct uvh_gr0_tlb_int0_config_s {
+ unsigned long vector_ : 8; /* RW */
+ unsigned long dm : 3; /* RW */
+ unsigned long destmode : 1; /* RW */
+ unsigned long status : 1; /* RO */
+ unsigned long p : 1; /* RO */
+ unsigned long rsvd_14 : 1; /* */
+ unsigned long t : 1; /* RO */
+ unsigned long m : 1; /* RW */
+ unsigned long rsvd_17_31: 15; /* */
+ unsigned long apic_id : 32; /* RW */
+ } s;
+};
+
+/* ========================================================================= */
+/* UVH_GR0_TLB_INT1_CONFIG */
+/* ========================================================================= */
+#define UVH_GR0_TLB_INT1_CONFIG 0x61b40UL
+
+#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_SHFT 0
+#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR0_TLB_INT1_CONFIG_DM_SHFT 8
+#define UVH_GR0_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR0_TLB_INT1_CONFIG_STATUS_SHFT 12
+#define UVH_GR0_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR0_TLB_INT1_CONFIG_P_SHFT 13
+#define UVH_GR0_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR0_TLB_INT1_CONFIG_T_SHFT 15
+#define UVH_GR0_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR0_TLB_INT1_CONFIG_M_SHFT 16
+#define UVH_GR0_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr0_tlb_int1_config_u {
+ unsigned long v;
+ struct uvh_gr0_tlb_int1_config_s {
+ unsigned long vector_ : 8; /* RW */
+ unsigned long dm : 3; /* RW */
+ unsigned long destmode : 1; /* RW */
+ unsigned long status : 1; /* RO */
+ unsigned long p : 1; /* RO */
+ unsigned long rsvd_14 : 1; /* */
+ unsigned long t : 1; /* RO */
+ unsigned long m : 1; /* RW */
+ unsigned long rsvd_17_31: 15; /* */
+ unsigned long apic_id : 32; /* RW */
+ } s;
+};
+
+/* ========================================================================= */
+/* UVH_GR1_TLB_INT0_CONFIG */
+/* ========================================================================= */
+#define UVH_GR1_TLB_INT0_CONFIG 0x61f00UL
+
+#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_SHFT 0
+#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR1_TLB_INT0_CONFIG_DM_SHFT 8
+#define UVH_GR1_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR1_TLB_INT0_CONFIG_STATUS_SHFT 12
+#define UVH_GR1_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR1_TLB_INT0_CONFIG_P_SHFT 13
+#define UVH_GR1_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR1_TLB_INT0_CONFIG_T_SHFT 15
+#define UVH_GR1_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR1_TLB_INT0_CONFIG_M_SHFT 16
+#define UVH_GR1_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr1_tlb_int0_config_u {
+ unsigned long v;
+ struct uvh_gr1_tlb_int0_config_s {
+ unsigned long vector_ : 8; /* RW */
+ unsigned long dm : 3; /* RW */
+ unsigned long destmode : 1; /* RW */
+ unsigned long status : 1; /* RO */
+ unsigned long p : 1; /* RO */
+ unsigned long rsvd_14 : 1; /* */
+ unsigned long t : 1; /* RO */
+ unsigned long m : 1; /* RW */
+ unsigned long rsvd_17_31: 15; /* */
+ unsigned long apic_id : 32; /* RW */
+ } s;
+};
+
+/* ========================================================================= */
+/* UVH_GR1_TLB_INT1_CONFIG */
+/* ========================================================================= */
+#define UVH_GR1_TLB_INT1_CONFIG 0x61f40UL
+
+#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_SHFT 0
+#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR1_TLB_INT1_CONFIG_DM_SHFT 8
+#define UVH_GR1_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR1_TLB_INT1_CONFIG_STATUS_SHFT 12
+#define UVH_GR1_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR1_TLB_INT1_CONFIG_P_SHFT 13
+#define UVH_GR1_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR1_TLB_INT1_CONFIG_T_SHFT 15
+#define UVH_GR1_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR1_TLB_INT1_CONFIG_M_SHFT 16
+#define UVH_GR1_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr1_tlb_int1_config_u {
+ unsigned long v;
+ struct uvh_gr1_tlb_int1_config_s {
+ unsigned long vector_ : 8; /* RW */
+ unsigned long dm : 3; /* RW */
+ unsigned long destmode : 1; /* RW */
+ unsigned long status : 1; /* RO */
+ unsigned long p : 1; /* RO */
+ unsigned long rsvd_14 : 1; /* */
+ unsigned long t : 1; /* RO */
+ unsigned long m : 1; /* RW */
+ unsigned long rsvd_17_31: 15; /* */
+ unsigned long apic_id : 32; /* RW */
+ } s;
+};
+
+/* ========================================================================= */
/* UVH_INT_CMPB */
/* ========================================================================= */
#define UVH_INT_CMPB 0x22080UL
@@ -670,4 +822,4 @@ union uvh_si_alias2_overlay_config_u {
};
-#endif /* __ASM_IA64_UV_MMRS__ */
+#endif /* _ASM_IA64_UV_UV_MMRS_H */
diff --git a/arch/ia64/include/asm/xen/hypervisor.h b/arch/ia64/include/asm/xen/hypervisor.h
index 7a804e80fc67..e425227a418e 100644
--- a/arch/ia64/include/asm/xen/hypervisor.h
+++ b/arch/ia64/include/asm/xen/hypervisor.h
@@ -33,9 +33,6 @@
#ifndef _ASM_IA64_XEN_HYPERVISOR_H
#define _ASM_IA64_XEN_HYPERVISOR_H
-#ifdef CONFIG_XEN
-
-#include <linux/init.h>
#include <xen/interface/xen.h>
#include <xen/interface/version.h> /* to compile feature.c */
#include <xen/features.h> /* to comiple xen-netfront.c */
@@ -43,22 +40,32 @@
/* xen_domain_type is set before executing any C code by early_xen_setup */
enum xen_domain_type {
- XEN_NATIVE,
- XEN_PV_DOMAIN,
- XEN_HVM_DOMAIN,
+ XEN_NATIVE, /* running on bare hardware */
+ XEN_PV_DOMAIN, /* running in a PV domain */
+ XEN_HVM_DOMAIN, /* running in a Xen hvm domain*/
};
+#ifdef CONFIG_XEN
extern enum xen_domain_type xen_domain_type;
+#else
+#define xen_domain_type XEN_NATIVE
+#endif
#define xen_domain() (xen_domain_type != XEN_NATIVE)
-#define xen_pv_domain() (xen_domain_type == XEN_PV_DOMAIN)
-#define xen_initial_domain() (xen_pv_domain() && \
+#define xen_pv_domain() (xen_domain() && \
+ xen_domain_type == XEN_PV_DOMAIN)
+#define xen_hvm_domain() (xen_domain() && \
+ xen_domain_type == XEN_HVM_DOMAIN)
+
+#ifdef CONFIG_XEN_DOM0
+#define xen_initial_domain() (xen_pv_domain() && \
(xen_start_info->flags & SIF_INITDOMAIN))
-#define xen_hvm_domain() (xen_domain_type == XEN_HVM_DOMAIN)
+#else
+#define xen_initial_domain() (0)
+#endif
-/* deprecated. remove this */
-#define is_running_on_xen() (xen_domain_type == XEN_PV_DOMAIN)
+#ifdef CONFIG_XEN
extern struct shared_info *HYPERVISOR_shared_info;
extern struct start_info *xen_start_info;
@@ -74,16 +81,6 @@ void force_evtchn_callback(void);
/* For setup_arch() in arch/ia64/kernel/setup.c */
void xen_ia64_enable_opt_feature(void);
-
-#else /* CONFIG_XEN */
-
-#define xen_domain() (0)
-#define xen_pv_domain() (0)
-#define xen_initial_domain() (0)
-#define xen_hvm_domain() (0)
-#define is_running_on_xen() (0) /* deprecated. remove this */
#endif
-#define is_initial_xendomain() (0) /* deprecated. remove this */
-
#endif /* _ASM_IA64_XEN_HYPERVISOR_H */
diff --git a/arch/ia64/include/asm/xen/inst.h b/arch/ia64/include/asm/xen/inst.h
index 19c2ae1d878a..c53a47611208 100644
--- a/arch/ia64/include/asm/xen/inst.h
+++ b/arch/ia64/include/asm/xen/inst.h
@@ -33,6 +33,9 @@
#define __paravirt_work_processed_syscall_target \
xen_work_processed_syscall
+#define paravirt_fsyscall_table xen_fsyscall_table
+#define paravirt_fsys_bubble_down xen_fsys_bubble_down
+
#define MOV_FROM_IFA(reg) \
movl reg = XSI_IFA; \
;; \
@@ -110,6 +113,27 @@
.endm
#define MOV_FROM_PSR(pred, reg, clob) __MOV_FROM_PSR pred, reg, clob
+/* assuming ar.itc is read with interrupt disabled. */
+#define MOV_FROM_ITC(pred, pred_clob, reg, clob) \
+(pred) movl clob = XSI_ITC_OFFSET; \
+ ;; \
+(pred) ld8 clob = [clob]; \
+(pred) mov reg = ar.itc; \
+ ;; \
+(pred) add reg = reg, clob; \
+ ;; \
+(pred) movl clob = XSI_ITC_LAST; \
+ ;; \
+(pred) ld8 clob = [clob]; \
+ ;; \
+(pred) cmp.geu.unc pred_clob, p0 = clob, reg; \
+ ;; \
+(pred_clob) add reg = 1, clob; \
+ ;; \
+(pred) movl clob = XSI_ITC_LAST; \
+ ;; \
+(pred) st8 [clob] = reg
+
#define MOV_TO_IFA(reg, clob) \
movl clob = XSI_IFA; \
@@ -362,6 +386,10 @@
#define RSM_PSR_DT \
XEN_HYPER_RSM_PSR_DT
+#define RSM_PSR_BE_I(clob0, clob1) \
+ RSM_PSR_I(p0, clob0, clob1); \
+ rum psr.be
+
#define SSM_PSR_DT_AND_SRLZ_I \
XEN_HYPER_SSM_PSR_DT
diff --git a/arch/ia64/include/asm/xen/interface.h b/arch/ia64/include/asm/xen/interface.h
index f00fab40854d..e951e740bdf2 100644
--- a/arch/ia64/include/asm/xen/interface.h
+++ b/arch/ia64/include/asm/xen/interface.h
@@ -209,6 +209,15 @@ struct mapped_regs {
unsigned long krs[8]; /* kernel registers */
unsigned long tmp[16]; /* temp registers
(e.g. for hyperprivops) */
+
+ /* itc paravirtualization
+ * vAR.ITC = mAR.ITC + itc_offset
+ * itc_last is one which was lastly passed to
+ * the guest OS in order to prevent it from
+ * going backwords.
+ */
+ unsigned long itc_offset;
+ unsigned long itc_last;
};
};
};
diff --git a/arch/ia64/include/asm/xen/minstate.h b/arch/ia64/include/asm/xen/minstate.h
index 4d92d9bbda7b..c57fa910f2c9 100644
--- a/arch/ia64/include/asm/xen/minstate.h
+++ b/arch/ia64/include/asm/xen/minstate.h
@@ -1,3 +1,12 @@
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+/* read ar.itc in advance, and use it before leaving bank 0 */
+#define XEN_ACCOUNT_GET_STAMP \
+ MOV_FROM_ITC(pUStk, p6, r20, r2);
+#else
+#define XEN_ACCOUNT_GET_STAMP
+#endif
+
/*
* DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
* the minimum state necessary that allows us to turn psr.ic back
@@ -123,7 +132,7 @@
;; \
.mem.offset 0,0; st8.spill [r16]=r2,16; \
.mem.offset 8,0; st8.spill [r17]=r3,16; \
- ACCOUNT_GET_STAMP \
+ XEN_ACCOUNT_GET_STAMP \
adds r2=IA64_PT_REGS_R16_OFFSET,r1; \
;; \
EXTRA; \
diff --git a/arch/ia64/include/asm/xen/patchlist.h b/arch/ia64/include/asm/xen/patchlist.h
new file mode 100644
index 000000000000..eae944e88846
--- /dev/null
+++ b/arch/ia64/include/asm/xen/patchlist.h
@@ -0,0 +1,38 @@
+/******************************************************************************
+ * arch/ia64/include/asm/xen/patchlist.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#define __paravirt_start_gate_fsyscall_patchlist \
+ __xen_start_gate_fsyscall_patchlist
+#define __paravirt_end_gate_fsyscall_patchlist \
+ __xen_end_gate_fsyscall_patchlist
+#define __paravirt_start_gate_brl_fsys_bubble_down_patchlist \
+ __xen_start_gate_brl_fsys_bubble_down_patchlist
+#define __paravirt_end_gate_brl_fsys_bubble_down_patchlist \
+ __xen_end_gate_brl_fsys_bubble_down_patchlist
+#define __paravirt_start_gate_vtop_patchlist \
+ __xen_start_gate_vtop_patchlist
+#define __paravirt_end_gate_vtop_patchlist \
+ __xen_end_gate_vtop_patchlist
+#define __paravirt_start_gate_mckinley_e9_patchlist \
+ __xen_start_gate_mckinley_e9_patchlist
+#define __paravirt_end_gate_mckinley_e9_patchlist \
+ __xen_end_gate_mckinley_e9_patchlist
diff --git a/arch/ia64/include/asm/xen/privop.h b/arch/ia64/include/asm/xen/privop.h
index 71ec7546e100..fb4ec5e0b066 100644
--- a/arch/ia64/include/asm/xen/privop.h
+++ b/arch/ia64/include/asm/xen/privop.h
@@ -55,6 +55,8 @@
#define XSI_BANK1_R16 (XSI_BASE + XSI_BANK1_R16_OFS)
#define XSI_BANKNUM (XSI_BASE + XSI_BANKNUM_OFS)
#define XSI_IHA (XSI_BASE + XSI_IHA_OFS)
+#define XSI_ITC_OFFSET (XSI_BASE + XSI_ITC_OFFSET_OFS)
+#define XSI_ITC_LAST (XSI_BASE + XSI_ITC_LAST_OFS)
#endif
#ifndef __ASSEMBLY__
@@ -67,7 +69,7 @@
* may have different semantics depending on whether they are executed
* at PL0 vs PL!=0. When paravirtualized, these instructions mustn't
* be allowed to execute directly, lest incorrect semantics result. */
-extern void xen_fc(unsigned long addr);
+extern void xen_fc(void *addr);
extern unsigned long xen_thash(unsigned long addr);
/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
@@ -80,8 +82,10 @@ extern unsigned long xen_thash(unsigned long addr);
extern unsigned long xen_get_cpuid(int index);
extern unsigned long xen_get_pmd(int index);
+#ifndef ASM_SUPPORTED
extern unsigned long xen_get_eflag(void); /* see xen_ia64_getreg */
extern void xen_set_eflag(unsigned long); /* see xen_ia64_setreg */
+#endif
/************************************************/
/* Instructions paravirtualized for performance */
@@ -106,6 +110,7 @@ extern void xen_set_eflag(unsigned long); /* see xen_ia64_setreg */
#define xen_get_virtual_pend() \
(*(((uint8_t *)XEN_MAPPEDREGS->interrupt_mask_addr) - 1))
+#ifndef ASM_SUPPORTED
/* Although all privileged operations can be left to trap and will
* be properly handled by Xen, some are frequent enough that we use
* hyperprivops for performance. */
@@ -123,6 +128,7 @@ extern void xen_set_rr0_to_rr4(unsigned long val0, unsigned long val1,
unsigned long val4);
extern void xen_set_kr(unsigned long index, unsigned long val);
extern void xen_ptcga(unsigned long addr, unsigned long size);
+#endif /* !ASM_SUPPORTED */
#endif /* !__ASSEMBLY__ */
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index ab6e7ec0bba3..6b7edcab0cb5 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -9,9 +9,9 @@ endif
extra-y := head.o init_task.o vmlinux.lds
obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \
- irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \
+ irq_lsapic.o ivt.o machvec.o pal.o paravirt_patchlist.o patch.o process.o perfmon.o ptrace.o sal.o \
salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
- unwind.o mca.o mca_asm.o topology.o
+ unwind.o mca.o mca_asm.o topology.o dma-mapping.o
obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o
obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o
@@ -41,46 +41,23 @@ obj-$(CONFIG_PCI_MSI) += msi_ia64.o
mca_recovery-y += mca_drv.o mca_drv_asm.o
obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
-obj-$(CONFIG_PARAVIRT) += paravirt.o paravirtentry.o
+obj-$(CONFIG_PARAVIRT) += paravirt.o paravirtentry.o \
+ paravirt_patch.o
obj-$(CONFIG_IA64_ESI) += esi.o
ifneq ($(CONFIG_IA64_ESI),)
obj-y += esi_stub.o # must be in kernel proper
endif
obj-$(CONFIG_DMAR) += pci-dma.o
-ifeq ($(CONFIG_DMAR), y)
obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
-endif
-
-# The gate DSO image is built using a special linker script.
-targets += gate.so gate-syms.o
-
-extra-y += gate.so gate-syms.o gate.lds gate.o
# fp_emulate() expects f2-f5,f16-f31 to contain the user-level state.
CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31
-CPPFLAGS_gate.lds := -P -C -U$(ARCH)
-
-quiet_cmd_gate = GATE $@
- cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@
-
-GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \
- $(call ld-option, -Wl$(comma)--hash-style=sysv)
-$(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE
- $(call if_changed,gate)
-
-$(obj)/built-in.o: $(obj)/gate-syms.o
-$(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o
-
-GATECFLAGS_gate-syms.o = -r
-$(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
- $(call if_changed,gate)
-
-# gate-data.o contains the gate DSO image as data in section .data.gate.
-# We must build gate.so before we can assemble it.
-# Note: kbuild does not track this dependency due to usage of .incbin
-$(obj)/gate-data.o: $(obj)/gate.so
+# The gate DSO image is built using a special linker script.
+include $(srctree)/arch/ia64/kernel/Makefile.gate
+# tell compiled for native
+CPPFLAGS_gate.lds += -D__IA64_GATE_PARAVIRTUALIZED_NATIVE
# Calculate NR_IRQ = max(IA64_NATIVE_NR_IRQS, XEN_NR_IRQS, ...) based on config
define sed-y
@@ -116,9 +93,9 @@ include/asm-ia64/nr-irqs.h: arch/$(SRCARCH)/kernel/nr-irqs.s
clean-files += $(objtree)/include/asm-ia64/nr-irqs.h
#
-# native ivt.S and entry.S
+# native ivt.S, entry.S and fsys.S
#
-ASM_PARAVIRT_OBJS = ivt.o entry.o
+ASM_PARAVIRT_OBJS = ivt.o entry.o fsys.o
define paravirtualized_native
AFLAGS_$(1) += -D__IA64_ASM_PARAVIRTUALIZED_NATIVE
AFLAGS_pvchk-sed-$(1) += -D__IA64_ASM_PARAVIRTUALIZED_PVCHECK
diff --git a/arch/ia64/kernel/Makefile.gate b/arch/ia64/kernel/Makefile.gate
new file mode 100644
index 000000000000..1d87f84069b3
--- /dev/null
+++ b/arch/ia64/kernel/Makefile.gate
@@ -0,0 +1,27 @@
+# The gate DSO image is built using a special linker script.
+
+targets += gate.so gate-syms.o
+
+extra-y += gate.so gate-syms.o gate.lds gate.o
+
+CPPFLAGS_gate.lds := -P -C -U$(ARCH)
+
+quiet_cmd_gate = GATE $@
+ cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@
+
+GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1 \
+ $(call ld-option, -Wl$(comma)--hash-style=sysv)
+$(obj)/gate.so: $(obj)/gate.lds $(obj)/gate.o FORCE
+ $(call if_changed,gate)
+
+$(obj)/built-in.o: $(obj)/gate-syms.o
+$(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o
+
+GATECFLAGS_gate-syms.o = -r
+$(obj)/gate-syms.o: $(obj)/gate.lds $(obj)/gate.o FORCE
+ $(call if_changed,gate)
+
+# gate-data.o contains the gate DSO image as data in section .data.gate.
+# We must build gate.so before we can assemble it.
+# Note: kbuild does not track this dependency due to usage of .incbin
+$(obj)/gate-data.o: $(obj)/gate.so
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index bdef2ce38c8b..5510317db37b 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -890,7 +890,7 @@ __init void prefill_possible_map(void)
possible, max((possible - available_cpus), 0));
for (i = 0; i < possible; i++)
- cpu_set(i, cpu_possible_map);
+ set_cpu_possible(i, true);
}
int acpi_map_lsapic(acpi_handle handle, int *pcpu)
@@ -928,9 +928,9 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu)
buffer.length = ACPI_ALLOCATE_BUFFER;
buffer.pointer = NULL;
- cpus_complement(tmp_map, cpu_present_map);
- cpu = first_cpu(tmp_map);
- if (cpu >= NR_CPUS)
+ cpumask_complement(&tmp_map, cpu_present_mask);
+ cpu = cpumask_first(&tmp_map);
+ if (cpu >= nr_cpu_ids)
return -EINVAL;
acpi_map_cpu2node(handle, cpu, physid);
diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c
index 742dbb1d5a4f..af5650169043 100644
--- a/arch/ia64/kernel/asm-offsets.c
+++ b/arch/ia64/kernel/asm-offsets.c
@@ -316,5 +316,7 @@ void foo(void)
DEFINE_MAPPED_REG_OFS(XSI_BANK1_R16_OFS, bank1_regs[0]);
DEFINE_MAPPED_REG_OFS(XSI_B0NATS_OFS, vbnat);
DEFINE_MAPPED_REG_OFS(XSI_B1NATS_OFS, vnat);
+ DEFINE_MAPPED_REG_OFS(XSI_ITC_OFFSET_OFS, itc_offset);
+ DEFINE_MAPPED_REG_OFS(XSI_ITC_LAST_OFS, itc_last);
#endif /* CONFIG_XEN */
}
diff --git a/arch/ia64/kernel/dma-mapping.c b/arch/ia64/kernel/dma-mapping.c
new file mode 100644
index 000000000000..086a2aeb0404
--- /dev/null
+++ b/arch/ia64/kernel/dma-mapping.c
@@ -0,0 +1,13 @@
+#include <linux/dma-mapping.h>
+
+/* Set this to 1 if there is a HW IOMMU in the system */
+int iommu_detected __read_mostly;
+
+struct dma_map_ops *dma_ops;
+EXPORT_SYMBOL(dma_ops);
+
+struct dma_map_ops *dma_get_ops(struct device *dev)
+{
+ return dma_ops;
+}
+EXPORT_SYMBOL(dma_get_ops);
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index efaff15d8cf1..7ef80e8161ce 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -456,6 +456,7 @@ efi_map_pal_code (void)
GRANULEROUNDDOWN((unsigned long) pal_vaddr),
pte_val(pfn_pte(__pa(pal_vaddr) >> PAGE_SHIFT, PAGE_KERNEL)),
IA64_GRANULE_SHIFT);
+ paravirt_dv_serialize_data();
ia64_set_psr(psr); /* restore psr */
}
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 7e3382b06d56..8dc69669586a 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -736,7 +736,7 @@ GLOBAL_ENTRY(__paravirt_leave_syscall)
__paravirt_work_processed_syscall:
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
adds r2=PT(LOADRS)+16,r12
-(pUStk) mov.m r22=ar.itc // fetch time at leave
+ MOV_FROM_ITC(pUStk, p9, r22, r19) // fetch time at leave
adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
;;
(p6) ld4 r31=[r18] // load current_thread_info()->flags
@@ -985,7 +985,7 @@ GLOBAL_ENTRY(__paravirt_leave_kernel)
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
.pred.rel.mutex pUStk,pKStk
MOV_FROM_PSR(pKStk, r22, r29) // M2 read PSR now that interrupts are disabled
-(pUStk) mov.m r22=ar.itc // M fetch time at leave
+ MOV_FROM_ITC(pUStk, p9, r22, r29) // M fetch time at leave
nop.i 0
;;
#else
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
index c1625c7e1779..3567d54f8cee 100644
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -25,6 +25,7 @@
#include <asm/unistd.h>
#include "entry.h"
+#include "paravirt_inst.h"
/*
* See Documentation/ia64/fsys.txt for details on fsyscalls.
@@ -279,7 +280,7 @@ ENTRY(fsys_gettimeofday)
(p9) cmp.eq p13,p0 = 0,r30 // if mmio_ptr, clear p13 jitter control
;;
.pred.rel.mutex p8,p9
-(p8) mov r2 = ar.itc // CPU_TIMER. 36 clocks latency!!!
+ MOV_FROM_ITC(p8, p6, r2, r10) // CPU_TIMER. 36 clocks latency!!!
(p9) ld8 r2 = [r30] // MMIO_TIMER. Could also have latency issues..
(p13) ld8 r25 = [r19] // get itc_lastcycle value
ld8 r9 = [r22],IA64_TIMESPEC_TV_NSEC_OFFSET // tv_sec
@@ -418,7 +419,7 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set
mov r17=(1 << (SIGKILL - 1)) | (1 << (SIGSTOP - 1))
;;
- rsm psr.i // mask interrupt delivery
+ RSM_PSR_I(p0, r18, r19) // mask interrupt delivery
mov ar.ccv=0
andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP
@@ -491,7 +492,7 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set
#ifdef CONFIG_SMP
st4.rel [r31]=r0 // release the lock
#endif
- ssm psr.i
+ SSM_PSR_I(p0, p9, r31)
;;
srlz.d // ensure psr.i is set again
@@ -513,7 +514,7 @@ EX(.fail_efault, (p15) st8 [r34]=r3)
#ifdef CONFIG_SMP
st4.rel [r31]=r0 // release the lock
#endif
- ssm psr.i
+ SSM_PSR_I(p0, p9, r17)
;;
srlz.d
br.sptk.many fsys_fallback_syscall // with signal pending, do the heavy-weight syscall
@@ -521,7 +522,7 @@ EX(.fail_efault, (p15) st8 [r34]=r3)
#ifdef CONFIG_SMP
.lock_contention:
/* Rather than spinning here, fall back on doing a heavy-weight syscall. */
- ssm psr.i
+ SSM_PSR_I(p0, p9, r17)
;;
srlz.d
br.sptk.many fsys_fallback_syscall
@@ -592,17 +593,17 @@ ENTRY(fsys_fallback_syscall)
adds r17=-1024,r15
movl r14=sys_call_table
;;
- rsm psr.i
+ RSM_PSR_I(p0, r26, r27)
shladd r18=r17,3,r14
;;
ld8 r18=[r18] // load normal (heavy-weight) syscall entry-point
- mov r29=psr // read psr (12 cyc load latency)
+ MOV_FROM_PSR(p0, r29, r26) // read psr (12 cyc load latency)
mov r27=ar.rsc
mov r21=ar.fpsr
mov r26=ar.pfs
END(fsys_fallback_syscall)
/* FALL THROUGH */
-GLOBAL_ENTRY(fsys_bubble_down)
+GLOBAL_ENTRY(paravirt_fsys_bubble_down)
.prologue
.altrp b6
.body
@@ -640,7 +641,7 @@ GLOBAL_ENTRY(fsys_bubble_down)
*
* PSR.BE : already is turned off in __kernel_syscall_via_epc()
* PSR.AC : don't care (kernel normally turns PSR.AC on)
- * PSR.I : already turned off by the time fsys_bubble_down gets
+ * PSR.I : already turned off by the time paravirt_fsys_bubble_down gets
* invoked
* PSR.DFL: always 0 (kernel never turns it on)
* PSR.DFH: don't care --- kernel never touches f32-f127 on its own
@@ -650,7 +651,7 @@ GLOBAL_ENTRY(fsys_bubble_down)
* PSR.DB : don't care --- kernel never enables kernel-level
* breakpoints
* PSR.TB : must be 0 already; if it wasn't zero on entry to
- * __kernel_syscall_via_epc, the branch to fsys_bubble_down
+ * __kernel_syscall_via_epc, the branch to paravirt_fsys_bubble_down
* will trigger a taken branch; the taken-trap-handler then
* converts the syscall into a break-based system-call.
*/
@@ -683,7 +684,7 @@ GLOBAL_ENTRY(fsys_bubble_down)
;;
mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- mov.m r30=ar.itc // M get cycle for accounting
+ MOV_FROM_ITC(p0, p6, r30, r23) // M get cycle for accounting
#else
nop.m 0
#endif
@@ -734,21 +735,21 @@ GLOBAL_ENTRY(fsys_bubble_down)
mov rp=r14 // I0 set the real return addr
and r3=_TIF_SYSCALL_TRACEAUDIT,r3 // A
;;
- ssm psr.i // M2 we're on kernel stacks now, reenable irqs
+ SSM_PSR_I(p0, p6, r22) // M2 we're on kernel stacks now, reenable irqs
cmp.eq p8,p0=r3,r0 // A
(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT
nop.m 0
(p8) br.call.sptk.many b6=b6 // B (ignore return address)
br.cond.spnt ia64_trace_syscall // B
-END(fsys_bubble_down)
+END(paravirt_fsys_bubble_down)
.rodata
.align 8
- .globl fsyscall_table
+ .globl paravirt_fsyscall_table
- data8 fsys_bubble_down
-fsyscall_table:
+ data8 paravirt_fsys_bubble_down
+paravirt_fsyscall_table:
data8 fsys_ni_syscall
data8 0 // exit // 1025
data8 0 // read
@@ -1033,4 +1034,4 @@ fsyscall_table:
// fill in zeros for the remaining entries
.zero:
- .space fsyscall_table + 8*NR_syscalls - .zero, 0
+ .space paravirt_fsyscall_table + 8*NR_syscalls - .zero, 0
diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S
index 74b1ccce4e84..cf5e0a105e16 100644
--- a/arch/ia64/kernel/gate.S
+++ b/arch/ia64/kernel/gate.S
@@ -13,6 +13,7 @@
#include <asm/sigcontext.h>
#include <asm/system.h>
#include <asm/unistd.h>
+#include "paravirt_inst.h"
/*
* We can't easily refer to symbols inside the kernel. To avoid full runtime relocation,
@@ -48,87 +49,6 @@ GLOBAL_ENTRY(__kernel_syscall_via_break)
}
END(__kernel_syscall_via_break)
-/*
- * On entry:
- * r11 = saved ar.pfs
- * r15 = system call #
- * b0 = saved return address
- * b6 = return address
- * On exit:
- * r11 = saved ar.pfs
- * r15 = system call #
- * b0 = saved return address
- * all other "scratch" registers: undefined
- * all "preserved" registers: same as on entry
- */
-
-GLOBAL_ENTRY(__kernel_syscall_via_epc)
- .prologue
- .altrp b6
- .body
-{
- /*
- * Note: the kernel cannot assume that the first two instructions in this
- * bundle get executed. The remaining code must be safe even if
- * they do not get executed.
- */
- adds r17=-1024,r15 // A
- mov r10=0 // A default to successful syscall execution
- epc // B causes split-issue
-}
- ;;
- rsm psr.be | psr.i // M2 (5 cyc to srlz.d)
- LOAD_FSYSCALL_TABLE(r14) // X
- ;;
- mov r16=IA64_KR(CURRENT) // M2 (12 cyc)
- shladd r18=r17,3,r14 // A
- mov r19=NR_syscalls-1 // A
- ;;
- lfetch [r18] // M0|1
- mov r29=psr // M2 (12 cyc)
- // If r17 is a NaT, p6 will be zero
- cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)?
- ;;
- mov r21=ar.fpsr // M2 (12 cyc)
- tnat.nz p10,p9=r15 // I0
- mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...)
- ;;
- srlz.d // M0 (forces split-issue) ensure PSR.BE==0
-(p6) ld8 r18=[r18] // M0|1
- nop.i 0
- ;;
- nop.m 0
-(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!)
- nop.i 0
- ;;
-(p8) ssm psr.i
-(p6) mov b7=r18 // I0
-(p8) br.dptk.many b7 // B
-
- mov r27=ar.rsc // M2 (12 cyc)
-/*
- * brl.cond doesn't work as intended because the linker would convert this branch
- * into a branch to a PLT. Perhaps there will be a way to avoid this with some
- * future version of the linker. In the meantime, we just use an indirect branch
- * instead.
- */
-#ifdef CONFIG_ITANIUM
-(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry
- ;;
-(p6) ld8 r14=[r14] // r14 <- fsys_bubble_down
- ;;
-(p6) mov b7=r14
-(p6) br.sptk.many b7
-#else
- BRL_COND_FSYS_BUBBLE_DOWN(p6)
-#endif
- ssm psr.i
- mov r10=-1
-(p10) mov r8=EINVAL
-(p9) mov r8=ENOSYS
- FSYS_RETURN
-END(__kernel_syscall_via_epc)
-
# define ARG0_OFF (16 + IA64_SIGFRAME_ARG0_OFFSET)
# define ARG1_OFF (16 + IA64_SIGFRAME_ARG1_OFFSET)
# define ARG2_OFF (16 + IA64_SIGFRAME_ARG2_OFFSET)
@@ -374,3 +294,92 @@ restore_rbs:
// invala not necessary as that will happen when returning to user-mode
br.cond.sptk back_from_restore_rbs
END(__kernel_sigtramp)
+
+/*
+ * On entry:
+ * r11 = saved ar.pfs
+ * r15 = system call #
+ * b0 = saved return address
+ * b6 = return address
+ * On exit:
+ * r11 = saved ar.pfs
+ * r15 = system call #
+ * b0 = saved return address
+ * all other "scratch" registers: undefined
+ * all "preserved" registers: same as on entry
+ */
+
+GLOBAL_ENTRY(__kernel_syscall_via_epc)
+ .prologue
+ .altrp b6
+ .body
+{
+ /*
+ * Note: the kernel cannot assume that the first two instructions in this
+ * bundle get executed. The remaining code must be safe even if
+ * they do not get executed.
+ */
+ adds r17=-1024,r15 // A
+ mov r10=0 // A default to successful syscall execution
+ epc // B causes split-issue
+}
+ ;;
+ RSM_PSR_BE_I(r20, r22) // M2 (5 cyc to srlz.d)
+ LOAD_FSYSCALL_TABLE(r14) // X
+ ;;
+ mov r16=IA64_KR(CURRENT) // M2 (12 cyc)
+ shladd r18=r17,3,r14 // A
+ mov r19=NR_syscalls-1 // A
+ ;;
+ lfetch [r18] // M0|1
+ MOV_FROM_PSR(p0, r29, r8) // M2 (12 cyc)
+ // If r17 is a NaT, p6 will be zero
+ cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)?
+ ;;
+ mov r21=ar.fpsr // M2 (12 cyc)
+ tnat.nz p10,p9=r15 // I0
+ mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...)
+ ;;
+ srlz.d // M0 (forces split-issue) ensure PSR.BE==0
+(p6) ld8 r18=[r18] // M0|1
+ nop.i 0
+ ;;
+ nop.m 0
+(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!)
+ nop.i 0
+ ;;
+ SSM_PSR_I(p8, p14, r25)
+(p6) mov b7=r18 // I0
+(p8) br.dptk.many b7 // B
+
+ mov r27=ar.rsc // M2 (12 cyc)
+/*
+ * brl.cond doesn't work as intended because the linker would convert this branch
+ * into a branch to a PLT. Perhaps there will be a way to avoid this with some
+ * future version of the linker. In the meantime, we just use an indirect branch
+ * instead.
+ */
+#ifdef CONFIG_ITANIUM
+(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry
+ ;;
+(p6) ld8 r14=[r14] // r14 <- fsys_bubble_down
+ ;;
+(p6) mov b7=r14
+(p6) br.sptk.many b7
+#else
+ BRL_COND_FSYS_BUBBLE_DOWN(p6)
+#endif
+ SSM_PSR_I(p0, p14, r10)
+ mov r10=-1
+(p10) mov r8=EINVAL
+(p9) mov r8=ENOSYS
+ FSYS_RETURN
+
+#ifdef CONFIG_PARAVIRT
+ /*
+ * padd to make the size of this symbol constant
+ * independent of paravirtualization.
+ */
+ .align PAGE_SIZE / 8
+#endif
+END(__kernel_syscall_via_epc)
diff --git a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S
index 3cb1abc00e24..88c64ed47c36 100644
--- a/arch/ia64/kernel/gate.lds.S
+++ b/arch/ia64/kernel/gate.lds.S
@@ -7,6 +7,7 @@
#include <asm/system.h>
+#include "paravirt_patchlist.h"
SECTIONS
{
@@ -33,21 +34,21 @@ SECTIONS
. = GATE_ADDR + 0x600;
.data.patch : {
- __start_gate_mckinley_e9_patchlist = .;
+ __paravirt_start_gate_mckinley_e9_patchlist = .;
*(.data.patch.mckinley_e9)
- __end_gate_mckinley_e9_patchlist = .;
+ __paravirt_end_gate_mckinley_e9_patchlist = .;
- __start_gate_vtop_patchlist = .;
+ __paravirt_start_gate_vtop_patchlist = .;
*(.data.patch.vtop)
- __end_gate_vtop_patchlist = .;
+ __paravirt_end_gate_vtop_patchlist = .;
- __start_gate_fsyscall_patchlist = .;
+ __paravirt_start_gate_fsyscall_patchlist = .;
*(.data.patch.fsyscall_table)
- __end_gate_fsyscall_patchlist = .;
+ __paravirt_end_gate_fsyscall_patchlist = .;
- __start_gate_brl_fsys_bubble_down_patchlist = .;
+ __paravirt_start_gate_brl_fsys_bubble_down_patchlist = .;
*(.data.patch.brl_fsys_bubble_down)
- __end_gate_brl_fsys_bubble_down_patchlist = .;
+ __paravirt_end_gate_brl_fsys_bubble_down_patchlist = .;
} :readable
.IA_64.unwind_info : { *(.IA_64.unwind_info*) }
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
index 59301c472800..23f846de62d5 100644
--- a/arch/ia64/kernel/head.S
+++ b/arch/ia64/kernel/head.S
@@ -1050,7 +1050,7 @@ END(ia64_delay_loop)
* except that the multiplication and the shift are done with 128-bit
* intermediate precision so that we can produce a full 64-bit result.
*/
-GLOBAL_ENTRY(sched_clock)
+GLOBAL_ENTRY(ia64_native_sched_clock)
addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
mov.m r9=ar.itc // fetch cycle-counter (35 cyc)
;;
@@ -1066,7 +1066,13 @@ GLOBAL_ENTRY(sched_clock)
;;
shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT
br.ret.sptk.many rp
-END(sched_clock)
+END(ia64_native_sched_clock)
+#ifndef CONFIG_PARAVIRT
+ //unsigned long long
+ //sched_clock(void) __attribute__((alias("ia64_native_sched_clock")));
+ .global sched_clock
+sched_clock = ia64_native_sched_clock
+#endif
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
GLOBAL_ENTRY(cycle_to_cputime)
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index 226233a6fa19..7429752ef5ad 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -80,7 +80,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%10u ", kstat_irqs(i));
#else
for_each_online_cpu(j) {
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
}
#endif
seq_printf(p, " %14s", irq_desc[i].chip->name);
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 927ad027820c..acc4d19ae62a 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -493,16 +493,15 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
ia64_srlz_d();
while (vector != IA64_SPURIOUS_INT_VECTOR) {
- struct irq_desc *desc = irq_to_desc(vector);
+ int irq = local_vector_to_irq(vector);
+ struct irq_desc *desc = irq_to_desc(irq);
if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) {
smp_local_flush_tlb();
- kstat_incr_irqs_this_cpu(vector, desc);
- } else if (unlikely(IS_RESCHEDULE(vector)))
- kstat_incr_irqs_this_cpu(vector, desc);
- else {
- int irq = local_vector_to_irq(vector);
-
+ kstat_incr_irqs_this_cpu(irq, desc);
+ } else if (unlikely(IS_RESCHEDULE(vector))) {
+ kstat_incr_irqs_this_cpu(irq, desc);
+ } else {
ia64_setreg(_IA64_REG_CR_TPR, vector);
ia64_srlz_d();
@@ -545,24 +544,24 @@ void ia64_process_pending_intr(void)
vector = ia64_get_ivr();
- irq_enter();
- saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
- ia64_srlz_d();
+ irq_enter();
+ saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
+ ia64_srlz_d();
/*
* Perform normal interrupt style processing
*/
while (vector != IA64_SPURIOUS_INT_VECTOR) {
- struct irq_desc *desc = irq_to_desc(vector);
+ int irq = local_vector_to_irq(vector);
+ struct irq_desc *desc = irq_to_desc(irq);
if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) {
smp_local_flush_tlb();
- kstat_incr_irqs_this_cpu(vector, desc);
- } else if (unlikely(IS_RESCHEDULE(vector)))
- kstat_incr_irqs_this_cpu(vector, desc);
- else {
+ kstat_incr_irqs_this_cpu(irq, desc);
+ } else if (unlikely(IS_RESCHEDULE(vector))) {
+ kstat_incr_irqs_this_cpu(irq, desc);
+ } else {
struct pt_regs *old_regs = set_irq_regs(NULL);
- int irq = local_vector_to_irq(vector);
ia64_setreg(_IA64_REG_CR_TPR, vector);
ia64_srlz_d();
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index f675d8e33853..ec9a5fdfa1b9 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -804,7 +804,7 @@ ENTRY(break_fault)
///////////////////////////////////////////////////////////////////////
st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- mov.m r30=ar.itc // M get cycle for accounting
+ MOV_FROM_ITC(p0, p14, r30, r18) // M get cycle for accounting
#else
mov b6=r30 // I0 setup syscall handler branch reg early
#endif
diff --git a/arch/ia64/kernel/machvec.c b/arch/ia64/kernel/machvec.c
index 7ccb228ceedc..d41a40ef80c0 100644
--- a/arch/ia64/kernel/machvec.c
+++ b/arch/ia64/kernel/machvec.c
@@ -1,5 +1,5 @@
#include <linux/module.h>
-
+#include <linux/dma-mapping.h>
#include <asm/machvec.h>
#include <asm/system.h>
@@ -75,14 +75,16 @@ machvec_timer_interrupt (int irq, void *dev_id)
EXPORT_SYMBOL(machvec_timer_interrupt);
void
-machvec_dma_sync_single (struct device *hwdev, dma_addr_t dma_handle, size_t size, int dir)
+machvec_dma_sync_single(struct device *hwdev, dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction dir)
{
mb();
}
EXPORT_SYMBOL(machvec_dma_sync_single);
void
-machvec_dma_sync_sg (struct device *hwdev, struct scatterlist *sg, int n, int dir)
+machvec_dma_sync_sg(struct device *hwdev, struct scatterlist *sg, int n,
+ enum dma_data_direction dir)
{
mb();
}
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index bab1de2d2f6a..8f33a8840422 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -1456,9 +1456,9 @@ ia64_mca_cmc_int_caller(int cmc_irq, void *arg)
ia64_mca_cmc_int_handler(cmc_irq, arg);
- for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++);
+ cpuid = cpumask_next(cpuid+1, cpu_online_mask);
- if (cpuid < NR_CPUS) {
+ if (cpuid < nr_cpu_ids) {
platform_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
} else {
/* If no log record, switch out of polling mode */
@@ -1525,7 +1525,7 @@ ia64_mca_cpe_int_caller(int cpe_irq, void *arg)
ia64_mca_cpe_int_handler(cpe_irq, arg);
- for (++cpuid ; cpuid < NR_CPUS && !cpu_online(cpuid) ; cpuid++);
+ cpuid = cpumask_next(cpuid+1, cpu_online_mask);
if (cpuid < NR_CPUS) {
platform_send_ipi(cpuid, IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index aaa7d901521f..da3b0cf495a3 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -446,6 +446,14 @@ module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings,
mod->arch.opd = s;
else if (strcmp(".IA_64.unwind", secstrings + s->sh_name) == 0)
mod->arch.unwind = s;
+#ifdef CONFIG_PARAVIRT
+ else if (strcmp(".paravirt_bundles",
+ secstrings + s->sh_name) == 0)
+ mod->arch.paravirt_bundles = s;
+ else if (strcmp(".paravirt_insts",
+ secstrings + s->sh_name) == 0)
+ mod->arch.paravirt_insts = s;
+#endif
if (!mod->arch.core_plt || !mod->arch.init_plt || !mod->arch.got || !mod->arch.opd) {
printk(KERN_ERR "%s: sections missing\n", mod->name);
@@ -525,8 +533,7 @@ get_ltoff (struct module *mod, uint64_t value, int *okp)
goto found;
/* Not enough GOT entries? */
- if (e >= (struct got_entry *) (mod->arch.got->sh_addr + mod->arch.got->sh_size))
- BUG();
+ BUG_ON(e >= (struct got_entry *) (mod->arch.got->sh_addr + mod->arch.got->sh_size));
e->val = value;
++mod->arch.next_got_entry;
@@ -921,6 +928,30 @@ module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mo
DEBUGP("%s: init: entry=%p\n", __func__, mod->init);
if (mod->arch.unwind)
register_unwind_table(mod);
+#ifdef CONFIG_PARAVIRT
+ if (mod->arch.paravirt_bundles) {
+ struct paravirt_patch_site_bundle *start =
+ (struct paravirt_patch_site_bundle *)
+ mod->arch.paravirt_bundles->sh_addr;
+ struct paravirt_patch_site_bundle *end =
+ (struct paravirt_patch_site_bundle *)
+ (mod->arch.paravirt_bundles->sh_addr +
+ mod->arch.paravirt_bundles->sh_size);
+
+ paravirt_patch_apply_bundle(start, end);
+ }
+ if (mod->arch.paravirt_insts) {
+ struct paravirt_patch_site_inst *start =
+ (struct paravirt_patch_site_inst *)
+ mod->arch.paravirt_insts->sh_addr;
+ struct paravirt_patch_site_inst *end =
+ (struct paravirt_patch_site_inst *)
+ (mod->arch.paravirt_insts->sh_addr +
+ mod->arch.paravirt_insts->sh_size);
+
+ paravirt_patch_apply_inst(start, end);
+ }
+#endif
return 0;
}
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index dcb6b7c51ea7..2b15e233f7fe 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -7,44 +7,7 @@
#include <linux/msi.h>
#include <linux/dmar.h>
#include <asm/smp.h>
-
-/*
- * Shifts for APIC-based data
- */
-
-#define MSI_DATA_VECTOR_SHIFT 0
-#define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT)
-#define MSI_DATA_VECTOR_MASK 0xffffff00
-
-#define MSI_DATA_DELIVERY_SHIFT 8
-#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT)
-#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_SHIFT)
-
-#define MSI_DATA_LEVEL_SHIFT 14
-#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT)
-#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT)
-
-#define MSI_DATA_TRIGGER_SHIFT 15
-#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT)
-#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT)
-
-/*
- * Shift/mask fields for APIC-based bus address
- */
-
-#define MSI_TARGET_CPU_SHIFT 4
-#define MSI_ADDR_HEADER 0xfee00000
-
-#define MSI_ADDR_DESTID_MASK 0xfff0000f
-#define MSI_ADDR_DESTID_CPU(cpu) ((cpu) << MSI_TARGET_CPU_SHIFT)
-
-#define MSI_ADDR_DESTMODE_SHIFT 2
-#define MSI_ADDR_DESTMODE_PHYS (0 << MSI_ADDR_DESTMODE_SHIFT)
-#define MSI_ADDR_DESTMODE_LOGIC (1 << MSI_ADDR_DESTMODE_SHIFT)
-
-#define MSI_ADDR_REDIRECTION_SHIFT 3
-#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT)
-#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT)
+#include <asm/msidef.h>
static struct irq_chip ia64_msi_chip;
@@ -65,8 +28,8 @@ static void ia64_set_msi_irq_affinity(unsigned int irq,
read_msi_msg(irq, &msg);
addr = msg.address_lo;
- addr &= MSI_ADDR_DESTID_MASK;
- addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(cpu));
+ addr &= MSI_ADDR_DEST_ID_MASK;
+ addr |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu));
msg.address_lo = addr;
data = msg.data;
@@ -98,9 +61,9 @@ int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
msg.address_hi = 0;
msg.address_lo =
MSI_ADDR_HEADER |
- MSI_ADDR_DESTMODE_PHYS |
+ MSI_ADDR_DEST_MODE_PHYS |
MSI_ADDR_REDIRECTION_CPU |
- MSI_ADDR_DESTID_CPU(dest_phys_id);
+ MSI_ADDR_DEST_ID_CPU(dest_phys_id);
msg.data =
MSI_DATA_TRIGGER_EDGE |
@@ -183,8 +146,8 @@ static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
msg.data &= ~MSI_DATA_VECTOR_MASK;
msg.data |= MSI_DATA_VECTOR(cfg->vector);
- msg.address_lo &= ~MSI_ADDR_DESTID_MASK;
- msg.address_lo |= MSI_ADDR_DESTID_CPU(cpu_physical_id(cpu));
+ msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
+ msg.address_lo |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu));
dmar_msi_write(irq, &msg);
cpumask_copy(irq_desc[irq].affinity, mask);
@@ -215,9 +178,9 @@ msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
msg->address_hi = 0;
msg->address_lo =
MSI_ADDR_HEADER |
- MSI_ADDR_DESTMODE_PHYS |
+ MSI_ADDR_DEST_MODE_PHYS |
MSI_ADDR_REDIRECTION_CPU |
- MSI_ADDR_DESTID_CPU(dest);
+ MSI_ADDR_DEST_ID_CPU(dest);
msg->data =
MSI_DATA_TRIGGER_EDGE |
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c
index e5c57f413ca2..a4f19c70aadd 100644
--- a/arch/ia64/kernel/palinfo.c
+++ b/arch/ia64/kernel/palinfo.c
@@ -1002,8 +1002,6 @@ create_palinfo_proc_entries(unsigned int cpu)
*pdir = create_proc_read_entry(
palinfo_entries[j].name, 0, cpu_dir,
palinfo_read_entry, (void *)f.value);
- if (*pdir)
- (*pdir)->owner = THIS_MODULE;
pdir++;
}
}
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c
index 9f14c16f6369..a21d7bb9c69c 100644
--- a/arch/ia64/kernel/paravirt.c
+++ b/arch/ia64/kernel/paravirt.c
@@ -46,13 +46,23 @@ struct pv_info pv_info = {
* initialization hooks.
*/
-struct pv_init_ops pv_init_ops;
+static void __init
+ia64_native_patch_branch(unsigned long tag, unsigned long type);
+
+struct pv_init_ops pv_init_ops =
+{
+#ifdef ASM_SUPPORTED
+ .patch_bundle = ia64_native_patch_bundle,
+#endif
+ .patch_branch = ia64_native_patch_branch,
+};
/***************************************************************************
* pv_cpu_ops
* intrinsics hooks.
*/
+#ifndef ASM_SUPPORTED
/* ia64_native_xxx are macros so that we have to make them real functions */
#define DEFINE_VOID_FUNC1(name) \
@@ -60,7 +70,14 @@ struct pv_init_ops pv_init_ops;
ia64_native_ ## name ## _func(unsigned long arg) \
{ \
ia64_native_ ## name(arg); \
- } \
+ }
+
+#define DEFINE_VOID_FUNC1_VOID(name) \
+ static void \
+ ia64_native_ ## name ## _func(void *arg) \
+ { \
+ ia64_native_ ## name(arg); \
+ }
#define DEFINE_VOID_FUNC2(name) \
static void \
@@ -68,7 +85,7 @@ struct pv_init_ops pv_init_ops;
unsigned long arg1) \
{ \
ia64_native_ ## name(arg0, arg1); \
- } \
+ }
#define DEFINE_FUNC0(name) \
static unsigned long \
@@ -84,7 +101,7 @@ struct pv_init_ops pv_init_ops;
return ia64_native_ ## name(arg); \
} \
-DEFINE_VOID_FUNC1(fc);
+DEFINE_VOID_FUNC1_VOID(fc);
DEFINE_VOID_FUNC1(intrin_local_irq_restore);
DEFINE_VOID_FUNC2(ptcga);
@@ -274,6 +291,266 @@ ia64_native_setreg_func(int regnum, unsigned long val)
break;
}
}
+#else
+
+#define __DEFINE_FUNC(name, code) \
+ extern const char ia64_native_ ## name ## _direct_start[]; \
+ extern const char ia64_native_ ## name ## _direct_end[]; \
+ asm (".align 32\n" \
+ ".proc ia64_native_" #name "_func\n" \
+ "ia64_native_" #name "_func:\n" \
+ "ia64_native_" #name "_direct_start:\n" \
+ code \
+ "ia64_native_" #name "_direct_end:\n" \
+ "br.cond.sptk.many b6\n" \
+ ".endp ia64_native_" #name "_func\n")
+
+#define DEFINE_VOID_FUNC0(name, code) \
+ extern void \
+ ia64_native_ ## name ## _func(void); \
+ __DEFINE_FUNC(name, code)
+
+#define DEFINE_VOID_FUNC1(name, code) \
+ extern void \
+ ia64_native_ ## name ## _func(unsigned long arg); \
+ __DEFINE_FUNC(name, code)
+
+#define DEFINE_VOID_FUNC1_VOID(name, code) \
+ extern void \
+ ia64_native_ ## name ## _func(void *arg); \
+ __DEFINE_FUNC(name, code)
+
+#define DEFINE_VOID_FUNC2(name, code) \
+ extern void \
+ ia64_native_ ## name ## _func(unsigned long arg0, \
+ unsigned long arg1); \
+ __DEFINE_FUNC(name, code)
+
+#define DEFINE_FUNC0(name, code) \
+ extern unsigned long \
+ ia64_native_ ## name ## _func(void); \
+ __DEFINE_FUNC(name, code)
+
+#define DEFINE_FUNC1(name, type, code) \
+ extern unsigned long \
+ ia64_native_ ## name ## _func(type arg); \
+ __DEFINE_FUNC(name, code)
+
+DEFINE_VOID_FUNC1_VOID(fc,
+ "fc r8\n");
+DEFINE_VOID_FUNC1(intrin_local_irq_restore,
+ ";;\n"
+ " cmp.ne p6, p7 = r8, r0\n"
+ ";;\n"
+ "(p6) ssm psr.i\n"
+ "(p7) rsm psr.i\n"
+ ";;\n"
+ "(p6) srlz.d\n");
+
+DEFINE_VOID_FUNC2(ptcga,
+ "ptc.ga r8, r9\n");
+DEFINE_VOID_FUNC2(set_rr,
+ "mov rr[r8] = r9\n");
+
+/* ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I */
+DEFINE_FUNC0(get_psr_i,
+ "mov r2 = " __stringify(1 << IA64_PSR_I_BIT) "\n"
+ "mov r8 = psr\n"
+ ";;\n"
+ "and r8 = r2, r8\n");
+
+DEFINE_FUNC1(thash, unsigned long,
+ "thash r8 = r8\n");
+DEFINE_FUNC1(get_cpuid, int,
+ "mov r8 = cpuid[r8]\n");
+DEFINE_FUNC1(get_pmd, int,
+ "mov r8 = pmd[r8]\n");
+DEFINE_FUNC1(get_rr, unsigned long,
+ "mov r8 = rr[r8]\n");
+
+DEFINE_VOID_FUNC0(ssm_i,
+ "ssm psr.i\n");
+DEFINE_VOID_FUNC0(rsm_i,
+ "rsm psr.i\n");
+
+extern void
+ia64_native_set_rr0_to_rr4_func(unsigned long val0, unsigned long val1,
+ unsigned long val2, unsigned long val3,
+ unsigned long val4);
+__DEFINE_FUNC(set_rr0_to_rr4,
+ "mov rr[r0] = r8\n"
+ "movl r2 = 0x2000000000000000\n"
+ ";;\n"
+ "mov rr[r2] = r9\n"
+ "shl r3 = r2, 1\n" /* movl r3 = 0x4000000000000000 */
+ ";;\n"
+ "add r2 = r2, r3\n" /* movl r2 = 0x6000000000000000 */
+ "mov rr[r3] = r10\n"
+ ";;\n"
+ "mov rr[r2] = r11\n"
+ "shl r3 = r3, 1\n" /* movl r3 = 0x8000000000000000 */
+ ";;\n"
+ "mov rr[r3] = r14\n");
+
+extern unsigned long ia64_native_getreg_func(int regnum);
+asm(".global ia64_native_getreg_func\n");
+#define __DEFINE_GET_REG(id, reg) \
+ "mov r2 = " __stringify(_IA64_REG_ ## id) "\n" \
+ ";;\n" \
+ "cmp.eq p6, p0 = r2, r8\n" \
+ ";;\n" \
+ "(p6) mov r8 = " #reg "\n" \
+ "(p6) br.cond.sptk.many b6\n" \
+ ";;\n"
+#define __DEFINE_GET_AR(id, reg) __DEFINE_GET_REG(AR_ ## id, ar.reg)
+#define __DEFINE_GET_CR(id, reg) __DEFINE_GET_REG(CR_ ## id, cr.reg)
+
+__DEFINE_FUNC(getreg,
+ __DEFINE_GET_REG(GP, gp)
+ /*__DEFINE_GET_REG(IP, ip)*/ /* returned ip value shouldn't be constant */
+ __DEFINE_GET_REG(PSR, psr)
+ __DEFINE_GET_REG(TP, tp)
+ __DEFINE_GET_REG(SP, sp)
+
+ __DEFINE_GET_REG(AR_KR0, ar0)
+ __DEFINE_GET_REG(AR_KR1, ar1)
+ __DEFINE_GET_REG(AR_KR2, ar2)
+ __DEFINE_GET_REG(AR_KR3, ar3)
+ __DEFINE_GET_REG(AR_KR4, ar4)
+ __DEFINE_GET_REG(AR_KR5, ar5)
+ __DEFINE_GET_REG(AR_KR6, ar6)
+ __DEFINE_GET_REG(AR_KR7, ar7)
+ __DEFINE_GET_AR(RSC, rsc)
+ __DEFINE_GET_AR(BSP, bsp)
+ __DEFINE_GET_AR(BSPSTORE, bspstore)
+ __DEFINE_GET_AR(RNAT, rnat)
+ __DEFINE_GET_AR(FCR, fcr)
+ __DEFINE_GET_AR(EFLAG, eflag)
+ __DEFINE_GET_AR(CSD, csd)
+ __DEFINE_GET_AR(SSD, ssd)
+ __DEFINE_GET_REG(AR_CFLAG, ar27)
+ __DEFINE_GET_AR(FSR, fsr)
+ __DEFINE_GET_AR(FIR, fir)
+ __DEFINE_GET_AR(FDR, fdr)
+ __DEFINE_GET_AR(CCV, ccv)
+ __DEFINE_GET_AR(UNAT, unat)
+ __DEFINE_GET_AR(FPSR, fpsr)
+ __DEFINE_GET_AR(ITC, itc)
+ __DEFINE_GET_AR(PFS, pfs)
+ __DEFINE_GET_AR(LC, lc)
+ __DEFINE_GET_AR(EC, ec)
+
+ __DEFINE_GET_CR(DCR, dcr)
+ __DEFINE_GET_CR(ITM, itm)
+ __DEFINE_GET_CR(IVA, iva)
+ __DEFINE_GET_CR(PTA, pta)
+ __DEFINE_GET_CR(IPSR, ipsr)
+ __DEFINE_GET_CR(ISR, isr)
+ __DEFINE_GET_CR(IIP, iip)
+ __DEFINE_GET_CR(IFA, ifa)
+ __DEFINE_GET_CR(ITIR, itir)
+ __DEFINE_GET_CR(IIPA, iipa)
+ __DEFINE_GET_CR(IFS, ifs)
+ __DEFINE_GET_CR(IIM, iim)
+ __DEFINE_GET_CR(IHA, iha)
+ __DEFINE_GET_CR(LID, lid)
+ __DEFINE_GET_CR(IVR, ivr)
+ __DEFINE_GET_CR(TPR, tpr)
+ __DEFINE_GET_CR(EOI, eoi)
+ __DEFINE_GET_CR(IRR0, irr0)
+ __DEFINE_GET_CR(IRR1, irr1)
+ __DEFINE_GET_CR(IRR2, irr2)
+ __DEFINE_GET_CR(IRR3, irr3)
+ __DEFINE_GET_CR(ITV, itv)
+ __DEFINE_GET_CR(PMV, pmv)
+ __DEFINE_GET_CR(CMCV, cmcv)
+ __DEFINE_GET_CR(LRR0, lrr0)
+ __DEFINE_GET_CR(LRR1, lrr1)
+
+ "mov r8 = -1\n" /* unsupported case */
+ );
+
+extern void ia64_native_setreg_func(int regnum, unsigned long val);
+asm(".global ia64_native_setreg_func\n");
+#define __DEFINE_SET_REG(id, reg) \
+ "mov r2 = " __stringify(_IA64_REG_ ## id) "\n" \
+ ";;\n" \
+ "cmp.eq p6, p0 = r2, r9\n" \
+ ";;\n" \
+ "(p6) mov " #reg " = r8\n" \
+ "(p6) br.cond.sptk.many b6\n" \
+ ";;\n"
+#define __DEFINE_SET_AR(id, reg) __DEFINE_SET_REG(AR_ ## id, ar.reg)
+#define __DEFINE_SET_CR(id, reg) __DEFINE_SET_REG(CR_ ## id, cr.reg)
+__DEFINE_FUNC(setreg,
+ "mov r2 = " __stringify(_IA64_REG_PSR_L) "\n"
+ ";;\n"
+ "cmp.eq p6, p0 = r2, r9\n"
+ ";;\n"
+ "(p6) mov psr.l = r8\n"
+#ifdef HAVE_SERIALIZE_DIRECTIVE
+ ".serialize.data\n"
+#endif
+ "(p6) br.cond.sptk.many b6\n"
+ __DEFINE_SET_REG(GP, gp)
+ __DEFINE_SET_REG(SP, sp)
+
+ __DEFINE_SET_REG(AR_KR0, ar0)
+ __DEFINE_SET_REG(AR_KR1, ar1)
+ __DEFINE_SET_REG(AR_KR2, ar2)
+ __DEFINE_SET_REG(AR_KR3, ar3)
+ __DEFINE_SET_REG(AR_KR4, ar4)
+ __DEFINE_SET_REG(AR_KR5, ar5)
+ __DEFINE_SET_REG(AR_KR6, ar6)
+ __DEFINE_SET_REG(AR_KR7, ar7)
+ __DEFINE_SET_AR(RSC, rsc)
+ __DEFINE_SET_AR(BSP, bsp)
+ __DEFINE_SET_AR(BSPSTORE, bspstore)
+ __DEFINE_SET_AR(RNAT, rnat)
+ __DEFINE_SET_AR(FCR, fcr)
+ __DEFINE_SET_AR(EFLAG, eflag)
+ __DEFINE_SET_AR(CSD, csd)
+ __DEFINE_SET_AR(SSD, ssd)
+ __DEFINE_SET_REG(AR_CFLAG, ar27)
+ __DEFINE_SET_AR(FSR, fsr)
+ __DEFINE_SET_AR(FIR, fir)
+ __DEFINE_SET_AR(FDR, fdr)
+ __DEFINE_SET_AR(CCV, ccv)
+ __DEFINE_SET_AR(UNAT, unat)
+ __DEFINE_SET_AR(FPSR, fpsr)
+ __DEFINE_SET_AR(ITC, itc)
+ __DEFINE_SET_AR(PFS, pfs)
+ __DEFINE_SET_AR(LC, lc)
+ __DEFINE_SET_AR(EC, ec)
+
+ __DEFINE_SET_CR(DCR, dcr)
+ __DEFINE_SET_CR(ITM, itm)
+ __DEFINE_SET_CR(IVA, iva)
+ __DEFINE_SET_CR(PTA, pta)
+ __DEFINE_SET_CR(IPSR, ipsr)
+ __DEFINE_SET_CR(ISR, isr)
+ __DEFINE_SET_CR(IIP, iip)
+ __DEFINE_SET_CR(IFA, ifa)
+ __DEFINE_SET_CR(ITIR, itir)
+ __DEFINE_SET_CR(IIPA, iipa)
+ __DEFINE_SET_CR(IFS, ifs)
+ __DEFINE_SET_CR(IIM, iim)
+ __DEFINE_SET_CR(IHA, iha)
+ __DEFINE_SET_CR(LID, lid)
+ __DEFINE_SET_CR(IVR, ivr)
+ __DEFINE_SET_CR(TPR, tpr)
+ __DEFINE_SET_CR(EOI, eoi)
+ __DEFINE_SET_CR(IRR0, irr0)
+ __DEFINE_SET_CR(IRR1, irr1)
+ __DEFINE_SET_CR(IRR2, irr2)
+ __DEFINE_SET_CR(IRR3, irr3)
+ __DEFINE_SET_CR(ITV, itv)
+ __DEFINE_SET_CR(PMV, pmv)
+ __DEFINE_SET_CR(CMCV, cmcv)
+ __DEFINE_SET_CR(LRR0, lrr0)
+ __DEFINE_SET_CR(LRR1, lrr1)
+ );
+#endif
struct pv_cpu_ops pv_cpu_ops = {
.fc = ia64_native_fc_func,
@@ -366,4 +643,258 @@ ia64_native_do_steal_accounting(unsigned long *new_itm)
struct pv_time_ops pv_time_ops = {
.do_steal_accounting = ia64_native_do_steal_accounting,
+ .sched_clock = ia64_native_sched_clock,
+};
+
+/***************************************************************************
+ * binary pacthing
+ * pv_init_ops.patch_bundle
+ */
+
+#ifdef ASM_SUPPORTED
+#define IA64_NATIVE_PATCH_DEFINE_GET_REG(name, reg) \
+ __DEFINE_FUNC(get_ ## name, \
+ ";;\n" \
+ "mov r8 = " #reg "\n" \
+ ";;\n")
+
+#define IA64_NATIVE_PATCH_DEFINE_SET_REG(name, reg) \
+ __DEFINE_FUNC(set_ ## name, \
+ ";;\n" \
+ "mov " #reg " = r8\n" \
+ ";;\n")
+
+#define IA64_NATIVE_PATCH_DEFINE_REG(name, reg) \
+ IA64_NATIVE_PATCH_DEFINE_GET_REG(name, reg); \
+ IA64_NATIVE_PATCH_DEFINE_SET_REG(name, reg) \
+
+#define IA64_NATIVE_PATCH_DEFINE_AR(name, reg) \
+ IA64_NATIVE_PATCH_DEFINE_REG(ar_ ## name, ar.reg)
+
+#define IA64_NATIVE_PATCH_DEFINE_CR(name, reg) \
+ IA64_NATIVE_PATCH_DEFINE_REG(cr_ ## name, cr.reg)
+
+
+IA64_NATIVE_PATCH_DEFINE_GET_REG(psr, psr);
+IA64_NATIVE_PATCH_DEFINE_GET_REG(tp, tp);
+
+/* IA64_NATIVE_PATCH_DEFINE_SET_REG(psr_l, psr.l); */
+__DEFINE_FUNC(set_psr_l,
+ ";;\n"
+ "mov psr.l = r8\n"
+#ifdef HAVE_SERIALIZE_DIRECTIVE
+ ".serialize.data\n"
+#endif
+ ";;\n");
+
+IA64_NATIVE_PATCH_DEFINE_REG(gp, gp);
+IA64_NATIVE_PATCH_DEFINE_REG(sp, sp);
+
+IA64_NATIVE_PATCH_DEFINE_REG(kr0, ar0);
+IA64_NATIVE_PATCH_DEFINE_REG(kr1, ar1);
+IA64_NATIVE_PATCH_DEFINE_REG(kr2, ar2);
+IA64_NATIVE_PATCH_DEFINE_REG(kr3, ar3);
+IA64_NATIVE_PATCH_DEFINE_REG(kr4, ar4);
+IA64_NATIVE_PATCH_DEFINE_REG(kr5, ar5);
+IA64_NATIVE_PATCH_DEFINE_REG(kr6, ar6);
+IA64_NATIVE_PATCH_DEFINE_REG(kr7, ar7);
+
+IA64_NATIVE_PATCH_DEFINE_AR(rsc, rsc);
+IA64_NATIVE_PATCH_DEFINE_AR(bsp, bsp);
+IA64_NATIVE_PATCH_DEFINE_AR(bspstore, bspstore);
+IA64_NATIVE_PATCH_DEFINE_AR(rnat, rnat);
+IA64_NATIVE_PATCH_DEFINE_AR(fcr, fcr);
+IA64_NATIVE_PATCH_DEFINE_AR(eflag, eflag);
+IA64_NATIVE_PATCH_DEFINE_AR(csd, csd);
+IA64_NATIVE_PATCH_DEFINE_AR(ssd, ssd);
+IA64_NATIVE_PATCH_DEFINE_REG(ar27, ar27);
+IA64_NATIVE_PATCH_DEFINE_AR(fsr, fsr);
+IA64_NATIVE_PATCH_DEFINE_AR(fir, fir);
+IA64_NATIVE_PATCH_DEFINE_AR(fdr, fdr);
+IA64_NATIVE_PATCH_DEFINE_AR(ccv, ccv);
+IA64_NATIVE_PATCH_DEFINE_AR(unat, unat);
+IA64_NATIVE_PATCH_DEFINE_AR(fpsr, fpsr);
+IA64_NATIVE_PATCH_DEFINE_AR(itc, itc);
+IA64_NATIVE_PATCH_DEFINE_AR(pfs, pfs);
+IA64_NATIVE_PATCH_DEFINE_AR(lc, lc);
+IA64_NATIVE_PATCH_DEFINE_AR(ec, ec);
+
+IA64_NATIVE_PATCH_DEFINE_CR(dcr, dcr);
+IA64_NATIVE_PATCH_DEFINE_CR(itm, itm);
+IA64_NATIVE_PATCH_DEFINE_CR(iva, iva);
+IA64_NATIVE_PATCH_DEFINE_CR(pta, pta);
+IA64_NATIVE_PATCH_DEFINE_CR(ipsr, ipsr);
+IA64_NATIVE_PATCH_DEFINE_CR(isr, isr);
+IA64_NATIVE_PATCH_DEFINE_CR(iip, iip);
+IA64_NATIVE_PATCH_DEFINE_CR(ifa, ifa);
+IA64_NATIVE_PATCH_DEFINE_CR(itir, itir);
+IA64_NATIVE_PATCH_DEFINE_CR(iipa, iipa);
+IA64_NATIVE_PATCH_DEFINE_CR(ifs, ifs);
+IA64_NATIVE_PATCH_DEFINE_CR(iim, iim);
+IA64_NATIVE_PATCH_DEFINE_CR(iha, iha);
+IA64_NATIVE_PATCH_DEFINE_CR(lid, lid);
+IA64_NATIVE_PATCH_DEFINE_CR(ivr, ivr);
+IA64_NATIVE_PATCH_DEFINE_CR(tpr, tpr);
+IA64_NATIVE_PATCH_DEFINE_CR(eoi, eoi);
+IA64_NATIVE_PATCH_DEFINE_CR(irr0, irr0);
+IA64_NATIVE_PATCH_DEFINE_CR(irr1, irr1);
+IA64_NATIVE_PATCH_DEFINE_CR(irr2, irr2);
+IA64_NATIVE_PATCH_DEFINE_CR(irr3, irr3);
+IA64_NATIVE_PATCH_DEFINE_CR(itv, itv);
+IA64_NATIVE_PATCH_DEFINE_CR(pmv, pmv);
+IA64_NATIVE_PATCH_DEFINE_CR(cmcv, cmcv);
+IA64_NATIVE_PATCH_DEFINE_CR(lrr0, lrr0);
+IA64_NATIVE_PATCH_DEFINE_CR(lrr1, lrr1);
+
+static const struct paravirt_patch_bundle_elem ia64_native_patch_bundle_elems[]
+__initdata_or_module =
+{
+#define IA64_NATIVE_PATCH_BUNDLE_ELEM(name, type) \
+ { \
+ (void*)ia64_native_ ## name ## _direct_start, \
+ (void*)ia64_native_ ## name ## _direct_end, \
+ PARAVIRT_PATCH_TYPE_ ## type, \
+ }
+
+ IA64_NATIVE_PATCH_BUNDLE_ELEM(fc, FC),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM(thash, THASH),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM(get_cpuid, GET_CPUID),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM(get_pmd, GET_PMD),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM(ptcga, PTCGA),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM(get_rr, GET_RR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM(set_rr, SET_RR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM(set_rr0_to_rr4, SET_RR0_TO_RR4),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM(ssm_i, SSM_I),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM(rsm_i, RSM_I),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM(get_psr_i, GET_PSR_I),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM(intrin_local_irq_restore,
+ INTRIN_LOCAL_IRQ_RESTORE),
+
+#define IA64_NATIVE_PATCH_BUNDLE_ELEM_GETREG(name, reg) \
+ { \
+ (void*)ia64_native_get_ ## name ## _direct_start, \
+ (void*)ia64_native_get_ ## name ## _direct_end, \
+ PARAVIRT_PATCH_TYPE_GETREG + _IA64_REG_ ## reg, \
+ }
+
+#define IA64_NATIVE_PATCH_BUNDLE_ELEM_SETREG(name, reg) \
+ { \
+ (void*)ia64_native_set_ ## name ## _direct_start, \
+ (void*)ia64_native_set_ ## name ## _direct_end, \
+ PARAVIRT_PATCH_TYPE_SETREG + _IA64_REG_ ## reg, \
+ }
+
+#define IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(name, reg) \
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_GETREG(name, reg), \
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_SETREG(name, reg) \
+
+#define IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(name, reg) \
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(ar_ ## name, AR_ ## reg)
+
+#define IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(name, reg) \
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(cr_ ## name, CR_ ## reg)
+
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_GETREG(psr, PSR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_GETREG(tp, TP),
+
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_SETREG(psr_l, PSR_L),
+
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(gp, GP),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(sp, SP),
+
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr0, AR_KR0),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr1, AR_KR1),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr2, AR_KR2),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr3, AR_KR3),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr4, AR_KR4),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr5, AR_KR5),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr6, AR_KR6),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(kr7, AR_KR7),
+
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(rsc, RSC),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(bsp, BSP),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(bspstore, BSPSTORE),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(rnat, RNAT),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fcr, FCR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(eflag, EFLAG),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(csd, CSD),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(ssd, SSD),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_REG(ar27, AR_CFLAG),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fsr, FSR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fir, FIR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fdr, FDR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(ccv, CCV),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(unat, UNAT),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(fpsr, FPSR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(itc, ITC),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(pfs, PFS),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(lc, LC),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_AR(ec, EC),
+
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(dcr, DCR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(itm, ITM),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iva, IVA),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(pta, PTA),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(ipsr, IPSR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(isr, ISR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iip, IIP),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(ifa, IFA),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(itir, ITIR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iipa, IIPA),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(ifs, IFS),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iim, IIM),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(iha, IHA),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(lid, LID),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(ivr, IVR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(tpr, TPR),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(eoi, EOI),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(irr0, IRR0),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(irr1, IRR1),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(irr2, IRR2),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(irr3, IRR3),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(itv, ITV),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(pmv, PMV),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(cmcv, CMCV),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(lrr0, LRR0),
+ IA64_NATIVE_PATCH_BUNDLE_ELEM_CR(lrr1, LRR1),
};
+
+unsigned long __init_or_module
+ia64_native_patch_bundle(void *sbundle, void *ebundle, unsigned long type)
+{
+ const unsigned long nelems = sizeof(ia64_native_patch_bundle_elems) /
+ sizeof(ia64_native_patch_bundle_elems[0]);
+
+ return __paravirt_patch_apply_bundle(sbundle, ebundle, type,
+ ia64_native_patch_bundle_elems,
+ nelems, NULL);
+}
+#endif /* ASM_SUPPOTED */
+
+extern const char ia64_native_switch_to[];
+extern const char ia64_native_leave_syscall[];
+extern const char ia64_native_work_processed_syscall[];
+extern const char ia64_native_leave_kernel[];
+
+const struct paravirt_patch_branch_target ia64_native_branch_target[]
+__initconst = {
+#define PARAVIRT_BR_TARGET(name, type) \
+ { \
+ ia64_native_ ## name, \
+ PARAVIRT_PATCH_TYPE_BR_ ## type, \
+ }
+ PARAVIRT_BR_TARGET(switch_to, SWITCH_TO),
+ PARAVIRT_BR_TARGET(leave_syscall, LEAVE_SYSCALL),
+ PARAVIRT_BR_TARGET(work_processed_syscall, WORK_PROCESSED_SYSCALL),
+ PARAVIRT_BR_TARGET(leave_kernel, LEAVE_KERNEL),
+};
+
+static void __init
+ia64_native_patch_branch(unsigned long tag, unsigned long type)
+{
+ const unsigned long nelem =
+ sizeof(ia64_native_branch_target) /
+ sizeof(ia64_native_branch_target[0]);
+ __paravirt_patch_apply_branch(tag, type,
+ ia64_native_branch_target, nelem);
+}
diff --git a/arch/ia64/kernel/paravirt_patch.c b/arch/ia64/kernel/paravirt_patch.c
new file mode 100644
index 000000000000..bfdfef1b1ffd
--- /dev/null
+++ b/arch/ia64/kernel/paravirt_patch.c
@@ -0,0 +1,514 @@
+/******************************************************************************
+ * linux/arch/ia64/xen/paravirt_patch.c
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <asm/intrinsics.h>
+#include <asm/kprobes.h>
+#include <asm/paravirt.h>
+#include <asm/paravirt_patch.h>
+
+typedef union ia64_inst {
+ struct {
+ unsigned long long qp : 6;
+ unsigned long long : 31;
+ unsigned long long opcode : 4;
+ unsigned long long reserved : 23;
+ } generic;
+ unsigned long long l;
+} ia64_inst_t;
+
+/*
+ * flush_icache_range() can't be used here.
+ * we are here before cpu_init() which initializes
+ * ia64_i_cache_stride_shift. flush_icache_range() uses it.
+ */
+void __init_or_module
+paravirt_flush_i_cache_range(const void *instr, unsigned long size)
+{
+ extern void paravirt_fc_i(const void *addr);
+ unsigned long i;
+
+ for (i = 0; i < size; i += sizeof(bundle_t))
+ paravirt_fc_i(instr + i);
+}
+
+bundle_t* __init_or_module
+paravirt_get_bundle(unsigned long tag)
+{
+ return (bundle_t *)(tag & ~3UL);
+}
+
+unsigned long __init_or_module
+paravirt_get_slot(unsigned long tag)
+{
+ return tag & 3UL;
+}
+
+unsigned long __init_or_module
+paravirt_get_num_inst(unsigned long stag, unsigned long etag)
+{
+ bundle_t *sbundle = paravirt_get_bundle(stag);
+ unsigned long sslot = paravirt_get_slot(stag);
+ bundle_t *ebundle = paravirt_get_bundle(etag);
+ unsigned long eslot = paravirt_get_slot(etag);
+
+ return (ebundle - sbundle) * 3 + eslot - sslot + 1;
+}
+
+unsigned long __init_or_module
+paravirt_get_next_tag(unsigned long tag)
+{
+ unsigned long slot = paravirt_get_slot(tag);
+
+ switch (slot) {
+ case 0:
+ case 1:
+ return tag + 1;
+ case 2: {
+ bundle_t *bundle = paravirt_get_bundle(tag);
+ return (unsigned long)(bundle + 1);
+ }
+ default:
+ BUG();
+ }
+ /* NOTREACHED */
+}
+
+ia64_inst_t __init_or_module
+paravirt_read_slot0(const bundle_t *bundle)
+{
+ ia64_inst_t inst;
+ inst.l = bundle->quad0.slot0;
+ return inst;
+}
+
+ia64_inst_t __init_or_module
+paravirt_read_slot1(const bundle_t *bundle)
+{
+ ia64_inst_t inst;
+ inst.l = bundle->quad0.slot1_p0 |
+ ((unsigned long long)bundle->quad1.slot1_p1 << 18UL);
+ return inst;
+}
+
+ia64_inst_t __init_or_module
+paravirt_read_slot2(const bundle_t *bundle)
+{
+ ia64_inst_t inst;
+ inst.l = bundle->quad1.slot2;
+ return inst;
+}
+
+ia64_inst_t __init_or_module
+paravirt_read_inst(unsigned long tag)
+{
+ bundle_t *bundle = paravirt_get_bundle(tag);
+ unsigned long slot = paravirt_get_slot(tag);
+
+ switch (slot) {
+ case 0:
+ return paravirt_read_slot0(bundle);
+ case 1:
+ return paravirt_read_slot1(bundle);
+ case 2:
+ return paravirt_read_slot2(bundle);
+ default:
+ BUG();
+ }
+ /* NOTREACHED */
+}
+
+void __init_or_module
+paravirt_write_slot0(bundle_t *bundle, ia64_inst_t inst)
+{
+ bundle->quad0.slot0 = inst.l;
+}
+
+void __init_or_module
+paravirt_write_slot1(bundle_t *bundle, ia64_inst_t inst)
+{
+ bundle->quad0.slot1_p0 = inst.l;
+ bundle->quad1.slot1_p1 = inst.l >> 18UL;
+}
+
+void __init_or_module
+paravirt_write_slot2(bundle_t *bundle, ia64_inst_t inst)
+{
+ bundle->quad1.slot2 = inst.l;
+}
+
+void __init_or_module
+paravirt_write_inst(unsigned long tag, ia64_inst_t inst)
+{
+ bundle_t *bundle = paravirt_get_bundle(tag);
+ unsigned long slot = paravirt_get_slot(tag);
+
+ switch (slot) {
+ case 0:
+ paravirt_write_slot0(bundle, inst);
+ break;
+ case 1:
+ paravirt_write_slot1(bundle, inst);
+ break;
+ case 2:
+ paravirt_write_slot2(bundle, inst);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ paravirt_flush_i_cache_range(bundle, sizeof(*bundle));
+}
+
+/* for debug */
+void
+paravirt_print_bundle(const bundle_t *bundle)
+{
+ const unsigned long *quad = (const unsigned long *)bundle;
+ ia64_inst_t slot0 = paravirt_read_slot0(bundle);
+ ia64_inst_t slot1 = paravirt_read_slot1(bundle);
+ ia64_inst_t slot2 = paravirt_read_slot2(bundle);
+
+ printk(KERN_DEBUG
+ "bundle 0x%p 0x%016lx 0x%016lx\n", bundle, quad[0], quad[1]);
+ printk(KERN_DEBUG
+ "bundle template 0x%x\n",
+ bundle->quad0.template);
+ printk(KERN_DEBUG
+ "slot0 0x%lx slot1_p0 0x%lx slot1_p1 0x%lx slot2 0x%lx\n",
+ (unsigned long)bundle->quad0.slot0,
+ (unsigned long)bundle->quad0.slot1_p0,
+ (unsigned long)bundle->quad1.slot1_p1,
+ (unsigned long)bundle->quad1.slot2);
+ printk(KERN_DEBUG
+ "slot0 0x%016llx slot1 0x%016llx slot2 0x%016llx\n",
+ slot0.l, slot1.l, slot2.l);
+}
+
+static int noreplace_paravirt __init_or_module = 0;
+
+static int __init setup_noreplace_paravirt(char *str)
+{
+ noreplace_paravirt = 1;
+ return 1;
+}
+__setup("noreplace-paravirt", setup_noreplace_paravirt);
+
+#ifdef ASM_SUPPORTED
+static void __init_or_module
+fill_nop_bundle(void *sbundle, void *ebundle)
+{
+ extern const char paravirt_nop_bundle[];
+ extern const unsigned long paravirt_nop_bundle_size;
+
+ void *bundle = sbundle;
+
+ BUG_ON((((unsigned long)sbundle) % sizeof(bundle_t)) != 0);
+ BUG_ON((((unsigned long)ebundle) % sizeof(bundle_t)) != 0);
+
+ while (bundle < ebundle) {
+ memcpy(bundle, paravirt_nop_bundle, paravirt_nop_bundle_size);
+
+ bundle += paravirt_nop_bundle_size;
+ }
+}
+
+/* helper function */
+unsigned long __init_or_module
+__paravirt_patch_apply_bundle(void *sbundle, void *ebundle, unsigned long type,
+ const struct paravirt_patch_bundle_elem *elems,
+ unsigned long nelems,
+ const struct paravirt_patch_bundle_elem **found)
+{
+ unsigned long used = 0;
+ unsigned long i;
+
+ BUG_ON((((unsigned long)sbundle) % sizeof(bundle_t)) != 0);
+ BUG_ON((((unsigned long)ebundle) % sizeof(bundle_t)) != 0);
+
+ found = NULL;
+ for (i = 0; i < nelems; i++) {
+ const struct paravirt_patch_bundle_elem *p = &elems[i];
+ if (p->type == type) {
+ unsigned long need = p->ebundle - p->sbundle;
+ unsigned long room = ebundle - sbundle;
+
+ if (found != NULL)
+ *found = p;
+
+ if (room < need) {
+ /* no room to replace. skip it */
+ printk(KERN_DEBUG
+ "the space is too small to put "
+ "bundles. type %ld need %ld room %ld\n",
+ type, need, room);
+ break;
+ }
+
+ used = need;
+ memcpy(sbundle, p->sbundle, used);
+ break;
+ }
+ }
+
+ return used;
+}
+
+void __init_or_module
+paravirt_patch_apply_bundle(const struct paravirt_patch_site_bundle *start,
+ const struct paravirt_patch_site_bundle *end)
+{
+ const struct paravirt_patch_site_bundle *p;
+
+ if (noreplace_paravirt)
+ return;
+ if (pv_init_ops.patch_bundle == NULL)
+ return;
+
+ for (p = start; p < end; p++) {
+ unsigned long used;
+
+ used = (*pv_init_ops.patch_bundle)(p->sbundle, p->ebundle,
+ p->type);
+ if (used == 0)
+ continue;
+
+ fill_nop_bundle(p->sbundle + used, p->ebundle);
+ paravirt_flush_i_cache_range(p->sbundle,
+ p->ebundle - p->sbundle);
+ }
+ ia64_sync_i();
+ ia64_srlz_i();
+}
+
+/*
+ * nop.i, nop.m, nop.f instruction are same format.
+ * but nop.b has differennt format.
+ * This doesn't support nop.b for now.
+ */
+static void __init_or_module
+fill_nop_inst(unsigned long stag, unsigned long etag)
+{
+ extern const bundle_t paravirt_nop_mfi_inst_bundle[];
+ unsigned long tag;
+ const ia64_inst_t nop_inst =
+ paravirt_read_slot0(paravirt_nop_mfi_inst_bundle);
+
+ for (tag = stag; tag < etag; tag = paravirt_get_next_tag(tag))
+ paravirt_write_inst(tag, nop_inst);
+}
+
+void __init_or_module
+paravirt_patch_apply_inst(const struct paravirt_patch_site_inst *start,
+ const struct paravirt_patch_site_inst *end)
+{
+ const struct paravirt_patch_site_inst *p;
+
+ if (noreplace_paravirt)
+ return;
+ if (pv_init_ops.patch_inst == NULL)
+ return;
+
+ for (p = start; p < end; p++) {
+ unsigned long tag;
+ bundle_t *sbundle;
+ bundle_t *ebundle;
+
+ tag = (*pv_init_ops.patch_inst)(p->stag, p->etag, p->type);
+ if (tag == p->stag)
+ continue;
+
+ fill_nop_inst(tag, p->etag);
+ sbundle = paravirt_get_bundle(p->stag);
+ ebundle = paravirt_get_bundle(p->etag) + 1;
+ paravirt_flush_i_cache_range(sbundle, (ebundle - sbundle) *
+ sizeof(bundle_t));
+ }
+ ia64_sync_i();
+ ia64_srlz_i();
+}
+#endif /* ASM_SUPPOTED */
+
+/* brl.cond.sptk.many <target64> X3 */
+typedef union inst_x3_op {
+ ia64_inst_t inst;
+ struct {
+ unsigned long qp: 6;
+ unsigned long btyp: 3;
+ unsigned long unused: 3;
+ unsigned long p: 1;
+ unsigned long imm20b: 20;
+ unsigned long wh: 2;
+ unsigned long d: 1;
+ unsigned long i: 1;
+ unsigned long opcode: 4;
+ };
+ unsigned long l;
+} inst_x3_op_t;
+
+typedef union inst_x3_imm {
+ ia64_inst_t inst;
+ struct {
+ unsigned long unused: 2;
+ unsigned long imm39: 39;
+ };
+ unsigned long l;
+} inst_x3_imm_t;
+
+void __init_or_module
+paravirt_patch_reloc_brl(unsigned long tag, const void *target)
+{
+ unsigned long tag_op = paravirt_get_next_tag(tag);
+ unsigned long tag_imm = tag;
+ bundle_t *bundle = paravirt_get_bundle(tag);
+
+ ia64_inst_t inst_op = paravirt_read_inst(tag_op);
+ ia64_inst_t inst_imm = paravirt_read_inst(tag_imm);
+
+ inst_x3_op_t inst_x3_op = { .l = inst_op.l };
+ inst_x3_imm_t inst_x3_imm = { .l = inst_imm.l };
+
+ unsigned long imm60 =
+ ((unsigned long)target - (unsigned long)bundle) >> 4;
+
+ BUG_ON(paravirt_get_slot(tag) != 1); /* MLX */
+ BUG_ON(((unsigned long)target & (sizeof(bundle_t) - 1)) != 0);
+
+ /* imm60[59] 1bit */
+ inst_x3_op.i = (imm60 >> 59) & 1;
+ /* imm60[19:0] 20bit */
+ inst_x3_op.imm20b = imm60 & ((1UL << 20) - 1);
+ /* imm60[58:20] 39bit */
+ inst_x3_imm.imm39 = (imm60 >> 20) & ((1UL << 39) - 1);
+
+ inst_op.l = inst_x3_op.l;
+ inst_imm.l = inst_x3_imm.l;
+
+ paravirt_write_inst(tag_op, inst_op);
+ paravirt_write_inst(tag_imm, inst_imm);
+}
+
+/* br.cond.sptk.many <target25> B1 */
+typedef union inst_b1 {
+ ia64_inst_t inst;
+ struct {
+ unsigned long qp: 6;
+ unsigned long btype: 3;
+ unsigned long unused: 3;
+ unsigned long p: 1;
+ unsigned long imm20b: 20;
+ unsigned long wh: 2;
+ unsigned long d: 1;
+ unsigned long s: 1;
+ unsigned long opcode: 4;
+ };
+ unsigned long l;
+} inst_b1_t;
+
+void __init
+paravirt_patch_reloc_br(unsigned long tag, const void *target)
+{
+ bundle_t *bundle = paravirt_get_bundle(tag);
+ ia64_inst_t inst = paravirt_read_inst(tag);
+ unsigned long target25 = (unsigned long)target - (unsigned long)bundle;
+ inst_b1_t inst_b1;
+
+ BUG_ON(((unsigned long)target & (sizeof(bundle_t) - 1)) != 0);
+
+ inst_b1.l = inst.l;
+ if (target25 & (1UL << 63))
+ inst_b1.s = 1;
+ else
+ inst_b1.s = 0;
+
+ inst_b1.imm20b = target25 >> 4;
+ inst.l = inst_b1.l;
+
+ paravirt_write_inst(tag, inst);
+}
+
+void __init
+__paravirt_patch_apply_branch(
+ unsigned long tag, unsigned long type,
+ const struct paravirt_patch_branch_target *entries,
+ unsigned int nr_entries)
+{
+ unsigned int i;
+ for (i = 0; i < nr_entries; i++) {
+ if (entries[i].type == type) {
+ paravirt_patch_reloc_br(tag, entries[i].entry);
+ break;
+ }
+ }
+}
+
+static void __init
+paravirt_patch_apply_branch(const struct paravirt_patch_site_branch *start,
+ const struct paravirt_patch_site_branch *end)
+{
+ const struct paravirt_patch_site_branch *p;
+
+ if (noreplace_paravirt)
+ return;
+ if (pv_init_ops.patch_branch == NULL)
+ return;
+
+ for (p = start; p < end; p++)
+ (*pv_init_ops.patch_branch)(p->tag, p->type);
+
+ ia64_sync_i();
+ ia64_srlz_i();
+}
+
+void __init
+paravirt_patch_apply(void)
+{
+ extern const char __start_paravirt_bundles[];
+ extern const char __stop_paravirt_bundles[];
+ extern const char __start_paravirt_insts[];
+ extern const char __stop_paravirt_insts[];
+ extern const char __start_paravirt_branches[];
+ extern const char __stop_paravirt_branches[];
+
+ paravirt_patch_apply_bundle((const struct paravirt_patch_site_bundle *)
+ __start_paravirt_bundles,
+ (const struct paravirt_patch_site_bundle *)
+ __stop_paravirt_bundles);
+ paravirt_patch_apply_inst((const struct paravirt_patch_site_inst *)
+ __start_paravirt_insts,
+ (const struct paravirt_patch_site_inst *)
+ __stop_paravirt_insts);
+ paravirt_patch_apply_branch((const struct paravirt_patch_site_branch *)
+ __start_paravirt_branches,
+ (const struct paravirt_patch_site_branch *)
+ __stop_paravirt_branches);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "linux"
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ */
diff --git a/arch/ia64/kernel/paravirt_patchlist.c b/arch/ia64/kernel/paravirt_patchlist.c
new file mode 100644
index 000000000000..b28082a95d45
--- /dev/null
+++ b/arch/ia64/kernel/paravirt_patchlist.c
@@ -0,0 +1,79 @@
+/******************************************************************************
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/bug.h>
+#include <asm/paravirt.h>
+
+#define DECLARE(name) \
+ extern unsigned long \
+ __ia64_native_start_gate_##name##_patchlist[]; \
+ extern unsigned long \
+ __ia64_native_end_gate_##name##_patchlist[]
+
+DECLARE(fsyscall);
+DECLARE(brl_fsys_bubble_down);
+DECLARE(vtop);
+DECLARE(mckinley_e9);
+
+extern unsigned long __start_gate_section[];
+
+#define ASSIGN(name) \
+ .start_##name##_patchlist = \
+ (unsigned long)__ia64_native_start_gate_##name##_patchlist, \
+ .end_##name##_patchlist = \
+ (unsigned long)__ia64_native_end_gate_##name##_patchlist
+
+struct pv_patchdata pv_patchdata __initdata = {
+ ASSIGN(fsyscall),
+ ASSIGN(brl_fsys_bubble_down),
+ ASSIGN(vtop),
+ ASSIGN(mckinley_e9),
+
+ .gate_section = (void*)__start_gate_section,
+};
+
+
+unsigned long __init
+paravirt_get_gate_patchlist(enum pv_gate_patchlist type)
+{
+
+#define CASE(NAME, name) \
+ case PV_GATE_START_##NAME: \
+ return pv_patchdata.start_##name##_patchlist; \
+ case PV_GATE_END_##NAME: \
+ return pv_patchdata.end_##name##_patchlist; \
+
+ switch (type) {
+ CASE(FSYSCALL, fsyscall);
+ CASE(BRL_FSYS_BUBBLE_DOWN, brl_fsys_bubble_down);
+ CASE(VTOP, vtop);
+ CASE(MCKINLEY_E9, mckinley_e9);
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+void * __init
+paravirt_get_gate_section(void)
+{
+ return pv_patchdata.gate_section;
+}
diff --git a/arch/ia64/kernel/paravirt_patchlist.h b/arch/ia64/kernel/paravirt_patchlist.h
new file mode 100644
index 000000000000..0684aa6c6507
--- /dev/null
+++ b/arch/ia64/kernel/paravirt_patchlist.h
@@ -0,0 +1,28 @@
+/******************************************************************************
+ * linux/arch/ia64/xen/paravirt_patchlist.h
+ *
+ * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
+ * VA Linux Systems Japan K.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#if defined(__IA64_GATE_PARAVIRTUALIZED_XEN)
+#include <asm/xen/patchlist.h>
+#else
+#include <asm/native/patchlist.h>
+#endif
+
diff --git a/arch/ia64/kernel/paravirtentry.S b/arch/ia64/kernel/paravirtentry.S
index 2f42fcb9776a..6158560d7f17 100644
--- a/arch/ia64/kernel/paravirtentry.S
+++ b/arch/ia64/kernel/paravirtentry.S
@@ -20,8 +20,11 @@
*
*/
+#include <linux/init.h>
#include <asm/asmmacro.h>
#include <asm/asm-offsets.h>
+#include <asm/paravirt_privop.h>
+#include <asm/paravirt_patch.h>
#include "entry.h"
#define DATA8(sym, init_value) \
@@ -32,29 +35,87 @@
data8 init_value ; \
.popsection
-#define BRANCH(targ, reg, breg) \
- movl reg=targ ; \
- ;; \
- ld8 reg=[reg] ; \
- ;; \
- mov breg=reg ; \
+#define BRANCH(targ, reg, breg, type) \
+ PARAVIRT_PATCH_SITE_BR(PARAVIRT_PATCH_TYPE_BR_ ## type) ; \
+ ;; \
+ movl reg=targ ; \
+ ;; \
+ ld8 reg=[reg] ; \
+ ;; \
+ mov breg=reg ; \
br.cond.sptk.many breg
-#define BRANCH_PROC(sym, reg, breg) \
- DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \
- GLOBAL_ENTRY(paravirt_ ## sym) ; \
- BRANCH(paravirt_ ## sym ## _targ, reg, breg) ; \
+#define BRANCH_PROC(sym, reg, breg, type) \
+ DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \
+ GLOBAL_ENTRY(paravirt_ ## sym) ; \
+ BRANCH(paravirt_ ## sym ## _targ, reg, breg, type) ; \
END(paravirt_ ## sym)
-#define BRANCH_PROC_UNWINFO(sym, reg, breg) \
- DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \
- GLOBAL_ENTRY(paravirt_ ## sym) ; \
- PT_REGS_UNWIND_INFO(0) ; \
- BRANCH(paravirt_ ## sym ## _targ, reg, breg) ; \
+#define BRANCH_PROC_UNWINFO(sym, reg, breg, type) \
+ DATA8(paravirt_ ## sym ## _targ, ia64_native_ ## sym) ; \
+ GLOBAL_ENTRY(paravirt_ ## sym) ; \
+ PT_REGS_UNWIND_INFO(0) ; \
+ BRANCH(paravirt_ ## sym ## _targ, reg, breg, type) ; \
END(paravirt_ ## sym)
-BRANCH_PROC(switch_to, r22, b7)
-BRANCH_PROC_UNWINFO(leave_syscall, r22, b7)
-BRANCH_PROC(work_processed_syscall, r2, b7)
-BRANCH_PROC_UNWINFO(leave_kernel, r22, b7)
+BRANCH_PROC(switch_to, r22, b7, SWITCH_TO)
+BRANCH_PROC_UNWINFO(leave_syscall, r22, b7, LEAVE_SYSCALL)
+BRANCH_PROC(work_processed_syscall, r2, b7, WORK_PROCESSED_SYSCALL)
+BRANCH_PROC_UNWINFO(leave_kernel, r22, b7, LEAVE_KERNEL)
+
+
+#ifdef CONFIG_MODULES
+#define __INIT_OR_MODULE .text
+#define __INITDATA_OR_MODULE .data
+#else
+#define __INIT_OR_MODULE __INIT
+#define __INITDATA_OR_MODULE __INITDATA
+#endif /* CONFIG_MODULES */
+
+ __INIT_OR_MODULE
+ GLOBAL_ENTRY(paravirt_fc_i)
+ fc.i r32
+ br.ret.sptk.many rp
+ END(paravirt_fc_i)
+ __FINIT
+
+ __INIT_OR_MODULE
+ .align 32
+ GLOBAL_ENTRY(paravirt_nop_b_inst_bundle)
+ {
+ nop.b 0
+ nop.b 0
+ nop.b 0
+ }
+ END(paravirt_nop_b_inst_bundle)
+ __FINIT
+
+ /* NOTE: nop.[mfi] has same format */
+ __INIT_OR_MODULE
+ GLOBAL_ENTRY(paravirt_nop_mfi_inst_bundle)
+ {
+ nop.m 0
+ nop.f 0
+ nop.i 0
+ }
+ END(paravirt_nop_mfi_inst_bundle)
+ __FINIT
+
+ __INIT_OR_MODULE
+ GLOBAL_ENTRY(paravirt_nop_bundle)
+paravirt_nop_bundle_start:
+ {
+ nop 0
+ nop 0
+ nop 0
+ }
+paravirt_nop_bundle_end:
+ END(paravirt_nop_bundle)
+ __FINIT
+
+ __INITDATA_OR_MODULE
+ .align 8
+ .global paravirt_nop_bundle_size
+paravirt_nop_bundle_size:
+ data8 paravirt_nop_bundle_end - paravirt_nop_bundle_start
diff --git a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c
index b83b2c516008..68a1311db806 100644
--- a/arch/ia64/kernel/patch.c
+++ b/arch/ia64/kernel/patch.c
@@ -7,6 +7,7 @@
#include <linux/init.h>
#include <linux/string.h>
+#include <asm/paravirt.h>
#include <asm/patch.h>
#include <asm/processor.h>
#include <asm/sections.h>
@@ -169,16 +170,35 @@ ia64_patch_mckinley_e9 (unsigned long start, unsigned long end)
ia64_srlz_i();
}
+extern unsigned long ia64_native_fsyscall_table[NR_syscalls];
+extern char ia64_native_fsys_bubble_down[];
+struct pv_fsys_data pv_fsys_data __initdata = {
+ .fsyscall_table = (unsigned long *)ia64_native_fsyscall_table,
+ .fsys_bubble_down = (void *)ia64_native_fsys_bubble_down,
+};
+
+unsigned long * __init
+paravirt_get_fsyscall_table(void)
+{
+ return pv_fsys_data.fsyscall_table;
+}
+
+char * __init
+paravirt_get_fsys_bubble_down(void)
+{
+ return pv_fsys_data.fsys_bubble_down;
+}
+
static void __init
patch_fsyscall_table (unsigned long start, unsigned long end)
{
- extern unsigned long fsyscall_table[NR_syscalls];
+ u64 fsyscall_table = (u64)paravirt_get_fsyscall_table();
s32 *offp = (s32 *) start;
u64 ip;
while (offp < (s32 *) end) {
ip = (u64) ia64_imva((char *) offp + *offp);
- ia64_patch_imm64(ip, (u64) fsyscall_table);
+ ia64_patch_imm64(ip, fsyscall_table);
ia64_fc((void *) ip);
++offp;
}
@@ -189,7 +209,7 @@ patch_fsyscall_table (unsigned long start, unsigned long end)
static void __init
patch_brl_fsys_bubble_down (unsigned long start, unsigned long end)
{
- extern char fsys_bubble_down[];
+ u64 fsys_bubble_down = (u64)paravirt_get_fsys_bubble_down();
s32 *offp = (s32 *) start;
u64 ip;
@@ -207,13 +227,13 @@ patch_brl_fsys_bubble_down (unsigned long start, unsigned long end)
void __init
ia64_patch_gate (void)
{
-# define START(name) ((unsigned long) __start_gate_##name##_patchlist)
-# define END(name) ((unsigned long)__end_gate_##name##_patchlist)
+# define START(name) paravirt_get_gate_patchlist(PV_GATE_START_##name)
+# define END(name) paravirt_get_gate_patchlist(PV_GATE_END_##name)
- patch_fsyscall_table(START(fsyscall), END(fsyscall));
- patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down));
- ia64_patch_vtop(START(vtop), END(vtop));
- ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9));
+ patch_fsyscall_table(START(FSYSCALL), END(FSYSCALL));
+ patch_brl_fsys_bubble_down(START(BRL_FSYS_BUBBLE_DOWN), END(BRL_FSYS_BUBBLE_DOWN));
+ ia64_patch_vtop(START(VTOP), END(VTOP));
+ ia64_patch_mckinley_e9(START(MCKINLEY_E9), END(MCKINLEY_E9));
}
void ia64_patch_phys_stack_reg(unsigned long val)
@@ -229,7 +249,7 @@ void ia64_patch_phys_stack_reg(unsigned long val)
while (offp < end) {
ip = (u64) offp + *offp;
ia64_patch(ip, mask, imm);
- ia64_fc(ip);
+ ia64_fc((void *)ip);
++offp;
}
ia64_sync_i();
diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c
index d0ada067a4af..e4cb443bb988 100644
--- a/arch/ia64/kernel/pci-dma.c
+++ b/arch/ia64/kernel/pci-dma.c
@@ -32,9 +32,6 @@ int force_iommu __read_mostly = 1;
int force_iommu __read_mostly;
#endif
-/* Set this to 1 if there is a HW IOMMU in the system */
-int iommu_detected __read_mostly;
-
/* Dummy device used for NULL arguments (normally ISA). Better would
be probably a smaller DMA mask, but this is bug-to-bug compatible
to i386. */
@@ -44,18 +41,7 @@ struct device fallback_dev = {
.dma_mask = &fallback_dev.coherent_dma_mask,
};
-void __init pci_iommu_alloc(void)
-{
- /*
- * The order of these functions is important for
- * fall-back/fail-over reasons
- */
- detect_intel_iommu();
-
-#ifdef CONFIG_SWIOTLB
- pci_swiotlb_init();
-#endif
-}
+extern struct dma_map_ops intel_dma_ops;
static int __init pci_iommu_init(void)
{
@@ -79,15 +65,12 @@ iommu_dma_init(void)
return;
}
-struct dma_mapping_ops *dma_ops;
-EXPORT_SYMBOL(dma_ops);
-
int iommu_dma_supported(struct device *dev, u64 mask)
{
- struct dma_mapping_ops *ops = get_dma_ops(dev);
+ struct dma_map_ops *ops = platform_dma_get_ops(dev);
- if (ops->dma_supported_op)
- return ops->dma_supported_op(dev, mask);
+ if (ops->dma_supported)
+ return ops->dma_supported(dev, mask);
/* Copied from i386. Doesn't make much sense, because it will
only work for pci_alloc_coherent.
@@ -116,4 +99,25 @@ int iommu_dma_supported(struct device *dev, u64 mask)
}
EXPORT_SYMBOL(iommu_dma_supported);
+void __init pci_iommu_alloc(void)
+{
+ dma_ops = &intel_dma_ops;
+
+ dma_ops->sync_single_for_cpu = machvec_dma_sync_single;
+ dma_ops->sync_sg_for_cpu = machvec_dma_sync_sg;
+ dma_ops->sync_single_for_device = machvec_dma_sync_single;
+ dma_ops->sync_sg_for_device = machvec_dma_sync_sg;
+ dma_ops->dma_supported = iommu_dma_supported;
+
+ /*
+ * The order of these functions is important for
+ * fall-back/fail-over reasons
+ */
+ detect_intel_iommu();
+
+#ifdef CONFIG_SWIOTLB
+ pci_swiotlb_init();
+#endif
+}
+
#endif
diff --git a/arch/ia64/kernel/pci-swiotlb.c b/arch/ia64/kernel/pci-swiotlb.c
index 16c50516dbc1..573f02c39a00 100644
--- a/arch/ia64/kernel/pci-swiotlb.c
+++ b/arch/ia64/kernel/pci-swiotlb.c
@@ -13,23 +13,37 @@
int swiotlb __read_mostly;
EXPORT_SYMBOL(swiotlb);
-struct dma_mapping_ops swiotlb_dma_ops = {
- .mapping_error = swiotlb_dma_mapping_error,
- .alloc_coherent = swiotlb_alloc_coherent,
+static void *ia64_swiotlb_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
+{
+ if (dev->coherent_dma_mask != DMA_64BIT_MASK)
+ gfp |= GFP_DMA;
+ return swiotlb_alloc_coherent(dev, size, dma_handle, gfp);
+}
+
+struct dma_map_ops swiotlb_dma_ops = {
+ .alloc_coherent = ia64_swiotlb_alloc_coherent,
.free_coherent = swiotlb_free_coherent,
- .map_single = swiotlb_map_single,
- .unmap_single = swiotlb_unmap_single,
+ .map_page = swiotlb_map_page,
+ .unmap_page = swiotlb_unmap_page,
+ .map_sg = swiotlb_map_sg_attrs,
+ .unmap_sg = swiotlb_unmap_sg_attrs,
.sync_single_for_cpu = swiotlb_sync_single_for_cpu,
.sync_single_for_device = swiotlb_sync_single_for_device,
.sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
.sync_single_range_for_device = swiotlb_sync_single_range_for_device,
.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
.sync_sg_for_device = swiotlb_sync_sg_for_device,
- .map_sg = swiotlb_map_sg,
- .unmap_sg = swiotlb_unmap_sg,
- .dma_supported_op = swiotlb_dma_supported,
+ .dma_supported = swiotlb_dma_supported,
+ .mapping_error = swiotlb_dma_mapping_error,
};
+void __init swiotlb_dma_init(void)
+{
+ dma_ops = &swiotlb_dma_ops;
+ swiotlb_init();
+}
+
void __init pci_swiotlb_init(void)
{
if (!iommu_detected) {
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 0e499757309b..8a06dc480594 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2196,7 +2196,7 @@ pfmfs_delete_dentry(struct dentry *dentry)
return 1;
}
-static struct dentry_operations pfmfs_dentry_operations = {
+static const struct dentry_operations pfmfs_dentry_operations = {
.d_delete = pfmfs_delete_dentry,
};
@@ -5603,7 +5603,7 @@ pfm_interrupt_handler(int irq, void *arg)
* /proc/perfmon interface, for debug only
*/
-#define PFM_PROC_SHOW_HEADER ((void *)NR_CPUS+1)
+#define PFM_PROC_SHOW_HEADER ((void *)nr_cpu_ids+1)
static void *
pfm_proc_start(struct seq_file *m, loff_t *pos)
@@ -5612,7 +5612,7 @@ pfm_proc_start(struct seq_file *m, loff_t *pos)
return PFM_PROC_SHOW_HEADER;
}
- while (*pos <= NR_CPUS) {
+ while (*pos <= nr_cpu_ids) {
if (cpu_online(*pos - 1)) {
return (void *)*pos;
}
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index c57162705147..5d7c0e5b9e76 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -413,7 +413,7 @@ ia64_load_extra (struct task_struct *task)
* so there is nothing to worry about.
*/
int
-copy_thread (int nr, unsigned long clone_flags,
+copy_thread(unsigned long clone_flags,
unsigned long user_stack_base, unsigned long user_stack_size,
struct task_struct *p, struct pt_regs *regs)
{
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
index ecb9eb78d687..7053c55b7649 100644
--- a/arch/ia64/kernel/salinfo.c
+++ b/arch/ia64/kernel/salinfo.c
@@ -317,7 +317,7 @@ retry:
}
n = data->cpu_check;
- for (i = 0; i < NR_CPUS; i++) {
+ for (i = 0; i < nr_cpu_ids; i++) {
if (cpu_isset(n, data->cpu_event)) {
if (!cpu_online(n)) {
cpu_clear(n, data->cpu_event);
@@ -326,7 +326,7 @@ retry:
cpu = n;
break;
}
- if (++n == NR_CPUS)
+ if (++n == nr_cpu_ids)
n = 0;
}
@@ -337,7 +337,7 @@ retry:
/* for next read, start checking at next CPU */
data->cpu_check = cpu;
- if (++data->cpu_check == NR_CPUS)
+ if (++data->cpu_check == nr_cpu_ids)
data->cpu_check = 0;
snprintf(cmd, sizeof(cmd), "read %d\n", cpu);
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 865af27c7737..714066aeda7f 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -52,6 +52,7 @@
#include <asm/meminit.h>
#include <asm/page.h>
#include <asm/paravirt.h>
+#include <asm/paravirt_patch.h>
#include <asm/patch.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
@@ -537,6 +538,7 @@ setup_arch (char **cmdline_p)
paravirt_arch_setup_early();
ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist);
+ paravirt_patch_apply();
*cmdline_p = __va(ia64_boot_param->command_line);
strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
@@ -730,10 +732,10 @@ static void *
c_start (struct seq_file *m, loff_t *pos)
{
#ifdef CONFIG_SMP
- while (*pos < NR_CPUS && !cpu_isset(*pos, cpu_online_map))
+ while (*pos < nr_cpu_ids && !cpu_online(*pos))
++*pos;
#endif
- return *pos < NR_CPUS ? cpu_data(*pos) : NULL;
+ return *pos < nr_cpu_ids ? cpu_data(*pos) : NULL;
}
static void *
@@ -1016,8 +1018,7 @@ cpu_init (void)
| IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC));
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
- if (current->mm)
- BUG();
+ BUG_ON(current->mm);
ia64_mmu_init(ia64_imva(cpu_data));
ia64_mca_cpu_init(ia64_imva(cpu_data));
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
index da8f020d82c1..2ea4199d9c57 100644
--- a/arch/ia64/kernel/smp.c
+++ b/arch/ia64/kernel/smp.c
@@ -166,11 +166,11 @@ send_IPI_allbutself (int op)
* Called with preemption disabled.
*/
static inline void
-send_IPI_mask(cpumask_t mask, int op)
+send_IPI_mask(const struct cpumask *mask, int op)
{
unsigned int cpu;
- for_each_cpu_mask(cpu, mask) {
+ for_each_cpu(cpu, mask) {
send_IPI_single(cpu, op);
}
}
@@ -316,7 +316,7 @@ void arch_send_call_function_single_ipi(int cpu)
send_IPI_single(cpu, IPI_CALL_FUNC_SINGLE);
}
-void arch_send_call_function_ipi(cpumask_t mask)
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
{
send_IPI_mask(mask, IPI_CALL_FUNC);
}
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 52290547c85b..7700e23034bb 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -581,14 +581,14 @@ smp_build_cpu_map (void)
ia64_cpu_to_sapicid[0] = boot_cpu_id;
cpus_clear(cpu_present_map);
- cpu_set(0, cpu_present_map);
- cpu_set(0, cpu_possible_map);
+ set_cpu_present(0, true);
+ set_cpu_possible(0, true);
for (cpu = 1, i = 0; i < smp_boot_data.cpu_count; i++) {
sapicid = smp_boot_data.cpu_phys_id[i];
if (sapicid == boot_cpu_id)
continue;
- cpu_set(cpu, cpu_present_map);
- cpu_set(cpu, cpu_possible_map);
+ set_cpu_present(cpu, true);
+ set_cpu_possible(cpu, true);
ia64_cpu_to_sapicid[cpu] = sapicid;
cpu++;
}
@@ -626,12 +626,9 @@ smp_prepare_cpus (unsigned int max_cpus)
*/
if (!max_cpus) {
printk(KERN_INFO "SMP mode deactivated.\n");
- cpus_clear(cpu_online_map);
- cpus_clear(cpu_present_map);
- cpus_clear(cpu_possible_map);
- cpu_set(0, cpu_online_map);
- cpu_set(0, cpu_present_map);
- cpu_set(0, cpu_possible_map);
+ init_cpu_online(cpumask_of(0));
+ init_cpu_present(cpumask_of(0));
+ init_cpu_possible(cpumask_of(0));
return;
}
}
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index f0ebb342409d..641c8b61c4f1 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -20,6 +20,7 @@
#include <linux/efi.h>
#include <linux/timex.h>
#include <linux/clocksource.h>
+#include <linux/platform_device.h>
#include <asm/machvec.h>
#include <asm/delay.h>
@@ -50,6 +51,15 @@ EXPORT_SYMBOL(last_cli_ip);
#endif
#ifdef CONFIG_PARAVIRT
+/* We need to define a real function for sched_clock, to override the
+ weak default version */
+unsigned long long sched_clock(void)
+{
+ return paravirt_sched_clock();
+}
+#endif
+
+#ifdef CONFIG_PARAVIRT
static void
paravirt_clocksource_resume(void)
{
@@ -405,6 +415,21 @@ static struct irqaction timer_irqaction = {
.name = "timer"
};
+static struct platform_device rtc_efi_dev = {
+ .name = "rtc-efi",
+ .id = -1,
+};
+
+static int __init rtc_init(void)
+{
+ if (platform_device_register(&rtc_efi_dev) < 0)
+ printk(KERN_ERR "unable to register rtc device...\n");
+
+ /* not necessarily an error */
+ return 0;
+}
+module_init(rtc_init);
+
void __init
time_init (void)
{
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index f45e4e508eca..4a95e86b9ac2 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -169,6 +169,30 @@ SECTIONS
__end___mckinley_e9_bundles = .;
}
+#if defined(CONFIG_PARAVIRT)
+ . = ALIGN(16);
+ .paravirt_bundles : AT(ADDR(.paravirt_bundles) - LOAD_OFFSET)
+ {
+ __start_paravirt_bundles = .;
+ *(.paravirt_bundles)
+ __stop_paravirt_bundles = .;
+ }
+ . = ALIGN(16);
+ .paravirt_insts : AT(ADDR(.paravirt_insts) - LOAD_OFFSET)
+ {
+ __start_paravirt_insts = .;
+ *(.paravirt_insts)
+ __stop_paravirt_insts = .;
+ }
+ . = ALIGN(16);
+ .paravirt_branches : AT(ADDR(.paravirt_branches) - LOAD_OFFSET)
+ {
+ __start_paravirt_branches = .;
+ *(.paravirt_branches)
+ __stop_paravirt_branches = .;
+ }
+#endif
+
#if defined(CONFIG_IA64_GENERIC)
/* Machine Vector */
. = ALIGN(16);
@@ -201,6 +225,12 @@ SECTIONS
__start_gate_section = .;
*(.data.gate)
__stop_gate_section = .;
+#ifdef CONFIG_XEN
+ . = ALIGN(PAGE_SIZE);
+ __xen_start_gate_section = .;
+ *(.data.gate.xen)
+ __xen_stop_gate_section = .;
+#endif
}
. = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose
* kernel data
@@ -213,17 +243,9 @@ SECTIONS
{ *(.data.cacheline_aligned) }
/* Per-cpu data: */
- percpu : { } :percpu
. = ALIGN(PERCPU_PAGE_SIZE);
- __phys_per_cpu_start = .;
- .data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - LOAD_OFFSET)
- {
- __per_cpu_start = .;
- *(.data.percpu.page_aligned)
- *(.data.percpu)
- *(.data.percpu.shared_aligned)
- __per_cpu_end = .;
- }
+ PERCPU_VADDR(PERCPU_ADDR, :percpu)
+ __phys_per_cpu_start = __per_cpu_load;
. = __phys_per_cpu_start + PERCPU_PAGE_SIZE; /* ensure percpu data fits
* into percpu page size
*/
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig
index f833a0b4188d..0a2d6b86075a 100644
--- a/arch/ia64/kvm/Kconfig
+++ b/arch/ia64/kvm/Kconfig
@@ -4,6 +4,10 @@
config HAVE_KVM
bool
+config HAVE_KVM_IRQCHIP
+ bool
+ default y
+
menuconfig VIRTUALIZATION
bool "Virtualization"
depends on HAVE_KVM || IA64
diff --git a/arch/ia64/kvm/irq.h b/arch/ia64/kvm/irq.h
index c6786e8b1bf4..c0785a728271 100644
--- a/arch/ia64/kvm/irq.h
+++ b/arch/ia64/kvm/irq.h
@@ -23,6 +23,8 @@
#ifndef __IRQ_H
#define __IRQ_H
+#include "lapic.h"
+
static inline int irqchip_in_kernel(struct kvm *kvm)
{
return 1;
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index 28f982045f29..28af6a731bb8 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -70,7 +70,7 @@ static void kvm_flush_icache(unsigned long start, unsigned long len)
int l;
for (l = 0; l < (len + 32); l += 32)
- ia64_fc(start + l);
+ ia64_fc((void *)(start + l));
ia64_sync_i();
ia64_srlz_i();
@@ -182,7 +182,7 @@ int kvm_dev_ioctl_check_extension(long ext)
switch (ext) {
case KVM_CAP_IRQCHIP:
case KVM_CAP_MP_STATE:
-
+ case KVM_CAP_IRQ_INJECT_STATUS:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
@@ -314,7 +314,7 @@ static struct kvm_vcpu *lid_to_vcpu(struct kvm *kvm, unsigned long id,
union ia64_lid lid;
int i;
- for (i = 0; i < KVM_MAX_VCPUS; i++) {
+ for (i = 0; i < kvm->arch.online_vcpus; i++) {
if (kvm->vcpus[i]) {
lid.val = VCPU_LID(kvm->vcpus[i]);
if (lid.id == id && lid.eid == eid)
@@ -388,7 +388,7 @@ static int handle_global_purge(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
call_data.ptc_g_data = p->u.ptc_g_data;
- for (i = 0; i < KVM_MAX_VCPUS; i++) {
+ for (i = 0; i < kvm->arch.online_vcpus; i++) {
if (!kvm->vcpus[i] || kvm->vcpus[i]->arch.mp_state ==
KVM_MP_STATE_UNINITIALIZED ||
vcpu == kvm->vcpus[i])
@@ -788,6 +788,8 @@ struct kvm *kvm_arch_create_vm(void)
return ERR_PTR(-ENOMEM);
kvm_init_vm(kvm);
+ kvm->arch.online_vcpus = 0;
+
return kvm;
}
@@ -919,7 +921,13 @@ long kvm_arch_vm_ioctl(struct file *filp,
r = kvm_ioapic_init(kvm);
if (r)
goto out;
+ r = kvm_setup_default_irq_routing(kvm);
+ if (r) {
+ kfree(kvm->arch.vioapic);
+ goto out;
+ }
break;
+ case KVM_IRQ_LINE_STATUS:
case KVM_IRQ_LINE: {
struct kvm_irq_level irq_event;
@@ -927,10 +935,17 @@ long kvm_arch_vm_ioctl(struct file *filp,
if (copy_from_user(&irq_event, argp, sizeof irq_event))
goto out;
if (irqchip_in_kernel(kvm)) {
+ __s32 status;
mutex_lock(&kvm->lock);
- kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
+ status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
irq_event.irq, irq_event.level);
mutex_unlock(&kvm->lock);
+ if (ioctl == KVM_IRQ_LINE_STATUS) {
+ irq_event.status = status;
+ if (copy_to_user(argp, &irq_event,
+ sizeof irq_event))
+ goto out;
+ }
r = 0;
}
break;
@@ -1149,7 +1164,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
/*Initialize itc offset for vcpus*/
itc_offset = 0UL - ia64_getreg(_IA64_REG_AR_ITC);
- for (i = 0; i < KVM_MAX_VCPUS; i++) {
+ for (i = 0; i < kvm->arch.online_vcpus; i++) {
v = (struct kvm_vcpu *)((char *)vcpu +
sizeof(struct kvm_vcpu_data) * i);
v->arch.itc_offset = itc_offset;
@@ -1283,6 +1298,8 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
goto fail;
}
+ kvm->arch.online_vcpus++;
+
return vcpu;
fail:
return ERR_PTR(r);
@@ -1303,8 +1320,8 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
return -EINVAL;
}
-int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
- struct kvm_debug_guest *dbg)
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+ struct kvm_guest_debug *dbg)
{
return -EINVAL;
}
@@ -1421,6 +1438,23 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
return 0;
}
+int kvm_arch_vcpu_ioctl_get_stack(struct kvm_vcpu *vcpu,
+ struct kvm_ia64_vcpu_stack *stack)
+{
+ memcpy(stack, vcpu, sizeof(struct kvm_ia64_vcpu_stack));
+ return 0;
+}
+
+int kvm_arch_vcpu_ioctl_set_stack(struct kvm_vcpu *vcpu,
+ struct kvm_ia64_vcpu_stack *stack)
+{
+ memcpy(vcpu + 1, &stack->stack[0] + sizeof(struct kvm_vcpu),
+ sizeof(struct kvm_ia64_vcpu_stack) - sizeof(struct kvm_vcpu));
+
+ vcpu->arch.exit_data = ((struct kvm_vcpu *)stack)->arch.exit_data;
+ return 0;
+}
+
void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
{
@@ -1430,9 +1464,78 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
long kvm_arch_vcpu_ioctl(struct file *filp,
- unsigned int ioctl, unsigned long arg)
+ unsigned int ioctl, unsigned long arg)
{
- return -EINVAL;
+ struct kvm_vcpu *vcpu = filp->private_data;
+ void __user *argp = (void __user *)arg;
+ struct kvm_ia64_vcpu_stack *stack = NULL;
+ long r;
+
+ switch (ioctl) {
+ case KVM_IA64_VCPU_GET_STACK: {
+ struct kvm_ia64_vcpu_stack __user *user_stack;
+ void __user *first_p = argp;
+
+ r = -EFAULT;
+ if (copy_from_user(&user_stack, first_p, sizeof(void *)))
+ goto out;
+
+ if (!access_ok(VERIFY_WRITE, user_stack,
+ sizeof(struct kvm_ia64_vcpu_stack))) {
+ printk(KERN_INFO "KVM_IA64_VCPU_GET_STACK: "
+ "Illegal user destination address for stack\n");
+ goto out;
+ }
+ stack = kzalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL);
+ if (!stack) {
+ r = -ENOMEM;
+ goto out;
+ }
+
+ r = kvm_arch_vcpu_ioctl_get_stack(vcpu, stack);
+ if (r)
+ goto out;
+
+ if (copy_to_user(user_stack, stack,
+ sizeof(struct kvm_ia64_vcpu_stack)))
+ goto out;
+
+ break;
+ }
+ case KVM_IA64_VCPU_SET_STACK: {
+ struct kvm_ia64_vcpu_stack __user *user_stack;
+ void __user *first_p = argp;
+
+ r = -EFAULT;
+ if (copy_from_user(&user_stack, first_p, sizeof(void *)))
+ goto out;
+
+ if (!access_ok(VERIFY_READ, user_stack,
+ sizeof(struct kvm_ia64_vcpu_stack))) {
+ printk(KERN_INFO "KVM_IA64_VCPU_SET_STACK: "
+ "Illegal user address for stack\n");
+ goto out;
+ }
+ stack = kmalloc(sizeof(struct kvm_ia64_vcpu_stack), GFP_KERNEL);
+ if (!stack) {
+ r = -ENOMEM;
+ goto out;
+ }
+ if (copy_from_user(stack, user_stack,
+ sizeof(struct kvm_ia64_vcpu_stack)))
+ goto out;
+
+ r = kvm_arch_vcpu_ioctl_set_stack(vcpu, stack);
+ break;
+ }
+
+ default:
+ r = -EINVAL;
+ }
+
+out:
+ kfree(stack);
+ return r;
}
int kvm_arch_set_memory_region(struct kvm *kvm,
@@ -1472,7 +1575,7 @@ void kvm_arch_flush_shadow(struct kvm *kvm)
}
long kvm_arch_dev_ioctl(struct file *filp,
- unsigned int ioctl, unsigned long arg)
+ unsigned int ioctl, unsigned long arg)
{
return -EINVAL;
}
@@ -1737,7 +1840,7 @@ struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector,
struct kvm_vcpu *lvcpu = kvm->vcpus[0];
int i;
- for (i = 1; i < KVM_MAX_VCPUS; i++) {
+ for (i = 1; i < kvm->arch.online_vcpus; i++) {
if (!kvm->vcpus[i])
continue;
if (lvcpu->arch.xtp > kvm->vcpus[i]->arch.xtp)
diff --git a/arch/ia64/kvm/kvm_fw.c b/arch/ia64/kvm/kvm_fw.c
index cb7600bdff9d..a8ae52ed5635 100644
--- a/arch/ia64/kvm/kvm_fw.c
+++ b/arch/ia64/kvm/kvm_fw.c
@@ -227,6 +227,18 @@ static struct ia64_pal_retval pal_proc_get_features(struct kvm_vcpu *vcpu)
return result;
}
+static struct ia64_pal_retval pal_register_info(struct kvm_vcpu *vcpu)
+{
+
+ struct ia64_pal_retval result = {0, 0, 0, 0};
+ long in0, in1, in2, in3;
+
+ kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
+ result.status = ia64_pal_register_info(in1, &result.v1, &result.v2);
+
+ return result;
+}
+
static struct ia64_pal_retval pal_cache_info(struct kvm_vcpu *vcpu)
{
@@ -268,8 +280,12 @@ static struct ia64_pal_retval pal_vm_summary(struct kvm_vcpu *vcpu)
static struct ia64_pal_retval pal_vm_info(struct kvm_vcpu *vcpu)
{
struct ia64_pal_retval result;
+ unsigned long in0, in1, in2, in3;
- INIT_PAL_STATUS_UNIMPLEMENTED(result);
+ kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
+
+ result.status = ia64_pal_vm_info(in1, in2,
+ (pal_tc_info_u_t *)&result.v1, &result.v2);
return result;
}
@@ -292,6 +308,108 @@ static void prepare_for_halt(struct kvm_vcpu *vcpu)
vcpu->arch.timer_fired = 0;
}
+static struct ia64_pal_retval pal_perf_mon_info(struct kvm_vcpu *vcpu)
+{
+ long status;
+ unsigned long in0, in1, in2, in3, r9;
+ unsigned long pm_buffer[16];
+
+ kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
+ status = ia64_pal_perf_mon_info(pm_buffer,
+ (pal_perf_mon_info_u_t *) &r9);
+ if (status != 0) {
+ printk(KERN_DEBUG"PAL_PERF_MON_INFO fails ret=%ld\n", status);
+ } else {
+ if (in1)
+ memcpy((void *)in1, pm_buffer, sizeof(pm_buffer));
+ else {
+ status = PAL_STATUS_EINVAL;
+ printk(KERN_WARNING"Invalid parameters "
+ "for PAL call:0x%lx!\n", in0);
+ }
+ }
+ return (struct ia64_pal_retval){status, r9, 0, 0};
+}
+
+static struct ia64_pal_retval pal_halt_info(struct kvm_vcpu *vcpu)
+{
+ unsigned long in0, in1, in2, in3;
+ long status;
+ unsigned long res = 1000UL | (1000UL << 16) | (10UL << 32)
+ | (1UL << 61) | (1UL << 60);
+
+ kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
+ if (in1) {
+ memcpy((void *)in1, &res, sizeof(res));
+ status = 0;
+ } else{
+ status = PAL_STATUS_EINVAL;
+ printk(KERN_WARNING"Invalid parameters "
+ "for PAL call:0x%lx!\n", in0);
+ }
+
+ return (struct ia64_pal_retval){status, 0, 0, 0};
+}
+
+static struct ia64_pal_retval pal_mem_attrib(struct kvm_vcpu *vcpu)
+{
+ unsigned long r9;
+ long status;
+
+ status = ia64_pal_mem_attrib(&r9);
+
+ return (struct ia64_pal_retval){status, r9, 0, 0};
+}
+
+static void remote_pal_prefetch_visibility(void *v)
+{
+ s64 trans_type = (s64)v;
+ ia64_pal_prefetch_visibility(trans_type);
+}
+
+static struct ia64_pal_retval pal_prefetch_visibility(struct kvm_vcpu *vcpu)
+{
+ struct ia64_pal_retval result = {0, 0, 0, 0};
+ unsigned long in0, in1, in2, in3;
+ kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
+ result.status = ia64_pal_prefetch_visibility(in1);
+ if (result.status == 0) {
+ /* Must be performed on all remote processors
+ in the coherence domain. */
+ smp_call_function(remote_pal_prefetch_visibility,
+ (void *)in1, 1);
+ /* Unnecessary on remote processor for other vcpus!*/
+ result.status = 1;
+ }
+ return result;
+}
+
+static void remote_pal_mc_drain(void *v)
+{
+ ia64_pal_mc_drain();
+}
+
+static struct ia64_pal_retval pal_get_brand_info(struct kvm_vcpu *vcpu)
+{
+ struct ia64_pal_retval result = {0, 0, 0, 0};
+ unsigned long in0, in1, in2, in3;
+
+ kvm_get_pal_call_data(vcpu, &in0, &in1, &in2, &in3);
+
+ if (in1 == 0 && in2) {
+ char brand_info[128];
+ result.status = ia64_pal_get_brand_info(brand_info);
+ if (result.status == PAL_STATUS_SUCCESS)
+ memcpy((void *)in2, brand_info, 128);
+ } else {
+ result.status = PAL_STATUS_REQUIRES_MEMORY;
+ printk(KERN_WARNING"Invalid parameters for "
+ "PAL call:0x%lx!\n", in0);
+ }
+
+ return result;
+}
+
int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
@@ -300,14 +418,22 @@ int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *run)
int ret = 1;
gr28 = kvm_get_pal_call_index(vcpu);
- /*printk("pal_call index:%lx\n",gr28);*/
switch (gr28) {
case PAL_CACHE_FLUSH:
result = pal_cache_flush(vcpu);
break;
+ case PAL_MEM_ATTRIB:
+ result = pal_mem_attrib(vcpu);
+ break;
case PAL_CACHE_SUMMARY:
result = pal_cache_summary(vcpu);
break;
+ case PAL_PERF_MON_INFO:
+ result = pal_perf_mon_info(vcpu);
+ break;
+ case PAL_HALT_INFO:
+ result = pal_halt_info(vcpu);
+ break;
case PAL_HALT_LIGHT:
{
INIT_PAL_STATUS_SUCCESS(result);
@@ -317,6 +443,16 @@ int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *run)
}
break;
+ case PAL_PREFETCH_VISIBILITY:
+ result = pal_prefetch_visibility(vcpu);
+ break;
+ case PAL_MC_DRAIN:
+ result.status = ia64_pal_mc_drain();
+ /* FIXME: All vcpus likely call PAL_MC_DRAIN.
+ That causes the congestion. */
+ smp_call_function(remote_pal_mc_drain, NULL, 1);
+ break;
+
case PAL_FREQ_RATIOS:
result = pal_freq_ratios(vcpu);
break;
@@ -346,6 +482,9 @@ int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *run)
INIT_PAL_STATUS_SUCCESS(result);
result.v1 = (1L << 32) | 1L;
break;
+ case PAL_REGISTER_INFO:
+ result = pal_register_info(vcpu);
+ break;
case PAL_VM_PAGE_SIZE:
result.status = ia64_pal_vm_page_size(&result.v0,
&result.v1);
@@ -365,12 +504,18 @@ int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *run)
result.status = ia64_pal_version(
(pal_version_u_t *)&result.v0,
(pal_version_u_t *)&result.v1);
-
break;
case PAL_FIXED_ADDR:
result.status = PAL_STATUS_SUCCESS;
result.v0 = vcpu->vcpu_id;
break;
+ case PAL_BRAND_INFO:
+ result = pal_get_brand_info(vcpu);
+ break;
+ case PAL_GET_PSTATE:
+ case PAL_CACHE_SHARED_INFO:
+ INIT_PAL_STATUS_UNIMPLEMENTED(result);
+ break;
default:
INIT_PAL_STATUS_UNIMPLEMENTED(result);
printk(KERN_WARNING"kvm: Unsupported pal call,"
diff --git a/arch/ia64/kvm/process.c b/arch/ia64/kvm/process.c
index 230eae482f32..b1dc80952d91 100644
--- a/arch/ia64/kvm/process.c
+++ b/arch/ia64/kvm/process.c
@@ -167,7 +167,6 @@ static u64 vcpu_get_itir_on_fault(struct kvm_vcpu *vcpu, u64 ifa)
return (rr1.val);
}
-
/*
* Set vIFA & vITIR & vIHA, when vPSR.ic =1
* Parameter:
@@ -222,8 +221,6 @@ void itlb_fault(struct kvm_vcpu *vcpu, u64 vadr)
inject_guest_interruption(vcpu, IA64_INST_TLB_VECTOR);
}
-
-
/*
* Data Nested TLB Fault
* @ Data Nested TLB Vector
@@ -245,7 +242,6 @@ void alt_dtlb(struct kvm_vcpu *vcpu, u64 vadr)
inject_guest_interruption(vcpu, IA64_ALT_DATA_TLB_VECTOR);
}
-
/*
* Data TLB Fault
* @ Data TLB vector
@@ -265,8 +261,6 @@ static void _vhpt_fault(struct kvm_vcpu *vcpu, u64 vadr)
/* If vPSR.ic, IFA, ITIR, IHA*/
set_ifa_itir_iha(vcpu, vadr, 1, 1, 1);
inject_guest_interruption(vcpu, IA64_VHPT_TRANS_VECTOR);
-
-
}
/*
@@ -279,7 +273,6 @@ void ivhpt_fault(struct kvm_vcpu *vcpu, u64 vadr)
_vhpt_fault(vcpu, vadr);
}
-
/*
* VHPT Data Fault
* @ VHPT Translation vector
@@ -290,8 +283,6 @@ void dvhpt_fault(struct kvm_vcpu *vcpu, u64 vadr)
_vhpt_fault(vcpu, vadr);
}
-
-
/*
* Deal with:
* General Exception vector
@@ -301,7 +292,6 @@ void _general_exception(struct kvm_vcpu *vcpu)
inject_guest_interruption(vcpu, IA64_GENEX_VECTOR);
}
-
/*
* Illegal Operation Fault
* @ General Exception Vector
@@ -419,19 +409,16 @@ static void __page_not_present(struct kvm_vcpu *vcpu, u64 vadr)
inject_guest_interruption(vcpu, IA64_PAGE_NOT_PRESENT_VECTOR);
}
-
void data_page_not_present(struct kvm_vcpu *vcpu, u64 vadr)
{
__page_not_present(vcpu, vadr);
}
-
void inst_page_not_present(struct kvm_vcpu *vcpu, u64 vadr)
{
__page_not_present(vcpu, vadr);
}
-
/* Deal with
* Data access rights vector
*/
@@ -563,22 +550,64 @@ void reflect_interruption(u64 ifa, u64 isr, u64 iim,
inject_guest_interruption(vcpu, vector);
}
+static unsigned long kvm_trans_pal_call_args(struct kvm_vcpu *vcpu,
+ unsigned long arg)
+{
+ struct thash_data *data;
+ unsigned long gpa, poff;
+
+ if (!is_physical_mode(vcpu)) {
+ /* Depends on caller to provide the DTR or DTC mapping.*/
+ data = vtlb_lookup(vcpu, arg, D_TLB);
+ if (data)
+ gpa = data->page_flags & _PAGE_PPN_MASK;
+ else {
+ data = vhpt_lookup(arg);
+ if (!data)
+ return 0;
+ gpa = data->gpaddr & _PAGE_PPN_MASK;
+ }
+
+ poff = arg & (PSIZE(data->ps) - 1);
+ arg = PAGEALIGN(gpa, data->ps) | poff;
+ }
+ arg = kvm_gpa_to_mpa(arg << 1 >> 1);
+
+ return (unsigned long)__va(arg);
+}
+
static void set_pal_call_data(struct kvm_vcpu *vcpu)
{
struct exit_ctl_data *p = &vcpu->arch.exit_data;
+ unsigned long gr28 = vcpu_get_gr(vcpu, 28);
+ unsigned long gr29 = vcpu_get_gr(vcpu, 29);
+ unsigned long gr30 = vcpu_get_gr(vcpu, 30);
/*FIXME:For static and stacked convention, firmware
* has put the parameters in gr28-gr31 before
* break to vmm !!*/
- p->u.pal_data.gr28 = vcpu_get_gr(vcpu, 28);
- p->u.pal_data.gr29 = vcpu_get_gr(vcpu, 29);
- p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30);
+ switch (gr28) {
+ case PAL_PERF_MON_INFO:
+ case PAL_HALT_INFO:
+ p->u.pal_data.gr29 = kvm_trans_pal_call_args(vcpu, gr29);
+ p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30);
+ break;
+ case PAL_BRAND_INFO:
+ p->u.pal_data.gr29 = gr29;;
+ p->u.pal_data.gr30 = kvm_trans_pal_call_args(vcpu, gr30);
+ break;
+ default:
+ p->u.pal_data.gr29 = gr29;;
+ p->u.pal_data.gr30 = vcpu_get_gr(vcpu, 30);
+ }
+ p->u.pal_data.gr28 = gr28;
p->u.pal_data.gr31 = vcpu_get_gr(vcpu, 31);
+
p->exit_reason = EXIT_REASON_PAL_CALL;
}
-static void set_pal_call_result(struct kvm_vcpu *vcpu)
+static void get_pal_call_result(struct kvm_vcpu *vcpu)
{
struct exit_ctl_data *p = &vcpu->arch.exit_data;
@@ -606,7 +635,7 @@ static void set_sal_call_data(struct kvm_vcpu *vcpu)
p->exit_reason = EXIT_REASON_SAL_CALL;
}
-static void set_sal_call_result(struct kvm_vcpu *vcpu)
+static void get_sal_call_result(struct kvm_vcpu *vcpu)
{
struct exit_ctl_data *p = &vcpu->arch.exit_data;
@@ -629,13 +658,13 @@ void kvm_ia64_handle_break(unsigned long ifa, struct kvm_pt_regs *regs,
if (iim == DOMN_PAL_REQUEST) {
set_pal_call_data(v);
vmm_transition(v);
- set_pal_call_result(v);
+ get_pal_call_result(v);
vcpu_increment_iip(v);
return;
} else if (iim == DOMN_SAL_REQUEST) {
set_sal_call_data(v);
vmm_transition(v);
- set_sal_call_result(v);
+ get_sal_call_result(v);
vcpu_increment_iip(v);
return;
}
@@ -703,7 +732,6 @@ void vhpi_detection(struct kvm_vcpu *vcpu)
}
}
-
void leave_hypervisor_tail(void)
{
struct kvm_vcpu *v = current_vcpu;
@@ -737,7 +765,6 @@ void leave_hypervisor_tail(void)
}
}
-
static inline void handle_lds(struct kvm_pt_regs *regs)
{
regs->cr_ipsr |= IA64_PSR_ED;
diff --git a/arch/ia64/kvm/vcpu.c b/arch/ia64/kvm/vcpu.c
index ecd526b55323..a18ee17b9192 100644
--- a/arch/ia64/kvm/vcpu.c
+++ b/arch/ia64/kvm/vcpu.c
@@ -112,7 +112,6 @@ void switch_to_physical_rid(struct kvm_vcpu *vcpu)
return;
}
-
void switch_to_virtual_rid(struct kvm_vcpu *vcpu)
{
unsigned long psr;
@@ -166,8 +165,6 @@ void switch_mm_mode(struct kvm_vcpu *vcpu, struct ia64_psr old_psr,
return;
}
-
-
/*
* In physical mode, insert tc/tr for region 0 and 4 uses
* RID[0] and RID[4] which is for physical mode emulation.
@@ -269,7 +266,6 @@ static inline unsigned long fph_index(struct kvm_pt_regs *regs,
return rotate_reg(96, rrb_fr, (regnum - IA64_FIRST_ROTATING_FR));
}
-
/*
* The inverse of the above: given bspstore and the number of
* registers, calculate ar.bsp.
@@ -390,7 +386,7 @@ void set_rse_reg(struct kvm_pt_regs *regs, unsigned long r1,
else
*rnat_addr = (*rnat_addr) & (~nat_mask);
- ia64_setreg(_IA64_REG_AR_BSPSTORE, bspstore);
+ ia64_setreg(_IA64_REG_AR_BSPSTORE, (unsigned long)bspstore);
ia64_setreg(_IA64_REG_AR_RNAT, rnat);
}
local_irq_restore(psr);
@@ -811,12 +807,15 @@ static inline void vcpu_set_itm(struct kvm_vcpu *vcpu, u64 val);
static void vcpu_set_itc(struct kvm_vcpu *vcpu, u64 val)
{
struct kvm_vcpu *v;
+ struct kvm *kvm;
int i;
long itc_offset = val - ia64_getreg(_IA64_REG_AR_ITC);
unsigned long vitv = VCPU(vcpu, itv);
+ kvm = (struct kvm *)KVM_VM_BASE;
+
if (vcpu->vcpu_id == 0) {
- for (i = 0; i < KVM_MAX_VCPUS; i++) {
+ for (i = 0; i < kvm->arch.online_vcpus; i++) {
v = (struct kvm_vcpu *)((char *)vcpu +
sizeof(struct kvm_vcpu_data) * i);
VMX(v, itc_offset) = itc_offset;
@@ -1039,8 +1038,6 @@ u64 vcpu_tak(struct kvm_vcpu *vcpu, u64 vadr)
return key;
}
-
-
void kvm_thash(struct kvm_vcpu *vcpu, INST64 inst)
{
unsigned long thash, vadr;
@@ -1050,7 +1047,6 @@ void kvm_thash(struct kvm_vcpu *vcpu, INST64 inst)
vcpu_set_gr(vcpu, inst.M46.r1, thash, 0);
}
-
void kvm_ttag(struct kvm_vcpu *vcpu, INST64 inst)
{
unsigned long tag, vadr;
@@ -1131,7 +1127,6 @@ int vcpu_tpa(struct kvm_vcpu *vcpu, u64 vadr, u64 *padr)
return IA64_NO_FAULT;
}
-
int kvm_tpa(struct kvm_vcpu *vcpu, INST64 inst)
{
unsigned long r1, r3;
@@ -1154,7 +1149,6 @@ void kvm_tak(struct kvm_vcpu *vcpu, INST64 inst)
vcpu_set_gr(vcpu, inst.M46.r1, r1, 0);
}
-
/************************************
* Insert/Purge translation register/cache
************************************/
@@ -1385,7 +1379,6 @@ void kvm_mov_to_ar_reg(struct kvm_vcpu *vcpu, INST64 inst)
vcpu_set_itc(vcpu, r2);
}
-
void kvm_mov_from_ar_reg(struct kvm_vcpu *vcpu, INST64 inst)
{
unsigned long r1;
@@ -1393,8 +1386,9 @@ void kvm_mov_from_ar_reg(struct kvm_vcpu *vcpu, INST64 inst)
r1 = vcpu_get_itc(vcpu);
vcpu_set_gr(vcpu, inst.M31.r1, r1, 0);
}
+
/**************************************************************************
- struct kvm_vcpu*protection key register access routines
+ struct kvm_vcpu protection key register access routines
**************************************************************************/
unsigned long vcpu_get_pkr(struct kvm_vcpu *vcpu, unsigned long reg)
@@ -1407,20 +1401,6 @@ void vcpu_set_pkr(struct kvm_vcpu *vcpu, unsigned long reg, unsigned long val)
ia64_set_pkr(reg, val);
}
-
-unsigned long vcpu_get_itir_on_fault(struct kvm_vcpu *vcpu, unsigned long ifa)
-{
- union ia64_rr rr, rr1;
-
- rr.val = vcpu_get_rr(vcpu, ifa);
- rr1.val = 0;
- rr1.ps = rr.ps;
- rr1.rid = rr.rid;
- return (rr1.val);
-}
-
-
-
/********************************
* Moves to privileged registers
********************************/
@@ -1464,8 +1444,6 @@ unsigned long vcpu_set_rr(struct kvm_vcpu *vcpu, unsigned long reg,
return (IA64_NO_FAULT);
}
-
-
void kvm_mov_to_rr(struct kvm_vcpu *vcpu, INST64 inst)
{
unsigned long r3, r2;
@@ -1510,8 +1488,6 @@ void kvm_mov_to_pkr(struct kvm_vcpu *vcpu, INST64 inst)
vcpu_set_pkr(vcpu, r3, r2);
}
-
-
void kvm_mov_from_rr(struct kvm_vcpu *vcpu, INST64 inst)
{
unsigned long r3, r1;
@@ -1557,7 +1533,6 @@ void kvm_mov_from_pmc(struct kvm_vcpu *vcpu, INST64 inst)
vcpu_set_gr(vcpu, inst.M43.r1, r1, 0);
}
-
unsigned long vcpu_get_cpuid(struct kvm_vcpu *vcpu, unsigned long reg)
{
/* FIXME: This could get called as a result of a rsvd-reg fault */
@@ -1609,7 +1584,6 @@ unsigned long kvm_mov_to_cr(struct kvm_vcpu *vcpu, INST64 inst)
return 0;
}
-
unsigned long kvm_mov_from_cr(struct kvm_vcpu *vcpu, INST64 inst)
{
unsigned long tgt = inst.M33.r1;
@@ -1633,8 +1607,6 @@ unsigned long kvm_mov_from_cr(struct kvm_vcpu *vcpu, INST64 inst)
return 0;
}
-
-
void vcpu_set_psr(struct kvm_vcpu *vcpu, unsigned long val)
{
@@ -1776,9 +1748,6 @@ void vcpu_bsw1(struct kvm_vcpu *vcpu)
}
}
-
-
-
void vcpu_rfi(struct kvm_vcpu *vcpu)
{
unsigned long ifs, psr;
@@ -1796,7 +1765,6 @@ void vcpu_rfi(struct kvm_vcpu *vcpu)
regs->cr_iip = VCPU(vcpu, iip);
}
-
/*
VPSR can't keep track of below bits of guest PSR
This function gets guest PSR
diff --git a/arch/ia64/kvm/vcpu.h b/arch/ia64/kvm/vcpu.h
index b2f12a562bdf..042af92ced83 100644
--- a/arch/ia64/kvm/vcpu.h
+++ b/arch/ia64/kvm/vcpu.h
@@ -703,7 +703,7 @@ extern u64 guest_vhpt_lookup(u64 iha, u64 *pte);
extern void thash_purge_entries(struct kvm_vcpu *v, u64 va, u64 ps);
extern void thash_purge_entries_remote(struct kvm_vcpu *v, u64 va, u64 ps);
extern u64 translate_phy_pte(u64 *pte, u64 itir, u64 va);
-extern int thash_purge_and_insert(struct kvm_vcpu *v, u64 pte,
+extern void thash_purge_and_insert(struct kvm_vcpu *v, u64 pte,
u64 itir, u64 ifa, int type);
extern void thash_purge_all(struct kvm_vcpu *v);
extern struct thash_data *vtlb_lookup(struct kvm_vcpu *v,
@@ -738,7 +738,7 @@ void kvm_init_vhpt(struct kvm_vcpu *v);
void thash_init(struct thash_cb *hcb, u64 sz);
void panic_vm(struct kvm_vcpu *v, const char *fmt, ...);
-
+u64 kvm_gpa_to_mpa(u64 gpa);
extern u64 ia64_call_vsa(u64 proc, u64 arg1, u64 arg2, u64 arg3,
u64 arg4, u64 arg5, u64 arg6, u64 arg7);
diff --git a/arch/ia64/kvm/vtlb.c b/arch/ia64/kvm/vtlb.c
index 6b6307a3bd55..2c2501f13159 100644
--- a/arch/ia64/kvm/vtlb.c
+++ b/arch/ia64/kvm/vtlb.c
@@ -164,11 +164,11 @@ static void vhpt_insert(u64 pte, u64 itir, u64 ifa, u64 gpte)
unsigned long ps, gpaddr;
ps = itir_ps(itir);
+ rr.val = ia64_get_rr(ifa);
- gpaddr = ((gpte & _PAGE_PPN_MASK) >> ps << ps) |
- (ifa & ((1UL << ps) - 1));
+ gpaddr = ((gpte & _PAGE_PPN_MASK) >> ps << ps) |
+ (ifa & ((1UL << ps) - 1));
- rr.val = ia64_get_rr(ifa);
head = (struct thash_data *)ia64_thash(ifa);
head->etag = INVALID_TI_TAG;
ia64_mf();
@@ -210,6 +210,7 @@ void thash_vhpt_insert(struct kvm_vcpu *v, u64 pte, u64 itir, u64 va, int type)
phy_pte &= ~PAGE_FLAGS_RV_MASK;
psr = ia64_clear_ic();
ia64_itc(type, va, phy_pte, itir_ps(itir));
+ paravirt_dv_serialize_data();
ia64_set_psr(psr);
}
@@ -412,16 +413,14 @@ u64 translate_phy_pte(u64 *pte, u64 itir, u64 va)
/*
* Purge overlap TCs and then insert the new entry to emulate itc ops.
- * Notes: Only TC entry can purge and insert.
- * 1 indicates this is MMIO
+ * Notes: Only TC entry can purge and insert.
*/
-int thash_purge_and_insert(struct kvm_vcpu *v, u64 pte, u64 itir,
+void thash_purge_and_insert(struct kvm_vcpu *v, u64 pte, u64 itir,
u64 ifa, int type)
{
u64 ps;
u64 phy_pte, io_mask, index;
union ia64_rr vrr, mrr;
- int ret = 0;
ps = itir_ps(itir);
vrr.val = vcpu_get_rr(v, ifa);
@@ -441,35 +440,29 @@ int thash_purge_and_insert(struct kvm_vcpu *v, u64 pte, u64 itir,
phy_pte &= ~_PAGE_MA_MASK;
}
- if (pte & VTLB_PTE_IO)
- ret = 1;
-
vtlb_purge(v, ifa, ps);
vhpt_purge(v, ifa, ps);
- if (ps == mrr.ps) {
- if (!(pte&VTLB_PTE_IO)) {
- vhpt_insert(phy_pte, itir, ifa, pte);
- } else {
- vtlb_insert(v, pte, itir, ifa);
- vcpu_quick_region_set(VMX(v, tc_regions), ifa);
- }
- } else if (ps > mrr.ps) {
+ if ((ps != mrr.ps) || (pte & VTLB_PTE_IO)) {
vtlb_insert(v, pte, itir, ifa);
vcpu_quick_region_set(VMX(v, tc_regions), ifa);
- if (!(pte&VTLB_PTE_IO))
- vhpt_insert(phy_pte, itir, ifa, pte);
- } else {
+ }
+ if (pte & VTLB_PTE_IO)
+ return;
+
+ if (ps >= mrr.ps)
+ vhpt_insert(phy_pte, itir, ifa, pte);
+ else {
u64 psr;
phy_pte &= ~PAGE_FLAGS_RV_MASK;
psr = ia64_clear_ic();
ia64_itc(type, ifa, phy_pte, ps);
+ paravirt_dv_serialize_data();
ia64_set_psr(psr);
}
if (!(pte&VTLB_PTE_IO))
mark_pages_dirty(v, pte, ps);
- return ret;
}
/*
@@ -509,7 +502,6 @@ void thash_purge_all(struct kvm_vcpu *v)
local_flush_tlb_all();
}
-
/*
* Lookup the hash table and its collision chain to find an entry
* covering this address rid:va or the entry.
@@ -517,7 +509,6 @@ void thash_purge_all(struct kvm_vcpu *v)
* INPUT:
* in: TLB format for both VHPT & TLB.
*/
-
struct thash_data *vtlb_lookup(struct kvm_vcpu *v, u64 va, int is_data)
{
struct thash_data *cch;
@@ -547,7 +538,6 @@ struct thash_data *vtlb_lookup(struct kvm_vcpu *v, u64 va, int is_data)
return NULL;
}
-
/*
* Initialize internal control data before service.
*/
@@ -573,6 +563,10 @@ void thash_init(struct thash_cb *hcb, u64 sz)
u64 kvm_get_mpt_entry(u64 gpfn)
{
u64 *base = (u64 *) KVM_P2M_BASE;
+
+ if (gpfn >= (KVM_P2M_SIZE >> 3))
+ panic_vm(current_vcpu, "Invalid gpfn =%lx\n", gpfn);
+
return *(base + gpfn);
}
@@ -589,7 +583,6 @@ u64 kvm_gpa_to_mpa(u64 gpa)
return (pte >> PAGE_SHIFT << PAGE_SHIFT) | (gpa & ~PAGE_MASK);
}
-
/*
* Fetch guest bundle code.
* INPUT:
@@ -631,7 +624,6 @@ int fetch_code(struct kvm_vcpu *vcpu, u64 gip, IA64_BUNDLE *pbundle)
return IA64_NO_FAULT;
}
-
void kvm_init_vhpt(struct kvm_vcpu *v)
{
v->arch.vhpt.num = VHPT_NUM_ENTRIES;
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 56e12903973c..c0f3bee69042 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -35,6 +35,7 @@
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include <asm/mca.h>
+#include <asm/paravirt.h>
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
@@ -259,6 +260,7 @@ put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
static void __init
setup_gate (void)
{
+ void *gate_section;
struct page *page;
/*
@@ -266,10 +268,11 @@ setup_gate (void)
* headers etc. and once execute-only page to enable
* privilege-promotion via "epc":
*/
- page = virt_to_page(ia64_imva(__start_gate_section));
+ gate_section = paravirt_get_gate_section();
+ page = virt_to_page(ia64_imva(gate_section));
put_kernel_page(page, GATE_ADDR, PAGE_READONLY);
#ifdef HAVE_BUGGY_SEGREL
- page = virt_to_page(ia64_imva(__start_gate_section + PAGE_SIZE));
+ page = virt_to_page(ia64_imva(gate_section + PAGE_SIZE));
put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE);
#else
put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE);
@@ -633,8 +636,7 @@ mem_init (void)
#endif
#ifdef CONFIG_FLATMEM
- if (!mem_map)
- BUG();
+ BUG_ON(!mem_map);
max_mapnr = max_low_pfn;
#endif
@@ -667,8 +669,8 @@ mem_init (void)
* code can tell them apart.
*/
for (i = 0; i < NR_syscalls; ++i) {
- extern unsigned long fsyscall_table[NR_syscalls];
extern unsigned long sys_call_table[NR_syscalls];
+ unsigned long *fsyscall_table = paravirt_get_fsyscall_table();
if (!fsyscall_table[i] || nolwsys)
fsyscall_table[i] = sys_call_table[i] | 1;
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
index bd9818a36b47..b9f3d7bbb338 100644
--- a/arch/ia64/mm/tlb.c
+++ b/arch/ia64/mm/tlb.c
@@ -309,7 +309,7 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start,
preempt_disable();
#ifdef CONFIG_SMP
- if (mm != current->active_mm || cpus_weight(mm->cpu_vm_mask) != 1) {
+ if (mm != current->active_mm || cpumask_weight(mm_cpumask(mm)) != 1) {
platform_global_tlb_purge(mm, start, end, nbits);
preempt_enable();
return;
diff --git a/arch/ia64/scripts/pvcheck.sed b/arch/ia64/scripts/pvcheck.sed
index ba66ac2e4c60..e59809a3fc01 100644
--- a/arch/ia64/scripts/pvcheck.sed
+++ b/arch/ia64/scripts/pvcheck.sed
@@ -17,6 +17,7 @@ s/mov.*=.*cr\.iip/.warning \"cr.iip should not used directly\"/g
s/mov.*=.*cr\.ivr/.warning \"cr.ivr should not used directly\"/g
s/mov.*=[^\.]*psr/.warning \"psr should not used directly\"/g # avoid ar.fpsr
s/mov.*=.*ar\.eflags/.warning \"ar.eflags should not used directly\"/g
+s/mov.*=.*ar\.itc.*/.warning \"ar.itc should not used directly\"/g
s/mov.*cr\.ifa.*=.*/.warning \"cr.ifa should not used directly\"/g
s/mov.*cr\.itir.*=.*/.warning \"cr.itir should not used directly\"/g
s/mov.*cr\.iha.*=.*/.warning \"cr.iha should not used directly\"/g
diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c
index 0d4ffa4da1da..57f280dd9def 100644
--- a/arch/ia64/sn/kernel/io_common.c
+++ b/arch/ia64/sn/kernel/io_common.c
@@ -135,8 +135,7 @@ static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device,
}
war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL);
- if (!war_list)
- BUG();
+ BUG_ON(!war_list);
SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST,
nasid, widget, __pa(war_list), 0, 0, 0 ,0);
@@ -180,23 +179,20 @@ sn_common_hubdev_init(struct hubdev_info *hubdev)
sizeof(struct sn_flush_device_kernel *);
hubdev->hdi_flush_nasid_list.widget_p =
kzalloc(size, GFP_KERNEL);
- if (!hubdev->hdi_flush_nasid_list.widget_p)
- BUG();
+ BUG_ON(!hubdev->hdi_flush_nasid_list.widget_p);
for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) {
size = DEV_PER_WIDGET *
sizeof(struct sn_flush_device_kernel);
sn_flush_device_kernel = kzalloc(size, GFP_KERNEL);
- if (!sn_flush_device_kernel)
- BUG();
+ BUG_ON(!sn_flush_device_kernel);
dev_entry = sn_flush_device_kernel;
for (device = 0; device < DEV_PER_WIDGET;
device++, dev_entry++) {
size = sizeof(struct sn_flush_device_common);
dev_entry->common = kzalloc(size, GFP_KERNEL);
- if (!dev_entry->common)
- BUG();
+ BUG_ON(!dev_entry->common);
if (sn_prom_feature_available(PRF_DEVICE_FLUSH_LIST))
status = sal_get_device_dmaflush_list(
hubdev->hdi_nasid, widget, device,
@@ -326,8 +322,7 @@ sn_common_bus_fixup(struct pci_bus *bus,
*/
controller->platform_data = kzalloc(sizeof(struct sn_platform_data),
GFP_KERNEL);
- if (controller->platform_data == NULL)
- BUG();
+ BUG_ON(controller->platform_data == NULL);
sn_platform_data =
(struct sn_platform_data *) controller->platform_data;
sn_platform_data->provider_soft = provider_soft;
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index e2eb2da60f96..ee774c366a06 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -128,8 +128,7 @@ sn_legacy_pci_window_fixup(struct pci_controller *controller,
{
controller->window = kcalloc(2, sizeof(struct pci_window),
GFP_KERNEL);
- if (controller->window == NULL)
- BUG();
+ BUG_ON(controller->window == NULL);
controller->window[0].offset = legacy_io;
controller->window[0].resource.name = "legacy_io";
controller->window[0].resource.flags = IORESOURCE_IO;
@@ -168,8 +167,7 @@ sn_pci_window_fixup(struct pci_dev *dev, unsigned int count,
idx = controller->windows;
new_count = controller->windows + count;
new_window = kcalloc(new_count, sizeof(struct pci_window), GFP_KERNEL);
- if (new_window == NULL)
- BUG();
+ BUG_ON(new_window == NULL);
if (controller->window) {
memcpy(new_window, controller->window,
sizeof(struct pci_window) * controller->windows);
@@ -222,8 +220,7 @@ sn_io_slot_fixup(struct pci_dev *dev)
(u64) __pa(pcidev_info),
(u64) __pa(sn_irq_info));
- if (status)
- BUG(); /* Cannot get platform pci device information */
+ BUG_ON(status); /* Cannot get platform pci device information */
/* Copy over PIO Mapped Addresses */
@@ -307,8 +304,7 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
prom_bussoft_ptr = __va(prom_bussoft_ptr);
controller = kzalloc(sizeof(*controller), GFP_KERNEL);
- if (!controller)
- BUG();
+ BUG_ON(!controller);
controller->segment = segment;
/*
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index 02c5b8a9fb60..e456f062f241 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -732,8 +732,7 @@ void __init build_cnode_tables(void)
kl_config_hdr_t *klgraph_header;
nasid = cnodeid_to_nasid(node);
klgraph_header = ia64_sn_get_klconfig_addr(nasid);
- if (klgraph_header == NULL)
- BUG();
+ BUG_ON(klgraph_header == NULL);
brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info);
while (brd) {
if (board_needs_cnode(brd->brd_type) && physical_node_map[brd->brd_nasid] < 0) {
@@ -750,7 +749,7 @@ nasid_slice_to_cpuid(int nasid, int slice)
{
long cpu;
- for (cpu = 0; cpu < NR_CPUS; cpu++)
+ for (cpu = 0; cpu < nr_cpu_ids; cpu++)
if (cpuid_to_nasid(cpu) == nasid &&
cpuid_to_slice(cpu) == slice)
return cpu;
diff --git a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c
index 4dcce3d0e04c..e63328818643 100644
--- a/arch/ia64/sn/kernel/sn2/prominfo_proc.c
+++ b/arch/ia64/sn/kernel/sn2/prominfo_proc.c
@@ -225,7 +225,6 @@ static struct proc_dir_entry *sgi_prominfo_entry;
int __init prominfo_init(void)
{
struct proc_dir_entry **entp;
- struct proc_dir_entry *p;
cnodeid_t cnodeid;
unsigned long nasid;
int size;
@@ -246,14 +245,10 @@ int __init prominfo_init(void)
sprintf(name, "node%d", cnodeid);
*entp = proc_mkdir(name, sgi_prominfo_entry);
nasid = cnodeid_to_nasid(cnodeid);
- p = create_proc_read_entry("fit", 0, *entp, read_fit_entry,
+ create_proc_read_entry("fit", 0, *entp, read_fit_entry,
(void *)nasid);
- if (p)
- p->owner = THIS_MODULE;
- p = create_proc_read_entry("version", 0, *entp,
+ create_proc_read_entry("version", 0, *entp,
read_version_entry, (void *)nasid);
- if (p)
- p->owner = THIS_MODULE;
entp++;
}
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
index e585f9a2afb9..1176506b2bae 100644
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c
@@ -133,7 +133,7 @@ sn2_ipi_flush_all_tlb(struct mm_struct *mm)
unsigned long itc;
itc = ia64_get_itc();
- smp_flush_tlb_cpumask(mm->cpu_vm_mask);
+ smp_flush_tlb_cpumask(*mm_cpumask(mm));
itc = ia64_get_itc() - itc;
__get_cpu_var(ptcstats).shub_ipi_flushes_itc_clocks += itc;
__get_cpu_var(ptcstats).shub_ipi_flushes++;
@@ -182,7 +182,7 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
nodes_clear(nodes_flushed);
i = 0;
- for_each_cpu_mask(cpu, mm->cpu_vm_mask) {
+ for_each_cpu(cpu, mm_cpumask(mm)) {
cnode = cpu_to_node(cpu);
node_set(cnode, nodes_flushed);
lcpu = cpu;
@@ -461,7 +461,7 @@ bool sn_cpu_disable_allowed(int cpu)
static void *sn2_ptc_seq_start(struct seq_file *file, loff_t * offset)
{
- if (*offset < NR_CPUS)
+ if (*offset < nr_cpu_ids)
return offset;
return NULL;
}
@@ -469,7 +469,7 @@ static void *sn2_ptc_seq_start(struct seq_file *file, loff_t * offset)
static void *sn2_ptc_seq_next(struct seq_file *file, void *data, loff_t * offset)
{
(*offset)++;
- if (*offset < NR_CPUS)
+ if (*offset < nr_cpu_ids)
return offset;
return NULL;
}
@@ -491,7 +491,7 @@ static int sn2_ptc_seq_show(struct seq_file *file, void *data)
seq_printf(file, "# ptctest %d, flushopt %d\n", sn2_ptctest, sn2_flush_opt);
}
- if (cpu < NR_CPUS && cpu_online(cpu)) {
+ if (cpu < nr_cpu_ids && cpu_online(cpu)) {
stat = &per_cpu(ptcstats, cpu);
seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l,
stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed,
@@ -554,7 +554,7 @@ static int __init sn2_ptc_init(void)
proc_sn2_ptc = proc_create(PTC_BASENAME, 0444,
NULL, &proc_sn2_ptc_operations);
- if (!&proc_sn2_ptc_operations) {
+ if (!proc_sn2_ptc) {
printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME);
return -EINVAL;
}
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index be339477f906..9e6491cf72bd 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -275,8 +275,7 @@ static int sn_hwperf_get_nearest_node_objdata(struct sn_hwperf_object_info *objb
/* get it's interconnect topology */
sz = op->ports * sizeof(struct sn_hwperf_port_info);
- if (sz > sizeof(ptdata))
- BUG();
+ BUG_ON(sz > sizeof(ptdata));
e = ia64_sn_hwperf_op(sn_hwperf_master_nasid,
SN_HWPERF_ENUM_PORTS, nodeobj->id, sz,
(u64)&ptdata, 0, 0, NULL);
@@ -310,8 +309,7 @@ static int sn_hwperf_get_nearest_node_objdata(struct sn_hwperf_object_info *objb
if (router && (!found_cpu || !found_mem)) {
/* search for a node connected to the same router */
sz = router->ports * sizeof(struct sn_hwperf_port_info);
- if (sz > sizeof(ptdata))
- BUG();
+ BUG_ON(sz > sizeof(ptdata));
e = ia64_sn_hwperf_op(sn_hwperf_master_nasid,
SN_HWPERF_ENUM_PORTS, router->id, sz,
(u64)&ptdata, 0, 0, NULL);
@@ -612,7 +610,7 @@ static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info)
op_info->a->arg &= SN_HWPERF_ARG_OBJID_MASK;
if (cpu != SN_HWPERF_ARG_ANY_CPU) {
- if (cpu >= NR_CPUS || !cpu_online(cpu)) {
+ if (cpu >= nr_cpu_ids || !cpu_online(cpu)) {
r = -EINVAL;
goto out;
}
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index 863f5017baae..8c130e8f00e1 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -10,7 +10,7 @@
*/
#include <linux/module.h>
-#include <linux/dma-attrs.h>
+#include <linux/dma-mapping.h>
#include <asm/dma.h>
#include <asm/sn/intr.h>
#include <asm/sn/pcibus_provider_defs.h>
@@ -31,7 +31,7 @@
* this function. Of course, SN only supports devices that have 32 or more
* address bits when using the PMU.
*/
-int sn_dma_supported(struct device *dev, u64 mask)
+static int sn_dma_supported(struct device *dev, u64 mask)
{
BUG_ON(dev->bus != &pci_bus_type);
@@ -39,7 +39,6 @@ int sn_dma_supported(struct device *dev, u64 mask)
return 0;
return 1;
}
-EXPORT_SYMBOL(sn_dma_supported);
/**
* sn_dma_set_mask - set the DMA mask
@@ -75,8 +74,8 @@ EXPORT_SYMBOL(sn_dma_set_mask);
* queue for a SCSI controller). See Documentation/DMA-API.txt for
* more information.
*/
-void *sn_dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t * dma_handle, gfp_t flags)
+static void *sn_dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t * dma_handle, gfp_t flags)
{
void *cpuaddr;
unsigned long phys_addr;
@@ -124,7 +123,6 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size,
return cpuaddr;
}
-EXPORT_SYMBOL(sn_dma_alloc_coherent);
/**
* sn_pci_free_coherent - free memory associated with coherent DMAable region
@@ -136,8 +134,8 @@ EXPORT_SYMBOL(sn_dma_alloc_coherent);
* Frees the memory allocated by dma_alloc_coherent(), potentially unmapping
* any associated IOMMU mappings.
*/
-void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t dma_handle)
+static void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t dma_handle)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
@@ -147,7 +145,6 @@ void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
provider->dma_unmap(pdev, dma_handle, 0);
free_pages((unsigned long)cpu_addr, get_order(size));
}
-EXPORT_SYMBOL(sn_dma_free_coherent);
/**
* sn_dma_map_single_attrs - map a single page for DMA
@@ -173,10 +170,12 @@ EXPORT_SYMBOL(sn_dma_free_coherent);
* TODO: simplify our interface;
* figure out how to save dmamap handle so can use two step.
*/
-dma_addr_t sn_dma_map_single_attrs(struct device *dev, void *cpu_addr,
- size_t size, int direction,
- struct dma_attrs *attrs)
+static dma_addr_t sn_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
+ void *cpu_addr = page_address(page) + offset;
dma_addr_t dma_addr;
unsigned long phys_addr;
struct pci_dev *pdev = to_pci_dev(dev);
@@ -201,7 +200,6 @@ dma_addr_t sn_dma_map_single_attrs(struct device *dev, void *cpu_addr,
}
return dma_addr;
}
-EXPORT_SYMBOL(sn_dma_map_single_attrs);
/**
* sn_dma_unmap_single_attrs - unamp a DMA mapped page
@@ -215,21 +213,20 @@ EXPORT_SYMBOL(sn_dma_map_single_attrs);
* by @dma_handle into the coherence domain. On SN, we're always cache
* coherent, so we just need to free any ATEs associated with this mapping.
*/
-void sn_dma_unmap_single_attrs(struct device *dev, dma_addr_t dma_addr,
- size_t size, int direction,
- struct dma_attrs *attrs)
+static void sn_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
BUG_ON(dev->bus != &pci_bus_type);
- provider->dma_unmap(pdev, dma_addr, direction);
+ provider->dma_unmap(pdev, dma_addr, dir);
}
-EXPORT_SYMBOL(sn_dma_unmap_single_attrs);
/**
- * sn_dma_unmap_sg_attrs - unmap a DMA scatterlist
+ * sn_dma_unmap_sg - unmap a DMA scatterlist
* @dev: device to unmap
* @sg: scatterlist to unmap
* @nhwentries: number of scatterlist entries
@@ -238,9 +235,9 @@ EXPORT_SYMBOL(sn_dma_unmap_single_attrs);
*
* Unmap a set of streaming mode DMA translations.
*/
-void sn_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sgl,
- int nhwentries, int direction,
- struct dma_attrs *attrs)
+static void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
+ int nhwentries, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
int i;
struct pci_dev *pdev = to_pci_dev(dev);
@@ -250,15 +247,14 @@ void sn_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sgl,
BUG_ON(dev->bus != &pci_bus_type);
for_each_sg(sgl, sg, nhwentries, i) {
- provider->dma_unmap(pdev, sg->dma_address, direction);
+ provider->dma_unmap(pdev, sg->dma_address, dir);
sg->dma_address = (dma_addr_t) NULL;
sg->dma_length = 0;
}
}
-EXPORT_SYMBOL(sn_dma_unmap_sg_attrs);
/**
- * sn_dma_map_sg_attrs - map a scatterlist for DMA
+ * sn_dma_map_sg - map a scatterlist for DMA
* @dev: device to map for
* @sg: scatterlist to map
* @nhwentries: number of entries
@@ -272,8 +268,9 @@ EXPORT_SYMBOL(sn_dma_unmap_sg_attrs);
*
* Maps each entry of @sg for DMA.
*/
-int sn_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
- int nhwentries, int direction, struct dma_attrs *attrs)
+static int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl,
+ int nhwentries, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
unsigned long phys_addr;
struct scatterlist *saved_sg = sgl, *sg;
@@ -310,8 +307,7 @@ int sn_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
* Free any successfully allocated entries.
*/
if (i > 0)
- sn_dma_unmap_sg_attrs(dev, saved_sg, i,
- direction, attrs);
+ sn_dma_unmap_sg(dev, saved_sg, i, dir, attrs);
return 0;
}
@@ -320,41 +316,36 @@ int sn_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl,
return nhwentries;
}
-EXPORT_SYMBOL(sn_dma_map_sg_attrs);
-void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
- size_t size, int direction)
+static void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction dir)
{
BUG_ON(dev->bus != &pci_bus_type);
}
-EXPORT_SYMBOL(sn_dma_sync_single_for_cpu);
-void sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
- size_t size, int direction)
+static void sn_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+ size_t size,
+ enum dma_data_direction dir)
{
BUG_ON(dev->bus != &pci_bus_type);
}
-EXPORT_SYMBOL(sn_dma_sync_single_for_device);
-void sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
- int nelems, int direction)
+static void sn_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+ int nelems, enum dma_data_direction dir)
{
BUG_ON(dev->bus != &pci_bus_type);
}
-EXPORT_SYMBOL(sn_dma_sync_sg_for_cpu);
-void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
- int nelems, int direction)
+static void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+ int nelems, enum dma_data_direction dir)
{
BUG_ON(dev->bus != &pci_bus_type);
}
-EXPORT_SYMBOL(sn_dma_sync_sg_for_device);
-int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+static int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
return 0;
}
-EXPORT_SYMBOL(sn_dma_mapping_error);
u64 sn_dma_get_required_mask(struct device *dev)
{
@@ -471,3 +462,23 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
out:
return ret;
}
+
+static struct dma_map_ops sn_dma_ops = {
+ .alloc_coherent = sn_dma_alloc_coherent,
+ .free_coherent = sn_dma_free_coherent,
+ .map_page = sn_dma_map_page,
+ .unmap_page = sn_dma_unmap_page,
+ .map_sg = sn_dma_map_sg,
+ .unmap_sg = sn_dma_unmap_sg,
+ .sync_single_for_cpu = sn_dma_sync_single_for_cpu,
+ .sync_sg_for_cpu = sn_dma_sync_sg_for_cpu,
+ .sync_single_for_device = sn_dma_sync_single_for_device,
+ .sync_sg_for_device = sn_dma_sync_sg_for_device,
+ .mapping_error = sn_dma_mapping_error,
+ .dma_supported = sn_dma_supported,
+};
+
+void sn_dma_init(void)
+{
+ dma_ops = &sn_dma_ops;
+}
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
index 060df4aa9916..c659ad5613a0 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
@@ -256,9 +256,7 @@ void sn_dma_flush(u64 addr)
hubinfo = (NODEPDA(nasid_to_cnodeid(nasid)))->pdinfo;
- if (!hubinfo) {
- BUG();
- }
+ BUG_ON(!hubinfo);
flush_nasid_list = &hubinfo->hdi_flush_nasid_list;
if (flush_nasid_list->widget_p == NULL)
diff --git a/arch/ia64/xen/Makefile b/arch/ia64/xen/Makefile
index 0ad0224693d9..e6f4a0a74228 100644
--- a/arch/ia64/xen/Makefile
+++ b/arch/ia64/xen/Makefile
@@ -3,14 +3,29 @@
#
obj-y := hypercall.o xenivt.o xensetup.o xen_pv_ops.o irq_xen.o \
- hypervisor.o xencomm.o xcom_hcall.o grant-table.o time.o suspend.o
+ hypervisor.o xencomm.o xcom_hcall.o grant-table.o time.o suspend.o \
+ gate-data.o
obj-$(CONFIG_IA64_GENERIC) += machvec.o
+# The gate DSO image is built using a special linker script.
+include $(srctree)/arch/ia64/kernel/Makefile.gate
+
+# tell compiled for xen
+CPPFLAGS_gate.lds += -D__IA64_GATE_PARAVIRTUALIZED_XEN
+AFLAGS_gate.o += -D__IA64_ASM_PARAVIRTUALIZED_XEN -D__IA64_GATE_PARAVIRTUALIZED_XEN
+
+# use same file of native.
+$(obj)/gate.o: $(src)/../kernel/gate.S FORCE
+ $(call if_changed_dep,as_o_S)
+$(obj)/gate.lds: $(src)/../kernel/gate.lds.S FORCE
+ $(call if_changed_dep,cpp_lds_S)
+
+
AFLAGS_xenivt.o += -D__IA64_ASM_PARAVIRTUALIZED_XEN
# xen multi compile
-ASM_PARAVIRT_MULTI_COMPILE_SRCS = ivt.S entry.S
+ASM_PARAVIRT_MULTI_COMPILE_SRCS = ivt.S entry.S fsys.S
ASM_PARAVIRT_OBJS = $(addprefix xen-,$(ASM_PARAVIRT_MULTI_COMPILE_SRCS:.S=.o))
obj-y += $(ASM_PARAVIRT_OBJS)
define paravirtualized_xen
diff --git a/arch/ia64/xen/gate-data.S b/arch/ia64/xen/gate-data.S
new file mode 100644
index 000000000000..7d4830afc91d
--- /dev/null
+++ b/arch/ia64/xen/gate-data.S
@@ -0,0 +1,3 @@
+ .section .data.gate.xen, "aw"
+
+ .incbin "arch/ia64/xen/gate.so"
diff --git a/arch/ia64/xen/hypercall.S b/arch/ia64/xen/hypercall.S
index 45e02bb64a92..e32dae444dd6 100644
--- a/arch/ia64/xen/hypercall.S
+++ b/arch/ia64/xen/hypercall.S
@@ -9,6 +9,7 @@
#include <asm/intrinsics.h>
#include <asm/xen/privop.h>
+#ifdef __INTEL_COMPILER
/*
* Hypercalls without parameter.
*/
@@ -72,6 +73,7 @@ GLOBAL_ENTRY(xen_set_rr0_to_rr4)
br.ret.sptk.many rp
;;
END(xen_set_rr0_to_rr4)
+#endif
GLOBAL_ENTRY(xen_send_ipi)
mov r14=r32
diff --git a/arch/ia64/xen/time.c b/arch/ia64/xen/time.c
index 68d6204c3f16..fb8332690179 100644
--- a/arch/ia64/xen/time.c
+++ b/arch/ia64/xen/time.c
@@ -175,10 +175,58 @@ static void xen_itc_jitter_data_reset(void)
} while (unlikely(ret != lcycle));
}
+/* based on xen_sched_clock() in arch/x86/xen/time.c. */
+/*
+ * This relies on HAVE_UNSTABLE_SCHED_CLOCK. If it can't be defined,
+ * something similar logic should be implemented here.
+ */
+/*
+ * Xen sched_clock implementation. Returns the number of unstolen
+ * nanoseconds, which is nanoseconds the VCPU spent in RUNNING+BLOCKED
+ * states.
+ */
+static unsigned long long xen_sched_clock(void)
+{
+ struct vcpu_runstate_info runstate;
+
+ unsigned long long now;
+ unsigned long long offset;
+ unsigned long long ret;
+
+ /*
+ * Ideally sched_clock should be called on a per-cpu basis
+ * anyway, so preempt should already be disabled, but that's
+ * not current practice at the moment.
+ */
+ preempt_disable();
+
+ /*
+ * both ia64_native_sched_clock() and xen's runstate are
+ * based on mAR.ITC. So difference of them makes sense.
+ */
+ now = ia64_native_sched_clock();
+
+ get_runstate_snapshot(&runstate);
+
+ WARN_ON(runstate.state != RUNSTATE_running);
+
+ offset = 0;
+ if (now > runstate.state_entry_time)
+ offset = now - runstate.state_entry_time;
+ ret = runstate.time[RUNSTATE_blocked] +
+ runstate.time[RUNSTATE_running] +
+ offset;
+
+ preempt_enable();
+
+ return ret;
+}
+
struct pv_time_ops xen_time_ops __initdata = {
.init_missing_ticks_accounting = xen_init_missing_ticks_accounting,
.do_steal_accounting = xen_do_steal_accounting,
.clocksource_resume = xen_itc_jitter_data_reset,
+ .sched_clock = xen_sched_clock,
};
/* Called after suspend, to resume time. */
diff --git a/arch/ia64/xen/xen_pv_ops.c b/arch/ia64/xen/xen_pv_ops.c
index 936cff3c96e0..5e2270a999fa 100644
--- a/arch/ia64/xen/xen_pv_ops.c
+++ b/arch/ia64/xen/xen_pv_ops.c
@@ -24,6 +24,7 @@
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/pm.h>
+#include <linux/unistd.h>
#include <asm/xen/hypervisor.h>
#include <asm/xen/xencomm.h>
@@ -153,6 +154,13 @@ xen_post_smp_prepare_boot_cpu(void)
xen_setup_vcpu_info_placement();
}
+#ifdef ASM_SUPPORTED
+static unsigned long __init_or_module
+xen_patch_bundle(void *sbundle, void *ebundle, unsigned long type);
+#endif
+static void __init
+xen_patch_branch(unsigned long tag, unsigned long type);
+
static const struct pv_init_ops xen_init_ops __initconst = {
.banner = xen_banner,
@@ -163,6 +171,53 @@ static const struct pv_init_ops xen_init_ops __initconst = {
.arch_setup_nomca = xen_arch_setup_nomca,
.post_smp_prepare_boot_cpu = xen_post_smp_prepare_boot_cpu,
+#ifdef ASM_SUPPORTED
+ .patch_bundle = xen_patch_bundle,
+#endif
+ .patch_branch = xen_patch_branch,
+};
+
+/***************************************************************************
+ * pv_fsys_data
+ * addresses for fsys
+ */
+
+extern unsigned long xen_fsyscall_table[NR_syscalls];
+extern char xen_fsys_bubble_down[];
+struct pv_fsys_data xen_fsys_data __initdata = {
+ .fsyscall_table = (unsigned long *)xen_fsyscall_table,
+ .fsys_bubble_down = (void *)xen_fsys_bubble_down,
+};
+
+/***************************************************************************
+ * pv_patchdata
+ * patchdata addresses
+ */
+
+#define DECLARE(name) \
+ extern unsigned long __xen_start_gate_##name##_patchlist[]; \
+ extern unsigned long __xen_end_gate_##name##_patchlist[]
+
+DECLARE(fsyscall);
+DECLARE(brl_fsys_bubble_down);
+DECLARE(vtop);
+DECLARE(mckinley_e9);
+
+extern unsigned long __xen_start_gate_section[];
+
+#define ASSIGN(name) \
+ .start_##name##_patchlist = \
+ (unsigned long)__xen_start_gate_##name##_patchlist, \
+ .end_##name##_patchlist = \
+ (unsigned long)__xen_end_gate_##name##_patchlist
+
+static struct pv_patchdata xen_patchdata __initdata = {
+ ASSIGN(fsyscall),
+ ASSIGN(brl_fsys_bubble_down),
+ ASSIGN(vtop),
+ ASSIGN(mckinley_e9),
+
+ .gate_section = (void*)__xen_start_gate_section,
};
/***************************************************************************
@@ -170,6 +225,76 @@ static const struct pv_init_ops xen_init_ops __initconst = {
* intrinsics hooks.
*/
+#ifndef ASM_SUPPORTED
+static void
+xen_set_itm_with_offset(unsigned long val)
+{
+ /* ia64_cpu_local_tick() calls this with interrupt enabled. */
+ /* WARN_ON(!irqs_disabled()); */
+ xen_set_itm(val - XEN_MAPPEDREGS->itc_offset);
+}
+
+static unsigned long
+xen_get_itm_with_offset(void)
+{
+ /* unused at this moment */
+ printk(KERN_DEBUG "%s is called.\n", __func__);
+
+ WARN_ON(!irqs_disabled());
+ return ia64_native_getreg(_IA64_REG_CR_ITM) +
+ XEN_MAPPEDREGS->itc_offset;
+}
+
+/* ia64_set_itc() is only called by
+ * cpu_init() with ia64_set_itc(0) and ia64_sync_itc().
+ * So XEN_MAPPEDRESG->itc_offset cal be considered as almost constant.
+ */
+static void
+xen_set_itc(unsigned long val)
+{
+ unsigned long mitc;
+
+ WARN_ON(!irqs_disabled());
+ mitc = ia64_native_getreg(_IA64_REG_AR_ITC);
+ XEN_MAPPEDREGS->itc_offset = val - mitc;
+ XEN_MAPPEDREGS->itc_last = val;
+}
+
+static unsigned long
+xen_get_itc(void)
+{
+ unsigned long res;
+ unsigned long itc_offset;
+ unsigned long itc_last;
+ unsigned long ret_itc_last;
+
+ itc_offset = XEN_MAPPEDREGS->itc_offset;
+ do {
+ itc_last = XEN_MAPPEDREGS->itc_last;
+ res = ia64_native_getreg(_IA64_REG_AR_ITC);
+ res += itc_offset;
+ if (itc_last >= res)
+ res = itc_last + 1;
+ ret_itc_last = cmpxchg(&XEN_MAPPEDREGS->itc_last,
+ itc_last, res);
+ } while (unlikely(ret_itc_last != itc_last));
+ return res;
+
+#if 0
+ /* ia64_itc_udelay() calls ia64_get_itc() with interrupt enabled.
+ Should it be paravirtualized instead? */
+ WARN_ON(!irqs_disabled());
+ itc_offset = XEN_MAPPEDREGS->itc_offset;
+ itc_last = XEN_MAPPEDREGS->itc_last;
+ res = ia64_native_getreg(_IA64_REG_AR_ITC);
+ res += itc_offset;
+ if (itc_last >= res)
+ res = itc_last + 1;
+ XEN_MAPPEDREGS->itc_last = res;
+ return res;
+#endif
+}
+
static void xen_setreg(int regnum, unsigned long val)
{
switch (regnum) {
@@ -181,11 +306,14 @@ static void xen_setreg(int regnum, unsigned long val)
xen_set_eflag(val);
break;
#endif
+ case _IA64_REG_AR_ITC:
+ xen_set_itc(val);
+ break;
case _IA64_REG_CR_TPR:
xen_set_tpr(val);
break;
case _IA64_REG_CR_ITM:
- xen_set_itm(val);
+ xen_set_itm_with_offset(val);
break;
case _IA64_REG_CR_EOI:
xen_eoi(val);
@@ -209,6 +337,12 @@ static unsigned long xen_getreg(int regnum)
res = xen_get_eflag();
break;
#endif
+ case _IA64_REG_AR_ITC:
+ res = xen_get_itc();
+ break;
+ case _IA64_REG_CR_ITM:
+ res = xen_get_itm_with_offset();
+ break;
case _IA64_REG_CR_IVR:
res = xen_get_ivr();
break;
@@ -259,8 +393,417 @@ xen_intrin_local_irq_restore(unsigned long mask)
else
xen_rsm_i();
}
+#else
+#define __DEFINE_FUNC(name, code) \
+ extern const char xen_ ## name ## _direct_start[]; \
+ extern const char xen_ ## name ## _direct_end[]; \
+ asm (".align 32\n" \
+ ".proc xen_" #name "\n" \
+ "xen_" #name ":\n" \
+ "xen_" #name "_direct_start:\n" \
+ code \
+ "xen_" #name "_direct_end:\n" \
+ "br.cond.sptk.many b6\n" \
+ ".endp xen_" #name "\n")
+
+#define DEFINE_VOID_FUNC0(name, code) \
+ extern void \
+ xen_ ## name (void); \
+ __DEFINE_FUNC(name, code)
+
+#define DEFINE_VOID_FUNC1(name, code) \
+ extern void \
+ xen_ ## name (unsigned long arg); \
+ __DEFINE_FUNC(name, code)
+
+#define DEFINE_VOID_FUNC1_VOID(name, code) \
+ extern void \
+ xen_ ## name (void *arg); \
+ __DEFINE_FUNC(name, code)
+
+#define DEFINE_VOID_FUNC2(name, code) \
+ extern void \
+ xen_ ## name (unsigned long arg0, \
+ unsigned long arg1); \
+ __DEFINE_FUNC(name, code)
-static const struct pv_cpu_ops xen_cpu_ops __initdata = {
+#define DEFINE_FUNC0(name, code) \
+ extern unsigned long \
+ xen_ ## name (void); \
+ __DEFINE_FUNC(name, code)
+
+#define DEFINE_FUNC1(name, type, code) \
+ extern unsigned long \
+ xen_ ## name (type arg); \
+ __DEFINE_FUNC(name, code)
+
+#define XEN_PSR_I_ADDR_ADDR (XSI_BASE + XSI_PSR_I_ADDR_OFS)
+
+/*
+ * static void xen_set_itm_with_offset(unsigned long val)
+ * xen_set_itm(val - XEN_MAPPEDREGS->itc_offset);
+ */
+/* 2 bundles */
+DEFINE_VOID_FUNC1(set_itm_with_offset,
+ "mov r2 = " __stringify(XSI_BASE) " + "
+ __stringify(XSI_ITC_OFFSET_OFS) "\n"
+ ";;\n"
+ "ld8 r3 = [r2]\n"
+ ";;\n"
+ "sub r8 = r8, r3\n"
+ "break " __stringify(HYPERPRIVOP_SET_ITM) "\n");
+
+/*
+ * static unsigned long xen_get_itm_with_offset(void)
+ * return ia64_native_getreg(_IA64_REG_CR_ITM) + XEN_MAPPEDREGS->itc_offset;
+ */
+/* 2 bundles */
+DEFINE_FUNC0(get_itm_with_offset,
+ "mov r2 = " __stringify(XSI_BASE) " + "
+ __stringify(XSI_ITC_OFFSET_OFS) "\n"
+ ";;\n"
+ "ld8 r3 = [r2]\n"
+ "mov r8 = cr.itm\n"
+ ";;\n"
+ "add r8 = r8, r2\n");
+
+/*
+ * static void xen_set_itc(unsigned long val)
+ * unsigned long mitc;
+ *
+ * WARN_ON(!irqs_disabled());
+ * mitc = ia64_native_getreg(_IA64_REG_AR_ITC);
+ * XEN_MAPPEDREGS->itc_offset = val - mitc;
+ * XEN_MAPPEDREGS->itc_last = val;
+ */
+/* 2 bundles */
+DEFINE_VOID_FUNC1(set_itc,
+ "mov r2 = " __stringify(XSI_BASE) " + "
+ __stringify(XSI_ITC_LAST_OFS) "\n"
+ "mov r3 = ar.itc\n"
+ ";;\n"
+ "sub r3 = r8, r3\n"
+ "st8 [r2] = r8, "
+ __stringify(XSI_ITC_LAST_OFS) " - "
+ __stringify(XSI_ITC_OFFSET_OFS) "\n"
+ ";;\n"
+ "st8 [r2] = r3\n");
+
+/*
+ * static unsigned long xen_get_itc(void)
+ * unsigned long res;
+ * unsigned long itc_offset;
+ * unsigned long itc_last;
+ * unsigned long ret_itc_last;
+ *
+ * itc_offset = XEN_MAPPEDREGS->itc_offset;
+ * do {
+ * itc_last = XEN_MAPPEDREGS->itc_last;
+ * res = ia64_native_getreg(_IA64_REG_AR_ITC);
+ * res += itc_offset;
+ * if (itc_last >= res)
+ * res = itc_last + 1;
+ * ret_itc_last = cmpxchg(&XEN_MAPPEDREGS->itc_last,
+ * itc_last, res);
+ * } while (unlikely(ret_itc_last != itc_last));
+ * return res;
+ */
+/* 5 bundles */
+DEFINE_FUNC0(get_itc,
+ "mov r2 = " __stringify(XSI_BASE) " + "
+ __stringify(XSI_ITC_OFFSET_OFS) "\n"
+ ";;\n"
+ "ld8 r9 = [r2], " __stringify(XSI_ITC_LAST_OFS) " - "
+ __stringify(XSI_ITC_OFFSET_OFS) "\n"
+ /* r9 = itc_offset */
+ /* r2 = XSI_ITC_OFFSET */
+ "888:\n"
+ "mov r8 = ar.itc\n" /* res = ar.itc */
+ ";;\n"
+ "ld8 r3 = [r2]\n" /* r3 = itc_last */
+ "add r8 = r8, r9\n" /* res = ar.itc + itc_offset */
+ ";;\n"
+ "cmp.gtu p6, p0 = r3, r8\n"
+ ";;\n"
+ "(p6) add r8 = 1, r3\n" /* if (itc_last > res) itc_last + 1 */
+ ";;\n"
+ "mov ar.ccv = r8\n"
+ ";;\n"
+ "cmpxchg8.acq r10 = [r2], r8, ar.ccv\n"
+ ";;\n"
+ "cmp.ne p6, p0 = r10, r3\n"
+ "(p6) hint @pause\n"
+ "(p6) br.cond.spnt 888b\n");
+
+DEFINE_VOID_FUNC1_VOID(fc,
+ "break " __stringify(HYPERPRIVOP_FC) "\n");
+
+/*
+ * psr_i_addr_addr = XEN_PSR_I_ADDR_ADDR
+ * masked_addr = *psr_i_addr_addr
+ * pending_intr_addr = masked_addr - 1
+ * if (val & IA64_PSR_I) {
+ * masked = *masked_addr
+ * *masked_addr = 0:xen_set_virtual_psr_i(1)
+ * compiler barrier
+ * if (masked) {
+ * uint8_t pending = *pending_intr_addr;
+ * if (pending)
+ * XEN_HYPER_SSM_I
+ * }
+ * } else {
+ * *masked_addr = 1:xen_set_virtual_psr_i(0)
+ * }
+ */
+/* 6 bundles */
+DEFINE_VOID_FUNC1(intrin_local_irq_restore,
+ /* r8 = input value: 0 or IA64_PSR_I
+ * p6 = (flags & IA64_PSR_I)
+ * = if clause
+ * p7 = !(flags & IA64_PSR_I)
+ * = else clause
+ */
+ "cmp.ne p6, p7 = r8, r0\n"
+ "mov r9 = " __stringify(XEN_PSR_I_ADDR_ADDR) "\n"
+ ";;\n"
+ /* r9 = XEN_PSR_I_ADDR */
+ "ld8 r9 = [r9]\n"
+ ";;\n"
+
+ /* r10 = masked previous value */
+ "(p6) ld1.acq r10 = [r9]\n"
+ ";;\n"
+
+ /* p8 = !masked interrupt masked previously? */
+ "(p6) cmp.ne.unc p8, p0 = r10, r0\n"
+
+ /* p7 = else clause */
+ "(p7) mov r11 = 1\n"
+ ";;\n"
+ /* masked = 1 */
+ "(p7) st1.rel [r9] = r11\n"
+
+ /* p6 = if clause */
+ /* masked = 0
+ * r9 = masked_addr - 1
+ * = pending_intr_addr
+ */
+ "(p8) st1.rel [r9] = r0, -1\n"
+ ";;\n"
+ /* r8 = pending_intr */
+ "(p8) ld1.acq r11 = [r9]\n"
+ ";;\n"
+ /* p9 = interrupt pending? */
+ "(p8) cmp.ne.unc p9, p10 = r11, r0\n"
+ ";;\n"
+ "(p10) mf\n"
+ /* issue hypercall to trigger interrupt */
+ "(p9) break " __stringify(HYPERPRIVOP_SSM_I) "\n");
+
+DEFINE_VOID_FUNC2(ptcga,
+ "break " __stringify(HYPERPRIVOP_PTC_GA) "\n");
+DEFINE_VOID_FUNC2(set_rr,
+ "break " __stringify(HYPERPRIVOP_SET_RR) "\n");
+
+/*
+ * tmp = XEN_MAPPEDREGS->interrupt_mask_addr = XEN_PSR_I_ADDR_ADDR;
+ * tmp = *tmp
+ * tmp = *tmp;
+ * psr_i = tmp? 0: IA64_PSR_I;
+ */
+/* 4 bundles */
+DEFINE_FUNC0(get_psr_i,
+ "mov r9 = " __stringify(XEN_PSR_I_ADDR_ADDR) "\n"
+ ";;\n"
+ "ld8 r9 = [r9]\n" /* r9 = XEN_PSR_I_ADDR */
+ "mov r8 = 0\n" /* psr_i = 0 */
+ ";;\n"
+ "ld1.acq r9 = [r9]\n" /* r9 = XEN_PSR_I */
+ ";;\n"
+ "cmp.eq.unc p6, p0 = r9, r0\n" /* p6 = (XEN_PSR_I != 0) */
+ ";;\n"
+ "(p6) mov r8 = " __stringify(1 << IA64_PSR_I_BIT) "\n");
+
+DEFINE_FUNC1(thash, unsigned long,
+ "break " __stringify(HYPERPRIVOP_THASH) "\n");
+DEFINE_FUNC1(get_cpuid, int,
+ "break " __stringify(HYPERPRIVOP_GET_CPUID) "\n");
+DEFINE_FUNC1(get_pmd, int,
+ "break " __stringify(HYPERPRIVOP_GET_PMD) "\n");
+DEFINE_FUNC1(get_rr, unsigned long,
+ "break " __stringify(HYPERPRIVOP_GET_RR) "\n");
+
+/*
+ * void xen_privop_ssm_i(void)
+ *
+ * int masked = !xen_get_virtual_psr_i();
+ * // masked = *(*XEN_MAPPEDREGS->interrupt_mask_addr)
+ * xen_set_virtual_psr_i(1)
+ * // *(*XEN_MAPPEDREGS->interrupt_mask_addr) = 0
+ * // compiler barrier
+ * if (masked) {
+ * uint8_t* pend_int_addr =
+ * (uint8_t*)(*XEN_MAPPEDREGS->interrupt_mask_addr) - 1;
+ * uint8_t pending = *pend_int_addr;
+ * if (pending)
+ * XEN_HYPER_SSM_I
+ * }
+ */
+/* 4 bundles */
+DEFINE_VOID_FUNC0(ssm_i,
+ "mov r8 = " __stringify(XEN_PSR_I_ADDR_ADDR) "\n"
+ ";;\n"
+ "ld8 r8 = [r8]\n" /* r8 = XEN_PSR_I_ADDR */
+ ";;\n"
+ "ld1.acq r9 = [r8]\n" /* r9 = XEN_PSR_I */
+ ";;\n"
+ "st1.rel [r8] = r0, -1\n" /* psr_i = 0. enable interrupt
+ * r8 = XEN_PSR_I_ADDR - 1
+ * = pend_int_addr
+ */
+ "cmp.eq.unc p0, p6 = r9, r0\n"/* p6 = !XEN_PSR_I
+ * previously interrupt
+ * masked?
+ */
+ ";;\n"
+ "(p6) ld1.acq r8 = [r8]\n" /* r8 = xen_pend_int */
+ ";;\n"
+ "(p6) cmp.eq.unc p6, p7 = r8, r0\n" /*interrupt pending?*/
+ ";;\n"
+ /* issue hypercall to get interrupt */
+ "(p7) break " __stringify(HYPERPRIVOP_SSM_I) "\n"
+ ";;\n");
+
+/*
+ * psr_i_addr_addr = XEN_MAPPEDREGS->interrupt_mask_addr
+ * = XEN_PSR_I_ADDR_ADDR;
+ * psr_i_addr = *psr_i_addr_addr;
+ * *psr_i_addr = 1;
+ */
+/* 2 bundles */
+DEFINE_VOID_FUNC0(rsm_i,
+ "mov r8 = " __stringify(XEN_PSR_I_ADDR_ADDR) "\n"
+ /* r8 = XEN_PSR_I_ADDR */
+ "mov r9 = 1\n"
+ ";;\n"
+ "ld8 r8 = [r8]\n" /* r8 = XEN_PSR_I */
+ ";;\n"
+ "st1.rel [r8] = r9\n"); /* XEN_PSR_I = 1 */
+
+extern void
+xen_set_rr0_to_rr4(unsigned long val0, unsigned long val1,
+ unsigned long val2, unsigned long val3,
+ unsigned long val4);
+__DEFINE_FUNC(set_rr0_to_rr4,
+ "break " __stringify(HYPERPRIVOP_SET_RR0_TO_RR4) "\n");
+
+
+extern unsigned long xen_getreg(int regnum);
+#define __DEFINE_GET_REG(id, privop) \
+ "mov r2 = " __stringify(_IA64_REG_ ## id) "\n" \
+ ";;\n" \
+ "cmp.eq p6, p0 = r2, r8\n" \
+ ";;\n" \
+ "(p6) break " __stringify(HYPERPRIVOP_GET_ ## privop) "\n" \
+ "(p6) br.cond.sptk.many b6\n" \
+ ";;\n"
+
+__DEFINE_FUNC(getreg,
+ __DEFINE_GET_REG(PSR, PSR)
+#ifdef CONFIG_IA32_SUPPORT
+ __DEFINE_GET_REG(AR_EFLAG, EFLAG)
+#endif
+
+ /* get_itc */
+ "mov r2 = " __stringify(_IA64_REG_AR_ITC) "\n"
+ ";;\n"
+ "cmp.eq p6, p0 = r2, r8\n"
+ ";;\n"
+ "(p6) br.cond.spnt xen_get_itc\n"
+ ";;\n"
+
+ /* get itm */
+ "mov r2 = " __stringify(_IA64_REG_CR_ITM) "\n"
+ ";;\n"
+ "cmp.eq p6, p0 = r2, r8\n"
+ ";;\n"
+ "(p6) br.cond.spnt xen_get_itm_with_offset\n"
+ ";;\n"
+
+ __DEFINE_GET_REG(CR_IVR, IVR)
+ __DEFINE_GET_REG(CR_TPR, TPR)
+
+ /* fall back */
+ "movl r2 = ia64_native_getreg_func\n"
+ ";;\n"
+ "mov b7 = r2\n"
+ ";;\n"
+ "br.cond.sptk.many b7\n");
+
+extern void xen_setreg(int regnum, unsigned long val);
+#define __DEFINE_SET_REG(id, privop) \
+ "mov r2 = " __stringify(_IA64_REG_ ## id) "\n" \
+ ";;\n" \
+ "cmp.eq p6, p0 = r2, r9\n" \
+ ";;\n" \
+ "(p6) break " __stringify(HYPERPRIVOP_ ## privop) "\n" \
+ "(p6) br.cond.sptk.many b6\n" \
+ ";;\n"
+
+__DEFINE_FUNC(setreg,
+ /* kr0 .. kr 7*/
+ /*
+ * if (_IA64_REG_AR_KR0 <= regnum &&
+ * regnum <= _IA64_REG_AR_KR7) {
+ * register __index asm ("r8") = regnum - _IA64_REG_AR_KR0
+ * register __val asm ("r9") = val
+ * "break HYPERPRIVOP_SET_KR"
+ * }
+ */
+ "mov r17 = r9\n"
+ "mov r2 = " __stringify(_IA64_REG_AR_KR0) "\n"
+ ";;\n"
+ "cmp.ge p6, p0 = r9, r2\n"
+ "sub r17 = r17, r2\n"
+ ";;\n"
+ "(p6) cmp.ge.unc p7, p0 = "
+ __stringify(_IA64_REG_AR_KR7) " - " __stringify(_IA64_REG_AR_KR0)
+ ", r17\n"
+ ";;\n"
+ "(p7) mov r9 = r8\n"
+ ";;\n"
+ "(p7) mov r8 = r17\n"
+ "(p7) break " __stringify(HYPERPRIVOP_SET_KR) "\n"
+
+ /* set itm */
+ "mov r2 = " __stringify(_IA64_REG_CR_ITM) "\n"
+ ";;\n"
+ "cmp.eq p6, p0 = r2, r8\n"
+ ";;\n"
+ "(p6) br.cond.spnt xen_set_itm_with_offset\n"
+
+ /* set itc */
+ "mov r2 = " __stringify(_IA64_REG_AR_ITC) "\n"
+ ";;\n"
+ "cmp.eq p6, p0 = r2, r8\n"
+ ";;\n"
+ "(p6) br.cond.spnt xen_set_itc\n"
+
+#ifdef CONFIG_IA32_SUPPORT
+ __DEFINE_SET_REG(AR_EFLAG, SET_EFLAG)
+#endif
+ __DEFINE_SET_REG(CR_TPR, SET_TPR)
+ __DEFINE_SET_REG(CR_EOI, EOI)
+
+ /* fall back */
+ "movl r2 = ia64_native_setreg_func\n"
+ ";;\n"
+ "mov b7 = r2\n"
+ ";;\n"
+ "br.cond.sptk.many b7\n");
+#endif
+
+static const struct pv_cpu_ops xen_cpu_ops __initconst = {
.fc = xen_fc,
.thash = xen_thash,
.get_cpuid = xen_get_cpuid,
@@ -337,7 +880,7 @@ xen_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
}
-static const struct pv_iosapic_ops xen_iosapic_ops __initconst = {
+static struct pv_iosapic_ops xen_iosapic_ops __initdata = {
.pcat_compat_init = xen_pcat_compat_init,
.__get_irq_chip = xen_iosapic_get_irq_chip,
@@ -355,6 +898,8 @@ xen_setup_pv_ops(void)
xen_info_init();
pv_info = xen_info;
pv_init_ops = xen_init_ops;
+ pv_fsys_data = xen_fsys_data;
+ pv_patchdata = xen_patchdata;
pv_cpu_ops = xen_cpu_ops;
pv_iosapic_ops = xen_iosapic_ops;
pv_irq_ops = xen_irq_ops;
@@ -362,3 +907,252 @@ xen_setup_pv_ops(void)
paravirt_cpu_asm_init(&xen_cpu_asm_switch);
}
+
+#ifdef ASM_SUPPORTED
+/***************************************************************************
+ * binary pacthing
+ * pv_init_ops.patch_bundle
+ */
+
+#define DEFINE_FUNC_GETREG(name, privop) \
+ DEFINE_FUNC0(get_ ## name, \
+ "break "__stringify(HYPERPRIVOP_GET_ ## privop) "\n")
+
+DEFINE_FUNC_GETREG(psr, PSR);
+DEFINE_FUNC_GETREG(eflag, EFLAG);
+DEFINE_FUNC_GETREG(ivr, IVR);
+DEFINE_FUNC_GETREG(tpr, TPR);
+
+#define DEFINE_FUNC_SET_KR(n) \
+ DEFINE_VOID_FUNC0(set_kr ## n, \
+ ";;\n" \
+ "mov r9 = r8\n" \
+ "mov r8 = " #n "\n" \
+ "break " __stringify(HYPERPRIVOP_SET_KR) "\n")
+
+DEFINE_FUNC_SET_KR(0);
+DEFINE_FUNC_SET_KR(1);
+DEFINE_FUNC_SET_KR(2);
+DEFINE_FUNC_SET_KR(3);
+DEFINE_FUNC_SET_KR(4);
+DEFINE_FUNC_SET_KR(5);
+DEFINE_FUNC_SET_KR(6);
+DEFINE_FUNC_SET_KR(7);
+
+#define __DEFINE_FUNC_SETREG(name, privop) \
+ DEFINE_VOID_FUNC0(name, \
+ "break "__stringify(HYPERPRIVOP_ ## privop) "\n")
+
+#define DEFINE_FUNC_SETREG(name, privop) \
+ __DEFINE_FUNC_SETREG(set_ ## name, SET_ ## privop)
+
+DEFINE_FUNC_SETREG(eflag, EFLAG);
+DEFINE_FUNC_SETREG(tpr, TPR);
+__DEFINE_FUNC_SETREG(eoi, EOI);
+
+extern const char xen_check_events[];
+extern const char __xen_intrin_local_irq_restore_direct_start[];
+extern const char __xen_intrin_local_irq_restore_direct_end[];
+extern const unsigned long __xen_intrin_local_irq_restore_direct_reloc;
+
+asm (
+ ".align 32\n"
+ ".proc xen_check_events\n"
+ "xen_check_events:\n"
+ /* masked = 0
+ * r9 = masked_addr - 1
+ * = pending_intr_addr
+ */
+ "st1.rel [r9] = r0, -1\n"
+ ";;\n"
+ /* r8 = pending_intr */
+ "ld1.acq r11 = [r9]\n"
+ ";;\n"
+ /* p9 = interrupt pending? */
+ "cmp.ne p9, p10 = r11, r0\n"
+ ";;\n"
+ "(p10) mf\n"
+ /* issue hypercall to trigger interrupt */
+ "(p9) break " __stringify(HYPERPRIVOP_SSM_I) "\n"
+ "br.cond.sptk.many b6\n"
+ ".endp xen_check_events\n"
+ "\n"
+ ".align 32\n"
+ ".proc __xen_intrin_local_irq_restore_direct\n"
+ "__xen_intrin_local_irq_restore_direct:\n"
+ "__xen_intrin_local_irq_restore_direct_start:\n"
+ "1:\n"
+ "{\n"
+ "cmp.ne p6, p7 = r8, r0\n"
+ "mov r17 = ip\n" /* get ip to calc return address */
+ "mov r9 = "__stringify(XEN_PSR_I_ADDR_ADDR) "\n"
+ ";;\n"
+ "}\n"
+ "{\n"
+ /* r9 = XEN_PSR_I_ADDR */
+ "ld8 r9 = [r9]\n"
+ ";;\n"
+ /* r10 = masked previous value */
+ "(p6) ld1.acq r10 = [r9]\n"
+ "adds r17 = 1f - 1b, r17\n" /* calculate return address */
+ ";;\n"
+ "}\n"
+ "{\n"
+ /* p8 = !masked interrupt masked previously? */
+ "(p6) cmp.ne.unc p8, p0 = r10, r0\n"
+ "\n"
+ /* p7 = else clause */
+ "(p7) mov r11 = 1\n"
+ ";;\n"
+ "(p8) mov b6 = r17\n" /* set return address */
+ "}\n"
+ "{\n"
+ /* masked = 1 */
+ "(p7) st1.rel [r9] = r11\n"
+ "\n"
+ "[99:]\n"
+ "(p8) brl.cond.dptk.few xen_check_events\n"
+ "}\n"
+ /* pv calling stub is 5 bundles. fill nop to adjust return address */
+ "{\n"
+ "nop 0\n"
+ "nop 0\n"
+ "nop 0\n"
+ "}\n"
+ "1:\n"
+ "__xen_intrin_local_irq_restore_direct_end:\n"
+ ".endp __xen_intrin_local_irq_restore_direct\n"
+ "\n"
+ ".align 8\n"
+ "__xen_intrin_local_irq_restore_direct_reloc:\n"
+ "data8 99b\n"
+);
+
+static struct paravirt_patch_bundle_elem xen_patch_bundle_elems[]
+__initdata_or_module =
+{
+#define XEN_PATCH_BUNDLE_ELEM(name, type) \
+ { \
+ (void*)xen_ ## name ## _direct_start, \
+ (void*)xen_ ## name ## _direct_end, \
+ PARAVIRT_PATCH_TYPE_ ## type, \
+ }
+
+ XEN_PATCH_BUNDLE_ELEM(fc, FC),
+ XEN_PATCH_BUNDLE_ELEM(thash, THASH),
+ XEN_PATCH_BUNDLE_ELEM(get_cpuid, GET_CPUID),
+ XEN_PATCH_BUNDLE_ELEM(get_pmd, GET_PMD),
+ XEN_PATCH_BUNDLE_ELEM(ptcga, PTCGA),
+ XEN_PATCH_BUNDLE_ELEM(get_rr, GET_RR),
+ XEN_PATCH_BUNDLE_ELEM(set_rr, SET_RR),
+ XEN_PATCH_BUNDLE_ELEM(set_rr0_to_rr4, SET_RR0_TO_RR4),
+ XEN_PATCH_BUNDLE_ELEM(ssm_i, SSM_I),
+ XEN_PATCH_BUNDLE_ELEM(rsm_i, RSM_I),
+ XEN_PATCH_BUNDLE_ELEM(get_psr_i, GET_PSR_I),
+ {
+ (void*)__xen_intrin_local_irq_restore_direct_start,
+ (void*)__xen_intrin_local_irq_restore_direct_end,
+ PARAVIRT_PATCH_TYPE_INTRIN_LOCAL_IRQ_RESTORE,
+ },
+
+#define XEN_PATCH_BUNDLE_ELEM_GETREG(name, reg) \
+ { \
+ xen_get_ ## name ## _direct_start, \
+ xen_get_ ## name ## _direct_end, \
+ PARAVIRT_PATCH_TYPE_GETREG + _IA64_REG_ ## reg, \
+ }
+
+ XEN_PATCH_BUNDLE_ELEM_GETREG(psr, PSR),
+ XEN_PATCH_BUNDLE_ELEM_GETREG(eflag, AR_EFLAG),
+
+ XEN_PATCH_BUNDLE_ELEM_GETREG(ivr, CR_IVR),
+ XEN_PATCH_BUNDLE_ELEM_GETREG(tpr, CR_TPR),
+
+ XEN_PATCH_BUNDLE_ELEM_GETREG(itc, AR_ITC),
+ XEN_PATCH_BUNDLE_ELEM_GETREG(itm_with_offset, CR_ITM),
+
+
+#define __XEN_PATCH_BUNDLE_ELEM_SETREG(name, reg) \
+ { \
+ xen_ ## name ## _direct_start, \
+ xen_ ## name ## _direct_end, \
+ PARAVIRT_PATCH_TYPE_SETREG + _IA64_REG_ ## reg, \
+ }
+
+#define XEN_PATCH_BUNDLE_ELEM_SETREG(name, reg) \
+ __XEN_PATCH_BUNDLE_ELEM_SETREG(set_ ## name, reg)
+
+ XEN_PATCH_BUNDLE_ELEM_SETREG(kr0, AR_KR0),
+ XEN_PATCH_BUNDLE_ELEM_SETREG(kr1, AR_KR1),
+ XEN_PATCH_BUNDLE_ELEM_SETREG(kr2, AR_KR2),
+ XEN_PATCH_BUNDLE_ELEM_SETREG(kr3, AR_KR3),
+ XEN_PATCH_BUNDLE_ELEM_SETREG(kr4, AR_KR4),
+ XEN_PATCH_BUNDLE_ELEM_SETREG(kr5, AR_KR5),
+ XEN_PATCH_BUNDLE_ELEM_SETREG(kr6, AR_KR6),
+ XEN_PATCH_BUNDLE_ELEM_SETREG(kr7, AR_KR7),
+
+ XEN_PATCH_BUNDLE_ELEM_SETREG(eflag, AR_EFLAG),
+ XEN_PATCH_BUNDLE_ELEM_SETREG(tpr, CR_TPR),
+ __XEN_PATCH_BUNDLE_ELEM_SETREG(eoi, CR_EOI),
+
+ XEN_PATCH_BUNDLE_ELEM_SETREG(itc, AR_ITC),
+ XEN_PATCH_BUNDLE_ELEM_SETREG(itm_with_offset, CR_ITM),
+};
+
+static unsigned long __init_or_module
+xen_patch_bundle(void *sbundle, void *ebundle, unsigned long type)
+{
+ const unsigned long nelems = sizeof(xen_patch_bundle_elems) /
+ sizeof(xen_patch_bundle_elems[0]);
+ unsigned long used;
+ const struct paravirt_patch_bundle_elem *found;
+
+ used = __paravirt_patch_apply_bundle(sbundle, ebundle, type,
+ xen_patch_bundle_elems, nelems,
+ &found);
+
+ if (found == NULL)
+ /* fallback */
+ return ia64_native_patch_bundle(sbundle, ebundle, type);
+ if (used == 0)
+ return used;
+
+ /* relocation */
+ switch (type) {
+ case PARAVIRT_PATCH_TYPE_INTRIN_LOCAL_IRQ_RESTORE: {
+ unsigned long reloc =
+ __xen_intrin_local_irq_restore_direct_reloc;
+ unsigned long reloc_offset = reloc - (unsigned long)
+ __xen_intrin_local_irq_restore_direct_start;
+ unsigned long tag = (unsigned long)sbundle + reloc_offset;
+ paravirt_patch_reloc_brl(tag, xen_check_events);
+ break;
+ }
+ default:
+ /* nothing */
+ break;
+ }
+ return used;
+}
+#endif /* ASM_SUPPOTED */
+
+const struct paravirt_patch_branch_target xen_branch_target[]
+__initconst = {
+#define PARAVIRT_BR_TARGET(name, type) \
+ { \
+ &xen_ ## name, \
+ PARAVIRT_PATCH_TYPE_BR_ ## type, \
+ }
+ PARAVIRT_BR_TARGET(switch_to, SWITCH_TO),
+ PARAVIRT_BR_TARGET(leave_syscall, LEAVE_SYSCALL),
+ PARAVIRT_BR_TARGET(work_processed_syscall, WORK_PROCESSED_SYSCALL),
+ PARAVIRT_BR_TARGET(leave_kernel, LEAVE_KERNEL),
+};
+
+static void __init
+xen_patch_branch(unsigned long tag, unsigned long type)
+{
+ const unsigned long nelem =
+ sizeof(xen_branch_target) / sizeof(xen_branch_target[0]);
+ __paravirt_patch_apply_branch(tag, type, xen_branch_target, nelem);
+}
diff --git a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c
index 2aeae4670098..8dfd31e87c4c 100644
--- a/arch/m32r/kernel/irq.c
+++ b/arch/m32r/kernel/irq.c
@@ -49,7 +49,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%10u ", kstat_irqs(i));
#else
for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#endif
seq_printf(p, " %14s", irq_desc[i].chip->typename);
seq_printf(p, " %s", action->name);
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index 7103d91e1a2f..3e876f0baebc 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -225,7 +225,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
return 0; /* Task didn't use the fpu at all. */
}
-int copy_thread(int nr, unsigned long clone_flags, unsigned long spu,
+int copy_thread(unsigned long clone_flags, unsigned long spu,
unsigned long unused, struct task_struct *tsk, struct pt_regs *regs)
{
struct pt_regs *childregs = task_pt_regs(tsk);
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index 6ea017727cce..cada3ba4b990 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -230,7 +230,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
static struct irqaction irq0 = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED,
- .mask = CPU_MASK_NONE,
.name = "MFT2",
};
diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile
index 8133dbc44964..570d85c3f97f 100644
--- a/arch/m68k/Makefile
+++ b/arch/m68k/Makefile
@@ -117,3 +117,6 @@ endif
archclean:
rm -f vmlinux.gz vmlinux.bz2
+
+install:
+ sh $(srctree)/arch/m68k/install.sh $(KERNELRELEASE) vmlinux.gz System.map "$(INSTALL_PATH)"
diff --git a/arch/m68k/include/asm/bootinfo.h b/arch/m68k/include/asm/bootinfo.h
index fedf3e326121..fb8a06b9ab6a 100644
--- a/arch/m68k/include/asm/bootinfo.h
+++ b/arch/m68k/include/asm/bootinfo.h
@@ -1,5 +1,378 @@
-#ifdef __uClinux__
-#include "bootinfo_no.h"
-#else
-#include "bootinfo_mm.h"
+/*
+** asm/bootinfo.h -- Definition of the Linux/m68k boot information structure
+**
+** Copyright 1992 by Greg Harp
+**
+** This file is subject to the terms and conditions of the GNU General Public
+** License. See the file COPYING in the main directory of this archive
+** for more details.
+**
+** Created 09/29/92 by Greg Harp
+**
+** 5/2/94 Roman Hodek:
+** Added bi_atari part of the machine dependent union bi_un; for now it
+** contains just a model field to distinguish between TT and Falcon.
+** 26/7/96 Roman Zippel:
+** Renamed to setup.h; added some useful macros to allow gcc some
+** optimizations if possible.
+** 5/10/96 Geert Uytterhoeven:
+** Redesign of the boot information structure; renamed to bootinfo.h again
+** 27/11/96 Geert Uytterhoeven:
+** Backwards compatibility with bootinfo interface version 1.0
+*/
+
+#ifndef _M68K_BOOTINFO_H
+#define _M68K_BOOTINFO_H
+
+
+ /*
+ * Bootinfo definitions
+ *
+ * This is an easily parsable and extendable structure containing all
+ * information to be passed from the bootstrap to the kernel.
+ *
+ * This way I hope to keep all future changes back/forewards compatible.
+ * Thus, keep your fingers crossed...
+ *
+ * This structure is copied right after the kernel bss by the bootstrap
+ * routine.
+ */
+
+#ifndef __ASSEMBLY__
+
+struct bi_record {
+ unsigned short tag; /* tag ID */
+ unsigned short size; /* size of record (in bytes) */
+ unsigned long data[0]; /* data */
+};
+
+#endif /* __ASSEMBLY__ */
+
+
+ /*
+ * Tag Definitions
+ *
+ * Machine independent tags start counting from 0x0000
+ * Machine dependent tags start counting from 0x8000
+ */
+
+#define BI_LAST 0x0000 /* last record (sentinel) */
+#define BI_MACHTYPE 0x0001 /* machine type (u_long) */
+#define BI_CPUTYPE 0x0002 /* cpu type (u_long) */
+#define BI_FPUTYPE 0x0003 /* fpu type (u_long) */
+#define BI_MMUTYPE 0x0004 /* mmu type (u_long) */
+#define BI_MEMCHUNK 0x0005 /* memory chunk address and size */
+ /* (struct mem_info) */
+#define BI_RAMDISK 0x0006 /* ramdisk address and size */
+ /* (struct mem_info) */
+#define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */
+ /* (string) */
+
+ /*
+ * Amiga-specific tags
+ */
+
+#define BI_AMIGA_MODEL 0x8000 /* model (u_long) */
+#define BI_AMIGA_AUTOCON 0x8001 /* AutoConfig device */
+ /* (struct ConfigDev) */
+#define BI_AMIGA_CHIP_SIZE 0x8002 /* size of Chip RAM (u_long) */
+#define BI_AMIGA_VBLANK 0x8003 /* VBLANK frequency (u_char) */
+#define BI_AMIGA_PSFREQ 0x8004 /* power supply frequency (u_char) */
+#define BI_AMIGA_ECLOCK 0x8005 /* EClock frequency (u_long) */
+#define BI_AMIGA_CHIPSET 0x8006 /* native chipset present (u_long) */
+#define BI_AMIGA_SERPER 0x8007 /* serial port period (u_short) */
+
+ /*
+ * Atari-specific tags
+ */
+
+#define BI_ATARI_MCH_COOKIE 0x8000 /* _MCH cookie from TOS (u_long) */
+#define BI_ATARI_MCH_TYPE 0x8001 /* special machine type (u_long) */
+ /* (values are ATARI_MACH_* defines */
+
+/* mch_cookie values (upper word) */
+#define ATARI_MCH_ST 0
+#define ATARI_MCH_STE 1
+#define ATARI_MCH_TT 2
+#define ATARI_MCH_FALCON 3
+
+/* mch_type values */
+#define ATARI_MACH_NORMAL 0 /* no special machine type */
+#define ATARI_MACH_MEDUSA 1 /* Medusa 040 */
+#define ATARI_MACH_HADES 2 /* Hades 040 or 060 */
+#define ATARI_MACH_AB40 3 /* Afterburner040 on Falcon */
+
+ /*
+ * VME-specific tags
+ */
+
+#define BI_VME_TYPE 0x8000 /* VME sub-architecture (u_long) */
+#define BI_VME_BRDINFO 0x8001 /* VME board information (struct) */
+
+/* BI_VME_TYPE codes */
+#define VME_TYPE_TP34V 0x0034 /* Tadpole TP34V */
+#define VME_TYPE_MVME147 0x0147 /* Motorola MVME147 */
+#define VME_TYPE_MVME162 0x0162 /* Motorola MVME162 */
+#define VME_TYPE_MVME166 0x0166 /* Motorola MVME166 */
+#define VME_TYPE_MVME167 0x0167 /* Motorola MVME167 */
+#define VME_TYPE_MVME172 0x0172 /* Motorola MVME172 */
+#define VME_TYPE_MVME177 0x0177 /* Motorola MVME177 */
+#define VME_TYPE_BVME4000 0x4000 /* BVM Ltd. BVME4000 */
+#define VME_TYPE_BVME6000 0x6000 /* BVM Ltd. BVME6000 */
+
+/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on
+ * Motorola VME boards. Contains board number, Bug version, board
+ * configuration options, etc. See include/asm/mvme16xhw.h for details.
+ */
+
+
+ /*
+ * Macintosh-specific tags (all u_long)
+ */
+
+#define BI_MAC_MODEL 0x8000 /* Mac Gestalt ID (model type) */
+#define BI_MAC_VADDR 0x8001 /* Mac video base address */
+#define BI_MAC_VDEPTH 0x8002 /* Mac video depth */
+#define BI_MAC_VROW 0x8003 /* Mac video rowbytes */
+#define BI_MAC_VDIM 0x8004 /* Mac video dimensions */
+#define BI_MAC_VLOGICAL 0x8005 /* Mac video logical base */
+#define BI_MAC_SCCBASE 0x8006 /* Mac SCC base address */
+#define BI_MAC_BTIME 0x8007 /* Mac boot time */
+#define BI_MAC_GMTBIAS 0x8008 /* Mac GMT timezone offset */
+#define BI_MAC_MEMSIZE 0x8009 /* Mac RAM size (sanity check) */
+#define BI_MAC_CPUID 0x800a /* Mac CPU type (sanity check) */
+#define BI_MAC_ROMBASE 0x800b /* Mac system ROM base address */
+
+ /*
+ * Macintosh hardware profile data - unused, see macintosh.h for
+ * resonable type values
+ */
+
+#define BI_MAC_VIA1BASE 0x8010 /* Mac VIA1 base address (always present) */
+#define BI_MAC_VIA2BASE 0x8011 /* Mac VIA2 base address (type varies) */
+#define BI_MAC_VIA2TYPE 0x8012 /* Mac VIA2 type (VIA, RBV, OSS) */
+#define BI_MAC_ADBTYPE 0x8013 /* Mac ADB interface type */
+#define BI_MAC_ASCBASE 0x8014 /* Mac Apple Sound Chip base address */
+#define BI_MAC_SCSI5380 0x8015 /* Mac NCR 5380 SCSI (base address, multi) */
+#define BI_MAC_SCSIDMA 0x8016 /* Mac SCSI DMA (base address) */
+#define BI_MAC_SCSI5396 0x8017 /* Mac NCR 53C96 SCSI (base address, multi) */
+#define BI_MAC_IDETYPE 0x8018 /* Mac IDE interface type */
+#define BI_MAC_IDEBASE 0x8019 /* Mac IDE interface base address */
+#define BI_MAC_NUBUS 0x801a /* Mac Nubus type (none, regular, pseudo) */
+#define BI_MAC_SLOTMASK 0x801b /* Mac Nubus slots present */
+#define BI_MAC_SCCTYPE 0x801c /* Mac SCC serial type (normal, IOP) */
+#define BI_MAC_ETHTYPE 0x801d /* Mac builtin ethernet type (Sonic, MACE */
+#define BI_MAC_ETHBASE 0x801e /* Mac builtin ethernet base address */
+#define BI_MAC_PMU 0x801f /* Mac power management / poweroff hardware */
+#define BI_MAC_IOP_SWIM 0x8020 /* Mac SWIM floppy IOP */
+#define BI_MAC_IOP_ADB 0x8021 /* Mac ADB IOP */
+
+ /*
+ * Mac: compatibility with old booter data format (temporarily)
+ * Fields unused with the new bootinfo can be deleted now; instead of
+ * adding new fields the struct might be splitted into a hardware address
+ * part and a hardware type part
+ */
+
+#ifndef __ASSEMBLY__
+
+struct mac_booter_data
+{
+ unsigned long videoaddr;
+ unsigned long videorow;
+ unsigned long videodepth;
+ unsigned long dimensions;
+ unsigned long args;
+ unsigned long boottime;
+ unsigned long gmtbias;
+ unsigned long bootver;
+ unsigned long videological;
+ unsigned long sccbase;
+ unsigned long id;
+ unsigned long memsize;
+ unsigned long serialmf;
+ unsigned long serialhsk;
+ unsigned long serialgpi;
+ unsigned long printmf;
+ unsigned long printhsk;
+ unsigned long printgpi;
+ unsigned long cpuid;
+ unsigned long rombase;
+ unsigned long adbdelay;
+ unsigned long timedbra;
+};
+
+extern struct mac_booter_data
+ mac_bi_data;
+
#endif
+
+ /*
+ * Apollo-specific tags
+ */
+
+#define BI_APOLLO_MODEL 0x8000 /* model (u_long) */
+
+ /*
+ * HP300-specific tags
+ */
+
+#define BI_HP300_MODEL 0x8000 /* model (u_long) */
+#define BI_HP300_UART_SCODE 0x8001 /* UART select code (u_long) */
+#define BI_HP300_UART_ADDR 0x8002 /* phys. addr of UART (u_long) */
+
+ /*
+ * Stuff for bootinfo interface versioning
+ *
+ * At the start of kernel code, a 'struct bootversion' is located.
+ * bootstrap checks for a matching version of the interface before booting
+ * a kernel, to avoid user confusion if kernel and bootstrap don't work
+ * together :-)
+ *
+ * If incompatible changes are made to the bootinfo interface, the major
+ * number below should be stepped (and the minor reset to 0) for the
+ * appropriate machine. If a change is backward-compatible, the minor
+ * should be stepped. "Backwards-compatible" means that booting will work,
+ * but certain features may not.
+ */
+
+#define BOOTINFOV_MAGIC 0x4249561A /* 'BIV^Z' */
+#define MK_BI_VERSION(major,minor) (((major)<<16)+(minor))
+#define BI_VERSION_MAJOR(v) (((v) >> 16) & 0xffff)
+#define BI_VERSION_MINOR(v) ((v) & 0xffff)
+
+#ifndef __ASSEMBLY__
+
+struct bootversion {
+ unsigned short branch;
+ unsigned long magic;
+ struct {
+ unsigned long machtype;
+ unsigned long version;
+ } machversions[0];
+};
+
+#endif /* __ASSEMBLY__ */
+
+#define AMIGA_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define ATARI_BOOTI_VERSION MK_BI_VERSION( 2, 1 )
+#define MAC_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define MVME147_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define MVME16x_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define Q40_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+#define HP300_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
+
+#ifdef BOOTINFO_COMPAT_1_0
+
+ /*
+ * Backwards compatibility with bootinfo interface version 1.0
+ */
+
+#define COMPAT_AMIGA_BOOTI_VERSION MK_BI_VERSION( 1, 0 )
+#define COMPAT_ATARI_BOOTI_VERSION MK_BI_VERSION( 1, 0 )
+#define COMPAT_MAC_BOOTI_VERSION MK_BI_VERSION( 1, 0 )
+
+#include <linux/zorro.h>
+
+#define COMPAT_NUM_AUTO 16
+
+struct compat_bi_Amiga {
+ int model;
+ int num_autocon;
+ struct ConfigDev autocon[COMPAT_NUM_AUTO];
+ unsigned long chip_size;
+ unsigned char vblank;
+ unsigned char psfreq;
+ unsigned long eclock;
+ unsigned long chipset;
+ unsigned long hw_present;
+};
+
+struct compat_bi_Atari {
+ unsigned long hw_present;
+ unsigned long mch_cookie;
+};
+
+#ifndef __ASSEMBLY__
+
+struct compat_bi_Macintosh
+{
+ unsigned long videoaddr;
+ unsigned long videorow;
+ unsigned long videodepth;
+ unsigned long dimensions;
+ unsigned long args;
+ unsigned long boottime;
+ unsigned long gmtbias;
+ unsigned long bootver;
+ unsigned long videological;
+ unsigned long sccbase;
+ unsigned long id;
+ unsigned long memsize;
+ unsigned long serialmf;
+ unsigned long serialhsk;
+ unsigned long serialgpi;
+ unsigned long printmf;
+ unsigned long printhsk;
+ unsigned long printgpi;
+ unsigned long cpuid;
+ unsigned long rombase;
+ unsigned long adbdelay;
+ unsigned long timedbra;
+};
+
+#endif
+
+struct compat_mem_info {
+ unsigned long addr;
+ unsigned long size;
+};
+
+#define COMPAT_NUM_MEMINFO 4
+
+#define COMPAT_CPUB_68020 0
+#define COMPAT_CPUB_68030 1
+#define COMPAT_CPUB_68040 2
+#define COMPAT_CPUB_68060 3
+#define COMPAT_FPUB_68881 5
+#define COMPAT_FPUB_68882 6
+#define COMPAT_FPUB_68040 7
+#define COMPAT_FPUB_68060 8
+
+#define COMPAT_CPU_68020 (1<<COMPAT_CPUB_68020)
+#define COMPAT_CPU_68030 (1<<COMPAT_CPUB_68030)
+#define COMPAT_CPU_68040 (1<<COMPAT_CPUB_68040)
+#define COMPAT_CPU_68060 (1<<COMPAT_CPUB_68060)
+#define COMPAT_CPU_MASK (31)
+#define COMPAT_FPU_68881 (1<<COMPAT_FPUB_68881)
+#define COMPAT_FPU_68882 (1<<COMPAT_FPUB_68882)
+#define COMPAT_FPU_68040 (1<<COMPAT_FPUB_68040)
+#define COMPAT_FPU_68060 (1<<COMPAT_FPUB_68060)
+#define COMPAT_FPU_MASK (0xfe0)
+
+#define COMPAT_CL_SIZE (256)
+
+struct compat_bootinfo {
+ unsigned long machtype;
+ unsigned long cputype;
+ struct compat_mem_info memory[COMPAT_NUM_MEMINFO];
+ int num_memory;
+ unsigned long ramdisk_size;
+ unsigned long ramdisk_addr;
+ char command_line[COMPAT_CL_SIZE];
+ union {
+ struct compat_bi_Amiga bi_ami;
+ struct compat_bi_Atari bi_ata;
+ struct compat_bi_Macintosh bi_mac;
+ } bi_un;
+};
+
+#define bi_amiga bi_un.bi_ami
+#define bi_atari bi_un.bi_ata
+#define bi_mac bi_un.bi_mac
+
+#endif /* BOOTINFO_COMPAT_1_0 */
+
+
+#endif /* _M68K_BOOTINFO_H */
diff --git a/arch/m68k/include/asm/bootinfo_mm.h b/arch/m68k/include/asm/bootinfo_mm.h
deleted file mode 100644
index fb8a06b9ab6a..000000000000
--- a/arch/m68k/include/asm/bootinfo_mm.h
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
-** asm/bootinfo.h -- Definition of the Linux/m68k boot information structure
-**
-** Copyright 1992 by Greg Harp
-**
-** This file is subject to the terms and conditions of the GNU General Public
-** License. See the file COPYING in the main directory of this archive
-** for more details.
-**
-** Created 09/29/92 by Greg Harp
-**
-** 5/2/94 Roman Hodek:
-** Added bi_atari part of the machine dependent union bi_un; for now it
-** contains just a model field to distinguish between TT and Falcon.
-** 26/7/96 Roman Zippel:
-** Renamed to setup.h; added some useful macros to allow gcc some
-** optimizations if possible.
-** 5/10/96 Geert Uytterhoeven:
-** Redesign of the boot information structure; renamed to bootinfo.h again
-** 27/11/96 Geert Uytterhoeven:
-** Backwards compatibility with bootinfo interface version 1.0
-*/
-
-#ifndef _M68K_BOOTINFO_H
-#define _M68K_BOOTINFO_H
-
-
- /*
- * Bootinfo definitions
- *
- * This is an easily parsable and extendable structure containing all
- * information to be passed from the bootstrap to the kernel.
- *
- * This way I hope to keep all future changes back/forewards compatible.
- * Thus, keep your fingers crossed...
- *
- * This structure is copied right after the kernel bss by the bootstrap
- * routine.
- */
-
-#ifndef __ASSEMBLY__
-
-struct bi_record {
- unsigned short tag; /* tag ID */
- unsigned short size; /* size of record (in bytes) */
- unsigned long data[0]; /* data */
-};
-
-#endif /* __ASSEMBLY__ */
-
-
- /*
- * Tag Definitions
- *
- * Machine independent tags start counting from 0x0000
- * Machine dependent tags start counting from 0x8000
- */
-
-#define BI_LAST 0x0000 /* last record (sentinel) */
-#define BI_MACHTYPE 0x0001 /* machine type (u_long) */
-#define BI_CPUTYPE 0x0002 /* cpu type (u_long) */
-#define BI_FPUTYPE 0x0003 /* fpu type (u_long) */
-#define BI_MMUTYPE 0x0004 /* mmu type (u_long) */
-#define BI_MEMCHUNK 0x0005 /* memory chunk address and size */
- /* (struct mem_info) */
-#define BI_RAMDISK 0x0006 /* ramdisk address and size */
- /* (struct mem_info) */
-#define BI_COMMAND_LINE 0x0007 /* kernel command line parameters */
- /* (string) */
-
- /*
- * Amiga-specific tags
- */
-
-#define BI_AMIGA_MODEL 0x8000 /* model (u_long) */
-#define BI_AMIGA_AUTOCON 0x8001 /* AutoConfig device */
- /* (struct ConfigDev) */
-#define BI_AMIGA_CHIP_SIZE 0x8002 /* size of Chip RAM (u_long) */
-#define BI_AMIGA_VBLANK 0x8003 /* VBLANK frequency (u_char) */
-#define BI_AMIGA_PSFREQ 0x8004 /* power supply frequency (u_char) */
-#define BI_AMIGA_ECLOCK 0x8005 /* EClock frequency (u_long) */
-#define BI_AMIGA_CHIPSET 0x8006 /* native chipset present (u_long) */
-#define BI_AMIGA_SERPER 0x8007 /* serial port period (u_short) */
-
- /*
- * Atari-specific tags
- */
-
-#define BI_ATARI_MCH_COOKIE 0x8000 /* _MCH cookie from TOS (u_long) */
-#define BI_ATARI_MCH_TYPE 0x8001 /* special machine type (u_long) */
- /* (values are ATARI_MACH_* defines */
-
-/* mch_cookie values (upper word) */
-#define ATARI_MCH_ST 0
-#define ATARI_MCH_STE 1
-#define ATARI_MCH_TT 2
-#define ATARI_MCH_FALCON 3
-
-/* mch_type values */
-#define ATARI_MACH_NORMAL 0 /* no special machine type */
-#define ATARI_MACH_MEDUSA 1 /* Medusa 040 */
-#define ATARI_MACH_HADES 2 /* Hades 040 or 060 */
-#define ATARI_MACH_AB40 3 /* Afterburner040 on Falcon */
-
- /*
- * VME-specific tags
- */
-
-#define BI_VME_TYPE 0x8000 /* VME sub-architecture (u_long) */
-#define BI_VME_BRDINFO 0x8001 /* VME board information (struct) */
-
-/* BI_VME_TYPE codes */
-#define VME_TYPE_TP34V 0x0034 /* Tadpole TP34V */
-#define VME_TYPE_MVME147 0x0147 /* Motorola MVME147 */
-#define VME_TYPE_MVME162 0x0162 /* Motorola MVME162 */
-#define VME_TYPE_MVME166 0x0166 /* Motorola MVME166 */
-#define VME_TYPE_MVME167 0x0167 /* Motorola MVME167 */
-#define VME_TYPE_MVME172 0x0172 /* Motorola MVME172 */
-#define VME_TYPE_MVME177 0x0177 /* Motorola MVME177 */
-#define VME_TYPE_BVME4000 0x4000 /* BVM Ltd. BVME4000 */
-#define VME_TYPE_BVME6000 0x6000 /* BVM Ltd. BVME6000 */
-
-/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on
- * Motorola VME boards. Contains board number, Bug version, board
- * configuration options, etc. See include/asm/mvme16xhw.h for details.
- */
-
-
- /*
- * Macintosh-specific tags (all u_long)
- */
-
-#define BI_MAC_MODEL 0x8000 /* Mac Gestalt ID (model type) */
-#define BI_MAC_VADDR 0x8001 /* Mac video base address */
-#define BI_MAC_VDEPTH 0x8002 /* Mac video depth */
-#define BI_MAC_VROW 0x8003 /* Mac video rowbytes */
-#define BI_MAC_VDIM 0x8004 /* Mac video dimensions */
-#define BI_MAC_VLOGICAL 0x8005 /* Mac video logical base */
-#define BI_MAC_SCCBASE 0x8006 /* Mac SCC base address */
-#define BI_MAC_BTIME 0x8007 /* Mac boot time */
-#define BI_MAC_GMTBIAS 0x8008 /* Mac GMT timezone offset */
-#define BI_MAC_MEMSIZE 0x8009 /* Mac RAM size (sanity check) */
-#define BI_MAC_CPUID 0x800a /* Mac CPU type (sanity check) */
-#define BI_MAC_ROMBASE 0x800b /* Mac system ROM base address */
-
- /*
- * Macintosh hardware profile data - unused, see macintosh.h for
- * resonable type values
- */
-
-#define BI_MAC_VIA1BASE 0x8010 /* Mac VIA1 base address (always present) */
-#define BI_MAC_VIA2BASE 0x8011 /* Mac VIA2 base address (type varies) */
-#define BI_MAC_VIA2TYPE 0x8012 /* Mac VIA2 type (VIA, RBV, OSS) */
-#define BI_MAC_ADBTYPE 0x8013 /* Mac ADB interface type */
-#define BI_MAC_ASCBASE 0x8014 /* Mac Apple Sound Chip base address */
-#define BI_MAC_SCSI5380 0x8015 /* Mac NCR 5380 SCSI (base address, multi) */
-#define BI_MAC_SCSIDMA 0x8016 /* Mac SCSI DMA (base address) */
-#define BI_MAC_SCSI5396 0x8017 /* Mac NCR 53C96 SCSI (base address, multi) */
-#define BI_MAC_IDETYPE 0x8018 /* Mac IDE interface type */
-#define BI_MAC_IDEBASE 0x8019 /* Mac IDE interface base address */
-#define BI_MAC_NUBUS 0x801a /* Mac Nubus type (none, regular, pseudo) */
-#define BI_MAC_SLOTMASK 0x801b /* Mac Nubus slots present */
-#define BI_MAC_SCCTYPE 0x801c /* Mac SCC serial type (normal, IOP) */
-#define BI_MAC_ETHTYPE 0x801d /* Mac builtin ethernet type (Sonic, MACE */
-#define BI_MAC_ETHBASE 0x801e /* Mac builtin ethernet base address */
-#define BI_MAC_PMU 0x801f /* Mac power management / poweroff hardware */
-#define BI_MAC_IOP_SWIM 0x8020 /* Mac SWIM floppy IOP */
-#define BI_MAC_IOP_ADB 0x8021 /* Mac ADB IOP */
-
- /*
- * Mac: compatibility with old booter data format (temporarily)
- * Fields unused with the new bootinfo can be deleted now; instead of
- * adding new fields the struct might be splitted into a hardware address
- * part and a hardware type part
- */
-
-#ifndef __ASSEMBLY__
-
-struct mac_booter_data
-{
- unsigned long videoaddr;
- unsigned long videorow;
- unsigned long videodepth;
- unsigned long dimensions;
- unsigned long args;
- unsigned long boottime;
- unsigned long gmtbias;
- unsigned long bootver;
- unsigned long videological;
- unsigned long sccbase;
- unsigned long id;
- unsigned long memsize;
- unsigned long serialmf;
- unsigned long serialhsk;
- unsigned long serialgpi;
- unsigned long printmf;
- unsigned long printhsk;
- unsigned long printgpi;
- unsigned long cpuid;
- unsigned long rombase;
- unsigned long adbdelay;
- unsigned long timedbra;
-};
-
-extern struct mac_booter_data
- mac_bi_data;
-
-#endif
-
- /*
- * Apollo-specific tags
- */
-
-#define BI_APOLLO_MODEL 0x8000 /* model (u_long) */
-
- /*
- * HP300-specific tags
- */
-
-#define BI_HP300_MODEL 0x8000 /* model (u_long) */
-#define BI_HP300_UART_SCODE 0x8001 /* UART select code (u_long) */
-#define BI_HP300_UART_ADDR 0x8002 /* phys. addr of UART (u_long) */
-
- /*
- * Stuff for bootinfo interface versioning
- *
- * At the start of kernel code, a 'struct bootversion' is located.
- * bootstrap checks for a matching version of the interface before booting
- * a kernel, to avoid user confusion if kernel and bootstrap don't work
- * together :-)
- *
- * If incompatible changes are made to the bootinfo interface, the major
- * number below should be stepped (and the minor reset to 0) for the
- * appropriate machine. If a change is backward-compatible, the minor
- * should be stepped. "Backwards-compatible" means that booting will work,
- * but certain features may not.
- */
-
-#define BOOTINFOV_MAGIC 0x4249561A /* 'BIV^Z' */
-#define MK_BI_VERSION(major,minor) (((major)<<16)+(minor))
-#define BI_VERSION_MAJOR(v) (((v) >> 16) & 0xffff)
-#define BI_VERSION_MINOR(v) ((v) & 0xffff)
-
-#ifndef __ASSEMBLY__
-
-struct bootversion {
- unsigned short branch;
- unsigned long magic;
- struct {
- unsigned long machtype;
- unsigned long version;
- } machversions[0];
-};
-
-#endif /* __ASSEMBLY__ */
-
-#define AMIGA_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define ATARI_BOOTI_VERSION MK_BI_VERSION( 2, 1 )
-#define MAC_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define MVME147_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define MVME16x_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define Q40_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-#define HP300_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-
-#ifdef BOOTINFO_COMPAT_1_0
-
- /*
- * Backwards compatibility with bootinfo interface version 1.0
- */
-
-#define COMPAT_AMIGA_BOOTI_VERSION MK_BI_VERSION( 1, 0 )
-#define COMPAT_ATARI_BOOTI_VERSION MK_BI_VERSION( 1, 0 )
-#define COMPAT_MAC_BOOTI_VERSION MK_BI_VERSION( 1, 0 )
-
-#include <linux/zorro.h>
-
-#define COMPAT_NUM_AUTO 16
-
-struct compat_bi_Amiga {
- int model;
- int num_autocon;
- struct ConfigDev autocon[COMPAT_NUM_AUTO];
- unsigned long chip_size;
- unsigned char vblank;
- unsigned char psfreq;
- unsigned long eclock;
- unsigned long chipset;
- unsigned long hw_present;
-};
-
-struct compat_bi_Atari {
- unsigned long hw_present;
- unsigned long mch_cookie;
-};
-
-#ifndef __ASSEMBLY__
-
-struct compat_bi_Macintosh
-{
- unsigned long videoaddr;
- unsigned long videorow;
- unsigned long videodepth;
- unsigned long dimensions;
- unsigned long args;
- unsigned long boottime;
- unsigned long gmtbias;
- unsigned long bootver;
- unsigned long videological;
- unsigned long sccbase;
- unsigned long id;
- unsigned long memsize;
- unsigned long serialmf;
- unsigned long serialhsk;
- unsigned long serialgpi;
- unsigned long printmf;
- unsigned long printhsk;
- unsigned long printgpi;
- unsigned long cpuid;
- unsigned long rombase;
- unsigned long adbdelay;
- unsigned long timedbra;
-};
-
-#endif
-
-struct compat_mem_info {
- unsigned long addr;
- unsigned long size;
-};
-
-#define COMPAT_NUM_MEMINFO 4
-
-#define COMPAT_CPUB_68020 0
-#define COMPAT_CPUB_68030 1
-#define COMPAT_CPUB_68040 2
-#define COMPAT_CPUB_68060 3
-#define COMPAT_FPUB_68881 5
-#define COMPAT_FPUB_68882 6
-#define COMPAT_FPUB_68040 7
-#define COMPAT_FPUB_68060 8
-
-#define COMPAT_CPU_68020 (1<<COMPAT_CPUB_68020)
-#define COMPAT_CPU_68030 (1<<COMPAT_CPUB_68030)
-#define COMPAT_CPU_68040 (1<<COMPAT_CPUB_68040)
-#define COMPAT_CPU_68060 (1<<COMPAT_CPUB_68060)
-#define COMPAT_CPU_MASK (31)
-#define COMPAT_FPU_68881 (1<<COMPAT_FPUB_68881)
-#define COMPAT_FPU_68882 (1<<COMPAT_FPUB_68882)
-#define COMPAT_FPU_68040 (1<<COMPAT_FPUB_68040)
-#define COMPAT_FPU_68060 (1<<COMPAT_FPUB_68060)
-#define COMPAT_FPU_MASK (0xfe0)
-
-#define COMPAT_CL_SIZE (256)
-
-struct compat_bootinfo {
- unsigned long machtype;
- unsigned long cputype;
- struct compat_mem_info memory[COMPAT_NUM_MEMINFO];
- int num_memory;
- unsigned long ramdisk_size;
- unsigned long ramdisk_addr;
- char command_line[COMPAT_CL_SIZE];
- union {
- struct compat_bi_Amiga bi_ami;
- struct compat_bi_Atari bi_ata;
- struct compat_bi_Macintosh bi_mac;
- } bi_un;
-};
-
-#define bi_amiga bi_un.bi_ami
-#define bi_atari bi_un.bi_ata
-#define bi_mac bi_un.bi_mac
-
-#endif /* BOOTINFO_COMPAT_1_0 */
-
-
-#endif /* _M68K_BOOTINFO_H */
diff --git a/arch/m68k/include/asm/bootinfo_no.h b/arch/m68k/include/asm/bootinfo_no.h
deleted file mode 100644
index c12e526f5189..000000000000
--- a/arch/m68k/include/asm/bootinfo_no.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-/* Nothing for m68knommu */
diff --git a/arch/m68k/include/asm/bug.h b/arch/m68k/include/asm/bug.h
index 997e0944ebc1..ef9a2e47352f 100644
--- a/arch/m68k/include/asm/bug.h
+++ b/arch/m68k/include/asm/bug.h
@@ -1,5 +1,30 @@
-#ifdef __uClinux__
-#include "bug_no.h"
+#ifndef _M68K_BUG_H
+#define _M68K_BUG_H
+
+#ifdef CONFIG_MMU
+#ifdef CONFIG_BUG
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+#ifndef CONFIG_SUN3
+#define BUG() do { \
+ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+ __builtin_trap(); \
+} while (0)
#else
-#include "bug_mm.h"
+#define BUG() do { \
+ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+ panic("BUG!"); \
+} while (0)
+#endif
+#else
+#define BUG() do { \
+ __builtin_trap(); \
+} while (0)
+#endif
+
+#define HAVE_ARCH_BUG
+#endif
+#endif /* CONFIG_MMU */
+
+#include <asm-generic/bug.h>
+
#endif
diff --git a/arch/m68k/include/asm/bug_mm.h b/arch/m68k/include/asm/bug_mm.h
deleted file mode 100644
index e5b528deb8a8..000000000000
--- a/arch/m68k/include/asm/bug_mm.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _M68K_BUG_H
-#define _M68K_BUG_H
-
-
-#ifdef CONFIG_BUG
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-#ifndef CONFIG_SUN3
-#define BUG() do { \
- printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
- __builtin_trap(); \
-} while (0)
-#else
-#define BUG() do { \
- printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
- panic("BUG!"); \
-} while (0)
-#endif
-#else
-#define BUG() do { \
- __builtin_trap(); \
-} while (0)
-#endif
-
-#define HAVE_ARCH_BUG
-#endif
-
-#include <asm-generic/bug.h>
-
-#endif
diff --git a/arch/m68k/include/asm/bug_no.h b/arch/m68k/include/asm/bug_no.h
deleted file mode 100644
index 70e7dc0af21a..000000000000
--- a/arch/m68k/include/asm/bug_no.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef _M68KNOMMU_BUG_H
-#define _M68KNOMMU_BUG_H
-#include <asm-generic/bug.h>
-#endif
diff --git a/arch/m68k/include/asm/bugs.h b/arch/m68k/include/asm/bugs.h
index 01f047d784ec..d06207b9ba5a 100644
--- a/arch/m68k/include/asm/bugs.h
+++ b/arch/m68k/include/asm/bugs.h
@@ -1,5 +1,20 @@
-#ifdef __uClinux__
-#include "bugs_no.h"
+/*
+ * include/asm-m68k/bugs.h
+ *
+ * Copyright (C) 1994 Linus Torvalds
+ */
+
+/*
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Needs:
+ * void check_bugs(void);
+ */
+
+#ifdef CONFIG_MMU
+extern void check_bugs(void); /* in arch/m68k/kernel/setup.c */
#else
-#include "bugs_mm.h"
+static void check_bugs(void)
+{
+}
#endif
diff --git a/arch/m68k/include/asm/bugs_mm.h b/arch/m68k/include/asm/bugs_mm.h
deleted file mode 100644
index d01935592410..000000000000
--- a/arch/m68k/include/asm/bugs_mm.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * include/asm-m68k/bugs.h
- *
- * Copyright (C) 1994 Linus Torvalds
- */
-
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- * void check_bugs(void);
- */
-
-extern void check_bugs(void); /* in arch/m68k/kernel/setup.c */
diff --git a/arch/m68k/include/asm/bugs_no.h b/arch/m68k/include/asm/bugs_no.h
deleted file mode 100644
index 5f382dac3a60..000000000000
--- a/arch/m68k/include/asm/bugs_no.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * include/asm-m68k/bugs.h
- *
- * Copyright (C) 1994 Linus Torvalds
- */
-
-/*
- * This is included by init/main.c to check for architecture-dependent bugs.
- *
- * Needs:
- * void check_bugs(void);
- */
-
-static void check_bugs(void)
-{
-}
diff --git a/arch/m68k/include/asm/cache.h b/arch/m68k/include/asm/cache.h
index 599c29bc8f40..fed3fd30de7e 100644
--- a/arch/m68k/include/asm/cache.h
+++ b/arch/m68k/include/asm/cache.h
@@ -1,5 +1,11 @@
-#ifdef __uClinux__
-#include "cache_no.h"
-#else
-#include "cache_mm.h"
+/*
+ * include/asm-m68k/cache.h
+ */
+#ifndef __ARCH_M68K_CACHE_H
+#define __ARCH_M68K_CACHE_H
+
+/* bytes per L1 cache line */
+#define L1_CACHE_SHIFT 4
+#define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT)
+
#endif
diff --git a/arch/m68k/include/asm/cache_mm.h b/arch/m68k/include/asm/cache_mm.h
deleted file mode 100644
index fed3fd30de7e..000000000000
--- a/arch/m68k/include/asm/cache_mm.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * include/asm-m68k/cache.h
- */
-#ifndef __ARCH_M68K_CACHE_H
-#define __ARCH_M68K_CACHE_H
-
-/* bytes per L1 cache line */
-#define L1_CACHE_SHIFT 4
-#define L1_CACHE_BYTES (1<< L1_CACHE_SHIFT)
-
-#endif
diff --git a/arch/m68k/include/asm/cache_no.h b/arch/m68k/include/asm/cache_no.h
deleted file mode 100644
index 24e9eace5f8c..000000000000
--- a/arch/m68k/include/asm/cache_no.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __ARCH_M68KNOMMU_CACHE_H
-#define __ARCH_M68KNOMMU_CACHE_H
-
-/* bytes per L1 cache line */
-#define L1_CACHE_BYTES 16 /* this need to be at least 1 */
-
-/* m68k-elf-gcc 2.95.2 doesn't like these */
-
-#define __cacheline_aligned
-#define ____cacheline_aligned
-
-#endif
diff --git a/arch/m68k/include/asm/current.h b/arch/m68k/include/asm/current.h
index 51b056dfaedd..91fcc5358cfe 100644
--- a/arch/m68k/include/asm/current.h
+++ b/arch/m68k/include/asm/current.h
@@ -1,5 +1,28 @@
-#ifdef __uClinux__
-#include "current_no.h"
+#ifndef _M68K_CURRENT_H
+#define _M68K_CURRENT_H
+
+#ifdef CONFIG_MMU
+
+register struct task_struct *current __asm__("%a2");
+
#else
-#include "current_mm.h"
-#endif
+
+/*
+ * Rather than dedicate a register (as the m68k source does), we
+ * just keep a global, we should probably just change it all to be
+ * current and lose _current_task.
+ */
+#include <linux/thread_info.h>
+
+struct task_struct;
+
+static inline struct task_struct *get_current(void)
+{
+ return(current_thread_info()->task);
+}
+
+#define current get_current()
+
+#endif /* CONFNIG_MMU */
+
+#endif /* !(_M68K_CURRENT_H) */
diff --git a/arch/m68k/include/asm/current_mm.h b/arch/m68k/include/asm/current_mm.h
deleted file mode 100644
index 8de8f8ceda61..000000000000
--- a/arch/m68k/include/asm/current_mm.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68K_CURRENT_H
-#define _M68K_CURRENT_H
-
-register struct task_struct *current __asm__("%a2");
-
-#endif /* !(_M68K_CURRENT_H) */
diff --git a/arch/m68k/include/asm/current_no.h b/arch/m68k/include/asm/current_no.h
deleted file mode 100644
index 53ee0f9f7cef..000000000000
--- a/arch/m68k/include/asm/current_no.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _M68KNOMMU_CURRENT_H
-#define _M68KNOMMU_CURRENT_H
-/*
- * current.h
- * (C) Copyright 2000, Lineo, David McCullough <davidm@uclinux.org>
- * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
- *
- * rather than dedicate a register (as the m68k source does), we
- * just keep a global, we should probably just change it all to be
- * current and lose _current_task.
- */
-
-#include <linux/thread_info.h>
-
-struct task_struct;
-
-static inline struct task_struct *get_current(void)
-{
- return(current_thread_info()->task);
-}
-
-#define current get_current()
-
-#endif /* _M68KNOMMU_CURRENT_H */
diff --git a/arch/m68k/include/asm/div64.h b/arch/m68k/include/asm/div64.h
index d211d9f54276..edb66148a71d 100644
--- a/arch/m68k/include/asm/div64.h
+++ b/arch/m68k/include/asm/div64.h
@@ -1,5 +1,34 @@
-#ifdef __uClinux__
-#include "div64_no.h"
+#ifndef _M68K_DIV64_H
+#define _M68K_DIV64_H
+
+#ifdef CONFIG_MMU
+
+#include <linux/types.h>
+
+/* n = n / base; return rem; */
+
+#define do_div(n, base) ({ \
+ union { \
+ unsigned long n32[2]; \
+ unsigned long long n64; \
+ } __n; \
+ unsigned long __rem, __upper; \
+ \
+ __n.n64 = (n); \
+ if ((__upper = __n.n32[0])) { \
+ asm ("divul.l %2,%1:%0" \
+ : "=d" (__n.n32[0]), "=d" (__upper) \
+ : "d" (base), "0" (__n.n32[0])); \
+ } \
+ asm ("divu.l %2,%1:%0" \
+ : "=d" (__n.n32[1]), "=d" (__rem) \
+ : "d" (base), "1" (__upper), "0" (__n.n32[1])); \
+ (n) = __n.n64; \
+ __rem; \
+})
+
#else
-#include "div64_mm.h"
-#endif
+#include <asm-generic/div64.h>
+#endif /* CONFIG_MMU */
+
+#endif /* _M68K_DIV64_H */
diff --git a/arch/m68k/include/asm/div64_mm.h b/arch/m68k/include/asm/div64_mm.h
deleted file mode 100644
index 8243c931b5c0..000000000000
--- a/arch/m68k/include/asm/div64_mm.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _M68K_DIV64_H
-#define _M68K_DIV64_H
-
-#include <linux/types.h>
-
-/* n = n / base; return rem; */
-
-#define do_div(n, base) ({ \
- union { \
- unsigned long n32[2]; \
- unsigned long long n64; \
- } __n; \
- unsigned long __rem, __upper; \
- \
- __n.n64 = (n); \
- if ((__upper = __n.n32[0])) { \
- asm ("divul.l %2,%1:%0" \
- : "=d" (__n.n32[0]), "=d" (__upper) \
- : "d" (base), "0" (__n.n32[0])); \
- } \
- asm ("divu.l %2,%1:%0" \
- : "=d" (__n.n32[1]), "=d" (__rem) \
- : "d" (base), "1" (__upper), "0" (__n.n32[1])); \
- (n) = __n.n64; \
- __rem; \
-})
-
-#endif /* _M68K_DIV64_H */
diff --git a/arch/m68k/include/asm/div64_no.h b/arch/m68k/include/asm/div64_no.h
deleted file mode 100644
index 6cd978cefb28..000000000000
--- a/arch/m68k/include/asm/div64_no.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/div64.h>
diff --git a/arch/m68k/include/asm/dma-mapping.h b/arch/m68k/include/asm/dma-mapping.h
index f4a4c7638f89..26f505488c11 100644
--- a/arch/m68k/include/asm/dma-mapping.h
+++ b/arch/m68k/include/asm/dma-mapping.h
@@ -1,5 +1,112 @@
-#ifdef __uClinux__
-#include "dma-mapping_no.h"
+#ifndef _M68K_DMA_MAPPING_H
+#define _M68K_DMA_MAPPING_H
+
+#include <asm/cache.h>
+
+struct scatterlist;
+
+#ifndef CONFIG_MMU_SUN3
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+ return 1;
+}
+
+static inline int dma_set_mask(struct device *dev, u64 mask)
+{
+ return 0;
+}
+
+static inline int dma_get_cache_alignment(void)
+{
+ return 1 << L1_CACHE_SHIFT;
+}
+
+static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+extern void *dma_alloc_coherent(struct device *, size_t,
+ dma_addr_t *, gfp_t);
+extern void dma_free_coherent(struct device *, size_t,
+ void *, dma_addr_t);
+
+static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t flag)
+{
+ return dma_alloc_coherent(dev, size, handle, flag);
+}
+static inline void dma_free_noncoherent(struct device *dev, size_t size,
+ void *addr, dma_addr_t handle)
+{
+ dma_free_coherent(dev, size, addr, handle);
+}
+static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+ enum dma_data_direction dir)
+{
+ /* we use coherent allocation, so not much to do here. */
+}
+
+extern dma_addr_t dma_map_single(struct device *, void *, size_t,
+ enum dma_data_direction);
+static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
+ size_t size, enum dma_data_direction dir)
+{
+}
+
+extern dma_addr_t dma_map_page(struct device *, struct page *,
+ unsigned long, size_t size,
+ enum dma_data_direction);
+static inline void dma_unmap_page(struct device *dev, dma_addr_t address,
+ size_t size, enum dma_data_direction dir)
+{
+}
+
+extern int dma_map_sg(struct device *, struct scatterlist *, int,
+ enum dma_data_direction);
+static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nhwentries, enum dma_data_direction dir)
+{
+}
+
+extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t,
+ enum dma_data_direction);
+extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
+ enum dma_data_direction);
+
+static inline void dma_sync_single_range_for_device(struct device *dev,
+ dma_addr_t dma_handle, unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ /* just sync everything for now */
+ dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
+}
+
+static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+}
+
+static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+}
+
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+ dma_addr_t dma_handle, unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ /* just sync everything for now */
+ dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
+}
+
+static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
+{
+ return 0;
+}
+
#else
-#include "dma-mapping_mm.h"
+#include <asm-generic/dma-mapping-broken.h>
#endif
+
+#endif /* _M68K_DMA_MAPPING_H */
diff --git a/arch/m68k/include/asm/dma-mapping_mm.h b/arch/m68k/include/asm/dma-mapping_mm.h
deleted file mode 100644
index 26f505488c11..000000000000
--- a/arch/m68k/include/asm/dma-mapping_mm.h
+++ /dev/null
@@ -1,112 +0,0 @@
-#ifndef _M68K_DMA_MAPPING_H
-#define _M68K_DMA_MAPPING_H
-
-#include <asm/cache.h>
-
-struct scatterlist;
-
-#ifndef CONFIG_MMU_SUN3
-static inline int dma_supported(struct device *dev, u64 mask)
-{
- return 1;
-}
-
-static inline int dma_set_mask(struct device *dev, u64 mask)
-{
- return 0;
-}
-
-static inline int dma_get_cache_alignment(void)
-{
- return 1 << L1_CACHE_SHIFT;
-}
-
-static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr)
-{
- return 0;
-}
-
-extern void *dma_alloc_coherent(struct device *, size_t,
- dma_addr_t *, gfp_t);
-extern void dma_free_coherent(struct device *, size_t,
- void *, dma_addr_t);
-
-static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
- dma_addr_t *handle, gfp_t flag)
-{
- return dma_alloc_coherent(dev, size, handle, flag);
-}
-static inline void dma_free_noncoherent(struct device *dev, size_t size,
- void *addr, dma_addr_t handle)
-{
- dma_free_coherent(dev, size, addr, handle);
-}
-static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
- enum dma_data_direction dir)
-{
- /* we use coherent allocation, so not much to do here. */
-}
-
-extern dma_addr_t dma_map_single(struct device *, void *, size_t,
- enum dma_data_direction);
-static inline void dma_unmap_single(struct device *dev, dma_addr_t addr,
- size_t size, enum dma_data_direction dir)
-{
-}
-
-extern dma_addr_t dma_map_page(struct device *, struct page *,
- unsigned long, size_t size,
- enum dma_data_direction);
-static inline void dma_unmap_page(struct device *dev, dma_addr_t address,
- size_t size, enum dma_data_direction dir)
-{
-}
-
-extern int dma_map_sg(struct device *, struct scatterlist *, int,
- enum dma_data_direction);
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nhwentries, enum dma_data_direction dir)
-{
-}
-
-extern void dma_sync_single_for_device(struct device *, dma_addr_t, size_t,
- enum dma_data_direction);
-extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
- enum dma_data_direction);
-
-static inline void dma_sync_single_range_for_device(struct device *dev,
- dma_addr_t dma_handle, unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- /* just sync everything for now */
- dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
-}
-
-static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
-}
-
-static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction dir)
-{
-}
-
-static inline void dma_sync_single_range_for_cpu(struct device *dev,
- dma_addr_t dma_handle, unsigned long offset, size_t size,
- enum dma_data_direction direction)
-{
- /* just sync everything for now */
- dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
-}
-
-static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
-{
- return 0;
-}
-
-#else
-#include <asm-generic/dma-mapping-broken.h>
-#endif
-
-#endif /* _M68K_DMA_MAPPING_H */
diff --git a/arch/m68k/include/asm/dma-mapping_no.h b/arch/m68k/include/asm/dma-mapping_no.h
deleted file mode 100644
index 1748f2bca940..000000000000
--- a/arch/m68k/include/asm/dma-mapping_no.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68KNOMMU_DMA_MAPPING_H
-#define _M68KNOMMU_DMA_MAPPING_H
-
-#include <asm-generic/dma-mapping-broken.h>
-
-#endif /* _M68KNOMMU_DMA_MAPPING_H */
diff --git a/arch/m68k/include/asm/elf.h b/arch/m68k/include/asm/elf.h
index 04ce488bc63f..0b0f49eb876b 100644
--- a/arch/m68k/include/asm/elf.h
+++ b/arch/m68k/include/asm/elf.h
@@ -1,5 +1,119 @@
-#ifdef __uClinux__
-#include "elf_no.h"
+#ifndef __ASMm68k_ELF_H
+#define __ASMm68k_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+/*
+ * 68k ELF relocation types
+ */
+#define R_68K_NONE 0
+#define R_68K_32 1
+#define R_68K_16 2
+#define R_68K_8 3
+#define R_68K_PC32 4
+#define R_68K_PC16 5
+#define R_68K_PC8 6
+#define R_68K_GOT32 7
+#define R_68K_GOT16 8
+#define R_68K_GOT8 9
+#define R_68K_GOT32O 10
+#define R_68K_GOT16O 11
+#define R_68K_GOT8O 12
+#define R_68K_PLT32 13
+#define R_68K_PLT16 14
+#define R_68K_PLT8 15
+#define R_68K_PLT32O 16
+#define R_68K_PLT16O 17
+#define R_68K_PLT8O 18
+#define R_68K_COPY 19
+#define R_68K_GLOB_DAT 20
+#define R_68K_JMP_SLOT 21
+#define R_68K_RELATIVE 22
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_m68kfp_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_68K)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2MSB
+#define ELF_ARCH EM_68K
+
+/* For SVR4/m68k the function pointer to be registered with `atexit' is
+ passed in %a1. Although my copy of the ABI has no such statement, it
+ is actually used on ASV. */
+#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0
+
+#define USE_ELF_CORE_DUMP
+#ifndef CONFIG_SUN3
+#define ELF_EXEC_PAGESIZE 4096
#else
-#include "elf_mm.h"
+#define ELF_EXEC_PAGESIZE 8192
+#endif
+
+/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
+ use of this is to invoke "./ld.so someprog" to test out a new version of
+ the loader. We need to make sure that it is out of the way of the program
+ that it will "exec", and that there is sufficient room for the brk. */
+
+#ifndef CONFIG_SUN3
+#define ELF_ET_DYN_BASE 0xD0000000UL
+#else
+#define ELF_ET_DYN_BASE 0x0D800000UL
+#endif
+
+#define ELF_CORE_COPY_REGS(pr_reg, regs) \
+ /* Bleech. */ \
+ pr_reg[0] = regs->d1; \
+ pr_reg[1] = regs->d2; \
+ pr_reg[2] = regs->d3; \
+ pr_reg[3] = regs->d4; \
+ pr_reg[4] = regs->d5; \
+ pr_reg[7] = regs->a0; \
+ pr_reg[8] = regs->a1; \
+ pr_reg[9] = regs->a2; \
+ pr_reg[14] = regs->d0; \
+ pr_reg[15] = rdusp(); \
+ pr_reg[16] = regs->orig_d0; \
+ pr_reg[17] = regs->sr; \
+ pr_reg[18] = regs->pc; \
+ pr_reg[19] = (regs->format << 12) | regs->vector; \
+ { \
+ struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \
+ pr_reg[5] = sw->d6; \
+ pr_reg[6] = sw->d7; \
+ pr_reg[10] = sw->a3; \
+ pr_reg[11] = sw->a4; \
+ pr_reg[12] = sw->a5; \
+ pr_reg[13] = sw->a6; \
+ }
+
+/* This yields a mask that user programs can use to figure out what
+ instruction set this cpu supports. */
+
+#define ELF_HWCAP (0)
+
+/* This yields a string that ld.so will use to load implementation
+ specific libraries for optimization. This is more specific in
+ intent than poking at uname or /proc/cpuinfo. */
+
+#define ELF_PLATFORM (NULL)
+
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+
#endif
diff --git a/arch/m68k/include/asm/elf_mm.h b/arch/m68k/include/asm/elf_mm.h
deleted file mode 100644
index 0b0f49eb876b..000000000000
--- a/arch/m68k/include/asm/elf_mm.h
+++ /dev/null
@@ -1,119 +0,0 @@
-#ifndef __ASMm68k_ELF_H
-#define __ASMm68k_ELF_H
-
-/*
- * ELF register definitions..
- */
-
-#include <asm/ptrace.h>
-#include <asm/user.h>
-
-/*
- * 68k ELF relocation types
- */
-#define R_68K_NONE 0
-#define R_68K_32 1
-#define R_68K_16 2
-#define R_68K_8 3
-#define R_68K_PC32 4
-#define R_68K_PC16 5
-#define R_68K_PC8 6
-#define R_68K_GOT32 7
-#define R_68K_GOT16 8
-#define R_68K_GOT8 9
-#define R_68K_GOT32O 10
-#define R_68K_GOT16O 11
-#define R_68K_GOT8O 12
-#define R_68K_PLT32 13
-#define R_68K_PLT16 14
-#define R_68K_PLT8 15
-#define R_68K_PLT32O 16
-#define R_68K_PLT16O 17
-#define R_68K_PLT8O 18
-#define R_68K_COPY 19
-#define R_68K_GLOB_DAT 20
-#define R_68K_JMP_SLOT 21
-#define R_68K_RELATIVE 22
-
-typedef unsigned long elf_greg_t;
-
-#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct user_m68kfp_struct elf_fpregset_t;
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ((x)->e_machine == EM_68K)
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS ELFCLASS32
-#define ELF_DATA ELFDATA2MSB
-#define ELF_ARCH EM_68K
-
-/* For SVR4/m68k the function pointer to be registered with `atexit' is
- passed in %a1. Although my copy of the ABI has no such statement, it
- is actually used on ASV. */
-#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0
-
-#define USE_ELF_CORE_DUMP
-#ifndef CONFIG_SUN3
-#define ELF_EXEC_PAGESIZE 4096
-#else
-#define ELF_EXEC_PAGESIZE 8192
-#endif
-
-/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
- use of this is to invoke "./ld.so someprog" to test out a new version of
- the loader. We need to make sure that it is out of the way of the program
- that it will "exec", and that there is sufficient room for the brk. */
-
-#ifndef CONFIG_SUN3
-#define ELF_ET_DYN_BASE 0xD0000000UL
-#else
-#define ELF_ET_DYN_BASE 0x0D800000UL
-#endif
-
-#define ELF_CORE_COPY_REGS(pr_reg, regs) \
- /* Bleech. */ \
- pr_reg[0] = regs->d1; \
- pr_reg[1] = regs->d2; \
- pr_reg[2] = regs->d3; \
- pr_reg[3] = regs->d4; \
- pr_reg[4] = regs->d5; \
- pr_reg[7] = regs->a0; \
- pr_reg[8] = regs->a1; \
- pr_reg[9] = regs->a2; \
- pr_reg[14] = regs->d0; \
- pr_reg[15] = rdusp(); \
- pr_reg[16] = regs->orig_d0; \
- pr_reg[17] = regs->sr; \
- pr_reg[18] = regs->pc; \
- pr_reg[19] = (regs->format << 12) | regs->vector; \
- { \
- struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \
- pr_reg[5] = sw->d6; \
- pr_reg[6] = sw->d7; \
- pr_reg[10] = sw->a3; \
- pr_reg[11] = sw->a4; \
- pr_reg[12] = sw->a5; \
- pr_reg[13] = sw->a6; \
- }
-
-/* This yields a mask that user programs can use to figure out what
- instruction set this cpu supports. */
-
-#define ELF_HWCAP (0)
-
-/* This yields a string that ld.so will use to load implementation
- specific libraries for optimization. This is more specific in
- intent than poking at uname or /proc/cpuinfo. */
-
-#define ELF_PLATFORM (NULL)
-
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
-
-#endif
diff --git a/arch/m68k/include/asm/elf_no.h b/arch/m68k/include/asm/elf_no.h
deleted file mode 100644
index b8046837f384..000000000000
--- a/arch/m68k/include/asm/elf_no.h
+++ /dev/null
@@ -1,110 +0,0 @@
-#ifndef __ASMm68k_ELF_H
-#define __ASMm68k_ELF_H
-
-/*
- * ELF register definitions..
- */
-
-#include <asm/ptrace.h>
-#include <asm/user.h>
-
-/*
- * 68k ELF relocation types
- */
-#define R_68K_NONE 0
-#define R_68K_32 1
-#define R_68K_16 2
-#define R_68K_8 3
-#define R_68K_PC32 4
-#define R_68K_PC16 5
-#define R_68K_PC8 6
-#define R_68K_GOT32 7
-#define R_68K_GOT16 8
-#define R_68K_GOT8 9
-#define R_68K_GOT32O 10
-#define R_68K_GOT16O 11
-#define R_68K_GOT8O 12
-#define R_68K_PLT32 13
-#define R_68K_PLT16 14
-#define R_68K_PLT8 15
-#define R_68K_PLT32O 16
-#define R_68K_PLT16O 17
-#define R_68K_PLT8O 18
-#define R_68K_COPY 19
-#define R_68K_GLOB_DAT 20
-#define R_68K_JMP_SLOT 21
-#define R_68K_RELATIVE 22
-
-typedef unsigned long elf_greg_t;
-
-#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct user_m68kfp_struct elf_fpregset_t;
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ((x)->e_machine == EM_68K)
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS ELFCLASS32
-#define ELF_DATA ELFDATA2MSB
-#define ELF_ARCH EM_68K
-
-/* For SVR4/m68k the function pointer to be registered with `atexit' is
- passed in %a1. Although my copy of the ABI has no such statement, it
- is actually used on ASV. */
-#define ELF_PLAT_INIT(_r, load_addr) _r->a1 = 0
-
-#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE 4096
-
-/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
- use of this is to invoke "./ld.so someprog" to test out a new version of
- the loader. We need to make sure that it is out of the way of the program
- that it will "exec", and that there is sufficient room for the brk. */
-
-#define ELF_ET_DYN_BASE 0xD0000000UL
-
-#define ELF_CORE_COPY_REGS(pr_reg, regs) \
- /* Bleech. */ \
- pr_reg[0] = regs->d1; \
- pr_reg[1] = regs->d2; \
- pr_reg[2] = regs->d3; \
- pr_reg[3] = regs->d4; \
- pr_reg[4] = regs->d5; \
- pr_reg[7] = regs->a0; \
- pr_reg[8] = regs->a1; \
- pr_reg[14] = regs->d0; \
- pr_reg[15] = rdusp(); \
- pr_reg[16] = 0 /* regs->orig_d0 */; \
- pr_reg[17] = regs->sr; \
- pr_reg[18] = regs->pc; \
- /* pr_reg[19] = (regs->format << 12) | regs->vector; */ \
- { \
- struct switch_stack *sw = ((struct switch_stack *)regs) - 1; \
- pr_reg[5] = sw->d6; \
- pr_reg[6] = sw->d7; \
- pr_reg[10] = sw->a3; \
- pr_reg[11] = sw->a4; \
- pr_reg[12] = sw->a5; \
- pr_reg[13] = sw->a6; \
- }
-
-/* This yields a mask that user programs can use to figure out what
- instruction set this cpu supports. */
-
-#define ELF_HWCAP (0)
-
-/* This yields a string that ld.so will use to load implementation
- specific libraries for optimization. This is more specific in
- intent than poking at uname or /proc/cpuinfo. */
-
-#define ELF_PLATFORM (NULL)
-
-#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
-
-#endif
diff --git a/arch/m68k/include/asm/fb.h b/arch/m68k/include/asm/fb.h
index 97bcaefd2064..be4e4c6797e8 100644
--- a/arch/m68k/include/asm/fb.h
+++ b/arch/m68k/include/asm/fb.h
@@ -1,5 +1,38 @@
-#ifdef __uClinux__
-#include "fb_no.h"
+#ifndef _ASM_FB_H_
+#define _ASM_FB_H_
+
+#include <linux/fb.h>
+#include <linux/fs.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_MMU
+#ifdef CONFIG_SUN3
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+ unsigned long off)
+{
+ pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE;
+}
#else
-#include "fb_mm.h"
-#endif
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+ unsigned long off)
+{
+ if (CPU_IS_020_OR_030)
+ pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
+ if (CPU_IS_040_OR_060) {
+ pgprot_val(vma->vm_page_prot) &= _CACHEMASK040;
+ /* Use no-cache mode, serialized */
+ pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S;
+ }
+}
+#endif /* CONFIG_SUN3 */
+#else
+#define fb_pgprotect(...) do {} while (0)
+#endif /* CONFIG_MMU */
+
+static inline int fb_is_primary_device(struct fb_info *info)
+{
+ return 0;
+}
+
+#endif /* _ASM_FB_H_ */
diff --git a/arch/m68k/include/asm/fb_mm.h b/arch/m68k/include/asm/fb_mm.h
deleted file mode 100644
index 380b97ae8157..000000000000
--- a/arch/m68k/include/asm/fb_mm.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-
-#include <linux/fb.h>
-#include <linux/fs.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-
-#ifdef CONFIG_SUN3
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
-{
- pgprot_val(vma->vm_page_prot) |= SUN3_PAGE_NOCACHE;
-}
-#else
-static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
- unsigned long off)
-{
- if (CPU_IS_020_OR_030)
- pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
- if (CPU_IS_040_OR_060) {
- pgprot_val(vma->vm_page_prot) &= _CACHEMASK040;
- /* Use no-cache mode, serialized */
- pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE_S;
- }
-}
-#endif /* CONFIG_SUN3 */
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
- return 0;
-}
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/m68k/include/asm/fb_no.h b/arch/m68k/include/asm/fb_no.h
deleted file mode 100644
index c7df38030992..000000000000
--- a/arch/m68k/include/asm/fb_no.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _ASM_FB_H_
-#define _ASM_FB_H_
-#include <linux/fb.h>
-
-#define fb_pgprotect(...) do {} while (0)
-
-static inline int fb_is_primary_device(struct fb_info *info)
-{
- return 0;
-}
-
-#endif /* _ASM_FB_H_ */
diff --git a/arch/m68k/include/asm/fpu.h b/arch/m68k/include/asm/fpu.h
index e19bc5ed9c37..ffb6b8cfc6d5 100644
--- a/arch/m68k/include/asm/fpu.h
+++ b/arch/m68k/include/asm/fpu.h
@@ -1,5 +1,21 @@
-#ifdef __uClinux__
-#include "fpu_no.h"
+#ifndef __M68K_FPU_H
+#define __M68K_FPU_H
+
+
+/*
+ * MAX floating point unit state size (FSAVE/FRESTORE)
+ */
+
+#if defined(CONFIG_M68020) || defined(CONFIG_M68030)
+#define FPSTATESIZE (216)
+#elif defined(CONFIG_M68040)
+#define FPSTATESIZE (96)
+#elif defined(CONFIG_M68KFPU_EMU)
+#define FPSTATESIZE (28)
+#elif defined(CONFIG_M68060)
+#define FPSTATESIZE (12)
#else
-#include "fpu_mm.h"
+#define FPSTATESIZE (0)
#endif
+
+#endif /* __M68K_FPU_H */
diff --git a/arch/m68k/include/asm/fpu_mm.h b/arch/m68k/include/asm/fpu_mm.h
deleted file mode 100644
index ffb6b8cfc6d5..000000000000
--- a/arch/m68k/include/asm/fpu_mm.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __M68K_FPU_H
-#define __M68K_FPU_H
-
-
-/*
- * MAX floating point unit state size (FSAVE/FRESTORE)
- */
-
-#if defined(CONFIG_M68020) || defined(CONFIG_M68030)
-#define FPSTATESIZE (216)
-#elif defined(CONFIG_M68040)
-#define FPSTATESIZE (96)
-#elif defined(CONFIG_M68KFPU_EMU)
-#define FPSTATESIZE (28)
-#elif defined(CONFIG_M68060)
-#define FPSTATESIZE (12)
-#else
-#define FPSTATESIZE (0)
-#endif
-
-#endif /* __M68K_FPU_H */
diff --git a/arch/m68k/include/asm/fpu_no.h b/arch/m68k/include/asm/fpu_no.h
deleted file mode 100644
index b16b2e4fca2a..000000000000
--- a/arch/m68k/include/asm/fpu_no.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __M68KNOMMU_FPU_H
-#define __M68KNOMMU_FPU_H
-
-
-/*
- * MAX floating point unit state size (FSAVE/FRESTORE)
- */
-#if defined(CONFIG_M68020) || defined(CONFIG_M68030)
-#define FPSTATESIZE (216/sizeof(unsigned char))
-#elif defined(CONFIG_M68040)
-#define FPSTATESIZE (96/sizeof(unsigned char))
-#elif defined(CONFIG_M68KFPU_EMU)
-#define FPSTATESIZE (28/sizeof(unsigned char))
-#elif defined(CONFIG_M68060)
-#define FPSTATESIZE (12/sizeof(unsigned char))
-#else
-/* Assume no FP unit present then... */
-#define FPSTATESIZE (2) /* dummy size */
-#endif
-
-#endif /* __M68K_FPU_H */
diff --git a/arch/m68k/include/asm/hw_irq.h b/arch/m68k/include/asm/hw_irq.h
index e19526015890..eacef0951fbf 100644
--- a/arch/m68k/include/asm/hw_irq.h
+++ b/arch/m68k/include/asm/hw_irq.h
@@ -1,5 +1,6 @@
-#ifdef __uClinux__
-#include "hw_irq_no.h"
-#else
-#include "hw_irq_mm.h"
+#ifndef __ASM_M68K_HW_IRQ_H
+#define __ASM_M68K_HW_IRQ_H
+
+/* Dummy include. */
+
#endif
diff --git a/arch/m68k/include/asm/hw_irq_mm.h b/arch/m68k/include/asm/hw_irq_mm.h
deleted file mode 100644
index eacef0951fbf..000000000000
--- a/arch/m68k/include/asm/hw_irq_mm.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ASM_M68K_HW_IRQ_H
-#define __ASM_M68K_HW_IRQ_H
-
-/* Dummy include. */
-
-#endif
diff --git a/arch/m68k/include/asm/hw_irq_no.h b/arch/m68k/include/asm/hw_irq_no.h
deleted file mode 100644
index f3ec9e5ae049..000000000000
--- a/arch/m68k/include/asm/hw_irq_no.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef __M68KNOMMU_HW_IRQ_H__
-#define __M68KNOMMU_HW_IRQ_H__
-
-#endif /* __M68KNOMMU_HW_IRQ_H__ */
diff --git a/arch/m68k/include/asm/ide.h b/arch/m68k/include/asm/ide.h
index b996a3c8cff5..3958726664ba 100644
--- a/arch/m68k/include/asm/ide.h
+++ b/arch/m68k/include/asm/ide.h
@@ -30,101 +30,28 @@
#define _M68K_IDE_H
#ifdef __KERNEL__
-
-
#include <asm/setup.h>
#include <asm/io.h>
#include <asm/irq.h>
-#ifdef CONFIG_ATARI
-#include <linux/interrupt.h>
-#include <asm/atari_stdma.h>
-#endif
-
-#ifdef CONFIG_MAC
-#include <asm/macints.h>
-#endif
-
/*
* Get rid of defs from io.h - ide has its private and conflicting versions
* Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we
* always use the `raw' MMIO versions
*/
-#undef inb
-#undef inw
-#undef insw
-#undef inl
-#undef insl
-#undef outb
-#undef outw
-#undef outsw
-#undef outl
-#undef outsl
#undef readb
#undef readw
-#undef readl
#undef writeb
#undef writew
-#undef writel
-#define inb in_8
-#define inw in_be16
-#define insw(port, addr, n) raw_insw((u16 *)port, addr, n)
-#define inl in_be32
-#define insl(port, addr, n) raw_insl((u32 *)port, addr, n)
-#define outb(val, port) out_8(port, val)
-#define outw(val, port) out_be16(port, val)
-#define outsw(port, addr, n) raw_outsw((u16 *)port, addr, n)
-#define outl(val, port) out_be32(port, val)
-#define outsl(port, addr, n) raw_outsl((u32 *)port, addr, n)
#define readb in_8
#define readw in_be16
#define __ide_mm_insw(port, addr, n) raw_insw((u16 *)port, addr, n)
-#define readl in_be32
#define __ide_mm_insl(port, addr, n) raw_insl((u32 *)port, addr, n)
#define writeb(val, port) out_8(port, val)
#define writew(val, port) out_be16(port, val)
#define __ide_mm_outsw(port, addr, n) raw_outsw((u16 *)port, addr, n)
-#define writel(val, port) out_be32(port, val)
#define __ide_mm_outsl(port, addr, n) raw_outsl((u32 *)port, addr, n)
-#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
-#define insw_swapw(port, addr, n) raw_insw_swapw((u16 *)port, addr, n)
-#define outsw_swapw(port, addr, n) raw_outsw_swapw((u16 *)port, addr, n)
-#endif
-
-#ifdef CONFIG_BLK_DEV_FALCON_IDE
-#define IDE_ARCH_LOCK
-
-extern int falconide_intr_lock;
-
-static __inline__ void ide_release_lock (void)
-{
- if (MACH_IS_ATARI) {
- if (falconide_intr_lock == 0) {
- printk("ide_release_lock: bug\n");
- return;
- }
- falconide_intr_lock = 0;
- stdma_release();
- }
-}
-
-static __inline__ void
-ide_get_lock(irq_handler_t handler, void *data)
-{
- if (MACH_IS_ATARI) {
- if (falconide_intr_lock == 0) {
- if (in_interrupt() > 0)
- panic( "Falcon IDE hasn't ST-DMA lock in interrupt" );
- stdma_lock(handler, data);
- falconide_intr_lock = 1;
- }
- }
-}
-#endif /* CONFIG_BLK_DEV_FALCON_IDE */
-
-#define IDE_ARCH_ACK_INTR
-#define ide_ack_intr(hwif) ((hwif)->ack_intr ? (hwif)->ack_intr(hwif) : 1)
#endif /* __KERNEL__ */
#endif /* _M68K_IDE_H */
diff --git a/arch/m68k/include/asm/irq_mm.h b/arch/m68k/include/asm/irq_mm.h
index 226bfc0f21b1..0cab42cad79e 100644
--- a/arch/m68k/include/asm/irq_mm.h
+++ b/arch/m68k/include/asm/irq_mm.h
@@ -3,6 +3,7 @@
#include <linux/linkage.h>
#include <linux/hardirq.h>
+#include <linux/irqreturn.h>
#include <linux/spinlock_types.h>
/*
@@ -80,7 +81,7 @@ struct pt_regs;
* interrupt source (if it supports chaining).
*/
typedef struct irq_node {
- int (*handler)(int, void *);
+ irqreturn_t (*handler)(int, void *);
void *dev_id;
struct irq_node *next;
unsigned long flags;
diff --git a/arch/m68k/include/asm/kmap_types.h b/arch/m68k/include/asm/kmap_types.h
index 045d9fd122a2..c843c63d3801 100644
--- a/arch/m68k/include/asm/kmap_types.h
+++ b/arch/m68k/include/asm/kmap_types.h
@@ -1,5 +1,21 @@
-#ifdef __uClinux__
-#include "kmap_types_no.h"
-#else
-#include "kmap_types_mm.h"
-#endif
+#ifndef __ASM_M68K_KMAP_TYPES_H
+#define __ASM_M68K_KMAP_TYPES_H
+
+enum km_type {
+ KM_BOUNCE_READ,
+ KM_SKB_SUNRPC_DATA,
+ KM_SKB_DATA_SOFTIRQ,
+ KM_USER0,
+ KM_USER1,
+ KM_BIO_SRC_IRQ,
+ KM_BIO_DST_IRQ,
+ KM_PTE0,
+ KM_PTE1,
+ KM_IRQ0,
+ KM_IRQ1,
+ KM_SOFTIRQ0,
+ KM_SOFTIRQ1,
+ KM_TYPE_NR
+};
+
+#endif /* __ASM_M68K_KMAP_TYPES_H */
diff --git a/arch/m68k/include/asm/kmap_types_mm.h b/arch/m68k/include/asm/kmap_types_mm.h
deleted file mode 100644
index c843c63d3801..000000000000
--- a/arch/m68k/include/asm/kmap_types_mm.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __ASM_M68K_KMAP_TYPES_H
-#define __ASM_M68K_KMAP_TYPES_H
-
-enum km_type {
- KM_BOUNCE_READ,
- KM_SKB_SUNRPC_DATA,
- KM_SKB_DATA_SOFTIRQ,
- KM_USER0,
- KM_USER1,
- KM_BIO_SRC_IRQ,
- KM_BIO_DST_IRQ,
- KM_PTE0,
- KM_PTE1,
- KM_IRQ0,
- KM_IRQ1,
- KM_SOFTIRQ0,
- KM_SOFTIRQ1,
- KM_TYPE_NR
-};
-
-#endif /* __ASM_M68K_KMAP_TYPES_H */
diff --git a/arch/m68k/include/asm/kmap_types_no.h b/arch/m68k/include/asm/kmap_types_no.h
deleted file mode 100644
index bfb6707575d1..000000000000
--- a/arch/m68k/include/asm/kmap_types_no.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef __ASM_M68K_KMAP_TYPES_H
-#define __ASM_M68K_KMAP_TYPES_H
-
-enum km_type {
- KM_BOUNCE_READ,
- KM_SKB_SUNRPC_DATA,
- KM_SKB_DATA_SOFTIRQ,
- KM_USER0,
- KM_USER1,
- KM_BIO_SRC_IRQ,
- KM_BIO_DST_IRQ,
- KM_PTE0,
- KM_PTE1,
- KM_IRQ0,
- KM_IRQ1,
- KM_SOFTIRQ0,
- KM_SOFTIRQ1,
- KM_TYPE_NR
-};
-
-#endif
diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h
index 1835fd20a82c..ce603451b55e 100644
--- a/arch/m68k/include/asm/m532xsim.h
+++ b/arch/m68k/include/asm/m532xsim.h
@@ -16,6 +16,7 @@
#define MCFINT_VECBASE 64
#define MCFINT_UART0 26 /* Interrupt number for UART0 */
#define MCFINT_UART1 27 /* Interrupt number for UART1 */
+#define MCFINT_UART2 28 /* Interrupt number for UART2 */
#define MCF_WTM_WCR MCF_REG16(0xFC098000)
diff --git a/arch/m68k/include/asm/macintosh.h b/arch/m68k/include/asm/macintosh.h
index 05309f7e3d06..50db3591ca15 100644
--- a/arch/m68k/include/asm/macintosh.h
+++ b/arch/m68k/include/asm/macintosh.h
@@ -34,6 +34,7 @@ struct mac_model
char scc_type;
char ether_type;
char nubus_type;
+ char floppy_type;
};
#define MAC_ADB_NONE 0
@@ -71,6 +72,12 @@ struct mac_model
#define MAC_NO_NUBUS 0
#define MAC_NUBUS 1
+#define MAC_FLOPPY_IWM 0
+#define MAC_FLOPPY_SWIM_ADDR1 1
+#define MAC_FLOPPY_SWIM_ADDR2 2
+#define MAC_FLOPPY_SWIM_IOP 3
+#define MAC_FLOPPY_AV 4
+
/*
* Gestalt numbers
*/
diff --git a/arch/m68k/include/asm/mc146818rtc.h b/arch/m68k/include/asm/mc146818rtc.h
index fb90dcf78426..9f70a01f73dc 100644
--- a/arch/m68k/include/asm/mc146818rtc.h
+++ b/arch/m68k/include/asm/mc146818rtc.h
@@ -1,5 +1,26 @@
-#ifdef __uClinux__
-#include "mc146818rtc_no.h"
-#else
-#include "mc146818rtc_mm.h"
-#endif
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+
+#ifdef CONFIG_ATARI
+/* RTC in Atari machines */
+
+#include <asm/atarihw.h>
+
+#define RTC_PORT(x) (TT_RTC_BAS + 2*(x))
+#define RTC_ALWAYS_BCD 0
+
+#define CMOS_READ(addr) ({ \
+atari_outb_p((addr),RTC_PORT(0)); \
+atari_inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+atari_outb_p((addr),RTC_PORT(0)); \
+atari_outb_p((val),RTC_PORT(1)); \
+})
+#endif /* CONFIG_ATARI */
+
+#endif /* _ASM_MC146818RTC_H */
diff --git a/arch/m68k/include/asm/mc146818rtc_mm.h b/arch/m68k/include/asm/mc146818rtc_mm.h
deleted file mode 100644
index 9f70a01f73dc..000000000000
--- a/arch/m68k/include/asm/mc146818rtc_mm.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Machine dependent access functions for RTC registers.
- */
-#ifndef _ASM_MC146818RTC_H
-#define _ASM_MC146818RTC_H
-
-
-#ifdef CONFIG_ATARI
-/* RTC in Atari machines */
-
-#include <asm/atarihw.h>
-
-#define RTC_PORT(x) (TT_RTC_BAS + 2*(x))
-#define RTC_ALWAYS_BCD 0
-
-#define CMOS_READ(addr) ({ \
-atari_outb_p((addr),RTC_PORT(0)); \
-atari_inb_p(RTC_PORT(1)); \
-})
-#define CMOS_WRITE(val, addr) ({ \
-atari_outb_p((addr),RTC_PORT(0)); \
-atari_outb_p((val),RTC_PORT(1)); \
-})
-#endif /* CONFIG_ATARI */
-
-#endif /* _ASM_MC146818RTC_H */
diff --git a/arch/m68k/include/asm/mc146818rtc_no.h b/arch/m68k/include/asm/mc146818rtc_no.h
deleted file mode 100644
index 907a0481a140..000000000000
--- a/arch/m68k/include/asm/mc146818rtc_no.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Machine dependent access functions for RTC registers.
- */
-#ifndef _M68KNOMMU_MC146818RTC_H
-#define _M68KNOMMU_MC146818RTC_H
-
-/* empty include file to satisfy the include in genrtc.c/ide-geometry.c */
-
-#endif /* _M68KNOMMU_MC146818RTC_H */
diff --git a/arch/m68k/include/asm/mcfpci.h b/arch/m68k/include/asm/mcfpci.h
deleted file mode 100644
index f1507dd06ec6..000000000000
--- a/arch/m68k/include/asm/mcfpci.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************/
-
-/*
- * mcfpci.h -- PCI bridge on ColdFire eval boards.
- *
- * (C) Copyright 2000, Greg Ungerer (gerg@snapgear.com)
- * (C) Copyright 2000, Lineo Inc. (www.lineo.com)
- */
-
-/****************************************************************************/
-#ifndef mcfpci_h
-#define mcfpci_h
-/****************************************************************************/
-
-
-#ifdef CONFIG_PCI
-
-/*
- * Address regions in the PCI address space are not mapped into the
- * normal memory space of the ColdFire. They must be accessed via
- * handler routines. This is easy for I/O space (inb/outb/etc) but
- * needs some code changes to support ordinary memory. Interrupts
- * also need to be vectored through the PCI handler first, then it
- * will call the actual driver sub-handlers.
- */
-
-/*
- * Un-define all the standard I/O access routines.
- */
-#undef inb
-#undef inw
-#undef inl
-#undef inb_p
-#undef inw_p
-#undef insb
-#undef insw
-#undef insl
-#undef outb
-#undef outw
-#undef outl
-#undef outb_p
-#undef outw_p
-#undef outsb
-#undef outsw
-#undef outsl
-
-#undef request_irq
-#undef free_irq
-
-#undef bus_to_virt
-#undef virt_to_bus
-
-
-/*
- * Re-direct all I/O memory accesses functions to PCI specific ones.
- */
-#define inb pci_inb
-#define inw pci_inw
-#define inl pci_inl
-#define inb_p pci_inb
-#define inw_p pci_inw
-#define insb pci_insb
-#define insw pci_insw
-#define insl pci_insl
-
-#define outb pci_outb
-#define outw pci_outw
-#define outl pci_outl
-#define outb_p pci_outb
-#define outw_p pci_outw
-#define outsb pci_outsb
-#define outsw pci_outsw
-#define outsl pci_outsl
-
-#define request_irq pci_request_irq
-#define free_irq pci_free_irq
-
-#define virt_to_bus pci_virt_to_bus
-#define bus_to_virt pci_bus_to_virt
-
-#define CONFIG_COMEMPCI 1
-
-
-/*
- * Prototypes of the real PCI functions (defined in bios32.c).
- */
-unsigned char pci_inb(unsigned int addr);
-unsigned short pci_inw(unsigned int addr);
-unsigned int pci_inl(unsigned int addr);
-void pci_insb(void *addr, void *buf, int len);
-void pci_insw(void *addr, void *buf, int len);
-void pci_insl(void *addr, void *buf, int len);
-
-void pci_outb(unsigned char val, unsigned int addr);
-void pci_outw(unsigned short val, unsigned int addr);
-void pci_outl(unsigned int val, unsigned int addr);
-void pci_outsb(void *addr, void *buf, int len);
-void pci_outsw(void *addr, void *buf, int len);
-void pci_outsl(void *addr, void *buf, int len);
-
-int pci_request_irq(unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
- unsigned long flags,
- const char *device,
- void *dev_id);
-void pci_free_irq(unsigned int irq, void *dev_id);
-
-void *pci_bmalloc(int size);
-void pci_bmfree(void *bmp, int len);
-void pci_copytoshmem(unsigned long bmp, void *src, int size);
-void pci_copyfromshmem(void *dst, unsigned long bmp, int size);
-unsigned long pci_virt_to_bus(volatile void *address);
-void *pci_bus_to_virt(unsigned long address);
-void pci_bmcpyto(void *dst, void *src, int len);
-void pci_bmcpyfrom(void *dst, void *src, int len);
-
-#endif /* CONFIG_PCI */
-/****************************************************************************/
-#endif /* mcfpci_h */
diff --git a/arch/m68k/include/asm/mmu.h b/arch/m68k/include/asm/mmu.h
index a81d3946675f..8a11a63ee15a 100644
--- a/arch/m68k/include/asm/mmu.h
+++ b/arch/m68k/include/asm/mmu.h
@@ -1,5 +1,13 @@
-#ifdef __uClinux__
-#include "mmu_no.h"
+#ifndef __MMU_H
+#define __MMU_H
+
+#ifdef CONFIG_MMU
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
#else
-#include "mmu_mm.h"
+typedef struct {
+ unsigned long end_brk;
+} mm_context_t;
+#endif
+
#endif
diff --git a/arch/m68k/include/asm/mmu_context.h b/arch/m68k/include/asm/mmu_context.h
index b440928fc6c7..7d4341e55a99 100644
--- a/arch/m68k/include/asm/mmu_context.h
+++ b/arch/m68k/include/asm/mmu_context.h
@@ -1,5 +1,175 @@
-#ifdef __uClinux__
-#include "mmu_context_no.h"
+#ifndef __M68K_MMU_CONTEXT_H
+#define __M68K_MMU_CONTEXT_H
+
+#include <asm-generic/mm_hooks.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+static inline int init_new_context(struct task_struct *tsk,
+ struct mm_struct *mm)
+{
+ mm->context = virt_to_phys(mm->pgd);
+ return 0;
+}
+
+#define destroy_context(mm) do { } while(0)
+
+static inline void switch_mm_0230(struct mm_struct *mm)
+{
+ unsigned long crp[2] = {
+ 0x80000000 | _PAGE_TABLE, mm->context
+ };
+ unsigned long tmp;
+
+ asm volatile (".chip 68030");
+
+ /* flush MC68030/MC68020 caches (they are virtually addressed) */
+ asm volatile (
+ "movec %%cacr,%0;"
+ "orw %1,%0; "
+ "movec %0,%%cacr"
+ : "=d" (tmp) : "di" (FLUSH_I_AND_D));
+
+ /* Switch the root pointer. For a 030-only kernel,
+ * avoid flushing the whole ATC, we only need to
+ * flush the user entries. The 68851 does this by
+ * itself. Avoid a runtime check here.
+ */
+ asm volatile (
+#ifdef CPU_M68030_ONLY
+ "pmovefd %0,%%crp; "
+ "pflush #0,#4"
#else
-#include "mmu_context_mm.h"
+ "pmove %0,%%crp"
#endif
+ : : "m" (crp[0]));
+
+ asm volatile (".chip 68k");
+}
+
+static inline void switch_mm_0460(struct mm_struct *mm)
+{
+ asm volatile (".chip 68040");
+
+ /* flush address translation cache (user entries) */
+ asm volatile ("pflushan");
+
+ /* switch the root pointer */
+ asm volatile ("movec %0,%%urp" : : "r" (mm->context));
+
+ if (CPU_IS_060) {
+ unsigned long tmp;
+
+ /* clear user entries in the branch cache */
+ asm volatile (
+ "movec %%cacr,%0; "
+ "orl %1,%0; "
+ "movec %0,%%cacr"
+ : "=d" (tmp): "di" (0x00200000));
+ }
+
+ asm volatile (".chip 68k");
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
+{
+ if (prev != next) {
+ if (CPU_IS_020_OR_030)
+ switch_mm_0230(next);
+ else
+ switch_mm_0460(next);
+ }
+}
+
+#define deactivate_mm(tsk,mm) do { } while (0)
+
+static inline void activate_mm(struct mm_struct *prev_mm,
+ struct mm_struct *next_mm)
+{
+ next_mm->context = virt_to_phys(next_mm->pgd);
+
+ if (CPU_IS_020_OR_030)
+ switch_mm_0230(next_mm);
+ else
+ switch_mm_0460(next_mm);
+}
+
+#else /* CONFIG_SUN3 */
+#include <asm/sun3mmu.h>
+#include <linux/sched.h>
+
+extern unsigned long get_free_context(struct mm_struct *mm);
+extern void clear_context(unsigned long context);
+
+/* set the context for a new task to unmapped */
+static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ mm->context = SUN3_INVALID_CONTEXT;
+ return 0;
+}
+
+/* find the context given to this process, and if it hasn't already
+ got one, go get one for it. */
+static inline void get_mmu_context(struct mm_struct *mm)
+{
+ if(mm->context == SUN3_INVALID_CONTEXT)
+ mm->context = get_free_context(mm);
+}
+
+/* flush context if allocated... */
+static inline void destroy_context(struct mm_struct *mm)
+{
+ if(mm->context != SUN3_INVALID_CONTEXT)
+ clear_context(mm->context);
+}
+
+static inline void activate_context(struct mm_struct *mm)
+{
+ get_mmu_context(mm);
+ sun3_put_context(mm->context);
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
+{
+ activate_context(tsk->mm);
+}
+
+#define deactivate_mm(tsk,mm) do { } while (0)
+
+static inline void activate_mm(struct mm_struct *prev_mm,
+ struct mm_struct *next_mm)
+{
+ activate_context(next_mm);
+}
+
+#endif
+#else /* !CONFIG_MMU */
+
+static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ return 0;
+}
+
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
+{
+}
+
+#define destroy_context(mm) do { } while (0)
+#define deactivate_mm(tsk,mm) do { } while (0)
+
+static inline void activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
+{
+}
+
+#endif /* CONFIG_MMU */
+#endif /* __M68K_MMU_CONTEXT_H */
diff --git a/arch/m68k/include/asm/mmu_context_mm.h b/arch/m68k/include/asm/mmu_context_mm.h
deleted file mode 100644
index 894dacbcee14..000000000000
--- a/arch/m68k/include/asm/mmu_context_mm.h
+++ /dev/null
@@ -1,154 +0,0 @@
-#ifndef __M68K_MMU_CONTEXT_H
-#define __M68K_MMU_CONTEXT_H
-
-#include <asm-generic/mm_hooks.h>
-
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-{
-}
-
-#ifndef CONFIG_SUN3
-
-#include <asm/setup.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-
-static inline int init_new_context(struct task_struct *tsk,
- struct mm_struct *mm)
-{
- mm->context = virt_to_phys(mm->pgd);
- return 0;
-}
-
-#define destroy_context(mm) do { } while(0)
-
-static inline void switch_mm_0230(struct mm_struct *mm)
-{
- unsigned long crp[2] = {
- 0x80000000 | _PAGE_TABLE, mm->context
- };
- unsigned long tmp;
-
- asm volatile (".chip 68030");
-
- /* flush MC68030/MC68020 caches (they are virtually addressed) */
- asm volatile (
- "movec %%cacr,%0;"
- "orw %1,%0; "
- "movec %0,%%cacr"
- : "=d" (tmp) : "di" (FLUSH_I_AND_D));
-
- /* Switch the root pointer. For a 030-only kernel,
- * avoid flushing the whole ATC, we only need to
- * flush the user entries. The 68851 does this by
- * itself. Avoid a runtime check here.
- */
- asm volatile (
-#ifdef CPU_M68030_ONLY
- "pmovefd %0,%%crp; "
- "pflush #0,#4"
-#else
- "pmove %0,%%crp"
-#endif
- : : "m" (crp[0]));
-
- asm volatile (".chip 68k");
-}
-
-static inline void switch_mm_0460(struct mm_struct *mm)
-{
- asm volatile (".chip 68040");
-
- /* flush address translation cache (user entries) */
- asm volatile ("pflushan");
-
- /* switch the root pointer */
- asm volatile ("movec %0,%%urp" : : "r" (mm->context));
-
- if (CPU_IS_060) {
- unsigned long tmp;
-
- /* clear user entries in the branch cache */
- asm volatile (
- "movec %%cacr,%0; "
- "orl %1,%0; "
- "movec %0,%%cacr"
- : "=d" (tmp): "di" (0x00200000));
- }
-
- asm volatile (".chip 68k");
-}
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
-{
- if (prev != next) {
- if (CPU_IS_020_OR_030)
- switch_mm_0230(next);
- else
- switch_mm_0460(next);
- }
-}
-
-#define deactivate_mm(tsk,mm) do { } while (0)
-
-static inline void activate_mm(struct mm_struct *prev_mm,
- struct mm_struct *next_mm)
-{
- next_mm->context = virt_to_phys(next_mm->pgd);
-
- if (CPU_IS_020_OR_030)
- switch_mm_0230(next_mm);
- else
- switch_mm_0460(next_mm);
-}
-
-#else /* CONFIG_SUN3 */
-#include <asm/sun3mmu.h>
-#include <linux/sched.h>
-
-extern unsigned long get_free_context(struct mm_struct *mm);
-extern void clear_context(unsigned long context);
-
-/* set the context for a new task to unmapped */
-static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-{
- mm->context = SUN3_INVALID_CONTEXT;
- return 0;
-}
-
-/* find the context given to this process, and if it hasn't already
- got one, go get one for it. */
-static inline void get_mmu_context(struct mm_struct *mm)
-{
- if(mm->context == SUN3_INVALID_CONTEXT)
- mm->context = get_free_context(mm);
-}
-
-/* flush context if allocated... */
-static inline void destroy_context(struct mm_struct *mm)
-{
- if(mm->context != SUN3_INVALID_CONTEXT)
- clear_context(mm->context);
-}
-
-static inline void activate_context(struct mm_struct *mm)
-{
- get_mmu_context(mm);
- sun3_put_context(mm->context);
-}
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
-{
- activate_context(tsk->mm);
-}
-
-#define deactivate_mm(tsk,mm) do { } while (0)
-
-static inline void activate_mm(struct mm_struct *prev_mm,
- struct mm_struct *next_mm)
-{
- activate_context(next_mm);
-}
-
-#endif
-#endif
diff --git a/arch/m68k/include/asm/mmu_context_no.h b/arch/m68k/include/asm/mmu_context_no.h
deleted file mode 100644
index 9ccee4278c97..000000000000
--- a/arch/m68k/include/asm/mmu_context_no.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __M68KNOMMU_MMU_CONTEXT_H
-#define __M68KNOMMU_MMU_CONTEXT_H
-
-#include <asm/setup.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-#include <asm-generic/mm_hooks.h>
-
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
-{
-}
-
-static inline int
-init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-{
- // mm->context = virt_to_phys(mm->pgd);
- return(0);
-}
-
-#define destroy_context(mm) do { } while(0)
-
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk)
-{
-}
-
-#define deactivate_mm(tsk,mm) do { } while (0)
-
-static inline void activate_mm(struct mm_struct *prev_mm,
- struct mm_struct *next_mm)
-{
-}
-
-#endif
diff --git a/arch/m68k/include/asm/mmu_mm.h b/arch/m68k/include/asm/mmu_mm.h
deleted file mode 100644
index ccd36d26615a..000000000000
--- a/arch/m68k/include/asm/mmu_mm.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __MMU_H
-#define __MMU_H
-
-/* Default "unsigned long" context */
-typedef unsigned long mm_context_t;
-
-#endif
diff --git a/arch/m68k/include/asm/mmu_no.h b/arch/m68k/include/asm/mmu_no.h
deleted file mode 100644
index e2da1e6f09fe..000000000000
--- a/arch/m68k/include/asm/mmu_no.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __M68KNOMMU_MMU_H
-#define __M68KNOMMU_MMU_H
-
-/* Copyright (C) 2002, David McCullough <davidm@snapgear.com> */
-
-typedef struct {
- unsigned long end_brk;
-} mm_context_t;
-
-#endif /* __M68KNOMMU_MMU_H */
diff --git a/arch/m68k/include/asm/module.h b/arch/m68k/include/asm/module.h
index 79b59d137dd0..5f21e11071bd 100644
--- a/arch/m68k/include/asm/module.h
+++ b/arch/m68k/include/asm/module.h
@@ -1,5 +1,48 @@
-#ifdef __uClinux__
-#include "module_no.h"
+#ifndef _ASM_M68K_MODULE_H
+#define _ASM_M68K_MODULE_H
+
+#ifdef CONFIG_MMU
+
+struct mod_arch_specific {
+ struct m68k_fixup_info *fixup_start, *fixup_end;
+};
+
+#define MODULE_ARCH_INIT { \
+ .fixup_start = __start_fixup, \
+ .fixup_end = __stop_fixup, \
+}
+
+
+enum m68k_fixup_type {
+ m68k_fixup_memoffset,
+ m68k_fixup_vnode_shift,
+};
+
+struct m68k_fixup_info {
+ enum m68k_fixup_type type;
+ void *addr;
+};
+
+#define m68k_fixup(type, addr) \
+ " .section \".m68k_fixup\",\"aw\"\n" \
+ " .long " #type "," #addr "\n" \
+ " .previous\n"
+
+extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
+
+struct module;
+extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
+ struct m68k_fixup_info *end);
+
#else
-#include "module_mm.h"
-#endif
+
+struct mod_arch_specific {
+};
+
+#endif /* CONFIG_MMU */
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+
+#endif /* _ASM_M68K_MODULE_H */
diff --git a/arch/m68k/include/asm/module_mm.h b/arch/m68k/include/asm/module_mm.h
deleted file mode 100644
index 382d20a6fc18..000000000000
--- a/arch/m68k/include/asm/module_mm.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef _ASM_M68K_MODULE_H
-#define _ASM_M68K_MODULE_H
-
-struct mod_arch_specific {
- struct m68k_fixup_info *fixup_start, *fixup_end;
-};
-
-#define MODULE_ARCH_INIT { \
- .fixup_start = __start_fixup, \
- .fixup_end = __stop_fixup, \
-}
-
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-
-
-enum m68k_fixup_type {
- m68k_fixup_memoffset,
- m68k_fixup_vnode_shift,
-};
-
-struct m68k_fixup_info {
- enum m68k_fixup_type type;
- void *addr;
-};
-
-#define m68k_fixup(type, addr) \
- " .section \".m68k_fixup\",\"aw\"\n" \
- " .long " #type "," #addr "\n" \
- " .previous\n"
-
-extern struct m68k_fixup_info __start_fixup[], __stop_fixup[];
-
-struct module;
-extern void module_fixup(struct module *mod, struct m68k_fixup_info *start,
- struct m68k_fixup_info *end);
-
-#endif /* _ASM_M68K_MODULE_H */
diff --git a/arch/m68k/include/asm/module_no.h b/arch/m68k/include/asm/module_no.h
deleted file mode 100644
index 2e45ab50b232..000000000000
--- a/arch/m68k/include/asm/module_no.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef ASM_M68KNOMMU_MODULE_H
-#define ASM_M68KNOMMU_MODULE_H
-
-struct mod_arch_specific {
-};
-
-#define Elf_Shdr Elf32_Shdr
-#define Elf_Sym Elf32_Sym
-#define Elf_Ehdr Elf32_Ehdr
-
-#endif /* ASM_M68KNOMMU_MODULE_H */
diff --git a/arch/m68k/include/asm/page_offset.h b/arch/m68k/include/asm/page_offset.h
index 66455c849fbb..1780152d81da 100644
--- a/arch/m68k/include/asm/page_offset.h
+++ b/arch/m68k/include/asm/page_offset.h
@@ -1,5 +1,11 @@
-#ifdef __uClinux__
-#include "page_offset_no.h"
+/* This handles the memory map.. */
+
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+#define PAGE_OFFSET_RAW 0x00000000
#else
-#include "page_offset_mm.h"
+#define PAGE_OFFSET_RAW 0x0E000000
+#endif
+#else
+#define PAGE_OFFSET_RAW CONFIG_RAMBASE
#endif
diff --git a/arch/m68k/include/asm/page_offset_mm.h b/arch/m68k/include/asm/page_offset_mm.h
deleted file mode 100644
index 1cbdb7f30ac2..000000000000
--- a/arch/m68k/include/asm/page_offset_mm.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-/* This handles the memory map.. */
-#ifndef CONFIG_SUN3
-#define PAGE_OFFSET_RAW 0x00000000
-#else
-#define PAGE_OFFSET_RAW 0x0E000000
-#endif
-
diff --git a/arch/m68k/include/asm/page_offset_no.h b/arch/m68k/include/asm/page_offset_no.h
deleted file mode 100644
index d4e73e0ba646..000000000000
--- a/arch/m68k/include/asm/page_offset_no.h
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-/* This handles the memory map.. */
-#define PAGE_OFFSET_RAW CONFIG_RAMBASE
-
diff --git a/arch/m68k/include/asm/param.h b/arch/m68k/include/asm/param.h
index 40d1112a4588..85c41b75aa78 100644
--- a/arch/m68k/include/asm/param.h
+++ b/arch/m68k/include/asm/param.h
@@ -1,5 +1,26 @@
+#ifndef _M68K_PARAM_H
+#define _M68K_PARAM_H
+
+#ifdef __KERNEL__
+# define HZ CONFIG_HZ /* Internal kernel timer frequency */
+# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
+# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
+#endif
+
+#ifndef HZ
+#define HZ 100
+#endif
+
#ifdef __uClinux__
-#include "param_no.h"
+#define EXEC_PAGESIZE 4096
#else
-#include "param_mm.h"
+#define EXEC_PAGESIZE 8192
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP (-1)
#endif
+
+#define MAXHOSTNAMELEN 64 /* max length of hostname */
+
+#endif /* _M68K_PARAM_H */
diff --git a/arch/m68k/include/asm/param_mm.h b/arch/m68k/include/asm/param_mm.h
deleted file mode 100644
index 536a27888358..000000000000
--- a/arch/m68k/include/asm/param_mm.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _M68K_PARAM_H
-#define _M68K_PARAM_H
-
-#ifdef __KERNEL__
-# define HZ CONFIG_HZ /* Internal kernel timer frequency */
-# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
-# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE 8192
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
-
-#endif /* _M68K_PARAM_H */
diff --git a/arch/m68k/include/asm/param_no.h b/arch/m68k/include/asm/param_no.h
deleted file mode 100644
index 6044397adb64..000000000000
--- a/arch/m68k/include/asm/param_no.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _M68KNOMMU_PARAM_H
-#define _M68KNOMMU_PARAM_H
-
-#ifdef __KERNEL__
-#define HZ CONFIG_HZ
-#define USER_HZ HZ
-#define CLOCKS_PER_SEC (USER_HZ)
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE 4096
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
-
-#endif /* _M68KNOMMU_PARAM_H */
diff --git a/arch/m68k/include/asm/pci.h b/arch/m68k/include/asm/pci.h
index dbea95373080..4ad0aea48ab4 100644
--- a/arch/m68k/include/asm/pci.h
+++ b/arch/m68k/include/asm/pci.h
@@ -1,5 +1,12 @@
-#ifdef __uClinux__
-#include "pci_no.h"
-#else
-#include "pci_mm.h"
-#endif
+#ifndef _ASM_M68K_PCI_H
+#define _ASM_M68K_PCI_H
+
+#include <asm-generic/pci-dma-compat.h>
+
+/* The PCI address space does equal the physical memory
+ * address space. The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS (1)
+
+#endif /* _ASM_M68K_PCI_H */
diff --git a/arch/m68k/include/asm/pci_mm.h b/arch/m68k/include/asm/pci_mm.h
deleted file mode 100644
index 4ad0aea48ab4..000000000000
--- a/arch/m68k/include/asm/pci_mm.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _ASM_M68K_PCI_H
-#define _ASM_M68K_PCI_H
-
-#include <asm-generic/pci-dma-compat.h>
-
-/* The PCI address space does equal the physical memory
- * address space. The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS (1)
-
-#endif /* _ASM_M68K_PCI_H */
diff --git a/arch/m68k/include/asm/pci_no.h b/arch/m68k/include/asm/pci_no.h
deleted file mode 100644
index 9abbc03c73ee..000000000000
--- a/arch/m68k/include/asm/pci_no.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef M68KNOMMU_PCI_H
-#define M68KNOMMU_PCI_H
-
-#include <asm/pci_mm.h>
-
-#ifdef CONFIG_COMEMPCI
-/*
- * These are pretty much arbitary with the CoMEM implementation.
- * We have the whole address space to ourselves.
- */
-#define PCIBIOS_MIN_IO 0x100
-#define PCIBIOS_MIN_MEM 0x00010000
-
-#define pcibios_scan_all_fns(a, b) 0
-
-/*
- * Return whether the given PCI device DMA address mask can
- * be supported properly. For example, if your device can
- * only drive the low 24-bits during PCI bus mastering, then
- * you would pass 0x00ffffff as the mask to this function.
- */
-static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask)
-{
- return 1;
-}
-
-#endif /* CONFIG_COMEMPCI */
-
-#endif /* M68KNOMMU_PCI_H */
diff --git a/arch/m68k/include/asm/pgalloc.h b/arch/m68k/include/asm/pgalloc.h
index 059cb73e78fc..c294aad8a900 100644
--- a/arch/m68k/include/asm/pgalloc.h
+++ b/arch/m68k/include/asm/pgalloc.h
@@ -1,5 +1,19 @@
-#ifdef __uClinux__
-#include "pgalloc_no.h"
+#ifndef M68K_PGALLOC_H
+#define M68K_PGALLOC_H
+
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <asm/setup.h>
+
+#ifdef CONFIG_MMU
+#include <asm/virtconvert.h>
+#ifdef CONFIG_SUN3
+#include <asm/sun3_pgalloc.h>
#else
-#include "pgalloc_mm.h"
+#include <asm/motorola_pgalloc.h>
#endif
+
+extern void m68k_setup_node(int node);
+#endif
+
+#endif /* M68K_PGALLOC_H */
diff --git a/arch/m68k/include/asm/pgalloc_mm.h b/arch/m68k/include/asm/pgalloc_mm.h
deleted file mode 100644
index 4cb1a57ab763..000000000000
--- a/arch/m68k/include/asm/pgalloc_mm.h
+++ /dev/null
@@ -1,19 +0,0 @@
-
-#ifndef M68K_PGALLOC_H
-#define M68K_PGALLOC_H
-
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <asm/setup.h>
-#include <asm/virtconvert.h>
-
-
-#ifdef CONFIG_SUN3
-#include <asm/sun3_pgalloc.h>
-#else
-#include <asm/motorola_pgalloc.h>
-#endif
-
-extern void m68k_setup_node(int node);
-
-#endif /* M68K_PGALLOC_H */
diff --git a/arch/m68k/include/asm/pgalloc_no.h b/arch/m68k/include/asm/pgalloc_no.h
deleted file mode 100644
index d6352f671ec0..000000000000
--- a/arch/m68k/include/asm/pgalloc_no.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _M68KNOMMU_PGALLOC_H
-#define _M68KNOMMU_PGALLOC_H
-
-#include <asm/setup.h>
-
-#define check_pgt_cache() do { } while (0)
-
-#endif /* _M68KNOMMU_PGALLOC_H */
diff --git a/arch/m68k/include/asm/pgtable_no.h b/arch/m68k/include/asm/pgtable_no.h
index 46251016e821..bf86b29fe64a 100644
--- a/arch/m68k/include/asm/pgtable_no.h
+++ b/arch/m68k/include/asm/pgtable_no.h
@@ -67,4 +67,6 @@ extern unsigned int kobjsize(const void *objp);
#include <asm-generic/pgtable.h>
+#define check_pgt_cache() do { } while (0)
+
#endif /* _M68KNOMMU_PGTABLE_H */
diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h
index e83cd2f66101..8c9194b98548 100644
--- a/arch/m68k/include/asm/ptrace.h
+++ b/arch/m68k/include/asm/ptrace.h
@@ -1,5 +1,87 @@
-#ifdef __uClinux__
-#include "ptrace_no.h"
+#ifndef _M68K_PTRACE_H
+#define _M68K_PTRACE_H
+
+#define PT_D1 0
+#define PT_D2 1
+#define PT_D3 2
+#define PT_D4 3
+#define PT_D5 4
+#define PT_D6 5
+#define PT_D7 6
+#define PT_A0 7
+#define PT_A1 8
+#define PT_A2 9
+#define PT_A3 10
+#define PT_A4 11
+#define PT_A5 12
+#define PT_A6 13
+#define PT_D0 14
+#define PT_USP 15
+#define PT_ORIG_D0 16
+#define PT_SR 17
+#define PT_PC 18
+
+#ifndef __ASSEMBLY__
+
+/* this struct defines the way the registers are stored on the
+ stack during a system call. */
+
+struct pt_regs {
+ long d1;
+ long d2;
+ long d3;
+ long d4;
+ long d5;
+ long a0;
+ long a1;
+ long a2;
+ long d0;
+ long orig_d0;
+ long stkadj;
+#ifdef CONFIG_COLDFIRE
+ unsigned format : 4; /* frame format specifier */
+ unsigned vector : 12; /* vector offset */
+ unsigned short sr;
+ unsigned long pc;
#else
-#include "ptrace_mm.h"
+ unsigned short sr;
+ unsigned long pc;
+ unsigned format : 4; /* frame format specifier */
+ unsigned vector : 12; /* vector offset */
#endif
+};
+
+/*
+ * This is the extended stack used by signal handlers and the context
+ * switcher: it's pushed after the normal "struct pt_regs".
+ */
+struct switch_stack {
+ unsigned long d6;
+ unsigned long d7;
+ unsigned long a3;
+ unsigned long a4;
+ unsigned long a5;
+ unsigned long a6;
+ unsigned long retpc;
+};
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+
+#ifdef __KERNEL__
+
+#ifndef PS_S
+#define PS_S (0x2000)
+#define PS_M (0x1000)
+#endif
+
+#define user_mode(regs) (!((regs)->sr & PS_S))
+#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
+extern void show_regs(struct pt_regs *);
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* _M68K_PTRACE_H */
diff --git a/arch/m68k/include/asm/ptrace_mm.h b/arch/m68k/include/asm/ptrace_mm.h
deleted file mode 100644
index 57e763d79bf4..000000000000
--- a/arch/m68k/include/asm/ptrace_mm.h
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef _M68K_PTRACE_H
-#define _M68K_PTRACE_H
-
-#define PT_D1 0
-#define PT_D2 1
-#define PT_D3 2
-#define PT_D4 3
-#define PT_D5 4
-#define PT_D6 5
-#define PT_D7 6
-#define PT_A0 7
-#define PT_A1 8
-#define PT_A2 9
-#define PT_A3 10
-#define PT_A4 11
-#define PT_A5 12
-#define PT_A6 13
-#define PT_D0 14
-#define PT_USP 15
-#define PT_ORIG_D0 16
-#define PT_SR 17
-#define PT_PC 18
-
-#ifndef __ASSEMBLY__
-
-/* this struct defines the way the registers are stored on the
- stack during a system call. */
-
-struct pt_regs {
- long d1;
- long d2;
- long d3;
- long d4;
- long d5;
- long a0;
- long a1;
- long a2;
- long d0;
- long orig_d0;
- long stkadj;
- unsigned short sr;
- unsigned long pc;
- unsigned format : 4; /* frame format specifier */
- unsigned vector : 12; /* vector offset */
-};
-
-/*
- * This is the extended stack used by signal handlers and the context
- * switcher: it's pushed after the normal "struct pt_regs".
- */
-struct switch_stack {
- unsigned long d6;
- unsigned long d7;
- unsigned long a3;
- unsigned long a4;
- unsigned long a5;
- unsigned long a6;
- unsigned long retpc;
-};
-
-/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-#define PTRACE_GETFPREGS 14
-#define PTRACE_SETFPREGS 15
-
-#ifdef __KERNEL__
-
-#ifndef PS_S
-#define PS_S (0x2000)
-#define PS_M (0x1000)
-#endif
-
-#define user_mode(regs) (!((regs)->sr & PS_S))
-#define instruction_pointer(regs) ((regs)->pc)
-#define profile_pc(regs) instruction_pointer(regs)
-extern void show_regs(struct pt_regs *);
-#endif /* __KERNEL__ */
-#endif /* __ASSEMBLY__ */
-#endif /* _M68K_PTRACE_H */
diff --git a/arch/m68k/include/asm/ptrace_no.h b/arch/m68k/include/asm/ptrace_no.h
deleted file mode 100644
index 8c9194b98548..000000000000
--- a/arch/m68k/include/asm/ptrace_no.h
+++ /dev/null
@@ -1,87 +0,0 @@
-#ifndef _M68K_PTRACE_H
-#define _M68K_PTRACE_H
-
-#define PT_D1 0
-#define PT_D2 1
-#define PT_D3 2
-#define PT_D4 3
-#define PT_D5 4
-#define PT_D6 5
-#define PT_D7 6
-#define PT_A0 7
-#define PT_A1 8
-#define PT_A2 9
-#define PT_A3 10
-#define PT_A4 11
-#define PT_A5 12
-#define PT_A6 13
-#define PT_D0 14
-#define PT_USP 15
-#define PT_ORIG_D0 16
-#define PT_SR 17
-#define PT_PC 18
-
-#ifndef __ASSEMBLY__
-
-/* this struct defines the way the registers are stored on the
- stack during a system call. */
-
-struct pt_regs {
- long d1;
- long d2;
- long d3;
- long d4;
- long d5;
- long a0;
- long a1;
- long a2;
- long d0;
- long orig_d0;
- long stkadj;
-#ifdef CONFIG_COLDFIRE
- unsigned format : 4; /* frame format specifier */
- unsigned vector : 12; /* vector offset */
- unsigned short sr;
- unsigned long pc;
-#else
- unsigned short sr;
- unsigned long pc;
- unsigned format : 4; /* frame format specifier */
- unsigned vector : 12; /* vector offset */
-#endif
-};
-
-/*
- * This is the extended stack used by signal handlers and the context
- * switcher: it's pushed after the normal "struct pt_regs".
- */
-struct switch_stack {
- unsigned long d6;
- unsigned long d7;
- unsigned long a3;
- unsigned long a4;
- unsigned long a5;
- unsigned long a6;
- unsigned long retpc;
-};
-
-/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
-#define PTRACE_GETREGS 12
-#define PTRACE_SETREGS 13
-#define PTRACE_GETFPREGS 14
-#define PTRACE_SETFPREGS 15
-
-#ifdef __KERNEL__
-
-#ifndef PS_S
-#define PS_S (0x2000)
-#define PS_M (0x1000)
-#endif
-
-#define user_mode(regs) (!((regs)->sr & PS_S))
-#define instruction_pointer(regs) ((regs)->pc)
-#define profile_pc(regs) instruction_pointer(regs)
-extern void show_regs(struct pt_regs *);
-#endif /* __KERNEL__ */
-#endif /* __ASSEMBLY__ */
-#endif /* _M68K_PTRACE_H */
diff --git a/arch/m68k/include/asm/rtc.h b/arch/m68k/include/asm/rtc.h
index 5d3e03859844..a4d08ea122ee 100644
--- a/arch/m68k/include/asm/rtc.h
+++ b/arch/m68k/include/asm/rtc.h
@@ -36,13 +36,16 @@ static inline unsigned int get_rtc_time(struct rtc_time *time)
* RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
* by the RTC when initially set to a non-zero value.
*/
- mach_hwclk(0, time);
+ if (mach_hwclk)
+ mach_hwclk(0, time);
return RTC_24H;
}
static inline int set_rtc_time(struct rtc_time *time)
{
- return mach_hwclk(1, time);
+ if (mach_hwclk)
+ return mach_hwclk(1, time);
+ return -EINVAL;
}
static inline unsigned int get_rtc_ss(void)
diff --git a/arch/m68k/include/asm/scatterlist.h b/arch/m68k/include/asm/scatterlist.h
index b7e528636252..e27ad902b1cf 100644
--- a/arch/m68k/include/asm/scatterlist.h
+++ b/arch/m68k/include/asm/scatterlist.h
@@ -1,5 +1,23 @@
-#ifdef __uClinux__
-#include "scatterlist_no.h"
-#else
-#include "scatterlist_mm.h"
+#ifndef _M68K_SCATTERLIST_H
+#define _M68K_SCATTERLIST_H
+
+#include <linux/types.h>
+
+struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
#endif
+ unsigned long page_link;
+ unsigned int offset;
+ unsigned int length;
+
+ dma_addr_t dma_address; /* A place to hang host-specific addresses at. */
+};
+
+/* This is bogus and should go away. */
+#define ISA_DMA_THRESHOLD (0x00ffffff)
+
+#define sg_dma_address(sg) ((sg)->dma_address)
+#define sg_dma_len(sg) ((sg)->length)
+
+#endif /* !(_M68K_SCATTERLIST_H) */
diff --git a/arch/m68k/include/asm/scatterlist_mm.h b/arch/m68k/include/asm/scatterlist_mm.h
deleted file mode 100644
index d3a7a0edfeca..000000000000
--- a/arch/m68k/include/asm/scatterlist_mm.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _M68K_SCATTERLIST_H
-#define _M68K_SCATTERLIST_H
-
-#include <linux/types.h>
-
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
- unsigned long sg_magic;
-#endif
- unsigned long page_link;
- unsigned int offset;
- unsigned int length;
-
- __u32 dma_address; /* A place to hang host-specific addresses at. */
-};
-
-/* This is bogus and should go away. */
-#define ISA_DMA_THRESHOLD (0x00ffffff)
-
-#define sg_dma_address(sg) ((sg)->dma_address)
-#define sg_dma_len(sg) ((sg)->length)
-
-#endif /* !(_M68K_SCATTERLIST_H) */
diff --git a/arch/m68k/include/asm/scatterlist_no.h b/arch/m68k/include/asm/scatterlist_no.h
deleted file mode 100644
index afc4788b0d2c..000000000000
--- a/arch/m68k/include/asm/scatterlist_no.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _M68KNOMMU_SCATTERLIST_H
-#define _M68KNOMMU_SCATTERLIST_H
-
-#include <linux/mm.h>
-#include <asm/types.h>
-
-struct scatterlist {
-#ifdef CONFIG_DEBUG_SG
- unsigned long sg_magic;
-#endif
- unsigned long page_link;
- unsigned int offset;
- dma_addr_t dma_address;
- unsigned int length;
-};
-
-#define sg_dma_address(sg) ((sg)->dma_address)
-#define sg_dma_len(sg) ((sg)->length)
-
-#define ISA_DMA_THRESHOLD (0xffffffff)
-
-#endif /* !(_M68KNOMMU_SCATTERLIST_H) */
diff --git a/arch/m68k/include/asm/segment.h b/arch/m68k/include/asm/segment.h
index 82583bc004bd..ee959219fdfe 100644
--- a/arch/m68k/include/asm/segment.h
+++ b/arch/m68k/include/asm/segment.h
@@ -1,5 +1,63 @@
-#ifdef __uClinux__
-#include "segment_no.h"
+#ifndef _M68K_SEGMENT_H
+#define _M68K_SEGMENT_H
+
+/* define constants */
+/* Address spaces (FC0-FC2) */
+#define USER_DATA (1)
+#ifndef __USER_DS
+#define __USER_DS (USER_DATA)
+#endif
+#define USER_PROGRAM (2)
+#define SUPER_DATA (5)
+#ifndef __KERNEL_DS
+#define __KERNEL_DS (SUPER_DATA)
+#endif
+#define SUPER_PROGRAM (6)
+#define CPU_SPACE (7)
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
+#define USER_DS MAKE_MM_SEG(__USER_DS)
+#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS)
+
+/*
+ * Get/set the SFC/DFC registers for MOVES instructions
+ */
+
+static inline mm_segment_t get_fs(void)
+{
+#ifdef CONFIG_MMU
+ mm_segment_t _v;
+ __asm__ ("movec %/dfc,%0":"=r" (_v.seg):);
+
+ return _v;
#else
-#include "segment_mm.h"
+ return USER_DS;
+#endif
+}
+
+static inline mm_segment_t get_ds(void)
+{
+ /* return the supervisor data space code */
+ return KERNEL_DS;
+}
+
+static inline void set_fs(mm_segment_t val)
+{
+#ifdef CONFIG_MMU
+ __asm__ __volatile__ ("movec %0,%/sfc\n\t"
+ "movec %0,%/dfc\n\t"
+ : /* no outputs */ : "r" (val.seg) : "memory");
#endif
+}
+
+#define segment_eq(a,b) ((a).seg == (b).seg)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _M68K_SEGMENT_H */
diff --git a/arch/m68k/include/asm/segment_mm.h b/arch/m68k/include/asm/segment_mm.h
deleted file mode 100644
index 7b0b2d3127f9..000000000000
--- a/arch/m68k/include/asm/segment_mm.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef _M68K_SEGMENT_H
-#define _M68K_SEGMENT_H
-
-/* define constants */
-/* Address spaces (FC0-FC2) */
-#define USER_DATA (1)
-#ifndef __USER_DS
-#define __USER_DS (USER_DATA)
-#endif
-#define USER_PROGRAM (2)
-#define SUPER_DATA (5)
-#ifndef __KERNEL_DS
-#define __KERNEL_DS (SUPER_DATA)
-#endif
-#define SUPER_PROGRAM (6)
-#define CPU_SPACE (7)
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
-#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-#define USER_DS MAKE_MM_SEG(__USER_DS)
-#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS)
-
-/*
- * Get/set the SFC/DFC registers for MOVES instructions
- */
-
-static inline mm_segment_t get_fs(void)
-{
- mm_segment_t _v;
- __asm__ ("movec %/dfc,%0":"=r" (_v.seg):);
-
- return _v;
-}
-
-static inline mm_segment_t get_ds(void)
-{
- /* return the supervisor data space code */
- return KERNEL_DS;
-}
-
-static inline void set_fs(mm_segment_t val)
-{
- __asm__ __volatile__ ("movec %0,%/sfc\n\t"
- "movec %0,%/dfc\n\t"
- : /* no outputs */ : "r" (val.seg) : "memory");
-}
-
-#define segment_eq(a,b) ((a).seg == (b).seg)
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _M68K_SEGMENT_H */
diff --git a/arch/m68k/include/asm/segment_no.h b/arch/m68k/include/asm/segment_no.h
deleted file mode 100644
index 42318ebec7ec..000000000000
--- a/arch/m68k/include/asm/segment_no.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _M68K_SEGMENT_H
-#define _M68K_SEGMENT_H
-
-/* define constants */
-/* Address spaces (FC0-FC2) */
-#define USER_DATA (1)
-#ifndef __USER_DS
-#define __USER_DS (USER_DATA)
-#endif
-#define USER_PROGRAM (2)
-#define SUPER_DATA (5)
-#ifndef __KERNEL_DS
-#define __KERNEL_DS (SUPER_DATA)
-#endif
-#define SUPER_PROGRAM (6)
-#define CPU_SPACE (7)
-
-#ifndef __ASSEMBLY__
-
-typedef struct {
- unsigned long seg;
-} mm_segment_t;
-
-#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-#define USER_DS MAKE_MM_SEG(__USER_DS)
-#define KERNEL_DS MAKE_MM_SEG(__KERNEL_DS)
-
-/*
- * Get/set the SFC/DFC registers for MOVES instructions
- */
-
-static inline mm_segment_t get_fs(void)
-{
- return USER_DS;
-}
-
-static inline mm_segment_t get_ds(void)
-{
- /* return the supervisor data space code */
- return KERNEL_DS;
-}
-
-static inline void set_fs(mm_segment_t val)
-{
-}
-
-#define segment_eq(a,b) ((a).seg == (b).seg)
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _M68K_SEGMENT_H */
diff --git a/arch/m68k/include/asm/setup.h b/arch/m68k/include/asm/setup.h
index 842f86f75ccd..4dfb3952b375 100644
--- a/arch/m68k/include/asm/setup.h
+++ b/arch/m68k/include/asm/setup.h
@@ -1,5 +1,376 @@
-#ifdef __uClinux__
-#include "setup_no.h"
+/*
+** asm/setup.h -- Definition of the Linux/m68k setup information
+**
+** Copyright 1992 by Greg Harp
+**
+** This file is subject to the terms and conditions of the GNU General Public
+** License. See the file COPYING in the main directory of this archive
+** for more details.
+**
+** Created 09/29/92 by Greg Harp
+**
+** 5/2/94 Roman Hodek:
+** Added bi_atari part of the machine dependent union bi_un; for now it
+** contains just a model field to distinguish between TT and Falcon.
+** 26/7/96 Roman Zippel:
+** Renamed to setup.h; added some useful macros to allow gcc some
+** optimizations if possible.
+** 5/10/96 Geert Uytterhoeven:
+** Redesign of the boot information structure; moved boot information
+** structure to bootinfo.h
+*/
+
+#ifndef _M68K_SETUP_H
+#define _M68K_SETUP_H
+
+
+
+ /*
+ * Linux/m68k Architectures
+ */
+
+#define MACH_AMIGA 1
+#define MACH_ATARI 2
+#define MACH_MAC 3
+#define MACH_APOLLO 4
+#define MACH_SUN3 5
+#define MACH_MVME147 6
+#define MACH_MVME16x 7
+#define MACH_BVME6000 8
+#define MACH_HP300 9
+#define MACH_Q40 10
+#define MACH_SUN3X 11
+
+#define COMMAND_LINE_SIZE 256
+
+#ifdef __KERNEL__
+
+#define CL_SIZE COMMAND_LINE_SIZE
+
+#ifndef __ASSEMBLY__
+extern unsigned long m68k_machtype;
+#endif /* !__ASSEMBLY__ */
+
+#if !defined(CONFIG_AMIGA)
+# define MACH_IS_AMIGA (0)
+#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \
+ || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
+ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
+# define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA)
#else
-#include "setup_mm.h"
+# define MACH_AMIGA_ONLY
+# define MACH_IS_AMIGA (1)
+# define MACH_TYPE (MACH_AMIGA)
#endif
+
+#if !defined(CONFIG_ATARI)
+# define MACH_IS_ATARI (0)
+#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \
+ || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
+ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
+# define MACH_IS_ATARI (m68k_machtype == MACH_ATARI)
+#else
+# define MACH_ATARI_ONLY
+# define MACH_IS_ATARI (1)
+# define MACH_TYPE (MACH_ATARI)
+#endif
+
+#if !defined(CONFIG_MAC)
+# define MACH_IS_MAC (0)
+#elif defined(CONFIG_AMIGA) || defined(CONFIG_ATARI) || defined(CONFIG_APOLLO) \
+ || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
+ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
+# define MACH_IS_MAC (m68k_machtype == MACH_MAC)
+#else
+# define MACH_MAC_ONLY
+# define MACH_IS_MAC (1)
+# define MACH_TYPE (MACH_MAC)
+#endif
+
+#if defined(CONFIG_SUN3)
+#define MACH_IS_SUN3 (1)
+#define MACH_SUN3_ONLY (1)
+#define MACH_TYPE (MACH_SUN3)
+#else
+#define MACH_IS_SUN3 (0)
+#endif
+
+#if !defined (CONFIG_APOLLO)
+# define MACH_IS_APOLLO (0)
+#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
+ || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
+ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
+# define MACH_IS_APOLLO (m68k_machtype == MACH_APOLLO)
+#else
+# define MACH_APOLLO_ONLY
+# define MACH_IS_APOLLO (1)
+# define MACH_TYPE (MACH_APOLLO)
+#endif
+
+#if !defined (CONFIG_MVME147)
+# define MACH_IS_MVME147 (0)
+#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
+ || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \
+ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x)
+# define MACH_IS_MVME147 (m68k_machtype == MACH_MVME147)
+#else
+# define MACH_MVME147_ONLY
+# define MACH_IS_MVME147 (1)
+# define MACH_TYPE (MACH_MVME147)
+#endif
+
+#if !defined (CONFIG_MVME16x)
+# define MACH_IS_MVME16x (0)
+#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
+ || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \
+ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
+# define MACH_IS_MVME16x (m68k_machtype == MACH_MVME16x)
+#else
+# define MACH_MVME16x_ONLY
+# define MACH_IS_MVME16x (1)
+# define MACH_TYPE (MACH_MVME16x)
+#endif
+
+#if !defined (CONFIG_BVME6000)
+# define MACH_IS_BVME6000 (0)
+#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
+ || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
+ || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
+# define MACH_IS_BVME6000 (m68k_machtype == MACH_BVME6000)
+#else
+# define MACH_BVME6000_ONLY
+# define MACH_IS_BVME6000 (1)
+# define MACH_TYPE (MACH_BVME6000)
+#endif
+
+#if !defined (CONFIG_HP300)
+# define MACH_IS_HP300 (0)
+#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
+ || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
+ || defined(CONFIG_BVME6000) || defined(CONFIG_Q40) \
+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
+# define MACH_IS_HP300 (m68k_machtype == MACH_HP300)
+#else
+# define MACH_HP300_ONLY
+# define MACH_IS_HP300 (1)
+# define MACH_TYPE (MACH_HP300)
+#endif
+
+#if !defined (CONFIG_Q40)
+# define MACH_IS_Q40 (0)
+#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
+ || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
+ || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \
+ || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
+# define MACH_IS_Q40 (m68k_machtype == MACH_Q40)
+#else
+# define MACH_Q40_ONLY
+# define MACH_IS_Q40 (1)
+# define MACH_TYPE (MACH_Q40)
+#endif
+
+#if !defined (CONFIG_SUN3X)
+# define MACH_IS_SUN3X (0)
+#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
+ || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
+ || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \
+ || defined(CONFIG_Q40) || defined(CONFIG_MVME147)
+# define MACH_IS_SUN3X (m68k_machtype == MACH_SUN3X)
+#else
+# define CONFIG_SUN3X_ONLY
+# define MACH_IS_SUN3X (1)
+# define MACH_TYPE (MACH_SUN3X)
+#endif
+
+#ifndef MACH_TYPE
+# define MACH_TYPE (m68k_machtype)
+#endif
+
+#endif /* __KERNEL__ */
+
+
+ /*
+ * CPU, FPU and MMU types
+ *
+ * Note: we may rely on the following equalities:
+ *
+ * CPU_68020 == MMU_68851
+ * CPU_68030 == MMU_68030
+ * CPU_68040 == FPU_68040 == MMU_68040
+ * CPU_68060 == FPU_68060 == MMU_68060
+ */
+
+#define CPUB_68020 0
+#define CPUB_68030 1
+#define CPUB_68040 2
+#define CPUB_68060 3
+
+#define CPU_68020 (1<<CPUB_68020)
+#define CPU_68030 (1<<CPUB_68030)
+#define CPU_68040 (1<<CPUB_68040)
+#define CPU_68060 (1<<CPUB_68060)
+
+#define FPUB_68881 0
+#define FPUB_68882 1
+#define FPUB_68040 2 /* Internal FPU */
+#define FPUB_68060 3 /* Internal FPU */
+#define FPUB_SUNFPA 4 /* Sun-3 FPA */
+
+#define FPU_68881 (1<<FPUB_68881)
+#define FPU_68882 (1<<FPUB_68882)
+#define FPU_68040 (1<<FPUB_68040)
+#define FPU_68060 (1<<FPUB_68060)
+#define FPU_SUNFPA (1<<FPUB_SUNFPA)
+
+#define MMUB_68851 0
+#define MMUB_68030 1 /* Internal MMU */
+#define MMUB_68040 2 /* Internal MMU */
+#define MMUB_68060 3 /* Internal MMU */
+#define MMUB_APOLLO 4 /* Custom Apollo */
+#define MMUB_SUN3 5 /* Custom Sun-3 */
+
+#define MMU_68851 (1<<MMUB_68851)
+#define MMU_68030 (1<<MMUB_68030)
+#define MMU_68040 (1<<MMUB_68040)
+#define MMU_68060 (1<<MMUB_68060)
+#define MMU_SUN3 (1<<MMUB_SUN3)
+#define MMU_APOLLO (1<<MMUB_APOLLO)
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+extern unsigned long m68k_cputype;
+extern unsigned long m68k_fputype;
+extern unsigned long m68k_mmutype;
+#ifdef CONFIG_VME
+extern unsigned long vme_brdtype;
+#endif
+
+ /*
+ * m68k_is040or060 is != 0 for a '040 or higher;
+ * used numbers are 4 for 68040 and 6 for 68060.
+ */
+
+extern int m68k_is040or060;
+#endif /* !__ASSEMBLY__ */
+
+#if !defined(CONFIG_M68020)
+# define CPU_IS_020 (0)
+# define MMU_IS_851 (0)
+# define MMU_IS_SUN3 (0)
+#elif defined(CONFIG_M68030) || defined(CONFIG_M68040) || defined(CONFIG_M68060)
+# define CPU_IS_020 (m68k_cputype & CPU_68020)
+# define MMU_IS_851 (m68k_mmutype & MMU_68851)
+# define MMU_IS_SUN3 (0) /* Sun3 not supported with other CPU enabled */
+#else
+# define CPU_M68020_ONLY
+# define CPU_IS_020 (1)
+#ifdef MACH_SUN3_ONLY
+# define MMU_IS_SUN3 (1)
+# define MMU_IS_851 (0)
+#else
+# define MMU_IS_SUN3 (0)
+# define MMU_IS_851 (1)
+#endif
+#endif
+
+#if !defined(CONFIG_M68030)
+# define CPU_IS_030 (0)
+# define MMU_IS_030 (0)
+#elif defined(CONFIG_M68020) || defined(CONFIG_M68040) || defined(CONFIG_M68060)
+# define CPU_IS_030 (m68k_cputype & CPU_68030)
+# define MMU_IS_030 (m68k_mmutype & MMU_68030)
+#else
+# define CPU_M68030_ONLY
+# define CPU_IS_030 (1)
+# define MMU_IS_030 (1)
+#endif
+
+#if !defined(CONFIG_M68040)
+# define CPU_IS_040 (0)
+# define MMU_IS_040 (0)
+#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68060)
+# define CPU_IS_040 (m68k_cputype & CPU_68040)
+# define MMU_IS_040 (m68k_mmutype & MMU_68040)
+#else
+# define CPU_M68040_ONLY
+# define CPU_IS_040 (1)
+# define MMU_IS_040 (1)
+#endif
+
+#if !defined(CONFIG_M68060)
+# define CPU_IS_060 (0)
+# define MMU_IS_060 (0)
+#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68040)
+# define CPU_IS_060 (m68k_cputype & CPU_68060)
+# define MMU_IS_060 (m68k_mmutype & MMU_68060)
+#else
+# define CPU_M68060_ONLY
+# define CPU_IS_060 (1)
+# define MMU_IS_060 (1)
+#endif
+
+#if !defined(CONFIG_M68020) && !defined(CONFIG_M68030)
+# define CPU_IS_020_OR_030 (0)
+#else
+# define CPU_M68020_OR_M68030
+# if defined(CONFIG_M68040) || defined(CONFIG_M68060)
+# define CPU_IS_020_OR_030 (!m68k_is040or060)
+# else
+# define CPU_M68020_OR_M68030_ONLY
+# define CPU_IS_020_OR_030 (1)
+# endif
+#endif
+
+#if !defined(CONFIG_M68040) && !defined(CONFIG_M68060)
+# define CPU_IS_040_OR_060 (0)
+#else
+# define CPU_M68040_OR_M68060
+# if defined(CONFIG_M68020) || defined(CONFIG_M68030)
+# define CPU_IS_040_OR_060 (m68k_is040or060)
+# else
+# define CPU_M68040_OR_M68060_ONLY
+# define CPU_IS_040_OR_060 (1)
+# endif
+#endif
+
+#define CPU_TYPE (m68k_cputype)
+
+#ifdef CONFIG_M68KFPU_EMU
+# ifdef CONFIG_M68KFPU_EMU_ONLY
+# define FPU_IS_EMU (1)
+# else
+# define FPU_IS_EMU (!m68k_fputype)
+# endif
+#else
+# define FPU_IS_EMU (0)
+#endif
+
+
+ /*
+ * Miscellaneous
+ */
+
+#define NUM_MEMINFO 4
+
+#ifndef __ASSEMBLY__
+struct mem_info {
+ unsigned long addr; /* physical address of memory chunk */
+ unsigned long size; /* length of memory chunk (in bytes) */
+};
+
+extern int m68k_num_memory; /* # of memory blocks found (and used) */
+extern int m68k_realnum_memory; /* real # of memory blocks found */
+extern struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* _M68K_SETUP_H */
diff --git a/arch/m68k/include/asm/setup_mm.h b/arch/m68k/include/asm/setup_mm.h
deleted file mode 100644
index 4dfb3952b375..000000000000
--- a/arch/m68k/include/asm/setup_mm.h
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
-** asm/setup.h -- Definition of the Linux/m68k setup information
-**
-** Copyright 1992 by Greg Harp
-**
-** This file is subject to the terms and conditions of the GNU General Public
-** License. See the file COPYING in the main directory of this archive
-** for more details.
-**
-** Created 09/29/92 by Greg Harp
-**
-** 5/2/94 Roman Hodek:
-** Added bi_atari part of the machine dependent union bi_un; for now it
-** contains just a model field to distinguish between TT and Falcon.
-** 26/7/96 Roman Zippel:
-** Renamed to setup.h; added some useful macros to allow gcc some
-** optimizations if possible.
-** 5/10/96 Geert Uytterhoeven:
-** Redesign of the boot information structure; moved boot information
-** structure to bootinfo.h
-*/
-
-#ifndef _M68K_SETUP_H
-#define _M68K_SETUP_H
-
-
-
- /*
- * Linux/m68k Architectures
- */
-
-#define MACH_AMIGA 1
-#define MACH_ATARI 2
-#define MACH_MAC 3
-#define MACH_APOLLO 4
-#define MACH_SUN3 5
-#define MACH_MVME147 6
-#define MACH_MVME16x 7
-#define MACH_BVME6000 8
-#define MACH_HP300 9
-#define MACH_Q40 10
-#define MACH_SUN3X 11
-
-#define COMMAND_LINE_SIZE 256
-
-#ifdef __KERNEL__
-
-#define CL_SIZE COMMAND_LINE_SIZE
-
-#ifndef __ASSEMBLY__
-extern unsigned long m68k_machtype;
-#endif /* !__ASSEMBLY__ */
-
-#if !defined(CONFIG_AMIGA)
-# define MACH_IS_AMIGA (0)
-#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \
- || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
-# define MACH_IS_AMIGA (m68k_machtype == MACH_AMIGA)
-#else
-# define MACH_AMIGA_ONLY
-# define MACH_IS_AMIGA (1)
-# define MACH_TYPE (MACH_AMIGA)
-#endif
-
-#if !defined(CONFIG_ATARI)
-# define MACH_IS_ATARI (0)
-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_APOLLO) \
- || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
-# define MACH_IS_ATARI (m68k_machtype == MACH_ATARI)
-#else
-# define MACH_ATARI_ONLY
-# define MACH_IS_ATARI (1)
-# define MACH_TYPE (MACH_ATARI)
-#endif
-
-#if !defined(CONFIG_MAC)
-# define MACH_IS_MAC (0)
-#elif defined(CONFIG_AMIGA) || defined(CONFIG_ATARI) || defined(CONFIG_APOLLO) \
- || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
-# define MACH_IS_MAC (m68k_machtype == MACH_MAC)
-#else
-# define MACH_MAC_ONLY
-# define MACH_IS_MAC (1)
-# define MACH_TYPE (MACH_MAC)
-#endif
-
-#if defined(CONFIG_SUN3)
-#define MACH_IS_SUN3 (1)
-#define MACH_SUN3_ONLY (1)
-#define MACH_TYPE (MACH_SUN3)
-#else
-#define MACH_IS_SUN3 (0)
-#endif
-
-#if !defined (CONFIG_APOLLO)
-# define MACH_IS_APOLLO (0)
-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
- || defined(CONFIG_MVME16x) || defined(CONFIG_BVME6000) \
- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
-# define MACH_IS_APOLLO (m68k_machtype == MACH_APOLLO)
-#else
-# define MACH_APOLLO_ONLY
-# define MACH_IS_APOLLO (1)
-# define MACH_TYPE (MACH_APOLLO)
-#endif
-
-#if !defined (CONFIG_MVME147)
-# define MACH_IS_MVME147 (0)
-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
- || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \
- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME16x)
-# define MACH_IS_MVME147 (m68k_machtype == MACH_MVME147)
-#else
-# define MACH_MVME147_ONLY
-# define MACH_IS_MVME147 (1)
-# define MACH_TYPE (MACH_MVME147)
-#endif
-
-#if !defined (CONFIG_MVME16x)
-# define MACH_IS_MVME16x (0)
-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
- || defined(CONFIG_APOLLO) || defined(CONFIG_BVME6000) \
- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
-# define MACH_IS_MVME16x (m68k_machtype == MACH_MVME16x)
-#else
-# define MACH_MVME16x_ONLY
-# define MACH_IS_MVME16x (1)
-# define MACH_TYPE (MACH_MVME16x)
-#endif
-
-#if !defined (CONFIG_BVME6000)
-# define MACH_IS_BVME6000 (0)
-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
- || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
- || defined(CONFIG_HP300) || defined(CONFIG_Q40) \
- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
-# define MACH_IS_BVME6000 (m68k_machtype == MACH_BVME6000)
-#else
-# define MACH_BVME6000_ONLY
-# define MACH_IS_BVME6000 (1)
-# define MACH_TYPE (MACH_BVME6000)
-#endif
-
-#if !defined (CONFIG_HP300)
-# define MACH_IS_HP300 (0)
-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
- || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
- || defined(CONFIG_BVME6000) || defined(CONFIG_Q40) \
- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
-# define MACH_IS_HP300 (m68k_machtype == MACH_HP300)
-#else
-# define MACH_HP300_ONLY
-# define MACH_IS_HP300 (1)
-# define MACH_TYPE (MACH_HP300)
-#endif
-
-#if !defined (CONFIG_Q40)
-# define MACH_IS_Q40 (0)
-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
- || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
- || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \
- || defined(CONFIG_SUN3X) || defined(CONFIG_MVME147)
-# define MACH_IS_Q40 (m68k_machtype == MACH_Q40)
-#else
-# define MACH_Q40_ONLY
-# define MACH_IS_Q40 (1)
-# define MACH_TYPE (MACH_Q40)
-#endif
-
-#if !defined (CONFIG_SUN3X)
-# define MACH_IS_SUN3X (0)
-#elif defined(CONFIG_AMIGA) || defined(CONFIG_MAC) || defined(CONFIG_ATARI) \
- || defined(CONFIG_APOLLO) || defined(CONFIG_MVME16x) \
- || defined(CONFIG_BVME6000) || defined(CONFIG_HP300) \
- || defined(CONFIG_Q40) || defined(CONFIG_MVME147)
-# define MACH_IS_SUN3X (m68k_machtype == MACH_SUN3X)
-#else
-# define CONFIG_SUN3X_ONLY
-# define MACH_IS_SUN3X (1)
-# define MACH_TYPE (MACH_SUN3X)
-#endif
-
-#ifndef MACH_TYPE
-# define MACH_TYPE (m68k_machtype)
-#endif
-
-#endif /* __KERNEL__ */
-
-
- /*
- * CPU, FPU and MMU types
- *
- * Note: we may rely on the following equalities:
- *
- * CPU_68020 == MMU_68851
- * CPU_68030 == MMU_68030
- * CPU_68040 == FPU_68040 == MMU_68040
- * CPU_68060 == FPU_68060 == MMU_68060
- */
-
-#define CPUB_68020 0
-#define CPUB_68030 1
-#define CPUB_68040 2
-#define CPUB_68060 3
-
-#define CPU_68020 (1<<CPUB_68020)
-#define CPU_68030 (1<<CPUB_68030)
-#define CPU_68040 (1<<CPUB_68040)
-#define CPU_68060 (1<<CPUB_68060)
-
-#define FPUB_68881 0
-#define FPUB_68882 1
-#define FPUB_68040 2 /* Internal FPU */
-#define FPUB_68060 3 /* Internal FPU */
-#define FPUB_SUNFPA 4 /* Sun-3 FPA */
-
-#define FPU_68881 (1<<FPUB_68881)
-#define FPU_68882 (1<<FPUB_68882)
-#define FPU_68040 (1<<FPUB_68040)
-#define FPU_68060 (1<<FPUB_68060)
-#define FPU_SUNFPA (1<<FPUB_SUNFPA)
-
-#define MMUB_68851 0
-#define MMUB_68030 1 /* Internal MMU */
-#define MMUB_68040 2 /* Internal MMU */
-#define MMUB_68060 3 /* Internal MMU */
-#define MMUB_APOLLO 4 /* Custom Apollo */
-#define MMUB_SUN3 5 /* Custom Sun-3 */
-
-#define MMU_68851 (1<<MMUB_68851)
-#define MMU_68030 (1<<MMUB_68030)
-#define MMU_68040 (1<<MMUB_68040)
-#define MMU_68060 (1<<MMUB_68060)
-#define MMU_SUN3 (1<<MMUB_SUN3)
-#define MMU_APOLLO (1<<MMUB_APOLLO)
-
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-extern unsigned long m68k_cputype;
-extern unsigned long m68k_fputype;
-extern unsigned long m68k_mmutype;
-#ifdef CONFIG_VME
-extern unsigned long vme_brdtype;
-#endif
-
- /*
- * m68k_is040or060 is != 0 for a '040 or higher;
- * used numbers are 4 for 68040 and 6 for 68060.
- */
-
-extern int m68k_is040or060;
-#endif /* !__ASSEMBLY__ */
-
-#if !defined(CONFIG_M68020)
-# define CPU_IS_020 (0)
-# define MMU_IS_851 (0)
-# define MMU_IS_SUN3 (0)
-#elif defined(CONFIG_M68030) || defined(CONFIG_M68040) || defined(CONFIG_M68060)
-# define CPU_IS_020 (m68k_cputype & CPU_68020)
-# define MMU_IS_851 (m68k_mmutype & MMU_68851)
-# define MMU_IS_SUN3 (0) /* Sun3 not supported with other CPU enabled */
-#else
-# define CPU_M68020_ONLY
-# define CPU_IS_020 (1)
-#ifdef MACH_SUN3_ONLY
-# define MMU_IS_SUN3 (1)
-# define MMU_IS_851 (0)
-#else
-# define MMU_IS_SUN3 (0)
-# define MMU_IS_851 (1)
-#endif
-#endif
-
-#if !defined(CONFIG_M68030)
-# define CPU_IS_030 (0)
-# define MMU_IS_030 (0)
-#elif defined(CONFIG_M68020) || defined(CONFIG_M68040) || defined(CONFIG_M68060)
-# define CPU_IS_030 (m68k_cputype & CPU_68030)
-# define MMU_IS_030 (m68k_mmutype & MMU_68030)
-#else
-# define CPU_M68030_ONLY
-# define CPU_IS_030 (1)
-# define MMU_IS_030 (1)
-#endif
-
-#if !defined(CONFIG_M68040)
-# define CPU_IS_040 (0)
-# define MMU_IS_040 (0)
-#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68060)
-# define CPU_IS_040 (m68k_cputype & CPU_68040)
-# define MMU_IS_040 (m68k_mmutype & MMU_68040)
-#else
-# define CPU_M68040_ONLY
-# define CPU_IS_040 (1)
-# define MMU_IS_040 (1)
-#endif
-
-#if !defined(CONFIG_M68060)
-# define CPU_IS_060 (0)
-# define MMU_IS_060 (0)
-#elif defined(CONFIG_M68020) || defined(CONFIG_M68030) || defined(CONFIG_M68040)
-# define CPU_IS_060 (m68k_cputype & CPU_68060)
-# define MMU_IS_060 (m68k_mmutype & MMU_68060)
-#else
-# define CPU_M68060_ONLY
-# define CPU_IS_060 (1)
-# define MMU_IS_060 (1)
-#endif
-
-#if !defined(CONFIG_M68020) && !defined(CONFIG_M68030)
-# define CPU_IS_020_OR_030 (0)
-#else
-# define CPU_M68020_OR_M68030
-# if defined(CONFIG_M68040) || defined(CONFIG_M68060)
-# define CPU_IS_020_OR_030 (!m68k_is040or060)
-# else
-# define CPU_M68020_OR_M68030_ONLY
-# define CPU_IS_020_OR_030 (1)
-# endif
-#endif
-
-#if !defined(CONFIG_M68040) && !defined(CONFIG_M68060)
-# define CPU_IS_040_OR_060 (0)
-#else
-# define CPU_M68040_OR_M68060
-# if defined(CONFIG_M68020) || defined(CONFIG_M68030)
-# define CPU_IS_040_OR_060 (m68k_is040or060)
-# else
-# define CPU_M68040_OR_M68060_ONLY
-# define CPU_IS_040_OR_060 (1)
-# endif
-#endif
-
-#define CPU_TYPE (m68k_cputype)
-
-#ifdef CONFIG_M68KFPU_EMU
-# ifdef CONFIG_M68KFPU_EMU_ONLY
-# define FPU_IS_EMU (1)
-# else
-# define FPU_IS_EMU (!m68k_fputype)
-# endif
-#else
-# define FPU_IS_EMU (0)
-#endif
-
-
- /*
- * Miscellaneous
- */
-
-#define NUM_MEMINFO 4
-
-#ifndef __ASSEMBLY__
-struct mem_info {
- unsigned long addr; /* physical address of memory chunk */
- unsigned long size; /* length of memory chunk (in bytes) */
-};
-
-extern int m68k_num_memory; /* # of memory blocks found (and used) */
-extern int m68k_realnum_memory; /* real # of memory blocks found */
-extern struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */
-#endif
-
-#endif /* __KERNEL__ */
-
-#endif /* _M68K_SETUP_H */
diff --git a/arch/m68k/include/asm/setup_no.h b/arch/m68k/include/asm/setup_no.h
deleted file mode 100644
index 45d286ce9398..000000000000
--- a/arch/m68k/include/asm/setup_no.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifdef __KERNEL__
-
-#include <asm/setup_mm.h>
-
-/* We have a bigger command line buffer. */
-#undef COMMAND_LINE_SIZE
-
-#endif /* __KERNEL__ */
-
-#define COMMAND_LINE_SIZE 512
diff --git a/arch/m68k/include/asm/sigcontext.h b/arch/m68k/include/asm/sigcontext.h
index bff6d40345a9..523db2a51cf3 100644
--- a/arch/m68k/include/asm/sigcontext.h
+++ b/arch/m68k/include/asm/sigcontext.h
@@ -1,5 +1,24 @@
+#ifndef _ASM_M68k_SIGCONTEXT_H
+#define _ASM_M68k_SIGCONTEXT_H
+
+struct sigcontext {
+ unsigned long sc_mask; /* old sigmask */
+ unsigned long sc_usp; /* old user stack pointer */
+ unsigned long sc_d0;
+ unsigned long sc_d1;
+ unsigned long sc_a0;
+ unsigned long sc_a1;
#ifdef __uClinux__
-#include "sigcontext_no.h"
-#else
-#include "sigcontext_mm.h"
+ unsigned long sc_a5;
+#endif
+ unsigned short sc_sr;
+ unsigned long sc_pc;
+ unsigned short sc_formatvec;
+#ifndef __uClinux__
+ unsigned long sc_fpregs[2*3]; /* room for two fp registers */
+ unsigned long sc_fpcntl[3];
+ unsigned char sc_fpstate[216];
+#endif
+};
+
#endif
diff --git a/arch/m68k/include/asm/sigcontext_mm.h b/arch/m68k/include/asm/sigcontext_mm.h
deleted file mode 100644
index 64fbe34cf26f..000000000000
--- a/arch/m68k/include/asm/sigcontext_mm.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _ASM_M68k_SIGCONTEXT_H
-#define _ASM_M68k_SIGCONTEXT_H
-
-struct sigcontext {
- unsigned long sc_mask; /* old sigmask */
- unsigned long sc_usp; /* old user stack pointer */
- unsigned long sc_d0;
- unsigned long sc_d1;
- unsigned long sc_a0;
- unsigned long sc_a1;
- unsigned short sc_sr;
- unsigned long sc_pc;
- unsigned short sc_formatvec;
- unsigned long sc_fpregs[2*3]; /* room for two fp registers */
- unsigned long sc_fpcntl[3];
- unsigned char sc_fpstate[216];
-};
-
-#endif
diff --git a/arch/m68k/include/asm/sigcontext_no.h b/arch/m68k/include/asm/sigcontext_no.h
deleted file mode 100644
index 36c293fc133d..000000000000
--- a/arch/m68k/include/asm/sigcontext_no.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _ASM_M68KNOMMU_SIGCONTEXT_H
-#define _ASM_M68KNOMMU_SIGCONTEXT_H
-
-struct sigcontext {
- unsigned long sc_mask; /* old sigmask */
- unsigned long sc_usp; /* old user stack pointer */
- unsigned long sc_d0;
- unsigned long sc_d1;
- unsigned long sc_a0;
- unsigned long sc_a1;
- unsigned long sc_a5;
- unsigned short sc_sr;
- unsigned long sc_pc;
- unsigned short sc_formatvec;
-};
-
-#endif
diff --git a/arch/m68k/include/asm/siginfo.h b/arch/m68k/include/asm/siginfo.h
index 61219d7affc8..ca7dde8fd223 100644
--- a/arch/m68k/include/asm/siginfo.h
+++ b/arch/m68k/include/asm/siginfo.h
@@ -1,5 +1,97 @@
-#ifdef __uClinux__
-#include "siginfo_no.h"
+#ifndef _M68K_SIGINFO_H
+#define _M68K_SIGINFO_H
+
+#ifndef __uClinux__
+#define HAVE_ARCH_SIGINFO_T
+#define HAVE_ARCH_COPY_SIGINFO
+#endif
+
+#include <asm-generic/siginfo.h>
+
+#ifndef __uClinux__
+
+typedef struct siginfo {
+ int si_signo;
+ int si_errno;
+ int si_code;
+
+ union {
+ int _pad[SI_PAD_SIZE];
+
+ /* kill() */
+ struct {
+ __kernel_pid_t _pid; /* sender's pid */
+ __kernel_uid_t _uid; /* backwards compatibility */
+ __kernel_uid32_t _uid32; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
+ sigval_t _sigval; /* same as below */
+ int _sys_private; /* not to be passed to user */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ __kernel_pid_t _pid; /* sender's pid */
+ __kernel_uid_t _uid; /* backwards compatibility */
+ sigval_t _sigval;
+ __kernel_uid32_t _uid32; /* sender's uid */
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ __kernel_pid_t _pid; /* which child */
+ __kernel_uid_t _uid; /* backwards compatibility */
+ int _status; /* exit code */
+ clock_t _utime;
+ clock_t _stime;
+ __kernel_uid32_t _uid32; /* sender's uid */
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ void *_addr; /* faulting insn/memory ref. */
+ } _sigfault;
+
+ /* SIGPOLL */
+ struct {
+ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+} siginfo_t;
+
+#define UID16_SIGINFO_COMPAT_NEEDED
+
+/*
+ * How these fields are to be accessed.
+ */
+#undef si_uid
+#ifdef __KERNEL__
+#define si_uid _sifields._kill._uid32
+#define si_uid16 _sifields._kill._uid
#else
-#include "siginfo_mm.h"
+#define si_uid _sifields._kill._uid
+#endif
+
+#ifdef __KERNEL__
+
+#include <linux/string.h>
+
+static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
+{
+ if (from->si_code < 0)
+ memcpy(to, from, sizeof(*to));
+ else
+ /* _sigchld is currently the largest know union member */
+ memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
+}
+
+#endif /* __KERNEL__ */
+#endif /* !__uClinux__ */
+
#endif
diff --git a/arch/m68k/include/asm/siginfo_mm.h b/arch/m68k/include/asm/siginfo_mm.h
deleted file mode 100644
index 05a8d6d90b58..000000000000
--- a/arch/m68k/include/asm/siginfo_mm.h
+++ /dev/null
@@ -1,92 +0,0 @@
-#ifndef _M68K_SIGINFO_H
-#define _M68K_SIGINFO_H
-
-#define HAVE_ARCH_SIGINFO_T
-#define HAVE_ARCH_COPY_SIGINFO
-
-#include <asm-generic/siginfo.h>
-
-typedef struct siginfo {
- int si_signo;
- int si_errno;
- int si_code;
-
- union {
- int _pad[SI_PAD_SIZE];
-
- /* kill() */
- struct {
- __kernel_pid_t _pid; /* sender's pid */
- __kernel_uid_t _uid; /* backwards compatibility */
- __kernel_uid32_t _uid32; /* sender's uid */
- } _kill;
-
- /* POSIX.1b timers */
- struct {
- timer_t _tid; /* timer id */
- int _overrun; /* overrun count */
- char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
- sigval_t _sigval; /* same as below */
- int _sys_private; /* not to be passed to user */
- } _timer;
-
- /* POSIX.1b signals */
- struct {
- __kernel_pid_t _pid; /* sender's pid */
- __kernel_uid_t _uid; /* backwards compatibility */
- sigval_t _sigval;
- __kernel_uid32_t _uid32; /* sender's uid */
- } _rt;
-
- /* SIGCHLD */
- struct {
- __kernel_pid_t _pid; /* which child */
- __kernel_uid_t _uid; /* backwards compatibility */
- int _status; /* exit code */
- clock_t _utime;
- clock_t _stime;
- __kernel_uid32_t _uid32; /* sender's uid */
- } _sigchld;
-
- /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
- struct {
- void *_addr; /* faulting insn/memory ref. */
- } _sigfault;
-
- /* SIGPOLL */
- struct {
- int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
- int _fd;
- } _sigpoll;
- } _sifields;
-} siginfo_t;
-
-#define UID16_SIGINFO_COMPAT_NEEDED
-
-/*
- * How these fields are to be accessed.
- */
-#undef si_uid
-#ifdef __KERNEL__
-#define si_uid _sifields._kill._uid32
-#define si_uid16 _sifields._kill._uid
-#else
-#define si_uid _sifields._kill._uid
-#endif
-
-#ifdef __KERNEL__
-
-#include <linux/string.h>
-
-static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
-{
- if (from->si_code < 0)
- memcpy(to, from, sizeof(*to));
- else
- /* _sigchld is currently the largest know union member */
- memcpy(to, from, 3*sizeof(int) + sizeof(from->_sifields._sigchld));
-}
-
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/arch/m68k/include/asm/siginfo_no.h b/arch/m68k/include/asm/siginfo_no.h
deleted file mode 100644
index b18e5f4064ae..000000000000
--- a/arch/m68k/include/asm/siginfo_no.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68KNOMMU_SIGINFO_H
-#define _M68KNOMMU_SIGINFO_H
-
-#include <asm-generic/siginfo.h>
-
-#endif
diff --git a/arch/m68k/include/asm/signal.h b/arch/m68k/include/asm/signal.h
index 3c19988bd93c..08788fdefde0 100644
--- a/arch/m68k/include/asm/signal.h
+++ b/arch/m68k/include/asm/signal.h
@@ -1,5 +1,213 @@
-#ifdef __uClinux__
-#include "signal_no.h"
+#ifndef _M68K_SIGNAL_H
+#define _M68K_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems. */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+ is taken to make libc match. */
+
+#define _NSIG 64
+#define _NSIG_BPW 32
+#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t; /* at least 32 bits */
+
+typedef struct {
+ unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
#else
-#include "signal_mm.h"
-#endif
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+#define NSIG 32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+/*
+#define SIGLOST 29
+*/
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP 0x00000001
+#define SA_NOCLDWAIT 0x00000002
+#define SA_SIGINFO 0x00000004
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#include <asm-generic/signal.h>
+
+#ifdef __KERNEL__
+struct old_sigaction {
+ __sighandler_t sa_handler;
+ old_sigset_t sa_mask;
+ unsigned long sa_flags;
+ __sigrestore_t sa_restorer;
+};
+
+struct sigaction {
+ __sighandler_t sa_handler;
+ unsigned long sa_flags;
+ __sigrestore_t sa_restorer;
+ sigset_t sa_mask; /* mask last for extensibility */
+};
+
+struct k_sigaction {
+ struct sigaction sa;
+};
+#else
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+struct sigaction {
+ union {
+ __sighandler_t _sa_handler;
+ void (*_sa_sigaction)(int, struct siginfo *, void *);
+ } _u;
+ sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+};
+
+#define sa_handler _u._sa_handler
+#define sa_sigaction _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+ void __user *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+
+#ifndef __uClinux__
+#define __HAVE_ARCH_SIG_BITOPS
+
+static inline void sigaddset(sigset_t *set, int _sig)
+{
+ asm ("bfset %0{%1,#1}"
+ : "+od" (*set)
+ : "id" ((_sig - 1) ^ 31)
+ : "cc");
+}
+
+static inline void sigdelset(sigset_t *set, int _sig)
+{
+ asm ("bfclr %0{%1,#1}"
+ : "+od" (*set)
+ : "id" ((_sig - 1) ^ 31)
+ : "cc");
+}
+
+static inline int __const_sigismember(sigset_t *set, int _sig)
+{
+ unsigned long sig = _sig - 1;
+ return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW));
+}
+
+static inline int __gen_sigismember(sigset_t *set, int _sig)
+{
+ int ret;
+ asm ("bfextu %1{%2,#1},%0"
+ : "=d" (ret)
+ : "od" (*set), "id" ((_sig-1) ^ 31)
+ : "cc");
+ return ret;
+}
+
+#define sigismember(set,sig) \
+ (__builtin_constant_p(sig) ? \
+ __const_sigismember(set,sig) : \
+ __gen_sigismember(set,sig))
+
+static inline int sigfindinword(unsigned long word)
+{
+ asm ("bfffo %1{#0,#0},%0"
+ : "=d" (word)
+ : "d" (word & -word)
+ : "cc");
+ return word ^ 31;
+}
+
+struct pt_regs;
+extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
+
+#else
+
+#undef __HAVE_ARCH_SIG_BITOPS
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#endif /* __uClinux__ */
+#endif /* __KERNEL__ */
+
+#endif /* _M68K_SIGNAL_H */
diff --git a/arch/m68k/include/asm/signal_mm.h b/arch/m68k/include/asm/signal_mm.h
deleted file mode 100644
index 3db8a81942f1..000000000000
--- a/arch/m68k/include/asm/signal_mm.h
+++ /dev/null
@@ -1,206 +0,0 @@
-#ifndef _M68K_SIGNAL_H
-#define _M68K_SIGNAL_H
-
-#include <linux/types.h>
-
-/* Avoid too many header ordering problems. */
-struct siginfo;
-
-#ifdef __KERNEL__
-/* Most things should be clean enough to redefine this at will, if care
- is taken to make libc match. */
-
-#define _NSIG 64
-#define _NSIG_BPW 32
-#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
-
-typedef unsigned long old_sigset_t; /* at least 32 bits */
-
-typedef struct {
- unsigned long sig[_NSIG_WORDS];
-} sigset_t;
-
-#else
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-#define NSIG 32
-typedef unsigned long sigset_t;
-
-#endif /* __KERNEL__ */
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP 0x00000001
-#define SA_NOCLDWAIT 0x00000002
-#define SA_SIGINFO 0x00000004
-#define SA_ONSTACK 0x08000000
-#define SA_RESTART 0x10000000
-#define SA_NODEFER 0x40000000
-#define SA_RESETHAND 0x80000000
-
-#define SA_NOMASK SA_NODEFER
-#define SA_ONESHOT SA_RESETHAND
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-#define MINSIGSTKSZ 2048
-#define SIGSTKSZ 8192
-
-#include <asm-generic/signal.h>
-
-#ifdef __KERNEL__
-struct old_sigaction {
- __sighandler_t sa_handler;
- old_sigset_t sa_mask;
- unsigned long sa_flags;
- __sigrestore_t sa_restorer;
-};
-
-struct sigaction {
- __sighandler_t sa_handler;
- unsigned long sa_flags;
- __sigrestore_t sa_restorer;
- sigset_t sa_mask; /* mask last for extensibility */
-};
-
-struct k_sigaction {
- struct sigaction sa;
-};
-#else
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-struct sigaction {
- union {
- __sighandler_t _sa_handler;
- void (*_sa_sigaction)(int, struct siginfo *, void *);
- } _u;
- sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
-};
-
-#define sa_handler _u._sa_handler
-#define sa_sigaction _u._sa_sigaction
-
-#endif /* __KERNEL__ */
-
-typedef struct sigaltstack {
- void __user *ss_sp;
- int ss_flags;
- size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
-#include <asm/sigcontext.h>
-
-#define __HAVE_ARCH_SIG_BITOPS
-
-static inline void sigaddset(sigset_t *set, int _sig)
-{
- asm ("bfset %0{%1,#1}"
- : "+od" (*set)
- : "id" ((_sig - 1) ^ 31)
- : "cc");
-}
-
-static inline void sigdelset(sigset_t *set, int _sig)
-{
- asm ("bfclr %0{%1,#1}"
- : "+od" (*set)
- : "id" ((_sig - 1) ^ 31)
- : "cc");
-}
-
-static inline int __const_sigismember(sigset_t *set, int _sig)
-{
- unsigned long sig = _sig - 1;
- return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW));
-}
-
-static inline int __gen_sigismember(sigset_t *set, int _sig)
-{
- int ret;
- asm ("bfextu %1{%2,#1},%0"
- : "=d" (ret)
- : "od" (*set), "id" ((_sig-1) ^ 31)
- : "cc");
- return ret;
-}
-
-#define sigismember(set,sig) \
- (__builtin_constant_p(sig) ? \
- __const_sigismember(set,sig) : \
- __gen_sigismember(set,sig))
-
-static inline int sigfindinword(unsigned long word)
-{
- asm ("bfffo %1{#0,#0},%0"
- : "=d" (word)
- : "d" (word & -word)
- : "cc");
- return word ^ 31;
-}
-
-struct pt_regs;
-extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
-
-#endif /* __KERNEL__ */
-
-#endif /* _M68K_SIGNAL_H */
diff --git a/arch/m68k/include/asm/signal_no.h b/arch/m68k/include/asm/signal_no.h
deleted file mode 100644
index 216c08be54a0..000000000000
--- a/arch/m68k/include/asm/signal_no.h
+++ /dev/null
@@ -1,159 +0,0 @@
-#ifndef _M68KNOMMU_SIGNAL_H
-#define _M68KNOMMU_SIGNAL_H
-
-#include <linux/types.h>
-
-/* Avoid too many header ordering problems. */
-struct siginfo;
-
-#ifdef __KERNEL__
-/* Most things should be clean enough to redefine this at will, if care
- is taken to make libc match. */
-
-#define _NSIG 64
-#define _NSIG_BPW 32
-#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
-
-typedef unsigned long old_sigset_t; /* at least 32 bits */
-
-typedef struct {
- unsigned long sig[_NSIG_WORDS];
-} sigset_t;
-
-#else
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-#define NSIG 32
-typedef unsigned long sigset_t;
-
-#endif /* __KERNEL__ */
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGSYS 31
-#define SIGUNUSED 31
-
-/* These should not be considered constants from userland. */
-#define SIGRTMIN 32
-#define SIGRTMAX _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP 0x00000001
-#define SA_NOCLDWAIT 0x00000002
-#define SA_SIGINFO 0x00000004
-#define SA_ONSTACK 0x08000000
-#define SA_RESTART 0x10000000
-#define SA_NODEFER 0x40000000
-#define SA_RESETHAND 0x80000000
-
-#define SA_NOMASK SA_NODEFER
-#define SA_ONESHOT SA_RESETHAND
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-
-#define MINSIGSTKSZ 2048
-#define SIGSTKSZ 8192
-
-#include <asm-generic/signal.h>
-
-#ifdef __KERNEL__
-struct old_sigaction {
- __sighandler_t sa_handler;
- old_sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
-};
-
-struct sigaction {
- __sighandler_t sa_handler;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
- sigset_t sa_mask; /* mask last for extensibility */
-};
-
-struct k_sigaction {
- struct sigaction sa;
-};
-#else
-/* Here we must cater to libcs that poke about in kernel headers. */
-
-struct sigaction {
- union {
- __sighandler_t _sa_handler;
- void (*_sa_sigaction)(int, struct siginfo *, void *);
- } _u;
- sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
-};
-
-#define sa_handler _u._sa_handler
-#define sa_sigaction _u._sa_sigaction
-
-#endif /* __KERNEL__ */
-
-typedef struct sigaltstack {
- void *ss_sp;
- int ss_flags;
- size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
-
-#include <asm/sigcontext.h>
-#undef __HAVE_ARCH_SIG_BITOPS
-
-#define ptrace_signal_deliver(regs, cookie) do { } while (0)
-
-#endif /* __KERNEL__ */
-
-#endif /* _M68KNOMMU_SIGNAL_H */
diff --git a/arch/m68k/include/asm/socket.h b/arch/m68k/include/asm/socket.h
index dbc64e92c41a..ca87f938b03f 100644
--- a/arch/m68k/include/asm/socket.h
+++ b/arch/m68k/include/asm/socket.h
@@ -54,4 +54,7 @@
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
#endif /* _ASM_SOCKET_H */
diff --git a/arch/m68k/include/asm/swab.h b/arch/m68k/include/asm/swab.h
index 7d7dde1c73ec..9e3054ea59e9 100644
--- a/arch/m68k/include/asm/swab.h
+++ b/arch/m68k/include/asm/swab.h
@@ -1,5 +1,27 @@
-#ifdef __uClinux__
-#include "swab_no.h"
-#else
-#include "swab_mm.h"
+#ifndef _M68K_SWAB_H
+#define _M68K_SWAB_H
+
+#include <asm/types.h>
+#include <linux/compiler.h>
+
+#define __SWAB_64_THRU_32__
+
+#if defined (__mcfisaaplus__) || defined (__mcfisac__)
+static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
+{
+ __asm__("byterev %0" : "=d" (val) : "0" (val));
+ return val;
+}
+
+#define __arch_swab32 __arch_swab32
+#elif !defined(__uClinux__)
+
+static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
+{
+ __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val));
+ return val;
+}
+#define __arch_swab32 __arch_swab32
#endif
+
+#endif /* _M68K_SWAB_H */
diff --git a/arch/m68k/include/asm/swab_mm.h b/arch/m68k/include/asm/swab_mm.h
deleted file mode 100644
index 7221e3066825..000000000000
--- a/arch/m68k/include/asm/swab_mm.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _M68K_SWAB_H
-#define _M68K_SWAB_H
-
-#include <asm/types.h>
-#include <linux/compiler.h>
-
-#define __SWAB_64_THRU_32__
-
-static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
-{
- __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val));
- return val;
-}
-#define __arch_swab32 __arch_swab32
-
-#endif /* _M68K_SWAB_H */
diff --git a/arch/m68k/include/asm/swab_no.h b/arch/m68k/include/asm/swab_no.h
deleted file mode 100644
index e582257db300..000000000000
--- a/arch/m68k/include/asm/swab_no.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _M68KNOMMU_SWAB_H
-#define _M68KNOMMU_SWAB_H
-
-#include <linux/types.h>
-
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
-# define __SWAB_64_THRU_32__
-#endif
-
-#if defined (__mcfisaaplus__) || defined (__mcfisac__)
-static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
-{
- asm(
- "byterev %0"
- : "=d" (val)
- : "0" (val)
- );
- return val;
-}
-
-#define __arch_swab32 __arch_swab32
-#endif
-
-#endif /* _M68KNOMMU_SWAB_H */
diff --git a/arch/m68k/include/asm/timex.h b/arch/m68k/include/asm/timex.h
index 719762980578..b87f2f278f67 100644
--- a/arch/m68k/include/asm/timex.h
+++ b/arch/m68k/include/asm/timex.h
@@ -1,5 +1,18 @@
-#ifdef __uClinux__
-#include "timex_no.h"
-#else
-#include "timex_mm.h"
+/*
+ * linux/include/asm-m68k/timex.h
+ *
+ * m68k architecture timex specifications
+ */
+#ifndef _ASMm68k_TIMEX_H
+#define _ASMm68k_TIMEX_H
+
+#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+ return 0;
+}
+
#endif
diff --git a/arch/m68k/include/asm/timex_mm.h b/arch/m68k/include/asm/timex_mm.h
deleted file mode 100644
index b87f2f278f67..000000000000
--- a/arch/m68k/include/asm/timex_mm.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * linux/include/asm-m68k/timex.h
- *
- * m68k architecture timex specifications
- */
-#ifndef _ASMm68k_TIMEX_H
-#define _ASMm68k_TIMEX_H
-
-#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
-
-typedef unsigned long cycles_t;
-
-static inline cycles_t get_cycles(void)
-{
- return 0;
-}
-
-#endif
diff --git a/arch/m68k/include/asm/timex_no.h b/arch/m68k/include/asm/timex_no.h
deleted file mode 100644
index 109050f3fe91..000000000000
--- a/arch/m68k/include/asm/timex_no.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/include/asm-m68knommu/timex.h
- *
- * m68knommu architecture timex specifications
- */
-#ifndef _ASM_M68KNOMMU_TIMEX_H
-#define _ASM_M68KNOMMU_TIMEX_H
-
-#ifdef CONFIG_COLDFIRE
-#include <asm/coldfire.h>
-#define CLOCK_TICK_RATE MCF_CLK
-#else
-#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
-#endif
-
-typedef unsigned long cycles_t;
-
-static inline cycles_t get_cycles(void)
-{
- return 0;
-}
-
-#endif
diff --git a/arch/m68k/include/asm/tlbflush.h b/arch/m68k/include/asm/tlbflush.h
index b6f93b30951e..a6b4ed4fc90f 100644
--- a/arch/m68k/include/asm/tlbflush.h
+++ b/arch/m68k/include/asm/tlbflush.h
@@ -1,5 +1,267 @@
-#ifdef __uClinux__
-#include "tlbflush_no.h"
+#ifndef _M68K_TLBFLUSH_H
+#define _M68K_TLBFLUSH_H
+
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+
+#include <asm/current.h>
+
+static inline void flush_tlb_kernel_page(void *addr)
+{
+ if (CPU_IS_040_OR_060) {
+ mm_segment_t old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflush (%0)\n\t"
+ ".chip 68k"
+ : : "a" (addr));
+ set_fs(old_fs);
+ } else if (CPU_IS_020_OR_030)
+ __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
+}
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+ if (CPU_IS_040_OR_060)
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflushan\n\t"
+ ".chip 68k");
+ else if (CPU_IS_020_OR_030)
+ __asm__ __volatile__("pflush #0,#4");
+}
+
+static inline void __flush_tlb040_one(unsigned long addr)
+{
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflush (%0)\n\t"
+ ".chip 68k"
+ : : "a" (addr));
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+ if (CPU_IS_040_OR_060)
+ __flush_tlb040_one(addr);
+ else if (CPU_IS_020_OR_030)
+ __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+ if (CPU_IS_040_OR_060)
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflusha\n\t"
+ ".chip 68k");
+ else if (CPU_IS_020_OR_030)
+ __asm__ __volatile__("pflusha");
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+ if (mm == current->active_mm)
+ __flush_tlb();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+ if (vma->vm_mm == current->active_mm) {
+ mm_segment_t old_fs = get_fs();
+ set_fs(USER_DS);
+ __flush_tlb_one(addr);
+ set_fs(old_fs);
+ }
+}
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ if (vma->vm_mm == current->active_mm)
+ __flush_tlb();
+}
+
+static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+ flush_tlb_all();
+}
+
#else
-#include "tlbflush_mm.h"
+
+
+/* Reserved PMEGs. */
+extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
+extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];
+extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];
+extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
+
+/* Flush all userspace mappings one by one... (why no flush command,
+ sun?) */
+static inline void flush_tlb_all(void)
+{
+ unsigned long addr;
+ unsigned char ctx, oldctx;
+
+ oldctx = sun3_get_context();
+ for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {
+ for(ctx = 0; ctx < 8; ctx++) {
+ sun3_put_context(ctx);
+ sun3_put_segmap(addr, SUN3_INVALID_PMEG);
+ }
+ }
+
+ sun3_put_context(oldctx);
+ /* erase all of the userspace pmeg maps, we've clobbered them
+ all anyway */
+ for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) {
+ if(pmeg_alloc[addr] == 1) {
+ pmeg_alloc[addr] = 0;
+ pmeg_ctx[addr] = 0;
+ pmeg_vaddr[addr] = 0;
+ }
+ }
+
+}
+
+/* Clear user TLB entries within the context named in mm */
+static inline void flush_tlb_mm (struct mm_struct *mm)
+{
+ unsigned char oldctx;
+ unsigned char seg;
+ unsigned long i;
+
+ oldctx = sun3_get_context();
+ sun3_put_context(mm->context);
+
+ for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {
+ seg = sun3_get_segmap(i);
+ if(seg == SUN3_INVALID_PMEG)
+ continue;
+
+ sun3_put_segmap(i, SUN3_INVALID_PMEG);
+ pmeg_alloc[seg] = 0;
+ pmeg_ctx[seg] = 0;
+ pmeg_vaddr[seg] = 0;
+ }
+
+ sun3_put_context(oldctx);
+
+}
+
+/* Flush a single TLB page. In this case, we're limited to flushing a
+ single PMEG */
+static inline void flush_tlb_page (struct vm_area_struct *vma,
+ unsigned long addr)
+{
+ unsigned char oldctx;
+ unsigned char i;
+
+ oldctx = sun3_get_context();
+ sun3_put_context(vma->vm_mm->context);
+ addr &= ~SUN3_PMEG_MASK;
+ if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG)
+ {
+ pmeg_alloc[i] = 0;
+ pmeg_ctx[i] = 0;
+ pmeg_vaddr[i] = 0;
+ sun3_put_segmap (addr, SUN3_INVALID_PMEG);
+ }
+ sun3_put_context(oldctx);
+
+}
+/* Flush a range of pages from TLB. */
+
+static inline void flush_tlb_range (struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ struct mm_struct *mm = vma->vm_mm;
+ unsigned char seg, oldctx;
+
+ start &= ~SUN3_PMEG_MASK;
+
+ oldctx = sun3_get_context();
+ sun3_put_context(mm->context);
+
+ while(start < end)
+ {
+ if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG)
+ goto next;
+ if(pmeg_ctx[seg] == mm->context) {
+ pmeg_alloc[seg] = 0;
+ pmeg_ctx[seg] = 0;
+ pmeg_vaddr[seg] = 0;
+ }
+ sun3_put_segmap(start, SUN3_INVALID_PMEG);
+ next:
+ start += SUN3_PMEG_SIZE;
+ }
+}
+
+static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+ flush_tlb_all();
+}
+
+/* Flush kernel page from TLB. */
+static inline void flush_tlb_kernel_page (unsigned long addr)
+{
+ sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
+}
+
#endif
+
+#else /* !CONFIG_MMU */
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+ BUG();
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+ BUG();
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+ BUG();
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+ BUG();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+ BUG();
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+{
+ BUG();
+}
+
+static inline void flush_tlb_kernel_page(unsigned long addr)
+{
+ BUG();
+}
+
+#endif /* CONFIG_MMU */
+
+#endif /* _M68K_TLBFLUSH_H */
diff --git a/arch/m68k/include/asm/tlbflush_mm.h b/arch/m68k/include/asm/tlbflush_mm.h
deleted file mode 100644
index acb6bf21a321..000000000000
--- a/arch/m68k/include/asm/tlbflush_mm.h
+++ /dev/null
@@ -1,219 +0,0 @@
-#ifndef _M68K_TLBFLUSH_H
-#define _M68K_TLBFLUSH_H
-
-
-#ifndef CONFIG_SUN3
-
-#include <asm/current.h>
-
-static inline void flush_tlb_kernel_page(void *addr)
-{
- if (CPU_IS_040_OR_060) {
- mm_segment_t old_fs = get_fs();
- set_fs(KERNEL_DS);
- __asm__ __volatile__(".chip 68040\n\t"
- "pflush (%0)\n\t"
- ".chip 68k"
- : : "a" (addr));
- set_fs(old_fs);
- } else if (CPU_IS_020_OR_030)
- __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
-}
-
-/*
- * flush all user-space atc entries.
- */
-static inline void __flush_tlb(void)
-{
- if (CPU_IS_040_OR_060)
- __asm__ __volatile__(".chip 68040\n\t"
- "pflushan\n\t"
- ".chip 68k");
- else if (CPU_IS_020_OR_030)
- __asm__ __volatile__("pflush #0,#4");
-}
-
-static inline void __flush_tlb040_one(unsigned long addr)
-{
- __asm__ __volatile__(".chip 68040\n\t"
- "pflush (%0)\n\t"
- ".chip 68k"
- : : "a" (addr));
-}
-
-static inline void __flush_tlb_one(unsigned long addr)
-{
- if (CPU_IS_040_OR_060)
- __flush_tlb040_one(addr);
- else if (CPU_IS_020_OR_030)
- __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
-}
-
-#define flush_tlb() __flush_tlb()
-
-/*
- * flush all atc entries (both kernel and user-space entries).
- */
-static inline void flush_tlb_all(void)
-{
- if (CPU_IS_040_OR_060)
- __asm__ __volatile__(".chip 68040\n\t"
- "pflusha\n\t"
- ".chip 68k");
- else if (CPU_IS_020_OR_030)
- __asm__ __volatile__("pflusha");
-}
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
- if (mm == current->active_mm)
- __flush_tlb();
-}
-
-static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
-{
- if (vma->vm_mm == current->active_mm) {
- mm_segment_t old_fs = get_fs();
- set_fs(USER_DS);
- __flush_tlb_one(addr);
- set_fs(old_fs);
- }
-}
-
-static inline void flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- if (vma->vm_mm == current->active_mm)
- __flush_tlb();
-}
-
-static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
- flush_tlb_all();
-}
-
-#else
-
-
-/* Reserved PMEGs. */
-extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
-extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];
-extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];
-extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
-
-/* Flush all userspace mappings one by one... (why no flush command,
- sun?) */
-static inline void flush_tlb_all(void)
-{
- unsigned long addr;
- unsigned char ctx, oldctx;
-
- oldctx = sun3_get_context();
- for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {
- for(ctx = 0; ctx < 8; ctx++) {
- sun3_put_context(ctx);
- sun3_put_segmap(addr, SUN3_INVALID_PMEG);
- }
- }
-
- sun3_put_context(oldctx);
- /* erase all of the userspace pmeg maps, we've clobbered them
- all anyway */
- for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) {
- if(pmeg_alloc[addr] == 1) {
- pmeg_alloc[addr] = 0;
- pmeg_ctx[addr] = 0;
- pmeg_vaddr[addr] = 0;
- }
- }
-
-}
-
-/* Clear user TLB entries within the context named in mm */
-static inline void flush_tlb_mm (struct mm_struct *mm)
-{
- unsigned char oldctx;
- unsigned char seg;
- unsigned long i;
-
- oldctx = sun3_get_context();
- sun3_put_context(mm->context);
-
- for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {
- seg = sun3_get_segmap(i);
- if(seg == SUN3_INVALID_PMEG)
- continue;
-
- sun3_put_segmap(i, SUN3_INVALID_PMEG);
- pmeg_alloc[seg] = 0;
- pmeg_ctx[seg] = 0;
- pmeg_vaddr[seg] = 0;
- }
-
- sun3_put_context(oldctx);
-
-}
-
-/* Flush a single TLB page. In this case, we're limited to flushing a
- single PMEG */
-static inline void flush_tlb_page (struct vm_area_struct *vma,
- unsigned long addr)
-{
- unsigned char oldctx;
- unsigned char i;
-
- oldctx = sun3_get_context();
- sun3_put_context(vma->vm_mm->context);
- addr &= ~SUN3_PMEG_MASK;
- if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG)
- {
- pmeg_alloc[i] = 0;
- pmeg_ctx[i] = 0;
- pmeg_vaddr[i] = 0;
- sun3_put_segmap (addr, SUN3_INVALID_PMEG);
- }
- sun3_put_context(oldctx);
-
-}
-/* Flush a range of pages from TLB. */
-
-static inline void flush_tlb_range (struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- struct mm_struct *mm = vma->vm_mm;
- unsigned char seg, oldctx;
-
- start &= ~SUN3_PMEG_MASK;
-
- oldctx = sun3_get_context();
- sun3_put_context(mm->context);
-
- while(start < end)
- {
- if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG)
- goto next;
- if(pmeg_ctx[seg] == mm->context) {
- pmeg_alloc[seg] = 0;
- pmeg_ctx[seg] = 0;
- pmeg_vaddr[seg] = 0;
- }
- sun3_put_segmap(start, SUN3_INVALID_PMEG);
- next:
- start += SUN3_PMEG_SIZE;
- }
-}
-
-static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
- flush_tlb_all();
-}
-
-/* Flush kernel page from TLB. */
-static inline void flush_tlb_kernel_page (unsigned long addr)
-{
- sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
-}
-
-#endif
-
-#endif /* _M68K_TLBFLUSH_H */
diff --git a/arch/m68k/include/asm/tlbflush_no.h b/arch/m68k/include/asm/tlbflush_no.h
deleted file mode 100644
index a470cfb803eb..000000000000
--- a/arch/m68k/include/asm/tlbflush_no.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _M68KNOMMU_TLBFLUSH_H
-#define _M68KNOMMU_TLBFLUSH_H
-
-/*
- * Copyright (C) 2000 Lineo, David McCullough <davidm@uclinux.org>
- * Copyright (C) 2000-2002, Greg Ungerer <gerg@snapgear.com>
- */
-
-#include <asm/setup.h>
-
-/*
- * flush all user-space atc entries.
- */
-static inline void __flush_tlb(void)
-{
- BUG();
-}
-
-static inline void __flush_tlb_one(unsigned long addr)
-{
- BUG();
-}
-
-#define flush_tlb() __flush_tlb()
-
-/*
- * flush all atc entries (both kernel and user-space entries).
- */
-static inline void flush_tlb_all(void)
-{
- BUG();
-}
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
- BUG();
-}
-
-static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
-{
- BUG();
-}
-
-static inline void flush_tlb_range(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- BUG();
-}
-
-static inline void flush_tlb_kernel_page(unsigned long addr)
-{
- BUG();
-}
-
-#endif /* _M68KNOMMU_TLBFLUSH_H */
diff --git a/arch/m68k/include/asm/ucontext.h b/arch/m68k/include/asm/ucontext.h
index b53cd160c0b3..e4e22669edc0 100644
--- a/arch/m68k/include/asm/ucontext.h
+++ b/arch/m68k/include/asm/ucontext.h
@@ -1,5 +1,30 @@
-#ifdef __uClinux__
-#include "ucontext_no.h"
-#else
-#include "ucontext_mm.h"
+#ifndef _M68K_UCONTEXT_H
+#define _M68K_UCONTEXT_H
+
+typedef int greg_t;
+#define NGREG 18
+typedef greg_t gregset_t[NGREG];
+
+typedef struct fpregset {
+ int f_fpcntl[3];
+ int f_fpregs[8*3];
+} fpregset_t;
+
+struct mcontext {
+ int version;
+ gregset_t gregs;
+ fpregset_t fpregs;
+};
+
+#define MCONTEXT_VERSION 2
+
+struct ucontext {
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ struct mcontext uc_mcontext;
+ unsigned long uc_filler[80];
+ sigset_t uc_sigmask; /* mask last for extensibility */
+};
+
#endif
diff --git a/arch/m68k/include/asm/ucontext_mm.h b/arch/m68k/include/asm/ucontext_mm.h
deleted file mode 100644
index e4e22669edc0..000000000000
--- a/arch/m68k/include/asm/ucontext_mm.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _M68K_UCONTEXT_H
-#define _M68K_UCONTEXT_H
-
-typedef int greg_t;
-#define NGREG 18
-typedef greg_t gregset_t[NGREG];
-
-typedef struct fpregset {
- int f_fpcntl[3];
- int f_fpregs[8*3];
-} fpregset_t;
-
-struct mcontext {
- int version;
- gregset_t gregs;
- fpregset_t fpregs;
-};
-
-#define MCONTEXT_VERSION 2
-
-struct ucontext {
- unsigned long uc_flags;
- struct ucontext *uc_link;
- stack_t uc_stack;
- struct mcontext uc_mcontext;
- unsigned long uc_filler[80];
- sigset_t uc_sigmask; /* mask last for extensibility */
-};
-
-#endif
diff --git a/arch/m68k/include/asm/ucontext_no.h b/arch/m68k/include/asm/ucontext_no.h
deleted file mode 100644
index 713a27f901cd..000000000000
--- a/arch/m68k/include/asm/ucontext_no.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _M68KNOMMU_UCONTEXT_H
-#define _M68KNOMMU_UCONTEXT_H
-
-typedef int greg_t;
-#define NGREG 18
-typedef greg_t gregset_t[NGREG];
-
-typedef struct fpregset {
- int f_pcr;
- int f_psr;
- int f_fpiaddr;
- int f_fpregs[8][3];
-} fpregset_t;
-
-struct mcontext {
- int version;
- gregset_t gregs;
- fpregset_t fpregs;
-};
-
-#define MCONTEXT_VERSION 2
-
-struct ucontext {
- unsigned long uc_flags;
- struct ucontext *uc_link;
- stack_t uc_stack;
- struct mcontext uc_mcontext;
- unsigned long uc_filler[80];
- sigset_t uc_sigmask; /* mask last for extensibility */
-};
-
-#endif
diff --git a/arch/m68k/include/asm/unaligned.h b/arch/m68k/include/asm/unaligned.h
index c640bba3bdf4..019caa740c21 100644
--- a/arch/m68k/include/asm/unaligned.h
+++ b/arch/m68k/include/asm/unaligned.h
@@ -1,5 +1,25 @@
-#ifdef __uClinux__
-#include "unaligned_no.h"
+#ifndef _ASM_M68K_UNALIGNED_H
+#define _ASM_M68K_UNALIGNED_H
+
+
+#ifdef CONFIG_COLDFIRE
+#include <linux/unaligned/be_struct.h>
+#include <linux/unaligned/le_byteshift.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned __get_unaligned_be
+#define put_unaligned __put_unaligned_be
+
#else
-#include "unaligned_mm.h"
+/*
+ * The m68k can do unaligned accesses itself.
+ */
+#include <linux/unaligned/access_ok.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned __get_unaligned_be
+#define put_unaligned __put_unaligned_be
+
#endif
+
+#endif /* _ASM_M68K_UNALIGNED_H */
diff --git a/arch/m68k/include/asm/unaligned_mm.h b/arch/m68k/include/asm/unaligned_mm.h
deleted file mode 100644
index 77698f2dc33c..000000000000
--- a/arch/m68k/include/asm/unaligned_mm.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _ASM_M68K_UNALIGNED_H
-#define _ASM_M68K_UNALIGNED_H
-
-/*
- * The m68k can do unaligned accesses itself.
- */
-#include <linux/unaligned/access_ok.h>
-#include <linux/unaligned/generic.h>
-
-#define get_unaligned __get_unaligned_be
-#define put_unaligned __put_unaligned_be
-
-#endif /* _ASM_M68K_UNALIGNED_H */
diff --git a/arch/m68k/include/asm/unaligned_no.h b/arch/m68k/include/asm/unaligned_no.h
deleted file mode 100644
index eb1ea4cb9a59..000000000000
--- a/arch/m68k/include/asm/unaligned_no.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _ASM_M68KNOMMU_UNALIGNED_H
-#define _ASM_M68KNOMMU_UNALIGNED_H
-
-
-#ifdef CONFIG_COLDFIRE
-#include <linux/unaligned/be_struct.h>
-#include <linux/unaligned/le_byteshift.h>
-#include <linux/unaligned/generic.h>
-
-#define get_unaligned __get_unaligned_be
-#define put_unaligned __put_unaligned_be
-
-#else
-/*
- * The m68k can do unaligned accesses itself.
- */
-#include <linux/unaligned/access_ok.h>
-#include <linux/unaligned/generic.h>
-
-#define get_unaligned __get_unaligned_be
-#define put_unaligned __put_unaligned_be
-
-#endif
-
-#endif /* _ASM_M68KNOMMU_UNALIGNED_H */
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
index df1d9d4cb1fd..3c19027331fa 100644
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -1,5 +1,372 @@
-#ifdef __uClinux__
-#include "unistd_no.h"
-#else
-#include "unistd_mm.h"
-#endif
+#ifndef _ASM_M68K_UNISTD_H_
+#define _ASM_M68K_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_restart_syscall 0
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_waitpid 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_chown 16
+#define __NR_break 17
+#define __NR_oldstat 18
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_oldfstat 28
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_stty 31
+#define __NR_gtty 32
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_ftime 35
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_prof 44
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_lock 53
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_mpx 56
+#define __NR_setpgid 57
+#define __NR_ulimit 58
+#define __NR_oldolduname 59
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sgetmask 68
+#define __NR_ssetmask 69
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_oldlstat 84
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_profil 98
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_ioperm 101
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_olduname 109
+#define __NR_iopl /* 110 */ not supported
+#define __NR_vhangup 111
+#define __NR_idle /* 112 */ Obsolete
+#define __NR_vm86 /* 113 */ not supported
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_cacheflush 123
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+#define __NR__newselect 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+#define __NR_getpagesize 166
+#define __NR_query_module 167
+#define __NR_poll 168
+#define __NR_nfsservctl 169
+#define __NR_setresgid 170
+#define __NR_getresgid 171
+#define __NR_prctl 172
+#define __NR_rt_sigreturn 173
+#define __NR_rt_sigaction 174
+#define __NR_rt_sigprocmask 175
+#define __NR_rt_sigpending 176
+#define __NR_rt_sigtimedwait 177
+#define __NR_rt_sigqueueinfo 178
+#define __NR_rt_sigsuspend 179
+#define __NR_pread64 180
+#define __NR_pwrite64 181
+#define __NR_lchown 182
+#define __NR_getcwd 183
+#define __NR_capget 184
+#define __NR_capset 185
+#define __NR_sigaltstack 186
+#define __NR_sendfile 187
+#define __NR_getpmsg 188 /* some people actually want streams */
+#define __NR_putpmsg 189 /* some people actually want streams */
+#define __NR_vfork 190
+#define __NR_ugetrlimit 191
+#define __NR_mmap2 192
+#define __NR_truncate64 193
+#define __NR_ftruncate64 194
+#define __NR_stat64 195
+#define __NR_lstat64 196
+#define __NR_fstat64 197
+#define __NR_chown32 198
+#define __NR_getuid32 199
+#define __NR_getgid32 200
+#define __NR_geteuid32 201
+#define __NR_getegid32 202
+#define __NR_setreuid32 203
+#define __NR_setregid32 204
+#define __NR_getgroups32 205
+#define __NR_setgroups32 206
+#define __NR_fchown32 207
+#define __NR_setresuid32 208
+#define __NR_getresuid32 209
+#define __NR_setresgid32 210
+#define __NR_getresgid32 211
+#define __NR_lchown32 212
+#define __NR_setuid32 213
+#define __NR_setgid32 214
+#define __NR_setfsuid32 215
+#define __NR_setfsgid32 216
+#define __NR_pivot_root 217
+#define __NR_getdents64 220
+#define __NR_gettid 221
+#define __NR_tkill 222
+#define __NR_setxattr 223
+#define __NR_lsetxattr 224
+#define __NR_fsetxattr 225
+#define __NR_getxattr 226
+#define __NR_lgetxattr 227
+#define __NR_fgetxattr 228
+#define __NR_listxattr 229
+#define __NR_llistxattr 230
+#define __NR_flistxattr 231
+#define __NR_removexattr 232
+#define __NR_lremovexattr 233
+#define __NR_fremovexattr 234
+#define __NR_futex 235
+#define __NR_sendfile64 236
+#define __NR_mincore 237
+#define __NR_madvise 238
+#define __NR_fcntl64 239
+#define __NR_readahead 240
+#define __NR_io_setup 241
+#define __NR_io_destroy 242
+#define __NR_io_getevents 243
+#define __NR_io_submit 244
+#define __NR_io_cancel 245
+#define __NR_fadvise64 246
+#define __NR_exit_group 247
+#define __NR_lookup_dcookie 248
+#define __NR_epoll_create 249
+#define __NR_epoll_ctl 250
+#define __NR_epoll_wait 251
+#define __NR_remap_file_pages 252
+#define __NR_set_tid_address 253
+#define __NR_timer_create 254
+#define __NR_timer_settime 255
+#define __NR_timer_gettime 256
+#define __NR_timer_getoverrun 257
+#define __NR_timer_delete 258
+#define __NR_clock_settime 259
+#define __NR_clock_gettime 260
+#define __NR_clock_getres 261
+#define __NR_clock_nanosleep 262
+#define __NR_statfs64 263
+#define __NR_fstatfs64 264
+#define __NR_tgkill 265
+#define __NR_utimes 266
+#define __NR_fadvise64_64 267
+#define __NR_mbind 268
+#define __NR_get_mempolicy 269
+#define __NR_set_mempolicy 270
+#define __NR_mq_open 271
+#define __NR_mq_unlink 272
+#define __NR_mq_timedsend 273
+#define __NR_mq_timedreceive 274
+#define __NR_mq_notify 275
+#define __NR_mq_getsetattr 276
+#define __NR_waitid 277
+#define __NR_vserver 278
+#define __NR_add_key 279
+#define __NR_request_key 280
+#define __NR_keyctl 281
+#define __NR_ioprio_set 282
+#define __NR_ioprio_get 283
+#define __NR_inotify_init 284
+#define __NR_inotify_add_watch 285
+#define __NR_inotify_rm_watch 286
+#define __NR_migrate_pages 287
+#define __NR_openat 288
+#define __NR_mkdirat 289
+#define __NR_mknodat 290
+#define __NR_fchownat 291
+#define __NR_futimesat 292
+#define __NR_fstatat64 293
+#define __NR_unlinkat 294
+#define __NR_renameat 295
+#define __NR_linkat 296
+#define __NR_symlinkat 297
+#define __NR_readlinkat 298
+#define __NR_fchmodat 299
+#define __NR_faccessat 300
+#define __NR_pselect6 301
+#define __NR_ppoll 302
+#define __NR_unshare 303
+#define __NR_set_robust_list 304
+#define __NR_get_robust_list 305
+#define __NR_splice 306
+#define __NR_sync_file_range 307
+#define __NR_tee 308
+#define __NR_vmsplice 309
+#define __NR_move_pages 310
+#define __NR_sched_setaffinity 311
+#define __NR_sched_getaffinity 312
+#define __NR_kexec_load 313
+#define __NR_getcpu 314
+#define __NR_epoll_pwait 315
+#define __NR_utimensat 316
+#define __NR_signalfd 317
+#define __NR_timerfd_create 318
+#define __NR_eventfd 319
+#define __NR_fallocate 320
+#define __NR_timerfd_settime 321
+#define __NR_timerfd_gettime 322
+#define __NR_signalfd4 323
+#define __NR_eventfd2 324
+#define __NR_epoll_create1 325
+#define __NR_dup3 326
+#define __NR_pipe2 327
+#define __NR_inotify_init1 328
+
+#ifdef __KERNEL__
+
+#define NR_syscalls 329
+
+#define __ARCH_WANT_IPC_PARSE_VERSION
+#define __ARCH_WANT_OLD_READDIR
+#define __ARCH_WANT_OLD_STAT
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_SGETMASK
+#define __ARCH_WANT_SYS_SIGNAL
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_M68K_UNISTD_H_ */
diff --git a/arch/m68k/include/asm/unistd_mm.h b/arch/m68k/include/asm/unistd_mm.h
deleted file mode 100644
index 3c19027331fa..000000000000
--- a/arch/m68k/include/asm/unistd_mm.h
+++ /dev/null
@@ -1,372 +0,0 @@
-#ifndef _ASM_M68K_UNISTD_H_
-#define _ASM_M68K_UNISTD_H_
-
-/*
- * This file contains the system call numbers.
- */
-
-#define __NR_restart_syscall 0
-#define __NR_exit 1
-#define __NR_fork 2
-#define __NR_read 3
-#define __NR_write 4
-#define __NR_open 5
-#define __NR_close 6
-#define __NR_waitpid 7
-#define __NR_creat 8
-#define __NR_link 9
-#define __NR_unlink 10
-#define __NR_execve 11
-#define __NR_chdir 12
-#define __NR_time 13
-#define __NR_mknod 14
-#define __NR_chmod 15
-#define __NR_chown 16
-#define __NR_break 17
-#define __NR_oldstat 18
-#define __NR_lseek 19
-#define __NR_getpid 20
-#define __NR_mount 21
-#define __NR_umount 22
-#define __NR_setuid 23
-#define __NR_getuid 24
-#define __NR_stime 25
-#define __NR_ptrace 26
-#define __NR_alarm 27
-#define __NR_oldfstat 28
-#define __NR_pause 29
-#define __NR_utime 30
-#define __NR_stty 31
-#define __NR_gtty 32
-#define __NR_access 33
-#define __NR_nice 34
-#define __NR_ftime 35
-#define __NR_sync 36
-#define __NR_kill 37
-#define __NR_rename 38
-#define __NR_mkdir 39
-#define __NR_rmdir 40
-#define __NR_dup 41
-#define __NR_pipe 42
-#define __NR_times 43
-#define __NR_prof 44
-#define __NR_brk 45
-#define __NR_setgid 46
-#define __NR_getgid 47
-#define __NR_signal 48
-#define __NR_geteuid 49
-#define __NR_getegid 50
-#define __NR_acct 51
-#define __NR_umount2 52
-#define __NR_lock 53
-#define __NR_ioctl 54
-#define __NR_fcntl 55
-#define __NR_mpx 56
-#define __NR_setpgid 57
-#define __NR_ulimit 58
-#define __NR_oldolduname 59
-#define __NR_umask 60
-#define __NR_chroot 61
-#define __NR_ustat 62
-#define __NR_dup2 63
-#define __NR_getppid 64
-#define __NR_getpgrp 65
-#define __NR_setsid 66
-#define __NR_sigaction 67
-#define __NR_sgetmask 68
-#define __NR_ssetmask 69
-#define __NR_setreuid 70
-#define __NR_setregid 71
-#define __NR_sigsuspend 72
-#define __NR_sigpending 73
-#define __NR_sethostname 74
-#define __NR_setrlimit 75
-#define __NR_getrlimit 76
-#define __NR_getrusage 77
-#define __NR_gettimeofday 78
-#define __NR_settimeofday 79
-#define __NR_getgroups 80
-#define __NR_setgroups 81
-#define __NR_select 82
-#define __NR_symlink 83
-#define __NR_oldlstat 84
-#define __NR_readlink 85
-#define __NR_uselib 86
-#define __NR_swapon 87
-#define __NR_reboot 88
-#define __NR_readdir 89
-#define __NR_mmap 90
-#define __NR_munmap 91
-#define __NR_truncate 92
-#define __NR_ftruncate 93
-#define __NR_fchmod 94
-#define __NR_fchown 95
-#define __NR_getpriority 96
-#define __NR_setpriority 97
-#define __NR_profil 98
-#define __NR_statfs 99
-#define __NR_fstatfs 100
-#define __NR_ioperm 101
-#define __NR_socketcall 102
-#define __NR_syslog 103
-#define __NR_setitimer 104
-#define __NR_getitimer 105
-#define __NR_stat 106
-#define __NR_lstat 107
-#define __NR_fstat 108
-#define __NR_olduname 109
-#define __NR_iopl /* 110 */ not supported
-#define __NR_vhangup 111
-#define __NR_idle /* 112 */ Obsolete
-#define __NR_vm86 /* 113 */ not supported
-#define __NR_wait4 114
-#define __NR_swapoff 115
-#define __NR_sysinfo 116
-#define __NR_ipc 117
-#define __NR_fsync 118
-#define __NR_sigreturn 119
-#define __NR_clone 120
-#define __NR_setdomainname 121
-#define __NR_uname 122
-#define __NR_cacheflush 123
-#define __NR_adjtimex 124
-#define __NR_mprotect 125
-#define __NR_sigprocmask 126
-#define __NR_create_module 127
-#define __NR_init_module 128
-#define __NR_delete_module 129
-#define __NR_get_kernel_syms 130
-#define __NR_quotactl 131
-#define __NR_getpgid 132
-#define __NR_fchdir 133
-#define __NR_bdflush 134
-#define __NR_sysfs 135
-#define __NR_personality 136
-#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
-#define __NR_setfsuid 138
-#define __NR_setfsgid 139
-#define __NR__llseek 140
-#define __NR_getdents 141
-#define __NR__newselect 142
-#define __NR_flock 143
-#define __NR_msync 144
-#define __NR_readv 145
-#define __NR_writev 146
-#define __NR_getsid 147
-#define __NR_fdatasync 148
-#define __NR__sysctl 149
-#define __NR_mlock 150
-#define __NR_munlock 151
-#define __NR_mlockall 152
-#define __NR_munlockall 153
-#define __NR_sched_setparam 154
-#define __NR_sched_getparam 155
-#define __NR_sched_setscheduler 156
-#define __NR_sched_getscheduler 157
-#define __NR_sched_yield 158
-#define __NR_sched_get_priority_max 159
-#define __NR_sched_get_priority_min 160
-#define __NR_sched_rr_get_interval 161
-#define __NR_nanosleep 162
-#define __NR_mremap 163
-#define __NR_setresuid 164
-#define __NR_getresuid 165
-#define __NR_getpagesize 166
-#define __NR_query_module 167
-#define __NR_poll 168
-#define __NR_nfsservctl 169
-#define __NR_setresgid 170
-#define __NR_getresgid 171
-#define __NR_prctl 172
-#define __NR_rt_sigreturn 173
-#define __NR_rt_sigaction 174
-#define __NR_rt_sigprocmask 175
-#define __NR_rt_sigpending 176
-#define __NR_rt_sigtimedwait 177
-#define __NR_rt_sigqueueinfo 178
-#define __NR_rt_sigsuspend 179
-#define __NR_pread64 180
-#define __NR_pwrite64 181
-#define __NR_lchown 182
-#define __NR_getcwd 183
-#define __NR_capget 184
-#define __NR_capset 185
-#define __NR_sigaltstack 186
-#define __NR_sendfile 187
-#define __NR_getpmsg 188 /* some people actually want streams */
-#define __NR_putpmsg 189 /* some people actually want streams */
-#define __NR_vfork 190
-#define __NR_ugetrlimit 191
-#define __NR_mmap2 192
-#define __NR_truncate64 193
-#define __NR_ftruncate64 194
-#define __NR_stat64 195
-#define __NR_lstat64 196
-#define __NR_fstat64 197
-#define __NR_chown32 198
-#define __NR_getuid32 199
-#define __NR_getgid32 200
-#define __NR_geteuid32 201
-#define __NR_getegid32 202
-#define __NR_setreuid32 203
-#define __NR_setregid32 204
-#define __NR_getgroups32 205
-#define __NR_setgroups32 206
-#define __NR_fchown32 207
-#define __NR_setresuid32 208
-#define __NR_getresuid32 209
-#define __NR_setresgid32 210
-#define __NR_getresgid32 211
-#define __NR_lchown32 212
-#define __NR_setuid32 213
-#define __NR_setgid32 214
-#define __NR_setfsuid32 215
-#define __NR_setfsgid32 216
-#define __NR_pivot_root 217
-#define __NR_getdents64 220
-#define __NR_gettid 221
-#define __NR_tkill 222
-#define __NR_setxattr 223
-#define __NR_lsetxattr 224
-#define __NR_fsetxattr 225
-#define __NR_getxattr 226
-#define __NR_lgetxattr 227
-#define __NR_fgetxattr 228
-#define __NR_listxattr 229
-#define __NR_llistxattr 230
-#define __NR_flistxattr 231
-#define __NR_removexattr 232
-#define __NR_lremovexattr 233
-#define __NR_fremovexattr 234
-#define __NR_futex 235
-#define __NR_sendfile64 236
-#define __NR_mincore 237
-#define __NR_madvise 238
-#define __NR_fcntl64 239
-#define __NR_readahead 240
-#define __NR_io_setup 241
-#define __NR_io_destroy 242
-#define __NR_io_getevents 243
-#define __NR_io_submit 244
-#define __NR_io_cancel 245
-#define __NR_fadvise64 246
-#define __NR_exit_group 247
-#define __NR_lookup_dcookie 248
-#define __NR_epoll_create 249
-#define __NR_epoll_ctl 250
-#define __NR_epoll_wait 251
-#define __NR_remap_file_pages 252
-#define __NR_set_tid_address 253
-#define __NR_timer_create 254
-#define __NR_timer_settime 255
-#define __NR_timer_gettime 256
-#define __NR_timer_getoverrun 257
-#define __NR_timer_delete 258
-#define __NR_clock_settime 259
-#define __NR_clock_gettime 260
-#define __NR_clock_getres 261
-#define __NR_clock_nanosleep 262
-#define __NR_statfs64 263
-#define __NR_fstatfs64 264
-#define __NR_tgkill 265
-#define __NR_utimes 266
-#define __NR_fadvise64_64 267
-#define __NR_mbind 268
-#define __NR_get_mempolicy 269
-#define __NR_set_mempolicy 270
-#define __NR_mq_open 271
-#define __NR_mq_unlink 272
-#define __NR_mq_timedsend 273
-#define __NR_mq_timedreceive 274
-#define __NR_mq_notify 275
-#define __NR_mq_getsetattr 276
-#define __NR_waitid 277
-#define __NR_vserver 278
-#define __NR_add_key 279
-#define __NR_request_key 280
-#define __NR_keyctl 281
-#define __NR_ioprio_set 282
-#define __NR_ioprio_get 283
-#define __NR_inotify_init 284
-#define __NR_inotify_add_watch 285
-#define __NR_inotify_rm_watch 286
-#define __NR_migrate_pages 287
-#define __NR_openat 288
-#define __NR_mkdirat 289
-#define __NR_mknodat 290
-#define __NR_fchownat 291
-#define __NR_futimesat 292
-#define __NR_fstatat64 293
-#define __NR_unlinkat 294
-#define __NR_renameat 295
-#define __NR_linkat 296
-#define __NR_symlinkat 297
-#define __NR_readlinkat 298
-#define __NR_fchmodat 299
-#define __NR_faccessat 300
-#define __NR_pselect6 301
-#define __NR_ppoll 302
-#define __NR_unshare 303
-#define __NR_set_robust_list 304
-#define __NR_get_robust_list 305
-#define __NR_splice 306
-#define __NR_sync_file_range 307
-#define __NR_tee 308
-#define __NR_vmsplice 309
-#define __NR_move_pages 310
-#define __NR_sched_setaffinity 311
-#define __NR_sched_getaffinity 312
-#define __NR_kexec_load 313
-#define __NR_getcpu 314
-#define __NR_epoll_pwait 315
-#define __NR_utimensat 316
-#define __NR_signalfd 317
-#define __NR_timerfd_create 318
-#define __NR_eventfd 319
-#define __NR_fallocate 320
-#define __NR_timerfd_settime 321
-#define __NR_timerfd_gettime 322
-#define __NR_signalfd4 323
-#define __NR_eventfd2 324
-#define __NR_epoll_create1 325
-#define __NR_dup3 326
-#define __NR_pipe2 327
-#define __NR_inotify_init1 328
-
-#ifdef __KERNEL__
-
-#define NR_syscalls 329
-
-#define __ARCH_WANT_IPC_PARSE_VERSION
-#define __ARCH_WANT_OLD_READDIR
-#define __ARCH_WANT_OLD_STAT
-#define __ARCH_WANT_STAT64
-#define __ARCH_WANT_SYS_ALARM
-#define __ARCH_WANT_SYS_GETHOSTNAME
-#define __ARCH_WANT_SYS_PAUSE
-#define __ARCH_WANT_SYS_SGETMASK
-#define __ARCH_WANT_SYS_SIGNAL
-#define __ARCH_WANT_SYS_TIME
-#define __ARCH_WANT_SYS_UTIME
-#define __ARCH_WANT_SYS_WAITPID
-#define __ARCH_WANT_SYS_SOCKETCALL
-#define __ARCH_WANT_SYS_FADVISE64
-#define __ARCH_WANT_SYS_GETPGRP
-#define __ARCH_WANT_SYS_LLSEEK
-#define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
-#define __ARCH_WANT_SYS_OLDUMOUNT
-#define __ARCH_WANT_SYS_SIGPENDING
-#define __ARCH_WANT_SYS_SIGPROCMASK
-#define __ARCH_WANT_SYS_RT_SIGACTION
-
-/*
- * "Conditional" syscalls
- *
- * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
- * but it doesn't work on all toolchains, so we just do it by hand
- */
-#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_M68K_UNISTD_H_ */
diff --git a/arch/m68k/include/asm/unistd_no.h b/arch/m68k/include/asm/unistd_no.h
deleted file mode 100644
index b034a2f7b444..000000000000
--- a/arch/m68k/include/asm/unistd_no.h
+++ /dev/null
@@ -1,372 +0,0 @@
-#ifndef _ASM_M68K_UNISTD_H_
-#define _ASM_M68K_UNISTD_H_
-
-/*
- * This file contains the system call numbers.
- */
-
-#define __NR_restart_syscall 0
-#define __NR_exit 1
-#define __NR_fork 2
-#define __NR_read 3
-#define __NR_write 4
-#define __NR_open 5
-#define __NR_close 6
-#define __NR_waitpid 7
-#define __NR_creat 8
-#define __NR_link 9
-#define __NR_unlink 10
-#define __NR_execve 11
-#define __NR_chdir 12
-#define __NR_time 13
-#define __NR_mknod 14
-#define __NR_chmod 15
-#define __NR_chown 16
-#define __NR_break 17
-#define __NR_oldstat 18
-#define __NR_lseek 19
-#define __NR_getpid 20
-#define __NR_mount 21
-#define __NR_umount 22
-#define __NR_setuid 23
-#define __NR_getuid 24
-#define __NR_stime 25
-#define __NR_ptrace 26
-#define __NR_alarm 27
-#define __NR_oldfstat 28
-#define __NR_pause 29
-#define __NR_utime 30
-#define __NR_stty 31
-#define __NR_gtty 32
-#define __NR_access 33
-#define __NR_nice 34
-#define __NR_ftime 35
-#define __NR_sync 36
-#define __NR_kill 37
-#define __NR_rename 38
-#define __NR_mkdir 39
-#define __NR_rmdir 40
-#define __NR_dup 41
-#define __NR_pipe 42
-#define __NR_times 43
-#define __NR_prof 44
-#define __NR_brk 45
-#define __NR_setgid 46
-#define __NR_getgid 47
-#define __NR_signal 48
-#define __NR_geteuid 49
-#define __NR_getegid 50
-#define __NR_acct 51
-#define __NR_umount2 52
-#define __NR_lock 53
-#define __NR_ioctl 54
-#define __NR_fcntl 55
-#define __NR_mpx 56
-#define __NR_setpgid 57
-#define __NR_ulimit 58
-#define __NR_oldolduname 59
-#define __NR_umask 60
-#define __NR_chroot 61
-#define __NR_ustat 62
-#define __NR_dup2 63
-#define __NR_getppid 64
-#define __NR_getpgrp 65
-#define __NR_setsid 66
-#define __NR_sigaction 67
-#define __NR_sgetmask 68
-#define __NR_ssetmask 69
-#define __NR_setreuid 70
-#define __NR_setregid 71
-#define __NR_sigsuspend 72
-#define __NR_sigpending 73
-#define __NR_sethostname 74
-#define __NR_setrlimit 75
-#define __NR_getrlimit 76
-#define __NR_getrusage 77
-#define __NR_gettimeofday 78
-#define __NR_settimeofday 79
-#define __NR_getgroups 80
-#define __NR_setgroups 81
-#define __NR_select 82
-#define __NR_symlink 83
-#define __NR_oldlstat 84
-#define __NR_readlink 85
-#define __NR_uselib 86
-#define __NR_swapon 87
-#define __NR_reboot 88
-#define __NR_readdir 89
-#define __NR_mmap 90
-#define __NR_munmap 91
-#define __NR_truncate 92
-#define __NR_ftruncate 93
-#define __NR_fchmod 94
-#define __NR_fchown 95
-#define __NR_getpriority 96
-#define __NR_setpriority 97
-#define __NR_profil 98
-#define __NR_statfs 99
-#define __NR_fstatfs 100
-#define __NR_ioperm 101
-#define __NR_socketcall 102
-#define __NR_syslog 103
-#define __NR_setitimer 104
-#define __NR_getitimer 105
-#define __NR_stat 106
-#define __NR_lstat 107
-#define __NR_fstat 108
-#define __NR_olduname 109
-#define __NR_iopl /* 110 */ not supported
-#define __NR_vhangup 111
-#define __NR_idle /* 112 */ Obsolete
-#define __NR_vm86 /* 113 */ not supported
-#define __NR_wait4 114
-#define __NR_swapoff 115
-#define __NR_sysinfo 116
-#define __NR_ipc 117
-#define __NR_fsync 118
-#define __NR_sigreturn 119
-#define __NR_clone 120
-#define __NR_setdomainname 121
-#define __NR_uname 122
-#define __NR_cacheflush 123
-#define __NR_adjtimex 124
-#define __NR_mprotect 125
-#define __NR_sigprocmask 126
-#define __NR_create_module 127
-#define __NR_init_module 128
-#define __NR_delete_module 129
-#define __NR_get_kernel_syms 130
-#define __NR_quotactl 131
-#define __NR_getpgid 132
-#define __NR_fchdir 133
-#define __NR_bdflush 134
-#define __NR_sysfs 135
-#define __NR_personality 136
-#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
-#define __NR_setfsuid 138
-#define __NR_setfsgid 139
-#define __NR__llseek 140
-#define __NR_getdents 141
-#define __NR__newselect 142
-#define __NR_flock 143
-#define __NR_msync 144
-#define __NR_readv 145
-#define __NR_writev 146
-#define __NR_getsid 147
-#define __NR_fdatasync 148
-#define __NR__sysctl 149
-#define __NR_mlock 150
-#define __NR_munlock 151
-#define __NR_mlockall 152
-#define __NR_munlockall 153
-#define __NR_sched_setparam 154
-#define __NR_sched_getparam 155
-#define __NR_sched_setscheduler 156
-#define __NR_sched_getscheduler 157
-#define __NR_sched_yield 158
-#define __NR_sched_get_priority_max 159
-#define __NR_sched_get_priority_min 160
-#define __NR_sched_rr_get_interval 161
-#define __NR_nanosleep 162
-#define __NR_mremap 163
-#define __NR_setresuid 164
-#define __NR_getresuid 165
-#define __NR_getpagesize 166
-#define __NR_query_module 167
-#define __NR_poll 168
-#define __NR_nfsservctl 169
-#define __NR_setresgid 170
-#define __NR_getresgid 171
-#define __NR_prctl 172
-#define __NR_rt_sigreturn 173
-#define __NR_rt_sigaction 174
-#define __NR_rt_sigprocmask 175
-#define __NR_rt_sigpending 176
-#define __NR_rt_sigtimedwait 177
-#define __NR_rt_sigqueueinfo 178
-#define __NR_rt_sigsuspend 179
-#define __NR_pread64 180
-#define __NR_pwrite64 181
-#define __NR_lchown 182
-#define __NR_getcwd 183
-#define __NR_capget 184
-#define __NR_capset 185
-#define __NR_sigaltstack 186
-#define __NR_sendfile 187
-#define __NR_getpmsg 188 /* some people actually want streams */
-#define __NR_putpmsg 189 /* some people actually want streams */
-#define __NR_vfork 190
-#define __NR_ugetrlimit 191
-#define __NR_mmap2 192
-#define __NR_truncate64 193
-#define __NR_ftruncate64 194
-#define __NR_stat64 195
-#define __NR_lstat64 196
-#define __NR_fstat64 197
-#define __NR_chown32 198
-#define __NR_getuid32 199
-#define __NR_getgid32 200
-#define __NR_geteuid32 201
-#define __NR_getegid32 202
-#define __NR_setreuid32 203
-#define __NR_setregid32 204
-#define __NR_getgroups32 205
-#define __NR_setgroups32 206
-#define __NR_fchown32 207
-#define __NR_setresuid32 208
-#define __NR_getresuid32 209
-#define __NR_setresgid32 210
-#define __NR_getresgid32 211
-#define __NR_lchown32 212
-#define __NR_setuid32 213
-#define __NR_setgid32 214
-#define __NR_setfsuid32 215
-#define __NR_setfsgid32 216
-#define __NR_pivot_root 217
-#define __NR_getdents64 220
-#define __NR_gettid 221
-#define __NR_tkill 222
-#define __NR_setxattr 223
-#define __NR_lsetxattr 224
-#define __NR_fsetxattr 225
-#define __NR_getxattr 226
-#define __NR_lgetxattr 227
-#define __NR_fgetxattr 228
-#define __NR_listxattr 229
-#define __NR_llistxattr 230
-#define __NR_flistxattr 231
-#define __NR_removexattr 232
-#define __NR_lremovexattr 233
-#define __NR_fremovexattr 234
-#define __NR_futex 235
-#define __NR_sendfile64 236
-#define __NR_mincore 237
-#define __NR_madvise 238
-#define __NR_fcntl64 239
-#define __NR_readahead 240
-#define __NR_io_setup 241
-#define __NR_io_destroy 242
-#define __NR_io_getevents 243
-#define __NR_io_submit 244
-#define __NR_io_cancel 245
-#define __NR_fadvise64 246
-#define __NR_exit_group 247
-#define __NR_lookup_dcookie 248
-#define __NR_epoll_create 249
-#define __NR_epoll_ctl 250
-#define __NR_epoll_wait 251
-#define __NR_remap_file_pages 252
-#define __NR_set_tid_address 253
-#define __NR_timer_create 254
-#define __NR_timer_settime 255
-#define __NR_timer_gettime 256
-#define __NR_timer_getoverrun 257
-#define __NR_timer_delete 258
-#define __NR_clock_settime 259
-#define __NR_clock_gettime 260
-#define __NR_clock_getres 261
-#define __NR_clock_nanosleep 262
-#define __NR_statfs64 263
-#define __NR_fstatfs64 264
-#define __NR_tgkill 265
-#define __NR_utimes 266
-#define __NR_fadvise64_64 267
-#define __NR_mbind 268
-#define __NR_get_mempolicy 269
-#define __NR_set_mempolicy 270
-#define __NR_mq_open 271
-#define __NR_mq_unlink 272
-#define __NR_mq_timedsend 273
-#define __NR_mq_timedreceive 274
-#define __NR_mq_notify 275
-#define __NR_mq_getsetattr 276
-#define __NR_waitid 277
-#define __NR_vserver 278
-#define __NR_add_key 279
-#define __NR_request_key 280
-#define __NR_keyctl 281
-#define __NR_ioprio_set 282
-#define __NR_ioprio_get 283
-#define __NR_inotify_init 284
-#define __NR_inotify_add_watch 285
-#define __NR_inotify_rm_watch 286
-#define __NR_migrate_pages 287
-#define __NR_openat 288
-#define __NR_mkdirat 289
-#define __NR_mknodat 290
-#define __NR_fchownat 291
-#define __NR_futimesat 292
-#define __NR_fstatat64 293
-#define __NR_unlinkat 294
-#define __NR_renameat 295
-#define __NR_linkat 296
-#define __NR_symlinkat 297
-#define __NR_readlinkat 298
-#define __NR_fchmodat 299
-#define __NR_faccessat 300
-#define __NR_pselect6 301
-#define __NR_ppoll 302
-#define __NR_unshare 303
-#define __NR_set_robust_list 304
-#define __NR_get_robust_list 305
-#define __NR_splice 306
-#define __NR_sync_file_range 307
-#define __NR_tee 308
-#define __NR_vmsplice 309
-#define __NR_move_pages 310
-#define __NR_sched_setaffinity 311
-#define __NR_sched_getaffinity 312
-#define __NR_kexec_load 313
-#define __NR_getcpu 314
-#define __NR_epoll_pwait 315
-#define __NR_utimensat 316
-#define __NR_signalfd 317
-#define __NR_timerfd_create 318
-#define __NR_eventfd 319
-#define __NR_fallocate 320
-#define __NR_timerfd_settime 321
-#define __NR_timerfd_gettime 322
-#define __NR_signalfd4 323
-#define __NR_eventfd2 324
-#define __NR_epoll_create1 325
-#define __NR_dup3 326
-#define __NR_pipe2 327
-#define __NR_inotify_init1 328
-
-#ifdef __KERNEL__
-
-#define NR_syscalls 329
-
-#define __ARCH_WANT_IPC_PARSE_VERSION
-#define __ARCH_WANT_OLD_READDIR
-#define __ARCH_WANT_OLD_STAT
-#define __ARCH_WANT_STAT64
-#define __ARCH_WANT_SYS_ALARM
-#define __ARCH_WANT_SYS_GETHOSTNAME
-#define __ARCH_WANT_SYS_PAUSE
-#define __ARCH_WANT_SYS_SGETMASK
-#define __ARCH_WANT_SYS_SIGNAL
-#define __ARCH_WANT_SYS_TIME
-#define __ARCH_WANT_SYS_UTIME
-#define __ARCH_WANT_SYS_WAITPID
-#define __ARCH_WANT_SYS_SOCKETCALL
-#define __ARCH_WANT_SYS_FADVISE64
-#define __ARCH_WANT_SYS_GETPGRP
-#define __ARCH_WANT_SYS_LLSEEK
-#define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
-#define __ARCH_WANT_SYS_OLDUMOUNT
-#define __ARCH_WANT_SYS_SIGPENDING
-#define __ARCH_WANT_SYS_SIGPROCMASK
-#define __ARCH_WANT_SYS_RT_SIGACTION
-
-/*
- * "Conditional" syscalls
- *
- * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
- * but it doesn't work on all toolchains, so we just do it by hand
- */
-#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_M68K_UNISTD_H_ */
diff --git a/arch/m68k/install.sh b/arch/m68k/install.sh
new file mode 100644
index 000000000000..9c6bae6112e3
--- /dev/null
+++ b/arch/m68k/install.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+#
+# "make install" script for m68k architecture
+#
+# Arguments:
+# $1 - kernel version
+# $2 - kernel image file
+# $3 - kernel map file
+# $4 - default install path (blank if root directory)
+#
+
+verify () {
+ if [ ! -f "$1" ]; then
+ echo "" 1>&2
+ echo " *** Missing file: $1" 1>&2
+ echo ' *** You need to run "make" before "make install".' 1>&2
+ echo "" 1>&2
+ exit 1
+ fi
+}
+
+# Make sure the files actually exist
+verify "$2"
+verify "$3"
+
+# User may have a custom install script
+
+if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
+if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
+
+# Default install - same as make zlilo
+
+if [ -f $4/vmlinuz ]; then
+ mv $4/vmlinuz $4/vmlinuz.old
+fi
+
+if [ -f $4/System.map ]; then
+ mv $4/System.map $4/System.old
+fi
+
+cat $2 > $4/vmlinuz
+cp $3 $4/System.map
+
+sync
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index 632ce016014d..ec37fb56c127 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -233,7 +233,7 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
parent_tidptr, child_tidptr);
}
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
index 7db41594d7b6..54d980795fc4 100644
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -18,6 +18,7 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/rtc.h>
+#include <linux/platform_device.h>
#include <asm/machdep.h>
#include <asm/io.h>
@@ -159,3 +160,20 @@ int do_settimeofday(struct timespec *tv)
}
EXPORT_SYMBOL(do_settimeofday);
+
+
+static int __init rtc_init(void)
+{
+ struct platform_device *pdev;
+
+ if (!mach_hwclk)
+ return -ENODEV;
+
+ pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
+}
+
+module_init(rtc_init);
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 98b6bcfb37bf..be017984a456 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -22,6 +22,7 @@
/* keyb */
#include <linux/init.h>
#include <linux/vt_kern.h>
+#include <linux/platform_device.h>
#define BOOTINFO_COMPAT_1_0
#include <asm/setup.h>
@@ -43,6 +44,10 @@
#include <asm/mac_oss.h>
#include <asm/mac_psc.h>
+/* platform device info */
+
+#define SWIM_IO_SIZE 0x2000 /* SWIM IO resource size */
+
/* Mac bootinfo struct */
struct mac_booter_data mac_bi_data;
@@ -224,7 +229,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_II,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_IWM
},
/*
@@ -239,7 +245,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_II,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_IWM
}, {
.ident = MAC_MODEL_IIX,
.name = "IIx",
@@ -247,7 +254,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_II,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_IICX,
.name = "IIcx",
@@ -255,7 +263,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_II,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_SE30,
.name = "SE/30",
@@ -263,7 +272,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_II,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
},
/*
@@ -280,7 +290,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_IIFX,
.name = "IIfx",
@@ -288,7 +299,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_IOP,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_IOP
}, {
.ident = MAC_MODEL_IISI,
.name = "IIsi",
@@ -296,7 +308,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_IIVI,
.name = "IIvi",
@@ -304,7 +317,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_IIVX,
.name = "IIvx",
@@ -312,7 +326,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
},
/*
@@ -326,7 +341,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_CCL,
.name = "Color Classic",
@@ -334,7 +350,9 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS},
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
+ },
/*
* Some Mac LC machines. Basically the same as the IIci, ADB like IIsi
@@ -347,7 +365,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_LCII,
.name = "LC II",
@@ -355,7 +374,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_LCIII,
.name = "LC III",
@@ -363,7 +383,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
},
/*
@@ -383,7 +404,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_QUADRA,
.scsi_type = MAC_SCSI_QUADRA,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR1
}, {
.ident = MAC_MODEL_Q605_ACC,
.name = "Quadra 605",
@@ -391,7 +413,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_QUADRA,
.scsi_type = MAC_SCSI_QUADRA,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR1
}, {
.ident = MAC_MODEL_Q610,
.name = "Quadra 610",
@@ -400,7 +423,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_QUADRA,
.scc_type = MAC_SCC_QUADRA,
.ether_type = MAC_ETHER_SONIC,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR1
}, {
.ident = MAC_MODEL_Q630,
.name = "Quadra 630",
@@ -410,7 +434,8 @@ static struct mac_model mac_data_table[] = {
.ide_type = MAC_IDE_QUADRA,
.scc_type = MAC_SCC_QUADRA,
.ether_type = MAC_ETHER_SONIC,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR1
}, {
.ident = MAC_MODEL_Q650,
.name = "Quadra 650",
@@ -419,7 +444,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_QUADRA,
.scc_type = MAC_SCC_QUADRA,
.ether_type = MAC_ETHER_SONIC,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR1
},
/* The Q700 does have a NS Sonic */
{
@@ -430,7 +456,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_QUADRA2,
.scc_type = MAC_SCC_QUADRA,
.ether_type = MAC_ETHER_SONIC,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR1
}, {
.ident = MAC_MODEL_Q800,
.name = "Quadra 800",
@@ -439,7 +466,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_QUADRA,
.scc_type = MAC_SCC_QUADRA,
.ether_type = MAC_ETHER_SONIC,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR1
}, {
.ident = MAC_MODEL_Q840,
.name = "Quadra 840AV",
@@ -448,7 +476,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_QUADRA3,
.scc_type = MAC_SCC_PSC,
.ether_type = MAC_ETHER_MACE,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_AV
}, {
.ident = MAC_MODEL_Q900,
.name = "Quadra 900",
@@ -457,7 +486,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_QUADRA2,
.scc_type = MAC_SCC_IOP,
.ether_type = MAC_ETHER_SONIC,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_IOP
}, {
.ident = MAC_MODEL_Q950,
.name = "Quadra 950",
@@ -466,7 +496,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_QUADRA2,
.scc_type = MAC_SCC_IOP,
.ether_type = MAC_ETHER_SONIC,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_IOP
},
/*
@@ -480,7 +511,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_P475,
.name = "Performa 475",
@@ -488,7 +520,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_QUADRA,
.scsi_type = MAC_SCSI_QUADRA,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR1
}, {
.ident = MAC_MODEL_P475F,
.name = "Performa 475",
@@ -496,7 +529,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_QUADRA,
.scsi_type = MAC_SCSI_QUADRA,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR1
}, {
.ident = MAC_MODEL_P520,
.name = "Performa 520",
@@ -504,7 +538,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_P550,
.name = "Performa 550",
@@ -512,7 +547,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
},
/* These have the comm slot, and therefore the possibility of SONIC ethernet */
{
@@ -523,7 +559,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_QUADRA,
.scc_type = MAC_SCC_II,
.ether_type = MAC_ETHER_SONIC,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR1
}, {
.ident = MAC_MODEL_P588,
.name = "Performa 588",
@@ -533,7 +570,8 @@ static struct mac_model mac_data_table[] = {
.ide_type = MAC_IDE_QUADRA,
.scc_type = MAC_SCC_II,
.ether_type = MAC_ETHER_SONIC,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR1
}, {
.ident = MAC_MODEL_TV,
.name = "TV",
@@ -541,7 +579,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_QUADRA,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_P600,
.name = "Performa 600",
@@ -549,7 +588,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
},
/*
@@ -565,7 +605,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_QUADRA,
.scc_type = MAC_SCC_QUADRA,
.ether_type = MAC_ETHER_SONIC,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR1
}, {
.ident = MAC_MODEL_C650,
.name = "Centris 650",
@@ -574,7 +615,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_QUADRA,
.scc_type = MAC_SCC_QUADRA,
.ether_type = MAC_ETHER_SONIC,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR1
}, {
.ident = MAC_MODEL_C660,
.name = "Centris 660AV",
@@ -583,7 +625,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_QUADRA3,
.scc_type = MAC_SCC_PSC,
.ether_type = MAC_ETHER_MACE,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_AV
},
/*
@@ -599,7 +642,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_QUADRA,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB145,
.name = "PowerBook 145",
@@ -607,7 +651,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_QUADRA,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB150,
.name = "PowerBook 150",
@@ -616,7 +661,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_OLD,
.ide_type = MAC_IDE_PB,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB160,
.name = "PowerBook 160",
@@ -624,7 +670,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_QUADRA,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB165,
.name = "PowerBook 165",
@@ -632,7 +679,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_QUADRA,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB165C,
.name = "PowerBook 165c",
@@ -640,7 +688,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_QUADRA,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB170,
.name = "PowerBook 170",
@@ -648,7 +697,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_QUADRA,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB180,
.name = "PowerBook 180",
@@ -656,7 +706,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_QUADRA,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB180C,
.name = "PowerBook 180c",
@@ -664,7 +715,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_QUADRA,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB190,
.name = "PowerBook 190",
@@ -673,7 +725,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_OLD,
.ide_type = MAC_IDE_BABOON,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB520,
.name = "PowerBook 520",
@@ -682,7 +735,8 @@ static struct mac_model mac_data_table[] = {
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
.ether_type = MAC_ETHER_SONIC,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
},
/*
@@ -702,7 +756,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB230,
.name = "PowerBook Duo 230",
@@ -710,7 +765,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB250,
.name = "PowerBook Duo 250",
@@ -718,7 +774,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB270C,
.name = "PowerBook Duo 270c",
@@ -726,7 +783,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB280,
.name = "PowerBook Duo 280",
@@ -734,7 +792,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
}, {
.ident = MAC_MODEL_PB280C,
.name = "PowerBook Duo 280c",
@@ -742,7 +801,8 @@ static struct mac_model mac_data_table[] = {
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
- .nubus_type = MAC_NUBUS
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2
},
/*
@@ -815,3 +875,42 @@ static void mac_get_model(char *str)
strcpy(str, "Macintosh ");
strcat(str, macintosh_config->name);
}
+
+static struct resource swim_resources[1];
+
+static struct platform_device swim_device = {
+ .name = "swim",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(swim_resources),
+ .resource = swim_resources,
+};
+
+static struct platform_device *mac_platform_devices[] __initdata = {
+ &swim_device
+};
+
+int __init mac_platform_init(void)
+{
+ u8 *swim_base;
+
+ switch (macintosh_config->floppy_type) {
+ case MAC_FLOPPY_SWIM_ADDR1:
+ swim_base = (u8 *)(VIA1_BASE + 0x1E000);
+ break;
+ case MAC_FLOPPY_SWIM_ADDR2:
+ swim_base = (u8 *)(VIA1_BASE + 0x16000);
+ break;
+ default:
+ return 0;
+ }
+
+ swim_resources[0].name = "swim-regs";
+ swim_resources[0].start = (resource_size_t)swim_base;
+ swim_resources[0].end = (resource_size_t)(swim_base + SWIM_IO_SIZE);
+ swim_resources[0].flags = IORESOURCE_MEM;
+
+ return platform_add_devices(mac_platform_devices,
+ ARRAY_SIZE(mac_platform_devices));
+}
+
+arch_initcall(mac_platform_init);
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index 7d97ba54536e..11bce3cb6482 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -645,3 +645,12 @@ int via_irq_pending(int irq)
}
return 0;
}
+
+void via1_set_head(int head)
+{
+ if (head == 0)
+ via1[vBufA] &= ~VIA1A_vHeadSel;
+ else
+ via1[vBufA] |= VIA1A_vHeadSel;
+}
+EXPORT_SYMBOL(via1_set_head);
diff --git a/arch/m68knommu/Makefile b/arch/m68knommu/Makefile
index fd0fb303d885..ce404bc9ccbd 100644
--- a/arch/m68knommu/Makefile
+++ b/arch/m68knommu/Makefile
@@ -88,18 +88,18 @@ export PLATFORM BOARD MODEL CPUCLASS
#
# Some CFLAG additions based on specific CPU type.
#
-cflags-$(CONFIG_M5206) := -m5200
-cflags-$(CONFIG_M5206e) := -m5200
-cflags-$(CONFIG_M520x) := -m5307
+cflags-$(CONFIG_M5206) := $(call cc-option,-mcpu=5206,-m5200)
+cflags-$(CONFIG_M5206e) := $(call cc-option,-m5206e,-m5200)
+cflags-$(CONFIG_M520x) := $(call cc-option,-mcpu=5208,-m5200)
cflags-$(CONFIG_M523x) := $(call cc-option,-mcpu=523x,-m5307)
-cflags-$(CONFIG_M5249) := -m5200
+cflags-$(CONFIG_M5249) := $(call cc-option,-mcpu=5249,-m5200)
cflags-$(CONFIG_M5271) := $(call cc-option,-mcpu=5271,-m5307)
-cflags-$(CONFIG_M5272) := -m5307
+cflags-$(CONFIG_M5272) := $(call cc-option,-mcpu=5271,-m5200)
cflags-$(CONFIG_M5275) := $(call cc-option,-mcpu=5275,-m5307)
cflags-$(CONFIG_M528x) := $(call cc-option,-m528x,-m5307)
-cflags-$(CONFIG_M5307) := -m5307
+cflags-$(CONFIG_M5307) := $(call cc-option,-m5307,-m5200)
cflags-$(CONFIG_M532x) := $(call cc-option,-mcpu=532x,-m5307)
-cflags-$(CONFIG_M5407) := -m5200
+cflags-$(CONFIG_M5407) := $(call cc-option,-m5407,-m5200)
cflags-$(CONFIG_M68328) := -m68000
cflags-$(CONFIG_M68EZ328) := -m68000
cflags-$(CONFIG_M68VZ328) := -m68000
diff --git a/arch/m68knommu/kernel/dma.c b/arch/m68knommu/kernel/dma.c
index e10eafc52789..936125806638 100644
--- a/arch/m68knommu/kernel/dma.c
+++ b/arch/m68knommu/kernel/dma.c
@@ -9,10 +9,11 @@
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/device.h>
+#include <linux/dma-mapping.h>
#include <asm/io.h>
void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, int gfp)
+ dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
/* ignore region specifiers */
@@ -34,3 +35,8 @@ void dma_free_coherent(struct device *dev, size_t size,
{
free_pages((unsigned long)vaddr, get_order(size));
}
+
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+}
+
diff --git a/arch/m68knommu/kernel/irq.c b/arch/m68knommu/kernel/irq.c
index bba1bb48a21f..56e0f4c55a67 100644
--- a/arch/m68knommu/kernel/irq.c
+++ b/arch/m68knommu/kernel/irq.c
@@ -23,7 +23,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
struct pt_regs *oldregs = set_irq_regs(regs);
irq_enter();
- __do_IRQ(irq);
+ generic_handle_irq(irq);
irq_exit();
set_irq_regs(oldregs);
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index 3f2d7745f31e..1e96c6eb6312 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -199,7 +199,7 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
}
-int copy_thread(int nr, unsigned long clone_flags,
+int copy_thread(unsigned long clone_flags,
unsigned long usp, unsigned long topstk,
struct task_struct * p, struct pt_regs * regs)
{
diff --git a/arch/m68knommu/mm/init.c b/arch/m68knommu/mm/init.c
index 3bf249c53e41..7befc0c357e0 100644
--- a/arch/m68knommu/mm/init.c
+++ b/arch/m68knommu/mm/init.c
@@ -111,11 +111,7 @@ void __init paging_init(void)
{
unsigned long zones_size[MAX_NR_ZONES] = {0, };
- zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT;
- zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
-#ifdef CONFIG_HIGHMEM
- zones_size[ZONE_HIGHMEM] = 0;
-#endif
+ zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
free_area_init(zones_size);
}
}
diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68knommu/platform/520x/config.c
index 06d887cdcbfb..855fc6a79d72 100644
--- a/arch/m68knommu/platform/520x/config.c
+++ b/arch/m68knommu/platform/520x/config.c
@@ -49,8 +49,39 @@ static struct platform_device m520x_uart = {
.dev.platform_data = m520x_uart_platform,
};
+static struct resource m520x_fec_resources[] = {
+ {
+ .start = MCF_MBAR + 0x30000,
+ .end = MCF_MBAR + 0x30000 + 0x7ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 64 + 36,
+ .end = 64 + 36,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 64 + 40,
+ .end = 64 + 40,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 64 + 42,
+ .end = 64 + 42,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device m520x_fec = {
+ .name = "fec",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m520x_fec_resources),
+ .resource = m520x_fec_resources,
+};
+
static struct platform_device *m520x_devices[] __initdata = {
&m520x_uart,
+ &m520x_fec,
};
/***************************************************************************/
@@ -103,6 +134,30 @@ static void __init m520x_uarts_init(void)
/***************************************************************************/
+static void __init m520x_fec_init(void)
+{
+ u32 imr;
+ u8 v;
+
+ /* Unmask FEC interrupts at ColdFire interrupt controller */
+ writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 36);
+ writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 40);
+ writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 42);
+
+ imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+ imr &= ~0x0001FFF0;
+ writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+
+ /* Set multi-function pins to ethernet mode */
+ v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FEC);
+ writeb(v | 0xf0, MCF_IPSBAR + MCF_GPIO_PAR_FEC);
+
+ v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+ writeb(v | 0x0f, MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+}
+
+/***************************************************************************/
+
/*
* Program the vector to be an auto-vectored.
*/
@@ -118,6 +173,7 @@ void __init config_BSP(char *commandp, int size)
{
mach_reset = coldfire_reset;
m520x_uarts_init();
+ m520x_fec_init();
}
/***************************************************************************/
diff --git a/arch/m68knommu/platform/523x/config.c b/arch/m68knommu/platform/523x/config.c
index 13f02611ea23..74133f27b30c 100644
--- a/arch/m68knommu/platform/523x/config.c
+++ b/arch/m68knommu/platform/523x/config.c
@@ -50,8 +50,39 @@ static struct platform_device m523x_uart = {
.dev.platform_data = m523x_uart_platform,
};
+static struct resource m523x_fec_resources[] = {
+ {
+ .start = MCF_MBAR + 0x1000,
+ .end = MCF_MBAR + 0x1000 + 0x7ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 64 + 23,
+ .end = 64 + 23,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 64 + 27,
+ .end = 64 + 27,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 64 + 29,
+ .end = 64 + 29,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device m523x_fec = {
+ .name = "fec",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m523x_fec_resources),
+ .resource = m523x_fec_resources,
+};
+
static struct platform_device *m523x_devices[] __initdata = {
&m523x_uart,
+ &m523x_fec,
};
/***************************************************************************/
@@ -83,6 +114,25 @@ static void __init m523x_uarts_init(void)
/***************************************************************************/
+static void __init m523x_fec_init(void)
+{
+ u32 imr;
+
+ /* Unmask FEC interrupts at ColdFire interrupt controller */
+ writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
+ writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
+ writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
+
+ imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+ imr &= ~0xf;
+ writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+ imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
+ imr &= ~0xff800001;
+ writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
+}
+
+/***************************************************************************/
+
void mcf_disableall(void)
{
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
@@ -103,6 +153,7 @@ void __init config_BSP(char *commandp, int size)
mcf_disableall();
mach_reset = coldfire_reset;
m523x_uarts_init();
+ m523x_fec_init();
}
/***************************************************************************/
diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c
index d299f7b8768a..9eab19d01eb1 100644
--- a/arch/m68knommu/platform/5249/config.c
+++ b/arch/m68knommu/platform/5249/config.c
@@ -32,7 +32,8 @@ static struct mcf_platform_uart m5249_uart_platform[] = {
{
.mapbase = MCF_MBAR + MCFUART_BASE2,
.irq = 74,
- }
+ },
+ { },
};
static struct platform_device m5249_uart = {
@@ -50,12 +51,12 @@ static struct platform_device *m5249_devices[] __initdata = {
static void __init m5249_uart_init_line(int line, int irq)
{
if (line == 0) {
- writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
- writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+ writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
} else if (line == 1) {
- writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
- writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+ writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
}
}
diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c
index 230bae691a7f..e049245f4092 100644
--- a/arch/m68knommu/platform/5272/config.c
+++ b/arch/m68knommu/platform/5272/config.c
@@ -55,8 +55,39 @@ static struct platform_device m5272_uart = {
.dev.platform_data = m5272_uart_platform,
};
+static struct resource m5272_fec_resources[] = {
+ {
+ .start = MCF_MBAR + 0x840,
+ .end = MCF_MBAR + 0x840 + 0x1cf,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 86,
+ .end = 86,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 87,
+ .end = 87,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 88,
+ .end = 88,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device m5272_fec = {
+ .name = "fec",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m5272_fec_resources),
+ .resource = m5272_fec_resources,
+};
+
static struct platform_device *m5272_devices[] __initdata = {
&m5272_uart,
+ &m5272_fec,
};
/***************************************************************************/
@@ -91,6 +122,22 @@ static void __init m5272_uarts_init(void)
/***************************************************************************/
+static void __init m5272_fec_init(void)
+{
+ u32 imr;
+
+ /* Unmask FEC interrupts at ColdFire interrupt controller */
+ imr = readl(MCF_MBAR + MCFSIM_ICR3);
+ imr = (imr & ~0x00000fff) | 0x00000ddd;
+ writel(imr, MCF_MBAR + MCFSIM_ICR3);
+
+ imr = readl(MCF_MBAR + MCFSIM_ICR1);
+ imr = (imr & ~0x0f000000) | 0x0d000000;
+ writel(imr, MCF_MBAR + MCFSIM_ICR1);
+}
+
+/***************************************************************************/
+
void mcf_disableall(void)
{
volatile unsigned long *icrp;
@@ -155,6 +202,7 @@ void __init config_BSP(char *commandp, int size)
static int __init init_BSP(void)
{
m5272_uarts_init();
+ m5272_fec_init();
platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices));
return 0;
}
diff --git a/arch/m68knommu/platform/527x/config.c b/arch/m68knommu/platform/527x/config.c
index 73cd1aef4a90..49343fb157b0 100644
--- a/arch/m68knommu/platform/527x/config.c
+++ b/arch/m68knommu/platform/527x/config.c
@@ -50,8 +50,73 @@ static struct platform_device m527x_uart = {
.dev.platform_data = m527x_uart_platform,
};
+static struct resource m527x_fec0_resources[] = {
+ {
+ .start = MCF_MBAR + 0x1000,
+ .end = MCF_MBAR + 0x1000 + 0x7ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 64 + 23,
+ .end = 64 + 23,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 64 + 27,
+ .end = 64 + 27,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 64 + 29,
+ .end = 64 + 29,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource m527x_fec1_resources[] = {
+ {
+ .start = MCF_MBAR + 0x1800,
+ .end = MCF_MBAR + 0x1800 + 0x7ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 128 + 23,
+ .end = 128 + 23,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 128 + 27,
+ .end = 128 + 27,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 128 + 29,
+ .end = 128 + 29,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device m527x_fec[] = {
+ {
+ .name = "fec",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m527x_fec0_resources),
+ .resource = m527x_fec0_resources,
+ },
+ {
+ .name = "fec",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(m527x_fec1_resources),
+ .resource = m527x_fec1_resources,
+ },
+};
+
static struct platform_device *m527x_devices[] __initdata = {
&m527x_uart,
+ &m527x_fec[0],
+#ifdef CONFIG_FEC2
+ &m527x_fec[1],
+#endif
};
/***************************************************************************/
@@ -97,6 +162,51 @@ static void __init m527x_uarts_init(void)
/***************************************************************************/
+static void __init m527x_fec_irq_init(int nr)
+{
+ unsigned long base;
+ u32 imr;
+
+ base = MCF_IPSBAR + (nr ? MCFICM_INTC1 : MCFICM_INTC0);
+
+ writeb(0x28, base + MCFINTC_ICR0 + 23);
+ writeb(0x27, base + MCFINTC_ICR0 + 27);
+ writeb(0x26, base + MCFINTC_ICR0 + 29);
+
+ imr = readl(base + MCFINTC_IMRH);
+ imr &= ~0xf;
+ writel(imr, base + MCFINTC_IMRH);
+ imr = readl(base + MCFINTC_IMRL);
+ imr &= ~0xff800001;
+ writel(imr, base + MCFINTC_IMRL);
+}
+
+static void __init m527x_fec_init(void)
+{
+ u16 par;
+ u8 v;
+
+ m527x_fec_irq_init(0);
+
+ /* Set multi-function pins to ethernet mode for fec0 */
+ par = readw(MCF_IPSBAR + 0x100082);
+ writew(par | 0xf00, MCF_IPSBAR + 0x100082);
+ v = readb(MCF_IPSBAR + 0x100078);
+ writeb(v | 0xc0, MCF_IPSBAR + 0x100078);
+
+#ifdef CONFIG_FEC2
+ m527x_fec_irq_init(1);
+
+ /* Set multi-function pins to ethernet mode for fec1 */
+ par = readw(MCF_IPSBAR + 0x100082);
+ writew(par | 0xa0, MCF_IPSBAR + 0x100082);
+ v = readb(MCF_IPSBAR + 0x100079);
+ writeb(v | 0xc0, MCF_IPSBAR + 0x100079);
+#endif
+}
+
+/***************************************************************************/
+
void mcf_disableall(void)
{
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
@@ -116,13 +226,14 @@ void __init config_BSP(char *commandp, int size)
{
mcf_disableall();
mach_reset = coldfire_reset;
+ m527x_uarts_init();
+ m527x_fec_init();
}
/***************************************************************************/
static int __init init_BSP(void)
{
- m527x_uarts_init();
platform_add_devices(m527x_devices, ARRAY_SIZE(m527x_devices));
return 0;
}
diff --git a/arch/m68knommu/platform/528x/config.c b/arch/m68knommu/platform/528x/config.c
index 44baeb225dc7..bee526f4d1af 100644
--- a/arch/m68knommu/platform/528x/config.c
+++ b/arch/m68knommu/platform/528x/config.c
@@ -57,8 +57,40 @@ static struct platform_device m528x_uart = {
.dev.platform_data = m528x_uart_platform,
};
+static struct resource m528x_fec_resources[] = {
+ {
+ .start = MCF_MBAR + 0x1000,
+ .end = MCF_MBAR + 0x1000 + 0x7ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 64 + 23,
+ .end = 64 + 23,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 64 + 27,
+ .end = 64 + 27,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 64 + 29,
+ .end = 64 + 29,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device m528x_fec = {
+ .name = "fec",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m528x_fec_resources),
+ .resource = m528x_fec_resources,
+};
+
+
static struct platform_device *m528x_devices[] __initdata = {
&m528x_uart,
+ &m528x_fec,
};
/***************************************************************************/
@@ -99,6 +131,31 @@ static void __init m528x_uarts_init(void)
/***************************************************************************/
+static void __init m528x_fec_init(void)
+{
+ u32 imr;
+ u16 v16;
+
+ /* Unmask FEC interrupts at ColdFire interrupt controller */
+ writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
+ writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
+ writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
+
+ imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+ imr &= ~0xf;
+ writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
+ imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
+ imr &= ~0xff800001;
+ writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
+
+ /* Set multi-function pins to ethernet mode for fec0 */
+ v16 = readw(MCF_IPSBAR + 0x100056);
+ writew(v16 | 0xf00, MCF_IPSBAR + 0x100056);
+ writeb(0xc0, MCF_IPSBAR + 0x100058);
+}
+
+/***************************************************************************/
+
void mcf_disableall(void)
{
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
@@ -158,6 +215,7 @@ void __init config_BSP(char *commandp, int size)
static int __init init_BSP(void)
{
m528x_uarts_init();
+ m528x_fec_init();
platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
return 0;
}
diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c
index 724faf05852a..44803bf70a6e 100644
--- a/arch/m68knommu/platform/5307/config.c
+++ b/arch/m68knommu/platform/5307/config.c
@@ -65,12 +65,12 @@ static struct platform_device *m5307_devices[] __initdata = {
static void __init m5307_uart_init_line(int line, int irq)
{
if (line == 0) {
- writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
- writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+ writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
} else if (line == 1) {
- writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
- writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+ writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
}
}
diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68knommu/platform/532x/config.c
index a347623d6ee6..591f2f801134 100644
--- a/arch/m68knommu/platform/532x/config.c
+++ b/arch/m68knommu/platform/532x/config.c
@@ -61,8 +61,38 @@ static struct platform_device m532x_uart = {
.dev.platform_data = m532x_uart_platform,
};
+static struct resource m532x_fec_resources[] = {
+ {
+ .start = 0xfc030000,
+ .end = 0xfc0307ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 64 + 36,
+ .end = 64 + 36,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 64 + 40,
+ .end = 64 + 40,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 64 + 42,
+ .end = 64 + 42,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device m532x_fec = {
+ .name = "fec",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m532x_fec_resources),
+ .resource = m532x_fec_resources,
+};
static struct platform_device *m532x_devices[] __initdata = {
&m532x_uart,
+ &m532x_fec,
};
/***************************************************************************/
@@ -93,6 +123,24 @@ static void __init m532x_uarts_init(void)
for (line = 0; (line < nrlines); line++)
m532x_uart_init_line(line, m532x_uart_platform[line].irq);
}
+/***************************************************************************/
+
+static void __init m532x_fec_init(void)
+{
+ /* Unmask FEC interrupts at ColdFire interrupt controller */
+ MCF_INTC0_ICR36 = 0x2;
+ MCF_INTC0_ICR40 = 0x2;
+ MCF_INTC0_ICR42 = 0x2;
+
+ MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK36 |
+ MCF_INTC_IMRH_INT_MASK40 | MCF_INTC_IMRH_INT_MASK42);
+
+ /* Set multi-function pins to ethernet mode for fec0 */
+ MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
+ MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
+ MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC |
+ MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC);
+}
/***************************************************************************/
@@ -150,6 +198,7 @@ void __init config_BSP(char *commandp, int size)
static int __init init_BSP(void)
{
m532x_uarts_init();
+ m532x_fec_init();
platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
return 0;
}
diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c
index 648b8b778211..0ee8c1a200c8 100644
--- a/arch/m68knommu/platform/5407/config.c
+++ b/arch/m68knommu/platform/5407/config.c
@@ -56,12 +56,12 @@ static struct platform_device *m5407_devices[] __initdata = {
static void __init m5407_uart_init_line(int line, int irq)
{
if (line == 0) {
- writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
- writeb(irq, MCFUART_BASE1 + MCFUART_UIVR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
+ writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
} else if (line == 1) {
- writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
- writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
+ writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
+ writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
}
}
diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile
index 4f416a91a829..1bcb9372353f 100644
--- a/arch/m68knommu/platform/coldfire/Makefile
+++ b/arch/m68knommu/platform/coldfire/Makefile
@@ -14,7 +14,7 @@
asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
-obj-$(CONFIG_COLDFIRE) += dma.o entry.o vectors.o
+obj-$(CONFIG_COLDFIRE) += clk.o dma.o entry.o vectors.o
obj-$(CONFIG_M5206) += timers.o
obj-$(CONFIG_M5206e) += timers.o
obj-$(CONFIG_M520x) += pit.o
diff --git a/arch/m68knommu/platform/coldfire/clk.c b/arch/m68knommu/platform/coldfire/clk.c
new file mode 100644
index 000000000000..7cdbf445b28f
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/clk.c
@@ -0,0 +1,40 @@
+/***************************************************************************/
+
+/*
+ * clk.c -- general ColdFire CPU kernel clk handling
+ *
+ * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <asm/coldfire.h>
+
+/***************************************************************************/
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ return NULL;
+}
+
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+
+void clk_disable(struct clk *clk)
+{
+}
+
+void clk_put(struct clk *clk)
+{
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return MCF_CLK;
+}
+
+/***************************************************************************/
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 206cb7953b0c..998e5db8cc0f 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -77,7 +77,6 @@ config MIPS_COBALT
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
- select GENERIC_HARDIRQS_NO__DO_IRQ
config MACH_DECSTATION
bool "DECstations"
@@ -132,11 +131,10 @@ config MACH_JAZZ
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
select SYS_SUPPORTS_100HZ
- select GENERIC_HARDIRQS_NO__DO_IRQ
help
This a family of machines based on the MIPS R4030 chipset which was
used by several vendors to build RISC/os and Windows NT workstations.
- Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
+ Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
Olivetti M700-10 workstations.
config LASAT
@@ -154,7 +152,6 @@ config LASAT
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL if BROKEN
select SYS_SUPPORTS_LITTLE_ENDIAN
- select GENERIC_HARDIRQS_NO__DO_IRQ
config LEMOTE_FULONG
bool "Lemote Fulong mini-PC"
@@ -175,7 +172,6 @@ config LEMOTE_FULONG
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_HIGHMEM
select SYS_HAS_EARLY_PRINTK
- select GENERIC_HARDIRQS_NO__DO_IRQ
select GENERIC_ISA_DMA_SUPPORT_BROKEN
select CPU_HAS_WB
help
@@ -250,7 +246,6 @@ config MACH_VR41XX
select CEVT_R4K
select CSRC_R4K
select SYS_HAS_CPU_VR41XX
- select GENERIC_HARDIRQS_NO__DO_IRQ
config NXP_STB220
bool "NXP STB220 board"
@@ -364,7 +359,6 @@ config SGI_IP27
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_NUMA
select SYS_SUPPORTS_SMP
- select GENERIC_HARDIRQS_NO__DO_IRQ
help
This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics
workstations. To compile a Linux kernel that runs on these, say Y
@@ -563,7 +557,6 @@ config MIKROTIK_RB532
select CEVT_R4K
select CSRC_R4K
select DMA_NONCOHERENT
- select GENERIC_HARDIRQS_NO__DO_IRQ
select HW_HAS_PCI
select IRQ_CPU
select SYS_HAS_CPU_MIPS32_R1
@@ -700,8 +693,7 @@ config SCHED_OMIT_FRAME_POINTER
default y
config GENERIC_HARDIRQS_NO__DO_IRQ
- bool
- default n
+ def_bool y
#
# Select some configuration options automatically based on user selections.
@@ -920,7 +912,6 @@ config SOC_PNX833X
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_BIG_ENDIAN
- select GENERIC_HARDIRQS_NO__DO_IRQ
select GENERIC_GPIO
select CPU_MIPSR2_IRQ_VI
@@ -939,7 +930,6 @@ config SOC_PNX8550
select SYS_HAS_CPU_MIPS32_R1
select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_32BIT_KERNEL
- select GENERIC_HARDIRQS_NO__DO_IRQ
select GENERIC_GPIO
config SWAP_IO_SPACE
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 22dab2e14348..8d544c7c9fe9 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -720,11 +720,17 @@ ifdef CONFIG_MIPS32_O32
$(Q)$(MAKE) $(build)=. missing-syscalls EXTRA_CFLAGS="-mabi=32"
endif
+install:
+ $(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE)
+ $(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE)
+ $(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE)
+
archclean:
@$(MAKE) $(clean)=arch/mips/boot
@$(MAKE) $(clean)=arch/mips/lasat
define archhelp
+ echo ' install - install kernel into $(INSTALL_PATH)'
echo ' vmlinux.ecoff - ECOFF boot image'
echo ' vmlinux.bin - Raw binary boot image'
echo ' vmlinux.srec - SREC boot image'
diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig
index 7f8ef13d0014..8128aebfb155 100644
--- a/arch/mips/alchemy/Kconfig
+++ b/arch/mips/alchemy/Kconfig
@@ -134,4 +134,4 @@ config SOC_AU1X00
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_APM_EMULATION
- select GENERIC_HARDIRQS_NO__DO_IRQ
+ select ARCH_REQUIRE_GPIOLIB
diff --git a/arch/mips/alchemy/common/gpio.c b/arch/mips/alchemy/common/gpio.c
index e660ddd611c4..91a9c4436c39 100644
--- a/arch/mips/alchemy/common/gpio.c
+++ b/arch/mips/alchemy/common/gpio.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
* Architecture specific GPIO support
*
* This program is free software; you can redistribute it and/or modify it
@@ -27,122 +27,175 @@
* others have a second one : GPIO2
*/
+#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/gpio.h>
-#define gpio1 sys
-#if !defined(CONFIG_SOC_AU1000)
-
-static struct au1x00_gpio2 *const gpio2 = (struct au1x00_gpio2 *) GPIO2_BASE;
-#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000
+struct au1000_gpio_chip {
+ struct gpio_chip chip;
+ void __iomem *regbase;
+};
-static int au1xxx_gpio2_read(unsigned gpio)
+#if !defined(CONFIG_SOC_AU1000)
+static int au1000_gpio2_get(struct gpio_chip *chip, unsigned offset)
{
- gpio -= AU1XXX_GPIO_BASE;
- return ((gpio2->pinstate >> gpio) & 0x01);
+ u32 mask = 1 << offset;
+ struct au1000_gpio_chip *gpch;
+
+ gpch = container_of(chip, struct au1000_gpio_chip, chip);
+ return readl(gpch->regbase + AU1000_GPIO2_ST) & mask;
}
-static void au1xxx_gpio2_write(unsigned gpio, int value)
+static void au1000_gpio2_set(struct gpio_chip *chip,
+ unsigned offset, int value)
{
- gpio -= AU1XXX_GPIO_BASE;
+ u32 mask = ((GPIO2_OUT_EN_MASK << offset) | (!!value << offset));
+ struct au1000_gpio_chip *gpch;
+ unsigned long flags;
+
+ gpch = container_of(chip, struct au1000_gpio_chip, chip);
- gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio);
+ local_irq_save(flags);
+ writel(mask, gpch->regbase + AU1000_GPIO2_OUT);
+ local_irq_restore(flags);
}
-static int au1xxx_gpio2_direction_input(unsigned gpio)
+static int au1000_gpio2_direction_input(struct gpio_chip *chip, unsigned offset)
{
- gpio -= AU1XXX_GPIO_BASE;
- gpio2->dir &= ~(0x01 << gpio);
+ u32 mask = 1 << offset;
+ u32 tmp;
+ struct au1000_gpio_chip *gpch;
+ unsigned long flags;
+
+ gpch = container_of(chip, struct au1000_gpio_chip, chip);
+
+ local_irq_save(flags);
+ tmp = readl(gpch->regbase + AU1000_GPIO2_DIR);
+ tmp &= ~mask;
+ writel(tmp, gpch->regbase + AU1000_GPIO2_DIR);
+ local_irq_restore(flags);
+
return 0;
}
-static int au1xxx_gpio2_direction_output(unsigned gpio, int value)
+static int au1000_gpio2_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
{
- gpio -= AU1XXX_GPIO_BASE;
- gpio2->dir |= 0x01 << gpio;
- gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio);
+ u32 mask = 1 << offset;
+ u32 out_mask = ((GPIO2_OUT_EN_MASK << offset) | (!!value << offset));
+ u32 tmp;
+ struct au1000_gpio_chip *gpch;
+ unsigned long flags;
+
+ gpch = container_of(chip, struct au1000_gpio_chip, chip);
+
+ local_irq_save(flags);
+ tmp = readl(gpch->regbase + AU1000_GPIO2_DIR);
+ tmp |= mask;
+ writel(tmp, gpch->regbase + AU1000_GPIO2_DIR);
+ writel(out_mask, gpch->regbase + AU1000_GPIO2_OUT);
+ local_irq_restore(flags);
+
return 0;
}
-
#endif /* !defined(CONFIG_SOC_AU1000) */
-static int au1xxx_gpio1_read(unsigned gpio)
+static int au1000_gpio1_get(struct gpio_chip *chip, unsigned offset)
{
- return (gpio1->pinstaterd >> gpio) & 0x01;
+ u32 mask = 1 << offset;
+ struct au1000_gpio_chip *gpch;
+
+ gpch = container_of(chip, struct au1000_gpio_chip, chip);
+ return readl(gpch->regbase + AU1000_GPIO1_ST) & mask;
}
-static void au1xxx_gpio1_write(unsigned gpio, int value)
+static void au1000_gpio1_set(struct gpio_chip *chip,
+ unsigned offset, int value)
{
+ u32 mask = 1 << offset;
+ u32 reg_offset;
+ struct au1000_gpio_chip *gpch;
+ unsigned long flags;
+
+ gpch = container_of(chip, struct au1000_gpio_chip, chip);
+
if (value)
- gpio1->outputset = (0x01 << gpio);
+ reg_offset = AU1000_GPIO1_OUT;
else
- /* Output a zero */
- gpio1->outputclr = (0x01 << gpio);
-}
+ reg_offset = AU1000_GPIO1_CLR;
-static int au1xxx_gpio1_direction_input(unsigned gpio)
-{
- gpio1->pininputen = (0x01 << gpio);
- return 0;
+ local_irq_save(flags);
+ writel(mask, gpch->regbase + reg_offset);
+ local_irq_restore(flags);
}
-static int au1xxx_gpio1_direction_output(unsigned gpio, int value)
+static int au1000_gpio1_direction_input(struct gpio_chip *chip, unsigned offset)
{
- gpio1->trioutclr = (0x01 & gpio);
- au1xxx_gpio1_write(gpio, value);
+ u32 mask = 1 << offset;
+ struct au1000_gpio_chip *gpch;
+
+ gpch = container_of(chip, struct au1000_gpio_chip, chip);
+ writel(mask, gpch->regbase + AU1000_GPIO1_ST);
+
return 0;
}
-int au1xxx_gpio_get_value(unsigned gpio)
+static int au1000_gpio1_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
{
- if (gpio >= AU1XXX_GPIO_BASE)
-#if defined(CONFIG_SOC_AU1000)
- return 0;
-#else
- return au1xxx_gpio2_read(gpio);
-#endif
- else
- return au1xxx_gpio1_read(gpio);
-}
-EXPORT_SYMBOL(au1xxx_gpio_get_value);
+ u32 mask = 1 << offset;
+ struct au1000_gpio_chip *gpch;
-void au1xxx_gpio_set_value(unsigned gpio, int value)
-{
- if (gpio >= AU1XXX_GPIO_BASE)
-#if defined(CONFIG_SOC_AU1000)
- ;
-#else
- au1xxx_gpio2_write(gpio, value);
-#endif
- else
- au1xxx_gpio1_write(gpio, value);
-}
-EXPORT_SYMBOL(au1xxx_gpio_set_value);
+ gpch = container_of(chip, struct au1000_gpio_chip, chip);
-int au1xxx_gpio_direction_input(unsigned gpio)
-{
- if (gpio >= AU1XXX_GPIO_BASE)
-#if defined(CONFIG_SOC_AU1000)
- return -ENODEV;
-#else
- return au1xxx_gpio2_direction_input(gpio);
-#endif
+ writel(mask, gpch->regbase + AU1000_GPIO1_TRI_OUT);
+ au1000_gpio1_set(chip, offset, value);
- return au1xxx_gpio1_direction_input(gpio);
+ return 0;
}
-EXPORT_SYMBOL(au1xxx_gpio_direction_input);
-int au1xxx_gpio_direction_output(unsigned gpio, int value)
+struct au1000_gpio_chip au1000_gpio_chip[] = {
+ [0] = {
+ .regbase = (void __iomem *)SYS_BASE,
+ .chip = {
+ .label = "au1000-gpio1",
+ .direction_input = au1000_gpio1_direction_input,
+ .direction_output = au1000_gpio1_direction_output,
+ .get = au1000_gpio1_get,
+ .set = au1000_gpio1_set,
+ .base = 0,
+ .ngpio = 32,
+ },
+ },
+#if !defined(CONFIG_SOC_AU1000)
+ [1] = {
+ .regbase = (void __iomem *)GPIO2_BASE,
+ .chip = {
+ .label = "au1000-gpio2",
+ .direction_input = au1000_gpio2_direction_input,
+ .direction_output = au1000_gpio2_direction_output,
+ .get = au1000_gpio2_get,
+ .set = au1000_gpio2_set,
+ .base = AU1XXX_GPIO_BASE,
+ .ngpio = 32,
+ },
+ },
+#endif
+};
+
+static int __init au1000_gpio_init(void)
{
- if (gpio >= AU1XXX_GPIO_BASE)
-#if defined(CONFIG_SOC_AU1000)
- return -ENODEV;
-#else
- return au1xxx_gpio2_direction_output(gpio, value);
+ gpiochip_add(&au1000_gpio_chip[0].chip);
+#if !defined(CONFIG_SOC_AU1000)
+ gpiochip_add(&au1000_gpio_chip[1].chip);
#endif
- return au1xxx_gpio1_direction_output(gpio, value);
+ return 0;
}
-EXPORT_SYMBOL(au1xxx_gpio_direction_output);
+arch_initcall(au1000_gpio_init);
+
diff --git a/arch/mips/alchemy/devboards/pb1200/platform.c b/arch/mips/alchemy/devboards/pb1200/platform.c
index 95303297c534..0d68e1985ffd 100644
--- a/arch/mips/alchemy/devboards/pb1200/platform.c
+++ b/arch/mips/alchemy/devboards/pb1200/platform.c
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/leds.h>
#include <linux/platform_device.h>
+#include <linux/smc91x.h>
#include <asm/mach-au1x00/au1xxx.h>
#include <asm/mach-au1x00/au1100_mmc.h>
@@ -131,6 +132,12 @@ static struct platform_device ide_device = {
.resource = ide_resources
};
+static struct smc91x_platdata smc_data = {
+ .flags = SMC91X_NOWAIT | SMC91X_USE_16BIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
static struct resource smc91c111_resources[] = {
[0] = {
.name = "smc91x-regs",
@@ -146,6 +153,9 @@ static struct resource smc91c111_resources[] = {
};
static struct platform_device smc91c111_device = {
+ .dev = {
+ .platform_data = &smc_data,
+ },
.name = "smc91x",
.id = -1,
.num_resources = ARRAY_SIZE(smc91c111_resources),
diff --git a/arch/mips/basler/excite/excite_iodev.c b/arch/mips/basler/excite/excite_iodev.c
index a1e3526b4a94..dfbfd7e2ac08 100644
--- a/arch/mips/basler/excite/excite_iodev.c
+++ b/arch/mips/basler/excite/excite_iodev.c
@@ -33,8 +33,8 @@
static const struct resource *iodev_get_resource(struct platform_device *, const char *, unsigned int);
-static int __init iodev_probe(struct device *);
-static int __exit iodev_remove(struct device *);
+static int __init iodev_probe(struct platform_device *);
+static int __exit iodev_remove(struct platform_device *);
static int iodev_open(struct inode *, struct file *);
static int iodev_release(struct inode *, struct file *);
static ssize_t iodev_read(struct file *, char __user *, size_t s, loff_t *);
@@ -65,13 +65,13 @@ static struct miscdevice miscdev =
.fops = &fops
};
-static struct device_driver iodev_driver =
-{
- .name = (char *) iodev_name,
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
+static struct platform_driver iodev_driver = {
+ .driver = {
+ .name = iodev_name,
+ .owner = THIS_MODULE,
+ },
.probe = iodev_probe,
- .remove = __exit_p(iodev_remove)
+ .remove = __devexit_p(iodev_remove),
};
@@ -89,11 +89,10 @@ iodev_get_resource(struct platform_device *pdv, const char *name,
/* No hotplugging on the platform bus - use __init */
-static int __init iodev_probe(struct device *dev)
+static int __init iodev_probe(struct platform_device *dev)
{
- struct platform_device * const pdv = to_platform_device(dev);
const struct resource * const ri =
- iodev_get_resource(pdv, IODEV_RESOURCE_IRQ, IORESOURCE_IRQ);
+ iodev_get_resource(dev, IODEV_RESOURCE_IRQ, IORESOURCE_IRQ);
if (unlikely(!ri))
return -ENXIO;
@@ -104,7 +103,7 @@ static int __init iodev_probe(struct device *dev)
-static int __exit iodev_remove(struct device *dev)
+static int __exit iodev_remove(struct platform_device *dev)
{
return misc_deregister(&miscdev);
}
@@ -160,14 +159,14 @@ static irqreturn_t iodev_irqhdl(int irq, void *ctxt)
static int __init iodev_init_module(void)
{
- return driver_register(&iodev_driver);
+ return platform_driver_register(&iodev_driver);
}
static void __exit iodev_cleanup_module(void)
{
- driver_unregister(&iodev_driver);
+ platform_driver_unregister(&iodev_driver);
}
module_init(iodev_init_module);
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index 1c2a7faf5881..d6903c3f3d51 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -14,3 +14,5 @@ obj-y += dma-octeon.o flash_setup.o
obj-y += octeon-memcpy.o
obj-$(CONFIG_SMP) += smp.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/cavium-octeon/flash_setup.c b/arch/mips/cavium-octeon/flash_setup.c
index 553d36cbcc42..008f657116eb 100644
--- a/arch/mips/cavium-octeon/flash_setup.c
+++ b/arch/mips/cavium-octeon/flash_setup.c
@@ -57,7 +57,7 @@ static int __init flash_init(void)
flash_map.bankwidth = 1;
flash_map.virt = ioremap(flash_map.phys, flash_map.size);
pr_notice("Bootbus flash: Setting flash for %luMB flash at "
- "0x%08lx\n", flash_map.size >> 20, flash_map.phys);
+ "0x%08llx\n", flash_map.size >> 20, flash_map.phys);
simple_map_init(&flash_map);
mymtd = do_map_probe("cfi_probe", &flash_map);
if (mymtd) {
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index fc72984a5dae..1c19af8daa62 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -31,7 +31,7 @@ static void octeon_irq_core_ack(unsigned int irq)
static void octeon_irq_core_eoi(unsigned int irq)
{
- irq_desc_t *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_desc + irq;
unsigned int bit = irq - OCTEON_IRQ_SW0;
/*
* If an IRQ is being processed while we are disabling it the
diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c
index ac4fb912649d..cb9bf820fe53 100644
--- a/arch/mips/cobalt/irq.c
+++ b/arch/mips/cobalt/irq.c
@@ -47,7 +47,6 @@ asmlinkage void plat_irq_dispatch(void)
static struct irqaction cascade = {
.handler = no_action,
- .mask = CPU_MASK_NONE,
.name = "cascade",
};
diff --git a/arch/mips/emma/markeins/irq.c b/arch/mips/emma/markeins/irq.c
index c2583ecc93cf..43828ae796ec 100644
--- a/arch/mips/emma/markeins/irq.c
+++ b/arch/mips/emma/markeins/irq.c
@@ -80,9 +80,9 @@ void emma2rh_irq_init(void)
u32 i;
for (i = 0; i < NUM_EMMA2RH_IRQ; i++)
- set_irq_chip_and_handler(EMMA2RH_IRQ_BASE + i,
- &emma2rh_irq_controller,
- handle_level_irq);
+ set_irq_chip_and_handler_name(EMMA2RH_IRQ_BASE + i,
+ &emma2rh_irq_controller,
+ handle_level_irq, "level");
}
static void emma2rh_sw_irq_enable(unsigned int irq)
@@ -120,9 +120,9 @@ void emma2rh_sw_irq_init(void)
u32 i;
for (i = 0; i < NUM_EMMA2RH_IRQ_SW; i++)
- set_irq_chip_and_handler(EMMA2RH_SW_IRQ_BASE + i,
- &emma2rh_sw_irq_controller,
- handle_level_irq);
+ set_irq_chip_and_handler_name(EMMA2RH_SW_IRQ_BASE + i,
+ &emma2rh_sw_irq_controller,
+ handle_level_irq, "level");
}
static void emma2rh_gpio_irq_enable(unsigned int irq)
@@ -149,37 +149,28 @@ static void emma2rh_gpio_irq_disable(unsigned int irq)
static void emma2rh_gpio_irq_ack(unsigned int irq)
{
- u32 reg;
-
irq -= EMMA2RH_GPIO_IRQ_BASE;
emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
-
- reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
- reg &= ~(1 << irq);
- emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
}
-static void emma2rh_gpio_irq_end(unsigned int irq)
+static void emma2rh_gpio_irq_mask_ack(unsigned int irq)
{
u32 reg;
- if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
-
- irq -= EMMA2RH_GPIO_IRQ_BASE;
+ irq -= EMMA2RH_GPIO_IRQ_BASE;
+ emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq));
- reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
- reg |= 1 << irq;
- emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
- }
+ reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
+ reg &= ~(1 << irq);
+ emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg);
}
struct irq_chip emma2rh_gpio_irq_controller = {
.name = "emma2rh_gpio_irq",
.ack = emma2rh_gpio_irq_ack,
.mask = emma2rh_gpio_irq_disable,
- .mask_ack = emma2rh_gpio_irq_ack,
+ .mask_ack = emma2rh_gpio_irq_mask_ack,
.unmask = emma2rh_gpio_irq_enable,
- .end = emma2rh_gpio_irq_end,
};
void emma2rh_gpio_irq_init(void)
@@ -187,14 +178,14 @@ void emma2rh_gpio_irq_init(void)
u32 i;
for (i = 0; i < NUM_EMMA2RH_IRQ_GPIO; i++)
- set_irq_chip(EMMA2RH_GPIO_IRQ_BASE + i,
- &emma2rh_gpio_irq_controller);
+ set_irq_chip_and_handler_name(EMMA2RH_GPIO_IRQ_BASE + i,
+ &emma2rh_gpio_irq_controller,
+ handle_edge_irq, "edge");
}
static struct irqaction irq_cascade = {
.handler = no_action,
.flags = 0,
- .mask = CPU_MASK_NONE,
.name = "cascade",
.dev_id = NULL,
.next = NULL,
@@ -213,8 +204,7 @@ void emma2rh_irq_dispatch(void)
emma2rh_in32(EMMA2RH_BHIF_INT_EN_0);
#ifdef EMMA2RH_SW_CASCADE
- if (intStatus &
- (1 << ((EMMA2RH_SW_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) {
+ if (intStatus & (1UL << EMMA2RH_SW_CASCADE)) {
u32 swIntStatus;
swIntStatus = emma2rh_in32(EMMA2RH_BHIF_SW_INT)
& emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN);
@@ -225,6 +215,8 @@ void emma2rh_irq_dispatch(void)
}
}
}
+ /* Skip S/W interrupt */
+ intStatus &= ~(1UL << EMMA2RH_SW_CASCADE);
#endif
for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) {
@@ -238,8 +230,7 @@ void emma2rh_irq_dispatch(void)
emma2rh_in32(EMMA2RH_BHIF_INT_EN_1);
#ifdef EMMA2RH_GPIO_CASCADE
- if (intStatus &
- (1 << ((EMMA2RH_GPIO_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) {
+ if (intStatus & (1UL << (EMMA2RH_GPIO_CASCADE % 32))) {
u32 gpioIntStatus;
gpioIntStatus = emma2rh_in32(EMMA2RH_GPIO_INT_ST)
& emma2rh_in32(EMMA2RH_GPIO_INT_MASK);
@@ -250,6 +241,8 @@ void emma2rh_irq_dispatch(void)
}
}
}
+ /* Skip GPIO interrupt */
+ intStatus &= ~(1UL << (EMMA2RH_GPIO_CASCADE % 32));
#endif
for (i = 32, bitmask = 1; i < 64; i++, bitmask <<= 1) {
diff --git a/arch/mips/emma/markeins/platform.c b/arch/mips/emma/markeins/platform.c
index d5f47e4f0d18..80ae12ef87db 100644
--- a/arch/mips/emma/markeins/platform.c
+++ b/arch/mips/emma/markeins/platform.c
@@ -110,6 +110,7 @@ struct platform_device i2c_emma_devices[] = {
static struct plat_serial8250_port platform_serial_ports[] = {
[0] = {
.membase= (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3),
+ .mapbase = EMMA2RH_PFUR0_BASE + 3,
.irq = EMMA2RH_IRQ_PFUR0,
.uartclk = EMMA2RH_SERIAL_CLOCK,
.regshift = 4,
@@ -117,6 +118,7 @@ static struct plat_serial8250_port platform_serial_ports[] = {
.flags = EMMA2RH_SERIAL_FLAGS,
}, [1] = {
.membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3),
+ .mapbase = EMMA2RH_PFUR1_BASE + 3,
.irq = EMMA2RH_IRQ_PFUR1,
.uartclk = EMMA2RH_SERIAL_CLOCK,
.regshift = 4,
@@ -124,6 +126,7 @@ static struct plat_serial8250_port platform_serial_ports[] = {
.flags = EMMA2RH_SERIAL_FLAGS,
}, [2] = {
.membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3),
+ .mapbase = EMMA2RH_PFUR2_BASE + 3,
.irq = EMMA2RH_IRQ_PFUR2,
.uartclk = EMMA2RH_SERIAL_CLOCK,
.regshift = 4,
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index c018727c7ddc..3bdc0e3d89cc 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -209,8 +209,7 @@ enum cpu_type_enum {
* MIPS32 class processors
*/
CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
- CPU_AU1000, CPU_AU1100, CPU_AU1200, CPU_AU1210, CPU_AU1250, CPU_AU1500,
- CPU_AU1550, CPU_PR4450, CPU_BCM3302, CPU_BCM4710,
+ CPU_ALCHEMY, CPU_PR4450, CPU_BCM3302, CPU_BCM4710,
/*
* MIPS64 class processors
diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h
index 134e1fc8f4d6..a12d971db4f9 100644
--- a/arch/mips/include/asm/hazards.h
+++ b/arch/mips/include/asm/hazards.h
@@ -87,7 +87,7 @@ do { \
: "=r" (tmp)); \
} while (0)
-#elif defined(CONFIG_CPU_MIPSR1)
+#elif defined(CONFIG_CPU_MIPSR1) && !defined(CONFIG_MACH_ALCHEMY)
/*
* These are slightly complicated by the fact that we guarantee R1 kernels to
@@ -139,7 +139,7 @@ do { \
} while (0)
#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \
- defined(CONFIG_CPU_R5500)
+ defined(CONFIG_CPU_R5500) || defined(CONFIG_MACH_ALCHEMY)
/*
* R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
diff --git a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
new file mode 100644
index 000000000000..d5df0cab9b87
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
@@ -0,0 +1,49 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 1
+#define cpu_has_tx39_cache 0
+#define cpu_has_fpu 0
+#define cpu_has_counter 1
+#define cpu_has_watch 1
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_mcheck 1
+#define cpu_has_ejtag 1
+#define cpu_has_llsc 1
+#define cpu_has_mips16 0
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+#define cpu_has_vtag_icache 0
+#define cpu_has_dc_aliases 0
+#define cpu_has_ic_fills_f_dc 1
+#define cpu_has_mips32r1 1
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+#define cpu_has_nofpuex 0
+#define cpu_has_64bits 0
+#define cpu_has_64bit_zero_reg 0
+#define cpu_has_vint 0
+#define cpu_has_veic 0
+#define cpu_has_inclusive_pcaches 0
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+
+#endif /* __ASM_MACH_AU1X00_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-au1x00/gpio.h b/arch/mips/include/asm/mach-au1x00/gpio.h
index 2dc61e009a08..34d9b7279024 100644
--- a/arch/mips/include/asm/mach-au1x00/gpio.h
+++ b/arch/mips/include/asm/mach-au1x00/gpio.h
@@ -5,65 +5,29 @@
#define AU1XXX_GPIO_BASE 200
-struct au1x00_gpio2 {
- u32 dir;
- u32 reserved;
- u32 output;
- u32 pinstate;
- u32 inten;
- u32 enable;
-};
+/* GPIO bank 1 offsets */
+#define AU1000_GPIO1_TRI_OUT 0x0100
+#define AU1000_GPIO1_OUT 0x0108
+#define AU1000_GPIO1_ST 0x0110
+#define AU1000_GPIO1_CLR 0x010C
-extern int au1xxx_gpio_get_value(unsigned gpio);
-extern void au1xxx_gpio_set_value(unsigned gpio, int value);
-extern int au1xxx_gpio_direction_input(unsigned gpio);
-extern int au1xxx_gpio_direction_output(unsigned gpio, int value);
+/* GPIO bank 2 offsets */
+#define AU1000_GPIO2_DIR 0x00
+#define AU1000_GPIO2_RSVD 0x04
+#define AU1000_GPIO2_OUT 0x08
+#define AU1000_GPIO2_ST 0x0C
+#define AU1000_GPIO2_INT 0x10
+#define AU1000_GPIO2_EN 0x14
+#define GPIO2_OUT_EN_MASK 0x00010000
-/* Wrappers for the arch-neutral GPIO API */
+#define gpio_to_irq(gpio) NULL
-static inline int gpio_request(unsigned gpio, const char *label)
-{
- /* Not yet implemented */
- return 0;
-}
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
-static inline void gpio_free(unsigned gpio)
-{
- /* Not yet implemented */
-}
+#define gpio_cansleep __gpio_cansleep
-static inline int gpio_direction_input(unsigned gpio)
-{
- return au1xxx_gpio_direction_input(gpio);
-}
-
-static inline int gpio_direction_output(unsigned gpio, int value)
-{
- return au1xxx_gpio_direction_output(gpio, value);
-}
-
-static inline int gpio_get_value(unsigned gpio)
-{
- return au1xxx_gpio_get_value(gpio);
-}
-
-static inline void gpio_set_value(unsigned gpio, int value)
-{
- au1xxx_gpio_set_value(gpio, value);
-}
-
-static inline int gpio_to_irq(unsigned gpio)
-{
- return gpio;
-}
-
-static inline int irq_to_gpio(unsigned irq)
-{
- return irq;
-}
-
-/* For cansleep */
#include <asm-generic/gpio.h>
#endif /* _AU1XXX_GPIO_H_ */
diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h
index d8ff4cd89ab5..1784fde2e28f 100644
--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
@@ -31,24 +31,28 @@ static inline void gpio_set_value(unsigned gpio, int value)
static inline int gpio_direction_input(unsigned gpio)
{
- return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0);
+ ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0);
+ return 0;
}
static inline int gpio_direction_output(unsigned gpio, int value)
{
- return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
+ ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
+ return 0;
}
-static int gpio_intmask(unsigned gpio, int value)
+static inline int gpio_intmask(unsigned gpio, int value)
{
- return ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio,
- value ? 1 << gpio : 0);
+ ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio,
+ value ? 1 << gpio : 0);
+ return 0;
}
-static int gpio_polarity(unsigned gpio, int value)
+static inline int gpio_polarity(unsigned gpio, int value)
{
- return ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio,
- value ? 1 << gpio : 0);
+ ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio,
+ value ? 1 << gpio : 0);
+ return 0;
}
diff --git a/arch/mips/include/asm/mach-ip27/topology.h b/arch/mips/include/asm/mach-ip27/topology.h
index 55d481569a1f..07547231e078 100644
--- a/arch/mips/include/asm/mach-ip27/topology.h
+++ b/arch/mips/include/asm/mach-ip27/topology.h
@@ -26,7 +26,6 @@ extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];
#define parent_node(node) (node)
#define node_to_cpumask(node) (hub_data(node)->h_cpus)
#define cpumask_of_node(node) (&hub_data(node)->h_cpus)
-#define node_to_first_cpu(node) (cpumask_first(cpumask_of_node(node)))
struct pci_bus;
extern int pcibus_to_node(struct pci_bus *);
diff --git a/arch/mips/include/asm/mips-boards/generic.h b/arch/mips/include/asm/mips-boards/generic.h
index 7f0b034dd9a5..c0da1a881e3d 100644
--- a/arch/mips/include/asm/mips-boards/generic.h
+++ b/arch/mips/include/asm/mips-boards/generic.h
@@ -71,8 +71,6 @@
#define MIPS_REVISION_CORID (((*(volatile u32 *)ioremap(MIPS_REVISION_REG, 4)) >> 10) & 0x3f)
-extern int mips_revision_corid;
-
#define MIPS_REVISION_SCON_OTHER 0
#define MIPS_REVISION_SCON_SOCITSC 1
#define MIPS_REVISION_SCON_SOCITSCP 2
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 0417516503f6..526f327475ce 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -1391,11 +1391,11 @@ static inline void tlb_write_random(void)
static inline unsigned int \
set_c0_##name(unsigned int set) \
{ \
- unsigned int res; \
+ unsigned int res, new; \
\
res = read_c0_##name(); \
- res |= set; \
- write_c0_##name(res); \
+ new = res | set; \
+ write_c0_##name(new); \
\
return res; \
} \
@@ -1403,24 +1403,24 @@ set_c0_##name(unsigned int set) \
static inline unsigned int \
clear_c0_##name(unsigned int clear) \
{ \
- unsigned int res; \
+ unsigned int res, new; \
\
res = read_c0_##name(); \
- res &= ~clear; \
- write_c0_##name(res); \
+ new = res & ~clear; \
+ write_c0_##name(new); \
\
return res; \
} \
\
static inline unsigned int \
-change_c0_##name(unsigned int change, unsigned int new) \
+change_c0_##name(unsigned int change, unsigned int val) \
{ \
- unsigned int res; \
+ unsigned int res, new; \
\
res = read_c0_##name(); \
- res &= ~change; \
- res |= (new & change); \
- write_c0_##name(res); \
+ new = res & ~change; \
+ new |= (val & change); \
+ write_c0_##name(new); \
\
return res; \
}
diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h
index 43c207e72a63..64ffc0290b84 100644
--- a/arch/mips/include/asm/smp-ops.h
+++ b/arch/mips/include/asm/smp-ops.h
@@ -15,6 +15,8 @@
#include <linux/cpumask.h>
+struct task_struct;
+
struct plat_smp_ops {
void (*send_ipi_single)(int cpu, unsigned int action);
void (*send_ipi_mask)(cpumask_t mask, unsigned int action);
diff --git a/arch/mips/include/asm/socket.h b/arch/mips/include/asm/socket.h
index facc2d7a87ca..2abca1780169 100644
--- a/arch/mips/include/asm/socket.h
+++ b/arch/mips/include/asm/socket.h
@@ -75,6 +75,9 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
#ifdef __KERNEL__
/** sock_type - Socket types
diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h
index 0884947ebe27..5b60a09a0f08 100644
--- a/arch/mips/include/asm/spinlock.h
+++ b/arch/mips/include/asm/spinlock.h
@@ -76,7 +76,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
"2: \n"
" .subsection 2 \n"
"4: andi %[ticket], %[ticket], 0x1fff \n"
- "5: sll %[ticket], 5 \n"
+ " sll %[ticket], 5 \n"
" \n"
"6: bnez %[ticket], 6b \n"
" subu %[ticket], 1 \n"
@@ -85,7 +85,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
" andi %[ticket], %[ticket], 0x1fff \n"
" beq %[ticket], %[my_ticket], 2b \n"
" subu %[ticket], %[my_ticket], %[ticket] \n"
- " b 5b \n"
+ " b 4b \n"
" subu %[ticket], %[ticket], 1 \n"
" .previous \n"
" .set pop \n"
@@ -113,7 +113,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
" ll %[ticket], %[ticket_ptr] \n"
" \n"
"4: andi %[ticket], %[ticket], 0x1fff \n"
- "5: sll %[ticket], 5 \n"
+ " sll %[ticket], 5 \n"
" \n"
"6: bnez %[ticket], 6b \n"
" subu %[ticket], 1 \n"
@@ -122,7 +122,7 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
" andi %[ticket], %[ticket], 0x1fff \n"
" beq %[ticket], %[my_ticket], 2b \n"
" subu %[ticket], %[my_ticket], %[ticket] \n"
- " b 5b \n"
+ " b 4b \n"
" subu %[ticket], %[ticket], 1 \n"
" .previous \n"
" .set pop \n"
@@ -480,6 +480,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
return ret;
}
+#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
+#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
#define _raw_spin_relax(lock) cpu_relax()
#define _raw_read_relax(lock) cpu_relax()
diff --git a/arch/mips/include/asm/txx9/ndfmc.h b/arch/mips/include/asm/txx9/ndfmc.h
new file mode 100644
index 000000000000..fa67f3df78fc
--- /dev/null
+++ b/arch/mips/include/asm/txx9/ndfmc.h
@@ -0,0 +1,30 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (C) Copyright TOSHIBA CORPORATION 2007
+ */
+#ifndef __ASM_TXX9_NDFMC_H
+#define __ASM_TXX9_NDFMC_H
+
+#define NDFMC_PLAT_FLAG_USE_BSPRT 0x01
+#define NDFMC_PLAT_FLAG_NO_RSTR 0x02
+#define NDFMC_PLAT_FLAG_HOLDADD 0x04
+#define NDFMC_PLAT_FLAG_DUMMYWRITE 0x08
+
+struct txx9ndfmc_platform_data {
+ unsigned int shift;
+ unsigned int gbus_clock;
+ unsigned int hold; /* hold time in nanosecond */
+ unsigned int spw; /* strobe pulse width in nanosecond */
+ unsigned int flags;
+ unsigned char ch_mask; /* available channel bitmask */
+ unsigned char wp_mask; /* write-protect bitmask */
+ unsigned char wide_mask; /* 16bit-nand bitmask */
+};
+
+void txx9_ndfmc_init(unsigned long baseaddr,
+ const struct txx9ndfmc_platform_data *plat_data);
+
+#endif /* __ASM_TXX9_NDFMC_H */
diff --git a/arch/mips/include/asm/txx9/rbtx4939.h b/arch/mips/include/asm/txx9/rbtx4939.h
index 1acf428c0b4f..e517899794a8 100644
--- a/arch/mips/include/asm/txx9/rbtx4939.h
+++ b/arch/mips/include/asm/txx9/rbtx4939.h
@@ -130,4 +130,13 @@
void rbtx4939_prom_init(void);
void rbtx4939_irq_setup(void);
+struct mtd_partition;
+struct map_info;
+struct rbtx4939_flash_data {
+ unsigned int width;
+ unsigned int nr_parts;
+ struct mtd_partition *parts;
+ void (*map_init)(struct map_info *map);
+};
+
#endif /* __ASM_TXX9_RBTX4939_H */
diff --git a/arch/mips/include/asm/txx9/tx4938.h b/arch/mips/include/asm/txx9/tx4938.h
index 0b068154054c..cd8bc2021755 100644
--- a/arch/mips/include/asm/txx9/tx4938.h
+++ b/arch/mips/include/asm/txx9/tx4938.h
@@ -291,6 +291,7 @@ int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot);
void tx4938_setup_pcierr_irq(void);
void tx4938_irq_init(void);
void tx4938_mtd_init(int ch);
+void tx4938_ndfmc_init(unsigned int hold, unsigned int spw);
struct tx4938ide_platform_info {
/*
diff --git a/arch/mips/include/asm/txx9/tx4939.h b/arch/mips/include/asm/txx9/tx4939.h
index 964ef7ede268..f02c50b3abfb 100644
--- a/arch/mips/include/asm/txx9/tx4939.h
+++ b/arch/mips/include/asm/txx9/tx4939.h
@@ -542,5 +542,7 @@ int tx4939_irq(void);
void tx4939_mtd_init(int ch);
void tx4939_ata_init(void);
void tx4939_rtc_init(void);
+void tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
+ unsigned char ch_mask, unsigned char wide_mask);
#endif /* __ASM_TXX9_TX4939_H */
diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h
index bcbb8d675af5..7956e69a3bd5 100644
--- a/arch/mips/include/asm/types.h
+++ b/arch/mips/include/asm/types.h
@@ -4,12 +4,18 @@
* for more details.
*
* Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
+ * Copyright (C) 2008 Wind River Systems,
+ * written by Ralf Baechle
* Copyright (C) 1999 Silicon Graphics, Inc.
*/
#ifndef _ASM_TYPES_H
#define _ASM_TYPES_H
-#if _MIPS_SZLONG == 64
+/*
+ * We don't use int-l64.h for the kernel anymore but still use it for
+ * userspace to avoid code changes.
+ */
+#if (_MIPS_SZLONG == 64) && !defined(__KERNEL__)
# include <asm-generic/int-l64.h>
#else
# include <asm-generic/int-ll64.h>
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index a73e1531e151..40005010827c 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -350,16 +350,18 @@
#define __NR_dup3 (__NR_Linux + 327)
#define __NR_pipe2 (__NR_Linux + 328)
#define __NR_inotify_init1 (__NR_Linux + 329)
+#define __NR_preadv (__NR_Linux + 330)
+#define __NR_pwritev (__NR_Linux + 331)
/*
* Offset of the last Linux o32 flavoured syscall
*/
-#define __NR_Linux_syscalls 329
+#define __NR_Linux_syscalls 331
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
#define __NR_O32_Linux 4000
-#define __NR_O32_Linux_syscalls 329
+#define __NR_O32_Linux_syscalls 331
#if _MIPS_SIM == _MIPS_SIM_ABI64
@@ -656,16 +658,18 @@
#define __NR_dup3 (__NR_Linux + 286)
#define __NR_pipe2 (__NR_Linux + 287)
#define __NR_inotify_init1 (__NR_Linux + 288)
+#define __NR_preadv (__NR_Linux + 289)
+#define __NR_pwritev (__NR_Linux + 290)
/*
* Offset of the last Linux 64-bit flavoured syscall
*/
-#define __NR_Linux_syscalls 288
+#define __NR_Linux_syscalls 290
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
#define __NR_64_Linux 5000
-#define __NR_64_Linux_syscalls 288
+#define __NR_64_Linux_syscalls 290
#if _MIPS_SIM == _MIPS_SIM_NABI32
@@ -966,16 +970,18 @@
#define __NR_dup3 (__NR_Linux + 290)
#define __NR_pipe2 (__NR_Linux + 291)
#define __NR_inotify_init1 (__NR_Linux + 292)
+#define __NR_preadv (__NR_Linux + 293)
+#define __NR_pwritev (__NR_Linux + 294)
/*
* Offset of the last N32 flavoured syscall
*/
-#define __NR_Linux_syscalls 292
+#define __NR_Linux_syscalls 294
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
#define __NR_N32_Linux 6000
-#define __NR_N32_Linux_syscalls 292
+#define __NR_N32_Linux_syscalls 294
#ifdef __KERNEL__
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index 03965cb1b252..d9b6a5b5399d 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -134,7 +134,6 @@ static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id)
static struct irqaction r4030_timer_irqaction = {
.handler = r4030_timer_interrupt,
.flags = IRQF_DISABLED,
- .mask = CPU_MASK_CPU0,
.name = "R4030 timer",
};
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c
index c672c08d49e5..f0fd636723be 100644
--- a/arch/mips/jazz/jazzdma.c
+++ b/arch/mips/jazz/jazzdma.c
@@ -68,8 +68,7 @@ static int __init vdma_init(void)
*/
pgtbl = (VDMA_PGTBL_ENTRY *)__get_free_pages(GFP_KERNEL | GFP_DMA,
get_order(VDMA_PGTBL_SIZE));
- if (!pgtbl)
- BUG();
+ BUG_ON(!pgtbl);
dma_cache_wback_inv((unsigned long)pgtbl, VDMA_PGTBL_SIZE);
pgtbl = (VDMA_PGTBL_ENTRY *)KSEG1ADDR(pgtbl);
diff --git a/arch/mips/kernel/cevt-bcm1480.c b/arch/mips/kernel/cevt-bcm1480.c
index b820661678b0..a5182a207696 100644
--- a/arch/mips/kernel/cevt-bcm1480.c
+++ b/arch/mips/kernel/cevt-bcm1480.c
@@ -144,7 +144,6 @@ void __cpuinit sb1480_clockevent_init(void)
action->handler = sibyte_counter_handler;
action->flags = IRQF_DISABLED | IRQF_PERCPU;
- action->mask = cpumask_of_cpu(cpu);
action->name = name;
action->dev_id = cd;
diff --git a/arch/mips/kernel/cevt-sb1250.c b/arch/mips/kernel/cevt-sb1250.c
index a2eebaafda52..340f53e5c6b1 100644
--- a/arch/mips/kernel/cevt-sb1250.c
+++ b/arch/mips/kernel/cevt-sb1250.c
@@ -143,7 +143,6 @@ void __cpuinit sb1250_clockevent_init(void)
action->handler = sibyte_counter_handler;
action->flags = IRQF_DISABLED | IRQF_PERCPU;
- action->mask = cpumask_of_cpu(cpu);
action->name = name;
action->dev_id = cd;
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 1bdbcad3bb74..b13b8eb30596 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -183,13 +183,7 @@ void __init check_wait(void)
case CPU_TX49XX:
cpu_wait = r4k_wait_irqoff;
break;
- case CPU_AU1000:
- case CPU_AU1100:
- case CPU_AU1500:
- case CPU_AU1550:
- case CPU_AU1200:
- case CPU_AU1210:
- case CPU_AU1250:
+ case CPU_ALCHEMY:
cpu_wait = au1k_wait;
break;
case CPU_20KC:
@@ -783,37 +777,30 @@ static inline void cpu_probe_alchemy(struct cpuinfo_mips *c, unsigned int cpu)
switch (c->processor_id & 0xff00) {
case PRID_IMP_AU1_REV1:
case PRID_IMP_AU1_REV2:
+ c->cputype = CPU_ALCHEMY;
switch ((c->processor_id >> 24) & 0xff) {
case 0:
- c->cputype = CPU_AU1000;
__cpu_name[cpu] = "Au1000";
break;
case 1:
- c->cputype = CPU_AU1500;
__cpu_name[cpu] = "Au1500";
break;
case 2:
- c->cputype = CPU_AU1100;
__cpu_name[cpu] = "Au1100";
break;
case 3:
- c->cputype = CPU_AU1550;
__cpu_name[cpu] = "Au1550";
break;
case 4:
- c->cputype = CPU_AU1200;
__cpu_name[cpu] = "Au1200";
- if ((c->processor_id & 0xff) == 2) {
- c->cputype = CPU_AU1250;
+ if ((c->processor_id & 0xff) == 2)
__cpu_name[cpu] = "Au1250";
- }
break;
case 5:
- c->cputype = CPU_AU1210;
__cpu_name[cpu] = "Au1210";
break;
default:
- panic("Unknown Au Core!");
+ __cpu_name[cpu] = "Au1xxx";
break;
}
break;
diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c
index f4d187825f96..689719e34f08 100644
--- a/arch/mips/kernel/i8253.c
+++ b/arch/mips/kernel/i8253.c
@@ -98,7 +98,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
static struct irqaction irq0 = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_NOBALANCING,
- .mask = CPU_MASK_NONE,
.name = "timer"
};
@@ -121,7 +120,6 @@ void __init setup_pit_timer(void)
cd->min_delta_ns = clockevent_delta2ns(0xF, cd);
clockevents_register_device(cd);
- irq0.mask = cpumask_of_cpu(cpu);
setup_irq(0, &irq0);
}
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 413bd1d37f54..01c0885a8061 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -306,7 +306,6 @@ static void init_8259A(int auto_eoi)
*/
static struct irqaction irq2 = {
.handler = no_action,
- .mask = CPU_MASK_NONE,
.name = "cascade",
};
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c
index 963c16d266ab..6a8cd28133d5 100644
--- a/arch/mips/kernel/irq-msc01.c
+++ b/arch/mips/kernel/irq-msc01.c
@@ -140,14 +140,16 @@ void __init init_msc_irqs(unsigned long icubase, unsigned int irqbase, msc_irqma
switch (imp->im_type) {
case MSC01_IRQ_EDGE:
- set_irq_chip(irqbase+n, &msc_edgeirq_type);
+ set_irq_chip_and_handler_name(irqbase + n,
+ &msc_edgeirq_type, handle_edge_irq, "edge");
if (cpu_has_veic)
MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT);
else
MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl);
break;
case MSC01_IRQ_LEVEL:
- set_irq_chip(irqbase+n, &msc_levelirq_type);
+ set_irq_chip_and_handler_name(irqbase+n,
+ &msc_levelirq_type, handle_level_irq, "level");
if (cpu_has_veic)
MSCIC_WRITE(MSC01_IC_SUP+n*8, 0);
else
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 4b4007b3083a..7b845ba9dff4 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -108,7 +108,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%10u ", kstat_irqs(i));
#else
for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#endif
seq_printf(p, " %14s", irq_desc[i].chip->name);
seq_printf(p, " %s", action->name);
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index 0ee2567b780d..55c8a3ca507b 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -112,7 +112,8 @@ void __init mips_cpu_irq_init(void)
*/
if (cpu_has_mipsmt)
for (i = irq_base; i < irq_base + 2; i++)
- set_irq_chip(i, &mips_mt_cpu_irq_controller);
+ set_irq_chip_and_handler(i, &mips_mt_cpu_irq_controller,
+ handle_percpu_irq);
for (i = irq_base + 2; i < irq_base + 8; i++)
set_irq_chip_and_handler(i, &mips_cpu_irq_controller,
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 1a86f84fa947..6242bc68add7 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -32,7 +32,6 @@
#include <linux/module.h>
#include <linux/binfmts.h>
#include <linux/security.h>
-#include <linux/syscalls.h>
#include <linux/compat.h>
#include <linux/vfs.h>
#include <linux/ipc.h>
@@ -134,9 +133,9 @@ SYSCALL_DEFINE4(32_ftruncate64, unsigned long, fd, unsigned long, __dummy,
return sys_ftruncate(fd, merge_64(a2, a3));
}
-SYSCALL_DEFINE5(32_llseek, unsigned long, fd, unsigned long, offset_high,
- unsigned long, offset_low, loff_t __user *, result,
- unsigned long, origin)
+SYSCALL_DEFINE5(32_llseek, unsigned int, fd, unsigned int, offset_high,
+ unsigned int, offset_low, loff_t __user *, result,
+ unsigned int, origin)
{
return sys_llseek(fd, offset_high, offset_low, result, origin);
}
@@ -356,40 +355,6 @@ SYSCALL_DEFINE1(32_personality, unsigned long, personality)
return ret;
}
-/* ustat compatibility */
-struct ustat32 {
- compat_daddr_t f_tfree;
- compat_ino_t f_tinode;
- char f_fname[6];
- char f_fpack[6];
-};
-
-extern asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf);
-
-SYSCALL_DEFINE2(32_ustat, dev_t, dev, struct ustat32 __user *, ubuf32)
-{
- int err;
- struct ustat tmp;
- struct ustat32 tmp32;
- mm_segment_t old_fs = get_fs();
-
- set_fs(KERNEL_DS);
- err = sys_ustat(dev, (struct ustat __user *)&tmp);
- set_fs(old_fs);
-
- if (err)
- goto out;
-
- memset(&tmp32, 0, sizeof(struct ustat32));
- tmp32.f_tfree = tmp.f_tfree;
- tmp32.f_tinode = tmp.f_tinode;
-
- err = copy_to_user(ubuf32, &tmp32, sizeof(struct ustat32)) ? -EFAULT : 0;
-
-out:
- return err;
-}
-
SYSCALL_DEFINE4(32_sendfile, long, out_fd, long, in_fd,
compat_off_t __user *, offset, s32, count)
{
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index ca2e4026ad20..1eaaa450e20c 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -99,7 +99,7 @@ void flush_thread(void)
{
}
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused, struct task_struct *p, struct pt_regs *regs)
{
struct thread_info *ti = task_thread_info(p);
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 9ab70c3b5be6..0b31b9bda048 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -650,6 +650,8 @@ einval: li v0, -ENOSYS
sys sys_dup3 3
sys sys_pipe2 2
sys sys_inotify_init1 1
+ sys sys_preadv 6 /* 4330 */
+ sys sys_pwritev 6
.endm
/* We pre-compute the number of _instruction_ bytes needed to
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 9b4698667154..c647fd6e722f 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -487,4 +487,6 @@ sys_call_table:
PTR sys_dup3
PTR sys_pipe2
PTR sys_inotify_init1
+ PTR sys_preadv
+ PTR sys_pwritev /* 5390 */
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 7438e92f8a01..c2c16ef9218f 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -253,7 +253,7 @@ EXPORT(sysn32_call_table)
PTR compat_sys_utime /* 6130 */
PTR sys_mknod
PTR sys_32_personality
- PTR sys_32_ustat
+ PTR compat_sys_ustat
PTR compat_sys_statfs
PTR compat_sys_fstatfs /* 6135 */
PTR sys_sysfs
@@ -413,4 +413,6 @@ EXPORT(sysn32_call_table)
PTR sys_dup3 /* 5290 */
PTR sys_pipe2
PTR sys_inotify_init1
+ PTR sys_preadv
+ PTR sys_pwritev
.size sysn32_call_table,.-sysn32_call_table
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index b0fef4ff9827..002fac27021e 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -265,7 +265,7 @@ sys_call_table:
PTR sys_olduname
PTR sys_umask /* 4060 */
PTR sys_chroot
- PTR sys_32_ustat
+ PTR compat_sys_ustat
PTR sys_dup2
PTR sys_getppid
PTR sys_getpgrp /* 4065 */
@@ -533,4 +533,6 @@ sys_call_table:
PTR sys_dup3
PTR sys_pipe2
PTR sys_inotify_init1
+ PTR compat_sys_preadv /* 4330 */
+ PTR compat_sys_pwritev
.size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 4430a1f8fdf1..2950b97253b7 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -277,7 +277,8 @@ static void __init bootmem_init(void)
* not selected. Once that done we can determine the low bound
* of usable memory.
*/
- reserved_end = max(init_initrd(), PFN_UP(__pa_symbol(&_end)));
+ reserved_end = max(init_initrd(),
+ (unsigned long) PFN_UP(__pa_symbol(&_end)));
/*
* max_low_pfn is not a number of pages. The number of pages
diff --git a/arch/mips/kernel/smp-up.c b/arch/mips/kernel/smp-up.c
index ead6c30eeb14..878e3733bbb2 100644
--- a/arch/mips/kernel/smp-up.c
+++ b/arch/mips/kernel/smp-up.c
@@ -13,7 +13,7 @@
/*
* Send inter-processor interrupt
*/
-void up_send_ipi_single(int cpu, unsigned int action)
+static void up_send_ipi_single(int cpu, unsigned int action)
{
panic(KERN_ERR "%s called", __func__);
}
@@ -27,31 +27,31 @@ static inline void up_send_ipi_mask(cpumask_t mask, unsigned int action)
* After we've done initial boot, this function is called to allow the
* board code to clean up state, if needed
*/
-void __cpuinit up_init_secondary(void)
+static void __cpuinit up_init_secondary(void)
{
}
-void __cpuinit up_smp_finish(void)
+static void __cpuinit up_smp_finish(void)
{
}
/* Hook for after all CPUs are online */
-void up_cpus_done(void)
+static void up_cpus_done(void)
{
}
/*
* Firmware CPU startup hook
*/
-void __cpuinit up_boot_secondary(int cpu, struct task_struct *idle)
+static void __cpuinit up_boot_secondary(int cpu, struct task_struct *idle)
{
}
-void __init up_smp_setup(void)
+static void __init up_smp_setup(void)
{
}
-void __init up_prepare_cpus(unsigned int max_cpus)
+static void __init up_prepare_cpus(unsigned int max_cpus)
{
}
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 3da94704f816..c937506a03aa 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -44,7 +44,7 @@
#include <asm/mipsmtregs.h>
#endif /* CONFIG_MIPS_MT_SMTC */
-volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */
+static volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */
int __cpu_number_map[NR_CPUS]; /* Map physical to logical */
int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index b2d7041341b8..e83da174b533 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1277,8 +1277,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
u32 *w;
unsigned char *b;
- if (!cpu_has_veic && !cpu_has_vint)
- BUG();
+ BUG_ON(!cpu_has_veic && !cpu_has_vint);
if (addr == NULL) {
handler = (unsigned long) do_default_vi;
@@ -1520,7 +1519,9 @@ void __cpuinit per_cpu_trap_init(void)
#endif /* CONFIG_MIPS_MT_SMTC */
if (cpu_has_veic || cpu_has_vint) {
+ unsigned long sr = set_c0_status(ST0_BEV);
write_c0_ebase(ebase);
+ write_c0_status(sr);
/* Setting vector spacing enables EI/VI mode */
change_c0_intctl(0x3e0, VECTORSPACING);
}
@@ -1602,8 +1603,6 @@ void __cpuinit set_uncached_handler(unsigned long offset, void *addr,
#ifdef CONFIG_64BIT
unsigned long uncached_ebase = TO_UNCAC(ebase);
#endif
- if (cpu_has_mips_r2)
- uncached_ebase += (read_c0_ebase() & 0x3ffff000);
if (!addr)
panic(panic_null_cerr);
@@ -1635,9 +1634,11 @@ void __init trap_init(void)
return; /* Already done */
#endif
- if (cpu_has_veic || cpu_has_vint)
- ebase = (unsigned long) alloc_bootmem_low_pages(0x200 + VECTORSPACING*64);
- else {
+ if (cpu_has_veic || cpu_has_vint) {
+ unsigned long size = 0x200 + VECTORSPACING*64;
+ ebase = (unsigned long)
+ __alloc_bootmem(size, 1 << fls(size), 0);
+ } else {
ebase = CAC_BASE;
if (cpu_has_mips_r2)
ebase += (read_c0_ebase() & 0x3ffff000);
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
index d1ac7a25c856..1353fb135ed3 100644
--- a/arch/mips/lasat/interrupt.c
+++ b/arch/mips/lasat/interrupt.c
@@ -104,7 +104,6 @@ asmlinkage void plat_irq_dispatch(void)
static struct irqaction cascade = {
.handler = no_action,
- .mask = CPU_MASK_NONE,
.name = "cascade",
};
diff --git a/arch/mips/lemote/lm2e/irq.c b/arch/mips/lemote/lm2e/irq.c
index 3e0b7beb1009..1d0a09f3b832 100644
--- a/arch/mips/lemote/lm2e/irq.c
+++ b/arch/mips/lemote/lm2e/irq.c
@@ -92,7 +92,6 @@ asmlinkage void plat_irq_dispatch(void)
static struct irqaction cascade_irqaction = {
.handler = no_action,
- .mask = CPU_MASK_NONE,
.name = "cascade",
};
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index c43f4b26a690..58d9075e86fe 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -780,7 +780,7 @@ static void __cpuinit probe_pcache(void)
c->dcache.ways = 2;
c->dcache.waybit = 0;
- c->options |= MIPS_CPU_CACHE_CDEX_P;
+ c->options |= MIPS_CPU_CACHE_CDEX_P | MIPS_CPU_PREFETCH;
break;
case CPU_TX49XX:
@@ -1026,13 +1026,7 @@ static void __cpuinit probe_pcache(void)
c->icache.flags |= MIPS_CACHE_VTAG;
break;
- case CPU_AU1000:
- case CPU_AU1500:
- case CPU_AU1100:
- case CPU_AU1550:
- case CPU_AU1200:
- case CPU_AU1210:
- case CPU_AU1250:
+ case CPU_ALCHEMY:
c->icache.flags |= MIPS_CACHE_IC_F_DC;
break;
}
@@ -1244,7 +1238,7 @@ void au1x00_fixup_config_od(void)
/*
* Au1100 errata actually keeps silence about this bit, so we set it
* just in case for those revisions that require it to be set according
- * to arch/mips/au1000/common/cputable.c
+ * to the (now gone) cpu table.
*/
case 0x02030200: /* Au1100 AB */
case 0x02030201: /* Au1100 BA */
@@ -1314,11 +1308,10 @@ static void __cpuinit coherency_setup(void)
break;
/*
* We need to catch the early Alchemy SOCs with
- * the write-only co_config.od bit and set it back to one...
+ * the write-only co_config.od bit and set it back to one on:
+ * Au1000 rev DA, HA, HB; Au1100 AB, BA, BC, Au1500 AB
*/
- case CPU_AU1000: /* rev. DA, HA, HB */
- case CPU_AU1100: /* rev. AB, BA, BC ?? */
- case CPU_AU1500: /* rev. AB */
+ case CPU_ALCHEMY:
au1x00_fixup_config_od();
break;
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 546e6977d4ff..bed56f1ac837 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -225,7 +225,7 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
if (!plat_device_is_coherent(dev) && direction != DMA_TO_DEVICE) {
unsigned long addr;
- addr = plat_dma_addr_to_phys(dma_address);
+ addr = dma_addr_to_virt(dma_address);
dma_cache_wback_inv(addr, size);
}
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index 8f2cd8eda741..4481656d1065 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -17,8 +17,7 @@ void *__kmap(struct page *page)
void __kunmap(struct page *page)
{
- if (in_interrupt())
- BUG();
+ BUG_ON(in_interrupt());
if (!PageHighMem(page))
return;
kunmap_high(page);
@@ -43,11 +42,11 @@ void *__kmap_atomic(struct page *page, enum km_type type)
if (!PageHighMem(page))
return page_address(page);
+ debug_kmap_atomic(type);
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
#ifdef CONFIG_DEBUG_HIGHMEM
- if (!pte_none(*(kmap_pte-idx)))
- BUG();
+ BUG_ON(!pte_none(*(kmap_pte - idx)));
#endif
set_pte(kmap_pte-idx, mk_pte(page, kmap_prot));
local_flush_tlb_one((unsigned long)vaddr);
@@ -66,8 +65,7 @@ void __kunmap_atomic(void *kvaddr, enum km_type type)
return;
}
- if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
- BUG();
+ BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
/*
* force other mappings to Oops if they'll try to access
@@ -91,6 +89,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
pagefault_disable();
+ debug_kmap_atomic(type);
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 137c14bafd6b..d9348946a19e 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -307,8 +307,7 @@ void __init fixrange_init(unsigned long start, unsigned long end,
if (pmd_none(*pmd)) {
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
set_pmd(pmd, __pmd((unsigned long)pte));
- if (pte != pte_offset_kernel(pmd, 0))
- BUG();
+ BUG_ON(pte != pte_offset_kernel(pmd, 0));
}
vaddr += PMD_SIZE;
}
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
index 59945b9ee23c..0c43248347bd 100644
--- a/arch/mips/mm/ioremap.c
+++ b/arch/mips/mm/ioremap.c
@@ -27,8 +27,7 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address,
end = address + size;
if (end > PMD_SIZE)
end = PMD_SIZE;
- if (address >= end)
- BUG();
+ BUG_ON(address >= end);
pfn = phys_addr >> PAGE_SHIFT;
do {
if (!pte_none(*pte)) {
@@ -52,8 +51,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
if (end > PGDIR_SIZE)
end = PGDIR_SIZE;
phys_addr -= address;
- if (address >= end)
- BUG();
+ BUG_ON(address >= end);
do {
pte_t * pte = pte_alloc_kernel(pmd, address);
if (!pte)
@@ -75,8 +73,7 @@ static int remap_area_pages(unsigned long address, phys_t phys_addr,
phys_addr -= address;
dir = pgd_offset(&init_mm, address);
flush_cache_all();
- if (address >= end)
- BUG();
+ BUG_ON(address >= end);
do {
pud_t *pud;
pmd_t *pmd;
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index f335cf6cdd78..0615b62efd6d 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -292,13 +292,6 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
case CPU_R4300:
case CPU_5KC:
case CPU_TX49XX:
- case CPU_AU1000:
- case CPU_AU1100:
- case CPU_AU1500:
- case CPU_AU1550:
- case CPU_AU1200:
- case CPU_AU1210:
- case CPU_AU1250:
case CPU_PR4450:
uasm_i_nop(p);
tlbw(p);
@@ -321,6 +314,7 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
case CPU_R5500:
if (m4kc_tlbp_war())
uasm_i_nop(p);
+ case CPU_ALCHEMY:
tlbw(p);
break;
diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c
index 4832af251668..475038a141a6 100644
--- a/arch/mips/mti-malta/malta-init.c
+++ b/arch/mips/mti-malta/malta-init.c
@@ -48,7 +48,7 @@ int *_prom_argv, *_prom_envp;
int init_debug = 0;
-int mips_revision_corid;
+static int mips_revision_corid;
int mips_revision_sconid;
/* Bonito64 system controller register base. */
diff --git a/arch/mips/sgi-ip27/ip27-berr.c b/arch/mips/sgi-ip27/ip27-berr.c
index 7d05e68fdc77..04cebadc2b3c 100644
--- a/arch/mips/sgi-ip27/ip27-berr.c
+++ b/arch/mips/sgi-ip27/ip27-berr.c
@@ -66,7 +66,7 @@ int ip27_be_handler(struct pt_regs *regs, int is_fixup)
printk("Slice %c got %cbe at 0x%lx\n", 'A' + cpu, data ? 'd' : 'i',
regs->cp0_epc);
printk("Hub information:\n");
- printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND));
+ printk("ERR_INT_PEND = 0x%06llx\n", LOCAL_HUB_L(PI_ERR_INT_PEND));
errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A);
errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A);
dump_hub_information(errst0, errst1);
diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c
index 64459e7d891b..6c5a630566f9 100644
--- a/arch/mips/sgi-ip27/ip27-nmi.c
+++ b/arch/mips/sgi-ip27/ip27-nmi.c
@@ -143,8 +143,8 @@ void nmi_dump_hub_irq(nasid_t nasid, int slice)
pend0 = REMOTE_HUB_L(nasid, PI_INT_PEND0);
pend1 = REMOTE_HUB_L(nasid, PI_INT_PEND1);
- printk("PI_INT_MASK0: %16lx PI_INT_MASK1: %16lx\n", mask0, mask1);
- printk("PI_INT_PEND0: %16lx PI_INT_PEND1: %16lx\n", pend0, pend1);
+ printk("PI_INT_MASK0: %16Lx PI_INT_MASK1: %16Lx\n", mask0, mask1);
+ printk("PI_INT_PEND0: %16Lx PI_INT_PEND1: %16Lx\n", pend0, pend1);
printk("\n\n");
}
@@ -219,7 +219,7 @@ cont_nmi_dump(void)
if (i == 1000) {
for_each_online_node(node)
if (NODEPDA(node)->dump_count == 0) {
- cpu = node_to_first_cpu(node);
+ cpu = cpumask_first(cpumask_of_node(node));
for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) {
CPUMASK_SETB(nmied_cpus, cpu);
/*
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index 5b47d6b65275..cbcd7eb83bd1 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -221,7 +221,7 @@ static void __init ip27_smp_setup(void)
* Assumption to be fixed: we're always booted on logical / physical
* processor 0. While we're always running on logical processor 0
* this still means this is physical processor zero; it might for
- * example be disabled in the firwware.
+ * example be disabled in the firmware.
*/
alloc_cpupda(0, 0);
}
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index 0d6b6663d5f6..83a0b3c359da 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -115,14 +115,12 @@ extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id);
struct irqaction memerr_irq = {
.handler = crime_memerr_intr,
.flags = IRQF_DISABLED,
- .mask = CPU_MASK_NONE,
.name = "CRIME memory error",
};
struct irqaction cpuerr_irq = {
.handler = crime_cpuerr_intr,
.flags = IRQF_DISABLED,
- .mask = CPU_MASK_NONE,
.name = "CRIME CPU error",
};
@@ -325,16 +323,11 @@ static void mask_and_ack_maceisa_irq(unsigned int irq)
{
unsigned long mace_int;
- switch (irq) {
- case MACEISA_PARALLEL_IRQ:
- case MACEISA_SERIAL1_TDMAPR_IRQ:
- case MACEISA_SERIAL2_TDMAPR_IRQ:
- /* edge triggered */
- mace_int = mace->perif.ctrl.istat;
- mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
- mace->perif.ctrl.istat = mace_int;
- break;
- }
+ /* edge triggered */
+ mace_int = mace->perif.ctrl.istat;
+ mace_int &= ~(1 << (irq - MACEISA_AUDIO_SW_IRQ));
+ mace->perif.ctrl.istat = mace_int;
+
disable_maceisa_irq(irq);
}
@@ -344,7 +337,16 @@ static void end_maceisa_irq(unsigned irq)
enable_maceisa_irq(irq);
}
-static struct irq_chip ip32_maceisa_interrupt = {
+static struct irq_chip ip32_maceisa_level_interrupt = {
+ .name = "IP32 MACE ISA",
+ .ack = disable_maceisa_irq,
+ .mask = disable_maceisa_irq,
+ .mask_ack = disable_maceisa_irq,
+ .unmask = enable_maceisa_irq,
+ .end = end_maceisa_irq,
+};
+
+static struct irq_chip ip32_maceisa_edge_interrupt = {
.name = "IP32 MACE ISA",
.ack = mask_and_ack_maceisa_irq,
.mask = disable_maceisa_irq,
@@ -500,27 +502,50 @@ void __init arch_init_irq(void)
for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) {
switch (irq) {
case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
- set_irq_chip(irq, &ip32_mace_interrupt);
+ set_irq_chip_and_handler_name(irq,&ip32_mace_interrupt,
+ handle_level_irq, "level");
break;
+
case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ:
- set_irq_chip(irq, &ip32_macepci_interrupt);
+ set_irq_chip_and_handler_name(irq,
+ &ip32_macepci_interrupt, handle_level_irq,
+ "level");
break;
+
case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ:
- set_irq_chip(irq, &crime_edge_interrupt);
+ set_irq_chip_and_handler_name(irq,
+ &crime_edge_interrupt, handle_edge_irq, "edge");
break;
case CRIME_CPUERR_IRQ:
case CRIME_MEMERR_IRQ:
- set_irq_chip(irq, &crime_level_interrupt);
+ set_irq_chip_and_handler_name(irq,
+ &crime_level_interrupt, handle_level_irq,
+ "level");
break;
+
case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ:
case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ:
- set_irq_chip(irq, &crime_edge_interrupt);
+ set_irq_chip_and_handler_name(irq,
+ &crime_edge_interrupt, handle_edge_irq, "edge");
break;
+
case CRIME_VICE_IRQ:
- set_irq_chip(irq, &crime_edge_interrupt);
+ set_irq_chip_and_handler_name(irq,
+ &crime_edge_interrupt, handle_edge_irq, "edge");
+ break;
+
+ case MACEISA_PARALLEL_IRQ:
+ case MACEISA_SERIAL1_TDMAPR_IRQ:
+ case MACEISA_SERIAL2_TDMAPR_IRQ:
+ set_irq_chip_and_handler_name(irq,
+ &ip32_maceisa_edge_interrupt, handle_edge_irq,
+ "edge");
break;
+
default:
- set_irq_chip(irq, &ip32_maceisa_interrupt);
+ set_irq_chip_and_handler_name(irq,
+ &ip32_maceisa_level_interrupt, handle_level_irq,
+ "level");
break;
}
}
diff --git a/arch/mips/sgi-ip32/ip32-memory.c b/arch/mips/sgi-ip32/ip32-memory.c
index ca93ecf825ae..828ce131c228 100644
--- a/arch/mips/sgi-ip32/ip32-memory.c
+++ b/arch/mips/sgi-ip32/ip32-memory.c
@@ -36,7 +36,7 @@ void __init prom_meminit(void)
if (base + size > (256 << 20))
base += CRIME_HI_MEM_BASE;
- printk("CRIME MC: bank %u base 0x%016lx size %luMiB\n",
+ printk("CRIME MC: bank %u base 0x%016Lx size %LuMiB\n",
bank, base, size >> 20);
add_memory_region(base, size, BOOT_MEM_RAM);
}
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 12b465d404df..352352b3cb2f 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -236,7 +236,7 @@ void __init init_bcm1480_irqs(void)
int i;
for (i = 0; i < BCM1480_NR_IRQS; i++) {
- set_irq_chip(i, &bcm1480_irq_type);
+ set_irq_chip_and_handler(i, &bcm1480_irq_type, handle_level_irq);
bcm1480_irq_owner[i] = 0;
}
}
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index 808ac2959b8c..c08ff582da6f 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -220,7 +220,7 @@ void __init init_sb1250_irqs(void)
int i;
for (i = 0; i < SB1250_NR_IRQS; i++) {
- set_irq_chip(i, &sb1250_irq_type);
+ set_irq_chip_and_handler(i, &sb1250_irq_type, handle_level_irq);
sb1250_irq_owner[i] = 0;
}
}
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
index 3f8cf5eb2f06..7dd76fb3b645 100644
--- a/arch/mips/sni/a20r.c
+++ b/arch/mips/sni/a20r.c
@@ -219,7 +219,7 @@ void __init sni_a20r_irq_init(void)
int i;
for (i = SNI_A20R_IRQ_BASE + 2 ; i < SNI_A20R_IRQ_BASE + 8; i++)
- set_irq_chip(i, &a20r_irq_type);
+ set_irq_chip_and_handler(i, &a20r_irq_type, handle_level_irq);
sni_hwint = a20r_hwint;
change_c0_status(ST0_IM, IE_IRQ0);
setup_irq(SNI_A20R_IRQ_BASE + 3, &sni_isa_irq);
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c
index 834650f371e0..74e6c67982fb 100644
--- a/arch/mips/sni/pcimt.c
+++ b/arch/mips/sni/pcimt.c
@@ -304,7 +304,7 @@ void __init sni_pcimt_irq_init(void)
mips_cpu_irq_init();
/* Actually we've got more interrupts to handle ... */
for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++)
- set_irq_chip(i, &pcimt_irq_type);
+ set_irq_chip_and_handler(i, &pcimt_irq_type, handle_level_irq);
sni_hwint = sni_pcimt_hwint;
change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3);
}
diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c
index e5f12cf96e8e..071a9573ac7f 100644
--- a/arch/mips/sni/pcit.c
+++ b/arch/mips/sni/pcit.c
@@ -246,7 +246,7 @@ void __init sni_pcit_irq_init(void)
mips_cpu_irq_init();
for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
- set_irq_chip(i, &pcit_irq_type);
+ set_irq_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
*(volatile u32 *)SNI_PCIT_INT_REG = 0;
sni_hwint = sni_pcit_hwint;
change_c0_status(ST0_IM, IE_IRQ1);
@@ -259,7 +259,7 @@ void __init sni_pcit_cplus_irq_init(void)
mips_cpu_irq_init();
for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
- set_irq_chip(i, &pcit_irq_type);
+ set_irq_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
*(volatile u32 *)SNI_PCIT_INT_REG = 0x40000000;
sni_hwint = sni_pcit_hwint_cplus;
change_c0_status(ST0_IM, IE_IRQ0);
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
index 5310aa75afa4..5e687819cbc2 100644
--- a/arch/mips/sni/rm200.c
+++ b/arch/mips/sni/rm200.c
@@ -359,7 +359,8 @@ void sni_rm200_init_8259A(void)
* IRQ2 is cascade interrupt to second interrupt controller
*/
static struct irqaction sni_rm200_irq2 = {
- no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL
+ .handler = no_action,
+ .name = "cascade",
};
static struct resource sni_rm200_pic1_resource = {
@@ -487,7 +488,7 @@ void __init sni_rm200_irq_init(void)
mips_cpu_irq_init();
/* Actually we've got more interrupts to handle ... */
for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++)
- set_irq_chip(i, &rm200_irq_type);
+ set_irq_chip_and_handler(i, &rm200_irq_type, handle_level_irq);
sni_hwint = sni_rm200_hwint;
change_c0_status(ST0_IM, IE_IRQ0);
setup_irq(SNI_RM200_INT_START + 0, &sni_rm200_i8259A_irq);
diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig
index 226e8bb2f0a1..0db7cf38ed8b 100644
--- a/arch/mips/txx9/Kconfig
+++ b/arch/mips/txx9/Kconfig
@@ -20,7 +20,6 @@ config MACH_TXX9
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_BIG_ENDIAN
- select GENERIC_HARDIRQS_NO__DO_IRQ
config TOSHIBA_JMR3927
bool "Toshiba JMR-TX3927 board"
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index a13a08b8c9ec..8a266c6a3f58 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -32,6 +32,7 @@
#include <asm/txx9/generic.h>
#include <asm/txx9/pci.h>
#include <asm/txx9tmr.h>
+#include <asm/txx9/ndfmc.h>
#ifdef CONFIG_CPU_TX49XX
#include <asm/txx9/tx4938.h>
#endif
@@ -691,6 +692,26 @@ void __init txx9_physmap_flash_init(int no, unsigned long addr,
#endif
}
+void __init txx9_ndfmc_init(unsigned long baseaddr,
+ const struct txx9ndfmc_platform_data *pdata)
+{
+#if defined(CONFIG_MTD_NAND_TXX9NDFMC) || \
+ defined(CONFIG_MTD_NAND_TXX9NDFMC_MODULE)
+ struct resource res = {
+ .start = baseaddr,
+ .end = baseaddr + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ };
+ struct platform_device *pdev = platform_device_alloc("txx9ndfmc", -1);
+
+ if (!pdev ||
+ platform_device_add_resources(pdev, &res, 1) ||
+ platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
+ platform_device_add(pdev))
+ platform_device_put(pdev);
+#endif
+}
+
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
static DEFINE_SPINLOCK(txx9_iocled_lock);
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c
index 25819ff1c350..f0844f891f0b 100644
--- a/arch/mips/txx9/generic/setup_tx4938.c
+++ b/arch/mips/txx9/generic/setup_tx4938.c
@@ -23,6 +23,7 @@
#include <asm/txx9tmr.h>
#include <asm/txx9pio.h>
#include <asm/txx9/generic.h>
+#include <asm/txx9/ndfmc.h>
#include <asm/txx9/tx4938.h>
static void __init tx4938_wdr_init(void)
@@ -382,6 +383,26 @@ void __init tx4938_ata_init(unsigned int irq, unsigned int shift, int tune)
platform_device_put(pdev);
}
+void __init tx4938_ndfmc_init(unsigned int hold, unsigned int spw)
+{
+ struct txx9ndfmc_platform_data plat_data = {
+ .shift = 1,
+ .gbus_clock = txx9_gbus_clock,
+ .hold = hold,
+ .spw = spw,
+ .ch_mask = 1,
+ };
+ unsigned long baseaddr = TX4938_NDFMC_REG & 0xfffffffffULL;
+
+#ifdef __BIG_ENDIAN
+ baseaddr += 4;
+#endif
+ if ((__raw_readq(&tx4938_ccfgptr->pcfg) &
+ (TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL)) ==
+ TX4938_PCFG_NDF_SEL)
+ txx9_ndfmc_init(baseaddr, &plat_data);
+}
+
static void __init tx4938_stop_unused_modules(void)
{
__u64 pcfg, rst = 0, ckd = 0;
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
index 55440967b3a8..7a25b573e9b0 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -27,6 +27,7 @@
#include <asm/txx9irq.h>
#include <asm/txx9tmr.h>
#include <asm/txx9/generic.h>
+#include <asm/txx9/ndfmc.h>
#include <asm/txx9/tx4939.h>
static void __init tx4939_wdr_init(void)
@@ -457,6 +458,22 @@ void __init tx4939_rtc_init(void)
platform_device_register(&rtc_dev);
}
+void __init tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
+ unsigned char ch_mask, unsigned char wide_mask)
+{
+ struct txx9ndfmc_platform_data plat_data = {
+ .shift = 1,
+ .gbus_clock = txx9_gbus_clock,
+ .hold = hold,
+ .spw = spw,
+ .flags = NDFMC_PLAT_FLAG_NO_RSTR | NDFMC_PLAT_FLAG_HOLDADD |
+ NDFMC_PLAT_FLAG_DUMMYWRITE,
+ .ch_mask = ch_mask,
+ .wide_mask = wide_mask,
+ };
+ txx9_ndfmc_init(TX4939_NDFMC_REG & 0xfffffffffULL, &plat_data);
+}
+
static void __init tx4939_stop_unused_modules(void)
{
__u64 pcfg, rst = 0, ckd = 0;
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c
index 547ff2920bf0..65d13df8878a 100644
--- a/arch/mips/txx9/rbtx4938/setup.c
+++ b/arch/mips/txx9/rbtx4938/setup.c
@@ -352,6 +352,8 @@ static void __init rbtx4938_device_init(void)
rbtx4938_ne_init();
tx4938_wdt_init();
rbtx4938_mtd_init();
+ /* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
+ tx4938_ndfmc_init(10, 35);
tx4938_ata_init(RBTX4938_IRQ_IOC_ATA, 0, 1);
txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL);
}
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
index 656603b85b71..011e1e332f47 100644
--- a/arch/mips/txx9/rbtx4939/setup.c
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -16,6 +16,9 @@
#include <linux/leds.h>
#include <linux/interrupt.h>
#include <linux/smc91x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/map.h>
#include <asm/reboot.h>
#include <asm/txx9/generic.h>
#include <asm/txx9/pci.h>
@@ -282,6 +285,159 @@ static void rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
__rbtx4939_7segled_putc(pos, val);
}
+#if defined(CONFIG_MTD_RBTX4939) || defined(CONFIG_MTD_RBTX4939_MODULE)
+/* special mapping for boot rom */
+static unsigned long rbtx4939_flash_fixup_ofs(unsigned long ofs)
+{
+ u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
+ unsigned char shift;
+
+ if (bdipsw & 8) {
+ /* BOOT Mode: USER ROM1 / USER ROM2 */
+ shift = bdipsw & 3;
+ /* rotate A[23:22] */
+ return (ofs & ~0xc00000) | ((((ofs >> 22) + shift) & 3) << 22);
+ }
+#ifdef __BIG_ENDIAN
+ if (bdipsw == 0)
+ /* BOOT Mode: Monitor ROM */
+ ofs ^= 0x400000; /* swap A[22] */
+#endif
+ return ofs;
+}
+
+static map_word rbtx4939_flash_read16(struct map_info *map, unsigned long ofs)
+{
+ map_word r;
+
+ ofs = rbtx4939_flash_fixup_ofs(ofs);
+ r.x[0] = __raw_readw(map->virt + ofs);
+ return r;
+}
+
+static void rbtx4939_flash_write16(struct map_info *map, const map_word datum,
+ unsigned long ofs)
+{
+ ofs = rbtx4939_flash_fixup_ofs(ofs);
+ __raw_writew(datum.x[0], map->virt + ofs);
+ mb(); /* see inline_map_write() in mtd/map.h */
+}
+
+static void rbtx4939_flash_copy_from(struct map_info *map, void *to,
+ unsigned long from, ssize_t len)
+{
+ u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
+ unsigned char shift;
+ ssize_t curlen;
+
+ from += (unsigned long)map->virt;
+ if (bdipsw & 8) {
+ /* BOOT Mode: USER ROM1 / USER ROM2 */
+ shift = bdipsw & 3;
+ while (len) {
+ curlen = min_t(unsigned long, len,
+ 0x400000 - (from & (0x400000 - 1)));
+ memcpy(to,
+ (void *)((from & ~0xc00000) |
+ ((((from >> 22) + shift) & 3) << 22)),
+ curlen);
+ len -= curlen;
+ from += curlen;
+ to += curlen;
+ }
+ return;
+ }
+#ifdef __BIG_ENDIAN
+ if (bdipsw == 0) {
+ /* BOOT Mode: Monitor ROM */
+ while (len) {
+ curlen = min_t(unsigned long, len,
+ 0x400000 - (from & (0x400000 - 1)));
+ memcpy(to, (void *)(from ^ 0x400000), curlen);
+ len -= curlen;
+ from += curlen;
+ to += curlen;
+ }
+ return;
+ }
+#endif
+ memcpy(to, (void *)from, len);
+}
+
+static void rbtx4939_flash_map_init(struct map_info *map)
+{
+ map->read = rbtx4939_flash_read16;
+ map->write = rbtx4939_flash_write16;
+ map->copy_from = rbtx4939_flash_copy_from;
+}
+
+static void __init rbtx4939_mtd_init(void)
+{
+ static struct {
+ struct platform_device dev;
+ struct resource res;
+ struct rbtx4939_flash_data data;
+ } pdevs[4];
+ int i;
+ static char names[4][8];
+ static struct mtd_partition parts[4];
+ struct rbtx4939_flash_data *boot_pdata = &pdevs[0].data;
+ u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
+
+ if (bdipsw & 8) {
+ /* BOOT Mode: USER ROM1 / USER ROM2 */
+ boot_pdata->nr_parts = 4;
+ for (i = 0; i < boot_pdata->nr_parts; i++) {
+ sprintf(names[i], "img%d", 4 - i);
+ parts[i].name = names[i];
+ parts[i].size = 0x400000;
+ parts[i].offset = MTDPART_OFS_NXTBLK;
+ }
+ } else if (bdipsw == 0) {
+ /* BOOT Mode: Monitor ROM */
+ boot_pdata->nr_parts = 2;
+ strcpy(names[0], "big");
+ strcpy(names[1], "little");
+ for (i = 0; i < boot_pdata->nr_parts; i++) {
+ parts[i].name = names[i];
+ parts[i].size = 0x400000;
+ parts[i].offset = MTDPART_OFS_NXTBLK;
+ }
+ } else {
+ /* BOOT Mode: ROM Emulator */
+ boot_pdata->nr_parts = 2;
+ parts[0].name = "boot";
+ parts[0].offset = 0xc00000;
+ parts[0].size = 0x400000;
+ parts[1].name = "user";
+ parts[1].offset = 0;
+ parts[1].size = 0xc00000;
+ }
+ boot_pdata->parts = parts;
+ boot_pdata->map_init = rbtx4939_flash_map_init;
+
+ for (i = 0; i < ARRAY_SIZE(pdevs); i++) {
+ struct resource *r = &pdevs[i].res;
+ struct platform_device *dev = &pdevs[i].dev;
+
+ r->start = 0x1f000000 - i * 0x1000000;
+ r->end = r->start + 0x1000000 - 1;
+ r->flags = IORESOURCE_MEM;
+ pdevs[i].data.width = 2;
+ dev->num_resources = 1;
+ dev->resource = r;
+ dev->id = i;
+ dev->name = "rbtx4939-flash";
+ dev->dev.platform_data = &pdevs[i].data;
+ platform_device_register(dev);
+ }
+}
+#else
+static void __init rbtx4939_mtd_init(void)
+{
+}
+#endif
+
static void __init rbtx4939_arch_init(void)
{
rbtx4939_pci_setup();
@@ -333,6 +489,11 @@ static void __init rbtx4939_device_init(void)
platform_device_add_data(pdev, &smc_pdata, sizeof(smc_pdata)) ||
platform_device_add(pdev))
platform_device_put(pdev);
+ rbtx4939_mtd_init();
+ /* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
+ tx4939_ndfmc_init(10, 35,
+ (1 << 1) | (1 << 2),
+ (1 << 2)); /* ch1:8bit, ch2:16bit */
rbtx4939_led_setup();
tx4939_wdt_init();
tx4939_ata_init();
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c
index 92dd1a0ca352..9cc389109b19 100644
--- a/arch/mips/vr41xx/common/irq.c
+++ b/arch/mips/vr41xx/common/irq.c
@@ -32,7 +32,6 @@ static irq_cascade_t irq_cascade[NR_IRQS] __cacheline_aligned;
static struct irqaction cascade_irqaction = {
.handler = no_action,
- .mask = CPU_MASK_NONE,
.name = "cascade",
};
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index 56c64ccc9c21..50fdb5c16e0c 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -221,7 +221,7 @@ int show_interrupts(struct seq_file *p, void *v)
if (action) {
seq_printf(p, "%3d: ", i);
for_each_present_cpu(cpu)
- seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
seq_printf(p, " %14s.%u", irq_desc[i].chip->name,
(GxICR(i) & GxICR_LEVEL) >>
GxICR_LEVEL_SHIFT);
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index b28c9a60445b..234cf344cdce 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -193,7 +193,7 @@ void prepare_to_copy(struct task_struct *tsk)
* set up the kernel stack for a new thread and copy arch-specific thread
* control information
*/
-int copy_thread(int nr, unsigned long clone_flags,
+int copy_thread(unsigned long clone_flags,
unsigned long c_usp, unsigned long ustk_size,
struct task_struct *p, struct pt_regs *kregs)
{
diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c
index e4606586f94c..395caf01b909 100644
--- a/arch/mn10300/kernel/time.c
+++ b/arch/mn10300/kernel/time.c
@@ -37,7 +37,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id);
static struct irqaction timer_irq = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_SHARED | IRQF_TIMER,
- .mask = CPU_MASK_NONE,
.name = "timer",
};
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index aacf11d33723..9038f39d9d73 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -9,9 +9,13 @@ config PARISC
def_bool y
select HAVE_IDE
select HAVE_OPROFILE
+ select HAVE_FUNCTION_TRACER if 64BIT
+ select HAVE_FUNCTION_GRAPH_TRACER if 64BIT
+ select HAVE_FUNCTION_TRACE_MCOUNT_TEST if 64BIT
select RTC_CLASS
- select RTC_DRV_PARISC
+ select RTC_DRV_GENERIC
select INIT_ALL_POSSIBLE
+ select BUG
help
The PA-RISC microprocessor is designed by Hewlett-Packard and used
in many of their workstations & servers (HP9000 700 and 800 series,
@@ -75,6 +79,9 @@ config GENERIC_HARDIRQS
config GENERIC_IRQ_PROBE
def_bool y
+config HAVE_LATENCYTOP_SUPPORT
+ def_bool y
+
config IRQ_PER_CPU
bool
default y
@@ -83,6 +90,9 @@ config IRQ_PER_CPU
config PM
bool
+config STACKTRACE_SUPPORT
+ def_bool y
+
config ISA_DMA_API
bool
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 0d428278356d..da6f66901c92 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -56,7 +56,9 @@ cflags-y += -mdisable-fpregs
# Without this, "ld -r" results in .text sections that are too big
# (> 0x40000) for branches to reach stubs.
-cflags-y += -ffunction-sections
+ifndef CONFIG_FUNCTION_TRACER
+ cflags-y += -ffunction-sections
+endif
# select which processor to optimise for
cflags-$(CONFIG_PA7100) += -march=1.1 -mschedule=7100
diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h
index edbfe25c5fc1..ada3e5364d82 100644
--- a/arch/parisc/include/asm/atomic.h
+++ b/arch/parisc/include/asm/atomic.h
@@ -25,7 +25,7 @@
* Since "a" is usually an address, use one spinlock per cacheline.
*/
# define ATOMIC_HASH_SIZE 4
-# define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) a)/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ]))
+# define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) (a))/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ]))
extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
@@ -222,13 +222,13 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
-#define atomic_add(i,v) ((void)(__atomic_add_return( ((int)i),(v))))
-#define atomic_sub(i,v) ((void)(__atomic_add_return(-((int)i),(v))))
+#define atomic_add(i,v) ((void)(__atomic_add_return( ((int)(i)),(v))))
+#define atomic_sub(i,v) ((void)(__atomic_add_return(-((int)(i)),(v))))
#define atomic_inc(v) ((void)(__atomic_add_return( 1,(v))))
#define atomic_dec(v) ((void)(__atomic_add_return( -1,(v))))
-#define atomic_add_return(i,v) (__atomic_add_return( ((int)i),(v)))
-#define atomic_sub_return(i,v) (__atomic_add_return(-((int)i),(v)))
+#define atomic_add_return(i,v) (__atomic_add_return( ((int)(i)),(v)))
+#define atomic_sub_return(i,v) (__atomic_add_return(-((int)(i)),(v)))
#define atomic_inc_return(v) (__atomic_add_return( 1,(v)))
#define atomic_dec_return(v) (__atomic_add_return( -1,(v)))
@@ -289,13 +289,13 @@ atomic64_read(const atomic64_t *v)
return v->counter;
}
-#define atomic64_add(i,v) ((void)(__atomic64_add_return( ((s64)i),(v))))
-#define atomic64_sub(i,v) ((void)(__atomic64_add_return(-((s64)i),(v))))
+#define atomic64_add(i,v) ((void)(__atomic64_add_return( ((s64)(i)),(v))))
+#define atomic64_sub(i,v) ((void)(__atomic64_add_return(-((s64)(i)),(v))))
#define atomic64_inc(v) ((void)(__atomic64_add_return( 1,(v))))
#define atomic64_dec(v) ((void)(__atomic64_add_return( -1,(v))))
-#define atomic64_add_return(i,v) (__atomic64_add_return( ((s64)i),(v)))
-#define atomic64_sub_return(i,v) (__atomic64_add_return(-((s64)i),(v)))
+#define atomic64_add_return(i,v) (__atomic64_add_return( ((s64)(i)),(v)))
+#define atomic64_sub_return(i,v) (__atomic64_add_return(-((s64)(i)),(v)))
#define atomic64_inc_return(v) (__atomic64_add_return( 1,(v)))
#define atomic64_dec_return(v) (__atomic64_add_return( -1,(v)))
diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h
index b7ca6dc7fddc..724395143f26 100644
--- a/arch/parisc/include/asm/cacheflush.h
+++ b/arch/parisc/include/asm/cacheflush.h
@@ -97,6 +97,9 @@ void mark_rodata_ro(void);
#ifdef CONFIG_PA8X00
/* Only pa8800, pa8900 needs this */
+
+#include <asm/kmap_types.h>
+
#define ARCH_HAS_KMAP
void kunmap_parisc(void *addr);
diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h
index 7fa675799e6d..9c802eb4be84 100644
--- a/arch/parisc/include/asm/elf.h
+++ b/arch/parisc/include/asm/elf.h
@@ -168,6 +168,16 @@ typedef struct elf64_fdesc {
__u64 gp;
} Elf64_Fdesc;
+#ifdef __KERNEL__
+
+#ifdef CONFIG_64BIT
+#define Elf_Fdesc Elf64_Fdesc
+#else
+#define Elf_Fdesc Elf32_Fdesc
+#endif /*CONFIG_64BIT*/
+
+#endif /*__KERNEL__*/
+
/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
#define PT_HP_TLS (PT_LOOS + 0x0)
diff --git a/arch/parisc/include/asm/ftrace.h b/arch/parisc/include/asm/ftrace.h
index 40a8c178f10d..2fa05dd6aeee 100644
--- a/arch/parisc/include/asm/ftrace.h
+++ b/arch/parisc/include/asm/ftrace.h
@@ -1 +1,25 @@
-/* empty */
+#ifndef _ASM_PARISC_FTRACE_H
+#define _ASM_PARISC_FTRACE_H
+
+#ifndef __ASSEMBLY__
+extern void mcount(void);
+
+/*
+ * Stack of return addresses for functions of a thread.
+ * Used in struct thread_info
+ */
+struct ftrace_ret_stack {
+ unsigned long ret;
+ unsigned long func;
+ unsigned long long calltime;
+};
+
+/*
+ * Primary handler of a function return.
+ * It relays on ftrace_return_to_handler.
+ * Defined in entry.S
+ */
+extern void return_to_handler(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_PARISC_FTRACE_H */
diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h
index c3941f09a878..7bc5125d7d4c 100644
--- a/arch/parisc/include/asm/page.h
+++ b/arch/parisc/include/asm/page.h
@@ -36,16 +36,7 @@ void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
*/
#define STRICT_MM_TYPECHECKS
#ifdef STRICT_MM_TYPECHECKS
-typedef struct { unsigned long pte;
-#if !defined(CONFIG_64BIT)
- unsigned long future_flags;
- /* XXX: it's possible to remove future_flags and change BITS_PER_PTE_ENTRY
- to 2, but then strangely the identical 32bit kernel boots on a
- c3000(pa20), but not any longer on a 715(pa11).
- Still investigating... HelgeD.
- */
-#endif
-} pte_t; /* either 32 or 64bit */
+typedef struct { unsigned long pte; } pte_t; /* either 32 or 64bit */
/* NOTE: even on 64 bits, these entries are __u32 because we allocate
* the pmd and pgd in ZONE_DMA (i.e. under 4GB) */
@@ -111,7 +102,7 @@ extern int npmem_ranges;
#define BITS_PER_PMD_ENTRY 2
#define BITS_PER_PGD_ENTRY 2
#else
-#define BITS_PER_PTE_ENTRY 3
+#define BITS_PER_PTE_ENTRY 2
#define BITS_PER_PMD_ENTRY 2
#define BITS_PER_PGD_ENTRY BITS_PER_PMD_ENTRY
#endif
diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h
index 430f1aeea0b8..4ca510b3c6f8 100644
--- a/arch/parisc/include/asm/pdc.h
+++ b/arch/parisc/include/asm/pdc.h
@@ -49,6 +49,8 @@
#define PDC_MODEL_CPU_ID 6 /* returns cpu-id (only newer machines!) */
#define PDC_MODEL_CAPABILITIES 7 /* returns OS32/OS64-flags */
/* Values for PDC_MODEL_CAPABILITIES non-equivalent virtual aliasing support */
+#define PDC_MODEL_OS64 (1 << 0)
+#define PDC_MODEL_OS32 (1 << 1)
#define PDC_MODEL_IOPDIR_FDC (1 << 2)
#define PDC_MODEL_NVA_MASK (3 << 4)
#define PDC_MODEL_NVA_SUPPORTED (0 << 4)
@@ -341,6 +343,8 @@
#ifdef __KERNEL__
+#include <asm/page.h> /* for __PAGE_OFFSET */
+
extern int pdc_type;
/* Values for pdc_type */
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index 470a4b88124d..a27d2e200fb2 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -50,11 +50,7 @@
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
/* This is the size of the initially mapped kernel memory */
-#ifdef CONFIG_64BIT
#define KERNEL_INITIAL_ORDER 24 /* 0 to 1<<24 = 16MB */
-#else
-#define KERNEL_INITIAL_ORDER 23 /* 0 to 1<<23 = 8MB */
-#endif
#define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER)
#if defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB)
@@ -91,16 +87,25 @@
/* Definitions for 1st level */
#define PGDIR_SHIFT (PMD_SHIFT + BITS_PER_PMD)
+#if (PGDIR_SHIFT + PAGE_SHIFT + PGD_ORDER - BITS_PER_PGD_ENTRY) > BITS_PER_LONG
+#define BITS_PER_PGD (BITS_PER_LONG - PGDIR_SHIFT)
+#else
#define BITS_PER_PGD (PAGE_SHIFT + PGD_ORDER - BITS_PER_PGD_ENTRY)
+#endif
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
#define PTRS_PER_PGD (1UL << BITS_PER_PGD)
#define USER_PTRS_PER_PGD PTRS_PER_PGD
+#ifdef CONFIG_64BIT
#define MAX_ADDRBITS (PGDIR_SHIFT + BITS_PER_PGD)
#define MAX_ADDRESS (1UL << MAX_ADDRBITS)
-
#define SPACEID_SHIFT (MAX_ADDRBITS - 32)
+#else
+#define MAX_ADDRBITS (BITS_PER_LONG)
+#define MAX_ADDRESS (1UL << MAX_ADDRBITS)
+#define SPACEID_SHIFT 0
+#endif
/* This calculates the number of initial pages we need for the initial
* page tables */
diff --git a/arch/parisc/include/asm/smp.h b/arch/parisc/include/asm/smp.h
index 6ef4b7867b1b..21eb45a52629 100644
--- a/arch/parisc/include/asm/smp.h
+++ b/arch/parisc/include/asm/smp.h
@@ -29,7 +29,8 @@ extern void smp_send_reschedule(int cpu);
extern void smp_send_all_nop(void);
extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi(cpumask_t mask);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
#endif /* !ASSEMBLY */
diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h
index fba402c95ac2..885472bf7b78 100644
--- a/arch/parisc/include/asm/socket.h
+++ b/arch/parisc/include/asm/socket.h
@@ -54,6 +54,9 @@
#define SO_MARK 0x401f
+#define SO_TIMESTAMPING 0x4020
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
* have to define SOCK_NONBLOCK to a different value here.
*/
diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h
index f3d2090a18dc..fae03e136fa8 100644
--- a/arch/parisc/include/asm/spinlock.h
+++ b/arch/parisc/include/asm/spinlock.h
@@ -187,6 +187,9 @@ static __inline__ int __raw_write_can_lock(raw_rwlock_t *rw)
return !rw->counter;
}
+#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
+#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+
#define _raw_spin_relax(lock) cpu_relax()
#define _raw_read_relax(lock) cpu_relax()
#define _raw_write_relax(lock) cpu_relax()
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
index 016d3fc4111c..67db0722e6ca 100644
--- a/arch/parisc/kernel/Makefile
+++ b/arch/parisc/kernel/Makefile
@@ -11,10 +11,25 @@ obj-y := cache.o pacache.o setup.o traps.o time.o irq.o \
process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \
topology.o
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o = -pg
+CFLAGS_REMOVE_cache.o = -pg
+CFLAGS_REMOVE_irq.o = -pg
+CFLAGS_REMOVE_pacache.o = -pg
+CFLAGS_REMOVE_perf.o = -pg
+CFLAGS_REMOVE_traps.o = -pg
+CFLAGS_REMOVE_unaligned.o = -pg
+CFLAGS_REMOVE_unwind.o = -pg
+endif
+
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_PA11) += pci-dma.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_64BIT) += binfmt_elf32.o sys_parisc32.o signal32.o
+obj-$(CONFIG_STACKTRACE)+= stacktrace.o
# only supported for PCX-W/U in 64-bit mode at the moment
obj-$(CONFIG_64BIT) += perf.o perf_asm.o
+obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 0db9fdcb7709..ae3e70cd1e14 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -505,6 +505,18 @@
STREG \pte,0(\ptep)
.endm
+ /* bitshift difference between a PFN (based on kernel's PAGE_SIZE)
+ * to a CPU TLB 4k PFN (4k => 12 bits to shift) */
+ #define PAGE_ADD_SHIFT (PAGE_SHIFT-12)
+
+ /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
+ .macro convert_for_tlb_insert20 pte
+ extrd,u \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
+ 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
+ depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\
+ (63-58)+PAGE_ADD_SHIFT,\pte
+ .endm
+
/* Convert the pte and prot to tlb insertion values. How
* this happens is quite subtle, read below */
.macro make_insert_tlb spc,pte,prot
@@ -544,8 +556,7 @@
depi 1,12,1,\prot
/* Drop prot bits and convert to page addr for iitlbt and idtlbt */
- extrd,u \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58),64-PAGE_SHIFT,\pte
- depdi _PAGE_SIZE_ENCODING_DEFAULT,63,63-58,\pte
+ convert_for_tlb_insert20 \pte
.endm
/* Identical macro to make_insert_tlb above, except it
@@ -563,8 +574,8 @@
/* Get rid of prot bits and convert to page addr for iitlba */
- depi _PAGE_SIZE_ENCODING_DEFAULT,31,ASM_PFN_PTE_SHIFT,\pte
- extru \pte,24,25,\pte
+ depi 0,31,ASM_PFN_PTE_SHIFT,\pte
+ SHRREG \pte,(ASM_PFN_PTE_SHIFT-(31-26)),\pte
.endm
/* This is for ILP32 PA2.0 only. The TLB insertion needs
@@ -1244,10 +1255,9 @@ nadtlb_check_flush_20w:
depdi,z 7,7,3,prot
depdi 1,10,1,prot
- /* Get rid of prot bits and convert to page addr for idtlbt */
+ /* Drop prot bits from pte and convert to page addr for idtlbt */
+ convert_for_tlb_insert20 pte
- depdi 0,63,12,pte
- extrd,u pte,56,52,pte
idtlbt pte,prot
rfir
@@ -1337,8 +1347,8 @@ nadtlb_check_flush_11:
/* Get rid of prot bits and convert to page addr for idtlba */
- depi 0,31,12,pte
- extru pte,24,25,pte
+ depi 0,31,ASM_PFN_PTE_SHIFT,pte
+ SHRREG pte,(ASM_PFN_PTE_SHIFT-(31-26)),pte
mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */
mtsp spc,%sr1
@@ -1403,10 +1413,9 @@ nadtlb_check_flush_20:
depdi,z 7,7,3,prot
depdi 1,10,1,prot
- /* Get rid of prot bits and convert to page addr for idtlbt */
+ /* Drop prot bits from pte and convert to page addr for idtlbt */
+ convert_for_tlb_insert20 pte
- depdi 0,63,12,pte
- extrd,u pte,56,32,pte
idtlbt pte,prot
rfir
@@ -2176,6 +2185,33 @@ syscall_do_resched:
ENDPROC(syscall_exit)
+#ifdef CONFIG_FUNCTION_TRACER
+ .import ftrace_function_trampoline,code
+ENTRY(_mcount)
+ copy %r3, %arg2
+ b ftrace_function_trampoline
+ nop
+ENDPROC(_mcount)
+
+ENTRY(return_to_handler)
+ load32 return_trampoline, %rp
+ copy %ret0, %arg0
+ copy %ret1, %arg1
+ b ftrace_return_to_handler
+ nop
+return_trampoline:
+ copy %ret0, %rp
+ copy %r23, %ret0
+ copy %r24, %ret1
+
+.globl ftrace_stub
+ftrace_stub:
+ bv %r0(%rp)
+ nop
+ENDPROC(return_to_handler)
+#endif /* CONFIG_FUNCTION_TRACER */
+
+
get_register:
/*
* get_register is used by the non access tlb miss handlers to
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index f6d241238a78..4c247e02d9b1 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -527,7 +527,11 @@ int pdc_model_capabilities(unsigned long *capabilities)
pdc_result[0] = 0; /* preset zero (call may not be implemented!) */
retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
convert_to_wide(pdc_result);
- *capabilities = pdc_result[0];
+ if (retval == PDC_OK) {
+ *capabilities = pdc_result[0];
+ } else {
+ *capabilities = PDC_MODEL_OS32;
+ }
spin_unlock_irqrestore(&pdc_lock, flags);
return retval;
diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
new file mode 100644
index 000000000000..9877372ffdba
--- /dev/null
+++ b/arch/parisc/kernel/ftrace.c
@@ -0,0 +1,185 @@
+/*
+ * Code for tracing calls in Linux kernel.
+ * Copyright (C) 2009 Helge Deller <deller@gmx.de>
+ *
+ * based on code for x86 which is:
+ * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
+ *
+ * future possible enhancements:
+ * - add CONFIG_DYNAMIC_FTRACE
+ * - add CONFIG_STACK_TRACER
+ */
+
+#include <linux/init.h>
+#include <linux/ftrace.h>
+
+#include <asm/sections.h>
+#include <asm/ftrace.h>
+
+
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+/* Add a function return address to the trace stack on thread info.*/
+static int push_return_trace(unsigned long ret, unsigned long long time,
+ unsigned long func, int *depth)
+{
+ int index;
+
+ if (!current->ret_stack)
+ return -EBUSY;
+
+ /* The return trace stack is full */
+ if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) {
+ atomic_inc(&current->trace_overrun);
+ return -EBUSY;
+ }
+
+ index = ++current->curr_ret_stack;
+ barrier();
+ current->ret_stack[index].ret = ret;
+ current->ret_stack[index].func = func;
+ current->ret_stack[index].calltime = time;
+ *depth = index;
+
+ return 0;
+}
+
+/* Retrieve a function return address to the trace stack on thread info.*/
+static void pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret)
+{
+ int index;
+
+ index = current->curr_ret_stack;
+
+ if (unlikely(index < 0)) {
+ ftrace_graph_stop();
+ WARN_ON(1);
+ /* Might as well panic, otherwise we have no where to go */
+ *ret = (unsigned long)
+ dereference_function_descriptor(&panic);
+ return;
+ }
+
+ *ret = current->ret_stack[index].ret;
+ trace->func = current->ret_stack[index].func;
+ trace->calltime = current->ret_stack[index].calltime;
+ trace->overrun = atomic_read(&current->trace_overrun);
+ trace->depth = index;
+ barrier();
+ current->curr_ret_stack--;
+
+}
+
+/*
+ * Send the trace to the ring-buffer.
+ * @return the original return address.
+ */
+unsigned long ftrace_return_to_handler(unsigned long retval0,
+ unsigned long retval1)
+{
+ struct ftrace_graph_ret trace;
+ unsigned long ret;
+
+ pop_return_trace(&trace, &ret);
+ trace.rettime = cpu_clock(raw_smp_processor_id());
+ ftrace_graph_return(&trace);
+
+ if (unlikely(!ret)) {
+ ftrace_graph_stop();
+ WARN_ON(1);
+ /* Might as well panic. What else to do? */
+ ret = (unsigned long)
+ dereference_function_descriptor(&panic);
+ }
+
+ /* HACK: we hand over the old functions' return values
+ in %r23 and %r24. Assembly in entry.S will take care
+ and move those to their final registers %ret0 and %ret1 */
+ asm( "copy %0, %%r23 \n\t"
+ "copy %1, %%r24 \n" : : "r" (retval0), "r" (retval1) );
+
+ return ret;
+}
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
+{
+ unsigned long old;
+ unsigned long long calltime;
+ struct ftrace_graph_ent trace;
+
+ if (unlikely(atomic_read(&current->tracing_graph_pause)))
+ return;
+
+ old = *parent;
+ *parent = (unsigned long)
+ dereference_function_descriptor(&return_to_handler);
+
+ if (unlikely(!__kernel_text_address(old))) {
+ ftrace_graph_stop();
+ *parent = old;
+ WARN_ON(1);
+ return;
+ }
+
+ calltime = cpu_clock(raw_smp_processor_id());
+
+ if (push_return_trace(old, calltime,
+ self_addr, &trace.depth) == -EBUSY) {
+ *parent = old;
+ return;
+ }
+
+ trace.func = self_addr;
+
+ /* Only trace if the calling function expects to */
+ if (!ftrace_graph_entry(&trace)) {
+ current->curr_ret_stack--;
+ *parent = old;
+ }
+}
+
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+
+void ftrace_function_trampoline(unsigned long parent,
+ unsigned long self_addr,
+ unsigned long org_sp_gr3)
+{
+ extern ftrace_func_t ftrace_trace_function;
+
+ if (function_trace_stop)
+ return;
+
+ if (ftrace_trace_function != ftrace_stub) {
+ ftrace_trace_function(parent, self_addr);
+ return;
+ }
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ if (ftrace_graph_entry && ftrace_graph_return) {
+ unsigned long sp;
+ unsigned long *parent_rp;
+
+ asm volatile ("copy %%r30, %0" : "=r"(sp));
+ /* sanity check: is stack pointer which we got from
+ assembler function in entry.S in a reasonable
+ range compared to current stack pointer? */
+ if ((sp - org_sp_gr3) > 0x400)
+ return;
+
+ /* calculate pointer to %rp in stack */
+ parent_rp = (unsigned long *) org_sp_gr3 - 0x10;
+ /* sanity check: parent_rp should hold parent */
+ if (*parent_rp != parent)
+ return;
+
+ prepare_ftrace_return(parent_rp, self_addr);
+ return;
+ }
+#endif
+}
+
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 2b5f5915dd1d..4ea4229d765c 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -185,7 +185,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%3d: ", i);
#ifdef CONFIG_SMP
for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#else
seq_printf(p, "%10u ", kstat_irqs(i));
#endif
@@ -311,12 +311,12 @@ unsigned long txn_alloc_addr(unsigned int virt_irq)
next_cpu++; /* assign to "next" CPU we want this bugger on */
/* validate entry */
- while ((next_cpu < NR_CPUS) &&
+ while ((next_cpu < nr_cpu_ids) &&
(!per_cpu(cpu_data, next_cpu).txn_addr ||
!cpu_online(next_cpu)))
next_cpu++;
- if (next_cpu >= NR_CPUS)
+ if (next_cpu >= nr_cpu_ids)
next_cpu = 0; /* nothing else, assign monarch */
return txn_affinity_addr(virt_irq, next_cpu);
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index 9013243cecca..ecd1c5024447 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -61,9 +61,7 @@
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/bug.h>
-#include <linux/uaccess.h>
-#include <asm/sections.h>
#include <asm/unwind.h>
#if 0
@@ -115,8 +113,6 @@ struct got_entry {
Elf32_Addr addr;
};
-#define Elf_Fdesc Elf32_Fdesc
-
struct stub_entry {
Elf32_Word insns[2]; /* each stub entry has two insns */
};
@@ -125,8 +121,6 @@ struct got_entry {
Elf64_Addr addr;
};
-#define Elf_Fdesc Elf64_Fdesc
-
struct stub_entry {
Elf64_Word insns[4]; /* each stub entry has four insns */
};
@@ -916,15 +910,3 @@ void module_arch_cleanup(struct module *mod)
deregister_unwind_table(mod);
module_bug_cleanup(mod);
}
-
-#ifdef CONFIG_64BIT
-void *dereference_function_descriptor(void *ptr)
-{
- Elf64_Fdesc *desc = ptr;
- void *p;
-
- if (!probe_kernel_address(&desc->addr, p))
- ptr = p;
- return ptr;
-}
-#endif
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
index 0eecfbbc59cd..df653663d3db 100644
--- a/arch/parisc/kernel/parisc_ksyms.c
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -153,5 +153,10 @@ EXPORT_SYMBOL(node_data);
EXPORT_SYMBOL(pfnnid_map);
#endif
+#ifdef CONFIG_FUNCTION_TRACER
+extern void _mcount(void);
+EXPORT_SYMBOL(_mcount);
+#endif
+
/* from pacache.S -- needed for copy_page */
EXPORT_SYMBOL(copy_user_page_asm);
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index b80e02a4d81d..6f69101f90bb 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -46,14 +46,15 @@
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/kallsyms.h>
+#include <linux/uaccess.h>
#include <asm/io.h>
#include <asm/asm-offsets.h>
#include <asm/pdc.h>
#include <asm/pdc_chassis.h>
#include <asm/pgalloc.h>
-#include <asm/uaccess.h>
#include <asm/unwind.h>
+#include <asm/sections.h>
/*
* The idle thread. There's no useful work to be
@@ -231,8 +232,8 @@ sys_clone(unsigned long clone_flags, unsigned long usp,
However, these last 3 args are only examined
if the proper flags are set. */
- int __user *child_tidptr;
- int __user *parent_tidptr;
+ int __user *parent_tidptr = (int __user *)regs->gr[24];
+ int __user *child_tidptr = (int __user *)regs->gr[22];
/* usp must be word aligned. This also prevents users from
* passing in the value 1 (which is the signal for a special
@@ -243,16 +244,6 @@ sys_clone(unsigned long clone_flags, unsigned long usp,
if (usp == 0)
usp = regs->gr[30];
- if (clone_flags & CLONE_PARENT_SETTID)
- parent_tidptr = (int __user *)regs->gr[24];
- else
- parent_tidptr = NULL;
-
- if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID))
- child_tidptr = (int __user *)regs->gr[22];
- else
- child_tidptr = NULL;
-
return do_fork(clone_flags, usp, regs, 0, parent_tidptr, child_tidptr);
}
@@ -263,7 +254,7 @@ sys_vfork(struct pt_regs *regs)
}
int
-copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused, /* in ia64 this is "user_stack_size" */
struct task_struct * p, struct pt_regs * pregs)
{
@@ -400,3 +391,15 @@ get_wchan(struct task_struct *p)
} while (count++ < 16);
return 0;
}
+
+#ifdef CONFIG_64BIT
+void *dereference_function_descriptor(void *ptr)
+{
+ Elf64_Fdesc *desc = ptr;
+ void *p;
+
+ if (!probe_kernel_address(&desc->addr, p))
+ ptr = p;
+ return ptr;
+}
+#endif
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index ecb609342feb..e09d0f7fb6b0 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -100,8 +100,8 @@ static int __cpuinit processor_probe(struct parisc_device *dev)
struct cpuinfo_parisc *p;
#ifdef CONFIG_SMP
- if (num_online_cpus() >= NR_CPUS) {
- printk(KERN_INFO "num_online_cpus() >= NR_CPUS\n");
+ if (num_online_cpus() >= nr_cpu_ids) {
+ printk(KERN_INFO "num_online_cpus() >= nr_cpu_ids\n");
return 1;
}
#else
@@ -214,7 +214,7 @@ static int __cpuinit processor_probe(struct parisc_device *dev)
*/
#ifdef CONFIG_SMP
if (cpuid) {
- cpu_set(cpuid, cpu_present_map);
+ set_cpu_present(cpuid, true);
cpu_up(cpuid);
}
#endif
@@ -364,6 +364,13 @@ show_cpuinfo (struct seq_file *m, void *v)
boot_cpu_data.cpu_hz / 1000000,
boot_cpu_data.cpu_hz % 1000000 );
+ seq_printf(m, "capabilities\t:");
+ if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS32)
+ seq_printf(m, " os32");
+ if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS64)
+ seq_printf(m, " os64");
+ seq_printf(m, "\n");
+
seq_printf(m, "model\t\t: %s\n"
"model name\t: %s\n",
boot_cpu_data.pdc.sys_model_name,
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 9995d7ed5819..1fd0f0cec037 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -31,6 +31,7 @@
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/bitops.h>
+#include <linux/ftrace.h>
#include <asm/system.h>
#include <asm/atomic.h>
@@ -113,14 +114,14 @@ halt_processor(void)
{
/* REVISIT : redirect I/O Interrupts to another CPU? */
/* REVISIT : does PM *know* this CPU isn't available? */
- cpu_clear(smp_processor_id(), cpu_online_map);
+ set_cpu_online(smp_processor_id(), false);
local_irq_disable();
for (;;)
;
}
-irqreturn_t
+irqreturn_t __irq_entry
ipi_interrupt(int irq, void *dev_id)
{
int this_cpu = smp_processor_id();
@@ -214,11 +215,11 @@ ipi_send(int cpu, enum ipi_message_type op)
}
static void
-send_IPI_mask(cpumask_t mask, enum ipi_message_type op)
+send_IPI_mask(const struct cpumask *mask, enum ipi_message_type op)
{
int cpu;
- for_each_cpu_mask(cpu, mask)
+ for_each_cpu(cpu, mask)
ipi_send(cpu, op);
}
@@ -257,7 +258,7 @@ smp_send_all_nop(void)
send_IPI_allbutself(IPI_NOP);
}
-void arch_send_call_function_ipi(cpumask_t mask)
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
{
send_IPI_mask(mask, IPI_CALL_FUNC);
}
@@ -296,13 +297,14 @@ smp_cpu_init(int cpunum)
mb();
/* Well, support 2.4 linux scheme as well. */
- if (cpu_test_and_set(cpunum, cpu_online_map))
+ if (cpu_isset(cpunum, cpu_online_map))
{
extern void machine_halt(void); /* arch/parisc.../process.c */
printk(KERN_CRIT "CPU#%d already initialized!\n", cpunum);
machine_halt();
}
+ set_cpu_online(cpunum, true);
/* Initialise the idle task for this CPU */
atomic_inc(&init_mm.mm_count);
@@ -424,8 +426,8 @@ void __init smp_prepare_boot_cpu(void)
/* Setup BSP mappings */
printk(KERN_INFO "SMP: bootstrap CPU ID is %d\n", bootstrap_processor);
- cpu_set(bootstrap_processor, cpu_online_map);
- cpu_set(bootstrap_processor, cpu_present_map);
+ set_cpu_online(bootstrap_processor, true);
+ set_cpu_present(bootstrap_processor, true);
}
@@ -436,8 +438,7 @@ void __init smp_prepare_boot_cpu(void)
*/
void __init smp_prepare_cpus(unsigned int max_cpus)
{
- cpus_clear(cpu_present_map);
- cpu_set(0, cpu_present_map);
+ init_cpu_present(cpumask_of(0));
parisc_max_cpus = max_cpus;
if (!max_cpus)
diff --git a/arch/parisc/kernel/stacktrace.c b/arch/parisc/kernel/stacktrace.c
new file mode 100644
index 000000000000..2fe914c5f533
--- /dev/null
+++ b/arch/parisc/kernel/stacktrace.c
@@ -0,0 +1,63 @@
+/*
+ * Stack trace management functions
+ *
+ * Copyright (C) 2009 Helge Deller <deller@gmx.de>
+ * based on arch/x86/kernel/stacktrace.c by Ingo Molnar <mingo@redhat.com>
+ * and parisc unwind functions by Randolph Chung <tausq@debian.org>
+ *
+ * TODO: Userspace stacktrace (CONFIG_USER_STACKTRACE_SUPPORT)
+ */
+#include <linux/module.h>
+#include <linux/stacktrace.h>
+
+#include <asm/unwind.h>
+
+static void dump_trace(struct task_struct *task, struct stack_trace *trace)
+{
+ struct unwind_frame_info info;
+
+ /* initialize unwind info */
+ if (task == current) {
+ unsigned long sp;
+ struct pt_regs r;
+HERE:
+ asm volatile ("copy %%r30, %0" : "=r"(sp));
+ memset(&r, 0, sizeof(struct pt_regs));
+ r.iaoq[0] = (unsigned long)&&HERE;
+ r.gr[2] = (unsigned long)__builtin_return_address(0);
+ r.gr[30] = sp;
+ unwind_frame_init(&info, task, &r);
+ } else {
+ unwind_frame_init_from_blocked_task(&info, task);
+ }
+
+ /* unwind stack and save entries in stack_trace struct */
+ trace->nr_entries = 0;
+ while (trace->nr_entries < trace->max_entries) {
+ if (unwind_once(&info) < 0 || info.ip == 0)
+ break;
+
+ if (__kernel_text_address(info.ip))
+ trace->entries[trace->nr_entries++] = info.ip;
+ }
+}
+
+
+/*
+ * Save stack-backtrace addresses into a stack_trace buffer.
+ */
+void save_stack_trace(struct stack_trace *trace)
+{
+ dump_trace(current, trace);
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+EXPORT_SYMBOL_GPL(save_stack_trace);
+
+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+{
+ dump_trace(tsk, trace);
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 69b6eebc466e..59fc1a43ec3e 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -365,17 +365,51 @@ tracesys_sigexit:
/*********************************************************
- Light-weight-syscall code
+ 32/64-bit Light-Weight-Syscall ABI
- r20 - lws number
- r26,r25,r24,r23,r22 - Input registers
- r28 - Function return register
- r21 - Error code.
+ * - Indicates a hint for userspace inline asm
+ implementations.
- Scracth: Any of the above that aren't being
- currently used, including r1.
+ Syscall number (caller-saves)
+ - %r20
+ * In asm clobber.
- Return pointer: r31 (Not usable)
+ Argument registers (caller-saves)
+ - %r26, %r25, %r24, %r23, %r22
+ * In asm input.
+
+ Return registers (caller-saves)
+ - %r28 (return), %r21 (errno)
+ * In asm output.
+
+ Caller-saves registers
+ - %r1, %r27, %r29
+ - %r2 (return pointer)
+ - %r31 (ble link register)
+ * In asm clobber.
+
+ Callee-saves registers
+ - %r3-%r18
+ - %r30 (stack pointer)
+ * Not in asm clobber.
+
+ If userspace is 32-bit:
+ Callee-saves registers
+ - %r19 (32-bit PIC register)
+
+ Differences from 32-bit calling convention:
+ - Syscall number in %r20
+ - Additional argument register %r22 (arg4)
+ - Callee-saves %r19.
+
+ If userspace is 64-bit:
+ Callee-saves registers
+ - %r27 (64-bit PIC register)
+
+ Differences from 64-bit calling convention:
+ - Syscall number in %r20
+ - Additional argument register %r22 (arg4)
+ - Callee-saves %r27.
Error codes returned by entry path:
@@ -473,7 +507,8 @@ lws_compare_and_swap64:
b,n lws_compare_and_swap
#else
/* If we are not a 64-bit kernel, then we don't
- * implement having 64-bit input registers
+ * have 64-bit input registers, and calling
+ * the 64-bit LWS CAS returns ENOSYS.
*/
b,n lws_exit_nosys
#endif
@@ -635,12 +670,15 @@ END(sys_call_table64)
/*
All light-weight-syscall atomic operations
will use this set of locks
+
+ NOTE: The lws_lock_start symbol must be
+ at least 16-byte aligned for safe use
+ with ldcw.
*/
.section .data
.align PAGE_SIZE
ENTRY(lws_lock_start)
/* lws locks */
- .align 16
.rept 16
/* Keep locks aligned at 16-bytes */
.word 1
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 303d2b647e41..03b9a01bc16c 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -130,7 +130,7 @@
ENTRY_OURS(newuname)
ENTRY_SAME(umask) /* 60 */
ENTRY_SAME(chroot)
- ENTRY_SAME(ustat)
+ ENTRY_COMP(ustat)
ENTRY_SAME(dup2)
ENTRY_SAME(getppid)
ENTRY_SAME(getpgrp) /* 65 */
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index 9d46c43a4152..d4dd05674c62 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -24,6 +24,7 @@
#include <linux/profile.h>
#include <linux/clocksource.h>
#include <linux/platform_device.h>
+#include <linux/ftrace.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -53,7 +54,7 @@ static unsigned long clocktick __read_mostly; /* timer cycles per tick */
* held off for an arbitrarily long period of time by interrupts being
* disabled, so we may miss one or more ticks.
*/
-irqreturn_t timer_interrupt(int irq, void *dev_id)
+irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
{
unsigned long now;
unsigned long next_tick;
@@ -216,17 +217,14 @@ void __init start_cpu_itimer(void)
per_cpu(cpu_data, cpu).it_value = next_tick;
}
-struct platform_device rtc_parisc_dev = {
- .name = "rtc-parisc",
+static struct platform_device rtc_generic_dev = {
+ .name = "rtc-generic",
.id = -1,
};
static int __init rtc_init(void)
{
- int ret;
-
- ret = platform_device_register(&rtc_parisc_dev);
- if (ret < 0)
+ if (platform_device_register(&rtc_generic_dev) < 0)
printk(KERN_ERR "unable to register rtc device...\n");
/* not necessarily an error */
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index ba658d2086f7..c32f5d6d778e 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -247,6 +247,8 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
oops_in_progress = 1;
+ oops_enter();
+
/* Amuse the user in a SPARC fashion */
if (err) printk(
KERN_CRIT " _______________________________ \n"
@@ -293,6 +295,7 @@ KERN_CRIT " || ||\n");
panic("Fatal exception");
}
+ oops_exit();
do_exit(SIGSEGV);
}
@@ -494,7 +497,7 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o
panic(msg);
}
-void handle_interruption(int code, struct pt_regs *regs)
+void notrace handle_interruption(int code, struct pt_regs *regs)
{
unsigned long fault_address = 0;
unsigned long fault_space = 0;
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 1a3b6ccd3620..fd2cc4fd2b65 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -54,6 +54,8 @@ SECTIONS
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT
+ KPROBES_TEXT
+ IRQENTRY_TEXT
*(.text.do_softirq)
*(.text.sys_exit)
*(.text.do_sigaltstack)
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 9d704d9831d1..4356ceb1e366 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -456,6 +456,13 @@ void __init mem_init(void)
{
int codesize, reservedpages, datasize, initsize;
+ /* Do sanity checks on page table constants */
+ BUILD_BUG_ON(PTE_ENTRY_SIZE != sizeof(pte_t));
+ BUILD_BUG_ON(PMD_ENTRY_SIZE != sizeof(pmd_t));
+ BUILD_BUG_ON(PGD_ENTRY_SIZE != sizeof(pgd_t));
+ BUILD_BUG_ON(PAGE_SHIFT + BITS_PER_PTE + BITS_PER_PMD + BITS_PER_PGD
+ > BITS_PER_LONG);
+
high_memory = __va((max_pfn << PAGE_SHIFT));
#ifndef CONFIG_DISCONTIGMEM
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 74cc312c347c..9e08d8a69fdf 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -111,6 +111,7 @@ config PPC
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_TRACER
+ select HAVE_FUNCTION_GRAPH_TRACER
select ARCH_WANT_OPTIONAL_GPIOLIB
select HAVE_IDE
select HAVE_IOREMAP_PROT
@@ -227,6 +228,9 @@ config PPC_OF_PLATFORM_PCI
depends on PPC64 # not supported on 32 bits yet
default n
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ def_bool y
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
@@ -312,7 +316,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE
config KEXEC
bool "kexec system call (EXPERIMENTAL)"
- depends on (PPC_PRPMC2800 || PPC_MULTIPLATFORM) && EXPERIMENTAL
+ depends on BOOK3S && EXPERIMENTAL
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
@@ -342,7 +346,7 @@ config PHYP_DUMP
help
Hypervisor-assisted dump is meant to be a kdump replacement
offering robustness and speed not possible without system
- hypervisor assistence.
+ hypervisor assistance.
If unsure, say "N"
@@ -409,6 +413,18 @@ config PPC_HAS_HASH_64K
depends on PPC64
default n
+config STDBINUTILS
+ bool "Using standard binutils settings"
+ depends on 44x
+ default y
+ help
+ Turning this option off allows you to select 256KB PAGE_SIZE on 44x.
+ Note, that kernel will be able to run only those applications,
+ which had been compiled using binutils later than 2.17.50.0.3 with
+ '-zmax-page-size' set to 256K (the default is 64K). Or, if using
+ the older binutils, you can patch them with a trivial patch, which
+ changes the ELF_MAXPAGESIZE definition from 0x10000 to 0x40000.
+
choice
prompt "Page size"
default PPC_4K_PAGES
@@ -444,6 +460,19 @@ config PPC_64K_PAGES
bool "64k page size" if 44x || PPC_STD_MMU_64
select PPC_HAS_HASH_64K if PPC_STD_MMU_64
+config PPC_256K_PAGES
+ bool "256k page size" if 44x
+ depends on !STDBINUTILS && (!SHMEM || BROKEN)
+ help
+ Make the page size 256k.
+
+ As the ELF standard only requires alignment to support page
+ sizes up to 64k, you will need to compile all of your user
+ space applications with a non-standard binutils settings
+ (see the STDBINUTILS description for details).
+
+ Say N unless you know what you are doing.
+
endchoice
config FORCE_MAX_ZONEORDER
@@ -456,6 +485,8 @@ config FORCE_MAX_ZONEORDER
default "9" if PPC_STD_MMU_32 && PPC_16K_PAGES
range 7 64 if PPC_STD_MMU_32 && PPC_64K_PAGES
default "7" if PPC_STD_MMU_32 && PPC_64K_PAGES
+ range 5 64 if PPC_STD_MMU_32 && PPC_256K_PAGES
+ default "5" if PPC_STD_MMU_32 && PPC_256K_PAGES
range 11 64
default "11"
help
@@ -594,6 +625,7 @@ config FSL_SOC
config FSL_PCI
bool
select PPC_INDIRECT_PCI
+ select PCI_QUIRKS
config 4xx_SOC
bool
@@ -730,6 +762,22 @@ config LOWMEM_SIZE
hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL
default "0x30000000"
+config LOWMEM_CAM_NUM_BOOL
+ bool "Set number of CAMs to use to map low memory"
+ depends on ADVANCED_OPTIONS && FSL_BOOKE
+ help
+ This option allows you to set the maximum number of CAM slots that
+ will be used to map low memory. There are a limited number of slots
+ available and even more limited number that will fit in the L1 MMU.
+ However, using more entries will allow mapping more low memory. This
+ can be useful in optimizing the layout of kernel virtual memory.
+
+ Say N here unless you know what you are doing.
+
+config LOWMEM_CAM_NUM
+ int "Number of CAMs to use to map low memory" if LOWMEM_CAM_NUM_BOOL
+ default 3
+
config RELOCATABLE
bool "Build a relocatable kernel (EXPERIMENTAL)"
depends on EXPERIMENTAL && ADVANCED_OPTIONS && FLATMEM && FSL_BOOKE
@@ -794,7 +842,7 @@ config PHYSICAL_START
config PHYSICAL_ALIGN
hex
- default "0x10000000" if FSL_BOOKE
+ default "0x04000000" if FSL_BOOKE
help
This value puts the alignment restrictions on physical address
where kernel is loaded and run from. Kernel is compiled for an
@@ -815,31 +863,6 @@ config TASK_SIZE
default "0x80000000" if PPC_PREP || PPC_8xx
default "0xc0000000"
-config CONSISTENT_START_BOOL
- bool "Set custom consistent memory pool address"
- depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
- help
- This option allows you to set the base virtual address
- of the consistent memory pool. This pool of virtual
- memory is used to make consistent memory allocations.
-
-config CONSISTENT_START
- hex "Base virtual address of consistent memory pool" if CONSISTENT_START_BOOL
- default "0xfd000000" if (NOT_COHERENT_CACHE && 8xx)
- default "0xff100000" if NOT_COHERENT_CACHE
-
-config CONSISTENT_SIZE_BOOL
- bool "Set custom consistent memory pool size"
- depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE
- help
- This option allows you to set the size of the
- consistent memory pool. This pool of virtual memory
- is used to make consistent memory allocations.
-
-config CONSISTENT_SIZE
- hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL
- default "0x00200000" if NOT_COHERENT_CACHE
-
config PIN_TLB
bool "Pinned Kernel TLBs (860 ONLY)"
depends on ADVANCED_OPTIONS && 8xx
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 08f7cc0a1953..a1098e23221f 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -27,15 +27,6 @@ config DEBUG_STACK_USAGE
This option will slow down process creation somewhat.
-config DEBUG_PAGEALLOC
- bool "Debug page memory allocations"
- depends on DEBUG_KERNEL && !HIBERNATION
- help
- Unmap pages from the kernel linear mapping after free_pages().
- This results in a large slowdown, but helps to find certain types
- of memory corruptions.
-
-
config HCALL_STATS
bool "Hypervisor call instrumentation"
depends on PPC_PSERIES && DEBUG_FS
@@ -129,7 +120,7 @@ config BDI_SWITCH
config BOOTX_TEXT
bool "Support for early boot text console (BootX or OpenFirmware only)"
- depends on PPC_OF && PPC_MULTIPLATFORM
+ depends on PPC_OF && PPC_BOOK3S
help
Say Y here to see progress messages from the boot firmware in text
mode. Requires either BootX or Open Firmware.
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 72d17f50e54f..551fc58c05cf 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -147,8 +147,8 @@ core-y += arch/powerpc/kernel/ \
arch/powerpc/mm/ \
arch/powerpc/lib/ \
arch/powerpc/sysdev/ \
- arch/powerpc/platforms/
-core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/
+ arch/powerpc/platforms/ \
+ arch/powerpc/math-emu/
core-$(CONFIG_XMON) += arch/powerpc/xmon/
core-$(CONFIG_KVM) += arch/powerpc/kvm/
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index e84df338ea29..4458abb67c51 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -70,7 +70,7 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c
cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \
cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \
virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \
- cuboot-acadia.c
+ cuboot-acadia.c cuboot-amigaone.c
src-boot := $(src-wlib) $(src-plat) empty.c
src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -235,7 +235,9 @@ image-$(CONFIG_PPC_ADDER875) += cuImage.adder875-uboot \
dtbImage.adder875-redboot
# Board ports in arch/powerpc/platform/52xx/Kconfig
-image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200 cuImage.lite5200b
+image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200 lite5200.dtb
+image-$(CONFIG_PPC_LITE5200) += cuImage.lite5200b lite5200b.dtb
+image-$(CONFIG_PPC_MEDIA5200) += cuImage.media5200 media5200.dtb
# Board ports in arch/powerpc/platform/82xx/Kconfig
image-$(CONFIG_MPC8272_ADS) += cuImage.mpc8272ads
@@ -274,6 +276,9 @@ image-$(CONFIG_STORCENTER) += cuImage.storcenter
image-$(CONFIG_MPC7448HPC2) += cuImage.mpc7448hpc2
image-$(CONFIG_PPC_C2K) += cuImage.c2k
+# Board port in arch/powerpc/platform/amigaone/Kconfig
+image-$(CONFIG_AMIGAONE) += cuImage.amigaone
+
# For 32-bit powermacs, build the COFF and miboot images
# as well as the ELF images.
ifeq ($(CONFIG_PPC32),y)
diff --git a/arch/powerpc/boot/cuboot-amigaone.c b/arch/powerpc/boot/cuboot-amigaone.c
new file mode 100644
index 000000000000..d5029674030b
--- /dev/null
+++ b/arch/powerpc/boot/cuboot-amigaone.c
@@ -0,0 +1,35 @@
+/*
+ * Old U-boot compatibility for AmigaOne
+ *
+ * Author: Gerhard Pircher (gerhard_pircher@gmx.net)
+ *
+ * Based on cuboot-83xx.c
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "ops.h"
+#include "stdio.h"
+#include "cuboot.h"
+
+#include "ppcboot.h"
+
+static bd_t bd;
+
+static void platform_fixups(void)
+{
+ dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
+ dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq);
+}
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7)
+{
+ CUBOOT_INIT();
+ fdt_init(_dtb_start);
+ serial_console_init();
+ platform_ops.fixups = platform_fixups;
+}
diff --git a/arch/powerpc/boot/dts/amigaone.dts b/arch/powerpc/boot/dts/amigaone.dts
new file mode 100644
index 000000000000..26549fca2ed4
--- /dev/null
+++ b/arch/powerpc/boot/dts/amigaone.dts
@@ -0,0 +1,173 @@
+/*
+ * AmigaOne Device Tree Source
+ *
+ * Copyright 2008 Gerhard Pircher (gerhard_pircher@gmx.net)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+ model = "AmigaOne";
+ compatible = "eyetech,amigaone";
+ coherency-off;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #cpus = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <32768>; // L1, 32K
+ i-cache-size = <32768>; // L1, 32K
+ timebase-frequency = <0>; // 33.3 MHz, from U-boot
+ clock-frequency = <0>; // From U-boot
+ bus-frequency = <0>; // From U-boot
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0>; // From U-boot
+ };
+
+ pci@80000000 {
+ device_type = "pci";
+ compatible = "mai-logic,articia-s";
+ bus-frequency = <33333333>;
+ bus-range = <0 0xff>;
+ ranges = <0x01000000 0 0x00000000 0xfe000000 0 0x00c00000 // PCI I/O
+ 0x02000000 0 0x80000000 0x80000000 0 0x7d000000 // PCI memory
+ 0x02000000 0 0x00000000 0xfd000000 0 0x01000000>; // PCI alias memory (ISA)
+ // Configuration address and data register.
+ reg = <0xfec00cf8 4
+ 0xfee00cfc 4>;
+ 8259-interrupt-acknowledge = <0xfef00000>;
+ // Do not define a interrupt-parent here, if there is no
+ // interrupt-map property.
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ isa@7 {
+ device_type = "isa";
+ compatible = "pciclass,0601";
+ vendor-id = <0x00001106>;
+ device-id = <0x00000686>;
+ revision-id = <0x00000010>;
+ class-code = <0x00060100>;
+ subsystem-id = <0>;
+ subsystem-vendor-id = <0>;
+ devsel-speed = <0x00000001>;
+ min-grant = <0>;
+ max-latency = <0>;
+ /* First 64k for I/O at 0x0 on PCI mapped to 0x0 on ISA. */
+ ranges = <0x00000001 0 0x01000000 0 0x00000000 0x00010000>;
+ interrupt-parent = <&i8259>;
+ #interrupt-cells = <2>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ dma-controller@0 {
+ compatible = "pnpPNP,200";
+ reg = <1 0x00000000 0x00000020
+ 1 0x00000080 0x00000010
+ 1 0x000000c0 0x00000020>;
+ };
+
+ i8259: interrupt-controller@20 {
+ device_type = "interrupt-controller";
+ compatible = "pnpPNP,000";
+ interrupt-controller;
+ reg = <1 0x00000020 0x00000002
+ 1 0x000000a0 0x00000002
+ 1 0x000004d0 0x00000002>;
+ reserved-interrupts = <2>;
+ #interrupt-cells = <2>;
+ };
+
+ timer@40 {
+ // Also adds pcspkr to platform devices.
+ compatible = "pnpPNP,100";
+ reg = <1 0x00000040 0x00000020>;
+ };
+
+ 8042@60 {
+ device_type = "8042";
+ reg = <1 0x00000060 0x00000001
+ 1 0x00000064 0x00000001>;
+ interrupts = <1 3 12 3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ keyboard@0 {
+ compatible = "pnpPNP,303";
+ reg = <0>;
+ };
+
+ mouse@1 {
+ compatible = "pnpPNP,f03";
+ reg = <1>;
+ };
+ };
+
+ rtc@70 {
+ compatible = "pnpPNP,b00";
+ reg = <1 0x00000070 0x00000002>;
+ interrupts = <8 3>;
+ };
+
+ serial@3f8 {
+ device_type = "serial";
+ compatible = "pnpPNP,501","pnpPNP,500";
+ reg = <1 0x000003f8 0x00000008>;
+ interrupts = <4 3>;
+ clock-frequency = <1843200>;
+ current-speed = <115200>;
+ };
+
+ serial@2f8 {
+ device_type = "serial";
+ compatible = "pnpPNP,501","pnpPNP,500";
+ reg = <1 0x000002f8 0x00000008>;
+ interrupts = <3 3>;
+ clock-frequency = <1843200>;
+ current-speed = <115200>;
+ };
+
+ parallel@378 {
+ device_type = "parallel";
+ // No ECP support for now, otherwise add "pnpPNP,401".
+ compatible = "pnpPNP,400";
+ reg = <1 0x00000378 0x00000003
+ 1 0x00000778 0x00000003>;
+ };
+
+ fdc@3f0 {
+ device_type = "fdc";
+ compatible = "pnpPNP,700";
+ reg = <1 0x000003f0 0x00000008>;
+ interrupts = <6 3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ disk@0 {
+ reg = <0>;
+ };
+ };
+ };
+ };
+
+ chosen {
+ linux,stdout-path = "/pci@80000000/isa@7/serial@3f8";
+ };
+};
diff --git a/arch/powerpc/boot/dts/asp834x-redboot.dts b/arch/powerpc/boot/dts/asp834x-redboot.dts
index 524af7ef9f26..7da84fd7be93 100644
--- a/arch/powerpc/boot/dts/asp834x-redboot.dts
+++ b/arch/powerpc/boot/dts/asp834x-redboot.dts
@@ -181,70 +181,76 @@
phy_type = "ulpi";
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&ipic>;
- interrupts = <17 0x8>;
- reg = <0x1>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&ipic>;
- interrupts = <18 0x8>;
- reg = <0x2>;
- device_type = "ethernet-phy";
- };
-
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 08 e5 11 32 33 ];
interrupts = <32 0x8 33 0x8 34 0x8>;
interrupt-parent = <&ipic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
linux,network-index = <0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&ipic>;
+ interrupts = <17 0x8>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&ipic>;
+ interrupts = <18 0x8>;
+ reg = <0x2>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 08 e5 11 32 34 ];
interrupts = <35 0x8 36 0x8 37 0x8>;
interrupt-parent = <&ipic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
linux,network-index = <1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts
index 8b5ba8261a36..5fd1ad09bdf2 100644
--- a/arch/powerpc/boot/dts/canyonlands.dts
+++ b/arch/powerpc/boot/dts/canyonlands.dts
@@ -127,6 +127,13 @@
dcr-reg = <0x010 0x002>;
};
+ CRYPTO: crypto@180000 {
+ compatible = "amcc,ppc460ex-crypto", "amcc,ppc4xx-crypto";
+ reg = <4 0x00180000 0x80400>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0x1d 0x4>;
+ };
+
MAL0: mcmal {
compatible = "ibm,mcmal-460ex", "ibm,mcmal2";
dcr-reg = <0x180 0x062>;
@@ -142,6 +149,20 @@
/*RXDE*/ 0x5 0x4>;
};
+ USB0: ehci@bffd0400 {
+ compatible = "ibm,usb-ehci-460ex", "usb-ehci";
+ interrupt-parent = <&UIC2>;
+ interrupts = <0x1d 4>;
+ reg = <4 0xbffd0400 0x90 4 0xbffd0490 0x70>;
+ };
+
+ USB1: usb@bffd0000 {
+ compatible = "ohci-le";
+ reg = <4 0xbffd0000 0x60>;
+ interrupt-parent = <&UIC2>;
+ interrupts = <0x1e 4>;
+ };
+
POB0: opb {
compatible = "ibm,opb-460ex", "ibm,opb";
#address-cells = <1>;
@@ -245,6 +266,20 @@
reg = <0xef600700 0x00000014>;
interrupt-parent = <&UIC0>;
interrupts = <0x2 0x4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ rtc@68 {
+ compatible = "stm,m41t80";
+ reg = <0x68>;
+ interrupt-parent = <&UIC2>;
+ interrupts = <0x19 0x8>;
+ };
+ sttm@48 {
+ compatible = "ad,ad7414";
+ reg = <0x48>;
+ interrupt-parent = <&UIC1>;
+ interrupts = <0x14 0x8>;
+ };
};
IIC1: i2c@ef600800 {
diff --git a/arch/powerpc/boot/dts/cm5200.dts b/arch/powerpc/boot/dts/cm5200.dts
index 2f74cc4e093e..cee8080aa245 100644
--- a/arch/powerpc/boot/dts/cm5200.dts
+++ b/arch/powerpc/boot/dts/cm5200.dts
@@ -17,6 +17,7 @@
compatible = "schindler,cm5200";
#address-cells = <1>;
#size-cells = <1>;
+ interrupt-parent = <&mpc5200_pic>;
cpus {
#address-cells = <1>;
@@ -66,7 +67,6 @@
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x600 0x10>;
interrupts = <1 9 0>;
- interrupt-parent = <&mpc5200_pic>;
fsl,has-wdt;
};
@@ -74,84 +74,76 @@
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x610 0x10>;
interrupts = <1 10 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@620 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x620 0x10>;
interrupts = <1 11 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@630 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x630 0x10>;
interrupts = <1 12 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@640 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x640 0x10>;
interrupts = <1 13 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@650 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x650 0x10>;
interrupts = <1 14 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@660 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x660 0x10>;
interrupts = <1 15 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@670 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x670 0x10>;
interrupts = <1 16 0>;
- interrupt-parent = <&mpc5200_pic>;
};
rtc@800 { // Real time clock
compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
reg = <0x800 0x100>;
interrupts = <1 5 0 1 6 0>;
- interrupt-parent = <&mpc5200_pic>;
};
- gpio@b00 {
+ gpio_simple: gpio@b00 {
compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
reg = <0xb00 0x40>;
interrupts = <1 7 0>;
- interrupt-parent = <&mpc5200_pic>;
+ gpio-controller;
+ #gpio-cells = <2>;
};
- gpio@c00 {
+ gpio_wkup: gpio@c00 {
compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
reg = <0xc00 0x40>;
interrupts = <1 8 0 0 3 0>;
- interrupt-parent = <&mpc5200_pic>;
+ gpio-controller;
+ #gpio-cells = <2>;
};
spi@f00 {
compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
reg = <0xf00 0x20>;
interrupts = <2 13 0 2 14 0>;
- interrupt-parent = <&mpc5200_pic>;
};
usb@1000 {
compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
reg = <0x1000 0xff>;
interrupts = <2 6 0>;
- interrupt-parent = <&mpc5200_pic>;
};
dma-controller@1200 {
@@ -161,7 +153,6 @@
3 4 0 3 5 0 3 6 0 3 7 0
3 8 0 3 9 0 3 10 0 3 11 0
3 12 0 3 13 0 3 14 0 3 15 0>;
- interrupt-parent = <&mpc5200_pic>;
};
xlb@1f00 {
@@ -170,48 +161,34 @@
};
serial@2000 { // PSC1
- device_type = "serial";
compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
- port-number = <0>; // Logical port assignment
reg = <0x2000 0x100>;
interrupts = <2 1 0>;
- interrupt-parent = <&mpc5200_pic>;
};
serial@2200 { // PSC2
- device_type = "serial";
- compatible = "fsl,mpc5200-psc-uart";
- port-number = <1>; // Logical port assignment
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
reg = <0x2200 0x100>;
interrupts = <2 2 0>;
- interrupt-parent = <&mpc5200_pic>;
};
serial@2400 { // PSC3
- device_type = "serial";
- compatible = "fsl,mpc5200-psc-uart";
- port-number = <2>; // Logical port assignment
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
reg = <0x2400 0x100>;
interrupts = <2 3 0>;
- interrupt-parent = <&mpc5200_pic>;
};
serial@2c00 { // PSC6
- device_type = "serial";
compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
- port-number = <5>; // Logical port assignment
reg = <0x2c00 0x100>;
interrupts = <2 4 0>;
- interrupt-parent = <&mpc5200_pic>;
};
ethernet@3000 {
- device_type = "network";
compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
reg = <0x3000 0x400>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <2 5 0>;
- interrupt-parent = <&mpc5200_pic>;
phy-handle = <&phy0>;
};
@@ -221,10 +198,8 @@
compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts
interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
- interrupt-parent = <&mpc5200_pic>;
phy0: ethernet-phy@0 {
- device_type = "ethernet-phy";
reg = <0>;
};
};
@@ -235,7 +210,6 @@
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
- interrupt-parent = <&mpc5200_pic>;
fsl5200-clocking;
};
@@ -245,9 +219,8 @@
};
};
- lpb {
- model = "fsl,lpb";
- compatible = "fsl,lpb";
+ localbus {
+ compatible = "fsl,mpc5200b-lpb","simple-bus";
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0 0xfc000000 0x2000000>;
diff --git a/arch/powerpc/boot/dts/digsy_mtc.dts b/arch/powerpc/boot/dts/digsy_mtc.dts
new file mode 100644
index 000000000000..4c36186ef946
--- /dev/null
+++ b/arch/powerpc/boot/dts/digsy_mtc.dts
@@ -0,0 +1,254 @@
+/*
+ * Digsy MTC board Device Tree Source
+ *
+ * Copyright (C) 2009 Semihalf
+ *
+ * Based on the CM5200 by M. Balakowicz
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+ model = "intercontrol,digsy-mtc";
+ compatible = "intercontrol,digsy-mtc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&mpc5200_pic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,5200@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>; // from bootloader
+ bus-frequency = <0>; // from bootloader
+ clock-frequency = <0>; // from bootloader
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x02000000>; // 32MB
+ };
+
+ soc5200@f0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc5200b-immr";
+ ranges = <0 0xf0000000 0x0000c000>;
+ reg = <0xf0000000 0x00000100>;
+ bus-frequency = <0>; // from bootloader
+ system-frequency = <0>; // from bootloader
+
+ cdm@200 {
+ compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm";
+ reg = <0x200 0x38>;
+ };
+
+ mpc5200_pic: interrupt-controller@500 {
+ // 5200 interrupts are encoded into two levels;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
+ reg = <0x500 0x80>;
+ };
+
+ timer@600 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x600 0x10>;
+ interrupts = <1 9 0>;
+ fsl,has-wdt;
+ };
+
+ timer@610 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x610 0x10>;
+ interrupts = <1 10 0>;
+ };
+
+ timer@620 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x620 0x10>;
+ interrupts = <1 11 0>;
+ };
+
+ timer@630 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x630 0x10>;
+ interrupts = <1 12 0>;
+ };
+
+ timer@640 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x640 0x10>;
+ interrupts = <1 13 0>;
+ };
+
+ timer@650 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x650 0x10>;
+ interrupts = <1 14 0>;
+ };
+
+ timer@660 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x660 0x10>;
+ interrupts = <1 15 0>;
+ };
+
+ timer@670 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x670 0x10>;
+ interrupts = <1 16 0>;
+ };
+
+ gpio_simple: gpio@b00 {
+ compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
+ reg = <0xb00 0x40>;
+ interrupts = <1 7 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio_wkup: gpio@c00 {
+ compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
+ reg = <0xc00 0x40>;
+ interrupts = <1 8 0 0 3 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ spi@f00 {
+ compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
+ reg = <0xf00 0x20>;
+ interrupts = <2 13 0 2 14 0>;
+ };
+
+ usb@1000 {
+ compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
+ reg = <0x1000 0xff>;
+ interrupts = <2 6 0>;
+ };
+
+ dma-controller@1200 {
+ compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
+ reg = <0x1200 0x80>;
+ interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
+ 3 4 0 3 5 0 3 6 0 3 7 0
+ 3 8 0 3 9 0 3 10 0 3 11 0
+ 3 12 0 3 13 0 3 14 0 3 15 0>;
+ };
+
+ xlb@1f00 {
+ compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb";
+ reg = <0x1f00 0x100>;
+ };
+
+ serial@2600 { // PSC4
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+ reg = <0x2600 0x100>;
+ interrupts = <2 11 0>;
+ };
+
+ serial@2800 { // PSC5
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+ reg = <0x2800 0x100>;
+ interrupts = <2 12 0>;
+ };
+
+ ethernet@3000 {
+ compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
+ reg = <0x3000 0x400>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <2 5 0>;
+ phy-handle = <&phy0>;
+ };
+
+ mdio@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
+ reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts
+ interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ ata@3a00 {
+ compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
+ reg = <0x3a00 0x100>;
+ interrupts = <2 7 0>;
+ };
+
+ i2c@3d00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+ reg = <0x3d00 0x40>;
+ interrupts = <2 15 0>;
+ fsl5200-clocking;
+
+ rtc@50 {
+ compatible = "at,24c08";
+ reg = <0x50>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+ };
+
+ sram@8000 {
+ compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
+ reg = <0x8000 0x4000>;
+ };
+ };
+
+ lpb {
+ compatible = "fsl,mpc5200b-lpb","simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0xff000000 0x1000000>;
+
+ // 16-bit flash device at LocalPlus Bus CS0
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x1000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #size-cells = <1>;
+ #address-cells = <1>;
+
+ partition@0 {
+ label = "kernel";
+ reg = <0x0 0x00200000>;
+ };
+ partition@200000 {
+ label = "root";
+ reg = <0x00200000 0x00300000>;
+ };
+ partition@500000 {
+ label = "user";
+ reg = <0x00500000 0x00a00000>;
+ };
+ partition@f00000 {
+ label = "u-boot";
+ reg = <0x00f00000 0x100000>;
+ };
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/gef_ppc9a.dts b/arch/powerpc/boot/dts/gef_ppc9a.dts
new file mode 100644
index 000000000000..d47ad0718759
--- /dev/null
+++ b/arch/powerpc/boot/dts/gef_ppc9a.dts
@@ -0,0 +1,367 @@
+/*
+ * GE Fanuc PPC9A Device Tree Source
+ *
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Based on: SBS CM6 Device Tree Source
+ * Copyright 2007 SBS Technologies GmbH & Co. KG
+ * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
+ * Copyright 2006 Freescale Semiconductor Inc.
+ */
+
+/*
+ * Compiled with dtc -I dts -O dtb -o gef_ppc9a.dtb gef_ppc9a.dts
+ */
+
+/dts-v1/;
+
+/ {
+ model = "GEF_PPC9A";
+ compatible = "gef,ppc9a";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8641@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <32768>; // L1, 32K
+ i-cache-size = <32768>; // L1, 32K
+ timebase-frequency = <0>; // From uboot
+ bus-frequency = <0>; // From uboot
+ clock-frequency = <0>; // From uboot
+ };
+ PowerPC,8641@1 {
+ device_type = "cpu";
+ reg = <1>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <32768>; // L1, 32K
+ i-cache-size = <32768>; // L1, 32K
+ timebase-frequency = <0>; // From uboot
+ bus-frequency = <0>; // From uboot
+ clock-frequency = <0>; // From uboot
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x40000000>; // set by uboot
+ };
+
+ localbus@fef05000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8641-localbus", "simple-bus";
+ reg = <0xfef05000 0x1000>;
+ interrupts = <19 2>;
+ interrupt-parent = <&mpic>;
+
+ ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
+ 1 0 0xe8000000 0x08000000 // Paged Flash 0
+ 2 0 0xe0000000 0x08000000 // Paged Flash 1
+ 3 0 0xfc100000 0x00020000 // NVRAM
+ 4 0 0xfc000000 0x00008000 // FPGA
+ 5 0 0xfc008000 0x00008000 // AFIX FPGA
+ 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit)
+ 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit)
+
+ /* flash@0,0 is a mirror of part of the memory in flash@1,0
+ flash@0,0 {
+ compatible = "gef,ppc9a-firmware-mirror", "cfi-flash";
+ reg = <0x0 0x0 0x1000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "firmware";
+ reg = <0x0 0x1000000>;
+ read-only;
+ };
+ };
+ */
+
+ flash@1,0 {
+ compatible = "gef,ppc9a-paged-flash", "cfi-flash";
+ reg = <0x1 0x0 0x8000000>;
+ bank-width = <4>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "user";
+ reg = <0x0 0x7800000>;
+ };
+ partition@7800000 {
+ label = "firmware";
+ reg = <0x7800000 0x800000>;
+ read-only;
+ };
+ };
+
+ fpga@4,0 {
+ compatible = "gef,ppc9a-fpga-regs";
+ reg = <0x4 0x0 0x40>;
+ };
+
+ wdt@4,2000 {
+ compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
+ "gef,fpga-wdt";
+ reg = <0x4 0x2000 0x8>;
+ interrupts = <0x1a 0x4>;
+ interrupt-parent = <&gef_pic>;
+ };
+ /* Second watchdog available, driver currently supports one.
+ wdt@4,2010 {
+ compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00",
+ "gef,fpga-wdt";
+ reg = <0x4 0x2010 0x8>;
+ interrupts = <0x1b 0x4>;
+ interrupt-parent = <&gef_pic>;
+ };
+ */
+ gef_pic: pic@4,4000 {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "gef,ppc9a-fpga-pic", "gef,fpga-pic-1.00";
+ reg = <0x4 0x4000 0x20>;
+ interrupts = <0x8
+ 0x9>;
+ interrupt-parent = <&mpic>;
+
+ };
+ gef_gpio: gpio@7,14000 {
+ #gpio-cells = <2>;
+ compatible = "gef,ppc9a-gpio", "gef,sbc610-gpio";
+ reg = <0x7 0x14000 0x24>;
+ gpio-controller;
+ };
+ };
+
+ soc@fef00000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ compatible = "fsl,mpc8641-soc", "simple-bus";
+ ranges = <0x0 0xfef00000 0x00100000>;
+ reg = <0xfef00000 0x100000>; // CCSRBAR 1M
+ bus-frequency = <33333333>;
+
+ i2c1: i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <0x2b 0x2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+
+ hwmon@48 {
+ compatible = "national,lm92";
+ reg = <0x48>;
+ };
+
+ hwmon@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+
+ rtc@51 {
+ compatible = "epson,rx8581";
+ reg = <0x00000051>;
+ };
+
+ eti@6b {
+ compatible = "dallas,ds1682";
+ reg = <0x6b>;
+ };
+ };
+
+ i2c2: i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3100 0x100>;
+ interrupts = <0x2b 0x2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,mpc8641-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8641-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8641-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8641-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "gmii";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0x9 0x4>;
+ reg = <1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0x8 0x4>;
+ reg = <3>;
+ };
+ };
+ };
+
+ enet1: ethernet@26000 {
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x26000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>;
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy2>;
+ phy-connection-type = "gmii";
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <0x2a 0x2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <0x1c 0x2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ mpic: pic@40000 {
+ clock-frequency = <0>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ global-utilities@e0000 {
+ compatible = "fsl,mpc8641-guts";
+ reg = <0xe0000 0x1000>;
+ fsl,has-rstcr;
+ };
+ };
+
+ pci0: pcie@fef08000 {
+ compatible = "fsl,mpc8641-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xfef08000 0x1000>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
+ 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <0x18 0x2>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1
+ >;
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x02000000 0x0 0x80000000
+ 0x02000000 0x0 0x80000000
+ 0x0 0x40000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00400000>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/gef_sbc310.dts b/arch/powerpc/boot/dts/gef_sbc310.dts
new file mode 100644
index 000000000000..1569117e5ddc
--- /dev/null
+++ b/arch/powerpc/boot/dts/gef_sbc310.dts
@@ -0,0 +1,367 @@
+/*
+ * GE Fanuc SBC310 Device Tree Source
+ *
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Based on: SBS CM6 Device Tree Source
+ * Copyright 2007 SBS Technologies GmbH & Co. KG
+ * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source)
+ * Copyright 2006 Freescale Semiconductor Inc.
+ */
+
+/*
+ * Compiled with dtc -I dts -O dtb -o gef_sbc310.dtb gef_sbc310.dts
+ */
+
+/dts-v1/;
+
+/ {
+ model = "GEF_SBC310";
+ compatible = "gef,sbc310";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8641@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <32768>; // L1, 32K
+ i-cache-size = <32768>; // L1, 32K
+ timebase-frequency = <0>; // From uboot
+ bus-frequency = <0>; // From uboot
+ clock-frequency = <0>; // From uboot
+ };
+ PowerPC,8641@1 {
+ device_type = "cpu";
+ reg = <1>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <32768>; // L1, 32K
+ i-cache-size = <32768>; // L1, 32K
+ timebase-frequency = <0>; // From uboot
+ bus-frequency = <0>; // From uboot
+ clock-frequency = <0>; // From uboot
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x0 0x40000000>; // set by uboot
+ };
+
+ localbus@fef05000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8641-localbus", "simple-bus";
+ reg = <0xfef05000 0x1000>;
+ interrupts = <19 2>;
+ interrupt-parent = <&mpic>;
+
+ ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash
+ 1 0 0xe0000000 0x08000000 // Paged Flash 0
+ 2 0 0xe8000000 0x08000000 // Paged Flash 1
+ 3 0 0xfc100000 0x00020000 // NVRAM
+ 4 0 0xfc000000 0x00010000>; // FPGA
+
+ /* flash@0,0 is a mirror of part of the memory in flash@1,0
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x01000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "firmware";
+ reg = <0x00000000 0x01000000>;
+ read-only;
+ };
+ };
+ */
+
+ flash@1,0 {
+ compatible = "cfi-flash";
+ reg = <1 0 0x8000000>;
+ bank-width = <2>;
+ device-width = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "user";
+ reg = <0x00000000 0x07800000>;
+ };
+ partition@7800000 {
+ label = "firmware";
+ reg = <0x07800000 0x00800000>;
+ read-only;
+ };
+ };
+
+ fpga@4,0 {
+ compatible = "gef,fpga-regs";
+ reg = <0x4 0x0 0x40>;
+ };
+
+ wdt@4,2000 {
+ #interrupt-cells = <2>;
+ device_type = "watchdog";
+ compatible = "gef,fpga-wdt";
+ reg = <0x4 0x2000 0x8>;
+ interrupts = <0x1a 0x4>;
+ interrupt-parent = <&gef_pic>;
+ };
+/*
+ wdt@4,2010 {
+ #interrupt-cells = <2>;
+ device_type = "watchdog";
+ compatible = "gef,fpga-wdt";
+ reg = <0x4 0x2010 0x8>;
+ interrupts = <0x1b 0x4>;
+ interrupt-parent = <&gef_pic>;
+ };
+*/
+ gef_pic: pic@4,4000 {
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "gef,fpga-pic";
+ reg = <0x4 0x4000 0x20>;
+ interrupts = <0x8
+ 0x9>;
+ interrupt-parent = <&mpic>;
+
+ };
+ gef_gpio: gpio@4,8000 {
+ #gpio-cells = <2>;
+ compatible = "gef,sbc310-gpio";
+ reg = <0x4 0x8000 0x24>;
+ gpio-controller;
+ };
+ };
+
+ soc@fef00000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ device_type = "soc";
+ compatible = "simple-bus";
+ ranges = <0x0 0xfef00000 0x00100000>;
+ reg = <0xfef00000 0x100000>; // CCSRBAR 1M
+ bus-frequency = <33333333>;
+
+ i2c1: i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <0x2b 0x2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+
+ rtc@51 {
+ compatible = "epson,rx8581";
+ reg = <0x00000051>;
+ };
+ };
+
+ i2c2: i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3100 0x100>;
+ interrupts = <0x2b 0x2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+
+ hwmon@48 {
+ compatible = "national,lm92";
+ reg = <0x48>;
+ };
+
+ hwmon@4c {
+ compatible = "adi,adt7461";
+ reg = <0x4c>;
+ };
+
+ eti@6b {
+ compatible = "dallas,ds1682";
+ reg = <0x6b>;
+ };
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,mpc8641-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8641-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8641-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8641-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "gmii";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0x9 0x4>;
+ reg = <1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0x8 0x4>;
+ reg = <3>;
+ };
+ };
+ };
+
+ enet1: ethernet@26000 {
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x26000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <0x1f 0x2 0x20 0x2 0x21 0x2>;
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy2>;
+ phy-connection-type = "gmii";
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <0x2a 0x2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <0x1c 0x2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ mpic: pic@40000 {
+ clock-frequency = <0>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+
+ global-utilities@e0000 {
+ compatible = "fsl,mpc8641-guts";
+ reg = <0xe0000 0x1000>;
+ fsl,has-rstcr;
+ };
+ };
+
+ pci0: pcie@fef08000 {
+ compatible = "fsl,mpc8641-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xfef08000 0x1000>;
+ bus-range = <0x0 0xff>;
+ ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000
+ 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <0x18 0x2>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ 0x0000 0x0 0x0 0x1 &mpic 0x0 0x2
+ 0x0000 0x0 0x0 0x2 &mpic 0x1 0x2
+ 0x0000 0x0 0x0 0x3 &mpic 0x2 0x2
+ 0x0000 0x0 0x0 0x4 &mpic 0x3 0x2
+ >;
+
+ pcie@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x02000000 0x0 0x80000000
+ 0x02000000 0x0 0x80000000
+ 0x0 0x40000000
+
+ 0x01000000 0x0 0x00000000
+ 0x01000000 0x0 0x00000000
+ 0x0 0x00400000>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts
index e78c355c7bac..6582dbd36da7 100644
--- a/arch/powerpc/boot/dts/gef_sbc610.dts
+++ b/arch/powerpc/boot/dts/gef_sbc610.dts
@@ -71,7 +71,7 @@
#address-cells = <2>;
#size-cells = <1>;
compatible = "fsl,mpc8641-localbus", "simple-bus";
- reg = <0xf8005000 0x1000>;
+ reg = <0xfef05000 0x1000>;
interrupts = <19 2>;
interrupt-parent = <&mpic>;
@@ -202,34 +202,37 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&gef_pic>;
- interrupts = <0x9 0x4>;
- reg = <1>;
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&gef_pic>;
- interrupts = <0x8 0x4>;
- reg = <3>;
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
interrupt-parent = <&mpic>;
phy-handle = <&phy0>;
phy-connection-type = "gmii";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0x9 0x4>;
+ reg = <1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&gef_pic>;
+ interrupts = <0x8 0x4>;
+ reg = <3>;
+ };
+ };
};
enet1: ethernet@26000 {
diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts
index 2804444812e5..5e6b08ff6f67 100644
--- a/arch/powerpc/boot/dts/kilauea.dts
+++ b/arch/powerpc/boot/dts/kilauea.dts
@@ -97,6 +97,13 @@
0x6 0x4>; /* ECC SEC Error */
};
+ CRYPTO: crypto@ef700000 {
+ compatible = "amcc,ppc405ex-crypto", "amcc,ppc4xx-crypto";
+ reg = <0xef700000 0x80400>;
+ interrupt-parent = <&UIC0>;
+ interrupts = <0x17 0x2>;
+ };
+
MAL0: mcmal {
compatible = "ibm,mcmal-405ex", "ibm,mcmal2";
dcr-reg = <0x180 0x062>;
diff --git a/arch/powerpc/boot/dts/ksi8560.dts b/arch/powerpc/boot/dts/ksi8560.dts
index 3bfff47418db..308fe7c29dea 100644
--- a/arch/powerpc/boot/dts/ksi8560.dts
+++ b/arch/powerpc/boot/dts/ksi8560.dts
@@ -124,67 +124,72 @@
};
};
- mdio@24520 { /* For TSECs */
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- PHY1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- reg = <0x1>;
- device_type = "ethernet-phy";
- };
-
- PHY2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- reg = <0x2>;
- device_type = "ethernet-phy";
- };
-
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
/* Mac address filled in by bootwrapper */
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&PHY1>;
+
+ mdio@520 { /* For TSECs */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ PHY1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+
+ PHY2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ reg = <0x2>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
/* Mac address filled in by bootwrapper */
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <0x23 0x2 0x24 0x2 0x28 0x2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&PHY2>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
mpic: pic@40000 {
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts
index 3f7a5dce8de0..de30b3f9eb26 100644
--- a/arch/powerpc/boot/dts/lite5200.dts
+++ b/arch/powerpc/boot/dts/lite5200.dts
@@ -17,6 +17,7 @@
compatible = "fsl,lite5200";
#address-cells = <1>;
#size-cells = <1>;
+ interrupt-parent = <&mpc5200_pic>;
cpus {
#address-cells = <1>;
@@ -58,96 +59,74 @@
// 5200 interrupts are encoded into two levels;
interrupt-controller;
#interrupt-cells = <3>;
- device_type = "interrupt-controller";
compatible = "fsl,mpc5200-pic";
reg = <0x500 0x80>;
};
timer@600 { // General Purpose Timer
compatible = "fsl,mpc5200-gpt";
- cell-index = <0>;
reg = <0x600 0x10>;
interrupts = <1 9 0>;
- interrupt-parent = <&mpc5200_pic>;
fsl,has-wdt;
};
timer@610 { // General Purpose Timer
compatible = "fsl,mpc5200-gpt";
- cell-index = <1>;
reg = <0x610 0x10>;
interrupts = <1 10 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@620 { // General Purpose Timer
compatible = "fsl,mpc5200-gpt";
- cell-index = <2>;
reg = <0x620 0x10>;
interrupts = <1 11 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@630 { // General Purpose Timer
compatible = "fsl,mpc5200-gpt";
- cell-index = <3>;
reg = <0x630 0x10>;
interrupts = <1 12 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@640 { // General Purpose Timer
compatible = "fsl,mpc5200-gpt";
- cell-index = <4>;
reg = <0x640 0x10>;
interrupts = <1 13 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@650 { // General Purpose Timer
compatible = "fsl,mpc5200-gpt";
- cell-index = <5>;
reg = <0x650 0x10>;
interrupts = <1 14 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@660 { // General Purpose Timer
compatible = "fsl,mpc5200-gpt";
- cell-index = <6>;
reg = <0x660 0x10>;
interrupts = <1 15 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@670 { // General Purpose Timer
compatible = "fsl,mpc5200-gpt";
- cell-index = <7>;
reg = <0x670 0x10>;
interrupts = <1 16 0>;
- interrupt-parent = <&mpc5200_pic>;
};
rtc@800 { // Real time clock
compatible = "fsl,mpc5200-rtc";
reg = <0x800 0x100>;
interrupts = <1 5 0 1 6 0>;
- interrupt-parent = <&mpc5200_pic>;
};
can@900 {
compatible = "fsl,mpc5200-mscan";
- cell-index = <0>;
interrupts = <2 17 0>;
- interrupt-parent = <&mpc5200_pic>;
reg = <0x900 0x80>;
};
can@980 {
compatible = "fsl,mpc5200-mscan";
- cell-index = <1>;
interrupts = <2 18 0>;
- interrupt-parent = <&mpc5200_pic>;
reg = <0x980 0x80>;
};
@@ -155,39 +134,33 @@
compatible = "fsl,mpc5200-gpio";
reg = <0xb00 0x40>;
interrupts = <1 7 0>;
- interrupt-parent = <&mpc5200_pic>;
};
gpio@c00 {
compatible = "fsl,mpc5200-gpio-wkup";
reg = <0xc00 0x40>;
interrupts = <1 8 0 0 3 0>;
- interrupt-parent = <&mpc5200_pic>;
};
spi@f00 {
compatible = "fsl,mpc5200-spi";
reg = <0xf00 0x20>;
interrupts = <2 13 0 2 14 0>;
- interrupt-parent = <&mpc5200_pic>;
};
usb@1000 {
compatible = "fsl,mpc5200-ohci","ohci-be";
reg = <0x1000 0xff>;
interrupts = <2 6 0>;
- interrupt-parent = <&mpc5200_pic>;
};
dma-controller@1200 {
- device_type = "dma-controller";
compatible = "fsl,mpc5200-bestcomm";
reg = <0x1200 0x80>;
interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
3 4 0 3 5 0 3 6 0 3 7 0
3 8 0 3 9 0 3 10 0 3 11 0
3 12 0 3 13 0 3 14 0 3 15 0>;
- interrupt-parent = <&mpc5200_pic>;
};
xlb@1f00 {
@@ -196,13 +169,10 @@
};
serial@2000 { // PSC1
- device_type = "serial";
compatible = "fsl,mpc5200-psc-uart";
- port-number = <0>; // Logical port assignment
cell-index = <0>;
reg = <0x2000 0x100>;
interrupts = <2 1 0>;
- interrupt-parent = <&mpc5200_pic>;
};
// PSC2 in ac97 mode example
@@ -211,7 +181,6 @@
// cell-index = <1>;
// reg = <0x2200 0x100>;
// interrupts = <2 2 0>;
- // interrupt-parent = <&mpc5200_pic>;
//};
// PSC3 in CODEC mode example
@@ -220,27 +189,22 @@
// cell-index = <2>;
// reg = <0x2400 0x100>;
// interrupts = <2 3 0>;
- // interrupt-parent = <&mpc5200_pic>;
//};
// PSC4 in uart mode example
//serial@2600 { // PSC4
- // device_type = "serial";
// compatible = "fsl,mpc5200-psc-uart";
// cell-index = <3>;
// reg = <0x2600 0x100>;
// interrupts = <2 11 0>;
- // interrupt-parent = <&mpc5200_pic>;
//};
// PSC5 in uart mode example
//serial@2800 { // PSC5
- // device_type = "serial";
// compatible = "fsl,mpc5200-psc-uart";
// cell-index = <4>;
// reg = <0x2800 0x100>;
// interrupts = <2 12 0>;
- // interrupt-parent = <&mpc5200_pic>;
//};
// PSC6 in spi mode example
@@ -249,16 +213,13 @@
// cell-index = <5>;
// reg = <0x2c00 0x100>;
// interrupts = <2 4 0>;
- // interrupt-parent = <&mpc5200_pic>;
//};
ethernet@3000 {
- device_type = "network";
compatible = "fsl,mpc5200-fec";
reg = <0x3000 0x400>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <2 5 0>;
- interrupt-parent = <&mpc5200_pic>;
phy-handle = <&phy0>;
};
@@ -268,30 +229,24 @@
compatible = "fsl,mpc5200-mdio";
reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts
interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
- interrupt-parent = <&mpc5200_pic>;
phy0: ethernet-phy@1 {
- device_type = "ethernet-phy";
reg = <1>;
};
};
ata@3a00 {
- device_type = "ata";
compatible = "fsl,mpc5200-ata";
reg = <0x3a00 0x100>;
interrupts = <2 7 0>;
- interrupt-parent = <&mpc5200_pic>;
};
i2c@3d00 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5200-i2c","fsl-i2c";
- cell-index = <0>;
reg = <0x3d00 0x40>;
interrupts = <2 15 0>;
- interrupt-parent = <&mpc5200_pic>;
fsl5200-clocking;
};
@@ -299,14 +254,12 @@
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5200-i2c","fsl-i2c";
- cell-index = <1>;
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
- interrupt-parent = <&mpc5200_pic>;
fsl5200-clocking;
};
sram@8000 {
- compatible = "fsl,mpc5200-sram","sram";
+ compatible = "fsl,mpc5200-sram";
reg = <0x8000 0x4000>;
};
};
@@ -325,7 +278,6 @@
0xc000 0 0 4 &mpc5200_pic 0 0 3>;
clock-frequency = <0>; // From boot loader
interrupts = <2 8 0 2 9 0 2 10 0>;
- interrupt-parent = <&mpc5200_pic>;
bus-range = <0 0>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts
index 63e3bb48e843..c63e3566479e 100644
--- a/arch/powerpc/boot/dts/lite5200b.dts
+++ b/arch/powerpc/boot/dts/lite5200b.dts
@@ -17,6 +17,7 @@
compatible = "fsl,lite5200b";
#address-cells = <1>;
#size-cells = <1>;
+ interrupt-parent = <&mpc5200_pic>;
cpus {
#address-cells = <1>;
@@ -58,136 +59,112 @@
// 5200 interrupts are encoded into two levels;
interrupt-controller;
#interrupt-cells = <3>;
- device_type = "interrupt-controller";
compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
reg = <0x500 0x80>;
};
timer@600 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
- cell-index = <0>;
reg = <0x600 0x10>;
interrupts = <1 9 0>;
- interrupt-parent = <&mpc5200_pic>;
fsl,has-wdt;
};
timer@610 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
- cell-index = <1>;
reg = <0x610 0x10>;
interrupts = <1 10 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@620 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
- cell-index = <2>;
reg = <0x620 0x10>;
interrupts = <1 11 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@630 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
- cell-index = <3>;
reg = <0x630 0x10>;
interrupts = <1 12 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@640 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
- cell-index = <4>;
reg = <0x640 0x10>;
interrupts = <1 13 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@650 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
- cell-index = <5>;
reg = <0x650 0x10>;
interrupts = <1 14 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@660 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
- cell-index = <6>;
reg = <0x660 0x10>;
interrupts = <1 15 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@670 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
- cell-index = <7>;
reg = <0x670 0x10>;
interrupts = <1 16 0>;
- interrupt-parent = <&mpc5200_pic>;
};
rtc@800 { // Real time clock
compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
reg = <0x800 0x100>;
interrupts = <1 5 0 1 6 0>;
- interrupt-parent = <&mpc5200_pic>;
};
can@900 {
compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
- cell-index = <0>;
interrupts = <2 17 0>;
- interrupt-parent = <&mpc5200_pic>;
reg = <0x900 0x80>;
};
can@980 {
compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
- cell-index = <1>;
interrupts = <2 18 0>;
- interrupt-parent = <&mpc5200_pic>;
reg = <0x980 0x80>;
};
- gpio@b00 {
+ gpio_simple: gpio@b00 {
compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
reg = <0xb00 0x40>;
interrupts = <1 7 0>;
- interrupt-parent = <&mpc5200_pic>;
+ gpio-controller;
+ #gpio-cells = <2>;
};
- gpio@c00 {
+ gpio_wkup: gpio@c00 {
compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
reg = <0xc00 0x40>;
interrupts = <1 8 0 0 3 0>;
- interrupt-parent = <&mpc5200_pic>;
+ gpio-controller;
+ #gpio-cells = <2>;
};
spi@f00 {
compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
reg = <0xf00 0x20>;
interrupts = <2 13 0 2 14 0>;
- interrupt-parent = <&mpc5200_pic>;
};
usb@1000 {
compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
reg = <0x1000 0xff>;
interrupts = <2 6 0>;
- interrupt-parent = <&mpc5200_pic>;
};
dma-controller@1200 {
- device_type = "dma-controller";
compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
reg = <0x1200 0x80>;
interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
3 4 0 3 5 0 3 6 0 3 7 0
3 8 0 3 9 0 3 10 0 3 11 0
3 12 0 3 13 0 3 14 0 3 15 0>;
- interrupt-parent = <&mpc5200_pic>;
};
xlb@1f00 {
@@ -196,13 +173,10 @@
};
serial@2000 { // PSC1
- device_type = "serial";
compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
- port-number = <0>; // Logical port assignment
cell-index = <0>;
reg = <0x2000 0x100>;
interrupts = <2 1 0>;
- interrupt-parent = <&mpc5200_pic>;
};
// PSC2 in ac97 mode example
@@ -211,7 +185,6 @@
// cell-index = <1>;
// reg = <0x2200 0x100>;
// interrupts = <2 2 0>;
- // interrupt-parent = <&mpc5200_pic>;
//};
// PSC3 in CODEC mode example
@@ -220,27 +193,22 @@
// cell-index = <2>;
// reg = <0x2400 0x100>;
// interrupts = <2 3 0>;
- // interrupt-parent = <&mpc5200_pic>;
//};
// PSC4 in uart mode example
//serial@2600 { // PSC4
- // device_type = "serial";
// compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
// cell-index = <3>;
// reg = <0x2600 0x100>;
// interrupts = <2 11 0>;
- // interrupt-parent = <&mpc5200_pic>;
//};
// PSC5 in uart mode example
//serial@2800 { // PSC5
- // device_type = "serial";
// compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
// cell-index = <4>;
// reg = <0x2800 0x100>;
// interrupts = <2 12 0>;
- // interrupt-parent = <&mpc5200_pic>;
//};
// PSC6 in spi mode example
@@ -249,49 +217,40 @@
// cell-index = <5>;
// reg = <0x2c00 0x100>;
// interrupts = <2 4 0>;
- // interrupt-parent = <&mpc5200_pic>;
//};
ethernet@3000 {
- device_type = "network";
compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
reg = <0x3000 0x400>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <2 5 0>;
- interrupt-parent = <&mpc5200_pic>;
phy-handle = <&phy0>;
};
mdio@3000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,mpc5200b-mdio", "fsl,mpc5200-mdio";
+ compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts
interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
- interrupt-parent = <&mpc5200_pic>;
phy0: ethernet-phy@0 {
- device_type = "ethernet-phy";
reg = <0>;
};
};
ata@3a00 {
- device_type = "ata";
compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
reg = <0x3a00 0x100>;
interrupts = <2 7 0>;
- interrupt-parent = <&mpc5200_pic>;
};
i2c@3d00 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
- cell-index = <0>;
reg = <0x3d00 0x40>;
interrupts = <2 15 0>;
- interrupt-parent = <&mpc5200_pic>;
fsl5200-clocking;
};
@@ -299,14 +258,13 @@
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
- cell-index = <1>;
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
- interrupt-parent = <&mpc5200_pic>;
fsl5200-clocking;
};
+
sram@8000 {
- compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram","sram";
+ compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
reg = <0x8000 0x4000>;
};
};
@@ -330,7 +288,6 @@
0xc800 0 0 4 &mpc5200_pic 0 0 3>;
clock-frequency = <0>; // From boot loader
interrupts = <2 8 0 2 9 0 2 10 0>;
- interrupt-parent = <&mpc5200_pic>;
bus-range = <0 0>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
diff --git a/arch/powerpc/boot/dts/media5200.dts b/arch/powerpc/boot/dts/media5200.dts
new file mode 100644
index 000000000000..e297d8b41875
--- /dev/null
+++ b/arch/powerpc/boot/dts/media5200.dts
@@ -0,0 +1,318 @@
+/*
+ * Freescale Media5200 board Device Tree Source
+ *
+ * Copyright 2009 Secret Lab Technologies Ltd.
+ * Grant Likely <grant.likely@secretlab.ca>
+ * Steven Cavanagh <scavanagh@secretlab.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+ model = "fsl,media5200";
+ compatible = "fsl,media5200";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&mpc5200_pic>;
+
+ aliases {
+ console = &console;
+ ethernet0 = &eth0;
+ };
+
+ chosen {
+ linux,stdout-path = &console;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,5200@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <33000000>; // 33 MHz, these were configured by U-Boot
+ bus-frequency = <132000000>; // 132 MHz
+ clock-frequency = <396000000>; // 396 MHz
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x08000000>; // 128MB RAM
+ };
+
+ soc@f0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc5200b-immr";
+ ranges = <0 0xf0000000 0x0000c000>;
+ reg = <0xf0000000 0x00000100>;
+ bus-frequency = <132000000>;// 132 MHz
+ system-frequency = <0>; // from bootloader
+
+ cdm@200 {
+ compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm";
+ reg = <0x200 0x38>;
+ };
+
+ mpc5200_pic: interrupt-controller@500 {
+ // 5200 interrupts are encoded into two levels;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
+ reg = <0x500 0x80>;
+ };
+
+ timer@600 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x600 0x10>;
+ interrupts = <1 9 0>;
+ fsl,has-wdt;
+ };
+
+ timer@610 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x610 0x10>;
+ interrupts = <1 10 0>;
+ };
+
+ timer@620 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x620 0x10>;
+ interrupts = <1 11 0>;
+ };
+
+ timer@630 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x630 0x10>;
+ interrupts = <1 12 0>;
+ };
+
+ timer@640 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x640 0x10>;
+ interrupts = <1 13 0>;
+ };
+
+ timer@650 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x650 0x10>;
+ interrupts = <1 14 0>;
+ };
+
+ timer@660 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x660 0x10>;
+ interrupts = <1 15 0>;
+ };
+
+ timer@670 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x670 0x10>;
+ interrupts = <1 16 0>;
+ };
+
+ rtc@800 { // Real time clock
+ compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
+ reg = <0x800 0x100>;
+ interrupts = <1 5 0 1 6 0>;
+ };
+
+ can@900 {
+ compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
+ interrupts = <2 17 0>;
+ reg = <0x900 0x80>;
+ };
+
+ can@980 {
+ compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
+ interrupts = <2 18 0>;
+ reg = <0x980 0x80>;
+ };
+
+ gpio_simple: gpio@b00 {
+ compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
+ reg = <0xb00 0x40>;
+ interrupts = <1 7 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio_wkup: gpio@c00 {
+ compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
+ reg = <0xc00 0x40>;
+ interrupts = <1 8 0 0 3 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ spi@f00 {
+ compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
+ reg = <0xf00 0x20>;
+ interrupts = <2 13 0 2 14 0>;
+ };
+
+ usb@1000 {
+ compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
+ reg = <0x1000 0x100>;
+ interrupts = <2 6 0>;
+ };
+
+ dma-controller@1200 {
+ compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
+ reg = <0x1200 0x80>;
+ interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
+ 3 4 0 3 5 0 3 6 0 3 7 0
+ 3 8 0 3 9 0 3 10 0 3 11 0
+ 3 12 0 3 13 0 3 14 0 3 15 0>;
+ };
+
+ xlb@1f00 {
+ compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb";
+ reg = <0x1f00 0x100>;
+ };
+
+ // PSC6 in uart mode
+ console: serial@2c00 { // PSC6
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+ cell-index = <5>;
+ port-number = <0>; // Logical port assignment
+ reg = <0x2c00 0x100>;
+ interrupts = <2 4 0>;
+ };
+
+ eth0: ethernet@3000 {
+ compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
+ reg = <0x3000 0x400>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <2 5 0>;
+ phy-handle = <&phy0>;
+ };
+
+ mdio@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
+ reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts
+ interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ ata@3a00 {
+ compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
+ reg = <0x3a00 0x100>;
+ interrupts = <2 7 0>;
+ };
+
+ i2c@3d00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+ reg = <0x3d00 0x40>;
+ interrupts = <2 15 0>;
+ fsl5200-clocking;
+ };
+
+ i2c@3d40 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+ reg = <0x3d40 0x40>;
+ interrupts = <2 16 0>;
+ fsl5200-clocking;
+ };
+
+ sram@8000 {
+ compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
+ reg = <0x8000 0x4000>;
+ };
+ };
+
+ pci@f0000d00 {
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci";
+ reg = <0xf0000d00 0x100>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0xc000 0 0 1 &media5200_fpga 0 2 // 1st slot
+ 0xc000 0 0 2 &media5200_fpga 0 3
+ 0xc000 0 0 3 &media5200_fpga 0 4
+ 0xc000 0 0 4 &media5200_fpga 0 5
+
+ 0xc800 0 0 1 &media5200_fpga 0 3 // 2nd slot
+ 0xc800 0 0 2 &media5200_fpga 0 4
+ 0xc800 0 0 3 &media5200_fpga 0 5
+ 0xc800 0 0 4 &media5200_fpga 0 2
+
+ 0xd000 0 0 1 &media5200_fpga 0 4 // miniPCI
+ 0xd000 0 0 2 &media5200_fpga 0 5
+
+ 0xe000 0 0 1 &media5200_fpga 0 5 // CoralIP
+ >;
+ clock-frequency = <0>; // From boot loader
+ interrupts = <2 8 0 2 9 0 2 10 0>;
+ interrupt-parent = <&mpc5200_pic>;
+ bus-range = <0 0>;
+ ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
+ 0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
+ };
+
+ localbus {
+ compatible = "fsl,mpc5200b-lpb","simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ ranges = < 0 0 0xfc000000 0x02000000
+ 1 0 0xfe000000 0x02000000
+ 2 0 0xf0010000 0x00010000
+ 3 0 0xf0020000 0x00010000 >;
+
+ flash@0,0 {
+ compatible = "amd,am29lv28ml", "cfi-flash";
+ reg = <0 0x0 0x2000000>; // 32 MB
+ bank-width = <4>; // Width in bytes of the flash bank
+ device-width = <2>; // Two devices on each bank
+ };
+
+ flash@1,0 {
+ compatible = "amd,am29lv28ml", "cfi-flash";
+ reg = <1 0 0x2000000>; // 32 MB
+ bank-width = <4>; // Width in bytes of the flash bank
+ device-width = <2>; // Two devices on each bank
+ };
+
+ media5200_fpga: fpga@2,0 {
+ compatible = "fsl,media5200-fpga";
+ interrupt-controller;
+ #interrupt-cells = <2>; // 0:bank 1:id; no type field
+ reg = <2 0 0x10000>;
+
+ interrupt-parent = <&mpc5200_pic>;
+ interrupts = <0 0 3 // IRQ bank 0
+ 1 1 3>; // IRQ bank 1
+ };
+
+ uart@3,0 {
+ compatible = "ti,tl16c752bpt";
+ reg = <3 0 0x10000>;
+ interrupt-parent = <&media5200_fpga>;
+ interrupts = <0 0 0 1>; // 2 irqs
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/motionpro.dts b/arch/powerpc/boot/dts/motionpro.dts
index 52ba6f98b273..7be8ca038676 100644
--- a/arch/powerpc/boot/dts/motionpro.dts
+++ b/arch/powerpc/boot/dts/motionpro.dts
@@ -17,6 +17,7 @@
compatible = "promess,motionpro";
#address-cells = <1>;
#size-cells = <1>;
+ interrupt-parent = <&mpc5200_pic>;
cpus {
#address-cells = <1>;
@@ -66,7 +67,6 @@
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x600 0x10>;
interrupts = <1 9 0>;
- interrupt-parent = <&mpc5200_pic>;
fsl,has-wdt;
};
@@ -74,35 +74,30 @@
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x610 0x10>;
interrupts = <1 10 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@620 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x620 0x10>;
interrupts = <1 11 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@630 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x630 0x10>;
interrupts = <1 12 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@640 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x640 0x10>;
interrupts = <1 13 0>;
- interrupt-parent = <&mpc5200_pic>;
};
timer@650 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
reg = <0x650 0x10>;
interrupts = <1 14 0>;
- interrupt-parent = <&mpc5200_pic>;
};
motionpro-led@660 { // Motion-PRO status LED
@@ -110,7 +105,6 @@
label = "motionpro-statusled";
reg = <0x660 0x10>;
interrupts = <1 15 0>;
- interrupt-parent = <&mpc5200_pic>;
blink-delay = <100>; // 100 msec
};
@@ -119,49 +113,46 @@
label = "motionpro-readyled";
reg = <0x670 0x10>;
interrupts = <1 16 0>;
- interrupt-parent = <&mpc5200_pic>;
};
rtc@800 { // Real time clock
compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
reg = <0x800 0x100>;
interrupts = <1 5 0 1 6 0>;
- interrupt-parent = <&mpc5200_pic>;
};
can@980 {
compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
interrupts = <2 18 0>;
- interrupt-parent = <&mpc5200_pic>;
reg = <0x980 0x80>;
};
- gpio@b00 {
+ gpio_simple: gpio@b00 {
compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
reg = <0xb00 0x40>;
interrupts = <1 7 0>;
- interrupt-parent = <&mpc5200_pic>;
+ gpio-controller;
+ #gpio-cells = <2>;
};
- gpio@c00 {
+ gpio_wkup: gpio@c00 {
compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
reg = <0xc00 0x40>;
interrupts = <1 8 0 0 3 0>;
- interrupt-parent = <&mpc5200_pic>;
+ gpio-controller;
+ #gpio-cells = <2>;
};
spi@f00 {
compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
reg = <0xf00 0x20>;
interrupts = <2 13 0 2 14 0>;
- interrupt-parent = <&mpc5200_pic>;
};
usb@1000 {
compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
reg = <0x1000 0xff>;
interrupts = <2 6 0>;
- interrupt-parent = <&mpc5200_pic>;
};
dma-controller@1200 {
@@ -171,7 +162,6 @@
3 4 0 3 5 0 3 6 0 3 7 0
3 8 0 3 9 0 3 10 0 3 11 0
3 12 0 3 13 0 3 14 0 3 15 0>;
- interrupt-parent = <&mpc5200_pic>;
};
xlb@1f00 {
@@ -180,12 +170,9 @@
};
serial@2000 { // PSC1
- device_type = "serial";
compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
- port-number = <0>; // Logical port assignment
reg = <0x2000 0x100>;
interrupts = <2 1 0>;
- interrupt-parent = <&mpc5200_pic>;
};
// PSC2 in spi master mode
@@ -194,26 +181,20 @@
cell-index = <1>;
reg = <0x2200 0x100>;
interrupts = <2 2 0>;
- interrupt-parent = <&mpc5200_pic>;
};
// PSC5 in uart mode
serial@2800 { // PSC5
- device_type = "serial";
compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
- port-number = <4>; // Logical port assignment
reg = <0x2800 0x100>;
interrupts = <2 12 0>;
- interrupt-parent = <&mpc5200_pic>;
};
ethernet@3000 {
- device_type = "network";
compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
reg = <0x3000 0x400>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <2 5 0>;
- interrupt-parent = <&mpc5200_pic>;
phy-handle = <&phy0>;
};
@@ -223,10 +204,8 @@
compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts
interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
- interrupt-parent = <&mpc5200_pic>;
phy0: ethernet-phy@2 {
- device_type = "ethernet-phy";
reg = <2>;
};
};
@@ -235,7 +214,6 @@
compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
reg = <0x3a00 0x100>;
interrupts = <2 7 0>;
- interrupt-parent = <&mpc5200_pic>;
};
i2c@3d40 {
@@ -244,7 +222,6 @@
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
- interrupt-parent = <&mpc5200_pic>;
fsl5200-clocking;
rtc@68 {
@@ -259,8 +236,8 @@
};
};
- lpb {
- compatible = "fsl,lpb";
+ localbus {
+ compatible = "fsl,mpc5200b-lpb","simple-bus";
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0 0xff000000 0x01000000
@@ -273,7 +250,6 @@
compatible = "promess,motionpro-kollmorgen";
reg = <1 0 0x10000>;
interrupts = <1 1 0>;
- interrupt-parent = <&mpc5200_pic>;
};
// 8-bit board CPLD on LocalPlus Bus CS2
diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts
index 3ebf7ec0484c..761faa7b6964 100644
--- a/arch/powerpc/boot/dts/mpc8313erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8313erdb.dts
@@ -180,7 +180,7 @@
#address-cells = <1>;
#size-cells = <1>;
sleep = <&pmc 0x20000000>;
- ranges;
+ ranges = <0x0 0x24000 0x1000>;
cell-index = <0>;
device_type = "network";
@@ -195,11 +195,11 @@
fixed-link = <1 1 1000 0 0>;
fsl,magic-packet;
- mdio@24520 {
+ mdio@520 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
+ reg = <0x520 0x20>;
phy4: ethernet-phy@4 {
interrupt-parent = <&ipic>;
interrupts = <20 0x8>;
@@ -221,6 +221,7 @@
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <34 0x8 33 0x8 32 0x8>;
interrupt-parent = <&ipic>;
@@ -229,11 +230,11 @@
sleep = <&pmc 0x10000000>;
fsl,magic-packet;
- mdio@25520 {
+ mdio@520 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
+ reg = <0x520 0x20>;
tbi1: tbi-phy@11 {
reg = <0x11>;
diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts
index 71784165b77e..3f4c5fb988a0 100644
--- a/arch/powerpc/boot/dts/mpc8315erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8315erdb.dts
@@ -22,6 +22,8 @@
serial0 = &serial0;
serial1 = &serial1;
pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
};
cpus {
@@ -188,66 +190,74 @@
phy_type = "utmi";
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
- phy0: ethernet-phy@0 {
- interrupt-parent = <&ipic>;
- interrupts = <20 0x8>;
- reg = <0x0>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&ipic>;
- interrupts = <19 0x8>;
- reg = <0x1>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <32 0x8 33 0x8 34 0x8>;
interrupt-parent = <&ipic>;
tbi-handle = <&tbi0>;
phy-handle = < &phy0 >;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&ipic>;
+ interrupts = <20 0x8>;
+ reg = <0x0>;
+ device_type = "ethernet-phy";
+ };
+
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&ipic>;
+ interrupts = <19 0x8>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 0x8 36 0x8 37 0x8>;
interrupt-parent = <&ipic>;
tbi-handle = <&tbi1>;
phy-handle = < &phy1 >;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
@@ -349,4 +359,66 @@
compatible = "fsl,mpc8349-pci";
device_type = "pci";
};
+
+ pci1: pcie@e0009000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "fsl,mpc8315-pcie", "fsl,mpc8314-pcie";
+ reg = <0xe0009000 0x00001000>;
+ ranges = <0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xb1000000 0 0x00800000>;
+ bus-range = <0 255>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0 0 0 1 &ipic 1 8
+ 0 0 0 2 &ipic 1 8
+ 0 0 0 3 &ipic 1 8
+ 0 0 0 4 &ipic 1 8>;
+ clock-frequency = <0>;
+
+ pcie@0 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0 0 0 0 0>;
+ ranges = <0x02000000 0 0xa0000000
+ 0x02000000 0 0xa0000000
+ 0 0x10000000
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00800000>;
+ };
+ };
+
+ pci2: pcie@e000a000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "fsl,mpc8315-pcie", "fsl,mpc8314-pcie";
+ reg = <0xe000a000 0x00001000>;
+ ranges = <0x02000000 0 0xc0000000 0xc0000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xd1000000 0 0x00800000>;
+ bus-range = <0 255>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0 0 0 1 &ipic 2 8
+ 0 0 0 2 &ipic 2 8
+ 0 0 0 3 &ipic 2 8
+ 0 0 0 4 &ipic 2 8>;
+ clock-frequency = <0>;
+
+ pcie@0 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0 0 0 0 0>;
+ ranges = <0x02000000 0 0xc0000000
+ 0x02000000 0 0xc0000000
+ 0 0x10000000
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00800000>;
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index dea30910c136..4319bd70a580 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -152,10 +152,21 @@
};
par_io@1400 {
+ #address-cells = <1>;
+ #size-cells = <1>;
reg = <0x1400 0x100>;
+ ranges = <3 0x1448 0x18>;
+ compatible = "fsl,mpc8323-qe-pario";
device_type = "par_io";
num-ports = <7>;
+ qe_pio_d: gpio-controller@1448 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8323-qe-pario-bank";
+ reg = <3 0x18>;
+ gpio-controller;
+ };
+
ucc2pio:ucc_pin@02 {
pio-map = <
/* port pin dir open_drain assignment has_irq */
@@ -225,12 +236,25 @@
};
spi@4c0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
cell-index = <0>;
compatible = "fsl,spi";
reg = <0x4c0 0x40>;
interrupts = <2>;
interrupt-parent = <&qeic>;
+ gpios = <&qe_pio_d 13 0>;
mode = "cpu-qe";
+
+ mmc-slot@0 {
+ compatible = "fsl,mpc8323rdb-mmc-slot",
+ "mmc-spi-slot";
+ reg = <0>;
+ gpios = <&qe_pio_d 14 1
+ &qe_pio_d 15 0>;
+ voltage-ranges = <3300 3300>;
+ spi-max-frequency = <50000000>;
+ };
};
spi@500 {
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts
index b5eda94a8e2a..1ae38f0ddef8 100644
--- a/arch/powerpc/boot/dts/mpc8349emitx.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitx.dts
@@ -170,57 +170,52 @@
phy_type = "ulpi";
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- /* Vitesse 8201 */
- phy1c: ethernet-phy@1c {
- interrupt-parent = <&ipic>;
- interrupts = <18 0x8>;
- reg = <0x1c>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <32 0x8 33 0x8 34 0x8>;
interrupt-parent = <&ipic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy1c>;
linux,network-index = <0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ /* Vitesse 8201 */
+ phy1c: ethernet-phy@1c {
+ interrupt-parent = <&ipic>;
+ interrupts = <18 0x8>;
+ reg = <0x1c>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 0x8 36 0x8 37 0x8>;
interrupt-parent = <&ipic>;
@@ -228,6 +223,18 @@
fixed-link = <1 1 1000 0 0>;
linux,network-index = <1>;
tbi-handle = <&tbi1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
index c87a6015e165..662abe1fb804 100644
--- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
@@ -149,37 +149,41 @@
phy_type = "ulpi";
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- /* Vitesse 8201 */
- phy1c: ethernet-phy@1c {
- interrupt-parent = <&ipic>;
- interrupts = <18 0x8>;
- reg = <0x1c>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <32 0x8 33 0x8 34 0x8>;
interrupt-parent = <&ipic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy1c>;
linux,network-index = <0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ /* Vitesse 8201 */
+ phy1c: ethernet-phy@1c {
+ interrupt-parent = <&ipic>;
+ interrupts = <18 0x8>;
+ reg = <0x1c>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts
index d9adba01c09c..d9f0a2325fa4 100644
--- a/arch/powerpc/boot/dts/mpc834x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc834x_mds.dts
@@ -167,69 +167,76 @@
phy_type = "ulpi";
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&ipic>;
- interrupts = <17 0x8>;
- reg = <0x0>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&ipic>;
- interrupts = <18 0x8>;
- reg = <0x1>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <32 0x8 33 0x8 34 0x8>;
interrupt-parent = <&ipic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
linux,network-index = <0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&ipic>;
+ interrupts = <17 0x8>;
+ reg = <0x0>;
+ device_type = "ethernet-phy";
+ };
+
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&ipic>;
+ interrupts = <18 0x8>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 0x8 36 0x8 37 0x8>;
interrupt-parent = <&ipic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
linux,network-index = <1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/mpc8377_mds.dts b/arch/powerpc/boot/dts/mpc8377_mds.dts
index 1d14d7052e6d..963708017e6c 100644
--- a/arch/powerpc/boot/dts/mpc8377_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8377_mds.dts
@@ -23,6 +23,8 @@
serial0 = &serial0;
serial1 = &serial1;
pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
};
cpus {
@@ -127,21 +129,38 @@
reg = <0x200 0x100>;
};
- i2c@3000 {
+ sleep-nexus {
#address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <14 0x8>;
- interrupt-parent = <&ipic>;
- dfsrr;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ sleep = <&pmc 0x0c000000>;
+ ranges;
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <14 0x8>;
+ interrupt-parent = <&ipic>;
+ dfsrr;
+
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ interrupts = <19 0x8>;
+ interrupt-parent = <&ipic>;
+ };
+ };
- rtc@68 {
- compatible = "dallas,ds1374";
- reg = <0x68>;
- interrupts = <19 0x8>;
+ sdhci@2e000 {
+ compatible = "fsl,mpc8377-esdhc", "fsl,mpc8379-esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <42 0x8>;
interrupt-parent = <&ipic>;
+ /* Filled in by U-Boot */
+ clock-frequency = <0>;
};
};
@@ -174,70 +193,83 @@
interrupts = <38 0x8>;
dr_mode = "host";
phy_type = "ulpi";
+ sleep = <&pmc 0x00c00000>;
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
- phy2: ethernet-phy@2 {
- interrupt-parent = <&ipic>;
- interrupts = <17 0x8>;
- reg = <0x2>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&ipic>;
- interrupts = <18 0x8>;
- reg = <0x3>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <32 0x8 33 0x8 34 0x8>;
phy-connection-type = "mii";
interrupt-parent = <&ipic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy2>;
+ sleep = <&pmc 0xc0000000>;
+ fsl,magic-packet;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&ipic>;
+ interrupts = <17 0x8>;
+ reg = <0x2>;
+ device_type = "ethernet-phy";
+ };
+
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&ipic>;
+ interrupts = <18 0x8>;
+ reg = <0x3>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 0x8 36 0x8 37 0x8>;
phy-connection-type = "mii";
interrupt-parent = <&ipic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy3>;
+ sleep = <&pmc 0x30000000>;
+ fsl,magic-packet;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
@@ -309,14 +341,7 @@
fsl,channel-fifo-len = <24>;
fsl,exec-units-mask = <0x9fe>;
fsl,descriptor-types-mask = <0x3ab0ebf>;
- };
-
- sdhc@2e000 {
- model = "eSDHC";
- compatible = "fsl,esdhc";
- reg = <0x2e000 0x1000>;
- interrupts = <42 0x8>;
- interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x03000000>;
};
sata@18000 {
@@ -324,6 +349,7 @@
reg = <0x18000 0x1000>;
interrupts = <44 0x8>;
interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x000000c0>;
};
sata@19000 {
@@ -331,6 +357,7 @@
reg = <0x19000 0x1000>;
interrupts = <45 0x8>;
interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x00000030>;
};
/* IPIC
@@ -346,6 +373,13 @@
#interrupt-cells = <2>;
reg = <0x700 0x100>;
};
+
+ pmc: power@b00 {
+ compatible = "fsl,mpc8377-pmc", "fsl,mpc8349-pmc";
+ reg = <0xb00 0x100 0xa00 0x100>;
+ interrupts = <80 0x8>;
+ interrupt-parent = <&ipic>;
+ };
};
pci0: pci@e0008500 {
@@ -400,6 +434,7 @@
ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>;
+ sleep = <&pmc 0x00010000>;
clock-frequency = <0>;
#interrupt-cells = <1>;
#size-cells = <2>;
@@ -409,4 +444,68 @@
compatible = "fsl,mpc8349-pci";
device_type = "pci";
};
+
+ pci1: pcie@e0009000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie";
+ reg = <0xe0009000 0x00001000>;
+ ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xb8000000 0 0x00800000>;
+ bus-range = <0 255>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0 0 0 1 &ipic 1 8
+ 0 0 0 2 &ipic 1 8
+ 0 0 0 3 &ipic 1 8
+ 0 0 0 4 &ipic 1 8>;
+ sleep = <&pmc 0x00300000>;
+ clock-frequency = <0>;
+
+ pcie@0 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0 0 0 0 0>;
+ ranges = <0x02000000 0 0xa8000000
+ 0x02000000 0 0xa8000000
+ 0 0x10000000
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00800000>;
+ };
+ };
+
+ pci2: pcie@e000a000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie";
+ reg = <0xe000a000 0x00001000>;
+ ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xd8000000 0 0x00800000>;
+ bus-range = <0 255>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0 0 0 1 &ipic 2 8
+ 0 0 0 2 &ipic 2 8
+ 0 0 0 3 &ipic 2 8
+ 0 0 0 4 &ipic 2 8>;
+ sleep = <&pmc 0x000c0000>;
+ clock-frequency = <0>;
+
+ pcie@0 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0 0 0 0 0>;
+ ranges = <0x02000000 0 0xc8000000
+ 0x02000000 0 0xc8000000
+ 0 0x10000000
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00800000>;
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts
index 9413af3b9925..053339390c22 100644
--- a/arch/powerpc/boot/dts/mpc8377_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts
@@ -22,6 +22,8 @@
serial0 = &serial0;
serial1 = &serial1;
pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
};
cpus {
@@ -107,26 +109,72 @@
reg = <0x200 0x100>;
};
- i2c@3000 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <14 0x8>;
+ gpio1: gpio-controller@c00 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8377-gpio", "fsl,mpc8349-gpio";
+ reg = <0xc00 0x100>;
+ interrupts = <74 0x8>;
interrupt-parent = <&ipic>;
- dfsrr;
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
+ gpio-controller;
+ };
+
+ gpio2: gpio-controller@d00 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8377-gpio", "fsl,mpc8349-gpio";
+ reg = <0xd00 0x100>;
+ interrupts = <75 0x8>;
+ interrupt-parent = <&ipic>;
+ gpio-controller;
+ };
+
+ sleep-nexus {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ sleep = <&pmc 0x0c000000>;
+ ranges;
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <14 0x8>;
+ interrupt-parent = <&ipic>;
+ dfsrr;
+
+ dtt@48 {
+ compatible = "national,lm75";
+ reg = <0x48>;
+ };
+
+ at24@50 {
+ compatible = "at24,24c256";
+ reg = <0x50>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+
+ mcu_pio: mcu@a {
+ #gpio-cells = <2>;
+ compatible = "fsl,mc9s08qg8-mpc8377erdb",
+ "fsl,mcu-mpc8349emitx";
+ reg = <0x0a>;
+ gpio-controller;
+ };
};
- mcu_pio: mcu@a {
- #gpio-cells = <2>;
- compatible = "fsl,mc9s08qg8-mpc8377erdb",
- "fsl,mcu-mpc8349emitx";
- reg = <0x0a>;
- gpio-controller;
+ sdhci@2e000 {
+ compatible = "fsl,mpc8377-esdhc", "fsl,mpc8379-esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <42 0x8>;
+ interrupt-parent = <&ipic>;
+ /* Filled in by U-Boot */
+ clock-frequency = <0>;
};
};
@@ -197,64 +245,76 @@
interrupt-parent = <&ipic>;
interrupts = <38 0x8>;
phy_type = "ulpi";
+ sleep = <&pmc 0x00c00000>;
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
- phy2: ethernet-phy@2 {
- interrupt-parent = <&ipic>;
- interrupts = <17 0x8>;
- reg = <0x2>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <32 0x8 33 0x8 34 0x8>;
phy-connection-type = "mii";
interrupt-parent = <&ipic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy2>;
+ sleep = <&pmc 0xc0000000>;
+ fsl,magic-packet;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&ipic>;
+ interrupts = <17 0x8>;
+ reg = <0x2>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 0x8 36 0x8 37 0x8>;
phy-connection-type = "mii";
interrupt-parent = <&ipic>;
fixed-link = <1 1 1000 0 0>;
tbi-handle = <&tbi1>;
+ sleep = <&pmc 0x30000000>;
+ fsl,magic-packet;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
@@ -287,6 +347,7 @@
fsl,channel-fifo-len = <24>;
fsl,exec-units-mask = <0x9fe>;
fsl,descriptor-types-mask = <0x3ab0ebf>;
+ sleep = <&pmc 0x03000000>;
};
sata@18000 {
@@ -294,6 +355,7 @@
reg = <0x18000 0x1000>;
interrupts = <44 0x8>;
interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x000000c0>;
};
sata@19000 {
@@ -301,6 +363,7 @@
reg = <0x19000 0x1000>;
interrupts = <45 0x8>;
interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x00000030>;
};
/* IPIC
@@ -316,6 +379,13 @@
#interrupt-cells = <2>;
reg = <0x700 0x100>;
};
+
+ pmc: power@b00 {
+ compatible = "fsl,mpc8377-pmc", "fsl,mpc8349-pmc";
+ reg = <0xb00 0x100 0xa00 0x100>;
+ interrupts = <80 0x8>;
+ interrupt-parent = <&ipic>;
+ };
};
pci0: pci@e0008500 {
@@ -341,6 +411,7 @@
ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
+ sleep = <&pmc 0x00010000>;
clock-frequency = <66666666>;
#interrupt-cells = <1>;
#size-cells = <2>;
@@ -350,4 +421,68 @@
compatible = "fsl,mpc8349-pci";
device_type = "pci";
};
+
+ pci1: pcie@e0009000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie";
+ reg = <0xe0009000 0x00001000>;
+ ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xb8000000 0 0x00800000>;
+ bus-range = <0 255>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0 0 0 1 &ipic 1 8
+ 0 0 0 2 &ipic 1 8
+ 0 0 0 3 &ipic 1 8
+ 0 0 0 4 &ipic 1 8>;
+ sleep = <&pmc 0x00300000>;
+ clock-frequency = <0>;
+
+ pcie@0 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0 0 0 0 0>;
+ ranges = <0x02000000 0 0xa8000000
+ 0x02000000 0 0xa8000000
+ 0 0x10000000
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00800000>;
+ };
+ };
+
+ pci2: pcie@e000a000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie";
+ reg = <0xe000a000 0x00001000>;
+ ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xd8000000 0 0x00800000>;
+ bus-range = <0 255>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0 0 0 1 &ipic 2 8
+ 0 0 0 2 &ipic 2 8
+ 0 0 0 3 &ipic 2 8
+ 0 0 0 4 &ipic 2 8>;
+ sleep = <&pmc 0x000c0000>;
+ clock-frequency = <0>;
+
+ pcie@0 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0 0 0 0 0>;
+ ranges = <0x02000000 0 0xc8000000
+ 0x02000000 0 0xc8000000
+ 0 0x10000000
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00800000>;
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/mpc8378_mds.dts b/arch/powerpc/boot/dts/mpc8378_mds.dts
index b85fc02682d2..651ff2f9db2d 100644
--- a/arch/powerpc/boot/dts/mpc8378_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8378_mds.dts
@@ -23,6 +23,8 @@
serial0 = &serial0;
serial1 = &serial1;
pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
};
cpus {
@@ -127,21 +129,38 @@
reg = <0x200 0x100>;
};
- i2c@3000 {
+ sleep-nexus {
#address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <14 0x8>;
- interrupt-parent = <&ipic>;
- dfsrr;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ sleep = <&pmc 0x0c000000>;
+ ranges;
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <14 0x8>;
+ interrupt-parent = <&ipic>;
+ dfsrr;
+
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ interrupts = <19 0x8>;
+ interrupt-parent = <&ipic>;
+ };
+ };
- rtc@68 {
- compatible = "dallas,ds1374";
- reg = <0x68>;
- interrupts = <19 0x8>;
+ sdhci@2e000 {
+ compatible = "fsl,mpc8378-esdhc", "fsl,mpc8379-esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <42 0x8>;
interrupt-parent = <&ipic>;
+ /* Filled in by U-Boot */
+ clock-frequency = <0>;
};
};
@@ -213,70 +232,83 @@
interrupts = <38 0x8>;
dr_mode = "host";
phy_type = "ulpi";
+ sleep = <&pmc 0x00c00000>;
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
- phy2: ethernet-phy@2 {
- interrupt-parent = <&ipic>;
- interrupts = <17 0x8>;
- reg = <0x2>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&ipic>;
- interrupts = <18 0x8>;
- reg = <0x3>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <32 0x8 33 0x8 34 0x8>;
phy-connection-type = "mii";
interrupt-parent = <&ipic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy2>;
+ sleep = <&pmc 0xc0000000>;
+ fsl,magic-packet;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&ipic>;
+ interrupts = <17 0x8>;
+ reg = <0x2>;
+ device_type = "ethernet-phy";
+ };
+
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&ipic>;
+ interrupts = <18 0x8>;
+ reg = <0x3>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 0x8 36 0x8 37 0x8>;
phy-connection-type = "mii";
interrupt-parent = <&ipic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy3>;
+ sleep = <&pmc 0x30000000>;
+ fsl,magic-packet;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
@@ -309,14 +341,7 @@
fsl,channel-fifo-len = <24>;
fsl,exec-units-mask = <0x9fe>;
fsl,descriptor-types-mask = <0x3ab0ebf>;
- };
-
- sdhc@2e000 {
- model = "eSDHC";
- compatible = "fsl,esdhc";
- reg = <0x2e000 0x1000>;
- interrupts = <42 0x8>;
- interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x03000000>;
};
/* IPIC
@@ -332,6 +357,13 @@
#interrupt-cells = <2>;
reg = <0x700 0x100>;
};
+
+ pmc: power@b00 {
+ compatible = "fsl,mpc8378-pmc", "fsl,mpc8349-pmc";
+ reg = <0xb00 0x100 0xa00 0x100>;
+ interrupts = <80 0x8>;
+ interrupt-parent = <&ipic>;
+ };
};
pci0: pci@e0008500 {
@@ -387,6 +419,7 @@
0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>;
clock-frequency = <0>;
+ sleep = <&pmc 0x00010000>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
@@ -395,4 +428,68 @@
compatible = "fsl,mpc8349-pci";
device_type = "pci";
};
+
+ pci1: pcie@e0009000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie";
+ reg = <0xe0009000 0x00001000>;
+ ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xb8000000 0 0x00800000>;
+ bus-range = <0 255>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0 0 0 1 &ipic 1 8
+ 0 0 0 2 &ipic 1 8
+ 0 0 0 3 &ipic 1 8
+ 0 0 0 4 &ipic 1 8>;
+ sleep = <&pmc 0x00300000>;
+ clock-frequency = <0>;
+
+ pcie@0 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0 0 0 0 0>;
+ ranges = <0x02000000 0 0xa8000000
+ 0x02000000 0 0xa8000000
+ 0 0x10000000
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00800000>;
+ };
+ };
+
+ pci2: pcie@e000a000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie";
+ reg = <0xe000a000 0x00001000>;
+ ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xd8000000 0 0x00800000>;
+ bus-range = <0 255>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0 0 0 1 &ipic 2 8
+ 0 0 0 2 &ipic 2 8
+ 0 0 0 3 &ipic 2 8
+ 0 0 0 4 &ipic 2 8>;
+ sleep = <&pmc 0x000c0000>;
+ clock-frequency = <0>;
+
+ pcie@0 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0 0 0 0 0>;
+ ranges = <0x02000000 0 0xc8000000
+ 0x02000000 0 0xc8000000
+ 0 0x10000000
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00800000>;
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts
index 23c10ce22c2c..5d90e85704c3 100644
--- a/arch/powerpc/boot/dts/mpc8378_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts
@@ -22,6 +22,8 @@
serial0 = &serial0;
serial1 = &serial1;
pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
};
cpus {
@@ -107,26 +109,72 @@
reg = <0x200 0x100>;
};
- i2c@3000 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <14 0x8>;
+ gpio1: gpio-controller@c00 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8378-gpio", "fsl,mpc8349-gpio";
+ reg = <0xc00 0x100>;
+ interrupts = <74 0x8>;
interrupt-parent = <&ipic>;
- dfsrr;
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
+ gpio-controller;
+ };
+
+ gpio2: gpio-controller@d00 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8378-gpio", "fsl,mpc8349-gpio";
+ reg = <0xd00 0x100>;
+ interrupts = <75 0x8>;
+ interrupt-parent = <&ipic>;
+ gpio-controller;
+ };
+
+ sleep-nexus {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ sleep = <&pmc 0x0c000000>;
+ ranges;
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <14 0x8>;
+ interrupt-parent = <&ipic>;
+ dfsrr;
+
+ dtt@48 {
+ compatible = "national,lm75";
+ reg = <0x48>;
+ };
+
+ at24@50 {
+ compatible = "at24,24c256";
+ reg = <0x50>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+
+ mcu_pio: mcu@a {
+ #gpio-cells = <2>;
+ compatible = "fsl,mc9s08qg8-mpc8378erdb",
+ "fsl,mcu-mpc8349emitx";
+ reg = <0x0a>;
+ gpio-controller;
+ };
};
- mcu_pio: mcu@a {
- #gpio-cells = <2>;
- compatible = "fsl,mc9s08qg8-mpc8378erdb",
- "fsl,mcu-mpc8349emitx";
- reg = <0x0a>;
- gpio-controller;
+ sdhci@2e000 {
+ compatible = "fsl,mpc8378-esdhc", "fsl,mpc8379-esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <42 0x8>;
+ interrupt-parent = <&ipic>;
+ /* Filled in by U-Boot */
+ clock-frequency = <0>;
};
};
@@ -197,62 +245,76 @@
interrupt-parent = <&ipic>;
interrupts = <38 0x8>;
phy_type = "ulpi";
+ sleep = <&pmc 0x00c00000>;
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
- phy2: ethernet-phy@2 {
- interrupt-parent = <&ipic>;
- interrupts = <17 0x8>;
- reg = <0x2>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <32 0x8 33 0x8 34 0x8>;
phy-connection-type = "mii";
interrupt-parent = <&ipic>;
+ tbi-handle = <&tbi0>;
phy-handle = <&phy2>;
+ sleep = <&pmc 0xc0000000>;
+ fsl,magic-packet;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&ipic>;
+ interrupts = <17 0x8>;
+ reg = <0x2>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 0x8 36 0x8 37 0x8>;
phy-connection-type = "mii";
interrupt-parent = <&ipic>;
fixed-link = <1 1 1000 0 0>;
+ tbi-handle = <&tbi1>;
+ sleep = <&pmc 0x30000000>;
+ fsl,magic-packet;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
@@ -285,6 +347,7 @@
fsl,channel-fifo-len = <24>;
fsl,exec-units-mask = <0x9fe>;
fsl,descriptor-types-mask = <0x3ab0ebf>;
+ sleep = <&pmc 0x03000000>;
};
/* IPIC
@@ -300,6 +363,13 @@
#interrupt-cells = <2>;
reg = <0x700 0x100>;
};
+
+ pmc: power@b00 {
+ compatible = "fsl,mpc8378-pmc", "fsl,mpc8349-pmc";
+ reg = <0xb00 0x100 0xa00 0x100>;
+ interrupts = <80 0x8>;
+ interrupt-parent = <&ipic>;
+ };
};
pci0: pci@e0008500 {
@@ -325,6 +395,7 @@
ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
+ sleep = <&pmc 0x00010000>;
clock-frequency = <66666666>;
#interrupt-cells = <1>;
#size-cells = <2>;
@@ -334,4 +405,68 @@
compatible = "fsl,mpc8349-pci";
device_type = "pci";
};
+
+ pci1: pcie@e0009000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie";
+ reg = <0xe0009000 0x00001000>;
+ ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xb8000000 0 0x00800000>;
+ bus-range = <0 255>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0 0 0 1 &ipic 1 8
+ 0 0 0 2 &ipic 1 8
+ 0 0 0 3 &ipic 1 8
+ 0 0 0 4 &ipic 1 8>;
+ sleep = <&pmc 0x00300000>;
+ clock-frequency = <0>;
+
+ pcie@0 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0 0 0 0 0>;
+ ranges = <0x02000000 0 0xa8000000
+ 0x02000000 0 0xa8000000
+ 0 0x10000000
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00800000>;
+ };
+ };
+
+ pci2: pcie@e000a000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "fsl,mpc8378-pcie", "fsl,mpc8314-pcie";
+ reg = <0xe000a000 0x00001000>;
+ ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xd8000000 0 0x00800000>;
+ bus-range = <0 255>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0 0 0 1 &ipic 2 8
+ 0 0 0 2 &ipic 2 8
+ 0 0 0 3 &ipic 2 8
+ 0 0 0 4 &ipic 2 8>;
+ sleep = <&pmc 0x000c0000>;
+ clock-frequency = <0>;
+
+ pcie@0 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0 0 0 0 0>;
+ ranges = <0x02000000 0 0xc8000000
+ 0x02000000 0 0xc8000000
+ 0 0x10000000
+ 0x01000000 0 0x00000000
+ 0x01000000 0 0x00000000
+ 0 0x00800000>;
+ };
+ };
};
diff --git a/arch/powerpc/boot/dts/mpc8379_mds.dts b/arch/powerpc/boot/dts/mpc8379_mds.dts
index acf06c438dbf..d6f208b8297a 100644
--- a/arch/powerpc/boot/dts/mpc8379_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8379_mds.dts
@@ -127,21 +127,38 @@
reg = <0x200 0x100>;
};
- i2c@3000 {
+ sleep-nexus {
#address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <14 0x8>;
- interrupt-parent = <&ipic>;
- dfsrr;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ sleep = <&pmc 0x0c000000>;
+ ranges;
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <14 0x8>;
+ interrupt-parent = <&ipic>;
+ dfsrr;
+
+ rtc@68 {
+ compatible = "dallas,ds1374";
+ reg = <0x68>;
+ interrupts = <19 0x8>;
+ interrupt-parent = <&ipic>;
+ };
+ };
- rtc@68 {
- compatible = "dallas,ds1374";
- reg = <0x68>;
- interrupts = <19 0x8>;
+ sdhci@2e000 {
+ compatible = "fsl,mpc8379-esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <42 0x8>;
interrupt-parent = <&ipic>;
+ /* Filled in by U-Boot */
+ clock-frequency = <0>;
};
};
@@ -213,69 +230,83 @@
interrupts = <38 0x8>;
dr_mode = "host";
phy_type = "ulpi";
- };
-
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
- phy2: ethernet-phy@2 {
- interrupt-parent = <&ipic>;
- interrupts = <17 0x8>;
- reg = <0x2>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&ipic>;
- interrupts = <18 0x8>;
- reg = <0x3>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
+ sleep = <&pmc 0x00c00000>;
};
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <32 0x8 33 0x8 34 0x8>;
phy-connection-type = "mii";
interrupt-parent = <&ipic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy2>;
+ sleep = <&pmc 0xc0000000>;
+ fsl,magic-packet;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&ipic>;
+ interrupts = <17 0x8>;
+ reg = <0x2>;
+ device_type = "ethernet-phy";
+ };
+
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&ipic>;
+ interrupts = <18 0x8>;
+ reg = <0x3>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 0x8 36 0x8 37 0x8>;
phy-connection-type = "mii";
interrupt-parent = <&ipic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy3>;
+ sleep = <&pmc 0x30000000>;
+ fsl,magic-packet;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
@@ -308,14 +339,7 @@
fsl,channel-fifo-len = <24>;
fsl,exec-units-mask = <0x9fe>;
fsl,descriptor-types-mask = <0x3ab0ebf>;
- };
-
- sdhc@2e000 {
- model = "eSDHC";
- compatible = "fsl,esdhc";
- reg = <0x2e000 0x1000>;
- interrupts = <42 0x8>;
- interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x03000000>;
};
sata@18000 {
@@ -323,6 +347,7 @@
reg = <0x18000 0x1000>;
interrupts = <44 0x8>;
interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x000000c0>;
};
sata@19000 {
@@ -330,6 +355,7 @@
reg = <0x19000 0x1000>;
interrupts = <45 0x8>;
interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x00000030>;
};
sata@1a000 {
@@ -337,6 +363,7 @@
reg = <0x1a000 0x1000>;
interrupts = <46 0x8>;
interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x0000000c>;
};
sata@1b000 {
@@ -344,6 +371,7 @@
reg = <0x1b000 0x1000>;
interrupts = <47 0x8>;
interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x00000003>;
};
/* IPIC
@@ -359,6 +387,13 @@
#interrupt-cells = <2>;
reg = <0x700 0x100>;
};
+
+ pmc: power@b00 {
+ compatible = "fsl,mpc8379-pmc", "fsl,mpc8349-pmc";
+ reg = <0xb00 0x100 0xa00 0x100>;
+ interrupts = <80 0x8>;
+ interrupt-parent = <&ipic>;
+ };
};
pci0: pci@e0008500 {
@@ -413,6 +448,7 @@
ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>;
+ sleep = <&pmc 0x00010000>;
clock-frequency = <0>;
#interrupt-cells = <1>;
#size-cells = <2>;
diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts
index 72cdc3c4c7e3..98ae95bd18f4 100644
--- a/arch/powerpc/boot/dts/mpc8379_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts
@@ -107,26 +107,72 @@
reg = <0x200 0x100>;
};
- i2c@3000 {
- #address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <14 0x8>;
+ gpio1: gpio-controller@c00 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8379-gpio", "fsl,mpc8349-gpio";
+ reg = <0xc00 0x100>;
+ interrupts = <74 0x8>;
interrupt-parent = <&ipic>;
- dfsrr;
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
+ gpio-controller;
+ };
+
+ gpio2: gpio-controller@d00 {
+ #gpio-cells = <2>;
+ compatible = "fsl,mpc8379-gpio", "fsl,mpc8349-gpio";
+ reg = <0xd00 0x100>;
+ interrupts = <75 0x8>;
+ interrupt-parent = <&ipic>;
+ gpio-controller;
+ };
+
+ sleep-nexus {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ sleep = <&pmc 0x0c000000>;
+ ranges;
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <14 0x8>;
+ interrupt-parent = <&ipic>;
+ dfsrr;
+
+ dtt@48 {
+ compatible = "national,lm75";
+ reg = <0x48>;
+ };
+
+ at24@50 {
+ compatible = "at24,24c256";
+ reg = <0x50>;
+ };
+
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+
+ mcu_pio: mcu@a {
+ #gpio-cells = <2>;
+ compatible = "fsl,mc9s08qg8-mpc8379erdb",
+ "fsl,mcu-mpc8349emitx";
+ reg = <0x0a>;
+ gpio-controller;
+ };
};
- mcu_pio: mcu@a {
- #gpio-cells = <2>;
- compatible = "fsl,mc9s08qg8-mpc8379erdb",
- "fsl,mcu-mpc8349emitx";
- reg = <0x0a>;
- gpio-controller;
+ sdhci@2e000 {
+ compatible = "fsl,mpc8379-esdhc";
+ reg = <0x2e000 0x1000>;
+ interrupts = <42 0x8>;
+ interrupt-parent = <&ipic>;
+ /* Filled in by U-Boot */
+ clock-frequency = <0>;
};
};
@@ -197,63 +243,76 @@
interrupt-parent = <&ipic>;
interrupts = <38 0x8>;
phy_type = "ulpi";
- };
-
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
- phy2: ethernet-phy@2 {
- interrupt-parent = <&ipic>;
- interrupts = <17 0x8>;
- reg = <0x2>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
+ sleep = <&pmc 0x00c00000>;
};
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <32 0x8 33 0x8 34 0x8>;
phy-connection-type = "mii";
interrupt-parent = <&ipic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy2>;
+ sleep = <&pmc 0xc0000000>;
+ fsl,magic-packet;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&ipic>;
+ interrupts = <17 0x8>;
+ reg = <0x2>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 0x8 36 0x8 37 0x8>;
phy-connection-type = "mii";
interrupt-parent = <&ipic>;
fixed-link = <1 1 1000 0 0>;
tbi-handle = <&tbi1>;
+ sleep = <&pmc 0x30000000>;
+ fsl,magic-packet;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
@@ -286,6 +345,7 @@
fsl,channel-fifo-len = <24>;
fsl,exec-units-mask = <0x9fe>;
fsl,descriptor-types-mask = <0x3ab0ebf>;
+ sleep = <&pmc 0x03000000>;
};
sata@18000 {
@@ -293,6 +353,7 @@
reg = <0x18000 0x1000>;
interrupts = <44 0x8>;
interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x000000c0>;
};
sata@19000 {
@@ -300,6 +361,7 @@
reg = <0x19000 0x1000>;
interrupts = <45 0x8>;
interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x00000030>;
};
sata@1a000 {
@@ -307,6 +369,7 @@
reg = <0x1a000 0x1000>;
interrupts = <46 0x8>;
interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x0000000c>;
};
sata@1b000 {
@@ -314,6 +377,7 @@
reg = <0x1b000 0x1000>;
interrupts = <47 0x8>;
interrupt-parent = <&ipic>;
+ sleep = <&pmc 0x00000003>;
};
/* IPIC
@@ -329,6 +393,13 @@
#interrupt-cells = <2>;
reg = <0x700 0x100>;
};
+
+ pmc: power@b00 {
+ compatible = "fsl,mpc8379-pmc", "fsl,mpc8349-pmc";
+ reg = <0xb00 0x100 0xa00 0x100>;
+ interrupts = <80 0x8>;
+ interrupt-parent = <&ipic>;
+ };
};
pci0: pci@e0008500 {
@@ -354,6 +425,7 @@
ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
+ sleep = <&pmc 0x00010000>;
clock-frequency = <66666666>;
#interrupt-cells = <1>;
#size-cells = <2>;
diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts
index 3c905df1812c..b31c5041350b 100644
--- a/arch/powerpc/boot/dts/mpc8536ds.dts
+++ b/arch/powerpc/boot/dts/mpc8536ds.dts
@@ -137,42 +137,6 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <10 0x1>;
- reg = <0>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <10 0x1>;
- reg = <1>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x26520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
usb@22000 {
compatible = "fsl,mpc8536-usb2-mph", "fsl-usb2-mph";
reg = <0x22000 0x1000>;
@@ -194,31 +158,73 @@
};
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy1>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 0x1>;
+ reg = <0>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 0x1>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <31 2 32 2 33 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy0>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
usb@2b000 {
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts
index 79570ffe41b9..ddd67be10b03 100644
--- a/arch/powerpc/boot/dts/mpc8540ads.dts
+++ b/arch/powerpc/boot/dts/mpc8540ads.dts
@@ -126,97 +126,106 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x0>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x1>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <7 1>;
- reg = <0x3>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x26520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x0>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <7 1>;
+ reg = <0x3>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet2: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <2>;
device_type = "network";
model = "FEC";
compatible = "gianfar";
reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <41 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi2>;
phy-handle = <&phy3>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts
index 221036a8ce23..e45097f44fbd 100644
--- a/arch/powerpc/boot/dts/mpc8541cds.dts
+++ b/arch/powerpc/boot/dts/mpc8541cds.dts
@@ -126,66 +126,72 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x0>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x1>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x0>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts
index 0668d1048779..7c6932be0197 100644
--- a/arch/powerpc/boot/dts/mpc8544ds.dts
+++ b/arch/powerpc/boot/dts/mpc8544ds.dts
@@ -98,44 +98,6 @@
dfsrr;
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0x0>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0x1>;
- device_type = "ethernet-phy";
- };
-
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x26520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
-
dma@21300 {
#address-cells = <1>;
#size-cells = <1>;
@@ -178,31 +140,74 @@
};
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
phy-handle = <&phy0>;
tbi-handle = <&tbi0>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x0>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <31 2 32 2 33 2>;
interrupt-parent = <&mpic>;
phy-handle = <&phy1>;
tbi-handle = <&tbi1>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts
index df774a7088ff..804e90353293 100644
--- a/arch/powerpc/boot/dts/mpc8548cds.dts
+++ b/arch/powerpc/boot/dts/mpc8548cds.dts
@@ -142,129 +142,141 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x0>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x1>;
- device_type = "ethernet-phy";
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x2>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x3>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x26520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@27520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x27520 0x20>;
-
- tbi3: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x0>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x2>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x3>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
/* eTSEC 3/4 are currently broken
enet2: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <2>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <31 2 32 2 33 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi2>;
phy-handle = <&phy2>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet3: ethernet@27000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <3>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x27000 0x1000>;
+ ranges = <0x0 0x27000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <37 2 38 2 39 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi3>;
phy-handle = <&phy3>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
*/
diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts
index 053b01e1c93b..9484f0729b10 100644
--- a/arch/powerpc/boot/dts/mpc8555cds.dts
+++ b/arch/powerpc/boot/dts/mpc8555cds.dts
@@ -126,66 +126,72 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x0>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x1>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x0>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts
index 11b1bcbe14ce..cc2acf87d02f 100644
--- a/arch/powerpc/boot/dts/mpc8560ads.dts
+++ b/arch/powerpc/boot/dts/mpc8560ads.dts
@@ -115,78 +115,84 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x0>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <5 1>;
- reg = <0x1>;
- device_type = "ethernet-phy";
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <7 1>;
- reg = <0x2>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <7 1>;
- reg = <0x3>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x0>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 1>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <7 1>;
+ reg = <0x2>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <7 1>;
+ reg = <0x3>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
mpic: pic@40000 {
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 1955bd9e113d..9d52e3b25047 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -149,78 +149,84 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@7 {
- interrupt-parent = <&mpic>;
- interrupts = <1 1>;
- reg = <0x7>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <2 1>;
- reg = <0x1>;
- device_type = "ethernet-phy";
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <1 1>;
- reg = <0x2>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <2 1>;
- reg = <0x3>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy2>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@7 {
+ interrupt-parent = <&mpic>;
+ interrupts = <1 1>;
+ reg = <0x7>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <1 1>;
+ reg = <0x2>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <2 1>;
+ reg = <0x3>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy3>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts
index 359c3b727420..6e79a4169088 100644
--- a/arch/powerpc/boot/dts/mpc8572ds.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds.dts
@@ -1,7 +1,7 @@
/*
* MPC8572 DS Device Tree Source
*
- * Copyright 2007, 2008 Freescale Semiconductor Inc.
+ * Copyright 2007-2009 Freescale Semiconductor Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -312,129 +312,141 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0x0>;
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0x1>;
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0x2>;
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0x3>;
- };
-
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x26520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@27520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x27520 0x20>;
-
- tbi3: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x2>;
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x3>;
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet2: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <2>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <31 2 32 2 33 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi2>;
phy-handle = <&phy2>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet3: ethernet@27000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <3>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x27000 0x1000>;
+ ranges = <0x0 0x27000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <37 2 38 2 39 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi3>;
phy-handle = <&phy3>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
@@ -643,7 +655,7 @@
0x1000000 0x0 0x0
0x1000000 0x0 0x0
- 0x0 0x100000>;
+ 0x0 0x10000>;
uli1575@0 {
reg = <0x0 0x0 0x0 0x0 0x0>;
#size-cells = <2>;
@@ -654,7 +666,7 @@
0x1000000 0x0 0x0
0x1000000 0x0 0x0
- 0x0 0x100000>;
+ 0x0 0x10000>;
isa@1e {
device_type = "isa";
#interrupt-cells = <2>;
@@ -744,7 +756,7 @@
0x1000000 0x0 0x0
0x1000000 0x0 0x0
- 0x0 0x100000>;
+ 0x0 0x10000>;
};
};
@@ -781,7 +793,7 @@
0x1000000 0x0 0x0
0x1000000 0x0 0x0
- 0x0 0x100000>;
+ 0x0 0x10000>;
};
};
};
diff --git a/arch/powerpc/boot/dts/mpc8572ds_36b.dts b/arch/powerpc/boot/dts/mpc8572ds_36b.dts
new file mode 100644
index 000000000000..dbd81a764742
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8572ds_36b.dts
@@ -0,0 +1,799 @@
+/*
+ * MPC8572 DS Device Tree Source
+ *
+ * Copyright 2007-2009 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+/ {
+ model = "fsl,MPC8572DS";
+ compatible = "fsl,MPC8572DS";
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ ethernet2 = &enet2;
+ ethernet3 = &enet3;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ pci1 = &pci1;
+ pci2 = &pci2;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8572@0 {
+ device_type = "cpu";
+ reg = <0x0>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ next-level-cache = <&L2>;
+ };
+
+ PowerPC,8572@1 {
+ device_type = "cpu";
+ reg = <0x1>;
+ d-cache-line-size = <32>; // 32 bytes
+ i-cache-line-size = <32>; // 32 bytes
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ };
+
+ localbus@fffe05000 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8572-elbc", "fsl,elbc", "simple-bus";
+ reg = <0xf 0xffe05000 0 0x1000>;
+ interrupts = <19 2>;
+ interrupt-parent = <&mpic>;
+
+ ranges = <0x0 0x0 0xf 0xe8000000 0x08000000
+ 0x1 0x0 0xf 0xe0000000 0x08000000
+ 0x2 0x0 0xf 0xffa00000 0x00040000
+ 0x3 0x0 0xf 0xffdf0000 0x00008000
+ 0x4 0x0 0xf 0xffa40000 0x00040000
+ 0x5 0x0 0xf 0xffa80000 0x00040000
+ 0x6 0x0 0xf 0xffac0000 0x00040000>;
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+
+ ramdisk@0 {
+ reg = <0x0 0x03000000>;
+ read-only;
+ };
+
+ diagnostic@3000000 {
+ reg = <0x03000000 0x00e00000>;
+ read-only;
+ };
+
+ dink@3e00000 {
+ reg = <0x03e00000 0x00200000>;
+ read-only;
+ };
+
+ kernel@4000000 {
+ reg = <0x04000000 0x00400000>;
+ read-only;
+ };
+
+ jffs2@4400000 {
+ reg = <0x04400000 0x03b00000>;
+ };
+
+ dtb@7f00000 {
+ reg = <0x07f00000 0x00080000>;
+ read-only;
+ };
+
+ u-boot@7f80000 {
+ reg = <0x07f80000 0x00080000>;
+ read-only;
+ };
+ };
+
+ nand@2,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8572-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x2 0x0 0x40000>;
+
+ u-boot@0 {
+ reg = <0x0 0x02000000>;
+ read-only;
+ };
+
+ jffs2@2000000 {
+ reg = <0x02000000 0x10000000>;
+ };
+
+ ramdisk@12000000 {
+ reg = <0x12000000 0x08000000>;
+ read-only;
+ };
+
+ kernel@1a000000 {
+ reg = <0x1a000000 0x04000000>;
+ };
+
+ dtb@1e000000 {
+ reg = <0x1e000000 0x01000000>;
+ read-only;
+ };
+
+ empty@1f000000 {
+ reg = <0x1f000000 0x21000000>;
+ };
+ };
+
+ nand@4,0 {
+ compatible = "fsl,mpc8572-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x4 0x0 0x40000>;
+ };
+
+ nand@5,0 {
+ compatible = "fsl,mpc8572-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x5 0x0 0x40000>;
+ };
+
+ nand@6,0 {
+ compatible = "fsl,mpc8572-fcm-nand",
+ "fsl,elbc-fcm-nand";
+ reg = <0x6 0x0 0x40000>;
+ };
+ };
+
+ soc8572@fffe00000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ compatible = "simple-bus";
+ ranges = <0x0 0xf 0xffe00000 0x100000>;
+ reg = <0xf 0xffe00000 0 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed
+ bus-frequency = <0>; // Filled out by uboot.
+
+ memory-controller@2000 {
+ compatible = "fsl,mpc8572-memory-controller";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <18 2>;
+ };
+
+ memory-controller@6000 {
+ compatible = "fsl,mpc8572-memory-controller";
+ reg = <0x6000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <18 2>;
+ };
+
+ L2: l2-cache-controller@20000 {
+ compatible = "fsl,mpc8572-l2-cache-controller";
+ reg = <0x20000 0x1000>;
+ cache-line-size = <32>; // 32 bytes
+ cache-size = <0x100000>; // L2, 1M
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x3100 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ dma@c300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8572-dma", "fsl,eloplus-dma";
+ reg = <0xc300 0x4>;
+ ranges = <0x0 0xc100 0x200>;
+ cell-index = <1>;
+ dma-channel@0 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <76 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <77 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <78 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <79 2>;
+ };
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8572-dma", "fsl,eloplus-dma";
+ reg = <0x21300 0x4>;
+ ranges = <0x0 0x21100 0x200>;
+ cell-index = <0>;
+ dma-channel@0 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x0 0x80>;
+ cell-index = <0>;
+ interrupt-parent = <&mpic>;
+ interrupts = <20 2>;
+ };
+ dma-channel@80 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x80 0x80>;
+ cell-index = <1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <21 2>;
+ };
+ dma-channel@100 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x100 0x80>;
+ cell-index = <2>;
+ interrupt-parent = <&mpic>;
+ interrupts = <22 2>;
+ };
+ dma-channel@180 {
+ compatible = "fsl,mpc8572-dma-channel",
+ "fsl,eloplus-dma-channel";
+ reg = <0x180 0x80>;
+ cell-index = <3>;
+ interrupt-parent = <&mpic>;
+ interrupts = <23 2>;
+ };
+ };
+
+ enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <29 2 30 2 34 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi0>;
+ phy-handle = <&phy0>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x1>;
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x2>;
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x3>;
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <35 2 36 2 40 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi1>;
+ phy-handle = <&phy1>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet2: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <2>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <31 2 32 2 33 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi2>;
+ phy-handle = <&phy2>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ enet3: ethernet@27000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <3>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x27000 0x1000>;
+ ranges = <0x0 0x27000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <37 2 38 2 39 2>;
+ interrupt-parent = <&mpic>;
+ tbi-handle = <&tbi3>;
+ phy-handle = <&phy3>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ global-utilities@e0000 { //global utilities block
+ compatible = "fsl,mpc8572-guts";
+ reg = <0xe0000 0x1000>;
+ fsl,has-rstcr;
+ };
+
+ msi@41600 {
+ compatible = "fsl,mpc8572-msi", "fsl,mpic-msi";
+ reg = <0x41600 0x80>;
+ msi-available-ranges = <0 0x100>;
+ interrupts = <
+ 0xe0 0
+ 0xe1 0
+ 0xe2 0
+ 0xe3 0
+ 0xe4 0
+ 0xe5 0
+ 0xe6 0
+ 0xe7 0>;
+ interrupt-parent = <&mpic>;
+ };
+
+ crypto@30000 {
+ compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2",
+ "fsl,sec2.1", "fsl,sec2.0";
+ reg = <0x30000 0x10000>;
+ interrupts = <45 2 58 2>;
+ interrupt-parent = <&mpic>;
+ fsl,num-channels = <4>;
+ fsl,channel-fifo-len = <24>;
+ fsl,exec-units-mask = <0x9fe>;
+ fsl,descriptor-types-mask = <0x3ab0ebf>;
+ };
+
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+ };
+
+ pci0: pcie@fffe08000 {
+ cell-index = <0>;
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xf 0xffe08000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0xc0000000 0xc 0x00000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x00010000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <24 2>;
+ interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x11 func 0 - PCI slot 1 */
+ 0x8800 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8800 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8800 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8800 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 1 - PCI slot 1 */
+ 0x8900 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8900 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8900 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8900 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 2 - PCI slot 1 */
+ 0x8a00 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8a00 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8a00 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8a00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 3 - PCI slot 1 */
+ 0x8b00 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8b00 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8b00 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8b00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 4 - PCI slot 1 */
+ 0x8c00 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8c00 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8c00 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8c00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 5 - PCI slot 1 */
+ 0x8d00 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8d00 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8d00 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8d00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 6 - PCI slot 1 */
+ 0x8e00 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8e00 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8e00 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8e00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x11 func 7 - PCI slot 1 */
+ 0x8f00 0x0 0x0 0x1 &mpic 0x2 0x1
+ 0x8f00 0x0 0x0 0x2 &mpic 0x3 0x1
+ 0x8f00 0x0 0x0 0x3 &mpic 0x4 0x1
+ 0x8f00 0x0 0x0 0x4 &mpic 0x1 0x1
+
+ /* IDSEL 0x12 func 0 - PCI slot 2 */
+ 0x9000 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9000 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9000 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9000 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 1 - PCI slot 2 */
+ 0x9100 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9100 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9100 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9100 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 2 - PCI slot 2 */
+ 0x9200 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9200 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9200 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9200 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 3 - PCI slot 2 */
+ 0x9300 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9300 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9300 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9300 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 4 - PCI slot 2 */
+ 0x9400 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9400 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9400 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9400 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 5 - PCI slot 2 */
+ 0x9500 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9500 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9500 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9500 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 6 - PCI slot 2 */
+ 0x9600 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9600 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9600 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9600 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ /* IDSEL 0x12 func 7 - PCI slot 2 */
+ 0x9700 0x0 0x0 0x1 &mpic 0x3 0x1
+ 0x9700 0x0 0x0 0x2 &mpic 0x4 0x1
+ 0x9700 0x0 0x0 0x3 &mpic 0x1 0x1
+ 0x9700 0x0 0x0 0x4 &mpic 0x2 0x1
+
+ // IDSEL 0x1c USB
+ 0xe000 0x0 0x0 0x1 &i8259 0xc 0x2
+ 0xe100 0x0 0x0 0x2 &i8259 0x9 0x2
+ 0xe200 0x0 0x0 0x3 &i8259 0xa 0x2
+ 0xe300 0x0 0x0 0x4 &i8259 0xb 0x2
+
+ // IDSEL 0x1d Audio
+ 0xe800 0x0 0x0 0x1 &i8259 0x6 0x2
+
+ // IDSEL 0x1e Legacy
+ 0xf000 0x0 0x0 0x1 &i8259 0x7 0x2
+ 0xf100 0x0 0x0 0x1 &i8259 0x7 0x2
+
+ // IDSEL 0x1f IDE/SATA
+ 0xf800 0x0 0x0 0x1 &i8259 0xe 0x2
+ 0xf900 0x0 0x0 0x1 &i8259 0x5 0x2
+
+ >;
+
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ uli1575@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ isa@1e {
+ device_type = "isa";
+ #interrupt-cells = <2>;
+ #size-cells = <1>;
+ #address-cells = <2>;
+ reg = <0xf000 0x0 0x0 0x0 0x0>;
+ ranges = <0x1 0x0 0x1000000 0x0 0x0
+ 0x1000>;
+ interrupt-parent = <&i8259>;
+
+ i8259: interrupt-controller@20 {
+ reg = <0x1 0x20 0x2
+ 0x1 0xa0 0x2
+ 0x1 0x4d0 0x2>;
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ compatible = "chrp,iic";
+ interrupts = <9 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ i8042@60 {
+ #size-cells = <0>;
+ #address-cells = <1>;
+ reg = <0x1 0x60 0x1 0x1 0x64 0x1>;
+ interrupts = <1 3 12 3>;
+ interrupt-parent =
+ <&i8259>;
+
+ keyboard@0 {
+ reg = <0x0>;
+ compatible = "pnpPNP,303";
+ };
+
+ mouse@1 {
+ reg = <0x1>;
+ compatible = "pnpPNP,f03";
+ };
+ };
+
+ rtc@70 {
+ compatible = "pnpPNP,b00";
+ reg = <0x1 0x70 0x2>;
+ };
+
+ gpio@400 {
+ reg = <0x1 0x400 0x80>;
+ };
+ };
+ };
+ };
+
+ };
+
+ pci1: pcie@fffe09000 {
+ cell-index = <1>;
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xf 0xffe09000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x00010000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <25 2>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0x0 0x0 0x1 &mpic 0x4 0x1
+ 0000 0x0 0x0 0x2 &mpic 0x5 0x1
+ 0000 0x0 0x0 0x3 &mpic 0x6 0x1
+ 0000 0x0 0x0 0x4 &mpic 0x7 0x1
+ >;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+
+ pci2: pcie@fffe0a000 {
+ cell-index = <2>;
+ compatible = "fsl,mpc8548-pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xf 0xffe0a000 0 0x1000>;
+ bus-range = <0 255>;
+ ranges = <0x2000000 0x0 0xc0000000 0xc 0x40000000 0x0 0x20000000
+ 0x1000000 0x0 0x00000000 0xf 0xffc20000 0x0 0x00010000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&mpic>;
+ interrupts = <26 2>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x0 */
+ 0000 0x0 0x0 0x1 &mpic 0x0 0x1
+ 0000 0x0 0x0 0x2 &mpic 0x1 0x1
+ 0000 0x0 0x0 0x3 &mpic 0x2 0x1
+ 0000 0x0 0x0 0x4 &mpic 0x3 0x1
+ >;
+ pcie@0 {
+ reg = <0x0 0x0 0x0 0x0 0x0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ ranges = <0x2000000 0x0 0xc0000000
+ 0x2000000 0x0 0xc0000000
+ 0x0 0x20000000
+
+ 0x1000000 0x0 0x0
+ 0x1000000 0x0 0x0
+ 0x0 0x10000>;
+ };
+ };
+};
diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
index fd462efa9e61..2bc0c7189653 100644
--- a/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
@@ -6,7 +6,7 @@
* This dts file allows core0 to have memory, l2, i2c, dma1, global-util, eth0,
* eth1, crypto, pci0, pci1.
*
- * Copyright 2007, 2008 Freescale Semiconductor Inc.
+ * Copyright 2007-2009 Freescale Semiconductor Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -148,35 +148,38 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0x0>;
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0x1>;
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
phy-handle = <&phy0>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x1>;
+ };
+ };
};
enet1: ethernet@25000 {
@@ -227,7 +230,7 @@
device_type = "open-pic";
protected-sources = <
31 32 33 37 38 39 /* enet2 enet3 */
- 76 77 78 79 27 42 /* dma2 pci2 serial*/
+ 76 77 78 79 26 42 /* dma2 pci2 serial*/
0xe0 0xe1 0xe2 0xe3 /* msi */
0xe4 0xe5 0xe6 0xe7
>;
@@ -376,7 +379,7 @@
0x1000000 0x0 0x0
0x1000000 0x0 0x0
- 0x0 0x100000>;
+ 0x0 0x10000>;
uli1575@0 {
reg = <0x0 0x0 0x0 0x0 0x0>;
#size-cells = <2>;
@@ -387,7 +390,7 @@
0x1000000 0x0 0x0
0x1000000 0x0 0x0
- 0x0 0x100000>;
+ 0x0 0x10000>;
isa@1e {
device_type = "isa";
#interrupt-cells = <2>;
@@ -477,7 +480,7 @@
0x1000000 0x0 0x0
0x1000000 0x0 0x0
- 0x0 0x100000>;
+ 0x0 0x10000>;
};
};
};
diff --git a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
index e35230f2ac93..159cb3a875f0 100644
--- a/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
@@ -7,7 +7,7 @@
*
* Please note to add "-b 1" for core1's dts compiling.
*
- * Copyright 2007, 2008 Freescale Semiconductor Inc.
+ * Copyright 2007-2009 Freescale Semiconductor Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -186,7 +186,7 @@
protected-sources = <
18 16 10 42 45 58 /* MEM L2 mdio serial crypto */
29 30 34 35 36 40 /* enet0 enet1 */
- 24 26 20 21 22 23 /* pcie0 pcie1 dma1 */
+ 24 25 20 21 22 23 /* pci0 pci1 dma1 */
43 /* i2c */
0x1 0x2 0x3 0x4 /* pci slot */
0x9 0xa 0xb 0xc /* usb */
@@ -228,7 +228,7 @@
0x1000000 0x0 0x0
0x1000000 0x0 0x0
- 0x0 0x100000>;
+ 0x0 0x10000>;
};
};
};
diff --git a/arch/powerpc/boot/dts/mpc8610_hpcd.dts b/arch/powerpc/boot/dts/mpc8610_hpcd.dts
index f724d72c7b92..1bd3ebe11437 100644
--- a/arch/powerpc/boot/dts/mpc8610_hpcd.dts
+++ b/arch/powerpc/boot/dts/mpc8610_hpcd.dts
@@ -217,6 +217,7 @@
codec-handle = <&cs4270>;
fsl,playback-dma = <&dma00>;
fsl,capture-dma = <&dma01>;
+ fsl,fifo-depth = <8>;
};
ssi@16100 {
@@ -225,6 +226,7 @@
reg = <0x16100 0x100>;
interrupt-parent = <&mpic>;
interrupts = <63 2>;
+ fsl,fifo-depth = <8>;
};
dma@21300 {
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index 4481532cbe77..d72beb192460 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -180,133 +180,144 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <1>;
- device_type = "ethernet-phy";
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <2>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <3>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x26520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@27520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x27520 0x20>;
-
- tbi3: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <2>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <3>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet2: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <2>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <31 2 32 2 33 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi2>;
phy-handle = <&phy2>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet3: ethernet@27000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <3>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x27000 0x1000>;
+ ranges = <0x0 0x27000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <37 2 38 2 39 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi3>;
phy-handle = <&phy3>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts
index be2c11ca0594..895834713894 100644
--- a/arch/powerpc/boot/dts/pcm030.dts
+++ b/arch/powerpc/boot/dts/pcm030.dts
@@ -19,6 +19,7 @@
compatible = "phytec,pcm030";
#address-cells = <1>;
#size-cells = <1>;
+ interrupt-parent = <&mpc5200_pic>;
cpus {
#address-cells = <1>;
@@ -29,26 +30,26 @@
reg = <0>;
d-cache-line-size = <32>;
i-cache-line-size = <32>;
- d-cache-size = <0x4000>; /* L1, 16K */
- i-cache-size = <0x4000>; /* L1, 16K */
- timebase-frequency = <0>; /* From Bootloader */
- bus-frequency = <0>; /* From Bootloader */
- clock-frequency = <0>; /* From Bootloader */
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>; // from bootloader
+ bus-frequency = <0>; // from bootloader
+ clock-frequency = <0>; // from bootloader
};
};
memory {
device_type = "memory";
- reg = <0x00000000 0x04000000>; /* 64MB */
+ reg = <0x00000000 0x04000000>; // 64MB
};
soc5200@f0000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc5200b-immr";
- ranges = <0x0 0xf0000000 0x0000c000>;
- bus-frequency = <0>; /* From bootloader */
- system-frequency = <0>; /* From bootloader */
+ ranges = <0 0xf0000000 0x0000c000>;
+ bus-frequency = <0>; // from bootloader
+ system-frequency = <0>; // from bootloader
cdm@200 {
compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm";
@@ -56,87 +57,70 @@
};
mpc5200_pic: interrupt-controller@500 {
- /* 5200 interrupts are encoded into two levels; */
+ // 5200 interrupts are encoded into two levels;
interrupt-controller;
#interrupt-cells = <3>;
- device_type = "interrupt-controller";
compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
reg = <0x500 0x80>;
};
- timer@600 { /* General Purpose Timer */
+ timer@600 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
- cell-index = <0>;
reg = <0x600 0x10>;
- interrupts = <0x1 0x9 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <1 9 0>;
fsl,has-wdt;
};
- timer@610 { /* General Purpose Timer */
+ timer@610 { // General Purpose Timer
compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
- cell-index = <1>;
reg = <0x610 0x10>;
- interrupts = <0x1 0xa 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <1 10 0>;
};
- gpt2: timer@620 { /* General Purpose Timer in GPIO mode */
+ gpt2: timer@620 { // General Purpose Timer in GPIO mode
compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio";
- cell-index = <2>;
reg = <0x620 0x10>;
- interrupts = <0x1 0xb 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <1 11 0>;
gpio-controller;
#gpio-cells = <2>;
};
- gpt3: timer@630 { /* General Purpose Timer in GPIO mode */
+ gpt3: timer@630 { // General Purpose Timer in GPIO mode
compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio";
- cell-index = <3>;
reg = <0x630 0x10>;
- interrupts = <0x1 0xc 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <1 12 0>;
gpio-controller;
#gpio-cells = <2>;
};
- gpt4: timer@640 { /* General Purpose Timer in GPIO mode */
+ gpt4: timer@640 { // General Purpose Timer in GPIO mode
compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio";
- cell-index = <4>;
reg = <0x640 0x10>;
- interrupts = <0x1 0xd 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <1 13 0>;
gpio-controller;
#gpio-cells = <2>;
};
- gpt5: timer@650 { /* General Purpose Timer in GPIO mode */
+ gpt5: timer@650 { // General Purpose Timer in GPIO mode
compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio";
- cell-index = <5>;
reg = <0x650 0x10>;
- interrupts = <0x1 0xe 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <1 14 0>;
gpio-controller;
#gpio-cells = <2>;
};
- gpt6: timer@660 { /* General Purpose Timer in GPIO mode */
+ gpt6: timer@660 { // General Purpose Timer in GPIO mode
compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio";
- cell-index = <6>;
reg = <0x660 0x10>;
- interrupts = <0x1 0xf 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <1 15 0>;
gpio-controller;
#gpio-cells = <2>;
};
- gpt7: timer@670 { /* General Purpose Timer in GPIO mode */
+ gpt7: timer@670 { // General Purpose Timer in GPIO mode
compatible = "fsl,mpc5200b-gpt-gpio","fsl,mpc5200-gpt-gpio";
- cell-index = <7>;
reg = <0x670 0x10>;
- interrupts = <0x1 0x10 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <1 16 0>;
gpio-controller;
#gpio-cells = <2>;
};
@@ -144,40 +128,33 @@
rtc@800 { // Real time clock
compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
reg = <0x800 0x100>;
- interrupts = <0x1 0x5 0x0 0x1 0x6 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <1 5 0 1 6 0>;
};
can@900 {
compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
- cell-index = <0>;
- interrupts = <0x2 0x11 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <2 17 0>;
reg = <0x900 0x80>;
};
can@980 {
compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
- cell-index = <1>;
- interrupts = <0x2 0x12 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <2 18 0>;
reg = <0x980 0x80>;
};
gpio_simple: gpio@b00 {
compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
reg = <0xb00 0x40>;
- interrupts = <0x1 0x7 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <1 7 0>;
gpio-controller;
#gpio-cells = <2>;
};
- gpio_wkup: gpio-wkup@c00 {
+ gpio_wkup: gpio@c00 {
compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
reg = <0xc00 0x40>;
- interrupts = <0x1 0x8 0x0 0x0 0x3 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <1 8 0 0 3 0>;
gpio-controller;
#gpio-cells = <2>;
};
@@ -185,26 +162,22 @@
spi@f00 {
compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
reg = <0xf00 0x20>;
- interrupts = <0x2 0xd 0x0 0x2 0xe 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <2 13 0 2 14 0>;
};
usb@1000 {
compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
reg = <0x1000 0xff>;
- interrupts = <0x2 0x6 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <2 6 0>;
};
dma-controller@1200 {
- device_type = "dma-controller";
compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
reg = <0x1200 0x80>;
- interrupts = <0x3 0x0 0x0 0x3 0x1 0x0 0x3 0x2 0x0 0x3 0x3 0x0
- 0x3 0x4 0x0 0x3 0x5 0x0 0x3 0x6 0x0 0x3 0x7 0x0
- 0x3 0x8 0x0 0x3 0x9 0x0 0x3 0xa 0x0 0x3 0xb 0x0
- 0x3 0xc 0x0 0x3 0xd 0x0 0x3 0xe 0x0 0x3 0xf 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
+ 3 4 0 3 5 0 3 6 0 3 7 0
+ 3 8 0 3 9 0 3 10 0 3 11 0
+ 3 12 0 3 13 0 3 14 0 3 15 0>;
};
xlb@1f00 {
@@ -213,24 +186,19 @@
};
ac97@2000 { /* PSC1 in ac97 mode */
- device_type = "sound";
compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97";
cell-index = <0>;
reg = <0x2000 0x100>;
- interrupts = <0x2 0x2 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <2 1 0>;
};
/* PSC2 port is used by CAN1/2 */
serial@2400 { /* PSC3 in UART mode */
- device_type = "serial";
compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
- port-number = <0>;
cell-index = <2>;
reg = <0x2400 0x100>;
- interrupts = <0x2 0x3 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <2 3 0>;
};
/* PSC4 is ??? */
@@ -238,55 +206,44 @@
/* PSC5 is ??? */
serial@2c00 { /* PSC6 in UART mode */
- device_type = "serial";
compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
- port-number = <1>;
cell-index = <5>;
reg = <0x2c00 0x100>;
- interrupts = <0x2 0x4 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <2 4 0>;
};
ethernet@3000 {
- device_type = "network";
compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
reg = <0x3000 0x400>;
- local-mac-address = [00 00 00 00 00 00];
- interrupts = <0x2 0x5 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <2 5 0>;
phy-handle = <&phy0>;
};
mdio@3000 {
#address-cells = <1>;
#size-cells = <0>;
- compatible = "fsl,mpc5200b-mdio", "fsl,mpc5200-mdio";
- reg = <0x3000 0x400>; /* fec range, since we need to setup fec interrupts */
- interrupts = <0x2 0x5 0x0>; /* these are for "mii command finished", not link changes & co. */
- interrupt-parent = <&mpc5200_pic>;
-
- phy0:ethernet-phy@0 {
- device_type = "ethernet-phy";
- reg = <0x0>;
+ compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
+ reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts
+ interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
};
};
ata@3a00 {
- device_type = "ata";
compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
reg = <0x3a00 0x100>;
- interrupts = <0x2 0x7 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <2 7 0>;
};
i2c@3d00 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
- cell-index = <0>;
reg = <0x3d00 0x40>;
- interrupts = <0x2 0xf 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <2 15 0>;
fsl5200-clocking;
};
@@ -294,10 +251,8 @@
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
- cell-index = <1>;
reg = <0x3d40 0x40>;
- interrupts = <0x2 0x10 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <2 16 0>;
fsl5200-clocking;
rtc@51 {
compatible = "nxp,pcf8563";
@@ -307,7 +262,7 @@
};
sram@8000 {
- compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram","sram";
+ compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
reg = <0x8000 0x4000>;
};
@@ -340,22 +295,21 @@
device_type = "pci";
compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci";
reg = <0xf0000d00 0x100>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <0xc000 0x0 0x0 0x1 &mpc5200_pic 0x0 0x0 0x3 /* 1st slot */
- 0xc000 0x0 0x0 0x2 &mpc5200_pic 0x1 0x1 0x3
- 0xc000 0x0 0x0 0x3 &mpc5200_pic 0x1 0x2 0x3
- 0xc000 0x0 0x0 0x4 &mpc5200_pic 0x1 0x3 0x3
-
- 0xc800 0x0 0x0 0x1 &mpc5200_pic 0x1 0x1 0x3 /* 2nd slot */
- 0xc800 0x0 0x0 0x2 &mpc5200_pic 0x1 0x2 0x3
- 0xc800 0x0 0x0 0x3 &mpc5200_pic 0x1 0x3 0x3
- 0xc800 0x0 0x0 0x4 &mpc5200_pic 0x0 0x0 0x3>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 // 1st slot
+ 0xc000 0 0 2 &mpc5200_pic 1 1 3
+ 0xc000 0 0 3 &mpc5200_pic 1 2 3
+ 0xc000 0 0 4 &mpc5200_pic 1 3 3
+
+ 0xc800 0 0 1 &mpc5200_pic 1 1 3 // 2nd slot
+ 0xc800 0 0 2 &mpc5200_pic 1 2 3
+ 0xc800 0 0 3 &mpc5200_pic 1 3 3
+ 0xc800 0 0 4 &mpc5200_pic 0 0 3>;
clock-frequency = <0>; // From boot loader
- interrupts = <0x2 0x8 0x0 0x2 0x9 0x0 0x2 0xa 0x0>;
- interrupt-parent = <&mpc5200_pic>;
+ interrupts = <2 8 0 2 9 0 2 10 0>;
bus-range = <0 0>;
- ranges = <0x42000000 0x0 0x80000000 0x80000000 0x0 0x20000000
- 0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
- 0x01000000 0x0 0x00000000 0xb0000000 0x0 0x01000000>;
+ ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
+ 0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
};
};
diff --git a/arch/powerpc/boot/dts/pcm032.dts b/arch/powerpc/boot/dts/pcm032.dts
new file mode 100644
index 000000000000..030042678392
--- /dev/null
+++ b/arch/powerpc/boot/dts/pcm032.dts
@@ -0,0 +1,392 @@
+/*
+ * phyCORE-MPC5200B-IO (pcm032) board Device Tree Source
+ *
+ * Copyright (C) 2006-2009 Pengutronix
+ * Sascha Hauer <s.hauer@pengutronix.de>
+ * Juergen Beisert <j.beisert@pengutronix.de>
+ * Wolfram Sang <w.sang@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+ model = "phytec,pcm032";
+ compatible = "phytec,pcm032";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&mpc5200_pic>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,5200@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <0x4000>; // L1, 16K
+ i-cache-size = <0x4000>; // L1, 16K
+ timebase-frequency = <0>; // from bootloader
+ bus-frequency = <0>; // from bootloader
+ clock-frequency = <0>; // from bootloader
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x08000000>; // 128MB
+ };
+
+ soc5200@f0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc5200b-immr";
+ ranges = <0 0xf0000000 0x0000c000>;
+ bus-frequency = <0>; // from bootloader
+ system-frequency = <0>; // from bootloader
+
+ cdm@200 {
+ compatible = "fsl,mpc5200b-cdm","fsl,mpc5200-cdm";
+ reg = <0x200 0x38>;
+ };
+
+ mpc5200_pic: interrupt-controller@500 {
+ // 5200 interrupts are encoded into two levels;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ compatible = "fsl,mpc5200b-pic","fsl,mpc5200-pic";
+ reg = <0x500 0x80>;
+ };
+
+ timer@600 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x600 0x10>;
+ interrupts = <1 9 0>;
+ fsl,has-wdt;
+ };
+
+ timer@610 { // General Purpose Timer
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x610 0x10>;
+ interrupts = <1 10 0>;
+ };
+
+ gpt2: timer@620 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x620 0x10>;
+ interrupts = <1 11 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt3: timer@630 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x630 0x10>;
+ interrupts = <1 12 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt4: timer@640 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x640 0x10>;
+ interrupts = <1 13 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt5: timer@650 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x650 0x10>;
+ interrupts = <1 14 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt6: timer@660 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x660 0x10>;
+ interrupts = <1 15 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpt7: timer@670 { // General Purpose Timer in GPIO mode
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
+ reg = <0x670 0x10>;
+ interrupts = <1 16 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ rtc@800 { // Real time clock
+ compatible = "fsl,mpc5200b-rtc","fsl,mpc5200-rtc";
+ reg = <0x800 0x100>;
+ interrupts = <1 5 0 1 6 0>;
+ };
+
+ can@900 {
+ compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
+ interrupts = <2 17 0>;
+ reg = <0x900 0x80>;
+ };
+
+ can@980 {
+ compatible = "fsl,mpc5200b-mscan","fsl,mpc5200-mscan";
+ interrupts = <2 18 0>;
+ reg = <0x980 0x80>;
+ };
+
+ gpio_simple: gpio@b00 {
+ compatible = "fsl,mpc5200b-gpio","fsl,mpc5200-gpio";
+ reg = <0xb00 0x40>;
+ interrupts = <1 7 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio_wkup: gpio@c00 {
+ compatible = "fsl,mpc5200b-gpio-wkup","fsl,mpc5200-gpio-wkup";
+ reg = <0xc00 0x40>;
+ interrupts = <1 8 0 0 3 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ spi@f00 {
+ compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi";
+ reg = <0xf00 0x20>;
+ interrupts = <2 13 0 2 14 0>;
+ };
+
+ usb@1000 {
+ compatible = "fsl,mpc5200b-ohci","fsl,mpc5200-ohci","ohci-be";
+ reg = <0x1000 0xff>;
+ interrupts = <2 6 0>;
+ };
+
+ dma-controller@1200 {
+ compatible = "fsl,mpc5200b-bestcomm","fsl,mpc5200-bestcomm";
+ reg = <0x1200 0x80>;
+ interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
+ 3 4 0 3 5 0 3 6 0 3 7 0
+ 3 8 0 3 9 0 3 10 0 3 11 0
+ 3 12 0 3 13 0 3 14 0 3 15 0>;
+ };
+
+ xlb@1f00 {
+ compatible = "fsl,mpc5200b-xlb","fsl,mpc5200-xlb";
+ reg = <0x1f00 0x100>;
+ };
+
+ ac97@2000 { /* PSC1 is ac97 */
+ compatible = "fsl,mpc5200b-psc-ac97","fsl,mpc5200-psc-ac97";
+ cell-index = <0>;
+ reg = <0x2000 0x100>;
+ interrupts = <2 1 0>;
+ };
+
+ /* PSC2 port is used by CAN1/2 */
+
+ serial@2400 { /* PSC3 in UART mode */
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+ cell-index = <2>;
+ reg = <0x2400 0x100>;
+ interrupts = <2 3 0>;
+ };
+
+ /* PSC4 is ??? */
+
+ /* PSC5 is ??? */
+
+ serial@2c00 { /* PSC6 in UART mode */
+ compatible = "fsl,mpc5200b-psc-uart","fsl,mpc5200-psc-uart";
+ cell-index = <5>;
+ reg = <0x2c00 0x100>;
+ interrupts = <2 4 0>;
+ };
+
+ ethernet@3000 {
+ compatible = "fsl,mpc5200b-fec","fsl,mpc5200-fec";
+ reg = <0x3000 0x400>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <2 5 0>;
+ phy-handle = <&phy0>;
+ };
+
+ mdio@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200b-mdio","fsl,mpc5200-mdio";
+ reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts
+ interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+
+ ata@3a00 {
+ compatible = "fsl,mpc5200b-ata","fsl,mpc5200-ata";
+ reg = <0x3a00 0x100>;
+ interrupts = <2 7 0>;
+ };
+
+ i2c@3d00 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+ reg = <0x3d00 0x40>;
+ interrupts = <2 15 0>;
+ fsl5200-clocking;
+ };
+
+ i2c@3d40 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
+ reg = <0x3d40 0x40>;
+ interrupts = <2 16 0>;
+ fsl5200-clocking;
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ eeprom@52 {
+ compatible = "at24,24c32";
+ reg = <0x52>;
+ };
+ };
+
+ sram@8000 {
+ compatible = "fsl,mpc5200b-sram","fsl,mpc5200-sram";
+ reg = <0x8000 0x4000>;
+ };
+ };
+
+ pci@f0000d00 {
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ device_type = "pci";
+ compatible = "fsl,mpc5200b-pci","fsl,mpc5200-pci";
+ reg = <0xf0000d00 0x100>;
+ interrupt-map-mask = <0xf800 0 0 7>;
+ interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 // 1st slot
+ 0xc000 0 0 2 &mpc5200_pic 1 1 3
+ 0xc000 0 0 3 &mpc5200_pic 1 2 3
+ 0xc000 0 0 4 &mpc5200_pic 1 3 3
+
+ 0xc800 0 0 1 &mpc5200_pic 1 1 3 // 2nd slot
+ 0xc800 0 0 2 &mpc5200_pic 1 2 3
+ 0xc800 0 0 3 &mpc5200_pic 1 3 3
+ 0xc800 0 0 4 &mpc5200_pic 0 0 3>;
+ clock-frequency = <0>; // From boot loader
+ interrupts = <2 8 0 2 9 0 2 10 0>;
+ bus-range = <0 0>;
+ ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
+ 0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
+ 0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;
+ };
+
+ localbus {
+ compatible = "fsl,mpc5200b-lpb","fsl,mpc5200-lpb","simple-bus";
+
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ ranges = <0 0 0xfe000000 0x02000000
+ 1 0 0xfc000000 0x02000000
+ 2 0 0xfbe00000 0x00200000
+ 3 0 0xf9e00000 0x02000000
+ 4 0 0xf7e00000 0x02000000
+ 5 0 0xe6000000 0x02000000
+ 6 0 0xe8000000 0x02000000
+ 7 0 0xea000000 0x02000000>;
+
+ flash@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x02000000>;
+ bank-width = <4>;
+ #size-cells = <1>;
+ #address-cells = <1>;
+
+ partition@0 {
+ label = "ubootl";
+ reg = <0x00000000 0x00040000>;
+ };
+ partition@40000 {
+ label = "kernel";
+ reg = <0x00040000 0x001c0000>;
+ };
+ partition@200000 {
+ label = "jffs2";
+ reg = <0x00200000 0x01d00000>;
+ };
+ partition@1f00000 {
+ label = "uboot";
+ reg = <0x01f00000 0x00040000>;
+ };
+ partition@1f40000 {
+ label = "env";
+ reg = <0x01f40000 0x00040000>;
+ };
+ partition@1f80000 {
+ label = "oftree";
+ reg = <0x01f80000 0x00040000>;
+ };
+ partition@1fc0000 {
+ label = "space";
+ reg = <0x01fc0000 0x00040000>;
+ };
+ };
+
+ sram@2,0 {
+ compatible = "mtd-ram";
+ reg = <2 0 0x00200000>;
+ bank-width = <2>;
+ };
+
+ /*
+ * example snippets for FPGA
+ *
+ * fpga@3,0 {
+ * compatible = "fpga_driver";
+ * reg = <3 0 0x02000000>;
+ * bank-width = <4>;
+ * };
+ *
+ * fpga@4,0 {
+ * compatible = "fpga_driver";
+ * reg = <4 0 0x02000000>;
+ * bank-width = <4>;
+ * };
+ */
+
+ /*
+ * example snippets for free chipselects
+ *
+ * device@5,0 {
+ * compatible = "custom_driver";
+ * reg = <5 0 0x02000000>;
+ * };
+ *
+ * device@6,0 {
+ * compatible = "custom_driver";
+ * reg = <6 0 0x02000000>;
+ * };
+ *
+ * device@7,0 {
+ * compatible = "custom_driver";
+ * reg = <7 0 0x02000000>;
+ * };
+ */
+ };
+};
+
diff --git a/arch/powerpc/boot/dts/redwood.dts b/arch/powerpc/boot/dts/redwood.dts
new file mode 100644
index 000000000000..ad402c488741
--- /dev/null
+++ b/arch/powerpc/boot/dts/redwood.dts
@@ -0,0 +1,244 @@
+/*
+ * Device Tree Source for AMCC Redwood(460SX)
+ *
+ * Copyright 2008 AMCC <tmarri@amcc.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ model = "amcc,redwood";
+ compatible = "amcc,redwood";
+ dcr-parent = <&{/cpus/cpu@0}>;
+
+ aliases {
+ ethernet0 = &EMAC0;
+ serial0 = &UART0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ model = "PowerPC,460SX";
+ reg = <0x00000000>;
+ clock-frequency = <0>; /* Filled in by U-Boot */
+ timebase-frequency = <0>; /* Filled in by U-Boot */
+ i-cache-line-size = <32>;
+ d-cache-line-size = <32>;
+ i-cache-size = <32768>;
+ d-cache-size = <32768>;
+ dcr-controller;
+ dcr-access-method = "native";
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by U-Boot */
+ };
+
+ UIC0: interrupt-controller0 {
+ compatible = "ibm,uic-460sx","ibm,uic";
+ interrupt-controller;
+ cell-index = <0>;
+ dcr-reg = <0x0c0 0x009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ };
+
+ UIC1: interrupt-controller1 {
+ compatible = "ibm,uic-460sx","ibm,uic";
+ interrupt-controller;
+ cell-index = <1>;
+ dcr-reg = <0x0d0 0x009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
+ interrupt-parent = <&UIC0>;
+ };
+
+ UIC2: interrupt-controller2 {
+ compatible = "ibm,uic-460sx","ibm,uic";
+ interrupt-controller;
+ cell-index = <2>;
+ dcr-reg = <0x0e0 0x009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <0xa 0x4 0xb 0x4>; /* cascade */
+ interrupt-parent = <&UIC0>;
+ };
+
+ UIC3: interrupt-controller3 {
+ compatible = "ibm,uic-460sx","ibm,uic";
+ interrupt-controller;
+ cell-index = <3>;
+ dcr-reg = <0x0f0 0x009>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+ interrupts = <0x10 0x4 0x11 0x4>; /* cascade */
+ interrupt-parent = <&UIC0>;
+ };
+
+ SDR0: sdr {
+ compatible = "ibm,sdr-460sx";
+ dcr-reg = <0x00e 0x002>;
+ };
+
+ CPR0: cpr {
+ compatible = "ibm,cpr-460sx";
+ dcr-reg = <0x00c 0x002>;
+ };
+
+ plb {
+ compatible = "ibm,plb-460sx", "ibm,plb4";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges;
+ clock-frequency = <0>; /* Filled in by U-Boot */
+
+ SDRAM0: sdram {
+ compatible = "ibm,sdram-460sx", "ibm,sdram-405gp";
+ dcr-reg = <0x010 0x002>;
+ };
+
+ MAL0: mcmal {
+ compatible = "ibm,mcmal-460sx", "ibm,mcmal2";
+ dcr-reg = <0x180 0x62>;
+ num-tx-chans = <4>;
+ num-rx-chans = <32>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-parent = <&UIC1>;
+ interrupts = < /*TXEOB*/ 0x6 0x4
+ /*RXEOB*/ 0x7 0x4
+ /*SERR*/ 0x1 0x4
+ /*TXDE*/ 0x2 0x4
+ /*RXDE*/ 0x3 0x4
+ /*COAL TX0*/ 0x18 0x2
+ /*COAL TX1*/ 0x19 0x2
+ /*COAL TX2*/ 0x1a 0x2
+ /*COAL TX3*/ 0x1b 0x2
+ /*COAL RX0*/ 0x1c 0x2
+ /*COAL RX1*/ 0x1d 0x2
+ /*COAL RX2*/ 0x1e 0x2
+ /*COAL RX3*/ 0x1f 0x2>;
+ };
+
+ POB0: opb {
+ compatible = "ibm,opb-460sx", "ibm,opb";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>;
+ clock-frequency = <0>; /* Filled in by U-Boot */
+
+ EBC0: ebc {
+ compatible = "ibm,ebc-460sx", "ibm,ebc";
+ dcr-reg = <0x012 0x002>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clock-frequency = <0>; /* Filled in by U-Boot */
+ /* ranges property is supplied by U-Boot */
+ interrupts = <0x6 0x4>;
+ interrupt-parent = <&UIC1>;
+
+ nor_flash@0,0 {
+ compatible = "amd,s29gl512n", "cfi-flash";
+ bank-width = <2>;
+ reg = <0x0000000 0x00000000 0x04000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "kernel";
+ reg = <0x00000000 0x001e0000>;
+ };
+ partition@1e0000 {
+ label = "dtb";
+ reg = <0x001e0000 0x00020000>;
+ };
+ partition@200000 {
+ label = "ramdisk";
+ reg = <0x00200000 0x01400000>;
+ };
+ partition@1600000 {
+ label = "jffs2";
+ reg = <0x01600000 0x00400000>;
+ };
+ partition@1a00000 {
+ label = "user";
+ reg = <0x01a00000 0x02560000>;
+ };
+ partition@3f60000 {
+ label = "env";
+ reg = <0x03f60000 0x00040000>;
+ };
+ partition@3fa0000 {
+ label = "u-boot";
+ reg = <0x03fa0000 0x00060000>;
+ };
+ };
+ };
+
+ UART0: serial@ef600200 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0xef600200 0x00000008>;
+ virtual-reg = <0xef600200>;
+ clock-frequency = <0>; /* Filled in by U-Boot */
+ current-speed = <0>; /* Filled in by U-Boot */
+ interrupt-parent = <&UIC0>;
+ interrupts = <0x0 0x4>;
+ };
+
+ RGMII0: emac-rgmii@ef600900 {
+ compatible = "ibm,rgmii-460sx", "ibm,rgmii";
+ reg = <0xef600900 0x00000008>;
+ };
+
+ EMAC0: ethernet@ef600a00 {
+ device_type = "network";
+ compatible = "ibm,emac-460sx", "ibm,emac4";
+ interrupt-parent = <&EMAC0>;
+ interrupts = <0x0 0x1>;
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ #size-cells = <0>;
+ interrupt-map = </*Status*/ 0x0 &UIC0 0x13 0x4
+ /*Wake*/ 0x1 &UIC2 0x1d 0x4>;
+ reg = <0xef600a00 0x00000070>;
+ local-mac-address = [000000000000]; /* Filled in by U-Boot */
+ mal-device = <&MAL0>;
+ mal-tx-channel = <0>;
+ mal-rx-channel = <0>;
+ cell-index = <0>;
+ max-frame-size = <9000>;
+ rx-fifo-size = <4096>;
+ tx-fifo-size = <2048>;
+ phy-mode = "rgmii";
+ phy-map = <0x00000000>;
+ rgmii-device = <&RGMII0>;
+ rgmii-channel = <0>;
+ has-inverted-stacr-oc;
+ has-new-stacr-staopc;
+ };
+
+ };
+
+ };
+ chosen {
+ linux,stdout-path = "/plb/opb/serial@ef600200";
+ };
+
+};
diff --git a/arch/powerpc/boot/dts/sbc8349.dts b/arch/powerpc/boot/dts/sbc8349.dts
index 8d365a57ebc1..a36dbbc48694 100644
--- a/arch/powerpc/boot/dts/sbc8349.dts
+++ b/arch/powerpc/boot/dts/sbc8349.dts
@@ -159,68 +159,76 @@
phy_type = "ulpi";
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@19 {
- interrupt-parent = <&ipic>;
- interrupts = <20 0x8>;
- reg = <0x19>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1a {
- interrupt-parent = <&ipic>;
- interrupts = <21 0x8>;
- reg = <0x1a>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <32 0x8 33 0x8 34 0x8>;
interrupt-parent = <&ipic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
linux,network-index = <0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@19 {
+ interrupt-parent = <&ipic>;
+ interrupts = <20 0x8>;
+ reg = <0x19>;
+ device_type = "ethernet-phy";
+ };
+
+ phy1: ethernet-phy@1a {
+ interrupt-parent = <&ipic>;
+ interrupts = <21 0x8>;
+ reg = <0x1a>;
+ device_type = "ethernet-phy";
+ };
+
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 0x8 36 0x8 37 0x8>;
interrupt-parent = <&ipic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
linux,network-index = <1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/sbc8548.dts b/arch/powerpc/boot/dts/sbc8548.dts
index 2baf4a51f224..9c5079fec4f2 100644
--- a/arch/powerpc/boot/dts/sbc8548.dts
+++ b/arch/powerpc/boot/dts/sbc8548.dts
@@ -234,66 +234,72 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@19 {
- interrupt-parent = <&mpic>;
- interrupts = <0x6 0x1>;
- reg = <0x19>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1a {
- interrupt-parent = <&mpic>;
- interrupts = <0x7 0x1>;
- reg = <0x1a>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@19 {
+ interrupt-parent = <&mpic>;
+ interrupts = <0x6 0x1>;
+ reg = <0x19>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@1a {
+ interrupt-parent = <&mpic>;
+ interrupts = <0x7 0x1>;
+ reg = <0x1a>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <0x23 0x2 0x24 0x2 0x28 0x2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/sbc8560.dts b/arch/powerpc/boot/dts/sbc8560.dts
index 01542f7062ab..b772405a9a0a 100644
--- a/arch/powerpc/boot/dts/sbc8560.dts
+++ b/arch/powerpc/boot/dts/sbc8560.dts
@@ -139,77 +139,83 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
- phy0: ethernet-phy@19 {
- interrupt-parent = <&mpic>;
- interrupts = <0x6 0x1>;
- reg = <0x19>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@1a {
- interrupt-parent = <&mpic>;
- interrupts = <0x7 0x1>;
- reg = <0x1a>;
- device_type = "ethernet-phy";
- };
- phy2: ethernet-phy@1b {
- interrupt-parent = <&mpic>;
- interrupts = <0x8 0x1>;
- reg = <0x1b>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@1c {
- interrupt-parent = <&mpic>;
- interrupts = <0x8 0x1>;
- reg = <0x1c>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <0x1d 0x2 0x1e 0x2 0x22 0x2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+ phy0: ethernet-phy@19 {
+ interrupt-parent = <&mpic>;
+ interrupts = <0x6 0x1>;
+ reg = <0x19>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@1a {
+ interrupt-parent = <&mpic>;
+ interrupts = <0x7 0x1>;
+ reg = <0x1a>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@1b {
+ interrupt-parent = <&mpic>;
+ interrupts = <0x8 0x1>;
+ reg = <0x1b>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@1c {
+ interrupt-parent = <&mpic>;
+ interrupts = <0x8 0x1>;
+ reg = <0x1c>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <0x23 0x2 0x24 0x2 0x28 0x2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
mpic: pic@40000 {
diff --git a/arch/powerpc/boot/dts/sbc8641d.dts b/arch/powerpc/boot/dts/sbc8641d.dts
index 36db981548e4..e3e914e78caa 100644
--- a/arch/powerpc/boot/dts/sbc8641d.dts
+++ b/arch/powerpc/boot/dts/sbc8641d.dts
@@ -192,132 +192,144 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy0: ethernet-phy@1f {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0x1f>;
- device_type = "ethernet-phy";
- };
- phy1: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <0>;
- device_type = "ethernet-phy";
- };
- phy2: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <1>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <10 1>;
- reg = <2>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x26520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@27520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x27520 0x20>;
-
- tbi3: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy0>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@1f {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0x1f>;
+ device_type = "ethernet-phy";
+ };
+ phy1: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <0>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <10 1>;
+ reg = <2>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet2: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <2>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <31 2 32 2 33 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi2>;
phy-handle = <&phy2>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet3: ethernet@27000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <3>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x27000 0x1000>;
+ ranges = <0x0 0x27000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <37 2 38 2 39 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi3>;
phy-handle = <&phy3>;
phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/socrates.dts b/arch/powerpc/boot/dts/socrates.dts
new file mode 100644
index 000000000000..b8d0fc6f0042
--- /dev/null
+++ b/arch/powerpc/boot/dts/socrates.dts
@@ -0,0 +1,338 @@
+/*
+ * Device Tree Source for the Socrates board (MPC8544).
+ *
+ * Copyright (c) 2008 Emcraft Systems.
+ * Sergei Poselenov, <sposelenov@emcraft.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+ model = "abb,socrates";
+ compatible = "abb,socrates";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ ethernet0 = &enet0;
+ ethernet1 = &enet1;
+ serial0 = &serial0;
+ serial1 = &serial1;
+ pci0 = &pci0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,8544@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <32>;
+ i-cache-line-size = <32>;
+ d-cache-size = <0x8000>; // L1, 32K
+ i-cache-size = <0x8000>; // L1, 32K
+ timebase-frequency = <0>;
+ bus-frequency = <0>;
+ clock-frequency = <0>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x00000000>; // Filled in by U-Boot
+ };
+
+ soc8544@e0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ ranges = <0x00000000 0xe0000000 0x00100000>;
+ reg = <0xe0000000 0x00001000>; // CCSRBAR 1M
+ bus-frequency = <0>; // Filled in by U-Boot
+ compatible = "fsl,mpc8544-immr", "simple-bus";
+
+ memory-controller@2000 {
+ compatible = "fsl,mpc8544-memory-controller";
+ reg = <0x2000 0x1000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <18 2>;
+ };
+
+ L2: l2-cache-controller@20000 {
+ compatible = "fsl,mpc8544-l2-cache-controller";
+ reg = <0x20000 0x1000>;
+ cache-line-size = <32>;
+ cache-size = <0x40000>; // L2, 256K
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+
+ dtt@28 {
+ compatible = "winbond,w83782d";
+ reg = <0x28>;
+ };
+ rtc@32 {
+ compatible = "epson,rx8025";
+ reg = <0x32>;
+ interrupts = <7 1>;
+ interrupt-parent = <&mpic>;
+ };
+ dtt@4c {
+ compatible = "dallas,ds75";
+ reg = <0x4c>;
+ };
+ ts@4a {
+ compatible = "ti,tsc2003";
+ reg = <0x4a>;
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ };
+ };
+
+ i2c@3100 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <1>;
+ compatible = "fsl-i2c";
+ reg = <0x3100 0x100>;
+ interrupts = <43 2>;
+ interrupt-parent = <&mpic>;
+ dfsrr;
+ };
+
+ enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <0>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <29 2 30 2 34 2>;
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy0>;
+ tbi-handle = <&tbi0>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy0: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <0 1>;
+ reg = <0>;
+ };
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <0 1>;
+ reg = <1>;
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ };
+ };
+ };
+
+ enet1: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ cell-index = <1>;
+ device_type = "network";
+ model = "eTSEC";
+ compatible = "gianfar";
+ reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ interrupts = <31 2 32 2 33 2>;
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy1>;
+ tbi-handle = <&tbi1>;
+ phy-connection-type = "rgmii-id";
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ };
+ };
+ };
+
+ serial0: serial@4500 {
+ cell-index = <0>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4500 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ serial1: serial@4600 {
+ cell-index = <1>;
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <0x4600 0x100>;
+ clock-frequency = <0>;
+ interrupts = <42 2>;
+ interrupt-parent = <&mpic>;
+ };
+
+ global-utilities@e0000 { //global utilities block
+ compatible = "fsl,mpc8548-guts";
+ reg = <0xe0000 0x1000>;
+ fsl,has-rstcr;
+ };
+
+ mpic: pic@40000 {
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x40000 0x40000>;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ };
+ };
+
+
+ localbus {
+ compatible = "fsl,mpc8544-localbus",
+ "fsl,pq3-localbus",
+ "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ reg = <0xe0005000 0x40>;
+
+ ranges = <0 0 0xfc000000 0x04000000
+ 2 0 0xc8000000 0x04000000
+ 3 0 0xc0000000 0x00100000
+ >; /* Overwritten by U-Boot */
+
+ nor_flash@0,0 {
+ compatible = "amd,s29gl256n", "cfi-flash";
+ bank-width = <2>;
+ reg = <0x0 0x000000 0x4000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@0 {
+ label = "kernel";
+ reg = <0x0 0x1e0000>;
+ read-only;
+ };
+ partition@1e0000 {
+ label = "dtb";
+ reg = <0x1e0000 0x20000>;
+ };
+ partition@200000 {
+ label = "root";
+ reg = <0x200000 0x200000>;
+ };
+ partition@400000 {
+ label = "user";
+ reg = <0x400000 0x3b80000>;
+ };
+ partition@3f80000 {
+ label = "env";
+ reg = <0x3f80000 0x40000>;
+ read-only;
+ };
+ partition@3fc0000 {
+ label = "u-boot";
+ reg = <0x3fc0000 0x40000>;
+ read-only;
+ };
+ };
+
+ display@2,0 {
+ compatible = "fujitsu,lime";
+ reg = <2 0x0 0x4000000>;
+ interrupt-parent = <&mpic>;
+ interrupts = <6 1>;
+ };
+
+ fpga_pic: fpga-pic@3,10 {
+ compatible = "abb,socrates-fpga-pic";
+ reg = <3 0x10 0x10>;
+ interrupt-controller;
+ /* IRQs 2, 10, 11, active low, level-sensitive */
+ interrupts = <2 1 10 1 11 1>;
+ interrupt-parent = <&mpic>;
+ #interrupt-cells = <3>;
+ };
+
+ spi@3,60 {
+ compatible = "abb,socrates-spi";
+ reg = <3 0x60 0x10>;
+ interrupts = <8 4 0>; // number, type, routing
+ interrupt-parent = <&fpga_pic>;
+ };
+
+ nand@3,70 {
+ compatible = "abb,socrates-nand";
+ reg = <3 0x70 0x04>;
+ bank-width = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ data@0 {
+ label = "data";
+ reg = <0x0 0x40000000>;
+ };
+ };
+
+ can@3,100 {
+ compatible = "philips,sja1000";
+ reg = <3 0x100 0x80>;
+ interrupts = <2 8 1>; // number, type, routing
+ interrupt-parent = <&fpga_pic>;
+ };
+ };
+
+ pci0: pci@e0008000 {
+ cell-index = <0>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ compatible = "fsl,mpc8540-pci";
+ device_type = "pci";
+ reg = <0xe0008000 0x1000>;
+ clock-frequency = <66666666>;
+
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x11 */
+ 0x8800 0x0 0x0 1 &mpic 5 1
+ /* IDSEL 0x12 */
+ 0x9000 0x0 0x0 1 &mpic 4 1>;
+ interrupt-parent = <&mpic>;
+ interrupts = <24 2>;
+ bus-range = <0x0 0x0>;
+ ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000
+ 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x01000000>;
+ };
+
+};
diff --git a/arch/powerpc/boot/dts/stx_gp3_8560.dts b/arch/powerpc/boot/dts/stx_gp3_8560.dts
index fff33fe6efc6..8b173957fb5f 100644
--- a/arch/powerpc/boot/dts/stx_gp3_8560.dts
+++ b/arch/powerpc/boot/dts/stx_gp3_8560.dts
@@ -124,66 +124,72 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <5 4>;
- reg = <2>;
- device_type = "ethernet-phy";
- };
- phy4: ethernet-phy@4 {
- interrupt-parent = <&mpic>;
- interrupts = <5 4>;
- reg = <4>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy2>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 4>;
+ reg = <2>;
+ device_type = "ethernet-phy";
+ };
+ phy4: ethernet-phy@4 {
+ interrupt-parent = <&mpic>;
+ interrupts = <5 4>;
+ reg = <4>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy4>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
mpic: pic@40000 {
diff --git a/arch/powerpc/boot/dts/tqm5200.dts b/arch/powerpc/boot/dts/tqm5200.dts
index 906302e26a62..c9590b58b7b0 100644
--- a/arch/powerpc/boot/dts/tqm5200.dts
+++ b/arch/powerpc/boot/dts/tqm5200.dts
@@ -17,6 +17,7 @@
compatible = "tqc,tqm5200";
#address-cells = <1>;
#size-cells = <1>;
+ interrupt-parent = <&mpc5200_pic>;
cpus {
#address-cells = <1>;
@@ -66,36 +67,33 @@
compatible = "fsl,mpc5200-gpt";
reg = <0x600 0x10>;
interrupts = <1 9 0>;
- interrupt-parent = <&mpc5200_pic>;
fsl,has-wdt;
};
can@900 {
compatible = "fsl,mpc5200-mscan";
interrupts = <2 17 0>;
- interrupt-parent = <&mpc5200_pic>;
reg = <0x900 0x80>;
};
can@980 {
compatible = "fsl,mpc5200-mscan";
interrupts = <2 18 0>;
- interrupt-parent = <&mpc5200_pic>;
reg = <0x980 0x80>;
};
- gpio@b00 {
+ gpio_simple: gpio@b00 {
compatible = "fsl,mpc5200-gpio";
reg = <0xb00 0x40>;
interrupts = <1 7 0>;
- interrupt-parent = <&mpc5200_pic>;
+ gpio-controller;
+ #gpio-cells = <2>;
};
usb@1000 {
compatible = "fsl,mpc5200-ohci","ohci-be";
reg = <0x1000 0xff>;
interrupts = <2 6 0>;
- interrupt-parent = <&mpc5200_pic>;
};
dma-controller@1200 {
@@ -105,7 +103,6 @@
3 4 0 3 5 0 3 6 0 3 7 0
3 8 0 3 9 0 3 10 0 3 11 0
3 12 0 3 13 0 3 14 0 3 15 0>;
- interrupt-parent = <&mpc5200_pic>;
};
xlb@1f00 {
@@ -114,39 +111,28 @@
};
serial@2000 { // PSC1
- device_type = "serial";
compatible = "fsl,mpc5200-psc-uart";
- port-number = <0>; // Logical port assignment
reg = <0x2000 0x100>;
interrupts = <2 1 0>;
- interrupt-parent = <&mpc5200_pic>;
};
serial@2200 { // PSC2
- device_type = "serial";
compatible = "fsl,mpc5200-psc-uart";
- port-number = <1>; // Logical port assignment
reg = <0x2200 0x100>;
interrupts = <2 2 0>;
- interrupt-parent = <&mpc5200_pic>;
};
serial@2400 { // PSC3
- device_type = "serial";
compatible = "fsl,mpc5200-psc-uart";
- port-number = <2>; // Logical port assignment
reg = <0x2400 0x100>;
interrupts = <2 3 0>;
- interrupt-parent = <&mpc5200_pic>;
};
ethernet@3000 {
- device_type = "network";
compatible = "fsl,mpc5200-fec";
reg = <0x3000 0x400>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <2 5 0>;
- interrupt-parent = <&mpc5200_pic>;
phy-handle = <&phy0>;
};
@@ -156,10 +142,8 @@
compatible = "fsl,mpc5200-mdio";
reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts
interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co.
- interrupt-parent = <&mpc5200_pic>;
phy0: ethernet-phy@0 {
- device_type = "ethernet-phy";
reg = <0>;
};
};
@@ -168,7 +152,6 @@
compatible = "fsl,mpc5200-ata";
reg = <0x3a00 0x100>;
interrupts = <2 7 0>;
- interrupt-parent = <&mpc5200_pic>;
};
i2c@3d40 {
@@ -177,7 +160,6 @@
compatible = "fsl,mpc5200-i2c","fsl-i2c";
reg = <0x3d40 0x40>;
interrupts = <2 16 0>;
- interrupt-parent = <&mpc5200_pic>;
fsl5200-clocking;
rtc@68 {
@@ -192,9 +174,8 @@
};
};
- lpb {
- model = "fsl,lpb";
- compatible = "fsl,lpb";
+ localbus {
+ compatible = "fsl,mpc5200-lpb","simple-bus";
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0 0xfc000000 0x02000000>;
@@ -223,7 +204,6 @@
0xc000 0 0 4 &mpc5200_pic 0 0 3>;
clock-frequency = <0>; // From boot loader
interrupts = <2 8 0 2 9 0 2 10 0>;
- interrupt-parent = <&mpc5200_pic>;
bus-range = <0 0>;
ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000
0x02000000 0 0x90000000 0x90000000 0 0x10000000
diff --git a/arch/powerpc/boot/dts/tqm8540.dts b/arch/powerpc/boot/dts/tqm8540.dts
index a693f01c21aa..ac9413a29f9f 100644
--- a/arch/powerpc/boot/dts/tqm8540.dts
+++ b/arch/powerpc/boot/dts/tqm8540.dts
@@ -84,6 +84,11 @@
interrupt-parent = <&mpic>;
dfsrr;
+ dtt@50 {
+ compatible = "national,lm75";
+ reg = <0x50>;
+ };
+
rtc@68 {
compatible = "dallas,ds1337";
reg = <0x68>;
@@ -131,94 +136,103 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <1>;
- device_type = "ethernet-phy";
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <2>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <3>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x26520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
phy-handle = <&phy2>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <2>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <3>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet2: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <2>;
device_type = "network";
model = "FEC";
compatible = "gianfar";
reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <41 2>;
interrupt-parent = <&mpic>;
phy-handle = <&phy3>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/tqm8541.dts b/arch/powerpc/boot/dts/tqm8541.dts
index 9e3f5f0dde20..c71bb5dd5e5e 100644
--- a/arch/powerpc/boot/dts/tqm8541.dts
+++ b/arch/powerpc/boot/dts/tqm8541.dts
@@ -83,6 +83,11 @@
interrupt-parent = <&mpic>;
dfsrr;
+ dtt@50 {
+ compatible = "national,lm75";
+ reg = <0x50>;
+ };
+
rtc@68 {
compatible = "dallas,ds1337";
reg = <0x68>;
@@ -130,72 +135,78 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <1>;
- device_type = "ethernet-phy";
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <2>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <3>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy2>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <2>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <3>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/tqm8548-bigflash.dts b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
index 15086eb65c50..19aa72301c83 100644
--- a/arch/powerpc/boot/dts/tqm8548-bigflash.dts
+++ b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
@@ -85,6 +85,11 @@
interrupt-parent = <&mpic>;
dfsrr;
+ dtt@50 {
+ compatible = "national,lm75";
+ reg = <0x50>;
+ };
+
rtc@68 {
compatible = "dallas,ds1337";
reg = <0x68>;
@@ -143,134 +148,146 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy1: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <1>;
- device_type = "ethernet-phy";
- };
- phy2: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <2>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <3>;
- device_type = "ethernet-phy";
- };
- phy4: ethernet-phy@4 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <4>;
- device_type = "ethernet-phy";
- };
- phy5: ethernet-phy@5 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <5>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x26520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@27520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x27520 0x20>;
-
- tbi3: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy2>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy1: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <2>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <3>;
+ device_type = "ethernet-phy";
+ };
+ phy4: ethernet-phy@4 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <4>;
+ device_type = "ethernet-phy";
+ };
+ phy5: ethernet-phy@5 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <5>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet2: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <2>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <31 2 32 2 33 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi2>;
phy-handle = <&phy3>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet3: ethernet@27000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <3>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x27000 0x1000>;
+ ranges = <0x0 0x27000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <37 2 38 2 39 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi3>;
phy-handle = <&phy4>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
@@ -365,14 +382,14 @@
can0@2,0 {
compatible = "intel,82527"; // Bosch CC770
reg = <2 0x0 0x100>;
- interrupts = <4 0>;
+ interrupts = <4 1>;
interrupt-parent = <&mpic>;
};
can1@2,100 {
compatible = "intel,82527"; // Bosch CC770
reg = <2 0x100 0x100>;
- interrupts = <4 0>;
+ interrupts = <4 1>;
interrupt-parent = <&mpic>;
};
@@ -380,10 +397,13 @@
upm@3,0 {
#address-cells = <0>;
#size-cells = <0>;
- compatible = "fsl,upm-nand";
+ compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
reg = <3 0x0 0x800>;
fsl,upm-addr-offset = <0x10>;
fsl,upm-cmd-offset = <0x08>;
+ /* Micron MT29F8G08FAB multi-chip device */
+ fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
+ fsl,upm-wait-flags = <0x5>;
chip-delay = <25>; // in micro-seconds
nand@0 {
@@ -392,7 +412,7 @@
partition@0 {
label = "fs";
- reg = <0x00000000 0x01000000>;
+ reg = <0x00000000 0x10000000>;
};
};
};
diff --git a/arch/powerpc/boot/dts/tqm8548.dts b/arch/powerpc/boot/dts/tqm8548.dts
index b7b65f5e79b6..49145a04fc6c 100644
--- a/arch/powerpc/boot/dts/tqm8548.dts
+++ b/arch/powerpc/boot/dts/tqm8548.dts
@@ -85,6 +85,11 @@
interrupt-parent = <&mpic>;
dfsrr;
+ dtt@50 {
+ compatible = "national,lm75";
+ reg = <0x50>;
+ };
+
rtc@68 {
compatible = "dallas,ds1337";
reg = <0x68>;
@@ -143,134 +148,146 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy1: ethernet-phy@0 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <1>;
- device_type = "ethernet-phy";
- };
- phy2: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <2>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <3>;
- device_type = "ethernet-phy";
- };
- phy4: ethernet-phy@4 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <4>;
- device_type = "ethernet-phy";
- };
- phy5: ethernet-phy@5 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <5>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@26520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x26520 0x20>;
-
- tbi2: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@27520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x27520 0x20>;
-
- tbi3: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy2>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy1: ethernet-phy@0 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <2>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <3>;
+ device_type = "ethernet-phy";
+ };
+ phy4: ethernet-phy@4 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <4>;
+ device_type = "ethernet-phy";
+ };
+ phy5: ethernet-phy@5 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <5>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet2: ethernet@26000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <2>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x26000 0x1000>;
+ ranges = <0x0 0x26000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <31 2 32 2 33 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi2>;
phy-handle = <&phy3>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi2: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet3: ethernet@27000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <3>;
device_type = "network";
model = "eTSEC";
compatible = "gianfar";
reg = <0x27000 0x1000>;
+ ranges = <0x0 0x27000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <37 2 38 2 39 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi3>;
phy-handle = <&phy4>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi3: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
@@ -365,14 +382,14 @@
can0@2,0 {
compatible = "intel,82527"; // Bosch CC770
reg = <2 0x0 0x100>;
- interrupts = <4 0>;
+ interrupts = <4 1>;
interrupt-parent = <&mpic>;
};
can1@2,100 {
compatible = "intel,82527"; // Bosch CC770
reg = <2 0x100 0x100>;
- interrupts = <4 0>;
+ interrupts = <4 1>;
interrupt-parent = <&mpic>;
};
@@ -380,10 +397,13 @@
upm@3,0 {
#address-cells = <0>;
#size-cells = <0>;
- compatible = "fsl,upm-nand";
+ compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
reg = <3 0x0 0x800>;
fsl,upm-addr-offset = <0x10>;
fsl,upm-cmd-offset = <0x08>;
+ /* Micron MT29F8G08FAB multi-chip device */
+ fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
+ fsl,upm-wait-flags = <0x5>;
chip-delay = <25>; // in micro-seconds
nand@0 {
@@ -392,7 +412,7 @@
partition@0 {
label = "fs";
- reg = <0x00000000 0x01000000>;
+ reg = <0x00000000 0x10000000>;
};
};
};
diff --git a/arch/powerpc/boot/dts/tqm8555.dts b/arch/powerpc/boot/dts/tqm8555.dts
index cf92b4e7945e..a133ded6dddb 100644
--- a/arch/powerpc/boot/dts/tqm8555.dts
+++ b/arch/powerpc/boot/dts/tqm8555.dts
@@ -83,6 +83,11 @@
interrupt-parent = <&mpic>;
dfsrr;
+ dtt@50 {
+ compatible = "national,lm75";
+ reg = <0x50>;
+ };
+
rtc@68 {
compatible = "dallas,ds1337";
reg = <0x68>;
@@ -130,72 +135,78 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <1>;
- device_type = "ethernet-phy";
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <2>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <3>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy2>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <2>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <3>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
serial0: serial@4500 {
diff --git a/arch/powerpc/boot/dts/tqm8560.dts b/arch/powerpc/boot/dts/tqm8560.dts
index 9e1ab2d2f669..649e2e576267 100644
--- a/arch/powerpc/boot/dts/tqm8560.dts
+++ b/arch/powerpc/boot/dts/tqm8560.dts
@@ -85,6 +85,11 @@
interrupt-parent = <&mpic>;
dfsrr;
+ dtt@50 {
+ compatible = "national,lm75";
+ reg = <0x50>;
+ };
+
rtc@68 {
compatible = "dallas,ds1337";
reg = <0x68>;
@@ -132,72 +137,78 @@
};
};
- mdio@24520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
-
- phy1: ethernet-phy@1 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <1>;
- device_type = "ethernet-phy";
- };
- phy2: ethernet-phy@2 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <2>;
- device_type = "ethernet-phy";
- };
- phy3: ethernet-phy@3 {
- interrupt-parent = <&mpic>;
- interrupts = <8 1>;
- reg = <3>;
- device_type = "ethernet-phy";
- };
- tbi0: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
- mdio@25520 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-tbi";
- reg = <0x25520 0x20>;
-
- tbi1: tbi-phy@11 {
- reg = <0x11>;
- device_type = "tbi-phy";
- };
- };
-
enet0: ethernet@24000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x24000 0x1000>;
+ ranges = <0x0 0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <29 2 30 2 34 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi0>;
phy-handle = <&phy2>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x520 0x20>;
+
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+ phy2: ethernet-phy@2 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <2>;
+ device_type = "ethernet-phy";
+ };
+ phy3: ethernet-phy@3 {
+ interrupt-parent = <&mpic>;
+ interrupts = <8 1>;
+ reg = <3>;
+ device_type = "ethernet-phy";
+ };
+ tbi0: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
enet1: ethernet@25000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
cell-index = <1>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <0x25000 0x1000>;
+ ranges = <0x0 0x25000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <35 2 36 2 40 2>;
interrupt-parent = <&mpic>;
tbi-handle = <&tbi1>;
phy-handle = <&phy1>;
+
+ mdio@520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-tbi";
+ reg = <0x520 0x20>;
+
+ tbi1: tbi-phy@11 {
+ reg = <0x11>;
+ device_type = "tbi-phy";
+ };
+ };
};
mpic: pic@40000 {
@@ -335,14 +346,14 @@
can0@2,0 {
compatible = "intel,82527"; // Bosch CC770
reg = <2 0x0 0x100>;
- interrupts = <4 0>;
+ interrupts = <4 1>;
interrupt-parent = <&mpic>;
};
can1@2,100 {
compatible = "intel,82527"; // Bosch CC770
reg = <2 0x100 0x100>;
- interrupts = <4 0>;
+ interrupts = <4 1>;
interrupt-parent = <&mpic>;
};
};
diff --git a/arch/powerpc/boot/dts/virtex440-ml507.dts b/arch/powerpc/boot/dts/virtex440-ml507.dts
index dc8e78e2dceb..52d8c1ad26a1 100644
--- a/arch/powerpc/boot/dts/virtex440-ml507.dts
+++ b/arch/powerpc/boot/dts/virtex440-ml507.dts
@@ -7,6 +7,15 @@
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
+ *
+ * ---
+ *
+ * Device Tree Generator version: 1.1
+ *
+ * CAUTION: This file is automatically generated by libgen.
+ * Version: Xilinx EDK 10.1.03 EDK_K_SP3.6
+ *
+ * XPS project directory: ml507_ppc440_emb_ref
*/
/dts-v1/;
@@ -22,8 +31,8 @@
reg = < 0 0x10000000 >;
} ;
chosen {
- bootargs = "console=ttyS0 ip=on root=/dev/ram";
- linux,stdout-path = "/plb@0/serial@83e00000";
+ bootargs = "console=ttyS0 root=/dev/ram";
+ linux,stdout-path = &RS232_Uart_1;
} ;
cpus {
#address-cells = <1>;
@@ -136,19 +145,19 @@
compatible = "xlnx,ll-dma-1.00.a";
dcr-reg = < 0x80 0x11 >;
interrupt-parent = <&xps_intc_0>;
- interrupts = < 9 2 0xa 2 >;
+ interrupts = < 10 2 11 2 >;
} ;
} ;
} ;
plb_v46_0: plb@0 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "xlnx,plb-v46-1.02.a", "simple-bus";
+ compatible = "xlnx,plb-v46-1.03.a", "simple-bus";
ranges ;
DIP_Switches_8Bit: gpio@81460000 {
compatible = "xlnx,xps-gpio-1.00.a";
interrupt-parent = <&xps_intc_0>;
- interrupts = < 6 2 >;
+ interrupts = < 7 2 >;
reg = < 0x81460000 0x10000 >;
xlnx,all-inputs = <1>;
xlnx,all-inputs-2 = <0>;
@@ -163,6 +172,86 @@
xlnx,tri-default = <0xffffffff>;
xlnx,tri-default-2 = <0xffffffff>;
} ;
+ FLASH: flash@fc000000 {
+ bank-width = <2>;
+ compatible = "xlnx,xps-mch-emc-2.00.a", "cfi-flash";
+ reg = < 0xfc000000 0x2000000 >;
+ xlnx,family = "virtex5";
+ xlnx,include-datawidth-matching-0 = <0x1>;
+ xlnx,include-datawidth-matching-1 = <0x0>;
+ xlnx,include-datawidth-matching-2 = <0x0>;
+ xlnx,include-datawidth-matching-3 = <0x0>;
+ xlnx,include-negedge-ioregs = <0x0>;
+ xlnx,include-plb-ipif = <0x1>;
+ xlnx,include-wrbuf = <0x1>;
+ xlnx,max-mem-width = <0x10>;
+ xlnx,mch-native-dwidth = <0x20>;
+ xlnx,mch-plb-clk-period-ps = <0x2710>;
+ xlnx,mch-splb-awidth = <0x20>;
+ xlnx,mch0-accessbuf-depth = <0x10>;
+ xlnx,mch0-protocol = <0x0>;
+ xlnx,mch0-rddatabuf-depth = <0x10>;
+ xlnx,mch1-accessbuf-depth = <0x10>;
+ xlnx,mch1-protocol = <0x0>;
+ xlnx,mch1-rddatabuf-depth = <0x10>;
+ xlnx,mch2-accessbuf-depth = <0x10>;
+ xlnx,mch2-protocol = <0x0>;
+ xlnx,mch2-rddatabuf-depth = <0x10>;
+ xlnx,mch3-accessbuf-depth = <0x10>;
+ xlnx,mch3-protocol = <0x0>;
+ xlnx,mch3-rddatabuf-depth = <0x10>;
+ xlnx,mem0-width = <0x10>;
+ xlnx,mem1-width = <0x20>;
+ xlnx,mem2-width = <0x20>;
+ xlnx,mem3-width = <0x20>;
+ xlnx,num-banks-mem = <0x1>;
+ xlnx,num-channels = <0x2>;
+ xlnx,priority-mode = <0x0>;
+ xlnx,synch-mem-0 = <0x0>;
+ xlnx,synch-mem-1 = <0x0>;
+ xlnx,synch-mem-2 = <0x0>;
+ xlnx,synch-mem-3 = <0x0>;
+ xlnx,synch-pipedelay-0 = <0x2>;
+ xlnx,synch-pipedelay-1 = <0x2>;
+ xlnx,synch-pipedelay-2 = <0x2>;
+ xlnx,synch-pipedelay-3 = <0x2>;
+ xlnx,tavdv-ps-mem-0 = <0x1adb0>;
+ xlnx,tavdv-ps-mem-1 = <0x3a98>;
+ xlnx,tavdv-ps-mem-2 = <0x3a98>;
+ xlnx,tavdv-ps-mem-3 = <0x3a98>;
+ xlnx,tcedv-ps-mem-0 = <0x1adb0>;
+ xlnx,tcedv-ps-mem-1 = <0x3a98>;
+ xlnx,tcedv-ps-mem-2 = <0x3a98>;
+ xlnx,tcedv-ps-mem-3 = <0x3a98>;
+ xlnx,thzce-ps-mem-0 = <0x88b8>;
+ xlnx,thzce-ps-mem-1 = <0x1b58>;
+ xlnx,thzce-ps-mem-2 = <0x1b58>;
+ xlnx,thzce-ps-mem-3 = <0x1b58>;
+ xlnx,thzoe-ps-mem-0 = <0x1b58>;
+ xlnx,thzoe-ps-mem-1 = <0x1b58>;
+ xlnx,thzoe-ps-mem-2 = <0x1b58>;
+ xlnx,thzoe-ps-mem-3 = <0x1b58>;
+ xlnx,tlzwe-ps-mem-0 = <0x88b8>;
+ xlnx,tlzwe-ps-mem-1 = <0x0>;
+ xlnx,tlzwe-ps-mem-2 = <0x0>;
+ xlnx,tlzwe-ps-mem-3 = <0x0>;
+ xlnx,twc-ps-mem-0 = <0x2af8>;
+ xlnx,twc-ps-mem-1 = <0x3a98>;
+ xlnx,twc-ps-mem-2 = <0x3a98>;
+ xlnx,twc-ps-mem-3 = <0x3a98>;
+ xlnx,twp-ps-mem-0 = <0x11170>;
+ xlnx,twp-ps-mem-1 = <0x2ee0>;
+ xlnx,twp-ps-mem-2 = <0x2ee0>;
+ xlnx,twp-ps-mem-3 = <0x2ee0>;
+ xlnx,xcl0-linesize = <0x4>;
+ xlnx,xcl0-writexfer = <0x1>;
+ xlnx,xcl1-linesize = <0x4>;
+ xlnx,xcl1-writexfer = <0x1>;
+ xlnx,xcl2-linesize = <0x4>;
+ xlnx,xcl2-writexfer = <0x1>;
+ xlnx,xcl3-linesize = <0x4>;
+ xlnx,xcl3-writexfer = <0x1>;
+ } ;
Hard_Ethernet_MAC: xps-ll-temac@81c00000 {
#address-cells = <1>;
#size-cells = <1>;
@@ -185,6 +274,19 @@
xlnx,txfifo = <0x1000>;
} ;
} ;
+ IIC_EEPROM: i2c@81600000 {
+ compatible = "xlnx,xps-iic-2.00.a";
+ interrupt-parent = <&xps_intc_0>;
+ interrupts = < 6 2 >;
+ reg = < 0x81600000 0x10000 >;
+ xlnx,clk-freq = <0x5f5e100>;
+ xlnx,family = "virtex5";
+ xlnx,gpo-width = <0x1>;
+ xlnx,iic-freq = <0x186a0>;
+ xlnx,scl-inertial-delay = <0x0>;
+ xlnx,sda-inertial-delay = <0x0>;
+ xlnx,ten-bit-adr = <0x0>;
+ } ;
LEDs_8Bit: gpio@81400000 {
compatible = "xlnx,xps-gpio-1.00.a";
reg = < 0x81400000 0x10000 >;
@@ -220,7 +322,7 @@
Push_Buttons_5Bit: gpio@81440000 {
compatible = "xlnx,xps-gpio-1.00.a";
interrupt-parent = <&xps_intc_0>;
- interrupts = < 7 2 >;
+ interrupts = < 8 2 >;
reg = < 0x81440000 0x10000 >;
xlnx,all-inputs = <1>;
xlnx,all-inputs-2 = <0>;
@@ -237,13 +339,13 @@
} ;
RS232_Uart_1: serial@83e00000 {
clock-frequency = <100000000>;
- compatible = "xlnx,xps-uart16550-2.00.a", "ns16550";
- current-speed = <0x2580>;
+ compatible = "xlnx,xps-uart16550-2.00.b", "ns16550";
+ current-speed = <9600>;
device_type = "serial";
interrupt-parent = <&xps_intc_0>;
- interrupts = < 8 2 >;
+ interrupts = < 9 2 >;
reg = < 0x83e00000 0x10000 >;
- reg-offset = <3>;
+ reg-offset = <0x1003>;
reg-shift = <2>;
xlnx,family = "virtex5";
xlnx,has-external-rclk = <0>;
@@ -268,7 +370,7 @@
compatible = "xlnx,xps-intc-1.00.a";
interrupt-controller ;
reg = < 0x81800000 0x10000 >;
- xlnx,num-intr-inputs = <0xb>;
+ xlnx,num-intr-inputs = <0xc>;
} ;
xps_timebase_wdt_1: xps-timebase-wdt@83a00000 {
compatible = "xlnx,xps-timebase-wdt-1.00.b";
diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c
index 8b3607cb53fb..f2156f07571f 100644
--- a/arch/powerpc/boot/serial.c
+++ b/arch/powerpc/boot/serial.c
@@ -117,7 +117,8 @@ int serial_console_init(void)
if (devp == NULL)
goto err_out;
- if (dt_is_compatible(devp, "ns16550"))
+ if (dt_is_compatible(devp, "ns16550") ||
+ dt_is_compatible(devp, "pnpPNP,501"))
rc = ns16550_console_init(devp, &serial_cd);
else if (dt_is_compatible(devp, "marvell,mv64360-mpsc"))
rc = mpsc_console_init(devp, &serial_cd);
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index 965c237c122d..3ac75aecdb94 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -186,6 +186,9 @@ cuboot*)
*-mpc85*|*-tqm85*|*-sbc85*)
platformo=$object/cuboot-85xx.o
;;
+ *-amigaone)
+ link_address='0x800000'
+ ;;
esac
;;
ps3)
@@ -211,11 +214,11 @@ simpleboot-virtex405-*)
binary=y
;;
simpleboot-virtex440-*)
- platformo="$object/simpleboot.o $object/virtex.o"
+ platformo="$object/fixed-head.o $object/simpleboot.o $object/virtex.o"
binary=y
;;
simpleboot-*)
- platformo="$object/simpleboot.o"
+ platformo="$object/fixed-head.o $object/simpleboot.o"
binary=y
;;
asp834x-redboot)
diff --git a/arch/powerpc/configs/44x/canyonlands_defconfig b/arch/powerpc/configs/44x/canyonlands_defconfig
index 81cdcc4b9278..f9a08ee49b96 100644
--- a/arch/powerpc/configs/44x/canyonlands_defconfig
+++ b/arch/powerpc/configs/44x/canyonlands_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:22:35 2009
+# Linux kernel version: 2.6.29-rc3
+# Mon Feb 2 13:13:04 2009
#
# CONFIG_PPC64 is not set
@@ -74,6 +74,15 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_GROUP_SCHED is not set
@@ -147,11 +156,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
CONFIG_PPC4xx_PCI_EXPRESS=y
@@ -373,6 +377,7 @@ CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y
# CONFIG_MTD is not set
CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
@@ -384,6 +389,7 @@ CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=35000
@@ -466,6 +472,15 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -533,13 +548,136 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_DEVPORT=y
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_IBM_IIC=y
+# CONFIG_I2C_MPC is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SPI is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+CONFIG_SENSORS_AD7414=y
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
@@ -556,7 +694,12 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -574,6 +717,7 @@ CONFIG_SSB_POSSIBLE=y
# Multimedia drivers
#
CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
#
# Graphics support
@@ -590,7 +734,109 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
#
# CONFIG_DISPLAY_SUPPORT is not set
# CONFIG_SOUND is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_HCD_PPC_OF=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PPC_OF=y
+CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
+CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
+CONFIG_USB_OHCI_HCD_PCI=y
+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
diff --git a/arch/powerpc/configs/44x/redwood_defconfig b/arch/powerpc/configs/44x/redwood_defconfig
new file mode 100644
index 000000000000..e665433762ba
--- /dev/null
+++ b/arch/powerpc/configs/44x/redwood_defconfig
@@ -0,0 +1,1176 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc3
+# Wed Feb 4 14:31:09 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_6xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+CONFIG_44x=y
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+CONFIG_4xx=y
+CONFIG_BOOKE=y
+CONFIG_PTE_64BIT=y
+CONFIG_PHYS_64BIT=y
+CONFIG_PPC_MMU_NOHASH=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_PPC_DCR_NATIVE=y
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_PPC_DCR=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_FREEZER is not set
+CONFIG_PPC4xx_PCI_EXPRESS=y
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_BAMBOO is not set
+# CONFIG_EBONY is not set
+# CONFIG_SAM440EP is not set
+# CONFIG_SEQUOIA is not set
+# CONFIG_TAISHAN is not set
+# CONFIG_KATMAI is not set
+# CONFIG_RAINIER is not set
+# CONFIG_WARP is not set
+# CONFIG_ARCHES is not set
+# CONFIG_CANYONLANDS is not set
+# CONFIG_GLACIER is not set
+CONFIG_REDWOOD=y
+# CONFIG_YOSEMITE is not set
+# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
+CONFIG_PPC44x_SIMPLE=y
+# CONFIG_PPC4xx_GPIO is not set
+CONFIG_460SX=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
+CONFIG_EXTRA_TARGETS=""
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_4xx_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+# CONFIG_PCIEASPM is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=35000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_XILINX_SYSACE is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_SAS_ATTRS=y
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_FUSION=y
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+CONFIG_FUSION_SAS=y
+CONFIG_FUSION_MAX_SGE=128
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LOGGING is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+CONFIG_I2O=y
+CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y
+CONFIG_I2O_EXT_ADAPTEC=y
+# CONFIG_I2O_CONFIG is not set
+# CONFIG_I2O_BUS is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=256
+CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+CONFIG_IBM_NEW_EMAC_DEBUG=y
+CONFIG_IBM_NEW_EMAC_ZMII=y
+CONFIG_IBM_NEW_EMAC_RGMII=y
+CONFIG_IBM_NEW_EMAC_TAH=y
+CONFIG_IBM_NEW_EMAC_EMAC4=y
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+CONFIG_E1000E=y
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_JME is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_IBM_IIC=y
+# CONFIG_I2C_MPC is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+CONFIG_I2C_DEBUG_CHIP=y
+# CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=y
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_SEQIV=y
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_CTS=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_XTS=y
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=y
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/powerpc/configs/85xx/socrates_defconfig b/arch/powerpc/configs/85xx/socrates_defconfig
new file mode 100644
index 000000000000..0cc9048290a8
--- /dev/null
+++ b/arch/powerpc/configs/85xx/socrates_defconfig
@@ -0,0 +1,1410 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.26.2
+# Sat Oct 18 11:06:13 2008
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_6xx is not set
+CONFIG_PPC_85xx=y
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_E500=y
+CONFIG_BOOKE=y
+CONFIG_FSL_BOOKE=y
+CONFIG_FSL_EMB_PERFMON=y
+# CONFIG_PHYS_64BIT is not set
+CONFIG_SPE=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+# CONFIG_EPOLL is not set
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+
+#
+# Platform support
+#
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+CONFIG_MPC85xx=y
+# CONFIG_MPC8540_ADS is not set
+# CONFIG_MPC8560_ADS is not set
+# CONFIG_MPC85xx_CDS is not set
+# CONFIG_MPC85xx_MDS is not set
+# CONFIG_MPC85xx_DS is not set
+CONFIG_SOCRATES=y
+# CONFIG_KSI8560 is not set
+# CONFIG_STX_GP3 is not set
+# CONFIG_TQM8540 is not set
+# CONFIG_TQM8541 is not set
+# CONFIG_TQM8555 is not set
+# CONFIG_TQM8560 is not set
+# CONFIG_SBC8548 is not set
+# CONFIG_SBC8560 is not set
+# CONFIG_IPIC is not set
+CONFIG_MPIC=y
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPM2 is not set
+# CONFIG_FSL_ULI1575 is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_MATH_EMULATION=y
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_FSL_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_PHYSICAL_ALIGN=0x10000000
+CONFIG_TASK_SIZE=0xc0000000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+# CONFIG_CAN_VCAN is not set
+# CONFIG_CAN_OLD_DRIVERS is not set
+# CONFIG_CAN_SLCAN is not set
+CONFIG_CAN_SJA1000=y
+CONFIG_CAN_SJA1000_MEM_OF=y
+# CONFIG_CAN_EMS_PCI is not set
+# CONFIG_CAN_IXXAT_PCI is not set
+# CONFIG_CAN_PEAK_PCI is not set
+# CONFIG_CAN_KVASER_PCI is not set
+# CONFIG_CAN_MSCAN is not set
+# CONFIG_CAN_DEBUG_DEVICES is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_NAND_FSL_ELBC is not set
+CONFIG_MTD_NAND_SOCRATES=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=32768
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_E1000E_ENABLED is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+CONFIG_GFAR_NAPI=y
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=800
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+CONFIG_TOUCHSCREEN_TSC2003=y
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DETECT_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_SOCRATES=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=y
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+CONFIG_SENSORS_LM75=y
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+CONFIG_SENSORS_W83781D=y
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_HWMON_DEBUG_CHIP=y
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+CONFIG_FB_FOREIGN_ENDIAN=y
+CONFIG_FB_BOTH_ENDIAN=y
+# CONFIG_FB_BIG_ENDIAN is not set
+# CONFIG_FB_LITTLE_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_MB862XX=y
+# CONFIG_FB_MB862XX_PCI_GDC is not set
+CONFIG_FB_MB862XX_LIME=y
+# CONFIG_FB_PRE_INIT_FB is not set
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_OF is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_FSL_DIU is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_FSL is not set
+CONFIG_USB_EHCI_HCD_PPC_OF=y
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PPC_OF=y
+CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
+# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
+CONFIG_USB_OHCI_HCD_PCI=y
+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+CONFIG_RTC_DRV_RX8025=y
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_PPC=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
new file mode 100644
index 000000000000..df2c16337794
--- /dev/null
+++ b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
@@ -0,0 +1,1889 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc7
+# Fri Mar 13 15:36:11 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+# CONFIG_PHYS_64BIT is not set
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_LOCKBREAK=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+CONFIG_GENERIC_TBSYNC=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+CONFIG_PPC_86xx=y
+# CONFIG_MPC8641_HPCN is not set
+# CONFIG_SBC8641D is not set
+# CONFIG_MPC8610_HPCD is not set
+CONFIG_GEF_PPC9A=y
+# CONFIG_GEF_SBC310 is not set
+# CONFIG_GEF_SBC610 is not set
+CONFIG_MPC8641=y
+# CONFIG_IPIC is not set
+CONFIG_MPIC=y
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_QUICC_ENGINE is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_MPC8xxx_GPIO is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+CONFIG_SCHED_HRTICK=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=m
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_FSL_PCI=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+# CONFIG_PCIEASPM is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+# CONFIG_PCI_LEGACY is not set
+CONFIG_PCI_DEBUG=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+# CONFIG_IP_NF_MATCH_AH is not set
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+# CONFIG_IP_NF_TARGET_TTL is not set
+CONFIG_IP_NF_RAW=m
+# CONFIG_IP_NF_SECURITY is not set
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+# CONFIG_IP6_NF_MATCH_AH is not set
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+# CONFIG_IP6_NF_MATCH_MH is not set
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+# CONFIG_IP6_NF_TARGET_REJECT is not set
+CONFIG_IP6_NF_MANGLE=m
+# CONFIG_IP6_NF_TARGET_HL is not set
+CONFIG_IP6_NF_RAW=m
+# CONFIG_IP6_NF_SECURITY is not set
+# CONFIG_BRIDGE_NF_EBTABLES is not set
+# CONFIG_IP_DCCP is not set
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+CONFIG_TIPC=m
+# CONFIG_TIPC_ADVANCED is not set
+# CONFIG_TIPC_DEBUG is not set
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+# CONFIG_ATM_CLIP_NO_ICMP is not set
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
+CONFIG_STP=m
+CONFIG_BRIDGE=m
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+CONFIG_WAN_ROUTER=m
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+# CONFIG_NET_SCH_MULTIQ is not set
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+# CONFIG_NET_SCH_DRR is not set
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+# CONFIG_NET_CLS_BASIC is not set
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_CLS_U32_MARK is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_I2C=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=131072
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_FSL is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+CONFIG_ATM_DRIVERS=y
+# CONFIG_ATM_DUMMY is not set
+# CONFIG_ATM_TCP is not set
+# CONFIG_ATM_LANAI is not set
+# CONFIG_ATM_ENI is not set
+# CONFIG_ATM_FIRESTREAM is not set
+# CONFIG_ATM_ZATM is not set
+# CONFIG_ATM_NICSTAR is not set
+# CONFIG_ATM_IDT77252 is not set
+# CONFIG_ATM_AMBASSADOR is not set
+# CONFIG_ATM_HORIZON is not set
+# CONFIG_ATM_IA is not set
+# CONFIG_ATM_FORE200E is not set
+# CONFIG_ATM_HE is not set
+# CONFIG_ATM_SOLOS is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+# CONFIG_PPPOL2TP is not set
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_NET_FC is not set
+CONFIG_NETCONSOLE=y
+# CONFIG_NETCONSOLE_DYNAMIC is not set
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+CONFIG_NVRAM=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_DS1682=y
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_XILINX is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+CONFIG_SENSORS_LM90=y
+CONFIG_SENSORS_LM92=y
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
+CONFIG_GEF_WDT=y
+# CONFIG_8xxx_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+CONFIG_THRUSTMASTER_FF=m
+CONFIG_ZEROPLUS_FF=m
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_FSL is not set
+# CONFIG_USB_EHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_ATM is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+# CONFIG_RTC_INTF_PROC is not set
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+CONFIG_RTC_DRV_RX8581=y
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PPC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+# CONFIG_SECURITY_PATH is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_SECURITY_ROOTPLUG is not set
+CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_NULL=m
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+# CONFIG_CRYPTO_CAMELLIA is not set
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/powerpc/configs/86xx/gef_sbc310_defconfig b/arch/powerpc/configs/86xx/gef_sbc310_defconfig
new file mode 100644
index 000000000000..bd236b3d915a
--- /dev/null
+++ b/arch/powerpc/configs/86xx/gef_sbc310_defconfig
@@ -0,0 +1,1613 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc3
+# Wed Jan 28 23:05:34 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+# CONFIG_PHYS_64BIT is not set
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_LOCKBREAK=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+CONFIG_GENERIC_TBSYNC=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+CONFIG_PPC_MSI_BITMAP=y
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+CONFIG_PPC_86xx=y
+# CONFIG_MPC8641_HPCN is not set
+# CONFIG_SBC8641D is not set
+# CONFIG_MPC8610_HPCD is not set
+CONFIG_GEF_SBC310=y
+# CONFIG_GEF_SBC610 is not set
+CONFIG_MPC8641=y
+# CONFIG_IPIC is not set
+CONFIG_MPIC=y
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_QUICC_ENGINE is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_MPC8xxx_GPIO is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+CONFIG_HZ_1000=y
+CONFIG_HZ=1000
+CONFIG_SCHED_HRTICK=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=y
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_FSL_PCI=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+# CONFIG_PCIEASPM is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+CONFIG_PCI_MSI=y
+# CONFIG_PCI_LEGACY is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_LOWMEM_CAM_NUM=3
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_FIB_RULES=y
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_QINFO_PROBE is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_GPIO=y
+CONFIG_OF_I2C=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=131072
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SIL24=y
+# CONFIG_SATA_FSL is not set
+# CONFIG_ATA_SFF is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_JME is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_NET_FC is not set
+CONFIG_NETCONSOLE=y
+# CONFIG_NETCONSOLE_DYNAMIC is not set
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+CONFIG_NVRAM=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+CONFIG_DS1682=y
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_XILINX is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+CONFIG_SENSORS_LM90=y
+CONFIG_SENSORS_LM92=y
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
+CONFIG_GEF_WDT=y
+# CONFIG_8xxx_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_FSL is not set
+# CONFIG_USB_EHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+# CONFIG_RTC_INTF_PROC is not set
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+CONFIG_RTC_DRV_RX8581=y
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PPC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_IRQSTACKS is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/powerpc/configs/amigaone_defconfig b/arch/powerpc/configs/amigaone_defconfig
new file mode 100644
index 000000000000..b63cc38df6b1
--- /dev/null
+++ b/arch/powerpc/configs/amigaone_defconfig
@@ -0,0 +1,1636 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc3
+# Sun Feb 1 14:22:42 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+CONFIG_6xx=y
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_PPC_MM_SLICES is not set
+# CONFIG_SMP is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_CHECK_CACHE_COHERENCY=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFAULT_UIMAGE=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=15
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_PCSPKR_PLATFORM=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_FREEZER is not set
+
+#
+# Platform support
+#
+CONFIG_PPC_MULTIPLATFORM=y
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_CHRP is not set
+# CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
+# CONFIG_EMBEDDED6xx is not set
+CONFIG_AMIGAONE=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+CONFIG_PPC_I8259=y
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+CONFIG_HIGHMEM=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=y
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_MIGRATION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+# CONFIG_PCI_LEGACY is not set
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER_ADVANCED is not set
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_STATE is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+# CONFIG_NF_NAT_TFTP is not set
+# CONFIG_NF_NAT_AMANDA is not set
+# CONFIG_NF_NAT_PPTP is not set
+# CONFIG_NF_NAT_H323 is not set
+CONFIG_NF_NAT_SIP=m
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=y
+# CONFIG_PARPORT_SERIAL is not set
+CONFIG_PARPORT_PC_FIFO=y
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_AX88796 is not set
+# CONFIG_PARPORT_1284 is not set
+CONFIG_BLK_DEV=y
+CONFIG_BLK_DEV_FD=y
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+CONFIG_IDE_TIMINGS=y
+CONFIG_IDE_ATAPI=y
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
+
+#
+# PCI IDE chipsets support
+#
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_PCIBUS_ORDER is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8172 is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_BLK_DEV_TC86C001 is not set
+CONFIG_BLK_DEV_IDEDMA=y
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_STEX is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_MMIO is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=y
+# CONFIG_TYPHOON is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+CONFIG_8139CP=y
+CONFIG_8139TOO=y
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_R6040 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_ATL2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PCSPKR=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+CONFIG_INPUT_UINPUT=y
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_XILINX_XPS_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_MPC is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_DDC=y
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+CONFIG_FB_MACMODES=y
+CONFIG_FB_BACKLIGHT=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_OF is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+CONFIG_FB_RADEON_BACKLIGHT=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+CONFIG_FB_3DFX=y
+# CONFIG_FB_3DFX_ACCEL is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=m
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_TOPSEED=y
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+#
+
+#
+# see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+CONFIG_RTC_DRV_CMOS=y
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PPC is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+# CONFIG_EXT4DEV_COMPAT is not set
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+CONFIG_JBD=y
+CONFIG_JBD2=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+CONFIG_AFFS_FS=m
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+CONFIG_XMON=y
+CONFIG_XMON_DEFAULT=y
+CONFIG_XMON_DISASSEMBLY=y
+CONFIG_DEBUGGER=y
+CONFIG_IRQSTACKS=y
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig
index 81afc8b373d7..af0cd55605d0 100644
--- a/arch/powerpc/configs/mpc5200_defconfig
+++ b/arch/powerpc/configs/mpc5200_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Mon Jan 26 21:40:44 2009
+# Linux kernel version: 2.6.29-rc3
+# Fri Feb 6 09:48:53 2009
#
# CONFIG_PPC64 is not set
@@ -388,7 +388,10 @@ CONFIG_MTD=y
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_TESTS is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_OF_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -502,7 +505,7 @@ CONFIG_MISC_DEVICES=y
#
# EEPROM support
#
-# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_AT24=y
# CONFIG_EEPROM_LEGACY is not set
# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
@@ -678,7 +681,7 @@ CONFIG_PHYLIB=y
# CONFIG_MARVELL_PHY is not set
# CONFIG_DAVICOM_PHY is not set
# CONFIG_QSEMI_PHY is not set
-# CONFIG_LXT_PHY is not set
+CONFIG_LXT_PHY=y
# CONFIG_CICADA_PHY is not set
# CONFIG_VITESSE_PHY is not set
# CONFIG_SMSC_PHY is not set
@@ -815,8 +818,6 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_NVRAM is not set
-CONFIG_GEN_RTC=y
-# CONFIG_GEN_RTC_X is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -1281,7 +1282,61 @@ CONFIG_NEW_LEDS=y
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+CONFIG_RTC_DRV_DS1307=y
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PPC is not set
# CONFIG_DMADEVICES is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 88c6295b76c1..252401824575 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -2067,9 +2067,9 @@ CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DEBUG_STACK_USAGE=y
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_HCALL_STATS is not set
-# CONFIG_CODE_PATCHING_SELFTEST is not set
-# CONFIG_FTR_FIXUP_SELFTEST is not set
-# CONFIG_MSI_BITMAP_SELFTEST is not set
+CONFIG_CODE_PATCHING_SELFTEST=y
+CONFIG_FTR_FIXUP_SELFTEST=y
+CONFIG_MSI_BITMAP_SELFTEST=y
CONFIG_XMON=y
# CONFIG_XMON_DEFAULT is not set
CONFIG_XMON_DISASSEMBLY=y
diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h
index 107d9b915e33..37c32aba79b7 100644
--- a/arch/powerpc/include/asm/code-patching.h
+++ b/arch/powerpc/include/asm/code-patching.h
@@ -11,9 +11,7 @@
*/
#include <asm/types.h>
-
-#define PPC_NOP_INSTR 0x60000000
-#define PPC_LWSYNC_INSTR 0x7c2004ac
+#include <asm/ppc-opcode.h>
/* Flags for create_branch:
* "b" == create_branch(addr, target, 0);
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 21172badd708..80f315e8a421 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -145,6 +145,7 @@ extern const char *powerpc_base_platform;
#define CPU_FTR_USE_TB ASM_CONST(0x0000000000000040)
#define CPU_FTR_L2CSR ASM_CONST(0x0000000000000080)
#define CPU_FTR_601 ASM_CONST(0x0000000000000100)
+#define CPU_FTR_DBELL ASM_CONST(0x0000000000000200)
#define CPU_FTR_CAN_NAP ASM_CONST(0x0000000000000400)
#define CPU_FTR_L3CR ASM_CONST(0x0000000000000800)
#define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x0000000000001000)
@@ -375,7 +376,8 @@ extern const char *powerpc_base_platform;
CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
#define CPU_FTRS_E500MC (CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN | \
- CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE)
+ CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
+ CPU_FTR_DBELL)
#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
/* 64-bit CPUs */
diff --git a/arch/powerpc/include/asm/dbell.h b/arch/powerpc/include/asm/dbell.h
new file mode 100644
index 000000000000..501189a543d1
--- /dev/null
+++ b/arch/powerpc/include/asm/dbell.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2009 Freescale Semicondutor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * provides masks and opcode images for use by code generation, emulation
+ * and for instructions that older assemblers might not know about
+ */
+#ifndef _ASM_POWERPC_DBELL_H
+#define _ASM_POWERPC_DBELL_H
+
+#include <linux/smp.h>
+#include <linux/threads.h>
+
+#include <asm/ppc-opcode.h>
+
+#define PPC_DBELL_MSG_BRDCAST (0x04000000)
+#define PPC_DBELL_TYPE(x) (((x) & 0xf) << 28)
+enum ppc_dbell {
+ PPC_DBELL = 0, /* doorbell */
+ PPC_DBELL_CRIT = 1, /* critical doorbell */
+ PPC_G_DBELL = 2, /* guest doorbell */
+ PPC_G_DBELL_CRIT = 3, /* guest critical doorbell */
+ PPC_G_DBELL_MC = 4, /* guest mcheck doorbell */
+};
+
+#ifdef CONFIG_SMP
+extern unsigned long dbell_smp_message[NR_CPUS];
+extern void smp_dbell_message_pass(int target, int msg);
+#endif
+
+static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag)
+{
+ u32 msg = PPC_DBELL_TYPE(type) | (flags & PPC_DBELL_MSG_BRDCAST) |
+ (tag & 0x07ffffff);
+
+ __asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
+}
+
+#endif /* _ASM_POWERPC_DBELL_H */
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 86cef7ddc8d5..c69f2b5f0cc4 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -109,18 +109,8 @@ static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
* only ISA DMA device we support is the floppy and we have a hack
* in the floppy driver directly to get a device for us.
*/
-
- if (unlikely(dev == NULL) || dev->archdata.dma_ops == NULL) {
-#ifdef CONFIG_PPC64
+ if (unlikely(dev == NULL))
return NULL;
-#else
- /* Use default on 32-bit if dma_ops is not set up */
- /* TODO: Long term, we should fix drivers so that dev and
- * archdata dma_ops are set up for all buses.
- */
- return &dma_direct_ops;
-#endif
- }
return dev->archdata.dma_ops;
}
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index b5600ce6055e..1a856b15226e 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -8,6 +8,7 @@
#endif
#include <linux/types.h>
+
#include <asm/ptrace.h>
#include <asm/cputable.h>
#include <asm/auxvec.h>
@@ -178,7 +179,8 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[ELF_NVSRHALFREG];
the loader. We need to make sure that it is out of the way of the program
that it will "exec", and that there is sufficient room for the brk. */
-#define ELF_ET_DYN_BASE (0x20000000)
+extern unsigned long randomize_et_dyn(unsigned long base);
+#define ELF_ET_DYN_BASE (randomize_et_dyn(0x20000000))
/*
* Our registers are always unsigned longs, whether we're a 32 bit
@@ -270,6 +272,14 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp);
#define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b);
+/* 1GB for 64bit, 8MB for 32bit */
+#define STACK_RND_MASK (is_32bit_task() ? \
+ (0x7ff >> (PAGE_SHIFT - 12)) : \
+ (0x3ffff >> (PAGE_SHIFT - 12)))
+
+extern unsigned long arch_randomize_brk(struct mm_struct *mm);
+#define arch_randomize_brk arch_randomize_brk
+
#endif /* __KERNEL__ */
/*
diff --git a/arch/powerpc/include/asm/fixmap.h b/arch/powerpc/include/asm/fixmap.h
index 8428b38a3d30..d60fd18f428c 100644
--- a/arch/powerpc/include/asm/fixmap.h
+++ b/arch/powerpc/include/asm/fixmap.h
@@ -61,7 +61,7 @@ extern void __set_fixmap (enum fixed_addresses idx,
* Some hardware wants to get fixmapped without caching.
*/
#define set_fixmap_nocache(idx, phys) \
- __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
+ __set_fixmap(idx, phys, PAGE_KERNEL_NCG)
#define clear_fixmap(idx) \
__set_fixmap(idx, 0, __pgprot(0))
diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h
index e5f2ae8362f7..dde1296b8b41 100644
--- a/arch/powerpc/include/asm/ftrace.h
+++ b/arch/powerpc/include/asm/ftrace.h
@@ -5,7 +5,44 @@
#define MCOUNT_ADDR ((long)(_mcount))
#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
-#ifndef __ASSEMBLY__
+#ifdef __ASSEMBLY__
+
+/* Based off of objdump optput from glibc */
+
+#define MCOUNT_SAVE_FRAME \
+ stwu r1,-48(r1); \
+ stw r3, 12(r1); \
+ stw r4, 16(r1); \
+ stw r5, 20(r1); \
+ stw r6, 24(r1); \
+ mflr r3; \
+ lwz r4, 52(r1); \
+ mfcr r5; \
+ stw r7, 28(r1); \
+ stw r8, 32(r1); \
+ stw r9, 36(r1); \
+ stw r10,40(r1); \
+ stw r3, 44(r1); \
+ stw r5, 8(r1)
+
+#define MCOUNT_RESTORE_FRAME \
+ lwz r6, 8(r1); \
+ lwz r0, 44(r1); \
+ lwz r3, 12(r1); \
+ mtctr r0; \
+ lwz r4, 16(r1); \
+ mtcr r6; \
+ lwz r5, 20(r1); \
+ lwz r6, 24(r1); \
+ lwz r0, 52(r1); \
+ lwz r7, 28(r1); \
+ lwz r8, 32(r1); \
+ mtlr r0; \
+ lwz r9, 36(r1); \
+ lwz r10,40(r1); \
+ addi r1, r1, 48
+
+#else /* !__ASSEMBLY__ */
extern void _mcount(void);
#ifdef CONFIG_DYNAMIC_FTRACE
diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h
index 04e4a620952e..684a73f4324f 100644
--- a/arch/powerpc/include/asm/highmem.h
+++ b/arch/powerpc/include/asm/highmem.h
@@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/highmem.h>
#include <asm/kmap_types.h>
#include <asm/tlbflush.h>
#include <asm/page.h>
@@ -39,15 +40,15 @@ extern pte_t *pkmap_page_table;
* chunk of RAM.
*/
/*
- * We use one full pte table with 4K pages. And with 16K/64K pages pte
- * table covers enough memory (32MB and 512MB resp.) that both FIXMAP
- * and PKMAP can be placed in single pte table. We use 1024 pages for
- * PKMAP in case of 16K/64K pages.
+ * We use one full pte table with 4K pages. And with 16K/64K/256K pages pte
+ * table covers enough memory (32MB/512MB/2GB resp.), so that both FIXMAP
+ * and PKMAP can be placed in a single pte table. We use 512 pages for PKMAP
+ * in case of 16K/64K/256K page sizes.
*/
#ifdef CONFIG_PPC_4K_PAGES
#define PKMAP_ORDER PTE_SHIFT
#else
-#define PKMAP_ORDER 10
+#define PKMAP_ORDER 9
#endif
#define LAST_PKMAP (1 << PKMAP_ORDER)
#ifndef CONFIG_PPC_4K_PAGES
@@ -94,12 +95,13 @@ static inline void *kmap_atomic_prot(struct page *page, enum km_type type, pgpro
if (!PageHighMem(page))
return page_address(page);
+ debug_kmap_atomic(type);
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
#ifdef CONFIG_DEBUG_HIGHMEM
BUG_ON(!pte_none(*(kmap_pte-idx)));
#endif
- __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot));
+ __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1);
local_flush_tlb_page(NULL, vaddr);
return (void*) vaddr;
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index f75a5fc64d2e..b7e034b0a6dd 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -129,7 +129,7 @@ static inline int irqs_disabled_flags(unsigned long flags)
* interrupt-retrigger: should we handle this via lost interrupts and IPIs
* or should we not care like we do now ? --BenH.
*/
-struct hw_interrupt_type;
+struct irq_chip;
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_HW_IRQ_H */
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index 494cd8b0a278..001f2f11c19b 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -632,6 +632,9 @@ static inline void iosync(void)
* ioremap_flags and cannot be hooked (but can be used by a hook on one
* of the previous ones)
*
+ * * __ioremap_caller is the same as above but takes an explicit caller
+ * reference rather than using __builtin_return_address(0)
+ *
* * __iounmap, is the low level implementation used by iounmap and cannot
* be hooked (but can be used by a hook on iounmap)
*
@@ -646,6 +649,9 @@ extern void iounmap(volatile void __iomem *addr);
extern void __iomem *__ioremap(phys_addr_t, unsigned long size,
unsigned long flags);
+extern void __iomem *__ioremap_caller(phys_addr_t, unsigned long size,
+ unsigned long flags, void *caller);
+
extern void __iounmap(volatile void __iomem *addr);
extern void __iomem * __ioremap_at(phys_addr_t pa, void *ea,
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index 4e0cf65f7f5a..bb2de6aa5ce0 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -52,4 +52,11 @@ struct kvm_fpu {
__u64 fpr[32];
};
+struct kvm_debug_exit_arch {
+};
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+};
+
#endif /* __LINUX_KVM_POWERPC_H */
diff --git a/arch/powerpc/include/asm/kvm_44x.h b/arch/powerpc/include/asm/kvm_44x.h
index f49031b632ca..d22d39942a92 100644
--- a/arch/powerpc/include/asm/kvm_44x.h
+++ b/arch/powerpc/include/asm/kvm_44x.h
@@ -28,6 +28,13 @@
* need to find some way of advertising it. */
#define KVM44x_GUEST_TLB_SIZE 64
+struct kvmppc_44x_tlbe {
+ u32 tid; /* Only the low 8 bits are used. */
+ u32 word0;
+ u32 word1;
+ u32 word2;
+};
+
struct kvmppc_44x_shadow_ref {
struct page *page;
u16 gtlb_index;
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
index 2197764796d9..56bfae59837f 100644
--- a/arch/powerpc/include/asm/kvm_asm.h
+++ b/arch/powerpc/include/asm/kvm_asm.h
@@ -42,7 +42,12 @@
#define BOOKE_INTERRUPT_DTLB_MISS 13
#define BOOKE_INTERRUPT_ITLB_MISS 14
#define BOOKE_INTERRUPT_DEBUG 15
-#define BOOKE_MAX_INTERRUPT 15
+
+/* E500 */
+#define BOOKE_INTERRUPT_SPE_UNAVAIL 32
+#define BOOKE_INTERRUPT_SPE_FP_DATA 33
+#define BOOKE_INTERRUPT_SPE_FP_ROUND 34
+#define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35
#define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */
#define RESUME_FLAG_HOST (1<<1) /* Resume host? */
diff --git a/arch/powerpc/include/asm/kvm_e500.h b/arch/powerpc/include/asm/kvm_e500.h
new file mode 100644
index 000000000000..9d497ce49726
--- /dev/null
+++ b/arch/powerpc/include/asm/kvm_e500.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, <yu.liu@freescale.com>
+ *
+ * Description:
+ * This file is derived from arch/powerpc/include/asm/kvm_44x.h,
+ * by Hollis Blanchard <hollisb@us.ibm.com>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_KVM_E500_H__
+#define __ASM_KVM_E500_H__
+
+#include <linux/kvm_host.h>
+
+#define BOOKE_INTERRUPT_SIZE 36
+
+#define E500_PID_NUM 3
+#define E500_TLB_NUM 2
+
+struct tlbe{
+ u32 mas1;
+ u32 mas2;
+ u32 mas3;
+ u32 mas7;
+};
+
+struct kvmppc_vcpu_e500 {
+ /* Unmodified copy of the guest's TLB. */
+ struct tlbe *guest_tlb[E500_TLB_NUM];
+ /* TLB that's actually used when the guest is running. */
+ struct tlbe *shadow_tlb[E500_TLB_NUM];
+ /* Pages which are referenced in the shadow TLB. */
+ struct page **shadow_pages[E500_TLB_NUM];
+
+ unsigned int guest_tlb_size[E500_TLB_NUM];
+ unsigned int shadow_tlb_size[E500_TLB_NUM];
+ unsigned int guest_tlb_nv[E500_TLB_NUM];
+
+ u32 host_pid[E500_PID_NUM];
+ u32 pid[E500_PID_NUM];
+
+ u32 mas0;
+ u32 mas1;
+ u32 mas2;
+ u32 mas3;
+ u32 mas4;
+ u32 mas5;
+ u32 mas6;
+ u32 mas7;
+ u32 l1csr1;
+ u32 hid0;
+ u32 hid1;
+
+ struct kvm_vcpu vcpu;
+};
+
+static inline struct kvmppc_vcpu_e500 *to_e500(struct kvm_vcpu *vcpu)
+{
+ return container_of(vcpu, struct kvmppc_vcpu_e500, vcpu);
+}
+
+#endif /* __ASM_KVM_E500_H__ */
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index c1e436fe7738..dfdf13c9fefd 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -64,13 +64,6 @@ struct kvm_vcpu_stat {
u32 halt_wakeup;
};
-struct kvmppc_44x_tlbe {
- u32 tid; /* Only the low 8 bits are used. */
- u32 word0;
- u32 word1;
- u32 word2;
-};
-
enum kvm_exit_types {
MMIO_EXITS,
DCR_EXITS,
@@ -118,11 +111,6 @@ struct kvm_arch {
struct kvm_vcpu_arch {
u32 host_stack;
u32 host_pid;
- u32 host_dbcr0;
- u32 host_dbcr1;
- u32 host_dbcr2;
- u32 host_iac[4];
- u32 host_msr;
u64 fpr[32];
ulong gpr[32];
@@ -157,7 +145,7 @@ struct kvm_vcpu_arch {
u32 tbu;
u32 tcr;
u32 tsr;
- u32 ivor[16];
+ u32 ivor[64];
ulong ivpr;
u32 pir;
@@ -170,6 +158,7 @@ struct kvm_vcpu_arch {
u32 ccr1;
u32 dbcr0;
u32 dbcr1;
+ u32 dbsr;
#ifdef CONFIG_KVM_EXIT_TIMING
struct kvmppc_exit_timing timing_exit;
@@ -200,10 +189,4 @@ struct kvm_vcpu_arch {
unsigned long pending_exceptions;
};
-struct kvm_guest_debug {
- int enabled;
- unsigned long bp[4];
- int singlestep;
-};
-
#endif /* __POWERPC_KVM_HOST_H__ */
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 36d2a50a8487..2c6ee349df5e 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -52,13 +52,19 @@ extern int kvmppc_emulate_instruction(struct kvm_run *run,
extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu);
extern void kvmppc_emulate_dec(struct kvm_vcpu *vcpu);
+/* Core-specific hooks */
+
extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr,
- u64 asid, u32 flags, u32 max_bytes,
unsigned int gtlb_idx);
extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode);
extern void kvmppc_mmu_switch_pid(struct kvm_vcpu *vcpu, u32 pid);
-
-/* Core-specific hooks */
+extern void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu);
+extern int kvmppc_mmu_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr);
+extern int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr);
+extern gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int gtlb_index,
+ gva_t eaddr);
+extern void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu);
+extern void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu);
extern struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm,
unsigned int id);
@@ -71,9 +77,6 @@ extern int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
extern void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
extern void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu);
-extern void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu);
-extern void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu);
-
extern void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu);
extern int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu);
extern void kvmppc_core_queue_program(struct kvm_vcpu *vcpu);
diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
index 25aaa97facd8..68235f7e4a8f 100644
--- a/arch/powerpc/include/asm/lppaca.h
+++ b/arch/powerpc/include/asm/lppaca.h
@@ -97,7 +97,7 @@ struct lppaca {
u64 saved_gpr4; // Saved GPR4 x28-x2F
u64 saved_gpr5; // Saved GPR5 x30-x37
- u8 reserved4; // Reserved x38-x38
+ u8 dtl_enable_mask; // Dispatch Trace Log mask x38-x38
u8 donate_dedicated_cpu; // Donate dedicated CPU cycles x39-x39
u8 fpregs_in_use; // FP regs in use x3A-x3A
u8 pmcregs_in_use; // PMC regs in use x3B-x3B
@@ -133,8 +133,10 @@ struct lppaca {
//=============================================================================
// CACHE_LINE_4-5 0x0180 - 0x027F Contains PMC interrupt data
//=============================================================================
- u32 page_ins; // CMO Hint - # page ins by OS x00-x04
- u8 pmc_save_area[252]; // PMC interrupt Area x04-xFF
+ u32 page_ins; // CMO Hint - # page ins by OS x00-x03
+ u8 reserved8[148]; // Reserved x04-x97
+ volatile u64 dtl_idx; // Dispatch Trace Log head idx x98-x9F
+ u8 reserved9[96]; // Reserved xA0-xFF
} __attribute__((__aligned__(0x400)));
extern struct lppaca lppaca[];
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 2740c44ff717..0efdb1dfdc5f 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -90,7 +90,7 @@ struct machdep_calls {
void (*tce_flush)(struct iommu_table *tbl);
void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size,
- unsigned long flags);
+ unsigned long flags, void *caller);
void (*iounmap)(volatile void __iomem *token);
#ifdef CONFIG_PM
@@ -327,8 +327,6 @@ extern void __devinit smp_generic_take_timebase(void);
*/
/* Print a boot progress message. */
void ppc64_boot_msg(unsigned int src, const char *msg);
-/* Print a termination message (print only -- does not stop the kernel) */
-void ppc64_terminate_msg(unsigned int src, const char *msg);
static inline void log_error(char *buf, unsigned int err_type, int fatal)
{
diff --git a/arch/powerpc/include/asm/mmu-44x.h b/arch/powerpc/include/asm/mmu-44x.h
index 27cc6fdcd3b7..3c86576bfefa 100644
--- a/arch/powerpc/include/asm/mmu-44x.h
+++ b/arch/powerpc/include/asm/mmu-44x.h
@@ -83,6 +83,8 @@ typedef struct {
#define PPC44x_TLBE_SIZE PPC44x_TLB_16K
#elif (PAGE_SHIFT == 16)
#define PPC44x_TLBE_SIZE PPC44x_TLB_64K
+#elif (PAGE_SHIFT == 18)
+#define PPC44x_TLBE_SIZE PPC44x_TLB_256K
#else
#error "Unsupported PAGE_SIZE"
#endif
diff --git a/arch/powerpc/include/asm/mmu-fsl-booke.h b/arch/powerpc/include/asm/mmu-book3e.h
index 3f941c0f7e8e..7e74cff81d86 100644
--- a/arch/powerpc/include/asm/mmu-fsl-booke.h
+++ b/arch/powerpc/include/asm/mmu-book3e.h
@@ -1,26 +1,42 @@
-#ifndef _ASM_POWERPC_MMU_FSL_BOOKE_H_
-#define _ASM_POWERPC_MMU_FSL_BOOKE_H_
+#ifndef _ASM_POWERPC_MMU_BOOK3E_H_
+#define _ASM_POWERPC_MMU_BOOK3E_H_
/*
- * Freescale Book-E MMU support
+ * Freescale Book-E/Book-3e (ISA 2.06+) MMU support
*/
-/* Book-E defined page sizes */
-#define BOOKE_PAGESZ_1K 0
-#define BOOKE_PAGESZ_4K 1
-#define BOOKE_PAGESZ_16K 2
-#define BOOKE_PAGESZ_64K 3
-#define BOOKE_PAGESZ_256K 4
-#define BOOKE_PAGESZ_1M 5
-#define BOOKE_PAGESZ_4M 6
-#define BOOKE_PAGESZ_16M 7
-#define BOOKE_PAGESZ_64M 8
-#define BOOKE_PAGESZ_256M 9
-#define BOOKE_PAGESZ_1GB 10
-#define BOOKE_PAGESZ_4GB 11
-#define BOOKE_PAGESZ_16GB 12
-#define BOOKE_PAGESZ_64GB 13
-#define BOOKE_PAGESZ_256GB 14
-#define BOOKE_PAGESZ_1TB 15
+/* Book-3e defined page sizes */
+#define BOOK3E_PAGESZ_1K 0
+#define BOOK3E_PAGESZ_2K 1
+#define BOOK3E_PAGESZ_4K 2
+#define BOOK3E_PAGESZ_8K 3
+#define BOOK3E_PAGESZ_16K 4
+#define BOOK3E_PAGESZ_32K 5
+#define BOOK3E_PAGESZ_64K 6
+#define BOOK3E_PAGESZ_128K 7
+#define BOOK3E_PAGESZ_256K 8
+#define BOOK3E_PAGESZ_512K 9
+#define BOOK3E_PAGESZ_1M 10
+#define BOOK3E_PAGESZ_2M 11
+#define BOOK3E_PAGESZ_4M 12
+#define BOOK3E_PAGESZ_8M 13
+#define BOOK3E_PAGESZ_16M 14
+#define BOOK3E_PAGESZ_32M 15
+#define BOOK3E_PAGESZ_64M 16
+#define BOOK3E_PAGESZ_128M 17
+#define BOOK3E_PAGESZ_256M 18
+#define BOOK3E_PAGESZ_512M 19
+#define BOOK3E_PAGESZ_1GB 20
+#define BOOK3E_PAGESZ_2GB 21
+#define BOOK3E_PAGESZ_4GB 22
+#define BOOK3E_PAGESZ_8GB 23
+#define BOOK3E_PAGESZ_16GB 24
+#define BOOK3E_PAGESZ_32GB 25
+#define BOOK3E_PAGESZ_64GB 26
+#define BOOK3E_PAGESZ_128GB 27
+#define BOOK3E_PAGESZ_256GB 28
+#define BOOK3E_PAGESZ_512GB 29
+#define BOOK3E_PAGESZ_1TB 30
+#define BOOK3E_PAGESZ_2TB 31
#define MAS0_TLBSEL(x) ((x << 28) & 0x30000000)
#define MAS0_ESEL(x) ((x << 16) & 0x0FFF0000)
@@ -29,8 +45,9 @@
#define MAS1_VALID 0x80000000
#define MAS1_IPROT 0x40000000
#define MAS1_TID(x) ((x << 16) & 0x3FFF0000)
+#define MAS1_IND 0x00002000
#define MAS1_TS 0x00001000
-#define MAS1_TSIZE(x) ((x << 8) & 0x00000F00)
+#define MAS1_TSIZE(x) ((x << 7) & 0x00000F80)
#define MAS2_EPN 0xFFFFF000
#define MAS2_X0 0x00000040
@@ -40,7 +57,7 @@
#define MAS2_M 0x00000004
#define MAS2_G 0x00000002
#define MAS2_E 0x00000001
-#define MAS2_EPN_MASK(size) (~0 << (2*(size) + 10))
+#define MAS2_EPN_MASK(size) (~0 << (size + 10))
#define MAS2_VAL(addr, size, flags) ((addr) & MAS2_EPN_MASK(size) | (flags))
#define MAS3_RPN 0xFFFFF000
@@ -56,7 +73,7 @@
#define MAS3_SR 0x00000001
#define MAS4_TLBSELD(x) MAS0_TLBSEL(x)
-#define MAS4_TIDDSEL 0x000F0000
+#define MAS4_INDD 0x00008000
#define MAS4_TSIZED(x) MAS1_TSIZE(x)
#define MAS4_X0D 0x00000040
#define MAS4_X1D 0x00000020
@@ -68,6 +85,7 @@
#define MAS6_SPID0 0x3FFF0000
#define MAS6_SPID1 0x00007FFE
+#define MAS6_ISIZE(x) MAS1_TSIZE(x)
#define MAS6_SAS 0x00000001
#define MAS6_SPID MAS6_SPID0
@@ -75,6 +93,8 @@
#ifndef __ASSEMBLY__
+extern unsigned int tlbcam_index;
+
typedef struct {
unsigned int id;
unsigned int active;
@@ -82,4 +102,4 @@ typedef struct {
} mm_context_t;
#endif /* !__ASSEMBLY__ */
-#endif /* _ASM_POWERPC_MMU_FSL_BOOKE_H_ */
+#endif /* _ASM_POWERPC_MMU_BOOK3E_H_ */
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index 68b752626808..98c104a09961 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -284,8 +284,6 @@ extern void add_gpage(unsigned long addr, unsigned long page_size,
unsigned long number_of_pages);
extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr);
-extern void htab_initialize(void);
-extern void htab_initialize_secondary(void);
extern void hpte_init_native(void);
extern void hpte_init_lpar(void);
extern void hpte_init_iSeries(void);
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index 6e7639911318..cbf154387091 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -36,9 +36,9 @@
*/
#define MMU_FTR_USE_TLBIVAX_BCAST ASM_CONST(0x00040000)
-/* Enable use of tlbilx invalidate-by-PID variant.
+/* Enable use of tlbilx invalidate instructions.
*/
-#define MMU_FTR_USE_TLBILX_PID ASM_CONST(0x00080000)
+#define MMU_FTR_USE_TLBILX ASM_CONST(0x00080000)
/* This indicates that the processor cannot handle multiple outstanding
* broadcast tlbivax or tlbsync. This makes the code use a spinlock
@@ -46,6 +46,12 @@
*/
#define MMU_FTR_LOCK_BCAST_INVAL ASM_CONST(0x00100000)
+/* This indicates that the processor doesn't handle way selection
+ * properly and needs SW to track and update the LRU state. This
+ * is specific to an errata on e300c2/c3/c4 class parts
+ */
+#define MMU_FTR_NEED_DTLB_SW_LRU ASM_CONST(0x00200000)
+
#ifndef __ASSEMBLY__
#include <asm/cputable.h>
@@ -56,6 +62,10 @@ static inline int mmu_has_feature(unsigned long feature)
extern unsigned int __start___mmu_ftr_fixup, __stop___mmu_ftr_fixup;
+/* MMU initialization (64-bit only fo now) */
+extern void early_init_mmu(void);
+extern void early_init_mmu_secondary(void);
+
#endif /* !__ASSEMBLY__ */
@@ -71,9 +81,9 @@ extern unsigned int __start___mmu_ftr_fixup, __stop___mmu_ftr_fixup;
#elif defined(CONFIG_44x)
/* 44x-style software loaded TLB */
# include <asm/mmu-44x.h>
-#elif defined(CONFIG_FSL_BOOKE)
-/* Freescale Book-E software loaded TLB */
-# include <asm/mmu-fsl-booke.h>
+#elif defined(CONFIG_PPC_BOOK3E_MMU)
+/* Freescale Book-E software loaded TLB or Book-3e (ISA 2.06+) MMU */
+# include <asm/mmu-book3e.h>
#elif defined (CONFIG_PPC_8xx)
/* Motorola/Freescale 8xx software loaded TLB */
# include <asm/mmu-8xx.h>
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index ab4f19263c42..b7063669f972 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -31,7 +31,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
{
/* Mark this context has been used on the new CPU */
- cpu_set(smp_processor_id(), next->cpu_vm_mask);
+ cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
/* 32-bit keeps track of the current PGDIR in the thread struct */
#ifdef CONFIG_PPC32
diff --git a/arch/powerpc/include/asm/mmzone.h b/arch/powerpc/include/asm/mmzone.h
index 19f299b7e256..35acac90c8ca 100644
--- a/arch/powerpc/include/asm/mmzone.h
+++ b/arch/powerpc/include/asm/mmzone.h
@@ -8,6 +8,7 @@
#define _ASM_MMZONE_H_
#ifdef __KERNEL__
+#include <linux/cpumask.h>
/*
* generic non-linear memory support:
diff --git a/arch/powerpc/include/asm/mpc52xx.h b/arch/powerpc/include/asm/mpc52xx.h
index 81a23932a160..52e049cd9e68 100644
--- a/arch/powerpc/include/asm/mpc52xx.h
+++ b/arch/powerpc/include/asm/mpc52xx.h
@@ -273,6 +273,7 @@ extern void mpc5200_setup_xlb_arbiter(void);
extern void mpc52xx_declare_of_platform_devices(void);
extern void mpc52xx_map_common_devices(void);
extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv);
+extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node);
extern void mpc52xx_restart(char *cmd);
/* mpc52xx_pic.c */
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 197d569f5bd3..32cbf16f10ea 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -19,12 +19,14 @@
#include <asm/kdump.h>
/*
- * On regular PPC32 page size is 4K (but we support 4K/16K/64K pages
+ * On regular PPC32 page size is 4K (but we support 4K/16K/64K/256K pages
* on PPC44x). For PPC64 we support either 4K or 64K software
* page size. When using 64K pages however, whether we are really supporting
* 64K pages in HW or not is irrelevant to those definitions.
*/
-#if defined(CONFIG_PPC_64K_PAGES)
+#if defined(CONFIG_PPC_256K_PAGES)
+#define PAGE_SHIFT 18
+#elif defined(CONFIG_PPC_64K_PAGES)
#define PAGE_SHIFT 16
#elif defined(CONFIG_PPC_16K_PAGES)
#define PAGE_SHIFT 14
diff --git a/arch/powerpc/include/asm/page_32.h b/arch/powerpc/include/asm/page_32.h
index 1458d9500381..a0e3f6e6b4ee 100644
--- a/arch/powerpc/include/asm/page_32.h
+++ b/arch/powerpc/include/asm/page_32.h
@@ -19,7 +19,11 @@
#define PTE_FLAGS_OFFSET 0
#endif
+#ifdef CONFIG_PPC_256K_PAGES
+#define PTE_SHIFT (PAGE_SHIFT - PTE_T_LOG2 - 2) /* 1/4 of a page */
+#else
#define PTE_SHIFT (PAGE_SHIFT - PTE_T_LOG2) /* full page */
+#endif
#ifndef __ASSEMBLY__
/*
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 3548159a1beb..ba17d5d90a49 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -114,6 +114,10 @@ extern int pci_domain_nr(struct pci_bus *bus);
/* Decide whether to display the domain number in /proc */
extern int pci_proc_domain(struct pci_bus *bus);
+/* MSI arch hooks */
+#define arch_setup_msi_irqs arch_setup_msi_irqs
+#define arch_teardown_msi_irqs arch_teardown_msi_irqs
+#define arch_msi_check_device arch_msi_check_device
struct vm_area_struct;
/* Map a range of PCI memory or I/O space for a device into user space */
diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h
index 820b5f0a35ce..ba45c997830f 100644
--- a/arch/powerpc/include/asm/pgtable-ppc32.h
+++ b/arch/powerpc/include/asm/pgtable-ppc32.h
@@ -19,55 +19,6 @@ extern int icache_44x_need_flush;
#endif /* __ASSEMBLY__ */
/*
- * The PowerPC MMU uses a hash table containing PTEs, together with
- * a set of 16 segment registers (on 32-bit implementations), to define
- * the virtual to physical address mapping.
- *
- * We use the hash table as an extended TLB, i.e. a cache of currently
- * active mappings. We maintain a two-level page table tree, much
- * like that used by the i386, for the sake of the Linux memory
- * management code. Low-level assembler code in hashtable.S
- * (procedure hash_page) is responsible for extracting ptes from the
- * tree and putting them into the hash table when necessary, and
- * updating the accessed and modified bits in the page table tree.
- */
-
-/*
- * The PowerPC MPC8xx uses a TLB with hardware assisted, software tablewalk.
- * We also use the two level tables, but we can put the real bits in them
- * needed for the TLB and tablewalk. These definitions require Mx_CTR.PPM = 0,
- * Mx_CTR.PPCS = 0, and MD_CTR.TWAM = 1. The level 2 descriptor has
- * additional page protection (when Mx_CTR.PPCS = 1) that allows TLB hit
- * based upon user/super access. The TLB does not have accessed nor write
- * protect. We assume that if the TLB get loaded with an entry it is
- * accessed, and overload the changed bit for write protect. We use
- * two bits in the software pte that are supposed to be set to zero in
- * the TLB entry (24 and 25) for these indicators. Although the level 1
- * descriptor contains the guarded and writethrough/copyback bits, we can
- * set these at the page level since they get copied from the Mx_TWC
- * register when the TLB entry is loaded. We will use bit 27 for guard, since
- * that is where it exists in the MD_TWC, and bit 26 for writethrough.
- * These will get masked from the level 2 descriptor at TLB load time, and
- * copied to the MD_TWC before it gets loaded.
- * Large page sizes added. We currently support two sizes, 4K and 8M.
- * This also allows a TLB hander optimization because we can directly
- * load the PMD into MD_TWC. The 8M pages are only used for kernel
- * mapping of well known areas. The PMD (PGD) entries contain control
- * flags in addition to the address, so care must be taken that the
- * software no longer assumes these are only pointers.
- */
-
-/*
- * At present, all PowerPC 400-class processors share a similar TLB
- * architecture. The instruction and data sides share a unified,
- * 64-entry, fully-associative TLB which is maintained totally under
- * software control. In addition, the instruction side has a
- * hardware-managed, 4-entry, fully-associative TLB which serves as a
- * first level to the shared TLB. These two TLBs are known as the UTLB
- * and ITLB, respectively (see "mmu.h" for definitions).
- */
-
-/*
* The normal case is that PTEs are 32-bits and we have a 1-page
* 1024-entry pgdir pointing to 1-page 1024-entry PTE pages. -- paulus
*
@@ -135,409 +86,22 @@ extern int icache_44x_need_flush;
*/
#if defined(CONFIG_40x)
-
-/* There are several potential gotchas here. The 40x hardware TLBLO
- field looks like this:
-
- 0 1 2 3 4 ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31
- RPN..................... 0 0 EX WR ZSEL....... W I M G
-
- Where possible we make the Linux PTE bits match up with this
-
- - bits 20 and 21 must be cleared, because we use 4k pages (40x can
- support down to 1k pages), this is done in the TLBMiss exception
- handler.
- - We use only zones 0 (for kernel pages) and 1 (for user pages)
- of the 16 available. Bit 24-26 of the TLB are cleared in the TLB
- miss handler. Bit 27 is PAGE_USER, thus selecting the correct
- zone.
- - PRESENT *must* be in the bottom two bits because swap cache
- entries use the top 30 bits. Because 40x doesn't support SMP
- anyway, M is irrelevant so we borrow it for PAGE_PRESENT. Bit 30
- is cleared in the TLB miss handler before the TLB entry is loaded.
- - All other bits of the PTE are loaded into TLBLO without
- modification, leaving us only the bits 20, 21, 24, 25, 26, 30 for
- software PTE bits. We actually use use bits 21, 24, 25, and
- 30 respectively for the software bits: ACCESSED, DIRTY, RW, and
- PRESENT.
-*/
-
-/* Definitions for 40x embedded chips. */
-#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */
-#define _PAGE_FILE 0x001 /* when !present: nonlinear file mapping */
-#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */
-#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */
-#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */
-#define _PAGE_USER 0x010 /* matches one of the zone permission bits */
-#define _PAGE_RW 0x040 /* software: Writes permitted */
-#define _PAGE_DIRTY 0x080 /* software: dirty page */
-#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */
-#define _PAGE_HWEXEC 0x200 /* hardware: EX permission */
-#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */
-
-#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
-#define _PMD_BAD 0x802
-#define _PMD_SIZE 0x0e0 /* size field, != 0 for large-page PMD entry */
-#define _PMD_SIZE_4M 0x0c0
-#define _PMD_SIZE_16M 0x0e0
-#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4))
-
-/* Until my rework is finished, 40x still needs atomic PTE updates */
-#define PTE_ATOMIC_UPDATES 1
-
+#include <asm/pte-40x.h>
#elif defined(CONFIG_44x)
-/*
- * Definitions for PPC440
- *
- * Because of the 3 word TLB entries to support 36-bit addressing,
- * the attribute are difficult to map in such a fashion that they
- * are easily loaded during exception processing. I decided to
- * organize the entry so the ERPN is the only portion in the
- * upper word of the PTE and the attribute bits below are packed
- * in as sensibly as they can be in the area below a 4KB page size
- * oriented RPN. This at least makes it easy to load the RPN and
- * ERPN fields in the TLB. -Matt
- *
- * Note that these bits preclude future use of a page size
- * less than 4KB.
- *
- *
- * PPC 440 core has following TLB attribute fields;
- *
- * TLB1:
- * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
- * RPN................................. - - - - - - ERPN.......
- *
- * TLB2:
- * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
- * - - - - - - U0 U1 U2 U3 W I M G E - UX UW UR SX SW SR
- *
- * Newer 440 cores (440x6 as used on AMCC 460EX/460GT) have additional
- * TLB2 storage attibute fields. Those are:
- *
- * TLB2:
- * 0...10 11 12 13 14 15 16...31
- * no change WL1 IL1I IL1D IL2I IL2D no change
- *
- * There are some constrains and options, to decide mapping software bits
- * into TLB entry.
- *
- * - PRESENT *must* be in the bottom three bits because swap cache
- * entries use the top 29 bits for TLB2.
- *
- * - FILE *must* be in the bottom three bits because swap cache
- * entries use the top 29 bits for TLB2.
- *
- * - CACHE COHERENT bit (M) has no effect on original PPC440 cores,
- * because it doesn't support SMP. However, some later 460 variants
- * have -some- form of SMP support and so I keep the bit there for
- * future use
- *
- * With the PPC 44x Linux implementation, the 0-11th LSBs of the PTE are used
- * for memory protection related functions (see PTE structure in
- * include/asm-ppc/mmu.h). The _PAGE_XXX definitions in this file map to the
- * above bits. Note that the bit values are CPU specific, not architecture
- * specific.
- *
- * The kernel PTE entry holds an arch-dependent swp_entry structure under
- * certain situations. In other words, in such situations some portion of
- * the PTE bits are used as a swp_entry. In the PPC implementation, the
- * 3-24th LSB are shared with swp_entry, however the 0-2nd three LSB still
- * hold protection values. That means the three protection bits are
- * reserved for both PTE and SWAP entry at the most significant three
- * LSBs.
- *
- * There are three protection bits available for SWAP entry:
- * _PAGE_PRESENT
- * _PAGE_FILE
- * _PAGE_HASHPTE (if HW has)
- *
- * So those three bits have to be inside of 0-2nd LSB of PTE.
- *
- */
-
-#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */
-#define _PAGE_RW 0x00000002 /* S: Write permission */
-#define _PAGE_FILE 0x00000004 /* S: nonlinear file mapping */
-#define _PAGE_HWEXEC 0x00000004 /* H: Execute permission */
-#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */
-#define _PAGE_DIRTY 0x00000010 /* S: Page dirty */
-#define _PAGE_SPECIAL 0x00000020 /* S: Special page */
-#define _PAGE_USER 0x00000040 /* S: User page */
-#define _PAGE_ENDIAN 0x00000080 /* H: E bit */
-#define _PAGE_GUARDED 0x00000100 /* H: G bit */
-#define _PAGE_COHERENT 0x00000200 /* H: M bit */
-#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */
-#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */
-
-/* TODO: Add large page lowmem mapping support */
-#define _PMD_PRESENT 0
-#define _PMD_PRESENT_MASK (PAGE_MASK)
-#define _PMD_BAD (~PAGE_MASK)
-
-/* ERPN in a PTE never gets cleared, ignore it */
-#define _PTE_NONE_MASK 0xffffffff00000000ULL
-
-#define __HAVE_ARCH_PTE_SPECIAL
-
+#include <asm/pte-44x.h>
#elif defined(CONFIG_FSL_BOOKE)
-/*
- MMU Assist Register 3:
-
- 32 33 34 35 36 ... 50 51 52 53 54 55 56 57 58 59 60 61 62 63
- RPN...................... 0 0 U0 U1 U2 U3 UX SX UW SW UR SR
-
- - PRESENT *must* be in the bottom three bits because swap cache
- entries use the top 29 bits.
-
- - FILE *must* be in the bottom three bits because swap cache
- entries use the top 29 bits.
-*/
-
-/* Definitions for FSL Book-E Cores */
-#define _PAGE_PRESENT 0x00001 /* S: PTE contains a translation */
-#define _PAGE_USER 0x00002 /* S: User page (maps to UR) */
-#define _PAGE_FILE 0x00002 /* S: when !present: nonlinear file mapping */
-#define _PAGE_RW 0x00004 /* S: Write permission (SW) */
-#define _PAGE_DIRTY 0x00008 /* S: Page dirty */
-#define _PAGE_HWEXEC 0x00010 /* H: SX permission */
-#define _PAGE_ACCESSED 0x00020 /* S: Page referenced */
-
-#define _PAGE_ENDIAN 0x00040 /* H: E bit */
-#define _PAGE_GUARDED 0x00080 /* H: G bit */
-#define _PAGE_COHERENT 0x00100 /* H: M bit */
-#define _PAGE_NO_CACHE 0x00200 /* H: I bit */
-#define _PAGE_WRITETHRU 0x00400 /* H: W bit */
-#define _PAGE_SPECIAL 0x00800 /* S: Special page */
-
-#ifdef CONFIG_PTE_64BIT
-/* ERPN in a PTE never gets cleared, ignore it */
-#define _PTE_NONE_MASK 0xffffffffffff0000ULL
-#endif
-
-#define _PMD_PRESENT 0
-#define _PMD_PRESENT_MASK (PAGE_MASK)
-#define _PMD_BAD (~PAGE_MASK)
-
-#define __HAVE_ARCH_PTE_SPECIAL
-
+#include <asm/pte-fsl-booke.h>
#elif defined(CONFIG_8xx)
-/* Definitions for 8xx embedded chips. */
-#define _PAGE_PRESENT 0x0001 /* Page is valid */
-#define _PAGE_FILE 0x0002 /* when !present: nonlinear file mapping */
-#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */
-#define _PAGE_SHARED 0x0004 /* No ASID (context) compare */
-
-/* These five software bits must be masked out when the entry is loaded
- * into the TLB.
- */
-#define _PAGE_EXEC 0x0008 /* software: i-cache coherency required */
-#define _PAGE_GUARDED 0x0010 /* software: guarded access */
-#define _PAGE_DIRTY 0x0020 /* software: page changed */
-#define _PAGE_RW 0x0040 /* software: user write access allowed */
-#define _PAGE_ACCESSED 0x0080 /* software: page referenced */
-
-/* Setting any bits in the nibble with the follow two controls will
- * require a TLB exception handler change. It is assumed unused bits
- * are always zero.
- */
-#define _PAGE_HWWRITE 0x0100 /* h/w write enable: never set in Linux PTE */
-#define _PAGE_USER 0x0800 /* One of the PP bits, the other is USER&~RW */
-
-#define _PMD_PRESENT 0x0001
-#define _PMD_BAD 0x0ff0
-#define _PMD_PAGE_MASK 0x000c
-#define _PMD_PAGE_8M 0x000c
-
-#define _PTE_NONE_MASK _PAGE_ACCESSED
-
-/* Until my rework is finished, 8xx still needs atomic PTE updates */
-#define PTE_ATOMIC_UPDATES 1
-
+#include <asm/pte-8xx.h>
#else /* CONFIG_6xx */
-/* Definitions for 60x, 740/750, etc. */
-#define _PAGE_PRESENT 0x001 /* software: pte contains a translation */
-#define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */
-#define _PAGE_FILE 0x004 /* when !present: nonlinear file mapping */
-#define _PAGE_USER 0x004 /* usermode access allowed */
-#define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */
-#define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */
-#define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */
-#define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
-#define _PAGE_DIRTY 0x080 /* C: page changed */
-#define _PAGE_ACCESSED 0x100 /* R: page referenced */
-#define _PAGE_EXEC 0x200 /* software: i-cache coherency required */
-#define _PAGE_RW 0x400 /* software: user write access allowed */
-#define _PAGE_SPECIAL 0x800 /* software: Special page */
-
-#ifdef CONFIG_PTE_64BIT
-/* We never clear the high word of the pte */
-#define _PTE_NONE_MASK (0xffffffff00000000ULL | _PAGE_HASHPTE)
-#else
-#define _PTE_NONE_MASK _PAGE_HASHPTE
+#include <asm/pte-hash32.h>
#endif
-#define _PMD_PRESENT 0
-#define _PMD_PRESENT_MASK (PAGE_MASK)
-#define _PMD_BAD (~PAGE_MASK)
-
-/* Hash table based platforms need atomic updates of the linux PTE */
-#define PTE_ATOMIC_UPDATES 1
-
-#define __HAVE_ARCH_PTE_SPECIAL
-
-#endif
-
-/*
- * Some bits are only used on some cpu families...
- */
-#ifndef _PAGE_HASHPTE
-#define _PAGE_HASHPTE 0
-#endif
-#ifndef _PTE_NONE_MASK
-#define _PTE_NONE_MASK 0
-#endif
-#ifndef _PAGE_SHARED
-#define _PAGE_SHARED 0
-#endif
-#ifndef _PAGE_HWWRITE
-#define _PAGE_HWWRITE 0
-#endif
-#ifndef _PAGE_HWEXEC
-#define _PAGE_HWEXEC 0
-#endif
-#ifndef _PAGE_EXEC
-#define _PAGE_EXEC 0
-#endif
-#ifndef _PAGE_ENDIAN
-#define _PAGE_ENDIAN 0
-#endif
-#ifndef _PAGE_COHERENT
-#define _PAGE_COHERENT 0
-#endif
-#ifndef _PAGE_WRITETHRU
-#define _PAGE_WRITETHRU 0
-#endif
-#ifndef _PAGE_SPECIAL
-#define _PAGE_SPECIAL 0
-#endif
-#ifndef _PMD_PRESENT_MASK
-#define _PMD_PRESENT_MASK _PMD_PRESENT
-#endif
-#ifndef _PMD_SIZE
-#define _PMD_SIZE 0
-#define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE()
-#endif
-
-#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \
- _PAGE_SPECIAL)
-
-
-#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
- _PAGE_WRITETHRU | _PAGE_ENDIAN | \
- _PAGE_USER | _PAGE_ACCESSED | \
- _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \
- _PAGE_EXEC | _PAGE_HWEXEC)
-
-/*
- * We define 2 sets of base prot bits, one for basic pages (ie,
- * cacheable kernel and user pages) and one for non cacheable
- * pages. We always set _PAGE_COHERENT when SMP is enabled or
- * the processor might need it for DMA coherency.
- */
-#if defined(CONFIG_SMP) || defined(CONFIG_PPC_STD_MMU)
-#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT)
-#else
-#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED)
-#endif
-#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_NO_CACHE)
-
-#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE)
-#define _PAGE_KERNEL (_PAGE_BASE | _PAGE_SHARED | _PAGE_WRENABLE)
-#define _PAGE_KERNEL_NC (_PAGE_BASE_NC | _PAGE_SHARED | _PAGE_WRENABLE)
-
-#ifdef CONFIG_PPC_STD_MMU
-/* On standard PPC MMU, no user access implies kernel read/write access,
- * so to write-protect kernel memory we must turn on user access */
-#define _PAGE_KERNEL_RO (_PAGE_BASE | _PAGE_SHARED | _PAGE_USER)
-#else
-#define _PAGE_KERNEL_RO (_PAGE_BASE | _PAGE_SHARED)
-#endif
-
-#define _PAGE_IO (_PAGE_KERNEL_NC | _PAGE_GUARDED)
-#define _PAGE_RAM (_PAGE_KERNEL | _PAGE_HWEXEC)
-
-#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) ||\
- defined(CONFIG_KPROBES)
-/* We want the debuggers to be able to set breakpoints anywhere, so
- * don't write protect the kernel text */
-#define _PAGE_RAM_TEXT _PAGE_RAM
-#else
-#define _PAGE_RAM_TEXT (_PAGE_KERNEL_RO | _PAGE_HWEXEC)
-#endif
-
-#define PAGE_NONE __pgprot(_PAGE_BASE)
-#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
-#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-
-#define PAGE_KERNEL __pgprot(_PAGE_RAM)
-#define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
-
-/*
- * The PowerPC can only do execute protection on a segment (256MB) basis,
- * not on a page basis. So we consider execute permission the same as read.
- * Also, write permissions imply read permissions.
- * This is the closest we can get..
- */
-#define __P000 PAGE_NONE
-#define __P001 PAGE_READONLY_X
-#define __P010 PAGE_COPY
-#define __P011 PAGE_COPY_X
-#define __P100 PAGE_READONLY
-#define __P101 PAGE_READONLY_X
-#define __P110 PAGE_COPY
-#define __P111 PAGE_COPY_X
-
-#define __S000 PAGE_NONE
-#define __S001 PAGE_READONLY_X
-#define __S010 PAGE_SHARED
-#define __S011 PAGE_SHARED_X
-#define __S100 PAGE_READONLY
-#define __S101 PAGE_READONLY_X
-#define __S110 PAGE_SHARED
-#define __S111 PAGE_SHARED_X
+/* And here we include common definitions */
+#include <asm/pte-common.h>
#ifndef __ASSEMBLY__
-/* Make sure we get a link error if PMD_PAGE_SIZE is ever called on a
- * kernel without large page PMD support */
-extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
-
-/*
- * Conversions between PTE values and page frame numbers.
- */
-
-/* in some case we want to additionaly adjust where the pfn is in the pte to
- * allow room for more flags */
-#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT)
-#define PFN_SHIFT_OFFSET (PAGE_SHIFT + 8)
-#else
-#define PFN_SHIFT_OFFSET (PAGE_SHIFT)
-#endif
-#define pte_pfn(x) (pte_val(x) >> PFN_SHIFT_OFFSET)
-#define pte_page(x) pfn_to_page(pte_pfn(x))
-
-#define pfn_pte(pfn, prot) __pte(((pte_basic_t)(pfn) << PFN_SHIFT_OFFSET) |\
- pgprot_val(prot))
-#define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot)
-#endif /* __ASSEMBLY__ */
-
-#define pte_none(pte) ((pte_val(pte) & ~_PTE_NONE_MASK) == 0)
-#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
#define pte_clear(mm, addr, ptep) \
do { pte_update(ptep, ~_PAGE_HASHPTE, 0); } while (0)
@@ -546,43 +110,6 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
#define pmd_present(pmd) (pmd_val(pmd) & _PMD_PRESENT_MASK)
#define pmd_clear(pmdp) do { pmd_val(*(pmdp)) = 0; } while (0)
-#ifndef __ASSEMBLY__
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
-static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
-static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
-static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
-static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
-
-static inline pte_t pte_wrprotect(pte_t pte) {
- pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); return pte; }
-static inline pte_t pte_mkclean(pte_t pte) {
- pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; }
-static inline pte_t pte_mkold(pte_t pte) {
- pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-
-static inline pte_t pte_mkwrite(pte_t pte) {
- pte_val(pte) |= _PAGE_RW; return pte; }
-static inline pte_t pte_mkdirty(pte_t pte) {
- pte_val(pte) |= _PAGE_DIRTY; return pte; }
-static inline pte_t pte_mkyoung(pte_t pte) {
- pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-static inline pte_t pte_mkspecial(pte_t pte) {
- pte_val(pte) |= _PAGE_SPECIAL; return pte; }
-static inline pgprot_t pte_pgprot(pte_t pte)
-{
- return __pgprot(pte_val(pte) & PAGE_PROT_BITS);
-}
-
-static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-{
- pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
- return pte;
-}
-
/*
* When flushing the tlb entry for a page, we also need to flush the hash
* table entry. flush_hash_pages is assembler (for speed) in hashtable.S.
@@ -599,11 +126,19 @@ extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep,
unsigned long address);
/*
- * Atomic PTE updates.
+ * PTE updates. This function is called whenever an existing
+ * valid PTE is updated. This does -not- include set_pte_at()
+ * which nowadays only sets a new PTE.
*
- * pte_update clears and sets bit atomically, and returns
- * the old pte value. In the 64-bit PTE case we lock around the
- * low PTE word since we expect ALL flag bits to be there
+ * Depending on the type of MMU, we may need to use atomic updates
+ * and the PTE may be either 32 or 64 bit wide. In the later case,
+ * when using atomic updates, only the low part of the PTE is
+ * accessed atomically.
+ *
+ * In addition, on 44x, we also maintain a global flag indicating
+ * that an executable user mapping was modified, which is needed
+ * to properly flush the virtually tagged instruction cache of
+ * those implementations.
*/
#ifndef CONFIG_PTE_64BIT
static inline unsigned long pte_update(pte_t *p,
@@ -668,44 +203,6 @@ static inline unsigned long long pte_update(pte_t *p,
#endif /* CONFIG_PTE_64BIT */
/*
- * set_pte stores a linux PTE into the linux page table.
- * On machines which use an MMU hash table we avoid changing the
- * _PAGE_HASHPTE bit.
- */
-
-static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte)
-{
-#if (_PAGE_HASHPTE != 0) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT)
- pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE);
-#elif defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP)
-#if _PAGE_HASHPTE != 0
- if (pte_val(*ptep) & _PAGE_HASHPTE)
- flush_hash_entry(mm, ptep, addr);
-#endif
- __asm__ __volatile__("\
- stw%U0%X0 %2,%0\n\
- eieio\n\
- stw%U0%X0 %L2,%1"
- : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
- : "r" (pte) : "memory");
-#else
- *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
- | (pte_val(pte) & ~_PAGE_HASHPTE));
-#endif
-}
-
-
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte)
-{
-#if defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP) && defined(CONFIG_DEBUG_VM)
- WARN_ON(pte_present(*ptep));
-#endif
- __set_pte_at(mm, addr, ptep, pte);
-}
-
-/*
* 2.6 calls this without flushing the TLB entry; this is wrong
* for our hash-based implementation, we fix that up here.
*/
@@ -745,24 +242,14 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
}
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
+static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
{
unsigned long bits = pte_val(entry) &
- (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW);
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW |
+ _PAGE_HWEXEC | _PAGE_EXEC);
pte_update(ptep, 0, bits);
}
-#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-({ \
- int __changed = !pte_same(*(__ptep), __entry); \
- if (__changed) { \
- __ptep_set_access_flags(__ptep, __entry, __dirty); \
- flush_tlb_page_nohash(__vma, __address); \
- } \
- __changed; \
-})
-
#define __HAVE_ARCH_PTE_SAME
#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
diff --git a/arch/powerpc/include/asm/pgtable-4k.h b/arch/powerpc/include/asm/pgtable-ppc64-4k.h
index 1dbca4e7de67..6eefdcffa359 100644
--- a/arch/powerpc/include/asm/pgtable-4k.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64-4k.h
@@ -1,5 +1,5 @@
-#ifndef _ASM_POWERPC_PGTABLE_4K_H
-#define _ASM_POWERPC_PGTABLE_4K_H
+#ifndef _ASM_POWERPC_PGTABLE_PPC64_4K_H
+#define _ASM_POWERPC_PGTABLE_PPC64_4K_H
/*
* Entries per page directory level. The PTE level must use a 64b record
* for each page table entry. The PMD and PGD level use a 32b record for
@@ -40,28 +40,6 @@
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
-/* PTE bits */
-#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */
-#define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */
-#define _PAGE_GROUP_IX 0x7000 /* software: HPTE index within group */
-#define _PAGE_F_SECOND _PAGE_SECONDARY
-#define _PAGE_F_GIX _PAGE_GROUP_IX
-#define _PAGE_SPECIAL 0x10000 /* software: special page */
-#define __HAVE_ARCH_PTE_SPECIAL
-
-/* PTE flags to conserve for HPTE identification */
-#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | \
- _PAGE_SECONDARY | _PAGE_GROUP_IX)
-
-/* There is no 4K PFN hack on 4K pages */
-#define _PAGE_4K_PFN 0
-
-/* PAGE_MASK gives the right answer below, but only by accident */
-/* It should be preserving the high 48 bits and then specifically */
-/* preserving _PAGE_SECONDARY | _PAGE_GROUP_IX */
-#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | \
- _PAGE_HPTEFLAGS | _PAGE_SPECIAL)
-
/* Bits to mask out from a PMD to get to the PTE page */
#define PMD_MASKED_BITS 0
/* Bits to mask out from a PUD to get to the PMD page */
@@ -69,30 +47,6 @@
/* Bits to mask out from a PGD to get to the PUD page */
#define PGD_MASKED_BITS 0
-/* shift to put page number into pte */
-#define PTE_RPN_SHIFT (17)
-
-#ifdef STRICT_MM_TYPECHECKS
-#define __real_pte(e,p) ((real_pte_t){(e)})
-#define __rpte_to_pte(r) ((r).pte)
-#else
-#define __real_pte(e,p) (e)
-#define __rpte_to_pte(r) (__pte(r))
-#endif
-#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> 12)
-
-#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \
- do { \
- index = 0; \
- shift = mmu_psize_defs[psize].shift; \
-
-#define pte_iterate_hashed_end() } while(0)
-
-#ifdef CONFIG_PPC_HAS_HASH_64K
-#define pte_pagesize_index(mm, addr, pte) get_slice_psize(mm, addr)
-#else
-#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K
-#endif
/*
* 4-level page tables related bits
@@ -112,6 +66,9 @@
#define pud_ERROR(e) \
printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e))
+/*
+ * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range() */
#define remap_4k_pfn(vma, addr, pfn, prot) \
remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot))
-#endif /* _ASM_POWERPC_PGTABLE_4K_H */
+
+#endif /* _ASM_POWERPC_PGTABLE_PPC64_4K_H */
diff --git a/arch/powerpc/include/asm/pgtable-ppc64-64k.h b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
new file mode 100644
index 000000000000..6cc085b945a5
--- /dev/null
+++ b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
@@ -0,0 +1,42 @@
+#ifndef _ASM_POWERPC_PGTABLE_PPC64_64K_H
+#define _ASM_POWERPC_PGTABLE_PPC64_64K_H
+
+#include <asm-generic/pgtable-nopud.h>
+
+
+#define PTE_INDEX_SIZE 12
+#define PMD_INDEX_SIZE 12
+#define PUD_INDEX_SIZE 0
+#define PGD_INDEX_SIZE 4
+
+#ifndef __ASSEMBLY__
+
+#define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE)
+#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
+#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
+
+#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
+#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
+#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
+
+/* With 4k base page size, hugepage PTEs go at the PMD level */
+#define MIN_HUGEPTE_SHIFT PAGE_SHIFT
+
+/* PMD_SHIFT determines what a second-level page table entry can map */
+#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+#endif /* __ASSEMBLY__ */
+
+/* Bits to mask out from a PMD to get to the PTE page */
+#define PMD_MASKED_BITS 0x1ff
+/* Bits to mask out from a PGD/PUD to get to the PMD page */
+#define PUD_MASKED_BITS 0x1ff
+
+#endif /* _ASM_POWERPC_PGTABLE_PPC64_64K_H */
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
index b0f18be81d9f..c40db05f21e0 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64.h
@@ -11,9 +11,9 @@
#endif /* __ASSEMBLY__ */
#ifdef CONFIG_PPC_64K_PAGES
-#include <asm/pgtable-64k.h>
+#include <asm/pgtable-ppc64-64k.h>
#else
-#include <asm/pgtable-4k.h>
+#include <asm/pgtable-ppc64-4k.h>
#endif
#define FIRST_USER_ADDRESS 0
@@ -25,6 +25,8 @@
PUD_INDEX_SIZE + PGD_INDEX_SIZE + PAGE_SHIFT)
#define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE)
+
+/* Some sanity checking */
#if TASK_SIZE_USER64 > PGTABLE_RANGE
#error TASK_SIZE_USER64 exceeds pagetable range
#endif
@@ -33,7 +35,6 @@
#error TASK_SIZE_USER64 exceeds user VSID range
#endif
-
/*
* Define the address range of the vmalloc VM area.
*/
@@ -76,83 +77,12 @@
/*
- * Common bits in a linux-style PTE. These match the bits in the
- * (hardware-defined) PowerPC PTE as closely as possible. Additional
- * bits may be defined in pgtable-*.h
+ * Include the PTE bits definitions
*/
-#define _PAGE_PRESENT 0x0001 /* software: pte contains a translation */
-#define _PAGE_USER 0x0002 /* matches one of the PP bits */
-#define _PAGE_FILE 0x0002 /* (!present only) software: pte holds file offset */
-#define _PAGE_EXEC 0x0004 /* No execute on POWER4 and newer (we invert) */
-#define _PAGE_GUARDED 0x0008
-#define _PAGE_COHERENT 0x0010 /* M: enforce memory coherence (SMP systems) */
-#define _PAGE_NO_CACHE 0x0020 /* I: cache inhibit */
-#define _PAGE_WRITETHRU 0x0040 /* W: cache write-through */
-#define _PAGE_DIRTY 0x0080 /* C: page changed */
-#define _PAGE_ACCESSED 0x0100 /* R: page referenced */
-#define _PAGE_RW 0x0200 /* software: user write access allowed */
-#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */
-
-/* Strong Access Ordering */
-#define _PAGE_SAO (_PAGE_WRITETHRU | _PAGE_NO_CACHE | _PAGE_COHERENT)
-
-#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_COHERENT)
-
-#define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY)
-
-/* __pgprot defined in arch/powerpc/include/asm/page.h */
-#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
-
-#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER)
-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
-#define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_WRENABLE)
-#define PAGE_KERNEL_CI __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
- _PAGE_WRENABLE | _PAGE_NO_CACHE | _PAGE_GUARDED)
-#define PAGE_KERNEL_EXEC __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_EXEC)
-
-#define PAGE_AGP __pgprot(_PAGE_BASE | _PAGE_WRENABLE | _PAGE_NO_CACHE)
-#define HAVE_PAGE_AGP
-
-#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | \
- _PAGE_NO_CACHE | _PAGE_WRITETHRU | \
- _PAGE_4K_PFN | _PAGE_RW | _PAGE_USER | \
- _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_EXEC)
-/* PTEIDX nibble */
-#define _PTEIDX_SECONDARY 0x8
-#define _PTEIDX_GROUP_IX 0x7
+#include <asm/pte-hash64.h>
+#include <asm/pte-common.h>
-/*
- * POWER4 and newer have per page execute protection, older chips can only
- * do this on a segment (256MB) basis.
- *
- * Also, write permissions imply read permissions.
- * This is the closest we can get..
- *
- * Note due to the way vm flags are laid out, the bits are XWR
- */
-#define __P000 PAGE_NONE
-#define __P001 PAGE_READONLY
-#define __P010 PAGE_COPY
-#define __P011 PAGE_COPY
-#define __P100 PAGE_READONLY_X
-#define __P101 PAGE_READONLY_X
-#define __P110 PAGE_COPY_X
-#define __P111 PAGE_COPY_X
-
-#define __S000 PAGE_NONE
-#define __S001 PAGE_READONLY
-#define __S010 PAGE_SHARED
-#define __S011 PAGE_SHARED
-#define __S100 PAGE_READONLY_X
-#define __S101 PAGE_READONLY_X
-#define __S110 PAGE_SHARED_X
-#define __S111 PAGE_SHARED_X
-
#ifdef CONFIG_PPC_MM_SLICES
#define HAVE_ARCH_UNMAPPED_AREA
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
@@ -161,32 +91,38 @@
#ifndef __ASSEMBLY__
/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- *
- * mk_pte takes a (struct page *) as input
+ * This is the default implementation of various PTE accessors, it's
+ * used in all cases except Book3S with 64K pages where we have a
+ * concept of sub-pages
*/
-#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
+#ifndef __real_pte
-static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
-{
- pte_t pte;
+#ifdef STRICT_MM_TYPECHECKS
+#define __real_pte(e,p) ((real_pte_t){(e)})
+#define __rpte_to_pte(r) ((r).pte)
+#else
+#define __real_pte(e,p) (e)
+#define __rpte_to_pte(r) (__pte(r))
+#endif
+#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> 12)
+#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \
+ do { \
+ index = 0; \
+ shift = mmu_psize_defs[psize].shift; \
- pte_val(pte) = (pfn << PTE_RPN_SHIFT) | pgprot_val(pgprot);
- return pte;
-}
+#define pte_iterate_hashed_end() } while(0)
-#define pte_modify(_pte, newprot) \
- (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)))
+#ifdef CONFIG_PPC_HAS_HASH_64K
+#define pte_pagesize_index(mm, addr, pte) get_slice_psize(mm, addr)
+#else
+#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K
+#endif
-#define pte_none(pte) ((pte_val(pte) & ~_PAGE_HPTEFLAGS) == 0)
-#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
+#endif /* __real_pte */
-/* pte_clear moved to later in this file */
-#define pte_pfn(x) ((unsigned long)((pte_val(x)>>PTE_RPN_SHIFT)))
-#define pte_page(x) pfn_to_page(pte_pfn(x))
+/* pte_clear moved to later in this file */
#define PMD_BAD_BITS (PTE_TABLE_SIZE-1)
#define PUD_BAD_BITS (PMD_TABLE_SIZE-1)
@@ -235,36 +171,6 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
/* This now only contains the vmalloc pages */
#define pgd_offset_k(address) pgd_offset(&init_mm, address)
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW;}
-static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY;}
-static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED;}
-static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE;}
-static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
-
-static inline pte_t pte_wrprotect(pte_t pte) {
- pte_val(pte) &= ~(_PAGE_RW); return pte; }
-static inline pte_t pte_mkclean(pte_t pte) {
- pte_val(pte) &= ~(_PAGE_DIRTY); return pte; }
-static inline pte_t pte_mkold(pte_t pte) {
- pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-static inline pte_t pte_mkwrite(pte_t pte) {
- pte_val(pte) |= _PAGE_RW; return pte; }
-static inline pte_t pte_mkdirty(pte_t pte) {
- pte_val(pte) |= _PAGE_DIRTY; return pte; }
-static inline pte_t pte_mkyoung(pte_t pte) {
- pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-static inline pte_t pte_mkhuge(pte_t pte) {
- return pte; }
-static inline pte_t pte_mkspecial(pte_t pte) {
- pte_val(pte) |= _PAGE_SPECIAL; return pte; }
-static inline pgprot_t pte_pgprot(pte_t pte)
-{
- return __pgprot(pte_val(pte) & PAGE_PROT_BITS);
-}
/* Atomic PTE updates */
static inline unsigned long pte_update(struct mm_struct *mm,
@@ -272,6 +178,7 @@ static inline unsigned long pte_update(struct mm_struct *mm,
pte_t *ptep, unsigned long clr,
int huge)
{
+#ifdef PTE_ATOMIC_UPDATES
unsigned long old, tmp;
__asm__ __volatile__(
@@ -284,6 +191,13 @@ static inline unsigned long pte_update(struct mm_struct *mm,
: "=&r" (old), "=&r" (tmp), "=m" (*ptep)
: "r" (ptep), "r" (clr), "m" (*ptep), "i" (_PAGE_BUSY)
: "cc" );
+#else
+ unsigned long old = pte_val(*ptep);
+ *ptep = __pte(old & ~clr);
+#endif
+ /* huge pages use the old page table lock */
+ if (!huge)
+ assert_pte_locked(mm, addr);
if (old & _PAGE_HASHPTE)
hpte_need_flush(mm, addr, ptep, old, huge);
@@ -359,26 +273,17 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
pte_update(mm, addr, ptep, ~0UL, 0);
}
-/*
- * set_pte stores a linux PTE into the linux page table.
- */
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte)
-{
- if (pte_present(*ptep))
- pte_clear(mm, addr, ptep);
- pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
- *ptep = pte;
-}
/* Set the dirty and/or accessed bits atomically in a linux PTE, this
* function doesn't need to flush the hash entry
*/
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
+static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
{
unsigned long bits = pte_val(entry) &
- (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
+ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW |
+ _PAGE_EXEC | _PAGE_HWEXEC);
+
+#ifdef PTE_ATOMIC_UPDATES
unsigned long old, tmp;
__asm__ __volatile__(
@@ -391,16 +296,11 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry, int dirty)
:"=&r" (old), "=&r" (tmp), "=m" (*ptep)
:"r" (bits), "r" (ptep), "m" (*ptep), "i" (_PAGE_BUSY)
:"cc");
+#else
+ unsigned long old = pte_val(*ptep);
+ *ptep = __pte(old | bits);
+#endif
}
-#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-({ \
- int __changed = !pte_same(*(__ptep), __entry); \
- if (__changed) { \
- __ptep_set_access_flags(__ptep, __entry, __dirty); \
- flush_tlb_page_nohash(__vma, __address); \
- } \
- __changed; \
-})
#define __HAVE_ARCH_PTE_SAME
#define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 07f55e601696..eb17da781128 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -6,7 +6,17 @@
#include <asm/processor.h> /* For TASK_SIZE */
#include <asm/mmu.h>
#include <asm/page.h>
+
struct mm_struct;
+
+#ifdef CONFIG_DEBUG_VM
+extern void assert_pte_locked(struct mm_struct *mm, unsigned long addr);
+#else /* CONFIG_DEBUG_VM */
+static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
+{
+}
+#endif /* !CONFIG_DEBUG_VM */
+
#endif /* !__ASSEMBLY__ */
#if defined(CONFIG_PPC64)
@@ -17,6 +27,130 @@ struct mm_struct;
#ifndef __ASSEMBLY__
+/* Generic accessors to PTE bits */
+static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
+static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
+static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; }
+static inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; }
+static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; }
+static inline pgprot_t pte_pgprot(pte_t pte) { return __pgprot(pte_val(pte) & PAGE_PROT_BITS); }
+
+/* Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ *
+ * Even if PTEs can be unsigned long long, a PFN is always an unsigned
+ * long for now.
+ */
+static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) {
+ return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) |
+ pgprot_val(pgprot)); }
+static inline unsigned long pte_pfn(pte_t pte) {
+ return pte_val(pte) >> PTE_RPN_SHIFT; }
+
+/* Keep these as a macros to avoid include dependency mess */
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
+
+/* Generic modifiers for PTE bits */
+static inline pte_t pte_wrprotect(pte_t pte) {
+ pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); return pte; }
+static inline pte_t pte_mkclean(pte_t pte) {
+ pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; }
+static inline pte_t pte_mkold(pte_t pte) {
+ pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte) {
+ pte_val(pte) |= _PAGE_RW; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte) {
+ pte_val(pte) |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte) {
+ pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkspecial(pte_t pte) {
+ pte_val(pte) |= _PAGE_SPECIAL; return pte; }
+static inline pte_t pte_mkhuge(pte_t pte) {
+ return pte; }
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
+ return pte;
+}
+
+
+/* Insert a PTE, top-level function is out of line. It uses an inline
+ * low level function in the respective pgtable-* files
+ */
+extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
+ pte_t pte);
+
+/* This low level function performs the actual PTE insertion
+ * Setting the PTE depends on the MMU type and other factors. It's
+ * an horrible mess that I'm not going to try to clean up now but
+ * I'm keeping it in one place rather than spread around
+ */
+static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte, int percpu)
+{
+#if defined(CONFIG_PPC_STD_MMU_32) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT)
+ /* First case is 32-bit Hash MMU in SMP mode with 32-bit PTEs. We use the
+ * helper pte_update() which does an atomic update. We need to do that
+ * because a concurrent invalidation can clear _PAGE_HASHPTE. If it's a
+ * per-CPU PTE such as a kmap_atomic, we do a simple update preserving
+ * the hash bits instead (ie, same as the non-SMP case)
+ */
+ if (percpu)
+ *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+ | (pte_val(pte) & ~_PAGE_HASHPTE));
+ else
+ pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte));
+
+#elif defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP)
+ /* Second case is 32-bit with 64-bit PTE in SMP mode. In this case, we
+ * can just store as long as we do the two halves in the right order
+ * with a barrier in between. This is possible because we take care,
+ * in the hash code, to pre-invalidate if the PTE was already hashed,
+ * which synchronizes us with any concurrent invalidation.
+ * In the percpu case, we also fallback to the simple update preserving
+ * the hash bits
+ */
+ if (percpu) {
+ *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+ | (pte_val(pte) & ~_PAGE_HASHPTE));
+ return;
+ }
+#if _PAGE_HASHPTE != 0
+ if (pte_val(*ptep) & _PAGE_HASHPTE)
+ flush_hash_entry(mm, ptep, addr);
+#endif
+ __asm__ __volatile__("\
+ stw%U0%X0 %2,%0\n\
+ eieio\n\
+ stw%U0%X0 %L2,%1"
+ : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
+ : "r" (pte) : "memory");
+
+#elif defined(CONFIG_PPC_STD_MMU_32)
+ /* Third case is 32-bit hash table in UP mode, we need to preserve
+ * the _PAGE_HASHPTE bit since we may not have invalidated the previous
+ * translation in the hash yet (done in a subsequent flush_tlb_xxx())
+ * and see we need to keep track that this PTE needs invalidating
+ */
+ *ptep = __pte((pte_val(*ptep) & _PAGE_HASHPTE)
+ | (pte_val(pte) & ~_PAGE_HASHPTE));
+
+#else
+ /* Anything else just stores the PTE normally. That covers all 64-bit
+ * cases, and 32-bit non-hash with 64-bit PTEs in UP mode
+ */
+ *ptep = pte;
+#endif
+}
+
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
+ pte_t *ptep, pte_t entry, int dirty);
+
/*
* Macro to mark a page protection value as "uncacheable".
*/
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
new file mode 100644
index 000000000000..f4a4db8d5555
--- /dev/null
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2009 Freescale Semicondutor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * provides masks and opcode images for use by code generation, emulation
+ * and for instructions that older assemblers might not know about
+ */
+#ifndef _ASM_POWERPC_PPC_OPCODE_H
+#define _ASM_POWERPC_PPC_OPCODE_H
+
+#include <linux/stringify.h>
+#include <asm/asm-compat.h>
+
+/* sorted alphabetically */
+#define PPC_INST_DCBA 0x7c0005ec
+#define PPC_INST_DCBA_MASK 0xfc0007fe
+#define PPC_INST_DCBAL 0x7c2005ec
+#define PPC_INST_DCBZL 0x7c2007ec
+#define PPC_INST_ISEL 0x7c00001e
+#define PPC_INST_ISEL_MASK 0xfc00003e
+#define PPC_INST_LSWI 0x7c0004aa
+#define PPC_INST_LSWX 0x7c00042a
+#define PPC_INST_LWSYNC 0x7c2004ac
+#define PPC_INST_MCRXR 0x7c000400
+#define PPC_INST_MCRXR_MASK 0xfc0007fe
+#define PPC_INST_MFSPR_PVR 0x7c1f42a6
+#define PPC_INST_MFSPR_PVR_MASK 0xfc1fffff
+#define PPC_INST_MSGSND 0x7c00019c
+#define PPC_INST_NOP 0x60000000
+#define PPC_INST_POPCNTB 0x7c0000f4
+#define PPC_INST_POPCNTB_MASK 0xfc0007fe
+#define PPC_INST_RFCI 0x4c000066
+#define PPC_INST_RFDI 0x4c00004e
+#define PPC_INST_RFMCI 0x4c00004c
+
+#define PPC_INST_STRING 0x7c00042a
+#define PPC_INST_STRING_MASK 0xfc0007fe
+#define PPC_INST_STRING_GEN_MASK 0xfc00067e
+
+#define PPC_INST_STSWI 0x7c0005aa
+#define PPC_INST_STSWX 0x7c00052a
+#define PPC_INST_TLBILX 0x7c000626
+#define PPC_INST_WAIT 0x7c00007c
+
+/* macros to insert fields into opcodes */
+#define __PPC_RA(a) ((a & 0x1f) << 16)
+#define __PPC_RB(b) ((b & 0x1f) << 11)
+#define __PPC_T_TLB(t) ((t & 0x3) << 21)
+#define __PPC_WC(w) ((w & 0x3) << 21)
+
+/* Deal with instructions that older assemblers aren't aware of */
+#define PPC_DCBAL(a, b) stringify_in_c(.long PPC_INST_DCBAL | \
+ __PPC_RA(a) | __PPC_RB(b))
+#define PPC_DCBZL(a, b) stringify_in_c(.long PPC_INST_DCBZL | \
+ __PPC_RA(a) | __PPC_RB(b))
+#define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \
+ __PPC_RB(b))
+#define PPC_RFCI stringify_in_c(.long PPC_INST_RFCI)
+#define PPC_RFDI stringify_in_c(.long PPC_INST_RFDI)
+#define PPC_RFMCI stringify_in_c(.long PPC_INST_RFMCI)
+#define PPC_TLBILX(t, a, b) stringify_in_c(.long PPC_INST_TLBILX | \
+ __PPC_T_TLB(t) | __PPC_RA(a) | __PPC_RB(b))
+#define PPC_TLBILX_ALL(a, b) PPC_TLBILX(0, a, b)
+#define PPC_TLBILX_PID(a, b) PPC_TLBILX(1, a, b)
+#define PPC_TLBILX_VA(a, b) PPC_TLBILX(3, a, b)
+#define PPC_WAIT(w) stringify_in_c(.long PPC_INST_WAIT | \
+ __PPC_WC(w))
+
+#endif /* _ASM_POWERPC_PPC_OPCODE_H */
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 1a0d628eb114..f59a66684aed 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -7,6 +7,7 @@
#include <linux/stringify.h>
#include <asm/asm-compat.h>
#include <asm/processor.h>
+#include <asm/ppc-opcode.h>
#ifndef __ASSEMBLY__
#error __FILE__ should only be used in assembler files
@@ -167,11 +168,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
#define HMT_MEDIUM_HIGH or 5,5,5 # medium high priority
#define HMT_HIGH or 3,3,3
-/* handle instructions that older assemblers may not know */
-#define RFCI .long 0x4c000066 /* rfci instruction */
-#define RFDI .long 0x4c00004e /* rfdi instruction */
-#define RFMCI .long 0x4c00004c /* rfmci instruction */
-
#ifdef __KERNEL__
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index d3466490104a..9eed29eee604 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -313,6 +313,25 @@ static inline void prefetchw(const void *x)
#define HAVE_ARCH_PICK_MMAP_LAYOUT
#endif
+#ifdef CONFIG_PPC64
+static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32)
+{
+ unsigned long sp;
+
+ if (is_32)
+ sp = regs->gpr[1] & 0x0ffffffffUL;
+ else
+ sp = regs->gpr[1];
+
+ return sp;
+}
+#else
+static inline unsigned long get_clean_sp(struct pt_regs *regs, int is_32)
+{
+ return regs->gpr[1];
+}
+#endif
+
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
#endif /* _ASM_POWERPC_PROCESSOR_H */
diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index 67f1812698d2..cdb6fd814de8 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -50,6 +50,9 @@ enum ps3_param_av_multi_out {
enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void);
+extern u64 ps3_os_area_get_rtc_diff(void);
+extern void ps3_os_area_set_rtc_diff(u64 rtc_diff);
+
/* dma routines */
enum ps3_dma_page_size {
diff --git a/arch/powerpc/include/asm/ps3av.h b/arch/powerpc/include/asm/ps3av.h
index cd24ac16660a..0427b0b53d2d 100644
--- a/arch/powerpc/include/asm/ps3av.h
+++ b/arch/powerpc/include/asm/ps3av.h
@@ -730,7 +730,7 @@ extern int ps3av_cmd_av_get_hw_conf(struct ps3av_pkt_av_get_hw_conf *);
extern int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *,
u32);
-extern int ps3av_set_video_mode(u32);
+extern int ps3av_set_video_mode(int);
extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32);
extern int ps3av_get_auto_mode(void);
extern int ps3av_get_mode(void);
diff --git a/arch/powerpc/include/asm/ps3fb.h b/arch/powerpc/include/asm/ps3fb.h
index e7233a849680..90dbefb8cfc4 100644
--- a/arch/powerpc/include/asm/ps3fb.h
+++ b/arch/powerpc/include/asm/ps3fb.h
@@ -21,6 +21,7 @@
#include <linux/types.h>
#include <linux/ioctl.h>
+#include <linux/types.h>
/* ioctl */
#define PS3FB_IOCTL_SETMODE _IOW('r', 1, int) /* set video mode */
diff --git a/arch/powerpc/include/asm/pte-40x.h b/arch/powerpc/include/asm/pte-40x.h
new file mode 100644
index 000000000000..07630faae029
--- /dev/null
+++ b/arch/powerpc/include/asm/pte-40x.h
@@ -0,0 +1,64 @@
+#ifndef _ASM_POWERPC_PTE_40x_H
+#define _ASM_POWERPC_PTE_40x_H
+#ifdef __KERNEL__
+
+/*
+ * At present, all PowerPC 400-class processors share a similar TLB
+ * architecture. The instruction and data sides share a unified,
+ * 64-entry, fully-associative TLB which is maintained totally under
+ * software control. In addition, the instruction side has a
+ * hardware-managed, 4-entry, fully-associative TLB which serves as a
+ * first level to the shared TLB. These two TLBs are known as the UTLB
+ * and ITLB, respectively (see "mmu.h" for definitions).
+ *
+ * There are several potential gotchas here. The 40x hardware TLBLO
+ * field looks like this:
+ *
+ * 0 1 2 3 4 ... 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ * RPN..................... 0 0 EX WR ZSEL....... W I M G
+ *
+ * Where possible we make the Linux PTE bits match up with this
+ *
+ * - bits 20 and 21 must be cleared, because we use 4k pages (40x can
+ * support down to 1k pages), this is done in the TLBMiss exception
+ * handler.
+ * - We use only zones 0 (for kernel pages) and 1 (for user pages)
+ * of the 16 available. Bit 24-26 of the TLB are cleared in the TLB
+ * miss handler. Bit 27 is PAGE_USER, thus selecting the correct
+ * zone.
+ * - PRESENT *must* be in the bottom two bits because swap cache
+ * entries use the top 30 bits. Because 40x doesn't support SMP
+ * anyway, M is irrelevant so we borrow it for PAGE_PRESENT. Bit 30
+ * is cleared in the TLB miss handler before the TLB entry is loaded.
+ * - All other bits of the PTE are loaded into TLBLO without
+ * modification, leaving us only the bits 20, 21, 24, 25, 26, 30 for
+ * software PTE bits. We actually use use bits 21, 24, 25, and
+ * 30 respectively for the software bits: ACCESSED, DIRTY, RW, and
+ * PRESENT.
+ */
+
+#define _PAGE_GUARDED 0x001 /* G: page is guarded from prefetch */
+#define _PAGE_FILE 0x001 /* when !present: nonlinear file mapping */
+#define _PAGE_PRESENT 0x002 /* software: PTE contains a translation */
+#define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */
+#define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */
+#define _PAGE_USER 0x010 /* matches one of the zone permission bits */
+#define _PAGE_RW 0x040 /* software: Writes permitted */
+#define _PAGE_DIRTY 0x080 /* software: dirty page */
+#define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */
+#define _PAGE_HWEXEC 0x200 /* hardware: EX permission */
+#define _PAGE_ACCESSED 0x400 /* software: R: page referenced */
+
+#define _PMD_PRESENT 0x400 /* PMD points to page of PTEs */
+#define _PMD_BAD 0x802
+#define _PMD_SIZE 0x0e0 /* size field, != 0 for large-page PMD entry */
+#define _PMD_SIZE_4M 0x0c0
+#define _PMD_SIZE_16M 0x0e0
+
+#define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4))
+
+/* Until my rework is finished, 40x still needs atomic PTE updates */
+#define PTE_ATOMIC_UPDATES 1
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_PTE_40x_H */
diff --git a/arch/powerpc/include/asm/pte-44x.h b/arch/powerpc/include/asm/pte-44x.h
new file mode 100644
index 000000000000..37e98bcf83e0
--- /dev/null
+++ b/arch/powerpc/include/asm/pte-44x.h
@@ -0,0 +1,102 @@
+#ifndef _ASM_POWERPC_PTE_44x_H
+#define _ASM_POWERPC_PTE_44x_H
+#ifdef __KERNEL__
+
+/*
+ * Definitions for PPC440
+ *
+ * Because of the 3 word TLB entries to support 36-bit addressing,
+ * the attribute are difficult to map in such a fashion that they
+ * are easily loaded during exception processing. I decided to
+ * organize the entry so the ERPN is the only portion in the
+ * upper word of the PTE and the attribute bits below are packed
+ * in as sensibly as they can be in the area below a 4KB page size
+ * oriented RPN. This at least makes it easy to load the RPN and
+ * ERPN fields in the TLB. -Matt
+ *
+ * This isn't entirely true anymore, at least some bits are now
+ * easier to move into the TLB from the PTE. -BenH.
+ *
+ * Note that these bits preclude future use of a page size
+ * less than 4KB.
+ *
+ *
+ * PPC 440 core has following TLB attribute fields;
+ *
+ * TLB1:
+ * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ * RPN................................. - - - - - - ERPN.......
+ *
+ * TLB2:
+ * 0 1 2 3 4 ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ * - - - - - - U0 U1 U2 U3 W I M G E - UX UW UR SX SW SR
+ *
+ * Newer 440 cores (440x6 as used on AMCC 460EX/460GT) have additional
+ * TLB2 storage attibute fields. Those are:
+ *
+ * TLB2:
+ * 0...10 11 12 13 14 15 16...31
+ * no change WL1 IL1I IL1D IL2I IL2D no change
+ *
+ * There are some constrains and options, to decide mapping software bits
+ * into TLB entry.
+ *
+ * - PRESENT *must* be in the bottom three bits because swap cache
+ * entries use the top 29 bits for TLB2.
+ *
+ * - FILE *must* be in the bottom three bits because swap cache
+ * entries use the top 29 bits for TLB2.
+ *
+ * - CACHE COHERENT bit (M) has no effect on original PPC440 cores,
+ * because it doesn't support SMP. However, some later 460 variants
+ * have -some- form of SMP support and so I keep the bit there for
+ * future use
+ *
+ * With the PPC 44x Linux implementation, the 0-11th LSBs of the PTE are used
+ * for memory protection related functions (see PTE structure in
+ * include/asm-ppc/mmu.h). The _PAGE_XXX definitions in this file map to the
+ * above bits. Note that the bit values are CPU specific, not architecture
+ * specific.
+ *
+ * The kernel PTE entry holds an arch-dependent swp_entry structure under
+ * certain situations. In other words, in such situations some portion of
+ * the PTE bits are used as a swp_entry. In the PPC implementation, the
+ * 3-24th LSB are shared with swp_entry, however the 0-2nd three LSB still
+ * hold protection values. That means the three protection bits are
+ * reserved for both PTE and SWAP entry at the most significant three
+ * LSBs.
+ *
+ * There are three protection bits available for SWAP entry:
+ * _PAGE_PRESENT
+ * _PAGE_FILE
+ * _PAGE_HASHPTE (if HW has)
+ *
+ * So those three bits have to be inside of 0-2nd LSB of PTE.
+ *
+ */
+
+#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */
+#define _PAGE_RW 0x00000002 /* S: Write permission */
+#define _PAGE_FILE 0x00000004 /* S: nonlinear file mapping */
+#define _PAGE_HWEXEC 0x00000004 /* H: Execute permission */
+#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */
+#define _PAGE_DIRTY 0x00000010 /* S: Page dirty */
+#define _PAGE_SPECIAL 0x00000020 /* S: Special page */
+#define _PAGE_USER 0x00000040 /* S: User page */
+#define _PAGE_ENDIAN 0x00000080 /* H: E bit */
+#define _PAGE_GUARDED 0x00000100 /* H: G bit */
+#define _PAGE_COHERENT 0x00000200 /* H: M bit */
+#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */
+#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */
+
+/* TODO: Add large page lowmem mapping support */
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+
+/* ERPN in a PTE never gets cleared, ignore it */
+#define _PTE_NONE_MASK 0xffffffff00000000ULL
+
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_PTE_44x_H */
diff --git a/arch/powerpc/include/asm/pte-8xx.h b/arch/powerpc/include/asm/pte-8xx.h
new file mode 100644
index 000000000000..8c6e31251034
--- /dev/null
+++ b/arch/powerpc/include/asm/pte-8xx.h
@@ -0,0 +1,67 @@
+#ifndef _ASM_POWERPC_PTE_8xx_H
+#define _ASM_POWERPC_PTE_8xx_H
+#ifdef __KERNEL__
+
+/*
+ * The PowerPC MPC8xx uses a TLB with hardware assisted, software tablewalk.
+ * We also use the two level tables, but we can put the real bits in them
+ * needed for the TLB and tablewalk. These definitions require Mx_CTR.PPM = 0,
+ * Mx_CTR.PPCS = 0, and MD_CTR.TWAM = 1. The level 2 descriptor has
+ * additional page protection (when Mx_CTR.PPCS = 1) that allows TLB hit
+ * based upon user/super access. The TLB does not have accessed nor write
+ * protect. We assume that if the TLB get loaded with an entry it is
+ * accessed, and overload the changed bit for write protect. We use
+ * two bits in the software pte that are supposed to be set to zero in
+ * the TLB entry (24 and 25) for these indicators. Although the level 1
+ * descriptor contains the guarded and writethrough/copyback bits, we can
+ * set these at the page level since they get copied from the Mx_TWC
+ * register when the TLB entry is loaded. We will use bit 27 for guard, since
+ * that is where it exists in the MD_TWC, and bit 26 for writethrough.
+ * These will get masked from the level 2 descriptor at TLB load time, and
+ * copied to the MD_TWC before it gets loaded.
+ * Large page sizes added. We currently support two sizes, 4K and 8M.
+ * This also allows a TLB hander optimization because we can directly
+ * load the PMD into MD_TWC. The 8M pages are only used for kernel
+ * mapping of well known areas. The PMD (PGD) entries contain control
+ * flags in addition to the address, so care must be taken that the
+ * software no longer assumes these are only pointers.
+ */
+
+/* Definitions for 8xx embedded chips. */
+#define _PAGE_PRESENT 0x0001 /* Page is valid */
+#define _PAGE_FILE 0x0002 /* when !present: nonlinear file mapping */
+#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */
+#define _PAGE_SHARED 0x0004 /* No ASID (context) compare */
+
+/* These five software bits must be masked out when the entry is loaded
+ * into the TLB.
+ */
+#define _PAGE_EXEC 0x0008 /* software: i-cache coherency required */
+#define _PAGE_GUARDED 0x0010 /* software: guarded access */
+#define _PAGE_DIRTY 0x0020 /* software: page changed */
+#define _PAGE_RW 0x0040 /* software: user write access allowed */
+#define _PAGE_ACCESSED 0x0080 /* software: page referenced */
+
+/* Setting any bits in the nibble with the follow two controls will
+ * require a TLB exception handler change. It is assumed unused bits
+ * are always zero.
+ */
+#define _PAGE_HWWRITE 0x0100 /* h/w write enable: never set in Linux PTE */
+#define _PAGE_USER 0x0800 /* One of the PP bits, the other is USER&~RW */
+
+#define _PMD_PRESENT 0x0001
+#define _PMD_BAD 0x0ff0
+#define _PMD_PAGE_MASK 0x000c
+#define _PMD_PAGE_8M 0x000c
+
+#define _PTE_NONE_MASK _PAGE_ACCESSED
+
+/* Until my rework is finished, 8xx still needs atomic PTE updates */
+#define PTE_ATOMIC_UPDATES 1
+
+/* We need to add _PAGE_SHARED to kernel pages */
+#define _PAGE_KERNEL_RO (_PAGE_SHARED)
+#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_PTE_8xx_H */
diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h
new file mode 100644
index 000000000000..d9740e886801
--- /dev/null
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -0,0 +1,180 @@
+/* Included from asm/pgtable-*.h only ! */
+
+/*
+ * Some bits are only used on some cpu families... Make sure that all
+ * the undefined gets a sensible default
+ */
+#ifndef _PAGE_HASHPTE
+#define _PAGE_HASHPTE 0
+#endif
+#ifndef _PAGE_SHARED
+#define _PAGE_SHARED 0
+#endif
+#ifndef _PAGE_HWWRITE
+#define _PAGE_HWWRITE 0
+#endif
+#ifndef _PAGE_HWEXEC
+#define _PAGE_HWEXEC 0
+#endif
+#ifndef _PAGE_EXEC
+#define _PAGE_EXEC 0
+#endif
+#ifndef _PAGE_ENDIAN
+#define _PAGE_ENDIAN 0
+#endif
+#ifndef _PAGE_COHERENT
+#define _PAGE_COHERENT 0
+#endif
+#ifndef _PAGE_WRITETHRU
+#define _PAGE_WRITETHRU 0
+#endif
+#ifndef _PAGE_SPECIAL
+#define _PAGE_SPECIAL 0
+#endif
+#ifndef _PAGE_4K_PFN
+#define _PAGE_4K_PFN 0
+#endif
+#ifndef _PAGE_PSIZE
+#define _PAGE_PSIZE 0
+#endif
+#ifndef _PMD_PRESENT_MASK
+#define _PMD_PRESENT_MASK _PMD_PRESENT
+#endif
+#ifndef _PMD_SIZE
+#define _PMD_SIZE 0
+#define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE()
+#endif
+#ifndef _PAGE_KERNEL_RO
+#define _PAGE_KERNEL_RO 0
+#endif
+#ifndef _PAGE_KERNEL_RW
+#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
+#endif
+#ifndef _PAGE_HPTEFLAGS
+#define _PAGE_HPTEFLAGS _PAGE_HASHPTE
+#endif
+#ifndef _PTE_NONE_MASK
+#define _PTE_NONE_MASK _PAGE_HPTEFLAGS
+#endif
+
+/* Make sure we get a link error if PMD_PAGE_SIZE is ever called on a
+ * kernel without large page PMD support
+ */
+#ifndef __ASSEMBLY__
+extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
+#endif /* __ASSEMBLY__ */
+
+/* Location of the PFN in the PTE. Most 32-bit platforms use the same
+ * as _PAGE_SHIFT here (ie, naturally aligned).
+ * Platform who don't just pre-define the value so we don't override it here
+ */
+#ifndef PTE_RPN_SHIFT
+#define PTE_RPN_SHIFT (PAGE_SHIFT)
+#endif
+
+/* The mask convered by the RPN must be a ULL on 32-bit platforms with
+ * 64-bit PTEs
+ */
+#if defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT)
+#define PTE_RPN_MAX (1ULL << (64 - PTE_RPN_SHIFT))
+#define PTE_RPN_MASK (~((1ULL<<PTE_RPN_SHIFT)-1))
+#else
+#define PTE_RPN_MAX (1UL << (32 - PTE_RPN_SHIFT))
+#define PTE_RPN_MASK (~((1UL<<PTE_RPN_SHIFT)-1))
+#endif
+
+/* _PAGE_CHG_MASK masks of bits that are to be preserved accross
+ * pgprot changes
+ */
+#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \
+ _PAGE_ACCESSED | _PAGE_SPECIAL)
+
+/* Mask of bits returned by pte_pgprot() */
+#define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
+ _PAGE_WRITETHRU | _PAGE_ENDIAN | _PAGE_4K_PFN | \
+ _PAGE_USER | _PAGE_ACCESSED | \
+ _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \
+ _PAGE_EXEC | _PAGE_HWEXEC)
+
+/*
+ * We define 2 sets of base prot bits, one for basic pages (ie,
+ * cacheable kernel and user pages) and one for non cacheable
+ * pages. We always set _PAGE_COHERENT when SMP is enabled or
+ * the processor might need it for DMA coherency.
+ */
+#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_PSIZE)
+#if defined(CONFIG_SMP) || defined(CONFIG_PPC_STD_MMU)
+#define _PAGE_BASE (_PAGE_BASE_NC | _PAGE_COHERENT)
+#else
+#define _PAGE_BASE (_PAGE_BASE_NC)
+#endif
+
+/* Permission masks used to generate the __P and __S table,
+ *
+ * Note:__pgprot is defined in arch/powerpc/include/asm/page.h
+ *
+ * Write permissions imply read permissions for now (we could make write-only
+ * pages on BookE but we don't bother for now). Execute permission control is
+ * possible on platforms that define _PAGE_EXEC
+ *
+ * Note due to the way vm flags are laid out, the bits are XWR
+ */
+#define PAGE_NONE __pgprot(_PAGE_BASE)
+#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
+#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
+#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
+#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
+
+#define __P000 PAGE_NONE
+#define __P001 PAGE_READONLY
+#define __P010 PAGE_COPY
+#define __P011 PAGE_COPY
+#define __P100 PAGE_READONLY_X
+#define __P101 PAGE_READONLY_X
+#define __P110 PAGE_COPY_X
+#define __P111 PAGE_COPY_X
+
+#define __S000 PAGE_NONE
+#define __S001 PAGE_READONLY
+#define __S010 PAGE_SHARED
+#define __S011 PAGE_SHARED
+#define __S100 PAGE_READONLY_X
+#define __S101 PAGE_READONLY_X
+#define __S110 PAGE_SHARED_X
+#define __S111 PAGE_SHARED_X
+
+/* Permission masks used for kernel mappings */
+#define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW)
+#define PAGE_KERNEL_NC __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
+ _PAGE_NO_CACHE)
+#define PAGE_KERNEL_NCG __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
+ _PAGE_NO_CACHE | _PAGE_GUARDED)
+#define PAGE_KERNEL_X __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW | _PAGE_EXEC)
+#define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO)
+#define PAGE_KERNEL_ROX __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO | _PAGE_EXEC)
+
+/* Protection used for kernel text. We want the debuggers to be able to
+ * set breakpoints anywhere, so don't write protect the kernel text
+ * on platforms where such control is possible.
+ */
+#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) ||\
+ defined(CONFIG_KPROBES)
+#define PAGE_KERNEL_TEXT PAGE_KERNEL_X
+#else
+#define PAGE_KERNEL_TEXT PAGE_KERNEL_ROX
+#endif
+
+/* Make modules code happy. We don't set RO yet */
+#define PAGE_KERNEL_EXEC PAGE_KERNEL_X
+
+/* Advertise special mapping type for AGP */
+#define PAGE_AGP (PAGE_KERNEL_NC)
+#define HAVE_PAGE_AGP
+
+/* Advertise support for _PAGE_SPECIAL */
+#ifdef _PAGE_SPECIAL
+#define __HAVE_ARCH_PTE_SPECIAL
+#endif
+
diff --git a/arch/powerpc/include/asm/pte-fsl-booke.h b/arch/powerpc/include/asm/pte-fsl-booke.h
new file mode 100644
index 000000000000..10820f58acf5
--- /dev/null
+++ b/arch/powerpc/include/asm/pte-fsl-booke.h
@@ -0,0 +1,48 @@
+#ifndef _ASM_POWERPC_PTE_FSL_BOOKE_H
+#define _ASM_POWERPC_PTE_FSL_BOOKE_H
+#ifdef __KERNEL__
+
+/* PTE bit definitions for Freescale BookE SW loaded TLB MMU based
+ * processors
+ *
+ MMU Assist Register 3:
+
+ 32 33 34 35 36 ... 50 51 52 53 54 55 56 57 58 59 60 61 62 63
+ RPN...................... 0 0 U0 U1 U2 U3 UX SX UW SW UR SR
+
+ - PRESENT *must* be in the bottom three bits because swap cache
+ entries use the top 29 bits.
+
+ - FILE *must* be in the bottom three bits because swap cache
+ entries use the top 29 bits.
+*/
+
+/* Definitions for FSL Book-E Cores */
+#define _PAGE_PRESENT 0x00001 /* S: PTE contains a translation */
+#define _PAGE_USER 0x00002 /* S: User page (maps to UR) */
+#define _PAGE_FILE 0x00002 /* S: when !present: nonlinear file mapping */
+#define _PAGE_RW 0x00004 /* S: Write permission (SW) */
+#define _PAGE_DIRTY 0x00008 /* S: Page dirty */
+#define _PAGE_HWEXEC 0x00010 /* H: SX permission */
+#define _PAGE_ACCESSED 0x00020 /* S: Page referenced */
+
+#define _PAGE_ENDIAN 0x00040 /* H: E bit */
+#define _PAGE_GUARDED 0x00080 /* H: G bit */
+#define _PAGE_COHERENT 0x00100 /* H: M bit */
+#define _PAGE_NO_CACHE 0x00200 /* H: I bit */
+#define _PAGE_WRITETHRU 0x00400 /* H: W bit */
+#define _PAGE_SPECIAL 0x00800 /* S: Special page */
+
+#ifdef CONFIG_PTE_64BIT
+/* ERPN in a PTE never gets cleared, ignore it */
+#define _PTE_NONE_MASK 0xffffffffffff0000ULL
+/* We extend the size of the PTE flags area when using 64-bit PTEs */
+#define PTE_RPN_SHIFT (PAGE_SHIFT + 8)
+#endif
+
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_PTE_FSL_BOOKE_H */
diff --git a/arch/powerpc/include/asm/pte-hash32.h b/arch/powerpc/include/asm/pte-hash32.h
new file mode 100644
index 000000000000..16e571c7f9ef
--- /dev/null
+++ b/arch/powerpc/include/asm/pte-hash32.h
@@ -0,0 +1,48 @@
+#ifndef _ASM_POWERPC_PTE_HASH32_H
+#define _ASM_POWERPC_PTE_HASH32_H
+#ifdef __KERNEL__
+
+/*
+ * The "classic" 32-bit implementation of the PowerPC MMU uses a hash
+ * table containing PTEs, together with a set of 16 segment registers,
+ * to define the virtual to physical address mapping.
+ *
+ * We use the hash table as an extended TLB, i.e. a cache of currently
+ * active mappings. We maintain a two-level page table tree, much
+ * like that used by the i386, for the sake of the Linux memory
+ * management code. Low-level assembler code in hash_low_32.S
+ * (procedure hash_page) is responsible for extracting ptes from the
+ * tree and putting them into the hash table when necessary, and
+ * updating the accessed and modified bits in the page table tree.
+ */
+
+#define _PAGE_PRESENT 0x001 /* software: pte contains a translation */
+#define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */
+#define _PAGE_FILE 0x004 /* when !present: nonlinear file mapping */
+#define _PAGE_USER 0x004 /* usermode access allowed */
+#define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */
+#define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */
+#define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */
+#define _PAGE_WRITETHRU 0x040 /* W: cache write-through */
+#define _PAGE_DIRTY 0x080 /* C: page changed */
+#define _PAGE_ACCESSED 0x100 /* R: page referenced */
+#define _PAGE_EXEC 0x200 /* software: i-cache coherency required */
+#define _PAGE_RW 0x400 /* software: user write access allowed */
+#define _PAGE_SPECIAL 0x800 /* software: Special page */
+
+#ifdef CONFIG_PTE_64BIT
+/* We never clear the high word of the pte */
+#define _PTE_NONE_MASK (0xffffffff00000000ULL | _PAGE_HASHPTE)
+#else
+#define _PTE_NONE_MASK _PAGE_HASHPTE
+#endif
+
+#define _PMD_PRESENT 0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD (~PAGE_MASK)
+
+/* Hash table based platforms need atomic updates of the linux PTE */
+#define PTE_ATOMIC_UPDATES 1
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_PTE_HASH32_H */
diff --git a/arch/powerpc/include/asm/pte-hash64-4k.h b/arch/powerpc/include/asm/pte-hash64-4k.h
new file mode 100644
index 000000000000..c134e809aac3
--- /dev/null
+++ b/arch/powerpc/include/asm/pte-hash64-4k.h
@@ -0,0 +1,17 @@
+/* To be include by pgtable-hash64.h only */
+
+/* PTE bits */
+#define _PAGE_HASHPTE 0x0400 /* software: pte has an associated HPTE */
+#define _PAGE_SECONDARY 0x8000 /* software: HPTE is in secondary group */
+#define _PAGE_GROUP_IX 0x7000 /* software: HPTE index within group */
+#define _PAGE_F_SECOND _PAGE_SECONDARY
+#define _PAGE_F_GIX _PAGE_GROUP_IX
+#define _PAGE_SPECIAL 0x10000 /* software: special page */
+
+/* PTE flags to conserve for HPTE identification */
+#define _PAGE_HPTEFLAGS (_PAGE_BUSY | _PAGE_HASHPTE | \
+ _PAGE_SECONDARY | _PAGE_GROUP_IX)
+
+/* shift to put page number into pte */
+#define PTE_RPN_SHIFT (17)
+
diff --git a/arch/powerpc/include/asm/pgtable-64k.h b/arch/powerpc/include/asm/pte-hash64-64k.h
index 7389003349a6..e05d26fa372f 100644
--- a/arch/powerpc/include/asm/pgtable-64k.h
+++ b/arch/powerpc/include/asm/pte-hash64-64k.h
@@ -1,76 +1,6 @@
-#ifndef _ASM_POWERPC_PGTABLE_64K_H
-#define _ASM_POWERPC_PGTABLE_64K_H
-
-#include <asm-generic/pgtable-nopud.h>
-
-
-#define PTE_INDEX_SIZE 12
-#define PMD_INDEX_SIZE 12
-#define PUD_INDEX_SIZE 0
-#define PGD_INDEX_SIZE 4
-
-#ifndef __ASSEMBLY__
-#define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE)
-#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
-#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
-
-#define PTRS_PER_PTE (1 << PTE_INDEX_SIZE)
-#define PTRS_PER_PMD (1 << PMD_INDEX_SIZE)
-#define PTRS_PER_PGD (1 << PGD_INDEX_SIZE)
-
-#ifdef CONFIG_PPC_SUBPAGE_PROT
-/*
- * For the sub-page protection option, we extend the PGD with one of
- * these. Basically we have a 3-level tree, with the top level being
- * the protptrs array. To optimize speed and memory consumption when
- * only addresses < 4GB are being protected, pointers to the first
- * four pages of sub-page protection words are stored in the low_prot
- * array.
- * Each page of sub-page protection words protects 1GB (4 bytes
- * protects 64k). For the 3-level tree, each page of pointers then
- * protects 8TB.
- */
-struct subpage_prot_table {
- unsigned long maxaddr; /* only addresses < this are protected */
- unsigned int **protptrs[2];
- unsigned int *low_prot[4];
-};
-
-#undef PGD_TABLE_SIZE
-#define PGD_TABLE_SIZE ((sizeof(pgd_t) << PGD_INDEX_SIZE) + \
- sizeof(struct subpage_prot_table))
-
-#define SBP_L1_BITS (PAGE_SHIFT - 2)
-#define SBP_L2_BITS (PAGE_SHIFT - 3)
-#define SBP_L1_COUNT (1 << SBP_L1_BITS)
-#define SBP_L2_COUNT (1 << SBP_L2_BITS)
-#define SBP_L2_SHIFT (PAGE_SHIFT + SBP_L1_BITS)
-#define SBP_L3_SHIFT (SBP_L2_SHIFT + SBP_L2_BITS)
-
-extern void subpage_prot_free(pgd_t *pgd);
-
-static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd)
-{
- return (struct subpage_prot_table *)(pgd + PTRS_PER_PGD);
-}
-#endif /* CONFIG_PPC_SUBPAGE_PROT */
-#endif /* __ASSEMBLY__ */
-
-/* With 4k base page size, hugepage PTEs go at the PMD level */
-#define MIN_HUGEPTE_SHIFT PAGE_SHIFT
-
-/* PMD_SHIFT determines what a second-level page table entry can map */
-#define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE)
-#define PMD_SIZE (1UL << PMD_SHIFT)
-#define PMD_MASK (~(PMD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE)
-#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
-#define PGDIR_MASK (~(PGDIR_SIZE-1))
+/* To be include by pgtable-hash64.h only */
/* Additional PTE bits (don't change without checking asm in hash_low.S) */
-#define __HAVE_ARCH_PTE_SPECIAL
#define _PAGE_SPECIAL 0x00000400 /* software: special page */
#define _PAGE_HPTE_SUB 0x0ffff000 /* combo only: sub pages HPTE bits */
#define _PAGE_HPTE_SUB0 0x08000000 /* combo only: first sub page */
@@ -107,21 +37,15 @@ static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd)
* of addressable physical space, or 46 bits for the special 4k PFNs.
*/
#define PTE_RPN_SHIFT (30)
-#define PTE_RPN_MAX (1UL << (64 - PTE_RPN_SHIFT))
-#define PTE_RPN_MASK (~((1UL<<PTE_RPN_SHIFT)-1))
-
-/* _PAGE_CHG_MASK masks of bits that are to be preserved accross
- * pgprot changes
- */
-#define _PAGE_CHG_MASK (PTE_RPN_MASK | _PAGE_HPTEFLAGS | _PAGE_DIRTY | \
- _PAGE_ACCESSED | _PAGE_SPECIAL)
-/* Bits to mask out from a PMD to get to the PTE page */
-#define PMD_MASKED_BITS 0x1ff
-/* Bits to mask out from a PGD/PUD to get to the PMD page */
-#define PUD_MASKED_BITS 0x1ff
+#ifndef __ASSEMBLY__
-/* Manipulate "rpte" values */
+/*
+ * With 64K pages on hash table, we have a special PTE format that
+ * uses a second "half" of the page table to encode sub-page information
+ * in order to deal with 64K made of 4K HW pages. Thus we override the
+ * generic accessors and iterators here
+ */
#define __real_pte(e,p) ((real_pte_t) { \
(e), pte_val(*((p) + PTRS_PER_PTE)) })
#define __rpte_to_hidx(r,index) ((pte_val((r).pte) & _PAGE_COMBO) ? \
@@ -130,7 +54,6 @@ static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd)
#define __rpte_sub_valid(rpte, index) \
(pte_val(rpte.pte) & (_PAGE_HPTE_SUB0 >> (index)))
-
/* Trick: we set __end to va + 64k, which happens works for
* a 16M page as well as we want only one iteration
*/
@@ -152,4 +75,41 @@ static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd)
remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \
__pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))
-#endif /* _ASM_POWERPC_PGTABLE_64K_H */
+
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+/*
+ * For the sub-page protection option, we extend the PGD with one of
+ * these. Basically we have a 3-level tree, with the top level being
+ * the protptrs array. To optimize speed and memory consumption when
+ * only addresses < 4GB are being protected, pointers to the first
+ * four pages of sub-page protection words are stored in the low_prot
+ * array.
+ * Each page of sub-page protection words protects 1GB (4 bytes
+ * protects 64k). For the 3-level tree, each page of pointers then
+ * protects 8TB.
+ */
+struct subpage_prot_table {
+ unsigned long maxaddr; /* only addresses < this are protected */
+ unsigned int **protptrs[2];
+ unsigned int *low_prot[4];
+};
+
+#undef PGD_TABLE_SIZE
+#define PGD_TABLE_SIZE ((sizeof(pgd_t) << PGD_INDEX_SIZE) + \
+ sizeof(struct subpage_prot_table))
+
+#define SBP_L1_BITS (PAGE_SHIFT - 2)
+#define SBP_L2_BITS (PAGE_SHIFT - 3)
+#define SBP_L1_COUNT (1 << SBP_L1_BITS)
+#define SBP_L2_COUNT (1 << SBP_L2_BITS)
+#define SBP_L2_SHIFT (PAGE_SHIFT + SBP_L1_BITS)
+#define SBP_L3_SHIFT (SBP_L2_SHIFT + SBP_L2_BITS)
+
+extern void subpage_prot_free(pgd_t *pgd);
+
+static inline struct subpage_prot_table *pgd_subpage_prot(pgd_t *pgd)
+{
+ return (struct subpage_prot_table *)(pgd + PTRS_PER_PGD);
+}
+#endif /* CONFIG_PPC_SUBPAGE_PROT */
+#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/include/asm/pte-hash64.h b/arch/powerpc/include/asm/pte-hash64.h
new file mode 100644
index 000000000000..0419eeb53274
--- /dev/null
+++ b/arch/powerpc/include/asm/pte-hash64.h
@@ -0,0 +1,54 @@
+#ifndef _ASM_POWERPC_PTE_HASH64_H
+#define _ASM_POWERPC_PTE_HASH64_H
+#ifdef __KERNEL__
+
+/*
+ * Common bits between 4K and 64K pages in a linux-style PTE.
+ * These match the bits in the (hardware-defined) PowerPC PTE as closely
+ * as possible. Additional bits may be defined in pgtable-hash64-*.h
+ *
+ * Note: We only support user read/write permissions. Supervisor always
+ * have full read/write to pages above PAGE_OFFSET (pages below that
+ * always use the user access permissions).
+ *
+ * We could create separate kernel read-only if we used the 3 PP bits
+ * combinations that newer processors provide but we currently don't.
+ */
+#define _PAGE_PRESENT 0x0001 /* software: pte contains a translation */
+#define _PAGE_USER 0x0002 /* matches one of the PP bits */
+#define _PAGE_FILE 0x0002 /* (!present only) software: pte holds file offset */
+#define _PAGE_EXEC 0x0004 /* No execute on POWER4 and newer (we invert) */
+#define _PAGE_GUARDED 0x0008
+#define _PAGE_COHERENT 0x0010 /* M: enforce memory coherence (SMP systems) */
+#define _PAGE_NO_CACHE 0x0020 /* I: cache inhibit */
+#define _PAGE_WRITETHRU 0x0040 /* W: cache write-through */
+#define _PAGE_DIRTY 0x0080 /* C: page changed */
+#define _PAGE_ACCESSED 0x0100 /* R: page referenced */
+#define _PAGE_RW 0x0200 /* software: user write access allowed */
+#define _PAGE_BUSY 0x0800 /* software: PTE & hash are busy */
+
+/* No separate kernel read-only */
+#define _PAGE_KERNEL_RW (_PAGE_RW | _PAGE_DIRTY) /* user access blocked by key */
+#define _PAGE_KERNEL_RO _PAGE_KERNEL_RW
+
+/* Strong Access Ordering */
+#define _PAGE_SAO (_PAGE_WRITETHRU | _PAGE_NO_CACHE | _PAGE_COHERENT)
+
+/* No page size encoding in the linux PTE */
+#define _PAGE_PSIZE 0
+
+/* PTEIDX nibble */
+#define _PTEIDX_SECONDARY 0x8
+#define _PTEIDX_GROUP_IX 0x7
+
+/* Hash table based platforms need atomic updates of the linux PTE */
+#define PTE_ATOMIC_UPDATES 1
+
+#ifdef CONFIG_PPC_64K_PAGES
+#include <asm/pte-hash64-64k.h>
+#else
+#include <asm/pte-hash64-4k.h>
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_PTE_HASH64_H */
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index f484a343efba..c9ff1ec97479 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -155,6 +155,8 @@
#define CTRL_RUNLATCH 0x1
#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */
#define DABR_TRANSLATION (1UL << 2)
+#define DABR_DATA_WRITE (1UL << 1)
+#define DABR_DATA_READ (1UL << 0)
#define SPRN_DABR2 0x13D /* e300 */
#define SPRN_DABRX 0x3F7 /* Data Address Breakpoint Register Extension */
#define DABRX_USER (1UL << 0)
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 67453766bff1..a56f4d61aa72 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -10,6 +10,7 @@
#define __ASM_POWERPC_REG_BOOKE_H__
/* Machine State Register (MSR) Fields */
+#define MSR_GS (1<<28) /* Guest state */
#define MSR_UCLE (1<<26) /* User-mode cache lock enable */
#define MSR_SPE (1<<25) /* Enable SPE */
#define MSR_DWE (1<<10) /* Debug Wait Enable */
@@ -110,6 +111,7 @@
#define SPRN_L1CSR0 0x3F2 /* L1 Cache Control and Status Register 0 */
#define SPRN_L1CSR1 0x3F3 /* L1 Cache Control and Status Register 1 */
#define SPRN_MMUCSR0 0x3F4 /* MMU Control and Status Register 0 */
+#define SPRN_MMUCFG 0x3F7 /* MMU Configuration Register */
#define SPRN_PIT 0x3DB /* Programmable Interval Timer */
#define SPRN_BUCSR 0x3F5 /* Branch Unit Control and Status */
#define SPRN_L2CSR0 0x3F9 /* L2 Data Cache Control and Status Register 0 */
diff --git a/arch/powerpc/include/asm/socket.h b/arch/powerpc/include/asm/socket.h
index f5a4e168e498..1e5cfad0e3f7 100644
--- a/arch/powerpc/include/asm/socket.h
+++ b/arch/powerpc/include/asm/socket.h
@@ -61,4 +61,7 @@
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
#endif /* _ASM_POWERPC_SOCKET_H */
diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h
index 36864364e601..c3b193121f81 100644
--- a/arch/powerpc/include/asm/spinlock.h
+++ b/arch/powerpc/include/asm/spinlock.h
@@ -287,6 +287,9 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw)
rw->lock = 0;
}
+#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
+#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+
#define _raw_spin_relax(lock) __spin_yield(lock)
#define _raw_read_relax(lock) __rw_yield(lock)
#define _raw_write_relax(lock) __rw_yield(lock)
diff --git a/arch/powerpc/include/asm/suspend.h b/arch/powerpc/include/asm/suspend.h
index cbf2c9404c37..c6efc3466aa6 100644
--- a/arch/powerpc/include/asm/suspend.h
+++ b/arch/powerpc/include/asm/suspend.h
@@ -3,7 +3,4 @@
static inline int arch_prepare_suspend(void) { return 0; }
-void save_processor_state(void);
-void restore_processor_state(void);
-
#endif /* __ASM_POWERPC_SUSPEND_H */
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 72353f6070a4..fe166491e9dc 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -65,7 +65,7 @@ SYSCALL(ni_syscall)
SYSX(sys_ni_syscall,sys_olduname, sys_olduname)
COMPAT_SYS_SPU(umask)
SYSCALL_SPU(chroot)
-SYSCALL(ustat)
+COMPAT_SYS(ustat)
SYSCALL_SPU(dup2)
SYSCALL_SPU(getppid)
SYSCALL_SPU(getpgrp)
diff --git a/arch/powerpc/include/asm/system.h b/arch/powerpc/include/asm/system.h
index 2a4be19a92c4..f612798e1c93 100644
--- a/arch/powerpc/include/asm/system.h
+++ b/arch/powerpc/include/asm/system.h
@@ -531,7 +531,7 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
#endif
-#define arch_align_stack(x) (x)
+extern unsigned long arch_align_stack(unsigned long sp);
/* Used in very early kernel initialization. */
extern unsigned long reloc_offset(void);
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index 9665a26a253a..9aba5a38a7c4 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -12,8 +12,10 @@
/* We have 8k stacks on ppc32 and 16k on ppc64 */
-#ifdef CONFIG_PPC64
+#if defined(CONFIG_PPC64)
#define THREAD_SHIFT 14
+#elif defined(CONFIG_PPC_256K_PAGES)
+#define THREAD_SHIFT 15
#else
#define THREAD_SHIFT 13
#endif
@@ -154,6 +156,13 @@ static inline void set_restore_sigmask(void)
ti->local_flags |= _TLF_RESTORE_SIGMASK;
set_bit(TIF_SIGPENDING, &ti->flags);
}
+
+#ifdef CONFIG_PPC64
+#define is_32bit_task() (test_thread_flag(TIF_32BIT))
+#else
+#define is_32bit_task() (1)
+#endif
+
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index 375258559ae6..054a16d68082 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -24,11 +24,6 @@ static inline cpumask_t node_to_cpumask(int node)
#define cpumask_of_node(node) (&numa_cpumask_lookup_table[node])
-static inline int node_to_first_cpu(int node)
-{
- return cpumask_first(cpumask_of_node(node));
-}
-
int of_node_to_nid(struct device_node *device);
struct pci_bus;
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
index 6418ceea44b7..cd21e5e6b04f 100644
--- a/arch/powerpc/include/asm/udbg.h
+++ b/arch/powerpc/include/asm/udbg.h
@@ -15,6 +15,7 @@
#include <linux/init.h>
extern void (*udbg_putc)(char c);
+extern void (*udbg_flush)(void);
extern int (*udbg_getc)(void);
extern int (*udbg_getc_poll)(void);
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 8d1a419df35d..71901fbda4a5 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -18,12 +18,10 @@ CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog
CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog
CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog
CFLAGS_REMOVE_prom.o = -pg -mno-sched-epilog
-
-ifdef CONFIG_DYNAMIC_FTRACE
-# dynamic ftrace setup.
+# do not trace tracer code
CFLAGS_REMOVE_ftrace.o = -pg -mno-sched-epilog
-endif
-
+# timers used by tracing
+CFLAGS_REMOVE_time.o = -pg -mno-sched-epilog
endif
obj-y := cputable.o ptrace.o syscalls.o \
@@ -61,6 +59,7 @@ obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o \
obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o
obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o
obj-$(CONFIG_44x) += cpu_setup_44x.o
+obj-$(CONFIG_FSL_BOOKE) += cpu_setup_fsl_booke.o dbell.o
extra-$(CONFIG_PPC_STD_MMU) := head_32.o
extra-$(CONFIG_PPC64) := head_64.o
@@ -76,7 +75,7 @@ obj-y += time.o prom.o traps.o setup-common.o \
obj-$(CONFIG_PPC32) += entry_32.o setup_32.o
obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o
obj-$(CONFIG_KGDB) += kgdb.o
-obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
+obj-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o
obj-$(CONFIG_MODULES) += ppc_ksyms.o
obj-$(CONFIG_BOOTX_TEXT) += btext.o
obj-$(CONFIG_SMP) += smp.o
@@ -94,6 +93,7 @@ obj-$(CONFIG_AUDIT) += audit.o
obj64-$(CONFIG_AUDIT) += compat_audit.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
obj-$(CONFIG_8XX_MINIMAL_FPEMU) += softemu8xx.o
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index 73cb6a3229ae..5ffcfaa77d6a 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -187,7 +187,7 @@ static struct aligninfo aligninfo[128] = {
{ 4, ST+F+S+U }, /* 11 1 1010: stfsux */
{ 8, ST+F+U }, /* 11 1 1011: stfdux */
INVALID, /* 11 1 1100 */
- INVALID, /* 11 1 1101 */
+ { 4, LD+F }, /* 11 1 1101: lfiwzx */
INVALID, /* 11 1 1110 */
INVALID, /* 11 1 1111 */
};
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 19ee491e9e23..1e40bc053946 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -49,7 +49,7 @@
#include <asm/iseries/alpaca.h>
#endif
#ifdef CONFIG_KVM
-#include <asm/kvm_44x.h>
+#include <linux/kvm_host.h>
#endif
#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
@@ -284,9 +284,6 @@ int main(void)
#endif /* ! CONFIG_PPC64 */
/* About the CPU features table */
- DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
- DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
- DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
@@ -361,8 +358,6 @@ int main(void)
DEFINE(PTE_SIZE, sizeof(pte_t));
#ifdef CONFIG_KVM
- DEFINE(TLBE_BYTES, sizeof(struct kvmppc_44x_tlbe));
-
DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack));
DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
diff --git a/arch/powerpc/kernel/cpu_setup_44x.S b/arch/powerpc/kernel/cpu_setup_44x.S
index 10b4ab1008af..7d606f89a839 100644
--- a/arch/powerpc/kernel/cpu_setup_44x.S
+++ b/arch/powerpc/kernel/cpu_setup_44x.S
@@ -34,6 +34,7 @@ _GLOBAL(__setup_cpu_440grx)
blr
_GLOBAL(__setup_cpu_460ex)
_GLOBAL(__setup_cpu_460gt)
+_GLOBAL(__setup_cpu_460sx)
mflr r4
bl __init_fpu_44x
bl __fixup_440A_mcheck
diff --git a/arch/powerpc/kernel/cpu_setup_6xx.S b/arch/powerpc/kernel/cpu_setup_6xx.S
index 72d1d7395254..54f767e31a1a 100644
--- a/arch/powerpc/kernel/cpu_setup_6xx.S
+++ b/arch/powerpc/kernel/cpu_setup_6xx.S
@@ -15,9 +15,14 @@
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
#include <asm/cache.h>
+#include <asm/mmu.h>
_GLOBAL(__setup_cpu_603)
mflr r4
+BEGIN_MMU_FTR_SECTION
+ li r10,0
+ mtspr SPRN_SPRG4,r10 /* init SW LRU tracking */
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
BEGIN_FTR_SECTION
bl __init_fpu_registers
END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE)
diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
new file mode 100644
index 000000000000..eb4b9adcedb4
--- /dev/null
+++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S
@@ -0,0 +1,31 @@
+/*
+ * This file contains low level CPU setup functions.
+ * Kumar Gala <galak@kernel.crashing.org>
+ * Copyright 2009 Freescale Semiconductor, Inc.
+ *
+ * Based on cpu_setup_6xx code by
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <asm/processor.h>
+#include <asm/cputable.h>
+#include <asm/ppc_asm.h>
+
+_GLOBAL(__setup_cpu_e200)
+ /* enable dedicated debug exception handling resources (Debug APU) */
+ mfspr r3,SPRN_HID0
+ ori r3,r3,HID0_DAPUEN@l
+ mtspr SPRN_HID0,r3
+ b __setup_e200_ivors
+_GLOBAL(__setup_cpu_e500v1)
+_GLOBAL(__setup_cpu_e500v2)
+ b __setup_e500_ivors
+_GLOBAL(__setup_cpu_e500mc)
+ b __setup_e500mc_ivors
+
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 923f87aff20a..cd1b687544f3 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -35,6 +35,10 @@ const char *powerpc_base_platform;
* and ppc64
*/
#ifdef CONFIG_PPC32
+extern void __setup_cpu_e200(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_e500v1(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_e500v2(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_e500mc(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec);
@@ -43,6 +47,7 @@ extern void __setup_cpu_440spe(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_440x5(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_460ex(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_460gt(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_460sx(unsigned long offset, struct cpu_spec *spec);
extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
@@ -726,6 +731,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_750,
.machine_check = machine_check_generic,
.platform = "ppc750",
+ .oprofile_cpu_type = "ppc/750",
+ .oprofile_type = PPC_OPROFILE_G4,
},
{ /* 750FX rev 2.0 must disable HID0[DPM] */
.pvr_mask = 0xffffffff,
@@ -741,6 +748,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_750,
.machine_check = machine_check_generic,
.platform = "ppc750",
+ .oprofile_cpu_type = "ppc/750",
+ .oprofile_type = PPC_OPROFILE_G4,
},
{ /* 750FX (All revs except 2.0) */
.pvr_mask = 0xffff0000,
@@ -756,6 +765,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_750fx,
.machine_check = machine_check_generic,
.platform = "ppc750",
+ .oprofile_cpu_type = "ppc/750",
+ .oprofile_type = PPC_OPROFILE_G4,
},
{ /* 750GX */
.pvr_mask = 0xffff0000,
@@ -771,6 +782,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_setup = __setup_cpu_750fx,
.machine_check = machine_check_generic,
.platform = "ppc750",
+ .oprofile_cpu_type = "ppc/750",
+ .oprofile_type = PPC_OPROFILE_G4,
},
{ /* 740/750 (L2CR bit need fixup for 740) */
.pvr_mask = 0xffff0000,
@@ -1077,7 +1090,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "e300c2",
.cpu_features = CPU_FTRS_E300C2,
.cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
- .mmu_features = MMU_FTR_USE_HIGH_BATS,
+ .mmu_features = MMU_FTR_USE_HIGH_BATS |
+ MMU_FTR_NEED_DTLB_SW_LRU,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603,
@@ -1090,7 +1104,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "e300c3",
.cpu_features = CPU_FTRS_E300,
.cpu_user_features = COMMON_USER,
- .mmu_features = MMU_FTR_USE_HIGH_BATS,
+ .mmu_features = MMU_FTR_USE_HIGH_BATS |
+ MMU_FTR_NEED_DTLB_SW_LRU,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603,
@@ -1105,7 +1120,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "e300c4",
.cpu_features = CPU_FTRS_E300,
.cpu_user_features = COMMON_USER,
- .mmu_features = MMU_FTR_USE_HIGH_BATS,
+ .mmu_features = MMU_FTR_USE_HIGH_BATS |
+ MMU_FTR_NEED_DTLB_SW_LRU,
.icache_bsize = 32,
.dcache_bsize = 32,
.cpu_setup = __setup_cpu_603,
@@ -1634,6 +1650,19 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_440A,
.platform = "ppc440",
},
+ { /* 460SX */
+ .pvr_mask = 0xffffff00,
+ .pvr_value = 0x13541800,
+ .cpu_name = "460SX",
+ .cpu_features = CPU_FTRS_44X,
+ .cpu_user_features = COMMON_USER_BOOKE,
+ .mmu_features = MMU_FTR_TYPE_44x,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+ .cpu_setup = __setup_cpu_460sx,
+ .machine_check = machine_check_440A,
+ .platform = "ppc440",
+ },
{ /* default match */
.pvr_mask = 0x00000000,
.pvr_value = 0x00000000,
@@ -1687,6 +1716,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
PPC_FEATURE_UNIFIED_CACHE,
.mmu_features = MMU_FTR_TYPE_FSL_E,
.dcache_bsize = 32,
+ .cpu_setup = __setup_cpu_e200,
.machine_check = machine_check_e200,
.platform = "ppc5554",
}
@@ -1706,6 +1736,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.num_pmcs = 4,
.oprofile_cpu_type = "ppc/e500",
.oprofile_type = PPC_OPROFILE_FSL_EMB,
+ .cpu_setup = __setup_cpu_e500v1,
.machine_check = machine_check_e500,
.platform = "ppc8540",
},
@@ -1724,6 +1755,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
.num_pmcs = 4,
.oprofile_cpu_type = "ppc/e500",
.oprofile_type = PPC_OPROFILE_FSL_EMB,
+ .cpu_setup = __setup_cpu_e500v2,
.machine_check = machine_check_e500,
.platform = "ppc8548",
},
@@ -1733,12 +1765,14 @@ static struct cpu_spec __initdata cpu_specs[] = {
.cpu_name = "e500mc",
.cpu_features = CPU_FTRS_E500MC,
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
- .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS,
+ .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS |
+ MMU_FTR_USE_TLBILX,
.icache_bsize = 64,
.dcache_bsize = 64,
.num_pmcs = 4,
.oprofile_cpu_type = "ppc/e500", /* xxx - galak, e500mc? */
.oprofile_type = PPC_OPROFILE_FSL_EMB,
+ .cpu_setup = __setup_cpu_e500mc,
.machine_check = machine_check_e500,
.platform = "ppce500mc",
},
@@ -1762,74 +1796,84 @@ static struct cpu_spec __initdata cpu_specs[] = {
static struct cpu_spec the_cpu_spec;
-struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr)
+static void __init setup_cpu_spec(unsigned long offset, struct cpu_spec *s)
{
- struct cpu_spec *s = cpu_specs;
struct cpu_spec *t = &the_cpu_spec;
- int i;
+ struct cpu_spec old;
- s = PTRRELOC(s);
t = PTRRELOC(t);
+ old = *t;
- for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++)
- if ((pvr & s->pvr_mask) == s->pvr_value) {
- /*
- * If we are overriding a previous value derived
- * from the real PVR with a new value obtained
- * using a logical PVR value, don't modify the
- * performance monitor fields.
- */
- if (t->num_pmcs && !s->num_pmcs) {
- t->cpu_name = s->cpu_name;
- t->cpu_features = s->cpu_features;
- t->cpu_user_features = s->cpu_user_features;
- t->icache_bsize = s->icache_bsize;
- t->dcache_bsize = s->dcache_bsize;
- t->cpu_setup = s->cpu_setup;
- t->cpu_restore = s->cpu_restore;
- t->platform = s->platform;
- /*
- * If we have passed through this logic once
- * before and have pulled the default case
- * because the real PVR was not found inside
- * cpu_specs[], then we are possibly running in
- * compatibility mode. In that case, let the
- * oprofiler know which set of compatibility
- * counters to pull from by making sure the
- * oprofile_cpu_type string is set to that of
- * compatibility mode. If the oprofile_cpu_type
- * already has a value, then we are possibly
- * overriding a real PVR with a logical one, and,
- * in that case, keep the current value for
- * oprofile_cpu_type.
- */
- if (t->oprofile_cpu_type == NULL)
- t->oprofile_cpu_type = s->oprofile_cpu_type;
- } else
- *t = *s;
- *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
+ /* Copy everything, then do fixups */
+ *t = *s;
+
+ /*
+ * If we are overriding a previous value derived from the real
+ * PVR with a new value obtained using a logical PVR value,
+ * don't modify the performance monitor fields.
+ */
+ if (old.num_pmcs && !s->num_pmcs) {
+ t->num_pmcs = old.num_pmcs;
+ t->pmc_type = old.pmc_type;
+ t->oprofile_type = old.oprofile_type;
+ t->oprofile_mmcra_sihv = old.oprofile_mmcra_sihv;
+ t->oprofile_mmcra_sipr = old.oprofile_mmcra_sipr;
+ t->oprofile_mmcra_clear = old.oprofile_mmcra_clear;
+
+ /*
+ * If we have passed through this logic once before and
+ * have pulled the default case because the real PVR was
+ * not found inside cpu_specs[], then we are possibly
+ * running in compatibility mode. In that case, let the
+ * oprofiler know which set of compatibility counters to
+ * pull from by making sure the oprofile_cpu_type string
+ * is set to that of compatibility mode. If the
+ * oprofile_cpu_type already has a value, then we are
+ * possibly overriding a real PVR with a logical one,
+ * and, in that case, keep the current value for
+ * oprofile_cpu_type.
+ */
+ if (old.oprofile_cpu_type == NULL)
+ t->oprofile_cpu_type = s->oprofile_cpu_type;
+ }
- /*
- * Set the base platform string once; assumes
- * we're called with real pvr first.
- */
- if (*PTRRELOC(&powerpc_base_platform) == NULL)
- *PTRRELOC(&powerpc_base_platform) = t->platform;
+ *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
+
+ /*
+ * Set the base platform string once; assumes
+ * we're called with real pvr first.
+ */
+ if (*PTRRELOC(&powerpc_base_platform) == NULL)
+ *PTRRELOC(&powerpc_base_platform) = t->platform;
#if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE)
- /* ppc64 and booke expect identify_cpu to also call
- * setup_cpu for that processor. I will consolidate
- * that at a later time, for now, just use #ifdef.
- * we also don't need to PTRRELOC the function pointer
- * on ppc64 and booke as we are running at 0 in real
- * mode on ppc64 and reloc_offset is always 0 on booke.
- */
- if (s->cpu_setup) {
- s->cpu_setup(offset, s);
- }
+ /* ppc64 and booke expect identify_cpu to also call setup_cpu for
+ * that processor. I will consolidate that at a later time, for now,
+ * just use #ifdef. We also don't need to PTRRELOC the function
+ * pointer on ppc64 and booke as we are running at 0 in real mode
+ * on ppc64 and reloc_offset is always 0 on booke.
+ */
+ if (s->cpu_setup) {
+ s->cpu_setup(offset, s);
+ }
#endif /* CONFIG_PPC64 || CONFIG_BOOKE */
+}
+
+struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr)
+{
+ struct cpu_spec *s = cpu_specs;
+ int i;
+
+ s = PTRRELOC(s);
+
+ for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) {
+ if ((pvr & s->pvr_mask) == s->pvr_value) {
+ setup_cpu_spec(offset, s);
return s;
}
+ }
+
BUG();
+
return NULL;
}
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index 19671aca6591..5fb667a60894 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -48,7 +48,7 @@ static void __init create_trampoline(unsigned long addr)
* branch to "addr" we jump to ("addr" + 32 MB). Although it requires
* two instructions it doesn't require any registers.
*/
- patch_instruction(p, PPC_NOP_INSTR);
+ patch_instruction(p, PPC_INST_NOP);
patch_branch(++p, addr + PHYSICAL_START, 0);
}
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c
new file mode 100644
index 000000000000..1493734cd871
--- /dev/null
+++ b/arch/powerpc/kernel/dbell.c
@@ -0,0 +1,44 @@
+/*
+ * Author: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * Copyright 2009 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/threads.h>
+
+#include <asm/dbell.h>
+
+#ifdef CONFIG_SMP
+unsigned long dbell_smp_message[NR_CPUS];
+
+void smp_dbell_message_pass(int target, int msg)
+{
+ int i;
+
+ if(target < NR_CPUS) {
+ set_bit(msg, &dbell_smp_message[target]);
+ ppc_msgsnd(PPC_DBELL, 0, target);
+ }
+ else if(target == MSG_ALL_BUT_SELF) {
+ for_each_online_cpu(i) {
+ if (i == smp_processor_id())
+ continue;
+ set_bit(msg, &dbell_smp_message[i]);
+ ppc_msgsnd(PPC_DBELL, 0, i);
+ }
+ }
+ else { /* target == MSG_ALL */
+ for_each_online_cpu(i)
+ set_bit(msg, &dbell_smp_message[i]);
+ ppc_msgsnd(PPC_DBELL, PPC_DBELL_MSG_BRDCAST, 0);
+ }
+}
+#endif
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 6f7eb7e00c79..4dd38f129153 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -63,7 +63,7 @@ debug_transfer_to_handler:
.globl crit_transfer_to_handler
crit_transfer_to_handler:
-#ifdef CONFIG_FSL_BOOKE
+#ifdef CONFIG_PPC_BOOK3E_MMU
mfspr r0,SPRN_MAS0
stw r0,MAS0(r11)
mfspr r0,SPRN_MAS1
@@ -78,7 +78,7 @@ crit_transfer_to_handler:
mfspr r0,SPRN_MAS7
stw r0,MAS7(r11)
#endif /* CONFIG_PHYS_64BIT */
-#endif /* CONFIG_FSL_BOOKE */
+#endif /* CONFIG_PPC_BOOK3E_MMU */
#ifdef CONFIG_44x
mfspr r0,SPRN_MMUCR
stw r0,MMUCR(r11)
@@ -914,7 +914,7 @@ exc_exit_restart_end:
mtspr SPRN_##exc_lvl_srr0,r9; \
mtspr SPRN_##exc_lvl_srr1,r10;
-#if defined(CONFIG_FSL_BOOKE)
+#if defined(CONFIG_PPC_BOOK3E_MMU)
#ifdef CONFIG_PHYS_64BIT
#define RESTORE_MAS7 \
lwz r11,MAS7(r1); \
@@ -956,7 +956,7 @@ ret_from_crit_exc:
lwz r10,crit_srr1@l(r10);
mtspr SPRN_SRR0,r9;
mtspr SPRN_SRR1,r10;
- RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
+ RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI)
#endif /* CONFIG_40x */
#ifdef CONFIG_BOOKE
@@ -967,7 +967,7 @@ ret_from_crit_exc:
stw r10,KSP_LIMIT(r9)
RESTORE_xSRR(SRR0,SRR1);
RESTORE_MMU_REGS;
- RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
+ RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI)
.globl ret_from_debug_exc
ret_from_debug_exc:
@@ -981,7 +981,7 @@ ret_from_debug_exc:
RESTORE_xSRR(SRR0,SRR1);
RESTORE_xSRR(CSRR0,CSRR1);
RESTORE_MMU_REGS;
- RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI)
+ RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, PPC_RFDI)
.globl ret_from_mcheck_exc
ret_from_mcheck_exc:
@@ -992,7 +992,7 @@ ret_from_mcheck_exc:
RESTORE_xSRR(CSRR0,CSRR1);
RESTORE_xSRR(DSRR0,DSRR1);
RESTORE_MMU_REGS;
- RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI)
+ RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, PPC_RFMCI)
#endif /* CONFIG_BOOKE */
/*
@@ -1176,59 +1176,27 @@ _GLOBAL(_mcount)
bctr
_GLOBAL(ftrace_caller)
- /* Based off of objdump optput from glibc */
- stwu r1,-48(r1)
- stw r3, 12(r1)
- stw r4, 16(r1)
- stw r5, 20(r1)
- stw r6, 24(r1)
- mflr r3
- lwz r4, 52(r1)
- mfcr r5
- stw r7, 28(r1)
- stw r8, 32(r1)
- stw r9, 36(r1)
- stw r10,40(r1)
- stw r3, 44(r1)
- stw r5, 8(r1)
+ MCOUNT_SAVE_FRAME
+ /* r3 ends up with link register */
subi r3, r3, MCOUNT_INSN_SIZE
.globl ftrace_call
ftrace_call:
bl ftrace_stub
nop
- lwz r6, 8(r1)
- lwz r0, 44(r1)
- lwz r3, 12(r1)
- mtctr r0
- lwz r4, 16(r1)
- mtcr r6
- lwz r5, 20(r1)
- lwz r6, 24(r1)
- lwz r0, 52(r1)
- lwz r7, 28(r1)
- lwz r8, 32(r1)
- mtlr r0
- lwz r9, 36(r1)
- lwz r10,40(r1)
- addi r1, r1, 48
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+.globl ftrace_graph_call
+ftrace_graph_call:
+ b ftrace_graph_stub
+_GLOBAL(ftrace_graph_stub)
+#endif
+ MCOUNT_RESTORE_FRAME
+ /* old link register ends up in ctr reg */
bctr
#else
_GLOBAL(mcount)
_GLOBAL(_mcount)
- stwu r1,-48(r1)
- stw r3, 12(r1)
- stw r4, 16(r1)
- stw r5, 20(r1)
- stw r6, 24(r1)
- mflr r3
- lwz r4, 52(r1)
- mfcr r5
- stw r7, 28(r1)
- stw r8, 32(r1)
- stw r9, 36(r1)
- stw r10,40(r1)
- stw r3, 44(r1)
- stw r5, 8(r1)
+
+ MCOUNT_SAVE_FRAME
subi r3, r3, MCOUNT_INSN_SIZE
LOAD_REG_ADDR(r5, ftrace_trace_function)
@@ -1236,28 +1204,55 @@ _GLOBAL(_mcount)
mtctr r5
bctrl
-
nop
- lwz r6, 8(r1)
- lwz r0, 44(r1)
- lwz r3, 12(r1)
- mtctr r0
- lwz r4, 16(r1)
- mtcr r6
- lwz r5, 20(r1)
- lwz r6, 24(r1)
- lwz r0, 52(r1)
- lwz r7, 28(r1)
- lwz r8, 32(r1)
- mtlr r0
- lwz r9, 36(r1)
- lwz r10,40(r1)
- addi r1, r1, 48
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ b ftrace_graph_caller
+#endif
+ MCOUNT_RESTORE_FRAME
bctr
#endif
_GLOBAL(ftrace_stub)
blr
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+_GLOBAL(ftrace_graph_caller)
+ /* load r4 with local address */
+ lwz r4, 44(r1)
+ subi r4, r4, MCOUNT_INSN_SIZE
+
+ /* get the parent address */
+ addi r3, r1, 52
+
+ bl prepare_ftrace_return
+ nop
+
+ MCOUNT_RESTORE_FRAME
+ /* old link register ends up in ctr reg */
+ bctr
+
+_GLOBAL(return_to_handler)
+ /* need to save return values */
+ stwu r1, -32(r1)
+ stw r3, 20(r1)
+ stw r4, 16(r1)
+ stw r31, 12(r1)
+ mr r31, r1
+
+ bl ftrace_return_to_handler
+ nop
+
+ /* return value has real return address */
+ mtlr r3
+
+ lwz r3, 20(r1)
+ lwz r4, 16(r1)
+ lwz r31,12(r1)
+ lwz r1, 0(r1)
+
+ /* Jump back to real return address */
+ blr
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
#endif /* CONFIG_MCOUNT */
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 383ed6eb0085..abfc32330479 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -908,6 +908,12 @@ _GLOBAL(ftrace_caller)
ftrace_call:
bl ftrace_stub
nop
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+.globl ftrace_graph_call
+ftrace_graph_call:
+ b ftrace_graph_stub
+_GLOBAL(ftrace_graph_stub)
+#endif
ld r0, 128(r1)
mtlr r0
addi r1, r1, 112
@@ -931,13 +937,90 @@ _GLOBAL(_mcount)
ld r5,0(r5)
mtctr r5
bctrl
-
nop
+
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ b ftrace_graph_caller
+#endif
ld r0, 128(r1)
mtlr r0
addi r1, r1, 112
_GLOBAL(ftrace_stub)
blr
-#endif
-#endif
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+_GLOBAL(ftrace_graph_caller)
+ /* load r4 with local address */
+ ld r4, 128(r1)
+ subi r4, r4, MCOUNT_INSN_SIZE
+
+ /* get the parent address */
+ ld r11, 112(r1)
+ addi r3, r11, 16
+
+ bl .prepare_ftrace_return
+ nop
+
+ ld r0, 128(r1)
+ mtlr r0
+ addi r1, r1, 112
+ blr
+
+_GLOBAL(return_to_handler)
+ /* need to save return values */
+ std r4, -24(r1)
+ std r3, -16(r1)
+ std r31, -8(r1)
+ mr r31, r1
+ stdu r1, -112(r1)
+
+ bl .ftrace_return_to_handler
+ nop
+
+ /* return value has real return address */
+ mtlr r3
+
+ ld r1, 0(r1)
+ ld r4, -24(r1)
+ ld r3, -16(r1)
+ ld r31, -8(r1)
+
+ /* Jump back to real return address */
+ blr
+
+_GLOBAL(mod_return_to_handler)
+ /* need to save return values */
+ std r4, -32(r1)
+ std r3, -24(r1)
+ /* save TOC */
+ std r2, -16(r1)
+ std r31, -8(r1)
+ mr r31, r1
+ stdu r1, -112(r1)
+
+ /*
+ * We are in a module using the module's TOC.
+ * Switch to our TOC to run inside the core kernel.
+ */
+ LOAD_REG_IMMEDIATE(r4,ftrace_return_to_handler)
+ ld r2, 8(r4)
+
+ bl .ftrace_return_to_handler
+ nop
+
+ /* return value has real return address */
+ mtlr r3
+
+ ld r1, 0(r1)
+ ld r4, -32(r1)
+ ld r3, -24(r1)
+ ld r2, -16(r1)
+ ld r31, -8(r1)
+
+ /* Jump back to real return address */
+ blr
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+#endif /* CONFIG_FUNCTION_TRACER */
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 60c60ccf5e3c..5455943f16aa 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -5,6 +5,9 @@
*
* Thanks goes out to P.A. Semi, Inc for supplying me with a PPC64 box.
*
+ * Added function graph tracer code, taken from x86 that was written
+ * by Frederic Weisbecker, and ported to PPC by Steven Rostedt.
+ *
*/
#include <linux/spinlock.h>
@@ -20,14 +23,6 @@
#include <asm/code-patching.h>
#include <asm/ftrace.h>
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(fmt , ...) do { } while (0)
-#endif
-
-static unsigned int ftrace_nop = PPC_NOP_INSTR;
-
#ifdef CONFIG_PPC32
# define GET_ADDR(addr) addr
#else
@@ -35,37 +30,23 @@ static unsigned int ftrace_nop = PPC_NOP_INSTR;
# define GET_ADDR(addr) (*(unsigned long *)addr)
#endif
-
-static unsigned int ftrace_calc_offset(long ip, long addr)
+#ifdef CONFIG_DYNAMIC_FTRACE
+static unsigned int ftrace_nop_replace(void)
{
- return (int)(addr - ip);
+ return PPC_INST_NOP;
}
-static unsigned char *ftrace_nop_replace(void)
+static unsigned int
+ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
{
- return (char *)&ftrace_nop;
-}
-
-static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
-{
- static unsigned int op;
+ unsigned int op;
- /*
- * It would be nice to just use create_function_call, but that will
- * update the code itself. Here we need to just return the
- * instruction that is going to be modified, without modifying the
- * code.
- */
addr = GET_ADDR(addr);
- /* Set to "bl addr" */
- op = 0x48000001 | (ftrace_calc_offset(ip, addr) & 0x03fffffc);
+ /* if (link) set op to 'bl' else 'b' */
+ op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
- /*
- * No locking needed, this must be called via kstop_machine
- * which in essence is like running on a uniprocessor machine.
- */
- return (unsigned char *)&op;
+ return op;
}
#ifdef CONFIG_PPC64
@@ -77,10 +58,9 @@ static unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
#endif
static int
-ftrace_modify_code(unsigned long ip, unsigned char *old_code,
- unsigned char *new_code)
+ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
{
- unsigned char replaced[MCOUNT_INSN_SIZE];
+ unsigned int replaced;
/*
* Note: Due to modules and __init, code can
@@ -93,15 +73,15 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
*/
/* read the text we want to modify */
- if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+ if (probe_kernel_read(&replaced, (void *)ip, MCOUNT_INSN_SIZE))
return -EFAULT;
/* Make sure it is what we expect it to be */
- if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
+ if (replaced != old)
return -EINVAL;
/* replace the text with the new text */
- if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE))
+ if (probe_kernel_write((void *)ip, &new, MCOUNT_INSN_SIZE))
return -EPERM;
flush_icache_range(ip, ip + 8);
@@ -119,6 +99,8 @@ static int test_24bit_addr(unsigned long ip, unsigned long addr)
return create_branch((unsigned int *)ip, addr, 0);
}
+#ifdef CONFIG_MODULES
+
static int is_bl_op(unsigned int op)
{
return (op & 0xfc000003) == 0x48000001;
@@ -175,7 +157,7 @@ __ftrace_make_nop(struct module *mod,
* 0xe8, 0x4c, 0x00, 0x28, ld r2,40(r12)
*/
- DEBUGP("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc);
+ pr_debug("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc);
/* Find where the trampoline jumps to */
if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
@@ -183,7 +165,7 @@ __ftrace_make_nop(struct module *mod,
return -EFAULT;
}
- DEBUGP(" %08x %08x", jmp[0], jmp[1]);
+ pr_debug(" %08x %08x", jmp[0], jmp[1]);
/* verify that this is what we expect it to be */
if (((jmp[0] & 0xffff0000) != 0x3d820000) ||
@@ -199,18 +181,18 @@ __ftrace_make_nop(struct module *mod,
offset = ((unsigned)((unsigned short)jmp[0]) << 16) +
(int)((short)jmp[1]);
- DEBUGP(" %x ", offset);
+ pr_debug(" %x ", offset);
/* get the address this jumps too */
tramp = mod->arch.toc + offset + 32;
- DEBUGP("toc: %lx", tramp);
+ pr_debug("toc: %lx", tramp);
if (probe_kernel_read(jmp, (void *)tramp, 8)) {
printk(KERN_ERR "Failed to read %lx\n", tramp);
return -EFAULT;
}
- DEBUGP(" %08x %08x\n", jmp[0], jmp[1]);
+ pr_debug(" %08x %08x\n", jmp[0], jmp[1]);
ptr = ((unsigned long)jmp[0] << 32) + jmp[1];
@@ -287,7 +269,7 @@ __ftrace_make_nop(struct module *mod,
* 0x4e, 0x80, 0x04, 0x20 bctr
*/
- DEBUGP("ip:%lx jumps to %lx", ip, tramp);
+ pr_debug("ip:%lx jumps to %lx", ip, tramp);
/* Find where the trampoline jumps to */
if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
@@ -295,7 +277,7 @@ __ftrace_make_nop(struct module *mod,
return -EFAULT;
}
- DEBUGP(" %08x %08x ", jmp[0], jmp[1]);
+ pr_debug(" %08x %08x ", jmp[0], jmp[1]);
/* verify that this is what we expect it to be */
if (((jmp[0] & 0xffff0000) != 0x3d600000) ||
@@ -311,7 +293,7 @@ __ftrace_make_nop(struct module *mod,
if (tramp & 0x8000)
tramp -= 0x10000;
- DEBUGP(" %x ", tramp);
+ pr_debug(" %x ", tramp);
if (tramp != addr) {
printk(KERN_ERR
@@ -320,7 +302,7 @@ __ftrace_make_nop(struct module *mod,
return -EINVAL;
}
- op = PPC_NOP_INSTR;
+ op = PPC_INST_NOP;
if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))
return -EPERM;
@@ -330,12 +312,13 @@ __ftrace_make_nop(struct module *mod,
return 0;
}
#endif /* PPC64 */
+#endif /* CONFIG_MODULES */
int ftrace_make_nop(struct module *mod,
struct dyn_ftrace *rec, unsigned long addr)
{
- unsigned char *old, *new;
unsigned long ip = rec->ip;
+ unsigned int old, new;
/*
* If the calling address is more that 24 bits away,
@@ -344,11 +327,12 @@ int ftrace_make_nop(struct module *mod,
*/
if (test_24bit_addr(ip, addr)) {
/* within range */
- old = ftrace_call_replace(ip, addr);
+ old = ftrace_call_replace(ip, addr, 1);
new = ftrace_nop_replace();
return ftrace_modify_code(ip, old, new);
}
+#ifdef CONFIG_MODULES
/*
* Out of range jumps are called from modules.
* We should either already have a pointer to the module
@@ -373,9 +357,13 @@ int ftrace_make_nop(struct module *mod,
mod = rec->arch.mod;
return __ftrace_make_nop(mod, rec, addr);
-
+#else
+ /* We should not get here without modules */
+ return -EINVAL;
+#endif /* CONFIG_MODULES */
}
+#ifdef CONFIG_MODULES
#ifdef CONFIG_PPC64
static int
__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
@@ -392,7 +380,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
* b +8; ld r2,40(r1)
*/
if (((op[0] != 0x48000008) || (op[1] != 0xe8410028)) &&
- ((op[0] != PPC_NOP_INSTR) || (op[1] != PPC_NOP_INSTR))) {
+ ((op[0] != PPC_INST_NOP) || (op[1] != PPC_INST_NOP))) {
printk(KERN_ERR "Expected NOPs but have %x %x\n", op[0], op[1]);
return -EINVAL;
}
@@ -414,7 +402,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
/* ld r2,40(r1) */
op[1] = 0xe8410028;
- DEBUGP("write to %lx\n", rec->ip);
+ pr_debug("write to %lx\n", rec->ip);
if (probe_kernel_write((void *)ip, op, MCOUNT_INSN_SIZE * 2))
return -EPERM;
@@ -435,7 +423,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
return -EFAULT;
/* It should be pointing to a nop */
- if (op != PPC_NOP_INSTR) {
+ if (op != PPC_INST_NOP) {
printk(KERN_ERR "Expected NOP but have %x\n", op);
return -EINVAL;
}
@@ -454,7 +442,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
return -EINVAL;
}
- DEBUGP("write to %lx\n", rec->ip);
+ pr_debug("write to %lx\n", rec->ip);
if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))
return -EPERM;
@@ -464,11 +452,12 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
return 0;
}
#endif /* CONFIG_PPC64 */
+#endif /* CONFIG_MODULES */
int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{
- unsigned char *old, *new;
unsigned long ip = rec->ip;
+ unsigned int old, new;
/*
* If the calling address is more that 24 bits away,
@@ -478,10 +467,11 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
if (test_24bit_addr(ip, addr)) {
/* within range */
old = ftrace_nop_replace();
- new = ftrace_call_replace(ip, addr);
+ new = ftrace_call_replace(ip, addr, 1);
return ftrace_modify_code(ip, old, new);
}
+#ifdef CONFIG_MODULES
/*
* Out of range jumps are called from modules.
* Being that we are converting from nop, it had better
@@ -493,16 +483,20 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
}
return __ftrace_make_call(rec, addr);
+#else
+ /* We should not get here without modules */
+ return -EINVAL;
+#endif /* CONFIG_MODULES */
}
int ftrace_update_ftrace_func(ftrace_func_t func)
{
unsigned long ip = (unsigned long)(&ftrace_call);
- unsigned char old[MCOUNT_INSN_SIZE], *new;
+ unsigned int old, new;
int ret;
- memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
- new = ftrace_call_replace(ip, (unsigned long)func);
+ old = *(unsigned int *)&ftrace_call;
+ new = ftrace_call_replace(ip, (unsigned long)func, 1);
ret = ftrace_modify_code(ip, old, new);
return ret;
@@ -517,3 +511,111 @@ int __init ftrace_dyn_arch_init(void *data)
return 0;
}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern void ftrace_graph_call(void);
+extern void ftrace_graph_stub(void);
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+ unsigned long ip = (unsigned long)(&ftrace_graph_call);
+ unsigned long addr = (unsigned long)(&ftrace_graph_caller);
+ unsigned long stub = (unsigned long)(&ftrace_graph_stub);
+ unsigned int old, new;
+
+ old = ftrace_call_replace(ip, stub, 0);
+ new = ftrace_call_replace(ip, addr, 0);
+
+ return ftrace_modify_code(ip, old, new);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+ unsigned long ip = (unsigned long)(&ftrace_graph_call);
+ unsigned long addr = (unsigned long)(&ftrace_graph_caller);
+ unsigned long stub = (unsigned long)(&ftrace_graph_stub);
+ unsigned int old, new;
+
+ old = ftrace_call_replace(ip, addr, 0);
+ new = ftrace_call_replace(ip, stub, 0);
+
+ return ftrace_modify_code(ip, old, new);
+}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_PPC64
+extern void mod_return_to_handler(void);
+#endif
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
+{
+ unsigned long old;
+ int faulted;
+ struct ftrace_graph_ent trace;
+ unsigned long return_hooker = (unsigned long)&return_to_handler;
+
+ if (unlikely(atomic_read(&current->tracing_graph_pause)))
+ return;
+
+#if CONFIG_PPC64
+ /* non core kernel code needs to save and restore the TOC */
+ if (REGION_ID(self_addr) != KERNEL_REGION_ID)
+ return_hooker = (unsigned long)&mod_return_to_handler;
+#endif
+
+ return_hooker = GET_ADDR(return_hooker);
+
+ /*
+ * Protect against fault, even if it shouldn't
+ * happen. This tool is too much intrusive to
+ * ignore such a protection.
+ */
+ asm volatile(
+ "1: " PPC_LL "%[old], 0(%[parent])\n"
+ "2: " PPC_STL "%[return_hooker], 0(%[parent])\n"
+ " li %[faulted], 0\n"
+ "3:\n"
+
+ ".section .fixup, \"ax\"\n"
+ "4: li %[faulted], 1\n"
+ " b 3b\n"
+ ".previous\n"
+
+ ".section __ex_table,\"a\"\n"
+ PPC_LONG_ALIGN "\n"
+ PPC_LONG "1b,4b\n"
+ PPC_LONG "2b,4b\n"
+ ".previous"
+
+ : [old] "=r" (old), [faulted] "=r" (faulted)
+ : [parent] "r" (parent), [return_hooker] "r" (return_hooker)
+ : "memory"
+ );
+
+ if (unlikely(faulted)) {
+ ftrace_graph_stop();
+ WARN_ON(1);
+ return;
+ }
+
+ if (ftrace_push_return_trace(old, self_addr, &trace.depth) == -EBUSY) {
+ *parent = old;
+ return;
+ }
+
+ trace.func = self_addr;
+
+ /* Only trace if the calling function expects to */
+ if (!ftrace_graph_entry(&trace)) {
+ current->curr_ret_stack--;
+ *parent = old;
+ }
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index 7db2e42d97a2..54e68c11ae15 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -108,18 +108,21 @@ __start:
* because OF may have I/O devices mapped into that area
* (particularly on CHRP).
*/
-#ifdef CONFIG_PPC_MULTIPLATFORM
cmpwi 0,r5,0
beq 1f
+#ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE
/* find out where we are now */
bcl 20,31,$+4
0: mflr r8 /* r8 = runtime addr here */
addis r8,r8,(_stext - 0b)@ha
addi r8,r8,(_stext - 0b)@l /* current runtime base addr */
bl prom_init
+#endif /* CONFIG_PPC_OF_BOOT_TRAMPOLINE */
+
+ /* We never return. We also hit that trap if trying to boot
+ * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */
trap
-#endif
/*
* Check for BootX signature when supporting PowerMac and branch to
@@ -472,12 +475,11 @@ SystemCall:
. = 0x1000
InstructionTLBMiss:
/*
- * r0: stored ctr
+ * r0: scratch
* r1: linux style pte ( later becomes ppc hardware pte )
* r2: ptr to linux-style pte
* r3: scratch
*/
- mfctr r0
/* Get PTE (linux-style) and check access */
mfspr r3,SPRN_IMISS
lis r1,PAGE_OFFSET@h /* check if kernel address */
@@ -496,25 +498,27 @@ InstructionTLBMiss:
rlwinm. r2,r2,0,0,19 /* extract address of pte page */
beq- InstructionAddressInvalid /* return if no mapping */
rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
- lwz r3,0(r2) /* get linux-style pte */
- andc. r1,r1,r3 /* check access & ~permission */
+ lwz r0,0(r2) /* get linux-style pte */
+ andc. r1,r1,r0 /* check access & ~permission */
bne- InstructionAddressInvalid /* return if access not permitted */
- ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
+ ori r0,r0,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
/*
* NOTE! We are assuming this is not an SMP system, otherwise
* we would need to update the pte atomically with lwarx/stwcx.
*/
- stw r3,0(r2) /* update PTE (accessed bit) */
+ stw r0,0(r2) /* update PTE (accessed bit) */
/* Convert linux-style PTE to low word of PPC-style PTE */
- rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */
- rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
+ rlwinm r1,r0,32-10,31,31 /* _PAGE_RW -> PP lsb */
+ rlwinm r2,r0,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
and r1,r1,r2 /* writable if _RW and _DIRTY */
- rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
- rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */
+ rlwimi r0,r0,32-1,30,30 /* _PAGE_USER -> PP msb */
+ rlwimi r0,r0,32-1,31,31 /* _PAGE_USER -> PP lsb */
ori r1,r1,0xe04 /* clear out reserved bits */
- andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
+ andc r1,r0,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
+BEGIN_FTR_SECTION
+ rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
+END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
mtspr SPRN_RPA,r1
- mfspr r3,SPRN_IMISS
tlbli r3
mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
mtcrf 0x80,r3
@@ -525,7 +529,6 @@ InstructionAddressInvalid:
addis r1,r1,0x2000
mtspr SPRN_DSISR,r1 /* (shouldn't be needed) */
- mtctr r0 /* Restore CTR */
andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
or r2,r2,r1
mtspr SPRN_SRR1,r2
@@ -546,12 +549,11 @@ InstructionAddressInvalid:
. = 0x1100
DataLoadTLBMiss:
/*
- * r0: stored ctr
+ * r0: scratch
* r1: linux style pte ( later becomes ppc hardware pte )
* r2: ptr to linux-style pte
* r3: scratch
*/
- mfctr r0
/* Get PTE (linux-style) and check access */
mfspr r3,SPRN_DMISS
lis r1,PAGE_OFFSET@h /* check if kernel address */
@@ -570,35 +572,48 @@ DataLoadTLBMiss:
rlwinm. r2,r2,0,0,19 /* extract address of pte page */
beq- DataAddressInvalid /* return if no mapping */
rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
- lwz r3,0(r2) /* get linux-style pte */
- andc. r1,r1,r3 /* check access & ~permission */
+ lwz r0,0(r2) /* get linux-style pte */
+ andc. r1,r1,r0 /* check access & ~permission */
bne- DataAddressInvalid /* return if access not permitted */
- ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
+ ori r0,r0,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
/*
* NOTE! We are assuming this is not an SMP system, otherwise
* we would need to update the pte atomically with lwarx/stwcx.
*/
- stw r3,0(r2) /* update PTE (accessed bit) */
+ stw r0,0(r2) /* update PTE (accessed bit) */
/* Convert linux-style PTE to low word of PPC-style PTE */
- rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */
- rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
+ rlwinm r1,r0,32-10,31,31 /* _PAGE_RW -> PP lsb */
+ rlwinm r2,r0,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
and r1,r1,r2 /* writable if _RW and _DIRTY */
- rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
- rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */
+ rlwimi r0,r0,32-1,30,30 /* _PAGE_USER -> PP msb */
+ rlwimi r0,r0,32-1,31,31 /* _PAGE_USER -> PP lsb */
ori r1,r1,0xe04 /* clear out reserved bits */
- andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
+ andc r1,r0,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
+BEGIN_FTR_SECTION
+ rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
+END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
mtspr SPRN_RPA,r1
- mfspr r3,SPRN_DMISS
+ mfspr r2,SPRN_SRR1 /* Need to restore CR0 */
+ mtcrf 0x80,r2
+BEGIN_MMU_FTR_SECTION
+ li r0,1
+ mfspr r1,SPRN_SPRG4
+ rlwinm r2,r3,20,27,31 /* Get Address bits 15:19 */
+ slw r0,r0,r2
+ xor r1,r0,r1
+ srw r0,r1,r2
+ mtspr SPRN_SPRG4,r1
+ mfspr r2,SPRN_SRR1
+ rlwimi r2,r0,31-14,14,14
+ mtspr SPRN_SRR1,r2
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
tlbld r3
- mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
- mtcrf 0x80,r3
rfi
DataAddressInvalid:
mfspr r3,SPRN_SRR1
rlwinm r1,r3,9,6,6 /* Get load/store bit */
addis r1,r1,0x2000
mtspr SPRN_DSISR,r1
- mtctr r0 /* Restore CTR */
andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
mtspr SPRN_SRR1,r2
mfspr r1,SPRN_DMISS /* Get failing address */
@@ -618,12 +633,11 @@ DataAddressInvalid:
. = 0x1200
DataStoreTLBMiss:
/*
- * r0: stored ctr
+ * r0: scratch
* r1: linux style pte ( later becomes ppc hardware pte )
* r2: ptr to linux-style pte
* r3: scratch
*/
- mfctr r0
/* Get PTE (linux-style) and check access */
mfspr r3,SPRN_DMISS
lis r1,PAGE_OFFSET@h /* check if kernel address */
@@ -642,24 +656,38 @@ DataStoreTLBMiss:
rlwinm. r2,r2,0,0,19 /* extract address of pte page */
beq- DataAddressInvalid /* return if no mapping */
rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
- lwz r3,0(r2) /* get linux-style pte */
- andc. r1,r1,r3 /* check access & ~permission */
+ lwz r0,0(r2) /* get linux-style pte */
+ andc. r1,r1,r0 /* check access & ~permission */
bne- DataAddressInvalid /* return if access not permitted */
- ori r3,r3,_PAGE_ACCESSED|_PAGE_DIRTY
+ ori r0,r0,_PAGE_ACCESSED|_PAGE_DIRTY
/*
* NOTE! We are assuming this is not an SMP system, otherwise
* we would need to update the pte atomically with lwarx/stwcx.
*/
- stw r3,0(r2) /* update PTE (accessed/dirty bits) */
+ stw r0,0(r2) /* update PTE (accessed/dirty bits) */
/* Convert linux-style PTE to low word of PPC-style PTE */
- rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
+ rlwimi r0,r0,32-1,30,30 /* _PAGE_USER -> PP msb */
li r1,0xe05 /* clear out reserved bits & PP lsb */
- andc r1,r3,r1 /* PP = user? 2: 0 */
+ andc r1,r0,r1 /* PP = user? 2: 0 */
+BEGIN_FTR_SECTION
+ rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
+END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
mtspr SPRN_RPA,r1
- mfspr r3,SPRN_DMISS
+ mfspr r2,SPRN_SRR1 /* Need to restore CR0 */
+ mtcrf 0x80,r2
+BEGIN_MMU_FTR_SECTION
+ li r0,1
+ mfspr r1,SPRN_SPRG4
+ rlwinm r2,r3,20,27,31 /* Get Address bits 15:19 */
+ slw r0,r0,r2
+ xor r1,r0,r1
+ srw r0,r1,r2
+ mtspr SPRN_SPRG4,r1
+ mfspr r2,SPRN_SRR1
+ rlwimi r2,r0,31-14,14,14
+ mtspr SPRN_SRR1,r2
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
tlbld r3
- mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
- mtcrf 0x80,r3
rfi
#ifndef CONFIG_ALTIVEC
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index ebaedafc8e67..50ef505b8fb6 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1360,6 +1360,7 @@ _GLOBAL(__start_initialization_multiplatform)
b .__after_prom_start
_INIT_STATIC(__boot_from_prom)
+#ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE
/* Save parameters */
mr r31,r3
mr r30,r4
@@ -1390,7 +1391,10 @@ _INIT_STATIC(__boot_from_prom)
/* Do all of the interaction with OF client interface */
mr r8,r26
bl .prom_init
- /* We never return */
+#endif /* #CONFIG_PPC_OF_BOOT_TRAMPOLINE */
+
+ /* We never return. We also hit that trap if trying to boot
+ * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */
trap
_STATIC(__after_prom_start)
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index fce2df988504..95f39f1e68d4 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -10,6 +10,15 @@
mtspr SPRN_IVOR##vector_number,r26; \
sync
+#if (THREAD_SHIFT < 15)
+#define ALLOC_STACK_FRAME(reg, val) \
+ addi reg,reg,val
+#else
+#define ALLOC_STACK_FRAME(reg, val) \
+ addis reg,reg,val@ha; \
+ addi reg,reg,val@l
+#endif
+
#define NORMAL_EXCEPTION_PROLOG \
mtspr SPRN_SPRG0,r10; /* save two registers to work with */\
mtspr SPRN_SPRG1,r11; \
@@ -20,7 +29,7 @@
beq 1f; \
mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\
lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\
- addi r1,r1,THREAD_SIZE; \
+ ALLOC_STACK_FRAME(r1, THREAD_SIZE); \
1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
mr r11,r1; \
stw r10,_CCR(r11); /* save various registers */\
@@ -70,10 +79,10 @@
/* only on e500mc/e200 */
#define DEBUG_STACK_BASE dbgirq_ctx
-#ifdef CONFIG_PPC_E500MC
-#define DEBUG_SPRG SPRN_SPRG9
-#else
+#ifdef CONFIG_E200
#define DEBUG_SPRG SPRN_SPRG6W
+#else
+#define DEBUG_SPRG SPRN_SPRG9
#endif
#define EXC_LVL_FRAME_OVERHEAD (THREAD_SIZE - INT_FRAME_SIZE - EXC_LVL_SIZE)
@@ -279,7 +288,7 @@ label:
lwz r11,GPR11(r8); \
mfspr r8,DEBUG_SPRG; \
\
- RFDI; \
+ PPC_RFDI; \
b .; \
\
/* continue normal handling for a debug exception... */ \
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 36ffb3504a4f..4c22620d009b 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -103,10 +103,15 @@ invstr: mflr r6 /* Make it accessible */
or r7,r7,r4
mtspr SPRN_MAS6,r7
tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */
-#ifndef CONFIG_E200
mfspr r7,SPRN_MAS1
andis. r7,r7,MAS1_VALID@h
bne match_TLB
+
+ mfspr r7,SPRN_MMUCFG
+ rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */
+ cmpwi r7,3
+ bne match_TLB /* skip if NPIDS != 3 */
+
mfspr r7,SPRN_PID1
slwi r7,r7,16
or r7,r7,r4
@@ -120,7 +125,7 @@ invstr: mflr r6 /* Make it accessible */
or r7,r7,r4
mtspr SPRN_MAS6,r7
tlbsx 0,r6 /* Fall through, we had to match */
-#endif
+
match_TLB:
mfspr r7,SPRN_MAS0
rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */
@@ -168,7 +173,7 @@ skpinv: addi r6,r6,1 /* Increment */
/* grab and fixup the RPN */
mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */
- rlwinm r6,r6,25,27,30
+ rlwinm r6,r6,25,27,31
li r8,-1
addi r6,r6,10
slw r6,r8,r6 /* convert to mask */
@@ -194,7 +199,7 @@ skpinv: addi r6,r6,1 /* Increment */
xori r6,r4,1 /* Setup TMP mapping in the other Address space */
slwi r6,r6,12
oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h
- ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l
+ ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l
mtspr SPRN_MAS1,r6
mfspr r6,SPRN_MAS2
li r7,0 /* temp EPN = 0 */
@@ -215,14 +220,19 @@ skpinv: addi r6,r6,1 /* Increment */
/* 4. Clear out PIDs & Search info */
li r6,0
+ mtspr SPRN_MAS6,r6
mtspr SPRN_PID0,r6
-#ifndef CONFIG_E200
+
+ mfspr r7,SPRN_MMUCFG
+ rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */
+ cmpwi r7,3
+ bne 2f /* skip if NPIDS != 3 */
+
mtspr SPRN_PID1,r6
mtspr SPRN_PID2,r6
-#endif
- mtspr SPRN_MAS6,r6
/* 5. Invalidate mapping we started in */
+2:
lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */
rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */
mtspr SPRN_MAS0,r7
@@ -247,10 +257,10 @@ skpinv: addi r6,r6,1 /* Increment */
lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */
mtspr SPRN_MAS0,r6
lis r6,(MAS1_VALID|MAS1_IPROT)@h
- ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l
+ ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l
mtspr SPRN_MAS1,r6
- lis r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@h
- ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@l
+ lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h
+ ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l
mtspr SPRN_MAS2,r6
mtspr SPRN_MAS3,r8
tlbwe
@@ -298,26 +308,14 @@ skpinv: addi r6,r6,1 /* Increment */
SET_IVOR(12, WatchdogTimer);
SET_IVOR(13, DataTLBError);
SET_IVOR(14, InstructionTLBError);
- SET_IVOR(15, DebugDebug);
-#if defined(CONFIG_E500) && !defined(CONFIG_PPC_E500MC)
SET_IVOR(15, DebugCrit);
-#endif
- SET_IVOR(32, SPEUnavailable);
- SET_IVOR(33, SPEFloatingPointData);
- SET_IVOR(34, SPEFloatingPointRound);
-#ifndef CONFIG_E200
- SET_IVOR(35, PerformanceMonitor);
-#endif
-#ifdef CONFIG_PPC_E500MC
- SET_IVOR(36, Doorbell);
-#endif
/* Establish the interrupt vector base */
lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
mtspr SPRN_IVPR,r4
/* Setup the defaults for TLB entries */
- li r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l
+ li r2,(MAS4_TSIZED(BOOK3E_PAGESZ_4K))@l
#ifdef CONFIG_E200
oris r2,r2,MAS4_TLBSELD(1)@h
#endif
@@ -329,12 +327,6 @@ skpinv: addi r6,r6,1 /* Increment */
oris r2,r2,HID0_DOZE@h
mtspr SPRN_HID0, r2
#endif
-#ifdef CONFIG_E200
- /* enable dedicated debug exception handling resources (Debug APU) */
- mfspr r2,SPRN_HID0
- ori r2,r2,HID0_DAPUEN@l
- mtspr SPRN_HID0,r2
-#endif
#if !defined(CONFIG_BDI_SWITCH)
/*
@@ -706,15 +698,13 @@ interrupt_base:
/* Performance Monitor */
EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD)
-#ifdef CONFIG_PPC_E500MC
- EXCEPTION(0x2070, Doorbell, unknown_exception, EXC_XFER_STD)
-#endif
+ EXCEPTION(0x2070, Doorbell, doorbell_exception, EXC_XFER_STD)
+
+ CRITICAL_EXCEPTION(0x2080, CriticalDoorbell, unknown_exception)
/* Debug Interrupt */
DEBUG_DEBUG_EXCEPTION
-#if defined(CONFIG_E500) && !defined(CONFIG_PPC_E500MC)
DEBUG_CRIT_EXCEPTION
-#endif
/*
* Local functions
@@ -897,6 +887,47 @@ KernelSPE:
* Global functions
*/
+/* Adjust or setup IVORs for e200 */
+_GLOBAL(__setup_e200_ivors)
+ li r3,DebugDebug@l
+ mtspr SPRN_IVOR15,r3
+ li r3,SPEUnavailable@l
+ mtspr SPRN_IVOR32,r3
+ li r3,SPEFloatingPointData@l
+ mtspr SPRN_IVOR33,r3
+ li r3,SPEFloatingPointRound@l
+ mtspr SPRN_IVOR34,r3
+ sync
+ blr
+
+/* Adjust or setup IVORs for e500v1/v2 */
+_GLOBAL(__setup_e500_ivors)
+ li r3,DebugCrit@l
+ mtspr SPRN_IVOR15,r3
+ li r3,SPEUnavailable@l
+ mtspr SPRN_IVOR32,r3
+ li r3,SPEFloatingPointData@l
+ mtspr SPRN_IVOR33,r3
+ li r3,SPEFloatingPointRound@l
+ mtspr SPRN_IVOR34,r3
+ li r3,PerformanceMonitor@l
+ mtspr SPRN_IVOR35,r3
+ sync
+ blr
+
+/* Adjust or setup IVORs for e500mc */
+_GLOBAL(__setup_e500mc_ivors)
+ li r3,DebugDebug@l
+ mtspr SPRN_IVOR15,r3
+ li r3,PerformanceMonitor@l
+ mtspr SPRN_IVOR35,r3
+ li r3,Doorbell@l
+ mtspr SPRN_IVOR36,r3
+ li r3,CriticalDoorbell@l
+ mtspr SPRN_IVOR37,r3
+ sync
+ blr
+
/*
* extern void loadcam_entry(unsigned int index)
*
@@ -1089,7 +1120,7 @@ __secondary_start:
mtspr SPRN_SPRG3,r4
/* Setup the defaults for TLB entries */
- li r4,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l
+ li r4,(MAS4_TSIZED(BOOK3E_PAGESZ_4K))@l
mtspr SPRN_MAS4,r4
/* Jump to start_secondary */
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index ad1e5ac721d8..5576147e57b6 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -171,7 +171,7 @@ int show_interrupts(struct seq_file *p, void *v)
{
int i = *(loff_t *)v, j;
struct irqaction *action;
- irq_desc_t *desc;
+ struct irq_desc *desc;
unsigned long flags;
if (i == 0) {
@@ -190,7 +190,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%3d: ", i);
#ifdef CONFIG_SMP
for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#else
seq_printf(p, "%10u ", kstat_irqs(i));
#endif /* CONFIG_SMP */
@@ -1038,7 +1038,7 @@ arch_initcall(irq_late_init);
static int virq_debug_show(struct seq_file *m, void *private)
{
unsigned long flags;
- irq_desc_t *desc;
+ struct irq_desc *desc;
const char *p;
char none[] = "none";
int i;
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 8992b031a7b6..8fbb12508bf3 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -329,7 +329,7 @@ static unsigned long stub_for_addr(Elf64_Shdr *sechdrs,
restore r2. */
static int restore_r2(u32 *instruction, struct module *me)
{
- if (*instruction != PPC_NOP_INSTR) {
+ if (*instruction != PPC_INST_NOP) {
printk("%s: Expect noop after relocate, got %08x\n",
me->name, *instruction);
return 0;
diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
index 3bb7d3dd28be..8bbc12d20f5c 100644
--- a/arch/powerpc/kernel/msi.c
+++ b/arch/powerpc/kernel/msi.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/msi.h>
+#include <linux/pci.h>
#include <asm/machdep.h>
@@ -19,6 +20,10 @@ int arch_msi_check_device(struct pci_dev* dev, int nvec, int type)
return -ENOSYS;
}
+ /* PowerPC doesn't support multiple MSI yet */
+ if (type == PCI_CAP_ID_MSI && nvec > 1)
+ return 1;
+
if (ppc_md.msi_check_device) {
pr_debug("msi: Using platform check routine.\n");
return ppc_md.msi_check_device(dev, nvec, type);
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 0f4181272311..9c69e7e145c5 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -38,6 +38,7 @@
#include <asm/eeh.h>
static DEFINE_SPINLOCK(hose_spinlock);
+LIST_HEAD(hose_list);
/* XXX kill that some day ... */
static int global_phb_number; /* Global phb counter */
@@ -49,7 +50,7 @@ resource_size_t isa_mem_base;
unsigned int ppc_pci_flags = 0;
-static struct dma_mapping_ops *pci_dma_ops;
+static struct dma_mapping_ops *pci_dma_ops = &dma_direct_ops;
void set_pci_dma_ops(struct dma_mapping_ops *dma_ops)
{
@@ -113,19 +114,24 @@ void pcibios_free_controller(struct pci_controller *phb)
kfree(phb);
}
+static resource_size_t pcibios_io_size(const struct pci_controller *hose)
+{
+#ifdef CONFIG_PPC64
+ return hose->pci_io_size;
+#else
+ return hose->io_resource.end - hose->io_resource.start + 1;
+#endif
+}
+
int pcibios_vaddr_is_ioport(void __iomem *address)
{
int ret = 0;
struct pci_controller *hose;
- unsigned long size;
+ resource_size_t size;
spin_lock(&hose_spinlock);
list_for_each_entry(hose, &hose_list, list_node) {
-#ifdef CONFIG_PPC64
- size = hose->pci_io_size;
-#else
- size = hose->io_resource.end - hose->io_resource.start + 1;
-#endif
+ size = pcibios_io_size(hose);
if (address >= hose->io_base_virt &&
address < (hose->io_base_virt + size)) {
ret = 1;
@@ -136,6 +142,29 @@ int pcibios_vaddr_is_ioport(void __iomem *address)
return ret;
}
+unsigned long pci_address_to_pio(phys_addr_t address)
+{
+ struct pci_controller *hose;
+ resource_size_t size;
+ unsigned long ret = ~0;
+
+ spin_lock(&hose_spinlock);
+ list_for_each_entry(hose, &hose_list, list_node) {
+ size = pcibios_io_size(hose);
+ if (address >= hose->io_base_phys &&
+ address < (hose->io_base_phys + size)) {
+ unsigned long base =
+ (unsigned long)hose->io_base_virt - _IO_BASE;
+ ret = base + (address - hose->io_base_phys);
+ break;
+ }
+ }
+ spin_unlock(&hose_spinlock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pci_address_to_pio);
+
/*
* Return the domain number for this bus.
*/
@@ -1453,7 +1482,7 @@ void __init pcibios_resource_survey(void)
* we proceed to assigning things that were left unassigned
*/
if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
- pr_debug("PCI: Assigning unassigned resouces...\n");
+ pr_debug("PCI: Assigning unassigned resources...\n");
pci_assign_unassigned_resources();
}
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 132cd80afa21..d473634e39e3 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -20,6 +20,7 @@
#include <asm/prom.h>
#include <asm/sections.h>
#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
#include <asm/machdep.h>
@@ -43,8 +44,6 @@ static u8* pci_to_OF_bus_map;
*/
static int pci_assign_all_buses;
-LIST_HEAD(hose_list);
-
static int pci_bus_count;
/* This will remain NULL for now, until isa-bridge.c is made common
@@ -219,16 +218,23 @@ scan_OF_pci_childs(struct device_node *parent, pci_OF_scan_iterator filter, void
static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,
unsigned int devfn)
{
- struct device_node *np;
+ struct device_node *np, *cnp;
const u32 *reg;
unsigned int psize;
for_each_child_of_node(parent, np) {
reg = of_get_property(np, "reg", &psize);
- if (reg == NULL || psize < 4)
- continue;
- if (((reg[0] >> 8) & 0xff) == devfn)
+ if (reg && psize >= 4 && ((reg[0] >> 8) & 0xff) == devfn)
return np;
+
+ /* Note: some OFs create a parent node "multifunc-device" as
+ * a fake root for all functions of a multi-function device,
+ * we go down them as well. */
+ if (!strcmp(np->name, "multifunc-device")) {
+ cnp = scan_OF_for_pci_dev(np, devfn);
+ if (cnp)
+ return cnp;
+ }
}
return NULL;
}
@@ -491,24 +497,6 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
return result;
}
-unsigned long pci_address_to_pio(phys_addr_t address)
-{
- struct pci_controller *hose, *tmp;
-
- list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
- unsigned int size = hose->io_resource.end -
- hose->io_resource.start + 1;
- if (address >= hose->io_base_phys &&
- address < (hose->io_base_phys + size)) {
- unsigned long base =
- (unsigned long)hose->io_base_virt - _IO_BASE;
- return base + (address - hose->io_base_phys);
- }
- }
- return (unsigned int)-1;
-}
-EXPORT_SYMBOL(pci_address_to_pio);
-
/*
* Null PCI config access functions, for the case when we can't
* find a hose.
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index ea8eda8c87cf..be574fc0d92f 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -43,8 +43,6 @@ unsigned long pci_probe_only = 1;
unsigned long pci_io_base = ISA_IO_BASE;
EXPORT_SYMBOL(pci_io_base);
-LIST_HEAD(hose_list);
-
static void fixup_broken_pcnet32(struct pci_dev* dev)
{
if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
@@ -524,23 +522,6 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
}
EXPORT_SYMBOL_GPL(pcibios_map_io_space);
-unsigned long pci_address_to_pio(phys_addr_t address)
-{
- struct pci_controller *hose, *tmp;
-
- list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
- if (address >= hose->io_base_phys &&
- address < (hose->io_base_phys + hose->pci_io_size)) {
- unsigned long base =
- (unsigned long)hose->io_base_virt - _IO_BASE;
- return base + (address - hose->io_base_phys);
- }
- }
- return (unsigned int)-1;
-}
-EXPORT_SYMBOL_GPL(pci_address_to_pio);
-
-
#define IOBASE_BRIDGE_NUMBER 0
#define IOBASE_MEMORY 1
#define IOBASE_IO 2
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index fb7049c054c0..7b44a33f03c2 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -33,7 +33,10 @@
#include <linux/mqueue.h>
#include <linux/hardirq.h>
#include <linux/utsname.h>
+#include <linux/ftrace.h>
#include <linux/kernel_stat.h>
+#include <linux/personality.h>
+#include <linux/random.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -595,7 +598,7 @@ void prepare_to_copy(struct task_struct *tsk)
/*
* Copy a thread..
*/
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused, struct task_struct *p,
struct pt_regs *regs)
{
@@ -1008,6 +1011,14 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
unsigned long sp, ip, lr, newsp;
int count = 0;
int firstframe = 1;
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ int curr_frame = current->curr_ret_stack;
+ extern void return_to_handler(void);
+ unsigned long addr = (unsigned long)return_to_handler;
+#ifdef CONFIG_PPC64
+ addr = *(unsigned long*)addr;
+#endif
+#endif
sp = (unsigned long) stack;
if (tsk == NULL)
@@ -1030,6 +1041,13 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
ip = stack[STACK_FRAME_LR_SAVE];
if (!firstframe || ip != lr) {
printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip);
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ if (ip == addr && curr_frame >= 0) {
+ printk(" (%pS)",
+ (void *)current->ret_stack[curr_frame].ret);
+ curr_frame--;
+ }
+#endif
if (firstframe)
printk(" (unreliable)");
printk("\n");
@@ -1122,3 +1140,43 @@ void thread_info_cache_init(void)
}
#endif /* THREAD_SHIFT < PAGE_SHIFT */
+
+unsigned long arch_align_stack(unsigned long sp)
+{
+ if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
+ sp -= get_random_int() & ~PAGE_MASK;
+ return sp & ~0xf;
+}
+
+static inline unsigned long brk_rnd(void)
+{
+ unsigned long rnd = 0;
+
+ /* 8MB for 32bit, 1GB for 64bit */
+ if (is_32bit_task())
+ rnd = (long)(get_random_int() % (1<<(23-PAGE_SHIFT)));
+ else
+ rnd = (long)(get_random_int() % (1<<(30-PAGE_SHIFT)));
+
+ return rnd << PAGE_SHIFT;
+}
+
+unsigned long arch_randomize_brk(struct mm_struct *mm)
+{
+ unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd());
+
+ if (ret < mm->brk)
+ return mm->brk;
+
+ return ret;
+}
+
+unsigned long randomize_et_dyn(unsigned long base)
+{
+ unsigned long ret = PAGE_ALIGN(base + brk_rnd());
+
+ if (ret < base)
+ return base;
+
+ return ret;
+}
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index f00f83109ab3..5ec6a9e23933 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1075,11 +1075,6 @@ static void __init early_reserve_mem(void)
DBG("reserving: %llx -> %llx\n", base, size);
lmb_reserve(base, size);
}
-
-#if 0
- DBG("memory reserved, lmbs :\n");
- lmb_dump_all();
-#endif
}
#ifdef CONFIG_PHYP_DUMP
@@ -1221,6 +1216,7 @@ void __init early_init_devtree(void *params)
lmb_enforce_memory_limit(limit);
lmb_analyze();
+ lmb_dump_all();
DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 7f1b33d5e30d..2e026c0407d4 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -2283,6 +2283,8 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
*/
prom_init_stdout();
+ prom_printf("Preparing to boot %s", RELOC(linux_banner));
+
/*
* Get default machine type. At this point, we do not differentiate
* between pSeries SMP and pSeries LPAR
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
index ea3a2ec03ffa..1ac136b128f0 100644
--- a/arch/powerpc/kernel/prom_init_check.sh
+++ b/arch/powerpc/kernel/prom_init_check.sh
@@ -20,7 +20,7 @@ WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
_end enter_prom memcpy memset reloc_offset __secondary_hold
__secondary_hold_acknowledge __secondary_hold_spinloop __start
strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
-reloc_got2 kernstart_addr memstart_addr"
+reloc_got2 kernstart_addr memstart_addr linux_banner"
NM="$1"
OBJ="$2"
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index fdfe14c4bdef..ee4c7609b649 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -46,6 +46,7 @@ EXPORT_SYMBOL(rtas);
struct rtas_suspend_me_data {
atomic_t working; /* number of cpus accessing this struct */
+ atomic_t done;
int token; /* ibm,suspend-me */
int error;
struct completion *complete; /* wait on this until working == 0 */
@@ -689,7 +690,7 @@ static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
#ifdef CONFIG_PPC_PSERIES
static void rtas_percpu_suspend_me(void *info)
{
- long rc;
+ long rc = H_SUCCESS;
unsigned long msr_save;
int cpu;
struct rtas_suspend_me_data *data =
@@ -701,7 +702,8 @@ static void rtas_percpu_suspend_me(void *info)
msr_save = mfmsr();
mtmsr(msr_save & ~(MSR_EE));
- rc = plpar_hcall_norets(H_JOIN);
+ while (rc == H_SUCCESS && !atomic_read(&data->done))
+ rc = plpar_hcall_norets(H_JOIN);
mtmsr(msr_save);
@@ -724,6 +726,9 @@ static void rtas_percpu_suspend_me(void *info)
smp_processor_id(), rc);
data->error = rc;
}
+
+ atomic_set(&data->done, 1);
+
/* This cpu did the suspend or got an error; in either case,
* we need to prod all other other cpus out of join state.
* Extra prods are harmless.
@@ -766,6 +771,7 @@ static int rtas_ibm_suspend_me(struct rtas_args *args)
}
atomic_set(&data.working, 0);
+ atomic_set(&data.done, 0);
data.token = rtas_token("ibm,suspend-me");
data.error = 0;
data.complete = &done;
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index 149cb112cd1a..13011a96a977 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -669,7 +669,6 @@ static void remove_flash_pde(struct proc_dir_entry *dp)
{
if (dp) {
kfree(dp->data);
- dp->owner = NULL;
remove_proc_entry(dp->name, dp->parent);
}
}
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 705fc4bf3800..9774f9fed96e 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -35,6 +35,8 @@
#include <linux/debugfs.h>
#include <linux/percpu.h>
#include <linux/lmb.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/processor.h>
@@ -669,3 +671,37 @@ static int powerpc_debugfs_init(void)
}
arch_initcall(powerpc_debugfs_init);
#endif
+
+static int ppc_dflt_bus_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct device *dev = data;
+
+ /* We are only intereted in device addition */
+ if (action != BUS_NOTIFY_ADD_DEVICE)
+ return 0;
+
+ set_dma_ops(dev, &dma_direct_ops);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block ppc_dflt_plat_bus_notifier = {
+ .notifier_call = ppc_dflt_bus_notify,
+ .priority = INT_MAX,
+};
+
+static struct notifier_block ppc_dflt_of_bus_notifier = {
+ .notifier_call = ppc_dflt_bus_notify,
+ .priority = INT_MAX,
+};
+
+static int __init setup_bus_notifier(void)
+{
+ bus_register_notifier(&platform_bus_type, &ppc_dflt_plat_bus_notifier);
+ bus_register_notifier(&of_platform_bus_type, &ppc_dflt_of_bus_notifier);
+
+ return 0;
+}
+
+arch_initcall(setup_bus_notifier);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 2d34196bba8c..c410c606955d 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -202,8 +202,6 @@ void __init early_setup(unsigned long dt_ptr)
/* Fix up paca fields required for the boot cpu */
get_paca()->cpu_start = 1;
- get_paca()->stab_real = __pa((u64)&initial_stab);
- get_paca()->stab_addr = (u64)&initial_stab;
/* Probe the machine type */
probe_machine();
@@ -212,20 +210,8 @@ void __init early_setup(unsigned long dt_ptr)
DBG("Found, Initializing memory management...\n");
- /*
- * Initialize the MMU Hash table and create the linear mapping
- * of memory. Has to be done before stab/slb initialization as
- * this is currently where the page size encoding is obtained
- */
- htab_initialize();
-
- /*
- * Initialize stab / SLB management except on iSeries
- */
- if (cpu_has_feature(CPU_FTR_SLB))
- slb_initialize();
- else if (!firmware_has_feature(FW_FEATURE_ISERIES))
- stab_initialize(get_paca()->stab_real);
+ /* Initialize the hash table or TLB handling */
+ early_init_mmu();
DBG(" <- early_setup()\n");
}
@@ -233,22 +219,11 @@ void __init early_setup(unsigned long dt_ptr)
#ifdef CONFIG_SMP
void early_setup_secondary(void)
{
- struct paca_struct *lpaca = get_paca();
-
/* Mark interrupts enabled in PACA */
- lpaca->soft_enabled = 0;
+ get_paca()->soft_enabled = 0;
- /* Initialize hash table for that CPU */
- htab_initialize_secondary();
-
- /* Initialize STAB/SLB. We use a virtual address as it works
- * in real mode on pSeries and we want a virutal address on
- * iSeries anyway
- */
- if (cpu_has_feature(CPU_FTR_SLB))
- slb_initialize();
- else
- stab_initialize(lpaca->stab_addr);
+ /* Initialize the hash table or TLB handling */
+ early_init_mmu_secondary();
}
#endif /* CONFIG_SMP */
@@ -578,13 +553,6 @@ void ppc64_boot_msg(unsigned int src, const char *msg)
printk("[boot]%04x %s\n", src, msg);
}
-/* Print a termination message (print only -- does not stop the kernel) */
-void ppc64_terminate_msg(unsigned int src, const char *msg)
-{
- ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg);
- printk("[terminate]%04x %s\n", src, msg);
-}
-
void cpu_die(void)
{
if (ppc_md.cpu_die)
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index a54405ebd7b0..00b5078da9a3 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -26,12 +26,12 @@ int show_unhandled_signals = 0;
* Allocate space for the signal frame
*/
void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
- size_t frame_size)
+ size_t frame_size, int is_32)
{
unsigned long oldsp, newsp;
/* Default to using normal stack */
- oldsp = regs->gpr[1];
+ oldsp = get_clean_sp(regs, is_32);
/* Check for alt stack */
if ((ka->sa.sa_flags & SA_ONSTACK) &&
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index b427bf8e1d8f..6c0ddfc0603e 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -15,7 +15,7 @@
extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags);
extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
- size_t frame_size);
+ size_t frame_size, int is_32);
extern void restore_sigmask(sigset_t *set);
extern int handle_signal32(unsigned long sig, struct k_sigaction *ka,
@@ -39,22 +39,12 @@ extern unsigned long copy_vsx_from_user(struct task_struct *task,
#ifdef CONFIG_PPC64
-static inline int is_32bit_task(void)
-{
- return test_thread_flag(TIF_32BIT);
-}
-
extern int handle_rt_signal64(int signr, struct k_sigaction *ka,
siginfo_t *info, sigset_t *set,
struct pt_regs *regs);
#else /* CONFIG_PPC64 */
-static inline int is_32bit_task(void)
-{
- return 1;
-}
-
static inline int handle_rt_signal64(int signr, struct k_sigaction *ka,
siginfo_t *info, sigset_t *set,
struct pt_regs *regs)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index b13abf305996..d670429a1608 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -836,7 +836,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
/* Set up Signal Frame */
/* Put a Real Time Context onto stack */
- rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf));
+ rt_sf = get_sigframe(ka, regs, sizeof(*rt_sf), 1);
addr = rt_sf;
if (unlikely(rt_sf == NULL))
goto badframe;
@@ -1182,7 +1182,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
unsigned long newsp = 0;
/* Set up Signal Frame */
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ka, regs, sizeof(*frame), 1);
if (unlikely(frame == NULL))
goto badframe;
sc = (struct sigcontext __user *) &frame->sctx;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index e132891d3cea..2fe6fc64b614 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -402,7 +402,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
unsigned long newsp = 0;
long err = 0;
- frame = get_sigframe(ka, regs, sizeof(*frame));
+ frame = get_sigframe(ka, regs, sizeof(*frame), 0);
if (unlikely(frame == NULL))
goto badframe;
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 4a2ee08af6a7..f41aec85aa49 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -134,44 +134,23 @@ void ppc_enable_pmcs(void)
}
EXPORT_SYMBOL(ppc_enable_pmcs);
-#if defined(CONFIG_6xx) || defined(CONFIG_PPC64)
-/* XXX convert to rusty's on_one_cpu */
-static unsigned long run_on_cpu(unsigned long cpu,
- unsigned long (*func)(unsigned long),
- unsigned long arg)
-{
- cpumask_t old_affinity = current->cpus_allowed;
- unsigned long ret;
-
- /* should return -EINVAL to userspace */
- if (set_cpus_allowed(current, cpumask_of_cpu(cpu)))
- return 0;
-
- ret = func(arg);
-
- set_cpus_allowed(current, old_affinity);
-
- return ret;
-}
-#endif
-
#define SYSFS_PMCSETUP(NAME, ADDRESS) \
-static unsigned long read_##NAME(unsigned long junk) \
+static void read_##NAME(void *val) \
{ \
- return mfspr(ADDRESS); \
+ *(unsigned long *)val = mfspr(ADDRESS); \
} \
-static unsigned long write_##NAME(unsigned long val) \
+static void write_##NAME(void *val) \
{ \
ppc_enable_pmcs(); \
- mtspr(ADDRESS, val); \
- return 0; \
+ mtspr(ADDRESS, *(unsigned long *)val); \
} \
static ssize_t show_##NAME(struct sys_device *dev, \
struct sysdev_attribute *attr, \
char *buf) \
{ \
struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
- unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \
+ unsigned long val; \
+ smp_call_function_single(cpu->sysdev.id, read_##NAME, &val, 1); \
return sprintf(buf, "%lx\n", val); \
} \
static ssize_t __used \
@@ -183,7 +162,7 @@ static ssize_t __used \
int ret = sscanf(buf, "%lx", &val); \
if (ret != 1) \
return -EINVAL; \
- run_on_cpu(cpu->sysdev.id, write_##NAME, val); \
+ smp_call_function_single(cpu->sysdev.id, write_##NAME, &val, 1); \
return count; \
}
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index c9564031a2a9..926ea864e34f 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -1127,3 +1127,19 @@ void div128_by_32(u64 dividend_high, u64 dividend_low,
dr->result_low = ((u64)y << 32) + z;
}
+
+static int __init rtc_init(void)
+{
+ struct platform_device *pdev;
+
+ if (!ppc_md.get_rtc_time)
+ return -ENODEV;
+
+ pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
+}
+
+module_init(rtc_init);
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 5457e9575685..678fbff0d206 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -52,6 +52,10 @@
#include <asm/processor.h>
#endif
#include <asm/kexec.h>
+#include <asm/ppc-opcode.h>
+#ifdef CONFIG_FSL_BOOKE
+#include <asm/dbell.h>
+#endif
#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
int (*__debugger)(struct pt_regs *regs);
@@ -637,29 +641,6 @@ static void parse_fpe(struct pt_regs *regs)
* bits is faster and easier.
*
*/
-#define INST_MFSPR_PVR 0x7c1f42a6
-#define INST_MFSPR_PVR_MASK 0xfc1fffff
-
-#define INST_DCBA 0x7c0005ec
-#define INST_DCBA_MASK 0xfc0007fe
-
-#define INST_MCRXR 0x7c000400
-#define INST_MCRXR_MASK 0xfc0007fe
-
-#define INST_STRING 0x7c00042a
-#define INST_STRING_MASK 0xfc0007fe
-#define INST_STRING_GEN_MASK 0xfc00067e
-#define INST_LSWI 0x7c0004aa
-#define INST_LSWX 0x7c00042a
-#define INST_STSWI 0x7c0005aa
-#define INST_STSWX 0x7c00052a
-
-#define INST_POPCNTB 0x7c0000f4
-#define INST_POPCNTB_MASK 0xfc0007fe
-
-#define INST_ISEL 0x7c00001e
-#define INST_ISEL_MASK 0xfc00003e
-
static int emulate_string_inst(struct pt_regs *regs, u32 instword)
{
u8 rT = (instword >> 21) & 0x1f;
@@ -670,20 +651,20 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
int pos = 0;
/* Early out if we are an invalid form of lswx */
- if ((instword & INST_STRING_MASK) == INST_LSWX)
+ if ((instword & PPC_INST_STRING_MASK) == PPC_INST_LSWX)
if ((rT == rA) || (rT == NB_RB))
return -EINVAL;
EA = (rA == 0) ? 0 : regs->gpr[rA];
- switch (instword & INST_STRING_MASK) {
- case INST_LSWX:
- case INST_STSWX:
+ switch (instword & PPC_INST_STRING_MASK) {
+ case PPC_INST_LSWX:
+ case PPC_INST_STSWX:
EA += NB_RB;
num_bytes = regs->xer & 0x7f;
break;
- case INST_LSWI:
- case INST_STSWI:
+ case PPC_INST_LSWI:
+ case PPC_INST_STSWI:
num_bytes = (NB_RB == 0) ? 32 : NB_RB;
break;
default:
@@ -695,9 +676,9 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
u8 val;
u32 shift = 8 * (3 - (pos & 0x3));
- switch ((instword & INST_STRING_MASK)) {
- case INST_LSWX:
- case INST_LSWI:
+ switch ((instword & PPC_INST_STRING_MASK)) {
+ case PPC_INST_LSWX:
+ case PPC_INST_LSWI:
if (get_user(val, (u8 __user *)EA))
return -EFAULT;
/* first time updating this reg,
@@ -706,8 +687,8 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
regs->gpr[rT] = 0;
regs->gpr[rT] |= val << shift;
break;
- case INST_STSWI:
- case INST_STSWX:
+ case PPC_INST_STSWI:
+ case PPC_INST_STSWX:
val = regs->gpr[rT] >> shift;
if (put_user(val, (u8 __user *)EA))
return -EFAULT;
@@ -775,18 +756,18 @@ static int emulate_instruction(struct pt_regs *regs)
return -EFAULT;
/* Emulate the mfspr rD, PVR. */
- if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
+ if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) {
rd = (instword >> 21) & 0x1f;
regs->gpr[rd] = mfspr(SPRN_PVR);
return 0;
}
/* Emulating the dcba insn is just a no-op. */
- if ((instword & INST_DCBA_MASK) == INST_DCBA)
+ if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA)
return 0;
/* Emulate the mcrxr insn. */
- if ((instword & INST_MCRXR_MASK) == INST_MCRXR) {
+ if ((instword & PPC_INST_MCRXR_MASK) == PPC_INST_MCRXR) {
int shift = (instword >> 21) & 0x1c;
unsigned long msk = 0xf0000000UL >> shift;
@@ -796,16 +777,16 @@ static int emulate_instruction(struct pt_regs *regs)
}
/* Emulate load/store string insn. */
- if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
+ if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING)
return emulate_string_inst(regs, instword);
/* Emulate the popcntb (Population Count Bytes) instruction. */
- if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) {
+ if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) {
return emulate_popcntb_inst(regs, instword);
}
/* Emulate isel (Integer Select) instruction */
- if ((instword & INST_ISEL_MASK) == INST_ISEL) {
+ if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) {
return emulate_isel(regs, instword);
}
@@ -1144,6 +1125,24 @@ void vsx_assist_exception(struct pt_regs *regs)
#endif /* CONFIG_VSX */
#ifdef CONFIG_FSL_BOOKE
+
+void doorbell_exception(struct pt_regs *regs)
+{
+#ifdef CONFIG_SMP
+ int cpu = smp_processor_id();
+ int msg;
+
+ if (num_online_cpus() < 2)
+ return;
+
+ for (msg = 0; msg < 4; msg++)
+ if (test_and_clear_bit(msg, &dbell_smp_message[cpu]))
+ smp_message_recv(msg);
+#else
+ printk(KERN_WARNING "Received doorbell on non-smp system\n");
+#endif
+}
+
void CacheLockingException(struct pt_regs *regs, unsigned long address,
unsigned long error_code)
{
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 7d6c9bb8c77f..fc9af47e2128 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -18,6 +18,7 @@
#include <asm/udbg.h>
void (*udbg_putc)(char c);
+void (*udbg_flush)(void);
int (*udbg_getc)(void);
int (*udbg_getc_poll)(void);
@@ -76,6 +77,9 @@ void udbg_puts(const char *s)
while ((c = *s++) != '\0')
udbg_putc(c);
}
+
+ if (udbg_flush)
+ udbg_flush();
}
#if 0
else {
@@ -98,6 +102,9 @@ int udbg_write(const char *s, int n)
}
}
+ if (udbg_flush)
+ udbg_flush();
+
return n - remain;
}
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index 7b7da8cfd5e8..0362a891e54e 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -48,14 +48,21 @@ struct NS16550 {
static struct NS16550 __iomem *udbg_comport;
-static void udbg_550_putc(char c)
+static void udbg_550_flush(void)
{
if (udbg_comport) {
while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0)
/* wait for idle */;
- out_8(&udbg_comport->thr, c);
+ }
+}
+
+static void udbg_550_putc(char c)
+{
+ if (udbg_comport) {
if (c == '\n')
udbg_550_putc('\r');
+ udbg_550_flush();
+ out_8(&udbg_comport->thr, c);
}
}
@@ -108,6 +115,7 @@ void udbg_init_uart(void __iomem *comport, unsigned int speed,
/* Clear & enable FIFOs */
out_8(&udbg_comport->fcr ,0x07);
udbg_putc = udbg_550_putc;
+ udbg_flush = udbg_550_flush;
udbg_getc = udbg_550_getc;
udbg_getc_poll = udbg_550_getc_poll;
}
@@ -149,14 +157,21 @@ unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock)
}
#ifdef CONFIG_PPC_MAPLE
-void udbg_maple_real_putc(char c)
+void udbg_maple_real_flush(void)
{
if (udbg_comport) {
while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
/* wait for idle */;
- real_writeb(c, &udbg_comport->thr); eieio();
+ }
+}
+
+void udbg_maple_real_putc(char c)
+{
+ if (udbg_comport) {
if (c == '\n')
udbg_maple_real_putc('\r');
+ udbg_maple_real_flush();
+ real_writeb(c, &udbg_comport->thr); eieio();
}
}
@@ -165,20 +180,28 @@ void __init udbg_init_maple_realmode(void)
udbg_comport = (struct NS16550 __iomem *)0xf40003f8;
udbg_putc = udbg_maple_real_putc;
+ udbg_flush = udbg_maple_real_flush;
udbg_getc = NULL;
udbg_getc_poll = NULL;
}
#endif /* CONFIG_PPC_MAPLE */
#ifdef CONFIG_PPC_PASEMI
-void udbg_pas_real_putc(char c)
+void udbg_pas_real_flush(void)
{
if (udbg_comport) {
while ((real_205_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
/* wait for idle */;
- real_205_writeb(c, &udbg_comport->thr); eieio();
+ }
+}
+
+void udbg_pas_real_putc(char c)
+{
+ if (udbg_comport) {
if (c == '\n')
udbg_pas_real_putc('\r');
+ udbg_pas_real_flush();
+ real_205_writeb(c, &udbg_comport->thr); eieio();
}
}
@@ -187,6 +210,7 @@ void udbg_init_pas_realmode(void)
udbg_comport = (struct NS16550 __iomem *)0xfcff03f8UL;
udbg_putc = udbg_pas_real_putc;
+ udbg_flush = udbg_pas_real_flush;
udbg_getc = NULL;
udbg_getc_poll = NULL;
}
@@ -195,14 +219,21 @@ void udbg_init_pas_realmode(void)
#ifdef CONFIG_PPC_EARLY_DEBUG_44x
#include <platforms/44x/44x.h>
-static void udbg_44x_as1_putc(char c)
+static int udbg_44x_as1_flush(void)
{
if (udbg_comport) {
while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
/* wait for idle */;
- as1_writeb(c, &udbg_comport->thr); eieio();
+ }
+}
+
+static void udbg_44x_as1_putc(char c)
+{
+ if (udbg_comport) {
if (c == '\n')
udbg_44x_as1_putc('\r');
+ udbg_44x_as1_flush();
+ as1_writeb(c, &udbg_comport->thr); eieio();
}
}
@@ -222,19 +253,27 @@ void __init udbg_init_44x_as1(void)
(struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR;
udbg_putc = udbg_44x_as1_putc;
+ udbg_flush = udbg_44x_as1_flush;
udbg_getc = udbg_44x_as1_getc;
}
#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
#ifdef CONFIG_PPC_EARLY_DEBUG_40x
-static void udbg_40x_real_putc(char c)
+static void udbg_40x_real_flush(void)
{
if (udbg_comport) {
while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
/* wait for idle */;
- real_writeb(c, &udbg_comport->thr); eieio();
+ }
+}
+
+static void udbg_40x_real_putc(char c)
+{
+ if (udbg_comport) {
if (c == '\n')
udbg_40x_real_putc('\r');
+ udbg_40x_real_flush();
+ real_writeb(c, &udbg_comport->thr); eieio();
}
}
@@ -254,6 +293,7 @@ void __init udbg_init_40x_realmode(void)
CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR;
udbg_putc = udbg_40x_real_putc;
+ udbg_flush = udbg_40x_real_flush;
udbg_getc = udbg_40x_real_getc;
udbg_getc_poll = NULL;
}
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index d3694498f3af..819e59f6f7c7 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -482,7 +482,7 @@ static void vio_cmo_balance(struct work_struct *work)
cmo->excess.size = cmo->entitled - cmo->reserve.size;
cmo->excess.free = cmo->excess.size - need;
- cancel_delayed_work(container_of(work, struct delayed_work, work));
+ cancel_delayed_work(to_delayed_work(work));
spin_unlock_irqrestore(&vio_cmo.lock, flags);
}
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 295ccc5e86b1..b9ef1644a722 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -58,6 +58,7 @@ SECTIONS
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
+ IRQENTRY_TEXT
#ifdef CONFIG_PPC32
*(.got1)
@@ -181,14 +182,7 @@ SECTIONS
__initramfs_end = .;
}
#endif
- . = ALIGN(PAGE_SIZE);
- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
- __per_cpu_start = .;
- *(.data.percpu.page_aligned)
- *(.data.percpu)
- *(.data.percpu.shared_aligned)
- __per_cpu_end = .;
- }
+ PERCPU(PAGE_SIZE)
. = ALIGN(8);
.machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) {
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index a66bec57265a..0cef809cec21 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -28,72 +28,6 @@
#include "44x_tlb.h"
-/* Note: clearing MSR[DE] just means that the debug interrupt will not be
- * delivered *immediately*. Instead, it simply sets the appropriate DBSR bits.
- * If those DBSR bits are still set when MSR[DE] is re-enabled, the interrupt
- * will be delivered as an "imprecise debug event" (which is indicated by
- * DBSR[IDE].
- */
-static void kvm44x_disable_debug_interrupts(void)
-{
- mtmsr(mfmsr() & ~MSR_DE);
-}
-
-void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu)
-{
- kvm44x_disable_debug_interrupts();
-
- mtspr(SPRN_IAC1, vcpu->arch.host_iac[0]);
- mtspr(SPRN_IAC2, vcpu->arch.host_iac[1]);
- mtspr(SPRN_IAC3, vcpu->arch.host_iac[2]);
- mtspr(SPRN_IAC4, vcpu->arch.host_iac[3]);
- mtspr(SPRN_DBCR1, vcpu->arch.host_dbcr1);
- mtspr(SPRN_DBCR2, vcpu->arch.host_dbcr2);
- mtspr(SPRN_DBCR0, vcpu->arch.host_dbcr0);
- mtmsr(vcpu->arch.host_msr);
-}
-
-void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu)
-{
- struct kvm_guest_debug *dbg = &vcpu->guest_debug;
- u32 dbcr0 = 0;
-
- vcpu->arch.host_msr = mfmsr();
- kvm44x_disable_debug_interrupts();
-
- /* Save host debug register state. */
- vcpu->arch.host_iac[0] = mfspr(SPRN_IAC1);
- vcpu->arch.host_iac[1] = mfspr(SPRN_IAC2);
- vcpu->arch.host_iac[2] = mfspr(SPRN_IAC3);
- vcpu->arch.host_iac[3] = mfspr(SPRN_IAC4);
- vcpu->arch.host_dbcr0 = mfspr(SPRN_DBCR0);
- vcpu->arch.host_dbcr1 = mfspr(SPRN_DBCR1);
- vcpu->arch.host_dbcr2 = mfspr(SPRN_DBCR2);
-
- /* set registers up for guest */
-
- if (dbg->bp[0]) {
- mtspr(SPRN_IAC1, dbg->bp[0]);
- dbcr0 |= DBCR0_IAC1 | DBCR0_IDM;
- }
- if (dbg->bp[1]) {
- mtspr(SPRN_IAC2, dbg->bp[1]);
- dbcr0 |= DBCR0_IAC2 | DBCR0_IDM;
- }
- if (dbg->bp[2]) {
- mtspr(SPRN_IAC3, dbg->bp[2]);
- dbcr0 |= DBCR0_IAC3 | DBCR0_IDM;
- }
- if (dbg->bp[3]) {
- mtspr(SPRN_IAC4, dbg->bp[3]);
- dbcr0 |= DBCR0_IAC4 | DBCR0_IDM;
- }
-
- mtspr(SPRN_DBCR0, dbcr0);
- mtspr(SPRN_DBCR1, 0);
- mtspr(SPRN_DBCR2, 0);
-}
-
void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
kvmppc_44x_tlb_load(vcpu);
@@ -149,8 +83,6 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
struct kvm_translation *tr)
{
- struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
- struct kvmppc_44x_tlbe *gtlbe;
int index;
gva_t eaddr;
u8 pid;
@@ -166,9 +98,7 @@ int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
return 0;
}
- gtlbe = &vcpu_44x->guest_tlb[index];
-
- tr->physical_address = tlb_xlate(gtlbe, eaddr);
+ tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr);
/* XXX what does "writeable" and "usermode" even mean? */
tr->valid = 1;
diff --git a/arch/powerpc/kvm/44x_emulate.c b/arch/powerpc/kvm/44x_emulate.c
index 82489a743a6f..61af58fcecee 100644
--- a/arch/powerpc/kvm/44x_emulate.c
+++ b/arch/powerpc/kvm/44x_emulate.c
@@ -27,25 +27,12 @@
#include "booke.h"
#include "44x_tlb.h"
-#define OP_RFI 19
-
-#define XOP_RFI 50
-#define XOP_MFMSR 83
-#define XOP_WRTEE 131
-#define XOP_MTMSR 146
-#define XOP_WRTEEI 163
#define XOP_MFDCR 323
#define XOP_MTDCR 451
#define XOP_TLBSX 914
#define XOP_ICCCI 966
#define XOP_TLBWE 978
-static void kvmppc_emul_rfi(struct kvm_vcpu *vcpu)
-{
- vcpu->arch.pc = vcpu->arch.srr0;
- kvmppc_set_msr(vcpu, vcpu->arch.srr1);
-}
-
int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int inst, int *advance)
{
@@ -59,48 +46,9 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
int ws;
switch (get_op(inst)) {
- case OP_RFI:
- switch (get_xop(inst)) {
- case XOP_RFI:
- kvmppc_emul_rfi(vcpu);
- kvmppc_set_exit_type(vcpu, EMULATED_RFI_EXITS);
- *advance = 0;
- break;
-
- default:
- emulated = EMULATE_FAIL;
- break;
- }
- break;
-
case 31:
switch (get_xop(inst)) {
- case XOP_MFMSR:
- rt = get_rt(inst);
- vcpu->arch.gpr[rt] = vcpu->arch.msr;
- kvmppc_set_exit_type(vcpu, EMULATED_MFMSR_EXITS);
- break;
-
- case XOP_MTMSR:
- rs = get_rs(inst);
- kvmppc_set_exit_type(vcpu, EMULATED_MTMSR_EXITS);
- kvmppc_set_msr(vcpu, vcpu->arch.gpr[rs]);
- break;
-
- case XOP_WRTEE:
- rs = get_rs(inst);
- vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
- | (vcpu->arch.gpr[rs] & MSR_EE);
- kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
- break;
-
- case XOP_WRTEEI:
- vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
- | (inst & MSR_EE);
- kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
- break;
-
case XOP_MFDCR:
dcrn = get_dcrn(inst);
rt = get_rt(inst);
@@ -186,186 +134,51 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
emulated = EMULATE_FAIL;
}
+ if (emulated == EMULATE_FAIL)
+ emulated = kvmppc_booke_emulate_op(run, vcpu, inst, advance);
+
return emulated;
}
int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
{
+ int emulated = EMULATE_DONE;
+
switch (sprn) {
- case SPRN_MMUCR:
- vcpu->arch.mmucr = vcpu->arch.gpr[rs]; break;
case SPRN_PID:
kvmppc_set_pid(vcpu, vcpu->arch.gpr[rs]); break;
+ case SPRN_MMUCR:
+ vcpu->arch.mmucr = vcpu->arch.gpr[rs]; break;
case SPRN_CCR0:
vcpu->arch.ccr0 = vcpu->arch.gpr[rs]; break;
case SPRN_CCR1:
vcpu->arch.ccr1 = vcpu->arch.gpr[rs]; break;
- case SPRN_DEAR:
- vcpu->arch.dear = vcpu->arch.gpr[rs]; break;
- case SPRN_ESR:
- vcpu->arch.esr = vcpu->arch.gpr[rs]; break;
- case SPRN_DBCR0:
- vcpu->arch.dbcr0 = vcpu->arch.gpr[rs]; break;
- case SPRN_DBCR1:
- vcpu->arch.dbcr1 = vcpu->arch.gpr[rs]; break;
- case SPRN_TSR:
- vcpu->arch.tsr &= ~vcpu->arch.gpr[rs]; break;
- case SPRN_TCR:
- vcpu->arch.tcr = vcpu->arch.gpr[rs];
- kvmppc_emulate_dec(vcpu);
- break;
-
- /* Note: SPRG4-7 are user-readable. These values are
- * loaded into the real SPRGs when resuming the
- * guest. */
- case SPRN_SPRG4:
- vcpu->arch.sprg4 = vcpu->arch.gpr[rs]; break;
- case SPRN_SPRG5:
- vcpu->arch.sprg5 = vcpu->arch.gpr[rs]; break;
- case SPRN_SPRG6:
- vcpu->arch.sprg6 = vcpu->arch.gpr[rs]; break;
- case SPRN_SPRG7:
- vcpu->arch.sprg7 = vcpu->arch.gpr[rs]; break;
-
- case SPRN_IVPR:
- vcpu->arch.ivpr = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR0:
- vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR1:
- vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR2:
- vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR3:
- vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR4:
- vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR5:
- vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR6:
- vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR7:
- vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR8:
- vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR9:
- vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR10:
- vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR11:
- vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR12:
- vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR13:
- vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR14:
- vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = vcpu->arch.gpr[rs];
- break;
- case SPRN_IVOR15:
- vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = vcpu->arch.gpr[rs];
- break;
-
default:
- return EMULATE_FAIL;
+ emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs);
}
kvmppc_set_exit_type(vcpu, EMULATED_MTSPR_EXITS);
- return EMULATE_DONE;
+ return emulated;
}
int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
{
+ int emulated = EMULATE_DONE;
+
switch (sprn) {
- /* 440 */
+ case SPRN_PID:
+ vcpu->arch.gpr[rt] = vcpu->arch.pid; break;
case SPRN_MMUCR:
vcpu->arch.gpr[rt] = vcpu->arch.mmucr; break;
case SPRN_CCR0:
vcpu->arch.gpr[rt] = vcpu->arch.ccr0; break;
case SPRN_CCR1:
vcpu->arch.gpr[rt] = vcpu->arch.ccr1; break;
-
- /* Book E */
- case SPRN_PID:
- vcpu->arch.gpr[rt] = vcpu->arch.pid; break;
- case SPRN_IVPR:
- vcpu->arch.gpr[rt] = vcpu->arch.ivpr; break;
- case SPRN_DEAR:
- vcpu->arch.gpr[rt] = vcpu->arch.dear; break;
- case SPRN_ESR:
- vcpu->arch.gpr[rt] = vcpu->arch.esr; break;
- case SPRN_DBCR0:
- vcpu->arch.gpr[rt] = vcpu->arch.dbcr0; break;
- case SPRN_DBCR1:
- vcpu->arch.gpr[rt] = vcpu->arch.dbcr1; break;
-
- case SPRN_IVOR0:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
- break;
- case SPRN_IVOR1:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
- break;
- case SPRN_IVOR2:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
- break;
- case SPRN_IVOR3:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
- break;
- case SPRN_IVOR4:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
- break;
- case SPRN_IVOR5:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
- break;
- case SPRN_IVOR6:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
- break;
- case SPRN_IVOR7:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
- break;
- case SPRN_IVOR8:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
- break;
- case SPRN_IVOR9:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
- break;
- case SPRN_IVOR10:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
- break;
- case SPRN_IVOR11:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
- break;
- case SPRN_IVOR12:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
- break;
- case SPRN_IVOR13:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
- break;
- case SPRN_IVOR14:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
- break;
- case SPRN_IVOR15:
- vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
- break;
-
default:
- return EMULATE_FAIL;
+ emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
}
kvmppc_set_exit_type(vcpu, EMULATED_MFSPR_EXITS);
- return EMULATE_DONE;
+ return emulated;
}
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
index 9a34b8edb9e2..4a16f472cc18 100644
--- a/arch/powerpc/kvm/44x_tlb.c
+++ b/arch/powerpc/kvm/44x_tlb.c
@@ -208,20 +208,38 @@ int kvmppc_44x_tlb_index(struct kvm_vcpu *vcpu, gva_t eaddr, unsigned int pid,
return -1;
}
-int kvmppc_44x_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
+gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int gtlb_index,
+ gva_t eaddr)
+{
+ struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
+ struct kvmppc_44x_tlbe *gtlbe = &vcpu_44x->guest_tlb[gtlb_index];
+ unsigned int pgmask = get_tlb_bytes(gtlbe) - 1;
+
+ return get_tlb_raddr(gtlbe) | (eaddr & pgmask);
+}
+
+int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
{
unsigned int as = !!(vcpu->arch.msr & MSR_IS);
return kvmppc_44x_tlb_index(vcpu, eaddr, vcpu->arch.pid, as);
}
-int kvmppc_44x_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
+int kvmppc_mmu_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
{
unsigned int as = !!(vcpu->arch.msr & MSR_DS);
return kvmppc_44x_tlb_index(vcpu, eaddr, vcpu->arch.pid, as);
}
+void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu)
+{
+}
+
+void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu)
+{
+}
+
static void kvmppc_44x_shadow_release(struct kvmppc_vcpu_44x *vcpu_44x,
unsigned int stlb_index)
{
@@ -248,7 +266,7 @@ static void kvmppc_44x_shadow_release(struct kvmppc_vcpu_44x *vcpu_44x,
KVMTRACE_1D(STLB_INVAL, &vcpu_44x->vcpu, stlb_index, handler);
}
-void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu)
+void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu)
{
struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
int i;
@@ -269,15 +287,19 @@ void kvmppc_core_destroy_mmu(struct kvm_vcpu *vcpu)
* Caller must ensure that the specified guest TLB entry is safe to insert into
* the shadow TLB.
*/
-void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr, u64 asid,
- u32 flags, u32 max_bytes, unsigned int gtlb_index)
+void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr,
+ unsigned int gtlb_index)
{
struct kvmppc_44x_tlbe stlbe;
struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
+ struct kvmppc_44x_tlbe *gtlbe = &vcpu_44x->guest_tlb[gtlb_index];
struct kvmppc_44x_shadow_ref *ref;
struct page *new_page;
hpa_t hpaddr;
gfn_t gfn;
+ u32 asid = gtlbe->tid;
+ u32 flags = gtlbe->word2;
+ u32 max_bytes = get_tlb_bytes(gtlbe);
unsigned int victim;
/* Select TLB entry to clobber. Indirectly guard against races with the TLB
@@ -448,10 +470,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
}
if (tlbe_is_host_safe(vcpu, tlbe)) {
- u64 asid;
gva_t eaddr;
gpa_t gpaddr;
- u32 flags;
u32 bytes;
eaddr = get_tlb_eaddr(tlbe);
@@ -462,10 +482,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
eaddr &= ~(bytes - 1);
gpaddr &= ~(bytes - 1);
- asid = (tlbe->word0 & PPC44x_TLB_TS) | tlbe->tid;
- flags = tlbe->word2 & 0xffff;
-
- kvmppc_mmu_map(vcpu, eaddr, gpaddr, asid, flags, bytes, gtlb_index);
+ kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index);
}
KVMTRACE_5D(GTLB_WRITE, vcpu, gtlb_index, tlbe->tid, tlbe->word0,
diff --git a/arch/powerpc/kvm/44x_tlb.h b/arch/powerpc/kvm/44x_tlb.h
index 772191f29e62..a9ff80e51526 100644
--- a/arch/powerpc/kvm/44x_tlb.h
+++ b/arch/powerpc/kvm/44x_tlb.h
@@ -25,8 +25,6 @@
extern int kvmppc_44x_tlb_index(struct kvm_vcpu *vcpu, gva_t eaddr,
unsigned int pid, unsigned int as);
-extern int kvmppc_44x_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr);
-extern int kvmppc_44x_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr);
extern int kvmppc_44x_emul_tlbsx(struct kvm_vcpu *vcpu, u8 rt, u8 ra, u8 rb,
u8 rc);
@@ -85,11 +83,4 @@ static inline unsigned int get_mmucr_sts(const struct kvm_vcpu *vcpu)
return (vcpu->arch.mmucr >> 16) & 0x1;
}
-static inline gpa_t tlb_xlate(struct kvmppc_44x_tlbe *tlbe, gva_t eaddr)
-{
- unsigned int pgmask = get_tlb_bytes(tlbe) - 1;
-
- return get_tlb_raddr(tlbe) | (eaddr & pgmask);
-}
-
#endif /* __KVM_POWERPC_TLB_H__ */
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 6dbdc4817d80..5a152a52796f 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -2,6 +2,9 @@
# KVM configuration
#
+config HAVE_KVM_IRQCHIP
+ bool
+
menuconfig VIRTUALIZATION
bool "Virtualization"
---help---
@@ -43,6 +46,19 @@ config KVM_EXIT_TIMING
If unsure, say N.
+config KVM_E500
+ bool "KVM support for PowerPC E500 processors"
+ depends on EXPERIMENTAL && E500
+ select KVM
+ ---help---
+ Support running unmodified E500 guest kernels in virtual machines on
+ E500 host processors.
+
+ This module provides access to the hardware capabilities through
+ a character device node named /dev/kvm.
+
+ If unsure, say N.
+
config KVM_TRACE
bool "KVM trace support"
depends on KVM && MARKERS && SYSFS
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index df7ba59e6d53..4b2df66c79d8 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -16,8 +16,18 @@ AFLAGS_booke_interrupts.o := -I$(obj)
kvm-440-objs := \
booke.o \
+ booke_emulate.o \
booke_interrupts.o \
44x.o \
44x_tlb.o \
44x_emulate.o
obj-$(CONFIG_KVM_440) += kvm-440.o
+
+kvm-e500-objs := \
+ booke.o \
+ booke_emulate.o \
+ booke_interrupts.o \
+ e500.o \
+ e500_tlb.o \
+ e500_emulate.o
+obj-$(CONFIG_KVM_E500) += kvm-e500.o
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 35485dd6927e..642e4204cf25 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -30,10 +30,8 @@
#include <asm/kvm_ppc.h>
#include "timing.h"
#include <asm/cacheflush.h>
-#include <asm/kvm_44x.h>
#include "booke.h"
-#include "44x_tlb.h"
unsigned long kvmppc_booke_handlers;
@@ -120,6 +118,9 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
case BOOKE_IRQPRIO_DATA_STORAGE:
case BOOKE_IRQPRIO_INST_STORAGE:
case BOOKE_IRQPRIO_FP_UNAVAIL:
+ case BOOKE_IRQPRIO_SPE_UNAVAIL:
+ case BOOKE_IRQPRIO_SPE_FP_DATA:
+ case BOOKE_IRQPRIO_SPE_FP_ROUND:
case BOOKE_IRQPRIO_AP_UNAVAIL:
case BOOKE_IRQPRIO_ALIGNMENT:
allowed = 1;
@@ -165,7 +166,7 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu)
unsigned int priority;
priority = __ffs(*pending);
- while (priority <= BOOKE_MAX_INTERRUPT) {
+ while (priority <= BOOKE_IRQPRIO_MAX) {
if (kvmppc_booke_irqprio_deliver(vcpu, priority))
break;
@@ -263,6 +264,21 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
r = RESUME_GUEST;
break;
+ case BOOKE_INTERRUPT_SPE_UNAVAIL:
+ kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_UNAVAIL);
+ r = RESUME_GUEST;
+ break;
+
+ case BOOKE_INTERRUPT_SPE_FP_DATA:
+ kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_DATA);
+ r = RESUME_GUEST;
+ break;
+
+ case BOOKE_INTERRUPT_SPE_FP_ROUND:
+ kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_ROUND);
+ r = RESUME_GUEST;
+ break;
+
case BOOKE_INTERRUPT_DATA_STORAGE:
vcpu->arch.dear = vcpu->arch.fault_dear;
vcpu->arch.esr = vcpu->arch.fault_esr;
@@ -284,29 +300,27 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
r = RESUME_GUEST;
break;
- /* XXX move to a 440-specific file. */
case BOOKE_INTERRUPT_DTLB_MISS: {
- struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
- struct kvmppc_44x_tlbe *gtlbe;
unsigned long eaddr = vcpu->arch.fault_dear;
int gtlb_index;
+ gpa_t gpaddr;
gfn_t gfn;
/* Check the guest TLB. */
- gtlb_index = kvmppc_44x_dtlb_index(vcpu, eaddr);
+ gtlb_index = kvmppc_mmu_dtlb_index(vcpu, eaddr);
if (gtlb_index < 0) {
/* The guest didn't have a mapping for it. */
kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DTLB_MISS);
vcpu->arch.dear = vcpu->arch.fault_dear;
vcpu->arch.esr = vcpu->arch.fault_esr;
+ kvmppc_mmu_dtlb_miss(vcpu);
kvmppc_account_exit(vcpu, DTLB_REAL_MISS_EXITS);
r = RESUME_GUEST;
break;
}
- gtlbe = &vcpu_44x->guest_tlb[gtlb_index];
- vcpu->arch.paddr_accessed = tlb_xlate(gtlbe, eaddr);
- gfn = vcpu->arch.paddr_accessed >> PAGE_SHIFT;
+ gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr);
+ gfn = gpaddr >> PAGE_SHIFT;
if (kvm_is_visible_gfn(vcpu->kvm, gfn)) {
/* The guest TLB had a mapping, but the shadow TLB
@@ -315,13 +329,13 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
* b) the guest used a large mapping which we're faking
* Either way, we need to satisfy the fault without
* invoking the guest. */
- kvmppc_mmu_map(vcpu, eaddr, vcpu->arch.paddr_accessed, gtlbe->tid,
- gtlbe->word2, get_tlb_bytes(gtlbe), gtlb_index);
+ kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index);
kvmppc_account_exit(vcpu, DTLB_VIRT_MISS_EXITS);
r = RESUME_GUEST;
} else {
/* Guest has mapped and accessed a page which is not
* actually RAM. */
+ vcpu->arch.paddr_accessed = gpaddr;
r = kvmppc_emulate_mmio(run, vcpu);
kvmppc_account_exit(vcpu, MMIO_EXITS);
}
@@ -329,10 +343,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
break;
}
- /* XXX move to a 440-specific file. */
case BOOKE_INTERRUPT_ITLB_MISS: {
- struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
- struct kvmppc_44x_tlbe *gtlbe;
unsigned long eaddr = vcpu->arch.pc;
gpa_t gpaddr;
gfn_t gfn;
@@ -341,18 +352,18 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
r = RESUME_GUEST;
/* Check the guest TLB. */
- gtlb_index = kvmppc_44x_itlb_index(vcpu, eaddr);
+ gtlb_index = kvmppc_mmu_itlb_index(vcpu, eaddr);
if (gtlb_index < 0) {
/* The guest didn't have a mapping for it. */
kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ITLB_MISS);
+ kvmppc_mmu_itlb_miss(vcpu);
kvmppc_account_exit(vcpu, ITLB_REAL_MISS_EXITS);
break;
}
kvmppc_account_exit(vcpu, ITLB_VIRT_MISS_EXITS);
- gtlbe = &vcpu_44x->guest_tlb[gtlb_index];
- gpaddr = tlb_xlate(gtlbe, eaddr);
+ gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr);
gfn = gpaddr >> PAGE_SHIFT;
if (kvm_is_visible_gfn(vcpu->kvm, gfn)) {
@@ -362,8 +373,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
* b) the guest used a large mapping which we're faking
* Either way, we need to satisfy the fault without
* invoking the guest. */
- kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlbe->tid,
- gtlbe->word2, get_tlb_bytes(gtlbe), gtlb_index);
+ kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index);
} else {
/* Guest mapped and leaped at non-RAM! */
kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_MACHINE_CHECK);
diff --git a/arch/powerpc/kvm/booke.h b/arch/powerpc/kvm/booke.h
index cf7c94ca24bf..d59bcca1f9d8 100644
--- a/arch/powerpc/kvm/booke.h
+++ b/arch/powerpc/kvm/booke.h
@@ -22,6 +22,7 @@
#include <linux/types.h>
#include <linux/kvm_host.h>
+#include <asm/kvm_ppc.h>
#include "timing.h"
/* interrupt priortity ordering */
@@ -30,17 +31,24 @@
#define BOOKE_IRQPRIO_ALIGNMENT 2
#define BOOKE_IRQPRIO_PROGRAM 3
#define BOOKE_IRQPRIO_FP_UNAVAIL 4
-#define BOOKE_IRQPRIO_SYSCALL 5
-#define BOOKE_IRQPRIO_AP_UNAVAIL 6
-#define BOOKE_IRQPRIO_DTLB_MISS 7
-#define BOOKE_IRQPRIO_ITLB_MISS 8
-#define BOOKE_IRQPRIO_MACHINE_CHECK 9
-#define BOOKE_IRQPRIO_DEBUG 10
-#define BOOKE_IRQPRIO_CRITICAL 11
-#define BOOKE_IRQPRIO_WATCHDOG 12
-#define BOOKE_IRQPRIO_EXTERNAL 13
-#define BOOKE_IRQPRIO_FIT 14
-#define BOOKE_IRQPRIO_DECREMENTER 15
+#define BOOKE_IRQPRIO_SPE_UNAVAIL 5
+#define BOOKE_IRQPRIO_SPE_FP_DATA 6
+#define BOOKE_IRQPRIO_SPE_FP_ROUND 7
+#define BOOKE_IRQPRIO_SYSCALL 8
+#define BOOKE_IRQPRIO_AP_UNAVAIL 9
+#define BOOKE_IRQPRIO_DTLB_MISS 10
+#define BOOKE_IRQPRIO_ITLB_MISS 11
+#define BOOKE_IRQPRIO_MACHINE_CHECK 12
+#define BOOKE_IRQPRIO_DEBUG 13
+#define BOOKE_IRQPRIO_CRITICAL 14
+#define BOOKE_IRQPRIO_WATCHDOG 15
+#define BOOKE_IRQPRIO_EXTERNAL 16
+#define BOOKE_IRQPRIO_FIT 17
+#define BOOKE_IRQPRIO_DECREMENTER 18
+#define BOOKE_IRQPRIO_PERFORMANCE_MONITOR 19
+#define BOOKE_IRQPRIO_MAX 19
+
+extern unsigned long kvmppc_booke_handlers;
/* Helper function for "full" MSR writes. No need to call this if only EE is
* changing. */
@@ -57,4 +65,9 @@ static inline void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
};
}
+int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
+ unsigned int inst, int *advance);
+int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt);
+int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs);
+
#endif /* __KVM_BOOKE_H__ */
diff --git a/arch/powerpc/kvm/booke_emulate.c b/arch/powerpc/kvm/booke_emulate.c
new file mode 100644
index 000000000000..aebc65e93f4b
--- /dev/null
+++ b/arch/powerpc/kvm/booke_emulate.c
@@ -0,0 +1,266 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * Authors: Hollis Blanchard <hollisb@us.ibm.com>
+ */
+
+#include <linux/kvm_host.h>
+#include <asm/disassemble.h>
+
+#include "booke.h"
+
+#define OP_19_XOP_RFI 50
+
+#define OP_31_XOP_MFMSR 83
+#define OP_31_XOP_WRTEE 131
+#define OP_31_XOP_MTMSR 146
+#define OP_31_XOP_WRTEEI 163
+
+static void kvmppc_emul_rfi(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.pc = vcpu->arch.srr0;
+ kvmppc_set_msr(vcpu, vcpu->arch.srr1);
+}
+
+int kvmppc_booke_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
+ unsigned int inst, int *advance)
+{
+ int emulated = EMULATE_DONE;
+ int rs;
+ int rt;
+
+ switch (get_op(inst)) {
+ case 19:
+ switch (get_xop(inst)) {
+ case OP_19_XOP_RFI:
+ kvmppc_emul_rfi(vcpu);
+ kvmppc_set_exit_type(vcpu, EMULATED_RFI_EXITS);
+ *advance = 0;
+ break;
+
+ default:
+ emulated = EMULATE_FAIL;
+ break;
+ }
+ break;
+
+ case 31:
+ switch (get_xop(inst)) {
+
+ case OP_31_XOP_MFMSR:
+ rt = get_rt(inst);
+ vcpu->arch.gpr[rt] = vcpu->arch.msr;
+ kvmppc_set_exit_type(vcpu, EMULATED_MFMSR_EXITS);
+ break;
+
+ case OP_31_XOP_MTMSR:
+ rs = get_rs(inst);
+ kvmppc_set_exit_type(vcpu, EMULATED_MTMSR_EXITS);
+ kvmppc_set_msr(vcpu, vcpu->arch.gpr[rs]);
+ break;
+
+ case OP_31_XOP_WRTEE:
+ rs = get_rs(inst);
+ vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
+ | (vcpu->arch.gpr[rs] & MSR_EE);
+ kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
+ break;
+
+ case OP_31_XOP_WRTEEI:
+ vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE)
+ | (inst & MSR_EE);
+ kvmppc_set_exit_type(vcpu, EMULATED_WRTEE_EXITS);
+ break;
+
+ default:
+ emulated = EMULATE_FAIL;
+ }
+
+ break;
+
+ default:
+ emulated = EMULATE_FAIL;
+ }
+
+ return emulated;
+}
+
+int kvmppc_booke_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
+{
+ int emulated = EMULATE_DONE;
+
+ switch (sprn) {
+ case SPRN_DEAR:
+ vcpu->arch.dear = vcpu->arch.gpr[rs]; break;
+ case SPRN_ESR:
+ vcpu->arch.esr = vcpu->arch.gpr[rs]; break;
+ case SPRN_DBCR0:
+ vcpu->arch.dbcr0 = vcpu->arch.gpr[rs]; break;
+ case SPRN_DBCR1:
+ vcpu->arch.dbcr1 = vcpu->arch.gpr[rs]; break;
+ case SPRN_DBSR:
+ vcpu->arch.dbsr &= ~vcpu->arch.gpr[rs]; break;
+ case SPRN_TSR:
+ vcpu->arch.tsr &= ~vcpu->arch.gpr[rs]; break;
+ case SPRN_TCR:
+ vcpu->arch.tcr = vcpu->arch.gpr[rs];
+ kvmppc_emulate_dec(vcpu);
+ break;
+
+ /* Note: SPRG4-7 are user-readable. These values are
+ * loaded into the real SPRGs when resuming the
+ * guest. */
+ case SPRN_SPRG4:
+ vcpu->arch.sprg4 = vcpu->arch.gpr[rs]; break;
+ case SPRN_SPRG5:
+ vcpu->arch.sprg5 = vcpu->arch.gpr[rs]; break;
+ case SPRN_SPRG6:
+ vcpu->arch.sprg6 = vcpu->arch.gpr[rs]; break;
+ case SPRN_SPRG7:
+ vcpu->arch.sprg7 = vcpu->arch.gpr[rs]; break;
+
+ case SPRN_IVPR:
+ vcpu->arch.ivpr = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR0:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR1:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR2:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR3:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR4:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR5:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR6:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR7:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR8:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR9:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR10:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR11:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR12:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR13:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR14:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR15:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = vcpu->arch.gpr[rs];
+ break;
+
+ default:
+ emulated = EMULATE_FAIL;
+ }
+
+ return emulated;
+}
+
+int kvmppc_booke_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
+{
+ int emulated = EMULATE_DONE;
+
+ switch (sprn) {
+ case SPRN_IVPR:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivpr; break;
+ case SPRN_DEAR:
+ vcpu->arch.gpr[rt] = vcpu->arch.dear; break;
+ case SPRN_ESR:
+ vcpu->arch.gpr[rt] = vcpu->arch.esr; break;
+ case SPRN_DBCR0:
+ vcpu->arch.gpr[rt] = vcpu->arch.dbcr0; break;
+ case SPRN_DBCR1:
+ vcpu->arch.gpr[rt] = vcpu->arch.dbcr1; break;
+ case SPRN_DBSR:
+ vcpu->arch.gpr[rt] = vcpu->arch.dbsr; break;
+
+ case SPRN_IVOR0:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
+ break;
+ case SPRN_IVOR1:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
+ break;
+ case SPRN_IVOR2:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
+ break;
+ case SPRN_IVOR3:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
+ break;
+ case SPRN_IVOR4:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
+ break;
+ case SPRN_IVOR5:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
+ break;
+ case SPRN_IVOR6:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
+ break;
+ case SPRN_IVOR7:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
+ break;
+ case SPRN_IVOR8:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
+ break;
+ case SPRN_IVOR9:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
+ break;
+ case SPRN_IVOR10:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
+ break;
+ case SPRN_IVOR11:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
+ break;
+ case SPRN_IVOR12:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
+ break;
+ case SPRN_IVOR13:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
+ break;
+ case SPRN_IVOR14:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
+ break;
+ case SPRN_IVOR15:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
+ break;
+
+ default:
+ emulated = EMULATE_FAIL;
+ }
+
+ return emulated;
+}
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index 084ebcd7dd83..d0c6f841bbd1 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -86,6 +86,9 @@ KVM_HANDLER BOOKE_INTERRUPT_WATCHDOG
KVM_HANDLER BOOKE_INTERRUPT_DTLB_MISS
KVM_HANDLER BOOKE_INTERRUPT_ITLB_MISS
KVM_HANDLER BOOKE_INTERRUPT_DEBUG
+KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL
+KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA
+KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND
_GLOBAL(kvmppc_handler_len)
.long kvmppc_handler_1 - kvmppc_handler_0
@@ -347,7 +350,9 @@ lightweight_exit:
lwz r3, VCPU_SHADOW_PID(r4)
mtspr SPRN_PID, r3
+#ifdef CONFIG_44x
iccci 0, 0 /* XXX hack */
+#endif
/* Load some guest volatiles. */
lwz r0, VCPU_GPR(r0)(r4)
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
new file mode 100644
index 000000000000..d8067fd81cdd
--- /dev/null
+++ b/arch/powerpc/kvm/e500.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, <yu.liu@freescale.com>
+ *
+ * Description:
+ * This file is derived from arch/powerpc/kvm/44x.c,
+ * by Hollis Blanchard <hollisb@us.ibm.com>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kvm_host.h>
+#include <linux/err.h>
+
+#include <asm/reg.h>
+#include <asm/cputable.h>
+#include <asm/tlbflush.h>
+#include <asm/kvm_e500.h>
+#include <asm/kvm_ppc.h>
+
+#include "booke.h"
+#include "e500_tlb.h"
+
+void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu)
+{
+}
+
+void kvmppc_core_load_guest_debugstate(struct kvm_vcpu *vcpu)
+{
+}
+
+void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+{
+ kvmppc_e500_tlb_load(vcpu, cpu);
+}
+
+void kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu)
+{
+ kvmppc_e500_tlb_put(vcpu);
+}
+
+int kvmppc_core_check_processor_compat(void)
+{
+ int r;
+
+ if (strcmp(cur_cpu_spec->cpu_name, "e500v2") == 0)
+ r = 0;
+ else
+ r = -ENOTSUPP;
+
+ return r;
+}
+
+int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+
+ kvmppc_e500_tlb_setup(vcpu_e500);
+
+ /* Use the same core vertion as host's */
+ vcpu->arch.pvr = mfspr(SPRN_PVR);
+
+ return 0;
+}
+
+/* 'linear_address' is actually an encoding of AS|PID|EADDR . */
+int kvmppc_core_vcpu_translate(struct kvm_vcpu *vcpu,
+ struct kvm_translation *tr)
+{
+ int index;
+ gva_t eaddr;
+ u8 pid;
+ u8 as;
+
+ eaddr = tr->linear_address;
+ pid = (tr->linear_address >> 32) & 0xff;
+ as = (tr->linear_address >> 40) & 0x1;
+
+ index = kvmppc_e500_tlb_search(vcpu, eaddr, pid, as);
+ if (index < 0) {
+ tr->valid = 0;
+ return 0;
+ }
+
+ tr->physical_address = kvmppc_mmu_xlate(vcpu, index, eaddr);
+ /* XXX what does "writeable" and "usermode" even mean? */
+ tr->valid = 1;
+
+ return 0;
+}
+
+struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500;
+ struct kvm_vcpu *vcpu;
+ int err;
+
+ vcpu_e500 = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
+ if (!vcpu_e500) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ vcpu = &vcpu_e500->vcpu;
+ err = kvm_vcpu_init(vcpu, kvm, id);
+ if (err)
+ goto free_vcpu;
+
+ err = kvmppc_e500_tlb_init(vcpu_e500);
+ if (err)
+ goto uninit_vcpu;
+
+ return vcpu;
+
+uninit_vcpu:
+ kvm_vcpu_uninit(vcpu);
+free_vcpu:
+ kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
+out:
+ return ERR_PTR(err);
+}
+
+void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+
+ kvmppc_e500_tlb_uninit(vcpu_e500);
+ kvm_vcpu_uninit(vcpu);
+ kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
+}
+
+static int kvmppc_e500_init(void)
+{
+ int r, i;
+ unsigned long ivor[3];
+ unsigned long max_ivor = 0;
+
+ r = kvmppc_booke_init();
+ if (r)
+ return r;
+
+ /* copy extra E500 exception handlers */
+ ivor[0] = mfspr(SPRN_IVOR32);
+ ivor[1] = mfspr(SPRN_IVOR33);
+ ivor[2] = mfspr(SPRN_IVOR34);
+ for (i = 0; i < 3; i++) {
+ if (ivor[i] > max_ivor)
+ max_ivor = ivor[i];
+
+ memcpy((void *)kvmppc_booke_handlers + ivor[i],
+ kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
+ kvmppc_handler_len);
+ }
+ flush_icache_range(kvmppc_booke_handlers,
+ kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
+
+ return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE);
+}
+
+static void kvmppc_e500_exit(void)
+{
+ kvmppc_booke_exit();
+}
+
+module_init(kvmppc_e500_init);
+module_exit(kvmppc_e500_exit);
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
new file mode 100644
index 000000000000..3f760414b9f8
--- /dev/null
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, <yu.liu@freescale.com>
+ *
+ * Description:
+ * This file is derived from arch/powerpc/kvm/44x_emulate.c,
+ * by Hollis Blanchard <hollisb@us.ibm.com>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <asm/kvm_ppc.h>
+#include <asm/disassemble.h>
+#include <asm/kvm_e500.h>
+
+#include "booke.h"
+#include "e500_tlb.h"
+
+#define XOP_TLBIVAX 786
+#define XOP_TLBSX 914
+#define XOP_TLBRE 946
+#define XOP_TLBWE 978
+
+int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
+ unsigned int inst, int *advance)
+{
+ int emulated = EMULATE_DONE;
+ int ra;
+ int rb;
+
+ switch (get_op(inst)) {
+ case 31:
+ switch (get_xop(inst)) {
+
+ case XOP_TLBRE:
+ emulated = kvmppc_e500_emul_tlbre(vcpu);
+ break;
+
+ case XOP_TLBWE:
+ emulated = kvmppc_e500_emul_tlbwe(vcpu);
+ break;
+
+ case XOP_TLBSX:
+ rb = get_rb(inst);
+ emulated = kvmppc_e500_emul_tlbsx(vcpu,rb);
+ break;
+
+ case XOP_TLBIVAX:
+ ra = get_ra(inst);
+ rb = get_rb(inst);
+ emulated = kvmppc_e500_emul_tlbivax(vcpu, ra, rb);
+ break;
+
+ default:
+ emulated = EMULATE_FAIL;
+ }
+
+ break;
+
+ default:
+ emulated = EMULATE_FAIL;
+ }
+
+ if (emulated == EMULATE_FAIL)
+ emulated = kvmppc_booke_emulate_op(run, vcpu, inst, advance);
+
+ return emulated;
+}
+
+int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ int emulated = EMULATE_DONE;
+
+ switch (sprn) {
+ case SPRN_PID:
+ vcpu_e500->pid[0] = vcpu->arch.shadow_pid =
+ vcpu->arch.pid = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_PID1:
+ vcpu_e500->pid[1] = vcpu->arch.gpr[rs]; break;
+ case SPRN_PID2:
+ vcpu_e500->pid[2] = vcpu->arch.gpr[rs]; break;
+ case SPRN_MAS0:
+ vcpu_e500->mas0 = vcpu->arch.gpr[rs]; break;
+ case SPRN_MAS1:
+ vcpu_e500->mas1 = vcpu->arch.gpr[rs]; break;
+ case SPRN_MAS2:
+ vcpu_e500->mas2 = vcpu->arch.gpr[rs]; break;
+ case SPRN_MAS3:
+ vcpu_e500->mas3 = vcpu->arch.gpr[rs]; break;
+ case SPRN_MAS4:
+ vcpu_e500->mas4 = vcpu->arch.gpr[rs]; break;
+ case SPRN_MAS6:
+ vcpu_e500->mas6 = vcpu->arch.gpr[rs]; break;
+ case SPRN_MAS7:
+ vcpu_e500->mas7 = vcpu->arch.gpr[rs]; break;
+ case SPRN_L1CSR1:
+ vcpu_e500->l1csr1 = vcpu->arch.gpr[rs]; break;
+ case SPRN_HID0:
+ vcpu_e500->hid0 = vcpu->arch.gpr[rs]; break;
+ case SPRN_HID1:
+ vcpu_e500->hid1 = vcpu->arch.gpr[rs]; break;
+
+ case SPRN_MMUCSR0:
+ emulated = kvmppc_e500_emul_mt_mmucsr0(vcpu_e500,
+ vcpu->arch.gpr[rs]);
+ break;
+
+ /* extra exceptions */
+ case SPRN_IVOR32:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR33:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR34:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = vcpu->arch.gpr[rs];
+ break;
+ case SPRN_IVOR35:
+ vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = vcpu->arch.gpr[rs];
+ break;
+
+ default:
+ emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs);
+ }
+
+ return emulated;
+}
+
+int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ int emulated = EMULATE_DONE;
+
+ switch (sprn) {
+ case SPRN_PID:
+ vcpu->arch.gpr[rt] = vcpu_e500->pid[0]; break;
+ case SPRN_PID1:
+ vcpu->arch.gpr[rt] = vcpu_e500->pid[1]; break;
+ case SPRN_PID2:
+ vcpu->arch.gpr[rt] = vcpu_e500->pid[2]; break;
+ case SPRN_MAS0:
+ vcpu->arch.gpr[rt] = vcpu_e500->mas0; break;
+ case SPRN_MAS1:
+ vcpu->arch.gpr[rt] = vcpu_e500->mas1; break;
+ case SPRN_MAS2:
+ vcpu->arch.gpr[rt] = vcpu_e500->mas2; break;
+ case SPRN_MAS3:
+ vcpu->arch.gpr[rt] = vcpu_e500->mas3; break;
+ case SPRN_MAS4:
+ vcpu->arch.gpr[rt] = vcpu_e500->mas4; break;
+ case SPRN_MAS6:
+ vcpu->arch.gpr[rt] = vcpu_e500->mas6; break;
+ case SPRN_MAS7:
+ vcpu->arch.gpr[rt] = vcpu_e500->mas7; break;
+
+ case SPRN_TLB0CFG:
+ vcpu->arch.gpr[rt] = mfspr(SPRN_TLB0CFG);
+ vcpu->arch.gpr[rt] &= ~0xfffUL;
+ vcpu->arch.gpr[rt] |= vcpu_e500->guest_tlb_size[0];
+ break;
+
+ case SPRN_TLB1CFG:
+ vcpu->arch.gpr[rt] = mfspr(SPRN_TLB1CFG);
+ vcpu->arch.gpr[rt] &= ~0xfffUL;
+ vcpu->arch.gpr[rt] |= vcpu_e500->guest_tlb_size[1];
+ break;
+
+ case SPRN_L1CSR1:
+ vcpu->arch.gpr[rt] = vcpu_e500->l1csr1; break;
+ case SPRN_HID0:
+ vcpu->arch.gpr[rt] = vcpu_e500->hid0; break;
+ case SPRN_HID1:
+ vcpu->arch.gpr[rt] = vcpu_e500->hid1; break;
+
+ case SPRN_MMUCSR0:
+ vcpu->arch.gpr[rt] = 0; break;
+
+ /* extra exceptions */
+ case SPRN_IVOR32:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
+ break;
+ case SPRN_IVOR33:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA];
+ break;
+ case SPRN_IVOR34:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND];
+ break;
+ case SPRN_IVOR35:
+ vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
+ break;
+ default:
+ emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
+ }
+
+ return emulated;
+}
+
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
new file mode 100644
index 000000000000..0e773fc2d5e4
--- /dev/null
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -0,0 +1,757 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, yu.liu@freescale.com
+ *
+ * Description:
+ * This file is based on arch/powerpc/kvm/44x_tlb.c,
+ * by Hollis Blanchard <hollisb@us.ibm.com>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kvm.h>
+#include <linux/kvm_host.h>
+#include <linux/highmem.h>
+#include <asm/kvm_ppc.h>
+#include <asm/kvm_e500.h>
+
+#include "../mm/mmu_decl.h"
+#include "e500_tlb.h"
+
+#define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1)
+
+static unsigned int tlb1_entry_num;
+
+void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ struct tlbe *tlbe;
+ int i, tlbsel;
+
+ printk("| %8s | %8s | %8s | %8s | %8s |\n",
+ "nr", "mas1", "mas2", "mas3", "mas7");
+
+ for (tlbsel = 0; tlbsel < 2; tlbsel++) {
+ printk("Guest TLB%d:\n", tlbsel);
+ for (i = 0; i < vcpu_e500->guest_tlb_size[tlbsel]; i++) {
+ tlbe = &vcpu_e500->guest_tlb[tlbsel][i];
+ if (tlbe->mas1 & MAS1_VALID)
+ printk(" G[%d][%3d] | %08X | %08X | %08X | %08X |\n",
+ tlbsel, i, tlbe->mas1, tlbe->mas2,
+ tlbe->mas3, tlbe->mas7);
+ }
+ }
+
+ for (tlbsel = 0; tlbsel < 2; tlbsel++) {
+ printk("Shadow TLB%d:\n", tlbsel);
+ for (i = 0; i < vcpu_e500->shadow_tlb_size[tlbsel]; i++) {
+ tlbe = &vcpu_e500->shadow_tlb[tlbsel][i];
+ if (tlbe->mas1 & MAS1_VALID)
+ printk(" S[%d][%3d] | %08X | %08X | %08X | %08X |\n",
+ tlbsel, i, tlbe->mas1, tlbe->mas2,
+ tlbe->mas3, tlbe->mas7);
+ }
+ }
+}
+
+static inline unsigned int tlb0_get_next_victim(
+ struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+ unsigned int victim;
+
+ victim = vcpu_e500->guest_tlb_nv[0]++;
+ if (unlikely(vcpu_e500->guest_tlb_nv[0] >= KVM_E500_TLB0_WAY_NUM))
+ vcpu_e500->guest_tlb_nv[0] = 0;
+
+ return victim;
+}
+
+static inline unsigned int tlb1_max_shadow_size(void)
+{
+ return tlb1_entry_num - tlbcam_index;
+}
+
+static inline int tlbe_is_writable(struct tlbe *tlbe)
+{
+ return tlbe->mas3 & (MAS3_SW|MAS3_UW);
+}
+
+static inline u32 e500_shadow_mas3_attrib(u32 mas3, int usermode)
+{
+ /* Mask off reserved bits. */
+ mas3 &= MAS3_ATTRIB_MASK;
+
+ if (!usermode) {
+ /* Guest is in supervisor mode,
+ * so we need to translate guest
+ * supervisor permissions into user permissions. */
+ mas3 &= ~E500_TLB_USER_PERM_MASK;
+ mas3 |= (mas3 & E500_TLB_SUPER_PERM_MASK) << 1;
+ }
+
+ return mas3 | E500_TLB_SUPER_PERM_MASK;
+}
+
+static inline u32 e500_shadow_mas2_attrib(u32 mas2, int usermode)
+{
+#ifdef CONFIG_SMP
+ return (mas2 & MAS2_ATTRIB_MASK) | MAS2_M;
+#else
+ return mas2 & MAS2_ATTRIB_MASK;
+#endif
+}
+
+/*
+ * writing shadow tlb entry to host TLB
+ */
+static inline void __write_host_tlbe(struct tlbe *stlbe)
+{
+ mtspr(SPRN_MAS1, stlbe->mas1);
+ mtspr(SPRN_MAS2, stlbe->mas2);
+ mtspr(SPRN_MAS3, stlbe->mas3);
+ mtspr(SPRN_MAS7, stlbe->mas7);
+ __asm__ __volatile__ ("tlbwe\n" : : );
+}
+
+static inline void write_host_tlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
+ int tlbsel, int esel)
+{
+ struct tlbe *stlbe = &vcpu_e500->shadow_tlb[tlbsel][esel];
+
+ local_irq_disable();
+ if (tlbsel == 0) {
+ __write_host_tlbe(stlbe);
+ } else {
+ unsigned register mas0;
+
+ mas0 = mfspr(SPRN_MAS0);
+
+ mtspr(SPRN_MAS0, MAS0_TLBSEL(1) | MAS0_ESEL(to_htlb1_esel(esel)));
+ __write_host_tlbe(stlbe);
+
+ mtspr(SPRN_MAS0, mas0);
+ }
+ local_irq_enable();
+}
+
+void kvmppc_e500_tlb_load(struct kvm_vcpu *vcpu, int cpu)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ int i;
+ unsigned register mas0;
+
+ /* Load all valid TLB1 entries to reduce guest tlb miss fault */
+ local_irq_disable();
+ mas0 = mfspr(SPRN_MAS0);
+ for (i = 0; i < tlb1_max_shadow_size(); i++) {
+ struct tlbe *stlbe = &vcpu_e500->shadow_tlb[1][i];
+
+ if (get_tlb_v(stlbe)) {
+ mtspr(SPRN_MAS0, MAS0_TLBSEL(1)
+ | MAS0_ESEL(to_htlb1_esel(i)));
+ __write_host_tlbe(stlbe);
+ }
+ }
+ mtspr(SPRN_MAS0, mas0);
+ local_irq_enable();
+}
+
+void kvmppc_e500_tlb_put(struct kvm_vcpu *vcpu)
+{
+ _tlbil_all();
+}
+
+/* Search the guest TLB for a matching entry. */
+static int kvmppc_e500_tlb_index(struct kvmppc_vcpu_e500 *vcpu_e500,
+ gva_t eaddr, int tlbsel, unsigned int pid, int as)
+{
+ int i;
+
+ /* XXX Replace loop with fancy data structures. */
+ for (i = 0; i < vcpu_e500->guest_tlb_size[tlbsel]; i++) {
+ struct tlbe *tlbe = &vcpu_e500->guest_tlb[tlbsel][i];
+ unsigned int tid;
+
+ if (eaddr < get_tlb_eaddr(tlbe))
+ continue;
+
+ if (eaddr > get_tlb_end(tlbe))
+ continue;
+
+ tid = get_tlb_tid(tlbe);
+ if (tid && (tid != pid))
+ continue;
+
+ if (!get_tlb_v(tlbe))
+ continue;
+
+ if (get_tlb_ts(tlbe) != as && as != -1)
+ continue;
+
+ return i;
+ }
+
+ return -1;
+}
+
+static void kvmppc_e500_shadow_release(struct kvmppc_vcpu_e500 *vcpu_e500,
+ int tlbsel, int esel)
+{
+ struct tlbe *stlbe = &vcpu_e500->shadow_tlb[tlbsel][esel];
+ struct page *page = vcpu_e500->shadow_pages[tlbsel][esel];
+
+ if (page) {
+ vcpu_e500->shadow_pages[tlbsel][esel] = NULL;
+
+ if (get_tlb_v(stlbe)) {
+ if (tlbe_is_writable(stlbe))
+ kvm_release_page_dirty(page);
+ else
+ kvm_release_page_clean(page);
+ }
+ }
+}
+
+static void kvmppc_e500_stlbe_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
+ int tlbsel, int esel)
+{
+ struct tlbe *stlbe = &vcpu_e500->shadow_tlb[tlbsel][esel];
+
+ kvmppc_e500_shadow_release(vcpu_e500, tlbsel, esel);
+ stlbe->mas1 = 0;
+ KVMTRACE_5D(STLB_INVAL, &vcpu_e500->vcpu, index_of(tlbsel, esel),
+ stlbe->mas1, stlbe->mas2, stlbe->mas3, stlbe->mas7,
+ handler);
+}
+
+static void kvmppc_e500_tlb1_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
+ gva_t eaddr, gva_t eend, u32 tid)
+{
+ unsigned int pid = tid & 0xff;
+ unsigned int i;
+
+ /* XXX Replace loop with fancy data structures. */
+ for (i = 0; i < vcpu_e500->guest_tlb_size[1]; i++) {
+ struct tlbe *stlbe = &vcpu_e500->shadow_tlb[1][i];
+ unsigned int tid;
+
+ if (!get_tlb_v(stlbe))
+ continue;
+
+ if (eend < get_tlb_eaddr(stlbe))
+ continue;
+
+ if (eaddr > get_tlb_end(stlbe))
+ continue;
+
+ tid = get_tlb_tid(stlbe);
+ if (tid && (tid != pid))
+ continue;
+
+ kvmppc_e500_stlbe_invalidate(vcpu_e500, 1, i);
+ write_host_tlbe(vcpu_e500, 1, i);
+ }
+}
+
+static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
+ unsigned int eaddr, int as)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ unsigned int victim, pidsel, tsized;
+ int tlbsel;
+
+ /* since we only have two TLBs, only lower bit is used. */
+ tlbsel = (vcpu_e500->mas4 >> 28) & 0x1;
+ victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0;
+ pidsel = (vcpu_e500->mas4 >> 16) & 0xf;
+ tsized = (vcpu_e500->mas4 >> 8) & 0xf;
+
+ vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim)
+ | MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]);
+ vcpu_e500->mas1 = MAS1_VALID | (as ? MAS1_TS : 0)
+ | MAS1_TID(vcpu_e500->pid[pidsel])
+ | MAS1_TSIZE(tsized);
+ vcpu_e500->mas2 = (eaddr & MAS2_EPN)
+ | (vcpu_e500->mas4 & MAS2_ATTRIB_MASK);
+ vcpu_e500->mas3 &= MAS3_U0 | MAS3_U1 | MAS3_U2 | MAS3_U3;
+ vcpu_e500->mas6 = (vcpu_e500->mas6 & MAS6_SPID1)
+ | (get_cur_pid(vcpu) << 16)
+ | (as ? MAS6_SAS : 0);
+ vcpu_e500->mas7 = 0;
+}
+
+static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
+ u64 gvaddr, gfn_t gfn, struct tlbe *gtlbe, int tlbsel, int esel)
+{
+ struct page *new_page;
+ struct tlbe *stlbe;
+ hpa_t hpaddr;
+
+ stlbe = &vcpu_e500->shadow_tlb[tlbsel][esel];
+
+ /* Get reference to new page. */
+ new_page = gfn_to_page(vcpu_e500->vcpu.kvm, gfn);
+ if (is_error_page(new_page)) {
+ printk(KERN_ERR "Couldn't get guest page for gfn %lx!\n", gfn);
+ kvm_release_page_clean(new_page);
+ return;
+ }
+ hpaddr = page_to_phys(new_page);
+
+ /* Drop reference to old page. */
+ kvmppc_e500_shadow_release(vcpu_e500, tlbsel, esel);
+
+ vcpu_e500->shadow_pages[tlbsel][esel] = new_page;
+
+ /* Force TS=1 IPROT=0 TSIZE=4KB for all guest mappings. */
+ stlbe->mas1 = MAS1_TSIZE(BOOKE_PAGESZ_4K)
+ | MAS1_TID(get_tlb_tid(gtlbe)) | MAS1_TS | MAS1_VALID;
+ stlbe->mas2 = (gvaddr & MAS2_EPN)
+ | e500_shadow_mas2_attrib(gtlbe->mas2,
+ vcpu_e500->vcpu.arch.msr & MSR_PR);
+ stlbe->mas3 = (hpaddr & MAS3_RPN)
+ | e500_shadow_mas3_attrib(gtlbe->mas3,
+ vcpu_e500->vcpu.arch.msr & MSR_PR);
+ stlbe->mas7 = (hpaddr >> 32) & MAS7_RPN;
+
+ KVMTRACE_5D(STLB_WRITE, &vcpu_e500->vcpu, index_of(tlbsel, esel),
+ stlbe->mas1, stlbe->mas2, stlbe->mas3, stlbe->mas7,
+ handler);
+}
+
+/* XXX only map the one-one case, for now use TLB0 */
+static int kvmppc_e500_stlbe_map(struct kvmppc_vcpu_e500 *vcpu_e500,
+ int tlbsel, int esel)
+{
+ struct tlbe *gtlbe;
+
+ gtlbe = &vcpu_e500->guest_tlb[tlbsel][esel];
+
+ kvmppc_e500_shadow_map(vcpu_e500, get_tlb_eaddr(gtlbe),
+ get_tlb_raddr(gtlbe) >> PAGE_SHIFT,
+ gtlbe, tlbsel, esel);
+
+ return esel;
+}
+
+/* Caller must ensure that the specified guest TLB entry is safe to insert into
+ * the shadow TLB. */
+/* XXX for both one-one and one-to-many , for now use TLB1 */
+static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500,
+ u64 gvaddr, gfn_t gfn, struct tlbe *gtlbe)
+{
+ unsigned int victim;
+
+ victim = vcpu_e500->guest_tlb_nv[1]++;
+
+ if (unlikely(vcpu_e500->guest_tlb_nv[1] >= tlb1_max_shadow_size()))
+ vcpu_e500->guest_tlb_nv[1] = 0;
+
+ kvmppc_e500_shadow_map(vcpu_e500, gvaddr, gfn, gtlbe, 1, victim);
+
+ return victim;
+}
+
+/* Invalidate all guest kernel mappings when enter usermode,
+ * so that when they fault back in they will get the
+ * proper permission bits. */
+void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode)
+{
+ if (usermode) {
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ int i;
+
+ /* XXX Replace loop with fancy data structures. */
+ for (i = 0; i < tlb1_max_shadow_size(); i++)
+ kvmppc_e500_stlbe_invalidate(vcpu_e500, 1, i);
+
+ _tlbil_all();
+ }
+}
+
+static int kvmppc_e500_gtlbe_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
+ int tlbsel, int esel)
+{
+ struct tlbe *gtlbe = &vcpu_e500->guest_tlb[tlbsel][esel];
+
+ if (unlikely(get_tlb_iprot(gtlbe)))
+ return -1;
+
+ if (tlbsel == 1) {
+ kvmppc_e500_tlb1_invalidate(vcpu_e500, get_tlb_eaddr(gtlbe),
+ get_tlb_end(gtlbe),
+ get_tlb_tid(gtlbe));
+ } else {
+ kvmppc_e500_stlbe_invalidate(vcpu_e500, tlbsel, esel);
+ }
+
+ gtlbe->mas1 = 0;
+
+ return 0;
+}
+
+int kvmppc_e500_emul_mt_mmucsr0(struct kvmppc_vcpu_e500 *vcpu_e500, ulong value)
+{
+ int esel;
+
+ if (value & MMUCSR0_TLB0FI)
+ for (esel = 0; esel < vcpu_e500->guest_tlb_size[0]; esel++)
+ kvmppc_e500_gtlbe_invalidate(vcpu_e500, 0, esel);
+ if (value & MMUCSR0_TLB1FI)
+ for (esel = 0; esel < vcpu_e500->guest_tlb_size[1]; esel++)
+ kvmppc_e500_gtlbe_invalidate(vcpu_e500, 1, esel);
+
+ _tlbil_all();
+
+ return EMULATE_DONE;
+}
+
+int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *vcpu, int ra, int rb)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ unsigned int ia;
+ int esel, tlbsel;
+ gva_t ea;
+
+ ea = ((ra) ? vcpu->arch.gpr[ra] : 0) + vcpu->arch.gpr[rb];
+
+ ia = (ea >> 2) & 0x1;
+
+ /* since we only have two TLBs, only lower bit is used. */
+ tlbsel = (ea >> 3) & 0x1;
+
+ if (ia) {
+ /* invalidate all entries */
+ for (esel = 0; esel < vcpu_e500->guest_tlb_size[tlbsel]; esel++)
+ kvmppc_e500_gtlbe_invalidate(vcpu_e500, tlbsel, esel);
+ } else {
+ ea &= 0xfffff000;
+ esel = kvmppc_e500_tlb_index(vcpu_e500, ea, tlbsel,
+ get_cur_pid(vcpu), -1);
+ if (esel >= 0)
+ kvmppc_e500_gtlbe_invalidate(vcpu_e500, tlbsel, esel);
+ }
+
+ _tlbil_all();
+
+ return EMULATE_DONE;
+}
+
+int kvmppc_e500_emul_tlbre(struct kvm_vcpu *vcpu)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ int tlbsel, esel;
+ struct tlbe *gtlbe;
+
+ tlbsel = get_tlb_tlbsel(vcpu_e500);
+ esel = get_tlb_esel(vcpu_e500, tlbsel);
+
+ gtlbe = &vcpu_e500->guest_tlb[tlbsel][esel];
+ vcpu_e500->mas0 &= ~MAS0_NV(~0);
+ vcpu_e500->mas0 |= MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]);
+ vcpu_e500->mas1 = gtlbe->mas1;
+ vcpu_e500->mas2 = gtlbe->mas2;
+ vcpu_e500->mas3 = gtlbe->mas3;
+ vcpu_e500->mas7 = gtlbe->mas7;
+
+ return EMULATE_DONE;
+}
+
+int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, int rb)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ int as = !!get_cur_sas(vcpu_e500);
+ unsigned int pid = get_cur_spid(vcpu_e500);
+ int esel, tlbsel;
+ struct tlbe *gtlbe = NULL;
+ gva_t ea;
+
+ ea = vcpu->arch.gpr[rb];
+
+ for (tlbsel = 0; tlbsel < 2; tlbsel++) {
+ esel = kvmppc_e500_tlb_index(vcpu_e500, ea, tlbsel, pid, as);
+ if (esel >= 0) {
+ gtlbe = &vcpu_e500->guest_tlb[tlbsel][esel];
+ break;
+ }
+ }
+
+ if (gtlbe) {
+ vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(esel)
+ | MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]);
+ vcpu_e500->mas1 = gtlbe->mas1;
+ vcpu_e500->mas2 = gtlbe->mas2;
+ vcpu_e500->mas3 = gtlbe->mas3;
+ vcpu_e500->mas7 = gtlbe->mas7;
+ } else {
+ int victim;
+
+ /* since we only have two TLBs, only lower bit is used. */
+ tlbsel = vcpu_e500->mas4 >> 28 & 0x1;
+ victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0;
+
+ vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim)
+ | MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]);
+ vcpu_e500->mas1 = (vcpu_e500->mas6 & MAS6_SPID0)
+ | (vcpu_e500->mas6 & (MAS6_SAS ? MAS1_TS : 0))
+ | (vcpu_e500->mas4 & MAS4_TSIZED(~0));
+ vcpu_e500->mas2 &= MAS2_EPN;
+ vcpu_e500->mas2 |= vcpu_e500->mas4 & MAS2_ATTRIB_MASK;
+ vcpu_e500->mas3 &= MAS3_U0 | MAS3_U1 | MAS3_U2 | MAS3_U3;
+ vcpu_e500->mas7 = 0;
+ }
+
+ return EMULATE_DONE;
+}
+
+int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ u64 eaddr;
+ u64 raddr;
+ u32 tid;
+ struct tlbe *gtlbe;
+ int tlbsel, esel, stlbsel, sesel;
+
+ tlbsel = get_tlb_tlbsel(vcpu_e500);
+ esel = get_tlb_esel(vcpu_e500, tlbsel);
+
+ gtlbe = &vcpu_e500->guest_tlb[tlbsel][esel];
+
+ if (get_tlb_v(gtlbe) && tlbsel == 1) {
+ eaddr = get_tlb_eaddr(gtlbe);
+ tid = get_tlb_tid(gtlbe);
+ kvmppc_e500_tlb1_invalidate(vcpu_e500, eaddr,
+ get_tlb_end(gtlbe), tid);
+ }
+
+ gtlbe->mas1 = vcpu_e500->mas1;
+ gtlbe->mas2 = vcpu_e500->mas2;
+ gtlbe->mas3 = vcpu_e500->mas3;
+ gtlbe->mas7 = vcpu_e500->mas7;
+
+ KVMTRACE_5D(GTLB_WRITE, vcpu, vcpu_e500->mas0,
+ gtlbe->mas1, gtlbe->mas2, gtlbe->mas3, gtlbe->mas7,
+ handler);
+
+ /* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */
+ if (tlbe_is_host_safe(vcpu, gtlbe)) {
+ switch (tlbsel) {
+ case 0:
+ /* TLB0 */
+ gtlbe->mas1 &= ~MAS1_TSIZE(~0);
+ gtlbe->mas1 |= MAS1_TSIZE(BOOKE_PAGESZ_4K);
+
+ stlbsel = 0;
+ sesel = kvmppc_e500_stlbe_map(vcpu_e500, 0, esel);
+
+ break;
+
+ case 1:
+ /* TLB1 */
+ eaddr = get_tlb_eaddr(gtlbe);
+ raddr = get_tlb_raddr(gtlbe);
+
+ /* Create a 4KB mapping on the host.
+ * If the guest wanted a large page,
+ * only the first 4KB is mapped here and the rest
+ * are mapped on the fly. */
+ stlbsel = 1;
+ sesel = kvmppc_e500_tlb1_map(vcpu_e500, eaddr,
+ raddr >> PAGE_SHIFT, gtlbe);
+ break;
+
+ default:
+ BUG();
+ }
+ write_host_tlbe(vcpu_e500, stlbsel, sesel);
+ }
+
+ return EMULATE_DONE;
+}
+
+int kvmppc_mmu_itlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
+{
+ unsigned int as = !!(vcpu->arch.msr & MSR_IS);
+
+ return kvmppc_e500_tlb_search(vcpu, eaddr, get_cur_pid(vcpu), as);
+}
+
+int kvmppc_mmu_dtlb_index(struct kvm_vcpu *vcpu, gva_t eaddr)
+{
+ unsigned int as = !!(vcpu->arch.msr & MSR_DS);
+
+ return kvmppc_e500_tlb_search(vcpu, eaddr, get_cur_pid(vcpu), as);
+}
+
+void kvmppc_mmu_itlb_miss(struct kvm_vcpu *vcpu)
+{
+ unsigned int as = !!(vcpu->arch.msr & MSR_IS);
+
+ kvmppc_e500_deliver_tlb_miss(vcpu, vcpu->arch.pc, as);
+}
+
+void kvmppc_mmu_dtlb_miss(struct kvm_vcpu *vcpu)
+{
+ unsigned int as = !!(vcpu->arch.msr & MSR_DS);
+
+ kvmppc_e500_deliver_tlb_miss(vcpu, vcpu->arch.fault_dear, as);
+}
+
+gpa_t kvmppc_mmu_xlate(struct kvm_vcpu *vcpu, unsigned int index,
+ gva_t eaddr)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ struct tlbe *gtlbe =
+ &vcpu_e500->guest_tlb[tlbsel_of(index)][esel_of(index)];
+ u64 pgmask = get_tlb_bytes(gtlbe) - 1;
+
+ return get_tlb_raddr(gtlbe) | (eaddr & pgmask);
+}
+
+void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ int tlbsel, i;
+
+ for (tlbsel = 0; tlbsel < 2; tlbsel++)
+ for (i = 0; i < vcpu_e500->guest_tlb_size[tlbsel]; i++)
+ kvmppc_e500_shadow_release(vcpu_e500, tlbsel, i);
+
+ /* discard all guest mapping */
+ _tlbil_all();
+}
+
+void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr,
+ unsigned int index)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ int tlbsel = tlbsel_of(index);
+ int esel = esel_of(index);
+ int stlbsel, sesel;
+
+ switch (tlbsel) {
+ case 0:
+ stlbsel = 0;
+ sesel = esel;
+ break;
+
+ case 1: {
+ gfn_t gfn = gpaddr >> PAGE_SHIFT;
+ struct tlbe *gtlbe
+ = &vcpu_e500->guest_tlb[tlbsel][esel];
+
+ stlbsel = 1;
+ sesel = kvmppc_e500_tlb1_map(vcpu_e500, eaddr, gfn, gtlbe);
+ break;
+ }
+
+ default:
+ BUG();
+ break;
+ }
+ write_host_tlbe(vcpu_e500, stlbsel, sesel);
+}
+
+int kvmppc_e500_tlb_search(struct kvm_vcpu *vcpu,
+ gva_t eaddr, unsigned int pid, int as)
+{
+ struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+ int esel, tlbsel;
+
+ for (tlbsel = 0; tlbsel < 2; tlbsel++) {
+ esel = kvmppc_e500_tlb_index(vcpu_e500, eaddr, tlbsel, pid, as);
+ if (esel >= 0)
+ return index_of(tlbsel, esel);
+ }
+
+ return -1;
+}
+
+void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+ struct tlbe *tlbe;
+
+ /* Insert large initial mapping for guest. */
+ tlbe = &vcpu_e500->guest_tlb[1][0];
+ tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOKE_PAGESZ_256M);
+ tlbe->mas2 = 0;
+ tlbe->mas3 = E500_TLB_SUPER_PERM_MASK;
+ tlbe->mas7 = 0;
+
+ /* 4K map for serial output. Used by kernel wrapper. */
+ tlbe = &vcpu_e500->guest_tlb[1][1];
+ tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOKE_PAGESZ_4K);
+ tlbe->mas2 = (0xe0004500 & 0xFFFFF000) | MAS2_I | MAS2_G;
+ tlbe->mas3 = (0xe0004500 & 0xFFFFF000) | E500_TLB_SUPER_PERM_MASK;
+ tlbe->mas7 = 0;
+}
+
+int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+ tlb1_entry_num = mfspr(SPRN_TLB1CFG) & 0xFFF;
+
+ vcpu_e500->guest_tlb_size[0] = KVM_E500_TLB0_SIZE;
+ vcpu_e500->guest_tlb[0] =
+ kzalloc(sizeof(struct tlbe) * KVM_E500_TLB0_SIZE, GFP_KERNEL);
+ if (vcpu_e500->guest_tlb[0] == NULL)
+ goto err_out;
+
+ vcpu_e500->shadow_tlb_size[0] = KVM_E500_TLB0_SIZE;
+ vcpu_e500->shadow_tlb[0] =
+ kzalloc(sizeof(struct tlbe) * KVM_E500_TLB0_SIZE, GFP_KERNEL);
+ if (vcpu_e500->shadow_tlb[0] == NULL)
+ goto err_out_guest0;
+
+ vcpu_e500->guest_tlb_size[1] = KVM_E500_TLB1_SIZE;
+ vcpu_e500->guest_tlb[1] =
+ kzalloc(sizeof(struct tlbe) * KVM_E500_TLB1_SIZE, GFP_KERNEL);
+ if (vcpu_e500->guest_tlb[1] == NULL)
+ goto err_out_shadow0;
+
+ vcpu_e500->shadow_tlb_size[1] = tlb1_entry_num;
+ vcpu_e500->shadow_tlb[1] =
+ kzalloc(sizeof(struct tlbe) * tlb1_entry_num, GFP_KERNEL);
+ if (vcpu_e500->shadow_tlb[1] == NULL)
+ goto err_out_guest1;
+
+ vcpu_e500->shadow_pages[0] = (struct page **)
+ kzalloc(sizeof(struct page *) * KVM_E500_TLB0_SIZE, GFP_KERNEL);
+ if (vcpu_e500->shadow_pages[0] == NULL)
+ goto err_out_shadow1;
+
+ vcpu_e500->shadow_pages[1] = (struct page **)
+ kzalloc(sizeof(struct page *) * tlb1_entry_num, GFP_KERNEL);
+ if (vcpu_e500->shadow_pages[1] == NULL)
+ goto err_out_page0;
+
+ return 0;
+
+err_out_page0:
+ kfree(vcpu_e500->shadow_pages[0]);
+err_out_shadow1:
+ kfree(vcpu_e500->shadow_tlb[1]);
+err_out_guest1:
+ kfree(vcpu_e500->guest_tlb[1]);
+err_out_shadow0:
+ kfree(vcpu_e500->shadow_tlb[0]);
+err_out_guest0:
+ kfree(vcpu_e500->guest_tlb[0]);
+err_out:
+ return -1;
+}
+
+void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+ kfree(vcpu_e500->shadow_pages[1]);
+ kfree(vcpu_e500->shadow_pages[0]);
+ kfree(vcpu_e500->shadow_tlb[1]);
+ kfree(vcpu_e500->guest_tlb[1]);
+ kfree(vcpu_e500->shadow_tlb[0]);
+ kfree(vcpu_e500->guest_tlb[0]);
+}
diff --git a/arch/powerpc/kvm/e500_tlb.h b/arch/powerpc/kvm/e500_tlb.h
new file mode 100644
index 000000000000..45b064b76906
--- /dev/null
+++ b/arch/powerpc/kvm/e500_tlb.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, yu.liu@freescale.com
+ *
+ * Description:
+ * This file is based on arch/powerpc/kvm/44x_tlb.h,
+ * by Hollis Blanchard <hollisb@us.ibm.com>.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __KVM_E500_TLB_H__
+#define __KVM_E500_TLB_H__
+
+#include <linux/kvm_host.h>
+#include <asm/mmu-fsl-booke.h>
+#include <asm/tlb.h>
+#include <asm/kvm_e500.h>
+
+#define KVM_E500_TLB0_WAY_SIZE_BIT 7 /* Fixed */
+#define KVM_E500_TLB0_WAY_SIZE (1UL << KVM_E500_TLB0_WAY_SIZE_BIT)
+#define KVM_E500_TLB0_WAY_SIZE_MASK (KVM_E500_TLB0_WAY_SIZE - 1)
+
+#define KVM_E500_TLB0_WAY_NUM_BIT 1 /* No greater than 7 */
+#define KVM_E500_TLB0_WAY_NUM (1UL << KVM_E500_TLB0_WAY_NUM_BIT)
+#define KVM_E500_TLB0_WAY_NUM_MASK (KVM_E500_TLB0_WAY_NUM - 1)
+
+#define KVM_E500_TLB0_SIZE (KVM_E500_TLB0_WAY_SIZE * KVM_E500_TLB0_WAY_NUM)
+#define KVM_E500_TLB1_SIZE 16
+
+#define index_of(tlbsel, esel) (((tlbsel) << 16) | ((esel) & 0xFFFF))
+#define tlbsel_of(index) ((index) >> 16)
+#define esel_of(index) ((index) & 0xFFFF)
+
+#define E500_TLB_USER_PERM_MASK (MAS3_UX|MAS3_UR|MAS3_UW)
+#define E500_TLB_SUPER_PERM_MASK (MAS3_SX|MAS3_SR|MAS3_SW)
+#define MAS2_ATTRIB_MASK \
+ (MAS2_X0 | MAS2_X1)
+#define MAS3_ATTRIB_MASK \
+ (MAS3_U0 | MAS3_U1 | MAS3_U2 | MAS3_U3 \
+ | E500_TLB_USER_PERM_MASK | E500_TLB_SUPER_PERM_MASK)
+
+extern void kvmppc_dump_tlbs(struct kvm_vcpu *);
+extern int kvmppc_e500_emul_mt_mmucsr0(struct kvmppc_vcpu_e500 *, ulong);
+extern int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *);
+extern int kvmppc_e500_emul_tlbre(struct kvm_vcpu *);
+extern int kvmppc_e500_emul_tlbivax(struct kvm_vcpu *, int, int);
+extern int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *, int);
+extern int kvmppc_e500_tlb_search(struct kvm_vcpu *, gva_t, unsigned int, int);
+extern void kvmppc_e500_tlb_put(struct kvm_vcpu *);
+extern void kvmppc_e500_tlb_load(struct kvm_vcpu *, int);
+extern int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *);
+extern void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *);
+extern void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *);
+
+/* TLB helper functions */
+static inline unsigned int get_tlb_size(const struct tlbe *tlbe)
+{
+ return (tlbe->mas1 >> 8) & 0xf;
+}
+
+static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe)
+{
+ return tlbe->mas2 & 0xfffff000;
+}
+
+static inline u64 get_tlb_bytes(const struct tlbe *tlbe)
+{
+ unsigned int pgsize = get_tlb_size(tlbe);
+ return 1ULL << 10 << (pgsize << 1);
+}
+
+static inline gva_t get_tlb_end(const struct tlbe *tlbe)
+{
+ u64 bytes = get_tlb_bytes(tlbe);
+ return get_tlb_eaddr(tlbe) + bytes - 1;
+}
+
+static inline u64 get_tlb_raddr(const struct tlbe *tlbe)
+{
+ u64 rpn = tlbe->mas7;
+ return (rpn << 32) | (tlbe->mas3 & 0xfffff000);
+}
+
+static inline unsigned int get_tlb_tid(const struct tlbe *tlbe)
+{
+ return (tlbe->mas1 >> 16) & 0xff;
+}
+
+static inline unsigned int get_tlb_ts(const struct tlbe *tlbe)
+{
+ return (tlbe->mas1 >> 12) & 0x1;
+}
+
+static inline unsigned int get_tlb_v(const struct tlbe *tlbe)
+{
+ return (tlbe->mas1 >> 31) & 0x1;
+}
+
+static inline unsigned int get_tlb_iprot(const struct tlbe *tlbe)
+{
+ return (tlbe->mas1 >> 30) & 0x1;
+}
+
+static inline unsigned int get_cur_pid(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.pid & 0xff;
+}
+
+static inline unsigned int get_cur_spid(
+ const struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+ return (vcpu_e500->mas6 >> 16) & 0xff;
+}
+
+static inline unsigned int get_cur_sas(
+ const struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+ return vcpu_e500->mas6 & 0x1;
+}
+
+static inline unsigned int get_tlb_tlbsel(
+ const struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+ /*
+ * Manual says that tlbsel has 2 bits wide.
+ * Since we only have two TLBs, only lower bit is used.
+ */
+ return (vcpu_e500->mas0 >> 28) & 0x1;
+}
+
+static inline unsigned int get_tlb_nv_bit(
+ const struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+ return vcpu_e500->mas0 & 0xfff;
+}
+
+static inline unsigned int get_tlb_esel_bit(
+ const struct kvmppc_vcpu_e500 *vcpu_e500)
+{
+ return (vcpu_e500->mas0 >> 16) & 0xfff;
+}
+
+static inline unsigned int get_tlb_esel(
+ const struct kvmppc_vcpu_e500 *vcpu_e500,
+ int tlbsel)
+{
+ unsigned int esel = get_tlb_esel_bit(vcpu_e500);
+
+ if (tlbsel == 0) {
+ esel &= KVM_E500_TLB0_WAY_NUM_MASK;
+ esel |= ((vcpu_e500->mas2 >> 12) & KVM_E500_TLB0_WAY_SIZE_MASK)
+ << KVM_E500_TLB0_WAY_NUM_BIT;
+ } else {
+ esel &= KVM_E500_TLB1_SIZE - 1;
+ }
+
+ return esel;
+}
+
+static inline int tlbe_is_host_safe(const struct kvm_vcpu *vcpu,
+ const struct tlbe *tlbe)
+{
+ gpa_t gpa;
+
+ if (!get_tlb_v(tlbe))
+ return 0;
+
+ /* Does it match current guest AS? */
+ /* XXX what about IS != DS? */
+ if (get_tlb_ts(tlbe) != !!(vcpu->arch.msr & MSR_IS))
+ return 0;
+
+ gpa = get_tlb_raddr(tlbe);
+ if (!gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT))
+ /* Mapping is not for RAM. */
+ return 0;
+
+ return 1;
+}
+
+#endif /* __KVM_E500_TLB_H__ */
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index d1d38daa93fb..a561d6e8da1c 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -30,6 +30,39 @@
#include <asm/disassemble.h>
#include "timing.h"
+#define OP_TRAP 3
+
+#define OP_31_XOP_LWZX 23
+#define OP_31_XOP_LBZX 87
+#define OP_31_XOP_STWX 151
+#define OP_31_XOP_STBX 215
+#define OP_31_XOP_STBUX 247
+#define OP_31_XOP_LHZX 279
+#define OP_31_XOP_LHZUX 311
+#define OP_31_XOP_MFSPR 339
+#define OP_31_XOP_STHX 407
+#define OP_31_XOP_STHUX 439
+#define OP_31_XOP_MTSPR 467
+#define OP_31_XOP_DCBI 470
+#define OP_31_XOP_LWBRX 534
+#define OP_31_XOP_TLBSYNC 566
+#define OP_31_XOP_STWBRX 662
+#define OP_31_XOP_LHBRX 790
+#define OP_31_XOP_STHBRX 918
+
+#define OP_LWZ 32
+#define OP_LWZU 33
+#define OP_LBZ 34
+#define OP_LBZU 35
+#define OP_STW 36
+#define OP_STWU 37
+#define OP_STB 38
+#define OP_STBU 39
+#define OP_LHZ 40
+#define OP_LHZU 41
+#define OP_STH 44
+#define OP_STHU 45
+
void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
{
if (vcpu->arch.tcr & TCR_DIE) {
@@ -78,7 +111,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
kvmppc_set_exit_type(vcpu, EMULATED_INST_EXITS);
switch (get_op(inst)) {
- case 3: /* trap */
+ case OP_TRAP:
vcpu->arch.esr |= ESR_PTR;
kvmppc_core_queue_program(vcpu);
advance = 0;
@@ -87,31 +120,31 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
case 31:
switch (get_xop(inst)) {
- case 23: /* lwzx */
+ case OP_31_XOP_LWZX:
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
break;
- case 87: /* lbzx */
+ case OP_31_XOP_LBZX:
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
break;
- case 151: /* stwx */
+ case OP_31_XOP_STWX:
rs = get_rs(inst);
emulated = kvmppc_handle_store(run, vcpu,
vcpu->arch.gpr[rs],
4, 1);
break;
- case 215: /* stbx */
+ case OP_31_XOP_STBX:
rs = get_rs(inst);
emulated = kvmppc_handle_store(run, vcpu,
vcpu->arch.gpr[rs],
1, 1);
break;
- case 247: /* stbux */
+ case OP_31_XOP_STBUX:
rs = get_rs(inst);
ra = get_ra(inst);
rb = get_rb(inst);
@@ -126,12 +159,12 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
vcpu->arch.gpr[rs] = ea;
break;
- case 279: /* lhzx */
+ case OP_31_XOP_LHZX:
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
break;
- case 311: /* lhzux */
+ case OP_31_XOP_LHZUX:
rt = get_rt(inst);
ra = get_ra(inst);
rb = get_rb(inst);
@@ -144,7 +177,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
vcpu->arch.gpr[ra] = ea;
break;
- case 339: /* mfspr */
+ case OP_31_XOP_MFSPR:
sprn = get_sprn(inst);
rt = get_rt(inst);
@@ -185,7 +218,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
}
break;
- case 407: /* sthx */
+ case OP_31_XOP_STHX:
rs = get_rs(inst);
ra = get_ra(inst);
rb = get_rb(inst);
@@ -195,7 +228,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
2, 1);
break;
- case 439: /* sthux */
+ case OP_31_XOP_STHUX:
rs = get_rs(inst);
ra = get_ra(inst);
rb = get_rb(inst);
@@ -210,7 +243,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
vcpu->arch.gpr[ra] = ea;
break;
- case 467: /* mtspr */
+ case OP_31_XOP_MTSPR:
sprn = get_sprn(inst);
rs = get_rs(inst);
switch (sprn) {
@@ -246,7 +279,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
}
break;
- case 470: /* dcbi */
+ case OP_31_XOP_DCBI:
/* Do nothing. The guest is performing dcbi because
* hardware DMA is not snooped by the dcache, but
* emulated DMA either goes through the dcache as
@@ -254,15 +287,15 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
* coherence. */
break;
- case 534: /* lwbrx */
+ case OP_31_XOP_LWBRX:
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 4, 0);
break;
- case 566: /* tlbsync */
+ case OP_31_XOP_TLBSYNC:
break;
- case 662: /* stwbrx */
+ case OP_31_XOP_STWBRX:
rs = get_rs(inst);
ra = get_ra(inst);
rb = get_rb(inst);
@@ -272,12 +305,12 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
4, 0);
break;
- case 790: /* lhbrx */
+ case OP_31_XOP_LHBRX:
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 2, 0);
break;
- case 918: /* sthbrx */
+ case OP_31_XOP_STHBRX:
rs = get_rs(inst);
ra = get_ra(inst);
rb = get_rb(inst);
@@ -293,37 +326,37 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
}
break;
- case 32: /* lwz */
+ case OP_LWZ:
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
break;
- case 33: /* lwzu */
+ case OP_LWZU:
ra = get_ra(inst);
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1);
vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
break;
- case 34: /* lbz */
+ case OP_LBZ:
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
break;
- case 35: /* lbzu */
+ case OP_LBZU:
ra = get_ra(inst);
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1);
vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
break;
- case 36: /* stw */
+ case OP_STW:
rs = get_rs(inst);
emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
4, 1);
break;
- case 37: /* stwu */
+ case OP_STWU:
ra = get_ra(inst);
rs = get_rs(inst);
emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
@@ -331,13 +364,13 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
break;
- case 38: /* stb */
+ case OP_STB:
rs = get_rs(inst);
emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
1, 1);
break;
- case 39: /* stbu */
+ case OP_STBU:
ra = get_ra(inst);
rs = get_rs(inst);
emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
@@ -345,25 +378,25 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
break;
- case 40: /* lhz */
+ case OP_LHZ:
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
break;
- case 41: /* lhzu */
+ case OP_LHZU:
ra = get_ra(inst);
rt = get_rt(inst);
emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1);
vcpu->arch.gpr[ra] = vcpu->arch.paddr_accessed;
break;
- case 44: /* sth */
+ case OP_STH:
rs = get_rs(inst);
emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
2, 1);
break;
- case 45: /* sthu */
+ case OP_STHU:
ra = get_ra(inst);
rs = get_rs(inst);
emulated = kvmppc_handle_store(run, vcpu, vcpu->arch.gpr[rs],
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 5f81256287f5..9057335fdc61 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -216,46 +216,23 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
{
- kvmppc_core_destroy_mmu(vcpu);
+ kvmppc_mmu_destroy(vcpu);
}
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
- if (vcpu->guest_debug.enabled)
- kvmppc_core_load_guest_debugstate(vcpu);
-
kvmppc_core_vcpu_load(vcpu, cpu);
}
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
{
- if (vcpu->guest_debug.enabled)
- kvmppc_core_load_host_debugstate(vcpu);
-
- /* Don't leave guest TLB entries resident when being de-scheduled. */
- /* XXX It would be nice to differentiate between heavyweight exit and
- * sched_out here, since we could avoid the TLB flush for heavyweight
- * exits. */
- _tlbil_all();
kvmppc_core_vcpu_put(vcpu);
}
-int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
- struct kvm_debug_guest *dbg)
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+ struct kvm_guest_debug *dbg)
{
- int i;
-
- vcpu->guest_debug.enabled = dbg->enabled;
- if (vcpu->guest_debug.enabled) {
- for (i=0; i < ARRAY_SIZE(vcpu->guest_debug.bp); i++) {
- if (dbg->breakpoints[i].enabled)
- vcpu->guest_debug.bp[i] = dbg->breakpoints[i].address;
- else
- vcpu->guest_debug.bp[i] = 0;
- }
- }
-
- return 0;
+ return -EINVAL;
}
static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu,
diff --git a/arch/powerpc/lib/dma-noncoherent.c b/arch/powerpc/lib/dma-noncoherent.c
index b7dc4c19f582..005a28d380af 100644
--- a/arch/powerpc/lib/dma-noncoherent.c
+++ b/arch/powerpc/lib/dma-noncoherent.c
@@ -29,121 +29,11 @@
#include <linux/types.h>
#include <linux/highmem.h>
#include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
#include <asm/tlbflush.h>
/*
- * This address range defaults to a value that is safe for all
- * platforms which currently set CONFIG_NOT_COHERENT_CACHE. It
- * can be further configured for specific applications under
- * the "Advanced Setup" menu. -Matt
- */
-#define CONSISTENT_BASE (CONFIG_CONSISTENT_START)
-#define CONSISTENT_END (CONFIG_CONSISTENT_START + CONFIG_CONSISTENT_SIZE)
-#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
-
-/*
- * This is the page table (2MB) covering uncached, DMA consistent allocations
- */
-static pte_t *consistent_pte;
-static DEFINE_SPINLOCK(consistent_lock);
-
-/*
- * VM region handling support.
- *
- * This should become something generic, handling VM region allocations for
- * vmalloc and similar (ioremap, module space, etc).
- *
- * I envisage vmalloc()'s supporting vm_struct becoming:
- *
- * struct vm_struct {
- * struct vm_region region;
- * unsigned long flags;
- * struct page **pages;
- * unsigned int nr_pages;
- * unsigned long phys_addr;
- * };
- *
- * get_vm_area() would then call vm_region_alloc with an appropriate
- * struct vm_region head (eg):
- *
- * struct vm_region vmalloc_head = {
- * .vm_list = LIST_HEAD_INIT(vmalloc_head.vm_list),
- * .vm_start = VMALLOC_START,
- * .vm_end = VMALLOC_END,
- * };
- *
- * However, vmalloc_head.vm_start is variable (typically, it is dependent on
- * the amount of RAM found at boot time.) I would imagine that get_vm_area()
- * would have to initialise this each time prior to calling vm_region_alloc().
- */
-struct ppc_vm_region {
- struct list_head vm_list;
- unsigned long vm_start;
- unsigned long vm_end;
-};
-
-static struct ppc_vm_region consistent_head = {
- .vm_list = LIST_HEAD_INIT(consistent_head.vm_list),
- .vm_start = CONSISTENT_BASE,
- .vm_end = CONSISTENT_END,
-};
-
-static struct ppc_vm_region *
-ppc_vm_region_alloc(struct ppc_vm_region *head, size_t size, gfp_t gfp)
-{
- unsigned long addr = head->vm_start, end = head->vm_end - size;
- unsigned long flags;
- struct ppc_vm_region *c, *new;
-
- new = kmalloc(sizeof(struct ppc_vm_region), gfp);
- if (!new)
- goto out;
-
- spin_lock_irqsave(&consistent_lock, flags);
-
- list_for_each_entry(c, &head->vm_list, vm_list) {
- if ((addr + size) < addr)
- goto nospc;
- if ((addr + size) <= c->vm_start)
- goto found;
- addr = c->vm_end;
- if (addr > end)
- goto nospc;
- }
-
- found:
- /*
- * Insert this entry _before_ the one we found.
- */
- list_add_tail(&new->vm_list, &c->vm_list);
- new->vm_start = addr;
- new->vm_end = addr + size;
-
- spin_unlock_irqrestore(&consistent_lock, flags);
- return new;
-
- nospc:
- spin_unlock_irqrestore(&consistent_lock, flags);
- kfree(new);
- out:
- return NULL;
-}
-
-static struct ppc_vm_region *ppc_vm_region_find(struct ppc_vm_region *head, unsigned long addr)
-{
- struct ppc_vm_region *c;
-
- list_for_each_entry(c, &head->vm_list, vm_list) {
- if (c->vm_start == addr)
- goto out;
- }
- c = NULL;
- out:
- return c;
-}
-
-/*
* Allocate DMA-coherent memory space and return both the kernel remapped
* virtual and bus address for that space.
*/
@@ -151,21 +41,21 @@ void *
__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp)
{
struct page *page;
- struct ppc_vm_region *c;
unsigned long order;
+ int i;
+ unsigned int nr_pages = PAGE_ALIGN(size)>>PAGE_SHIFT;
+ unsigned int array_size = nr_pages * sizeof(struct page *);
+ struct page **pages;
+ struct page *end;
u64 mask = 0x00ffffff, limit; /* ISA default */
+ struct vm_struct *area;
- if (!consistent_pte) {
- printk(KERN_ERR "%s: not initialised\n", __func__);
- dump_stack();
- return NULL;
- }
-
+ BUG_ON(!mem_init_done);
size = PAGE_ALIGN(size);
limit = (mask + 1) & ~mask;
- if ((limit && size >= limit) || size >= (CONSISTENT_END - CONSISTENT_BASE)) {
- printk(KERN_WARNING "coherent allocation too big (requested %#x mask %#Lx)\n",
- size, mask);
+ if (limit && size >= limit) {
+ printk(KERN_WARNING "coherent allocation too big (requested "
+ "%#x mask %#Lx)\n", size, mask);
return NULL;
}
@@ -178,6 +68,8 @@ __dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp)
if (!page)
goto no_page;
+ end = page + (1 << order);
+
/*
* Invalidate any data that might be lurking in the
* kernel direct-mapped region for device DMA.
@@ -188,48 +80,59 @@ __dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp)
flush_dcache_range(kaddr, kaddr + size);
}
+ split_page(page, order);
+
/*
- * Allocate a virtual address in the consistent mapping region.
+ * Set the "dma handle"
*/
- c = ppc_vm_region_alloc(&consistent_head, size,
- gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
- if (c) {
- unsigned long vaddr = c->vm_start;
- pte_t *pte = consistent_pte + CONSISTENT_OFFSET(vaddr);
- struct page *end = page + (1 << order);
-
- split_page(page, order);
-
- /*
- * Set the "dma handle"
- */
- *handle = page_to_phys(page);
+ *handle = page_to_phys(page);
+
+ area = get_vm_area_caller(size, VM_IOREMAP,
+ __builtin_return_address(1));
+ if (!area)
+ goto out_free_pages;
+
+ if (array_size > PAGE_SIZE) {
+ pages = vmalloc(array_size);
+ area->flags |= VM_VPAGES;
+ } else {
+ pages = kmalloc(array_size, GFP_KERNEL);
+ }
+ if (!pages)
+ goto out_free_area;
- do {
- BUG_ON(!pte_none(*pte));
+ area->pages = pages;
+ area->nr_pages = nr_pages;
- SetPageReserved(page);
- set_pte_at(&init_mm, vaddr,
- pte, mk_pte(page, pgprot_noncached(PAGE_KERNEL)));
- page++;
- pte++;
- vaddr += PAGE_SIZE;
- } while (size -= PAGE_SIZE);
+ for (i = 0; i < nr_pages; i++)
+ pages[i] = page + i;
- /*
- * Free the otherwise unused pages.
- */
- while (page < end) {
- __free_page(page);
- page++;
- }
+ if (map_vm_area(area, pgprot_noncached(PAGE_KERNEL), &pages))
+ goto out_unmap;
- return (void *)c->vm_start;
+ /*
+ * Free the otherwise unused pages.
+ */
+ page += nr_pages;
+ while (page < end) {
+ __free_page(page);
+ page++;
}
+ return area->addr;
+out_unmap:
+ vunmap(area->addr);
+ if (array_size > PAGE_SIZE)
+ vfree(pages);
+ else
+ kfree(pages);
+ goto out_free_pages;
+out_free_area:
+ free_vm_area(area);
+out_free_pages:
if (page)
__free_pages(page, order);
- no_page:
+no_page:
return NULL;
}
EXPORT_SYMBOL(__dma_alloc_coherent);
@@ -239,104 +142,12 @@ EXPORT_SYMBOL(__dma_alloc_coherent);
*/
void __dma_free_coherent(size_t size, void *vaddr)
{
- struct ppc_vm_region *c;
- unsigned long flags, addr;
- pte_t *ptep;
-
- size = PAGE_ALIGN(size);
-
- spin_lock_irqsave(&consistent_lock, flags);
-
- c = ppc_vm_region_find(&consistent_head, (unsigned long)vaddr);
- if (!c)
- goto no_area;
-
- if ((c->vm_end - c->vm_start) != size) {
- printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
- __func__, c->vm_end - c->vm_start, size);
- dump_stack();
- size = c->vm_end - c->vm_start;
- }
-
- ptep = consistent_pte + CONSISTENT_OFFSET(c->vm_start);
- addr = c->vm_start;
- do {
- pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
- unsigned long pfn;
-
- ptep++;
- addr += PAGE_SIZE;
+ vfree(vaddr);
- if (!pte_none(pte) && pte_present(pte)) {
- pfn = pte_pfn(pte);
-
- if (pfn_valid(pfn)) {
- struct page *page = pfn_to_page(pfn);
- ClearPageReserved(page);
-
- __free_page(page);
- continue;
- }
- }
-
- printk(KERN_CRIT "%s: bad page in kernel page table\n",
- __func__);
- } while (size -= PAGE_SIZE);
-
- flush_tlb_kernel_range(c->vm_start, c->vm_end);
-
- list_del(&c->vm_list);
-
- spin_unlock_irqrestore(&consistent_lock, flags);
-
- kfree(c);
- return;
-
- no_area:
- spin_unlock_irqrestore(&consistent_lock, flags);
- printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
- __func__, vaddr);
- dump_stack();
}
EXPORT_SYMBOL(__dma_free_coherent);
/*
- * Initialise the consistent memory allocation.
- */
-static int __init dma_alloc_init(void)
-{
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
- int ret = 0;
-
- do {
- pgd = pgd_offset(&init_mm, CONSISTENT_BASE);
- pud = pud_alloc(&init_mm, pgd, CONSISTENT_BASE);
- pmd = pmd_alloc(&init_mm, pud, CONSISTENT_BASE);
- if (!pmd) {
- printk(KERN_ERR "%s: no pmd tables\n", __func__);
- ret = -ENOMEM;
- break;
- }
-
- pte = pte_alloc_kernel(pmd, CONSISTENT_BASE);
- if (!pte) {
- printk(KERN_ERR "%s: no pte tables\n", __func__);
- ret = -ENOMEM;
- break;
- }
-
- consistent_pte = pte;
- } while (0);
-
- return ret;
-}
-
-core_initcall(dma_alloc_init);
-
-/*
* make an area consistent.
*/
void __dma_sync(void *vaddr, size_t size, int direction)
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index 8c5a03be31e0..7e8865bcd683 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -85,7 +85,7 @@ static int patch_feature_section(unsigned long value, struct fixup_entry *fcur)
}
for (; dest < end; dest++)
- patch_instruction(dest, PPC_NOP_INSTR);
+ patch_instruction(dest, PPC_INST_NOP);
return 0;
}
@@ -122,7 +122,7 @@ void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
for (; start < end; start++) {
dest = (void *)start + *start;
- patch_instruction(dest, PPC_LWSYNC_INSTR);
+ patch_instruction(dest, PPC_INST_LWSYNC);
}
}
diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile
index f9e506a735ae..0c16ab947f1f 100644
--- a/arch/powerpc/math-emu/Makefile
+++ b/arch/powerpc/math-emu/Makefile
@@ -1,6 +1,4 @@
-obj-y := math.o fmr.o lfd.o stfd.o
-
obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
fctiw.o fctiwz.o fdiv.o fdivs.o \
fmadd.o fmadds.o fmsub.o fmsubs.o \
@@ -9,7 +7,8 @@ obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
fres.o frsp.o frsqrte.o fsel.o lfs.o \
fsqrt.o fsqrts.o fsub.o fsubs.o \
mcrfs.o mffs.o mtfsb0.o mtfsb1.o \
- mtfsf.o mtfsfi.o stfiwx.o stfs.o
+ mtfsf.o mtfsfi.o stfiwx.o stfs.o \
+ math.o fmr.o lfd.o stfd.o
obj-$(CONFIG_SPE) += math_efp.o
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 953cc4a1cde5..17290bcedc5e 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -6,7 +6,7 @@ ifeq ($(CONFIG_PPC64),y)
EXTRA_CFLAGS += -mno-minimal-toc
endif
-obj-y := fault.o mem.o pgtable.o \
+obj-y := fault.o mem.o pgtable.o gup.o \
init_$(CONFIG_WORD_SIZE).o \
pgtable_$(CONFIG_WORD_SIZE).o
obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \
@@ -14,7 +14,7 @@ obj-$(CONFIG_PPC_MMU_NOHASH) += mmu_context_nohash.o tlb_nohash.o \
hash-$(CONFIG_PPC_NATIVE) := hash_native_64.o
obj-$(CONFIG_PPC64) += hash_utils_64.o \
slb_low.o slb.o stab.o \
- gup.o mmap.o $(hash-y)
+ mmap_64.o $(hash-y)
obj-$(CONFIG_PPC_STD_MMU_32) += ppc_mmu_32.o
obj-$(CONFIG_PPC_STD_MMU) += hash_low_$(CONFIG_WORD_SIZE).o \
tlb_hash$(CONFIG_WORD_SIZE).o \
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 91c7b8636b8a..76993941cac9 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -253,45 +253,33 @@ good_area:
#endif /* CONFIG_8xx */
if (is_exec) {
-#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
- /* protection fault */
+#ifdef CONFIG_PPC_STD_MMU
+ /* Protection fault on exec go straight to failure on
+ * Hash based MMUs as they either don't support per-page
+ * execute permission, or if they do, it's handled already
+ * at the hash level. This test would probably have to
+ * be removed if we change the way this works to make hash
+ * processors use the same I/D cache coherency mechanism
+ * as embedded.
+ */
if (error_code & DSISR_PROTFAULT)
goto bad_area;
+#endif /* CONFIG_PPC_STD_MMU */
+
/*
* Allow execution from readable areas if the MMU does not
* provide separate controls over reading and executing.
+ *
+ * Note: That code used to not be enabled for 4xx/BookE.
+ * It is now as I/D cache coherency for these is done at
+ * set_pte_at() time and I see no reason why the test
+ * below wouldn't be valid on those processors. This -may-
+ * break programs compiled with a really old ABI though.
*/
if (!(vma->vm_flags & VM_EXEC) &&
(cpu_has_feature(CPU_FTR_NOEXECUTE) ||
!(vma->vm_flags & (VM_READ | VM_WRITE))))
goto bad_area;
-#else
- pte_t *ptep;
- pmd_t *pmdp;
-
- /* Since 4xx/Book-E supports per-page execute permission,
- * we lazily flush dcache to icache. */
- ptep = NULL;
- if (get_pteptr(mm, address, &ptep, &pmdp)) {
- spinlock_t *ptl = pte_lockptr(mm, pmdp);
- spin_lock(ptl);
- if (pte_present(*ptep)) {
- struct page *page = pte_page(*ptep);
-
- if (!test_bit(PG_arch_1, &page->flags)) {
- flush_dcache_icache_page(page);
- set_bit(PG_arch_1, &page->flags);
- }
- pte_update(ptep, 0, _PAGE_HWEXEC |
- _PAGE_ACCESSED);
- local_flush_tlb_page(vma, address);
- pte_unmap_unlock(ptep, ptl);
- up_read(&mm->mmap_sem);
- return 0;
- }
- pte_unmap_unlock(ptep, ptl);
- }
-#endif
/* a write */
} else if (is_write) {
if (!(vma->vm_flags & VM_WRITE))
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index ea6e41e39d9f..bb3d65998e6b 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -56,10 +56,14 @@
extern void loadcam_entry(unsigned int index);
unsigned int tlbcam_index;
-static unsigned long __cam0, __cam1, __cam2;
+static unsigned long cam[CONFIG_LOWMEM_CAM_NUM];
#define NUM_TLBCAMS (16)
+#if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS)
+#error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS"
+#endif
+
struct tlbcam TLBCAM[NUM_TLBCAMS];
struct tlbcamrange {
@@ -107,7 +111,7 @@ void settlbcam(int index, unsigned long virt, phys_addr_t phys,
unsigned int tsize, lz;
asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size));
- tsize = (21 - lz) / 2;
+ tsize = 21 - lz;
#ifdef CONFIG_SMP
if ((flags & _PAGE_NO_CACHE) == 0)
@@ -152,19 +156,19 @@ void invalidate_tlbcam_entry(int index)
loadcam_entry(index);
}
-void __init cam_mapin_ram(unsigned long cam0, unsigned long cam1,
- unsigned long cam2)
+unsigned long __init mmu_mapin_ram(void)
{
- settlbcam(0, PAGE_OFFSET, memstart_addr, cam0, _PAGE_KERNEL, 0);
- tlbcam_index++;
- if (cam1) {
- tlbcam_index++;
- settlbcam(1, PAGE_OFFSET+cam0, memstart_addr+cam0, cam1, _PAGE_KERNEL, 0);
- }
- if (cam2) {
+ unsigned long virt = PAGE_OFFSET;
+ phys_addr_t phys = memstart_addr;
+
+ while (cam[tlbcam_index] && tlbcam_index < ARRAY_SIZE(cam)) {
+ settlbcam(tlbcam_index, virt, phys, cam[tlbcam_index], PAGE_KERNEL_X, 0);
+ virt += cam[tlbcam_index];
+ phys += cam[tlbcam_index];
tlbcam_index++;
- settlbcam(2, PAGE_OFFSET+cam0+cam1, memstart_addr+cam0+cam1, cam2, _PAGE_KERNEL, 0);
}
+
+ return virt - PAGE_OFFSET;
}
/*
@@ -175,51 +179,46 @@ void __init MMU_init_hw(void)
flush_instruction_cache();
}
-unsigned long __init mmu_mapin_ram(void)
-{
- cam_mapin_ram(__cam0, __cam1, __cam2);
-
- return __cam0 + __cam1 + __cam2;
-}
-
-
void __init
adjust_total_lowmem(void)
{
- phys_addr_t max_lowmem_size = __max_low_memory;
- phys_addr_t cam_max_size = 0x10000000;
phys_addr_t ram;
+ unsigned int max_cam = (mfspr(SPRN_TLB1CFG) >> 16) & 0xff;
+ char buf[ARRAY_SIZE(cam) * 5 + 1], *p = buf;
+ int i;
+ unsigned long virt = PAGE_OFFSET & 0xffffffffUL;
+ unsigned long phys = memstart_addr & 0xffffffffUL;
- /* adjust CAM size to max_lowmem_size */
- if (max_lowmem_size < cam_max_size)
- cam_max_size = max_lowmem_size;
+ /* Convert (4^max) kB to (2^max) bytes */
+ max_cam = max_cam * 2 + 10;
- /* adjust lowmem size to max_lowmem_size */
- ram = min(max_lowmem_size, total_lowmem);
+ /* adjust lowmem size to __max_low_memory */
+ ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem);
/* Calculate CAM values */
- __cam0 = 1UL << 2 * (__ilog2(ram) / 2);
- if (__cam0 > cam_max_size)
- __cam0 = cam_max_size;
- ram -= __cam0;
- if (ram) {
- __cam1 = 1UL << 2 * (__ilog2(ram) / 2);
- if (__cam1 > cam_max_size)
- __cam1 = cam_max_size;
- ram -= __cam1;
- }
- if (ram) {
- __cam2 = 1UL << 2 * (__ilog2(ram) / 2);
- if (__cam2 > cam_max_size)
- __cam2 = cam_max_size;
- ram -= __cam2;
+ __max_low_memory = 0;
+ for (i = 0; ram && i < ARRAY_SIZE(cam); i++) {
+ unsigned int camsize = __ilog2(ram) & ~1U;
+ unsigned int align = __ffs(virt | phys) & ~1U;
+
+ if (camsize > align)
+ camsize = align;
+ if (camsize > max_cam)
+ camsize = max_cam;
+
+ cam[i] = 1UL << camsize;
+ ram -= cam[i];
+ __max_low_memory += cam[i];
+ virt += cam[i];
+ phys += cam[i];
+
+ p += sprintf(p, "%lu/", cam[i] >> 20);
}
+ for (; i < ARRAY_SIZE(cam); i++)
+ p += sprintf(p, "0/");
+ p[-1] = '\0';
- printk(KERN_INFO "Memory CAM mapping: CAM0=%ldMb, CAM1=%ldMb,"
- " CAM2=%ldMb residual: %ldMb\n",
- __cam0 >> 20, __cam1 >> 20, __cam2 >> 20,
- (long int)((total_lowmem - __cam0 - __cam1 - __cam2)
- >> 20));
- __max_low_memory = __cam0 + __cam1 + __cam2;
+ pr_info("Memory CAM mapping: %s Mb, residual: %dMb\n", buf,
+ (unsigned int)((total_lowmem - __max_low_memory) >> 20));
__initial_memory_limit_addr = memstart_addr + __max_low_memory;
}
diff --git a/arch/powerpc/mm/gup.c b/arch/powerpc/mm/gup.c
index 28a114db3ba0..bc400c78c97f 100644
--- a/arch/powerpc/mm/gup.c
+++ b/arch/powerpc/mm/gup.c
@@ -14,6 +14,8 @@
#include <linux/rwsem.h>
#include <asm/pgtable.h>
+#ifdef __HAVE_ARCH_PTE_SPECIAL
+
/*
* The performance critical leaf functions are made noinline otherwise gcc
* inlines everything into a single function which results in too much
@@ -151,8 +153,11 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
unsigned long addr, len, end;
unsigned long next;
pgd_t *pgdp;
- int psize, nr = 0;
+ int nr = 0;
+#ifdef CONFIG_PPC64
unsigned int shift;
+ int psize;
+#endif
pr_debug("%s(%lx,%x,%s)\n", __func__, start, nr_pages, write ? "write" : "read");
@@ -205,8 +210,13 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
*/
local_irq_disable();
+#ifdef CONFIG_PPC64
+ /* Those bits are related to hugetlbfs implementation and only exist
+ * on 64-bit for now
+ */
psize = get_slice_psize(mm, addr);
shift = mmu_psize_defs[psize].shift;
+#endif /* CONFIG_PPC64 */
#ifdef CONFIG_HUGETLB_PAGE
if (unlikely(mmu_huge_psizes[psize])) {
@@ -236,7 +246,9 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
do {
pgd_t pgd = *pgdp;
+#ifdef CONFIG_PPC64
VM_BUG_ON(shift != mmu_psize_defs[get_slice_psize(mm, addr)].shift);
+#endif
pr_debug(" %016lx: normal pgd %p\n", addr,
(void *)pgd_val(pgd));
next = pgd_addr_end(addr, end);
@@ -279,3 +291,5 @@ slow_irqon:
return ret;
}
}
+
+#endif /* __HAVE_ARCH_PTE_SPECIAL */
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 8d5b4758c13a..db556d25c3a7 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -516,7 +516,7 @@ static int __init htab_dt_scan_pftsize(unsigned long node,
static unsigned long __init htab_get_table_size(void)
{
- unsigned long mem_size, rnd_mem_size, pteg_count;
+ unsigned long mem_size, rnd_mem_size, pteg_count, psize;
/* If hash size isn't already provided by the platform, we try to
* retrieve it from the device-tree. If it's not there neither, we
@@ -534,7 +534,8 @@ static unsigned long __init htab_get_table_size(void)
rnd_mem_size <<= 1;
/* # pages / 2 */
- pteg_count = max(rnd_mem_size >> (12 + 1), 1UL << 11);
+ psize = mmu_psize_defs[mmu_virtual_psize].shift;
+ pteg_count = max(rnd_mem_size >> (psize + 1), 1UL << 11);
return pteg_count << 7;
}
@@ -589,7 +590,7 @@ static void __init htab_finish_init(void)
make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
}
-void __init htab_initialize(void)
+static void __init htab_initialize(void)
{
unsigned long table;
unsigned long pteg_count;
@@ -731,11 +732,43 @@ void __init htab_initialize(void)
#undef KB
#undef MB
-void htab_initialize_secondary(void)
+void __init early_init_mmu(void)
{
+ /* Setup initial STAB address in the PACA */
+ get_paca()->stab_real = __pa((u64)&initial_stab);
+ get_paca()->stab_addr = (u64)&initial_stab;
+
+ /* Initialize the MMU Hash table and create the linear mapping
+ * of memory. Has to be done before stab/slb initialization as
+ * this is currently where the page size encoding is obtained
+ */
+ htab_initialize();
+
+ /* Initialize stab / SLB management except on iSeries
+ */
+ if (cpu_has_feature(CPU_FTR_SLB))
+ slb_initialize();
+ else if (!firmware_has_feature(FW_FEATURE_ISERIES))
+ stab_initialize(get_paca()->stab_real);
+}
+
+#ifdef CONFIG_SMP
+void __init early_init_mmu_secondary(void)
+{
+ /* Initialize hash table for that CPU */
if (!firmware_has_feature(FW_FEATURE_LPAR))
mtspr(SPRN_SDR1, _SDR1);
+
+ /* Initialize STAB/SLB. We use a virtual address as it works
+ * in real mode on pSeries and we want a virutal address on
+ * iSeries anyway
+ */
+ if (cpu_has_feature(CPU_FTR_SLB))
+ slb_initialize();
+ else
+ stab_initialize(get_paca()->stab_addr);
}
+#endif /* CONFIG_SMP */
/*
* Called by asm hashtable.S for doing lazy icache flush
@@ -858,7 +891,7 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
unsigned long vsid;
struct mm_struct *mm;
pte_t *ptep;
- cpumask_t tmp;
+ const struct cpumask *tmp;
int rc, user_region = 0, local = 0;
int psize, ssize;
@@ -906,8 +939,8 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
return 1;
/* Check CPU locality */
- tmp = cpumask_of_cpu(smp_processor_id());
- if (user_region && cpus_equal(mm->cpu_vm_mask, tmp))
+ tmp = cpumask_of(smp_processor_id());
+ if (user_region && cpumask_equal(mm_cpumask(mm), tmp))
local = 1;
#ifdef CONFIG_HUGETLB_PAGE
@@ -1023,7 +1056,6 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
unsigned long vsid;
void *pgdir;
pte_t *ptep;
- cpumask_t mask;
unsigned long flags;
int local = 0;
int ssize;
@@ -1066,8 +1098,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
local_irq_save(flags);
/* Is that local to this CPU ? */
- mask = cpumask_of_cpu(smp_processor_id());
- if (cpus_equal(mm->cpu_vm_mask, mask))
+ if (cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id())))
local = 1;
/* Hash it in */
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index f00f09a77f12..f668fa9ba804 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -472,40 +472,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
{
#ifdef CONFIG_PPC_STD_MMU
unsigned long access = 0, trap;
-#endif
- unsigned long pfn = pte_pfn(pte);
-
- /* handle i-cache coherency */
- if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE) &&
- !cpu_has_feature(CPU_FTR_NOEXECUTE) &&
- pfn_valid(pfn)) {
- struct page *page = pfn_to_page(pfn);
-#ifdef CONFIG_8xx
- /* On 8xx, cache control instructions (particularly
- * "dcbst" from flush_dcache_icache) fault as write
- * operation if there is an unpopulated TLB entry
- * for the address in question. To workaround that,
- * we invalidate the TLB here, thus avoiding dcbst
- * misbehaviour.
- */
- _tlbil_va(address, 0 /* 8xx doesn't care about PID */);
-#endif
- /* The _PAGE_USER test should really be _PAGE_EXEC, but
- * older glibc versions execute some code from no-exec
- * pages, which for now we are supporting. If exec-only
- * pages are ever implemented, this will have to change.
- */
- if (!PageReserved(page) && (pte_val(pte) & _PAGE_USER)
- && !test_bit(PG_arch_1, &page->flags)) {
- if (vma->vm_mm == current->active_mm) {
- __flush_dcache_icache((void *) address);
- } else
- flush_dcache_icache_page(page);
- set_bit(PG_arch_1, &page->flags);
- }
- }
-#ifdef CONFIG_PPC_STD_MMU
/* We only want HPTEs for linux PTEs that have _PAGE_ACCESSED set */
if (!pte_young(pte) || address >= TASK_SIZE)
return;
diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap_64.c
index 86010fc7d3b1..0d957a4c70fe 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap_64.c
@@ -24,36 +24,26 @@
#include <linux/personality.h>
#include <linux/mm.h>
+#include <linux/random.h>
#include <linux/sched.h>
/*
* Top of mmap area (just below the process stack).
*
- * Leave an at least ~128 MB hole.
+ * Leave at least a ~128 MB hole on 32bit applications.
+ *
+ * On 64bit applications we randomise the stack by 1GB so we need to
+ * space our mmap start address by a further 1GB, otherwise there is a
+ * chance the mmap area will end up closer to the stack than our ulimit
+ * requires.
*/
-#define MIN_GAP (128*1024*1024)
+#define MIN_GAP32 (128*1024*1024)
+#define MIN_GAP64 ((128 + 1024)*1024*1024UL)
+#define MIN_GAP ((is_32bit_task()) ? MIN_GAP32 : MIN_GAP64)
#define MAX_GAP (TASK_SIZE/6*5)
-static inline unsigned long mmap_base(void)
-{
- unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
-
- if (gap < MIN_GAP)
- gap = MIN_GAP;
- else if (gap > MAX_GAP)
- gap = MAX_GAP;
-
- return TASK_SIZE - (gap & PAGE_MASK);
-}
-
static inline int mmap_is_legacy(void)
{
- /*
- * Force standard allocation for 64 bit programs.
- */
- if (!test_thread_flag(TIF_32BIT))
- return 1;
-
if (current->personality & ADDR_COMPAT_LAYOUT)
return 1;
@@ -64,6 +54,40 @@ static inline int mmap_is_legacy(void)
}
/*
+ * Since get_random_int() returns the same value within a 1 jiffy window,
+ * we will almost always get the same randomisation for the stack and mmap
+ * region. This will mean the relative distance between stack and mmap will
+ * be the same.
+ *
+ * To avoid this we can shift the randomness by 1 bit.
+ */
+static unsigned long mmap_rnd(void)
+{
+ unsigned long rnd = 0;
+
+ if (current->flags & PF_RANDOMIZE) {
+ /* 8MB for 32bit, 1GB for 64bit */
+ if (is_32bit_task())
+ rnd = (long)(get_random_int() % (1<<(22-PAGE_SHIFT)));
+ else
+ rnd = (long)(get_random_int() % (1<<(29-PAGE_SHIFT)));
+ }
+ return (rnd << PAGE_SHIFT) * 2;
+}
+
+static inline unsigned long mmap_base(void)
+{
+ unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
+
+ if (gap < MIN_GAP)
+ gap = MIN_GAP;
+ else if (gap > MAX_GAP)
+ gap = MAX_GAP;
+
+ return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
+}
+
+/*
* This function, called very early during the creation of a new
* process VM image, sets up which VM layout function to use:
*/
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
index 52a0cfc38b64..a70e311bd457 100644
--- a/arch/powerpc/mm/mmu_context_nohash.c
+++ b/arch/powerpc/mm/mmu_context_nohash.c
@@ -97,7 +97,7 @@ static unsigned int steal_context_smp(unsigned int id)
mm->context.id = MMU_NO_CONTEXT;
/* Mark it stale on all CPUs that used this mm */
- for_each_cpu_mask_nr(cpu, mm->cpu_vm_mask)
+ for_each_cpu(cpu, mm_cpumask(mm))
__set_bit(id, stale_map[cpu]);
return id;
}
@@ -380,7 +380,7 @@ void __init mmu_context_init(void)
#endif
printk(KERN_INFO
- "MMU: Allocated %d bytes of context maps for %d contexts\n",
+ "MMU: Allocated %zu bytes of context maps for %d contexts\n",
2 * CTX_MAP_SIZE + (sizeof(void *) * (last_context + 1)),
last_context - first_context + 1);
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 5ac08b8ab654..9047145095aa 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -158,35 +158,6 @@ static void unmap_cpu_from_node(unsigned long cpu)
}
#endif /* CONFIG_HOTPLUG_CPU */
-static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
-{
- unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
- struct device_node *cpu_node = NULL;
- const unsigned int *interrupt_server, *reg;
- int len;
-
- while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) {
- /* Try interrupt server first */
- interrupt_server = of_get_property(cpu_node,
- "ibm,ppc-interrupt-server#s", &len);
-
- len = len / sizeof(u32);
-
- if (interrupt_server && (len > 0)) {
- while (len--) {
- if (interrupt_server[len] == hw_cpuid)
- return cpu_node;
- }
- } else {
- reg = of_get_property(cpu_node, "reg", &len);
- if (reg && (len > 0) && (reg[0] == hw_cpuid))
- return cpu_node;
- }
- }
-
- return NULL;
-}
-
/* must hold reference to node during call */
static const int *of_get_associativity(struct device_node *dev)
{
@@ -290,7 +261,7 @@ static int __init find_min_common_depth(void)
ref_points = of_get_property(rtas_root,
"ibm,associativity-reference-points", &len);
- if ((len >= 1) && ref_points) {
+ if ((len >= 2 * sizeof(unsigned int)) && ref_points) {
depth = ref_points[1];
} else {
dbg("NUMA: ibm,associativity-reference-points not found.\n");
@@ -470,7 +441,7 @@ static int of_drconf_to_nid_single(struct of_drconf_cell *drmem,
static int __cpuinit numa_setup_cpu(unsigned long lcpu)
{
int nid = 0;
- struct device_node *cpu = find_cpu_node(lcpu);
+ struct device_node *cpu = of_get_cpu_node(lcpu, NULL);
if (!cpu) {
WARN_ON(1);
@@ -652,7 +623,7 @@ static int __init parse_numa_properties(void)
for_each_present_cpu(i) {
int nid;
- cpu = find_cpu_node(i);
+ cpu = of_get_cpu_node(i, NULL);
BUG_ON(!cpu);
nid = of_node_to_nid_single(cpu);
of_node_put(cpu);
@@ -1041,57 +1012,32 @@ early_param("numa", early_numa);
#ifdef CONFIG_MEMORY_HOTPLUG
/*
- * Validate the node associated with the memory section we are
- * trying to add.
- */
-int valid_hot_add_scn(int *nid, unsigned long start, u32 lmb_size,
- unsigned long scn_addr)
-{
- nodemask_t nodes;
-
- if (*nid < 0 || !node_online(*nid))
- *nid = any_online_node(NODE_MASK_ALL);
-
- if ((scn_addr >= start) && (scn_addr < (start + lmb_size))) {
- nodes_setall(nodes);
- while (NODE_DATA(*nid)->node_spanned_pages == 0) {
- node_clear(*nid, nodes);
- *nid = any_online_node(nodes);
- }
-
- return 1;
- }
-
- return 0;
-}
-
-/*
- * Find the node associated with a hot added memory section represented
- * by the ibm,dynamic-reconfiguration-memory node.
+ * Find the node associated with a hot added memory section for
+ * memory represented in the device tree by the property
+ * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory.
*/
static int hot_add_drconf_scn_to_nid(struct device_node *memory,
unsigned long scn_addr)
{
const u32 *dm;
- unsigned int n, rc;
+ unsigned int drconf_cell_cnt, rc;
unsigned long lmb_size;
- int default_nid = any_online_node(NODE_MASK_ALL);
- int nid;
struct assoc_arrays aa;
+ int nid = -1;
- n = of_get_drconf_memory(memory, &dm);
- if (!n)
- return default_nid;;
+ drconf_cell_cnt = of_get_drconf_memory(memory, &dm);
+ if (!drconf_cell_cnt)
+ return -1;
lmb_size = of_get_lmb_size(memory);
if (!lmb_size)
- return default_nid;
+ return -1;
rc = of_get_assoc_arrays(memory, &aa);
if (rc)
- return default_nid;
+ return -1;
- for (; n != 0; --n) {
+ for (; drconf_cell_cnt != 0; --drconf_cell_cnt) {
struct of_drconf_cell drmem;
read_drconf_cell(&drmem, &dm);
@@ -1102,15 +1048,57 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory,
|| !(drmem.flags & DRCONF_MEM_ASSIGNED))
continue;
+ if ((scn_addr < drmem.base_addr)
+ || (scn_addr >= (drmem.base_addr + lmb_size)))
+ continue;
+
nid = of_drconf_to_nid_single(&drmem, &aa);
+ break;
+ }
+
+ return nid;
+}
- if (valid_hot_add_scn(&nid, drmem.base_addr, lmb_size,
- scn_addr))
- return nid;
+/*
+ * Find the node associated with a hot added memory section for memory
+ * represented in the device tree as a node (i.e. memory@XXXX) for
+ * each lmb.
+ */
+int hot_add_node_scn_to_nid(unsigned long scn_addr)
+{
+ struct device_node *memory = NULL;
+ int nid = -1;
+
+ while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
+ unsigned long start, size;
+ int ranges;
+ const unsigned int *memcell_buf;
+ unsigned int len;
+
+ memcell_buf = of_get_property(memory, "reg", &len);
+ if (!memcell_buf || len <= 0)
+ continue;
+
+ /* ranges in cell */
+ ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells);
+
+ while (ranges--) {
+ start = read_n_cells(n_mem_addr_cells, &memcell_buf);
+ size = read_n_cells(n_mem_size_cells, &memcell_buf);
+
+ if ((scn_addr < start) || (scn_addr >= (start + size)))
+ continue;
+
+ nid = of_node_to_nid_single(memory);
+ break;
+ }
+
+ of_node_put(memory);
+ if (nid >= 0)
+ break;
}
- BUG(); /* section address should be found above */
- return 0;
+ return nid;
}
/*
@@ -1121,7 +1109,7 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory,
int hot_add_scn_to_nid(unsigned long scn_addr)
{
struct device_node *memory = NULL;
- int nid;
+ int nid, found = 0;
if (!numa_enabled || (min_common_depth < 0))
return any_online_node(NODE_MASK_ALL);
@@ -1130,35 +1118,25 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
if (memory) {
nid = hot_add_drconf_scn_to_nid(memory, scn_addr);
of_node_put(memory);
- return nid;
+ } else {
+ nid = hot_add_node_scn_to_nid(scn_addr);
}
- while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
- unsigned long start, size;
- int ranges;
- const unsigned int *memcell_buf;
- unsigned int len;
-
- memcell_buf = of_get_property(memory, "reg", &len);
- if (!memcell_buf || len <= 0)
- continue;
+ if (nid < 0 || !node_online(nid))
+ nid = any_online_node(NODE_MASK_ALL);
- /* ranges in cell */
- ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells);
-ha_new_range:
- start = read_n_cells(n_mem_addr_cells, &memcell_buf);
- size = read_n_cells(n_mem_size_cells, &memcell_buf);
- nid = of_node_to_nid_single(memory);
+ if (NODE_DATA(nid)->node_spanned_pages)
+ return nid;
- if (valid_hot_add_scn(&nid, start, size, scn_addr)) {
- of_node_put(memory);
- return nid;
+ for_each_online_node(nid) {
+ if (NODE_DATA(nid)->node_spanned_pages) {
+ found = 1;
+ break;
}
-
- if (--ranges) /* process all ranges in cell */
- goto ha_new_range;
}
- BUG(); /* section address should be found above */
- return 0;
+
+ BUG_ON(!found);
+ return nid;
}
+
#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 6d94116fdea1..f5c6fd42265c 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -1,5 +1,6 @@
/*
* This file contains common routines for dealing with free of page tables
+ * Along with common page table handling code
*
* Derived from arch/powerpc/mm/tlb_64.c:
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
@@ -81,11 +82,10 @@ static void pte_free_submit(struct pte_freelist_batch *batch)
void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
{
/* This is safe since tlb_gather_mmu has disabled preemption */
- cpumask_t local_cpumask = cpumask_of_cpu(smp_processor_id());
struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
if (atomic_read(&tlb->mm->mm_users) < 2 ||
- cpus_equal(tlb->mm->cpu_vm_mask, local_cpumask)) {
+ cpumask_equal(mm_cpumask(tlb->mm), cpumask_of(smp_processor_id()))){
pgtable_free(pgf);
return;
}
@@ -115,3 +115,133 @@ void pte_free_finish(void)
pte_free_submit(*batchp);
*batchp = NULL;
}
+
+/*
+ * Handle i/d cache flushing, called from set_pte_at() or ptep_set_access_flags()
+ */
+static pte_t do_dcache_icache_coherency(pte_t pte)
+{
+ unsigned long pfn = pte_pfn(pte);
+ struct page *page;
+
+ if (unlikely(!pfn_valid(pfn)))
+ return pte;
+ page = pfn_to_page(pfn);
+
+ if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) {
+ pr_debug("do_dcache_icache_coherency... flushing\n");
+ flush_dcache_icache_page(page);
+ set_bit(PG_arch_1, &page->flags);
+ }
+ else
+ pr_debug("do_dcache_icache_coherency... already clean\n");
+ return __pte(pte_val(pte) | _PAGE_HWEXEC);
+}
+
+static inline int is_exec_fault(void)
+{
+ return current->thread.regs && TRAP(current->thread.regs) == 0x400;
+}
+
+/* We only try to do i/d cache coherency on stuff that looks like
+ * reasonably "normal" PTEs. We currently require a PTE to be present
+ * and we avoid _PAGE_SPECIAL and _PAGE_NO_CACHE
+ */
+static inline int pte_looks_normal(pte_t pte)
+{
+ return (pte_val(pte) &
+ (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE)) ==
+ (_PAGE_PRESENT);
+}
+
+#if defined(CONFIG_PPC_STD_MMU)
+/* Server-style MMU handles coherency when hashing if HW exec permission
+ * is supposed per page (currently 64-bit only). Else, we always flush
+ * valid PTEs in set_pte.
+ */
+static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+{
+ return set_pte && pte_looks_normal(pte) &&
+ !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
+ cpu_has_feature(CPU_FTR_NOEXECUTE));
+}
+#elif _PAGE_HWEXEC == 0
+/* Embedded type MMU without HW exec support (8xx only so far), we flush
+ * the cache for any present PTE
+ */
+static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+{
+ return set_pte && pte_looks_normal(pte);
+}
+#else
+/* Other embedded CPUs with HW exec support per-page, we flush on exec
+ * fault if HWEXEC is not set
+ */
+static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+{
+ return pte_looks_normal(pte) && is_exec_fault() &&
+ !(pte_val(pte) & _PAGE_HWEXEC);
+}
+#endif
+
+/*
+ * set_pte stores a linux PTE into the linux page table.
+ */
+void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
+{
+#ifdef CONFIG_DEBUG_VM
+ WARN_ON(pte_present(*ptep));
+#endif
+ /* Note: mm->context.id might not yet have been assigned as
+ * this context might not have been activated yet when this
+ * is called.
+ */
+ pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
+ if (pte_need_exec_flush(pte, 1))
+ pte = do_dcache_icache_coherency(pte);
+
+ /* Perform the setting of the PTE */
+ __set_pte_at(mm, addr, ptep, pte, 0);
+}
+
+/*
+ * This is called when relaxing access to a PTE. It's also called in the page
+ * fault path when we don't hit any of the major fault cases, ie, a minor
+ * update of _PAGE_ACCESSED, _PAGE_DIRTY, etc... The generic code will have
+ * handled those two for us, we additionally deal with missing execute
+ * permission here on some processors
+ */
+int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
+ pte_t *ptep, pte_t entry, int dirty)
+{
+ int changed;
+ if (!dirty && pte_need_exec_flush(entry, 0))
+ entry = do_dcache_icache_coherency(entry);
+ changed = !pte_same(*(ptep), entry);
+ if (changed) {
+ assert_pte_locked(vma->vm_mm, address);
+ __ptep_set_access_flags(ptep, entry);
+ flush_tlb_page_nohash(vma, address);
+ }
+ return changed;
+}
+
+#ifdef CONFIG_DEBUG_VM
+void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+
+ if (mm == &init_mm)
+ return;
+ pgd = mm->pgd + pgd_index(addr);
+ BUG_ON(pgd_none(*pgd));
+ pud = pud_offset(pgd, addr);
+ BUG_ON(pud_none(*pud));
+ pmd = pmd_offset(pud, addr);
+ BUG_ON(!pmd_present(*pmd));
+ BUG_ON(!spin_is_locked(pte_lockptr(mm, pmd)));
+}
+#endif /* CONFIG_DEBUG_VM */
+
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 58bcaeba728d..430d0908fa50 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -129,7 +129,8 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
void __iomem *
ioremap(phys_addr_t addr, unsigned long size)
{
- return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
+ return __ioremap_caller(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED,
+ __builtin_return_address(0));
}
EXPORT_SYMBOL(ioremap);
@@ -143,20 +144,27 @@ ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags)
/* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
flags &= ~(_PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC);
- return __ioremap(addr, size, flags);
+ return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
}
EXPORT_SYMBOL(ioremap_flags);
void __iomem *
__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
{
+ return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
+}
+
+void __iomem *
+__ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags,
+ void *caller)
+{
unsigned long v, i;
phys_addr_t p;
int err;
/* Make sure we have the base flags */
if ((flags & _PAGE_PRESENT) == 0)
- flags |= _PAGE_KERNEL;
+ flags |= PAGE_KERNEL;
/* Non-cacheable page cannot be coherent */
if (flags & _PAGE_NO_CACHE)
@@ -212,7 +220,7 @@ __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
if (mem_init_done) {
struct vm_struct *area;
- area = get_vm_area(size, VM_IOREMAP);
+ area = get_vm_area_caller(size, VM_IOREMAP, caller);
if (area == 0)
return NULL;
v = (unsigned long) area->addr;
@@ -288,7 +296,7 @@ void __init mapin_ram(void)
p = memstart_addr + s;
for (; s < total_lowmem; s += PAGE_SIZE) {
ktext = ((char *) v >= _stext && (char *) v < etext);
- f = ktext ?_PAGE_RAM_TEXT : _PAGE_RAM;
+ f = ktext ? PAGE_KERNEL_TEXT : PAGE_KERNEL;
map_page(v, p, f);
#ifdef CONFIG_PPC_STD_MMU_32
if (ktext)
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 365e61ae5dbc..bfa7db6b2fd5 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -144,8 +144,8 @@ void __iounmap_at(void *ea, unsigned long size)
unmap_kernel_range((unsigned long)ea, size);
}
-void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
- unsigned long flags)
+void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size,
+ unsigned long flags, void *caller)
{
phys_addr_t paligned;
void __iomem *ret;
@@ -168,8 +168,9 @@ void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
if (mem_init_done) {
struct vm_struct *area;
- area = __get_vm_area(size, VM_IOREMAP,
- ioremap_bot, IOREMAP_END);
+ area = __get_vm_area_caller(size, VM_IOREMAP,
+ ioremap_bot, IOREMAP_END,
+ caller);
if (area == NULL)
return NULL;
ret = __ioremap_at(paligned, area->addr, size, flags);
@@ -186,19 +187,27 @@ void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
return ret;
}
+void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
+ unsigned long flags)
+{
+ return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
+}
void __iomem * ioremap(phys_addr_t addr, unsigned long size)
{
unsigned long flags = _PAGE_NO_CACHE | _PAGE_GUARDED;
+ void *caller = __builtin_return_address(0);
if (ppc_md.ioremap)
- return ppc_md.ioremap(addr, size, flags);
- return __ioremap(addr, size, flags);
+ return ppc_md.ioremap(addr, size, flags, caller);
+ return __ioremap_caller(addr, size, flags, caller);
}
void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size,
unsigned long flags)
{
+ void *caller = __builtin_return_address(0);
+
/* writeable implies dirty for kernel addresses */
if (flags & _PAGE_RW)
flags |= _PAGE_DIRTY;
@@ -207,8 +216,8 @@ void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size,
flags &= ~(_PAGE_USER | _PAGE_EXEC);
if (ppc_md.ioremap)
- return ppc_md.ioremap(addr, size, flags);
- return __ioremap(addr, size, flags);
+ return ppc_md.ioremap(addr, size, flags, caller);
+ return __ioremap_caller(addr, size, flags, caller);
}
diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c
index fe65c405412c..2d2a87e10154 100644
--- a/arch/powerpc/mm/ppc_mmu_32.c
+++ b/arch/powerpc/mm/ppc_mmu_32.c
@@ -74,9 +74,6 @@ unsigned long p_mapped_by_bats(phys_addr_t pa)
unsigned long __init mmu_mapin_ram(void)
{
-#ifdef CONFIG_POWER4
- return 0;
-#else
unsigned long tot, bl, done;
unsigned long max_size = (256<<20);
@@ -95,7 +92,7 @@ unsigned long __init mmu_mapin_ram(void)
break;
}
- setbat(2, PAGE_OFFSET, 0, bl, _PAGE_RAM);
+ setbat(2, PAGE_OFFSET, 0, bl, PAGE_KERNEL_X);
done = (unsigned long)bat_addrs[2].limit - PAGE_OFFSET + 1;
if ((done < tot) && !bat_addrs[3].limit) {
/* use BAT3 to cover a bit more */
@@ -103,12 +100,11 @@ unsigned long __init mmu_mapin_ram(void)
for (bl = 128<<10; bl < max_size; bl <<= 1)
if (bl * 2 > tot)
break;
- setbat(3, PAGE_OFFSET+done, done, bl, _PAGE_RAM);
+ setbat(3, PAGE_OFFSET+done, done, bl, PAGE_KERNEL_X);
done = (unsigned long)bat_addrs[3].limit - PAGE_OFFSET + 1;
}
return done;
-#endif
}
/*
@@ -136,9 +132,7 @@ void __init setbat(int index, unsigned long virt, phys_addr_t phys,
wimgxpp |= (flags & _PAGE_RW)? BPP_RW: BPP_RX;
bat[1].batu = virt | (bl << 2) | 2; /* Vs=1, Vp=0 */
bat[1].batl = BAT_PHYS_ADDR(phys) | wimgxpp;
-#ifndef CONFIG_KGDB /* want user access for breakpoints */
if (flags & _PAGE_USER)
-#endif
bat[1].batu |= 1; /* Vp = 1 */
if (flags & _PAGE_GUARDED) {
/* G bit must be zero in IBATs */
diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c
index c931bc7d1079..1be1b5e59796 100644
--- a/arch/powerpc/mm/tlb_hash64.c
+++ b/arch/powerpc/mm/tlb_hash64.c
@@ -139,12 +139,12 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
*/
void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
{
- cpumask_t tmp;
+ const struct cpumask *tmp;
int i, local = 0;
i = batch->index;
- tmp = cpumask_of_cpu(smp_processor_id());
- if (cpus_equal(batch->mm->cpu_vm_mask, tmp))
+ tmp = cpumask_of(smp_processor_id());
+ if (cpumask_equal(mm_cpumask(batch->mm), tmp))
local = 1;
if (i == 1)
flush_hash_page(batch->vaddr[0], batch->pte[0],
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index 39ac22b13c73..7af72970faed 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -132,11 +132,11 @@ void flush_tlb_mm(struct mm_struct *mm)
pid = mm->context.id;
if (unlikely(pid == MMU_NO_CONTEXT))
goto no_context;
- cpu_mask = mm->cpu_vm_mask;
- cpu_clear(smp_processor_id(), cpu_mask);
- if (!cpus_empty(cpu_mask)) {
+ if (!cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) {
struct tlb_flush_param p = { .pid = pid };
- smp_call_function_mask(cpu_mask, do_flush_tlb_mm_ipi, &p, 1);
+ /* Ignores smp_processor_id() even if set. */
+ smp_call_function_many(mm_cpumask(mm),
+ do_flush_tlb_mm_ipi, &p, 1);
}
_tlbil_pid(pid);
no_context:
@@ -146,16 +146,15 @@ EXPORT_SYMBOL(flush_tlb_mm);
void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
{
- cpumask_t cpu_mask;
+ struct cpumask *cpu_mask;
unsigned int pid;
preempt_disable();
pid = vma ? vma->vm_mm->context.id : 0;
if (unlikely(pid == MMU_NO_CONTEXT))
goto bail;
- cpu_mask = vma->vm_mm->cpu_vm_mask;
- cpu_clear(smp_processor_id(), cpu_mask);
- if (!cpus_empty(cpu_mask)) {
+ cpu_mask = mm_cpumask(vma->vm_mm);
+ if (!cpumask_equal(cpu_mask, cpumask_of(smp_processor_id()))) {
/* If broadcast tlbivax is supported, use it */
if (mmu_has_feature(MMU_FTR_USE_TLBIVAX_BCAST)) {
int lock = mmu_has_feature(MMU_FTR_LOCK_BCAST_INVAL);
@@ -167,7 +166,8 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
goto bail;
} else {
struct tlb_flush_param p = { .pid = pid, .addr = vmaddr };
- smp_call_function_mask(cpu_mask,
+ /* Ignores smp_processor_id() even if set in cpu_mask */
+ smp_call_function_many(cpu_mask,
do_flush_tlb_page_ipi, &p, 1);
}
}
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S
index f900a39e6ec4..788b87c36f77 100644
--- a/arch/powerpc/mm/tlb_nohash_low.S
+++ b/arch/powerpc/mm/tlb_nohash_low.S
@@ -118,25 +118,50 @@ _GLOBAL(_tlbil_pid)
#elif defined(CONFIG_FSL_BOOKE)
/*
- * FSL BookE implementations. Currently _pid and _all are the
- * same. This will change when tlbilx is actually supported and
- * performs invalidate-by-PID. This change will be driven by
- * mmu_features conditional
+ * FSL BookE implementations.
+ *
+ * Since feature sections are using _SECTION_ELSE we need
+ * to have the larger code path before the _SECTION_ELSE
*/
+#define MMUCSR0_TLBFI (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \
+ MMUCSR0_TLB2FI | MMUCSR0_TLB3FI)
/*
* Flush MMU TLB on the local processor
*/
-_GLOBAL(_tlbil_pid)
_GLOBAL(_tlbil_all)
-#define MMUCSR0_TLBFI (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \
- MMUCSR0_TLB2FI | MMUCSR0_TLB3FI)
+BEGIN_MMU_FTR_SECTION
+ li r3,(MMUCSR0_TLBFI)@l
+ mtspr SPRN_MMUCSR0, r3
+1:
+ mfspr r3,SPRN_MMUCSR0
+ andi. r3,r3,MMUCSR0_TLBFI@l
+ bne 1b
+MMU_FTR_SECTION_ELSE
+ PPC_TLBILX_ALL(0,0)
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
+ msync
+ isync
+ blr
+
+_GLOBAL(_tlbil_pid)
+BEGIN_MMU_FTR_SECTION
+ slwi r3,r3,16
+ mfmsr r10
+ wrteei 0
+ mfspr r4,SPRN_MAS6 /* save MAS6 */
+ mtspr SPRN_MAS6,r3
+ PPC_TLBILX_PID(0,0)
+ mtspr SPRN_MAS6,r4 /* restore MAS6 */
+ wrtee r10
+MMU_FTR_SECTION_ELSE
li r3,(MMUCSR0_TLBFI)@l
mtspr SPRN_MMUCSR0, r3
1:
mfspr r3,SPRN_MMUCSR0
andi. r3,r3,MMUCSR0_TLBFI@l
bne 1b
+ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBILX)
msync
isync
blr
@@ -149,7 +174,9 @@ _GLOBAL(_tlbil_va)
mfmsr r10
wrteei 0
slwi r4,r4,16
+ ori r4,r4,(MAS6_ISIZE(BOOK3E_PAGESZ_4K))@l
mtspr SPRN_MAS6,r4 /* assume AS=0 for now */
+BEGIN_MMU_FTR_SECTION
tlbsx 0,r3
mfspr r4,SPRN_MAS1 /* check valid */
andis. r3,r4,MAS1_VALID@h
@@ -157,6 +184,9 @@ _GLOBAL(_tlbil_va)
rlwinm r4,r4,0,1,31
mtspr SPRN_MAS1,r4
tlbwe
+MMU_FTR_SECTION_ELSE
+ PPC_TLBILX_VA(0,r3)
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
msync
isync
1: wrtee r10
diff --git a/arch/powerpc/oprofile/op_model_7450.c b/arch/powerpc/oprofile/op_model_7450.c
index cc599eb8768b..f8d36f940e88 100644
--- a/arch/powerpc/oprofile/op_model_7450.c
+++ b/arch/powerpc/oprofile/op_model_7450.c
@@ -29,7 +29,7 @@
static unsigned long reset_value[OP_MAX_COUNTER];
static int oprofile_running;
-static u32 mmcr0_val, mmcr1_val, mmcr2_val;
+static u32 mmcr0_val, mmcr1_val, mmcr2_val, num_pmcs;
#define MMCR0_PMC1_SHIFT 6
#define MMCR0_PMC2_SHIFT 0
@@ -88,13 +88,12 @@ static int fsl7450_cpu_setup(struct op_counter_config *ctr)
mtspr(SPRN_MMCR0, mmcr0_val);
mtspr(SPRN_MMCR1, mmcr1_val);
- mtspr(SPRN_MMCR2, mmcr2_val);
+ if (num_pmcs > 4)
+ mtspr(SPRN_MMCR2, mmcr2_val);
return 0;
}
-#define NUM_CTRS 6
-
/* Configures the global settings for the countes on all CPUs. */
static int fsl7450_reg_setup(struct op_counter_config *ctr,
struct op_system_config *sys,
@@ -102,12 +101,13 @@ static int fsl7450_reg_setup(struct op_counter_config *ctr,
{
int i;
+ num_pmcs = num_ctrs;
/* Our counters count up, and "count" refers to
* how much before the next interrupt, and we interrupt
* on overflow. So we calculate the starting value
* which will give us "count" until overflow.
* Then we set the events on the enabled counters */
- for (i = 0; i < NUM_CTRS; ++i)
+ for (i = 0; i < num_ctrs; ++i)
reset_value[i] = 0x80000000UL - ctr[i].count;
/* Set events for Counters 1 & 2 */
@@ -123,9 +123,10 @@ static int fsl7450_reg_setup(struct op_counter_config *ctr,
/* Set events for Counters 3-6 */
mmcr1_val = mmcr1_event3(ctr[2].event)
- | mmcr1_event4(ctr[3].event)
- | mmcr1_event5(ctr[4].event)
- | mmcr1_event6(ctr[5].event);
+ | mmcr1_event4(ctr[3].event);
+ if (num_ctrs > 4)
+ mmcr1_val |= mmcr1_event5(ctr[4].event)
+ | mmcr1_event6(ctr[5].event);
mmcr2_val = 0;
@@ -139,7 +140,7 @@ static int fsl7450_start(struct op_counter_config *ctr)
mtmsr(mfmsr() | MSR_PMM);
- for (i = 0; i < NUM_CTRS; ++i) {
+ for (i = 0; i < num_pmcs; ++i) {
if (ctr[i].enabled)
classic_ctr_write(i, reset_value[i]);
else
@@ -184,7 +185,7 @@ static void fsl7450_handle_interrupt(struct pt_regs *regs,
pc = mfspr(SPRN_SIAR);
is_kernel = is_kernel_addr(pc);
- for (i = 0; i < NUM_CTRS; ++i) {
+ for (i = 0; i < num_pmcs; ++i) {
val = classic_ctr_read(i);
if (val < 0) {
if (oprofile_running && ctr[i].enabled) {
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 3496bc05058e..bf5c7ff2e6e5 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -118,6 +118,17 @@ config GLACIER
help
This option enables support for the AMCC PPC460GT evaluation board.
+config REDWOOD
+ bool "Redwood"
+ depends on 44x
+ default n
+ select PPC44x_SIMPLE
+ select 460SX
+ select PCI
+ select PPC4xx_PCI_EXPRESS
+ help
+ This option enables support for the AMCC PPC460SX Redwood board.
+
config YOSEMITE
bool "Yosemite"
depends on 44x
@@ -220,6 +231,14 @@ config 460EX
select IBM_NEW_EMAC_EMAC4
select IBM_NEW_EMAC_TAH
+config 460SX
+ bool
+ select PPC_FPU
+ select IBM_NEW_EMAC_EMAC4
+ select IBM_NEW_EMAC_RGMII
+ select IBM_NEW_EMAC_ZMII
+ select IBM_NEW_EMAC_TAH
+
# 44x errata/workaround config symbols, selected by the CPU models above
config IBM440EP_ERR42
bool
diff --git a/arch/powerpc/platforms/44x/ppc44x_simple.c b/arch/powerpc/platforms/44x/ppc44x_simple.c
index 76fdc51dac8b..5bcd441885e8 100644
--- a/arch/powerpc/platforms/44x/ppc44x_simple.c
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
@@ -57,6 +57,7 @@ static char *board[] __initdata = {
"ibm,ebony",
"amcc,katmai",
"amcc,rainier",
+ "amcc,redwood",
"amcc,sequoia",
"amcc,taishan",
"amcc,yosemite"
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
index 326852c78b8f..4dac9b0525a4 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -12,7 +12,7 @@ config PPC_MPC5121
config MPC5121_ADS
bool "Freescale MPC5121E ADS"
- depends on PPC_MULTIPLATFORM && PPC32
+ depends on 6xx
select DEFAULT_UIMAGE
select PPC_MPC5121
select MPC5121_ADS_CPLD
@@ -21,7 +21,7 @@ config MPC5121_ADS
config MPC5121_GENERIC
bool "Generic support for simple MPC5121 based boards"
- depends on PPC_MULTIPLATFORM && PPC32
+ depends on 6xx
select DEFAULT_UIMAGE
select PPC_MPC5121
help
diff --git a/arch/powerpc/platforms/52xx/Kconfig b/arch/powerpc/platforms/52xx/Kconfig
index 696a5ee4962d..8b8e9560a315 100644
--- a/arch/powerpc/platforms/52xx/Kconfig
+++ b/arch/powerpc/platforms/52xx/Kconfig
@@ -1,6 +1,6 @@
config PPC_MPC52xx
bool "52xx-based boards"
- depends on PPC_MULTIPLATFORM && PPC32
+ depends on 6xx
select PPC_CLOCK
select PPC_PCI_CHOICE
@@ -21,7 +21,13 @@ config PPC_MPC5200_SIMPLE
and if there is a PCI bus node defined in the device tree.
Boards that are compatible with this generic platform support
- are: 'tqc,tqm5200', 'promess,motionpro', 'schindler,cm5200'.
+ are:
+ intercontrol,digsy-mtc
+ phytec,pcm030
+ phytec,pcm032
+ promess,motionpro
+ schindler,cm5200
+ tqc,tqm5200
config PPC_EFIKA
bool "bPlan Efika 5k2. MPC5200B based computer"
@@ -35,6 +41,11 @@ config PPC_LITE5200
depends on PPC_MPC52xx
select DEFAULT_UIMAGE
+config PPC_MEDIA5200
+ bool "Freescale Media5200 Eval Board"
+ depends on PPC_MPC52xx
+ select DEFAULT_UIMAGE
+
config PPC_MPC5200_BUGFIX
bool "MPC5200 (L25R) bugfix support"
depends on PPC_MPC52xx
diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile
index b8a52062738a..bfd4f52cf3dd 100644
--- a/arch/powerpc/platforms/52xx/Makefile
+++ b/arch/powerpc/platforms/52xx/Makefile
@@ -1,12 +1,13 @@
#
# Makefile for 52xx based boards
#
-obj-y += mpc52xx_pic.o mpc52xx_common.o
+obj-y += mpc52xx_pic.o mpc52xx_common.o mpc52xx_gpt.o
obj-$(CONFIG_PCI) += mpc52xx_pci.o
obj-$(CONFIG_PPC_MPC5200_SIMPLE) += mpc5200_simple.o
obj-$(CONFIG_PPC_EFIKA) += efika.o
obj-$(CONFIG_PPC_LITE5200) += lite5200.o
+obj-$(CONFIG_PPC_MEDIA5200) += media5200.o
obj-$(CONFIG_PM) += mpc52xx_sleep.o mpc52xx_pm.o
ifeq ($(CONFIG_PPC_LITE5200),y)
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
new file mode 100644
index 000000000000..68e4f1696d14
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -0,0 +1,273 @@
+/*
+ * Support for 'media5200-platform' compatible boards.
+ *
+ * Copyright (C) 2008 Secret Lab Technologies Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Description:
+ * This code implements support for the Freescape Media5200 platform
+ * (built around the MPC5200 SoC).
+ *
+ * Notable characteristic of the Media5200 is the presence of an FPGA
+ * that has all external IRQ lines routed through it. This file implements
+ * a cascaded interrupt controller driver which attaches itself to the
+ * Virtual IRQ subsystem after the primary mpc5200 interrupt controller
+ * is initialized.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <asm/time.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/mpc52xx.h>
+
+static struct of_device_id mpc5200_gpio_ids[] __initdata = {
+ { .compatible = "fsl,mpc5200-gpio", },
+ { .compatible = "mpc5200-gpio", },
+ {}
+};
+
+/* FPGA register set */
+#define MEDIA5200_IRQ_ENABLE (0x40c)
+#define MEDIA5200_IRQ_STATUS (0x410)
+#define MEDIA5200_NUM_IRQS (6)
+#define MEDIA5200_IRQ_SHIFT (32 - MEDIA5200_NUM_IRQS)
+
+struct media5200_irq {
+ void __iomem *regs;
+ spinlock_t lock;
+ struct irq_host *irqhost;
+};
+struct media5200_irq media5200_irq;
+
+static void media5200_irq_unmask(unsigned int virq)
+{
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&media5200_irq.lock, flags);
+ val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
+ val |= 1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq);
+ out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
+ spin_unlock_irqrestore(&media5200_irq.lock, flags);
+}
+
+static void media5200_irq_mask(unsigned int virq)
+{
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&media5200_irq.lock, flags);
+ val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
+ val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irq_map[virq].hwirq));
+ out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
+ spin_unlock_irqrestore(&media5200_irq.lock, flags);
+}
+
+static struct irq_chip media5200_irq_chip = {
+ .typename = "Media5200 FPGA",
+ .unmask = media5200_irq_unmask,
+ .mask = media5200_irq_mask,
+ .mask_ack = media5200_irq_mask,
+};
+
+void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
+{
+ int sub_virq, val;
+ u32 status, enable;
+
+ /* Mask off the cascaded IRQ */
+ spin_lock(&desc->lock);
+ desc->chip->mask(virq);
+ spin_unlock(&desc->lock);
+
+ /* Ask the FPGA for IRQ status. If 'val' is 0, then no irqs
+ * are pending. 'ffs()' is 1 based */
+ status = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
+ enable = in_be32(media5200_irq.regs + MEDIA5200_IRQ_STATUS);
+ val = ffs((status & enable) >> MEDIA5200_IRQ_SHIFT);
+ if (val) {
+ sub_virq = irq_linear_revmap(media5200_irq.irqhost, val - 1);
+ /* pr_debug("%s: virq=%i s=%.8x e=%.8x hwirq=%i subvirq=%i\n",
+ * __func__, virq, status, enable, val - 1, sub_virq);
+ */
+ generic_handle_irq(sub_virq);
+ }
+
+ /* Processing done; can reenable the cascade now */
+ spin_lock(&desc->lock);
+ desc->chip->ack(virq);
+ if (!(desc->status & IRQ_DISABLED))
+ desc->chip->unmask(virq);
+ spin_unlock(&desc->lock);
+}
+
+static int media5200_irq_map(struct irq_host *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ struct irq_desc *desc = get_irq_desc(virq);
+
+ pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw);
+ set_irq_chip_data(virq, &media5200_irq);
+ set_irq_chip_and_handler(virq, &media5200_irq_chip, handle_level_irq);
+ set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
+ desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
+ desc->status |= IRQ_TYPE_LEVEL_LOW | IRQ_LEVEL;
+
+ return 0;
+}
+
+static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct,
+ u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq,
+ unsigned int *out_flags)
+{
+ if (intsize != 2)
+ return -1;
+
+ pr_debug("%s: bank=%i, number=%i\n", __func__, intspec[0], intspec[1]);
+ *out_hwirq = intspec[1];
+ *out_flags = IRQ_TYPE_NONE;
+ return 0;
+}
+
+static struct irq_host_ops media5200_irq_ops = {
+ .map = media5200_irq_map,
+ .xlate = media5200_irq_xlate,
+};
+
+/*
+ * Setup Media5200 IRQ mapping
+ */
+static void __init media5200_init_irq(void)
+{
+ struct device_node *fpga_np;
+ int cascade_virq;
+
+ /* First setup the regular MPC5200 interrupt controller */
+ mpc52xx_init_irq();
+
+ /* Now find the FPGA IRQ */
+ fpga_np = of_find_compatible_node(NULL, NULL, "fsl,media5200-fpga");
+ if (!fpga_np)
+ goto out;
+ pr_debug("%s: found fpga node: %s\n", __func__, fpga_np->full_name);
+
+ media5200_irq.regs = of_iomap(fpga_np, 0);
+ if (!media5200_irq.regs)
+ goto out;
+ pr_debug("%s: mapped to %p\n", __func__, media5200_irq.regs);
+
+ cascade_virq = irq_of_parse_and_map(fpga_np, 0);
+ if (!cascade_virq)
+ goto out;
+ pr_debug("%s: cascaded on virq=%i\n", __func__, cascade_virq);
+
+ /* Disable all FPGA IRQs */
+ out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, 0);
+
+ spin_lock_init(&media5200_irq.lock);
+
+ media5200_irq.irqhost = irq_alloc_host(fpga_np, IRQ_HOST_MAP_LINEAR,
+ MEDIA5200_NUM_IRQS,
+ &media5200_irq_ops, -1);
+ if (!media5200_irq.irqhost)
+ goto out;
+ pr_debug("%s: allocated irqhost\n", __func__);
+
+ media5200_irq.irqhost->host_data = &media5200_irq;
+
+ set_irq_data(cascade_virq, &media5200_irq);
+ set_irq_chained_handler(cascade_virq, media5200_irq_cascade);
+
+ return;
+
+ out:
+ pr_err("Could not find Media5200 FPGA; PCI interrupts will not work\n");
+}
+
+/*
+ * Setup the architecture
+ */
+static void __init media5200_setup_arch(void)
+{
+
+ struct device_node *np;
+ struct mpc52xx_gpio __iomem *gpio;
+ u32 port_config;
+
+ if (ppc_md.progress)
+ ppc_md.progress("media5200_setup_arch()", 0);
+
+ /* Map important registers from the internal memory map */
+ mpc52xx_map_common_devices();
+
+ /* Some mpc5200 & mpc5200b related configuration */
+ mpc5200_setup_xlb_arbiter();
+
+ mpc52xx_setup_pci();
+
+ np = of_find_matching_node(NULL, mpc5200_gpio_ids);
+ gpio = of_iomap(np, 0);
+ of_node_put(np);
+ if (!gpio) {
+ printk(KERN_ERR "%s() failed. expect abnormal behavior\n",
+ __func__);
+ return;
+ }
+
+ /* Set port config */
+ port_config = in_be32(&gpio->port_config);
+
+ port_config &= ~0x03000000; /* ATA CS is on csb_4/5 */
+ port_config |= 0x01000000;
+
+ out_be32(&gpio->port_config, port_config);
+
+ /* Unmap zone */
+ iounmap(gpio);
+
+}
+
+/* list of the supported boards */
+static char *board[] __initdata = {
+ "fsl,media5200",
+ NULL
+};
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init media5200_probe(void)
+{
+ unsigned long node = of_get_flat_dt_root();
+ int i = 0;
+
+ while (board[i]) {
+ if (of_flat_dt_is_compatible(node, board[i]))
+ break;
+ i++;
+ }
+
+ return (board[i] != NULL);
+}
+
+define_machine(media5200_platform) {
+ .name = "media5200-platform",
+ .probe = media5200_probe,
+ .setup_arch = media5200_setup_arch,
+ .init = mpc52xx_declare_of_platform_devices,
+ .init_IRQ = media5200_init_irq,
+ .get_irq = mpc52xx_get_irq,
+ .restart = mpc52xx_restart,
+ .calibrate_decr = generic_calibrate_decr,
+};
diff --git a/arch/powerpc/platforms/52xx/mpc5200_simple.c b/arch/powerpc/platforms/52xx/mpc5200_simple.c
index a3bda0b9f1ff..c31e5b534f0a 100644
--- a/arch/powerpc/platforms/52xx/mpc5200_simple.c
+++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c
@@ -50,8 +50,10 @@ static void __init mpc5200_simple_setup_arch(void)
/* list of the supported boards */
static char *board[] __initdata = {
- "promess,motionpro",
+ "intercontrol,digsy-mtc",
"phytec,pcm030",
+ "phytec,pcm032",
+ "promess,motionpro",
"schindler,cm5200",
"tqc,tqm5200",
NULL
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 98367a0255f3..8e3dd5a0f228 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -28,9 +28,10 @@ static struct of_device_id mpc52xx_xlb_ids[] __initdata = {
static struct of_device_id mpc52xx_bus_ids[] __initdata = {
{ .compatible = "fsl,mpc5200-immr", },
{ .compatible = "fsl,mpc5200b-immr", },
- { .compatible = "fsl,lpb", },
+ { .compatible = "simple-bus", },
/* depreciated matches; shouldn't be used in new device trees */
+ { .compatible = "fsl,lpb", },
{ .type = "builtin", .compatible = "mpc5200", }, /* efika */
{ .type = "soc", .compatible = "mpc5200", }, /* lite5200 */
{}
@@ -205,6 +206,43 @@ int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
EXPORT_SYMBOL(mpc52xx_set_psc_clkdiv);
/**
+ * mpc52xx_get_xtal_freq - Get SYS_XTAL_IN frequency for a device
+ *
+ * @node: device node
+ *
+ * Returns the frequency of the external oscillator clock connected
+ * to the SYS_XTAL_IN pin, or 0 if it cannot be determined.
+ */
+unsigned int mpc52xx_get_xtal_freq(struct device_node *node)
+{
+ u32 val;
+ unsigned int freq;
+
+ if (!mpc52xx_cdm)
+ return 0;
+
+ freq = mpc52xx_find_ipb_freq(node);
+ if (!freq)
+ return 0;
+
+ if (in_8(&mpc52xx_cdm->ipb_clk_sel) & 0x1)
+ freq *= 2;
+
+ val = in_be32(&mpc52xx_cdm->rstcfg);
+ if (val & (1 << 5))
+ freq *= 8;
+ else
+ freq *= 4;
+ if (val & (1 << 6))
+ freq /= 12;
+ else
+ freq /= 16;
+
+ return freq;
+}
+EXPORT_SYMBOL(mpc52xx_get_xtal_freq);
+
+/**
* mpc52xx_restart: ppc_md->restart hook for mpc5200 using the watchdog timer
*/
void
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
index 07f89ae46d04..2b8d8ef32e4e 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
@@ -354,88 +354,6 @@ static struct of_platform_driver mpc52xx_simple_gpiochip_driver = {
.remove = mpc52xx_gpiochip_remove,
};
-/*
- * GPIO LIB API implementation for gpt GPIOs.
- *
- * Each gpt only has a single GPIO.
- */
-static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
-
- return (in_be32(&regs->status) & (1 << (31 - 23))) ? 1 : 0;
-}
-
-static void
-mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
-
- if (val)
- out_be32(&regs->mode, 0x34);
- else
- out_be32(&regs->mode, 0x24);
-
- pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
-}
-
-static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
-{
- struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
- struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
-
- out_be32(&regs->mode, 0x04);
-
- return 0;
-}
-
-static int
-mpc52xx_gpt_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
-{
- mpc52xx_gpt_gpio_set(gc, gpio, val);
- pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
-
- return 0;
-}
-
-static int __devinit mpc52xx_gpt_gpiochip_probe(struct of_device *ofdev,
- const struct of_device_id *match)
-{
- struct of_mm_gpio_chip *mmchip;
- struct of_gpio_chip *chip;
-
- mmchip = kzalloc(sizeof(*mmchip), GFP_KERNEL);
- if (!mmchip)
- return -ENOMEM;
-
- chip = &mmchip->of_gc;
-
- chip->gpio_cells = 2;
- chip->gc.ngpio = 1;
- chip->gc.direction_input = mpc52xx_gpt_gpio_dir_in;
- chip->gc.direction_output = mpc52xx_gpt_gpio_dir_out;
- chip->gc.get = mpc52xx_gpt_gpio_get;
- chip->gc.set = mpc52xx_gpt_gpio_set;
-
- return of_mm_gpiochip_add(ofdev->node, mmchip);
-}
-
-static const struct of_device_id mpc52xx_gpt_gpiochip_match[] = {
- {
- .compatible = "fsl,mpc5200-gpt-gpio",
- },
- {}
-};
-
-static struct of_platform_driver mpc52xx_gpt_gpiochip_driver = {
- .name = "gpio_gpt",
- .match_table = mpc52xx_gpt_gpiochip_match,
- .probe = mpc52xx_gpt_gpiochip_probe,
- .remove = mpc52xx_gpiochip_remove,
-};
-
static int __init mpc52xx_gpio_init(void)
{
if (of_register_platform_driver(&mpc52xx_wkup_gpiochip_driver))
@@ -444,9 +362,6 @@ static int __init mpc52xx_gpio_init(void)
if (of_register_platform_driver(&mpc52xx_simple_gpiochip_driver))
printk(KERN_ERR "Unable to register simple GPIO driver\n");
- if (of_register_platform_driver(&mpc52xx_gpt_gpiochip_driver))
- printk(KERN_ERR "Unable to register gpt GPIO driver\n");
-
return 0;
}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
new file mode 100644
index 000000000000..bfbcd418e690
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -0,0 +1,396 @@
+/*
+ * MPC5200 General Purpose Timer device driver
+ *
+ * Copyright (c) 2009 Secret Lab Technologies Ltd.
+ * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This file is a driver for the the General Purpose Timer (gpt) devices
+ * found on the MPC5200 SoC. Each timer has an IO pin which can be used
+ * for GPIO or can be used to raise interrupts. The timer function can
+ * be used independently from the IO pin, or it can be used to control
+ * output signals or measure input signals.
+ *
+ * This driver supports the GPIO and IRQ controller functions of the GPT
+ * device. Timer functions are not yet supported, nor is the watchdog
+ * timer.
+ *
+ * To use the GPIO function, the following two properties must be added
+ * to the device tree node for the gpt device (typically in the .dts file
+ * for the board):
+ * gpio-controller;
+ * #gpio-cells = < 2 >;
+ * This driver will register the GPIO pin if it finds the gpio-controller
+ * property in the device tree.
+ *
+ * To use the IRQ controller function, the following two properties must
+ * be added to the device tree node for the gpt device:
+ * interrupt-controller;
+ * #interrupt-cells = < 1 >;
+ * The IRQ controller binding only uses one cell to specify the interrupt,
+ * and the IRQ flags are encoded in the cell. A cell is not used to encode
+ * the IRQ number because the GPT only has a single IRQ source. For flags,
+ * a value of '1' means rising edge sensitive and '2' means falling edge.
+ *
+ * The GPIO and the IRQ controller functions can be used at the same time,
+ * but in this use case the IO line will only work as an input. Trying to
+ * use it as a GPIO output will not work.
+ *
+ * When using the GPIO line as an output, it can either be driven as normal
+ * IO, or it can be an Open Collector (OC) output. At the moment it is the
+ * responsibility of either the bootloader or the platform setup code to set
+ * the output mode. This driver does not change the output mode setting.
+ */
+
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+#include <linux/kernel.h>
+#include <asm/mpc52xx.h>
+
+MODULE_DESCRIPTION("Freescale MPC52xx gpt driver");
+MODULE_AUTHOR("Sascha Hauer, Grant Likely");
+MODULE_LICENSE("GPL");
+
+/**
+ * struct mpc52xx_gpt - Private data structure for MPC52xx GPT driver
+ * @dev: pointer to device structure
+ * @regs: virtual address of GPT registers
+ * @lock: spinlock to coordinate between different functions.
+ * @of_gc: of_gpio_chip instance structure; used when GPIO is enabled
+ * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported
+ */
+struct mpc52xx_gpt_priv {
+ struct device *dev;
+ struct mpc52xx_gpt __iomem *regs;
+ spinlock_t lock;
+ struct irq_host *irqhost;
+
+#if defined(CONFIG_GPIOLIB)
+ struct of_gpio_chip of_gc;
+#endif
+};
+
+#define MPC52xx_GPT_MODE_MS_MASK (0x07)
+#define MPC52xx_GPT_MODE_MS_IC (0x01)
+#define MPC52xx_GPT_MODE_MS_OC (0x02)
+#define MPC52xx_GPT_MODE_MS_PWM (0x03)
+#define MPC52xx_GPT_MODE_MS_GPIO (0x04)
+
+#define MPC52xx_GPT_MODE_GPIO_MASK (0x30)
+#define MPC52xx_GPT_MODE_GPIO_OUT_LOW (0x20)
+#define MPC52xx_GPT_MODE_GPIO_OUT_HIGH (0x30)
+
+#define MPC52xx_GPT_MODE_IRQ_EN (0x0100)
+
+#define MPC52xx_GPT_MODE_ICT_MASK (0x030000)
+#define MPC52xx_GPT_MODE_ICT_RISING (0x010000)
+#define MPC52xx_GPT_MODE_ICT_FALLING (0x020000)
+#define MPC52xx_GPT_MODE_ICT_TOGGLE (0x030000)
+
+#define MPC52xx_GPT_STATUS_IRQMASK (0x000f)
+
+/* ---------------------------------------------------------------------
+ * Cascaded interrupt controller hooks
+ */
+
+static void mpc52xx_gpt_irq_unmask(unsigned int virq)
+{
+ struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+ unsigned long flags;
+
+ spin_lock_irqsave(&gpt->lock, flags);
+ setbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
+ spin_unlock_irqrestore(&gpt->lock, flags);
+}
+
+static void mpc52xx_gpt_irq_mask(unsigned int virq)
+{
+ struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+ unsigned long flags;
+
+ spin_lock_irqsave(&gpt->lock, flags);
+ clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_IRQ_EN);
+ spin_unlock_irqrestore(&gpt->lock, flags);
+}
+
+static void mpc52xx_gpt_irq_ack(unsigned int virq)
+{
+ struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+
+ out_be32(&gpt->regs->status, MPC52xx_GPT_STATUS_IRQMASK);
+}
+
+static int mpc52xx_gpt_irq_set_type(unsigned int virq, unsigned int flow_type)
+{
+ struct mpc52xx_gpt_priv *gpt = get_irq_chip_data(virq);
+ unsigned long flags;
+ u32 reg;
+
+ dev_dbg(gpt->dev, "%s: virq=%i type=%x\n", __func__, virq, flow_type);
+
+ spin_lock_irqsave(&gpt->lock, flags);
+ reg = in_be32(&gpt->regs->mode) & ~MPC52xx_GPT_MODE_ICT_MASK;
+ if (flow_type & IRQF_TRIGGER_RISING)
+ reg |= MPC52xx_GPT_MODE_ICT_RISING;
+ if (flow_type & IRQF_TRIGGER_FALLING)
+ reg |= MPC52xx_GPT_MODE_ICT_FALLING;
+ out_be32(&gpt->regs->mode, reg);
+ spin_unlock_irqrestore(&gpt->lock, flags);
+
+ return 0;
+}
+
+static struct irq_chip mpc52xx_gpt_irq_chip = {
+ .typename = "MPC52xx GPT",
+ .unmask = mpc52xx_gpt_irq_unmask,
+ .mask = mpc52xx_gpt_irq_mask,
+ .ack = mpc52xx_gpt_irq_ack,
+ .set_type = mpc52xx_gpt_irq_set_type,
+};
+
+void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc)
+{
+ struct mpc52xx_gpt_priv *gpt = get_irq_data(virq);
+ int sub_virq;
+ u32 status;
+
+ status = in_be32(&gpt->regs->status) & MPC52xx_GPT_STATUS_IRQMASK;
+ if (status) {
+ sub_virq = irq_linear_revmap(gpt->irqhost, 0);
+ generic_handle_irq(sub_virq);
+ }
+}
+
+static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ struct mpc52xx_gpt_priv *gpt = h->host_data;
+
+ dev_dbg(gpt->dev, "%s: h=%p, virq=%i\n", __func__, h, virq);
+ set_irq_chip_data(virq, gpt);
+ set_irq_chip_and_handler(virq, &mpc52xx_gpt_irq_chip, handle_edge_irq);
+
+ return 0;
+}
+
+static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct,
+ u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq,
+ unsigned int *out_flags)
+{
+ struct mpc52xx_gpt_priv *gpt = h->host_data;
+
+ dev_dbg(gpt->dev, "%s: flags=%i\n", __func__, intspec[0]);
+
+ if ((intsize < 1) || (intspec[0] < 1) || (intspec[0] > 3)) {
+ dev_err(gpt->dev, "bad irq specifier in %s\n", ct->full_name);
+ return -EINVAL;
+ }
+
+ *out_hwirq = 0; /* The GPT only has 1 IRQ line */
+ *out_flags = intspec[0];
+
+ return 0;
+}
+
+static struct irq_host_ops mpc52xx_gpt_irq_ops = {
+ .map = mpc52xx_gpt_irq_map,
+ .xlate = mpc52xx_gpt_irq_xlate,
+};
+
+static void
+mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
+{
+ int cascade_virq;
+ unsigned long flags;
+
+ /* Only setup cascaded IRQ if device tree claims the GPT is
+ * an interrupt controller */
+ if (!of_find_property(node, "interrupt-controller", NULL))
+ return;
+
+ cascade_virq = irq_of_parse_and_map(node, 0);
+
+ gpt->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 1,
+ &mpc52xx_gpt_irq_ops, -1);
+ if (!gpt->irqhost) {
+ dev_err(gpt->dev, "irq_alloc_host() failed\n");
+ return;
+ }
+
+ gpt->irqhost->host_data = gpt;
+
+ set_irq_data(cascade_virq, gpt);
+ set_irq_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade);
+
+ /* Set to Input Capture mode */
+ spin_lock_irqsave(&gpt->lock, flags);
+ clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK,
+ MPC52xx_GPT_MODE_MS_IC);
+ spin_unlock_irqrestore(&gpt->lock, flags);
+
+ dev_dbg(gpt->dev, "%s() complete. virq=%i\n", __func__, cascade_virq);
+}
+
+
+/* ---------------------------------------------------------------------
+ * GPIOLIB hooks
+ */
+#if defined(CONFIG_GPIOLIB)
+static inline struct mpc52xx_gpt_priv *gc_to_mpc52xx_gpt(struct gpio_chip *gc)
+{
+ return container_of(to_of_gpio_chip(gc), struct mpc52xx_gpt_priv,of_gc);
+}
+
+static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct mpc52xx_gpt_priv *gpt = gc_to_mpc52xx_gpt(gc);
+
+ return (in_be32(&gpt->regs->status) >> 8) & 1;
+}
+
+static void
+mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int v)
+{
+ struct mpc52xx_gpt_priv *gpt = gc_to_mpc52xx_gpt(gc);
+ unsigned long flags;
+ u32 r;
+
+ dev_dbg(gpt->dev, "%s: gpio:%d v:%d\n", __func__, gpio, v);
+ r = v ? MPC52xx_GPT_MODE_GPIO_OUT_HIGH : MPC52xx_GPT_MODE_GPIO_OUT_LOW;
+
+ spin_lock_irqsave(&gpt->lock, flags);
+ clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK, r);
+ spin_unlock_irqrestore(&gpt->lock, flags);
+}
+
+static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct mpc52xx_gpt_priv *gpt = gc_to_mpc52xx_gpt(gc);
+ unsigned long flags;
+
+ dev_dbg(gpt->dev, "%s: gpio:%d\n", __func__, gpio);
+
+ spin_lock_irqsave(&gpt->lock, flags);
+ clrbits32(&gpt->regs->mode, MPC52xx_GPT_MODE_GPIO_MASK);
+ spin_unlock_irqrestore(&gpt->lock, flags);
+
+ return 0;
+}
+
+static int
+mpc52xx_gpt_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+ mpc52xx_gpt_gpio_set(gc, gpio, val);
+ return 0;
+}
+
+static void
+mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
+{
+ int rc;
+
+ /* Only setup GPIO if the device tree claims the GPT is
+ * a GPIO controller */
+ if (!of_find_property(node, "gpio-controller", NULL))
+ return;
+
+ gpt->of_gc.gc.label = kstrdup(node->full_name, GFP_KERNEL);
+ if (!gpt->of_gc.gc.label) {
+ dev_err(gpt->dev, "out of memory\n");
+ return;
+ }
+
+ gpt->of_gc.gpio_cells = 2;
+ gpt->of_gc.gc.ngpio = 1;
+ gpt->of_gc.gc.direction_input = mpc52xx_gpt_gpio_dir_in;
+ gpt->of_gc.gc.direction_output = mpc52xx_gpt_gpio_dir_out;
+ gpt->of_gc.gc.get = mpc52xx_gpt_gpio_get;
+ gpt->of_gc.gc.set = mpc52xx_gpt_gpio_set;
+ gpt->of_gc.gc.base = -1;
+ gpt->of_gc.xlate = of_gpio_simple_xlate;
+ node->data = &gpt->of_gc;
+ of_node_get(node);
+
+ /* Setup external pin in GPIO mode */
+ clrsetbits_be32(&gpt->regs->mode, MPC52xx_GPT_MODE_MS_MASK,
+ MPC52xx_GPT_MODE_MS_GPIO);
+
+ rc = gpiochip_add(&gpt->of_gc.gc);
+ if (rc)
+ dev_err(gpt->dev, "gpiochip_add() failed; rc=%i\n", rc);
+
+ dev_dbg(gpt->dev, "%s() complete.\n", __func__);
+}
+#else /* defined(CONFIG_GPIOLIB) */
+static void
+mpc52xx_gpt_gpio_setup(struct mpc52xx_gpt_priv *p, struct device_node *np) { }
+#endif /* defined(CONFIG_GPIOLIB) */
+
+/* ---------------------------------------------------------------------
+ * of_platform bus binding code
+ */
+static int __devinit mpc52xx_gpt_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct mpc52xx_gpt_priv *gpt;
+
+ gpt = kzalloc(sizeof *gpt, GFP_KERNEL);
+ if (!gpt)
+ return -ENOMEM;
+
+ spin_lock_init(&gpt->lock);
+ gpt->dev = &ofdev->dev;
+ gpt->regs = of_iomap(ofdev->node, 0);
+ if (!gpt->regs) {
+ kfree(gpt);
+ return -ENOMEM;
+ }
+
+ dev_set_drvdata(&ofdev->dev, gpt);
+
+ mpc52xx_gpt_gpio_setup(gpt, ofdev->node);
+ mpc52xx_gpt_irq_setup(gpt, ofdev->node);
+
+ return 0;
+}
+
+static int mpc52xx_gpt_remove(struct of_device *ofdev)
+{
+ return -EBUSY;
+}
+
+static const struct of_device_id mpc52xx_gpt_match[] = {
+ { .compatible = "fsl,mpc5200-gpt", },
+
+ /* Depreciated compatible values; don't use for new dts files */
+ { .compatible = "fsl,mpc5200-gpt-gpio", },
+ { .compatible = "mpc5200-gpt", },
+ {}
+};
+
+static struct of_platform_driver mpc52xx_gpt_driver = {
+ .name = "mpc52xx-gpt",
+ .match_table = mpc52xx_gpt_match,
+ .probe = mpc52xx_gpt_probe,
+ .remove = mpc52xx_gpt_remove,
+};
+
+static int __init mpc52xx_gpt_init(void)
+{
+ if (of_register_platform_driver(&mpc52xx_gpt_driver))
+ pr_err("error registering MPC52xx GPT driver\n");
+
+ return 0;
+}
+
+/* Make sure GPIOs and IRQs get set up before anyone tries to use them */
+subsys_initcall(mpc52xx_gpt_init);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 0a093f03c758..480f806fd0a9 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -163,8 +163,6 @@ static void mpc52xx_extirq_mask(unsigned int virq)
irq = irq_map[virq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
- pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
io_be_clrbit(&intr->ctrl, 11 - l2irq);
}
@@ -176,8 +174,6 @@ static void mpc52xx_extirq_unmask(unsigned int virq)
irq = irq_map[virq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
- pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
io_be_setbit(&intr->ctrl, 11 - l2irq);
}
@@ -189,17 +185,15 @@ static void mpc52xx_extirq_ack(unsigned int virq)
irq = irq_map[virq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
- pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
io_be_setbit(&intr->ctrl, 27-l2irq);
}
static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
{
- struct irq_desc *desc = get_irq_desc(virq);
u32 ctrl_reg, type;
int irq;
int l2irq;
+ void *handler = handle_level_irq;
irq = irq_map[virq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
@@ -207,32 +201,21 @@ static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__, irq, l2irq, flow_type);
switch (flow_type) {
- case IRQF_TRIGGER_HIGH:
- type = 0;
- break;
- case IRQF_TRIGGER_RISING:
- type = 1;
- break;
- case IRQF_TRIGGER_FALLING:
- type = 2;
- break;
- case IRQF_TRIGGER_LOW:
- type = 3;
- break;
+ case IRQF_TRIGGER_HIGH: type = 0; break;
+ case IRQF_TRIGGER_RISING: type = 1; handler = handle_edge_irq; break;
+ case IRQF_TRIGGER_FALLING: type = 2; handler = handle_edge_irq; break;
+ case IRQF_TRIGGER_LOW: type = 3; break;
default:
type = 0;
}
- desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
- desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
- if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
- desc->status |= IRQ_LEVEL;
-
ctrl_reg = in_be32(&intr->ctrl);
ctrl_reg &= ~(0x3 << (22 - (l2irq * 2)));
ctrl_reg |= (type << (22 - (l2irq * 2)));
out_be32(&intr->ctrl, ctrl_reg);
+ __set_irq_handler_unlocked(virq, handler);
+
return 0;
}
@@ -247,6 +230,11 @@ static struct irq_chip mpc52xx_extirq_irqchip = {
/*
* Main interrupt irq_chip
*/
+static int mpc52xx_null_set_type(unsigned int virq, unsigned int flow_type)
+{
+ return 0; /* Do nothing so that the sense mask will get updated */
+}
+
static void mpc52xx_main_mask(unsigned int virq)
{
int irq;
@@ -255,8 +243,6 @@ static void mpc52xx_main_mask(unsigned int virq)
irq = irq_map[virq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
- pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
io_be_setbit(&intr->main_mask, 16 - l2irq);
}
@@ -268,8 +254,6 @@ static void mpc52xx_main_unmask(unsigned int virq)
irq = irq_map[virq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
- pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
io_be_clrbit(&intr->main_mask, 16 - l2irq);
}
@@ -278,6 +262,7 @@ static struct irq_chip mpc52xx_main_irqchip = {
.mask = mpc52xx_main_mask,
.mask_ack = mpc52xx_main_mask,
.unmask = mpc52xx_main_unmask,
+ .set_type = mpc52xx_null_set_type,
};
/*
@@ -291,8 +276,6 @@ static void mpc52xx_periph_mask(unsigned int virq)
irq = irq_map[virq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
- pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
io_be_setbit(&intr->per_mask, 31 - l2irq);
}
@@ -304,8 +287,6 @@ static void mpc52xx_periph_unmask(unsigned int virq)
irq = irq_map[virq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
- pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
io_be_clrbit(&intr->per_mask, 31 - l2irq);
}
@@ -314,6 +295,7 @@ static struct irq_chip mpc52xx_periph_irqchip = {
.mask = mpc52xx_periph_mask,
.mask_ack = mpc52xx_periph_mask,
.unmask = mpc52xx_periph_unmask,
+ .set_type = mpc52xx_null_set_type,
};
/*
@@ -327,8 +309,6 @@ static void mpc52xx_sdma_mask(unsigned int virq)
irq = irq_map[virq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
- pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
io_be_setbit(&sdma->IntMask, l2irq);
}
@@ -340,8 +320,6 @@ static void mpc52xx_sdma_unmask(unsigned int virq)
irq = irq_map[virq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
- pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
io_be_clrbit(&sdma->IntMask, l2irq);
}
@@ -353,8 +331,6 @@ static void mpc52xx_sdma_ack(unsigned int virq)
irq = irq_map[virq].hwirq;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
- pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
-
out_be32(&sdma->IntPend, 1 << l2irq);
}
@@ -363,9 +339,19 @@ static struct irq_chip mpc52xx_sdma_irqchip = {
.mask = mpc52xx_sdma_mask,
.unmask = mpc52xx_sdma_unmask,
.ack = mpc52xx_sdma_ack,
+ .set_type = mpc52xx_null_set_type,
};
/**
+ * mpc52xx_is_extirq - Returns true if hwirq number is for an external IRQ
+ */
+static int mpc52xx_is_extirq(int l1, int l2)
+{
+ return ((l1 == 0) && (l2 == 0)) ||
+ ((l1 == 1) && (l2 >= 1) && (l2 <= 3));
+}
+
+/**
* mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property
*/
static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
@@ -383,38 +369,23 @@ static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
intrvect_l1 = (int)intspec[0];
intrvect_l2 = (int)intspec[1];
- intrvect_type = (int)intspec[2];
+ intrvect_type = (int)intspec[2] & 0x3;
intrvect_linux = (intrvect_l1 << MPC52xx_IRQ_L1_OFFSET) &
MPC52xx_IRQ_L1_MASK;
intrvect_linux |= intrvect_l2 & MPC52xx_IRQ_L2_MASK;
- pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1,
- intrvect_l2);
-
*out_hwirq = intrvect_linux;
- *out_flags = mpc52xx_map_senses[intrvect_type];
+ *out_flags = IRQ_TYPE_LEVEL_LOW;
+ if (mpc52xx_is_extirq(intrvect_l1, intrvect_l2))
+ *out_flags = mpc52xx_map_senses[intrvect_type];
+ pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1,
+ intrvect_l2);
return 0;
}
/**
- * mpc52xx_irqx_gettype - determine the IRQ sense type (level/edge)
- *
- * Only external IRQs need this.
- */
-static int mpc52xx_irqx_gettype(int irq)
-{
- int type;
- u32 ctrl_reg;
-
- ctrl_reg = in_be32(&intr->ctrl);
- type = (ctrl_reg >> (22 - irq * 2)) & 0x3;
-
- return mpc52xx_map_senses[type];
-}
-
-/**
* mpc52xx_irqhost_map - Hook to map from virq to an irq_chip structure
*/
static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
@@ -422,68 +393,46 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
{
int l1irq;
int l2irq;
- struct irq_chip *good_irqchip;
- void *good_handle;
+ struct irq_chip *irqchip;
+ void *hndlr;
int type;
+ u32 reg;
l1irq = (irq & MPC52xx_IRQ_L1_MASK) >> MPC52xx_IRQ_L1_OFFSET;
l2irq = irq & MPC52xx_IRQ_L2_MASK;
/*
- * Most of ours IRQs will be level low
- * Only external IRQs on some platform may be others
+ * External IRQs are handled differently by the hardware so they are
+ * handled by a dedicated irq_chip structure.
*/
- type = IRQ_TYPE_LEVEL_LOW;
+ if (mpc52xx_is_extirq(l1irq, l2irq)) {
+ reg = in_be32(&intr->ctrl);
+ type = mpc52xx_map_senses[(reg >> (22 - l2irq * 2)) & 0x3];
+ if ((type == IRQ_TYPE_EDGE_FALLING) ||
+ (type == IRQ_TYPE_EDGE_RISING))
+ hndlr = handle_edge_irq;
+ else
+ hndlr = handle_level_irq;
+
+ set_irq_chip_and_handler(virq, &mpc52xx_extirq_irqchip, hndlr);
+ pr_debug("%s: External IRQ%i virq=%x, hw=%x. type=%x\n",
+ __func__, l2irq, virq, (int)irq, type);
+ return 0;
+ }
+ /* It is an internal SOC irq. Choose the correct irq_chip */
switch (l1irq) {
- case MPC52xx_IRQ_L1_CRIT:
- pr_debug("%s: Critical. l2=%x\n", __func__, l2irq);
-
- BUG_ON(l2irq != 0);
-
- type = mpc52xx_irqx_gettype(l2irq);
- good_irqchip = &mpc52xx_extirq_irqchip;
- break;
-
- case MPC52xx_IRQ_L1_MAIN:
- pr_debug("%s: Main IRQ[1-3] l2=%x\n", __func__, l2irq);
-
- if ((l2irq >= 1) && (l2irq <= 3)) {
- type = mpc52xx_irqx_gettype(l2irq);
- good_irqchip = &mpc52xx_extirq_irqchip;
- } else {
- good_irqchip = &mpc52xx_main_irqchip;
- }
- break;
-
- case MPC52xx_IRQ_L1_PERP:
- pr_debug("%s: Peripherals. l2=%x\n", __func__, l2irq);
- good_irqchip = &mpc52xx_periph_irqchip;
- break;
-
- case MPC52xx_IRQ_L1_SDMA:
- pr_debug("%s: SDMA. l2=%x\n", __func__, l2irq);
- good_irqchip = &mpc52xx_sdma_irqchip;
- break;
-
+ case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break;
+ case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break;
+ case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break;
default:
- pr_err("%s: invalid virq requested (0x%x)\n", __func__, virq);
+ pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n",
+ __func__, virq, l1irq, l2irq);
return -EINVAL;
}
- switch (type) {
- case IRQ_TYPE_EDGE_FALLING:
- case IRQ_TYPE_EDGE_RISING:
- good_handle = handle_edge_irq;
- break;
- default:
- good_handle = handle_level_irq;
- }
-
- set_irq_chip_and_handler(virq, good_irqchip, good_handle);
-
- pr_debug("%s: virq=%x, hw=%x. type=%x\n", __func__, virq,
- (int)irq, type);
+ set_irq_chip_and_handler(virq, irqchip, handle_level_irq);
+ pr_debug("%s: virq=%x, l1=%i, l2=%i\n", __func__, virq, l1irq, l2irq);
return 0;
}
@@ -522,6 +471,8 @@ void __init mpc52xx_init_irq(void)
panic(__FILE__ ": find_and_map failed on 'mpc5200-bestcomm'. "
"Check node !");
+ pr_debug("MPC5200 IRQ controller mapped to 0x%p\n", intr);
+
/* Disable all interrupt sources. */
out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */
out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */
@@ -613,8 +564,5 @@ unsigned int mpc52xx_get_irq(void)
}
}
- pr_debug("%s: irq=%x. virq=%d\n", __func__, irq,
- irq_linear_revmap(mpc52xx_irqhost, irq));
-
return irq_linear_revmap(mpc52xx_irqhost, irq);
}
diff --git a/arch/powerpc/platforms/82xx/Kconfig b/arch/powerpc/platforms/82xx/Kconfig
index 30f008b2f92e..7c7df4003820 100644
--- a/arch/powerpc/platforms/82xx/Kconfig
+++ b/arch/powerpc/platforms/82xx/Kconfig
@@ -1,6 +1,6 @@
menuconfig PPC_82xx
bool "82xx-based boards (PQ II)"
- depends on 6xx && PPC_MULTIPLATFORM
+ depends on 6xx
if PPC_82xx
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 83c664afc897..437d29a59d72 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -1,6 +1,6 @@
menuconfig PPC_83xx
bool "83xx-based boards"
- depends on 6xx && PPC_MULTIPLATFORM
+ depends on 6xx
select PPC_UDBG_16550
select PPC_PCI_CHOICE
select FSL_PCI if PCI
diff --git a/arch/powerpc/platforms/83xx/asp834x.c b/arch/powerpc/platforms/83xx/asp834x.c
index bb30d67ad0a2..aa0d84d22585 100644
--- a/arch/powerpc/platforms/83xx/asp834x.c
+++ b/arch/powerpc/platforms/83xx/asp834x.c
@@ -58,6 +58,7 @@ static struct __initdata of_device_id asp8347_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/mpc831x_rdb.c b/arch/powerpc/platforms/83xx/mpc831x_rdb.c
index 91a2c80b9d72..0b4f883b20eb 100644
--- a/arch/powerpc/platforms/83xx/mpc831x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc831x_rdb.c
@@ -38,6 +38,8 @@ static void __init mpc831x_rdb_setup_arch(void)
#ifdef CONFIG_PCI
for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
mpc83xx_add_bridge(np);
+ for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie")
+ mpc83xx_add_bridge(np);
#endif
mpc831x_usb_cfg();
}
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index 2a1295f19832..567ded7c3b9b 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -20,6 +20,7 @@
#include <linux/spi/mmc_spi.h>
#include <linux/mmc/host.h>
#include <linux/of_platform.h>
+#include <linux/fsl_devices.h>
#include <asm/time.h>
#include <asm/ipic.h>
@@ -39,16 +40,116 @@
#endif
#ifdef CONFIG_QUICC_ENGINE
-static void mpc83xx_spi_activate_cs(u8 cs, u8 polarity)
+static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
+ struct spi_board_info *board_infos,
+ unsigned int num_board_infos,
+ void (*cs_control)(struct spi_device *dev,
+ bool on))
{
- pr_debug("%s %d %d\n", __func__, cs, polarity);
- par_io_data_set(3, 13, polarity);
+ struct device_node *np;
+ unsigned int i = 0;
+
+ for_each_compatible_node(np, type, compatible) {
+ int ret;
+ unsigned int j;
+ const void *prop;
+ struct resource res[2];
+ struct platform_device *pdev;
+ struct fsl_spi_platform_data pdata = {
+ .cs_control = cs_control,
+ };
+
+ memset(res, 0, sizeof(res));
+
+ pdata.sysclk = sysclk;
+
+ prop = of_get_property(np, "reg", NULL);
+ if (!prop)
+ goto err;
+ pdata.bus_num = *(u32 *)prop;
+
+ prop = of_get_property(np, "cell-index", NULL);
+ if (prop)
+ i = *(u32 *)prop;
+
+ prop = of_get_property(np, "mode", NULL);
+ if (prop && !strcmp(prop, "cpu-qe"))
+ pdata.qe_mode = 1;
+
+ for (j = 0; j < num_board_infos; j++) {
+ if (board_infos[j].bus_num == pdata.bus_num)
+ pdata.max_chipselect++;
+ }
+
+ if (!pdata.max_chipselect)
+ continue;
+
+ ret = of_address_to_resource(np, 0, &res[0]);
+ if (ret)
+ goto err;
+
+ ret = of_irq_to_resource(np, 0, &res[1]);
+ if (ret == NO_IRQ)
+ goto err;
+
+ pdev = platform_device_alloc("mpc83xx_spi", i);
+ if (!pdev)
+ goto err;
+
+ ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (ret)
+ goto unreg;
+
+ ret = platform_device_add_resources(pdev, res,
+ ARRAY_SIZE(res));
+ if (ret)
+ goto unreg;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+ goto unreg;
+
+ goto next;
+unreg:
+ platform_device_del(pdev);
+err:
+ pr_err("%s: registration failed\n", np->full_name);
+next:
+ i++;
+ }
+
+ return i;
}
-static void mpc83xx_spi_deactivate_cs(u8 cs, u8 polarity)
+static int __init fsl_spi_init(struct spi_board_info *board_infos,
+ unsigned int num_board_infos,
+ void (*cs_control)(struct spi_device *spi,
+ bool on))
{
- pr_debug("%s %d %d\n", __func__, cs, polarity);
- par_io_data_set(3, 13, !polarity);
+ u32 sysclk = -1;
+ int ret;
+
+ /* SPI controller is either clocked from QE or SoC clock */
+ sysclk = get_brgfreq();
+ if (sysclk == -1) {
+ sysclk = fsl_get_sys_freq();
+ if (sysclk == -1)
+ return -ENODEV;
+ }
+
+ ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos,
+ num_board_infos, cs_control);
+ if (!ret)
+ of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos,
+ num_board_infos, cs_control);
+
+ return spi_register_board_info(board_infos, num_board_infos);
+}
+
+static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on)
+{
+ pr_debug("%s %d %d\n", __func__, spi->chip_select, on);
+ par_io_data_set(3, 13, on);
}
static struct mmc_spi_platform_data mpc832x_mmc_pdata = {
@@ -74,9 +175,13 @@ static int __init mpc832x_spi_init(void)
par_io_config_pin(3, 14, 2, 0, 0, 0); /* SD_INSERT, I */
par_io_config_pin(3, 15, 2, 0, 0, 0); /* SD_PROTECT,I */
- return fsl_spi_init(&mpc832x_spi_boardinfo, 1,
- mpc83xx_spi_activate_cs,
- mpc83xx_spi_deactivate_cs);
+ /*
+ * Don't bother with legacy stuff when device tree contains
+ * mmc-spi-slot node.
+ */
+ if (of_find_compatible_node(NULL, NULL, "mmc-spi-slot"))
+ return 0;
+ return fsl_spi_init(&mpc832x_spi_boardinfo, 1, mpc83xx_spi_cs_control);
}
machine_device_initcall(mpc832x_rdb, mpc832x_spi_init);
#endif /* CONFIG_QUICC_ENGINE */
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index 76092d37c7d9..81e44fa1c644 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -42,6 +42,7 @@
static struct of_device_id __initdata mpc834x_itx_ids[] = {
{ .compatible = "fsl,pq2pro-localbus", },
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c
index fc3f2ed1f3e9..d0a634b056ca 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
@@ -112,6 +112,7 @@ static struct of_device_id mpc834x_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c
index 530ef990ca7c..51df7e754698 100644
--- a/arch/powerpc/platforms/83xx/mpc837x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c
@@ -84,14 +84,10 @@ static void __init mpc837x_mds_setup_arch(void)
ppc_md.progress("mpc837x_mds_setup_arch()", 0);
#ifdef CONFIG_PCI
- for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") {
- if (!of_device_is_available(np)) {
- pr_warning("%s: disabled by the firmware.\n",
- np->full_name);
- continue;
- }
+ for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
+ mpc83xx_add_bridge(np);
+ for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie")
mpc83xx_add_bridge(np);
- }
#endif
mpc837xmds_usb_cfg();
}
@@ -100,6 +96,7 @@ static struct of_device_id mpc837x_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c
index 1d096545322b..76f3b32a155e 100644
--- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c
@@ -38,6 +38,8 @@ static void __init mpc837x_rdb_setup_arch(void)
#ifdef CONFIG_PCI
for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
mpc83xx_add_bridge(np);
+ for_each_compatible_node(np, "pci", "fsl,mpc8314-pcie")
+ mpc83xx_add_bridge(np);
#endif
mpc837x_usb_cfg();
}
@@ -46,6 +48,7 @@ static struct of_device_id mpc837x_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/sbc834x.c b/arch/powerpc/platforms/83xx/sbc834x.c
index 156c4e218009..49023dbe1576 100644
--- a/arch/powerpc/platforms/83xx/sbc834x.c
+++ b/arch/powerpc/platforms/83xx/sbc834x.c
@@ -84,6 +84,7 @@ static struct __initdata of_device_id sbc834x_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/83xx/usb.c b/arch/powerpc/platforms/83xx/usb.c
index cc99c280aad9..11e1fac17c7f 100644
--- a/arch/powerpc/platforms/83xx/usb.c
+++ b/arch/powerpc/platforms/83xx/usb.c
@@ -14,6 +14,7 @@
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/of.h>
#include <asm/io.h>
#include <asm/prom.h>
@@ -210,7 +211,7 @@ int mpc837x_usb_cfg(void)
int ret = 0;
np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr");
- if (!np)
+ if (!np || !of_device_is_available(np))
return -ENODEV;
prop = of_get_property(np, "phy_type", NULL);
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index b79dc710ed34..7f066adc068c 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -51,6 +51,12 @@ config MPC85xx_DS
help
This option enables support for the MPC85xx DS (MPC8544 DS) board
+config SOCRATES
+ bool "Socrates"
+ select DEFAULT_UIMAGE
+ help
+ This option enables support for the Socrates board.
+
config KSI8560
bool "Emerson KSI8560"
select DEFAULT_UIMAGE
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index f0798c09980f..a857b35b9828 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -13,4 +13,5 @@ obj-$(CONFIG_STX_GP3) += stx_gp3.o
obj-$(CONFIG_TQM85xx) += tqm85xx.o
obj-$(CONFIG_SBC8560) += sbc8560.o
obj-$(CONFIG_SBC8548) += sbc8548.o
+obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o
obj-$(CONFIG_KSI8560) += ksi8560.o
diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c
index 81cee7bbf2d2..f4d36b5a2e00 100644
--- a/arch/powerpc/platforms/85xx/ksi8560.c
+++ b/arch/powerpc/platforms/85xx/ksi8560.c
@@ -106,8 +106,6 @@ static void __init ksi8560_pic_init(void)
cpm2_pic_init(np);
of_node_put(np);
set_irq_chained_handler(irq, cpm2_cascade);
-
- setup_irq(0, NULL);
#endif
}
@@ -221,6 +219,7 @@ static struct of_device_id __initdata of_bus_ids[] = {
{ .type = "simple-bus", },
{ .name = "cpm", },
{ .name = "localbus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c
index 1bf5aefdfeb1..63efca20d7bd 100644
--- a/arch/powerpc/platforms/85xx/mpc8536_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c
@@ -92,6 +92,7 @@ static struct of_device_id __initdata mpc8536_ds_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 21f009023e26..9438a892afc4 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -226,6 +226,7 @@ static struct of_device_id __initdata of_bus_ids[] = {
{ .name = "cpm", },
{ .name = "localbus", },
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index aeb6a5bc5522..458d91fba91d 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -179,7 +179,6 @@ static irqreturn_t mpc85xx_8259_cascade_action(int irq, void *dev_id)
static struct irqaction mpc85xxcds_8259_irqaction = {
.handler = mpc85xx_8259_cascade_action,
.flags = IRQF_SHARED,
- .mask = CPU_MASK_NONE,
.name = "8259 cascade",
};
#endif /* PPC_I8259 */
@@ -336,6 +335,7 @@ static struct of_device_id __initdata of_bus_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 7326d904202c..de66de7a9ca2 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -204,6 +204,7 @@ static struct of_device_id __initdata mpc85xxds_ids[] = {
{ .type = "soc", },
{ .compatible = "soc", },
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 658a36fab3ab..7dd029034aec 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -265,6 +265,7 @@ static struct of_device_id mpc85xx_ids[] = {
{ .compatible = "simple-bus", },
{ .type = "qe", },
{ .compatible = "fsl,qe", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c
index 7ec77ce12dad..ecdd8c09e4ed 100644
--- a/arch/powerpc/platforms/85xx/sbc8548.c
+++ b/arch/powerpc/platforms/85xx/sbc8548.c
@@ -154,6 +154,7 @@ static struct of_device_id __initdata of_bus_ids[] = {
{ .name = "soc", },
{ .type = "soc", },
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c
index 472f254a19d2..cc27807a8b64 100644
--- a/arch/powerpc/platforms/85xx/sbc8560.c
+++ b/arch/powerpc/platforms/85xx/sbc8560.c
@@ -213,6 +213,7 @@ static struct of_device_id __initdata of_bus_ids[] = {
{ .name = "cpm", },
{ .name = "localbus", },
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 79a0df17078b..cc0b0db8a6f3 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -21,6 +21,7 @@
#include <asm/page.h>
#include <asm/mpic.h>
#include <asm/cacheflush.h>
+#include <asm/dbell.h>
#include <sysdev/fsl_soc.h>
@@ -80,10 +81,8 @@ smp_85xx_kick_cpu(int nr)
}
static void __init
-smp_85xx_setup_cpu(int cpu_nr)
+smp_85xx_basic_setup(int cpu_nr)
{
- mpic_setup_this_cpu();
-
/* Clear any pending timer interrupts */
mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
@@ -91,15 +90,43 @@ smp_85xx_setup_cpu(int cpu_nr)
mtspr(SPRN_TCR, TCR_DIE);
}
+static void __init
+smp_85xx_setup_cpu(int cpu_nr)
+{
+ mpic_setup_this_cpu();
+
+ smp_85xx_basic_setup(cpu_nr);
+}
+
struct smp_ops_t smp_85xx_ops = {
- .message_pass = smp_mpic_message_pass,
- .probe = smp_mpic_probe,
.kick_cpu = smp_85xx_kick_cpu,
- .setup_cpu = smp_85xx_setup_cpu,
};
-void __init
-mpc85xx_smp_init(void)
+static int __init smp_dummy_probe(void)
{
+ return NR_CPUS;
+}
+
+void __init mpc85xx_smp_init(void)
+{
+ struct device_node *np;
+
+ smp_85xx_ops.message_pass = NULL;
+
+ np = of_find_node_by_type(NULL, "open-pic");
+ if (np) {
+ smp_85xx_ops.probe = smp_mpic_probe;
+ smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu;
+ smp_85xx_ops.message_pass = smp_mpic_message_pass;
+ } else {
+ smp_85xx_ops.probe = smp_dummy_probe;
+ smp_85xx_ops.setup_cpu = smp_85xx_basic_setup;
+ }
+
+ if (cpu_has_feature(CPU_FTR_DBELL))
+ smp_85xx_ops.message_pass = smp_dbell_message_pass;
+
+ BUG_ON(!smp_85xx_ops.message_pass);
+
smp_ops = &smp_85xx_ops;
}
diff --git a/arch/powerpc/platforms/85xx/socrates.c b/arch/powerpc/platforms/85xx/socrates.c
new file mode 100644
index 000000000000..d0e8443b12c6
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/socrates.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2008 Emcraft Systems
+ * Sergei Poselenov <sposelenov@emcraft.com>
+ *
+ * Based on MPC8560 ADS and arch/ppc tqm85xx ports
+ *
+ * Maintained by Kumar Gala (see MAINTAINERS for contact information)
+ *
+ * Copyright 2008 Freescale Semiconductor Inc.
+ *
+ * Copyright (c) 2005-2006 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
+ *
+ * Based on original work by
+ * Kumar Gala <kumar.gala@freescale.com>
+ * Copyright 2004 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/of_platform.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpic.h>
+#include <asm/prom.h>
+#include <mm/mmu_decl.h>
+#include <asm/udbg.h>
+
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+
+#include "socrates_fpga_pic.h"
+
+static void __init socrates_pic_init(void)
+{
+ struct mpic *mpic;
+ struct resource r;
+ struct device_node *np;
+
+ np = of_find_node_by_type(NULL, "open-pic");
+ if (!np) {
+ printk(KERN_ERR "Could not find open-pic node\n");
+ return;
+ }
+
+ if (of_address_to_resource(np, 0, &r)) {
+ printk(KERN_ERR "Could not map mpic register space\n");
+ of_node_put(np);
+ return;
+ }
+
+ mpic = mpic_alloc(np, r.start,
+ MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
+ 0, 256, " OpenPIC ");
+ BUG_ON(mpic == NULL);
+ of_node_put(np);
+
+ mpic_init(mpic);
+
+ np = of_find_compatible_node(NULL, NULL, "abb,socrates-fpga-pic");
+ if (!np) {
+ printk(KERN_ERR "Could not find socrates-fpga-pic node\n");
+ return;
+ }
+ socrates_fpga_pic_init(np);
+ of_node_put(np);
+}
+
+/*
+ * Setup the architecture
+ */
+static void __init socrates_setup_arch(void)
+{
+#ifdef CONFIG_PCI
+ struct device_node *np;
+#endif
+
+ if (ppc_md.progress)
+ ppc_md.progress("socrates_setup_arch()", 0);
+
+#ifdef CONFIG_PCI
+ for_each_compatible_node(np, "pci", "fsl,mpc8540-pci")
+ fsl_add_bridge(np, 1);
+#endif
+}
+
+static struct of_device_id __initdata socrates_of_bus_ids[] = {
+ { .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
+ {},
+};
+
+static void __init socrates_init(void)
+{
+ of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL);
+}
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init socrates_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (of_flat_dt_is_compatible(root, "abb,socrates"))
+ return 1;
+
+ return 0;
+}
+
+define_machine(socrates) {
+ .name = "Socrates",
+ .probe = socrates_probe,
+ .setup_arch = socrates_setup_arch,
+ .init = socrates_init,
+ .init_IRQ = socrates_pic_init,
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
new file mode 100644
index 000000000000..60edf63d0157
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2008 Ilya Yanok, Emcraft Systems
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/irq.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+
+/*
+ * The FPGA supports 9 interrupt sources, which can be routed to 3
+ * interrupt request lines of the MPIC. The line to be used can be
+ * specified through the third cell of FDT property "interrupts".
+ */
+
+#define SOCRATES_FPGA_NUM_IRQS 9
+
+#define FPGA_PIC_IRQCFG (0x0)
+#define FPGA_PIC_IRQMASK(n) (0x4 + 0x4 * (n))
+
+#define SOCRATES_FPGA_IRQ_MASK ((1 << SOCRATES_FPGA_NUM_IRQS) - 1)
+
+struct socrates_fpga_irq_info {
+ unsigned int irq_line;
+ int type;
+};
+
+/*
+ * Interrupt routing and type table
+ *
+ * IRQ_TYPE_NONE means the interrupt type is configurable,
+ * otherwise it's fixed to the specified value.
+ */
+static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = {
+ [0] = {0, IRQ_TYPE_NONE},
+ [1] = {0, IRQ_TYPE_LEVEL_HIGH},
+ [2] = {0, IRQ_TYPE_LEVEL_LOW},
+ [3] = {0, IRQ_TYPE_NONE},
+ [4] = {0, IRQ_TYPE_NONE},
+ [5] = {0, IRQ_TYPE_NONE},
+ [6] = {0, IRQ_TYPE_NONE},
+ [7] = {0, IRQ_TYPE_NONE},
+ [8] = {0, IRQ_TYPE_LEVEL_HIGH},
+};
+
+#define socrates_fpga_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
+
+static DEFINE_SPINLOCK(socrates_fpga_pic_lock);
+
+static void __iomem *socrates_fpga_pic_iobase;
+static struct irq_host *socrates_fpga_pic_irq_host;
+static unsigned int socrates_fpga_irqs[3];
+
+static inline uint32_t socrates_fpga_pic_read(int reg)
+{
+ return in_be32(socrates_fpga_pic_iobase + reg);
+}
+
+static inline void socrates_fpga_pic_write(int reg, uint32_t val)
+{
+ out_be32(socrates_fpga_pic_iobase + reg, val);
+}
+
+static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq)
+{
+ uint32_t cause;
+ unsigned long flags;
+ int i;
+
+ /* Check irq line routed to the MPIC */
+ for (i = 0; i < 3; i++) {
+ if (irq == socrates_fpga_irqs[i])
+ break;
+ }
+ if (i == 3)
+ return NO_IRQ;
+
+ spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ cause = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(i));
+ spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+ for (i = SOCRATES_FPGA_NUM_IRQS - 1; i >= 0; i--) {
+ if (cause >> (i + 16))
+ break;
+ }
+ return irq_linear_revmap(socrates_fpga_pic_irq_host,
+ (irq_hw_number_t)i);
+}
+
+void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned int cascade_irq;
+
+ /*
+ * See if we actually have an interrupt, call generic handling code if
+ * we do.
+ */
+ cascade_irq = socrates_fpga_pic_get_irq(irq);
+
+ if (cascade_irq != NO_IRQ)
+ generic_handle_irq(cascade_irq);
+ desc->chip->eoi(irq);
+
+}
+
+static void socrates_fpga_pic_ack(unsigned int virq)
+{
+ unsigned long flags;
+ unsigned int hwirq, irq_line;
+ uint32_t mask;
+
+ hwirq = socrates_fpga_irq_to_hw(virq);
+
+ irq_line = fpga_irqs[hwirq].irq_line;
+ spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
+ & SOCRATES_FPGA_IRQ_MASK;
+ mask |= (1 << (hwirq + 16));
+ socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
+ spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+}
+
+static void socrates_fpga_pic_mask(unsigned int virq)
+{
+ unsigned long flags;
+ unsigned int hwirq;
+ int irq_line;
+ u32 mask;
+
+ hwirq = socrates_fpga_irq_to_hw(virq);
+
+ irq_line = fpga_irqs[hwirq].irq_line;
+ spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
+ & SOCRATES_FPGA_IRQ_MASK;
+ mask &= ~(1 << hwirq);
+ socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
+ spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+}
+
+static void socrates_fpga_pic_mask_ack(unsigned int virq)
+{
+ unsigned long flags;
+ unsigned int hwirq;
+ int irq_line;
+ u32 mask;
+
+ hwirq = socrates_fpga_irq_to_hw(virq);
+
+ irq_line = fpga_irqs[hwirq].irq_line;
+ spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
+ & SOCRATES_FPGA_IRQ_MASK;
+ mask &= ~(1 << hwirq);
+ mask |= (1 << (hwirq + 16));
+ socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
+ spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+}
+
+static void socrates_fpga_pic_unmask(unsigned int virq)
+{
+ unsigned long flags;
+ unsigned int hwirq;
+ int irq_line;
+ u32 mask;
+
+ hwirq = socrates_fpga_irq_to_hw(virq);
+
+ irq_line = fpga_irqs[hwirq].irq_line;
+ spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
+ & SOCRATES_FPGA_IRQ_MASK;
+ mask |= (1 << hwirq);
+ socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
+ spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+}
+
+static void socrates_fpga_pic_eoi(unsigned int virq)
+{
+ unsigned long flags;
+ unsigned int hwirq;
+ int irq_line;
+ u32 mask;
+
+ hwirq = socrates_fpga_irq_to_hw(virq);
+
+ irq_line = fpga_irqs[hwirq].irq_line;
+ spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
+ & SOCRATES_FPGA_IRQ_MASK;
+ mask |= (1 << (hwirq + 16));
+ socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
+ spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+}
+
+static int socrates_fpga_pic_set_type(unsigned int virq,
+ unsigned int flow_type)
+{
+ unsigned long flags;
+ unsigned int hwirq;
+ int polarity;
+ u32 mask;
+
+ hwirq = socrates_fpga_irq_to_hw(virq);
+
+ if (fpga_irqs[hwirq].type != IRQ_TYPE_NONE)
+ return -EINVAL;
+
+ switch (flow_type & IRQ_TYPE_SENSE_MASK) {
+ case IRQ_TYPE_LEVEL_HIGH:
+ polarity = 1;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ polarity = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ mask = socrates_fpga_pic_read(FPGA_PIC_IRQCFG);
+ if (polarity)
+ mask |= (1 << hwirq);
+ else
+ mask &= ~(1 << hwirq);
+ socrates_fpga_pic_write(FPGA_PIC_IRQCFG, mask);
+ spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+ return 0;
+}
+
+static struct irq_chip socrates_fpga_pic_chip = {
+ .typename = " FPGA-PIC ",
+ .ack = socrates_fpga_pic_ack,
+ .mask = socrates_fpga_pic_mask,
+ .mask_ack = socrates_fpga_pic_mask_ack,
+ .unmask = socrates_fpga_pic_unmask,
+ .eoi = socrates_fpga_pic_eoi,
+ .set_type = socrates_fpga_pic_set_type,
+};
+
+static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,
+ irq_hw_number_t hwirq)
+{
+ /* All interrupts are LEVEL sensitive */
+ get_irq_desc(virq)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(virq, &socrates_fpga_pic_chip,
+ handle_fasteoi_irq);
+
+ return 0;
+}
+
+static int socrates_fpga_pic_host_xlate(struct irq_host *h,
+ struct device_node *ct, u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq, unsigned int *out_flags)
+{
+ struct socrates_fpga_irq_info *fpga_irq = &fpga_irqs[intspec[0]];
+
+ *out_hwirq = intspec[0];
+ if (fpga_irq->type == IRQ_TYPE_NONE) {
+ /* type is configurable */
+ if (intspec[1] != IRQ_TYPE_LEVEL_LOW &&
+ intspec[1] != IRQ_TYPE_LEVEL_HIGH) {
+ pr_warning("FPGA PIC: invalid irq type, "
+ "setting default active low\n");
+ *out_flags = IRQ_TYPE_LEVEL_LOW;
+ } else {
+ *out_flags = intspec[1];
+ }
+ } else {
+ /* type is fixed */
+ *out_flags = fpga_irq->type;
+ }
+
+ /* Use specified interrupt routing */
+ if (intspec[2] <= 2)
+ fpga_irq->irq_line = intspec[2];
+ else
+ pr_warning("FPGA PIC: invalid irq routing\n");
+
+ return 0;
+}
+
+static struct irq_host_ops socrates_fpga_pic_host_ops = {
+ .map = socrates_fpga_pic_host_map,
+ .xlate = socrates_fpga_pic_host_xlate,
+};
+
+void socrates_fpga_pic_init(struct device_node *pic)
+{
+ unsigned long flags;
+ int i;
+
+ /* Setup an irq_host structure */
+ socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR,
+ SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops,
+ SOCRATES_FPGA_NUM_IRQS);
+ if (socrates_fpga_pic_irq_host == NULL) {
+ pr_err("FPGA PIC: Unable to allocate host\n");
+ return;
+ }
+
+ for (i = 0; i < 3; i++) {
+ socrates_fpga_irqs[i] = irq_of_parse_and_map(pic, i);
+ if (socrates_fpga_irqs[i] == NO_IRQ) {
+ pr_warning("FPGA PIC: can't get irq%d.\n", i);
+ continue;
+ }
+ set_irq_chained_handler(socrates_fpga_irqs[i],
+ socrates_fpga_pic_cascade);
+ }
+
+ socrates_fpga_pic_iobase = of_iomap(pic, 0);
+
+ spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
+ socrates_fpga_pic_write(FPGA_PIC_IRQMASK(0),
+ SOCRATES_FPGA_IRQ_MASK << 16);
+ socrates_fpga_pic_write(FPGA_PIC_IRQMASK(1),
+ SOCRATES_FPGA_IRQ_MASK << 16);
+ socrates_fpga_pic_write(FPGA_PIC_IRQMASK(2),
+ SOCRATES_FPGA_IRQ_MASK << 16);
+ spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
+
+ pr_info("FPGA PIC: Setting up Socrates FPGA PIC\n");
+}
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.h b/arch/powerpc/platforms/85xx/socrates_fpga_pic.h
new file mode 100644
index 000000000000..21d7d8e42199
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2008 Ilya Yanok, Emcraft Systems
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef SOCRATES_FPGA_PIC_H
+#define SOCRATES_FPGA_PIC_H
+
+void socrates_fpga_pic_init(struct device_node *pic);
+
+#endif
diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c
index 0cca8f5cb272..f559918f3c6f 100644
--- a/arch/powerpc/platforms/85xx/stx_gp3.c
+++ b/arch/powerpc/platforms/85xx/stx_gp3.c
@@ -145,6 +145,7 @@ static void stx_gp3_show_cpuinfo(struct seq_file *m)
static struct of_device_id __initdata of_bus_ids[] = {
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c
index 2933a8e827d9..5b0ab9966e90 100644
--- a/arch/powerpc/platforms/85xx/tqm85xx.c
+++ b/arch/powerpc/platforms/85xx/tqm85xx.c
@@ -153,6 +153,7 @@ static void tqm85xx_show_cpuinfo(struct seq_file *m)
static struct of_device_id __initdata of_bus_ids[] = {
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index 8e5693935975..fdaf4ddaa955 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -1,7 +1,7 @@
config PPC_86xx
menuconfig PPC_86xx
bool "86xx-based boards"
- depends on 6xx && PPC_MULTIPLATFORM
+ depends on 6xx
select FSL_SOC
select ALTIVEC
help
@@ -31,6 +31,22 @@ config MPC8610_HPCD
help
This option enables support for the MPC8610 HPCD board.
+config GEF_PPC9A
+ bool "GE Fanuc PPC9A"
+ select DEFAULT_UIMAGE
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ This option enables support for GE Fanuc's PPC9A.
+
+config GEF_SBC310
+ bool "GE Fanuc SBC310"
+ select DEFAULT_UIMAGE
+ select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ This option enables support for GE Fanuc's SBC310.
+
config GEF_SBC610
bool "GE Fanuc SBC610"
select DEFAULT_UIMAGE
@@ -48,7 +64,7 @@ config MPC8641
select FSL_PCI if PCI
select PPC_UDBG_16550
select MPIC
- default y if MPC8641_HPCN || SBC8641D || GEF_SBC610
+ default y if MPC8641_HPCN || SBC8641D || GEF_SBC610 || GEF_SBC310 || GEF_PPC9A
config MPC8610
bool
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile
index 31e540c2ebbc..4b0d7b1aa005 100644
--- a/arch/powerpc/platforms/86xx/Makefile
+++ b/arch/powerpc/platforms/86xx/Makefile
@@ -9,3 +9,5 @@ obj-$(CONFIG_SBC8641D) += sbc8641d.o
obj-$(CONFIG_MPC8610_HPCD) += mpc8610_hpcd.o
gef-gpio-$(CONFIG_GPIOLIB) += gef_gpio.o
obj-$(CONFIG_GEF_SBC610) += gef_sbc610.o gef_pic.o $(gef-gpio-y)
+obj-$(CONFIG_GEF_SBC310) += gef_sbc310.o gef_pic.o $(gef-gpio-y)
+obj-$(CONFIG_GEF_PPC9A) += gef_ppc9a.o gef_pic.o $(gef-gpio-y)
diff --git a/arch/powerpc/platforms/86xx/gef_gpio.c b/arch/powerpc/platforms/86xx/gef_gpio.c
index 85b2800f4cb7..b2ea8875adba 100644
--- a/arch/powerpc/platforms/86xx/gef_gpio.c
+++ b/arch/powerpc/platforms/86xx/gef_gpio.c
@@ -37,8 +37,6 @@
#define GEF_GPIO_OVERRUN 0x1C
#define GEF_GPIO_MODE 0x20
-#define NUM_GPIO 19
-
static void _gef_gpio_set(void __iomem *reg, unsigned int offset, int value)
{
unsigned int data;
@@ -103,10 +101,10 @@ static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
static int __init gef_gpio_init(void)
{
struct device_node *np;
+ int retval;
+ struct of_mm_gpio_chip *gef_gpio_chip;
for_each_compatible_node(np, NULL, "gef,sbc610-gpio") {
- int retval;
- struct of_mm_gpio_chip *gef_gpio_chip;
pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
@@ -120,7 +118,35 @@ static int __init gef_gpio_init(void)
/* Setup pointers to chip functions */
gef_gpio_chip->of_gc.gpio_cells = 2;
- gef_gpio_chip->of_gc.gc.ngpio = NUM_GPIO;
+ gef_gpio_chip->of_gc.gc.ngpio = 19;
+ gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in;
+ gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out;
+ gef_gpio_chip->of_gc.gc.get = gef_gpio_get;
+ gef_gpio_chip->of_gc.gc.set = gef_gpio_set;
+
+ /* This function adds a memory mapped GPIO chip */
+ retval = of_mm_gpiochip_add(np, gef_gpio_chip);
+ if (retval) {
+ kfree(gef_gpio_chip);
+ pr_err("%s: Unable to add GPIO\n", np->full_name);
+ }
+ }
+
+ for_each_compatible_node(np, NULL, "gef,sbc310-gpio") {
+
+ pr_debug("%s: Initialising GEF GPIO\n", np->full_name);
+
+ /* Allocate chip structure */
+ gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL);
+ if (!gef_gpio_chip) {
+ pr_err("%s: Unable to allocate structure\n",
+ np->full_name);
+ continue;
+ }
+
+ /* Setup pointers to chip functions */
+ gef_gpio_chip->of_gc.gpio_cells = 2;
+ gef_gpio_chip->of_gc.gc.ngpio = 6;
gef_gpio_chip->of_gc.gc.direction_input = gef_gpio_dir_in;
gef_gpio_chip->of_gc.gc.direction_output = gef_gpio_dir_out;
gef_gpio_chip->of_gc.gc.get = gef_gpio_get;
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c
new file mode 100644
index 000000000000..d79104669cdc
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c
@@ -0,0 +1,224 @@
+/*
+ * GE Fanuc PPC9A board support
+ *
+ * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ *
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Based on: mpc86xx_hpcn.c (MPC86xx HPCN board specific routines)
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * NEC fixup adapted from arch/mips/pci/fixup-lm2e.c
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/of_platform.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc86xx.h>
+#include <asm/prom.h>
+#include <mm/mmu_decl.h>
+#include <asm/udbg.h>
+
+#include <asm/mpic.h>
+
+#include <sysdev/fsl_pci.h>
+#include <sysdev/fsl_soc.h>
+
+#include "mpc86xx.h"
+#include "gef_pic.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG (fmt...) do { printk(KERN_ERR "PPC9A: " fmt); } while (0)
+#else
+#define DBG (fmt...) do { } while (0)
+#endif
+
+void __iomem *ppc9a_regs;
+
+static void __init gef_ppc9a_init_irq(void)
+{
+ struct device_node *cascade_node = NULL;
+
+ mpc86xx_init_irq();
+
+ /*
+ * There is a simple interrupt handler in the main FPGA, this needs
+ * to be cascaded into the MPIC
+ */
+ cascade_node = of_find_compatible_node(NULL, NULL, "gef,fpga-pic-1.00");
+ if (!cascade_node) {
+ printk(KERN_WARNING "PPC9A: No FPGA PIC\n");
+ return;
+ }
+
+ gef_pic_init(cascade_node);
+ of_node_put(cascade_node);
+}
+
+static void __init gef_ppc9a_setup_arch(void)
+{
+ struct device_node *regs;
+#ifdef CONFIG_PCI
+ struct device_node *np;
+
+ for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") {
+ fsl_add_bridge(np, 1);
+ }
+#endif
+
+ printk(KERN_INFO "GE Fanuc Intelligent Platforms PPC9A 6U VME SBC\n");
+
+#ifdef CONFIG_SMP
+ mpc86xx_smp_init();
+#endif
+
+ /* Remap basic board registers */
+ regs = of_find_compatible_node(NULL, NULL, "gef,ppc9a-fpga-regs");
+ if (regs) {
+ ppc9a_regs = of_iomap(regs, 0);
+ if (ppc9a_regs == NULL)
+ printk(KERN_WARNING "Unable to map board registers\n");
+ of_node_put(regs);
+ }
+}
+
+/* Return the PCB revision */
+static unsigned int gef_ppc9a_get_pcb_rev(void)
+{
+ unsigned int reg;
+
+ reg = ioread32(ppc9a_regs);
+ return (reg >> 8) & 0xff;
+}
+
+/* Return the board (software) revision */
+static unsigned int gef_ppc9a_get_board_rev(void)
+{
+ unsigned int reg;
+
+ reg = ioread32(ppc9a_regs);
+ return (reg >> 16) & 0xff;
+}
+
+/* Return the FPGA revision */
+static unsigned int gef_ppc9a_get_fpga_rev(void)
+{
+ unsigned int reg;
+
+ reg = ioread32(ppc9a_regs);
+ return (reg >> 24) & 0xf;
+}
+
+static void gef_ppc9a_show_cpuinfo(struct seq_file *m)
+{
+ uint svid = mfspr(SPRN_SVR);
+
+ seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+
+ seq_printf(m, "Revision\t: %u%c\n", gef_ppc9a_get_pcb_rev(),
+ ('A' + gef_ppc9a_get_board_rev() - 1));
+ seq_printf(m, "FPGA Revision\t: %u\n", gef_ppc9a_get_fpga_rev());
+
+ seq_printf(m, "SVR\t\t: 0x%x\n", svid);
+}
+
+static void __init gef_ppc9a_nec_fixup(struct pci_dev *pdev)
+{
+ unsigned int val;
+
+ /* Do not do the fixup on other platforms! */
+ if (!machine_is(gef_ppc9a))
+ return;
+
+ printk(KERN_INFO "Running NEC uPD720101 Fixup\n");
+
+ /* Ensure ports 1, 2, 3, 4 & 5 are enabled */
+ pci_read_config_dword(pdev, 0xe0, &val);
+ pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x5);
+
+ /* System clock is 48-MHz Oscillator and EHCI Enabled. */
+ pci_write_config_dword(pdev, 0xe4, 1 << 5);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+ gef_ppc9a_nec_fixup);
+
+/*
+ * Called very early, device-tree isn't unflattened
+ *
+ * This function is called to determine whether the BSP is compatible with the
+ * supplied device-tree, which is assumed to be the correct one for the actual
+ * board. It is expected thati, in the future, a kernel may support multiple
+ * boards.
+ */
+static int __init gef_ppc9a_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (of_flat_dt_is_compatible(root, "gef,ppc9a"))
+ return 1;
+
+ return 0;
+}
+
+static long __init mpc86xx_time_init(void)
+{
+ unsigned int temp;
+
+ /* Set the time base to zero */
+ mtspr(SPRN_TBWL, 0);
+ mtspr(SPRN_TBWU, 0);
+
+ temp = mfspr(SPRN_HID0);
+ temp |= HID0_TBEN;
+ mtspr(SPRN_HID0, temp);
+ asm volatile("isync");
+
+ return 0;
+}
+
+static __initdata struct of_device_id of_bus_ids[] = {
+ { .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
+ {},
+};
+
+static int __init declare_of_platform_devices(void)
+{
+ printk(KERN_DEBUG "Probe platform devices\n");
+ of_platform_bus_probe(NULL, of_bus_ids, NULL);
+
+ return 0;
+}
+machine_device_initcall(gef_ppc9a, declare_of_platform_devices);
+
+define_machine(gef_ppc9a) {
+ .name = "GE Fanuc PPC9A",
+ .probe = gef_ppc9a_probe,
+ .setup_arch = gef_ppc9a_setup_arch,
+ .init_IRQ = gef_ppc9a_init_irq,
+ .show_cpuinfo = gef_ppc9a_show_cpuinfo,
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .time_init = mpc86xx_time_init,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+};
diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c
new file mode 100644
index 000000000000..af14f852d747
--- /dev/null
+++ b/arch/powerpc/platforms/86xx/gef_sbc310.c
@@ -0,0 +1,235 @@
+/*
+ * GE Fanuc SBC310 board support
+ *
+ * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ *
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Based on: mpc86xx_hpcn.c (MPC86xx HPCN board specific routines)
+ * Copyright 2006 Freescale Semiconductor Inc.
+ *
+ * NEC fixup adapted from arch/mips/pci/fixup-lm2e.c
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/of_platform.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc86xx.h>
+#include <asm/prom.h>
+#include <mm/mmu_decl.h>
+#include <asm/udbg.h>
+
+#include <asm/mpic.h>
+
+#include <sysdev/fsl_pci.h>
+#include <sysdev/fsl_soc.h>
+
+#include "mpc86xx.h"
+#include "gef_pic.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG (fmt...) do { printk(KERN_ERR "SBC310: " fmt); } while (0)
+#else
+#define DBG (fmt...) do { } while (0)
+#endif
+
+void __iomem *sbc310_regs;
+
+static void __init gef_sbc310_init_irq(void)
+{
+ struct device_node *cascade_node = NULL;
+
+ mpc86xx_init_irq();
+
+ /*
+ * There is a simple interrupt handler in the main FPGA, this needs
+ * to be cascaded into the MPIC
+ */
+ cascade_node = of_find_compatible_node(NULL, NULL, "gef,fpga-pic");
+ if (!cascade_node) {
+ printk(KERN_WARNING "SBC310: No FPGA PIC\n");
+ return;
+ }
+
+ gef_pic_init(cascade_node);
+ of_node_put(cascade_node);
+}
+
+static void __init gef_sbc310_setup_arch(void)
+{
+ struct device_node *regs;
+#ifdef CONFIG_PCI
+ struct device_node *np;
+
+ for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") {
+ fsl_add_bridge(np, 1);
+ }
+#endif
+
+ printk(KERN_INFO "GE Fanuc Intelligent Platforms SBC310 6U VPX SBC\n");
+
+#ifdef CONFIG_SMP
+ mpc86xx_smp_init();
+#endif
+
+ /* Remap basic board registers */
+ regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs");
+ if (regs) {
+ sbc310_regs = of_iomap(regs, 0);
+ if (sbc310_regs == NULL)
+ printk(KERN_WARNING "Unable to map board registers\n");
+ of_node_put(regs);
+ }
+}
+
+/* Return the PCB revision */
+static unsigned int gef_sbc310_get_board_id(void)
+{
+ unsigned int reg;
+
+ reg = ioread32(sbc310_regs);
+ return reg & 0xff;
+}
+
+/* Return the PCB revision */
+static unsigned int gef_sbc310_get_pcb_rev(void)
+{
+ unsigned int reg;
+
+ reg = ioread32(sbc310_regs);
+ return (reg >> 8) & 0xff;
+}
+
+/* Return the board (software) revision */
+static unsigned int gef_sbc310_get_board_rev(void)
+{
+ unsigned int reg;
+
+ reg = ioread32(sbc310_regs);
+ return (reg >> 16) & 0xff;
+}
+
+/* Return the FPGA revision */
+static unsigned int gef_sbc310_get_fpga_rev(void)
+{
+ unsigned int reg;
+
+ reg = ioread32(sbc310_regs);
+ return (reg >> 24) & 0xf;
+}
+
+static void gef_sbc310_show_cpuinfo(struct seq_file *m)
+{
+ uint svid = mfspr(SPRN_SVR);
+
+ seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
+
+ seq_printf(m, "Board ID\t: 0x%2.2x\n", gef_sbc310_get_board_id());
+ seq_printf(m, "Revision\t: %u%c\n", gef_sbc310_get_pcb_rev(),
+ ('A' + gef_sbc310_get_board_rev() - 1));
+ seq_printf(m, "FPGA Revision\t: %u\n", gef_sbc310_get_fpga_rev());
+
+ seq_printf(m, "SVR\t\t: 0x%x\n", svid);
+
+}
+
+static void __init gef_sbc310_nec_fixup(struct pci_dev *pdev)
+{
+ unsigned int val;
+
+ /* Do not do the fixup on other platforms! */
+ if (!machine_is(gef_sbc310))
+ return;
+
+ printk(KERN_INFO "Running NEC uPD720101 Fixup\n");
+
+ /* Ensure only ports 1 & 2 are enabled */
+ pci_read_config_dword(pdev, 0xe0, &val);
+ pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x2);
+
+ /* System clock is 48-MHz Oscillator and EHCI Enabled. */
+ pci_write_config_dword(pdev, 0xe4, 1 << 5);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+ gef_sbc310_nec_fixup);
+
+/*
+ * Called very early, device-tree isn't unflattened
+ *
+ * This function is called to determine whether the BSP is compatible with the
+ * supplied device-tree, which is assumed to be the correct one for the actual
+ * board. It is expected thati, in the future, a kernel may support multiple
+ * boards.
+ */
+static int __init gef_sbc310_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (of_flat_dt_is_compatible(root, "gef,sbc310"))
+ return 1;
+
+ return 0;
+}
+
+static long __init mpc86xx_time_init(void)
+{
+ unsigned int temp;
+
+ /* Set the time base to zero */
+ mtspr(SPRN_TBWL, 0);
+ mtspr(SPRN_TBWU, 0);
+
+ temp = mfspr(SPRN_HID0);
+ temp |= HID0_TBEN;
+ mtspr(SPRN_HID0, temp);
+ asm volatile("isync");
+
+ return 0;
+}
+
+static __initdata struct of_device_id of_bus_ids[] = {
+ { .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
+ {},
+};
+
+static int __init declare_of_platform_devices(void)
+{
+ printk(KERN_DEBUG "Probe platform devices\n");
+ of_platform_bus_probe(NULL, of_bus_ids, NULL);
+
+ return 0;
+}
+machine_device_initcall(gef_sbc310, declare_of_platform_devices);
+
+define_machine(gef_sbc310) {
+ .name = "GE Fanuc SBC310",
+ .probe = gef_sbc310_probe,
+ .setup_arch = gef_sbc310_setup_arch,
+ .init_IRQ = gef_sbc310_init_irq,
+ .show_cpuinfo = gef_sbc310_show_cpuinfo,
+ .get_irq = mpic_get_irq,
+ .restart = fsl_rstcr_restart,
+ .time_init = mpc86xx_time_init,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+#ifdef CONFIG_PCI
+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
+#endif
+};
diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c
index d6b772ba3b8f..ea2360639652 100644
--- a/arch/powerpc/platforms/86xx/gef_sbc610.c
+++ b/arch/powerpc/platforms/86xx/gef_sbc610.c
@@ -194,6 +194,7 @@ static long __init mpc86xx_time_init(void)
static __initdata struct of_device_id of_bus_ids[] = {
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index e8d54ac5292c..3f49a6f893a3 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -46,6 +46,7 @@ static unsigned char *pixis_bdcfg0, *pixis_arch;
static struct of_device_id __initdata mpc8610_ids[] = {
{ .compatible = "fsl,mpc8610-immr", },
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{}
};
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 27e0e682d8e1..c4ec49b5f7f8 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -148,6 +148,7 @@ mpc86xx_time_init(void)
static __initdata struct of_device_id of_bus_ids[] = {
{ .compatible = "simple-bus", },
{ .compatible = "fsl,rapidio-delta", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c
index 5fd7ed40986f..2886a36fc085 100644
--- a/arch/powerpc/platforms/86xx/sbc8641d.c
+++ b/arch/powerpc/platforms/86xx/sbc8641d.c
@@ -103,6 +103,7 @@ mpc86xx_time_init(void)
static __initdata struct of_device_id of_bus_ids[] = {
{ .compatible = "simple-bus", },
+ { .compatible = "gianfar", },
{},
};
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index 0d9f75c74f8c..385acfc48397 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -44,7 +44,6 @@ static irqreturn_t timebase_interrupt(int irq, void *dev)
static struct irqaction tbint_irqaction = {
.handler = timebase_interrupt,
- .mask = CPU_MASK_NONE,
.name = "tbint",
};
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 200b9cb900ea..e3e87078d03f 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -1,14 +1,5 @@
menu "Platform support"
-config PPC_MULTIPLATFORM
- bool
- depends on PPC64 || 6xx
- default y
-
-config CLASSIC32
- def_bool y
- depends on 6xx && PPC_MULTIPLATFORM
-
source "arch/powerpc/platforms/pseries/Kconfig"
source "arch/powerpc/platforms/iseries/Kconfig"
source "arch/powerpc/platforms/chrp/Kconfig"
@@ -28,15 +19,28 @@ source "arch/powerpc/platforms/86xx/Kconfig"
source "arch/powerpc/platforms/embedded6xx/Kconfig"
source "arch/powerpc/platforms/44x/Kconfig"
source "arch/powerpc/platforms/40x/Kconfig"
+source "arch/powerpc/platforms/amigaone/Kconfig"
config PPC_NATIVE
bool
- depends on PPC_MULTIPLATFORM
+ depends on 6xx || PPC64
help
Support for running natively on the hardware, i.e. without
a hypervisor. This option is not user-selectable but should
be selected by all platforms that need it.
+config PPC_OF_BOOT_TRAMPOLINE
+ bool "Support booting from Open Firmware or yaboot"
+ depends on 6xx || PPC64
+ default y
+ help
+ Support from booting from Open Firmware or yaboot using an
+ Open Firmware client interface. This enables the kernel to
+ communicate with open firmware to retrieve system informations
+ such as the device tree.
+
+ In case of doubt, say Y
+
config UDBG_RTAS_CONSOLE
bool "RTAS based debug console"
depends on PPC_RTAS
@@ -70,7 +74,7 @@ config PPC_I8259
config U3_DART
bool
- depends on PPC_MULTIPLATFORM && PPC64
+ depends on PPC64
default n
config PPC_RTAS
@@ -91,15 +95,6 @@ config RTAS_FLASH
tristate "Firmware flash interface"
depends on PPC64 && RTAS_PROC
-config PPC_PMI
- tristate "Support for PMI"
- depends on PPC_IBM_CELL_BLADE
- help
- PMI (Platform Management Interrupt) is a way to
- communicate with the BMC (Baseboard Management Controller).
- It is used in some IBM Cell blades.
- default m
-
config MMIO_NVRAM
bool
default n
@@ -196,7 +191,7 @@ config PPC601_SYNC_FIX
config TAU
bool "On-chip CPU temperature sensor support"
- depends on CLASSIC32
+ depends on 6xx
help
G3 and G4 processors have an on-chip temperature sensor called the
'Thermal Assist Unit (TAU)', which, in theory, can measure the on-die
@@ -274,7 +269,7 @@ config CPM2
config AXON_RAM
tristate "Axon DDR2 memory device driver"
- depends on PPC_IBM_CELL_BLADE
+ depends on PPC_IBM_CELL_BLADE && BLOCK
default m
help
It registers one block device per Axon's DDR2 memory bank found
@@ -298,7 +293,7 @@ config CPM
config OF_RTC
bool
help
- Uses information from the OF or flattened device tree to instatiate
+ Uses information from the OF or flattened device tree to instantiate
platform devices for direct mapped RTC chips like the DS1742 or DS1743.
source "arch/powerpc/sysdev/bestcomm/Kconfig"
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index e868b5c50723..9da795e49337 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -57,9 +57,17 @@ config E200
endchoice
+# Until we have a choice of exclusive CPU types on 64-bit, we always
+# use PPC_BOOK3S. On 32-bit, this is equivalent to 6xx which is
+# "classic" MMU
+
+config PPC_BOOK3S
+ def_bool y
+ depends on PPC64 || 6xx
+
config POWER4_ONLY
bool "Optimize for POWER4"
- depends on PPC64
+ depends on PPC64 && PPC_BOOK3S
default n
---help---
Cause the compiler to optimize for POWER4/POWER5/PPC970 processors.
@@ -68,16 +76,16 @@ config POWER4_ONLY
config POWER3
bool
- depends on PPC64
+ depends on PPC64 && PPC_BOOK3S
default y if !POWER4_ONLY
config POWER4
- depends on PPC64
+ depends on PPC64 && PPC_BOOK3S
def_bool y
config TUNE_CELL
bool "Optimize for Cell Broadband Engine"
- depends on PPC64
+ depends on PPC64 && PPC_BOOK3S
help
Cause the compiler to optimize for the PPE of the Cell Broadband
Engine. This will make the code run considerably faster on Cell
@@ -147,7 +155,7 @@ config PHYS_64BIT
config ALTIVEC
bool "AltiVec Support"
- depends on CLASSIC32 || POWER4
+ depends on 6xx || POWER4
---help---
This option enables kernel support for the Altivec extensions to the
PowerPC processor. The kernel currently supports saving and restoring
@@ -210,6 +218,10 @@ config PPC_MMU_NOHASH
def_bool y
depends on !PPC_STD_MMU
+config PPC_BOOK3E_MMU
+ def_bool y
+ depends on FSL_BOOKE
+
config PPC_MM_SLICES
bool
default y if HUGETLB_PAGE || (PPC_STD_MMU_64 && PPC_64K_PAGES)
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 8079e0b4fd69..f7419198e635 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -19,3 +19,4 @@ obj-$(CONFIG_PPC_PASEMI) += pasemi/
obj-$(CONFIG_PPC_CELL) += cell/
obj-$(CONFIG_PPC_PS3) += ps3/
obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
+obj-$(CONFIG_AMIGAONE) += amigaone/
diff --git a/arch/powerpc/platforms/amigaone/Kconfig b/arch/powerpc/platforms/amigaone/Kconfig
new file mode 100644
index 000000000000..022476717718
--- /dev/null
+++ b/arch/powerpc/platforms/amigaone/Kconfig
@@ -0,0 +1,18 @@
+config AMIGAONE
+ bool "Eyetech AmigaOne/MAI Teron"
+ depends on 6xx && BROKEN_ON_SMP
+ select PPC_I8259
+ select PPC_INDIRECT_PCI
+ select PPC_UDBG_16550
+ select PCI
+ select NOT_COHERENT_CACHE
+ select CHECK_CACHE_COHERENCY
+ select DEFAULT_UIMAGE
+ select PCSPKR_PLATFORM
+ help
+ Select AmigaOne for the following machines:
+ - AmigaOne SE/Teron CX (G3 only)
+ - AmigaOne XE/Teron PX
+ - uA1/Teron mini
+ More information is available at:
+ <http://amigaone-linux.sourceforge.net/>.
diff --git a/arch/powerpc/platforms/amigaone/Makefile b/arch/powerpc/platforms/amigaone/Makefile
new file mode 100644
index 000000000000..e6885b3b2ee7
--- /dev/null
+++ b/arch/powerpc/platforms/amigaone/Makefile
@@ -0,0 +1 @@
+obj-y += setup.o
diff --git a/arch/powerpc/platforms/amigaone/setup.c b/arch/powerpc/platforms/amigaone/setup.c
new file mode 100644
index 000000000000..443035366c12
--- /dev/null
+++ b/arch/powerpc/platforms/amigaone/setup.c
@@ -0,0 +1,170 @@
+/*
+ * AmigaOne platform setup
+ *
+ * Copyright 2008 Gerhard Pircher (gerhard_pircher@gmx.net)
+ *
+ * Based on original amigaone_setup.c source code
+ * Copyright 2003 by Hans-Joerg Frieden and Thomas Frieden
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/seq_file.h>
+#include <linux/utsrelease.h>
+
+#include <asm/machdep.h>
+#include <asm/cputable.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/i8259.h>
+#include <asm/time.h>
+#include <asm/udbg.h>
+
+extern void __flush_disable_L1(void);
+
+void amigaone_show_cpuinfo(struct seq_file *m)
+{
+ seq_printf(m, "vendor\t\t: Eyetech Ltd.\n");
+}
+
+static int __init amigaone_add_bridge(struct device_node *dev)
+{
+ const u32 *cfg_addr, *cfg_data;
+ int len;
+ const int *bus_range;
+ struct pci_controller *hose;
+
+ printk(KERN_INFO "Adding PCI host bridge %s\n", dev->full_name);
+
+ cfg_addr = of_get_address(dev, 0, NULL, NULL);
+ cfg_data = of_get_address(dev, 1, NULL, NULL);
+ if ((cfg_addr == NULL) || (cfg_data == NULL))
+ return -ENODEV;
+
+ bus_range = of_get_property(dev, "bus-range", &len);
+ if ((bus_range == NULL) || (len < 2 * sizeof(int)))
+ printk(KERN_WARNING "Can't get bus-range for %s, assume"
+ " bus 0\n", dev->full_name);
+
+ hose = pcibios_alloc_controller(dev);
+ if (hose == NULL)
+ return -ENOMEM;
+
+ hose->first_busno = bus_range ? bus_range[0] : 0;
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+ setup_indirect_pci(hose, cfg_addr[0], cfg_data[0], 0);
+
+ /* Interpret the "ranges" property */
+ /* This also maps the I/O region and sets isa_io/mem_base */
+ pci_process_bridge_OF_ranges(hose, dev, 1);
+
+ return 0;
+}
+
+void __init amigaone_setup_arch(void)
+{
+ struct device_node *np;
+ int phb = -ENODEV;
+
+ /* Lookup PCI host bridges. */
+ for_each_compatible_node(np, "pci", "mai-logic,articia-s")
+ phb = amigaone_add_bridge(np);
+
+ BUG_ON(phb != 0);
+
+ if (ppc_md.progress)
+ ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0);
+}
+
+void __init amigaone_init_IRQ(void)
+{
+ struct device_node *pic, *np = NULL;
+ const unsigned long *prop = NULL;
+ unsigned long int_ack = 0;
+
+ /* Search for ISA interrupt controller. */
+ pic = of_find_compatible_node(NULL, "interrupt-controller",
+ "pnpPNP,000");
+ BUG_ON(pic == NULL);
+
+ /* Look for interrupt acknowledge address in the PCI root node. */
+ np = of_find_compatible_node(NULL, "pci", "mai-logic,articia-s");
+ if (np) {
+ prop = of_get_property(np, "8259-interrupt-acknowledge", NULL);
+ if (prop)
+ int_ack = prop[0];
+ of_node_put(np);
+ }
+
+ if (int_ack == 0)
+ printk(KERN_WARNING "Cannot find PCI interrupt acknowledge"
+ " address, polling\n");
+
+ i8259_init(pic, int_ack);
+ ppc_md.get_irq = i8259_irq;
+ irq_set_default_host(i8259_get_host());
+}
+
+void __init amigaone_init(void)
+{
+ request_region(0x00, 0x20, "dma1");
+ request_region(0x40, 0x20, "timer");
+ request_region(0x80, 0x10, "dma page reg");
+ request_region(0xc0, 0x20, "dma2");
+}
+
+void amigaone_restart(char *cmd)
+{
+ local_irq_disable();
+
+ /* Flush and disable caches. */
+ __flush_disable_L1();
+
+ /* Set SRR0 to the reset vector and turn on MSR_IP. */
+ mtspr(SPRN_SRR0, 0xfff00100);
+ mtspr(SPRN_SRR1, MSR_IP);
+
+ /* Do an rfi to jump back to firmware. */
+ __asm__ __volatile__("rfi" : : : "memory");
+
+ /* Not reached. */
+ while (1);
+}
+
+static int __init amigaone_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (of_flat_dt_is_compatible(root, "eyetech,amigaone")) {
+ /*
+ * Coherent memory access cause complete system lockup! Thus
+ * disable this CPU feature, even if the CPU needs it.
+ */
+ cur_cpu_spec->cpu_features &= ~CPU_FTR_NEED_COHERENT;
+
+ ISA_DMA_THRESHOLD = 0x00ffffff;
+ DMA_MODE_READ = 0x44;
+ DMA_MODE_WRITE = 0x48;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+define_machine(amigaone) {
+ .name = "AmigaOne",
+ .probe = amigaone_probe,
+ .setup_arch = amigaone_setup_arch,
+ .init = amigaone_init,
+ .show_cpuinfo = amigaone_show_cpuinfo,
+ .init_IRQ = amigaone_init_IRQ,
+ .restart = amigaone_restart,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index 5cc3279559a4..40e24c39ad06 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -23,7 +23,7 @@ config PPC_CELL_NATIVE
config PPC_IBM_CELL_BLADE
bool "IBM Cell Blade"
- depends on PPC_MULTIPLATFORM && PPC64
+ depends on PPC64 && PPC_BOOK3S
select PPC_CELL_NATIVE
select MMIO_NVRAM
select PPC_UDBG_16550
@@ -31,7 +31,7 @@ config PPC_IBM_CELL_BLADE
config PPC_CELLEB
bool "Toshiba's Cell Reference Set 'Celleb' Architecture"
- depends on PPC_MULTIPLATFORM && PPC64
+ depends on PPC64 && PPC_BOOK3S
select PPC_CELL_NATIVE
select HAS_TXX9_SERIAL
select PPC_UDBG_BEAT
@@ -40,9 +40,14 @@ config PPC_CELLEB
config PPC_CELL_QPACE
bool "IBM Cell - QPACE"
- depends on PPC_MULTIPLATFORM && PPC64
+ depends on PPC64 && PPC_BOOK3S
select PPC_CELL_COMMON
+config AXON_MSI
+ bool
+ depends on PPC_IBM_CELL_BLADE && PCI_MSI
+ default y
+
menu "Cell Broadband Engine options"
depends on PPC_CELL
@@ -98,7 +103,7 @@ config PPC_IBM_CELL_RESETBUTTON
config PPC_IBM_CELL_POWERBUTTON
tristate "IBM Cell Blade power button"
- depends on PPC_IBM_CELL_BLADE && PPC_PMI && INPUT_EVDEV
+ depends on PPC_IBM_CELL_BLADE && INPUT_EVDEV
default y
help
Support Powerbutton on IBM Cell blades.
@@ -118,9 +123,9 @@ config CBE_CPUFREQ
For details, take a look at <file:Documentation/cpu-freq/>.
If you don't have such processor, say N
-config CBE_CPUFREQ_PMI
- tristate "CBE frequency scaling using PMI interface"
- depends on CBE_CPUFREQ && PPC_PMI && EXPERIMENTAL
+config CBE_CPUFREQ_PMI_ENABLE
+ bool "CBE frequency scaling using PMI interface"
+ depends on CBE_CPUFREQ && EXPERIMENTAL
default n
help
Select this, if you want to use the PMI interface
@@ -128,6 +133,20 @@ config CBE_CPUFREQ_PMI
processor will not only be able to run at lower speed,
but also at lower core voltage.
+config CBE_CPUFREQ_PMI
+ tristate
+ depends on CBE_CPUFREQ_PMI_ENABLE
+ default CBE_CPUFREQ
+
+config PPC_PMI
+ tristate
+ default y
+ depends on CBE_CPUFREQ_PMI || PPC_IBM_CELL_POWERBUTTON
+ help
+ PMI (Platform Management Interrupt) is a way to
+ communicate with the BMC (Baseboard Management Controller).
+ It is used in some IBM Cell blades.
+
config CBE_CPUFREQ_SPU_GOVERNOR
tristate "CBE frequency scaling based on SPU usage"
depends on SPU_FS && CPU_FREQ
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index 43eccb270301..83fafe922641 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -28,7 +28,7 @@ obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \
$(spu-manage-y) \
spufs/
-obj-$(CONFIG_PCI_MSI) += axon_msi.o
+obj-$(CONFIG_AXON_MSI) += axon_msi.o
# qpace setup
obj-$(CONFIG_PPC_CELL_QPACE) += qpace_setup.o
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 28c04dab2633..882e47080e74 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -237,8 +237,6 @@ extern int noirqdebug;
static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
{
- const unsigned int cpu = smp_processor_id();
-
spin_lock(&desc->lock);
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
@@ -254,7 +252,7 @@ static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
goto out_eoi;
}
- kstat_cpu(cpu).irqs[irq]++;
+ kstat_incr_irqs_this_cpu(irq, desc);
/* Mark the IRQ currently in progress.*/
desc->status |= IRQ_INPROGRESS;
diff --git a/arch/powerpc/platforms/cell/io-workarounds.c b/arch/powerpc/platforms/cell/io-workarounds.c
index 059cad6c3f69..5c1118e31940 100644
--- a/arch/powerpc/platforms/cell/io-workarounds.c
+++ b/arch/powerpc/platforms/cell/io-workarounds.c
@@ -131,10 +131,10 @@ static const struct ppc_pci_io __devinitconst iowa_pci_io = {
};
static void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size,
- unsigned long flags)
+ unsigned long flags, void *caller)
{
struct iowa_bus *bus;
- void __iomem *res = __ioremap(addr, size, flags);
+ void __iomem *res = __ioremap_caller(addr, size, flags, caller);
int busno;
bus = iowa_pci_find(0, (unsigned long)addr);
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index ee5033eddf01..5744527a7f2a 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -74,7 +74,7 @@
#define IOC_IO_ExcpStat_V 0x8000000000000000ul
#define IOC_IO_ExcpStat_SPF_Mask 0x6000000000000000ul
#define IOC_IO_ExcpStat_SPF_S 0x6000000000000000ul
-#define IOC_IO_ExcpStat_SPF_P 0x4000000000000000ul
+#define IOC_IO_ExcpStat_SPF_P 0x2000000000000000ul
#define IOC_IO_ExcpStat_ADDR_Mask 0x00000007fffff000ul
#define IOC_IO_ExcpStat_RW_Mask 0x0000000000000800ul
#define IOC_IO_ExcpStat_IOID_Mask 0x00000000000007fful
@@ -247,17 +247,18 @@ static void tce_free_cell(struct iommu_table *tbl, long index, long npages)
static irqreturn_t ioc_interrupt(int irq, void *data)
{
- unsigned long stat;
+ unsigned long stat, spf;
struct cbe_iommu *iommu = data;
stat = in_be64(iommu->xlate_regs + IOC_IO_ExcpStat);
+ spf = stat & IOC_IO_ExcpStat_SPF_Mask;
/* Might want to rate limit it */
printk(KERN_ERR "iommu: DMA exception 0x%016lx\n", stat);
printk(KERN_ERR " V=%d, SPF=[%c%c], RW=%s, IOID=0x%04x\n",
!!(stat & IOC_IO_ExcpStat_V),
- (stat & IOC_IO_ExcpStat_SPF_S) ? 'S' : ' ',
- (stat & IOC_IO_ExcpStat_SPF_P) ? 'P' : ' ',
+ (spf == IOC_IO_ExcpStat_SPF_S) ? 'S' : ' ',
+ (spf == IOC_IO_ExcpStat_SPF_P) ? 'P' : ' ',
(stat & IOC_IO_ExcpStat_RW_Mask) ? "Read" : "Write",
(unsigned int)(stat & IOC_IO_ExcpStat_IOID_Mask));
printk(KERN_ERR " page=0x%016lx\n",
diff --git a/arch/powerpc/platforms/cell/qpace_setup.c b/arch/powerpc/platforms/cell/qpace_setup.c
index be84e6a16b30..c5ce02e84c8e 100644
--- a/arch/powerpc/platforms/cell/qpace_setup.c
+++ b/arch/powerpc/platforms/cell/qpace_setup.c
@@ -81,16 +81,6 @@ static int __init qpace_publish_devices(void)
}
machine_subsys_initcall(qpace, qpace_publish_devices);
-extern int qpace_notify(struct device *dev)
-{
- /* set dma_ops for of_platform bus */
- if (dev->bus && dev->bus->name
- && !strcmp(dev->bus->name, "of_platform"))
- set_dma_ops(dev, &dma_direct_ops);
-
- return 0;
-}
-
static void __init qpace_setup_arch(void)
{
#ifdef CONFIG_SPU_BASE
@@ -115,9 +105,6 @@ static void __init qpace_setup_arch(void)
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
#endif
-
- /* set notifier function */
- platform_notify = &qpace_notify;
}
static int __init qpace_probe(void)
@@ -141,6 +128,8 @@ define_machine(qpace) {
.power_off = rtas_power_off,
.halt = rtas_halt,
.get_boot_time = rtas_get_boot_time,
+ .get_rtc_time = rtas_get_rtc_time,
+ .set_rtc_time = rtas_set_rtc_time,
.calibrate_decr = generic_calibrate_decr,
.progress = qpace_progress,
.init_IRQ = iic_init_IRQ,
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index e487ad68ac11..9abd210d87c1 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -114,7 +114,7 @@ static inline void mm_needs_global_tlbie(struct mm_struct *mm)
int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1;
/* Global TLBIE broadcast required with SPEs. */
- __cpus_setall(&mm->cpu_vm_mask, nr);
+ bitmap_fill(cpumask_bits(mm_cpumask(mm)), nr);
}
void spu_associate_mm(struct spu *spu, struct mm_struct *mm)
diff --git a/arch/powerpc/platforms/cell/spu_fault.c b/arch/powerpc/platforms/cell/spu_fault.c
index c8b1cd42905d..95d8dadf2d87 100644
--- a/arch/powerpc/platforms/cell/spu_fault.c
+++ b/arch/powerpc/platforms/cell/spu_fault.c
@@ -39,60 +39,56 @@ int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
unsigned long is_write;
int ret;
-#if 0
- if (!IS_VALID_EA(ea)) {
+ if (mm == NULL)
return -EFAULT;
- }
-#endif /* XXX */
- if (mm == NULL) {
- return -EFAULT;
- }
- if (mm->pgd == NULL) {
+
+ if (mm->pgd == NULL)
return -EFAULT;
- }
down_read(&mm->mmap_sem);
+ ret = -EFAULT;
vma = find_vma(mm, ea);
if (!vma)
- goto bad_area;
- if (vma->vm_start <= ea)
- goto good_area;
- if (!(vma->vm_flags & VM_GROWSDOWN))
- goto bad_area;
- if (expand_stack(vma, ea))
- goto bad_area;
-good_area:
+ goto out_unlock;
+
+ if (ea < vma->vm_start) {
+ if (!(vma->vm_flags & VM_GROWSDOWN))
+ goto out_unlock;
+ if (expand_stack(vma, ea))
+ goto out_unlock;
+ }
+
is_write = dsisr & MFC_DSISR_ACCESS_PUT;
if (is_write) {
if (!(vma->vm_flags & VM_WRITE))
- goto bad_area;
+ goto out_unlock;
} else {
if (dsisr & MFC_DSISR_ACCESS_DENIED)
- goto bad_area;
+ goto out_unlock;
if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
- goto bad_area;
+ goto out_unlock;
}
+
ret = 0;
*flt = handle_mm_fault(mm, vma, ea, is_write);
if (unlikely(*flt & VM_FAULT_ERROR)) {
if (*flt & VM_FAULT_OOM) {
ret = -ENOMEM;
- goto bad_area;
+ goto out_unlock;
} else if (*flt & VM_FAULT_SIGBUS) {
ret = -EFAULT;
- goto bad_area;
+ goto out_unlock;
}
BUG();
}
+
if (*flt & VM_FAULT_MAJOR)
current->maj_flt++;
else
current->min_flt++;
- up_read(&mm->mmap_sem);
- return ret;
-bad_area:
+out_unlock:
up_read(&mm->mmap_sem);
- return -EFAULT;
+ return ret;
}
EXPORT_SYMBOL_GPL(spu_handle_mm_fault);
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 6653ddbed048..db5398c0339f 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -35,6 +35,8 @@ atomic_t nr_spu_contexts = ATOMIC_INIT(0);
struct spu_context *alloc_spu_context(struct spu_gang *gang)
{
struct spu_context *ctx;
+ struct timespec ts;
+
ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
if (!ctx)
goto out;
@@ -64,6 +66,8 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang)
__spu_update_sched_info(ctx);
spu_set_timeslice(ctx);
ctx->stats.util_state = SPU_UTIL_IDLE_LOADED;
+ ktime_get_ts(&ts);
+ ctx->stats.tstamp = timespec_to_ns(&ts);
atomic_inc(&nr_spu_contexts);
goto out;
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 0da7f2bf5ee1..d6a519e6e1c1 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -568,16 +568,17 @@ spufs_regs_write(struct file *file, const char __user *buffer,
struct spu_lscsa *lscsa = ctx->csa.lscsa;
int ret;
- size = min_t(ssize_t, sizeof lscsa->gprs - *pos, size);
- if (size <= 0)
+ if (*pos >= sizeof(lscsa->gprs))
return -EFBIG;
+
+ size = min_t(ssize_t, sizeof(lscsa->gprs) - *pos, size);
*pos += size;
ret = spu_acquire_saved(ctx);
if (ret)
return ret;
- ret = copy_from_user(lscsa->gprs + *pos - size,
+ ret = copy_from_user((char *)lscsa->gprs + *pos - size,
buffer, size) ? -EFAULT : size;
spu_release_saved(ctx);
@@ -623,10 +624,11 @@ spufs_fpcr_write(struct file *file, const char __user * buffer,
struct spu_lscsa *lscsa = ctx->csa.lscsa;
int ret;
- size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
- if (size <= 0)
+ if (*pos >= sizeof(lscsa->fpcr))
return -EFBIG;
+ size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
+
ret = spu_acquire_saved(ctx);
if (ret)
return ret;
@@ -2665,7 +2667,7 @@ static const struct file_operations spufs_ctx_fops = {
.release = single_release,
};
-struct spufs_tree_descr spufs_dir_contents[] = {
+const struct spufs_tree_descr spufs_dir_contents[] = {
{ "capabilities", &spufs_caps_fops, 0444, },
{ "mem", &spufs_mem_fops, 0666, LS_SIZE, },
{ "regs", &spufs_regs_fops, 0666, sizeof(struct spu_reg128[128]), },
@@ -2706,7 +2708,7 @@ struct spufs_tree_descr spufs_dir_contents[] = {
{},
};
-struct spufs_tree_descr spufs_dir_nosched_contents[] = {
+const struct spufs_tree_descr spufs_dir_nosched_contents[] = {
{ "capabilities", &spufs_caps_fops, 0444, },
{ "mem", &spufs_mem_fops, 0666, LS_SIZE, },
{ "mbox", &spufs_mbox_fops, 0444, },
@@ -2731,12 +2733,12 @@ struct spufs_tree_descr spufs_dir_nosched_contents[] = {
{},
};
-struct spufs_tree_descr spufs_dir_debug_contents[] = {
+const struct spufs_tree_descr spufs_dir_debug_contents[] = {
{ ".ctx", &spufs_ctx_fops, 0444, },
{},
};
-struct spufs_coredump_reader spufs_coredump_read[] = {
+const struct spufs_coredump_reader spufs_coredump_read[] = {
{ "regs", __spufs_regs_read, NULL, sizeof(struct spu_reg128[128])},
{ "fpcr", __spufs_fpcr_read, NULL, sizeof(struct spu_reg128) },
{ "lslr", NULL, spufs_lslr_get, 19 },
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index e309ef70a531..706eb5c7e2ee 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -186,8 +186,9 @@ static int spufs_rmdir(struct inode *parent, struct dentry *dir)
return simple_rmdir(parent, dir);
}
-static int spufs_fill_dir(struct dentry *dir, struct spufs_tree_descr *files,
- int mode, struct spu_context *ctx)
+static int spufs_fill_dir(struct dentry *dir,
+ const struct spufs_tree_descr *files, int mode,
+ struct spu_context *ctx)
{
struct dentry *dentry, *tmp;
int ret;
@@ -634,7 +635,7 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode,
if (dentry->d_inode)
goto out_dput;
- mode &= ~current->fs->umask;
+ mode &= ~current_umask();
if (flags & SPU_CREATE_GANG)
ret = spufs_create_gang(nd->path.dentry->d_inode,
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index c58bd36b0c5b..4ddf769a64e5 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -117,6 +117,9 @@ static int spu_setup_isolated(struct spu_context *ctx)
cond_resched();
}
+ /* clear purge status */
+ out_be64(mfc_cntl, 0);
+
/* put the SPE in kernel mode to allow access to the loader */
sr1 = spu_mfc_sr1_get(ctx->spu);
sr1 &= ~MFC_STATE1_PROBLEM_STATE_MASK;
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 6a0ad196aeb3..f085369301b1 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -508,7 +508,7 @@ static void __spu_add_to_rq(struct spu_context *ctx)
list_add_tail(&ctx->rq, &spu_prio->runq[ctx->prio]);
set_bit(ctx->prio, spu_prio->bitmap);
if (!spu_prio->nr_waiting++)
- __mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK);
+ mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK);
}
}
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 3bf908e2873a..ae31573bea4a 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -241,9 +241,9 @@ struct spufs_tree_descr {
size_t size;
};
-extern struct spufs_tree_descr spufs_dir_contents[];
-extern struct spufs_tree_descr spufs_dir_nosched_contents[];
-extern struct spufs_tree_descr spufs_dir_debug_contents[];
+extern const struct spufs_tree_descr spufs_dir_contents[];
+extern const struct spufs_tree_descr spufs_dir_nosched_contents[];
+extern const struct spufs_tree_descr spufs_dir_debug_contents[];
/* system call implementation */
extern struct spufs_calls spufs_calls;
@@ -358,7 +358,7 @@ struct spufs_coredump_reader {
u64 (*get)(struct spu_context *ctx);
size_t size;
};
-extern struct spufs_coredump_reader spufs_coredump_read[];
+extern const struct spufs_coredump_reader spufs_coredump_read[];
extern int spufs_coredump_num_notes;
extern int spu_init_csa(struct spu_state *csa);
diff --git a/arch/powerpc/platforms/chrp/Kconfig b/arch/powerpc/platforms/chrp/Kconfig
index 22b4b4e3b6f0..37d438bd5b7a 100644
--- a/arch/powerpc/platforms/chrp/Kconfig
+++ b/arch/powerpc/platforms/chrp/Kconfig
@@ -1,6 +1,6 @@
config PPC_CHRP
bool "Common Hardware Reference Platform (CHRP) based machines"
- depends on PPC_MULTIPLATFORM && PPC32
+ depends on 6xx
select MPIC
select PPC_I8259
select PPC_INDIRECT_PCI
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
index 130ff72d99dd..039fc8e82199 100644
--- a/arch/powerpc/platforms/chrp/pegasos_eth.c
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -21,8 +21,8 @@
#define PEGASOS2_SRAM_BASE (0xf2000000)
#define PEGASOS2_SRAM_SIZE (256*1024)
-#define PEGASOS2_SRAM_BASE_ETH0 (PEGASOS2_SRAM_BASE)
-#define PEGASOS2_SRAM_BASE_ETH1 (PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) )
+#define PEGASOS2_SRAM_BASE_ETH_PORT0 (PEGASOS2_SRAM_BASE)
+#define PEGASOS2_SRAM_BASE_ETH_PORT1 (PEGASOS2_SRAM_BASE_ETH_PORT0 + (PEGASOS2_SRAM_SIZE / 2) )
#define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4)
@@ -47,75 +47,42 @@ static struct platform_device mv643xx_eth_shared_device = {
.resource = mv643xx_eth_shared_resources,
};
-static struct resource mv643xx_eth0_resources[] = {
+static struct resource mv643xx_eth_port1_resources[] = {
[0] = {
- .name = "eth0 irq",
+ .name = "eth port1 irq",
.start = 9,
.end = 9,
.flags = IORESOURCE_IRQ,
},
};
-
-static struct mv643xx_eth_platform_data eth0_pd = {
- .shared = &mv643xx_eth_shared_device,
- .port_number = 0,
-
- .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
- .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
- .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
-
- .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE,
- .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
- .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
-};
-
-static struct platform_device eth0_device = {
- .name = MV643XX_ETH_NAME,
- .id = 0,
- .num_resources = ARRAY_SIZE(mv643xx_eth0_resources),
- .resource = mv643xx_eth0_resources,
- .dev = {
- .platform_data = &eth0_pd,
- },
-};
-
-static struct resource mv643xx_eth1_resources[] = {
- [0] = {
- .name = "eth1 irq",
- .start = 9,
- .end = 9,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct mv643xx_eth_platform_data eth1_pd = {
+static struct mv643xx_eth_platform_data eth_port1_pd = {
.shared = &mv643xx_eth_shared_device,
.port_number = 1,
+ .phy_addr = MV643XX_ETH_PHY_ADDR(7),
- .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
+ .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH_PORT1,
.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
- .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE,
+ .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH_PORT1 + PEGASOS2_SRAM_TXRING_SIZE,
.rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
.rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
};
-static struct platform_device eth1_device = {
+static struct platform_device eth_port1_device = {
.name = MV643XX_ETH_NAME,
.id = 1,
- .num_resources = ARRAY_SIZE(mv643xx_eth1_resources),
- .resource = mv643xx_eth1_resources,
+ .num_resources = ARRAY_SIZE(mv643xx_eth_port1_resources),
+ .resource = mv643xx_eth_port1_resources,
.dev = {
- .platform_data = &eth1_pd,
+ .platform_data = &eth_port1_pd,
},
};
static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
&mv643xx_eth_shared_device,
- &eth0_device,
- &eth1_device,
+ &eth_port1_device,
};
/***********/
@@ -191,15 +158,10 @@ static int __init mv643xx_eth_add_pds(void)
if ( Enable_SRAM() < 0)
{
- eth0_pd.tx_sram_addr = 0;
- eth0_pd.tx_sram_size = 0;
- eth0_pd.rx_sram_addr = 0;
- eth0_pd.rx_sram_size = 0;
-
- eth1_pd.tx_sram_addr = 0;
- eth1_pd.tx_sram_size = 0;
- eth1_pd.rx_sram_addr = 0;
- eth1_pd.rx_sram_size = 0;
+ eth_port1_pd.tx_sram_addr = 0;
+ eth_port1_pd.tx_sram_size = 0;
+ eth_port1_pd.rx_sram_addr = 0;
+ eth_port1_pd.rx_sram_size = 0;
#ifdef BE_VERBOSE
printk("Pegasos II/Marvell MV64361: Can't enable the "
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 272d79a8d289..cd4ad9aea760 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -472,7 +472,6 @@ static void __init chrp_find_openpic(void)
#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_XMON)
static struct irqaction xmon_irqaction = {
.handler = xmon_irq,
- .mask = CPU_MASK_NONE,
.name = "XMON break",
};
#endif
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 4f9f8184d164..291ac9d8cbee 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -1,6 +1,6 @@
config EMBEDDED6xx
bool "Embedded 6xx/7xx/7xxx-based boards"
- depends on PPC32 && BROKEN_ON_SMP && PPC_MULTIPLATFORM
+ depends on 6xx && BROKEN_ON_SMP
config LINKSTATION
bool "Linkstation / Kurobox(HG) from Buffalo"
diff --git a/arch/powerpc/platforms/iseries/Kconfig b/arch/powerpc/platforms/iseries/Kconfig
index 7ddd0a2c8027..647e87787437 100644
--- a/arch/powerpc/platforms/iseries/Kconfig
+++ b/arch/powerpc/platforms/iseries/Kconfig
@@ -1,6 +1,6 @@
config PPC_ISERIES
bool "IBM Legacy iSeries"
- depends on PPC_MULTIPLATFORM && PPC64
+ depends on PPC64 && PPC_BOOK3S
select PPC_INDIRECT_IO
select PPC_PCI_CHOICE if EMBEDDED
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 701d9297c207..94f444758836 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -214,7 +214,7 @@ void __init iSeries_activate_IRQs()
unsigned long flags;
for_each_irq (irq) {
- irq_desc_t *desc = get_irq_desc(irq);
+ struct irq_desc *desc = get_irq_desc(irq);
if (desc && desc->chip && desc->chip->startup) {
spin_lock_irqsave(&desc->lock, flags);
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 24519b96d6ad..a6cd3394feaa 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -617,7 +617,7 @@ static void iseries_dedicated_idle(void)
}
static void __iomem *iseries_ioremap(phys_addr_t address, unsigned long size,
- unsigned long flags)
+ unsigned long flags, void *caller)
{
return (void __iomem *)address;
}
diff --git a/arch/powerpc/platforms/maple/Kconfig b/arch/powerpc/platforms/maple/Kconfig
index a6467a5591fa..1ea621a94c3b 100644
--- a/arch/powerpc/platforms/maple/Kconfig
+++ b/arch/powerpc/platforms/maple/Kconfig
@@ -1,5 +1,5 @@
config PPC_MAPLE
- depends on PPC_MULTIPLATFORM && PPC64
+ depends on PPC64 && PPC_BOOK3S
bool "Maple 970FX Evaluation Board"
select PCI
select MPIC
diff --git a/arch/powerpc/platforms/pasemi/Kconfig b/arch/powerpc/platforms/pasemi/Kconfig
index 348e0619e3e5..a2aeb327d185 100644
--- a/arch/powerpc/platforms/pasemi/Kconfig
+++ b/arch/powerpc/platforms/pasemi/Kconfig
@@ -1,5 +1,5 @@
config PPC_PASEMI
- depends on PPC_MULTIPLATFORM && PPC64
+ depends on PPC64 && PPC_BOOK3S
bool "PA Semi SoC-based platforms"
default n
select MPIC
diff --git a/arch/powerpc/platforms/powermac/Kconfig b/arch/powerpc/platforms/powermac/Kconfig
index 055990ca8ce6..1e1a0873e1dd 100644
--- a/arch/powerpc/platforms/powermac/Kconfig
+++ b/arch/powerpc/platforms/powermac/Kconfig
@@ -1,6 +1,6 @@
config PPC_PMAC
bool "Apple PowerMac based machines"
- depends on PPC_MULTIPLATFORM
+ depends on PPC_BOOK3S
select MPIC
select PCI
select PPC_INDIRECT_PCI if PPC32
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index beb38333b6d2..22ecfbe7183d 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -86,6 +86,7 @@ static int (*g5_query_freq)(void);
static DEFINE_MUTEX(g5_switch_mutex);
+static unsigned long transition_latency;
#ifdef CONFIG_PMAC_SMU
@@ -357,7 +358,7 @@ static unsigned int g5_cpufreq_get_speed(unsigned int cpu)
static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy)
{
- policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ policy->cpuinfo.transition_latency = transition_latency;
policy->cur = g5_cpu_freqs[g5_query_freq()].frequency;
/* secondary CPUs are tied to the primary one by the
* cpufreq core if in the secondary policy we tell it that
@@ -500,6 +501,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
g5_cpu_freqs[1].frequency = max_freq/2;
/* Set callbacks */
+ transition_latency = 12000;
g5_switch_freq = g5_scom_switch_freq;
g5_query_freq = g5_scom_query_freq;
freq_method = "SCOM";
@@ -675,6 +677,7 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
g5_cpu_freqs[1].frequency = min_freq;
/* Set callbacks */
+ transition_latency = CPUFREQ_ETERNAL;
g5_switch_volt = g5_pfunc_switch_volt;
g5_switch_freq = g5_pfunc_switch_freq;
g5_query_freq = g5_pfunc_query_freq;
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 6d149ae8ffa7..7039d8f1d3ba 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -266,7 +266,6 @@ static unsigned int pmac_pic_get_irq(void)
static struct irqaction xmon_action = {
.handler = xmon_irq,
.flags = 0,
- .mask = CPU_MASK_NONE,
.name = "NMI - XMON"
};
#endif
@@ -274,7 +273,6 @@ static struct irqaction xmon_action = {
static struct irqaction gatwick_cascade_action = {
.handler = gatwick_action,
.flags = IRQF_DISABLED,
- .mask = CPU_MASK_NONE,
.name = "cascade",
};
diff --git a/arch/powerpc/platforms/powermac/pic.h b/arch/powerpc/platforms/powermac/pic.h
index c44c89f5e532..d622a8345aaa 100644
--- a/arch/powerpc/platforms/powermac/pic.h
+++ b/arch/powerpc/platforms/powermac/pic.h
@@ -3,7 +3,7 @@
#include <linux/irq.h>
-extern struct hw_interrupt_type pmac_pic;
+extern struct irq_chip pmac_pic;
extern void pmac_pic_init(void);
extern int pmac_get_irq(void);
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 9b78f5300c24..45936c9ed0ec 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -746,4 +746,7 @@ define_machine(powermac) {
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
.cpu_die = pmac_cpu_die,
#endif
+#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
+ .cpu_die = generic_mach_cpu_die,
+#endif
};
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index bd8817b00fa4..cf1dbe758890 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -385,7 +385,6 @@ static void __init psurge_dual_sync_tb(int cpu_nr)
static struct irqaction psurge_irqaction = {
.handler = psurge_primary_intr,
.flags = IRQF_DISABLED,
- .mask = CPU_MASK_NONE,
.name = "primary IPI",
};
diff --git a/arch/powerpc/platforms/prep/Kconfig b/arch/powerpc/platforms/prep/Kconfig
index 29d411279b0c..bf8330ef2e76 100644
--- a/arch/powerpc/platforms/prep/Kconfig
+++ b/arch/powerpc/platforms/prep/Kconfig
@@ -1,6 +1,6 @@
config PPC_PREP
bool "PowerPC Reference Platform (PReP) based machines"
- depends on PPC_MULTIPLATFORM && PPC32 && BROKEN
+ depends on 6xx && BROKEN
select MPIC
select PPC_I8259
select PPC_INDIRECT_PCI
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 740ef56a1550..dfe316b161a9 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -1,6 +1,6 @@
config PPC_PS3
bool "Sony PS3"
- depends on PPC_MULTIPLATFORM && PPC64
+ depends on PPC64 && PPC_BOOK3S
select PPC_CELL
select USB_ARCH_HAS_OHCI
select USB_OHCI_LITTLE_ENDIAN
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index d281cc0bca71..9a2b6d948610 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -311,7 +311,7 @@ static int __init ps3_mm_add_memory(void)
result = add_memory(0, start_addr, map.r1.size);
if (result) {
- DBG("%s:%d: add_memory failed: (%d)\n",
+ pr_err("%s:%d: add_memory failed: (%d)\n",
__func__, __LINE__, result);
return result;
}
@@ -322,7 +322,7 @@ static int __init ps3_mm_add_memory(void)
result = online_pages(start_pfn, nr_pages);
if (result)
- DBG("%s:%d: online_pages failed: (%d)\n",
+ pr_err("%s:%d: online_pages failed: (%d)\n",
__func__, __LINE__, result);
return result;
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
index e1c83c23b435..86e392b1b049 100644
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -808,6 +808,7 @@ u64 ps3_os_area_get_rtc_diff(void)
{
return saved_params.rtc_diff;
}
+EXPORT_SYMBOL(ps3_os_area_get_rtc_diff);
/**
* ps3_os_area_set_rtc_diff - Set the rtc diff value.
@@ -823,6 +824,7 @@ void ps3_os_area_set_rtc_diff(u64 rtc_diff)
os_area_queue_work();
}
}
+EXPORT_SYMBOL(ps3_os_area_set_rtc_diff);
/**
* ps3_os_area_get_av_multi_out - Returns the default video mode.
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index 235c13ebacd9..136aa0637d9c 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -64,8 +64,6 @@ int ps3_set_rtc_time(struct rtc_time *time);
void __init ps3_os_area_save_params(void);
void __init ps3_os_area_init(void);
-u64 ps3_os_area_get_rtc_diff(void);
-void ps3_os_area_set_rtc_diff(u64 rtc_diff);
/* spu */
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 3331ccbb8d38..66181821322a 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -270,8 +270,6 @@ define_machine(ps3) {
.init_IRQ = ps3_init_IRQ,
.panic = ps3_panic,
.get_boot_time = ps3_get_boot_time,
- .set_rtc_time = ps3_set_rtc_time,
- .get_rtc_time = ps3_get_rtc_time,
.set_dabr = ps3_set_dabr,
.calibrate_decr = ps3_calibrate_decr,
.progress = ps3_progress,
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 58311a867851..a705fffbb498 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -376,7 +376,7 @@ static int ps3_system_bus_probe(struct device *_dev)
struct ps3_system_bus_driver *drv;
BUG_ON(!dev);
- pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
+ dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);
drv = ps3_system_bus_dev_to_system_bus_drv(dev);
BUG_ON(!drv);
@@ -398,7 +398,7 @@ static int ps3_system_bus_remove(struct device *_dev)
struct ps3_system_bus_driver *drv;
BUG_ON(!dev);
- pr_debug(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
+ dev_dbg(_dev, "%s:%d\n", __func__, __LINE__);
drv = ps3_system_bus_dev_to_system_bus_drv(dev);
BUG_ON(!drv);
diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c
index d0daf7d6d3b2..b178a1e66c91 100644
--- a/arch/powerpc/platforms/ps3/time.c
+++ b/arch/powerpc/platforms/ps3/time.c
@@ -19,6 +19,7 @@
*/
#include <linux/kernel.h>
+#include <linux/platform_device.h>
#include <asm/rtc.h>
#include <asm/lv1call.h>
@@ -74,23 +75,20 @@ static u64 read_rtc(void)
return rtc_val;
}
-int ps3_set_rtc_time(struct rtc_time *tm)
+unsigned long __init ps3_get_boot_time(void)
{
- u64 now = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
-
- ps3_os_area_set_rtc_diff(now - read_rtc());
- return 0;
+ return read_rtc() + ps3_os_area_get_rtc_diff();
}
-void ps3_get_rtc_time(struct rtc_time *tm)
+static int __init ps3_rtc_init(void)
{
- to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm);
- tm->tm_year -= 1900;
- tm->tm_mon -= 1;
-}
+ struct platform_device *pdev;
-unsigned long __init ps3_get_boot_time(void)
-{
- return read_rtc() + ps3_os_area_get_rtc_diff();
+ pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
}
+
+module_init(ps3_rtc_init);
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index ddc2a307cd50..f0e6f28427bd 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -1,5 +1,5 @@
config PPC_PSERIES
- depends on PPC_MULTIPLATFORM && PPC64
+ depends on PPC64 && PPC_BOOK3S
bool "IBM pSeries & new (POWER5-based) iSeries"
select MPIC
select PPC_I8259
@@ -25,6 +25,11 @@ config EEH
depends on PPC_PSERIES && PCI
default y if !EMBEDDED
+config PSERIES_MSI
+ bool
+ depends on PCI_MSI && EEH
+ default y
+
config SCANLOG
tristate "Scanlog dump interface"
depends on RTAS_PROC && PPC_PSERIES
@@ -63,3 +68,13 @@ config CMM
makes sense for a system running in an LPAR where the unused pages
will be reused for other LPARs. The interface allows firmware to
balance memory across many LPARs.
+
+config DTL
+ bool "Dispatch Trace Log"
+ depends on PPC_SPLPAR && DEBUG_FS
+ help
+ SPLPAR machines can log hypervisor preempt & dispatch events to a
+ kernel buffer. Saying Y here will enable logging these events,
+ which are accessible through a debugfs file.
+
+ Say N if you are unsure.
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index dfe574af2dc0..790c0b872d4f 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_SCANLOG) += scanlog.o
obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o eeh_sysfs.o
obj-$(CONFIG_KEXEC) += kexec.o
obj-$(CONFIG_PCI) += pci.o pci_dlpar.o
-obj-$(CONFIG_PCI_MSI) += msi.o
+obj-$(CONFIG_PSERIES_MSI) += msi.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o
obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o
@@ -25,3 +25,4 @@ obj-$(CONFIG_HVCS) += hvcserver.o
obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o
obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o
obj-$(CONFIG_CMM) += cmm.o
+obj-$(CONFIG_DTL) += dtl.o
diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
new file mode 100644
index 000000000000..fafcaa0e81ef
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/dtl.c
@@ -0,0 +1,278 @@
+/*
+ * Virtual Processor Dispatch Trace Log
+ *
+ * (C) Copyright IBM Corporation 2009
+ *
+ * Author: Jeremy Kerr <jk@ozlabs.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/debugfs.h>
+#include <asm/smp.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include "plpar_wrappers.h"
+
+/*
+ * Layout of entries in the hypervisor's DTL buffer. Although we don't
+ * actually access the internals of an entry (we only need to know the size),
+ * we might as well define it here for reference.
+ */
+struct dtl_entry {
+ u8 dispatch_reason;
+ u8 preempt_reason;
+ u16 processor_id;
+ u32 enqueue_to_dispatch_time;
+ u32 ready_to_enqueue_time;
+ u32 waiting_to_ready_time;
+ u64 timebase;
+ u64 fault_addr;
+ u64 srr0;
+ u64 srr1;
+};
+
+struct dtl {
+ struct dtl_entry *buf;
+ struct dentry *file;
+ int cpu;
+ int buf_entries;
+ u64 last_idx;
+};
+static DEFINE_PER_CPU(struct dtl, dtl);
+
+/*
+ * Dispatch trace log event mask:
+ * 0x7: 0x1: voluntary virtual processor waits
+ * 0x2: time-slice preempts
+ * 0x4: virtual partition memory page faults
+ */
+static u8 dtl_event_mask = 0x7;
+
+
+/*
+ * Size of per-cpu log buffers. Default is just under 16 pages worth.
+ */
+static int dtl_buf_entries = (16 * 85);
+
+
+static int dtl_enable(struct dtl *dtl)
+{
+ unsigned long addr;
+ int ret, hwcpu;
+
+ /* only allow one reader */
+ if (dtl->buf)
+ return -EBUSY;
+
+ /* we need to store the original allocation size for use during read */
+ dtl->buf_entries = dtl_buf_entries;
+
+ dtl->buf = kmalloc_node(dtl->buf_entries * sizeof(struct dtl_entry),
+ GFP_KERNEL, cpu_to_node(dtl->cpu));
+ if (!dtl->buf) {
+ printk(KERN_WARNING "%s: buffer alloc failed for cpu %d\n",
+ __func__, dtl->cpu);
+ return -ENOMEM;
+ }
+
+ /* Register our dtl buffer with the hypervisor. The HV expects the
+ * buffer size to be passed in the second word of the buffer */
+ ((u32 *)dtl->buf)[1] = dtl->buf_entries * sizeof(struct dtl_entry);
+
+ hwcpu = get_hard_smp_processor_id(dtl->cpu);
+ addr = __pa(dtl->buf);
+ ret = register_dtl(hwcpu, addr);
+ if (ret) {
+ printk(KERN_WARNING "%s: DTL registration for cpu %d (hw %d) "
+ "failed with %d\n", __func__, dtl->cpu, hwcpu, ret);
+ kfree(dtl->buf);
+ return -EIO;
+ }
+
+ /* set our initial buffer indices */
+ dtl->last_idx = lppaca[dtl->cpu].dtl_idx = 0;
+
+ /* ensure that our updates to the lppaca fields have occurred before
+ * we actually enable the logging */
+ smp_wmb();
+
+ /* enable event logging */
+ lppaca[dtl->cpu].dtl_enable_mask = dtl_event_mask;
+
+ return 0;
+}
+
+static void dtl_disable(struct dtl *dtl)
+{
+ int hwcpu = get_hard_smp_processor_id(dtl->cpu);
+
+ lppaca[dtl->cpu].dtl_enable_mask = 0x0;
+
+ unregister_dtl(hwcpu, __pa(dtl->buf));
+
+ kfree(dtl->buf);
+ dtl->buf = NULL;
+ dtl->buf_entries = 0;
+}
+
+/* file interface */
+
+static int dtl_file_open(struct inode *inode, struct file *filp)
+{
+ struct dtl *dtl = inode->i_private;
+ int rc;
+
+ rc = dtl_enable(dtl);
+ if (rc)
+ return rc;
+
+ filp->private_data = dtl;
+ return 0;
+}
+
+static int dtl_file_release(struct inode *inode, struct file *filp)
+{
+ struct dtl *dtl = inode->i_private;
+ dtl_disable(dtl);
+ return 0;
+}
+
+static ssize_t dtl_file_read(struct file *filp, char __user *buf, size_t len,
+ loff_t *pos)
+{
+ int rc, cur_idx, last_idx, n_read, n_req, read_size;
+ struct dtl *dtl;
+
+ if ((len % sizeof(struct dtl_entry)) != 0)
+ return -EINVAL;
+
+ dtl = filp->private_data;
+
+ /* requested number of entries to read */
+ n_req = len / sizeof(struct dtl_entry);
+
+ /* actual number of entries read */
+ n_read = 0;
+
+ cur_idx = lppaca[dtl->cpu].dtl_idx;
+ last_idx = dtl->last_idx;
+
+ if (cur_idx - last_idx > dtl->buf_entries) {
+ pr_debug("%s: hv buffer overflow for cpu %d, samples lost\n",
+ __func__, dtl->cpu);
+ }
+
+ cur_idx %= dtl->buf_entries;
+ last_idx %= dtl->buf_entries;
+
+ /* read the tail of the buffer if we've wrapped */
+ if (last_idx > cur_idx) {
+ read_size = min(n_req, dtl->buf_entries - last_idx);
+
+ rc = copy_to_user(buf, &dtl->buf[last_idx],
+ read_size * sizeof(struct dtl_entry));
+ if (rc)
+ return -EFAULT;
+
+ last_idx = 0;
+ n_req -= read_size;
+ n_read += read_size;
+ buf += read_size * sizeof(struct dtl_entry);
+ }
+
+ /* .. and now the head */
+ read_size = min(n_req, cur_idx - last_idx);
+ rc = copy_to_user(buf, &dtl->buf[last_idx],
+ read_size * sizeof(struct dtl_entry));
+ if (rc)
+ return -EFAULT;
+
+ n_read += read_size;
+ dtl->last_idx += n_read;
+
+ return n_read * sizeof(struct dtl_entry);
+}
+
+static struct file_operations dtl_fops = {
+ .open = dtl_file_open,
+ .release = dtl_file_release,
+ .read = dtl_file_read,
+ .llseek = no_llseek,
+};
+
+static struct dentry *dtl_dir;
+
+static int dtl_setup_file(struct dtl *dtl)
+{
+ char name[10];
+
+ sprintf(name, "cpu-%d", dtl->cpu);
+
+ dtl->file = debugfs_create_file(name, 0400, dtl_dir, dtl, &dtl_fops);
+ if (!dtl->file)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int dtl_init(void)
+{
+ struct dentry *event_mask_file, *buf_entries_file;
+ int rc, i;
+
+ if (!firmware_has_feature(FW_FEATURE_SPLPAR))
+ return -ENODEV;
+
+ /* set up common debugfs structure */
+
+ rc = -ENOMEM;
+ dtl_dir = debugfs_create_dir("dtl", powerpc_debugfs_root);
+ if (!dtl_dir) {
+ printk(KERN_WARNING "%s: can't create dtl root dir\n",
+ __func__);
+ goto err;
+ }
+
+ event_mask_file = debugfs_create_x8("dtl_event_mask", 0600,
+ dtl_dir, &dtl_event_mask);
+ buf_entries_file = debugfs_create_u32("dtl_buf_entries", 0600,
+ dtl_dir, &dtl_buf_entries);
+
+ if (!event_mask_file || !buf_entries_file) {
+ printk(KERN_WARNING "%s: can't create dtl files\n", __func__);
+ goto err_remove_dir;
+ }
+
+ /* set up the per-cpu log structures */
+ for_each_possible_cpu(i) {
+ struct dtl *dtl = &per_cpu(dtl, i);
+ dtl->cpu = i;
+
+ rc = dtl_setup_file(dtl);
+ if (rc)
+ goto err_remove_dir;
+ }
+
+ return 0;
+
+err_remove_dir:
+ debugfs_remove_recursive(dtl_dir);
+err:
+ return rc;
+}
+arch_initcall(dtl_init);
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 0ad56ff7b4a0..380420f8c400 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -79,6 +79,40 @@ static int irq_in_use(unsigned int irq)
return rc;
}
+/**
+ * eeh_disable_irq - disable interrupt for the recovering device
+ */
+static void eeh_disable_irq(struct pci_dev *dev)
+{
+ struct device_node *dn = pci_device_to_OF_node(dev);
+
+ /* Don't disable MSI and MSI-X interrupts. They are
+ * effectively disabled by the DMA Stopped state
+ * when an EEH error occurs.
+ */
+ if (dev->msi_enabled || dev->msix_enabled)
+ return;
+
+ if (!irq_in_use(dev->irq))
+ return;
+
+ PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
+ disable_irq_nosync(dev->irq);
+}
+
+/**
+ * eeh_enable_irq - enable interrupt for the recovering device
+ */
+static void eeh_enable_irq(struct pci_dev *dev)
+{
+ struct device_node *dn = pci_device_to_OF_node(dev);
+
+ if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) {
+ PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED;
+ enable_irq(dev->irq);
+ }
+}
+
/* ------------------------------------------------------- */
/**
* eeh_report_error - report pci error to each device driver
@@ -98,11 +132,8 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata)
if (!driver)
return;
- if (irq_in_use (dev->irq)) {
- struct device_node *dn = pci_device_to_OF_node(dev);
- PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
- disable_irq_nosync(dev->irq);
- }
+ eeh_disable_irq(dev);
+
if (!driver->err_handler ||
!driver->err_handler->error_detected)
return;
@@ -147,15 +178,12 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata)
{
enum pci_ers_result rc, *res = userdata;
struct pci_driver *driver = dev->driver;
- struct device_node *dn = pci_device_to_OF_node(dev);
if (!driver)
return;
- if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) {
- PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED;
- enable_irq(dev->irq);
- }
+ eeh_enable_irq(dev);
+
if (!driver->err_handler ||
!driver->err_handler->slot_reset)
return;
@@ -174,17 +202,14 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata)
static void eeh_report_resume(struct pci_dev *dev, void *userdata)
{
struct pci_driver *driver = dev->driver;
- struct device_node *dn = pci_device_to_OF_node(dev);
dev->error_state = pci_channel_io_normal;
if (!driver)
return;
- if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) {
- PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED;
- enable_irq(dev->irq);
- }
+ eeh_enable_irq(dev);
+
if (!driver->err_handler ||
!driver->err_handler->resume)
return;
@@ -208,15 +233,12 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata)
if (!driver)
return;
- if (irq_in_use (dev->irq)) {
- struct device_node *dn = pci_device_to_OF_node(dev);
- PCI_DN(dn)->eeh_mode |= EEH_MODE_IRQ_DISABLED;
- disable_irq_nosync(dev->irq);
- }
- if (!driver->err_handler)
- return;
- if (!driver->err_handler->error_detected)
+ eeh_disable_irq(dev);
+
+ if (!driver->err_handler ||
+ !driver->err_handler->error_detected)
return;
+
driver->err_handler->error_detected(dev, pci_channel_io_perm_failure);
}
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index f15222bbe136..bf2e1ac41308 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -71,11 +71,13 @@ static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs)
} while (rtas_busy_delay(rc));
/*
- * If the RTAS call succeeded, check the number of irqs is actually
- * what we asked for. If not, return an error.
+ * If the RTAS call succeeded, return the number of irqs allocated.
+ * If not, make sure we return a negative error code.
*/
- if (rc == 0 && rtas_ret[0] != num_irqs)
- rc = -ENOSPC;
+ if (rc == 0)
+ rc = rtas_ret[0];
+ else if (rc > 0)
+ rc = -rc;
pr_debug("rtas_msi: ibm,change_msi(func=%d,num=%d), got %d rc = %d\n",
func, num_irqs, rtas_ret[0], rc);
@@ -91,7 +93,7 @@ static void rtas_disable_msi(struct pci_dev *pdev)
if (!pdn)
return;
- if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0))
+ if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0) != 0)
pr_debug("rtas_msi: Setting MSIs to 0 failed!\n");
}
@@ -132,7 +134,7 @@ static void rtas_teardown_msi_irqs(struct pci_dev *pdev)
rtas_disable_msi(pdev);
}
-static int check_req_msi(struct pci_dev *pdev, int nvec)
+static int check_req(struct pci_dev *pdev, int nvec, char *prop_name)
{
struct device_node *dn;
struct pci_dn *pdn;
@@ -144,26 +146,235 @@ static int check_req_msi(struct pci_dev *pdev, int nvec)
dn = pdn->node;
- req_msi = of_get_property(dn, "ibm,req#msi", NULL);
+ req_msi = of_get_property(dn, prop_name, NULL);
if (!req_msi) {
- pr_debug("rtas_msi: No ibm,req#msi on %s\n", dn->full_name);
+ pr_debug("rtas_msi: No %s on %s\n", prop_name, dn->full_name);
return -ENOENT;
}
if (*req_msi < nvec) {
- pr_debug("rtas_msi: ibm,req#msi requests < %d MSIs\n", nvec);
- return -ENOSPC;
+ pr_debug("rtas_msi: %s requests < %d MSIs\n", prop_name, nvec);
+
+ if (*req_msi == 0) /* Be paranoid */
+ return -ENOSPC;
+
+ return *req_msi;
}
return 0;
}
+static int check_req_msi(struct pci_dev *pdev, int nvec)
+{
+ return check_req(pdev, nvec, "ibm,req#msi");
+}
+
+static int check_req_msix(struct pci_dev *pdev, int nvec)
+{
+ return check_req(pdev, nvec, "ibm,req#msi-x");
+}
+
+/* Quota calculation */
+
+static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total)
+{
+ struct device_node *dn;
+ const u32 *p;
+
+ dn = of_node_get(pci_device_to_OF_node(dev));
+ while (dn) {
+ p = of_get_property(dn, "ibm,pe-total-#msi", NULL);
+ if (p) {
+ pr_debug("rtas_msi: found prop on dn %s\n",
+ dn->full_name);
+ *total = *p;
+ return dn;
+ }
+
+ dn = of_get_next_parent(dn);
+ }
+
+ return NULL;
+}
+
+static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
+{
+ struct device_node *dn;
+
+ /* Found our PE and assume 8 at that point. */
+
+ dn = pci_device_to_OF_node(dev);
+ if (!dn)
+ return NULL;
+
+ dn = find_device_pe(dn);
+ if (!dn)
+ return NULL;
+
+ /* We actually want the parent */
+ dn = of_get_parent(dn);
+ if (!dn)
+ return NULL;
+
+ /* Hardcode of 8 for old firmwares */
+ *total = 8;
+ pr_debug("rtas_msi: using PE dn %s\n", dn->full_name);
+
+ return dn;
+}
+
+struct msi_counts {
+ struct device_node *requestor;
+ int num_devices;
+ int request;
+ int quota;
+ int spare;
+ int over_quota;
+};
+
+static void *count_non_bridge_devices(struct device_node *dn, void *data)
+{
+ struct msi_counts *counts = data;
+ const u32 *p;
+ u32 class;
+
+ pr_debug("rtas_msi: counting %s\n", dn->full_name);
+
+ p = of_get_property(dn, "class-code", NULL);
+ class = p ? *p : 0;
+
+ if ((class >> 8) != PCI_CLASS_BRIDGE_PCI)
+ counts->num_devices++;
+
+ return NULL;
+}
+
+static void *count_spare_msis(struct device_node *dn, void *data)
+{
+ struct msi_counts *counts = data;
+ const u32 *p;
+ int req;
+
+ if (dn == counts->requestor)
+ req = counts->request;
+ else {
+ /* We don't know if a driver will try to use MSI or MSI-X,
+ * so we just have to punt and use the larger of the two. */
+ req = 0;
+ p = of_get_property(dn, "ibm,req#msi", NULL);
+ if (p)
+ req = *p;
+
+ p = of_get_property(dn, "ibm,req#msi-x", NULL);
+ if (p)
+ req = max(req, (int)*p);
+ }
+
+ if (req < counts->quota)
+ counts->spare += counts->quota - req;
+ else if (req > counts->quota)
+ counts->over_quota++;
+
+ return NULL;
+}
+
+static int msi_quota_for_device(struct pci_dev *dev, int request)
+{
+ struct device_node *pe_dn;
+ struct msi_counts counts;
+ int total;
+
+ pr_debug("rtas_msi: calc quota for %s, request %d\n", pci_name(dev),
+ request);
+
+ pe_dn = find_pe_total_msi(dev, &total);
+ if (!pe_dn)
+ pe_dn = find_pe_dn(dev, &total);
+
+ if (!pe_dn) {
+ pr_err("rtas_msi: couldn't find PE for %s\n", pci_name(dev));
+ goto out;
+ }
+
+ pr_debug("rtas_msi: found PE %s\n", pe_dn->full_name);
+
+ memset(&counts, 0, sizeof(struct msi_counts));
+
+ /* Work out how many devices we have below this PE */
+ traverse_pci_devices(pe_dn, count_non_bridge_devices, &counts);
+
+ if (counts.num_devices == 0) {
+ pr_err("rtas_msi: found 0 devices under PE for %s\n",
+ pci_name(dev));
+ goto out;
+ }
+
+ counts.quota = total / counts.num_devices;
+ if (request <= counts.quota)
+ goto out;
+
+ /* else, we have some more calculating to do */
+ counts.requestor = pci_device_to_OF_node(dev);
+ counts.request = request;
+ traverse_pci_devices(pe_dn, count_spare_msis, &counts);
+
+ /* If the quota isn't an integer multiple of the total, we can
+ * use the remainder as spare MSIs for anyone that wants them. */
+ counts.spare += total % counts.num_devices;
+
+ /* Divide any spare by the number of over-quota requestors */
+ if (counts.over_quota)
+ counts.quota += counts.spare / counts.over_quota;
+
+ /* And finally clamp the request to the possibly adjusted quota */
+ request = min(counts.quota, request);
+
+ pr_debug("rtas_msi: request clamped to quota %d\n", request);
+out:
+ of_node_put(pe_dn);
+
+ return request;
+}
+
static int rtas_msi_check_device(struct pci_dev *pdev, int nvec, int type)
{
+ int quota, rc;
+
if (type == PCI_CAP_ID_MSIX)
- pr_debug("rtas_msi: MSI-X untested, trying anyway.\n");
+ rc = check_req_msix(pdev, nvec);
+ else
+ rc = check_req_msi(pdev, nvec);
+
+ if (rc)
+ return rc;
+
+ quota = msi_quota_for_device(pdev, nvec);
- return check_req_msi(pdev, nvec);
+ if (quota && quota < nvec)
+ return quota;
+
+ return 0;
+}
+
+static int check_msix_entries(struct pci_dev *pdev)
+{
+ struct msi_desc *entry;
+ int expected;
+
+ /* There's no way for us to express to firmware that we want
+ * a discontiguous, or non-zero based, range of MSI-X entries.
+ * So we must reject such requests. */
+
+ expected = 0;
+ list_for_each_entry(entry, &pdev->msi_list, list) {
+ if (entry->msi_attrib.entry_nr != expected) {
+ pr_debug("rtas_msi: bad MSI-X entries.\n");
+ return -EINVAL;
+ }
+ expected++;
+ }
+
+ return 0;
}
static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
@@ -177,6 +388,9 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
if (!pdn)
return -ENODEV;
+ if (type == PCI_CAP_ID_MSIX && check_msix_entries(pdev))
+ return -EINVAL;
+
/*
* Try the new more explicit firmware interface, if that fails fall
* back to the old interface. The old interface is known to never
@@ -185,21 +399,21 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
if (type == PCI_CAP_ID_MSI) {
rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec);
- if (rc) {
+ if (rc < 0) {
pr_debug("rtas_msi: trying the old firmware call.\n");
rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec);
}
} else
rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec);
- if (rc) {
+ if (rc != nvec) {
pr_debug("rtas_msi: rtas_change_msi() failed\n");
return rc;
}
i = 0;
list_for_each_entry(entry, &pdev->msi_list, list) {
- hwirq = rtas_query_irq_number(pdn, i);
+ hwirq = rtas_query_irq_number(pdn, i++);
if (hwirq < 0) {
pr_debug("rtas_msi: error (%d) getting hwirq\n", rc);
return hwirq;
@@ -234,8 +448,8 @@ static void rtas_msi_pci_irq_fixup(struct pci_dev *pdev)
}
/* No MSI -> MSIs can't have been assigned by fw, leave LSI */
- if (check_req_msi(pdev, 1)) {
- dev_dbg(&pdev->dev, "rtas_msi: no req#msi, nothing to do.\n");
+ if (check_req_msi(pdev, 1) && check_req_msix(pdev, 1)) {
+ dev_dbg(&pdev->dev, "rtas_msi: no req#msi/x, nothing to do.\n");
return;
}
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 5e1ed3d60ee5..ad152a0e3946 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -137,11 +137,9 @@ EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
{
struct pci_controller *phb;
- int primary;
pr_debug("PCI: Initializing new hotplug PHB %s\n", dn->full_name);
- primary = list_empty(&hose_list);
phb = pcibios_alloc_controller(dn);
if (!phb)
return NULL;
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
index d967c1893ab5..a24a6b2333b2 100644
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -43,6 +43,16 @@ static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa)
return vpa_call(0x3, cpu, vpa);
}
+static inline long unregister_dtl(unsigned long cpu, unsigned long vpa)
+{
+ return vpa_call(0x6, cpu, vpa);
+}
+
+static inline long register_dtl(unsigned long cpu, unsigned long vpa)
+{
+ return vpa_call(0x2, cpu, vpa);
+}
+
static inline long plpar_page_set_loaned(unsigned long vpa)
{
unsigned long cmo_page_sz = cmo_get_page_size();
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index c591a25b0b0d..b6f1b137d427 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -468,9 +468,13 @@ static int do_update_property(char *buf, size_t bufsize)
rc = blocking_notifier_call_chain(&pSeries_reconfig_chain,
action, value);
+ if (rc == NOTIFY_BAD) {
+ rc = prom_update_property(np, oldprop, newprop);
+ return -ENOMEM;
+ }
}
- return rc;
+ return 0;
}
/**
diff --git a/arch/powerpc/sysdev/bestcomm/Kconfig b/arch/powerpc/sysdev/bestcomm/Kconfig
index 0b192a1c429d..29e427085efb 100644
--- a/arch/powerpc/sysdev/bestcomm/Kconfig
+++ b/arch/powerpc/sysdev/bestcomm/Kconfig
@@ -9,8 +9,8 @@ config PPC_BESTCOMM
select PPC_LIB_RHEAP
help
BestComm is the name of the communication coprocessor found
- on the Freescale MPC5200 family of processor. It's usage is
- optionnal for some drivers (like ATA), but required for
+ on the Freescale MPC5200 family of processor. Its usage is
+ optional for some drivers (like ATA), but required for
others (like FEC).
If you want to use drivers that require DMA operations,
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 490473ce8103..82424cd7e128 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -119,7 +119,6 @@ static irqreturn_t cpm_error_interrupt(int irq, void *dev)
static struct irqaction cpm_error_irqaction = {
.handler = cpm_error_interrupt,
- .mask = CPU_MASK_NONE,
.name = "error",
};
diff --git a/arch/powerpc/sysdev/cpm2.c b/arch/powerpc/sysdev/cpm2.c
index f1c3395633b9..fd969f0e3121 100644
--- a/arch/powerpc/sysdev/cpm2.c
+++ b/arch/powerpc/sysdev/cpm2.c
@@ -52,6 +52,7 @@ cpm_cpm2_t __iomem *cpmp; /* Pointer to comm processor space */
* the communication processor devices.
*/
cpm2_map_t __iomem *cpm2_immr;
+EXPORT_SYMBOL(cpm2_immr);
#define CPM_MAP_SIZE (0x40000) /* 256k - the PQ3 reserve this amount
of space for CPM as it is larger
@@ -129,7 +130,8 @@ void __cpm2_setbrg(uint brg, uint rate, uint clk, int div16, int src)
brg -= 4;
}
bp += brg;
- val = (((clk / rate) - 1) << 1) | CPM_BRG_EN | src;
+ /* Round the clock divider to the nearest integer. */
+ val = (((clk * 2 / rate) - 1) & ~1) | CPM_BRG_EN | src;
if (div16)
val |= CPM_BRG_DIV16;
diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
index 00d3d17c84a3..e4b6d66d93de 100644
--- a/arch/powerpc/sysdev/cpm_common.c
+++ b/arch/powerpc/sysdev/cpm_common.c
@@ -56,7 +56,7 @@ void __init udbg_init_cpm(void)
{
if (cpm_udbg_txdesc) {
#ifdef CONFIG_CPM2
- setbat(1, 0xf0000000, 0xf0000000, 1024*1024, _PAGE_IO);
+ setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG);
#endif
udbg_putc = udbg_putc_cpm;
}
diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c
index 0494ee55920f..dceb8d1a843d 100644
--- a/arch/powerpc/sysdev/fsl_lbc.c
+++ b/arch/powerpc/sysdev/fsl_lbc.c
@@ -150,7 +150,7 @@ int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar)
spin_lock_irqsave(&fsl_lbc_lock, flags);
- out_be32(&fsl_lbc_regs->mar, mar << (32 - upm->width));
+ out_be32(&fsl_lbc_regs->mar, mar);
switch (upm->width) {
case 8:
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 9817f63723dd..78021d8afc53 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -1,12 +1,16 @@
/*
* MPC83xx/85xx/86xx PCI/PCIE support routing.
*
- * Copyright 2007,2008 Freescale Semiconductor, Inc
+ * Copyright 2007-2009 Freescale Semiconductor, Inc.
+ * Copyright 2008-2009 MontaVista Software, Inc.
*
* Initial author: Xianghua Xiao <x.xiao@freescale.com>
* Recode: ZHANG WEI <wei.zhang@freescale.com>
* Rewrite the routing for Frescale PCI and PCI Express
* Roy Zang <tie-fei.zang@freescale.com>
+ * MPC83xx PCI-Express support:
+ * Tony Li <tony.li@freescale.com>
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -27,6 +31,29 @@
#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
+static int fsl_pcie_bus_fixup;
+
+static void __init quirk_fsl_pcie_header(struct pci_dev *dev)
+{
+ /* if we aren't a PCIe don't bother */
+ if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
+ return;
+
+ dev->class = PCI_CLASS_BRIDGE_PCI << 8;
+ fsl_pcie_bus_fixup = 1;
+ return;
+}
+
+static int __init fsl_pcie_check_link(struct pci_controller *hose)
+{
+ u32 val;
+
+ early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
+ if (val < PCIE_LTSSM_L0)
+ return 1;
+ return 0;
+}
+
#if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)
static int __init setup_one_atmu(struct ccsr_pci __iomem *pci,
unsigned int index, const struct resource *res,
@@ -159,28 +186,6 @@ static void __init setup_pci_pcsrbar(struct pci_controller *hose)
#endif
}
-static int fsl_pcie_bus_fixup;
-
-static void __init quirk_fsl_pcie_header(struct pci_dev *dev)
-{
- /* if we aren't a PCIe don't bother */
- if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
- return ;
-
- dev->class = PCI_CLASS_BRIDGE_PCI << 8;
- fsl_pcie_bus_fixup = 1;
- return ;
-}
-
-static int __init fsl_pcie_check_link(struct pci_controller *hose)
-{
- u32 val;
- early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
- if (val < PCIE_LTSSM_L0)
- return 1;
- return 0;
-}
-
void fsl_pcibios_fixup_bus(struct pci_bus *bus)
{
struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
@@ -294,8 +299,184 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);
#endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */
#if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8314, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8315, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8377E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8377, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8378E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8378, quirk_fsl_pcie_header);
+
+struct mpc83xx_pcie_priv {
+ void __iomem *cfg_type0;
+ void __iomem *cfg_type1;
+ u32 dev_base;
+};
+
+/*
+ * With the convention of u-boot, the PCIE outbound window 0 serves
+ * as configuration transactions outbound.
+ */
+#define PEX_OUTWIN0_BAR 0xCA4
+#define PEX_OUTWIN0_TAL 0xCA8
+#define PEX_OUTWIN0_TAH 0xCAC
+
+static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn)
+{
+ struct pci_controller *hose = bus->sysdata;
+
+ if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ /*
+ * Workaround for the HW bug: for Type 0 configure transactions the
+ * PCI-E controller does not check the device number bits and just
+ * assumes that the device number bits are 0.
+ */
+ if (bus->number == hose->first_busno ||
+ bus->primary == hose->first_busno) {
+ if (devfn & 0xf8)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ if (ppc_md.pci_exclude_device) {
+ if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus,
+ unsigned int devfn, int offset)
+{
+ struct pci_controller *hose = bus->sysdata;
+ struct mpc83xx_pcie_priv *pcie = hose->dn->data;
+ u8 bus_no = bus->number - hose->first_busno;
+ u32 dev_base = bus_no << 24 | devfn << 16;
+ int ret;
+
+ ret = mpc83xx_pcie_exclude_device(bus, devfn);
+ if (ret)
+ return NULL;
+
+ offset &= 0xfff;
+
+ /* Type 0 */
+ if (bus->number == hose->first_busno)
+ return pcie->cfg_type0 + offset;
+
+ if (pcie->dev_base == dev_base)
+ goto mapped;
+
+ out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, dev_base);
+
+ pcie->dev_base = dev_base;
+mapped:
+ return pcie->cfg_type1 + offset;
+}
+
+static int mpc83xx_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 *val)
+{
+ void __iomem *cfg_addr;
+
+ cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
+ if (!cfg_addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ switch (len) {
+ case 1:
+ *val = in_8(cfg_addr);
+ break;
+ case 2:
+ *val = in_le16(cfg_addr);
+ break;
+ default:
+ *val = in_le32(cfg_addr);
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int mpc83xx_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 val)
+{
+ void __iomem *cfg_addr;
+
+ cfg_addr = mpc83xx_pcie_remap_cfg(bus, devfn, offset);
+ if (!cfg_addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ switch (len) {
+ case 1:
+ out_8(cfg_addr, val);
+ break;
+ case 2:
+ out_le16(cfg_addr, val);
+ break;
+ default:
+ out_le32(cfg_addr, val);
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops mpc83xx_pcie_ops = {
+ .read = mpc83xx_pcie_read_config,
+ .write = mpc83xx_pcie_write_config,
+};
+
+static int __init mpc83xx_pcie_setup(struct pci_controller *hose,
+ struct resource *reg)
+{
+ struct mpc83xx_pcie_priv *pcie;
+ u32 cfg_bar;
+ int ret = -ENOMEM;
+
+ pcie = zalloc_maybe_bootmem(sizeof(*pcie), GFP_KERNEL);
+ if (!pcie)
+ return ret;
+
+ pcie->cfg_type0 = ioremap(reg->start, resource_size(reg));
+ if (!pcie->cfg_type0)
+ goto err0;
+
+ cfg_bar = in_le32(pcie->cfg_type0 + PEX_OUTWIN0_BAR);
+ if (!cfg_bar) {
+ /* PCI-E isn't configured. */
+ ret = -ENODEV;
+ goto err1;
+ }
+
+ pcie->cfg_type1 = ioremap(cfg_bar, 0x1000);
+ if (!pcie->cfg_type1)
+ goto err1;
+
+ WARN_ON(hose->dn->data);
+ hose->dn->data = pcie;
+ hose->ops = &mpc83xx_pcie_ops;
+
+ out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAH, 0);
+ out_le32(pcie->cfg_type0 + PEX_OUTWIN0_TAL, 0);
+
+ if (fsl_pcie_check_link(hose))
+ hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+
+ return 0;
+err1:
+ iounmap(pcie->cfg_type0);
+err0:
+ kfree(pcie);
+ return ret;
+
+}
+
int __init mpc83xx_add_bridge(struct device_node *dev)
{
+ int ret;
int len;
struct pci_controller *hose;
struct resource rsrc_reg;
@@ -303,6 +484,11 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
const int *bus_range;
int primary;
+ if (!of_device_is_available(dev)) {
+ pr_warning("%s: disabled by the firmware.\n",
+ dev->full_name);
+ return -ENODEV;
+ }
pr_debug("Adding PCI host bridge %s\n", dev->full_name);
/* Fetch host bridge registers address */
@@ -350,7 +536,14 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
hose->first_busno = bus_range ? bus_range[0] : 0;
hose->last_busno = bus_range ? bus_range[1] : 0xff;
- setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 4, 0);
+ if (of_device_is_compatible(dev, "fsl,mpc8314-pcie")) {
+ ret = mpc83xx_pcie_setup(hose, &rsrc_reg);
+ if (ret)
+ goto err0;
+ } else {
+ setup_indirect_pci(hose, rsrc_cfg.start,
+ rsrc_cfg.start + 4, 0);
+ }
printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
"Firmware bus number: %d->%d\n",
@@ -365,5 +558,8 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
pci_process_bridge_OF_ranges(hose, dev, primary);
return 0;
+err0:
+ pcibios_free_controller(hose);
+ return ret;
}
#endif /* CONFIG_PPC_83xx */
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 115cb16351fd..afe8dbc964aa 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
+#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
#include <linux/phy_fixed.h>
@@ -328,6 +329,9 @@ static int __init fsl_usb_of_init(void)
struct fsl_usb2_platform_data usb_data;
const unsigned char *prop = NULL;
+ if (!of_device_is_available(np))
+ continue;
+
memset(&r, 0, sizeof(r));
memset(&usb_data, 0, sizeof(usb_data));
@@ -413,115 +417,6 @@ err:
arch_initcall(fsl_usb_of_init);
-static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
- struct spi_board_info *board_infos,
- unsigned int num_board_infos,
- void (*activate_cs)(u8 cs, u8 polarity),
- void (*deactivate_cs)(u8 cs, u8 polarity))
-{
- struct device_node *np;
- unsigned int i = 0;
-
- for_each_compatible_node(np, type, compatible) {
- int ret;
- unsigned int j;
- const void *prop;
- struct resource res[2];
- struct platform_device *pdev;
- struct fsl_spi_platform_data pdata = {
- .activate_cs = activate_cs,
- .deactivate_cs = deactivate_cs,
- };
-
- memset(res, 0, sizeof(res));
-
- pdata.sysclk = sysclk;
-
- prop = of_get_property(np, "reg", NULL);
- if (!prop)
- goto err;
- pdata.bus_num = *(u32 *)prop;
-
- prop = of_get_property(np, "cell-index", NULL);
- if (prop)
- i = *(u32 *)prop;
-
- prop = of_get_property(np, "mode", NULL);
- if (prop && !strcmp(prop, "cpu-qe"))
- pdata.qe_mode = 1;
-
- for (j = 0; j < num_board_infos; j++) {
- if (board_infos[j].bus_num == pdata.bus_num)
- pdata.max_chipselect++;
- }
-
- if (!pdata.max_chipselect)
- continue;
-
- ret = of_address_to_resource(np, 0, &res[0]);
- if (ret)
- goto err;
-
- ret = of_irq_to_resource(np, 0, &res[1]);
- if (ret == NO_IRQ)
- goto err;
-
- pdev = platform_device_alloc("mpc83xx_spi", i);
- if (!pdev)
- goto err;
-
- ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
- if (ret)
- goto unreg;
-
- ret = platform_device_add_resources(pdev, res,
- ARRAY_SIZE(res));
- if (ret)
- goto unreg;
-
- ret = platform_device_add(pdev);
- if (ret)
- goto unreg;
-
- goto next;
-unreg:
- platform_device_del(pdev);
-err:
- pr_err("%s: registration failed\n", np->full_name);
-next:
- i++;
- }
-
- return i;
-}
-
-int __init fsl_spi_init(struct spi_board_info *board_infos,
- unsigned int num_board_infos,
- void (*activate_cs)(u8 cs, u8 polarity),
- void (*deactivate_cs)(u8 cs, u8 polarity))
-{
- u32 sysclk = -1;
- int ret;
-
-#ifdef CONFIG_QUICC_ENGINE
- /* SPI controller is either clocked from QE or SoC clock */
- sysclk = get_brgfreq();
-#endif
- if (sysclk == -1) {
- sysclk = fsl_get_sys_freq();
- if (sysclk == -1)
- return -ENODEV;
- }
-
- ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos,
- num_board_infos, activate_cs, deactivate_cs);
- if (!ret)
- of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos,
- num_board_infos, activate_cs, deactivate_cs);
-
- return spi_register_board_info(board_infos, num_board_infos);
-}
-
#if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)
static __be32 __iomem *rstcr;
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index 9c744e4285a0..42381bb6cd51 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -4,6 +4,8 @@
#include <asm/mmu.h>
+struct spi_device;
+
extern phys_addr_t get_immrbase(void);
#if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx)
extern u32 get_brgfreq(void);
@@ -17,11 +19,6 @@ extern u32 fsl_get_sys_freq(void);
struct spi_board_info;
struct device_node;
-extern int fsl_spi_init(struct spi_board_info *board_infos,
- unsigned int num_board_infos,
- void (*activate_cs)(u8 cs, u8 polarity),
- void (*deactivate_cs)(u8 cs, u8 polarity));
-
extern void fsl_rstcr_restart(char *cmd);
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 9a89cd3e80a2..a86d3ce01ead 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -568,8 +568,7 @@ static void ipic_ack_irq(unsigned int virq)
spin_lock_irqsave(&ipic_lock, flags);
- temp = ipic_read(ipic->regs, ipic_info[src].ack);
- temp |= (1 << (31 - ipic_info[src].bit));
+ temp = 1 << (31 - ipic_info[src].bit);
ipic_write(ipic->regs, ipic_info[src].ack, temp);
/* mb() can't guarantee that ack is finished. But it does finish
@@ -592,8 +591,7 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
temp &= ~(1 << (31 - ipic_info[src].bit));
ipic_write(ipic->regs, ipic_info[src].mask, temp);
- temp = ipic_read(ipic->regs, ipic_info[src].ack);
- temp |= (1 << (31 - ipic_info[src].bit));
+ temp = 1 << (31 - ipic_info[src].bit);
ipic_write(ipic->regs, ipic_info[src].ack, temp);
/* mb() can't guarantee that ack is finished. But it does finish
diff --git a/arch/powerpc/sysdev/msi_bitmap.c b/arch/powerpc/sysdev/msi_bitmap.c
index f84217b8863a..5a32cbef9b6c 100644
--- a/arch/powerpc/sysdev/msi_bitmap.c
+++ b/arch/powerpc/sysdev/msi_bitmap.c
@@ -141,7 +141,7 @@ void msi_bitmap_free(struct msi_bitmap *bmp)
#define check(x) \
if (!(x)) printk("msi_bitmap: test failed at line %d\n", __LINE__);
-void test_basics(void)
+void __init test_basics(void)
{
struct msi_bitmap bmp;
int i, size = 512;
@@ -186,7 +186,7 @@ void test_basics(void)
kfree(bmp.bitmap);
}
-void test_of_node(void)
+void __init test_of_node(void)
{
u32 prop_data[] = { 10, 10, 25, 3, 40, 1, 100, 100, 200, 20 };
const char *expected_str = "0-9,20-24,28-39,41-99,220-255";
@@ -234,7 +234,7 @@ void test_of_node(void)
kfree(bmp.bitmap);
}
-int msi_bitmap_selftest(void)
+int __init msi_bitmap_selftest(void)
{
printk(KERN_DEBUG "Running MSI bitmap self-tests ...\n");
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c
index c858749263e0..aaa915998eb6 100644
--- a/arch/powerpc/sysdev/pmi.c
+++ b/arch/powerpc/sysdev/pmi.c
@@ -50,7 +50,7 @@ struct pmi_data {
static struct pmi_data *data;
-static int pmi_irq_handler(int irq, void *dev_id)
+static irqreturn_t pmi_irq_handler(int irq, void *dev_id)
{
u8 type;
int rc;
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index 5558d932b4d5..6a2d473c345a 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -1839,6 +1839,8 @@ static int __init ppc4xx_pci_find_bridges(void)
{
struct device_node *np;
+ ppc_pci_flags |= PPC_PCI_ENABLE_PROC_DOMAINS | PPC_PCI_COMPAT_DOMAIN_0;
+
#ifdef CONFIG_PPC4xx_PCI_EXPRESS
for_each_compatible_node(np, NULL, "ibm,plb-pciex")
ppc4xx_probe_pciex_bridge(np);
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 6b0a3538dc63..dcb667c4375a 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -72,6 +72,9 @@ config PGSTE
config VIRT_CPU_ACCOUNTING
def_bool y
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ def_bool y
+
mainmenu "Linux Kernel Configuration"
config S390
@@ -343,13 +346,6 @@ source "mm/Kconfig"
comment "I/O subsystem configuration"
-config MACHCHK_WARNING
- bool "Process warning machine checks"
- help
- Select this option if you want the machine check handler on IBM S/390 or
- zSeries to process warning machine checks (e.g. on power failures).
- If unsure, say "Y".
-
config QDIO
tristate "QDIO support"
---help---
@@ -521,7 +517,7 @@ config APPLDATA_OS
config APPLDATA_NET_SUM
tristate "Monitor overall network statistics"
- depends on APPLDATA_BASE
+ depends on APPLDATA_BASE && NET
help
This provides network related data to the Linux - VM Monitor Stream,
currently there is only a total sum of network I/O statistics, no
@@ -552,7 +548,7 @@ config KEXEC
but is independent of hardware/microcode support.
config ZFCPDUMP
- tristate "zfcpdump support"
+ bool "zfcpdump support"
select SMP
default n
help
diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug
index 4599fa06bd82..2283933a9a93 100644
--- a/arch/s390/Kconfig.debug
+++ b/arch/s390/Kconfig.debug
@@ -6,12 +6,4 @@ config TRACE_IRQFLAGS_SUPPORT
source "lib/Kconfig.debug"
-config DEBUG_PAGEALLOC
- bool "Debug page memory allocations"
- depends on DEBUG_KERNEL
- help
- Unmap pages from the kernel linear mapping after free_pages().
- This results in a slowdown, but helps to find certain types of
- memory corruptions.
-
endmenu
diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c
index eca724d229ec..b49c00ce65e9 100644
--- a/arch/s390/crypto/prng.c
+++ b/arch/s390/crypto/prng.c
@@ -201,8 +201,7 @@ out_free:
static void __exit prng_exit(void)
{
/* wipe me */
- memset(p->buf, 0, prng_chunk_size);
- kfree(p->buf);
+ kzfree(p->buf);
kfree(p);
misc_deregister(&prng_dev);
diff --git a/arch/s390/crypto/sha.h b/arch/s390/crypto/sha.h
index 1ceafa571eab..f4e9dc71675f 100644
--- a/arch/s390/crypto/sha.h
+++ b/arch/s390/crypto/sha.h
@@ -29,7 +29,9 @@ struct s390_sha_ctx {
int func; /* KIMD function to use */
};
-void s390_sha_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len);
-void s390_sha_final(struct crypto_tfm *tfm, u8 *out);
+struct shash_desc;
+
+int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len);
+int s390_sha_final(struct shash_desc *desc, u8 *out);
#endif
diff --git a/arch/s390/crypto/sha1_s390.c b/arch/s390/crypto/sha1_s390.c
index b3cb5a89b00d..e85ba348722a 100644
--- a/arch/s390/crypto/sha1_s390.c
+++ b/arch/s390/crypto/sha1_s390.c
@@ -23,17 +23,17 @@
* any later version.
*
*/
+#include <crypto/internal/hash.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/crypto.h>
#include <crypto/sha.h>
#include "crypt_s390.h"
#include "sha.h"
-static void sha1_init(struct crypto_tfm *tfm)
+static int sha1_init(struct shash_desc *desc)
{
- struct s390_sha_ctx *sctx = crypto_tfm_ctx(tfm);
+ struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
sctx->state[0] = SHA1_H0;
sctx->state[1] = SHA1_H1;
@@ -42,34 +42,36 @@ static void sha1_init(struct crypto_tfm *tfm)
sctx->state[4] = SHA1_H4;
sctx->count = 0;
sctx->func = KIMD_SHA_1;
+
+ return 0;
}
-static struct crypto_alg alg = {
- .cra_name = "sha1",
- .cra_driver_name= "sha1-s390",
- .cra_priority = CRYPT_S390_PRIORITY,
- .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
- .cra_blocksize = SHA1_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct s390_sha_ctx),
- .cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
- .cra_u = { .digest = {
- .dia_digestsize = SHA1_DIGEST_SIZE,
- .dia_init = sha1_init,
- .dia_update = s390_sha_update,
- .dia_final = s390_sha_final } }
+static struct shash_alg alg = {
+ .digestsize = SHA1_DIGEST_SIZE,
+ .init = sha1_init,
+ .update = s390_sha_update,
+ .final = s390_sha_final,
+ .descsize = sizeof(struct s390_sha_ctx),
+ .base = {
+ .cra_name = "sha1",
+ .cra_driver_name= "sha1-s390",
+ .cra_priority = CRYPT_S390_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
};
static int __init sha1_s390_init(void)
{
if (!crypt_s390_func_available(KIMD_SHA_1))
return -EOPNOTSUPP;
- return crypto_register_alg(&alg);
+ return crypto_register_shash(&alg);
}
static void __exit sha1_s390_fini(void)
{
- crypto_unregister_alg(&alg);
+ crypto_unregister_shash(&alg);
}
module_init(sha1_s390_init);
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c
index 19c03fb6ba7e..f9fefc569632 100644
--- a/arch/s390/crypto/sha256_s390.c
+++ b/arch/s390/crypto/sha256_s390.c
@@ -16,17 +16,17 @@
* any later version.
*
*/
+#include <crypto/internal/hash.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/crypto.h>
#include <crypto/sha.h>
#include "crypt_s390.h"
#include "sha.h"
-static void sha256_init(struct crypto_tfm *tfm)
+static int sha256_init(struct shash_desc *desc)
{
- struct s390_sha_ctx *sctx = crypto_tfm_ctx(tfm);
+ struct s390_sha_ctx *sctx = shash_desc_ctx(desc);
sctx->state[0] = SHA256_H0;
sctx->state[1] = SHA256_H1;
@@ -38,22 +38,24 @@ static void sha256_init(struct crypto_tfm *tfm)
sctx->state[7] = SHA256_H7;
sctx->count = 0;
sctx->func = KIMD_SHA_256;
+
+ return 0;
}
-static struct crypto_alg alg = {
- .cra_name = "sha256",
- .cra_driver_name = "sha256-s390",
- .cra_priority = CRYPT_S390_PRIORITY,
- .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
- .cra_blocksize = SHA256_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct s390_sha_ctx),
- .cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(alg.cra_list),
- .cra_u = { .digest = {
- .dia_digestsize = SHA256_DIGEST_SIZE,
- .dia_init = sha256_init,
- .dia_update = s390_sha_update,
- .dia_final = s390_sha_final } }
+static struct shash_alg alg = {
+ .digestsize = SHA256_DIGEST_SIZE,
+ .init = sha256_init,
+ .update = s390_sha_update,
+ .final = s390_sha_final,
+ .descsize = sizeof(struct s390_sha_ctx),
+ .base = {
+ .cra_name = "sha256",
+ .cra_driver_name= "sha256-s390",
+ .cra_priority = CRYPT_S390_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
};
static int sha256_s390_init(void)
@@ -61,12 +63,12 @@ static int sha256_s390_init(void)
if (!crypt_s390_func_available(KIMD_SHA_256))
return -EOPNOTSUPP;
- return crypto_register_alg(&alg);
+ return crypto_register_shash(&alg);
}
static void __exit sha256_s390_fini(void)
{
- crypto_unregister_alg(&alg);
+ crypto_unregister_shash(&alg);
}
module_init(sha256_s390_init);
diff --git a/arch/s390/crypto/sha512_s390.c b/arch/s390/crypto/sha512_s390.c
index 23c7861f6aeb..83192bfc8048 100644
--- a/arch/s390/crypto/sha512_s390.c
+++ b/arch/s390/crypto/sha512_s390.c
@@ -12,16 +12,16 @@
* any later version.
*
*/
+#include <crypto/internal/hash.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/crypto.h>
#include "sha.h"
#include "crypt_s390.h"
-static void sha512_init(struct crypto_tfm *tfm)
+static int sha512_init(struct shash_desc *desc)
{
- struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
*(__u64 *)&ctx->state[0] = 0x6a09e667f3bcc908ULL;
*(__u64 *)&ctx->state[2] = 0xbb67ae8584caa73bULL;
@@ -33,29 +33,31 @@ static void sha512_init(struct crypto_tfm *tfm)
*(__u64 *)&ctx->state[14] = 0x5be0cd19137e2179ULL;
ctx->count = 0;
ctx->func = KIMD_SHA_512;
+
+ return 0;
}
-static struct crypto_alg sha512_alg = {
- .cra_name = "sha512",
- .cra_driver_name = "sha512-s390",
- .cra_priority = CRYPT_S390_PRIORITY,
- .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
- .cra_blocksize = SHA512_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct s390_sha_ctx),
- .cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(sha512_alg.cra_list),
- .cra_u = { .digest = {
- .dia_digestsize = SHA512_DIGEST_SIZE,
- .dia_init = sha512_init,
- .dia_update = s390_sha_update,
- .dia_final = s390_sha_final } }
+static struct shash_alg sha512_alg = {
+ .digestsize = SHA512_DIGEST_SIZE,
+ .init = sha512_init,
+ .update = s390_sha_update,
+ .final = s390_sha_final,
+ .descsize = sizeof(struct s390_sha_ctx),
+ .base = {
+ .cra_name = "sha512",
+ .cra_driver_name= "sha512-s390",
+ .cra_priority = CRYPT_S390_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA512_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
};
MODULE_ALIAS("sha512");
-static void sha384_init(struct crypto_tfm *tfm)
+static int sha384_init(struct shash_desc *desc)
{
- struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
*(__u64 *)&ctx->state[0] = 0xcbbb9d5dc1059ed8ULL;
*(__u64 *)&ctx->state[2] = 0x629a292a367cd507ULL;
@@ -67,22 +69,25 @@ static void sha384_init(struct crypto_tfm *tfm)
*(__u64 *)&ctx->state[14] = 0x47b5481dbefa4fa4ULL;
ctx->count = 0;
ctx->func = KIMD_SHA_512;
+
+ return 0;
}
-static struct crypto_alg sha384_alg = {
- .cra_name = "sha384",
- .cra_driver_name = "sha384-s390",
- .cra_priority = CRYPT_S390_PRIORITY,
- .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
- .cra_blocksize = SHA384_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct s390_sha_ctx),
- .cra_module = THIS_MODULE,
- .cra_list = LIST_HEAD_INIT(sha384_alg.cra_list),
- .cra_u = { .digest = {
- .dia_digestsize = SHA384_DIGEST_SIZE,
- .dia_init = sha384_init,
- .dia_update = s390_sha_update,
- .dia_final = s390_sha_final } }
+static struct shash_alg sha384_alg = {
+ .digestsize = SHA384_DIGEST_SIZE,
+ .init = sha384_init,
+ .update = s390_sha_update,
+ .final = s390_sha_final,
+ .descsize = sizeof(struct s390_sha_ctx),
+ .base = {
+ .cra_name = "sha384",
+ .cra_driver_name= "sha384-s390",
+ .cra_priority = CRYPT_S390_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
+ .cra_blocksize = SHA384_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct s390_sha_ctx),
+ .cra_module = THIS_MODULE,
+ }
};
MODULE_ALIAS("sha384");
@@ -93,18 +98,18 @@ static int __init init(void)
if (!crypt_s390_func_available(KIMD_SHA_512))
return -EOPNOTSUPP;
- if ((ret = crypto_register_alg(&sha512_alg)) < 0)
+ if ((ret = crypto_register_shash(&sha512_alg)) < 0)
goto out;
- if ((ret = crypto_register_alg(&sha384_alg)) < 0)
- crypto_unregister_alg(&sha512_alg);
+ if ((ret = crypto_register_shash(&sha384_alg)) < 0)
+ crypto_unregister_shash(&sha512_alg);
out:
return ret;
}
static void __exit fini(void)
{
- crypto_unregister_alg(&sha512_alg);
- crypto_unregister_alg(&sha384_alg);
+ crypto_unregister_shash(&sha512_alg);
+ crypto_unregister_shash(&sha384_alg);
}
module_init(init);
diff --git a/arch/s390/crypto/sha_common.c b/arch/s390/crypto/sha_common.c
index 9d6eb8c3d37e..7903ec47e6b9 100644
--- a/arch/s390/crypto/sha_common.c
+++ b/arch/s390/crypto/sha_common.c
@@ -13,14 +13,14 @@
*
*/
-#include <linux/crypto.h>
+#include <crypto/internal/hash.h>
#include "sha.h"
#include "crypt_s390.h"
-void s390_sha_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
+int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len)
{
- struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm);
- unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
+ struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
+ unsigned int bsize = crypto_shash_blocksize(desc->tfm);
unsigned int index;
int ret;
@@ -51,13 +51,15 @@ void s390_sha_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
store:
if (len)
memcpy(ctx->buf + index , data, len);
+
+ return 0;
}
EXPORT_SYMBOL_GPL(s390_sha_update);
-void s390_sha_final(struct crypto_tfm *tfm, u8 *out)
+int s390_sha_final(struct shash_desc *desc, u8 *out)
{
- struct s390_sha_ctx *ctx = crypto_tfm_ctx(tfm);
- unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
+ struct s390_sha_ctx *ctx = shash_desc_ctx(desc);
+ unsigned int bsize = crypto_shash_blocksize(desc->tfm);
u64 bits;
unsigned int index, end, plen;
int ret;
@@ -87,9 +89,11 @@ void s390_sha_final(struct crypto_tfm *tfm, u8 *out)
BUG_ON(ret != end);
/* copy digest to out */
- memcpy(out, ctx->state, crypto_hash_digestsize(crypto_hash_cast(tfm)));
+ memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
/* wipe context */
memset(ctx, 0, sizeof *ctx);
+
+ return 0;
}
EXPORT_SYMBOL_GPL(s390_sha_final);
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
index b1e892a43816..704dd396257b 100644
--- a/arch/s390/hypfs/hypfs_diag.c
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -12,6 +12,8 @@
#include <linux/types.h>
#include <linux/errno.h>
+#include <linux/gfp.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <asm/ebcdic.h>
diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h
index 8e9243ae0c19..b30606f6d523 100644
--- a/arch/s390/include/asm/bitops.h
+++ b/arch/s390/include/asm/bitops.h
@@ -57,7 +57,7 @@
* with operation of the form "set_bit(bitnr, flags)".
*/
-/* bitmap tables from arch/S390/kernel/bitmap.S */
+/* bitmap tables from arch/s390/kernel/bitmap.c */
extern const char _oi_bitmap[];
extern const char _ni_bitmap[];
extern const char _zb_findmap[];
@@ -525,16 +525,16 @@ static inline unsigned long __ffs_word_loop(const unsigned long *addr,
static inline unsigned long __ffz_word(unsigned long nr, unsigned long word)
{
#ifdef __s390x__
- if (likely((word & 0xffffffff) == 0xffffffff)) {
+ if ((word & 0xffffffff) == 0xffffffff) {
word >>= 32;
nr += 32;
}
#endif
- if (likely((word & 0xffff) == 0xffff)) {
+ if ((word & 0xffff) == 0xffff) {
word >>= 16;
nr += 16;
}
- if (likely((word & 0xff) == 0xff)) {
+ if ((word & 0xff) == 0xff) {
word >>= 8;
nr += 8;
}
@@ -549,16 +549,16 @@ static inline unsigned long __ffz_word(unsigned long nr, unsigned long word)
static inline unsigned long __ffs_word(unsigned long nr, unsigned long word)
{
#ifdef __s390x__
- if (likely((word & 0xffffffff) == 0)) {
+ if ((word & 0xffffffff) == 0) {
word >>= 32;
nr += 32;
}
#endif
- if (likely((word & 0xffff) == 0)) {
+ if ((word & 0xffff) == 0) {
word >>= 16;
nr += 16;
}
- if (likely((word & 0xff) == 0)) {
+ if ((word & 0xff) == 0) {
word >>= 8;
nr += 8;
}
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h
index 6dccb071aec3..619bf94b11f1 100644
--- a/arch/s390/include/asm/cio.h
+++ b/arch/s390/include/asm/cio.h
@@ -456,6 +456,8 @@ struct ciw {
#define CIO_OPER 0x0004
/* Sick revalidation of device. */
#define CIO_REVALIDATE 0x0008
+/* Device did not respond in time. */
+#define CIO_BOXED 0x0010
/**
* struct ccw_dev_id - unique identifier for ccw devices
diff --git a/arch/s390/include/asm/crw.h b/arch/s390/include/asm/crw.h
new file mode 100644
index 000000000000..2185a6d619d3
--- /dev/null
+++ b/arch/s390/include/asm/crw.h
@@ -0,0 +1,68 @@
+/*
+ * Data definitions for channel report processing
+ * Copyright IBM Corp. 2000,2009
+ * Author(s): Ingo Adlung <adlung@de.ibm.com>,
+ * Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ * Cornelia Huck <cornelia.huck@de.ibm.com>,
+ * Heiko Carstens <heiko.carstens@de.ibm.com>,
+ */
+
+#ifndef _ASM_S390_CRW_H
+#define _ASM_S390_CRW_H
+
+#include <linux/types.h>
+
+/*
+ * Channel Report Word
+ */
+struct crw {
+ __u32 res1 : 1; /* reserved zero */
+ __u32 slct : 1; /* solicited */
+ __u32 oflw : 1; /* overflow */
+ __u32 chn : 1; /* chained */
+ __u32 rsc : 4; /* reporting source code */
+ __u32 anc : 1; /* ancillary report */
+ __u32 res2 : 1; /* reserved zero */
+ __u32 erc : 6; /* error-recovery code */
+ __u32 rsid : 16; /* reporting-source ID */
+} __attribute__ ((packed));
+
+typedef void (*crw_handler_t)(struct crw *, struct crw *, int);
+
+extern int crw_register_handler(int rsc, crw_handler_t handler);
+extern void crw_unregister_handler(int rsc);
+extern void crw_handle_channel_report(void);
+
+#define NR_RSCS 16
+
+#define CRW_RSC_MONITOR 0x2 /* monitoring facility */
+#define CRW_RSC_SCH 0x3 /* subchannel */
+#define CRW_RSC_CPATH 0x4 /* channel path */
+#define CRW_RSC_CONFIG 0x9 /* configuration-alert facility */
+#define CRW_RSC_CSS 0xB /* channel subsystem */
+
+#define CRW_ERC_EVENT 0x00 /* event information pending */
+#define CRW_ERC_AVAIL 0x01 /* available */
+#define CRW_ERC_INIT 0x02 /* initialized */
+#define CRW_ERC_TERROR 0x03 /* temporary error */
+#define CRW_ERC_IPARM 0x04 /* installed parm initialized */
+#define CRW_ERC_TERM 0x05 /* terminal */
+#define CRW_ERC_PERRN 0x06 /* perm. error, fac. not init */
+#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */
+#define CRW_ERC_PMOD 0x08 /* installed parameters modified */
+
+static inline int stcrw(struct crw *pcrw)
+{
+ int ccode;
+
+ asm volatile(
+ " stcrw 0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ : "=d" (ccode), "=m" (*pcrw)
+ : "a" (pcrw)
+ : "cc" );
+ return ccode;
+}
+
+#endif /* _ASM_S390_CRW_H */
diff --git a/arch/s390/include/asm/dasd.h b/arch/s390/include/asm/dasd.h
index e2db6f16d9c8..218bce81ec70 100644
--- a/arch/s390/include/asm/dasd.h
+++ b/arch/s390/include/asm/dasd.h
@@ -162,15 +162,15 @@ typedef struct dasd_profile_info_t {
unsigned int dasd_io_nr_req[32]; /* histogram of # of requests in chanq */
} dasd_profile_info_t;
-/*
+/*
* struct format_data_t
* represents all data necessary to format a dasd
*/
typedef struct format_data_t {
- int start_unit; /* from track */
- int stop_unit; /* to track */
- int blksize; /* sectorsize */
- int intensity;
+ unsigned int start_unit; /* from track */
+ unsigned int stop_unit; /* to track */
+ unsigned int blksize; /* sectorsize */
+ unsigned int intensity;
} format_data_t;
/*
diff --git a/arch/s390/include/asm/idals.h b/arch/s390/include/asm/idals.h
index e82c10efe65a..aae276d00383 100644
--- a/arch/s390/include/asm/idals.h
+++ b/arch/s390/include/asm/idals.h
@@ -44,24 +44,18 @@ idal_is_needed(void *vaddr, unsigned int length)
/*
* Return the number of idal words needed for an address/length pair.
*/
-static inline unsigned int
-idal_nr_words(void *vaddr, unsigned int length)
+static inline unsigned int idal_nr_words(void *vaddr, unsigned int length)
{
-#ifdef __s390x__
- if (idal_is_needed(vaddr, length))
- return ((__pa(vaddr) & (IDA_BLOCK_SIZE-1)) + length +
- (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
-#endif
- return 0;
+ return ((__pa(vaddr) & (IDA_BLOCK_SIZE-1)) + length +
+ (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
}
/*
* Create the list of idal words for an address/length pair.
*/
-static inline unsigned long *
-idal_create_words(unsigned long *idaws, void *vaddr, unsigned int length)
+static inline unsigned long *idal_create_words(unsigned long *idaws,
+ void *vaddr, unsigned int length)
{
-#ifdef __s390x__
unsigned long paddr;
unsigned int cidaw;
@@ -74,7 +68,6 @@ idal_create_words(unsigned long *idaws, void *vaddr, unsigned int length)
paddr += IDA_BLOCK_SIZE;
*idaws++ = paddr;
}
-#endif
return idaws;
}
diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h
index e1f54654e3ae..0b2f829f6d50 100644
--- a/arch/s390/include/asm/kvm.h
+++ b/arch/s390/include/asm/kvm.h
@@ -42,4 +42,11 @@ struct kvm_fpu {
__u64 fprs[16];
};
+struct kvm_debug_exit_arch {
+};
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+};
+
#endif
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 3c55e4107dcc..c6e674f5fca9 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -21,9 +21,6 @@
/* memory slots that does not exposed to userspace */
#define KVM_PRIVATE_MEM_SLOTS 4
-struct kvm_guest_debug {
-};
-
struct sca_entry {
atomic_t scn;
__u64 reserved;
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index f3720defdd16..b349f1c7fdfa 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -11,129 +11,118 @@
#ifndef _ASM_S390_LOWCORE_H
#define _ASM_S390_LOWCORE_H
-#ifndef __s390x__
-#define __LC_EXT_OLD_PSW 0x018
-#define __LC_SVC_OLD_PSW 0x020
-#define __LC_PGM_OLD_PSW 0x028
-#define __LC_MCK_OLD_PSW 0x030
-#define __LC_IO_OLD_PSW 0x038
-#define __LC_EXT_NEW_PSW 0x058
-#define __LC_SVC_NEW_PSW 0x060
-#define __LC_PGM_NEW_PSW 0x068
-#define __LC_MCK_NEW_PSW 0x070
-#define __LC_IO_NEW_PSW 0x078
-#else /* !__s390x__ */
-#define __LC_EXT_OLD_PSW 0x0130
-#define __LC_SVC_OLD_PSW 0x0140
-#define __LC_PGM_OLD_PSW 0x0150
-#define __LC_MCK_OLD_PSW 0x0160
-#define __LC_IO_OLD_PSW 0x0170
-#define __LC_EXT_NEW_PSW 0x01b0
-#define __LC_SVC_NEW_PSW 0x01c0
-#define __LC_PGM_NEW_PSW 0x01d0
-#define __LC_MCK_NEW_PSW 0x01e0
-#define __LC_IO_NEW_PSW 0x01f0
-#endif /* !__s390x__ */
-
-#define __LC_IPL_PARMBLOCK_PTR 0x014
-#define __LC_EXT_PARAMS 0x080
-#define __LC_CPU_ADDRESS 0x084
-#define __LC_EXT_INT_CODE 0x086
-
-#define __LC_SVC_ILC 0x088
-#define __LC_SVC_INT_CODE 0x08A
-#define __LC_PGM_ILC 0x08C
-#define __LC_PGM_INT_CODE 0x08E
+#define __LC_IPL_PARMBLOCK_PTR 0x0014
+#define __LC_EXT_PARAMS 0x0080
+#define __LC_CPU_ADDRESS 0x0084
+#define __LC_EXT_INT_CODE 0x0086
-#define __LC_PER_ATMID 0x096
-#define __LC_PER_ADDRESS 0x098
-#define __LC_PER_ACCESS_ID 0x0A1
-#define __LC_AR_MODE_ID 0x0A3
+#define __LC_SVC_ILC 0x0088
+#define __LC_SVC_INT_CODE 0x008a
+#define __LC_PGM_ILC 0x008c
+#define __LC_PGM_INT_CODE 0x008e
-#define __LC_SUBCHANNEL_ID 0x0B8
-#define __LC_SUBCHANNEL_NR 0x0BA
-#define __LC_IO_INT_PARM 0x0BC
-#define __LC_IO_INT_WORD 0x0C0
-#define __LC_MCCK_CODE 0x0E8
+#define __LC_PER_ATMID 0x0096
+#define __LC_PER_ADDRESS 0x0098
+#define __LC_PER_ACCESS_ID 0x00a1
+#define __LC_AR_MODE_ID 0x00a3
-#define __LC_LAST_BREAK 0x110
-
-#define __LC_RETURN_PSW 0x200
-
-#define __LC_SAVE_AREA 0xC00
-
-#ifndef __s390x__
-#define __LC_IRB 0x208
-#define __LC_SYNC_ENTER_TIMER 0x248
-#define __LC_ASYNC_ENTER_TIMER 0x250
-#define __LC_EXIT_TIMER 0x258
-#define __LC_USER_TIMER 0x260
-#define __LC_SYSTEM_TIMER 0x268
-#define __LC_STEAL_TIMER 0x270
-#define __LC_LAST_UPDATE_TIMER 0x278
-#define __LC_LAST_UPDATE_CLOCK 0x280
-#define __LC_RETURN_MCCK_PSW 0x288
-#define __LC_KERNEL_STACK 0xC40
-#define __LC_THREAD_INFO 0xC44
-#define __LC_ASYNC_STACK 0xC48
-#define __LC_KERNEL_ASCE 0xC4C
-#define __LC_USER_ASCE 0xC50
-#define __LC_PANIC_STACK 0xC54
-#define __LC_CPUID 0xC60
-#define __LC_CPUADDR 0xC68
-#define __LC_IPLDEV 0xC7C
-#define __LC_CURRENT 0xC90
-#define __LC_INT_CLOCK 0xC98
-#else /* __s390x__ */
-#define __LC_IRB 0x210
-#define __LC_SYNC_ENTER_TIMER 0x250
-#define __LC_ASYNC_ENTER_TIMER 0x258
-#define __LC_EXIT_TIMER 0x260
-#define __LC_USER_TIMER 0x268
-#define __LC_SYSTEM_TIMER 0x270
-#define __LC_STEAL_TIMER 0x278
-#define __LC_LAST_UPDATE_TIMER 0x280
-#define __LC_LAST_UPDATE_CLOCK 0x288
-#define __LC_RETURN_MCCK_PSW 0x290
-#define __LC_KERNEL_STACK 0xD40
-#define __LC_THREAD_INFO 0xD48
-#define __LC_ASYNC_STACK 0xD50
-#define __LC_KERNEL_ASCE 0xD58
-#define __LC_USER_ASCE 0xD60
-#define __LC_PANIC_STACK 0xD68
-#define __LC_CPUID 0xD80
-#define __LC_CPUADDR 0xD88
-#define __LC_IPLDEV 0xDB8
-#define __LC_CURRENT 0xDD8
-#define __LC_INT_CLOCK 0xDE8
-#define __LC_VDSO_PER_CPU 0xE38
-#endif /* __s390x__ */
+#define __LC_SUBCHANNEL_ID 0x00b8
+#define __LC_SUBCHANNEL_NR 0x00ba
+#define __LC_IO_INT_PARM 0x00bc
+#define __LC_IO_INT_WORD 0x00c0
+#define __LC_MCCK_CODE 0x00e8
-#define __LC_PASTE 0xE40
+#define __LC_DUMP_REIPL 0x0e00
-#define __LC_PANIC_MAGIC 0xE00
#ifndef __s390x__
-#define __LC_PFAULT_INTPARM 0x080
-#define __LC_CPU_TIMER_SAVE_AREA 0x0D8
-#define __LC_CLOCK_COMP_SAVE_AREA 0x0E0
-#define __LC_PSW_SAVE_AREA 0x100
-#define __LC_PREFIX_SAVE_AREA 0x108
-#define __LC_AREGS_SAVE_AREA 0x120
-#define __LC_FPREGS_SAVE_AREA 0x160
-#define __LC_GPREGS_SAVE_AREA 0x180
-#define __LC_CREGS_SAVE_AREA 0x1C0
+#define __LC_EXT_OLD_PSW 0x0018
+#define __LC_SVC_OLD_PSW 0x0020
+#define __LC_PGM_OLD_PSW 0x0028
+#define __LC_MCK_OLD_PSW 0x0030
+#define __LC_IO_OLD_PSW 0x0038
+#define __LC_EXT_NEW_PSW 0x0058
+#define __LC_SVC_NEW_PSW 0x0060
+#define __LC_PGM_NEW_PSW 0x0068
+#define __LC_MCK_NEW_PSW 0x0070
+#define __LC_IO_NEW_PSW 0x0078
+#define __LC_SAVE_AREA 0x0200
+#define __LC_RETURN_PSW 0x0240
+#define __LC_RETURN_MCCK_PSW 0x0248
+#define __LC_SYNC_ENTER_TIMER 0x0250
+#define __LC_ASYNC_ENTER_TIMER 0x0258
+#define __LC_EXIT_TIMER 0x0260
+#define __LC_USER_TIMER 0x0268
+#define __LC_SYSTEM_TIMER 0x0270
+#define __LC_STEAL_TIMER 0x0278
+#define __LC_LAST_UPDATE_TIMER 0x0280
+#define __LC_LAST_UPDATE_CLOCK 0x0288
+#define __LC_CURRENT 0x0290
+#define __LC_THREAD_INFO 0x0294
+#define __LC_KERNEL_STACK 0x0298
+#define __LC_ASYNC_STACK 0x029c
+#define __LC_PANIC_STACK 0x02a0
+#define __LC_KERNEL_ASCE 0x02a4
+#define __LC_USER_ASCE 0x02a8
+#define __LC_USER_EXEC_ASCE 0x02ac
+#define __LC_CPUID 0x02b0
+#define __LC_INT_CLOCK 0x02c8
+#define __LC_IRB 0x0300
+#define __LC_PFAULT_INTPARM 0x0080
+#define __LC_CPU_TIMER_SAVE_AREA 0x00d8
+#define __LC_CLOCK_COMP_SAVE_AREA 0x00e0
+#define __LC_PSW_SAVE_AREA 0x0100
+#define __LC_PREFIX_SAVE_AREA 0x0108
+#define __LC_AREGS_SAVE_AREA 0x0120
+#define __LC_FPREGS_SAVE_AREA 0x0160
+#define __LC_GPREGS_SAVE_AREA 0x0180
+#define __LC_CREGS_SAVE_AREA 0x01c0
#else /* __s390x__ */
-#define __LC_PFAULT_INTPARM 0x11B8
+#define __LC_LAST_BREAK 0x0110
+#define __LC_EXT_OLD_PSW 0x0130
+#define __LC_SVC_OLD_PSW 0x0140
+#define __LC_PGM_OLD_PSW 0x0150
+#define __LC_MCK_OLD_PSW 0x0160
+#define __LC_IO_OLD_PSW 0x0170
+#define __LC_EXT_NEW_PSW 0x01b0
+#define __LC_SVC_NEW_PSW 0x01c0
+#define __LC_PGM_NEW_PSW 0x01d0
+#define __LC_MCK_NEW_PSW 0x01e0
+#define __LC_IO_NEW_PSW 0x01f0
+#define __LC_SAVE_AREA 0x0200
+#define __LC_RETURN_PSW 0x0280
+#define __LC_RETURN_MCCK_PSW 0x0290
+#define __LC_SYNC_ENTER_TIMER 0x02a0
+#define __LC_ASYNC_ENTER_TIMER 0x02a8
+#define __LC_EXIT_TIMER 0x02b0
+#define __LC_USER_TIMER 0x02b8
+#define __LC_SYSTEM_TIMER 0x02c0
+#define __LC_STEAL_TIMER 0x02c8
+#define __LC_LAST_UPDATE_TIMER 0x02d0
+#define __LC_LAST_UPDATE_CLOCK 0x02d8
+#define __LC_CURRENT 0x02e0
+#define __LC_THREAD_INFO 0x02e8
+#define __LC_KERNEL_STACK 0x02f0
+#define __LC_ASYNC_STACK 0x02f8
+#define __LC_PANIC_STACK 0x0300
+#define __LC_KERNEL_ASCE 0x0308
+#define __LC_USER_ASCE 0x0310
+#define __LC_USER_EXEC_ASCE 0x0318
+#define __LC_CPUID 0x0320
+#define __LC_INT_CLOCK 0x0340
+#define __LC_VDSO_PER_CPU 0x0350
+#define __LC_IRB 0x0380
+#define __LC_PASTE 0x03c0
+#define __LC_PFAULT_INTPARM 0x11b8
#define __LC_FPREGS_SAVE_AREA 0x1200
-#define __LC_GPREGS_SAVE_AREA 0x1280
+#define __LC_GPREGS_SAVE_AREA 0x1280
#define __LC_PSW_SAVE_AREA 0x1300
#define __LC_PREFIX_SAVE_AREA 0x1318
-#define __LC_FP_CREG_SAVE_AREA 0x131C
+#define __LC_FP_CREG_SAVE_AREA 0x131c
#define __LC_TODREG_SAVE_AREA 0x1324
-#define __LC_CPU_TIMER_SAVE_AREA 0x1328
+#define __LC_CPU_TIMER_SAVE_AREA 0x1328
#define __LC_CLOCK_COMP_SAVE_AREA 0x1331
-#define __LC_AREGS_SAVE_AREA 0x1340
-#define __LC_CREGS_SAVE_AREA 0x1380
+#define __LC_AREGS_SAVE_AREA 0x1340
+#define __LC_CREGS_SAVE_AREA 0x1380
#endif /* __s390x__ */
#ifndef __ASSEMBLY__
@@ -198,222 +187,240 @@ union save_area {
struct _lowcore
{
#ifndef __s390x__
- /* prefix area: defined by architecture */
- psw_t restart_psw; /* 0x000 */
- __u32 ccw2[4]; /* 0x008 */
- psw_t external_old_psw; /* 0x018 */
- psw_t svc_old_psw; /* 0x020 */
- psw_t program_old_psw; /* 0x028 */
- psw_t mcck_old_psw; /* 0x030 */
- psw_t io_old_psw; /* 0x038 */
- __u8 pad1[0x58-0x40]; /* 0x040 */
- psw_t external_new_psw; /* 0x058 */
- psw_t svc_new_psw; /* 0x060 */
- psw_t program_new_psw; /* 0x068 */
- psw_t mcck_new_psw; /* 0x070 */
- psw_t io_new_psw; /* 0x078 */
- __u32 ext_params; /* 0x080 */
- __u16 cpu_addr; /* 0x084 */
- __u16 ext_int_code; /* 0x086 */
- __u16 svc_ilc; /* 0x088 */
- __u16 svc_code; /* 0x08a */
- __u16 pgm_ilc; /* 0x08c */
- __u16 pgm_code; /* 0x08e */
- __u32 trans_exc_code; /* 0x090 */
- __u16 mon_class_num; /* 0x094 */
- __u16 per_perc_atmid; /* 0x096 */
- __u32 per_address; /* 0x098 */
- __u32 monitor_code; /* 0x09c */
- __u8 exc_access_id; /* 0x0a0 */
- __u8 per_access_id; /* 0x0a1 */
- __u8 pad2[0xB8-0xA2]; /* 0x0a2 */
- __u16 subchannel_id; /* 0x0b8 */
- __u16 subchannel_nr; /* 0x0ba */
- __u32 io_int_parm; /* 0x0bc */
- __u32 io_int_word; /* 0x0c0 */
- __u8 pad3[0xc8-0xc4]; /* 0x0c4 */
- __u32 stfl_fac_list; /* 0x0c8 */
- __u8 pad4[0xd4-0xcc]; /* 0x0cc */
- __u32 extended_save_area_addr; /* 0x0d4 */
- __u32 cpu_timer_save_area[2]; /* 0x0d8 */
- __u32 clock_comp_save_area[2]; /* 0x0e0 */
- __u32 mcck_interruption_code[2]; /* 0x0e8 */
- __u8 pad5[0xf4-0xf0]; /* 0x0f0 */
- __u32 external_damage_code; /* 0x0f4 */
- __u32 failing_storage_address; /* 0x0f8 */
- __u8 pad6[0x100-0xfc]; /* 0x0fc */
- __u32 st_status_fixed_logout[4];/* 0x100 */
- __u8 pad7[0x120-0x110]; /* 0x110 */
- __u32 access_regs_save_area[16];/* 0x120 */
- __u32 floating_pt_save_area[8]; /* 0x160 */
- __u32 gpregs_save_area[16]; /* 0x180 */
- __u32 cregs_save_area[16]; /* 0x1c0 */
-
- psw_t return_psw; /* 0x200 */
- __u8 irb[64]; /* 0x208 */
- __u64 sync_enter_timer; /* 0x248 */
- __u64 async_enter_timer; /* 0x250 */
- __u64 exit_timer; /* 0x258 */
- __u64 user_timer; /* 0x260 */
- __u64 system_timer; /* 0x268 */
- __u64 steal_timer; /* 0x270 */
- __u64 last_update_timer; /* 0x278 */
- __u64 last_update_clock; /* 0x280 */
- psw_t return_mcck_psw; /* 0x288 */
- __u8 pad8[0xc00-0x290]; /* 0x290 */
-
- /* System info area */
- __u32 save_area[16]; /* 0xc00 */
- __u32 kernel_stack; /* 0xc40 */
- __u32 thread_info; /* 0xc44 */
- __u32 async_stack; /* 0xc48 */
- __u32 kernel_asce; /* 0xc4c */
- __u32 user_asce; /* 0xc50 */
- __u32 panic_stack; /* 0xc54 */
- __u32 user_exec_asce; /* 0xc58 */
- __u8 pad10[0xc60-0xc5c]; /* 0xc5c */
- /* entry.S sensitive area start */
- struct cpuinfo_S390 cpu_data; /* 0xc60 */
- __u32 ipl_device; /* 0xc7c */
- /* entry.S sensitive area end */
-
- /* SMP info area: defined by DJB */
- __u64 clock_comparator; /* 0xc80 */
- __u32 ext_call_fast; /* 0xc88 */
- __u32 percpu_offset; /* 0xc8c */
- __u32 current_task; /* 0xc90 */
- __u32 softirq_pending; /* 0xc94 */
- __u64 int_clock; /* 0xc98 */
- __u8 pad11[0xe00-0xca0]; /* 0xca0 */
-
- /* 0xe00 is used as indicator for dump tools */
- /* whether the kernel died with panic() or not */
- __u32 panic_magic; /* 0xe00 */
-
- /* Align to the top 1k of prefix area */
- __u8 pad12[0x1000-0xe04]; /* 0xe04 */
+ /* 0x0000 - 0x01ff: defined by architecture */
+ psw_t restart_psw; /* 0x0000 */
+ __u32 ccw2[4]; /* 0x0008 */
+ psw_t external_old_psw; /* 0x0018 */
+ psw_t svc_old_psw; /* 0x0020 */
+ psw_t program_old_psw; /* 0x0028 */
+ psw_t mcck_old_psw; /* 0x0030 */
+ psw_t io_old_psw; /* 0x0038 */
+ __u8 pad_0x0040[0x0058-0x0040]; /* 0x0040 */
+ psw_t external_new_psw; /* 0x0058 */
+ psw_t svc_new_psw; /* 0x0060 */
+ psw_t program_new_psw; /* 0x0068 */
+ psw_t mcck_new_psw; /* 0x0070 */
+ psw_t io_new_psw; /* 0x0078 */
+ __u32 ext_params; /* 0x0080 */
+ __u16 cpu_addr; /* 0x0084 */
+ __u16 ext_int_code; /* 0x0086 */
+ __u16 svc_ilc; /* 0x0088 */
+ __u16 svc_code; /* 0x008a */
+ __u16 pgm_ilc; /* 0x008c */
+ __u16 pgm_code; /* 0x008e */
+ __u32 trans_exc_code; /* 0x0090 */
+ __u16 mon_class_num; /* 0x0094 */
+ __u16 per_perc_atmid; /* 0x0096 */
+ __u32 per_address; /* 0x0098 */
+ __u32 monitor_code; /* 0x009c */
+ __u8 exc_access_id; /* 0x00a0 */
+ __u8 per_access_id; /* 0x00a1 */
+ __u8 pad_0x00a2[0x00b8-0x00a2]; /* 0x00a2 */
+ __u16 subchannel_id; /* 0x00b8 */
+ __u16 subchannel_nr; /* 0x00ba */
+ __u32 io_int_parm; /* 0x00bc */
+ __u32 io_int_word; /* 0x00c0 */
+ __u8 pad_0x00c4[0x00c8-0x00c4]; /* 0x00c4 */
+ __u32 stfl_fac_list; /* 0x00c8 */
+ __u8 pad_0x00cc[0x00d4-0x00cc]; /* 0x00cc */
+ __u32 extended_save_area_addr; /* 0x00d4 */
+ __u32 cpu_timer_save_area[2]; /* 0x00d8 */
+ __u32 clock_comp_save_area[2]; /* 0x00e0 */
+ __u32 mcck_interruption_code[2]; /* 0x00e8 */
+ __u8 pad_0x00f0[0x00f4-0x00f0]; /* 0x00f0 */
+ __u32 external_damage_code; /* 0x00f4 */
+ __u32 failing_storage_address; /* 0x00f8 */
+ __u8 pad_0x00fc[0x0100-0x00fc]; /* 0x00fc */
+ __u32 st_status_fixed_logout[4]; /* 0x0100 */
+ __u8 pad_0x0110[0x0120-0x0110]; /* 0x0110 */
+
+ /* CPU register save area: defined by architecture */
+ __u32 access_regs_save_area[16]; /* 0x0120 */
+ __u32 floating_pt_save_area[8]; /* 0x0160 */
+ __u32 gpregs_save_area[16]; /* 0x0180 */
+ __u32 cregs_save_area[16]; /* 0x01c0 */
+
+ /* Return psws. */
+ __u32 save_area[16]; /* 0x0200 */
+ psw_t return_psw; /* 0x0240 */
+ psw_t return_mcck_psw; /* 0x0248 */
+
+ /* CPU time accounting values */
+ __u64 sync_enter_timer; /* 0x0250 */
+ __u64 async_enter_timer; /* 0x0258 */
+ __u64 exit_timer; /* 0x0260 */
+ __u64 user_timer; /* 0x0268 */
+ __u64 system_timer; /* 0x0270 */
+ __u64 steal_timer; /* 0x0278 */
+ __u64 last_update_timer; /* 0x0280 */
+ __u64 last_update_clock; /* 0x0288 */
+
+ /* Current process. */
+ __u32 current_task; /* 0x0290 */
+ __u32 thread_info; /* 0x0294 */
+ __u32 kernel_stack; /* 0x0298 */
+
+ /* Interrupt and panic stack. */
+ __u32 async_stack; /* 0x029c */
+ __u32 panic_stack; /* 0x02a0 */
+
+ /* Address space pointer. */
+ __u32 kernel_asce; /* 0x02a4 */
+ __u32 user_asce; /* 0x02a8 */
+ __u32 user_exec_asce; /* 0x02ac */
+
+ /* SMP info area */
+ cpuid_t cpu_id; /* 0x02b0 */
+ __u32 cpu_nr; /* 0x02b8 */
+ __u32 softirq_pending; /* 0x02bc */
+ __u32 percpu_offset; /* 0x02c0 */
+ __u32 ext_call_fast; /* 0x02c4 */
+ __u64 int_clock; /* 0x02c8 */
+ __u64 clock_comparator; /* 0x02d0 */
+ __u8 pad_0x02d8[0x0300-0x02d8]; /* 0x02d8 */
+
+ /* Interrupt response block */
+ __u8 irb[64]; /* 0x0300 */
+
+ __u8 pad_0x0400[0x0e00-0x0400]; /* 0x0400 */
+
+ /*
+ * 0xe00 contains the address of the IPL Parameter Information
+ * block. Dump tools need IPIB for IPL after dump.
+ * Note: do not change the position of any fields in 0x0e00-0x0f00
+ */
+ __u32 ipib; /* 0x0e00 */
+ __u32 ipib_checksum; /* 0x0e04 */
+
+ /* Align to the top 1k of prefix area */
+ __u8 pad_0x0e08[0x1000-0x0e08]; /* 0x0e08 */
#else /* !__s390x__ */
- /* prefix area: defined by architecture */
- __u32 ccw1[2]; /* 0x000 */
- __u32 ccw2[4]; /* 0x008 */
- __u8 pad1[0x80-0x18]; /* 0x018 */
- __u32 ext_params; /* 0x080 */
- __u16 cpu_addr; /* 0x084 */
- __u16 ext_int_code; /* 0x086 */
- __u16 svc_ilc; /* 0x088 */
- __u16 svc_code; /* 0x08a */
- __u16 pgm_ilc; /* 0x08c */
- __u16 pgm_code; /* 0x08e */
- __u32 data_exc_code; /* 0x090 */
- __u16 mon_class_num; /* 0x094 */
- __u16 per_perc_atmid; /* 0x096 */
- addr_t per_address; /* 0x098 */
- __u8 exc_access_id; /* 0x0a0 */
- __u8 per_access_id; /* 0x0a1 */
- __u8 op_access_id; /* 0x0a2 */
- __u8 ar_access_id; /* 0x0a3 */
- __u8 pad2[0xA8-0xA4]; /* 0x0a4 */
- addr_t trans_exc_code; /* 0x0A0 */
- addr_t monitor_code; /* 0x09c */
- __u16 subchannel_id; /* 0x0b8 */
- __u16 subchannel_nr; /* 0x0ba */
- __u32 io_int_parm; /* 0x0bc */
- __u32 io_int_word; /* 0x0c0 */
- __u8 pad3[0xc8-0xc4]; /* 0x0c4 */
- __u32 stfl_fac_list; /* 0x0c8 */
- __u8 pad4[0xe8-0xcc]; /* 0x0cc */
- __u32 mcck_interruption_code[2]; /* 0x0e8 */
- __u8 pad5[0xf4-0xf0]; /* 0x0f0 */
- __u32 external_damage_code; /* 0x0f4 */
- addr_t failing_storage_address; /* 0x0f8 */
- __u8 pad6[0x120-0x100]; /* 0x100 */
- psw_t restart_old_psw; /* 0x120 */
- psw_t external_old_psw; /* 0x130 */
- psw_t svc_old_psw; /* 0x140 */
- psw_t program_old_psw; /* 0x150 */
- psw_t mcck_old_psw; /* 0x160 */
- psw_t io_old_psw; /* 0x170 */
- __u8 pad7[0x1a0-0x180]; /* 0x180 */
- psw_t restart_psw; /* 0x1a0 */
- psw_t external_new_psw; /* 0x1b0 */
- psw_t svc_new_psw; /* 0x1c0 */
- psw_t program_new_psw; /* 0x1d0 */
- psw_t mcck_new_psw; /* 0x1e0 */
- psw_t io_new_psw; /* 0x1f0 */
- psw_t return_psw; /* 0x200 */
- __u8 irb[64]; /* 0x210 */
- __u64 sync_enter_timer; /* 0x250 */
- __u64 async_enter_timer; /* 0x258 */
- __u64 exit_timer; /* 0x260 */
- __u64 user_timer; /* 0x268 */
- __u64 system_timer; /* 0x270 */
- __u64 steal_timer; /* 0x278 */
- __u64 last_update_timer; /* 0x280 */
- __u64 last_update_clock; /* 0x288 */
- psw_t return_mcck_psw; /* 0x290 */
- __u8 pad8[0xc00-0x2a0]; /* 0x2a0 */
- /* System info area */
- __u64 save_area[16]; /* 0xc00 */
- __u8 pad9[0xd40-0xc80]; /* 0xc80 */
- __u64 kernel_stack; /* 0xd40 */
- __u64 thread_info; /* 0xd48 */
- __u64 async_stack; /* 0xd50 */
- __u64 kernel_asce; /* 0xd58 */
- __u64 user_asce; /* 0xd60 */
- __u64 panic_stack; /* 0xd68 */
- __u64 user_exec_asce; /* 0xd70 */
- __u8 pad10[0xd80-0xd78]; /* 0xd78 */
- /* entry.S sensitive area start */
- struct cpuinfo_S390 cpu_data; /* 0xd80 */
- __u32 ipl_device; /* 0xdb8 */
- __u32 pad11; /* 0xdbc */
- /* entry.S sensitive area end */
-
- /* SMP info area: defined by DJB */
- __u64 clock_comparator; /* 0xdc0 */
- __u64 ext_call_fast; /* 0xdc8 */
- __u64 percpu_offset; /* 0xdd0 */
- __u64 current_task; /* 0xdd8 */
- __u32 softirq_pending; /* 0xde0 */
- __u32 pad_0x0de4; /* 0xde4 */
- __u64 int_clock; /* 0xde8 */
- __u8 pad12[0xe00-0xdf0]; /* 0xdf0 */
-
- /* 0xe00 is used as indicator for dump tools */
- /* whether the kernel died with panic() or not */
- __u32 panic_magic; /* 0xe00 */
+ /* 0x0000 - 0x01ff: defined by architecture */
+ __u32 ccw1[2]; /* 0x0000 */
+ __u32 ccw2[4]; /* 0x0008 */
+ __u8 pad_0x0018[0x0080-0x0018]; /* 0x0018 */
+ __u32 ext_params; /* 0x0080 */
+ __u16 cpu_addr; /* 0x0084 */
+ __u16 ext_int_code; /* 0x0086 */
+ __u16 svc_ilc; /* 0x0088 */
+ __u16 svc_code; /* 0x008a */
+ __u16 pgm_ilc; /* 0x008c */
+ __u16 pgm_code; /* 0x008e */
+ __u32 data_exc_code; /* 0x0090 */
+ __u16 mon_class_num; /* 0x0094 */
+ __u16 per_perc_atmid; /* 0x0096 */
+ addr_t per_address; /* 0x0098 */
+ __u8 exc_access_id; /* 0x00a0 */
+ __u8 per_access_id; /* 0x00a1 */
+ __u8 op_access_id; /* 0x00a2 */
+ __u8 ar_access_id; /* 0x00a3 */
+ __u8 pad_0x00a4[0x00a8-0x00a4]; /* 0x00a4 */
+ addr_t trans_exc_code; /* 0x00a8 */
+ addr_t monitor_code; /* 0x00b0 */
+ __u16 subchannel_id; /* 0x00b8 */
+ __u16 subchannel_nr; /* 0x00ba */
+ __u32 io_int_parm; /* 0x00bc */
+ __u32 io_int_word; /* 0x00c0 */
+ __u8 pad_0x00c4[0x00c8-0x00c4]; /* 0x00c4 */
+ __u32 stfl_fac_list; /* 0x00c8 */
+ __u8 pad_0x00cc[0x00e8-0x00cc]; /* 0x00cc */
+ __u32 mcck_interruption_code[2]; /* 0x00e8 */
+ __u8 pad_0x00f0[0x00f4-0x00f0]; /* 0x00f0 */
+ __u32 external_damage_code; /* 0x00f4 */
+ addr_t failing_storage_address; /* 0x00f8 */
+ __u8 pad_0x0100[0x0120-0x0100]; /* 0x0100 */
+ psw_t restart_old_psw; /* 0x0120 */
+ psw_t external_old_psw; /* 0x0130 */
+ psw_t svc_old_psw; /* 0x0140 */
+ psw_t program_old_psw; /* 0x0150 */
+ psw_t mcck_old_psw; /* 0x0160 */
+ psw_t io_old_psw; /* 0x0170 */
+ __u8 pad_0x0180[0x01a0-0x0180]; /* 0x0180 */
+ psw_t restart_psw; /* 0x01a0 */
+ psw_t external_new_psw; /* 0x01b0 */
+ psw_t svc_new_psw; /* 0x01c0 */
+ psw_t program_new_psw; /* 0x01d0 */
+ psw_t mcck_new_psw; /* 0x01e0 */
+ psw_t io_new_psw; /* 0x01f0 */
+
+ /* Entry/exit save area & return psws. */
+ __u64 save_area[16]; /* 0x0200 */
+ psw_t return_psw; /* 0x0280 */
+ psw_t return_mcck_psw; /* 0x0290 */
+
+ /* CPU accounting and timing values. */
+ __u64 sync_enter_timer; /* 0x02a0 */
+ __u64 async_enter_timer; /* 0x02a8 */
+ __u64 exit_timer; /* 0x02b0 */
+ __u64 user_timer; /* 0x02b8 */
+ __u64 system_timer; /* 0x02c0 */
+ __u64 steal_timer; /* 0x02c8 */
+ __u64 last_update_timer; /* 0x02d0 */
+ __u64 last_update_clock; /* 0x02d8 */
+
+ /* Current process. */
+ __u64 current_task; /* 0x02e0 */
+ __u64 thread_info; /* 0x02e8 */
+ __u64 kernel_stack; /* 0x02f0 */
+
+ /* Interrupt and panic stack. */
+ __u64 async_stack; /* 0x02f8 */
+ __u64 panic_stack; /* 0x0300 */
+
+ /* Address space pointer. */
+ __u64 kernel_asce; /* 0x0308 */
+ __u64 user_asce; /* 0x0310 */
+ __u64 user_exec_asce; /* 0x0318 */
+
+ /* SMP info area */
+ cpuid_t cpu_id; /* 0x0320 */
+ __u32 cpu_nr; /* 0x0328 */
+ __u32 softirq_pending; /* 0x032c */
+ __u64 percpu_offset; /* 0x0330 */
+ __u64 ext_call_fast; /* 0x0338 */
+ __u64 int_clock; /* 0x0340 */
+ __u64 clock_comparator; /* 0x0348 */
+ __u64 vdso_per_cpu_data; /* 0x0350 */
+ __u8 pad_0x0358[0x0380-0x0358]; /* 0x0358 */
+
+ /* Interrupt response block. */
+ __u8 irb[64]; /* 0x0380 */
/* Per cpu primary space access list */
- __u8 pad_0xe04[0xe38-0xe04]; /* 0xe04 */
- __u64 vdso_per_cpu_data; /* 0xe38 */
- __u32 paste[16]; /* 0xe40 */
-
- __u8 pad13[0x11b8-0xe80]; /* 0xe80 */
-
- /* 64 bit extparam used for pfault, diag 250 etc */
- __u64 ext_params2; /* 0x11B8 */
-
- __u8 pad14[0x1200-0x11C0]; /* 0x11C0 */
-
- /* System info area */
-
- __u64 floating_pt_save_area[16]; /* 0x1200 */
- __u64 gpregs_save_area[16]; /* 0x1280 */
- __u32 st_status_fixed_logout[4]; /* 0x1300 */
- __u8 pad15[0x1318-0x1310]; /* 0x1310 */
- __u32 prefixreg_save_area; /* 0x1318 */
- __u32 fpt_creg_save_area; /* 0x131c */
- __u8 pad16[0x1324-0x1320]; /* 0x1320 */
- __u32 tod_progreg_save_area; /* 0x1324 */
- __u32 cpu_timer_save_area[2]; /* 0x1328 */
- __u32 clock_comp_save_area[2]; /* 0x1330 */
- __u8 pad17[0x1340-0x1338]; /* 0x1338 */
- __u32 access_regs_save_area[16]; /* 0x1340 */
- __u64 cregs_save_area[16]; /* 0x1380 */
+ __u32 paste[16]; /* 0x03c0 */
+
+ __u8 pad_0x0400[0x0e00-0x0400]; /* 0x0400 */
+
+ /*
+ * 0xe00 contains the address of the IPL Parameter Information
+ * block. Dump tools need IPIB for IPL after dump.
+ * Note: do not change the position of any fields in 0x0e00-0x0f00
+ */
+ __u64 ipib; /* 0x0e00 */
+ __u32 ipib_checksum; /* 0x0e08 */
+ __u8 pad_0x0e0c[0x11b8-0x0e0c]; /* 0x0e0c */
+
+ /* 64 bit extparam used for pfault/diag 250: defined by architecture */
+ __u64 ext_params2; /* 0x11B8 */
+ __u8 pad_0x11c0[0x1200-0x11C0]; /* 0x11C0 */
+
+ /* CPU register save area: defined by architecture */
+ __u64 floating_pt_save_area[16]; /* 0x1200 */
+ __u64 gpregs_save_area[16]; /* 0x1280 */
+ __u32 st_status_fixed_logout[4]; /* 0x1300 */
+ __u8 pad_0x1310[0x1318-0x1310]; /* 0x1310 */
+ __u32 prefixreg_save_area; /* 0x1318 */
+ __u32 fpt_creg_save_area; /* 0x131c */
+ __u8 pad_0x1320[0x1324-0x1320]; /* 0x1320 */
+ __u32 tod_progreg_save_area; /* 0x1324 */
+ __u32 cpu_timer_save_area[2]; /* 0x1328 */
+ __u32 clock_comp_save_area[2]; /* 0x1330 */
+ __u8 pad_0x1338[0x1340-0x1338]; /* 0x1338 */
+ __u32 access_regs_save_area[16]; /* 0x1340 */
+ __u64 cregs_save_area[16]; /* 0x1380 */
/* align to the top of the prefix area */
-
- __u8 pad18[0x2000-0x1400]; /* 0x1400 */
+ __u8 pad_0x1400[0x2000-0x1400]; /* 0x1400 */
#endif /* !__s390x__ */
} __attribute__((packed)); /* End structure*/
@@ -433,8 +440,6 @@ static inline __u32 store_prefix(void)
return address;
}
-#define __PANIC_MAGIC 0xDEADC0DE
-
#endif
#endif
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h
index 28ec870655af..fc7edd6f41b6 100644
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -74,7 +74,7 @@ static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk)
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
{
- cpu_set(smp_processor_id(), next->cpu_vm_mask);
+ cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
update_mm(next, tsk);
}
diff --git a/arch/s390/include/asm/nmi.h b/arch/s390/include/asm/nmi.h
new file mode 100644
index 000000000000..f4b60441adca
--- /dev/null
+++ b/arch/s390/include/asm/nmi.h
@@ -0,0 +1,66 @@
+/*
+ * Machine check handler definitions
+ *
+ * Copyright IBM Corp. 2000,2009
+ * Author(s): Ingo Adlung <adlung@de.ibm.com>,
+ * Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ * Cornelia Huck <cornelia.huck@de.ibm.com>,
+ * Heiko Carstens <heiko.carstens@de.ibm.com>,
+ */
+
+#ifndef _ASM_S390_NMI_H
+#define _ASM_S390_NMI_H
+
+#include <linux/types.h>
+
+struct mci {
+ __u32 sd : 1; /* 00 system damage */
+ __u32 pd : 1; /* 01 instruction-processing damage */
+ __u32 sr : 1; /* 02 system recovery */
+ __u32 : 1; /* 03 */
+ __u32 cd : 1; /* 04 timing-facility damage */
+ __u32 ed : 1; /* 05 external damage */
+ __u32 : 1; /* 06 */
+ __u32 dg : 1; /* 07 degradation */
+ __u32 w : 1; /* 08 warning pending */
+ __u32 cp : 1; /* 09 channel-report pending */
+ __u32 sp : 1; /* 10 service-processor damage */
+ __u32 ck : 1; /* 11 channel-subsystem damage */
+ __u32 : 2; /* 12-13 */
+ __u32 b : 1; /* 14 backed up */
+ __u32 : 1; /* 15 */
+ __u32 se : 1; /* 16 storage error uncorrected */
+ __u32 sc : 1; /* 17 storage error corrected */
+ __u32 ke : 1; /* 18 storage-key error uncorrected */
+ __u32 ds : 1; /* 19 storage degradation */
+ __u32 wp : 1; /* 20 psw mwp validity */
+ __u32 ms : 1; /* 21 psw mask and key validity */
+ __u32 pm : 1; /* 22 psw program mask and cc validity */
+ __u32 ia : 1; /* 23 psw instruction address validity */
+ __u32 fa : 1; /* 24 failing storage address validity */
+ __u32 : 1; /* 25 */
+ __u32 ec : 1; /* 26 external damage code validity */
+ __u32 fp : 1; /* 27 floating point register validity */
+ __u32 gr : 1; /* 28 general register validity */
+ __u32 cr : 1; /* 29 control register validity */
+ __u32 : 1; /* 30 */
+ __u32 st : 1; /* 31 storage logical validity */
+ __u32 ie : 1; /* 32 indirect storage error */
+ __u32 ar : 1; /* 33 access register validity */
+ __u32 da : 1; /* 34 delayed access exception */
+ __u32 : 7; /* 35-41 */
+ __u32 pr : 1; /* 42 tod programmable register validity */
+ __u32 fc : 1; /* 43 fp control register validity */
+ __u32 ap : 1; /* 44 ancillary report */
+ __u32 : 1; /* 45 */
+ __u32 ct : 1; /* 46 cpu timer validity */
+ __u32 cc : 1; /* 47 clock comparator validity */
+ __u32 : 16; /* 47-63 */
+};
+
+struct pt_regs;
+
+extern void s390_handle_mcck(void);
+extern void s390_do_machine_check(struct pt_regs *regs);
+
+#endif /* _ASM_S390_NMI_H */
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index db4523fe38ac..61862b3ac794 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -42,22 +42,8 @@ static inline void get_cpu_id(cpuid_t *ptr)
asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr));
}
-struct cpuinfo_S390
-{
- cpuid_t cpu_id;
- __u16 cpu_addr;
- __u16 cpu_nr;
- unsigned long loops_per_jiffy;
- unsigned long *pgd_quick;
-#ifdef __s390x__
- unsigned long *pmd_quick;
-#endif /* __s390x__ */
- unsigned long *pte_quick;
- unsigned long pgtable_cache_sz;
-};
-
extern void s390_adjust_jiffies(void);
-extern void print_cpu_info(struct cpuinfo_S390 *);
+extern void print_cpu_info(void);
extern int get_cpu_capability(unsigned int *);
/*
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index 8920025c3c02..f1b051630c50 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -172,6 +172,8 @@
#define NUM_CRS 16
#define NUM_ACRS 16
+#define NUM_CR_WORDS 3
+
#define FPR_SIZE 8
#define FPC_SIZE 4
#define FPC_PAD_SIZE 4 /* gcc insists on aligning the fpregs */
@@ -334,7 +336,7 @@ struct pt_regs
*/
typedef struct
{
- unsigned long cr[3];
+ unsigned long cr[NUM_CR_WORDS];
} per_cr_words;
#define PER_EM_MASK 0xE8000000UL
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
index 27fc1746de15..402d6dcf0d26 100644
--- a/arch/s390/include/asm/qdio.h
+++ b/arch/s390/include/asm/qdio.h
@@ -314,6 +314,7 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
int, int, unsigned long);
/* qdio errors reported to the upper-layer program */
+#define QDIO_ERROR_SIGA_TARGET 0x02
#define QDIO_ERROR_SIGA_ACCESS_EXCEPTION 0x10
#define QDIO_ERROR_SIGA_BUSY 0x20
#define QDIO_ERROR_ACTIVATE_CHECK_CONDITION 0x40
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index 024b91e06239..72137bc907ac 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -50,12 +50,7 @@ extern void machine_power_off_smp(void);
#define PROC_CHANGE_PENALTY 20 /* Schedule penalty */
-#define raw_smp_processor_id() (S390_lowcore.cpu_data.cpu_nr)
-
-static inline __u16 hard_smp_processor_id(void)
-{
- return stap();
-}
+#define raw_smp_processor_id() (S390_lowcore.cpu_nr)
/*
* returns 1 if cpu is in stopped/check stopped state or not operational
@@ -97,12 +92,6 @@ extern void arch_send_call_function_ipi(cpumask_t mask);
#endif
#ifndef CONFIG_SMP
-static inline void smp_send_stop(void)
-{
- /* Disable all interrupts/machine checks */
- __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
-}
-
#define hard_smp_processor_id() 0
#define smp_cpu_not_running(cpu) 1
#endif
diff --git a/arch/s390/include/asm/socket.h b/arch/s390/include/asm/socket.h
index c786ab623b2d..02330c50241b 100644
--- a/arch/s390/include/asm/socket.h
+++ b/arch/s390/include/asm/socket.h
@@ -62,4 +62,7 @@
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
#endif /* _ASM_SOCKET_H */
diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h
index df84ae96915f..f3861b09ebb0 100644
--- a/arch/s390/include/asm/spinlock.h
+++ b/arch/s390/include/asm/spinlock.h
@@ -172,6 +172,9 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
return _raw_write_trylock_retry(rw);
}
+#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
+#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+
#define _raw_read_relax(lock) cpu_relax()
#define _raw_write_relax(lock) cpu_relax()
diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h
index d074673a6d9b..cd0241db5a46 100644
--- a/arch/s390/include/asm/string.h
+++ b/arch/s390/include/asm/string.h
@@ -100,6 +100,7 @@ static inline char *strcat(char *dst, const char *src)
static inline char *strcpy(char *dst, const char *src)
{
+#if __GNUC__ < 4
register int r0 asm("0") = 0;
char *ret = dst;
@@ -109,10 +110,14 @@ static inline char *strcpy(char *dst, const char *src)
: "+&a" (dst), "+&a" (src) : "d" (r0)
: "cc", "memory");
return ret;
+#else
+ return __builtin_strcpy(dst, src);
+#endif
}
static inline size_t strlen(const char *s)
{
+#if __GNUC__ < 4
register unsigned long r0 asm("0") = 0;
const char *tmp = s;
@@ -121,6 +126,9 @@ static inline size_t strlen(const char *s)
" jo 0b"
: "+d" (r0), "+a" (tmp) : : "cc");
return r0 - (unsigned long) s;
+#else
+ return __builtin_strlen(s);
+#endif
}
static inline size_t strnlen(const char * s, size_t n)
@@ -135,7 +143,13 @@ static inline size_t strnlen(const char * s, size_t n)
: "+a" (end), "+a" (tmp) : "d" (r0) : "cc");
return end - s;
}
-
+#else /* IN_ARCH_STRING_C */
+void *memchr(const void * s, int c, size_t n);
+void *memscan(void *s, int c, size_t n);
+char *strcat(char *dst, const char *src);
+char *strcpy(char *dst, const char *src);
+size_t strlen(const char *s);
+size_t strnlen(const char * s, size_t n);
#endif /* !IN_ARCH_STRING_C */
#endif /* __KERNEL__ */
diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h
index ad93212d9e16..9d70057d828c 100644
--- a/arch/s390/include/asm/sysinfo.h
+++ b/arch/s390/include/asm/sysinfo.h
@@ -100,6 +100,7 @@ struct sysinfo_3_2_2 {
char reserved_1[24];
} vm[8];
+ char reserved_544[3552];
};
static inline int stsi(void *sysinfo, int fc, int sel1, int sel2)
diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h
index d60394b9745e..304cffa623e1 100644
--- a/arch/s390/include/asm/tlbflush.h
+++ b/arch/s390/include/asm/tlbflush.h
@@ -51,7 +51,7 @@ static inline void __tlb_flush_full(struct mm_struct *mm)
* If the process only ran on the local cpu, do a local flush.
*/
local_cpumask = cpumask_of_cpu(smp_processor_id());
- if (cpus_equal(mm->cpu_vm_mask, local_cpumask))
+ if (cpumask_equal(mm_cpumask(mm), &local_cpumask))
__tlb_flush_local();
else
__tlb_flush_global();
@@ -73,7 +73,7 @@ static inline void __tlb_flush_idte(unsigned long asce)
static inline void __tlb_flush_mm(struct mm_struct * mm)
{
- if (unlikely(cpus_empty(mm->cpu_vm_mask)))
+ if (unlikely(cpumask_empty(mm_cpumask(mm))))
return;
/*
* If the machine has IDTE we prefer to do a per mm flush
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h
index c979c3b56ab0..5e0ad618dc45 100644
--- a/arch/s390/include/asm/topology.h
+++ b/arch/s390/include/asm/topology.h
@@ -5,7 +5,6 @@
#define mc_capable() (1)
-cpumask_t cpu_coregroup_map(unsigned int cpu);
const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
extern cpumask_t cpu_core_map[NR_CPUS];
diff --git a/arch/s390/include/asm/vtoc.h b/arch/s390/include/asm/vtoc.h
index 3a5267d90d29..8406a2b3157a 100644
--- a/arch/s390/include/asm/vtoc.h
+++ b/arch/s390/include/asm/vtoc.h
@@ -39,7 +39,7 @@ struct vtoc_labeldate
__u16 day;
} __attribute__ ((packed));
-struct vtoc_volume_label
+struct vtoc_volume_label_cdl
{
char volkey[4]; /* volume key = volume label */
char vollbl[4]; /* volume label */
@@ -56,6 +56,14 @@ struct vtoc_volume_label
char res3[29]; /* reserved */
} __attribute__ ((packed));
+struct vtoc_volume_label_ldl {
+ char vollbl[4]; /* volume label */
+ char volid[6]; /* volume identifier */
+ char res3[69]; /* reserved */
+ char ldl_version; /* version number, valid for ldl format */
+ __u64 formatted_blocks; /* valid when ldl_version >= f2 */
+} __attribute__ ((packed));
+
struct vtoc_extent
{
__u8 typeind; /* extent type indicator */
@@ -140,7 +148,11 @@ struct vtoc_format4_label
char res2[10]; /* reserved */
__u8 DS4EFLVL; /* extended free-space management level */
struct vtoc_cchhb DS4EFPTR; /* pointer to extended free-space info */
- char res3[9]; /* reserved */
+ char res3; /* reserved */
+ __u32 DS4DCYL; /* number of logical cyls */
+ char res4[2]; /* reserved */
+ __u8 DS4DEVF2; /* device flags */
+ char res5; /* reserved */
} __attribute__ ((packed));
struct vtoc_ds5ext
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 3edc6c6f258b..228e3105ded7 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -17,10 +17,12 @@ CFLAGS_smp.o := -Wno-nonnull
#
CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
+CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
+
obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o \
processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
s390_ext.o debug.o irq.o ipl.o dis.o diag.o mem_detect.o \
- vdso.o vtime.o
+ vdso.o vtime.o sysinfo.o nmi.o
obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
diff --git a/arch/s390/kernel/bitmap.S b/arch/s390/kernel/bitmap.S
deleted file mode 100644
index dfb41f946e23..000000000000
--- a/arch/s390/kernel/bitmap.S
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * arch/s390/kernel/bitmap.S
- * Bitmaps for set_bit, clear_bit, test_and_set_bit, ...
- * See include/asm-s390/{bitops.h|posix_types.h} for details
- *
- * S390 version
- * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- */
-
- .globl _oi_bitmap
-_oi_bitmap:
- .byte 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
-
- .globl _ni_bitmap
-_ni_bitmap:
- .byte 0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F
-
- .globl _zb_findmap
-_zb_findmap:
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4
- .byte 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8
-
- .globl _sb_findmap
-_sb_findmap:
- .byte 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
- .byte 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
-
diff --git a/arch/s390/kernel/bitmap.c b/arch/s390/kernel/bitmap.c
new file mode 100644
index 000000000000..3ae4757b006a
--- /dev/null
+++ b/arch/s390/kernel/bitmap.c
@@ -0,0 +1,54 @@
+/*
+ * Bitmaps for set_bit, clear_bit, test_and_set_bit, ...
+ * See include/asm/{bitops.h|posix_types.h} for details
+ *
+ * Copyright IBM Corp. 1999,2009
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ */
+
+#include <linux/bitops.h>
+#include <linux/module.h>
+
+const char _oi_bitmap[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
+EXPORT_SYMBOL(_oi_bitmap);
+
+const char _ni_bitmap[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
+EXPORT_SYMBOL(_ni_bitmap);
+
+const char _zb_findmap[] = {
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,
+ 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8 };
+EXPORT_SYMBOL(_zb_findmap);
+
+const char _sb_findmap[] = {
+ 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+ 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 };
+EXPORT_SYMBOL(_sb_findmap);
diff --git a/arch/s390/kernel/compat_ptrace.h b/arch/s390/kernel/compat_ptrace.h
index a2be3a978d5c..123dd660d7fb 100644
--- a/arch/s390/kernel/compat_ptrace.h
+++ b/arch/s390/kernel/compat_ptrace.h
@@ -1,10 +1,11 @@
#ifndef _PTRACE32_H
#define _PTRACE32_H
+#include <asm/ptrace.h> /* needed for NUM_CR_WORDS */
#include "compat_linux.h" /* needed for psw_compat_t */
typedef struct {
- __u32 cr[3];
+ __u32 cr[NUM_CR_WORDS];
} per_cr_words32;
typedef struct {
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 62c706eb0de6..87cf5a79a351 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -252,7 +252,7 @@ sys32_chroot_wrapper:
sys32_ustat_wrapper:
llgfr %r2,%r2 # dev_t
llgtr %r3,%r3 # struct ustat *
- jg sys_ustat
+ jg compat_sys_ustat
.globl sys32_dup2_wrapper
sys32_dup2_wrapper:
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index ba03fc0a3a56..be8bceaf37d9 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -603,7 +603,7 @@ debug_input(struct file *file, const char __user *user_buf, size_t length,
static int
debug_open(struct inode *inode, struct file *file)
{
- int i = 0, rc = 0;
+ int i, rc = 0;
file_private_info_t *p_info;
debug_info_t *debug_info, *debug_info_snapshot;
@@ -642,8 +642,7 @@ found:
p_info = kmalloc(sizeof(file_private_info_t),
GFP_KERNEL);
if(!p_info){
- if(debug_info_snapshot)
- debug_info_free(debug_info_snapshot);
+ debug_info_free(debug_info_snapshot);
rc = -ENOMEM;
goto out;
}
@@ -698,8 +697,7 @@ debug_info_t *debug_register_mode(const char *name, int pages_per_area,
if ((uid != 0) || (gid != 0))
pr_warning("Root becomes the owner of all s390dbf files "
"in sysfs\n");
- if (!initialized)
- BUG();
+ BUG_ON(!initialized);
mutex_lock(&debug_mutex);
/* create new debug_info */
@@ -1156,7 +1154,6 @@ debug_unregister_view(debug_info_t * id, struct debug_view *view)
else {
debugfs_remove(id->debugfs_entries[i]);
id->views[i] = NULL;
- rc = 0;
}
spin_unlock_irqrestore(&id->lock, flags);
out:
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 2a2ca268b1dd..4d221c81c849 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -6,6 +6,7 @@
* Heiko Carstens <heiko.carstens@de.ibm.com>
*/
+#include <linux/compiler.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/string.h>
@@ -20,6 +21,7 @@
#include <asm/processor.h>
#include <asm/sections.h>
#include <asm/setup.h>
+#include <asm/sysinfo.h>
#include <asm/cpcmd.h>
#include <asm/sclp.h>
#include "entry.h"
@@ -173,19 +175,21 @@ static noinline __init void init_kernel_storage_key(void)
page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
}
+static __initdata struct sysinfo_3_2_2 vmms __aligned(PAGE_SIZE);
+
static noinline __init void detect_machine_type(void)
{
- struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data;
-
- get_cpu_id(&S390_lowcore.cpu_data.cpu_id);
-
- /* Running under z/VM ? */
- if (cpuinfo->cpu_id.version == 0xff)
- machine_flags |= MACHINE_FLAG_VM;
+ /* No VM information? Looks like LPAR */
+ if (stsi(&vmms, 3, 2, 2) == -ENOSYS)
+ return;
+ if (!vmms.count)
+ return;
- /* Running under KVM ? */
- if (cpuinfo->cpu_id.version == 0xfe)
+ /* Running under KVM? If not we assume z/VM */
+ if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3))
machine_flags |= MACHINE_FLAG_KVM;
+ else
+ machine_flags |= MACHINE_FLAG_VM;
}
static __init void early_pgm_check_handler(void)
@@ -348,7 +352,6 @@ static void __init setup_boot_command_line(void)
/* copy arch command line */
strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
- boot_command_line[ARCH_COMMAND_LINE_SIZE - 1] = 0;
/* append IPL PARM data to the boot command line */
if (MACHINE_IS_VM) {
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index ec7e35f6055b..1046c2c9f8d1 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -469,6 +469,8 @@ start:
.org 0x10000
startup:basr %r13,0 # get base
.LPG0:
+ xc 0x200(256),0x200 # partially clear lowcore
+ xc 0x300(256),0x300
#ifndef CONFIG_MARCH_G5
# check processor version against MARCH_{G5,Z900,Z990,Z9_109,Z10}
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index db476d114caa..2ced846065b7 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -20,7 +20,6 @@ startup_continue:
lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
# move IPL device to lowcore
- mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
#
# Setup stack
#
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index f9f70aa15244..65667b2e65ce 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -86,7 +86,6 @@ startup_continue:
lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area
# move IPL device to lowcore
- mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12)
lghi %r0,__LC_PASTE
stg %r0,__LC_VDSO_PER_CPU
#
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 2dcf590faba6..6f3711a0eaaa 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -23,7 +23,7 @@
#include <asm/ebcdic.h>
#include <asm/reset.h>
#include <asm/sclp.h>
-#include <asm/setup.h>
+#include <asm/checksum.h>
#define IPL_PARM_BLOCK_VERSION 0
@@ -56,13 +56,14 @@ struct shutdown_trigger {
};
/*
- * Five shutdown action types are supported:
+ * The following shutdown action types are supported:
*/
#define SHUTDOWN_ACTION_IPL_STR "ipl"
#define SHUTDOWN_ACTION_REIPL_STR "reipl"
#define SHUTDOWN_ACTION_DUMP_STR "dump"
#define SHUTDOWN_ACTION_VMCMD_STR "vmcmd"
#define SHUTDOWN_ACTION_STOP_STR "stop"
+#define SHUTDOWN_ACTION_DUMP_REIPL_STR "dump_reipl"
struct shutdown_action {
char *name;
@@ -146,6 +147,7 @@ static enum ipl_method reipl_method = REIPL_METHOD_DEFAULT;
static struct ipl_parameter_block *reipl_block_fcp;
static struct ipl_parameter_block *reipl_block_ccw;
static struct ipl_parameter_block *reipl_block_nss;
+static struct ipl_parameter_block *reipl_block_actual;
static int dump_capabilities = DUMP_TYPE_NONE;
static enum dump_type dump_type = DUMP_TYPE_NONE;
@@ -835,6 +837,7 @@ static int reipl_set_type(enum ipl_type type)
reipl_method = REIPL_METHOD_CCW_VM;
else
reipl_method = REIPL_METHOD_CCW_CIO;
+ reipl_block_actual = reipl_block_ccw;
break;
case IPL_TYPE_FCP:
if (diag308_set_works)
@@ -843,6 +846,7 @@ static int reipl_set_type(enum ipl_type type)
reipl_method = REIPL_METHOD_FCP_RO_VM;
else
reipl_method = REIPL_METHOD_FCP_RO_DIAG;
+ reipl_block_actual = reipl_block_fcp;
break;
case IPL_TYPE_FCP_DUMP:
reipl_method = REIPL_METHOD_FCP_DUMP;
@@ -852,6 +856,7 @@ static int reipl_set_type(enum ipl_type type)
reipl_method = REIPL_METHOD_NSS_DIAG;
else
reipl_method = REIPL_METHOD_NSS;
+ reipl_block_actual = reipl_block_nss;
break;
case IPL_TYPE_UNKNOWN:
reipl_method = REIPL_METHOD_DEFAULT;
@@ -960,7 +965,6 @@ static void reipl_run(struct shutdown_trigger *trigger)
diag308(DIAG308_IPL, NULL);
break;
case REIPL_METHOD_FCP_DUMP:
- default:
break;
}
disabled_wait((unsigned long) __builtin_return_address(0));
@@ -1069,10 +1073,12 @@ static int __init reipl_fcp_init(void)
{
int rc;
- if ((!diag308_set_works) && (ipl_info.type != IPL_TYPE_FCP))
- return 0;
- if ((!diag308_set_works) && (ipl_info.type == IPL_TYPE_FCP))
- make_attrs_ro(reipl_fcp_attrs);
+ if (!diag308_set_works) {
+ if (ipl_info.type == IPL_TYPE_FCP)
+ make_attrs_ro(reipl_fcp_attrs);
+ else
+ return 0;
+ }
reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
if (!reipl_block_fcp)
@@ -1253,7 +1259,6 @@ static void dump_run(struct shutdown_trigger *trigger)
diag308(DIAG308_DUMP, NULL);
break;
case DUMP_METHOD_NONE:
- default:
return;
}
printk(KERN_EMERG "Dump failed!\n");
@@ -1332,6 +1337,49 @@ static struct shutdown_action __refdata dump_action = {
.init = dump_init,
};
+static void dump_reipl_run(struct shutdown_trigger *trigger)
+{
+ preempt_disable();
+ /*
+ * Bypass dynamic address translation (DAT) when storing IPL parameter
+ * information block address and checksum into the prefix area
+ * (corresponding to absolute addresses 0-8191).
+ * When enhanced DAT applies and the STE format control in one,
+ * the absolute address is formed without prefixing. In this case a
+ * normal store (stg/st) into the prefix area would no more match to
+ * absolute addresses 0-8191.
+ */
+#ifdef CONFIG_64BIT
+ asm volatile("sturg %0,%1"
+ :: "a" ((unsigned long) reipl_block_actual),
+ "a" (&lowcore_ptr[smp_processor_id()]->ipib));
+#else
+ asm volatile("stura %0,%1"
+ :: "a" ((unsigned long) reipl_block_actual),
+ "a" (&lowcore_ptr[smp_processor_id()]->ipib));
+#endif
+ asm volatile("stura %0,%1"
+ :: "a" (csum_partial(reipl_block_actual,
+ reipl_block_actual->hdr.len, 0)),
+ "a" (&lowcore_ptr[smp_processor_id()]->ipib_checksum));
+ preempt_enable();
+ dump_run(trigger);
+}
+
+static int __init dump_reipl_init(void)
+{
+ if (!diag308_set_works)
+ return -EOPNOTSUPP;
+ else
+ return 0;
+}
+
+static struct shutdown_action __refdata dump_reipl_action = {
+ .name = SHUTDOWN_ACTION_DUMP_REIPL_STR,
+ .fn = dump_reipl_run,
+ .init = dump_reipl_init,
+};
+
/*
* vmcmd shutdown action: Trigger vm command on shutdown.
*/
@@ -1421,7 +1469,8 @@ static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
/* action list */
static struct shutdown_action *shutdown_actions_list[] = {
- &ipl_action, &reipl_action, &dump_action, &vmcmd_action, &stop_action};
+ &ipl_action, &reipl_action, &dump_reipl_action, &dump_action,
+ &vmcmd_action, &stop_action};
#define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *))
/*
@@ -1434,11 +1483,11 @@ static int set_trigger(const char *buf, struct shutdown_trigger *trigger,
size_t len)
{
int i;
+
for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
if (!shutdown_actions_list[i])
continue;
- if (strncmp(buf, shutdown_actions_list[i]->name,
- strlen(shutdown_actions_list[i]->name)) == 0) {
+ if (sysfs_streq(buf, shutdown_actions_list[i]->name)) {
trigger->action = shutdown_actions_list[i];
return len;
}
@@ -1672,7 +1721,7 @@ static int on_panic_notify(struct notifier_block *self,
static struct notifier_block on_panic_nb = {
.notifier_call = on_panic_notify,
- .priority = 0,
+ .priority = INT_MIN,
};
void __init setup_ipl(void)
@@ -1696,7 +1745,6 @@ void __init setup_ipl(void)
sizeof(ipl_info.data.nss.name));
break;
case IPL_TYPE_UNKNOWN:
- default:
/* We have no info to copy */
break;
}
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index 59b4e796680a..eed4a00cb676 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -310,15 +310,20 @@ apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
info->plt_initialized = 1;
}
if (r_type == R_390_PLTOFF16 ||
- r_type == R_390_PLTOFF32
- || r_type == R_390_PLTOFF64
- )
+ r_type == R_390_PLTOFF32 ||
+ r_type == R_390_PLTOFF64)
val = me->arch.plt_offset - me->arch.got_offset +
info->plt_offset + rela->r_addend;
- else
- val = (Elf_Addr) me->module_core +
- me->arch.plt_offset + info->plt_offset +
- rela->r_addend - loc;
+ else {
+ if (!((r_type == R_390_PLT16DBL &&
+ val - loc + 0xffffUL < 0x1ffffeUL) ||
+ (r_type == R_390_PLT32DBL &&
+ val - loc + 0xffffffffULL < 0x1fffffffeULL)))
+ val = (Elf_Addr) me->module_core +
+ me->arch.plt_offset +
+ info->plt_offset;
+ val += rela->r_addend - loc;
+ }
if (r_type == R_390_PLT16DBL)
*(unsigned short *) loc = val >> 1;
else if (r_type == R_390_PLTOFF16)
diff --git a/drivers/s390/s390mach.c b/arch/s390/kernel/nmi.c
index 92b0417f8e12..4bfdc421d7e9 100644
--- a/drivers/s390/s390mach.c
+++ b/arch/s390/kernel/nmi.c
@@ -1,137 +1,23 @@
/*
- * drivers/s390/s390mach.c
- * S/390 machine check handler
+ * Machine check handler
*
- * Copyright IBM Corp. 2000,2008
- * Author(s): Ingo Adlung (adlung@de.ibm.com)
- * Martin Schwidefsky (schwidefsky@de.ibm.com)
- * Cornelia Huck <cornelia.huck@de.ibm.com>
+ * Copyright IBM Corp. 2000,2009
+ * Author(s): Ingo Adlung <adlung@de.ibm.com>,
+ * Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ * Cornelia Huck <cornelia.huck@de.ibm.com>,
+ * Heiko Carstens <heiko.carstens@de.ibm.com>,
*/
#include <linux/init.h>
-#include <linux/sched.h>
#include <linux/errno.h>
-#include <linux/workqueue.h>
#include <linux/time.h>
-#include <linux/device.h>
-#include <linux/kthread.h>
-#include <asm/etr.h>
+#include <linux/module.h>
#include <asm/lowcore.h>
-#include <asm/cio.h>
+#include <asm/smp.h>
+#include <asm/etr.h>
#include <asm/cpu.h>
-#include "s390mach.h"
-
-static struct semaphore m_sem;
-
-static NORET_TYPE void
-s390_handle_damage(char *msg)
-{
-#ifdef CONFIG_SMP
- smp_send_stop();
-#endif
- disabled_wait((unsigned long) __builtin_return_address(0));
- for(;;);
-}
-
-static crw_handler_t crw_handlers[NR_RSCS];
-
-/**
- * s390_register_crw_handler() - register a channel report word handler
- * @rsc: reporting source code to handle
- * @handler: handler to be registered
- *
- * Returns %0 on success and a negative error value otherwise.
- */
-int s390_register_crw_handler(int rsc, crw_handler_t handler)
-{
- if ((rsc < 0) || (rsc >= NR_RSCS))
- return -EINVAL;
- if (!cmpxchg(&crw_handlers[rsc], NULL, handler))
- return 0;
- return -EBUSY;
-}
-
-/**
- * s390_unregister_crw_handler() - unregister a channel report word handler
- * @rsc: reporting source code to handle
- */
-void s390_unregister_crw_handler(int rsc)
-{
- if ((rsc < 0) || (rsc >= NR_RSCS))
- return;
- xchg(&crw_handlers[rsc], NULL);
- synchronize_sched();
-}
-
-/*
- * Retrieve CRWs and call function to handle event.
- */
-static int s390_collect_crw_info(void *param)
-{
- struct crw crw[2];
- int ccode;
- struct semaphore *sem;
- unsigned int chain;
- int ignore;
-
- sem = (struct semaphore *)param;
-repeat:
- ignore = down_interruptible(sem);
- chain = 0;
- while (1) {
- if (unlikely(chain > 1)) {
- struct crw tmp_crw;
-
- printk(KERN_WARNING"%s: Code does not support more "
- "than two chained crws; please report to "
- "linux390@de.ibm.com!\n", __func__);
- ccode = stcrw(&tmp_crw);
- printk(KERN_WARNING"%s: crw reports slct=%d, oflw=%d, "
- "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
- __func__, tmp_crw.slct, tmp_crw.oflw,
- tmp_crw.chn, tmp_crw.rsc, tmp_crw.anc,
- tmp_crw.erc, tmp_crw.rsid);
- printk(KERN_WARNING"%s: This was crw number %x in the "
- "chain\n", __func__, chain);
- if (ccode != 0)
- break;
- chain = tmp_crw.chn ? chain + 1 : 0;
- continue;
- }
- ccode = stcrw(&crw[chain]);
- if (ccode != 0)
- break;
- printk(KERN_DEBUG "crw_info : CRW reports slct=%d, oflw=%d, "
- "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
- crw[chain].slct, crw[chain].oflw, crw[chain].chn,
- crw[chain].rsc, crw[chain].anc, crw[chain].erc,
- crw[chain].rsid);
- /* Check for overflows. */
- if (crw[chain].oflw) {
- int i;
-
- pr_debug("%s: crw overflow detected!\n", __func__);
- for (i = 0; i < NR_RSCS; i++) {
- if (crw_handlers[i])
- crw_handlers[i](NULL, NULL, 1);
- }
- chain = 0;
- continue;
- }
- if (crw[0].chn && !chain) {
- chain++;
- continue;
- }
- if (crw_handlers[crw[chain].rsc])
- crw_handlers[crw[chain].rsc](&crw[0],
- chain ? &crw[1] : NULL,
- 0);
- /* chain is always 0 or 1 here. */
- chain = crw[chain].chn ? chain + 1 : 0;
- }
- goto repeat;
- return 0;
-}
+#include <asm/nmi.h>
+#include <asm/crw.h>
struct mcck_struct {
int kill_task;
@@ -142,12 +28,18 @@ struct mcck_struct {
static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck);
+static NORET_TYPE void s390_handle_damage(char *msg)
+{
+ smp_send_stop();
+ disabled_wait((unsigned long) __builtin_return_address(0));
+ while (1);
+}
+
/*
* Main machine check handler function. Will be called with interrupts enabled
* or disabled and machine checks enabled or disabled.
*/
-void
-s390_handle_mcck(void)
+void s390_handle_mcck(void)
{
unsigned long flags;
struct mcck_struct mcck;
@@ -166,29 +58,24 @@ s390_handle_mcck(void)
local_irq_restore(flags);
if (mcck.channel_report)
- up(&m_sem);
-
-#ifdef CONFIG_MACHCHK_WARNING
-/*
- * The warning may remain for a prolonged period on the bare iron.
- * (actually till the machine is powered off, or until the problem is gone)
- * So we just stop listening for the WARNING MCH and prevent continuously
- * being interrupted. One caveat is however, that we must do this per
- * processor and cannot use the smp version of ctl_clear_bit().
- * On VM we only get one interrupt per virtally presented machinecheck.
- * Though one suffices, we may get one interrupt per (virtual) processor.
- */
+ crw_handle_channel_report();
+ /*
+ * A warning may remain for a prolonged period on the bare iron.
+ * (actually until the machine is powered off, or the problem is gone)
+ * So we just stop listening for the WARNING MCH and avoid continuously
+ * being interrupted. One caveat is however, that we must do this per
+ * processor and cannot use the smp version of ctl_clear_bit().
+ * On VM we only get one interrupt per virtally presented machinecheck.
+ * Though one suffices, we may get one interrupt per (virtual) cpu.
+ */
if (mcck.warning) { /* WARNING pending ? */
static int mchchk_wng_posted = 0;
- /*
- * Use single machine clear, as we cannot handle smp right now
- */
+
+ /* Use single cpu clear, as we cannot handle smp here. */
__ctl_clear_bit(14, 24); /* Disable WARNING MCH */
if (xchg(&mchchk_wng_posted, 1) == 0)
kill_cad_pid(SIGPWR, 1);
}
-#endif
-
if (mcck.kill_task) {
local_irq_enable();
printk(KERN_EMERG "mcck: Terminating task because of machine "
@@ -204,8 +91,7 @@ EXPORT_SYMBOL_GPL(s390_handle_mcck);
* returns 0 if all registers could be validated
* returns 1 otherwise
*/
-static int
-s390_revalidate_registers(struct mci *mci)
+static int notrace s390_revalidate_registers(struct mci *mci)
{
int kill_task;
u64 tmpclock;
@@ -214,22 +100,21 @@ s390_revalidate_registers(struct mci *mci)
kill_task = 0;
zero = 0;
- /* General purpose registers */
- if (!mci->gr)
+
+ if (!mci->gr) {
/*
* General purpose registers couldn't be restored and have
* unknown contents. Process needs to be terminated.
*/
kill_task = 1;
-
- /* Revalidate floating point registers */
- if (!mci->fp)
+ }
+ if (!mci->fp) {
/*
* Floating point registers can't be restored and
* therefore the process needs to be terminated.
*/
kill_task = 1;
-
+ }
#ifndef CONFIG_64BIT
asm volatile(
" ld 0,0(%0)\n"
@@ -245,9 +130,8 @@ s390_revalidate_registers(struct mci *mci)
fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area;
#else
fpt_save_area = (void *) S390_lowcore.extended_save_area_addr;
- fpt_creg_save_area = fpt_save_area+128;
+ fpt_creg_save_area = fpt_save_area + 128;
#endif
- /* Floating point control register */
if (!mci->fc) {
/*
* Floating point control register can't be restored.
@@ -278,26 +162,25 @@ s390_revalidate_registers(struct mci *mci)
" ld 15,120(%0)\n"
: : "a" (fpt_save_area));
}
-
/* Revalidate access registers */
asm volatile(
" lam 0,15,0(%0)"
: : "a" (&S390_lowcore.access_regs_save_area));
- if (!mci->ar)
+ if (!mci->ar) {
/*
* Access registers have unknown contents.
* Terminating task.
*/
kill_task = 1;
-
+ }
/* Revalidate control registers */
- if (!mci->cr)
+ if (!mci->cr) {
/*
* Control registers have unknown contents.
* Can't recover and therefore stopping machine.
*/
s390_handle_damage("invalid control registers.");
- else
+ } else {
#ifdef CONFIG_64BIT
asm volatile(
" lctlg 0,15,0(%0)"
@@ -307,12 +190,11 @@ s390_revalidate_registers(struct mci *mci)
" lctl 0,15,0(%0)"
: : "a" (&S390_lowcore.cregs_save_area));
#endif
-
+ }
/*
* We don't even try to revalidate the TOD register, since we simply
* can't write something sensible into that register.
*/
-
#ifdef CONFIG_64BIT
/*
* See if we can revalidate the TOD programmable register with its
@@ -330,7 +212,6 @@ s390_revalidate_registers(struct mci *mci)
: : "a" (&S390_lowcore.tod_progreg_save_area)
: "0", "cc");
#endif
-
/* Revalidate clock comparator register */
asm volatile(
" stck 0(%1)\n"
@@ -354,32 +235,35 @@ s390_revalidate_registers(struct mci *mci)
#define MAX_IPD_COUNT 29
#define MAX_IPD_TIME (5 * 60 * USEC_PER_SEC) /* 5 minutes */
+#define ED_STP_ISLAND 6 /* External damage STP island check */
+#define ED_STP_SYNC 7 /* External damage STP sync check */
+#define ED_ETR_SYNC 12 /* External damage ETR sync check */
+#define ED_ETR_SWITCH 13 /* External damage ETR switch to local */
+
/*
* machine check handler.
*/
-void
-s390_do_machine_check(struct pt_regs *regs)
+void notrace s390_do_machine_check(struct pt_regs *regs)
{
+ static int ipd_count;
static DEFINE_SPINLOCK(ipd_lock);
static unsigned long long last_ipd;
- static int ipd_count;
+ struct mcck_struct *mcck;
unsigned long long tmp;
struct mci *mci;
- struct mcck_struct *mcck;
int umode;
lockdep_off();
-
s390_idle_check();
mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
mcck = &__get_cpu_var(cpu_mcck);
umode = user_mode(regs);
- if (mci->sd)
+ if (mci->sd) {
/* System damage -> stopping machine */
s390_handle_damage("received system damage machine check.");
-
+ }
if (mci->pd) {
if (mci->b) {
/* Processing backup -> verify if we can survive this */
@@ -409,24 +293,17 @@ s390_do_machine_check(struct pt_regs *regs)
* Nullifying exigent condition, therefore we might
* retry this instruction.
*/
-
spin_lock(&ipd_lock);
-
tmp = get_clock();
-
if (((tmp - last_ipd) >> 12) < MAX_IPD_TIME)
ipd_count++;
else
ipd_count = 1;
-
last_ipd = tmp;
-
if (ipd_count == MAX_IPD_COUNT)
s390_handle_damage("too many ipd retries.");
-
spin_unlock(&ipd_lock);
- }
- else {
+ } else {
/* Processing damage -> stopping machine */
s390_handle_damage("received instruction processing "
"damage machine check.");
@@ -441,20 +318,18 @@ s390_do_machine_check(struct pt_regs *regs)
mcck->kill_task = 1;
mcck->mcck_code = *(unsigned long long *) mci;
set_thread_flag(TIF_MCCK_PENDING);
- }
- else
+ } else {
/*
* Couldn't restore all register contents while in
* kernel mode -> stopping machine.
*/
s390_handle_damage("unable to revalidate registers.");
+ }
}
-
if (mci->cd) {
/* Timing facility damage */
s390_handle_damage("TOD clock damaged");
}
-
if (mci->ed && mci->ec) {
/* External damage */
if (S390_lowcore.external_damage_code & (1U << ED_ETR_SYNC))
@@ -466,28 +341,23 @@ s390_do_machine_check(struct pt_regs *regs)
if (S390_lowcore.external_damage_code & (1U << ED_STP_ISLAND))
stp_island_check();
}
-
if (mci->se)
/* Storage error uncorrected */
s390_handle_damage("received storage error uncorrected "
"machine check.");
-
if (mci->ke)
/* Storage key-error uncorrected */
s390_handle_damage("received storage key-error uncorrected "
"machine check.");
-
if (mci->ds && mci->fa)
/* Storage degradation */
s390_handle_damage("received storage degradation machine "
"check.");
-
if (mci->cp) {
/* Channel report word pending */
mcck->channel_report = 1;
set_thread_flag(TIF_MCCK_PENDING);
}
-
if (mci->w) {
/* Warning pending */
mcck->warning = 1;
@@ -496,43 +366,11 @@ s390_do_machine_check(struct pt_regs *regs)
lockdep_on();
}
-/*
- * s390_init_machine_check
- *
- * initialize machine check handling
- */
-static int
-machine_check_init(void)
+static int __init machine_check_init(void)
{
- init_MUTEX_LOCKED(&m_sem);
ctl_set_bit(14, 25); /* enable external damage MCH */
- ctl_set_bit(14, 27); /* enable system recovery MCH */
-#ifdef CONFIG_MACHCHK_WARNING
+ ctl_set_bit(14, 27); /* enable system recovery MCH */
ctl_set_bit(14, 24); /* enable warning MCH */
-#endif
return 0;
}
-
-/*
- * Initialize the machine check handler really early to be able to
- * catch all machine checks that happen during boot
- */
arch_initcall(machine_check_init);
-
-/*
- * Machine checks for the channel subsystem must be enabled
- * after the channel subsystem is initialized
- */
-static int __init
-machine_check_crw_init (void)
-{
- struct task_struct *task;
-
- task = kthread_run(s390_collect_crw_info, &m_sem, "kmcheck");
- if (IS_ERR(task))
- return PTR_ERR(task);
- ctl_set_bit(14, 28); /* enable channel report MCH */
- return 0;
-}
-
-device_initcall (machine_check_crw_init);
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 5cd38a90e64d..a3acd8e60aff 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -1,18 +1,10 @@
/*
- * arch/s390/kernel/process.c
+ * This file handles the architecture dependent parts of process handling.
*
- * S390 version
- * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- * Hartmut Penner (hp@de.ibm.com),
- * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
- *
- * Derived from "arch/i386/kernel/process.c"
- * Copyright (C) 1995, Linus Torvalds
- */
-
-/*
- * This file handles the architecture-dependent parts of process handling..
+ * Copyright IBM Corp. 1999,2009
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ * Hartmut Penner <hp@de.ibm.com>,
+ * Denis Joseph Barrow,
*/
#include <linux/compiler.h>
@@ -47,6 +39,7 @@
#include <asm/processor.h>
#include <asm/irq.h>
#include <asm/timer.h>
+#include <asm/nmi.h>
#include "entry.h"
asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
@@ -76,7 +69,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
return sf->gprs[8];
}
-extern void s390_handle_mcck(void);
/*
* The idle loop on a S390...
*/
@@ -149,6 +141,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
0, &regs, 0, NULL, NULL);
}
+EXPORT_SYMBOL(kernel_thread);
/*
* Free current thread data structures etc..
@@ -167,35 +160,36 @@ void release_thread(struct task_struct *dead_task)
{
}
-int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
- unsigned long unused,
- struct task_struct * p, struct pt_regs * regs)
+int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
+ unsigned long unused,
+ struct task_struct *p, struct pt_regs *regs)
{
- struct fake_frame
- {
- struct stack_frame sf;
- struct pt_regs childregs;
- } *frame;
-
- frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
- p->thread.ksp = (unsigned long) frame;
+ struct thread_info *ti;
+ struct fake_frame
+ {
+ struct stack_frame sf;
+ struct pt_regs childregs;
+ } *frame;
+
+ frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
+ p->thread.ksp = (unsigned long) frame;
/* Store access registers to kernel stack of new process. */
- frame->childregs = *regs;
+ frame->childregs = *regs;
frame->childregs.gprs[2] = 0; /* child returns 0 on fork. */
- frame->childregs.gprs[15] = new_stackp;
- frame->sf.back_chain = 0;
+ frame->childregs.gprs[15] = new_stackp;
+ frame->sf.back_chain = 0;
- /* new return point is ret_from_fork */
- frame->sf.gprs[8] = (unsigned long) ret_from_fork;
+ /* new return point is ret_from_fork */
+ frame->sf.gprs[8] = (unsigned long) ret_from_fork;
- /* fake return stack for resume(), don't go back to schedule */
- frame->sf.gprs[9] = (unsigned long) frame;
+ /* fake return stack for resume(), don't go back to schedule */
+ frame->sf.gprs[9] = (unsigned long) frame;
/* Save access registers to new thread structure. */
save_access_regs(&p->thread.acrs[0]);
#ifndef CONFIG_64BIT
- /*
+ /*
* save fprs to current->thread.fp_regs to merge them with
* the emulated registers and then copy the result to the child.
*/
@@ -220,10 +214,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
#endif /* CONFIG_64BIT */
/* start new process with ar4 pointing to the correct address space */
p->thread.mm_segment = get_fs();
- /* Don't copy debug registers */
- memset(&p->thread.per_info,0,sizeof(p->thread.per_info));
-
- return 0;
+ /* Don't copy debug registers */
+ memset(&p->thread.per_info, 0, sizeof(p->thread.per_info));
+ /* Initialize per thread user and system timer values */
+ ti = task_thread_info(p);
+ ti->user_timer = 0;
+ ti->system_timer = 0;
+ return 0;
}
SYSCALL_DEFINE0(fork)
@@ -311,7 +308,7 @@ out:
int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
{
#ifndef CONFIG_64BIT
- /*
+ /*
* save fprs to current->thread.fp_regs to merge them with
* the emulated registers and then copy the result to the dump.
*/
@@ -322,6 +319,7 @@ int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
#endif /* CONFIG_64BIT */
return 1;
}
+EXPORT_SYMBOL(dump_fpu);
unsigned long get_wchan(struct task_struct *p)
{
@@ -346,4 +344,3 @@ unsigned long get_wchan(struct task_struct *p)
}
return 0;
}
-
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c
index 82c1872cfe80..802c8ab247f3 100644
--- a/arch/s390/kernel/processor.c
+++ b/arch/s390/kernel/processor.c
@@ -18,10 +18,11 @@
#include <asm/lowcore.h>
#include <asm/param.h>
-void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo)
+void __cpuinit print_cpu_info(void)
{
pr_info("Processor %d started, address %d, identification %06X\n",
- cpuinfo->cpu_nr, cpuinfo->cpu_addr, cpuinfo->cpu_id.ident);
+ S390_lowcore.cpu_nr, S390_lowcore.cpu_addr,
+ S390_lowcore.cpu_id.ident);
}
/*
@@ -30,48 +31,46 @@ void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo)
static int show_cpuinfo(struct seq_file *m, void *v)
{
- static const char *hwcap_str[8] = {
+ static const char *hwcap_str[9] = {
"esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp",
- "edat"
+ "edat", "etf3eh"
};
- struct cpuinfo_S390 *cpuinfo;
- unsigned long n = (unsigned long) v - 1;
- int i;
+ struct _lowcore *lc;
+ unsigned long n = (unsigned long) v - 1;
+ int i;
- s390_adjust_jiffies();
- preempt_disable();
- if (!n) {
- seq_printf(m, "vendor_id : IBM/S390\n"
- "# processors : %i\n"
- "bogomips per cpu: %lu.%02lu\n",
- num_online_cpus(), loops_per_jiffy/(500000/HZ),
- (loops_per_jiffy/(5000/HZ))%100);
- seq_puts(m, "features\t: ");
- for (i = 0; i < 8; i++)
- if (hwcap_str[i] && (elf_hwcap & (1UL << i)))
- seq_printf(m, "%s ", hwcap_str[i]);
- seq_puts(m, "\n");
- }
+ s390_adjust_jiffies();
+ preempt_disable();
+ if (!n) {
+ seq_printf(m, "vendor_id : IBM/S390\n"
+ "# processors : %i\n"
+ "bogomips per cpu: %lu.%02lu\n",
+ num_online_cpus(), loops_per_jiffy/(500000/HZ),
+ (loops_per_jiffy/(5000/HZ))%100);
+ seq_puts(m, "features\t: ");
+ for (i = 0; i < 9; i++)
+ if (hwcap_str[i] && (elf_hwcap & (1UL << i)))
+ seq_printf(m, "%s ", hwcap_str[i]);
+ seq_puts(m, "\n");
+ }
- if (cpu_online(n)) {
+ if (cpu_online(n)) {
#ifdef CONFIG_SMP
- if (smp_processor_id() == n)
- cpuinfo = &S390_lowcore.cpu_data;
- else
- cpuinfo = &lowcore_ptr[n]->cpu_data;
+ lc = (smp_processor_id() == n) ?
+ &S390_lowcore : lowcore_ptr[n];
#else
- cpuinfo = &S390_lowcore.cpu_data;
+ lc = &S390_lowcore;
#endif
- seq_printf(m, "processor %li: "
- "version = %02X, "
- "identification = %06X, "
- "machine = %04X\n",
- n, cpuinfo->cpu_id.version,
- cpuinfo->cpu_id.ident,
- cpuinfo->cpu_id.machine);
- }
- preempt_enable();
- return 0;
+ seq_printf(m, "processor %li: "
+ "version = %02X, "
+ "identification = %06X, "
+ "machine = %04X\n",
+ n, lc->cpu_id.version,
+ lc->cpu_id.ident,
+ lc->cpu_id.machine);
+ }
+ preempt_enable();
+ return 0;
}
static void *c_start(struct seq_file *m, loff_t *pos)
diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S
index c41930499a5f..774147824c3d 100644
--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -1,10 +1,7 @@
/*
- * arch/s390/kernel/reipl.S
- *
- * S390 version
- * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com)
- Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ * Copyright IBM Corp 2000,2009
+ * Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>,
+ * Denis Joseph Barrow,
*/
#include <asm/lowcore.h>
@@ -30,7 +27,7 @@ do_reipl_asm: basr %r13,0
mvc __LC_PREFIX_SAVE_AREA-0x1000(4,%r1),0(%r10)
stfpc __LC_FP_CREG_SAVE_AREA-0x1000(%r1)
stckc .Lclkcmp-.Lpg0(%r13)
- mvc __LC_CLOCK_COMP_SAVE_AREA-0x1000(8,%r1),.Lclkcmp-.Lpg0(%r13)
+ mvc __LC_CLOCK_COMP_SAVE_AREA-0x1000(7,%r1),.Lclkcmp-.Lpg0(%r13)
stpt __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1)
stg %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1)
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c
index 46b90cb03707..656fcbb9bd83 100644
--- a/arch/s390/kernel/s390_ksyms.c
+++ b/arch/s390/kernel/s390_ksyms.c
@@ -1,49 +1,5 @@
-/*
- * arch/s390/kernel/s390_ksyms.c
- *
- * S390 version
- */
-#include <linux/highuid.h>
#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/syscalls.h>
-#include <linux/interrupt.h>
-#include <asm/checksum.h>
-#include <asm/cpcmd.h>
-#include <asm/delay.h>
-#include <asm/pgalloc.h>
-#include <asm/setup.h>
#include <asm/ftrace.h>
-#ifdef CONFIG_IP_MULTICAST
-#include <net/arp.h>
-#endif
-
-/*
- * memory management
- */
-EXPORT_SYMBOL(_oi_bitmap);
-EXPORT_SYMBOL(_ni_bitmap);
-EXPORT_SYMBOL(_zb_findmap);
-EXPORT_SYMBOL(_sb_findmap);
-
-/*
- * binfmt_elf loader
- */
-extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs);
-EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL(empty_zero_page);
-
-/*
- * misc.
- */
-EXPORT_SYMBOL(machine_flags);
-EXPORT_SYMBOL(__udelay);
-EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(csum_fold);
-EXPORT_SYMBOL(console_mode);
-EXPORT_SYMBOL(console_devno);
-EXPORT_SYMBOL(console_irq);
#ifdef CONFIG_FUNCTION_TRACER
EXPORT_SYMBOL(_mcount);
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index c5cfb6185eac..06201b93cbbf 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -74,9 +74,17 @@ EXPORT_SYMBOL(uaccess);
* Machine setup..
*/
unsigned int console_mode = 0;
+EXPORT_SYMBOL(console_mode);
+
unsigned int console_devno = -1;
+EXPORT_SYMBOL(console_devno);
+
unsigned int console_irq = -1;
+EXPORT_SYMBOL(console_irq);
+
unsigned long machine_flags;
+EXPORT_SYMBOL(machine_flags);
+
unsigned long elf_hwcap = 0;
char elf_platform[ELF_PLATFORM_SIZE];
@@ -86,6 +94,10 @@ volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
int __initdata memory_end_set;
unsigned long __initdata memory_end;
+/* An array with a pointer to the lowcore of every CPU. */
+struct _lowcore *lowcore_ptr[NR_CPUS];
+EXPORT_SYMBOL(lowcore_ptr);
+
/*
* This is set up by the setup-routine at boot-time
* for S390 need to find out, what we have to setup
@@ -109,13 +121,10 @@ static struct resource data_resource = {
*/
void __cpuinit cpu_init(void)
{
- int addr = hard_smp_processor_id();
-
/*
* Store processor id in lowcore (used e.g. in timer_interrupt)
*/
- get_cpu_id(&S390_lowcore.cpu_data.cpu_id);
- S390_lowcore.cpu_data.cpu_addr = addr;
+ get_cpu_id(&S390_lowcore.cpu_id);
/*
* Force FPU initialization:
@@ -125,8 +134,7 @@ void __cpuinit cpu_init(void)
atomic_inc(&init_mm.mm_count);
current->active_mm = &init_mm;
- if (current->mm)
- BUG();
+ BUG_ON(current->mm);
enter_lazy_tlb(&init_mm, current);
}
@@ -217,7 +225,7 @@ static void __init conmode_default(void)
}
}
-#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
+#ifdef CONFIG_ZFCPDUMP
static void __init setup_zfcpdump(unsigned int console_devno)
{
static char str[41];
@@ -289,11 +297,7 @@ static int __init early_parse_mem(char *p)
early_param("mem", early_parse_mem);
#ifdef CONFIG_S390_SWITCH_AMODE
-#ifdef CONFIG_PGSTE
-unsigned int switch_amode = 1;
-#else
unsigned int switch_amode = 0;
-#endif
EXPORT_SYMBOL_GPL(switch_amode);
static int set_amode_and_uaccess(unsigned long user_amode,
@@ -414,7 +418,6 @@ setup_lowcore(void)
PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
lc->io_new_psw.mask = psw_kernel_bits;
lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
- lc->ipl_device = S390_lowcore.ipl_device;
lc->clock_comparator = -1ULL;
lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;
lc->async_stack = (unsigned long)
@@ -434,6 +437,7 @@ setup_lowcore(void)
lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0];
#endif
set_prefix((u32)(unsigned long) lc);
+ lowcore_ptr[0] = lc;
}
static void __init
@@ -510,7 +514,7 @@ static void __init setup_memory_end(void)
unsigned long max_mem;
int i;
-#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
+#ifdef CONFIG_ZFCPDUMP
if (ipl_info.type == IPL_TYPE_FCP_DUMP) {
memory_end = ZFCPDUMP_HSA_SIZE;
memory_end_set = 1;
@@ -677,7 +681,6 @@ setup_memory(void)
static void __init setup_hwcaps(void)
{
static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 };
- struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data;
unsigned long long facility_list_extended;
unsigned int facility_list;
int i;
@@ -693,15 +696,22 @@ static void __init setup_hwcaps(void)
* Bit 17: the message-security assist is installed
* Bit 19: the long-displacement facility is installed
* Bit 21: the extended-immediate facility is installed
+ * Bit 22: extended-translation facility 3 is installed
+ * Bit 30: extended-translation facility 3 enhancement facility
* These get translated to:
* HWCAP_S390_ESAN3 bit 0, HWCAP_S390_ZARCH bit 1,
* HWCAP_S390_STFLE bit 2, HWCAP_S390_MSA bit 3,
- * HWCAP_S390_LDISP bit 4, and HWCAP_S390_EIMM bit 5.
+ * HWCAP_S390_LDISP bit 4, HWCAP_S390_EIMM bit 5 and
+ * HWCAP_S390_ETF3EH bit 8 (22 && 30).
*/
for (i = 0; i < 6; i++)
if (facility_list & (1UL << (31 - stfl_bits[i])))
elf_hwcap |= 1UL << i;
+ if ((facility_list & (1UL << (31 - 22)))
+ && (facility_list & (1UL << (31 - 30))))
+ elf_hwcap |= 1UL << 8;
+
/*
* Check for additional facilities with store-facility-list-extended.
* stfle stores doublewords (8 byte) with bit 1ULL<<63 as bit 0
@@ -710,20 +720,22 @@ static void __init setup_hwcaps(void)
* How many facility words are stored depends on the number of
* doublewords passed to the instruction. The additional facilites
* are:
- * Bit 43: decimal floating point facility is installed
+ * Bit 42: decimal floating point facility is installed
+ * Bit 44: perform floating point operation facility is installed
* translated to:
- * HWCAP_S390_DFP bit 6.
+ * HWCAP_S390_DFP bit 6 (42 && 44).
*/
if ((elf_hwcap & (1UL << 2)) &&
__stfle(&facility_list_extended, 1) > 0) {
- if (facility_list_extended & (1ULL << (64 - 43)))
+ if ((facility_list_extended & (1ULL << (63 - 42)))
+ && (facility_list_extended & (1ULL << (63 - 44))))
elf_hwcap |= 1UL << 6;
}
if (MACHINE_HAS_HPAGE)
elf_hwcap |= 1UL << 7;
- switch (cpuinfo->cpu_id.machine) {
+ switch (S390_lowcore.cpu_id.machine) {
case 0x9672:
#if !defined(CONFIG_64BIT)
default: /* Use "g5" as default for 31 bit kernels. */
@@ -816,7 +828,7 @@ setup_arch(char **cmdline_p)
setup_lowcore();
cpu_init();
- __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;
+ __cpu_logical_map[0] = stap();
s390_init_cpu_topology();
/*
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 2d337cbb9329..006ed5016eb4 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -32,6 +32,7 @@
#include <linux/delay.h>
#include <linux/cache.h>
#include <linux/interrupt.h>
+#include <linux/irqflags.h>
#include <linux/cpu.h>
#include <linux/timex.h>
#include <linux/bootmem.h>
@@ -50,12 +51,6 @@
#include <asm/vdso.h>
#include "entry.h"
-/*
- * An array with a pointer the lowcore of every CPU.
- */
-struct _lowcore *lowcore_ptr[NR_CPUS];
-EXPORT_SYMBOL(lowcore_ptr);
-
static struct task_struct *current_set[NR_CPUS];
static u8 smp_cpu_type;
@@ -81,9 +76,7 @@ void smp_send_stop(void)
/* Disable all interrupts/machine checks */
__load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
-
- /* write magic number to zero page (absolute 0) */
- lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
+ trace_hardirqs_off();
/* stop all processors */
for_each_online_cpu(cpu) {
@@ -233,7 +226,7 @@ EXPORT_SYMBOL(smp_ctl_clear_bit);
*/
#define CPU_INIT_NO 1
-#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)
+#ifdef CONFIG_ZFCPDUMP
/*
* zfcpdump_prefix_array holds prefix registers for the following scenario:
@@ -274,7 +267,7 @@ EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { }
-#endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */
+#endif /* CONFIG_ZFCPDUMP */
static int cpu_stopped(int cpu)
{
@@ -304,8 +297,8 @@ static int smp_rescan_cpus_sigp(cpumask_t avail)
{
int cpu_id, logical_cpu;
- logical_cpu = first_cpu(avail);
- if (logical_cpu == NR_CPUS)
+ logical_cpu = cpumask_first(&avail);
+ if (logical_cpu >= nr_cpu_ids)
return 0;
for (cpu_id = 0; cpu_id <= 65535; cpu_id++) {
if (cpu_known(cpu_id))
@@ -316,8 +309,8 @@ static int smp_rescan_cpus_sigp(cpumask_t avail)
continue;
cpu_set(logical_cpu, cpu_present_map);
smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
- logical_cpu = next_cpu(logical_cpu, avail);
- if (logical_cpu == NR_CPUS)
+ logical_cpu = cpumask_next(logical_cpu, &avail);
+ if (logical_cpu >= nr_cpu_ids)
break;
}
return 0;
@@ -329,8 +322,8 @@ static int smp_rescan_cpus_sclp(cpumask_t avail)
int cpu_id, logical_cpu, cpu;
int rc;
- logical_cpu = first_cpu(avail);
- if (logical_cpu == NR_CPUS)
+ logical_cpu = cpumask_first(&avail);
+ if (logical_cpu >= nr_cpu_ids)
return 0;
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info)
@@ -351,8 +344,8 @@ static int smp_rescan_cpus_sclp(cpumask_t avail)
smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY;
else
smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
- logical_cpu = next_cpu(logical_cpu, avail);
- if (logical_cpu == NR_CPUS)
+ logical_cpu = cpumask_next(logical_cpu, &avail);
+ if (logical_cpu >= nr_cpu_ids)
break;
}
out:
@@ -379,7 +372,7 @@ static void __init smp_detect_cpus(void)
c_cpus = 1;
s_cpus = 0;
- boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
+ boot_cpu_addr = __cpu_logical_map[0];
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info)
panic("smp_detect_cpus failed to allocate memory\n");
@@ -453,7 +446,7 @@ int __cpuinit start_secondary(void *cpuvoid)
/* Switch on interrupts */
local_irq_enable();
/* Print info about this processor */
- print_cpu_info(&S390_lowcore.cpu_data);
+ print_cpu_info();
/* cpu_idle will call schedule for us */
cpu_idle();
return 0;
@@ -515,7 +508,6 @@ out:
return -ENOMEM;
}
-#ifdef CONFIG_HOTPLUG_CPU
static void smp_free_lowcore(int cpu)
{
struct _lowcore *lowcore;
@@ -534,7 +526,6 @@ static void smp_free_lowcore(int cpu)
free_pages((unsigned long) lowcore, lc_order);
lowcore_ptr[cpu] = NULL;
}
-#endif /* CONFIG_HOTPLUG_CPU */
/* Upping and downing of CPUs */
int __cpuinit __cpu_up(unsigned int cpu)
@@ -543,16 +534,23 @@ int __cpuinit __cpu_up(unsigned int cpu)
struct _lowcore *cpu_lowcore;
struct stack_frame *sf;
sigp_ccode ccode;
+ u32 lowcore;
if (smp_cpu_state[cpu] != CPU_STATE_CONFIGURED)
return -EIO;
if (smp_alloc_lowcore(cpu))
return -ENOMEM;
-
- ccode = signal_processor_p((__u32)(unsigned long)(lowcore_ptr[cpu]),
- cpu, sigp_set_prefix);
- if (ccode)
- return -EIO;
+ do {
+ ccode = signal_processor(cpu, sigp_initial_cpu_reset);
+ if (ccode == sigp_busy)
+ udelay(10);
+ if (ccode == sigp_not_operational)
+ goto err_out;
+ } while (ccode == sigp_busy);
+
+ lowcore = (u32)(unsigned long)lowcore_ptr[cpu];
+ while (signal_processor_p(lowcore, cpu, sigp_set_prefix) == sigp_busy)
+ udelay(10);
idle = current_set[cpu];
cpu_lowcore = lowcore_ptr[cpu];
@@ -571,9 +569,8 @@ int __cpuinit __cpu_up(unsigned int cpu)
: : "a" (&cpu_lowcore->access_regs_save_area) : "memory");
cpu_lowcore->percpu_offset = __per_cpu_offset[cpu];
cpu_lowcore->current_task = (unsigned long) idle;
- cpu_lowcore->cpu_data.cpu_nr = cpu;
+ cpu_lowcore->cpu_nr = cpu;
cpu_lowcore->kernel_asce = S390_lowcore.kernel_asce;
- cpu_lowcore->ipl_device = S390_lowcore.ipl_device;
eieio();
while (signal_processor(cpu, sigp_restart) == sigp_busy)
@@ -582,6 +579,10 @@ int __cpuinit __cpu_up(unsigned int cpu)
while (!cpu_online(cpu))
cpu_relax();
return 0;
+
+err_out:
+ smp_free_lowcore(cpu);
+ return -EIO;
}
static int __init setup_possible_cpus(char *s)
@@ -589,9 +590,8 @@ static int __init setup_possible_cpus(char *s)
int pcpus, cpu;
pcpus = simple_strtoul(s, NULL, 0);
- cpu_possible_map = cpumask_of_cpu(0);
- for (cpu = 1; cpu < pcpus && cpu < NR_CPUS; cpu++)
- cpu_set(cpu, cpu_possible_map);
+ for (cpu = 0; cpu < pcpus && cpu < nr_cpu_ids; cpu++)
+ set_cpu_possible(cpu, true);
return 0;
}
early_param("possible_cpus", setup_possible_cpus);
@@ -663,7 +663,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
/* request the 0x1201 emergency signal external interrupt */
if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
panic("Couldn't request external interrupt 0x1201");
- print_cpu_info(&S390_lowcore.cpu_data);
+ print_cpu_info();
/* Reallocate current lowcore, but keep its contents. */
lc_order = sizeof(long) == 8 ? 1 : 0;
diff --git a/drivers/s390/sysinfo.c b/arch/s390/kernel/sysinfo.c
index 0eea90781385..b5e75e1061c8 100644
--- a/drivers/s390/sysinfo.c
+++ b/arch/s390/kernel/sysinfo.c
@@ -1,9 +1,7 @@
/*
- * drivers/s390/sysinfo.c
- *
- * Copyright IBM Corp. 2001, 2008
- * Author(s): Ulrich Weigand (Ulrich.Weigand@de.ibm.com)
- * Martin Schwidefsky <schwidefsky@de.ibm.com>
+ * Copyright IBM Corp. 2001, 2009
+ * Author(s): Ulrich Weigand <Ulrich.Weigand@de.ibm.com>,
+ * Martin Schwidefsky <schwidefsky@de.ibm.com>,
*/
#include <linux/kernel.h>
@@ -24,7 +22,7 @@
static inline int stsi_0(void)
{
- int rc = stsi (NULL, 0, 0, 0);
+ int rc = stsi(NULL, 0, 0, 0);
return rc == -ENOSYS ? rc : (((unsigned int) rc) >> 28);
}
@@ -78,23 +76,6 @@ static int stsi_1_1_1(struct sysinfo_1_1_1 *info, char *page, int len)
return len;
}
-#if 0 /* Currently unused */
-static int stsi_1_2_1(struct sysinfo_1_2_1 *info, char *page, int len)
-{
- if (stsi(info, 1, 2, 1) == -ENOSYS)
- return len;
-
- len += sprintf(page + len, "\n");
- EBCASC(info->sequence, sizeof(info->sequence));
- EBCASC(info->plant, sizeof(info->plant));
- len += sprintf(page + len, "Sequence Code of CPU: %-16.16s\n",
- info->sequence);
- len += sprintf(page + len, "Plant of CPU: %-16.16s\n",
- info->plant);
- return len;
-}
-#endif
-
static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
{
struct sysinfo_1_2_2_extension *ext;
@@ -145,33 +126,15 @@ static int stsi_1_2_2(struct sysinfo_1_2_2 *info, char *page, int len)
if (info->secondary_capability != 0)
len += sprintf(page + len, "Secondary Capability: %d\n",
info->secondary_capability);
-
return len;
}
-#if 0 /* Currently unused */
-static int stsi_2_2_1(struct sysinfo_2_2_1 *info, char *page, int len)
-{
- if (stsi(info, 2, 2, 1) == -ENOSYS)
- return len;
-
- len += sprintf(page + len, "\n");
- EBCASC (info->sequence, sizeof(info->sequence));
- EBCASC (info->plant, sizeof(info->plant));
- len += sprintf(page + len, "Sequence Code of logical CPU: %-16.16s\n",
- info->sequence);
- len += sprintf(page + len, "Plant of logical CPU: %-16.16s\n",
- info->plant);
- return len;
-}
-#endif
-
static int stsi_2_2_2(struct sysinfo_2_2_2 *info, char *page, int len)
{
if (stsi(info, 2, 2, 2) == -ENOSYS)
return len;
- EBCASC (info->name, sizeof(info->name));
+ EBCASC(info->name, sizeof(info->name));
len += sprintf(page + len, "\n");
len += sprintf(page + len, "LPAR Number: %d\n",
@@ -214,8 +177,8 @@ static int stsi_3_2_2(struct sysinfo_3_2_2 *info, char *page, int len)
if (stsi(info, 3, 2, 2) == -ENOSYS)
return len;
for (i = 0; i < info->count; i++) {
- EBCASC (info->vm[i].name, sizeof(info->vm[i].name));
- EBCASC (info->vm[i].cpi, sizeof(info->vm[i].cpi));
+ EBCASC(info->vm[i].name, sizeof(info->vm[i].name));
+ EBCASC(info->vm[i].cpi, sizeof(info->vm[i].cpi));
len += sprintf(page + len, "\n");
len += sprintf(page + len, "VM%02d Name: %-8.8s\n",
i, info->vm[i].name);
@@ -237,14 +200,13 @@ static int stsi_3_2_2(struct sysinfo_3_2_2 *info, char *page, int len)
return len;
}
-
static int proc_read_sysinfo(char *page, char **start,
- off_t off, int count,
- int *eof, void *data)
+ off_t off, int count,
+ int *eof, void *data)
{
- unsigned long info = get_zeroed_page (GFP_KERNEL);
+ unsigned long info = get_zeroed_page(GFP_KERNEL);
int level, len;
-
+
if (!info)
return 0;
@@ -262,8 +224,8 @@ static int proc_read_sysinfo(char *page, char **start,
if (level >= 3)
len = stsi_3_2_2((struct sysinfo_3_2_2 *) info, page, len);
- free_page (info);
- return len;
+ free_page(info);
+ return len;
}
static __init int create_proc_sysinfo(void)
@@ -272,8 +234,7 @@ static __init int create_proc_sysinfo(void)
proc_read_sysinfo, NULL);
return 0;
}
-
-__initcall(create_proc_sysinfo);
+device_initcall(create_proc_sysinfo);
/*
* Service levels interface.
@@ -387,13 +348,11 @@ static __init int create_proc_service_level(void)
register_service_level(&service_level_vm);
return 0;
}
-
subsys_initcall(create_proc_service_level);
/*
* Bogomips calculation based on cpu capability.
*/
-
int get_cpu_capability(unsigned int *capability)
{
struct sysinfo_1_2_2 *info;
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index fc468cae4460..f72d41068dc2 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -331,6 +331,7 @@ static unsigned long long adjust_time(unsigned long long old,
}
static DEFINE_PER_CPU(atomic_t, clock_sync_word);
+static DEFINE_MUTEX(clock_sync_mutex);
static unsigned long clock_sync_flags;
#define CLOCK_SYNC_HAS_ETR 0
@@ -394,6 +395,20 @@ static void enable_sync_clock(void)
atomic_set_mask(0x80000000, sw_ptr);
}
+/*
+ * Function to check if the clock is in sync.
+ */
+static inline int check_sync_clock(void)
+{
+ atomic_t *sw_ptr;
+ int rc;
+
+ sw_ptr = &get_cpu_var(clock_sync_word);
+ rc = (atomic_read(sw_ptr) & 0x80000000U) != 0;
+ put_cpu_var(clock_sync_sync);
+ return rc;
+}
+
/* Single threaded workqueue used for etr and stp sync events */
static struct workqueue_struct *time_sync_wq;
@@ -485,6 +500,8 @@ static void etr_reset(void)
if (etr_setr(&etr_eacr) == 0) {
etr_tolec = get_clock();
set_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags);
+ if (etr_port0_online && etr_port1_online)
+ set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
} else if (etr_port0_online || etr_port1_online) {
pr_warning("The real or virtual hardware system does "
"not provide an ETR interface\n");
@@ -533,8 +550,7 @@ void etr_switch_to_local(void)
{
if (!etr_eacr.sl)
return;
- if (test_bit(CLOCK_SYNC_ETR, &clock_sync_flags))
- disable_sync_clock(NULL);
+ disable_sync_clock(NULL);
set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events);
queue_work(time_sync_wq, &etr_work);
}
@@ -549,8 +565,7 @@ void etr_sync_check(void)
{
if (!etr_eacr.es)
return;
- if (test_bit(CLOCK_SYNC_ETR, &clock_sync_flags))
- disable_sync_clock(NULL);
+ disable_sync_clock(NULL);
set_bit(ETR_EVENT_SYNC_CHECK, &etr_events);
queue_work(time_sync_wq, &etr_work);
}
@@ -914,7 +929,7 @@ static struct etr_eacr etr_handle_update(struct etr_aib *aib,
* Do not try to get the alternate port aib if the clock
* is not in sync yet.
*/
- if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags) && !eacr.es)
+ if (!check_sync_clock())
return eacr;
/*
@@ -997,7 +1012,6 @@ static void etr_work_fn(struct work_struct *work)
on_each_cpu(disable_sync_clock, NULL, 1);
del_timer_sync(&etr_timer);
etr_update_eacr(eacr);
- clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
goto out_unlock;
}
@@ -1071,18 +1085,13 @@ static void etr_work_fn(struct work_struct *work)
/* Both ports not usable. */
eacr.es = eacr.sl = 0;
sync_port = -1;
- clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
}
- if (!test_bit(CLOCK_SYNC_ETR, &clock_sync_flags))
- eacr.es = 0;
-
/*
* If the clock is in sync just update the eacr and return.
* If there is no valid sync port wait for a port update.
*/
- if (test_bit(CLOCK_SYNC_STP, &clock_sync_flags) ||
- eacr.es || sync_port < 0) {
+ if (check_sync_clock() || sync_port < 0) {
etr_update_eacr(eacr);
etr_set_tolec_timeout(now);
goto out_unlock;
@@ -1103,13 +1112,11 @@ static void etr_work_fn(struct work_struct *work)
* and set up a timer to try again after 0.5 seconds
*/
etr_update_eacr(eacr);
- set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
if (now < etr_tolec + (1600000 << 12) ||
etr_sync_clock_stop(&aib, sync_port) != 0) {
/* Sync failed. Try again in 1/2 second. */
eacr.es = 0;
etr_update_eacr(eacr);
- clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
etr_set_sync_timeout();
} else
etr_set_tolec_timeout(now);
@@ -1191,19 +1198,30 @@ static ssize_t etr_online_store(struct sys_device *dev,
return -EINVAL;
if (!test_bit(CLOCK_SYNC_HAS_ETR, &clock_sync_flags))
return -EOPNOTSUPP;
+ mutex_lock(&clock_sync_mutex);
if (dev == &etr_port0_dev) {
if (etr_port0_online == value)
- return count; /* Nothing to do. */
+ goto out; /* Nothing to do. */
etr_port0_online = value;
+ if (etr_port0_online && etr_port1_online)
+ set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
+ else
+ clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events);
queue_work(time_sync_wq, &etr_work);
} else {
if (etr_port1_online == value)
- return count; /* Nothing to do. */
+ goto out; /* Nothing to do. */
etr_port1_online = value;
+ if (etr_port0_online && etr_port1_online)
+ set_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
+ else
+ clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events);
queue_work(time_sync_wq, &etr_work);
}
+out:
+ mutex_unlock(&clock_sync_mutex);
return count;
}
@@ -1471,8 +1489,6 @@ static void stp_timing_alert(struct stp_irq_parm *intparm)
*/
void stp_sync_check(void)
{
- if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags))
- return;
disable_sync_clock(NULL);
queue_work(time_sync_wq, &stp_work);
}
@@ -1485,8 +1501,6 @@ void stp_sync_check(void)
*/
void stp_island_check(void)
{
- if (!test_bit(CLOCK_SYNC_STP, &clock_sync_flags))
- return;
disable_sync_clock(NULL);
queue_work(time_sync_wq, &stp_work);
}
@@ -1513,10 +1527,6 @@ static int stp_sync_clock(void *data)
enable_sync_clock();
- set_bit(CLOCK_SYNC_STP, &clock_sync_flags);
- if (test_and_clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags))
- queue_work(time_sync_wq, &etr_work);
-
rc = 0;
if (stp_info.todoff[0] || stp_info.todoff[1] ||
stp_info.todoff[2] || stp_info.todoff[3] ||
@@ -1535,9 +1545,6 @@ static int stp_sync_clock(void *data)
if (rc) {
disable_sync_clock(NULL);
stp_sync->in_sync = -EAGAIN;
- clear_bit(CLOCK_SYNC_STP, &clock_sync_flags);
- if (etr_port0_online || etr_port1_online)
- queue_work(time_sync_wq, &etr_work);
} else
stp_sync->in_sync = 1;
xchg(&first, 0);
@@ -1569,6 +1576,10 @@ static void stp_work_fn(struct work_struct *work)
if (rc || stp_info.c == 0)
goto out_unlock;
+ /* Skip synchronization if the clock is already in sync. */
+ if (check_sync_clock())
+ goto out_unlock;
+
memset(&stp_sync, 0, sizeof(stp_sync));
get_online_cpus();
atomic_set(&stp_sync.cpus, num_online_cpus() - 1);
@@ -1684,8 +1695,14 @@ static ssize_t stp_online_store(struct sysdev_class *class,
return -EINVAL;
if (!test_bit(CLOCK_SYNC_HAS_STP, &clock_sync_flags))
return -EOPNOTSUPP;
+ mutex_lock(&clock_sync_mutex);
stp_online = value;
+ if (stp_online)
+ set_bit(CLOCK_SYNC_STP, &clock_sync_flags);
+ else
+ clear_bit(CLOCK_SYNC_STP, &clock_sync_flags);
queue_work(time_sync_wq, &stp_work);
+ mutex_unlock(&clock_sync_mutex);
return count;
}
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index cc362c9ea8f1..3c72c9cf22b6 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -74,7 +74,7 @@ static DEFINE_SPINLOCK(topology_lock);
cpumask_t cpu_core_map[NR_CPUS];
-cpumask_t cpu_coregroup_map(unsigned int cpu)
+static cpumask_t cpu_coregroup_map(unsigned int cpu)
{
struct core_info *core = &core_info;
unsigned long flags;
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 4584d81984c0..c2e42cc65ce7 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -61,9 +61,11 @@ extern pgm_check_handler_t do_asce_exception;
#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
#ifndef CONFIG_64BIT
+#define LONG "%08lx "
#define FOURLONG "%08lx %08lx %08lx %08lx\n"
static int kstack_depth_to_print = 12;
#else /* CONFIG_64BIT */
+#define LONG "%016lx "
#define FOURLONG "%016lx %016lx %016lx %016lx\n"
static int kstack_depth_to_print = 20;
#endif /* CONFIG_64BIT */
@@ -155,7 +157,7 @@ void show_stack(struct task_struct *task, unsigned long *sp)
break;
if (i && ((i * sizeof (long) % 32) == 0))
printk("\n ");
- printk("%p ", (void *)*stack++);
+ printk(LONG, *stack++);
}
printk("\n");
show_trace(task, sp);
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index 690e17819686..89b2e7f1b7a9 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -144,7 +144,6 @@ out:
return -ENOMEM;
}
-#ifdef CONFIG_HOTPLUG_CPU
void vdso_free_per_cpu(int cpu, struct _lowcore *lowcore)
{
unsigned long segment_table, page_table, page_frame;
@@ -163,7 +162,6 @@ void vdso_free_per_cpu(int cpu, struct _lowcore *lowcore)
free_page(page_table);
free_pages(segment_table, SEGMENT_ORDER);
}
-#endif /* CONFIG_HOTPLUG_CPU */
static void __vdso_init_cr5(void *dummy)
{
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index d796d05c9c01..7a2063eb88f0 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -108,6 +108,8 @@ SECTIONS
EXIT_TEXT
}
+ /* early.c uses stsi, which requires page aligned data. */
+ . = ALIGN(PAGE_SIZE);
.init.data : {
INIT_DATA
}
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index e051cad1f1e0..3e260b7e37b2 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -4,6 +4,9 @@
config HAVE_KVM
bool
+config HAVE_KVM_IRQCHIP
+ bool
+
menuconfig VIRTUALIZATION
bool "Virtualization"
default y
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 61236102203e..9d19803111ba 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -103,7 +103,7 @@ static int handle_lctl(struct kvm_vcpu *vcpu)
static intercept_handler_t instruction_handlers[256] = {
[0x83] = kvm_s390_handle_diag,
[0xae] = kvm_s390_handle_sigp,
- [0xb2] = kvm_s390_handle_priv,
+ [0xb2] = kvm_s390_handle_b2,
[0xb7] = handle_lctl,
[0xeb] = handle_lctlg,
};
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index f4fe28a2521a..0189356fe209 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -555,9 +555,14 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
VCPU_EVENT(vcpu, 3, "inject: program check %d (from user)",
s390int->parm);
break;
+ case KVM_S390_SIGP_SET_PREFIX:
+ inti->prefix.address = s390int->parm;
+ inti->type = s390int->type;
+ VCPU_EVENT(vcpu, 3, "inject: set prefix to %x (from user)",
+ s390int->parm);
+ break;
case KVM_S390_SIGP_STOP:
case KVM_S390_RESTART:
- case KVM_S390_SIGP_SET_PREFIX:
case KVM_S390_INT_EMERGENCY:
VCPU_EVENT(vcpu, 3, "inject: type %x", s390int->type);
inti->type = s390int->type;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 0d33893e1e89..f4d56e9939c9 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -23,7 +23,7 @@
#include <linux/timer.h>
#include <asm/lowcore.h>
#include <asm/pgtable.h>
-
+#include <asm/nmi.h>
#include "kvm-s390.h"
#include "gaccess.h"
@@ -286,7 +286,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
setup_timer(&vcpu->arch.ckc_timer, kvm_s390_idle_wakeup,
(unsigned long) vcpu);
get_cpu_id(&vcpu->arch.cpu_id);
- vcpu->arch.cpu_id.version = 0xfe;
+ vcpu->arch.cpu_id.version = 0xff;
return 0;
}
@@ -422,8 +422,8 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
return -EINVAL; /* not implemented yet */
}
-int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
- struct kvm_debug_guest *dbg)
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+ struct kvm_guest_debug *dbg)
{
return -EINVAL; /* not implemented yet */
}
@@ -440,8 +440,6 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
return -EINVAL; /* not implemented yet */
}
-extern void s390_handle_mcck(void);
-
static void __vcpu_run(struct kvm_vcpu *vcpu)
{
memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 3893cf12eacf..00bbe69b78da 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -50,7 +50,7 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code);
/* implemented in priv.c */
-int kvm_s390_handle_priv(struct kvm_vcpu *vcpu);
+int kvm_s390_handle_b2(struct kvm_vcpu *vcpu);
/* implemented in sigp.c */
int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 3605df45dd41..4b88834b8dd8 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -304,12 +304,24 @@ static intercept_handler_t priv_handlers[256] = {
[0xb1] = handle_stfl,
};
-int kvm_s390_handle_priv(struct kvm_vcpu *vcpu)
+int kvm_s390_handle_b2(struct kvm_vcpu *vcpu)
{
intercept_handler_t handler;
+ /*
+ * a lot of B2 instructions are priviledged. We first check for
+ * the priviledges ones, that we can handle in the kernel. If the
+ * kernel can handle this instruction, we check for the problem
+ * state bit and (a) handle the instruction or (b) send a code 2
+ * program check.
+ * Anything else goes to userspace.*/
handler = priv_handlers[vcpu->arch.sie_block->ipa & 0x00ff];
- if (handler)
- return handler(vcpu);
+ if (handler) {
+ if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+ return kvm_s390_inject_program_int(vcpu,
+ PGM_PRIVILEGED_OPERATION);
+ else
+ return handler(vcpu);
+ }
return -ENOTSUPP;
}
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index 2a01b9e02801..f27dbedf0866 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -153,8 +153,6 @@ static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter)
switch (parameter & 0xff) {
case 0:
- printk(KERN_WARNING "kvm: request to switch to ESA/390 mode"
- " not supported");
rc = 3; /* not operational */
break;
case 1:
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c
index 6ccb9fab055a..3f5f680726ed 100644
--- a/arch/s390/lib/delay.c
+++ b/arch/s390/lib/delay.c
@@ -9,6 +9,7 @@
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/timex.h>
+#include <linux/module.h>
#include <linux/irqflags.h>
#include <linux/interrupt.h>
@@ -92,6 +93,7 @@ out:
local_irq_restore(flags);
preempt_enable();
}
+EXPORT_SYMBOL(__udelay);
/*
* Simple udelay variant. To be used on startup and reboot
diff --git a/arch/s390/lib/string.c b/arch/s390/lib/string.c
index ae5cf5d03d41..4143b7c19096 100644
--- a/arch/s390/lib/string.c
+++ b/arch/s390/lib/string.c
@@ -44,7 +44,11 @@ static inline char *__strnend(const char *s, size_t n)
*/
size_t strlen(const char *s)
{
+#if __GNUC__ < 4
return __strend(s) - s;
+#else
+ return __builtin_strlen(s);
+#endif
}
EXPORT_SYMBOL(strlen);
@@ -70,6 +74,7 @@ EXPORT_SYMBOL(strnlen);
*/
char *strcpy(char *dest, const char *src)
{
+#if __GNUC__ < 4
register int r0 asm("0") = 0;
char *ret = dest;
@@ -78,6 +83,9 @@ char *strcpy(char *dest, const char *src)
: "+&a" (dest), "+&a" (src) : "d" (r0)
: "cc", "memory" );
return ret;
+#else
+ return __builtin_strcpy(dest, src);
+#endif
}
EXPORT_SYMBOL(strcpy);
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 4d537205e83c..833e8366c351 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -200,29 +200,6 @@ static void do_low_address(struct pt_regs *regs, unsigned long error_code)
do_no_context(regs, error_code, 0);
}
-/*
- * We ran out of memory, or some other thing happened to us that made
- * us unable to handle the page fault gracefully.
- */
-static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code,
- unsigned long address)
-{
- struct task_struct *tsk = current;
- struct mm_struct *mm = tsk->mm;
-
- up_read(&mm->mmap_sem);
- if (is_global_init(tsk)) {
- yield();
- down_read(&mm->mmap_sem);
- return 1;
- }
- printk("VM: killing process %s\n", tsk->comm);
- if (regs->psw.mask & PSW_MASK_PSTATE)
- do_group_exit(SIGKILL);
- do_no_context(regs, error_code, address);
- return 0;
-}
-
static void do_sigbus(struct pt_regs *regs, unsigned long error_code,
unsigned long address)
{
@@ -367,7 +344,6 @@ good_area:
goto bad_area;
}
-survive:
if (is_vm_hugetlb_page(vma))
address &= HPAGE_MASK;
/*
@@ -378,8 +354,8 @@ survive:
fault = handle_mm_fault(mm, vma, address, write);
if (unlikely(fault & VM_FAULT_ERROR)) {
if (fault & VM_FAULT_OOM) {
- if (do_out_of_memory(regs, error_code, address))
- goto survive;
+ up_read(&mm->mmap_sem);
+ pagefault_out_of_memory();
return;
} else if (fault & VM_FAULT_SIGBUS) {
do_sigbus(regs, error_code, address);
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index f0258ca3b17e..c634dfbe92e9 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -40,7 +40,9 @@
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE)));
+
char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
+EXPORT_SYMBOL(empty_zero_page);
/*
* paging_init() sets up the page tables
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 6b6ddc4ea02b..be6c1cf4ad5a 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -258,6 +258,10 @@ int s390_enable_sie(void)
struct task_struct *tsk = current;
struct mm_struct *mm, *old_mm;
+ /* Do we have switched amode? If no, we cannot do sie */
+ if (!switch_amode)
+ return -EINVAL;
+
/* Do we have pgstes? if yes, we are done */
if (tsk->mm->context.has_pgste)
return 0;
@@ -292,7 +296,7 @@ int s390_enable_sie(void)
tsk->mm = tsk->active_mm = mm;
preempt_disable();
update_mm(mm, tsk);
- cpu_set(smp_processor_id(), mm->cpu_vm_mask);
+ cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
preempt_enable();
task_unlock(tsk);
mmput(old_mm);
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index ebabe518e729..5e4babecf934 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -28,6 +28,7 @@ config SUPERH32
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE
select HAVE_ARCH_KGDB
+ select ARCH_HIBERNATION_POSSIBLE if MMU
config SUPERH64
def_bool y if CPU_SH5
@@ -107,6 +108,9 @@ config SYS_SUPPORTS_NUMA
config SYS_SUPPORTS_PCI
bool
+config SYS_SUPPORTS_CMT
+ bool
+
config STACKTRACE_SUPPORT
def_bool y
@@ -126,6 +130,9 @@ config ARCH_HAS_ILOG2_U64
config ARCH_NO_VIRT_TO_BUS
def_bool y
+config ARCH_HAS_DEFAULT_IDLE
+ def_bool y
+
config IO_TRAPPED
bool
@@ -176,6 +183,10 @@ config CPU_SHX2
config CPU_SHX3
bool
+config ARCH_SHMOBILE
+ bool
+ select ARCH_SUSPEND_POSSIBLE
+
choice
prompt "Processor sub-type selection"
@@ -188,6 +199,7 @@ choice
config CPU_SUBTYPE_SH7619
bool "Support SH7619 processor"
select CPU_SH2
+ select SYS_SUPPORTS_CMT
# SH-2A Processor Support
@@ -200,15 +212,18 @@ config CPU_SUBTYPE_SH7203
bool "Support SH7203 processor"
select CPU_SH2A
select CPU_HAS_FPU
+ select SYS_SUPPORTS_CMT
config CPU_SUBTYPE_SH7206
bool "Support SH7206 processor"
select CPU_SH2A
+ select SYS_SUPPORTS_CMT
config CPU_SUBTYPE_SH7263
bool "Support SH7263 processor"
select CPU_SH2A
select CPU_HAS_FPU
+ select SYS_SUPPORTS_CMT
config CPU_SUBTYPE_MXG
bool "Support MX-G processor"
@@ -323,7 +338,9 @@ config CPU_SUBTYPE_SH7723
bool "Support SH7723 processor"
select CPU_SH4A
select CPU_SHX2
+ select ARCH_SHMOBILE
select ARCH_SPARSEMEM_ENABLE
+ select SYS_SUPPORTS_CMT
help
Select SH7723 if you have an SH-MobileR2 CPU.
@@ -348,6 +365,14 @@ config CPU_SUBTYPE_SH7785
select ARCH_SPARSEMEM_ENABLE
select SYS_SUPPORTS_NUMA
+config CPU_SUBTYPE_SH7786
+ bool "Support SH7786 processor"
+ select CPU_SH4A
+ select CPU_SHX3
+ select CPU_HAS_PTEAEX
+ select ARCH_SPARSEMEM_ENABLE
+ select SYS_SUPPORTS_NUMA
+
config CPU_SUBTYPE_SHX3
bool "Support SH-X3 processor"
select CPU_SH4A
@@ -362,20 +387,26 @@ config CPU_SUBTYPE_SHX3
config CPU_SUBTYPE_SH7343
bool "Support SH7343 processor"
select CPU_SH4AL_DSP
+ select ARCH_SHMOBILE
+ select SYS_SUPPORTS_CMT
config CPU_SUBTYPE_SH7722
bool "Support SH7722 processor"
select CPU_SH4AL_DSP
select CPU_SHX2
+ select ARCH_SHMOBILE
select ARCH_SPARSEMEM_ENABLE
select SYS_SUPPORTS_NUMA
+ select SYS_SUPPORTS_CMT
config CPU_SUBTYPE_SH7366
bool "Support SH7366 processor"
select CPU_SH4AL_DSP
select CPU_SHX2
+ select ARCH_SHMOBILE
select ARCH_SPARSEMEM_ENABLE
select SYS_SUPPORTS_NUMA
+ select SYS_SUPPORTS_CMT
# SH-5 Processor Support
@@ -398,25 +429,34 @@ source "arch/sh/boards/Kconfig"
menu "Timer and clock configuration"
config SH_TMU
- def_bool y
- prompt "TMU timer support"
+ bool "TMU timer support"
depends on CPU_SH3 || CPU_SH4
+ default y
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
This enables the use of the TMU as the system timer.
config SH_CMT
- def_bool y
- prompt "CMT timer support"
- depends on CPU_SH2 && !CPU_SUBTYPE_MXG
+ bool "CMT timer support"
+ depends on SYS_SUPPORTS_CMT && CPU_SH2
+ default y
help
This enables the use of the CMT as the system timer.
+#
+# Support for the new-style CMT driver. This will replace SH_CMT
+# once its other dependencies are merged.
+#
+config SH_TIMER_CMT
+ bool "CMT clockevents driver"
+ depends on SYS_SUPPORTS_CMT && !SH_CMT
+ select GENERIC_CLOCKEVENTS
+
config SH_MTU2
- def_bool n
- prompt "MTU2 timer support"
+ bool "MTU2 timer support"
depends on CPU_SH2A
+ default y
help
This enables the use of the MTU2 as the system timer.
@@ -426,7 +466,8 @@ config SH_TIMER_IRQ
CPU_SUBTYPE_SH7763
default "86" if CPU_SUBTYPE_SH7619
default "140" if CPU_SUBTYPE_SH7206
- default "142" if CPU_SUBTYPE_SH7203
+ default "142" if CPU_SUBTYPE_SH7203 && SH_CMT
+ default "153" if CPU_SUBTYPE_SH7203 && SH_MTU2
default "238" if CPU_SUBTYPE_MXG
default "16"
@@ -438,7 +479,8 @@ config SH_PCLK_FREQ
default "33333333" if CPU_SUBTYPE_SH7770 || CPU_SUBTYPE_SH7723 || \
CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \
CPU_SUBTYPE_SH7203 || CPU_SUBTYPE_SH7206 || \
- CPU_SUBTYPE_SH7263 || CPU_SUBTYPE_MXG
+ CPU_SUBTYPE_SH7263 || CPU_SUBTYPE_MXG || \
+ CPU_SUBTYPE_SH7786
default "60000000" if CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7751R
default "66000000" if CPU_SUBTYPE_SH4_202
default "50000000"
@@ -492,7 +534,7 @@ source kernel/Kconfig.hz
config KEXEC
bool "kexec system call (EXPERIMENTAL)"
- depends on SUPERH32 && EXPERIMENTAL
+ depends on SUPERH32 && EXPERIMENTAL && MMU
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
@@ -521,6 +563,13 @@ config CRASH_DUMP
For more details see Documentation/kdump/kdump.txt
+config KEXEC_JUMP
+ bool "kexec jump (EXPERIMENTAL)"
+ depends on SUPERH32 && KEXEC && HIBERNATION && EXPERIMENTAL
+ help
+ Jump between original kernel and kexeced kernel and invoke
+ code via KEXEC
+
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
depends on PROC_FS
@@ -595,10 +644,10 @@ config GUSA_RB
depends on GUSA && CPU_SH3 || (CPU_SH4 && !CPU_SH4A)
help
Enabling this option will allow the kernel to implement some
- atomic operations using a software implemention of load-locked/
+ atomic operations using a software implementation of load-locked/
store-conditional (LLSC). On machines which do not have hardware
LLSC, this should be more efficient than the other alternative of
- disabling insterrupts around the atomic sequence.
+ disabling interrupts around the atomic sequence.
endmenu
diff --git a/arch/sh/Kconfig.cpu b/arch/sh/Kconfig.cpu
index 0e27fe3b182b..c7d704381a6d 100644
--- a/arch/sh/Kconfig.cpu
+++ b/arch/sh/Kconfig.cpu
@@ -104,6 +104,9 @@ config CPU_HAS_SR_RB
config CPU_HAS_PTEA
bool
+config CPU_HAS_PTEAEX
+ bool
+
config CPU_HAS_DSP
bool
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 4067b0d9287b..bece1f7535f2 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -80,6 +80,7 @@ OBJCOPYFLAGS := -O binary -R .note -R .note.gnu.build-id -R .comment \
defaultimage-$(CONFIG_SUPERH32) := zImage
defaultimage-$(CONFIG_SH_SH7785LCR) := uImage
defaultimage-$(CONFIG_SH_RSK) := uImage
+defaultimage-$(CONFIG_SH_URQUELL) := uImage
defaultimage-$(CONFIG_SH_7206_SOLUTION_ENGINE) := vmlinux
defaultimage-$(CONFIG_SH_7619_SOLUTION_ENGINE) := vmlinux
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 861914747e4e..dcc1af8a2cfe 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -155,17 +155,22 @@ config SH_SH7785LCR
config SH_SH7785LCR_29BIT_PHYSMAPS
bool "SH7785LCR 29bit physmaps"
- depends on SH_SH7785LCR
+ depends on SH_SH7785LCR && 29BIT
default y
help
This board has 2 physical memory maps. It can be changed with
DIP switch(S2-5). If you set the DIP switch for S2-5 = ON,
you can access all on-board device in 29bit address mode.
+config SH_URQUELL
+ bool "Urquell"
+ depends on CPU_SUBTYPE_SH7786
+ select ARCH_REQUIRE_GPIOLIB
+
config SH_MIGOR
bool "Migo-R"
depends on CPU_SUBTYPE_SH7722
- select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
help
Select Migo-R if configuring for the SH7722 Migo-R platform
by Renesas System Solutions Asia Pte. Ltd.
@@ -173,7 +178,7 @@ config SH_MIGOR
config SH_AP325RXA
bool "AP-325RXA"
depends on CPU_SUBTYPE_SH7723
- select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
help
Renesas "AP-325RXA" support.
Compatible with ALGO SYSTEM CO.,LTD. "AP-320A"
@@ -185,6 +190,13 @@ config SH_SH7763RDP
Select SH7763RDP if configuring for a Renesas SH7763
evaluation board.
+config SH_ESPT
+ bool "ESPT"
+ depends on CPU_SUBTYPE_SH7763
+ help
+ Select ESPT if configuring for a Renesas SH7763
+ with gigabit ether evaluation board.
+
config SH_EDOSK7705
bool "EDOSK7705"
depends on CPU_SUBTYPE_SH7705
@@ -240,7 +252,7 @@ config SH_X3PROTO
config SH_MAGIC_PANEL_R2
bool "Magic Panel R2"
depends on CPU_SUBTYPE_SH7720
- select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
help
Select Magic Panel R2 if configuring for Magic Panel R2.
@@ -249,6 +261,13 @@ config SH_CAYMAN
depends on CPU_SUBTYPE_SH5_101 || CPU_SUBTYPE_SH5_103
select SYS_SUPPORTS_PCI
+config SH_POLARIS
+ bool "SMSC Polaris"
+ select CPU_HAS_IPR_IRQ
+ depends on CPU_SUBTYPE_SH7709
+ help
+ Select if configuring for an SMSC Polaris development board
+
endmenu
source "arch/sh/boards/mach-r2d/Kconfig"
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile
index 269ae2be49ef..7baa21090231 100644
--- a/arch/sh/boards/Makefile
+++ b/arch/sh/boards/Makefile
@@ -4,5 +4,8 @@
obj-$(CONFIG_SH_AP325RXA) += board-ap325rxa.o
obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o
obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o
+obj-$(CONFIG_SH_URQUELL) += board-urquell.o
obj-$(CONFIG_SH_SHMIN) += board-shmin.o
obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o
+obj-$(CONFIG_SH_ESPT) += board-espt.o
+obj-$(CONFIG_SH_POLARIS) += board-polaris.o
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
index 15b6d450fbf0..912458f666eb 100644
--- a/arch/sh/boards/board-ap325rxa.c
+++ b/arch/sh/boards/board-ap325rxa.c
@@ -22,6 +22,7 @@
#include <linux/gpio.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_gpio.h>
+#include <media/ov772x.h>
#include <media/soc_camera.h>
#include <media/soc_camera_platform.h>
#include <media/sh_mobile_ceu.h>
@@ -166,6 +167,16 @@ static void ap320_wvga_power_on(void *board_data)
ctrl_outw(0x100, FPGA_BKLREG);
}
+static void ap320_wvga_power_off(void *board_data)
+{
+ /* backlight */
+ ctrl_outw(0, FPGA_BKLREG);
+ gpio_set_value(GPIO_PTS3, 1);
+
+ /* ASD AP-320/325 LCD OFF */
+ ctrl_outw(0, FPGA_LCDREG);
+}
+
static struct sh_mobile_lcdc_info lcdc_info = {
.clock_source = LCDC_CLK_EXTERNAL,
.ch[0] = {
@@ -191,6 +202,7 @@ static struct sh_mobile_lcdc_info lcdc_info = {
},
.board_cfg = {
.display_on = ap320_wvga_power_on,
+ .display_off = ap320_wvga_power_off,
},
}
};
@@ -224,6 +236,7 @@ static void camera_power(int val)
}
#ifdef CONFIG_I2C
+/* support for the old ncm03j camera */
static unsigned char camera_ncm03j_magic[] =
{
0x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,
@@ -244,6 +257,23 @@ static unsigned char camera_ncm03j_magic[] =
0x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,
};
+static int camera_probe(void)
+{
+ struct i2c_adapter *a = i2c_get_adapter(0);
+ struct i2c_msg msg;
+ int ret;
+
+ camera_power(1);
+ msg.addr = 0x6e;
+ msg.buf = camera_ncm03j_magic;
+ msg.len = 2;
+ msg.flags = 0;
+ ret = i2c_transfer(a, &msg, 1);
+ camera_power(0);
+
+ return ret;
+}
+
static int camera_set_capture(struct soc_camera_platform_info *info,
int enable)
{
@@ -295,11 +325,37 @@ static struct platform_device camera_device = {
.platform_data = &camera_info,
},
};
+
+static int __init camera_setup(void)
+{
+ if (camera_probe() > 0)
+ platform_device_register(&camera_device);
+
+ return 0;
+}
+late_initcall(camera_setup);
+
#endif /* CONFIG_I2C */
+static int ov7725_power(struct device *dev, int mode)
+{
+ camera_power(0);
+ if (mode)
+ camera_power(1);
+
+ return 0;
+}
+
+static struct ov772x_camera_info ov7725_info = {
+ .buswidth = SOCAM_DATAWIDTH_8,
+ .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
+ .link = {
+ .power = ov7725_power,
+ },
+};
+
static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
- .flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
- SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
+ .flags = SH_CEU_FLAG_USE_8BIT_BUS,
};
static struct resource ceu_resources[] = {
@@ -347,9 +403,6 @@ static struct platform_device *ap325rxa_devices[] __initdata = {
&ap325rxa_nor_flash_device,
&lcdc_device,
&ceu_device,
-#ifdef CONFIG_I2C
- &camera_device,
-#endif
&nand_flash_device,
&sdcard_cn3_device,
};
@@ -358,6 +411,10 @@ static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
{
I2C_BOARD_INFO("pcf8563", 0x51),
},
+ {
+ I2C_BOARD_INFO("ov772x", 0x21),
+ .platform_data = &ov7725_info,
+ },
};
static struct spi_board_info ap325rxa_spi_devices[] = {
diff --git a/arch/sh/boards/board-espt.c b/arch/sh/boards/board-espt.c
new file mode 100644
index 000000000000..d5ce5e18eb37
--- /dev/null
+++ b/arch/sh/boards/board-espt.c
@@ -0,0 +1,102 @@
+/*
+ * Data Technology Inc. ESPT-GIGA board suport
+ *
+ * Copyright (C) 2008, 2009 Renesas Solutions Corp.
+ * Copyright (C) 2008, 2009 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+#include <asm/machvec.h>
+#include <asm/sizes.h>
+#include <asm/sh_eth.h>
+
+/* NOR Flash */
+static struct mtd_partition espt_nor_flash_partitions[] = {
+ {
+ .name = "U-Boot",
+ .offset = 0,
+ .size = (2 * SZ_128K),
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ }, {
+ .name = "Linux-Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (20 * SZ_128K),
+ }, {
+ .name = "Root Filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data espt_nor_flash_data = {
+ .width = 2,
+ .parts = espt_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(espt_nor_flash_partitions),
+};
+
+static struct resource espt_nor_flash_resources[] = {
+ [0] = {
+ .name = "NOR Flash",
+ .start = 0,
+ .end = SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device espt_nor_flash_device = {
+ .name = "physmap-flash",
+ .resource = espt_nor_flash_resources,
+ .num_resources = ARRAY_SIZE(espt_nor_flash_resources),
+ .dev = {
+ .platform_data = &espt_nor_flash_data,
+ },
+};
+
+/* SH-Ether */
+static struct resource sh_eth_resources[] = {
+ {
+ .start = 0xFEE00800, /* use eth1 */
+ .end = 0xFEE00F7C - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 57, /* irq number */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_eth_plat_data sh7763_eth_pdata = {
+ .phy = 0,
+ .edmac_endian = EDMAC_LITTLE_ENDIAN,
+};
+
+static struct platform_device espt_eth_device = {
+ .name = "sh-eth",
+ .resource = sh_eth_resources,
+ .num_resources = ARRAY_SIZE(sh_eth_resources),
+ .dev = {
+ .platform_data = &sh7763_eth_pdata,
+ },
+};
+
+static struct platform_device *espt_devices[] __initdata = {
+ &espt_nor_flash_device,
+ &espt_eth_device,
+};
+
+static int __init espt_devices_setup(void)
+{
+ return platform_add_devices(espt_devices,
+ ARRAY_SIZE(espt_devices));
+}
+device_initcall(espt_devices_setup);
+
+static struct sh_machine_vector mv_espt __initmv = {
+ .mv_name = "ESPT-GIGA",
+};
diff --git a/arch/sh/boards/board-polaris.c b/arch/sh/boards/board-polaris.c
new file mode 100644
index 000000000000..62607eb51004
--- /dev/null
+++ b/arch/sh/boards/board-polaris.c
@@ -0,0 +1,149 @@
+/*
+ * June 2006 steve.glendinning@smsc.com
+ *
+ * Polaris-specific resource declaration
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <asm/machvec.h>
+#include <asm/heartbeat.h>
+#include <cpu/gpio.h>
+#include <mach-se/mach/se.h>
+
+#define BCR2 (0xFFFFFF62)
+#define WCR2 (0xFFFFFF66)
+#define AREA5_WAIT_CTRL (0x1C00)
+#define WAIT_STATES_10 (0x7)
+
+static struct resource smsc911x_resources[] = {
+ [0] = {
+ .name = "smsc911x-memory",
+ .start = PA_EXT5,
+ .end = PA_EXT5 + 0x1fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "smsc911x-irq",
+ .start = IRQ0_IRQ,
+ .end = IRQ0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device smsc911x_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+};
+
+static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3 };
+
+static struct heartbeat_data heartbeat_data = {
+ .bit_pos = heartbeat_bit_pos,
+ .nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
+ .regsize = 8,
+};
+
+static struct resource heartbeat_resources[] = {
+ [0] = {
+ .start = PORT_PCDR,
+ .end = PORT_PCDR,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+ .num_resources = ARRAY_SIZE(heartbeat_resources),
+ .resource = heartbeat_resources,
+};
+
+static struct platform_device *polaris_devices[] __initdata = {
+ &smsc911x_device,
+ &heartbeat_device,
+};
+
+static int __init polaris_initialise(void)
+{
+ u16 wcr, bcr_mask;
+
+ printk(KERN_INFO "Configuring Polaris external bus\n");
+
+ /* Configure area 5 with 2 wait states */
+ wcr = ctrl_inw(WCR2);
+ wcr &= (~AREA5_WAIT_CTRL);
+ wcr |= (WAIT_STATES_10 << 10);
+ ctrl_outw(wcr, WCR2);
+
+ /* Configure area 5 for 32-bit access */
+ bcr_mask = ctrl_inw(BCR2);
+ bcr_mask |= 1 << 10;
+ ctrl_outw(bcr_mask, BCR2);
+
+ return platform_add_devices(polaris_devices,
+ ARRAY_SIZE(polaris_devices));
+}
+arch_initcall(polaris_initialise);
+
+static struct ipr_data ipr_irq_table[] = {
+ /* External IRQs */
+ { IRQ0_IRQ, 0, 0, 1, }, /* IRQ0 */
+ { IRQ1_IRQ, 0, 4, 1, }, /* IRQ1 */
+};
+
+static unsigned long ipr_offsets[] = {
+ INTC_IPRC
+};
+
+static struct ipr_desc ipr_irq_desc = {
+ .ipr_offsets = ipr_offsets,
+ .nr_offsets = ARRAY_SIZE(ipr_offsets),
+
+ .ipr_data = ipr_irq_table,
+ .nr_irqs = ARRAY_SIZE(ipr_irq_table),
+ .chip = {
+ .name = "sh7709-ext",
+ },
+};
+
+static void __init init_polaris_irq(void)
+{
+ /* Disable all interrupts */
+ ctrl_outw(0, BCR_ILCRA);
+ ctrl_outw(0, BCR_ILCRB);
+ ctrl_outw(0, BCR_ILCRC);
+ ctrl_outw(0, BCR_ILCRD);
+ ctrl_outw(0, BCR_ILCRE);
+ ctrl_outw(0, BCR_ILCRF);
+ ctrl_outw(0, BCR_ILCRG);
+
+ register_ipr_controller(&ipr_irq_desc);
+}
+
+static struct sh_machine_vector mv_polaris __initmv = {
+ .mv_name = "Polaris",
+ .mv_nr_irqs = 61,
+ .mv_init_irq = init_polaris_irq,
+};
diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c
index 38a64968d7bf..6f94f17adc46 100644
--- a/arch/sh/boards/board-sh7785lcr.c
+++ b/arch/sh/boards/board-sh7785lcr.c
@@ -229,7 +229,7 @@ static struct resource i2c_resources[] = {
static struct i2c_pca9564_pf_platform_data i2c_platform_data = {
.gpio = 0,
.i2c_clock_speed = I2C_PCA_CON_330kHz,
- .timeout = 100,
+ .timeout = HZ,
};
static struct platform_device i2c_device = {
@@ -275,7 +275,18 @@ void __init init_sh7785lcr_IRQ(void)
static void sh7785lcr_power_off(void)
{
- ctrl_outb(0x01, P2SEGADDR(PLD_POFCR));
+ unsigned char *p;
+
+ p = ioremap(PLD_POFCR, PLD_POFCR + 1);
+ if (!p) {
+ printk(KERN_ERR "%s: ioremap error.\n", __func__);
+ return;
+ }
+ *p = 0x01;
+ iounmap(p);
+ set_bl_bit();
+ while (1)
+ cpu_relax();
}
/* Initialize the board */
diff --git a/arch/sh/boards/board-urquell.c b/arch/sh/boards/board-urquell.c
new file mode 100644
index 000000000000..8367d1d789c3
--- /dev/null
+++ b/arch/sh/boards/board-urquell.c
@@ -0,0 +1,166 @@
+/*
+ * Renesas Technology Corp. SH7786 Urquell Support.
+ *
+ * Copyright (C) 2008 Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/smc91x.h>
+#include <linux/mtd/physmap.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <mach/urquell.h>
+#include <cpu/sh7786.h>
+#include <asm/heartbeat.h>
+#include <asm/sizes.h>
+
+static struct resource heartbeat_resources[] = {
+ [0] = {
+ .start = BOARDREG(SLEDR),
+ .end = BOARDREG(SLEDR),
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct heartbeat_data heartbeat_data = {
+ .regsize = 16,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+ .num_resources = ARRAY_SIZE(heartbeat_resources),
+ .resource = heartbeat_resources,
+};
+
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_eth_resources[] = {
+ [0] = {
+ .name = "SMC91C111" ,
+ .start = 0x05800300,
+ .end = 0x0580030f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 11,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_eth_device = {
+ .name = "smc91x",
+ .num_resources = ARRAY_SIZE(smc91x_eth_resources),
+ .resource = smc91x_eth_resources,
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+};
+
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = SZ_512K,
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ },
+ {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_512K,
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ },
+ {
+ .name = "data",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .start = NOR_FLASH_ADDR,
+ .end = NOR_FLASH_ADDR + NOR_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .resource = nor_flash_resources,
+};
+
+static struct platform_device *urquell_devices[] __initdata = {
+ &heartbeat_device,
+ &smc91x_eth_device,
+ &nor_flash_device,
+};
+
+static int __init urquell_devices_setup(void)
+{
+ /* USB */
+ gpio_request(GPIO_FN_USB_OVC0, NULL);
+ gpio_request(GPIO_FN_USB_PENC0, NULL);
+
+ /* enable LAN */
+ __raw_writew(__raw_readw(UBOARDREG(IRL2MSKR)) & ~0x00000001,
+ UBOARDREG(IRL2MSKR));
+
+ return platform_add_devices(urquell_devices,
+ ARRAY_SIZE(urquell_devices));
+}
+device_initcall(urquell_devices_setup);
+
+static void urquell_power_off(void)
+{
+ __raw_writew(0xa5a5, UBOARDREG(SRSTR));
+}
+
+static void __init urquell_init_irq(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRL3210_MASK);
+}
+
+/* Initialize the board */
+static void __init urquell_setup(char **cmdline_p)
+{
+ printk(KERN_INFO "Renesas Technology Corp. Urquell support.\n");
+
+ pm_power_off = urquell_power_off;
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_urquell __initmv = {
+ .mv_name = "Urquell",
+ .mv_setup = urquell_setup,
+ .mv_init_irq = urquell_init_irq,
+};
diff --git a/arch/sh/boards/mach-highlander/Kconfig b/arch/sh/boards/mach-highlander/Kconfig
index 08057f62687b..def49cc0a7b9 100644
--- a/arch/sh/boards/mach-highlander/Kconfig
+++ b/arch/sh/boards/mach-highlander/Kconfig
@@ -18,7 +18,7 @@ config SH_R7780MP
config SH_R7785RP
bool "R7785RP board support"
depends on CPU_SUBTYPE_SH7785
- select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
endchoice
diff --git a/arch/sh/boards/mach-hp6xx/pm_wakeup.S b/arch/sh/boards/mach-hp6xx/pm_wakeup.S
index 44b648cf6f23..4f18d44e0541 100644
--- a/arch/sh/boards/mach-hp6xx/pm_wakeup.S
+++ b/arch/sh/boards/mach-hp6xx/pm_wakeup.S
@@ -10,47 +10,32 @@
#include <linux/linkage.h>
#include <cpu/mmu_context.h>
-#define k0 r0
-#define k1 r1
-#define k2 r2
-#define k3 r3
-#define k4 r4
-
/*
* Kernel mode register usage:
* k0 scratch
* k1 scratch
- * k2 scratch (Exception code)
- * k3 scratch (Return address)
- * k4 scratch
- * k5 reserved
- * k6 Global Interrupt Mask (0--15 << 4)
- * k7 CURRENT_THREAD_INFO (pointer to current thread info)
+ * For more details, please have a look at entry.S
*/
+#define k0 r0
+#define k1 r1
+
ENTRY(wakeup_start)
! clear STBY bit
- mov #-126, k2
+ mov #-126, k1
and #127, k0
- mov.b k0, @k2
+ mov.b k0, @k1
! enable refresh
mov.l 5f, k1
mov.w 6f, k0
mov.w k0, @k1
! jump to handler
- mov.l 2f, k2
- mov.l 3f, k3
- mov.l @k2, k2
-
mov.l 4f, k1
jmp @k1
- nop
+ nop
.align 2
-1: .long EXPEVT
-2: .long INTEVT
-3: .long ret_from_irq
-4: .long handle_exception
+4: .long handle_interrupt
5: .long 0xffffff68
6: .word 0x0524
diff --git a/arch/sh/boards/mach-hp6xx/setup.c b/arch/sh/boards/mach-hp6xx/setup.c
index 746742bdc014..8f305b36358b 100644
--- a/arch/sh/boards/mach-hp6xx/setup.c
+++ b/arch/sh/boards/mach-hp6xx/setup.c
@@ -115,7 +115,6 @@ static struct sh_machine_vector mv_hp6xx __initmv = {
.mv_setup = hp6xx_setup,
/* IRQ's : CPU(64) + CCHIP(16) + FREE_TO_USE(6) */
.mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM + 6,
- .mv_irq_demux = hd64461_irq_demux,
/* Enable IRQ0 -> IRQ3 in IRQ_MODE */
.mv_init_irq = hp6xx_init_irq,
};
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 28e56c5809a2..1ee1de0bc1c3 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -352,8 +352,7 @@ static int tw9910_power(struct device *dev, int mode)
}
static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
- .flags = SOCAM_MASTER | SOCAM_DATAWIDTH_8 | SOCAM_PCLK_SAMPLE_RISING \
- | SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH,
+ .flags = SH_CEU_FLAG_USE_8BIT_BUS,
};
static struct resource migor_ceu_resources[] = {
@@ -450,6 +449,14 @@ static struct spi_board_info migor_spi_devices[] = {
static int __init migor_devices_setup(void)
{
+
+#ifdef CONFIG_PM
+ /* Let D11 LED show STATUS0 */
+ gpio_request(GPIO_FN_STATUS0, NULL);
+
+ /* Lit D12 LED show PDSTATUS */
+ gpio_request(GPIO_FN_PDSTATUS, NULL);
+#else
/* Lit D11 LED */
gpio_request(GPIO_PTJ7, NULL);
gpio_direction_output(GPIO_PTJ7, 1);
@@ -459,6 +466,7 @@ static int __init migor_devices_setup(void)
gpio_request(GPIO_PTJ5, NULL);
gpio_direction_output(GPIO_PTJ5, 1);
gpio_export(GPIO_PTJ5, 0);
+#endif
/* SMC91C111 - Enable IRQ0, Setup CS4 for 16-bit fast access */
gpio_request(GPIO_FN_IRQ0, NULL);
diff --git a/arch/sh/boards/mach-rsk/Kconfig b/arch/sh/boards/mach-rsk/Kconfig
index bff095dffc02..aeff3b042205 100644
--- a/arch/sh/boards/mach-rsk/Kconfig
+++ b/arch/sh/boards/mach-rsk/Kconfig
@@ -10,7 +10,7 @@ config SH_RSK7201
config SH_RSK7203
bool "RSK7203"
- select GENERIC_GPIO
+ select ARCH_REQUIRE_GPIOLIB
depends on CPU_SUBTYPE_SH7203
endchoice
diff --git a/arch/sh/boards/mach-sh7763rdp/setup.c b/arch/sh/boards/mach-sh7763rdp/setup.c
index 6f926fd2162b..390534a0b35c 100644
--- a/arch/sh/boards/mach-sh7763rdp/setup.c
+++ b/arch/sh/boards/mach-sh7763rdp/setup.c
@@ -63,15 +63,19 @@ static struct platform_device sh7763rdp_nor_flash_device = {
},
};
-/* SH-Ether */
+/*
+ * SH-Ether
+ *
+ * SH Ether of SH7763 has multi IRQ handling.
+ * (57,58,59 -> 57)
+ */
static struct resource sh_eth_resources[] = {
{
.start = 0xFEE00800, /* use eth1 */
.end = 0xFEE00F7C - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = 58, /* irq number */
- .end = 58,
+ .start = 57, /* irq number */
.flags = IORESOURCE_IRQ,
},
};
diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
index c16ccd4bfa16..95483d161258 100644
--- a/arch/sh/boot/Makefile
+++ b/arch/sh/boot/Makefile
@@ -33,20 +33,24 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(obj)/compressed/vmlinux: FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
-ifeq ($(CONFIG_32BIT),y)
-KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%08x" \
- $$[$(CONFIG_PAGE_OFFSET) + \
- $(CONFIG_ZERO_PAGE_OFFSET)]')
-else
+KERNEL_MEMORY := 0x00000000
+ifeq ($(CONFIG_PMB_FIXED),y)
+KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
+ $$[$(CONFIG_MEMORY_START) & 0x1fffffff]')
+endif
+ifeq ($(CONFIG_29BIT),y)
+KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
+ $$[$(CONFIG_MEMORY_START)]')
+endif
+
KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%08x" \
$$[$(CONFIG_PAGE_OFFSET) + \
- $(CONFIG_MEMORY_START) + \
+ $(KERNEL_MEMORY) + \
$(CONFIG_ZERO_PAGE_OFFSET)]')
-endif
KERNEL_ENTRY := $(shell /bin/bash -c 'printf "0x%08x" \
$$[$(CONFIG_PAGE_OFFSET) + \
- $(CONFIG_MEMORY_START) + \
+ $(KERNEL_MEMORY) + \
$(CONFIG_ZERO_PAGE_OFFSET) + $(CONFIG_ENTRY_OFFSET)]')
quiet_cmd_uimage = UIMAGE $@
diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c
index 27ceeb948bb1..25ef91061521 100644
--- a/arch/sh/cchips/hd6446x/hd64461.c
+++ b/arch/sh/cchips/hd6446x/hd64461.c
@@ -53,21 +53,22 @@ static struct irq_chip hd64461_irq_chip = {
.unmask = hd64461_unmask_irq,
};
-int hd64461_irq_demux(int irq)
+static void hd64461_irq_demux(unsigned int irq, struct irq_desc *desc)
{
- if (irq == CONFIG_HD64461_IRQ) {
- unsigned short bit;
- unsigned short nirr = inw(HD64461_NIRR);
- unsigned short nimr = inw(HD64461_NIMR);
- int i;
-
- nirr &= ~nimr;
- for (bit = 1, i = 0; i < 16; bit <<= 1, i++)
- if (nirr & bit)
- break;
- irq = HD64461_IRQBASE + i;
+ unsigned short intv = ctrl_inw(HD64461_NIRR);
+ struct irq_desc *ext_desc;
+ unsigned int ext_irq = HD64461_IRQBASE;
+
+ intv &= (1 << HD64461_IRQ_NUM) - 1;
+
+ while (intv) {
+ if (intv & 1) {
+ ext_desc = irq_desc + ext_irq;
+ handle_level_irq(ext_irq, ext_desc);
+ }
+ intv >>= 1;
+ ext_irq++;
}
- return irq;
}
int __init setup_hd64461(void)
@@ -93,6 +94,9 @@ int __init setup_hd64461(void)
set_irq_chip_and_handler(i, &hd64461_irq_chip,
handle_level_irq);
+ set_irq_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux);
+ set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW);
+
#ifdef CONFIG_HD64461_ENABLER
printk(KERN_INFO "HD64461: enabling PCMCIA devices\n");
__raw_writeb(0x4c, HD64461_PCC1CSCIER);
diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig
index 352f87d50fdc..c8d982a8a2e6 100644
--- a/arch/sh/configs/ap325rxa_defconfig
+++ b/arch/sh/configs/ap325rxa_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 27 11:45:08 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 17:46:53 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,14 +16,16 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -43,6 +45,15 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
CONFIG_GROUP_SCHED=y
@@ -58,6 +69,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -66,10 +78,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -77,6 +87,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -115,11 +126,6 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -128,6 +134,7 @@ CONFIG_CLASSIC_RCU=y
CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -156,6 +163,7 @@ CONFIG_CPU_SUBTYPE_SH7723=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -198,11 +206,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -228,6 +237,7 @@ CONFIG_SH_AP325RXA=y
# Timer and clock configuration
#
CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
CONFIG_SH_TIMER_IRQ=16
CONFIG_SH_PCLK_FREQ=33333333
CONFIG_TICK_ONESHOT=y
@@ -304,7 +314,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -359,6 +368,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -371,7 +381,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -483,7 +492,6 @@ CONFIG_MTD_NAND_SH_FLCTL=y
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
#
# UBI - Unsorted block images
@@ -510,10 +518,18 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -559,9 +575,11 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -594,8 +612,10 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -612,7 +632,6 @@ CONFIG_SMSC911X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -687,6 +706,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -723,12 +743,9 @@ CONFIG_I2C_SH_MOBILE=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_AT24 is not set
-# CONFIG_SENSORS_EEPROM is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -748,7 +765,6 @@ CONFIG_SPI_GPIO=y
#
# SPI Protocol Masters
#
-# CONFIG_SPI_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
CONFIG_ARCH_REQUIRE_GPIOLIB=y
@@ -822,7 +838,7 @@ CONFIG_VIDEO_MEDIA=y
#
# CONFIG_MEDIA_ATTACH is not set
CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
CONFIG_MEDIA_TUNER_SIMPLE=y
CONFIG_MEDIA_TUNER_TDA8290=y
CONFIG_MEDIA_TUNER_TDA9887=y
@@ -831,6 +847,7 @@ CONFIG_MEDIA_TUNER_TEA5767=y
CONFIG_MEDIA_TUNER_MT20XX=y
CONFIG_MEDIA_TUNER_XC2028=y
CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
CONFIG_VIDEO_V4L2=y
CONFIG_VIDEOBUF_GEN=y
CONFIG_VIDEOBUF_DMA_CONTIG=y
@@ -886,6 +903,7 @@ CONFIG_FB_SH_MOBILE_LCDC=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -995,6 +1013,7 @@ CONFIG_RTC_DRV_PCF8563=y
#
# CONFIG_RTC_DRV_SH is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=y
# CONFIG_UIO_PDRV is not set
CONFIG_UIO_PDRV_GENIRQ=y
@@ -1096,7 +1115,6 @@ CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1177,7 +1195,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1204,10 +1221,12 @@ CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1276,6 +1295,7 @@ CONFIG_CRYPTO_CBC=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1296,7 +1316,7 @@ CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
CONFIG_CRC7=y
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/cayman_defconfig b/arch/sh/configs/cayman_defconfig
index 92895013813d..fa5fc1e1e980 100644
--- a/arch/sh/configs/cayman_defconfig
+++ b/arch/sh/configs/cayman_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27
-# Wed Oct 22 18:04:52 2008
+# Linux kernel version: 2.6.29
+# Thu Apr 2 17:49:14 2009
#
CONFIG_SUPERH=y
# CONFIG_SUPERH32 is not set
@@ -16,6 +16,8 @@ CONFIG_GENERIC_IRQ_PROBE=y
# CONFIG_GENERIC_GPIO is not set
# CONFIG_GENERIC_TIME is not set
# CONFIG_GENERIC_CLOCKEVENTS is not set
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -23,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -40,10 +43,19 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -51,6 +63,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -61,10 +74,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -73,18 +84,18 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
@@ -92,11 +103,9 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
@@ -112,7 +121,6 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
# CONFIG_FREEZER is not set
#
@@ -120,6 +128,7 @@ CONFIG_CLASSIC_RCU=y
#
CONFIG_CPU_SH5=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
# CONFIG_CPU_SUBTYPE_SH7206 is not set
# CONFIG_CPU_SUBTYPE_SH7263 is not set
@@ -146,6 +155,7 @@ CONFIG_CPU_SH5=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -188,16 +198,16 @@ CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_SPARSEMEM_STATIC=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_CACHE_WRITEBACK is not set
# CONFIG_CACHE_WRITETHROUGH is not set
CONFIG_CACHE_OFF=y
@@ -256,7 +266,6 @@ CONFIG_HZ=250
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
-# CONFIG_PREEMPT_RCU is not set
#
# Boot options
@@ -272,9 +281,12 @@ CONFIG_PCI=y
CONFIG_SH_PCIDMA_NONCOHERENT=y
CONFIG_PCI_AUTO=y
CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
+# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
@@ -285,6 +297,12 @@ CONFIG_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE is not set
CONFIG_NET=y
#
@@ -344,7 +362,9 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
#
# Network testing
@@ -355,13 +375,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -400,11 +420,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -447,6 +476,7 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -459,7 +489,10 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
@@ -478,6 +511,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_FUSION is not set
@@ -493,6 +527,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -510,7 +545,10 @@ CONFIG_NET_ETHERNET=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -543,9 +581,11 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_CHELSIO_T3 is not set
# CONFIG_ENIC is not set
# CONFIG_IXGBE is not set
@@ -554,11 +594,13 @@ CONFIG_NETDEV_10000=y
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -566,7 +608,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -636,10 +681,12 @@ CONFIG_DEVKMEM=y
# CONFIG_SERIAL_SH_SCI is not set
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -700,12 +747,9 @@ CONFIG_I2C_HELPER_AUTO=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -725,8 +769,10 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -747,10 +793,14 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
@@ -786,11 +836,11 @@ CONFIG_WATCHDOG=y
#
# CONFIG_PCIPCWATCHDOG is not set
# CONFIG_WDTPCI is not set
+CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
-CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
#
@@ -802,6 +852,8 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
#
# Multimedia devices
@@ -822,7 +874,7 @@ CONFIG_VIDEO_MEDIA=m
#
# CONFIG_MEDIA_ATTACH is not set
CONFIG_MEDIA_TUNER=m
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
CONFIG_MEDIA_TUNER_SIMPLE=m
CONFIG_MEDIA_TUNER_TDA8290=m
CONFIG_MEDIA_TUNER_TDA9887=m
@@ -831,6 +883,7 @@ CONFIG_MEDIA_TUNER_TEA5767=m
CONFIG_MEDIA_TUNER_MT20XX=m
CONFIG_MEDIA_TUNER_XC2028=m
CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MEDIA_TUNER_MC44S803=m
CONFIG_VIDEO_V4L2=m
CONFIG_VIDEO_V4L1=m
CONFIG_VIDEO_CAPTURE_DRIVERS=y
@@ -853,6 +906,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
# CONFIG_VIDEO_CAFE_CCIC is not set
# CONFIG_SOC_CAMERA is not set
# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DVB_DYNAMIC_MINORS is not set
CONFIG_DVB_CAPTURE_DRIVERS=y
#
@@ -884,89 +938,7 @@ CONFIG_DVB_CAPTURE_DRIVERS=y
#
# Supported DVB Frontends
#
-
-#
-# Customise DVB Frontends
-#
# CONFIG_DVB_FE_CUSTOMISE is not set
-
-#
-# DVB-S (satellite) frontends
-#
-# CONFIG_DVB_CX24110 is not set
-# CONFIG_DVB_CX24123 is not set
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_S5H1420 is not set
-# CONFIG_DVB_STV0288 is not set
-# CONFIG_DVB_STB6000 is not set
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_TDA8083 is not set
-# CONFIG_DVB_TDA10086 is not set
-# CONFIG_DVB_VES1X93 is not set
-# CONFIG_DVB_TUNER_ITD1000 is not set
-# CONFIG_DVB_TDA826X is not set
-# CONFIG_DVB_TUA6100 is not set
-# CONFIG_DVB_CX24116 is not set
-# CONFIG_DVB_SI21XX is not set
-
-#
-# DVB-T (terrestrial) frontends
-#
-# CONFIG_DVB_SP8870 is not set
-# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_CX22700 is not set
-# CONFIG_DVB_CX22702 is not set
-# CONFIG_DVB_DRX397XD is not set
-# CONFIG_DVB_L64781 is not set
-# CONFIG_DVB_TDA1004X is not set
-# CONFIG_DVB_NXT6000 is not set
-# CONFIG_DVB_MT352 is not set
-# CONFIG_DVB_ZL10353 is not set
-# CONFIG_DVB_DIB3000MB is not set
-# CONFIG_DVB_DIB3000MC is not set
-# CONFIG_DVB_DIB7000M is not set
-# CONFIG_DVB_DIB7000P is not set
-# CONFIG_DVB_TDA10048 is not set
-
-#
-# DVB-C (cable) frontends
-#
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_TDA10021 is not set
-# CONFIG_DVB_TDA10023 is not set
-# CONFIG_DVB_STV0297 is not set
-
-#
-# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
-#
-# CONFIG_DVB_NXT200X is not set
-# CONFIG_DVB_OR51211 is not set
-# CONFIG_DVB_OR51132 is not set
-# CONFIG_DVB_BCM3510 is not set
-# CONFIG_DVB_LGDT330X is not set
-# CONFIG_DVB_S5H1409 is not set
-# CONFIG_DVB_AU8522 is not set
-# CONFIG_DVB_S5H1411 is not set
-
-#
-# Digital terrestrial only tuners/PLL
-#
-# CONFIG_DVB_PLL is not set
-# CONFIG_DVB_TUNER_DIB0070 is not set
-
-#
-# SEC control devices for DVB-S
-#
-# CONFIG_DVB_LNBP21 is not set
-# CONFIG_DVB_ISL6405 is not set
-# CONFIG_DVB_ISL6421 is not set
-# CONFIG_DVB_LGS8GL5 is not set
-
-#
-# Tools to develop new frontends
-#
-# CONFIG_DVB_DUMMY_FE is not set
-# CONFIG_DVB_AF9013 is not set
CONFIG_DAB=y
#
@@ -979,15 +951,16 @@ CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
# CONFIG_FB_DDC is not set
# CONFIG_FB_BOOT_VESA_SUPPORT is not set
-CONFIG_FB_CFB_FILLRECT=m
-CONFIG_FB_CFB_COPYAREA=m
-CONFIG_FB_CFB_IMAGEBLIT=m
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
-# CONFIG_FB_SYS_FILLRECT is not set
-# CONFIG_FB_SYS_COPYAREA is not set
-# CONFIG_FB_SYS_IMAGEBLIT is not set
+CONFIG_FB_SYS_FILLRECT=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
# CONFIG_FB_FOREIGN_ENDIAN is not set
-# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_SYS_FOPS=m
+CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
@@ -1025,6 +998,8 @@ CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_SH_MOBILE_LCDC=m
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -1081,9 +1056,14 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -1091,6 +1071,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1114,6 +1095,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1148,10 +1130,7 @@ CONFIG_TMPFS=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -1160,6 +1139,7 @@ CONFIG_HUGETLB_PAGE=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1179,7 +1159,6 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1252,6 +1231,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
CONFIG_FRAME_POINTER=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
@@ -1260,17 +1240,25 @@ CONFIG_FRAME_POINTER=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_PAGE_POISONING is not set
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
# CONFIG_EARLY_SCIF_CONSOLE is not set
# CONFIG_DEBUG_BOOTMEM is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_4KSTACKS is not set
-CONFIG_SH64_PROC_ASIDS=y
+# CONFIG_SH_NO_BSS_INIT is not set
+# CONFIG_MORE_COMPILE_OPTIONS is not set
CONFIG_SH64_SR_WATCH=y
# CONFIG_POOR_MANS_STRACE is not set
-# CONFIG_SH_ALPHANUMERIC is not set
-# CONFIG_SH_NO_BSS_INIT is not set
#
# Security options
@@ -1286,6 +1274,7 @@ CONFIG_CRYPTO=y
#
# CONFIG_CRYPTO_FIPS is not set
# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
@@ -1356,6 +1345,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1369,6 +1359,7 @@ CONFIG_CRYPTO_HW=y
# Library routines
#
CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
@@ -1376,7 +1367,7 @@ CONFIG_BITREVERSE=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig
index 2d86e0487517..5c1123640142 100644
--- a/arch/sh/configs/dreamcast_defconfig
+++ b/arch/sh/configs/dreamcast_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 16:54:55 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 17:51:48 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -44,10 +45,19 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -55,6 +65,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -64,10 +75,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -76,6 +85,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -116,11 +126,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -155,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7091=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -202,11 +208,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -263,9 +270,12 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_SH_DMA_IRQ_MULTI=y
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
CONFIG_NR_DMA_CHANNELS_BOOL=y
CONFIG_NR_DMA_CHANNELS=9
+# CONFIG_PVR2_DMA is not set
+# CONFIG_G2_DMA is not set
#
# Companion Chips
@@ -314,6 +324,8 @@ CONFIG_PCI_AUTO=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
@@ -335,7 +347,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -387,6 +398,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -399,13 +411,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -439,12 +451,16 @@ CONFIG_GDROM=y
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -470,6 +486,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -487,8 +504,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -532,7 +551,10 @@ CONFIG_8139TOO=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -628,6 +650,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -746,6 +769,7 @@ CONFIG_FB_PVR2=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -802,9 +826,13 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -813,6 +841,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -828,6 +857,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -871,6 +901,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -920,7 +951,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1012,6 +1042,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1033,7 +1064,7 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/edosk7705_defconfig b/arch/sh/configs/edosk7705_defconfig
index 461bfb350221..f4c34b039312 100644
--- a/arch/sh/configs/edosk7705_defconfig
+++ b/arch/sh/configs/edosk7705_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 16:55:29 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 17:54:02 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -35,6 +36,15 @@ CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
# CONFIG_CGROUPS is not set
@@ -50,7 +60,6 @@ CONFIG_EMBEDDED=y
# CONFIG_PRINTK is not set
# CONFIG_BUG is not set
# CONFIG_ELF_CORE is not set
-# CONFIG_COMPAT_BRK is not set
# CONFIG_BASE_FULL is not set
# CONFIG_FUTEX is not set
# CONFIG_EPOLL is not set
@@ -60,6 +69,7 @@ CONFIG_EMBEDDED=y
CONFIG_SHMEM=y
# CONFIG_AIO is not set
# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
@@ -74,11 +84,6 @@ CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_BASE_SMALL=1
# CONFIG_MODULES is not set
# CONFIG_BLOCK is not set
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -113,6 +118,7 @@ CONFIG_CPU_SUBTYPE_SH7705=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -157,12 +163,13 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
CONFIG_SH7705_CACHE_32KB=y
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -243,7 +250,6 @@ CONFIG_BOOT_LINK_OFFSET=0x00800000
# Executable file formats
#
CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
# CONFIG_NET is not set
@@ -361,6 +367,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig
index 14d4b35685a1..7825c2699f18 100644
--- a/arch/sh/configs/edosk7760_defconfig
+++ b/arch/sh/configs/edosk7760_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 16:55:48 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 17:54:57 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -43,34 +44,45 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -79,6 +91,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
@@ -118,11 +131,6 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -157,6 +165,7 @@ CONFIG_CPU_SUBTYPE_SH7760=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -198,11 +207,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -245,7 +255,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=8
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
# CONFIG_SH_DMABRG is not set
@@ -310,7 +320,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -360,6 +369,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -372,13 +382,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -402,6 +412,7 @@ CONFIG_MTD_DEBUG=y
CONFIG_MTD_DEBUG_VERBOSE=0
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set
@@ -454,9 +465,7 @@ CONFIG_MTD_ABSENT=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xffffffff
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -477,6 +486,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -506,6 +520,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -518,8 +533,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -536,7 +553,10 @@ CONFIG_SMC91X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -607,6 +627,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -643,12 +664,9 @@ CONFIG_I2C_SH7760=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
CONFIG_I2C_DEBUG_CORE=y
@@ -680,6 +698,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -732,6 +751,7 @@ CONFIG_FB_SH_MOBILE_LCDC=m
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -750,6 +770,7 @@ CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
# CONFIG_SND_SEQUENCER is not set
# CONFIG_SND_MIXER_OSS is not set
# CONFIG_SND_PCM_OSS is not set
@@ -781,6 +802,7 @@ CONFIG_SND_SOC_I2C_AND_SPI=y
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -806,6 +828,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -851,6 +874,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -868,7 +892,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -974,6 +997,7 @@ CONFIG_DEBUG_INFO=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -989,7 +1013,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1095,6 +1118,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1115,7 +1139,9 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/espt_defconfig b/arch/sh/configs/espt_defconfig
new file mode 100644
index 000000000000..ebb4c37abaa6
--- /dev/null
+++ b/arch/sh/configs/espt_defconfig
@@ -0,0 +1,1199 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29
+# Thu Apr 2 17:58:18 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+# CONFIG_MODULE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_FREEZER is not set
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+CONFIG_CPU_SUBTYPE_SH7763=y
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_29BIT=y
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_STATIC=y
+# CONFIG_MEMORY_HOTPLUG is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_SH7763RDP is not set
+CONFIG_SH_ESPT=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=28
+CONFIG_SH_PCLK_FREQ=66666666
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_SECCOMP=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/nfs ip=bootp"
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_STNIC is not set
+CONFIG_SH_ETH=y
+# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=3
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+CONFIG_FB_FOREIGN_ENDIAN=y
+CONFIG_FB_BOTH_ENDIAN=y
+# CONFIG_FB_BIG_ENDIAN is not set
+# CONFIG_FB_LITTLE_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_SH_MOBILE_LCDC is not set
+CONFIG_FB_SH7760=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_LOGO_SUPERH_MONO=y
+CONFIG_LOGO_SUPERH_VGA16=y
+CONFIG_LOGO_SUPERH_CLUT224=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_MORE_COMPILE_OPTIONS is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig
index 847a25106635..82b113af08d3 100644
--- a/arch/sh/configs/hp6xx_defconfig
+++ b/arch/sh/configs/hp6xx_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 16:56:55 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:01:05 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -39,11 +40,20 @@ CONFIG_SWAP=y
# CONFIG_SYSVIPC is not set
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -51,6 +61,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -60,10 +71,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -71,6 +80,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -104,11 +114,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_FREEZER=y
#
@@ -143,6 +148,7 @@ CONFIG_CPU_SUBTYPE_SH7709=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -184,11 +190,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -208,6 +215,7 @@ CONFIG_CPU_HAS_SR_RB=y
#
# CONFIG_SH_SOLUTION_ENGINE is not set
CONFIG_SH_HP6XX=y
+# CONFIG_SH_POLARIS is not set
#
# Timer and clock configuration
@@ -229,7 +237,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
#
@@ -302,6 +310,7 @@ CONFIG_PM=y
CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
CONFIG_APM_EMULATION=y
# CONFIG_CPU_IDLE is not set
# CONFIG_NET is not set
@@ -329,9 +338,13 @@ CONFIG_BLK_DEV=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -375,6 +388,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -471,6 +485,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=64
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
#
@@ -554,12 +569,13 @@ CONFIG_FB_SH_MOBILE_LCDC=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
# CONFIG_LCD_ILI9320 is not set
# CONFIG_LCD_PLATFORM is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_GENERIC=y
CONFIG_BACKLIGHT_HP680=y
#
@@ -631,6 +647,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -647,6 +664,7 @@ CONFIG_EXT2_FS=y
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -692,6 +710,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -771,7 +790,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -799,10 +817,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
@@ -870,6 +890,7 @@ CONFIG_CRYPTO_MD5=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -890,7 +911,6 @@ CONFIG_CRC_T10DIF=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig
index d3bbbb037716..b6fa4a7599d0 100644
--- a/arch/sh/configs/landisk_defconfig
+++ b/arch/sh/configs/landisk_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 16:58:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:02:54 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,10 +43,19 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -53,6 +63,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -62,10 +73,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -74,6 +83,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -113,11 +123,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -152,6 +157,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -193,11 +199,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -290,6 +297,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
CONFIG_PCCARD=y
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=y
@@ -329,7 +338,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -410,6 +418,7 @@ CONFIG_ATALK=m
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -422,13 +431,13 @@ CONFIG_ATALK=m
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -468,18 +477,23 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
#
# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
+CONFIG_IDE_XFER_MODE=y
CONFIG_IDE_ATAPI=y
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_IDE_GD=y
@@ -585,6 +599,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -607,6 +622,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
@@ -631,6 +647,7 @@ CONFIG_MD_RAID1=m
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -648,8 +665,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -700,6 +719,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -718,6 +738,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -725,7 +746,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -814,6 +838,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -898,6 +923,7 @@ CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
CONFIG_V4L_USB_DRIVERS=y
# CONFIG_USB_VIDEO_CLASS is not set
# CONFIG_USB_GSPCA is not set
+# CONFIG_VIDEO_HDPVR is not set
CONFIG_VIDEO_USBVIDEO=m
CONFIG_USB_VICAM=m
CONFIG_USB_IBMCAM=m
@@ -911,6 +937,7 @@ CONFIG_USB_STV680=m
# CONFIG_USB_ZC0301 is not set
CONFIG_USB_PWC=m
# CONFIG_USB_PWC_DEBUG is not set
+CONFIG_USB_PWC_INPUT_EVDEV=y
# CONFIG_USB_ZR364XX is not set
# CONFIG_USB_STKWEBCAM is not set
# CONFIG_USB_S2255 is not set
@@ -1020,6 +1047,7 @@ CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
@@ -1041,22 +1069,21 @@ CONFIG_USB_PRINTER=m
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
# CONFIG_USB_STORAGE_USBAT is not set
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_STORAGE_KARMA is not set
@@ -1081,7 +1108,7 @@ CONFIG_USB_SERIAL=m
# CONFIG_USB_SERIAL_CH341 is not set
# CONFIG_USB_SERIAL_WHITEHEAT is not set
# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CP210X is not set
# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
# CONFIG_USB_SERIAL_EMPEG is not set
CONFIG_USB_SERIAL_FTDI_SIO=m
@@ -1105,15 +1132,19 @@ CONFIG_USB_SERIAL_FTDI_SIO=m
# CONFIG_USB_SERIAL_NAVMAN is not set
CONFIG_USB_SERIAL_PL2303=m
# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
# CONFIG_USB_SERIAL_SPCP8X5 is not set
# CONFIG_USB_SERIAL_HP4X is not set
# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
# CONFIG_USB_SERIAL_TI is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
# CONFIG_USB_SERIAL_XIRCOM is not set
# CONFIG_USB_SERIAL_OPTION is not set
# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
# CONFIG_USB_SERIAL_DEBUG is not set
#
@@ -1130,7 +1161,6 @@ CONFIG_USB_EMI26=m
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1143,6 +1173,11 @@ CONFIG_USB_SISUSBVGA_CON=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1151,6 +1186,7 @@ CONFIG_USB_SISUSBVGA_CON=y
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1176,6 +1212,7 @@ CONFIG_REISERFS_FS=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1226,6 +1263,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1250,7 +1288,6 @@ CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=m
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1331,7 +1368,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -1424,6 +1460,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1445,7 +1482,7 @@ CONFIG_CRC_T10DIF=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/lboxre2_defconfig b/arch/sh/configs/lboxre2_defconfig
index d5c5a1dbaa62..92c515c4199f 100644
--- a/arch/sh/configs/lboxre2_defconfig
+++ b/arch/sh/configs/lboxre2_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:02:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:06:51 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,10 +43,19 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -53,6 +63,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -62,10 +73,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -74,6 +83,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -113,11 +123,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -152,6 +157,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -193,11 +199,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -291,6 +298,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
CONFIG_PCCARD=y
CONFIG_PCMCIA_DEBUG=y
CONFIG_PCMCIA=y
@@ -329,7 +338,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -408,6 +416,7 @@ CONFIG_NETFILTER_ADVANCED=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -420,13 +429,13 @@ CONFIG_NETFILTER_ADVANCED=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -465,12 +474,16 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -526,6 +539,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -549,6 +563,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -624,6 +639,7 @@ CONFIG_PATA_PLATFORM=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -641,8 +657,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -697,6 +715,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -715,6 +734,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -722,7 +742,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
CONFIG_NET_PCMCIA=y
# CONFIG_PCMCIA_3C589 is not set
# CONFIG_PCMCIA_3C574 is not set
@@ -810,6 +833,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -921,9 +945,13 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -968,6 +996,7 @@ CONFIG_RTC_INTF_DEV=y
#
# CONFIG_RTC_DRV_SH is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -990,6 +1019,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1036,6 +1066,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1124,7 +1155,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -1217,6 +1247,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1238,7 +1269,7 @@ CONFIG_CRC_T10DIF=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig
index 125d8019dc2f..26586c2d64ca 100644
--- a/arch/sh/configs/magicpanelr2_defconfig
+++ b/arch/sh/configs/magicpanelr2_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:03:37 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:07:39 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -43,33 +44,44 @@ CONFIG_BSD_PROCESS_ACCT_V3=y
# CONFIG_TASKSTATS is not set
CONFIG_AUDIT=y
# CONFIG_AUDITSYSCALL is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -77,6 +89,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -116,11 +129,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -155,6 +163,7 @@ CONFIG_CPU_SUBTYPE_SH7720=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +205,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -309,7 +319,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -359,6 +368,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -371,13 +381,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -402,6 +412,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -452,9 +463,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0000000
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -475,6 +484,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -491,9 +505,13 @@ CONFIG_BLK_DEV_RAM_SIZE=65536
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -507,6 +525,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -538,8 +557,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -556,7 +577,10 @@ CONFIG_SMSC911X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -778,6 +802,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -797,6 +822,7 @@ CONFIG_JBD=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -849,6 +875,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -868,7 +895,6 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -970,6 +996,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -984,7 +1011,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1025,7 +1051,8 @@ CONFIG_CRC32=y
CONFIG_AUDIT_GENERIC=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/microdev_defconfig b/arch/sh/configs/microdev_defconfig
index 5a1c0485a354..75178355d69a 100644
--- a/arch/sh/configs/microdev_defconfig
+++ b/arch/sh/configs/microdev_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:06:47 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:11:13 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,18 +43,32 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +78,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -74,6 +87,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -107,11 +121,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -146,6 +155,7 @@ CONFIG_CPU_SUBTYPE_SH4_202=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -193,11 +203,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -239,7 +250,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
#
@@ -304,7 +315,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_PACKET is not set
# CONFIG_UNIX is not set
CONFIG_XFRM=y
@@ -358,6 +368,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -370,13 +381,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -407,9 +418,13 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
@@ -443,6 +458,7 @@ CONFIG_IDE_PROC_FS=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -455,8 +471,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -473,7 +491,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -520,6 +541,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -601,15 +623,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -632,6 +659,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -678,6 +706,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -698,7 +727,6 @@ CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -778,7 +806,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -806,10 +833,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
@@ -877,6 +906,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -897,7 +927,9 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig
index 678576796bdf..a8720f9c6047 100644
--- a/arch/sh/configs/migor_defconfig
+++ b/arch/sh/configs/migor_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc1
-# Thu Jan 22 09:16:16 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:14:03 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,15 +16,17 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,14 +44,19 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_GROUP_SCHED is not set
-
-#
-# Control Group support
-#
# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
@@ -57,8 +64,13 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -68,10 +80,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -79,6 +89,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -120,11 +131,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -134,6 +140,7 @@ CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
CONFIG_CPU_SH4AL_DSP=y
CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -162,6 +169,7 @@ CONFIG_CPU_SHX2=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
CONFIG_CPU_SUBTYPE_SH7722=y
@@ -209,11 +217,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -243,6 +252,7 @@ CONFIG_SH_MIGOR_QVGA=y
# Timer and clock configuration
#
CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
CONFIG_SH_TIMER_IRQ=16
CONFIG_SH_PCLK_FREQ=33333333
# CONFIG_NO_HZ is not set
@@ -318,7 +328,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -373,6 +382,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -380,12 +390,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -495,7 +505,6 @@ CONFIG_MTD_NAND_PLATFORM=y
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
#
# UBI - Unsorted block images
@@ -514,10 +523,17 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -563,9 +579,11 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -578,8 +596,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -596,7 +616,6 @@ CONFIG_SMC91X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -679,6 +698,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -715,12 +735,9 @@ CONFIG_I2C_SH_MOBILE=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -797,7 +814,7 @@ CONFIG_VIDEO_MEDIA=y
#
# CONFIG_MEDIA_ATTACH is not set
CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
CONFIG_MEDIA_TUNER_SIMPLE=y
CONFIG_MEDIA_TUNER_TDA8290=y
CONFIG_MEDIA_TUNER_TDA9887=y
@@ -806,6 +823,7 @@ CONFIG_MEDIA_TUNER_TEA5767=y
CONFIG_MEDIA_TUNER_MT20XX=y
CONFIG_MEDIA_TUNER_XC2028=y
CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
CONFIG_VIDEO_V4L2=y
CONFIG_VIDEOBUF_GEN=y
CONFIG_VIDEOBUF_DMA_CONTIG=y
@@ -866,7 +884,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_USB_GADGET_MUSB_HDRC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
CONFIG_USB_GADGET=y
# CONFIG_USB_GADGET_DEBUG_FILES is not set
@@ -905,6 +923,7 @@ CONFIG_USB_G_SERIAL=y
# OTG and related infrastructure
#
# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -964,6 +983,7 @@ CONFIG_RTC_DRV_RS5C372=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=y
# CONFIG_UIO_PDRV is not set
CONFIG_UIO_PDRV_GENIRQ=y
@@ -1045,7 +1065,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1090,7 +1109,7 @@ CONFIG_TRACING=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1117,10 +1136,12 @@ CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1189,6 +1210,7 @@ CONFIG_CRYPTO_MANAGER2=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1209,7 +1231,9 @@ CONFIG_CRC_T10DIF=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/polaris_defconfig b/arch/sh/configs/polaris_defconfig
new file mode 100644
index 000000000000..df2d177d5346
--- /dev/null
+++ b/arch/sh/configs/polaris_defconfig
@@ -0,0 +1,972 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:16:48 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+CONFIG_AUDIT=y
+# CONFIG_AUDITSYSCALL is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System type
+#
+CONFIG_CPU_SH3=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+CONFIG_CPU_SUBTYPE_SH7709=y
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0C000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_29BIT=y
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU_EMU=y
+CONFIG_SH_ADC=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_IPR_IRQ=y
+CONFIG_CPU_HAS_SR_RB=y
+
+#
+# Board support
+#
+# CONFIG_SH_SOLUTION_ENGINE is not set
+# CONFIG_SH_HP6XX is not set
+CONFIG_SH_POLARIS=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+CONFIG_SH_PCLK_FREQ=33000000
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+CONFIG_SH_DMA_API=y
+CONFIG_SH_DMA=y
+CONFIG_NR_ONCHIP_DMA_CHANNELS=6
+# CONFIG_NR_DMA_CHANNELS_BOOL is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,115200 root=/dev/mtdblock2 rootfstype=jffs2 mem=63M mtdparts=physmap-flash.0:0x00100000(bootloader)ro,0x00500000(Kernel)ro,0x00A00000(Filesystem)"
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_COMPAT=y
+CONFIG_MTD_PHYSMAP_START=0x00000000
+CONFIG_MTD_PHYSMAP_LEN=0x01000000
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+CONFIG_SMSC_PHY=y
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_STNIC is not set
+# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=3
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SH=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_JFFS2_FS_WRITEBUFFER is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_LOCK_ALLOC=y
+# CONFIG_PROVE_LOCKING is not set
+CONFIG_LOCKDEP=y
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_LOCKDEP is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_DEBUG_SG=y
+# CONFIG_DEBUG_NOTIFIERS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+CONFIG_EARLY_SCIF_CONSOLE=y
+CONFIG_EARLY_SCIF_CONSOLE_PORT=0x00000000
+CONFIG_EARLY_PRINTK=y
+# CONFIG_DEBUG_BOOTMEM is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
+# CONFIG_IRQSTACKS is not set
+CONFIG_DUMP_CODE=y
+# CONFIG_SH_NO_BSS_INIT is not set
+# CONFIG_MORE_COMPILE_OPTIONS is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig
index 65b01a9e5934..7def4df46ddb 100644
--- a/arch/sh/configs/r7780mp_defconfig
+++ b/arch/sh/configs/r7780mp_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:10:19 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:20:17 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_IO_TRAPPED=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -45,15 +46,24 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -61,6 +71,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -71,10 +82,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -83,6 +92,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -124,11 +134,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -164,6 +169,7 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
CONFIG_CPU_SUBTYPE_SH7780=y
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -179,8 +185,11 @@ CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
# CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
CONFIG_VSYSCALL=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -212,11 +221,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -309,6 +319,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
@@ -330,7 +342,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -392,6 +403,7 @@ CONFIG_LLC=m
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -399,12 +411,12 @@ CONFIG_LLC=m
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -412,6 +424,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -451,13 +464,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-CONFIG_EEPROM_93CX6=y
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+CONFIG_EEPROM_93CX6=y
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -513,6 +533,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -535,6 +556,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -609,6 +631,7 @@ CONFIG_PATA_PLATFORM=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -627,8 +650,10 @@ CONFIG_AX88796_93CX6=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -684,6 +709,7 @@ CONFIG_R8169=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -702,6 +728,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -709,7 +736,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -796,6 +826,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -857,12 +888,9 @@ CONFIG_I2C_HIGHLANDER=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -885,6 +913,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -905,10 +934,14 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
@@ -949,6 +982,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -1007,9 +1041,13 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1071,6 +1109,7 @@ CONFIG_RTC_DRV_RS5C372=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1094,6 +1133,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1142,6 +1182,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1166,7 +1207,6 @@ CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1269,6 +1309,7 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1288,7 +1329,7 @@ CONFIG_TRACING=y
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1325,10 +1366,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1397,6 +1440,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1421,3 +1465,4 @@ CONFIG_CRC32=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig
index 8defaa5f13b9..cb134ffc2118 100644
--- a/arch/sh/configs/r7785rp_defconfig
+++ b/arch/sh/configs/r7785rp_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:14:41 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:24:35 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_NUMA=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
@@ -26,6 +26,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_IO_TRAPPED=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -48,11 +49,21 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
CONFIG_AUDIT_TREE=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_PREEMPT_RCU_TRACE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -60,21 +71,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -83,6 +92,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -126,12 +136,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_CLASSIC_RCU is not set
-# CONFIG_TREE_RCU is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_RCU_TRACE=y
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_PREEMPT_RCU_TRACE=y
# CONFIG_FREEZER is not set
#
@@ -168,6 +172,7 @@ CONFIG_CPU_SHX2=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
CONFIG_CPU_SUBTYPE_SH7785=y
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -183,8 +188,11 @@ CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
# CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
# CONFIG_X2TLB is not set
CONFIG_VSYSCALL=y
# CONFIG_NUMA is not set
@@ -222,11 +230,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -334,6 +343,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
@@ -355,7 +366,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -417,6 +427,7 @@ CONFIG_LLC=m
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -425,12 +436,12 @@ CONFIG_LLC=m
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -438,6 +449,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -477,13 +489,20 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-CONFIG_EEPROM_93CX6=y
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+CONFIG_EEPROM_93CX6=y
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -539,6 +558,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -561,6 +581,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -635,6 +656,7 @@ CONFIG_PATA_PLATFORM=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -653,8 +675,10 @@ CONFIG_AX88796_93CX6=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -687,6 +711,7 @@ CONFIG_R8169=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -705,6 +730,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -712,7 +738,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -800,6 +829,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -862,12 +892,9 @@ CONFIG_I2C_HIGHLANDER=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -914,6 +941,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
@@ -934,10 +962,14 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LM95241 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
@@ -979,6 +1011,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -1055,6 +1088,7 @@ CONFIG_FB_SH_MOBILE_LCDC=m
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -1089,9 +1123,13 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1153,6 +1191,7 @@ CONFIG_RTC_DRV_RS5C372=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1176,6 +1215,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1224,6 +1264,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1248,7 +1289,6 @@ CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1354,6 +1394,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1373,7 +1414,7 @@ CONFIG_TRACING=y
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1410,10 +1451,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1482,6 +1525,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1504,7 +1548,7 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_AUDIT_GENERIC=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/rsk7201_defconfig b/arch/sh/configs/rsk7201_defconfig
index 64ee69eef47c..a037c744b798 100644
--- a/arch/sh/configs/rsk7201_defconfig
+++ b/arch/sh/configs/rsk7201_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:19:04 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:29:08 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -24,6 +24,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -38,11 +39,20 @@ CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
# CONFIG_IKCONFIG_PROC is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
CONFIG_NAMESPACES=y
@@ -52,8 +62,13 @@ CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -63,16 +78,15 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
# CONFIG_AIO is not set
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
# CONFIG_SLUB is not set
CONFIG_SLOB=y
@@ -112,11 +126,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -152,6 +161,7 @@ CONFIG_CPU_SUBTYPE_SH7201=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -190,11 +200,11 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -217,7 +227,6 @@ CONFIG_SH_RSK7201=y
#
# Timer and clock configuration
#
-# CONFIG_SH_CMT is not set
CONFIG_SH_MTU2=y
CONFIG_SH_TIMER_IRQ=16
CONFIG_SH_PCLK_FREQ=40000000
@@ -251,7 +260,6 @@ CONFIG_SH_CLK_MD=0
CONFIG_HZ_1000=y
CONFIG_HZ=1000
# CONFIG_SCHED_HRTICK is not set
-# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
# CONFIG_SECCOMP is not set
CONFIG_PREEMPT_NONE=y
@@ -308,6 +316,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -358,9 +367,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -381,6 +388,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -392,9 +404,13 @@ CONFIG_BLK_DEV=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -562,6 +578,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -577,6 +594,7 @@ CONFIG_EXT2_FS=y
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_FILE_LOCKING is not set
# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -626,6 +644,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -671,7 +690,7 @@ CONFIG_TRACING=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -701,7 +720,7 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/rsk7203_defconfig b/arch/sh/configs/rsk7203_defconfig
index 8d7a5972a86a..9ae28e88426c 100644
--- a/arch/sh/configs/rsk7203_defconfig
+++ b/arch/sh/configs/rsk7203_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:20:31 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:30:34 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -18,12 +18,14 @@ CONFIG_GENERIC_GPIO=y
# CONFIG_GENERIC_CLOCKEVENTS is not set
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,11 +43,20 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
# CONFIG_IKCONFIG_PROC is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
# CONFIG_RELAY is not set
CONFIG_NAMESPACES=y
@@ -53,31 +64,35 @@ CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
+# CONFIG_NET_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
# CONFIG_SLUB is not set
CONFIG_SLOB=y
@@ -117,11 +132,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -157,6 +167,7 @@ CONFIG_CPU_SUBTYPE_SH7203=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -195,11 +206,11 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -271,7 +282,6 @@ CONFIG_HEARTBEAT=y
CONFIG_HZ_1000=y
CONFIG_HZ=1000
# CONFIG_SCHED_HRTICK is not set
-# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
# CONFIG_SECCOMP is not set
CONFIG_PREEMPT_NONE=y
@@ -315,8 +325,6 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_PACKET is not set
# CONFIG_UNIX is not set
# CONFIG_NET_KEY is not set
@@ -364,6 +372,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -371,18 +380,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -405,6 +415,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -455,9 +466,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -478,6 +487,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -492,9 +506,13 @@ CONFIG_BLK_DEV=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -508,6 +526,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -539,8 +558,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -557,7 +578,10 @@ CONFIG_SMSC911X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -777,7 +801,9 @@ CONFIG_USB_MON=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_SL811_HCD is not set
CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_HWA_HCD is not set
@@ -791,11 +817,11 @@ CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
# CONFIG_USB_LIBUSUAL is not set
@@ -823,7 +849,6 @@ CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -834,6 +859,12 @@ CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
CONFIG_NEW_LEDS=y
@@ -852,6 +883,10 @@ CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
# CONFIG_ACCESSIBILITY is not set
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
@@ -891,6 +926,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -906,6 +942,7 @@ CONFIG_RTC_DRV_SH=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -945,6 +982,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -962,7 +1000,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1018,6 +1055,7 @@ CONFIG_STACKTRACE=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
CONFIG_DEBUG_WRITECOUNT=y
# CONFIG_DEBUG_MEMORY_INIT is not set
CONFIG_DEBUG_LIST=y
@@ -1031,6 +1069,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1048,7 +1087,7 @@ CONFIG_TRACING=y
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1086,7 +1125,8 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig
index d6680f4382c2..c0f741af6da8 100644
--- a/arch/sh/configs/rts7751r2d1_defconfig
+++ b/arch/sh/configs/rts7751r2d1_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:23:15 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:33:25 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_IO_TRAPPED=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -43,10 +44,19 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -54,6 +64,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +74,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -75,6 +84,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -116,11 +126,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -155,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +202,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -300,6 +307,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
CONFIG_HOTPLUG_PCI=y
# CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -324,7 +333,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -376,6 +384,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -383,12 +392,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -396,6 +405,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -434,12 +444,17 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -495,6 +510,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -517,6 +533,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -591,6 +608,7 @@ CONFIG_PATA_PLATFORM=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -609,8 +627,10 @@ CONFIG_MII=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -665,6 +685,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -683,6 +704,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -690,7 +712,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -780,6 +805,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -798,7 +824,6 @@ CONFIG_SPI_SH_SCI=y
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_W1 is not set
@@ -822,6 +847,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
@@ -918,6 +944,7 @@ CONFIG_FB_SM501=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -996,6 +1023,8 @@ CONFIG_SND_PCI=y
# CONFIG_SND_INDIGO is not set
# CONFIG_SND_INDIGOIO is not set
# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
@@ -1101,6 +1130,7 @@ CONFIG_USB_DEVICE_CLASS=y
#
# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
@@ -1122,18 +1152,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1169,7 +1198,6 @@ CONFIG_USB_LIBUSUAL=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1179,6 +1207,11 @@ CONFIG_USB_LIBUSUAL=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1230,6 +1263,7 @@ CONFIG_RTC_DRV_R9701=y
#
# CONFIG_RTC_DRV_SH is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1247,6 +1281,7 @@ CONFIG_EXT2_FS=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1293,6 +1328,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1385,7 +1421,7 @@ CONFIG_TRACING=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1479,6 +1515,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1500,7 +1537,7 @@ CONFIG_CRC_T10DIF=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig
index 3fca10e24833..8feef629e49c 100644
--- a/arch/sh/configs/rts7751r2dplus_defconfig
+++ b/arch/sh/configs/rts7751r2dplus_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:26:10 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:34:12 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_IO_TRAPPED=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -43,10 +44,19 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -54,6 +64,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +74,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -75,6 +84,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -116,11 +126,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -155,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +202,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -300,6 +307,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
CONFIG_HOTPLUG_PCI=y
# CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -324,7 +333,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -376,6 +384,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -383,12 +392,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -396,6 +405,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -434,12 +444,17 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -495,6 +510,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -517,6 +533,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -591,6 +608,7 @@ CONFIG_PATA_PLATFORM=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -609,8 +627,10 @@ CONFIG_MII=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -665,6 +685,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -683,6 +704,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -690,7 +712,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -780,6 +805,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -798,7 +824,6 @@ CONFIG_SPI_SH_SCI=y
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_W1 is not set
@@ -822,6 +847,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
@@ -918,6 +944,7 @@ CONFIG_FB_SM501=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -996,6 +1023,8 @@ CONFIG_SND_PCI=y
# CONFIG_SND_INDIGO is not set
# CONFIG_SND_INDIGOIO is not set
# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_INDIGOIOX is not set
+# CONFIG_SND_INDIGODJX is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
@@ -1101,6 +1130,7 @@ CONFIG_USB_DEVICE_CLASS=y
#
# CONFIG_USB_C67X00_HCD is not set
# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
@@ -1122,18 +1152,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1169,7 +1198,6 @@ CONFIG_USB_LIBUSUAL=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1179,6 +1207,11 @@ CONFIG_USB_LIBUSUAL=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1230,6 +1263,7 @@ CONFIG_RTC_DRV_R9701=y
#
# CONFIG_RTC_DRV_SH is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1247,6 +1281,7 @@ CONFIG_EXT2_FS=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1293,6 +1328,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1385,7 +1421,7 @@ CONFIG_TRACING=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1479,6 +1515,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1500,7 +1537,7 @@ CONFIG_CRC_T10DIF=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sdk7780_defconfig b/arch/sh/configs/sdk7780_defconfig
index 5d6b06755ae7..739e2299ae80 100644
--- a/arch/sh/configs/sdk7780_defconfig
+++ b/arch/sh/configs/sdk7780_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:26:40 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:34:43 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -44,11 +45,20 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=18
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
@@ -56,21 +66,19 @@ CONFIG_RELAY=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -80,6 +88,7 @@ CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
@@ -119,11 +128,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -159,6 +163,7 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
CONFIG_CPU_SUBTYPE_SH7780=y
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -174,8 +179,11 @@ CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
# CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
CONFIG_VSYSCALL=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
@@ -207,11 +215,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -257,6 +266,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
+CONFIG_SH_DMA_IRQ_MULTI=y
CONFIG_NR_ONCHIP_DMA_CHANNELS=12
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
@@ -306,6 +316,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCI_LEGACY is not set
CONFIG_PCI_DEBUG=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
CONFIG_PCCARD=y
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_PCMCIA=y
@@ -348,7 +360,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -427,6 +438,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
CONFIG_NET_SCHED=y
#
@@ -471,13 +483,13 @@ CONFIG_NET_SCH_FIFO=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -631,6 +643,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -654,6 +667,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -739,6 +753,7 @@ CONFIG_BLK_DEV_DM=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -756,8 +771,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -780,7 +797,10 @@ CONFIG_SMC91X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -840,7 +860,6 @@ CONFIG_MOUSE_PS2=y
CONFIG_MOUSE_PS2_ALPS=y
CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_LIFEBOOK=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
# CONFIG_MOUSE_PS2_ELANTECH is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
@@ -899,6 +918,7 @@ CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_PPDEV is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -1023,6 +1043,7 @@ CONFIG_FB_SH_MOBILE_LCDC=m
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -1123,6 +1144,7 @@ CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
@@ -1141,18 +1163,17 @@ CONFIG_USB_PRINTER=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1189,7 +1210,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1201,6 +1221,11 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1243,7 +1268,9 @@ CONFIG_FS_MBCACHE=y
CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1295,6 +1322,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1318,7 +1346,6 @@ CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1424,6 +1451,7 @@ CONFIG_DEBUG_INFO=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1439,7 +1467,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1544,6 +1571,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1565,7 +1593,7 @@ CONFIG_CRC_T10DIF=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig
index e5b55b6f002d..d30e0a7ad9f1 100644
--- a/arch/sh/configs/se7206_defconfig
+++ b/arch/sh/configs/se7206_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:31:27 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:39:37 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -18,12 +18,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
# CONFIG_GENERIC_CLOCKEVENTS is not set
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -43,18 +45,28 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_TASKSTATS is not set
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_PREEMPT_RCU_TRACE=y
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_GROUP_SCHED is not set
CONFIG_CGROUPS=y
CONFIG_CGROUP_DEBUG=y
CONFIG_CGROUP_NS=y
# CONFIG_CGROUP_FREEZER is not set
CONFIG_CGROUP_DEVICE=y
-# CONFIG_GROUP_SCHED is not set
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_MM_OWNER=y
CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_MM_OWNER=y
# CONFIG_SYSFS_DEPRECATED_V2 is not set
CONFIG_RELAY=y
CONFIG_NAMESPACES=y
@@ -62,31 +74,35 @@ CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
+# CONFIG_NET_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
-# CONFIG_COMPAT_BRK is not set
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_COMPAT_BRK is not set
# CONFIG_SLAB is not set
# CONFIG_SLUB is not set
CONFIG_SLOB=y
@@ -127,12 +143,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_CLASSIC_RCU is not set
-# CONFIG_TREE_RCU is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_RCU_TRACE=y
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_PREEMPT_RCU_TRACE=y
# CONFIG_FREEZER is not set
#
@@ -168,6 +178,7 @@ CONFIG_CPU_SUBTYPE_SH7206=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -206,11 +217,11 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -280,7 +291,6 @@ CONFIG_HEARTBEAT=y
CONFIG_HZ_1000=y
CONFIG_HZ=1000
# CONFIG_SCHED_HRTICK is not set
-CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
# CONFIG_SECCOMP is not set
# CONFIG_PREEMPT_NONE is not set
@@ -322,8 +332,6 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -378,6 +386,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -385,18 +394,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -419,6 +429,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -466,9 +477,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x20000000
-CONFIG_MTD_PHYSMAP_LEN=0x01000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -489,6 +498,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -506,9 +520,13 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-CONFIG_EEPROM_93CX6=y
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+CONFIG_EEPROM_93CX6=y
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -522,6 +540,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -534,8 +553,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -552,7 +573,10 @@ CONFIG_SMC91X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -696,6 +720,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -712,6 +737,7 @@ CONFIG_EXT2_FS=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -752,6 +778,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -771,7 +798,6 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -824,6 +850,7 @@ CONFIG_STACKTRACE=y
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
# CONFIG_DEBUG_WRITECOUNT is not set
# CONFIG_DEBUG_MEMORY_INIT is not set
CONFIG_DEBUG_LIST=y
@@ -835,6 +862,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -852,7 +880,7 @@ CONFIG_TRACING=y
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -955,6 +983,7 @@ CONFIG_CRYPTO_CRC32C=y
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
CONFIG_CRYPTO_LZO=y
#
@@ -980,7 +1009,8 @@ CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig
index 390052577031..fbb72d029e68 100644
--- a/arch/sh/configs/se7343_defconfig
+++ b/arch/sh/configs/se7343_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:33:53 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:42:00 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,14 +16,16 @@ CONFIG_GENERIC_IRQ_PROBE=y
# CONFIG_GENERIC_GPIO is not set
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,14 +43,23 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -56,6 +67,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -65,10 +77,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -76,6 +86,7 @@ CONFIG_EVENTFD=y
# CONFIG_SHMEM is not set
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -114,11 +125,6 @@ CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="deadline"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -127,6 +133,7 @@ CONFIG_CLASSIC_RCU=y
CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
CONFIG_CPU_SH4AL_DSP=y
+CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -155,6 +162,7 @@ CONFIG_CPU_SH4AL_DSP=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
CONFIG_CPU_SUBTYPE_SH7343=y
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +204,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -227,6 +236,7 @@ CONFIG_SH_7343_SOLUTION_ENGINE=y
# Timer and clock configuration
#
CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
CONFIG_SH_TIMER_IRQ=16
CONFIG_SH_PCLK_FREQ=33333333
# CONFIG_NO_HZ is not set
@@ -302,7 +312,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -353,6 +362,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -365,13 +375,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -394,6 +404,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -441,9 +452,7 @@ CONFIG_MTD_RAM=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x0
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -464,6 +473,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -520,9 +534,11 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -539,7 +555,10 @@ CONFIG_MII=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -633,6 +652,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -669,12 +689,9 @@ CONFIG_I2C_SH_MOBILE=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -706,6 +723,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -727,7 +745,7 @@ CONFIG_VIDEO_MEDIA=y
#
# CONFIG_MEDIA_ATTACH is not set
CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
CONFIG_MEDIA_TUNER_SIMPLE=y
CONFIG_MEDIA_TUNER_TDA8290=y
CONFIG_MEDIA_TUNER_TDA9887=y
@@ -736,6 +754,7 @@ CONFIG_MEDIA_TUNER_TEA5767=y
CONFIG_MEDIA_TUNER_MT20XX=y
CONFIG_MEDIA_TUNER_XC2028=y
CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
CONFIG_VIDEO_V4L2=y
CONFIG_VIDEO_V4L1=y
CONFIG_VIDEO_CAPTURE_DRIVERS=y
@@ -757,6 +776,7 @@ CONFIG_USB_GSPCA=m
# CONFIG_USB_GSPCA_ETOMS is not set
# CONFIG_USB_GSPCA_FINEPIX is not set
# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_MR97310A is not set
# CONFIG_USB_GSPCA_OV519 is not set
# CONFIG_USB_GSPCA_OV534 is not set
# CONFIG_USB_GSPCA_PAC207 is not set
@@ -769,6 +789,8 @@ CONFIG_USB_GSPCA=m
# CONFIG_USB_GSPCA_SPCA506 is not set
# CONFIG_USB_GSPCA_SPCA508 is not set
# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_SQ905 is not set
+# CONFIG_USB_GSPCA_SQ905C is not set
# CONFIG_USB_GSPCA_STK014 is not set
# CONFIG_USB_GSPCA_SUNPLUS is not set
# CONFIG_USB_GSPCA_T613 is not set
@@ -776,6 +798,7 @@ CONFIG_USB_GSPCA=m
# CONFIG_USB_GSPCA_VC032X is not set
# CONFIG_USB_GSPCA_ZC3XX is not set
# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_HDPVR is not set
# CONFIG_VIDEO_EM28XX is not set
# CONFIG_VIDEO_USBVISION is not set
# CONFIG_USB_VICAM is not set
@@ -833,6 +856,7 @@ CONFIG_FB_SH_MOBILE_LCDC=m
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -940,7 +964,9 @@ CONFIG_USB_DEVICE_CLASS=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
CONFIG_USB_ISP116X_HCD=y
+# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_HWA_HCD is not set
@@ -954,11 +980,11 @@ CONFIG_USB_ISP116X_HCD=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
# CONFIG_USB_STORAGE is not set
# CONFIG_USB_LIBUSUAL is not set
@@ -988,7 +1014,6 @@ CONFIG_USB_ISP116X_HCD=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -999,12 +1024,18 @@ CONFIG_USB_ISP116X_HCD=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=y
# CONFIG_UIO_PDRV is not set
# CONFIG_UIO_PDRV_GENIRQ is not set
@@ -1031,6 +1062,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -1084,6 +1116,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1105,7 +1138,6 @@ CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1146,7 +1178,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1240,6 +1271,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1265,3 +1297,4 @@ CONFIG_ZLIB_DEFLATE=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig
index 932b0235b1de..125304e80f57 100644
--- a/arch/sh/configs/se7619_defconfig
+++ b/arch/sh/configs/se7619_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:36:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:44:53 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -18,12 +18,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
# CONFIG_GENERIC_CLOCKEVENTS is not set
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -36,15 +38,25 @@ CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
# CONFIG_SYSCTL_SYSCALL is not set
@@ -53,16 +65,15 @@ CONFIG_EMBEDDED=y
CONFIG_PRINTK=y
CONFIG_BUG=y
# CONFIG_ELF_CORE is not set
-CONFIG_COMPAT_BRK=y
# CONFIG_BASE_FULL is not set
# CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_AIO=y
# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -93,11 +104,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -132,6 +138,7 @@ CONFIG_CPU_SUBTYPE_SH7619=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -170,11 +177,11 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
# CONFIG_CACHE_WRITEBACK is not set
CONFIG_CACHE_WRITETHROUGH=y
# CONFIG_CACHE_OFF is not set
@@ -228,7 +235,6 @@ CONFIG_HZ_100=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
# CONFIG_SCHED_HRTICK is not set
-# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
# CONFIG_SECCOMP is not set
CONFIG_PREEMPT_NONE=y
@@ -329,9 +335,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xa0000000
-CONFIG_MTD_PHYSMAP_LEN=0x01000000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_SOLUTIONENGINE is not set
# CONFIG_MTD_PLATRAM is not set
@@ -353,6 +357,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -364,9 +373,13 @@ CONFIG_BLK_DEV=y
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -514,15 +527,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -537,6 +555,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -575,6 +594,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -614,7 +634,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
diff --git a/arch/sh/configs/se7705_defconfig b/arch/sh/configs/se7705_defconfig
index 8574d6eb00a3..0308abf52384 100644
--- a/arch/sh/configs/se7705_defconfig
+++ b/arch/sh/configs/se7705_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:37:50 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:45:56 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,16 +42,30 @@ CONFIG_LOCALVERSION_AUTO=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -59,10 +74,8 @@ CONFIG_UID16=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -70,6 +83,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -106,11 +120,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -145,6 +154,7 @@ CONFIG_CPU_SUBTYPE_SH7705=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -186,12 +196,13 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
CONFIG_SH7705_CACHE_32KB=y
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -292,7 +303,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -347,6 +357,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -359,13 +370,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -384,6 +395,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -451,6 +463,11 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -467,9 +484,13 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -483,6 +504,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -495,8 +517,10 @@ CONFIG_NET_ETHERNET=y
# CONFIG_AX88796 is not set
CONFIG_STNIC=y
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -513,7 +537,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
CONFIG_PPP=y
# CONFIG_PPP_MULTILINK is not set
@@ -593,6 +620,7 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -684,15 +712,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -709,6 +742,7 @@ CONFIG_EXT2_FS=y
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -761,6 +795,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -778,7 +813,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -817,7 +851,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -908,6 +941,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -930,7 +964,8 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7712_defconfig b/arch/sh/configs/se7712_defconfig
index e31ea84f116d..a8c24b703489 100644
--- a/arch/sh/configs/se7712_defconfig
+++ b/arch/sh/configs/se7712_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:40:12 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:48:18 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,10 +42,19 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -52,21 +62,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
# CONFIG_BUG is not set
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
# CONFIG_BASE_FULL is not set
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -74,6 +82,7 @@ CONFIG_EVENTFD=y
# CONFIG_SHMEM is not set
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -112,11 +121,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -151,6 +155,7 @@ CONFIG_CPU_SUBTYPE_SH7712=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +197,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -300,7 +306,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -364,6 +369,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
CONFIG_NET_SCHED=y
#
@@ -411,7 +417,6 @@ CONFIG_NET_SCH_FIFO=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
@@ -419,6 +424,7 @@ CONFIG_WIRELESS=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -443,6 +449,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -510,6 +517,11 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -523,9 +535,13 @@ CONFIG_BLK_DEV=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -571,6 +587,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -579,6 +596,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_PLATFORM=y
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -611,8 +629,10 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
CONFIG_SH_ETH=y
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -629,7 +649,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -675,6 +698,7 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -744,9 +768,13 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
CONFIG_NEW_LEDS=y
@@ -764,9 +792,14 @@ CONFIG_LEDS_TRIGGERS=y
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -791,6 +824,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -844,6 +878,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -861,7 +896,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -923,6 +957,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -937,7 +972,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -974,10 +1008,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=y
# CONFIG_CRYPTO_TEST is not set
@@ -1046,6 +1082,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1068,7 +1105,7 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7721_defconfig b/arch/sh/configs/se7721_defconfig
index ad1bace3ad46..4b79c2567dc8 100644
--- a/arch/sh/configs/se7721_defconfig
+++ b/arch/sh/configs/se7721_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:43:33 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:51:44 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,14 +42,23 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -56,21 +66,19 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
# CONFIG_BUG is not set
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
# CONFIG_BASE_FULL is not set
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -78,6 +86,7 @@ CONFIG_EVENTFD=y
# CONFIG_SHMEM is not set
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -116,11 +125,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -155,6 +159,7 @@ CONFIG_CPU_SUBTYPE_SH7721=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +201,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -303,7 +309,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -367,6 +372,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
CONFIG_NET_SCHED=y
#
@@ -414,7 +420,6 @@ CONFIG_NET_SCH_FIFO=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
@@ -422,6 +427,7 @@ CONFIG_WIRELESS=y
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -446,6 +452,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -513,6 +520,11 @@ CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -527,9 +539,13 @@ CONFIG_BLK_DEV=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -572,6 +588,7 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -580,6 +597,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_PLATFORM=y
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -595,7 +613,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -805,7 +826,9 @@ CONFIG_USB_MON=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -823,18 +846,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -870,7 +892,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -880,6 +901,11 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
CONFIG_NEW_LEDS=y
@@ -897,9 +923,14 @@ CONFIG_LEDS_TRIGGERS=y
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -924,6 +955,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -980,6 +1012,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1082,6 +1115,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1096,7 +1130,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1133,10 +1166,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=y
# CONFIG_CRYPTO_TEST is not set
@@ -1205,6 +1240,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1227,7 +1263,7 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7722_defconfig b/arch/sh/configs/se7722_defconfig
index abb189a1d314..82bdaac45fb5 100644
--- a/arch/sh/configs/se7722_defconfig
+++ b/arch/sh/configs/se7722_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:46:59 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:55:10 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,15 +16,17 @@ CONFIG_GENERIC_IRQ_PROBE=y
# CONFIG_GENERIC_GPIO is not set
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -44,19 +46,33 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -66,10 +82,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -78,6 +92,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
@@ -118,11 +133,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -132,6 +142,7 @@ CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
CONFIG_CPU_SH4AL_DSP=y
CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -160,6 +171,7 @@ CONFIG_CPU_SHX2=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
CONFIG_CPU_SUBTYPE_SH7722=y
@@ -213,11 +225,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -246,6 +259,7 @@ CONFIG_SH_7722_SOLUTION_ENGINE=y
# Timer and clock configuration
#
CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
CONFIG_SH_TIMER_IRQ=16
CONFIG_SH_PCLK_FREQ=33333333
CONFIG_TICK_ONESHOT=y
@@ -321,7 +335,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -373,6 +386,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -385,13 +399,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -422,9 +436,13 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -470,6 +488,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -478,6 +497,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_PLATFORM=y
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -490,8 +510,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -508,7 +530,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -589,6 +614,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -680,9 +706,13 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -725,6 +755,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -748,6 +779,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -791,6 +823,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -843,7 +876,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -936,6 +969,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -956,7 +990,9 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7750_defconfig b/arch/sh/configs/se7750_defconfig
index ac874f63a625..ceef6d9138ee 100644
--- a/arch/sh/configs/se7750_defconfig
+++ b/arch/sh/configs/se7750_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:49:22 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:57:31 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,11 +43,20 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -54,6 +64,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +74,8 @@ CONFIG_KALLSYMS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -74,6 +83,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -112,11 +122,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -151,6 +156,7 @@ CONFIG_CPU_SUBTYPE_SH7750=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +198,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -299,7 +306,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -355,6 +361,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -367,13 +374,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -392,6 +399,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -459,6 +467,11 @@ CONFIG_MTD_ROM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -472,9 +485,13 @@ CONFIG_BLK_DEV=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
@@ -538,9 +555,11 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -553,8 +572,10 @@ CONFIG_NET_ETHERNET=y
# CONFIG_AX88796 is not set
CONFIG_STNIC=y
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -571,7 +592,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -622,6 +646,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -711,15 +736,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -735,6 +765,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -789,6 +820,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -806,7 +838,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -859,7 +890,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -951,6 +981,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -973,7 +1004,7 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7751_defconfig b/arch/sh/configs/se7751_defconfig
index f54ae056f177..67fc26b3a7d0 100644
--- a/arch/sh/configs/se7751_defconfig
+++ b/arch/sh/configs/se7751_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:51:47 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 18:59:59 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,18 +43,32 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -63,10 +78,8 @@ CONFIG_KALLSYMS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -74,6 +87,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -112,11 +126,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -151,6 +160,7 @@ CONFIG_CPU_SUBTYPE_SH7751=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +202,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -301,7 +312,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -376,6 +386,7 @@ CONFIG_IP_NF_QUEUE=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -388,13 +399,13 @@ CONFIG_IP_NF_QUEUE=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -413,6 +424,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -480,6 +492,11 @@ CONFIG_MTD_RAM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -496,9 +513,13 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -512,6 +533,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -524,8 +546,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -542,7 +566,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -585,6 +612,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -673,15 +701,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -699,6 +732,7 @@ CONFIG_EXT2_FS=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -753,6 +787,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -802,7 +837,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -894,6 +928,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -916,7 +951,8 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig
index 7504978e8747..ebce23cc2ad8 100644
--- a/arch/sh/configs/se7780_defconfig
+++ b/arch/sh/configs/se7780_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:53:50 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:02:05 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,6 +42,15 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -52,6 +62,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -60,10 +71,8 @@ CONFIG_SYSCTL_SYSCALL=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -72,6 +81,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -108,11 +118,6 @@ CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="deadline"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -148,6 +153,7 @@ CONFIG_CPU_SH4A=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
CONFIG_CPU_SUBTYPE_SH7780=y
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -192,11 +198,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -283,6 +290,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
#
# Executable file formats
@@ -296,7 +305,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -351,6 +359,7 @@ CONFIG_IPV6=y
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -362,13 +371,13 @@ CONFIG_IPV6=y
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
#
@@ -386,6 +395,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -460,6 +470,11 @@ CONFIG_MTD_ROM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -479,10 +494,14 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -536,6 +555,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -557,6 +577,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -565,6 +586,7 @@ CONFIG_SATA_PMP=y
CONFIG_ATA_SFF=y
# CONFIG_SATA_SVW is not set
# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
@@ -619,6 +641,7 @@ CONFIG_SATA_SIL=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
@@ -654,8 +677,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -693,7 +718,10 @@ CONFIG_NET_PCI=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -885,6 +913,7 @@ CONFIG_FB_SH_MOBILE_LCDC=m
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -978,6 +1007,7 @@ CONFIG_USB_MON=y
# CONFIG_USB_C67X00_HCD is not set
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
@@ -996,18 +1026,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1043,7 +1072,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1055,6 +1083,11 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -1062,6 +1095,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1120,6 +1154,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_HFSPLUS_FS is not set
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1214,7 +1249,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1301,6 +1336,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1323,7 +1359,7 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig
index 04bde1e96965..6fcdb090cf32 100644
--- a/arch/sh/configs/sh03_defconfig
+++ b/arch/sh/configs/sh03_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 17:56:46 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:04:59 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -44,18 +45,32 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -65,10 +80,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -77,6 +90,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -119,11 +133,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -158,6 +167,7 @@ CONFIG_CPU_SUBTYPE_SH7751=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -199,11 +209,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -294,6 +305,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
CONFIG_HOTPLUG_PCI=m
# CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -318,7 +331,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -375,6 +387,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -382,18 +395,19 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -430,12 +444,16 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y
@@ -541,6 +559,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -562,6 +581,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_FUSION is not set
@@ -577,6 +597,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -594,8 +615,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -646,6 +669,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -664,6 +688,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -671,7 +696,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -754,6 +782,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -872,9 +901,13 @@ CONFIG_USB_ARCH_HAS_EHCI=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -883,6 +916,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -908,6 +942,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -957,6 +992,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -981,7 +1017,6 @@ CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1081,7 +1116,7 @@ CONFIG_TRACING=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -1110,10 +1145,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1182,6 +1219,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1205,7 +1243,8 @@ CONFIG_CRC32=y
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig
index 1b869f452ad1..1ab37c01da6e 100644
--- a/arch/sh/configs/sh7710voipgw_defconfig
+++ b/arch/sh/configs/sh7710voipgw_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:00:31 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:09:01 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,14 +42,23 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -56,6 +66,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -65,10 +76,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
# CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -76,6 +85,7 @@ CONFIG_EVENTFD=y
# CONFIG_SHMEM is not set
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -114,11 +124,6 @@ CONFIG_DEFAULT_DEADLINE=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="deadline"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -153,6 +158,7 @@ CONFIG_CPU_SUBTYPE_SH7710=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -194,11 +200,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -299,7 +306,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -369,6 +375,7 @@ CONFIG_NETFILTER_ADVANCED=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
CONFIG_NET_SCHED=y
#
@@ -418,13 +425,13 @@ CONFIG_NET_SCH_FIFO=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -447,6 +454,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -514,6 +522,11 @@ CONFIG_MTD_RAM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -527,9 +540,13 @@ CONFIG_BLK_DEV=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -543,6 +560,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -556,8 +574,10 @@ CONFIG_NET_ETHERNET=y
# CONFIG_STNIC is not set
# CONFIG_SH_ETH is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -574,7 +594,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -640,6 +663,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -718,15 +742,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -742,6 +771,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -795,6 +825,7 @@ CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -844,7 +875,7 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -936,6 +967,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -961,3 +993,4 @@ CONFIG_ZLIB_DEFLATE=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh7763rdp_defconfig b/arch/sh/configs/sh7763rdp_defconfig
index ba33aca75af6..c79bb84ec305 100644
--- a/arch/sh/configs/sh7763rdp_defconfig
+++ b/arch/sh/configs/sh7763rdp_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:02:28 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:10:57 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,15 +42,24 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -58,9 +68,11 @@ CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -70,10 +82,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -81,6 +91,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -122,11 +133,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -162,6 +168,7 @@ CONFIG_CPU_SUBTYPE_SH7763=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -207,11 +214,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -231,6 +239,7 @@ CONFIG_CPU_HAS_FPU=y
# Board support
#
CONFIG_SH_SH7763RDP=y
+# CONFIG_SH_ESPT is not set
#
# Timer and clock configuration
@@ -311,8 +320,6 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -367,6 +374,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -374,12 +382,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Network testing
#
# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -387,6 +395,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -409,6 +418,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set
@@ -462,9 +472,7 @@ CONFIG_MTD_CFI_UTIL=y
#
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x8000000
-CONFIG_MTD_PHYSMAP_LEN=0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -485,6 +493,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -544,9 +557,11 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -579,8 +594,10 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
CONFIG_SH_ETH=y
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -597,7 +614,10 @@ CONFIG_SH_ETH=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -677,6 +697,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -756,6 +777,7 @@ CONFIG_FB_SH7760=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -807,7 +829,9 @@ CONFIG_USB_MON=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -825,18 +849,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -872,7 +895,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -882,6 +904,11 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
@@ -903,6 +930,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -926,6 +954,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -974,6 +1003,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -991,7 +1021,6 @@ CONFIG_ROOT_NFS=y
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1075,7 +1104,7 @@ CONFIG_TRACING=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1167,6 +1196,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1187,7 +1217,7 @@ CONFIG_CRC_T10DIF=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh7785lcr_32bit_defconfig b/arch/sh/configs/sh7785lcr_32bit_defconfig
new file mode 100644
index 000000000000..a6cf4505741c
--- /dev/null
+++ b/arch/sh/configs/sh7785lcr_32bit_defconfig
@@ -0,0 +1,1561 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:12:18 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_PCI=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_IO_TRAPPED=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_OPROFILE is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX2=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+CONFIG_CPU_SUBTYPE_SH7785=y
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x40000000
+CONFIG_MEMORY_SIZE=0x20000000
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
+# CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+# CONFIG_NUMA is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=2
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_STATIC=y
+# CONFIG_MEMORY_HOTPLUG is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+CONFIG_SH_STORE_QUEUES=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_HIGHLANDER is not set
+CONFIG_SH_SH7785LCR=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=28
+CONFIG_SH_PCLK_FREQ=50000000
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_GUSA=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_SH_PCIDMA_NONCOHERENT=y
+CONFIG_PCI_AUTO=y
+CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
+# CONFIG_PCIEPORTBUS is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SIL24 is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_MII=y
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+CONFIG_R8169=y
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SH_KEYSC is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOPCA=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SH_MOBILE is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+CONFIG_I2C_PCA_PLATFORM=y
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+CONFIG_MFD_SM501=y
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=m
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+CONFIG_FB_SH_MOBILE_LCDC=m
+CONFIG_FB_SM501=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_LOGO_SUPERH_MONO is not set
+# CONFIG_LOGO_SUPERH_VGA16 is not set
+# CONFIG_LOGO_SUPERH_CLUT224 is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+CONFIG_THRUSTMASTER_FF=m
+CONFIG_ZEROPLUS_FF=m
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+CONFIG_USB_R8A66597_HCD=y
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=m
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+CONFIG_RTC_DRV_RS5C372=y
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_SH is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+CONFIG_NLS_CODEPAGE_932=y
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DEBUG_BOOTMEM is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_DUMP_CODE is not set
+# CONFIG_SH_NO_BSS_INIT is not set
+# CONFIG_MORE_COMPILE_OPTIONS is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/sh7785lcr_defconfig b/arch/sh/configs/sh7785lcr_defconfig
index 1d63628df6f6..8a42bbef1f50 100644
--- a/arch/sh/configs/sh7785lcr_defconfig
+++ b/arch/sh/configs/sh7785lcr_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:05:18 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:15:58 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_NUMA=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
@@ -26,6 +26,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_IO_TRAPPED=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -46,15 +47,24 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
@@ -62,6 +72,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -72,10 +83,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -84,6 +93,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -124,11 +134,6 @@ CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -165,6 +170,7 @@ CONFIG_CPU_SHX2=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
CONFIG_CPU_SUBTYPE_SH7785=y
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -180,8 +186,11 @@ CONFIG_MMU=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_MEMORY_START=0x08000000
CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_29BIT=y
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB_ENABLE=y
# CONFIG_PMB is not set
+CONFIG_PMB_FIXED=y
# CONFIG_X2TLB is not set
CONFIG_VSYSCALL=y
# CONFIG_NUMA is not set
@@ -213,11 +222,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -239,7 +249,6 @@ CONFIG_CPU_HAS_FPU=y
#
# CONFIG_SH_HIGHLANDER is not set
CONFIG_SH_SH7785LCR=y
-CONFIG_SH_SH7785LCR_29BIT_PHYSMAPS=y
#
# Timer and clock configuration
@@ -307,6 +316,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
@@ -328,7 +339,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -388,6 +398,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -400,7 +411,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
@@ -408,6 +418,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -430,6 +441,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -477,9 +489,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x00000000
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=0
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set
@@ -502,6 +512,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=0
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -565,6 +580,7 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_SRP_ATTRS is not set
# CONFIG_SCSI_LOWLEVEL is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -639,6 +655,7 @@ CONFIG_SATA_SIL=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -668,6 +685,7 @@ CONFIG_R8169=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set
@@ -677,7 +695,10 @@ CONFIG_R8169=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -772,6 +793,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -834,12 +856,9 @@ CONFIG_I2C_PCA_PLATFORM=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -871,6 +890,7 @@ CONFIG_MFD_SM501=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -948,6 +968,7 @@ CONFIG_FB_SM501=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
@@ -1041,6 +1062,7 @@ CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=m
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=m
@@ -1062,18 +1084,17 @@ CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1109,7 +1130,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1121,6 +1141,11 @@ CONFIG_USB_TEST=m
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1182,6 +1207,7 @@ CONFIG_RTC_DRV_RS5C372=y
#
# CONFIG_RTC_DRV_SH is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1204,6 +1230,7 @@ CONFIG_FS_POSIX_ACL=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1253,6 +1280,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
CONFIG_MINIX_FS=y
# CONFIG_OMFS_FS is not set
@@ -1277,7 +1305,6 @@ CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=y
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1382,6 +1409,7 @@ CONFIG_DEBUG_PREEMPT=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1397,7 +1425,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1433,10 +1460,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1505,6 +1534,7 @@ CONFIG_CRYPTO_DES=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1525,7 +1555,7 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/shmin_defconfig b/arch/sh/configs/shmin_defconfig
index 8ba10e1e08cd..d695e9061874 100644
--- a/arch/sh/configs/shmin_defconfig
+++ b/arch/sh/configs/shmin_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:09:00 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:19:03 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,13 +16,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -39,15 +40,25 @@ CONFIG_LOCALVERSION_AUTO=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
# CONFIG_UID16 is not set
# CONFIG_SYSCTL_SYSCALL is not set
@@ -56,10 +67,8 @@ CONFIG_EMBEDDED=y
CONFIG_PRINTK=y
# CONFIG_BUG is not set
# CONFIG_ELF_CORE is not set
-CONFIG_COMPAT_BRK=y
# CONFIG_BASE_FULL is not set
# CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
# CONFIG_EPOLL is not set
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -67,6 +76,7 @@ CONFIG_EVENTFD=y
# CONFIG_SHMEM is not set
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
# CONFIG_SLUB is not set
CONFIG_SLOB=y
@@ -97,11 +107,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -136,6 +141,7 @@ CONFIG_CPU_SUBTYPE_SH7706=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -177,11 +183,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -267,7 +274,6 @@ CONFIG_CMDLINE="console=ttySC1,115200 root=1f01 mtdparts=phys_mapped_flash:64k(f
# Executable file formats
#
CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
@@ -281,7 +287,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_PACKET is not set
CONFIG_UNIX=y
CONFIG_XFRM=y
@@ -335,6 +340,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -347,13 +353,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -419,9 +425,7 @@ CONFIG_MTD_CFI_UTIL=y
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0xa0000000
-CONFIG_MTD_PHYSMAP_LEN=0x80000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=1
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_PLATRAM is not set
#
@@ -442,6 +446,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -456,9 +465,13 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -472,6 +485,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -484,8 +498,10 @@ CONFIG_NET_ETHERNET=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -502,7 +518,10 @@ CONFIG_NETDEV_10000=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -549,6 +568,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -618,15 +638,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -641,6 +666,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -683,6 +709,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -702,7 +729,6 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -740,7 +766,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_SH_STANDARD_BIOS=y
@@ -831,6 +856,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -855,3 +881,4 @@ CONFIG_ZLIB_INFLATE=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig
index ed90a7e81099..e3651f574399 100644
--- a/arch/sh/configs/shx3_defconfig
+++ b/arch/sh/configs/shx3_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:10:57 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:20:54 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -19,7 +19,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_LOCKBREAK=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_SMP=y
CONFIG_SYS_SUPPORTS_NUMA=y
CONFIG_STACKTRACE_SUPPORT=y
@@ -27,6 +27,7 @@ CONFIG_LOCKDEP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -47,24 +48,35 @@ CONFIG_BSD_PROCESS_ACCT=y
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
CONFIG_AUDIT_TREE=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+CONFIG_RCU_TRACE=y
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_PREEMPT_RCU_TRACE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_NS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
# CONFIG_CPUSETS is not set
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_MM_OWNER=y
CONFIG_CGROUP_MEM_RES_CTLR=y
+# CONFIG_CGROUP_MEM_RES_CTLR_SWAP is not set
+CONFIG_MM_OWNER=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
@@ -73,24 +85,23 @@ CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
+# CONFIG_NET_NS is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -98,6 +109,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
# CONFIG_SLUB is not set
CONFIG_SLOB=y
@@ -142,12 +154,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-# CONFIG_CLASSIC_RCU is not set
-# CONFIG_TREE_RCU is not set
-CONFIG_PREEMPT_RCU=y
-CONFIG_RCU_TRACE=y
-# CONFIG_TREE_RCU_TRACE is not set
-CONFIG_PREEMPT_RCU_TRACE=y
CONFIG_FREEZER=y
#
@@ -184,6 +190,7 @@ CONFIG_CPU_SHX3=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
CONFIG_CPU_SUBTYPE_SHX3=y
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -240,11 +247,12 @@ CONFIG_MIGRATION=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -361,8 +369,6 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_PACKET is not set
# CONFIG_UNIX is not set
CONFIG_XFRM=y
@@ -434,6 +440,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -442,6 +449,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
CONFIG_CAN=m
CONFIG_CAN_RAW=m
@@ -455,8 +463,8 @@ CONFIG_CAN_VCAN=m
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -490,10 +498,18 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -539,6 +555,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -547,6 +564,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_PLATFORM=y
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -560,8 +578,10 @@ CONFIG_MII=y
# CONFIG_STNIC is not set
CONFIG_SMC91X=y
# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -578,7 +598,10 @@ CONFIG_SMC91X=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -670,12 +693,9 @@ CONFIG_I2C_HELPER_AUTO=y
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_LEGACY is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
@@ -695,7 +715,6 @@ CONFIG_SPI_MASTER=y
#
# SPI Protocol Masters
#
-# CONFIG_EEPROM_AT25 is not set
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_TLE62X0 is not set
# CONFIG_W1 is not set
@@ -732,6 +751,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
# CONFIG_REGULATOR is not set
#
@@ -788,7 +808,9 @@ CONFIG_USB_MON=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_SL811_HCD is not set
CONFIG_USB_R8A66597_HCD=m
# CONFIG_USB_HWA_HCD is not set
@@ -803,11 +825,11 @@ CONFIG_USB_R8A66597_HCD=m
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
# CONFIG_USB_STORAGE is not set
# CONFIG_USB_LIBUSUAL is not set
@@ -837,7 +859,6 @@ CONFIG_USB_R8A66597_HCD=m
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -860,10 +881,12 @@ CONFIG_USB_GADGET_SELECTED=y
# CONFIG_USB_GADGET_PXA25X is not set
# CONFIG_USB_GADGET_PXA27X is not set
# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_IMX is not set
CONFIG_USB_GADGET_M66592=y
CONFIG_USB_M66592=y
# CONFIG_USB_GADGET_AMD5536UDC is not set
# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
# CONFIG_USB_GADGET_NET2280 is not set
# CONFIG_USB_GADGET_GOKU is not set
# CONFIG_USB_GADGET_DUMMY_HCD is not set
@@ -876,6 +899,11 @@ CONFIG_USB_GADGET_DUALSPEED=y
# CONFIG_USB_MIDI_GADGET is not set
# CONFIG_USB_G_PRINTER is not set
# CONFIG_USB_CDC_COMPOSITE is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
@@ -942,6 +970,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=y
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=m
# CONFIG_UIO_PDRV is not set
# CONFIG_UIO_PDRV_GENIRQ is not set
@@ -969,6 +998,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1012,6 +1042,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1086,6 +1117,7 @@ CONFIG_FRAME_POINTER=y
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
@@ -1105,7 +1137,7 @@ CONFIG_TRACING=y
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1205,6 +1237,7 @@ CONFIG_CRYPTO=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1226,7 +1259,7 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_AUDIT_GENERIC=y
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig
index 98377e502650..6960f60bf52e 100644
--- a/arch/sh/configs/snapgear_defconfig
+++ b/arch/sh/configs/snapgear_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:14:08 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:21:39 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -41,18 +42,32 @@ CONFIG_LOCALVERSION_AUTO=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -62,10 +77,8 @@ CONFIG_KALLSYMS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -74,6 +87,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -107,11 +121,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -146,6 +155,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -187,11 +197,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -239,6 +250,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
+CONFIG_SH_DMA_IRQ_MULTI=y
CONFIG_NR_ONCHIP_DMA_CHANNELS=8
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
@@ -288,6 +300,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
#
# Executable file formats
@@ -307,7 +321,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_PACKET is not set
# CONFIG_UNIX is not set
# CONFIG_NET_KEY is not set
@@ -352,6 +365,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -364,13 +378,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
# CONFIG_WIRELESS_OLD_REGULATORY is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -464,6 +478,11 @@ CONFIG_MTD_PLATRAM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -509,6 +528,7 @@ CONFIG_HAVE_IDE=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -526,8 +546,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -571,7 +593,10 @@ CONFIG_8139TOO_PIO=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -711,6 +736,7 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_INFINIBAND is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -728,6 +754,7 @@ CONFIG_EXT2_FS=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY is not set
# CONFIG_QUOTA is not set
@@ -771,6 +798,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -820,7 +848,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -849,7 +876,8 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig
index 72703bf57afa..7ea639bc5936 100644
--- a/arch/sh/configs/systemh_defconfig
+++ b/arch/sh/configs/systemh_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:15:56 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:23:31 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,13 +17,14 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -38,18 +39,32 @@ CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -59,10 +74,8 @@ CONFIG_KALLSYMS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -70,6 +83,7 @@ CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -109,11 +123,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -148,6 +157,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -189,11 +199,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -318,9 +329,13 @@ CONFIG_BLK_DEV_RAM_SIZE=1024
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -372,6 +387,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
@@ -452,15 +468,20 @@ CONFIG_USB_ARCH_HAS_HCD=y
#
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -475,6 +496,7 @@ CONFIG_USB_ARCH_HAS_HCD=y
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -518,6 +540,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -558,7 +581,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -587,7 +609,7 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
index 01fc1defb33b..bbeb4c6ebb95 100644
--- a/arch/sh/configs/titan_defconfig
+++ b/arch/sh/configs/titan_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:17:19 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:24:55 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -17,7 +17,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_PCI=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -25,6 +25,7 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -42,19 +43,33 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
@@ -65,10 +80,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -77,6 +90,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
@@ -116,11 +130,6 @@ CONFIG_DEFAULT_AS=y
# CONFIG_DEFAULT_CFQ is not set
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -155,6 +164,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -196,11 +206,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -248,6 +259,7 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
#
CONFIG_SH_DMA_API=y
CONFIG_SH_DMA=y
+CONFIG_SH_DMA_IRQ_MULTI=y
CONFIG_NR_ONCHIP_DMA_CHANNELS=8
# CONFIG_NR_DMA_CHANNELS_BOOL is not set
@@ -299,6 +311,8 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set
CONFIG_HOTPLUG_PCI=y
# CONFIG_HOTPLUG_PCI_FAKE is not set
@@ -323,7 +337,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -406,6 +419,7 @@ CONFIG_NETFILTER_NETLINK_LOG=m
CONFIG_NETFILTER_XTABLES=m
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+CONFIG_NETFILTER_XT_TARGET_HL=m
CONFIG_NETFILTER_XT_TARGET_MARK=m
# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
@@ -418,6 +432,7 @@ CONFIG_NETFILTER_XT_MATCH_DCCP=m
# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
CONFIG_NETFILTER_XT_MATCH_ESP=m
# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+CONFIG_NETFILTER_XT_MATCH_HL=m
# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
@@ -475,11 +490,11 @@ CONFIG_IP6_NF_MATCH_HL=m
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
# CONFIG_IP6_NF_MATCH_MH is not set
CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_REJECT=m
CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_HL=m
CONFIG_IP6_NF_RAW=m
# CONFIG_BRIDGE_NF_EBTABLES is not set
# CONFIG_IP_DCCP is not set
@@ -500,6 +515,7 @@ CONFIG_LLC=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
CONFIG_NET_SCHED=y
#
@@ -565,7 +581,6 @@ CONFIG_NET_SCH_FIFO=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
@@ -574,6 +589,7 @@ CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -599,6 +615,7 @@ CONFIG_MTD_DEBUG=y
CONFIG_MTD_DEBUG_VERBOSE=0
# CONFIG_MTD_CONCAT is not set
# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_TESTS is not set
#
# User Modules And Translation Layers
@@ -675,6 +692,11 @@ CONFIG_MTD_NAND_IDS=m
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -698,12 +720,16 @@ CONFIG_ATA_OVER_ETH=m
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -760,6 +786,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_FCOE is not set
@@ -781,6 +808,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_FUSION is not set
@@ -796,6 +824,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_IFB is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
@@ -832,8 +861,10 @@ CONFIG_MII=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
@@ -888,6 +919,7 @@ CONFIG_NETDEV_1000=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
@@ -906,6 +938,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_BNX2X is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
# CONFIG_TR is not set
#
@@ -913,7 +946,10 @@ CONFIG_CHELSIO_T3_DEPENDS=y
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
#
# USB Network Adapters
@@ -1025,6 +1061,7 @@ CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
@@ -1174,6 +1211,7 @@ CONFIG_USB_MON=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
CONFIG_USB_OHCI_HCD=y
@@ -1195,18 +1233,17 @@ CONFIG_USB_PRINTER=m
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -1235,7 +1272,7 @@ CONFIG_USB_SERIAL_ARK3116=m
# CONFIG_USB_SERIAL_CH341 is not set
# CONFIG_USB_SERIAL_WHITEHEAT is not set
# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CP210X is not set
# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
# CONFIG_USB_SERIAL_EMPEG is not set
# CONFIG_USB_SERIAL_FTDI_SIO is not set
@@ -1259,15 +1296,19 @@ CONFIG_USB_SERIAL_ARK3116=m
# CONFIG_USB_SERIAL_NAVMAN is not set
CONFIG_USB_SERIAL_PL2303=m
# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
# CONFIG_USB_SERIAL_SPCP8X5 is not set
# CONFIG_USB_SERIAL_HP4X is not set
# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
# CONFIG_USB_SERIAL_TI is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
# CONFIG_USB_SERIAL_XIRCOM is not set
# CONFIG_USB_SERIAL_OPTION is not set
# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
# CONFIG_USB_SERIAL_DEBUG is not set
#
@@ -1284,7 +1325,6 @@ CONFIG_USB_SERIAL_PL2303=m
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -1296,6 +1336,11 @@ CONFIG_USB_SERIAL_PL2303=m
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
@@ -1337,6 +1382,7 @@ CONFIG_RTC_INTF_DEV=y
#
CONFIG_RTC_DRV_SH=m
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -1363,6 +1409,7 @@ CONFIG_XFS_FS=m
# CONFIG_XFS_RT is not set
# CONFIG_XFS_DEBUG is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -1413,6 +1460,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -1436,7 +1484,6 @@ CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
CONFIG_SMB_FS=m
@@ -1559,6 +1606,7 @@ CONFIG_SCHED_DEBUG=y
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
+# CONFIG_PAGE_POISONING is not set
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
@@ -1573,7 +1621,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
@@ -1610,10 +1657,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_AUTHENC=y
# CONFIG_CRYPTO_TEST is not set
@@ -1683,6 +1732,7 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1706,11 +1756,12 @@ CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_TEXTSEARCH_BM=m
CONFIG_TEXTSEARCH_FSM=m
-CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/ul2_defconfig b/arch/sh/configs/ul2_defconfig
index 27f968a959f8..34f5192a3241 100644
--- a/arch/sh/configs/ul2_defconfig
+++ b/arch/sh/configs/ul2_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28
-# Fri Jan 9 18:22:53 2009
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:30:27 2009
#
CONFIG_SUPERH=y
CONFIG_SUPERH32=y
@@ -16,15 +16,17 @@ CONFIG_GENERIC_IRQ_PROBE=y
# CONFIG_GENERIC_GPIO is not set
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
-# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
-# CONFIG_ARCH_HIBERNATION_POSSIBLE is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_SYS_SUPPORTS_CMT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -44,19 +46,33 @@ CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
@@ -66,10 +82,8 @@ CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
@@ -78,6 +92,7 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
@@ -118,11 +133,6 @@ CONFIG_IOSCHED_NOOP=y
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_FREEZER is not set
#
@@ -132,6 +142,7 @@ CONFIG_CPU_SH4=y
CONFIG_CPU_SH4A=y
CONFIG_CPU_SH4AL_DSP=y
CONFIG_CPU_SHX2=y
+CONFIG_ARCH_SHMOBILE=y
# CONFIG_CPU_SUBTYPE_SH7619 is not set
# CONFIG_CPU_SUBTYPE_SH7201 is not set
# CONFIG_CPU_SUBTYPE_SH7203 is not set
@@ -160,6 +171,7 @@ CONFIG_CPU_SHX2=y
# CONFIG_CPU_SUBTYPE_SH7770 is not set
# CONFIG_CPU_SUBTYPE_SH7780 is not set
# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
# CONFIG_CPU_SUBTYPE_SHX3 is not set
# CONFIG_CPU_SUBTYPE_SH7343 is not set
# CONFIG_CPU_SUBTYPE_SH7722 is not set
@@ -213,11 +225,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ZONE_DMA_FLAG=0
CONFIG_NR_QUICK=2
CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
#
# Cache configuration
#
-# CONFIG_SH_DIRECT_MAPPED is not set
CONFIG_CACHE_WRITEBACK=y
# CONFIG_CACHE_WRITETHROUGH is not set
# CONFIG_CACHE_OFF is not set
@@ -243,6 +256,7 @@ CONFIG_CPU_HAS_DSP=y
# Timer and clock configuration
#
CONFIG_SH_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
CONFIG_SH_TIMER_IRQ=16
CONFIG_SH_PCLK_FREQ=33333333
CONFIG_TICK_ONESHOT=y
@@ -319,7 +333,6 @@ CONFIG_NET=y
#
# Networking options
#
-CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
@@ -374,6 +387,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
@@ -386,15 +400,14 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
CONFIG_WIRELESS=y
CONFIG_CFG80211=y
# CONFIG_CFG80211_REG_DEBUG is not set
-CONFIG_NL80211=y
# CONFIG_WIRELESS_OLD_REGULATORY is not set
CONFIG_WIRELESS_EXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
CONFIG_LIB80211=m
+# CONFIG_LIB80211_DEBUG is not set
CONFIG_MAC80211=y
#
@@ -408,6 +421,7 @@ CONFIG_MAC80211_RC_DEFAULT="pid"
# CONFIG_MAC80211_MESH is not set
# CONFIG_MAC80211_LEDS is not set
# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -430,6 +444,7 @@ CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -497,6 +512,11 @@ CONFIG_MTD_RAM=y
# CONFIG_MTD_ONENAND is not set
#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
@@ -514,9 +534,13 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -562,6 +586,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_LIBFC is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
@@ -570,6 +595,7 @@ CONFIG_ATA_SFF=y
CONFIG_PATA_PLATFORM=y
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -582,8 +608,10 @@ CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_STNIC is not set
# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -605,12 +633,13 @@ CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_SDIO=m
CONFIG_LIBERTAS_DEBUG=y
# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
# CONFIG_USB_ZD1201 is not set
# CONFIG_USB_NET_RNDIS_WLAN is not set
# CONFIG_RTL8187 is not set
# CONFIG_MAC80211_HWSIM is not set
# CONFIG_P54_COMMON is not set
-# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_AR9170_USB is not set
# CONFIG_HOSTAP is not set
# CONFIG_B43 is not set
# CONFIG_B43LEGACY is not set
@@ -618,6 +647,10 @@ CONFIG_LIBERTAS_DEBUG=y
# CONFIG_RT2X00 is not set
#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
@@ -794,7 +827,9 @@ CONFIG_USB_MON=y
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_SL811_HCD is not set
CONFIG_USB_R8A66597_HCD=y
# CONFIG_SUPERH_ON_CHIP_R8A66597 is not set
@@ -809,18 +844,17 @@ CONFIG_USB_R8A66597_HCD=y
# CONFIG_USB_TMC is not set
#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#
#
-# see USB_STORAGE Help for more information
+# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
# CONFIG_USB_STORAGE_USBAT is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_STORAGE_SDDR55 is not set
@@ -856,7 +890,6 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
@@ -866,6 +899,11 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
@@ -887,6 +925,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_ACCESSIBILITY is not set
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
@@ -909,6 +948,7 @@ CONFIG_FS_MBCACHE=y
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
@@ -956,6 +996,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
@@ -976,7 +1017,6 @@ CONFIG_LOCKD=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1059,7 +1099,6 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
#
# Tracers
#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_SH_STANDARD_BIOS is not set
@@ -1087,10 +1126,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
@@ -1159,6 +1200,7 @@ CONFIG_CRYPTO_ARC4=y
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set
#
@@ -1180,7 +1222,8 @@ CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig
new file mode 100644
index 000000000000..d174b1a4d802
--- /dev/null
+++ b/arch/sh/configs/urquell_defconfig
@@ -0,0 +1,1341 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29
+# Thu Apr 2 19:33:39 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_NUMA=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_OPROFILE is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX3=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+CONFIG_CPU_SUBTYPE_SH7786=y
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_29BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+# CONFIG_NUMA is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_STATIC=y
+# CONFIG_MEMORY_HOTPLUG is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+CONFIG_SH_STORE_QUEUES=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEAEX=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+CONFIG_SH_URQUELL=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+CONFIG_SH_PCLK_FREQ=33333333
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_GUSA=y
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1, 38400 earlyprintk=serial ip=on ignore_loglevel root=/dev/nfs ip=dhcp memchunk.vpu=4m"
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_OLD_REGULATORY is not set
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_STNIC is not set
+CONFIG_SMC91X=y
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_SH_KEYSC is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOPCA=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SH_MOBILE is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+CONFIG_I2C_PCA_PLATFORM=y
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+CONFIG_MFD_SM501=y
+# CONFIG_MFD_SM501_GPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=m
+CONFIG_FB_SYS_COPYAREA=m
+CONFIG_FB_SYS_IMAGEBLIT=m
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=m
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_SH_MOBILE_LCDC=m
+CONFIG_FB_SM501=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_LOGO_SUPERH_MONO is not set
+# CONFIG_LOGO_SUPERH_VGA16 is not set
+# CONFIG_LOGO_SUPERH_CLUT224 is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
+CONFIG_HID_PANTHERLORD=y
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+CONFIG_THRUSTMASTER_FF=m
+CONFIG_ZEROPLUS_FF=m
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+CONFIG_NLS_CODEPAGE_932=y
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+
+#
+# Tracers
+#
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_MORE_COMPILE_OPTIONS is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
index 01936368b8b0..666713ac5fcf 100644
--- a/arch/sh/drivers/dma/Kconfig
+++ b/arch/sh/drivers/dma/Kconfig
@@ -9,16 +9,28 @@ config SH_DMA
select SH_DMA_API
default n
+config SH_DMA_IRQ_MULTI
+ bool
+ depends on SH_DMA
+ default y if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7751 || \
+ CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7750R || \
+ CPU_SUBTYPE_SH7751R || CPU_SUBTYPE_SH7091 || \
+ CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7764 || \
+ CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
+
config NR_ONCHIP_DMA_CHANNELS
int
depends on SH_DMA
- default "6" if CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721
- default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R
- default "12" if CPU_SUBTYPE_SH7780
- default "4"
+ default "4" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7751 || \
+ CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7091
+ default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R || \
+ CPU_SUBTYPE_SH7760
+ default "12" if CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7780 || \
+ CPU_SUBTYPE_SH7785
+ default "6"
help
This allows you to specify the number of channels that the on-chip
- DMAC supports. This will be 4 for SH7750/SH7751 and 8 for the
+ DMAC supports. This will be 4 for SH7091/SH7750/SH7751 and 8 for the
SH7750R/SH7751R.
config NR_DMA_CHANNELS_BOOL
@@ -46,4 +58,28 @@ config SH_DMABRG
of the SH7760.
Say Y if you want to use Audio/USB DMA on your SH7760 board.
+config PVR2_DMA
+ tristate "PowerVR 2 DMAC support"
+ depends on SH_DREAMCAST && SH_DMA
+ help
+ Selecting this will enable support for the PVR2 DMA controller.
+ As this chains off of the on-chip DMAC, that must also be
+ enabled by default.
+
+ This is primarily used by the pvr2fb framebuffer driver for
+ certain optimizations, but is not necessary for functionality.
+
+ If in doubt, say N.
+
+config G2_DMA
+ tristate "G2 Bus DMA support"
+ depends on SH_DREAMCAST
+ select SH_DMA_API
+ help
+ This enables support for the DMA controller for the Dreamcast's
+ G2 bus. Drivers that want this will generally enable this on
+ their own.
+
+ If in doubt, say N.
+
endmenu
diff --git a/arch/sh/drivers/dma/Makefile b/arch/sh/drivers/dma/Makefile
index ab956adacb47..c6068137b46f 100644
--- a/arch/sh/drivers/dma/Makefile
+++ b/arch/sh/drivers/dma/Makefile
@@ -4,5 +4,6 @@
obj-$(CONFIG_SH_DMA_API) += dma-api.o dma-sysfs.o
obj-$(CONFIG_SH_DMA) += dma-sh.o
-obj-$(CONFIG_SH_DREAMCAST) += dma-pvr2.o dma-g2.o
+obj-$(CONFIG_PVR2_DMA) += dma-pvr2.o
+obj-$(CONFIG_G2_DMA) += dma-g2.o
obj-$(CONFIG_SH_DMABRG) += dmabrg.o
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index 50887a592dd0..37fb5b8bbc3f 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -17,28 +17,16 @@
#include <mach-dreamcast/mach/dma.h>
#include <asm/dma.h>
#include <asm/io.h>
-#include "dma-sh.h"
-
-static int dmte_irq_map[] = {
- DMTE0_IRQ,
- DMTE1_IRQ,
- DMTE2_IRQ,
- DMTE3_IRQ,
-#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
- defined(CONFIG_CPU_SUBTYPE_SH7721) || \
- defined(CONFIG_CPU_SUBTYPE_SH7751R) || \
- defined(CONFIG_CPU_SUBTYPE_SH7760) || \
- defined(CONFIG_CPU_SUBTYPE_SH7709) || \
- defined(CONFIG_CPU_SUBTYPE_SH7780)
- DMTE4_IRQ,
- DMTE5_IRQ,
-#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7751R) || \
- defined(CONFIG_CPU_SUBTYPE_SH7760) || \
- defined(CONFIG_CPU_SUBTYPE_SH7780)
- DMTE6_IRQ,
- DMTE7_IRQ,
+#include <asm/dma-sh.h>
+
+#if defined(DMAE1_IRQ)
+#define NR_DMAE 2
+#else
+#define NR_DMAE 1
#endif
+
+static const char *dmae_name[] = {
+ "DMAC Address Error0", "DMAC Address Error1"
};
static inline unsigned int get_dmte_irq(unsigned int chan)
@@ -46,7 +34,14 @@ static inline unsigned int get_dmte_irq(unsigned int chan)
unsigned int irq = 0;
if (chan < ARRAY_SIZE(dmte_irq_map))
irq = dmte_irq_map[chan];
+
+#if defined(CONFIG_SH_DMA_IRQ_MULTI)
+ if (irq > DMTE6_IRQ)
+ return DMTE6_IRQ;
+ return DMTE0_IRQ;
+#else
return irq;
+#endif
}
/*
@@ -59,7 +54,7 @@ static inline unsigned int get_dmte_irq(unsigned int chan)
*/
static inline unsigned int calc_xmit_shift(struct dma_channel *chan)
{
- u32 chcr = ctrl_inl(CHCR[chan->chan]);
+ u32 chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
return ts_shift[(chcr & CHCR_TS_MASK)>>CHCR_TS_SHIFT];
}
@@ -75,13 +70,13 @@ static irqreturn_t dma_tei(int irq, void *dev_id)
struct dma_channel *chan = dev_id;
u32 chcr;
- chcr = ctrl_inl(CHCR[chan->chan]);
+ chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
if (!(chcr & CHCR_TE))
return IRQ_NONE;
chcr &= ~(CHCR_IE | CHCR_DE);
- ctrl_outl(chcr, CHCR[chan->chan]);
+ ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
wake_up(&chan->wait_queue);
@@ -94,7 +89,12 @@ static int sh_dmac_request_dma(struct dma_channel *chan)
return 0;
return request_irq(get_dmte_irq(chan->chan), dma_tei,
- IRQF_DISABLED, chan->dev_id, chan);
+#if defined(CONFIG_SH_DMA_IRQ_MULTI)
+ IRQF_SHARED,
+#else
+ IRQF_DISABLED,
+#endif
+ chan->dev_id, chan);
}
static void sh_dmac_free_dma(struct dma_channel *chan)
@@ -115,7 +115,7 @@ sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr)
chan->flags &= ~DMA_TEI_CAPABLE;
}
- ctrl_outl(chcr, CHCR[chan->chan]);
+ ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
chan->flags |= DMA_CONFIGURED;
return 0;
@@ -126,13 +126,13 @@ static void sh_dmac_enable_dma(struct dma_channel *chan)
int irq;
u32 chcr;
- chcr = ctrl_inl(CHCR[chan->chan]);
+ chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
chcr |= CHCR_DE;
if (chan->flags & DMA_TEI_CAPABLE)
chcr |= CHCR_IE;
- ctrl_outl(chcr, CHCR[chan->chan]);
+ ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
if (chan->flags & DMA_TEI_CAPABLE) {
irq = get_dmte_irq(chan->chan);
@@ -150,9 +150,9 @@ static void sh_dmac_disable_dma(struct dma_channel *chan)
disable_irq(irq);
}
- chcr = ctrl_inl(CHCR[chan->chan]);
+ chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE);
- ctrl_outl(chcr, CHCR[chan->chan]);
+ ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
}
static int sh_dmac_xfer_dma(struct dma_channel *chan)
@@ -183,12 +183,13 @@ static int sh_dmac_xfer_dma(struct dma_channel *chan)
*/
if (chan->sar || (mach_is_dreamcast() &&
chan->chan == PVR2_CASCADE_CHAN))
- ctrl_outl(chan->sar, SAR[chan->chan]);
+ ctrl_outl(chan->sar, (dma_base_addr[chan->chan]+SAR));
if (chan->dar || (mach_is_dreamcast() &&
chan->chan == PVR2_CASCADE_CHAN))
- ctrl_outl(chan->dar, DAR[chan->chan]);
+ ctrl_outl(chan->dar, (dma_base_addr[chan->chan] + DAR));
- ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]);
+ ctrl_outl(chan->count >> calc_xmit_shift(chan),
+ (dma_base_addr[chan->chan] + TCR));
sh_dmac_enable_dma(chan);
@@ -197,36 +198,26 @@ static int sh_dmac_xfer_dma(struct dma_channel *chan)
static int sh_dmac_get_dma_residue(struct dma_channel *chan)
{
- if (!(ctrl_inl(CHCR[chan->chan]) & CHCR_DE))
+ if (!(ctrl_inl(dma_base_addr[chan->chan] + CHCR) & CHCR_DE))
return 0;
- return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan);
+ return ctrl_inl(dma_base_addr[chan->chan] + TCR)
+ << calc_xmit_shift(chan);
}
-#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
- defined(CONFIG_CPU_SUBTYPE_SH7721) || \
- defined(CONFIG_CPU_SUBTYPE_SH7780) || \
- defined(CONFIG_CPU_SUBTYPE_SH7709)
-#define dmaor_read_reg() ctrl_inw(DMAOR)
-#define dmaor_write_reg(data) ctrl_outw(data, DMAOR)
-#else
-#define dmaor_read_reg() ctrl_inl(DMAOR)
-#define dmaor_write_reg(data) ctrl_outl(data, DMAOR)
-#endif
-
-static inline int dmaor_reset(void)
+static inline int dmaor_reset(int no)
{
- unsigned long dmaor = dmaor_read_reg();
+ unsigned long dmaor = dmaor_read_reg(no);
/* Try to clear the error flags first, incase they are set */
dmaor &= ~(DMAOR_NMIF | DMAOR_AE);
- dmaor_write_reg(dmaor);
+ dmaor_write_reg(no, dmaor);
dmaor |= DMAOR_INIT;
- dmaor_write_reg(dmaor);
+ dmaor_write_reg(no, dmaor);
/* See if we got an error again */
- if ((dmaor_read_reg() & (DMAOR_AE | DMAOR_NMIF))) {
+ if ((dmaor_read_reg(no) & (DMAOR_AE | DMAOR_NMIF))) {
printk(KERN_ERR "dma-sh: Can't initialize DMAOR.\n");
return -EINVAL;
}
@@ -237,10 +228,33 @@ static inline int dmaor_reset(void)
#if defined(CONFIG_CPU_SH4)
static irqreturn_t dma_err(int irq, void *dummy)
{
- dmaor_reset();
+#if defined(CONFIG_SH_DMA_IRQ_MULTI)
+ int cnt = 0;
+ switch (irq) {
+#if defined(DMTE6_IRQ) && defined(DMAE1_IRQ)
+ case DMTE6_IRQ:
+ cnt++;
+#endif
+ case DMTE0_IRQ:
+ if (dmaor_read_reg(cnt) & (DMAOR_NMIF | DMAOR_AE)) {
+ disable_irq(irq);
+ /* DMA multi and error IRQ */
+ return IRQ_HANDLED;
+ }
+ default:
+ return IRQ_NONE;
+ }
+#else
+ dmaor_reset(0);
+#if defined(CONFIG_CPU_SUBTYPE_SH7723) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7785)
+ dmaor_reset(1);
+#endif
disable_irq(irq);
return IRQ_HANDLED;
+#endif
}
#endif
@@ -259,24 +273,59 @@ static struct dma_info sh_dmac_info = {
.flags = DMAC_CHANNELS_TEI_CAPABLE,
};
+#ifdef CONFIG_CPU_SH4
+static unsigned int get_dma_error_irq(int n)
+{
+#if defined(CONFIG_SH_DMA_IRQ_MULTI)
+ return (n == 0) ? get_dmte_irq(0) : get_dmte_irq(6);
+#else
+ return (n == 0) ? DMAE0_IRQ :
+#if defined(DMAE1_IRQ)
+ DMAE1_IRQ;
+#else
+ -1;
+#endif
+#endif
+}
+#endif
+
static int __init sh_dmac_init(void)
{
struct dma_info *info = &sh_dmac_info;
int i;
#ifdef CONFIG_CPU_SH4
- i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0);
- if (unlikely(i < 0))
- return i;
+ int n;
+
+ for (n = 0; n < NR_DMAE; n++) {
+ i = request_irq(get_dma_error_irq(n), dma_err,
+#if defined(CONFIG_SH_DMA_IRQ_MULTI)
+ IRQF_SHARED,
+#else
+ IRQF_DISABLED,
#endif
+ dmae_name[n], (void *)dmae_name[n]);
+ if (unlikely(i < 0)) {
+ printk(KERN_ERR "%s request_irq fail\n", dmae_name[n]);
+ return i;
+ }
+ }
+#endif /* CONFIG_CPU_SH4 */
/*
* Initialize DMAOR, and clean up any error flags that may have
* been set.
*/
- i = dmaor_reset();
+ i = dmaor_reset(0);
+ if (unlikely(i != 0))
+ return i;
+#if defined(CONFIG_CPU_SUBTYPE_SH7723) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7785)
+ i = dmaor_reset(1);
if (unlikely(i != 0))
return i;
+#endif
return register_dmac(info);
}
@@ -284,8 +333,12 @@ static int __init sh_dmac_init(void)
static void __exit sh_dmac_exit(void)
{
#ifdef CONFIG_CPU_SH4
- free_irq(DMAE_IRQ, 0);
-#endif
+ int n;
+
+ for (n = 0; n < NR_DMAE; n++) {
+ free_irq(get_dma_error_irq(n), (void *)dmae_name[n]);
+ }
+#endif /* CONFIG_CPU_SH4 */
unregister_dmac(&sh_dmac_info);
}
diff --git a/arch/sh/drivers/dma/dma-sh.h b/arch/sh/drivers/dma/dma-sh.h
deleted file mode 100644
index 05fecd5428e4..000000000000
--- a/arch/sh/drivers/dma/dma-sh.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * arch/sh/drivers/dma/dma-sh.h
- *
- * Copyright (C) 2000 Takashi YOSHII
- * Copyright (C) 2003 Paul Mundt
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#ifndef __DMA_SH_H
-#define __DMA_SH_H
-
-#include <cpu/dma.h>
-
-/* Definitions for the SuperH DMAC */
-#define REQ_L 0x00000000
-#define REQ_E 0x00080000
-#define RACK_H 0x00000000
-#define RACK_L 0x00040000
-#define ACK_R 0x00000000
-#define ACK_W 0x00020000
-#define ACK_H 0x00000000
-#define ACK_L 0x00010000
-#define DM_INC 0x00004000
-#define DM_DEC 0x00008000
-#define SM_INC 0x00001000
-#define SM_DEC 0x00002000
-#define RS_IN 0x00000200
-#define RS_OUT 0x00000300
-#define TS_BLK 0x00000040
-#define TM_BUR 0x00000020
-#define CHCR_DE 0x00000001
-#define CHCR_TE 0x00000002
-#define CHCR_IE 0x00000004
-
-/* DMAOR definitions */
-#define DMAOR_AE 0x00000004
-#define DMAOR_NMIF 0x00000002
-#define DMAOR_DME 0x00000001
-
-/*
- * Define the default configuration for dual address memory-memory transfer.
- * The 0x400 value represents auto-request, external->external.
- */
-#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_32)
-
-#define MAX_DMAC_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS)
-
-/*
- * Subtypes that have fewer channels than this simply need to change
- * CONFIG_NR_ONCHIP_DMA_CHANNELS. Likewise, subtypes with a larger number
- * of channels should expand on this.
- *
- * For most subtypes we can easily figure these values out with some
- * basic calculation, unfortunately on other subtypes these are more
- * scattered, so we just leave it unrolled for simplicity.
- */
-#define SAR ((unsigned long[]){SH_DMAC_BASE + 0x00, SH_DMAC_BASE + 0x10, \
- SH_DMAC_BASE + 0x20, SH_DMAC_BASE + 0x30, \
- SH_DMAC_BASE + 0x50, SH_DMAC_BASE + 0x60})
-#define DAR ((unsigned long[]){SH_DMAC_BASE + 0x04, SH_DMAC_BASE + 0x14, \
- SH_DMAC_BASE + 0x24, SH_DMAC_BASE + 0x34, \
- SH_DMAC_BASE + 0x54, SH_DMAC_BASE + 0x64})
-#define DMATCR ((unsigned long[]){SH_DMAC_BASE + 0x08, SH_DMAC_BASE + 0x18, \
- SH_DMAC_BASE + 0x28, SH_DMAC_BASE + 0x38, \
- SH_DMAC_BASE + 0x58, SH_DMAC_BASE + 0x68})
-#define CHCR ((unsigned long[]){SH_DMAC_BASE + 0x0c, SH_DMAC_BASE + 0x1c, \
- SH_DMAC_BASE + 0x2c, SH_DMAC_BASE + 0x3c, \
- SH_DMAC_BASE + 0x5c, SH_DMAC_BASE + 0x6c})
-
-#define DMAOR (SH_DMAC_BASE + 0x40)
-
-#endif /* __DMA_SH_H */
-
diff --git a/arch/sh/drivers/pci/ops-sh7785lcr.c b/arch/sh/drivers/pci/ops-sh7785lcr.c
index b3bd68702059..e8b7446a7c2b 100644
--- a/arch/sh/drivers/pci/ops-sh7785lcr.c
+++ b/arch/sh/drivers/pci/ops-sh7785lcr.c
@@ -48,13 +48,8 @@ EXPORT_SYMBOL(board_pci_channels);
static struct sh4_pci_address_map sh7785_pci_map = {
.window0 = {
- .base = SH7780_CS2_BASE_ADDR,
- .size = 0x04000000,
- },
-
- .window1 = {
- .base = SH7780_CS3_BASE_ADDR,
- .size = 0x04000000,
+ .base = SH7780_CS0_BASE_ADDR,
+ .size = 0x20000000,
},
.flags = SH4_PCIC_NO_RESET,
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index 078dc44d6b08..bae6a2cf047d 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -120,19 +120,15 @@ int __init sh7780_pcic_init(struct sh4_pci_address_map *map)
/* Set IO and Mem windows to local address
* Make PCI and local address the same for easy 1 to 1 mapping
- * Window0 = map->window0.size @ non-cached area base = SDRAM
- * Window1 = map->window1.size @ cached area base = SDRAM
*/
- word = (CONFIG_MEMORY_SIZE - 0x00100000) | 0x00000001;
- pci_write_reg(word, SH4_PCILSR0);
- pci_write_reg(0x00000001, SH4_PCILSR1);
+ pci_write_reg(map->window0.size - 0xfffff, SH4_PCILSR0);
+ pci_write_reg(map->window1.size - 0xfffff, SH4_PCILSR1);
/* Set the values on window 0 PCI config registers */
- word = (CONFIG_MEMORY_SIZE > 0x08000000) ? 0x10000000 : 0x08000000;
- pci_write_reg(word | 0xa0000000, SH4_PCILAR0);
- pci_write_reg(word, SH7780_PCIMBAR0);
+ pci_write_reg(map->window0.base, SH4_PCILAR0);
+ pci_write_reg(map->window0.base, SH7780_PCIMBAR0);
/* Set the values on window 1 PCI config registers */
- pci_write_reg(0x00000000, SH4_PCILAR1);
- pci_write_reg(0x00000000, SH7780_PCIMBAR1);
+ pci_write_reg(map->window1.base, SH4_PCILAR1);
+ pci_write_reg(map->window1.base, SH7780_PCIMBAR1);
/* Map IO space into PCI IO window
* The IO window is 64K-PCIBIOS_MIN_IO in size
diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h
index 36736c7e93db..80d40813e057 100644
--- a/arch/sh/include/asm/addrspace.h
+++ b/arch/sh/include/asm/addrspace.h
@@ -31,7 +31,7 @@
/* Returns the physical address of a PnSEG (n=1,2) address */
#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff)
-#ifdef CONFIG_29BIT
+#if defined(CONFIG_29BIT) || defined(CONFIG_PMB_FIXED)
/*
* Map an address to a certain privileged segment
*/
@@ -43,7 +43,7 @@
((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P3SEG))
#define P4SEGADDR(a) \
((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | P4SEG))
-#endif /* 29BIT */
+#endif /* 29BIT || PMB_FIXED */
#endif /* P1SEG */
/* Check if an address can be reached in 29 bits */
diff --git a/arch/sh/include/asm/atomic-irq.h b/arch/sh/include/asm/atomic-irq.h
index 74f7943cff6f..a0b348068cae 100644
--- a/arch/sh/include/asm/atomic-irq.h
+++ b/arch/sh/include/asm/atomic-irq.h
@@ -11,7 +11,7 @@ static inline void atomic_add(int i, atomic_t *v)
unsigned long flags;
local_irq_save(flags);
- *(long *)v += i;
+ v->counter += i;
local_irq_restore(flags);
}
@@ -20,7 +20,7 @@ static inline void atomic_sub(int i, atomic_t *v)
unsigned long flags;
local_irq_save(flags);
- *(long *)v -= i;
+ v->counter -= i;
local_irq_restore(flags);
}
@@ -29,9 +29,9 @@ static inline int atomic_add_return(int i, atomic_t *v)
unsigned long temp, flags;
local_irq_save(flags);
- temp = *(long *)v;
+ temp = v->counter;
temp += i;
- *(long *)v = temp;
+ v->counter = temp;
local_irq_restore(flags);
return temp;
@@ -42,9 +42,9 @@ static inline int atomic_sub_return(int i, atomic_t *v)
unsigned long temp, flags;
local_irq_save(flags);
- temp = *(long *)v;
+ temp = v->counter;
temp -= i;
- *(long *)v = temp;
+ v->counter = temp;
local_irq_restore(flags);
return temp;
@@ -55,7 +55,7 @@ static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
unsigned long flags;
local_irq_save(flags);
- *(long *)v &= ~mask;
+ v->counter &= ~mask;
local_irq_restore(flags);
}
@@ -64,7 +64,7 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
unsigned long flags;
local_irq_save(flags);
- *(long *)v |= mask;
+ v->counter |= mask;
local_irq_restore(flags);
}
diff --git a/arch/sh/include/asm/bitops-llsc.h b/arch/sh/include/asm/bitops-llsc.h
index 1d2fc0b010ad..d8328be06191 100644
--- a/arch/sh/include/asm/bitops-llsc.h
+++ b/arch/sh/include/asm/bitops-llsc.h
@@ -1,7 +1,7 @@
#ifndef __ASM_SH_BITOPS_LLSC_H
#define __ASM_SH_BITOPS_LLSC_H
-static inline void set_bit(int nr, volatile void * addr)
+static inline void set_bit(int nr, volatile void *addr)
{
int mask;
volatile unsigned int *a = addr;
@@ -13,16 +13,16 @@ static inline void set_bit(int nr, volatile void * addr)
__asm__ __volatile__ (
"1: \n\t"
"movli.l @%1, %0 ! set_bit \n\t"
- "or %3, %0 \n\t"
+ "or %2, %0 \n\t"
"movco.l %0, @%1 \n\t"
"bf 1b \n\t"
- : "=&z" (tmp), "=r" (a)
- : "1" (a), "r" (mask)
+ : "=&z" (tmp)
+ : "r" (a), "r" (mask)
: "t", "memory"
);
}
-static inline void clear_bit(int nr, volatile void * addr)
+static inline void clear_bit(int nr, volatile void *addr)
{
int mask;
volatile unsigned int *a = addr;
@@ -34,16 +34,16 @@ static inline void clear_bit(int nr, volatile void * addr)
__asm__ __volatile__ (
"1: \n\t"
"movli.l @%1, %0 ! clear_bit \n\t"
- "and %3, %0 \n\t"
+ "and %2, %0 \n\t"
"movco.l %0, @%1 \n\t"
"bf 1b \n\t"
- : "=&z" (tmp), "=r" (a)
- : "1" (a), "r" (~mask)
+ : "=&z" (tmp)
+ : "r" (a), "r" (~mask)
: "t", "memory"
);
}
-static inline void change_bit(int nr, volatile void * addr)
+static inline void change_bit(int nr, volatile void *addr)
{
int mask;
volatile unsigned int *a = addr;
@@ -55,16 +55,16 @@ static inline void change_bit(int nr, volatile void * addr)
__asm__ __volatile__ (
"1: \n\t"
"movli.l @%1, %0 ! change_bit \n\t"
- "xor %3, %0 \n\t"
+ "xor %2, %0 \n\t"
"movco.l %0, @%1 \n\t"
"bf 1b \n\t"
- : "=&z" (tmp), "=r" (a)
- : "1" (a), "r" (mask)
+ : "=&z" (tmp)
+ : "r" (a), "r" (mask)
: "t", "memory"
);
}
-static inline int test_and_set_bit(int nr, volatile void * addr)
+static inline int test_and_set_bit(int nr, volatile void *addr)
{
int mask, retval;
volatile unsigned int *a = addr;
@@ -75,21 +75,21 @@ static inline int test_and_set_bit(int nr, volatile void * addr)
__asm__ __volatile__ (
"1: \n\t"
- "movli.l @%1, %0 ! test_and_set_bit \n\t"
- "mov %0, %2 \n\t"
- "or %4, %0 \n\t"
- "movco.l %0, @%1 \n\t"
+ "movli.l @%2, %0 ! test_and_set_bit \n\t"
+ "mov %0, %1 \n\t"
+ "or %3, %0 \n\t"
+ "movco.l %0, @%2 \n\t"
"bf 1b \n\t"
- "and %4, %2 \n\t"
- : "=&z" (tmp), "=r" (a), "=&r" (retval)
- : "1" (a), "r" (mask)
+ "and %3, %1 \n\t"
+ : "=&z" (tmp), "=&r" (retval)
+ : "r" (a), "r" (mask)
: "t", "memory"
);
return retval != 0;
}
-static inline int test_and_clear_bit(int nr, volatile void * addr)
+static inline int test_and_clear_bit(int nr, volatile void *addr)
{
int mask, retval;
volatile unsigned int *a = addr;
@@ -100,22 +100,22 @@ static inline int test_and_clear_bit(int nr, volatile void * addr)
__asm__ __volatile__ (
"1: \n\t"
- "movli.l @%1, %0 ! test_and_clear_bit \n\t"
- "mov %0, %2 \n\t"
- "and %5, %0 \n\t"
- "movco.l %0, @%1 \n\t"
+ "movli.l @%2, %0 ! test_and_clear_bit \n\t"
+ "mov %0, %1 \n\t"
+ "and %4, %0 \n\t"
+ "movco.l %0, @%2 \n\t"
"bf 1b \n\t"
- "and %4, %2 \n\t"
+ "and %3, %1 \n\t"
"synco \n\t"
- : "=&z" (tmp), "=r" (a), "=&r" (retval)
- : "1" (a), "r" (mask), "r" (~mask)
+ : "=&z" (tmp), "=&r" (retval)
+ : "r" (a), "r" (mask), "r" (~mask)
: "t", "memory"
);
return retval != 0;
}
-static inline int test_and_change_bit(int nr, volatile void * addr)
+static inline int test_and_change_bit(int nr, volatile void *addr)
{
int mask, retval;
volatile unsigned int *a = addr;
@@ -126,15 +126,15 @@ static inline int test_and_change_bit(int nr, volatile void * addr)
__asm__ __volatile__ (
"1: \n\t"
- "movli.l @%1, %0 ! test_and_change_bit \n\t"
- "mov %0, %2 \n\t"
- "xor %4, %0 \n\t"
- "movco.l %0, @%1 \n\t"
+ "movli.l @%2, %0 ! test_and_change_bit \n\t"
+ "mov %0, %1 \n\t"
+ "xor %3, %0 \n\t"
+ "movco.l %0, @%2 \n\t"
"bf 1b \n\t"
- "and %4, %2 \n\t"
+ "and %3, %1 \n\t"
"synco \n\t"
- : "=&z" (tmp), "=r" (a), "=&r" (retval)
- : "1" (a), "r" (mask)
+ : "=&z" (tmp), "=&r" (retval)
+ : "r" (a), "r" (mask)
: "t", "memory"
);
diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h
index f9c88583d90a..2f6c9627bc1f 100644
--- a/arch/sh/include/asm/clock.h
+++ b/arch/sh/include/asm/clock.h
@@ -15,6 +15,7 @@ struct clk_ops {
void (*disable)(struct clk *clk);
void (*recalc)(struct clk *clk);
int (*set_rate)(struct clk *clk, unsigned long rate, int algo_id);
+ int (*set_parent)(struct clk *clk, struct clk *parent);
long (*round_rate)(struct clk *clk, unsigned long rate);
};
diff --git a/arch/sh/include/asm/cmpxchg-llsc.h b/arch/sh/include/asm/cmpxchg-llsc.h
index aee3bf286581..0fac3da536ca 100644
--- a/arch/sh/include/asm/cmpxchg-llsc.h
+++ b/arch/sh/include/asm/cmpxchg-llsc.h
@@ -8,14 +8,14 @@ static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val)
__asm__ __volatile__ (
"1: \n\t"
- "movli.l @%1, %0 ! xchg_u32 \n\t"
- "mov %0, %2 \n\t"
- "mov %4, %0 \n\t"
- "movco.l %0, @%1 \n\t"
+ "movli.l @%2, %0 ! xchg_u32 \n\t"
+ "mov %0, %1 \n\t"
+ "mov %3, %0 \n\t"
+ "movco.l %0, @%2 \n\t"
"bf 1b \n\t"
"synco \n\t"
- : "=&z"(tmp), "=r" (m), "=&r" (retval)
- : "1" (m), "r" (val)
+ : "=&z"(tmp), "=&r" (retval)
+ : "r" (m), "r" (val)
: "t", "memory"
);
@@ -29,14 +29,14 @@ static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
__asm__ __volatile__ (
"1: \n\t"
- "movli.l @%1, %0 ! xchg_u8 \n\t"
- "mov %0, %2 \n\t"
- "mov %4, %0 \n\t"
- "movco.l %0, @%1 \n\t"
+ "movli.l @%2, %0 ! xchg_u8 \n\t"
+ "mov %0, %1 \n\t"
+ "mov %3, %0 \n\t"
+ "movco.l %0, @%2 \n\t"
"bf 1b \n\t"
"synco \n\t"
- : "=&z"(tmp), "=r" (m), "=&r" (retval)
- : "1" (m), "r" (val & 0xff)
+ : "=&z"(tmp), "=&r" (retval)
+ : "r" (m), "r" (val & 0xff)
: "t", "memory"
);
@@ -51,17 +51,17 @@ __cmpxchg_u32(volatile int *m, unsigned long old, unsigned long new)
__asm__ __volatile__ (
"1: \n\t"
- "movli.l @%1, %0 ! __cmpxchg_u32 \n\t"
- "mov %0, %2 \n\t"
- "cmp/eq %2, %4 \n\t"
+ "movli.l @%2, %0 ! __cmpxchg_u32 \n\t"
+ "mov %0, %1 \n\t"
+ "cmp/eq %1, %3 \n\t"
"bf 2f \n\t"
- "mov %5, %0 \n\t"
+ "mov %3, %0 \n\t"
"2: \n\t"
- "movco.l %0, @%1 \n\t"
+ "movco.l %0, @%2 \n\t"
"bf 1b \n\t"
"synco \n\t"
- : "=&z" (tmp), "=r" (m), "=&r" (retval)
- : "1" (m), "r" (old), "r" (new)
+ : "=&z" (tmp), "=&r" (retval)
+ : "r" (m), "r" (old), "r" (new)
: "t", "memory"
);
diff --git a/arch/sh/include/asm/cpu-features.h b/arch/sh/include/asm/cpu-features.h
index 86308aa39731..694abe490edb 100644
--- a/arch/sh/include/asm/cpu-features.h
+++ b/arch/sh/include/asm/cpu-features.h
@@ -21,5 +21,6 @@
#define CPU_HAS_LLSC 0x0040 /* movli.l/movco.l */
#define CPU_HAS_L2_CACHE 0x0080 /* Secondary cache / URAM */
#define CPU_HAS_OP32 0x0100 /* 32-bit instruction support */
+#define CPU_HAS_PTEAEX 0x0200 /* PTE ASID Extension support */
#endif /* __ASM_SH_CPU_FEATURES_H */
diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h
new file mode 100644
index 000000000000..0c8f8e14622a
--- /dev/null
+++ b/arch/sh/include/asm/dma-sh.h
@@ -0,0 +1,118 @@
+/*
+ * arch/sh/include/asm/dma-sh.h
+ *
+ * Copyright (C) 2000 Takashi YOSHII
+ * Copyright (C) 2003 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __DMA_SH_H
+#define __DMA_SH_H
+
+#include <asm/dma.h>
+#include <cpu/dma.h>
+
+/* DMAOR contorl: The DMAOR access size is different by CPU.*/
+#if defined(CONFIG_CPU_SUBTYPE_SH7723) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7785)
+#define dmaor_read_reg(n) \
+ (n ? ctrl_inw(SH_DMAC_BASE1 + DMAOR) \
+ : ctrl_inw(SH_DMAC_BASE0 + DMAOR))
+#define dmaor_write_reg(n, data) \
+ (n ? ctrl_outw(data, SH_DMAC_BASE1 + DMAOR) \
+ : ctrl_outw(data, SH_DMAC_BASE0 + DMAOR))
+#else /* Other CPU */
+#define dmaor_read_reg(n) ctrl_inw(SH_DMAC_BASE0 + DMAOR)
+#define dmaor_write_reg(n, data) ctrl_outw(data, SH_DMAC_BASE0 + DMAOR)
+#endif
+
+static int dmte_irq_map[] __maybe_unused = {
+#if (MAX_DMA_CHANNELS >= 4)
+ DMTE0_IRQ,
+ DMTE0_IRQ + 1,
+ DMTE0_IRQ + 2,
+ DMTE0_IRQ + 3,
+#endif
+#if (MAX_DMA_CHANNELS >= 6)
+ DMTE4_IRQ,
+ DMTE4_IRQ + 1,
+#endif
+#if (MAX_DMA_CHANNELS >= 8)
+ DMTE6_IRQ,
+ DMTE6_IRQ + 1,
+#endif
+#if (MAX_DMA_CHANNELS >= 12)
+ DMTE8_IRQ,
+ DMTE9_IRQ,
+ DMTE10_IRQ,
+ DMTE11_IRQ,
+#endif
+};
+
+/* Definitions for the SuperH DMAC */
+#define REQ_L 0x00000000
+#define REQ_E 0x00080000
+#define RACK_H 0x00000000
+#define RACK_L 0x00040000
+#define ACK_R 0x00000000
+#define ACK_W 0x00020000
+#define ACK_H 0x00000000
+#define ACK_L 0x00010000
+#define DM_INC 0x00004000
+#define DM_DEC 0x00008000
+#define SM_INC 0x00001000
+#define SM_DEC 0x00002000
+#define RS_IN 0x00000200
+#define RS_OUT 0x00000300
+#define TS_BLK 0x00000040
+#define TM_BUR 0x00000020
+#define CHCR_DE 0x00000001
+#define CHCR_TE 0x00000002
+#define CHCR_IE 0x00000004
+
+/* DMAOR definitions */
+#define DMAOR_AE 0x00000004
+#define DMAOR_NMIF 0x00000002
+#define DMAOR_DME 0x00000001
+
+/*
+ * Define the default configuration for dual address memory-memory transfer.
+ * The 0x400 value represents auto-request, external->external.
+ */
+#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_32)
+
+/* DMA base address */
+static u32 dma_base_addr[] __maybe_unused = {
+#if (MAX_DMA_CHANNELS >= 4)
+ SH_DMAC_BASE0 + 0x00, /* channel 0 */
+ SH_DMAC_BASE0 + 0x10,
+ SH_DMAC_BASE0 + 0x20,
+ SH_DMAC_BASE0 + 0x30,
+#endif
+#if (MAX_DMA_CHANNELS >= 6)
+ SH_DMAC_BASE0 + 0x50,
+ SH_DMAC_BASE0 + 0x60,
+#endif
+#if (MAX_DMA_CHANNELS >= 8)
+ SH_DMAC_BASE1 + 0x00,
+ SH_DMAC_BASE1 + 0x10,
+#endif
+#if (MAX_DMA_CHANNELS >= 12)
+ SH_DMAC_BASE1 + 0x20,
+ SH_DMAC_BASE1 + 0x30,
+ SH_DMAC_BASE1 + 0x50,
+ SH_DMAC_BASE1 + 0x60, /* channel 11 */
+#endif
+};
+
+/* DMA register */
+#define SAR 0x00
+#define DAR 0x04
+#define TCR 0x08
+#define CHCR 0x0C
+#define DMAOR 0x40
+
+#endif /* __DMA_SH_H */
diff --git a/arch/sh/include/asm/dma.h b/arch/sh/include/asm/dma.h
index beca7128e2ab..6bd178473878 100644
--- a/arch/sh/include/asm/dma.h
+++ b/arch/sh/include/asm/dma.h
@@ -25,9 +25,9 @@
#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x10000000)
#ifdef CONFIG_NR_DMA_CHANNELS
-# define MAX_DMA_CHANNELS (CONFIG_NR_DMA_CHANNELS)
+# define MAX_DMA_CHANNELS (CONFIG_NR_DMA_CHANNELS)
#else
-# define MAX_DMA_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS)
+# define MAX_DMA_CHANNELS (CONFIG_NR_ONCHIP_DMA_CHANNELS)
#endif
/*
diff --git a/arch/sh/include/asm/entry-macros.S b/arch/sh/include/asm/entry-macros.S
index 2dab0b8d9454..3a4752a65722 100644
--- a/arch/sh/include/asm/entry-macros.S
+++ b/arch/sh/include/asm/entry-macros.S
@@ -31,3 +31,8 @@
#endif
.endm
+#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
+# define PREF(x) pref @x
+#else
+# define PREF(x) nop
+#endif
diff --git a/arch/sh/include/asm/gpio.h b/arch/sh/include/asm/gpio.h
index 90673658eb14..61f93da2c62e 100644
--- a/arch/sh/include/asm/gpio.h
+++ b/arch/sh/include/asm/gpio.h
@@ -19,8 +19,42 @@
#include <cpu/gpio.h>
#endif
+#define ARCH_NR_GPIOS 512
+#include <asm-generic/gpio.h>
+
+#ifdef CONFIG_GPIOLIB
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ __gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+ return __gpio_cansleep(gpio);
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+ WARN_ON(1);
+ return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+ WARN_ON(1);
+ return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
typedef unsigned short pinmux_enum_t;
-typedef unsigned char pinmux_flag_t;
+typedef unsigned short pinmux_flag_t;
#define PINMUX_TYPE_NONE 0
#define PINMUX_TYPE_FUNCTION 1
@@ -34,6 +68,11 @@ typedef unsigned char pinmux_flag_t;
#define PINMUX_FLAG_WANT_PULLUP (1 << 3)
#define PINMUX_FLAG_WANT_PULLDOWN (1 << 4)
+#define PINMUX_FLAG_DBIT_SHIFT 5
+#define PINMUX_FLAG_DBIT (0x1f << PINMUX_FLAG_DBIT_SHIFT)
+#define PINMUX_FLAG_DREG_SHIFT 10
+#define PINMUX_FLAG_DREG (0x3f << PINMUX_FLAG_DREG_SHIFT)
+
struct pinmux_gpio {
pinmux_enum_t enum_id;
pinmux_flag_t flags;
@@ -54,7 +93,7 @@ struct pinmux_cfg_reg {
.enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) \
struct pinmux_data_reg {
- unsigned long reg, reg_width;
+ unsigned long reg, reg_width, reg_shadow;
pinmux_enum_t *enum_ids;
};
@@ -89,34 +128,9 @@ struct pinmux_info {
unsigned int gpio_data_size;
unsigned long *gpio_in_use;
+ struct gpio_chip chip;
};
int register_pinmux(struct pinmux_info *pip);
-int __gpio_request(unsigned gpio);
-static inline int gpio_request(unsigned gpio, const char *label)
-{
- return __gpio_request(gpio);
-}
-void gpio_free(unsigned gpio);
-int gpio_direction_input(unsigned gpio);
-int gpio_direction_output(unsigned gpio, int value);
-int gpio_get_value(unsigned gpio);
-void gpio_set_value(unsigned gpio, int value);
-
-/* IRQ modes are unspported */
-static inline int gpio_to_irq(unsigned gpio)
-{
- WARN_ON(1);
- return -EINVAL;
-}
-
-static inline int irq_to_gpio(unsigned irq)
-{
- WARN_ON(1);
- return -EINVAL;
-}
-
-#include <asm-generic/gpio.h>
-
#endif /* __ASM_SH_GPIO_H */
diff --git a/arch/sh/include/asm/hd64461.h b/arch/sh/include/asm/hd64461.h
index 8c1353baf00f..52b4b6238277 100644
--- a/arch/sh/include/asm/hd64461.h
+++ b/arch/sh/include/asm/hd64461.h
@@ -242,7 +242,6 @@
#include <asm/io_generic.h>
/* arch/sh/cchips/hd6446x/hd64461/setup.c */
-int hd64461_irq_demux(int irq);
void hd64461_register_irq_demux(int irq,
int (*demux) (int irq, void *dev), void *dev);
void hd64461_unregister_irq_demux(int irq);
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 61f6dae40534..0454f8d68059 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -238,7 +238,7 @@ extern void onchip_unmap(unsigned long vaddr);
static inline void __iomem *
__ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
{
-#ifdef CONFIG_SUPERH32
+#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED)
unsigned long last_addr = offset + size - 1;
#endif
void __iomem *ret;
@@ -247,7 +247,7 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
if (ret)
return ret;
-#ifdef CONFIG_SUPERH32
+#if defined(CONFIG_SUPERH32) && !defined(CONFIG_PMB_FIXED)
/*
* For P1 and P2 space this is trivial, as everything is already
* mapped. Uncached access for P1 addresses are done through P2.
diff --git a/arch/sh/include/asm/kprobes.h b/arch/sh/include/asm/kprobes.h
index 6078d8e551d4..613644a758e8 100644
--- a/arch/sh/include/asm/kprobes.h
+++ b/arch/sh/include/asm/kprobes.h
@@ -16,7 +16,7 @@ typedef u16 kprobe_opcode_t;
? (MAX_STACK_SIZE) \
: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
-#define regs_return_value(regs) ((regs)->regs[0])
+#define regs_return_value(_regs) ((_regs)->regs[0])
#define flush_insn_slot(p) do { } while (0)
#define kretprobe_blacklist_size 0
diff --git a/arch/sh/include/asm/mmu.h b/arch/sh/include/asm/mmu.h
index 6c43625bb1a5..f5963037c9d6 100644
--- a/arch/sh/include/asm/mmu.h
+++ b/arch/sh/include/asm/mmu.h
@@ -1,22 +1,6 @@
#ifndef __MMU_H
#define __MMU_H
-/* Default "unsigned long" context */
-typedef unsigned long mm_context_id_t[NR_CPUS];
-
-typedef struct {
-#ifdef CONFIG_MMU
- mm_context_id_t id;
- void *vdso;
-#else
- unsigned long end_brk;
-#endif
-#ifdef CONFIG_BINFMT_ELF_FDPIC
- unsigned long exec_fdpic_loadmap;
- unsigned long interp_fdpic_loadmap;
-#endif
-} mm_context_t;
-
/*
* Privileged Space Mapping Buffer (PMB) definitions
*/
@@ -41,6 +25,24 @@ typedef struct {
#define PMB_NO_ENTRY (-1)
+#ifndef __ASSEMBLY__
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_id_t[NR_CPUS];
+
+typedef struct {
+#ifdef CONFIG_MMU
+ mm_context_id_t id;
+ void *vdso;
+#else
+ unsigned long end_brk;
+#endif
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+ unsigned long exec_fdpic_loadmap;
+ unsigned long interp_fdpic_loadmap;
+#endif
+} mm_context_t;
+
struct pmb_entry;
struct pmb_entry {
@@ -70,6 +72,7 @@ void pmb_free(struct pmb_entry *pmbe);
long pmb_remap(unsigned long virt, unsigned long phys,
unsigned long size, unsigned long flags);
void pmb_unmap(unsigned long addr);
+#endif /* __ASSEMBLY__ */
#endif /* __MMU_H */
diff --git a/arch/sh/include/asm/mmu_context.h b/arch/sh/include/asm/mmu_context.h
index 5d9157bd474d..2a9c55f1a83f 100644
--- a/arch/sh/include/asm/mmu_context.h
+++ b/arch/sh/include/asm/mmu_context.h
@@ -19,13 +19,18 @@
* (a) TLB cache version (or round, cycle whatever expression you like)
* (b) ASID (Address Space IDentifier)
*/
+#ifdef CONFIG_CPU_HAS_PTEAEX
+#define MMU_CONTEXT_ASID_MASK 0x0000ffff
+#else
#define MMU_CONTEXT_ASID_MASK 0x000000ff
-#define MMU_CONTEXT_VERSION_MASK 0xffffff00
-#define MMU_CONTEXT_FIRST_VERSION 0x00000100
-#define NO_CONTEXT 0UL
+#endif
-/* ASID is 8-bit value, so it can't be 0x100 */
-#define MMU_NO_ASID 0x100
+#define MMU_CONTEXT_VERSION_MASK (~0UL & ~MMU_CONTEXT_ASID_MASK)
+#define MMU_CONTEXT_FIRST_VERSION (MMU_CONTEXT_ASID_MASK + 1)
+
+/* Impossible ASID value, to differentiate from NO_CONTEXT. */
+#define MMU_NO_ASID MMU_CONTEXT_FIRST_VERSION
+#define NO_CONTEXT 0UL
#define asid_cache(cpu) (cpu_data[cpu].asid_cache)
diff --git a/arch/sh/include/asm/mmu_context_32.h b/arch/sh/include/asm/mmu_context_32.h
index f4f9aebd68b7..8ef800c549ab 100644
--- a/arch/sh/include/asm/mmu_context_32.h
+++ b/arch/sh/include/asm/mmu_context_32.h
@@ -10,6 +10,17 @@ static inline void destroy_context(struct mm_struct *mm)
/* Do nothing */
}
+#ifdef CONFIG_CPU_HAS_PTEAEX
+static inline void set_asid(unsigned long asid)
+{
+ __raw_writel(asid, MMU_PTEAEX);
+}
+
+static inline unsigned long get_asid(void)
+{
+ return __raw_readl(MMU_PTEAEX) & MMU_CONTEXT_ASID_MASK;
+}
+#else
static inline void set_asid(unsigned long asid)
{
unsigned long __dummy;
@@ -33,6 +44,7 @@ static inline unsigned long get_asid(void)
asid &= MMU_CONTEXT_ASID_MASK;
return asid;
}
+#endif /* CONFIG_CPU_HAS_PTEAEX */
/* MMU_TTB is used for optimizing the fault handling. */
static inline void set_TTB(pgd_t *pgd)
diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h
index 5871d78e47e5..9c6d21ec0240 100644
--- a/arch/sh/include/asm/page.h
+++ b/arch/sh/include/asm/page.h
@@ -129,7 +129,12 @@ typedef struct page *pgtable_t;
* is not visible (it is part of the PMB mapping) and so needs to be
* added or subtracted as required.
*/
-#ifdef CONFIG_32BIT
+#if defined(CONFIG_PMB_FIXED)
+/* phys = virt - PAGE_OFFSET - (__MEMORY_START & 0xe0000000) */
+#define PMB_OFFSET (PAGE_OFFSET - PXSEG(__MEMORY_START))
+#define __pa(x) ((unsigned long)(x) - PMB_OFFSET)
+#define __va(x) ((void *)((unsigned long)(x) + PMB_OFFSET))
+#elif defined(CONFIG_32BIT)
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET+__MEMORY_START)
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET-__MEMORY_START))
#else
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index 1ef4b24d7619..1fd58b421438 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -31,7 +31,7 @@ enum cpu_type {
CPU_SH7760, CPU_SH4_202, CPU_SH4_501,
/* SH-4A types */
- CPU_SH7763, CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785,
+ CPU_SH7763, CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SH7786,
CPU_SH7723, CPU_SHX3,
/* SH4AL-DSP types */
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h
index d79063c5eb9c..9a8714945dc9 100644
--- a/arch/sh/include/asm/processor_32.h
+++ b/arch/sh/include/asm/processor_32.h
@@ -58,6 +58,14 @@ asmlinkage void __init sh_cpu_init(void);
#define SR_FD 0x00008000
/*
+ * DSP structure and data
+ */
+struct sh_dsp_struct {
+ unsigned long dsp_regs[14];
+ long status;
+};
+
+/*
* FPU structure and data
*/
@@ -96,6 +104,11 @@ struct thread_struct {
/* floating point info */
union sh_fpu_union fpu;
+
+#ifdef CONFIG_SH_DSP
+ /* Dsp status information */
+ struct sh_dsp_struct dsp_status;
+#endif
};
/* Count of active tasks with UBC settings */
@@ -108,12 +121,12 @@ extern int ubc_usercnt;
/*
* Do necessary setup to start up a newly executed thread.
*/
-#define start_thread(regs, new_pc, new_sp) \
+#define start_thread(_regs, new_pc, new_sp) \
set_fs(USER_DS); \
- regs->pr = 0; \
- regs->sr = SR_FD; /* User mode. */ \
- regs->pc = new_pc; \
- regs->regs[15] = new_sp
+ _regs->pr = 0; \
+ _regs->sr = SR_FD; /* User mode. */ \
+ _regs->pc = new_pc; \
+ _regs->regs[15] = new_sp
/* Forward declaration, a strange C thing */
struct task_struct;
@@ -189,10 +202,9 @@ extern unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[15])
-#define user_stack_pointer(regs) ((regs)->regs[15])
+#define user_stack_pointer(_regs) ((_regs)->regs[15])
-#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH3) || \
- defined(CONFIG_CPU_SH4)
+#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
#define PREFETCH_STRIDE L1_CACHE_BYTES
#define ARCH_HAS_PREFETCH
#define ARCH_HAS_PREFETCHW
diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h
index 803177fcf086..5727d31b0ccf 100644
--- a/arch/sh/include/asm/processor_64.h
+++ b/arch/sh/include/asm/processor_64.h
@@ -145,13 +145,13 @@ struct thread_struct {
*/
#define SR_USER (SR_MMU | SR_FD)
-#define start_thread(regs, new_pc, new_sp) \
+#define start_thread(_regs, new_pc, new_sp) \
set_fs(USER_DS); \
- regs->sr = SR_USER; /* User mode. */ \
- regs->pc = new_pc - 4; /* Compensate syscall exit */ \
- regs->pc |= 1; /* Set SHmedia ! */ \
- regs->regs[18] = 0; \
- regs->regs[15] = new_sp
+ _regs->sr = SR_USER; /* User mode. */ \
+ _regs->pc = new_pc - 4; /* Compensate syscall exit */ \
+ _regs->pc |= 1; /* Set SHmedia ! */ \
+ _regs->regs[18] = 0; \
+ _regs->regs[15] = new_sp
/* Forward declaration, a strange C thing */
struct task_struct;
@@ -226,7 +226,7 @@ extern unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) ((tsk)->thread.pc)
#define KSTK_ESP(tsk) ((tsk)->thread.sp)
-#define user_stack_pointer(regs) ((regs)->regs[15])
+#define user_stack_pointer(_regs) ((_regs)->regs[15])
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SH_PROCESSOR_64_H */
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index 12912ab80c15..d3f6caa936b0 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -119,18 +119,8 @@ struct task_struct;
extern void user_enable_single_step(struct task_struct *);
extern void user_disable_single_step(struct task_struct *);
-#ifdef CONFIG_SH_DSP
#define task_pt_regs(task) \
- ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \
- - sizeof(struct pt_dspregs) - sizeof(unsigned long)) - 1)
-#define task_pt_dspregs(task) \
- ((struct pt_dspregs *) (task_stack_page(task) + THREAD_SIZE \
- - sizeof(unsigned long)) - 1)
-#else
-#define task_pt_regs(task) \
- ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \
- - sizeof(unsigned long)) - 1)
-#endif
+ ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE) - 1)
static inline unsigned long profile_pc(struct pt_regs *regs)
{
diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h
index 8f8f4ad400df..01a4076a3719 100644
--- a/arch/sh/include/asm/sections.h
+++ b/arch/sh/include/asm/sections.h
@@ -3,6 +3,7 @@
#include <asm-generic/sections.h>
+extern void __nosave_begin, __nosave_end;
extern long __machvec_start, __machvec_end;
extern char __uncached_start, __uncached_end;
extern char _ebss[];
diff --git a/arch/sh/include/asm/socket.h b/arch/sh/include/asm/socket.h
index 6d4bf6512959..345653b96826 100644
--- a/arch/sh/include/asm/socket.h
+++ b/arch/sh/include/asm/socket.h
@@ -54,4 +54,7 @@
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
#endif /* __ASM_SH_SOCKET_H */
diff --git a/arch/sh/include/asm/spinlock.h b/arch/sh/include/asm/spinlock.h
index e793181d64da..60283565f89b 100644
--- a/arch/sh/include/asm/spinlock.h
+++ b/arch/sh/include/asm/spinlock.h
@@ -216,6 +216,9 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
return (oldval > (RW_LOCK_BIAS - 1));
}
+#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
+#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+
#define _raw_spin_relax(lock) cpu_relax()
#define _raw_read_relax(lock) cpu_relax()
#define _raw_write_relax(lock) cpu_relax()
diff --git a/arch/sh/include/asm/suspend.h b/arch/sh/include/asm/suspend.h
new file mode 100644
index 000000000000..b1b995370e79
--- /dev/null
+++ b/arch/sh/include/asm/suspend.h
@@ -0,0 +1,22 @@
+#ifndef _ASM_SH_SUSPEND_H
+#define _ASM_SH_SUSPEND_H
+
+#ifndef __ASSEMBLY__
+static inline int arch_prepare_suspend(void) { return 0; }
+
+#include <asm/ptrace.h>
+
+struct swsusp_arch_regs {
+ struct pt_regs user_regs;
+ unsigned long bank1_regs[8];
+};
+#endif
+
+/* flags passed to assembly suspend code */
+#define SUSP_SH_SLEEP (1 << 0) /* Regular sleep mode */
+#define SUSP_SH_STANDBY (1 << 1) /* SH-Mobile Software standby mode */
+#define SUSP_SH_RSTANDBY (1 << 2) /* SH-Mobile R-standby mode */
+#define SUSP_SH_USTANDBY (1 << 3) /* SH-Mobile U-standby mode */
+#define SUSP_SH_SF (1 << 4) /* Enable self-refresh */
+
+#endif /* _ASM_SH_SUSPEND_H */
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index c9ec6af8e745..a88895e6dcb0 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -153,6 +153,7 @@ extern unsigned long cached_to_uncached;
extern struct dentry *sh_debugfs_root;
void per_cpu_trap_init(void);
+void default_idle(void);
asmlinkage void break_point_trap(void);
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h
index a726d5d07277..240b31e1142c 100644
--- a/arch/sh/include/asm/system_32.h
+++ b/arch/sh/include/asm/system_32.h
@@ -3,59 +3,135 @@
#include <linux/types.h>
+#ifdef CONFIG_SH_DSP
+
+#define is_dsp_enabled(tsk) \
+ (!!(tsk->thread.dsp_status.status & SR_DSP))
+
+#define __restore_dsp(tsk) \
+do { \
+ register u32 *__ts2 __asm__ ("r2") = \
+ (u32 *)&tsk->thread.dsp_status; \
+ __asm__ __volatile__ ( \
+ ".balign 4\n\t" \
+ "movs.l @r2+, a1\n\t" \
+ "movs.l @r2+, a0g\n\t" \
+ "movs.l @r2+, a1g\n\t" \
+ "movs.l @r2+, m0\n\t" \
+ "movs.l @r2+, m1\n\t" \
+ "movs.l @r2+, a0\n\t" \
+ "movs.l @r2+, x0\n\t" \
+ "movs.l @r2+, x1\n\t" \
+ "movs.l @r2+, y0\n\t" \
+ "movs.l @r2+, y1\n\t" \
+ "lds.l @r2+, dsr\n\t" \
+ "ldc.l @r2+, rs\n\t" \
+ "ldc.l @r2+, re\n\t" \
+ "ldc.l @r2+, mod\n\t" \
+ : : "r" (__ts2)); \
+} while (0)
+
+
+#define __save_dsp(tsk) \
+do { \
+ register u32 *__ts2 __asm__ ("r2") = \
+ (u32 *)&tsk->thread.dsp_status + 14; \
+ \
+ __asm__ __volatile__ ( \
+ ".balign 4\n\t" \
+ "stc.l mod, @-r2\n\t" \
+ "stc.l re, @-r2\n\t" \
+ "stc.l rs, @-r2\n\t" \
+ "sts.l dsr, @-r2\n\t" \
+ "sts.l y1, @-r2\n\t" \
+ "sts.l y0, @-r2\n\t" \
+ "sts.l x1, @-r2\n\t" \
+ "sts.l x0, @-r2\n\t" \
+ "sts.l a0, @-r2\n\t" \
+ ".word 0xf653 ! movs.l a1, @-r2\n\t" \
+ ".word 0xf6f3 ! movs.l a0g, @-r2\n\t" \
+ ".word 0xf6d3 ! movs.l a1g, @-r2\n\t" \
+ ".word 0xf6c3 ! movs.l m0, @-r2\n\t" \
+ ".word 0xf6e3 ! movs.l m1, @-r2\n\t" \
+ : : "r" (__ts2)); \
+} while (0)
+
+#else
+
+#define is_dsp_enabled(tsk) (0)
+#define __save_dsp(tsk) do { } while (0)
+#define __restore_dsp(tsk) do { } while (0)
+#endif
+
struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *next);
/*
* switch_to() should switch tasks to task nr n, first
*/
-#define switch_to(prev, next, last) \
-do { \
- register u32 *__ts1 __asm__ ("r1") = (u32 *)&prev->thread.sp; \
- register u32 *__ts2 __asm__ ("r2") = (u32 *)&prev->thread.pc; \
- register u32 *__ts4 __asm__ ("r4") = (u32 *)prev; \
- register u32 *__ts5 __asm__ ("r5") = (u32 *)next; \
- register u32 *__ts6 __asm__ ("r6") = (u32 *)&next->thread.sp; \
- register u32 __ts7 __asm__ ("r7") = next->thread.pc; \
- struct task_struct *__last; \
- \
- __asm__ __volatile__ ( \
- ".balign 4\n\t" \
- "stc.l gbr, @-r15\n\t" \
- "sts.l pr, @-r15\n\t" \
- "mov.l r8, @-r15\n\t" \
- "mov.l r9, @-r15\n\t" \
- "mov.l r10, @-r15\n\t" \
- "mov.l r11, @-r15\n\t" \
- "mov.l r12, @-r15\n\t" \
- "mov.l r13, @-r15\n\t" \
- "mov.l r14, @-r15\n\t" \
- "mov.l r15, @r1\t! save SP\n\t" \
- "mov.l @r6, r15\t! change to new stack\n\t" \
- "mova 1f, %0\n\t" \
- "mov.l %0, @r2\t! save PC\n\t" \
- "mov.l 2f, %0\n\t" \
- "jmp @%0\t! call __switch_to\n\t" \
- " lds r7, pr\t! with return to new PC\n\t" \
- ".balign 4\n" \
- "2:\n\t" \
- ".long __switch_to\n" \
- "1:\n\t" \
- "mov.l @r15+, r14\n\t" \
- "mov.l @r15+, r13\n\t" \
- "mov.l @r15+, r12\n\t" \
- "mov.l @r15+, r11\n\t" \
- "mov.l @r15+, r10\n\t" \
- "mov.l @r15+, r9\n\t" \
- "mov.l @r15+, r8\n\t" \
- "lds.l @r15+, pr\n\t" \
- "ldc.l @r15+, gbr\n\t" \
- : "=z" (__last) \
- : "r" (__ts1), "r" (__ts2), "r" (__ts4), \
- "r" (__ts5), "r" (__ts6), "r" (__ts7) \
- : "r3", "t"); \
- \
- last = __last; \
+#define switch_to(prev, next, last) \
+do { \
+ register u32 *__ts1 __asm__ ("r1"); \
+ register u32 *__ts2 __asm__ ("r2"); \
+ register u32 *__ts4 __asm__ ("r4"); \
+ register u32 *__ts5 __asm__ ("r5"); \
+ register u32 *__ts6 __asm__ ("r6"); \
+ register u32 __ts7 __asm__ ("r7"); \
+ struct task_struct *__last; \
+ \
+ if (is_dsp_enabled(prev)) \
+ __save_dsp(prev); \
+ \
+ __ts1 = (u32 *)&prev->thread.sp; \
+ __ts2 = (u32 *)&prev->thread.pc; \
+ __ts4 = (u32 *)prev; \
+ __ts5 = (u32 *)next; \
+ __ts6 = (u32 *)&next->thread.sp; \
+ __ts7 = next->thread.pc; \
+ \
+ __asm__ __volatile__ ( \
+ ".balign 4\n\t" \
+ "stc.l gbr, @-r15\n\t" \
+ "sts.l pr, @-r15\n\t" \
+ "mov.l r8, @-r15\n\t" \
+ "mov.l r9, @-r15\n\t" \
+ "mov.l r10, @-r15\n\t" \
+ "mov.l r11, @-r15\n\t" \
+ "mov.l r12, @-r15\n\t" \
+ "mov.l r13, @-r15\n\t" \
+ "mov.l r14, @-r15\n\t" \
+ "mov.l r15, @r1\t! save SP\n\t" \
+ "mov.l @r6, r15\t! change to new stack\n\t" \
+ "mova 1f, %0\n\t" \
+ "mov.l %0, @r2\t! save PC\n\t" \
+ "mov.l 2f, %0\n\t" \
+ "jmp @%0\t! call __switch_to\n\t" \
+ " lds r7, pr\t! with return to new PC\n\t" \
+ ".balign 4\n" \
+ "2:\n\t" \
+ ".long __switch_to\n" \
+ "1:\n\t" \
+ "mov.l @r15+, r14\n\t" \
+ "mov.l @r15+, r13\n\t" \
+ "mov.l @r15+, r12\n\t" \
+ "mov.l @r15+, r11\n\t" \
+ "mov.l @r15+, r10\n\t" \
+ "mov.l @r15+, r9\n\t" \
+ "mov.l @r15+, r8\n\t" \
+ "lds.l @r15+, pr\n\t" \
+ "ldc.l @r15+, gbr\n\t" \
+ : "=z" (__last) \
+ : "r" (__ts1), "r" (__ts2), "r" (__ts4), \
+ "r" (__ts5), "r" (__ts6), "r" (__ts7) \
+ : "r3", "t"); \
+ \
+ last = __last; \
+} while (0)
+
+#define finish_arch_switch(prev) \
+do { \
+ if (is_dsp_enabled(prev)) \
+ __restore_dsp(prev); \
} while (0)
#define __uses_jump_to_uncached \
diff --git a/arch/sh/include/asm/timer.h b/arch/sh/include/asm/timer.h
index a7ca3a195bb5..4c3b66e30af2 100644
--- a/arch/sh/include/asm/timer.h
+++ b/arch/sh/include/asm/timer.h
@@ -9,7 +9,6 @@ struct sys_timer_ops {
int (*init)(void);
int (*start)(void);
int (*stop)(void);
- cycle_t (*read)(void);
#ifndef CONFIG_GENERIC_TIME
unsigned long (*get_offset)(void);
#endif
@@ -39,6 +38,7 @@ struct sys_timer *get_sys_timer(void);
/* arch/sh/kernel/time.c */
void handle_timer_tick(void);
-extern unsigned long sh_hpt_frequency;
+
+extern struct clocksource clocksource_sh;
#endif /* __ASM_SH_TIMER_H */
diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h
index 88ff1ae8a6b8..9c16f737074a 100644
--- a/arch/sh/include/asm/tlb.h
+++ b/arch/sh/include/asm/tlb.h
@@ -6,22 +6,106 @@
#endif
#ifndef __ASSEMBLY__
+#include <linux/pagemap.h>
+
+#ifdef CONFIG_MMU
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+
+/*
+ * TLB handling. This allows us to remove pages from the page
+ * tables, and efficiently handle the TLB issues.
+ */
+struct mmu_gather {
+ struct mm_struct *mm;
+ unsigned int fullmm;
+ unsigned long start, end;
+};
-#define tlb_start_vma(tlb, vma) \
- flush_cache_range(vma, vma->vm_start, vma->vm_end)
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
-#define tlb_end_vma(tlb, vma) \
- flush_tlb_range(vma, vma->vm_start, vma->vm_end)
+static inline void init_tlb_gather(struct mmu_gather *tlb)
+{
+ tlb->start = TASK_SIZE;
+ tlb->end = 0;
-#define __tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
+ if (tlb->fullmm) {
+ tlb->start = 0;
+ tlb->end = TASK_SIZE;
+ }
+}
+
+static inline struct mmu_gather *
+tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+{
+ struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
+
+ tlb->mm = mm;
+ tlb->fullmm = full_mm_flush;
+
+ init_tlb_gather(tlb);
+
+ return tlb;
+}
+
+static inline void
+tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+{
+ if (tlb->fullmm)
+ flush_tlb_mm(tlb->mm);
+
+ /* keep the page table cache within bounds */
+ check_pgt_cache();
+
+ put_cpu_var(mmu_gathers);
+}
+
+static inline void
+tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep, unsigned long address)
+{
+ if (tlb->start > address)
+ tlb->start = address;
+ if (tlb->end < address + PAGE_SIZE)
+ tlb->end = address + PAGE_SIZE;
+}
/*
- * Flush whole TLBs for MM
+ * In the case of tlb vma handling, we can optimise these away in the
+ * case where we're doing a full MM flush. When we're doing a munmap,
+ * the vmas are adjusted to only cover the region to be torn down.
*/
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+static inline void
+tlb_start_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
+{
+ if (!tlb->fullmm)
+ flush_cache_range(vma, vma->vm_start, vma->vm_end);
+}
+
+static inline void
+tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
+{
+ if (!tlb->fullmm && tlb->end) {
+ flush_tlb_range(vma, tlb->start, tlb->end);
+ init_tlb_gather(tlb);
+ }
+}
+
+#define tlb_remove_page(tlb,page) free_page_and_swap_cache(page)
+#define pte_free_tlb(tlb, ptep) pte_free((tlb)->mm, ptep)
+#define pmd_free_tlb(tlb, pmdp) pmd_free((tlb)->mm, pmdp)
+#define pud_free_tlb(tlb, pudp) pud_free((tlb)->mm, pudp)
+
+#define tlb_migrate_finish(mm) do { } while (0)
+
+#else /* CONFIG_MMU */
+
+#define tlb_start_vma(tlb, vma) do { } while (0)
+#define tlb_end_vma(tlb, vma) do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
+#define tlb_flush(tlb) do { } while (0)
-#include <linux/pagemap.h>
#include <asm-generic/tlb.h>
+#endif /* CONFIG_MMU */
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SH_TLB_H */
diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h
index 066f0fba590e..a3f239545897 100644
--- a/arch/sh/include/asm/topology.h
+++ b/arch/sh/include/asm/topology.h
@@ -33,7 +33,6 @@
#define node_to_cpumask(node) ((void)node, cpu_online_map)
#define cpumask_of_node(node) ((void)node, cpu_online_mask)
-#define node_to_first_cpu(node) ((void)(node),0)
#define pcibus_to_node(bus) ((void)(bus), -1)
#define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \
diff --git a/arch/sh/include/cpu-sh3/cpu/dma.h b/arch/sh/include/cpu-sh3/cpu/dma.h
index 6813c3220a1d..0ea15f3f2363 100644
--- a/arch/sh/include/cpu-sh3/cpu/dma.h
+++ b/arch/sh/include/cpu-sh3/cpu/dma.h
@@ -1,22 +1,17 @@
#ifndef __ASM_CPU_SH3_DMA_H
#define __ASM_CPU_SH3_DMA_H
-
#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
- defined(CONFIG_CPU_SUBTYPE_SH7721)
-#define SH_DMAC_BASE 0xa4010020
-#else
-#define SH_DMAC_BASE 0xa4000020
+ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7710) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7712)
+#define SH_DMAC_BASE0 0xa4010020
+#else /* SH7705/06/07/09 */
+#define SH_DMAC_BASE0 0xa4000020
#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7709)
#define DMTE0_IRQ 48
-#define DMTE1_IRQ 49
-#define DMTE2_IRQ 50
-#define DMTE3_IRQ 51
#define DMTE4_IRQ 76
-#define DMTE5_IRQ 77
-#endif
/* Definitions for the SuperH DMAC */
#define TM_BURST 0x00000020
diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
new file mode 100644
index 000000000000..0ed5178fed69
--- /dev/null
+++ b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
@@ -0,0 +1,94 @@
+#ifndef __ASM_SH_CPU_SH4_DMA_SH7780_H
+#define __ASM_SH_CPU_SH4_DMA_SH7780_H
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7343) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7722) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7730)
+#define DMTE0_IRQ 48
+#define DMTE4_IRQ 76
+#define DMAE0_IRQ 78 /* DMA Error IRQ*/
+#define SH_DMAC_BASE0 0xFE008020
+#define SH_DMARS_BASE 0xFE009000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7764)
+#define DMTE0_IRQ 34
+#define DMTE4_IRQ 44
+#define DMAE0_IRQ 38
+#define SH_DMAC_BASE0 0xFF608020
+#define SH_DMARS_BASE 0xFF609000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+#define DMTE0_IRQ 48 /* DMAC0A*/
+#define DMTE4_IRQ 40 /* DMAC0B */
+#define DMTE6_IRQ 42
+#define DMTE8_IRQ 76 /* DMAC1A */
+#define DMTE9_IRQ 77
+#define DMTE10_IRQ 72 /* DMAC1B */
+#define DMTE11_IRQ 73
+#define DMAE0_IRQ 78 /* DMA Error IRQ*/
+#define DMAE1_IRQ 74 /* DMA Error IRQ*/
+#define SH_DMAC_BASE0 0xFE008020
+#define SH_DMAC_BASE1 0xFDC08020
+#define SH_DMARS_BASE 0xFDC09000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+#define DMTE0_IRQ 34
+#define DMTE4_IRQ 44
+#define DMTE6_IRQ 46
+#define DMTE8_IRQ 92
+#define DMTE9_IRQ 93
+#define DMTE10_IRQ 94
+#define DMTE11_IRQ 95
+#define DMAE0_IRQ 38 /* DMA Error IRQ */
+#define SH_DMAC_BASE0 0xFC808020
+#define SH_DMAC_BASE1 0xFC818020
+#define SH_DMARS_BASE 0xFC809000
+#else /* SH7785 */
+#define DMTE0_IRQ 33
+#define DMTE4_IRQ 37
+#define DMTE6_IRQ 52
+#define DMTE8_IRQ 54
+#define DMTE9_IRQ 55
+#define DMTE10_IRQ 56
+#define DMTE11_IRQ 57
+#define DMAE0_IRQ 39 /* DMA Error IRQ0 */
+#define DMAE1_IRQ 58 /* DMA Error IRQ1 */
+#define SH_DMAC_BASE0 0xFC808020
+#define SH_DMAC_BASE1 0xFCC08020
+#define SH_DMARS_BASE 0xFC809000
+#endif
+
+#define REQ_HE 0x000000C0
+#define REQ_H 0x00000080
+#define REQ_LE 0x00000040
+#define TM_BURST 0x0000020
+#define TS_8 0x00000000
+#define TS_16 0x00000008
+#define TS_32 0x00000010
+#define TS_16BLK 0x00000018
+#define TS_32BLK 0x00100000
+
+/*
+ * The SuperH DMAC supports a number of transmit sizes, we list them here,
+ * with their respective values as they appear in the CHCR registers.
+ *
+ * Defaults to a 64-bit transfer size.
+ */
+enum {
+ XMIT_SZ_8BIT,
+ XMIT_SZ_16BIT,
+ XMIT_SZ_32BIT,
+ XMIT_SZ_128BIT,
+ XMIT_SZ_256BIT,
+};
+
+/*
+ * The DMA count is defined as the number of bytes to transfer.
+ */
+static unsigned int ts_shift[] __maybe_unused = {
+ [XMIT_SZ_8BIT] = 0,
+ [XMIT_SZ_16BIT] = 1,
+ [XMIT_SZ_32BIT] = 2,
+ [XMIT_SZ_128BIT] = 4,
+ [XMIT_SZ_256BIT] = 5,
+};
+
+#endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh7780.h b/arch/sh/include/cpu-sh4/cpu/dma-sh7780.h
deleted file mode 100644
index 71b426a6e482..000000000000
--- a/arch/sh/include/cpu-sh4/cpu/dma-sh7780.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef __ASM_SH_CPU_SH4_DMA_SH7780_H
-#define __ASM_SH_CPU_SH4_DMA_SH7780_H
-
-#define REQ_HE 0x000000C0
-#define REQ_H 0x00000080
-#define REQ_LE 0x00000040
-#define TM_BURST 0x0000020
-#define TS_8 0x00000000
-#define TS_16 0x00000008
-#define TS_32 0x00000010
-#define TS_16BLK 0x00000018
-#define TS_32BLK 0x00100000
-
-/*
- * The SuperH DMAC supports a number of transmit sizes, we list them here,
- * with their respective values as they appear in the CHCR registers.
- *
- * Defaults to a 64-bit transfer size.
- */
-enum {
- XMIT_SZ_8BIT,
- XMIT_SZ_16BIT,
- XMIT_SZ_32BIT,
- XMIT_SZ_128BIT,
- XMIT_SZ_256BIT,
-};
-
-/*
- * The DMA count is defined as the number of bytes to transfer.
- */
-static unsigned int ts_shift[] __maybe_unused = {
- [XMIT_SZ_8BIT] = 0,
- [XMIT_SZ_16BIT] = 1,
- [XMIT_SZ_32BIT] = 2,
- [XMIT_SZ_128BIT] = 4,
- [XMIT_SZ_256BIT] = 5,
-};
-
-#endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma.h b/arch/sh/include/cpu-sh4/cpu/dma.h
index 235b7cd1fc9a..bcb30246e85c 100644
--- a/arch/sh/include/cpu-sh4/cpu/dma.h
+++ b/arch/sh/include/cpu-sh4/cpu/dma.h
@@ -1,31 +1,29 @@
#ifndef __ASM_CPU_SH4_DMA_H
#define __ASM_CPU_SH4_DMA_H
-#define DMAOR_INIT ( 0x8000 | DMAOR_DME )
-
/* SH7751/7760/7780 DMA IRQ sources */
-#define DMTE0_IRQ 34
-#define DMTE1_IRQ 35
-#define DMTE2_IRQ 36
-#define DMTE3_IRQ 37
-#define DMTE4_IRQ 44
-#define DMTE5_IRQ 45
-#define DMTE6_IRQ 46
-#define DMTE7_IRQ 47
-#define DMAE_IRQ 38
#ifdef CONFIG_CPU_SH4A
-#define SH_DMAC_BASE 0xfc808020
+#define DMAOR_INIT (DMAOR_DME)
#define CHCR_TS_MASK 0x18
#define CHCR_TS_SHIFT 3
-#include <cpu/dma-sh7780.h>
-#else
-#define SH_DMAC_BASE 0xffa00000
+#include <cpu/dma-sh4a.h>
+#else /* CONFIG_CPU_SH4A */
+/*
+ * SH7750/SH7751/SH7760
+ */
+#define DMTE0_IRQ 34
+#define DMTE4_IRQ 44
+#define DMTE6_IRQ 46
+#define DMAE0_IRQ 38
+#define DMAOR_INIT (0x8000|DMAOR_DME)
+#define SH_DMAC_BASE0 0xffa00000
+#define SH_DMAC_BASE1 0xffa00070
/* Definitions for the SuperH DMAC */
-#define TM_BURST 0x0000080
+#define TM_BURST 0x00000080
#define TS_8 0x00000010
#define TS_16 0x00000020
#define TS_32 0x00000030
diff --git a/arch/sh/include/cpu-sh4/cpu/freq.h b/arch/sh/include/cpu-sh4/cpu/freq.h
index c23af81c2e70..749d1c434337 100644
--- a/arch/sh/include/cpu-sh4/cpu/freq.h
+++ b/arch/sh/include/cpu-sh4/cpu/freq.h
@@ -29,6 +29,10 @@
#define FRQCR0 0xffc80000
#define FRQCR1 0xffc80004
#define FRQMR1 0xffc80014
+#elif defined(CONFIG_CPU_SUBTYPE_SH7786)
+#define FRQCR0 0xffc40000
+#define FRQCR1 0xffc40004
+#define FRQMR1 0xffc40014
#elif defined(CONFIG_CPU_SUBTYPE_SHX3)
#define FRQCR 0xffc00014
#else
diff --git a/arch/sh/include/cpu-sh4/cpu/mmu_context.h b/arch/sh/include/cpu-sh4/cpu/mmu_context.h
index 9ea8eb27b18e..3ce7ef6c2978 100644
--- a/arch/sh/include/cpu-sh4/cpu/mmu_context.h
+++ b/arch/sh/include/cpu-sh4/cpu/mmu_context.h
@@ -14,28 +14,35 @@
#define MMU_PTEL 0xFF000004 /* Page table entry register LOW */
#define MMU_TTB 0xFF000008 /* Translation table base register */
#define MMU_TEA 0xFF00000C /* TLB Exception Address */
-#define MMU_PTEA 0xFF000034 /* Page table entry assistance register */
+#define MMU_PTEA 0xFF000034 /* PTE assistance register */
+#define MMU_PTEAEX 0xFF00007C /* PTE ASID extension register */
#define MMUCR 0xFF000010 /* MMU Control Register */
-#define MMU_ITLB_ADDRESS_ARRAY 0xF2000000
#define MMU_UTLB_ADDRESS_ARRAY 0xF6000000
+#define MMU_UTLB_ADDRESS_ARRAY2 0xF6800000
#define MMU_PAGE_ASSOC_BIT 0x80
#define MMUCR_TI (1<<2)
-#ifdef CONFIG_X2TLB
-#define MMUCR_ME (1 << 7)
-#else
-#define MMUCR_ME (0)
-#endif
-
#if defined(CONFIG_32BIT) && defined(CONFIG_CPU_SUBTYPE_ST40)
#define MMUCR_SE (1 << 4)
#else
#define MMUCR_SE (0)
#endif
+#ifdef CONFIG_CPU_HAS_PTEAEX
+#define MMUCR_AEX (1 << 6)
+#else
+#define MMUCR_AEX (0)
+#endif
+
+#ifdef CONFIG_X2TLB
+#define MMUCR_ME (1 << 7)
+#else
+#define MMUCR_ME (0)
+#endif
+
#ifdef CONFIG_SH_STORE_QUEUES
#define MMUCR_SQMD (1 << 9)
#else
@@ -43,17 +50,7 @@
#endif
#define MMU_NTLB_ENTRIES 64
-#define MMU_CONTROL_INIT (0x05|MMUCR_SQMD|MMUCR_ME|MMUCR_SE)
-
-#define MMU_ITLB_DATA_ARRAY 0xF3000000
-#define MMU_UTLB_DATA_ARRAY 0xF7000000
-
-#define MMU_UTLB_ENTRIES 64
-#define MMU_U_ENTRY_SHIFT 8
-#define MMU_UTLB_VALID 0x100
-#define MMU_ITLB_ENTRIES 4
-#define MMU_I_ENTRY_SHIFT 8
-#define MMU_ITLB_VALID 0x100
+#define MMU_CONTROL_INIT (0x05|MMUCR_SQMD|MMUCR_ME|MMUCR_SE|MMUCR_AEX)
#define TRA 0xff000020
#define EXPEVT 0xff000024
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7786.h b/arch/sh/include/cpu-sh4/cpu/sh7786.h
new file mode 100644
index 000000000000..977862f9072a
--- /dev/null
+++ b/arch/sh/include/cpu-sh4/cpu/sh7786.h
@@ -0,0 +1,136 @@
+/*
+ * SH7786 Pinmux
+ *
+ * Copyright (C) 2008, 2009 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on sh7785.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __CPU_SH7786_H__
+#define __CPU_SH7786_H__
+
+enum {
+ /* PA */
+ GPIO_PA7, GPIO_PA6, GPIO_PA5, GPIO_PA4,
+ GPIO_PA3, GPIO_PA2, GPIO_PA1, GPIO_PA0,
+
+ /* PB */
+ GPIO_PB7, GPIO_PB6, GPIO_PB5, GPIO_PB4,
+ GPIO_PB3, GPIO_PB2, GPIO_PB1, GPIO_PB0,
+
+ /* PC */
+ GPIO_PC7, GPIO_PC6, GPIO_PC5, GPIO_PC4,
+ GPIO_PC3, GPIO_PC2, GPIO_PC1, GPIO_PC0,
+
+ /* PD */
+ GPIO_PD7, GPIO_PD6, GPIO_PD5, GPIO_PD4,
+ GPIO_PD3, GPIO_PD2, GPIO_PD1, GPIO_PD0,
+
+ /* PE */
+ GPIO_PE5, GPIO_PE4, GPIO_PE3, GPIO_PE2,
+ GPIO_PE1, GPIO_PE0,
+
+ /* PF */
+ GPIO_PF7, GPIO_PF6, GPIO_PF5, GPIO_PF4,
+ GPIO_PF3, GPIO_PF2, GPIO_PF1, GPIO_PF0,
+
+ /* PG */
+ GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4,
+ GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0,
+
+ /* PH */
+ GPIO_PH7, GPIO_PH6, GPIO_PH5, GPIO_PH4,
+ GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0,
+
+ /* PJ */
+ GPIO_PJ7, GPIO_PJ6, GPIO_PJ5, GPIO_PJ4,
+ GPIO_PJ3, GPIO_PJ2, GPIO_PJ1, GPIO_PJ0,
+
+ /* DU */
+ GPIO_FN_DCLKIN, GPIO_FN_DCLKOUT, GPIO_FN_ODDF,
+ GPIO_FN_VSYNC, GPIO_FN_HSYNC, GPIO_FN_CDE, GPIO_FN_DISP,
+ GPIO_FN_DR0, GPIO_FN_DG0, GPIO_FN_DB0,
+ GPIO_FN_DR1, GPIO_FN_DG1, GPIO_FN_DB1,
+ GPIO_FN_DR2, GPIO_FN_DG2, GPIO_FN_DB2,
+ GPIO_FN_DR3, GPIO_FN_DG3, GPIO_FN_DB3,
+ GPIO_FN_DR4, GPIO_FN_DG4, GPIO_FN_DB4,
+ GPIO_FN_DR5, GPIO_FN_DG5, GPIO_FN_DB5,
+
+ /* Eth */
+ GPIO_FN_ETH_MAGIC, GPIO_FN_ETH_LINK, GPIO_FN_ETH_TX_ER,
+ GPIO_FN_ETH_TX_EN, GPIO_FN_ETH_MDIO, GPIO_FN_ETH_RX_CLK,
+ GPIO_FN_ETH_MDC, GPIO_FN_ETH_COL, GPIO_FN_ETH_TX_CLK,
+ GPIO_FN_ETH_CRS, GPIO_FN_ETH_RX_DV, GPIO_FN_ETH_RX_ER,
+ GPIO_FN_ETH_TXD3, GPIO_FN_ETH_TXD2, GPIO_FN_ETH_TXD1, GPIO_FN_ETH_TXD0,
+ GPIO_FN_ETH_RXD3, GPIO_FN_ETH_RXD2, GPIO_FN_ETH_RXD1, GPIO_FN_ETH_RXD0,
+
+ /* HSPI */
+ GPIO_FN_HSPI_CLK, GPIO_FN_HSPI_CS, GPIO_FN_HSPI_RX, GPIO_FN_HSPI_TX,
+
+ /* SCIF0 */
+ GPIO_FN_SCIF0_CTS, GPIO_FN_SCIF0_RTS, GPIO_FN_SCIF0_SCK,
+ GPIO_FN_SCIF0_RXD, GPIO_FN_SCIF0_TXD,
+
+ /* SCIF1 */
+ GPIO_FN_SCIF1_SCK, GPIO_FN_SCIF1_RXD, GPIO_FN_SCIF1_TXD,
+
+ /* SCIF3 */
+ GPIO_FN_SCIF3_SCK, GPIO_FN_SCIF3_RXD, GPIO_FN_SCIF3_TXD,
+
+ /* SCIF4 */
+ GPIO_FN_SCIF4_SCK, GPIO_FN_SCIF4_RXD, GPIO_FN_SCIF4_TXD,
+
+ /* SCIF5 */
+ GPIO_FN_SCIF5_SCK, GPIO_FN_SCIF5_RXD, GPIO_FN_SCIF5_TXD,
+
+ /* LBSC */
+ GPIO_FN_BREQ, GPIO_FN_IOIS16, GPIO_FN_CE2B, GPIO_FN_CE2A, GPIO_FN_BACK,
+
+ /* FLCTL */
+ GPIO_FN_FALE, GPIO_FN_FRB, GPIO_FN_FSTATUS,
+ GPIO_FN_FSE, GPIO_FN_FCLE,
+
+ /* DMAC */
+ GPIO_FN_DACK0, GPIO_FN_DREQ0, GPIO_FN_DRAK0,
+ GPIO_FN_DACK1, GPIO_FN_DREQ1, GPIO_FN_DRAK1,
+ GPIO_FN_DACK2, GPIO_FN_DREQ2, GPIO_FN_DRAK2,
+ GPIO_FN_DACK3, GPIO_FN_DREQ3, GPIO_FN_DRAK3,
+
+ /* USB */
+ GPIO_FN_USB_OVC0, GPIO_FN_USB_PENC0,
+ GPIO_FN_USB_OVC1, GPIO_FN_USB_PENC1,
+
+ /* HAC */
+ GPIO_FN_HAC_RES,
+ GPIO_FN_HAC0_SDOUT, GPIO_FN_HAC0_SDIN,
+ GPIO_FN_HAC0_SYNC, GPIO_FN_HAC0_BITCLK,
+ GPIO_FN_HAC1_SDOUT, GPIO_FN_HAC1_SDIN,
+ GPIO_FN_HAC1_SYNC, GPIO_FN_HAC1_BITCLK,
+
+ /* SSI */
+ GPIO_FN_SSI0_SDATA, GPIO_FN_SSI0_SCK, GPIO_FN_SSI0_WS, GPIO_FN_SSI0_CLK,
+ GPIO_FN_SSI1_SDATA, GPIO_FN_SSI1_SCK, GPIO_FN_SSI1_WS, GPIO_FN_SSI1_CLK,
+ GPIO_FN_SSI2_SDATA, GPIO_FN_SSI2_SCK, GPIO_FN_SSI2_WS,
+ GPIO_FN_SSI3_SDATA, GPIO_FN_SSI3_SCK, GPIO_FN_SSI3_WS,
+
+ /* SDIF1 */
+ GPIO_FN_SDIF1CMD, GPIO_FN_SDIF1CD, GPIO_FN_SDIF1WP, GPIO_FN_SDIF1CLK,
+ GPIO_FN_SDIF1D3, GPIO_FN_SDIF1D2, GPIO_FN_SDIF1D1, GPIO_FN_SDIF1D0,
+
+ /* SDIF0 */
+ GPIO_FN_SDIF0CMD, GPIO_FN_SDIF0CD, GPIO_FN_SDIF0WP, GPIO_FN_SDIF0CLK,
+ GPIO_FN_SDIF0D3, GPIO_FN_SDIF0D2, GPIO_FN_SDIF0D1, GPIO_FN_SDIF0D0,
+
+ /* TMU */
+ GPIO_FN_TCLK,
+
+ /* INTC */
+ GPIO_FN_IRL7, GPIO_FN_IRL6, GPIO_FN_IRL5, GPIO_FN_IRL4,
+};
+
+#endif /* __CPU_SH7786_H__ */
diff --git a/arch/sh/include/mach-common/mach/urquell.h b/arch/sh/include/mach-common/mach/urquell.h
new file mode 100644
index 000000000000..14b3e1d01777
--- /dev/null
+++ b/arch/sh/include/mach-common/mach/urquell.h
@@ -0,0 +1,68 @@
+#ifndef __MACH_URQUELL_H
+#define __MACH_URQUELL_H
+
+/*
+ * ------ 0x00000000 ------------------------------------
+ * CS0 | (SW1,SW47) EEPROM, SRAM, NOR FLASH
+ * -----+ 0x04000000 ------------------------------------
+ * CS1 | (SW47) SRAM, SRAM-LAN-PCMCIA, NOR FLASH
+ * -----+ 0x08000000 ------------------------------------
+ * CS2 | DDR3
+ * CS3 |
+ * -----+ 0x10000000 ------------------------------------
+ * CS4 | PCIe
+ * -----+ 0x14000000 ------------------------------------
+ * CS5 | (SW47) LRAM/URAM, SRAM-LAN-PCMCIA
+ * -----+ 0x18000000 ------------------------------------
+ * CS6 | ATA, NAND FLASH
+ * -----+ 0x1c000000 ------------------------------------
+ * CS7 | SH7786 register
+ * -----+------------------------------------------------
+ */
+
+#define NOR_FLASH_ADDR 0x00000000
+#define NOR_FLASH_SIZE 0x04000000
+
+#define CS1_BASE 0x05000000
+#define CS5_BASE 0x15000000
+#define FPGA_BASE CS1_BASE
+
+#define BOARDREG(ofs) (FPGA_BASE + ofs##_OFS)
+#define UBOARDREG(ofs) (0xa0000000 + FPGA_BASE + ofs##_OFS)
+
+#define SRSTR_OFS 0x0000 /* System reset register */
+#define BDMR_OFS 0x0010 /* Board operating mode resister */
+#define IRL0SR_OFS 0x0020 /* IRL0 Status register */
+#define IRL0MSKR_OFS 0x0030 /* IRL0 Mask register */
+#define IRL1SR_OFS 0x0040 /* IRL1 Status register */
+#define IRL1MSKR_OFS 0x0050 /* IRL1 Mask register */
+#define IRL2SR_OFS 0x0060 /* IRL2 Status register */
+#define IRL2MSKR_OFS 0x0070 /* IRL2 Mask register */
+#define IRL3SR_OFS 0x0080 /* IRL3 Status register */
+#define IRL3MSKR_OFS 0x0090 /* IRL3 Mask register */
+#define SOFTINTR_OFS 0x0120 /* Softwear Interrupt register */
+#define SLEDR_OFS 0x0130 /* LED control resister */
+#define MAPSCIFSWR_OFS 0x0140 /* Map/SCIF Switch register */
+#define FPVERR_OFS 0x0150 /* FPGA Version register */
+#define FPDATER_OFS 0x0160 /* FPGA Date register */
+#define FPYEARR_OFS 0x0170 /* FPGA Year register */
+#define TCLKCR_OFS 0x0180 /* TCLK Control register */
+#define DIPSWMR_OFS 0x1000 /* DIPSW monitor register */
+#define FPODR_OFS 0x1010 /* Output port data register */
+#define ATACNR_OFS 0x1020 /* ATA-CN Control/status register */
+#define FPINDR_OFS 0x1030 /* Input port data register */
+#define MDSWMR_OFS 0x1040 /* MODE SW monitor register */
+#define DDR3BUPCR_OFS 0x1050 /* DDR3 Backup control register */
+#define SSICODECCR_OFS 0x1060 /* SSI-CODEC control register */
+#define PCIESLOTSR_OFS 0x1070 /* PCIexpress Slot status register */
+#define ETHERPORTSR_OFS 0x1080 /* EtherPhy Port status register */
+#define LATCHCR_OFS 0x3000 /* Latch control register */
+#define LATCUAR_OFS 0x3010 /* Latch upper address register */
+#define LATCLAR_OFS 0x3012 /* Latch lower address register */
+#define LATCLUDR_OFS 0x3024 /* Latch D31-16 register */
+#define LATCLLDR_OFS 0x3026 /* Latch D15-0 register */
+
+#define CHARLED_OFS 0x2000 /* Character LED */
+
+#endif /* __MACH_URQUELL_H */
+
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
index 2e1b86e16ab5..82a3a150c00d 100644
--- a/arch/sh/kernel/Makefile_32
+++ b/arch/sh/kernel/Makefile_32
@@ -30,5 +30,6 @@ obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_GENERIC_GPIO) += gpio.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
obj-$(CONFIG_DUMP_CODE) += disassemble.o
+obj-$(CONFIG_HIBERNATION) += swsusp.o
EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/asm-offsets.c b/arch/sh/kernel/asm-offsets.c
index 57cf0e0680f3..99aceb28ee24 100644
--- a/arch/sh/kernel/asm-offsets.c
+++ b/arch/sh/kernel/asm-offsets.c
@@ -12,8 +12,10 @@
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/kbuild.h>
+#include <linux/suspend.h>
#include <asm/thread_info.h>
+#include <asm/suspend.h>
int main(void)
{
@@ -25,5 +27,11 @@ int main(void)
DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
DEFINE(TI_RESTART_BLOCK,offsetof(struct thread_info, restart_block));
+#ifdef CONFIG_HIBERNATION
+ DEFINE(PBE_ADDRESS, offsetof(struct pbe, address));
+ DEFINE(PBE_ORIG_ADDRESS, offsetof(struct pbe, orig_address));
+ DEFINE(PBE_NEXT, offsetof(struct pbe, next));
+ DEFINE(SWSUSP_ARCH_REGS_SIZE, sizeof(struct swsusp_arch_regs));
+#endif
return 0;
}
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index f471d242774e..2600641a483f 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_CPU_SH5) = sh5/
# Special cases for family ancestry.
obj-$(CONFIG_CPU_SH4A) += sh4a/
+obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/
# Common interfaces.
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 7b17137536d6..1dc896483b59 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -20,6 +20,8 @@
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/kref.h>
+#include <linux/kobject.h>
+#include <linux/sysdev.h>
#include <linux/seq_file.h>
#include <linux/err.h>
#include <linux/platform_device.h>
@@ -239,6 +241,35 @@ void clk_recalc_rate(struct clk *clk)
}
EXPORT_SYMBOL_GPL(clk_recalc_rate);
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = -EINVAL;
+ struct clk *old;
+
+ if (!parent || !clk)
+ return ret;
+
+ old = clk->parent;
+ if (likely(clk->ops && clk->ops->set_parent)) {
+ unsigned long flags;
+ spin_lock_irqsave(&clock_lock, flags);
+ ret = clk->ops->set_parent(clk, parent);
+ spin_unlock_irqrestore(&clock_lock, flags);
+ clk->parent = (ret ? old : parent);
+ }
+
+ if (unlikely(clk->flags & CLK_RATE_PROPAGATES))
+ propagate_rate(clk);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ return clk->parent;
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);
+
long clk_round_rate(struct clk *clk, unsigned long rate)
{
if (likely(clk->ops && clk->ops->round_rate)) {
@@ -329,6 +360,70 @@ static int show_clocks(char *buf, char **start, off_t off,
return p - buf;
}
+#ifdef CONFIG_PM
+static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state)
+{
+ static pm_message_t prev_state;
+ struct clk *clkp;
+
+ switch (state.event) {
+ case PM_EVENT_ON:
+ /* Resumeing from hibernation */
+ if (prev_state.event == PM_EVENT_FREEZE) {
+ list_for_each_entry(clkp, &clock_list, node)
+ if (likely(clkp->ops)) {
+ unsigned long rate = clkp->rate;
+
+ if (likely(clkp->ops->set_parent))
+ clkp->ops->set_parent(clkp,
+ clkp->parent);
+ if (likely(clkp->ops->set_rate))
+ clkp->ops->set_rate(clkp,
+ rate, NO_CHANGE);
+ else if (likely(clkp->ops->recalc))
+ clkp->ops->recalc(clkp);
+ }
+ }
+ break;
+ case PM_EVENT_FREEZE:
+ break;
+ case PM_EVENT_SUSPEND:
+ break;
+ }
+
+ prev_state = state;
+ return 0;
+}
+
+static int clks_sysdev_resume(struct sys_device *dev)
+{
+ return clks_sysdev_suspend(dev, PMSG_ON);
+}
+
+static struct sysdev_class clks_sysdev_class = {
+ .name = "clks",
+};
+
+static struct sysdev_driver clks_sysdev_driver = {
+ .suspend = clks_sysdev_suspend,
+ .resume = clks_sysdev_resume,
+};
+
+static struct sys_device clks_sysdev_dev = {
+ .cls = &clks_sysdev_class,
+};
+
+static int __init clk_sysdev_init(void)
+{
+ sysdev_class_register(&clks_sysdev_class);
+ sysdev_driver_register(&clks_sysdev_class, &clks_sysdev_driver);
+ sysdev_register(&clks_sysdev_dev);
+
+ return 0;
+}
+subsys_initcall(clk_sysdev_init);
+#endif
+
int __init clk_init(void)
{
int i, ret = 0;
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
index 56e5878e5516..0e32d8e448ca 100644
--- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c
+++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c
@@ -2,6 +2,7 @@
* SH7619 Setup
*
* Copyright (C) 2006 Yoshinori Sato
+ * Copyright (C) 2009 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -18,15 +19,10 @@ enum {
/* interrupt sources */
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
WDT, EDMAC, CMT0, CMT1,
- SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
- SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
- SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
+ SCIF0, SCIF1, SCIF2,
HIF_HIFI, HIF_HIFBI,
DMAC0, DMAC1, DMAC2, DMAC3,
SIOF,
-
- /* interrupt groups */
- SCIF0, SCIF1, SCIF2,
};
static struct intc_vect vectors[] __initdata = {
@@ -36,24 +32,18 @@ static struct intc_vect vectors[] __initdata = {
INTC_IRQ(IRQ6, 82), INTC_IRQ(IRQ7, 83),
INTC_IRQ(WDT, 84), INTC_IRQ(EDMAC, 85),
INTC_IRQ(CMT0, 86), INTC_IRQ(CMT1, 87),
- INTC_IRQ(SCIF0_ERI, 88), INTC_IRQ(SCIF0_RXI, 89),
- INTC_IRQ(SCIF0_BRI, 90), INTC_IRQ(SCIF0_TXI, 91),
- INTC_IRQ(SCIF1_ERI, 92), INTC_IRQ(SCIF1_RXI, 93),
- INTC_IRQ(SCIF1_BRI, 94), INTC_IRQ(SCIF1_TXI, 95),
- INTC_IRQ(SCIF2_ERI, 96), INTC_IRQ(SCIF2_RXI, 97),
- INTC_IRQ(SCIF2_BRI, 98), INTC_IRQ(SCIF2_TXI, 99),
+ INTC_IRQ(SCIF0, 88), INTC_IRQ(SCIF0, 89),
+ INTC_IRQ(SCIF0, 90), INTC_IRQ(SCIF0, 91),
+ INTC_IRQ(SCIF1, 92), INTC_IRQ(SCIF1, 93),
+ INTC_IRQ(SCIF1, 94), INTC_IRQ(SCIF1, 95),
+ INTC_IRQ(SCIF2, 96), INTC_IRQ(SCIF2, 97),
+ INTC_IRQ(SCIF2, 98), INTC_IRQ(SCIF2, 99),
INTC_IRQ(HIF_HIFI, 100), INTC_IRQ(HIF_HIFBI, 101),
INTC_IRQ(DMAC0, 104), INTC_IRQ(DMAC1, 105),
INTC_IRQ(DMAC2, 106), INTC_IRQ(DMAC3, 107),
INTC_IRQ(SIOF, 108),
};
-static struct intc_group groups[] __initdata = {
- INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
- INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
- INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
-};
-
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xf8140006, 0, 16, 4, /* IPRA */ { IRQ0, IRQ1, IRQ2, IRQ3 } },
{ 0xf8140008, 0, 16, 4, /* IPRB */ { IRQ4, IRQ5, IRQ6, IRQ7 } },
@@ -64,7 +54,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xf8080008, 0, 16, 4, /* IPRG */ { SIOF } },
};
-static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, groups,
+static DECLARE_INTC_DESC(intc_desc, "sh7619", vectors, NULL,
NULL, prio_registers, NULL);
static struct plat_sci_port sci_platform_data[] = {
@@ -72,17 +62,17 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xf8400000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 88, 89, 91, 90},
+ .irqs = { 88, 88, 88, 88 },
}, {
.mapbase = 0xf8410000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 92, 93, 95, 94},
+ .irqs = { 92, 92, 92, 92 },
}, {
.mapbase = 0xf8420000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 96, 97, 99, 98},
+ .irqs = { 96, 96, 96, 96 },
}, {
.flags = 0,
}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
index e611d79fac4c..844293723cfc 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c
@@ -1,7 +1,7 @@
/*
* Renesas MX-G (R8A03022BG) Setup
*
- * Copyright (C) 2008 Paul Mundt
+ * Copyright (C) 2008, 2009 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -20,23 +20,15 @@ enum {
IRQ8, IRQ9, IRQ10, IRQ11, IRQ12, IRQ13, IRQ14, IRQ15,
PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
-
SINT8, SINT7, SINT6, SINT5, SINT4, SINT3, SINT2, SINT1,
- SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
- SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
+ SCIF0, SCIF1,
- MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
- MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
- MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
- MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
- MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
- MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
- MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W,
+ MTU2_GROUP1, MTU2_GROUP2, MTU2_GROUP3, MTU2_GROUP4, MTU2_GROUP5
+ MTU2_TGI3B, MTU2_TGI3C,
/* interrupt groups */
- PINT, SCIF0, SCIF1,
- MTU2_GROUP1, MTU2_GROUP2, MTU2_GROUP3, MTU2_GROUP4, MTU2_GROUP5
+ PINT,
};
static struct intc_vect vectors[] __initdata = {
@@ -59,47 +51,36 @@ static struct intc_vect vectors[] __initdata = {
INTC_IRQ(SINT4, 98), INTC_IRQ(SINT3, 99),
INTC_IRQ(SINT2, 100), INTC_IRQ(SINT1, 101),
- INTC_IRQ(SCIF0_RXI, 220), INTC_IRQ(SCIF0_TXI, 221),
- INTC_IRQ(SCIF0_BRI, 222), INTC_IRQ(SCIF0_ERI, 223),
- INTC_IRQ(SCIF1_RXI, 224), INTC_IRQ(SCIF1_TXI, 225),
- INTC_IRQ(SCIF1_BRI, 226), INTC_IRQ(SCIF1_ERI, 227),
+ INTC_IRQ(SCIF0, 220), INTC_IRQ(SCIF0, 221),
+ INTC_IRQ(SCIF0, 222), INTC_IRQ(SCIF0, 223),
+ INTC_IRQ(SCIF1, 224), INTC_IRQ(SCIF1, 225),
+ INTC_IRQ(SCIF1, 226), INTC_IRQ(SCIF1, 227),
- INTC_IRQ(MTU2_TGI0A, 228), INTC_IRQ(MTU2_TGI0B, 229),
- INTC_IRQ(MTU2_TGI0C, 230), INTC_IRQ(MTU2_TGI0D, 231),
- INTC_IRQ(MTU2_TCI0V, 232), INTC_IRQ(MTU2_TGI0E, 233),
+ INTC_IRQ(MTU2_GROUP1, 228), INTC_IRQ(MTU2_GROUP1, 229),
+ INTC_IRQ(MTU2_GROUP1, 230), INTC_IRQ(MTU2_GROUP1, 231),
+ INTC_IRQ(MTU2_GROUP1, 232), INTC_IRQ(MTU2_GROUP1, 233),
- INTC_IRQ(MTU2_TGI0F, 234), INTC_IRQ(MTU2_TGI1A, 235),
- INTC_IRQ(MTU2_TGI1B, 236), INTC_IRQ(MTU2_TCI1V, 237),
- INTC_IRQ(MTU2_TCI1U, 238), INTC_IRQ(MTU2_TGI2A, 239),
+ INTC_IRQ(MTU2_GROUP2, 234), INTC_IRQ(MTU2_GROUP2, 235),
+ INTC_IRQ(MTU2_GROUP2, 236), INTC_IRQ(MTU2_GROUP2, 237),
+ INTC_IRQ(MTU2_GROUP2, 238), INTC_IRQ(MTU2_GROUP2, 239),
- INTC_IRQ(MTU2_TGI2B, 240), INTC_IRQ(MTU2_TCI2V, 241),
- INTC_IRQ(MTU2_TCI2U, 242), INTC_IRQ(MTU2_TGI3A, 243),
+ INTC_IRQ(MTU2_GROUP3, 240), INTC_IRQ(MTU2_GROUP3, 241),
+ INTC_IRQ(MTU2_GROUP3, 242), INTC_IRQ(MTU2_GROUP3, 243),
INTC_IRQ(MTU2_TGI3B, 244),
INTC_IRQ(MTU2_TGI3C, 245),
- INTC_IRQ(MTU2_TGI3D, 246), INTC_IRQ(MTU2_TCI3V, 247),
- INTC_IRQ(MTU2_TGI4A, 248), INTC_IRQ(MTU2_TGI4B, 249),
- INTC_IRQ(MTU2_TGI4C, 250), INTC_IRQ(MTU2_TGI4D, 251),
+ INTC_IRQ(MTU2_GROUP4, 246), INTC_IRQ(MTU2_GROUP4, 247),
+ INTC_IRQ(MTU2_GROUP4, 248), INTC_IRQ(MTU2_GROUP4, 249),
+ INTC_IRQ(MTU2_GROUP4, 250), INTC_IRQ(MTU2_GROUP4, 251),
- INTC_IRQ(MTU2_TCI4V, 252), INTC_IRQ(MTU2_TGI5U, 253),
- INTC_IRQ(MTU2_TGI5V, 254), INTC_IRQ(MTU2_TGI5W, 255),
+ INTC_IRQ(MTU2_GROUP5, 252), INTC_IRQ(MTU2_GROUP5, 253),
+ INTC_IRQ(MTU2_GROUP5, 254), INTC_IRQ(MTU2_GROUP5, 255),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
PINT4, PINT5, PINT6, PINT7),
- INTC_GROUP(MTU2_GROUP1, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
- MTU2_TCI0V, MTU2_TGI0E),
- INTC_GROUP(MTU2_GROUP2, MTU2_TGI0F, MTU2_TGI1A, MTU2_TGI1B,
- MTU2_TCI1V, MTU2_TCI1U, MTU2_TGI2A),
- INTC_GROUP(MTU2_GROUP3, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
- MTU2_TGI3A),
- INTC_GROUP(MTU2_GROUP4, MTU2_TGI3D, MTU2_TCI3V, MTU2_TGI4A,
- MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
- INTC_GROUP(MTU2_GROUP5, MTU2_TCI4V, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W),
- INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
- INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
};
static struct intc_prio_reg prio_registers[] __initdata = {
@@ -137,7 +118,7 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xff804000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 223, 220, 221, 222 },
+ .irqs = { 220, 220, 220, 220 },
}, {
.flags = 0,
}
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
index 0631e421c022..00f42f9e3f5c 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c
@@ -2,6 +2,7 @@
* SH7201 setup
*
* Copyright (C) 2008 Peter Griffin pgriffin@mpc-data.co.uk
+ * Copyright (C) 2009 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -18,57 +19,32 @@ enum {
/* interrupt sources */
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
+
ADC_ADI,
- MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
- MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
- MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
- MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
- MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
- MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
- MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W,
- RTC_ARM, RTC_PRD, RTC_CUP,
- WDT,
- IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI, IIC30_TEI,
- IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI, IIC31_TEI,
- IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI, IIC32_TEI,
+
+ MTU20_ABCD, MTU20_VEF, MTU21_AB, MTU21_VU, MTU22_AB, MTU22_VU,
+ MTU23_ABCD, MTU24_ABCD, MTU25_UVW, MTU2_TCI3V, MTU2_TCI4V,
+
+ RTC, WDT,
+
+ IIC30, IIC31, IIC32,
DMAC0_DMINT0, DMAC1_DMINT1,
DMAC2_DMINT2, DMAC3_DMINT3,
- SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
- SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
- SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
- SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI,
- SCIF4_BRI, SCIF4_ERI, SCIF4_RXI, SCIF4_TXI,
- SCIF5_BRI, SCIF5_ERI, SCIF5_RXI, SCIF5_TXI,
- SCIF6_BRI, SCIF6_ERI, SCIF6_RXI, SCIF6_TXI,
- SCIF7_BRI, SCIF7_ERI, SCIF7_RXI, SCIF7_TXI,
+ SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5, SCIF6, SCIF7,
DMAC0_DMINTA, DMAC4_DMINT4, DMAC5_DMINT5, DMAC6_DMINT6,
DMAC7_DMINT7,
- RCAN0_ERS, RCAN0_OVR,
- RCAN0_SLE,
- RCAN0_RM0, RCAN0_RM1,
-
- RCAN1_ERS, RCAN1_OVR,
- RCAN1_SLE,
- RCAN1_RM0, RCAN1_RM1,
+ RCAN0, RCAN1,
SSI0_SSII, SSI1_SSII,
- TMR0_CMIA0, TMR0_CMIB0, TMR0_OVI0,
- TMR1_CMIA1, TMR1_CMIB1, TMR1_OVI1,
+ TMR0, TMR1,
/* interrupt groups */
-
- IRQ, PINT, ADC,
- MTU20_ABCD, MTU20_VEF, MTU21_AB, MTU21_VU, MTU22_AB, MTU22_VU,
- MTU23_ABCD, MTU24_ABCD, MTU25_UVW,
- RTC, IIC30, IIC31, IIC32,
- SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5, SCIF6, SCIF7,
- RCAN0, RCAN1, TMR0, TMR1
-
+ PINT,
};
static struct intc_vect vectors[] __initdata = {
@@ -76,6 +52,7 @@ static struct intc_vect vectors[] __initdata = {
INTC_IRQ(IRQ2, 66), INTC_IRQ(IRQ3, 67),
INTC_IRQ(IRQ4, 68), INTC_IRQ(IRQ5, 69),
INTC_IRQ(IRQ6, 70), INTC_IRQ(IRQ7, 71),
+
INTC_IRQ(PINT0, 80), INTC_IRQ(PINT1, 81),
INTC_IRQ(PINT2, 82), INTC_IRQ(PINT3, 83),
INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85),
@@ -83,123 +60,92 @@ static struct intc_vect vectors[] __initdata = {
INTC_IRQ(ADC_ADI, 92),
- INTC_IRQ(MTU2_TGI0A, 108), INTC_IRQ(MTU2_TGI0B, 109),
- INTC_IRQ(MTU2_TGI0C, 110), INTC_IRQ(MTU2_TGI0D, 111),
- INTC_IRQ(MTU2_TCI0V, 112),
- INTC_IRQ(MTU2_TGI0E, 113), INTC_IRQ(MTU2_TGI0F, 114),
+ INTC_IRQ(MTU20_ABCD, 108), INTC_IRQ(MTU20_ABCD, 109),
+ INTC_IRQ(MTU20_ABCD, 110), INTC_IRQ(MTU20_ABCD, 111),
+
+ INTC_IRQ(MTU20_VEF, 112), INTC_IRQ(MTU20_VEF, 113),
+ INTC_IRQ(MTU20_VEF, 114),
+
+ INTC_IRQ(MTU21_AB, 116), INTC_IRQ(MTU21_AB, 117),
+ INTC_IRQ(MTU21_VU, 120), INTC_IRQ(MTU21_VU, 121),
- INTC_IRQ(MTU2_TGI1A, 116), INTC_IRQ(MTU2_TGI1B, 117),
- INTC_IRQ(MTU2_TCI1V, 120), INTC_IRQ(MTU2_TCI1U, 121),
+ INTC_IRQ(MTU22_AB, 124), INTC_IRQ(MTU22_AB, 125),
+ INTC_IRQ(MTU22_VU, 128), INTC_IRQ(MTU22_VU, 129),
- INTC_IRQ(MTU2_TGI2A, 124), INTC_IRQ(MTU2_TGI2B, 125),
- INTC_IRQ(MTU2_TCI2V, 128), INTC_IRQ(MTU2_TCI2U, 129),
+ INTC_IRQ(MTU23_ABCD, 132), INTC_IRQ(MTU23_ABCD, 133),
+ INTC_IRQ(MTU23_ABCD, 134), INTC_IRQ(MTU23_ABCD, 135),
- INTC_IRQ(MTU2_TGI3A, 132), INTC_IRQ(MTU2_TGI3B, 133),
- INTC_IRQ(MTU2_TGI3C, 134), INTC_IRQ(MTU2_TGI3D, 135),
INTC_IRQ(MTU2_TCI3V, 136),
- INTC_IRQ(MTU2_TGI4A, 140), INTC_IRQ(MTU2_TGI4B, 141),
- INTC_IRQ(MTU2_TGI4C, 142), INTC_IRQ(MTU2_TGI4D, 143),
+ INTC_IRQ(MTU24_ABCD, 140), INTC_IRQ(MTU24_ABCD, 141),
+ INTC_IRQ(MTU24_ABCD, 142), INTC_IRQ(MTU24_ABCD, 143),
+
INTC_IRQ(MTU2_TCI4V, 144),
- INTC_IRQ(MTU2_TGI5U, 148), INTC_IRQ(MTU2_TGI5V, 149),
- INTC_IRQ(MTU2_TGI5W, 150),
+ INTC_IRQ(MTU25_UVW, 148), INTC_IRQ(MTU25_UVW, 149),
+ INTC_IRQ(MTU25_UVW, 150),
+
+ INTC_IRQ(RTC, 152), INTC_IRQ(RTC, 153),
+ INTC_IRQ(RTC, 154),
- INTC_IRQ(RTC_ARM, 152), INTC_IRQ(RTC_PRD, 153),
- INTC_IRQ(RTC_CUP, 154), INTC_IRQ(WDT, 156),
+ INTC_IRQ(WDT, 156),
- INTC_IRQ(IIC30_STPI, 157), INTC_IRQ(IIC30_NAKI, 158),
- INTC_IRQ(IIC30_RXI, 159), INTC_IRQ(IIC30_TXI, 160),
- INTC_IRQ(IIC30_TEI, 161),
+ INTC_IRQ(IIC30, 157), INTC_IRQ(IIC30, 158),
+ INTC_IRQ(IIC30, 159), INTC_IRQ(IIC30, 160),
+ INTC_IRQ(IIC30, 161),
- INTC_IRQ(IIC31_STPI, 164), INTC_IRQ(IIC31_NAKI, 165),
- INTC_IRQ(IIC31_RXI, 166), INTC_IRQ(IIC31_TXI, 167),
- INTC_IRQ(IIC31_TEI, 168),
+ INTC_IRQ(IIC31, 164), INTC_IRQ(IIC31, 165),
+ INTC_IRQ(IIC31, 166), INTC_IRQ(IIC31, 167),
+ INTC_IRQ(IIC31, 168),
- INTC_IRQ(IIC32_STPI, 170), INTC_IRQ(IIC32_NAKI, 171),
- INTC_IRQ(IIC32_RXI, 172), INTC_IRQ(IIC32_TXI, 173),
- INTC_IRQ(IIC32_TEI, 174),
+ INTC_IRQ(IIC32, 170), INTC_IRQ(IIC32, 171),
+ INTC_IRQ(IIC32, 172), INTC_IRQ(IIC32, 173),
+ INTC_IRQ(IIC32, 174),
INTC_IRQ(DMAC0_DMINT0, 176), INTC_IRQ(DMAC1_DMINT1, 177),
INTC_IRQ(DMAC2_DMINT2, 178), INTC_IRQ(DMAC3_DMINT3, 179),
- INTC_IRQ(SCIF0_BRI, 180), INTC_IRQ(SCIF0_ERI, 181),
- INTC_IRQ(SCIF0_RXI, 182), INTC_IRQ(SCIF0_TXI, 183),
- INTC_IRQ(SCIF1_BRI, 184), INTC_IRQ(SCIF1_ERI, 185),
- INTC_IRQ(SCIF1_RXI, 186), INTC_IRQ(SCIF1_TXI, 187),
- INTC_IRQ(SCIF2_BRI, 188), INTC_IRQ(SCIF2_ERI, 189),
- INTC_IRQ(SCIF2_RXI, 190), INTC_IRQ(SCIF2_TXI, 191),
- INTC_IRQ(SCIF3_BRI, 192), INTC_IRQ(SCIF3_ERI, 193),
- INTC_IRQ(SCIF3_RXI, 194), INTC_IRQ(SCIF3_TXI, 195),
- INTC_IRQ(SCIF4_BRI, 196), INTC_IRQ(SCIF4_ERI, 197),
- INTC_IRQ(SCIF4_RXI, 198), INTC_IRQ(SCIF4_TXI, 199),
- INTC_IRQ(SCIF5_BRI, 200), INTC_IRQ(SCIF5_ERI, 201),
- INTC_IRQ(SCIF5_RXI, 202), INTC_IRQ(SCIF5_TXI, 203),
- INTC_IRQ(SCIF6_BRI, 204), INTC_IRQ(SCIF6_ERI, 205),
- INTC_IRQ(SCIF6_RXI, 206), INTC_IRQ(SCIF6_TXI, 207),
- INTC_IRQ(SCIF7_BRI, 208), INTC_IRQ(SCIF7_ERI, 209),
- INTC_IRQ(SCIF7_RXI, 210), INTC_IRQ(SCIF7_TXI, 211),
+ INTC_IRQ(SCIF0, 180), INTC_IRQ(SCIF0, 181),
+ INTC_IRQ(SCIF0, 182), INTC_IRQ(SCIF0, 183),
+ INTC_IRQ(SCIF1, 184), INTC_IRQ(SCIF1, 185),
+ INTC_IRQ(SCIF1, 186), INTC_IRQ(SCIF1, 187),
+ INTC_IRQ(SCIF2, 188), INTC_IRQ(SCIF2, 189),
+ INTC_IRQ(SCIF2, 190), INTC_IRQ(SCIF2, 191),
+ INTC_IRQ(SCIF3, 192), INTC_IRQ(SCIF3, 193),
+ INTC_IRQ(SCIF3, 194), INTC_IRQ(SCIF3, 195),
+ INTC_IRQ(SCIF4, 196), INTC_IRQ(SCIF4, 197),
+ INTC_IRQ(SCIF4, 198), INTC_IRQ(SCIF4, 199),
+ INTC_IRQ(SCIF5, 200), INTC_IRQ(SCIF5, 201),
+ INTC_IRQ(SCIF5, 202), INTC_IRQ(SCIF5, 203),
+ INTC_IRQ(SCIF6, 204), INTC_IRQ(SCIF6, 205),
+ INTC_IRQ(SCIF6, 206), INTC_IRQ(SCIF6, 207),
+ INTC_IRQ(SCIF7, 208), INTC_IRQ(SCIF7, 209),
+ INTC_IRQ(SCIF7, 210), INTC_IRQ(SCIF7, 211),
INTC_IRQ(DMAC0_DMINTA, 212), INTC_IRQ(DMAC4_DMINT4, 216),
INTC_IRQ(DMAC5_DMINT5, 217), INTC_IRQ(DMAC6_DMINT6, 218),
INTC_IRQ(DMAC7_DMINT7, 219),
- INTC_IRQ(RCAN0_ERS, 228), INTC_IRQ(RCAN0_OVR, 229),
- INTC_IRQ(RCAN0_SLE, 230),
- INTC_IRQ(RCAN0_RM0, 231), INTC_IRQ(RCAN0_RM1, 232),
+ INTC_IRQ(RCAN0, 228), INTC_IRQ(RCAN0, 229),
+ INTC_IRQ(RCAN0, 230),
+ INTC_IRQ(RCAN0, 231), INTC_IRQ(RCAN0, 232),
- INTC_IRQ(RCAN1_ERS, 234), INTC_IRQ(RCAN1_OVR, 235),
- INTC_IRQ(RCAN1_SLE, 236),
- INTC_IRQ(RCAN1_RM0, 237), INTC_IRQ(RCAN1_RM1, 238),
+ INTC_IRQ(RCAN1, 234), INTC_IRQ(RCAN1, 235),
+ INTC_IRQ(RCAN1, 236),
+ INTC_IRQ(RCAN1, 237), INTC_IRQ(RCAN1, 238),
INTC_IRQ(SSI0_SSII, 244), INTC_IRQ(SSI1_SSII, 245),
- INTC_IRQ(TMR0_CMIA0, 246), INTC_IRQ(TMR0_CMIB0, 247),
- INTC_IRQ(TMR0_OVI0, 248),
-
- INTC_IRQ(TMR1_CMIA1, 252), INTC_IRQ(TMR1_CMIB1, 253),
- INTC_IRQ(TMR1_OVI1, 254),
+ INTC_IRQ(TMR0, 246), INTC_IRQ(TMR0, 247),
+ INTC_IRQ(TMR0, 248),
+ INTC_IRQ(TMR1, 252), INTC_IRQ(TMR1, 253),
+ INTC_IRQ(TMR1, 254),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
PINT4, PINT5, PINT6, PINT7),
- INTC_GROUP(MTU20_ABCD, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D),
- INTC_GROUP(MTU20_VEF, MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F),
-
- INTC_GROUP(MTU21_AB, MTU2_TGI1A, MTU2_TGI1B),
- INTC_GROUP(MTU21_VU, MTU2_TCI1V, MTU2_TCI1U),
- INTC_GROUP(MTU22_AB, MTU2_TGI2A, MTU2_TGI2B),
- INTC_GROUP(MTU22_VU, MTU2_TCI2V, MTU2_TCI2U),
- INTC_GROUP(MTU23_ABCD, MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D),
- INTC_GROUP(MTU24_ABCD, MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
- INTC_GROUP(MTU25_UVW, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W),
- INTC_GROUP(RTC, RTC_ARM, RTC_PRD, RTC_CUP ),
-
- INTC_GROUP(IIC30, IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI,
- IIC30_TEI),
- INTC_GROUP(IIC31, IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI,
- IIC31_TEI),
- INTC_GROUP(IIC32, IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI,
- IIC32_TEI),
-
- INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
- INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
- INTC_GROUP(SCIF2, SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
- INTC_GROUP(SCIF3, SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI),
- INTC_GROUP(SCIF4, SCIF4_BRI, SCIF4_ERI, SCIF4_RXI, SCIF4_TXI),
- INTC_GROUP(SCIF5, SCIF5_BRI, SCIF5_ERI, SCIF5_RXI, SCIF5_TXI),
- INTC_GROUP(SCIF6, SCIF6_BRI, SCIF6_ERI, SCIF6_RXI, SCIF6_TXI),
- INTC_GROUP(SCIF7, SCIF7_BRI, SCIF7_ERI, SCIF7_RXI, SCIF7_TXI),
-
- INTC_GROUP(RCAN0, RCAN0_ERS, RCAN0_OVR, RCAN0_RM0, RCAN0_RM1,
- RCAN0_SLE),
- INTC_GROUP(RCAN1, RCAN1_ERS, RCAN1_OVR, RCAN1_RM0, RCAN1_RM1,
- RCAN1_SLE),
-
- INTC_GROUP(TMR0, TMR0_CMIA0, TMR0_CMIB0, TMR0_OVI0),
- INTC_GROUP(TMR1, TMR1_CMIA1, TMR1_CMIB1, TMR1_OVI1),
};
static struct intc_prio_reg prio_registers[] __initdata = {
@@ -212,7 +158,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xfffe9806, 0, 16, 4, /* IPR09 */ { RTC, WDT, IIC30, 0 } },
{ 0xfffe9808, 0, 16, 4, /* IPR10 */ { IIC31, IIC32, DMAC0_DMINT0, DMAC1_DMINT1 } },
- { 0xfffe980a, 0, 16, 4, /* IPR11 */ { DMAC2_DMINT2, DMAC3_DMINT3, SCIF0 , SCIF1 } },
+ { 0xfffe980a, 0, 16, 4, /* IPR11 */ { DMAC2_DMINT2, DMAC3_DMINT3, SCIF0, SCIF1 } },
{ 0xfffe980c, 0, 16, 4, /* IPR12 */ { SCIF2, SCIF3, SCIF4, SCIF5 } },
{ 0xfffe980e, 0, 16, 4, /* IPR13 */ { SCIF6, SCIF7, DMAC0_DMINTA, DMAC4_DMINT4 } },
{ 0xfffe9810, 0, 16, 4, /* IPR14 */ { DMAC5_DMINT5, DMAC6_DMINT6, DMAC7_DMINT7, 0 } },
@@ -234,42 +180,42 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xfffe8000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 181, 182, 183, 180}
+ .irqs = { 180, 180, 180, 180 }
}, {
.mapbase = 0xfffe8800,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 185, 186, 187, 184}
+ .irqs = { 184, 184, 184, 184 }
}, {
.mapbase = 0xfffe9000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 189, 186, 187, 188}
+ .irqs = { 188, 188, 188, 188 }
}, {
.mapbase = 0xfffe9800,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 193, 194, 195, 192}
+ .irqs = { 192, 192, 192, 192 }
}, {
.mapbase = 0xfffea000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 196, 198, 199, 196}
+ .irqs = { 196, 196, 196, 196 }
}, {
.mapbase = 0xfffea800,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 201, 202, 203, 200}
+ .irqs = { 200, 200, 200, 200 }
}, {
.mapbase = 0xfffeb000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 205, 206, 207, 204}
+ .irqs = { 204, 204, 204, 204 }
}, {
.mapbase = 0xfffeb800,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 209, 210, 211, 208}
+ .irqs = { 208, 208, 208, 208 }
}, {
.flags = 0,
}
@@ -290,17 +236,7 @@ static struct resource rtc_resources[] = {
.flags = IORESOURCE_IO,
},
[1] = {
- /* Period IRQ */
- .start = 153,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- /* Carry IRQ */
- .start = 154,
- .flags = IORESOURCE_IRQ,
- },
- [3] = {
- /* Alarm IRQ */
+ /* Shared Period/Carry/Alarm IRQ */
.start = 152,
.flags = IORESOURCE_IRQ,
},
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
index e98dc4450352..820dfb2e8656 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c
@@ -1,7 +1,7 @@
/*
* SH7203 and SH7263 Setup
*
- * Copyright (C) 2007 Paul Mundt
+ * Copyright (C) 2007 - 2009 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -18,50 +18,27 @@ enum {
/* interrupt sources */
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
- DMAC0_DEI, DMAC0_HEI, DMAC1_DEI, DMAC1_HEI,
- DMAC2_DEI, DMAC2_HEI, DMAC3_DEI, DMAC3_HEI,
- DMAC4_DEI, DMAC4_HEI, DMAC5_DEI, DMAC5_HEI,
- DMAC6_DEI, DMAC6_HEI, DMAC7_DEI, DMAC7_HEI,
+ DMAC0, DMAC1, DMAC2, DMAC3, DMAC4, DMAC5, DMAC6, DMAC7,
USB, LCDC, CMT0, CMT1, BSC, WDT,
- MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
- MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
- MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
- MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
- MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
- MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
- ADC_ADI,
- IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI, IIC30_TEI,
- IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI, IIC31_TEI,
- IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI, IIC32_TEI,
- IIC33_STPI, IIC33_NAKI, IIC33_RXI, IIC33_TXI, IIC33_TEI,
- SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
- SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
- SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
- SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI,
- SSU0_SSERI, SSU0_SSRXI, SSU0_SSTXI,
- SSU1_SSERI, SSU1_SSRXI, SSU1_SSTXI,
- SSI0_SSII, SSI1_SSII, SSI2_SSII, SSI3_SSII,
- /* ROM-DEC, SDHI, SRC, and IEB are SH7263 specific */
- ROMDEC_ISY, ROMDEC_IERR, ROMDEC_IARG, ROMDEC_ISEC, ROMDEC_IBUF,
- ROMDEC_IREADY,
+ MTU0_ABCD, MTU0_VEF, MTU1_AB, MTU1_VU, MTU2_AB, MTU2_VU,
+ MTU3_ABCD, MTU4_ABCD, MTU2_TCI3V, MTU2_TCI4V,
- FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
+ ADC_ADI,
+
+ IIC30, IIC31, IIC32, IIC33,
+ SCIF0, SCIF1, SCIF2, SCIF3,
- SDHI3, SDHI0, SDHI1,
+ SSU0, SSU1,
- RTC_ARM, RTC_PRD, RTC_CUP,
- RCAN0_ERS, RCAN0_OVR, RCAN0_RM0, RCAN0_RM1, RCAN0_SLE,
- RCAN1_ERS, RCAN1_OVR, RCAN1_RM0, RCAN1_RM1, RCAN1_SLE,
+ SSI0_SSII, SSI1_SSII, SSI2_SSII, SSI3_SSII,
- SRC_OVF, SRC_ODFI, SRC_IDEI, IEBI,
+ /* ROM-DEC, SDHI, SRC, and IEB are SH7263 specific */
+ ROMDEC, FLCTL, SDHI, RTC, RCAN0, RCAN1,
+ SRC, IEBI,
/* interrupt groups */
- PINT, DMAC0, DMAC1, DMAC2, DMAC3, DMAC4, DMAC5, DMAC6, DMAC7,
- MTU0_ABCD, MTU0_VEF, MTU1_AB, MTU1_VU, MTU2_AB, MTU2_VU,
- MTU3_ABCD, MTU4_ABCD,
- IIC30, IIC31, IIC32, IIC33, SCIF0, SCIF1, SCIF2, SCIF3,
- SSU0, SSU1, ROMDEC, SDHI, FLCTL, RTC, RCAN0, RCAN1, SRC
+ PINT,
};
static struct intc_vect vectors[] __initdata = {
@@ -73,79 +50,80 @@ static struct intc_vect vectors[] __initdata = {
INTC_IRQ(PINT2, 82), INTC_IRQ(PINT3, 83),
INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85),
INTC_IRQ(PINT6, 86), INTC_IRQ(PINT7, 87),
- INTC_IRQ(DMAC0_DEI, 108), INTC_IRQ(DMAC0_HEI, 109),
- INTC_IRQ(DMAC1_DEI, 112), INTC_IRQ(DMAC1_HEI, 113),
- INTC_IRQ(DMAC2_DEI, 116), INTC_IRQ(DMAC2_HEI, 117),
- INTC_IRQ(DMAC3_DEI, 120), INTC_IRQ(DMAC3_HEI, 121),
- INTC_IRQ(DMAC4_DEI, 124), INTC_IRQ(DMAC4_HEI, 125),
- INTC_IRQ(DMAC5_DEI, 128), INTC_IRQ(DMAC5_HEI, 129),
- INTC_IRQ(DMAC6_DEI, 132), INTC_IRQ(DMAC6_HEI, 133),
- INTC_IRQ(DMAC7_DEI, 136), INTC_IRQ(DMAC7_HEI, 137),
+ INTC_IRQ(DMAC0, 108), INTC_IRQ(DMAC0, 109),
+ INTC_IRQ(DMAC1, 112), INTC_IRQ(DMAC1, 113),
+ INTC_IRQ(DMAC2, 116), INTC_IRQ(DMAC2, 117),
+ INTC_IRQ(DMAC3, 120), INTC_IRQ(DMAC3, 121),
+ INTC_IRQ(DMAC4, 124), INTC_IRQ(DMAC4, 125),
+ INTC_IRQ(DMAC5, 128), INTC_IRQ(DMAC5, 129),
+ INTC_IRQ(DMAC6, 132), INTC_IRQ(DMAC6, 133),
+ INTC_IRQ(DMAC7, 136), INTC_IRQ(DMAC7, 137),
INTC_IRQ(USB, 140), INTC_IRQ(LCDC, 141),
INTC_IRQ(CMT0, 142), INTC_IRQ(CMT1, 143),
INTC_IRQ(BSC, 144), INTC_IRQ(WDT, 145),
- INTC_IRQ(MTU2_TGI0A, 146), INTC_IRQ(MTU2_TGI0B, 147),
- INTC_IRQ(MTU2_TGI0C, 148), INTC_IRQ(MTU2_TGI0D, 149),
- INTC_IRQ(MTU2_TCI0V, 150),
- INTC_IRQ(MTU2_TGI0E, 151), INTC_IRQ(MTU2_TGI0F, 152),
- INTC_IRQ(MTU2_TGI1A, 153), INTC_IRQ(MTU2_TGI1B, 154),
- INTC_IRQ(MTU2_TCI1V, 155), INTC_IRQ(MTU2_TCI1U, 156),
- INTC_IRQ(MTU2_TGI2A, 157), INTC_IRQ(MTU2_TGI2B, 158),
- INTC_IRQ(MTU2_TCI2V, 159), INTC_IRQ(MTU2_TCI2U, 160),
- INTC_IRQ(MTU2_TGI3A, 161), INTC_IRQ(MTU2_TGI3B, 162),
- INTC_IRQ(MTU2_TGI3C, 163), INTC_IRQ(MTU2_TGI3D, 164),
+ INTC_IRQ(MTU0_ABCD, 146), INTC_IRQ(MTU0_ABCD, 147),
+ INTC_IRQ(MTU0_ABCD, 148), INTC_IRQ(MTU0_ABCD, 149),
+ INTC_IRQ(MTU0_VEF, 150),
+ INTC_IRQ(MTU0_VEF, 151), INTC_IRQ(MTU0_VEF, 152),
+ INTC_IRQ(MTU1_AB, 153), INTC_IRQ(MTU1_AB, 154),
+ INTC_IRQ(MTU1_VU, 155), INTC_IRQ(MTU1_VU, 156),
+ INTC_IRQ(MTU2_AB, 157), INTC_IRQ(MTU2_AB, 158),
+ INTC_IRQ(MTU2_VU, 159), INTC_IRQ(MTU2_VU, 160),
+ INTC_IRQ(MTU3_ABCD, 161), INTC_IRQ(MTU3_ABCD, 162),
+ INTC_IRQ(MTU3_ABCD, 163), INTC_IRQ(MTU3_ABCD, 164),
INTC_IRQ(MTU2_TCI3V, 165),
- INTC_IRQ(MTU2_TGI4A, 166), INTC_IRQ(MTU2_TGI4B, 167),
- INTC_IRQ(MTU2_TGI4C, 168), INTC_IRQ(MTU2_TGI4D, 169),
+ INTC_IRQ(MTU4_ABCD, 166), INTC_IRQ(MTU4_ABCD, 167),
+ INTC_IRQ(MTU4_ABCD, 168), INTC_IRQ(MTU4_ABCD, 169),
INTC_IRQ(MTU2_TCI4V, 170),
INTC_IRQ(ADC_ADI, 171),
- INTC_IRQ(IIC30_STPI, 172), INTC_IRQ(IIC30_NAKI, 173),
- INTC_IRQ(IIC30_RXI, 174), INTC_IRQ(IIC30_TXI, 175),
- INTC_IRQ(IIC30_TEI, 176),
- INTC_IRQ(IIC31_STPI, 177), INTC_IRQ(IIC31_NAKI, 178),
- INTC_IRQ(IIC31_RXI, 179), INTC_IRQ(IIC31_TXI, 180),
- INTC_IRQ(IIC31_TEI, 181),
- INTC_IRQ(IIC32_STPI, 182), INTC_IRQ(IIC32_NAKI, 183),
- INTC_IRQ(IIC32_RXI, 184), INTC_IRQ(IIC32_TXI, 185),
- INTC_IRQ(IIC32_TEI, 186),
- INTC_IRQ(IIC33_STPI, 187), INTC_IRQ(IIC33_NAKI, 188),
- INTC_IRQ(IIC33_RXI, 189), INTC_IRQ(IIC33_TXI, 190),
- INTC_IRQ(IIC33_TEI, 191),
- INTC_IRQ(SCIF0_BRI, 192), INTC_IRQ(SCIF0_ERI, 193),
- INTC_IRQ(SCIF0_RXI, 194), INTC_IRQ(SCIF0_TXI, 195),
- INTC_IRQ(SCIF1_BRI, 196), INTC_IRQ(SCIF1_ERI, 197),
- INTC_IRQ(SCIF1_RXI, 198), INTC_IRQ(SCIF1_TXI, 199),
- INTC_IRQ(SCIF2_BRI, 200), INTC_IRQ(SCIF2_ERI, 201),
- INTC_IRQ(SCIF2_RXI, 202), INTC_IRQ(SCIF2_TXI, 203),
- INTC_IRQ(SCIF3_BRI, 204), INTC_IRQ(SCIF3_ERI, 205),
- INTC_IRQ(SCIF3_RXI, 206), INTC_IRQ(SCIF3_TXI, 207),
- INTC_IRQ(SSU0_SSERI, 208), INTC_IRQ(SSU0_SSRXI, 209),
- INTC_IRQ(SSU0_SSTXI, 210),
- INTC_IRQ(SSU1_SSERI, 211), INTC_IRQ(SSU1_SSRXI, 212),
- INTC_IRQ(SSU1_SSTXI, 213),
+ INTC_IRQ(IIC30, 172), INTC_IRQ(IIC30, 173),
+ INTC_IRQ(IIC30, 174), INTC_IRQ(IIC30, 175),
+ INTC_IRQ(IIC30, 176),
+ INTC_IRQ(IIC31, 177), INTC_IRQ(IIC31, 178),
+ INTC_IRQ(IIC31, 179), INTC_IRQ(IIC31, 180),
+ INTC_IRQ(IIC31, 181),
+ INTC_IRQ(IIC32, 182), INTC_IRQ(IIC32, 183),
+ INTC_IRQ(IIC32, 184), INTC_IRQ(IIC32, 185),
+ INTC_IRQ(IIC32, 186),
+ INTC_IRQ(IIC33, 187), INTC_IRQ(IIC33, 188),
+ INTC_IRQ(IIC33, 189), INTC_IRQ(IIC33, 190),
+ INTC_IRQ(IIC33, 191),
+ INTC_IRQ(SCIF0, 192), INTC_IRQ(SCIF0, 193),
+ INTC_IRQ(SCIF0, 194), INTC_IRQ(SCIF0, 195),
+ INTC_IRQ(SCIF1, 196), INTC_IRQ(SCIF1, 197),
+ INTC_IRQ(SCIF1, 198), INTC_IRQ(SCIF1, 199),
+ INTC_IRQ(SCIF2, 200), INTC_IRQ(SCIF2, 201),
+ INTC_IRQ(SCIF2, 202), INTC_IRQ(SCIF2, 203),
+ INTC_IRQ(SCIF3, 204), INTC_IRQ(SCIF3, 205),
+ INTC_IRQ(SCIF3, 206), INTC_IRQ(SCIF3, 207),
+ INTC_IRQ(SSU0, 208), INTC_IRQ(SSU0, 209),
+ INTC_IRQ(SSU0, 210),
+ INTC_IRQ(SSU1, 211), INTC_IRQ(SSU1, 212),
+ INTC_IRQ(SSU1, 213),
INTC_IRQ(SSI0_SSII, 214), INTC_IRQ(SSI1_SSII, 215),
INTC_IRQ(SSI2_SSII, 216), INTC_IRQ(SSI3_SSII, 217),
- INTC_IRQ(FLCTL_FLSTEI, 224), INTC_IRQ(FLCTL_FLTENDI, 225),
- INTC_IRQ(FLCTL_FLTREQ0I, 226), INTC_IRQ(FLCTL_FLTREQ1I, 227),
- INTC_IRQ(RTC_ARM, 231), INTC_IRQ(RTC_PRD, 232),
- INTC_IRQ(RTC_CUP, 233),
- INTC_IRQ(RCAN0_ERS, 234), INTC_IRQ(RCAN0_OVR, 235),
- INTC_IRQ(RCAN0_RM0, 236), INTC_IRQ(RCAN0_RM1, 237),
- INTC_IRQ(RCAN0_SLE, 238),
- INTC_IRQ(RCAN1_ERS, 239), INTC_IRQ(RCAN1_OVR, 240),
- INTC_IRQ(RCAN1_RM0, 241), INTC_IRQ(RCAN1_RM1, 242),
- INTC_IRQ(RCAN1_SLE, 243),
+ INTC_IRQ(FLCTL, 224), INTC_IRQ(FLCTL, 225),
+ INTC_IRQ(FLCTL, 226), INTC_IRQ(FLCTL, 227),
+ INTC_IRQ(RTC, 231), INTC_IRQ(RTC, 232),
+ INTC_IRQ(RTC, 233),
+ INTC_IRQ(RCAN0, 234), INTC_IRQ(RCAN0, 235),
+ INTC_IRQ(RCAN0, 236), INTC_IRQ(RCAN0, 237),
+ INTC_IRQ(RCAN0, 238),
+ INTC_IRQ(RCAN1, 239), INTC_IRQ(RCAN1, 240),
+ INTC_IRQ(RCAN1, 241), INTC_IRQ(RCAN1, 242),
+ INTC_IRQ(RCAN1, 243),
/* SH7263-specific trash */
#ifdef CONFIG_CPU_SUBTYPE_SH7263
- INTC_IRQ(ROMDEC_ISY, 218), INTC_IRQ(ROMDEC_IERR, 219),
- INTC_IRQ(ROMDEC_IARG, 220), INTC_IRQ(ROMDEC_ISEC, 221),
- INTC_IRQ(ROMDEC_IBUF, 222), INTC_IRQ(ROMDEC_IREADY, 223),
+ INTC_IRQ(ROMDEC, 218), INTC_IRQ(ROMDEC, 219),
+ INTC_IRQ(ROMDEC, 220), INTC_IRQ(ROMDEC, 221),
+ INTC_IRQ(ROMDEC, 222), INTC_IRQ(ROMDEC, 223),
- INTC_IRQ(SDHI3, 228), INTC_IRQ(SDHI0, 229), INTC_IRQ(SDHI1, 230),
+ INTC_IRQ(SDHI, 228), INTC_IRQ(SDHI, 229),
+ INTC_IRQ(SDHI, 230),
- INTC_IRQ(SRC_OVF, 244), INTC_IRQ(SRC_ODFI, 245),
- INTC_IRQ(SRC_IDEI, 246),
+ INTC_IRQ(SRC, 244), INTC_IRQ(SRC, 245),
+ INTC_IRQ(SRC, 246),
INTC_IRQ(IEBI, 247),
#endif
@@ -154,50 +132,6 @@ static struct intc_vect vectors[] __initdata = {
static struct intc_group groups[] __initdata = {
INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
PINT4, PINT5, PINT6, PINT7),
- INTC_GROUP(DMAC0, DMAC0_DEI, DMAC0_HEI),
- INTC_GROUP(DMAC1, DMAC1_DEI, DMAC1_HEI),
- INTC_GROUP(DMAC2, DMAC2_DEI, DMAC2_HEI),
- INTC_GROUP(DMAC3, DMAC3_DEI, DMAC3_HEI),
- INTC_GROUP(DMAC4, DMAC4_DEI, DMAC4_HEI),
- INTC_GROUP(DMAC5, DMAC5_DEI, DMAC5_HEI),
- INTC_GROUP(DMAC6, DMAC6_DEI, DMAC6_HEI),
- INTC_GROUP(DMAC7, DMAC7_DEI, DMAC7_HEI),
- INTC_GROUP(MTU0_ABCD, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D),
- INTC_GROUP(MTU0_VEF, MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F),
- INTC_GROUP(MTU1_AB, MTU2_TGI1A, MTU2_TGI1B),
- INTC_GROUP(MTU1_VU, MTU2_TCI1V, MTU2_TCI1U),
- INTC_GROUP(MTU2_AB, MTU2_TGI2A, MTU2_TGI2B),
- INTC_GROUP(MTU2_VU, MTU2_TCI2V, MTU2_TCI2U),
- INTC_GROUP(MTU3_ABCD, MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D),
- INTC_GROUP(MTU4_ABCD, MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
- INTC_GROUP(IIC30, IIC30_STPI, IIC30_NAKI, IIC30_RXI, IIC30_TXI,
- IIC30_TEI),
- INTC_GROUP(IIC31, IIC31_STPI, IIC31_NAKI, IIC31_RXI, IIC31_TXI,
- IIC31_TEI),
- INTC_GROUP(IIC32, IIC32_STPI, IIC32_NAKI, IIC32_RXI, IIC32_TXI,
- IIC32_TEI),
- INTC_GROUP(IIC33, IIC33_STPI, IIC33_NAKI, IIC33_RXI, IIC33_TXI,
- IIC33_TEI),
- INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
- INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
- INTC_GROUP(SCIF2, SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
- INTC_GROUP(SCIF3, SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI),
- INTC_GROUP(SSU0, SSU0_SSERI, SSU0_SSRXI, SSU0_SSTXI),
- INTC_GROUP(SSU1, SSU1_SSERI, SSU1_SSRXI, SSU1_SSTXI),
- INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I,
- FLCTL_FLTREQ1I),
- INTC_GROUP(RTC, RTC_ARM, RTC_PRD, RTC_CUP),
- INTC_GROUP(RCAN0, RCAN0_ERS, RCAN0_OVR, RCAN0_RM0, RCAN0_RM1,
- RCAN0_SLE),
- INTC_GROUP(RCAN1, RCAN1_ERS, RCAN1_OVR, RCAN1_RM0, RCAN1_RM1,
- RCAN1_SLE),
-
-#ifdef CONFIG_CPU_SUBTYPE_SH7263
- INTC_GROUP(ROMDEC, ROMDEC_ISY, ROMDEC_IERR, ROMDEC_IARG,
- ROMDEC_ISEC, ROMDEC_IBUF, ROMDEC_IREADY),
- INTC_GROUP(SDHI, SDHI3, SDHI0, SDHI1),
- INTC_GROUP(SRC, SRC_OVF, SRC_ODFI, SRC_IDEI),
-#endif
};
static struct intc_prio_reg prio_registers[] __initdata = {
@@ -242,22 +176,22 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xfffe8000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 193, 194, 195, 192 },
+ .irqs = { 192, 192, 192, 192 },
}, {
.mapbase = 0xfffe8800,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 197, 198, 199, 196 },
+ .irqs = { 196, 196, 196, 196 },
}, {
.mapbase = 0xfffe9000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 201, 202, 203, 200 },
+ .irqs = { 200, 200, 200, 200 },
}, {
.mapbase = 0xfffe9800,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 205, 206, 207, 204 },
+ .irqs = { 204, 204, 204, 204 },
}, {
.flags = 0,
}
@@ -278,17 +212,7 @@ static struct resource rtc_resources[] = {
.flags = IORESOURCE_IO,
},
[1] = {
- /* Period IRQ */
- .start = 232,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- /* Carry IRQ */
- .start = 233,
- .flags = IORESOURCE_IRQ,
- },
- [3] = {
- /* Alarm IRQ */
+ /* Shared Period/Carry/Alarm IRQ */
.start = 231,
.flags = IORESOURCE_IRQ,
},
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
index e6d4ec445dd8..c46a8355726d 100644
--- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
+++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c
@@ -2,6 +2,7 @@
* SH7206 Setup
*
* Copyright (C) 2006 Yoshinori Sato
+ * Copyright (C) 2009 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -19,34 +20,23 @@ enum {
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
PINT0, PINT1, PINT2, PINT3, PINT4, PINT5, PINT6, PINT7,
ADC_ADI0, ADC_ADI1,
- DMAC0_DEI, DMAC0_HEI, DMAC1_DEI, DMAC1_HEI,
- DMAC2_DEI, DMAC2_HEI, DMAC3_DEI, DMAC3_HEI,
- DMAC4_DEI, DMAC4_HEI, DMAC5_DEI, DMAC5_HEI,
- DMAC6_DEI, DMAC6_HEI, DMAC7_DEI, DMAC7_HEI,
+
+ DMAC0, DMAC1, DMAC2, DMAC3, DMAC4, DMAC5, DMAC6, DMAC7,
+
+ MTU0_ABCD, MTU0_VEF, MTU1_AB, MTU1_VU, MTU2_AB, MTU2_VU,
+ MTU3_ABCD, MTU4_ABCD, MTU5, POE2_12, MTU3S_ABCD, MTU4S_ABCD, MTU5S,
+ IIC3,
+
CMT0, CMT1, BSC, WDT,
- MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D,
- MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F,
- MTU2_TGI1A, MTU2_TGI1B, MTU2_TCI1V, MTU2_TCI1U,
- MTU2_TGI2A, MTU2_TGI2B, MTU2_TCI2V, MTU2_TCI2U,
- MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D, MTU2_TCI3V,
- MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D, MTU2_TCI4V,
- MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W,
- POE2_OEI1, POE2_OEI2,
- MTU2S_TGI3A, MTU2S_TGI3B, MTU2S_TGI3C, MTU2S_TGI3D, MTU2S_TCI3V,
- MTU2S_TGI4A, MTU2S_TGI4B, MTU2S_TGI4C, MTU2S_TGI4D, MTU2S_TCI4V,
- MTU2S_TGI5U, MTU2S_TGI5V, MTU2S_TGI5W,
+
+ MTU2_TCI3V, MTU2_TCI4V, MTU2S_TCI3V, MTU2S_TCI4V,
+
POE2_OEI3,
- IIC3_STPI, IIC3_NAKI, IIC3_RXI, IIC3_TXI, IIC3_TEI,
- SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
- SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI,
- SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
- SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI,
+
+ SCIF0, SCIF1, SCIF2, SCIF3,
/* interrupt groups */
- PINT, DMAC0, DMAC1, DMAC2, DMAC3, DMAC4, DMAC5, DMAC6, DMAC7,
- MTU0_ABCD, MTU0_VEF, MTU1_AB, MTU1_VU, MTU2_AB, MTU2_VU,
- MTU3_ABCD, MTU4_ABCD, MTU5, POE2_12, MTU3S_ABCD, MTU4S_ABCD, MTU5S,
- IIC3, SCIF0, SCIF1, SCIF2, SCIF3,
+ PINT,
};
static struct intc_vect vectors[] __initdata = {
@@ -59,86 +49,58 @@ static struct intc_vect vectors[] __initdata = {
INTC_IRQ(PINT4, 84), INTC_IRQ(PINT5, 85),
INTC_IRQ(PINT6, 86), INTC_IRQ(PINT7, 87),
INTC_IRQ(ADC_ADI0, 92), INTC_IRQ(ADC_ADI1, 96),
- INTC_IRQ(DMAC0_DEI, 108), INTC_IRQ(DMAC0_HEI, 109),
- INTC_IRQ(DMAC1_DEI, 112), INTC_IRQ(DMAC1_HEI, 113),
- INTC_IRQ(DMAC2_DEI, 116), INTC_IRQ(DMAC2_HEI, 117),
- INTC_IRQ(DMAC3_DEI, 120), INTC_IRQ(DMAC3_HEI, 121),
- INTC_IRQ(DMAC4_DEI, 124), INTC_IRQ(DMAC4_HEI, 125),
- INTC_IRQ(DMAC5_DEI, 128), INTC_IRQ(DMAC5_HEI, 129),
- INTC_IRQ(DMAC6_DEI, 132), INTC_IRQ(DMAC6_HEI, 133),
- INTC_IRQ(DMAC7_DEI, 136), INTC_IRQ(DMAC7_HEI, 137),
+ INTC_IRQ(DMAC0, 108), INTC_IRQ(DMAC0, 109),
+ INTC_IRQ(DMAC1, 112), INTC_IRQ(DMAC1, 113),
+ INTC_IRQ(DMAC2, 116), INTC_IRQ(DMAC2, 117),
+ INTC_IRQ(DMAC3, 120), INTC_IRQ(DMAC3, 121),
+ INTC_IRQ(DMAC4, 124), INTC_IRQ(DMAC4, 125),
+ INTC_IRQ(DMAC5, 128), INTC_IRQ(DMAC5, 129),
+ INTC_IRQ(DMAC6, 132), INTC_IRQ(DMAC6, 133),
+ INTC_IRQ(DMAC7, 136), INTC_IRQ(DMAC7, 137),
INTC_IRQ(CMT0, 140), INTC_IRQ(CMT1, 144),
INTC_IRQ(BSC, 148), INTC_IRQ(WDT, 152),
- INTC_IRQ(MTU2_TGI0A, 156), INTC_IRQ(MTU2_TGI0B, 157),
- INTC_IRQ(MTU2_TGI0C, 158), INTC_IRQ(MTU2_TGI0D, 159),
- INTC_IRQ(MTU2_TCI0V, 160),
- INTC_IRQ(MTU2_TGI0E, 161), INTC_IRQ(MTU2_TGI0F, 162),
- INTC_IRQ(MTU2_TGI1A, 164), INTC_IRQ(MTU2_TGI1B, 165),
- INTC_IRQ(MTU2_TCI1V, 168), INTC_IRQ(MTU2_TCI1U, 169),
- INTC_IRQ(MTU2_TGI2A, 172), INTC_IRQ(MTU2_TGI2B, 173),
- INTC_IRQ(MTU2_TCI2V, 176), INTC_IRQ(MTU2_TCI2U, 177),
- INTC_IRQ(MTU2_TGI3A, 180), INTC_IRQ(MTU2_TGI3B, 181),
- INTC_IRQ(MTU2_TGI3C, 182), INTC_IRQ(MTU2_TGI3D, 183),
+ INTC_IRQ(MTU0_ABCD, 156), INTC_IRQ(MTU0_ABCD, 157),
+ INTC_IRQ(MTU0_ABCD, 158), INTC_IRQ(MTU0_ABCD, 159),
+ INTC_IRQ(MTU0_VEF, 160), INTC_IRQ(MTU0_VEF, 161),
+ INTC_IRQ(MTU0_VEF, 162),
+ INTC_IRQ(MTU1_AB, 164), INTC_IRQ(MTU1_AB, 165),
+ INTC_IRQ(MTU1_VU, 168), INTC_IRQ(MTU1_VU, 169),
+ INTC_IRQ(MTU2_AB, 172), INTC_IRQ(MTU2_AB, 173),
+ INTC_IRQ(MTU2_VU, 176), INTC_IRQ(MTU2_VU, 177),
+ INTC_IRQ(MTU3_ABCD, 180), INTC_IRQ(MTU3_ABCD, 181),
+ INTC_IRQ(MTU3_ABCD, 182), INTC_IRQ(MTU3_ABCD, 183),
INTC_IRQ(MTU2_TCI3V, 184),
- INTC_IRQ(MTU2_TGI4A, 188), INTC_IRQ(MTU2_TGI4B, 189),
- INTC_IRQ(MTU2_TGI4C, 190), INTC_IRQ(MTU2_TGI4D, 191),
+ INTC_IRQ(MTU4_ABCD, 188), INTC_IRQ(MTU4_ABCD, 189),
+ INTC_IRQ(MTU4_ABCD, 190), INTC_IRQ(MTU4_ABCD, 191),
INTC_IRQ(MTU2_TCI4V, 192),
- INTC_IRQ(MTU2_TGI5U, 196), INTC_IRQ(MTU2_TGI5V, 197),
- INTC_IRQ(MTU2_TGI5W, 198),
- INTC_IRQ(POE2_OEI1, 200), INTC_IRQ(POE2_OEI2, 201),
- INTC_IRQ(MTU2S_TGI3A, 204), INTC_IRQ(MTU2S_TGI3B, 205),
- INTC_IRQ(MTU2S_TGI3C, 206), INTC_IRQ(MTU2S_TGI3D, 207),
+ INTC_IRQ(MTU5, 196), INTC_IRQ(MTU5, 197),
+ INTC_IRQ(MTU5, 198),
+ INTC_IRQ(POE2_12, 200), INTC_IRQ(POE2_12, 201),
+ INTC_IRQ(MTU3S_ABCD, 204), INTC_IRQ(MTU3S_ABCD, 205),
+ INTC_IRQ(MTU3S_ABCD, 206), INTC_IRQ(MTU3S_ABCD, 207),
INTC_IRQ(MTU2S_TCI3V, 208),
- INTC_IRQ(MTU2S_TGI4A, 212), INTC_IRQ(MTU2S_TGI4B, 213),
- INTC_IRQ(MTU2S_TGI4C, 214), INTC_IRQ(MTU2S_TGI4D, 215),
+ INTC_IRQ(MTU4S_ABCD, 212), INTC_IRQ(MTU4S_ABCD, 213),
+ INTC_IRQ(MTU4S_ABCD, 214), INTC_IRQ(MTU4S_ABCD, 215),
INTC_IRQ(MTU2S_TCI4V, 216),
- INTC_IRQ(MTU2S_TGI5U, 220), INTC_IRQ(MTU2S_TGI5V, 221),
- INTC_IRQ(MTU2S_TGI5W, 222),
+ INTC_IRQ(MTU5S, 220), INTC_IRQ(MTU5S, 221),
+ INTC_IRQ(MTU5S, 222),
INTC_IRQ(POE2_OEI3, 224),
- INTC_IRQ(IIC3_STPI, 228), INTC_IRQ(IIC3_NAKI, 229),
- INTC_IRQ(IIC3_RXI, 230), INTC_IRQ(IIC3_TXI, 231),
- INTC_IRQ(IIC3_TEI, 232),
- INTC_IRQ(SCIF0_BRI, 240), INTC_IRQ(SCIF0_ERI, 241),
- INTC_IRQ(SCIF0_RXI, 242), INTC_IRQ(SCIF0_TXI, 243),
- INTC_IRQ(SCIF1_BRI, 244), INTC_IRQ(SCIF1_ERI, 245),
- INTC_IRQ(SCIF1_RXI, 246), INTC_IRQ(SCIF1_TXI, 247),
- INTC_IRQ(SCIF2_BRI, 248), INTC_IRQ(SCIF2_ERI, 249),
- INTC_IRQ(SCIF2_RXI, 250), INTC_IRQ(SCIF2_TXI, 251),
- INTC_IRQ(SCIF3_BRI, 252), INTC_IRQ(SCIF3_ERI, 253),
- INTC_IRQ(SCIF3_RXI, 254), INTC_IRQ(SCIF3_TXI, 255),
+ INTC_IRQ(IIC3, 228), INTC_IRQ(IIC3, 229),
+ INTC_IRQ(IIC3, 230), INTC_IRQ(IIC3, 231),
+ INTC_IRQ(IIC3, 232),
+ INTC_IRQ(SCIF0, 240), INTC_IRQ(SCIF0, 241),
+ INTC_IRQ(SCIF0, 242), INTC_IRQ(SCIF0, 243),
+ INTC_IRQ(SCIF1, 244), INTC_IRQ(SCIF1, 245),
+ INTC_IRQ(SCIF1, 246), INTC_IRQ(SCIF1, 247),
+ INTC_IRQ(SCIF2, 248), INTC_IRQ(SCIF2, 249),
+ INTC_IRQ(SCIF2, 250), INTC_IRQ(SCIF2, 251),
+ INTC_IRQ(SCIF3, 252), INTC_IRQ(SCIF3, 253),
+ INTC_IRQ(SCIF3, 254), INTC_IRQ(SCIF3, 255),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(PINT, PINT0, PINT1, PINT2, PINT3,
PINT4, PINT5, PINT6, PINT7),
- INTC_GROUP(DMAC0, DMAC0_DEI, DMAC0_HEI),
- INTC_GROUP(DMAC1, DMAC1_DEI, DMAC1_HEI),
- INTC_GROUP(DMAC2, DMAC2_DEI, DMAC2_HEI),
- INTC_GROUP(DMAC3, DMAC3_DEI, DMAC3_HEI),
- INTC_GROUP(DMAC4, DMAC4_DEI, DMAC4_HEI),
- INTC_GROUP(DMAC5, DMAC5_DEI, DMAC5_HEI),
- INTC_GROUP(DMAC6, DMAC6_DEI, DMAC6_HEI),
- INTC_GROUP(DMAC7, DMAC7_DEI, DMAC7_HEI),
- INTC_GROUP(MTU0_ABCD, MTU2_TGI0A, MTU2_TGI0B, MTU2_TGI0C, MTU2_TGI0D),
- INTC_GROUP(MTU0_VEF, MTU2_TCI0V, MTU2_TGI0E, MTU2_TGI0F),
- INTC_GROUP(MTU1_AB, MTU2_TGI1A, MTU2_TGI1B),
- INTC_GROUP(MTU1_VU, MTU2_TCI1V, MTU2_TCI1U),
- INTC_GROUP(MTU2_AB, MTU2_TGI2A, MTU2_TGI2B),
- INTC_GROUP(MTU2_VU, MTU2_TCI2V, MTU2_TCI2U),
- INTC_GROUP(MTU3_ABCD, MTU2_TGI3A, MTU2_TGI3B, MTU2_TGI3C, MTU2_TGI3D),
- INTC_GROUP(MTU4_ABCD, MTU2_TGI4A, MTU2_TGI4B, MTU2_TGI4C, MTU2_TGI4D),
- INTC_GROUP(MTU5, MTU2_TGI5U, MTU2_TGI5V, MTU2_TGI5W),
- INTC_GROUP(POE2_12, POE2_OEI1, POE2_OEI2),
- INTC_GROUP(MTU3S_ABCD, MTU2S_TGI3A, MTU2S_TGI3B,
- MTU2S_TGI3C, MTU2S_TGI3D),
- INTC_GROUP(MTU4S_ABCD, MTU2S_TGI4A, MTU2S_TGI4B,
- MTU2S_TGI4C, MTU2S_TGI4D),
- INTC_GROUP(MTU5S, MTU2S_TGI5U, MTU2S_TGI5V, MTU2S_TGI5W),
- INTC_GROUP(IIC3, IIC3_STPI, IIC3_NAKI, IIC3_RXI, IIC3_TXI, IIC3_TEI),
- INTC_GROUP(SCIF0, SCIF0_BRI, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
- INTC_GROUP(SCIF1, SCIF1_BRI, SCIF1_ERI, SCIF1_RXI, SCIF1_TXI),
- INTC_GROUP(SCIF2, SCIF2_BRI, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
- INTC_GROUP(SCIF3, SCIF3_BRI, SCIF3_ERI, SCIF3_RXI, SCIF3_TXI),
};
static struct intc_prio_reg prio_registers[] __initdata = {
@@ -174,22 +136,22 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xfffe8000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 241, 242, 243, 240 },
+ .irqs = { 240, 240, 240, 240 },
}, {
.mapbase = 0xfffe8800,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 245, 246, 247, 244 },
+ .irqs = { 244, 244, 244, 244 },
}, {
.mapbase = 0xfffe9000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 249, 250, 251, 248 },
+ .irqs = { 248, 248, 248, 248 },
}, {
.mapbase = 0xfffe9800,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 253, 254, 255, 252 },
+ .irqs = { 252, 252, 252, 252 },
}, {
.flags = 0,
}
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile
index e07c69e16d9b..ecab274141a8 100644
--- a/arch/sh/kernel/cpu/sh3/Makefile
+++ b/arch/sh/kernel/cpu/sh3/Makefile
@@ -4,6 +4,8 @@
obj-y := ex.o probe.o entry.o setup-sh3.o
+obj-$(CONFIG_HIBERNATION) += swsusp.o
+
# CPU subtype setup
obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o
obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh770x.o
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index b4106d0c68ec..3cb531f233f2 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -16,6 +16,7 @@
#include <asm/unistd.h>
#include <cpu/mmu_context.h>
#include <asm/page.h>
+#include <asm/cache.h>
! NOTE:
! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
@@ -187,44 +188,35 @@ call_dae:
#if defined(CONFIG_SH_STANDARD_BIOS)
/* Unwind the stack and jmp to the debug entry */
ENTRY(sh_bios_handler)
- mov.l @r15+, r0
- mov.l @r15+, r1
- mov.l @r15+, r2
- mov.l @r15+, r3
- mov.l @r15+, r4
- mov.l @r15+, r5
- mov.l @r15+, r6
- mov.l @r15+, r7
- stc sr, r8
- mov.l 1f, r9 ! BL =1, RB=1, IMASK=0x0F
- or r9, r8
- ldc r8, sr ! here, change the register bank
- mov.l @r15+, r8
- mov.l @r15+, r9
- mov.l @r15+, r10
- mov.l @r15+, r11
- mov.l @r15+, r12
- mov.l @r15+, r13
- mov.l @r15+, r14
- mov.l @r15+, k0
- ldc.l @r15+, spc
- lds.l @r15+, pr
- mov.l @r15+, k1
- ldc.l @r15+, gbr
- lds.l @r15+, mach
- lds.l @r15+, macl
- mov k0, r15
+ mov.l 1f, r8
+ bsr restore_regs
+ nop
+
+ lds k2, pr ! restore pr
+ mov k4, r15
!
mov.l 2f, k0
mov.l @k0, k0
jmp @k0
- ldc k1, ssr
+ ldc k3, ssr
.align 2
1: .long 0x300000f0
2: .long gdb_vbr_vector
#endif /* CONFIG_SH_STANDARD_BIOS */
-restore_all:
+! restore_regs()
+! - restore r0, r1, r2, r3, r4, r5, r6, r7 from the stack
+! - switch bank
+! - restore r8, r9, r10, r11, r12, r13, r14, r15 from the stack
+! - restore spc, pr*, ssr, gbr, mach, macl, skip default tra
+! k2 returns original pr
+! k3 returns original sr
+! k4 returns original stack pointer
+! r8 passes SR bitmask, overwritten with restored data on return
+! r9 trashed
+! BL=0 on entry, on exit BL=1 (depending on r8).
+
+ENTRY(restore_regs)
mov.l @r15+, r0
mov.l @r15+, r1
mov.l @r15+, r2
@@ -234,10 +226,9 @@ restore_all:
mov.l @r15+, r6
mov.l @r15+, r7
!
- stc sr, r8
- mov.l 7f, r9
- or r9, r8 ! BL =1, RB=1
- ldc r8, sr ! here, change the register bank
+ stc sr, r9
+ or r8, r9
+ ldc r9, sr
!
mov.l @r15+, r8
mov.l @r15+, r9
@@ -248,53 +239,27 @@ restore_all:
mov.l @r15+, r14
mov.l @r15+, k4 ! original stack pointer
ldc.l @r15+, spc
- lds.l @r15+, pr
+ mov.l @r15+, k2 ! original PR
mov.l @r15+, k3 ! original SR
ldc.l @r15+, gbr
lds.l @r15+, mach
lds.l @r15+, macl
- add #4, r15 ! Skip syscall number
- !
-#ifdef CONFIG_SH_DSP
- mov.l @r15+, k0 ! DSP mode marker
- mov.l 5f, k1
- cmp/eq k0, k1 ! Do we have a DSP stack frame?
- bf skip_restore
-
- stc sr, k0 ! Enable CPU DSP mode
- or k1, k0 ! (within kernel it may be disabled)
- ldc k0, sr
- mov r2, k0 ! Backup r2
-
- ! Restore DSP registers from stack
- mov r15, r2
- movs.l @r2+, a1
- movs.l @r2+, a0g
- movs.l @r2+, a1g
- movs.l @r2+, m0
- movs.l @r2+, m1
- mov r2, r15
-
- lds.l @r15+, a0
- lds.l @r15+, x0
- lds.l @r15+, x1
- lds.l @r15+, y0
- lds.l @r15+, y1
- lds.l @r15+, dsr
- ldc.l @r15+, rs
- ldc.l @r15+, re
- ldc.l @r15+, mod
-
- mov k0, r2 ! Restore r2
-skip_restore:
-#endif
+ rts
+ add #4, r15 ! Skip syscall number
+
+restore_all:
+ mov.l 7f, r8
+ bsr restore_regs
+ nop
+
+ lds k2, pr ! restore pr
!
! Calculate new SR value
mov k3, k2 ! original SR value
mov #0xf0, k1
extu.b k1, k1
not k1, k1
- and k1, k2 ! Mask orignal SR value
+ and k1, k2 ! Mask original SR value
!
mov k3, k0 ! Calculate IMASK-bits
shlr2 k0
@@ -313,7 +278,6 @@ skip_restore:
mov #0, k1
mov.b k1, @k0
#endif
- mov.l @r15+, k2 ! restore EXPEVT
mov k4, r15
rte
nop
@@ -336,81 +300,54 @@ skip_restore:
ENTRY(vbr_base)
.long 0
!
+! 0x100: General exception vector
+!
.balign 256,0,256
general_exception:
- mov.l 1f, k2
- mov.l 2f, k3
-#ifdef CONFIG_CPU_SUBTYPE_SHX3
- mov.l @k2, k2
+#ifndef CONFIG_CPU_SUBTYPE_SHX3
+ bra handle_exception
+ sts pr, k3 ! save original pr value in k3
+#else
+ mov.l 1f, k4
+ mov.l @k4, k4
! Is EXPEVT larger than 0x800?
mov #0x8, k0
shll8 k0
- cmp/hs k0, k2
+ cmp/hs k0, k4
bf 0f
! then add 0x580 (k2 is 0xd80 or 0xda0)
mov #0x58, k0
shll2 k0
shll2 k0
- add k0, k2
+ add k0, k4
0:
- bra handle_exception
+ ! Setup stack and save DSP context (k0 contains original r15 on return)
+ bsr prepare_stack
nop
-#else
- bra handle_exception
- mov.l @k2, k2
-#endif
- .align 2
-1: .long EXPEVT
-2: .long ret_from_exception
-!
-!
- .balign 1024,0,1024
-tlb_miss:
- mov.l 1f, k2
- mov.l 4f, k3
- bra handle_exception
- mov.l @k2, k2
-!
- .balign 512,0,512
-interrupt:
- mov.l 3f, k3
-#if defined(CONFIG_KGDB)
- mov.l 2f, k2
- ! Debounce (filter nested NMI)
- mov.l @k2, k0
- mov.l 5f, k1
- cmp/eq k1, k0
- bf 0f
- mov.l 6f, k1
- tas.b @k1
- bt 0f
- rte
+ ! Save registers / Switch to bank 0
+ mov k4, k2 ! keep vector in k2
+ mov.l 1f, k4 ! SR bits to clear in k4
+ bsr save_regs ! needs original pr value in k3
+ nop
+
+ bra handle_exception_special
nop
- .align 2
-2: .long INTEVT
-5: .long NMI_VEC
-6: .long in_nmi
-0:
-#endif /* defined(CONFIG_KGDB) */
- bra handle_exception
- mov #-1, k2 ! interrupt exception marker
.align 2
1: .long EXPEVT
-3: .long ret_from_irq
-4: .long ret_from_exception
+#endif
-!
-!
- .align 2
-ENTRY(handle_exception)
- ! Using k0, k1 for scratch registers (r0_bank1, r1_bank),
- ! save all registers onto stack.
- !
+! prepare_stack()
+! - roll back gRB
+! - switch to kernel stack
+! k0 returns original sp (after roll back)
+! k1 trashed
+! k2 trashed
+prepare_stack:
#ifdef CONFIG_GUSA
! Check for roll back gRB (User and Kernel)
mov r15, k0
@@ -430,7 +367,7 @@ ENTRY(handle_exception)
2: mov k1, r15 ! SP = r1
1:
#endif
-
+ ! Switch to kernel stack if needed
stc ssr, k0 ! Is it from kernel space?
shll k0 ! Check MD bit (bit30) by shifting it into...
shll k0 ! ...the T bit
@@ -443,65 +380,65 @@ ENTRY(handle_exception)
add current, k1
mov k1, r15 ! change to kernel stack
!
-1: mov.l 2f, k1
- !
-#ifdef CONFIG_SH_DSP
- mov.l r2, @-r15 ! Save r2, we need another reg
- stc sr, k4
- mov.l 1f, r2
- tst r2, k4 ! Check if in DSP mode
- mov.l @r15+, r2 ! Restore r2 now
- bt/s skip_save
- mov #0, k4 ! Set marker for no stack frame
-
- mov r2, k4 ! Backup r2 (in k4) for later
-
- ! Save DSP registers on stack
- stc.l mod, @-r15
- stc.l re, @-r15
- stc.l rs, @-r15
- sts.l dsr, @-r15
- sts.l y1, @-r15
- sts.l y0, @-r15
- sts.l x1, @-r15
- sts.l x0, @-r15
- sts.l a0, @-r15
-
- ! GAS is broken, does not generate correct "movs.l Ds,@-As" instr.
-
- ! FIXME: Make sure that this is still the case with newer toolchains,
- ! as we're not at all interested in supporting ancient toolchains at
- ! this point. -- PFM.
-
- mov r15, r2
- .word 0xf653 ! movs.l a1, @-r2
- .word 0xf6f3 ! movs.l a0g, @-r2
- .word 0xf6d3 ! movs.l a1g, @-r2
- .word 0xf6c3 ! movs.l m0, @-r2
- .word 0xf6e3 ! movs.l m1, @-r2
- mov r2, r15
-
- mov k4, r2 ! Restore r2
- mov.l 1f, k4 ! Force DSP stack frame
-skip_save:
- mov.l k4, @-r15 ! Push DSP mode marker onto stack
-#endif
- ! Save the user registers on the stack.
- mov.l k2, @-r15 ! EXPEVT
+1:
+ rts
+ nop
- mov #-1, k4
- mov.l k4, @-r15 ! set TRA (default: -1)
- !
+!
+! 0x400: Instruction and Data TLB miss exception vector
+!
+ .balign 1024,0,1024
+tlb_miss:
+ sts pr, k3 ! save original pr value in k3
+
+handle_exception:
+ mova exception_data, k0
+
+ ! Setup stack and save DSP context (k0 contains original r15 on return)
+ bsr prepare_stack
+ PREF(k0)
+
+ ! Save registers / Switch to bank 0
+ mov.l 5f, k2 ! vector register address
+ mov.l 1f, k4 ! SR bits to clear in k4
+ bsr save_regs ! needs original pr value in k3
+ mov.l @k2, k2 ! read out vector and keep in k2
+
+handle_exception_special:
+ ! Setup return address and jump to exception handler
+ mov.l 7f, r9 ! fetch return address
+ stc r2_bank, r0 ! k2 (vector)
+ mov.l 6f, r10
+ shlr2 r0
+ shlr r0
+ mov.l @(r0, r10), r10
+ jmp @r10
+ lds r9, pr ! put return address in pr
+
+ .align L1_CACHE_SHIFT
+
+! save_regs()
+! - save default tra, macl, mach, gbr, ssr, pr* and spc on the stack
+! - save r15*, r14, r13, r12, r11, r10, r9, r8 on the stack
+! - switch bank
+! - save r7, r6, r5, r4, r3, r2, r1, r0 on the stack
+! k0 contains original stack pointer*
+! k1 trashed
+! k3 passes original pr*
+! k4 passes SR bitmask
+! BL=1 on entry, on exit BL=0.
+
+ENTRY(save_regs)
+ mov #-1, r1
+ mov.l k1, @-r15 ! set TRA (default: -1)
sts.l macl, @-r15
sts.l mach, @-r15
stc.l gbr, @-r15
stc.l ssr, @-r15
- sts.l pr, @-r15
+ mov.l k3, @-r15 ! original pr in k3
stc.l spc, @-r15
- !
- lds k3, pr ! Set the return address to pr
- !
- mov.l k0, @-r15 ! save orignal stack
+
+ mov.l k0, @-r15 ! original stack pointer in k0
mov.l r14, @-r15
mov.l r13, @-r15
mov.l r12, @-r15
@@ -509,13 +446,23 @@ skip_save:
mov.l r10, @-r15
mov.l r9, @-r15
mov.l r8, @-r15
- !
- stc sr, r8 ! Back to normal register bank, and
- or k1, r8 ! Block all interrupts
- mov.l 3f, k1
- and k1, r8 ! ...
- ldc r8, sr ! ...changed here.
- !
+
+ mov.l 0f, k3 ! SR bits to set in k3
+
+ ! fall-through
+
+! save_low_regs()
+! - modify SR for bank switch
+! - save r7, r6, r5, r4, r3, r2, r1, r0 on the stack
+! k3 passes bits to set in SR
+! k4 passes bits to clear in SR
+
+ENTRY(save_low_regs)
+ stc sr, r8
+ or k3, r8
+ and k4, r8
+ ldc r8, sr
+
mov.l r7, @-r15
mov.l r6, @-r15
mov.l r5, @-r15
@@ -523,52 +470,63 @@ skip_save:
mov.l r3, @-r15
mov.l r2, @-r15
mov.l r1, @-r15
- mov.l r0, @-r15
-
- /*
- * This gets a bit tricky.. in the INTEVT case we don't want to use
- * the VBR offset as a destination in the jump call table, since all
- * of the destinations are the same. In this case, (interrupt) sets
- * a marker in r2 (now r2_bank since SR.RB changed), which we check
- * to determine the exception type. For all other exceptions, we
- * forcibly read EXPEVT from memory and fix up the jump address, in
- * the interrupt exception case we jump to do_IRQ() and defer the
- * INTEVT read until there. As a bonus, we can also clean up the SR.RB
- * checks that do_IRQ() was doing..
- */
- stc r2_bank, r8
- cmp/pz r8
- bf interrupt_exception
- shlr2 r8
- shlr r8
- mov.l 4f, r9
- add r8, r9
- mov.l @r9, r9
- jmp @r9
- nop
rts
- nop
+ mov.l r0, @-r15
+!
+! 0x600: Interrupt / NMI vector
+!
+ .balign 512,0,512
+ENTRY(handle_interrupt)
+#if defined(CONFIG_KGDB)
+ mov.l 2f, k2
+ ! Debounce (filter nested NMI)
+ mov.l @k2, k0
+ mov.l 9f, k1
+ cmp/eq k1, k0
+ bf 11f
+ mov.l 10f, k1
+ tas.b @k1
+ bt 11f
+ rte
+ nop
.align 2
-1: .long 0x00001000 ! DSP=1
-2: .long 0x000080f0 ! FD=1, IMASK=15
-3: .long 0xcfffffff ! RB=0, BL=0
-4: .long exception_handling_table
+9: .long NMI_VEC
+10: .long in_nmi
+11:
+#endif /* defined(CONFIG_KGDB) */
+ sts pr, k3 ! save original pr value in k3
+ mova exception_data, k0
-interrupt_exception:
- mov.l 1f, r9
+ ! Setup stack and save DSP context (k0 contains original r15 on return)
+ bsr prepare_stack
+ PREF(k0)
+
+ ! Save registers / Switch to bank 0
+ mov.l 1f, k4 ! SR bits to clear in k4
+ bsr save_regs ! needs original pr value in k3
+ mov #-1, k2 ! default vector kept in k2
+
+ ! Setup return address and jump to do_IRQ
+ mov.l 4f, r9 ! fetch return address
+ lds r9, pr ! put return address in pr
mov.l 2f, r4
- mov.l @r4, r4
+ mov.l 3f, r9
+ mov.l @r4, r4 ! pass INTEVT vector as arg0
jmp @r9
- mov r15, r5
- rts
- nop
-
- .align 2
-1: .long do_IRQ
-2: .long INTEVT
+ mov r15, r5 ! pass saved registers as arg1
- .align 2
ENTRY(exception_none)
rts
nop
+
+ .align L1_CACHE_SHIFT
+exception_data:
+0: .long 0x000080f0 ! FD=1, IMASK=15
+1: .long 0xcfffffff ! RB=0, BL=0
+2: .long INTEVT
+3: .long do_IRQ
+4: .long ret_from_irq
+5: .long EXPEVT
+6: .long exception_handling_table
+7: .long ret_from_exception
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
index 6468ae86b944..63b67badd67e 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -1,7 +1,7 @@
/*
* SH7705 Setup
*
- * Copyright (C) 2006, 2007 Paul Mundt
+ * Copyright (C) 2006 - 2009 Paul Mundt
* Copyright (C) 2007 Nobuhiro Iwamatsu
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -21,51 +21,36 @@ enum {
/* interrupt sources */
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
PINT07, PINT815,
- DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3,
- SCIF0_ERI, SCIF0_RXI, SCIF0_TXI,
- SCIF2_ERI, SCIF2_RXI, SCIF2_TXI,
- ADC_ADI,
- USB_USI0, USB_USI1,
+
+ DMAC, SCIF0, SCIF2, ADC_ADI, USB,
+
TPU0, TPU1, TPU2, TPU3,
- TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
- RTC_ATI, RTC_PRI, RTC_CUI,
- WDT,
- REF_RCMI,
+ TMU0, TMU1, TMU2,
- /* interrupt groups */
- RTC, TMU2, DMAC, USB, SCIF2, SCIF0,
+ RTC, WDT, REF_RCMI,
};
static struct intc_vect vectors[] __initdata = {
/* IRQ0->5 are handled in setup-sh3.c */
INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720),
- INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
- INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
- INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
- INTC_VECT(SCIF0_TXI, 0x8e0),
- INTC_VECT(SCIF2_ERI, 0x900), INTC_VECT(SCIF2_RXI, 0x920),
- INTC_VECT(SCIF2_TXI, 0x960),
+ INTC_VECT(DMAC, 0x800), INTC_VECT(DMAC, 0x820),
+ INTC_VECT(DMAC, 0x840), INTC_VECT(DMAC, 0x860),
+ INTC_VECT(SCIF0, 0x880), INTC_VECT(SCIF0, 0x8a0),
+ INTC_VECT(SCIF0, 0x8e0),
+ INTC_VECT(SCIF2, 0x900), INTC_VECT(SCIF2, 0x920),
+ INTC_VECT(SCIF2, 0x960),
INTC_VECT(ADC_ADI, 0x980),
- INTC_VECT(USB_USI0, 0xa20), INTC_VECT(USB_USI1, 0xa40),
+ INTC_VECT(USB, 0xa20), INTC_VECT(USB, 0xa40),
INTC_VECT(TPU0, 0xc00), INTC_VECT(TPU1, 0xc20),
INTC_VECT(TPU2, 0xc80), INTC_VECT(TPU3, 0xca0),
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
- INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
- INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
- INTC_VECT(RTC_CUI, 0x4c0),
+ INTC_VECT(TMU2, 0x440), INTC_VECT(TMU2, 0x460),
+ INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
+ INTC_VECT(RTC, 0x4c0),
INTC_VECT(WDT, 0x560),
INTC_VECT(REF_RCMI, 0x580),
};
-static struct intc_group groups[] __initdata = {
- INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
- INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
- INTC_GROUP(DMAC, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3),
- INTC_GROUP(USB, USB_USI0, USB_USI1),
- INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_TXI),
- INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI),
-};
-
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
{ 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, 0, 0 } },
@@ -78,7 +63,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
};
-static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups,
+static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, NULL,
NULL, prio_registers, NULL);
static struct plat_sci_port sci_platform_data[] = {
@@ -86,12 +71,12 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xa4410000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 56, 57, 59 },
+ .irqs = { 56, 56, 56 },
}, {
.mapbase = 0xa4400000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 52, 53, 55 },
+ .irqs = { 52, 52, 52 },
}, {
.flags = 0,
}
@@ -115,14 +100,6 @@ static struct resource rtc_resources[] = {
.start = 20,
.flags = IORESOURCE_IRQ,
},
- [2] = {
- .start = 21,
- .flags = IORESOURCE_IRQ,
- },
- [3] = {
- .start = 22,
- .flags = IORESOURCE_IRQ,
- },
};
static struct sh_rtc_platform_info rtc_info = {
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
index 93c55e2ed952..a74f960b5e79 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c
@@ -2,6 +2,7 @@
* SH3 Setup code for SH7706, SH7707, SH7708, SH7709
*
* Copyright (C) 2007 Magnus Damm
+ * Copyright (C) 2009 Paul Mundt
*
* Based on setup-sh7709.c
*
@@ -24,46 +25,37 @@ enum {
/* interrupt sources */
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
PINT07, PINT815,
- DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3,
- SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
- SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
- SCI_ERI, SCI_RXI, SCI_TXI, SCI_TEI,
- ADC_ADI,
+ DMAC, SCIF0, SCIF2, SCI, ADC_ADI,
LCDC, PCC0, PCC1,
- TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
- RTC_ATI, RTC_PRI, RTC_CUI,
- WDT,
- REF_RCMI, REF_ROVI,
-
- /* interrupt groups */
- RTC, REF, TMU2, DMAC, SCI, SCIF2, SCIF0,
+ TMU0, TMU1, TMU2,
+ RTC, WDT, REF,
};
static struct intc_vect vectors[] __initdata = {
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
- INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
- INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
- INTC_VECT(RTC_CUI, 0x4c0),
- INTC_VECT(SCI_ERI, 0x4e0), INTC_VECT(SCI_RXI, 0x500),
- INTC_VECT(SCI_TXI, 0x520), INTC_VECT(SCI_TEI, 0x540),
+ INTC_VECT(TMU2, 0x440), INTC_VECT(TMU2, 0x460),
+ INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
+ INTC_VECT(RTC, 0x4c0),
+ INTC_VECT(SCI, 0x4e0), INTC_VECT(SCI, 0x500),
+ INTC_VECT(SCI, 0x520), INTC_VECT(SCI, 0x540),
INTC_VECT(WDT, 0x560),
- INTC_VECT(REF_RCMI, 0x580),
- INTC_VECT(REF_ROVI, 0x5a0),
+ INTC_VECT(REF, 0x580),
+ INTC_VECT(REF, 0x5a0),
#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
defined(CONFIG_CPU_SUBTYPE_SH7707) || \
defined(CONFIG_CPU_SUBTYPE_SH7709)
/* IRQ0->5 are handled in setup-sh3.c */
- INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
- INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
+ INTC_VECT(DMAC, 0x800), INTC_VECT(DMAC, 0x820),
+ INTC_VECT(DMAC, 0x840), INTC_VECT(DMAC, 0x860),
INTC_VECT(ADC_ADI, 0x980),
- INTC_VECT(SCIF2_ERI, 0x900), INTC_VECT(SCIF2_RXI, 0x920),
- INTC_VECT(SCIF2_BRI, 0x940), INTC_VECT(SCIF2_TXI, 0x960),
+ INTC_VECT(SCIF2, 0x900), INTC_VECT(SCIF2, 0x920),
+ INTC_VECT(SCIF2, 0x940), INTC_VECT(SCIF2, 0x960),
#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
defined(CONFIG_CPU_SUBTYPE_SH7709)
INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720),
- INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
- INTC_VECT(SCIF0_BRI, 0x8c0), INTC_VECT(SCIF0_TXI, 0x8e0),
+ INTC_VECT(SCIF0, 0x880), INTC_VECT(SCIF0, 0x8a0),
+ INTC_VECT(SCIF0, 0x8c0), INTC_VECT(SCIF0, 0x8e0),
#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7707)
INTC_VECT(LCDC, 0x9a0),
@@ -71,16 +63,6 @@ static struct intc_vect vectors[] __initdata = {
#endif
};
-static struct intc_group groups[] __initdata = {
- INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
- INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
- INTC_GROUP(REF, REF_RCMI, REF_ROVI),
- INTC_GROUP(DMAC, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3),
- INTC_GROUP(SCI, SCI_ERI, SCI_RXI, SCI_TXI, SCI_TEI),
- INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
- INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
-};
-
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
{ 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, SCI, 0 } },
@@ -101,7 +83,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
#endif
};
-static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups,
+static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, NULL,
NULL, prio_registers, NULL);
static struct resource rtc_resources[] = {
@@ -111,14 +93,6 @@ static struct resource rtc_resources[] = {
.flags = IORESOURCE_IO,
},
[1] = {
- .start = 21,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = 22,
- .flags = IORESOURCE_IRQ,
- },
- [3] = {
.start = 20,
.flags = IORESOURCE_IRQ,
},
@@ -136,7 +110,7 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xfffffe80,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCI,
- .irqs = { 23, 24, 25, 0 },
+ .irqs = { 23, 23, 23, 0 },
},
#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \
defined(CONFIG_CPU_SUBTYPE_SH7707) || \
@@ -145,7 +119,7 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xa4000150,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 56, 57, 59, 58 },
+ .irqs = { 56, 56, 56, 56 },
},
#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
@@ -154,7 +128,7 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xa4000140,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_IRDA,
- .irqs = { 52, 53, 55, 54 },
+ .irqs = { 52, 52, 52, 52 },
},
#endif
{
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
index 77eee481de47..335098b66e2f 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -1,7 +1,7 @@
/*
* SH3 Setup code for SH7710, SH7712
*
- * Copyright (C) 2006, 2007 Paul Mundt
+ * Copyright (C) 2006 - 2009 Paul Mundt
* Copyright (C) 2007 Nobuhiro Iwamatsu
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -20,59 +20,40 @@ enum {
/* interrupt sources */
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5,
- DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3,
- SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
- SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
- DMAC_DEI4, DMAC_DEI5,
- IPSEC,
+ DMAC1, SCIF0, SCIF1, DMAC2, IPSEC,
EDMAC0, EDMAC1, EDMAC2,
- SIOF0_ERI, SIOF0_TXI, SIOF0_RXI, SIOF0_CCI,
- SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI,
- TMU0, TMU1, TMU2,
- RTC_ATI, RTC_PRI, RTC_CUI,
- WDT,
- REF,
+ SIOF0, SIOF1,
- /* interrupt groups */
- RTC, DMAC1, SCIF0, SCIF1, DMAC2, SIOF0, SIOF1,
+ TMU0, TMU1, TMU2,
+ RTC, WDT, REF,
};
static struct intc_vect vectors[] __initdata = {
/* IRQ0->5 are handled in setup-sh3.c */
- INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820),
- INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860),
- INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0),
- INTC_VECT(SCIF0_BRI, 0x8c0), INTC_VECT(SCIF0_TXI, 0x8e0),
- INTC_VECT(SCIF1_ERI, 0x900), INTC_VECT(SCIF1_RXI, 0x920),
- INTC_VECT(SCIF1_BRI, 0x940), INTC_VECT(SCIF1_TXI, 0x960),
- INTC_VECT(DMAC_DEI4, 0xb80), INTC_VECT(DMAC_DEI5, 0xba0),
+ INTC_VECT(DMAC1, 0x800), INTC_VECT(DMAC1, 0x820),
+ INTC_VECT(DMAC1, 0x840), INTC_VECT(DMAC1, 0x860),
+ INTC_VECT(SCIF0, 0x880), INTC_VECT(SCIF0, 0x8a0),
+ INTC_VECT(SCIF0, 0x8c0), INTC_VECT(SCIF0, 0x8e0),
+ INTC_VECT(SCIF1, 0x900), INTC_VECT(SCIF1, 0x920),
+ INTC_VECT(SCIF1, 0x940), INTC_VECT(SCIF1, 0x960),
+ INTC_VECT(DMAC2, 0xb80), INTC_VECT(DMAC2, 0xba0),
#ifdef CONFIG_CPU_SUBTYPE_SH7710
INTC_VECT(IPSEC, 0xbe0),
#endif
INTC_VECT(EDMAC0, 0xc00), INTC_VECT(EDMAC1, 0xc20),
INTC_VECT(EDMAC2, 0xc40),
- INTC_VECT(SIOF0_ERI, 0xe00), INTC_VECT(SIOF0_TXI, 0xe20),
- INTC_VECT(SIOF0_RXI, 0xe40), INTC_VECT(SIOF0_CCI, 0xe60),
- INTC_VECT(SIOF1_ERI, 0xe80), INTC_VECT(SIOF1_TXI, 0xea0),
- INTC_VECT(SIOF1_RXI, 0xec0), INTC_VECT(SIOF1_CCI, 0xee0),
+ INTC_VECT(SIOF0, 0xe00), INTC_VECT(SIOF0, 0xe20),
+ INTC_VECT(SIOF0, 0xe40), INTC_VECT(SIOF0, 0xe60),
+ INTC_VECT(SIOF1, 0xe80), INTC_VECT(SIOF1, 0xea0),
+ INTC_VECT(SIOF1, 0xec0), INTC_VECT(SIOF1, 0xee0),
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
INTC_VECT(TMU2, 0x440),
- INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
- INTC_VECT(RTC_CUI, 0x4c0),
+ INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
+ INTC_VECT(RTC, 0x4c0),
INTC_VECT(WDT, 0x560),
INTC_VECT(REF, 0x580),
};
-static struct intc_group groups[] __initdata = {
- INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
- INTC_GROUP(DMAC1, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3),
- INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
- INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
- INTC_GROUP(DMAC2, DMAC_DEI4, DMAC_DEI5),
- INTC_GROUP(SIOF0, SIOF0_ERI, SIOF0_TXI, SIOF0_RXI, SIOF0_CCI),
- INTC_GROUP(SIOF1, SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI),
-};
-
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
{ 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } },
@@ -85,7 +66,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xa4080006, 0, 16, 4, /* IPRI */ { 0, 0, SIOF1 } },
};
-static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups,
+static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, NULL,
NULL, prio_registers, NULL);
static struct resource rtc_resources[] = {
@@ -98,14 +79,6 @@ static struct resource rtc_resources[] = {
.start = 20,
.flags = IORESOURCE_IRQ,
},
- [2] = {
- .start = 21,
- .flags = IORESOURCE_IRQ,
- },
- [3] = {
- .start = 22,
- .flags = IORESOURCE_IRQ,
- },
};
static struct sh_rtc_platform_info rtc_info = {
@@ -127,12 +100,12 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xa4400000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 52, 53, 55, 54 },
+ .irqs = { 52, 52, 52, 52 },
}, {
.mapbase = 0xa4410000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 56, 57, 59, 58 },
+ .irqs = { 56, 56, 56, 56 },
}, {
.flags = 0,
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
index f807a21b066c..003874a2fd2a 100644
--- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c
@@ -2,6 +2,7 @@
* SH7720 Setup
*
* Copyright (C) 2007 Markus Brunner, Mark Jonas
+ * Copyright (C) 2009 Paul Mundt
*
* Based on arch/sh/kernel/cpu/sh4/setup-sh7750.c:
*
@@ -26,17 +27,7 @@ static struct resource rtc_resources[] = {
.flags = IORESOURCE_IO,
},
[1] = {
- /* Period IRQ */
- .start = 21,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- /* Carry IRQ */
- .start = 22,
- .flags = IORESOURCE_IRQ,
- },
- [3] = {
- /* Alarm IRQ */
+ /* Shared Period/Carry/Alarm IRQ */
.start = 20,
.flags = IORESOURCE_IRQ,
},
@@ -150,62 +141,49 @@ enum {
UNUSED = 0,
/* interrupt sources */
- TMU0, TMU1, TMU2, RTC_ATI, RTC_PRI, RTC_CUI,
- WDT, REF_RCMI, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND,
+ TMU0, TMU1, TMU2, RTC,
+ WDT, REF_RCMI, SIM,
IRQ0, IRQ1, IRQ2, IRQ3,
USBF_SPD, TMU_SUNI, IRQ5, IRQ4,
- DMAC1_DEI0, DMAC1_DEI1, DMAC1_DEI2, DMAC1_DEI3, LCDC, SSL,
- ADC, DMAC2_DEI4, DMAC2_DEI5, USBFI0, USBFI1, CMT,
+ DMAC1, LCDC, SSL,
+ ADC, DMAC2, USBFI, CMT,
SCIF0, SCIF1,
- PINT07, PINT815, TPU0, TPU1, TPU2, TPU3, IIC,
- SIOF0, SIOF1, MMCI0, MMCI1, MMCI2, MMCI3, PCC,
+ PINT07, PINT815, TPU, IIC,
+ SIOF0, SIOF1, MMC, PCC,
USBHI, AFEIF,
H_UDI,
- /* interrupt groups */
- TMU, RTC, SIM, DMAC1, USBFI, DMAC2, USB, TPU, MMC,
};
static struct intc_vect vectors[] __initdata = {
/* IRQ0->5 are handled in setup-sh3.c */
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
- INTC_VECT(TMU2, 0x440), INTC_VECT(RTC_ATI, 0x480),
- INTC_VECT(RTC_PRI, 0x4a0), INTC_VECT(RTC_CUI, 0x4c0),
- INTC_VECT(SIM_ERI, 0x4e0), INTC_VECT(SIM_RXI, 0x500),
- INTC_VECT(SIM_TXI, 0x520), INTC_VECT(SIM_TEND, 0x540),
+ INTC_VECT(TMU2, 0x440), INTC_VECT(RTC, 0x480),
+ INTC_VECT(RTC, 0x4a0), INTC_VECT(RTC, 0x4c0),
+ INTC_VECT(SIM, 0x4e0), INTC_VECT(SIM, 0x500),
+ INTC_VECT(SIM, 0x520), INTC_VECT(SIM, 0x540),
INTC_VECT(WDT, 0x560), INTC_VECT(REF_RCMI, 0x580),
/* H_UDI cannot be masked */ INTC_VECT(TMU_SUNI, 0x6c0),
- INTC_VECT(USBF_SPD, 0x6e0), INTC_VECT(DMAC1_DEI0, 0x800),
- INTC_VECT(DMAC1_DEI1, 0x820), INTC_VECT(DMAC1_DEI2, 0x840),
- INTC_VECT(DMAC1_DEI3, 0x860), INTC_VECT(LCDC, 0x900),
+ INTC_VECT(USBF_SPD, 0x6e0), INTC_VECT(DMAC1, 0x800),
+ INTC_VECT(DMAC1, 0x820), INTC_VECT(DMAC1, 0x840),
+ INTC_VECT(DMAC1, 0x860), INTC_VECT(LCDC, 0x900),
#if defined(CONFIG_CPU_SUBTYPE_SH7720)
INTC_VECT(SSL, 0x980),
#endif
- INTC_VECT(USBFI0, 0xa20), INTC_VECT(USBFI1, 0xa40),
+ INTC_VECT(USBFI, 0xa20), INTC_VECT(USBFI, 0xa40),
INTC_VECT(USBHI, 0xa60),
- INTC_VECT(DMAC2_DEI4, 0xb80), INTC_VECT(DMAC2_DEI5, 0xba0),
+ INTC_VECT(DMAC2, 0xb80), INTC_VECT(DMAC2, 0xba0),
INTC_VECT(ADC, 0xbe0), INTC_VECT(SCIF0, 0xc00),
INTC_VECT(SCIF1, 0xc20), INTC_VECT(PINT07, 0xc80),
INTC_VECT(PINT815, 0xca0), INTC_VECT(SIOF0, 0xd00),
- INTC_VECT(SIOF1, 0xd20), INTC_VECT(TPU0, 0xd80),
- INTC_VECT(TPU1, 0xda0), INTC_VECT(TPU2, 0xdc0),
- INTC_VECT(TPU3, 0xde0), INTC_VECT(IIC, 0xe00),
- INTC_VECT(MMCI0, 0xe80), INTC_VECT(MMCI1, 0xea0),
- INTC_VECT(MMCI2, 0xec0), INTC_VECT(MMCI3, 0xee0),
+ INTC_VECT(SIOF1, 0xd20), INTC_VECT(TPU, 0xd80),
+ INTC_VECT(TPU, 0xda0), INTC_VECT(TPU, 0xdc0),
+ INTC_VECT(TPU, 0xde0), INTC_VECT(IIC, 0xe00),
+ INTC_VECT(MMC, 0xe80), INTC_VECT(MMC, 0xea0),
+ INTC_VECT(MMC, 0xec0), INTC_VECT(MMC, 0xee0),
INTC_VECT(CMT, 0xf00), INTC_VECT(PCC, 0xf60),
INTC_VECT(AFEIF, 0xfe0),
};
-static struct intc_group groups[] __initdata = {
- INTC_GROUP(TMU, TMU0, TMU1, TMU2),
- INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
- INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND),
- INTC_GROUP(DMAC1, DMAC1_DEI0, DMAC1_DEI1, DMAC1_DEI2, DMAC1_DEI3),
- INTC_GROUP(USBFI, USBFI0, USBFI1),
- INTC_GROUP(DMAC2, DMAC2_DEI4, DMAC2_DEI5),
- INTC_GROUP(TPU, TPU0, TPU1, TPU2, TPU3),
- INTC_GROUP(MMC, MMCI0, MMCI1, MMCI2, MMCI3),
-};
-
static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xA414FEE2UL, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } },
{ 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } },
@@ -219,7 +197,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
{ 0xA4080008UL, 0, 16, 4, /* IPRJ */ { 0, USBHI, 0, AFEIF } },
};
-static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups,
+static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, NULL,
NULL, prio_registers, NULL);
void __init plat_irq_setup(void)
diff --git a/arch/sh/kernel/cpu/sh3/swsusp.S b/arch/sh/kernel/cpu/sh3/swsusp.S
new file mode 100644
index 000000000000..01145426a2b8
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/swsusp.S
@@ -0,0 +1,147 @@
+/*
+ * arch/sh/kernel/cpu/sh3/swsusp.S
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+
+#define k0 r0
+#define k1 r1
+#define k2 r2
+#define k3 r3
+#define k4 r4
+
+! swsusp_arch_resume()
+! - copy restore_pblist pages
+! - restore registers from swsusp_arch_regs_cpu0
+
+ENTRY(swsusp_arch_resume)
+ mov.l 1f, r15
+ mov.l 2f, r4
+ mov.l @r4, r4
+
+swsusp_copy_loop:
+ mov r4, r0
+ cmp/eq #0, r0
+ bt swsusp_restore_regs
+
+ mov.l @(PBE_ADDRESS, r4), r2
+ mov.l @(PBE_ORIG_ADDRESS, r4), r5
+
+ mov #(PAGE_SIZE >> 10), r3
+ shll8 r3
+ shlr2 r3 /* PAGE_SIZE / 16 */
+swsusp_copy_page:
+ dt r3
+ mov.l @r2+,r1 /* 16n+0 */
+ mov.l r1,@r5
+ add #4,r5
+ mov.l @r2+,r1 /* 16n+4 */
+ mov.l r1,@r5
+ add #4,r5
+ mov.l @r2+,r1 /* 16n+8 */
+ mov.l r1,@r5
+ add #4,r5
+ mov.l @r2+,r1 /* 16n+12 */
+ mov.l r1,@r5
+ bf/s swsusp_copy_page
+ add #4,r5
+
+ bra swsusp_copy_loop
+ mov.l @(PBE_NEXT, r4), r4
+
+swsusp_restore_regs:
+ ! BL=0: R7->R0 is bank0
+ mov.l 3f, r8
+ mov.l 4f, r5
+ jsr @r5
+ nop
+
+ ! BL=1: R7->R0 is bank1
+ lds k2, pr
+ ldc k3, ssr
+
+ mov.l @r15+, r0
+ mov.l @r15+, r1
+ mov.l @r15+, r2
+ mov.l @r15+, r3
+ mov.l @r15+, r4
+ mov.l @r15+, r5
+ mov.l @r15+, r6
+ mov.l @r15+, r7
+
+ rte
+ nop
+ ! BL=0: R7->R0 is bank0
+
+ .align 2
+1: .long swsusp_arch_regs_cpu0
+2: .long restore_pblist
+3: .long 0x20000000 ! RB=1
+4: .long restore_regs
+
+! swsusp_arch_suspend()
+! - prepare pc for resume, return from function without swsusp_save on resume
+! - save registers in swsusp_arch_regs_cpu0
+! - call swsusp_save write suspend image
+
+ENTRY(swsusp_arch_suspend)
+ sts pr, r0 ! save pr in r0
+ mov r15, r2 ! save sp in r2
+ mov r8, r5 ! save r8 in r5
+ stc sr, r1
+ ldc r1, ssr ! save sr in ssr
+ mov.l 1f, r1
+ ldc r1, spc ! setup pc value for resuming
+ mov.l 5f, r15 ! use swsusp_arch_regs_cpu0 as stack
+ mov.l 6f, r3
+ add r3, r15 ! save from top of structure
+
+ ! BL=0: R7->R0 is bank0
+ mov.l 2f, r3 ! get new SR value for bank1
+ mov #0, r4
+ mov.l 7f, r1
+ jsr @r1 ! switch to bank1 and save bank1 r7->r0
+ not r4, r4
+
+ ! BL=1: R7->R0 is bank1
+ stc r2_bank, k0 ! fetch old sp from r2_bank0
+ mov.l 3f, k4 ! SR bits to clear in k4
+ mov.l 8f, k1
+ jsr @k1 ! switch to bank0 and save all regs
+ stc r0_bank, k3 ! fetch old pr from r0_bank0
+
+ ! BL=0: R7->R0 is bank0
+ mov r2, r15 ! restore old sp
+ mov r5, r8 ! restore old r8
+ stc ssr, r1
+ ldc r1, sr ! restore old sr
+ lds r0, pr ! restore old pr
+ mov.l 4f, r0
+ jmp @r0
+ nop
+
+swsusp_call_save:
+ mov r2, r15 ! restore old sp
+ mov r5, r8 ! restore old r8
+ lds r0, pr ! restore old pr
+ rts
+ mov #0, r0
+
+ .align 2
+1: .long swsusp_call_save
+2: .long 0x20000000 ! RB=1
+3: .long 0xdfffffff ! RB=0
+4: .long swsusp_save
+5: .long swsusp_arch_regs_cpu0
+6: .long SWSUSP_ARCH_REGS_SIZE
+7: .long save_low_regs
+8: .long save_regs
diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile
index d608557c7a3f..203b18347b83 100644
--- a/arch/sh/kernel/cpu/sh4/Makefile
+++ b/arch/sh/kernel/cpu/sh4/Makefile
@@ -5,6 +5,7 @@
obj-y := probe.o common.o
common-y += $(addprefix ../sh3/, entry.o ex.o)
+obj-$(CONFIG_HIBERNATION) += $(addprefix ../sh3/, swsusp.o)
obj-$(CONFIG_SH_FPU) += fpu.o softfloat.o
obj-$(CONFIG_SH_STORE_QUEUES) += sq.o
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 2e42572b1b11..91e3677ae09d 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -129,6 +129,13 @@ int __init detect_cpu_and_cache_system(void)
boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
CPU_HAS_LLSC;
break;
+ case 0x4004:
+ boot_cpu_data.type = CPU_SH7786;
+ boot_cpu_data.icache.ways = 4;
+ boot_cpu_data.dcache.ways = 4;
+ boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
+ CPU_HAS_LLSC | CPU_HAS_PTEAEX;
+ break;
case 0x3008:
boot_cpu_data.icache.ways = 4;
boot_cpu_data.dcache.ways = 4;
@@ -192,11 +199,6 @@ int __init detect_cpu_and_cache_system(void)
break;
}
-#ifdef CONFIG_SH_DIRECT_MAPPED
- boot_cpu_data.icache.ways = 1;
- boot_cpu_data.dcache.ways = 1;
-#endif
-
#ifdef CONFIG_CPU_HAS_PTEA
boot_cpu_data.flags |= CPU_HAS_PTEA;
#endif
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
index ec884039b914..a1c80d909cd6 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -21,17 +21,7 @@ static struct resource rtc_resources[] = {
.flags = IORESOURCE_IO,
},
[1] = {
- /* Period IRQ */
- .start = 21,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- /* Carry IRQ */
- .start = 22,
- .flags = IORESOURCE_IRQ,
- },
- [3] = {
- /* Alarm IRQ */
+ /* Shared Period/Carry/Alarm IRQ */
.start = 20,
.flags = IORESOURCE_IRQ,
},
@@ -50,13 +40,13 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xffe00000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCI,
- .irqs = { 23, 24, 25, 0 },
+ .irqs = { 23, 23, 23, 0 },
}, {
#endif
.mapbase = 0xffe80000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 40, 41, 43, 42 },
+ .irqs = { 40, 40, 40, 40 },
}, {
.flags = 0,
}
@@ -87,43 +77,27 @@ enum {
/* interrupt sources */
IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */
- HUDI, GPIOI,
- DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3,
- DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7,
- DMAC_DMAE,
+ HUDI, GPIOI, DMAC,
PCIC0_PCISERR, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON,
PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3,
- TMU3, TMU4, TMU0, TMU1, TMU2_TUNI, TMU2_TICPI,
- RTC_ATI, RTC_PRI, RTC_CUI,
- SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI,
- SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI,
- WDT,
- REF_RCMI, REF_ROVI,
+ TMU3, TMU4, TMU0, TMU1, TMU2, RTC, SCI1, SCIF, WDT, REF,
/* interrupt groups */
- DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF,
+ PCIC1,
};
static struct intc_vect vectors[] __initdata = {
INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620),
INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420),
- INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460),
- INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
- INTC_VECT(RTC_CUI, 0x4c0),
- INTC_VECT(SCI1_ERI, 0x4e0), INTC_VECT(SCI1_RXI, 0x500),
- INTC_VECT(SCI1_TXI, 0x520), INTC_VECT(SCI1_TEI, 0x540),
- INTC_VECT(SCIF_ERI, 0x700), INTC_VECT(SCIF_RXI, 0x720),
- INTC_VECT(SCIF_BRI, 0x740), INTC_VECT(SCIF_TXI, 0x760),
+ INTC_VECT(TMU2, 0x440), INTC_VECT(TMU2, 0x460),
+ INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
+ INTC_VECT(RTC, 0x4c0),
+ INTC_VECT(SCI1, 0x4e0), INTC_VECT(SCI1, 0x500),
+ INTC_VECT(SCI1, 0x520), INTC_VECT(SCI1, 0x540),
+ INTC_VECT(SCIF, 0x700), INTC_VECT(SCIF, 0x720),
+ INTC_VECT(SCIF, 0x740), INTC_VECT(SCIF, 0x760),
INTC_VECT(WDT, 0x560),
- INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0),
-};
-
-static struct intc_group groups[] __initdata = {
- INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI),
- INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
- INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI),
- INTC_GROUP(SCIF, SCIF_ERI, SCIF_RXI, SCIF_BRI, SCIF_TXI),
- INTC_GROUP(REF, REF_RCMI, REF_ROVI),
+ INTC_VECT(REF, 0x580), INTC_VECT(REF, 0x5a0),
};
static struct intc_prio_reg prio_registers[] __initdata = {
@@ -136,7 +110,7 @@ static struct intc_prio_reg prio_registers[] __initdata = {
PCIC1, PCIC0_PCISERR } },
};
-static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups,
+static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, NULL,
NULL, prio_registers, NULL);
/* SH7750, SH7750S, SH7751 and SH7091 all have 4-channel DMA controllers */
@@ -145,39 +119,28 @@ static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups,
defined(CONFIG_CPU_SUBTYPE_SH7751) || \
defined(CONFIG_CPU_SUBTYPE_SH7091)
static struct intc_vect vectors_dma4[] __initdata = {
- INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
- INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
- INTC_VECT(DMAC_DMAE, 0x6c0),
-};
-
-static struct intc_group groups_dma4[] __initdata = {
- INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
- DMAC_DMTE3, DMAC_DMAE),
+ INTC_VECT(DMAC, 0x640), INTC_VECT(DMAC, 0x660),
+ INTC_VECT(DMAC, 0x680), INTC_VECT(DMAC, 0x6a0),
+ INTC_VECT(DMAC, 0x6c0),
};
static DECLARE_INTC_DESC(intc_desc_dma4, "sh7750_dma4",
- vectors_dma4, groups_dma4,
+ vectors_dma4, NULL,
NULL, prio_registers, NULL);
#endif
/* SH7750R and SH7751R both have 8-channel DMA controllers */
#if defined(CONFIG_CPU_SUBTYPE_SH7750R) || defined(CONFIG_CPU_SUBTYPE_SH7751R)
static struct intc_vect vectors_dma8[] __initdata = {
- INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660),
- INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0),
- INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0),
- INTC_VECT(DMAC_DMTE6, 0x7c0), INTC_VECT(DMAC_DMTE7, 0x7e0),
- INTC_VECT(DMAC_DMAE, 0x6c0),
-};
-
-static struct intc_group groups_dma8[] __initdata = {
- INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2,
- DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5,
- DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE),
+ INTC_VECT(DMAC, 0x640), INTC_VECT(DMAC, 0x660),
+ INTC_VECT(DMAC, 0x680), INTC_VECT(DMAC, 0x6a0),
+ INTC_VECT(DMAC, 0x780), INTC_VECT(DMAC, 0x7a0),
+ INTC_VECT(DMAC, 0x7c0), INTC_VECT(DMAC, 0x7e0),
+ INTC_VECT(DMAC, 0x6c0),
};
static DECLARE_INTC_DESC(intc_desc_dma8, "sh7750_dma8",
- vectors_dma8, groups_dma8,
+ vectors_dma8, NULL,
NULL, prio_registers, NULL);
#endif
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index 8e344ec5847e..1a92361feeb9 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7763) += setup-sh7763.o
obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o
obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o
obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o
+obj-$(CONFIG_CPU_SUBTYPE_SH7786) += setup-sh7786.o
obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o
obj-$(CONFIG_CPU_SUBTYPE_SH7723) += setup-sh7723.o
@@ -21,6 +22,7 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7763) := clock-sh7763.o
clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o
clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7786) := clock-sh7786.o
clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7722.o
@@ -31,6 +33,7 @@ clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7722) := pinmux-sh7722.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7723) := pinmux-sh7723.o
pinmux-$(CONFIG_CPU_SUBTYPE_SH7785) := pinmux-sh7785.o
+pinmux-$(CONFIG_CPU_SUBTYPE_SH7786) := pinmux-sh7786.o
obj-y += $(clock-y)
obj-$(CONFIG_SMP) += $(smp-y)
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
new file mode 100644
index 000000000000..f84a9c134471
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
@@ -0,0 +1,148 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/clock-sh7786.c
+ *
+ * SH7786 support for the clock framework
+ *
+ * Copyright (C) 2008, 2009 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on SH7785
+ * Copyright (C) 2007 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+#include <asm/io.h>
+
+static int ifc_divisors[] = { 1, 2, 4, 1 };
+static int sfc_divisors[] = { 1, 1, 4, 1 };
+static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 1,
+ 24, 32, 1, 1, 1, 1, 1, 1 };
+static int mfc_divisors[] = { 1, 1, 4, 1 };
+static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 16, 1,
+ 24, 32, 1, 48, 1, 1, 1, 1 };
+
+static void master_clk_init(struct clk *clk)
+{
+ clk->rate *= pfc_divisors[ctrl_inl(FRQMR1) & 0x000f];
+}
+
+static struct clk_ops sh7786_master_clk_ops = {
+ .init = master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+ int idx = (ctrl_inl(FRQMR1) & 0x000f);
+ clk->rate = clk->parent->rate / pfc_divisors[idx];
+}
+
+static struct clk_ops sh7786_module_clk_ops = {
+ .recalc = module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 16) & 0x000f);
+ clk->rate = clk->parent->rate / bfc_divisors[idx];
+}
+
+static struct clk_ops sh7786_bus_clk_ops = {
+ .recalc = bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 28) & 0x0003);
+ clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh7786_cpu_clk_ops = {
+ .recalc = cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7786_clk_ops[] = {
+ &sh7786_master_clk_ops,
+ &sh7786_module_clk_ops,
+ &sh7786_bus_clk_ops,
+ &sh7786_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+ if (idx < ARRAY_SIZE(sh7786_clk_ops))
+ *ops = sh7786_clk_ops[idx];
+}
+
+static void shyway_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 20) & 0x0003);
+ clk->rate = clk->parent->rate / sfc_divisors[idx];
+}
+
+static struct clk_ops sh7786_shyway_clk_ops = {
+ .recalc = shyway_clk_recalc,
+};
+
+static struct clk sh7786_shyway_clk = {
+ .name = "shyway_clk",
+ .flags = CLK_ALWAYS_ENABLED,
+ .ops = &sh7786_shyway_clk_ops,
+};
+
+static void ddr_clk_recalc(struct clk *clk)
+{
+ int idx = ((ctrl_inl(FRQMR1) >> 12) & 0x0003);
+ clk->rate = clk->parent->rate / mfc_divisors[idx];
+}
+
+static struct clk_ops sh7786_ddr_clk_ops = {
+ .recalc = ddr_clk_recalc,
+};
+
+static struct clk sh7786_ddr_clk = {
+ .name = "ddr_clk",
+ .flags = CLK_ALWAYS_ENABLED,
+ .ops = &sh7786_ddr_clk_ops,
+};
+
+/*
+ * Additional SH7786-specific on-chip clocks that aren't already part of the
+ * clock framework
+ */
+static struct clk *sh7786_onchip_clocks[] = {
+ &sh7786_shyway_clk,
+ &sh7786_ddr_clk,
+};
+
+static int __init sh7786_clk_init(void)
+{
+ struct clk *clk = clk_get(NULL, "master_clk");
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sh7786_onchip_clocks); i++) {
+ struct clk *clkp = sh7786_onchip_clocks[i];
+
+ clkp->parent = clk;
+ clk_register(clkp);
+ clk_enable(clkp);
+ }
+
+ /*
+ * Now that we have the rest of the clocks registered, we need to
+ * force the parent clock to propagate so that these clocks will
+ * automatically figure out their rate. We cheat by handing the
+ * parent clock its current rate and forcing child propagation.
+ */
+ clk_set_rate(clk, clk_get_rate(clk));
+
+ clk_put(clk);
+
+ return 0;
+}
+arch_initcall(sh7786_clk_init);
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c
new file mode 100644
index 000000000000..4229e0724c89
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7786.c
@@ -0,0 +1,843 @@
+/*
+ * SH7786 Pinmux
+ *
+ * Copyright (C) 2008, 2009 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on SH7785 pinmux
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <cpu/sh7786.h>
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
+ PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA,
+ PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
+ PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA,
+ PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
+ PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA,
+ PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
+ PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA,
+ PE7_DATA, PE6_DATA,
+ PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
+ PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA,
+ PG7_DATA, PG6_DATA, PG5_DATA,
+ PH7_DATA, PH6_DATA, PH5_DATA, PH4_DATA,
+ PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA,
+ PJ7_DATA, PJ6_DATA, PJ5_DATA, PJ4_DATA,
+ PJ3_DATA, PJ2_DATA, PJ1_DATA,
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ PA7_IN, PA6_IN, PA5_IN, PA4_IN,
+ PA3_IN, PA2_IN, PA1_IN, PA0_IN,
+ PB7_IN, PB6_IN, PB5_IN, PB4_IN,
+ PB3_IN, PB2_IN, PB1_IN, PB0_IN,
+ PC7_IN, PC6_IN, PC5_IN, PC4_IN,
+ PC3_IN, PC2_IN, PC1_IN, PC0_IN,
+ PD7_IN, PD6_IN, PD5_IN, PD4_IN,
+ PD3_IN, PD2_IN, PD1_IN, PD0_IN,
+ PE7_IN, PE6_IN,
+ PF7_IN, PF6_IN, PF5_IN, PF4_IN,
+ PF3_IN, PF2_IN, PF1_IN, PF0_IN,
+ PG7_IN, PG6_IN, PG5_IN,
+ PH7_IN, PH6_IN, PH5_IN, PH4_IN,
+ PH3_IN, PH2_IN, PH1_IN, PH0_IN,
+ PJ7_IN, PJ6_IN, PJ5_IN, PJ4_IN,
+ PJ3_IN, PJ2_IN, PJ1_IN,
+ PINMUX_INPUT_END,
+
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PA7_IN_PU, PA6_IN_PU, PA5_IN_PU, PA4_IN_PU,
+ PA3_IN_PU, PA2_IN_PU, PA1_IN_PU, PA0_IN_PU,
+ PB7_IN_PU, PB6_IN_PU, PB5_IN_PU, PB4_IN_PU,
+ PB3_IN_PU, PB2_IN_PU, PB1_IN_PU, PB0_IN_PU,
+ PC7_IN_PU, PC6_IN_PU, PC5_IN_PU, PC4_IN_PU,
+ PC3_IN_PU, PC2_IN_PU, PC1_IN_PU, PC0_IN_PU,
+ PD7_IN_PU, PD6_IN_PU, PD5_IN_PU, PD4_IN_PU,
+ PD3_IN_PU, PD2_IN_PU, PD1_IN_PU, PD0_IN_PU,
+ PE7_IN_PU, PE6_IN_PU,
+ PF7_IN_PU, PF6_IN_PU, PF5_IN_PU, PF4_IN_PU,
+ PF3_IN_PU, PF2_IN_PU, PF1_IN_PU, PF0_IN_PU,
+ PG7_IN_PU, PG6_IN_PU, PG5_IN_PU,
+ PH7_IN_PU, PH6_IN_PU, PH5_IN_PU, PH4_IN_PU,
+ PH3_IN_PU, PH2_IN_PU, PH1_IN_PU, PH0_IN_PU,
+ PJ7_IN_PU, PJ6_IN_PU, PJ5_IN_PU, PJ4_IN_PU,
+ PJ3_IN_PU, PJ2_IN_PU, PJ1_IN_PU,
+ PINMUX_INPUT_PULLUP_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ PA7_OUT, PA6_OUT, PA5_OUT, PA4_OUT,
+ PA3_OUT, PA2_OUT, PA1_OUT, PA0_OUT,
+ PB7_OUT, PB6_OUT, PB5_OUT, PB4_OUT,
+ PB3_OUT, PB2_OUT, PB1_OUT, PB0_OUT,
+ PC7_OUT, PC6_OUT, PC5_OUT, PC4_OUT,
+ PC3_OUT, PC2_OUT, PC1_OUT, PC0_OUT,
+ PD7_OUT, PD6_OUT, PD5_OUT, PD4_OUT,
+ PD3_OUT, PD2_OUT, PD1_OUT, PD0_OUT,
+ PE7_OUT, PE6_OUT,
+ PF7_OUT, PF6_OUT, PF5_OUT, PF4_OUT,
+ PF3_OUT, PF2_OUT, PF1_OUT, PF0_OUT,
+ PG7_OUT, PG6_OUT, PG5_OUT,
+ PH7_OUT, PH6_OUT, PH5_OUT, PH4_OUT,
+ PH3_OUT, PH2_OUT, PH1_OUT, PH0_OUT,
+ PJ7_OUT, PJ6_OUT, PJ5_OUT, PJ4_OUT,
+ PJ3_OUT, PJ2_OUT, PJ1_OUT,
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PA7_FN, PA6_FN, PA5_FN, PA4_FN,
+ PA3_FN, PA2_FN, PA1_FN, PA0_FN,
+ PB7_FN, PB6_FN, PB5_FN, PB4_FN,
+ PB3_FN, PB2_FN, PB1_FN, PB0_FN,
+ PC7_FN, PC6_FN, PC5_FN, PC4_FN,
+ PC3_FN, PC2_FN, PC1_FN, PC0_FN,
+ PD7_FN, PD6_FN, PD5_FN, PD4_FN,
+ PD3_FN, PD2_FN, PD1_FN, PD0_FN,
+ PE7_FN, PE6_FN,
+ PF7_FN, PF6_FN, PF5_FN, PF4_FN,
+ PF3_FN, PF2_FN, PF1_FN, PF0_FN,
+ PG7_FN, PG6_FN, PG5_FN,
+ PH7_FN, PH6_FN, PH5_FN, PH4_FN,
+ PH3_FN, PH2_FN, PH1_FN, PH0_FN,
+ PJ7_FN, PJ6_FN, PJ5_FN, PJ4_FN,
+ PJ3_FN, PJ2_FN, PJ1_FN,
+ P1MSEL14_0, P1MSEL14_1,
+ P1MSEL13_0, P1MSEL13_1,
+ P1MSEL12_0, P1MSEL12_1,
+ P1MSEL11_0, P1MSEL11_1,
+ P1MSEL10_0, P1MSEL10_1,
+ P1MSEL9_0, P1MSEL9_1,
+ P1MSEL8_0, P1MSEL8_1,
+ P1MSEL7_0, P1MSEL7_1,
+ P1MSEL6_0, P1MSEL6_1,
+ P1MSEL5_0, P1MSEL5_1,
+ P1MSEL4_0, P1MSEL4_1,
+ P1MSEL3_0, P1MSEL3_1,
+ P1MSEL2_0, P1MSEL2_1,
+ P1MSEL1_0, P1MSEL1_1,
+ P1MSEL0_0, P1MSEL0_1,
+
+ P2MSEL15_0, P2MSEL15_1,
+ P2MSEL14_0, P2MSEL14_1,
+ P2MSEL13_0, P2MSEL13_1,
+ P2MSEL12_0, P2MSEL12_1,
+ P2MSEL11_0, P2MSEL11_1,
+ P2MSEL10_0, P2MSEL10_1,
+ P2MSEL9_0, P2MSEL9_1,
+ P2MSEL8_0, P2MSEL8_1,
+ P2MSEL7_0, P2MSEL7_1,
+ P2MSEL6_0, P2MSEL6_1,
+ P2MSEL5_0, P2MSEL5_1,
+ P2MSEL4_0, P2MSEL4_1,
+ P2MSEL3_0, P2MSEL3_1,
+ P2MSEL2_0, P2MSEL2_1,
+ P2MSEL1_0, P2MSEL1_1,
+ P2MSEL0_0, P2MSEL0_1,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+ DCLKIN_MARK, DCLKOUT_MARK, ODDF_MARK,
+ VSYNC_MARK, HSYNC_MARK, CDE_MARK, DISP_MARK,
+ DR0_MARK, DR1_MARK, DR2_MARK, DR3_MARK, DR4_MARK, DR5_MARK,
+ DG0_MARK, DG1_MARK, DG2_MARK, DG3_MARK, DG4_MARK, DG5_MARK,
+ DB0_MARK, DB1_MARK, DB2_MARK, DB3_MARK, DB4_MARK, DB5_MARK,
+ ETH_MAGIC_MARK, ETH_LINK_MARK, ETH_TX_ER_MARK, ETH_TX_EN_MARK,
+ ETH_MDIO_MARK, ETH_RX_CLK_MARK, ETH_MDC_MARK, ETH_COL_MARK,
+ ETH_TX_CLK_MARK, ETH_CRS_MARK, ETH_RX_DV_MARK, ETH_RX_ER_MARK,
+ ETH_TXD3_MARK, ETH_TXD2_MARK, ETH_TXD1_MARK, ETH_TXD0_MARK,
+ ETH_RXD3_MARK, ETH_RXD2_MARK, ETH_RXD1_MARK, ETH_RXD0_MARK,
+ HSPI_CLK_MARK, HSPI_CS_MARK, HSPI_RX_MARK, HSPI_TX_MARK,
+ SCIF0_CTS_MARK, SCIF0_RTS_MARK,
+ SCIF0_SCK_MARK, SCIF0_RXD_MARK, SCIF0_TXD_MARK,
+ SCIF1_SCK_MARK, SCIF1_RXD_MARK, SCIF1_TXD_MARK,
+ SCIF3_SCK_MARK, SCIF3_RXD_MARK, SCIF3_TXD_MARK,
+ SCIF4_SCK_MARK, SCIF4_RXD_MARK, SCIF4_TXD_MARK,
+ SCIF5_SCK_MARK, SCIF5_RXD_MARK, SCIF5_TXD_MARK,
+ BREQ_MARK, IOIS16_MARK, CE2B_MARK, CE2A_MARK, BACK_MARK,
+ FALE_MARK, FRB_MARK, FSTATUS_MARK,
+ FSE_MARK, FCLE_MARK,
+ DACK0_MARK, DACK1_MARK, DACK2_MARK, DACK3_MARK,
+ DREQ0_MARK, DREQ1_MARK, DREQ2_MARK, DREQ3_MARK,
+ DRAK0_MARK, DRAK1_MARK, DRAK2_MARK, DRAK3_MARK,
+ USB_OVC1_MARK, USB_OVC0_MARK,
+ USB_PENC1_MARK, USB_PENC0_MARK,
+ HAC_RES_MARK,
+ HAC1_SDOUT_MARK, HAC1_SDIN_MARK, HAC1_SYNC_MARK, HAC1_BITCLK_MARK,
+ HAC0_SDOUT_MARK, HAC0_SDIN_MARK, HAC0_SYNC_MARK, HAC0_BITCLK_MARK,
+ SSI0_SDATA_MARK, SSI0_SCK_MARK, SSI0_WS_MARK, SSI0_CLK_MARK,
+ SSI1_SDATA_MARK, SSI1_SCK_MARK, SSI1_WS_MARK, SSI1_CLK_MARK,
+ SSI2_SDATA_MARK, SSI2_SCK_MARK, SSI2_WS_MARK,
+ SSI3_SDATA_MARK, SSI3_SCK_MARK, SSI3_WS_MARK,
+ SDIF1CMD_MARK, SDIF1CD_MARK, SDIF1WP_MARK, SDIF1CLK_MARK,
+ SDIF1D3_MARK, SDIF1D2_MARK, SDIF1D1_MARK, SDIF1D0_MARK,
+ SDIF0CMD_MARK, SDIF0CD_MARK, SDIF0WP_MARK, SDIF0CLK_MARK,
+ SDIF0D3_MARK, SDIF0D2_MARK, SDIF0D1_MARK, SDIF0D0_MARK,
+ TCLK_MARK,
+ IRL7_MARK, IRL6_MARK, IRL5_MARK, IRL4_MARK,
+ PINMUX_MARK_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+
+ /* PA GPIO */
+ PINMUX_DATA(PA7_DATA, PA7_IN, PA7_OUT, PA7_IN_PU),
+ PINMUX_DATA(PA6_DATA, PA6_IN, PA6_OUT, PA6_IN_PU),
+ PINMUX_DATA(PA5_DATA, PA5_IN, PA5_OUT, PA5_IN_PU),
+ PINMUX_DATA(PA4_DATA, PA4_IN, PA4_OUT, PA4_IN_PU),
+ PINMUX_DATA(PA3_DATA, PA3_IN, PA3_OUT, PA3_IN_PU),
+ PINMUX_DATA(PA2_DATA, PA2_IN, PA2_OUT, PA2_IN_PU),
+ PINMUX_DATA(PA1_DATA, PA1_IN, PA1_OUT, PA1_IN_PU),
+ PINMUX_DATA(PA0_DATA, PA0_IN, PA0_OUT, PA0_IN_PU),
+
+ /* PB GPIO */
+ PINMUX_DATA(PB7_DATA, PB7_IN, PB7_OUT, PB7_IN_PU),
+ PINMUX_DATA(PB6_DATA, PB6_IN, PB6_OUT, PB6_IN_PU),
+ PINMUX_DATA(PB5_DATA, PB5_IN, PB5_OUT, PB5_IN_PU),
+ PINMUX_DATA(PB4_DATA, PB4_IN, PB4_OUT, PB4_IN_PU),
+ PINMUX_DATA(PB3_DATA, PB3_IN, PB3_OUT, PB3_IN_PU),
+ PINMUX_DATA(PB2_DATA, PB2_IN, PB2_OUT, PB2_IN_PU),
+ PINMUX_DATA(PB1_DATA, PB1_IN, PB1_OUT, PB1_IN_PU),
+ PINMUX_DATA(PB0_DATA, PB0_IN, PB0_OUT, PB0_IN_PU),
+
+ /* PC GPIO */
+ PINMUX_DATA(PC7_DATA, PC7_IN, PC7_OUT, PC7_IN_PU),
+ PINMUX_DATA(PC6_DATA, PC6_IN, PC6_OUT, PC6_IN_PU),
+ PINMUX_DATA(PC5_DATA, PC5_IN, PC5_OUT, PC5_IN_PU),
+ PINMUX_DATA(PC4_DATA, PC4_IN, PC4_OUT, PC4_IN_PU),
+ PINMUX_DATA(PC3_DATA, PC3_IN, PC3_OUT, PC3_IN_PU),
+ PINMUX_DATA(PC2_DATA, PC2_IN, PC2_OUT, PC2_IN_PU),
+ PINMUX_DATA(PC1_DATA, PC1_IN, PC1_OUT, PC1_IN_PU),
+ PINMUX_DATA(PC0_DATA, PC0_IN, PC0_OUT, PC0_IN_PU),
+
+ /* PD GPIO */
+ PINMUX_DATA(PD7_DATA, PD7_IN, PD7_OUT, PD7_IN_PU),
+ PINMUX_DATA(PD6_DATA, PD6_IN, PD6_OUT, PD6_IN_PU),
+ PINMUX_DATA(PD5_DATA, PD5_IN, PD5_OUT, PD5_IN_PU),
+ PINMUX_DATA(PD4_DATA, PD4_IN, PD4_OUT, PD4_IN_PU),
+ PINMUX_DATA(PD3_DATA, PD3_IN, PD3_OUT, PD3_IN_PU),
+ PINMUX_DATA(PD2_DATA, PD2_IN, PD2_OUT, PD2_IN_PU),
+ PINMUX_DATA(PD1_DATA, PD1_IN, PD1_OUT, PD1_IN_PU),
+ PINMUX_DATA(PD0_DATA, PD0_IN, PD0_OUT, PD0_IN_PU),
+
+ /* PE GPIO */
+ PINMUX_DATA(PE7_DATA, PE7_IN, PE7_OUT, PE7_IN_PU),
+ PINMUX_DATA(PE6_DATA, PE6_IN, PE6_OUT, PE6_IN_PU),
+
+ /* PF GPIO */
+ PINMUX_DATA(PF7_DATA, PF7_IN, PF7_OUT, PF7_IN_PU),
+ PINMUX_DATA(PF6_DATA, PF6_IN, PF6_OUT, PF6_IN_PU),
+ PINMUX_DATA(PF5_DATA, PF5_IN, PF5_OUT, PF5_IN_PU),
+ PINMUX_DATA(PF4_DATA, PF4_IN, PF4_OUT, PF4_IN_PU),
+ PINMUX_DATA(PF3_DATA, PF3_IN, PF3_OUT, PF3_IN_PU),
+ PINMUX_DATA(PF2_DATA, PF2_IN, PF2_OUT, PF2_IN_PU),
+ PINMUX_DATA(PF1_DATA, PF1_IN, PF1_OUT, PF1_IN_PU),
+ PINMUX_DATA(PF0_DATA, PF0_IN, PF0_OUT, PF0_IN_PU),
+
+ /* PG GPIO */
+ PINMUX_DATA(PG7_DATA, PG7_IN, PG7_OUT, PG7_IN_PU),
+ PINMUX_DATA(PG6_DATA, PG6_IN, PG6_OUT, PG6_IN_PU),
+ PINMUX_DATA(PG5_DATA, PG5_IN, PG5_OUT, PG5_IN_PU),
+
+ /* PH GPIO */
+ PINMUX_DATA(PH7_DATA, PH7_IN, PH7_OUT, PH7_IN_PU),
+ PINMUX_DATA(PH6_DATA, PH6_IN, PH6_OUT, PH6_IN_PU),
+ PINMUX_DATA(PH5_DATA, PH5_IN, PH5_OUT, PH5_IN_PU),
+ PINMUX_DATA(PH4_DATA, PH4_IN, PH4_OUT, PH4_IN_PU),
+ PINMUX_DATA(PH3_DATA, PH3_IN, PH3_OUT, PH3_IN_PU),
+ PINMUX_DATA(PH2_DATA, PH2_IN, PH2_OUT, PH2_IN_PU),
+ PINMUX_DATA(PH1_DATA, PH1_IN, PH1_OUT, PH1_IN_PU),
+ PINMUX_DATA(PH0_DATA, PH0_IN, PH0_OUT, PH0_IN_PU),
+
+ /* PJ GPIO */
+ PINMUX_DATA(PJ7_DATA, PJ7_IN, PJ7_OUT, PJ7_IN_PU),
+ PINMUX_DATA(PJ6_DATA, PJ6_IN, PJ6_OUT, PJ6_IN_PU),
+ PINMUX_DATA(PJ5_DATA, PJ5_IN, PJ5_OUT, PJ5_IN_PU),
+ PINMUX_DATA(PJ4_DATA, PJ4_IN, PJ4_OUT, PJ4_IN_PU),
+ PINMUX_DATA(PJ3_DATA, PJ3_IN, PJ3_OUT, PJ3_IN_PU),
+ PINMUX_DATA(PJ2_DATA, PJ2_IN, PJ2_OUT, PJ2_IN_PU),
+ PINMUX_DATA(PJ1_DATA, PJ1_IN, PJ1_OUT, PJ1_IN_PU),
+
+ /* PA FN */
+ PINMUX_DATA(CDE_MARK, P1MSEL2_0, PA7_FN),
+ PINMUX_DATA(DISP_MARK, P1MSEL2_0, PA6_FN),
+ PINMUX_DATA(DR5_MARK, P1MSEL2_0, PA5_FN),
+ PINMUX_DATA(DR4_MARK, P1MSEL2_0, PA4_FN),
+ PINMUX_DATA(DR3_MARK, P1MSEL2_0, PA3_FN),
+ PINMUX_DATA(DR2_MARK, P1MSEL2_0, PA2_FN),
+ PINMUX_DATA(DR1_MARK, P1MSEL2_0, PA1_FN),
+ PINMUX_DATA(DR0_MARK, P1MSEL2_0, PA0_FN),
+ PINMUX_DATA(ETH_MAGIC_MARK, P1MSEL2_1, PA7_FN),
+ PINMUX_DATA(ETH_LINK_MARK, P1MSEL2_1, PA6_FN),
+ PINMUX_DATA(ETH_TX_ER_MARK, P1MSEL2_1, PA5_FN),
+ PINMUX_DATA(ETH_TX_EN_MARK, P1MSEL2_1, PA4_FN),
+ PINMUX_DATA(ETH_TXD3_MARK, P1MSEL2_1, PA3_FN),
+ PINMUX_DATA(ETH_TXD2_MARK, P1MSEL2_1, PA2_FN),
+ PINMUX_DATA(ETH_TXD1_MARK, P1MSEL2_1, PA1_FN),
+ PINMUX_DATA(ETH_TXD0_MARK, P1MSEL2_1, PA0_FN),
+
+ /* PB FN */
+ PINMUX_DATA(VSYNC_MARK, P1MSEL3_0, PB7_FN),
+ PINMUX_DATA(ODDF_MARK, P1MSEL3_0, PB6_FN),
+ PINMUX_DATA(DG5_MARK, P1MSEL2_0, PB5_FN),
+ PINMUX_DATA(DG4_MARK, P1MSEL2_0, PB4_FN),
+ PINMUX_DATA(DG3_MARK, P1MSEL2_0, PB3_FN),
+ PINMUX_DATA(DG2_MARK, P1MSEL2_0, PB2_FN),
+ PINMUX_DATA(DG1_MARK, P1MSEL2_0, PB1_FN),
+ PINMUX_DATA(DG0_MARK, P1MSEL2_0, PB0_FN),
+ PINMUX_DATA(HSPI_CLK_MARK, P1MSEL3_1, PB7_FN),
+ PINMUX_DATA(HSPI_CS_MARK, P1MSEL3_1, PB6_FN),
+ PINMUX_DATA(ETH_MDIO_MARK, P1MSEL2_1, PB5_FN),
+ PINMUX_DATA(ETH_RX_CLK_MARK, P1MSEL2_1, PB4_FN),
+ PINMUX_DATA(ETH_MDC_MARK, P1MSEL2_1, PB3_FN),
+ PINMUX_DATA(ETH_COL_MARK, P1MSEL2_1, PB2_FN),
+ PINMUX_DATA(ETH_TX_CLK_MARK, P1MSEL2_1, PB1_FN),
+ PINMUX_DATA(ETH_CRS_MARK, P1MSEL2_1, PB0_FN),
+
+ /* PC FN */
+ PINMUX_DATA(DCLKIN_MARK, P1MSEL3_0, PC7_FN),
+ PINMUX_DATA(HSYNC_MARK, P1MSEL3_0, PC6_FN),
+ PINMUX_DATA(DB5_MARK, P1MSEL2_0, PC5_FN),
+ PINMUX_DATA(DB4_MARK, P1MSEL2_0, PC4_FN),
+ PINMUX_DATA(DB3_MARK, P1MSEL2_0, PC3_FN),
+ PINMUX_DATA(DB2_MARK, P1MSEL2_0, PC2_FN),
+ PINMUX_DATA(DB1_MARK, P1MSEL2_0, PC1_FN),
+ PINMUX_DATA(DB0_MARK, P1MSEL2_0, PC0_FN),
+
+ PINMUX_DATA(HSPI_RX_MARK, P1MSEL3_1, PC7_FN),
+ PINMUX_DATA(HSPI_TX_MARK, P1MSEL3_1, PC6_FN),
+ PINMUX_DATA(ETH_RXD3_MARK, P1MSEL2_1, PC5_FN),
+ PINMUX_DATA(ETH_RXD2_MARK, P1MSEL2_1, PC4_FN),
+ PINMUX_DATA(ETH_RXD1_MARK, P1MSEL2_1, PC3_FN),
+ PINMUX_DATA(ETH_RXD0_MARK, P1MSEL2_1, PC2_FN),
+ PINMUX_DATA(ETH_RX_DV_MARK, P1MSEL2_1, PC1_FN),
+ PINMUX_DATA(ETH_RX_ER_MARK, P1MSEL2_1, PC0_FN),
+
+ /* PD FN */
+ PINMUX_DATA(DCLKOUT_MARK, PD7_FN),
+ PINMUX_DATA(SCIF1_SCK_MARK, PD6_FN),
+ PINMUX_DATA(SCIF1_RXD_MARK, PD5_FN),
+ PINMUX_DATA(SCIF1_TXD_MARK, PD4_FN),
+ PINMUX_DATA(DACK1_MARK, P1MSEL13_1, P1MSEL12_0, PD3_FN),
+ PINMUX_DATA(BACK_MARK, P1MSEL13_0, P1MSEL12_1, PD3_FN),
+ PINMUX_DATA(FALE_MARK, P1MSEL13_0, P1MSEL12_0, PD3_FN),
+ PINMUX_DATA(DACK0_MARK, P1MSEL14_1, PD2_FN),
+ PINMUX_DATA(FCLE_MARK, P1MSEL14_0, PD2_FN),
+ PINMUX_DATA(DREQ1_MARK, P1MSEL10_0, P1MSEL9_1, PD1_FN),
+ PINMUX_DATA(BREQ_MARK, P1MSEL10_1, P1MSEL9_0, PD1_FN),
+ PINMUX_DATA(USB_OVC1_MARK, P1MSEL10_0, P1MSEL9_0, PD1_FN),
+ PINMUX_DATA(DREQ0_MARK, P1MSEL11_1, PD0_FN),
+ PINMUX_DATA(USB_OVC0_MARK, P1MSEL11_0, PD0_FN),
+
+ /* PE FN */
+ PINMUX_DATA(USB_PENC1_MARK, PE7_FN),
+ PINMUX_DATA(USB_PENC0_MARK, PE6_FN),
+
+ /* PF FN */
+ PINMUX_DATA(HAC1_SDOUT_MARK, P2MSEL15_0, P2MSEL14_0, PF7_FN),
+ PINMUX_DATA(HAC1_SDIN_MARK, P2MSEL15_0, P2MSEL14_0, PF6_FN),
+ PINMUX_DATA(HAC1_SYNC_MARK, P2MSEL15_0, P2MSEL14_0, PF5_FN),
+ PINMUX_DATA(HAC1_BITCLK_MARK, P2MSEL15_0, P2MSEL14_0, PF4_FN),
+ PINMUX_DATA(HAC0_SDOUT_MARK, P2MSEL13_0, P2MSEL12_0, PF3_FN),
+ PINMUX_DATA(HAC0_SDIN_MARK, P2MSEL13_0, P2MSEL12_0, PF2_FN),
+ PINMUX_DATA(HAC0_SYNC_MARK, P2MSEL13_0, P2MSEL12_0, PF1_FN),
+ PINMUX_DATA(HAC0_BITCLK_MARK, P2MSEL13_0, P2MSEL12_0, PF0_FN),
+ PINMUX_DATA(SSI1_SDATA_MARK, P2MSEL15_0, P2MSEL14_1, PF7_FN),
+ PINMUX_DATA(SSI1_SCK_MARK, P2MSEL15_0, P2MSEL14_1, PF6_FN),
+ PINMUX_DATA(SSI1_WS_MARK, P2MSEL15_0, P2MSEL14_1, PF5_FN),
+ PINMUX_DATA(SSI1_CLK_MARK, P2MSEL15_0, P2MSEL14_1, PF4_FN),
+ PINMUX_DATA(SSI0_SDATA_MARK, P2MSEL13_0, P2MSEL12_1, PF3_FN),
+ PINMUX_DATA(SSI0_SCK_MARK, P2MSEL13_0, P2MSEL12_1, PF2_FN),
+ PINMUX_DATA(SSI0_WS_MARK, P2MSEL13_0, P2MSEL12_1, PF1_FN),
+ PINMUX_DATA(SSI0_CLK_MARK, P2MSEL13_0, P2MSEL12_1, PF0_FN),
+ PINMUX_DATA(SDIF1CMD_MARK, P2MSEL15_1, P2MSEL14_0, PF7_FN),
+ PINMUX_DATA(SDIF1CD_MARK, P2MSEL15_1, P2MSEL14_0, PF6_FN),
+ PINMUX_DATA(SDIF1WP_MARK, P2MSEL15_1, P2MSEL14_0, PF5_FN),
+ PINMUX_DATA(SDIF1CLK_MARK, P2MSEL15_1, P2MSEL14_0, PF4_FN),
+ PINMUX_DATA(SDIF1D3_MARK, P2MSEL13_1, P2MSEL12_0, PF3_FN),
+ PINMUX_DATA(SDIF1D2_MARK, P2MSEL13_1, P2MSEL12_0, PF2_FN),
+ PINMUX_DATA(SDIF1D1_MARK, P2MSEL13_1, P2MSEL12_0, PF1_FN),
+ PINMUX_DATA(SDIF1D0_MARK, P2MSEL13_1, P2MSEL12_0, PF0_FN),
+
+ /* PG FN */
+ PINMUX_DATA(SCIF3_SCK_MARK, P1MSEL8_0, PG7_FN),
+ PINMUX_DATA(SSI2_SDATA_MARK, P1MSEL8_1, PG7_FN),
+ PINMUX_DATA(SCIF3_RXD_MARK, P1MSEL7_0, P1MSEL6_0, PG6_FN),
+ PINMUX_DATA(SSI2_SCK_MARK, P1MSEL7_1, P1MSEL6_0, PG6_FN),
+ PINMUX_DATA(TCLK_MARK, P1MSEL7_0, P1MSEL6_1, PG6_FN),
+ PINMUX_DATA(SCIF3_TXD_MARK, P1MSEL5_0, P1MSEL4_0, PG5_FN),
+ PINMUX_DATA(SSI2_WS_MARK, P1MSEL5_1, P1MSEL4_0, PG5_FN),
+ PINMUX_DATA(HAC_RES_MARK, P1MSEL5_0, P1MSEL4_1, PG5_FN),
+
+ /* PH FN */
+ PINMUX_DATA(DACK3_MARK, P2MSEL4_0, PH7_FN),
+ PINMUX_DATA(SDIF0CMD_MARK, P2MSEL4_1, PH7_FN),
+ PINMUX_DATA(DACK2_MARK, P2MSEL4_0, PH6_FN),
+ PINMUX_DATA(SDIF0CD_MARK, P2MSEL4_1, PH6_FN),
+ PINMUX_DATA(DREQ3_MARK, P2MSEL4_0, PH5_FN),
+ PINMUX_DATA(SDIF0WP_MARK, P2MSEL4_1, PH5_FN),
+ PINMUX_DATA(DREQ2_MARK, P2MSEL3_0, P2MSEL2_1, PH4_FN),
+ PINMUX_DATA(SDIF0CLK_MARK, P2MSEL3_1, P2MSEL2_0, PH4_FN),
+ PINMUX_DATA(SCIF0_CTS_MARK, P2MSEL3_0, P2MSEL2_0, PH4_FN),
+ PINMUX_DATA(SDIF0D3_MARK, P2MSEL1_1, P2MSEL0_0, PH3_FN),
+ PINMUX_DATA(SCIF0_RTS_MARK, P2MSEL1_0, P2MSEL0_0, PH3_FN),
+ PINMUX_DATA(IRL7_MARK, P2MSEL1_0, P2MSEL0_1, PH3_FN),
+ PINMUX_DATA(SDIF0D2_MARK, P2MSEL1_1, P2MSEL0_0, PH2_FN),
+ PINMUX_DATA(SCIF0_SCK_MARK, P2MSEL1_0, P2MSEL0_0, PH2_FN),
+ PINMUX_DATA(IRL6_MARK, P2MSEL1_0, P2MSEL0_1, PH2_FN),
+ PINMUX_DATA(SDIF0D1_MARK, P2MSEL1_1, P2MSEL0_0, PH1_FN),
+ PINMUX_DATA(SCIF0_RXD_MARK, P2MSEL1_0, P2MSEL0_0, PH1_FN),
+ PINMUX_DATA(IRL5_MARK, P2MSEL1_0, P2MSEL0_1, PH1_FN),
+ PINMUX_DATA(SDIF0D0_MARK, P2MSEL1_1, P2MSEL0_0, PH0_FN),
+ PINMUX_DATA(SCIF0_TXD_MARK, P2MSEL1_0, P2MSEL0_0, PH0_FN),
+ PINMUX_DATA(IRL4_MARK, P2MSEL1_0, P2MSEL0_1, PH0_FN),
+
+ /* PJ FN */
+ PINMUX_DATA(SCIF5_SCK_MARK, P2MSEL11_1, PJ7_FN),
+ PINMUX_DATA(FRB_MARK, P2MSEL11_0, PJ7_FN),
+ PINMUX_DATA(SCIF5_RXD_MARK, P2MSEL10_0, PJ6_FN),
+ PINMUX_DATA(IOIS16_MARK, P2MSEL10_1, PJ6_FN),
+ PINMUX_DATA(SCIF5_TXD_MARK, P2MSEL10_0, PJ5_FN),
+ PINMUX_DATA(CE2B_MARK, P2MSEL10_1, PJ5_FN),
+ PINMUX_DATA(DRAK3_MARK, P2MSEL7_0, PJ4_FN),
+ PINMUX_DATA(CE2A_MARK, P2MSEL7_1, PJ4_FN),
+ PINMUX_DATA(SCIF4_SCK_MARK, P2MSEL9_0, P2MSEL8_0, PJ3_FN),
+ PINMUX_DATA(DRAK2_MARK, P2MSEL9_0, P2MSEL8_1, PJ3_FN),
+ PINMUX_DATA(SSI3_WS_MARK, P2MSEL9_1, P2MSEL8_0, PJ3_FN),
+ PINMUX_DATA(SCIF4_RXD_MARK, P2MSEL6_1, P2MSEL5_0, PJ2_FN),
+ PINMUX_DATA(DRAK1_MARK, P2MSEL6_0, P2MSEL5_1, PJ2_FN),
+ PINMUX_DATA(FSTATUS_MARK, P2MSEL6_0, P2MSEL5_0, PJ2_FN),
+ PINMUX_DATA(SSI3_SDATA_MARK, P2MSEL6_1, P2MSEL5_1, PJ2_FN),
+ PINMUX_DATA(SCIF4_TXD_MARK, P2MSEL6_1, P2MSEL5_0, PJ1_FN),
+ PINMUX_DATA(DRAK0_MARK, P2MSEL6_0, P2MSEL5_1, PJ1_FN),
+ PINMUX_DATA(FSE_MARK, P2MSEL6_0, P2MSEL5_0, PJ1_FN),
+ PINMUX_DATA(SSI3_SCK_MARK, P2MSEL6_1, P2MSEL5_1, PJ1_FN),
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+ /* PA */
+ PINMUX_GPIO(GPIO_PA7, PA7_DATA),
+ PINMUX_GPIO(GPIO_PA6, PA6_DATA),
+ PINMUX_GPIO(GPIO_PA5, PA5_DATA),
+ PINMUX_GPIO(GPIO_PA4, PA4_DATA),
+ PINMUX_GPIO(GPIO_PA3, PA3_DATA),
+ PINMUX_GPIO(GPIO_PA2, PA2_DATA),
+ PINMUX_GPIO(GPIO_PA1, PA1_DATA),
+ PINMUX_GPIO(GPIO_PA0, PA0_DATA),
+
+ /* PB */
+ PINMUX_GPIO(GPIO_PB7, PB7_DATA),
+ PINMUX_GPIO(GPIO_PB6, PB6_DATA),
+ PINMUX_GPIO(GPIO_PB5, PB5_DATA),
+ PINMUX_GPIO(GPIO_PB4, PB4_DATA),
+ PINMUX_GPIO(GPIO_PB3, PB3_DATA),
+ PINMUX_GPIO(GPIO_PB2, PB2_DATA),
+ PINMUX_GPIO(GPIO_PB1, PB1_DATA),
+ PINMUX_GPIO(GPIO_PB0, PB0_DATA),
+
+ /* PC */
+ PINMUX_GPIO(GPIO_PC7, PC7_DATA),
+ PINMUX_GPIO(GPIO_PC6, PC6_DATA),
+ PINMUX_GPIO(GPIO_PC5, PC5_DATA),
+ PINMUX_GPIO(GPIO_PC4, PC4_DATA),
+ PINMUX_GPIO(GPIO_PC3, PC3_DATA),
+ PINMUX_GPIO(GPIO_PC2, PC2_DATA),
+ PINMUX_GPIO(GPIO_PC1, PC1_DATA),
+ PINMUX_GPIO(GPIO_PC0, PC0_DATA),
+
+ /* PD */
+ PINMUX_GPIO(GPIO_PD7, PD7_DATA),
+ PINMUX_GPIO(GPIO_PD6, PD6_DATA),
+ PINMUX_GPIO(GPIO_PD5, PD5_DATA),
+ PINMUX_GPIO(GPIO_PD4, PD4_DATA),
+ PINMUX_GPIO(GPIO_PD3, PD3_DATA),
+ PINMUX_GPIO(GPIO_PD2, PD2_DATA),
+ PINMUX_GPIO(GPIO_PD1, PD1_DATA),
+ PINMUX_GPIO(GPIO_PD0, PD0_DATA),
+
+ /* PE */
+ PINMUX_GPIO(GPIO_PE5, PE7_DATA),
+ PINMUX_GPIO(GPIO_PE4, PE6_DATA),
+
+ /* PF */
+ PINMUX_GPIO(GPIO_PF7, PF7_DATA),
+ PINMUX_GPIO(GPIO_PF6, PF6_DATA),
+ PINMUX_GPIO(GPIO_PF5, PF5_DATA),
+ PINMUX_GPIO(GPIO_PF4, PF4_DATA),
+ PINMUX_GPIO(GPIO_PF3, PF3_DATA),
+ PINMUX_GPIO(GPIO_PF2, PF2_DATA),
+ PINMUX_GPIO(GPIO_PF1, PF1_DATA),
+ PINMUX_GPIO(GPIO_PF0, PF0_DATA),
+
+ /* PG */
+ PINMUX_GPIO(GPIO_PG7, PG7_DATA),
+ PINMUX_GPIO(GPIO_PG6, PG6_DATA),
+ PINMUX_GPIO(GPIO_PG5, PG5_DATA),
+
+ /* PH */
+ PINMUX_GPIO(GPIO_PH7, PH7_DATA),
+ PINMUX_GPIO(GPIO_PH6, PH6_DATA),
+ PINMUX_GPIO(GPIO_PH5, PH5_DATA),
+ PINMUX_GPIO(GPIO_PH4, PH4_DATA),
+ PINMUX_GPIO(GPIO_PH3, PH3_DATA),
+ PINMUX_GPIO(GPIO_PH2, PH2_DATA),
+ PINMUX_GPIO(GPIO_PH1, PH1_DATA),
+ PINMUX_GPIO(GPIO_PH0, PH0_DATA),
+
+ /* PJ */
+ PINMUX_GPIO(GPIO_PJ7, PJ7_DATA),
+ PINMUX_GPIO(GPIO_PJ6, PJ6_DATA),
+ PINMUX_GPIO(GPIO_PJ5, PJ5_DATA),
+ PINMUX_GPIO(GPIO_PJ4, PJ4_DATA),
+ PINMUX_GPIO(GPIO_PJ3, PJ3_DATA),
+ PINMUX_GPIO(GPIO_PJ2, PJ2_DATA),
+ PINMUX_GPIO(GPIO_PJ1, PJ1_DATA),
+
+ /* FN */
+ PINMUX_GPIO(GPIO_FN_CDE, CDE_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_MAGIC, ETH_MAGIC_MARK),
+ PINMUX_GPIO(GPIO_FN_DISP, DISP_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_LINK, ETH_LINK_MARK),
+ PINMUX_GPIO(GPIO_FN_DR5, DR5_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_TX_ER, ETH_TX_ER_MARK),
+ PINMUX_GPIO(GPIO_FN_DR4, DR4_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_TX_EN, ETH_TX_EN_MARK),
+ PINMUX_GPIO(GPIO_FN_DR3, DR3_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_TXD3, ETH_TXD3_MARK),
+ PINMUX_GPIO(GPIO_FN_DR2, DR2_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_TXD2, ETH_TXD2_MARK),
+ PINMUX_GPIO(GPIO_FN_DR1, DR1_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_TXD1, ETH_TXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_DR0, DR0_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_TXD0, ETH_TXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_VSYNC, VSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_HSPI_CLK, HSPI_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_ODDF, ODDF_MARK),
+ PINMUX_GPIO(GPIO_FN_HSPI_CS, HSPI_CS_MARK),
+ PINMUX_GPIO(GPIO_FN_DG5, DG5_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_MDIO, ETH_MDIO_MARK),
+ PINMUX_GPIO(GPIO_FN_DG4, DG4_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_RX_CLK, ETH_RX_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_DG3, DG3_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_MDC, ETH_MDC_MARK),
+ PINMUX_GPIO(GPIO_FN_DG2, DG2_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_COL, ETH_COL_MARK),
+ PINMUX_GPIO(GPIO_FN_DG1, DG1_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_TX_CLK, ETH_TX_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_DG0, DG0_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_CRS, ETH_CRS_MARK),
+ PINMUX_GPIO(GPIO_FN_DCLKIN, DCLKIN_MARK),
+ PINMUX_GPIO(GPIO_FN_HSPI_RX, HSPI_RX_MARK),
+ PINMUX_GPIO(GPIO_FN_HSYNC, HSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_HSPI_TX, HSPI_TX_MARK),
+ PINMUX_GPIO(GPIO_FN_DB5, DB5_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_RXD3, ETH_RXD3_MARK),
+ PINMUX_GPIO(GPIO_FN_DB4, DB4_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_RXD2, ETH_RXD2_MARK),
+ PINMUX_GPIO(GPIO_FN_DB3, DB3_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_RXD1, ETH_RXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_DB2, DB2_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_RXD0, ETH_RXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_DB1, DB1_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_RX_DV, ETH_RX_DV_MARK),
+ PINMUX_GPIO(GPIO_FN_DB0, DB0_MARK),
+ PINMUX_GPIO(GPIO_FN_ETH_RX_ER, ETH_RX_ER_MARK),
+ PINMUX_GPIO(GPIO_FN_DCLKOUT, DCLKOUT_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_SCK, SCIF1_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_RXD, SCIF1_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_TXD, SCIF1_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK),
+ PINMUX_GPIO(GPIO_FN_BACK, BACK_MARK),
+ PINMUX_GPIO(GPIO_FN_FALE, FALE_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK),
+ PINMUX_GPIO(GPIO_FN_FCLE, FCLE_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK),
+ PINMUX_GPIO(GPIO_FN_BREQ, BREQ_MARK),
+ PINMUX_GPIO(GPIO_FN_USB_OVC1, USB_OVC1_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK),
+ PINMUX_GPIO(GPIO_FN_USB_OVC0, USB_OVC0_MARK),
+ PINMUX_GPIO(GPIO_FN_USB_PENC1, USB_PENC1_MARK),
+ PINMUX_GPIO(GPIO_FN_USB_PENC0, USB_PENC0_MARK),
+ PINMUX_GPIO(GPIO_FN_HAC1_SDOUT, HAC1_SDOUT_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI1_SDATA, SSI1_SDATA_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF1CMD, SDIF1CMD_MARK),
+ PINMUX_GPIO(GPIO_FN_HAC1_SDIN, HAC1_SDIN_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI1_SCK, SSI1_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF1CD, SDIF1CD_MARK),
+ PINMUX_GPIO(GPIO_FN_HAC1_SYNC, HAC1_SYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI1_WS, SSI1_WS_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF1WP, SDIF1WP_MARK),
+ PINMUX_GPIO(GPIO_FN_HAC1_BITCLK, HAC1_BITCLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI1_CLK, SSI1_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF1CLK, SDIF1CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_HAC0_SDOUT, HAC0_SDOUT_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI0_SDATA, SSI0_SDATA_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF1D3, SDIF1D3_MARK),
+ PINMUX_GPIO(GPIO_FN_HAC0_SDIN, HAC0_SDIN_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI0_SCK, SSI0_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF1D2, SDIF1D2_MARK),
+ PINMUX_GPIO(GPIO_FN_HAC0_SYNC, HAC0_SYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI0_WS, SSI0_WS_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF1D1, SDIF1D1_MARK),
+ PINMUX_GPIO(GPIO_FN_HAC0_BITCLK, HAC0_BITCLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI0_CLK, SSI0_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF1D0, SDIF1D0_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_SCK, SCIF3_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI2_SDATA, SSI2_SDATA_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_RXD, SCIF3_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_TCLK, TCLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI2_SCK, SSI2_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_TXD, SCIF3_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_HAC_RES, HAC_RES_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI2_WS, SSI2_WS_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK3, DACK3_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF0CMD, SDIF0CMD_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK2, DACK2_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF0CD, SDIF0CD_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ3, DREQ3_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF0WP, SDIF0WP_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_CTS, SCIF0_CTS_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ2, DREQ2_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF0CLK, SDIF0CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_RTS, SCIF0_RTS_MARK),
+ PINMUX_GPIO(GPIO_FN_IRL7, IRL7_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF0D3, SDIF0D3_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_SCK, SCIF0_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_IRL6, IRL6_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF0D2, SDIF0D2_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_RXD, SCIF0_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_IRL5, IRL5_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF0D1, SDIF0D1_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_TXD, SCIF0_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_IRL4, IRL4_MARK),
+ PINMUX_GPIO(GPIO_FN_SDIF0D0, SDIF0D0_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF5_SCK, SCIF5_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_FRB, FRB_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF5_RXD, SCIF5_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF5_TXD, SCIF5_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_CE2B, CE2B_MARK),
+ PINMUX_GPIO(GPIO_FN_DRAK3, DRAK3_MARK),
+ PINMUX_GPIO(GPIO_FN_CE2A, CE2A_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF4_SCK, SCIF4_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_DRAK2, DRAK2_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI3_WS, SSI3_WS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF4_RXD, SCIF4_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_DRAK1, DRAK1_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI3_SDATA, SSI3_SDATA_MARK),
+ PINMUX_GPIO(GPIO_FN_FSTATUS, FSTATUS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF4_TXD, SCIF4_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_DRAK0, DRAK0_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI3_SCK, SSI3_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_FSE, FSE_MARK),
+};
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ { PINMUX_CFG_REG("PACR", 0xffcc0000, 16, 2) {
+ PA7_FN, PA7_OUT, PA7_IN, PA7_IN_PU,
+ PA6_FN, PA6_OUT, PA6_IN, PA6_IN_PU,
+ PA5_FN, PA5_OUT, PA5_IN, PA5_IN_PU,
+ PA4_FN, PA4_OUT, PA4_IN, PA4_IN_PU,
+ PA3_FN, PA3_OUT, PA3_IN, PA3_IN_PU,
+ PA2_FN, PA2_OUT, PA2_IN, PA2_IN_PU,
+ PA1_FN, PA1_OUT, PA1_IN, PA1_IN_PU,
+ PA0_FN, PA0_OUT, PA0_IN, PA0_IN_PU }
+ },
+ { PINMUX_CFG_REG("PBCR", 0xffcc0002, 16, 2) {
+ PB7_FN, PB7_OUT, PB7_IN, PB7_IN_PU,
+ PB6_FN, PB6_OUT, PB6_IN, PB6_IN_PU,
+ PB5_FN, PB5_OUT, PB5_IN, PB5_IN_PU,
+ PB4_FN, PB4_OUT, PB4_IN, PB4_IN_PU,
+ PB3_FN, PB3_OUT, PB3_IN, PB3_IN_PU,
+ PB2_FN, PB2_OUT, PB2_IN, PB2_IN_PU,
+ PB1_FN, PB1_OUT, PB1_IN, PB1_IN_PU,
+ PB0_FN, PB0_OUT, PB0_IN, PB0_IN_PU }
+ },
+ { PINMUX_CFG_REG("PCCR", 0xffcc0004, 16, 2) {
+ PC7_FN, PC7_OUT, PC7_IN, PC7_IN_PU,
+ PC6_FN, PC6_OUT, PC6_IN, PC6_IN_PU,
+ PC5_FN, PC5_OUT, PC5_IN, PC5_IN_PU,
+ PC4_FN, PC4_OUT, PC4_IN, PC4_IN_PU,
+ PC3_FN, PC3_OUT, PC3_IN, PC3_IN_PU,
+ PC2_FN, PC2_OUT, PC2_IN, PC2_IN_PU,
+ PC1_FN, PC1_OUT, PC1_IN, PC1_IN_PU,
+ PC0_FN, PC0_OUT, PC0_IN, PC0_IN_PU }
+ },
+ { PINMUX_CFG_REG("PDCR", 0xffcc0006, 16, 2) {
+ PD7_FN, PD7_OUT, PD7_IN, PD7_IN_PU,
+ PD6_FN, PD6_OUT, PD6_IN, PD6_IN_PU,
+ PD5_FN, PD5_OUT, PD5_IN, PD5_IN_PU,
+ PD4_FN, PD4_OUT, PD4_IN, PD4_IN_PU,
+ PD3_FN, PD3_OUT, PD3_IN, PD3_IN_PU,
+ PD2_FN, PD2_OUT, PD2_IN, PD2_IN_PU,
+ PD1_FN, PD1_OUT, PD1_IN, PD1_IN_PU,
+ PD0_FN, PD0_OUT, PD0_IN, PD0_IN_PU }
+ },
+ { PINMUX_CFG_REG("PECR", 0xffcc0008, 16, 2) {
+ PE7_FN, PE7_OUT, PE7_IN, PE7_IN_PU,
+ PE6_FN, PE6_OUT, PE6_IN, PE6_IN_PU,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0, }
+ },
+ { PINMUX_CFG_REG("PFCR", 0xffcc000a, 16, 2) {
+ PF7_FN, PF7_OUT, PF7_IN, PF7_IN_PU,
+ PF6_FN, PF6_OUT, PF6_IN, PF6_IN_PU,
+ PF5_FN, PF5_OUT, PF5_IN, PF5_IN_PU,
+ PF4_FN, PF4_OUT, PF4_IN, PF4_IN_PU,
+ PF3_FN, PF3_OUT, PF3_IN, PF3_IN_PU,
+ PF2_FN, PF2_OUT, PF2_IN, PF2_IN_PU,
+ PF1_FN, PF1_OUT, PF1_IN, PF1_IN_PU,
+ PF0_FN, PF0_OUT, PF0_IN, PF0_IN_PU }
+ },
+ { PINMUX_CFG_REG("PGCR", 0xffcc000c, 16, 2) {
+ PG7_FN, PG7_OUT, PG7_IN, PG7_IN_PU,
+ PG6_FN, PG6_OUT, PG6_IN, PG6_IN_PU,
+ PG5_FN, PG5_OUT, PG5_IN, PG5_IN_PU,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0, }
+ },
+ { PINMUX_CFG_REG("PHCR", 0xffcc000e, 16, 2) {
+ PH7_FN, PH7_OUT, PH7_IN, PH7_IN_PU,
+ PH6_FN, PH6_OUT, PH6_IN, PH6_IN_PU,
+ PH5_FN, PH5_OUT, PH5_IN, PH5_IN_PU,
+ PH4_FN, PH4_OUT, PH4_IN, PH4_IN_PU,
+ PH3_FN, PH3_OUT, PH3_IN, PH3_IN_PU,
+ PH2_FN, PH2_OUT, PH2_IN, PH2_IN_PU,
+ PH1_FN, PH1_OUT, PH1_IN, PH1_IN_PU,
+ PH0_FN, PH0_OUT, PH0_IN, PH0_IN_PU }
+ },
+ { PINMUX_CFG_REG("PJCR", 0xffcc0010, 16, 2) {
+ PJ7_FN, PJ7_OUT, PJ7_IN, PJ7_IN_PU,
+ PJ6_FN, PJ6_OUT, PJ6_IN, PJ6_IN_PU,
+ PJ5_FN, PJ5_OUT, PJ5_IN, PJ5_IN_PU,
+ PJ4_FN, PJ4_OUT, PJ4_IN, PJ4_IN_PU,
+ PJ3_FN, PJ3_OUT, PJ3_IN, PJ3_IN_PU,
+ PJ2_FN, PJ2_OUT, PJ2_IN, PJ2_IN_PU,
+ PJ1_FN, PJ1_OUT, PJ1_IN, PJ1_IN_PU,
+ 0, 0, 0, 0, }
+ },
+ { PINMUX_CFG_REG("P1MSELR", 0xffcc0080, 16, 1) {
+ 0, 0,
+ P1MSEL14_0, P1MSEL14_1,
+ P1MSEL13_0, P1MSEL13_1,
+ P1MSEL12_0, P1MSEL12_1,
+ P1MSEL11_0, P1MSEL11_1,
+ P1MSEL10_0, P1MSEL10_1,
+ P1MSEL9_0, P1MSEL9_1,
+ P1MSEL8_0, P1MSEL8_1,
+ P1MSEL7_0, P1MSEL7_1,
+ P1MSEL6_0, P1MSEL6_1,
+ P1MSEL5_0, P1MSEL5_1,
+ P1MSEL4_0, P1MSEL4_1,
+ P1MSEL3_0, P1MSEL3_1,
+ P1MSEL2_0, P1MSEL2_1,
+ P1MSEL1_0, P1MSEL1_1,
+ P1MSEL0_0, P1MSEL0_1 }
+ },
+ { PINMUX_CFG_REG("P2MSELR", 0xffcc0082, 16, 1) {
+ P2MSEL15_0, P2MSEL15_1,
+ P2MSEL14_0, P2MSEL14_1,
+ P2MSEL13_0, P2MSEL13_1,
+ P2MSEL12_0, P2MSEL12_1,
+ P2MSEL11_0, P2MSEL11_1,
+ P2MSEL10_0, P2MSEL10_1,
+ P2MSEL9_0, P2MSEL9_1,
+ P2MSEL8_0, P2MSEL8_1,
+ P2MSEL7_0, P2MSEL7_1,
+ P2MSEL6_0, P2MSEL6_1,
+ P2MSEL5_0, P2MSEL5_1,
+ P2MSEL4_0, P2MSEL4_1,
+ P2MSEL3_0, P2MSEL3_1,
+ P2MSEL2_0, P2MSEL2_1,
+ P2MSEL1_0, P2MSEL1_1,
+ P2MSEL0_0, P2MSEL0_1 }
+ },
+ {}
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PADR", 0xffcc0020, 8) {
+ PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
+ PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA }
+ },
+ { PINMUX_DATA_REG("PBDR", 0xffcc0022, 8) {
+ PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
+ PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA }
+ },
+ { PINMUX_DATA_REG("PCDR", 0xffcc0024, 8) {
+ PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
+ PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA }
+ },
+ { PINMUX_DATA_REG("PDDR", 0xffcc0026, 8) {
+ PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
+ PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA }
+ },
+ { PINMUX_DATA_REG("PEDR", 0xffcc0028, 8) {
+ PE7_DATA, PE6_DATA,
+ 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_DATA_REG("PFDR", 0xffcc002a, 8) {
+ PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
+ PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA }
+ },
+ { PINMUX_DATA_REG("PGDR", 0xffcc002c, 8) {
+ PG7_DATA, PG6_DATA, PG5_DATA, 0,
+ 0, 0, 0, 0 }
+ },
+ { PINMUX_DATA_REG("PHDR", 0xffcc002e, 8) {
+ PH7_DATA, PH6_DATA, PH5_DATA, PH4_DATA,
+ PH3_DATA, PH2_DATA, PH1_DATA, PH0_DATA }
+ },
+ { PINMUX_DATA_REG("PJDR", 0xffcc0030, 8) {
+ PJ7_DATA, PJ6_DATA, PJ5_DATA, PJ4_DATA,
+ PJ3_DATA, PJ2_DATA, PJ1_DATA, 0 }
+ },
+ { },
+};
+
+static struct pinmux_info sh7786_pinmux_info = {
+ .name = "sh7786_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PA7,
+ .last_gpio = GPIO_FN_FSE,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+static int __init plat_pinmux_setup(void)
+{
+ return register_pinmux(&sh7786_pinmux_info);
+}
+
+arch_initcall(plat_pinmux_setup);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
index 4ff4dc64520c..c1549382c87c 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c
@@ -12,6 +12,7 @@
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/uio_driver.h>
+#include <linux/sh_cmt.h>
#include <asm/clock.h>
static struct resource iic0_resources[] = {
@@ -140,6 +141,38 @@ static struct platform_device jpu_device = {
.num_resources = ARRAY_SIZE(jpu_resources),
};
+static struct sh_cmt_config cmt_platform_data = {
+ .name = "CMT",
+ .channel_offset = 0x60,
+ .timer_bit = 5,
+ .clk = "cmt0",
+ .clockevent_rating = 125,
+ .clocksource_rating = 200,
+};
+
+static struct resource cmt_resources[] = {
+ [0] = {
+ .name = "CMT",
+ .start = 0x044a0060,
+ .end = 0x044a006b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 104,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt_device = {
+ .name = "sh_cmt",
+ .id = 0,
+ .dev = {
+ .platform_data = &cmt_platform_data,
+ },
+ .resource = cmt_resources,
+ .num_resources = ARRAY_SIZE(cmt_resources),
+};
+
static struct plat_sci_port sci_platform_data[] = {
{
.mapbase = 0xffe00000,
@@ -175,6 +208,7 @@ static struct platform_device sci_device = {
};
static struct platform_device *sh7343_devices[] __initdata = {
+ &cmt_device,
&iic0_device,
&iic1_device,
&sci_device,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index 839ae97a7fd2..93ecf8ed5c6c 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -14,6 +14,7 @@
#include <linux/serial.h>
#include <linux/serial_sci.h>
#include <linux/uio_driver.h>
+#include <linux/sh_cmt.h>
#include <asm/clock.h>
static struct resource iic_resources[] = {
@@ -147,6 +148,38 @@ static struct platform_device veu1_device = {
.num_resources = ARRAY_SIZE(veu1_resources),
};
+static struct sh_cmt_config cmt_platform_data = {
+ .name = "CMT",
+ .channel_offset = 0x60,
+ .timer_bit = 5,
+ .clk = "cmt0",
+ .clockevent_rating = 125,
+ .clocksource_rating = 200,
+};
+
+static struct resource cmt_resources[] = {
+ [0] = {
+ .name = "CMT",
+ .start = 0x044a0060,
+ .end = 0x044a006b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 104,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt_device = {
+ .name = "sh_cmt",
+ .id = 0,
+ .dev = {
+ .platform_data = &cmt_platform_data,
+ },
+ .resource = cmt_resources,
+ .num_resources = ARRAY_SIZE(cmt_resources),
+};
+
static struct plat_sci_port sci_platform_data[] = {
{
.mapbase = 0xffe00000,
@@ -167,6 +200,7 @@ static struct platform_device sci_device = {
};
static struct platform_device *sh7366_devices[] __initdata = {
+ &cmt_device,
&iic_device,
&sci_device,
&usb_host_device,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index 5146afc156e0..0e5d204bc792 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -13,6 +13,7 @@
#include <linux/serial_sci.h>
#include <linux/mm.h>
#include <linux/uio_driver.h>
+#include <linux/sh_cmt.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
@@ -176,6 +177,38 @@ static struct platform_device jpu_device = {
.num_resources = ARRAY_SIZE(jpu_resources),
};
+static struct sh_cmt_config cmt_platform_data = {
+ .name = "CMT",
+ .channel_offset = 0x60,
+ .timer_bit = 5,
+ .clk = "cmt0",
+ .clockevent_rating = 125,
+ .clocksource_rating = 200,
+};
+
+static struct resource cmt_resources[] = {
+ [0] = {
+ .name = "CMT",
+ .start = 0x044a0060,
+ .end = 0x044a006b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 104,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt_device = {
+ .name = "sh_cmt",
+ .id = 0,
+ .dev = {
+ .platform_data = &cmt_platform_data,
+ },
+ .resource = cmt_resources,
+ .num_resources = ARRAY_SIZE(cmt_resources),
+};
+
static struct plat_sci_port sci_platform_data[] = {
{
.mapbase = 0xffe00000,
@@ -209,6 +242,7 @@ static struct platform_device sci_device = {
};
static struct platform_device *sh7722_devices[] __initdata = {
+ &cmt_device,
&rtc_device,
&usbf_device,
&iic_device,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index 849770d780ae..5338dacbcfba 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -13,6 +13,7 @@
#include <linux/mm.h>
#include <linux/serial_sci.h>
#include <linux/uio_driver.h>
+#include <linux/sh_cmt.h>
#include <asm/clock.h>
#include <asm/mmzone.h>
@@ -100,6 +101,38 @@ static struct platform_device veu1_device = {
.num_resources = ARRAY_SIZE(veu1_resources),
};
+static struct sh_cmt_config cmt_platform_data = {
+ .name = "CMT",
+ .channel_offset = 0x60,
+ .timer_bit = 5,
+ .clk = "cmt0",
+ .clockevent_rating = 125,
+ .clocksource_rating = 200,
+};
+
+static struct resource cmt_resources[] = {
+ [0] = {
+ .name = "CMT",
+ .start = 0x044a0060,
+ .end = 0x044a006b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 104,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt_device = {
+ .name = "sh_cmt",
+ .id = 0,
+ .dev = {
+ .platform_data = &cmt_platform_data,
+ },
+ .resource = cmt_resources,
+ .num_resources = ARRAY_SIZE(cmt_resources),
+};
+
static struct plat_sci_port sci_platform_data[] = {
{
.mapbase = 0xffe00000,
@@ -221,6 +254,7 @@ static struct platform_device iic_device = {
};
static struct platform_device *sh7723_devices[] __initdata = {
+ &cmt_device,
&sci_device,
&rtc_device,
&iic_device,
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
index 3c5b629887a8..bdf0f61ae1ed 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2006 Paul Mundt
* Copyright (C) 2007 Yoshihiro Shimoda
- * Copyright (C) 2008 Nobuhiro Iwamatsu
+ * Copyright (C) 2008, 2009 Nobuhiro Iwamatsu
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -22,18 +22,8 @@ static struct resource rtc_resources[] = {
.flags = IORESOURCE_IO,
},
[1] = {
- /* Period IRQ */
- .start = 21,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- /* Carry IRQ */
- .start = 22,
- .flags = IORESOURCE_IRQ,
- },
- [3] = {
- /* Alarm IRQ */
- .start = 20,
+ /* Shared Period/Carry/Alarm IRQ */
+ .start = 20,
.flags = IORESOURCE_IRQ,
},
};
@@ -50,17 +40,17 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xffe00000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 40, 41, 43, 42 },
+ .irqs = { 40, 40, 40, 40 },
}, {
.mapbase = 0xffe08000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 76, 77, 79, 78 },
+ .irqs = { 76, 76, 76, 76 },
}, {
.mapbase = 0xffe10000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 104, 105, 107, 106 },
+ .irqs = { 104, 104, 104, 104 },
}, {
.flags = 0,
}
@@ -148,93 +138,65 @@ enum {
IRL_HHLL, IRL_HHLH, IRL_HHHL,
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
- RTC_ATI, RTC_PRI, RTC_CUI,
- WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
- HUDI, LCDC,
- DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, DMAC0_DMAE,
- SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
- DMAC0_DMINT4, DMAC0_DMINT5,
- IIC0, IIC1,
- CMT,
- GEINT0, GEINT1, GEINT2,
- HAC,
- PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD,
- PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0,
- STIF0, STIF1,
- SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
- SIOF0, SIOF1, SIOF2,
- USBH, USBFI0, USBFI1,
- TPU, PCC,
- MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY,
- SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND,
+ RTC, WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
+ HUDI, LCDC, DMAC, SCIF0, IIC0, IIC1, CMT, GETHER, HAC,
+ PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,
+ STIF0, STIF1, SCIF1, SIOF0, SIOF1, SIOF2,
+ USBH, USBF, TPU, PCC, MMCIF, SIM,
TMU3, TMU4, TMU5, ADC, SSI0, SSI1, SSI2, SSI3,
- SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI,
- GPIO_CH0, GPIO_CH1, GPIO_CH2, GPIO_CH3,
+ SCIF2, GPIO,
/* interrupt groups */
- TMU012, TMU345, RTC, DMAC, SCIF0, GETHER, PCIC5,
- SCIF1, USBF, MMCIF, SIM, SCIF2, GPIO,
+ TMU012, TMU345,
};
static struct intc_vect vectors[] __initdata = {
- INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
- INTC_VECT(RTC_CUI, 0x4c0),
+ INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
+ INTC_VECT(RTC, 0x4c0),
INTC_VECT(WDT, 0x560), INTC_VECT(TMU0, 0x580),
INTC_VECT(TMU1, 0x5a0), INTC_VECT(TMU2, 0x5c0),
INTC_VECT(TMU2_TICPI, 0x5e0), INTC_VECT(HUDI, 0x600),
INTC_VECT(LCDC, 0x620),
- INTC_VECT(DMAC0_DMINT0, 0x640), INTC_VECT(DMAC0_DMINT1, 0x660),
- INTC_VECT(DMAC0_DMINT2, 0x680), INTC_VECT(DMAC0_DMINT3, 0x6a0),
- INTC_VECT(DMAC0_DMAE, 0x6c0),
- INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
- INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
- INTC_VECT(DMAC0_DMINT4, 0x780), INTC_VECT(DMAC0_DMINT5, 0x7a0),
+ INTC_VECT(DMAC, 0x640), INTC_VECT(DMAC, 0x660),
+ INTC_VECT(DMAC, 0x680), INTC_VECT(DMAC, 0x6a0),
+ INTC_VECT(DMAC, 0x6c0),
+ INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),
+ INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),
+ INTC_VECT(DMAC, 0x780), INTC_VECT(DMAC, 0x7a0),
INTC_VECT(IIC0, 0x8A0), INTC_VECT(IIC1, 0x8C0),
- INTC_VECT(CMT, 0x900), INTC_VECT(GEINT0, 0x920),
- INTC_VECT(GEINT1, 0x940), INTC_VECT(GEINT2, 0x960),
+ INTC_VECT(CMT, 0x900), INTC_VECT(GETHER, 0x920),
+ INTC_VECT(GETHER, 0x940), INTC_VECT(GETHER, 0x960),
INTC_VECT(HAC, 0x980),
INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
- INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0),
- INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0),
- INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20),
+ INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),
+ INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),
+ INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),
INTC_VECT(STIF0, 0xb40), INTC_VECT(STIF1, 0xb60),
- INTC_VECT(SCIF1_ERI, 0xb80), INTC_VECT(SCIF1_RXI, 0xba0),
- INTC_VECT(SCIF1_BRI, 0xbc0), INTC_VECT(SCIF1_TXI, 0xbe0),
+ INTC_VECT(SCIF1, 0xb80), INTC_VECT(SCIF1, 0xba0),
+ INTC_VECT(SCIF1, 0xbc0), INTC_VECT(SCIF1, 0xbe0),
INTC_VECT(SIOF0, 0xc00), INTC_VECT(SIOF1, 0xc20),
- INTC_VECT(USBH, 0xc60), INTC_VECT(USBFI0, 0xc80),
- INTC_VECT(USBFI1, 0xca0),
+ INTC_VECT(USBH, 0xc60), INTC_VECT(USBF, 0xc80),
+ INTC_VECT(USBF, 0xca0),
INTC_VECT(TPU, 0xcc0), INTC_VECT(PCC, 0xce0),
- INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20),
- INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60),
- INTC_VECT(SIM_ERI, 0xd80), INTC_VECT(SIM_RXI, 0xda0),
- INTC_VECT(SIM_TXI, 0xdc0), INTC_VECT(SIM_TEND, 0xde0),
+ INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),
+ INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),
+ INTC_VECT(SIM, 0xd80), INTC_VECT(SIM, 0xda0),
+ INTC_VECT(SIM, 0xdc0), INTC_VECT(SIM, 0xde0),
INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
INTC_VECT(TMU5, 0xe40), INTC_VECT(ADC, 0xe60),
INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0),
INTC_VECT(SSI2, 0xec0), INTC_VECT(SSI3, 0xee0),
- INTC_VECT(SCIF2_ERI, 0xf00), INTC_VECT(SCIF2_RXI, 0xf20),
- INTC_VECT(SCIF2_BRI, 0xf40), INTC_VECT(SCIF2_TXI, 0xf60),
- INTC_VECT(GPIO_CH0, 0xf80), INTC_VECT(GPIO_CH1, 0xfa0),
- INTC_VECT(GPIO_CH2, 0xfc0), INTC_VECT(GPIO_CH3, 0xfe0),
+ INTC_VECT(SCIF2, 0xf00), INTC_VECT(SCIF2, 0xf20),
+ INTC_VECT(SCIF2, 0xf40), INTC_VECT(SCIF2, 0xf60),
+ INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),
+ INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
- INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
- INTC_GROUP(DMAC, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
- DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
- INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
- INTC_GROUP(GETHER, GEINT0, GEINT1, GEINT2),
- INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0),
- INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
- INTC_GROUP(USBF, USBFI0, USBFI1),
- INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY),
- INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND),
- INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI),
- INTC_GROUP(GPIO, GPIO_CH0, GPIO_CH1, GPIO_CH2, GPIO_CH3),
};
static struct intc_mask_reg mask_registers[] __initdata = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
index fb8200cc7440..6f7227cd65bf 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c
@@ -20,17 +20,7 @@ static struct resource rtc_resources[] = {
.flags = IORESOURCE_IO,
},
[1] = {
- /* Period IRQ */
- .start = 21,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- /* Carry IRQ */
- .start = 22,
- .flags = IORESOURCE_IRQ,
- },
- [3] = {
- /* Alarm IRQ */
+ /* Shared Period/Carry/Alarm IRQ */
.start = 20,
.flags = IORESOURCE_IRQ,
},
@@ -48,12 +38,12 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xffe00000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 40, 41, 43, 42 },
+ .irqs = { 40, 40, 40, 40 },
}, {
.mapbase = 0xffe10000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 76, 77, 79, 78 },
+ .irqs = { 76, 76, 76, 76 },
}, {
.flags = 0,
}
@@ -90,82 +80,55 @@ enum {
IRL_HHLL, IRL_HHLH, IRL_HHHL,
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
- RTC_ATI, RTC_PRI, RTC_CUI,
- WDT,
- TMU0, TMU1, TMU2, TMU2_TICPI,
- HUDI,
- DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, DMAC0_DMAE,
- SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
- DMAC0_DMINT4, DMAC0_DMINT5, DMAC1_DMINT6, DMAC1_DMINT7,
- CMT, HAC,
- PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD,
- PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0,
- SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
- SIOF, HSPI,
- MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY,
- DMAC1_DMINT8, DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11,
- TMU3, TMU4, TMU5,
- SSI,
- FLCTL_FLSTE, FLCTL_FLEND, FLCTL_FLTRQ0, FLCTL_FLTRQ1,
- GPIOI0, GPIOI1, GPIOI2, GPIOI3,
+ RTC, WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
+ HUDI, DMAC0, SCIF0, DMAC1, CMT, HAC,
+ PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,
+ SCIF1, SIOF, HSPI, MMCIF, TMU3, TMU4, TMU5, SSI, FLCTL, GPIO,
/* interrupt groups */
- RTC, TMU012, DMAC0, SCIF0, DMAC45, DMAC1,
- PCIC5, SCIF1, MMCIF, TMU345, FLCTL, GPIO,
+ TMU012, TMU345,
};
static struct intc_vect vectors[] __initdata = {
- INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0),
- INTC_VECT(RTC_CUI, 0x4c0),
+ INTC_VECT(RTC, 0x480), INTC_VECT(RTC, 0x4a0),
+ INTC_VECT(RTC, 0x4c0),
INTC_VECT(WDT, 0x560),
INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
INTC_VECT(HUDI, 0x600),
- INTC_VECT(DMAC0_DMINT0, 0x640), INTC_VECT(DMAC0_DMINT1, 0x660),
- INTC_VECT(DMAC0_DMINT2, 0x680), INTC_VECT(DMAC0_DMINT3, 0x6a0),
- INTC_VECT(DMAC0_DMAE, 0x6c0),
- INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
- INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
- INTC_VECT(DMAC0_DMINT4, 0x780), INTC_VECT(DMAC0_DMINT5, 0x7a0),
- INTC_VECT(DMAC1_DMINT6, 0x7c0), INTC_VECT(DMAC1_DMINT7, 0x7e0),
+ INTC_VECT(DMAC0, 0x640), INTC_VECT(DMAC0, 0x660),
+ INTC_VECT(DMAC0, 0x680), INTC_VECT(DMAC0, 0x6a0),
+ INTC_VECT(DMAC0, 0x6c0),
+ INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),
+ INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),
+ INTC_VECT(DMAC0, 0x780), INTC_VECT(DMAC0, 0x7a0),
+ INTC_VECT(DMAC1, 0x7c0), INTC_VECT(DMAC1, 0x7e0),
INTC_VECT(CMT, 0x900), INTC_VECT(HAC, 0x980),
INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
- INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0),
- INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0),
- INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20),
- INTC_VECT(SCIF1_ERI, 0xb80), INTC_VECT(SCIF1_RXI, 0xba0),
- INTC_VECT(SCIF1_BRI, 0xbc0), INTC_VECT(SCIF1_TXI, 0xbe0),
+ INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),
+ INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),
+ INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),
+ INTC_VECT(SCIF1, 0xb80), INTC_VECT(SCIF1, 0xba0),
+ INTC_VECT(SCIF1, 0xbc0), INTC_VECT(SCIF1, 0xbe0),
INTC_VECT(SIOF, 0xc00), INTC_VECT(HSPI, 0xc80),
- INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20),
- INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60),
- INTC_VECT(DMAC1_DMINT8, 0xd80), INTC_VECT(DMAC1_DMINT9, 0xda0),
- INTC_VECT(DMAC1_DMINT10, 0xdc0), INTC_VECT(DMAC1_DMINT11, 0xde0),
+ INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),
+ INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),
+ INTC_VECT(DMAC1, 0xd80), INTC_VECT(DMAC1, 0xda0),
+ INTC_VECT(DMAC1, 0xdc0), INTC_VECT(DMAC1, 0xde0),
INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
INTC_VECT(TMU5, 0xe40),
INTC_VECT(SSI, 0xe80),
- INTC_VECT(FLCTL_FLSTE, 0xf00), INTC_VECT(FLCTL_FLEND, 0xf20),
- INTC_VECT(FLCTL_FLTRQ0, 0xf40), INTC_VECT(FLCTL_FLTRQ1, 0xf60),
- INTC_VECT(GPIOI0, 0xf80), INTC_VECT(GPIOI1, 0xfa0),
- INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0),
+ INTC_VECT(FLCTL, 0xf00), INTC_VECT(FLCTL, 0xf20),
+ INTC_VECT(FLCTL, 0xf40), INTC_VECT(FLCTL, 0xf60),
+ INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),
+ INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),
};
static struct intc_group groups[] __initdata = {
- INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI),
INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
- INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
- DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
- INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
- INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
- DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
- INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0),
- INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
- INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY),
INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
- INTC_GROUP(FLCTL, FLCTL_FLSTE, FLCTL_FLEND,
- FLCTL_FLTRQ0, FLCTL_FLTRQ1),
- INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3),
};
static struct intc_mask_reg mask_registers[] __initdata = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
index 30baa63b24c8..d80802a49dbd 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c
@@ -20,18 +20,13 @@ static struct plat_sci_port sci_platform_data[] = {
.mapbase = 0xffea0000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 40, 41, 43, 42 },
+ .irqs = { 40, 40, 40, 40 },
}, {
.mapbase = 0xffeb0000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 44, 45, 47, 46 },
- },
-
- /*
- * The rest of these all have multiplexed IRQs
- */
- {
+ .irqs = { 44, 44, 44, 44 },
+ }, {
.mapbase = 0xffec0000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
@@ -91,33 +86,19 @@ enum {
IRL4_HHLL, IRL4_HHLH, IRL4_HHHL,
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
- WDT,
- TMU0, TMU1, TMU2, TMU2_TICPI,
- HUDI,
- DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3,
- DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE,
- SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI,
- SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI,
- DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
- DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
- HSPI,
+ WDT, TMU0, TMU1, TMU2, TMU2_TICPI,
+ HUDI, DMAC0, SCIF0, SCIF1, DMAC1, HSPI,
SCIF2, SCIF3, SCIF4, SCIF5,
- PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD,
- PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0,
- SIOF,
- MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY,
- DU,
- GDTA_GACLI, GDTA_GAMCI, GDTA_GAERI,
+ PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, PCIC5,
+ SIOF, MMCIF, DU, GDTA,
TMU3, TMU4, TMU5,
SSI0, SSI1,
HAC0, HAC1,
- FLCTL_FLSTE, FLCTL_FLEND, FLCTL_FLTRQ0, FLCTL_FLTRQ1,
- GPIOI0, GPIOI1, GPIOI2, GPIOI3,
+ FLCTL, GPIO,
/* interrupt groups */
- TMU012, DMAC0, SCIF0, SCIF1, DMAC1,
- PCIC5, MMCIF, GDTA, TMU345, FLCTL, GPIO
+ TMU012, TMU345
};
static struct intc_vect vectors[] __initdata = {
@@ -125,57 +106,45 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
INTC_VECT(HUDI, 0x600),
- INTC_VECT(DMAC0_DMINT0, 0x620), INTC_VECT(DMAC0_DMINT1, 0x640),
- INTC_VECT(DMAC0_DMINT2, 0x660), INTC_VECT(DMAC0_DMINT3, 0x680),
- INTC_VECT(DMAC0_DMINT4, 0x6a0), INTC_VECT(DMAC0_DMINT5, 0x6c0),
- INTC_VECT(DMAC0_DMAE, 0x6e0),
- INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720),
- INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760),
- INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0),
- INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0),
- INTC_VECT(DMAC1_DMINT6, 0x880), INTC_VECT(DMAC1_DMINT7, 0x8a0),
- INTC_VECT(DMAC1_DMINT8, 0x8c0), INTC_VECT(DMAC1_DMINT9, 0x8e0),
- INTC_VECT(DMAC1_DMINT10, 0x900), INTC_VECT(DMAC1_DMINT11, 0x920),
- INTC_VECT(DMAC1_DMAE, 0x940),
+ INTC_VECT(DMAC0, 0x620), INTC_VECT(DMAC0, 0x640),
+ INTC_VECT(DMAC0, 0x660), INTC_VECT(DMAC0, 0x680),
+ INTC_VECT(DMAC0, 0x6a0), INTC_VECT(DMAC0, 0x6c0),
+ INTC_VECT(DMAC0, 0x6e0),
+ INTC_VECT(SCIF0, 0x700), INTC_VECT(SCIF0, 0x720),
+ INTC_VECT(SCIF0, 0x740), INTC_VECT(SCIF0, 0x760),
+ INTC_VECT(SCIF1, 0x780), INTC_VECT(SCIF1, 0x7a0),
+ INTC_VECT(SCIF1, 0x7c0), INTC_VECT(SCIF1, 0x7e0),
+ INTC_VECT(DMAC1, 0x880), INTC_VECT(DMAC1, 0x8a0),
+ INTC_VECT(DMAC1, 0x8c0), INTC_VECT(DMAC1, 0x8e0),
+ INTC_VECT(DMAC1, 0x900), INTC_VECT(DMAC1, 0x920),
+ INTC_VECT(DMAC1, 0x940),
INTC_VECT(HSPI, 0x960),
INTC_VECT(SCIF2, 0x980), INTC_VECT(SCIF3, 0x9a0),
INTC_VECT(SCIF4, 0x9c0), INTC_VECT(SCIF5, 0x9e0),
INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20),
INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60),
- INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0),
- INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0),
- INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20),
+ INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIC5, 0xaa0),
+ INTC_VECT(PCIC5, 0xac0), INTC_VECT(PCIC5, 0xae0),
+ INTC_VECT(PCIC5, 0xb00), INTC_VECT(PCIC5, 0xb20),
INTC_VECT(SIOF, 0xc00),
- INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20),
- INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60),
+ INTC_VECT(MMCIF, 0xd00), INTC_VECT(MMCIF, 0xd20),
+ INTC_VECT(MMCIF, 0xd40), INTC_VECT(MMCIF, 0xd60),
INTC_VECT(DU, 0xd80),
- INTC_VECT(GDTA_GACLI, 0xda0), INTC_VECT(GDTA_GAMCI, 0xdc0),
- INTC_VECT(GDTA_GAERI, 0xde0),
+ INTC_VECT(GDTA, 0xda0), INTC_VECT(GDTA, 0xdc0),
+ INTC_VECT(GDTA, 0xde0),
INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
INTC_VECT(TMU5, 0xe40),
INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0),
INTC_VECT(HAC0, 0xec0), INTC_VECT(HAC1, 0xee0),
- INTC_VECT(FLCTL_FLSTE, 0xf00), INTC_VECT(FLCTL_FLEND, 0xf20),
- INTC_VECT(FLCTL_FLTRQ0, 0xf40), INTC_VECT(FLCTL_FLTRQ1, 0xf60),
- INTC_VECT(GPIOI0, 0xf80), INTC_VECT(GPIOI1, 0xfa0),
- INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0),
+ INTC_VECT(FLCTL, 0xf00), INTC_VECT(FLCTL, 0xf20),
+ INTC_VECT(FLCTL, 0xf40), INTC_VECT(FLCTL, 0xf60),
+ INTC_VECT(GPIO, 0xf80), INTC_VECT(GPIO, 0xfa0),
+ INTC_VECT(GPIO, 0xfc0), INTC_VECT(GPIO, 0xfe0),
};
static struct intc_group groups[] __initdata = {
INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
- INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2,
- DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
- INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
- INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
- INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
- DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE),
- INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0),
- INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY),
- INTC_GROUP(GDTA, GDTA_GACLI, GDTA_GAMCI, GDTA_GAERI),
INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
- INTC_GROUP(FLCTL, FLCTL_FLSTE, FLCTL_FLEND,
- FLCTL_FLTRQ0, FLCTL_FLTRQ1),
- INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3),
};
static struct intc_mask_reg mask_registers[] __initdata = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
new file mode 100644
index 000000000000..5a47e1cf442e
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c
@@ -0,0 +1,490 @@
+/*
+ * SH7786 Setup
+ *
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on SH7785 Setup
+ *
+ * Copyright (C) 2007 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/serial_sci.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <asm/mmzone.h>
+
+static struct plat_sci_port sci_platform_data[] = {
+ {
+ .mapbase = 0xffea0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 40, 41, 43, 42 },
+ },
+ /*
+ * The rest of these all have multiplexed IRQs
+ */
+ {
+ .mapbase = 0xffeb0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 44, 44, 44, 44 },
+ }, {
+ .mapbase = 0xffec0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 50, 50, 50, 50 },
+ }, {
+ .mapbase = 0xffed0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 51, 51, 51, 51 },
+ }, {
+ .mapbase = 0xffee0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 52, 52, 52, 52 },
+ }, {
+ .mapbase = 0xffef0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .type = PORT_SCIF,
+ .irqs = { 53, 53, 53, 53 },
+ }, {
+ .flags = 0,
+ }
+};
+
+static struct platform_device sci_device = {
+ .name = "sh-sci",
+ .id = -1,
+ .dev = {
+ .platform_data = sci_platform_data,
+ },
+};
+
+static struct resource usb_ohci_resources[] = {
+ [0] = {
+ .start = 0xffe70400,
+ .end = 0xffe704ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 77,
+ .end = 77,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 usb_ohci_dma_mask = DMA_BIT_MASK(32);
+static struct platform_device usb_ohci_device = {
+ .name = "sh_ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &usb_ohci_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(usb_ohci_resources),
+ .resource = usb_ohci_resources,
+};
+
+static struct platform_device *sh7786_devices[] __initdata = {
+ &sci_device,
+ &usb_ohci_device,
+};
+
+
+/*
+ * Please call this function if your platform board
+ * use external clock for USB
+ * */
+#define USBCTL0 0xffe70858
+#define CLOCK_MODE_MASK 0xffffff7f
+#define EXT_CLOCK_MODE 0x00000080
+void __init sh7786_usb_use_exclock(void)
+{
+ u32 val = __raw_readl(USBCTL0) & CLOCK_MODE_MASK;
+ __raw_writel(val | EXT_CLOCK_MODE, USBCTL0);
+}
+
+#define USBINITREG1 0xffe70094
+#define USBINITREG2 0xffe7009c
+#define USBINITVAL1 0x00ff0040
+#define USBINITVAL2 0x00000001
+
+#define USBPCTL1 0xffe70804
+#define USBST 0xffe70808
+#define PHY_ENB 0x00000001
+#define PLL_ENB 0x00000002
+#define PHY_RST 0x00000004
+#define ACT_PLL_STATUS 0xc0000000
+static void __init sh7786_usb_setup(void)
+{
+ int i = 1000000;
+
+ /*
+ * USB initial settings
+ *
+ * The following settings are necessary
+ * for using the USB modules.
+ *
+ * see "USB Inital Settings" for detail
+ */
+ __raw_writel(USBINITVAL1, USBINITREG1);
+ __raw_writel(USBINITVAL2, USBINITREG2);
+
+ /*
+ * Set the PHY and PLL enable bit
+ */
+ __raw_writel(PHY_ENB | PLL_ENB, USBPCTL1);
+ while (i-- &&
+ ((__raw_readl(USBST) & ACT_PLL_STATUS) != ACT_PLL_STATUS))
+ cpu_relax();
+
+ if (i) {
+ /* Set the PHY RST bit */
+ __raw_writel(PHY_ENB | PLL_ENB | PHY_RST, USBPCTL1);
+ printk(KERN_INFO "sh7786 usb setup done\n");
+ }
+}
+
+static int __init sh7786_devices_setup(void)
+{
+ sh7786_usb_setup();
+ return platform_add_devices(sh7786_devices,
+ ARRAY_SIZE(sh7786_devices));
+}
+device_initcall(sh7786_devices_setup);
+
+enum {
+ UNUSED = 0,
+
+ /* interrupt sources */
+
+ IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
+ IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
+ IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
+ IRL0_HHLL, IRL0_HHLH, IRL0_HHHL,
+
+ IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
+ IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
+ IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
+ IRL4_HHLL, IRL4_HHLH, IRL4_HHHL,
+
+ IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
+ WDT,
+ TMU0_0, TMU0_1, TMU0_2, TMU0_3,
+ TMU1_0, TMU1_1, TMU1_2,
+ DMAC0_0, DMAC0_1, DMAC0_2, DMAC0_3, DMAC0_4, DMAC0_5, DMAC0_6,
+ HUDI1, HUDI0,
+ DMAC1_0, DMAC1_1, DMAC1_2, DMAC1_3,
+ HPB_0, HPB_1, HPB_2,
+ SCIF0_0, SCIF0_1, SCIF0_2, SCIF0_3,
+ SCIF1,
+ TMU2, TMU3,
+ SCIF2, SCIF3, SCIF4, SCIF5,
+ Eth_0, Eth_1,
+ PCIeC0_0, PCIeC0_1, PCIeC0_2,
+ PCIeC1_0, PCIeC1_1, PCIeC1_2,
+ USB,
+ I2C0, I2C1,
+ DU,
+ SSI0, SSI1, SSI2, SSI3,
+ PCIeC2_0, PCIeC2_1, PCIeC2_2,
+ HAC0, HAC1,
+ FLCTL,
+ HSPI,
+ GPIO0, GPIO1,
+ Thermal,
+ INTC0, INTC1, INTC2, INTC3, INTC4, INTC5, INTC6, INTC7,
+
+ /* interrupt groups */
+};
+
+static struct intc_vect vectors[] __initdata = {
+ INTC_VECT(WDT, 0x3e0),
+ INTC_VECT(TMU0_0, 0x400), INTC_VECT(TMU0_1, 0x420),
+ INTC_VECT(TMU0_2, 0x440), INTC_VECT(TMU0_3, 0x460),
+ INTC_VECT(TMU1_0, 0x480), INTC_VECT(TMU1_1, 0x4a0),
+ INTC_VECT(TMU1_2, 0x4c0),
+ INTC_VECT(DMAC0_0, 0x500), INTC_VECT(DMAC0_1, 0x520),
+ INTC_VECT(DMAC0_2, 0x540), INTC_VECT(DMAC0_3, 0x560),
+ INTC_VECT(DMAC0_4, 0x580), INTC_VECT(DMAC0_5, 0x5a0),
+ INTC_VECT(DMAC0_6, 0x5c0),
+ INTC_VECT(HUDI1, 0x5e0), INTC_VECT(HUDI0, 0x600),
+ INTC_VECT(DMAC1_0, 0x620), INTC_VECT(DMAC1_1, 0x640),
+ INTC_VECT(DMAC1_2, 0x660), INTC_VECT(DMAC1_3, 0x680),
+ INTC_VECT(HPB_0, 0x6a0), INTC_VECT(HPB_1, 0x6c0),
+ INTC_VECT(HPB_2, 0x6e0),
+ INTC_VECT(SCIF0_0, 0x700), INTC_VECT(SCIF0_1, 0x720),
+ INTC_VECT(SCIF0_2, 0x740), INTC_VECT(SCIF0_3, 0x760),
+ INTC_VECT(SCIF1, 0x780),
+ INTC_VECT(TMU2, 0x7a0), INTC_VECT(TMU3, 0x7c0),
+ INTC_VECT(SCIF2, 0x840), INTC_VECT(SCIF3, 0x860),
+ INTC_VECT(SCIF4, 0x880), INTC_VECT(SCIF5, 0x8a0),
+ INTC_VECT(Eth_0, 0x8c0), INTC_VECT(Eth_1, 0x8e0),
+ INTC_VECT(PCIeC0_0, 0xae0), INTC_VECT(PCIeC0_1, 0xb00),
+ INTC_VECT(PCIeC0_2, 0xb20),
+ INTC_VECT(PCIeC1_0, 0xb40), INTC_VECT(PCIeC1_1, 0xb60),
+ INTC_VECT(PCIeC1_2, 0xb80),
+ INTC_VECT(USB, 0xba0),
+ INTC_VECT(I2C0, 0xcc0), INTC_VECT(I2C1, 0xce0),
+ INTC_VECT(DU, 0xd00),
+ INTC_VECT(SSI0, 0xd20), INTC_VECT(SSI1, 0xd40),
+ INTC_VECT(SSI2, 0xd60), INTC_VECT(SSI3, 0xd80),
+ INTC_VECT(PCIeC2_0, 0xda0), INTC_VECT(PCIeC2_1, 0xdc0),
+ INTC_VECT(PCIeC2_2, 0xde0),
+ INTC_VECT(HAC0, 0xe00), INTC_VECT(HAC1, 0xe20),
+ INTC_VECT(FLCTL, 0xe40),
+ INTC_VECT(HSPI, 0xe80),
+ INTC_VECT(GPIO0, 0xea0), INTC_VECT(GPIO1, 0xec0),
+ INTC_VECT(Thermal, 0xee0),
+};
+
+/* FIXME: Main CPU support only now */
+#if 1 /* Main CPU */
+#define CnINTMSK0 0xfe410030
+#define CnINTMSK1 0xfe410040
+#define CnINTMSKCLR0 0xfe410050
+#define CnINTMSKCLR1 0xfe410060
+#define CnINT2MSKR0 0xfe410a20
+#define CnINT2MSKR1 0xfe410a24
+#define CnINT2MSKR2 0xfe410a28
+#define CnINT2MSKR3 0xfe410a2c
+#define CnINT2MSKCR0 0xfe410a30
+#define CnINT2MSKCR1 0xfe410a34
+#define CnINT2MSKCR2 0xfe410a38
+#define CnINT2MSKCR3 0xfe410a3c
+#else /* Sub CPU */
+#define CnINTMSK0 0xfe410034
+#define CnINTMSK1 0xfe410044
+#define CnINTMSKCLR0 0xfe410054
+#define CnINTMSKCLR1 0xfe410064
+#define CnINT2MSKR0 0xfe410b20
+#define CnINT2MSKR1 0xfe410b24
+#define CnINT2MSKR2 0xfe410b28
+#define CnINT2MSKR3 0xfe410b2c
+#define CnINT2MSKCR0 0xfe410b30
+#define CnINT2MSKCR1 0xfe410b34
+#define CnINT2MSKCR2 0xfe410b38
+#define CnINT2MSKCR3 0xfe410b3c
+#endif
+
+#define INTMSK2 0xfe410068
+#define INTMSKCLR2 0xfe41006c
+
+static struct intc_mask_reg mask_registers[] __initdata = {
+ { CnINTMSK0, CnINTMSKCLR0, 32,
+ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+ { INTMSK2, INTMSKCLR2, 32,
+ { IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
+ IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
+ IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
+ IRL0_HHLL, IRL0_HHLH, IRL0_HHHL, 0,
+ IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
+ IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
+ IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
+ IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } },
+ { CnINT2MSKR0, CnINT2MSKCR0 , 32,
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, WDT } },
+ { CnINT2MSKR1, CnINT2MSKCR1, 32,
+ { TMU0_0, TMU0_1, TMU0_2, TMU0_3, TMU1_0, TMU1_1, TMU1_2, 0,
+ DMAC0_0, DMAC0_1, DMAC0_2, DMAC0_3, DMAC0_4, DMAC0_5, DMAC0_6,
+ HUDI1, HUDI0,
+ DMAC1_0, DMAC1_1, DMAC1_2, DMAC1_3,
+ HPB_0, HPB_1, HPB_2,
+ SCIF0_0, SCIF0_1, SCIF0_2, SCIF0_3,
+ SCIF1,
+ TMU2, TMU3, 0, } },
+ { CnINT2MSKR2, CnINT2MSKCR2, 32,
+ { 0, 0, SCIF2, SCIF3, SCIF4, SCIF5,
+ Eth_0, Eth_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ PCIeC0_0, PCIeC0_1, PCIeC0_2,
+ PCIeC1_0, PCIeC1_1, PCIeC1_2,
+ USB, 0, 0 } },
+ { CnINT2MSKR3, CnINT2MSKCR3, 32,
+ { 0, 0, 0, 0, 0, 0,
+ I2C0, I2C1,
+ DU, SSI0, SSI1, SSI2, SSI3,
+ PCIeC2_0, PCIeC2_1, PCIeC2_2,
+ HAC0, HAC1,
+ FLCTL, 0,
+ HSPI, GPIO0, GPIO1, Thermal,
+ 0, 0, 0, 0, 0, 0, 0, 0 } },
+};
+
+static struct intc_prio_reg prio_registers[] __initdata = {
+ { 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3,
+ IRQ4, IRQ5, IRQ6, IRQ7 } },
+ { 0xfe410800, 0, 32, 8, /* INT2PRI0 */ { 0, 0, 0, WDT } },
+ { 0xfe410804, 0, 32, 8, /* INT2PRI1 */ { TMU0_0, TMU0_1,
+ TMU0_2, TMU0_3 } },
+ { 0xfe410808, 0, 32, 8, /* INT2PRI2 */ { TMU1_0, TMU1_1,
+ TMU1_2, 0 } },
+ { 0xfe41080c, 0, 32, 8, /* INT2PRI3 */ { DMAC0_0, DMAC0_1,
+ DMAC0_2, DMAC0_3 } },
+ { 0xfe410810, 0, 32, 8, /* INT2PRI4 */ { DMAC0_4, DMAC0_5,
+ DMAC0_6, HUDI1 } },
+ { 0xfe410814, 0, 32, 8, /* INT2PRI5 */ { HUDI0, DMAC1_0,
+ DMAC1_1, DMAC1_2 } },
+ { 0xfe410818, 0, 32, 8, /* INT2PRI6 */ { DMAC1_3, HPB_0,
+ HPB_1, HPB_2 } },
+ { 0xfe41081c, 0, 32, 8, /* INT2PRI7 */ { SCIF0_0, SCIF0_1,
+ SCIF0_2, SCIF0_3 } },
+ { 0xfe410820, 0, 32, 8, /* INT2PRI8 */ { SCIF1, TMU2, TMU3, 0 } },
+ { 0xfe410824, 0, 32, 8, /* INT2PRI9 */ { 0, 0, SCIF2, SCIF3 } },
+ { 0xfe410828, 0, 32, 8, /* INT2PRI10 */ { SCIF4, SCIF5,
+ Eth_0, Eth_1 } },
+ { 0xfe41082c, 0, 32, 8, /* INT2PRI11 */ { 0, 0, 0, 0 } },
+ { 0xfe410830, 0, 32, 8, /* INT2PRI12 */ { 0, 0, 0, 0 } },
+ { 0xfe410834, 0, 32, 8, /* INT2PRI13 */ { 0, 0, 0, 0 } },
+ { 0xfe410838, 0, 32, 8, /* INT2PRI14 */ { 0, 0, 0, PCIeC0_0 } },
+ { 0xfe41083c, 0, 32, 8, /* INT2PRI15 */ { PCIeC0_1, PCIeC0_2,
+ PCIeC1_0, PCIeC1_1 } },
+ { 0xfe410840, 0, 32, 8, /* INT2PRI16 */ { PCIeC1_2, USB, 0, 0 } },
+ { 0xfe410844, 0, 32, 8, /* INT2PRI17 */ { 0, 0, 0, 0 } },
+ { 0xfe410848, 0, 32, 8, /* INT2PRI18 */ { 0, 0, I2C0, I2C1 } },
+ { 0xfe41084c, 0, 32, 8, /* INT2PRI19 */ { DU, SSI0, SSI1, SSI2 } },
+ { 0xfe410850, 0, 32, 8, /* INT2PRI20 */ { SSI3, PCIeC2_0,
+ PCIeC2_1, PCIeC2_2 } },
+ { 0xfe410854, 0, 32, 8, /* INT2PRI21 */ { HAC0, HAC1, FLCTL, 0 } },
+ { 0xfe410858, 0, 32, 8, /* INT2PRI22 */ { HSPI, GPIO0,
+ GPIO1, Thermal } },
+ { 0xfe41085c, 0, 32, 8, /* INT2PRI23 */ { 0, 0, 0, 0 } },
+ { 0xfe410860, 0, 32, 8, /* INT2PRI24 */ { 0, 0, 0, 0 } },
+};
+
+static DECLARE_INTC_DESC(intc_desc, "sh7786", vectors, NULL,
+ mask_registers, prio_registers, NULL);
+
+/* Support for external interrupt pins in IRQ mode */
+
+static struct intc_vect vectors_irq0123[] __initdata = {
+ INTC_VECT(IRQ0, 0x200), INTC_VECT(IRQ1, 0x240),
+ INTC_VECT(IRQ2, 0x280), INTC_VECT(IRQ3, 0x2c0),
+};
+
+static struct intc_vect vectors_irq4567[] __initdata = {
+ INTC_VECT(IRQ4, 0x300), INTC_VECT(IRQ5, 0x340),
+ INTC_VECT(IRQ6, 0x380), INTC_VECT(IRQ7, 0x3c0),
+};
+
+static struct intc_sense_reg sense_registers[] __initdata = {
+ { 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3,
+ IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static struct intc_mask_reg ack_registers[] __initdata = {
+ { 0xfe410024, 0, 32, /* INTREQ */
+ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh7786-irq0123",
+ vectors_irq0123, NULL, mask_registers,
+ prio_registers, sense_registers, ack_registers);
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq4567, "sh7786-irq4567",
+ vectors_irq4567, NULL, mask_registers,
+ prio_registers, sense_registers, ack_registers);
+
+/* External interrupt pins in IRL mode */
+
+static struct intc_vect vectors_irl0123[] __initdata = {
+ INTC_VECT(IRL0_LLLL, 0x200), INTC_VECT(IRL0_LLLH, 0x220),
+ INTC_VECT(IRL0_LLHL, 0x240), INTC_VECT(IRL0_LLHH, 0x260),
+ INTC_VECT(IRL0_LHLL, 0x280), INTC_VECT(IRL0_LHLH, 0x2a0),
+ INTC_VECT(IRL0_LHHL, 0x2c0), INTC_VECT(IRL0_LHHH, 0x2e0),
+ INTC_VECT(IRL0_HLLL, 0x300), INTC_VECT(IRL0_HLLH, 0x320),
+ INTC_VECT(IRL0_HLHL, 0x340), INTC_VECT(IRL0_HLHH, 0x360),
+ INTC_VECT(IRL0_HHLL, 0x380), INTC_VECT(IRL0_HHLH, 0x3a0),
+ INTC_VECT(IRL0_HHHL, 0x3c0),
+};
+
+static struct intc_vect vectors_irl4567[] __initdata = {
+ INTC_VECT(IRL4_LLLL, 0x900), INTC_VECT(IRL4_LLLH, 0x920),
+ INTC_VECT(IRL4_LLHL, 0x940), INTC_VECT(IRL4_LLHH, 0x960),
+ INTC_VECT(IRL4_LHLL, 0x980), INTC_VECT(IRL4_LHLH, 0x9a0),
+ INTC_VECT(IRL4_LHHL, 0x9c0), INTC_VECT(IRL4_LHHH, 0x9e0),
+ INTC_VECT(IRL4_HLLL, 0xa00), INTC_VECT(IRL4_HLLH, 0xa20),
+ INTC_VECT(IRL4_HLHL, 0xa40), INTC_VECT(IRL4_HLHH, 0xa60),
+ INTC_VECT(IRL4_HHLL, 0xa80), INTC_VECT(IRL4_HHLH, 0xaa0),
+ INTC_VECT(IRL4_HHHL, 0xac0),
+};
+
+static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7786-irl0123", vectors_irl0123,
+ NULL, mask_registers, NULL, NULL);
+
+static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7786-irl4567", vectors_irl4567,
+ NULL, mask_registers, NULL, NULL);
+
+#define INTC_ICR0 0xfe410000
+#define INTC_INTMSK0 CnINTMSK0
+#define INTC_INTMSK1 CnINTMSK1
+#define INTC_INTMSK2 INTMSK2
+#define INTC_INTMSKCLR1 CnINTMSKCLR1
+#define INTC_INTMSKCLR2 INTMSKCLR2
+
+void __init plat_irq_setup(void)
+{
+ /* disable IRQ3-0 + IRQ7-4 */
+ ctrl_outl(0xff000000, INTC_INTMSK0);
+
+ /* disable IRL3-0 + IRL7-4 */
+ ctrl_outl(0xc0000000, INTC_INTMSK1);
+ ctrl_outl(0xfffefffe, INTC_INTMSK2);
+
+ /* select IRL mode for IRL3-0 + IRL7-4 */
+ ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+
+ register_intc_controller(&intc_desc);
+}
+
+void __init plat_irq_setup_pins(int mode)
+{
+ switch (mode) {
+ case IRQ_MODE_IRQ7654:
+ /* select IRQ mode for IRL7-4 */
+ ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0);
+ register_intc_controller(&intc_desc_irq4567);
+ break;
+ case IRQ_MODE_IRQ3210:
+ /* select IRQ mode for IRL3-0 */
+ ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0);
+ register_intc_controller(&intc_desc_irq0123);
+ break;
+ case IRQ_MODE_IRL7654:
+ /* enable IRL7-4 but don't provide any masking */
+ ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+ ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
+ break;
+ case IRQ_MODE_IRL3210:
+ /* enable IRL0-3 but don't provide any masking */
+ ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+ ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
+ break;
+ case IRQ_MODE_IRL7654_MASK:
+ /* enable IRL7-4 and mask using cpu intc controller */
+ ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+ register_intc_controller(&intc_desc_irl4567);
+ break;
+ case IRQ_MODE_IRL3210_MASK:
+ /* enable IRL0-3 and mask using cpu intc controller */
+ ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+ register_intc_controller(&intc_desc_irl0123);
+ break;
+ default:
+ BUG();
+ }
+}
+
+void __init plat_mem_setup(void)
+{
+}
diff --git a/arch/sh/kernel/cpu/shmobile/Makefile b/arch/sh/kernel/cpu/shmobile/Makefile
new file mode 100644
index 000000000000..08bfa7c7db29
--- /dev/null
+++ b/arch/sh/kernel/cpu/shmobile/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the Linux/SuperH SH-Mobile backends.
+#
+
+# Power Management & Sleep mode
+obj-$(CONFIG_PM) += pm.o sleep.o
diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c
new file mode 100644
index 000000000000..8c067adf6830
--- /dev/null
+++ b/arch/sh/kernel/cpu/shmobile/pm.c
@@ -0,0 +1,92 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/pm-sh_mobile.c
+ *
+ * Power management support code for SuperH Mobile
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+#include <asm/suspend.h>
+#include <asm/uaccess.h>
+
+/*
+ * Sleep modes available on SuperH Mobile:
+ *
+ * Sleep mode is just plain "sleep" instruction
+ * Sleep Self-Refresh mode is above plus RAM put in Self-Refresh
+ * Standby Self-Refresh mode is above plus stopped clocks
+ */
+#define SUSP_MODE_SLEEP (SUSP_SH_SLEEP)
+#define SUSP_MODE_SLEEP_SF (SUSP_SH_SLEEP | SUSP_SH_SF)
+#define SUSP_MODE_STANDBY_SF (SUSP_SH_STANDBY | SUSP_SH_SF)
+
+/*
+ * The following modes are not there yet:
+ *
+ * R-standby mode is unsupported, but will be added in the future
+ * U-standby mode is low priority since it needs bootloader hacks
+ *
+ * All modes should be tied in with cpuidle. But before that can
+ * happen we need to keep track of enabled hardware blocks so we
+ * can avoid entering sleep modes that stop clocks to hardware
+ * blocks that are in use even though the cpu core is idle.
+ */
+
+extern const unsigned char sh_mobile_standby[];
+extern const unsigned int sh_mobile_standby_size;
+
+static void sh_mobile_call_standby(unsigned long mode)
+{
+ extern void *vbr_base;
+ void *onchip_mem = (void *)0xe5200000; /* ILRAM */
+ void (*standby_onchip_mem)(unsigned long) = onchip_mem;
+
+ /* Note: Wake up from sleep may generate exceptions!
+ * Setup VBR to point to on-chip ram if self-refresh is
+ * going to be used.
+ */
+ if (mode & SUSP_SH_SF)
+ asm volatile("ldc %0, vbr" : : "r" (onchip_mem) : "memory");
+
+ /* Copy the assembly snippet to the otherwise ununsed ILRAM */
+ memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size);
+ wmb();
+ ctrl_barrier();
+
+ /* Let assembly snippet in on-chip memory handle the rest */
+ standby_onchip_mem(mode);
+
+ /* Put VBR back in System RAM again */
+ if (mode & SUSP_SH_SF)
+ asm volatile("ldc %0, vbr" : : "r" (&vbr_base) : "memory");
+}
+
+static int sh_pm_enter(suspend_state_t state)
+{
+ local_irq_disable();
+ set_bl_bit();
+ sh_mobile_call_standby(SUSP_MODE_STANDBY_SF);
+ local_irq_disable();
+ clear_bl_bit();
+ return 0;
+}
+
+static struct platform_suspend_ops sh_pm_ops = {
+ .enter = sh_pm_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+static int __init sh_pm_init(void)
+{
+ suspend_set_ops(&sh_pm_ops);
+ return 0;
+}
+
+late_initcall(sh_pm_init);
diff --git a/arch/sh/kernel/cpu/shmobile/sleep.S b/arch/sh/kernel/cpu/shmobile/sleep.S
new file mode 100644
index 000000000000..5d888ef53d82
--- /dev/null
+++ b/arch/sh/kernel/cpu/shmobile/sleep.S
@@ -0,0 +1,125 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/sleep-sh_mobile.S
+ *
+ * Sleep mode and Standby modes support for SuperH Mobile
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/sys.h>
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/suspend.h>
+
+/* manage self-refresh and enter standby mode.
+ * this code will be copied to on-chip memory and executed from there.
+ */
+
+ .balign 4096,0,4096
+ENTRY(sh_mobile_standby)
+ mov r4, r0
+
+ tst #SUSP_SH_SF, r0
+ bt skip_set_sf
+
+ /* SDRAM: disable power down and put in self-refresh mode */
+ mov.l 1f, r4
+ mov.l 2f, r1
+ mov.l @r4, r2
+ or r1, r2
+ mov.l 3f, r3
+ and r3, r2
+ mov.l r2, @r4
+
+skip_set_sf:
+ tst #SUSP_SH_SLEEP, r0
+ bt test_standby
+
+ /* set mode to "sleep mode" */
+ bra do_sleep
+ mov #0x00, r1
+
+test_standby:
+ tst #SUSP_SH_STANDBY, r0
+ bt test_rstandby
+
+ /* set mode to "software standby mode" */
+ bra do_sleep
+ mov #0x80, r1
+
+test_rstandby:
+ tst #SUSP_SH_RSTANDBY, r0
+ bt test_ustandby
+
+ /* set mode to "r-standby mode" */
+ bra do_sleep
+ mov #0x20, r1
+
+test_ustandby:
+ tst #SUSP_SH_USTANDBY, r0
+ bt done_sleep
+
+ /* set mode to "u-standby mode" */
+ mov #0x10, r1
+
+ /* fall-through */
+
+do_sleep:
+ /* setup and enter selected standby mode */
+ mov.l 5f, r4
+ mov.l r1, @r4
+ sleep
+
+done_sleep:
+ /* reset standby mode to sleep mode */
+ mov.l 5f, r4
+ mov #0x00, r1
+ mov.l r1, @r4
+
+ tst #SUSP_SH_SF, r0
+ bt skip_restore_sf
+
+ /* SDRAM: set auto-refresh mode */
+ mov.l 1f, r4
+ mov.l @r4, r2
+ mov.l 4f, r3
+ and r3, r2
+ mov.l r2, @r4
+ mov.l 6f, r4
+ mov.l 7f, r1
+ mov.l 8f, r2
+ mov.l @r4, r3
+ mov #-1, r4
+ add r4, r3
+ or r2, r3
+ mov.l r3, @r1
+skip_restore_sf:
+ rts
+ nop
+
+ .balign 4
+1: .long 0xfe400008 /* SDCR0 */
+2: .long 0x00000400
+3: .long 0xffff7fff
+4: .long 0xfffffbff
+5: .long 0xa4150020 /* STBCR */
+6: .long 0xfe40001c /* RTCOR */
+7: .long 0xfe400018 /* RTCNT */
+8: .long 0xa55a0000
+
+/* interrupt vector @ 0x600 */
+ .balign 0x400,0,0x400
+ .long 0xdeadbeef
+ .balign 0x200,0,0x200
+ /* sh7722 will end up here in sleep mode */
+ rte
+ nop
+sh_mobile_standby_end:
+
+ENTRY(sh_mobile_standby_size)
+ .long sh_mobile_standby_end - sh_mobile_standby
diff --git a/arch/sh/kernel/gpio.c b/arch/sh/kernel/gpio.c
index d37165361034..d22e5af699f9 100644
--- a/arch/sh/kernel/gpio.c
+++ b/arch/sh/kernel/gpio.c
@@ -19,36 +19,75 @@
#include <linux/bitops.h>
#include <linux/gpio.h>
-static struct pinmux_info *registered_gpio;
+static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
+{
+ if (enum_id < r->begin)
+ return 0;
-static struct pinmux_info *gpio_controller(unsigned gpio)
+ if (enum_id > r->end)
+ return 0;
+
+ return 1;
+}
+
+static unsigned long gpio_read_raw_reg(unsigned long reg,
+ unsigned long reg_width)
{
- if (!registered_gpio)
- return NULL;
+ switch (reg_width) {
+ case 8:
+ return ctrl_inb(reg);
+ case 16:
+ return ctrl_inw(reg);
+ case 32:
+ return ctrl_inl(reg);
+ }
- if (gpio < registered_gpio->first_gpio)
- return NULL;
+ BUG();
+ return 0;
+}
- if (gpio > registered_gpio->last_gpio)
- return NULL;
+static void gpio_write_raw_reg(unsigned long reg,
+ unsigned long reg_width,
+ unsigned long data)
+{
+ switch (reg_width) {
+ case 8:
+ ctrl_outb(data, reg);
+ return;
+ case 16:
+ ctrl_outw(data, reg);
+ return;
+ case 32:
+ ctrl_outl(data, reg);
+ return;
+ }
- return registered_gpio;
+ BUG();
}
-static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
+static void gpio_write_bit(struct pinmux_data_reg *dr,
+ unsigned long in_pos, unsigned long value)
{
- if (enum_id < r->begin)
- return 0;
+ unsigned long pos;
- if (enum_id > r->end)
- return 0;
+ pos = dr->reg_width - (in_pos + 1);
- return 1;
+#ifdef DEBUG
+ pr_info("write_bit addr = %lx, value = %ld, pos = %ld, "
+ "r_width = %ld\n",
+ dr->reg, !!value, pos, dr->reg_width);
+#endif
+
+ if (value)
+ set_bit(pos, &dr->reg_shadow);
+ else
+ clear_bit(pos, &dr->reg_shadow);
+
+ gpio_write_raw_reg(dr->reg, dr->reg_width, dr->reg_shadow);
}
-static int read_write_reg(unsigned long reg, unsigned long reg_width,
- unsigned long field_width, unsigned long in_pos,
- unsigned long value, int do_write)
+static int gpio_read_reg(unsigned long reg, unsigned long reg_width,
+ unsigned long field_width, unsigned long in_pos)
{
unsigned long data, mask, pos;
@@ -57,52 +96,53 @@ static int read_write_reg(unsigned long reg, unsigned long reg_width,
pos = reg_width - ((in_pos + 1) * field_width);
#ifdef DEBUG
- pr_info("%s, addr = %lx, value = %ld, pos = %ld, "
+ pr_info("read_reg: addr = %lx, pos = %ld, "
"r_width = %ld, f_width = %ld\n",
- do_write ? "write" : "read", reg, value, pos,
- reg_width, field_width);
+ reg, pos, reg_width, field_width);
#endif
- switch (reg_width) {
- case 8:
- data = ctrl_inb(reg);
- break;
- case 16:
- data = ctrl_inw(reg);
- break;
- case 32:
- data = ctrl_inl(reg);
- break;
- }
+ data = gpio_read_raw_reg(reg, reg_width);
+ return (data >> pos) & mask;
+}
- if (!do_write)
- return (data >> pos) & mask;
+static void gpio_write_reg(unsigned long reg, unsigned long reg_width,
+ unsigned long field_width, unsigned long in_pos,
+ unsigned long value)
+{
+ unsigned long mask, pos;
- data &= ~(mask << pos);
- data |= value << pos;
+ mask = (1 << field_width) - 1;
+ pos = reg_width - ((in_pos + 1) * field_width);
+
+#ifdef DEBUG
+ pr_info("write_reg addr = %lx, value = %ld, pos = %ld, "
+ "r_width = %ld, f_width = %ld\n",
+ reg, value, pos, reg_width, field_width);
+#endif
+
+ mask = ~(mask << pos);
+ value = value << pos;
switch (reg_width) {
case 8:
- ctrl_outb(data, reg);
+ ctrl_outb((ctrl_inb(reg) & mask) | value, reg);
break;
case 16:
- ctrl_outw(data, reg);
+ ctrl_outw((ctrl_inw(reg) & mask) | value, reg);
break;
case 32:
- ctrl_outl(data, reg);
+ ctrl_outl((ctrl_inl(reg) & mask) | value, reg);
break;
}
- return 0;
}
-static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
- struct pinmux_data_reg **drp, int *bitp)
+static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
{
- pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
+ struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
struct pinmux_data_reg *data_reg;
int k, n;
- if (!enum_in_range(enum_id, &gpioc->data))
+ if (!enum_in_range(gpiop->enum_id, &gpioc->data))
return -1;
k = 0;
@@ -113,19 +153,58 @@ static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
break;
for (n = 0; n < data_reg->reg_width; n++) {
- if (data_reg->enum_ids[n] == enum_id) {
- *drp = data_reg;
- *bitp = n;
+ if (data_reg->enum_ids[n] == gpiop->enum_id) {
+ gpiop->flags &= ~PINMUX_FLAG_DREG;
+ gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT);
+ gpiop->flags &= ~PINMUX_FLAG_DBIT;
+ gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT);
return 0;
-
}
}
k++;
}
+ BUG();
+
return -1;
}
+static void setup_data_regs(struct pinmux_info *gpioc)
+{
+ struct pinmux_data_reg *drp;
+ int k;
+
+ for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++)
+ setup_data_reg(gpioc, k);
+
+ k = 0;
+ while (1) {
+ drp = gpioc->data_regs + k;
+
+ if (!drp->reg_width)
+ break;
+
+ drp->reg_shadow = gpio_read_raw_reg(drp->reg, drp->reg_width);
+ k++;
+ }
+}
+
+static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
+ struct pinmux_data_reg **drp, int *bitp)
+{
+ struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
+ int k, n;
+
+ if (!enum_in_range(gpiop->enum_id, &gpioc->data))
+ return -1;
+
+ k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
+ n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
+ *drp = gpioc->data_regs + k;
+ *bitp = n;
+ return 0;
+}
+
static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
struct pinmux_cfg_reg **crp, int *indexp,
unsigned long **cntp)
@@ -187,9 +266,9 @@ static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
return -1;
}
-static int write_config_reg(struct pinmux_info *gpioc,
- struct pinmux_cfg_reg *crp,
- int index)
+static void write_config_reg(struct pinmux_info *gpioc,
+ struct pinmux_cfg_reg *crp,
+ int index)
{
unsigned long ncomb, pos, value;
@@ -197,8 +276,7 @@ static int write_config_reg(struct pinmux_info *gpioc,
pos = index / ncomb;
value = index % ncomb;
- return read_write_reg(crp->reg, crp->reg_width,
- crp->field_width, pos, value, 1);
+ gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value);
}
static int check_config_reg(struct pinmux_info *gpioc,
@@ -211,8 +289,8 @@ static int check_config_reg(struct pinmux_info *gpioc,
pos = index / ncomb;
value = index % ncomb;
- if (read_write_reg(crp->reg, crp->reg_width,
- crp->field_width, pos, 0, 0) == value)
+ if (gpio_read_reg(crp->reg, crp->reg_width,
+ crp->field_width, pos) == value)
return 0;
return -1;
@@ -220,8 +298,8 @@ static int check_config_reg(struct pinmux_info *gpioc,
enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
-int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
- int pinmux_type, int cfg_mode)
+static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
+ int pinmux_type, int cfg_mode)
{
struct pinmux_cfg_reg *cr = NULL;
pinmux_enum_t enum_id;
@@ -287,8 +365,7 @@ int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
break;
case GPIO_CFG_REQ:
- if (write_config_reg(gpioc, cr, index) != 0)
- goto out_err;
+ write_config_reg(gpioc, cr, index);
*cntp = *cntp + 1;
break;
@@ -305,9 +382,14 @@ int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
static DEFINE_SPINLOCK(gpio_lock);
-int __gpio_request(unsigned gpio)
+static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
{
- struct pinmux_info *gpioc = gpio_controller(gpio);
+ return container_of(chip, struct pinmux_info, chip);
+}
+
+static int sh_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct pinmux_info *gpioc = chip_to_pinmux(chip);
struct pinmux_data_reg *dummy;
unsigned long flags;
int i, ret, pinmux_type;
@@ -319,29 +401,30 @@ int __gpio_request(unsigned gpio)
spin_lock_irqsave(&gpio_lock, flags);
- if ((gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
+ if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
goto err_unlock;
/* setup pin function here if no data is associated with pin */
- if (get_data_reg(gpioc, gpio, &dummy, &i) != 0)
+ if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
pinmux_type = PINMUX_TYPE_FUNCTION;
else
pinmux_type = PINMUX_TYPE_GPIO;
if (pinmux_type == PINMUX_TYPE_FUNCTION) {
- if (pinmux_config_gpio(gpioc, gpio,
+ if (pinmux_config_gpio(gpioc, offset,
pinmux_type,
GPIO_CFG_DRYRUN) != 0)
goto err_unlock;
- if (pinmux_config_gpio(gpioc, gpio,
+ if (pinmux_config_gpio(gpioc, offset,
pinmux_type,
GPIO_CFG_REQ) != 0)
BUG();
}
- gpioc->gpios[gpio].flags = pinmux_type;
+ gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
+ gpioc->gpios[offset].flags |= pinmux_type;
ret = 0;
err_unlock:
@@ -349,11 +432,10 @@ int __gpio_request(unsigned gpio)
err_out:
return ret;
}
-EXPORT_SYMBOL(__gpio_request);
-void gpio_free(unsigned gpio)
+static void sh_gpio_free(struct gpio_chip *chip, unsigned offset)
{
- struct pinmux_info *gpioc = gpio_controller(gpio);
+ struct pinmux_info *gpioc = chip_to_pinmux(chip);
unsigned long flags;
int pinmux_type;
@@ -362,20 +444,23 @@ void gpio_free(unsigned gpio)
spin_lock_irqsave(&gpio_lock, flags);
- pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
- pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
- gpioc->gpios[gpio].flags = PINMUX_TYPE_NONE;
+ pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
+ pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
+ gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
+ gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
spin_unlock_irqrestore(&gpio_lock, flags);
}
-EXPORT_SYMBOL(gpio_free);
static int pinmux_direction(struct pinmux_info *gpioc,
unsigned gpio, int new_pinmux_type)
{
- int ret, pinmux_type;
+ int pinmux_type;
+ int ret = -EINVAL;
+
+ if (!gpioc)
+ goto err_out;
- ret = -EINVAL;
pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
switch (pinmux_type) {
@@ -401,102 +486,99 @@ static int pinmux_direction(struct pinmux_info *gpioc,
GPIO_CFG_REQ) != 0)
BUG();
- gpioc->gpios[gpio].flags = new_pinmux_type;
+ gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
+ gpioc->gpios[gpio].flags |= new_pinmux_type;
ret = 0;
err_out:
return ret;
}
-int gpio_direction_input(unsigned gpio)
+static int sh_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
- struct pinmux_info *gpioc = gpio_controller(gpio);
+ struct pinmux_info *gpioc = chip_to_pinmux(chip);
unsigned long flags;
- int ret = -EINVAL;
-
- if (!gpioc)
- goto err_out;
+ int ret;
spin_lock_irqsave(&gpio_lock, flags);
- ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_INPUT);
+ ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
spin_unlock_irqrestore(&gpio_lock, flags);
- err_out:
+
return ret;
}
-EXPORT_SYMBOL(gpio_direction_input);
-static int __gpio_get_set_value(struct pinmux_info *gpioc,
- unsigned gpio, int value,
- int do_write)
+static void sh_gpio_set_value(struct pinmux_info *gpioc,
+ unsigned gpio, int value)
{
struct pinmux_data_reg *dr = NULL;
int bit = 0;
- if (get_data_reg(gpioc, gpio, &dr, &bit) != 0)
+ if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
BUG();
else
- value = read_write_reg(dr->reg, dr->reg_width,
- 1, bit, !!value, do_write);
-
- return value;
+ gpio_write_bit(dr, bit, value);
}
-int gpio_direction_output(unsigned gpio, int value)
+static int sh_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
{
- struct pinmux_info *gpioc = gpio_controller(gpio);
+ struct pinmux_info *gpioc = chip_to_pinmux(chip);
unsigned long flags;
- int ret = -EINVAL;
-
- if (!gpioc)
- goto err_out;
+ int ret;
+ sh_gpio_set_value(gpioc, offset, value);
spin_lock_irqsave(&gpio_lock, flags);
- __gpio_get_set_value(gpioc, gpio, value, 1);
- ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_OUTPUT);
+ ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
spin_unlock_irqrestore(&gpio_lock, flags);
- err_out:
+
return ret;
}
-EXPORT_SYMBOL(gpio_direction_output);
-int gpio_get_value(unsigned gpio)
+static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
{
- struct pinmux_info *gpioc = gpio_controller(gpio);
- unsigned long flags;
- int value = 0;
+ struct pinmux_data_reg *dr = NULL;
+ int bit = 0;
- if (!gpioc)
+ if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0) {
BUG();
- else {
- spin_lock_irqsave(&gpio_lock, flags);
- value = __gpio_get_set_value(gpioc, gpio, 0, 0);
- spin_unlock_irqrestore(&gpio_lock, flags);
+ return 0;
}
- return value;
+ return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
}
-EXPORT_SYMBOL(gpio_get_value);
-void gpio_set_value(unsigned gpio, int value)
+static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
{
- struct pinmux_info *gpioc = gpio_controller(gpio);
- unsigned long flags;
+ return sh_gpio_get_value(chip_to_pinmux(chip), offset);
+}
- if (!gpioc)
- BUG();
- else {
- spin_lock_irqsave(&gpio_lock, flags);
- __gpio_get_set_value(gpioc, gpio, value, 1);
- spin_unlock_irqrestore(&gpio_lock, flags);
- }
+static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ sh_gpio_set_value(chip_to_pinmux(chip), offset, value);
}
-EXPORT_SYMBOL(gpio_set_value);
int register_pinmux(struct pinmux_info *pip)
{
- registered_gpio = pip;
- pr_info("pinmux: %s handling gpio %d -> %d\n",
+ struct gpio_chip *chip = &pip->chip;
+
+ pr_info("sh pinmux: %s handling gpio %d -> %d\n",
pip->name, pip->first_gpio, pip->last_gpio);
- return 0;
+ setup_data_regs(pip);
+
+ chip->request = sh_gpio_request;
+ chip->free = sh_gpio_free;
+ chip->direction_input = sh_gpio_direction_input;
+ chip->get = sh_gpio_get;
+ chip->direction_output = sh_gpio_direction_output;
+ chip->set = sh_gpio_set;
+
+ WARN_ON(pip->first_gpio != 0); /* needs testing */
+
+ chip->label = pip->name;
+ chip->owner = THIS_MODULE;
+ chip->base = pip->first_gpio;
+ chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
+
+ return gpiochip_add(chip);
}
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index fe59ccfc1152..f35ed0348850 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -38,7 +38,7 @@ static int __init hlt_setup(char *__unused)
}
__setup("hlt", hlt_setup);
-static void default_idle(void)
+void default_idle(void)
{
if (!hlt_counter) {
clear_thread_flag(TIF_POLLING_NRFLAG);
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index 39cd7f3aec7b..c22853b059ef 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -14,6 +14,7 @@
#include <linux/bitops.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/uaccess.h>
@@ -32,6 +33,15 @@ EXPORT_SYMBOL_GPL(trapped_mem);
#endif
static DEFINE_SPINLOCK(trapped_lock);
+static int trapped_io_disable __read_mostly;
+
+static int __init trapped_io_setup(char *__unused)
+{
+ trapped_io_disable = 1;
+ return 1;
+}
+__setup("noiotrap", trapped_io_setup);
+
int register_trapped_io(struct trapped_io *tiop)
{
struct resource *res;
@@ -39,6 +49,9 @@ int register_trapped_io(struct trapped_io *tiop)
struct page *pages[TRAPPED_PAGES_MAX];
int k, n;
+ if (unlikely(trapped_io_disable))
+ return 0;
+
/* structure must be page aligned */
if ((unsigned long)tiop & (PAGE_SIZE - 1))
goto bad;
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 64b7690c664c..3f1372eb0091 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -51,7 +51,7 @@ int show_interrupts(struct seq_file *p, void *v)
goto unlock;
seq_printf(p, "%3d: ",i);
for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
seq_printf(p, " %14s", irq_desc[i].chip->name);
seq_printf(p, "-%-8s", irq_desc[i].name);
seq_printf(p, " %s", action->name);
@@ -106,7 +106,7 @@ asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs)
}
#endif
- irq = irq_demux(evt2irq(irq));
+ irq = irq_demux(intc_evt2irq(irq));
#ifdef CONFIG_IRQSTACKS
curctx = (union irq_ctx *)current_thread_info();
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index 94df56b0d1f6..7ea2704ea033 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -14,21 +14,22 @@
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/numa.h>
+#include <linux/ftrace.h>
+#include <linux/suspend.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
#include <asm/cacheflush.h>
-typedef NORET_TYPE void (*relocate_new_kernel_t)(
- unsigned long indirection_page,
- unsigned long reboot_code_buffer,
- unsigned long start_address,
- unsigned long vbr_reg) ATTRIB_NORET;
+typedef void (*relocate_new_kernel_t)(unsigned long indirection_page,
+ unsigned long reboot_code_buffer,
+ unsigned long start_address);
extern const unsigned char relocate_new_kernel[];
extern const unsigned int relocate_new_kernel_size;
extern void *gdb_vbr_vector;
+extern void *vbr_base;
void machine_shutdown(void)
{
@@ -45,6 +46,12 @@ void machine_crash_shutdown(struct pt_regs *regs)
*/
int machine_kexec_prepare(struct kimage *image)
{
+ /* older versions of kexec-tools are passing
+ * the zImage entry point as a virtual address.
+ */
+ if (image->start != PHYSADDR(image->start))
+ return -EINVAL; /* upgrade your kexec-tools */
+
return 0;
}
@@ -73,17 +80,33 @@ static void kexec_info(struct kimage *image)
*/
void machine_kexec(struct kimage *image)
{
-
unsigned long page_list;
unsigned long reboot_code_buffer;
- unsigned long vbr_reg;
relocate_new_kernel_t rnk;
+ unsigned long entry;
+ unsigned long *ptr;
+ int save_ftrace_enabled;
+
+ /*
+ * Nicked from the mips version of machine_kexec():
+ * The generic kexec code builds a page list with physical
+ * addresses. Use phys_to_virt() to convert them to virtual.
+ */
+ for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE);
+ ptr = (entry & IND_INDIRECTION) ?
+ phys_to_virt(entry & PAGE_MASK) : ptr + 1) {
+ if (*ptr & IND_SOURCE || *ptr & IND_INDIRECTION ||
+ *ptr & IND_DESTINATION)
+ *ptr = (unsigned long) phys_to_virt(*ptr);
+ }
-#if defined(CONFIG_SH_STANDARD_BIOS)
- vbr_reg = ((unsigned long )gdb_vbr_vector) - 0x100;
-#else
- vbr_reg = 0x80000000; // dummy
+#ifdef CONFIG_KEXEC_JUMP
+ if (image->preserve_context)
+ save_processor_state();
#endif
+
+ save_ftrace_enabled = __ftrace_enabled_save();
+
/* Interrupts aren't acceptable while we reboot */
local_irq_disable();
@@ -97,12 +120,37 @@ void machine_kexec(struct kimage *image)
memcpy((void *)reboot_code_buffer, relocate_new_kernel,
relocate_new_kernel_size);
- kexec_info(image);
+ kexec_info(image);
flush_cache_all();
+#if defined(CONFIG_SH_STANDARD_BIOS)
+ asm volatile("ldc %0, vbr" :
+ : "r" (((unsigned long) gdb_vbr_vector) - 0x100)
+ : "memory");
+#endif
+
/* now call it */
rnk = (relocate_new_kernel_t) reboot_code_buffer;
- (*rnk)(page_list, reboot_code_buffer, P2SEGADDR(image->start), vbr_reg);
+ (*rnk)(page_list, reboot_code_buffer,
+ (unsigned long)phys_to_virt(image->start));
+
+#ifdef CONFIG_KEXEC_JUMP
+ asm volatile("ldc %0, vbr" : : "r" (&vbr_base) : "memory");
+
+ if (image->preserve_context)
+ restore_processor_state();
+
+ /* Convert page list back to physical addresses, what a mess. */
+ for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE);
+ ptr = (*ptr & IND_INDIRECTION) ?
+ phys_to_virt(*ptr & PAGE_MASK) : ptr + 1) {
+ if (*ptr & IND_SOURCE || *ptr & IND_INDIRECTION ||
+ *ptr & IND_DESTINATION)
+ *ptr = virt_to_phys(*ptr);
+ }
+#endif
+
+ __ftrace_enabled_restore(save_ftrace_enabled);
}
void arch_crash_save_vmcoreinfo(void)
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index ddafbbbab2ab..6d94725d22f2 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -170,20 +170,32 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
asmlinkage void ret_from_fork(void);
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
struct thread_info *ti = task_thread_info(p);
struct pt_regs *childregs;
-#if defined(CONFIG_SH_FPU)
+#if defined(CONFIG_SH_FPU) || defined(CONFIG_SH_DSP)
struct task_struct *tsk = current;
+#endif
+#if defined(CONFIG_SH_FPU)
unlazy_fpu(tsk, regs);
p->thread.fpu = tsk->thread.fpu;
copy_to_stopped_child_used_math(p);
#endif
+#if defined(CONFIG_SH_DSP)
+ if (is_dsp_enabled(tsk)) {
+ /* We can use the __save_dsp or just copy the struct:
+ * __save_dsp(p);
+ * p->thread.dsp_status.status |= SR_DSP
+ */
+ p->thread.dsp_status = tsk->thread.dsp_status;
+ }
+#endif
+
childregs = task_pt_regs(p);
*childregs = *regs;
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index c90c7e5e5fee..96be839040f8 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -425,7 +425,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
asmlinkage void ret_from_fork(void);
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 29ca09d24ef8..f7b22dd83b0c 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -200,7 +200,8 @@ static int dspregs_get(struct task_struct *target,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
{
- const struct pt_dspregs *regs = task_pt_dspregs(target);
+ const struct pt_dspregs *regs =
+ (struct pt_dspregs *)&target->thread.dsp_status.dsp_regs;
int ret;
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs,
@@ -217,7 +218,8 @@ static int dspregs_set(struct task_struct *target,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
- struct pt_dspregs *regs = task_pt_dspregs(target);
+ struct pt_dspregs *regs =
+ (struct pt_dspregs *)&target->thread.dsp_status.dsp_regs;
int ret;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs,
diff --git a/arch/sh/kernel/relocate_kernel.S b/arch/sh/kernel/relocate_kernel.S
index c66cb3209db5..fcc9934fb97b 100644
--- a/arch/sh/kernel/relocate_kernel.S
+++ b/arch/sh/kernel/relocate_kernel.S
@@ -4,6 +4,8 @@
*
* LANDISK/sh4 is supported. Maybe, SH archtecture works well.
*
+ * 2009-03-18 Magnus Damm - Added Kexec Jump support
+ *
* This source code is licensed under the GNU General Public License,
* Version 2. See the file COPYING for more details.
*/
@@ -16,23 +18,141 @@ relocate_new_kernel:
/* r4 = indirection_page */
/* r5 = reboot_code_buffer */
/* r6 = start_address */
- /* r7 = vbr_reg */
- mov.l 10f,r8 /* PAGE_SIZE */
- mov.l 11f,r9 /* P2SEG */
+ mov.l 10f, r0 /* PAGE_SIZE */
+ add r5, r0 /* setup new stack at end of control page */
+
+ /* save r15->r8 to new stack */
+ mov.l r15, @-r0
+ mov r0, r15
+ mov.l r14, @-r15
+ mov.l r13, @-r15
+ mov.l r12, @-r15
+ mov.l r11, @-r15
+ mov.l r10, @-r15
+ mov.l r9, @-r15
+ mov.l r8, @-r15
+
+ /* save other random registers */
+ sts.l macl, @-r15
+ sts.l mach, @-r15
+ stc.l gbr, @-r15
+ stc.l ssr, @-r15
+ stc.l sr, @-r15
+ sts.l pr, @-r15
+ stc.l spc, @-r15
+
+ /* switch to bank1 and save r7->r0 */
+ mov.l 12f, r9
+ stc sr, r8
+ or r9, r8
+ ldc r8, sr
+ mov.l r7, @-r15
+ mov.l r6, @-r15
+ mov.l r5, @-r15
+ mov.l r4, @-r15
+ mov.l r3, @-r15
+ mov.l r2, @-r15
+ mov.l r1, @-r15
+ mov.l r0, @-r15
+
+ /* switch to bank0 and save r7->r0 */
+ mov.l 12f, r9
+ not r9, r9
+ stc sr, r8
+ and r9, r8
+ ldc r8, sr
+ mov.l r7, @-r15
+ mov.l r6, @-r15
+ mov.l r5, @-r15
+ mov.l r4, @-r15
+ mov.l r3, @-r15
+ mov.l r2, @-r15
+ mov.l r1, @-r15
+ mov.l r0, @-r15
+
+ mov.l r4, @-r15 /* save indirection page again */
+
+ bsr swap_pages /* swap pages before jumping to new kernel */
+ nop
+
+ mova 11f, r0
+ mov.l r15, @r0 /* save pointer to stack */
+
+ jsr @r6 /* hand over control to new kernel */
+ nop
+
+ mov.l 11f, r15 /* get pointer to stack */
+ mov.l @r15+, r4 /* restore r4 to get indirection page */
- /* stack setting */
- add r8,r5
- mov r5,r15
+ bsr swap_pages /* swap pages back to previous state */
+ nop
+ /* make sure bank0 is active and restore r0->r7 */
+ mov.l 12f, r9
+ not r9, r9
+ stc sr, r8
+ and r9, r8
+ ldc r8, sr
+ mov.l @r15+, r0
+ mov.l @r15+, r1
+ mov.l @r15+, r2
+ mov.l @r15+, r3
+ mov.l @r15+, r4
+ mov.l @r15+, r5
+ mov.l @r15+, r6
+ mov.l @r15+, r7
+
+ /* switch to bank1 and restore r0->r7 */
+ mov.l 12f, r9
+ stc sr, r8
+ or r9, r8
+ ldc r8, sr
+ mov.l @r15+, r0
+ mov.l @r15+, r1
+ mov.l @r15+, r2
+ mov.l @r15+, r3
+ mov.l @r15+, r4
+ mov.l @r15+, r5
+ mov.l @r15+, r6
+ mov.l @r15+, r7
+
+ /* switch back to bank0 */
+ mov.l 12f, r9
+ not r9, r9
+ stc sr, r8
+ and r9, r8
+ ldc r8, sr
+
+ /* restore other random registers */
+ ldc.l @r15+, spc
+ lds.l @r15+, pr
+ ldc.l @r15+, sr
+ ldc.l @r15+, ssr
+ ldc.l @r15+, gbr
+ lds.l @r15+, mach
+ lds.l @r15+, macl
+
+ /* restore r8->r15 */
+ mov.l @r15+, r8
+ mov.l @r15+, r9
+ mov.l @r15+, r10
+ mov.l @r15+, r11
+ mov.l @r15+, r12
+ mov.l @r15+, r13
+ mov.l @r15+, r14
+ mov.l @r15+, r15
+ rts
+ nop
+
+swap_pages:
bra 1f
- mov r4,r0 /* cmd = indirection_page */
+ mov r4,r0 /* cmd = indirection_page */
0:
mov.l @r4+,r0 /* cmd = *ind++ */
-1: /* addr = (cmd | P2SEG) & 0xfffffff0 */
+1: /* addr = cmd & 0xfffffff0 */
mov r0,r2
- or r9,r2
mov #-16,r1
and r1,r2
@@ -40,57 +160,70 @@ relocate_new_kernel:
tst #1,r0
bt 2f
bra 0b
- mov r2,r5
+ mov r2,r5
2: /* else if(cmd & IND_INDIRECTION) ind = addr */
tst #2,r0
bt 3f
bra 0b
- mov r2,r4
+ mov r2,r4
-3: /* else if(cmd & IND_DONE) goto 6 */
+3: /* else if(cmd & IND_DONE) return */
tst #4,r0
bt 4f
- bra 6f
- nop
+ rts
+ nop
4: /* else if(cmd & IND_SOURCE) memcpy(dst,addr,PAGE_SIZE) */
tst #8,r0
bt 0b
- mov r8,r3
+ mov.l 10f,r3 /* PAGE_SIZE */
shlr2 r3
shlr2 r3
5:
dt r3
- mov.l @r2+,r1 /* 16n+0 */
- mov.l r1,@r5
- add #4,r5
- mov.l @r2+,r1 /* 16n+4 */
- mov.l r1,@r5
- add #4,r5
- mov.l @r2+,r1 /* 16n+8 */
- mov.l r1,@r5
- add #4,r5
- mov.l @r2+,r1 /* 16n+12 */
- mov.l r1,@r5
- add #4,r5
+
+ /* regular kexec just overwrites the destination page
+ * with the contents of the source page.
+ * for the kexec jump case we need to swap the contents
+ * of the pages.
+ * to keep it simple swap the contents for both cases.
+ */
+ mov.l @(0, r2), r8
+ mov.l @(0, r5), r1
+ mov.l r8, @(0, r5)
+ mov.l r1, @(0, r2)
+
+ mov.l @(4, r2), r8
+ mov.l @(4, r5), r1
+ mov.l r8, @(4, r5)
+ mov.l r1, @(4, r2)
+
+ mov.l @(8, r2), r8
+ mov.l @(8, r5), r1
+ mov.l r8, @(8, r5)
+ mov.l r1, @(8, r2)
+
+ mov.l @(12, r2), r8
+ mov.l @(12, r5), r1
+ mov.l r8, @(12, r5)
+ mov.l r1, @(12, r2)
+
+ add #16,r5
+ add #16,r2
bf 5b
bra 0b
- nop
-6:
-#ifdef CONFIG_SH_STANDARD_BIOS
- ldc r7, vbr
-#endif
- jmp @r6
- nop
+ nop
.align 2
10:
.long PAGE_SIZE
11:
- .long P2SEG
+ .long 0
+12:
+ .long 0x20000000 ! RB=1
relocate_new_kernel_end:
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 370d2cfa34eb..04a6004fccc4 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -103,12 +103,11 @@ static int __init early_parse_mem(char *p)
size = memparse(p, &p);
if (size > __MEMORY_SIZE) {
- static char msg[] __initdata = KERN_ERR
+ printk(KERN_ERR
"Using mem= to increase the size of kernel memory "
"is not allowed.\n"
" Recompile the kernel with the correct value for "
- "CONFIG_MEMORY_SIZE.\n";
- printk(msg);
+ "CONFIG_MEMORY_SIZE.\n");
return 0;
}
@@ -432,6 +431,7 @@ static const char *cpu_name[] = {
[CPU_SH7763] = "SH7763", [CPU_SH7770] = "SH7770",
[CPU_SH7780] = "SH7780", [CPU_SH7781] = "SH7781",
[CPU_SH7343] = "SH7343", [CPU_SH7785] = "SH7785",
+ [CPU_SH7786] = "SH7786",
[CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3",
[CPU_SH5_101] = "SH5-101", [CPU_SH5_103] = "SH5-103",
[CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723",
@@ -448,7 +448,7 @@ EXPORT_SYMBOL(get_cpu_subtype);
/* Symbolic CPU flags, keep in sync with asm/cpu-features.h */
static const char *cpu_flags[] = {
"none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr",
- "ptea", "llsc", "l2", "op32", NULL
+ "ptea", "llsc", "l2", "op32", "pteaex", NULL
};
static void show_cpuflags(struct seq_file *m, struct sh_cpuinfo *c)
diff --git a/arch/sh/kernel/swsusp.c b/arch/sh/kernel/swsusp.c
new file mode 100644
index 000000000000..12b64a0f2f01
--- /dev/null
+++ b/arch/sh/kernel/swsusp.c
@@ -0,0 +1,38 @@
+/*
+ * swsusp.c - SuperH hibernation support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/suspend.h>
+#include <asm/suspend.h>
+#include <asm/sections.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+#include <asm/fpu.h>
+
+struct swsusp_arch_regs swsusp_arch_regs_cpu0;
+
+int pfn_is_nosave(unsigned long pfn)
+{
+ unsigned long begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT;
+ unsigned long end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT;
+
+ return (pfn >= begin_pfn) && (pfn < end_pfn);
+}
+
+void save_processor_state(void)
+{
+ init_fpu(current);
+}
+
+void restore_processor_state(void)
+{
+ local_flush_tlb_all();
+}
diff --git a/arch/sh/kernel/time_32.c b/arch/sh/kernel/time_32.c
index 8457f83242c5..c34e1e0f9b02 100644
--- a/arch/sh/kernel/time_32.c
+++ b/arch/sh/kernel/time_32.c
@@ -41,14 +41,6 @@ static int null_rtc_set_time(const time_t secs)
return 0;
}
-/*
- * Null high precision timer functions for systems lacking one.
- */
-static cycle_t null_hpt_read(void)
-{
- return 0;
-}
-
void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
@@ -112,7 +104,6 @@ int do_settimeofday(struct timespec *tv)
EXPORT_SYMBOL(do_settimeofday);
#endif /* !CONFIG_GENERIC_TIME */
-#ifndef CONFIG_GENERIC_CLOCKEVENTS
/* last time the RTC clock got updated */
static long last_rtc_update;
@@ -156,7 +147,6 @@ void handle_timer_tick(void)
update_process_times(user_mode(get_irq_regs()));
#endif
}
-#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
#ifdef CONFIG_PM
int timer_suspend(struct sys_device *dev, pm_message_t state)
@@ -189,7 +179,12 @@ static struct sysdev_class timer_sysclass = {
static int __init timer_init_sysfs(void)
{
- int ret = sysdev_class_register(&timer_sysclass);
+ int ret;
+
+ if (!sys_timer)
+ return 0;
+
+ ret = sysdev_class_register(&timer_sysclass);
if (ret != 0)
return ret;
@@ -200,42 +195,21 @@ device_initcall(timer_init_sysfs);
void (*board_time_init)(void);
-/*
- * Shamelessly based on the MIPS and Sparc64 work.
- */
-static unsigned long timer_ticks_per_nsec_quotient __read_mostly;
-unsigned long sh_hpt_frequency = 0;
-
-#define NSEC_PER_CYC_SHIFT 10
-
-static struct clocksource clocksource_sh = {
+struct clocksource clocksource_sh = {
.name = "SuperH",
- .rating = 200,
- .mask = CLOCKSOURCE_MASK(32),
- .read = null_hpt_read,
- .shift = 16,
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static void __init init_sh_clocksource(void)
-{
- if (!sh_hpt_frequency || clocksource_sh.read == null_hpt_read)
- return;
-
- clocksource_sh.mult = clocksource_hz2mult(sh_hpt_frequency,
- clocksource_sh.shift);
-
- timer_ticks_per_nsec_quotient =
- clocksource_hz2mult(sh_hpt_frequency, NSEC_PER_CYC_SHIFT);
-
- clocksource_register(&clocksource_sh);
-}
-
#ifdef CONFIG_GENERIC_TIME
unsigned long long sched_clock(void)
{
- unsigned long long ticks = clocksource_sh.read();
- return (ticks * timer_ticks_per_nsec_quotient) >> NSEC_PER_CYC_SHIFT;
+ unsigned long long cycles;
+
+ /* jiffies based sched_clock if no clocksource is installed */
+ if (!clocksource_sh.rating)
+ return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ);
+
+ cycles = clocksource_sh.read();
+ return cyc2ns(&clocksource_sh, cycles);
}
#endif
@@ -259,17 +233,8 @@ void __init time_init(void)
* initialized for us.
*/
sys_timer = get_sys_timer();
- printk(KERN_INFO "Using %s for system timer\n", sys_timer->name);
-
-
- if (sys_timer->ops->read)
- clocksource_sh.read = sys_timer->ops->read;
-
- init_sh_clocksource();
-
- if (sh_hpt_frequency)
- printk("Using %lu.%03lu MHz high precision timer.\n",
- ((sh_hpt_frequency + 500) / 1000) / 1000,
- ((sh_hpt_frequency + 500) / 1000) % 1000);
+ if (unlikely(!sys_timer))
+ panic("System timer missing.\n");
+ printk(KERN_INFO "Using %s for system timer\n", sys_timer->name);
}
diff --git a/arch/sh/kernel/time_64.c b/arch/sh/kernel/time_64.c
index 59d2a03e8b3c..988c77c37231 100644
--- a/arch/sh/kernel/time_64.c
+++ b/arch/sh/kernel/time_64.c
@@ -284,7 +284,6 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
static struct irqaction irq0 = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED,
- .mask = CPU_MASK_NONE,
.name = "timer",
};
diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c
index c127293271e1..9aa348658ae3 100644
--- a/arch/sh/kernel/timers/timer-cmt.c
+++ b/arch/sh/kernel/timers/timer-cmt.c
@@ -109,7 +109,6 @@ static struct irqaction cmt_irq = {
.name = "timer",
.handler = cmt_timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
- .mask = CPU_MASK_NONE,
};
static void cmt_clk_init(struct clk *clk)
diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c
index c3d237e1d566..9b0ef0126479 100644
--- a/arch/sh/kernel/timers/timer-mtu2.c
+++ b/arch/sh/kernel/timers/timer-mtu2.c
@@ -35,7 +35,8 @@
#define MTU2_TSR_1 0xfffe4385
#define MTU2_TCNT_1 0xfffe4386 /* 16-bit counter */
-#if defined(CONFIG_CPU_SUBTYPE_SH7201)
+#if defined(CONFIG_CPU_SUBTYPE_SH7201) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7203)
#define MTU2_TGRA_1 0xfffe4388
#else
#define MTU2_TGRA_1 0xfffe438a
@@ -114,7 +115,6 @@ static struct irqaction mtu2_irq = {
.name = "timer",
.handler = mtu2_timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
- .mask = CPU_MASK_NONE,
};
static unsigned int divisors[] = { 1, 4, 16, 64, 1, 1, 256 };
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c
index 0db3f9510336..c5d3396f5960 100644
--- a/arch/sh/kernel/timers/timer-tmu.c
+++ b/arch/sh/kernel/timers/timer-tmu.c
@@ -146,7 +146,14 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dummy)
_tmu_clear_status(TMU0);
_tmu_set_irq(TMU0,tmu0_clockevent.mode != CLOCK_EVT_MODE_ONESHOT);
- evt->event_handler(evt);
+ switch (tmu0_clockevent.mode) {
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_PERIODIC:
+ evt->event_handler(evt);
+ break;
+ default:
+ break;
+ }
return IRQ_HANDLED;
}
@@ -155,7 +162,6 @@ static struct irqaction tmu0_irq = {
.name = "periodic/oneshot timer",
.handler = tmu_timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
- .mask = CPU_MASK_NONE,
};
static void __init tmu_clk_init(struct clk *clk)
@@ -237,6 +243,7 @@ static int tmu_timer_init(void)
!defined(CONFIG_CPU_SUBTYPE_SH7721) && \
!defined(CONFIG_CPU_SUBTYPE_SH7760) && \
!defined(CONFIG_CPU_SUBTYPE_SH7785) && \
+ !defined(CONFIG_CPU_SUBTYPE_SH7786) && \
!defined(CONFIG_CPU_SUBTYPE_SHX3)
ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
#endif
@@ -254,7 +261,14 @@ static int tmu_timer_init(void)
_tmu_start(TMU1);
- sh_hpt_frequency = clk_get_rate(&tmu1_clk);
+ clocksource_sh.rating = 200;
+ clocksource_sh.mask = CLOCKSOURCE_MASK(32);
+ clocksource_sh.read = tmu_timer_read;
+ clocksource_sh.shift = 10;
+ clocksource_sh.mult = clocksource_hz2mult(clk_get_rate(&tmu1_clk),
+ clocksource_sh.shift);
+ clocksource_sh.flags = CLOCK_SOURCE_IS_CONTINUOUS;
+ clocksource_register(&clocksource_sh);
tmu0_clockevent.mult = div_sc(frequency, NSEC_PER_SEC,
tmu0_clockevent.shift);
@@ -264,6 +278,7 @@ static int tmu_timer_init(void)
clockevent_delta2ns(1, &tmu0_clockevent);
tmu0_clockevent.cpumask = cpumask_of(0);
+ tmu0_clockevent.rating = 100;
clockevents_register_device(&tmu0_clockevent);
@@ -274,7 +289,6 @@ static struct sys_timer_ops tmu_timer_ops = {
.init = tmu_timer_init,
.start = tmu_timer_start,
.stop = tmu_timer_stop,
- .read = tmu_timer_read,
};
struct sys_timer tmu_timer = {
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 60dcf87ed019..30ca9c51e52d 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -664,6 +664,8 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
if (is_dsp_inst(regs)) {
/* Enable DSP mode, and restart instruction. */
regs->sr |= SR_DSP;
+ /* Save DSP mode */
+ tsk->thread.dsp_status.status |= SR_DSP;
return;
}
#endif
diff --git a/arch/sh/kernel/vmlinux_32.lds.S b/arch/sh/kernel/vmlinux_32.lds.S
index 7b4b82bd1156..d0b2a715cd14 100644
--- a/arch/sh/kernel/vmlinux_32.lds.S
+++ b/arch/sh/kernel/vmlinux_32.lds.S
@@ -15,7 +15,10 @@ OUTPUT_ARCH(sh)
ENTRY(_start)
SECTIONS
{
-#ifdef CONFIG_32BIT
+#ifdef CONFIG_PMB_FIXED
+ . = CONFIG_PAGE_OFFSET + (CONFIG_MEMORY_START & 0x1fffffff) +
+ CONFIG_ZERO_PAGE_OFFSET;
+#elif defined(CONFIG_32BIT)
. = CONFIG_PAGE_OFFSET + CONFIG_ZERO_PAGE_OFFSET;
#else
. = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET;
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 555ec9714b9e..d4079cab2d58 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -57,7 +57,7 @@ config 32BIT
bool
default y if CPU_SH5
-config PMB
+config PMB_ENABLE
bool "Support 32-bit physical addressing through PMB"
depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
select 32BIT
@@ -67,6 +67,33 @@ config PMB
32-bits through the SH-4A PMB. If this is not set, legacy
29-bit physical addressing will be used.
+choice
+ prompt "PMB handling type"
+ depends on PMB_ENABLE
+ default PMB_FIXED
+
+config PMB
+ bool "PMB"
+ depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
+ select 32BIT
+ help
+ If you say Y here, physical addressing will be extended to
+ 32-bits through the SH-4A PMB. If this is not set, legacy
+ 29-bit physical addressing will be used.
+
+config PMB_FIXED
+ bool "fixed PMB"
+ depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || \
+ CPU_SUBTYPE_SH7785)
+ select 32BIT
+ help
+ If this option is enabled, fixed PMB mappings are inherited
+ from the boot loader, and the kernel does not attempt dynamic
+ management. This is the closest to legacy 29-bit physical mode,
+ and allows systems to support up to 512MiB of system memory.
+
+endchoice
+
config X2TLB
bool "Enable extended TLB mode"
depends on (CPU_SHX2 || CPU_SHX3) && MMU && EXPERIMENTAL
@@ -224,18 +251,6 @@ config SH7705_CACHE_32KB
depends on CPU_SUBTYPE_SH7705
default y
-config SH_DIRECT_MAPPED
- bool "Use direct-mapped caching"
- default n
- help
- Selecting this option will configure the caches to be direct-mapped,
- even if the cache supports a 2 or 4-way mode. This is useful primarily
- for debugging on platforms with 2 and 4-way caches (SH7750R/SH7751R,
- SH4-202, SH4-501, etc.)
-
- Turn this option off for platforms that do not have a direct-mapped
- cache, and you have no need to run the caches in such a configuration.
-
choice
prompt "Cache mode"
default CACHE_WRITEBACK if CPU_SH2A || CPU_SH3 || CPU_SH4 || CPU_SH5
diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32
index cb2f3f299591..986a1e055834 100644
--- a/arch/sh/mm/Makefile_32
+++ b/arch/sh/mm/Makefile_32
@@ -25,8 +25,10 @@ obj-$(CONFIG_CPU_SH4) += cache-debugfs.o
endif
ifdef CONFIG_MMU
-obj-$(CONFIG_CPU_SH3) += tlb-sh3.o
-obj-$(CONFIG_CPU_SH4) += tlb-sh4.o
+tlb-$(CONFIG_CPU_SH3) := tlb-sh3.o
+tlb-$(CONFIG_CPU_SH4) := tlb-sh4.o
+tlb-$(CONFIG_CPU_HAS_PTEAEX) := tlb-pteaex.o
+obj-y += $(tlb-y)
ifndef CONFIG_CACHE_OFF
obj-$(CONFIG_CPU_SH4) += pg-sh4.o
obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o
@@ -35,6 +37,7 @@ endif
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_PMB) += pmb.o
+obj-$(CONFIG_PMB_FIXED) += pmb-fixed.o
obj-$(CONFIG_NUMA) += numa.o
EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/mm/asids-debugfs.c b/arch/sh/mm/asids-debugfs.c
index 8e912a15e94f..cd8c3bf39b5a 100644
--- a/arch/sh/mm/asids-debugfs.c
+++ b/arch/sh/mm/asids-debugfs.c
@@ -37,10 +37,8 @@ static int asids_seq_show(struct seq_file *file, void *iter)
continue;
if (p->mm)
- seq_printf(file, "%5d : %02lx\n", pid,
+ seq_printf(file, "%5d : %04lx\n", pid,
cpu_asid(smp_processor_id(), p->mm));
- else
- seq_printf(file, "%5d : (none)\n", pid);
}
read_unlock(&tasklist_lock);
diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c
index 32946fba123e..60cc486d2c2c 100644
--- a/arch/sh/mm/ioremap_32.c
+++ b/arch/sh/mm/ioremap_32.c
@@ -59,11 +59,13 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
if (is_pci_memaddr(phys_addr) && is_pci_memaddr(last_addr))
return (void __iomem *)phys_addr;
+#if !defined(CONFIG_PMB_FIXED)
/*
* Don't allow anybody to remap normal RAM that we're using..
*/
if (phys_addr < virt_to_phys(high_memory))
return NULL;
+#endif
/*
* Mappings have to be page-aligned
@@ -81,7 +83,7 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
area->phys_addr = phys_addr;
orig_addr = addr = (unsigned long)area->addr;
-#ifdef CONFIG_32BIT
+#ifdef CONFIG_PMB
/*
* First try to remap through the PMB once a valid VMA has been
* established. Smaller allocations (or the rest of the size
@@ -119,10 +121,10 @@ void __iounmap(void __iomem *addr)
unsigned long seg = PXSEG(vaddr);
struct vm_struct *p;
- if (seg < P3SEG || seg >= P3_ADDR_MAX || is_pci_memaddr(vaddr))
+ if (seg < P3SEG || vaddr >= P3_ADDR_MAX || is_pci_memaddr(vaddr))
return;
-#ifdef CONFIG_32BIT
+#ifdef CONFIG_PMB
/*
* Purge any PMB entries that may have been established for this
* mapping, then proceed with conventional VMA teardown.
diff --git a/arch/sh/mm/pmb-fixed.c b/arch/sh/mm/pmb-fixed.c
new file mode 100644
index 000000000000..43c8eac4d8a1
--- /dev/null
+++ b/arch/sh/mm/pmb-fixed.c
@@ -0,0 +1,45 @@
+/*
+ * arch/sh/mm/fixed_pmb.c
+ *
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <asm/mmu.h>
+#include <asm/mmu_context.h>
+
+static int __uses_jump_to_uncached fixed_pmb_init(void)
+{
+ int i;
+ unsigned long addr, data;
+
+ jump_to_uncached();
+
+ for (i = 0; i < PMB_ENTRY_MAX; i++) {
+ addr = PMB_DATA + (i << PMB_E_SHIFT);
+ data = ctrl_inl(addr);
+ if (!(data & PMB_V))
+ continue;
+
+ if (data & PMB_C) {
+#if defined(CONFIG_CACHE_WRITETHROUGH)
+ data |= PMB_WT;
+#elif defined(CONFIG_CACHE_WRITEBACK)
+ data &= ~PMB_WT;
+#else
+ data &= ~(PMB_C | PMB_WT);
+#endif
+ }
+ ctrl_outl(data, addr);
+ }
+
+ back_to_cached();
+
+ return 0;
+}
+arch_initcall(fixed_pmb_init);
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index 84241676265e..b1a714a92b14 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -15,6 +15,8 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/bitops.h>
@@ -402,3 +404,39 @@ static int __init pmb_debugfs_init(void)
return 0;
}
postcore_initcall(pmb_debugfs_init);
+
+#ifdef CONFIG_PM
+static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state)
+{
+ static pm_message_t prev_state;
+
+ /* Restore the PMB after a resume from hibernation */
+ if (state.event == PM_EVENT_ON &&
+ prev_state.event == PM_EVENT_FREEZE) {
+ struct pmb_entry *pmbe;
+ spin_lock_irq(&pmb_list_lock);
+ for (pmbe = pmb_list; pmbe; pmbe = pmbe->next)
+ set_pmb_entry(pmbe);
+ spin_unlock_irq(&pmb_list_lock);
+ }
+ prev_state = state;
+ return 0;
+}
+
+static int pmb_sysdev_resume(struct sys_device *dev)
+{
+ return pmb_sysdev_suspend(dev, PMSG_ON);
+}
+
+static struct sysdev_driver pmb_sysdev_driver = {
+ .suspend = pmb_sysdev_suspend,
+ .resume = pmb_sysdev_resume,
+};
+
+static int __init pmb_sysdev_init(void)
+{
+ return sysdev_driver_register(&cpu_sysdev_class, &pmb_sysdev_driver);
+}
+
+subsys_initcall(pmb_sysdev_init);
+#endif
diff --git a/arch/sh/mm/tlb-pteaex.c b/arch/sh/mm/tlb-pteaex.c
new file mode 100644
index 000000000000..2aab3ea934d7
--- /dev/null
+++ b/arch/sh/mm/tlb-pteaex.c
@@ -0,0 +1,96 @@
+/*
+ * arch/sh/mm/tlb-pteaex.c
+ *
+ * TLB operations for SH-X3 CPUs featuring PTE ASID Extensions.
+ *
+ * Copyright (C) 2009 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+
+void update_mmu_cache(struct vm_area_struct * vma,
+ unsigned long address, pte_t pte)
+{
+ unsigned long flags;
+ unsigned long pteval;
+ unsigned long vpn;
+
+ /* Ptrace may call this routine. */
+ if (vma && current->active_mm != vma->vm_mm)
+ return;
+
+#ifndef CONFIG_CACHE_OFF
+ {
+ unsigned long pfn = pte_pfn(pte);
+
+ if (pfn_valid(pfn)) {
+ struct page *page = pfn_to_page(pfn);
+
+ if (!test_bit(PG_mapped, &page->flags)) {
+ unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
+ __flush_wback_region((void *)P1SEGADDR(phys),
+ PAGE_SIZE);
+ __set_bit(PG_mapped, &page->flags);
+ }
+ }
+ }
+#endif
+
+ local_irq_save(flags);
+
+ /* Set PTEH register */
+ vpn = address & MMU_VPN_MASK;
+ __raw_writel(vpn, MMU_PTEH);
+
+ /* Set PTEAEX */
+ __raw_writel(get_asid(), MMU_PTEAEX);
+
+ pteval = pte.pte_low;
+
+ /* Set PTEA register */
+#ifdef CONFIG_X2TLB
+ /*
+ * For the extended mode TLB this is trivial, only the ESZ and
+ * EPR bits need to be written out to PTEA, with the remainder of
+ * the protection bits (with the exception of the compat-mode SZ
+ * and PR bits, which are cleared) being written out in PTEL.
+ */
+ __raw_writel(pte.pte_high, MMU_PTEA);
+#endif
+
+ /* Set PTEL register */
+ pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
+#ifdef CONFIG_CACHE_WRITETHROUGH
+ pteval |= _PAGE_WT;
+#endif
+ /* conveniently, we want all the software flags to be 0 anyway */
+ __raw_writel(pteval, MMU_PTEL);
+
+ /* Load the TLB */
+ asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
+ local_irq_restore(flags);
+}
+
+/*
+ * While SH-X2 extended TLB mode splits out the memory-mapped I/UTLB
+ * data arrays, SH-X3 cores with PTEAEX split out the memory-mapped
+ * address arrays. In compat mode the second array is inaccessible, while
+ * in extended mode, the legacy 8-bit ASID field in address array 1 has
+ * undefined behaviour.
+ */
+void __uses_jump_to_uncached local_flush_tlb_one(unsigned long asid,
+ unsigned long page)
+{
+ jump_to_uncached();
+ __raw_writel(page, MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT);
+ __raw_writel(asid, MMU_UTLB_ADDRESS_ARRAY2 | MMU_PAGE_ASSOC_BIT);
+ back_to_cached();
+}
diff --git a/arch/sh/oprofile/common.c b/arch/sh/oprofile/common.c
index 1d97d64cb95f..1b9d4304b3bf 100644
--- a/arch/sh/oprofile/common.c
+++ b/arch/sh/oprofile/common.c
@@ -107,6 +107,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
case CPU_SH7780:
case CPU_SH7781:
case CPU_SH7785:
+ case CPU_SH7786:
case CPU_SH7723:
case CPU_SHX3:
lmodel = &op_model_sh4a_ops;
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index 284b7e867496..8477b5d884fd 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -52,3 +52,6 @@ RSK7203 SH_RSK7203
AP325RXA SH_AP325RXA
SH7763RDP SH_SH7763RDP
SH7785LCR SH_SH7785LCR
+URQUELL SH_URQUELL
+ESPT SH_ESPT
+POLARIS SH_POLARIS
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index c3ea215334f6..cc12cd48bbc5 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -124,6 +124,9 @@ config ARCH_NO_VIRT_TO_BUS
config OF
def_bool y
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ def_bool y if SPARC64
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
diff --git a/arch/sparc/Kconfig.debug b/arch/sparc/Kconfig.debug
index b8a15e271bfa..90d5fe223a74 100644
--- a/arch/sparc/Kconfig.debug
+++ b/arch/sparc/Kconfig.debug
@@ -22,14 +22,6 @@ config DEBUG_DCFLUSH
config STACK_DEBUG
bool "Stack Overflow Detection Support"
-config DEBUG_PAGEALLOC
- bool "Debug page memory allocations"
- depends on SPARC64 && DEBUG_KERNEL && !HIBERNATION
- help
- Unmap pages from the kernel linear mapping after free_pages().
- This results in a large slowdown, but helps to find certain types
- of memory corruptions.
-
config MCOUNT
bool
depends on SPARC64
diff --git a/arch/sparc/include/asm/mmu_context_64.h b/arch/sparc/include/asm/mmu_context_64.h
index 5693ab482606..666a73fef28d 100644
--- a/arch/sparc/include/asm/mmu_context_64.h
+++ b/arch/sparc/include/asm/mmu_context_64.h
@@ -121,8 +121,8 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str
* local TLB.
*/
cpu = smp_processor_id();
- if (!ctx_valid || !cpu_isset(cpu, mm->cpu_vm_mask)) {
- cpu_set(cpu, mm->cpu_vm_mask);
+ if (!ctx_valid || !cpumask_test_cpu(cpu, mm_cpumask(mm))) {
+ cpumask_set_cpu(cpu, mm_cpumask(mm));
__flush_tlb_mm(CTX_HWBITS(mm->context),
SECONDARY_CONTEXT);
}
@@ -141,8 +141,8 @@ static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm
if (!CTX_VALID(mm->context))
get_new_mmu_context(mm);
cpu = smp_processor_id();
- if (!cpu_isset(cpu, mm->cpu_vm_mask))
- cpu_set(cpu, mm->cpu_vm_mask);
+ if (!cpumask_test_cpu(cpu, mm_cpumask(mm)))
+ cpumask_set_cpu(cpu, mm_cpumask(mm));
load_secondary_context(mm);
__flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT);
diff --git a/arch/sparc/include/asm/mmzone.h b/arch/sparc/include/asm/mmzone.h
index ebf5986c12ed..e8c648741ed4 100644
--- a/arch/sparc/include/asm/mmzone.h
+++ b/arch/sparc/include/asm/mmzone.h
@@ -3,6 +3,8 @@
#ifdef CONFIG_NEED_MULTIPLE_NODES
+#include <linux/cpumask.h>
+
extern struct pglist_data *node_data[];
#define NODE_DATA(nid) (node_data[nid])
diff --git a/arch/sparc/include/asm/pil.h b/arch/sparc/include/asm/pil.h
index 32a7efe76d00..266937030546 100644
--- a/arch/sparc/include/asm/pil.h
+++ b/arch/sparc/include/asm/pil.h
@@ -24,6 +24,7 @@
#define PIL_DEVICE_IRQ 5
#define PIL_SMP_CALL_FUNC_SNGL 6
#define PIL_DEFERRED_PCR_WORK 7
+#define PIL_KGDB_CAPTURE 8
#define PIL_NORMAL_MAX 14
#define PIL_NMI 15
diff --git a/arch/sparc/include/asm/smp_64.h b/arch/sparc/include/asm/smp_64.h
index 57224dd37b3a..becb6bf353a9 100644
--- a/arch/sparc/include/asm/smp_64.h
+++ b/arch/sparc/include/asm/smp_64.h
@@ -35,7 +35,8 @@ extern cpumask_t cpu_core_map[NR_CPUS];
extern int sparc64_multi_core;
extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi(cpumask_t mask);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
/*
* General functions that each host system must provide.
diff --git a/arch/sparc/include/asm/socket.h b/arch/sparc/include/asm/socket.h
index bf50d0c2d583..982a12f959f4 100644
--- a/arch/sparc/include/asm/socket.h
+++ b/arch/sparc/include/asm/socket.h
@@ -50,6 +50,9 @@
#define SO_MARK 0x0022
+#define SO_TIMESTAMPING 0x0023
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h
index bf2d532593e3..46f91ab66a50 100644
--- a/arch/sparc/include/asm/spinlock_32.h
+++ b/arch/sparc/include/asm/spinlock_32.h
@@ -177,6 +177,8 @@ static inline int __read_trylock(raw_rwlock_t *rw)
#define __raw_write_unlock(rw) do { (rw)->lock = 0; } while(0)
#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define __raw_read_lock_flags(rw, flags) __raw_read_lock(rw)
+#define __raw_write_lock_flags(rw, flags) __raw_write_lock(rw)
#define _raw_spin_relax(lock) cpu_relax()
#define _raw_read_relax(lock) cpu_relax()
diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h
index c4d274d330e9..f6b2b92ad8d2 100644
--- a/arch/sparc/include/asm/spinlock_64.h
+++ b/arch/sparc/include/asm/spinlock_64.h
@@ -211,9 +211,11 @@ static int inline __write_trylock(raw_rwlock_t *lock)
}
#define __raw_read_lock(p) __read_lock(p)
+#define __raw_read_lock_flags(p, f) __read_lock(p)
#define __raw_read_trylock(p) __read_trylock(p)
#define __raw_read_unlock(p) __read_unlock(p)
#define __raw_write_lock(p) __write_lock(p)
+#define __raw_write_lock_flags(p, f) __write_lock(p)
#define __raw_write_unlock(p) __write_unlock(p)
#define __raw_write_trylock(p) __write_trylock(p)
diff --git a/arch/sparc/include/asm/system_32.h b/arch/sparc/include/asm/system_32.h
index 79c1ae2b42a3..751c8c17f5a0 100644
--- a/arch/sparc/include/asm/system_32.h
+++ b/arch/sparc/include/asm/system_32.h
@@ -126,7 +126,7 @@ extern void flushw_all(void);
#define switch_to(prev, next, last) do { \
SWITCH_ENTER(prev); \
SWITCH_DO_LAZY_FPU(next); \
- cpu_set(smp_processor_id(), next->active_mm->cpu_vm_mask); \
+ cpumask_set_cpu(smp_processor_id(), mm_cpumask(next->active_mm)); \
__asm__ __volatile__( \
"sethi %%hi(here - 0x8), %%o7\n\t" \
"mov %%g6, %%g3\n\t" \
diff --git a/arch/sparc/include/asm/tlb_64.h b/arch/sparc/include/asm/tlb_64.h
index ec81cdedef2c..ee38e731bfa6 100644
--- a/arch/sparc/include/asm/tlb_64.h
+++ b/arch/sparc/include/asm/tlb_64.h
@@ -57,6 +57,8 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned i
static inline void tlb_flush_mmu(struct mmu_gather *mp)
{
+ if (!mp->fullmm)
+ flush_tlb_pending();
if (mp->need_flush) {
free_pages_and_swap_cache(mp->pages, mp->pages_nr);
mp->pages_nr = 0;
@@ -78,8 +80,6 @@ static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, un
if (mp->fullmm)
mp->fullmm = 0;
- else
- flush_tlb_pending();
/* keep the page table cache within bounds */
check_pgt_cache();
diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h
index 5bc0b8fd6374..e5ea8d332421 100644
--- a/arch/sparc/include/asm/topology_64.h
+++ b/arch/sparc/include/asm/topology_64.h
@@ -28,11 +28,6 @@ static inline cpumask_t node_to_cpumask(int node)
#define node_to_cpumask_ptr_next(v, node) \
v = &(numa_cpumask_lookup_table[node])
-static inline int node_to_first_cpu(int node)
-{
- return cpumask_first(cpumask_of_node(node));
-}
-
struct pci_bus;
#ifdef CONFIG_PCI
extern int pcibus_to_node(struct pci_bus *pbus);
@@ -43,13 +38,9 @@ static inline int pcibus_to_node(struct pci_bus *pbus)
}
#endif
-#define pcibus_to_cpumask(bus) \
- (pcibus_to_node(bus) == -1 ? \
- CPU_MASK_ALL : \
- node_to_cpumask(pcibus_to_node(bus)))
#define cpumask_of_pcibus(bus) \
(pcibus_to_node(bus) == -1 ? \
- CPU_MASK_ALL_PTR : \
+ cpu_all_mask : \
cpumask_of_node(pcibus_to_node(bus)))
#define SD_NODE_INIT (struct sched_domain) { \
@@ -89,7 +80,6 @@ static inline int pcibus_to_node(struct pci_bus *pbus)
#define smt_capable() (sparc64_multi_core)
#endif /* CONFIG_SMP */
-#define cpu_coregroup_map(cpu) (cpu_core_map[cpu])
#define cpu_coregroup_mask(cpu) (&cpu_core_map[cpu])
#endif /* _ASM_SPARC64_TOPOLOGY_H */
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c
index 57c39843fb2a..90350f838f05 100644
--- a/arch/sparc/kernel/ds.c
+++ b/arch/sparc/kernel/ds.c
@@ -653,7 +653,7 @@ static void __cpuinit dr_cpu_data(struct ds_info *dp,
if (cpu_list[i] == CPU_SENTINEL)
continue;
- if (cpu_list[i] < NR_CPUS)
+ if (cpu_list[i] < nr_cpu_ids)
cpu_set(cpu_list[i], mask);
}
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
index a46c3a21e26d..3a1b7bf03cff 100644
--- a/arch/sparc/kernel/head_64.S
+++ b/arch/sparc/kernel/head_64.S
@@ -686,7 +686,7 @@ tlb_fixup_done:
* point.
*
* There used to be enormous complexity wrt. transferring
- * over from the firwmare's trap table to the Linux kernel's.
+ * over from the firmware's trap table to the Linux kernel's.
* For example, there was a chicken & egg problem wrt. building
* the OBP page tables, yet needing to be on the Linux kernel
* trap table (to translate PAGE_OFFSET addresses) in order to
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index 44dd5ee64339..ad800b80c718 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -439,7 +439,6 @@ static int request_fast_irq(unsigned int irq,
flush_cache_all();
action->flags = irqflags;
- cpus_clear(action->mask);
action->name = devname;
action->dev_id = NULL;
action->next = NULL;
@@ -574,7 +573,6 @@ int request_irq(unsigned int irq,
action->handler = handler;
action->flags = irqflags;
- cpus_clear(action->mask);
action->name = devname;
action->next = NULL;
action->dev_id = dev_id;
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index 233bd87a9637..5deabe921a47 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -185,7 +185,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%10u ", kstat_irqs(i));
#else
for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#endif
seq_printf(p, " %9s", irq_desc[i].chip->typename);
seq_printf(p, " %s", action->name);
@@ -266,12 +266,12 @@ static int irq_choose_cpu(unsigned int virt_irq)
spin_lock_irqsave(&irq_rover_lock, flags);
while (!cpu_online(irq_rover)) {
- if (++irq_rover >= NR_CPUS)
+ if (++irq_rover >= nr_cpu_ids)
irq_rover = 0;
}
cpuid = irq_rover;
do {
- if (++irq_rover >= NR_CPUS)
+ if (++irq_rover >= nr_cpu_ids)
irq_rover = 0;
} while (!cpu_online(irq_rover));
diff --git a/arch/sparc/kernel/kgdb_64.c b/arch/sparc/kernel/kgdb_64.c
index fefbe6dc51be..f5a0fd490b59 100644
--- a/arch/sparc/kernel/kgdb_64.c
+++ b/arch/sparc/kernel/kgdb_64.c
@@ -108,7 +108,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
}
#ifdef CONFIG_SMP
-void smp_kgdb_capture_client(struct pt_regs *regs)
+void smp_kgdb_capture_client(int irq, struct pt_regs *regs)
{
unsigned long flags;
diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c
index adaaed4ea2fb..00d034ea2164 100644
--- a/arch/sparc/kernel/led.c
+++ b/arch/sparc/kernel/led.c
@@ -126,7 +126,6 @@ static int __init led_init(void)
led = proc_create("led", 0, NULL, &led_proc_fops);
if (!led)
return -ENOMEM;
- led->owner = THIS_MODULE;
printk(KERN_INFO
"led: version %s, Lars Kotthoff <metalhead@metalhead.ws>\n",
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 3f79f0c23a08..f0e6ed23a468 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -567,7 +567,7 @@ static void __init report_platform_properties(void)
max_cpu = NR_CPUS;
}
for (i = 0; i < max_cpu; i++)
- cpu_set(i, cpu_possible_map);
+ set_cpu_possible(i, true);
}
#endif
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
index f3577223c863..2c0cc72d295b 100644
--- a/arch/sparc/kernel/nmi.c
+++ b/arch/sparc/kernel/nmi.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/kernel_stat.h>
+#include <linux/reboot.h>
#include <linux/slab.h>
#include <linux/kdebug.h>
#include <linux/delay.h>
@@ -206,13 +207,33 @@ void nmi_adjust_hz(unsigned int new_hz)
}
EXPORT_SYMBOL_GPL(nmi_adjust_hz);
+static int nmi_shutdown(struct notifier_block *nb, unsigned long cmd, void *p)
+{
+ on_each_cpu(stop_watchdog, NULL, 1);
+ return 0;
+}
+
+static struct notifier_block nmi_reboot_notifier = {
+ .notifier_call = nmi_shutdown,
+};
+
int __init nmi_init(void)
{
+ int err;
+
nmi_usable = 1;
on_each_cpu(start_watchdog, NULL, 1);
- return check_nmi_watchdog();
+ err = check_nmi_watchdog();
+ if (!err) {
+ err = register_reboot_notifier(&nmi_reboot_notifier);
+ if (err) {
+ nmi_usable = 0;
+ on_each_cpu(stop_watchdog, NULL, 1);
+ }
+ }
+ return err;
}
static int __init setup_nmi_watchdog(char *str)
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index 64e6edf17b9d..b775658a927d 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -368,7 +368,7 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm)
const u32 *vdma = of_get_property(pbm->op->node, "virtual-dma", NULL);
if (vdma) {
- struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL);
+ struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL);
if (!rp) {
prom_printf("Cannot allocate IOMMU resource.\n");
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index f4bee35a1b46..2830b415e214 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -455,7 +455,7 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags,
*/
extern void ret_from_fork(void);
-int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+int copy_thread(unsigned long clone_flags, unsigned long sp,
unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index a73954b87f0a..4041f94e7724 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -561,7 +561,7 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags,
* Parent --> %o0 == childs pid, %o1 == 0
* Child --> %o0 == parents pid, %o1 == 1
*/
-int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+int copy_thread(unsigned long clone_flags, unsigned long sp,
unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
diff --git a/arch/sparc/kernel/prom_64.c b/arch/sparc/kernel/prom_64.c
index edecca7b8116..ca55c7012f77 100644
--- a/arch/sparc/kernel/prom_64.c
+++ b/arch/sparc/kernel/prom_64.c
@@ -518,8 +518,8 @@ void __init of_fill_in_cpu_data(void)
}
#ifdef CONFIG_SMP
- cpu_set(cpuid, cpu_present_map);
- cpu_set(cpuid, cpu_possible_map);
+ set_cpu_present(cpuid, true);
+ set_cpu_possible(cpuid, true);
#endif
}
diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c
index 1e5ac4e282e1..132d81fb2616 100644
--- a/arch/sparc/kernel/smp_32.c
+++ b/arch/sparc/kernel/smp_32.c
@@ -70,13 +70,12 @@ void __init smp_cpus_done(unsigned int max_cpus)
extern void smp4m_smp_done(void);
extern void smp4d_smp_done(void);
unsigned long bogosum = 0;
- int cpu, num;
+ int cpu, num = 0;
- for (cpu = 0, num = 0; cpu < NR_CPUS; cpu++)
- if (cpu_online(cpu)) {
- num++;
- bogosum += cpu_data(cpu).udelay_val;
- }
+ for_each_online_cpu(cpu) {
+ num++;
+ bogosum += cpu_data(cpu).udelay_val;
+ }
printk("Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
num, bogosum/(500000/HZ),
@@ -144,7 +143,7 @@ void smp_flush_tlb_all(void)
void smp_flush_cache_mm(struct mm_struct *mm)
{
if(mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask = mm->cpu_vm_mask;
+ cpumask_t cpu_mask = *mm_cpumask(mm);
cpu_clear(smp_processor_id(), cpu_mask);
if (!cpus_empty(cpu_mask))
xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm);
@@ -155,12 +154,13 @@ void smp_flush_cache_mm(struct mm_struct *mm)
void smp_flush_tlb_mm(struct mm_struct *mm)
{
if(mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask = mm->cpu_vm_mask;
+ cpumask_t cpu_mask = *mm_cpumask(mm);
cpu_clear(smp_processor_id(), cpu_mask);
if (!cpus_empty(cpu_mask)) {
xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm);
if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm)
- mm->cpu_vm_mask = cpumask_of_cpu(smp_processor_id());
+ cpumask_copy(mm_cpumask(mm),
+ cpumask_of(smp_processor_id()));
}
local_flush_tlb_mm(mm);
}
@@ -172,7 +172,7 @@ void smp_flush_cache_range(struct vm_area_struct *vma, unsigned long start,
struct mm_struct *mm = vma->vm_mm;
if (mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask = mm->cpu_vm_mask;
+ cpumask_t cpu_mask = *mm_cpumask(mm);
cpu_clear(smp_processor_id(), cpu_mask);
if (!cpus_empty(cpu_mask))
xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) vma, start, end);
@@ -186,7 +186,7 @@ void smp_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
struct mm_struct *mm = vma->vm_mm;
if (mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask = mm->cpu_vm_mask;
+ cpumask_t cpu_mask = *mm_cpumask(mm);
cpu_clear(smp_processor_id(), cpu_mask);
if (!cpus_empty(cpu_mask))
xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) vma, start, end);
@@ -199,7 +199,7 @@ void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
struct mm_struct *mm = vma->vm_mm;
if(mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask = mm->cpu_vm_mask;
+ cpumask_t cpu_mask = *mm_cpumask(mm);
cpu_clear(smp_processor_id(), cpu_mask);
if (!cpus_empty(cpu_mask))
xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page);
@@ -212,7 +212,7 @@ void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
struct mm_struct *mm = vma->vm_mm;
if(mm->context != NO_CONTEXT) {
- cpumask_t cpu_mask = mm->cpu_vm_mask;
+ cpumask_t cpu_mask = *mm_cpumask(mm);
cpu_clear(smp_processor_id(), cpu_mask);
if (!cpus_empty(cpu_mask))
xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page);
@@ -241,7 +241,7 @@ void smp_flush_page_to_ram(unsigned long page)
void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
{
- cpumask_t cpu_mask = mm->cpu_vm_mask;
+ cpumask_t cpu_mask = *mm_cpumask(mm);
cpu_clear(smp_processor_id(), cpu_mask);
if (!cpus_empty(cpu_mask))
xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr);
@@ -332,8 +332,8 @@ void __init smp_setup_cpu_possible_map(void)
instance = 0;
while (!cpu_find_by_instance(instance, NULL, &mid)) {
if (mid < NR_CPUS) {
- cpu_set(mid, cpu_possible_map);
- cpu_set(mid, cpu_present_map);
+ set_cpu_possible(mid, true);
+ set_cpu_present(mid, true);
}
instance++;
}
@@ -351,8 +351,8 @@ void __init smp_prepare_boot_cpu(void)
printk("boot cpu id != 0, this could work but is untested\n");
current_thread_info()->cpu = cpuid;
- cpu_set(cpuid, cpu_online_map);
- cpu_set(cpuid, cpu_possible_map);
+ set_cpu_online(cpuid, true);
+ set_cpu_possible(cpuid, true);
}
int __cpuinit __cpu_up(unsigned int cpu)
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index 6cd1a5b65067..708e12a26b05 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -808,9 +808,9 @@ static void smp_start_sync_tick_client(int cpu)
extern unsigned long xcall_call_function;
-void arch_send_call_function_ipi(cpumask_t mask)
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
{
- xcall_deliver((u64) &xcall_call_function, 0, 0, &mask);
+ xcall_deliver((u64) &xcall_call_function, 0, 0, mask);
}
extern unsigned long xcall_call_function_single;
@@ -850,7 +850,7 @@ static void tsb_sync(void *info)
void smp_tsb_sync(struct mm_struct *mm)
{
- smp_call_function_mask(mm->cpu_vm_mask, tsb_sync, mm, 1);
+ smp_call_function_many(mm_cpumask(mm), tsb_sync, mm, 1);
}
extern unsigned long xcall_flush_tlb_mm;
@@ -1031,7 +1031,7 @@ void smp_fetch_global_regs(void)
* If the address space is non-shared (ie. mm->count == 1) we avoid
* cross calls when we want to flush the currently running process's
* tlb state. This is done by clearing all cpu bits except the current
- * processor's in current->active_mm->cpu_vm_mask and performing the
+ * processor's in current->mm->cpu_vm_mask and performing the
* flush locally only. This will force any subsequent cpus which run
* this task to flush the context from the local tlb if the process
* migrates to another cpu (again).
@@ -1055,13 +1055,13 @@ void smp_flush_tlb_mm(struct mm_struct *mm)
int cpu = get_cpu();
if (atomic_read(&mm->mm_users) == 1) {
- mm->cpu_vm_mask = cpumask_of_cpu(cpu);
+ cpumask_copy(mm_cpumask(mm), cpumask_of(cpu));
goto local_flush_and_out;
}
smp_cross_call_masked(&xcall_flush_tlb_mm,
ctx, 0, 0,
- &mm->cpu_vm_mask);
+ mm_cpumask(mm));
local_flush_and_out:
__flush_tlb_mm(ctx, SECONDARY_CONTEXT);
@@ -1074,12 +1074,12 @@ void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long
u32 ctx = CTX_HWBITS(mm->context);
int cpu = get_cpu();
- if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1)
- mm->cpu_vm_mask = cpumask_of_cpu(cpu);
+ if (mm == current->mm && atomic_read(&mm->mm_users) == 1)
+ cpumask_copy(mm_cpumask(mm), cpumask_of(cpu));
else
smp_cross_call_masked(&xcall_flush_tlb_pending,
ctx, nr, (unsigned long) vaddrs,
- &mm->cpu_vm_mask);
+ mm_cpumask(mm));
__flush_tlb_pending(ctx, nr, vaddrs);
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index 3369fef5b4b3..ab036a72de5a 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -326,7 +326,6 @@ int sun4d_request_irq(unsigned int irq,
action->handler = handler;
action->flags = irqflags;
- cpus_clear(action->mask);
action->name = devname;
action->next = NULL;
action->dev_id = dev_id;
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index 50afaed99c8a..54fb02468f0d 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -150,7 +150,7 @@ void __cpuinit smp4d_callin(void)
spin_lock_irqsave(&sun4d_imsk_lock, flags);
cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */
spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
- cpu_set(cpuid, cpu_online_map);
+ set_cpu_online(cpuid, true);
}
@@ -228,11 +228,10 @@ void __init smp4d_smp_done(void)
/* setup cpu list for irq rotation */
first = 0;
prev = &first;
- for (i = 0; i < NR_CPUS; i++)
- if (cpu_online(i)) {
- *prev = i;
- prev = &cpu_data(i).next;
- }
+ for_each_online_cpu(i) {
+ *prev = i;
+ prev = &cpu_data(i).next;
+ }
*prev = first;
local_flush_cache_all();
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index 8040376c4890..960b113d0006 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -113,7 +113,7 @@ void __cpuinit smp4m_callin(void)
local_irq_enable();
- cpu_set(cpuid, cpu_online_map);
+ set_cpu_online(cpuid, true);
}
/*
@@ -186,11 +186,9 @@ void __init smp4m_smp_done(void)
/* setup cpu list for irq rotation */
first = 0;
prev = &first;
- for (i = 0; i < NR_CPUS; i++) {
- if (cpu_online(i)) {
- *prev = i;
- prev = &cpu_data(i).next;
- }
+ for_each_online_cpu(i) {
+ *prev = i;
+ prev = &cpu_data(i).next;
}
*prev = first;
local_flush_cache_all();
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index f93c42a2b522..a8000b1cda74 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -51,7 +51,7 @@ sys_call_table32:
/*150*/ .word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
.word compat_sys_fcntl64, sys_inotify_rm_watch, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount
/*160*/ .word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys32_getdomainname, sys32_setdomainname, sys_nis_syscall
- .word sys_quotactl, sys_set_tid_address, compat_sys_mount, sys_ustat, sys32_setxattr
+ .word sys_quotactl, sys_set_tid_address, compat_sys_mount, compat_sys_ustat, sys32_setxattr
/*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents
.word sys_setsid, sys_fchdir, sys32_fgetxattr, sys_listxattr, sys_llistxattr
/*180*/ .word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall
diff --git a/arch/sparc/kernel/ttable.S b/arch/sparc/kernel/ttable.S
index d9bdfb9d5c18..76d837fc47d3 100644
--- a/arch/sparc/kernel/ttable.S
+++ b/arch/sparc/kernel/ttable.S
@@ -64,7 +64,12 @@ tl0_irq6: TRAP_IRQ(smp_call_function_single_client, 6)
tl0_irq6: BTRAP(0x46)
#endif
tl0_irq7: TRAP_IRQ(deferred_pcr_work_irq, 7)
-tl0_irq8: BTRAP(0x48) BTRAP(0x49)
+#ifdef CONFIG_KGDB
+tl0_irq8: TRAP_IRQ(smp_kgdb_capture_client, 8)
+#else
+tl0_irq8: BTRAP(0x48)
+#endif
+tl0_irq9: BTRAP(0x49)
tl0_irq10: BTRAP(0x4a) BTRAP(0x4b) BTRAP(0x4c) BTRAP(0x4d)
tl0_irq14: TRAP_IRQ(timer_interrupt, 14)
tl0_irq15: TRAP_NMI_IRQ(perfctr_irq, 15)
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
index 752d0c9fb544..7916feba6e4a 100644
--- a/arch/sparc/mm/highmem.c
+++ b/arch/sparc/mm/highmem.c
@@ -39,6 +39,7 @@ void *kmap_atomic(struct page *page, enum km_type type)
if (!PageHighMem(page))
return page_address(page);
+ debug_kmap_atomic(type);
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 00373ce2d8fb..2c8dfeb7ab04 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -1092,7 +1092,7 @@ static void __init numa_parse_mdesc_group_cpus(struct mdesc_handle *md,
if (strcmp(name, "cpu"))
continue;
id = mdesc_get_property(md, target, "id", NULL);
- if (*id < NR_CPUS)
+ if (*id < nr_cpu_ids)
cpu_set(*id, *mask);
}
}
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index fe7ed08390bb..06c9a7d98206 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -1425,7 +1425,7 @@ static void __init init_vac_layout(void)
min_line_size = vac_line_size;
//FIXME: cpus not contiguous!!
cpu++;
- if (cpu >= NR_CPUS || !cpu_online(cpu))
+ if (cpu >= nr_cpu_ids || !cpu_online(cpu))
break;
#else
break;
diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S
index 80c788ec7c32..b57a5942ba64 100644
--- a/arch/sparc/mm/ultra.S
+++ b/arch/sparc/mm/ultra.S
@@ -679,28 +679,8 @@ xcall_new_mmu_context_version:
#ifdef CONFIG_KGDB
.globl xcall_kgdb_capture
xcall_kgdb_capture:
-661: rdpr %pstate, %g2
- wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
- .section .sun4v_2insn_patch, "ax"
- .word 661b
- nop
- nop
- .previous
-
- rdpr %pil, %g2
- wrpr %g0, PIL_NORMAL_MAX, %pil
- sethi %hi(109f), %g7
- ba,pt %xcc, etrap_irq
-109: or %g7, %lo(109b), %g7
-#ifdef CONFIG_TRACE_IRQFLAGS
- call trace_hardirqs_off
- nop
-#endif
- call smp_kgdb_capture_client
- add %sp, PTREGS_OFF, %o0
- /* Has to be a non-v9 branch due to the large distance. */
- ba rtrap_xcall
- ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
+ wr %g0, (1 << PIL_KGDB_CAPTURE), %set_softint
+ retry
#endif
#endif /* CONFIG_SMP */
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index fde510b664d3..434ba121e3c5 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -86,7 +86,7 @@ static int uml_net_rx(struct net_device *dev)
drop_skb->dev = dev;
/* Read a packet into drop_skb and don't do anything with it. */
(*lp->read)(lp->fd, drop_skb, lp);
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return 0;
}
@@ -99,8 +99,8 @@ static int uml_net_rx(struct net_device *dev)
skb_trim(skb, pkt_len);
skb->protocol = (*lp->protocol)(skb);
- lp->stats.rx_bytes += skb->len;
- lp->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
netif_rx(skb);
return pkt_len;
}
@@ -224,8 +224,8 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
len = (*lp->write)(lp->fd, skb, lp);
if (len == skb->len) {
- lp->stats.tx_packets++;
- lp->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
dev->trans_start = jiffies;
netif_start_queue(dev);
@@ -234,7 +234,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
else if (len == 0) {
netif_start_queue(dev);
- lp->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
}
else {
netif_start_queue(dev);
@@ -248,12 +248,6 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
-static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
-{
- struct uml_net_private *lp = netdev_priv(dev);
- return &lp->stats;
-}
-
static void uml_net_set_multicast_list(struct net_device *dev)
{
return;
@@ -377,6 +371,18 @@ static void net_device_release(struct device *dev)
free_netdev(netdev);
}
+static const struct net_device_ops uml_netdev_ops = {
+ .ndo_open = uml_net_open,
+ .ndo_stop = uml_net_close,
+ .ndo_start_xmit = uml_net_start_xmit,
+ .ndo_set_multicast_list = uml_net_set_multicast_list,
+ .ndo_tx_timeout = uml_net_tx_timeout,
+ .ndo_set_mac_address = uml_net_set_mac,
+ .ndo_change_mtu = uml_net_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*
* Ensures that platform_driver_register is called only once by
* eth_configure. Will be set in an initcall.
@@ -473,14 +479,7 @@ static void eth_configure(int n, void *init, char *mac,
set_ether_mac(dev, device->mac);
dev->mtu = transport->user->mtu;
- dev->open = uml_net_open;
- dev->hard_start_xmit = uml_net_start_xmit;
- dev->stop = uml_net_close;
- dev->get_stats = uml_net_get_stats;
- dev->set_multicast_list = uml_net_set_multicast_list;
- dev->tx_timeout = uml_net_tx_timeout;
- dev->set_mac_address = uml_net_set_mac;
- dev->change_mtu = uml_net_change_mtu;
+ dev->netdev_ops = &uml_netdev_ops;
dev->ethtool_ops = &uml_net_ethtool_ops;
dev->watchdog_timeo = (HZ >> 1);
dev->irq = UM_ETH_IRQ;
@@ -758,7 +757,7 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
void (*proc)(unsigned char *, unsigned char *, void *);
unsigned char addr_buf[4], netmask_buf[4];
- if (dev->open != uml_net_open)
+ if (dev->netdev_ops->ndo_open != uml_net_open)
return NOTIFY_DONE;
lp = netdev_priv(dev);
diff --git a/arch/um/drivers/pcap_user.h b/arch/um/drivers/pcap_user.h
index 96b80b565eeb..d8ba6153f912 100644
--- a/arch/um/drivers/pcap_user.h
+++ b/arch/um/drivers/pcap_user.h
@@ -19,13 +19,3 @@ extern const struct net_user_info pcap_user_info;
extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri);
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/port.h b/arch/um/drivers/port.h
index 9117609a575d..372a80c0556a 100644
--- a/arch/um/drivers/port.h
+++ b/arch/um/drivers/port.h
@@ -18,13 +18,3 @@ extern void port_remove_dev(void *d);
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/ssl.h b/arch/um/drivers/ssl.h
index 98412aa66607..314d17725ce6 100644
--- a/arch/um/drivers/ssl.h
+++ b/arch/um/drivers/ssl.h
@@ -11,13 +11,3 @@ extern void ssl_receive_char(int line, char ch);
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/stdio_console.h b/arch/um/drivers/stdio_console.h
index 505a3d5bea5e..6d8275f71fd4 100644
--- a/arch/um/drivers/stdio_console.h
+++ b/arch/um/drivers/stdio_console.h
@@ -9,13 +9,3 @@
extern void save_console_flags(void);
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 0a868118cf06..f934225fd8ef 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -17,12 +17,12 @@
* James McMechan
*/
-#define MAJOR_NR UBD_MAJOR
#define UBD_SHIFT 4
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/blkdev.h"
+#include "linux/ata.h"
#include "linux/hdreg.h"
#include "linux/init.h"
#include "linux/cdrom.h"
@@ -115,7 +115,7 @@ static struct block_device_operations ubd_blops = {
};
/* Protected by ubd_lock */
-static int fake_major = MAJOR_NR;
+static int fake_major = UBD_MAJOR;
static struct gendisk *ubd_gendisk[MAX_DEV];
static struct gendisk *fake_gendisk[MAX_DEV];
@@ -299,7 +299,7 @@ static int ubd_setup_common(char *str, int *index_out, char **error_out)
}
mutex_lock(&ubd_lock);
- if(fake_major != MAJOR_NR){
+ if (fake_major != UBD_MAJOR) {
*error_out = "Can't assign a fake major twice";
goto out1;
}
@@ -818,13 +818,13 @@ static int ubd_disk_register(int major, u64 size, int unit,
disk->first_minor = unit << UBD_SHIFT;
disk->fops = &ubd_blops;
set_capacity(disk, size / 512);
- if(major == MAJOR_NR)
+ if (major == UBD_MAJOR)
sprintf(disk->disk_name, "ubd%c", 'a' + unit);
else
sprintf(disk->disk_name, "ubd_fake%d", unit);
/* sysfs register (not for ide fake devices) */
- if (major == MAJOR_NR) {
+ if (major == UBD_MAJOR) {
ubd_devs[unit].pdev.id = unit;
ubd_devs[unit].pdev.name = DRIVER_NAME;
ubd_devs[unit].pdev.dev.release = ubd_device_release;
@@ -871,13 +871,13 @@ static int ubd_add(int n, char **error_out)
ubd_dev->queue->queuedata = ubd_dev;
blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG);
- err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
+ err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
if(err){
*error_out = "Failed to register device";
goto out_cleanup;
}
- if(fake_major != MAJOR_NR)
+ if (fake_major != UBD_MAJOR)
ubd_disk_register(fake_major, ubd_dev->size, n,
&fake_gendisk[n]);
@@ -1059,10 +1059,10 @@ static int __init ubd_init(void)
char *error;
int i, err;
- if (register_blkdev(MAJOR_NR, "ubd"))
+ if (register_blkdev(UBD_MAJOR, "ubd"))
return -1;
- if (fake_major != MAJOR_NR) {
+ if (fake_major != UBD_MAJOR) {
char name[sizeof("ubd_nnn\0")];
snprintf(name, sizeof(name), "ubd_%d", fake_major);
@@ -1309,16 +1309,15 @@ static int ubd_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
struct ubd *ubd_dev = bdev->bd_disk->private_data;
- struct hd_driveid ubd_id = {
- .cyls = 0,
- .heads = 128,
- .sectors = 32,
- };
+ u16 ubd_id[ATA_ID_WORDS];
switch (cmd) {
struct cdrom_volctrl volume;
case HDIO_GET_IDENTITY:
- ubd_id.cyls = ubd_dev->size / (128 * 32 * 512);
+ memset(&ubd_id, 0, ATA_ID_WORDS * 2);
+ ubd_id[ATA_ID_CYLS] = ubd_dev->size / (128 * 32 * 512);
+ ubd_id[ATA_ID_HEADS] = 128;
+ ubd_id[ATA_ID_SECTORS] = 32;
if(copy_to_user((char __user *) arg, (char *) &ubd_id,
sizeof(ubd_id)))
return -EFAULT;
diff --git a/arch/um/drivers/xterm.h b/arch/um/drivers/xterm.h
index f33a6e77b186..56b9c4aba423 100644
--- a/arch/um/drivers/xterm.h
+++ b/arch/um/drivers/xterm.h
@@ -10,13 +10,3 @@ extern int xterm_fd(int socket, int *pid_out);
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/asm/irq_vectors.h b/arch/um/include/asm/irq_vectors.h
index 62ddba6fc733..272a81e0ce14 100644
--- a/arch/um/include/asm/irq_vectors.h
+++ b/arch/um/include/asm/irq_vectors.h
@@ -8,13 +8,3 @@
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h
index 2cf35c21d694..cf259de51531 100644
--- a/arch/um/include/asm/mmu.h
+++ b/arch/um/include/asm/mmu.h
@@ -10,13 +10,3 @@
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/asm/pda.h b/arch/um/include/asm/pda.h
index 0d8bf33ffd42..ddcd774fc2a0 100644
--- a/arch/um/include/asm/pda.h
+++ b/arch/um/include/asm/pda.h
@@ -19,13 +19,3 @@ extern struct foo me;
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/asm/pgalloc.h b/arch/um/include/asm/pgalloc.h
index 9062a6e72241..718984359f8c 100644
--- a/arch/um/include/asm/pgalloc.h
+++ b/arch/um/include/asm/pgalloc.h
@@ -60,13 +60,3 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/asm/pgtable-3level.h b/arch/um/include/asm/pgtable-3level.h
index 0446f456b428..084de4a9fc70 100644
--- a/arch/um/include/asm/pgtable-3level.h
+++ b/arch/um/include/asm/pgtable-3level.h
@@ -134,13 +134,3 @@ static inline pmd_t pfn_pmd(pfn_t page_nr, pgprot_t pgprot)
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/shared/frame_kern.h b/arch/um/include/shared/frame_kern.h
index ce9514f57211..76078490c258 100644
--- a/arch/um/include/shared/frame_kern.h
+++ b/arch/um/include/shared/frame_kern.h
@@ -20,13 +20,3 @@ extern int setup_signal_stack_si(unsigned long stack_top, int sig,
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/shared/initrd.h b/arch/um/include/shared/initrd.h
index 439b9a814985..22673bcc273d 100644
--- a/arch/um/include/shared/initrd.h
+++ b/arch/um/include/shared/initrd.h
@@ -10,13 +10,3 @@ extern int load_initrd(char *filename, void *buf, int size);
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/shared/irq_kern.h b/arch/um/include/shared/irq_kern.h
index fba3895274f9..b05d22f3d84e 100644
--- a/arch/um/include/shared/irq_kern.h
+++ b/arch/um/include/shared/irq_kern.h
@@ -16,13 +16,3 @@ extern int um_request_irq(unsigned int irq, int fd, int type,
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/shared/mem_kern.h b/arch/um/include/shared/mem_kern.h
index cb7e196d366b..69be0fd0ce4b 100644
--- a/arch/um/include/shared/mem_kern.h
+++ b/arch/um/include/shared/mem_kern.h
@@ -18,13 +18,3 @@ extern void register_remapper(struct remapper *info);
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/shared/net_kern.h b/arch/um/include/shared/net_kern.h
index d843c7924a7c..5c367f22595b 100644
--- a/arch/um/include/shared/net_kern.h
+++ b/arch/um/include/shared/net_kern.h
@@ -26,7 +26,7 @@ struct uml_net_private {
spinlock_t lock;
struct net_device *dev;
struct timer_list tl;
- struct net_device_stats stats;
+
struct work_struct work;
int fd;
unsigned char mac[ETH_ALEN];
diff --git a/arch/um/include/shared/ubd_user.h b/arch/um/include/shared/ubd_user.h
index bb66517f0739..3845051f1b10 100644
--- a/arch/um/include/shared/ubd_user.h
+++ b/arch/um/include/shared/ubd_user.h
@@ -14,13 +14,3 @@ extern int kernel_fd;
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 499e5e95e609..388ec0a3ea9b 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -28,7 +28,7 @@ $(obj)/config.tmp: $(objtree)/.config FORCE
$(call if_changed,quote1)
quiet_cmd_quote1 = QUOTE $@
- cmd_quote1 = sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n"/' \
+ cmd_quote1 = sed -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n",/' \
$< > $@
$(obj)/config.c: $(src)/config.c.in $(obj)/config.tmp FORCE
@@ -36,9 +36,9 @@ $(obj)/config.c: $(src)/config.c.in $(obj)/config.tmp FORCE
quiet_cmd_quote2 = QUOTE $@
cmd_quote2 = sed -e '/CONFIG/{' \
- -e 's/"CONFIG"\;/""/' \
+ -e 's/"CONFIG"//' \
-e 'r $(obj)/config.tmp' \
-e 'a \' \
- -e '""\;' \
+ -e '""' \
-e '}' \
$< > $@
diff --git a/arch/um/kernel/config.c.in b/arch/um/kernel/config.c.in
index c062cbfe386e..b7a43feafde7 100644
--- a/arch/um/kernel/config.c.in
+++ b/arch/um/kernel/config.c.in
@@ -7,11 +7,15 @@
#include <stdlib.h>
#include "init.h"
-static __initdata char *config = "CONFIG";
+static __initdata const char *config[] = {
+"CONFIG"
+};
static int __init print_config(char *line, int *add)
{
- printf("%s", config);
+ int i;
+ for (i = 0; i < sizeof(config)/sizeof(config[0]); i++)
+ printf("%s", config[i]);
exit(0);
}
@@ -20,13 +24,3 @@ __uml_setup("--showconfig", print_config,
" Prints the config file that this UML binary was generated from.\n\n"
);
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 3d7aad09b171..336b61569072 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -42,7 +42,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%10u ", kstat_irqs(i));
#else
for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#endif
seq_printf(p, " %14s", irq_desc[i].chip->typename);
seq_printf(p, " %s", action->name);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index a1c6d07cac3e..4a28a1568d85 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -179,7 +179,7 @@ void fork_handler(void)
userspace(&current->thread.regs.regs);
}
-int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+int copy_thread(unsigned long clone_flags, unsigned long sp,
unsigned long stack_top, struct task_struct * p,
struct pt_regs *regs)
{
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index c4df705b8359..a4625c7b2bf9 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -127,7 +127,8 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[])
fs = get_fs();
set_fs(KERNEL_DS);
- ret = um_execve(filename, argv, envp);
+ ret = um_execve((char *)filename, (char __user *__user *)argv,
+ (char __user *__user *) envp);
set_fs(fs);
return ret;
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 183db26d01bf..02ee9adff54a 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -244,7 +244,7 @@ static void __init check_sysemu(void)
if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
(void *) PTRACE_O_TRACESYSGOOD) < 0))
- fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
+ fatal_perror("check_sysemu: PTRACE_OLDSETOPTIONS failed");
while (1) {
count++;
@@ -252,12 +252,12 @@ static void __init check_sysemu(void)
goto fail;
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if (n < 0)
- fatal_perror("check_ptrace : wait failed");
+ fatal_perror("check_sysemu: wait failed");
if (WIFSTOPPED(status) &&
(WSTOPSIG(status) == (SIGTRAP|0x80))) {
if (!count) {
- non_fatal("check_ptrace : SYSEMU_SINGLESTEP "
+ non_fatal("check_sysemu: SYSEMU_SINGLESTEP "
"doesn't singlestep");
goto fail;
}
@@ -271,7 +271,7 @@ static void __init check_sysemu(void)
else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
count++;
else {
- non_fatal("check_ptrace : expected SIGTRAP or "
+ non_fatal("check_sysemu: expected SIGTRAP or "
"(SIGTRAP | 0x80), got status = %d\n",
status);
goto fail;
diff --git a/arch/um/sys-i386/asm/archparam.h b/arch/um/sys-i386/asm/archparam.h
index 93fd723344e5..2a18a884ca1b 100644
--- a/arch/um/sys-i386/asm/archparam.h
+++ b/arch/um/sys-i386/asm/archparam.h
@@ -14,13 +14,3 @@
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/shared/sysdep/checksum.h b/arch/um/sys-i386/shared/sysdep/checksum.h
index 0cb4645cbeb8..ed47445f3905 100644
--- a/arch/um/sys-i386/shared/sysdep/checksum.h
+++ b/arch/um/sys-i386/shared/sysdep/checksum.h
@@ -199,13 +199,3 @@ static __inline__ __wsum csum_and_copy_to_user(const void *src,
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S
index 00e5f5203eea..c6260dd6ebb9 100644
--- a/arch/um/sys-i386/sys_call_table.S
+++ b/arch/um/sys-i386/sys_call_table.S
@@ -9,6 +9,17 @@
#define old_mmap old_mmap_i386
+#define ptregs_fork sys_fork
+#define ptregs_execve sys_execve
+#define ptregs_iopl sys_iopl
+#define ptregs_vm86old sys_vm86old
+#define ptregs_sigreturn sys_sigreturn
+#define ptregs_clone sys_clone
+#define ptregs_vm86 sys_vm86
+#define ptregs_rt_sigreturn sys_rt_sigreturn
+#define ptregs_sigaltstack sys_sigaltstack
+#define ptregs_vfork sys_vfork
+
.section .rodata,"a"
#include "../../x86/kernel/syscall_table_32.S"
diff --git a/arch/um/sys-ia64/sysdep/ptrace.h b/arch/um/sys-ia64/sysdep/ptrace.h
index 42dd8fb6f2f9..0f0f4e6fd334 100644
--- a/arch/um/sys-ia64/sysdep/ptrace.h
+++ b/arch/um/sys-ia64/sysdep/ptrace.h
@@ -14,13 +14,3 @@ struct sys_pt_regs {
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ia64/sysdep/sigcontext.h b/arch/um/sys-ia64/sysdep/sigcontext.h
index f15fb25260ba..76b43161e779 100644
--- a/arch/um/sys-ia64/sysdep/sigcontext.h
+++ b/arch/um/sys-ia64/sysdep/sigcontext.h
@@ -8,13 +8,3 @@
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ia64/sysdep/syscalls.h b/arch/um/sys-ia64/sysdep/syscalls.h
index 4a1f46ef1ebc..5f6700c41558 100644
--- a/arch/um/sys-ia64/sysdep/syscalls.h
+++ b/arch/um/sys-ia64/sysdep/syscalls.h
@@ -8,13 +8,3 @@
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/miscthings.c b/arch/um/sys-ppc/miscthings.c
index 373061c50129..1c11aed9c719 100644
--- a/arch/um/sys-ppc/miscthings.c
+++ b/arch/um/sys-ppc/miscthings.c
@@ -40,14 +40,3 @@ void shove_aux_table(unsigned long sp)
}
/* END stuff taken from arch/ppc/kernel/process.c */
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/ptrace.c b/arch/um/sys-ppc/ptrace.c
index 8e71b47f2b8e..66ef155248f1 100644
--- a/arch/um/sys-ppc/ptrace.c
+++ b/arch/um/sys-ppc/ptrace.c
@@ -56,13 +56,3 @@ int peek_user(struct task_struct *child, long addr, long data)
return put_user(tmp, (unsigned long *) data);
}
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/ptrace_user.c b/arch/um/sys-ppc/ptrace_user.c
index ff0b9c077a13..224d2403c37b 100644
--- a/arch/um/sys-ppc/ptrace_user.c
+++ b/arch/um/sys-ppc/ptrace_user.c
@@ -27,13 +27,3 @@ int ptrace_setregs(long pid, unsigned long *regs_in)
}
return 0;
}
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/shared/sysdep/ptrace.h b/arch/um/sys-ppc/shared/sysdep/ptrace.h
index df2397dba3e5..0e3230e937e1 100644
--- a/arch/um/sys-ppc/shared/sysdep/ptrace.h
+++ b/arch/um/sys-ppc/shared/sysdep/ptrace.h
@@ -91,13 +91,3 @@ extern void shove_aux_table(unsigned long sp);
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/shared/sysdep/sigcontext.h b/arch/um/sys-ppc/shared/sysdep/sigcontext.h
index f20d965de9c7..b7286f0a1e00 100644
--- a/arch/um/sys-ppc/shared/sysdep/sigcontext.h
+++ b/arch/um/sys-ppc/shared/sysdep/sigcontext.h
@@ -50,13 +50,3 @@
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/shared/sysdep/syscalls.h b/arch/um/sys-ppc/shared/sysdep/syscalls.h
index 679df351e19b..1ff81552251c 100644
--- a/arch/um/sys-ppc/shared/sysdep/syscalls.h
+++ b/arch/um/sys-ppc/shared/sysdep/syscalls.h
@@ -41,13 +41,3 @@ int old_mmap(unsigned long addr, unsigned long len,
#define LAST_ARCH_SYSCALL __NR_fadvise64
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-ppc/sigcontext.c b/arch/um/sys-ppc/sigcontext.c
index 4bdc15c89edd..40694d0f3d15 100644
--- a/arch/um/sys-ppc/sigcontext.c
+++ b/arch/um/sys-ppc/sigcontext.c
@@ -2,13 +2,3 @@
#include "asm/sigcontext.h"
#include "sysdep/ptrace.h"
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/asm/archparam.h b/arch/um/sys-x86_64/asm/archparam.h
index 270ed9586b68..6c083663b8d9 100644
--- a/arch/um/sys-x86_64/asm/archparam.h
+++ b/arch/um/sys-x86_64/asm/archparam.h
@@ -14,13 +14,3 @@
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/asm/module.h b/arch/um/sys-x86_64/asm/module.h
index 35b5491d3e96..8eb79c2d07d5 100644
--- a/arch/um/sys-x86_64/asm/module.h
+++ b/arch/um/sys-x86_64/asm/module.h
@@ -18,13 +18,3 @@ struct mod_arch_specific
#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/mem.c b/arch/um/sys-x86_64/mem.c
index 3f59a0a4f156..3f8df8abf347 100644
--- a/arch/um/sys-x86_64/mem.c
+++ b/arch/um/sys-x86_64/mem.c
@@ -14,12 +14,3 @@ unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS;
unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS;
unsigned long vm_force_exec32 = PROT_EXEC;
-/* Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 1a3150570785..4b3408206091 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -42,6 +42,7 @@ config X86
select HAVE_GENERIC_DMA_COHERENT if X86_32
select HAVE_EFFICIENT_UNALIGNED_ACCESS
select USER_STACKTRACE_SUPPORT
+ select HAVE_DMA_API_DEBUG
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
@@ -166,11 +167,17 @@ config AUDIT_ARCH
config ARCH_SUPPORTS_OPTIMIZED_INLINING
def_bool y
+config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+ def_bool y
+
# Use the generic interrupt handling code in kernel/irq/:
config GENERIC_HARDIRQS
bool
default y
+config GENERIC_HARDIRQS_NO__DO_IRQ
+ def_bool y
+
config GENERIC_IRQ_PROBE
bool
default y
@@ -246,6 +253,7 @@ config SMP
config X86_X2APIC
bool "Support x2apic"
depends on X86_LOCAL_APIC && X86_64
+ select INTR_REMAP
---help---
This enables x2apic support on CPUs that have this feature.
@@ -1131,7 +1139,7 @@ config NUMA_EMU
config NODES_SHIFT
int "Maximum NUMA Nodes (as a power of 2)" if !MAXSMP
- range 1 9 if X86_64
+ range 1 9
default "9" if MAXSMP
default "6" if X86_64
default "4" if X86_NUMAQ
@@ -1139,7 +1147,7 @@ config NODES_SHIFT
depends on NEED_MULTIPLE_NODES
---help---
Specify the maximum number of NUMA Nodes available on the target
- system. Increases memory reserved to accomodate various tables.
+ system. Increases memory reserved to accommodate various tables.
config HAVE_ARCH_BOOTMEM
def_bool y
@@ -1317,7 +1325,7 @@ config MTRR_SANITIZER
add writeback entries.
Can be disabled with disable_mtrr_cleanup on the kernel command line.
- The largest mtrr entry size for a continous block can be set with
+ The largest mtrr entry size for a continuous block can be set with
mtrr_chunk_size.
If unsure, say Y.
@@ -1832,8 +1840,8 @@ config PCI_MMCONFIG
config DMAR
bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
- depends on X86_64 && PCI_MSI && ACPI && EXPERIMENTAL
- ---help---
+ depends on PCI_MSI && ACPI && EXPERIMENTAL
+ help
DMA remapping (DMAR) devices support enables independent address
translations for Direct Memory Access (DMA) from devices.
These DMA remapping devices are reported via ACPI tables
@@ -1874,7 +1882,6 @@ config DMAR_FLOPPY_WA
config INTR_REMAP
bool "Support for Interrupt Remapping (EXPERIMENTAL)"
depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
- select X86_X2APIC
---help---
Supports Interrupt remapping for IO-APIC and MSI devices.
To use x2apic mode in the CPU's which support x2APIC enhancements or
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index a95eaf0e582a..924e156a85ab 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -456,24 +456,9 @@ config CPU_SUP_AMD
If unsure, say N.
-config CPU_SUP_CENTAUR_32
+config CPU_SUP_CENTAUR
default y
bool "Support Centaur processors" if PROCESSOR_SELECT
- depends on !64BIT
- ---help---
- This enables detection, tunings and quirks for Centaur processors
-
- You need this enabled if you want your kernel to run on a
- Centaur CPU. Disabling this option on other types of CPUs
- makes the kernel a tiny bit smaller. Disabling it on a Centaur
- CPU might render the kernel unbootable.
-
- If unsure, say N.
-
-config CPU_SUP_CENTAUR_64
- default y
- bool "Support Centaur processors" if PROCESSOR_SELECT
- depends on 64BIT
---help---
This enables detection, tunings and quirks for Centaur processors
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index fdb45df608b6..d8359e73317f 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -72,14 +72,6 @@ config DEBUG_STACK_USAGE
This option will slow down process creation somewhat.
-config DEBUG_PAGEALLOC
- bool "Debug page memory allocations"
- depends on DEBUG_KERNEL
- ---help---
- Unmap pages from the kernel linear mapping after free_pages().
- This results in a large slowdown, but helps to find certain types
- of memory corruptions.
-
config DEBUG_PER_CPU_MAPS
bool "Debug access to per_cpu maps"
depends on DEBUG_KERNEL
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 1836191839ee..f05d8c91d9e5 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -153,34 +153,23 @@ endif
boot := arch/x86/boot
-PHONY += zImage bzImage compressed zlilo bzlilo \
- zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install
+BOOT_TARGETS = bzlilo bzdisk fdimage fdimage144 fdimage288 isoimage install
+
+PHONY += bzImage $(BOOT_TARGETS)
# Default kernel to build
all: bzImage
# KBUILD_IMAGE specify target image being built
- KBUILD_IMAGE := $(boot)/bzImage
-zImage zlilo zdisk: KBUILD_IMAGE := $(boot)/zImage
+KBUILD_IMAGE := $(boot)/bzImage
-zImage bzImage: vmlinux
+bzImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
$(Q)mkdir -p $(objtree)/arch/$(UTS_MACHINE)/boot
$(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/$(UTS_MACHINE)/boot/$@
-compressed: zImage
-
-zlilo bzlilo: vmlinux
- $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zlilo
-
-zdisk bzdisk: vmlinux
- $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zdisk
-
-fdimage fdimage144 fdimage288 isoimage: vmlinux
- $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
-
-install:
- $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
+$(BOOT_TARGETS): vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $@
PHONY += vdso_install
vdso_install:
@@ -205,7 +194,3 @@ define archhelp
echo ' FDARGS="..." arguments for the booted kernel'
echo ' FDINITRD=file initrd for the booted kernel'
endef
-
-CLEAN_FILES += arch/x86/boot/fdimage \
- arch/x86/boot/image.iso \
- arch/x86/boot/mtools.conf
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index 57a29fecf6bb..6633b6e7505a 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -23,6 +23,7 @@ ROOT_DEV := CURRENT
SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
targets := vmlinux.bin setup.bin setup.elf bzImage
+targets += fdimage fdimage144 fdimage288 image.iso mtools.conf
subdir- := compressed
setup-y += a20.o cmdline.o copy.o cpu.o cpucheck.o edd.o
@@ -56,6 +57,7 @@ $(obj)/cpustr.h: $(obj)/mkcpustr FORCE
# How to compile the 16-bit code. Note we always compile for -march=i386,
# that way we can complain to the user if the CPU is insufficient.
KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
+ -DDISABLE_BRANCH_PROFILING \
-Wall -Wstrict-prototypes \
-march=i386 -mregparm=3 \
-include $(srctree)/$(src)/code16gcc.h \
@@ -65,7 +67,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
$(call cc-option, -fno-unit-at-a-time)) \
$(call cc-option, -fno-stack-protector) \
$(call cc-option, -mpreferred-stack-boundary=2)
-KBUILD_CFLAGS += $(call cc-option,-m32)
+KBUILD_CFLAGS += $(call cc-option, -m32)
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
$(obj)/bzImage: asflags-y := $(SVGA_MODE)
@@ -109,9 +111,11 @@ $(obj)/setup.bin: $(obj)/setup.elf FORCE
$(obj)/compressed/vmlinux: FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
-# Set this if you want to pass append arguments to the zdisk/fdimage/isoimage kernel
+# Set this if you want to pass append arguments to the
+# bzdisk/fdimage/isoimage kernel
FDARGS =
-# Set this if you want an initrd included with the zdisk/fdimage/isoimage kernel
+# Set this if you want an initrd included with the
+# bzdisk/fdimage/isoimage kernel
FDINITRD =
image_cmdline = default linux $(FDARGS) $(if $(FDINITRD),initrd=initrd.img,)
@@ -120,7 +124,7 @@ $(obj)/mtools.conf: $(src)/mtools.conf.in
sed -e 's|@OBJ@|$(obj)|g' < $< > $@
# This requires write access to /dev/fd0
-zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
+bzdisk: $(obj)/bzImage $(obj)/mtools.conf
MTOOLSRC=$(obj)/mtools.conf mformat a: ; sync
syslinux /dev/fd0 ; sync
echo '$(image_cmdline)' | \
@@ -128,10 +132,10 @@ zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
if [ -f '$(FDINITRD)' ] ; then \
MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' a:initrd.img ; \
fi
- MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux ; sync
+ MTOOLSRC=$(obj)/mtools.conf mcopy $(obj)/bzImage a:linux ; sync
# These require being root or having syslinux 2.02 or higher installed
-fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf
+fdimage fdimage144: $(obj)/bzImage $(obj)/mtools.conf
dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440
MTOOLSRC=$(obj)/mtools.conf mformat v: ; sync
syslinux $(obj)/fdimage ; sync
@@ -140,9 +144,9 @@ fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf
if [ -f '$(FDINITRD)' ] ; then \
MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' v:initrd.img ; \
fi
- MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux ; sync
+ MTOOLSRC=$(obj)/mtools.conf mcopy $(obj)/bzImage v:linux ; sync
-fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf
+fdimage288: $(obj)/bzImage $(obj)/mtools.conf
dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880
MTOOLSRC=$(obj)/mtools.conf mformat w: ; sync
syslinux $(obj)/fdimage ; sync
@@ -151,9 +155,9 @@ fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf
if [ -f '$(FDINITRD)' ] ; then \
MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' w:initrd.img ; \
fi
- MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux ; sync
+ MTOOLSRC=$(obj)/mtools.conf mcopy $(obj)/bzImage w:linux ; sync
-isoimage: $(BOOTIMAGE)
+isoimage: $(obj)/bzImage
-rm -rf $(obj)/isoimage
mkdir $(obj)/isoimage
for i in lib lib64 share end ; do \
@@ -163,7 +167,7 @@ isoimage: $(BOOTIMAGE)
fi ; \
if [ $$i = end ] ; then exit 1 ; fi ; \
done
- cp $(BOOTIMAGE) $(obj)/isoimage/linux
+ cp $(obj)/bzImage $(obj)/isoimage/linux
echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg
if [ -f '$(FDINITRD)' ] ; then \
cp '$(FDINITRD)' $(obj)/isoimage/initrd.img ; \
@@ -174,12 +178,13 @@ isoimage: $(BOOTIMAGE)
isohybrid $(obj)/image.iso 2>/dev/null || true
rm -rf $(obj)/isoimage
-zlilo: $(BOOTIMAGE)
+bzlilo: $(obj)/bzImage
if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
- cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
+ cat $(obj)/bzImage > $(INSTALL_PATH)/vmlinuz
cp System.map $(INSTALL_PATH)/
if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
install:
- sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
+ sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(obj)/bzImage \
+ System.map "$(INSTALL_PATH)"
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 3ca4c194b8e5..65551c9f8571 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -8,6 +8,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma h
KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
+KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
cflags-$(CONFIG_X86_64) := -mcmodel=small
KBUILD_CFLAGS += $(cflags-y)
KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c
index 8c3c25f35578..5054c2ddd1a0 100644
--- a/arch/x86/boot/memory.c
+++ b/arch/x86/boot/memory.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright 2007 rPath, Inc. - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
*
* This file is part of the Linux kernel, and is made available under
* the terms of the GNU General Public License version 2.
@@ -16,24 +17,38 @@
#define SMAP 0x534d4150 /* ASCII "SMAP" */
+struct e820_ext_entry {
+ struct e820entry std;
+ u32 ext_flags;
+} __attribute__((packed));
+
static int detect_memory_e820(void)
{
int count = 0;
u32 next = 0;
- u32 size, id;
+ u32 size, id, edi;
u8 err;
struct e820entry *desc = boot_params.e820_map;
+ static struct e820_ext_entry buf; /* static so it is zeroed */
+
+ /*
+ * Set this here so that if the BIOS doesn't change this field
+ * but still doesn't change %ecx, we're still okay...
+ */
+ buf.ext_flags = 1;
do {
- size = sizeof(struct e820entry);
+ size = sizeof buf;
- /* Important: %edx is clobbered by some BIOSes,
- so it must be either used for the error output
- or explicitly marked clobbered. */
- asm("int $0x15; setc %0"
+ /* Important: %edx and %esi are clobbered by some BIOSes,
+ so they must be either used for the error output
+ or explicitly marked clobbered. Given that, assume there
+ is something out there clobbering %ebp and %edi, too. */
+ asm("pushl %%ebp; int $0x15; popl %%ebp; setc %0"
: "=d" (err), "+b" (next), "=a" (id), "+c" (size),
- "=m" (*desc)
- : "D" (desc), "d" (SMAP), "a" (0xe820));
+ "=D" (edi), "+m" (buf)
+ : "D" (&buf), "d" (SMAP), "a" (0xe820)
+ : "esi");
/* BIOSes which terminate the chain with CF = 1 as opposed
to %ebx = 0 don't always report the SMAP signature on
@@ -51,8 +66,14 @@ static int detect_memory_e820(void)
break;
}
+ /* ACPI 3.0 added the extended flags support. If bit 0
+ in the extended flags is zero, we're supposed to simply
+ ignore the entry -- a backwards incompatible change! */
+ if (size > 20 && !(buf.ext_flags & 1))
+ continue;
+
+ *desc++ = buf.std;
count++;
- desc++;
} while (next && count < ARRAY_SIZE(boot_params.e820_map));
return boot_params.e820_entries = count;
diff --git a/arch/x86/boot/pmjump.S b/arch/x86/boot/pmjump.S
index 019c17a75851..3e0edc6d2a20 100644
--- a/arch/x86/boot/pmjump.S
+++ b/arch/x86/boot/pmjump.S
@@ -47,6 +47,7 @@ GLOBAL(protected_mode_jump)
ENDPROC(protected_mode_jump)
.code32
+ .section ".text32","ax"
GLOBAL(in_pm32)
# Set up data segments for flat 32-bit mode
movl %ecx, %ds
diff --git a/arch/x86/boot/setup.ld b/arch/x86/boot/setup.ld
index df9234b3a5e0..bb8dc2de7969 100644
--- a/arch/x86/boot/setup.ld
+++ b/arch/x86/boot/setup.ld
@@ -17,7 +17,8 @@ SECTIONS
.header : { *(.header) }
.inittext : { *(.inittext) }
.initdata : { *(.initdata) }
- .text : { *(.text*) }
+ .text : { *(.text) }
+ .text32 : { *(.text32) }
. = ALIGN(16);
.rodata : { *(.rodata*) }
diff --git a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c
index 5d4742ed4aa2..95d86ce0421c 100644
--- a/arch/x86/boot/video-vga.c
+++ b/arch/x86/boot/video-vga.c
@@ -129,41 +129,45 @@ u16 vga_crtc(void)
return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
}
-static void vga_set_480_scanlines(int end)
+static void vga_set_480_scanlines(int lines)
{
- u16 crtc;
- u8 csel;
+ u16 crtc; /* CRTC base address */
+ u8 csel; /* CRTC miscellaneous output register */
+ u8 ovfw; /* CRTC overflow register */
+ int end = lines-1;
crtc = vga_crtc();
+ ovfw = 0x3c | ((end >> (8-1)) & 0x02) | ((end >> (9-6)) & 0x40);
+
out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */
out_idx(0x0b, crtc, 0x06); /* Vertical total */
- out_idx(0x3e, crtc, 0x07); /* Vertical overflow */
+ out_idx(ovfw, crtc, 0x07); /* Vertical overflow */
out_idx(0xea, crtc, 0x10); /* Vertical sync start */
- out_idx(end, crtc, 0x12); /* Vertical display end */
+ out_idx(end, crtc, 0x12); /* Vertical display end */
out_idx(0xe7, crtc, 0x15); /* Vertical blank start */
out_idx(0x04, crtc, 0x16); /* Vertical blank end */
csel = inb(0x3cc);
csel &= 0x0d;
csel |= 0xe2;
- outb(csel, 0x3cc);
+ outb(csel, 0x3c2);
}
static void vga_set_80x30(void)
{
- vga_set_480_scanlines(0xdf);
+ vga_set_480_scanlines(30*16);
}
static void vga_set_80x34(void)
{
vga_set_14font();
- vga_set_480_scanlines(0xdb);
+ vga_set_480_scanlines(34*14);
}
static void vga_set_80x60(void)
{
vga_set_8font();
- vga_set_480_scanlines(0xdf);
+ vga_set_480_scanlines(60*8);
}
static int vga_set_mode(struct mode_info *mode)
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index 903de4aa5094..ebe7deedd5b4 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o
obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o
+obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o
obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o
@@ -19,3 +20,5 @@ salsa20-i586-y := salsa20-i586-asm_32.o salsa20_glue.o
aes-x86_64-y := aes-x86_64-asm_64.o aes_glue.o
twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o
salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o
+
+aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o
diff --git a/arch/x86/crypto/aes-i586-asm_32.S b/arch/x86/crypto/aes-i586-asm_32.S
index e41b147f4509..b949ec2f9af4 100644
--- a/arch/x86/crypto/aes-i586-asm_32.S
+++ b/arch/x86/crypto/aes-i586-asm_32.S
@@ -41,14 +41,14 @@
#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words)
/* offsets to parameters with one register pushed onto stack */
-#define tfm 8
+#define ctx 8
#define out_blk 12
#define in_blk 16
-/* offsets in crypto_tfm structure */
-#define klen (crypto_tfm_ctx_offset + 0)
-#define ekey (crypto_tfm_ctx_offset + 4)
-#define dkey (crypto_tfm_ctx_offset + 244)
+/* offsets in crypto_aes_ctx structure */
+#define klen (480)
+#define ekey (0)
+#define dkey (240)
// register mapping for encrypt and decrypt subroutines
@@ -217,7 +217,7 @@
do_col (table, r5,r0,r1,r4, r2,r3); /* idx=r5 */
// AES (Rijndael) Encryption Subroutine
-/* void aes_enc_blk(struct crypto_tfm *tfm, u8 *out_blk, const u8 *in_blk) */
+/* void aes_enc_blk(struct crypto_aes_ctx *ctx, u8 *out_blk, const u8 *in_blk) */
.global aes_enc_blk
@@ -228,7 +228,7 @@
aes_enc_blk:
push %ebp
- mov tfm(%esp),%ebp
+ mov ctx(%esp),%ebp
// CAUTION: the order and the values used in these assigns
// rely on the register mappings
@@ -292,7 +292,7 @@ aes_enc_blk:
ret
// AES (Rijndael) Decryption Subroutine
-/* void aes_dec_blk(struct crypto_tfm *tfm, u8 *out_blk, const u8 *in_blk) */
+/* void aes_dec_blk(struct crypto_aes_ctx *ctx, u8 *out_blk, const u8 *in_blk) */
.global aes_dec_blk
@@ -303,7 +303,7 @@ aes_enc_blk:
aes_dec_blk:
push %ebp
- mov tfm(%esp),%ebp
+ mov ctx(%esp),%ebp
// CAUTION: the order and the values used in these assigns
// rely on the register mappings
diff --git a/arch/x86/crypto/aes-x86_64-asm_64.S b/arch/x86/crypto/aes-x86_64-asm_64.S
index a120f526c3df..5b577d5a059b 100644
--- a/arch/x86/crypto/aes-x86_64-asm_64.S
+++ b/arch/x86/crypto/aes-x86_64-asm_64.S
@@ -17,8 +17,6 @@
#include <asm/asm-offsets.h>
-#define BASE crypto_tfm_ctx_offset
-
#define R1 %rax
#define R1E %eax
#define R1X %ax
@@ -56,13 +54,13 @@
.align 8; \
FUNC: movq r1,r2; \
movq r3,r4; \
- leaq BASE+KEY+48+4(r8),r9; \
+ leaq KEY+48(r8),r9; \
movq r10,r11; \
movl (r7),r5 ## E; \
movl 4(r7),r1 ## E; \
movl 8(r7),r6 ## E; \
movl 12(r7),r7 ## E; \
- movl BASE+0(r8),r10 ## E; \
+ movl 480(r8),r10 ## E; \
xorl -48(r9),r5 ## E; \
xorl -44(r9),r1 ## E; \
xorl -40(r9),r6 ## E; \
diff --git a/arch/x86/crypto/aes_glue.c b/arch/x86/crypto/aes_glue.c
index 71f457827116..49ae9fe32b22 100644
--- a/arch/x86/crypto/aes_glue.c
+++ b/arch/x86/crypto/aes_glue.c
@@ -5,17 +5,29 @@
#include <crypto/aes.h>
-asmlinkage void aes_enc_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
-asmlinkage void aes_dec_blk(struct crypto_tfm *tfm, u8 *out, const u8 *in);
+asmlinkage void aes_enc_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in);
+asmlinkage void aes_dec_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in);
+
+void crypto_aes_encrypt_x86(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src)
+{
+ aes_enc_blk(ctx, dst, src);
+}
+EXPORT_SYMBOL_GPL(crypto_aes_encrypt_x86);
+
+void crypto_aes_decrypt_x86(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src)
+{
+ aes_dec_blk(ctx, dst, src);
+}
+EXPORT_SYMBOL_GPL(crypto_aes_decrypt_x86);
static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
{
- aes_enc_blk(tfm, dst, src);
+ aes_enc_blk(crypto_tfm_ctx(tfm), dst, src);
}
static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
{
- aes_dec_blk(tfm, dst, src);
+ aes_dec_blk(crypto_tfm_ctx(tfm), dst, src);
}
static struct crypto_alg aes_alg = {
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
new file mode 100644
index 000000000000..caba99601703
--- /dev/null
+++ b/arch/x86/crypto/aesni-intel_asm.S
@@ -0,0 +1,896 @@
+/*
+ * Implement AES algorithm in Intel AES-NI instructions.
+ *
+ * The white paper of AES-NI instructions can be downloaded from:
+ * http://softwarecommunity.intel.com/isn/downloads/intelavx/AES-Instructions-Set_WP.pdf
+ *
+ * Copyright (C) 2008, Intel Corp.
+ * Author: Huang Ying <ying.huang@intel.com>
+ * Vinodh Gopal <vinodh.gopal@intel.com>
+ * Kahraman Akdemir
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/linkage.h>
+
+.text
+
+#define STATE1 %xmm0
+#define STATE2 %xmm4
+#define STATE3 %xmm5
+#define STATE4 %xmm6
+#define STATE STATE1
+#define IN1 %xmm1
+#define IN2 %xmm7
+#define IN3 %xmm8
+#define IN4 %xmm9
+#define IN IN1
+#define KEY %xmm2
+#define IV %xmm3
+
+#define KEYP %rdi
+#define OUTP %rsi
+#define INP %rdx
+#define LEN %rcx
+#define IVP %r8
+#define KLEN %r9d
+#define T1 %r10
+#define TKEYP T1
+#define T2 %r11
+
+_key_expansion_128:
+_key_expansion_256a:
+ pshufd $0b11111111, %xmm1, %xmm1
+ shufps $0b00010000, %xmm0, %xmm4
+ pxor %xmm4, %xmm0
+ shufps $0b10001100, %xmm0, %xmm4
+ pxor %xmm4, %xmm0
+ pxor %xmm1, %xmm0
+ movaps %xmm0, (%rcx)
+ add $0x10, %rcx
+ ret
+
+_key_expansion_192a:
+ pshufd $0b01010101, %xmm1, %xmm1
+ shufps $0b00010000, %xmm0, %xmm4
+ pxor %xmm4, %xmm0
+ shufps $0b10001100, %xmm0, %xmm4
+ pxor %xmm4, %xmm0
+ pxor %xmm1, %xmm0
+
+ movaps %xmm2, %xmm5
+ movaps %xmm2, %xmm6
+ pslldq $4, %xmm5
+ pshufd $0b11111111, %xmm0, %xmm3
+ pxor %xmm3, %xmm2
+ pxor %xmm5, %xmm2
+
+ movaps %xmm0, %xmm1
+ shufps $0b01000100, %xmm0, %xmm6
+ movaps %xmm6, (%rcx)
+ shufps $0b01001110, %xmm2, %xmm1
+ movaps %xmm1, 16(%rcx)
+ add $0x20, %rcx
+ ret
+
+_key_expansion_192b:
+ pshufd $0b01010101, %xmm1, %xmm1
+ shufps $0b00010000, %xmm0, %xmm4
+ pxor %xmm4, %xmm0
+ shufps $0b10001100, %xmm0, %xmm4
+ pxor %xmm4, %xmm0
+ pxor %xmm1, %xmm0
+
+ movaps %xmm2, %xmm5
+ pslldq $4, %xmm5
+ pshufd $0b11111111, %xmm0, %xmm3
+ pxor %xmm3, %xmm2
+ pxor %xmm5, %xmm2
+
+ movaps %xmm0, (%rcx)
+ add $0x10, %rcx
+ ret
+
+_key_expansion_256b:
+ pshufd $0b10101010, %xmm1, %xmm1
+ shufps $0b00010000, %xmm2, %xmm4
+ pxor %xmm4, %xmm2
+ shufps $0b10001100, %xmm2, %xmm4
+ pxor %xmm4, %xmm2
+ pxor %xmm1, %xmm2
+ movaps %xmm2, (%rcx)
+ add $0x10, %rcx
+ ret
+
+/*
+ * int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
+ * unsigned int key_len)
+ */
+ENTRY(aesni_set_key)
+ movups (%rsi), %xmm0 # user key (first 16 bytes)
+ movaps %xmm0, (%rdi)
+ lea 0x10(%rdi), %rcx # key addr
+ movl %edx, 480(%rdi)
+ pxor %xmm4, %xmm4 # xmm4 is assumed 0 in _key_expansion_x
+ cmp $24, %dl
+ jb .Lenc_key128
+ je .Lenc_key192
+ movups 0x10(%rsi), %xmm2 # other user key
+ movaps %xmm2, (%rcx)
+ add $0x10, %rcx
+ # aeskeygenassist $0x1, %xmm2, %xmm1 # round 1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x01
+ call _key_expansion_256a
+ # aeskeygenassist $0x1, %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x01
+ call _key_expansion_256b
+ # aeskeygenassist $0x2, %xmm2, %xmm1 # round 2
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x02
+ call _key_expansion_256a
+ # aeskeygenassist $0x2, %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x02
+ call _key_expansion_256b
+ # aeskeygenassist $0x4, %xmm2, %xmm1 # round 3
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x04
+ call _key_expansion_256a
+ # aeskeygenassist $0x4, %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x04
+ call _key_expansion_256b
+ # aeskeygenassist $0x8, %xmm2, %xmm1 # round 4
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x08
+ call _key_expansion_256a
+ # aeskeygenassist $0x8, %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x08
+ call _key_expansion_256b
+ # aeskeygenassist $0x10, %xmm2, %xmm1 # round 5
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x10
+ call _key_expansion_256a
+ # aeskeygenassist $0x10, %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x10
+ call _key_expansion_256b
+ # aeskeygenassist $0x20, %xmm2, %xmm1 # round 6
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x20
+ call _key_expansion_256a
+ # aeskeygenassist $0x20, %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x20
+ call _key_expansion_256b
+ # aeskeygenassist $0x40, %xmm2, %xmm1 # round 7
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x40
+ call _key_expansion_256a
+ jmp .Ldec_key
+.Lenc_key192:
+ movq 0x10(%rsi), %xmm2 # other user key
+ # aeskeygenassist $0x1, %xmm2, %xmm1 # round 1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x01
+ call _key_expansion_192a
+ # aeskeygenassist $0x2, %xmm2, %xmm1 # round 2
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x02
+ call _key_expansion_192b
+ # aeskeygenassist $0x4, %xmm2, %xmm1 # round 3
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x04
+ call _key_expansion_192a
+ # aeskeygenassist $0x8, %xmm2, %xmm1 # round 4
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x08
+ call _key_expansion_192b
+ # aeskeygenassist $0x10, %xmm2, %xmm1 # round 5
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x10
+ call _key_expansion_192a
+ # aeskeygenassist $0x20, %xmm2, %xmm1 # round 6
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x20
+ call _key_expansion_192b
+ # aeskeygenassist $0x40, %xmm2, %xmm1 # round 7
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x40
+ call _key_expansion_192a
+ # aeskeygenassist $0x80, %xmm2, %xmm1 # round 8
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xca, 0x80
+ call _key_expansion_192b
+ jmp .Ldec_key
+.Lenc_key128:
+ # aeskeygenassist $0x1, %xmm0, %xmm1 # round 1
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x01
+ call _key_expansion_128
+ # aeskeygenassist $0x2, %xmm0, %xmm1 # round 2
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x02
+ call _key_expansion_128
+ # aeskeygenassist $0x4, %xmm0, %xmm1 # round 3
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x04
+ call _key_expansion_128
+ # aeskeygenassist $0x8, %xmm0, %xmm1 # round 4
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x08
+ call _key_expansion_128
+ # aeskeygenassist $0x10, %xmm0, %xmm1 # round 5
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x10
+ call _key_expansion_128
+ # aeskeygenassist $0x20, %xmm0, %xmm1 # round 6
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x20
+ call _key_expansion_128
+ # aeskeygenassist $0x40, %xmm0, %xmm1 # round 7
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x40
+ call _key_expansion_128
+ # aeskeygenassist $0x80, %xmm0, %xmm1 # round 8
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x80
+ call _key_expansion_128
+ # aeskeygenassist $0x1b, %xmm0, %xmm1 # round 9
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x1b
+ call _key_expansion_128
+ # aeskeygenassist $0x36, %xmm0, %xmm1 # round 10
+ .byte 0x66, 0x0f, 0x3a, 0xdf, 0xc8, 0x36
+ call _key_expansion_128
+.Ldec_key:
+ sub $0x10, %rcx
+ movaps (%rdi), %xmm0
+ movaps (%rcx), %xmm1
+ movaps %xmm0, 240(%rcx)
+ movaps %xmm1, 240(%rdi)
+ add $0x10, %rdi
+ lea 240-16(%rcx), %rsi
+.align 4
+.Ldec_key_loop:
+ movaps (%rdi), %xmm0
+ # aesimc %xmm0, %xmm1
+ .byte 0x66, 0x0f, 0x38, 0xdb, 0xc8
+ movaps %xmm1, (%rsi)
+ add $0x10, %rdi
+ sub $0x10, %rsi
+ cmp %rcx, %rdi
+ jb .Ldec_key_loop
+ xor %rax, %rax
+ ret
+
+/*
+ * void aesni_enc(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src)
+ */
+ENTRY(aesni_enc)
+ movl 480(KEYP), KLEN # key length
+ movups (INP), STATE # input
+ call _aesni_enc1
+ movups STATE, (OUTP) # output
+ ret
+
+/*
+ * _aesni_enc1: internal ABI
+ * input:
+ * KEYP: key struct pointer
+ * KLEN: round count
+ * STATE: initial state (input)
+ * output:
+ * STATE: finial state (output)
+ * changed:
+ * KEY
+ * TKEYP (T1)
+ */
+_aesni_enc1:
+ movaps (KEYP), KEY # key
+ mov KEYP, TKEYP
+ pxor KEY, STATE # round 0
+ add $0x30, TKEYP
+ cmp $24, KLEN
+ jb .Lenc128
+ lea 0x20(TKEYP), TKEYP
+ je .Lenc192
+ add $0x20, TKEYP
+ movaps -0x60(TKEYP), KEY
+ # aesenc KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ movaps -0x50(TKEYP), KEY
+ # aesenc KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+.align 4
+.Lenc192:
+ movaps -0x40(TKEYP), KEY
+ # aesenc KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ movaps -0x30(TKEYP), KEY
+ # aesenc KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+.align 4
+.Lenc128:
+ movaps -0x20(TKEYP), KEY
+ # aesenc KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ movaps -0x10(TKEYP), KEY
+ # aesenc KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ movaps (TKEYP), KEY
+ # aesenc KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ movaps 0x10(TKEYP), KEY
+ # aesenc KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ movaps 0x20(TKEYP), KEY
+ # aesenc KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ movaps 0x30(TKEYP), KEY
+ # aesenc KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ movaps 0x40(TKEYP), KEY
+ # aesenc KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ movaps 0x50(TKEYP), KEY
+ # aesenc KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ movaps 0x60(TKEYP), KEY
+ # aesenc KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ movaps 0x70(TKEYP), KEY
+ # aesenclast KEY, STATE # last round
+ .byte 0x66, 0x0f, 0x38, 0xdd, 0xc2
+ ret
+
+/*
+ * _aesni_enc4: internal ABI
+ * input:
+ * KEYP: key struct pointer
+ * KLEN: round count
+ * STATE1: initial state (input)
+ * STATE2
+ * STATE3
+ * STATE4
+ * output:
+ * STATE1: finial state (output)
+ * STATE2
+ * STATE3
+ * STATE4
+ * changed:
+ * KEY
+ * TKEYP (T1)
+ */
+_aesni_enc4:
+ movaps (KEYP), KEY # key
+ mov KEYP, TKEYP
+ pxor KEY, STATE1 # round 0
+ pxor KEY, STATE2
+ pxor KEY, STATE3
+ pxor KEY, STATE4
+ add $0x30, TKEYP
+ cmp $24, KLEN
+ jb .L4enc128
+ lea 0x20(TKEYP), TKEYP
+ je .L4enc192
+ add $0x20, TKEYP
+ movaps -0x60(TKEYP), KEY
+ # aesenc KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ # aesenc KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
+ # aesenc KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xea
+ # aesenc KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+ movaps -0x50(TKEYP), KEY
+ # aesenc KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ # aesenc KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
+ # aesenc KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xea
+ # aesenc KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+#.align 4
+.L4enc192:
+ movaps -0x40(TKEYP), KEY
+ # aesenc KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ # aesenc KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
+ # aesenc KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xea
+ # aesenc KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+ movaps -0x30(TKEYP), KEY
+ # aesenc KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ # aesenc KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
+ # aesenc KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xea
+ # aesenc KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+#.align 4
+.L4enc128:
+ movaps -0x20(TKEYP), KEY
+ # aesenc KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ # aesenc KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
+ # aesenc KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xea
+ # aesenc KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+ movaps -0x10(TKEYP), KEY
+ # aesenc KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ # aesenc KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
+ # aesenc KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xea
+ # aesenc KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+ movaps (TKEYP), KEY
+ # aesenc KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ # aesenc KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
+ # aesenc KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xea
+ # aesenc KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+ movaps 0x10(TKEYP), KEY
+ # aesenc KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ # aesenc KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
+ # aesenc KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xea
+ # aesenc KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+ movaps 0x20(TKEYP), KEY
+ # aesenc KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ # aesenc KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
+ # aesenc KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xea
+ # aesenc KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+ movaps 0x30(TKEYP), KEY
+ # aesenc KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ # aesenc KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
+ # aesenc KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xea
+ # aesenc KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+ movaps 0x40(TKEYP), KEY
+ # aesenc KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ # aesenc KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
+ # aesenc KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xea
+ # aesenc KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+ movaps 0x50(TKEYP), KEY
+ # aesenc KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ # aesenc KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
+ # aesenc KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xea
+ # aesenc KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+ movaps 0x60(TKEYP), KEY
+ # aesenc KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xc2
+ # aesenc KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xe2
+ # aesenc KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xea
+ # aesenc KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdc, 0xf2
+ movaps 0x70(TKEYP), KEY
+ # aesenclast KEY, STATE1 # last round
+ .byte 0x66, 0x0f, 0x38, 0xdd, 0xc2
+ # aesenclast KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdd, 0xe2
+ # aesenclast KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdd, 0xea
+ # aesenclast KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdd, 0xf2
+ ret
+
+/*
+ * void aesni_dec (struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src)
+ */
+ENTRY(aesni_dec)
+ mov 480(KEYP), KLEN # key length
+ add $240, KEYP
+ movups (INP), STATE # input
+ call _aesni_dec1
+ movups STATE, (OUTP) #output
+ ret
+
+/*
+ * _aesni_dec1: internal ABI
+ * input:
+ * KEYP: key struct pointer
+ * KLEN: key length
+ * STATE: initial state (input)
+ * output:
+ * STATE: finial state (output)
+ * changed:
+ * KEY
+ * TKEYP (T1)
+ */
+_aesni_dec1:
+ movaps (KEYP), KEY # key
+ mov KEYP, TKEYP
+ pxor KEY, STATE # round 0
+ add $0x30, TKEYP
+ cmp $24, KLEN
+ jb .Ldec128
+ lea 0x20(TKEYP), TKEYP
+ je .Ldec192
+ add $0x20, TKEYP
+ movaps -0x60(TKEYP), KEY
+ # aesdec KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ movaps -0x50(TKEYP), KEY
+ # aesdec KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+.align 4
+.Ldec192:
+ movaps -0x40(TKEYP), KEY
+ # aesdec KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ movaps -0x30(TKEYP), KEY
+ # aesdec KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+.align 4
+.Ldec128:
+ movaps -0x20(TKEYP), KEY
+ # aesdec KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ movaps -0x10(TKEYP), KEY
+ # aesdec KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ movaps (TKEYP), KEY
+ # aesdec KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ movaps 0x10(TKEYP), KEY
+ # aesdec KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ movaps 0x20(TKEYP), KEY
+ # aesdec KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ movaps 0x30(TKEYP), KEY
+ # aesdec KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ movaps 0x40(TKEYP), KEY
+ # aesdec KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ movaps 0x50(TKEYP), KEY
+ # aesdec KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ movaps 0x60(TKEYP), KEY
+ # aesdec KEY, STATE
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ movaps 0x70(TKEYP), KEY
+ # aesdeclast KEY, STATE # last round
+ .byte 0x66, 0x0f, 0x38, 0xdf, 0xc2
+ ret
+
+/*
+ * _aesni_dec4: internal ABI
+ * input:
+ * KEYP: key struct pointer
+ * KLEN: key length
+ * STATE1: initial state (input)
+ * STATE2
+ * STATE3
+ * STATE4
+ * output:
+ * STATE1: finial state (output)
+ * STATE2
+ * STATE3
+ * STATE4
+ * changed:
+ * KEY
+ * TKEYP (T1)
+ */
+_aesni_dec4:
+ movaps (KEYP), KEY # key
+ mov KEYP, TKEYP
+ pxor KEY, STATE1 # round 0
+ pxor KEY, STATE2
+ pxor KEY, STATE3
+ pxor KEY, STATE4
+ add $0x30, TKEYP
+ cmp $24, KLEN
+ jb .L4dec128
+ lea 0x20(TKEYP), TKEYP
+ je .L4dec192
+ add $0x20, TKEYP
+ movaps -0x60(TKEYP), KEY
+ # aesdec KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ # aesdec KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xe2
+ # aesdec KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xea
+ # aesdec KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+ movaps -0x50(TKEYP), KEY
+ # aesdec KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ # aesdec KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xe2
+ # aesdec KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xea
+ # aesdec KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+.align 4
+.L4dec192:
+ movaps -0x40(TKEYP), KEY
+ # aesdec KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ # aesdec KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xe2
+ # aesdec KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xea
+ # aesdec KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+ movaps -0x30(TKEYP), KEY
+ # aesdec KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ # aesdec KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xe2
+ # aesdec KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xea
+ # aesdec KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+.align 4
+.L4dec128:
+ movaps -0x20(TKEYP), KEY
+ # aesdec KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ # aesdec KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xe2
+ # aesdec KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xea
+ # aesdec KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+ movaps -0x10(TKEYP), KEY
+ # aesdec KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ # aesdec KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xe2
+ # aesdec KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xea
+ # aesdec KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+ movaps (TKEYP), KEY
+ # aesdec KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ # aesdec KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xe2
+ # aesdec KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xea
+ # aesdec KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+ movaps 0x10(TKEYP), KEY
+ # aesdec KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ # aesdec KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xe2
+ # aesdec KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xea
+ # aesdec KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+ movaps 0x20(TKEYP), KEY
+ # aesdec KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ # aesdec KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xe2
+ # aesdec KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xea
+ # aesdec KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+ movaps 0x30(TKEYP), KEY
+ # aesdec KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ # aesdec KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xe2
+ # aesdec KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xea
+ # aesdec KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+ movaps 0x40(TKEYP), KEY
+ # aesdec KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ # aesdec KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xe2
+ # aesdec KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xea
+ # aesdec KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+ movaps 0x50(TKEYP), KEY
+ # aesdec KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ # aesdec KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xe2
+ # aesdec KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xea
+ # aesdec KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+ movaps 0x60(TKEYP), KEY
+ # aesdec KEY, STATE1
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xc2
+ # aesdec KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xe2
+ # aesdec KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xea
+ # aesdec KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xde, 0xf2
+ movaps 0x70(TKEYP), KEY
+ # aesdeclast KEY, STATE1 # last round
+ .byte 0x66, 0x0f, 0x38, 0xdf, 0xc2
+ # aesdeclast KEY, STATE2
+ .byte 0x66, 0x0f, 0x38, 0xdf, 0xe2
+ # aesdeclast KEY, STATE3
+ .byte 0x66, 0x0f, 0x38, 0xdf, 0xea
+ # aesdeclast KEY, STATE4
+ .byte 0x66, 0x0f, 0x38, 0xdf, 0xf2
+ ret
+
+/*
+ * void aesni_ecb_enc(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
+ * size_t len)
+ */
+ENTRY(aesni_ecb_enc)
+ test LEN, LEN # check length
+ jz .Lecb_enc_ret
+ mov 480(KEYP), KLEN
+ cmp $16, LEN
+ jb .Lecb_enc_ret
+ cmp $64, LEN
+ jb .Lecb_enc_loop1
+.align 4
+.Lecb_enc_loop4:
+ movups (INP), STATE1
+ movups 0x10(INP), STATE2
+ movups 0x20(INP), STATE3
+ movups 0x30(INP), STATE4
+ call _aesni_enc4
+ movups STATE1, (OUTP)
+ movups STATE2, 0x10(OUTP)
+ movups STATE3, 0x20(OUTP)
+ movups STATE4, 0x30(OUTP)
+ sub $64, LEN
+ add $64, INP
+ add $64, OUTP
+ cmp $64, LEN
+ jge .Lecb_enc_loop4
+ cmp $16, LEN
+ jb .Lecb_enc_ret
+.align 4
+.Lecb_enc_loop1:
+ movups (INP), STATE1
+ call _aesni_enc1
+ movups STATE1, (OUTP)
+ sub $16, LEN
+ add $16, INP
+ add $16, OUTP
+ cmp $16, LEN
+ jge .Lecb_enc_loop1
+.Lecb_enc_ret:
+ ret
+
+/*
+ * void aesni_ecb_dec(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
+ * size_t len);
+ */
+ENTRY(aesni_ecb_dec)
+ test LEN, LEN
+ jz .Lecb_dec_ret
+ mov 480(KEYP), KLEN
+ add $240, KEYP
+ cmp $16, LEN
+ jb .Lecb_dec_ret
+ cmp $64, LEN
+ jb .Lecb_dec_loop1
+.align 4
+.Lecb_dec_loop4:
+ movups (INP), STATE1
+ movups 0x10(INP), STATE2
+ movups 0x20(INP), STATE3
+ movups 0x30(INP), STATE4
+ call _aesni_dec4
+ movups STATE1, (OUTP)
+ movups STATE2, 0x10(OUTP)
+ movups STATE3, 0x20(OUTP)
+ movups STATE4, 0x30(OUTP)
+ sub $64, LEN
+ add $64, INP
+ add $64, OUTP
+ cmp $64, LEN
+ jge .Lecb_dec_loop4
+ cmp $16, LEN
+ jb .Lecb_dec_ret
+.align 4
+.Lecb_dec_loop1:
+ movups (INP), STATE1
+ call _aesni_dec1
+ movups STATE1, (OUTP)
+ sub $16, LEN
+ add $16, INP
+ add $16, OUTP
+ cmp $16, LEN
+ jge .Lecb_dec_loop1
+.Lecb_dec_ret:
+ ret
+
+/*
+ * void aesni_cbc_enc(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
+ * size_t len, u8 *iv)
+ */
+ENTRY(aesni_cbc_enc)
+ cmp $16, LEN
+ jb .Lcbc_enc_ret
+ mov 480(KEYP), KLEN
+ movups (IVP), STATE # load iv as initial state
+.align 4
+.Lcbc_enc_loop:
+ movups (INP), IN # load input
+ pxor IN, STATE
+ call _aesni_enc1
+ movups STATE, (OUTP) # store output
+ sub $16, LEN
+ add $16, INP
+ add $16, OUTP
+ cmp $16, LEN
+ jge .Lcbc_enc_loop
+ movups STATE, (IVP)
+.Lcbc_enc_ret:
+ ret
+
+/*
+ * void aesni_cbc_dec(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
+ * size_t len, u8 *iv)
+ */
+ENTRY(aesni_cbc_dec)
+ cmp $16, LEN
+ jb .Lcbc_dec_ret
+ mov 480(KEYP), KLEN
+ add $240, KEYP
+ movups (IVP), IV
+ cmp $64, LEN
+ jb .Lcbc_dec_loop1
+.align 4
+.Lcbc_dec_loop4:
+ movups (INP), IN1
+ movaps IN1, STATE1
+ movups 0x10(INP), IN2
+ movaps IN2, STATE2
+ movups 0x20(INP), IN3
+ movaps IN3, STATE3
+ movups 0x30(INP), IN4
+ movaps IN4, STATE4
+ call _aesni_dec4
+ pxor IV, STATE1
+ pxor IN1, STATE2
+ pxor IN2, STATE3
+ pxor IN3, STATE4
+ movaps IN4, IV
+ movups STATE1, (OUTP)
+ movups STATE2, 0x10(OUTP)
+ movups STATE3, 0x20(OUTP)
+ movups STATE4, 0x30(OUTP)
+ sub $64, LEN
+ add $64, INP
+ add $64, OUTP
+ cmp $64, LEN
+ jge .Lcbc_dec_loop4
+ cmp $16, LEN
+ jb .Lcbc_dec_ret
+.align 4
+.Lcbc_dec_loop1:
+ movups (INP), IN
+ movaps IN, STATE
+ call _aesni_dec1
+ pxor IV, STATE
+ movups STATE, (OUTP)
+ movaps IN, IV
+ sub $16, LEN
+ add $16, INP
+ add $16, OUTP
+ cmp $16, LEN
+ jge .Lcbc_dec_loop1
+ movups IV, (IVP)
+.Lcbc_dec_ret:
+ ret
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
new file mode 100644
index 000000000000..02af0af65497
--- /dev/null
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -0,0 +1,461 @@
+/*
+ * Support for Intel AES-NI instructions. This file contains glue
+ * code, the real AES implementation is in intel-aes_asm.S.
+ *
+ * Copyright (C) 2008, Intel Corp.
+ * Author: Huang Ying <ying.huang@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/hardirq.h>
+#include <linux/types.h>
+#include <linux/crypto.h>
+#include <linux/err.h>
+#include <crypto/algapi.h>
+#include <crypto/aes.h>
+#include <crypto/cryptd.h>
+#include <asm/i387.h>
+#include <asm/aes.h>
+
+struct async_aes_ctx {
+ struct cryptd_ablkcipher *cryptd_tfm;
+};
+
+#define AESNI_ALIGN 16
+#define AES_BLOCK_MASK (~(AES_BLOCK_SIZE-1))
+
+asmlinkage int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
+ unsigned int key_len);
+asmlinkage void aesni_enc(struct crypto_aes_ctx *ctx, u8 *out,
+ const u8 *in);
+asmlinkage void aesni_dec(struct crypto_aes_ctx *ctx, u8 *out,
+ const u8 *in);
+asmlinkage void aesni_ecb_enc(struct crypto_aes_ctx *ctx, u8 *out,
+ const u8 *in, unsigned int len);
+asmlinkage void aesni_ecb_dec(struct crypto_aes_ctx *ctx, u8 *out,
+ const u8 *in, unsigned int len);
+asmlinkage void aesni_cbc_enc(struct crypto_aes_ctx *ctx, u8 *out,
+ const u8 *in, unsigned int len, u8 *iv);
+asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out,
+ const u8 *in, unsigned int len, u8 *iv);
+
+static inline int kernel_fpu_using(void)
+{
+ if (in_interrupt() && !(read_cr0() & X86_CR0_TS))
+ return 1;
+ return 0;
+}
+
+static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx)
+{
+ unsigned long addr = (unsigned long)raw_ctx;
+ unsigned long align = AESNI_ALIGN;
+
+ if (align <= crypto_tfm_ctx_alignment())
+ align = 1;
+ return (struct crypto_aes_ctx *)ALIGN(addr, align);
+}
+
+static int aes_set_key_common(struct crypto_tfm *tfm, void *raw_ctx,
+ const u8 *in_key, unsigned int key_len)
+{
+ struct crypto_aes_ctx *ctx = aes_ctx(raw_ctx);
+ u32 *flags = &tfm->crt_flags;
+ int err;
+
+ if (key_len != AES_KEYSIZE_128 && key_len != AES_KEYSIZE_192 &&
+ key_len != AES_KEYSIZE_256) {
+ *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+ return -EINVAL;
+ }
+
+ if (kernel_fpu_using())
+ err = crypto_aes_expand_key(ctx, in_key, key_len);
+ else {
+ kernel_fpu_begin();
+ err = aesni_set_key(ctx, in_key, key_len);
+ kernel_fpu_end();
+ }
+
+ return err;
+}
+
+static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+ unsigned int key_len)
+{
+ return aes_set_key_common(tfm, crypto_tfm_ctx(tfm), in_key, key_len);
+}
+
+static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
+
+ if (kernel_fpu_using())
+ crypto_aes_encrypt_x86(ctx, dst, src);
+ else {
+ kernel_fpu_begin();
+ aesni_enc(ctx, dst, src);
+ kernel_fpu_end();
+ }
+}
+
+static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+{
+ struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
+
+ if (kernel_fpu_using())
+ crypto_aes_decrypt_x86(ctx, dst, src);
+ else {
+ kernel_fpu_begin();
+ aesni_dec(ctx, dst, src);
+ kernel_fpu_end();
+ }
+}
+
+static struct crypto_alg aesni_alg = {
+ .cra_name = "aes",
+ .cra_driver_name = "aes-aesni",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx)+AESNI_ALIGN-1,
+ .cra_alignmask = 0,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(aesni_alg.cra_list),
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = AES_MIN_KEY_SIZE,
+ .cia_max_keysize = AES_MAX_KEY_SIZE,
+ .cia_setkey = aes_set_key,
+ .cia_encrypt = aes_encrypt,
+ .cia_decrypt = aes_decrypt
+ }
+ }
+};
+
+static int ecb_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct crypto_aes_ctx *ctx = aes_ctx(crypto_blkcipher_ctx(desc->tfm));
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ kernel_fpu_begin();
+ while ((nbytes = walk.nbytes)) {
+ aesni_ecb_enc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ nbytes & AES_BLOCK_MASK);
+ nbytes &= AES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+ kernel_fpu_end();
+
+ return err;
+}
+
+static int ecb_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct crypto_aes_ctx *ctx = aes_ctx(crypto_blkcipher_ctx(desc->tfm));
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ kernel_fpu_begin();
+ while ((nbytes = walk.nbytes)) {
+ aesni_ecb_dec(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ nbytes & AES_BLOCK_MASK);
+ nbytes &= AES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+ kernel_fpu_end();
+
+ return err;
+}
+
+static struct crypto_alg blk_ecb_alg = {
+ .cra_name = "__ecb-aes-aesni",
+ .cra_driver_name = "__driver-ecb-aes-aesni",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx)+AESNI_ALIGN-1,
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(blk_ecb_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .setkey = aes_set_key,
+ .encrypt = ecb_encrypt,
+ .decrypt = ecb_decrypt,
+ },
+ },
+};
+
+static int cbc_encrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct crypto_aes_ctx *ctx = aes_ctx(crypto_blkcipher_ctx(desc->tfm));
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ kernel_fpu_begin();
+ while ((nbytes = walk.nbytes)) {
+ aesni_cbc_enc(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ nbytes & AES_BLOCK_MASK, walk.iv);
+ nbytes &= AES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+ kernel_fpu_end();
+
+ return err;
+}
+
+static int cbc_decrypt(struct blkcipher_desc *desc,
+ struct scatterlist *dst, struct scatterlist *src,
+ unsigned int nbytes)
+{
+ struct crypto_aes_ctx *ctx = aes_ctx(crypto_blkcipher_ctx(desc->tfm));
+ struct blkcipher_walk walk;
+ int err;
+
+ blkcipher_walk_init(&walk, dst, src, nbytes);
+ err = blkcipher_walk_virt(desc, &walk);
+
+ kernel_fpu_begin();
+ while ((nbytes = walk.nbytes)) {
+ aesni_cbc_dec(ctx, walk.dst.virt.addr, walk.src.virt.addr,
+ nbytes & AES_BLOCK_MASK, walk.iv);
+ nbytes &= AES_BLOCK_SIZE - 1;
+ err = blkcipher_walk_done(desc, &walk, nbytes);
+ }
+ kernel_fpu_end();
+
+ return err;
+}
+
+static struct crypto_alg blk_cbc_alg = {
+ .cra_name = "__cbc-aes-aesni",
+ .cra_driver_name = "__driver-cbc-aes-aesni",
+ .cra_priority = 0,
+ .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto_aes_ctx)+AESNI_ALIGN-1,
+ .cra_alignmask = 0,
+ .cra_type = &crypto_blkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(blk_cbc_alg.cra_list),
+ .cra_u = {
+ .blkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .setkey = aes_set_key,
+ .encrypt = cbc_encrypt,
+ .decrypt = cbc_decrypt,
+ },
+ },
+};
+
+static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key,
+ unsigned int key_len)
+{
+ struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+
+ return crypto_ablkcipher_setkey(&ctx->cryptd_tfm->base, key, key_len);
+}
+
+static int ablk_encrypt(struct ablkcipher_request *req)
+{
+ struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
+ struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+
+ if (kernel_fpu_using()) {
+ struct ablkcipher_request *cryptd_req =
+ ablkcipher_request_ctx(req);
+ memcpy(cryptd_req, req, sizeof(*req));
+ ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
+ return crypto_ablkcipher_encrypt(cryptd_req);
+ } else {
+ struct blkcipher_desc desc;
+ desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm);
+ desc.info = req->info;
+ desc.flags = 0;
+ return crypto_blkcipher_crt(desc.tfm)->encrypt(
+ &desc, req->dst, req->src, req->nbytes);
+ }
+}
+
+static int ablk_decrypt(struct ablkcipher_request *req)
+{
+ struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
+ struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+
+ if (kernel_fpu_using()) {
+ struct ablkcipher_request *cryptd_req =
+ ablkcipher_request_ctx(req);
+ memcpy(cryptd_req, req, sizeof(*req));
+ ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
+ return crypto_ablkcipher_decrypt(cryptd_req);
+ } else {
+ struct blkcipher_desc desc;
+ desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm);
+ desc.info = req->info;
+ desc.flags = 0;
+ return crypto_blkcipher_crt(desc.tfm)->decrypt(
+ &desc, req->dst, req->src, req->nbytes);
+ }
+}
+
+static void ablk_exit(struct crypto_tfm *tfm)
+{
+ struct async_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ cryptd_free_ablkcipher(ctx->cryptd_tfm);
+}
+
+static void ablk_init_common(struct crypto_tfm *tfm,
+ struct cryptd_ablkcipher *cryptd_tfm)
+{
+ struct async_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ ctx->cryptd_tfm = cryptd_tfm;
+ tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) +
+ crypto_ablkcipher_reqsize(&cryptd_tfm->base);
+}
+
+static int ablk_ecb_init(struct crypto_tfm *tfm)
+{
+ struct cryptd_ablkcipher *cryptd_tfm;
+
+ cryptd_tfm = cryptd_alloc_ablkcipher("__driver-ecb-aes-aesni", 0, 0);
+ if (IS_ERR(cryptd_tfm))
+ return PTR_ERR(cryptd_tfm);
+ ablk_init_common(tfm, cryptd_tfm);
+ return 0;
+}
+
+static struct crypto_alg ablk_ecb_alg = {
+ .cra_name = "ecb(aes)",
+ .cra_driver_name = "ecb-aes-aesni",
+ .cra_priority = 400,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_aes_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ablk_ecb_alg.cra_list),
+ .cra_init = ablk_ecb_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+};
+
+static int ablk_cbc_init(struct crypto_tfm *tfm)
+{
+ struct cryptd_ablkcipher *cryptd_tfm;
+
+ cryptd_tfm = cryptd_alloc_ablkcipher("__driver-cbc-aes-aesni", 0, 0);
+ if (IS_ERR(cryptd_tfm))
+ return PTR_ERR(cryptd_tfm);
+ ablk_init_common(tfm, cryptd_tfm);
+ return 0;
+}
+
+static struct crypto_alg ablk_cbc_alg = {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "cbc-aes-aesni",
+ .cra_priority = 400,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER|CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct async_aes_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_list = LIST_HEAD_INIT(ablk_cbc_alg.cra_list),
+ .cra_init = ablk_cbc_init,
+ .cra_exit = ablk_exit,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = ablk_set_key,
+ .encrypt = ablk_encrypt,
+ .decrypt = ablk_decrypt,
+ },
+ },
+};
+
+static int __init aesni_init(void)
+{
+ int err;
+
+ if (!cpu_has_aes) {
+ printk(KERN_ERR "Intel AES-NI instructions are not detected.\n");
+ return -ENODEV;
+ }
+ if ((err = crypto_register_alg(&aesni_alg)))
+ goto aes_err;
+ if ((err = crypto_register_alg(&blk_ecb_alg)))
+ goto blk_ecb_err;
+ if ((err = crypto_register_alg(&blk_cbc_alg)))
+ goto blk_cbc_err;
+ if ((err = crypto_register_alg(&ablk_ecb_alg)))
+ goto ablk_ecb_err;
+ if ((err = crypto_register_alg(&ablk_cbc_alg)))
+ goto ablk_cbc_err;
+
+ return err;
+
+ablk_cbc_err:
+ crypto_unregister_alg(&ablk_ecb_alg);
+ablk_ecb_err:
+ crypto_unregister_alg(&blk_cbc_alg);
+blk_cbc_err:
+ crypto_unregister_alg(&blk_ecb_alg);
+blk_ecb_err:
+ crypto_unregister_alg(&aesni_alg);
+aes_err:
+ return err;
+}
+
+static void __exit aesni_exit(void)
+{
+ crypto_unregister_alg(&ablk_cbc_alg);
+ crypto_unregister_alg(&ablk_ecb_alg);
+ crypto_unregister_alg(&blk_cbc_alg);
+ crypto_unregister_alg(&blk_ecb_alg);
+ crypto_unregister_alg(&aesni_alg);
+}
+
+module_init(aesni_init);
+module_exit(aesni_exit);
+
+MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm, Intel AES-NI instructions optimized");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("aes");
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 097a6b64c24d..a505202086e8 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -557,7 +557,7 @@ ia32_sys_call_table:
.quad sys32_olduname
.quad sys_umask /* 60 */
.quad sys_chroot
- .quad sys32_ustat
+ .quad compat_sys_ustat
.quad sys_dup2
.quad sys_getppid
.quad sys_getpgrp /* 65 */
@@ -828,4 +828,6 @@ ia32_sys_call_table:
.quad sys_dup3 /* 330 */
.quad sys_pipe2
.quad sys_inotify_init1
+ .quad compat_sys_preadv
+ .quad compat_sys_pwritev
ia32_syscall_end:
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index 6c0d7f6231af..efac92fd1efb 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -638,28 +638,6 @@ long sys32_uname(struct old_utsname __user *name)
return err ? -EFAULT : 0;
}
-long sys32_ustat(unsigned dev, struct ustat32 __user *u32p)
-{
- struct ustat u;
- mm_segment_t seg;
- int ret;
-
- seg = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ustat(dev, (struct ustat __user *)&u);
- set_fs(seg);
- if (ret < 0)
- return ret;
-
- if (!access_ok(VERIFY_WRITE, u32p, sizeof(struct ustat32)) ||
- __put_user((__u32) u.f_tfree, &u32p->f_tfree) ||
- __put_user((__u32) u.f_tinode, &u32p->f_tfree) ||
- __copy_to_user(&u32p->f_fname, u.f_fname, sizeof(u.f_fname)) ||
- __copy_to_user(&u32p->f_fpack, u.f_fpack, sizeof(u.f_fpack)))
- ret = -EFAULT;
- return ret;
-}
-
asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv,
compat_uptr_t __user *envp, struct pt_regs *regs)
{
diff --git a/arch/x86/include/asm/aes.h b/arch/x86/include/asm/aes.h
new file mode 100644
index 000000000000..80545a1cbe39
--- /dev/null
+++ b/arch/x86/include/asm/aes.h
@@ -0,0 +1,11 @@
+#ifndef ASM_X86_AES_H
+#define ASM_X86_AES_H
+
+#include <linux/crypto.h>
+#include <crypto/aes.h>
+
+void crypto_aes_encrypt_x86(struct crypto_aes_ctx *ctx, u8 *dst,
+ const u8 *src);
+void crypto_aes_decrypt_x86(struct crypto_aes_ctx *ctx, u8 *dst,
+ const u8 *src);
+#endif
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 394d177d721b..42f2f8377422 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -75,7 +75,7 @@ static inline void default_inquire_remote_apic(int apicid)
#define setup_secondary_clock setup_secondary_APIC_clock
#endif
-#ifdef CONFIG_X86_VSMP
+#ifdef CONFIG_X86_64
extern int is_vsmp_box(void);
#else
static inline int is_vsmp_box(void)
@@ -107,7 +107,20 @@ extern u32 native_safe_apic_wait_icr_idle(void);
extern void native_apic_icr_write(u32 low, u32 id);
extern u64 native_apic_icr_read(void);
+#define EIM_8BIT_APIC_ID 0
+#define EIM_32BIT_APIC_ID 1
+
#ifdef CONFIG_X86_X2APIC
+/*
+ * Make previous memory operations globally visible before
+ * sending the IPI through x2apic wrmsr. We need a serializing instruction or
+ * mfence for this.
+ */
+static inline void x2apic_wrmsr_fence(void)
+{
+ asm volatile("mfence" : : : "memory");
+}
+
static inline void native_apic_msr_write(u32 reg, u32 v)
{
if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR ||
@@ -184,6 +197,9 @@ static inline int x2apic_enabled(void)
{
return 0;
}
+
+#define x2apic 0
+
#endif
extern int get_physical_broadcast(void);
@@ -476,10 +492,19 @@ static inline int default_apic_id_registered(void)
return physid_isset(read_apic_id(), phys_cpu_present_map);
}
+static inline int default_phys_pkg_id(int cpuid_apic, int index_msb)
+{
+ return cpuid_apic >> index_msb;
+}
+
+extern int default_apicid_to_node(int logical_apicid);
+
+#endif
+
static inline unsigned int
default_cpu_mask_to_apicid(const struct cpumask *cpumask)
{
- return cpumask_bits(cpumask)[0];
+ return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS;
}
static inline unsigned int
@@ -493,15 +518,6 @@ default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
return (unsigned int)(mask1 & mask2 & mask3);
}
-static inline int default_phys_pkg_id(int cpuid_apic, int index_msb)
-{
- return cpuid_apic >> index_msb;
-}
-
-extern int default_apicid_to_node(int logical_apicid);
-
-#endif
-
static inline unsigned long default_check_apicid_used(physid_mask_t bitmap, int apicid)
{
return physid_isset(apicid, bitmap);
diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h
index eb2221d5add2..e55dfc1ad453 100644
--- a/arch/x86/include/asm/cacheflush.h
+++ b/arch/x86/include/asm/cacheflush.h
@@ -90,6 +90,9 @@ int set_memory_4k(unsigned long addr, int numpages);
int set_memory_array_uc(unsigned long *addr, int addrinarray);
int set_memory_array_wb(unsigned long *addr, int addrinarray);
+int set_pages_array_uc(struct page **pages, int addrinarray);
+int set_pages_array_wb(struct page **pages, int addrinarray);
+
/*
* For legacy compatibility with the old APIs, a few functions
* are provided that work on a "struct page".
diff --git a/arch/x86/include/asm/cpu_debug.h b/arch/x86/include/asm/cpu_debug.h
index d24d64fcee04..222802029fa6 100755
--- a/arch/x86/include/asm/cpu_debug.h
+++ b/arch/x86/include/asm/cpu_debug.h
@@ -33,6 +33,8 @@ enum cpu_debug_bit {
CPU_VMX_BIT, /* VMX */
CPU_CALL_BIT, /* System Call */
CPU_BASE_BIT, /* BASE Address */
+ CPU_VER_BIT, /* Version ID */
+ CPU_CONF_BIT, /* Configuration */
CPU_SMM_BIT, /* System mgmt mode */
CPU_SVM_BIT, /*Secure Virtual Machine*/
CPU_OSVM_BIT, /* OS-Visible Workaround*/
@@ -69,6 +71,8 @@ enum cpu_debug_bit {
#define CPU_VMX (1 << CPU_VMX_BIT)
#define CPU_CALL (1 << CPU_CALL_BIT)
#define CPU_BASE (1 << CPU_BASE_BIT)
+#define CPU_VER (1 << CPU_VER_BIT)
+#define CPU_CONF (1 << CPU_CONF_BIT)
#define CPU_SMM (1 << CPU_SMM_BIT)
#define CPU_SVM (1 << CPU_SVM_BIT)
#define CPU_OSVM (1 << CPU_OSVM_BIT)
@@ -123,10 +127,15 @@ enum cpu_processor_bit {
CPU_INTEL_ATOM_BIT,
CPU_INTEL_XEON_P4_BIT,
CPU_INTEL_XEON_MP_BIT,
+/* AMD */
+ CPU_AMD_K6_BIT,
+ CPU_AMD_K7_BIT,
+ CPU_AMD_K8_BIT,
+ CPU_AMD_0F_BIT,
+ CPU_AMD_10_BIT,
+ CPU_AMD_11_BIT,
};
-#define CPU_ALL (~0) /* Select all CPUs */
-
#define CPU_INTEL_PENTIUM (1 << CPU_INTEL_PENTIUM_BIT)
#define CPU_INTEL_P6 (1 << CPU_INTEL_P6_BIT)
#define CPU_INTEL_PENTIUM_M (1 << CPU_INTEL_PENTIUM_M_BIT)
@@ -156,9 +165,27 @@ enum cpu_processor_bit {
#define CPU_PX_CX_AT (CPU_INTEL_PX | CPU_CX_AT)
#define CPU_PX_CX_AT_XE (CPU_INTEL_PX | CPU_CX_AT_XE)
-/* Select all Intel CPUs*/
+/* Select all supported Intel CPUs */
#define CPU_INTEL_ALL (CPU_INTEL_PENTIUM | CPU_PX_CX_AT_XE)
+#define CPU_AMD_K6 (1 << CPU_AMD_K6_BIT)
+#define CPU_AMD_K7 (1 << CPU_AMD_K7_BIT)
+#define CPU_AMD_K8 (1 << CPU_AMD_K8_BIT)
+#define CPU_AMD_0F (1 << CPU_AMD_0F_BIT)
+#define CPU_AMD_10 (1 << CPU_AMD_10_BIT)
+#define CPU_AMD_11 (1 << CPU_AMD_11_BIT)
+
+#define CPU_K10_PLUS (CPU_AMD_10 | CPU_AMD_11)
+#define CPU_K0F_PLUS (CPU_AMD_0F | CPU_K10_PLUS)
+#define CPU_K8_PLUS (CPU_AMD_K8 | CPU_K0F_PLUS)
+#define CPU_K7_PLUS (CPU_AMD_K7 | CPU_K8_PLUS)
+
+/* Select all supported AMD CPUs */
+#define CPU_AMD_ALL (CPU_AMD_K6 | CPU_K7_PLUS)
+
+/* Select all supported CPUs */
+#define CPU_ALL (CPU_INTEL_ALL | CPU_AMD_ALL)
+
#define MAX_CPU_FILES 512
struct cpu_private {
@@ -171,16 +198,22 @@ struct cpu_private {
struct cpu_debug_base {
char *name; /* Register name */
unsigned flag; /* Register flag */
+ unsigned write; /* Register write flag */
};
-struct cpu_cpuX_base {
- struct dentry *dentry; /* Register dentry */
- int init; /* Register index file */
-};
-
+/*
+ * Currently it looks similar to cpu_debug_base but once we add more files
+ * cpu_file_base will go in different direction
+ */
struct cpu_file_base {
char *name; /* Register file name */
unsigned flag; /* Register file flag */
+ unsigned write; /* Register write flag */
+};
+
+struct cpu_cpuX_base {
+ struct dentry *dentry; /* Register dentry */
+ int init; /* Register index file */
};
struct cpu_debug_range {
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 7301e60dc4a8..0beba0d1468d 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -213,6 +213,7 @@ extern const char * const x86_power_flags[32];
#define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM)
#define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2)
#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3)
+#define cpu_has_aes boot_cpu_has(X86_FEATURE_AES)
#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT)
#define cpu_has_mp boot_cpu_has(X86_FEATURE_MP)
#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX)
diff --git a/arch/x86/include/asm/cpumask.h b/arch/x86/include/asm/cpumask.h
index a7f3c75f8ad7..61c852fa346b 100644
--- a/arch/x86/include/asm/cpumask.h
+++ b/arch/x86/include/asm/cpumask.h
@@ -3,8 +3,6 @@
#ifndef __ASSEMBLY__
#include <linux/cpumask.h>
-#ifdef CONFIG_X86_64
-
extern cpumask_var_t cpu_callin_mask;
extern cpumask_var_t cpu_callout_mask;
extern cpumask_var_t cpu_initialized_mask;
@@ -12,21 +10,5 @@ extern cpumask_var_t cpu_sibling_setup_mask;
extern void setup_cpu_local_masks(void);
-#else /* CONFIG_X86_32 */
-
-extern cpumask_t cpu_callin_map;
-extern cpumask_t cpu_callout_map;
-extern cpumask_t cpu_initialized;
-extern cpumask_t cpu_sibling_setup_map;
-
-#define cpu_callin_mask ((struct cpumask *)&cpu_callin_map)
-#define cpu_callout_mask ((struct cpumask *)&cpu_callout_map)
-#define cpu_initialized_mask ((struct cpumask *)&cpu_initialized)
-#define cpu_sibling_setup_mask ((struct cpumask *)&cpu_sibling_setup_map)
-
-static inline void setup_cpu_local_masks(void) { }
-
-#endif /* CONFIG_X86_32 */
-
#endif /* __ASSEMBLY__ */
#endif /* _ASM_X86_CPUMASK_H */
diff --git a/arch/x86/include/asm/device.h b/arch/x86/include/asm/device.h
index 3c034f48fdb0..4994a20acbcb 100644
--- a/arch/x86/include/asm/device.h
+++ b/arch/x86/include/asm/device.h
@@ -6,7 +6,7 @@ struct dev_archdata {
void *acpi_handle;
#endif
#ifdef CONFIG_X86_64
-struct dma_mapping_ops *dma_ops;
+struct dma_map_ops *dma_ops;
#endif
#ifdef CONFIG_DMAR
void *iommu; /* hook for IOMMU specific extension */
diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h
index 132a134d12f2..cea7b74963e9 100644
--- a/arch/x86/include/asm/dma-mapping.h
+++ b/arch/x86/include/asm/dma-mapping.h
@@ -7,6 +7,8 @@
*/
#include <linux/scatterlist.h>
+#include <linux/dma-debug.h>
+#include <linux/dma-attrs.h>
#include <asm/io.h>
#include <asm/swiotlb.h>
#include <asm-generic/dma-coherent.h>
@@ -16,47 +18,9 @@ extern int iommu_merge;
extern struct device x86_dma_fallback_dev;
extern int panic_on_overflow;
-struct dma_mapping_ops {
- int (*mapping_error)(struct device *dev,
- dma_addr_t dma_addr);
- void* (*alloc_coherent)(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp);
- void (*free_coherent)(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
- dma_addr_t (*map_single)(struct device *hwdev, phys_addr_t ptr,
- size_t size, int direction);
- void (*unmap_single)(struct device *dev, dma_addr_t addr,
- size_t size, int direction);
- void (*sync_single_for_cpu)(struct device *hwdev,
- dma_addr_t dma_handle, size_t size,
- int direction);
- void (*sync_single_for_device)(struct device *hwdev,
- dma_addr_t dma_handle, size_t size,
- int direction);
- void (*sync_single_range_for_cpu)(struct device *hwdev,
- dma_addr_t dma_handle, unsigned long offset,
- size_t size, int direction);
- void (*sync_single_range_for_device)(struct device *hwdev,
- dma_addr_t dma_handle, unsigned long offset,
- size_t size, int direction);
- void (*sync_sg_for_cpu)(struct device *hwdev,
- struct scatterlist *sg, int nelems,
- int direction);
- void (*sync_sg_for_device)(struct device *hwdev,
- struct scatterlist *sg, int nelems,
- int direction);
- int (*map_sg)(struct device *hwdev, struct scatterlist *sg,
- int nents, int direction);
- void (*unmap_sg)(struct device *hwdev,
- struct scatterlist *sg, int nents,
- int direction);
- int (*dma_supported)(struct device *hwdev, u64 mask);
- int is_phys;
-};
-
-extern struct dma_mapping_ops *dma_ops;
-
-static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
+extern struct dma_map_ops *dma_ops;
+
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
#ifdef CONFIG_X86_32
return dma_ops;
@@ -71,7 +35,7 @@ static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
/* Make sure we keep the same behaviour */
static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
- struct dma_mapping_ops *ops = get_dma_ops(dev);
+ struct dma_map_ops *ops = get_dma_ops(dev);
if (ops->mapping_error)
return ops->mapping_error(dev, dma_addr);
@@ -90,137 +54,167 @@ extern void *dma_generic_alloc_coherent(struct device *dev, size_t size,
static inline dma_addr_t
dma_map_single(struct device *hwdev, void *ptr, size_t size,
- int direction)
+ enum dma_data_direction dir)
{
- struct dma_mapping_ops *ops = get_dma_ops(hwdev);
-
- BUG_ON(!valid_dma_direction(direction));
- return ops->map_single(hwdev, virt_to_phys(ptr), size, direction);
+ struct dma_map_ops *ops = get_dma_ops(hwdev);
+ dma_addr_t addr;
+
+ BUG_ON(!valid_dma_direction(dir));
+ addr = ops->map_page(hwdev, virt_to_page(ptr),
+ (unsigned long)ptr & ~PAGE_MASK, size,
+ dir, NULL);
+ debug_dma_map_page(hwdev, virt_to_page(ptr),
+ (unsigned long)ptr & ~PAGE_MASK, size,
+ dir, addr, true);
+ return addr;
}
static inline void
dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size,
- int direction)
+ enum dma_data_direction dir)
{
- struct dma_mapping_ops *ops = get_dma_ops(dev);
+ struct dma_map_ops *ops = get_dma_ops(dev);
- BUG_ON(!valid_dma_direction(direction));
- if (ops->unmap_single)
- ops->unmap_single(dev, addr, size, direction);
+ BUG_ON(!valid_dma_direction(dir));
+ if (ops->unmap_page)
+ ops->unmap_page(dev, addr, size, dir, NULL);
+ debug_dma_unmap_page(dev, addr, size, dir, true);
}
static inline int
dma_map_sg(struct device *hwdev, struct scatterlist *sg,
- int nents, int direction)
+ int nents, enum dma_data_direction dir)
{
- struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+ struct dma_map_ops *ops = get_dma_ops(hwdev);
+ int ents;
+
+ BUG_ON(!valid_dma_direction(dir));
+ ents = ops->map_sg(hwdev, sg, nents, dir, NULL);
+ debug_dma_map_sg(hwdev, sg, nents, ents, dir);
- BUG_ON(!valid_dma_direction(direction));
- return ops->map_sg(hwdev, sg, nents, direction);
+ return ents;
}
static inline void
dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
- int direction)
+ enum dma_data_direction dir)
{
- struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+ struct dma_map_ops *ops = get_dma_ops(hwdev);
- BUG_ON(!valid_dma_direction(direction));
+ BUG_ON(!valid_dma_direction(dir));
+ debug_dma_unmap_sg(hwdev, sg, nents, dir);
if (ops->unmap_sg)
- ops->unmap_sg(hwdev, sg, nents, direction);
+ ops->unmap_sg(hwdev, sg, nents, dir, NULL);
}
static inline void
dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
- size_t size, int direction)
+ size_t size, enum dma_data_direction dir)
{
- struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+ struct dma_map_ops *ops = get_dma_ops(hwdev);
- BUG_ON(!valid_dma_direction(direction));
+ BUG_ON(!valid_dma_direction(dir));
if (ops->sync_single_for_cpu)
- ops->sync_single_for_cpu(hwdev, dma_handle, size, direction);
+ ops->sync_single_for_cpu(hwdev, dma_handle, size, dir);
+ debug_dma_sync_single_for_cpu(hwdev, dma_handle, size, dir);
flush_write_buffers();
}
static inline void
dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle,
- size_t size, int direction)
+ size_t size, enum dma_data_direction dir)
{
- struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+ struct dma_map_ops *ops = get_dma_ops(hwdev);
- BUG_ON(!valid_dma_direction(direction));
+ BUG_ON(!valid_dma_direction(dir));
if (ops->sync_single_for_device)
- ops->sync_single_for_device(hwdev, dma_handle, size, direction);
+ ops->sync_single_for_device(hwdev, dma_handle, size, dir);
+ debug_dma_sync_single_for_device(hwdev, dma_handle, size, dir);
flush_write_buffers();
}
static inline void
dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
- unsigned long offset, size_t size, int direction)
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir)
{
- struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+ struct dma_map_ops *ops = get_dma_ops(hwdev);
- BUG_ON(!valid_dma_direction(direction));
+ BUG_ON(!valid_dma_direction(dir));
if (ops->sync_single_range_for_cpu)
ops->sync_single_range_for_cpu(hwdev, dma_handle, offset,
- size, direction);
+ size, dir);
+ debug_dma_sync_single_range_for_cpu(hwdev, dma_handle,
+ offset, size, dir);
flush_write_buffers();
}
static inline void
dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle,
unsigned long offset, size_t size,
- int direction)
+ enum dma_data_direction dir)
{
- struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+ struct dma_map_ops *ops = get_dma_ops(hwdev);
- BUG_ON(!valid_dma_direction(direction));
+ BUG_ON(!valid_dma_direction(dir));
if (ops->sync_single_range_for_device)
ops->sync_single_range_for_device(hwdev, dma_handle,
- offset, size, direction);
+ offset, size, dir);
+ debug_dma_sync_single_range_for_device(hwdev, dma_handle,
+ offset, size, dir);
flush_write_buffers();
}
static inline void
dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
- int nelems, int direction)
+ int nelems, enum dma_data_direction dir)
{
- struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+ struct dma_map_ops *ops = get_dma_ops(hwdev);
- BUG_ON(!valid_dma_direction(direction));
+ BUG_ON(!valid_dma_direction(dir));
if (ops->sync_sg_for_cpu)
- ops->sync_sg_for_cpu(hwdev, sg, nelems, direction);
+ ops->sync_sg_for_cpu(hwdev, sg, nelems, dir);
+ debug_dma_sync_sg_for_cpu(hwdev, sg, nelems, dir);
flush_write_buffers();
}
static inline void
dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
- int nelems, int direction)
+ int nelems, enum dma_data_direction dir)
{
- struct dma_mapping_ops *ops = get_dma_ops(hwdev);
+ struct dma_map_ops *ops = get_dma_ops(hwdev);
- BUG_ON(!valid_dma_direction(direction));
+ BUG_ON(!valid_dma_direction(dir));
if (ops->sync_sg_for_device)
- ops->sync_sg_for_device(hwdev, sg, nelems, direction);
+ ops->sync_sg_for_device(hwdev, sg, nelems, dir);
+ debug_dma_sync_sg_for_device(hwdev, sg, nelems, dir);
flush_write_buffers();
}
static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
size_t offset, size_t size,
- int direction)
+ enum dma_data_direction dir)
{
- struct dma_mapping_ops *ops = get_dma_ops(dev);
+ struct dma_map_ops *ops = get_dma_ops(dev);
+ dma_addr_t addr;
- BUG_ON(!valid_dma_direction(direction));
- return ops->map_single(dev, page_to_phys(page) + offset,
- size, direction);
+ BUG_ON(!valid_dma_direction(dir));
+ addr = ops->map_page(dev, page, offset, size, dir, NULL);
+ debug_dma_map_page(dev, page, offset, size, dir, addr, false);
+
+ return addr;
}
static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
- size_t size, int direction)
+ size_t size, enum dma_data_direction dir)
{
- dma_unmap_single(dev, addr, size, direction);
+ struct dma_map_ops *ops = get_dma_ops(dev);
+
+ BUG_ON(!valid_dma_direction(dir));
+ if (ops->unmap_page)
+ ops->unmap_page(dev, addr, size, dir, NULL);
+ debug_dma_unmap_page(dev, addr, size, dir, false);
}
static inline void
@@ -266,7 +260,7 @@ static inline void *
dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
gfp_t gfp)
{
- struct dma_mapping_ops *ops = get_dma_ops(dev);
+ struct dma_map_ops *ops = get_dma_ops(dev);
void *memory;
gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
@@ -285,20 +279,24 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
if (!ops->alloc_coherent)
return NULL;
- return ops->alloc_coherent(dev, size, dma_handle,
- dma_alloc_coherent_gfp_flags(dev, gfp));
+ memory = ops->alloc_coherent(dev, size, dma_handle,
+ dma_alloc_coherent_gfp_flags(dev, gfp));
+ debug_dma_alloc_coherent(dev, size, *dma_handle, memory);
+
+ return memory;
}
static inline void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t bus)
{
- struct dma_mapping_ops *ops = get_dma_ops(dev);
+ struct dma_map_ops *ops = get_dma_ops(dev);
WARN_ON(irqs_disabled()); /* for portability */
if (dma_release_from_coherent(dev, get_order(size), vaddr))
return;
+ debug_dma_free_coherent(dev, size, vaddr, bus);
if (ops->free_coherent)
ops->free_coherent(dev, size, vaddr, bus);
}
diff --git a/arch/x86/include/asm/dmi.h b/arch/x86/include/asm/dmi.h
index bc68212c6bc0..fd8f9e2ca35f 100644
--- a/arch/x86/include/asm/dmi.h
+++ b/arch/x86/include/asm/dmi.h
@@ -1,22 +1,15 @@
#ifndef _ASM_X86_DMI_H
#define _ASM_X86_DMI_H
-#include <asm/io.h>
-
-#define DMI_MAX_DATA 2048
+#include <linux/compiler.h>
+#include <linux/init.h>
-extern int dmi_alloc_index;
-extern char dmi_alloc_data[DMI_MAX_DATA];
+#include <asm/io.h>
+#include <asm/setup.h>
-/* This is so early that there is no good way to allocate dynamic memory.
- Allocate data in an BSS array. */
-static inline void *dmi_alloc(unsigned len)
+static __always_inline __init void *dmi_alloc(unsigned len)
{
- int idx = dmi_alloc_index;
- if ((dmi_alloc_index + len) > DMI_MAX_DATA)
- return NULL;
- dmi_alloc_index += len;
- return dmi_alloc_data + idx;
+ return extend_brk(len, sizeof(int));
}
/* Use early IO mappings for DMI because it's initialized early */
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 00d41ce4c844..7ecba4d85089 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -72,7 +72,7 @@ extern int e820_all_mapped(u64 start, u64 end, unsigned type);
extern void e820_add_region(u64 start, u64 size, int type);
extern void e820_print_map(char *who);
extern int
-sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, int *pnr_map);
+sanitize_e820_map(struct e820entry *biosmap, int max_nr_map, u32 *pnr_map);
extern u64 e820_update_range(u64 start, u64 size, unsigned old_type,
unsigned new_type);
extern u64 e820_remove_range(u64 start, u64 size, unsigned old_type,
diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h
index 50ca486fd88c..1f7e62517284 100644
--- a/arch/x86/include/asm/ia32.h
+++ b/arch/x86/include/asm/ia32.h
@@ -129,13 +129,6 @@ typedef struct compat_siginfo {
} _sifields;
} compat_siginfo_t;
-struct ustat32 {
- __u32 f_tfree;
- compat_ino_t f_tinode;
- char f_fname[6];
- char f_fpack[6];
-};
-
#define IA32_STACK_TOP IA32_PAGE_OFFSET
#ifdef __KERNEL__
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 59cb4a1317b7..9d826e436010 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -162,9 +162,13 @@ extern int (*ioapic_renumber_irq)(int ioapic, int irq);
extern void ioapic_init_mappings(void);
#ifdef CONFIG_X86_64
-extern int save_mask_IO_APIC_setup(void);
-extern void restore_IO_APIC_setup(void);
-extern void reinit_intr_remapped_IO_APIC(int);
+extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
+extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries);
+extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
+extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
+extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
+extern void reinit_intr_remapped_IO_APIC(int intr_remapping,
+ struct IO_APIC_route_entry **ioapic_entries);
#endif
extern void probe_nr_irqs_gsi(void);
@@ -172,7 +176,7 @@ extern void probe_nr_irqs_gsi(void);
extern int setup_ioapic_entry(int apic, int irq,
struct IO_APIC_route_entry *entry,
unsigned int destination, int trigger,
- int polarity, int vector);
+ int polarity, int vector, int pin);
extern void ioapic_write_entry(int apic, int pin,
struct IO_APIC_route_entry e);
#else /* !CONFIG_X86_IO_APIC */
diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h
index a6ee9e6f530f..af326a2975b5 100644
--- a/arch/x86/include/asm/iommu.h
+++ b/arch/x86/include/asm/iommu.h
@@ -3,7 +3,7 @@
extern void pci_iommu_shutdown(void);
extern void no_iommu_init(void);
-extern struct dma_mapping_ops nommu_dma_ops;
+extern struct dma_map_ops nommu_dma_ops;
extern int force_iommu, no_iommu;
extern int iommu_detected;
diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h
index 20e1fd588dbf..0396760fccb8 100644
--- a/arch/x86/include/asm/irq_remapping.h
+++ b/arch/x86/include/asm/irq_remapping.h
@@ -1,8 +1,6 @@
#ifndef _ASM_X86_IRQ_REMAPPING_H
#define _ASM_X86_IRQ_REMAPPING_H
-extern int x2apic;
-
#define IRTE_DEST(dest) ((x2apic) ? dest : dest << 8)
#endif /* _ASM_X86_IRQ_REMAPPING_H */
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
index 886c9402ec45..dc3f6cf11704 100644
--- a/arch/x86/include/asm/kvm.h
+++ b/arch/x86/include/asm/kvm.h
@@ -15,6 +15,7 @@
#define __KVM_HAVE_DEVICE_ASSIGNMENT
#define __KVM_HAVE_MSI
#define __KVM_HAVE_USER_NMI
+#define __KVM_HAVE_GUEST_DEBUG
/* Architectural interrupt line count. */
#define KVM_NR_INTERRUPTS 256
@@ -212,7 +213,30 @@ struct kvm_pit_channel_state {
__s64 count_load_time;
};
+struct kvm_debug_exit_arch {
+ __u32 exception;
+ __u32 pad;
+ __u64 pc;
+ __u64 dr6;
+ __u64 dr7;
+};
+
+#define KVM_GUESTDBG_USE_SW_BP 0x00010000
+#define KVM_GUESTDBG_USE_HW_BP 0x00020000
+#define KVM_GUESTDBG_INJECT_DB 0x00040000
+#define KVM_GUESTDBG_INJECT_BP 0x00080000
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+ __u64 debugreg[8];
+};
+
struct kvm_pit_state {
struct kvm_pit_channel_state channels[3];
};
+
+struct kvm_reinject_control {
+ __u8 pit_reinject;
+ __u8 reserved[31];
+};
#endif /* _ASM_X86_KVM_H */
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 730843d1d2fb..f0faf58044ff 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -22,6 +22,7 @@
#include <asm/pvclock-abi.h>
#include <asm/desc.h>
#include <asm/mtrr.h>
+#include <asm/msr-index.h>
#define KVM_MAX_VCPUS 16
#define KVM_MEMORY_SLOTS 32
@@ -134,11 +135,18 @@ enum {
#define KVM_NR_MEM_OBJS 40
-struct kvm_guest_debug {
- int enabled;
- unsigned long bp[4];
- int singlestep;
-};
+#define KVM_NR_DB_REGS 4
+
+#define DR6_BD (1 << 13)
+#define DR6_BS (1 << 14)
+#define DR6_FIXED_1 0xffff0ff0
+#define DR6_VOLATILE 0x0000e00f
+
+#define DR7_BP_EN_MASK 0x000000ff
+#define DR7_GE (1 << 9)
+#define DR7_GD (1 << 13)
+#define DR7_FIXED_1 0x00000400
+#define DR7_VOLATILE 0xffff23ff
/*
* We don't want allocation failures within the mmu code, so we preallocate
@@ -162,7 +170,8 @@ struct kvm_pte_chain {
* bits 0:3 - total guest paging levels (2-4, or zero for real mode)
* bits 4:7 - page table level for this shadow (1-4)
* bits 8:9 - page table quadrant for 2-level guests
- * bit 16 - "metaphysical" - gfn is not a real page (huge page/real mode)
+ * bit 16 - direct mapping of virtual to physical mapping at gfn
+ * used for real mode and two-dimensional paging
* bits 17:19 - common access permissions for all ptes in this shadow page
*/
union kvm_mmu_page_role {
@@ -172,9 +181,10 @@ union kvm_mmu_page_role {
unsigned level:4;
unsigned quadrant:2;
unsigned pad_for_nice_hex_output:6;
- unsigned metaphysical:1;
+ unsigned direct:1;
unsigned access:3;
unsigned invalid:1;
+ unsigned cr4_pge:1;
};
};
@@ -218,6 +228,18 @@ struct kvm_pv_mmu_op_buffer {
char buf[512] __aligned(sizeof(long));
};
+struct kvm_pio_request {
+ unsigned long count;
+ int cur_count;
+ gva_t guest_gva;
+ int in;
+ int port;
+ int size;
+ int string;
+ int down;
+ int rep;
+};
+
/*
* x86 supports 3 paging modes (4-level 64-bit, 3-level 64-bit, and 2-level
* 32-bit). The kvm_mmu structure abstracts the details of the current mmu
@@ -236,6 +258,7 @@ struct kvm_mmu {
hpa_t root_hpa;
int root_level;
int shadow_root_level;
+ union kvm_mmu_page_role base_role;
u64 *pae_root;
};
@@ -258,6 +281,7 @@ struct kvm_vcpu_arch {
unsigned long cr3;
unsigned long cr4;
unsigned long cr8;
+ u32 hflags;
u64 pdptrs[4]; /* pae */
u64 shadow_efer;
u64 apic_base;
@@ -338,6 +362,15 @@ struct kvm_vcpu_arch {
struct mtrr_state_type mtrr_state;
u32 pat;
+
+ int switch_db_regs;
+ unsigned long host_db[KVM_NR_DB_REGS];
+ unsigned long host_dr6;
+ unsigned long host_dr7;
+ unsigned long db[KVM_NR_DB_REGS];
+ unsigned long dr6;
+ unsigned long dr7;
+ unsigned long eff_db[KVM_NR_DB_REGS];
};
struct kvm_mem_alias {
@@ -378,6 +411,7 @@ struct kvm_arch{
unsigned long irq_sources_bitmap;
unsigned long irq_states[KVM_IOAPIC_NUM_PINS];
+ u64 vm_init_tsc;
};
struct kvm_vm_stat {
@@ -446,8 +480,7 @@ struct kvm_x86_ops {
void (*vcpu_put)(struct kvm_vcpu *vcpu);
int (*set_guest_debug)(struct kvm_vcpu *vcpu,
- struct kvm_debug_guest *dbg);
- void (*guest_debug_pre)(struct kvm_vcpu *vcpu);
+ struct kvm_guest_debug *dbg);
int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg);
@@ -583,16 +616,12 @@ void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2,
u32 error_code);
-void kvm_pic_set_irq(void *opaque, int irq, int level);
+int kvm_pic_set_irq(void *opaque, int irq, int level);
void kvm_inject_nmi(struct kvm_vcpu *vcpu);
void fx_init(struct kvm_vcpu *vcpu);
-int emulator_read_std(unsigned long addr,
- void *val,
- unsigned int bytes,
- struct kvm_vcpu *vcpu);
int emulator_write_emulated(unsigned long addr,
const void *val,
unsigned int bytes,
@@ -737,6 +766,10 @@ enum {
TASK_SWITCH_GATE = 3,
};
+#define HF_GIF_MASK (1 << 0)
+#define HF_HIF_MASK (1 << 1)
+#define HF_VINTR_MASK (1 << 2)
+
/*
* Hardware virtualization extension instructions may fault if a
* reboot turns off virtualization while processes are running.
diff --git a/arch/x86/include/asm/lguest_hcall.h b/arch/x86/include/asm/lguest_hcall.h
index 43894428c3c2..0f4ee7148afe 100644
--- a/arch/x86/include/asm/lguest_hcall.h
+++ b/arch/x86/include/asm/lguest_hcall.h
@@ -26,36 +26,20 @@
#ifndef __ASSEMBLY__
#include <asm/hw_irq.h>
+#include <asm/kvm_para.h>
/*G:031 But first, how does our Guest contact the Host to ask for privileged
* operations? There are two ways: the direct way is to make a "hypercall",
* to make requests of the Host Itself.
*
- * Our hypercall mechanism uses the highest unused trap code (traps 32 and
- * above are used by real hardware interrupts). Fifteen hypercalls are
+ * We use the KVM hypercall mechanism. Eighteen hypercalls are
* available: the hypercall number is put in the %eax register, and the
- * arguments (when required) are placed in %edx, %ebx and %ecx. If a return
+ * arguments (when required) are placed in %ebx, %ecx and %edx. If a return
* value makes sense, it's returned in %eax.
*
* Grossly invalid calls result in Sudden Death at the hands of the vengeful
* Host, rather than returning failure. This reflects Winston Churchill's
* definition of a gentleman: "someone who is only rude intentionally". */
-static inline unsigned long
-hcall(unsigned long call,
- unsigned long arg1, unsigned long arg2, unsigned long arg3)
-{
- /* "int" is the Intel instruction to trigger a trap. */
- asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY)
- /* The call in %eax (aka "a") might be overwritten */
- : "=a"(call)
- /* The arguments are in %eax, %edx, %ebx & %ecx */
- : "a"(call), "d"(arg1), "b"(arg2), "c"(arg3)
- /* "memory" means this might write somewhere in memory.
- * This isn't true for all calls, but it's safe to tell
- * gcc that it might happen so it doesn't get clever. */
- : "memory");
- return call;
-}
/*:*/
/* Can't use our min() macro here: needs to be a constant */
@@ -64,7 +48,7 @@ hcall(unsigned long call,
#define LHCALL_RING_SIZE 64
struct hcall_args {
/* These map directly onto eax, ebx, ecx, edx in struct lguest_regs */
- unsigned long arg0, arg2, arg3, arg1;
+ unsigned long arg0, arg1, arg2, arg3;
};
#endif /* !__ASSEMBLY__ */
diff --git a/arch/x86/include/asm/msidef.h b/arch/x86/include/asm/msidef.h
index 6706b3006f13..4cc48af23fef 100644
--- a/arch/x86/include/asm/msidef.h
+++ b/arch/x86/include/asm/msidef.h
@@ -47,6 +47,7 @@
#define MSI_ADDR_DEST_ID_MASK 0x00ffff0
#define MSI_ADDR_DEST_ID(dest) (((dest) << MSI_ADDR_DEST_ID_SHIFT) & \
MSI_ADDR_DEST_ID_MASK)
+#define MSI_ADDR_EXT_DEST_ID(dest) ((dest) & 0xffffff00)
#define MSI_ADDR_IR_EXT_INT (1 << 4)
#define MSI_ADDR_IR_SHV (1 << 3)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 2dbd2314139e..ec41fc16c167 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -18,11 +18,15 @@
#define _EFER_LME 8 /* Long mode enable */
#define _EFER_LMA 10 /* Long mode active (read-only) */
#define _EFER_NX 11 /* No execute enable */
+#define _EFER_SVME 12 /* Enable virtualization */
+#define _EFER_FFXSR 14 /* Enable Fast FXSAVE/FXRSTOR */
#define EFER_SCE (1<<_EFER_SCE)
#define EFER_LME (1<<_EFER_LME)
#define EFER_LMA (1<<_EFER_LMA)
#define EFER_NX (1<<_EFER_NX)
+#define EFER_SVME (1<<_EFER_SVME)
+#define EFER_FFXSR (1<<_EFER_FFXSR)
/* Intel MSRs. Some also available on other CPUs */
#define MSR_IA32_PERFCTR0 0x000000c1
@@ -365,4 +369,9 @@
#define MSR_IA32_VMX_PROCBASED_CTLS2 0x0000048b
#define MSR_IA32_VMX_EPT_VPID_CAP 0x0000048c
+/* AMD-V MSRs */
+
+#define MSR_VM_CR 0xc0010114
+#define MSR_VM_HSAVE_PA 0xc0010117
+
#endif /* _ASM_X86_MSR_INDEX_H */
diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h
index f1e4a79a6e41..0f915ae649a7 100644
--- a/arch/x86/include/asm/page_32_types.h
+++ b/arch/x86/include/asm/page_32_types.h
@@ -39,6 +39,11 @@
#define __VIRTUAL_MASK_SHIFT 32
#endif /* CONFIG_X86_PAE */
+/*
+ * Kernel image size is limited to 512 MB (see in arch/x86/kernel/head_32.S)
+ */
+#define KERNEL_IMAGE_SIZE (512 * 1024 * 1024)
+
#ifndef __ASSEMBLY__
/*
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 0617d5cc9712..7727aa8b7dda 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -317,8 +317,6 @@ struct pv_mmu_ops {
#if PAGETABLE_LEVELS >= 3
#ifdef CONFIG_X86_PAE
void (*set_pte_atomic)(pte_t *ptep, pte_t pteval);
- void (*set_pte_present)(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte);
void (*pte_clear)(struct mm_struct *mm, unsigned long addr,
pte_t *ptep);
void (*pmd_clear)(pmd_t *pmdp);
@@ -389,7 +387,7 @@ extern struct pv_lock_ops pv_lock_ops;
#define paravirt_type(op) \
[paravirt_typenum] "i" (PARAVIRT_PATCH(op)), \
- [paravirt_opptr] "m" (op)
+ [paravirt_opptr] "i" (&(op))
#define paravirt_clobber(clobber) \
[paravirt_clobber] "i" (clobber)
@@ -443,7 +441,7 @@ int paravirt_disable_iospace(void);
* offset into the paravirt_patch_template structure, and can therefore be
* freely converted back into a structure offset.
*/
-#define PARAVIRT_CALL "call *%[paravirt_opptr];"
+#define PARAVIRT_CALL "call *%c[paravirt_opptr];"
/*
* These macros are intended to wrap calls through one of the paravirt
@@ -1365,13 +1363,6 @@ static inline void set_pte_atomic(pte_t *ptep, pte_t pte)
pte.pte, pte.pte >> 32);
}
-static inline void set_pte_present(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte)
-{
- /* 5 arg words */
- pv_mmu_ops.set_pte_present(mm, addr, ptep, pte);
-}
-
static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep)
{
@@ -1388,12 +1379,6 @@ static inline void set_pte_atomic(pte_t *ptep, pte_t pte)
set_pte(ptep, pte);
}
-static inline void set_pte_present(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte)
-{
- set_pte(ptep, pte);
-}
-
static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
pte_t *ptep)
{
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index a977de23cb4d..b51a1e8b0baf 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -86,12 +86,43 @@ static inline void early_quirks(void) { }
extern void pci_iommu_alloc(void);
-#endif /* __KERNEL__ */
+/* MSI arch hook */
+#define arch_setup_msi_irqs arch_setup_msi_irqs
+
+#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
+
+#if defined(CONFIG_X86_64) || defined(CONFIG_DMA_API_DEBUG)
+
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
+ dma_addr_t ADDR_NAME;
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
+ __u32 LEN_NAME;
+#define pci_unmap_addr(PTR, ADDR_NAME) \
+ ((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
+ (((PTR)->ADDR_NAME) = (VAL))
+#define pci_unmap_len(PTR, LEN_NAME) \
+ ((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
+ (((PTR)->LEN_NAME) = (VAL))
-#ifdef CONFIG_X86_32
-# include "pci_32.h"
#else
-# include "pci_64.h"
+
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME[0];
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) unsigned LEN_NAME[0];
+#define pci_unmap_addr(PTR, ADDR_NAME) sizeof((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
+ do { break; } while (pci_unmap_addr(PTR, ADDR_NAME))
+#define pci_unmap_len(PTR, LEN_NAME) sizeof((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
+ do { break; } while (pci_unmap_len(PTR, LEN_NAME))
+
+#endif
+
+#endif /* __KERNEL__ */
+
+#ifdef CONFIG_X86_64
+#include "pci_64.h"
#endif
/* implement the pci_ DMA API in terms of the generic device dma_ one */
@@ -109,11 +140,6 @@ static inline int __pcibus_to_node(const struct pci_bus *bus)
return sd->node;
}
-static inline cpumask_t __pcibus_to_cpumask(struct pci_bus *bus)
-{
- return node_to_cpumask(__pcibus_to_node(bus));
-}
-
static inline const struct cpumask *
cpumask_of_pcibus(const struct pci_bus *bus)
{
diff --git a/arch/x86/include/asm/pci_32.h b/arch/x86/include/asm/pci_32.h
deleted file mode 100644
index 6f1213a6ef4f..000000000000
--- a/arch/x86/include/asm/pci_32.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef _ASM_X86_PCI_32_H
-#define _ASM_X86_PCI_32_H
-
-
-#ifdef __KERNEL__
-
-
-/* Dynamic DMA mapping stuff.
- * i386 has everything mapped statically.
- */
-
-struct pci_dev;
-
-/* The PCI address space does equal the physical memory
- * address space. The networking and block device layers use
- * this boolean for bounce buffer decisions.
- */
-#define PCI_DMA_BUS_IS_PHYS (1)
-
-/* pci_unmap_{page,single} is a nop so... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME[0];
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) unsigned LEN_NAME[0];
-#define pci_unmap_addr(PTR, ADDR_NAME) sizeof((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- do { break; } while (pci_unmap_addr(PTR, ADDR_NAME))
-#define pci_unmap_len(PTR, LEN_NAME) sizeof((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- do { break; } while (pci_unmap_len(PTR, LEN_NAME))
-
-
-#endif /* __KERNEL__ */
-
-
-#endif /* _ASM_X86_PCI_32_H */
diff --git a/arch/x86/include/asm/pci_64.h b/arch/x86/include/asm/pci_64.h
index 4da207982777..ae5e40f67daf 100644
--- a/arch/x86/include/asm/pci_64.h
+++ b/arch/x86/include/asm/pci_64.h
@@ -24,28 +24,6 @@ extern int (*pci_config_write)(int seg, int bus, int dev, int fn,
extern void dma32_reserve_bootmem(void);
-/* The PCI address space does equal the physical memory
- * address space. The networking and block device layers use
- * this boolean for bounce buffer decisions
- *
- * On AMD64 it mostly equals, but we set it to zero if a hardware
- * IOMMU (gart) of sotware IOMMU (swiotlb) is available.
- */
-#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
-
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
- dma_addr_t ADDR_NAME;
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
- __u32 LEN_NAME;
-#define pci_unmap_addr(PTR, ADDR_NAME) \
- ((PTR)->ADDR_NAME)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
- (((PTR)->ADDR_NAME) = (VAL))
-#define pci_unmap_len(PTR, LEN_NAME) \
- ((PTR)->LEN_NAME)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
- (((PTR)->LEN_NAME) = (VAL))
-
#endif /* __KERNEL__ */
#endif /* _ASM_X86_PCI_64_H */
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 8f1d2fbec1d4..aee103b26d01 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -43,14 +43,6 @@
#else /* ...!ASSEMBLY */
#include <linux/stringify.h>
-#include <asm/sections.h>
-
-#define __addr_to_pcpu_ptr(addr) \
- (void *)((unsigned long)(addr) - (unsigned long)pcpu_base_addr \
- + (unsigned long)__per_cpu_start)
-#define __pcpu_ptr_to_addr(ptr) \
- (void *)((unsigned long)(ptr) + (unsigned long)pcpu_base_addr \
- - (unsigned long)__per_cpu_start)
#ifdef CONFIG_SMP
#define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x
diff --git a/arch/x86/include/asm/pgtable-2level.h b/arch/x86/include/asm/pgtable-2level.h
index c1774ac9da7a..2334982b339e 100644
--- a/arch/x86/include/asm/pgtable-2level.h
+++ b/arch/x86/include/asm/pgtable-2level.h
@@ -26,13 +26,6 @@ static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
native_set_pte(ptep, pte);
}
-static inline void native_set_pte_present(struct mm_struct *mm,
- unsigned long addr,
- pte_t *ptep, pte_t pte)
-{
- native_set_pte(ptep, pte);
-}
-
static inline void native_pmd_clear(pmd_t *pmdp)
{
native_set_pmd(pmdp, __pmd(0));
diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h
index 3f13cdf61156..177b0165ea01 100644
--- a/arch/x86/include/asm/pgtable-3level.h
+++ b/arch/x86/include/asm/pgtable-3level.h
@@ -31,23 +31,6 @@ static inline void native_set_pte(pte_t *ptep, pte_t pte)
ptep->pte_low = pte.pte_low;
}
-/*
- * Since this is only called on user PTEs, and the page fault handler
- * must handle the already racy situation of simultaneous page faults,
- * we are justified in merely clearing the PTE present bit, followed
- * by a set. The ordering here is important.
- */
-static inline void native_set_pte_present(struct mm_struct *mm,
- unsigned long addr,
- pte_t *ptep, pte_t pte)
-{
- ptep->pte_low = 0;
- smp_wmb();
- ptep->pte_high = pte.pte_high;
- smp_wmb();
- ptep->pte_low = pte.pte_low;
-}
-
static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
{
set_64bit((unsigned long long *)(ptep), native_pte_val(pte));
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index d0812e155f1d..29d96d168bc0 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -31,8 +31,6 @@ extern struct list_head pgd_list;
#define set_pte(ptep, pte) native_set_pte(ptep, pte)
#define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte)
-#define set_pte_present(mm, addr, ptep, pte) \
- native_set_pte_present(mm, addr, ptep, pte)
#define set_pte_atomic(ptep, pte) \
native_set_pte_atomic(ptep, pte)
diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h
index 97612fc7632f..31bd120cf2a2 100644
--- a/arch/x86/include/asm/pgtable_32.h
+++ b/arch/x86/include/asm/pgtable_32.h
@@ -42,9 +42,6 @@ extern void set_pmd_pfn(unsigned long, unsigned long, pgprot_t);
*/
#undef TEST_ACCESS_OK
-/* The boot page tables (all created as a single array) */
-extern unsigned long pg0[];
-
#ifdef CONFIG_X86_PAE
# include <asm/pgtable-3level.h>
#else
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 76139506c3e4..34c52370f2fe 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -75,9 +75,9 @@ struct cpuinfo_x86 {
#else
/* Number of 4K pages in DTLB/ITLB combined(in pages): */
int x86_tlbsize;
+#endif
__u8 x86_virt_bits;
__u8 x86_phys_bits;
-#endif
/* CPUID returned core id bits: */
__u8 x86_coreid_bits;
/* Max extended CPUID function supported: */
@@ -94,7 +94,7 @@ struct cpuinfo_x86 {
unsigned long loops_per_jiffy;
#ifdef CONFIG_SMP
/* cpus sharing the last level cache: */
- cpumask_t llc_shared_map;
+ cpumask_var_t llc_shared_map;
#endif
/* cpuid returned max cores value: */
u16 x86_max_cores;
@@ -391,6 +391,9 @@ DECLARE_PER_CPU(union irq_stack_union, irq_stack_union);
DECLARE_INIT_PER_CPU(irq_stack_union);
DECLARE_PER_CPU(char *, irq_stack_ptr);
+DECLARE_PER_CPU(unsigned int, irq_count);
+extern unsigned long kernel_eflags;
+extern asmlinkage void ignore_sysret(void);
#else /* X86_64 */
#ifdef CONFIG_CC_STACKPROTECTOR
DECLARE_PER_CPU(unsigned long, stack_canary);
@@ -733,6 +736,7 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
extern void select_idle_routine(const struct cpuinfo_x86 *c);
+extern void init_c1e_mask(void);
extern unsigned long boot_option_idle_override;
extern unsigned long idle_halt;
diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h
index 2b8c5160388f..1b7ee5d673c2 100644
--- a/arch/x86/include/asm/sections.h
+++ b/arch/x86/include/asm/sections.h
@@ -1 +1,8 @@
+#ifndef _ASM_X86_SECTIONS_H
+#define _ASM_X86_SECTIONS_H
+
#include <asm-generic/sections.h>
+
+extern char __brk_base[], __brk_limit[];
+
+#endif /* _ASM_X86_SECTIONS_H */
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 05c6f6b11fd5..bdc2ada05ae0 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -64,7 +64,7 @@ extern void x86_quirk_time_init(void);
#include <asm/bootparam.h>
/* Interrupt control for vSMPowered x86_64 systems */
-#ifdef CONFIG_X86_VSMP
+#ifdef CONFIG_X86_64
void vsmp_init(void);
#else
static inline void vsmp_init(void) { }
@@ -100,20 +100,51 @@ extern struct boot_params boot_params;
*/
#define LOWMEMSIZE() (0x9f000)
+/* exceedingly early brk-like allocator */
+extern unsigned long _brk_end;
+void *extend_brk(size_t size, size_t align);
+
+/*
+ * Reserve space in the brk section. The name must be unique within
+ * the file, and somewhat descriptive. The size is in bytes. Must be
+ * used at file scope.
+ *
+ * (This uses a temp function to wrap the asm so we can pass it the
+ * size parameter; otherwise we wouldn't be able to. We can't use a
+ * "section" attribute on a normal variable because it always ends up
+ * being @progbits, which ends up allocating space in the vmlinux
+ * executable.)
+ */
+#define RESERVE_BRK(name,sz) \
+ static void __section(.discard) __used \
+ __brk_reservation_fn_##name##__(void) { \
+ asm volatile ( \
+ ".pushsection .brk_reservation,\"aw\",@nobits;" \
+ ".brk." #name ":" \
+ " 1:.skip %c0;" \
+ " .size .brk." #name ", . - 1b;" \
+ " .popsection" \
+ : : "i" (sz)); \
+ }
+
#ifdef __i386__
void __init i386_start_kernel(void);
extern void probe_roms(void);
-extern unsigned long init_pg_tables_start;
-extern unsigned long init_pg_tables_end;
-
#else
void __init x86_64_start_kernel(char *real_mode);
void __init x86_64_start_reservations(char *real_mode_data);
#endif /* __i386__ */
#endif /* _SETUP */
+#else
+#define RESERVE_BRK(name,sz) \
+ .pushsection .brk_reservation,"aw",@nobits; \
+.brk.name: \
+1: .skip sz; \
+ .size .brk.name,.-1b; \
+ .popsection
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 47d0e21f2b9e..19e0d88b966d 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -21,19 +21,19 @@
extern int smp_num_siblings;
extern unsigned int num_processors;
-DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
-DECLARE_PER_CPU(cpumask_t, cpu_core_map);
+DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map);
+DECLARE_PER_CPU(cpumask_var_t, cpu_core_map);
DECLARE_PER_CPU(u16, cpu_llc_id);
DECLARE_PER_CPU(int, cpu_number);
static inline struct cpumask *cpu_sibling_mask(int cpu)
{
- return &per_cpu(cpu_sibling_map, cpu);
+ return per_cpu(cpu_sibling_map, cpu);
}
static inline struct cpumask *cpu_core_mask(int cpu)
{
- return &per_cpu(cpu_core_map, cpu);
+ return per_cpu(cpu_core_map, cpu);
}
DECLARE_EARLY_PER_CPU(u16, x86_cpu_to_apicid);
@@ -121,9 +121,10 @@ static inline void arch_send_call_function_single_ipi(int cpu)
smp_ops.send_call_func_single_ipi(cpu);
}
-static inline void arch_send_call_function_ipi(cpumask_t mask)
+#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask
+static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
{
- smp_ops.send_call_func_ipi(&mask);
+ smp_ops.send_call_func_ipi(mask);
}
void cpu_disable_common(void);
diff --git a/arch/x86/include/asm/socket.h b/arch/x86/include/asm/socket.h
index 8ab9cc8b2ecc..ca8bf2cd0ba9 100644
--- a/arch/x86/include/asm/socket.h
+++ b/arch/x86/include/asm/socket.h
@@ -54,4 +54,7 @@
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
#endif /* _ASM_X86_SOCKET_H */
diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h
index 3a5696656680..e5e6caffec87 100644
--- a/arch/x86/include/asm/spinlock.h
+++ b/arch/x86/include/asm/spinlock.h
@@ -295,6 +295,9 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw)
: "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
}
+#define __raw_read_lock_flags(lock, flags) __raw_read_lock(lock)
+#define __raw_write_lock_flags(lock, flags) __raw_write_lock(lock)
+
#define _raw_spin_relax(lock) cpu_relax()
#define _raw_read_relax(lock) cpu_relax()
#define _raw_write_relax(lock) cpu_relax()
diff --git a/arch/x86/include/asm/suspend_32.h b/arch/x86/include/asm/suspend_32.h
index a5074bd0f8be..48dcfa62ea07 100644
--- a/arch/x86/include/asm/suspend_32.h
+++ b/arch/x86/include/asm/suspend_32.h
@@ -24,28 +24,4 @@ struct saved_context {
unsigned long return_address;
} __attribute__((packed));
-#ifdef CONFIG_ACPI
-extern unsigned long saved_eip;
-extern unsigned long saved_esp;
-extern unsigned long saved_ebp;
-extern unsigned long saved_ebx;
-extern unsigned long saved_esi;
-extern unsigned long saved_edi;
-
-static inline void acpi_save_register_state(unsigned long return_point)
-{
- saved_eip = return_point;
- asm volatile("movl %%esp,%0" : "=m" (saved_esp));
- asm volatile("movl %%ebp,%0" : "=m" (saved_ebp));
- asm volatile("movl %%ebx,%0" : "=m" (saved_ebx));
- asm volatile("movl %%edi,%0" : "=m" (saved_edi));
- asm volatile("movl %%esi,%0" : "=m" (saved_esi));
-}
-
-#define acpi_restore_register_state() do {} while (0)
-
-/* routines for saving/restoring kernel state */
-extern int acpi_save_state_mem(void);
-#endif
-
#endif /* _ASM_X86_SUSPEND_32_H */
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 1b8afa78e869..82ada75f3ebf 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -174,10 +174,6 @@ struct __attribute__ ((__packed__)) vmcb {
#define SVM_CPUID_FEATURE_SHIFT 2
#define SVM_CPUID_FUNC 0x8000000a
-#define MSR_EFER_SVME_MASK (1ULL << 12)
-#define MSR_VM_CR 0xc0010114
-#define MSR_VM_HSAVE_PA 0xc0010117ULL
-
#define SVM_VM_CR_SVM_DISABLE 4
#define SVM_SELECTOR_S_SHIFT 4
diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h
index ffb08be2a530..72a6dcd1299b 100644
--- a/arch/x86/include/asm/sys_ia32.h
+++ b/arch/x86/include/asm/sys_ia32.h
@@ -70,8 +70,6 @@ struct old_utsname;
asmlinkage long sys32_olduname(struct oldold_utsname __user *);
long sys32_uname(struct old_utsname __user *);
-long sys32_ustat(unsigned, struct ustat32 __user *);
-
asmlinkage long sys32_execve(char __user *, compat_uptr_t __user *,
compat_uptr_t __user *, struct pt_regs *);
asmlinkage long sys32_clone(unsigned int, unsigned int, struct pt_regs *);
diff --git a/arch/x86/include/asm/timer.h b/arch/x86/include/asm/timer.h
index a81195eaa2b3..bd37ed444a21 100644
--- a/arch/x86/include/asm/timer.h
+++ b/arch/x86/include/asm/timer.h
@@ -12,9 +12,9 @@ unsigned long native_calibrate_tsc(void);
#ifdef CONFIG_X86_32
extern int timer_ack;
-extern int recalibrate_cpu_khz(void);
extern irqreturn_t timer_interrupt(int irq, void *dev_id);
#endif /* CONFIG_X86_32 */
+extern int recalibrate_cpu_khz(void);
extern int no_timer_check;
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 77cfb2cfb386..892b119dba6f 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -44,9 +44,6 @@
#ifdef CONFIG_X86_32
-/* Mappings between node number and cpus on that node. */
-extern cpumask_t node_to_cpumask_map[];
-
/* Mappings between logical cpu number and node number */
extern int cpu_to_node_map[];
@@ -57,30 +54,8 @@ static inline int cpu_to_node(int cpu)
}
#define early_cpu_to_node(cpu) cpu_to_node(cpu)
-/* Returns a bitmask of CPUs on Node 'node'.
- *
- * Side note: this function creates the returned cpumask on the stack
- * so with a high NR_CPUS count, excessive stack space is used. The
- * cpumask_of_node function should be used whenever possible.
- */
-static inline cpumask_t node_to_cpumask(int node)
-{
- return node_to_cpumask_map[node];
-}
-
-/* Returns a bitmask of CPUs on Node 'node'. */
-static inline const struct cpumask *cpumask_of_node(int node)
-{
- return &node_to_cpumask_map[node];
-}
-
-static inline void setup_node_to_cpumask_map(void) { }
-
#else /* CONFIG_X86_64 */
-/* Mappings between node number and cpus on that node. */
-extern cpumask_t *node_to_cpumask_map;
-
/* Mappings between logical cpu number and node number */
DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map);
@@ -91,8 +66,6 @@ DECLARE_PER_CPU(int, node_number);
#ifdef CONFIG_DEBUG_PER_CPU_MAPS
extern int cpu_to_node(int cpu);
extern int early_cpu_to_node(int cpu);
-extern const cpumask_t *cpumask_of_node(int node);
-extern cpumask_t node_to_cpumask(int node);
#else /* !CONFIG_DEBUG_PER_CPU_MAPS */
@@ -108,42 +81,32 @@ static inline int early_cpu_to_node(int cpu)
return early_per_cpu(x86_cpu_to_node_map, cpu);
}
-/* Returns a pointer to the cpumask of CPUs on Node 'node'. */
-static inline const cpumask_t *cpumask_of_node(int node)
-{
- return &node_to_cpumask_map[node];
-}
+#endif /* !CONFIG_DEBUG_PER_CPU_MAPS */
+
+#endif /* CONFIG_X86_64 */
-/* Returns a bitmask of CPUs on Node 'node'. */
-static inline cpumask_t node_to_cpumask(int node)
+/* Mappings between node number and cpus on that node. */
+extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+extern const struct cpumask *cpumask_of_node(int node);
+#else
+/* Returns a pointer to the cpumask of CPUs on Node 'node'. */
+static inline const struct cpumask *cpumask_of_node(int node)
{
return node_to_cpumask_map[node];
}
-
-#endif /* !CONFIG_DEBUG_PER_CPU_MAPS */
+#endif
extern void setup_node_to_cpumask_map(void);
/*
- * Replace default node_to_cpumask_ptr with optimized version
- * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)"
- */
-#define node_to_cpumask_ptr(v, node) \
- const cpumask_t *v = cpumask_of_node(node)
-
-#define node_to_cpumask_ptr_next(v, node) \
- v = cpumask_of_node(node)
-
-#endif /* CONFIG_X86_64 */
-
-/*
* Returns the number of the node containing Node 'node'. This
* architecture is flat, so it is a pretty simple function!
*/
#define parent_node(node) (node)
#define pcibus_to_node(bus) __pcibus_to_node(bus)
-#define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus)
#ifdef CONFIG_X86_32
extern unsigned long node_start_pfn[];
@@ -209,52 +172,24 @@ static inline int early_cpu_to_node(int cpu)
return 0;
}
-static inline const cpumask_t *cpumask_of_node(int node)
-{
- return &cpu_online_map;
-}
-static inline cpumask_t node_to_cpumask(int node)
-{
- return cpu_online_map;
-}
-static inline int node_to_first_cpu(int node)
+static inline const struct cpumask *cpumask_of_node(int node)
{
- return first_cpu(cpu_online_map);
+ return cpu_online_mask;
}
static inline void setup_node_to_cpumask_map(void) { }
-/*
- * Replace default node_to_cpumask_ptr with optimized version
- * Deprecated: use "const struct cpumask *mask = cpumask_of_node(node)"
- */
-#define node_to_cpumask_ptr(v, node) \
- const cpumask_t *v = cpumask_of_node(node)
-
-#define node_to_cpumask_ptr_next(v, node) \
- v = cpumask_of_node(node)
#endif
#include <asm-generic/topology.h>
-#ifdef CONFIG_NUMA
-/* Returns the number of the first CPU on Node 'node'. */
-static inline int node_to_first_cpu(int node)
-{
- return cpumask_first(cpumask_of_node(node));
-}
-#endif
-
-extern cpumask_t cpu_coregroup_map(int cpu);
extern const struct cpumask *cpu_coregroup_mask(int cpu);
#ifdef ENABLE_TOPO_DEFINES
#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id)
#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
-#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu))
-#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
-#define topology_core_cpumask(cpu) (&per_cpu(cpu_core_map, cpu))
-#define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu))
+#define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu))
+#define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu))
/* indicates that pointers to the topology cpumask_t maps are valid */
#define arch_provides_topology_pointers yes
@@ -268,7 +203,7 @@ struct pci_bus;
void set_pci_bus_resources_arch_default(struct pci_bus *b);
#ifdef CONFIG_SMP
-#define mc_capable() (cpus_weight(per_cpu(cpu_core_map, 0)) != nr_cpu_ids)
+#define mc_capable() (cpumask_weight(cpu_core_mask(0)) != nr_cpu_ids)
#define smt_capable() (smp_num_siblings > 1)
#endif
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h
index f2bba78430a4..6e72d74cf8dc 100644
--- a/arch/x86/include/asm/unistd_32.h
+++ b/arch/x86/include/asm/unistd_32.h
@@ -338,6 +338,8 @@
#define __NR_dup3 330
#define __NR_pipe2 331
#define __NR_inotify_init1 332
+#define __NR_preadv 333
+#define __NR_pwritev 334
#ifdef __KERNEL__
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h
index d2e415e6666f..f81829462325 100644
--- a/arch/x86/include/asm/unistd_64.h
+++ b/arch/x86/include/asm/unistd_64.h
@@ -653,6 +653,10 @@ __SYSCALL(__NR_dup3, sys_dup3)
__SYSCALL(__NR_pipe2, sys_pipe2)
#define __NR_inotify_init1 294
__SYSCALL(__NR_inotify_init1, sys_inotify_init1)
+#define __NR_preadv 295
+__SYSCALL(__NR_preadv, sys_preadv)
+#define __NR_pwritev 296
+__SYSCALL(__NR_pwritev, sys_pwritev)
#ifndef __NO_STUBS
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
index 9f4dfba33b28..d3a98ea1062e 100644
--- a/arch/x86/include/asm/uv/uv_hub.h
+++ b/arch/x86/include/asm/uv/uv_hub.h
@@ -11,11 +11,13 @@
#ifndef _ASM_X86_UV_UV_HUB_H
#define _ASM_X86_UV_UV_HUB_H
+#ifdef CONFIG_X86_64
#include <linux/numa.h>
#include <linux/percpu.h>
#include <linux/timer.h>
#include <asm/types.h>
#include <asm/percpu.h>
+#include <asm/uv/uv_mmrs.h>
/*
@@ -397,6 +399,7 @@ static inline void uv_set_scir_bits(unsigned char value)
uv_write_local_mmr8(uv_hub_info->scir.offset, value);
}
}
+
static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value)
{
if (uv_cpu_hub_info(cpu)->scir.state != value) {
@@ -405,4 +408,15 @@ static inline void uv_set_cpu_scir_bits(int cpu, unsigned char value)
}
}
+static inline void uv_hub_send_ipi(int pnode, int apicid, int vector)
+{
+ unsigned long val;
+
+ val = (1UL << UVH_IPI_INT_SEND_SHFT) |
+ ((apicid & 0x3f) << UVH_IPI_INT_APIC_ID_SHFT) |
+ (vector << UVH_IPI_INT_VECTOR_SHFT);
+ uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
+}
+
+#endif /* CONFIG_X86_64 */
#endif /* _ASM_X86_UV_UV_HUB_H */
diff --git a/arch/x86/include/asm/uv/uv_mmrs.h b/arch/x86/include/asm/uv/uv_mmrs.h
index dd627793a234..db68ac8a5ac2 100644
--- a/arch/x86/include/asm/uv/uv_mmrs.h
+++ b/arch/x86/include/asm/uv/uv_mmrs.h
@@ -1,3 +1,4 @@
+
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -243,6 +244,158 @@ union uvh_event_occurred0_u {
#define UVH_EVENT_OCCURRED0_ALIAS_32 0x005f0
/* ========================================================================= */
+/* UVH_GR0_TLB_INT0_CONFIG */
+/* ========================================================================= */
+#define UVH_GR0_TLB_INT0_CONFIG 0x61b00UL
+
+#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_SHFT 0
+#define UVH_GR0_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR0_TLB_INT0_CONFIG_DM_SHFT 8
+#define UVH_GR0_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR0_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR0_TLB_INT0_CONFIG_STATUS_SHFT 12
+#define UVH_GR0_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR0_TLB_INT0_CONFIG_P_SHFT 13
+#define UVH_GR0_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR0_TLB_INT0_CONFIG_T_SHFT 15
+#define UVH_GR0_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR0_TLB_INT0_CONFIG_M_SHFT 16
+#define UVH_GR0_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR0_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr0_tlb_int0_config_u {
+ unsigned long v;
+ struct uvh_gr0_tlb_int0_config_s {
+ unsigned long vector_ : 8; /* RW */
+ unsigned long dm : 3; /* RW */
+ unsigned long destmode : 1; /* RW */
+ unsigned long status : 1; /* RO */
+ unsigned long p : 1; /* RO */
+ unsigned long rsvd_14 : 1; /* */
+ unsigned long t : 1; /* RO */
+ unsigned long m : 1; /* RW */
+ unsigned long rsvd_17_31: 15; /* */
+ unsigned long apic_id : 32; /* RW */
+ } s;
+};
+
+/* ========================================================================= */
+/* UVH_GR0_TLB_INT1_CONFIG */
+/* ========================================================================= */
+#define UVH_GR0_TLB_INT1_CONFIG 0x61b40UL
+
+#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_SHFT 0
+#define UVH_GR0_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR0_TLB_INT1_CONFIG_DM_SHFT 8
+#define UVH_GR0_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR0_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR0_TLB_INT1_CONFIG_STATUS_SHFT 12
+#define UVH_GR0_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR0_TLB_INT1_CONFIG_P_SHFT 13
+#define UVH_GR0_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR0_TLB_INT1_CONFIG_T_SHFT 15
+#define UVH_GR0_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR0_TLB_INT1_CONFIG_M_SHFT 16
+#define UVH_GR0_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR0_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr0_tlb_int1_config_u {
+ unsigned long v;
+ struct uvh_gr0_tlb_int1_config_s {
+ unsigned long vector_ : 8; /* RW */
+ unsigned long dm : 3; /* RW */
+ unsigned long destmode : 1; /* RW */
+ unsigned long status : 1; /* RO */
+ unsigned long p : 1; /* RO */
+ unsigned long rsvd_14 : 1; /* */
+ unsigned long t : 1; /* RO */
+ unsigned long m : 1; /* RW */
+ unsigned long rsvd_17_31: 15; /* */
+ unsigned long apic_id : 32; /* RW */
+ } s;
+};
+
+/* ========================================================================= */
+/* UVH_GR1_TLB_INT0_CONFIG */
+/* ========================================================================= */
+#define UVH_GR1_TLB_INT0_CONFIG 0x61f00UL
+
+#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_SHFT 0
+#define UVH_GR1_TLB_INT0_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR1_TLB_INT0_CONFIG_DM_SHFT 8
+#define UVH_GR1_TLB_INT0_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR1_TLB_INT0_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR1_TLB_INT0_CONFIG_STATUS_SHFT 12
+#define UVH_GR1_TLB_INT0_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR1_TLB_INT0_CONFIG_P_SHFT 13
+#define UVH_GR1_TLB_INT0_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR1_TLB_INT0_CONFIG_T_SHFT 15
+#define UVH_GR1_TLB_INT0_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR1_TLB_INT0_CONFIG_M_SHFT 16
+#define UVH_GR1_TLB_INT0_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR1_TLB_INT0_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr1_tlb_int0_config_u {
+ unsigned long v;
+ struct uvh_gr1_tlb_int0_config_s {
+ unsigned long vector_ : 8; /* RW */
+ unsigned long dm : 3; /* RW */
+ unsigned long destmode : 1; /* RW */
+ unsigned long status : 1; /* RO */
+ unsigned long p : 1; /* RO */
+ unsigned long rsvd_14 : 1; /* */
+ unsigned long t : 1; /* RO */
+ unsigned long m : 1; /* RW */
+ unsigned long rsvd_17_31: 15; /* */
+ unsigned long apic_id : 32; /* RW */
+ } s;
+};
+
+/* ========================================================================= */
+/* UVH_GR1_TLB_INT1_CONFIG */
+/* ========================================================================= */
+#define UVH_GR1_TLB_INT1_CONFIG 0x61f40UL
+
+#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_SHFT 0
+#define UVH_GR1_TLB_INT1_CONFIG_VECTOR_MASK 0x00000000000000ffUL
+#define UVH_GR1_TLB_INT1_CONFIG_DM_SHFT 8
+#define UVH_GR1_TLB_INT1_CONFIG_DM_MASK 0x0000000000000700UL
+#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_SHFT 11
+#define UVH_GR1_TLB_INT1_CONFIG_DESTMODE_MASK 0x0000000000000800UL
+#define UVH_GR1_TLB_INT1_CONFIG_STATUS_SHFT 12
+#define UVH_GR1_TLB_INT1_CONFIG_STATUS_MASK 0x0000000000001000UL
+#define UVH_GR1_TLB_INT1_CONFIG_P_SHFT 13
+#define UVH_GR1_TLB_INT1_CONFIG_P_MASK 0x0000000000002000UL
+#define UVH_GR1_TLB_INT1_CONFIG_T_SHFT 15
+#define UVH_GR1_TLB_INT1_CONFIG_T_MASK 0x0000000000008000UL
+#define UVH_GR1_TLB_INT1_CONFIG_M_SHFT 16
+#define UVH_GR1_TLB_INT1_CONFIG_M_MASK 0x0000000000010000UL
+#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_SHFT 32
+#define UVH_GR1_TLB_INT1_CONFIG_APIC_ID_MASK 0xffffffff00000000UL
+
+union uvh_gr1_tlb_int1_config_u {
+ unsigned long v;
+ struct uvh_gr1_tlb_int1_config_s {
+ unsigned long vector_ : 8; /* RW */
+ unsigned long dm : 3; /* RW */
+ unsigned long destmode : 1; /* RW */
+ unsigned long status : 1; /* RO */
+ unsigned long p : 1; /* RO */
+ unsigned long rsvd_14 : 1; /* */
+ unsigned long t : 1; /* RO */
+ unsigned long m : 1; /* RW */
+ unsigned long rsvd_17_31: 15; /* */
+ unsigned long apic_id : 32; /* RW */
+ } s;
+};
+
+/* ========================================================================= */
/* UVH_INT_CMPB */
/* ========================================================================= */
#define UVH_INT_CMPB 0x22080UL
diff --git a/arch/x86/include/asm/virtext.h b/arch/x86/include/asm/virtext.h
index 593636275238..e0f9aa16358b 100644
--- a/arch/x86/include/asm/virtext.h
+++ b/arch/x86/include/asm/virtext.h
@@ -118,7 +118,7 @@ static inline void cpu_svm_disable(void)
wrmsrl(MSR_VM_HSAVE_PA, 0);
rdmsrl(MSR_EFER, efer);
- wrmsrl(MSR_EFER, efer & ~MSR_EFER_SVME_MASK);
+ wrmsrl(MSR_EFER, efer & ~EFER_SVME);
}
/** Makes sure SVM is disabled, if it is supported on the CPU
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index d0238e6151d8..498f944010b9 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -270,8 +270,9 @@ enum vmcs_field {
#define INTR_TYPE_EXT_INTR (0 << 8) /* external interrupt */
#define INTR_TYPE_NMI_INTR (2 << 8) /* NMI */
-#define INTR_TYPE_EXCEPTION (3 << 8) /* processor exception */
+#define INTR_TYPE_HARD_EXCEPTION (3 << 8) /* processor exception */
#define INTR_TYPE_SOFT_INTR (4 << 8) /* software interrupt */
+#define INTR_TYPE_SOFT_EXCEPTION (6 << 8) /* software exception */
/* GUEST_INTERRUPTIBILITY_INFO flags. */
#define GUEST_INTR_STATE_STI 0x00000001
@@ -311,7 +312,7 @@ enum vmcs_field {
#define DEBUG_REG_ACCESS_TYPE 0x10 /* 4, direction of access */
#define TYPE_MOV_TO_DR (0 << 4)
#define TYPE_MOV_FROM_DR (1 << 4)
-#define DEBUG_REG_ACCESS_REG 0xf00 /* 11:8, general purpose reg. */
+#define DEBUG_REG_ACCESS_REG(eq) (((eq) >> 8) & 0xf) /* 11:8, general purpose reg. */
/* segment AR */
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 5e79ca694326..9c371e4a9fa6 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -296,6 +296,8 @@ HYPERVISOR_get_debugreg(int reg)
static inline int
HYPERVISOR_update_descriptor(u64 ma, u64 desc)
{
+ if (sizeof(u64) == sizeof(long))
+ return _hypercall2(int, update_descriptor, ma, desc);
return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32);
}
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 84000eb931ff..145cce75cda7 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -71,7 +71,6 @@ obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o
obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o
obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o
-obj-$(CONFIG_X86_VSMP) += vsmp_64.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_MODULES) += module_$(BITS).o
obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o
@@ -107,7 +106,7 @@ obj-$(CONFIG_MICROCODE) += microcode.o
obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
-obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o # NB rename without _64
+obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
###
# 64 bit specific files
@@ -121,4 +120,5 @@ ifeq ($(CONFIG_X86_64),y)
obj-$(CONFIG_AMD_IOMMU) += amd_iommu_init.o amd_iommu.o
obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o
+ obj-y += vsmp_64.o
endif
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index a18eb7ce2236..723989d7f802 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -230,6 +230,35 @@ static void __cpuinit acpi_register_lapic(int id, u8 enabled)
}
static int __init
+acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
+{
+ struct acpi_madt_local_x2apic *processor = NULL;
+
+ processor = (struct acpi_madt_local_x2apic *)header;
+
+ if (BAD_MADT_ENTRY(processor, end))
+ return -EINVAL;
+
+ acpi_table_print_madt_entry(header);
+
+#ifdef CONFIG_X86_X2APIC
+ /*
+ * We need to register disabled CPU as well to permit
+ * counting disabled CPUs. This allows us to size
+ * cpus_possible_map more accurately, to permit
+ * to not preallocating memory for all NR_CPUS
+ * when we use CPU hotplug.
+ */
+ acpi_register_lapic(processor->local_apic_id, /* APIC ID */
+ processor->lapic_flags & ACPI_MADT_ENABLED);
+#else
+ printk(KERN_WARNING PREFIX "x2apic entry ignored\n");
+#endif
+
+ return 0;
+}
+
+static int __init
acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end)
{
struct acpi_madt_local_apic *processor = NULL;
@@ -289,6 +318,25 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header,
}
static int __init
+acpi_parse_x2apic_nmi(struct acpi_subtable_header *header,
+ const unsigned long end)
+{
+ struct acpi_madt_local_x2apic_nmi *x2apic_nmi = NULL;
+
+ x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header;
+
+ if (BAD_MADT_ENTRY(x2apic_nmi, end))
+ return -EINVAL;
+
+ acpi_table_print_madt_entry(header);
+
+ if (x2apic_nmi->lint != 1)
+ printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n");
+
+ return 0;
+}
+
+static int __init
acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end)
{
struct acpi_madt_local_apic_nmi *lapic_nmi = NULL;
@@ -793,6 +841,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
static int __init acpi_parse_madt_lapic_entries(void)
{
int count;
+ int x2count = 0;
if (!cpu_has_apic)
return -ENODEV;
@@ -816,22 +865,28 @@ static int __init acpi_parse_madt_lapic_entries(void)
count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_SAPIC,
acpi_parse_sapic, MAX_APICS);
- if (!count)
+ if (!count) {
+ x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
+ acpi_parse_x2apic, MAX_APICS);
count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
acpi_parse_lapic, MAX_APICS);
- if (!count) {
+ }
+ if (!count && !x2count) {
printk(KERN_ERR PREFIX "No LAPIC entries present\n");
/* TBD: Cleanup to allow fallback to MPS */
return -ENODEV;
- } else if (count < 0) {
+ } else if (count < 0 || x2count < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
/* TBD: Cleanup to allow fallback to MPS */
return count;
}
+ x2count =
+ acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI,
+ acpi_parse_x2apic_nmi, 0);
count =
acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0);
- if (count < 0) {
+ if (count < 0 || x2count < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
/* TBD: Cleanup to allow fallback to MPS */
return count;
@@ -1470,7 +1525,7 @@ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d)
/*
* If your system is blacklisted here, but you find that acpi=force
- * works for you, please contact acpi-devel@sourceforge.net
+ * works for you, please contact linux-acpi@vger.kernel.org
*/
static struct dmi_system_id __initdata acpi_dmi_table[] = {
/*
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 5113c080f0c4..a97db99dad52 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -22,10 +22,9 @@
#include <linux/bitops.h>
#include <linux/debugfs.h>
#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
#include <linux/iommu-helper.h>
-#ifdef CONFIG_IOMMU_API
#include <linux/iommu.h>
-#endif
#include <asm/proto.h>
#include <asm/iommu.h>
#include <asm/gart.h>
@@ -1297,8 +1296,10 @@ static void __unmap_single(struct amd_iommu *iommu,
/*
* The exported map_single function for dma_ops.
*/
-static dma_addr_t map_single(struct device *dev, phys_addr_t paddr,
- size_t size, int dir)
+static dma_addr_t map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
unsigned long flags;
struct amd_iommu *iommu;
@@ -1306,6 +1307,7 @@ static dma_addr_t map_single(struct device *dev, phys_addr_t paddr,
u16 devid;
dma_addr_t addr;
u64 dma_mask;
+ phys_addr_t paddr = page_to_phys(page) + offset;
INC_STATS_COUNTER(cnt_map_single);
@@ -1340,8 +1342,8 @@ out:
/*
* The exported unmap_single function for dma_ops.
*/
-static void unmap_single(struct device *dev, dma_addr_t dma_addr,
- size_t size, int dir)
+static void unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
{
unsigned long flags;
struct amd_iommu *iommu;
@@ -1390,7 +1392,8 @@ static int map_sg_no_iommu(struct device *dev, struct scatterlist *sglist,
* lists).
*/
static int map_sg(struct device *dev, struct scatterlist *sglist,
- int nelems, int dir)
+ int nelems, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
unsigned long flags;
struct amd_iommu *iommu;
@@ -1457,7 +1460,8 @@ unmap:
* lists).
*/
static void unmap_sg(struct device *dev, struct scatterlist *sglist,
- int nelems, int dir)
+ int nelems, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
unsigned long flags;
struct amd_iommu *iommu;
@@ -1644,11 +1648,11 @@ static void prealloc_protection_domains(void)
}
}
-static struct dma_mapping_ops amd_iommu_dma_ops = {
+static struct dma_map_ops amd_iommu_dma_ops = {
.alloc_coherent = alloc_coherent,
.free_coherent = free_coherent,
- .map_single = map_single,
- .unmap_single = unmap_single,
+ .map_page = map_page,
+ .unmap_page = unmap_page,
.map_sg = map_sg,
.unmap_sg = unmap_sg,
.dma_supported = amd_iommu_dma_supported,
@@ -1924,6 +1928,12 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
return paddr;
}
+static int amd_iommu_domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap)
+{
+ return 0;
+}
+
static struct iommu_ops amd_iommu_ops = {
.domain_init = amd_iommu_domain_init,
.domain_destroy = amd_iommu_domain_destroy,
@@ -1932,5 +1942,6 @@ static struct iommu_ops amd_iommu_ops = {
.map = amd_iommu_map_range,
.unmap = amd_iommu_unmap_range,
.iova_to_phys = amd_iommu_iova_to_phys,
+ .domain_has_cap = amd_iommu_domain_has_cap,
};
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 30909a258d0f..098ec84b8c00 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -809,7 +809,7 @@ void clear_local_APIC(void)
u32 v;
/* APIC hasn't been mapped yet */
- if (!apic_phys)
+ if (!x2apic && !apic_phys)
return;
maxlvt = lapic_get_maxlvt();
@@ -1304,6 +1304,7 @@ void __init enable_IR_x2apic(void)
#ifdef CONFIG_INTR_REMAP
int ret;
unsigned long flags;
+ struct IO_APIC_route_entry **ioapic_entries = NULL;
if (!cpu_has_x2apic)
return;
@@ -1334,16 +1335,23 @@ void __init enable_IR_x2apic(void)
return;
}
- local_irq_save(flags);
- mask_8259A();
+ ioapic_entries = alloc_ioapic_entries();
+ if (!ioapic_entries) {
+ pr_info("Allocate ioapic_entries failed: %d\n", ret);
+ goto end;
+ }
- ret = save_mask_IO_APIC_setup();
+ ret = save_IO_APIC_setup(ioapic_entries);
if (ret) {
pr_info("Saving IO-APIC state failed: %d\n", ret);
goto end;
}
- ret = enable_intr_remapping(1);
+ local_irq_save(flags);
+ mask_IO_APIC_setup(ioapic_entries);
+ mask_8259A();
+
+ ret = enable_intr_remapping(EIM_32BIT_APIC_ID);
if (ret && x2apic_preenabled) {
local_irq_restore(flags);
@@ -1363,14 +1371,14 @@ end_restore:
/*
* IR enabling failed
*/
- restore_IO_APIC_setup();
+ restore_IO_APIC_setup(ioapic_entries);
else
- reinit_intr_remapped_IO_APIC(x2apic_preenabled);
+ reinit_intr_remapped_IO_APIC(x2apic_preenabled, ioapic_entries);
-end:
unmask_8259A();
local_irq_restore(flags);
+end:
if (!ret) {
if (!x2apic_preenabled)
pr_info("Enabled x2apic and interrupt-remapping\n");
@@ -1378,6 +1386,8 @@ end:
pr_info("Enabled Interrupt-remapping\n");
} else
pr_err("Failed to enable Interrupt-remapping and x2apic\n");
+ if (ioapic_entries)
+ free_ioapic_entries(ioapic_entries);
#else
if (!cpu_has_x2apic)
return;
@@ -1523,12 +1533,10 @@ void __init early_init_lapic_mapping(void)
*/
void __init init_apic_mappings(void)
{
-#ifdef CONFIG_X86_X2APIC
if (x2apic) {
boot_cpu_physical_apicid = read_apic_id();
return;
}
-#endif
/*
* If no local APIC can be found then set up a fake all
@@ -1955,6 +1963,10 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state)
local_irq_save(flags);
disable_local_APIC();
+#ifdef CONFIG_INTR_REMAP
+ if (intr_remapping_enabled)
+ disable_intr_remapping();
+#endif
local_irq_restore(flags);
return 0;
}
@@ -1965,19 +1977,42 @@ static int lapic_resume(struct sys_device *dev)
unsigned long flags;
int maxlvt;
+#ifdef CONFIG_INTR_REMAP
+ int ret;
+ struct IO_APIC_route_entry **ioapic_entries = NULL;
+
if (!apic_pm_state.active)
return 0;
- maxlvt = lapic_get_maxlvt();
-
local_irq_save(flags);
+ if (x2apic) {
+ ioapic_entries = alloc_ioapic_entries();
+ if (!ioapic_entries) {
+ WARN(1, "Alloc ioapic_entries in lapic resume failed.");
+ return -ENOMEM;
+ }
-#ifdef CONFIG_X86_X2APIC
+ ret = save_IO_APIC_setup(ioapic_entries);
+ if (ret) {
+ WARN(1, "Saving IO-APIC state failed: %d\n", ret);
+ free_ioapic_entries(ioapic_entries);
+ return ret;
+ }
+
+ mask_IO_APIC_setup(ioapic_entries);
+ mask_8259A();
+ enable_x2apic();
+ }
+#else
+ if (!apic_pm_state.active)
+ return 0;
+
+ local_irq_save(flags);
if (x2apic)
enable_x2apic();
- else
#endif
- {
+
+ else {
/*
* Make sure the APICBASE points to the right address
*
@@ -1990,6 +2025,7 @@ static int lapic_resume(struct sys_device *dev)
wrmsr(MSR_IA32_APICBASE, l, h);
}
+ maxlvt = lapic_get_maxlvt();
apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
apic_write(APIC_ID, apic_pm_state.apic_id);
apic_write(APIC_DFR, apic_pm_state.apic_dfr);
@@ -2013,8 +2049,20 @@ static int lapic_resume(struct sys_device *dev)
apic_write(APIC_ESR, 0);
apic_read(APIC_ESR);
+#ifdef CONFIG_INTR_REMAP
+ if (intr_remapping_enabled)
+ reenable_intr_remapping(EIM_32BIT_APIC_ID);
+
+ if (x2apic) {
+ unmask_8259A();
+ restore_IO_APIC_setup(ioapic_entries);
+ free_ioapic_entries(ioapic_entries);
+ }
+#endif
+
local_irq_restore(flags);
+
return 0;
}
@@ -2052,7 +2100,9 @@ static int __init init_lapic_sysfs(void)
error = sysdev_register(&device_lapic);
return error;
}
-device_initcall(init_lapic_sysfs);
+
+/* local apic needs to resume before other devices access its registers. */
+core_initcall(init_lapic_sysfs);
#else /* CONFIG_PM */
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c
index f933822dba18..0014714ea97b 100644
--- a/arch/x86/kernel/apic/apic_flat_64.c
+++ b/arch/x86/kernel/apic/apic_flat_64.c
@@ -159,20 +159,6 @@ static int flat_apic_id_registered(void)
return physid_isset(read_xapic_id(), phys_cpu_present_map);
}
-static unsigned int flat_cpu_mask_to_apicid(const struct cpumask *cpumask)
-{
- return cpumask_bits(cpumask)[0] & APIC_ALL_CPUS;
-}
-
-static unsigned int flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
- const struct cpumask *andmask)
-{
- unsigned long mask1 = cpumask_bits(cpumask)[0] & APIC_ALL_CPUS;
- unsigned long mask2 = cpumask_bits(andmask)[0] & APIC_ALL_CPUS;
-
- return mask1 & mask2;
-}
-
static int flat_phys_pkg_id(int initial_apic_id, int index_msb)
{
return hard_smp_processor_id() >> index_msb;
@@ -213,8 +199,8 @@ struct apic apic_flat = {
.set_apic_id = set_apic_id,
.apic_id_mask = 0xFFu << 24,
- .cpu_mask_to_apicid = flat_cpu_mask_to_apicid,
- .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and,
+ .cpu_mask_to_apicid = default_cpu_mask_to_apicid,
+ .cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
.send_IPI_mask = flat_send_IPI_mask,
.send_IPI_mask_allbutself = flat_send_IPI_mask_allbutself,
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c
index d806ecaa948f..676cdac385c0 100644
--- a/arch/x86/kernel/apic/bigsmp_32.c
+++ b/arch/x86/kernel/apic/bigsmp_32.c
@@ -26,12 +26,12 @@ static int bigsmp_apic_id_registered(void)
return 1;
}
-static const cpumask_t *bigsmp_target_cpus(void)
+static const struct cpumask *bigsmp_target_cpus(void)
{
#ifdef CONFIG_SMP
- return &cpu_online_map;
+ return cpu_online_mask;
#else
- return &cpumask_of_cpu(0);
+ return cpumask_of(0);
#endif
}
@@ -118,9 +118,9 @@ static int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid)
}
/* As we are using single CPU as destination, pick only one CPU here */
-static unsigned int bigsmp_cpu_mask_to_apicid(const cpumask_t *cpumask)
+static unsigned int bigsmp_cpu_mask_to_apicid(const struct cpumask *cpumask)
{
- return bigsmp_cpu_to_logical_apicid(first_cpu(*cpumask));
+ return bigsmp_cpu_to_logical_apicid(cpumask_first(cpumask));
}
static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
@@ -188,10 +188,10 @@ static const struct dmi_system_id bigsmp_dmi_table[] = {
{ } /* NULL entry stops DMI scanning */
};
-static void bigsmp_vector_allocation_domain(int cpu, cpumask_t *retmask)
+static void bigsmp_vector_allocation_domain(int cpu, struct cpumask *retmask)
{
- cpus_clear(*retmask);
- cpu_set(cpu, *retmask);
+ cpumask_clear(retmask);
+ cpumask_set_cpu(cpu, retmask);
}
static int probe_bigsmp(void)
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index 19588f2770ee..1c11b819f245 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -410,7 +410,7 @@ static void es7000_enable_apic_mode(void)
WARN(1, "Command failed, status = %x\n", mip_status);
}
-static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask)
+static void es7000_vector_allocation_domain(int cpu, struct cpumask *retmask)
{
/* Careful. Some cpus do not strictly honor the set of cpus
* specified in the interrupt destination when using lowest
@@ -420,7 +420,8 @@ static void es7000_vector_allocation_domain(int cpu, cpumask_t *retmask)
* deliver interrupts to the wrong hyperthread when only one
* hyperthread was specified in the interrupt desitination.
*/
- *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
+ cpumask_clear(retmask);
+ cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
}
@@ -455,14 +456,14 @@ static int es7000_apic_id_registered(void)
return 1;
}
-static const cpumask_t *target_cpus_cluster(void)
+static const struct cpumask *target_cpus_cluster(void)
{
- return &CPU_MASK_ALL;
+ return cpu_all_mask;
}
-static const cpumask_t *es7000_target_cpus(void)
+static const struct cpumask *es7000_target_cpus(void)
{
- return &cpumask_of_cpu(smp_processor_id());
+ return cpumask_of(smp_processor_id());
}
static unsigned long
@@ -517,7 +518,7 @@ static void es7000_setup_apic_routing(void)
"Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n",
(apic_version[apic] == 0x14) ?
"Physical Cluster" : "Logical Cluster",
- nr_ioapics, cpus_addr(*es7000_target_cpus())[0]);
+ nr_ioapics, cpumask_bits(es7000_target_cpus())[0]);
}
static int es7000_apicid_to_node(int logical_apicid)
@@ -572,7 +573,7 @@ static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
return 1;
}
-static unsigned int es7000_cpu_mask_to_apicid(const cpumask_t *cpumask)
+static unsigned int es7000_cpu_mask_to_apicid(const struct cpumask *cpumask)
{
unsigned int round = 0;
int cpu, uninitialized_var(apicid);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 00e6071cefc4..767fe7e46d68 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -389,6 +389,8 @@ struct io_apic {
unsigned int index;
unsigned int unused[3];
unsigned int data;
+ unsigned int unused2[11];
+ unsigned int eoi;
};
static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
@@ -397,6 +399,12 @@ static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
+ (mp_ioapics[idx].apicaddr & ~PAGE_MASK);
}
+static inline void io_apic_eoi(unsigned int apic, unsigned int vector)
+{
+ struct io_apic __iomem *io_apic = io_apic_base(apic);
+ writel(vector, &io_apic->eoi);
+}
+
static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
{
struct io_apic __iomem *io_apic = io_apic_base(apic);
@@ -546,16 +554,12 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq
apic = entry->apic;
pin = entry->pin;
-#ifdef CONFIG_INTR_REMAP
/*
* With interrupt-remapping, destination information comes
* from interrupt-remapping table entry.
*/
if (!irq_remapped(irq))
io_apic_write(apic, 0x11 + pin*2, dest);
-#else
- io_apic_write(apic, 0x11 + pin*2, dest);
-#endif
reg = io_apic_read(apic, 0x10 + pin*2);
reg &= ~IO_APIC_REDIR_VECTOR_MASK;
reg |= vector;
@@ -588,10 +592,12 @@ set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
if (assign_irq_vector(irq, cfg, mask))
return BAD_APICID;
- cpumask_and(desc->affinity, cfg->domain, mask);
+ /* check that before desc->addinity get updated */
set_extra_move_desc(desc, mask);
- return apic->cpu_mask_to_apicid_and(desc->affinity, cpu_online_mask);
+ cpumask_copy(desc->affinity, mask);
+
+ return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
}
static void
@@ -845,75 +851,106 @@ __setup("pirq=", ioapic_pirq_setup);
#endif /* CONFIG_X86_32 */
#ifdef CONFIG_INTR_REMAP
-/* I/O APIC RTE contents at the OS boot up */
-static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS];
+struct IO_APIC_route_entry **alloc_ioapic_entries(void)
+{
+ int apic;
+ struct IO_APIC_route_entry **ioapic_entries;
+
+ ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics,
+ GFP_ATOMIC);
+ if (!ioapic_entries)
+ return 0;
+
+ for (apic = 0; apic < nr_ioapics; apic++) {
+ ioapic_entries[apic] =
+ kzalloc(sizeof(struct IO_APIC_route_entry) *
+ nr_ioapic_registers[apic], GFP_ATOMIC);
+ if (!ioapic_entries[apic])
+ goto nomem;
+ }
+
+ return ioapic_entries;
+
+nomem:
+ while (--apic >= 0)
+ kfree(ioapic_entries[apic]);
+ kfree(ioapic_entries);
+
+ return 0;
+}
/*
- * Saves and masks all the unmasked IO-APIC RTE's
+ * Saves all the IO-APIC RTE's
*/
-int save_mask_IO_APIC_setup(void)
+int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
{
- union IO_APIC_reg_01 reg_01;
- unsigned long flags;
int apic, pin;
- /*
- * The number of IO-APIC IRQ registers (== #pins):
- */
+ if (!ioapic_entries)
+ return -ENOMEM;
+
for (apic = 0; apic < nr_ioapics; apic++) {
- spin_lock_irqsave(&ioapic_lock, flags);
- reg_01.raw = io_apic_read(apic, 1);
- spin_unlock_irqrestore(&ioapic_lock, flags);
- nr_ioapic_registers[apic] = reg_01.bits.entries+1;
+ if (!ioapic_entries[apic])
+ return -ENOMEM;
+
+ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
+ ioapic_entries[apic][pin] =
+ ioapic_read_entry(apic, pin);
}
+ return 0;
+}
+
+/*
+ * Mask all IO APIC entries.
+ */
+void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
+{
+ int apic, pin;
+
+ if (!ioapic_entries)
+ return;
+
for (apic = 0; apic < nr_ioapics; apic++) {
- early_ioapic_entries[apic] =
- kzalloc(sizeof(struct IO_APIC_route_entry) *
- nr_ioapic_registers[apic], GFP_KERNEL);
- if (!early_ioapic_entries[apic])
- goto nomem;
- }
+ if (!ioapic_entries[apic])
+ break;
- for (apic = 0; apic < nr_ioapics; apic++)
for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
struct IO_APIC_route_entry entry;
- entry = early_ioapic_entries[apic][pin] =
- ioapic_read_entry(apic, pin);
+ entry = ioapic_entries[apic][pin];
if (!entry.mask) {
entry.mask = 1;
ioapic_write_entry(apic, pin, entry);
}
}
-
- return 0;
-
-nomem:
- while (apic >= 0)
- kfree(early_ioapic_entries[apic--]);
- memset(early_ioapic_entries, 0,
- ARRAY_SIZE(early_ioapic_entries));
-
- return -ENOMEM;
+ }
}
-void restore_IO_APIC_setup(void)
+/*
+ * Restore IO APIC entries which was saved in ioapic_entries.
+ */
+int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
{
int apic, pin;
+ if (!ioapic_entries)
+ return -ENOMEM;
+
for (apic = 0; apic < nr_ioapics; apic++) {
- if (!early_ioapic_entries[apic])
- break;
+ if (!ioapic_entries[apic])
+ return -ENOMEM;
+
for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
ioapic_write_entry(apic, pin,
- early_ioapic_entries[apic][pin]);
- kfree(early_ioapic_entries[apic]);
- early_ioapic_entries[apic] = NULL;
+ ioapic_entries[apic][pin]);
}
+ return 0;
}
-void reinit_intr_remapped_IO_APIC(int intr_remapping)
+void reinit_intr_remapped_IO_APIC(int intr_remapping,
+ struct IO_APIC_route_entry **ioapic_entries)
+
{
/*
* for now plain restore of previous settings.
@@ -922,7 +959,17 @@ void reinit_intr_remapped_IO_APIC(int intr_remapping)
* table entries. for now, do a plain restore, and wait for
* the setup_IO_APIC_irqs() to do proper initialization.
*/
- restore_IO_APIC_setup();
+ restore_IO_APIC_setup(ioapic_entries);
+}
+
+void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries)
+{
+ int apic;
+
+ for (apic = 0; apic < nr_ioapics; apic++)
+ kfree(ioapic_entries[apic]);
+
+ kfree(ioapic_entries);
}
#endif
@@ -1411,9 +1458,7 @@ void __setup_vector_irq(int cpu)
}
static struct irq_chip ioapic_chip;
-#ifdef CONFIG_INTR_REMAP
static struct irq_chip ir_ioapic_chip;
-#endif
#define IOAPIC_AUTO -1
#define IOAPIC_EDGE 0
@@ -1452,7 +1497,6 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t
else
desc->status &= ~IRQ_LEVEL;
-#ifdef CONFIG_INTR_REMAP
if (irq_remapped(irq)) {
desc->status |= IRQ_MOVE_PCNTXT;
if (trigger)
@@ -1464,7 +1508,7 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t
handle_edge_irq, "edge");
return;
}
-#endif
+
if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
trigger == IOAPIC_LEVEL)
set_irq_chip_and_handler_name(irq, &ioapic_chip,
@@ -1478,14 +1522,13 @@ static void ioapic_register_intr(int irq, struct irq_desc *desc, unsigned long t
int setup_ioapic_entry(int apic_id, int irq,
struct IO_APIC_route_entry *entry,
unsigned int destination, int trigger,
- int polarity, int vector)
+ int polarity, int vector, int pin)
{
/*
* add it to the IO-APIC irq-routing table:
*/
memset(entry,0,sizeof(*entry));
-#ifdef CONFIG_INTR_REMAP
if (intr_remapping_enabled) {
struct intel_iommu *iommu = map_ioapic_to_ir(apic_id);
struct irte irte;
@@ -1504,7 +1547,14 @@ int setup_ioapic_entry(int apic_id, int irq,
irte.present = 1;
irte.dst_mode = apic->irq_dest_mode;
- irte.trigger_mode = trigger;
+ /*
+ * Trigger mode in the IRTE will always be edge, and the
+ * actual level or edge trigger will be setup in the IO-APIC
+ * RTE. This will help simplify level triggered irq migration.
+ * For more details, see the comments above explainig IO-APIC
+ * irq migration in the presence of interrupt-remapping.
+ */
+ irte.trigger_mode = 0;
irte.dlvry_mode = apic->irq_delivery_mode;
irte.vector = vector;
irte.dest_id = IRTE_DEST(destination);
@@ -1515,18 +1565,21 @@ int setup_ioapic_entry(int apic_id, int irq,
ir_entry->zero = 0;
ir_entry->format = 1;
ir_entry->index = (index & 0x7fff);
- } else
-#endif
- {
+ /*
+ * IO-APIC RTE will be configured with virtual vector.
+ * irq handler will do the explicit EOI to the io-apic.
+ */
+ ir_entry->vector = pin;
+ } else {
entry->delivery_mode = apic->irq_delivery_mode;
entry->dest_mode = apic->irq_dest_mode;
entry->dest = destination;
+ entry->vector = vector;
}
entry->mask = 0; /* enable IRQ */
entry->trigger = trigger;
entry->polarity = polarity;
- entry->vector = vector;
/* Mask level triggered irqs.
* Use IRQ_DELAYED_DISABLE for edge triggered irqs.
@@ -1561,7 +1614,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
if (setup_ioapic_entry(mp_ioapics[apic_id].apicid, irq, &entry,
- dest, trigger, polarity, cfg->vector)) {
+ dest, trigger, polarity, cfg->vector, pin)) {
printk("Failed to setup ioapic entry for ioapic %d, pin %d\n",
mp_ioapics[apic_id].apicid, pin);
__clear_irq_vector(irq, cfg);
@@ -1642,10 +1695,8 @@ static void __init setup_timer_IRQ0_pin(unsigned int apic_id, unsigned int pin,
{
struct IO_APIC_route_entry entry;
-#ifdef CONFIG_INTR_REMAP
if (intr_remapping_enabled)
return;
-#endif
memset(&entry, 0, sizeof(entry));
@@ -2040,8 +2091,13 @@ void disable_IO_APIC(void)
* If the i8259 is routed through an IOAPIC
* Put that IOAPIC in virtual wire mode
* so legacy interrupts can be delivered.
+ *
+ * With interrupt-remapping, for now we will use virtual wire A mode,
+ * as virtual wire B is little complex (need to configure both
+ * IOAPIC RTE aswell as interrupt-remapping table entry).
+ * As this gets called during crash dump, keep this simple for now.
*/
- if (ioapic_i8259.pin != -1) {
+ if (ioapic_i8259.pin != -1 && !intr_remapping_enabled) {
struct IO_APIC_route_entry entry;
memset(&entry, 0, sizeof(entry));
@@ -2061,7 +2117,10 @@ void disable_IO_APIC(void)
ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry);
}
- disconnect_bsp_APIC(ioapic_i8259.pin != -1);
+ /*
+ * Use virtual wire A mode when interrupt remapping is enabled.
+ */
+ disconnect_bsp_APIC(!intr_remapping_enabled && ioapic_i8259.pin != -1);
}
#ifdef CONFIG_X86_32
@@ -2303,37 +2362,24 @@ static int ioapic_retrigger_irq(unsigned int irq)
#ifdef CONFIG_SMP
#ifdef CONFIG_INTR_REMAP
-static void ir_irq_migration(struct work_struct *work);
-
-static DECLARE_DELAYED_WORK(ir_migration_work, ir_irq_migration);
/*
* Migrate the IO-APIC irq in the presence of intr-remapping.
*
- * For edge triggered, irq migration is a simple atomic update(of vector
- * and cpu destination) of IRTE and flush the hardware cache.
- *
- * For level triggered, we need to modify the io-apic RTE aswell with the update
- * vector information, along with modifying IRTE with vector and destination.
- * So irq migration for level triggered is little bit more complex compared to
- * edge triggered migration. But the good news is, we use the same algorithm
- * for level triggered migration as we have today, only difference being,
- * we now initiate the irq migration from process context instead of the
- * interrupt context.
+ * For both level and edge triggered, irq migration is a simple atomic
+ * update(of vector and cpu destination) of IRTE and flush the hardware cache.
*
- * In future, when we do a directed EOI (combined with cpu EOI broadcast
- * suppression) to the IO-APIC, level triggered irq migration will also be
- * as simple as edge triggered migration and we can do the irq migration
- * with a simple atomic update to IO-APIC RTE.
+ * For level triggered, we eliminate the io-apic RTE modification (with the
+ * updated vector information), by using a virtual vector (io-apic pin number).
+ * Real vector that is used for interrupting cpu will be coming from
+ * the interrupt-remapping table entry.
*/
static void
migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
{
struct irq_cfg *cfg;
struct irte irte;
- int modify_ioapic_rte;
unsigned int dest;
- unsigned long flags;
unsigned int irq;
if (!cpumask_intersects(mask, cpu_online_mask))
@@ -2351,13 +2397,6 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
dest = apic->cpu_mask_to_apicid_and(cfg->domain, mask);
- modify_ioapic_rte = desc->status & IRQ_LEVEL;
- if (modify_ioapic_rte) {
- spin_lock_irqsave(&ioapic_lock, flags);
- __target_IO_APIC_irq(irq, dest, cfg);
- spin_unlock_irqrestore(&ioapic_lock, flags);
- }
-
irte.vector = cfg->vector;
irte.dest_id = IRTE_DEST(dest);
@@ -2372,73 +2411,12 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
cpumask_copy(desc->affinity, mask);
}
-static int migrate_irq_remapped_level_desc(struct irq_desc *desc)
-{
- int ret = -1;
- struct irq_cfg *cfg = desc->chip_data;
-
- mask_IO_APIC_irq_desc(desc);
-
- if (io_apic_level_ack_pending(cfg)) {
- /*
- * Interrupt in progress. Migrating irq now will change the
- * vector information in the IO-APIC RTE and that will confuse
- * the EOI broadcast performed by cpu.
- * So, delay the irq migration to the next instance.
- */
- schedule_delayed_work(&ir_migration_work, 1);
- goto unmask;
- }
-
- /* everthing is clear. we have right of way */
- migrate_ioapic_irq_desc(desc, desc->pending_mask);
-
- ret = 0;
- desc->status &= ~IRQ_MOVE_PENDING;
- cpumask_clear(desc->pending_mask);
-
-unmask:
- unmask_IO_APIC_irq_desc(desc);
-
- return ret;
-}
-
-static void ir_irq_migration(struct work_struct *work)
-{
- unsigned int irq;
- struct irq_desc *desc;
-
- for_each_irq_desc(irq, desc) {
- if (desc->status & IRQ_MOVE_PENDING) {
- unsigned long flags;
-
- spin_lock_irqsave(&desc->lock, flags);
- if (!desc->chip->set_affinity ||
- !(desc->status & IRQ_MOVE_PENDING)) {
- desc->status &= ~IRQ_MOVE_PENDING;
- spin_unlock_irqrestore(&desc->lock, flags);
- continue;
- }
-
- desc->chip->set_affinity(irq, desc->pending_mask);
- spin_unlock_irqrestore(&desc->lock, flags);
- }
- }
-}
-
/*
* Migrates the IRQ destination in the process context.
*/
static void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
const struct cpumask *mask)
{
- if (desc->status & IRQ_LEVEL) {
- desc->status |= IRQ_MOVE_PENDING;
- cpumask_copy(desc->pending_mask, mask);
- migrate_irq_remapped_level_desc(desc);
- return;
- }
-
migrate_ioapic_irq_desc(desc, mask);
}
static void set_ir_ioapic_affinity_irq(unsigned int irq,
@@ -2448,6 +2426,11 @@ static void set_ir_ioapic_affinity_irq(unsigned int irq,
set_ir_ioapic_affinity_irq_desc(desc, mask);
}
+#else
+static inline void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
+ const struct cpumask *mask)
+{
+}
#endif
asmlinkage void smp_irq_move_cleanup_interrupt(void)
@@ -2461,6 +2444,7 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
me = smp_processor_id();
for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; vector++) {
unsigned int irq;
+ unsigned int irr;
struct irq_desc *desc;
struct irq_cfg *cfg;
irq = __get_cpu_var(vector_irq)[vector];
@@ -2480,6 +2464,18 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
if (vector == cfg->vector && cpumask_test_cpu(me, cfg->domain))
goto unlock;
+ irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
+ /*
+ * Check if the vector that needs to be cleanedup is
+ * registered at the cpu's IRR. If so, then this is not
+ * the best time to clean it up. Lets clean it up in the
+ * next attempt by sending another IRQ_MOVE_CLEANUP_VECTOR
+ * to myself.
+ */
+ if (irr & (1 << (vector % 32))) {
+ apic->send_IPI_self(IRQ_MOVE_CLEANUP_VECTOR);
+ goto unlock;
+ }
__get_cpu_var(vector_irq)[vector] = -1;
cfg->move_cleanup_count--;
unlock:
@@ -2528,17 +2524,51 @@ static void irq_complete_move(struct irq_desc **descp)
static inline void irq_complete_move(struct irq_desc **descp) {}
#endif
-#ifdef CONFIG_INTR_REMAP
+#ifdef CONFIG_X86_X2APIC
+static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
+{
+ int apic, pin;
+ struct irq_pin_list *entry;
+
+ entry = cfg->irq_2_pin;
+ for (;;) {
+
+ if (!entry)
+ break;
+
+ apic = entry->apic;
+ pin = entry->pin;
+ io_apic_eoi(apic, pin);
+ entry = entry->next;
+ }
+}
+
+static void
+eoi_ioapic_irq(struct irq_desc *desc)
+{
+ struct irq_cfg *cfg;
+ unsigned long flags;
+ unsigned int irq;
+
+ irq = desc->irq;
+ cfg = desc->chip_data;
+
+ spin_lock_irqsave(&ioapic_lock, flags);
+ __eoi_ioapic_irq(irq, cfg);
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
static void ack_x2apic_level(unsigned int irq)
{
+ struct irq_desc *desc = irq_to_desc(irq);
ack_x2APIC_irq();
+ eoi_ioapic_irq(desc);
}
static void ack_x2apic_edge(unsigned int irq)
{
ack_x2APIC_irq();
}
-
#endif
static void ack_apic_edge(unsigned int irq)
@@ -2649,6 +2679,26 @@ static void ack_apic_level(unsigned int irq)
#endif
}
+#ifdef CONFIG_INTR_REMAP
+static void ir_ack_apic_edge(unsigned int irq)
+{
+#ifdef CONFIG_X86_X2APIC
+ if (x2apic_enabled())
+ return ack_x2apic_edge(irq);
+#endif
+ return ack_apic_edge(irq);
+}
+
+static void ir_ack_apic_level(unsigned int irq)
+{
+#ifdef CONFIG_X86_X2APIC
+ if (x2apic_enabled())
+ return ack_x2apic_level(irq);
+#endif
+ return ack_apic_level(irq);
+}
+#endif /* CONFIG_INTR_REMAP */
+
static struct irq_chip ioapic_chip __read_mostly = {
.name = "IO-APIC",
.startup = startup_ioapic_irq,
@@ -2662,20 +2712,20 @@ static struct irq_chip ioapic_chip __read_mostly = {
.retrigger = ioapic_retrigger_irq,
};
-#ifdef CONFIG_INTR_REMAP
static struct irq_chip ir_ioapic_chip __read_mostly = {
.name = "IR-IO-APIC",
.startup = startup_ioapic_irq,
.mask = mask_IO_APIC_irq,
.unmask = unmask_IO_APIC_irq,
- .ack = ack_x2apic_edge,
- .eoi = ack_x2apic_level,
+#ifdef CONFIG_INTR_REMAP
+ .ack = ir_ack_apic_edge,
+ .eoi = ir_ack_apic_level,
#ifdef CONFIG_SMP
.set_affinity = set_ir_ioapic_affinity_irq,
#endif
+#endif
.retrigger = ioapic_retrigger_irq,
};
-#endif
static inline void init_IO_APIC_traps(void)
{
@@ -2901,10 +2951,8 @@ static inline void __init check_timer(void)
* 8259A.
*/
if (pin1 == -1) {
-#ifdef CONFIG_INTR_REMAP
if (intr_remapping_enabled)
panic("BIOS bug: timer not connected to IO-APIC");
-#endif
pin1 = pin2;
apic1 = apic2;
no_pin1 = 1;
@@ -2940,10 +2988,8 @@ static inline void __init check_timer(void)
clear_IO_APIC_pin(0, pin1);
goto out;
}
-#ifdef CONFIG_INTR_REMAP
if (intr_remapping_enabled)
panic("timer doesn't work through Interrupt-remapped IO-APIC");
-#endif
local_irq_disable();
clear_IO_APIC_pin(apic1, pin1);
if (!no_pin1)
@@ -3237,9 +3283,7 @@ void destroy_irq(unsigned int irq)
if (desc)
desc->chip_data = cfg;
-#ifdef CONFIG_INTR_REMAP
free_irte(irq);
-#endif
spin_lock_irqsave(&vector_lock, flags);
__clear_irq_vector(irq, cfg);
spin_unlock_irqrestore(&vector_lock, flags);
@@ -3265,7 +3309,6 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms
dest = apic->cpu_mask_to_apicid_and(cfg->domain, apic->target_cpus());
-#ifdef CONFIG_INTR_REMAP
if (irq_remapped(irq)) {
struct irte irte;
int ir_index;
@@ -3291,10 +3334,13 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms
MSI_ADDR_IR_SHV |
MSI_ADDR_IR_INDEX1(ir_index) |
MSI_ADDR_IR_INDEX2(ir_index);
- } else
-#endif
- {
- msg->address_hi = MSI_ADDR_BASE_HI;
+ } else {
+ if (x2apic_enabled())
+ msg->address_hi = MSI_ADDR_BASE_HI |
+ MSI_ADDR_EXT_DEST_ID(dest);
+ else
+ msg->address_hi = MSI_ADDR_BASE_HI;
+
msg->address_lo =
MSI_ADDR_BASE_LO |
((apic->irq_dest_mode == 0) ?
@@ -3394,15 +3440,16 @@ static struct irq_chip msi_chip = {
.retrigger = ioapic_retrigger_irq,
};
-#ifdef CONFIG_INTR_REMAP
static struct irq_chip msi_ir_chip = {
.name = "IR-PCI-MSI",
.unmask = unmask_msi_irq,
.mask = mask_msi_irq,
- .ack = ack_x2apic_edge,
+#ifdef CONFIG_INTR_REMAP
+ .ack = ir_ack_apic_edge,
#ifdef CONFIG_SMP
.set_affinity = ir_set_msi_irq_affinity,
#endif
+#endif
.retrigger = ioapic_retrigger_irq,
};
@@ -3432,7 +3479,6 @@ static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec)
}
return index;
}
-#endif
static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
{
@@ -3446,7 +3492,6 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
set_irq_msi(irq, msidesc);
write_msi_msg(irq, &msg);
-#ifdef CONFIG_INTR_REMAP
if (irq_remapped(irq)) {
struct irq_desc *desc = irq_to_desc(irq);
/*
@@ -3455,7 +3500,6 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
desc->status |= IRQ_MOVE_PCNTXT;
set_irq_chip_and_handler_name(irq, &msi_ir_chip, handle_edge_irq, "edge");
} else
-#endif
set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge");
dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq);
@@ -3469,11 +3513,12 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
int ret, sub_handle;
struct msi_desc *msidesc;
unsigned int irq_want;
-
-#ifdef CONFIG_INTR_REMAP
- struct intel_iommu *iommu = 0;
+ struct intel_iommu *iommu = NULL;
int index = 0;
-#endif
+
+ /* x86 doesn't support multiple MSI yet */
+ if (type == PCI_CAP_ID_MSI && nvec > 1)
+ return 1;
irq_want = nr_irqs_gsi;
sub_handle = 0;
@@ -3482,7 +3527,6 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (irq == 0)
return -1;
irq_want = irq + 1;
-#ifdef CONFIG_INTR_REMAP
if (!intr_remapping_enabled)
goto no_ir;
@@ -3510,7 +3554,6 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
set_irte_irq(irq, iommu, index, sub_handle);
}
no_ir:
-#endif
ret = setup_msi_irq(dev, msidesc, irq);
if (ret < 0)
goto error;
@@ -3528,7 +3571,7 @@ void arch_teardown_msi_irq(unsigned int irq)
destroy_irq(irq);
}
-#ifdef CONFIG_DMAR
+#if defined (CONFIG_DMAR) || defined (CONFIG_INTR_REMAP)
#ifdef CONFIG_SMP
static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
{
@@ -3609,7 +3652,7 @@ static void hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
#endif /* CONFIG_SMP */
-struct irq_chip hpet_msi_type = {
+static struct irq_chip hpet_msi_type = {
.name = "HPET_MSI",
.unmask = hpet_msi_unmask,
.mask = hpet_msi_mask,
@@ -4045,11 +4088,9 @@ void __init setup_ioapic_dest(void)
else
mask = apic->target_cpus();
-#ifdef CONFIG_INTR_REMAP
if (intr_remapping_enabled)
set_ir_ioapic_affinity_irq_desc(desc, mask);
else
-#endif
set_ioapic_affinity_irq_desc(desc, mask);
}
@@ -4142,9 +4183,12 @@ static int __init ioapic_insert_resources(void)
struct resource *r = ioapic_resources;
if (!r) {
- printk(KERN_ERR
- "IO APIC resources could be not be allocated.\n");
- return -1;
+ if (nr_ioapics > 0) {
+ printk(KERN_ERR
+ "IO APIC resources couldn't be allocated.\n");
+ return -1;
+ }
+ return 0;
}
for (i = 0; i < nr_ioapics; i++) {
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c
index bdfad80c3cf1..d6bd62407152 100644
--- a/arch/x86/kernel/apic/nmi.c
+++ b/arch/x86/kernel/apic/nmi.c
@@ -39,7 +39,7 @@
int unknown_nmi_panic;
int nmi_watchdog_enabled;
-static cpumask_t backtrace_mask = CPU_MASK_NONE;
+static cpumask_var_t backtrace_mask;
/* nmi_active:
* >0: the lapic NMI watchdog is active, but can be disabled
@@ -138,6 +138,7 @@ int __init check_nmi_watchdog(void)
if (!prev_nmi_count)
goto error;
+ alloc_cpumask_var(&backtrace_mask, GFP_KERNEL);
printk(KERN_INFO "Testing NMI watchdog ... ");
#ifdef CONFIG_SMP
@@ -413,14 +414,14 @@ nmi_watchdog_tick(struct pt_regs *regs, unsigned reason)
touched = 1;
}
- if (cpu_isset(cpu, backtrace_mask)) {
+ if (cpumask_test_cpu(cpu, backtrace_mask)) {
static DEFINE_SPINLOCK(lock); /* Serialise the printks */
spin_lock(&lock);
printk(KERN_WARNING "NMI backtrace for cpu %d\n", cpu);
dump_stack();
spin_unlock(&lock);
- cpu_clear(cpu, backtrace_mask);
+ cpumask_clear_cpu(cpu, backtrace_mask);
}
/* Could check oops_in_progress here too, but it's safer not to */
@@ -554,10 +555,10 @@ void __trigger_all_cpu_backtrace(void)
{
int i;
- backtrace_mask = cpu_online_map;
+ cpumask_copy(backtrace_mask, cpu_online_mask);
/* Wait for up to 10 seconds for all CPUs to do the backtrace */
for (i = 0; i < 10 * 1000; i++) {
- if (cpus_empty(backtrace_mask))
+ if (cpumask_empty(backtrace_mask))
break;
mdelay(1);
}
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c
index ba2fc6465534..533e59c6fc82 100644
--- a/arch/x86/kernel/apic/numaq_32.c
+++ b/arch/x86/kernel/apic/numaq_32.c
@@ -334,9 +334,9 @@ static inline void numaq_smp_callin_clear_local_apic(void)
clear_local_APIC();
}
-static inline const cpumask_t *numaq_target_cpus(void)
+static inline const struct cpumask *numaq_target_cpus(void)
{
- return &CPU_MASK_ALL;
+ return cpu_all_mask;
}
static inline unsigned long
@@ -427,7 +427,7 @@ static inline int numaq_check_phys_apicid_present(int boot_cpu_physical_apicid)
* We use physical apicids here, not logical, so just return the default
* physical broadcast to stop people from breaking us
*/
-static inline unsigned int numaq_cpu_mask_to_apicid(const cpumask_t *cpumask)
+static unsigned int numaq_cpu_mask_to_apicid(const struct cpumask *cpumask)
{
return 0x0F;
}
@@ -462,7 +462,7 @@ static int probe_numaq(void)
return found_numaq;
}
-static void numaq_vector_allocation_domain(int cpu, cpumask_t *retmask)
+static void numaq_vector_allocation_domain(int cpu, struct cpumask *retmask)
{
/* Careful. Some cpus do not strictly honor the set of cpus
* specified in the interrupt destination when using lowest
@@ -472,7 +472,8 @@ static void numaq_vector_allocation_domain(int cpu, cpumask_t *retmask)
* deliver interrupts to the wrong hyperthread when only one
* hyperthread was specified in the interrupt desitination.
*/
- *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
+ cpumask_clear(retmask);
+ cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
}
static void numaq_setup_portio_remap(void)
diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index 141c99a1c264..01eda2ac65e4 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -83,7 +83,8 @@ static void default_vector_allocation_domain(int cpu, struct cpumask *retmask)
* deliver interrupts to the wrong hyperthread when only one
* hyperthread was specified in the interrupt desitination.
*/
- *retmask = (cpumask_t) { { [0] = APIC_ALL_CPUS } };
+ cpumask_clear(retmask);
+ cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
}
/* should be called last. */
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index 8d7748efe6a8..1783652bb0e5 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -68,6 +68,13 @@ void __init default_setup_apic_routing(void)
apic = &apic_physflat;
printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
}
+
+ /*
+ * Now that apic routing model is selected, configure the
+ * fault handling for intr remapping.
+ */
+ if (intr_remapping_enabled)
+ enable_drhd_fault_handling();
}
/* Same for both flat and physical. */
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c
index aac52fa873ff..9cfe1f415d81 100644
--- a/arch/x86/kernel/apic/summit_32.c
+++ b/arch/x86/kernel/apic/summit_32.c
@@ -53,23 +53,19 @@ static unsigned summit_get_apic_id(unsigned long x)
return (x >> 24) & 0xFF;
}
-static inline void summit_send_IPI_mask(const cpumask_t *mask, int vector)
+static inline void summit_send_IPI_mask(const struct cpumask *mask, int vector)
{
default_send_IPI_mask_sequence_logical(mask, vector);
}
static void summit_send_IPI_allbutself(int vector)
{
- cpumask_t mask = cpu_online_map;
- cpu_clear(smp_processor_id(), mask);
-
- if (!cpus_empty(mask))
- summit_send_IPI_mask(&mask, vector);
+ default_send_IPI_mask_allbutself_logical(cpu_online_mask, vector);
}
static void summit_send_IPI_all(int vector)
{
- summit_send_IPI_mask(&cpu_online_map, vector);
+ summit_send_IPI_mask(cpu_online_mask, vector);
}
#include <asm/tsc.h>
@@ -186,13 +182,13 @@ static inline int is_WPEG(struct rio_detail *rio){
#define SUMMIT_APIC_DFR_VALUE (APIC_DFR_CLUSTER)
-static const cpumask_t *summit_target_cpus(void)
+static const struct cpumask *summit_target_cpus(void)
{
/* CPU_MASK_ALL (0xff) has undefined behaviour with
* dest_LowestPrio mode logical clustered apic interrupt routing
* Just start on cpu 0. IRQ balancing will spread load
*/
- return &cpumask_of_cpu(0);
+ return cpumask_of(0);
}
static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid)
@@ -289,7 +285,7 @@ static int summit_check_phys_apicid_present(int boot_cpu_physical_apicid)
return 1;
}
-static unsigned int summit_cpu_mask_to_apicid(const cpumask_t *cpumask)
+static unsigned int summit_cpu_mask_to_apicid(const struct cpumask *cpumask)
{
unsigned int round = 0;
int cpu, apicid = 0;
@@ -346,7 +342,7 @@ static int probe_summit(void)
return 0;
}
-static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask)
+static void summit_vector_allocation_domain(int cpu, struct cpumask *retmask)
{
/* Careful. Some cpus do not strictly honor the set of cpus
* specified in the interrupt destination when using lowest
@@ -356,7 +352,8 @@ static void summit_vector_allocation_domain(int cpu, cpumask_t *retmask)
* deliver interrupts to the wrong hyperthread when only one
* hyperthread was specified in the interrupt desitination.
*/
- *retmask = (cpumask_t){ { [0] = APIC_ALL_CPUS, } };
+ cpumask_clear(retmask);
+ cpumask_bits(retmask)[0] = APIC_ALL_CPUS;
}
#ifdef CONFIG_X86_SUMMIT_NUMA
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c
index 8fb87b6dd633..4a903e2f0d17 100644
--- a/arch/x86/kernel/apic/x2apic_cluster.c
+++ b/arch/x86/kernel/apic/x2apic_cluster.c
@@ -57,6 +57,8 @@ static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)
unsigned long query_cpu;
unsigned long flags;
+ x2apic_wrmsr_fence();
+
local_irq_save(flags);
for_each_cpu(query_cpu, mask) {
__x2apic_send_IPI_dest(
@@ -73,6 +75,8 @@ static void
unsigned long query_cpu;
unsigned long flags;
+ x2apic_wrmsr_fence();
+
local_irq_save(flags);
for_each_cpu(query_cpu, mask) {
if (query_cpu == this_cpu)
@@ -90,6 +94,8 @@ static void x2apic_send_IPI_allbutself(int vector)
unsigned long query_cpu;
unsigned long flags;
+ x2apic_wrmsr_fence();
+
local_irq_save(flags);
for_each_online_cpu(query_cpu) {
if (query_cpu == this_cpu)
diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c
index 23625b9f98b2..a284359627e7 100644
--- a/arch/x86/kernel/apic/x2apic_phys.c
+++ b/arch/x86/kernel/apic/x2apic_phys.c
@@ -58,6 +58,8 @@ static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)
unsigned long query_cpu;
unsigned long flags;
+ x2apic_wrmsr_fence();
+
local_irq_save(flags);
for_each_cpu(query_cpu, mask) {
__x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu),
@@ -73,6 +75,8 @@ static void
unsigned long query_cpu;
unsigned long flags;
+ x2apic_wrmsr_fence();
+
local_irq_save(flags);
for_each_cpu(query_cpu, mask) {
if (query_cpu != this_cpu)
@@ -89,6 +93,8 @@ static void x2apic_send_IPI_allbutself(int vector)
unsigned long query_cpu;
unsigned long flags;
+ x2apic_wrmsr_fence();
+
local_irq_save(flags);
for_each_online_cpu(query_cpu) {
if (query_cpu == this_cpu)
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index 1bd6da1f8fad..1248318436e8 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -118,17 +118,12 @@ static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip)
static void uv_send_IPI_one(int cpu, int vector)
{
- unsigned long val, apicid;
+ unsigned long apicid;
int pnode;
apicid = per_cpu(x86_cpu_to_apicid, cpu);
pnode = uv_apicid_to_pnode(apicid);
-
- val = (1UL << UVH_IPI_INT_SEND_SHFT) |
- (apicid << UVH_IPI_INT_APIC_ID_SHFT) |
- (vector << UVH_IPI_INT_VECTOR_SHFT);
-
- uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
+ uv_hub_send_ipi(pnode, apicid, vector);
}
static void uv_send_IPI_mask(const struct cpumask *mask, int vector)
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 10033fe718e0..49e0939bac42 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -466,7 +466,7 @@ static const lookup_t error_table[] = {
* @err: APM BIOS return code
*
* Write a meaningful log entry to the kernel log in the event of
- * an APM error.
+ * an APM error. Note that this also handles (negative) kernel errors.
*/
static void apm_error(char *str, int err)
@@ -478,43 +478,14 @@ static void apm_error(char *str, int err)
break;
if (i < ERROR_COUNT)
printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg);
+ else if (err < 0)
+ printk(KERN_NOTICE "apm: %s: linux error code %i\n", str, err);
else
printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n",
str, err);
}
/*
- * Lock APM functionality to physical CPU 0
- */
-
-#ifdef CONFIG_SMP
-
-static cpumask_t apm_save_cpus(void)
-{
- cpumask_t x = current->cpus_allowed;
- /* Some bioses don't like being called from CPU != 0 */
- set_cpus_allowed(current, cpumask_of_cpu(0));
- BUG_ON(smp_processor_id() != 0);
- return x;
-}
-
-static inline void apm_restore_cpus(cpumask_t mask)
-{
- set_cpus_allowed(current, mask);
-}
-
-#else
-
-/*
- * No CPU lockdown needed on a uniprocessor
- */
-
-#define apm_save_cpus() (current->cpus_allowed)
-#define apm_restore_cpus(x) (void)(x)
-
-#endif
-
-/*
* These are the actual BIOS calls. Depending on APM_ZERO_SEGS and
* apm_info.allow_ints, we are being really paranoid here! Not only
* are interrupts disabled, but all the segment registers (except SS)
@@ -568,16 +539,23 @@ static inline void apm_irq_restore(unsigned long flags)
# define APM_DO_RESTORE_SEGS
#endif
+struct apm_bios_call {
+ u32 func;
+ /* In and out */
+ u32 ebx;
+ u32 ecx;
+ /* Out only */
+ u32 eax;
+ u32 edx;
+ u32 esi;
+
+ /* Error: -ENOMEM, or bits 8-15 of eax */
+ int err;
+};
+
/**
- * apm_bios_call - Make an APM BIOS 32bit call
- * @func: APM function to execute
- * @ebx_in: EBX register for call entry
- * @ecx_in: ECX register for call entry
- * @eax: EAX register return
- * @ebx: EBX register return
- * @ecx: ECX register return
- * @edx: EDX register return
- * @esi: ESI register return
+ * __apm_bios_call - Make an APM BIOS 32bit call
+ * @_call: pointer to struct apm_bios_call.
*
* Make an APM call using the 32bit protected mode interface. The
* caller is responsible for knowing if APM BIOS is configured and
@@ -586,80 +564,142 @@ static inline void apm_irq_restore(unsigned long flags)
* flag is loaded into AL. If there is an error, then the error
* code is returned in AH (bits 8-15 of eax) and this function
* returns non-zero.
+ *
+ * Note: this makes the call on the current CPU.
*/
-
-static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
- u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, u32 *esi)
+static long __apm_bios_call(void *_call)
{
APM_DECL_SEGS
unsigned long flags;
- cpumask_t cpus;
int cpu;
struct desc_struct save_desc_40;
struct desc_struct *gdt;
-
- cpus = apm_save_cpus();
+ struct apm_bios_call *call = _call;
cpu = get_cpu();
+ BUG_ON(cpu != 0);
gdt = get_cpu_gdt_table(cpu);
save_desc_40 = gdt[0x40 / 8];
gdt[0x40 / 8] = bad_bios_desc;
apm_irq_save(flags);
APM_DO_SAVE_SEGS;
- apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
+ apm_bios_call_asm(call->func, call->ebx, call->ecx,
+ &call->eax, &call->ebx, &call->ecx, &call->edx,
+ &call->esi);
APM_DO_RESTORE_SEGS;
apm_irq_restore(flags);
gdt[0x40 / 8] = save_desc_40;
put_cpu();
- apm_restore_cpus(cpus);
- return *eax & 0xff;
+ return call->eax & 0xff;
+}
+
+/* Run __apm_bios_call or __apm_bios_call_simple on CPU 0 */
+static int on_cpu0(long (*fn)(void *), struct apm_bios_call *call)
+{
+ int ret;
+
+ /* Don't bother with work_on_cpu in the common case, so we don't
+ * have to worry about OOM or overhead. */
+ if (get_cpu() == 0) {
+ ret = fn(call);
+ put_cpu();
+ } else {
+ put_cpu();
+ ret = work_on_cpu(0, fn, call);
+ }
+
+ /* work_on_cpu can fail with -ENOMEM */
+ if (ret < 0)
+ call->err = ret;
+ else
+ call->err = (call->eax >> 8) & 0xff;
+
+ return ret;
}
/**
- * apm_bios_call_simple - make a simple APM BIOS 32bit call
- * @func: APM function to invoke
- * @ebx_in: EBX register value for BIOS call
- * @ecx_in: ECX register value for BIOS call
- * @eax: EAX register on return from the BIOS call
+ * apm_bios_call - Make an APM BIOS 32bit call (on CPU 0)
+ * @call: the apm_bios_call registers.
+ *
+ * If there is an error, it is returned in @call.err.
+ */
+static int apm_bios_call(struct apm_bios_call *call)
+{
+ return on_cpu0(__apm_bios_call, call);
+}
+
+/**
+ * __apm_bios_call_simple - Make an APM BIOS 32bit call (on CPU 0)
+ * @_call: pointer to struct apm_bios_call.
*
* Make a BIOS call that returns one value only, or just status.
* If there is an error, then the error code is returned in AH
- * (bits 8-15 of eax) and this function returns non-zero. This is
- * used for simpler BIOS operations. This call may hold interrupts
- * off for a long time on some laptops.
+ * (bits 8-15 of eax) and this function returns non-zero (it can
+ * also return -ENOMEM). This is used for simpler BIOS operations.
+ * This call may hold interrupts off for a long time on some laptops.
+ *
+ * Note: this makes the call on the current CPU.
*/
-
-static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
+static long __apm_bios_call_simple(void *_call)
{
u8 error;
APM_DECL_SEGS
unsigned long flags;
- cpumask_t cpus;
int cpu;
struct desc_struct save_desc_40;
struct desc_struct *gdt;
-
- cpus = apm_save_cpus();
+ struct apm_bios_call *call = _call;
cpu = get_cpu();
+ BUG_ON(cpu != 0);
gdt = get_cpu_gdt_table(cpu);
save_desc_40 = gdt[0x40 / 8];
gdt[0x40 / 8] = bad_bios_desc;
apm_irq_save(flags);
APM_DO_SAVE_SEGS;
- error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
+ error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx,
+ &call->eax);
APM_DO_RESTORE_SEGS;
apm_irq_restore(flags);
gdt[0x40 / 8] = save_desc_40;
put_cpu();
- apm_restore_cpus(cpus);
return error;
}
/**
+ * apm_bios_call_simple - make a simple APM BIOS 32bit call
+ * @func: APM function to invoke
+ * @ebx_in: EBX register value for BIOS call
+ * @ecx_in: ECX register value for BIOS call
+ * @eax: EAX register on return from the BIOS call
+ * @err: bits
+ *
+ * Make a BIOS call that returns one value only, or just status.
+ * If there is an error, then the error code is returned in @err
+ * and this function returns non-zero. This is used for simpler
+ * BIOS operations. This call may hold interrupts off for a long
+ * time on some laptops.
+ */
+static int apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax,
+ int *err)
+{
+ struct apm_bios_call call;
+ int ret;
+
+ call.func = func;
+ call.ebx = ebx_in;
+ call.ecx = ecx_in;
+
+ ret = on_cpu0(__apm_bios_call_simple, &call);
+ *eax = call.eax;
+ *err = call.err;
+ return ret;
+}
+
+/**
* apm_driver_version - APM driver version
* @val: loaded with the APM version on return
*
@@ -678,9 +718,10 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
static int apm_driver_version(u_short *val)
{
u32 eax;
+ int err;
- if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax))
- return (eax >> 8) & 0xff;
+ if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax, &err))
+ return err;
*val = eax;
return APM_SUCCESS;
}
@@ -701,22 +742,21 @@ static int apm_driver_version(u_short *val)
* that APM 1.2 is in use. If no messges are pending the value 0x80
* is returned (No power management events pending).
*/
-
static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
{
- u32 eax;
- u32 ebx;
- u32 ecx;
- u32 dummy;
+ struct apm_bios_call call;
- if (apm_bios_call(APM_FUNC_GET_EVENT, 0, 0, &eax, &ebx, &ecx,
- &dummy, &dummy))
- return (eax >> 8) & 0xff;
- *event = ebx;
+ call.func = APM_FUNC_GET_EVENT;
+ call.ebx = call.ecx = 0;
+
+ if (apm_bios_call(&call))
+ return call.err;
+
+ *event = call.ebx;
if (apm_info.connection_version < 0x0102)
*info = ~0; /* indicate info not valid */
else
- *info = ecx;
+ *info = call.ecx;
return APM_SUCCESS;
}
@@ -737,9 +777,10 @@ static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
static int set_power_state(u_short what, u_short state)
{
u32 eax;
+ int err;
- if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax))
- return (eax >> 8) & 0xff;
+ if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax, &err))
+ return err;
return APM_SUCCESS;
}
@@ -770,6 +811,7 @@ static int apm_do_idle(void)
u8 ret = 0;
int idled = 0;
int polling;
+ int err;
polling = !!(current_thread_info()->status & TS_POLLING);
if (polling) {
@@ -782,7 +824,7 @@ static int apm_do_idle(void)
}
if (!need_resched()) {
idled = 1;
- ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax);
+ ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax, &err);
}
if (polling)
current_thread_info()->status |= TS_POLLING;
@@ -797,8 +839,7 @@ static int apm_do_idle(void)
* Only report the failure the first 5 times.
*/
if (++t < 5) {
- printk(KERN_DEBUG "apm_do_idle failed (%d)\n",
- (eax >> 8) & 0xff);
+ printk(KERN_DEBUG "apm_do_idle failed (%d)\n", err);
t = jiffies;
}
return -1;
@@ -816,9 +857,10 @@ static int apm_do_idle(void)
static void apm_do_busy(void)
{
u32 dummy;
+ int err;
if (clock_slowed || ALWAYS_CALL_BUSY) {
- (void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy);
+ (void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy, &err);
clock_slowed = 0;
}
}
@@ -937,7 +979,7 @@ static void apm_power_off(void)
/* Some bioses don't like being called from CPU != 0 */
if (apm_info.realmode_power_off) {
- (void)apm_save_cpus();
+ set_cpus_allowed_ptr(current, cpumask_of(0));
machine_real_restart(po_bios_call, sizeof(po_bios_call));
} else {
(void)set_system_power_state(APM_STATE_OFF);
@@ -956,12 +998,13 @@ static void apm_power_off(void)
static int apm_enable_power_management(int enable)
{
u32 eax;
+ int err;
if ((enable == 0) && (apm_info.bios.flags & APM_BIOS_DISENGAGED))
return APM_NOT_ENGAGED;
if (apm_bios_call_simple(APM_FUNC_ENABLE_PM, APM_DEVICE_BALL,
- enable, &eax))
- return (eax >> 8) & 0xff;
+ enable, &eax, &err))
+ return err;
if (enable)
apm_info.bios.flags &= ~APM_BIOS_DISABLED;
else
@@ -986,24 +1029,23 @@ static int apm_enable_power_management(int enable)
static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
{
- u32 eax;
- u32 ebx;
- u32 ecx;
- u32 edx;
- u32 dummy;
+ struct apm_bios_call call;
+
+ call.func = APM_FUNC_GET_STATUS;
+ call.ebx = APM_DEVICE_ALL;
+ call.ecx = 0;
if (apm_info.get_power_status_broken)
return APM_32_UNSUPPORTED;
- if (apm_bios_call(APM_FUNC_GET_STATUS, APM_DEVICE_ALL, 0,
- &eax, &ebx, &ecx, &edx, &dummy))
- return (eax >> 8) & 0xff;
- *status = ebx;
- *bat = ecx;
+ if (apm_bios_call(&call))
+ return call.err;
+ *status = call.ebx;
+ *bat = call.ecx;
if (apm_info.get_power_status_swabinminutes) {
- *life = swab16((u16)edx);
+ *life = swab16((u16)call.edx);
*life |= 0x8000;
} else
- *life = edx;
+ *life = call.edx;
return APM_SUCCESS;
}
@@ -1048,12 +1090,14 @@ static int apm_get_battery_status(u_short which, u_short *status,
static int apm_engage_power_management(u_short device, int enable)
{
u32 eax;
+ int err;
if ((enable == 0) && (device == APM_DEVICE_ALL)
&& (apm_info.bios.flags & APM_BIOS_DISABLED))
return APM_DISABLED;
- if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, enable, &eax))
- return (eax >> 8) & 0xff;
+ if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, enable,
+ &eax, &err))
+ return err;
if (device == APM_DEVICE_ALL) {
if (enable)
apm_info.bios.flags &= ~APM_BIOS_DISENGAGED;
@@ -1190,8 +1234,10 @@ static int suspend(int vetoable)
struct apm_user *as;
device_suspend(PMSG_SUSPEND);
- local_irq_disable();
+
device_power_down(PMSG_SUSPEND);
+
+ local_irq_disable();
sysdev_suspend(PMSG_SUSPEND);
local_irq_enable();
@@ -1209,9 +1255,12 @@ static int suspend(int vetoable)
if (err != APM_SUCCESS)
apm_error("suspend", err);
err = (err == APM_SUCCESS) ? 0 : -EIO;
+
sysdev_resume();
- device_power_up(PMSG_RESUME);
local_irq_enable();
+
+ device_power_up(PMSG_RESUME);
+
device_resume(PMSG_RESUME);
queue_event(APM_NORMAL_RESUME, NULL);
spin_lock(&user_list_lock);
@@ -1228,8 +1277,9 @@ static void standby(void)
{
int err;
- local_irq_disable();
device_power_down(PMSG_SUSPEND);
+
+ local_irq_disable();
sysdev_suspend(PMSG_SUSPEND);
local_irq_enable();
@@ -1239,8 +1289,9 @@ static void standby(void)
local_irq_disable();
sysdev_resume();
- device_power_up(PMSG_RESUME);
local_irq_enable();
+
+ device_power_up(PMSG_RESUME);
}
static apm_event_t get_event(void)
@@ -1682,16 +1733,14 @@ static int apm(void *unused)
char *power_stat;
char *bat_stat;
-#ifdef CONFIG_SMP
/* 2002/08/01 - WT
* This is to avoid random crashes at boot time during initialization
* on SMP systems in case of "apm=power-off" mode. Seen on ASUS A7M266D.
* Some bioses don't like being called from CPU != 0.
* Method suggested by Ingo Molnar.
*/
- set_cpus_allowed(current, cpumask_of_cpu(0));
+ set_cpus_allowed_ptr(current, cpumask_of(0));
BUG_ON(smp_processor_id() != 0);
-#endif
if (apm_info.connection_version == 0) {
apm_info.connection_version = apm_info.bios.version;
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index fbf2f33e3080..5a6aa1c1162f 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -18,6 +18,7 @@
#include <asm/thread_info.h>
#include <asm/bootparam.h>
#include <asm/elf.h>
+#include <asm/suspend.h>
#include <xen/interface/xen.h>
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
index 8793ab33e2c1..e72f062fb4b5 100644
--- a/arch/x86/kernel/asm-offsets_64.c
+++ b/arch/x86/kernel/asm-offsets_64.c
@@ -16,6 +16,7 @@
#include <asm/thread_info.h>
#include <asm/ia32.h>
#include <asm/bootparam.h>
+#include <asm/suspend.h>
#include <xen/interface/xen.h>
diff --git a/arch/x86/kernel/check.c b/arch/x86/kernel/check.c
index 2ac0ab71412a..fc999e6fc46a 100644
--- a/arch/x86/kernel/check.c
+++ b/arch/x86/kernel/check.c
@@ -83,15 +83,15 @@ void __init setup_bios_corruption_check(void)
u64 size;
addr = find_e820_area_size(addr, &size, PAGE_SIZE);
- if (addr == 0)
+ if (!(addr + 1))
+ break;
+
+ if (addr >= corruption_check_size)
break;
if ((addr + size) > corruption_check_size)
size = corruption_check_size - addr;
- if (size == 0)
- break;
-
e820_update_range(addr, size, E820_RAM, E820_RESERVED);
scan_areas[num_scan_areas].addr = addr;
scan_areas[num_scan_areas].size = size;
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index d4356f8b7522..4e242f9a06e4 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -19,8 +19,7 @@ obj-$(CONFIG_X86_CPU_DEBUG) += cpu_debug.o
obj-$(CONFIG_CPU_SUP_INTEL) += intel.o
obj-$(CONFIG_CPU_SUP_AMD) += amd.o
obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o
-obj-$(CONFIG_CPU_SUP_CENTAUR_32) += centaur.o
-obj-$(CONFIG_CPU_SUP_CENTAUR_64) += centaur_64.o
+obj-$(CONFIG_CPU_SUP_CENTAUR) += centaur.o
obj-$(CONFIG_CPU_SUP_TRANSMETA_32) += transmeta.o
obj-$(CONFIG_CPU_SUP_UMC_32) += umc.o
diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c
index 6882a735d9c0..8220ae69849d 100644
--- a/arch/x86/kernel/cpu/addon_cpuid_features.c
+++ b/arch/x86/kernel/cpu/addon_cpuid_features.c
@@ -29,7 +29,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
u32 regs[4];
const struct cpuid_bit *cb;
- static const struct cpuid_bit cpuid_bits[] = {
+ static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
{ X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
{ 0, 0, 0, 0 }
};
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index f47df59016c5..7e4a459daa64 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -502,7 +502,7 @@ static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c, unsigned int
}
#endif
-static struct cpu_dev amd_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst amd_cpu_dev = {
.c_vendor = "AMD",
.c_ident = { "AuthenticAMD" },
#ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c
index 89bfdd9cacc6..c95e831bb095 100644
--- a/arch/x86/kernel/cpu/centaur.c
+++ b/arch/x86/kernel/cpu/centaur.c
@@ -1,11 +1,11 @@
+#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/init.h>
-#include <linux/bitops.h>
#include <asm/processor.h>
-#include <asm/msr.h>
#include <asm/e820.h>
#include <asm/mtrr.h>
+#include <asm/msr.h>
#include "cpu.h"
@@ -276,7 +276,7 @@ static void __cpuinit init_c3(struct cpuinfo_x86 *c)
*/
c->x86_capability[5] = cpuid_edx(0xC0000001);
}
-
+#ifdef CONFIG_X86_32
/* Cyrix III family needs CX8 & PGE explicitly enabled. */
if (c->x86_model >= 6 && c->x86_model <= 9) {
rdmsr(MSR_VIA_FCR, lo, hi);
@@ -288,6 +288,11 @@ static void __cpuinit init_c3(struct cpuinfo_x86 *c)
/* Before Nehemiah, the C3's had 3dNOW! */
if (c->x86_model >= 6 && c->x86_model < 9)
set_cpu_cap(c, X86_FEATURE_3DNOW);
+#endif
+ if (c->x86 == 0x6 && c->x86_model >= 0xf) {
+ c->x86_cache_alignment = c->x86_clflush_size * 2;
+ set_cpu_cap(c, X86_FEATURE_REP_GOOD);
+ }
display_cacheinfo(c);
}
@@ -316,16 +321,25 @@ enum {
static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
{
switch (c->x86) {
+#ifdef CONFIG_X86_32
case 5:
/* Emulate MTRRs using Centaur's MCR. */
set_cpu_cap(c, X86_FEATURE_CENTAUR_MCR);
break;
+#endif
+ case 6:
+ if (c->x86_model >= 0xf)
+ set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
+ break;
}
+#ifdef CONFIG_X86_64
+ set_cpu_cap(c, X86_FEATURE_SYSENTER32);
+#endif
}
static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
{
-
+#ifdef CONFIG_X86_32
char *name;
u32 fcr_set = 0;
u32 fcr_clr = 0;
@@ -337,8 +351,10 @@ static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
* 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway
*/
clear_cpu_cap(c, 0*32+31);
-
+#endif
+ early_init_centaur(c);
switch (c->x86) {
+#ifdef CONFIG_X86_32
case 5:
switch (c->x86_model) {
case 4:
@@ -442,16 +458,20 @@ static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
}
sprintf(c->x86_model_id, "WinChip %s", name);
break;
-
+#endif
case 6:
init_c3(c);
break;
}
+#ifdef CONFIG_X86_64
+ set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
+#endif
}
static unsigned int __cpuinit
centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size)
{
+#ifdef CONFIG_X86_32
/* VIA C3 CPUs (670-68F) need further shifting. */
if ((c->x86 == 6) && ((c->x86_model == 7) || (c->x86_model == 8)))
size >>= 8;
@@ -464,11 +484,11 @@ centaur_size_cache(struct cpuinfo_x86 *c, unsigned int size)
if ((c->x86 == 6) && (c->x86_model == 9) &&
(c->x86_mask == 1) && (size == 65))
size -= 1;
-
+#endif
return size;
}
-static struct cpu_dev centaur_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst centaur_cpu_dev = {
.c_vendor = "Centaur",
.c_ident = { "CentaurHauls" },
.c_early_init = early_init_centaur,
diff --git a/arch/x86/kernel/cpu/centaur_64.c b/arch/x86/kernel/cpu/centaur_64.c
deleted file mode 100644
index a1625f5a1e78..000000000000
--- a/arch/x86/kernel/cpu/centaur_64.c
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <linux/init.h>
-#include <linux/smp.h>
-
-#include <asm/cpufeature.h>
-#include <asm/processor.h>
-
-#include "cpu.h"
-
-static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c)
-{
- if (c->x86 == 0x6 && c->x86_model >= 0xf)
- set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
-
- set_cpu_cap(c, X86_FEATURE_SYSENTER32);
-}
-
-static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
-{
- early_init_centaur(c);
-
- if (c->x86 == 0x6 && c->x86_model >= 0xf) {
- c->x86_cache_alignment = c->x86_clflush_size * 2;
- set_cpu_cap(c, X86_FEATURE_REP_GOOD);
- }
- set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
-}
-
-static struct cpu_dev centaur_cpu_dev __cpuinitdata = {
- .c_vendor = "Centaur",
- .c_ident = { "CentaurHauls" },
- .c_early_init = early_init_centaur,
- .c_init = init_centaur,
- .c_x86_vendor = X86_VENDOR_CENTAUR,
-};
-
-cpu_dev_register(centaur_cpu_dev);
-
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index f8869978bbb7..c4f667896c28 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1,52 +1,50 @@
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
#include <linux/bootmem.h>
+#include <linux/linkage.h>
#include <linux/bitops.h>
+#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/kgdb.h>
-#include <linux/topology.h>
+#include <linux/percpu.h>
+#include <linux/string.h>
#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/kgdb.h>
#include <linux/smp.h>
-#include <linux/percpu.h>
-#include <asm/i387.h>
-#include <asm/msr.h>
-#include <asm/io.h>
-#include <asm/linkage.h>
+#include <linux/io.h>
+
+#include <asm/stackprotector.h>
#include <asm/mmu_context.h>
+#include <asm/hypervisor.h>
+#include <asm/processor.h>
+#include <asm/sections.h>
+#include <asm/topology.h>
+#include <asm/cpumask.h>
+#include <asm/pgtable.h>
+#include <asm/atomic.h>
+#include <asm/proto.h>
+#include <asm/setup.h>
+#include <asm/apic.h>
+#include <asm/desc.h>
+#include <asm/i387.h>
#include <asm/mtrr.h>
+#include <asm/numa.h>
+#include <asm/asm.h>
+#include <asm/cpu.h>
#include <asm/mce.h>
+#include <asm/msr.h>
#include <asm/pat.h>
-#include <asm/asm.h>
-#include <asm/numa.h>
#include <asm/smp.h>
-#include <asm/cpu.h>
-#include <asm/cpumask.h>
-#include <asm/apic.h>
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/uv/uv.h>
#endif
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/desc.h>
-#include <asm/atomic.h>
-#include <asm/proto.h>
-#include <asm/sections.h>
-#include <asm/setup.h>
-#include <asm/hypervisor.h>
-#include <asm/stackprotector.h>
-
#include "cpu.h"
-#ifdef CONFIG_X86_64
-
/* all of these masks are initialized in setup_cpu_local_masks() */
-cpumask_var_t cpu_callin_mask;
-cpumask_var_t cpu_callout_mask;
cpumask_var_t cpu_initialized_mask;
+cpumask_var_t cpu_callout_mask;
+cpumask_var_t cpu_callin_mask;
/* representing cpus for which sibling maps can be computed */
cpumask_var_t cpu_sibling_setup_mask;
@@ -60,17 +58,7 @@ void __init setup_cpu_local_masks(void)
alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);
}
-#else /* CONFIG_X86_32 */
-
-cpumask_t cpu_callin_map;
-cpumask_t cpu_callout_map;
-cpumask_t cpu_initialized;
-cpumask_t cpu_sibling_setup_map;
-
-#endif /* CONFIG_X86_32 */
-
-
-static struct cpu_dev *this_cpu __cpuinitdata;
+static const struct cpu_dev *this_cpu __cpuinitdata;
DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
#ifdef CONFIG_X86_64
@@ -79,48 +67,48 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
* IRET will check the segment types kkeil 2000/10/28
* Also sysret mandates a special GDT layout
*
- * The TLS descriptors are currently at a different place compared to i386.
+ * TLS descriptors are currently at a different place compared to i386.
* Hopefully nobody expects them at a fixed place (Wine?)
*/
- [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
- [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
+ [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
+ [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
+ [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
+ [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
+ [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
+ [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
#else
- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
+ [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
+ [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
+ [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
+ [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
/*
* Segments used for calling PnP BIOS have byte granularity.
* They code segments and data segments have fixed 64k limits,
* the transfer segment sizes are set at run time.
*/
/* 32-bit code */
- [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
+ [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
/* 16-bit code */
- [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
+ [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
/* 16-bit data */
- [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
+ [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
/* 16-bit data */
- [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
+ [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
/* 16-bit data */
- [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
+ [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
/*
* The APM segments have byte granularity and their bases
* are set at run time. All have 64k limits.
*/
/* 32-bit code */
- [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
+ [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
/* 16-bit code */
- [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
+ [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
/* data */
- [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
+ [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
- [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
- [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } },
+ [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
+ [GDT_ENTRY_PERCPU] = { { { 0x0000ffff, 0x00cf9200 } } },
GDT_STACK_CANARY_INIT
#endif
} };
@@ -164,16 +152,17 @@ static inline int flag_is_changeable_p(u32 flag)
* the CPUID. Add "volatile" to not allow gcc to
* optimize the subsequent calls to this function.
*/
- asm volatile ("pushfl\n\t"
- "pushfl\n\t"
- "popl %0\n\t"
- "movl %0,%1\n\t"
- "xorl %2,%0\n\t"
- "pushl %0\n\t"
- "popfl\n\t"
- "pushfl\n\t"
- "popl %0\n\t"
- "popfl\n\t"
+ asm volatile ("pushfl \n\t"
+ "pushfl \n\t"
+ "popl %0 \n\t"
+ "movl %0, %1 \n\t"
+ "xorl %2, %0 \n\t"
+ "pushl %0 \n\t"
+ "popfl \n\t"
+ "pushfl \n\t"
+ "popl %0 \n\t"
+ "popfl \n\t"
+
: "=&r" (f1), "=&r" (f2)
: "ir" (flag));
@@ -188,18 +177,22 @@ static int __cpuinit have_cpuid_p(void)
static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
{
- if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr) {
- /* Disable processor serial number */
- unsigned long lo, hi;
- rdmsr(MSR_IA32_BBL_CR_CTL, lo, hi);
- lo |= 0x200000;
- wrmsr(MSR_IA32_BBL_CR_CTL, lo, hi);
- printk(KERN_NOTICE "CPU serial number disabled.\n");
- clear_cpu_cap(c, X86_FEATURE_PN);
-
- /* Disabling the serial number may affect the cpuid level */
- c->cpuid_level = cpuid_eax(0);
- }
+ unsigned long lo, hi;
+
+ if (!cpu_has(c, X86_FEATURE_PN) || !disable_x86_serial_nr)
+ return;
+
+ /* Disable processor serial number: */
+
+ rdmsr(MSR_IA32_BBL_CR_CTL, lo, hi);
+ lo |= 0x200000;
+ wrmsr(MSR_IA32_BBL_CR_CTL, lo, hi);
+
+ printk(KERN_NOTICE "CPU serial number disabled.\n");
+ clear_cpu_cap(c, X86_FEATURE_PN);
+
+ /* Disabling the serial number may affect the cpuid level */
+ c->cpuid_level = cpuid_eax(0);
}
static int __init x86_serial_nr_setup(char *s)
@@ -232,6 +225,7 @@ struct cpuid_dependent_feature {
u32 feature;
u32 level;
};
+
static const struct cpuid_dependent_feature __cpuinitconst
cpuid_dependent_features[] = {
{ X86_FEATURE_MWAIT, 0x00000005 },
@@ -243,7 +237,11 @@ cpuid_dependent_features[] = {
static void __cpuinit filter_cpuid_features(struct cpuinfo_x86 *c, bool warn)
{
const struct cpuid_dependent_feature *df;
+
for (df = cpuid_dependent_features; df->feature; df++) {
+
+ if (!cpu_has(c, df->feature))
+ continue;
/*
* Note: cpuid_level is set to -1 if unavailable, but
* extended_extended_level is set to 0 if unavailable
@@ -251,32 +249,32 @@ static void __cpuinit filter_cpuid_features(struct cpuinfo_x86 *c, bool warn)
* when signed; hence the weird messing around with
* signs here...
*/
- if (cpu_has(c, df->feature) &&
- ((s32)df->level < 0 ?
+ if (!((s32)df->level < 0 ?
(u32)df->level > (u32)c->extended_cpuid_level :
- (s32)df->level > (s32)c->cpuid_level)) {
- clear_cpu_cap(c, df->feature);
- if (warn)
- printk(KERN_WARNING
- "CPU: CPU feature %s disabled "
- "due to lack of CPUID level 0x%x\n",
- x86_cap_flags[df->feature],
- df->level);
- }
+ (s32)df->level > (s32)c->cpuid_level))
+ continue;
+
+ clear_cpu_cap(c, df->feature);
+ if (!warn)
+ continue;
+
+ printk(KERN_WARNING
+ "CPU: CPU feature %s disabled, no CPUID level 0x%x\n",
+ x86_cap_flags[df->feature], df->level);
}
}
/*
* Naming convention should be: <Name> [(<Codename>)]
* This table only is used unless init_<vendor>() below doesn't set it;
- * in particular, if CPUID levels 0x80000002..4 are supported, this isn't used
- *
+ * in particular, if CPUID levels 0x80000002..4 are supported, this
+ * isn't used
*/
/* Look up CPU names by table lookup. */
-static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c)
+static const char *__cpuinit table_lookup_model(struct cpuinfo_x86 *c)
{
- struct cpu_model_info *info;
+ const struct cpu_model_info *info;
if (c->x86_model >= 16)
return NULL; /* Range check */
@@ -307,8 +305,10 @@ void load_percpu_segment(int cpu)
load_stack_canary_segment();
}
-/* Current gdt points %fs at the "master" per-cpu area: after this,
- * it's on the real one. */
+/*
+ * Current gdt points %fs at the "master" per-cpu area: after this,
+ * it's on the real one.
+ */
void switch_to_new_gdt(int cpu)
{
struct desc_ptr gdt_descr;
@@ -321,7 +321,7 @@ void switch_to_new_gdt(int cpu)
load_percpu_segment(cpu);
}
-static struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {};
+static const struct cpu_dev *__cpuinitdata cpu_devs[X86_VENDOR_NUM] = {};
static void __cpuinit default_init(struct cpuinfo_x86 *c)
{
@@ -340,7 +340,7 @@ static void __cpuinit default_init(struct cpuinfo_x86 *c)
#endif
}
-static struct cpu_dev __cpuinitdata default_cpu = {
+static const struct cpu_dev __cpuinitconst default_cpu = {
.c_init = default_init,
.c_vendor = "Unknown",
.c_x86_vendor = X86_VENDOR_UNKNOWN,
@@ -354,22 +354,24 @@ static void __cpuinit get_model_name(struct cpuinfo_x86 *c)
if (c->extended_cpuid_level < 0x80000004)
return;
- v = (unsigned int *) c->x86_model_id;
+ v = (unsigned int *)c->x86_model_id;
cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
c->x86_model_id[48] = 0;
- /* Intel chips right-justify this string for some dumb reason;
- undo that brain damage */
+ /*
+ * Intel chips right-justify this string for some dumb reason;
+ * undo that brain damage:
+ */
p = q = &c->x86_model_id[0];
while (*p == ' ')
- p++;
+ p++;
if (p != q) {
- while (*p)
- *q++ = *p++;
- while (q <= &c->x86_model_id[48])
- *q++ = '\0'; /* Zero-pad the rest */
+ while (*p)
+ *q++ = *p++;
+ while (q <= &c->x86_model_id[48])
+ *q++ = '\0'; /* Zero-pad the rest */
}
}
@@ -438,27 +440,30 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c)
if (smp_num_siblings == 1) {
printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
- } else if (smp_num_siblings > 1) {
+ goto out;
+ }
- if (smp_num_siblings > nr_cpu_ids) {
- printk(KERN_WARNING "CPU: Unsupported number of siblings %d",
- smp_num_siblings);
- smp_num_siblings = 1;
- return;
- }
+ if (smp_num_siblings <= 1)
+ goto out;
- index_msb = get_count_order(smp_num_siblings);
- c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, index_msb);
+ if (smp_num_siblings > nr_cpu_ids) {
+ pr_warning("CPU: Unsupported number of siblings %d",
+ smp_num_siblings);
+ smp_num_siblings = 1;
+ return;
+ }
- smp_num_siblings = smp_num_siblings / c->x86_max_cores;
+ index_msb = get_count_order(smp_num_siblings);
+ c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, index_msb);
- index_msb = get_count_order(smp_num_siblings);
+ smp_num_siblings = smp_num_siblings / c->x86_max_cores;
- core_bits = get_count_order(c->x86_max_cores);
+ index_msb = get_count_order(smp_num_siblings);
- c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, index_msb) &
- ((1 << core_bits) - 1);
- }
+ core_bits = get_count_order(c->x86_max_cores);
+
+ c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, index_msb) &
+ ((1 << core_bits) - 1);
out:
if ((c->x86_max_cores * smp_num_siblings) > 1) {
@@ -473,8 +478,8 @@ out:
static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
{
char *v = c->x86_vendor_id;
- int i;
static int printed;
+ int i;
for (i = 0; i < X86_VENDOR_NUM; i++) {
if (!cpu_devs[i])
@@ -483,6 +488,7 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
if (!strcmp(v, cpu_devs[i]->c_ident[0]) ||
(cpu_devs[i]->c_ident[1] &&
!strcmp(v, cpu_devs[i]->c_ident[1]))) {
+
this_cpu = cpu_devs[i];
c->x86_vendor = this_cpu->c_x86_vendor;
return;
@@ -491,7 +497,9 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
if (!printed) {
printed++;
- printk(KERN_ERR "CPU: vendor_id '%s' unknown, using generic init.\n", v);
+ printk(KERN_ERR
+ "CPU: vendor_id '%s' unknown, using generic init.\n", v);
+
printk(KERN_ERR "CPU: Your system may be unstable.\n");
}
@@ -511,14 +519,17 @@ void __cpuinit cpu_detect(struct cpuinfo_x86 *c)
/* Intel-defined flags: level 0x00000001 */
if (c->cpuid_level >= 0x00000001) {
u32 junk, tfms, cap0, misc;
+
cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
c->x86 = (tfms >> 8) & 0xf;
c->x86_model = (tfms >> 4) & 0xf;
c->x86_mask = tfms & 0xf;
+
if (c->x86 == 0xf)
c->x86 += (tfms >> 20) & 0xff;
if (c->x86 >= 0x6)
c->x86_model += ((tfms >> 16) & 0xf) << 4;
+
if (cap0 & (1<<19)) {
c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
c->x86_cache_alignment = c->x86_clflush_size;
@@ -534,6 +545,7 @@ static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
/* Intel-defined flags: level 0x00000001 */
if (c->cpuid_level >= 0x00000001) {
u32 capability, excap;
+
cpuid(0x00000001, &tfms, &ebx, &excap, &capability);
c->x86_capability[0] = capability;
c->x86_capability[4] = excap;
@@ -542,6 +554,7 @@ static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
/* AMD-defined flags: level 0x80000001 */
xlvl = cpuid_eax(0x80000000);
c->extended_cpuid_level = xlvl;
+
if ((xlvl & 0xffff0000) == 0x80000000) {
if (xlvl >= 0x80000001) {
c->x86_capability[1] = cpuid_edx(0x80000001);
@@ -549,13 +562,15 @@ static void __cpuinit get_cpu_cap(struct cpuinfo_x86 *c)
}
}
-#ifdef CONFIG_X86_64
if (c->extended_cpuid_level >= 0x80000008) {
u32 eax = cpuid_eax(0x80000008);
c->x86_virt_bits = (eax >> 8) & 0xff;
c->x86_phys_bits = eax & 0xff;
}
+#ifdef CONFIG_X86_32
+ else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36))
+ c->x86_phys_bits = 36;
#endif
if (c->extended_cpuid_level >= 0x80000007)
@@ -602,8 +617,12 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
{
#ifdef CONFIG_X86_64
c->x86_clflush_size = 64;
+ c->x86_phys_bits = 36;
+ c->x86_virt_bits = 48;
#else
c->x86_clflush_size = 32;
+ c->x86_phys_bits = 32;
+ c->x86_virt_bits = 32;
#endif
c->x86_cache_alignment = c->x86_clflush_size;
@@ -634,12 +653,12 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
void __init early_cpu_init(void)
{
- struct cpu_dev **cdev;
+ const struct cpu_dev *const *cdev;
int count = 0;
- printk("KERNEL supported cpus:\n");
+ printk(KERN_INFO "KERNEL supported cpus:\n");
for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) {
- struct cpu_dev *cpudev = *cdev;
+ const struct cpu_dev *cpudev = *cdev;
unsigned int j;
if (count >= X86_VENDOR_NUM)
@@ -650,7 +669,7 @@ void __init early_cpu_init(void)
for (j = 0; j < 2; j++) {
if (!cpudev->c_ident[j])
continue;
- printk(" %s %s\n", cpudev->c_vendor,
+ printk(KERN_INFO " %s %s\n", cpudev->c_vendor,
cpudev->c_ident[j]);
}
}
@@ -726,9 +745,13 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
c->x86_coreid_bits = 0;
#ifdef CONFIG_X86_64
c->x86_clflush_size = 64;
+ c->x86_phys_bits = 36;
+ c->x86_virt_bits = 48;
#else
c->cpuid_level = -1; /* CPUID not detected */
c->x86_clflush_size = 32;
+ c->x86_phys_bits = 32;
+ c->x86_virt_bits = 32;
#endif
c->x86_cache_alignment = c->x86_clflush_size;
memset(&c->x86_capability, 0, sizeof c->x86_capability);
@@ -759,8 +782,8 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
squash_the_stupid_serial_number(c);
/*
- * The vendor-specific functions might have changed features. Now
- * we do "generic changes."
+ * The vendor-specific functions might have changed features.
+ * Now we do "generic changes."
*/
/* Filter out anything that depends on CPUID levels we don't have */
@@ -768,7 +791,7 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
/* If the model name is still unset, do table lookup. */
if (!c->x86_model_id[0]) {
- char *p;
+ const char *p;
p = table_lookup_model(c);
if (p)
strcpy(c->x86_model_id, p);
@@ -824,6 +847,7 @@ static void vgetcpu_set_mode(void)
void __init identify_boot_cpu(void)
{
identify_cpu(&boot_cpu_data);
+ init_c1e_mask();
#ifdef CONFIG_X86_32
sysenter_setup();
enable_sep_cpu();
@@ -843,11 +867,11 @@ void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c)
}
struct msr_range {
- unsigned min;
- unsigned max;
+ unsigned min;
+ unsigned max;
};
-static struct msr_range msr_range_array[] __cpuinitdata = {
+static const struct msr_range msr_range_array[] __cpuinitconst = {
{ 0x00000000, 0x00000418},
{ 0xc0000000, 0xc000040b},
{ 0xc0010000, 0xc0010142},
@@ -856,14 +880,15 @@ static struct msr_range msr_range_array[] __cpuinitdata = {
static void __cpuinit print_cpu_msr(void)
{
+ unsigned index_min, index_max;
unsigned index;
u64 val;
int i;
- unsigned index_min, index_max;
for (i = 0; i < ARRAY_SIZE(msr_range_array); i++) {
index_min = msr_range_array[i].min;
index_max = msr_range_array[i].max;
+
for (index = index_min; index < index_max; index++) {
if (rdmsrl_amd_safe(index, &val))
continue;
@@ -873,6 +898,7 @@ static void __cpuinit print_cpu_msr(void)
}
static int show_msr __cpuinitdata;
+
static __init int setup_show_msr(char *arg)
{
int num;
@@ -894,12 +920,14 @@ __setup("noclflush", setup_noclflush);
void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
{
- char *vendor = NULL;
+ const char *vendor = NULL;
- if (c->x86_vendor < X86_VENDOR_NUM)
+ if (c->x86_vendor < X86_VENDOR_NUM) {
vendor = this_cpu->c_vendor;
- else if (c->cpuid_level >= 0)
- vendor = c->x86_vendor_id;
+ } else {
+ if (c->cpuid_level >= 0)
+ vendor = c->x86_vendor_id;
+ }
if (vendor && !strstr(c->x86_model_id, vendor))
printk(KERN_CONT "%s ", vendor);
@@ -926,10 +954,12 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
static __init int setup_disablecpuid(char *arg)
{
int bit;
+
if (get_option(&arg, &bit) && bit < NCAPINTS*32)
setup_clear_cpu_cap(bit);
else
return 0;
+
return 1;
}
__setup("clearcpuid=", setup_disablecpuid);
@@ -939,6 +969,7 @@ struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
DEFINE_PER_CPU_FIRST(union irq_stack_union,
irq_stack_union) __aligned(PAGE_SIZE);
+
DEFINE_PER_CPU(char *, irq_stack_ptr) =
init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64;
@@ -948,12 +979,21 @@ EXPORT_PER_CPU_SYMBOL(kernel_stack);
DEFINE_PER_CPU(unsigned int, irq_count) = -1;
+/*
+ * Special IST stacks which the CPU switches to when it calls
+ * an IST-marked descriptor entry. Up to 7 stacks (hardware
+ * limit), all of them are 4K, except the debug stack which
+ * is 8K.
+ */
+static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = {
+ [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ,
+ [DEBUG_STACK - 1] = DEBUG_STKSZ
+};
+
static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks
[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ])
__aligned(PAGE_SIZE);
-extern asmlinkage void ignore_sysret(void);
-
/* May not be marked __init: used by software suspend */
void syscall_init(void)
{
@@ -983,7 +1023,7 @@ unsigned long kernel_eflags;
*/
DEFINE_PER_CPU(struct orig_ist, orig_ist);
-#else /* x86_64 */
+#else /* CONFIG_X86_64 */
#ifdef CONFIG_CC_STACKPROTECTOR
DEFINE_PER_CPU(unsigned long, stack_canary);
@@ -995,9 +1035,26 @@ struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs)
memset(regs, 0, sizeof(struct pt_regs));
regs->fs = __KERNEL_PERCPU;
regs->gs = __KERNEL_STACK_CANARY;
+
return regs;
}
-#endif /* x86_64 */
+#endif /* CONFIG_X86_64 */
+
+/*
+ * Clear all 6 debug registers:
+ */
+static void clear_all_debug_regs(void)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ /* Ignore db4, db5 */
+ if ((i == 4) || (i == 5))
+ continue;
+
+ set_debugreg(0, i);
+ }
+}
/*
* cpu_init() initializes state that is per-CPU. Some data is already
@@ -1007,15 +1064,20 @@ struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs)
* A lot of state is already set up in PDA init for 64 bit
*/
#ifdef CONFIG_X86_64
+
void __cpuinit cpu_init(void)
{
- int cpu = stack_smp_processor_id();
- struct tss_struct *t = &per_cpu(init_tss, cpu);
- struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
- unsigned long v;
+ struct orig_ist *orig_ist;
struct task_struct *me;
+ struct tss_struct *t;
+ unsigned long v;
+ int cpu;
int i;
+ cpu = stack_smp_processor_id();
+ t = &per_cpu(init_tss, cpu);
+ orig_ist = &per_cpu(orig_ist, cpu);
+
#ifdef CONFIG_NUMA
if (cpu != 0 && percpu_read(node_number) == 0 &&
cpu_to_node(cpu) != NUMA_NO_NODE)
@@ -1056,19 +1118,17 @@ void __cpuinit cpu_init(void)
* set up and load the per-CPU TSS
*/
if (!orig_ist->ist[0]) {
- static const unsigned int sizes[N_EXCEPTION_STACKS] = {
- [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ,
- [DEBUG_STACK - 1] = DEBUG_STKSZ
- };
char *estacks = per_cpu(exception_stacks, cpu);
+
for (v = 0; v < N_EXCEPTION_STACKS; v++) {
- estacks += sizes[v];
+ estacks += exception_stack_sizes[v];
orig_ist->ist[v] = t->x86_tss.ist[v] =
(unsigned long)estacks;
}
}
t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
+
/*
* <= is required because the CPU will access up to
* 8 bits beyond the end of the IO permission bitmap.
@@ -1097,17 +1157,7 @@ void __cpuinit cpu_init(void)
arch_kgdb_ops.correct_hw_break();
else
#endif
- {
- /*
- * Clear all 6 debug registers:
- */
- set_debugreg(0UL, 0);
- set_debugreg(0UL, 1);
- set_debugreg(0UL, 2);
- set_debugreg(0UL, 3);
- set_debugreg(0UL, 6);
- set_debugreg(0UL, 7);
- }
+ clear_all_debug_regs();
fpu_init();
@@ -1128,7 +1178,8 @@ void __cpuinit cpu_init(void)
if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) {
printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
- for (;;) local_irq_enable();
+ for (;;)
+ local_irq_enable();
}
printk(KERN_INFO "Initializing CPU#%d\n", cpu);
@@ -1157,13 +1208,7 @@ void __cpuinit cpu_init(void)
__set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
#endif
- /* Clear all 6 debug registers: */
- set_debugreg(0, 0);
- set_debugreg(0, 1);
- set_debugreg(0, 2);
- set_debugreg(0, 3);
- set_debugreg(0, 6);
- set_debugreg(0, 7);
+ clear_all_debug_regs();
/*
* Force FPU initialization:
@@ -1183,6 +1228,4 @@ void __cpuinit cpu_init(void)
xsave_init();
}
-
-
#endif
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index de4094a39210..6de9a908e400 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -3,33 +3,34 @@
#define ARCH_X86_CPU_H
struct cpu_model_info {
- int vendor;
- int family;
- char *model_names[16];
+ int vendor;
+ int family;
+ const char *model_names[16];
};
/* attempt to consolidate cpu attributes */
struct cpu_dev {
- char * c_vendor;
+ const char *c_vendor;
/* some have two possibilities for cpuid string */
- char * c_ident[2];
+ const char *c_ident[2];
struct cpu_model_info c_models[4];
- void (*c_early_init)(struct cpuinfo_x86 *c);
- void (*c_init)(struct cpuinfo_x86 * c);
- void (*c_identify)(struct cpuinfo_x86 * c);
- unsigned int (*c_size_cache)(struct cpuinfo_x86 * c, unsigned int size);
- int c_x86_vendor;
+ void (*c_early_init)(struct cpuinfo_x86 *);
+ void (*c_init)(struct cpuinfo_x86 *);
+ void (*c_identify)(struct cpuinfo_x86 *);
+ unsigned int (*c_size_cache)(struct cpuinfo_x86 *, unsigned int);
+ int c_x86_vendor;
};
#define cpu_dev_register(cpu_devX) \
- static struct cpu_dev *__cpu_dev_##cpu_devX __used \
+ static const struct cpu_dev *const __cpu_dev_##cpu_devX __used \
__attribute__((__section__(".x86_cpu_dev.init"))) = \
&cpu_devX;
-extern struct cpu_dev *__x86_cpu_dev_start[], *__x86_cpu_dev_end[];
+extern const struct cpu_dev *const __x86_cpu_dev_start[],
+ *const __x86_cpu_dev_end[];
extern void display_cacheinfo(struct cpuinfo_x86 *c);
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index 9abbcbd933cc..46e29ab96c6a 100755
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -11,6 +11,7 @@
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <linux/kprobes.h>
+#include <linux/uaccess.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/percpu.h>
@@ -40,41 +41,43 @@ static DEFINE_MUTEX(cpu_debug_lock);
static struct dentry *cpu_debugfs_dir;
static struct cpu_debug_base cpu_base[] = {
- { "mc", CPU_MC }, /* Machine Check */
- { "monitor", CPU_MONITOR }, /* Monitor */
- { "time", CPU_TIME }, /* Time */
- { "pmc", CPU_PMC }, /* Performance Monitor */
- { "platform", CPU_PLATFORM }, /* Platform */
- { "apic", CPU_APIC }, /* APIC */
- { "poweron", CPU_POWERON }, /* Power-on */
- { "control", CPU_CONTROL }, /* Control */
- { "features", CPU_FEATURES }, /* Features control */
- { "lastbranch", CPU_LBRANCH }, /* Last Branch */
- { "bios", CPU_BIOS }, /* BIOS */
- { "freq", CPU_FREQ }, /* Frequency */
- { "mtrr", CPU_MTRR }, /* MTRR */
- { "perf", CPU_PERF }, /* Performance */
- { "cache", CPU_CACHE }, /* Cache */
- { "sysenter", CPU_SYSENTER }, /* Sysenter */
- { "therm", CPU_THERM }, /* Thermal */
- { "misc", CPU_MISC }, /* Miscellaneous */
- { "debug", CPU_DEBUG }, /* Debug */
- { "pat", CPU_PAT }, /* PAT */
- { "vmx", CPU_VMX }, /* VMX */
- { "call", CPU_CALL }, /* System Call */
- { "base", CPU_BASE }, /* BASE Address */
- { "smm", CPU_SMM }, /* System mgmt mode */
- { "svm", CPU_SVM }, /*Secure Virtial Machine*/
- { "osvm", CPU_OSVM }, /* OS-Visible Workaround*/
- { "tss", CPU_TSS }, /* Task Stack Segment */
- { "cr", CPU_CR }, /* Control Registers */
- { "dt", CPU_DT }, /* Descriptor Table */
- { "registers", CPU_REG_ALL }, /* Select all Registers */
+ { "mc", CPU_MC, 0 },
+ { "monitor", CPU_MONITOR, 0 },
+ { "time", CPU_TIME, 0 },
+ { "pmc", CPU_PMC, 1 },
+ { "platform", CPU_PLATFORM, 0 },
+ { "apic", CPU_APIC, 0 },
+ { "poweron", CPU_POWERON, 0 },
+ { "control", CPU_CONTROL, 0 },
+ { "features", CPU_FEATURES, 0 },
+ { "lastbranch", CPU_LBRANCH, 0 },
+ { "bios", CPU_BIOS, 0 },
+ { "freq", CPU_FREQ, 0 },
+ { "mtrr", CPU_MTRR, 0 },
+ { "perf", CPU_PERF, 0 },
+ { "cache", CPU_CACHE, 0 },
+ { "sysenter", CPU_SYSENTER, 0 },
+ { "therm", CPU_THERM, 0 },
+ { "misc", CPU_MISC, 0 },
+ { "debug", CPU_DEBUG, 0 },
+ { "pat", CPU_PAT, 0 },
+ { "vmx", CPU_VMX, 0 },
+ { "call", CPU_CALL, 0 },
+ { "base", CPU_BASE, 0 },
+ { "ver", CPU_VER, 0 },
+ { "conf", CPU_CONF, 0 },
+ { "smm", CPU_SMM, 0 },
+ { "svm", CPU_SVM, 0 },
+ { "osvm", CPU_OSVM, 0 },
+ { "tss", CPU_TSS, 0 },
+ { "cr", CPU_CR, 0 },
+ { "dt", CPU_DT, 0 },
+ { "registers", CPU_REG_ALL, 0 },
};
static struct cpu_file_base cpu_file[] = {
- { "index", CPU_REG_ALL }, /* index */
- { "value", CPU_REG_ALL }, /* value */
+ { "index", CPU_REG_ALL, 0 },
+ { "value", CPU_REG_ALL, 1 },
};
/* Intel Registers Range */
@@ -176,54 +179,59 @@ static struct cpu_debug_range cpu_intel_range[] = {
/* AMD Registers Range */
static struct cpu_debug_range cpu_amd_range[] = {
- { 0x00000010, 0x00000010, CPU_TIME, CPU_ALL, },
- { 0x0000001B, 0x0000001B, CPU_APIC, CPU_ALL, },
- { 0x000000FE, 0x000000FE, CPU_MTRR, CPU_ALL, },
-
- { 0x00000174, 0x00000176, CPU_SYSENTER, CPU_ALL, },
- { 0x00000179, 0x0000017A, CPU_MC, CPU_ALL, },
- { 0x0000017B, 0x0000017B, CPU_MC, CPU_ALL, },
- { 0x000001D9, 0x000001D9, CPU_DEBUG, CPU_ALL, },
- { 0x000001DB, 0x000001DE, CPU_LBRANCH, CPU_ALL, },
-
- { 0x00000200, 0x0000020F, CPU_MTRR, CPU_ALL, },
- { 0x00000250, 0x00000250, CPU_MTRR, CPU_ALL, },
- { 0x00000258, 0x00000259, CPU_MTRR, CPU_ALL, },
- { 0x00000268, 0x0000026F, CPU_MTRR, CPU_ALL, },
- { 0x00000277, 0x00000277, CPU_PAT, CPU_ALL, },
- { 0x000002FF, 0x000002FF, CPU_MTRR, CPU_ALL, },
-
- { 0x00000400, 0x00000417, CPU_MC, CPU_ALL, },
-
- { 0xC0000080, 0xC0000080, CPU_FEATURES, CPU_ALL, },
- { 0xC0000081, 0xC0000084, CPU_CALL, CPU_ALL, },
- { 0xC0000100, 0xC0000102, CPU_BASE, CPU_ALL, },
- { 0xC0000103, 0xC0000103, CPU_TIME, CPU_ALL, },
-
- { 0xC0000408, 0xC000040A, CPU_MC, CPU_ALL, },
-
- { 0xc0010000, 0xc0010007, CPU_PMC, CPU_ALL, },
- { 0xc0010010, 0xc0010010, CPU_MTRR, CPU_ALL, },
- { 0xc0010016, 0xc001001A, CPU_MTRR, CPU_ALL, },
- { 0xc001001D, 0xc001001D, CPU_MTRR, CPU_ALL, },
- { 0xc0010030, 0xc0010035, CPU_BIOS, CPU_ALL, },
- { 0xc0010056, 0xc0010056, CPU_SMM, CPU_ALL, },
- { 0xc0010061, 0xc0010063, CPU_SMM, CPU_ALL, },
- { 0xc0010074, 0xc0010074, CPU_MC, CPU_ALL, },
- { 0xc0010111, 0xc0010113, CPU_SMM, CPU_ALL, },
- { 0xc0010114, 0xc0010118, CPU_SVM, CPU_ALL, },
- { 0xc0010119, 0xc001011A, CPU_SMM, CPU_ALL, },
- { 0xc0010140, 0xc0010141, CPU_OSVM, CPU_ALL, },
- { 0xc0010156, 0xc0010156, CPU_SMM, CPU_ALL, },
+ { 0x00000000, 0x00000001, CPU_MC, CPU_K10_PLUS, },
+ { 0x00000010, 0x00000010, CPU_TIME, CPU_K8_PLUS, },
+ { 0x0000001B, 0x0000001B, CPU_APIC, CPU_K8_PLUS, },
+ { 0x0000002A, 0x0000002A, CPU_POWERON, CPU_K7_PLUS },
+ { 0x0000008B, 0x0000008B, CPU_VER, CPU_K8_PLUS },
+ { 0x000000FE, 0x000000FE, CPU_MTRR, CPU_K8_PLUS, },
+
+ { 0x00000174, 0x00000176, CPU_SYSENTER, CPU_K8_PLUS, },
+ { 0x00000179, 0x0000017B, CPU_MC, CPU_K8_PLUS, },
+ { 0x000001D9, 0x000001D9, CPU_DEBUG, CPU_K8_PLUS, },
+ { 0x000001DB, 0x000001DE, CPU_LBRANCH, CPU_K8_PLUS, },
+
+ { 0x00000200, 0x0000020F, CPU_MTRR, CPU_K8_PLUS, },
+ { 0x00000250, 0x00000250, CPU_MTRR, CPU_K8_PLUS, },
+ { 0x00000258, 0x00000259, CPU_MTRR, CPU_K8_PLUS, },
+ { 0x00000268, 0x0000026F, CPU_MTRR, CPU_K8_PLUS, },
+ { 0x00000277, 0x00000277, CPU_PAT, CPU_K8_PLUS, },
+ { 0x000002FF, 0x000002FF, CPU_MTRR, CPU_K8_PLUS, },
+
+ { 0x00000400, 0x00000413, CPU_MC, CPU_K8_PLUS, },
+
+ { 0xC0000080, 0xC0000080, CPU_FEATURES, CPU_AMD_ALL, },
+ { 0xC0000081, 0xC0000084, CPU_CALL, CPU_K8_PLUS, },
+ { 0xC0000100, 0xC0000102, CPU_BASE, CPU_K8_PLUS, },
+ { 0xC0000103, 0xC0000103, CPU_TIME, CPU_K10_PLUS, },
+
+ { 0xC0010000, 0xC0010007, CPU_PMC, CPU_K8_PLUS, },
+ { 0xC0010010, 0xC0010010, CPU_CONF, CPU_K7_PLUS, },
+ { 0xC0010015, 0xC0010015, CPU_CONF, CPU_K7_PLUS, },
+ { 0xC0010016, 0xC001001A, CPU_MTRR, CPU_K8_PLUS, },
+ { 0xC001001D, 0xC001001D, CPU_MTRR, CPU_K8_PLUS, },
+ { 0xC001001F, 0xC001001F, CPU_CONF, CPU_K8_PLUS, },
+ { 0xC0010030, 0xC0010035, CPU_BIOS, CPU_K8_PLUS, },
+ { 0xC0010044, 0xC0010048, CPU_MC, CPU_K8_PLUS, },
+ { 0xC0010050, 0xC0010056, CPU_SMM, CPU_K0F_PLUS, },
+ { 0xC0010058, 0xC0010058, CPU_CONF, CPU_K10_PLUS, },
+ { 0xC0010060, 0xC0010060, CPU_CACHE, CPU_AMD_11, },
+ { 0xC0010061, 0xC0010068, CPU_SMM, CPU_K10_PLUS, },
+ { 0xC0010069, 0xC001006B, CPU_SMM, CPU_AMD_11, },
+ { 0xC0010070, 0xC0010071, CPU_SMM, CPU_K10_PLUS, },
+ { 0xC0010111, 0xC0010113, CPU_SMM, CPU_K8_PLUS, },
+ { 0xC0010114, 0xC0010118, CPU_SVM, CPU_K10_PLUS, },
+ { 0xC0010140, 0xC0010141, CPU_OSVM, CPU_K10_PLUS, },
+ { 0xC0011022, 0xC0011023, CPU_CONF, CPU_K10_PLUS, },
};
-static int get_cpu_modelflag(unsigned cpu)
+/* Intel */
+static int get_intel_modelflag(unsigned model)
{
int flag;
- switch (per_cpu(cpu_model, cpu)) {
- /* Intel */
+ switch (model) {
case 0x0501:
case 0x0502:
case 0x0504:
@@ -270,6 +278,59 @@ static int get_cpu_modelflag(unsigned cpu)
return flag;
}
+/* AMD */
+static int get_amd_modelflag(unsigned model)
+{
+ int flag;
+
+ switch (model >> 8) {
+ case 0x6:
+ flag = CPU_AMD_K6;
+ break;
+ case 0x7:
+ flag = CPU_AMD_K7;
+ break;
+ case 0x8:
+ flag = CPU_AMD_K8;
+ break;
+ case 0xf:
+ flag = CPU_AMD_0F;
+ break;
+ case 0x10:
+ flag = CPU_AMD_10;
+ break;
+ case 0x11:
+ flag = CPU_AMD_11;
+ break;
+ default:
+ flag = CPU_NONE;
+ break;
+ }
+
+ return flag;
+}
+
+static int get_cpu_modelflag(unsigned cpu)
+{
+ int flag;
+
+ flag = per_cpu(cpu_model, cpu);
+
+ switch (flag >> 16) {
+ case X86_VENDOR_INTEL:
+ flag = get_intel_modelflag(flag);
+ break;
+ case X86_VENDOR_AMD:
+ flag = get_amd_modelflag(flag & 0xffff);
+ break;
+ default:
+ flag = CPU_NONE;
+ break;
+ }
+
+ return flag;
+}
+
static int get_cpu_range_count(unsigned cpu)
{
int index;
@@ -310,7 +371,8 @@ static int is_typeflag_valid(unsigned cpu, unsigned flag)
return 1;
break;
case X86_VENDOR_AMD:
- if (cpu_amd_range[i].flag & flag)
+ if ((cpu_amd_range[i].model & modelflag) &&
+ (cpu_amd_range[i].flag & flag))
return 1;
break;
}
@@ -336,7 +398,8 @@ static unsigned get_cpu_range(unsigned cpu, unsigned *min, unsigned *max,
}
break;
case X86_VENDOR_AMD:
- if (cpu_amd_range[index].flag & flag) {
+ if ((cpu_amd_range[index].model & modelflag) &&
+ (cpu_amd_range[index].flag & flag)) {
*min = cpu_amd_range[index].min;
*max = cpu_amd_range[index].max;
}
@@ -608,9 +671,62 @@ static int cpu_seq_open(struct inode *inode, struct file *file)
return err;
}
+static int write_msr(struct cpu_private *priv, u64 val)
+{
+ u32 low, high;
+
+ high = (val >> 32) & 0xffffffff;
+ low = val & 0xffffffff;
+
+ if (!wrmsr_safe_on_cpu(priv->cpu, priv->reg, low, high))
+ return 0;
+
+ return -EPERM;
+}
+
+static int write_cpu_register(struct cpu_private *priv, const char *buf)
+{
+ int ret = -EPERM;
+ u64 val;
+
+ ret = strict_strtoull(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ /* Supporting only MSRs */
+ if (priv->type < CPU_TSS_BIT)
+ return write_msr(priv, val);
+
+ return ret;
+}
+
+static ssize_t cpu_write(struct file *file, const char __user *ubuf,
+ size_t count, loff_t *off)
+{
+ struct seq_file *seq = file->private_data;
+ struct cpu_private *priv = seq->private;
+ char buf[19];
+
+ if ((priv == NULL) || (count >= sizeof(buf)))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, count))
+ return -EFAULT;
+
+ buf[count] = 0;
+
+ if ((cpu_base[priv->type].write) && (cpu_file[priv->file].write))
+ if (!write_cpu_register(priv, buf))
+ return count;
+
+ return -EACCES;
+}
+
static const struct file_operations cpu_fops = {
+ .owner = THIS_MODULE,
.open = cpu_seq_open,
.read = seq_read,
+ .write = cpu_write,
.llseek = seq_lseek,
.release = seq_release,
};
diff --git a/arch/x86/kernel/cpu/cpufreq/Kconfig b/arch/x86/kernel/cpu/cpufreq/Kconfig
index 65792c2cc462..52c839875478 100644
--- a/arch/x86/kernel/cpu/cpufreq/Kconfig
+++ b/arch/x86/kernel/cpu/cpufreq/Kconfig
@@ -87,30 +87,15 @@ config X86_POWERNOW_K7_ACPI
config X86_POWERNOW_K8
tristate "AMD Opteron/Athlon64 PowerNow!"
select CPU_FREQ_TABLE
+ depends on ACPI && ACPI_PROCESSOR
help
- This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors.
+ This adds the CPUFreq driver for K8/K10 Opteron/Athlon64 processors.
To compile this driver as a module, choose M here: the
module will be called powernow-k8.
For details, take a look at <file:Documentation/cpu-freq/>.
- If in doubt, say N.
-
-config X86_POWERNOW_K8_ACPI
- bool
- prompt "ACPI Support" if X86_32
- depends on ACPI && X86_POWERNOW_K8 && ACPI_PROCESSOR
- depends on !(X86_POWERNOW_K8 = y && ACPI_PROCESSOR = m)
- default y
- help
- This provides access to the K8s Processor Performance States via ACPI.
- This driver is probably required for CPUFreq to work with multi-socket and
- SMP systems. It is not required on at least some single-socket yet
- multi-core systems, even if SMP is enabled.
-
- It is safe to say Y here.
-
config X86_GX_SUSPMOD
tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
depends on X86_32 && PCI
diff --git a/arch/x86/kernel/cpu/cpufreq/Makefile b/arch/x86/kernel/cpu/cpufreq/Makefile
index 560f7760dae5..509296df294d 100644
--- a/arch/x86/kernel/cpu/cpufreq/Makefile
+++ b/arch/x86/kernel/cpu/cpufreq/Makefile
@@ -1,6 +1,11 @@
+# Link order matters. K8 is preferred to ACPI because of firmware bugs in early
+# K8 systems. ACPI is preferred to all other hardware-specific drivers.
+# speedstep-* is preferred over p4-clockmod.
+
+obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
+obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o
obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o
-obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o
obj-$(CONFIG_X86_LONGHAUL) += longhaul.o
obj-$(CONFIG_X86_E_POWERSAVER) += e_powersaver.o
obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o
@@ -10,7 +15,6 @@ obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o
obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o
obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o
obj-$(CONFIG_X86_SPEEDSTEP_SMI) += speedstep-smi.o
-obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o
obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o
obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o
obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 5e40f54171e7..19f6b9d27e83 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -1,5 +1,5 @@
/*
- * acpi-cpufreq.c - ACPI Processor P-States Driver ($Revision: 1.4 $)
+ * acpi-cpufreq.c - ACPI Processor P-States Driver
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
@@ -36,16 +36,18 @@
#include <trace/power.h>
#include <linux/acpi.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+
#include <acpi/processor.h>
-#include <asm/io.h>
#include <asm/msr.h>
#include <asm/processor.h>
#include <asm/cpufeature.h>
-#include <asm/delay.h>
-#include <asm/uaccess.h>
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "acpi-cpufreq", msg)
MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
MODULE_DESCRIPTION("ACPI Processor P-States Driver");
@@ -97,7 +99,7 @@ static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)
perf = data->acpi_data;
- for (i=0; i<perf->state_count; i++) {
+ for (i = 0; i < perf->state_count; i++) {
if (value == perf->states[i].status)
return data->freq_table[i].frequency;
}
@@ -112,7 +114,7 @@ static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
msr &= INTEL_MSR_RANGE;
perf = data->acpi_data;
- for (i=0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
if (msr == perf->states[data->freq_table[i].index].status)
return data->freq_table[i].frequency;
}
@@ -140,15 +142,13 @@ struct io_addr {
u8 bit_width;
};
-typedef union {
- struct msr_addr msr;
- struct io_addr io;
-} drv_addr_union;
-
struct drv_cmd {
unsigned int type;
const struct cpumask *mask;
- drv_addr_union addr;
+ union {
+ struct msr_addr msr;
+ struct io_addr io;
+ } addr;
u32 val;
};
@@ -371,7 +371,7 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq,
unsigned int cur_freq;
unsigned int i;
- for (i=0; i<100; i++) {
+ for (i = 0; i < 100; i++) {
cur_freq = extract_freq(get_cur_val(mask), data);
if (cur_freq == freq)
return 1;
@@ -496,7 +496,7 @@ acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu)
unsigned long freq;
unsigned long freqn = perf->states[0].core_frequency * 1000;
- for (i=0; i<(perf->state_count-1); i++) {
+ for (i = 0; i < (perf->state_count-1); i++) {
freq = freqn;
freqn = perf->states[i+1].core_frequency * 1000;
if ((2 * cpu_khz) > (freqn + freq)) {
@@ -675,17 +675,29 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
/* detect transition latency */
policy->cpuinfo.transition_latency = 0;
- for (i=0; i<perf->state_count; i++) {
+ for (i = 0; i < perf->state_count; i++) {
if ((perf->states[i].transition_latency * 1000) >
policy->cpuinfo.transition_latency)
policy->cpuinfo.transition_latency =
perf->states[i].transition_latency * 1000;
}
+ /* Check for high latency (>20uS) from buggy BIOSes, like on T42 */
+ if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE &&
+ policy->cpuinfo.transition_latency > 20 * 1000) {
+ static int print_once;
+ policy->cpuinfo.transition_latency = 20 * 1000;
+ if (!print_once) {
+ print_once = 1;
+ printk(KERN_INFO "Capping off P-state tranision latency"
+ " at 20 uS\n");
+ }
+ }
+
data->max_freq = perf->states[0].core_frequency * 1000;
/* table init */
- for (i=0; i<perf->state_count; i++) {
- if (i>0 && perf->states[i].core_frequency >=
+ for (i = 0; i < perf->state_count; i++) {
+ if (i > 0 && perf->states[i].core_frequency >=
data->freq_table[valid_states-1].frequency / 1000)
continue;
diff --git a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
index 965ea52767ac..733093d60436 100644
--- a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
+++ b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
@@ -32,7 +32,7 @@
* nforce2_chipset:
* FSB is changed using the chipset
*/
-static struct pci_dev *nforce2_chipset_dev;
+static struct pci_dev *nforce2_dev;
/* fid:
* multiplier * 10
@@ -56,7 +56,9 @@ MODULE_PARM_DESC(fid, "CPU multiplier to use (11.5 = 115)");
MODULE_PARM_DESC(min_fsb,
"Minimum FSB to use, if not defined: current FSB - 50");
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "cpufreq-nforce2", msg)
+#define PFX "cpufreq-nforce2: "
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "cpufreq-nforce2", msg)
/**
* nforce2_calc_fsb - calculate FSB
@@ -118,11 +120,11 @@ static void nforce2_write_pll(int pll)
int temp;
/* Set the pll addr. to 0x00 */
- pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLADR, 0);
+ pci_write_config_dword(nforce2_dev, NFORCE2_PLLADR, 0);
/* Now write the value in all 64 registers */
for (temp = 0; temp <= 0x3f; temp++)
- pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLREG, pll);
+ pci_write_config_dword(nforce2_dev, NFORCE2_PLLREG, pll);
return;
}
@@ -139,8 +141,8 @@ static unsigned int nforce2_fsb_read(int bootfsb)
u32 fsb, temp = 0;
/* Get chipset boot FSB from subdevice 5 (FSB at boot-time) */
- nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
- 0x01EF, PCI_ANY_ID, PCI_ANY_ID, NULL);
+ nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, 0x01EF,
+ PCI_ANY_ID, PCI_ANY_ID, NULL);
if (!nforce2_sub5)
return 0;
@@ -148,13 +150,13 @@ static unsigned int nforce2_fsb_read(int bootfsb)
fsb /= 1000000;
/* Check if PLL register is already set */
- pci_read_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
+ pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
if (bootfsb || !temp)
return fsb;
/* Use PLL register FSB value */
- pci_read_config_dword(nforce2_chipset_dev, NFORCE2_PLLREG, &temp);
+ pci_read_config_dword(nforce2_dev, NFORCE2_PLLREG, &temp);
fsb = nforce2_calc_fsb(temp);
return fsb;
@@ -174,18 +176,18 @@ static int nforce2_set_fsb(unsigned int fsb)
int pll = 0;
if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
- printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);
+ printk(KERN_ERR PFX "FSB %d is out of range!\n", fsb);
return -EINVAL;
}
tfsb = nforce2_fsb_read(0);
if (!tfsb) {
- printk(KERN_ERR "cpufreq: Error while reading the FSB\n");
+ printk(KERN_ERR PFX "Error while reading the FSB\n");
return -EINVAL;
}
/* First write? Then set actual value */
- pci_read_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
+ pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
if (!temp) {
pll = nforce2_calc_pll(tfsb);
@@ -197,7 +199,7 @@ static int nforce2_set_fsb(unsigned int fsb)
/* Enable write access */
temp = 0x01;
- pci_write_config_byte(nforce2_chipset_dev, NFORCE2_PLLENABLE, (u8)temp);
+ pci_write_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8)temp);
diff = tfsb - fsb;
@@ -222,7 +224,7 @@ static int nforce2_set_fsb(unsigned int fsb)
}
temp = 0x40;
- pci_write_config_byte(nforce2_chipset_dev, NFORCE2_PLLADR, (u8)temp);
+ pci_write_config_byte(nforce2_dev, NFORCE2_PLLADR, (u8)temp);
return 0;
}
@@ -244,7 +246,8 @@ static unsigned int nforce2_get(unsigned int cpu)
* nforce2_target - set a new CPUFreq policy
* @policy: new policy
* @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ * @relation: how that frequency relates to achieved frequency
+ * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
*
* Sets a new CPUFreq policy.
*/
@@ -276,7 +279,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
/* local_irq_save(flags); */
if (nforce2_set_fsb(target_fsb) < 0)
- printk(KERN_ERR "cpufreq: Changing FSB to %d failed\n",
+ printk(KERN_ERR PFX "Changing FSB to %d failed\n",
target_fsb);
else
dprintk("Changed FSB successfully to %d\n",
@@ -327,8 +330,8 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy)
/* FIX: Get FID from CPU */
if (!fid) {
if (!cpu_khz) {
- printk(KERN_WARNING
- "cpufreq: cpu_khz not set, can't calculate multiplier!\n");
+ printk(KERN_WARNING PFX
+ "cpu_khz not set, can't calculate multiplier!\n");
return -ENODEV;
}
@@ -343,7 +346,7 @@ static int nforce2_cpu_init(struct cpufreq_policy *policy)
}
}
- printk(KERN_INFO "cpufreq: FSB currently at %i MHz, FID %d.%d\n", fsb,
+ printk(KERN_INFO PFX "FSB currently at %i MHz, FID %d.%d\n", fsb,
fid / 10, fid % 10);
/* Set maximum FSB to FSB at boot time */
@@ -392,17 +395,18 @@ static struct cpufreq_driver nforce2_driver = {
*/
static unsigned int nforce2_detect_chipset(void)
{
- nforce2_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
+ nforce2_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
PCI_DEVICE_ID_NVIDIA_NFORCE2,
PCI_ANY_ID, PCI_ANY_ID, NULL);
- if (nforce2_chipset_dev == NULL)
+ if (nforce2_dev == NULL)
return -ENODEV;
- printk(KERN_INFO "cpufreq: Detected nForce2 chipset revision %X\n",
- nforce2_chipset_dev->revision);
- printk(KERN_INFO
- "cpufreq: FSB changing is maybe unstable and can lead to crashes and data loss.\n");
+ printk(KERN_INFO PFX "Detected nForce2 chipset revision %X\n",
+ nforce2_dev->revision);
+ printk(KERN_INFO PFX
+ "FSB changing is maybe unstable and can lead to "
+ "crashes and data loss.\n");
return 0;
}
@@ -420,7 +424,7 @@ static int __init nforce2_init(void)
/* detect chipset */
if (nforce2_detect_chipset()) {
- printk(KERN_ERR "cpufreq: No nForce2 chipset.\n");
+ printk(KERN_INFO PFX "No nForce2 chipset.\n");
return -ENODEV;
}
diff --git a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
index 41ab3f064cb1..35a257dd4bb7 100644
--- a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
+++ b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
@@ -12,12 +12,12 @@
#include <linux/cpufreq.h>
#include <linux/ioport.h>
#include <linux/slab.h>
+#include <linux/timex.h>
+#include <linux/io.h>
+#include <linux/delay.h>
#include <asm/msr.h>
#include <asm/tsc.h>
-#include <asm/timex.h>
-#include <asm/io.h>
-#include <asm/delay.h>
#define EPS_BRAND_C7M 0
#define EPS_BRAND_C7 1
@@ -184,7 +184,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
break;
}
- switch(brand) {
+ switch (brand) {
case EPS_BRAND_C7M:
printk(KERN_CONT "C7-M\n");
break;
@@ -218,17 +218,20 @@ static int eps_cpu_init(struct cpufreq_policy *policy)
/* Print voltage and multiplier */
rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
current_voltage = lo & 0xff;
- printk(KERN_INFO "eps: Current voltage = %dmV\n", current_voltage * 16 + 700);
+ printk(KERN_INFO "eps: Current voltage = %dmV\n",
+ current_voltage * 16 + 700);
current_multiplier = (lo >> 8) & 0xff;
printk(KERN_INFO "eps: Current multiplier = %d\n", current_multiplier);
/* Print limits */
max_voltage = hi & 0xff;
- printk(KERN_INFO "eps: Highest voltage = %dmV\n", max_voltage * 16 + 700);
+ printk(KERN_INFO "eps: Highest voltage = %dmV\n",
+ max_voltage * 16 + 700);
max_multiplier = (hi >> 8) & 0xff;
printk(KERN_INFO "eps: Highest multiplier = %d\n", max_multiplier);
min_voltage = (hi >> 16) & 0xff;
- printk(KERN_INFO "eps: Lowest voltage = %dmV\n", min_voltage * 16 + 700);
+ printk(KERN_INFO "eps: Lowest voltage = %dmV\n",
+ min_voltage * 16 + 700);
min_multiplier = (hi >> 24) & 0xff;
printk(KERN_INFO "eps: Lowest multiplier = %d\n", min_multiplier);
@@ -318,7 +321,7 @@ static int eps_cpu_exit(struct cpufreq_policy *policy)
return 0;
}
-static struct freq_attr* eps_attr[] = {
+static struct freq_attr *eps_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};
@@ -356,7 +359,7 @@ static void __exit eps_exit(void)
cpufreq_unregister_driver(&eps_driver);
}
-MODULE_AUTHOR("Rafa Bilski <rafalbilski@interia.pl>");
+MODULE_AUTHOR("Rafal Bilski <rafalbilski@interia.pl>");
MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's.");
MODULE_LICENSE("GPL");
diff --git a/arch/x86/kernel/cpu/cpufreq/elanfreq.c b/arch/x86/kernel/cpu/cpufreq/elanfreq.c
index fe613c93b366..006b278b0d5d 100644
--- a/arch/x86/kernel/cpu/cpufreq/elanfreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/elanfreq.c
@@ -184,7 +184,8 @@ static int elanfreq_target(struct cpufreq_policy *policy,
{
unsigned int newstate = 0;
- if (cpufreq_frequency_table_target(policy, &elanfreq_table[0], target_freq, relation, &newstate))
+ if (cpufreq_frequency_table_target(policy, &elanfreq_table[0],
+ target_freq, relation, &newstate))
return -EINVAL;
elanfreq_set_cpu_state(newstate);
@@ -301,7 +302,8 @@ static void __exit elanfreq_exit(void)
module_param(max_freq, int, 0444);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, Sven Geggus <sven@geggus.net>");
+MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, "
+ "Sven Geggus <sven@geggus.net>");
MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs");
module_init(elanfreq_init);
diff --git a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
index 9d9eae82e60f..ac27ec2264d5 100644
--- a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
@@ -79,8 +79,9 @@
#include <linux/smp.h>
#include <linux/cpufreq.h>
#include <linux/pci.h>
+#include <linux/errno.h>
+
#include <asm/processor-cyrix.h>
-#include <asm/errno.h>
/* PCI config registers, all at F0 */
#define PCI_PMER1 0x80 /* power management enable register 1 */
@@ -122,8 +123,8 @@ static struct gxfreq_params *gx_params;
static int stock_freq;
/* PCI bus clock - defaults to 30.000 if cpu_khz is not available */
-static int pci_busclk = 0;
-module_param (pci_busclk, int, 0444);
+static int pci_busclk;
+module_param(pci_busclk, int, 0444);
/* maximum duration for which the cpu may be suspended
* (32us * MAX_DURATION). If no parameter is given, this defaults
@@ -132,7 +133,7 @@ module_param (pci_busclk, int, 0444);
* is suspended -- processing power is just 0.39% of what it used to be,
* though. 781.25 kHz(!) for a 200 MHz processor -- wow. */
static int max_duration = 255;
-module_param (max_duration, int, 0444);
+module_param(max_duration, int, 0444);
/* For the default policy, we want at least some processing power
* - let's say 5%. (min = maxfreq / POLICY_MIN_DIV)
@@ -140,7 +141,8 @@ module_param (max_duration, int, 0444);
#define POLICY_MIN_DIV 20
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "gx-suspmod", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "gx-suspmod", msg)
/**
* we can detect a core multipiler from dir0_lsb
@@ -166,12 +168,20 @@ static int gx_freq_mult[16] = {
* Low Level chipset interface *
****************************************************************/
static struct pci_device_id gx_chipset_tbl[] __initdata = {
- { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520,
+ PCI_ANY_ID, PCI_ANY_ID },
+ { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510,
+ PCI_ANY_ID, PCI_ANY_ID },
{ 0, },
};
+static void gx_write_byte(int reg, int value)
+{
+ pci_write_config_byte(gx_params->cs55x0, reg, value);
+}
+
/**
* gx_detect_chipset:
*
@@ -200,7 +210,8 @@ static __init struct pci_dev *gx_detect_chipset(void)
/**
* gx_get_cpuspeed:
*
- * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi Geode CPU runs.
+ * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi
+ * Geode CPU runs.
*/
static unsigned int gx_get_cpuspeed(unsigned int cpu)
{
@@ -217,17 +228,18 @@ static unsigned int gx_get_cpuspeed(unsigned int cpu)
*
**/
-static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration, u8 *off_duration)
+static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration,
+ u8 *off_duration)
{
unsigned int i;
u8 tmp_on, tmp_off;
int old_tmp_freq = stock_freq;
int tmp_freq;
- *off_duration=1;
- *on_duration=0;
+ *off_duration = 1;
+ *on_duration = 0;
- for (i=max_duration; i>0; i--) {
+ for (i = max_duration; i > 0; i--) {
tmp_off = ((khz * i) / stock_freq) & 0xff;
tmp_on = i - tmp_off;
tmp_freq = (stock_freq * tmp_off) / i;
@@ -259,26 +271,34 @@ static void gx_set_cpuspeed(unsigned int khz)
freqs.cpu = 0;
freqs.old = gx_get_cpuspeed(0);
- new_khz = gx_validate_speed(khz, &gx_params->on_duration, &gx_params->off_duration);
+ new_khz = gx_validate_speed(khz, &gx_params->on_duration,
+ &gx_params->off_duration);
freqs.new = new_khz;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
local_irq_save(flags);
- if (new_khz != stock_freq) { /* if new khz == 100% of CPU speed, it is special case */
+
+
+ if (new_khz != stock_freq) {
+ /* if new khz == 100% of CPU speed, it is special case */
switch (gx_params->cs55x0->device) {
case PCI_DEVICE_ID_CYRIX_5530_LEGACY:
pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP;
/* FIXME: need to test other values -- Zwane,Miura */
- pci_write_config_byte(gx_params->cs55x0, PCI_IRQTC, 4); /* typical 2 to 4ms */
- pci_write_config_byte(gx_params->cs55x0, PCI_VIDTC, 100);/* typical 50 to 100ms */
- pci_write_config_byte(gx_params->cs55x0, PCI_PMER1, pmer1);
-
- if (gx_params->cs55x0->revision < 0x10) { /* CS5530(rev 1.2, 1.3) */
- suscfg = gx_params->pci_suscfg | SUSMOD;
- } else { /* CS5530A,B.. */
- suscfg = gx_params->pci_suscfg | SUSMOD | PWRSVE;
+ /* typical 2 to 4ms */
+ gx_write_byte(PCI_IRQTC, 4);
+ /* typical 50 to 100ms */
+ gx_write_byte(PCI_VIDTC, 100);
+ gx_write_byte(PCI_PMER1, pmer1);
+
+ if (gx_params->cs55x0->revision < 0x10) {
+ /* CS5530(rev 1.2, 1.3) */
+ suscfg = gx_params->pci_suscfg|SUSMOD;
+ } else {
+ /* CS5530A,B.. */
+ suscfg = gx_params->pci_suscfg|SUSMOD|PWRSVE;
}
break;
case PCI_DEVICE_ID_CYRIX_5520:
@@ -294,13 +314,13 @@ static void gx_set_cpuspeed(unsigned int khz)
suscfg = gx_params->pci_suscfg & ~(SUSMOD);
gx_params->off_duration = 0;
gx_params->on_duration = 0;
- dprintk("suspend modulation disabled: cpu runs 100 percent speed.\n");
+ dprintk("suspend modulation disabled: cpu runs 100%% speed.\n");
}
- pci_write_config_byte(gx_params->cs55x0, PCI_MODOFF, gx_params->off_duration);
- pci_write_config_byte(gx_params->cs55x0, PCI_MODON, gx_params->on_duration);
+ gx_write_byte(PCI_MODOFF, gx_params->off_duration);
+ gx_write_byte(PCI_MODON, gx_params->on_duration);
- pci_write_config_byte(gx_params->cs55x0, PCI_SUSCFG, suscfg);
+ gx_write_byte(PCI_SUSCFG, suscfg);
pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg);
local_irq_restore(flags);
@@ -334,7 +354,8 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy)
return -EINVAL;
policy->cpu = 0;
- cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq);
+ cpufreq_verify_within_limits(policy, (stock_freq / max_duration),
+ stock_freq);
/* it needs to be assured that at least one supported frequency is
* within policy->min and policy->max. If it is not, policy->max
@@ -354,7 +375,8 @@ static int cpufreq_gx_verify(struct cpufreq_policy *policy)
policy->max = tmp_freq;
if (policy->max < policy->min)
policy->max = policy->min;
- cpufreq_verify_within_limits(policy, (stock_freq / max_duration), stock_freq);
+ cpufreq_verify_within_limits(policy, (stock_freq / max_duration),
+ stock_freq);
return 0;
}
@@ -398,18 +420,18 @@ static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy)
return -ENODEV;
/* determine maximum frequency */
- if (pci_busclk) {
+ if (pci_busclk)
maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
- } else if (cpu_khz) {
+ else if (cpu_khz)
maxfreq = cpu_khz;
- } else {
+ else
maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
- }
+
stock_freq = maxfreq;
curfreq = gx_get_cpuspeed(0);
dprintk("cpu max frequency is %d.\n", maxfreq);
- dprintk("cpu current frequency is %dkHz.\n",curfreq);
+ dprintk("cpu current frequency is %dkHz.\n", curfreq);
/* setup basic struct for cpufreq API */
policy->cpu = 0;
@@ -447,7 +469,8 @@ static int __init cpufreq_gx_init(void)
struct pci_dev *gx_pci;
/* Test if we have the right hardware */
- if ((gx_pci = gx_detect_chipset()) == NULL)
+ gx_pci = gx_detect_chipset();
+ if (gx_pci == NULL)
return -ENODEV;
/* check whether module parameters are sane */
@@ -468,9 +491,11 @@ static int __init cpufreq_gx_init(void)
pci_read_config_byte(params->cs55x0, PCI_PMER1, &(params->pci_pmer1));
pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2));
pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration));
- pci_read_config_byte(params->cs55x0, PCI_MODOFF, &(params->off_duration));
+ pci_read_config_byte(params->cs55x0, PCI_MODOFF,
+ &(params->off_duration));
- if ((ret = cpufreq_register_driver(&gx_suspmod_driver))) {
+ ret = cpufreq_register_driver(&gx_suspmod_driver);
+ if (ret) {
kfree(params);
return ret; /* register error! */
}
@@ -485,9 +510,9 @@ static void __exit cpufreq_gx_exit(void)
kfree(gx_params);
}
-MODULE_AUTHOR ("Hiroshi Miura <miura@da-cha.org>");
-MODULE_DESCRIPTION ("Cpufreq driver for Cyrix MediaGX and NatSemi Geode");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Hiroshi Miura <miura@da-cha.org>");
+MODULE_DESCRIPTION("Cpufreq driver for Cyrix MediaGX and NatSemi Geode");
+MODULE_LICENSE("GPL");
module_init(cpufreq_gx_init);
module_exit(cpufreq_gx_exit);
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c
index a4cff5d6e380..0bd48e65a0ca 100644
--- a/arch/x86/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c
@@ -30,12 +30,12 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/delay.h>
+#include <linux/timex.h>
+#include <linux/io.h>
+#include <linux/acpi.h>
+#include <linux/kernel.h>
#include <asm/msr.h>
-#include <asm/timex.h>
-#include <asm/io.h>
-#include <asm/acpi.h>
-#include <linux/acpi.h>
#include <acpi/processor.h>
#include "longhaul.h"
@@ -58,7 +58,7 @@
#define USE_NORTHBRIDGE (1 << 2)
static int cpu_model;
-static unsigned int numscales=16;
+static unsigned int numscales = 16;
static unsigned int fsb;
static const struct mV_pos *vrm_mV_table;
@@ -67,8 +67,8 @@ static const unsigned char *mV_vrm_table;
static unsigned int highest_speed, lowest_speed; /* kHz */
static unsigned int minmult, maxmult;
static int can_scale_voltage;
-static struct acpi_processor *pr = NULL;
-static struct acpi_processor_cx *cx = NULL;
+static struct acpi_processor *pr;
+static struct acpi_processor_cx *cx;
static u32 acpi_regs_addr;
static u8 longhaul_flags;
static unsigned int longhaul_index;
@@ -78,12 +78,13 @@ static int scale_voltage;
static int disable_acpi_c3;
static int revid_errata;
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longhaul", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "longhaul", msg)
/* Clock ratios multiplied by 10 */
-static int clock_ratio[32];
-static int eblcr_table[32];
+static int mults[32];
+static int eblcr[32];
static int longhaul_version;
static struct cpufreq_frequency_table *longhaul_table;
@@ -93,7 +94,7 @@ static char speedbuffer[8];
static char *print_speed(int speed)
{
if (speed < 1000) {
- snprintf(speedbuffer, sizeof(speedbuffer),"%dMHz", speed);
+ snprintf(speedbuffer, sizeof(speedbuffer), "%dMHz", speed);
return speedbuffer;
}
@@ -122,27 +123,28 @@ static unsigned int calc_speed(int mult)
static int longhaul_get_cpu_mult(void)
{
- unsigned long invalue=0,lo, hi;
+ unsigned long invalue = 0, lo, hi;
- rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);
- invalue = (lo & (1<<22|1<<23|1<<24|1<<25)) >>22;
- if (longhaul_version==TYPE_LONGHAUL_V2 || longhaul_version==TYPE_POWERSAVER) {
+ rdmsr(MSR_IA32_EBL_CR_POWERON, lo, hi);
+ invalue = (lo & (1<<22|1<<23|1<<24|1<<25))>>22;
+ if (longhaul_version == TYPE_LONGHAUL_V2 ||
+ longhaul_version == TYPE_POWERSAVER) {
if (lo & (1<<27))
- invalue+=16;
+ invalue += 16;
}
- return eblcr_table[invalue];
+ return eblcr[invalue];
}
/* For processor with BCR2 MSR */
-static void do_longhaul1(unsigned int clock_ratio_index)
+static void do_longhaul1(unsigned int mults_index)
{
union msr_bcr2 bcr2;
rdmsrl(MSR_VIA_BCR2, bcr2.val);
/* Enable software clock multiplier */
bcr2.bits.ESOFTBF = 1;
- bcr2.bits.CLOCKMUL = clock_ratio_index & 0xff;
+ bcr2.bits.CLOCKMUL = mults_index & 0xff;
/* Sync to timer tick */
safe_halt();
@@ -161,7 +163,7 @@ static void do_longhaul1(unsigned int clock_ratio_index)
/* For processor with Longhaul MSR */
-static void do_powersaver(int cx_address, unsigned int clock_ratio_index,
+static void do_powersaver(int cx_address, unsigned int mults_index,
unsigned int dir)
{
union msr_longhaul longhaul;
@@ -173,11 +175,11 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index,
longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
else
longhaul.bits.RevisionKey = 0;
- longhaul.bits.SoftBusRatio = clock_ratio_index & 0xf;
- longhaul.bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
+ longhaul.bits.SoftBusRatio = mults_index & 0xf;
+ longhaul.bits.SoftBusRatio4 = (mults_index & 0x10) >> 4;
/* Setup new voltage */
if (can_scale_voltage)
- longhaul.bits.SoftVID = (clock_ratio_index >> 8) & 0x1f;
+ longhaul.bits.SoftVID = (mults_index >> 8) & 0x1f;
/* Sync to timer tick */
safe_halt();
/* Raise voltage if necessary */
@@ -240,14 +242,14 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index,
/**
* longhaul_set_cpu_frequency()
- * @clock_ratio_index : bitpattern of the new multiplier.
+ * @mults_index : bitpattern of the new multiplier.
*
* Sets a new clock ratio.
*/
static void longhaul_setstate(unsigned int table_index)
{
- unsigned int clock_ratio_index;
+ unsigned int mults_index;
int speed, mult;
struct cpufreq_freqs freqs;
unsigned long flags;
@@ -256,9 +258,9 @@ static void longhaul_setstate(unsigned int table_index)
u32 bm_timeout = 1000;
unsigned int dir = 0;
- clock_ratio_index = longhaul_table[table_index].index;
+ mults_index = longhaul_table[table_index].index;
/* Safety precautions */
- mult = clock_ratio[clock_ratio_index & 0x1f];
+ mult = mults[mults_index & 0x1f];
if (mult == -1)
return;
speed = calc_speed(mult);
@@ -274,7 +276,7 @@ static void longhaul_setstate(unsigned int table_index)
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- dprintk ("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
+ dprintk("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
fsb, mult/10, mult%10, print_speed(speed/1000));
retry_loop:
preempt_disable();
@@ -282,8 +284,8 @@ retry_loop:
pic2_mask = inb(0xA1);
pic1_mask = inb(0x21); /* works on C3. save mask. */
- outb(0xFF,0xA1); /* Overkill */
- outb(0xFE,0x21); /* TMR0 only */
+ outb(0xFF, 0xA1); /* Overkill */
+ outb(0xFE, 0x21); /* TMR0 only */
/* Wait while PCI bus is busy. */
if (acpi_regs_addr && (longhaul_flags & USE_NORTHBRIDGE
@@ -303,7 +305,7 @@ retry_loop:
outb(3, 0x22);
} else if ((pr != NULL) && pr->flags.bm_control) {
/* Disable bus master arbitration */
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+ acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
}
switch (longhaul_version) {
@@ -312,7 +314,7 @@ retry_loop:
* Software controlled multipliers only.
*/
case TYPE_LONGHAUL_V1:
- do_longhaul1(clock_ratio_index);
+ do_longhaul1(mults_index);
break;
/*
@@ -326,10 +328,10 @@ retry_loop:
case TYPE_POWERSAVER:
if (longhaul_flags & USE_ACPI_C3) {
/* Don't allow wakeup */
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
- do_powersaver(cx->address, clock_ratio_index, dir);
+ acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
+ do_powersaver(cx->address, mults_index, dir);
} else {
- do_powersaver(0, clock_ratio_index, dir);
+ do_powersaver(0, mults_index, dir);
}
break;
}
@@ -339,10 +341,10 @@ retry_loop:
outb(0, 0x22);
} else if ((pr != NULL) && pr->flags.bm_control) {
/* Enable bus master arbitration */
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+ acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
}
- outb(pic2_mask,0xA1); /* restore mask */
- outb(pic1_mask,0x21);
+ outb(pic2_mask, 0xA1); /* restore mask */
+ outb(pic1_mask, 0x21);
local_irq_restore(flags);
preempt_enable();
@@ -392,7 +394,8 @@ retry_loop:
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
if (!bm_timeout)
- printk(KERN_INFO PFX "Warning: Timeout while waiting for idle PCI bus.\n");
+ printk(KERN_INFO PFX "Warning: Timeout while waiting for "
+ "idle PCI bus.\n");
}
/*
@@ -458,31 +461,32 @@ static int __init longhaul_get_ranges(void)
break;
}
- dprintk ("MinMult:%d.%dx MaxMult:%d.%dx\n",
+ dprintk("MinMult:%d.%dx MaxMult:%d.%dx\n",
minmult/10, minmult%10, maxmult/10, maxmult%10);
highest_speed = calc_speed(maxmult);
lowest_speed = calc_speed(minmult);
- dprintk ("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb,
+ dprintk("FSB:%dMHz Lowest speed: %s Highest speed:%s\n", fsb,
print_speed(lowest_speed/1000),
print_speed(highest_speed/1000));
if (lowest_speed == highest_speed) {
- printk (KERN_INFO PFX "highestspeed == lowest, aborting.\n");
+ printk(KERN_INFO PFX "highestspeed == lowest, aborting.\n");
return -EINVAL;
}
if (lowest_speed > highest_speed) {
- printk (KERN_INFO PFX "nonsense! lowest (%d > %d) !\n",
+ printk(KERN_INFO PFX "nonsense! lowest (%d > %d) !\n",
lowest_speed, highest_speed);
return -EINVAL;
}
- longhaul_table = kmalloc((numscales + 1) * sizeof(struct cpufreq_frequency_table), GFP_KERNEL);
- if(!longhaul_table)
+ longhaul_table = kmalloc((numscales + 1) * sizeof(*longhaul_table),
+ GFP_KERNEL);
+ if (!longhaul_table)
return -ENOMEM;
for (j = 0; j < numscales; j++) {
- ratio = clock_ratio[j];
+ ratio = mults[j];
if (ratio == -1)
continue;
if (ratio > maxmult || ratio < minmult)
@@ -507,13 +511,10 @@ static int __init longhaul_get_ranges(void)
}
}
if (min_i != j) {
- unsigned int temp;
- temp = longhaul_table[j].frequency;
- longhaul_table[j].frequency = longhaul_table[min_i].frequency;
- longhaul_table[min_i].frequency = temp;
- temp = longhaul_table[j].index;
- longhaul_table[j].index = longhaul_table[min_i].index;
- longhaul_table[min_i].index = temp;
+ swap(longhaul_table[j].frequency,
+ longhaul_table[min_i].frequency);
+ swap(longhaul_table[j].index,
+ longhaul_table[min_i].index);
}
}
@@ -521,7 +522,7 @@ static int __init longhaul_get_ranges(void)
/* Find index we are running on */
for (j = 0; j < k; j++) {
- if (clock_ratio[longhaul_table[j].index & 0x1f] == mult) {
+ if (mults[longhaul_table[j].index & 0x1f] == mult) {
longhaul_index = j;
break;
}
@@ -559,20 +560,22 @@ static void __init longhaul_setup_voltagescaling(void)
maxvid = vrm_mV_table[longhaul.bits.MaximumVID];
if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) {
- printk (KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
+ printk(KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
"Voltage scaling disabled.\n",
- minvid.mV/1000, minvid.mV%1000, maxvid.mV/1000, maxvid.mV%1000);
+ minvid.mV/1000, minvid.mV%1000,
+ maxvid.mV/1000, maxvid.mV%1000);
return;
}
if (minvid.mV == maxvid.mV) {
- printk (KERN_INFO PFX "Claims to support voltage scaling but min & max are "
- "both %d.%03d. Voltage scaling disabled\n",
+ printk(KERN_INFO PFX "Claims to support voltage scaling but "
+ "min & max are both %d.%03d. "
+ "Voltage scaling disabled\n",
maxvid.mV/1000, maxvid.mV%1000);
return;
}
- /* How many voltage steps */
+ /* How many voltage steps*/
numvscales = maxvid.pos - minvid.pos + 1;
printk(KERN_INFO PFX
"Max VID=%d.%03d "
@@ -586,7 +589,7 @@ static void __init longhaul_setup_voltagescaling(void)
j = longhaul.bits.MinMHzBR;
if (longhaul.bits.MinMHzBR4)
j += 16;
- min_vid_speed = eblcr_table[j];
+ min_vid_speed = eblcr[j];
if (min_vid_speed == -1)
return;
switch (longhaul.bits.MinMHzFSB) {
@@ -617,7 +620,8 @@ static void __init longhaul_setup_voltagescaling(void)
pos = minvid.pos;
longhaul_table[j].index |= mV_vrm_table[pos] << 8;
vid = vrm_mV_table[mV_vrm_table[pos]];
- printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n", speed, j, vid.mV);
+ printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n",
+ speed, j, vid.mV);
j++;
}
@@ -640,7 +644,8 @@ static int longhaul_target(struct cpufreq_policy *policy,
unsigned int dir = 0;
u8 vid, current_vid;
- if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq, relation, &table_index))
+ if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq,
+ relation, &table_index))
return -EINVAL;
/* Don't set same frequency again */
@@ -656,7 +661,8 @@ static int longhaul_target(struct cpufreq_policy *policy,
* this in hardware, C3 is old and we need to do this
* in software. */
i = longhaul_index;
- current_vid = (longhaul_table[longhaul_index].index >> 8) & 0x1f;
+ current_vid = (longhaul_table[longhaul_index].index >> 8);
+ current_vid &= 0x1f;
if (table_index > longhaul_index)
dir = 1;
while (i != table_index) {
@@ -691,9 +697,9 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
{
struct acpi_device *d;
- if ( acpi_bus_get_device(obj_handle, &d) ) {
+ if (acpi_bus_get_device(obj_handle, &d))
return 0;
- }
+
*return_value = acpi_driver_data(d);
return 1;
}
@@ -750,7 +756,7 @@ static int longhaul_setup_southbridge(void)
/* Find VT8235 southbridge */
dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL);
if (dev == NULL)
- /* Find VT8237 southbridge */
+ /* Find VT8237 southbridge */
dev = pci_get_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_8237, NULL);
if (dev != NULL) {
@@ -769,7 +775,8 @@ static int longhaul_setup_southbridge(void)
if (pci_cmd & 1 << 7) {
pci_read_config_dword(dev, 0x88, &acpi_regs_addr);
acpi_regs_addr &= 0xff00;
- printk(KERN_INFO PFX "ACPI I/O at 0x%x\n", acpi_regs_addr);
+ printk(KERN_INFO PFX "ACPI I/O at 0x%x\n",
+ acpi_regs_addr);
}
pci_dev_put(dev);
@@ -781,7 +788,7 @@ static int longhaul_setup_southbridge(void)
static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
{
struct cpuinfo_x86 *c = &cpu_data(0);
- char *cpuname=NULL;
+ char *cpuname = NULL;
int ret;
u32 lo, hi;
@@ -791,8 +798,8 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
cpu_model = CPU_SAMUEL;
cpuname = "C3 'Samuel' [C5A]";
longhaul_version = TYPE_LONGHAUL_V1;
- memcpy (clock_ratio, samuel1_clock_ratio, sizeof(samuel1_clock_ratio));
- memcpy (eblcr_table, samuel1_eblcr, sizeof(samuel1_eblcr));
+ memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
+ memcpy(eblcr, samuel1_eblcr, sizeof(samuel1_eblcr));
break;
case 7:
@@ -803,10 +810,8 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
cpuname = "C3 'Samuel 2' [C5B]";
/* Note, this is not a typo, early Samuel2's had
* Samuel1 ratios. */
- memcpy(clock_ratio, samuel1_clock_ratio,
- sizeof(samuel1_clock_ratio));
- memcpy(eblcr_table, samuel2_eblcr,
- sizeof(samuel2_eblcr));
+ memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
+ memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr));
break;
case 1 ... 15:
longhaul_version = TYPE_LONGHAUL_V1;
@@ -817,10 +822,8 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
cpu_model = CPU_EZRA;
cpuname = "C3 'Ezra' [C5C]";
}
- memcpy(clock_ratio, ezra_clock_ratio,
- sizeof(ezra_clock_ratio));
- memcpy(eblcr_table, ezra_eblcr,
- sizeof(ezra_eblcr));
+ memcpy(mults, ezra_mults, sizeof(ezra_mults));
+ memcpy(eblcr, ezra_eblcr, sizeof(ezra_eblcr));
break;
}
break;
@@ -829,18 +832,16 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
cpu_model = CPU_EZRA_T;
cpuname = "C3 'Ezra-T' [C5M]";
longhaul_version = TYPE_POWERSAVER;
- numscales=32;
- memcpy (clock_ratio, ezrat_clock_ratio, sizeof(ezrat_clock_ratio));
- memcpy (eblcr_table, ezrat_eblcr, sizeof(ezrat_eblcr));
+ numscales = 32;
+ memcpy(mults, ezrat_mults, sizeof(ezrat_mults));
+ memcpy(eblcr, ezrat_eblcr, sizeof(ezrat_eblcr));
break;
case 9:
longhaul_version = TYPE_POWERSAVER;
numscales = 32;
- memcpy(clock_ratio,
- nehemiah_clock_ratio,
- sizeof(nehemiah_clock_ratio));
- memcpy(eblcr_table, nehemiah_eblcr, sizeof(nehemiah_eblcr));
+ memcpy(mults, nehemiah_mults, sizeof(nehemiah_mults));
+ memcpy(eblcr, nehemiah_eblcr, sizeof(nehemiah_eblcr));
switch (c->x86_mask) {
case 0 ... 1:
cpu_model = CPU_NEHEMIAH;
@@ -869,14 +870,14 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
longhaul_version = TYPE_LONGHAUL_V1;
}
- printk (KERN_INFO PFX "VIA %s CPU detected. ", cpuname);
+ printk(KERN_INFO PFX "VIA %s CPU detected. ", cpuname);
switch (longhaul_version) {
case TYPE_LONGHAUL_V1:
case TYPE_LONGHAUL_V2:
- printk ("Longhaul v%d supported.\n", longhaul_version);
+ printk(KERN_CONT "Longhaul v%d supported.\n", longhaul_version);
break;
case TYPE_POWERSAVER:
- printk ("Powersaver supported.\n");
+ printk(KERN_CONT "Powersaver supported.\n");
break;
};
@@ -940,7 +941,7 @@ static int __devexit longhaul_cpu_exit(struct cpufreq_policy *policy)
return 0;
}
-static struct freq_attr* longhaul_attr[] = {
+static struct freq_attr *longhaul_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};
@@ -966,13 +967,15 @@ static int __init longhaul_init(void)
#ifdef CONFIG_SMP
if (num_online_cpus() > 1) {
- printk(KERN_ERR PFX "More than 1 CPU detected, longhaul disabled.\n");
+ printk(KERN_ERR PFX "More than 1 CPU detected, "
+ "longhaul disabled.\n");
return -ENODEV;
}
#endif
#ifdef CONFIG_X86_IO_APIC
if (cpu_has_apic) {
- printk(KERN_ERR PFX "APIC detected. Longhaul is currently broken in this configuration.\n");
+ printk(KERN_ERR PFX "APIC detected. Longhaul is currently "
+ "broken in this configuration.\n");
return -ENODEV;
}
#endif
@@ -993,8 +996,8 @@ static void __exit longhaul_exit(void)
{
int i;
- for (i=0; i < numscales; i++) {
- if (clock_ratio[i] == maxmult) {
+ for (i = 0; i < numscales; i++) {
+ if (mults[i] == maxmult) {
longhaul_setstate(i);
break;
}
@@ -1007,11 +1010,11 @@ static void __exit longhaul_exit(void)
/* Even if BIOS is exporting ACPI C3 state, and it is used
* with success when CPU is idle, this state doesn't
* trigger frequency transition in some cases. */
-module_param (disable_acpi_c3, int, 0644);
+module_param(disable_acpi_c3, int, 0644);
MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support");
/* Change CPU voltage with frequency. Very usefull to save
* power, but most VIA C3 processors aren't supporting it. */
-module_param (scale_voltage, int, 0644);
+module_param(scale_voltage, int, 0644);
MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
/* Force revision key to 0 for processors which doesn't
* support voltage scaling, but are introducing itself as
@@ -1019,9 +1022,9 @@ MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
module_param(revid_errata, int, 0644);
MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID");
-MODULE_AUTHOR ("Dave Jones <davej@redhat.com>");
-MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
+MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors.");
+MODULE_LICENSE("GPL");
late_initcall(longhaul_init);
module_exit(longhaul_exit);
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.h b/arch/x86/kernel/cpu/cpufreq/longhaul.h
index 4fcc320997df..e2360a469f79 100644
--- a/arch/x86/kernel/cpu/cpufreq/longhaul.h
+++ b/arch/x86/kernel/cpu/cpufreq/longhaul.h
@@ -49,14 +49,14 @@ union msr_longhaul {
/*
* Clock ratio tables. Div/Mod by 10 to get ratio.
- * The eblcr ones specify the ratio read from the CPU.
- * The clock_ratio ones specify what to write to the CPU.
+ * The eblcr values specify the ratio read from the CPU.
+ * The mults values specify what to write to the CPU.
*/
/*
* VIA C3 Samuel 1 & Samuel 2 (stepping 0)
*/
-static const int __initdata samuel1_clock_ratio[16] = {
+static const int __initdata samuel1_mults[16] = {
-1, /* 0000 -> RESERVED */
30, /* 0001 -> 3.0x */
40, /* 0010 -> 4.0x */
@@ -119,7 +119,7 @@ static const int __initdata samuel2_eblcr[16] = {
/*
* VIA C3 Ezra
*/
-static const int __initdata ezra_clock_ratio[16] = {
+static const int __initdata ezra_mults[16] = {
100, /* 0000 -> 10.0x */
30, /* 0001 -> 3.0x */
40, /* 0010 -> 4.0x */
@@ -160,7 +160,7 @@ static const int __initdata ezra_eblcr[16] = {
/*
* VIA C3 (Ezra-T) [C5M].
*/
-static const int __initdata ezrat_clock_ratio[32] = {
+static const int __initdata ezrat_mults[32] = {
100, /* 0000 -> 10.0x */
30, /* 0001 -> 3.0x */
40, /* 0010 -> 4.0x */
@@ -235,7 +235,7 @@ static const int __initdata ezrat_eblcr[32] = {
/*
* VIA C3 Nehemiah */
-static const int __initdata nehemiah_clock_ratio[32] = {
+static const int __initdata nehemiah_mults[32] = {
100, /* 0000 -> 10.0x */
-1, /* 0001 -> 16.0x */
40, /* 0010 -> 4.0x */
diff --git a/arch/x86/kernel/cpu/cpufreq/longrun.c b/arch/x86/kernel/cpu/cpufreq/longrun.c
index 777a7ff075de..da5f70fcb766 100644
--- a/arch/x86/kernel/cpu/cpufreq/longrun.c
+++ b/arch/x86/kernel/cpu/cpufreq/longrun.c
@@ -11,12 +11,13 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/cpufreq.h>
+#include <linux/timex.h>
#include <asm/msr.h>
#include <asm/processor.h>
-#include <asm/timex.h>
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "longrun", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "longrun", msg)
static struct cpufreq_driver longrun_driver;
@@ -51,7 +52,7 @@ static void __init longrun_get_policy(struct cpufreq_policy *policy)
msr_lo &= 0x0000007F;
msr_hi &= 0x0000007F;
- if ( longrun_high_freq <= longrun_low_freq ) {
+ if (longrun_high_freq <= longrun_low_freq) {
/* Assume degenerate Longrun table */
policy->min = policy->max = longrun_high_freq;
} else {
@@ -79,7 +80,7 @@ static int longrun_set_policy(struct cpufreq_policy *policy)
if (!policy)
return -EINVAL;
- if ( longrun_high_freq <= longrun_low_freq ) {
+ if (longrun_high_freq <= longrun_low_freq) {
/* Assume degenerate Longrun table */
pctg_lo = pctg_hi = 100;
} else {
@@ -152,7 +153,7 @@ static unsigned int longrun_get(unsigned int cpu)
cpuid(0x80860007, &eax, &ebx, &ecx, &edx);
dprintk("cpuid eax is %u\n", eax);
- return (eax * 1000);
+ return eax * 1000;
}
/**
@@ -196,7 +197,8 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq,
rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi);
*high_freq = msr_lo * 1000; /* to kHz */
- dprintk("longrun table interface told %u - %u kHz\n", *low_freq, *high_freq);
+ dprintk("longrun table interface told %u - %u kHz\n",
+ *low_freq, *high_freq);
if (*low_freq > *high_freq)
*low_freq = *high_freq;
@@ -219,7 +221,7 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq,
cpuid(0x80860007, &eax, &ebx, &ecx, &edx);
/* try decreasing in 10% steps, some processors react only
* on some barrier values */
- for (try_hi = 80; try_hi > 0 && ecx > 90; try_hi -=10) {
+ for (try_hi = 80; try_hi > 0 && ecx > 90; try_hi -= 10) {
/* set to 0 to try_hi perf_pctg */
msr_lo &= 0xFFFFFF80;
msr_hi &= 0xFFFFFF80;
@@ -236,7 +238,7 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq,
/* performance_pctg = (current_freq - low_freq)/(high_freq - low_freq)
* eqals
- * low_freq * ( 1 - perf_pctg) = (cur_freq - high_freq * perf_pctg)
+ * low_freq * (1 - perf_pctg) = (cur_freq - high_freq * perf_pctg)
*
* high_freq * perf_pctg is stored tempoarily into "ebx".
*/
@@ -317,9 +319,10 @@ static void __exit longrun_exit(void)
}
-MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION ("LongRun driver for Transmeta Crusoe and Efficeon processors.");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("LongRun driver for Transmeta Crusoe and "
+ "Efficeon processors.");
+MODULE_LICENSE("GPL");
module_init(longrun_init);
module_exit(longrun_exit);
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
index 3178c3acd97e..6ac55bd341ae 100644
--- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
@@ -27,15 +27,17 @@
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/cpumask.h>
+#include <linux/timex.h>
#include <asm/processor.h>
#include <asm/msr.h>
-#include <asm/timex.h>
+#include <asm/timer.h>
#include "speedstep-lib.h"
#define PFX "p4-clockmod: "
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "p4-clockmod", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "p4-clockmod", msg)
/*
* Duty Cycle (3bits), note DC_DISABLE is not specified in
@@ -58,7 +60,8 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
{
u32 l, h;
- if (!cpu_online(cpu) || (newstate > DC_DISABLE) || (newstate == DC_RESV))
+ if (!cpu_online(cpu) ||
+ (newstate > DC_DISABLE) || (newstate == DC_RESV))
return -EINVAL;
rdmsr_on_cpu(cpu, MSR_IA32_THERM_STATUS, &l, &h);
@@ -66,7 +69,8 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
if (l & 0x01)
dprintk("CPU#%d currently thermal throttled\n", cpu);
- if (has_N44_O17_errata[cpu] && (newstate == DC_25PT || newstate == DC_DFLT))
+ if (has_N44_O17_errata[cpu] &&
+ (newstate == DC_25PT || newstate == DC_DFLT))
newstate = DC_38PT;
rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h);
@@ -112,7 +116,8 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy,
struct cpufreq_freqs freqs;
int i;
- if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0], target_freq, relation, &newstate))
+ if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0],
+ target_freq, relation, &newstate))
return -EINVAL;
freqs.old = cpufreq_p4_get(policy->cpu);
@@ -127,7 +132,8 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy,
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
}
- /* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software
+ /* run on each logical CPU,
+ * see section 13.15.3 of IA32 Intel Architecture Software
* Developer's Manual, Volume 3
*/
for_each_cpu(i, policy->cpus)
@@ -153,28 +159,30 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
{
if (c->x86 == 0x06) {
if (cpu_has(c, X86_FEATURE_EST))
- printk(KERN_WARNING PFX "Warning: EST-capable CPU detected. "
- "The acpi-cpufreq module offers voltage scaling"
- " in addition of frequency scaling. You should use "
- "that instead of p4-clockmod, if possible.\n");
+ printk(KERN_WARNING PFX "Warning: EST-capable CPU "
+ "detected. The acpi-cpufreq module offers "
+ "voltage scaling in addition of frequency "
+ "scaling. You should use that instead of "
+ "p4-clockmod, if possible.\n");
switch (c->x86_model) {
case 0x0E: /* Core */
case 0x0F: /* Core Duo */
case 0x16: /* Celeron Core */
p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
- return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PCORE);
+ return speedstep_get_frequency(SPEEDSTEP_CPU_PCORE);
case 0x0D: /* Pentium M (Dothan) */
p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
/* fall through */
case 0x09: /* Pentium M (Banias) */
- return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_PM);
+ return speedstep_get_frequency(SPEEDSTEP_CPU_PM);
}
}
if (c->x86 != 0xF) {
if (!cpu_has(c, X86_FEATURE_EST))
- printk(KERN_WARNING PFX "Unknown p4-clockmod-capable CPU. "
- "Please send an e-mail to <cpufreq@vger.kernel.org>\n");
+ printk(KERN_WARNING PFX "Unknown CPU. "
+ "Please send an e-mail to "
+ "<cpufreq@vger.kernel.org>\n");
return 0;
}
@@ -182,16 +190,16 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
* throttling is active or not. */
p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
- if (speedstep_detect_processor() == SPEEDSTEP_PROCESSOR_P4M) {
+ if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4M) {
printk(KERN_WARNING PFX "Warning: Pentium 4-M detected. "
"The speedstep-ich or acpi cpufreq modules offer "
"voltage scaling in addition of frequency scaling. "
"You should use either one instead of p4-clockmod, "
"if possible.\n");
- return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_P4M);
+ return speedstep_get_frequency(SPEEDSTEP_CPU_P4M);
}
- return speedstep_get_processor_frequency(SPEEDSTEP_PROCESSOR_P4D);
+ return speedstep_get_frequency(SPEEDSTEP_CPU_P4D);
}
@@ -203,7 +211,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
unsigned int i;
#ifdef CONFIG_SMP
- cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu));
+ cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
#endif
/* Errata workaround */
@@ -217,14 +225,20 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
dprintk("has errata -- disabling low frequencies\n");
}
+ if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4D &&
+ c->x86_model < 2) {
+ /* switch to maximum frequency and measure result */
+ cpufreq_p4_setdc(policy->cpu, DC_DISABLE);
+ recalibrate_cpu_khz();
+ }
/* get max frequency */
stock_freq = cpufreq_p4_get_frequency(c);
if (!stock_freq)
return -EINVAL;
/* table init */
- for (i=1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) {
- if ((i<2) && (has_N44_O17_errata[policy->cpu]))
+ for (i = 1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ if ((i < 2) && (has_N44_O17_errata[policy->cpu]))
p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID;
else
p4clockmod_table[i].frequency = (stock_freq * i)/8;
@@ -232,7 +246,10 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu);
/* cpuinfo and default policy values */
- policy->cpuinfo.transition_latency = 1000000; /* assumed */
+
+ /* the transition latency is set to be 1 higher than the maximum
+ * transition latency of the ondemand governor */
+ policy->cpuinfo.transition_latency = 10000001;
policy->cur = stock_freq;
return cpufreq_frequency_table_cpuinfo(policy, &p4clockmod_table[0]);
@@ -258,12 +275,12 @@ static unsigned int cpufreq_p4_get(unsigned int cpu)
l = DC_DISABLE;
if (l != DC_DISABLE)
- return (stock_freq * l / 8);
+ return stock_freq * l / 8;
return stock_freq;
}
-static struct freq_attr* p4clockmod_attr[] = {
+static struct freq_attr *p4clockmod_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};
@@ -298,9 +315,10 @@ static int __init cpufreq_p4_init(void)
ret = cpufreq_register_driver(&p4clockmod_driver);
if (!ret)
- printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock Modulation available\n");
+ printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock "
+ "Modulation available\n");
- return (ret);
+ return ret;
}
@@ -310,9 +328,9 @@ static void __exit cpufreq_p4_exit(void)
}
-MODULE_AUTHOR ("Zwane Mwaikambo <zwane@commfireservices.com>");
-MODULE_DESCRIPTION ("cpufreq driver for Pentium(TM) 4/Xeon(TM)");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Zwane Mwaikambo <zwane@commfireservices.com>");
+MODULE_DESCRIPTION("cpufreq driver for Pentium(TM) 4/Xeon(TM)");
+MODULE_LICENSE("GPL");
late_initcall(cpufreq_p4_init);
module_exit(cpufreq_p4_exit);
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
index c1ac5790c63e..f10dea409f40 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
@@ -1,6 +1,7 @@
/*
* This file was based upon code in Powertweak Linux (http://powertweak.sf.net)
- * (C) 2000-2003 Dave Jones, Arjan van de Ven, Janne Pänkälä, Dominik Brodowski.
+ * (C) 2000-2003 Dave Jones, Arjan van de Ven, Janne Pänkälä,
+ * Dominik Brodowski.
*
* Licensed under the terms of the GNU GPL License version 2.
*
@@ -13,14 +14,15 @@
#include <linux/cpufreq.h>
#include <linux/ioport.h>
#include <linux/slab.h>
-
-#include <asm/msr.h>
#include <linux/timex.h>
#include <linux/io.h>
+#include <asm/msr.h>
+
#define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long
as it is unused */
+#define PFX "powernow-k6: "
static unsigned int busfreq; /* FSB, in 10 kHz */
static unsigned int max_multiplier;
@@ -47,8 +49,8 @@ static struct cpufreq_frequency_table clock_ratio[] = {
*/
static int powernow_k6_get_cpu_multiplier(void)
{
- u64 invalue = 0;
- u32 msrval;
+ u64 invalue = 0;
+ u32 msrval;
msrval = POWERNOW_IOPORT + 0x1;
wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
@@ -68,12 +70,12 @@ static int powernow_k6_get_cpu_multiplier(void)
*/
static void powernow_k6_set_state(unsigned int best_i)
{
- unsigned long outvalue = 0, invalue = 0;
- unsigned long msrval;
- struct cpufreq_freqs freqs;
+ unsigned long outvalue = 0, invalue = 0;
+ unsigned long msrval;
+ struct cpufreq_freqs freqs;
if (clock_ratio[best_i].index > max_multiplier) {
- printk(KERN_ERR "cpufreq: invalid target frequency\n");
+ printk(KERN_ERR PFX "invalid target frequency\n");
return;
}
@@ -119,7 +121,8 @@ static int powernow_k6_verify(struct cpufreq_policy *policy)
* powernow_k6_setpolicy - sets a new CPUFreq policy
* @policy: new policy
* @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ * @relation: how that frequency relates to achieved frequency
+ * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
*
* sets a new CPUFreq policy
*/
@@ -127,9 +130,10 @@ static int powernow_k6_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
- unsigned int newstate = 0;
+ unsigned int newstate = 0;
- if (cpufreq_frequency_table_target(policy, &clock_ratio[0], target_freq, relation, &newstate))
+ if (cpufreq_frequency_table_target(policy, &clock_ratio[0],
+ target_freq, relation, &newstate))
return -EINVAL;
powernow_k6_set_state(newstate);
@@ -140,7 +144,7 @@ static int powernow_k6_target(struct cpufreq_policy *policy,
static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
{
- unsigned int i;
+ unsigned int i, f;
int result;
if (policy->cpu != 0)
@@ -152,10 +156,11 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
/* table init */
for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
- if (clock_ratio[i].index > max_multiplier)
+ f = clock_ratio[i].index;
+ if (f > max_multiplier)
clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID;
else
- clock_ratio[i].frequency = busfreq * clock_ratio[i].index;
+ clock_ratio[i].frequency = busfreq * f;
}
/* cpuinfo and default policy values */
@@ -185,7 +190,9 @@ static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
static unsigned int powernow_k6_get(unsigned int cpu)
{
- return busfreq * powernow_k6_get_cpu_multiplier();
+ unsigned int ret;
+ ret = (busfreq * powernow_k6_get_cpu_multiplier());
+ return ret;
}
static struct freq_attr *powernow_k6_attr[] = {
@@ -221,7 +228,7 @@ static int __init powernow_k6_init(void)
return -ENODEV;
if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) {
- printk("cpufreq: PowerNow IOPORT region already used.\n");
+ printk(KERN_INFO PFX "PowerNow IOPORT region already used.\n");
return -EIO;
}
@@ -246,7 +253,8 @@ static void __exit powernow_k6_exit(void)
}
-MODULE_AUTHOR("Arjan van de Ven, Dave Jones <davej@redhat.com>, Dominik Brodowski <linux@brodo.de>");
+MODULE_AUTHOR("Arjan van de Ven, Dave Jones <davej@redhat.com>, "
+ "Dominik Brodowski <linux@brodo.de>");
MODULE_DESCRIPTION("PowerNow! driver for AMD K6-2+ / K6-3+ processors.");
MODULE_LICENSE("GPL");
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
index 1b446d79a8fd..3c28ccd49742 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
@@ -6,10 +6,12 @@
* Licensed under the terms of the GNU GPL License version 2.
* Based upon datasheets & sample CPUs kindly provided by AMD.
*
- * Errata 5: Processor may fail to execute a FID/VID change in presence of interrupt.
- * - We cli/sti on stepping A0 CPUs around the FID/VID transition.
- * Errata 15: Processors with half frequency multipliers may hang upon wakeup from disconnect.
- * - We disable half multipliers if ACPI is used on A0 stepping CPUs.
+ * Errata 5:
+ * CPU may fail to execute a FID/VID change in presence of interrupt.
+ * - We cli/sti on stepping A0 CPUs around the FID/VID transition.
+ * Errata 15:
+ * CPU with half frequency multipliers may hang upon wakeup from disconnect.
+ * - We disable half multipliers if ACPI is used on A0 stepping CPUs.
*/
#include <linux/kernel.h>
@@ -20,11 +22,11 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/dmi.h>
+#include <linux/timex.h>
+#include <linux/io.h>
+#include <asm/timer.h> /* Needed for recalibrate_cpu_khz() */
#include <asm/msr.h>
-#include <asm/timer.h>
-#include <asm/timex.h>
-#include <asm/io.h>
#include <asm/system.h>
#ifdef CONFIG_X86_POWERNOW_K7_ACPI
@@ -58,9 +60,9 @@ struct pst_s {
union powernow_acpi_control_t {
struct {
unsigned long fid:5,
- vid:5,
- sgtc:20,
- res1:2;
+ vid:5,
+ sgtc:20,
+ res1:2;
} bits;
unsigned long val;
};
@@ -94,14 +96,15 @@ static struct cpufreq_frequency_table *powernow_table;
static unsigned int can_scale_bus;
static unsigned int can_scale_vid;
-static unsigned int minimum_speed=-1;
+static unsigned int minimum_speed = -1;
static unsigned int maximum_speed;
static unsigned int number_scales;
static unsigned int fsb;
static unsigned int latency;
static char have_a0;
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k7", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "powernow-k7", msg)
static int check_fsb(unsigned int fsbspeed)
{
@@ -109,7 +112,7 @@ static int check_fsb(unsigned int fsbspeed)
unsigned int f = fsb / 1000;
delta = (fsbspeed > f) ? fsbspeed - f : f - fsbspeed;
- return (delta < 5);
+ return delta < 5;
}
static int check_powernow(void)
@@ -117,24 +120,26 @@ static int check_powernow(void)
struct cpuinfo_x86 *c = &cpu_data(0);
unsigned int maxei, eax, ebx, ecx, edx;
- if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 !=6)) {
+ if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 6)) {
#ifdef MODULE
- printk (KERN_INFO PFX "This module only works with AMD K7 CPUs\n");
+ printk(KERN_INFO PFX "This module only works with "
+ "AMD K7 CPUs\n");
#endif
return 0;
}
/* Get maximum capabilities */
- maxei = cpuid_eax (0x80000000);
+ maxei = cpuid_eax(0x80000000);
if (maxei < 0x80000007) { /* Any powernow info ? */
#ifdef MODULE
- printk (KERN_INFO PFX "No powernow capabilities detected\n");
+ printk(KERN_INFO PFX "No powernow capabilities detected\n");
#endif
return 0;
}
if ((c->x86_model == 6) && (c->x86_mask == 0)) {
- printk (KERN_INFO PFX "K7 660[A0] core detected, enabling errata workarounds\n");
+ printk(KERN_INFO PFX "K7 660[A0] core detected, "
+ "enabling errata workarounds\n");
have_a0 = 1;
}
@@ -144,37 +149,42 @@ static int check_powernow(void)
if (!(edx & (1 << 1 | 1 << 2)))
return 0;
- printk (KERN_INFO PFX "PowerNOW! Technology present. Can scale: ");
+ printk(KERN_INFO PFX "PowerNOW! Technology present. Can scale: ");
if (edx & 1 << 1) {
- printk ("frequency");
- can_scale_bus=1;
+ printk("frequency");
+ can_scale_bus = 1;
}
if ((edx & (1 << 1 | 1 << 2)) == 0x6)
- printk (" and ");
+ printk(" and ");
if (edx & 1 << 2) {
- printk ("voltage");
- can_scale_vid=1;
+ printk("voltage");
+ can_scale_vid = 1;
}
- printk (".\n");
+ printk(".\n");
return 1;
}
+static void invalidate_entry(unsigned int entry)
+{
+ powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
+}
-static int get_ranges (unsigned char *pst)
+static int get_ranges(unsigned char *pst)
{
unsigned int j;
unsigned int speed;
u8 fid, vid;
- powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL);
+ powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) *
+ (number_scales + 1)), GFP_KERNEL);
if (!powernow_table)
return -ENOMEM;
- for (j=0 ; j < number_scales; j++) {
+ for (j = 0 ; j < number_scales; j++) {
fid = *pst++;
powernow_table[j].frequency = (fsb * fid_codes[fid]) / 10;
@@ -182,10 +192,10 @@ static int get_ranges (unsigned char *pst)
speed = powernow_table[j].frequency;
- if ((fid_codes[fid] % 10)==5) {
+ if ((fid_codes[fid] % 10) == 5) {
#ifdef CONFIG_X86_POWERNOW_K7_ACPI
if (have_a0 == 1)
- powernow_table[j].frequency = CPUFREQ_ENTRY_INVALID;
+ invalidate_entry(j);
#endif
}
@@ -197,7 +207,7 @@ static int get_ranges (unsigned char *pst)
vid = *pst++;
powernow_table[j].index |= (vid << 8); /* upper 8 bits */
- dprintk (" FID: 0x%x (%d.%dx [%dMHz]) "
+ dprintk(" FID: 0x%x (%d.%dx [%dMHz]) "
"VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
fid_codes[fid] % 10, speed/1000, vid,
mobile_vid_table[vid]/1000,
@@ -214,13 +224,13 @@ static void change_FID(int fid)
{
union msr_fidvidctl fidvidctl;
- rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+ rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
if (fidvidctl.bits.FID != fid) {
fidvidctl.bits.SGTC = latency;
fidvidctl.bits.FID = fid;
fidvidctl.bits.VIDC = 0;
fidvidctl.bits.FIDC = 1;
- wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+ wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
}
}
@@ -229,18 +239,18 @@ static void change_VID(int vid)
{
union msr_fidvidctl fidvidctl;
- rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+ rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
if (fidvidctl.bits.VID != vid) {
fidvidctl.bits.SGTC = latency;
fidvidctl.bits.VID = vid;
fidvidctl.bits.FIDC = 0;
fidvidctl.bits.VIDC = 1;
- wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
+ wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
}
}
-static void change_speed (unsigned int index)
+static void change_speed(unsigned int index)
{
u8 fid, vid;
struct cpufreq_freqs freqs;
@@ -257,7 +267,7 @@ static void change_speed (unsigned int index)
freqs.cpu = 0;
- rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
+ rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
cfid = fidvidstatus.bits.CFID;
freqs.old = fsb * fid_codes[cfid] / 10;
@@ -321,12 +331,14 @@ static int powernow_acpi_init(void)
goto err1;
}
- if (acpi_processor_perf->control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) {
+ if (acpi_processor_perf->control_register.space_id !=
+ ACPI_ADR_SPACE_FIXED_HARDWARE) {
retval = -ENODEV;
goto err2;
}
- if (acpi_processor_perf->status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) {
+ if (acpi_processor_perf->status_register.space_id !=
+ ACPI_ADR_SPACE_FIXED_HARDWARE) {
retval = -ENODEV;
goto err2;
}
@@ -338,7 +350,8 @@ static int powernow_acpi_init(void)
goto err2;
}
- powernow_table = kzalloc((number_scales + 1) * (sizeof(struct cpufreq_frequency_table)), GFP_KERNEL);
+ powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) *
+ (number_scales + 1)), GFP_KERNEL);
if (!powernow_table) {
retval = -ENOMEM;
goto err2;
@@ -352,7 +365,7 @@ static int powernow_acpi_init(void)
unsigned int speed, speed_mhz;
pc.val = (unsigned long) state->control;
- dprintk ("acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
+ dprintk("acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
i,
(u32) state->core_frequency,
(u32) state->power,
@@ -381,12 +394,12 @@ static int powernow_acpi_init(void)
if (speed % 1000 > 0)
speed_mhz++;
- if ((fid_codes[fid] % 10)==5) {
+ if ((fid_codes[fid] % 10) == 5) {
if (have_a0 == 1)
- powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ invalidate_entry(i);
}
- dprintk (" FID: 0x%x (%d.%dx [%dMHz]) "
+ dprintk(" FID: 0x%x (%d.%dx [%dMHz]) "
"VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
fid_codes[fid] % 10, speed_mhz, vid,
mobile_vid_table[vid]/1000,
@@ -422,7 +435,8 @@ err1:
err05:
kfree(acpi_processor_perf);
err0:
- printk(KERN_WARNING PFX "ACPI perflib can not be used in this platform\n");
+ printk(KERN_WARNING PFX "ACPI perflib can not be used on "
+ "this platform\n");
acpi_processor_perf = NULL;
return retval;
}
@@ -435,7 +449,14 @@ static int powernow_acpi_init(void)
}
#endif
-static int powernow_decode_bios (int maxfid, int startvid)
+static void print_pst_entry(struct pst_s *pst, unsigned int j)
+{
+ dprintk("PST:%d (@%p)\n", j, pst);
+ dprintk(" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n",
+ pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid);
+}
+
+static int powernow_decode_bios(int maxfid, int startvid)
{
struct psb_s *psb;
struct pst_s *pst;
@@ -446,61 +467,67 @@ static int powernow_decode_bios (int maxfid, int startvid)
etuple = cpuid_eax(0x80000001);
- for (i=0xC0000; i < 0xffff0 ; i+=16) {
+ for (i = 0xC0000; i < 0xffff0 ; i += 16) {
p = phys_to_virt(i);
- if (memcmp(p, "AMDK7PNOW!", 10) == 0){
- dprintk ("Found PSB header at %p\n", p);
+ if (memcmp(p, "AMDK7PNOW!", 10) == 0) {
+ dprintk("Found PSB header at %p\n", p);
psb = (struct psb_s *) p;
- dprintk ("Table version: 0x%x\n", psb->tableversion);
+ dprintk("Table version: 0x%x\n", psb->tableversion);
if (psb->tableversion != 0x12) {
- printk (KERN_INFO PFX "Sorry, only v1.2 tables supported right now\n");
+ printk(KERN_INFO PFX "Sorry, only v1.2 tables"
+ " supported right now\n");
return -ENODEV;
}
- dprintk ("Flags: 0x%x\n", psb->flags);
- if ((psb->flags & 1)==0) {
- dprintk ("Mobile voltage regulator\n");
- } else {
- dprintk ("Desktop voltage regulator\n");
- }
+ dprintk("Flags: 0x%x\n", psb->flags);
+ if ((psb->flags & 1) == 0)
+ dprintk("Mobile voltage regulator\n");
+ else
+ dprintk("Desktop voltage regulator\n");
latency = psb->settlingtime;
if (latency < 100) {
- printk(KERN_INFO PFX "BIOS set settling time to %d microseconds. "
- "Should be at least 100. Correcting.\n", latency);
+ printk(KERN_INFO PFX "BIOS set settling time "
+ "to %d microseconds. "
+ "Should be at least 100. "
+ "Correcting.\n", latency);
latency = 100;
}
- dprintk ("Settling Time: %d microseconds.\n", psb->settlingtime);
- dprintk ("Has %d PST tables. (Only dumping ones relevant to this CPU).\n", psb->numpst);
+ dprintk("Settling Time: %d microseconds.\n",
+ psb->settlingtime);
+ dprintk("Has %d PST tables. (Only dumping ones "
+ "relevant to this CPU).\n",
+ psb->numpst);
- p += sizeof (struct psb_s);
+ p += sizeof(struct psb_s);
pst = (struct pst_s *) p;
- for (j=0; j<psb->numpst; j++) {
+ for (j = 0; j < psb->numpst; j++) {
pst = (struct pst_s *) p;
number_scales = pst->numpstates;
- if ((etuple == pst->cpuid) && check_fsb(pst->fsbspeed) &&
- (maxfid==pst->maxfid) && (startvid==pst->startvid))
- {
- dprintk ("PST:%d (@%p)\n", j, pst);
- dprintk (" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n",
- pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid);
-
- ret = get_ranges ((char *) pst + sizeof (struct pst_s));
+ if ((etuple == pst->cpuid) &&
+ check_fsb(pst->fsbspeed) &&
+ (maxfid == pst->maxfid) &&
+ (startvid == pst->startvid)) {
+ print_pst_entry(pst, j);
+ p = (char *)pst + sizeof(struct pst_s);
+ ret = get_ranges(p);
return ret;
} else {
unsigned int k;
- p = (char *) pst + sizeof (struct pst_s);
- for (k=0; k<number_scales; k++)
- p+=2;
+ p = (char *)pst + sizeof(struct pst_s);
+ for (k = 0; k < number_scales; k++)
+ p += 2;
}
}
- printk (KERN_INFO PFX "No PST tables match this cpuid (0x%x)\n", etuple);
- printk (KERN_INFO PFX "This is indicative of a broken BIOS.\n");
+ printk(KERN_INFO PFX "No PST tables match this cpuid "
+ "(0x%x)\n", etuple);
+ printk(KERN_INFO PFX "This is indicative of a broken "
+ "BIOS.\n");
return -EINVAL;
}
@@ -511,13 +538,14 @@ static int powernow_decode_bios (int maxfid, int startvid)
}
-static int powernow_target (struct cpufreq_policy *policy,
+static int powernow_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
unsigned int newstate;
- if (cpufreq_frequency_table_target(policy, powernow_table, target_freq, relation, &newstate))
+ if (cpufreq_frequency_table_target(policy, powernow_table, target_freq,
+ relation, &newstate))
return -EINVAL;
change_speed(newstate);
@@ -526,7 +554,7 @@ static int powernow_target (struct cpufreq_policy *policy,
}
-static int powernow_verify (struct cpufreq_policy *policy)
+static int powernow_verify(struct cpufreq_policy *policy)
{
return cpufreq_frequency_table_verify(policy, powernow_table);
}
@@ -566,18 +594,23 @@ static unsigned int powernow_get(unsigned int cpu)
if (cpu)
return 0;
- rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
+ rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
cfid = fidvidstatus.bits.CFID;
- return (fsb * fid_codes[cfid] / 10);
+ return fsb * fid_codes[cfid] / 10;
}
static int __init acer_cpufreq_pst(const struct dmi_system_id *d)
{
- printk(KERN_WARNING "%s laptop with broken PST tables in BIOS detected.\n", d->ident);
- printk(KERN_WARNING "You need to downgrade to 3A21 (09/09/2002), or try a newer BIOS than 3A71 (01/20/2003)\n");
- printk(KERN_WARNING "cpufreq scaling has been disabled as a result of this.\n");
+ printk(KERN_WARNING PFX
+ "%s laptop with broken PST tables in BIOS detected.\n",
+ d->ident);
+ printk(KERN_WARNING PFX
+ "You need to downgrade to 3A21 (09/09/2002), or try a newer "
+ "BIOS than 3A71 (01/20/2003)\n");
+ printk(KERN_WARNING PFX
+ "cpufreq scaling has been disabled as a result of this.\n");
return 0;
}
@@ -598,7 +631,7 @@ static struct dmi_system_id __initdata powernow_dmi_table[] = {
{ }
};
-static int __init powernow_cpu_init (struct cpufreq_policy *policy)
+static int __init powernow_cpu_init(struct cpufreq_policy *policy)
{
union msr_fidvidstatus fidvidstatus;
int result;
@@ -606,7 +639,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
if (policy->cpu != 0)
return -ENODEV;
- rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
+ rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
recalibrate_cpu_khz();
@@ -618,19 +651,21 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
dprintk("FSB: %3dMHz\n", fsb/1000);
if (dmi_check_system(powernow_dmi_table) || acpi_force) {
- printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n");
+ printk(KERN_INFO PFX "PSB/PST known to be broken. "
+ "Trying ACPI instead\n");
result = powernow_acpi_init();
} else {
- result = powernow_decode_bios(fidvidstatus.bits.MFID, fidvidstatus.bits.SVID);
+ result = powernow_decode_bios(fidvidstatus.bits.MFID,
+ fidvidstatus.bits.SVID);
if (result) {
- printk (KERN_INFO PFX "Trying ACPI perflib\n");
+ printk(KERN_INFO PFX "Trying ACPI perflib\n");
maximum_speed = 0;
minimum_speed = -1;
latency = 0;
result = powernow_acpi_init();
if (result) {
- printk (KERN_INFO PFX "ACPI and legacy methods failed\n");
- printk (KERN_INFO PFX "See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.html\n");
+ printk(KERN_INFO PFX
+ "ACPI and legacy methods failed\n");
}
} else {
/* SGTC use the bus clock as timer */
@@ -642,10 +677,11 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
if (result)
return result;
- printk (KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n",
+ printk(KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n",
minimum_speed/1000, maximum_speed/1000);
- policy->cpuinfo.transition_latency = cpufreq_scale(2000000UL, fsb, latency);
+ policy->cpuinfo.transition_latency =
+ cpufreq_scale(2000000UL, fsb, latency);
policy->cur = powernow_get(0);
@@ -654,7 +690,8 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
return cpufreq_frequency_table_cpuinfo(policy, powernow_table);
}
-static int powernow_cpu_exit (struct cpufreq_policy *policy) {
+static int powernow_cpu_exit(struct cpufreq_policy *policy)
+{
cpufreq_frequency_table_put_attr(policy->cpu);
#ifdef CONFIG_X86_POWERNOW_K7_ACPI
@@ -669,7 +706,7 @@ static int powernow_cpu_exit (struct cpufreq_policy *policy) {
return 0;
}
-static struct freq_attr* powernow_table_attr[] = {
+static struct freq_attr *powernow_table_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};
@@ -685,15 +722,15 @@ static struct cpufreq_driver powernow_driver = {
.attr = powernow_table_attr,
};
-static int __init powernow_init (void)
+static int __init powernow_init(void)
{
- if (check_powernow()==0)
+ if (check_powernow() == 0)
return -ENODEV;
return cpufreq_register_driver(&powernow_driver);
}
-static void __exit powernow_exit (void)
+static void __exit powernow_exit(void)
{
cpufreq_unregister_driver(&powernow_driver);
}
@@ -701,9 +738,9 @@ static void __exit powernow_exit (void)
module_param(acpi_force, int, 0444);
MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
-MODULE_AUTHOR ("Dave Jones <davej@redhat.com>");
-MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
+MODULE_DESCRIPTION("Powernow driver for AMD K7 processors.");
+MODULE_LICENSE("GPL");
late_initcall(powernow_init);
module_exit(powernow_exit);
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index 6428aa17b40e..4709ead2db52 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -33,16 +33,14 @@
#include <linux/string.h>
#include <linux/cpumask.h>
#include <linux/sched.h> /* for current / set_cpus_allowed() */
+#include <linux/io.h>
+#include <linux/delay.h>
#include <asm/msr.h>
-#include <asm/io.h>
-#include <asm/delay.h>
-#ifdef CONFIG_X86_POWERNOW_K8_ACPI
#include <linux/acpi.h>
#include <linux/mutex.h>
#include <acpi/processor.h>
-#endif
#define PFX "powernow-k8: "
#define VERSION "version 2.20.00"
@@ -56,7 +54,10 @@ static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data);
static int cpu_family = CPU_OPTERON;
#ifndef CONFIG_SMP
-DEFINE_PER_CPU(cpumask_t, cpu_core_map);
+static inline const struct cpumask *cpu_core_mask(int cpu)
+{
+ return cpumask_of(0);
+}
#endif
/* Return a frequency in MHz, given an input fid */
@@ -71,7 +72,8 @@ static u32 find_khz_freq_from_fid(u32 fid)
return 1000 * find_freq_from_fid(fid);
}
-static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, u32 pstate)
+static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data,
+ u32 pstate)
{
return data[pstate].frequency;
}
@@ -186,7 +188,9 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid)
return 1;
}
- lo = fid | (data->currvid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID;
+ lo = fid;
+ lo |= (data->currvid << MSR_C_LO_VID_SHIFT);
+ lo |= MSR_C_LO_INIT_FID_VID;
dprintk("writing fid 0x%x, lo 0x%x, hi 0x%x\n",
fid, lo, data->plllock * PLL_LOCK_CONVERSION);
@@ -194,7 +198,9 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid)
do {
wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION);
if (i++ > 100) {
- printk(KERN_ERR PFX "Hardware error - pending bit very stuck - no further pstate changes possible\n");
+ printk(KERN_ERR PFX
+ "Hardware error - pending bit very stuck - "
+ "no further pstate changes possible\n");
return 1;
}
} while (query_current_values_with_pending_wait(data));
@@ -202,14 +208,16 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid)
count_off_irt(data);
if (savevid != data->currvid) {
- printk(KERN_ERR PFX "vid change on fid trans, old 0x%x, new 0x%x\n",
- savevid, data->currvid);
+ printk(KERN_ERR PFX
+ "vid change on fid trans, old 0x%x, new 0x%x\n",
+ savevid, data->currvid);
return 1;
}
if (fid != data->currfid) {
- printk(KERN_ERR PFX "fid trans failed, fid 0x%x, curr 0x%x\n", fid,
- data->currfid);
+ printk(KERN_ERR PFX
+ "fid trans failed, fid 0x%x, curr 0x%x\n", fid,
+ data->currfid);
return 1;
}
@@ -228,7 +236,9 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid)
return 1;
}
- lo = data->currfid | (vid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID;
+ lo = data->currfid;
+ lo |= (vid << MSR_C_LO_VID_SHIFT);
+ lo |= MSR_C_LO_INIT_FID_VID;
dprintk("writing vid 0x%x, lo 0x%x, hi 0x%x\n",
vid, lo, STOP_GRANT_5NS);
@@ -236,20 +246,24 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid)
do {
wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
if (i++ > 100) {
- printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
+ printk(KERN_ERR PFX "internal error - pending bit "
+ "very stuck - no further pstate "
+ "changes possible\n");
return 1;
}
} while (query_current_values_with_pending_wait(data));
if (savefid != data->currfid) {
- printk(KERN_ERR PFX "fid changed on vid trans, old 0x%x new 0x%x\n",
+ printk(KERN_ERR PFX "fid changed on vid trans, old "
+ "0x%x new 0x%x\n",
savefid, data->currfid);
return 1;
}
if (vid != data->currvid) {
- printk(KERN_ERR PFX "vid trans failed, vid 0x%x, curr 0x%x\n", vid,
- data->currvid);
+ printk(KERN_ERR PFX "vid trans failed, vid 0x%x, "
+ "curr 0x%x\n",
+ vid, data->currvid);
return 1;
}
@@ -261,7 +275,8 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid)
* Decreasing vid codes represent increasing voltages:
* vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off.
*/
-static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid, u32 step)
+static int decrease_vid_code_by_step(struct powernow_k8_data *data,
+ u32 reqvid, u32 step)
{
if ((data->currvid - reqvid) > step)
reqvid = data->currvid - step;
@@ -283,7 +298,8 @@ static int transition_pstate(struct powernow_k8_data *data, u32 pstate)
}
/* Change Opteron/Athlon64 fid and vid, by the 3 phases. */
-static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 reqvid)
+static int transition_fid_vid(struct powernow_k8_data *data,
+ u32 reqfid, u32 reqvid)
{
if (core_voltage_pre_transition(data, reqvid))
return 1;
@@ -298,7 +314,8 @@ static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 req
return 1;
if ((reqfid != data->currfid) || (reqvid != data->currvid)) {
- printk(KERN_ERR PFX "failed (cpu%d): req 0x%x 0x%x, curr 0x%x 0x%x\n",
+ printk(KERN_ERR PFX "failed (cpu%d): req 0x%x 0x%x, "
+ "curr 0x%x 0x%x\n",
smp_processor_id(),
reqfid, reqvid, data->currfid, data->currvid);
return 1;
@@ -311,13 +328,15 @@ static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 req
}
/* Phase 1 - core voltage transition ... setup voltage */
-static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid)
+static int core_voltage_pre_transition(struct powernow_k8_data *data,
+ u32 reqvid)
{
u32 rvosteps = data->rvo;
u32 savefid = data->currfid;
u32 maxvid, lo;
- dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n",
+ dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, "
+ "reqvid 0x%x, rvo 0x%x\n",
smp_processor_id(),
data->currfid, data->currvid, reqvid, data->rvo);
@@ -340,7 +359,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
} else {
dprintk("ph1: changing vid for rvo, req 0x%x\n",
data->currvid - 1);
- if (decrease_vid_code_by_step(data, data->currvid - 1, 1))
+ if (decrease_vid_code_by_step(data, data->currvid-1, 1))
return 1;
rvosteps--;
}
@@ -350,7 +369,8 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
return 1;
if (savefid != data->currfid) {
- printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n", data->currfid);
+ printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n",
+ data->currfid);
return 1;
}
@@ -363,20 +383,24 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
/* Phase 2 - core frequency transition */
static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
{
- u32 vcoreqfid, vcocurrfid, vcofiddiff, fid_interval, savevid = data->currvid;
+ u32 vcoreqfid, vcocurrfid, vcofiddiff;
+ u32 fid_interval, savevid = data->currvid;
- if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
- printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n",
- reqfid, data->currfid);
+ if ((reqfid < HI_FID_TABLE_BOTTOM) &&
+ (data->currfid < HI_FID_TABLE_BOTTOM)) {
+ printk(KERN_ERR PFX "ph2: illegal lo-lo transition "
+ "0x%x 0x%x\n", reqfid, data->currfid);
return 1;
}
if (data->currfid == reqfid) {
- printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n", data->currfid);
+ printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n",
+ data->currfid);
return 0;
}
- dprintk("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, reqfid 0x%x\n",
+ dprintk("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, "
+ "reqfid 0x%x\n",
smp_processor_id(),
data->currfid, data->currvid, reqfid);
@@ -390,14 +414,14 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
if (reqfid > data->currfid) {
if (data->currfid > LO_FID_TABLE_TOP) {
- if (write_new_fid(data, data->currfid + fid_interval)) {
+ if (write_new_fid(data,
+ data->currfid + fid_interval))
return 1;
- }
} else {
if (write_new_fid
- (data, 2 + convert_fid_to_vco_fid(data->currfid))) {
+ (data,
+ 2 + convert_fid_to_vco_fid(data->currfid)))
return 1;
- }
}
} else {
if (write_new_fid(data, data->currfid - fid_interval))
@@ -417,7 +441,8 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
if (data->currfid != reqfid) {
printk(KERN_ERR PFX
- "ph2: mismatch, failed fid transition, curr 0x%x, req 0x%x\n",
+ "ph2: mismatch, failed fid transition, "
+ "curr 0x%x, req 0x%x\n",
data->currfid, reqfid);
return 1;
}
@@ -435,7 +460,8 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
}
/* Phase 3 - core voltage transition flow ... jump to the final vid. */
-static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid)
+static int core_voltage_post_transition(struct powernow_k8_data *data,
+ u32 reqvid)
{
u32 savefid = data->currfid;
u32 savereqvid = reqvid;
@@ -457,7 +483,8 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvi
if (data->currvid != reqvid) {
printk(KERN_ERR PFX
- "ph3: failed vid transition\n, req 0x%x, curr 0x%x",
+ "ph3: failed vid transition\n, "
+ "req 0x%x, curr 0x%x",
reqvid, data->currvid);
return 1;
}
@@ -508,7 +535,8 @@ static int check_supported_cpu(unsigned int cpu)
if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) {
if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) {
- printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
+ printk(KERN_INFO PFX
+ "Processor cpuid %x not supported\n", eax);
goto out;
}
@@ -520,8 +548,10 @@ static int check_supported_cpu(unsigned int cpu)
}
cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
- if ((edx & P_STATE_TRANSITION_CAPABLE) != P_STATE_TRANSITION_CAPABLE) {
- printk(KERN_INFO PFX "Power state transitions not supported\n");
+ if ((edx & P_STATE_TRANSITION_CAPABLE)
+ != P_STATE_TRANSITION_CAPABLE) {
+ printk(KERN_INFO PFX
+ "Power state transitions not supported\n");
goto out;
}
} else { /* must be a HW Pstate capable processor */
@@ -539,7 +569,8 @@ out:
return rc;
}
-static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid)
+static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst,
+ u8 maxvid)
{
unsigned int j;
u8 lastfid = 0xff;
@@ -550,12 +581,14 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8
j, pst[j].vid);
return -EINVAL;
}
- if (pst[j].vid < data->rvo) { /* vid + rvo >= 0 */
+ if (pst[j].vid < data->rvo) {
+ /* vid + rvo >= 0 */
printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate"
" %d\n", j);
return -ENODEV;
}
- if (pst[j].vid < maxvid + data->rvo) { /* vid + rvo >= maxvid */
+ if (pst[j].vid < maxvid + data->rvo) {
+ /* vid + rvo >= maxvid */
printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate"
" %d\n", j);
return -ENODEV;
@@ -579,23 +612,31 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8
return -EINVAL;
}
if (lastfid > LO_FID_TABLE_TOP)
- printk(KERN_INFO FW_BUG PFX "first fid not from lo freq table\n");
+ printk(KERN_INFO FW_BUG PFX
+ "first fid not from lo freq table\n");
return 0;
}
+static void invalidate_entry(struct powernow_k8_data *data, unsigned int entry)
+{
+ data->powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
+}
+
static void print_basics(struct powernow_k8_data *data)
{
int j;
for (j = 0; j < data->numps; j++) {
- if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) {
+ if (data->powernow_table[j].frequency !=
+ CPUFREQ_ENTRY_INVALID) {
if (cpu_family == CPU_HW_PSTATE) {
- printk(KERN_INFO PFX " %d : pstate %d (%d MHz)\n",
- j,
+ printk(KERN_INFO PFX
+ " %d : pstate %d (%d MHz)\n", j,
data->powernow_table[j].index,
data->powernow_table[j].frequency/1000);
} else {
- printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x\n",
+ printk(KERN_INFO PFX
+ " %d : fid 0x%x (%d MHz), vid 0x%x\n",
j,
data->powernow_table[j].index & 0xff,
data->powernow_table[j].frequency/1000,
@@ -604,20 +645,25 @@ static void print_basics(struct powernow_k8_data *data)
}
}
if (data->batps)
- printk(KERN_INFO PFX "Only %d pstates on battery\n", data->batps);
+ printk(KERN_INFO PFX "Only %d pstates on battery\n",
+ data->batps);
}
-static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid)
+static int fill_powernow_table(struct powernow_k8_data *data,
+ struct pst_s *pst, u8 maxvid)
{
struct cpufreq_frequency_table *powernow_table;
unsigned int j;
- if (data->batps) { /* use ACPI support to get full speed on mains power */
- printk(KERN_WARNING PFX "Only %d pstates usable (use ACPI driver for full range\n", data->batps);
+ if (data->batps) {
+ /* use ACPI support to get full speed on mains power */
+ printk(KERN_WARNING PFX
+ "Only %d pstates usable (use ACPI driver for full "
+ "range\n", data->batps);
data->numps = data->batps;
}
- for ( j=1; j<data->numps; j++ ) {
+ for (j = 1; j < data->numps; j++) {
if (pst[j-1].fid >= pst[j].fid) {
printk(KERN_ERR PFX "PST out of sequence\n");
return -EINVAL;
@@ -640,9 +686,11 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst,
}
for (j = 0; j < data->numps; j++) {
+ int freq;
powernow_table[j].index = pst[j].fid; /* lower 8 bits */
powernow_table[j].index |= (pst[j].vid << 8); /* upper 8 bits */
- powernow_table[j].frequency = find_khz_freq_from_fid(pst[j].fid);
+ freq = find_khz_freq_from_fid(pst[j].fid);
+ powernow_table[j].frequency = freq;
}
powernow_table[data->numps].frequency = CPUFREQ_TABLE_END;
powernow_table[data->numps].index = 0;
@@ -654,11 +702,12 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst,
dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
data->powernow_table = powernow_table;
- if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
+ if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
print_basics(data);
for (j = 0; j < data->numps; j++)
- if ((pst[j].fid==data->currfid) && (pst[j].vid==data->currvid))
+ if ((pst[j].fid == data->currfid) &&
+ (pst[j].vid == data->currvid))
return 0;
dprintk("currfid/vid do not match PST, ignoring\n");
@@ -698,7 +747,8 @@ static int find_psb_table(struct powernow_k8_data *data)
}
data->vstable = psb->vstable;
- dprintk("voltage stabilization time: %d(*20us)\n", data->vstable);
+ dprintk("voltage stabilization time: %d(*20us)\n",
+ data->vstable);
dprintk("flags2: 0x%x\n", psb->flags2);
data->rvo = psb->flags2 & 3;
@@ -713,11 +763,12 @@ static int find_psb_table(struct powernow_k8_data *data)
dprintk("numpst: 0x%x\n", psb->num_tables);
cpst = psb->num_tables;
- if ((psb->cpuid == 0x00000fc0) || (psb->cpuid == 0x00000fe0) ){
+ if ((psb->cpuid == 0x00000fc0) ||
+ (psb->cpuid == 0x00000fe0)) {
thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
- if ((thiscpuid == 0x00000fc0) || (thiscpuid == 0x00000fe0) ) {
+ if ((thiscpuid == 0x00000fc0) ||
+ (thiscpuid == 0x00000fe0))
cpst = 1;
- }
}
if (cpst != 1) {
printk(KERN_ERR FW_BUG PFX "numpst must be 1\n");
@@ -732,7 +783,8 @@ static int find_psb_table(struct powernow_k8_data *data)
data->numps = psb->numps;
dprintk("numpstates: 0x%x\n", data->numps);
- return fill_powernow_table(data, (struct pst_s *)(psb+1), maxvid);
+ return fill_powernow_table(data,
+ (struct pst_s *)(psb+1), maxvid);
}
/*
* If you see this message, complain to BIOS manufacturer. If
@@ -745,28 +797,31 @@ static int find_psb_table(struct powernow_k8_data *data)
* BIOS and Kernel Developer's Guide, which is available on
* www.amd.com
*/
- printk(KERN_ERR PFX "BIOS error - no PSB or ACPI _PSS objects\n");
+ printk(KERN_ERR FW_BUG PFX "No PSB or ACPI _PSS objects\n");
return -ENODEV;
}
-#ifdef CONFIG_X86_POWERNOW_K8_ACPI
-static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index)
+static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data,
+ unsigned int index)
{
+ acpi_integer control;
+
if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE))
return;
- data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK;
- data->rvo = (data->acpi_data.states[index].control >> RVO_SHIFT) & RVO_MASK;
- data->exttype = (data->acpi_data.states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
- data->plllock = (data->acpi_data.states[index].control >> PLL_L_SHIFT) & PLL_L_MASK;
- data->vidmvs = 1 << ((data->acpi_data.states[index].control >> MVS_SHIFT) & MVS_MASK);
- data->vstable = (data->acpi_data.states[index].control >> VST_SHIFT) & VST_MASK;
-}
+ control = data->acpi_data.states[index].control; data->irt = (control
+ >> IRT_SHIFT) & IRT_MASK; data->rvo = (control >>
+ RVO_SHIFT) & RVO_MASK; data->exttype = (control
+ >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
+ data->plllock = (control >> PLL_L_SHIFT) & PLL_L_MASK; data->vidmvs = 1
+ << ((control >> MVS_SHIFT) & MVS_MASK); data->vstable =
+ (control >> VST_SHIFT) & VST_MASK; }
static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
{
struct cpufreq_frequency_table *powernow_table;
int ret_val = -ENODEV;
+ acpi_integer space_id;
if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
dprintk("register performance failed: bad ACPI data\n");
@@ -779,11 +834,12 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
goto err_out;
}
- if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
- (data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
+ space_id = data->acpi_data.control_register.space_id;
+ if ((space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
+ (space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
dprintk("Invalid control/status registers (%x - %x)\n",
data->acpi_data.control_register.space_id,
- data->acpi_data.status_register.space_id);
+ space_id);
goto err_out;
}
@@ -802,13 +858,14 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
if (ret_val)
goto err_out_mem;
- powernow_table[data->acpi_data.state_count].frequency = CPUFREQ_TABLE_END;
+ powernow_table[data->acpi_data.state_count].frequency =
+ CPUFREQ_TABLE_END;
powernow_table[data->acpi_data.state_count].index = 0;
data->powernow_table = powernow_table;
/* fill in data */
data->numps = data->acpi_data.state_count;
- if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
+ if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
print_basics(data);
powernow_k8_acpi_pst_values(data, 0);
@@ -830,13 +887,15 @@ err_out_mem:
err_out:
acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
- /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */
+ /* data->acpi_data.state_count informs us at ->exit()
+ * whether ACPI was used */
data->acpi_data.state_count = 0;
return ret_val;
}
-static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table)
+static int fill_powernow_table_pstate(struct powernow_k8_data *data,
+ struct cpufreq_frequency_table *powernow_table)
{
int i;
u32 hi = 0, lo = 0;
@@ -848,84 +907,101 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpuf
index = data->acpi_data.states[i].control & HW_PSTATE_MASK;
if (index > data->max_hw_pstate) {
- printk(KERN_ERR PFX "invalid pstate %d - bad value %d.\n", i, index);
- printk(KERN_ERR PFX "Please report to BIOS manufacturer\n");
- powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ printk(KERN_ERR PFX "invalid pstate %d - "
+ "bad value %d.\n", i, index);
+ printk(KERN_ERR PFX "Please report to BIOS "
+ "manufacturer\n");
+ invalidate_entry(data, i);
continue;
}
rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
if (!(hi & HW_PSTATE_VALID_MASK)) {
dprintk("invalid pstate %d, ignoring\n", index);
- powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ invalidate_entry(data, i);
continue;
}
powernow_table[i].index = index;
- powernow_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000;
+ powernow_table[i].frequency =
+ data->acpi_data.states[i].core_frequency * 1000;
}
return 0;
}
-static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table)
+static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
+ struct cpufreq_frequency_table *powernow_table)
{
int i;
int cntlofreq = 0;
+
for (i = 0; i < data->acpi_data.state_count; i++) {
u32 fid;
u32 vid;
+ u32 freq, index;
+ acpi_integer status, control;
if (data->exttype) {
- fid = data->acpi_data.states[i].status & EXT_FID_MASK;
- vid = (data->acpi_data.states[i].status >> VID_SHIFT) & EXT_VID_MASK;
+ status = data->acpi_data.states[i].status;
+ fid = status & EXT_FID_MASK;
+ vid = (status >> VID_SHIFT) & EXT_VID_MASK;
} else {
- fid = data->acpi_data.states[i].control & FID_MASK;
- vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK;
+ control = data->acpi_data.states[i].control;
+ fid = control & FID_MASK;
+ vid = (control >> VID_SHIFT) & VID_MASK;
}
dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
- powernow_table[i].index = fid; /* lower 8 bits */
- powernow_table[i].index |= (vid << 8); /* upper 8 bits */
- powernow_table[i].frequency = find_khz_freq_from_fid(fid);
+ index = fid | (vid<<8);
+ powernow_table[i].index = index;
+
+ freq = find_khz_freq_from_fid(fid);
+ powernow_table[i].frequency = freq;
/* verify frequency is OK */
- if ((powernow_table[i].frequency > (MAX_FREQ * 1000)) ||
- (powernow_table[i].frequency < (MIN_FREQ * 1000))) {
- dprintk("invalid freq %u kHz, ignoring\n", powernow_table[i].frequency);
- powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) {
+ dprintk("invalid freq %u kHz, ignoring\n", freq);
+ invalidate_entry(data, i);
continue;
}
- /* verify voltage is OK - BIOSs are using "off" to indicate invalid */
+ /* verify voltage is OK -
+ * BIOSs are using "off" to indicate invalid */
if (vid == VID_OFF) {
dprintk("invalid vid %u, ignoring\n", vid);
- powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ invalidate_entry(data, i);
continue;
}
/* verify only 1 entry from the lo frequency table */
if (fid < HI_FID_TABLE_BOTTOM) {
if (cntlofreq) {
- /* if both entries are the same, ignore this one ... */
- if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) ||
- (powernow_table[i].index != powernow_table[cntlofreq].index)) {
- printk(KERN_ERR PFX "Too many lo freq table entries\n");
+ /* if both entries are the same,
+ * ignore this one ... */
+ if ((freq != powernow_table[cntlofreq].frequency) ||
+ (index != powernow_table[cntlofreq].index)) {
+ printk(KERN_ERR PFX
+ "Too many lo freq table "
+ "entries\n");
return 1;
}
- dprintk("double low frequency table entry, ignoring it.\n");
- powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ dprintk("double low frequency table entry, "
+ "ignoring it.\n");
+ invalidate_entry(data, i);
continue;
} else
cntlofreq = i;
}
- if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
- printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n",
- powernow_table[i].frequency,
- (unsigned int) (data->acpi_data.states[i].core_frequency * 1000));
- powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ if (freq != (data->acpi_data.states[i].core_frequency * 1000)) {
+ printk(KERN_INFO PFX "invalid freq entries "
+ "%u kHz vs. %u kHz\n", freq,
+ (unsigned int)
+ (data->acpi_data.states[i].core_frequency
+ * 1000));
+ invalidate_entry(data, i);
continue;
}
}
@@ -935,7 +1011,8 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf
static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data)
{
if (data->acpi_data.state_count)
- acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
+ acpi_processor_unregister_performance(&data->acpi_data,
+ data->cpu);
free_cpumask_var(data->acpi_data.shared_cpu_map);
}
@@ -953,15 +1030,9 @@ static int get_transition_latency(struct powernow_k8_data *data)
return 1000 * max_latency;
}
-#else
-static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; }
-static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; }
-static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; }
-static int get_transition_latency(struct powernow_k8_data *data) { return 0; }
-#endif /* CONFIG_X86_POWERNOW_K8_ACPI */
-
/* Take a frequency, and issue the fid/vid transition command */
-static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned int index)
+static int transition_frequency_fidvid(struct powernow_k8_data *data,
+ unsigned int index)
{
u32 fid = 0;
u32 vid = 0;
@@ -989,7 +1060,8 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned i
return 0;
}
- if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
+ if ((fid < HI_FID_TABLE_BOTTOM) &&
+ (data->currfid < HI_FID_TABLE_BOTTOM)) {
printk(KERN_ERR PFX
"ignoring illegal change in lo freq table-%x to 0x%x\n",
data->currfid, fid);
@@ -1017,7 +1089,8 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned i
}
/* Take a frequency, and issue the hardware pstate transition command */
-static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned int index)
+static int transition_frequency_pstate(struct powernow_k8_data *data,
+ unsigned int index)
{
u32 pstate = 0;
int res, i;
@@ -1029,7 +1102,8 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned i
pstate = index & HW_PSTATE_MASK;
if (pstate > data->max_hw_pstate)
return 0;
- freqs.old = find_khz_freq_from_pstate(data->powernow_table, data->currpstate);
+ freqs.old = find_khz_freq_from_pstate(data->powernow_table,
+ data->currpstate);
freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
for_each_cpu_mask_nr(i, *(data->available_cores)) {
@@ -1048,7 +1122,8 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned i
}
/* Driver entry point to switch to the target frequency */
-static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsigned relation)
+static int powernowk8_target(struct cpufreq_policy *pol,
+ unsigned targfreq, unsigned relation)
{
cpumask_t oldmask;
struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
@@ -1087,14 +1162,18 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
dprintk("targ: curr fid 0x%x, vid 0x%x\n",
data->currfid, data->currvid);
- if ((checkvid != data->currvid) || (checkfid != data->currfid)) {
+ if ((checkvid != data->currvid) ||
+ (checkfid != data->currfid)) {
printk(KERN_INFO PFX
- "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n",
- checkfid, data->currfid, checkvid, data->currvid);
+ "error - out of sync, fix 0x%x 0x%x, "
+ "vid 0x%x 0x%x\n",
+ checkfid, data->currfid,
+ checkvid, data->currvid);
}
}
- if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate))
+ if (cpufreq_frequency_table_target(pol, data->powernow_table,
+ targfreq, relation, &newstate))
goto err_out;
mutex_lock(&fidvid_mutex);
@@ -1114,7 +1193,8 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
mutex_unlock(&fidvid_mutex);
if (cpu_family == CPU_HW_PSTATE)
- pol->cur = find_khz_freq_from_pstate(data->powernow_table, newstate);
+ pol->cur = find_khz_freq_from_pstate(data->powernow_table,
+ newstate);
else
pol->cur = find_khz_freq_from_fid(data->currfid);
ret = 0;
@@ -1141,6 +1221,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
struct powernow_k8_data *data;
cpumask_t oldmask;
int rc;
+ static int print_once;
if (!cpu_online(pol->cpu))
return -ENODEV;
@@ -1163,33 +1244,31 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
* an UP version, and is deprecated by AMD.
*/
if (num_online_cpus() != 1) {
-#ifndef CONFIG_ACPI_PROCESSOR
- printk(KERN_ERR PFX "ACPI Processor support is required "
- "for SMP systems but is absent. Please load the "
- "ACPI Processor module before starting this "
- "driver.\n");
-#else
- printk(KERN_ERR FW_BUG PFX "Your BIOS does not provide"
- " ACPI _PSS objects in a way that Linux "
- "understands. Please report this to the Linux "
- "ACPI maintainers and complain to your BIOS "
- "vendor.\n");
-#endif
- kfree(data);
- return -ENODEV;
+ /*
+ * Replace this one with print_once as soon as such a
+ * thing gets introduced
+ */
+ if (!print_once) {
+ WARN_ONCE(1, KERN_ERR FW_BUG PFX "Your BIOS "
+ "does not provide ACPI _PSS objects "
+ "in a way that Linux understands. "
+ "Please report this to the Linux ACPI"
+ " maintainers and complain to your "
+ "BIOS vendor.\n");
+ print_once++;
+ }
+ goto err_out;
}
if (pol->cpu != 0) {
printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for "
"CPU other than CPU0. Complain to your BIOS "
"vendor.\n");
- kfree(data);
- return -ENODEV;
+ goto err_out;
}
rc = find_psb_table(data);
- if (rc) {
- kfree(data);
- return -ENODEV;
- }
+ if (rc)
+ goto err_out;
+
/* Take a crude guess here.
* That guess was in microseconds, so multiply with 1000 */
pol->cpuinfo.transition_latency = (
@@ -1204,16 +1283,16 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
if (smp_processor_id() != pol->cpu) {
printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
- goto err_out;
+ goto err_out_unmask;
}
if (pending_bit_stuck()) {
printk(KERN_ERR PFX "failing init, change pending bit set\n");
- goto err_out;
+ goto err_out_unmask;
}
if (query_current_values_with_pending_wait(data))
- goto err_out;
+ goto err_out_unmask;
if (cpu_family == CPU_OPTERON)
fidvid_msr_init();
@@ -1224,11 +1303,12 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
if (cpu_family == CPU_HW_PSTATE)
cpumask_copy(pol->cpus, cpumask_of(pol->cpu));
else
- cpumask_copy(pol->cpus, &per_cpu(cpu_core_map, pol->cpu));
+ cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu));
data->available_cores = pol->cpus;
if (cpu_family == CPU_HW_PSTATE)
- pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate);
+ pol->cur = find_khz_freq_from_pstate(data->powernow_table,
+ data->currpstate);
else
pol->cur = find_khz_freq_from_fid(data->currfid);
dprintk("policy current frequency %d kHz\n", pol->cur);
@@ -1245,7 +1325,8 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
if (cpu_family == CPU_HW_PSTATE)
- dprintk("cpu_init done, current pstate 0x%x\n", data->currpstate);
+ dprintk("cpu_init done, current pstate 0x%x\n",
+ data->currpstate);
else
dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n",
data->currfid, data->currvid);
@@ -1254,15 +1335,16 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
return 0;
-err_out:
+err_out_unmask:
set_cpus_allowed_ptr(current, &oldmask);
powernow_k8_cpu_exit_acpi(data);
+err_out:
kfree(data);
return -ENODEV;
}
-static int __devexit powernowk8_cpu_exit (struct cpufreq_policy *pol)
+static int __devexit powernowk8_cpu_exit(struct cpufreq_policy *pol)
{
struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
@@ -1279,14 +1361,14 @@ static int __devexit powernowk8_cpu_exit (struct cpufreq_policy *pol)
return 0;
}
-static unsigned int powernowk8_get (unsigned int cpu)
+static unsigned int powernowk8_get(unsigned int cpu)
{
struct powernow_k8_data *data;
cpumask_t oldmask = current->cpus_allowed;
unsigned int khz = 0;
unsigned int first;
- first = first_cpu(per_cpu(cpu_core_map, cpu));
+ first = cpumask_first(cpu_core_mask(cpu));
data = per_cpu(powernow_data, first);
if (!data)
@@ -1315,7 +1397,7 @@ out:
return khz;
}
-static struct freq_attr* powernow_k8_attr[] = {
+static struct freq_attr *powernow_k8_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};
@@ -1360,7 +1442,8 @@ static void __exit powernowk8_exit(void)
cpufreq_unregister_driver(&cpufreq_amd64_driver);
}
-MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com>");
+MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and "
+ "Mark Langsdorf <mark.langsdorf@amd.com>");
MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
MODULE_LICENSE("GPL");
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
index 8ecc75b6c7c3..6c6698feade1 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
@@ -45,11 +45,10 @@ struct powernow_k8_data {
* frequency is in kHz */
struct cpufreq_frequency_table *powernow_table;
-#ifdef CONFIG_X86_POWERNOW_K8_ACPI
/* the acpi table needs to be kept. it's only available if ACPI was
* used to determine valid frequency/vid/fid states */
struct acpi_processor_performance acpi_data;
-#endif
+
/* we need to keep track of associated cores, but let cpufreq
* handle hotplug events - so just point at cpufreq pol->cpus
* structure */
@@ -222,10 +221,8 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);
static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index);
-#ifdef CONFIG_X86_POWERNOW_K8_ACPI
static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
-#endif
#ifdef CONFIG_SMP
static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[])
diff --git a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
index 42da9bd677d6..435a996a613a 100644
--- a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
+++ b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
@@ -19,17 +19,19 @@
#include <linux/delay.h>
#include <linux/cpufreq.h>
+#include <linux/timex.h>
+#include <linux/io.h>
#include <asm/msr.h>
-#include <asm/timex.h>
-#include <asm/io.h>
#define MMCR_BASE 0xfffef000 /* The default base address */
#define OFFS_CPUCTL 0x2 /* CPU Control Register */
static __u8 __iomem *cpuctl;
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "sc520_freq", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "sc520_freq", msg)
+#define PFX "sc520_freq: "
static struct cpufreq_frequency_table sc520_freq_table[] = {
{0x01, 100000},
@@ -43,7 +45,8 @@ static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu)
switch (clockspeed_reg & 0x03) {
default:
- printk(KERN_ERR "sc520_freq: error: cpuctl register has unexpected value %02x\n", clockspeed_reg);
+ printk(KERN_ERR PFX "error: cpuctl register has unexpected "
+ "value %02x\n", clockspeed_reg);
case 0x01:
return 100000;
case 0x02:
@@ -51,7 +54,7 @@ static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu)
}
}
-static void sc520_freq_set_cpu_state (unsigned int state)
+static void sc520_freq_set_cpu_state(unsigned int state)
{
struct cpufreq_freqs freqs;
@@ -76,18 +79,19 @@ static void sc520_freq_set_cpu_state (unsigned int state)
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
};
-static int sc520_freq_verify (struct cpufreq_policy *policy)
+static int sc520_freq_verify(struct cpufreq_policy *policy)
{
return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]);
}
-static int sc520_freq_target (struct cpufreq_policy *policy,
+static int sc520_freq_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
unsigned int newstate = 0;
- if (cpufreq_frequency_table_target(policy, sc520_freq_table, target_freq, relation, &newstate))
+ if (cpufreq_frequency_table_target(policy, sc520_freq_table,
+ target_freq, relation, &newstate))
return -EINVAL;
sc520_freq_set_cpu_state(newstate);
@@ -116,7 +120,7 @@ static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table);
if (result)
- return (result);
+ return result;
cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu);
@@ -131,7 +135,7 @@ static int sc520_freq_cpu_exit(struct cpufreq_policy *policy)
}
-static struct freq_attr* sc520_freq_attr[] = {
+static struct freq_attr *sc520_freq_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};
@@ -155,13 +159,13 @@ static int __init sc520_freq_init(void)
int err;
/* Test if we have the right hardware */
- if(c->x86_vendor != X86_VENDOR_AMD ||
- c->x86 != 4 || c->x86_model != 9) {
+ if (c->x86_vendor != X86_VENDOR_AMD ||
+ c->x86 != 4 || c->x86_model != 9) {
dprintk("no Elan SC520 processor found!\n");
return -ENODEV;
}
cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
- if(!cpuctl) {
+ if (!cpuctl) {
printk(KERN_ERR "sc520_freq: error: failed to remap memory\n");
return -ENOMEM;
}
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
index dedc1e98f168..016c1a4fa3fc 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
@@ -39,7 +39,7 @@ static struct pci_dev *speedstep_chipset_dev;
/* speedstep_processor
*/
-static unsigned int speedstep_processor = 0;
+static unsigned int speedstep_processor;
static u32 pmbase;
@@ -54,7 +54,8 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
};
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-ich", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "speedstep-ich", msg)
/**
@@ -62,7 +63,7 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
*
* Returns: -ENODEV if no register could be found
*/
-static int speedstep_find_register (void)
+static int speedstep_find_register(void)
{
if (!speedstep_chipset_dev)
return -ENODEV;
@@ -90,7 +91,7 @@ static int speedstep_find_register (void)
*
* Tries to change the SpeedStep state.
*/
-static void speedstep_set_state (unsigned int state)
+static void speedstep_set_state(unsigned int state)
{
u8 pm2_blk;
u8 value;
@@ -133,11 +134,11 @@ static void speedstep_set_state (unsigned int state)
dprintk("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
- if (state == (value & 0x1)) {
- dprintk("change to %u MHz succeeded\n", (speedstep_get_processor_frequency(speedstep_processor) / 1000));
- } else {
- printk (KERN_ERR "cpufreq: change failed - I/O error\n");
- }
+ if (state == (value & 0x1))
+ dprintk("change to %u MHz succeeded\n",
+ speedstep_get_frequency(speedstep_processor) / 1000);
+ else
+ printk(KERN_ERR "cpufreq: change failed - I/O error\n");
return;
}
@@ -149,7 +150,7 @@ static void speedstep_set_state (unsigned int state)
* Tries to activate the SpeedStep status and control registers.
* Returns -EINVAL on an unsupported chipset, and zero on success.
*/
-static int speedstep_activate (void)
+static int speedstep_activate(void)
{
u16 value = 0;
@@ -175,20 +176,18 @@ static int speedstep_activate (void)
* functions. Returns the SPEEDSTEP_CHIPSET_-number for the detected
* chipset, or zero on failure.
*/
-static unsigned int speedstep_detect_chipset (void)
+static unsigned int speedstep_detect_chipset(void)
{
speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82801DB_12,
- PCI_ANY_ID,
- PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
NULL);
if (speedstep_chipset_dev)
return 4; /* 4-M */
speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82801CA_12,
- PCI_ANY_ID,
- PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
NULL);
if (speedstep_chipset_dev)
return 3; /* 3-M */
@@ -196,8 +195,7 @@ static unsigned int speedstep_detect_chipset (void)
speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82801BA_10,
- PCI_ANY_ID,
- PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
NULL);
if (speedstep_chipset_dev) {
/* speedstep.c causes lockups on Dell Inspirons 8000 and
@@ -208,8 +206,7 @@ static unsigned int speedstep_detect_chipset (void)
hostbridge = pci_get_subsys(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82815_MC,
- PCI_ANY_ID,
- PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
NULL);
if (!hostbridge)
@@ -236,7 +233,7 @@ static unsigned int _speedstep_get(const struct cpumask *cpus)
cpus_allowed = current->cpus_allowed;
set_cpus_allowed_ptr(current, cpus);
- speed = speedstep_get_processor_frequency(speedstep_processor);
+ speed = speedstep_get_frequency(speedstep_processor);
set_cpus_allowed_ptr(current, &cpus_allowed);
dprintk("detected %u kHz as current frequency\n", speed);
return speed;
@@ -251,11 +248,12 @@ static unsigned int speedstep_get(unsigned int cpu)
* speedstep_target - set a new CPUFreq policy
* @policy: new policy
* @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ * @relation: how that frequency relates to achieved frequency
+ * (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
*
* Sets a new CPUFreq policy.
*/
-static int speedstep_target (struct cpufreq_policy *policy,
+static int speedstep_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
@@ -264,7 +262,8 @@ static int speedstep_target (struct cpufreq_policy *policy,
cpumask_t cpus_allowed;
int i;
- if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate))
+ if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0],
+ target_freq, relation, &newstate))
return -EINVAL;
freqs.old = _speedstep_get(policy->cpus);
@@ -308,7 +307,7 @@ static int speedstep_target (struct cpufreq_policy *policy,
* Limit must be within speedstep_low_freq and speedstep_high_freq, with
* at least one border included.
*/
-static int speedstep_verify (struct cpufreq_policy *policy)
+static int speedstep_verify(struct cpufreq_policy *policy)
{
return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]);
}
@@ -322,7 +321,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
/* only run on CPU to be set, or on its sibling */
#ifdef CONFIG_SMP
- cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu));
+ cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
#endif
cpus_allowed = current->cpus_allowed;
@@ -344,7 +343,8 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
return -EIO;
dprintk("currently at %s speed setting - %i MHz\n",
- (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high",
+ (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency)
+ ? "low" : "high",
(speed / 1000));
/* cpuinfo and default policy values */
@@ -352,9 +352,9 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
if (result)
- return (result);
+ return result;
- cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu);
+ cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu);
return 0;
}
@@ -366,7 +366,7 @@ static int speedstep_cpu_exit(struct cpufreq_policy *policy)
return 0;
}
-static struct freq_attr* speedstep_attr[] = {
+static struct freq_attr *speedstep_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};
@@ -396,13 +396,15 @@ static int __init speedstep_init(void)
/* detect processor */
speedstep_processor = speedstep_detect_processor();
if (!speedstep_processor) {
- dprintk("Intel(R) SpeedStep(TM) capable processor not found\n");
+ dprintk("Intel(R) SpeedStep(TM) capable processor "
+ "not found\n");
return -ENODEV;
}
/* detect chipset */
if (!speedstep_detect_chipset()) {
- dprintk("Intel(R) SpeedStep(TM) for this chipset not (yet) available.\n");
+ dprintk("Intel(R) SpeedStep(TM) for this chipset not "
+ "(yet) available.\n");
return -ENODEV;
}
@@ -431,9 +433,11 @@ static void __exit speedstep_exit(void)
}
-MODULE_AUTHOR ("Dave Jones <davej@redhat.com>, Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION ("Speedstep driver for Intel mobile processors on chipsets with ICH-M southbridges.");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>, "
+ "Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("Speedstep driver for Intel mobile processors on chipsets "
+ "with ICH-M southbridges.");
+MODULE_LICENSE("GPL");
module_init(speedstep_init);
module_exit(speedstep_exit);
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
index cdac7d62369b..2e3c6862657b 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
@@ -16,12 +16,16 @@
#include <linux/slab.h>
#include <asm/msr.h>
+#include <asm/tsc.h>
#include "speedstep-lib.h"
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-lib", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "speedstep-lib", msg)
+
+#define PFX "speedstep-lib: "
#ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
-static int relaxed_check = 0;
+static int relaxed_check;
#else
#define relaxed_check 0
#endif
@@ -30,14 +34,14 @@ static int relaxed_check = 0;
* GET PROCESSOR CORE SPEED IN KHZ *
*********************************************************************/
-static unsigned int pentium3_get_frequency (unsigned int processor)
+static unsigned int pentium3_get_frequency(unsigned int processor)
{
- /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */
+ /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */
struct {
unsigned int ratio; /* Frequency Multiplier (x10) */
u8 bitmap; /* power on configuration bits
[27, 25:22] (in MSR 0x2a) */
- } msr_decode_mult [] = {
+ } msr_decode_mult[] = {
{ 30, 0x01 },
{ 35, 0x05 },
{ 40, 0x02 },
@@ -52,7 +56,7 @@ static unsigned int pentium3_get_frequency (unsigned int processor)
{ 85, 0x26 },
{ 90, 0x20 },
{ 100, 0x2b },
- { 0, 0xff } /* error or unknown value */
+ { 0, 0xff } /* error or unknown value */
};
/* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */
@@ -60,7 +64,7 @@ static unsigned int pentium3_get_frequency (unsigned int processor)
unsigned int value; /* Front Side Bus speed in MHz */
u8 bitmap; /* power on configuration bits [18: 19]
(in MSR 0x2a) */
- } msr_decode_fsb [] = {
+ } msr_decode_fsb[] = {
{ 66, 0x0 },
{ 100, 0x2 },
{ 133, 0x1 },
@@ -85,7 +89,7 @@ static unsigned int pentium3_get_frequency (unsigned int processor)
}
/* decode the multiplier */
- if (processor == SPEEDSTEP_PROCESSOR_PIII_C_EARLY) {
+ if (processor == SPEEDSTEP_CPU_PIII_C_EARLY) {
dprintk("workaround for early PIIIs\n");
msr_lo &= 0x03c00000;
} else
@@ -97,9 +101,10 @@ static unsigned int pentium3_get_frequency (unsigned int processor)
j++;
}
- dprintk("speed is %u\n", (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100));
+ dprintk("speed is %u\n",
+ (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100));
- return (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100);
+ return msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100;
}
@@ -112,20 +117,23 @@ static unsigned int pentiumM_get_frequency(void)
/* see table B-2 of 24547212.pdf */
if (msr_lo & 0x00040000) {
- printk(KERN_DEBUG "speedstep-lib: PM - invalid FSB: 0x%x 0x%x\n", msr_lo, msr_tmp);
+ printk(KERN_DEBUG PFX "PM - invalid FSB: 0x%x 0x%x\n",
+ msr_lo, msr_tmp);
return 0;
}
msr_tmp = (msr_lo >> 22) & 0x1f;
- dprintk("bits 22-26 are 0x%x, speed is %u\n", msr_tmp, (msr_tmp * 100 * 1000));
+ dprintk("bits 22-26 are 0x%x, speed is %u\n",
+ msr_tmp, (msr_tmp * 100 * 1000));
- return (msr_tmp * 100 * 1000);
+ return msr_tmp * 100 * 1000;
}
static unsigned int pentium_core_get_frequency(void)
{
u32 fsb = 0;
u32 msr_lo, msr_tmp;
+ int ret;
rdmsr(MSR_FSB_FREQ, msr_lo, msr_tmp);
/* see table B-2 of 25366920.pdf */
@@ -153,12 +161,15 @@ static unsigned int pentium_core_get_frequency(void)
}
rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
- dprintk("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
+ dprintk("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n",
+ msr_lo, msr_tmp);
msr_tmp = (msr_lo >> 22) & 0x1f;
- dprintk("bits 22-26 are 0x%x, speed is %u\n", msr_tmp, (msr_tmp * fsb));
+ dprintk("bits 22-26 are 0x%x, speed is %u\n",
+ msr_tmp, (msr_tmp * fsb));
- return (msr_tmp * fsb);
+ ret = (msr_tmp * fsb);
+ return ret;
}
@@ -167,6 +178,16 @@ static unsigned int pentium4_get_frequency(void)
struct cpuinfo_x86 *c = &boot_cpu_data;
u32 msr_lo, msr_hi, mult;
unsigned int fsb = 0;
+ unsigned int ret;
+ u8 fsb_code;
+
+ /* Pentium 4 Model 0 and 1 do not have the Core Clock Frequency
+ * to System Bus Frequency Ratio Field in the Processor Frequency
+ * Configuration Register of the MSR. Therefore the current
+ * frequency cannot be calculated and has to be measured.
+ */
+ if (c->x86_model < 2)
+ return cpu_khz;
rdmsr(0x2c, msr_lo, msr_hi);
@@ -177,62 +198,61 @@ static unsigned int pentium4_get_frequency(void)
* revision #12 in Table B-1: MSRs in the Pentium 4 and
* Intel Xeon Processors, on page B-4 and B-5.
*/
- if (c->x86_model < 2)
+ fsb_code = (msr_lo >> 16) & 0x7;
+ switch (fsb_code) {
+ case 0:
fsb = 100 * 1000;
- else {
- u8 fsb_code = (msr_lo >> 16) & 0x7;
- switch (fsb_code) {
- case 0:
- fsb = 100 * 1000;
- break;
- case 1:
- fsb = 13333 * 10;
- break;
- case 2:
- fsb = 200 * 1000;
- break;
- }
+ break;
+ case 1:
+ fsb = 13333 * 10;
+ break;
+ case 2:
+ fsb = 200 * 1000;
+ break;
}
if (!fsb)
- printk(KERN_DEBUG "speedstep-lib: couldn't detect FSB speed. Please send an e-mail to <linux@brodo.de>\n");
+ printk(KERN_DEBUG PFX "couldn't detect FSB speed. "
+ "Please send an e-mail to <linux@brodo.de>\n");
/* Multiplier. */
mult = msr_lo >> 24;
- dprintk("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n", fsb, mult, (fsb * mult));
+ dprintk("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n",
+ fsb, mult, (fsb * mult));
- return (fsb * mult);
+ ret = (fsb * mult);
+ return ret;
}
-unsigned int speedstep_get_processor_frequency(unsigned int processor)
+unsigned int speedstep_get_frequency(unsigned int processor)
{
switch (processor) {
- case SPEEDSTEP_PROCESSOR_PCORE:
+ case SPEEDSTEP_CPU_PCORE:
return pentium_core_get_frequency();
- case SPEEDSTEP_PROCESSOR_PM:
+ case SPEEDSTEP_CPU_PM:
return pentiumM_get_frequency();
- case SPEEDSTEP_PROCESSOR_P4D:
- case SPEEDSTEP_PROCESSOR_P4M:
+ case SPEEDSTEP_CPU_P4D:
+ case SPEEDSTEP_CPU_P4M:
return pentium4_get_frequency();
- case SPEEDSTEP_PROCESSOR_PIII_T:
- case SPEEDSTEP_PROCESSOR_PIII_C:
- case SPEEDSTEP_PROCESSOR_PIII_C_EARLY:
+ case SPEEDSTEP_CPU_PIII_T:
+ case SPEEDSTEP_CPU_PIII_C:
+ case SPEEDSTEP_CPU_PIII_C_EARLY:
return pentium3_get_frequency(processor);
default:
return 0;
};
return 0;
}
-EXPORT_SYMBOL_GPL(speedstep_get_processor_frequency);
+EXPORT_SYMBOL_GPL(speedstep_get_frequency);
/*********************************************************************
* DETECT SPEEDSTEP-CAPABLE PROCESSOR *
*********************************************************************/
-unsigned int speedstep_detect_processor (void)
+unsigned int speedstep_detect_processor(void)
{
struct cpuinfo_x86 *c = &cpu_data(0);
u32 ebx, msr_lo, msr_hi;
@@ -261,7 +281,7 @@ unsigned int speedstep_detect_processor (void)
* sample has ebx = 0x0f, production has 0x0e.
*/
if ((ebx == 0x0e) || (ebx == 0x0f))
- return SPEEDSTEP_PROCESSOR_P4M;
+ return SPEEDSTEP_CPU_P4M;
break;
case 7:
/*
@@ -272,7 +292,7 @@ unsigned int speedstep_detect_processor (void)
* samples are only of B-stepping...
*/
if (ebx == 0x0e)
- return SPEEDSTEP_PROCESSOR_P4M;
+ return SPEEDSTEP_CPU_P4M;
break;
case 9:
/*
@@ -288,10 +308,13 @@ unsigned int speedstep_detect_processor (void)
* M-P4-Ms may have either ebx=0xe or 0xf [see above]
* M-P4/533 have either ebx=0xe or 0xf. [25317607.pdf]
* also, M-P4M HTs have ebx=0x8, too
- * For now, they are distinguished by the model_id string
+ * For now, they are distinguished by the model_id
+ * string
*/
- if ((ebx == 0x0e) || (strstr(c->x86_model_id,"Mobile Intel(R) Pentium(R) 4") != NULL))
- return SPEEDSTEP_PROCESSOR_P4M;
+ if ((ebx == 0x0e) ||
+ (strstr(c->x86_model_id,
+ "Mobile Intel(R) Pentium(R) 4") != NULL))
+ return SPEEDSTEP_CPU_P4M;
break;
default:
break;
@@ -301,7 +324,8 @@ unsigned int speedstep_detect_processor (void)
switch (c->x86_model) {
case 0x0B: /* Intel PIII [Tualatin] */
- /* cpuid_ebx(1) is 0x04 for desktop PIII, 0x06 for mobile PIII-M */
+ /* cpuid_ebx(1) is 0x04 for desktop PIII,
+ * 0x06 for mobile PIII-M */
ebx = cpuid_ebx(0x00000001);
dprintk("ebx is %x\n", ebx);
@@ -313,14 +337,15 @@ unsigned int speedstep_detect_processor (void)
/* So far all PIII-M processors support SpeedStep. See
* Intel's 24540640.pdf of June 2003
*/
- return SPEEDSTEP_PROCESSOR_PIII_T;
+ return SPEEDSTEP_CPU_PIII_T;
case 0x08: /* Intel PIII [Coppermine] */
/* all mobile PIII Coppermines have FSB 100 MHz
* ==> sort out a few desktop PIIIs. */
rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi);
- dprintk("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n", msr_lo, msr_hi);
+ dprintk("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n",
+ msr_lo, msr_hi);
msr_lo &= 0x00c0000;
if (msr_lo != 0x0080000)
return 0;
@@ -332,13 +357,15 @@ unsigned int speedstep_detect_processor (void)
* bit 56 or 57 is set
*/
rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi);
- dprintk("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n", msr_lo, msr_hi);
- if ((msr_hi & (1<<18)) && (relaxed_check ? 1 : (msr_hi & (3<<24)))) {
+ dprintk("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n",
+ msr_lo, msr_hi);
+ if ((msr_hi & (1<<18)) &&
+ (relaxed_check ? 1 : (msr_hi & (3<<24)))) {
if (c->x86_mask == 0x01) {
dprintk("early PIII version\n");
- return SPEEDSTEP_PROCESSOR_PIII_C_EARLY;
+ return SPEEDSTEP_CPU_PIII_C_EARLY;
} else
- return SPEEDSTEP_PROCESSOR_PIII_C;
+ return SPEEDSTEP_CPU_PIII_C;
}
default:
@@ -369,7 +396,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
dprintk("trying to determine both speeds\n");
/* get current speed */
- prev_speed = speedstep_get_processor_frequency(processor);
+ prev_speed = speedstep_get_frequency(processor);
if (!prev_speed)
return -EIO;
@@ -379,7 +406,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
/* switch to low state */
set_state(SPEEDSTEP_LOW);
- *low_speed = speedstep_get_processor_frequency(processor);
+ *low_speed = speedstep_get_frequency(processor);
if (!*low_speed) {
ret = -EIO;
goto out;
@@ -398,7 +425,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
if (transition_latency)
do_gettimeofday(&tv2);
- *high_speed = speedstep_get_processor_frequency(processor);
+ *high_speed = speedstep_get_frequency(processor);
if (!*high_speed) {
ret = -EIO;
goto out;
@@ -426,9 +453,12 @@ unsigned int speedstep_get_freqs(unsigned int processor,
/* check if the latency measurement is too high or too low
* and set it to a safe value (500uSec) in that case
*/
- if (*transition_latency > 10000000 || *transition_latency < 50000) {
- printk (KERN_WARNING "speedstep: frequency transition measured seems out of "
- "range (%u nSec), falling back to a safe one of %u nSec.\n",
+ if (*transition_latency > 10000000 ||
+ *transition_latency < 50000) {
+ printk(KERN_WARNING PFX "frequency transition "
+ "measured seems out of range (%u "
+ "nSec), falling back to a safe one of"
+ "%u nSec.\n",
*transition_latency, 500000);
*transition_latency = 500000;
}
@@ -436,15 +466,16 @@ unsigned int speedstep_get_freqs(unsigned int processor,
out:
local_irq_restore(flags);
- return (ret);
+ return ret;
}
EXPORT_SYMBOL_GPL(speedstep_get_freqs);
#ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
module_param(relaxed_check, int, 0444);
-MODULE_PARM_DESC(relaxed_check, "Don't do all checks for speedstep capability.");
+MODULE_PARM_DESC(relaxed_check,
+ "Don't do all checks for speedstep capability.");
#endif
-MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION ("Library for Intel SpeedStep 1 or 2 cpufreq drivers.");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("Library for Intel SpeedStep 1 or 2 cpufreq drivers.");
+MODULE_LICENSE("GPL");
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h
index b11bcc608cac..2b6c04e5a304 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h
@@ -12,17 +12,17 @@
/* processors */
-#define SPEEDSTEP_PROCESSOR_PIII_C_EARLY 0x00000001 /* Coppermine core */
-#define SPEEDSTEP_PROCESSOR_PIII_C 0x00000002 /* Coppermine core */
-#define SPEEDSTEP_PROCESSOR_PIII_T 0x00000003 /* Tualatin core */
-#define SPEEDSTEP_PROCESSOR_P4M 0x00000004 /* P4-M */
+#define SPEEDSTEP_CPU_PIII_C_EARLY 0x00000001 /* Coppermine core */
+#define SPEEDSTEP_CPU_PIII_C 0x00000002 /* Coppermine core */
+#define SPEEDSTEP_CPU_PIII_T 0x00000003 /* Tualatin core */
+#define SPEEDSTEP_CPU_P4M 0x00000004 /* P4-M */
/* the following processors are not speedstep-capable and are not auto-detected
* in speedstep_detect_processor(). However, their speed can be detected using
- * the speedstep_get_processor_frequency() call. */
-#define SPEEDSTEP_PROCESSOR_PM 0xFFFFFF03 /* Pentium M */
-#define SPEEDSTEP_PROCESSOR_P4D 0xFFFFFF04 /* desktop P4 */
-#define SPEEDSTEP_PROCESSOR_PCORE 0xFFFFFF05 /* Core */
+ * the speedstep_get_frequency() call. */
+#define SPEEDSTEP_CPU_PM 0xFFFFFF03 /* Pentium M */
+#define SPEEDSTEP_CPU_P4D 0xFFFFFF04 /* desktop P4 */
+#define SPEEDSTEP_CPU_PCORE 0xFFFFFF05 /* Core */
/* speedstep states -- only two of them */
@@ -34,7 +34,7 @@
extern unsigned int speedstep_detect_processor (void);
/* detect the current speed (in khz) of the processor */
-extern unsigned int speedstep_get_processor_frequency(unsigned int processor);
+extern unsigned int speedstep_get_frequency(unsigned int processor);
/* detect the low and high speeds of the processor. The callback
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
index 8a85c93bd62a..befea088e4f5 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
@@ -19,8 +19,8 @@
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/io.h>
#include <asm/ist.h>
-#include <asm/io.h>
#include "speedstep-lib.h"
@@ -30,12 +30,12 @@
* If user gives it, these are used.
*
*/
-static int smi_port = 0;
-static int smi_cmd = 0;
-static unsigned int smi_sig = 0;
+static int smi_port;
+static int smi_cmd;
+static unsigned int smi_sig;
/* info about the processor */
-static unsigned int speedstep_processor = 0;
+static unsigned int speedstep_processor;
/*
* There are only two frequency states for each processor. Values
@@ -56,12 +56,13 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
* of DMA activity going on? */
#define SMI_TRIES 5
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-smi", msg)
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
+ "speedstep-smi", msg)
/**
* speedstep_smi_ownership
*/
-static int speedstep_smi_ownership (void)
+static int speedstep_smi_ownership(void)
{
u32 command, result, magic, dummy;
u32 function = GET_SPEEDSTEP_OWNER;
@@ -70,16 +71,18 @@ static int speedstep_smi_ownership (void)
command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
magic = virt_to_phys(magic_data);
- dprintk("trying to obtain ownership with command %x at port %x\n", command, smi_port);
+ dprintk("trying to obtain ownership with command %x at port %x\n",
+ command, smi_port);
__asm__ __volatile__(
"push %%ebp\n"
"out %%al, (%%dx)\n"
"pop %%ebp\n"
- : "=D" (result), "=a" (dummy), "=b" (dummy), "=c" (dummy), "=d" (dummy),
- "=S" (dummy)
+ : "=D" (result),
+ "=a" (dummy), "=b" (dummy), "=c" (dummy), "=d" (dummy),
+ "=S" (dummy)
: "a" (command), "b" (function), "c" (0), "d" (smi_port),
- "D" (0), "S" (magic)
+ "D" (0), "S" (magic)
: "memory"
);
@@ -97,10 +100,10 @@ static int speedstep_smi_ownership (void)
* even hangs [cf. bugme.osdl.org # 1422] on earlier systems. Empirical testing
* shows that the latter occurs if !(ist_info.event & 0xFFFF).
*/
-static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
+static int speedstep_smi_get_freqs(unsigned int *low, unsigned int *high)
{
u32 command, result = 0, edi, high_mhz, low_mhz, dummy;
- u32 state=0;
+ u32 state = 0;
u32 function = GET_SPEEDSTEP_FREQS;
if (!(ist_info.event & 0xFFFF)) {
@@ -110,17 +113,25 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
- dprintk("trying to determine frequencies with command %x at port %x\n", command, smi_port);
+ dprintk("trying to determine frequencies with command %x at port %x\n",
+ command, smi_port);
__asm__ __volatile__(
"push %%ebp\n"
"out %%al, (%%dx)\n"
"pop %%ebp"
- : "=a" (result), "=b" (high_mhz), "=c" (low_mhz), "=d" (state), "=D" (edi), "=S" (dummy)
- : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0), "D" (0)
+ : "=a" (result),
+ "=b" (high_mhz),
+ "=c" (low_mhz),
+ "=d" (state), "=D" (edi), "=S" (dummy)
+ : "a" (command),
+ "b" (function),
+ "c" (state),
+ "d" (smi_port), "S" (0), "D" (0)
);
- dprintk("result %x, low_freq %u, high_freq %u\n", result, low_mhz, high_mhz);
+ dprintk("result %x, low_freq %u, high_freq %u\n",
+ result, low_mhz, high_mhz);
/* abort if results are obviously incorrect... */
if ((high_mhz + low_mhz) < 600)
@@ -137,26 +148,30 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
* @state: processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
*
*/
-static int speedstep_get_state (void)
+static int speedstep_get_state(void)
{
- u32 function=GET_SPEEDSTEP_STATE;
+ u32 function = GET_SPEEDSTEP_STATE;
u32 result, state, edi, command, dummy;
command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
- dprintk("trying to determine current setting with command %x at port %x\n", command, smi_port);
+ dprintk("trying to determine current setting with command %x "
+ "at port %x\n", command, smi_port);
__asm__ __volatile__(
"push %%ebp\n"
"out %%al, (%%dx)\n"
"pop %%ebp\n"
- : "=a" (result), "=b" (state), "=D" (edi), "=c" (dummy), "=d" (dummy), "=S" (dummy)
- : "a" (command), "b" (function), "c" (0), "d" (smi_port), "S" (0), "D" (0)
+ : "=a" (result),
+ "=b" (state), "=D" (edi),
+ "=c" (dummy), "=d" (dummy), "=S" (dummy)
+ : "a" (command), "b" (function), "c" (0),
+ "d" (smi_port), "S" (0), "D" (0)
);
dprintk("state is %x, result is %x\n", state, result);
- return (state & 1);
+ return state & 1;
}
@@ -165,11 +180,11 @@ static int speedstep_get_state (void)
* @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
*
*/
-static void speedstep_set_state (unsigned int state)
+static void speedstep_set_state(unsigned int state)
{
unsigned int result = 0, command, new_state, dummy;
unsigned long flags;
- unsigned int function=SET_SPEEDSTEP_STATE;
+ unsigned int function = SET_SPEEDSTEP_STATE;
unsigned int retry = 0;
if (state > 0x1)
@@ -180,11 +195,14 @@ static void speedstep_set_state (unsigned int state)
command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
- dprintk("trying to set frequency to state %u with command %x at port %x\n", state, command, smi_port);
+ dprintk("trying to set frequency to state %u "
+ "with command %x at port %x\n",
+ state, command, smi_port);
do {
if (retry) {
- dprintk("retry %u, previous result %u, waiting...\n", retry, result);
+ dprintk("retry %u, previous result %u, waiting...\n",
+ retry, result);
mdelay(retry * 50);
}
retry++;
@@ -192,20 +210,26 @@ static void speedstep_set_state (unsigned int state)
"push %%ebp\n"
"out %%al, (%%dx)\n"
"pop %%ebp"
- : "=b" (new_state), "=D" (result), "=c" (dummy), "=a" (dummy),
- "=d" (dummy), "=S" (dummy)
- : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0), "D" (0)
+ : "=b" (new_state), "=D" (result),
+ "=c" (dummy), "=a" (dummy),
+ "=d" (dummy), "=S" (dummy)
+ : "a" (command), "b" (function), "c" (state),
+ "d" (smi_port), "S" (0), "D" (0)
);
} while ((new_state != state) && (retry <= SMI_TRIES));
/* enable IRQs */
local_irq_restore(flags);
- if (new_state == state) {
- dprintk("change to %u MHz succeeded after %u tries with result %u\n", (speedstep_freqs[new_state].frequency / 1000), retry, result);
- } else {
- printk(KERN_ERR "cpufreq: change to state %u failed with new_state %u and result %u\n", state, new_state, result);
- }
+ if (new_state == state)
+ dprintk("change to %u MHz succeeded after %u tries "
+ "with result %u\n",
+ (speedstep_freqs[new_state].frequency / 1000),
+ retry, result);
+ else
+ printk(KERN_ERR "cpufreq: change to state %u "
+ "failed with new_state %u and result %u\n",
+ state, new_state, result);
return;
}
@@ -219,13 +243,14 @@ static void speedstep_set_state (unsigned int state)
*
* Sets a new CPUFreq policy/freq.
*/
-static int speedstep_target (struct cpufreq_policy *policy,
+static int speedstep_target(struct cpufreq_policy *policy,
unsigned int target_freq, unsigned int relation)
{
unsigned int newstate = 0;
struct cpufreq_freqs freqs;
- if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate))
+ if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0],
+ target_freq, relation, &newstate))
return -EINVAL;
freqs.old = speedstep_freqs[speedstep_get_state()].frequency;
@@ -250,7 +275,7 @@ static int speedstep_target (struct cpufreq_policy *policy,
* Limit must be within speedstep_low_freq and speedstep_high_freq, with
* at least one border included.
*/
-static int speedstep_verify (struct cpufreq_policy *policy)
+static int speedstep_verify(struct cpufreq_policy *policy)
{
return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]);
}
@@ -259,7 +284,8 @@ static int speedstep_verify (struct cpufreq_policy *policy)
static int speedstep_cpu_init(struct cpufreq_policy *policy)
{
int result;
- unsigned int speed,state;
+ unsigned int speed, state;
+ unsigned int *low, *high;
/* capability check */
if (policy->cpu != 0)
@@ -272,19 +298,23 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
}
/* detect low and high frequency */
- result = speedstep_smi_get_freqs(&speedstep_freqs[SPEEDSTEP_LOW].frequency,
- &speedstep_freqs[SPEEDSTEP_HIGH].frequency);
+ low = &speedstep_freqs[SPEEDSTEP_LOW].frequency;
+ high = &speedstep_freqs[SPEEDSTEP_HIGH].frequency;
+
+ result = speedstep_smi_get_freqs(low, high);
if (result) {
- /* fall back to speedstep_lib.c dection mechanism: try both states out */
- dprintk("could not detect low and high frequencies by SMI call.\n");
+ /* fall back to speedstep_lib.c dection mechanism:
+ * try both states out */
+ dprintk("could not detect low and high frequencies "
+ "by SMI call.\n");
result = speedstep_get_freqs(speedstep_processor,
- &speedstep_freqs[SPEEDSTEP_LOW].frequency,
- &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
+ low, high,
NULL,
&speedstep_set_state);
if (result) {
- dprintk("could not detect two different speeds -- aborting.\n");
+ dprintk("could not detect two different speeds"
+ " -- aborting.\n");
return result;
} else
dprintk("workaround worked.\n");
@@ -295,7 +325,8 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
speed = speedstep_freqs[state].frequency;
dprintk("currently at %s speed setting - %i MHz\n",
- (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high",
+ (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency)
+ ? "low" : "high",
(speed / 1000));
/* cpuinfo and default policy values */
@@ -304,7 +335,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
if (result)
- return (result);
+ return result;
cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu);
@@ -321,7 +352,7 @@ static unsigned int speedstep_get(unsigned int cpu)
{
if (cpu)
return -ENODEV;
- return speedstep_get_processor_frequency(speedstep_processor);
+ return speedstep_get_frequency(speedstep_processor);
}
@@ -335,7 +366,7 @@ static int speedstep_resume(struct cpufreq_policy *policy)
return result;
}
-static struct freq_attr* speedstep_attr[] = {
+static struct freq_attr *speedstep_attr[] = {
&cpufreq_freq_attr_scaling_available_freqs,
NULL,
};
@@ -364,21 +395,23 @@ static int __init speedstep_init(void)
speedstep_processor = speedstep_detect_processor();
switch (speedstep_processor) {
- case SPEEDSTEP_PROCESSOR_PIII_T:
- case SPEEDSTEP_PROCESSOR_PIII_C:
- case SPEEDSTEP_PROCESSOR_PIII_C_EARLY:
+ case SPEEDSTEP_CPU_PIII_T:
+ case SPEEDSTEP_CPU_PIII_C:
+ case SPEEDSTEP_CPU_PIII_C_EARLY:
break;
default:
speedstep_processor = 0;
}
if (!speedstep_processor) {
- dprintk ("No supported Intel CPU detected.\n");
+ dprintk("No supported Intel CPU detected.\n");
return -ENODEV;
}
- dprintk("signature:0x%.8lx, command:0x%.8lx, event:0x%.8lx, perf_level:0x%.8lx.\n",
- ist_info.signature, ist_info.command, ist_info.event, ist_info.perf_level);
+ dprintk("signature:0x%.8lx, command:0x%.8lx, "
+ "event:0x%.8lx, perf_level:0x%.8lx.\n",
+ ist_info.signature, ist_info.command,
+ ist_info.event, ist_info.perf_level);
/* Error if no IST-SMI BIOS or no PARM
sig= 'ISGE' aka 'Intel Speedstep Gate E' */
@@ -416,17 +449,20 @@ static void __exit speedstep_exit(void)
cpufreq_unregister_driver(&speedstep_driver);
}
-module_param(smi_port, int, 0444);
-module_param(smi_cmd, int, 0444);
-module_param(smi_sig, uint, 0444);
+module_param(smi_port, int, 0444);
+module_param(smi_cmd, int, 0444);
+module_param(smi_sig, uint, 0444);
-MODULE_PARM_DESC(smi_port, "Override the BIOS-given IST port with this value -- Intel's default setting is 0xb2");
-MODULE_PARM_DESC(smi_cmd, "Override the BIOS-given IST command with this value -- Intel's default setting is 0x82");
-MODULE_PARM_DESC(smi_sig, "Set to 1 to fake the IST signature when using the SMI interface.");
+MODULE_PARM_DESC(smi_port, "Override the BIOS-given IST port with this value "
+ "-- Intel's default setting is 0xb2");
+MODULE_PARM_DESC(smi_cmd, "Override the BIOS-given IST command with this value "
+ "-- Intel's default setting is 0x82");
+MODULE_PARM_DESC(smi_sig, "Set to 1 to fake the IST signature when using the "
+ "SMI interface.");
-MODULE_AUTHOR ("Hiroshi Miura");
-MODULE_DESCRIPTION ("Speedstep driver for IST applet SMI interface.");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Hiroshi Miura");
+MODULE_DESCRIPTION("Speedstep driver for IST applet SMI interface.");
+MODULE_LICENSE("GPL");
module_init(speedstep_init);
module_exit(speedstep_exit);
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c
index ffd0f5ed071a..593171e967ef 100644
--- a/arch/x86/kernel/cpu/cyrix.c
+++ b/arch/x86/kernel/cpu/cyrix.c
@@ -61,23 +61,23 @@ static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
*/
static unsigned char Cx86_dir0_msb __cpuinitdata = 0;
-static char Cx86_model[][9] __cpuinitdata = {
+static const char __cpuinitconst Cx86_model[][9] = {
"Cx486", "Cx486", "5x86 ", "6x86", "MediaGX ", "6x86MX ",
"M II ", "Unknown"
};
-static char Cx486_name[][5] __cpuinitdata = {
+static const char __cpuinitconst Cx486_name[][5] = {
"SLC", "DLC", "SLC2", "DLC2", "SRx", "DRx",
"SRx2", "DRx2"
};
-static char Cx486S_name[][4] __cpuinitdata = {
+static const char __cpuinitconst Cx486S_name[][4] = {
"S", "S2", "Se", "S2e"
};
-static char Cx486D_name[][4] __cpuinitdata = {
+static const char __cpuinitconst Cx486D_name[][4] = {
"DX", "DX2", "?", "?", "?", "DX4"
};
static char Cx86_cb[] __cpuinitdata = "?.5x Core/Bus Clock";
-static char cyrix_model_mult1[] __cpuinitdata = "12??43";
-static char cyrix_model_mult2[] __cpuinitdata = "12233445";
+static const char __cpuinitconst cyrix_model_mult1[] = "12??43";
+static const char __cpuinitconst cyrix_model_mult2[] = "12233445";
/*
* Reset the slow-loop (SLOP) bit on the 686(L) which is set by some old
@@ -435,7 +435,7 @@ static void __cpuinit cyrix_identify(struct cpuinfo_x86 *c)
}
}
-static struct cpu_dev cyrix_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst cyrix_cpu_dev = {
.c_vendor = "Cyrix",
.c_ident = { "CyrixInstead" },
.c_early_init = early_init_cyrix,
@@ -446,7 +446,7 @@ static struct cpu_dev cyrix_cpu_dev __cpuinitdata = {
cpu_dev_register(cyrix_cpu_dev);
-static struct cpu_dev nsc_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst nsc_cpu_dev = {
.c_vendor = "NSC",
.c_ident = { "Geode by NSC" },
.c_init = init_nsc,
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index c1c04bf0df77..7437fa133c02 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -55,6 +55,11 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
c->x86_cache_alignment = 128;
#endif
+ /* CPUID workaround for 0F33/0F34 CPU */
+ if (c->x86 == 0xF && c->x86_model == 0x3
+ && (c->x86_mask == 0x3 || c->x86_mask == 0x4))
+ c->x86_phys_bits = 36;
+
/*
* c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate
* with P/T states and does not stop in deep C-states.
@@ -416,7 +421,7 @@ static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 *c, unsigned i
}
#endif
-static struct cpu_dev intel_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst intel_cpu_dev = {
.c_vendor = "Intel",
.c_ident = { "GenuineIntel" },
#ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 7293508d8f5c..483eda96e102 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -32,7 +32,7 @@ struct _cache_table
};
/* all the cache descriptor types we care about (no TLB or trace cache entries) */
-static struct _cache_table cache_table[] __cpuinitdata =
+static const struct _cache_table __cpuinitconst cache_table[] =
{
{ 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
{ 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */
@@ -159,7 +159,7 @@ struct _cpuid4_info_regs {
unsigned long can_disable;
};
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && defined(CONFIG_SYSFS)
static struct pci_device_id k8_nb_id[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1203) },
@@ -206,15 +206,15 @@ union l3_cache {
unsigned val;
};
-static unsigned short assocs[] __cpuinitdata = {
+static const unsigned short __cpuinitconst assocs[] = {
[1] = 1, [2] = 2, [4] = 4, [6] = 8,
[8] = 16, [0xa] = 32, [0xb] = 48,
[0xc] = 64,
[0xf] = 0xffff // ??
};
-static unsigned char levels[] __cpuinitdata = { 1, 1, 2, 3 };
-static unsigned char types[] __cpuinitdata = { 1, 2, 3, 3 };
+static const unsigned char __cpuinitconst levels[] = { 1, 1, 2, 3 };
+static const unsigned char __cpuinitconst types[] = { 1, 2, 3, 3 };
static void __cpuinit
amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
@@ -324,15 +324,6 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
return 0;
}
-static int
-__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
-{
- struct _cpuid4_info_regs *leaf_regs =
- (struct _cpuid4_info_regs *)this_leaf;
-
- return cpuid4_cache_lookup_regs(index, leaf_regs);
-}
-
static int __cpuinit find_num_cache_leaves(void)
{
unsigned int eax, ebx, ecx, edx;
@@ -508,6 +499,8 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
return l2;
}
+#ifdef CONFIG_SYSFS
+
/* pointer to _cpuid4_info array (for each cache leaf) */
static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info);
#define CPUID4_INFO_IDX(x, y) (&((per_cpu(cpuid4_info, x))[y]))
@@ -571,6 +564,15 @@ static void __cpuinit free_cache_attributes(unsigned int cpu)
per_cpu(cpuid4_info, cpu) = NULL;
}
+static int
+__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
+{
+ struct _cpuid4_info_regs *leaf_regs =
+ (struct _cpuid4_info_regs *)this_leaf;
+
+ return cpuid4_cache_lookup_regs(index, leaf_regs);
+}
+
static void __cpuinit get_cpu_leaves(void *_retval)
{
int j, *retval = _retval, cpu = smp_processor_id();
@@ -612,8 +614,6 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu)
return retval;
}
-#ifdef CONFIG_SYSFS
-
#include <linux/kobject.h>
#include <linux/sysfs.h>
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
index ca14604611ec..863f89568b1a 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_64.c
@@ -990,7 +990,7 @@ static struct sysdev_attribute *mce_attributes[] = {
NULL
};
-static cpumask_t mce_device_initialized = CPU_MASK_NONE;
+static cpumask_var_t mce_device_initialized;
/* Per cpu sysdev init. All of the cpus still share the same ctl bank */
static __cpuinit int mce_create_device(unsigned int cpu)
@@ -1021,7 +1021,7 @@ static __cpuinit int mce_create_device(unsigned int cpu)
if (err)
goto error2;
}
- cpu_set(cpu, mce_device_initialized);
+ cpumask_set_cpu(cpu, mce_device_initialized);
return 0;
error2:
@@ -1043,7 +1043,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu)
{
int i;
- if (!cpu_isset(cpu, mce_device_initialized))
+ if (!cpumask_test_cpu(cpu, mce_device_initialized))
return;
for (i = 0; mce_attributes[i]; i++)
@@ -1053,7 +1053,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu)
sysdev_remove_file(&per_cpu(device_mce, cpu),
&bank_attrs[i]);
sysdev_unregister(&per_cpu(device_mce,cpu));
- cpu_clear(cpu, mce_device_initialized);
+ cpumask_clear_cpu(cpu, mce_device_initialized);
}
/* Make sure there are no machine checks on offlined CPUs. */
@@ -1162,6 +1162,8 @@ static __init int mce_init_device(void)
if (!mce_available(&boot_cpu_data))
return -EIO;
+ alloc_cpumask_var(&mce_device_initialized, GFP_KERNEL);
+
err = mce_init_banks();
if (err)
return err;
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
index c5a32f92d07e..56dde9c4bc96 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
@@ -92,7 +92,8 @@ struct thresh_restart {
};
/* must be called with correct cpu affinity */
-static long threshold_restart_bank(void *_tr)
+/* Called via smp_call_function_single() */
+static void threshold_restart_bank(void *_tr)
{
struct thresh_restart *tr = _tr;
u32 mci_misc_hi, mci_misc_lo;
@@ -119,7 +120,6 @@ static long threshold_restart_bank(void *_tr)
mci_misc_hi |= MASK_COUNT_EN_HI;
wrmsr(tr->b->address, mci_misc_lo, mci_misc_hi);
- return 0;
}
/* cpu init entry point, called from mce.c with preempt off */
@@ -279,7 +279,7 @@ static ssize_t store_interrupt_enable(struct threshold_block *b,
tr.b = b;
tr.reset = 0;
tr.old_limit = 0;
- work_on_cpu(b->cpu, threshold_restart_bank, &tr);
+ smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);
return end - buf;
}
@@ -301,23 +301,32 @@ static ssize_t store_threshold_limit(struct threshold_block *b,
tr.b = b;
tr.reset = 0;
- work_on_cpu(b->cpu, threshold_restart_bank, &tr);
+ smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);
return end - buf;
}
-static long local_error_count(void *_b)
+struct threshold_block_cross_cpu {
+ struct threshold_block *tb;
+ long retval;
+};
+
+static void local_error_count_handler(void *_tbcc)
{
- struct threshold_block *b = _b;
+ struct threshold_block_cross_cpu *tbcc = _tbcc;
+ struct threshold_block *b = tbcc->tb;
u32 low, high;
rdmsr(b->address, low, high);
- return (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit);
+ tbcc->retval = (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit);
}
static ssize_t show_error_count(struct threshold_block *b, char *buf)
{
- return sprintf(buf, "%lx\n", work_on_cpu(b->cpu, local_error_count, b));
+ struct threshold_block_cross_cpu tbcc = { .tb = b, };
+
+ smp_call_function_single(b->cpu, local_error_count_handler, &tbcc, 1);
+ return sprintf(buf, "%lx\n", tbcc.retval);
}
static ssize_t store_error_count(struct threshold_block *b,
@@ -325,7 +334,7 @@ static ssize_t store_error_count(struct threshold_block *b,
{
struct thresh_restart tr = { .b = b, .reset = 1, .old_limit = 0 };
- work_on_cpu(b->cpu, threshold_restart_bank, &tr);
+ smp_call_function_single(b->cpu, threshold_restart_bank, &tr, 1);
return 1;
}
@@ -394,7 +403,7 @@ static __cpuinit int allocate_threshold_blocks(unsigned int cpu,
if ((bank >= NR_BANKS) || (block >= NR_BLOCKS))
return 0;
- if (rdmsr_safe(address, &low, &high))
+ if (rdmsr_safe_on_cpu(cpu, address, &low, &high))
return 0;
if (!(high & MASK_VALID_HI)) {
@@ -458,12 +467,11 @@ out_free:
return err;
}
-static __cpuinit long local_allocate_threshold_blocks(void *_bank)
+static __cpuinit long
+local_allocate_threshold_blocks(int cpu, unsigned int bank)
{
- unsigned int *bank = _bank;
-
- return allocate_threshold_blocks(smp_processor_id(), *bank, 0,
- MSR_IA32_MC0_MISC + *bank * 4);
+ return allocate_threshold_blocks(cpu, bank, 0,
+ MSR_IA32_MC0_MISC + bank * 4);
}
/* symlinks sibling shared banks to first core. first core owns dir/files. */
@@ -477,7 +485,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
#ifdef CONFIG_SMP
if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) { /* symlink */
- i = cpumask_first(&per_cpu(cpu_core_map, cpu));
+ i = cpumask_first(cpu_core_mask(cpu));
/* first core not up yet */
if (cpu_data(i).cpu_core_id)
@@ -497,7 +505,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
if (err)
goto out;
- cpumask_copy(b->cpus, &per_cpu(cpu_core_map, cpu));
+ cpumask_copy(b->cpus, cpu_core_mask(cpu));
per_cpu(threshold_banks, cpu)[bank] = b;
goto out;
}
@@ -521,12 +529,12 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
#ifndef CONFIG_SMP
cpumask_setall(b->cpus);
#else
- cpumask_copy(b->cpus, &per_cpu(cpu_core_map, cpu));
+ cpumask_copy(b->cpus, cpu_core_mask(cpu));
#endif
per_cpu(threshold_banks, cpu)[bank] = b;
- err = work_on_cpu(cpu, local_allocate_threshold_blocks, &bank);
+ err = local_allocate_threshold_blocks(cpu, bank);
if (err)
goto out_free;
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
index aaa7d9730938..d6b72df89d69 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_intel_64.c
@@ -249,7 +249,7 @@ void cmci_rediscover(int dying)
for_each_online_cpu (cpu) {
if (cpu == dying)
continue;
- if (set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)))
+ if (set_cpus_allowed_ptr(current, cpumask_of(cpu)))
continue;
/* Recheck banks in case CPUs don't all have the same */
if (cmci_supported(&banks))
@@ -270,7 +270,7 @@ void cmci_reenable(void)
cmci_discover(banks, 0);
}
-static __cpuinit void intel_init_cmci(void)
+static void intel_init_cmci(void)
{
int banks;
diff --git a/arch/x86/kernel/cpu/mtrr/Makefile b/arch/x86/kernel/cpu/mtrr/Makefile
index 191fc0533649..f4361b56f8e9 100644
--- a/arch/x86/kernel/cpu/mtrr/Makefile
+++ b/arch/x86/kernel/cpu/mtrr/Makefile
@@ -1,3 +1,3 @@
-obj-y := main.o if.o generic.o state.o
+obj-y := main.o if.o generic.o state.o cleanup.o
obj-$(CONFIG_X86_32) += amd.o cyrix.o centaur.o
diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c
new file mode 100644
index 000000000000..ce0fe4b5c04f
--- /dev/null
+++ b/arch/x86/kernel/cpu/mtrr/cleanup.c
@@ -0,0 +1,1101 @@
+/* MTRR (Memory Type Range Register) cleanup
+
+ Copyright (C) 2009 Yinghai Lu
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/smp.h>
+#include <linux/cpu.h>
+#include <linux/mutex.h>
+#include <linux/sort.h>
+
+#include <asm/e820.h>
+#include <asm/mtrr.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
+#include <asm/kvm_para.h>
+#include "mtrr.h"
+
+/* should be related to MTRR_VAR_RANGES nums */
+#define RANGE_NUM 256
+
+struct res_range {
+ unsigned long start;
+ unsigned long end;
+};
+
+static int __init
+add_range(struct res_range *range, int nr_range, unsigned long start,
+ unsigned long end)
+{
+ /* out of slots */
+ if (nr_range >= RANGE_NUM)
+ return nr_range;
+
+ range[nr_range].start = start;
+ range[nr_range].end = end;
+
+ nr_range++;
+
+ return nr_range;
+}
+
+static int __init
+add_range_with_merge(struct res_range *range, int nr_range, unsigned long start,
+ unsigned long end)
+{
+ int i;
+
+ /* try to merge it with old one */
+ for (i = 0; i < nr_range; i++) {
+ unsigned long final_start, final_end;
+ unsigned long common_start, common_end;
+
+ if (!range[i].end)
+ continue;
+
+ common_start = max(range[i].start, start);
+ common_end = min(range[i].end, end);
+ if (common_start > common_end + 1)
+ continue;
+
+ final_start = min(range[i].start, start);
+ final_end = max(range[i].end, end);
+
+ range[i].start = final_start;
+ range[i].end = final_end;
+ return nr_range;
+ }
+
+ /* need to add that */
+ return add_range(range, nr_range, start, end);
+}
+
+static void __init
+subtract_range(struct res_range *range, unsigned long start, unsigned long end)
+{
+ int i, j;
+
+ for (j = 0; j < RANGE_NUM; j++) {
+ if (!range[j].end)
+ continue;
+
+ if (start <= range[j].start && end >= range[j].end) {
+ range[j].start = 0;
+ range[j].end = 0;
+ continue;
+ }
+
+ if (start <= range[j].start && end < range[j].end &&
+ range[j].start < end + 1) {
+ range[j].start = end + 1;
+ continue;
+ }
+
+
+ if (start > range[j].start && end >= range[j].end &&
+ range[j].end > start - 1) {
+ range[j].end = start - 1;
+ continue;
+ }
+
+ if (start > range[j].start && end < range[j].end) {
+ /* find the new spare */
+ for (i = 0; i < RANGE_NUM; i++) {
+ if (range[i].end == 0)
+ break;
+ }
+ if (i < RANGE_NUM) {
+ range[i].end = range[j].end;
+ range[i].start = end + 1;
+ } else {
+ printk(KERN_ERR "run of slot in ranges\n");
+ }
+ range[j].end = start - 1;
+ continue;
+ }
+ }
+}
+
+static int __init cmp_range(const void *x1, const void *x2)
+{
+ const struct res_range *r1 = x1;
+ const struct res_range *r2 = x2;
+ long start1, start2;
+
+ start1 = r1->start;
+ start2 = r2->start;
+
+ return start1 - start2;
+}
+
+struct var_mtrr_range_state {
+ unsigned long base_pfn;
+ unsigned long size_pfn;
+ mtrr_type type;
+};
+
+static struct var_mtrr_range_state __initdata range_state[RANGE_NUM];
+static int __initdata debug_print;
+
+static int __init
+x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
+ unsigned long extra_remove_base,
+ unsigned long extra_remove_size)
+{
+ unsigned long base, size;
+ mtrr_type type;
+ int i;
+
+ for (i = 0; i < num_var_ranges; i++) {
+ type = range_state[i].type;
+ if (type != MTRR_TYPE_WRBACK)
+ continue;
+ base = range_state[i].base_pfn;
+ size = range_state[i].size_pfn;
+ nr_range = add_range_with_merge(range, nr_range, base,
+ base + size - 1);
+ }
+ if (debug_print) {
+ printk(KERN_DEBUG "After WB checking\n");
+ for (i = 0; i < nr_range; i++)
+ printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
+ range[i].start, range[i].end + 1);
+ }
+
+ /* take out UC ranges */
+ for (i = 0; i < num_var_ranges; i++) {
+ type = range_state[i].type;
+ if (type != MTRR_TYPE_UNCACHABLE &&
+ type != MTRR_TYPE_WRPROT)
+ continue;
+ size = range_state[i].size_pfn;
+ if (!size)
+ continue;
+ base = range_state[i].base_pfn;
+ if (base < (1<<(20-PAGE_SHIFT)) && mtrr_state.have_fixed &&
+ (mtrr_state.enabled & 1)) {
+ /* Var MTRR contains UC entry below 1M? Skip it: */
+ printk(KERN_WARNING "WARNING: BIOS bug: VAR MTRR %d "
+ "contains strange UC entry under 1M, check "
+ "with your system vendor!\n", i);
+ if (base + size <= (1<<(20-PAGE_SHIFT)))
+ continue;
+ size -= (1<<(20-PAGE_SHIFT)) - base;
+ base = 1<<(20-PAGE_SHIFT);
+ }
+ subtract_range(range, base, base + size - 1);
+ }
+ if (extra_remove_size)
+ subtract_range(range, extra_remove_base,
+ extra_remove_base + extra_remove_size - 1);
+
+ /* get new range num */
+ nr_range = 0;
+ for (i = 0; i < RANGE_NUM; i++) {
+ if (!range[i].end)
+ continue;
+ nr_range++;
+ }
+ if (debug_print) {
+ printk(KERN_DEBUG "After UC checking\n");
+ for (i = 0; i < nr_range; i++)
+ printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
+ range[i].start, range[i].end + 1);
+ }
+
+ /* sort the ranges */
+ sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
+ if (debug_print) {
+ printk(KERN_DEBUG "After sorting\n");
+ for (i = 0; i < nr_range; i++)
+ printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
+ range[i].start, range[i].end + 1);
+ }
+
+ /* clear those is not used */
+ for (i = nr_range; i < RANGE_NUM; i++)
+ memset(&range[i], 0, sizeof(range[i]));
+
+ return nr_range;
+}
+
+static struct res_range __initdata range[RANGE_NUM];
+static int __initdata nr_range;
+
+#ifdef CONFIG_MTRR_SANITIZER
+
+static unsigned long __init sum_ranges(struct res_range *range, int nr_range)
+{
+ unsigned long sum;
+ int i;
+
+ sum = 0;
+ for (i = 0; i < nr_range; i++)
+ sum += range[i].end + 1 - range[i].start;
+
+ return sum;
+}
+
+static int enable_mtrr_cleanup __initdata =
+ CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT;
+
+static int __init disable_mtrr_cleanup_setup(char *str)
+{
+ enable_mtrr_cleanup = 0;
+ return 0;
+}
+early_param("disable_mtrr_cleanup", disable_mtrr_cleanup_setup);
+
+static int __init enable_mtrr_cleanup_setup(char *str)
+{
+ enable_mtrr_cleanup = 1;
+ return 0;
+}
+early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup);
+
+static int __init mtrr_cleanup_debug_setup(char *str)
+{
+ debug_print = 1;
+ return 0;
+}
+early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup);
+
+struct var_mtrr_state {
+ unsigned long range_startk;
+ unsigned long range_sizek;
+ unsigned long chunk_sizek;
+ unsigned long gran_sizek;
+ unsigned int reg;
+};
+
+static void __init
+set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
+ unsigned char type, unsigned int address_bits)
+{
+ u32 base_lo, base_hi, mask_lo, mask_hi;
+ u64 base, mask;
+
+ if (!sizek) {
+ fill_mtrr_var_range(reg, 0, 0, 0, 0);
+ return;
+ }
+
+ mask = (1ULL << address_bits) - 1;
+ mask &= ~((((u64)sizek) << 10) - 1);
+
+ base = ((u64)basek) << 10;
+
+ base |= type;
+ mask |= 0x800;
+
+ base_lo = base & ((1ULL<<32) - 1);
+ base_hi = base >> 32;
+
+ mask_lo = mask & ((1ULL<<32) - 1);
+ mask_hi = mask >> 32;
+
+ fill_mtrr_var_range(reg, base_lo, base_hi, mask_lo, mask_hi);
+}
+
+static void __init
+save_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
+ unsigned char type)
+{
+ range_state[reg].base_pfn = basek >> (PAGE_SHIFT - 10);
+ range_state[reg].size_pfn = sizek >> (PAGE_SHIFT - 10);
+ range_state[reg].type = type;
+}
+
+static void __init
+set_var_mtrr_all(unsigned int address_bits)
+{
+ unsigned long basek, sizek;
+ unsigned char type;
+ unsigned int reg;
+
+ for (reg = 0; reg < num_var_ranges; reg++) {
+ basek = range_state[reg].base_pfn << (PAGE_SHIFT - 10);
+ sizek = range_state[reg].size_pfn << (PAGE_SHIFT - 10);
+ type = range_state[reg].type;
+
+ set_var_mtrr(reg, basek, sizek, type, address_bits);
+ }
+}
+
+static unsigned long to_size_factor(unsigned long sizek, char *factorp)
+{
+ char factor;
+ unsigned long base = sizek;
+
+ if (base & ((1<<10) - 1)) {
+ /* not MB alignment */
+ factor = 'K';
+ } else if (base & ((1<<20) - 1)) {
+ factor = 'M';
+ base >>= 10;
+ } else {
+ factor = 'G';
+ base >>= 20;
+ }
+
+ *factorp = factor;
+
+ return base;
+}
+
+static unsigned int __init
+range_to_mtrr(unsigned int reg, unsigned long range_startk,
+ unsigned long range_sizek, unsigned char type)
+{
+ if (!range_sizek || (reg >= num_var_ranges))
+ return reg;
+
+ while (range_sizek) {
+ unsigned long max_align, align;
+ unsigned long sizek;
+
+ /* Compute the maximum size I can make a range */
+ if (range_startk)
+ max_align = ffs(range_startk) - 1;
+ else
+ max_align = 32;
+ align = fls(range_sizek) - 1;
+ if (align > max_align)
+ align = max_align;
+
+ sizek = 1 << align;
+ if (debug_print) {
+ char start_factor = 'K', size_factor = 'K';
+ unsigned long start_base, size_base;
+
+ start_base = to_size_factor(range_startk,
+ &start_factor),
+ size_base = to_size_factor(sizek, &size_factor),
+
+ printk(KERN_DEBUG "Setting variable MTRR %d, "
+ "base: %ld%cB, range: %ld%cB, type %s\n",
+ reg, start_base, start_factor,
+ size_base, size_factor,
+ (type == MTRR_TYPE_UNCACHABLE) ? "UC" :
+ ((type == MTRR_TYPE_WRBACK) ? "WB" : "Other")
+ );
+ }
+ save_var_mtrr(reg++, range_startk, sizek, type);
+ range_startk += sizek;
+ range_sizek -= sizek;
+ if (reg >= num_var_ranges)
+ break;
+ }
+ return reg;
+}
+
+static unsigned __init
+range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
+ unsigned long sizek)
+{
+ unsigned long hole_basek, hole_sizek;
+ unsigned long second_basek, second_sizek;
+ unsigned long range0_basek, range0_sizek;
+ unsigned long range_basek, range_sizek;
+ unsigned long chunk_sizek;
+ unsigned long gran_sizek;
+
+ hole_basek = 0;
+ hole_sizek = 0;
+ second_basek = 0;
+ second_sizek = 0;
+ chunk_sizek = state->chunk_sizek;
+ gran_sizek = state->gran_sizek;
+
+ /* align with gran size, prevent small block used up MTRRs */
+ range_basek = ALIGN(state->range_startk, gran_sizek);
+ if ((range_basek > basek) && basek)
+ return second_sizek;
+ state->range_sizek -= (range_basek - state->range_startk);
+ range_sizek = ALIGN(state->range_sizek, gran_sizek);
+
+ while (range_sizek > state->range_sizek) {
+ range_sizek -= gran_sizek;
+ if (!range_sizek)
+ return 0;
+ }
+ state->range_sizek = range_sizek;
+
+ /* try to append some small hole */
+ range0_basek = state->range_startk;
+ range0_sizek = ALIGN(state->range_sizek, chunk_sizek);
+
+ /* no increase */
+ if (range0_sizek == state->range_sizek) {
+ if (debug_print)
+ printk(KERN_DEBUG "rangeX: %016lx - %016lx\n",
+ range0_basek<<10,
+ (range0_basek + state->range_sizek)<<10);
+ state->reg = range_to_mtrr(state->reg, range0_basek,
+ state->range_sizek, MTRR_TYPE_WRBACK);
+ return 0;
+ }
+
+ /* only cut back, when it is not the last */
+ if (sizek) {
+ while (range0_basek + range0_sizek > (basek + sizek)) {
+ if (range0_sizek >= chunk_sizek)
+ range0_sizek -= chunk_sizek;
+ else
+ range0_sizek = 0;
+
+ if (!range0_sizek)
+ break;
+ }
+ }
+
+second_try:
+ range_basek = range0_basek + range0_sizek;
+
+ /* one hole in the middle */
+ if (range_basek > basek && range_basek <= (basek + sizek))
+ second_sizek = range_basek - basek;
+
+ if (range0_sizek > state->range_sizek) {
+
+ /* one hole in middle or at end */
+ hole_sizek = range0_sizek - state->range_sizek - second_sizek;
+
+ /* hole size should be less than half of range0 size */
+ if (hole_sizek >= (range0_sizek >> 1) &&
+ range0_sizek >= chunk_sizek) {
+ range0_sizek -= chunk_sizek;
+ second_sizek = 0;
+ hole_sizek = 0;
+
+ goto second_try;
+ }
+ }
+
+ if (range0_sizek) {
+ if (debug_print)
+ printk(KERN_DEBUG "range0: %016lx - %016lx\n",
+ range0_basek<<10,
+ (range0_basek + range0_sizek)<<10);
+ state->reg = range_to_mtrr(state->reg, range0_basek,
+ range0_sizek, MTRR_TYPE_WRBACK);
+ }
+
+ if (range0_sizek < state->range_sizek) {
+ /* need to handle left over */
+ range_sizek = state->range_sizek - range0_sizek;
+
+ if (debug_print)
+ printk(KERN_DEBUG "range: %016lx - %016lx\n",
+ range_basek<<10,
+ (range_basek + range_sizek)<<10);
+ state->reg = range_to_mtrr(state->reg, range_basek,
+ range_sizek, MTRR_TYPE_WRBACK);
+ }
+
+ if (hole_sizek) {
+ hole_basek = range_basek - hole_sizek - second_sizek;
+ if (debug_print)
+ printk(KERN_DEBUG "hole: %016lx - %016lx\n",
+ hole_basek<<10,
+ (hole_basek + hole_sizek)<<10);
+ state->reg = range_to_mtrr(state->reg, hole_basek,
+ hole_sizek, MTRR_TYPE_UNCACHABLE);
+ }
+
+ return second_sizek;
+}
+
+static void __init
+set_var_mtrr_range(struct var_mtrr_state *state, unsigned long base_pfn,
+ unsigned long size_pfn)
+{
+ unsigned long basek, sizek;
+ unsigned long second_sizek = 0;
+
+ if (state->reg >= num_var_ranges)
+ return;
+
+ basek = base_pfn << (PAGE_SHIFT - 10);
+ sizek = size_pfn << (PAGE_SHIFT - 10);
+
+ /* See if I can merge with the last range */
+ if ((basek <= 1024) ||
+ (state->range_startk + state->range_sizek == basek)) {
+ unsigned long endk = basek + sizek;
+ state->range_sizek = endk - state->range_startk;
+ return;
+ }
+ /* Write the range mtrrs */
+ if (state->range_sizek != 0)
+ second_sizek = range_to_mtrr_with_hole(state, basek, sizek);
+
+ /* Allocate an msr */
+ state->range_startk = basek + second_sizek;
+ state->range_sizek = sizek - second_sizek;
+}
+
+/* mininum size of mtrr block that can take hole */
+static u64 mtrr_chunk_size __initdata = (256ULL<<20);
+
+static int __init parse_mtrr_chunk_size_opt(char *p)
+{
+ if (!p)
+ return -EINVAL;
+ mtrr_chunk_size = memparse(p, &p);
+ return 0;
+}
+early_param("mtrr_chunk_size", parse_mtrr_chunk_size_opt);
+
+/* granity of mtrr of block */
+static u64 mtrr_gran_size __initdata;
+
+static int __init parse_mtrr_gran_size_opt(char *p)
+{
+ if (!p)
+ return -EINVAL;
+ mtrr_gran_size = memparse(p, &p);
+ return 0;
+}
+early_param("mtrr_gran_size", parse_mtrr_gran_size_opt);
+
+static int nr_mtrr_spare_reg __initdata =
+ CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT;
+
+static int __init parse_mtrr_spare_reg(char *arg)
+{
+ if (arg)
+ nr_mtrr_spare_reg = simple_strtoul(arg, NULL, 0);
+ return 0;
+}
+
+early_param("mtrr_spare_reg_nr", parse_mtrr_spare_reg);
+
+static int __init
+x86_setup_var_mtrrs(struct res_range *range, int nr_range,
+ u64 chunk_size, u64 gran_size)
+{
+ struct var_mtrr_state var_state;
+ int i;
+ int num_reg;
+
+ var_state.range_startk = 0;
+ var_state.range_sizek = 0;
+ var_state.reg = 0;
+ var_state.chunk_sizek = chunk_size >> 10;
+ var_state.gran_sizek = gran_size >> 10;
+
+ memset(range_state, 0, sizeof(range_state));
+
+ /* Write the range etc */
+ for (i = 0; i < nr_range; i++)
+ set_var_mtrr_range(&var_state, range[i].start,
+ range[i].end - range[i].start + 1);
+
+ /* Write the last range */
+ if (var_state.range_sizek != 0)
+ range_to_mtrr_with_hole(&var_state, 0, 0);
+
+ num_reg = var_state.reg;
+ /* Clear out the extra MTRR's */
+ while (var_state.reg < num_var_ranges) {
+ save_var_mtrr(var_state.reg, 0, 0, 0);
+ var_state.reg++;
+ }
+
+ return num_reg;
+}
+
+struct mtrr_cleanup_result {
+ unsigned long gran_sizek;
+ unsigned long chunk_sizek;
+ unsigned long lose_cover_sizek;
+ unsigned int num_reg;
+ int bad;
+};
+
+/*
+ * gran_size: 64K, 128K, 256K, 512K, 1M, 2M, ..., 2G
+ * chunk size: gran_size, ..., 2G
+ * so we need (1+16)*8
+ */
+#define NUM_RESULT 136
+#define PSHIFT (PAGE_SHIFT - 10)
+
+static struct mtrr_cleanup_result __initdata result[NUM_RESULT];
+static unsigned long __initdata min_loss_pfn[RANGE_NUM];
+
+static void __init print_out_mtrr_range_state(void)
+{
+ int i;
+ char start_factor = 'K', size_factor = 'K';
+ unsigned long start_base, size_base;
+ mtrr_type type;
+
+ for (i = 0; i < num_var_ranges; i++) {
+
+ size_base = range_state[i].size_pfn << (PAGE_SHIFT - 10);
+ if (!size_base)
+ continue;
+
+ size_base = to_size_factor(size_base, &size_factor),
+ start_base = range_state[i].base_pfn << (PAGE_SHIFT - 10);
+ start_base = to_size_factor(start_base, &start_factor),
+ type = range_state[i].type;
+
+ printk(KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n",
+ i, start_base, start_factor,
+ size_base, size_factor,
+ (type == MTRR_TYPE_UNCACHABLE) ? "UC" :
+ ((type == MTRR_TYPE_WRPROT) ? "WP" :
+ ((type == MTRR_TYPE_WRBACK) ? "WB" : "Other"))
+ );
+ }
+}
+
+static int __init mtrr_need_cleanup(void)
+{
+ int i;
+ mtrr_type type;
+ unsigned long size;
+ /* extra one for all 0 */
+ int num[MTRR_NUM_TYPES + 1];
+
+ /* check entries number */
+ memset(num, 0, sizeof(num));
+ for (i = 0; i < num_var_ranges; i++) {
+ type = range_state[i].type;
+ size = range_state[i].size_pfn;
+ if (type >= MTRR_NUM_TYPES)
+ continue;
+ if (!size)
+ type = MTRR_NUM_TYPES;
+ if (type == MTRR_TYPE_WRPROT)
+ type = MTRR_TYPE_UNCACHABLE;
+ num[type]++;
+ }
+
+ /* check if we got UC entries */
+ if (!num[MTRR_TYPE_UNCACHABLE])
+ return 0;
+
+ /* check if we only had WB and UC */
+ if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] !=
+ num_var_ranges - num[MTRR_NUM_TYPES])
+ return 0;
+
+ return 1;
+}
+
+static unsigned long __initdata range_sums;
+static void __init mtrr_calc_range_state(u64 chunk_size, u64 gran_size,
+ unsigned long extra_remove_base,
+ unsigned long extra_remove_size,
+ int i)
+{
+ int num_reg;
+ static struct res_range range_new[RANGE_NUM];
+ static int nr_range_new;
+ unsigned long range_sums_new;
+
+ /* convert ranges to var ranges state */
+ num_reg = x86_setup_var_mtrrs(range, nr_range,
+ chunk_size, gran_size);
+
+ /* we got new setting in range_state, check it */
+ memset(range_new, 0, sizeof(range_new));
+ nr_range_new = x86_get_mtrr_mem_range(range_new, 0,
+ extra_remove_base, extra_remove_size);
+ range_sums_new = sum_ranges(range_new, nr_range_new);
+
+ result[i].chunk_sizek = chunk_size >> 10;
+ result[i].gran_sizek = gran_size >> 10;
+ result[i].num_reg = num_reg;
+ if (range_sums < range_sums_new) {
+ result[i].lose_cover_sizek =
+ (range_sums_new - range_sums) << PSHIFT;
+ result[i].bad = 1;
+ } else
+ result[i].lose_cover_sizek =
+ (range_sums - range_sums_new) << PSHIFT;
+
+ /* double check it */
+ if (!result[i].bad && !result[i].lose_cover_sizek) {
+ if (nr_range_new != nr_range ||
+ memcmp(range, range_new, sizeof(range)))
+ result[i].bad = 1;
+ }
+
+ if (!result[i].bad && (range_sums - range_sums_new <
+ min_loss_pfn[num_reg])) {
+ min_loss_pfn[num_reg] =
+ range_sums - range_sums_new;
+ }
+}
+
+static void __init mtrr_print_out_one_result(int i)
+{
+ char gran_factor, chunk_factor, lose_factor;
+ unsigned long gran_base, chunk_base, lose_base;
+
+ gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
+ chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
+ lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
+ printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t",
+ result[i].bad ? "*BAD*" : " ",
+ gran_base, gran_factor, chunk_base, chunk_factor);
+ printk(KERN_CONT "num_reg: %d \tlose cover RAM: %s%ld%c\n",
+ result[i].num_reg, result[i].bad ? "-" : "",
+ lose_base, lose_factor);
+}
+
+static int __init mtrr_search_optimal_index(void)
+{
+ int i;
+ int num_reg_good;
+ int index_good;
+
+ if (nr_mtrr_spare_reg >= num_var_ranges)
+ nr_mtrr_spare_reg = num_var_ranges - 1;
+ num_reg_good = -1;
+ for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) {
+ if (!min_loss_pfn[i])
+ num_reg_good = i;
+ }
+
+ index_good = -1;
+ if (num_reg_good != -1) {
+ for (i = 0; i < NUM_RESULT; i++) {
+ if (!result[i].bad &&
+ result[i].num_reg == num_reg_good &&
+ !result[i].lose_cover_sizek) {
+ index_good = i;
+ break;
+ }
+ }
+ }
+
+ return index_good;
+}
+
+
+int __init mtrr_cleanup(unsigned address_bits)
+{
+ unsigned long extra_remove_base, extra_remove_size;
+ unsigned long base, size, def, dummy;
+ mtrr_type type;
+ u64 chunk_size, gran_size;
+ int index_good;
+ int i;
+
+ if (!is_cpu(INTEL) || enable_mtrr_cleanup < 1)
+ return 0;
+ rdmsr(MTRRdefType_MSR, def, dummy);
+ def &= 0xff;
+ if (def != MTRR_TYPE_UNCACHABLE)
+ return 0;
+
+ /* get it and store it aside */
+ memset(range_state, 0, sizeof(range_state));
+ for (i = 0; i < num_var_ranges; i++) {
+ mtrr_if->get(i, &base, &size, &type);
+ range_state[i].base_pfn = base;
+ range_state[i].size_pfn = size;
+ range_state[i].type = type;
+ }
+
+ /* check if we need handle it and can handle it */
+ if (!mtrr_need_cleanup())
+ return 0;
+
+ /* print original var MTRRs at first, for debugging: */
+ printk(KERN_DEBUG "original variable MTRRs\n");
+ print_out_mtrr_range_state();
+
+ memset(range, 0, sizeof(range));
+ extra_remove_size = 0;
+ extra_remove_base = 1 << (32 - PAGE_SHIFT);
+ if (mtrr_tom2)
+ extra_remove_size =
+ (mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base;
+ nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base,
+ extra_remove_size);
+ /*
+ * [0, 1M) should always be coverred by var mtrr with WB
+ * and fixed mtrrs should take effective before var mtrr for it
+ */
+ nr_range = add_range_with_merge(range, nr_range, 0,
+ (1ULL<<(20 - PAGE_SHIFT)) - 1);
+ /* sort the ranges */
+ sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
+
+ range_sums = sum_ranges(range, nr_range);
+ printk(KERN_INFO "total RAM coverred: %ldM\n",
+ range_sums >> (20 - PAGE_SHIFT));
+
+ if (mtrr_chunk_size && mtrr_gran_size) {
+ i = 0;
+ mtrr_calc_range_state(mtrr_chunk_size, mtrr_gran_size,
+ extra_remove_base, extra_remove_size, i);
+
+ mtrr_print_out_one_result(i);
+
+ if (!result[i].bad) {
+ set_var_mtrr_all(address_bits);
+ printk(KERN_DEBUG "New variable MTRRs\n");
+ print_out_mtrr_range_state();
+ return 1;
+ }
+ printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, "
+ "will find optimal one\n");
+ }
+
+ i = 0;
+ memset(min_loss_pfn, 0xff, sizeof(min_loss_pfn));
+ memset(result, 0, sizeof(result));
+ for (gran_size = (1ULL<<16); gran_size < (1ULL<<32); gran_size <<= 1) {
+
+ for (chunk_size = gran_size; chunk_size < (1ULL<<32);
+ chunk_size <<= 1) {
+
+ if (i >= NUM_RESULT)
+ continue;
+
+ mtrr_calc_range_state(chunk_size, gran_size,
+ extra_remove_base, extra_remove_size, i);
+ if (debug_print) {
+ mtrr_print_out_one_result(i);
+ printk(KERN_INFO "\n");
+ }
+
+ i++;
+ }
+ }
+
+ /* try to find the optimal index */
+ index_good = mtrr_search_optimal_index();
+
+ if (index_good != -1) {
+ printk(KERN_INFO "Found optimal setting for mtrr clean up\n");
+ i = index_good;
+ mtrr_print_out_one_result(i);
+
+ /* convert ranges to var ranges state */
+ chunk_size = result[i].chunk_sizek;
+ chunk_size <<= 10;
+ gran_size = result[i].gran_sizek;
+ gran_size <<= 10;
+ x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size);
+ set_var_mtrr_all(address_bits);
+ printk(KERN_DEBUG "New variable MTRRs\n");
+ print_out_mtrr_range_state();
+ return 1;
+ } else {
+ /* print out all */
+ for (i = 0; i < NUM_RESULT; i++)
+ mtrr_print_out_one_result(i);
+ }
+
+ printk(KERN_INFO "mtrr_cleanup: can not find optimal value\n");
+ printk(KERN_INFO "please specify mtrr_gran_size/mtrr_chunk_size\n");
+
+ return 0;
+}
+#else
+int __init mtrr_cleanup(unsigned address_bits)
+{
+ return 0;
+}
+#endif
+
+static int disable_mtrr_trim;
+
+static int __init disable_mtrr_trim_setup(char *str)
+{
+ disable_mtrr_trim = 1;
+ return 0;
+}
+early_param("disable_mtrr_trim", disable_mtrr_trim_setup);
+
+/*
+ * Newer AMD K8s and later CPUs have a special magic MSR way to force WB
+ * for memory >4GB. Check for that here.
+ * Note this won't check if the MTRRs < 4GB where the magic bit doesn't
+ * apply to are wrong, but so far we don't know of any such case in the wild.
+ */
+#define Tom2Enabled (1U << 21)
+#define Tom2ForceMemTypeWB (1U << 22)
+
+int __init amd_special_default_mtrr(void)
+{
+ u32 l, h;
+
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+ return 0;
+ if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11)
+ return 0;
+ /* In case some hypervisor doesn't pass SYSCFG through */
+ if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0)
+ return 0;
+ /*
+ * Memory between 4GB and top of mem is forced WB by this magic bit.
+ * Reserved before K8RevF, but should be zero there.
+ */
+ if ((l & (Tom2Enabled | Tom2ForceMemTypeWB)) ==
+ (Tom2Enabled | Tom2ForceMemTypeWB))
+ return 1;
+ return 0;
+}
+
+static u64 __init real_trim_memory(unsigned long start_pfn,
+ unsigned long limit_pfn)
+{
+ u64 trim_start, trim_size;
+ trim_start = start_pfn;
+ trim_start <<= PAGE_SHIFT;
+ trim_size = limit_pfn;
+ trim_size <<= PAGE_SHIFT;
+ trim_size -= trim_start;
+
+ return e820_update_range(trim_start, trim_size, E820_RAM,
+ E820_RESERVED);
+}
+/**
+ * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs
+ * @end_pfn: ending page frame number
+ *
+ * Some buggy BIOSes don't setup the MTRRs properly for systems with certain
+ * memory configurations. This routine checks that the highest MTRR matches
+ * the end of memory, to make sure the MTRRs having a write back type cover
+ * all of the memory the kernel is intending to use. If not, it'll trim any
+ * memory off the end by adjusting end_pfn, removing it from the kernel's
+ * allocation pools, warning the user with an obnoxious message.
+ */
+int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
+{
+ unsigned long i, base, size, highest_pfn = 0, def, dummy;
+ mtrr_type type;
+ u64 total_trim_size;
+
+ /* extra one for all 0 */
+ int num[MTRR_NUM_TYPES + 1];
+ /*
+ * Make sure we only trim uncachable memory on machines that
+ * support the Intel MTRR architecture:
+ */
+ if (!is_cpu(INTEL) || disable_mtrr_trim)
+ return 0;
+ rdmsr(MTRRdefType_MSR, def, dummy);
+ def &= 0xff;
+ if (def != MTRR_TYPE_UNCACHABLE)
+ return 0;
+
+ /* get it and store it aside */
+ memset(range_state, 0, sizeof(range_state));
+ for (i = 0; i < num_var_ranges; i++) {
+ mtrr_if->get(i, &base, &size, &type);
+ range_state[i].base_pfn = base;
+ range_state[i].size_pfn = size;
+ range_state[i].type = type;
+ }
+
+ /* Find highest cached pfn */
+ for (i = 0; i < num_var_ranges; i++) {
+ type = range_state[i].type;
+ if (type != MTRR_TYPE_WRBACK)
+ continue;
+ base = range_state[i].base_pfn;
+ size = range_state[i].size_pfn;
+ if (highest_pfn < base + size)
+ highest_pfn = base + size;
+ }
+
+ /* kvm/qemu doesn't have mtrr set right, don't trim them all */
+ if (!highest_pfn) {
+ printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n");
+ return 0;
+ }
+
+ /* check entries number */
+ memset(num, 0, sizeof(num));
+ for (i = 0; i < num_var_ranges; i++) {
+ type = range_state[i].type;
+ if (type >= MTRR_NUM_TYPES)
+ continue;
+ size = range_state[i].size_pfn;
+ if (!size)
+ type = MTRR_NUM_TYPES;
+ num[type]++;
+ }
+
+ /* no entry for WB? */
+ if (!num[MTRR_TYPE_WRBACK])
+ return 0;
+
+ /* check if we only had WB and UC */
+ if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] !=
+ num_var_ranges - num[MTRR_NUM_TYPES])
+ return 0;
+
+ memset(range, 0, sizeof(range));
+ nr_range = 0;
+ if (mtrr_tom2) {
+ range[nr_range].start = (1ULL<<(32 - PAGE_SHIFT));
+ range[nr_range].end = (mtrr_tom2 >> PAGE_SHIFT) - 1;
+ if (highest_pfn < range[nr_range].end + 1)
+ highest_pfn = range[nr_range].end + 1;
+ nr_range++;
+ }
+ nr_range = x86_get_mtrr_mem_range(range, nr_range, 0, 0);
+
+ total_trim_size = 0;
+ /* check the head */
+ if (range[0].start)
+ total_trim_size += real_trim_memory(0, range[0].start);
+ /* check the holes */
+ for (i = 0; i < nr_range - 1; i++) {
+ if (range[i].end + 1 < range[i+1].start)
+ total_trim_size += real_trim_memory(range[i].end + 1,
+ range[i+1].start);
+ }
+ /* check the top */
+ i = nr_range - 1;
+ if (range[i].end + 1 < end_pfn)
+ total_trim_size += real_trim_memory(range[i].end + 1,
+ end_pfn);
+
+ if (total_trim_size) {
+ printk(KERN_WARNING "WARNING: BIOS bug: CPU MTRRs don't cover"
+ " all of memory, losing %lluMB of RAM.\n",
+ total_trim_size >> 20);
+
+ if (!changed_by_mtrr_cleanup)
+ WARN_ON(1);
+
+ printk(KERN_INFO "update e820 for mtrr\n");
+ update_e820();
+
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 0c0a455fe95c..0b776c09aff3 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -33,13 +33,31 @@ u64 mtrr_tom2;
struct mtrr_state_type mtrr_state = {};
EXPORT_SYMBOL_GPL(mtrr_state);
-static int __initdata mtrr_show;
-static int __init mtrr_debug(char *opt)
+/**
+ * BIOS is expected to clear MtrrFixDramModEn bit, see for example
+ * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
+ * Opteron Processors" (26094 Rev. 3.30 February 2006), section
+ * "13.2.1.2 SYSCFG Register": "The MtrrFixDramModEn bit should be set
+ * to 1 during BIOS initalization of the fixed MTRRs, then cleared to
+ * 0 for operation."
+ */
+static inline void k8_check_syscfg_dram_mod_en(void)
{
- mtrr_show = 1;
- return 0;
+ u32 lo, hi;
+
+ if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
+ (boot_cpu_data.x86 >= 0x0f)))
+ return;
+
+ rdmsr(MSR_K8_SYSCFG, lo, hi);
+ if (lo & K8_MTRRFIXRANGE_DRAM_MODIFY) {
+ printk(KERN_ERR FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]"
+ " not cleared by BIOS, clearing this bit\n",
+ smp_processor_id());
+ lo &= ~K8_MTRRFIXRANGE_DRAM_MODIFY;
+ mtrr_wrmsr(MSR_K8_SYSCFG, lo, hi);
+ }
}
-early_param("mtrr.show", mtrr_debug);
/*
* Returns the effective MTRR type for the region
@@ -174,6 +192,8 @@ get_fixed_ranges(mtrr_type * frs)
unsigned int *p = (unsigned int *) frs;
int i;
+ k8_check_syscfg_dram_mod_en();
+
rdmsr(MTRRfix64K_00000_MSR, p[0], p[1]);
for (i = 0; i < 2; i++)
@@ -188,18 +208,94 @@ void mtrr_save_fixed_ranges(void *info)
get_fixed_ranges(mtrr_state.fixed_ranges);
}
-static void print_fixed(unsigned base, unsigned step, const mtrr_type*types)
+static unsigned __initdata last_fixed_start;
+static unsigned __initdata last_fixed_end;
+static mtrr_type __initdata last_fixed_type;
+
+static void __init print_fixed_last(void)
+{
+ if (!last_fixed_end)
+ return;
+
+ printk(KERN_DEBUG " %05X-%05X %s\n", last_fixed_start,
+ last_fixed_end - 1, mtrr_attrib_to_str(last_fixed_type));
+
+ last_fixed_end = 0;
+}
+
+static void __init update_fixed_last(unsigned base, unsigned end,
+ mtrr_type type)
+{
+ last_fixed_start = base;
+ last_fixed_end = end;
+ last_fixed_type = type;
+}
+
+static void __init print_fixed(unsigned base, unsigned step,
+ const mtrr_type *types)
{
unsigned i;
- for (i = 0; i < 8; ++i, ++types, base += step)
- printk(KERN_INFO "MTRR %05X-%05X %s\n",
- base, base + step - 1, mtrr_attrib_to_str(*types));
+ for (i = 0; i < 8; ++i, ++types, base += step) {
+ if (last_fixed_end == 0) {
+ update_fixed_last(base, base + step, *types);
+ continue;
+ }
+ if (last_fixed_end == base && last_fixed_type == *types) {
+ last_fixed_end = base + step;
+ continue;
+ }
+ /* new segments: gap or different type */
+ print_fixed_last();
+ update_fixed_last(base, base + step, *types);
+ }
}
static void prepare_set(void);
static void post_set(void);
+static void __init print_mtrr_state(void)
+{
+ unsigned int i;
+ int high_width;
+
+ printk(KERN_DEBUG "MTRR default type: %s\n",
+ mtrr_attrib_to_str(mtrr_state.def_type));
+ if (mtrr_state.have_fixed) {
+ printk(KERN_DEBUG "MTRR fixed ranges %sabled:\n",
+ mtrr_state.enabled & 1 ? "en" : "dis");
+ print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0);
+ for (i = 0; i < 2; ++i)
+ print_fixed(0x80000 + i * 0x20000, 0x04000, mtrr_state.fixed_ranges + (i + 1) * 8);
+ for (i = 0; i < 8; ++i)
+ print_fixed(0xC0000 + i * 0x08000, 0x01000, mtrr_state.fixed_ranges + (i + 3) * 8);
+
+ /* tail */
+ print_fixed_last();
+ }
+ printk(KERN_DEBUG "MTRR variable ranges %sabled:\n",
+ mtrr_state.enabled & 2 ? "en" : "dis");
+ high_width = ((size_or_mask ? ffs(size_or_mask) - 1 : 32) - (32 - PAGE_SHIFT) + 3) / 4;
+ for (i = 0; i < num_var_ranges; ++i) {
+ if (mtrr_state.var_ranges[i].mask_lo & (1 << 11))
+ printk(KERN_DEBUG " %u base %0*X%05X000 mask %0*X%05X000 %s\n",
+ i,
+ high_width,
+ mtrr_state.var_ranges[i].base_hi,
+ mtrr_state.var_ranges[i].base_lo >> 12,
+ high_width,
+ mtrr_state.var_ranges[i].mask_hi,
+ mtrr_state.var_ranges[i].mask_lo >> 12,
+ mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff));
+ else
+ printk(KERN_DEBUG " %u disabled\n", i);
+ }
+ if (mtrr_tom2) {
+ printk(KERN_DEBUG "TOM2: %016llx aka %lldM\n",
+ mtrr_tom2, mtrr_tom2>>20);
+ }
+}
+
/* Grab all of the MTRR state for this CPU into *state */
void __init get_mtrr_state(void)
{
@@ -231,41 +327,9 @@ void __init get_mtrr_state(void)
mtrr_tom2 |= low;
mtrr_tom2 &= 0xffffff800000ULL;
}
- if (mtrr_show) {
- int high_width;
-
- printk(KERN_INFO "MTRR default type: %s\n", mtrr_attrib_to_str(mtrr_state.def_type));
- if (mtrr_state.have_fixed) {
- printk(KERN_INFO "MTRR fixed ranges %sabled:\n",
- mtrr_state.enabled & 1 ? "en" : "dis");
- print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0);
- for (i = 0; i < 2; ++i)
- print_fixed(0x80000 + i * 0x20000, 0x04000, mtrr_state.fixed_ranges + (i + 1) * 8);
- for (i = 0; i < 8; ++i)
- print_fixed(0xC0000 + i * 0x08000, 0x01000, mtrr_state.fixed_ranges + (i + 3) * 8);
- }
- printk(KERN_INFO "MTRR variable ranges %sabled:\n",
- mtrr_state.enabled & 2 ? "en" : "dis");
- high_width = ((size_or_mask ? ffs(size_or_mask) - 1 : 32) - (32 - PAGE_SHIFT) + 3) / 4;
- for (i = 0; i < num_var_ranges; ++i) {
- if (mtrr_state.var_ranges[i].mask_lo & (1 << 11))
- printk(KERN_INFO "MTRR %u base %0*X%05X000 mask %0*X%05X000 %s\n",
- i,
- high_width,
- mtrr_state.var_ranges[i].base_hi,
- mtrr_state.var_ranges[i].base_lo >> 12,
- high_width,
- mtrr_state.var_ranges[i].mask_hi,
- mtrr_state.var_ranges[i].mask_lo >> 12,
- mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff));
- else
- printk(KERN_INFO "MTRR %u disabled\n", i);
- }
- if (mtrr_tom2) {
- printk(KERN_INFO "TOM2: %016llx aka %lldM\n",
- mtrr_tom2, mtrr_tom2>>20);
- }
- }
+
+ print_mtrr_state();
+
mtrr_state_set = 1;
/* PAT setup for BP. We need to go through sync steps here */
@@ -308,27 +372,10 @@ void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b)
}
/**
- * Enable and allow read/write of extended fixed-range MTRR bits on K8 CPUs
- * see AMD publication no. 24593, chapter 3.2.1 for more information
- */
-static inline void k8_enable_fixed_iorrs(void)
-{
- unsigned lo, hi;
-
- rdmsr(MSR_K8_SYSCFG, lo, hi);
- mtrr_wrmsr(MSR_K8_SYSCFG, lo
- | K8_MTRRFIXRANGE_DRAM_ENABLE
- | K8_MTRRFIXRANGE_DRAM_MODIFY, hi);
-}
-
-/**
* set_fixed_range - checks & updates a fixed-range MTRR if it differs from the value it should have
* @msr: MSR address of the MTTR which should be checked and updated
* @changed: pointer which indicates whether the MTRR needed to be changed
* @msrwords: pointer to the MSR values which the MSR should have
- *
- * If K8 extentions are wanted, update the K8 SYSCFG MSR also.
- * See AMD publication no. 24593, chapter 7.8.1, page 233 for more information.
*/
static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords)
{
@@ -337,10 +384,6 @@ static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords)
rdmsr(msr, lo, hi);
if (lo != msrwords[0] || hi != msrwords[1]) {
- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
- (boot_cpu_data.x86 >= 0x0f && boot_cpu_data.x86 <= 0x11) &&
- ((msrwords[0] | msrwords[1]) & K8_MTRR_RDMEM_WRMEM_MASK))
- k8_enable_fixed_iorrs();
mtrr_wrmsr(msr, msrwords[0], msrwords[1]);
*changed = true;
}
@@ -376,22 +419,31 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
{
unsigned int mask_lo, mask_hi, base_lo, base_hi;
unsigned int tmp, hi;
+ int cpu;
+
+ /*
+ * get_mtrr doesn't need to update mtrr_state, also it could be called
+ * from any cpu, so try to print it out directly.
+ */
+ cpu = get_cpu();
rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi);
+
if ((mask_lo & 0x800) == 0) {
/* Invalid (i.e. free) range */
*base = 0;
*size = 0;
*type = 0;
- return;
+ goto out_put_cpu;
}
rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi);
- /* Work out the shifted address mask. */
+ /* Work out the shifted address mask: */
tmp = mask_hi << (32 - PAGE_SHIFT) | mask_lo >> PAGE_SHIFT;
mask_lo = size_or_mask | tmp;
- /* Expand tmp with high bits to all 1s*/
+
+ /* Expand tmp with high bits to all 1s: */
hi = fls(tmp);
if (hi > 0) {
tmp |= ~((1<<(hi - 1)) - 1);
@@ -402,11 +454,16 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
}
}
- /* This works correctly if size is a power of two, i.e. a
- contiguous range. */
+ /*
+ * This works correctly if size is a power of two, i.e. a
+ * contiguous range:
+ */
*size = -mask_lo;
*base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
*type = base_lo & 0xff;
+
+out_put_cpu:
+ put_cpu();
}
/**
@@ -419,6 +476,8 @@ static int set_fixed_ranges(mtrr_type * frs)
bool changed = false;
int block=-1, range;
+ k8_check_syscfg_dram_mod_en();
+
while (fixed_range_blocks[++block].ranges)
for (range=0; range < fixed_range_blocks[block].ranges; range++)
set_fixed_range(fixed_range_blocks[block].base_msr + range,
diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c
index 4c4214690dd1..fb73a52913a4 100644
--- a/arch/x86/kernel/cpu/mtrr/if.c
+++ b/arch/x86/kernel/cpu/mtrr/if.c
@@ -377,10 +377,6 @@ static const struct file_operations mtrr_fops = {
.release = mtrr_close,
};
-
-static struct proc_dir_entry *proc_root_mtrr;
-
-
static int mtrr_seq_show(struct seq_file *seq, void *offset)
{
char factor;
@@ -423,11 +419,7 @@ static int __init mtrr_if_init(void)
(!cpu_has(c, X86_FEATURE_CENTAUR_MCR)))
return -ENODEV;
- proc_root_mtrr =
- proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops);
-
- if (proc_root_mtrr)
- proc_root_mtrr->owner = THIS_MODULE;
+ proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops);
return 0;
}
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 236a401b8259..03cda01f57c7 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -574,7 +574,7 @@ struct mtrr_value {
unsigned long lsize;
};
-static struct mtrr_value mtrr_state[MTRR_MAX_VAR_RANGES];
+static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES];
static int mtrr_save(struct sys_device * sysdev, pm_message_t state)
{
@@ -582,9 +582,9 @@ static int mtrr_save(struct sys_device * sysdev, pm_message_t state)
for (i = 0; i < num_var_ranges; i++) {
mtrr_if->get(i,
- &mtrr_state[i].lbase,
- &mtrr_state[i].lsize,
- &mtrr_state[i].ltype);
+ &mtrr_value[i].lbase,
+ &mtrr_value[i].lsize,
+ &mtrr_value[i].ltype);
}
return 0;
}
@@ -594,11 +594,11 @@ static int mtrr_restore(struct sys_device * sysdev)
int i;
for (i = 0; i < num_var_ranges; i++) {
- if (mtrr_state[i].lsize)
+ if (mtrr_value[i].lsize)
set_mtrr(i,
- mtrr_state[i].lbase,
- mtrr_state[i].lsize,
- mtrr_state[i].ltype);
+ mtrr_value[i].lbase,
+ mtrr_value[i].lsize,
+ mtrr_value[i].ltype);
}
return 0;
}
@@ -610,1058 +610,7 @@ static struct sysdev_driver mtrr_sysdev_driver = {
.resume = mtrr_restore,
};
-/* should be related to MTRR_VAR_RANGES nums */
-#define RANGE_NUM 256
-
-struct res_range {
- unsigned long start;
- unsigned long end;
-};
-
-static int __init
-add_range(struct res_range *range, int nr_range, unsigned long start,
- unsigned long end)
-{
- /* out of slots */
- if (nr_range >= RANGE_NUM)
- return nr_range;
-
- range[nr_range].start = start;
- range[nr_range].end = end;
-
- nr_range++;
-
- return nr_range;
-}
-
-static int __init
-add_range_with_merge(struct res_range *range, int nr_range, unsigned long start,
- unsigned long end)
-{
- int i;
-
- /* try to merge it with old one */
- for (i = 0; i < nr_range; i++) {
- unsigned long final_start, final_end;
- unsigned long common_start, common_end;
-
- if (!range[i].end)
- continue;
-
- common_start = max(range[i].start, start);
- common_end = min(range[i].end, end);
- if (common_start > common_end + 1)
- continue;
-
- final_start = min(range[i].start, start);
- final_end = max(range[i].end, end);
-
- range[i].start = final_start;
- range[i].end = final_end;
- return nr_range;
- }
-
- /* need to add that */
- return add_range(range, nr_range, start, end);
-}
-
-static void __init
-subtract_range(struct res_range *range, unsigned long start, unsigned long end)
-{
- int i, j;
-
- for (j = 0; j < RANGE_NUM; j++) {
- if (!range[j].end)
- continue;
-
- if (start <= range[j].start && end >= range[j].end) {
- range[j].start = 0;
- range[j].end = 0;
- continue;
- }
-
- if (start <= range[j].start && end < range[j].end &&
- range[j].start < end + 1) {
- range[j].start = end + 1;
- continue;
- }
-
-
- if (start > range[j].start && end >= range[j].end &&
- range[j].end > start - 1) {
- range[j].end = start - 1;
- continue;
- }
-
- if (start > range[j].start && end < range[j].end) {
- /* find the new spare */
- for (i = 0; i < RANGE_NUM; i++) {
- if (range[i].end == 0)
- break;
- }
- if (i < RANGE_NUM) {
- range[i].end = range[j].end;
- range[i].start = end + 1;
- } else {
- printk(KERN_ERR "run of slot in ranges\n");
- }
- range[j].end = start - 1;
- continue;
- }
- }
-}
-
-static int __init cmp_range(const void *x1, const void *x2)
-{
- const struct res_range *r1 = x1;
- const struct res_range *r2 = x2;
- long start1, start2;
-
- start1 = r1->start;
- start2 = r2->start;
-
- return start1 - start2;
-}
-
-struct var_mtrr_range_state {
- unsigned long base_pfn;
- unsigned long size_pfn;
- mtrr_type type;
-};
-
-static struct var_mtrr_range_state __initdata range_state[RANGE_NUM];
-static int __initdata debug_print;
-
-static int __init
-x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
- unsigned long extra_remove_base,
- unsigned long extra_remove_size)
-{
- unsigned long i, base, size;
- mtrr_type type;
-
- for (i = 0; i < num_var_ranges; i++) {
- type = range_state[i].type;
- if (type != MTRR_TYPE_WRBACK)
- continue;
- base = range_state[i].base_pfn;
- size = range_state[i].size_pfn;
- nr_range = add_range_with_merge(range, nr_range, base,
- base + size - 1);
- }
- if (debug_print) {
- printk(KERN_DEBUG "After WB checking\n");
- for (i = 0; i < nr_range; i++)
- printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
- range[i].start, range[i].end + 1);
- }
-
- /* take out UC ranges */
- for (i = 0; i < num_var_ranges; i++) {
- type = range_state[i].type;
- if (type != MTRR_TYPE_UNCACHABLE &&
- type != MTRR_TYPE_WRPROT)
- continue;
- size = range_state[i].size_pfn;
- if (!size)
- continue;
- base = range_state[i].base_pfn;
- subtract_range(range, base, base + size - 1);
- }
- if (extra_remove_size)
- subtract_range(range, extra_remove_base,
- extra_remove_base + extra_remove_size - 1);
-
- /* get new range num */
- nr_range = 0;
- for (i = 0; i < RANGE_NUM; i++) {
- if (!range[i].end)
- continue;
- nr_range++;
- }
- if (debug_print) {
- printk(KERN_DEBUG "After UC checking\n");
- for (i = 0; i < nr_range; i++)
- printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
- range[i].start, range[i].end + 1);
- }
-
- /* sort the ranges */
- sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
- if (debug_print) {
- printk(KERN_DEBUG "After sorting\n");
- for (i = 0; i < nr_range; i++)
- printk(KERN_DEBUG "MTRR MAP PFN: %016lx - %016lx\n",
- range[i].start, range[i].end + 1);
- }
-
- /* clear those is not used */
- for (i = nr_range; i < RANGE_NUM; i++)
- memset(&range[i], 0, sizeof(range[i]));
-
- return nr_range;
-}
-
-static struct res_range __initdata range[RANGE_NUM];
-static int __initdata nr_range;
-
-#ifdef CONFIG_MTRR_SANITIZER
-
-static unsigned long __init sum_ranges(struct res_range *range, int nr_range)
-{
- unsigned long sum;
- int i;
-
- sum = 0;
- for (i = 0; i < nr_range; i++)
- sum += range[i].end + 1 - range[i].start;
-
- return sum;
-}
-
-static int enable_mtrr_cleanup __initdata =
- CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT;
-
-static int __init disable_mtrr_cleanup_setup(char *str)
-{
- enable_mtrr_cleanup = 0;
- return 0;
-}
-early_param("disable_mtrr_cleanup", disable_mtrr_cleanup_setup);
-
-static int __init enable_mtrr_cleanup_setup(char *str)
-{
- enable_mtrr_cleanup = 1;
- return 0;
-}
-early_param("enable_mtrr_cleanup", enable_mtrr_cleanup_setup);
-
-static int __init mtrr_cleanup_debug_setup(char *str)
-{
- debug_print = 1;
- return 0;
-}
-early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup);
-
-struct var_mtrr_state {
- unsigned long range_startk;
- unsigned long range_sizek;
- unsigned long chunk_sizek;
- unsigned long gran_sizek;
- unsigned int reg;
-};
-
-static void __init
-set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
- unsigned char type, unsigned int address_bits)
-{
- u32 base_lo, base_hi, mask_lo, mask_hi;
- u64 base, mask;
-
- if (!sizek) {
- fill_mtrr_var_range(reg, 0, 0, 0, 0);
- return;
- }
-
- mask = (1ULL << address_bits) - 1;
- mask &= ~((((u64)sizek) << 10) - 1);
-
- base = ((u64)basek) << 10;
-
- base |= type;
- mask |= 0x800;
-
- base_lo = base & ((1ULL<<32) - 1);
- base_hi = base >> 32;
-
- mask_lo = mask & ((1ULL<<32) - 1);
- mask_hi = mask >> 32;
-
- fill_mtrr_var_range(reg, base_lo, base_hi, mask_lo, mask_hi);
-}
-
-static void __init
-save_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
- unsigned char type)
-{
- range_state[reg].base_pfn = basek >> (PAGE_SHIFT - 10);
- range_state[reg].size_pfn = sizek >> (PAGE_SHIFT - 10);
- range_state[reg].type = type;
-}
-
-static void __init
-set_var_mtrr_all(unsigned int address_bits)
-{
- unsigned long basek, sizek;
- unsigned char type;
- unsigned int reg;
-
- for (reg = 0; reg < num_var_ranges; reg++) {
- basek = range_state[reg].base_pfn << (PAGE_SHIFT - 10);
- sizek = range_state[reg].size_pfn << (PAGE_SHIFT - 10);
- type = range_state[reg].type;
-
- set_var_mtrr(reg, basek, sizek, type, address_bits);
- }
-}
-
-static unsigned long to_size_factor(unsigned long sizek, char *factorp)
-{
- char factor;
- unsigned long base = sizek;
-
- if (base & ((1<<10) - 1)) {
- /* not MB alignment */
- factor = 'K';
- } else if (base & ((1<<20) - 1)){
- factor = 'M';
- base >>= 10;
- } else {
- factor = 'G';
- base >>= 20;
- }
-
- *factorp = factor;
-
- return base;
-}
-
-static unsigned int __init
-range_to_mtrr(unsigned int reg, unsigned long range_startk,
- unsigned long range_sizek, unsigned char type)
-{
- if (!range_sizek || (reg >= num_var_ranges))
- return reg;
-
- while (range_sizek) {
- unsigned long max_align, align;
- unsigned long sizek;
-
- /* Compute the maximum size I can make a range */
- if (range_startk)
- max_align = ffs(range_startk) - 1;
- else
- max_align = 32;
- align = fls(range_sizek) - 1;
- if (align > max_align)
- align = max_align;
-
- sizek = 1 << align;
- if (debug_print) {
- char start_factor = 'K', size_factor = 'K';
- unsigned long start_base, size_base;
-
- start_base = to_size_factor(range_startk, &start_factor),
- size_base = to_size_factor(sizek, &size_factor),
-
- printk(KERN_DEBUG "Setting variable MTRR %d, "
- "base: %ld%cB, range: %ld%cB, type %s\n",
- reg, start_base, start_factor,
- size_base, size_factor,
- (type == MTRR_TYPE_UNCACHABLE)?"UC":
- ((type == MTRR_TYPE_WRBACK)?"WB":"Other")
- );
- }
- save_var_mtrr(reg++, range_startk, sizek, type);
- range_startk += sizek;
- range_sizek -= sizek;
- if (reg >= num_var_ranges)
- break;
- }
- return reg;
-}
-
-static unsigned __init
-range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
- unsigned long sizek)
-{
- unsigned long hole_basek, hole_sizek;
- unsigned long second_basek, second_sizek;
- unsigned long range0_basek, range0_sizek;
- unsigned long range_basek, range_sizek;
- unsigned long chunk_sizek;
- unsigned long gran_sizek;
-
- hole_basek = 0;
- hole_sizek = 0;
- second_basek = 0;
- second_sizek = 0;
- chunk_sizek = state->chunk_sizek;
- gran_sizek = state->gran_sizek;
-
- /* align with gran size, prevent small block used up MTRRs */
- range_basek = ALIGN(state->range_startk, gran_sizek);
- if ((range_basek > basek) && basek)
- return second_sizek;
- state->range_sizek -= (range_basek - state->range_startk);
- range_sizek = ALIGN(state->range_sizek, gran_sizek);
-
- while (range_sizek > state->range_sizek) {
- range_sizek -= gran_sizek;
- if (!range_sizek)
- return 0;
- }
- state->range_sizek = range_sizek;
-
- /* try to append some small hole */
- range0_basek = state->range_startk;
- range0_sizek = ALIGN(state->range_sizek, chunk_sizek);
-
- /* no increase */
- if (range0_sizek == state->range_sizek) {
- if (debug_print)
- printk(KERN_DEBUG "rangeX: %016lx - %016lx\n",
- range0_basek<<10,
- (range0_basek + state->range_sizek)<<10);
- state->reg = range_to_mtrr(state->reg, range0_basek,
- state->range_sizek, MTRR_TYPE_WRBACK);
- return 0;
- }
-
- /* only cut back, when it is not the last */
- if (sizek) {
- while (range0_basek + range0_sizek > (basek + sizek)) {
- if (range0_sizek >= chunk_sizek)
- range0_sizek -= chunk_sizek;
- else
- range0_sizek = 0;
-
- if (!range0_sizek)
- break;
- }
- }
-
-second_try:
- range_basek = range0_basek + range0_sizek;
-
- /* one hole in the middle */
- if (range_basek > basek && range_basek <= (basek + sizek))
- second_sizek = range_basek - basek;
-
- if (range0_sizek > state->range_sizek) {
-
- /* one hole in middle or at end */
- hole_sizek = range0_sizek - state->range_sizek - second_sizek;
-
- /* hole size should be less than half of range0 size */
- if (hole_sizek >= (range0_sizek >> 1) &&
- range0_sizek >= chunk_sizek) {
- range0_sizek -= chunk_sizek;
- second_sizek = 0;
- hole_sizek = 0;
-
- goto second_try;
- }
- }
-
- if (range0_sizek) {
- if (debug_print)
- printk(KERN_DEBUG "range0: %016lx - %016lx\n",
- range0_basek<<10,
- (range0_basek + range0_sizek)<<10);
- state->reg = range_to_mtrr(state->reg, range0_basek,
- range0_sizek, MTRR_TYPE_WRBACK);
- }
-
- if (range0_sizek < state->range_sizek) {
- /* need to handle left over */
- range_sizek = state->range_sizek - range0_sizek;
-
- if (debug_print)
- printk(KERN_DEBUG "range: %016lx - %016lx\n",
- range_basek<<10,
- (range_basek + range_sizek)<<10);
- state->reg = range_to_mtrr(state->reg, range_basek,
- range_sizek, MTRR_TYPE_WRBACK);
- }
-
- if (hole_sizek) {
- hole_basek = range_basek - hole_sizek - second_sizek;
- if (debug_print)
- printk(KERN_DEBUG "hole: %016lx - %016lx\n",
- hole_basek<<10,
- (hole_basek + hole_sizek)<<10);
- state->reg = range_to_mtrr(state->reg, hole_basek,
- hole_sizek, MTRR_TYPE_UNCACHABLE);
- }
-
- return second_sizek;
-}
-
-static void __init
-set_var_mtrr_range(struct var_mtrr_state *state, unsigned long base_pfn,
- unsigned long size_pfn)
-{
- unsigned long basek, sizek;
- unsigned long second_sizek = 0;
-
- if (state->reg >= num_var_ranges)
- return;
-
- basek = base_pfn << (PAGE_SHIFT - 10);
- sizek = size_pfn << (PAGE_SHIFT - 10);
-
- /* See if I can merge with the last range */
- if ((basek <= 1024) ||
- (state->range_startk + state->range_sizek == basek)) {
- unsigned long endk = basek + sizek;
- state->range_sizek = endk - state->range_startk;
- return;
- }
- /* Write the range mtrrs */
- if (state->range_sizek != 0)
- second_sizek = range_to_mtrr_with_hole(state, basek, sizek);
-
- /* Allocate an msr */
- state->range_startk = basek + second_sizek;
- state->range_sizek = sizek - second_sizek;
-}
-
-/* mininum size of mtrr block that can take hole */
-static u64 mtrr_chunk_size __initdata = (256ULL<<20);
-
-static int __init parse_mtrr_chunk_size_opt(char *p)
-{
- if (!p)
- return -EINVAL;
- mtrr_chunk_size = memparse(p, &p);
- return 0;
-}
-early_param("mtrr_chunk_size", parse_mtrr_chunk_size_opt);
-
-/* granity of mtrr of block */
-static u64 mtrr_gran_size __initdata;
-
-static int __init parse_mtrr_gran_size_opt(char *p)
-{
- if (!p)
- return -EINVAL;
- mtrr_gran_size = memparse(p, &p);
- return 0;
-}
-early_param("mtrr_gran_size", parse_mtrr_gran_size_opt);
-
-static int nr_mtrr_spare_reg __initdata =
- CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT;
-
-static int __init parse_mtrr_spare_reg(char *arg)
-{
- if (arg)
- nr_mtrr_spare_reg = simple_strtoul(arg, NULL, 0);
- return 0;
-}
-
-early_param("mtrr_spare_reg_nr", parse_mtrr_spare_reg);
-
-static int __init
-x86_setup_var_mtrrs(struct res_range *range, int nr_range,
- u64 chunk_size, u64 gran_size)
-{
- struct var_mtrr_state var_state;
- int i;
- int num_reg;
-
- var_state.range_startk = 0;
- var_state.range_sizek = 0;
- var_state.reg = 0;
- var_state.chunk_sizek = chunk_size >> 10;
- var_state.gran_sizek = gran_size >> 10;
-
- memset(range_state, 0, sizeof(range_state));
-
- /* Write the range etc */
- for (i = 0; i < nr_range; i++)
- set_var_mtrr_range(&var_state, range[i].start,
- range[i].end - range[i].start + 1);
-
- /* Write the last range */
- if (var_state.range_sizek != 0)
- range_to_mtrr_with_hole(&var_state, 0, 0);
-
- num_reg = var_state.reg;
- /* Clear out the extra MTRR's */
- while (var_state.reg < num_var_ranges) {
- save_var_mtrr(var_state.reg, 0, 0, 0);
- var_state.reg++;
- }
-
- return num_reg;
-}
-
-struct mtrr_cleanup_result {
- unsigned long gran_sizek;
- unsigned long chunk_sizek;
- unsigned long lose_cover_sizek;
- unsigned int num_reg;
- int bad;
-};
-
-/*
- * gran_size: 64K, 128K, 256K, 512K, 1M, 2M, ..., 2G
- * chunk size: gran_size, ..., 2G
- * so we need (1+16)*8
- */
-#define NUM_RESULT 136
-#define PSHIFT (PAGE_SHIFT - 10)
-
-static struct mtrr_cleanup_result __initdata result[NUM_RESULT];
-static unsigned long __initdata min_loss_pfn[RANGE_NUM];
-
-static void __init print_out_mtrr_range_state(void)
-{
- int i;
- char start_factor = 'K', size_factor = 'K';
- unsigned long start_base, size_base;
- mtrr_type type;
-
- for (i = 0; i < num_var_ranges; i++) {
-
- size_base = range_state[i].size_pfn << (PAGE_SHIFT - 10);
- if (!size_base)
- continue;
-
- size_base = to_size_factor(size_base, &size_factor),
- start_base = range_state[i].base_pfn << (PAGE_SHIFT - 10);
- start_base = to_size_factor(start_base, &start_factor),
- type = range_state[i].type;
-
- printk(KERN_DEBUG "reg %d, base: %ld%cB, range: %ld%cB, type %s\n",
- i, start_base, start_factor,
- size_base, size_factor,
- (type == MTRR_TYPE_UNCACHABLE) ? "UC" :
- ((type == MTRR_TYPE_WRPROT) ? "WP" :
- ((type == MTRR_TYPE_WRBACK) ? "WB" : "Other"))
- );
- }
-}
-
-static int __init mtrr_need_cleanup(void)
-{
- int i;
- mtrr_type type;
- unsigned long size;
- /* extra one for all 0 */
- int num[MTRR_NUM_TYPES + 1];
-
- /* check entries number */
- memset(num, 0, sizeof(num));
- for (i = 0; i < num_var_ranges; i++) {
- type = range_state[i].type;
- size = range_state[i].size_pfn;
- if (type >= MTRR_NUM_TYPES)
- continue;
- if (!size)
- type = MTRR_NUM_TYPES;
- if (type == MTRR_TYPE_WRPROT)
- type = MTRR_TYPE_UNCACHABLE;
- num[type]++;
- }
-
- /* check if we got UC entries */
- if (!num[MTRR_TYPE_UNCACHABLE])
- return 0;
-
- /* check if we only had WB and UC */
- if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] !=
- num_var_ranges - num[MTRR_NUM_TYPES])
- return 0;
-
- return 1;
-}
-
-static unsigned long __initdata range_sums;
-static void __init mtrr_calc_range_state(u64 chunk_size, u64 gran_size,
- unsigned long extra_remove_base,
- unsigned long extra_remove_size,
- int i)
-{
- int num_reg;
- static struct res_range range_new[RANGE_NUM];
- static int nr_range_new;
- unsigned long range_sums_new;
-
- /* convert ranges to var ranges state */
- num_reg = x86_setup_var_mtrrs(range, nr_range,
- chunk_size, gran_size);
-
- /* we got new setting in range_state, check it */
- memset(range_new, 0, sizeof(range_new));
- nr_range_new = x86_get_mtrr_mem_range(range_new, 0,
- extra_remove_base, extra_remove_size);
- range_sums_new = sum_ranges(range_new, nr_range_new);
-
- result[i].chunk_sizek = chunk_size >> 10;
- result[i].gran_sizek = gran_size >> 10;
- result[i].num_reg = num_reg;
- if (range_sums < range_sums_new) {
- result[i].lose_cover_sizek =
- (range_sums_new - range_sums) << PSHIFT;
- result[i].bad = 1;
- } else
- result[i].lose_cover_sizek =
- (range_sums - range_sums_new) << PSHIFT;
-
- /* double check it */
- if (!result[i].bad && !result[i].lose_cover_sizek) {
- if (nr_range_new != nr_range ||
- memcmp(range, range_new, sizeof(range)))
- result[i].bad = 1;
- }
-
- if (!result[i].bad && (range_sums - range_sums_new <
- min_loss_pfn[num_reg])) {
- min_loss_pfn[num_reg] =
- range_sums - range_sums_new;
- }
-}
-
-static void __init mtrr_print_out_one_result(int i)
-{
- char gran_factor, chunk_factor, lose_factor;
- unsigned long gran_base, chunk_base, lose_base;
-
- gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
- chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
- lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
- printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t",
- result[i].bad ? "*BAD*" : " ",
- gran_base, gran_factor, chunk_base, chunk_factor);
- printk(KERN_CONT "num_reg: %d \tlose cover RAM: %s%ld%c\n",
- result[i].num_reg, result[i].bad ? "-" : "",
- lose_base, lose_factor);
-}
-
-static int __init mtrr_search_optimal_index(void)
-{
- int i;
- int num_reg_good;
- int index_good;
-
- if (nr_mtrr_spare_reg >= num_var_ranges)
- nr_mtrr_spare_reg = num_var_ranges - 1;
- num_reg_good = -1;
- for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) {
- if (!min_loss_pfn[i])
- num_reg_good = i;
- }
-
- index_good = -1;
- if (num_reg_good != -1) {
- for (i = 0; i < NUM_RESULT; i++) {
- if (!result[i].bad &&
- result[i].num_reg == num_reg_good &&
- !result[i].lose_cover_sizek) {
- index_good = i;
- break;
- }
- }
- }
-
- return index_good;
-}
-
-
-static int __init mtrr_cleanup(unsigned address_bits)
-{
- unsigned long extra_remove_base, extra_remove_size;
- unsigned long base, size, def, dummy;
- mtrr_type type;
- u64 chunk_size, gran_size;
- int index_good;
- int i;
-
- if (!is_cpu(INTEL) || enable_mtrr_cleanup < 1)
- return 0;
- rdmsr(MTRRdefType_MSR, def, dummy);
- def &= 0xff;
- if (def != MTRR_TYPE_UNCACHABLE)
- return 0;
-
- /* get it and store it aside */
- memset(range_state, 0, sizeof(range_state));
- for (i = 0; i < num_var_ranges; i++) {
- mtrr_if->get(i, &base, &size, &type);
- range_state[i].base_pfn = base;
- range_state[i].size_pfn = size;
- range_state[i].type = type;
- }
-
- /* check if we need handle it and can handle it */
- if (!mtrr_need_cleanup())
- return 0;
-
- /* print original var MTRRs at first, for debugging: */
- printk(KERN_DEBUG "original variable MTRRs\n");
- print_out_mtrr_range_state();
-
- memset(range, 0, sizeof(range));
- extra_remove_size = 0;
- extra_remove_base = 1 << (32 - PAGE_SHIFT);
- if (mtrr_tom2)
- extra_remove_size =
- (mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base;
- nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base,
- extra_remove_size);
- /*
- * [0, 1M) should always be coverred by var mtrr with WB
- * and fixed mtrrs should take effective before var mtrr for it
- */
- nr_range = add_range_with_merge(range, nr_range, 0,
- (1ULL<<(20 - PAGE_SHIFT)) - 1);
- /* sort the ranges */
- sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
-
- range_sums = sum_ranges(range, nr_range);
- printk(KERN_INFO "total RAM coverred: %ldM\n",
- range_sums >> (20 - PAGE_SHIFT));
-
- if (mtrr_chunk_size && mtrr_gran_size) {
- i = 0;
- mtrr_calc_range_state(mtrr_chunk_size, mtrr_gran_size,
- extra_remove_base, extra_remove_size, i);
-
- mtrr_print_out_one_result(i);
-
- if (!result[i].bad) {
- set_var_mtrr_all(address_bits);
- return 1;
- }
- printk(KERN_INFO "invalid mtrr_gran_size or mtrr_chunk_size, "
- "will find optimal one\n");
- }
-
- i = 0;
- memset(min_loss_pfn, 0xff, sizeof(min_loss_pfn));
- memset(result, 0, sizeof(result));
- for (gran_size = (1ULL<<16); gran_size < (1ULL<<32); gran_size <<= 1) {
-
- for (chunk_size = gran_size; chunk_size < (1ULL<<32);
- chunk_size <<= 1) {
-
- if (i >= NUM_RESULT)
- continue;
-
- mtrr_calc_range_state(chunk_size, gran_size,
- extra_remove_base, extra_remove_size, i);
- if (debug_print) {
- mtrr_print_out_one_result(i);
- printk(KERN_INFO "\n");
- }
-
- i++;
- }
- }
-
- /* try to find the optimal index */
- index_good = mtrr_search_optimal_index();
-
- if (index_good != -1) {
- printk(KERN_INFO "Found optimal setting for mtrr clean up\n");
- i = index_good;
- mtrr_print_out_one_result(i);
-
- /* convert ranges to var ranges state */
- chunk_size = result[i].chunk_sizek;
- chunk_size <<= 10;
- gran_size = result[i].gran_sizek;
- gran_size <<= 10;
- x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size);
- set_var_mtrr_all(address_bits);
- printk(KERN_DEBUG "New variable MTRRs\n");
- print_out_mtrr_range_state();
- return 1;
- } else {
- /* print out all */
- for (i = 0; i < NUM_RESULT; i++)
- mtrr_print_out_one_result(i);
- }
-
- printk(KERN_INFO "mtrr_cleanup: can not find optimal value\n");
- printk(KERN_INFO "please specify mtrr_gran_size/mtrr_chunk_size\n");
-
- return 0;
-}
-#else
-static int __init mtrr_cleanup(unsigned address_bits)
-{
- return 0;
-}
-#endif
-
-static int __initdata changed_by_mtrr_cleanup;
-
-static int disable_mtrr_trim;
-
-static int __init disable_mtrr_trim_setup(char *str)
-{
- disable_mtrr_trim = 1;
- return 0;
-}
-early_param("disable_mtrr_trim", disable_mtrr_trim_setup);
-
-/*
- * Newer AMD K8s and later CPUs have a special magic MSR way to force WB
- * for memory >4GB. Check for that here.
- * Note this won't check if the MTRRs < 4GB where the magic bit doesn't
- * apply to are wrong, but so far we don't know of any such case in the wild.
- */
-#define Tom2Enabled (1U << 21)
-#define Tom2ForceMemTypeWB (1U << 22)
-
-int __init amd_special_default_mtrr(void)
-{
- u32 l, h;
-
- if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
- return 0;
- if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11)
- return 0;
- /* In case some hypervisor doesn't pass SYSCFG through */
- if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0)
- return 0;
- /*
- * Memory between 4GB and top of mem is forced WB by this magic bit.
- * Reserved before K8RevF, but should be zero there.
- */
- if ((l & (Tom2Enabled | Tom2ForceMemTypeWB)) ==
- (Tom2Enabled | Tom2ForceMemTypeWB))
- return 1;
- return 0;
-}
-
-static u64 __init real_trim_memory(unsigned long start_pfn,
- unsigned long limit_pfn)
-{
- u64 trim_start, trim_size;
- trim_start = start_pfn;
- trim_start <<= PAGE_SHIFT;
- trim_size = limit_pfn;
- trim_size <<= PAGE_SHIFT;
- trim_size -= trim_start;
-
- return e820_update_range(trim_start, trim_size, E820_RAM,
- E820_RESERVED);
-}
-/**
- * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs
- * @end_pfn: ending page frame number
- *
- * Some buggy BIOSes don't setup the MTRRs properly for systems with certain
- * memory configurations. This routine checks that the highest MTRR matches
- * the end of memory, to make sure the MTRRs having a write back type cover
- * all of the memory the kernel is intending to use. If not, it'll trim any
- * memory off the end by adjusting end_pfn, removing it from the kernel's
- * allocation pools, warning the user with an obnoxious message.
- */
-int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
-{
- unsigned long i, base, size, highest_pfn = 0, def, dummy;
- mtrr_type type;
- u64 total_trim_size;
-
- /* extra one for all 0 */
- int num[MTRR_NUM_TYPES + 1];
- /*
- * Make sure we only trim uncachable memory on machines that
- * support the Intel MTRR architecture:
- */
- if (!is_cpu(INTEL) || disable_mtrr_trim)
- return 0;
- rdmsr(MTRRdefType_MSR, def, dummy);
- def &= 0xff;
- if (def != MTRR_TYPE_UNCACHABLE)
- return 0;
-
- /* get it and store it aside */
- memset(range_state, 0, sizeof(range_state));
- for (i = 0; i < num_var_ranges; i++) {
- mtrr_if->get(i, &base, &size, &type);
- range_state[i].base_pfn = base;
- range_state[i].size_pfn = size;
- range_state[i].type = type;
- }
-
- /* Find highest cached pfn */
- for (i = 0; i < num_var_ranges; i++) {
- type = range_state[i].type;
- if (type != MTRR_TYPE_WRBACK)
- continue;
- base = range_state[i].base_pfn;
- size = range_state[i].size_pfn;
- if (highest_pfn < base + size)
- highest_pfn = base + size;
- }
-
- /* kvm/qemu doesn't have mtrr set right, don't trim them all */
- if (!highest_pfn) {
- printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n");
- return 0;
- }
-
- /* check entries number */
- memset(num, 0, sizeof(num));
- for (i = 0; i < num_var_ranges; i++) {
- type = range_state[i].type;
- if (type >= MTRR_NUM_TYPES)
- continue;
- size = range_state[i].size_pfn;
- if (!size)
- type = MTRR_NUM_TYPES;
- num[type]++;
- }
-
- /* no entry for WB? */
- if (!num[MTRR_TYPE_WRBACK])
- return 0;
-
- /* check if we only had WB and UC */
- if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] !=
- num_var_ranges - num[MTRR_NUM_TYPES])
- return 0;
-
- memset(range, 0, sizeof(range));
- nr_range = 0;
- if (mtrr_tom2) {
- range[nr_range].start = (1ULL<<(32 - PAGE_SHIFT));
- range[nr_range].end = (mtrr_tom2 >> PAGE_SHIFT) - 1;
- if (highest_pfn < range[nr_range].end + 1)
- highest_pfn = range[nr_range].end + 1;
- nr_range++;
- }
- nr_range = x86_get_mtrr_mem_range(range, nr_range, 0, 0);
-
- total_trim_size = 0;
- /* check the head */
- if (range[0].start)
- total_trim_size += real_trim_memory(0, range[0].start);
- /* check the holes */
- for (i = 0; i < nr_range - 1; i++) {
- if (range[i].end + 1 < range[i+1].start)
- total_trim_size += real_trim_memory(range[i].end + 1,
- range[i+1].start);
- }
- /* check the top */
- i = nr_range - 1;
- if (range[i].end + 1 < end_pfn)
- total_trim_size += real_trim_memory(range[i].end + 1,
- end_pfn);
-
- if (total_trim_size) {
- printk(KERN_WARNING "WARNING: BIOS bug: CPU MTRRs don't cover"
- " all of memory, losing %lluMB of RAM.\n",
- total_trim_size >> 20);
-
- if (!changed_by_mtrr_cleanup)
- WARN_ON(1);
-
- printk(KERN_INFO "update e820 for mtrr\n");
- update_e820();
-
- return 1;
- }
-
- return 0;
-}
+int __initdata changed_by_mtrr_cleanup;
/**
* mtrr_bp_init - initialize mtrrs on the boot CPU
diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h
index ffd60409cc6d..77f67f7b347a 100644
--- a/arch/x86/kernel/cpu/mtrr/mtrr.h
+++ b/arch/x86/kernel/cpu/mtrr/mtrr.h
@@ -79,6 +79,7 @@ extern struct mtrr_ops * mtrr_if;
extern unsigned int num_var_ranges;
extern u64 mtrr_tom2;
+extern struct mtrr_state_type mtrr_state;
void mtrr_state_warn(void);
const char *mtrr_attrib_to_str(int x);
@@ -88,3 +89,6 @@ void mtrr_wrmsr(unsigned, unsigned, unsigned);
int amd_init_mtrr(void);
int cyrix_init_mtrr(void);
int centaur_init_mtrr(void);
+
+extern int changed_by_mtrr_cleanup;
+extern int mtrr_cleanup(unsigned address_bits);
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index d67e0e48bc2d..f93047fed791 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -14,7 +14,7 @@ static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c,
if (c->x86_max_cores * smp_num_siblings > 1) {
seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
seq_printf(m, "siblings\t: %d\n",
- cpus_weight(per_cpu(cpu_core_map, cpu)));
+ cpumask_weight(cpu_sibling_mask(cpu)));
seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
seq_printf(m, "apicid\t\t: %d\n", c->apicid);
@@ -143,9 +143,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
static void *c_start(struct seq_file *m, loff_t *pos)
{
if (*pos == 0) /* just in case, cpu 0 is not the first */
- *pos = first_cpu(cpu_online_map);
+ *pos = cpumask_first(cpu_online_mask);
else
- *pos = next_cpu_nr(*pos - 1, cpu_online_map);
+ *pos = cpumask_next(*pos - 1, cpu_online_mask);
if ((*pos) < nr_cpu_ids)
return &cpu_data(*pos);
return NULL;
diff --git a/arch/x86/kernel/cpu/transmeta.c b/arch/x86/kernel/cpu/transmeta.c
index 52b3fefbd5af..bb62b3e5caad 100644
--- a/arch/x86/kernel/cpu/transmeta.c
+++ b/arch/x86/kernel/cpu/transmeta.c
@@ -98,7 +98,7 @@ static void __cpuinit init_transmeta(struct cpuinfo_x86 *c)
#endif
}
-static struct cpu_dev transmeta_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst transmeta_cpu_dev = {
.c_vendor = "Transmeta",
.c_ident = { "GenuineTMx86", "TransmetaCPU" },
.c_early_init = early_init_transmeta,
diff --git a/arch/x86/kernel/cpu/umc.c b/arch/x86/kernel/cpu/umc.c
index e777f79e0960..fd2c37bf7acb 100644
--- a/arch/x86/kernel/cpu/umc.c
+++ b/arch/x86/kernel/cpu/umc.c
@@ -8,7 +8,7 @@
* so no special init takes place.
*/
-static struct cpu_dev umc_cpu_dev __cpuinitdata = {
+static const struct cpu_dev __cpuinitconst umc_cpu_dev = {
.c_vendor = "UMC",
.c_ident = { "UMC UMC UMC" },
.c_models = {
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 508bec1cee27..ef2c3563357d 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -110,19 +110,50 @@ int __init e820_all_mapped(u64 start, u64 end, unsigned type)
/*
* Add a memory region to the kernel e820 map.
*/
-void __init e820_add_region(u64 start, u64 size, int type)
+static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
+ int type)
{
- int x = e820.nr_map;
+ int x = e820x->nr_map;
- if (x == ARRAY_SIZE(e820.map)) {
+ if (x == ARRAY_SIZE(e820x->map)) {
printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
return;
}
- e820.map[x].addr = start;
- e820.map[x].size = size;
- e820.map[x].type = type;
- e820.nr_map++;
+ e820x->map[x].addr = start;
+ e820x->map[x].size = size;
+ e820x->map[x].type = type;
+ e820x->nr_map++;
+}
+
+void __init e820_add_region(u64 start, u64 size, int type)
+{
+ __e820_add_region(&e820, start, size, type);
+}
+
+static void __init e820_print_type(u32 type)
+{
+ switch (type) {
+ case E820_RAM:
+ case E820_RESERVED_KERN:
+ printk(KERN_CONT "(usable)");
+ break;
+ case E820_RESERVED:
+ printk(KERN_CONT "(reserved)");
+ break;
+ case E820_ACPI:
+ printk(KERN_CONT "(ACPI data)");
+ break;
+ case E820_NVS:
+ printk(KERN_CONT "(ACPI NVS)");
+ break;
+ case E820_UNUSABLE:
+ printk(KERN_CONT "(unusable)");
+ break;
+ default:
+ printk(KERN_CONT "type %u", type);
+ break;
+ }
}
void __init e820_print_map(char *who)
@@ -134,27 +165,8 @@ void __init e820_print_map(char *who)
(unsigned long long) e820.map[i].addr,
(unsigned long long)
(e820.map[i].addr + e820.map[i].size));
- switch (e820.map[i].type) {
- case E820_RAM:
- case E820_RESERVED_KERN:
- printk(KERN_CONT "(usable)\n");
- break;
- case E820_RESERVED:
- printk(KERN_CONT "(reserved)\n");
- break;
- case E820_ACPI:
- printk(KERN_CONT "(ACPI data)\n");
- break;
- case E820_NVS:
- printk(KERN_CONT "(ACPI NVS)\n");
- break;
- case E820_UNUSABLE:
- printk("(unusable)\n");
- break;
- default:
- printk(KERN_CONT "type %u\n", e820.map[i].type);
- break;
- }
+ e820_print_type(e820.map[i].type);
+ printk(KERN_CONT "\n");
}
}
@@ -221,7 +233,7 @@ void __init e820_print_map(char *who)
*/
int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
- int *pnr_map)
+ u32 *pnr_map)
{
struct change_member {
struct e820entry *pbios; /* pointer to original bios entry */
@@ -417,11 +429,12 @@ static int __init append_e820_map(struct e820entry *biosmap, int nr_map)
return __append_e820_map(biosmap, nr_map);
}
-static u64 __init e820_update_range_map(struct e820map *e820x, u64 start,
+static u64 __init __e820_update_range(struct e820map *e820x, u64 start,
u64 size, unsigned old_type,
unsigned new_type)
{
- int i;
+ u64 end;
+ unsigned int i;
u64 real_updated_size = 0;
BUG_ON(old_type == new_type);
@@ -429,27 +442,55 @@ static u64 __init e820_update_range_map(struct e820map *e820x, u64 start,
if (size > (ULLONG_MAX - start))
size = ULLONG_MAX - start;
- for (i = 0; i < e820.nr_map; i++) {
+ end = start + size;
+ printk(KERN_DEBUG "e820 update range: %016Lx - %016Lx ",
+ (unsigned long long) start,
+ (unsigned long long) end);
+ e820_print_type(old_type);
+ printk(KERN_CONT " ==> ");
+ e820_print_type(new_type);
+ printk(KERN_CONT "\n");
+
+ for (i = 0; i < e820x->nr_map; i++) {
struct e820entry *ei = &e820x->map[i];
u64 final_start, final_end;
+ u64 ei_end;
+
if (ei->type != old_type)
continue;
- /* totally covered? */
- if (ei->addr >= start &&
- (ei->addr + ei->size) <= (start + size)) {
+
+ ei_end = ei->addr + ei->size;
+ /* totally covered by new range? */
+ if (ei->addr >= start && ei_end <= end) {
ei->type = new_type;
real_updated_size += ei->size;
continue;
}
+
+ /* new range is totally covered? */
+ if (ei->addr < start && ei_end > end) {
+ __e820_add_region(e820x, start, size, new_type);
+ __e820_add_region(e820x, end, ei_end - end, ei->type);
+ ei->size = start - ei->addr;
+ real_updated_size += size;
+ continue;
+ }
+
/* partially covered */
final_start = max(start, ei->addr);
- final_end = min(start + size, ei->addr + ei->size);
+ final_end = min(end, ei_end);
if (final_start >= final_end)
continue;
- e820_add_region(final_start, final_end - final_start,
- new_type);
+
+ __e820_add_region(e820x, final_start, final_end - final_start,
+ new_type);
+
real_updated_size += final_end - final_start;
+ /*
+ * left range could be head or tail, so need to update
+ * size at first.
+ */
ei->size -= final_end - final_start;
if (ei->addr < final_start)
continue;
@@ -461,13 +502,13 @@ static u64 __init e820_update_range_map(struct e820map *e820x, u64 start,
u64 __init e820_update_range(u64 start, u64 size, unsigned old_type,
unsigned new_type)
{
- return e820_update_range_map(&e820, start, size, old_type, new_type);
+ return __e820_update_range(&e820, start, size, old_type, new_type);
}
static u64 __init e820_update_range_saved(u64 start, u64 size,
unsigned old_type, unsigned new_type)
{
- return e820_update_range_map(&e820_saved, start, size, old_type,
+ return __e820_update_range(&e820_saved, start, size, old_type,
new_type);
}
@@ -511,7 +552,7 @@ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
void __init update_e820(void)
{
- int nr_map;
+ u32 nr_map;
nr_map = e820.nr_map;
if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map))
@@ -522,7 +563,7 @@ void __init update_e820(void)
}
static void __init update_e820_saved(void)
{
- int nr_map;
+ u32 nr_map;
nr_map = e820_saved.nr_map;
if (sanitize_e820_map(e820_saved.map, ARRAY_SIZE(e820_saved.map), &nr_map))
@@ -1020,8 +1061,8 @@ u64 __init find_e820_area_size(u64 start, u64 *sizep, u64 align)
continue;
return addr;
}
- return -1UL;
+ return -1ULL;
}
/*
@@ -1034,13 +1075,22 @@ u64 __init early_reserve_e820(u64 startt, u64 sizet, u64 align)
u64 start;
start = startt;
- while (size < sizet)
+ while (size < sizet && (start + 1))
start = find_e820_area_size(start, &size, align);
if (size < sizet)
return 0;
+#ifdef CONFIG_X86_32
+ if (start >= MAXMEM)
+ return 0;
+ if (start + size > MAXMEM)
+ size = MAXMEM - start;
+#endif
+
addr = round_down(start + size - sizet, align);
+ if (addr < start)
+ return 0;
e820_update_range(addr, sizet, E820_RAM, E820_RESERVED);
e820_update_range_saved(addr, sizet, E820_RAM, E820_RESERVED);
printk(KERN_INFO "update e820 for early_reserve_e820\n");
@@ -1253,7 +1303,7 @@ early_param("memmap", parse_memmap_opt);
void __init finish_e820_parsing(void)
{
if (userdef) {
- int nr = e820.nr_map;
+ u32 nr = e820.nr_map;
if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr) < 0)
early_panic("Invalid user supplied memory map");
@@ -1336,7 +1386,7 @@ void __init e820_reserve_resources_late(void)
char *__init default_machine_specific_memory_setup(void)
{
char *who = "BIOS-e820";
- int new_nr;
+ u32 new_nr;
/*
* Try to copy the BIOS-supplied E820-map.
*
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index 639ad98238a2..335f049d110f 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -250,7 +250,7 @@ static int dbgp_wait_until_complete(void)
return (ctrl & DBGP_ERROR) ? -DBGP_ERRCODE(ctrl) : DBGP_LEN(ctrl);
}
-static void dbgp_mdelay(int ms)
+static void __init dbgp_mdelay(int ms)
{
int i;
@@ -311,7 +311,7 @@ static void dbgp_set_data(const void *buf, int size)
writel(hi, &ehci_debug->data47);
}
-static void dbgp_get_data(void *buf, int size)
+static void __init dbgp_get_data(void *buf, int size)
{
unsigned char *bytes = buf;
u32 lo, hi;
@@ -355,7 +355,7 @@ static int dbgp_bulk_write(unsigned devnum, unsigned endpoint,
return ret;
}
-static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data,
+static int __init dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data,
int size)
{
u32 pids, addr, ctrl;
@@ -386,8 +386,8 @@ static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data,
return ret;
}
-static int dbgp_control_msg(unsigned devnum, int requesttype, int request,
- int value, int index, void *data, int size)
+static int __init dbgp_control_msg(unsigned devnum, int requesttype,
+ int request, int value, int index, void *data, int size)
{
u32 pids, addr, ctrl;
struct usb_ctrlrequest req;
@@ -489,7 +489,7 @@ static u32 __init find_dbgp(int ehci_num, u32 *rbus, u32 *rslot, u32 *rfunc)
return 0;
}
-static int ehci_reset_port(int port)
+static int __init ehci_reset_port(int port)
{
u32 portsc;
u32 delay_time, delay;
@@ -532,7 +532,7 @@ static int ehci_reset_port(int port)
return -EBUSY;
}
-static int ehci_wait_for_port(int port)
+static int __init ehci_wait_for_port(int port)
{
u32 status;
int ret, reps;
@@ -557,13 +557,13 @@ static inline void dbgp_printk(const char *fmt, ...) { }
typedef void (*set_debug_port_t)(int port);
-static void default_set_debug_port(int port)
+static void __init default_set_debug_port(int port)
{
}
-static set_debug_port_t set_debug_port = default_set_debug_port;
+static set_debug_port_t __initdata set_debug_port = default_set_debug_port;
-static void nvidia_set_debug_port(int port)
+static void __init nvidia_set_debug_port(int port)
{
u32 dword;
dword = read_pci_config(ehci_dev.bus, ehci_dev.slot, ehci_dev.func,
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index ac108d1fe182..3f8579f8d42c 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -18,7 +18,7 @@ void __init i386_start_kernel(void)
{
reserve_trampoline_memory();
- reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
+ reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
#ifdef CONFIG_BLK_DEV_INITRD
/* Reserve INITRD */
@@ -29,9 +29,6 @@ void __init i386_start_kernel(void)
reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
}
#endif
- reserve_early(init_pg_tables_start, init_pg_tables_end,
- "INIT_PG_TABLE");
-
reserve_ebda_region();
/*
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index f5b272247690..70eaa852c732 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -100,7 +100,7 @@ void __init x86_64_start_reservations(char *real_mode_data)
reserve_trampoline_memory();
- reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
+ reserve_early(__pa_symbol(&_text), __pa_symbol(&__bss_stop), "TEXT DATA BSS");
#ifdef CONFIG_BLK_DEV_INITRD
/* Reserve INITRD */
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index c32ca19d591a..30683883e0cd 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -38,42 +38,40 @@
#define X86_VENDOR_ID new_cpu_data+CPUINFO_x86_vendor_id
/*
- * This is how much memory *in addition to the memory covered up to
- * and including _end* we need mapped initially.
+ * This is how much memory in addition to the memory covered up to
+ * and including _end we need mapped initially.
* We need:
- * - one bit for each possible page, but only in low memory, which means
- * 2^32/4096/8 = 128K worst case (4G/4G split.)
- * - enough space to map all low memory, which means
- * (2^32/4096) / 1024 pages (worst case, non PAE)
- * (2^32/4096) / 512 + 4 pages (worst case for PAE)
- * - a few pages for allocator use before the kernel pagetable has
- * been set up
+ * (KERNEL_IMAGE_SIZE/4096) / 1024 pages (worst case, non PAE)
+ * (KERNEL_IMAGE_SIZE/4096) / 512 + 4 pages (worst case for PAE)
*
* Modulo rounding, each megabyte assigned here requires a kilobyte of
* memory, which is currently unreclaimed.
*
* This should be a multiple of a page.
+ *
+ * KERNEL_IMAGE_SIZE should be greater than pa(_end)
+ * and small than max_low_pfn, otherwise will waste some page table entries
*/
-LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
-
-/*
- * To preserve the DMA pool in PAGEALLOC kernels, we'll allocate
- * pagetables from above the 16MB DMA limit, so we'll have to set
- * up pagetables 16MB more (worst-case):
- */
-#ifdef CONFIG_DEBUG_PAGEALLOC
-LOW_PAGES = LOW_PAGES + 0x1000000
-#endif
#if PTRS_PER_PMD > 1
-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
+#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD)
#else
-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
+#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
#endif
-BOOTBITMAP_SIZE = LOW_PAGES / 8
-ALLOCATOR_SLOP = 4
-INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
+/* Enough space to fit pagetables for the low memory linear map */
+MAPPING_BEYOND_END = \
+ PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
+
+/*
+ * Worst-case size of the kernel mapping we need to make:
+ * the worst-case size of the kernel itself, plus the extra we need
+ * to map for the linear map.
+ */
+KERNEL_PAGES = (KERNEL_IMAGE_SIZE + MAPPING_BEYOND_END)>>PAGE_SHIFT
+
+INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm
+RESERVE_BRK(pagetables, INIT_MAP_SIZE)
/*
* 32-bit kernel entrypoint; only used by the boot CPU. On entry,
@@ -166,10 +164,10 @@ num_subarch_entries = (. - subarch_entries) / 4
/*
* Initialize page tables. This creates a PDE and a set of page
- * tables, which are located immediately beyond _end. The variable
- * init_pg_tables_end is set up to point to the first "safe" location.
+ * tables, which are located immediately beyond __brk_base. The variable
+ * _brk_end is set up to point to the first "safe" location.
* Mappings are created both at virtual address 0 (identity mapping)
- * and PAGE_OFFSET for up to _end+sizeof(page tables)+INIT_MAP_BEYOND_END.
+ * and PAGE_OFFSET for up to _end.
*
* Note that the stack is not yet set up!
*/
@@ -190,8 +188,7 @@ default_entry:
xorl %ebx,%ebx /* %ebx is kept at zero */
- movl $pa(pg0), %edi
- movl %edi, pa(init_pg_tables_start)
+ movl $pa(__brk_base), %edi
movl $pa(swapper_pg_pmd), %edx
movl $PTE_IDENT_ATTR, %eax
10:
@@ -209,14 +206,14 @@ default_entry:
loop 11b
/*
- * End condition: we must map up to and including INIT_MAP_BEYOND_END
- * bytes beyond the end of our own page tables.
+ * End condition: we must map up to the end + MAPPING_BEYOND_END.
*/
- leal (INIT_MAP_BEYOND_END+PTE_IDENT_ATTR)(%edi),%ebp
+ movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
cmpl %ebp,%eax
jb 10b
1:
- movl %edi,pa(init_pg_tables_end)
+ addl $__PAGE_OFFSET, %edi
+ movl %edi, pa(_brk_end)
shrl $12, %eax
movl %eax, pa(max_pfn_mapped)
@@ -227,8 +224,7 @@ default_entry:
page_pde_offset = (__PAGE_OFFSET >> 20);
- movl $pa(pg0), %edi
- movl %edi, pa(init_pg_tables_start)
+ movl $pa(__brk_base), %edi
movl $pa(swapper_pg_dir), %edx
movl $PTE_IDENT_ATTR, %eax
10:
@@ -242,14 +238,13 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
addl $0x1000,%eax
loop 11b
/*
- * End condition: we must map up to and including INIT_MAP_BEYOND_END
- * bytes beyond the end of our own page tables; the +0x007 is
- * the attribute bits
+ * End condition: we must map up to the end + MAPPING_BEYOND_END.
*/
- leal (INIT_MAP_BEYOND_END+PTE_IDENT_ATTR)(%edi),%ebp
+ movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
cmpl %ebp,%eax
jb 10b
- movl %edi,pa(init_pg_tables_end)
+ addl $__PAGE_OFFSET, %edi
+ movl %edi, pa(_brk_end)
shrl $12, %eax
movl %eax, pa(max_pfn_mapped)
@@ -636,6 +631,7 @@ swapper_pg_fixmap:
.fill 1024,4,0
ENTRY(empty_zero_page)
.fill 4096,1,0
+
/*
* This starts the data section.
*/
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index a00545fe5cdd..648b3a2a3a44 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -80,6 +80,7 @@ static inline void hpet_clear_mapping(void)
*/
static int boot_hpet_disable;
int hpet_force_user;
+static int hpet_verbose;
static int __init hpet_setup(char *str)
{
@@ -88,6 +89,8 @@ static int __init hpet_setup(char *str)
boot_hpet_disable = 1;
if (!strncmp("force", str, 5))
hpet_force_user = 1;
+ if (!strncmp("verbose", str, 7))
+ hpet_verbose = 1;
}
return 1;
}
@@ -119,6 +122,43 @@ int is_hpet_enabled(void)
}
EXPORT_SYMBOL_GPL(is_hpet_enabled);
+static void _hpet_print_config(const char *function, int line)
+{
+ u32 i, timers, l, h;
+ printk(KERN_INFO "hpet: %s(%d):\n", function, line);
+ l = hpet_readl(HPET_ID);
+ h = hpet_readl(HPET_PERIOD);
+ timers = ((l & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT) + 1;
+ printk(KERN_INFO "hpet: ID: 0x%x, PERIOD: 0x%x\n", l, h);
+ l = hpet_readl(HPET_CFG);
+ h = hpet_readl(HPET_STATUS);
+ printk(KERN_INFO "hpet: CFG: 0x%x, STATUS: 0x%x\n", l, h);
+ l = hpet_readl(HPET_COUNTER);
+ h = hpet_readl(HPET_COUNTER+4);
+ printk(KERN_INFO "hpet: COUNTER_l: 0x%x, COUNTER_h: 0x%x\n", l, h);
+
+ for (i = 0; i < timers; i++) {
+ l = hpet_readl(HPET_Tn_CFG(i));
+ h = hpet_readl(HPET_Tn_CFG(i)+4);
+ printk(KERN_INFO "hpet: T%d: CFG_l: 0x%x, CFG_h: 0x%x\n",
+ i, l, h);
+ l = hpet_readl(HPET_Tn_CMP(i));
+ h = hpet_readl(HPET_Tn_CMP(i)+4);
+ printk(KERN_INFO "hpet: T%d: CMP_l: 0x%x, CMP_h: 0x%x\n",
+ i, l, h);
+ l = hpet_readl(HPET_Tn_ROUTE(i));
+ h = hpet_readl(HPET_Tn_ROUTE(i)+4);
+ printk(KERN_INFO "hpet: T%d ROUTE_l: 0x%x, ROUTE_h: 0x%x\n",
+ i, l, h);
+ }
+}
+
+#define hpet_print_config() \
+do { \
+ if (hpet_verbose) \
+ _hpet_print_config(__FUNCTION__, __LINE__); \
+} while (0)
+
/*
* When the hpet driver (/dev/hpet) is enabled, we need to reserve
* timer 0 and timer 1 in case of RTC emulation.
@@ -191,27 +231,37 @@ static struct clock_event_device hpet_clockevent = {
.rating = 50,
};
-static void hpet_start_counter(void)
+static void hpet_stop_counter(void)
{
unsigned long cfg = hpet_readl(HPET_CFG);
-
cfg &= ~HPET_CFG_ENABLE;
hpet_writel(cfg, HPET_CFG);
hpet_writel(0, HPET_COUNTER);
hpet_writel(0, HPET_COUNTER + 4);
+}
+
+static void hpet_start_counter(void)
+{
+ unsigned long cfg = hpet_readl(HPET_CFG);
cfg |= HPET_CFG_ENABLE;
hpet_writel(cfg, HPET_CFG);
}
+static void hpet_restart_counter(void)
+{
+ hpet_stop_counter();
+ hpet_start_counter();
+}
+
static void hpet_resume_device(void)
{
force_hpet_resume();
}
-static void hpet_restart_counter(void)
+static void hpet_resume_counter(void)
{
hpet_resume_device();
- hpet_start_counter();
+ hpet_restart_counter();
}
static void hpet_enable_legacy_int(void)
@@ -259,29 +309,23 @@ static int hpet_setup_msi_irq(unsigned int irq);
static void hpet_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt, int timer)
{
- unsigned long cfg, cmp, now;
+ unsigned long cfg;
uint64_t delta;
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
+ hpet_stop_counter();
delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * evt->mult;
delta >>= evt->shift;
- now = hpet_readl(HPET_COUNTER);
- cmp = now + (unsigned long) delta;
cfg = hpet_readl(HPET_Tn_CFG(timer));
/* Make sure we use edge triggered interrupts */
cfg &= ~HPET_TN_LEVEL;
cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
HPET_TN_SETVAL | HPET_TN_32BIT;
hpet_writel(cfg, HPET_Tn_CFG(timer));
- /*
- * The first write after writing TN_SETVAL to the
- * config register sets the counter value, the second
- * write sets the period.
- */
- hpet_writel(cmp, HPET_Tn_CMP(timer));
- udelay(1);
hpet_writel((unsigned long) delta, HPET_Tn_CMP(timer));
+ hpet_start_counter();
+ hpet_print_config();
break;
case CLOCK_EVT_MODE_ONESHOT:
@@ -308,6 +352,7 @@ static void hpet_set_mode(enum clock_event_mode mode,
irq_set_affinity(hdev->irq, cpumask_of(hdev->cpu));
enable_irq(hdev->irq);
}
+ hpet_print_config();
break;
}
}
@@ -526,6 +571,7 @@ static void hpet_msi_capability_lookup(unsigned int start_timer)
num_timers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT);
num_timers++; /* Value read out starts from 0 */
+ hpet_print_config();
hpet_devs = kzalloc(sizeof(struct hpet_dev) * num_timers, GFP_KERNEL);
if (!hpet_devs)
@@ -695,7 +741,7 @@ static struct clocksource clocksource_hpet = {
.mask = HPET_MASK,
.shift = HPET_SHIFT,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
- .resume = hpet_restart_counter,
+ .resume = hpet_resume_counter,
#ifdef CONFIG_X86_64
.vread = vread_hpet,
#endif
@@ -707,7 +753,7 @@ static int hpet_clocksource_register(void)
cycle_t t1;
/* Start the counter */
- hpet_start_counter();
+ hpet_restart_counter();
/* Verify whether hpet counter works */
t1 = read_hpet();
@@ -793,6 +839,7 @@ int __init hpet_enable(void)
* information and the number of channels
*/
id = hpet_readl(HPET_ID);
+ hpet_print_config();
#ifdef CONFIG_HPET_EMULATE_RTC
/*
@@ -845,6 +892,7 @@ static __init int hpet_late_init(void)
return -ENODEV;
hpet_reserve_platform_timers(hpet_readl(HPET_ID));
+ hpet_print_config();
for_each_online_cpu(cpu) {
hpet_cpuhp_notify(NULL, CPU_ONLINE, (void *)(long)cpu);
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c
index 10f92fb532f3..3475440baa54 100644
--- a/arch/x86/kernel/i8253.c
+++ b/arch/x86/kernel/i8253.c
@@ -3,17 +3,17 @@
*
*/
#include <linux/clockchips.h>
-#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/spinlock.h>
#include <linux/jiffies.h>
#include <linux/module.h>
-#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
-#include <asm/smp.h>
-#include <asm/delay.h>
#include <asm/i8253.h>
-#include <asm/io.h>
#include <asm/hpet.h>
+#include <asm/smp.h>
DEFINE_SPINLOCK(i8253_lock);
EXPORT_SYMBOL(i8253_lock);
@@ -40,7 +40,7 @@ static void init_pit_timer(enum clock_event_mode mode,
{
spin_lock(&i8253_lock);
- switch(mode) {
+ switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
/* binary, mode 2, LSB/MSB, ch 0 */
outb_pit(0x34, PIT_MODE);
@@ -95,7 +95,7 @@ static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
* registered. This mechanism replaces the previous #ifdef LOCAL_APIC -
* !using_apic_timer decisions in do_timer_interrupt_hook()
*/
-static struct clock_event_device pit_clockevent = {
+static struct clock_event_device pit_ce = {
.name = "pit",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.set_mode = init_pit_timer,
@@ -114,15 +114,13 @@ void __init setup_pit_timer(void)
* Start pit with the boot cpu mask and make it global after the
* IO_APIC has been initialized.
*/
- pit_clockevent.cpumask = cpumask_of(smp_processor_id());
- pit_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
- pit_clockevent.shift);
- pit_clockevent.max_delta_ns =
- clockevent_delta2ns(0x7FFF, &pit_clockevent);
- pit_clockevent.min_delta_ns =
- clockevent_delta2ns(0xF, &pit_clockevent);
- clockevents_register_device(&pit_clockevent);
- global_clock_event = &pit_clockevent;
+ pit_ce.cpumask = cpumask_of(smp_processor_id());
+ pit_ce.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, pit_ce.shift);
+ pit_ce.max_delta_ns = clockevent_delta2ns(0x7FFF, &pit_ce);
+ pit_ce.min_delta_ns = clockevent_delta2ns(0xF, &pit_ce);
+
+ clockevents_register_device(&pit_ce);
+ global_clock_event = &pit_ce;
}
#ifndef CONFIG_X86_64
@@ -133,11 +131,11 @@ void __init setup_pit_timer(void)
*/
static cycle_t pit_read(void)
{
+ static int old_count;
+ static u32 old_jifs;
unsigned long flags;
int count;
u32 jifs;
- static int old_count;
- static u32 old_jifs;
spin_lock_irqsave(&i8253_lock, flags);
/*
@@ -179,9 +177,9 @@ static cycle_t pit_read(void)
* Previous attempts to handle these cases intelligently were
* buggy, so we just do the simple thing now.
*/
- if (count > old_count && jifs == old_jifs) {
+ if (count > old_count && jifs == old_jifs)
count = old_count;
- }
+
old_count = count;
old_jifs = jifs;
@@ -192,13 +190,13 @@ static cycle_t pit_read(void)
return (cycle_t)(jifs * LATCH) + count;
}
-static struct clocksource clocksource_pit = {
- .name = "pit",
- .rating = 110,
- .read = pit_read,
- .mask = CLOCKSOURCE_MASK(32),
- .mult = 0,
- .shift = 20,
+static struct clocksource pit_cs = {
+ .name = "pit",
+ .rating = 110,
+ .read = pit_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .mult = 0,
+ .shift = 20,
};
static void pit_disable_clocksource(void)
@@ -206,9 +204,9 @@ static void pit_disable_clocksource(void)
/*
* Use mult to check whether it is registered or not
*/
- if (clocksource_pit.mult) {
- clocksource_unregister(&clocksource_pit);
- clocksource_pit.mult = 0;
+ if (pit_cs.mult) {
+ clocksource_unregister(&pit_cs);
+ pit_cs.mult = 0;
}
}
@@ -222,13 +220,13 @@ static int __init init_pit_clocksource(void)
* - when local APIC timer is active (PIT is switched off)
*/
if (num_possible_cpus() > 1 || is_hpet_enabled() ||
- pit_clockevent.mode != CLOCK_EVT_MODE_PERIODIC)
+ pit_ce.mode != CLOCK_EVT_MODE_PERIODIC)
return 0;
- clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE,
- clocksource_pit.shift);
- return clocksource_register(&clocksource_pit);
+ pit_cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE, pit_cs.shift);
+
+ return clocksource_register(&pit_cs);
}
arch_initcall(init_pit_clocksource);
-#endif
+#endif /* !CONFIG_X86_64 */
diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c
index 720d2607aacb..a979b5bd2fc0 100644
--- a/arch/x86/kernel/io_delay.c
+++ b/arch/x86/kernel/io_delay.c
@@ -7,10 +7,10 @@
*/
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/init.h>
#include <linux/dmi.h>
-#include <asm/io.h>
+#include <linux/io.h>
int io_delay_type __read_mostly = CONFIG_DEFAULT_IO_DELAY_TYPE;
@@ -47,8 +47,7 @@ EXPORT_SYMBOL(native_io_delay);
static int __init dmi_io_delay_0xed_port(const struct dmi_system_id *id)
{
if (io_delay_type == CONFIG_IO_DELAY_TYPE_0X80) {
- printk(KERN_NOTICE "%s: using 0xed I/O delay port\n",
- id->ident);
+ pr_notice("%s: using 0xed I/O delay port\n", id->ident);
io_delay_type = CONFIG_IO_DELAY_TYPE_0XED;
}
@@ -64,40 +63,40 @@ static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = {
.callback = dmi_io_delay_0xed_port,
.ident = "Compaq Presario V6000",
.matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
- DMI_MATCH(DMI_BOARD_NAME, "30B7")
+ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+ DMI_MATCH(DMI_BOARD_NAME, "30B7")
}
},
{
.callback = dmi_io_delay_0xed_port,
.ident = "HP Pavilion dv9000z",
.matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
- DMI_MATCH(DMI_BOARD_NAME, "30B9")
+ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+ DMI_MATCH(DMI_BOARD_NAME, "30B9")
}
},
{
.callback = dmi_io_delay_0xed_port,
.ident = "HP Pavilion dv6000",
.matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
- DMI_MATCH(DMI_BOARD_NAME, "30B8")
+ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+ DMI_MATCH(DMI_BOARD_NAME, "30B8")
}
},
{
.callback = dmi_io_delay_0xed_port,
.ident = "HP Pavilion tx1000",
.matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
- DMI_MATCH(DMI_BOARD_NAME, "30BF")
+ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+ DMI_MATCH(DMI_BOARD_NAME, "30BF")
}
},
{
.callback = dmi_io_delay_0xed_port,
.ident = "Presario F700",
.matches = {
- DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
- DMI_MATCH(DMI_BOARD_NAME, "30D3")
+ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+ DMI_MATCH(DMI_BOARD_NAME, "30D3")
}
},
{ }
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index b864341dcc45..3aaf7b9e3a8b 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -45,19 +45,24 @@ void ack_bad_irq(unsigned int irq)
/*
* /proc/interrupts printing:
*/
-static int show_other_interrupts(struct seq_file *p)
+static int show_other_interrupts(struct seq_file *p, int prec)
{
int j;
- seq_printf(p, "NMI: ");
+ seq_printf(p, "%*s: ", prec, "NMI");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->__nmi_count);
seq_printf(p, " Non-maskable interrupts\n");
#ifdef CONFIG_X86_LOCAL_APIC
- seq_printf(p, "LOC: ");
+ seq_printf(p, "%*s: ", prec, "LOC");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs);
seq_printf(p, " Local timer interrupts\n");
+
+ seq_printf(p, "%*s: ", prec, "SPU");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
+ seq_printf(p, " Spurious interrupts\n");
#endif
if (generic_interrupt_extension) {
seq_printf(p, "PLT: ");
@@ -66,40 +71,34 @@ static int show_other_interrupts(struct seq_file *p)
seq_printf(p, " Platform interrupts\n");
}
#ifdef CONFIG_SMP
- seq_printf(p, "RES: ");
+ seq_printf(p, "%*s: ", prec, "RES");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
seq_printf(p, " Rescheduling interrupts\n");
- seq_printf(p, "CAL: ");
+ seq_printf(p, "%*s: ", prec, "CAL");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
seq_printf(p, " Function call interrupts\n");
- seq_printf(p, "TLB: ");
+ seq_printf(p, "%*s: ", prec, "TLB");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
seq_printf(p, " TLB shootdowns\n");
#endif
#ifdef CONFIG_X86_MCE
- seq_printf(p, "TRM: ");
+ seq_printf(p, "%*s: ", prec, "TRM");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_thermal_count);
seq_printf(p, " Thermal event interrupts\n");
# ifdef CONFIG_X86_64
- seq_printf(p, "THR: ");
+ seq_printf(p, "%*s: ", prec, "THR");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_threshold_count);
seq_printf(p, " Threshold APIC interrupts\n");
# endif
#endif
-#ifdef CONFIG_X86_LOCAL_APIC
- seq_printf(p, "SPU: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
- seq_printf(p, " Spurious interrupts\n");
-#endif
- seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+ seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
#if defined(CONFIG_X86_IO_APIC)
- seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
+ seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count));
#endif
return 0;
}
@@ -107,19 +106,22 @@ static int show_other_interrupts(struct seq_file *p)
int show_interrupts(struct seq_file *p, void *v)
{
unsigned long flags, any_count = 0;
- int i = *(loff_t *) v, j;
+ int i = *(loff_t *) v, j, prec;
struct irqaction *action;
struct irq_desc *desc;
if (i > nr_irqs)
return 0;
+ for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec)
+ j *= 10;
+
if (i == nr_irqs)
- return show_other_interrupts(p);
+ return show_other_interrupts(p, prec);
/* print header */
if (i == 0) {
- seq_printf(p, " ");
+ seq_printf(p, "%*s", prec + 8, "");
for_each_online_cpu(j)
seq_printf(p, "CPU%-8d", j);
seq_putc(p, '\n');
@@ -130,23 +132,15 @@ int show_interrupts(struct seq_file *p, void *v)
return 0;
spin_lock_irqsave(&desc->lock, flags);
-#ifndef CONFIG_SMP
- any_count = kstat_irqs(i);
-#else
for_each_online_cpu(j)
any_count |= kstat_irqs_cpu(i, j);
-#endif
action = desc->action;
if (!action && !any_count)
goto out;
- seq_printf(p, "%3d: ", i);
-#ifndef CONFIG_SMP
- seq_printf(p, "%10u ", kstat_irqs(i));
-#else
+ seq_printf(p, "%*d: ", prec, i);
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
-#endif
seq_printf(p, " %8s", desc->chip->name);
seq_printf(p, "-%-8s", desc->name);
@@ -171,6 +165,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
#ifdef CONFIG_X86_LOCAL_APIC
sum += irq_stats(cpu)->apic_timer_irqs;
+ sum += irq_stats(cpu)->irq_spurious_count;
#endif
if (generic_interrupt_extension)
sum += irq_stats(cpu)->generic_irqs;
@@ -185,9 +180,6 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
sum += irq_stats(cpu)->irq_threshold_count;
#endif
#endif
-#ifdef CONFIG_X86_LOCAL_APIC
- sum += irq_stats(cpu)->irq_spurious_count;
-#endif
return sum;
}
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c
index bc1326105448..368b0a8836f9 100644
--- a/arch/x86/kernel/irqinit_32.c
+++ b/arch/x86/kernel/irqinit_32.c
@@ -50,7 +50,6 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id)
*/
static struct irqaction fpu_irq = {
.handler = math_error_irq,
- .mask = CPU_MASK_NONE,
.name = "fpu",
};
@@ -83,7 +82,6 @@ void __init init_ISA_irqs(void)
*/
static struct irqaction irq2 = {
.handler = no_action,
- .mask = CPU_MASK_NONE,
.name = "cascade",
};
diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c
index c7a49e0ffbfb..8cd10537fd46 100644
--- a/arch/x86/kernel/irqinit_64.c
+++ b/arch/x86/kernel/irqinit_64.c
@@ -45,7 +45,6 @@
static struct irqaction irq2 = {
.handler = no_action,
- .mask = CPU_MASK_NONE,
.name = "cascade",
};
DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c
index ff7d3b0124f1..e444357375ce 100644
--- a/arch/x86/kernel/kdebugfs.c
+++ b/arch/x86/kernel/kdebugfs.c
@@ -8,11 +8,11 @@
*/
#include <linux/debugfs.h>
#include <linux/uaccess.h>
-#include <linux/stat.h>
+#include <linux/module.h>
#include <linux/init.h>
+#include <linux/stat.h>
#include <linux/io.h>
#include <linux/mm.h>
-#include <linux/module.h>
#include <asm/setup.h>
@@ -26,9 +26,8 @@ struct setup_data_node {
u32 len;
};
-static ssize_t
-setup_data_read(struct file *file, char __user *user_buf, size_t count,
- loff_t *ppos)
+static ssize_t setup_data_read(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
{
struct setup_data_node *node = file->private_data;
unsigned long remain;
@@ -39,20 +38,21 @@ setup_data_read(struct file *file, char __user *user_buf, size_t count,
if (pos < 0)
return -EINVAL;
+
if (pos >= node->len)
return 0;
if (count > node->len - pos)
count = node->len - pos;
+
pa = node->paddr + sizeof(struct setup_data) + pos;
pg = pfn_to_page((pa + count - 1) >> PAGE_SHIFT);
if (PageHighMem(pg)) {
p = ioremap_cache(pa, count);
if (!p)
return -ENXIO;
- } else {
+ } else
p = __va(pa);
- }
remain = copy_to_user(user_buf, p, count);
@@ -70,12 +70,13 @@ setup_data_read(struct file *file, char __user *user_buf, size_t count,
static int setup_data_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
+
return 0;
}
static const struct file_operations fops_setup_data = {
- .read = setup_data_read,
- .open = setup_data_open,
+ .read = setup_data_read,
+ .open = setup_data_open,
};
static int __init
@@ -84,57 +85,50 @@ create_setup_data_node(struct dentry *parent, int no,
{
struct dentry *d, *type, *data;
char buf[16];
- int error;
sprintf(buf, "%d", no);
d = debugfs_create_dir(buf, parent);
- if (!d) {
- error = -ENOMEM;
- goto err_return;
- }
+ if (!d)
+ return -ENOMEM;
+
type = debugfs_create_x32("type", S_IRUGO, d, &node->type);
- if (!type) {
- error = -ENOMEM;
+ if (!type)
goto err_dir;
- }
+
data = debugfs_create_file("data", S_IRUGO, d, node, &fops_setup_data);
- if (!data) {
- error = -ENOMEM;
+ if (!data)
goto err_type;
- }
+
return 0;
err_type:
debugfs_remove(type);
err_dir:
debugfs_remove(d);
-err_return:
- return error;
+ return -ENOMEM;
}
static int __init create_setup_data_nodes(struct dentry *parent)
{
struct setup_data_node *node;
struct setup_data *data;
- int error, no = 0;
+ int error = -ENOMEM;
struct dentry *d;
struct page *pg;
u64 pa_data;
+ int no = 0;
d = debugfs_create_dir("setup_data", parent);
- if (!d) {
- error = -ENOMEM;
- goto err_return;
- }
+ if (!d)
+ return -ENOMEM;
pa_data = boot_params.hdr.setup_data;
while (pa_data) {
node = kmalloc(sizeof(*node), GFP_KERNEL);
- if (!node) {
- error = -ENOMEM;
+ if (!node)
goto err_dir;
- }
+
pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT);
if (PageHighMem(pg)) {
data = ioremap_cache(pa_data, sizeof(*data));
@@ -143,9 +137,8 @@ static int __init create_setup_data_nodes(struct dentry *parent)
error = -ENXIO;
goto err_dir;
}
- } else {
+ } else
data = __va(pa_data);
- }
node->paddr = pa_data;
node->type = data->type;
@@ -159,11 +152,11 @@ static int __init create_setup_data_nodes(struct dentry *parent)
goto err_dir;
no++;
}
+
return 0;
err_dir:
debugfs_remove(d);
-err_return:
return error;
}
@@ -175,28 +168,26 @@ static struct debugfs_blob_wrapper boot_params_blob = {
static int __init boot_params_kdebugfs_init(void)
{
struct dentry *dbp, *version, *data;
- int error;
+ int error = -ENOMEM;
dbp = debugfs_create_dir("boot_params", NULL);
- if (!dbp) {
- error = -ENOMEM;
- goto err_return;
- }
+ if (!dbp)
+ return -ENOMEM;
+
version = debugfs_create_x16("version", S_IRUGO, dbp,
&boot_params.hdr.version);
- if (!version) {
- error = -ENOMEM;
+ if (!version)
goto err_dir;
- }
+
data = debugfs_create_blob("data", S_IRUGO, dbp,
&boot_params_blob);
- if (!data) {
- error = -ENOMEM;
+ if (!data)
goto err_version;
- }
+
error = create_setup_data_nodes(dbp);
if (error)
goto err_data;
+
return 0;
err_data:
@@ -205,10 +196,9 @@ err_version:
debugfs_remove(version);
err_dir:
debugfs_remove(dbp);
-err_return:
return error;
}
-#endif
+#endif /* CONFIG_DEBUG_BOOT_PARAMS */
static int __init arch_kdebugfs_init(void)
{
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 4558dd3918cf..7b5169d2b000 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -193,7 +193,7 @@ static int __kprobes can_boost(kprobe_opcode_t *opcodes)
kprobe_opcode_t opcode;
kprobe_opcode_t *orig_opcodes = opcodes;
- if (search_exception_tables(opcodes))
+ if (search_exception_tables((unsigned long)opcodes))
return 0; /* Page fault may occur on this address. */
retry:
@@ -638,13 +638,13 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
#else
" pushf\n"
/*
- * Skip cs, ip, orig_ax.
+ * Skip cs, ip, orig_ax and gs.
* trampoline_handler() will plug in these values
*/
- " subl $12, %esp\n"
+ " subl $16, %esp\n"
" pushl %fs\n"
- " pushl %ds\n"
" pushl %es\n"
+ " pushl %ds\n"
" pushl %eax\n"
" pushl %ebp\n"
" pushl %edi\n"
@@ -655,10 +655,10 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
" movl %esp, %eax\n"
" call trampoline_handler\n"
/* Move flags to cs */
- " movl 52(%esp), %edx\n"
- " movl %edx, 48(%esp)\n"
+ " movl 56(%esp), %edx\n"
+ " movl %edx, 52(%esp)\n"
/* Replace saved flags with true return address. */
- " movl %eax, 52(%esp)\n"
+ " movl %eax, 56(%esp)\n"
" popl %ebx\n"
" popl %ecx\n"
" popl %edx\n"
@@ -666,8 +666,8 @@ static void __used __kprobes kretprobe_trampoline_holder(void)
" popl %edi\n"
" popl %ebp\n"
" popl %eax\n"
- /* Skip ip, orig_ax, es, ds, fs */
- " addl $20, %esp\n"
+ /* Skip ds, es, fs, gs, orig_ax and ip */
+ " addl $24, %esp\n"
" popf\n"
#endif
" ret\n");
@@ -691,6 +691,7 @@ static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
regs->cs = __KERNEL_CS;
#else
regs->cs = __KERNEL_CS | get_kernel_rpl();
+ regs->gs = 0;
#endif
regs->ip = trampoline_address;
regs->orig_ax = ~0UL;
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 478bca986eca..33019ddb56b4 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -138,12 +138,6 @@ static void kvm_set_pte_atomic(pte_t *ptep, pte_t pte)
kvm_mmu_write(ptep, pte_val(pte));
}
-static void kvm_set_pte_present(struct mm_struct *mm, unsigned long addr,
- pte_t *ptep, pte_t pte)
-{
- kvm_mmu_write(ptep, pte_val(pte));
-}
-
static void kvm_pte_clear(struct mm_struct *mm,
unsigned long addr, pte_t *ptep)
{
@@ -220,7 +214,6 @@ static void paravirt_ops_setup(void)
#if PAGETABLE_LEVELS >= 3
#ifdef CONFIG_X86_PAE
pv_mmu_ops.set_pte_atomic = kvm_set_pte_atomic;
- pv_mmu_ops.set_pte_present = kvm_set_pte_present;
pv_mmu_ops.pte_clear = kvm_pte_clear;
pv_mmu_ops.pmd_clear = kvm_pmd_clear;
#endif
diff --git a/arch/x86/kernel/mfgpt_32.c b/arch/x86/kernel/mfgpt_32.c
index 8815f3c7fec7..846510b78a09 100644
--- a/arch/x86/kernel/mfgpt_32.c
+++ b/arch/x86/kernel/mfgpt_32.c
@@ -348,7 +348,6 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id)
static struct irqaction mfgptirq = {
.handler = mfgpt_tick,
.flags = IRQF_DISABLED | IRQF_NOBALANCING,
- .mask = CPU_MASK_NONE,
.name = "mfgpt-timer"
};
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index c25fdb382292..453b5795a5c6 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -12,31 +12,30 @@
*
* Licensed under the terms of the GNU General Public
* License version 2. See file COPYING for details.
-*/
-
+ */
+#include <linux/platform_device.h>
#include <linux/capability.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
#include <linux/miscdevice.h>
+#include <linux/firmware.h>
#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
+#include <linux/cpumask.h>
+#include <linux/pci_ids.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/cpu.h>
-#include <linux/firmware.h>
-#include <linux/platform_device.h>
#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
-#include <asm/msr.h>
-#include <asm/processor.h>
#include <asm/microcode.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
MODULE_DESCRIPTION("AMD Microcode Update Driver");
MODULE_AUTHOR("Peter Oruba");
@@ -72,8 +71,8 @@ struct microcode_header_amd {
} __attribute__((packed));
struct microcode_amd {
- struct microcode_header_amd hdr;
- unsigned int mpb[0];
+ struct microcode_header_amd hdr;
+ unsigned int mpb[0];
};
#define UCODE_MAX_SIZE 2048
@@ -184,8 +183,8 @@ static int get_ucode_data(void *to, const u8 *from, size_t n)
return 0;
}
-static void *get_next_ucode(const u8 *buf, unsigned int size,
- unsigned int *mc_size)
+static void *
+get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size)
{
unsigned int total_size;
u8 section_hdr[UCODE_CONTAINER_SECTION_HDR];
@@ -223,7 +222,6 @@ static void *get_next_ucode(const u8 *buf, unsigned int size,
return mc;
}
-
static int install_equiv_cpu_table(const u8 *buf)
{
u8 *container_hdr[UCODE_CONTAINER_HEADER_SIZE];
@@ -372,4 +370,3 @@ struct microcode_ops * __init init_amd_microcode(void)
{
return &microcode_amd_ops;
}
-
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index c9b721ba968c..a0f3851ef310 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -70,67 +70,78 @@
* Fix sigmatch() macro to handle old CPUs with pf == 0.
* Thanks to Stuart Swales for pointing out this bug.
*/
+#include <linux/platform_device.h>
#include <linux/capability.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/firmware.h>
#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
#include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/uaccess.h>
#include <linux/vmalloc.h>
-#include <linux/miscdevice.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/cpu.h>
-#include <linux/firmware.h>
-#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
-#include <asm/msr.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
#include <asm/microcode.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
MODULE_DESCRIPTION("Microcode Update Driver");
MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
MODULE_LICENSE("GPL");
-#define MICROCODE_VERSION "2.00"
+#define MICROCODE_VERSION "2.00"
-static struct microcode_ops *microcode_ops;
+static struct microcode_ops *microcode_ops;
/* no concurrent ->write()s are allowed on /dev/cpu/microcode */
static DEFINE_MUTEX(microcode_mutex);
-struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
+struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
EXPORT_SYMBOL_GPL(ucode_cpu_info);
#ifdef CONFIG_MICROCODE_OLD_INTERFACE
+struct update_for_cpu {
+ const void __user *buf;
+ size_t size;
+};
+
+static long update_for_cpu(void *_ufc)
+{
+ struct update_for_cpu *ufc = _ufc;
+ int error;
+
+ error = microcode_ops->request_microcode_user(smp_processor_id(),
+ ufc->buf, ufc->size);
+ if (error < 0)
+ return error;
+ if (!error)
+ microcode_ops->apply_microcode(smp_processor_id());
+ return error;
+}
+
static int do_microcode_update(const void __user *buf, size_t size)
{
- cpumask_t old;
int error = 0;
int cpu;
-
- old = current->cpus_allowed;
+ struct update_for_cpu ufc = { .buf = buf, .size = size };
for_each_online_cpu(cpu) {
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
if (!uci->valid)
continue;
-
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
- error = microcode_ops->request_microcode_user(cpu, buf, size);
+ error = work_on_cpu(cpu, update_for_cpu, &ufc);
if (error < 0)
- goto out;
- if (!error)
- microcode_ops->apply_microcode(cpu);
+ break;
}
-out:
- set_cpus_allowed_ptr(current, &old);
return error;
}
@@ -198,18 +209,33 @@ static void microcode_dev_exit(void)
MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
#else
-#define microcode_dev_init() 0
-#define microcode_dev_exit() do { } while (0)
+#define microcode_dev_init() 0
+#define microcode_dev_exit() do { } while (0)
#endif
/* fake device for request_firmware */
-static struct platform_device *microcode_pdev;
+static struct platform_device *microcode_pdev;
+
+static long reload_for_cpu(void *unused)
+{
+ struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id();
+ int err = 0;
+
+ mutex_lock(&microcode_mutex);
+ if (uci->valid) {
+ err = microcode_ops->request_microcode_fw(smp_processor_id(),
+ &microcode_pdev->dev);
+ if (!err)
+ microcode_ops->apply_microcode(smp_processor_id());
+ }
+ mutex_unlock(&microcode_mutex);
+ return err;
+}
static ssize_t reload_store(struct sys_device *dev,
struct sysdev_attribute *attr,
const char *buf, size_t sz)
{
- struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
char *end;
unsigned long val = simple_strtoul(buf, &end, 0);
int err = 0;
@@ -218,21 +244,9 @@ static ssize_t reload_store(struct sys_device *dev,
if (end == buf)
return -EINVAL;
if (val == 1) {
- cpumask_t old = current->cpus_allowed;
-
get_online_cpus();
- if (cpu_online(cpu)) {
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
- mutex_lock(&microcode_mutex);
- if (uci->valid) {
- err = microcode_ops->request_microcode_fw(cpu,
- &microcode_pdev->dev);
- if (!err)
- microcode_ops->apply_microcode(cpu);
- }
- mutex_unlock(&microcode_mutex);
- set_cpus_allowed_ptr(current, &old);
- }
+ if (cpu_online(cpu))
+ err = work_on_cpu(cpu, reload_for_cpu, NULL);
put_online_cpus();
}
if (err)
@@ -268,8 +282,8 @@ static struct attribute *mc_default_attrs[] = {
};
static struct attribute_group mc_attr_group = {
- .attrs = mc_default_attrs,
- .name = "microcode",
+ .attrs = mc_default_attrs,
+ .name = "microcode",
};
static void __microcode_fini_cpu(int cpu)
@@ -328,9 +342,9 @@ static int microcode_resume_cpu(int cpu)
return 0;
}
-static void microcode_update_cpu(int cpu)
+static long microcode_update_cpu(void *unused)
{
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+ struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id();
int err = 0;
/*
@@ -338,30 +352,27 @@ static void microcode_update_cpu(int cpu)
* otherwise just request a firmware:
*/
if (uci->valid) {
- err = microcode_resume_cpu(cpu);
- } else {
- collect_cpu_info(cpu);
+ err = microcode_resume_cpu(smp_processor_id());
+ } else {
+ collect_cpu_info(smp_processor_id());
if (uci->valid && system_state == SYSTEM_RUNNING)
- err = microcode_ops->request_microcode_fw(cpu,
+ err = microcode_ops->request_microcode_fw(
+ smp_processor_id(),
&microcode_pdev->dev);
}
if (!err)
- microcode_ops->apply_microcode(cpu);
+ microcode_ops->apply_microcode(smp_processor_id());
+ return err;
}
-static void microcode_init_cpu(int cpu)
+static int microcode_init_cpu(int cpu)
{
- cpumask_t old = current->cpus_allowed;
-
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
- /* We should bind the task to the CPU */
- BUG_ON(raw_smp_processor_id() != cpu);
-
+ int err;
mutex_lock(&microcode_mutex);
- microcode_update_cpu(cpu);
+ err = work_on_cpu(cpu, microcode_update_cpu, NULL);
mutex_unlock(&microcode_mutex);
- set_cpus_allowed_ptr(current, &old);
+ return err;
}
static int mc_sysdev_add(struct sys_device *sys_dev)
@@ -379,8 +390,11 @@ static int mc_sysdev_add(struct sys_device *sys_dev)
if (err)
return err;
- microcode_init_cpu(cpu);
- return 0;
+ err = microcode_init_cpu(cpu);
+ if (err)
+ sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
+
+ return err;
}
static int mc_sysdev_remove(struct sys_device *sys_dev)
@@ -404,14 +418,14 @@ static int mc_sysdev_resume(struct sys_device *dev)
return 0;
/* only CPU 0 will apply ucode here */
- microcode_update_cpu(0);
+ microcode_update_cpu(NULL);
return 0;
}
static struct sysdev_driver mc_sysdev_driver = {
- .add = mc_sysdev_add,
- .remove = mc_sysdev_remove,
- .resume = mc_sysdev_resume,
+ .add = mc_sysdev_add,
+ .remove = mc_sysdev_remove,
+ .resume = mc_sysdev_resume,
};
static __cpuinit int
@@ -424,7 +438,9 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
- microcode_init_cpu(cpu);
+ if (microcode_init_cpu(cpu))
+ printk(KERN_ERR "microcode: failed to init CPU%d\n",
+ cpu);
case CPU_DOWN_FAILED:
case CPU_DOWN_FAILED_FROZEN:
pr_debug("microcode: CPU%d added\n", cpu);
@@ -448,7 +464,7 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
}
static struct notifier_block __refdata mc_cpu_notifier = {
- .notifier_call = mc_cpu_callback,
+ .notifier_call = mc_cpu_callback,
};
static int __init microcode_init(void)
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index 5e9f4fc51385..149b9ec7c1ab 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -70,28 +70,28 @@
* Fix sigmatch() macro to handle old CPUs with pf == 0.
* Thanks to Stuart Swales for pointing out this bug.
*/
+#include <linux/platform_device.h>
#include <linux/capability.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
+#include <linux/miscdevice.h>
+#include <linux/firmware.h>
#include <linux/smp_lock.h>
+#include <linux/spinlock.h>
#include <linux/cpumask.h>
-#include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/uaccess.h>
#include <linux/vmalloc.h>
-#include <linux/miscdevice.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/cpu.h>
-#include <linux/firmware.h>
-#include <linux/platform_device.h>
-#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
-#include <asm/msr.h>
-#include <asm/processor.h>
#include <asm/microcode.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
MODULE_DESCRIPTION("Microcode Update Driver");
MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
@@ -129,12 +129,13 @@ struct extended_sigtable {
struct extended_signature sigs[0];
};
-#define DEFAULT_UCODE_DATASIZE (2000)
+#define DEFAULT_UCODE_DATASIZE (2000)
#define MC_HEADER_SIZE (sizeof(struct microcode_header_intel))
#define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)
#define EXT_HEADER_SIZE (sizeof(struct extended_sigtable))
#define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature))
#define DWSIZE (sizeof(u32))
+
#define get_totalsize(mc) \
(((struct microcode_intel *)mc)->hdr.totalsize ? \
((struct microcode_intel *)mc)->hdr.totalsize : \
@@ -197,30 +198,31 @@ static inline int update_match_cpu(struct cpu_signature *csig, int sig, int pf)
}
static inline int
-update_match_revision(struct microcode_header_intel *mc_header, int rev)
+update_match_revision(struct microcode_header_intel *mc_header, int rev)
{
return (mc_header->rev <= rev) ? 0 : 1;
}
static int microcode_sanity_check(void *mc)
{
+ unsigned long total_size, data_size, ext_table_size;
struct microcode_header_intel *mc_header = mc;
struct extended_sigtable *ext_header = NULL;
- struct extended_signature *ext_sig;
- unsigned long total_size, data_size, ext_table_size;
int sum, orig_sum, ext_sigcount = 0, i;
+ struct extended_signature *ext_sig;
total_size = get_totalsize(mc_header);
data_size = get_datasize(mc_header);
+
if (data_size + MC_HEADER_SIZE > total_size) {
printk(KERN_ERR "microcode: error! "
- "Bad data size in microcode data file\n");
+ "Bad data size in microcode data file\n");
return -EINVAL;
}
if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {
printk(KERN_ERR "microcode: error! "
- "Unknown microcode update format\n");
+ "Unknown microcode update format\n");
return -EINVAL;
}
ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
@@ -318,11 +320,15 @@ get_matching_microcode(struct cpu_signature *cpu_sig, void *mc, int rev)
static void apply_microcode(int cpu)
{
+ struct microcode_intel *mc_intel;
+ struct ucode_cpu_info *uci;
unsigned long flags;
unsigned int val[2];
- int cpu_num = raw_smp_processor_id();
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
- struct microcode_intel *mc_intel = uci->mc;
+ int cpu_num;
+
+ cpu_num = raw_smp_processor_id();
+ uci = ucode_cpu_info + cpu;
+ mc_intel = uci->mc;
/* We should bind the task to the CPU */
BUG_ON(cpu_num != cpu);
@@ -348,15 +354,17 @@ static void apply_microcode(int cpu)
spin_unlock_irqrestore(&microcode_update_lock, flags);
if (val[1] != mc_intel->hdr.rev) {
printk(KERN_ERR "microcode: CPU%d update from revision "
- "0x%x to 0x%x failed\n", cpu_num, uci->cpu_sig.rev, val[1]);
+ "0x%x to 0x%x failed\n",
+ cpu_num, uci->cpu_sig.rev, val[1]);
return;
}
printk(KERN_INFO "microcode: CPU%d updated from revision "
- "0x%x to 0x%x, date = %04x-%02x-%02x \n",
+ "0x%x to 0x%x, date = %04x-%02x-%02x \n",
cpu_num, uci->cpu_sig.rev, val[1],
mc_intel->hdr.date & 0xffff,
mc_intel->hdr.date >> 24,
(mc_intel->hdr.date >> 16) & 0xff);
+
uci->cpu_sig.rev = val[1];
}
@@ -404,18 +412,23 @@ static int generic_load_microcode(int cpu, void *data, size_t size,
leftover -= mc_size;
}
- if (new_mc) {
- if (!leftover) {
- if (uci->mc)
- vfree(uci->mc);
- uci->mc = (struct microcode_intel *)new_mc;
- pr_debug("microcode: CPU%d found a matching microcode update with"
- " version 0x%x (current=0x%x)\n",
- cpu, new_rev, uci->cpu_sig.rev);
- } else
- vfree(new_mc);
+ if (!new_mc)
+ goto out;
+
+ if (leftover) {
+ vfree(new_mc);
+ goto out;
}
+ if (uci->mc)
+ vfree(uci->mc);
+ uci->mc = (struct microcode_intel *)new_mc;
+
+ pr_debug("microcode: CPU%d found a matching microcode update with"
+ " version 0x%x (current=0x%x)\n",
+ cpu, new_rev, uci->cpu_sig.rev);
+
+ out:
return (int)leftover;
}
diff --git a/arch/x86/kernel/mmconf-fam10h_64.c b/arch/x86/kernel/mmconf-fam10h_64.c
index 666e43df51f9..712d15fdc416 100644
--- a/arch/x86/kernel/mmconf-fam10h_64.c
+++ b/arch/x86/kernel/mmconf-fam10h_64.c
@@ -226,7 +226,7 @@ static int __devinit set_check_enable_amd_mmconf(const struct dmi_system_id *d)
return 0;
}
-static struct dmi_system_id __devinitdata mmconf_dmi_table[] = {
+static const struct dmi_system_id __cpuinitconst mmconf_dmi_table[] = {
{
.callback = set_check_enable_amd_mmconf,
.ident = "Sun Microsystems Machine",
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index e8192401da47..dce99dca6cf8 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -109,9 +109,6 @@ static void __init MP_bus_info(struct mpc_bus *m)
} else
printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
}
-#endif
-
-#ifdef CONFIG_X86_IO_APIC
static int bad_ioapic(unsigned long address)
{
@@ -224,8 +221,12 @@ static void __init MP_intsrc_info(struct mpc_intsrc *m)
if (++mp_irq_entries == MAX_IRQ_SOURCES)
panic("Max # of irq sources exceeded!!\n");
}
+#else /* CONFIG_X86_IO_APIC */
+static inline void __init MP_bus_info(struct mpc_bus *m) {}
+static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {}
+static inline void __init MP_intsrc_info(struct mpc_intsrc *m) {}
+#endif /* CONFIG_X86_IO_APIC */
-#endif
static void __init MP_lintsrc_info(struct mpc_lintsrc *m)
{
@@ -275,6 +276,20 @@ static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str)
return 1;
}
+static void skip_entry(unsigned char **ptr, int *count, int size)
+{
+ *ptr += size;
+ *count += size;
+}
+
+static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt)
+{
+ printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"
+ "type %x\n", *mpt);
+ print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_ADDRESS, 16,
+ 1, mpc, mpc->length, 1);
+}
+
static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
{
char str[16];
@@ -310,61 +325,30 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
while (count < mpc->length) {
switch (*mpt) {
case MP_PROCESSOR:
- {
- struct mpc_cpu *m = (struct mpc_cpu *)mpt;
- /* ACPI may have already provided this data */
- if (!acpi_lapic)
- MP_processor_info(m);
- mpt += sizeof(*m);
- count += sizeof(*m);
- break;
- }
+ /* ACPI may have already provided this data */
+ if (!acpi_lapic)
+ MP_processor_info((struct mpc_cpu *)mpt);
+ skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
+ break;
case MP_BUS:
- {
- struct mpc_bus *m = (struct mpc_bus *)mpt;
-#ifdef CONFIG_X86_IO_APIC
- MP_bus_info(m);
-#endif
- mpt += sizeof(*m);
- count += sizeof(*m);
- break;
- }
+ MP_bus_info((struct mpc_bus *)mpt);
+ skip_entry(&mpt, &count, sizeof(struct mpc_bus));
+ break;
case MP_IOAPIC:
- {
-#ifdef CONFIG_X86_IO_APIC
- struct mpc_ioapic *m = (struct mpc_ioapic *)mpt;
- MP_ioapic_info(m);
-#endif
- mpt += sizeof(struct mpc_ioapic);
- count += sizeof(struct mpc_ioapic);
- break;
- }
+ MP_ioapic_info((struct mpc_ioapic *)mpt);
+ skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
+ break;
case MP_INTSRC:
- {
-#ifdef CONFIG_X86_IO_APIC
- struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
-
- MP_intsrc_info(m);
-#endif
- mpt += sizeof(struct mpc_intsrc);
- count += sizeof(struct mpc_intsrc);
- break;
- }
+ MP_intsrc_info((struct mpc_intsrc *)mpt);
+ skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
+ break;
case MP_LINTSRC:
- {
- struct mpc_lintsrc *m =
- (struct mpc_lintsrc *)mpt;
- MP_lintsrc_info(m);
- mpt += sizeof(*m);
- count += sizeof(*m);
- break;
- }
+ MP_lintsrc_info((struct mpc_lintsrc *)mpt);
+ skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
+ break;
default:
/* wrong mptable */
- printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n");
- printk(KERN_ERR "type %x\n", *mpt);
- print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_ADDRESS, 16,
- 1, mpc, mpc->length, 1);
+ smp_dump_mptable(mpc, mpt);
count = mpc->length;
break;
}
@@ -571,6 +555,55 @@ static unsigned long __init get_mpc_size(unsigned long physptr)
return size;
}
+static int __init check_physptr(struct mpf_intel *mpf, unsigned int early)
+{
+ struct mpc_table *mpc;
+ unsigned long size;
+
+ size = get_mpc_size(mpf->physptr);
+ mpc = early_ioremap(mpf->physptr, size);
+ /*
+ * Read the physical hardware table. Anything here will
+ * override the defaults.
+ */
+ if (!smp_read_mpc(mpc, early)) {
+#ifdef CONFIG_X86_LOCAL_APIC
+ smp_found_config = 0;
+#endif
+ printk(KERN_ERR "BIOS bug, MP table errors detected!...\n"
+ "... disabling SMP support. (tell your hw vendor)\n");
+ early_iounmap(mpc, size);
+ return -1;
+ }
+ early_iounmap(mpc, size);
+
+ if (early)
+ return -1;
+
+#ifdef CONFIG_X86_IO_APIC
+ /*
+ * If there are no explicit MP IRQ entries, then we are
+ * broken. We set up most of the low 16 IO-APIC pins to
+ * ISA defaults and hope it will work.
+ */
+ if (!mp_irq_entries) {
+ struct mpc_bus bus;
+
+ printk(KERN_ERR "BIOS bug, no explicit IRQ entries, "
+ "using default mptable. (tell your hw vendor)\n");
+
+ bus.type = MP_BUS;
+ bus.busid = 0;
+ memcpy(bus.bustype, "ISA ", 6);
+ MP_bus_info(&bus);
+
+ construct_default_ioirq_mptable(0);
+ }
+#endif
+
+ return 0;
+}
+
/*
* Scan the memory blocks for an SMP configuration block.
*/
@@ -624,51 +657,8 @@ static void __init __get_smp_config(unsigned int early)
construct_default_ISA_mptable(mpf->feature1);
} else if (mpf->physptr) {
- struct mpc_table *mpc;
- unsigned long size;
-
- size = get_mpc_size(mpf->physptr);
- mpc = early_ioremap(mpf->physptr, size);
- /*
- * Read the physical hardware table. Anything here will
- * override the defaults.
- */
- if (!smp_read_mpc(mpc, early)) {
-#ifdef CONFIG_X86_LOCAL_APIC
- smp_found_config = 0;
-#endif
- printk(KERN_ERR
- "BIOS bug, MP table errors detected!...\n");
- printk(KERN_ERR "... disabling SMP support. "
- "(tell your hw vendor)\n");
- early_iounmap(mpc, size);
- return;
- }
- early_iounmap(mpc, size);
-
- if (early)
+ if (check_physptr(mpf, early))
return;
-#ifdef CONFIG_X86_IO_APIC
- /*
- * If there are no explicit MP IRQ entries, then we are
- * broken. We set up most of the low 16 IO-APIC pins to
- * ISA defaults and hope it will work.
- */
- if (!mp_irq_entries) {
- struct mpc_bus bus;
-
- printk(KERN_ERR "BIOS bug, no explicit IRQ entries, "
- "using default mptable. "
- "(tell your hw vendor)\n");
-
- bus.type = MP_BUS;
- bus.busid = 0;
- memcpy(bus.bustype, "ISA ", 6);
- MP_bus_info(&bus);
-
- construct_default_ioirq_mptable(0);
- }
-#endif
} else
BUG();
@@ -689,6 +679,31 @@ void __init get_smp_config(void)
__get_smp_config(0);
}
+static void smp_reserve_bootmem(struct mpf_intel *mpf)
+{
+ unsigned long size = get_mpc_size(mpf->physptr);
+#ifdef CONFIG_X86_32
+ /*
+ * We cannot access to MPC table to compute table size yet,
+ * as only few megabytes from the bottom is mapped now.
+ * PC-9800's MPC table places on the very last of physical
+ * memory; so that simply reserving PAGE_SIZE from mpf->physptr
+ * yields BUG() in reserve_bootmem.
+ * also need to make sure physptr is below than max_low_pfn
+ * we don't need reserve the area above max_low_pfn
+ */
+ unsigned long end = max_low_pfn * PAGE_SIZE;
+
+ if (mpf->physptr < end) {
+ if (mpf->physptr + size > end)
+ size = end - mpf->physptr;
+ reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT);
+ }
+#else
+ reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT);
+#endif
+}
+
static int __init smp_scan_config(unsigned long base, unsigned long length,
unsigned reserve)
{
@@ -717,35 +732,9 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
if (!reserve)
return 1;
reserve_bootmem_generic(virt_to_phys(mpf), sizeof(*mpf),
- BOOTMEM_DEFAULT);
- if (mpf->physptr) {
- unsigned long size = get_mpc_size(mpf->physptr);
-#ifdef CONFIG_X86_32
- /*
- * We cannot access to MPC table to compute
- * table size yet, as only few megabytes from
- * the bottom is mapped now.
- * PC-9800's MPC table places on the very last
- * of physical memory; so that simply reserving
- * PAGE_SIZE from mpf->physptr yields BUG()
- * in reserve_bootmem.
- * also need to make sure physptr is below than
- * max_low_pfn
- * we don't need reserve the area above max_low_pfn
- */
- unsigned long end = max_low_pfn * PAGE_SIZE;
-
- if (mpf->physptr < end) {
- if (mpf->physptr + size > end)
- size = end - mpf->physptr;
- reserve_bootmem_generic(mpf->physptr, size,
- BOOTMEM_DEFAULT);
- }
-#else
- reserve_bootmem_generic(mpf->physptr, size,
BOOTMEM_DEFAULT);
-#endif
- }
+ if (mpf->physptr)
+ smp_reserve_bootmem(mpf);
return 1;
}
@@ -848,7 +837,57 @@ static int __init get_MP_intsrc_index(struct mpc_intsrc *m)
#define SPARE_SLOT_NUM 20
static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM];
-#endif
+
+static void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare)
+{
+ int i;
+
+ apic_printk(APIC_VERBOSE, "OLD ");
+ print_MP_intsrc_info(m);
+
+ i = get_MP_intsrc_index(m);
+ if (i > 0) {
+ assign_to_mpc_intsrc(&mp_irqs[i], m);
+ apic_printk(APIC_VERBOSE, "NEW ");
+ print_mp_irq_info(&mp_irqs[i]);
+ return;
+ }
+ if (!i) {
+ /* legacy, do nothing */
+ return;
+ }
+ if (*nr_m_spare < SPARE_SLOT_NUM) {
+ /*
+ * not found (-1), or duplicated (-2) are invalid entries,
+ * we need to use the slot later
+ */
+ m_spare[*nr_m_spare] = m;
+ *nr_m_spare += 1;
+ }
+}
+#else /* CONFIG_X86_IO_APIC */
+static inline void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {}
+#endif /* CONFIG_X86_IO_APIC */
+
+static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length,
+ int count)
+{
+ if (!mpc_new_phys) {
+ pr_info("No spare slots, try to append...take your risk, "
+ "new mpc_length %x\n", count);
+ } else {
+ if (count <= mpc_new_length)
+ pr_info("No spare slots, try to append..., "
+ "new mpc_length %x\n", count);
+ else {
+ pr_err("mpc_new_length %lx is too small\n",
+ mpc_new_length);
+ return -1;
+ }
+ }
+
+ return 0;
+}
static int __init replace_intsrc_all(struct mpc_table *mpc,
unsigned long mpc_new_phys,
@@ -856,77 +895,33 @@ static int __init replace_intsrc_all(struct mpc_table *mpc,
{
#ifdef CONFIG_X86_IO_APIC
int i;
- int nr_m_spare = 0;
#endif
-
int count = sizeof(*mpc);
+ int nr_m_spare = 0;
unsigned char *mpt = ((unsigned char *)mpc) + count;
printk(KERN_INFO "mpc_length %x\n", mpc->length);
while (count < mpc->length) {
switch (*mpt) {
case MP_PROCESSOR:
- {
- struct mpc_cpu *m = (struct mpc_cpu *)mpt;
- mpt += sizeof(*m);
- count += sizeof(*m);
- break;
- }
+ skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
+ break;
case MP_BUS:
- {
- struct mpc_bus *m = (struct mpc_bus *)mpt;
- mpt += sizeof(*m);
- count += sizeof(*m);
- break;
- }
+ skip_entry(&mpt, &count, sizeof(struct mpc_bus));
+ break;
case MP_IOAPIC:
- {
- mpt += sizeof(struct mpc_ioapic);
- count += sizeof(struct mpc_ioapic);
- break;
- }
+ skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
+ break;
case MP_INTSRC:
- {
-#ifdef CONFIG_X86_IO_APIC
- struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
-
- printk(KERN_INFO "OLD ");
- print_MP_intsrc_info(m);
- i = get_MP_intsrc_index(m);
- if (i > 0) {
- assign_to_mpc_intsrc(&mp_irqs[i], m);
- printk(KERN_INFO "NEW ");
- print_mp_irq_info(&mp_irqs[i]);
- } else if (!i) {
- /* legacy, do nothing */
- } else if (nr_m_spare < SPARE_SLOT_NUM) {
- /*
- * not found (-1), or duplicated (-2)
- * are invalid entries,
- * we need to use the slot later
- */
- m_spare[nr_m_spare] = m;
- nr_m_spare++;
- }
-#endif
- mpt += sizeof(struct mpc_intsrc);
- count += sizeof(struct mpc_intsrc);
- break;
- }
+ check_irq_src((struct mpc_intsrc *)mpt, &nr_m_spare);
+ skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
+ break;
case MP_LINTSRC:
- {
- struct mpc_lintsrc *m =
- (struct mpc_lintsrc *)mpt;
- mpt += sizeof(*m);
- count += sizeof(*m);
- break;
- }
+ skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
+ break;
default:
/* wrong mptable */
- printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n");
- printk(KERN_ERR "type %x\n", *mpt);
- print_hex_dump(KERN_ERR, " ", DUMP_PREFIX_ADDRESS, 16,
- 1, mpc, mpc->length, 1);
+ smp_dump_mptable(mpc, mpt);
goto out;
}
}
@@ -943,23 +938,15 @@ static int __init replace_intsrc_all(struct mpc_table *mpc,
continue;
if (nr_m_spare > 0) {
- printk(KERN_INFO "*NEW* found ");
+ apic_printk(APIC_VERBOSE, "*NEW* found\n");
nr_m_spare--;
assign_to_mpc_intsrc(&mp_irqs[i], m_spare[nr_m_spare]);
m_spare[nr_m_spare] = NULL;
} else {
struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
count += sizeof(struct mpc_intsrc);
- if (!mpc_new_phys) {
- printk(KERN_INFO "No spare slots, try to append...take your risk, new mpc_length %x\n", count);
- } else {
- if (count <= mpc_new_length)
- printk(KERN_INFO "No spare slots, try to append..., new mpc_length %x\n", count);
- else {
- printk(KERN_ERR "mpc_new_length %lx is too small\n", mpc_new_length);
- goto out;
- }
- }
+ if (!check_slot(mpc_new_phys, mpc_new_length, count))
+ goto out;
assign_to_mpc_intsrc(&mp_irqs[i], m);
mpc->length = count;
mpt += sizeof(struct mpc_intsrc);
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 63dd358d8ee1..8e45f4464880 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -470,7 +470,6 @@ struct pv_mmu_ops pv_mmu_ops = {
#if PAGETABLE_LEVELS >= 3
#ifdef CONFIG_X86_PAE
.set_pte_atomic = native_set_pte_atomic,
- .set_pte_present = native_set_pte_present,
.pte_clear = native_pte_clear,
.pmd_clear = native_pmd_clear,
#endif
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index d28bbdc35e4e..755c21e906f3 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -380,8 +380,9 @@ static inline struct iommu_table *find_iommu_table(struct device *dev)
return tbl;
}
-static void calgary_unmap_sg(struct device *dev,
- struct scatterlist *sglist, int nelems, int direction)
+static void calgary_unmap_sg(struct device *dev, struct scatterlist *sglist,
+ int nelems,enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
struct iommu_table *tbl = find_iommu_table(dev);
struct scatterlist *s;
@@ -404,7 +405,8 @@ static void calgary_unmap_sg(struct device *dev,
}
static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
- int nelems, int direction)
+ int nelems, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
struct iommu_table *tbl = find_iommu_table(dev);
struct scatterlist *s;
@@ -429,15 +431,14 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
s->dma_address = (entry << PAGE_SHIFT) | s->offset;
/* insert into HW table */
- tce_build(tbl, entry, npages, vaddr & PAGE_MASK,
- direction);
+ tce_build(tbl, entry, npages, vaddr & PAGE_MASK, dir);
s->dma_length = s->length;
}
return nelems;
error:
- calgary_unmap_sg(dev, sg, nelems, direction);
+ calgary_unmap_sg(dev, sg, nelems, dir, NULL);
for_each_sg(sg, s, nelems, i) {
sg->dma_address = bad_dma_address;
sg->dma_length = 0;
@@ -445,10 +446,12 @@ error:
return 0;
}
-static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr,
- size_t size, int direction)
+static dma_addr_t calgary_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
- void *vaddr = phys_to_virt(paddr);
+ void *vaddr = page_address(page) + offset;
unsigned long uaddr;
unsigned int npages;
struct iommu_table *tbl = find_iommu_table(dev);
@@ -456,17 +459,18 @@ static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr,
uaddr = (unsigned long)vaddr;
npages = iommu_num_pages(uaddr, size, PAGE_SIZE);
- return iommu_alloc(dev, tbl, vaddr, npages, direction);
+ return iommu_alloc(dev, tbl, vaddr, npages, dir);
}
-static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle,
- size_t size, int direction)
+static void calgary_unmap_page(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
struct iommu_table *tbl = find_iommu_table(dev);
unsigned int npages;
- npages = iommu_num_pages(dma_handle, size, PAGE_SIZE);
- iommu_free(tbl, dma_handle, npages);
+ npages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
+ iommu_free(tbl, dma_addr, npages);
}
static void* calgary_alloc_coherent(struct device *dev, size_t size,
@@ -515,13 +519,13 @@ static void calgary_free_coherent(struct device *dev, size_t size,
free_pages((unsigned long)vaddr, get_order(size));
}
-static struct dma_mapping_ops calgary_dma_ops = {
+static struct dma_map_ops calgary_dma_ops = {
.alloc_coherent = calgary_alloc_coherent,
.free_coherent = calgary_free_coherent,
- .map_single = calgary_map_single,
- .unmap_single = calgary_unmap_single,
.map_sg = calgary_map_sg,
.unmap_sg = calgary_unmap_sg,
+ .map_page = calgary_map_page,
+ .unmap_page = calgary_unmap_page,
};
static inline void __iomem * busno_to_bbar(unsigned char num)
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index b25428533141..90f5b9ef5def 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -1,4 +1,5 @@
#include <linux/dma-mapping.h>
+#include <linux/dma-debug.h>
#include <linux/dmar.h>
#include <linux/bootmem.h>
#include <linux/pci.h>
@@ -12,7 +13,7 @@
static int forbid_dac __read_mostly;
-struct dma_mapping_ops *dma_ops;
+struct dma_map_ops *dma_ops;
EXPORT_SYMBOL(dma_ops);
static int iommu_sac_force __read_mostly;
@@ -44,6 +45,9 @@ struct device x86_dma_fallback_dev = {
};
EXPORT_SYMBOL(x86_dma_fallback_dev);
+/* Number of entries preallocated for DMA-API debugging */
+#define PREALLOC_DMA_DEBUG_ENTRIES 32768
+
int dma_set_mask(struct device *dev, u64 mask)
{
if (!dev->dma_mask || !dma_supported(dev, mask))
@@ -224,7 +228,7 @@ early_param("iommu", iommu_setup);
int dma_supported(struct device *dev, u64 mask)
{
- struct dma_mapping_ops *ops = get_dma_ops(dev);
+ struct dma_map_ops *ops = get_dma_ops(dev);
#ifdef CONFIG_PCI
if (mask > 0xffffffff && forbid_dac > 0) {
@@ -265,6 +269,12 @@ EXPORT_SYMBOL(dma_supported);
static int __init pci_iommu_init(void)
{
+ dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+
+#ifdef CONFIG_PCI
+ dma_debug_add_bus(&pci_bus_type);
+#endif
+
calgary_iommu_init();
intel_iommu_init();
@@ -290,8 +300,7 @@ fs_initcall(pci_iommu_init);
static __devinit void via_no_dac(struct pci_dev *dev)
{
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) {
- printk(KERN_INFO
- "PCI: VIA PCI bridge detected. Disabling DAC.\n");
+ dev_info(&dev->dev, "disabling DAC on VIA PCI bridge\n");
forbid_dac = 1;
}
}
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index d5768b1af080..b284b58c035c 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -255,10 +255,13 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
}
/* Map a single area into the IOMMU */
-static dma_addr_t
-gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir)
+static dma_addr_t gart_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
unsigned long bus;
+ phys_addr_t paddr = page_to_phys(page) + offset;
if (!dev)
dev = &x86_dma_fallback_dev;
@@ -275,8 +278,9 @@ gart_map_single(struct device *dev, phys_addr_t paddr, size_t size, int dir)
/*
* Free a DMA mapping.
*/
-static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
- size_t size, int direction)
+static void gart_unmap_page(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
unsigned long iommu_page;
int npages;
@@ -298,8 +302,8 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
/*
* Wrapper for pci_unmap_single working with scatterlists.
*/
-static void
-gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
+static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
{
struct scatterlist *s;
int i;
@@ -307,7 +311,7 @@ gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
for_each_sg(sg, s, nents, i) {
if (!s->dma_length || !s->length)
break;
- gart_unmap_single(dev, s->dma_address, s->dma_length, dir);
+ gart_unmap_page(dev, s->dma_address, s->dma_length, dir, NULL);
}
}
@@ -329,7 +333,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
addr = dma_map_area(dev, addr, s->length, dir, 0);
if (addr == bad_dma_address) {
if (i > 0)
- gart_unmap_sg(dev, sg, i, dir);
+ gart_unmap_sg(dev, sg, i, dir, NULL);
nents = 0;
sg[0].dma_length = 0;
break;
@@ -400,8 +404,8 @@ dma_map_cont(struct device *dev, struct scatterlist *start, int nelems,
* DMA map all entries in a scatterlist.
* Merge chunks that have page aligned sizes into a continuous mapping.
*/
-static int
-gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
+static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
{
struct scatterlist *s, *ps, *start_sg, *sgmap;
int need = 0, nextneed, i, out, start;
@@ -468,7 +472,7 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
error:
flush_gart();
- gart_unmap_sg(dev, sg, out, dir);
+ gart_unmap_sg(dev, sg, out, dir, NULL);
/* When it was forced or merged try again in a dumb way */
if (force_iommu || iommu_merge) {
@@ -521,7 +525,7 @@ static void
gart_free_coherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_addr)
{
- gart_unmap_single(dev, dma_addr, size, DMA_BIDIRECTIONAL);
+ gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL);
free_pages((unsigned long)vaddr, get_order(size));
}
@@ -707,11 +711,11 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
return -1;
}
-static struct dma_mapping_ops gart_dma_ops = {
- .map_single = gart_map_single,
- .unmap_single = gart_unmap_single,
+static struct dma_map_ops gart_dma_ops = {
.map_sg = gart_map_sg,
.unmap_sg = gart_unmap_sg,
+ .map_page = gart_map_page,
+ .unmap_page = gart_unmap_page,
.alloc_coherent = gart_alloc_coherent,
.free_coherent = gart_free_coherent,
};
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
index c70ab5a5d4c8..c6d703b39326 100644
--- a/arch/x86/kernel/pci-nommu.c
+++ b/arch/x86/kernel/pci-nommu.c
@@ -1,14 +1,14 @@
/* Fallback functions when the main IOMMU code is not compiled in. This
code is roughly equivalent to i386. */
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/string.h>
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/mm.h>
-#include <asm/iommu.h>
#include <asm/processor.h>
+#include <asm/iommu.h>
#include <asm/dma.h>
static int
@@ -25,19 +25,19 @@ check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size)
return 1;
}
-static dma_addr_t
-nommu_map_single(struct device *hwdev, phys_addr_t paddr, size_t size,
- int direction)
+static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
- dma_addr_t bus = paddr;
+ dma_addr_t bus = page_to_phys(page) + offset;
WARN_ON(size == 0);
- if (!check_addr("map_single", hwdev, bus, size))
- return bad_dma_address;
+ if (!check_addr("map_single", dev, bus, size))
+ return bad_dma_address;
flush_write_buffers();
return bus;
}
-
/* Map a set of buffers described by scatterlist in streaming
* mode for DMA. This is the scatter-gather version of the
* above pci_map_single interface. Here the scatter gather list
@@ -54,7 +54,8 @@ nommu_map_single(struct device *hwdev, phys_addr_t paddr, size_t size,
* the same here.
*/
static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
- int nents, int direction)
+ int nents, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
struct scatterlist *s;
int i;
@@ -78,12 +79,12 @@ static void nommu_free_coherent(struct device *dev, size_t size, void *vaddr,
free_pages((unsigned long)vaddr, get_order(size));
}
-struct dma_mapping_ops nommu_dma_ops = {
- .alloc_coherent = dma_generic_alloc_coherent,
- .free_coherent = nommu_free_coherent,
- .map_single = nommu_map_single,
- .map_sg = nommu_map_sg,
- .is_phys = 1,
+struct dma_map_ops nommu_dma_ops = {
+ .alloc_coherent = dma_generic_alloc_coherent,
+ .free_coherent = nommu_free_coherent,
+ .map_sg = nommu_map_sg,
+ .map_page = nommu_map_page,
+ .is_phys = 1,
};
void __init no_iommu_init(void)
diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb.c
index d59c91747665..34f12e9996ed 100644
--- a/arch/x86/kernel/pci-swiotlb_64.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -33,18 +33,11 @@ phys_addr_t swiotlb_bus_to_phys(dma_addr_t baddr)
return baddr;
}
-int __weak swiotlb_arch_range_needs_mapping(void *ptr, size_t size)
+int __weak swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size)
{
return 0;
}
-static dma_addr_t
-swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size,
- int direction)
-{
- return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction);
-}
-
static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, gfp_t flags)
{
@@ -57,20 +50,20 @@ static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags);
}
-struct dma_mapping_ops swiotlb_dma_ops = {
+struct dma_map_ops swiotlb_dma_ops = {
.mapping_error = swiotlb_dma_mapping_error,
.alloc_coherent = x86_swiotlb_alloc_coherent,
.free_coherent = swiotlb_free_coherent,
- .map_single = swiotlb_map_single_phys,
- .unmap_single = swiotlb_unmap_single,
.sync_single_for_cpu = swiotlb_sync_single_for_cpu,
.sync_single_for_device = swiotlb_sync_single_for_device,
.sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
.sync_single_range_for_device = swiotlb_sync_single_range_for_device,
.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
.sync_sg_for_device = swiotlb_sync_sg_for_device,
- .map_sg = swiotlb_map_sg,
- .unmap_sg = swiotlb_unmap_sg,
+ .map_sg = swiotlb_map_sg_attrs,
+ .unmap_sg = swiotlb_unmap_sg_attrs,
+ .map_page = swiotlb_map_page,
+ .unmap_page = swiotlb_unmap_page,
.dma_supported = NULL,
};
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 8c037051b353..ca989158e847 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -68,11 +68,11 @@ void exit_thread(void)
{
struct task_struct *me = current;
struct thread_struct *t = &me->thread;
+ unsigned long *bp = t->io_bitmap_ptr;
- if (me->thread.io_bitmap_ptr) {
+ if (bp) {
struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
- kfree(t->io_bitmap_ptr);
t->io_bitmap_ptr = NULL;
clear_thread_flag(TIF_IO_BITMAP);
/*
@@ -81,6 +81,7 @@ void exit_thread(void)
memset(tss->io_bitmap, 0xff, t->io_bitmap_max);
t->io_bitmap_max = 0;
put_cpu();
+ kfree(bp);
}
ds_exit_thread(current);
@@ -327,7 +328,7 @@ void stop_this_cpu(void *dummy)
/*
* Remove this CPU:
*/
- cpu_clear(smp_processor_id(), cpu_online_map);
+ set_cpu_online(smp_processor_id(), false);
disable_local_APIC();
for (;;) {
@@ -477,12 +478,13 @@ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
return 1;
}
-static cpumask_t c1e_mask = CPU_MASK_NONE;
+static cpumask_var_t c1e_mask;
static int c1e_detected;
void c1e_remove_cpu(int cpu)
{
- cpu_clear(cpu, c1e_mask);
+ if (c1e_mask != NULL)
+ cpumask_clear_cpu(cpu, c1e_mask);
}
/*
@@ -511,8 +513,8 @@ static void c1e_idle(void)
if (c1e_detected) {
int cpu = smp_processor_id();
- if (!cpu_isset(cpu, c1e_mask)) {
- cpu_set(cpu, c1e_mask);
+ if (!cpumask_test_cpu(cpu, c1e_mask)) {
+ cpumask_set_cpu(cpu, c1e_mask);
/*
* Force broadcast so ACPI can not interfere. Needs
* to run with interrupts enabled as it uses
@@ -564,6 +566,15 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
pm_idle = default_idle;
}
+void __init init_c1e_mask(void)
+{
+ /* If we're using c1e_idle, we need to allocate c1e_mask. */
+ if (pm_idle == c1e_idle) {
+ alloc_cpumask_var(&c1e_mask, GFP_KERNEL);
+ cpumask_clear(c1e_mask);
+ }
+}
+
static int __init idle_setup(char *str)
{
if (!str)
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 14014d766cad..76f8f84043a2 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -245,7 +245,7 @@ void prepare_to_copy(struct task_struct *tsk)
unlazy_fpu(tsk);
}
-int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+int copy_thread(unsigned long clone_flags, unsigned long sp,
unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index abb7e6a7f0c6..b751a41392b1 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -278,7 +278,7 @@ void prepare_to_copy(struct task_struct *tsk)
unlazy_fpu(tsk);
}
-int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+int copy_thread(unsigned long clone_flags, unsigned long sp,
unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 99749d6e87a8..fe9345c967de 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -686,9 +686,8 @@ static int ptrace_bts_config(struct task_struct *child,
if (!cfg.signal)
return -EINVAL;
- return -EOPNOTSUPP;
-
child->thread.bts_ovfl_signal = cfg.signal;
+ return -EOPNOTSUPP;
}
if ((cfg.flags & PTRACE_BTS_O_ALLOC) &&
@@ -1463,6 +1462,6 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
* system call instruction.
*/
if (test_thread_flag(TIF_SINGLESTEP) &&
- tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL))
+ tracehook_consider_fatal_signal(current, SIGTRAP))
send_sigtrap(current, regs, 0, TRAP_BRKPT);
}
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index 6a5a2970f4c5..e95022e4f5d5 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -171,7 +171,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_4,
ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_7,
ich_force_enable_hpet);
-
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x3a16, /* ICH10 */
+ ich_force_enable_hpet);
static struct pci_dev *cached_dev;
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index dd6f2b71561b..5d465b207e72 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -1,14 +1,14 @@
/*
* RTC related functions
*/
+#include <linux/platform_device.h>
+#include <linux/mc146818rtc.h>
#include <linux/acpi.h>
#include <linux/bcd.h>
-#include <linux/mc146818rtc.h>
-#include <linux/platform_device.h>
#include <linux/pnp.h>
-#include <asm/time.h>
#include <asm/vsyscall.h>
+#include <asm/time.h>
#ifdef CONFIG_X86_32
/*
@@ -16,9 +16,9 @@
* register we are working with. It is required for NMI access to the
* CMOS/RTC registers. See include/asm-i386/mc146818rtc.h for details.
*/
-volatile unsigned long cmos_lock = 0;
+volatile unsigned long cmos_lock;
EXPORT_SYMBOL(cmos_lock);
-#endif
+#endif /* CONFIG_X86_32 */
/* For two digit years assume time is always after that */
#define CMOS_YEARS_OFFS 2000
@@ -38,9 +38,9 @@ EXPORT_SYMBOL(rtc_lock);
*/
int mach_set_rtc_mmss(unsigned long nowtime)
{
- int retval = 0;
int real_seconds, real_minutes, cmos_minutes;
unsigned char save_control, save_freq_select;
+ int retval = 0;
/* tell the clock it's being set */
save_control = CMOS_READ(RTC_CONTROL);
@@ -72,8 +72,8 @@ int mach_set_rtc_mmss(unsigned long nowtime)
real_seconds = bin2bcd(real_seconds);
real_minutes = bin2bcd(real_minutes);
}
- CMOS_WRITE(real_seconds,RTC_SECONDS);
- CMOS_WRITE(real_minutes,RTC_MINUTES);
+ CMOS_WRITE(real_seconds, RTC_SECONDS);
+ CMOS_WRITE(real_minutes, RTC_MINUTES);
} else {
printk(KERN_WARNING
"set_rtc_mmss: can't update from %d to %d\n",
@@ -151,6 +151,7 @@ unsigned char rtc_cmos_read(unsigned char addr)
outb(addr, RTC_PORT(0));
val = inb(RTC_PORT(1));
lock_cmos_suffix(addr);
+
return val;
}
EXPORT_SYMBOL(rtc_cmos_read);
@@ -166,8 +167,8 @@ EXPORT_SYMBOL(rtc_cmos_write);
static int set_rtc_mmss(unsigned long nowtime)
{
- int retval;
unsigned long flags;
+ int retval;
spin_lock_irqsave(&rtc_lock, flags);
retval = set_wallclock(nowtime);
@@ -242,6 +243,7 @@ static __init int add_rtc_cmos(void)
platform_device_register(&rtc_device);
dev_info(&rtc_device.dev,
"registered platform RTC device (no PNP device found)\n");
+
return 0;
}
device_initcall(add_rtc_cmos);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f28c56e6bf94..b4158439bf63 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -112,8 +112,13 @@
#define ARCH_SETUP
#endif
+RESERVE_BRK(dmi_alloc, 65536);
+
unsigned int boot_cpu_id __read_mostly;
+static __initdata unsigned long _brk_start = (unsigned long)__brk_base;
+unsigned long _brk_end = (unsigned long)__brk_base;
+
#ifdef CONFIG_X86_64
int default_cpu_present_to_apicid(int mps_cpu)
{
@@ -158,12 +163,6 @@ static struct resource bss_resource = {
#ifdef CONFIG_X86_32
-/* This value is set up by the early boot code to point to the value
- immediately after the boot time page tables. It contains a *physical*
- address, and must not be in the .bss segment! */
-unsigned long init_pg_tables_start __initdata = ~0UL;
-unsigned long init_pg_tables_end __initdata = ~0UL;
-
static struct resource video_ram_resource = {
.name = "Video RAM area",
.start = 0xa0000,
@@ -219,12 +218,6 @@ unsigned long mmu_cr4_features = X86_CR4_PAE;
int bootloader_type;
/*
- * Early DMI memory
- */
-int dmi_alloc_index;
-char dmi_alloc_data[DMI_MAX_DATA];
-
-/*
* Setup options
*/
struct screen_info screen_info;
@@ -269,6 +262,35 @@ static inline void copy_edd(void)
}
#endif
+void * __init extend_brk(size_t size, size_t align)
+{
+ size_t mask = align - 1;
+ void *ret;
+
+ BUG_ON(_brk_start == 0);
+ BUG_ON(align & mask);
+
+ _brk_end = (_brk_end + mask) & ~mask;
+ BUG_ON((char *)(_brk_end + size) > __brk_limit);
+
+ ret = (void *)_brk_end;
+ _brk_end += size;
+
+ memset(ret, 0, size);
+
+ return ret;
+}
+
+static void __init reserve_brk(void)
+{
+ if (_brk_end > _brk_start)
+ reserve_early(__pa(_brk_start), __pa(_brk_end), "BRK");
+
+ /* Mark brk area as locked down and no longer taking any
+ new allocations */
+ _brk_start = 0;
+}
+
#ifdef CONFIG_BLK_DEV_INITRD
#ifdef CONFIG_X86_32
@@ -717,11 +739,7 @@ void __init setup_arch(char **cmdline_p)
init_mm.start_code = (unsigned long) _text;
init_mm.end_code = (unsigned long) _etext;
init_mm.end_data = (unsigned long) _edata;
-#ifdef CONFIG_X86_32
- init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
-#else
- init_mm.brk = (unsigned long) &_end;
-#endif
+ init_mm.brk = _brk_end;
code_resource.start = virt_to_phys(_text);
code_resource.end = virt_to_phys(_etext)-1;
@@ -842,6 +860,8 @@ void __init setup_arch(char **cmdline_p)
setup_bios_corruption_check();
#endif
+ reserve_brk();
+
/* max_pfn_mapped is updated here */
max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT);
max_pfn_mapped = max_low_pfn_mapped;
@@ -1029,7 +1049,6 @@ void __init x86_quirk_trap_init(void)
static struct irqaction irq0 = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
- .mask = CPU_MASK_NONE,
.name = "timer"
};
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index efa615f2bf43..3a97a4cf1872 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -153,7 +153,6 @@ static struct page * __init pcpur_get_page(unsigned int cpu, int pageno)
static ssize_t __init setup_pcpu_remap(size_t static_size)
{
static struct vm_struct vm;
- pg_data_t *last;
size_t ptrs_size, dyn_size;
unsigned int cpu;
ssize_t ret;
@@ -162,22 +161,9 @@ static ssize_t __init setup_pcpu_remap(size_t static_size)
* If large page isn't supported, there's no benefit in doing
* this. Also, on non-NUMA, embedding is better.
*/
- if (!cpu_has_pse || pcpu_need_numa())
+ if (!cpu_has_pse || !pcpu_need_numa())
return -EINVAL;
- last = NULL;
- for_each_possible_cpu(cpu) {
- int node = early_cpu_to_node(cpu);
-
- if (node_online(node) && NODE_DATA(node) &&
- last && last != NODE_DATA(node))
- goto proceed;
-
- last = NODE_DATA(node);
- }
- return -EINVAL;
-
-proceed:
/*
* Currently supports only single page. Supporting multiple
* pages won't be too difficult if it ever becomes necessary.
@@ -233,8 +219,8 @@ proceed:
"%zu bytes\n", vm.addr, static_size);
ret = pcpu_setup_first_chunk(pcpur_get_page, static_size,
- PERCPU_FIRST_CHUNK_RESERVE,
- PMD_SIZE, dyn_size, vm.addr, NULL);
+ PERCPU_FIRST_CHUNK_RESERVE, dyn_size,
+ PMD_SIZE, vm.addr, NULL);
goto out_free_ar;
enomem:
@@ -257,31 +243,13 @@ static ssize_t __init setup_pcpu_remap(size_t static_size)
* Embedding allocator
*
* The first chunk is sized to just contain the static area plus
- * module and dynamic reserves, and allocated as a contiguous area
- * using bootmem allocator and used as-is without being mapped into
- * vmalloc area. This enables the first chunk to piggy back on the
- * linear physical PMD mapping and doesn't add any additional pressure
- * to TLB. Note that if the needed size is smaller than the minimum
- * unit size, the leftover is returned to the bootmem allocator.
+ * module and dynamic reserves and embedded into linear physical
+ * mapping so that it can use PMD mapping without additional TLB
+ * pressure.
*/
-static void *pcpue_ptr __initdata;
-static size_t pcpue_size __initdata;
-static size_t pcpue_unit_size __initdata;
-
-static struct page * __init pcpue_get_page(unsigned int cpu, int pageno)
-{
- size_t off = (size_t)pageno << PAGE_SHIFT;
-
- if (off >= pcpue_size)
- return NULL;
-
- return virt_to_page(pcpue_ptr + cpu * pcpue_unit_size + off);
-}
-
static ssize_t __init setup_pcpu_embed(size_t static_size)
{
- unsigned int cpu;
- size_t dyn_size;
+ size_t reserve = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE;
/*
* If large page isn't supported, there's no benefit in doing
@@ -291,33 +259,8 @@ static ssize_t __init setup_pcpu_embed(size_t static_size)
if (!cpu_has_pse || pcpu_need_numa())
return -EINVAL;
- /* allocate and copy */
- pcpue_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE +
- PERCPU_DYNAMIC_RESERVE);
- pcpue_unit_size = max_t(size_t, pcpue_size, PCPU_MIN_UNIT_SIZE);
- dyn_size = pcpue_size - static_size - PERCPU_FIRST_CHUNK_RESERVE;
-
- pcpue_ptr = pcpu_alloc_bootmem(0, num_possible_cpus() * pcpue_unit_size,
- PAGE_SIZE);
- if (!pcpue_ptr)
- return -ENOMEM;
-
- for_each_possible_cpu(cpu) {
- void *ptr = pcpue_ptr + cpu * pcpue_unit_size;
-
- free_bootmem(__pa(ptr + pcpue_size),
- pcpue_unit_size - pcpue_size);
- memcpy(ptr, __per_cpu_load, static_size);
- }
-
- /* we're ready, commit */
- pr_info("PERCPU: Embedded %zu pages at %p, static data %zu bytes\n",
- pcpue_size >> PAGE_SHIFT, pcpue_ptr, static_size);
-
- return pcpu_setup_first_chunk(pcpue_get_page, static_size,
- PERCPU_FIRST_CHUNK_RESERVE,
- pcpue_unit_size, dyn_size,
- pcpue_ptr, NULL);
+ return pcpu_embed_first_chunk(static_size, PERCPU_FIRST_CHUNK_RESERVE,
+ reserve - PERCPU_FIRST_CHUNK_RESERVE, -1);
}
/*
@@ -375,8 +318,8 @@ static ssize_t __init setup_pcpu_4k(size_t static_size)
pcpu4k_nr_static_pages, static_size);
ret = pcpu_setup_first_chunk(pcpu4k_get_page, static_size,
- PERCPU_FIRST_CHUNK_RESERVE, -1, -1, NULL,
- pcpu4k_populate_pte);
+ PERCPU_FIRST_CHUNK_RESERVE, -1,
+ -1, NULL, pcpu4k_populate_pte);
goto out_free_ar;
enomem:
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index d2cc6428c587..14425166b8e3 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -211,31 +211,27 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
{
/* Default to using normal stack */
unsigned long sp = regs->sp;
+ int onsigstack = on_sig_stack(sp);
#ifdef CONFIG_X86_64
/* redzone */
sp -= 128;
#endif /* CONFIG_X86_64 */
- /*
- * If we are on the alternate signal stack and would overflow it, don't.
- * Return an always-bogus address instead so we will die with SIGSEGV.
- */
- if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
- return (void __user *) -1L;
-
- /* This is the X/Open sanctioned signal stack switching. */
- if (ka->sa.sa_flags & SA_ONSTACK) {
- if (sas_ss_flags(sp) == 0)
- sp = current->sas_ss_sp + current->sas_ss_size;
- } else {
+ if (!onsigstack) {
+ /* This is the X/Open sanctioned signal stack switching. */
+ if (ka->sa.sa_flags & SA_ONSTACK) {
+ if (current->sas_ss_size)
+ sp = current->sas_ss_sp + current->sas_ss_size;
+ } else {
#ifdef CONFIG_X86_32
- /* This is the legacy signal stack switching. */
- if ((regs->ss & 0xffff) != __USER_DS &&
- !(ka->sa.sa_flags & SA_RESTORER) &&
- ka->sa.sa_restorer)
- sp = (unsigned long) ka->sa.sa_restorer;
+ /* This is the legacy signal stack switching. */
+ if ((regs->ss & 0xffff) != __USER_DS &&
+ !(ka->sa.sa_flags & SA_RESTORER) &&
+ ka->sa.sa_restorer)
+ sp = (unsigned long) ka->sa.sa_restorer;
#endif /* CONFIG_X86_32 */
+ }
}
if (used_math()) {
@@ -244,12 +240,22 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
sp = round_down(sp, 64);
#endif /* CONFIG_X86_64 */
*fpstate = (void __user *)sp;
-
- if (save_i387_xstate(*fpstate) < 0)
- return (void __user *)-1L;
}
- return (void __user *)align_sigframe(sp - frame_size);
+ sp = align_sigframe(sp - frame_size);
+
+ /*
+ * If we are on the alternate signal stack and would overflow it, don't.
+ * Return an always-bogus address instead so we will die with SIGSEGV.
+ */
+ if (onsigstack && !likely(on_sig_stack(sp)))
+ return (void __user *)-1L;
+
+ /* save i387 state */
+ if (used_math() && save_i387_xstate(*fpstate) < 0)
+ return (void __user *)-1L;
+
+ return (void __user *)sp;
}
#ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index ef7d10170c30..58d24ef917d8 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -101,11 +101,11 @@ EXPORT_SYMBOL(smp_num_siblings);
DEFINE_PER_CPU(u16, cpu_llc_id) = BAD_APICID;
/* representing HT siblings of each logical CPU */
-DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
+DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map);
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
/* representing HT and core siblings of each logical CPU */
-DEFINE_PER_CPU(cpumask_t, cpu_core_map);
+DEFINE_PER_CPU(cpumask_var_t, cpu_core_map);
EXPORT_PER_CPU_SYMBOL(cpu_core_map);
/* Per CPU bogomips and other parameters */
@@ -115,11 +115,6 @@ EXPORT_PER_CPU_SYMBOL(cpu_info);
atomic_t init_deasserted;
#if defined(CONFIG_NUMA) && defined(CONFIG_X86_32)
-
-/* which logical CPUs are on which nodes */
-cpumask_t node_to_cpumask_map[MAX_NUMNODES] __read_mostly =
- { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
-EXPORT_SYMBOL(node_to_cpumask_map);
/* which node each logical CPU is on */
int cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
EXPORT_SYMBOL(cpu_to_node_map);
@@ -128,7 +123,7 @@ EXPORT_SYMBOL(cpu_to_node_map);
static void map_cpu_to_node(int cpu, int node)
{
printk(KERN_INFO "Mapping cpu %d to node %d\n", cpu, node);
- cpumask_set_cpu(cpu, &node_to_cpumask_map[node]);
+ cpumask_set_cpu(cpu, node_to_cpumask_map[node]);
cpu_to_node_map[cpu] = node;
}
@@ -139,7 +134,7 @@ static void unmap_cpu_to_node(int cpu)
printk(KERN_INFO "Unmapping cpu %d from all nodes\n", cpu);
for (node = 0; node < MAX_NUMNODES; node++)
- cpumask_clear_cpu(cpu, &node_to_cpumask_map[node]);
+ cpumask_clear_cpu(cpu, node_to_cpumask_map[node]);
cpu_to_node_map[cpu] = 0;
}
#else /* !(CONFIG_NUMA && CONFIG_X86_32) */
@@ -301,7 +296,7 @@ notrace static void __cpuinit start_secondary(void *unused)
__flush_tlb_all();
#endif
- /* This must be done before setting cpu_online_map */
+ /* This must be done before setting cpu_online_mask */
set_cpu_sibling_map(raw_smp_processor_id());
wmb();
@@ -334,6 +329,23 @@ notrace static void __cpuinit start_secondary(void *unused)
cpu_idle();
}
+#ifdef CONFIG_CPUMASK_OFFSTACK
+/* In this case, llc_shared_map is a pointer to a cpumask. */
+static inline void copy_cpuinfo_x86(struct cpuinfo_x86 *dst,
+ const struct cpuinfo_x86 *src)
+{
+ struct cpumask *llc = dst->llc_shared_map;
+ *dst = *src;
+ dst->llc_shared_map = llc;
+}
+#else
+static inline void copy_cpuinfo_x86(struct cpuinfo_x86 *dst,
+ const struct cpuinfo_x86 *src)
+{
+ *dst = *src;
+}
+#endif /* CONFIG_CPUMASK_OFFSTACK */
+
/*
* The bootstrap kernel entry code has set these up. Save them for
* a given CPU
@@ -343,7 +355,7 @@ void __cpuinit smp_store_cpu_info(int id)
{
struct cpuinfo_x86 *c = &cpu_data(id);
- *c = boot_cpu_data;
+ copy_cpuinfo_x86(c, &boot_cpu_data);
c->cpu_index = id;
if (id != 0)
identify_secondary_cpu(c);
@@ -367,15 +379,15 @@ void __cpuinit set_cpu_sibling_map(int cpu)
cpumask_set_cpu(cpu, cpu_sibling_mask(i));
cpumask_set_cpu(i, cpu_core_mask(cpu));
cpumask_set_cpu(cpu, cpu_core_mask(i));
- cpumask_set_cpu(i, &c->llc_shared_map);
- cpumask_set_cpu(cpu, &o->llc_shared_map);
+ cpumask_set_cpu(i, c->llc_shared_map);
+ cpumask_set_cpu(cpu, o->llc_shared_map);
}
}
} else {
cpumask_set_cpu(cpu, cpu_sibling_mask(cpu));
}
- cpumask_set_cpu(cpu, &c->llc_shared_map);
+ cpumask_set_cpu(cpu, c->llc_shared_map);
if (current_cpu_data.x86_max_cores == 1) {
cpumask_copy(cpu_core_mask(cpu), cpu_sibling_mask(cpu));
@@ -386,8 +398,8 @@ void __cpuinit set_cpu_sibling_map(int cpu)
for_each_cpu(i, cpu_sibling_setup_mask) {
if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
- cpumask_set_cpu(i, &c->llc_shared_map);
- cpumask_set_cpu(cpu, &cpu_data(i).llc_shared_map);
+ cpumask_set_cpu(i, c->llc_shared_map);
+ cpumask_set_cpu(cpu, cpu_data(i).llc_shared_map);
}
if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
cpumask_set_cpu(i, cpu_core_mask(cpu));
@@ -425,12 +437,7 @@ const struct cpumask *cpu_coregroup_mask(int cpu)
if (sched_mc_power_savings || sched_smt_power_savings)
return cpu_core_mask(cpu);
else
- return &c->llc_shared_map;
-}
-
-cpumask_t cpu_coregroup_map(int cpu)
-{
- return *cpu_coregroup_mask(cpu);
+ return c->llc_shared_map;
}
static void impress_friends(void)
@@ -897,9 +904,8 @@ int __cpuinit native_cpu_up(unsigned int cpu)
*/
static __init void disable_smp(void)
{
- /* use the read/write pointers to the present and possible maps */
- cpumask_copy(&cpu_present_map, cpumask_of(0));
- cpumask_copy(&cpu_possible_map, cpumask_of(0));
+ init_cpu_present(cpumask_of(0));
+ init_cpu_possible(cpumask_of(0));
smpboot_clear_io_apic_irqs();
if (smp_found_config)
@@ -1031,6 +1037,8 @@ static void __init smp_cpu_index_default(void)
*/
void __init native_smp_prepare_cpus(unsigned int max_cpus)
{
+ unsigned int i;
+
preempt_disable();
smp_cpu_index_default();
current_cpu_data = boot_cpu_data;
@@ -1044,6 +1052,14 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
boot_cpu_logical_apicid = logical_smp_processor_id();
#endif
current_thread_info()->cpu = 0; /* needed? */
+ for_each_possible_cpu(i) {
+ alloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL);
+ alloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL);
+ alloc_cpumask_var(&cpu_data(i).llc_shared_map, GFP_KERNEL);
+ cpumask_clear(per_cpu(cpu_core_map, i));
+ cpumask_clear(per_cpu(cpu_sibling_map, i));
+ cpumask_clear(cpu_data(i).llc_shared_map);
+ }
set_cpu_sibling_map(0);
enable_IR_x2apic();
@@ -1132,11 +1148,11 @@ early_param("possible_cpus", _setup_possible_cpus);
/*
- * cpu_possible_map should be static, it cannot change as cpu's
+ * cpu_possible_mask should be static, it cannot change as cpu's
* are onlined, or offlined. The reason is per-cpu data-structures
* are allocated by some modules at init time, and dont expect to
* do this dynamically on cpu arrival/departure.
- * cpu_present_map on the other hand can change dynamically.
+ * cpu_present_mask on the other hand can change dynamically.
* In case when cpu_hotplug is not compiled, then we resort to current
* behaviour, which is cpu_possible == cpu_present.
* - Ashok Raj
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
index 3bdb64829b82..ff5c8736b491 100644
--- a/arch/x86/kernel/syscall_table_32.S
+++ b/arch/x86/kernel/syscall_table_32.S
@@ -332,3 +332,5 @@ ENTRY(sys_call_table)
.long sys_dup3 /* 330 */
.long sys_pipe2
.long sys_inotify_init1
+ .long sys_preadv
+ .long sys_pwritev
diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c
index 241ec3923f61..5ba343e61844 100644
--- a/arch/x86/kernel/time_64.c
+++ b/arch/x86/kernel/time_64.c
@@ -116,7 +116,6 @@ unsigned long __init calibrate_cpu(void)
static struct irqaction irq0 = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER,
- .mask = CPU_MASK_NONE,
.name = "timer"
};
@@ -125,7 +124,6 @@ void __init hpet_time_init(void)
if (!hpet_enable())
setup_pit_timer();
- irq0.mask = cpumask_of_cpu(0);
setup_irq(0, &irq0);
}
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index d038b9c45cf8..deb5ebb32c3b 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -275,6 +275,8 @@ const struct cpumask *uv_flush_send_and_wait(int cpu, int this_blade,
return NULL;
}
+static DEFINE_PER_CPU(cpumask_var_t, uv_flush_tlb_mask);
+
/**
* uv_flush_tlb_others - globally purge translation cache of a virtual
* address or all TLB's
@@ -304,8 +306,7 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
struct mm_struct *mm,
unsigned long va, unsigned int cpu)
{
- static DEFINE_PER_CPU(cpumask_t, flush_tlb_mask);
- struct cpumask *flush_mask = &__get_cpu_var(flush_tlb_mask);
+ struct cpumask *flush_mask = __get_cpu_var(uv_flush_tlb_mask);
int i;
int bit;
int blade;
@@ -750,16 +751,21 @@ static int __init uv_bau_init(void)
int node;
int nblades;
int last_blade;
- int cur_cpu = 0;
+ int cur_cpu;
if (!is_uv_system())
return 0;
+ for_each_possible_cpu(cur_cpu)
+ alloc_cpumask_var_node(&per_cpu(uv_flush_tlb_mask, cur_cpu),
+ GFP_KERNEL, cpu_to_node(cur_cpu));
+
uv_bau_retry_limit = 1;
uv_nshift = uv_hub_info->n_val;
uv_mmask = (1UL << uv_hub_info->n_val) - 1;
nblades = 0;
last_blade = -1;
+ cur_cpu = 0;
for_each_online_node(node) {
blade = uv_node_to_blade_id(node);
if (blade == last_blade)
diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index 0fcc95a354f7..7e4515957a1c 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -25,10 +25,10 @@
*
* Send feedback to <colpatch@us.ibm.com>
*/
-#include <linux/init.h>
-#include <linux/smp.h>
#include <linux/nodemask.h>
#include <linux/mmzone.h>
+#include <linux/init.h>
+#include <linux/smp.h>
#include <asm/cpu.h>
static DEFINE_PER_CPU(struct x86_cpu, cpu_devices);
@@ -47,6 +47,7 @@ int __ref arch_register_cpu(int num)
*/
if (num)
per_cpu(cpu_devices, num).cpu.hotpluggable = 1;
+
return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
}
EXPORT_SYMBOL(arch_register_cpu);
@@ -56,12 +57,13 @@ void arch_unregister_cpu(int num)
unregister_cpu(&per_cpu(cpu_devices, num).cpu);
}
EXPORT_SYMBOL(arch_unregister_cpu);
-#else
+#else /* CONFIG_HOTPLUG_CPU */
+
static int __init arch_register_cpu(int num)
{
return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
}
-#endif /*CONFIG_HOTPLUG_CPU*/
+#endif /* CONFIG_HOTPLUG_CPU */
static int __init topology_init(void)
{
@@ -70,11 +72,11 @@ static int __init topology_init(void)
#ifdef CONFIG_NUMA
for_each_online_node(i)
register_one_node(i);
-#endif /* CONFIG_NUMA */
+#endif
for_each_present_cpu(i)
arch_register_cpu(i);
+
return 0;
}
-
subsys_initcall(topology_init);
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 462b9ba67e92..7a567ebe6361 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -17,20 +17,21 @@
#include <asm/delay.h>
#include <asm/hypervisor.h>
-unsigned int cpu_khz; /* TSC clocks / usec, not used here */
+unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */
EXPORT_SYMBOL(cpu_khz);
-unsigned int tsc_khz;
+
+unsigned int __read_mostly tsc_khz;
EXPORT_SYMBOL(tsc_khz);
/*
* TSC can be unstable due to cpufreq or due to unsynced TSCs
*/
-static int tsc_unstable;
+static int __read_mostly tsc_unstable;
/* native_sched_clock() is called before tsc_init(), so
we must start with the TSC soft disabled to prevent
erroneous rdtsc usage on !cpu_has_tsc processors */
-static int tsc_disabled = -1;
+static int __read_mostly tsc_disabled = -1;
static int tsc_clocksource_reliable;
/*
@@ -543,8 +544,6 @@ unsigned long native_calibrate_tsc(void)
return tsc_pit_min;
}
-#ifdef CONFIG_X86_32
-/* Only called from the Powernow K7 cpu freq driver */
int recalibrate_cpu_khz(void)
{
#ifndef CONFIG_SMP
@@ -566,7 +565,6 @@ int recalibrate_cpu_khz(void)
EXPORT_SYMBOL(recalibrate_cpu_khz);
-#endif /* CONFIG_X86_32 */
/* Accelerators for sched_clock()
* convert from cycles(64bits) => nanoseconds (64bits)
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
index 2cc4a90e2cb3..95deb9f2211e 100644
--- a/arch/x86/kernel/vmi_32.c
+++ b/arch/x86/kernel/vmi_32.c
@@ -395,11 +395,6 @@ static void vmi_set_pte_atomic(pte_t *ptep, pte_t pteval)
vmi_ops.update_pte(ptep, VMI_PAGE_PT);
}
-static void vmi_set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
-{
- vmi_ops.set_pte(pte, ptep, vmi_flags_addr_defer(mm, addr, VMI_PAGE_PT, 1));
-}
-
static void vmi_set_pud(pud_t *pudp, pud_t pudval)
{
/* Um, eww */
@@ -750,7 +745,6 @@ static inline int __init activate_vmi(void)
pv_mmu_ops.set_pmd = vmi_set_pmd;
#ifdef CONFIG_X86_PAE
pv_mmu_ops.set_pte_atomic = vmi_set_pte_atomic;
- pv_mmu_ops.set_pte_present = vmi_set_pte_present;
pv_mmu_ops.set_pud = vmi_set_pud;
pv_mmu_ops.pte_clear = vmi_pte_clear;
pv_mmu_ops.pmd_clear = vmi_pmd_clear;
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c
index 33a788d5879c..d303369a7bad 100644
--- a/arch/x86/kernel/vmiclock_32.c
+++ b/arch/x86/kernel/vmiclock_32.c
@@ -202,7 +202,6 @@ static struct irqaction vmi_clock_action = {
.name = "vmi-timer",
.handler = vmi_timer_interrupt,
.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
- .mask = CPU_MASK_ALL,
};
static void __devinit vmi_time_init_clockevent(void)
diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S
index 0d860963f268..62ad500d55f3 100644
--- a/arch/x86/kernel/vmlinux_32.lds.S
+++ b/arch/x86/kernel/vmlinux_32.lds.S
@@ -189,15 +189,24 @@ SECTIONS
*(.bss)
. = ALIGN(4);
__bss_stop = .;
- _end = . ;
- /* This is where the kernel creates the early boot page tables */
+ }
+
+ .brk : AT(ADDR(.brk) - LOAD_OFFSET) {
. = ALIGN(PAGE_SIZE);
- pg0 = . ;
+ __brk_base = . ;
+ . += 64 * 1024 ; /* 64k alignment slop space */
+ *(.brk_reservation) /* areas brk users have reserved */
+ __brk_limit = . ;
+ }
+
+ .end : AT(ADDR(.end) - LOAD_OFFSET) {
+ _end = . ;
}
/* Sections to be discarded */
/DISCARD/ : {
*(.exitcall.exit)
+ *(.discard)
}
STABS_DEBUG
@@ -205,6 +214,12 @@ SECTIONS
DWARF_DEBUG
}
+/*
+ * Build-time check on the image size:
+ */
+ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),
+ "kernel image bigger than KERNEL_IMAGE_SIZE")
+
#ifdef CONFIG_KEXEC
/* Link time checks */
#include <asm/kexec.h>
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
index 5bf54e40c6ef..c8742507b030 100644
--- a/arch/x86/kernel/vmlinux_64.lds.S
+++ b/arch/x86/kernel/vmlinux_64.lds.S
@@ -29,8 +29,8 @@ SECTIONS
{
. = __START_KERNEL;
phys_startup_64 = startup_64 - LOAD_OFFSET;
- _text = .; /* Text and read-only data */
.text : AT(ADDR(.text) - LOAD_OFFSET) {
+ _text = .; /* Text and read-only data */
/* First the code that has to be first for bootstrapping */
*(.text.head)
_stext = .;
@@ -61,13 +61,13 @@ SECTIONS
.data : AT(ADDR(.data) - LOAD_OFFSET) {
DATA_DATA
CONSTRUCTORS
+ _edata = .; /* End of data section */
} :data
- _edata = .; /* End of data section */
- . = ALIGN(PAGE_SIZE);
- . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
+ . = ALIGN(PAGE_SIZE);
+ . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
*(.data.cacheline_aligned)
}
. = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES);
@@ -125,29 +125,29 @@ SECTIONS
#undef VVIRT_OFFSET
#undef VVIRT
- . = ALIGN(THREAD_SIZE); /* init_task */
.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
+ . = ALIGN(THREAD_SIZE); /* init_task */
*(.data.init_task)
}:data.init
- . = ALIGN(PAGE_SIZE);
.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
+ . = ALIGN(PAGE_SIZE);
*(.data.page_aligned)
}
- /* might get freed after init */
- . = ALIGN(PAGE_SIZE);
- __smp_alt_begin = .;
- __smp_locks = .;
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
+ /* might get freed after init */
+ . = ALIGN(PAGE_SIZE);
+ __smp_alt_begin = .;
+ __smp_locks = .;
*(.smp_locks)
+ __smp_locks_end = .;
+ . = ALIGN(PAGE_SIZE);
+ __smp_alt_end = .;
}
- __smp_locks_end = .;
- . = ALIGN(PAGE_SIZE);
- __smp_alt_end = .;
. = ALIGN(PAGE_SIZE); /* Init code and data */
- __init_begin = .;
+ __init_begin = .; /* paired with __init_end */
.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
_sinittext = .;
INIT_TEXT
@@ -159,40 +159,42 @@ SECTIONS
__initdata_end = .;
}
- . = ALIGN(16);
- __setup_start = .;
- .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
- __setup_end = .;
- __initcall_start = .;
+ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
+ . = ALIGN(16);
+ __setup_start = .;
+ *(.init.setup)
+ __setup_end = .;
+ }
.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
+ __initcall_start = .;
INITCALLS
+ __initcall_end = .;
}
- __initcall_end = .;
- __con_initcall_start = .;
.con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
+ __con_initcall_start = .;
*(.con_initcall.init)
+ __con_initcall_end = .;
}
- __con_initcall_end = .;
- __x86_cpu_dev_start = .;
.x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
+ __x86_cpu_dev_start = .;
*(.x86_cpu_dev.init)
+ __x86_cpu_dev_end = .;
}
- __x86_cpu_dev_end = .;
SECURITY_INIT
. = ALIGN(8);
.parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
- __parainstructions = .;
+ __parainstructions = .;
*(.parainstructions)
- __parainstructions_end = .;
+ __parainstructions_end = .;
}
- . = ALIGN(8);
- __alt_instructions = .;
.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
+ . = ALIGN(8);
+ __alt_instructions = .;
*(.altinstructions)
+ __alt_instructions_end = .;
}
- __alt_instructions_end = .;
.altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
*(.altinstr_replacement)
}
@@ -207,9 +209,11 @@ SECTIONS
#ifdef CONFIG_BLK_DEV_INITRD
. = ALIGN(PAGE_SIZE);
- __initramfs_start = .;
- .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
- __initramfs_end = .;
+ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
+ __initramfs_start = .;
+ *(.init.ramfs)
+ __initramfs_end = .;
+ }
#endif
#ifdef CONFIG_SMP
@@ -229,20 +233,29 @@ SECTIONS
. = ALIGN(PAGE_SIZE);
__init_end = .;
- . = ALIGN(PAGE_SIZE);
- __nosave_begin = .;
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
- *(.data.nosave)
+ . = ALIGN(PAGE_SIZE);
+ __nosave_begin = .;
+ *(.data.nosave)
+ . = ALIGN(PAGE_SIZE);
+ __nosave_end = .;
} :data.init2 /* use another section data.init2, see PERCPU_VADDR() above */
- . = ALIGN(PAGE_SIZE);
- __nosave_end = .;
- __bss_start = .; /* BSS */
.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
+ . = ALIGN(PAGE_SIZE);
+ __bss_start = .; /* BSS */
*(.bss.page_aligned)
*(.bss)
- }
- __bss_stop = .;
+ __bss_stop = .;
+ }
+
+ .brk : AT(ADDR(.brk) - LOAD_OFFSET) {
+ . = ALIGN(PAGE_SIZE);
+ __brk_base = . ;
+ . += 64 * 1024 ; /* 64k alignment slop space */
+ *(.brk_reservation) /* areas brk users have reserved */
+ __brk_limit = . ;
+ }
_end = . ;
@@ -250,6 +263,7 @@ SECTIONS
/DISCARD/ : {
*(.exitcall.exit)
*(.eh_frame)
+ *(.discard)
}
STABS_DEBUG
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c
index 74de562812cc..a1d804bcd483 100644
--- a/arch/x86/kernel/vsmp_64.c
+++ b/arch/x86/kernel/vsmp_64.c
@@ -22,7 +22,7 @@
#include <asm/paravirt.h>
#include <asm/setup.h>
-#ifdef CONFIG_PARAVIRT
+#if defined CONFIG_PCI && defined CONFIG_PARAVIRT
/*
* Interrupt control on vSMPowered systems:
* ~AC is a shadow of IF. If IF is 'on' AC should be 'off'
@@ -114,6 +114,7 @@ static void __init set_vsmp_pv_ops(void)
}
#endif
+#ifdef CONFIG_PCI
static int is_vsmp = -1;
static void __init detect_vsmp_box(void)
@@ -139,6 +140,15 @@ int is_vsmp_box(void)
}
}
+#else
+static void __init detect_vsmp_box(void)
+{
+}
+int is_vsmp_box(void)
+{
+ return 0;
+}
+#endif
void __init vsmp_init(void)
{
detect_vsmp_box();
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index c7da3683f4c5..a58504ea78cc 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -4,6 +4,10 @@
config HAVE_KVM
bool
+config HAVE_KVM_IRQCHIP
+ bool
+ default y
+
menuconfig VIRTUALIZATION
bool "Virtualization"
depends on HAVE_KVM || X86
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 72bd275a9b5c..c13bb92d3157 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -201,6 +201,9 @@ static int __pit_timer_fn(struct kvm_kpit_state *ps)
if (!atomic_inc_and_test(&pt->pending))
set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests);
+ if (!pt->reinject)
+ atomic_set(&pt->pending, 1);
+
if (vcpu0 && waitqueue_active(&vcpu0->wq))
wake_up_interruptible(&vcpu0->wq);
@@ -536,6 +539,16 @@ void kvm_pit_reset(struct kvm_pit *pit)
pit->pit_state.irq_ack = 1;
}
+static void pit_mask_notifer(struct kvm_irq_mask_notifier *kimn, bool mask)
+{
+ struct kvm_pit *pit = container_of(kimn, struct kvm_pit, mask_notifier);
+
+ if (!mask) {
+ atomic_set(&pit->pit_state.pit_timer.pending, 0);
+ pit->pit_state.irq_ack = 1;
+ }
+}
+
struct kvm_pit *kvm_create_pit(struct kvm *kvm)
{
struct kvm_pit *pit;
@@ -545,9 +558,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
if (!pit)
return NULL;
- mutex_lock(&kvm->lock);
pit->irq_source_id = kvm_request_irq_source_id(kvm);
- mutex_unlock(&kvm->lock);
if (pit->irq_source_id < 0) {
kfree(pit);
return NULL;
@@ -580,10 +591,14 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
pit_state->irq_ack_notifier.gsi = 0;
pit_state->irq_ack_notifier.irq_acked = kvm_pit_ack_irq;
kvm_register_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
+ pit_state->pit_timer.reinject = true;
mutex_unlock(&pit->pit_state.lock);
kvm_pit_reset(pit);
+ pit->mask_notifier.func = pit_mask_notifer;
+ kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
+
return pit;
}
@@ -592,6 +607,8 @@ void kvm_free_pit(struct kvm *kvm)
struct hrtimer *timer;
if (kvm->arch.vpit) {
+ kvm_unregister_irq_mask_notifier(kvm, 0,
+ &kvm->arch.vpit->mask_notifier);
mutex_lock(&kvm->arch.vpit->pit_state.lock);
timer = &kvm->arch.vpit->pit_state.pit_timer.timer;
hrtimer_cancel(timer);
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index 4178022b97aa..6acbe4b505d5 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -9,6 +9,7 @@ struct kvm_kpit_timer {
s64 period; /* unit: ns */
s64 scheduled;
atomic_t pending;
+ bool reinject;
};
struct kvm_kpit_channel_state {
@@ -45,6 +46,7 @@ struct kvm_pit {
struct kvm *kvm;
struct kvm_kpit_state pit_state;
int irq_source_id;
+ struct kvm_irq_mask_notifier mask_notifier;
};
#define KVM_PIT_BASE_ADDRESS 0x40
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index 179dcb0103fd..1ccb50c74f18 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -32,11 +32,13 @@
#include <linux/kvm_host.h>
static void pic_lock(struct kvm_pic *s)
+ __acquires(&s->lock)
{
spin_lock(&s->lock);
}
static void pic_unlock(struct kvm_pic *s)
+ __releases(&s->lock)
{
struct kvm *kvm = s->kvm;
unsigned acks = s->pending_acks;
@@ -49,7 +51,8 @@ static void pic_unlock(struct kvm_pic *s)
spin_unlock(&s->lock);
while (acks) {
- kvm_notify_acked_irq(kvm, __ffs(acks));
+ kvm_notify_acked_irq(kvm, SELECT_PIC(__ffs(acks)),
+ __ffs(acks));
acks &= acks - 1;
}
@@ -76,12 +79,13 @@ void kvm_pic_clear_isr_ack(struct kvm *kvm)
/*
* set irq level. If an edge is detected, then the IRR is set to 1
*/
-static inline void pic_set_irq1(struct kvm_kpic_state *s, int irq, int level)
+static inline int pic_set_irq1(struct kvm_kpic_state *s, int irq, int level)
{
- int mask;
+ int mask, ret = 1;
mask = 1 << irq;
if (s->elcr & mask) /* level triggered */
if (level) {
+ ret = !(s->irr & mask);
s->irr |= mask;
s->last_irr |= mask;
} else {
@@ -90,11 +94,15 @@ static inline void pic_set_irq1(struct kvm_kpic_state *s, int irq, int level)
}
else /* edge triggered */
if (level) {
- if ((s->last_irr & mask) == 0)
+ if ((s->last_irr & mask) == 0) {
+ ret = !(s->irr & mask);
s->irr |= mask;
+ }
s->last_irr |= mask;
} else
s->last_irr &= ~mask;
+
+ return (s->imr & mask) ? -1 : ret;
}
/*
@@ -171,16 +179,19 @@ void kvm_pic_update_irq(struct kvm_pic *s)
pic_unlock(s);
}
-void kvm_pic_set_irq(void *opaque, int irq, int level)
+int kvm_pic_set_irq(void *opaque, int irq, int level)
{
struct kvm_pic *s = opaque;
+ int ret = -1;
pic_lock(s);
if (irq >= 0 && irq < PIC_NUM_PINS) {
- pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
+ ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
pic_update_irq(s);
}
pic_unlock(s);
+
+ return ret;
}
/*
@@ -232,7 +243,7 @@ int kvm_pic_read_irq(struct kvm *kvm)
}
pic_update_irq(s);
pic_unlock(s);
- kvm_notify_acked_irq(kvm, irq);
+ kvm_notify_acked_irq(kvm, SELECT_PIC(irq), irq);
return intno;
}
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index 82579ee538d0..9f593188129e 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -32,6 +32,8 @@
#include "lapic.h"
#define PIC_NUM_PINS 16
+#define SELECT_PIC(irq) \
+ ((irq) < 8 ? KVM_IRQCHIP_PIC_MASTER : KVM_IRQCHIP_PIC_SLAVE)
struct kvm;
struct kvm_vcpu;
diff --git a/arch/x86/kvm/kvm_svm.h b/arch/x86/kvm/kvm_svm.h
index 8e5ee99551f6..ed66e4c078dc 100644
--- a/arch/x86/kvm/kvm_svm.h
+++ b/arch/x86/kvm/kvm_svm.h
@@ -18,7 +18,6 @@ static const u32 host_save_user_msrs[] = {
};
#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
-#define NUM_DB_REGS 4
struct kvm_vcpu;
@@ -29,18 +28,23 @@ struct vcpu_svm {
struct svm_cpu_data *svm_data;
uint64_t asid_generation;
- unsigned long db_regs[NUM_DB_REGS];
-
u64 next_rip;
u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
u64 host_gs_base;
unsigned long host_cr2;
- unsigned long host_db_regs[NUM_DB_REGS];
- unsigned long host_dr6;
- unsigned long host_dr7;
u32 *msrpm;
+ struct vmcb *hsave;
+ u64 hsave_msr;
+
+ u64 nested_vmcb;
+
+ /* These are the merged vectors */
+ u32 *nested_msrpm;
+
+ /* gpa pointers to the real vectors */
+ u64 nested_vmcb_msrpm;
};
#endif
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 2d4477c71473..2a36f7f7c4c7 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -145,11 +145,20 @@ struct kvm_rmap_desc {
struct kvm_rmap_desc *more;
};
-struct kvm_shadow_walk {
- int (*entry)(struct kvm_shadow_walk *walk, struct kvm_vcpu *vcpu,
- u64 addr, u64 *spte, int level);
+struct kvm_shadow_walk_iterator {
+ u64 addr;
+ hpa_t shadow_addr;
+ int level;
+ u64 *sptep;
+ unsigned index;
};
+#define for_each_shadow_entry(_vcpu, _addr, _walker) \
+ for (shadow_walk_init(&(_walker), _vcpu, _addr); \
+ shadow_walk_okay(&(_walker)); \
+ shadow_walk_next(&(_walker)))
+
+
struct kvm_unsync_walk {
int (*entry) (struct kvm_mmu_page *sp, struct kvm_unsync_walk *walk);
};
@@ -343,7 +352,6 @@ static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc,
BUG_ON(!mc->nobjs);
p = mc->objects[--mc->nobjs];
- memset(p, 0, size);
return p;
}
@@ -794,10 +802,8 @@ static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu,
set_page_private(virt_to_page(sp->spt), (unsigned long)sp);
list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages);
INIT_LIST_HEAD(&sp->oos_link);
- ASSERT(is_empty_shadow_page(sp->spt));
bitmap_zero(sp->slot_bitmap, KVM_MEMORY_SLOTS + KVM_PRIVATE_MEM_SLOTS);
sp->multimapped = 0;
- sp->global = 1;
sp->parent_pte = parent_pte;
--vcpu->kvm->arch.n_free_mmu_pages;
return sp;
@@ -983,8 +989,8 @@ struct kvm_mmu_pages {
idx < 512; \
idx = find_next_bit(bitmap, 512, idx+1))
-int mmu_pages_add(struct kvm_mmu_pages *pvec, struct kvm_mmu_page *sp,
- int idx)
+static int mmu_pages_add(struct kvm_mmu_pages *pvec, struct kvm_mmu_page *sp,
+ int idx)
{
int i;
@@ -1059,7 +1065,7 @@ static struct kvm_mmu_page *kvm_mmu_lookup_page(struct kvm *kvm, gfn_t gfn)
index = kvm_page_table_hashfn(gfn);
bucket = &kvm->arch.mmu_page_hash[index];
hlist_for_each_entry(sp, node, bucket, hash_link)
- if (sp->gfn == gfn && !sp->role.metaphysical
+ if (sp->gfn == gfn && !sp->role.direct
&& !sp->role.invalid) {
pgprintk("%s: found role %x\n",
__func__, sp->role.word);
@@ -1115,8 +1121,9 @@ struct mmu_page_path {
i < pvec.nr && ({ sp = pvec.page[i].sp; 1;}); \
i = mmu_pages_next(&pvec, &parents, i))
-int mmu_pages_next(struct kvm_mmu_pages *pvec, struct mmu_page_path *parents,
- int i)
+static int mmu_pages_next(struct kvm_mmu_pages *pvec,
+ struct mmu_page_path *parents,
+ int i)
{
int n;
@@ -1135,7 +1142,7 @@ int mmu_pages_next(struct kvm_mmu_pages *pvec, struct mmu_page_path *parents,
return n;
}
-void mmu_pages_clear_parents(struct mmu_page_path *parents)
+static void mmu_pages_clear_parents(struct mmu_page_path *parents)
{
struct kvm_mmu_page *sp;
unsigned int level = 0;
@@ -1193,7 +1200,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
gfn_t gfn,
gva_t gaddr,
unsigned level,
- int metaphysical,
+ int direct,
unsigned access,
u64 *parent_pte)
{
@@ -1204,10 +1211,9 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
struct kvm_mmu_page *sp;
struct hlist_node *node, *tmp;
- role.word = 0;
- role.glevels = vcpu->arch.mmu.root_level;
+ role = vcpu->arch.mmu.base_role;
role.level = level;
- role.metaphysical = metaphysical;
+ role.direct = direct;
role.access = access;
if (vcpu->arch.mmu.root_level <= PT32_ROOT_LEVEL) {
quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level));
@@ -1242,8 +1248,9 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
pgprintk("%s: adding gfn %lx role %x\n", __func__, gfn, role.word);
sp->gfn = gfn;
sp->role = role;
+ sp->global = role.cr4_pge;
hlist_add_head(&sp->hash_link, bucket);
- if (!metaphysical) {
+ if (!direct) {
if (rmap_write_protect(vcpu->kvm, gfn))
kvm_flush_remote_tlbs(vcpu->kvm);
account_shadowed(vcpu->kvm, gfn);
@@ -1255,35 +1262,35 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
return sp;
}
-static int walk_shadow(struct kvm_shadow_walk *walker,
- struct kvm_vcpu *vcpu, u64 addr)
+static void shadow_walk_init(struct kvm_shadow_walk_iterator *iterator,
+ struct kvm_vcpu *vcpu, u64 addr)
{
- hpa_t shadow_addr;
- int level;
- int r;
- u64 *sptep;
- unsigned index;
-
- shadow_addr = vcpu->arch.mmu.root_hpa;
- level = vcpu->arch.mmu.shadow_root_level;
- if (level == PT32E_ROOT_LEVEL) {
- shadow_addr = vcpu->arch.mmu.pae_root[(addr >> 30) & 3];
- shadow_addr &= PT64_BASE_ADDR_MASK;
- if (!shadow_addr)
- return 1;
- --level;
+ iterator->addr = addr;
+ iterator->shadow_addr = vcpu->arch.mmu.root_hpa;
+ iterator->level = vcpu->arch.mmu.shadow_root_level;
+ if (iterator->level == PT32E_ROOT_LEVEL) {
+ iterator->shadow_addr
+ = vcpu->arch.mmu.pae_root[(addr >> 30) & 3];
+ iterator->shadow_addr &= PT64_BASE_ADDR_MASK;
+ --iterator->level;
+ if (!iterator->shadow_addr)
+ iterator->level = 0;
}
+}
- while (level >= PT_PAGE_TABLE_LEVEL) {
- index = SHADOW_PT_INDEX(addr, level);
- sptep = ((u64 *)__va(shadow_addr)) + index;
- r = walker->entry(walker, vcpu, addr, sptep, level);
- if (r)
- return r;
- shadow_addr = *sptep & PT64_BASE_ADDR_MASK;
- --level;
- }
- return 0;
+static bool shadow_walk_okay(struct kvm_shadow_walk_iterator *iterator)
+{
+ if (iterator->level < PT_PAGE_TABLE_LEVEL)
+ return false;
+ iterator->index = SHADOW_PT_INDEX(iterator->addr, iterator->level);
+ iterator->sptep = ((u64 *)__va(iterator->shadow_addr)) + iterator->index;
+ return true;
+}
+
+static void shadow_walk_next(struct kvm_shadow_walk_iterator *iterator)
+{
+ iterator->shadow_addr = *iterator->sptep & PT64_BASE_ADDR_MASK;
+ --iterator->level;
}
static void kvm_mmu_page_unlink_children(struct kvm *kvm,
@@ -1388,7 +1395,7 @@ static int kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp)
kvm_mmu_page_unlink_children(kvm, sp);
kvm_mmu_unlink_parents(kvm, sp);
kvm_flush_remote_tlbs(kvm);
- if (!sp->role.invalid && !sp->role.metaphysical)
+ if (!sp->role.invalid && !sp->role.direct)
unaccount_shadowed(kvm, sp->gfn);
if (sp->unsync)
kvm_unlink_unsync_page(kvm, sp);
@@ -1451,7 +1458,7 @@ static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn)
index = kvm_page_table_hashfn(gfn);
bucket = &kvm->arch.mmu_page_hash[index];
hlist_for_each_entry_safe(sp, node, n, bucket, hash_link)
- if (sp->gfn == gfn && !sp->role.metaphysical) {
+ if (sp->gfn == gfn && !sp->role.direct) {
pgprintk("%s: gfn %lx role %x\n", __func__, gfn,
sp->role.word);
r = 1;
@@ -1463,11 +1470,20 @@ static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn)
static void mmu_unshadow(struct kvm *kvm, gfn_t gfn)
{
+ unsigned index;
+ struct hlist_head *bucket;
struct kvm_mmu_page *sp;
+ struct hlist_node *node, *nn;
- while ((sp = kvm_mmu_lookup_page(kvm, gfn)) != NULL) {
- pgprintk("%s: zap %lx %x\n", __func__, gfn, sp->role.word);
- kvm_mmu_zap_page(kvm, sp);
+ index = kvm_page_table_hashfn(gfn);
+ bucket = &kvm->arch.mmu_page_hash[index];
+ hlist_for_each_entry_safe(sp, node, nn, bucket, hash_link) {
+ if (sp->gfn == gfn && !sp->role.direct
+ && !sp->role.invalid) {
+ pgprintk("%s: zap %lx %x\n",
+ __func__, gfn, sp->role.word);
+ kvm_mmu_zap_page(kvm, sp);
+ }
}
}
@@ -1622,7 +1638,7 @@ static int kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
bucket = &vcpu->kvm->arch.mmu_page_hash[index];
/* don't unsync if pagetable is shadowed with multiple roles */
hlist_for_each_entry_safe(s, node, n, bucket, hash_link) {
- if (s->gfn != sp->gfn || s->role.metaphysical)
+ if (s->gfn != sp->gfn || s->role.direct)
continue;
if (s->role.word != sp->role.word)
return 1;
@@ -1669,8 +1685,6 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
u64 mt_mask = shadow_mt_mask;
struct kvm_mmu_page *sp = page_header(__pa(shadow_pte));
- if (!(vcpu->arch.cr4 & X86_CR4_PGE))
- global = 0;
if (!global && sp->global) {
sp->global = 0;
if (sp->unsync) {
@@ -1777,12 +1791,8 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
pgprintk("hfn old %lx new %lx\n",
spte_to_pfn(*shadow_pte), pfn);
rmap_remove(vcpu->kvm, shadow_pte);
- } else {
- if (largepage)
- was_rmapped = is_large_pte(*shadow_pte);
- else
- was_rmapped = 1;
- }
+ } else
+ was_rmapped = 1;
}
if (set_spte(vcpu, shadow_pte, pte_access, user_fault, write_fault,
dirty, largepage, global, gfn, pfn, speculative, true)) {
@@ -1820,67 +1830,42 @@ static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
{
}
-struct direct_shadow_walk {
- struct kvm_shadow_walk walker;
- pfn_t pfn;
- int write;
- int largepage;
- int pt_write;
-};
-
-static int direct_map_entry(struct kvm_shadow_walk *_walk,
- struct kvm_vcpu *vcpu,
- u64 addr, u64 *sptep, int level)
+static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
+ int largepage, gfn_t gfn, pfn_t pfn)
{
- struct direct_shadow_walk *walk =
- container_of(_walk, struct direct_shadow_walk, walker);
+ struct kvm_shadow_walk_iterator iterator;
struct kvm_mmu_page *sp;
+ int pt_write = 0;
gfn_t pseudo_gfn;
- gfn_t gfn = addr >> PAGE_SHIFT;
-
- if (level == PT_PAGE_TABLE_LEVEL
- || (walk->largepage && level == PT_DIRECTORY_LEVEL)) {
- mmu_set_spte(vcpu, sptep, ACC_ALL, ACC_ALL,
- 0, walk->write, 1, &walk->pt_write,
- walk->largepage, 0, gfn, walk->pfn, false);
- ++vcpu->stat.pf_fixed;
- return 1;
- }
- if (*sptep == shadow_trap_nonpresent_pte) {
- pseudo_gfn = (addr & PT64_DIR_BASE_ADDR_MASK) >> PAGE_SHIFT;
- sp = kvm_mmu_get_page(vcpu, pseudo_gfn, (gva_t)addr, level - 1,
- 1, ACC_ALL, sptep);
- if (!sp) {
- pgprintk("nonpaging_map: ENOMEM\n");
- kvm_release_pfn_clean(walk->pfn);
- return -ENOMEM;
+ for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) {
+ if (iterator.level == PT_PAGE_TABLE_LEVEL
+ || (largepage && iterator.level == PT_DIRECTORY_LEVEL)) {
+ mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL,
+ 0, write, 1, &pt_write,
+ largepage, 0, gfn, pfn, false);
+ ++vcpu->stat.pf_fixed;
+ break;
}
- set_shadow_pte(sptep,
- __pa(sp->spt)
- | PT_PRESENT_MASK | PT_WRITABLE_MASK
- | shadow_user_mask | shadow_x_mask);
- }
- return 0;
-}
+ if (*iterator.sptep == shadow_trap_nonpresent_pte) {
+ pseudo_gfn = (iterator.addr & PT64_DIR_BASE_ADDR_MASK) >> PAGE_SHIFT;
+ sp = kvm_mmu_get_page(vcpu, pseudo_gfn, iterator.addr,
+ iterator.level - 1,
+ 1, ACC_ALL, iterator.sptep);
+ if (!sp) {
+ pgprintk("nonpaging_map: ENOMEM\n");
+ kvm_release_pfn_clean(pfn);
+ return -ENOMEM;
+ }
-static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
- int largepage, gfn_t gfn, pfn_t pfn)
-{
- int r;
- struct direct_shadow_walk walker = {
- .walker = { .entry = direct_map_entry, },
- .pfn = pfn,
- .largepage = largepage,
- .write = write,
- .pt_write = 0,
- };
-
- r = walk_shadow(&walker.walker, vcpu, gfn << PAGE_SHIFT);
- if (r < 0)
- return r;
- return walker.pt_write;
+ set_shadow_pte(iterator.sptep,
+ __pa(sp->spt)
+ | PT_PRESENT_MASK | PT_WRITABLE_MASK
+ | shadow_user_mask | shadow_x_mask);
+ }
+ }
+ return pt_write;
}
static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
@@ -1962,7 +1947,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
int i;
gfn_t root_gfn;
struct kvm_mmu_page *sp;
- int metaphysical = 0;
+ int direct = 0;
root_gfn = vcpu->arch.cr3 >> PAGE_SHIFT;
@@ -1971,18 +1956,18 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
ASSERT(!VALID_PAGE(root));
if (tdp_enabled)
- metaphysical = 1;
+ direct = 1;
sp = kvm_mmu_get_page(vcpu, root_gfn, 0,
- PT64_ROOT_LEVEL, metaphysical,
+ PT64_ROOT_LEVEL, direct,
ACC_ALL, NULL);
root = __pa(sp->spt);
++sp->root_count;
vcpu->arch.mmu.root_hpa = root;
return;
}
- metaphysical = !is_paging(vcpu);
+ direct = !is_paging(vcpu);
if (tdp_enabled)
- metaphysical = 1;
+ direct = 1;
for (i = 0; i < 4; ++i) {
hpa_t root = vcpu->arch.mmu.pae_root[i];
@@ -1996,7 +1981,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
} else if (vcpu->arch.mmu.root_level == 0)
root_gfn = 0;
sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30,
- PT32_ROOT_LEVEL, metaphysical,
+ PT32_ROOT_LEVEL, direct,
ACC_ALL, NULL);
root = __pa(sp->spt);
++sp->root_count;
@@ -2251,17 +2236,23 @@ static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
static int init_kvm_softmmu(struct kvm_vcpu *vcpu)
{
+ int r;
+
ASSERT(vcpu);
ASSERT(!VALID_PAGE(vcpu->arch.mmu.root_hpa));
if (!is_paging(vcpu))
- return nonpaging_init_context(vcpu);
+ r = nonpaging_init_context(vcpu);
else if (is_long_mode(vcpu))
- return paging64_init_context(vcpu);
+ r = paging64_init_context(vcpu);
else if (is_pae(vcpu))
- return paging32E_init_context(vcpu);
+ r = paging32E_init_context(vcpu);
else
- return paging32_init_context(vcpu);
+ r = paging32_init_context(vcpu);
+
+ vcpu->arch.mmu.base_role.glevels = vcpu->arch.mmu.root_level;
+
+ return r;
}
static int init_kvm_mmu(struct kvm_vcpu *vcpu)
@@ -2492,7 +2483,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
index = kvm_page_table_hashfn(gfn);
bucket = &vcpu->kvm->arch.mmu_page_hash[index];
hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) {
- if (sp->gfn != gfn || sp->role.metaphysical || sp->role.invalid)
+ if (sp->gfn != gfn || sp->role.direct || sp->role.invalid)
continue;
pte_size = sp->role.glevels == PT32_ROOT_LEVEL ? 4 : 8;
misaligned = (offset ^ (offset + bytes - 1)) & ~(pte_size - 1);
@@ -3130,7 +3121,7 @@ static void audit_write_protection(struct kvm_vcpu *vcpu)
gfn_t gfn;
list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) {
- if (sp->role.metaphysical)
+ if (sp->role.direct)
continue;
gfn = unalias_gfn(vcpu->kvm, sp->gfn);
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index 258e5d56298e..eaab2145f62b 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -54,7 +54,7 @@ static inline int kvm_mmu_reload(struct kvm_vcpu *vcpu)
static inline int is_long_mode(struct kvm_vcpu *vcpu)
{
#ifdef CONFIG_X86_64
- return vcpu->arch.shadow_efer & EFER_LME;
+ return vcpu->arch.shadow_efer & EFER_LMA;
#else
return 0;
#endif
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 9fd78b6e17ad..6bd70206c561 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -25,7 +25,6 @@
#if PTTYPE == 64
#define pt_element_t u64
#define guest_walker guest_walker64
- #define shadow_walker shadow_walker64
#define FNAME(name) paging##64_##name
#define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK
#define PT_DIR_BASE_ADDR_MASK PT64_DIR_BASE_ADDR_MASK
@@ -42,7 +41,6 @@
#elif PTTYPE == 32
#define pt_element_t u32
#define guest_walker guest_walker32
- #define shadow_walker shadow_walker32
#define FNAME(name) paging##32_##name
#define PT_BASE_ADDR_MASK PT32_BASE_ADDR_MASK
#define PT_DIR_BASE_ADDR_MASK PT32_DIR_BASE_ADDR_MASK
@@ -73,18 +71,6 @@ struct guest_walker {
u32 error_code;
};
-struct shadow_walker {
- struct kvm_shadow_walk walker;
- struct guest_walker *guest_walker;
- int user_fault;
- int write_fault;
- int largepage;
- int *ptwrite;
- pfn_t pfn;
- u64 *sptep;
- gpa_t pte_gpa;
-};
-
static gfn_t gpte_to_gfn(pt_element_t gpte)
{
return (gpte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT;
@@ -283,91 +269,79 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
/*
* Fetch a shadow pte for a specific level in the paging hierarchy.
*/
-static int FNAME(shadow_walk_entry)(struct kvm_shadow_walk *_sw,
- struct kvm_vcpu *vcpu, u64 addr,
- u64 *sptep, int level)
+static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
+ struct guest_walker *gw,
+ int user_fault, int write_fault, int largepage,
+ int *ptwrite, pfn_t pfn)
{
- struct shadow_walker *sw =
- container_of(_sw, struct shadow_walker, walker);
- struct guest_walker *gw = sw->guest_walker;
unsigned access = gw->pt_access;
struct kvm_mmu_page *shadow_page;
- u64 spte;
- int metaphysical;
+ u64 spte, *sptep;
+ int direct;
gfn_t table_gfn;
int r;
+ int level;
pt_element_t curr_pte;
+ struct kvm_shadow_walk_iterator iterator;
- if (level == PT_PAGE_TABLE_LEVEL
- || (sw->largepage && level == PT_DIRECTORY_LEVEL)) {
- mmu_set_spte(vcpu, sptep, access, gw->pte_access & access,
- sw->user_fault, sw->write_fault,
- gw->ptes[gw->level-1] & PT_DIRTY_MASK,
- sw->ptwrite, sw->largepage,
- gw->ptes[gw->level-1] & PT_GLOBAL_MASK,
- gw->gfn, sw->pfn, false);
- sw->sptep = sptep;
- return 1;
- }
+ if (!is_present_pte(gw->ptes[gw->level - 1]))
+ return NULL;
- if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep))
- return 0;
+ for_each_shadow_entry(vcpu, addr, iterator) {
+ level = iterator.level;
+ sptep = iterator.sptep;
+ if (level == PT_PAGE_TABLE_LEVEL
+ || (largepage && level == PT_DIRECTORY_LEVEL)) {
+ mmu_set_spte(vcpu, sptep, access,
+ gw->pte_access & access,
+ user_fault, write_fault,
+ gw->ptes[gw->level-1] & PT_DIRTY_MASK,
+ ptwrite, largepage,
+ gw->ptes[gw->level-1] & PT_GLOBAL_MASK,
+ gw->gfn, pfn, false);
+ break;
+ }
- if (is_large_pte(*sptep)) {
- set_shadow_pte(sptep, shadow_trap_nonpresent_pte);
- kvm_flush_remote_tlbs(vcpu->kvm);
- rmap_remove(vcpu->kvm, sptep);
- }
+ if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep))
+ continue;
- if (level == PT_DIRECTORY_LEVEL && gw->level == PT_DIRECTORY_LEVEL) {
- metaphysical = 1;
- if (!is_dirty_pte(gw->ptes[level - 1]))
- access &= ~ACC_WRITE_MASK;
- table_gfn = gpte_to_gfn(gw->ptes[level - 1]);
- } else {
- metaphysical = 0;
- table_gfn = gw->table_gfn[level - 2];
- }
- shadow_page = kvm_mmu_get_page(vcpu, table_gfn, (gva_t)addr, level-1,
- metaphysical, access, sptep);
- if (!metaphysical) {
- r = kvm_read_guest_atomic(vcpu->kvm, gw->pte_gpa[level - 2],
- &curr_pte, sizeof(curr_pte));
- if (r || curr_pte != gw->ptes[level - 2]) {
- kvm_mmu_put_page(shadow_page, sptep);
- kvm_release_pfn_clean(sw->pfn);
- sw->sptep = NULL;
- return 1;
+ if (is_large_pte(*sptep)) {
+ rmap_remove(vcpu->kvm, sptep);
+ set_shadow_pte(sptep, shadow_trap_nonpresent_pte);
+ kvm_flush_remote_tlbs(vcpu->kvm);
}
- }
- spte = __pa(shadow_page->spt) | PT_PRESENT_MASK | PT_ACCESSED_MASK
- | PT_WRITABLE_MASK | PT_USER_MASK;
- *sptep = spte;
- return 0;
-}
-
-static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
- struct guest_walker *guest_walker,
- int user_fault, int write_fault, int largepage,
- int *ptwrite, pfn_t pfn)
-{
- struct shadow_walker walker = {
- .walker = { .entry = FNAME(shadow_walk_entry), },
- .guest_walker = guest_walker,
- .user_fault = user_fault,
- .write_fault = write_fault,
- .largepage = largepage,
- .ptwrite = ptwrite,
- .pfn = pfn,
- };
-
- if (!is_present_pte(guest_walker->ptes[guest_walker->level - 1]))
- return NULL;
+ if (level == PT_DIRECTORY_LEVEL
+ && gw->level == PT_DIRECTORY_LEVEL) {
+ direct = 1;
+ if (!is_dirty_pte(gw->ptes[level - 1]))
+ access &= ~ACC_WRITE_MASK;
+ table_gfn = gpte_to_gfn(gw->ptes[level - 1]);
+ } else {
+ direct = 0;
+ table_gfn = gw->table_gfn[level - 2];
+ }
+ shadow_page = kvm_mmu_get_page(vcpu, table_gfn, addr, level-1,
+ direct, access, sptep);
+ if (!direct) {
+ r = kvm_read_guest_atomic(vcpu->kvm,
+ gw->pte_gpa[level - 2],
+ &curr_pte, sizeof(curr_pte));
+ if (r || curr_pte != gw->ptes[level - 2]) {
+ kvm_mmu_put_page(shadow_page, sptep);
+ kvm_release_pfn_clean(pfn);
+ sptep = NULL;
+ break;
+ }
+ }
- walk_shadow(&walker.walker, vcpu, addr);
+ spte = __pa(shadow_page->spt)
+ | PT_PRESENT_MASK | PT_ACCESSED_MASK
+ | PT_WRITABLE_MASK | PT_USER_MASK;
+ *sptep = spte;
+ }
- return walker.sptep;
+ return sptep;
}
/*
@@ -465,54 +439,56 @@ out_unlock:
return 0;
}
-static int FNAME(shadow_invlpg_entry)(struct kvm_shadow_walk *_sw,
- struct kvm_vcpu *vcpu, u64 addr,
- u64 *sptep, int level)
+static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
{
- struct shadow_walker *sw =
- container_of(_sw, struct shadow_walker, walker);
-
- /* FIXME: properly handle invlpg on large guest pages */
- if (level == PT_PAGE_TABLE_LEVEL ||
- ((level == PT_DIRECTORY_LEVEL) && is_large_pte(*sptep))) {
- struct kvm_mmu_page *sp = page_header(__pa(sptep));
+ struct kvm_shadow_walk_iterator iterator;
+ pt_element_t gpte;
+ gpa_t pte_gpa = -1;
+ int level;
+ u64 *sptep;
+ int need_flush = 0;
- sw->pte_gpa = (sp->gfn << PAGE_SHIFT);
- sw->pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t);
+ spin_lock(&vcpu->kvm->mmu_lock);
- if (is_shadow_present_pte(*sptep)) {
- rmap_remove(vcpu->kvm, sptep);
- if (is_large_pte(*sptep))
- --vcpu->kvm->stat.lpages;
+ for_each_shadow_entry(vcpu, gva, iterator) {
+ level = iterator.level;
+ sptep = iterator.sptep;
+
+ /* FIXME: properly handle invlpg on large guest pages */
+ if (level == PT_PAGE_TABLE_LEVEL ||
+ ((level == PT_DIRECTORY_LEVEL) && is_large_pte(*sptep))) {
+ struct kvm_mmu_page *sp = page_header(__pa(sptep));
+
+ pte_gpa = (sp->gfn << PAGE_SHIFT);
+ pte_gpa += (sptep - sp->spt) * sizeof(pt_element_t);
+
+ if (is_shadow_present_pte(*sptep)) {
+ rmap_remove(vcpu->kvm, sptep);
+ if (is_large_pte(*sptep))
+ --vcpu->kvm->stat.lpages;
+ need_flush = 1;
+ }
+ set_shadow_pte(sptep, shadow_trap_nonpresent_pte);
+ break;
}
- set_shadow_pte(sptep, shadow_trap_nonpresent_pte);
- return 1;
- }
- if (!is_shadow_present_pte(*sptep))
- return 1;
- return 0;
-}
-static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
-{
- pt_element_t gpte;
- struct shadow_walker walker = {
- .walker = { .entry = FNAME(shadow_invlpg_entry), },
- .pte_gpa = -1,
- };
+ if (!is_shadow_present_pte(*sptep))
+ break;
+ }
- spin_lock(&vcpu->kvm->mmu_lock);
- walk_shadow(&walker.walker, vcpu, gva);
+ if (need_flush)
+ kvm_flush_remote_tlbs(vcpu->kvm);
spin_unlock(&vcpu->kvm->mmu_lock);
- if (walker.pte_gpa == -1)
+
+ if (pte_gpa == -1)
return;
- if (kvm_read_guest_atomic(vcpu->kvm, walker.pte_gpa, &gpte,
+ if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte,
sizeof(pt_element_t)))
return;
if (is_present_pte(gpte) && (gpte & PT_ACCESSED_MASK)) {
if (mmu_topup_memory_caches(vcpu))
return;
- kvm_mmu_pte_write(vcpu, walker.pte_gpa, (const u8 *)&gpte,
+ kvm_mmu_pte_write(vcpu, pte_gpa, (const u8 *)&gpte,
sizeof(pt_element_t), 0);
}
}
@@ -540,7 +516,7 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu,
pt_element_t pt[256 / sizeof(pt_element_t)];
gpa_t pte_gpa;
- if (sp->role.metaphysical
+ if (sp->role.direct
|| (PTTYPE == 32 && sp->role.level > PT_PAGE_TABLE_LEVEL)) {
nonpaging_prefetch_page(vcpu, sp);
return;
@@ -619,7 +595,6 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
#undef pt_element_t
#undef guest_walker
-#undef shadow_walker
#undef FNAME
#undef PT_BASE_ADDR_MASK
#undef PT_INDEX
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index a9e769e4e251..1821c2078199 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -38,9 +38,6 @@ MODULE_LICENSE("GPL");
#define IOPM_ALLOC_ORDER 2
#define MSRPM_ALLOC_ORDER 1
-#define DR7_GD_MASK (1 << 13)
-#define DR6_BD_MASK (1 << 13)
-
#define SEG_TYPE_LDT 2
#define SEG_TYPE_BUSY_TSS16 3
@@ -50,6 +47,15 @@ MODULE_LICENSE("GPL");
#define DEBUGCTL_RESERVED_BITS (~(0x3fULL))
+/* Turn on to get debugging output*/
+/* #define NESTED_DEBUG */
+
+#ifdef NESTED_DEBUG
+#define nsvm_printk(fmt, args...) printk(KERN_INFO fmt, ## args)
+#else
+#define nsvm_printk(fmt, args...) do {} while(0)
+#endif
+
/* enable NPT for AMD64 and X86 with PAE */
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
static bool npt_enabled = true;
@@ -60,14 +66,29 @@ static int npt = 1;
module_param(npt, int, S_IRUGO);
+static int nested = 0;
+module_param(nested, int, S_IRUGO);
+
static void kvm_reput_irq(struct vcpu_svm *svm);
static void svm_flush_tlb(struct kvm_vcpu *vcpu);
+static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override);
+static int nested_svm_vmexit(struct vcpu_svm *svm);
+static int nested_svm_vmsave(struct vcpu_svm *svm, void *nested_vmcb,
+ void *arg2, void *opaque);
+static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
+ bool has_error_code, u32 error_code);
+
static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
{
return container_of(vcpu, struct vcpu_svm, vcpu);
}
+static inline bool is_nested(struct vcpu_svm *svm)
+{
+ return svm->nested_vmcb;
+}
+
static unsigned long iopm_base;
struct kvm_ldttss_desc {
@@ -157,32 +178,6 @@ static inline void kvm_write_cr2(unsigned long val)
asm volatile ("mov %0, %%cr2" :: "r" (val));
}
-static inline unsigned long read_dr6(void)
-{
- unsigned long dr6;
-
- asm volatile ("mov %%dr6, %0" : "=r" (dr6));
- return dr6;
-}
-
-static inline void write_dr6(unsigned long val)
-{
- asm volatile ("mov %0, %%dr6" :: "r" (val));
-}
-
-static inline unsigned long read_dr7(void)
-{
- unsigned long dr7;
-
- asm volatile ("mov %%dr7, %0" : "=r" (dr7));
- return dr7;
-}
-
-static inline void write_dr7(unsigned long val)
-{
- asm volatile ("mov %0, %%dr7" :: "r" (val));
-}
-
static inline void force_new_asid(struct kvm_vcpu *vcpu)
{
to_svm(vcpu)->asid_generation--;
@@ -198,7 +193,7 @@ static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
if (!npt_enabled && !(efer & EFER_LMA))
efer &= ~EFER_LME;
- to_svm(vcpu)->vmcb->save.efer = efer | MSR_EFER_SVME_MASK;
+ to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME;
vcpu->arch.shadow_efer = efer;
}
@@ -207,6 +202,11 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
{
struct vcpu_svm *svm = to_svm(vcpu);
+ /* If we are within a nested VM we'd better #VMEXIT and let the
+ guest handle the exception */
+ if (nested_svm_check_exception(svm, nr, has_error_code, error_code))
+ return;
+
svm->vmcb->control.event_inj = nr
| SVM_EVTINJ_VALID
| (has_error_code ? SVM_EVTINJ_VALID_ERR : 0)
@@ -242,7 +242,7 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
kvm_rip_write(vcpu, svm->next_rip);
svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
- vcpu->arch.interrupt_window_open = 1;
+ vcpu->arch.interrupt_window_open = (svm->vcpu.arch.hflags & HF_GIF_MASK);
}
static int has_svm(void)
@@ -250,7 +250,7 @@ static int has_svm(void)
const char *msg;
if (!cpu_has_svm(&msg)) {
- printk(KERN_INFO "has_svn: %s\n", msg);
+ printk(KERN_INFO "has_svm: %s\n", msg);
return 0;
}
@@ -292,7 +292,7 @@ static void svm_hardware_enable(void *garbage)
svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
rdmsrl(MSR_EFER, efer);
- wrmsrl(MSR_EFER, efer | MSR_EFER_SVME_MASK);
+ wrmsrl(MSR_EFER, efer | EFER_SVME);
wrmsrl(MSR_VM_HSAVE_PA,
page_to_pfn(svm_data->save_area) << PAGE_SHIFT);
@@ -417,6 +417,14 @@ static __init int svm_hardware_setup(void)
if (boot_cpu_has(X86_FEATURE_NX))
kvm_enable_efer_bits(EFER_NX);
+ if (boot_cpu_has(X86_FEATURE_FXSR_OPT))
+ kvm_enable_efer_bits(EFER_FFXSR);
+
+ if (nested) {
+ printk(KERN_INFO "kvm: Nested Virtualization enabled\n");
+ kvm_enable_efer_bits(EFER_SVME);
+ }
+
for_each_online_cpu(cpu) {
r = svm_cpu_init(cpu);
if (r)
@@ -559,7 +567,7 @@ static void init_vmcb(struct vcpu_svm *svm)
init_sys_seg(&save->ldtr, SEG_TYPE_LDT);
init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16);
- save->efer = MSR_EFER_SVME_MASK;
+ save->efer = EFER_SVME;
save->dr6 = 0xffff0ff0;
save->dr7 = 0x400;
save->rflags = 2;
@@ -591,6 +599,9 @@ static void init_vmcb(struct vcpu_svm *svm)
save->cr4 = 0;
}
force_new_asid(&svm->vcpu);
+
+ svm->nested_vmcb = 0;
+ svm->vcpu.arch.hflags = HF_GIF_MASK;
}
static int svm_vcpu_reset(struct kvm_vcpu *vcpu)
@@ -615,6 +626,8 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
struct vcpu_svm *svm;
struct page *page;
struct page *msrpm_pages;
+ struct page *hsave_page;
+ struct page *nested_msrpm_pages;
int err;
svm = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
@@ -637,14 +650,25 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
if (!msrpm_pages)
goto uninit;
+
+ nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
+ if (!nested_msrpm_pages)
+ goto uninit;
+
svm->msrpm = page_address(msrpm_pages);
svm_vcpu_init_msrpm(svm->msrpm);
+ hsave_page = alloc_page(GFP_KERNEL);
+ if (!hsave_page)
+ goto uninit;
+ svm->hsave = page_address(hsave_page);
+
+ svm->nested_msrpm = page_address(nested_msrpm_pages);
+
svm->vmcb = page_address(page);
clear_page(svm->vmcb);
svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT;
svm->asid_generation = 0;
- memset(svm->db_regs, 0, sizeof(svm->db_regs));
init_vmcb(svm);
fx_init(&svm->vcpu);
@@ -669,6 +693,8 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu)
__free_page(pfn_to_page(svm->vmcb_pa >> PAGE_SHIFT));
__free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER);
+ __free_page(virt_to_page(svm->hsave));
+ __free_pages(virt_to_page(svm->nested_msrpm), MSRPM_ALLOC_ORDER);
kvm_vcpu_uninit(vcpu);
kmem_cache_free(kvm_vcpu_cache, svm);
}
@@ -718,6 +744,16 @@ static void svm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
to_svm(vcpu)->vmcb->save.rflags = rflags;
}
+static void svm_set_vintr(struct vcpu_svm *svm)
+{
+ svm->vmcb->control.intercept |= 1ULL << INTERCEPT_VINTR;
+}
+
+static void svm_clear_vintr(struct vcpu_svm *svm)
+{
+ svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VINTR);
+}
+
static struct vmcb_seg *svm_seg(struct kvm_vcpu *vcpu, int seg)
{
struct vmcb_save_area *save = &to_svm(vcpu)->vmcb->save;
@@ -760,20 +796,37 @@ static void svm_get_segment(struct kvm_vcpu *vcpu,
var->db = (s->attrib >> SVM_SELECTOR_DB_SHIFT) & 1;
var->g = (s->attrib >> SVM_SELECTOR_G_SHIFT) & 1;
- /*
- * SVM always stores 0 for the 'G' bit in the CS selector in
- * the VMCB on a VMEXIT. This hurts cross-vendor migration:
- * Intel's VMENTRY has a check on the 'G' bit.
- */
- if (seg == VCPU_SREG_CS)
+ switch (seg) {
+ case VCPU_SREG_CS:
+ /*
+ * SVM always stores 0 for the 'G' bit in the CS selector in
+ * the VMCB on a VMEXIT. This hurts cross-vendor migration:
+ * Intel's VMENTRY has a check on the 'G' bit.
+ */
var->g = s->limit > 0xfffff;
-
- /*
- * Work around a bug where the busy flag in the tr selector
- * isn't exposed
- */
- if (seg == VCPU_SREG_TR)
+ break;
+ case VCPU_SREG_TR:
+ /*
+ * Work around a bug where the busy flag in the tr selector
+ * isn't exposed
+ */
var->type |= 0x2;
+ break;
+ case VCPU_SREG_DS:
+ case VCPU_SREG_ES:
+ case VCPU_SREG_FS:
+ case VCPU_SREG_GS:
+ /*
+ * The accessed bit must always be set in the segment
+ * descriptor cache, although it can be cleared in the
+ * descriptor, the cached bit always remains at 1. Since
+ * Intel has a check on this, set it here to support
+ * cross-vendor migration.
+ */
+ if (!var->unusable)
+ var->type |= 0x1;
+ break;
+ }
var->unusable = !var->present;
}
@@ -905,9 +958,37 @@ static void svm_set_segment(struct kvm_vcpu *vcpu,
}
-static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg)
+static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg)
{
- return -EOPNOTSUPP;
+ int old_debug = vcpu->guest_debug;
+ struct vcpu_svm *svm = to_svm(vcpu);
+
+ vcpu->guest_debug = dbg->control;
+
+ svm->vmcb->control.intercept_exceptions &=
+ ~((1 << DB_VECTOR) | (1 << BP_VECTOR));
+ if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
+ if (vcpu->guest_debug &
+ (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
+ svm->vmcb->control.intercept_exceptions |=
+ 1 << DB_VECTOR;
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+ svm->vmcb->control.intercept_exceptions |=
+ 1 << BP_VECTOR;
+ } else
+ vcpu->guest_debug = 0;
+
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
+ svm->vmcb->save.dr7 = dbg->arch.debugreg[7];
+ else
+ svm->vmcb->save.dr7 = vcpu->arch.dr7;
+
+ if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+ svm->vmcb->save.rflags |= X86_EFLAGS_TF | X86_EFLAGS_RF;
+ else if (old_debug & KVM_GUESTDBG_SINGLESTEP)
+ svm->vmcb->save.rflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF);
+
+ return 0;
}
static int svm_get_irq(struct kvm_vcpu *vcpu)
@@ -949,7 +1030,29 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *svm_data)
static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
{
- unsigned long val = to_svm(vcpu)->db_regs[dr];
+ struct vcpu_svm *svm = to_svm(vcpu);
+ unsigned long val;
+
+ switch (dr) {
+ case 0 ... 3:
+ val = vcpu->arch.db[dr];
+ break;
+ case 6:
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
+ val = vcpu->arch.dr6;
+ else
+ val = svm->vmcb->save.dr6;
+ break;
+ case 7:
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
+ val = vcpu->arch.dr7;
+ else
+ val = svm->vmcb->save.dr7;
+ break;
+ default:
+ val = 0;
+ }
+
KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler);
return val;
}
@@ -959,33 +1062,40 @@ static void svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value,
{
struct vcpu_svm *svm = to_svm(vcpu);
- *exception = 0;
+ KVMTRACE_2D(DR_WRITE, vcpu, (u32)dr, (u32)value, handler);
- if (svm->vmcb->save.dr7 & DR7_GD_MASK) {
- svm->vmcb->save.dr7 &= ~DR7_GD_MASK;
- svm->vmcb->save.dr6 |= DR6_BD_MASK;
- *exception = DB_VECTOR;
- return;
- }
+ *exception = 0;
switch (dr) {
case 0 ... 3:
- svm->db_regs[dr] = value;
+ vcpu->arch.db[dr] = value;
+ if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
+ vcpu->arch.eff_db[dr] = value;
return;
case 4 ... 5:
- if (vcpu->arch.cr4 & X86_CR4_DE) {
+ if (vcpu->arch.cr4 & X86_CR4_DE)
*exception = UD_VECTOR;
+ return;
+ case 6:
+ if (value & 0xffffffff00000000ULL) {
+ *exception = GP_VECTOR;
return;
}
- case 7: {
- if (value & ~((1ULL << 32) - 1)) {
+ vcpu->arch.dr6 = (value & DR6_VOLATILE) | DR6_FIXED_1;
+ return;
+ case 7:
+ if (value & 0xffffffff00000000ULL) {
*exception = GP_VECTOR;
return;
}
- svm->vmcb->save.dr7 = value;
+ vcpu->arch.dr7 = (value & DR7_VOLATILE) | DR7_FIXED_1;
+ if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) {
+ svm->vmcb->save.dr7 = vcpu->arch.dr7;
+ vcpu->arch.switch_db_regs = (value & DR7_BP_EN_MASK);
+ }
return;
- }
default:
+ /* FIXME: Possible case? */
printk(KERN_DEBUG "%s: unexpected dr %u\n",
__func__, dr);
*exception = UD_VECTOR;
@@ -1031,6 +1141,27 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
}
+static int db_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+ if (!(svm->vcpu.guest_debug &
+ (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) {
+ kvm_queue_exception(&svm->vcpu, DB_VECTOR);
+ return 1;
+ }
+ kvm_run->exit_reason = KVM_EXIT_DEBUG;
+ kvm_run->debug.arch.pc = svm->vmcb->save.cs.base + svm->vmcb->save.rip;
+ kvm_run->debug.arch.exception = DB_VECTOR;
+ return 0;
+}
+
+static int bp_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+ kvm_run->exit_reason = KVM_EXIT_DEBUG;
+ kvm_run->debug.arch.pc = svm->vmcb->save.cs.base + svm->vmcb->save.rip;
+ kvm_run->debug.arch.exception = BP_VECTOR;
+ return 0;
+}
+
static int ud_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
{
int er;
@@ -1080,7 +1211,7 @@ static int shutdown_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
{
u32 io_info = svm->vmcb->control.exit_info_1; /* address size bug? */
- int size, down, in, string, rep;
+ int size, in, string;
unsigned port;
++svm->vcpu.stat.io_exits;
@@ -1099,8 +1230,6 @@ static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
in = (io_info & SVM_IOIO_TYPE_MASK) != 0;
port = io_info >> 16;
size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT;
- rep = (io_info & SVM_IOIO_REP_MASK) != 0;
- down = (svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0;
skip_emulated_instruction(&svm->vcpu);
return kvm_emulate_pio(&svm->vcpu, kvm_run, in, size, port);
@@ -1139,6 +1268,567 @@ static int vmmcall_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
return 1;
}
+static int nested_svm_check_permissions(struct vcpu_svm *svm)
+{
+ if (!(svm->vcpu.arch.shadow_efer & EFER_SVME)
+ || !is_paging(&svm->vcpu)) {
+ kvm_queue_exception(&svm->vcpu, UD_VECTOR);
+ return 1;
+ }
+
+ if (svm->vmcb->save.cpl) {
+ kvm_inject_gp(&svm->vcpu, 0);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
+ bool has_error_code, u32 error_code)
+{
+ if (is_nested(svm)) {
+ svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr;
+ svm->vmcb->control.exit_code_hi = 0;
+ svm->vmcb->control.exit_info_1 = error_code;
+ svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2;
+ if (nested_svm_exit_handled(svm, false)) {
+ nsvm_printk("VMexit -> EXCP 0x%x\n", nr);
+
+ nested_svm_vmexit(svm);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static inline int nested_svm_intr(struct vcpu_svm *svm)
+{
+ if (is_nested(svm)) {
+ if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
+ return 0;
+
+ if (!(svm->vcpu.arch.hflags & HF_HIF_MASK))
+ return 0;
+
+ svm->vmcb->control.exit_code = SVM_EXIT_INTR;
+
+ if (nested_svm_exit_handled(svm, false)) {
+ nsvm_printk("VMexit -> INTR\n");
+ nested_svm_vmexit(svm);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static struct page *nested_svm_get_page(struct vcpu_svm *svm, u64 gpa)
+{
+ struct page *page;
+
+ down_read(&current->mm->mmap_sem);
+ page = gfn_to_page(svm->vcpu.kvm, gpa >> PAGE_SHIFT);
+ up_read(&current->mm->mmap_sem);
+
+ if (is_error_page(page)) {
+ printk(KERN_INFO "%s: could not find page at 0x%llx\n",
+ __func__, gpa);
+ kvm_release_page_clean(page);
+ kvm_inject_gp(&svm->vcpu, 0);
+ return NULL;
+ }
+ return page;
+}
+
+static int nested_svm_do(struct vcpu_svm *svm,
+ u64 arg1_gpa, u64 arg2_gpa, void *opaque,
+ int (*handler)(struct vcpu_svm *svm,
+ void *arg1,
+ void *arg2,
+ void *opaque))
+{
+ struct page *arg1_page;
+ struct page *arg2_page = NULL;
+ void *arg1;
+ void *arg2 = NULL;
+ int retval;
+
+ arg1_page = nested_svm_get_page(svm, arg1_gpa);
+ if(arg1_page == NULL)
+ return 1;
+
+ if (arg2_gpa) {
+ arg2_page = nested_svm_get_page(svm, arg2_gpa);
+ if(arg2_page == NULL) {
+ kvm_release_page_clean(arg1_page);
+ return 1;
+ }
+ }
+
+ arg1 = kmap_atomic(arg1_page, KM_USER0);
+ if (arg2_gpa)
+ arg2 = kmap_atomic(arg2_page, KM_USER1);
+
+ retval = handler(svm, arg1, arg2, opaque);
+
+ kunmap_atomic(arg1, KM_USER0);
+ if (arg2_gpa)
+ kunmap_atomic(arg2, KM_USER1);
+
+ kvm_release_page_dirty(arg1_page);
+ if (arg2_gpa)
+ kvm_release_page_dirty(arg2_page);
+
+ return retval;
+}
+
+static int nested_svm_exit_handled_real(struct vcpu_svm *svm,
+ void *arg1,
+ void *arg2,
+ void *opaque)
+{
+ struct vmcb *nested_vmcb = (struct vmcb *)arg1;
+ bool kvm_overrides = *(bool *)opaque;
+ u32 exit_code = svm->vmcb->control.exit_code;
+
+ if (kvm_overrides) {
+ switch (exit_code) {
+ case SVM_EXIT_INTR:
+ case SVM_EXIT_NMI:
+ return 0;
+ /* For now we are always handling NPFs when using them */
+ case SVM_EXIT_NPF:
+ if (npt_enabled)
+ return 0;
+ break;
+ /* When we're shadowing, trap PFs */
+ case SVM_EXIT_EXCP_BASE + PF_VECTOR:
+ if (!npt_enabled)
+ return 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ switch (exit_code) {
+ case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: {
+ u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0);
+ if (nested_vmcb->control.intercept_cr_read & cr_bits)
+ return 1;
+ break;
+ }
+ case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR8: {
+ u32 cr_bits = 1 << (exit_code - SVM_EXIT_WRITE_CR0);
+ if (nested_vmcb->control.intercept_cr_write & cr_bits)
+ return 1;
+ break;
+ }
+ case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR7: {
+ u32 dr_bits = 1 << (exit_code - SVM_EXIT_READ_DR0);
+ if (nested_vmcb->control.intercept_dr_read & dr_bits)
+ return 1;
+ break;
+ }
+ case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR7: {
+ u32 dr_bits = 1 << (exit_code - SVM_EXIT_WRITE_DR0);
+ if (nested_vmcb->control.intercept_dr_write & dr_bits)
+ return 1;
+ break;
+ }
+ case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 0x1f: {
+ u32 excp_bits = 1 << (exit_code - SVM_EXIT_EXCP_BASE);
+ if (nested_vmcb->control.intercept_exceptions & excp_bits)
+ return 1;
+ break;
+ }
+ default: {
+ u64 exit_bits = 1ULL << (exit_code - SVM_EXIT_INTR);
+ nsvm_printk("exit code: 0x%x\n", exit_code);
+ if (nested_vmcb->control.intercept & exit_bits)
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int nested_svm_exit_handled_msr(struct vcpu_svm *svm,
+ void *arg1, void *arg2,
+ void *opaque)
+{
+ struct vmcb *nested_vmcb = (struct vmcb *)arg1;
+ u8 *msrpm = (u8 *)arg2;
+ u32 t0, t1;
+ u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX];
+ u32 param = svm->vmcb->control.exit_info_1 & 1;
+
+ if (!(nested_vmcb->control.intercept & (1ULL << INTERCEPT_MSR_PROT)))
+ return 0;
+
+ switch(msr) {
+ case 0 ... 0x1fff:
+ t0 = (msr * 2) % 8;
+ t1 = msr / 8;
+ break;
+ case 0xc0000000 ... 0xc0001fff:
+ t0 = (8192 + msr - 0xc0000000) * 2;
+ t1 = (t0 / 8);
+ t0 %= 8;
+ break;
+ case 0xc0010000 ... 0xc0011fff:
+ t0 = (16384 + msr - 0xc0010000) * 2;
+ t1 = (t0 / 8);
+ t0 %= 8;
+ break;
+ default:
+ return 1;
+ break;
+ }
+ if (msrpm[t1] & ((1 << param) << t0))
+ return 1;
+
+ return 0;
+}
+
+static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override)
+{
+ bool k = kvm_override;
+
+ switch (svm->vmcb->control.exit_code) {
+ case SVM_EXIT_MSR:
+ return nested_svm_do(svm, svm->nested_vmcb,
+ svm->nested_vmcb_msrpm, NULL,
+ nested_svm_exit_handled_msr);
+ default: break;
+ }
+
+ return nested_svm_do(svm, svm->nested_vmcb, 0, &k,
+ nested_svm_exit_handled_real);
+}
+
+static int nested_svm_vmexit_real(struct vcpu_svm *svm, void *arg1,
+ void *arg2, void *opaque)
+{
+ struct vmcb *nested_vmcb = (struct vmcb *)arg1;
+ struct vmcb *hsave = svm->hsave;
+ u64 nested_save[] = { nested_vmcb->save.cr0,
+ nested_vmcb->save.cr3,
+ nested_vmcb->save.cr4,
+ nested_vmcb->save.efer,
+ nested_vmcb->control.intercept_cr_read,
+ nested_vmcb->control.intercept_cr_write,
+ nested_vmcb->control.intercept_dr_read,
+ nested_vmcb->control.intercept_dr_write,
+ nested_vmcb->control.intercept_exceptions,
+ nested_vmcb->control.intercept,
+ nested_vmcb->control.msrpm_base_pa,
+ nested_vmcb->control.iopm_base_pa,
+ nested_vmcb->control.tsc_offset };
+
+ /* Give the current vmcb to the guest */
+ memcpy(nested_vmcb, svm->vmcb, sizeof(struct vmcb));
+ nested_vmcb->save.cr0 = nested_save[0];
+ if (!npt_enabled)
+ nested_vmcb->save.cr3 = nested_save[1];
+ nested_vmcb->save.cr4 = nested_save[2];
+ nested_vmcb->save.efer = nested_save[3];
+ nested_vmcb->control.intercept_cr_read = nested_save[4];
+ nested_vmcb->control.intercept_cr_write = nested_save[5];
+ nested_vmcb->control.intercept_dr_read = nested_save[6];
+ nested_vmcb->control.intercept_dr_write = nested_save[7];
+ nested_vmcb->control.intercept_exceptions = nested_save[8];
+ nested_vmcb->control.intercept = nested_save[9];
+ nested_vmcb->control.msrpm_base_pa = nested_save[10];
+ nested_vmcb->control.iopm_base_pa = nested_save[11];
+ nested_vmcb->control.tsc_offset = nested_save[12];
+
+ /* We always set V_INTR_MASKING and remember the old value in hflags */
+ if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
+ nested_vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
+
+ if ((nested_vmcb->control.int_ctl & V_IRQ_MASK) &&
+ (nested_vmcb->control.int_vector)) {
+ nsvm_printk("WARNING: IRQ 0x%x still enabled on #VMEXIT\n",
+ nested_vmcb->control.int_vector);
+ }
+
+ /* Restore the original control entries */
+ svm->vmcb->control = hsave->control;
+
+ /* Kill any pending exceptions */
+ if (svm->vcpu.arch.exception.pending == true)
+ nsvm_printk("WARNING: Pending Exception\n");
+ svm->vcpu.arch.exception.pending = false;
+
+ /* Restore selected save entries */
+ svm->vmcb->save.es = hsave->save.es;
+ svm->vmcb->save.cs = hsave->save.cs;
+ svm->vmcb->save.ss = hsave->save.ss;
+ svm->vmcb->save.ds = hsave->save.ds;
+ svm->vmcb->save.gdtr = hsave->save.gdtr;
+ svm->vmcb->save.idtr = hsave->save.idtr;
+ svm->vmcb->save.rflags = hsave->save.rflags;
+ svm_set_efer(&svm->vcpu, hsave->save.efer);
+ svm_set_cr0(&svm->vcpu, hsave->save.cr0 | X86_CR0_PE);
+ svm_set_cr4(&svm->vcpu, hsave->save.cr4);
+ if (npt_enabled) {
+ svm->vmcb->save.cr3 = hsave->save.cr3;
+ svm->vcpu.arch.cr3 = hsave->save.cr3;
+ } else {
+ kvm_set_cr3(&svm->vcpu, hsave->save.cr3);
+ }
+ kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, hsave->save.rax);
+ kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, hsave->save.rsp);
+ kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, hsave->save.rip);
+ svm->vmcb->save.dr7 = 0;
+ svm->vmcb->save.cpl = 0;
+ svm->vmcb->control.exit_int_info = 0;
+
+ svm->vcpu.arch.hflags &= ~HF_GIF_MASK;
+ /* Exit nested SVM mode */
+ svm->nested_vmcb = 0;
+
+ return 0;
+}
+
+static int nested_svm_vmexit(struct vcpu_svm *svm)
+{
+ nsvm_printk("VMexit\n");
+ if (nested_svm_do(svm, svm->nested_vmcb, 0,
+ NULL, nested_svm_vmexit_real))
+ return 1;
+
+ kvm_mmu_reset_context(&svm->vcpu);
+ kvm_mmu_load(&svm->vcpu);
+
+ return 0;
+}
+
+static int nested_svm_vmrun_msrpm(struct vcpu_svm *svm, void *arg1,
+ void *arg2, void *opaque)
+{
+ int i;
+ u32 *nested_msrpm = (u32*)arg1;
+ for (i=0; i< PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++)
+ svm->nested_msrpm[i] = svm->msrpm[i] | nested_msrpm[i];
+ svm->vmcb->control.msrpm_base_pa = __pa(svm->nested_msrpm);
+
+ return 0;
+}
+
+static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1,
+ void *arg2, void *opaque)
+{
+ struct vmcb *nested_vmcb = (struct vmcb *)arg1;
+ struct vmcb *hsave = svm->hsave;
+
+ /* nested_vmcb is our indicator if nested SVM is activated */
+ svm->nested_vmcb = svm->vmcb->save.rax;
+
+ /* Clear internal status */
+ svm->vcpu.arch.exception.pending = false;
+
+ /* Save the old vmcb, so we don't need to pick what we save, but
+ can restore everything when a VMEXIT occurs */
+ memcpy(hsave, svm->vmcb, sizeof(struct vmcb));
+ /* We need to remember the original CR3 in the SPT case */
+ if (!npt_enabled)
+ hsave->save.cr3 = svm->vcpu.arch.cr3;
+ hsave->save.cr4 = svm->vcpu.arch.cr4;
+ hsave->save.rip = svm->next_rip;
+
+ if (svm->vmcb->save.rflags & X86_EFLAGS_IF)
+ svm->vcpu.arch.hflags |= HF_HIF_MASK;
+ else
+ svm->vcpu.arch.hflags &= ~HF_HIF_MASK;
+
+ /* Load the nested guest state */
+ svm->vmcb->save.es = nested_vmcb->save.es;
+ svm->vmcb->save.cs = nested_vmcb->save.cs;
+ svm->vmcb->save.ss = nested_vmcb->save.ss;
+ svm->vmcb->save.ds = nested_vmcb->save.ds;
+ svm->vmcb->save.gdtr = nested_vmcb->save.gdtr;
+ svm->vmcb->save.idtr = nested_vmcb->save.idtr;
+ svm->vmcb->save.rflags = nested_vmcb->save.rflags;
+ svm_set_efer(&svm->vcpu, nested_vmcb->save.efer);
+ svm_set_cr0(&svm->vcpu, nested_vmcb->save.cr0);
+ svm_set_cr4(&svm->vcpu, nested_vmcb->save.cr4);
+ if (npt_enabled) {
+ svm->vmcb->save.cr3 = nested_vmcb->save.cr3;
+ svm->vcpu.arch.cr3 = nested_vmcb->save.cr3;
+ } else {
+ kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3);
+ kvm_mmu_reset_context(&svm->vcpu);
+ }
+ svm->vmcb->save.cr2 = nested_vmcb->save.cr2;
+ kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, nested_vmcb->save.rax);
+ kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, nested_vmcb->save.rsp);
+ kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, nested_vmcb->save.rip);
+ /* In case we don't even reach vcpu_run, the fields are not updated */
+ svm->vmcb->save.rax = nested_vmcb->save.rax;
+ svm->vmcb->save.rsp = nested_vmcb->save.rsp;
+ svm->vmcb->save.rip = nested_vmcb->save.rip;
+ svm->vmcb->save.dr7 = nested_vmcb->save.dr7;
+ svm->vmcb->save.dr6 = nested_vmcb->save.dr6;
+ svm->vmcb->save.cpl = nested_vmcb->save.cpl;
+
+ /* We don't want a nested guest to be more powerful than the guest,
+ so all intercepts are ORed */
+ svm->vmcb->control.intercept_cr_read |=
+ nested_vmcb->control.intercept_cr_read;
+ svm->vmcb->control.intercept_cr_write |=
+ nested_vmcb->control.intercept_cr_write;
+ svm->vmcb->control.intercept_dr_read |=
+ nested_vmcb->control.intercept_dr_read;
+ svm->vmcb->control.intercept_dr_write |=
+ nested_vmcb->control.intercept_dr_write;
+ svm->vmcb->control.intercept_exceptions |=
+ nested_vmcb->control.intercept_exceptions;
+
+ svm->vmcb->control.intercept |= nested_vmcb->control.intercept;
+
+ svm->nested_vmcb_msrpm = nested_vmcb->control.msrpm_base_pa;
+
+ force_new_asid(&svm->vcpu);
+ svm->vmcb->control.exit_int_info = nested_vmcb->control.exit_int_info;
+ svm->vmcb->control.exit_int_info_err = nested_vmcb->control.exit_int_info_err;
+ svm->vmcb->control.int_ctl = nested_vmcb->control.int_ctl | V_INTR_MASKING_MASK;
+ if (nested_vmcb->control.int_ctl & V_IRQ_MASK) {
+ nsvm_printk("nSVM Injecting Interrupt: 0x%x\n",
+ nested_vmcb->control.int_ctl);
+ }
+ if (nested_vmcb->control.int_ctl & V_INTR_MASKING_MASK)
+ svm->vcpu.arch.hflags |= HF_VINTR_MASK;
+ else
+ svm->vcpu.arch.hflags &= ~HF_VINTR_MASK;
+
+ nsvm_printk("nSVM exit_int_info: 0x%x | int_state: 0x%x\n",
+ nested_vmcb->control.exit_int_info,
+ nested_vmcb->control.int_state);
+
+ svm->vmcb->control.int_vector = nested_vmcb->control.int_vector;
+ svm->vmcb->control.int_state = nested_vmcb->control.int_state;
+ svm->vmcb->control.tsc_offset += nested_vmcb->control.tsc_offset;
+ if (nested_vmcb->control.event_inj & SVM_EVTINJ_VALID)
+ nsvm_printk("Injecting Event: 0x%x\n",
+ nested_vmcb->control.event_inj);
+ svm->vmcb->control.event_inj = nested_vmcb->control.event_inj;
+ svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err;
+
+ svm->vcpu.arch.hflags |= HF_GIF_MASK;
+
+ return 0;
+}
+
+static int nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb)
+{
+ to_vmcb->save.fs = from_vmcb->save.fs;
+ to_vmcb->save.gs = from_vmcb->save.gs;
+ to_vmcb->save.tr = from_vmcb->save.tr;
+ to_vmcb->save.ldtr = from_vmcb->save.ldtr;
+ to_vmcb->save.kernel_gs_base = from_vmcb->save.kernel_gs_base;
+ to_vmcb->save.star = from_vmcb->save.star;
+ to_vmcb->save.lstar = from_vmcb->save.lstar;
+ to_vmcb->save.cstar = from_vmcb->save.cstar;
+ to_vmcb->save.sfmask = from_vmcb->save.sfmask;
+ to_vmcb->save.sysenter_cs = from_vmcb->save.sysenter_cs;
+ to_vmcb->save.sysenter_esp = from_vmcb->save.sysenter_esp;
+ to_vmcb->save.sysenter_eip = from_vmcb->save.sysenter_eip;
+
+ return 1;
+}
+
+static int nested_svm_vmload(struct vcpu_svm *svm, void *nested_vmcb,
+ void *arg2, void *opaque)
+{
+ return nested_svm_vmloadsave((struct vmcb *)nested_vmcb, svm->vmcb);
+}
+
+static int nested_svm_vmsave(struct vcpu_svm *svm, void *nested_vmcb,
+ void *arg2, void *opaque)
+{
+ return nested_svm_vmloadsave(svm->vmcb, (struct vmcb *)nested_vmcb);
+}
+
+static int vmload_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+ if (nested_svm_check_permissions(svm))
+ return 1;
+
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+ skip_emulated_instruction(&svm->vcpu);
+
+ nested_svm_do(svm, svm->vmcb->save.rax, 0, NULL, nested_svm_vmload);
+
+ return 1;
+}
+
+static int vmsave_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+ if (nested_svm_check_permissions(svm))
+ return 1;
+
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+ skip_emulated_instruction(&svm->vcpu);
+
+ nested_svm_do(svm, svm->vmcb->save.rax, 0, NULL, nested_svm_vmsave);
+
+ return 1;
+}
+
+static int vmrun_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+ nsvm_printk("VMrun\n");
+ if (nested_svm_check_permissions(svm))
+ return 1;
+
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+ skip_emulated_instruction(&svm->vcpu);
+
+ if (nested_svm_do(svm, svm->vmcb->save.rax, 0,
+ NULL, nested_svm_vmrun))
+ return 1;
+
+ if (nested_svm_do(svm, svm->nested_vmcb_msrpm, 0,
+ NULL, nested_svm_vmrun_msrpm))
+ return 1;
+
+ return 1;
+}
+
+static int stgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+ if (nested_svm_check_permissions(svm))
+ return 1;
+
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+ skip_emulated_instruction(&svm->vcpu);
+
+ svm->vcpu.arch.hflags |= HF_GIF_MASK;
+
+ return 1;
+}
+
+static int clgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+ if (nested_svm_check_permissions(svm))
+ return 1;
+
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+ skip_emulated_instruction(&svm->vcpu);
+
+ svm->vcpu.arch.hflags &= ~HF_GIF_MASK;
+
+ /* After a CLGI no interrupts should come */
+ svm_clear_vintr(svm);
+ svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
+
+ return 1;
+}
+
static int invalid_op_interception(struct vcpu_svm *svm,
struct kvm_run *kvm_run)
{
@@ -1250,6 +1940,15 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
case MSR_IA32_LASTINTTOIP:
*data = svm->vmcb->save.last_excp_to;
break;
+ case MSR_VM_HSAVE_PA:
+ *data = svm->hsave_msr;
+ break;
+ case MSR_VM_CR:
+ *data = 0;
+ break;
+ case MSR_IA32_UCODE_REV:
+ *data = 0x01000065;
+ break;
default:
return kvm_get_msr_common(vcpu, ecx, data);
}
@@ -1344,6 +2043,9 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
pr_unimpl(vcpu, "unimplemented perfctr wrmsr: 0x%x data 0x%llx\n", ecx, data);
break;
+ case MSR_VM_HSAVE_PA:
+ svm->hsave_msr = data;
+ break;
default:
return kvm_set_msr_common(vcpu, ecx, data);
}
@@ -1380,7 +2082,7 @@ static int interrupt_window_interception(struct vcpu_svm *svm,
{
KVMTRACE_0D(PEND_INTR, &svm->vcpu, handler);
- svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VINTR);
+ svm_clear_vintr(svm);
svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
/*
* If the user space waits to inject interrupts, exit as soon as
@@ -1417,6 +2119,8 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
[SVM_EXIT_WRITE_DR3] = emulate_on_interception,
[SVM_EXIT_WRITE_DR5] = emulate_on_interception,
[SVM_EXIT_WRITE_DR7] = emulate_on_interception,
+ [SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception,
+ [SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception,
[SVM_EXIT_EXCP_BASE + UD_VECTOR] = ud_interception,
[SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception,
[SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception,
@@ -1436,12 +2140,12 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
[SVM_EXIT_MSR] = msr_interception,
[SVM_EXIT_TASK_SWITCH] = task_switch_interception,
[SVM_EXIT_SHUTDOWN] = shutdown_interception,
- [SVM_EXIT_VMRUN] = invalid_op_interception,
+ [SVM_EXIT_VMRUN] = vmrun_interception,
[SVM_EXIT_VMMCALL] = vmmcall_interception,
- [SVM_EXIT_VMLOAD] = invalid_op_interception,
- [SVM_EXIT_VMSAVE] = invalid_op_interception,
- [SVM_EXIT_STGI] = invalid_op_interception,
- [SVM_EXIT_CLGI] = invalid_op_interception,
+ [SVM_EXIT_VMLOAD] = vmload_interception,
+ [SVM_EXIT_VMSAVE] = vmsave_interception,
+ [SVM_EXIT_STGI] = stgi_interception,
+ [SVM_EXIT_CLGI] = clgi_interception,
[SVM_EXIT_SKINIT] = invalid_op_interception,
[SVM_EXIT_WBINVD] = emulate_on_interception,
[SVM_EXIT_MONITOR] = invalid_op_interception,
@@ -1457,6 +2161,17 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
KVMTRACE_3D(VMEXIT, vcpu, exit_code, (u32)svm->vmcb->save.rip,
(u32)((u64)svm->vmcb->save.rip >> 32), entryexit);
+ if (is_nested(svm)) {
+ nsvm_printk("nested handle_exit: 0x%x | 0x%lx | 0x%lx | 0x%lx\n",
+ exit_code, svm->vmcb->control.exit_info_1,
+ svm->vmcb->control.exit_info_2, svm->vmcb->save.rip);
+ if (nested_svm_exit_handled(svm, true)) {
+ nested_svm_vmexit(svm);
+ nsvm_printk("-> #VMEXIT\n");
+ return 1;
+ }
+ }
+
if (npt_enabled) {
int mmu_reload = 0;
if ((vcpu->arch.cr0 ^ svm->vmcb->save.cr0) & X86_CR0_PG) {
@@ -1544,6 +2259,8 @@ static void svm_set_irq(struct kvm_vcpu *vcpu, int irq)
{
struct vcpu_svm *svm = to_svm(vcpu);
+ nested_svm_intr(svm);
+
svm_inject_irq(svm, irq);
}
@@ -1589,11 +2306,17 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu)
if (!kvm_cpu_has_interrupt(vcpu))
goto out;
+ if (nested_svm_intr(svm))
+ goto out;
+
+ if (!(svm->vcpu.arch.hflags & HF_GIF_MASK))
+ goto out;
+
if (!(vmcb->save.rflags & X86_EFLAGS_IF) ||
(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) ||
(vmcb->control.event_inj & SVM_EVTINJ_VALID)) {
/* unable to deliver irq, set pending irq */
- vmcb->control.intercept |= (1ULL << INTERCEPT_VINTR);
+ svm_set_vintr(svm);
svm_inject_irq(svm, 0x0);
goto out;
}
@@ -1615,7 +2338,8 @@ static void kvm_reput_irq(struct vcpu_svm *svm)
}
svm->vcpu.arch.interrupt_window_open =
- !(control->int_state & SVM_INTERRUPT_SHADOW_MASK);
+ !(control->int_state & SVM_INTERRUPT_SHADOW_MASK) &&
+ (svm->vcpu.arch.hflags & HF_GIF_MASK);
}
static void svm_do_inject_vector(struct vcpu_svm *svm)
@@ -1637,9 +2361,13 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
struct vcpu_svm *svm = to_svm(vcpu);
struct vmcb_control_area *control = &svm->vmcb->control;
+ if (nested_svm_intr(svm))
+ return;
+
svm->vcpu.arch.interrupt_window_open =
(!(control->int_state & SVM_INTERRUPT_SHADOW_MASK) &&
- (svm->vmcb->save.rflags & X86_EFLAGS_IF));
+ (svm->vmcb->save.rflags & X86_EFLAGS_IF) &&
+ (svm->vcpu.arch.hflags & HF_GIF_MASK));
if (svm->vcpu.arch.interrupt_window_open && svm->vcpu.arch.irq_summary)
/*
@@ -1652,9 +2380,9 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
*/
if (!svm->vcpu.arch.interrupt_window_open &&
(svm->vcpu.arch.irq_summary || kvm_run->request_interrupt_window))
- control->intercept |= 1ULL << INTERCEPT_VINTR;
- else
- control->intercept &= ~(1ULL << INTERCEPT_VINTR);
+ svm_set_vintr(svm);
+ else
+ svm_clear_vintr(svm);
}
static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr)
@@ -1662,22 +2390,6 @@ static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr)
return 0;
}
-static void save_db_regs(unsigned long *db_regs)
-{
- asm volatile ("mov %%dr0, %0" : "=r"(db_regs[0]));
- asm volatile ("mov %%dr1, %0" : "=r"(db_regs[1]));
- asm volatile ("mov %%dr2, %0" : "=r"(db_regs[2]));
- asm volatile ("mov %%dr3, %0" : "=r"(db_regs[3]));
-}
-
-static void load_db_regs(unsigned long *db_regs)
-{
- asm volatile ("mov %0, %%dr0" : : "r"(db_regs[0]));
- asm volatile ("mov %0, %%dr1" : : "r"(db_regs[1]));
- asm volatile ("mov %0, %%dr2" : : "r"(db_regs[2]));
- asm volatile ("mov %0, %%dr3" : : "r"(db_regs[3]));
-}
-
static void svm_flush_tlb(struct kvm_vcpu *vcpu)
{
force_new_asid(vcpu);
@@ -1736,19 +2448,12 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
gs_selector = kvm_read_gs();
ldt_selector = kvm_read_ldt();
svm->host_cr2 = kvm_read_cr2();
- svm->host_dr6 = read_dr6();
- svm->host_dr7 = read_dr7();
- svm->vmcb->save.cr2 = vcpu->arch.cr2;
+ if (!is_nested(svm))
+ svm->vmcb->save.cr2 = vcpu->arch.cr2;
/* required for live migration with NPT */
if (npt_enabled)
svm->vmcb->save.cr3 = vcpu->arch.cr3;
- if (svm->vmcb->save.dr7 & 0xff) {
- write_dr7(0);
- save_db_regs(svm->host_db_regs);
- load_db_regs(svm->db_regs);
- }
-
clgi();
local_irq_enable();
@@ -1824,16 +2529,11 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
#endif
);
- if ((svm->vmcb->save.dr7 & 0xff))
- load_db_regs(svm->host_db_regs);
-
vcpu->arch.cr2 = svm->vmcb->save.cr2;
vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax;
vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
- write_dr6(svm->host_dr6);
- write_dr7(svm->host_dr7);
kvm_write_cr2(svm->host_cr2);
kvm_load_fs(fs_selector);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7611af576829..bb481330716f 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -91,6 +91,7 @@ struct vcpu_vmx {
} rmode;
int vpid;
bool emulation_required;
+ enum emulation_result invalid_state_emulation_result;
/* Support for vnmi-less CPUs */
int soft_vnmi_blocked;
@@ -189,21 +190,21 @@ static inline int is_page_fault(u32 intr_info)
{
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
INTR_INFO_VALID_MASK)) ==
- (INTR_TYPE_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK);
+ (INTR_TYPE_HARD_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK);
}
static inline int is_no_device(u32 intr_info)
{
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
INTR_INFO_VALID_MASK)) ==
- (INTR_TYPE_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK);
+ (INTR_TYPE_HARD_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK);
}
static inline int is_invalid_opcode(u32 intr_info)
{
return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
INTR_INFO_VALID_MASK)) ==
- (INTR_TYPE_EXCEPTION | UD_VECTOR | INTR_INFO_VALID_MASK);
+ (INTR_TYPE_HARD_EXCEPTION | UD_VECTOR | INTR_INFO_VALID_MASK);
}
static inline int is_external_interrupt(u32 intr_info)
@@ -480,8 +481,13 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
eb = (1u << PF_VECTOR) | (1u << UD_VECTOR);
if (!vcpu->fpu_active)
eb |= 1u << NM_VECTOR;
- if (vcpu->guest_debug.enabled)
- eb |= 1u << DB_VECTOR;
+ if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
+ if (vcpu->guest_debug &
+ (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
+ eb |= 1u << DB_VECTOR;
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+ eb |= 1u << BP_VECTOR;
+ }
if (vcpu->arch.rmode.active)
eb = ~0;
if (vm_need_ept())
@@ -747,29 +753,33 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
bool has_error_code, u32 error_code)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
+ u32 intr_info = nr | INTR_INFO_VALID_MASK;
- if (has_error_code)
+ if (has_error_code) {
vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
+ intr_info |= INTR_INFO_DELIVER_CODE_MASK;
+ }
if (vcpu->arch.rmode.active) {
vmx->rmode.irq.pending = true;
vmx->rmode.irq.vector = nr;
vmx->rmode.irq.rip = kvm_rip_read(vcpu);
- if (nr == BP_VECTOR)
+ if (nr == BP_VECTOR || nr == OF_VECTOR)
vmx->rmode.irq.rip++;
- vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
- nr | INTR_TYPE_SOFT_INTR
- | (has_error_code ? INTR_INFO_DELIVER_CODE_MASK : 0)
- | INTR_INFO_VALID_MASK);
+ intr_info |= INTR_TYPE_SOFT_INTR;
+ vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
return;
}
- vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
- nr | INTR_TYPE_EXCEPTION
- | (has_error_code ? INTR_INFO_DELIVER_CODE_MASK : 0)
- | INTR_INFO_VALID_MASK);
+ if (nr == BP_VECTOR || nr == OF_VECTOR) {
+ vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
+ intr_info |= INTR_TYPE_SOFT_EXCEPTION;
+ } else
+ intr_info |= INTR_TYPE_HARD_EXCEPTION;
+
+ vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
}
static bool vmx_exception_injected(struct kvm_vcpu *vcpu)
@@ -856,11 +866,8 @@ static u64 guest_read_tsc(void)
* writes 'guest_tsc' into guest's timestamp counter "register"
* guest_tsc = host_tsc + tsc_offset ==> tsc_offset = guest_tsc - host_tsc
*/
-static void guest_write_tsc(u64 guest_tsc)
+static void guest_write_tsc(u64 guest_tsc, u64 host_tsc)
{
- u64 host_tsc;
-
- rdtscll(host_tsc);
vmcs_write64(TSC_OFFSET, guest_tsc - host_tsc);
}
@@ -925,14 +932,15 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
struct kvm_msr_entry *msr;
+ u64 host_tsc;
int ret = 0;
switch (msr_index) {
-#ifdef CONFIG_X86_64
case MSR_EFER:
vmx_load_host_state(vmx);
ret = kvm_set_msr_common(vcpu, msr_index, data);
break;
+#ifdef CONFIG_X86_64
case MSR_FS_BASE:
vmcs_writel(GUEST_FS_BASE, data);
break;
@@ -950,7 +958,8 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
vmcs_writel(GUEST_SYSENTER_ESP, data);
break;
case MSR_IA32_TIME_STAMP_COUNTER:
- guest_write_tsc(data);
+ rdtscll(host_tsc);
+ guest_write_tsc(data, host_tsc);
break;
case MSR_P6_PERFCTR0:
case MSR_P6_PERFCTR1:
@@ -999,40 +1008,28 @@ static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
}
}
-static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg)
+static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_guest_debug *dbg)
{
- unsigned long dr7 = 0x400;
- int old_singlestep;
-
- old_singlestep = vcpu->guest_debug.singlestep;
-
- vcpu->guest_debug.enabled = dbg->enabled;
- if (vcpu->guest_debug.enabled) {
- int i;
+ int old_debug = vcpu->guest_debug;
+ unsigned long flags;
- dr7 |= 0x200; /* exact */
- for (i = 0; i < 4; ++i) {
- if (!dbg->breakpoints[i].enabled)
- continue;
- vcpu->guest_debug.bp[i] = dbg->breakpoints[i].address;
- dr7 |= 2 << (i*2); /* global enable */
- dr7 |= 0 << (i*4+16); /* execution breakpoint */
- }
+ vcpu->guest_debug = dbg->control;
+ if (!(vcpu->guest_debug & KVM_GUESTDBG_ENABLE))
+ vcpu->guest_debug = 0;
- vcpu->guest_debug.singlestep = dbg->singlestep;
- } else
- vcpu->guest_debug.singlestep = 0;
-
- if (old_singlestep && !vcpu->guest_debug.singlestep) {
- unsigned long flags;
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
+ vmcs_writel(GUEST_DR7, dbg->arch.debugreg[7]);
+ else
+ vmcs_writel(GUEST_DR7, vcpu->arch.dr7);
- flags = vmcs_readl(GUEST_RFLAGS);
+ flags = vmcs_readl(GUEST_RFLAGS);
+ if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+ flags |= X86_EFLAGS_TF | X86_EFLAGS_RF;
+ else if (old_debug & KVM_GUESTDBG_SINGLESTEP)
flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF);
- vmcs_writel(GUEST_RFLAGS, flags);
- }
+ vmcs_writel(GUEST_RFLAGS, flags);
update_exception_bitmap(vcpu);
- vmcs_writel(GUEST_DR7, dr7);
return 0;
}
@@ -1433,6 +1430,29 @@ continue_rmode:
init_rmode(vcpu->kvm);
}
+static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
+{
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ struct kvm_msr_entry *msr = find_msr_entry(vmx, MSR_EFER);
+
+ vcpu->arch.shadow_efer = efer;
+ if (!msr)
+ return;
+ if (efer & EFER_LMA) {
+ vmcs_write32(VM_ENTRY_CONTROLS,
+ vmcs_read32(VM_ENTRY_CONTROLS) |
+ VM_ENTRY_IA32E_MODE);
+ msr->data = efer;
+ } else {
+ vmcs_write32(VM_ENTRY_CONTROLS,
+ vmcs_read32(VM_ENTRY_CONTROLS) &
+ ~VM_ENTRY_IA32E_MODE);
+
+ msr->data = efer & ~EFER_LME;
+ }
+ setup_msrs(vmx);
+}
+
#ifdef CONFIG_X86_64
static void enter_lmode(struct kvm_vcpu *vcpu)
@@ -1447,13 +1467,8 @@ static void enter_lmode(struct kvm_vcpu *vcpu)
(guest_tr_ar & ~AR_TYPE_MASK)
| AR_TYPE_BUSY_64_TSS);
}
-
vcpu->arch.shadow_efer |= EFER_LMA;
-
- find_msr_entry(to_vmx(vcpu), MSR_EFER)->data |= EFER_LMA | EFER_LME;
- vmcs_write32(VM_ENTRY_CONTROLS,
- vmcs_read32(VM_ENTRY_CONTROLS)
- | VM_ENTRY_IA32E_MODE);
+ vmx_set_efer(vcpu, vcpu->arch.shadow_efer);
}
static void exit_lmode(struct kvm_vcpu *vcpu)
@@ -1612,30 +1627,6 @@ static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
vmcs_writel(GUEST_CR4, hw_cr4);
}
-static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
-{
- struct vcpu_vmx *vmx = to_vmx(vcpu);
- struct kvm_msr_entry *msr = find_msr_entry(vmx, MSR_EFER);
-
- vcpu->arch.shadow_efer = efer;
- if (!msr)
- return;
- if (efer & EFER_LMA) {
- vmcs_write32(VM_ENTRY_CONTROLS,
- vmcs_read32(VM_ENTRY_CONTROLS) |
- VM_ENTRY_IA32E_MODE);
- msr->data = efer;
-
- } else {
- vmcs_write32(VM_ENTRY_CONTROLS,
- vmcs_read32(VM_ENTRY_CONTROLS) &
- ~VM_ENTRY_IA32E_MODE);
-
- msr->data = efer & ~EFER_LME;
- }
- setup_msrs(vmx);
-}
-
static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
{
struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
@@ -1653,7 +1644,7 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu,
var->limit = vmcs_read32(sf->limit);
var->selector = vmcs_read16(sf->selector);
ar = vmcs_read32(sf->ar_bytes);
- if (ar & AR_UNUSABLE_MASK)
+ if ((ar & AR_UNUSABLE_MASK) && !emulate_invalid_guest_state)
ar = 0;
var->type = ar & 15;
var->s = (ar >> 4) & 1;
@@ -1788,14 +1779,16 @@ static bool code_segment_valid(struct kvm_vcpu *vcpu)
vmx_get_segment(vcpu, &cs, VCPU_SREG_CS);
cs_rpl = cs.selector & SELECTOR_RPL_MASK;
+ if (cs.unusable)
+ return false;
if (~cs.type & (AR_TYPE_CODE_MASK|AR_TYPE_ACCESSES_MASK))
return false;
if (!cs.s)
return false;
- if (!(~cs.type & (AR_TYPE_CODE_MASK|AR_TYPE_WRITEABLE_MASK))) {
+ if (cs.type & AR_TYPE_WRITEABLE_MASK) {
if (cs.dpl > cs_rpl)
return false;
- } else if (cs.type & AR_TYPE_CODE_MASK) {
+ } else {
if (cs.dpl != cs_rpl)
return false;
}
@@ -1814,7 +1807,9 @@ static bool stack_segment_valid(struct kvm_vcpu *vcpu)
vmx_get_segment(vcpu, &ss, VCPU_SREG_SS);
ss_rpl = ss.selector & SELECTOR_RPL_MASK;
- if ((ss.type != 3) || (ss.type != 7))
+ if (ss.unusable)
+ return true;
+ if (ss.type != 3 && ss.type != 7)
return false;
if (!ss.s)
return false;
@@ -1834,6 +1829,8 @@ static bool data_segment_valid(struct kvm_vcpu *vcpu, int seg)
vmx_get_segment(vcpu, &var, seg);
rpl = var.selector & SELECTOR_RPL_MASK;
+ if (var.unusable)
+ return true;
if (!var.s)
return false;
if (!var.present)
@@ -1855,9 +1852,11 @@ static bool tr_valid(struct kvm_vcpu *vcpu)
vmx_get_segment(vcpu, &tr, VCPU_SREG_TR);
+ if (tr.unusable)
+ return false;
if (tr.selector & SELECTOR_TI_MASK) /* TI = 1 */
return false;
- if ((tr.type != 3) || (tr.type != 11)) /* TODO: Check if guest is in IA32e mode */
+ if (tr.type != 3 && tr.type != 11) /* TODO: Check if guest is in IA32e mode */
return false;
if (!tr.present)
return false;
@@ -1871,6 +1870,8 @@ static bool ldtr_valid(struct kvm_vcpu *vcpu)
vmx_get_segment(vcpu, &ldtr, VCPU_SREG_LDTR);
+ if (ldtr.unusable)
+ return true;
if (ldtr.selector & SELECTOR_TI_MASK) /* TI = 1 */
return false;
if (ldtr.type != 2)
@@ -2112,7 +2113,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
{
u32 host_sysenter_cs, msr_low, msr_high;
u32 junk;
- u64 host_pat;
+ u64 host_pat, tsc_this, tsc_base;
unsigned long a;
struct descriptor_table dt;
int i;
@@ -2240,6 +2241,12 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL);
vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK);
+ tsc_base = vmx->vcpu.kvm->arch.vm_init_tsc;
+ rdtscll(tsc_this);
+ if (tsc_this < vmx->vcpu.kvm->arch.vm_init_tsc)
+ tsc_base = tsc_this;
+
+ guest_write_tsc(0, tsc_base);
return 0;
}
@@ -2319,7 +2326,6 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
kvm_rip_write(vcpu, 0);
kvm_register_write(vcpu, VCPU_REGS_RSP, 0);
- /* todo: dr0 = dr1 = dr2 = dr3 = 0; dr6 = 0xffff0ff0 */
vmcs_writel(GUEST_DR7, 0x400);
vmcs_writel(GUEST_GDTR_BASE, 0);
@@ -2332,8 +2338,6 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0);
vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0);
- guest_write_tsc(0);
-
/* Special registers */
vmcs_write64(GUEST_IA32_DEBUGCTL, 0);
@@ -2486,6 +2490,11 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
{
vmx_update_window_states(vcpu);
+ if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+ vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
+ GUEST_INTR_STATE_STI |
+ GUEST_INTR_STATE_MOV_SS);
+
if (vcpu->arch.nmi_pending && !vcpu->arch.nmi_injected) {
if (vcpu->arch.interrupt.pending) {
enable_nmi_window(vcpu);
@@ -2536,24 +2545,6 @@ static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
return 0;
}
-static void kvm_guest_debug_pre(struct kvm_vcpu *vcpu)
-{
- struct kvm_guest_debug *dbg = &vcpu->guest_debug;
-
- set_debugreg(dbg->bp[0], 0);
- set_debugreg(dbg->bp[1], 1);
- set_debugreg(dbg->bp[2], 2);
- set_debugreg(dbg->bp[3], 3);
-
- if (dbg->singlestep) {
- unsigned long flags;
-
- flags = vmcs_readl(GUEST_RFLAGS);
- flags |= X86_EFLAGS_TF | X86_EFLAGS_RF;
- vmcs_writel(GUEST_RFLAGS, flags);
- }
-}
-
static int handle_rmode_exception(struct kvm_vcpu *vcpu,
int vec, u32 err_code)
{
@@ -2570,9 +2561,17 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu,
* the required debugging infrastructure rework.
*/
switch (vec) {
- case DE_VECTOR:
case DB_VECTOR:
+ if (vcpu->guest_debug &
+ (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
+ return 0;
+ kvm_queue_exception(vcpu, vec);
+ return 1;
case BP_VECTOR:
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+ return 0;
+ /* fall through */
+ case DE_VECTOR:
case OF_VECTOR:
case BR_VECTOR:
case UD_VECTOR:
@@ -2589,8 +2588,8 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu,
static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- u32 intr_info, error_code;
- unsigned long cr2, rip;
+ u32 intr_info, ex_no, error_code;
+ unsigned long cr2, rip, dr6;
u32 vect_info;
enum emulation_result er;
@@ -2649,14 +2648,30 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return 1;
}
- if ((intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK)) ==
- (INTR_TYPE_EXCEPTION | 1)) {
+ ex_no = intr_info & INTR_INFO_VECTOR_MASK;
+ switch (ex_no) {
+ case DB_VECTOR:
+ dr6 = vmcs_readl(EXIT_QUALIFICATION);
+ if (!(vcpu->guest_debug &
+ (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))) {
+ vcpu->arch.dr6 = dr6 | DR6_FIXED_1;
+ kvm_queue_exception(vcpu, DB_VECTOR);
+ return 1;
+ }
+ kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1;
+ kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7);
+ /* fall through */
+ case BP_VECTOR:
kvm_run->exit_reason = KVM_EXIT_DEBUG;
- return 0;
+ kvm_run->debug.arch.pc = vmcs_readl(GUEST_CS_BASE) + rip;
+ kvm_run->debug.arch.exception = ex_no;
+ break;
+ default:
+ kvm_run->exit_reason = KVM_EXIT_EXCEPTION;
+ kvm_run->ex.exception = ex_no;
+ kvm_run->ex.error_code = error_code;
+ break;
}
- kvm_run->exit_reason = KVM_EXIT_EXCEPTION;
- kvm_run->ex.exception = intr_info & INTR_INFO_VECTOR_MASK;
- kvm_run->ex.error_code = error_code;
return 0;
}
@@ -2677,7 +2692,7 @@ static int handle_triple_fault(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
unsigned long exit_qualification;
- int size, down, in, string, rep;
+ int size, in, string;
unsigned port;
++vcpu->stat.io_exits;
@@ -2693,8 +2708,6 @@ static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
size = (exit_qualification & 7) + 1;
in = (exit_qualification & 8) != 0;
- down = (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_DF) != 0;
- rep = (exit_qualification & 32) != 0;
port = exit_qualification >> 16;
skip_emulated_instruction(vcpu);
@@ -2795,21 +2808,44 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
unsigned long val;
int dr, reg;
- /*
- * FIXME: this code assumes the host is debugging the guest.
- * need to deal with guest debugging itself too.
- */
+ dr = vmcs_readl(GUEST_DR7);
+ if (dr & DR7_GD) {
+ /*
+ * As the vm-exit takes precedence over the debug trap, we
+ * need to emulate the latter, either for the host or the
+ * guest debugging itself.
+ */
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
+ kvm_run->debug.arch.dr6 = vcpu->arch.dr6;
+ kvm_run->debug.arch.dr7 = dr;
+ kvm_run->debug.arch.pc =
+ vmcs_readl(GUEST_CS_BASE) +
+ vmcs_readl(GUEST_RIP);
+ kvm_run->debug.arch.exception = DB_VECTOR;
+ kvm_run->exit_reason = KVM_EXIT_DEBUG;
+ return 0;
+ } else {
+ vcpu->arch.dr7 &= ~DR7_GD;
+ vcpu->arch.dr6 |= DR6_BD;
+ vmcs_writel(GUEST_DR7, vcpu->arch.dr7);
+ kvm_queue_exception(vcpu, DB_VECTOR);
+ return 1;
+ }
+ }
+
exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
- dr = exit_qualification & 7;
- reg = (exit_qualification >> 8) & 15;
- if (exit_qualification & 16) {
- /* mov from dr */
+ dr = exit_qualification & DEBUG_REG_ACCESS_NUM;
+ reg = DEBUG_REG_ACCESS_REG(exit_qualification);
+ if (exit_qualification & TYPE_MOV_FROM_DR) {
switch (dr) {
+ case 0 ... 3:
+ val = vcpu->arch.db[dr];
+ break;
case 6:
- val = 0xffff0ff0;
+ val = vcpu->arch.dr6;
break;
case 7:
- val = 0x400;
+ val = vcpu->arch.dr7;
break;
default:
val = 0;
@@ -2817,7 +2853,38 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
kvm_register_write(vcpu, reg, val);
KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler);
} else {
- /* mov to dr */
+ val = vcpu->arch.regs[reg];
+ switch (dr) {
+ case 0 ... 3:
+ vcpu->arch.db[dr] = val;
+ if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
+ vcpu->arch.eff_db[dr] = val;
+ break;
+ case 4 ... 5:
+ if (vcpu->arch.cr4 & X86_CR4_DE)
+ kvm_queue_exception(vcpu, UD_VECTOR);
+ break;
+ case 6:
+ if (val & 0xffffffff00000000ULL) {
+ kvm_queue_exception(vcpu, GP_VECTOR);
+ break;
+ }
+ vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1;
+ break;
+ case 7:
+ if (val & 0xffffffff00000000ULL) {
+ kvm_queue_exception(vcpu, GP_VECTOR);
+ break;
+ }
+ vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1;
+ if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) {
+ vmcs_writel(GUEST_DR7, vcpu->arch.dr7);
+ vcpu->arch.switch_db_regs =
+ (val & DR7_BP_EN_MASK);
+ }
+ break;
+ }
+ KVMTRACE_2D(DR_WRITE, vcpu, (u32)dr, (u32)val, handler);
}
skip_emulated_instruction(vcpu);
return 1;
@@ -2968,17 +3035,25 @@ static int handle_task_switch(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
}
tss_selector = exit_qualification;
- return kvm_task_switch(vcpu, tss_selector, reason);
+ if (!kvm_task_switch(vcpu, tss_selector, reason))
+ return 0;
+
+ /* clear all local breakpoint enable flags */
+ vmcs_writel(GUEST_DR7, vmcs_readl(GUEST_DR7) & ~55);
+
+ /*
+ * TODO: What about debug traps on tss switch?
+ * Are we supposed to inject them and update dr6?
+ */
+
+ return 1;
}
static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
u64 exit_qualification;
- enum emulation_result er;
gpa_t gpa;
- unsigned long hva;
int gla_validity;
- int r;
exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
@@ -3001,32 +3076,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
}
gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
- hva = gfn_to_hva(vcpu->kvm, gpa >> PAGE_SHIFT);
- if (!kvm_is_error_hva(hva)) {
- r = kvm_mmu_page_fault(vcpu, gpa & PAGE_MASK, 0);
- if (r < 0) {
- printk(KERN_ERR "EPT: Not enough memory!\n");
- return -ENOMEM;
- }
- return 1;
- } else {
- /* must be MMIO */
- er = emulate_instruction(vcpu, kvm_run, 0, 0, 0);
-
- if (er == EMULATE_FAIL) {
- printk(KERN_ERR
- "EPT: Fail to handle EPT violation vmexit!er is %d\n",
- er);
- printk(KERN_ERR "EPT: GPA: 0x%lx, GVA: 0x%lx\n",
- (long unsigned int)vmcs_read64(GUEST_PHYSICAL_ADDRESS),
- (long unsigned int)vmcs_read64(GUEST_LINEAR_ADDRESS));
- printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n",
- (long unsigned int)exit_qualification);
- return -ENOTSUPP;
- } else if (er == EMULATE_DO_MMIO)
- return 0;
- }
- return 1;
+ return kvm_mmu_page_fault(vcpu, gpa & PAGE_MASK, 0);
}
static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
@@ -3046,7 +3096,7 @@ static void handle_invalid_guest_state(struct kvm_vcpu *vcpu,
struct kvm_run *kvm_run)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
- int err;
+ enum emulation_result err = EMULATE_DONE;
preempt_enable();
local_irq_enable();
@@ -3071,10 +3121,7 @@ static void handle_invalid_guest_state(struct kvm_vcpu *vcpu,
local_irq_disable();
preempt_disable();
- /* Guest state should be valid now except if we need to
- * emulate an MMIO */
- if (guest_state_valid(vcpu))
- vmx->emulation_required = 0;
+ vmx->invalid_state_emulation_result = err;
}
/*
@@ -3123,8 +3170,11 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
/* If we need to emulate an MMIO from handle_invalid_guest_state
* we just return 0 */
- if (vmx->emulation_required && emulate_invalid_guest_state)
- return 0;
+ if (vmx->emulation_required && emulate_invalid_guest_state) {
+ if (guest_state_valid(vcpu))
+ vmx->emulation_required = 0;
+ return vmx->invalid_state_emulation_result != EMULATE_DO_MMIO;
+ }
/* Access CR3 don't cause VMExit in paging mode, so we need
* to sync with guest real CR3. */
@@ -3238,7 +3288,8 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
vmx->vcpu.arch.nmi_injected = false;
}
kvm_clear_exception_queue(&vmx->vcpu);
- if (idtv_info_valid && type == INTR_TYPE_EXCEPTION) {
+ if (idtv_info_valid && (type == INTR_TYPE_HARD_EXCEPTION ||
+ type == INTR_TYPE_SOFT_EXCEPTION)) {
if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) {
error = vmcs_read32(IDT_VECTORING_ERROR_CODE);
kvm_queue_exception_e(&vmx->vcpu, vector, error);
@@ -3259,6 +3310,11 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu)
vmx_update_window_states(vcpu);
+ if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+ vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
+ GUEST_INTR_STATE_STI |
+ GUEST_INTR_STATE_MOV_SS);
+
if (vcpu->arch.nmi_pending && !vcpu->arch.nmi_injected) {
if (vcpu->arch.interrupt.pending) {
enable_nmi_window(vcpu);
@@ -3347,6 +3403,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
*/
vmcs_writel(HOST_CR0, read_cr0());
+ set_debugreg(vcpu->arch.dr6, 6);
+
asm(
/* Store host registers */
"push %%"R"dx; push %%"R"bp;"
@@ -3441,6 +3499,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP));
vcpu->arch.regs_dirty = 0;
+ get_debugreg(vcpu->arch.dr6, 6);
+
vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
if (vmx->rmode.irq.pending)
fixup_rmode_irq(vmx);
@@ -3595,7 +3655,6 @@ static struct kvm_x86_ops vmx_x86_ops = {
.vcpu_put = vmx_vcpu_put,
.set_guest_debug = set_guest_debug,
- .guest_debug_pre = kvm_guest_debug_pre,
.get_msr = vmx_get_msr,
.set_msr = vmx_set_msr,
.get_segment_base = vmx_get_segment_base,
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 758b7a155ae9..8ca100a9ecac 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -36,6 +36,7 @@
#include <linux/highmem.h>
#include <linux/iommu.h>
#include <linux/intel-iommu.h>
+#include <linux/cpufreq.h>
#include <asm/uaccess.h>
#include <asm/msr.h>
@@ -69,6 +70,8 @@ static u64 __read_mostly efer_reserved_bits = 0xfffffffffffffffeULL;
static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
struct kvm_cpuid_entry2 __user *entries);
+struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
+ u32 function, u32 index);
struct kvm_x86_ops *kvm_x86_ops;
EXPORT_SYMBOL_GPL(kvm_x86_ops);
@@ -173,6 +176,7 @@ void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr,
u32 error_code)
{
++vcpu->stat.pf_guest;
+
if (vcpu->arch.exception.pending) {
if (vcpu->arch.exception.nr == PF_VECTOR) {
printk(KERN_DEBUG "kvm: inject_page_fault:"
@@ -361,6 +365,7 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
}
kvm_x86_ops->set_cr4(vcpu, cr4);
vcpu->arch.cr4 = cr4;
+ vcpu->arch.mmu.base_role.cr4_pge = (cr4 & X86_CR4_PGE) && !tdp_enabled;
kvm_mmu_sync_global(vcpu);
kvm_mmu_reset_context(vcpu);
}
@@ -442,6 +447,11 @@ unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu)
}
EXPORT_SYMBOL_GPL(kvm_get_cr8);
+static inline u32 bit(int bitno)
+{
+ return 1 << (bitno & 31);
+}
+
/*
* List of msr numbers which we expose to userspace through KVM_GET_MSRS
* and KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST.
@@ -456,7 +466,7 @@ static u32 msrs_to_save[] = {
MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
#endif
MSR_IA32_TIME_STAMP_COUNTER, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
- MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT
+ MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA
};
static unsigned num_msrs_to_save;
@@ -481,6 +491,28 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
return;
}
+ if (efer & EFER_FFXSR) {
+ struct kvm_cpuid_entry2 *feat;
+
+ feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
+ if (!feat || !(feat->edx & bit(X86_FEATURE_FXSR_OPT))) {
+ printk(KERN_DEBUG "set_efer: #GP, enable FFXSR w/o CPUID capability\n");
+ kvm_inject_gp(vcpu, 0);
+ return;
+ }
+ }
+
+ if (efer & EFER_SVME) {
+ struct kvm_cpuid_entry2 *feat;
+
+ feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
+ if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM))) {
+ printk(KERN_DEBUG "set_efer: #GP, enable SVM w/o SVM\n");
+ kvm_inject_gp(vcpu, 0);
+ return;
+ }
+ }
+
kvm_x86_ops->set_efer(vcpu, efer);
efer &= ~EFER_LMA;
@@ -586,6 +618,8 @@ static void kvm_set_time_scale(uint32_t tsc_khz, struct pvclock_vcpu_time_info *
hv_clock->tsc_to_system_mul);
}
+static DEFINE_PER_CPU(unsigned long, cpu_tsc_khz);
+
static void kvm_write_guest_time(struct kvm_vcpu *v)
{
struct timespec ts;
@@ -596,9 +630,9 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
if ((!vcpu->time_page))
return;
- if (unlikely(vcpu->hv_clock_tsc_khz != tsc_khz)) {
- kvm_set_time_scale(tsc_khz, &vcpu->hv_clock);
- vcpu->hv_clock_tsc_khz = tsc_khz;
+ if (unlikely(vcpu->hv_clock_tsc_khz != __get_cpu_var(cpu_tsc_khz))) {
+ kvm_set_time_scale(__get_cpu_var(cpu_tsc_khz), &vcpu->hv_clock);
+ vcpu->hv_clock_tsc_khz = __get_cpu_var(cpu_tsc_khz);
}
/* Keep irq disabled to prevent changes to the clock */
@@ -629,6 +663,16 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT);
}
+static int kvm_request_guest_time_update(struct kvm_vcpu *v)
+{
+ struct kvm_vcpu_arch *vcpu = &v->arch;
+
+ if (!vcpu->time_page)
+ return 0;
+ set_bit(KVM_REQ_KVMCLOCK_UPDATE, &v->requests);
+ return 1;
+}
+
static bool msr_mtrr_valid(unsigned msr)
{
switch (msr) {
@@ -722,6 +766,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
break;
case MSR_IA32_UCODE_REV:
case MSR_IA32_UCODE_WRITE:
+ case MSR_VM_HSAVE_PA:
break;
case 0x200 ... 0x2ff:
return set_msr_mtrr(vcpu, msr, data);
@@ -758,7 +803,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
vcpu->arch.time_page = NULL;
}
- kvm_write_guest_time(vcpu);
+ kvm_request_guest_time_update(vcpu);
break;
}
default:
@@ -843,6 +888,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case MSR_IA32_LASTBRANCHTOIP:
case MSR_IA32_LASTINTFROMIP:
case MSR_IA32_LASTINTTOIP:
+ case MSR_VM_HSAVE_PA:
data = 0;
break;
case MSR_MTRRcap:
@@ -967,10 +1013,13 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_MMU_SHADOW_CACHE_CONTROL:
case KVM_CAP_SET_TSS_ADDR:
case KVM_CAP_EXT_CPUID:
+ case KVM_CAP_CLOCKSOURCE:
case KVM_CAP_PIT:
case KVM_CAP_NOP_IO_DELAY:
case KVM_CAP_MP_STATE:
case KVM_CAP_SYNC_MMU:
+ case KVM_CAP_REINJECT_CONTROL:
+ case KVM_CAP_IRQ_INJECT_STATUS:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
@@ -991,9 +1040,6 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_IOMMU:
r = iommu_found();
break;
- case KVM_CAP_CLOCKSOURCE:
- r = boot_cpu_has(X86_FEATURE_CONSTANT_TSC);
- break;
default:
r = 0;
break;
@@ -1044,7 +1090,7 @@ long kvm_arch_dev_ioctl(struct file *filp,
if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
goto out;
r = kvm_dev_ioctl_get_supported_cpuid(&cpuid,
- cpuid_arg->entries);
+ cpuid_arg->entries);
if (r)
goto out;
@@ -1064,7 +1110,7 @@ out:
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
kvm_x86_ops->vcpu_load(vcpu, cpu);
- kvm_write_guest_time(vcpu);
+ kvm_request_guest_time_update(vcpu);
}
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
@@ -1142,8 +1188,8 @@ out:
}
static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
- struct kvm_cpuid2 *cpuid,
- struct kvm_cpuid_entry2 __user *entries)
+ struct kvm_cpuid2 *cpuid,
+ struct kvm_cpuid_entry2 __user *entries)
{
int r;
@@ -1162,8 +1208,8 @@ out:
}
static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
- struct kvm_cpuid2 *cpuid,
- struct kvm_cpuid_entry2 __user *entries)
+ struct kvm_cpuid2 *cpuid,
+ struct kvm_cpuid_entry2 __user *entries)
{
int r;
@@ -1172,7 +1218,7 @@ static int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
goto out;
r = -EFAULT;
if (copy_to_user(entries, &vcpu->arch.cpuid_entries,
- vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
+ vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
goto out;
return 0;
@@ -1181,18 +1227,13 @@ out:
return r;
}
-static inline u32 bit(int bitno)
-{
- return 1 << (bitno & 31);
-}
-
static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function,
- u32 index)
+ u32 index)
{
entry->function = function;
entry->index = index;
cpuid_count(entry->function, entry->index,
- &entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
+ &entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
entry->flags = 0;
}
@@ -1222,15 +1263,17 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
#ifdef CONFIG_X86_64
bit(X86_FEATURE_LM) |
#endif
+ bit(X86_FEATURE_FXSR_OPT) |
bit(X86_FEATURE_MMXEXT) |
bit(X86_FEATURE_3DNOWEXT) |
bit(X86_FEATURE_3DNOW);
const u32 kvm_supported_word3_x86_features =
bit(X86_FEATURE_XMM3) | bit(X86_FEATURE_CX16);
const u32 kvm_supported_word6_x86_features =
- bit(X86_FEATURE_LAHF_LM) | bit(X86_FEATURE_CMP_LEGACY);
+ bit(X86_FEATURE_LAHF_LM) | bit(X86_FEATURE_CMP_LEGACY) |
+ bit(X86_FEATURE_SVM);
- /* all func 2 cpuid_count() should be called on the same cpu */
+ /* all calls to cpuid_count() should be made on the same cpu */
get_cpu();
do_cpuid_1_ent(entry, function, index);
++*nent;
@@ -1304,7 +1347,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
}
static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
- struct kvm_cpuid_entry2 __user *entries)
+ struct kvm_cpuid_entry2 __user *entries)
{
struct kvm_cpuid_entry2 *cpuid_entries;
int limit, nent = 0, r = -E2BIG;
@@ -1321,7 +1364,7 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
limit = cpuid_entries[0].eax;
for (func = 1; func <= limit && nent < cpuid->nent; ++func)
do_cpuid_ent(&cpuid_entries[nent], func, 0,
- &nent, cpuid->nent);
+ &nent, cpuid->nent);
r = -E2BIG;
if (nent >= cpuid->nent)
goto out_free;
@@ -1330,10 +1373,10 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
limit = cpuid_entries[nent - 1].eax;
for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func)
do_cpuid_ent(&cpuid_entries[nent], func, 0,
- &nent, cpuid->nent);
+ &nent, cpuid->nent);
r = -EFAULT;
if (copy_to_user(entries, cpuid_entries,
- nent * sizeof(struct kvm_cpuid_entry2)))
+ nent * sizeof(struct kvm_cpuid_entry2)))
goto out_free;
cpuid->nent = nent;
r = 0;
@@ -1477,7 +1520,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
goto out;
r = kvm_vcpu_ioctl_set_cpuid2(vcpu, &cpuid,
- cpuid_arg->entries);
+ cpuid_arg->entries);
if (r)
goto out;
break;
@@ -1490,7 +1533,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))
goto out;
r = kvm_vcpu_ioctl_get_cpuid2(vcpu, &cpuid,
- cpuid_arg->entries);
+ cpuid_arg->entries);
if (r)
goto out;
r = -EFAULT;
@@ -1710,6 +1753,15 @@ static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
return r;
}
+static int kvm_vm_ioctl_reinject(struct kvm *kvm,
+ struct kvm_reinject_control *control)
+{
+ if (!kvm->arch.vpit)
+ return -ENXIO;
+ kvm->arch.vpit->pit_state.pit_timer.reinject = control->pit_reinject;
+ return 0;
+}
+
/*
* Get (and clear) the dirty memory log for a memory slot.
*/
@@ -1807,13 +1859,26 @@ long kvm_arch_vm_ioctl(struct file *filp,
}
} else
goto out;
+ r = kvm_setup_default_irq_routing(kvm);
+ if (r) {
+ kfree(kvm->arch.vpic);
+ kfree(kvm->arch.vioapic);
+ goto out;
+ }
break;
case KVM_CREATE_PIT:
+ mutex_lock(&kvm->lock);
+ r = -EEXIST;
+ if (kvm->arch.vpit)
+ goto create_pit_unlock;
r = -ENOMEM;
kvm->arch.vpit = kvm_create_pit(kvm);
if (kvm->arch.vpit)
r = 0;
+ create_pit_unlock:
+ mutex_unlock(&kvm->lock);
break;
+ case KVM_IRQ_LINE_STATUS:
case KVM_IRQ_LINE: {
struct kvm_irq_level irq_event;
@@ -1821,10 +1886,17 @@ long kvm_arch_vm_ioctl(struct file *filp,
if (copy_from_user(&irq_event, argp, sizeof irq_event))
goto out;
if (irqchip_in_kernel(kvm)) {
+ __s32 status;
mutex_lock(&kvm->lock);
- kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
- irq_event.irq, irq_event.level);
+ status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
+ irq_event.irq, irq_event.level);
mutex_unlock(&kvm->lock);
+ if (ioctl == KVM_IRQ_LINE_STATUS) {
+ irq_event.status = status;
+ if (copy_to_user(argp, &irq_event,
+ sizeof irq_event))
+ goto out;
+ }
r = 0;
}
break;
@@ -1907,6 +1979,17 @@ long kvm_arch_vm_ioctl(struct file *filp,
r = 0;
break;
}
+ case KVM_REINJECT_CONTROL: {
+ struct kvm_reinject_control control;
+ r = -EFAULT;
+ if (copy_from_user(&control, argp, sizeof(control)))
+ goto out;
+ r = kvm_vm_ioctl_reinject(kvm, &control);
+ if (r)
+ goto out;
+ r = 0;
+ break;
+ }
default:
;
}
@@ -1960,10 +2043,38 @@ static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
return dev;
}
-int emulator_read_std(unsigned long addr,
- void *val,
- unsigned int bytes,
- struct kvm_vcpu *vcpu)
+static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes,
+ struct kvm_vcpu *vcpu)
+{
+ void *data = val;
+ int r = X86EMUL_CONTINUE;
+
+ while (bytes) {
+ gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
+ unsigned offset = addr & (PAGE_SIZE-1);
+ unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset);
+ int ret;
+
+ if (gpa == UNMAPPED_GVA) {
+ r = X86EMUL_PROPAGATE_FAULT;
+ goto out;
+ }
+ ret = kvm_read_guest(vcpu->kvm, gpa, data, toread);
+ if (ret < 0) {
+ r = X86EMUL_UNHANDLEABLE;
+ goto out;
+ }
+
+ bytes -= toread;
+ data += toread;
+ addr += toread;
+ }
+out:
+ return r;
+}
+
+static int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes,
+ struct kvm_vcpu *vcpu)
{
void *data = val;
int r = X86EMUL_CONTINUE;
@@ -1971,27 +2082,27 @@ int emulator_read_std(unsigned long addr,
while (bytes) {
gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
unsigned offset = addr & (PAGE_SIZE-1);
- unsigned tocopy = min(bytes, (unsigned)PAGE_SIZE - offset);
+ unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset);
int ret;
if (gpa == UNMAPPED_GVA) {
r = X86EMUL_PROPAGATE_FAULT;
goto out;
}
- ret = kvm_read_guest(vcpu->kvm, gpa, data, tocopy);
+ ret = kvm_write_guest(vcpu->kvm, gpa, data, towrite);
if (ret < 0) {
r = X86EMUL_UNHANDLEABLE;
goto out;
}
- bytes -= tocopy;
- data += tocopy;
- addr += tocopy;
+ bytes -= towrite;
+ data += towrite;
+ addr += towrite;
}
out:
return r;
}
-EXPORT_SYMBOL_GPL(emulator_read_std);
+
static int emulator_read_emulated(unsigned long addr,
void *val,
@@ -2013,8 +2124,8 @@ static int emulator_read_emulated(unsigned long addr,
if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
goto mmio;
- if (emulator_read_std(addr, val, bytes, vcpu)
- == X86EMUL_CONTINUE)
+ if (kvm_read_guest_virt(addr, val, bytes, vcpu)
+ == X86EMUL_CONTINUE)
return X86EMUL_CONTINUE;
if (gpa == UNMAPPED_GVA)
return X86EMUL_PROPAGATE_FAULT;
@@ -2217,7 +2328,7 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
rip_linear = rip + get_segment_base(vcpu, VCPU_SREG_CS);
- emulator_read_std(rip_linear, (void *)opcodes, 4, vcpu);
+ kvm_read_guest_virt(rip_linear, (void *)opcodes, 4, vcpu);
printk(KERN_ERR "emulation failed (%s) rip %lx %02x %02x %02x %02x\n",
context, rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]);
@@ -2225,7 +2336,7 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
EXPORT_SYMBOL_GPL(kvm_report_emulation_failure);
static struct x86_emulate_ops emulate_ops = {
- .read_std = emulator_read_std,
+ .read_std = kvm_read_guest_virt,
.read_emulated = emulator_read_emulated,
.write_emulated = emulator_write_emulated,
.cmpxchg_emulated = emulator_cmpxchg_emulated,
@@ -2327,40 +2438,19 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
}
EXPORT_SYMBOL_GPL(emulate_instruction);
-static void free_pio_guest_pages(struct kvm_vcpu *vcpu)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(vcpu->arch.pio.guest_pages); ++i)
- if (vcpu->arch.pio.guest_pages[i]) {
- kvm_release_page_dirty(vcpu->arch.pio.guest_pages[i]);
- vcpu->arch.pio.guest_pages[i] = NULL;
- }
-}
-
static int pio_copy_data(struct kvm_vcpu *vcpu)
{
void *p = vcpu->arch.pio_data;
- void *q;
+ gva_t q = vcpu->arch.pio.guest_gva;
unsigned bytes;
- int nr_pages = vcpu->arch.pio.guest_pages[1] ? 2 : 1;
+ int ret;
- q = vmap(vcpu->arch.pio.guest_pages, nr_pages, VM_READ|VM_WRITE,
- PAGE_KERNEL);
- if (!q) {
- free_pio_guest_pages(vcpu);
- return -ENOMEM;
- }
- q += vcpu->arch.pio.guest_page_offset;
bytes = vcpu->arch.pio.size * vcpu->arch.pio.cur_count;
if (vcpu->arch.pio.in)
- memcpy(q, p, bytes);
+ ret = kvm_write_guest_virt(q, p, bytes, vcpu);
else
- memcpy(p, q, bytes);
- q -= vcpu->arch.pio.guest_page_offset;
- vunmap(q);
- free_pio_guest_pages(vcpu);
- return 0;
+ ret = kvm_read_guest_virt(q, p, bytes, vcpu);
+ return ret;
}
int complete_pio(struct kvm_vcpu *vcpu)
@@ -2471,7 +2561,6 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
vcpu->arch.pio.in = in;
vcpu->arch.pio.string = 0;
vcpu->arch.pio.down = 0;
- vcpu->arch.pio.guest_page_offset = 0;
vcpu->arch.pio.rep = 0;
if (vcpu->run->io.direction == KVM_EXIT_IO_IN)
@@ -2499,9 +2588,7 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
gva_t address, int rep, unsigned port)
{
unsigned now, in_page;
- int i, ret = 0;
- int nr_pages = 1;
- struct page *page;
+ int ret = 0;
struct kvm_io_device *pio_dev;
vcpu->run->exit_reason = KVM_EXIT_IO;
@@ -2513,7 +2600,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
vcpu->arch.pio.in = in;
vcpu->arch.pio.string = 1;
vcpu->arch.pio.down = down;
- vcpu->arch.pio.guest_page_offset = offset_in_page(address);
vcpu->arch.pio.rep = rep;
if (vcpu->run->io.direction == KVM_EXIT_IO_IN)
@@ -2533,15 +2619,8 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
else
in_page = offset_in_page(address) + size;
now = min(count, (unsigned long)in_page / size);
- if (!now) {
- /*
- * String I/O straddles page boundary. Pin two guest pages
- * so that we satisfy atomicity constraints. Do just one
- * transaction to avoid complexity.
- */
- nr_pages = 2;
+ if (!now)
now = 1;
- }
if (down) {
/*
* String I/O in reverse. Yuck. Kill the guest, fix later.
@@ -2556,15 +2635,7 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
if (vcpu->arch.pio.cur_count == vcpu->arch.pio.count)
kvm_x86_ops->skip_emulated_instruction(vcpu);
- for (i = 0; i < nr_pages; ++i) {
- page = gva_to_page(vcpu, address + i * PAGE_SIZE);
- vcpu->arch.pio.guest_pages[i] = page;
- if (!page) {
- kvm_inject_gp(vcpu, 0);
- free_pio_guest_pages(vcpu);
- return 1;
- }
- }
+ vcpu->arch.pio.guest_gva = address;
pio_dev = vcpu_find_pio_dev(vcpu, port,
vcpu->arch.pio.cur_count,
@@ -2572,7 +2643,11 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
if (!vcpu->arch.pio.in) {
/* string PIO write */
ret = pio_copy_data(vcpu);
- if (ret >= 0 && pio_dev) {
+ if (ret == X86EMUL_PROPAGATE_FAULT) {
+ kvm_inject_gp(vcpu, 0);
+ return 1;
+ }
+ if (ret == 0 && pio_dev) {
pio_string_write(pio_dev, vcpu);
complete_pio(vcpu);
if (vcpu->arch.pio.count == 0)
@@ -2587,9 +2662,72 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
}
EXPORT_SYMBOL_GPL(kvm_emulate_pio_string);
+static void bounce_off(void *info)
+{
+ /* nothing */
+}
+
+static unsigned int ref_freq;
+static unsigned long tsc_khz_ref;
+
+static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
+ void *data)
+{
+ struct cpufreq_freqs *freq = data;
+ struct kvm *kvm;
+ struct kvm_vcpu *vcpu;
+ int i, send_ipi = 0;
+
+ if (!ref_freq)
+ ref_freq = freq->old;
+
+ if (val == CPUFREQ_PRECHANGE && freq->old > freq->new)
+ return 0;
+ if (val == CPUFREQ_POSTCHANGE && freq->old < freq->new)
+ return 0;
+ per_cpu(cpu_tsc_khz, freq->cpu) = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new);
+
+ spin_lock(&kvm_lock);
+ list_for_each_entry(kvm, &vm_list, vm_list) {
+ for (i = 0; i < KVM_MAX_VCPUS; ++i) {
+ vcpu = kvm->vcpus[i];
+ if (!vcpu)
+ continue;
+ if (vcpu->cpu != freq->cpu)
+ continue;
+ if (!kvm_request_guest_time_update(vcpu))
+ continue;
+ if (vcpu->cpu != smp_processor_id())
+ send_ipi++;
+ }
+ }
+ spin_unlock(&kvm_lock);
+
+ if (freq->old < freq->new && send_ipi) {
+ /*
+ * We upscale the frequency. Must make the guest
+ * doesn't see old kvmclock values while running with
+ * the new frequency, otherwise we risk the guest sees
+ * time go backwards.
+ *
+ * In case we update the frequency for another cpu
+ * (which might be in guest context) send an interrupt
+ * to kick the cpu out of guest context. Next time
+ * guest context is entered kvmclock will be updated,
+ * so the guest will not see stale values.
+ */
+ smp_call_function_single(freq->cpu, bounce_off, NULL, 1);
+ }
+ return 0;
+}
+
+static struct notifier_block kvmclock_cpufreq_notifier_block = {
+ .notifier_call = kvmclock_cpufreq_notifier
+};
+
int kvm_arch_init(void *opaque)
{
- int r;
+ int r, cpu;
struct kvm_x86_ops *ops = (struct kvm_x86_ops *)opaque;
if (kvm_x86_ops) {
@@ -2620,6 +2758,15 @@ int kvm_arch_init(void *opaque)
kvm_mmu_set_base_ptes(PT_PRESENT_MASK);
kvm_mmu_set_mask_ptes(PT_USER_MASK, PT_ACCESSED_MASK,
PT_DIRTY_MASK, PT64_NX_MASK, 0, 0);
+
+ for_each_possible_cpu(cpu)
+ per_cpu(cpu_tsc_khz, cpu) = tsc_khz;
+ if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) {
+ tsc_khz_ref = tsc_khz;
+ cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block,
+ CPUFREQ_TRANSITION_NOTIFIER);
+ }
+
return 0;
out:
@@ -2827,25 +2974,20 @@ static int is_matching_cpuid_entry(struct kvm_cpuid_entry2 *e,
if ((e->flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX) && e->index != index)
return 0;
if ((e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC) &&
- !(e->flags & KVM_CPUID_FLAG_STATE_READ_NEXT))
+ !(e->flags & KVM_CPUID_FLAG_STATE_READ_NEXT))
return 0;
return 1;
}
-void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
+struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
+ u32 function, u32 index)
{
int i;
- u32 function, index;
- struct kvm_cpuid_entry2 *e, *best;
+ struct kvm_cpuid_entry2 *best = NULL;
- function = kvm_register_read(vcpu, VCPU_REGS_RAX);
- index = kvm_register_read(vcpu, VCPU_REGS_RCX);
- kvm_register_write(vcpu, VCPU_REGS_RAX, 0);
- kvm_register_write(vcpu, VCPU_REGS_RBX, 0);
- kvm_register_write(vcpu, VCPU_REGS_RCX, 0);
- kvm_register_write(vcpu, VCPU_REGS_RDX, 0);
- best = NULL;
for (i = 0; i < vcpu->arch.cpuid_nent; ++i) {
+ struct kvm_cpuid_entry2 *e;
+
e = &vcpu->arch.cpuid_entries[i];
if (is_matching_cpuid_entry(e, function, index)) {
if (e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC)
@@ -2860,6 +3002,21 @@ void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
if (!best || e->function > best->function)
best = e;
}
+ return best;
+}
+
+void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
+{
+ u32 function, index;
+ struct kvm_cpuid_entry2 *best;
+
+ function = kvm_register_read(vcpu, VCPU_REGS_RAX);
+ index = kvm_register_read(vcpu, VCPU_REGS_RCX);
+ kvm_register_write(vcpu, VCPU_REGS_RAX, 0);
+ kvm_register_write(vcpu, VCPU_REGS_RBX, 0);
+ kvm_register_write(vcpu, VCPU_REGS_RCX, 0);
+ kvm_register_write(vcpu, VCPU_REGS_RDX, 0);
+ best = kvm_find_cpuid_entry(vcpu, function, index);
if (best) {
kvm_register_write(vcpu, VCPU_REGS_RAX, best->eax);
kvm_register_write(vcpu, VCPU_REGS_RBX, best->ebx);
@@ -2945,6 +3102,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
if (vcpu->requests) {
if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests))
__kvm_migrate_timers(vcpu);
+ if (test_and_clear_bit(KVM_REQ_KVMCLOCK_UPDATE, &vcpu->requests))
+ kvm_write_guest_time(vcpu);
if (test_and_clear_bit(KVM_REQ_MMU_SYNC, &vcpu->requests))
kvm_mmu_sync_roots(vcpu);
if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))
@@ -2979,9 +3138,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
goto out;
}
- if (vcpu->guest_debug.enabled)
- kvm_x86_ops->guest_debug_pre(vcpu);
-
vcpu->guest_mode = 1;
/*
* Make sure that guest_mode assignment won't happen after
@@ -3002,10 +3158,34 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
kvm_guest_enter();
+ get_debugreg(vcpu->arch.host_dr6, 6);
+ get_debugreg(vcpu->arch.host_dr7, 7);
+ if (unlikely(vcpu->arch.switch_db_regs)) {
+ get_debugreg(vcpu->arch.host_db[0], 0);
+ get_debugreg(vcpu->arch.host_db[1], 1);
+ get_debugreg(vcpu->arch.host_db[2], 2);
+ get_debugreg(vcpu->arch.host_db[3], 3);
+
+ set_debugreg(0, 7);
+ set_debugreg(vcpu->arch.eff_db[0], 0);
+ set_debugreg(vcpu->arch.eff_db[1], 1);
+ set_debugreg(vcpu->arch.eff_db[2], 2);
+ set_debugreg(vcpu->arch.eff_db[3], 3);
+ }
KVMTRACE_0D(VMENTRY, vcpu, entryexit);
kvm_x86_ops->run(vcpu, kvm_run);
+ if (unlikely(vcpu->arch.switch_db_regs)) {
+ set_debugreg(0, 7);
+ set_debugreg(vcpu->arch.host_db[0], 0);
+ set_debugreg(vcpu->arch.host_db[1], 1);
+ set_debugreg(vcpu->arch.host_db[2], 2);
+ set_debugreg(vcpu->arch.host_db[3], 3);
+ }
+ set_debugreg(vcpu->arch.host_dr6, 6);
+ set_debugreg(vcpu->arch.host_dr7, 7);
+
vcpu->guest_mode = 0;
local_irq_enable();
@@ -3192,7 +3372,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
/*
* Don't leak debug flags in case they were set for guest debugging
*/
- if (vcpu->guest_debug.enabled && vcpu->guest_debug.singlestep)
+ if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
regs->rflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF);
vcpu_put(vcpu);
@@ -3811,15 +3991,32 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
return 0;
}
-int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
- struct kvm_debug_guest *dbg)
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+ struct kvm_guest_debug *dbg)
{
- int r;
+ int i, r;
vcpu_load(vcpu);
+ if ((dbg->control & (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP)) ==
+ (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP)) {
+ for (i = 0; i < KVM_NR_DB_REGS; ++i)
+ vcpu->arch.eff_db[i] = dbg->arch.debugreg[i];
+ vcpu->arch.switch_db_regs =
+ (dbg->arch.debugreg[7] & DR7_BP_EN_MASK);
+ } else {
+ for (i = 0; i < KVM_NR_DB_REGS; i++)
+ vcpu->arch.eff_db[i] = vcpu->arch.db[i];
+ vcpu->arch.switch_db_regs = (vcpu->arch.dr7 & DR7_BP_EN_MASK);
+ }
+
r = kvm_x86_ops->set_guest_debug(vcpu, dbg);
+ if (dbg->control & KVM_GUESTDBG_INJECT_DB)
+ kvm_queue_exception(vcpu, DB_VECTOR);
+ else if (dbg->control & KVM_GUESTDBG_INJECT_BP)
+ kvm_queue_exception(vcpu, BP_VECTOR);
+
vcpu_put(vcpu);
return r;
@@ -4007,6 +4204,11 @@ int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu)
vcpu->arch.nmi_pending = false;
vcpu->arch.nmi_injected = false;
+ vcpu->arch.switch_db_regs = 0;
+ memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db));
+ vcpu->arch.dr6 = DR6_FIXED_1;
+ vcpu->arch.dr7 = DR7_FIXED_1;
+
return kvm_x86_ops->vcpu_reset(vcpu);
}
@@ -4100,6 +4302,8 @@ struct kvm *kvm_arch_create_vm(void)
/* Reserve bit 0 of irq_sources_bitmap for userspace irq source */
set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap);
+ rdtscll(kvm->arch.vm_init_tsc);
+
return kvm;
}
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index d174db7a3370..ca91749d2083 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -178,7 +178,7 @@ static u32 opcode_table[256] = {
0, ImplicitOps | Stack, 0, 0,
ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov,
/* 0xC8 - 0xCF */
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, ImplicitOps | Stack, 0, 0, 0, 0,
/* 0xD0 - 0xD7 */
ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
@@ -1136,18 +1136,19 @@ static inline void emulate_push(struct x86_emulate_ctxt *ctxt)
}
static int emulate_pop(struct x86_emulate_ctxt *ctxt,
- struct x86_emulate_ops *ops)
+ struct x86_emulate_ops *ops,
+ void *dest, int len)
{
struct decode_cache *c = &ctxt->decode;
int rc;
rc = ops->read_emulated(register_address(c, ss_base(ctxt),
c->regs[VCPU_REGS_RSP]),
- &c->src.val, c->src.bytes, ctxt->vcpu);
+ dest, len, ctxt->vcpu);
if (rc != 0)
return rc;
- register_address_increment(c, &c->regs[VCPU_REGS_RSP], c->src.bytes);
+ register_address_increment(c, &c->regs[VCPU_REGS_RSP], len);
return rc;
}
@@ -1157,11 +1158,9 @@ static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
struct decode_cache *c = &ctxt->decode;
int rc;
- c->src.bytes = c->dst.bytes;
- rc = emulate_pop(ctxt, ops);
+ rc = emulate_pop(ctxt, ops, &c->dst.val, c->dst.bytes);
if (rc != 0)
return rc;
- c->dst.val = c->src.val;
return 0;
}
@@ -1279,6 +1278,25 @@ static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
return 0;
}
+static int emulate_ret_far(struct x86_emulate_ctxt *ctxt,
+ struct x86_emulate_ops *ops)
+{
+ struct decode_cache *c = &ctxt->decode;
+ int rc;
+ unsigned long cs;
+
+ rc = emulate_pop(ctxt, ops, &c->eip, c->op_bytes);
+ if (rc)
+ return rc;
+ if (c->op_bytes == 4)
+ c->eip = (u32)c->eip;
+ rc = emulate_pop(ctxt, ops, &cs, c->op_bytes);
+ if (rc)
+ return rc;
+ rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, 1, VCPU_SREG_CS);
+ return rc;
+}
+
static inline int writeback(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops)
{
@@ -1467,11 +1485,9 @@ special_insn:
break;
case 0x58 ... 0x5f: /* pop reg */
pop_instruction:
- c->src.bytes = c->op_bytes;
- rc = emulate_pop(ctxt, ops);
+ rc = emulate_pop(ctxt, ops, &c->dst.val, c->op_bytes);
if (rc != 0)
goto done;
- c->dst.val = c->src.val;
break;
case 0x63: /* movsxd */
if (ctxt->mode != X86EMUL_MODE_PROT64)
@@ -1738,6 +1754,11 @@ special_insn:
mov:
c->dst.val = c->src.val;
break;
+ case 0xcb: /* ret far */
+ rc = emulate_ret_far(ctxt, ops);
+ if (rc)
+ goto done;
+ break;
case 0xd0 ... 0xd1: /* Grp2 */
c->src.val = 1;
emulate_grp2(ctxt);
@@ -1908,11 +1929,16 @@ twobyte_insn:
c->dst.type = OP_NONE;
break;
case 3: /* lidt/vmmcall */
- if (c->modrm_mod == 3 && c->modrm_rm == 1) {
- rc = kvm_fix_hypercall(ctxt->vcpu);
- if (rc)
- goto done;
- kvm_emulate_hypercall(ctxt->vcpu);
+ if (c->modrm_mod == 3) {
+ switch (c->modrm_rm) {
+ case 1:
+ rc = kvm_fix_hypercall(ctxt->vcpu);
+ if (rc)
+ goto done;
+ break;
+ default:
+ goto cannot_emulate;
+ }
} else {
rc = read_descriptor(ctxt, ops, c->src.ptr,
&size, &address,
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 9fe4ddaa8f6f..e94a11e42f98 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -107,7 +107,7 @@ static void async_hcall(unsigned long call, unsigned long arg1,
local_irq_save(flags);
if (lguest_data.hcall_status[next_call] != 0xFF) {
/* Table full, so do normal hcall which will flush table. */
- hcall(call, arg1, arg2, arg3);
+ kvm_hypercall3(call, arg1, arg2, arg3);
} else {
lguest_data.hcalls[next_call].arg0 = call;
lguest_data.hcalls[next_call].arg1 = arg1;
@@ -134,13 +134,32 @@ static void async_hcall(unsigned long call, unsigned long arg1,
*
* So, when we're in lazy mode, we call async_hcall() to store the call for
* future processing: */
-static void lazy_hcall(unsigned long call,
+static void lazy_hcall1(unsigned long call,
+ unsigned long arg1)
+{
+ if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
+ kvm_hypercall1(call, arg1);
+ else
+ async_hcall(call, arg1, 0, 0);
+}
+
+static void lazy_hcall2(unsigned long call,
+ unsigned long arg1,
+ unsigned long arg2)
+{
+ if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
+ kvm_hypercall2(call, arg1, arg2);
+ else
+ async_hcall(call, arg1, arg2, 0);
+}
+
+static void lazy_hcall3(unsigned long call,
unsigned long arg1,
unsigned long arg2,
unsigned long arg3)
{
if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
- hcall(call, arg1, arg2, arg3);
+ kvm_hypercall3(call, arg1, arg2, arg3);
else
async_hcall(call, arg1, arg2, arg3);
}
@@ -150,7 +169,7 @@ static void lazy_hcall(unsigned long call,
static void lguest_leave_lazy_mode(void)
{
paravirt_leave_lazy(paravirt_get_lazy_mode());
- hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0);
+ kvm_hypercall0(LHCALL_FLUSH_ASYNC);
}
/*G:033
@@ -229,7 +248,7 @@ static void lguest_write_idt_entry(gate_desc *dt,
/* Keep the local copy up to date. */
native_write_idt_entry(dt, entrynum, g);
/* Tell Host about this new entry. */
- hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]);
+ kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]);
}
/* Changing to a different IDT is very rare: we keep the IDT up-to-date every
@@ -241,7 +260,7 @@ static void lguest_load_idt(const struct desc_ptr *desc)
struct desc_struct *idt = (void *)desc->address;
for (i = 0; i < (desc->size+1)/8; i++)
- hcall(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b);
+ kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b);
}
/*
@@ -261,8 +280,8 @@ static void lguest_load_idt(const struct desc_ptr *desc)
*/
static void lguest_load_gdt(const struct desc_ptr *desc)
{
- BUG_ON((desc->size+1)/8 != GDT_ENTRIES);
- hcall(LHCALL_LOAD_GDT, __pa(desc->address), GDT_ENTRIES, 0);
+ BUG_ON((desc->size + 1) / 8 != GDT_ENTRIES);
+ kvm_hypercall2(LHCALL_LOAD_GDT, __pa(desc->address), GDT_ENTRIES);
}
/* For a single GDT entry which changes, we do the lazy thing: alter our GDT,
@@ -272,7 +291,7 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum,
const void *desc, int type)
{
native_write_gdt_entry(dt, entrynum, desc, type);
- hcall(LHCALL_LOAD_GDT, __pa(dt), GDT_ENTRIES, 0);
+ kvm_hypercall2(LHCALL_LOAD_GDT, __pa(dt), GDT_ENTRIES);
}
/* OK, I lied. There are three "thread local storage" GDT entries which change
@@ -284,7 +303,7 @@ static void lguest_load_tls(struct thread_struct *t, unsigned int cpu)
* can't handle us removing entries we're currently using. So we clear
* the GS register here: if it's needed it'll be reloaded anyway. */
lazy_load_gs(0);
- lazy_hcall(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu, 0);
+ lazy_hcall2(LHCALL_LOAD_TLS, __pa(&t->tls_array), cpu);
}
/*G:038 That's enough excitement for now, back to ploughing through each of
@@ -382,7 +401,7 @@ static void lguest_cpuid(unsigned int *ax, unsigned int *bx,
static unsigned long current_cr0;
static void lguest_write_cr0(unsigned long val)
{
- lazy_hcall(LHCALL_TS, val & X86_CR0_TS, 0, 0);
+ lazy_hcall1(LHCALL_TS, val & X86_CR0_TS);
current_cr0 = val;
}
@@ -396,7 +415,7 @@ static unsigned long lguest_read_cr0(void)
* the vowels have been optimized out. */
static void lguest_clts(void)
{
- lazy_hcall(LHCALL_TS, 0, 0, 0);
+ lazy_hcall1(LHCALL_TS, 0);
current_cr0 &= ~X86_CR0_TS;
}
@@ -418,7 +437,7 @@ static bool cr3_changed = false;
static void lguest_write_cr3(unsigned long cr3)
{
lguest_data.pgdir = cr3;
- lazy_hcall(LHCALL_NEW_PGTABLE, cr3, 0, 0);
+ lazy_hcall1(LHCALL_NEW_PGTABLE, cr3);
cr3_changed = true;
}
@@ -490,11 +509,17 @@ static void lguest_write_cr4(unsigned long val)
* into a process' address space. We set the entry then tell the Host the
* toplevel and address this corresponds to. The Guest uses one pagetable per
* process, so we need to tell the Host which one we're changing (mm->pgd). */
+static void lguest_pte_update(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep)
+{
+ lazy_hcall3(LHCALL_SET_PTE, __pa(mm->pgd), addr, ptep->pte_low);
+}
+
static void lguest_set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval)
{
*ptep = pteval;
- lazy_hcall(LHCALL_SET_PTE, __pa(mm->pgd), addr, pteval.pte_low);
+ lguest_pte_update(mm, addr, ptep);
}
/* The Guest calls this to set a top-level entry. Again, we set the entry then
@@ -503,8 +528,8 @@ static void lguest_set_pte_at(struct mm_struct *mm, unsigned long addr,
static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval)
{
*pmdp = pmdval;
- lazy_hcall(LHCALL_SET_PMD, __pa(pmdp)&PAGE_MASK,
- (__pa(pmdp)&(PAGE_SIZE-1))/4, 0);
+ lazy_hcall2(LHCALL_SET_PMD, __pa(pmdp) & PAGE_MASK,
+ (__pa(pmdp) & (PAGE_SIZE - 1)) / 4);
}
/* There are a couple of legacy places where the kernel sets a PTE, but we
@@ -520,7 +545,7 @@ static void lguest_set_pte(pte_t *ptep, pte_t pteval)
{
*ptep = pteval;
if (cr3_changed)
- lazy_hcall(LHCALL_FLUSH_TLB, 1, 0, 0);
+ lazy_hcall1(LHCALL_FLUSH_TLB, 1);
}
/* Unfortunately for Lguest, the pv_mmu_ops for page tables were based on
@@ -536,7 +561,7 @@ static void lguest_set_pte(pte_t *ptep, pte_t pteval)
static void lguest_flush_tlb_single(unsigned long addr)
{
/* Simply set it to zero: if it was not, it will fault back in. */
- lazy_hcall(LHCALL_SET_PTE, lguest_data.pgdir, addr, 0);
+ lazy_hcall3(LHCALL_SET_PTE, lguest_data.pgdir, addr, 0);
}
/* This is what happens after the Guest has removed a large number of entries.
@@ -544,7 +569,7 @@ static void lguest_flush_tlb_single(unsigned long addr)
* have changed, ie. virtual addresses below PAGE_OFFSET. */
static void lguest_flush_tlb_user(void)
{
- lazy_hcall(LHCALL_FLUSH_TLB, 0, 0, 0);
+ lazy_hcall1(LHCALL_FLUSH_TLB, 0);
}
/* This is called when the kernel page tables have changed. That's not very
@@ -552,7 +577,7 @@ static void lguest_flush_tlb_user(void)
* slow), so it's worth separating this from the user flushing above. */
static void lguest_flush_tlb_kernel(void)
{
- lazy_hcall(LHCALL_FLUSH_TLB, 1, 0, 0);
+ lazy_hcall1(LHCALL_FLUSH_TLB, 1);
}
/*
@@ -689,7 +714,7 @@ static int lguest_clockevent_set_next_event(unsigned long delta,
}
/* Please wake us this far in the future. */
- hcall(LHCALL_SET_CLOCKEVENT, delta, 0, 0);
+ kvm_hypercall1(LHCALL_SET_CLOCKEVENT, delta);
return 0;
}
@@ -700,7 +725,7 @@ static void lguest_clockevent_set_mode(enum clock_event_mode mode,
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
/* A 0 argument shuts the clock down. */
- hcall(LHCALL_SET_CLOCKEVENT, 0, 0, 0);
+ kvm_hypercall0(LHCALL_SET_CLOCKEVENT);
break;
case CLOCK_EVT_MODE_ONESHOT:
/* This is what we expect. */
@@ -775,8 +800,8 @@ static void lguest_time_init(void)
static void lguest_load_sp0(struct tss_struct *tss,
struct thread_struct *thread)
{
- lazy_hcall(LHCALL_SET_STACK, __KERNEL_DS|0x1, thread->sp0,
- THREAD_SIZE/PAGE_SIZE);
+ lazy_hcall3(LHCALL_SET_STACK, __KERNEL_DS | 0x1, thread->sp0,
+ THREAD_SIZE / PAGE_SIZE);
}
/* Let's just say, I wouldn't do debugging under a Guest. */
@@ -849,7 +874,7 @@ static void set_lguest_basic_apic_ops(void)
/* STOP! Until an interrupt comes in. */
static void lguest_safe_halt(void)
{
- hcall(LHCALL_HALT, 0, 0, 0);
+ kvm_hypercall0(LHCALL_HALT);
}
/* The SHUTDOWN hypercall takes a string to describe what's happening, and
@@ -859,7 +884,8 @@ static void lguest_safe_halt(void)
* rather than virtual addresses, so we use __pa() here. */
static void lguest_power_off(void)
{
- hcall(LHCALL_SHUTDOWN, __pa("Power down"), LGUEST_SHUTDOWN_POWEROFF, 0);
+ kvm_hypercall2(LHCALL_SHUTDOWN, __pa("Power down"),
+ LGUEST_SHUTDOWN_POWEROFF);
}
/*
@@ -869,7 +895,7 @@ static void lguest_power_off(void)
*/
static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p)
{
- hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0);
+ kvm_hypercall2(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF);
/* The hcall won't return, but to keep gcc happy, we're "done". */
return NOTIFY_DONE;
}
@@ -910,7 +936,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
len = sizeof(scratch) - 1;
scratch[len] = '\0';
memcpy(scratch, buf, len);
- hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0);
+ kvm_hypercall1(LHCALL_NOTIFY, __pa(scratch));
/* This routine returns the number of bytes actually written. */
return len;
@@ -920,7 +946,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
* Launcher to reboot us. */
static void lguest_restart(char *reason)
{
- hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0);
+ kvm_hypercall2(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART);
}
/*G:050
@@ -1040,6 +1066,8 @@ __init void lguest_init(void)
pv_mmu_ops.read_cr3 = lguest_read_cr3;
pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu;
pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mode;
+ pv_mmu_ops.pte_update = lguest_pte_update;
+ pv_mmu_ops.pte_update_defer = lguest_pte_update;
#ifdef CONFIG_X86_LOCAL_APIC
/* apic read/write intercepts */
@@ -1058,14 +1086,6 @@ __init void lguest_init(void)
* lguest_init() where the rest of the fairly chaotic boot setup
* occurs. */
- /* The native boot code sets up initial page tables immediately after
- * the kernel itself, and sets init_pg_tables_end so they're not
- * clobbered. The Launcher places our initial pagetables somewhere at
- * the top of our physical memory, so we don't need extra space: set
- * init_pg_tables_end to the end of the kernel. */
- init_pg_tables_start = __pa(pg0);
- init_pg_tables_end = __pa(pg0);
-
/* As described in head_32.S, we map the first 128M of memory. */
max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT;
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S
index 10b9bd35a8ff..f79541989471 100644
--- a/arch/x86/lguest/i386_head.S
+++ b/arch/x86/lguest/i386_head.S
@@ -27,8 +27,8 @@ ENTRY(lguest_entry)
/* We make the "initialization" hypercall now to tell the Host about
* us, and also find out where it put our page tables. */
movl $LHCALL_LGUEST_INIT, %eax
- movl $lguest_data - __PAGE_OFFSET, %edx
- int $LGUEST_TRAP_ENTRY
+ movl $lguest_data - __PAGE_OFFSET, %ebx
+ .byte 0x0f,0x01,0xc1 /* KVM_HYPERCALL */
/* Set up the initial stack so we can run C code. */
movl $(init_thread_union+THREAD_SIZE),%esp
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 08537747cb58..fdd30d08ab52 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -14,7 +14,7 @@ obj-$(CONFIG_MMIOTRACE) += mmiotrace.o
mmiotrace-y := kmmio.o pf_in.o mmio-mod.o
obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o
-obj-$(CONFIG_NUMA) += numa_$(BITS).o
+obj-$(CONFIG_NUMA) += numa.o numa_$(BITS).o
obj-$(CONFIG_K8_NUMA) += k8topology_64.o
obj-$(CONFIG_ACPI_NUMA) += srat_$(BITS).o
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index f256e73542d7..8126e8d1a2a4 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -19,49 +19,6 @@ void kunmap(struct page *page)
kunmap_high(page);
}
-static void debug_kmap_atomic_prot(enum km_type type)
-{
-#ifdef CONFIG_DEBUG_HIGHMEM
- static unsigned warn_count = 10;
-
- if (unlikely(warn_count == 0))
- return;
-
- if (unlikely(in_interrupt())) {
- if (in_irq()) {
- if (type != KM_IRQ0 && type != KM_IRQ1 &&
- type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ &&
- type != KM_BOUNCE_READ) {
- WARN_ON(1);
- warn_count--;
- }
- } else if (!irqs_disabled()) { /* softirq */
- if (type != KM_IRQ0 && type != KM_IRQ1 &&
- type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 &&
- type != KM_SKB_SUNRPC_DATA &&
- type != KM_SKB_DATA_SOFTIRQ &&
- type != KM_BOUNCE_READ) {
- WARN_ON(1);
- warn_count--;
- }
- }
- }
-
- if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ ||
- type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) {
- if (!irqs_disabled()) {
- WARN_ON(1);
- warn_count--;
- }
- } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) {
- if (irq_count() == 0 && !irqs_disabled()) {
- WARN_ON(1);
- warn_count--;
- }
- }
-#endif
-}
-
/*
* kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
* no global lock is needed and because the kmap code must perform a global TLB
@@ -81,7 +38,7 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
if (!PageHighMem(page))
return page_address(page);
- debug_kmap_atomic_prot(type);
+ debug_kmap_atomic(type);
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
@@ -121,24 +78,8 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
pagefault_enable();
}
-void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
-{
- enum fixed_addresses idx;
- unsigned long vaddr;
-
- pagefault_disable();
-
- debug_kmap_atomic_prot(type);
-
- idx = type + KM_TYPE_NR * smp_processor_id();
- vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
- set_pte(kmap_pte - idx, pfn_pte(pfn, prot));
- arch_flush_lazy_mmu_mode();
-
- return (void*) vaddr;
-}
-
-/* This is the same as kmap_atomic() but can map memory that doesn't
+/*
+ * This is the same as kmap_atomic() but can map memory that doesn't
* have a struct page associated with it.
*/
void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 15219e0d1243..fd3da1dda1c9 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -94,9 +94,9 @@ struct map_range {
#define NR_RANGE_MR 5
#endif
-static int save_mr(struct map_range *mr, int nr_range,
- unsigned long start_pfn, unsigned long end_pfn,
- unsigned long page_size_mask)
+static int __meminit save_mr(struct map_range *mr, int nr_range,
+ unsigned long start_pfn, unsigned long end_pfn,
+ unsigned long page_size_mask)
{
if (start_pfn < end_pfn) {
if (nr_range >= NR_RANGE_MR)
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c
index 592984e5496b..8056545e2d39 100644
--- a/arch/x86/mm/iomap_32.c
+++ b/arch/x86/mm/iomap_32.c
@@ -18,12 +18,12 @@
#include <asm/iomap.h>
#include <asm/pat.h>
-#include <asm/highmem.h>
#include <linux/module.h>
+#include <linux/highmem.h>
int is_io_mapping_possible(resource_size_t base, unsigned long size)
{
-#ifndef CONFIG_X86_PAE
+#if !defined(CONFIG_X86_PAE) && defined(CONFIG_PHYS_ADDR_T_64BIT)
/* There is no way to map greater than 1 << 32 address without PAE */
if (base + size > 0x100000000ULL)
return 0;
@@ -32,7 +32,24 @@ int is_io_mapping_possible(resource_size_t base, unsigned long size)
}
EXPORT_SYMBOL_GPL(is_io_mapping_possible);
-/* Map 'pfn' using fixed map 'type' and protections 'prot'
+void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
+{
+ enum fixed_addresses idx;
+ unsigned long vaddr;
+
+ pagefault_disable();
+
+ debug_kmap_atomic(type);
+ idx = type + KM_TYPE_NR * smp_processor_id();
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ set_pte(kmap_pte - idx, pfn_pte(pfn, prot));
+ arch_flush_lazy_mmu_mode();
+
+ return (void *)vaddr;
+}
+
+/*
+ * Map 'pfn' using fixed map 'type' and protections 'prot'
*/
void *
iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index aca924a30ee6..0dfa09d69e80 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -22,13 +22,17 @@
#include <asm/pgalloc.h>
#include <asm/pat.h>
-#ifdef CONFIG_X86_64
-
-static inline int phys_addr_valid(unsigned long addr)
+static inline int phys_addr_valid(resource_size_t addr)
{
- return addr < (1UL << boot_cpu_data.x86_phys_bits);
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+ return !(addr >> boot_cpu_data.x86_phys_bits);
+#else
+ return 1;
+#endif
}
+#ifdef CONFIG_X86_64
+
unsigned long __phys_addr(unsigned long x)
{
if (x >= __START_KERNEL_map) {
@@ -65,11 +69,6 @@ EXPORT_SYMBOL(__virt_addr_valid);
#else
-static inline int phys_addr_valid(unsigned long addr)
-{
- return 1;
-}
-
#ifdef CONFIG_DEBUG_VIRTUAL
unsigned long __phys_addr(unsigned long x)
{
@@ -517,7 +516,7 @@ void __init early_ioremap_init(void)
printk(KERN_INFO "early_ioremap_init()\n");
for (i = 0; i < FIX_BTMAPS_SLOTS; i++)
- slot_virt[i] = fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
+ slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
memset(bm_pte, 0, sizeof(bm_pte));
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index 2c4baa88f2cb..c9342ed8b402 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -378,27 +378,34 @@ static void clear_trace_list(void)
}
#ifdef CONFIG_HOTPLUG_CPU
-static cpumask_t downed_cpus;
+static cpumask_var_t downed_cpus;
static void enter_uniprocessor(void)
{
int cpu;
int err;
+ if (downed_cpus == NULL &&
+ !alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) {
+ pr_notice(NAME "Failed to allocate mask\n");
+ goto out;
+ }
+
get_online_cpus();
- downed_cpus = cpu_online_map;
- cpu_clear(first_cpu(cpu_online_map), downed_cpus);
+ cpumask_copy(downed_cpus, cpu_online_mask);
+ cpumask_clear_cpu(cpumask_first(cpu_online_mask), downed_cpus);
if (num_online_cpus() > 1)
pr_notice(NAME "Disabling non-boot CPUs...\n");
put_online_cpus();
- for_each_cpu_mask(cpu, downed_cpus) {
+ for_each_cpu(cpu, downed_cpus) {
err = cpu_down(cpu);
if (!err)
pr_info(NAME "CPU%d is down.\n", cpu);
else
pr_err(NAME "Error taking CPU%d down: %d\n", cpu, err);
}
+out:
if (num_online_cpus() > 1)
pr_warning(NAME "multiple CPUs still online, "
"may miss events.\n");
@@ -411,10 +418,10 @@ static void __ref leave_uniprocessor(void)
int cpu;
int err;
- if (cpus_weight(downed_cpus) == 0)
+ if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0)
return;
pr_notice(NAME "Re-enabling CPUs...\n");
- for_each_cpu_mask(cpu, downed_cpus) {
+ for_each_cpu(cpu, downed_cpus) {
err = cpu_up(cpu);
if (!err)
pr_info(NAME "enabled CPU%d.\n", cpu);
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
new file mode 100644
index 000000000000..550df481accd
--- /dev/null
+++ b/arch/x86/mm/numa.c
@@ -0,0 +1,67 @@
+/* Common code for 32 and 64-bit NUMA */
+#include <linux/topology.h>
+#include <linux/module.h>
+#include <linux/bootmem.h>
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+# define DBG(x...) printk(KERN_DEBUG x)
+#else
+# define DBG(x...)
+#endif
+
+/*
+ * Which logical CPUs are on which nodes
+ */
+cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+EXPORT_SYMBOL(node_to_cpumask_map);
+
+/*
+ * Allocate node_to_cpumask_map based on number of available nodes
+ * Requires node_possible_map to be valid.
+ *
+ * Note: node_to_cpumask() is not valid until after this is done.
+ * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
+ */
+void __init setup_node_to_cpumask_map(void)
+{
+ unsigned int node, num = 0;
+
+ /* setup nr_node_ids if not done yet */
+ if (nr_node_ids == MAX_NUMNODES) {
+ for_each_node_mask(node, node_possible_map)
+ num = node;
+ nr_node_ids = num + 1;
+ }
+
+ /* allocate the map */
+ for (node = 0; node < nr_node_ids; node++)
+ alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
+
+ /* cpumask_of_node() will now work */
+ pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
+}
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+/*
+ * Returns a pointer to the bitmask of CPUs on Node 'node'.
+ */
+const struct cpumask *cpumask_of_node(int node)
+{
+ if (node >= nr_node_ids) {
+ printk(KERN_WARNING
+ "cpumask_of_node(%d): node > nr_node_ids(%d)\n",
+ node, nr_node_ids);
+ dump_stack();
+ return cpu_none_mask;
+ }
+ if (node_to_cpumask_map[node] == NULL) {
+ printk(KERN_WARNING
+ "cpumask_of_node(%d): no node_to_cpumask_map!\n",
+ node);
+ dump_stack();
+ return cpu_online_mask;
+ }
+ return node_to_cpumask_map[node];
+}
+EXPORT_SYMBOL(cpumask_of_node);
+#endif
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 64c9cf043cdd..d73aaa892371 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -20,12 +20,6 @@
#include <asm/acpi.h>
#include <asm/k8.h>
-#ifdef CONFIG_DEBUG_PER_CPU_MAPS
-# define DBG(x...) printk(KERN_DEBUG x)
-#else
-# define DBG(x...)
-#endif
-
struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
EXPORT_SYMBOL(node_data);
@@ -49,12 +43,6 @@ DEFINE_EARLY_PER_CPU(int, x86_cpu_to_node_map, NUMA_NO_NODE);
EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_node_map);
/*
- * Which logical CPUs are on which nodes
- */
-cpumask_t *node_to_cpumask_map;
-EXPORT_SYMBOL(node_to_cpumask_map);
-
-/*
* Given a shift value, try to populate memnodemap[]
* Returns :
* 1 if OK
@@ -661,36 +649,6 @@ void __init init_cpu_to_node(void)
#endif
-/*
- * Allocate node_to_cpumask_map based on number of available nodes
- * Requires node_possible_map to be valid.
- *
- * Note: node_to_cpumask() is not valid until after this is done.
- * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
- */
-void __init setup_node_to_cpumask_map(void)
-{
- unsigned int node, num = 0;
- cpumask_t *map;
-
- /* setup nr_node_ids if not done yet */
- if (nr_node_ids == MAX_NUMNODES) {
- for_each_node_mask(node, node_possible_map)
- num = node;
- nr_node_ids = num + 1;
- }
-
- /* allocate the map */
- map = alloc_bootmem_low(nr_node_ids * sizeof(cpumask_t));
- DBG("node_to_cpumask_map at %p for %d nodes\n", map, nr_node_ids);
-
- pr_debug("Node to cpumask map at %p for %d nodes\n",
- map, nr_node_ids);
-
- /* node_to_cpumask() will now work */
- node_to_cpumask_map = map;
-}
-
void __cpuinit numa_set_node(int cpu, int node)
{
int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map);
@@ -723,12 +681,12 @@ void __cpuinit numa_clear_node(int cpu)
void __cpuinit numa_add_cpu(int cpu)
{
- cpu_set(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
+ cpumask_set_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
}
void __cpuinit numa_remove_cpu(int cpu)
{
- cpu_clear(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
+ cpumask_clear_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
}
#else /* CONFIG_DEBUG_PER_CPU_MAPS */
@@ -739,20 +697,20 @@ void __cpuinit numa_remove_cpu(int cpu)
static void __cpuinit numa_set_cpumask(int cpu, int enable)
{
int node = early_cpu_to_node(cpu);
- cpumask_t *mask;
+ struct cpumask *mask;
char buf[64];
- if (node_to_cpumask_map == NULL) {
- printk(KERN_ERR "node_to_cpumask_map NULL\n");
+ mask = node_to_cpumask_map[node];
+ if (mask == NULL) {
+ printk(KERN_ERR "node_to_cpumask_map[%i] NULL\n", node);
dump_stack();
return;
}
- mask = &node_to_cpumask_map[node];
if (enable)
- cpu_set(cpu, *mask);
+ cpumask_set_cpu(cpu, mask);
else
- cpu_clear(cpu, *mask);
+ cpumask_clear_cpu(cpu, mask);
cpulist_scnprintf(buf, sizeof(buf), mask);
printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n",
@@ -799,59 +757,6 @@ int early_cpu_to_node(int cpu)
return per_cpu(x86_cpu_to_node_map, cpu);
}
-
-/* empty cpumask */
-static const cpumask_t cpu_mask_none;
-
-/*
- * Returns a pointer to the bitmask of CPUs on Node 'node'.
- */
-const cpumask_t *cpumask_of_node(int node)
-{
- if (node_to_cpumask_map == NULL) {
- printk(KERN_WARNING
- "cpumask_of_node(%d): no node_to_cpumask_map!\n",
- node);
- dump_stack();
- return (const cpumask_t *)&cpu_online_map;
- }
- if (node >= nr_node_ids) {
- printk(KERN_WARNING
- "cpumask_of_node(%d): node > nr_node_ids(%d)\n",
- node, nr_node_ids);
- dump_stack();
- return &cpu_mask_none;
- }
- return &node_to_cpumask_map[node];
-}
-EXPORT_SYMBOL(cpumask_of_node);
-
-/*
- * Returns a bitmask of CPUs on Node 'node'.
- *
- * Side note: this function creates the returned cpumask on the stack
- * so with a high NR_CPUS count, excessive stack space is used. The
- * node_to_cpumask_ptr function should be used whenever possible.
- */
-cpumask_t node_to_cpumask(int node)
-{
- if (node_to_cpumask_map == NULL) {
- printk(KERN_WARNING
- "node_to_cpumask(%d): no node_to_cpumask_map!\n", node);
- dump_stack();
- return cpu_online_map;
- }
- if (node >= nr_node_ids) {
- printk(KERN_WARNING
- "node_to_cpumask(%d): node > nr_node_ids(%d)\n",
- node, nr_node_ids);
- dump_stack();
- return cpu_mask_none;
- }
- return node_to_cpumask_map[node];
-}
-EXPORT_SYMBOL(node_to_cpumask);
-
/*
* --------- end of debug versions of the numa functions ---------
*/
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 9c4294986af7..d71e1b636ce6 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -16,6 +16,7 @@
#include <asm/processor.h>
#include <asm/tlbflush.h>
#include <asm/sections.h>
+#include <asm/setup.h>
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
#include <asm/proto.h>
@@ -33,6 +34,7 @@ struct cpa_data {
unsigned long pfn;
unsigned force_split : 1;
int curpage;
+ struct page **pages;
};
/*
@@ -45,6 +47,7 @@ static DEFINE_SPINLOCK(cpa_lock);
#define CPA_FLUSHTLB 1
#define CPA_ARRAY 2
+#define CPA_PAGES_ARRAY 4
#ifdef CONFIG_PROC_FS
static unsigned long direct_pages_count[PG_LEVEL_NUM];
@@ -95,7 +98,7 @@ static inline unsigned long highmap_start_pfn(void)
static inline unsigned long highmap_end_pfn(void)
{
- return __pa(roundup((unsigned long)_end, PMD_SIZE)) >> PAGE_SHIFT;
+ return __pa(roundup(_brk_end, PMD_SIZE)) >> PAGE_SHIFT;
}
#endif
@@ -201,10 +204,10 @@ static void cpa_flush_range(unsigned long start, int numpages, int cache)
}
}
-static void cpa_flush_array(unsigned long *start, int numpages, int cache)
+static void cpa_flush_array(unsigned long *start, int numpages, int cache,
+ int in_flags, struct page **pages)
{
unsigned int i, level;
- unsigned long *addr;
BUG_ON(irqs_disabled());
@@ -225,14 +228,22 @@ static void cpa_flush_array(unsigned long *start, int numpages, int cache)
* will cause all other CPUs to flush the same
* cachelines:
*/
- for (i = 0, addr = start; i < numpages; i++, addr++) {
- pte_t *pte = lookup_address(*addr, &level);
+ for (i = 0; i < numpages; i++) {
+ unsigned long addr;
+ pte_t *pte;
+
+ if (in_flags & CPA_PAGES_ARRAY)
+ addr = (unsigned long)page_address(pages[i]);
+ else
+ addr = start[i];
+
+ pte = lookup_address(addr, &level);
/*
* Only flush present addresses:
*/
if (pte && (pte_val(*pte) & _PAGE_PRESENT))
- clflush_cache_range((void *) *addr, PAGE_SIZE);
+ clflush_cache_range((void *)addr, PAGE_SIZE);
}
}
@@ -584,7 +595,9 @@ static int __change_page_attr(struct cpa_data *cpa, int primary)
unsigned int level;
pte_t *kpte, old_pte;
- if (cpa->flags & CPA_ARRAY)
+ if (cpa->flags & CPA_PAGES_ARRAY)
+ address = (unsigned long)page_address(cpa->pages[cpa->curpage]);
+ else if (cpa->flags & CPA_ARRAY)
address = cpa->vaddr[cpa->curpage];
else
address = *cpa->vaddr;
@@ -687,7 +700,9 @@ static int cpa_process_alias(struct cpa_data *cpa)
* No need to redo, when the primary call touched the direct
* mapping already:
*/
- if (cpa->flags & CPA_ARRAY)
+ if (cpa->flags & CPA_PAGES_ARRAY)
+ vaddr = (unsigned long)page_address(cpa->pages[cpa->curpage]);
+ else if (cpa->flags & CPA_ARRAY)
vaddr = cpa->vaddr[cpa->curpage];
else
vaddr = *cpa->vaddr;
@@ -698,7 +713,7 @@ static int cpa_process_alias(struct cpa_data *cpa)
alias_cpa = *cpa;
temp_cpa_vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT);
alias_cpa.vaddr = &temp_cpa_vaddr;
- alias_cpa.flags &= ~CPA_ARRAY;
+ alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY);
ret = __change_page_attr_set_clr(&alias_cpa, 0);
@@ -711,7 +726,7 @@ static int cpa_process_alias(struct cpa_data *cpa)
* No need to redo, when the primary call touched the high
* mapping already:
*/
- if (within(vaddr, (unsigned long) _text, (unsigned long) _end))
+ if (within(vaddr, (unsigned long) _text, _brk_end))
return 0;
/*
@@ -724,7 +739,7 @@ static int cpa_process_alias(struct cpa_data *cpa)
alias_cpa = *cpa;
temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map - phys_base;
alias_cpa.vaddr = &temp_cpa_vaddr;
- alias_cpa.flags &= ~CPA_ARRAY;
+ alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY);
/*
* The high mapping range is imprecise, so ignore the return value.
@@ -745,7 +760,7 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
*/
cpa->numpages = numpages;
/* for array changes, we can't use large page */
- if (cpa->flags & CPA_ARRAY)
+ if (cpa->flags & (CPA_ARRAY | CPA_PAGES_ARRAY))
cpa->numpages = 1;
if (!debug_pagealloc)
@@ -769,7 +784,7 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
*/
BUG_ON(cpa->numpages > numpages);
numpages -= cpa->numpages;
- if (cpa->flags & CPA_ARRAY)
+ if (cpa->flags & (CPA_PAGES_ARRAY | CPA_ARRAY))
cpa->curpage++;
else
*cpa->vaddr += cpa->numpages * PAGE_SIZE;
@@ -786,7 +801,8 @@ static inline int cache_attr(pgprot_t attr)
static int change_page_attr_set_clr(unsigned long *addr, int numpages,
pgprot_t mask_set, pgprot_t mask_clr,
- int force_split, int array)
+ int force_split, int in_flag,
+ struct page **pages)
{
struct cpa_data cpa;
int ret, cache, checkalias;
@@ -801,15 +817,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
return 0;
/* Ensure we are PAGE_SIZE aligned */
- if (!array) {
- if (*addr & ~PAGE_MASK) {
- *addr &= PAGE_MASK;
- /*
- * People should not be passing in unaligned addresses:
- */
- WARN_ON_ONCE(1);
- }
- } else {
+ if (in_flag & CPA_ARRAY) {
int i;
for (i = 0; i < numpages; i++) {
if (addr[i] & ~PAGE_MASK) {
@@ -817,6 +825,18 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
WARN_ON_ONCE(1);
}
}
+ } else if (!(in_flag & CPA_PAGES_ARRAY)) {
+ /*
+ * in_flag of CPA_PAGES_ARRAY implies it is aligned.
+ * No need to cehck in that case
+ */
+ if (*addr & ~PAGE_MASK) {
+ *addr &= PAGE_MASK;
+ /*
+ * People should not be passing in unaligned addresses:
+ */
+ WARN_ON_ONCE(1);
+ }
}
/* Must avoid aliasing mappings in the highmem code */
@@ -832,6 +852,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
arch_flush_lazy_mmu_mode();
cpa.vaddr = addr;
+ cpa.pages = pages;
cpa.numpages = numpages;
cpa.mask_set = mask_set;
cpa.mask_clr = mask_clr;
@@ -839,8 +860,8 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
cpa.curpage = 0;
cpa.force_split = force_split;
- if (array)
- cpa.flags |= CPA_ARRAY;
+ if (in_flag & (CPA_ARRAY | CPA_PAGES_ARRAY))
+ cpa.flags |= in_flag;
/* No alias checking for _NX bit modifications */
checkalias = (pgprot_val(mask_set) | pgprot_val(mask_clr)) != _PAGE_NX;
@@ -866,9 +887,10 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
* wbindv):
*/
if (!ret && cpu_has_clflush) {
- if (cpa.flags & CPA_ARRAY)
- cpa_flush_array(addr, numpages, cache);
- else
+ if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) {
+ cpa_flush_array(addr, numpages, cache,
+ cpa.flags, pages);
+ } else
cpa_flush_range(*addr, numpages, cache);
} else
cpa_flush_all(cache);
@@ -888,14 +910,28 @@ static inline int change_page_attr_set(unsigned long *addr, int numpages,
pgprot_t mask, int array)
{
return change_page_attr_set_clr(addr, numpages, mask, __pgprot(0), 0,
- array);
+ (array ? CPA_ARRAY : 0), NULL);
}
static inline int change_page_attr_clear(unsigned long *addr, int numpages,
pgprot_t mask, int array)
{
return change_page_attr_set_clr(addr, numpages, __pgprot(0), mask, 0,
- array);
+ (array ? CPA_ARRAY : 0), NULL);
+}
+
+static inline int cpa_set_pages_array(struct page **pages, int numpages,
+ pgprot_t mask)
+{
+ return change_page_attr_set_clr(NULL, numpages, mask, __pgprot(0), 0,
+ CPA_PAGES_ARRAY, pages);
+}
+
+static inline int cpa_clear_pages_array(struct page **pages, int numpages,
+ pgprot_t mask)
+{
+ return change_page_attr_set_clr(NULL, numpages, __pgprot(0), mask, 0,
+ CPA_PAGES_ARRAY, pages);
}
int _set_memory_uc(unsigned long addr, int numpages)
@@ -1043,7 +1079,7 @@ int set_memory_np(unsigned long addr, int numpages)
int set_memory_4k(unsigned long addr, int numpages)
{
return change_page_attr_set_clr(&addr, numpages, __pgprot(0),
- __pgprot(0), 1, 0);
+ __pgprot(0), 1, 0, NULL);
}
int set_pages_uc(struct page *page, int numpages)
@@ -1054,6 +1090,35 @@ int set_pages_uc(struct page *page, int numpages)
}
EXPORT_SYMBOL(set_pages_uc);
+int set_pages_array_uc(struct page **pages, int addrinarray)
+{
+ unsigned long start;
+ unsigned long end;
+ int i;
+ int free_idx;
+
+ for (i = 0; i < addrinarray; i++) {
+ start = (unsigned long)page_address(pages[i]);
+ end = start + PAGE_SIZE;
+ if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL))
+ goto err_out;
+ }
+
+ if (cpa_set_pages_array(pages, addrinarray,
+ __pgprot(_PAGE_CACHE_UC_MINUS)) == 0) {
+ return 0; /* Success */
+ }
+err_out:
+ free_idx = i;
+ for (i = 0; i < free_idx; i++) {
+ start = (unsigned long)page_address(pages[i]);
+ end = start + PAGE_SIZE;
+ free_memtype(start, end);
+ }
+ return -EINVAL;
+}
+EXPORT_SYMBOL(set_pages_array_uc);
+
int set_pages_wb(struct page *page, int numpages)
{
unsigned long addr = (unsigned long)page_address(page);
@@ -1062,6 +1127,26 @@ int set_pages_wb(struct page *page, int numpages)
}
EXPORT_SYMBOL(set_pages_wb);
+int set_pages_array_wb(struct page **pages, int addrinarray)
+{
+ int retval;
+ unsigned long start;
+ unsigned long end;
+ int i;
+
+ retval = cpa_clear_pages_array(pages, addrinarray,
+ __pgprot(_PAGE_CACHE_MASK));
+
+ for (i = 0; i < addrinarray; i++) {
+ start = (unsigned long)page_address(pages[i]);
+ end = start + PAGE_SIZE;
+ free_memtype(start, end);
+ }
+
+ return retval;
+}
+EXPORT_SYMBOL(set_pages_array_wb);
+
int set_pages_x(struct page *page, int numpages)
{
unsigned long addr = (unsigned long)page_address(page);
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 2ed37158012d..640339ee4fb2 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -677,10 +677,11 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
is_ram = pat_pagerange_is_ram(paddr, paddr + size);
/*
- * reserve_pfn_range() doesn't support RAM pages.
+ * reserve_pfn_range() doesn't support RAM pages. Maintain the current
+ * behavior with RAM pages by returning success.
*/
if (is_ram != 0)
- return -EINVAL;
+ return 0;
ret = reserve_memtype(paddr, paddr + size, want_flags, &flags);
if (ret)
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
index f2e477c91c1b..46c8834aedc0 100644
--- a/arch/x86/mm/pgtable_32.c
+++ b/arch/x86/mm/pgtable_32.c
@@ -50,7 +50,7 @@ void set_pte_vaddr(unsigned long vaddr, pte_t pteval)
}
pte = pte_offset_kernel(pmd, vaddr);
if (pte_val(pteval))
- set_pte_present(&init_mm, vaddr, pte, pteval);
+ set_pte_at(&init_mm, vaddr, pte, pteval);
else
pte_clear(&init_mm, vaddr, pte);
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index 574c8bc95ef0..c7d272b8574c 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -116,6 +116,36 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
reserve_early(phys, phys + length, "ACPI SLIT");
}
+/* Callback for Proximity Domain -> x2APIC mapping */
+void __init
+acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
+{
+ int pxm, node;
+ int apic_id;
+
+ if (srat_disabled())
+ return;
+ if (pa->header.length < sizeof(struct acpi_srat_x2apic_cpu_affinity)) {
+ bad_srat();
+ return;
+ }
+ if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
+ return;
+ pxm = pa->proximity_domain;
+ node = setup_node(pxm);
+ if (node < 0) {
+ printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
+ bad_srat();
+ return;
+ }
+
+ apic_id = pa->apic_id;
+ apicid_to_node[apic_id] = node;
+ acpi_numa = 1;
+ printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
+ pxm, apic_id, node);
+}
+
/* Callback for Proximity Domain -> LAPIC mapping */
void __init
acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index a654d59e4483..821e97017e95 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -187,11 +187,6 @@ static void flush_tlb_others_ipi(const struct cpumask *cpumask,
cpumask, cpumask_of(smp_processor_id()));
/*
- * Make the above memory operations globally visible before
- * sending the IPI.
- */
- smp_mb();
- /*
* We have to send the IPI only to
* CPUs affected.
*/
diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c
index 4c4a51c90bc2..819b131fd752 100644
--- a/arch/x86/oprofile/op_model_p4.c
+++ b/arch/x86/oprofile/op_model_p4.c
@@ -380,7 +380,7 @@ static unsigned int get_stagger(void)
{
#ifdef CONFIG_SMP
int cpu = smp_processor_id();
- return (cpu != first_cpu(per_cpu(cpu_sibling_map, cpu)));
+ return cpu != cpumask_first(__get_cpu_var(cpu_sibling_map));
#endif
return 0;
}
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 82d22fc601ae..8c362b96b644 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -90,7 +90,7 @@ static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d)
return 0;
}
-static struct dmi_system_id can_skip_pciprobe_dmi_table[] __devinitdata = {
+static const struct dmi_system_id can_skip_pciprobe_dmi_table[] __devinitconst = {
/*
* Systems where PCI IO resource ISA alignment can be skipped
* when the ISA enable bit in the bridge control is not set
@@ -183,7 +183,7 @@ static int __devinit assign_all_busses(const struct dmi_system_id *d)
}
#endif
-static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
+static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = {
#ifdef __i386__
/*
* Laptops which need pci=assign-busses to see Cardbus cards
diff --git a/arch/x86/pci/early.c b/arch/x86/pci/early.c
index f6adf2c6d751..aaf26ae58cd5 100644
--- a/arch/x86/pci/early.c
+++ b/arch/x86/pci/early.c
@@ -69,11 +69,12 @@ void early_dump_pci_device(u8 bus, u8 slot, u8 func)
int j;
u32 val;
- printk(KERN_INFO "PCI: %02x:%02x:%02x", bus, slot, func);
+ printk(KERN_INFO "pci 0000:%02x:%02x.%d config space:",
+ bus, slot, func);
for (i = 0; i < 256; i += 4) {
if (!(i & 0x0f))
- printk("\n%04x:",i);
+ printk("\n %02x:",i);
val = read_pci_config(bus, slot, func, i);
for (j = 0; j < 4; j++) {
@@ -96,20 +97,22 @@ void early_dump_pci_devices(void)
for (func = 0; func < 8; func++) {
u32 class;
u8 type;
+
class = read_pci_config(bus, slot, func,
PCI_CLASS_REVISION);
if (class == 0xffffffff)
- break;
+ continue;
early_dump_pci_device(bus, slot, func);
- /* No multi-function device? */
- type = read_pci_config_byte(bus, slot, func,
+ if (func == 0) {
+ type = read_pci_config_byte(bus, slot,
+ func,
PCI_HEADER_TYPE);
- if (!(type & 0x80))
- break;
+ if (!(type & 0x80))
+ break;
+ }
}
}
}
}
-
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index 7d388d5cf548..6dd89555fbfa 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -356,7 +356,7 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
-static struct dmi_system_id __devinitdata msi_k8t_dmi_table[] = {
+static const struct dmi_system_id __devinitconst msi_k8t_dmi_table[] = {
{
.ident = "MSI-K8T-Neo2Fir",
.matches = {
@@ -413,7 +413,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
*/
static u16 toshiba_line_size;
-static struct dmi_system_id __devinitdata toshiba_ohci1394_dmi_table[] = {
+static const struct dmi_system_id __devinitconst toshiba_ohci1394_dmi_table[] = {
{
.ident = "Toshiba PS5 based laptop",
.matches = {
@@ -495,26 +495,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015,
pci_siemens_interrupt_controller);
/*
- * Regular PCI devices have 256 bytes, but AMD Family 10h/11h CPUs have
- * 4096 bytes configuration space for each function of their processor
- * configuration space.
- */
-static void amd_cpu_pci_cfg_space_size(struct pci_dev *dev)
-{
- dev->cfg_size = pci_cfg_space_size_ext(dev);
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1201, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1202, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1203, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1204, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1300, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1301, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1302, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1303, amd_cpu_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1304, amd_cpu_pci_cfg_space_size);
-
-/*
* SB600: Disable BAR1 on device 14.0 to avoid HPET resources from
* confusing the PCI engine:
*/
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 5ead808dd70c..f1817f71e009 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -258,24 +258,7 @@ void pcibios_set_master(struct pci_dev *dev)
pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
}
-static void pci_unmap_page_range(struct vm_area_struct *vma)
-{
- u64 addr = (u64)vma->vm_pgoff << PAGE_SHIFT;
- free_memtype(addr, addr + vma->vm_end - vma->vm_start);
-}
-
-static void pci_track_mmap_page_range(struct vm_area_struct *vma)
-{
- u64 addr = (u64)vma->vm_pgoff << PAGE_SHIFT;
- unsigned long flags = pgprot_val(vma->vm_page_prot)
- & _PAGE_CACHE_MASK;
-
- reserve_memtype(addr, addr + vma->vm_end - vma->vm_start, flags, NULL);
-}
-
static struct vm_operations_struct pci_mmap_ops = {
- .open = pci_track_mmap_page_range,
- .close = pci_unmap_page_range,
.access = generic_access_phys,
};
@@ -283,11 +266,6 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine)
{
unsigned long prot;
- u64 addr = vma->vm_pgoff << PAGE_SHIFT;
- unsigned long len = vma->vm_end - vma->vm_start;
- unsigned long flags;
- unsigned long new_flags;
- int retval;
/* I/O space cannot be accessed via normal processor loads and
* stores on this platform.
@@ -308,27 +286,6 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
vma->vm_page_prot = __pgprot(prot);
- flags = pgprot_val(vma->vm_page_prot) & _PAGE_CACHE_MASK;
- retval = reserve_memtype(addr, addr + len, flags, &new_flags);
- if (retval)
- return retval;
-
- if (flags != new_flags) {
- if (!is_new_memtype_allowed(flags, new_flags)) {
- free_memtype(addr, addr+len);
- return -EINVAL;
- }
- flags = new_flags;
- }
-
- if (((vma->vm_pgoff < max_low_pfn_mapped) ||
- (vma->vm_pgoff >= (1UL<<(32 - PAGE_SHIFT)) &&
- vma->vm_pgoff < max_pfn_mapped)) &&
- ioremap_change_attr((unsigned long)__va(addr), len, flags)) {
- free_memtype(addr, addr + len);
- return -EINVAL;
- }
-
if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c
index f1065b129e9c..4061bb0f267d 100644
--- a/arch/x86/pci/legacy.c
+++ b/arch/x86/pci/legacy.c
@@ -50,8 +50,6 @@ static int __init pci_legacy_init(void)
if (pci_root_bus)
pci_bus_add_devices(pci_root_bus);
- pcibios_fixup_peer_bridges();
-
return 0;
}
@@ -67,6 +65,7 @@ int __init pci_subsys_init(void)
pci_visws_init();
#endif
pci_legacy_init();
+ pcibios_fixup_peer_bridges();
pcibios_irq_init();
pcibios_init();
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 89bf9242c80a..905bb526b133 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/bitmap.h>
+#include <linux/sort.h>
#include <asm/e820.h>
#include <asm/pci_x86.h>
@@ -24,24 +25,49 @@
/* Indicate if the mmcfg resources have been placed into the resource table. */
static int __initdata pci_mmcfg_resources_inserted;
+static __init int extend_mmcfg(int num)
+{
+ struct acpi_mcfg_allocation *new;
+ int new_num = pci_mmcfg_config_num + num;
+
+ new = kzalloc(sizeof(pci_mmcfg_config[0]) * new_num, GFP_KERNEL);
+ if (!new)
+ return -1;
+
+ if (pci_mmcfg_config) {
+ memcpy(new, pci_mmcfg_config,
+ sizeof(pci_mmcfg_config[0]) * new_num);
+ kfree(pci_mmcfg_config);
+ }
+ pci_mmcfg_config = new;
+
+ return 0;
+}
+
+static __init void fill_one_mmcfg(u64 addr, int segment, int start, int end)
+{
+ int i = pci_mmcfg_config_num;
+
+ pci_mmcfg_config_num++;
+ pci_mmcfg_config[i].address = addr;
+ pci_mmcfg_config[i].pci_segment = segment;
+ pci_mmcfg_config[i].start_bus_number = start;
+ pci_mmcfg_config[i].end_bus_number = end;
+}
+
static const char __init *pci_mmcfg_e7520(void)
{
u32 win;
raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0xce, 2, &win);
win = win & 0xf000;
- if(win == 0x0000 || win == 0xf000)
- pci_mmcfg_config_num = 0;
- else {
- pci_mmcfg_config_num = 1;
- pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
- if (!pci_mmcfg_config)
- return NULL;
- pci_mmcfg_config[0].address = win << 16;
- pci_mmcfg_config[0].pci_segment = 0;
- pci_mmcfg_config[0].start_bus_number = 0;
- pci_mmcfg_config[0].end_bus_number = 255;
- }
+ if (win == 0x0000 || win == 0xf000)
+ return NULL;
+
+ if (extend_mmcfg(1) == -1)
+ return NULL;
+
+ fill_one_mmcfg(win << 16, 0, 0, 255);
return "Intel Corporation E7520 Memory Controller Hub";
}
@@ -50,13 +76,11 @@ static const char __init *pci_mmcfg_intel_945(void)
{
u32 pciexbar, mask = 0, len = 0;
- pci_mmcfg_config_num = 1;
-
raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0x48, 4, &pciexbar);
/* Enable bit */
if (!(pciexbar & 1))
- pci_mmcfg_config_num = 0;
+ return NULL;
/* Size bits */
switch ((pciexbar >> 1) & 3) {
@@ -73,28 +97,23 @@ static const char __init *pci_mmcfg_intel_945(void)
len = 0x04000000U;
break;
default:
- pci_mmcfg_config_num = 0;
+ return NULL;
}
/* Errata #2, things break when not aligned on a 256Mb boundary */
/* Can only happen in 64M/128M mode */
if ((pciexbar & mask) & 0x0fffffffU)
- pci_mmcfg_config_num = 0;
+ return NULL;
/* Don't hit the APIC registers and their friends */
if ((pciexbar & mask) >= 0xf0000000U)
- pci_mmcfg_config_num = 0;
-
- if (pci_mmcfg_config_num) {
- pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
- if (!pci_mmcfg_config)
- return NULL;
- pci_mmcfg_config[0].address = pciexbar & mask;
- pci_mmcfg_config[0].pci_segment = 0;
- pci_mmcfg_config[0].start_bus_number = 0;
- pci_mmcfg_config[0].end_bus_number = (len >> 20) - 1;
- }
+ return NULL;
+
+ if (extend_mmcfg(1) == -1)
+ return NULL;
+
+ fill_one_mmcfg(pciexbar & mask, 0, 0, (len >> 20) - 1);
return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
}
@@ -138,22 +157,77 @@ static const char __init *pci_mmcfg_amd_fam10h(void)
busnbits = 8;
}
- pci_mmcfg_config_num = (1 << segnbits);
- pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]) *
- pci_mmcfg_config_num, GFP_KERNEL);
- if (!pci_mmcfg_config)
+ if (extend_mmcfg(1 << segnbits) == -1)
return NULL;
- for (i = 0; i < (1 << segnbits); i++) {
- pci_mmcfg_config[i].address = base + (1<<28) * i;
- pci_mmcfg_config[i].pci_segment = i;
- pci_mmcfg_config[i].start_bus_number = 0;
- pci_mmcfg_config[i].end_bus_number = (1 << busnbits) - 1;
- }
+ for (i = 0; i < (1 << segnbits); i++)
+ fill_one_mmcfg(base + (1<<28) * i, i, 0, (1 << busnbits) - 1);
return "AMD Family 10h NB";
}
+static bool __initdata mcp55_checked;
+static const char __init *pci_mmcfg_nvidia_mcp55(void)
+{
+ int bus;
+ int mcp55_mmconf_found = 0;
+
+ static const u32 extcfg_regnum = 0x90;
+ static const u32 extcfg_regsize = 4;
+ static const u32 extcfg_enable_mask = 1<<31;
+ static const u32 extcfg_start_mask = 0xff<<16;
+ static const int extcfg_start_shift = 16;
+ static const u32 extcfg_size_mask = 0x3<<28;
+ static const int extcfg_size_shift = 28;
+ static const int extcfg_sizebus[] = {0x100, 0x80, 0x40, 0x20};
+ static const u32 extcfg_base_mask[] = {0x7ff8, 0x7ffc, 0x7ffe, 0x7fff};
+ static const int extcfg_base_lshift = 25;
+
+ /*
+ * do check if amd fam10h already took over
+ */
+ if (!acpi_disabled || pci_mmcfg_config_num || mcp55_checked)
+ return NULL;
+
+ mcp55_checked = true;
+ for (bus = 0; bus < 256; bus++) {
+ u64 base;
+ u32 l, extcfg;
+ u16 vendor, device;
+ int start, size_index, end;
+
+ raw_pci_ops->read(0, bus, PCI_DEVFN(0, 0), 0, 4, &l);
+ vendor = l & 0xffff;
+ device = (l >> 16) & 0xffff;
+
+ if (PCI_VENDOR_ID_NVIDIA != vendor || 0x0369 != device)
+ continue;
+
+ raw_pci_ops->read(0, bus, PCI_DEVFN(0, 0), extcfg_regnum,
+ extcfg_regsize, &extcfg);
+
+ if (!(extcfg & extcfg_enable_mask))
+ continue;
+
+ if (extend_mmcfg(1) == -1)
+ continue;
+
+ size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift;
+ base = extcfg & extcfg_base_mask[size_index];
+ /* base could > 4G */
+ base <<= extcfg_base_lshift;
+ start = (extcfg & extcfg_start_mask) >> extcfg_start_shift;
+ end = start + extcfg_sizebus[size_index] - 1;
+ fill_one_mmcfg(base, 0, start, end);
+ mcp55_mmconf_found++;
+ }
+
+ if (!mcp55_mmconf_found)
+ return NULL;
+
+ return "nVidia MCP55";
+}
+
struct pci_mmcfg_hostbridge_probe {
u32 bus;
u32 devfn;
@@ -171,8 +245,52 @@ static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = {
0x1200, pci_mmcfg_amd_fam10h },
{ 0xff, PCI_DEVFN(0, 0), PCI_VENDOR_ID_AMD,
0x1200, pci_mmcfg_amd_fam10h },
+ { 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_NVIDIA,
+ 0x0369, pci_mmcfg_nvidia_mcp55 },
};
+static int __init cmp_mmcfg(const void *x1, const void *x2)
+{
+ const typeof(pci_mmcfg_config[0]) *m1 = x1;
+ const typeof(pci_mmcfg_config[0]) *m2 = x2;
+ int start1, start2;
+
+ start1 = m1->start_bus_number;
+ start2 = m2->start_bus_number;
+
+ return start1 - start2;
+}
+
+static void __init pci_mmcfg_check_end_bus_number(void)
+{
+ int i;
+ typeof(pci_mmcfg_config[0]) *cfg, *cfgx;
+
+ /* sort them at first */
+ sort(pci_mmcfg_config, pci_mmcfg_config_num,
+ sizeof(pci_mmcfg_config[0]), cmp_mmcfg, NULL);
+
+ /* last one*/
+ if (pci_mmcfg_config_num > 0) {
+ i = pci_mmcfg_config_num - 1;
+ cfg = &pci_mmcfg_config[i];
+ if (cfg->end_bus_number < cfg->start_bus_number)
+ cfg->end_bus_number = 255;
+ }
+
+ /* don't overlap please */
+ for (i = 0; i < pci_mmcfg_config_num - 1; i++) {
+ cfg = &pci_mmcfg_config[i];
+ cfgx = &pci_mmcfg_config[i+1];
+
+ if (cfg->end_bus_number < cfg->start_bus_number)
+ cfg->end_bus_number = 255;
+
+ if (cfg->end_bus_number >= cfgx->start_bus_number)
+ cfg->end_bus_number = cfgx->start_bus_number - 1;
+ }
+}
+
static int __init pci_mmcfg_check_hostbridge(void)
{
u32 l;
@@ -186,31 +304,33 @@ static int __init pci_mmcfg_check_hostbridge(void)
pci_mmcfg_config_num = 0;
pci_mmcfg_config = NULL;
- name = NULL;
- for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
+ for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
bus = pci_mmcfg_probes[i].bus;
devfn = pci_mmcfg_probes[i].devfn;
raw_pci_ops->read(0, bus, devfn, 0, 4, &l);
vendor = l & 0xffff;
device = (l >> 16) & 0xffff;
+ name = NULL;
if (pci_mmcfg_probes[i].vendor == vendor &&
pci_mmcfg_probes[i].device == device)
name = pci_mmcfg_probes[i].probe();
- }
- if (name) {
- printk(KERN_INFO "PCI: Found %s %s MMCONFIG support.\n",
- name, pci_mmcfg_config_num ? "with" : "without");
+ if (name)
+ printk(KERN_INFO "PCI: Found %s with MMCONFIG support.\n",
+ name);
}
- return name != NULL;
+ /* some end_bus_number is crazy, fix it */
+ pci_mmcfg_check_end_bus_number();
+
+ return pci_mmcfg_config_num != 0;
}
static void __init pci_mmcfg_insert_resources(void)
{
-#define PCI_MMCFG_RESOURCE_NAME_LEN 19
+#define PCI_MMCFG_RESOURCE_NAME_LEN 24
int i;
struct resource *res;
char *names;
@@ -228,9 +348,10 @@ static void __init pci_mmcfg_insert_resources(void)
struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i];
num_buses = cfg->end_bus_number - cfg->start_bus_number + 1;
res->name = names;
- snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u",
- cfg->pci_segment);
- res->start = cfg->address;
+ snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN,
+ "PCI MMCONFIG %u [%02x-%02x]", cfg->pci_segment,
+ cfg->start_bus_number, cfg->end_bus_number);
+ res->start = cfg->address + (cfg->start_bus_number << 20);
res->end = res->start + (num_buses << 20) - 1;
res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
insert_resource(&iomem_resource, res);
@@ -354,8 +475,6 @@ static void __init pci_mmcfg_reject_broken(int early)
(pci_mmcfg_config[0].address == 0))
return;
- cfg = &pci_mmcfg_config[0];
-
for (i = 0; i < pci_mmcfg_config_num; i++) {
int valid = 0;
u64 addr, size;
@@ -423,10 +542,10 @@ static void __init __pci_mmcfg_init(int early)
known_bridge = 1;
}
- if (!known_bridge) {
+ if (!known_bridge)
acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
- pci_mmcfg_reject_broken(early);
- }
+
+ pci_mmcfg_reject_broken(early);
if ((pci_mmcfg_config_num == 0) ||
(pci_mmcfg_config == NULL) ||
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index 30007ffc8e11..94349f8b2f96 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -112,13 +112,18 @@ static struct pci_raw_ops pci_mmcfg = {
static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
{
void __iomem *addr;
- u32 size;
-
- size = (cfg->end_bus_number + 1) << 20;
- addr = ioremap_nocache(cfg->address, size);
+ u64 start, size;
+
+ start = cfg->start_bus_number;
+ start <<= 20;
+ start += cfg->address;
+ size = cfg->end_bus_number + 1 - cfg->start_bus_number;
+ size <<= 20;
+ addr = ioremap_nocache(start, size);
if (addr) {
printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n",
- cfg->address, cfg->address + size - 1);
+ start, start + size - 1);
+ addr -= cfg->start_bus_number << 20;
}
return addr;
}
@@ -157,7 +162,7 @@ void __init pci_mmcfg_arch_free(void)
for (i = 0; i < pci_mmcfg_config_num; ++i) {
if (pci_mmcfg_virt[i].virt) {
- iounmap(pci_mmcfg_virt[i].virt);
+ iounmap(pci_mmcfg_virt[i].virt + (pci_mmcfg_virt[i].cfg->start_bus_number << 20));
pci_mmcfg_virt[i].virt = NULL;
pci_mmcfg_virt[i].cfg = NULL;
}
diff --git a/arch/x86/power/Makefile b/arch/x86/power/Makefile
index 9ff4d5b55ad1..58b32db33125 100644
--- a/arch/x86/power/Makefile
+++ b/arch/x86/power/Makefile
@@ -1,2 +1,7 @@
+# __restore_processor_state() restores %gs after S3 resume and so should not
+# itself be stack-protected
+nostackp := $(call cc-option, -fno-stack-protector)
+CFLAGS_cpu_$(BITS).o := $(nostackp)
+
obj-$(CONFIG_PM_SLEEP) += cpu_$(BITS).o
obj-$(CONFIG_HIBERNATION) += hibernate_$(BITS).o hibernate_asm_$(BITS).o
diff --git a/arch/x86/power/cpu_32.c b/arch/x86/power/cpu_32.c
index 274d06082f48..ce702c5b3a2c 100644
--- a/arch/x86/power/cpu_32.c
+++ b/arch/x86/power/cpu_32.c
@@ -12,6 +12,7 @@
#include <asm/mtrr.h>
#include <asm/mce.h>
#include <asm/xcr.h>
+#include <asm/suspend.h>
static struct saved_context saved_context;
diff --git a/arch/x86/power/cpu_64.c b/arch/x86/power/cpu_64.c
index e3b6cf70d62c..5343540f2607 100644
--- a/arch/x86/power/cpu_64.c
+++ b/arch/x86/power/cpu_64.c
@@ -15,6 +15,7 @@
#include <asm/pgtable.h>
#include <asm/mtrr.h>
#include <asm/xcr.h>
+#include <asm/suspend.h>
static void fix_processor_context(void);
diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c
index 6dd000dd7933..65fdc86e923f 100644
--- a/arch/x86/power/hibernate_64.c
+++ b/arch/x86/power/hibernate_64.c
@@ -14,6 +14,7 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/mtrr.h>
+#include <asm/suspend.h>
/* References to section boundaries */
extern const void __nosave_begin, __nosave_end;
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index cb6afa4ec95c..db3802fb7b84 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1723,9 +1723,9 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
{
pmd_t *kernel_pmd;
- init_pg_tables_start = __pa(pgd);
- init_pg_tables_end = __pa(pgd) + xen_start_info->nr_pt_frames*PAGE_SIZE;
- max_pfn_mapped = PFN_DOWN(init_pg_tables_end + 512*1024);
+ max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) +
+ xen_start_info->nr_pt_frames * PAGE_SIZE +
+ 512*1024);
kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd);
memcpy(level2_kernel_pgt, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD);
@@ -1870,7 +1870,6 @@ const struct pv_mmu_ops xen_mmu_ops __initdata = {
#ifdef CONFIG_X86_PAE
.set_pte_atomic = xen_set_pte_atomic,
- .set_pte_present = xen_set_pte_at,
.pte_clear = xen_pte_clear,
.pmd_clear = xen_pmd_clear,
#endif /* CONFIG_X86_PAE */
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 8d470562ffc9..585a6e330837 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -158,7 +158,7 @@ static void __init xen_fill_possible_map(void)
rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
if (rc >= 0) {
num_processors++;
- cpu_set(i, cpu_possible_map);
+ set_cpu_possible(i, true);
}
}
}
@@ -197,7 +197,7 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus)
while ((num_possible_cpus() > 1) && (num_possible_cpus() > max_cpus)) {
for (cpu = nr_cpu_ids - 1; !cpu_possible(cpu); cpu--)
continue;
- cpu_clear(cpu, cpu_possible_map);
+ set_cpu_possible(cpu, false);
}
for_each_possible_cpu (cpu) {
@@ -210,7 +210,7 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus)
if (IS_ERR(idle))
panic("failed fork for CPU %d", cpu);
- cpu_set(cpu, cpu_present_map);
+ set_cpu_present(cpu, true);
}
}
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 981200830432..fa6dc4dd3b19 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -4,16 +4,13 @@
mainmenu "Linux/Xtensa Kernel Configuration"
config FRAME_POINTER
- bool
- default n
+ def_bool n
config ZONE_DMA
- bool
- default y
+ def_bool y
config XTENSA
- bool
- default y
+ def_bool y
select HAVE_IDE
help
Xtensa processors are 32-bit RISC machines designed by Tensilica
@@ -24,28 +21,25 @@ config XTENSA
a home page at <http://xtensa.sourceforge.net/>.
config RWSEM_XCHGADD_ALGORITHM
- bool
- default y
+ def_bool y
config GENERIC_FIND_NEXT_BIT
- bool
- default y
+ def_bool y
config GENERIC_HWEIGHT
- bool
- default y
+ def_bool y
config GENERIC_HARDIRQS
- bool
- default y
+ def_bool y
+
+config GENERIC_GPIO
+ def_bool y
config ARCH_HAS_ILOG2_U32
- bool
- default n
+ def_bool n
config ARCH_HAS_ILOG2_U64
- bool
- default n
+ def_bool n
config NO_IOPORT
def_bool y
@@ -54,9 +48,18 @@ config HZ
int
default 100
+config GENERIC_TIME
+ def_bool y
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
+config MMU
+ def_bool n
+
+config VARIANT_IRQ_SWITCH
+ def_bool n
+
menu "Processor type and features"
choice
@@ -65,38 +68,41 @@ choice
config XTENSA_VARIANT_FSF
bool "fsf - default (not generic) configuration"
+ select MMU
config XTENSA_VARIANT_DC232B
bool "dc232b - Diamond 232L Standard Core Rev.B (LE)"
+ select MMU
help
- This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE).
-endchoice
+ This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE).
-config MMU
- bool
- default y
+config XTENSA_VARIANT_S6000
+ bool "s6000 - Stretch software configurable processor"
+ select VARIANT_IRQ_SWITCH
+ select ARCH_REQUIRE_GPIOLIB
+endchoice
config XTENSA_UNALIGNED_USER
bool "Unaligned memory access in use space"
- ---help---
- The Xtensa architecture currently does not handle unaligned
- memory accesses in hardware but through an exception handler.
- Per default, unaligned memory accesses are disabled in user space.
+ help
+ The Xtensa architecture currently does not handle unaligned
+ memory accesses in hardware but through an exception handler.
+ Per default, unaligned memory accesses are disabled in user space.
- Say Y here to enable unaligned memory access in user space.
+ Say Y here to enable unaligned memory access in user space.
config PREEMPT
bool "Preemptible Kernel"
- ---help---
- This option reduces the latency of the kernel when reacting to
- real-time or interactive events by allowing a low priority process to
- be preempted even if it is in kernel mode executing a system call.
- Unfortunately the kernel code has some race conditions if both
- CONFIG_SMP and CONFIG_PREEMPT are enabled, so this option is
- currently disabled if you are building an SMP kernel.
+ help
+ This option reduces the latency of the kernel when reacting to
+ real-time or interactive events by allowing a low priority process to
+ be preempted even if it is in kernel mode executing a system call.
+ Unfortunately the kernel code has some race conditions if both
+ CONFIG_SMP and CONFIG_PREEMPT are enabled, so this option is
+ currently disabled if you are building an SMP kernel.
- Say Y here if you are building a kernel for a desktop, embedded
- or real-time system. Say N if you are unsure.
+ Say Y here if you are building a kernel for a desktop, embedded
+ or real-time system. Say N if you are unsure.
config MATH_EMULATION
bool "Math emulation"
@@ -105,6 +111,32 @@ config MATH_EMULATION
endmenu
+config XTENSA_CALIBRATE_CCOUNT
+ def_bool n
+ help
+ On some platforms (XT2000, for example), the CPU clock rate can
+ vary. The frequency can be determined, however, by measuring
+ against a well known, fixed frequency, such as an UART oscillator.
+
+config SERIAL_CONSOLE
+ def_bool n
+
+config XTENSA_ISS_NETWORK
+ def_bool n
+
+menu "Bus options"
+
+config PCI
+ bool "PCI support"
+ default y
+ help
+ Find out whether you have a PCI motherboard. PCI is the name of a
+ bus system, i.e. the way the CPU talks to the other stuff inside
+ your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
+ VESA. If you have PCI, say Y, otherwise N.
+
+source "drivers/pci/Kconfig"
+
menu "Platform options"
choice
@@ -113,33 +145,35 @@ choice
config XTENSA_PLATFORM_ISS
bool "ISS"
+ select XTENSA_CALIBRATE_CCOUNT
+ select SERIAL_CONSOLE
+ select XTENSA_ISS_NETWORK
help
ISS is an acronym for Tensilica's Instruction Set Simulator.
config XTENSA_PLATFORM_XT2000
bool "XT2000"
+ select XTENSA_CALIBRATE_CCOUNT
+ select PCI
help
XT2000 is the name of Tensilica's feature-rich emulation platform.
This hardware is capable of running a full Linux distribution.
-endchoice
+config XTENSA_PLATFORM_S6105
+ bool "S6105"
+ select SERIAL_CONSOLE
+endchoice
-config XTENSA_CALIBRATE_CCOUNT
- bool "Auto calibration of the CPU clock rate"
- ---help---
- On some platforms (XT2000, for example), the CPU clock rate can
- vary. The frequency can be determined, however, by measuring
- against a well known, fixed frequency, such as an UART oscillator.
config XTENSA_CPU_CLOCK
int "CPU clock rate [MHz]"
depends on !XTENSA_CALIBRATE_CCOUNT
- default "16"
+ default 16
config GENERIC_CALIBRATE_DELAY
bool "Auto calibration of the BogoMIPS value"
- ---help---
+ help
The BogoMIPS value can easily be derived from the CPU frequency.
config CMDLINE_BOOL
@@ -156,52 +190,27 @@ config CMDLINE
time by entering them here. As a minimum, you should specify the
memory size and the root device (e.g., mem=64M root=/dev/nfs).
-config SERIAL_CONSOLE
- bool
- depends on XTENSA_PLATFORM_ISS
- default y
-
-config XTENSA_ISS_NETWORK
- bool
- depends on XTENSA_PLATFORM_ISS
- default y
-
source "mm/Kconfig"
endmenu
-menu "Bus options"
-
-config PCI
- bool "PCI support" if !XTENSA_PLATFORM_ISS
- depends on !XTENSA_PLATFORM_ISS
- default y
+config HOTPLUG
+ bool "Support for hot-pluggable devices"
help
- Find out whether you have a PCI motherboard. PCI is the name of a
- bus system, i.e. the way the CPU talks to the other stuff inside
- your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
- VESA. If you have PCI, say Y, otherwise N.
+ Say Y here if you want to plug devices into your computer while
+ the system is running, and be able to use them quickly. In many
+ cases, the devices can likewise be unplugged at any time too.
-source "drivers/pci/Kconfig"
+ One well known example of this is PCMCIA- or PC-cards, credit-card
+ size devices such as network cards, modems or hard drives which are
+ plugged into slots found on all modern laptop computers. Another
+ example, used on modern desktops as well as laptops, is USB.
-config HOTPLUG
-
- bool "Support for hot-pluggable devices"
- ---help---
- Say Y here if you want to plug devices into your computer while
- the system is running, and be able to use them quickly. In many
- cases, the devices can likewise be unplugged at any time too.
-
- One well known example of this is PCMCIA- or PC-cards, credit-card
- size devices such as network cards, modems or hard drives which are
- plugged into slots found on all modern laptop computers. Another
- example, used on modern desktops as well as laptops, is USB.
-
- Enable HOTPLUG and build a modular kernel. Get agent software
- (from <http://linux-hotplug.sourceforge.net/>) and install it.
- Then your kernel will automatically call out to a user mode "policy
- agent" (/sbin/hotplug) to load modules and set up software needed
- to use devices as you hotplug them.
+ Enable HOTPLUG and build a modular kernel. Get agent software
+ (from <http://linux-hotplug.sourceforge.net/>) and install it.
+ Then your kernel will automatically call out to a user mode "policy
+ agent" (/sbin/hotplug) to load modules and set up software needed
+ to use devices as you hotplug them.
source "drivers/pcmcia/Kconfig"
@@ -213,9 +222,8 @@ menu "Executable file formats"
# only elf supported
config KCORE_ELF
- bool
+ def_bool y
depends on PROC_FS
- default y
help
If you enabled support for /proc file system then the file
/proc/kcore will contain the kernel core image in ELF format. This
@@ -240,7 +248,7 @@ source "fs/Kconfig"
menu "Xtensa initrd options"
depends on BLK_DEV_INITRD
- config EMBEDDED_RAMDISK
+config EMBEDDED_RAMDISK
bool "Embed root filesystem ramdisk into the kernel"
config EMBEDDED_RAMDISK_IMAGE
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index 1da55fe4beff..4caffac3ca2e 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -15,6 +15,7 @@
variant-$(CONFIG_XTENSA_VARIANT_FSF) := fsf
variant-$(CONFIG_XTENSA_VARIANT_DC232B) := dc232b
+variant-$(CONFIG_XTENSA_VARIANT_S6000) := s6000
variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM) := custom
VARIANT = $(variant-y)
@@ -24,6 +25,7 @@ export VARIANT
platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000
platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss
+platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105
PLATFORM = $(platform-y)
export PLATFORM
@@ -62,20 +64,23 @@ ifneq ($(VARIANT),)
endif
endif
-#
+# Only build variant and/or platform if it includes a Makefile
+
+buildvar := $(shell test -a $(srctree)/arch/xtensa/variants/$(VARIANT)/Makefile && echo arch/xtensa/variants/$(VARIANT)/)
+buildplf := $(shell test -a $(srctree)/arch/xtensa/platforms/$(PLATFORM)/Makefile && echo arch/xtensa/platforms/$(PLATFORM)/)
+
+# Find libgcc.a
LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
head-y := arch/xtensa/kernel/head.o
core-y += arch/xtensa/kernel/ arch/xtensa/mm/
-ifneq ($(PLATFORM),)
-core-y += arch/xtensa/platforms/$(PLATFORM)/
-endif
+core-y += $(buildvar) $(buildplf)
+
libs-y += arch/xtensa/lib/ $(LIBGCC)
boot := arch/xtensa/boot
-
all: zImage
bzImage : zImage
diff --git a/arch/xtensa/configs/s6105_defconfig b/arch/xtensa/configs/s6105_defconfig
new file mode 100644
index 000000000000..6e1deff41590
--- /dev/null
+++ b/arch/xtensa/configs/s6105_defconfig
@@ -0,0 +1,530 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.29-rc7-s6
+# Tue Mar 10 11:09:26 2009
+#
+# CONFIG_FRAME_POINTER is not set
+CONFIG_ZONE_DMA=y
+CONFIG_XTENSA=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_NO_IOPORT=y
+CONFIG_HZ=100
+CONFIG_GENERIC_TIME=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_CLASSIC_RCU is not set
+# CONFIG_TREE_RCU is not set
+CONFIG_PREEMPT_RCU=y
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+# CONFIG_MMU is not set
+CONFIG_VARIANT_IRQ_SWITCH=y
+
+#
+# Processor type and features
+#
+# CONFIG_XTENSA_VARIANT_FSF is not set
+# CONFIG_XTENSA_VARIANT_DC232B is not set
+CONFIG_XTENSA_VARIANT_S6000=y
+# CONFIG_XTENSA_UNALIGNED_USER is not set
+CONFIG_PREEMPT=y
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_HIGHMEM is not set
+# CONFIG_XTENSA_CALIBRATE_CCOUNT is not set
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_XTENSA_ISS_NETWORK is not set
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# Platform options
+#
+# CONFIG_XTENSA_PLATFORM_ISS is not set
+# CONFIG_XTENSA_PLATFORM_XT2000 is not set
+CONFIG_XTENSA_PLATFORM_S6105=y
+CONFIG_XTENSA_CPU_CLOCK=300
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS1,38400 debug bootmem_debug loglevel=7"
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_VIRT_TO_BUS=y
+
+#
+# Executable file formats
+#
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_COMPAT_NET_DEV_OPS=y
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_NETDEVICES is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Xtensa initrd options
+#
+# CONFIG_EMBEDDED_RAMDISK is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_DEBUG_NOMMU_REGIONS=y
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+
+#
+# Tracers
+#
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h
index 94c4c53a099e..8fc1c0c8de07 100644
--- a/arch/xtensa/include/asm/cacheflush.h
+++ b/arch/xtensa/include/asm/cacheflush.h
@@ -65,13 +65,17 @@ extern void __flush_invalidate_dcache_range(unsigned long, unsigned long);
# define __flush_invalidate_dcache_range(p,s) __invalidate_dcache_range(p,s)
#endif
-#if (DCACHE_WAY_SIZE > PAGE_SIZE)
+#if defined(CONFIG_MMU) && (DCACHE_WAY_SIZE > PAGE_SIZE)
extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long);
+#else
+static inline void __flush_invalidate_dcache_page_alias(unsigned long virt,
+ unsigned long phys) { }
#endif
-#if (ICACHE_WAY_SIZE > PAGE_SIZE)
+#if defined(CONFIG_MMU) && (ICACHE_WAY_SIZE > PAGE_SIZE)
extern void __invalidate_icache_page_alias(unsigned long, unsigned long);
#else
-# define __invalidate_icache_page_alias(v,p) do { } while(0)
+static inline void __invalidate_icache_page_alias(unsigned long virt,
+ unsigned long phys) { }
#endif
/*
diff --git a/arch/xtensa/include/asm/dma.h b/arch/xtensa/include/asm/dma.h
index e30f3abf48f0..137ca3945b07 100644
--- a/arch/xtensa/include/asm/dma.h
+++ b/arch/xtensa/include/asm/dma.h
@@ -44,8 +44,9 @@
* the value desired).
*/
+#ifndef MAX_DMA_ADDRESS
#define MAX_DMA_ADDRESS (PAGE_OFFSET + XCHAL_KIO_SIZE - 1)
-
+#endif
/* Reserve and release a DMA channel */
extern int request_dma(unsigned int dmanr, const char * device_id);
diff --git a/arch/xtensa/include/asm/flat.h b/arch/xtensa/include/asm/flat.h
new file mode 100644
index 000000000000..94c44abf15e4
--- /dev/null
+++ b/arch/xtensa/include/asm/flat.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_XTENSA_FLAT_H
+#define __ASM_XTENSA_FLAT_H
+
+#define flat_argvp_envp_on_stack() 0
+#define flat_old_ram_flag(flags) (flags)
+#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
+#define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp)
+#define flat_put_addr_at_rp(rp, val, relval ) put_unaligned(val, rp)
+#define flat_get_relocate_addr(rel) (rel)
+#define flat_set_persistent(relval, p) 0
+
+#endif /* __ASM_XTENSA_FLAT_H */
diff --git a/arch/xtensa/include/asm/gpio.h b/arch/xtensa/include/asm/gpio.h
new file mode 100644
index 000000000000..0763b0763960
--- /dev/null
+++ b/arch/xtensa/include/asm/gpio.h
@@ -0,0 +1,56 @@
+/*
+ * Generic GPIO API implementation for xtensa.
+ *
+ * Stolen from x86, which is derived from the generic GPIO API for powerpc:
+ *
+ * Copyright (c) 2007-2008 MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _ASM_XTENSA_GPIO_H
+#define _ASM_XTENSA_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+#ifdef CONFIG_GPIOLIB
+
+/*
+ * Just call gpiolib.
+ */
+static inline int gpio_get_value(unsigned int gpio)
+{
+ return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned int gpio, int value)
+{
+ __gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned int gpio)
+{
+ return __gpio_cansleep(gpio);
+}
+
+/*
+ * Not implemented, yet.
+ */
+static inline int gpio_to_irq(unsigned int gpio)
+{
+ return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+ return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+#endif /* _ASM_XTENSA_GPIO_H */
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index 07b7299dab20..d04cd3a625fa 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -69,21 +69,28 @@ static inline void * phys_to_virt(unsigned long address)
static inline void *ioremap(unsigned long offset, unsigned long size)
{
+#ifdef CONFIG_MMU
if (offset >= XCHAL_KIO_PADDR
&& offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR);
-
else
BUG();
+#else
+ return (void *)offset;
+#endif
}
static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
{
+#ifdef CONFIG_MMU
if (offset >= XCHAL_KIO_PADDR
&& offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR);
else
BUG();
+#else
+ return (void *)offset;
+#endif
}
static inline void iounmap(void *addr)
diff --git a/arch/xtensa/include/asm/irq.h b/arch/xtensa/include/asm/irq.h
index 1620d1e0e695..dfac82dc52ad 100644
--- a/arch/xtensa/include/asm/irq.h
+++ b/arch/xtensa/include/asm/irq.h
@@ -14,6 +14,13 @@
#include <platform/hardware.h>
#include <variant/core.h>
+#ifdef CONFIG_VARIANT_IRQ_SWITCH
+#include <variant/irq.h>
+#else
+static inline void variant_irq_enable(unsigned int irq) { }
+static inline void variant_irq_disable(unsigned int irq) { }
+#endif
+
#ifndef PLATFORM_NR_IRQS
# define PLATFORM_NR_IRQS 0
#endif
diff --git a/arch/xtensa/include/asm/mmu.h b/arch/xtensa/include/asm/mmu.h
index 44c5bb04c55c..04890d6e2335 100644
--- a/arch/xtensa/include/asm/mmu.h
+++ b/arch/xtensa/include/asm/mmu.h
@@ -11,7 +11,12 @@
#ifndef _XTENSA_MMU_H
#define _XTENSA_MMU_H
+#ifndef CONFIG_MMU
+#include <asm/nommu.h>
+#else
+
/* Default "unsigned long" context */
typedef unsigned long mm_context_t;
+#endif /* CONFIG_MMU */
#endif /* _XTENSA_MMU_H */
diff --git a/arch/xtensa/include/asm/mmu_context.h b/arch/xtensa/include/asm/mmu_context.h
index c0fd8e5b4513..dbd8731a876a 100644
--- a/arch/xtensa/include/asm/mmu_context.h
+++ b/arch/xtensa/include/asm/mmu_context.h
@@ -13,16 +13,20 @@
#ifndef _XTENSA_MMU_CONTEXT_H
#define _XTENSA_MMU_CONTEXT_H
+#ifndef CONFIG_MMU
+#include <asm/nommu_context.h>
+#else
+
#include <linux/stringify.h>
#include <linux/sched.h>
+#include <variant/core.h>
+
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm-generic/mm_hooks.h>
-#define XCHAL_MMU_ASID_BITS 8
-
#if (XCHAL_HAVE_TLBS != 1)
# error "Linux must have an MMU!"
#endif
@@ -133,4 +137,5 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
}
+#endif /* CONFIG_MMU */
#endif /* _XTENSA_MMU_CONTEXT_H */
diff --git a/arch/xtensa/include/asm/nommu.h b/arch/xtensa/include/asm/nommu.h
new file mode 100644
index 000000000000..dce2c438c5ba
--- /dev/null
+++ b/arch/xtensa/include/asm/nommu.h
@@ -0,0 +1,3 @@
+typedef struct {
+ unsigned long end_brk;
+} mm_context_t;
diff --git a/arch/xtensa/include/asm/nommu_context.h b/arch/xtensa/include/asm/nommu_context.h
new file mode 100644
index 000000000000..599e7a2e729d
--- /dev/null
+++ b/arch/xtensa/include/asm/nommu_context.h
@@ -0,0 +1,25 @@
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ return 0;
+}
+
+static inline void destroy_context(struct mm_struct *mm)
+{
+}
+
+static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
+{
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+ struct task_struct *tsk)
+{
+}
+
+static inline void deactivate_mm(struct task_struct *tsk, struct mm_struct *mm)
+{
+}
diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h
index 11f7dc2dbec7..17e0c5383b10 100644
--- a/arch/xtensa/include/asm/page.h
+++ b/arch/xtensa/include/asm/page.h
@@ -14,6 +14,7 @@
#include <asm/processor.h>
#include <asm/types.h>
#include <asm/cache.h>
+#include <platform/hardware.h>
/*
* Fixed TLB translations in the processor.
@@ -32,8 +33,14 @@
#define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
+#ifdef CONFIG_MMU
#define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR
#define MAX_MEM_PFN XCHAL_KSEG_SIZE
+#else
+#define PAGE_OFFSET 0
+#define MAX_MEM_PFN (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE)
+#endif
+
#define PGTABLE_START 0x80000000
/*
@@ -150,9 +157,11 @@ extern void copy_user_page(void*, void*, unsigned long, struct page*);
* addresses.
*/
+#define ARCH_PFN_OFFSET (PLATFORM_DEFAULT_MEM_START >> PAGE_SHIFT)
+
#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET))
-#define pfn_valid(pfn) ((unsigned long)pfn < max_mapnr)
+#define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
#ifdef CONFIG_DISCONTIGMEM
# error CONFIG_DISCONTIGMEM not supported
#endif
@@ -162,8 +171,9 @@ extern void copy_user_page(void*, void*, unsigned long, struct page*);
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
+#ifdef CONFIG_MMU
#define WANT_PAGE_VIRTUAL
-
+#endif
#endif /* __ASSEMBLY__ */
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h
index 8014d96b21f1..a138770c358e 100644
--- a/arch/xtensa/include/asm/pgtable.h
+++ b/arch/xtensa/include/asm/pgtable.h
@@ -183,7 +183,15 @@ extern unsigned long empty_zero_page[1024];
#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+#ifdef CONFIG_MMU
extern pgd_t swapper_pg_dir[PAGE_SIZE/sizeof(pgd_t)];
+extern void paging_init(void);
+extern void pgtable_cache_init(void);
+#else
+# define swapper_pg_dir NULL
+static inline void paging_init(void) { }
+static inline void pgtable_cache_init(void) { }
+#endif
/*
* The pmd contains the kernel virtual address of the pte page.
@@ -383,8 +391,6 @@ ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
#else
-extern void paging_init(void);
-
#define kern_addr_valid(addr) (1)
extern void update_mmu_cache(struct vm_area_struct * vma,
@@ -398,9 +404,6 @@ extern void update_mmu_cache(struct vm_area_struct * vma,
#define io_remap_pfn_range(vma,from,pfn,size,prot) \
remap_pfn_range(vma, from, pfn, size, prot)
-
-extern void pgtable_cache_init(void);
-
typedef pte_t *pte_addr_t;
#endif /* !defined (__ASSEMBLY__) */
diff --git a/arch/xtensa/include/asm/platform.h b/arch/xtensa/include/asm/platform.h
index e3d5a48ad495..7d936e58e9be 100644
--- a/arch/xtensa/include/asm/platform.h
+++ b/arch/xtensa/include/asm/platform.h
@@ -74,16 +74,5 @@ extern int platform_pcibios_fixup (void);
*/
extern void platform_calibrate_ccount (void);
-/*
- * platform_get_rtc_time returns RTC seconds (returns 0 for no error)
- */
-extern int platform_get_rtc_time(time_t*);
-
-/*
- * platform_set_rtc_time set RTC seconds (returns 0 for no error)
- */
-extern int platform_set_rtc_time(time_t);
-
-
#endif /* _XTENSA_PLATFORM_H */
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h
index 07387d3b99f4..0ea4937c0b61 100644
--- a/arch/xtensa/include/asm/processor.h
+++ b/arch/xtensa/include/asm/processor.h
@@ -13,6 +13,7 @@
#include <variant/core.h>
#include <asm/coprocessor.h>
+#include <platform/hardware.h>
#include <linux/compiler.h>
#include <asm/ptrace.h>
@@ -25,6 +26,8 @@
# error Linux requires the Xtensa Windowed Registers Option.
#endif
+#define ARCH_SLAB_MINALIGN XCHAL_DATA_WIDTH
+
/*
* User space process size: 1 GB.
* Windowed call ABI requires caller and callee to be located within the same
@@ -33,7 +36,12 @@
* the 1 GB requirement applies to the stack as well.
*/
+#ifdef CONFIG_MMU
#define TASK_SIZE __XTENSA_UL_CONST(0x40000000)
+#else
+#define TASK_SIZE (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE)
+#endif
+
#define STACK_TOP TASK_SIZE
#define STACK_TOP_MAX STACK_TOP
diff --git a/arch/xtensa/include/asm/socket.h b/arch/xtensa/include/asm/socket.h
index 6100682b1da2..dd1a7a4a1cea 100644
--- a/arch/xtensa/include/asm/socket.h
+++ b/arch/xtensa/include/asm/socket.h
@@ -65,4 +65,7 @@
#define SO_MARK 36
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
#endif /* _XTENSA_SOCKET_H */
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index a51d36a27389..80d24c485fd3 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -1463,6 +1463,7 @@ ENTRY(_spill_registers)
callx0 a0 # should not return
1: j 1b
+#ifdef CONFIG_MMU
/*
* We should never get here. Bail out!
*/
@@ -1775,7 +1776,7 @@ ENTRY(fast_store_prohibited)
bbsi.l a2, PS_UM_BIT, 1f
j _kernel_exception
1: j _user_exception
-
+#endif /* CONFIG_MMU */
/*
* System Calls.
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S
index 67e69139520b..0817f9db836e 100644
--- a/arch/xtensa/kernel/head.S
+++ b/arch/xtensa/kernel/head.S
@@ -53,7 +53,7 @@ _start: _j 2f
2: l32r a0, 1b
jx a0
- .text
+ .section .init.text, "ax"
.align 4
_startup:
@@ -235,8 +235,9 @@ should_never_return:
*/
.section ".bss.page_aligned", "w"
+#ifdef CONFIG_MMU
ENTRY(swapper_pg_dir)
.fill PAGE_SIZE, 1, 0
+#endif
ENTRY(empty_zero_page)
.fill PAGE_SIZE, 1, 0
-
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index 5fbcde59a92d..a36c85edd045 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -99,7 +99,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%10u ", kstat_irqs(i));
#else
for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
#endif
seq_printf(p, " %14s", irq_desc[i].chip->typename);
seq_printf(p, " %s", action->name);
@@ -132,6 +132,18 @@ static void xtensa_irq_unmask(unsigned int irq)
set_sr (cached_irq_mask, INTENABLE);
}
+static void xtensa_irq_enable(unsigned int irq)
+{
+ variant_irq_enable(irq);
+ xtensa_irq_unmask(irq);
+}
+
+static void xtensa_irq_disable(unsigned int irq)
+{
+ xtensa_irq_mask(irq);
+ variant_irq_disable(irq);
+}
+
static void xtensa_irq_ack(unsigned int irq)
{
set_sr(1 << irq, INTCLEAR);
@@ -146,6 +158,8 @@ static int xtensa_irq_retrigger(unsigned int irq)
static struct irq_chip xtensa_irq_chip = {
.name = "xtensa",
+ .enable = xtensa_irq_enable,
+ .disable = xtensa_irq_disable,
.mask = xtensa_irq_mask,
.unmask = xtensa_irq_unmask,
.ack = xtensa_irq_ack,
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c
index 69675f216062..1b91a97f1d84 100644
--- a/arch/xtensa/kernel/platform.c
+++ b/arch/xtensa/kernel/platform.c
@@ -36,8 +36,6 @@ _F(void, power_off, (void), { while(1); });
_F(void, idle, (void), { __asm__ __volatile__ ("waiti 0" ::: "memory"); });
_F(void, heartbeat, (void), { });
_F(int, pcibios_fixup, (void), { return 0; });
-_F(int, get_rtc_time, (time_t* t), { return 0; });
-_F(int, set_rtc_time, (time_t t), { return 0; });
#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
_F(void, calibrate_ccount, (void),
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
index 9185597eb6a0..031f36685710 100644
--- a/arch/xtensa/kernel/process.c
+++ b/arch/xtensa/kernel/process.c
@@ -172,7 +172,7 @@ void prepare_to_copy(struct task_struct *tsk)
* childregs.
*/
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 4ec1633c2941..1e5a034fe011 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -84,7 +84,13 @@ sysmem_info_t __initdata sysmem;
int initrd_is_mapped;
#endif
+#ifdef CONFIG_MMU
extern void init_mmu(void);
+#else
+static inline void init_mmu(void) { }
+#endif
+
+extern void zones_init(void);
/*
* Boot parameter parsing.
@@ -286,6 +292,7 @@ void __init setup_arch(char **cmdline_p)
paging_init();
+ zones_init();
#ifdef CONFIG_VT
# if defined(CONFIG_VGA_CONSOLE)
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index 8df1e842f6d4..8848120d291b 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -14,7 +14,7 @@
#include <linux/errno.h>
#include <linux/time.h>
-#include <linux/timex.h>
+#include <linux/clocksource.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -25,27 +25,31 @@
#include <asm/timex.h>
#include <asm/platform.h>
-
-DEFINE_SPINLOCK(rtc_lock);
-EXPORT_SYMBOL(rtc_lock);
-
-
#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
unsigned long ccount_per_jiffy; /* per 1/HZ */
unsigned long nsec_per_ccount; /* nsec per ccount increment */
#endif
-static long last_rtc_update = 0;
-
-/*
- * Scheduler clock - returns current tim in nanosec units.
- */
-
-unsigned long long sched_clock(void)
+static cycle_t ccount_read(void)
{
- return (unsigned long long)jiffies * (1000000000 / HZ);
+ return (cycle_t)get_ccount();
}
+static struct clocksource ccount_clocksource = {
+ .name = "ccount",
+ .rating = 200,
+ .read = ccount_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ /*
+ * With a shift of 22 the lower limit of the cpu clock is
+ * 1MHz, where NSEC_PER_CCOUNT is 1000 or a bit less than
+ * 2^10: Since we have 32 bits and the multiplicator can
+ * already take up as much as 10 bits, this leaves us with
+ * remaining upper 22 bits.
+ */
+ .shift = 22,
+};
+
static irqreturn_t timer_interrupt(int irq, void *dev_id);
static struct irqaction timer_irqaction = {
.handler = timer_interrupt,
@@ -55,11 +59,11 @@ static struct irqaction timer_irqaction = {
void __init time_init(void)
{
- time_t sec_o, sec_n = 0;
+ xtime.tv_nsec = 0;
+ xtime.tv_sec = read_persistent_clock();
- /* The platform must provide a function to calibrate the processor
- * speed for the CALIBRATE.
- */
+ set_normalized_timespec(&wall_to_monotonic,
+ -xtime.tv_sec, -xtime.tv_nsec);
#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
printk("Calibrating CPU frequency ");
@@ -67,19 +71,10 @@ void __init time_init(void)
printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ),
(int)(ccount_per_jiffy/(10000/HZ))%100);
#endif
-
- /* Set time from RTC (if provided) */
-
- if (platform_get_rtc_time(&sec_o) == 0)
- while (platform_get_rtc_time(&sec_n))
- if (sec_o != sec_n)
- break;
-
- xtime.tv_nsec = 0;
- last_rtc_update = xtime.tv_sec = sec_n;
-
- set_normalized_timespec(&wall_to_monotonic,
- -xtime.tv_sec, -xtime.tv_nsec);
+ ccount_clocksource.mult =
+ clocksource_hz2mult(CCOUNT_PER_JIFFY * HZ,
+ ccount_clocksource.shift);
+ clocksource_register(&ccount_clocksource);
/* Initialize the linux timer interrupt. */
@@ -87,69 +82,6 @@ void __init time_init(void)
set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY);
}
-
-int do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
- unsigned long delta;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
-
- /* This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * made, and then undo it!
- */
-
- delta = CCOUNT_PER_JIFFY;
- delta += get_ccount() - get_linux_timer();
- nsec -= delta * NSEC_PER_CCOUNT;
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
-
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
- unsigned long volatile sec, usec, delta, seq;
-
- do {
- seq = read_seqbegin_irqsave(&xtime_lock, flags);
-
- sec = xtime.tv_sec;
- usec = (xtime.tv_nsec / NSEC_PER_USEC);
-
- delta = get_linux_timer() - get_ccount();
-
- } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-
- usec += (((unsigned long) CCOUNT_PER_JIFFY - delta)
- * (unsigned long) NSEC_PER_CCOUNT) / NSEC_PER_USEC;
-
- for (; usec >= 1000000; sec++, usec -= 1000000)
- ;
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
/*
* The timer interrupt is called HZ times per second.
*/
@@ -178,16 +110,6 @@ again:
next += CCOUNT_PER_JIFFY;
set_linux_timer(next);
- if (ntp_synced() &&
- xtime.tv_sec - last_rtc_update >= 659 &&
- abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ) {
-
- if (platform_set_rtc_time(xtime.tv_sec+1) == 0)
- last_rtc_update = xtime.tv_sec+1;
- else
- /* Do it again in 60 s */
- last_rtc_update += 60;
- }
write_sequnlock(&xtime_lock);
}
@@ -213,4 +135,3 @@ void __cpuinit calibrate_delay(void)
(loops_per_jiffy/(10000/HZ)) % 100);
}
#endif
-
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index c44f830b6c7a..9f0b71189e94 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -104,6 +104,7 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
#endif
{ EXCCAUSE_UNALIGNED, KRNL, fast_unaligned },
#endif
+#ifdef CONFIG_MMU
{ EXCCAUSE_ITLB_MISS, 0, do_page_fault },
{ EXCCAUSE_ITLB_MISS, USER|KRNL, fast_second_level_miss},
{ EXCCAUSE_ITLB_MULTIHIT, 0, do_multihit },
@@ -118,6 +119,7 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = {
{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, USER|KRNL, fast_store_prohibited },
{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault },
{ EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault },
+#endif /* CONFIG_MMU */
/* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */
#if XTENSA_HAVE_COPROCESSOR(0)
COPROCESSOR(0),
@@ -372,11 +374,10 @@ void show_trace(struct task_struct *task, unsigned long *sp)
unsigned long a0, a1, pc;
unsigned long sp_start, sp_end;
- a1 = (unsigned long)sp;
-
- if (a1 == 0)
- __asm__ __volatile__ ("mov %0, a1\n" : "=a"(a1));
-
+ if (sp)
+ a1 = (unsigned long)sp;
+ else
+ a1 = task->thread.sp;
sp_start = a1 & ~(THREAD_SIZE-1);
sp_end = sp_start + THREAD_SIZE;
@@ -418,9 +419,8 @@ void show_stack(struct task_struct *task, unsigned long *sp)
int i = 0;
unsigned long *stack;
- if (sp == 0)
- __asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp));
-
+ if (!sp)
+ sp = (unsigned long *)task->thread.sp;
stack = sp;
printk("\nStack: ");
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
index eb2d7bb69ee0..74a7518faf16 100644
--- a/arch/xtensa/kernel/vectors.S
+++ b/arch/xtensa/kernel/vectors.S
@@ -309,6 +309,7 @@ ENTRY(_DoubleExceptionVector)
* All other exceptions are unexpected and thus unrecoverable!
*/
+#ifdef CONFIG_MMU
.extern fast_second_level_miss_double_kernel
.Lksp: /* a0: a0, a1: a1, a2: a2, a3: trashed, depc: depc, excsave: a3 */
@@ -319,6 +320,9 @@ ENTRY(_DoubleExceptionVector)
bnez a3, .Lunrecoverable
1: movi a3, fast_second_level_miss_double_kernel
jx a3
+#else
+.equ .Lksp, .Lunrecoverable
+#endif
/* Critical! We can't handle this situation. PANIC! */
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index d506774f4b05..c1be9a4a740c 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -17,6 +17,7 @@
#include <asm-generic/vmlinux.lds.h>
#include <variant/core.h>
+#include <platform/hardware.h>
OUTPUT_ARCH(xtensa)
ENTRY(_start)
@@ -26,7 +27,9 @@ jiffies = jiffies_64 + 4;
jiffies = jiffies_64;
#endif
+#ifndef KERNELOFFSET
#define KERNELOFFSET 0xd0001000
+#endif
/* Note: In the following macros, it would be nice to specify only the
vector name and section kind and construct "sym" and "section" using
diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile
index 64e304a2f884..f0b646d2f843 100644
--- a/arch/xtensa/mm/Makefile
+++ b/arch/xtensa/mm/Makefile
@@ -2,4 +2,5 @@
# Makefile for the Linux/Xtensa-specific parts of the memory manager.
#
-obj-y := init.o fault.o tlb.o misc.o cache.o
+obj-y := init.o cache.o misc.o
+obj-$(CONFIG_MMU) += fault.o mmu.o tlb.o
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
index 34163cfaaffc..427e14fa43c5 100644
--- a/arch/xtensa/mm/init.c
+++ b/arch/xtensa/mm/init.c
@@ -24,15 +24,8 @@
#include <linux/mm.h>
#include <linux/slab.h>
-#include <asm/pgtable.h>
#include <asm/bootparam.h>
-#include <asm/mmu_context.h>
-#include <asm/tlb.h>
#include <asm/page.h>
-#include <asm/pgalloc.h>
-
-
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
/* References to section boundaries */
@@ -130,7 +123,8 @@ void __init bootmem_init(void)
/* Find an area to use for the bootmem bitmap. */
- bootmap_size = bootmem_bootmap_pages(max_low_pfn) << PAGE_SHIFT;
+ bootmap_size = bootmem_bootmap_pages(max_low_pfn - min_low_pfn);
+ bootmap_size <<= PAGE_SHIFT;
bootmap_start = ~0;
for (i=0; i<sysmem.nr_banks; i++)
@@ -145,8 +139,9 @@ void __init bootmem_init(void)
/* Reserve the bootmem bitmap area */
mem_reserve(bootmap_start, bootmap_start + bootmap_size, 1);
- bootmap_size = init_bootmem_node(NODE_DATA(0), min_low_pfn,
+ bootmap_size = init_bootmem_node(NODE_DATA(0),
bootmap_start >> PAGE_SHIFT,
+ min_low_pfn,
max_low_pfn);
/* Add all remaining memory pieces into the bootmem map */
@@ -158,14 +153,14 @@ void __init bootmem_init(void)
}
-void __init paging_init(void)
+void __init zones_init(void)
{
unsigned long zones_size[MAX_NR_ZONES];
int i;
/* All pages are DMA-able, so we put them all in the DMA zone. */
- zones_size[ZONE_DMA] = max_low_pfn;
+ zones_size[ZONE_DMA] = max_low_pfn - ARCH_PFN_OFFSET;
for (i = 1; i < MAX_NR_ZONES; i++)
zones_size[i] = 0;
@@ -173,40 +168,7 @@ void __init paging_init(void)
zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
#endif
- /* Initialize the kernel's page tables. */
-
- memset(swapper_pg_dir, 0, PAGE_SIZE);
-
- free_area_init(zones_size);
-}
-
-/*
- * Flush the mmu and reset associated register to default values.
- */
-
-void __init init_mmu (void)
-{
- /* Writing zeros to the <t>TLBCFG special registers ensure
- * that valid values exist in the register. For existing
- * PGSZID<w> fields, zero selects the first element of the
- * page-size array. For nonexistent PGSZID<w> fields, zero is
- * the best value to write. Also, when changing PGSZID<w>
- * fields, the corresponding TLB must be flushed.
- */
- set_itlbcfg_register (0);
- set_dtlbcfg_register (0);
- flush_tlb_all ();
-
- /* Set rasid register to a known value. */
-
- set_rasid_register (ASID_USER_FIRST);
-
- /* Set PTEVADDR special register to the start of the page
- * table, which is in kernel mappable space (ie. not
- * statically mapped). This register's value is undefined on
- * reset.
- */
- set_ptevaddr_register (PGTABLE_START);
+ free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL);
}
/*
@@ -218,8 +180,8 @@ void __init mem_init(void)
unsigned long codesize, reservedpages, datasize, initsize;
unsigned long highmemsize, tmp, ram;
- max_mapnr = num_physpages = max_low_pfn;
- high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
+ max_mapnr = num_physpages = max_low_pfn - ARCH_PFN_OFFSET;
+ high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
highmemsize = 0;
#ifdef CONFIG_HIGHMEM
@@ -229,7 +191,7 @@ void __init mem_init(void)
totalram_pages += free_all_bootmem();
reservedpages = ram = 0;
- for (tmp = 0; tmp < max_low_pfn; tmp++) {
+ for (tmp = 0; tmp < max_mapnr; tmp++) {
ram++;
if (PageReserved(mem_map+tmp))
reservedpages++;
@@ -279,23 +241,3 @@ void free_initmem(void)
printk("Freeing unused kernel memory: %dk freed\n",
(&__init_end - &__init_begin) >> 10);
}
-
-struct kmem_cache *pgtable_cache __read_mostly;
-
-static void pgd_ctor(void* addr)
-{
- pte_t* ptep = (pte_t*)addr;
- int i;
-
- for (i = 0; i < 1024; i++, ptep++)
- pte_clear(NULL, 0, ptep);
-
-}
-
-void __init pgtable_cache_init(void)
-{
- pgtable_cache = kmem_cache_create("pgd",
- PAGE_SIZE, PAGE_SIZE,
- SLAB_HWCACHE_ALIGN,
- pgd_ctor);
-}
diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S
index c885664211d1..b048406d8756 100644
--- a/arch/xtensa/mm/misc.S
+++ b/arch/xtensa/mm/misc.S
@@ -84,6 +84,7 @@ ENTRY(copy_page)
retw
+#ifdef CONFIG_MMU
/*
* If we have to deal with cache aliasing, we use temporary memory mappings
* to ensure that the source and destination pages have the same color as
@@ -311,6 +312,7 @@ ENTRY(__invalidate_icache_page_alias)
/* End of special treatment in tlb miss exception */
ENTRY(__tlbtemp_mapping_end)
+#endif /* CONFIG_MMU
/*
* void __invalidate_icache_page(ulong start)
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c
new file mode 100644
index 000000000000..4bb91a970f1f
--- /dev/null
+++ b/arch/xtensa/mm/mmu.c
@@ -0,0 +1,70 @@
+/*
+ * xtensa mmu stuff
+ *
+ * Extracted from init.c
+ */
+#include <linux/percpu.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/cache.h>
+
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+#include <asm/page.h>
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+void __init paging_init(void)
+{
+ memset(swapper_pg_dir, 0, PAGE_SIZE);
+}
+
+/*
+ * Flush the mmu and reset associated register to default values.
+ */
+void __init init_mmu(void)
+{
+ /* Writing zeros to the <t>TLBCFG special registers ensure
+ * that valid values exist in the register. For existing
+ * PGSZID<w> fields, zero selects the first element of the
+ * page-size array. For nonexistent PGSZID<w> fields, zero is
+ * the best value to write. Also, when changing PGSZID<w>
+ * fields, the corresponding TLB must be flushed.
+ */
+ set_itlbcfg_register(0);
+ set_dtlbcfg_register(0);
+ flush_tlb_all();
+
+ /* Set rasid register to a known value. */
+
+ set_rasid_register(ASID_USER_FIRST);
+
+ /* Set PTEVADDR special register to the start of the page
+ * table, which is in kernel mappable space (ie. not
+ * statically mapped). This register's value is undefined on
+ * reset.
+ */
+ set_ptevaddr_register(PGTABLE_START);
+}
+
+struct kmem_cache *pgtable_cache __read_mostly;
+
+static void pgd_ctor(void *addr)
+{
+ pte_t *ptep = (pte_t *)addr;
+ int i;
+
+ for (i = 0; i < 1024; i++, ptep++)
+ pte_clear(NULL, 0, ptep);
+
+}
+
+void __init pgtable_cache_init(void)
+{
+ pgtable_cache = kmem_cache_create("pgd",
+ PAGE_SIZE, PAGE_SIZE,
+ SLAB_HWCACHE_ALIGN,
+ pgd_ctor);
+}
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
index 25d46c84eb08..4c559cf7da2d 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -18,6 +18,7 @@
#include <linux/mm.h>
#include <linux/major.h>
#include <linux/param.h>
+#include <linux/seq_file.h>
#include <linux/serial.h>
#include <linux/serialP.h>
@@ -176,22 +177,24 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
/* Stub, once again.. */
}
-static int rs_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int rs_proc_show(struct seq_file *m, void *v)
{
- int len = 0;
- off_t begin = 0;
-
- len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
- *eof = 1;
-
- if (off >= len + begin)
- return 0;
+ seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version);
+ return 0;
+}
- *start = page + (off - begin);
- return ((count < begin + len - off) ? count : begin + len - off);
+static int rs_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, rs_proc_show, NULL);
}
+static const struct file_operations rs_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = rs_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
static struct tty_operations serial_ops = {
.open = rs_open,
@@ -203,7 +206,7 @@ static struct tty_operations serial_ops = {
.chars_in_buffer = rs_chars_in_buffer,
.hangup = rs_hangup,
.wait_until_sent = rs_wait_until_sent,
- .read_proc = rs_read_proc
+ .proc_fops = &rs_proc_fops,
};
int __init rs_init(void)
diff --git a/arch/xtensa/platforms/s6105/Makefile b/arch/xtensa/platforms/s6105/Makefile
new file mode 100644
index 000000000000..0be6194bcb72
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/Makefile
@@ -0,0 +1,3 @@
+# Makefile for the Stretch S6105 eval board
+
+obj-y := setup.o device.o
diff --git a/arch/xtensa/platforms/s6105/device.c b/arch/xtensa/platforms/s6105/device.c
new file mode 100644
index 000000000000..78b08be5a92d
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/device.c
@@ -0,0 +1,67 @@
+/*
+ * s6105 platform devices
+ *
+ * Copyright (c) 2009 emlix GmbH
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+
+#include <variant/hardware.h>
+
+#define UART_INTNUM 4
+
+static const signed char uart_irq_mappings[] = {
+ S6_INTC_UART(0),
+ S6_INTC_UART(1),
+ -1,
+};
+
+const signed char *platform_irq_mappings[NR_IRQS] = {
+ [UART_INTNUM] = uart_irq_mappings,
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .membase = (void *)S6_REG_UART + 0x0000,
+ .mapbase = S6_REG_UART + 0x0000,
+ .irq = UART_INTNUM,
+ .uartclk = S6_SCLK,
+ .regshift = 2,
+ .iotype = SERIAL_IO_MEM,
+ .flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST,
+ },
+ {
+ .membase = (void *)S6_REG_UART + 0x1000,
+ .mapbase = S6_REG_UART + 0x1000,
+ .irq = UART_INTNUM,
+ .uartclk = S6_SCLK,
+ .regshift = 2,
+ .iotype = SERIAL_IO_MEM,
+ .flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST,
+ },
+ { },
+};
+
+static struct platform_device platform_devices[] = {
+ {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+ },
+};
+
+static int __init device_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(platform_devices); i++)
+ platform_device_register(&platform_devices[i]);
+ return 0;
+}
+arch_initcall_sync(device_init);
diff --git a/arch/xtensa/platforms/s6105/include/platform/gpio.h b/arch/xtensa/platforms/s6105/include/platform/gpio.h
new file mode 100644
index 000000000000..fa11aa4b61e9
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/include/platform/gpio.h
@@ -0,0 +1,27 @@
+#ifndef __ASM_XTENSA_S6105_GPIO_H
+#define __ASM_XTENSA_S6105_GPIO_H
+
+#define GPIO_BP_TEMP_ALARM 0
+#define GPIO_PB_RESET_IN 1
+#define GPIO_EXP_IRQ 2
+#define GPIO_TRIGGER_IRQ 3
+#define GPIO_RTC_IRQ 4
+#define GPIO_PHY_IRQ 5
+#define GPIO_IMAGER_RESET 6
+#define GPIO_SD_IRQ 7
+#define GPIO_MINI_BOOT_INH 8
+#define GPIO_BOARD_RESET 9
+#define GPIO_EXP_PRESENT 10
+#define GPIO_LED1_NGREEN 12
+#define GPIO_LED1_RED 13
+#define GPIO_LED0_NGREEN 14
+#define GPIO_LED0_NRED 15
+#define GPIO_SPI_CS0 16
+#define GPIO_SPI_CS1 17
+#define GPIO_SPI_CS3 19
+#define GPIO_SPI_CS4 20
+#define GPIO_SD_WP 21
+#define GPIO_BP_RESET 22
+#define GPIO_ALARM_OUT 23
+
+#endif /* __ASM_XTENSA_S6105_GPIO_H */
diff --git a/arch/xtensa/platforms/s6105/include/platform/hardware.h b/arch/xtensa/platforms/s6105/include/platform/hardware.h
new file mode 100644
index 000000000000..d628efac7089
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/include/platform/hardware.h
@@ -0,0 +1,11 @@
+#ifndef __XTENSA_S6105_HARDWARE_H
+#define __XTENSA_S6105_HARDWARE_H
+
+#define PLATFORM_DEFAULT_MEM_START 0x40000000
+#define PLATFORM_DEFAULT_MEM_SIZE 0x08000000
+
+#define MAX_DMA_ADDRESS 0
+
+#define KERNELOFFSET (PLATFORM_DEFAULT_MEM_START + 0x1000)
+
+#endif /* __XTENSA_S6105_HARDWARE_H */
diff --git a/arch/xtensa/platforms/s6105/include/platform/serial.h b/arch/xtensa/platforms/s6105/include/platform/serial.h
new file mode 100644
index 000000000000..c8a771e5981b
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/include/platform/serial.h
@@ -0,0 +1,8 @@
+#ifndef __ASM_XTENSA_S6105_SERIAL_H
+#define __ASM_XTENSA_S6105_SERIAL_H
+
+#include <variant/hardware.h>
+
+#define BASE_BAUD (S6_SCLK / 16)
+
+#endif /* __ASM_XTENSA_S6105_SERIAL_H */
diff --git a/arch/xtensa/platforms/s6105/setup.c b/arch/xtensa/platforms/s6105/setup.c
new file mode 100644
index 000000000000..ae041d5027a2
--- /dev/null
+++ b/arch/xtensa/platforms/s6105/setup.c
@@ -0,0 +1,61 @@
+/*
+ * s6105 control routines
+ *
+ * Copyright (c) 2009 emlix GmbH
+ */
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/bootparam.h>
+
+#include <variant/hardware.h>
+#include <platform/gpio.h>
+
+void platform_halt(void)
+{
+ local_irq_disable();
+ while (1)
+ ;
+}
+
+void platform_power_off(void)
+{
+ platform_halt();
+}
+
+void platform_restart(void)
+{
+ platform_halt();
+}
+
+void __init platform_setup(char **cmdline)
+{
+ unsigned long reg;
+
+ reg = readl(S6_REG_GREG1 + S6_GREG1_CLKGATE);
+ reg &= ~(1 << S6_GREG1_BLOCK_SB);
+ writel(reg, S6_REG_GREG1 + S6_GREG1_CLKGATE);
+
+ reg = readl(S6_REG_GREG1 + S6_GREG1_BLOCKENA);
+ reg |= 1 << S6_GREG1_BLOCK_SB;
+ writel(reg, S6_REG_GREG1 + S6_GREG1_BLOCKENA);
+
+ printk(KERN_NOTICE "S6105 on Stretch S6000 - "
+ "Copyright (C) 2009 emlix GmbH <info@emlix.com>\n");
+}
+
+void __init platform_init(bp_tag_t *first)
+{
+ gpio_request(GPIO_LED1_NGREEN, "led1_green");
+ gpio_request(GPIO_LED1_RED, "led1_red");
+ gpio_direction_output(GPIO_LED1_NGREEN, 1);
+}
+
+void platform_heartbeat(void)
+{
+ static unsigned int c;
+
+ if (!(++c & 0x4F))
+ gpio_direction_output(GPIO_LED1_RED, !(c & 0x10));
+}
diff --git a/arch/xtensa/platforms/xt2000/include/platform/hardware.h b/arch/xtensa/platforms/xt2000/include/platform/hardware.h
index 41459ad07766..886ef156ded3 100644
--- a/arch/xtensa/platforms/xt2000/include/platform/hardware.h
+++ b/arch/xtensa/platforms/xt2000/include/platform/hardware.h
@@ -16,7 +16,6 @@
#define _XTENSA_XT2000_HARDWARE_H
#include <variant/core.h>
-#include <asm/io.h>
/*
* Memory configuration.
diff --git a/arch/xtensa/variants/s6000/Makefile b/arch/xtensa/variants/s6000/Makefile
new file mode 100644
index 000000000000..03b3975468bd
--- /dev/null
+++ b/arch/xtensa/variants/s6000/Makefile
@@ -0,0 +1,3 @@
+# s6000 Makefile
+
+obj-y += irq.o gpio.o
diff --git a/arch/xtensa/variants/s6000/gpio.c b/arch/xtensa/variants/s6000/gpio.c
new file mode 100644
index 000000000000..33a8d952934c
--- /dev/null
+++ b/arch/xtensa/variants/s6000/gpio.c
@@ -0,0 +1,71 @@
+/*
+ * s6000 gpio driver
+ *
+ * Copyright (c) 2009 emlix GmbH
+ * Authors: Oskar Schirmer <os@emlix.com>
+ * Johannes Weiner <jw@emlix.com>
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <variant/hardware.h>
+
+#define S6_GPIO_DATA 0x000
+#define S6_GPIO_IS 0x404
+#define S6_GPIO_IBE 0x408
+#define S6_GPIO_IEV 0x40C
+#define S6_GPIO_IE 0x410
+#define S6_GPIO_RIS 0x414
+#define S6_GPIO_MIS 0x418
+#define S6_GPIO_IC 0x41C
+#define S6_GPIO_AFSEL 0x420
+#define S6_GPIO_DIR 0x800
+#define S6_GPIO_BANK(nr) ((nr) * 0x1000)
+#define S6_GPIO_MASK(nr) (4 << (nr))
+#define S6_GPIO_OFFSET(nr) \
+ (S6_GPIO_BANK((nr) >> 3) + S6_GPIO_MASK((nr) & 7))
+
+static int direction_input(struct gpio_chip *chip, unsigned int off)
+{
+ writeb(0, S6_REG_GPIO + S6_GPIO_DIR + S6_GPIO_OFFSET(off));
+ return 0;
+}
+
+static int get(struct gpio_chip *chip, unsigned int off)
+{
+ return readb(S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off));
+}
+
+static int direction_output(struct gpio_chip *chip, unsigned int off, int val)
+{
+ unsigned rel = S6_GPIO_OFFSET(off);
+ writeb(~0, S6_REG_GPIO + S6_GPIO_DIR + rel);
+ writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + rel);
+ return 0;
+}
+
+static void set(struct gpio_chip *chip, unsigned int off, int val)
+{
+ writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off));
+}
+
+static struct gpio_chip gpiochip = {
+ .owner = THIS_MODULE,
+ .direction_input = direction_input,
+ .get = get,
+ .direction_output = direction_output,
+ .set = set,
+ .base = 0,
+ .ngpio = 24,
+ .can_sleep = 0, /* no blocking io needed */
+ .exported = 0, /* no exporting to userspace */
+};
+
+static int gpio_init(void)
+{
+ return gpiochip_add(&gpiochip);
+}
+device_initcall(gpio_init);
diff --git a/arch/xtensa/variants/s6000/include/variant/core.h b/arch/xtensa/variants/s6000/include/variant/core.h
new file mode 100644
index 000000000000..af007953027e
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/core.h
@@ -0,0 +1,431 @@
+/*
+ * Xtensa processor core configuration information.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 1999-2008 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_CONFIGURATION_H
+#define _XTENSA_CORE_CONFIGURATION_H
+
+
+/****************************************************************************
+ Parameters Useful for Any Code, USER or PRIVILEGED
+ ****************************************************************************/
+
+/*
+ * Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is
+ * configured, and a value of 0 otherwise. These macros are always defined.
+ */
+
+
+/*----------------------------------------------------------------------
+ ISA
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_BE 0 /* big-endian byte ordering */
+#define XCHAL_HAVE_WINDOWED 1 /* windowed registers option */
+#define XCHAL_NUM_AREGS 64 /* num of physical addr regs */
+#define XCHAL_NUM_AREGS_LOG2 6 /* log2(XCHAL_NUM_AREGS) */
+#define XCHAL_MAX_INSTRUCTION_SIZE 8 /* max instr bytes (3..8) */
+#define XCHAL_HAVE_DEBUG 1 /* debug option */
+#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */
+#define XCHAL_HAVE_LOOPS 1 /* zero-overhead loops */
+#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */
+#define XCHAL_HAVE_MINMAX 1 /* MIN/MAX instructions */
+#define XCHAL_HAVE_SEXT 1 /* SEXT instruction */
+#define XCHAL_HAVE_CLAMPS 1 /* CLAMPS instruction */
+#define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */
+#define XCHAL_HAVE_MUL32 1 /* MULL instruction */
+#define XCHAL_HAVE_MUL32_HIGH 1 /* MULUH/MULSH instructions */
+#define XCHAL_HAVE_DIV32 0 /* QUOS/QUOU/REMS/REMU instructions */
+#define XCHAL_HAVE_L32R 1 /* L32R instruction */
+#define XCHAL_HAVE_ABSOLUTE_LITERALS 1 /* non-PC-rel (extended) L32R */
+#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */
+#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */
+#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */
+#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */
+#define XCHAL_HAVE_CALL4AND12 1 /* (obsolete option) */
+#define XCHAL_HAVE_ABS 1 /* ABS instruction */
+/*#define XCHAL_HAVE_POPC 0*/ /* POPC instruction */
+/*#define XCHAL_HAVE_CRC 0*/ /* CRC instruction */
+#define XCHAL_HAVE_RELEASE_SYNC 0 /* L32AI/S32RI instructions */
+#define XCHAL_HAVE_S32C1I 0 /* S32C1I instruction */
+#define XCHAL_HAVE_SPECULATION 0 /* speculation */
+#define XCHAL_HAVE_FULL_RESET 0 /* all regs/state reset */
+#define XCHAL_NUM_CONTEXTS 1 /* */
+#define XCHAL_NUM_MISC_REGS 4 /* num of scratch regs (0..4) */
+#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */
+#define XCHAL_HAVE_PRID 0 /* processor ID register */
+#define XCHAL_HAVE_THREADPTR 0 /* THREADPTR register */
+#define XCHAL_HAVE_BOOLEANS 1 /* boolean registers */
+#define XCHAL_HAVE_CP 1 /* CPENABLE reg (coprocessor) */
+#define XCHAL_CP_MAXCFG 8 /* max allowed cp id plus one */
+#define XCHAL_HAVE_MAC16 0 /* MAC16 package */
+#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */
+#define XCHAL_HAVE_FP 1 /* floating point pkg */
+#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */
+#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */
+#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */
+
+
+/*----------------------------------------------------------------------
+ MISC
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_WRITEBUFFER_ENTRIES 8 /* size of write buffer */
+#define XCHAL_INST_FETCH_WIDTH 8 /* instr-fetch width in bytes */
+#define XCHAL_DATA_WIDTH 16 /* data width in bytes */
+/* In T1050, applies to selected core load and store instructions (see ISA): */
+#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */
+#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/
+
+#define XCHAL_SW_VERSION 701001 /* sw version of this header */
+
+#define XCHAL_CORE_ID "stretch_bali" /* alphanum core name
+ (CoreID) set in the Xtensa
+ Processor Generator */
+
+#define XCHAL_BUILD_UNIQUE_ID 0x000104B9 /* 22-bit sw build ID */
+
+/*
+ * These definitions describe the hardware targeted by this software.
+ */
+#define XCHAL_HW_CONFIGID0 0xC2F3F9FE /* ConfigID hi 32 bits*/
+#define XCHAL_HW_CONFIGID1 0x054104B9 /* ConfigID lo 32 bits*/
+#define XCHAL_HW_VERSION_NAME "LX1.0.2" /* full version name */
+#define XCHAL_HW_VERSION_MAJOR 2100 /* major ver# of targeted hw */
+#define XCHAL_HW_VERSION_MINOR 2 /* minor ver# of targeted hw */
+#define XCHAL_HW_VERSION 210002 /* major*100+minor */
+#define XCHAL_HW_REL_LX1 1
+#define XCHAL_HW_REL_LX1_0 1
+#define XCHAL_HW_REL_LX1_0_2 1
+#define XCHAL_HW_CONFIGID_RELIABLE 1
+/* If software targets a *range* of hardware versions, these are the bounds: */
+#define XCHAL_HW_MIN_VERSION_MAJOR 2100 /* major v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION_MINOR 2 /* minor v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION 210002 /* earliest targeted hw */
+#define XCHAL_HW_MAX_VERSION_MAJOR 2100 /* major v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION_MINOR 2 /* minor v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION 210002 /* latest targeted hw */
+
+
+/*----------------------------------------------------------------------
+ CACHE
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_ICACHE_LINESIZE 16 /* I-cache line size in bytes */
+#define XCHAL_DCACHE_LINESIZE 16 /* D-cache line size in bytes */
+#define XCHAL_ICACHE_LINEWIDTH 4 /* log2(I line size in bytes) */
+#define XCHAL_DCACHE_LINEWIDTH 4 /* log2(D line size in bytes) */
+
+#define XCHAL_ICACHE_SIZE 32768 /* I-cache size in bytes or 0 */
+#define XCHAL_DCACHE_SIZE 32768 /* D-cache size in bytes or 0 */
+
+#define XCHAL_DCACHE_IS_WRITEBACK 1 /* writeback feature */
+
+
+
+
+/****************************************************************************
+ Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code
+ ****************************************************************************/
+
+
+#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY
+
+/*----------------------------------------------------------------------
+ CACHE
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_PIF 1 /* any outbound PIF present */
+
+/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */
+
+/* Number of cache sets in log2(lines per way): */
+#define XCHAL_ICACHE_SETWIDTH 9
+#define XCHAL_DCACHE_SETWIDTH 10
+
+/* Cache set associativity (number of ways): */
+#define XCHAL_ICACHE_WAYS 4
+#define XCHAL_DCACHE_WAYS 2
+
+/* Cache features: */
+#define XCHAL_ICACHE_LINE_LOCKABLE 1
+#define XCHAL_DCACHE_LINE_LOCKABLE 0
+#define XCHAL_ICACHE_ECC_PARITY 0
+#define XCHAL_DCACHE_ECC_PARITY 0
+
+/* Number of encoded cache attr bits (see <xtensa/hal.h> for decoded bits): */
+#define XCHAL_CA_BITS 4
+
+
+/*----------------------------------------------------------------------
+ INTERNAL I/D RAM/ROMs and XLMI
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_INSTROM 0 /* number of core instr. ROMs */
+#define XCHAL_NUM_INSTRAM 0 /* number of core instr. RAMs */
+#define XCHAL_NUM_DATAROM 0 /* number of core data ROMs */
+#define XCHAL_NUM_DATARAM 1 /* number of core data RAMs */
+#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/
+#define XCHAL_NUM_XLMI 1 /* number of core XLMI ports */
+
+/* Data RAM 0: */
+#define XCHAL_DATARAM0_VADDR 0x3FFF0000
+#define XCHAL_DATARAM0_PADDR 0x3FFF0000
+#define XCHAL_DATARAM0_SIZE 65536
+#define XCHAL_DATARAM0_ECC_PARITY 0
+
+/* XLMI Port 0: */
+#define XCHAL_XLMI0_VADDR 0x37F80000
+#define XCHAL_XLMI0_PADDR 0x37F80000
+#define XCHAL_XLMI0_SIZE 262144
+#define XCHAL_XLMI0_ECC_PARITY 0
+
+
+/*----------------------------------------------------------------------
+ INTERRUPTS and TIMERS
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */
+#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */
+#define XCHAL_HAVE_NMI 1 /* non-maskable interrupt */
+#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */
+#define XCHAL_NUM_TIMERS 3 /* number of CCOMPAREn regs */
+#define XCHAL_NUM_INTERRUPTS 27 /* number of interrupts */
+#define XCHAL_NUM_INTERRUPTS_LOG2 5 /* ceil(log2(NUM_INTERRUPTS)) */
+#define XCHAL_NUM_EXTINTERRUPTS 20 /* num of external interrupts */
+#define XCHAL_NUM_INTLEVELS 4 /* number of interrupt levels
+ (not including level zero) */
+#define XCHAL_EXCM_LEVEL 1 /* level masked by PS.EXCM */
+ /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */
+
+/* Masks of interrupts at each interrupt level: */
+#define XCHAL_INTLEVEL1_MASK 0x01F07FFF
+#define XCHAL_INTLEVEL2_MASK 0x02018000
+#define XCHAL_INTLEVEL3_MASK 0x04060000
+#define XCHAL_INTLEVEL4_MASK 0x00000000
+#define XCHAL_INTLEVEL5_MASK 0x00080000
+#define XCHAL_INTLEVEL6_MASK 0x00000000
+#define XCHAL_INTLEVEL7_MASK 0x00000000
+
+/* Masks of interrupts at each range 1..n of interrupt levels: */
+#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x01F07FFF
+#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x03F1FFFF
+#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x07F7FFFF
+#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x07F7FFFF
+#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x07FFFFFF
+#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x07FFFFFF
+#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x07FFFFFF
+
+/* Level of each interrupt: */
+#define XCHAL_INT0_LEVEL 1
+#define XCHAL_INT1_LEVEL 1
+#define XCHAL_INT2_LEVEL 1
+#define XCHAL_INT3_LEVEL 1
+#define XCHAL_INT4_LEVEL 1
+#define XCHAL_INT5_LEVEL 1
+#define XCHAL_INT6_LEVEL 1
+#define XCHAL_INT7_LEVEL 1
+#define XCHAL_INT8_LEVEL 1
+#define XCHAL_INT9_LEVEL 1
+#define XCHAL_INT10_LEVEL 1
+#define XCHAL_INT11_LEVEL 1
+#define XCHAL_INT12_LEVEL 1
+#define XCHAL_INT13_LEVEL 1
+#define XCHAL_INT14_LEVEL 1
+#define XCHAL_INT15_LEVEL 2
+#define XCHAL_INT16_LEVEL 2
+#define XCHAL_INT17_LEVEL 3
+#define XCHAL_INT18_LEVEL 3
+#define XCHAL_INT19_LEVEL 5
+#define XCHAL_INT20_LEVEL 1
+#define XCHAL_INT21_LEVEL 1
+#define XCHAL_INT22_LEVEL 1
+#define XCHAL_INT23_LEVEL 1
+#define XCHAL_INT24_LEVEL 1
+#define XCHAL_INT25_LEVEL 2
+#define XCHAL_INT26_LEVEL 3
+#define XCHAL_DEBUGLEVEL 4 /* debug interrupt level */
+#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */
+#define XCHAL_NMILEVEL 5 /* NMI "level" (for use with
+ EXCSAVE/EPS/EPC_n, RFI n) */
+
+/* Type of each interrupt: */
+#define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT6_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT7_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT10_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT11_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT12_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT13_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT14_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT15_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT16_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT17_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT18_TYPE XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT19_TYPE XTHAL_INTTYPE_NMI
+#define XCHAL_INT20_TYPE XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT21_TYPE XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT22_TYPE XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT23_TYPE XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT24_TYPE XTHAL_INTTYPE_TIMER
+#define XCHAL_INT25_TYPE XTHAL_INTTYPE_TIMER
+#define XCHAL_INT26_TYPE XTHAL_INTTYPE_TIMER
+
+/* Masks of interrupts for each type of interrupt: */
+#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xF8000000
+#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00F00000
+#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x00000000
+#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0007FFFF
+#define XCHAL_INTTYPE_MASK_TIMER 0x07000000
+#define XCHAL_INTTYPE_MASK_NMI 0x00080000
+#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000
+
+/* Interrupt numbers assigned to specific interrupt sources: */
+#define XCHAL_TIMER0_INTERRUPT 24 /* CCOMPARE0 */
+#define XCHAL_TIMER1_INTERRUPT 25 /* CCOMPARE1 */
+#define XCHAL_TIMER2_INTERRUPT 26 /* CCOMPARE2 */
+#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED
+#define XCHAL_NMI_INTERRUPT 19 /* non-maskable interrupt */
+
+/* Interrupt numbers for levels at which only one interrupt is configured: */
+#define XCHAL_INTLEVEL5_NUM 19
+/* (There are many interrupts each at level(s) 1, 2, 3.) */
+
+
+/*
+ * External interrupt vectors/levels.
+ * These macros describe how Xtensa processor interrupt numbers
+ * (as numbered internally, eg. in INTERRUPT and INTENABLE registers)
+ * map to external BInterrupt<n> pins, for those interrupts
+ * configured as external (level-triggered, edge-triggered, or NMI).
+ * See the Xtensa processor databook for more details.
+ */
+
+/* Core interrupt numbers mapped to each EXTERNAL interrupt number: */
+#define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */
+#define XCHAL_EXTINT1_NUM 1 /* (intlevel 1) */
+#define XCHAL_EXTINT2_NUM 2 /* (intlevel 1) */
+#define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */
+#define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */
+#define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */
+#define XCHAL_EXTINT6_NUM 6 /* (intlevel 1) */
+#define XCHAL_EXTINT7_NUM 7 /* (intlevel 1) */
+#define XCHAL_EXTINT8_NUM 8 /* (intlevel 1) */
+#define XCHAL_EXTINT9_NUM 9 /* (intlevel 1) */
+#define XCHAL_EXTINT10_NUM 10 /* (intlevel 1) */
+#define XCHAL_EXTINT11_NUM 11 /* (intlevel 1) */
+#define XCHAL_EXTINT12_NUM 12 /* (intlevel 1) */
+#define XCHAL_EXTINT13_NUM 13 /* (intlevel 1) */
+#define XCHAL_EXTINT14_NUM 14 /* (intlevel 1) */
+#define XCHAL_EXTINT15_NUM 15 /* (intlevel 2) */
+#define XCHAL_EXTINT16_NUM 16 /* (intlevel 2) */
+#define XCHAL_EXTINT17_NUM 17 /* (intlevel 3) */
+#define XCHAL_EXTINT18_NUM 18 /* (intlevel 3) */
+#define XCHAL_EXTINT19_NUM 19 /* (intlevel 5) */
+
+
+/*----------------------------------------------------------------------
+ EXCEPTIONS and VECTORS
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture
+ number: 1 == XEA1 (old)
+ 2 == XEA2 (new)
+ 0 == XEAX (extern) */
+#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */
+#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */
+#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */
+#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */
+#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */
+#define XCHAL_HAVE_VECTOR_SELECT 0 /* relocatable vectors */
+#define XCHAL_HAVE_VECBASE 0 /* relocatable vectors */
+
+#define XCHAL_RESET_VECOFS 0x00000000
+#define XCHAL_RESET_VECTOR_VADDR 0x3FFE03D0
+#define XCHAL_RESET_VECTOR_PADDR 0x3FFE03D0
+#define XCHAL_USER_VECOFS 0x00000000
+#define XCHAL_USER_VECTOR_VADDR 0x40000220
+#define XCHAL_USER_VECTOR_PADDR 0x40000220
+#define XCHAL_KERNEL_VECOFS 0x00000000
+#define XCHAL_KERNEL_VECTOR_VADDR 0x40000200
+#define XCHAL_KERNEL_VECTOR_PADDR 0x40000200
+#define XCHAL_DOUBLEEXC_VECOFS 0x00000000
+#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0x400002A0
+#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x400002A0
+#define XCHAL_WINDOW_OF4_VECOFS 0x00000000
+#define XCHAL_WINDOW_UF4_VECOFS 0x00000040
+#define XCHAL_WINDOW_OF8_VECOFS 0x00000080
+#define XCHAL_WINDOW_UF8_VECOFS 0x000000C0
+#define XCHAL_WINDOW_OF12_VECOFS 0x00000100
+#define XCHAL_WINDOW_UF12_VECOFS 0x00000140
+#define XCHAL_WINDOW_VECTORS_VADDR 0x40000000
+#define XCHAL_WINDOW_VECTORS_PADDR 0x40000000
+#define XCHAL_INTLEVEL2_VECOFS 0x00000000
+#define XCHAL_INTLEVEL2_VECTOR_VADDR 0x40000240
+#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x40000240
+#define XCHAL_INTLEVEL3_VECOFS 0x00000000
+#define XCHAL_INTLEVEL3_VECTOR_VADDR 0x40000260
+#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x40000260
+#define XCHAL_INTLEVEL4_VECOFS 0x00000000
+#define XCHAL_INTLEVEL4_VECTOR_VADDR 0x40000390
+#define XCHAL_INTLEVEL4_VECTOR_PADDR 0x40000390
+#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL4_VECOFS
+#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL4_VECTOR_VADDR
+#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL4_VECTOR_PADDR
+#define XCHAL_NMI_VECOFS 0x00000000
+#define XCHAL_NMI_VECTOR_VADDR 0x400003B0
+#define XCHAL_NMI_VECTOR_PADDR 0x400003B0
+#define XCHAL_INTLEVEL5_VECOFS XCHAL_NMI_VECOFS
+#define XCHAL_INTLEVEL5_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR
+#define XCHAL_INTLEVEL5_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR
+
+
+/*----------------------------------------------------------------------
+ DEBUG
+ ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */
+#define XCHAL_NUM_IBREAK 2 /* number of IBREAKn regs */
+#define XCHAL_NUM_DBREAK 2 /* number of DBREAKn regs */
+#define XCHAL_HAVE_OCD_DIR_ARRAY 1 /* faster OCD option */
+
+
+/*----------------------------------------------------------------------
+ MMU
+ ----------------------------------------------------------------------*/
+
+/* See core-matmap.h header file for more details. */
+
+#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */
+#define XCHAL_HAVE_SPANNING_WAY 1 /* one way maps I+D 4GB vaddr */
+#define XCHAL_HAVE_IDENTITY_MAP 1 /* vaddr == paddr always */
+#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */
+#define XCHAL_HAVE_MIMIC_CACHEATTR 1 /* region protection */
+#define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */
+#define XCHAL_HAVE_PTP_MMU 0 /* full MMU (with page table
+ [autorefill] and protection)
+ usable for an MMU-based OS */
+/* If none of the above last 4 are set, it's a custom TLB configuration. */
+
+#define XCHAL_MMU_ASID_BITS 0 /* number of bits in ASIDs */
+#define XCHAL_MMU_RINGS 1 /* number of rings (1..4) */
+#define XCHAL_MMU_RING_BITS 0 /* num of bits in RING field */
+
+#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
+
+
+#endif /* _XTENSA_CORE_CONFIGURATION_H */
+
diff --git a/arch/xtensa/variants/s6000/include/variant/hardware.h b/arch/xtensa/variants/s6000/include/variant/hardware.h
new file mode 100644
index 000000000000..5d9ba098d84a
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/hardware.h
@@ -0,0 +1,259 @@
+#ifndef __XTENSA_S6000_HARDWARE_H
+#define __XTENSA_S6000_HARDWARE_H
+
+#define S6_SCLK 1843200
+
+#define S6_MEM_REG 0x20000000
+#define S6_MEM_EFI 0x33F00000
+#define S6_MEM_PCIE_DATARAM1 0x34000000
+#define S6_MEM_XLMI 0x37F80000
+#define S6_MEM_PIF_DATARAM1 0x37FFC000
+#define S6_MEM_GMAC 0x38000000
+#define S6_MEM_I2S 0x3A000000
+#define S6_MEM_EGIB 0x3C000000
+#define S6_MEM_PCIE_CFG 0x3E000000
+#define S6_MEM_PIF_DATARAM 0x3FFE0000
+#define S6_MEM_XLMI_DATARAM 0x3FFF0000
+#define S6_MEM_DDR 0x40000000
+#define S6_MEM_PCIE_APER 0xC0000000
+#define S6_MEM_AUX 0xF0000000
+
+/* Device addresses */
+
+#define S6_REG_SCB S6_MEM_REG
+#define S6_REG_NB (S6_REG_SCB + 0x10000)
+#define S6_REG_LMSDMA (S6_REG_SCB + 0x20000)
+#define S6_REG_NI (S6_REG_SCB + 0x30000)
+#define S6_REG_NIDMA (S6_REG_SCB + 0x40000)
+#define S6_REG_NS (S6_REG_SCB + 0x50000)
+#define S6_REG_DDR (S6_REG_SCB + 0x60000)
+#define S6_REG_GREG1 (S6_REG_SCB + 0x70000)
+#define S6_REG_DP (S6_REG_SCB + 0x80000)
+#define S6_REG_DPDMA (S6_REG_SCB + 0x90000)
+#define S6_REG_EGIB (S6_REG_SCB + 0xA0000)
+#define S6_REG_PCIE (S6_REG_SCB + 0xB0000)
+#define S6_REG_I2S (S6_REG_SCB + 0xC0000)
+#define S6_REG_GMAC (S6_REG_SCB + 0xD0000)
+#define S6_REG_HIFDMA (S6_REG_SCB + 0xE0000)
+#define S6_REG_GREG2 (S6_REG_SCB + 0xF0000)
+
+#define S6_REG_APB S6_REG_SCB
+#define S6_REG_UART (S6_REG_APB + 0x0000)
+#define S6_REG_INTC (S6_REG_APB + 0x2000)
+#define S6_REG_SPI (S6_REG_APB + 0x3000)
+#define S6_REG_I2C (S6_REG_APB + 0x4000)
+#define S6_REG_GPIO (S6_REG_APB + 0x8000)
+
+/* Global register block */
+
+#define S6_GREG1_PLL_LOCKCLEAR 0x000
+#define S6_GREG1_PLL_LOCK_SYS 0
+#define S6_GREG1_PLL_LOCK_IO 1
+#define S6_GREG1_PLL_LOCK_AIM 2
+#define S6_GREG1_PLL_LOCK_DP0 3
+#define S6_GREG1_PLL_LOCK_DP2 4
+#define S6_GREG1_PLL_LOCK_DDR 5
+#define S6_GREG1_PLL_LOCKSTAT 0x004
+#define S6_GREG1_PLL_LOCKSTAT_CURLOCK 0
+#define S6_GREG1_PLL_LOCKSTAT_EVERUNLCK 8
+#define S6_GREG1_PLLSEL 0x010
+#define S6_GREG1_PLLSEL_AIM 0
+#define S6_GREG1_PLLSEL_AIM_DDR2 0
+#define S6_GREG1_PLLSEL_AIM_300MHZ 1
+#define S6_GREG1_PLLSEL_AIM_240MHZ 2
+#define S6_GREG1_PLLSEL_AIM_200MHZ 3
+#define S6_GREG1_PLLSEL_AIM_150MHZ 4
+#define S6_GREG1_PLLSEL_AIM_120MHZ 5
+#define S6_GREG1_PLLSEL_AIM_40MHZ 6
+#define S6_GREG1_PLLSEL_AIM_PLLAIMREF 7
+#define S6_GREG1_PLLSEL_AIM_MASK 7
+#define S6_GREG1_PLLSEL_DDR 8
+#define S6_GREG1_PLLSEL_DDR_HS 0
+#define S6_GREG1_PLLSEL_DDR_333MHZ 1
+#define S6_GREG1_PLLSEL_DDR_250MHZ 2
+#define S6_GREG1_PLLSEL_DDR_200MHZ 3
+#define S6_GREG1_PLLSEL_DDR_167MHZ 4
+#define S6_GREG1_PLLSEL_DDR_100MHZ 5
+#define S6_GREG1_PLLSEL_DDR_33MHZ 6
+#define S6_GREG1_PLLSEL_DDR_PLLIOREF 7
+#define S6_GREG1_PLLSEL_DDR_MASK 7
+#define S6_GREG1_PLLSEL_GMAC 16
+#define S6_GREG1_PLLSEL_GMAC_125MHZ 0
+#define S6_GREG1_PLLSEL_GMAC_25MHZ 1
+#define S6_GREG1_PLLSEL_GMAC_2500KHZ 2
+#define S6_GREG1_PLLSEL_GMAC_EXTERN 3
+#define S6_GREG1_PLLSEL_GMAC_MASK 3
+#define S6_GREG1_PLLSEL_GMII 18
+#define S6_GREG1_PLLSEL_GMII_111MHZ 0
+#define S6_GREG1_PLLSEL_GMII_IOREF 1
+#define S6_GREG1_PLLSEL_GMII_NONE 2
+#define S6_GREG1_PLLSEL_GMII_125MHZ 3
+#define S6_GREG1_PLLSEL_GMII_MASK 3
+#define S6_GREG1_SYSUNLOCKCNT 0x020
+#define S6_GREG1_IOUNLOCKCNT 0x024
+#define S6_GREG1_AIMUNLOCKCNT 0x028
+#define S6_GREG1_DP0UNLOCKCNT 0x02C
+#define S6_GREG1_DP2UNLOCKCNT 0x030
+#define S6_GREG1_DDRUNLOCKCNT 0x034
+#define S6_GREG1_CLKBAL0 0x040
+#define S6_GREG1_CLKBAL0_LSGB 0
+#define S6_GREG1_CLKBAL0_LSPX 8
+#define S6_GREG1_CLKBAL0_MEMDO 16
+#define S6_GREG1_CLKBAL0_HSXT1 24
+#define S6_GREG1_CLKBAL1 0x044
+#define S6_GREG1_CLKBAL1_HSISEF 0
+#define S6_GREG1_CLKBAL1_HSNI 8
+#define S6_GREG1_CLKBAL1_HSNS 16
+#define S6_GREG1_CLKBAL1_HSISEFCFG 24
+#define S6_GREG1_CLKBAL2 0x048
+#define S6_GREG1_CLKBAL2_LSNB 0
+#define S6_GREG1_CLKBAL2_LSSB 8
+#define S6_GREG1_CLKBAL2_LSREST 24
+#define S6_GREG1_CLKBAL3 0x04C
+#define S6_GREG1_CLKBAL3_ISEFXAD 0
+#define S6_GREG1_CLKBAL3_ISEFLMS 8
+#define S6_GREG1_CLKBAL3_ISEFISEF 16
+#define S6_GREG1_CLKBAL3_DDRDD 24
+#define S6_GREG1_CLKBAL4 0x050
+#define S6_GREG1_CLKBAL4_DDRDP 0
+#define S6_GREG1_CLKBAL4_DDRDO 8
+#define S6_GREG1_CLKBAL4_DDRNB 16
+#define S6_GREG1_CLKBAL4_DDRLMS 24
+#define S6_GREG1_BLOCKENA 0x100
+#define S6_GREG1_BLOCK_DDR 0
+#define S6_GREG1_BLOCK_DP 1
+#define S6_GREG1_BLOCK_NSNI 2
+#define S6_GREG1_BLOCK_PCIE 3
+#define S6_GREG1_BLOCK_GMAC 4
+#define S6_GREG1_BLOCK_I2S 5
+#define S6_GREG1_BLOCK_EGIB 6
+#define S6_GREG1_BLOCK_SB 7
+#define S6_GREG1_BLOCK_XT1 8
+#define S6_GREG1_CLKGATE 0x104
+#define S6_GREG1_BGATE_AIMNORTH 9
+#define S6_GREG1_BGATE_AIMEAST 10
+#define S6_GREG1_BGATE_AIMWEST 11
+#define S6_GREG1_BGATE_AIMSOUTH 12
+#define S6_GREG1_CHIPRES 0x108
+#define S6_GREG1_CHIPRES_SOFTRES 0
+#define S6_GREG1_CHIPRES_LOSTLOCK 1
+#define S6_GREG1_RESETCAUSE 0x10C
+#define S6_GREG1_RESETCAUSE_RESETN 0
+#define S6_GREG1_RESETCAUSE_GLOBAL 1
+#define S6_GREG1_RESETCAUSE_WDOGTIMER 2
+#define S6_GREG1_RESETCAUSE_SWCHIP 3
+#define S6_GREG1_RESETCAUSE_PLLSYSLOSS 4
+#define S6_GREG1_RESETCAUSE_PCIE 5
+#define S6_GREG1_RESETCAUSE_CREATEDGLOB 6
+#define S6_GREG1_REFCLOCKCNT 0x110
+#define S6_GREG1_RESETTIMER 0x114
+#define S6_GREG1_NMITIMER 0x118
+#define S6_GREG1_GLOBAL_TIMER 0x11C
+#define S6_GREG1_TIMER0 0x180
+#define S6_GREG1_TIMER1 0x184
+#define S6_GREG1_UARTCLOCKSEL 0x204
+#define S6_GREG1_CHIPVERSPACKG 0x208
+#define S6_GREG1_CHIPVERSPACKG_CHIPVID 0
+#define S6_GREG1_CHIPVERSPACKG_PACKSEL 8
+#define S6_GREG1_ONDIETERMCTRL 0x20C
+#define S6_GREG1_ONDIETERMCTRL_WEST 0
+#define S6_GREG1_ONDIETERMCTRL_NORTH 2
+#define S6_GREG1_ONDIETERMCTRL_EAST 4
+#define S6_GREG1_ONDIETERMCTRL_SOUTH 6
+#define S6_GREG1_ONDIETERMCTRL_NONE 0
+#define S6_GREG1_ONDIETERMCTRL_75OHM 2
+#define S6_GREG1_ONDIETERMCTRL_MASK 3
+#define S6_GREG1_BOOT_CFG0 0x210
+#define S6_GREG1_BOOT_CFG0_AIMSTRONG 1
+#define S6_GREG1_BOOT_CFG0_MINIBOOTDL 2
+#define S6_GREG1_BOOT_CFG0_OCDGPIO8SET 5
+#define S6_GREG1_BOOT_CFG0_OCDGPIOENA 6
+#define S6_GREG1_BOOT_CFG0_DOWNSTREAM 7
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV 8
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_300MHZ 1
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_240MHZ 2
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_200MHZ 3
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_150MHZ 4
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_120MHZ 5
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_40MHZ 6
+#define S6_GREG1_BOOT_CFG0_PLLSYSDIV_MASK 7
+#define S6_GREG1_BOOT_CFG0_BALHSLMS 12
+#define S6_GREG1_BOOT_CFG0_BALHSNB 18
+#define S6_GREG1_BOOT_CFG0_BALHSXAD 24
+#define S6_GREG1_BOOT_CFG1 0x214
+#define S6_GREG1_BOOT_CFG1_PCIE1LANE 1
+#define S6_GREG1_BOOT_CFG1_MPLLPRESCALE 2
+#define S6_GREG1_BOOT_CFG1_MPLLNCY 4
+#define S6_GREG1_BOOT_CFG1_MPLLNCY5 9
+#define S6_GREG1_BOOT_CFG1_BALHSREST 14
+#define S6_GREG1_BOOT_CFG1_BALHSPSMEMS 20
+#define S6_GREG1_BOOT_CFG1_BALLSGI 26
+#define S6_GREG1_BOOT_CFG2 0x218
+#define S6_GREG1_BOOT_CFG2_PEID 0
+#define S6_GREG1_BOOT_CFG3 0x21C
+#define S6_GREG1_DRAMBUSYHOLDOF 0x220
+#define S6_GREG1_DRAMBUSYHOLDOF_XT0 0
+#define S6_GREG1_DRAMBUSYHOLDOF_XT1 4
+#define S6_GREG1_DRAMBUSYHOLDOF_XT_MASK 7
+#define S6_GREG1_PCIEBAR1SIZE 0x224
+#define S6_GREG1_PCIEBAR2SIZE 0x228
+#define S6_GREG1_PCIEVENDOR 0x22C
+#define S6_GREG1_PCIEDEVICE 0x230
+#define S6_GREG1_PCIEREV 0x234
+#define S6_GREG1_PCIECLASS 0x238
+#define S6_GREG1_XT1DCACHEMISS 0x240
+#define S6_GREG1_XT1ICACHEMISS 0x244
+#define S6_GREG1_HWSEMAPHORE(n) (0x400 + 4 * (n))
+#define S6_GREG1_HWSEMAPHORE_NB 16
+
+/* peripheral interrupt numbers */
+
+#define S6_INTC_GPIO(n) (n) /* 0..3 */
+#define S6_INTC_I2C 4
+#define S6_INTC_SPI 5
+#define S6_INTC_NB_ERR 6
+#define S6_INTC_DMA_LMSERR 7
+#define S6_INTC_DMA_LMSLOWWMRK(n) (8 + (n)) /* 0..11 */
+#define S6_INTC_DMA_LMSPENDCNT(n) (20 + (n)) /* 0..11 */
+#define S6_INTC_DMA HOSTLOWWMRK(n) (32 + (n)) /* 0..6 */
+#define S6_INTC_DMA_HOSTPENDCNT(n) (39 + (n)) /* 0..6 */
+#define S6_INTC_DMA_HOSTERR 46
+#define S6_INTC_UART(n) (47 + (n)) /* 0..1 */
+#define S6_INTC_XAD 49
+#define S6_INTC_NI_ERR 50
+#define S6_INTC_NI_INFIFOFULL 51
+#define S6_INTC_DMA_NIERR 52
+#define S6_INTC_DMA_NILOWWMRK(n) (53 + (n)) /* 0..3 */
+#define S6_INTC_DMA_NIPENDCNT(n) (57 + (n)) /* 0..3 */
+#define S6_INTC_DDR 61
+#define S6_INTC_NS_ERR 62
+#define S6_INTC_EFI_CFGERR 63
+#define S6_INTC_EFI_ISEFTEST 64
+#define S6_INTC_EFI_WRITEERR 65
+#define S6_INTC_NMI_TIMER 66
+#define S6_INTC_PLLLOCK_SYS 67
+#define S6_INTC_PLLLOCK_IO 68
+#define S6_INTC_PLLLOCK_AIM 69
+#define S6_INTC_PLLLOCK_DP0 70
+#define S6_INTC_PLLLOCK_DP2 71
+#define S6_INTC_I2S_ERR 72
+#define S6_INTC_GMAC_STAT 73
+#define S6_INTC_GMAC_ERR 74
+#define S6_INTC_GIB_ERR 75
+#define S6_INTC_PCIE_ERR 76
+#define S6_INTC_PCIE_MSI(n) (77 + (n)) /* 0..3 */
+#define S6_INTC_PCIE_INTA 81
+#define S6_INTC_PCIE_INTB 82
+#define S6_INTC_PCIE_INTC 83
+#define S6_INTC_PCIE_INTD 84
+#define S6_INTC_SW(n) (85 + (n)) /* 0..9 */
+#define S6_INTC_SW_ENABLE(n) (85 + 256 + (n))
+#define S6_INTC_DMA_DP_ERR 95
+#define S6_INTC_DMA_DPLOWWMRK(n) (96 + (n)) /* 0..3 */
+#define S6_INTC_DMA_DPPENDCNT(n) (100 + (n)) /* 0..3 */
+#define S6_INTC_DMA_DPTERMCNT(n) (104 + (n)) /* 0..3 */
+#define S6_INTC_TIMER0 108
+#define S6_INTC_TIMER1 109
+#define S6_INTC_DMA_HOSTTERMCNT(n) (110 + (n)) /* 0..6 */
+
+#endif /* __XTENSA_S6000_HARDWARE_H */
diff --git a/arch/xtensa/variants/s6000/include/variant/irq.h b/arch/xtensa/variants/s6000/include/variant/irq.h
new file mode 100644
index 000000000000..fa031cb0acc4
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/irq.h
@@ -0,0 +1,9 @@
+#ifndef __XTENSA_S6000_IRQ_H
+#define __XTENSA_S6000_IRQ_H
+
+#define NO_IRQ (-1)
+
+extern void variant_irq_enable(unsigned int irq);
+extern void variant_irq_disable(unsigned int irq);
+
+#endif /* __XTENSA_S6000_IRQ_H */
diff --git a/arch/xtensa/variants/s6000/include/variant/tie-asm.h b/arch/xtensa/variants/s6000/include/variant/tie-asm.h
new file mode 100644
index 000000000000..f02d0a3a2e20
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/tie-asm.h
@@ -0,0 +1,304 @@
+/*
+ * This header file contains assembly-language definitions (assembly
+ * macros, etc.) for this specific Xtensa processor's TIE extensions
+ * and options. It is customized to this Xtensa processor configuration.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999-2008 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_TIE_ASM_H
+#define _XTENSA_CORE_TIE_ASM_H
+
+/* Selection parameter values for save-area save/restore macros: */
+/* Option vs. TIE: */
+#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */
+#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */
+/* Whether used automatically by compiler: */
+#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */
+#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */
+/* ABI handling across function calls: */
+#define XTHAL_SAS_CALR 0x0010 /* caller-saved */
+#define XTHAL_SAS_CALE 0x0020 /* callee-saved */
+#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */
+/* Misc */
+#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */
+
+
+
+/* Macro to save all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Save area ptr (clobbered): ptr (16 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed)
+ */
+ .macro xchal_ncp_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+ xchal_sa_align \ptr, 0, 1024-4, 4, 4
+ rsr \at1, BR // boolean option
+ s32i \at1, \ptr, .Lxchal_ofs_ + 0
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 4
+ .endif
+ .endm // xchal_ncp_store
+
+/* Macro to save all non-coprocessor (extra) custom TIE and optional state
+ * (not including zero-overhead loop registers).
+ * Save area ptr (clobbered): ptr (16 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed)
+ */
+ .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+ xchal_sa_align \ptr, 0, 1024-4, 4, 4
+ l32i \at1, \ptr, .Lxchal_ofs_ + 0
+ wsr \at1, BR // boolean option
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 4
+ .endif
+ .endm // xchal_ncp_load
+
+
+
+#define XCHAL_NCP_NUM_ATMPS 1
+
+
+
+/* Macro to save the state of TIE coprocessor FPU.
+ * Save area ptr (clobbered): ptr (16 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP0_NUM_ATMPS needed)
+ */
+#define xchal_cp_FPU_store xchal_cp0_store
+/* #define xchal_cp_FPU_store_a2 xchal_cp0_store a2 a3 a4 a5 a6 */
+ .macro xchal_cp0_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+ xchal_sa_align \ptr, 0, 0, 1, 16
+ rur232 \at1 // FCR
+ s32i \at1, \ptr, 0
+ rur233 \at1 // FSR
+ s32i \at1, \ptr, 4
+ SSI f0, \ptr, 8
+ SSI f1, \ptr, 12
+ SSI f2, \ptr, 16
+ SSI f3, \ptr, 20
+ SSI f4, \ptr, 24
+ SSI f5, \ptr, 28
+ SSI f6, \ptr, 32
+ SSI f7, \ptr, 36
+ SSI f8, \ptr, 40
+ SSI f9, \ptr, 44
+ SSI f10, \ptr, 48
+ SSI f11, \ptr, 52
+ SSI f12, \ptr, 56
+ SSI f13, \ptr, 60
+ SSI f14, \ptr, 64
+ SSI f15, \ptr, 68
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 72
+ .endif
+ .endm // xchal_cp0_store
+
+/* Macro to restore the state of TIE coprocessor FPU.
+ * Save area ptr (clobbered): ptr (16 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP0_NUM_ATMPS needed)
+ */
+#define xchal_cp_FPU_load xchal_cp0_load
+/* #define xchal_cp_FPU_load_a2 xchal_cp0_load a2 a3 a4 a5 a6 */
+ .macro xchal_cp0_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+ xchal_sa_align \ptr, 0, 0, 1, 16
+ l32i \at1, \ptr, 0
+ wur232 \at1 // FCR
+ l32i \at1, \ptr, 4
+ wur233 \at1 // FSR
+ LSI f0, \ptr, 8
+ LSI f1, \ptr, 12
+ LSI f2, \ptr, 16
+ LSI f3, \ptr, 20
+ LSI f4, \ptr, 24
+ LSI f5, \ptr, 28
+ LSI f6, \ptr, 32
+ LSI f7, \ptr, 36
+ LSI f8, \ptr, 40
+ LSI f9, \ptr, 44
+ LSI f10, \ptr, 48
+ LSI f11, \ptr, 52
+ LSI f12, \ptr, 56
+ LSI f13, \ptr, 60
+ LSI f14, \ptr, 64
+ LSI f15, \ptr, 68
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 72
+ .endif
+ .endm // xchal_cp0_load
+
+#define XCHAL_CP0_NUM_ATMPS 1
+
+/* Macro to save the state of TIE coprocessor XAD.
+ * Save area ptr (clobbered): ptr (16 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP6_NUM_ATMPS needed)
+ */
+#define xchal_cp_XAD_store xchal_cp6_store
+/* #define xchal_cp_XAD_store_a2 xchal_cp6_store a2 a3 a4 a5 a6 */
+ .macro xchal_cp6_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+ xchal_sa_align \ptr, 0, 0, 1, 16
+ rur0 \at1 // LDCBHI
+ s32i \at1, \ptr, 0
+ rur1 \at1 // LDCBLO
+ s32i \at1, \ptr, 4
+ rur2 \at1 // STCBHI
+ s32i \at1, \ptr, 8
+ rur3 \at1 // STCBLO
+ s32i \at1, \ptr, 12
+ rur8 \at1 // LDBRBASE
+ s32i \at1, \ptr, 16
+ rur9 \at1 // LDBROFF
+ s32i \at1, \ptr, 20
+ rur10 \at1 // LDBRINC
+ s32i \at1, \ptr, 24
+ rur11 \at1 // STBRBASE
+ s32i \at1, \ptr, 28
+ rur12 \at1 // STBROFF
+ s32i \at1, \ptr, 32
+ rur13 \at1 // STBRINC
+ s32i \at1, \ptr, 36
+ rur24 \at1 // SCRATCH0
+ s32i \at1, \ptr, 40
+ rur25 \at1 // SCRATCH1
+ s32i \at1, \ptr, 44
+ rur26 \at1 // SCRATCH2
+ s32i \at1, \ptr, 48
+ rur27 \at1 // SCRATCH3
+ s32i \at1, \ptr, 52
+ WRAS128I wra0, \ptr, 64
+ WRAS128I wra1, \ptr, 80
+ WRAS128I wra2, \ptr, 96
+ WRAS128I wra3, \ptr, 112
+ WRAS128I wra4, \ptr, 128
+ WRAS128I wra5, \ptr, 144
+ WRAS128I wra6, \ptr, 160
+ WRAS128I wra7, \ptr, 176
+ WRAS128I wra8, \ptr, 192
+ WRAS128I wra9, \ptr, 208
+ WRAS128I wra10, \ptr, 224
+ WRAS128I wra11, \ptr, 240
+ WRAS128I wra12, \ptr, 256
+ WRAS128I wra13, \ptr, 272
+ WRAS128I wra14, \ptr, 288
+ WRAS128I wra15, \ptr, 304
+ WRBS128I wrb0, \ptr, 320
+ WRBS128I wrb1, \ptr, 336
+ WRBS128I wrb2, \ptr, 352
+ WRBS128I wrb3, \ptr, 368
+ WRBS128I wrb4, \ptr, 384
+ WRBS128I wrb5, \ptr, 400
+ WRBS128I wrb6, \ptr, 416
+ WRBS128I wrb7, \ptr, 432
+ WRBS128I wrb8, \ptr, 448
+ WRBS128I wrb9, \ptr, 464
+ WRBS128I wrb10, \ptr, 480
+ WRBS128I wrb11, \ptr, 496
+ WRBS128I wrb12, \ptr, 512
+ WRBS128I wrb13, \ptr, 528
+ WRBS128I wrb14, \ptr, 544
+ WRBS128I wrb15, \ptr, 560
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 576
+ .endif
+ .endm // xchal_cp6_store
+
+/* Macro to restore the state of TIE coprocessor XAD.
+ * Save area ptr (clobbered): ptr (16 byte aligned)
+ * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP6_NUM_ATMPS needed)
+ */
+#define xchal_cp_XAD_load xchal_cp6_load
+/* #define xchal_cp_XAD_load_a2 xchal_cp6_load a2 a3 a4 a5 a6 */
+ .macro xchal_cp6_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL
+ xchal_sa_start \continue, \ofs
+ .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select
+ xchal_sa_align \ptr, 0, 0, 1, 16
+ l32i \at1, \ptr, 0
+ wur0 \at1 // LDCBHI
+ l32i \at1, \ptr, 4
+ wur1 \at1 // LDCBLO
+ l32i \at1, \ptr, 8
+ wur2 \at1 // STCBHI
+ l32i \at1, \ptr, 12
+ wur3 \at1 // STCBLO
+ l32i \at1, \ptr, 16
+ wur8 \at1 // LDBRBASE
+ l32i \at1, \ptr, 20
+ wur9 \at1 // LDBROFF
+ l32i \at1, \ptr, 24
+ wur10 \at1 // LDBRINC
+ l32i \at1, \ptr, 28
+ wur11 \at1 // STBRBASE
+ l32i \at1, \ptr, 32
+ wur12 \at1 // STBROFF
+ l32i \at1, \ptr, 36
+ wur13 \at1 // STBRINC
+ l32i \at1, \ptr, 40
+ wur24 \at1 // SCRATCH0
+ l32i \at1, \ptr, 44
+ wur25 \at1 // SCRATCH1
+ l32i \at1, \ptr, 48
+ wur26 \at1 // SCRATCH2
+ l32i \at1, \ptr, 52
+ wur27 \at1 // SCRATCH3
+ WRBL128I wrb0, \ptr, 320
+ WRBL128I wrb1, \ptr, 336
+ WRBL128I wrb2, \ptr, 352
+ WRBL128I wrb3, \ptr, 368
+ WRBL128I wrb4, \ptr, 384
+ WRBL128I wrb5, \ptr, 400
+ WRBL128I wrb6, \ptr, 416
+ WRBL128I wrb7, \ptr, 432
+ WRBL128I wrb8, \ptr, 448
+ WRBL128I wrb9, \ptr, 464
+ WRBL128I wrb10, \ptr, 480
+ WRBL128I wrb11, \ptr, 496
+ WRBL128I wrb12, \ptr, 512
+ WRBL128I wrb13, \ptr, 528
+ WRBL128I wrb14, \ptr, 544
+ WRBL128I wrb15, \ptr, 560
+ WRAL128I wra0, \ptr, 64
+ WRAL128I wra1, \ptr, 80
+ WRAL128I wra2, \ptr, 96
+ WRAL128I wra3, \ptr, 112
+ WRAL128I wra4, \ptr, 128
+ WRAL128I wra5, \ptr, 144
+ WRAL128I wra6, \ptr, 160
+ WRAL128I wra7, \ptr, 176
+ WRAL128I wra8, \ptr, 192
+ WRAL128I wra9, \ptr, 208
+ WRAL128I wra10, \ptr, 224
+ WRAL128I wra11, \ptr, 240
+ WRAL128I wra12, \ptr, 256
+ WRAL128I wra13, \ptr, 272
+ WRAL128I wra14, \ptr, 288
+ WRAL128I wra15, \ptr, 304
+ .set .Lxchal_ofs_, .Lxchal_ofs_ + 576
+ .endif
+ .endm // xchal_cp6_load
+
+#define XCHAL_CP6_NUM_ATMPS 1
+#define XCHAL_SA_NUM_ATMPS 1
+
+ /* Empty macros for unconfigured coprocessors: */
+ .macro xchal_cp1_store p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp1_load p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp2_store p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp2_load p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp3_store p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp3_load p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp4_store p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp4_load p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp5_store p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp5_load p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp7_store p a b c d continue=0 ofs=-1 select=-1 ; .endm
+ .macro xchal_cp7_load p a b c d continue=0 ofs=-1 select=-1 ; .endm
+
+#endif /*_XTENSA_CORE_TIE_ASM_H*/
+
diff --git a/arch/xtensa/variants/s6000/include/variant/tie.h b/arch/xtensa/variants/s6000/include/variant/tie.h
new file mode 100644
index 000000000000..be7ea843d5df
--- /dev/null
+++ b/arch/xtensa/variants/s6000/include/variant/tie.h
@@ -0,0 +1,191 @@
+/*
+ * This header file describes this specific Xtensa processor's TIE extensions
+ * that extend basic Xtensa core functionality. It is customized to this
+ * Xtensa processor configuration.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1999-2008 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CORE_TIE_H
+#define _XTENSA_CORE_TIE_H
+
+#define XCHAL_CP_NUM 2 /* number of coprocessors */
+#define XCHAL_CP_MAX 7 /* max CP ID + 1 (0 if none) */
+#define XCHAL_CP_MASK 0x41 /* bitmask of all CPs by ID */
+#define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */
+
+/* Basic parameters of each coprocessor: */
+#define XCHAL_CP0_NAME "FPU"
+#define XCHAL_CP0_IDENT FPU
+#define XCHAL_CP0_SA_SIZE 72 /* size of state save area */
+#define XCHAL_CP0_SA_ALIGN 4 /* min alignment of save area */
+#define XCHAL_CP_ID_FPU 0 /* coprocessor ID (0..7) */
+#define XCHAL_CP6_NAME "XAD"
+#define XCHAL_CP6_IDENT XAD
+#define XCHAL_CP6_SA_SIZE 576 /* size of state save area */
+#define XCHAL_CP6_SA_ALIGN 16 /* min alignment of save area */
+#define XCHAL_CP_ID_XAD 6 /* coprocessor ID (0..7) */
+
+/* Filler info for unassigned coprocessors, to simplify arrays etc: */
+#define XCHAL_CP1_SA_SIZE 0
+#define XCHAL_CP1_SA_ALIGN 1
+#define XCHAL_CP2_SA_SIZE 0
+#define XCHAL_CP2_SA_ALIGN 1
+#define XCHAL_CP3_SA_SIZE 0
+#define XCHAL_CP3_SA_ALIGN 1
+#define XCHAL_CP4_SA_SIZE 0
+#define XCHAL_CP4_SA_ALIGN 1
+#define XCHAL_CP5_SA_SIZE 0
+#define XCHAL_CP5_SA_ALIGN 1
+#define XCHAL_CP7_SA_SIZE 0
+#define XCHAL_CP7_SA_ALIGN 1
+
+/* Save area for non-coprocessor optional and custom (TIE) state: */
+#define XCHAL_NCP_SA_SIZE 4
+#define XCHAL_NCP_SA_ALIGN 4
+
+/* Total save area for optional and custom state (NCP + CPn): */
+#define XCHAL_TOTAL_SA_SIZE 672 /* with 16-byte align padding */
+#define XCHAL_TOTAL_SA_ALIGN 16 /* actual minimum alignment */
+
+/*
+ * Detailed contents of save areas.
+ * NOTE: caller must define the XCHAL_SA_REG macro (not defined here)
+ * before expanding the XCHAL_xxx_SA_LIST() macros.
+ *
+ * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize,
+ * dbnum,base,regnum,bitsz,gapsz,reset,x...)
+ *
+ * s = passed from XCHAL_*_LIST(s), eg. to select how to expand
+ * ccused = set if used by compiler without special options or code
+ * abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global)
+ * kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg)
+ * opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg)
+ * name = lowercase reg name (no quotes)
+ * galign = group byte alignment (power of 2) (galign >= align)
+ * align = register byte alignment (power of 2)
+ * asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz)
+ * (not including any pad bytes required to galign this or next reg)
+ * dbnum = unique target number f/debug (see <xtensa-libdb-macros.h>)
+ * base = reg shortname w/o index (or sr=special, ur=TIE user reg)
+ * regnum = reg index in regfile, or special/TIE-user reg number
+ * bitsz = number of significant bits (regfile width, or ur/sr mask bits)
+ * gapsz = intervening bits, if bitsz bits not stored contiguously
+ * (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize)
+ * reset = register reset value (or 0 if undefined at reset)
+ * x = reserved for future use (0 until then)
+ *
+ * To filter out certain registers, e.g. to expand only the non-global
+ * registers used by the compiler, you can do something like this:
+ *
+ * #define XCHAL_SA_REG(s,ccused,p...) SELCC##ccused(p)
+ * #define SELCC0(p...)
+ * #define SELCC1(abikind,p...) SELAK##abikind(p)
+ * #define SELAK0(p...) REG(p)
+ * #define SELAK1(p...) REG(p)
+ * #define SELAK2(p...)
+ * #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \
+ * ...what you want to expand...
+ */
+
+#define XCHAL_NCP_SA_NUM 1
+#define XCHAL_NCP_SA_LIST(s) \
+ XCHAL_SA_REG(s,0,0,0,1, br, 4, 4, 4,0x0204, sr,4 , 16,0,0,0)
+
+#define XCHAL_CP0_SA_NUM 18
+#define XCHAL_CP0_SA_LIST(s) \
+ XCHAL_SA_REG(s,0,0,1,0, fcr, 4, 4, 4,0x03E8, ur,232, 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, fsr, 4, 4, 4,0x03E9, ur,233, 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f0, 4, 4, 4,0x0030, f,0 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f1, 4, 4, 4,0x0031, f,1 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f2, 4, 4, 4,0x0032, f,2 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f3, 4, 4, 4,0x0033, f,3 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f4, 4, 4, 4,0x0034, f,4 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f5, 4, 4, 4,0x0035, f,5 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f6, 4, 4, 4,0x0036, f,6 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f7, 4, 4, 4,0x0037, f,7 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f8, 4, 4, 4,0x0038, f,8 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f9, 4, 4, 4,0x0039, f,9 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f10, 4, 4, 4,0x003A, f,10 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f11, 4, 4, 4,0x003B, f,11 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f12, 4, 4, 4,0x003C, f,12 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f13, 4, 4, 4,0x003D, f,13 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f14, 4, 4, 4,0x003E, f,14 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, f15, 4, 4, 4,0x003F, f,15 , 32,0,0,0)
+
+#define XCHAL_CP1_SA_NUM 0
+#define XCHAL_CP1_SA_LIST(s) /* empty */
+
+#define XCHAL_CP2_SA_NUM 0
+#define XCHAL_CP2_SA_LIST(s) /* empty */
+
+#define XCHAL_CP3_SA_NUM 0
+#define XCHAL_CP3_SA_LIST(s) /* empty */
+
+#define XCHAL_CP4_SA_NUM 0
+#define XCHAL_CP4_SA_LIST(s) /* empty */
+
+#define XCHAL_CP5_SA_NUM 0
+#define XCHAL_CP5_SA_LIST(s) /* empty */
+
+#define XCHAL_CP6_SA_NUM 46
+#define XCHAL_CP6_SA_LIST(s) \
+ XCHAL_SA_REG(s,0,0,1,0, ldcbhi,16, 4, 4,0x0300, ur,0 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, ldcblo, 4, 4, 4,0x0301, ur,1 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, stcbhi, 4, 4, 4,0x0302, ur,2 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, stcblo, 4, 4, 4,0x0303, ur,3 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, ldbrbase, 4, 4, 4,0x0308, ur,8 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, ldbroff, 4, 4, 4,0x0309, ur,9 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, ldbrinc, 4, 4, 4,0x030A, ur,10 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, stbrbase, 4, 4, 4,0x030B, ur,11 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, stbroff, 4, 4, 4,0x030C, ur,12 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, stbrinc, 4, 4, 4,0x030D, ur,13 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, scratch0, 4, 4, 4,0x0318, ur,24 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, scratch1, 4, 4, 4,0x0319, ur,25 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, scratch2, 4, 4, 4,0x031A, ur,26 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,1,0, scratch3, 4, 4, 4,0x031B, ur,27 , 32,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra0,16,16,16,0x1010, wra,0 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra1,16,16,16,0x1011, wra,1 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra2,16,16,16,0x1012, wra,2 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra3,16,16,16,0x1013, wra,3 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra4,16,16,16,0x1014, wra,4 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra5,16,16,16,0x1015, wra,5 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra6,16,16,16,0x1016, wra,6 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra7,16,16,16,0x1017, wra,7 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra8,16,16,16,0x1018, wra,8 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra9,16,16,16,0x1019, wra,9 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra10,16,16,16,0x101A, wra,10 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra11,16,16,16,0x101B, wra,11 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra12,16,16,16,0x101C, wra,12 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra13,16,16,16,0x101D, wra,13 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra14,16,16,16,0x101E, wra,14 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wra15,16,16,16,0x101F, wra,15 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb0,16,16,16,0x1020, wrb,0 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb1,16,16,16,0x1021, wrb,1 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb2,16,16,16,0x1022, wrb,2 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb3,16,16,16,0x1023, wrb,3 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb4,16,16,16,0x1024, wrb,4 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb5,16,16,16,0x1025, wrb,5 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb6,16,16,16,0x1026, wrb,6 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb7,16,16,16,0x1027, wrb,7 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb8,16,16,16,0x1028, wrb,8 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb9,16,16,16,0x1029, wrb,9 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb10,16,16,16,0x102A, wrb,10 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb11,16,16,16,0x102B, wrb,11 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb12,16,16,16,0x102C, wrb,12 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb13,16,16,16,0x102D, wrb,13 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb14,16,16,16,0x102E, wrb,14 ,128,0,0,0) \
+ XCHAL_SA_REG(s,0,0,2,0, wrb15,16,16,16,0x102F, wrb,15 ,128,0,0,0)
+
+#define XCHAL_CP7_SA_NUM 0
+#define XCHAL_CP7_SA_LIST(s) /* empty */
+
+/* Byte length of instruction from its first nibble (op0 field), per FLIX. */
+#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8
+
+#endif /*_XTENSA_CORE_TIE_H*/
+
diff --git a/arch/xtensa/variants/s6000/irq.c b/arch/xtensa/variants/s6000/irq.c
new file mode 100644
index 000000000000..6651e3285fcf
--- /dev/null
+++ b/arch/xtensa/variants/s6000/irq.c
@@ -0,0 +1,74 @@
+/*
+ * s6000 irq crossbar
+ *
+ * Copyright (c) 2009 emlix GmbH
+ * Authors: Johannes Weiner <jw@emlix.com>
+ * Oskar Schirmer <os@emlix.com>
+ */
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <variant/hardware.h>
+
+/* S6_REG_INTC */
+#define INTC_STATUS 0x000
+#define INTC_RAW 0x010
+#define INTC_STATUS_AG 0x100
+#define INTC_CFG(n) (0x200 + 4 * (n))
+
+/*
+ * The s6000 has a crossbar that multiplexes interrupt output lines
+ * from the peripherals to input lines on the xtensa core.
+ *
+ * We leave the mapping decisions to the platform as it depends on the
+ * actually connected peripherals which distribution makes sense.
+ */
+extern const signed char *platform_irq_mappings[NR_IRQS];
+
+static unsigned long scp_to_intc_enable[] = {
+#define TO_INTC_ENABLE(n) (((n) << 1) + 1)
+ TO_INTC_ENABLE(0),
+ TO_INTC_ENABLE(1),
+ TO_INTC_ENABLE(2),
+ TO_INTC_ENABLE(3),
+ TO_INTC_ENABLE(4),
+ TO_INTC_ENABLE(5),
+ TO_INTC_ENABLE(6),
+ TO_INTC_ENABLE(7),
+ TO_INTC_ENABLE(8),
+ TO_INTC_ENABLE(9),
+ TO_INTC_ENABLE(10),
+ TO_INTC_ENABLE(11),
+ TO_INTC_ENABLE(12),
+ -1,
+ -1,
+ TO_INTC_ENABLE(13),
+ -1,
+ TO_INTC_ENABLE(14),
+ -1,
+ TO_INTC_ENABLE(15),
+#undef TO_INTC_ENABLE
+};
+
+static void irq_set(unsigned int irq, int enable)
+{
+ unsigned long en;
+ const signed char *m = platform_irq_mappings[irq];
+
+ if (!m)
+ return;
+ en = enable ? scp_to_intc_enable[irq] : 0;
+ while (*m >= 0) {
+ writel(en, S6_REG_INTC + INTC_CFG(*m));
+ m++;
+ }
+}
+
+void variant_irq_enable(unsigned int irq)
+{
+ irq_set(irq, 1);
+}
+
+void variant_irq_disable(unsigned int irq)
+{
+ irq_set(irq, 0);
+}
diff --git a/block/blk-core.c b/block/blk-core.c
index 29bcfac6c688..25572802dac2 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -484,11 +484,11 @@ static int blk_init_free_list(struct request_queue *q)
{
struct request_list *rl = &q->rq;
- rl->count[READ] = rl->count[WRITE] = 0;
- rl->starved[READ] = rl->starved[WRITE] = 0;
+ rl->count[BLK_RW_SYNC] = rl->count[BLK_RW_ASYNC] = 0;
+ rl->starved[BLK_RW_SYNC] = rl->starved[BLK_RW_ASYNC] = 0;
rl->elvpriv = 0;
- init_waitqueue_head(&rl->wait[READ]);
- init_waitqueue_head(&rl->wait[WRITE]);
+ init_waitqueue_head(&rl->wait[BLK_RW_SYNC]);
+ init_waitqueue_head(&rl->wait[BLK_RW_ASYNC]);
rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
mempool_free_slab, request_cachep, q->node);
@@ -603,13 +603,10 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
q->queue_flags = QUEUE_FLAG_DEFAULT;
q->queue_lock = lock;
- blk_queue_segment_boundary(q, BLK_SEG_BOUNDARY_MASK);
-
+ /*
+ * This also sets hw/phys segments, boundary and size
+ */
blk_queue_make_request(q, __make_request);
- blk_queue_max_segment_size(q, MAX_SEGMENT_SIZE);
-
- blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS);
- blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS);
q->sg_reserved_size = INT_MAX;
@@ -702,18 +699,18 @@ static void ioc_set_batching(struct request_queue *q, struct io_context *ioc)
ioc->last_waited = jiffies;
}
-static void __freed_request(struct request_queue *q, int rw)
+static void __freed_request(struct request_queue *q, int sync)
{
struct request_list *rl = &q->rq;
- if (rl->count[rw] < queue_congestion_off_threshold(q))
- blk_clear_queue_congested(q, rw);
+ if (rl->count[sync] < queue_congestion_off_threshold(q))
+ blk_clear_queue_congested(q, sync);
- if (rl->count[rw] + 1 <= q->nr_requests) {
- if (waitqueue_active(&rl->wait[rw]))
- wake_up(&rl->wait[rw]);
+ if (rl->count[sync] + 1 <= q->nr_requests) {
+ if (waitqueue_active(&rl->wait[sync]))
+ wake_up(&rl->wait[sync]);
- blk_clear_queue_full(q, rw);
+ blk_clear_queue_full(q, sync);
}
}
@@ -721,21 +718,20 @@ static void __freed_request(struct request_queue *q, int rw)
* A request has just been released. Account for it, update the full and
* congestion status, wake up any waiters. Called under q->queue_lock.
*/
-static void freed_request(struct request_queue *q, int rw, int priv)
+static void freed_request(struct request_queue *q, int sync, int priv)
{
struct request_list *rl = &q->rq;
- rl->count[rw]--;
+ rl->count[sync]--;
if (priv)
rl->elvpriv--;
- __freed_request(q, rw);
+ __freed_request(q, sync);
- if (unlikely(rl->starved[rw ^ 1]))
- __freed_request(q, rw ^ 1);
+ if (unlikely(rl->starved[sync ^ 1]))
+ __freed_request(q, sync ^ 1);
}
-#define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
/*
* Get a free request, queue_lock must be held.
* Returns NULL on failure, with queue_lock held.
@@ -747,15 +743,15 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
struct request *rq = NULL;
struct request_list *rl = &q->rq;
struct io_context *ioc = NULL;
- const int rw = rw_flags & 0x01;
+ const bool is_sync = rw_is_sync(rw_flags) != 0;
int may_queue, priv;
may_queue = elv_may_queue(q, rw_flags);
if (may_queue == ELV_MQUEUE_NO)
goto rq_starved;
- if (rl->count[rw]+1 >= queue_congestion_on_threshold(q)) {
- if (rl->count[rw]+1 >= q->nr_requests) {
+ if (rl->count[is_sync]+1 >= queue_congestion_on_threshold(q)) {
+ if (rl->count[is_sync]+1 >= q->nr_requests) {
ioc = current_io_context(GFP_ATOMIC, q->node);
/*
* The queue will fill after this allocation, so set
@@ -763,9 +759,9 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
* This process will be allowed to complete a batch of
* requests, others will be blocked.
*/
- if (!blk_queue_full(q, rw)) {
+ if (!blk_queue_full(q, is_sync)) {
ioc_set_batching(q, ioc);
- blk_set_queue_full(q, rw);
+ blk_set_queue_full(q, is_sync);
} else {
if (may_queue != ELV_MQUEUE_MUST
&& !ioc_batching(q, ioc)) {
@@ -778,7 +774,7 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
}
}
}
- blk_set_queue_congested(q, rw);
+ blk_set_queue_congested(q, is_sync);
}
/*
@@ -786,11 +782,11 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
* limit of requests, otherwise we could have thousands of requests
* allocated with any setting of ->nr_requests
*/
- if (rl->count[rw] >= (3 * q->nr_requests / 2))
+ if (rl->count[is_sync] >= (3 * q->nr_requests / 2))
goto out;
- rl->count[rw]++;
- rl->starved[rw] = 0;
+ rl->count[is_sync]++;
+ rl->starved[is_sync] = 0;
priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
if (priv)
@@ -808,7 +804,7 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
* wait queue, but this is pretty rare.
*/
spin_lock_irq(q->queue_lock);
- freed_request(q, rw, priv);
+ freed_request(q, is_sync, priv);
/*
* in the very unlikely event that allocation failed and no
@@ -818,8 +814,8 @@ static struct request *get_request(struct request_queue *q, int rw_flags,
* rq mempool into READ and WRITE
*/
rq_starved:
- if (unlikely(rl->count[rw] == 0))
- rl->starved[rw] = 1;
+ if (unlikely(rl->count[is_sync] == 0))
+ rl->starved[is_sync] = 1;
goto out;
}
@@ -833,7 +829,7 @@ rq_starved:
if (ioc_batching(q, ioc))
ioc->nr_batch_requests--;
- trace_block_getrq(q, bio, rw);
+ trace_block_getrq(q, bio, rw_flags & 1);
out:
return rq;
}
@@ -847,7 +843,7 @@ out:
static struct request *get_request_wait(struct request_queue *q, int rw_flags,
struct bio *bio)
{
- const int rw = rw_flags & 0x01;
+ const bool is_sync = rw_is_sync(rw_flags) != 0;
struct request *rq;
rq = get_request(q, rw_flags, bio, GFP_NOIO);
@@ -856,10 +852,10 @@ static struct request *get_request_wait(struct request_queue *q, int rw_flags,
struct io_context *ioc;
struct request_list *rl = &q->rq;
- prepare_to_wait_exclusive(&rl->wait[rw], &wait,
+ prepare_to_wait_exclusive(&rl->wait[is_sync], &wait,
TASK_UNINTERRUPTIBLE);
- trace_block_sleeprq(q, bio, rw);
+ trace_block_sleeprq(q, bio, rw_flags & 1);
__generic_unplug_device(q);
spin_unlock_irq(q->queue_lock);
@@ -875,7 +871,7 @@ static struct request *get_request_wait(struct request_queue *q, int rw_flags,
ioc_set_batching(q, ioc);
spin_lock_irq(q->queue_lock);
- finish_wait(&rl->wait[rw], &wait);
+ finish_wait(&rl->wait[is_sync], &wait);
rq = get_request(q, rw_flags, bio, GFP_NOIO);
};
@@ -1066,19 +1062,22 @@ void __blk_put_request(struct request_queue *q, struct request *req)
elv_completed_request(q, req);
+ /* this is a bio leak */
+ WARN_ON(req->bio != NULL);
+
/*
* Request may not have originated from ll_rw_blk. if not,
* it didn't come out of our reserved rq pools
*/
if (req->cmd_flags & REQ_ALLOCED) {
- int rw = rq_data_dir(req);
+ int is_sync = rq_is_sync(req) != 0;
int priv = req->cmd_flags & REQ_ELVPRIV;
BUG_ON(!list_empty(&req->queuelist));
BUG_ON(!hlist_unhashed(&req->hash));
blk_free_request(q, req);
- freed_request(q, rw, priv);
+ freed_request(q, is_sync, priv);
}
}
EXPORT_SYMBOL_GPL(__blk_put_request);
@@ -1129,6 +1128,8 @@ void init_request_from_bio(struct request *req, struct bio *bio)
req->cmd_flags |= REQ_UNPLUG;
if (bio_rw_meta(bio))
req->cmd_flags |= REQ_RW_META;
+ if (bio_noidle(bio))
+ req->cmd_flags |= REQ_NOIDLE;
req->errors = 0;
req->hard_sector = req->sector = bio->bi_sector;
@@ -1137,6 +1138,15 @@ void init_request_from_bio(struct request *req, struct bio *bio)
blk_rq_bio_prep(req->q, req, bio);
}
+/*
+ * Only disabling plugging for non-rotational devices if it does tagging
+ * as well, otherwise we do need the proper merging
+ */
+static inline bool queue_should_plug(struct request_queue *q)
+{
+ return !(blk_queue_nonrot(q) && blk_queue_tagged(q));
+}
+
static int __make_request(struct request_queue *q, struct bio *bio)
{
struct request *req;
@@ -1243,11 +1253,11 @@ get_rq:
if (test_bit(QUEUE_FLAG_SAME_COMP, &q->queue_flags) ||
bio_flagged(bio, BIO_CPU_AFFINE))
req->cpu = blk_cpu_to_group(smp_processor_id());
- if (!blk_queue_nonrot(q) && elv_queue_empty(q))
+ if (queue_should_plug(q) && elv_queue_empty(q))
blk_plug_device(q);
add_request(q, req);
out:
- if (unplug || blk_queue_nonrot(q))
+ if (unplug || !queue_should_plug(q))
__generic_unplug_device(q);
spin_unlock_irq(q->queue_lock);
return 0;
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 5a244f05360f..e39cb24b7679 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -403,6 +403,8 @@ static int attempt_merge(struct request_queue *q, struct request *req,
if (blk_rq_cpu_valid(next))
req->cpu = next->cpu;
+ /* owner-ship of bio passed from next to req */
+ next->bio = NULL;
__blk_put_request(q, next);
return 1;
}
diff --git a/block/blk-softirq.c b/block/blk-softirq.c
index ce0efc6b26dc..ee9c21602228 100644
--- a/block/blk-softirq.c
+++ b/block/blk-softirq.c
@@ -64,7 +64,7 @@ static int raise_blk_irq(int cpu, struct request *rq)
data->info = rq;
data->flags = 0;
- __smp_call_function_single(cpu, data);
+ __smp_call_function_single(cpu, data, 0);
return 0;
}
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index e29ddfc73cf4..3ff9bba3379a 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -48,28 +48,28 @@ queue_requests_store(struct request_queue *q, const char *page, size_t count)
q->nr_requests = nr;
blk_queue_congestion_threshold(q);
- if (rl->count[READ] >= queue_congestion_on_threshold(q))
- blk_set_queue_congested(q, READ);
- else if (rl->count[READ] < queue_congestion_off_threshold(q))
- blk_clear_queue_congested(q, READ);
-
- if (rl->count[WRITE] >= queue_congestion_on_threshold(q))
- blk_set_queue_congested(q, WRITE);
- else if (rl->count[WRITE] < queue_congestion_off_threshold(q))
- blk_clear_queue_congested(q, WRITE);
-
- if (rl->count[READ] >= q->nr_requests) {
- blk_set_queue_full(q, READ);
- } else if (rl->count[READ]+1 <= q->nr_requests) {
- blk_clear_queue_full(q, READ);
- wake_up(&rl->wait[READ]);
+ if (rl->count[BLK_RW_SYNC] >= queue_congestion_on_threshold(q))
+ blk_set_queue_congested(q, BLK_RW_SYNC);
+ else if (rl->count[BLK_RW_SYNC] < queue_congestion_off_threshold(q))
+ blk_clear_queue_congested(q, BLK_RW_SYNC);
+
+ if (rl->count[BLK_RW_ASYNC] >= queue_congestion_on_threshold(q))
+ blk_set_queue_congested(q, BLK_RW_ASYNC);
+ else if (rl->count[BLK_RW_ASYNC] < queue_congestion_off_threshold(q))
+ blk_clear_queue_congested(q, BLK_RW_ASYNC);
+
+ if (rl->count[BLK_RW_SYNC] >= q->nr_requests) {
+ blk_set_queue_full(q, BLK_RW_SYNC);
+ } else if (rl->count[BLK_RW_SYNC]+1 <= q->nr_requests) {
+ blk_clear_queue_full(q, BLK_RW_SYNC);
+ wake_up(&rl->wait[BLK_RW_SYNC]);
}
- if (rl->count[WRITE] >= q->nr_requests) {
- blk_set_queue_full(q, WRITE);
- } else if (rl->count[WRITE]+1 <= q->nr_requests) {
- blk_clear_queue_full(q, WRITE);
- wake_up(&rl->wait[WRITE]);
+ if (rl->count[BLK_RW_ASYNC] >= q->nr_requests) {
+ blk_set_queue_full(q, BLK_RW_ASYNC);
+ } else if (rl->count[BLK_RW_ASYNC]+1 <= q->nr_requests) {
+ blk_clear_queue_full(q, BLK_RW_ASYNC);
+ wake_up(&rl->wait[BLK_RW_ASYNC]);
}
spin_unlock_irq(q->queue_lock);
return ret;
diff --git a/block/blk.h b/block/blk.h
index 0dce92c37496..3ee94358b43d 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -102,7 +102,7 @@ static inline int blk_cpu_to_group(int cpu)
const struct cpumask *mask = cpu_coregroup_mask(cpu);
return cpumask_first(mask);
#elif defined(CONFIG_SCHED_SMT)
- return first_cpu(per_cpu(cpu_sibling_map, cpu));
+ return cpumask_first(topology_thread_cpumask(cpu));
#else
return cpu;
#endif
diff --git a/block/bsg.c b/block/bsg.c
index 0ce8806dd0c1..206060e795da 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -218,9 +218,6 @@ bsg_validate_sgv4_hdr(struct request_queue *q, struct sg_io_v4 *hdr, int *rw)
if (hdr->guard != 'Q')
return -EINVAL;
- if (hdr->dout_xfer_len > (q->max_sectors << 9) ||
- hdr->din_xfer_len > (q->max_sectors << 9))
- return -EIO;
switch (hdr->protocol) {
case BSG_PROTOCOL_SCSI:
@@ -353,6 +350,8 @@ static void bsg_rq_end_io(struct request *rq, int uptodate)
static void bsg_add_command(struct bsg_device *bd, struct request_queue *q,
struct bsg_command *bc, struct request *rq)
{
+ int at_head = (0 == (bc->hdr.flags & BSG_FLAG_Q_AT_TAIL));
+
/*
* add bc command to busy queue and submit rq for io
*/
@@ -368,7 +367,7 @@ static void bsg_add_command(struct bsg_device *bd, struct request_queue *q,
dprintk("%s: queueing rq %p, bc %p\n", bd->name, rq, bc);
rq->end_io_data = bc;
- blk_execute_rq_nowait(q, NULL, rq, 1, bsg_rq_end_io);
+ blk_execute_rq_nowait(q, NULL, rq, at_head, bsg_rq_end_io);
}
static struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd)
@@ -924,6 +923,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct request *rq;
struct bio *bio, *bidi_bio = NULL;
struct sg_io_v4 hdr;
+ int at_head;
u8 sense[SCSI_SENSE_BUFFERSIZE];
if (copy_from_user(&hdr, uarg, sizeof(hdr)))
@@ -936,7 +936,9 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
bio = rq->bio;
if (rq->next_rq)
bidi_bio = rq->next_rq->bio;
- blk_execute_rq(bd->queue, NULL, rq, 0);
+
+ at_head = (0 == (hdr.flags & BSG_FLAG_Q_AT_TAIL));
+ blk_execute_rq(bd->queue, NULL, rq, at_head);
ret = blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio);
if (copy_to_user(uarg, &hdr, sizeof(hdr)))
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 664ebfd092ec..9e809345f71a 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -1992,8 +1992,10 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
}
if (cfq_slice_used(cfqq) || cfq_class_idle(cfqq))
cfq_slice_expired(cfqd, 1);
- else if (sync && RB_EMPTY_ROOT(&cfqq->sort_list))
+ else if (sync && !rq_noidle(rq) &&
+ RB_EMPTY_ROOT(&cfqq->sort_list)) {
cfq_arm_slice_timer(cfqd);
+ }
}
if (!cfqd->rq_in_driver)
diff --git a/block/cmd-filter.c b/block/cmd-filter.c
index 504b275e1b90..572bbc2f900d 100644
--- a/block/cmd-filter.c
+++ b/block/cmd-filter.c
@@ -22,6 +22,7 @@
#include <linux/spinlock.h>
#include <linux/capability.h>
#include <linux/bitops.h>
+#include <linux/blkdev.h>
#include <scsi/scsi.h>
#include <linux/cdrom.h>
diff --git a/block/elevator.c b/block/elevator.c
index 98259eda0ef6..ca6788a0195a 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -677,7 +677,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where)
}
if (unplug_it && blk_queue_plugged(q)) {
- int nrq = q->rq.count[READ] + q->rq.count[WRITE]
+ int nrq = q->rq.count[BLK_RW_SYNC] + q->rq.count[BLK_RW_ASYNC]
- q->in_flight;
if (nrq >= q->unplug_thresh)
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index ee9c67d7e1be..626ee274c5c4 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -214,21 +214,10 @@ static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
return 0;
}
-/*
- * unmap a request that was previously mapped to this sg_io_hdr. handles
- * both sg and non-sg sg_io_hdr.
- */
-static int blk_unmap_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr)
-{
- blk_rq_unmap_user(rq->bio);
- blk_put_request(rq);
- return 0;
-}
-
static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
struct bio *bio)
{
- int r, ret = 0;
+ int ret = 0;
/*
* fill in all the output members
@@ -253,12 +242,10 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
ret = -EFAULT;
}
- rq->bio = bio;
- r = blk_unmap_sghdr_rq(rq, hdr);
- if (ret)
- r = ret;
+ blk_rq_unmap_user(bio);
+ blk_put_request(rq);
- return r;
+ return ret;
}
static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 8dde4fcf99c9..74d0e622a515 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -56,6 +56,7 @@ config CRYPTO_BLKCIPHER2
tristate
select CRYPTO_ALGAPI2
select CRYPTO_RNG2
+ select CRYPTO_WORKQUEUE
config CRYPTO_HASH
tristate
@@ -75,6 +76,10 @@ config CRYPTO_RNG2
tristate
select CRYPTO_ALGAPI2
+config CRYPTO_PCOMP
+ tristate
+ select CRYPTO_ALGAPI2
+
config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_MANAGER2
@@ -87,6 +92,7 @@ config CRYPTO_MANAGER2
select CRYPTO_AEAD2
select CRYPTO_HASH2
select CRYPTO_BLKCIPHER2
+ select CRYPTO_PCOMP
config CRYPTO_GF128MUL
tristate "GF(2^128) multiplication functions (EXPERIMENTAL)"
@@ -106,11 +112,15 @@ config CRYPTO_NULL
help
These are 'Null' algorithms, used by IPsec, which do nothing.
+config CRYPTO_WORKQUEUE
+ tristate
+
config CRYPTO_CRYPTD
tristate "Software async crypto daemon"
select CRYPTO_BLKCIPHER
select CRYPTO_HASH
select CRYPTO_MANAGER
+ select CRYPTO_WORKQUEUE
help
This is a generic software asynchronous crypto daemon that
converts an arbitrary synchronous software crypto algorithm
@@ -470,6 +480,31 @@ config CRYPTO_AES_X86_64
See <http://csrc.nist.gov/encryption/aes/> for more information.
+config CRYPTO_AES_NI_INTEL
+ tristate "AES cipher algorithms (AES-NI)"
+ depends on (X86 || UML_X86) && 64BIT
+ select CRYPTO_AES_X86_64
+ select CRYPTO_CRYPTD
+ select CRYPTO_ALGAPI
+ help
+ Use Intel AES-NI instructions for AES algorithm.
+
+ AES cipher algorithms (FIPS-197). AES uses the Rijndael
+ algorithm.
+
+ Rijndael appears to be consistently a very good performer in
+ both hardware and software across a wide range of computing
+ environments regardless of its use in feedback or non-feedback
+ modes. Its key setup time is excellent, and its key agility is
+ good. Rijndael's very low memory requirements make it very well
+ suited for restricted-space environments, in which it also
+ demonstrates excellent performance. Rijndael's operations are
+ among the easiest to defend against power and timing attacks.
+
+ The AES specifies three key sizes: 128, 192 and 256 bits
+
+ See <http://csrc.nist.gov/encryption/aes/> for more information.
+
config CRYPTO_ANUBIS
tristate "Anubis cipher algorithm"
select CRYPTO_ALGAPI
@@ -714,6 +749,15 @@ config CRYPTO_DEFLATE
You will most probably want this if using IPSec.
+config CRYPTO_ZLIB
+ tristate "Zlib compression algorithm"
+ select CRYPTO_PCOMP
+ select ZLIB_INFLATE
+ select ZLIB_DEFLATE
+ select NLATTR
+ help
+ This is the zlib algorithm.
+
config CRYPTO_LZO
tristate "LZO compression algorithm"
select CRYPTO_ALGAPI
diff --git a/crypto/Makefile b/crypto/Makefile
index 46b08bf2035f..673d9f7c1bda 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -5,6 +5,8 @@
obj-$(CONFIG_CRYPTO) += crypto.o
crypto-objs := api.o cipher.o digest.o compress.o
+obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o
+
obj-$(CONFIG_CRYPTO_FIPS) += fips.o
crypto_algapi-$(CONFIG_PROC_FS) += proc.o
@@ -25,6 +27,8 @@ crypto_hash-objs += ahash.o
crypto_hash-objs += shash.o
obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
+obj-$(CONFIG_CRYPTO_PCOMP) += pcompress.o
+
cryptomgr-objs := algboss.o testmgr.o
obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
@@ -70,6 +74,7 @@ obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o
obj-$(CONFIG_CRYPTO_SEED) += seed.o
obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o
obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
+obj-$(CONFIG_CRYPTO_ZLIB) += zlib.o
obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
index 94140b3756fc..e11ce37c7104 100644
--- a/crypto/ablkcipher.c
+++ b/crypto/ablkcipher.c
@@ -282,6 +282,25 @@ static struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type,
alg->cra_ablkcipher.ivsize))
return alg;
+ crypto_mod_put(alg);
+ alg = crypto_alg_mod_lookup(name, type | CRYPTO_ALG_TESTED,
+ mask & ~CRYPTO_ALG_TESTED);
+ if (IS_ERR(alg))
+ return alg;
+
+ if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+ CRYPTO_ALG_TYPE_GIVCIPHER) {
+ if ((alg->cra_flags ^ type ^ ~mask) & CRYPTO_ALG_TESTED) {
+ crypto_mod_put(alg);
+ alg = ERR_PTR(-ENOENT);
+ }
+ return alg;
+ }
+
+ BUG_ON(!((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+ CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize :
+ alg->cra_ablkcipher.ivsize));
+
return ERR_PTR(crypto_givcipher_default(alg, type, mask));
}
diff --git a/crypto/aead.c b/crypto/aead.c
index 3a6f3f52c7c7..d9aa733db164 100644
--- a/crypto/aead.c
+++ b/crypto/aead.c
@@ -422,6 +422,22 @@ static struct crypto_alg *crypto_lookup_aead(const char *name, u32 type,
if (!alg->cra_aead.ivsize)
return alg;
+ crypto_mod_put(alg);
+ alg = crypto_alg_mod_lookup(name, type | CRYPTO_ALG_TESTED,
+ mask & ~CRYPTO_ALG_TESTED);
+ if (IS_ERR(alg))
+ return alg;
+
+ if (alg->cra_type == &crypto_aead_type) {
+ if ((alg->cra_flags ^ type ^ ~mask) & CRYPTO_ALG_TESTED) {
+ crypto_mod_put(alg);
+ alg = ERR_PTR(-ENOENT);
+ }
+ return alg;
+ }
+
+ BUG_ON(!alg->cra_aead.ivsize);
+
return ERR_PTR(crypto_nivaead_default(alg, type, mask));
}
diff --git a/crypto/algboss.c b/crypto/algboss.c
index 4601e4267c88..6906f92aeac0 100644
--- a/crypto/algboss.c
+++ b/crypto/algboss.c
@@ -10,7 +10,7 @@
*
*/
-#include <linux/crypto.h>
+#include <crypto/internal/aead.h>
#include <linux/ctype.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -206,8 +206,7 @@ static int cryptomgr_test(void *data)
u32 type = param->type;
int err = 0;
- if (!((type ^ CRYPTO_ALG_TYPE_BLKCIPHER) &
- CRYPTO_ALG_TYPE_BLKCIPHER_MASK) && !(type & CRYPTO_ALG_GENIV))
+ if (type & CRYPTO_ALG_TESTED)
goto skiptest;
err = alg_test(param->driver, param->alg, type, CRYPTO_ALG_TESTED);
@@ -223,6 +222,7 @@ static int cryptomgr_schedule_test(struct crypto_alg *alg)
{
struct task_struct *thread;
struct crypto_test_param *param;
+ u32 type;
if (!try_module_get(THIS_MODULE))
goto err;
@@ -233,7 +233,19 @@ static int cryptomgr_schedule_test(struct crypto_alg *alg)
memcpy(param->driver, alg->cra_driver_name, sizeof(param->driver));
memcpy(param->alg, alg->cra_name, sizeof(param->alg));
- param->type = alg->cra_flags;
+ type = alg->cra_flags;
+
+ /* This piece of crap needs to disappear into per-type test hooks. */
+ if ((!((type ^ CRYPTO_ALG_TYPE_BLKCIPHER) &
+ CRYPTO_ALG_TYPE_BLKCIPHER_MASK) && !(type & CRYPTO_ALG_GENIV) &&
+ ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+ CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize :
+ alg->cra_ablkcipher.ivsize)) ||
+ (!((type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK) &&
+ alg->cra_type == &crypto_nivaead_type && alg->cra_aead.ivsize))
+ type |= CRYPTO_ALG_TESTED;
+
+ param->type = type;
thread = kthread_run(cryptomgr_test, param, "cryptomgr_test");
if (IS_ERR(thread))
diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c
index 0fac8ffc2fb7..d80ed4c1e009 100644
--- a/crypto/ansi_cprng.c
+++ b/crypto/ansi_cprng.c
@@ -132,9 +132,15 @@ static int _get_more_prng_bytes(struct prng_context *ctx)
*/
if (!memcmp(ctx->rand_data, ctx->last_rand_data,
DEFAULT_BLK_SZ)) {
+ if (fips_enabled) {
+ panic("cprng %p Failed repetition check!\n",
+ ctx);
+ }
+
printk(KERN_ERR
"ctx %p Failed repetition check!\n",
ctx);
+
ctx->flags |= PRNG_NEED_RESET;
return -EINVAL;
}
@@ -338,7 +344,16 @@ static int cprng_init(struct crypto_tfm *tfm)
spin_lock_init(&ctx->prng_lock);
- return reset_prng_context(ctx, NULL, DEFAULT_PRNG_KSZ, NULL, NULL);
+ if (reset_prng_context(ctx, NULL, DEFAULT_PRNG_KSZ, NULL, NULL) < 0)
+ return -EINVAL;
+
+ /*
+ * after allocation, we should always force the user to reset
+ * so they don't inadvertently use the insecure default values
+ * without specifying them intentially
+ */
+ ctx->flags |= PRNG_NEED_RESET;
+ return 0;
}
static void cprng_exit(struct crypto_tfm *tfm)
diff --git a/crypto/api.c b/crypto/api.c
index 38a2bc02a98c..314dab96840e 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -255,7 +255,7 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
struct crypto_alg *larval;
int ok;
- if (!(mask & CRYPTO_ALG_TESTED)) {
+ if (!((type | mask) & CRYPTO_ALG_TESTED)) {
type |= CRYPTO_ALG_TESTED;
mask |= CRYPTO_ALG_TESTED;
}
@@ -464,8 +464,8 @@ err:
}
EXPORT_SYMBOL_GPL(crypto_alloc_base);
-struct crypto_tfm *crypto_create_tfm(struct crypto_alg *alg,
- const struct crypto_type *frontend)
+void *crypto_create_tfm(struct crypto_alg *alg,
+ const struct crypto_type *frontend)
{
char *mem;
struct crypto_tfm *tfm = NULL;
@@ -499,9 +499,9 @@ out_free_tfm:
crypto_shoot_alg(alg);
kfree(mem);
out_err:
- tfm = ERR_PTR(err);
+ mem = ERR_PTR(err);
out:
- return tfm;
+ return mem;
}
EXPORT_SYMBOL_GPL(crypto_create_tfm);
@@ -525,12 +525,11 @@ EXPORT_SYMBOL_GPL(crypto_create_tfm);
*
* In case of error the return value is an error pointer.
*/
-struct crypto_tfm *crypto_alloc_tfm(const char *alg_name,
- const struct crypto_type *frontend,
- u32 type, u32 mask)
+void *crypto_alloc_tfm(const char *alg_name,
+ const struct crypto_type *frontend, u32 type, u32 mask)
{
struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask);
- struct crypto_tfm *tfm;
+ void *tfm;
int err;
type &= frontend->maskclear;
diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
index f21147f3626a..06eb6cc09fef 100644
--- a/crypto/async_tx/async_tx.c
+++ b/crypto/async_tx/async_tx.c
@@ -30,7 +30,7 @@
#ifdef CONFIG_DMA_ENGINE
static int __init async_tx_init(void)
{
- dmaengine_get();
+ async_dmaengine_get();
printk(KERN_INFO "async_tx: api initialized (async)\n");
@@ -39,7 +39,7 @@ static int __init async_tx_init(void)
static void __exit async_tx_exit(void)
{
- dmaengine_put();
+ async_dmaengine_put();
}
/**
@@ -56,7 +56,7 @@ __async_tx_find_channel(struct dma_async_tx_descriptor *depend_tx,
if (depend_tx &&
dma_has_cap(tx_type, depend_tx->chan->device->cap_mask))
return depend_tx->chan;
- return dma_find_channel(tx_type);
+ return async_dma_find_channel(tx_type);
}
EXPORT_SYMBOL_GPL(__async_tx_find_channel);
#else
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index 595b78672b36..95fe2c8d6c51 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -30,11 +30,8 @@
#include <linux/raid/xor.h>
#include <linux/async_tx.h>
-/* do_async_xor - dma map the pages and perform the xor with an engine.
- * This routine is marked __always_inline so it can be compiled away
- * when CONFIG_DMA_ENGINE=n
- */
-static __always_inline struct dma_async_tx_descriptor *
+/* do_async_xor - dma map the pages and perform the xor with an engine */
+static __async_inline struct dma_async_tx_descriptor *
do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list,
unsigned int offset, int src_cnt, size_t len,
enum async_tx_flags flags,
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index d70a41c002df..90d26c91f4e9 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -521,7 +521,7 @@ static int crypto_grab_nivcipher(struct crypto_skcipher_spawn *spawn,
int err;
type = crypto_skcipher_type(type);
- mask = crypto_skcipher_mask(mask) | CRYPTO_ALG_GENIV;
+ mask = crypto_skcipher_mask(mask)| CRYPTO_ALG_GENIV;
alg = crypto_alg_mod_lookup(name, type, mask);
if (IS_ERR(alg))
diff --git a/crypto/chainiv.c b/crypto/chainiv.c
index 7c37a497b860..ba200b07449d 100644
--- a/crypto/chainiv.c
+++ b/crypto/chainiv.c
@@ -15,6 +15,7 @@
#include <crypto/internal/skcipher.h>
#include <crypto/rng.h>
+#include <crypto/crypto_wq.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -133,7 +134,7 @@ static int async_chainiv_schedule_work(struct async_chainiv_ctx *ctx)
goto out;
}
- queued = schedule_work(&ctx->postponed);
+ queued = queue_work(kcrypto_wq, &ctx->postponed);
BUG_ON(!queued);
out:
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index d29e06b350ff..d14b22658d7a 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -12,30 +12,31 @@
#include <crypto/algapi.h>
#include <crypto/internal/hash.h>
+#include <crypto/cryptd.h>
+#include <crypto/crypto_wq.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/kthread.h>
#include <linux/list.h>
#include <linux/module.h>
-#include <linux/mutex.h>
#include <linux/scatterlist.h>
#include <linux/sched.h>
#include <linux/slab.h>
-#include <linux/spinlock.h>
-#define CRYPTD_MAX_QLEN 100
+#define CRYPTD_MAX_CPU_QLEN 100
-struct cryptd_state {
- spinlock_t lock;
- struct mutex mutex;
+struct cryptd_cpu_queue {
struct crypto_queue queue;
- struct task_struct *task;
+ struct work_struct work;
+};
+
+struct cryptd_queue {
+ struct cryptd_cpu_queue *cpu_queue;
};
struct cryptd_instance_ctx {
struct crypto_spawn spawn;
- struct cryptd_state *state;
+ struct cryptd_queue *queue;
};
struct cryptd_blkcipher_ctx {
@@ -54,11 +55,85 @@ struct cryptd_hash_request_ctx {
crypto_completion_t complete;
};
-static inline struct cryptd_state *cryptd_get_state(struct crypto_tfm *tfm)
+static void cryptd_queue_worker(struct work_struct *work);
+
+static int cryptd_init_queue(struct cryptd_queue *queue,
+ unsigned int max_cpu_qlen)
+{
+ int cpu;
+ struct cryptd_cpu_queue *cpu_queue;
+
+ queue->cpu_queue = alloc_percpu(struct cryptd_cpu_queue);
+ if (!queue->cpu_queue)
+ return -ENOMEM;
+ for_each_possible_cpu(cpu) {
+ cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu);
+ crypto_init_queue(&cpu_queue->queue, max_cpu_qlen);
+ INIT_WORK(&cpu_queue->work, cryptd_queue_worker);
+ }
+ return 0;
+}
+
+static void cryptd_fini_queue(struct cryptd_queue *queue)
+{
+ int cpu;
+ struct cryptd_cpu_queue *cpu_queue;
+
+ for_each_possible_cpu(cpu) {
+ cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu);
+ BUG_ON(cpu_queue->queue.qlen);
+ }
+ free_percpu(queue->cpu_queue);
+}
+
+static int cryptd_enqueue_request(struct cryptd_queue *queue,
+ struct crypto_async_request *request)
+{
+ int cpu, err;
+ struct cryptd_cpu_queue *cpu_queue;
+
+ cpu = get_cpu();
+ cpu_queue = per_cpu_ptr(queue->cpu_queue, cpu);
+ err = crypto_enqueue_request(&cpu_queue->queue, request);
+ queue_work_on(cpu, kcrypto_wq, &cpu_queue->work);
+ put_cpu();
+
+ return err;
+}
+
+/* Called in workqueue context, do one real cryption work (via
+ * req->complete) and reschedule itself if there are more work to
+ * do. */
+static void cryptd_queue_worker(struct work_struct *work)
+{
+ struct cryptd_cpu_queue *cpu_queue;
+ struct crypto_async_request *req, *backlog;
+
+ cpu_queue = container_of(work, struct cryptd_cpu_queue, work);
+ /* Only handle one request at a time to avoid hogging crypto
+ * workqueue. preempt_disable/enable is used to prevent
+ * being preempted by cryptd_enqueue_request() */
+ preempt_disable();
+ backlog = crypto_get_backlog(&cpu_queue->queue);
+ req = crypto_dequeue_request(&cpu_queue->queue);
+ preempt_enable();
+
+ if (!req)
+ return;
+
+ if (backlog)
+ backlog->complete(backlog, -EINPROGRESS);
+ req->complete(req, 0);
+
+ if (cpu_queue->queue.qlen)
+ queue_work(kcrypto_wq, &cpu_queue->work);
+}
+
+static inline struct cryptd_queue *cryptd_get_queue(struct crypto_tfm *tfm)
{
struct crypto_instance *inst = crypto_tfm_alg_instance(tfm);
struct cryptd_instance_ctx *ictx = crypto_instance_ctx(inst);
- return ictx->state;
+ return ictx->queue;
}
static int cryptd_blkcipher_setkey(struct crypto_ablkcipher *parent,
@@ -130,19 +205,13 @@ static int cryptd_blkcipher_enqueue(struct ablkcipher_request *req,
{
struct cryptd_blkcipher_request_ctx *rctx = ablkcipher_request_ctx(req);
struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
- struct cryptd_state *state =
- cryptd_get_state(crypto_ablkcipher_tfm(tfm));
- int err;
+ struct cryptd_queue *queue;
+ queue = cryptd_get_queue(crypto_ablkcipher_tfm(tfm));
rctx->complete = req->base.complete;
req->base.complete = complete;
- spin_lock_bh(&state->lock);
- err = ablkcipher_enqueue_request(&state->queue, req);
- spin_unlock_bh(&state->lock);
-
- wake_up_process(state->task);
- return err;
+ return cryptd_enqueue_request(queue, &req->base);
}
static int cryptd_blkcipher_encrypt_enqueue(struct ablkcipher_request *req)
@@ -176,21 +245,12 @@ static int cryptd_blkcipher_init_tfm(struct crypto_tfm *tfm)
static void cryptd_blkcipher_exit_tfm(struct crypto_tfm *tfm)
{
struct cryptd_blkcipher_ctx *ctx = crypto_tfm_ctx(tfm);
- struct cryptd_state *state = cryptd_get_state(tfm);
- int active;
-
- mutex_lock(&state->mutex);
- active = ablkcipher_tfm_in_queue(&state->queue,
- __crypto_ablkcipher_cast(tfm));
- mutex_unlock(&state->mutex);
-
- BUG_ON(active);
crypto_free_blkcipher(ctx->child);
}
static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg,
- struct cryptd_state *state)
+ struct cryptd_queue *queue)
{
struct crypto_instance *inst;
struct cryptd_instance_ctx *ctx;
@@ -213,7 +273,7 @@ static struct crypto_instance *cryptd_alloc_instance(struct crypto_alg *alg,
if (err)
goto out_free_inst;
- ctx->state = state;
+ ctx->queue = queue;
memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME);
@@ -231,7 +291,7 @@ out_free_inst:
}
static struct crypto_instance *cryptd_alloc_blkcipher(
- struct rtattr **tb, struct cryptd_state *state)
+ struct rtattr **tb, struct cryptd_queue *queue)
{
struct crypto_instance *inst;
struct crypto_alg *alg;
@@ -241,7 +301,7 @@ static struct crypto_instance *cryptd_alloc_blkcipher(
if (IS_ERR(alg))
return ERR_CAST(alg);
- inst = cryptd_alloc_instance(alg, state);
+ inst = cryptd_alloc_instance(alg, queue);
if (IS_ERR(inst))
goto out_put_alg;
@@ -289,15 +349,6 @@ static int cryptd_hash_init_tfm(struct crypto_tfm *tfm)
static void cryptd_hash_exit_tfm(struct crypto_tfm *tfm)
{
struct cryptd_hash_ctx *ctx = crypto_tfm_ctx(tfm);
- struct cryptd_state *state = cryptd_get_state(tfm);
- int active;
-
- mutex_lock(&state->mutex);
- active = ahash_tfm_in_queue(&state->queue,
- __crypto_ahash_cast(tfm));
- mutex_unlock(&state->mutex);
-
- BUG_ON(active);
crypto_free_hash(ctx->child);
}
@@ -323,19 +374,13 @@ static int cryptd_hash_enqueue(struct ahash_request *req,
{
struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
- struct cryptd_state *state =
- cryptd_get_state(crypto_ahash_tfm(tfm));
- int err;
+ struct cryptd_queue *queue =
+ cryptd_get_queue(crypto_ahash_tfm(tfm));
rctx->complete = req->base.complete;
req->base.complete = complete;
- spin_lock_bh(&state->lock);
- err = ahash_enqueue_request(&state->queue, req);
- spin_unlock_bh(&state->lock);
-
- wake_up_process(state->task);
- return err;
+ return cryptd_enqueue_request(queue, &req->base);
}
static void cryptd_hash_init(struct crypto_async_request *req_async, int err)
@@ -468,7 +513,7 @@ static int cryptd_hash_digest_enqueue(struct ahash_request *req)
}
static struct crypto_instance *cryptd_alloc_hash(
- struct rtattr **tb, struct cryptd_state *state)
+ struct rtattr **tb, struct cryptd_queue *queue)
{
struct crypto_instance *inst;
struct crypto_alg *alg;
@@ -478,7 +523,7 @@ static struct crypto_instance *cryptd_alloc_hash(
if (IS_ERR(alg))
return ERR_PTR(PTR_ERR(alg));
- inst = cryptd_alloc_instance(alg, state);
+ inst = cryptd_alloc_instance(alg, queue);
if (IS_ERR(inst))
goto out_put_alg;
@@ -502,7 +547,7 @@ out_put_alg:
return inst;
}
-static struct cryptd_state state;
+static struct cryptd_queue queue;
static struct crypto_instance *cryptd_alloc(struct rtattr **tb)
{
@@ -514,9 +559,9 @@ static struct crypto_instance *cryptd_alloc(struct rtattr **tb)
switch (algt->type & algt->mask & CRYPTO_ALG_TYPE_MASK) {
case CRYPTO_ALG_TYPE_BLKCIPHER:
- return cryptd_alloc_blkcipher(tb, &state);
+ return cryptd_alloc_blkcipher(tb, &queue);
case CRYPTO_ALG_TYPE_DIGEST:
- return cryptd_alloc_hash(tb, &state);
+ return cryptd_alloc_hash(tb, &queue);
}
return ERR_PTR(-EINVAL);
@@ -537,82 +582,58 @@ static struct crypto_template cryptd_tmpl = {
.module = THIS_MODULE,
};
-static inline int cryptd_create_thread(struct cryptd_state *state,
- int (*fn)(void *data), const char *name)
-{
- spin_lock_init(&state->lock);
- mutex_init(&state->mutex);
- crypto_init_queue(&state->queue, CRYPTD_MAX_QLEN);
-
- state->task = kthread_run(fn, state, name);
- if (IS_ERR(state->task))
- return PTR_ERR(state->task);
+struct cryptd_ablkcipher *cryptd_alloc_ablkcipher(const char *alg_name,
+ u32 type, u32 mask)
+{
+ char cryptd_alg_name[CRYPTO_MAX_ALG_NAME];
+ struct crypto_ablkcipher *tfm;
+
+ if (snprintf(cryptd_alg_name, CRYPTO_MAX_ALG_NAME,
+ "cryptd(%s)", alg_name) >= CRYPTO_MAX_ALG_NAME)
+ return ERR_PTR(-EINVAL);
+ tfm = crypto_alloc_ablkcipher(cryptd_alg_name, type, mask);
+ if (IS_ERR(tfm))
+ return ERR_CAST(tfm);
+ if (crypto_ablkcipher_tfm(tfm)->__crt_alg->cra_module != THIS_MODULE) {
+ crypto_free_ablkcipher(tfm);
+ return ERR_PTR(-EINVAL);
+ }
- return 0;
+ return __cryptd_ablkcipher_cast(tfm);
}
+EXPORT_SYMBOL_GPL(cryptd_alloc_ablkcipher);
-static inline void cryptd_stop_thread(struct cryptd_state *state)
+struct crypto_blkcipher *cryptd_ablkcipher_child(struct cryptd_ablkcipher *tfm)
{
- BUG_ON(state->queue.qlen);
- kthread_stop(state->task);
+ struct cryptd_blkcipher_ctx *ctx = crypto_ablkcipher_ctx(&tfm->base);
+ return ctx->child;
}
+EXPORT_SYMBOL_GPL(cryptd_ablkcipher_child);
-static int cryptd_thread(void *data)
+void cryptd_free_ablkcipher(struct cryptd_ablkcipher *tfm)
{
- struct cryptd_state *state = data;
- int stop;
-
- current->flags |= PF_NOFREEZE;
-
- do {
- struct crypto_async_request *req, *backlog;
-
- mutex_lock(&state->mutex);
- __set_current_state(TASK_INTERRUPTIBLE);
-
- spin_lock_bh(&state->lock);
- backlog = crypto_get_backlog(&state->queue);
- req = crypto_dequeue_request(&state->queue);
- spin_unlock_bh(&state->lock);
-
- stop = kthread_should_stop();
-
- if (stop || req) {
- __set_current_state(TASK_RUNNING);
- if (req) {
- if (backlog)
- backlog->complete(backlog,
- -EINPROGRESS);
- req->complete(req, 0);
- }
- }
-
- mutex_unlock(&state->mutex);
-
- schedule();
- } while (!stop);
-
- return 0;
+ crypto_free_ablkcipher(&tfm->base);
}
+EXPORT_SYMBOL_GPL(cryptd_free_ablkcipher);
static int __init cryptd_init(void)
{
int err;
- err = cryptd_create_thread(&state, cryptd_thread, "cryptd");
+ err = cryptd_init_queue(&queue, CRYPTD_MAX_CPU_QLEN);
if (err)
return err;
err = crypto_register_template(&cryptd_tmpl);
if (err)
- kthread_stop(state.task);
+ cryptd_fini_queue(&queue);
return err;
}
static void __exit cryptd_exit(void)
{
- cryptd_stop_thread(&state);
+ cryptd_fini_queue(&queue);
crypto_unregister_template(&cryptd_tmpl);
}
diff --git a/crypto/crypto_wq.c b/crypto/crypto_wq.c
new file mode 100644
index 000000000000..fdcf6248f152
--- /dev/null
+++ b/crypto/crypto_wq.c
@@ -0,0 +1,38 @@
+/*
+ * Workqueue for crypto subsystem
+ *
+ * Copyright (c) 2009 Intel Corp.
+ * Author: Huang Ying <ying.huang@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <linux/workqueue.h>
+#include <crypto/algapi.h>
+#include <crypto/crypto_wq.h>
+
+struct workqueue_struct *kcrypto_wq;
+EXPORT_SYMBOL_GPL(kcrypto_wq);
+
+static int __init crypto_wq_init(void)
+{
+ kcrypto_wq = create_workqueue("crypto");
+ if (unlikely(!kcrypto_wq))
+ return -ENOMEM;
+ return 0;
+}
+
+static void __exit crypto_wq_exit(void)
+{
+ destroy_workqueue(kcrypto_wq);
+}
+
+module_init(crypto_wq_init);
+module_exit(crypto_wq_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Workqueue for crypto subsystem");
diff --git a/crypto/gf128mul.c b/crypto/gf128mul.c
index ecbeaa1f17e1..a90d260528d4 100644
--- a/crypto/gf128mul.c
+++ b/crypto/gf128mul.c
@@ -4,7 +4,7 @@
* Copyright (c) 2006, Rik Snel <rsnel@cube.dyndns.org>
*
* Based on Dr Brian Gladman's (GPL'd) work published at
- * http://fp.gladman.plus.com/cryptography_technology/index.htm
+ * http://gladman.plushost.co.uk/oldsite/cryptography_technology/index.php
* See the original copyright notice below.
*
* This program is free software; you can redistribute it and/or modify it
diff --git a/crypto/internal.h b/crypto/internal.h
index 3c19a27a7563..fc76e1f37fc3 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -109,8 +109,10 @@ void crypto_alg_tested(const char *name, int err);
void crypto_shoot_alg(struct crypto_alg *alg);
struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
u32 mask);
-struct crypto_tfm *crypto_create_tfm(struct crypto_alg *alg,
- const struct crypto_type *frontend);
+void *crypto_create_tfm(struct crypto_alg *alg,
+ const struct crypto_type *frontend);
+void *crypto_alloc_tfm(const char *alg_name,
+ const struct crypto_type *frontend, u32 type, u32 mask);
int crypto_register_instance(struct crypto_template *tmpl,
struct crypto_instance *inst);
diff --git a/crypto/pcompress.c b/crypto/pcompress.c
new file mode 100644
index 000000000000..ca9a4af91efe
--- /dev/null
+++ b/crypto/pcompress.c
@@ -0,0 +1,97 @@
+/*
+ * Cryptographic API.
+ *
+ * Partial (de)compression operations.
+ *
+ * Copyright 2008 Sony Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/crypto.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/string.h>
+
+#include <crypto/compress.h>
+
+#include "internal.h"
+
+
+static int crypto_pcomp_init(struct crypto_tfm *tfm, u32 type, u32 mask)
+{
+ return 0;
+}
+
+static unsigned int crypto_pcomp_extsize(struct crypto_alg *alg,
+ const struct crypto_type *frontend)
+{
+ return alg->cra_ctxsize;
+}
+
+static int crypto_pcomp_init_tfm(struct crypto_tfm *tfm,
+ const struct crypto_type *frontend)
+{
+ return 0;
+}
+
+static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg)
+ __attribute__ ((unused));
+static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg)
+{
+ seq_printf(m, "type : pcomp\n");
+}
+
+static const struct crypto_type crypto_pcomp_type = {
+ .extsize = crypto_pcomp_extsize,
+ .init = crypto_pcomp_init,
+ .init_tfm = crypto_pcomp_init_tfm,
+#ifdef CONFIG_PROC_FS
+ .show = crypto_pcomp_show,
+#endif
+ .maskclear = ~CRYPTO_ALG_TYPE_MASK,
+ .maskset = CRYPTO_ALG_TYPE_MASK,
+ .type = CRYPTO_ALG_TYPE_PCOMPRESS,
+ .tfmsize = offsetof(struct crypto_pcomp, base),
+};
+
+struct crypto_pcomp *crypto_alloc_pcomp(const char *alg_name, u32 type,
+ u32 mask)
+{
+ return crypto_alloc_tfm(alg_name, &crypto_pcomp_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_pcomp);
+
+int crypto_register_pcomp(struct pcomp_alg *alg)
+{
+ struct crypto_alg *base = &alg->base;
+
+ base->cra_type = &crypto_pcomp_type;
+ base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
+ base->cra_flags |= CRYPTO_ALG_TYPE_PCOMPRESS;
+
+ return crypto_register_alg(base);
+}
+EXPORT_SYMBOL_GPL(crypto_register_pcomp);
+
+int crypto_unregister_pcomp(struct pcomp_alg *alg)
+{
+ return crypto_unregister_alg(&alg->base);
+}
+EXPORT_SYMBOL_GPL(crypto_unregister_pcomp);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Partial (de)compression type");
+MODULE_AUTHOR("Sony Corporation");
diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c
index caa3542e6ce8..6349d8339d37 100644
--- a/crypto/sha256_generic.c
+++ b/crypto/sha256_generic.c
@@ -2,7 +2,7 @@
* Cryptographic API.
*
* SHA-256, as specified in
- * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
+ * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf
*
* SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>.
*
diff --git a/crypto/shash.c b/crypto/shash.c
index d5a2b619c55f..2ccc8b0076ce 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -18,15 +18,10 @@
#include <linux/slab.h>
#include <linux/seq_file.h>
-static const struct crypto_type crypto_shash_type;
-
-static inline struct crypto_shash *__crypto_shash_cast(struct crypto_tfm *tfm)
-{
- return container_of(tfm, struct crypto_shash, base);
-}
-
#include "internal.h"
+static const struct crypto_type crypto_shash_type;
+
static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
unsigned int keylen)
{
@@ -82,6 +77,9 @@ static int shash_update_unaligned(struct shash_desc *desc, const u8 *data,
u8 buf[shash_align_buffer_size(unaligned_len, alignmask)]
__attribute__ ((aligned));
+ if (unaligned_len > len)
+ unaligned_len = len;
+
memcpy(buf, data, unaligned_len);
return shash->update(desc, buf, unaligned_len) ?:
@@ -282,8 +280,7 @@ static int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
if (!crypto_mod_get(calg))
return -EAGAIN;
- shash = __crypto_shash_cast(crypto_create_tfm(
- calg, &crypto_shash_type));
+ shash = crypto_create_tfm(calg, &crypto_shash_type);
if (IS_ERR(shash)) {
crypto_mod_put(calg);
return PTR_ERR(shash);
@@ -391,8 +388,7 @@ static int crypto_init_shash_ops_compat(struct crypto_tfm *tfm)
if (!crypto_mod_get(calg))
return -EAGAIN;
- shash = __crypto_shash_cast(crypto_create_tfm(
- calg, &crypto_shash_type));
+ shash = crypto_create_tfm(calg, &crypto_shash_type);
if (IS_ERR(shash)) {
crypto_mod_put(calg);
return PTR_ERR(shash);
@@ -442,8 +438,6 @@ static unsigned int crypto_shash_ctxsize(struct crypto_alg *alg, u32 type,
static int crypto_shash_init_tfm(struct crypto_tfm *tfm,
const struct crypto_type *frontend)
{
- if (frontend->type != CRYPTO_ALG_TYPE_SHASH)
- return -EINVAL;
return 0;
}
@@ -482,8 +476,7 @@ static const struct crypto_type crypto_shash_type = {
struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
u32 mask)
{
- return __crypto_shash_cast(
- crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask));
+ return crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask);
}
EXPORT_SYMBOL_GPL(crypto_alloc_shash);
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 28a45a1e6f42..c3c9124209a1 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -53,7 +53,7 @@ static char *check[] = {
"cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
"khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt",
"camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320",
- "lzo", "cts", NULL
+ "lzo", "cts", "zlib", NULL
};
static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc,
@@ -661,6 +661,10 @@ static void do_test(int m)
tcrypt_test("ecb(seed)");
break;
+ case 44:
+ tcrypt_test("zlib");
+ break;
+
case 100:
tcrypt_test("hmac(md5)");
break;
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index a75f11ffb957..b50c3c6b17a2 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -72,6 +72,13 @@ struct comp_test_suite {
} comp, decomp;
};
+struct pcomp_test_suite {
+ struct {
+ struct pcomp_testvec *vecs;
+ unsigned int count;
+ } comp, decomp;
+};
+
struct hash_test_suite {
struct hash_testvec *vecs;
unsigned int count;
@@ -86,6 +93,7 @@ struct alg_test_desc {
struct aead_test_suite aead;
struct cipher_test_suite cipher;
struct comp_test_suite comp;
+ struct pcomp_test_suite pcomp;
struct hash_test_suite hash;
} suite;
};
@@ -898,6 +906,159 @@ out:
return ret;
}
+static int test_pcomp(struct crypto_pcomp *tfm,
+ struct pcomp_testvec *ctemplate,
+ struct pcomp_testvec *dtemplate, int ctcount,
+ int dtcount)
+{
+ const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm));
+ unsigned int i;
+ char result[COMP_BUF_SIZE];
+ int error;
+
+ for (i = 0; i < ctcount; i++) {
+ struct comp_request req;
+
+ error = crypto_compress_setup(tfm, ctemplate[i].params,
+ ctemplate[i].paramsize);
+ if (error) {
+ pr_err("alg: pcomp: compression setup failed on test "
+ "%d for %s: error=%d\n", i + 1, algo, error);
+ return error;
+ }
+
+ error = crypto_compress_init(tfm);
+ if (error) {
+ pr_err("alg: pcomp: compression init failed on test "
+ "%d for %s: error=%d\n", i + 1, algo, error);
+ return error;
+ }
+
+ memset(result, 0, sizeof(result));
+
+ req.next_in = ctemplate[i].input;
+ req.avail_in = ctemplate[i].inlen / 2;
+ req.next_out = result;
+ req.avail_out = ctemplate[i].outlen / 2;
+
+ error = crypto_compress_update(tfm, &req);
+ if (error && (error != -EAGAIN || req.avail_in)) {
+ pr_err("alg: pcomp: compression update failed on test "
+ "%d for %s: error=%d\n", i + 1, algo, error);
+ return error;
+ }
+
+ /* Add remaining input data */
+ req.avail_in += (ctemplate[i].inlen + 1) / 2;
+
+ error = crypto_compress_update(tfm, &req);
+ if (error && (error != -EAGAIN || req.avail_in)) {
+ pr_err("alg: pcomp: compression update failed on test "
+ "%d for %s: error=%d\n", i + 1, algo, error);
+ return error;
+ }
+
+ /* Provide remaining output space */
+ req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2;
+
+ error = crypto_compress_final(tfm, &req);
+ if (error) {
+ pr_err("alg: pcomp: compression final failed on test "
+ "%d for %s: error=%d\n", i + 1, algo, error);
+ return error;
+ }
+
+ if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) {
+ pr_err("alg: comp: Compression test %d failed for %s: "
+ "output len = %d (expected %d)\n", i + 1, algo,
+ COMP_BUF_SIZE - req.avail_out,
+ ctemplate[i].outlen);
+ return -EINVAL;
+ }
+
+ if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) {
+ pr_err("alg: pcomp: Compression test %d failed for "
+ "%s\n", i + 1, algo);
+ hexdump(result, ctemplate[i].outlen);
+ return -EINVAL;
+ }
+ }
+
+ for (i = 0; i < dtcount; i++) {
+ struct comp_request req;
+
+ error = crypto_decompress_setup(tfm, dtemplate[i].params,
+ dtemplate[i].paramsize);
+ if (error) {
+ pr_err("alg: pcomp: decompression setup failed on "
+ "test %d for %s: error=%d\n", i + 1, algo,
+ error);
+ return error;
+ }
+
+ error = crypto_decompress_init(tfm);
+ if (error) {
+ pr_err("alg: pcomp: decompression init failed on test "
+ "%d for %s: error=%d\n", i + 1, algo, error);
+ return error;
+ }
+
+ memset(result, 0, sizeof(result));
+
+ req.next_in = dtemplate[i].input;
+ req.avail_in = dtemplate[i].inlen / 2;
+ req.next_out = result;
+ req.avail_out = dtemplate[i].outlen / 2;
+
+ error = crypto_decompress_update(tfm, &req);
+ if (error && (error != -EAGAIN || req.avail_in)) {
+ pr_err("alg: pcomp: decompression update failed on "
+ "test %d for %s: error=%d\n", i + 1, algo,
+ error);
+ return error;
+ }
+
+ /* Add remaining input data */
+ req.avail_in += (dtemplate[i].inlen + 1) / 2;
+
+ error = crypto_decompress_update(tfm, &req);
+ if (error && (error != -EAGAIN || req.avail_in)) {
+ pr_err("alg: pcomp: decompression update failed on "
+ "test %d for %s: error=%d\n", i + 1, algo,
+ error);
+ return error;
+ }
+
+ /* Provide remaining output space */
+ req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2;
+
+ error = crypto_decompress_final(tfm, &req);
+ if (error && (error != -EAGAIN || req.avail_in)) {
+ pr_err("alg: pcomp: decompression final failed on "
+ "test %d for %s: error=%d\n", i + 1, algo,
+ error);
+ return error;
+ }
+
+ if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) {
+ pr_err("alg: comp: Decompression test %d failed for "
+ "%s: output len = %d (expected %d)\n", i + 1,
+ algo, COMP_BUF_SIZE - req.avail_out,
+ dtemplate[i].outlen);
+ return -EINVAL;
+ }
+
+ if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) {
+ pr_err("alg: pcomp: Decompression test %d failed for "
+ "%s\n", i + 1, algo);
+ hexdump(result, dtemplate[i].outlen);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
u32 type, u32 mask)
{
@@ -1007,6 +1168,28 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
return err;
}
+static int alg_test_pcomp(const struct alg_test_desc *desc, const char *driver,
+ u32 type, u32 mask)
+{
+ struct crypto_pcomp *tfm;
+ int err;
+
+ tfm = crypto_alloc_pcomp(driver, type, mask);
+ if (IS_ERR(tfm)) {
+ pr_err("alg: pcomp: Failed to load transform for %s: %ld\n",
+ driver, PTR_ERR(tfm));
+ return PTR_ERR(tfm);
+ }
+
+ err = test_pcomp(tfm, desc->suite.pcomp.comp.vecs,
+ desc->suite.pcomp.decomp.vecs,
+ desc->suite.pcomp.comp.count,
+ desc->suite.pcomp.decomp.count);
+
+ crypto_free_pcomp(tfm);
+ return err;
+}
+
static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
u32 type, u32 mask)
{
@@ -1835,6 +2018,21 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}
}
+ }, {
+ .alg = "zlib",
+ .test = alg_test_pcomp,
+ .suite = {
+ .pcomp = {
+ .comp = {
+ .vecs = zlib_comp_tv_template,
+ .count = ZLIB_COMP_TEST_VECTORS
+ },
+ .decomp = {
+ .vecs = zlib_decomp_tv_template,
+ .count = ZLIB_DECOMP_TEST_VECTORS
+ }
+ }
+ }
}
};
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 132953e144d3..526f00a9c72f 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -15,6 +15,11 @@
#ifndef _CRYPTO_TESTMGR_H
#define _CRYPTO_TESTMGR_H
+#include <linux/netlink.h>
+#include <linux/zlib.h>
+
+#include <crypto/compress.h>
+
#define MAX_DIGEST_SIZE 64
#define MAX_TAP 8
@@ -8347,10 +8352,19 @@ struct comp_testvec {
char output[COMP_BUF_SIZE];
};
+struct pcomp_testvec {
+ void *params;
+ unsigned int paramsize;
+ int inlen, outlen;
+ char input[COMP_BUF_SIZE];
+ char output[COMP_BUF_SIZE];
+};
+
/*
* Deflate test vectors (null-terminated strings).
* Params: winbits=-11, Z_DEFAULT_COMPRESSION, MAX_MEM_LEVEL.
*/
+
#define DEFLATE_COMP_TEST_VECTORS 2
#define DEFLATE_DECOMP_TEST_VECTORS 2
@@ -8426,6 +8440,139 @@ static struct comp_testvec deflate_decomp_tv_template[] = {
},
};
+#define ZLIB_COMP_TEST_VECTORS 2
+#define ZLIB_DECOMP_TEST_VECTORS 2
+
+static const struct {
+ struct nlattr nla;
+ int val;
+} deflate_comp_params[] = {
+ {
+ .nla = {
+ .nla_len = NLA_HDRLEN + sizeof(int),
+ .nla_type = ZLIB_COMP_LEVEL,
+ },
+ .val = Z_DEFAULT_COMPRESSION,
+ }, {
+ .nla = {
+ .nla_len = NLA_HDRLEN + sizeof(int),
+ .nla_type = ZLIB_COMP_METHOD,
+ },
+ .val = Z_DEFLATED,
+ }, {
+ .nla = {
+ .nla_len = NLA_HDRLEN + sizeof(int),
+ .nla_type = ZLIB_COMP_WINDOWBITS,
+ },
+ .val = -11,
+ }, {
+ .nla = {
+ .nla_len = NLA_HDRLEN + sizeof(int),
+ .nla_type = ZLIB_COMP_MEMLEVEL,
+ },
+ .val = MAX_MEM_LEVEL,
+ }, {
+ .nla = {
+ .nla_len = NLA_HDRLEN + sizeof(int),
+ .nla_type = ZLIB_COMP_STRATEGY,
+ },
+ .val = Z_DEFAULT_STRATEGY,
+ }
+};
+
+static const struct {
+ struct nlattr nla;
+ int val;
+} deflate_decomp_params[] = {
+ {
+ .nla = {
+ .nla_len = NLA_HDRLEN + sizeof(int),
+ .nla_type = ZLIB_DECOMP_WINDOWBITS,
+ },
+ .val = -11,
+ }
+};
+
+static struct pcomp_testvec zlib_comp_tv_template[] = {
+ {
+ .params = &deflate_comp_params,
+ .paramsize = sizeof(deflate_comp_params),
+ .inlen = 70,
+ .outlen = 38,
+ .input = "Join us now and share the software "
+ "Join us now and share the software ",
+ .output = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+ "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+ "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+ "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+ "\x71\xbc\x08\x2b\x01\x00",
+ }, {
+ .params = &deflate_comp_params,
+ .paramsize = sizeof(deflate_comp_params),
+ .inlen = 191,
+ .outlen = 122,
+ .input = "This document describes a compression method based on the DEFLATE"
+ "compression algorithm. This document defines the application of "
+ "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+ .output = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+ "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+ "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+ "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+ "\x68\x12\x51\xae\x76\x67\xd6\x27"
+ "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+ "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+ "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+ "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+ "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+ "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+ "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+ "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+ "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+ "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+ "\xfa\x02",
+ },
+};
+
+static struct pcomp_testvec zlib_decomp_tv_template[] = {
+ {
+ .params = &deflate_decomp_params,
+ .paramsize = sizeof(deflate_decomp_params),
+ .inlen = 122,
+ .outlen = 191,
+ .input = "\x5d\x8d\x31\x0e\xc2\x30\x10\x04"
+ "\xbf\xb2\x2f\xc8\x1f\x10\x04\x09"
+ "\x89\xc2\x85\x3f\x70\xb1\x2f\xf8"
+ "\x24\xdb\x67\xd9\x47\xc1\xef\x49"
+ "\x68\x12\x51\xae\x76\x67\xd6\x27"
+ "\x19\x88\x1a\xde\x85\xab\x21\xf2"
+ "\x08\x5d\x16\x1e\x20\x04\x2d\xad"
+ "\xf3\x18\xa2\x15\x85\x2d\x69\xc4"
+ "\x42\x83\x23\xb6\x6c\x89\x71\x9b"
+ "\xef\xcf\x8b\x9f\xcf\x33\xca\x2f"
+ "\xed\x62\xa9\x4c\x80\xff\x13\xaf"
+ "\x52\x37\xed\x0e\x52\x6b\x59\x02"
+ "\xd9\x4e\xe8\x7a\x76\x1d\x02\x98"
+ "\xfe\x8a\x87\x83\xa3\x4f\x56\x8a"
+ "\xb8\x9e\x8e\x5c\x57\xd3\xa0\x79"
+ "\xfa\x02",
+ .output = "This document describes a compression method based on the DEFLATE"
+ "compression algorithm. This document defines the application of "
+ "the DEFLATE algorithm to the IP Payload Compression Protocol.",
+ }, {
+ .params = &deflate_decomp_params,
+ .paramsize = sizeof(deflate_decomp_params),
+ .inlen = 38,
+ .outlen = 70,
+ .input = "\xf3\xca\xcf\xcc\x53\x28\x2d\x56"
+ "\xc8\xcb\x2f\x57\x48\xcc\x4b\x51"
+ "\x28\xce\x48\x2c\x4a\x55\x28\xc9"
+ "\x48\x55\x28\xce\x4f\x2b\x29\x07"
+ "\x71\xbc\x08\x2b\x01\x00",
+ .output = "Join us now and share the software "
+ "Join us now and share the software ",
+ },
+};
+
/*
* LZO test vectors (null-terminated strings).
*/
diff --git a/crypto/xor.c b/crypto/xor.c
index b2e6db075e49..996b6ee57d9e 100644
--- a/crypto/xor.c
+++ b/crypto/xor.c
@@ -18,8 +18,8 @@
#define BH_TRACE 0
#include <linux/module.h>
-#include <linux/raid/md.h>
#include <linux/raid/xor.h>
+#include <linux/jiffies.h>
#include <asm/xor.h>
/* The xor routines to use. */
diff --git a/crypto/zlib.c b/crypto/zlib.c
new file mode 100644
index 000000000000..33609bab614e
--- /dev/null
+++ b/crypto/zlib.c
@@ -0,0 +1,378 @@
+/*
+ * Cryptographic API.
+ *
+ * Zlib algorithm
+ *
+ * Copyright 2008 Sony Corporation
+ *
+ * Based on deflate.c, which is
+ * Copyright (c) 2003 James Morris <jmorris@intercode.com.au>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * FIXME: deflate transforms will require up to a total of about 436k of kernel
+ * memory on i386 (390k for compression, the rest for decompression), as the
+ * current zlib kernel code uses a worst case pre-allocation system by default.
+ * This needs to be fixed so that the amount of memory required is properly
+ * related to the winbits and memlevel parameters.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/zlib.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/net.h>
+#include <linux/slab.h>
+
+#include <crypto/internal/compress.h>
+
+#include <net/netlink.h>
+
+
+struct zlib_ctx {
+ struct z_stream_s comp_stream;
+ struct z_stream_s decomp_stream;
+ int decomp_windowBits;
+};
+
+
+static void zlib_comp_exit(struct zlib_ctx *ctx)
+{
+ struct z_stream_s *stream = &ctx->comp_stream;
+
+ if (stream->workspace) {
+ zlib_deflateEnd(stream);
+ vfree(stream->workspace);
+ stream->workspace = NULL;
+ }
+}
+
+static void zlib_decomp_exit(struct zlib_ctx *ctx)
+{
+ struct z_stream_s *stream = &ctx->decomp_stream;
+
+ if (stream->workspace) {
+ zlib_inflateEnd(stream);
+ kfree(stream->workspace);
+ stream->workspace = NULL;
+ }
+}
+
+static int zlib_init(struct crypto_tfm *tfm)
+{
+ return 0;
+}
+
+static void zlib_exit(struct crypto_tfm *tfm)
+{
+ struct zlib_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ zlib_comp_exit(ctx);
+ zlib_decomp_exit(ctx);
+}
+
+
+static int zlib_compress_setup(struct crypto_pcomp *tfm, void *params,
+ unsigned int len)
+{
+ struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+ struct z_stream_s *stream = &ctx->comp_stream;
+ struct nlattr *tb[ZLIB_COMP_MAX + 1];
+ size_t workspacesize;
+ int ret;
+
+ ret = nla_parse(tb, ZLIB_COMP_MAX, params, len, NULL);
+ if (ret)
+ return ret;
+
+ zlib_comp_exit(ctx);
+
+ workspacesize = zlib_deflate_workspacesize();
+ stream->workspace = vmalloc(workspacesize);
+ if (!stream->workspace)
+ return -ENOMEM;
+
+ memset(stream->workspace, 0, workspacesize);
+ ret = zlib_deflateInit2(stream,
+ tb[ZLIB_COMP_LEVEL]
+ ? nla_get_u32(tb[ZLIB_COMP_LEVEL])
+ : Z_DEFAULT_COMPRESSION,
+ tb[ZLIB_COMP_METHOD]
+ ? nla_get_u32(tb[ZLIB_COMP_METHOD])
+ : Z_DEFLATED,
+ tb[ZLIB_COMP_WINDOWBITS]
+ ? nla_get_u32(tb[ZLIB_COMP_WINDOWBITS])
+ : MAX_WBITS,
+ tb[ZLIB_COMP_MEMLEVEL]
+ ? nla_get_u32(tb[ZLIB_COMP_MEMLEVEL])
+ : DEF_MEM_LEVEL,
+ tb[ZLIB_COMP_STRATEGY]
+ ? nla_get_u32(tb[ZLIB_COMP_STRATEGY])
+ : Z_DEFAULT_STRATEGY);
+ if (ret != Z_OK) {
+ vfree(stream->workspace);
+ stream->workspace = NULL;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int zlib_compress_init(struct crypto_pcomp *tfm)
+{
+ int ret;
+ struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+ struct z_stream_s *stream = &dctx->comp_stream;
+
+ ret = zlib_deflateReset(stream);
+ if (ret != Z_OK)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int zlib_compress_update(struct crypto_pcomp *tfm,
+ struct comp_request *req)
+{
+ int ret;
+ struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+ struct z_stream_s *stream = &dctx->comp_stream;
+
+ pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
+ stream->next_in = req->next_in;
+ stream->avail_in = req->avail_in;
+ stream->next_out = req->next_out;
+ stream->avail_out = req->avail_out;
+
+ ret = zlib_deflate(stream, Z_NO_FLUSH);
+ switch (ret) {
+ case Z_OK:
+ break;
+
+ case Z_BUF_ERROR:
+ pr_debug("zlib_deflate could not make progress\n");
+ return -EAGAIN;
+
+ default:
+ pr_debug("zlib_deflate failed %d\n", ret);
+ return -EINVAL;
+ }
+
+ pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
+ stream->avail_in, stream->avail_out,
+ req->avail_in - stream->avail_in,
+ req->avail_out - stream->avail_out);
+ req->next_in = stream->next_in;
+ req->avail_in = stream->avail_in;
+ req->next_out = stream->next_out;
+ req->avail_out = stream->avail_out;
+ return 0;
+}
+
+static int zlib_compress_final(struct crypto_pcomp *tfm,
+ struct comp_request *req)
+{
+ int ret;
+ struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+ struct z_stream_s *stream = &dctx->comp_stream;
+
+ pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
+ stream->next_in = req->next_in;
+ stream->avail_in = req->avail_in;
+ stream->next_out = req->next_out;
+ stream->avail_out = req->avail_out;
+
+ ret = zlib_deflate(stream, Z_FINISH);
+ if (ret != Z_STREAM_END) {
+ pr_debug("zlib_deflate failed %d\n", ret);
+ return -EINVAL;
+ }
+
+ pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
+ stream->avail_in, stream->avail_out,
+ req->avail_in - stream->avail_in,
+ req->avail_out - stream->avail_out);
+ req->next_in = stream->next_in;
+ req->avail_in = stream->avail_in;
+ req->next_out = stream->next_out;
+ req->avail_out = stream->avail_out;
+ return 0;
+}
+
+
+static int zlib_decompress_setup(struct crypto_pcomp *tfm, void *params,
+ unsigned int len)
+{
+ struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+ struct z_stream_s *stream = &ctx->decomp_stream;
+ struct nlattr *tb[ZLIB_DECOMP_MAX + 1];
+ int ret = 0;
+
+ ret = nla_parse(tb, ZLIB_DECOMP_MAX, params, len, NULL);
+ if (ret)
+ return ret;
+
+ zlib_decomp_exit(ctx);
+
+ ctx->decomp_windowBits = tb[ZLIB_DECOMP_WINDOWBITS]
+ ? nla_get_u32(tb[ZLIB_DECOMP_WINDOWBITS])
+ : DEF_WBITS;
+
+ stream->workspace = kzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
+ if (!stream->workspace)
+ return -ENOMEM;
+
+ ret = zlib_inflateInit2(stream, ctx->decomp_windowBits);
+ if (ret != Z_OK) {
+ kfree(stream->workspace);
+ stream->workspace = NULL;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int zlib_decompress_init(struct crypto_pcomp *tfm)
+{
+ int ret;
+ struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+ struct z_stream_s *stream = &dctx->decomp_stream;
+
+ ret = zlib_inflateReset(stream);
+ if (ret != Z_OK)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int zlib_decompress_update(struct crypto_pcomp *tfm,
+ struct comp_request *req)
+{
+ int ret;
+ struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+ struct z_stream_s *stream = &dctx->decomp_stream;
+
+ pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
+ stream->next_in = req->next_in;
+ stream->avail_in = req->avail_in;
+ stream->next_out = req->next_out;
+ stream->avail_out = req->avail_out;
+
+ ret = zlib_inflate(stream, Z_SYNC_FLUSH);
+ switch (ret) {
+ case Z_OK:
+ case Z_STREAM_END:
+ break;
+
+ case Z_BUF_ERROR:
+ pr_debug("zlib_inflate could not make progress\n");
+ return -EAGAIN;
+
+ default:
+ pr_debug("zlib_inflate failed %d\n", ret);
+ return -EINVAL;
+ }
+
+ pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
+ stream->avail_in, stream->avail_out,
+ req->avail_in - stream->avail_in,
+ req->avail_out - stream->avail_out);
+ req->next_in = stream->next_in;
+ req->avail_in = stream->avail_in;
+ req->next_out = stream->next_out;
+ req->avail_out = stream->avail_out;
+ return 0;
+}
+
+static int zlib_decompress_final(struct crypto_pcomp *tfm,
+ struct comp_request *req)
+{
+ int ret;
+ struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
+ struct z_stream_s *stream = &dctx->decomp_stream;
+
+ pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out);
+ stream->next_in = req->next_in;
+ stream->avail_in = req->avail_in;
+ stream->next_out = req->next_out;
+ stream->avail_out = req->avail_out;
+
+ if (dctx->decomp_windowBits < 0) {
+ ret = zlib_inflate(stream, Z_SYNC_FLUSH);
+ /*
+ * Work around a bug in zlib, which sometimes wants to taste an
+ * extra byte when being used in the (undocumented) raw deflate
+ * mode. (From USAGI).
+ */
+ if (ret == Z_OK && !stream->avail_in && stream->avail_out) {
+ const void *saved_next_in = stream->next_in;
+ u8 zerostuff = 0;
+
+ stream->next_in = &zerostuff;
+ stream->avail_in = 1;
+ ret = zlib_inflate(stream, Z_FINISH);
+ stream->next_in = saved_next_in;
+ stream->avail_in = 0;
+ }
+ } else
+ ret = zlib_inflate(stream, Z_FINISH);
+ if (ret != Z_STREAM_END) {
+ pr_debug("zlib_inflate failed %d\n", ret);
+ return -EINVAL;
+ }
+
+ pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n",
+ stream->avail_in, stream->avail_out,
+ req->avail_in - stream->avail_in,
+ req->avail_out - stream->avail_out);
+ req->next_in = stream->next_in;
+ req->avail_in = stream->avail_in;
+ req->next_out = stream->next_out;
+ req->avail_out = stream->avail_out;
+ return 0;
+}
+
+
+static struct pcomp_alg zlib_alg = {
+ .compress_setup = zlib_compress_setup,
+ .compress_init = zlib_compress_init,
+ .compress_update = zlib_compress_update,
+ .compress_final = zlib_compress_final,
+ .decompress_setup = zlib_decompress_setup,
+ .decompress_init = zlib_decompress_init,
+ .decompress_update = zlib_decompress_update,
+ .decompress_final = zlib_decompress_final,
+
+ .base = {
+ .cra_name = "zlib",
+ .cra_flags = CRYPTO_ALG_TYPE_PCOMPRESS,
+ .cra_ctxsize = sizeof(struct zlib_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_init = zlib_init,
+ .cra_exit = zlib_exit,
+ }
+};
+
+static int __init zlib_mod_init(void)
+{
+ return crypto_register_pcomp(&zlib_alg);
+}
+
+static void __exit zlib_mod_fini(void)
+{
+ crypto_unregister_pcomp(&zlib_alg);
+}
+
+module_init(zlib_mod_init);
+module_exit(zlib_mod_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Zlib Compression Algorithm");
+MODULE_AUTHOR("Sony Corporation");
diff --git a/drivers/Makefile b/drivers/Makefile
index c1bf41737936..2618a6169a13 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -36,13 +36,14 @@ obj-$(CONFIG_FB_INTEL) += video/intelfb/
obj-y += serial/
obj-$(CONFIG_PARPORT) += parport/
-obj-y += base/ block/ misc/ mfd/ net/ media/
+obj-y += base/ block/ misc/ mfd/ media/
obj-$(CONFIG_NUBUS) += nubus/
-obj-$(CONFIG_ATM) += atm/
obj-y += macintosh/
obj-$(CONFIG_IDE) += ide/
obj-$(CONFIG_SCSI) += scsi/
obj-$(CONFIG_ATA) += ata/
+obj-y += net/
+obj-$(CONFIG_ATM) += atm/
obj-$(CONFIG_FUSION) += message/
obj-$(CONFIG_FIREWIRE) += firewire/
obj-y += ieee1394/
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 8a851d0f4384..431f8b439553 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -11,9 +11,9 @@ menuconfig ACPI
select PNP
select CPU_IDLE
default y
- ---help---
+ help
Advanced Configuration and Power Interface (ACPI) support for
- Linux requires an ACPI compliant platform (hardware/firmware),
+ Linux requires an ACPI-compliant platform (hardware/firmware),
and assumes the presence of OS-directed configuration and power
management (OSPM) software. This option will enlarge your
kernel by about 70K.
@@ -23,20 +23,19 @@ menuconfig ACPI
the Plug-and-Play BIOS specification (PnP BIOS), the
MultiProcessor Specification (MPS), and the Advanced Power
Management (APM) specification. If both ACPI and APM support
- are configured, whichever is loaded first shall be used.
+ are configured, ACPI is used.
- The ACPI SourceForge project contains the latest source code,
- documentation, tools, mailing list subscription, and other
- information. This project is available at:
- <http://sourceforge.net/projects/acpi>
+ The project home page for the Linux ACPI subsystem is here:
+ <http://www.lesswatts.org/projects/acpi/>
Linux support for ACPI is based on Intel Corporation's ACPI
- Component Architecture (ACPI CA). For more information see:
- <http://developer.intel.com/technology/iapc/acpi>
+ Component Architecture (ACPI CA). For more information on the
+ ACPI CA, see:
+ <http://acpica.org/>
- ACPI is an open industry specification co-developed by Compaq,
- Intel, Microsoft, Phoenix, and Toshiba. The specification is
- available at:
+ ACPI is an open industry specification co-developed by
+ Hewlett-Packard, Intel, Microsoft, Phoenix, and Toshiba.
+ The specification is available at:
<http://www.acpi.info>
if ACPI
@@ -49,14 +48,14 @@ config ACPI_SLEEP
config ACPI_PROCFS
bool "Deprecated /proc/acpi files"
depends on PROC_FS
- ---help---
+ help
For backwards compatibility, this option allows
deprecated /proc/acpi/ files to exist, even when
they have been replaced by functions in /sys.
The deprecated files (and their replacements) include:
/proc/acpi/sleep (/sys/power/state)
- /proc/acpi/info (/sys/modules/acpi/parameters/acpica_version)
+ /proc/acpi/info (/sys/module/acpi/parameters/acpica_version)
/proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT)
/proc/acpi/fadt (/sys/firmware/acpi/tables/FACP)
/proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer)
@@ -66,11 +65,12 @@ config ACPI_PROCFS
and functions which do not yet exist in /sys.
Say N to delete /proc/acpi/ files that have moved to /sys/
+
config ACPI_PROCFS_POWER
bool "Deprecated power /proc/acpi directories"
depends on PROC_FS
default y
- ---help---
+ help
For backwards compatibility, this option allows
deprecated power /proc/acpi/ directories to exist, even when
they have been replaced by functions in /sys.
@@ -86,19 +86,19 @@ config ACPI_SYSFS_POWER
bool "Future power /sys interface"
select POWER_SUPPLY
default y
- ---help---
+ help
Say N to disable power /sys interface
config ACPI_PROC_EVENT
bool "Deprecated /proc/acpi/event support"
depends on PROC_FS
default y
- ---help---
- A user-space daemon, acpi, typically read /proc/acpi/event
- and handled all ACPI sub-system generated events.
+ help
+ A user-space daemon, acpid, typically reads /proc/acpi/event
+ and handles all ACPI-generated events.
- These events are now delivered to user-space via
- either the input layer, or as netlink events.
+ These events are now delivered to user-space either
+ via the input layer or as netlink events.
This build option enables the old code for legacy
user-space implementation. After some time, this will
@@ -112,10 +112,13 @@ config ACPI_AC
depends on X86
default y
help
- This driver adds support for the AC Adapter object, which indicates
- whether a system is on AC, or not. If you have a system that can
+ This driver supports the AC Adapter object, which indicates
+ whether a system is on AC or not. If you have a system that can
switch between A/C and battery, say Y.
+ To compile this driver as a module, choose M here:
+ the module will be called ac.
+
config ACPI_BATTERY
tristate "Battery"
depends on X86
@@ -125,15 +128,21 @@ config ACPI_BATTERY
/proc/acpi/battery. If you have a mobile system with a battery,
say Y.
+ To compile this driver as a module, choose M here:
+ the module will be called battery.
+
config ACPI_BUTTON
tristate "Button"
depends on INPUT
default y
help
- This driver handles events on the power, sleep and lid buttons.
+ This driver handles events on the power, sleep, and lid buttons.
A daemon reads /proc/acpi/event and perform user-defined actions
such as shutting down the system. This is necessary for
- software controlled poweroff.
+ software-controlled poweroff.
+
+ To compile this driver as a module, choose M here:
+ the module will be called button.
config ACPI_VIDEO
tristate "Video"
@@ -141,38 +150,45 @@ config ACPI_VIDEO
depends on INPUT
select THERMAL
help
- This driver implement the ACPI Extensions For Display Adapters
+ This driver implements the ACPI Extensions For Display Adapters
for integrated graphics devices on motherboard, as specified in
- ACPI 2.0 Specification, Appendix B, allowing to perform some basic
- control like defining the video POST device, retrieving EDID information
- or to setup a video output, etc.
- Note that this is an ref. implementation only. It may or may not work
- for your integrated video device.
+ ACPI 2.0 Specification, Appendix B. This supports basic operations
+ such as defining the video POST device, retrieving EDID information,
+ and setting up a video output.
+
+ To compile this driver as a module, choose M here:
+ the module will be called video.
config ACPI_FAN
tristate "Fan"
select THERMAL
default y
help
- This driver adds support for ACPI fan devices, allowing user-mode
+ This driver supports ACPI fan devices, allowing user-mode
applications to perform basic fan control (on, off, status).
+ To compile this driver as a module, choose M here:
+ the module will be called fan.
+
config ACPI_DOCK
bool "Dock"
depends on EXPERIMENTAL
help
- This driver adds support for ACPI controlled docking stations and removable
- drive bays such as the IBM ultrabay or the Dell Module Bay.
+ This driver supports ACPI-controlled docking stations and removable
+ drive bays such as the IBM Ultrabay and the Dell Module Bay.
config ACPI_PROCESSOR
tristate "Processor"
select THERMAL
default y
help
- This driver installs ACPI as the idle handler for Linux, and uses
- ACPI C2 and C3 processor states to save power, on systems that
+ This driver installs ACPI as the idle handler for Linux and uses
+ ACPI C2 and C3 processor states to save power on systems that
support it. It is required by several flavors of cpufreq
- Performance-state drivers.
+ performance-state drivers.
+
+ To compile this driver as a module, choose M here:
+ the module will be called processor.
config ACPI_HOTPLUG_CPU
bool
@@ -186,11 +202,14 @@ config ACPI_THERMAL
select THERMAL
default y
help
- This driver adds support for ACPI thermal zones. Most mobile and
+ This driver supports ACPI thermal zones. Most mobile and
some desktop systems support ACPI thermal zones. It is HIGHLY
recommended that this option be enabled, as your processor(s)
may be damaged without it.
+ To compile this driver as a module, choose M here:
+ the module will be called thermal.
+
config ACPI_NUMA
bool "NUMA support"
depends on NUMA
@@ -218,7 +237,7 @@ config ACPI_BLACKLIST_YEAR
int "Disable ACPI for systems before Jan 1st this year" if X86_32
default 0
help
- enter a 4-digit year, eg. 2001 to disable ACPI by default
+ Enter a 4-digit year, e.g., 2001, to disable ACPI by default
on platforms with DMI BIOS date before January 1st that year.
"acpi=force" can be used to override this mechanism.
@@ -249,10 +268,13 @@ config ACPI_PCI_SLOT
tristate "PCI slot detection driver"
default n
help
- This driver will attempt to discover all PCI slots in your system,
- and creates entries in /sys/bus/pci/slots/. This feature can
- help you correlate PCI bus addresses with the physical geography
- of your slots. If you are unsure, say N.
+ This driver creates entries in /sys/bus/pci/slots/ for all PCI
+ slots in the system. This can help correlate PCI bus addresses,
+ i.e., segment/bus/device/function tuples, with physical slots in
+ the system. If you are unsure, say N.
+
+ To compile this driver as a module, choose M here:
+ the module will be called pci_slot.
config X86_PM_TIMER
bool "Power Management Timer Support" if EMBEDDED
@@ -271,43 +293,43 @@ config X86_PM_TIMER
systems require this timer.
config ACPI_CONTAINER
- tristate "ACPI0004,PNP0A05 and PNP0A06 Container Driver (EXPERIMENTAL)"
+ tristate "Container and Module Devices (EXPERIMENTAL)"
depends on EXPERIMENTAL
default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
- ---help---
- This allows _physical_ insertion and removal of CPUs and memory.
- This can be useful, for example, on NUMA machines that support
- ACPI based physical hotplug of nodes, or non-NUMA machines that
- support physical cpu/memory hot-plug.
+ help
+ This driver supports ACPI Container and Module devices (IDs
+ ACPI0004, PNP0A05, and PNP0A06).
- If one selects "m", this driver can be loaded with
- "modprobe container".
+ This helps support hotplug of nodes, CPUs, and memory.
+
+ To compile this driver as a module, choose M here:
+ the module will be called container.
config ACPI_HOTPLUG_MEMORY
tristate "Memory Hotplug"
depends on MEMORY_HOTPLUG
default n
help
- This driver adds supports for ACPI Memory Hotplug. This driver
- provides support for fielding notifications on ACPI memory
- devices (PNP0C80) which represent memory ranges that may be
- onlined or offlined during runtime.
+ This driver supports ACPI memory hotplug. The driver
+ fields notifications on ACPI memory devices (PNP0C80),
+ which represent memory ranges that may be onlined or
+ offlined during runtime.
- Enabling this driver assumes that your platform hardware
- and firmware have support for hot-plugging physical memory. If
- your system does not support physically adding or ripping out
- memory DIMMs at some platform defined granularity (individually
- or as a bank) at runtime, then you need not enable this driver.
+ If your hardware and firmware do not support adding or
+ removing memory devices at runtime, you need not enable
+ this driver.
- If one selects "m," this driver can be loaded using the following
- command:
- $>modprobe acpi_memhotplug
+ To compile this driver as a module, choose M here:
+ the module will be called acpi_memhotplug.
config ACPI_SBS
tristate "Smart Battery System"
depends on X86
help
- This driver adds support for the Smart Battery System, another
+ This driver supports the Smart Battery System, another
type of access to battery information, found on some laptops.
+ To compile this driver as a module, choose M here:
+ the modules will be called sbs and sbshc.
+
endif # ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index b130ea0d0759..03a985be3fe3 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -14,48 +14,50 @@ obj-$(CONFIG_X86) += blacklist.o
#
# ACPI Core Subsystem (Interpreter)
#
-obj-y += osl.o utils.o reboot.o\
+obj-y += acpi.o \
acpica/
+# All the builtin files are in the "acpi." module_param namespace.
+acpi-y += osl.o utils.o reboot.o
+
# sleep related files
-obj-y += wakeup.o
-obj-y += sleep.o
-obj-$(CONFIG_ACPI_SLEEP) += proc.o
+acpi-y += wakeup.o
+acpi-y += sleep.o
+acpi-$(CONFIG_ACPI_SLEEP) += proc.o
#
# ACPI Bus and Device Drivers
#
-processor-objs += processor_core.o processor_throttling.o \
- processor_idle.o processor_thermal.o
-ifdef CONFIG_CPU_FREQ
-processor-objs += processor_perflib.o
+acpi-y += bus.o glue.o
+acpi-y += scan.o
+acpi-y += ec.o
+acpi-$(CONFIG_ACPI_DOCK) += dock.o
+acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
+acpi-y += power.o
+acpi-y += system.o event.o
+acpi-$(CONFIG_ACPI_DEBUG) += debug.o
+acpi-$(CONFIG_ACPI_NUMA) += numa.o
+acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
+ifdef CONFIG_ACPI_VIDEO
+acpi-y += video_detect.o
endif
-obj-y += bus.o glue.o
-obj-y += scan.o
-# Keep EC driver first. Initialization of others depend on it.
-obj-y += ec.o
+# These are (potentially) separate modules
obj-$(CONFIG_ACPI_AC) += ac.o
-obj-$(CONFIG_ACPI_BATTERY) += battery.o
obj-$(CONFIG_ACPI_BUTTON) += button.o
obj-$(CONFIG_ACPI_FAN) += fan.o
-obj-$(CONFIG_ACPI_DOCK) += dock.o
obj-$(CONFIG_ACPI_VIDEO) += video.o
-ifdef CONFIG_ACPI_VIDEO
-obj-y += video_detect.o
-endif
-
-obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o
obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
obj-$(CONFIG_ACPI_CONTAINER) += container.o
obj-$(CONFIG_ACPI_THERMAL) += thermal.o
-obj-y += power.o
-obj-y += system.o event.o
-obj-$(CONFIG_ACPI_DEBUG) += debug.o
-obj-$(CONFIG_ACPI_NUMA) += numa.o
-obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
-obj-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
+obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
+obj-$(CONFIG_ACPI_BATTERY) += battery.o
obj-$(CONFIG_ACPI_SBS) += sbshc.o
obj-$(CONFIG_ACPI_SBS) += sbs.o
+
+# processor has its own "processor." module_param namespace
+processor-y := processor_core.o processor_throttling.o
+processor-y += processor_idle.o processor_thermal.o
+processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 9b917dac7732..88e42abf5d88 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -191,7 +191,6 @@ static int acpi_ac_add_fs(struct acpi_device *device)
acpi_ac_dir);
if (!acpi_device_dir(device))
return -ENODEV;
- acpi_device_dir(device)->owner = THIS_MODULE;
}
/* 'state' [R] */
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index 3f23298ee3fd..17e50824a6f1 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -18,7 +18,7 @@ obj-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\
excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \
exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o
-obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o
+obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o
obj-$(ACPI_FUTURE_USAGE) += hwtimer.o
@@ -41,4 +41,4 @@ obj-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
- utstate.o utmutex.o utobject.o utresrc.o
+ utstate.o utmutex.o utobject.o utresrc.o utlock.o
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index ddb40f5c68fc..16e5210ae936 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -148,9 +148,12 @@ ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list;
ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT;
ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS;
-/* These addresses are calculated from FADT address values */
+/* These addresses are calculated from the FADT Event Block addresses */
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_status;
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
+
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_status;
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
/*
@@ -162,6 +165,10 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width;
ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
+/* Reader/Writer lock is used for namespace walk and dynamic table unload */
+
+ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock;
+
/*****************************************************************************
*
* Mutual exlusion within ACPICA subsystem
@@ -245,6 +252,7 @@ ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
ACPI_EXTERN u8 acpi_gbl_events_initialized;
ACPI_EXTERN u8 acpi_gbl_system_awake_and_running;
+ACPI_EXTERN u8 acpi_gbl_osi_data;
#ifndef DEFINE_ACPI_GLOBALS
@@ -371,7 +379,6 @@ ACPI_EXTERN char *acpi_gbl_db_buffer;
ACPI_EXTERN char *acpi_gbl_db_filename;
ACPI_EXTERN u32 acpi_gbl_db_debug_level;
ACPI_EXTERN u32 acpi_gbl_db_console_debug_level;
-ACPI_EXTERN struct acpi_table_header *acpi_gbl_db_table_ptr;
ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node;
/*
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h
index 58c69dc49ab4..4afa3d8e0efb 100644
--- a/drivers/acpi/acpica/achware.h
+++ b/drivers/acpi/acpica/achware.h
@@ -64,14 +64,22 @@ u32 acpi_hw_get_mode(void);
*/
struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id);
-acpi_status
-acpi_hw_register_read(u32 register_id, u32 * return_value);
+acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control);
+
+acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value);
acpi_status acpi_hw_register_write(u32 register_id, u32 value);
acpi_status acpi_hw_clear_acpi_status(void);
/*
+ * hwvalid - Port I/O with validation
+ */
+acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width);
+
+acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width);
+
+/*
* hwgpe - GPE support
*/
acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 492d02761bb7..772ee5c4ccca 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -108,6 +108,14 @@ static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = {
#endif
#endif
+/* Lock structure for reader/writer interfaces */
+
+struct acpi_rw_lock {
+ acpi_mutex writer_mutex;
+ acpi_mutex reader_mutex;
+ u32 num_readers;
+};
+
/*
* Predefined handles for spinlocks used within the subsystem.
* These spinlocks are created by acpi_ut_mutex_initialize
@@ -772,7 +780,19 @@ struct acpi_bit_register_info {
* must be preserved.
*/
#define ACPI_PM1_STATUS_PRESERVED_BITS 0x0800 /* Bit 11 */
-#define ACPI_PM1_CONTROL_PRESERVED_BITS 0x0200 /* Bit 9 (whatever) */
+
+/* Write-only bits must be zeroed by software */
+
+#define ACPI_PM1_CONTROL_WRITEONLY_BITS 0x2004 /* Bits 13, 2 */
+
+/* For control registers, both ignored and reserved bits must be preserved */
+
+#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0201 /* Bits 9, 0(SCI_EN) */
+#define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */
+#define ACPI_PM1_CONTROL_PRESERVED_BITS \
+ (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS)
+
+#define ACPI_PM2_CONTROL_PRESERVED_BITS 0xFFFFFFFE /* All except bit 0 */
/*
* Register IDs
@@ -781,12 +801,10 @@ struct acpi_bit_register_info {
#define ACPI_REGISTER_PM1_STATUS 0x01
#define ACPI_REGISTER_PM1_ENABLE 0x02
#define ACPI_REGISTER_PM1_CONTROL 0x03
-#define ACPI_REGISTER_PM1A_CONTROL 0x04
-#define ACPI_REGISTER_PM1B_CONTROL 0x05
-#define ACPI_REGISTER_PM2_CONTROL 0x06
-#define ACPI_REGISTER_PM_TIMER 0x07
-#define ACPI_REGISTER_PROCESSOR_BLOCK 0x08
-#define ACPI_REGISTER_SMI_COMMAND_BLOCK 0x09
+#define ACPI_REGISTER_PM2_CONTROL 0x04
+#define ACPI_REGISTER_PM_TIMER 0x05
+#define ACPI_REGISTER_PROCESSOR_BLOCK 0x06
+#define ACPI_REGISTER_SMI_COMMAND_BLOCK 0x07
/* Masks used to access the bit_registers */
@@ -818,7 +836,7 @@ struct acpi_bit_register_info {
#define ACPI_BITMASK_SCI_ENABLE 0x0001
#define ACPI_BITMASK_BUS_MASTER_RLD 0x0002
#define ACPI_BITMASK_GLOBAL_LOCK_RELEASE 0x0004
-#define ACPI_BITMASK_SLEEP_TYPE_X 0x1C00
+#define ACPI_BITMASK_SLEEP_TYPE 0x1C00
#define ACPI_BITMASK_SLEEP_ENABLE 0x2000
#define ACPI_BITMASK_ARB_DISABLE 0x0001
@@ -844,11 +862,35 @@ struct acpi_bit_register_info {
#define ACPI_BITPOSITION_SCI_ENABLE 0x00
#define ACPI_BITPOSITION_BUS_MASTER_RLD 0x01
#define ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE 0x02
-#define ACPI_BITPOSITION_SLEEP_TYPE_X 0x0A
+#define ACPI_BITPOSITION_SLEEP_TYPE 0x0A
#define ACPI_BITPOSITION_SLEEP_ENABLE 0x0D
#define ACPI_BITPOSITION_ARB_DISABLE 0x00
+/* Structs and definitions for _OSI support and I/O port validation */
+
+#define ACPI_OSI_WIN_2000 0x01
+#define ACPI_OSI_WIN_XP 0x02
+#define ACPI_OSI_WIN_XP_SP1 0x03
+#define ACPI_OSI_WINSRV_2003 0x04
+#define ACPI_OSI_WIN_XP_SP2 0x05
+#define ACPI_OSI_WINSRV_2003_SP1 0x06
+#define ACPI_OSI_WIN_VISTA 0x07
+
+#define ACPI_ALWAYS_ILLEGAL 0x00
+
+struct acpi_interface_info {
+ char *name;
+ u8 value;
+};
+
+struct acpi_port_info {
+ char *name;
+ u16 start;
+ u16 end;
+ u8 osi_dependency;
+};
+
/*****************************************************************************
*
* Resource descriptors
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h
index 9c127e8e2d6d..91ac7d7b4402 100644
--- a/drivers/acpi/acpica/acmacros.h
+++ b/drivers/acpi/acpica/acmacros.h
@@ -292,10 +292,6 @@
#define ACPI_GET_DESCRIPTOR_TYPE(d) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type)
#define ACPI_SET_DESCRIPTOR_TYPE(d, t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t)
-/* Macro to test the object type */
-
-#define ACPI_GET_OBJECT_TYPE(d) (((union acpi_operand_object *)(void *)(d))->common.type)
-
/*
* Macros for the master AML opcode table
*/
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h
index eb6f038b03d9..544dcf834922 100644
--- a/drivers/acpi/acpica/acobject.h
+++ b/drivers/acpi/acpica/acobject.h
@@ -97,7 +97,6 @@
#define AOPOBJ_OBJECT_INITIALIZED 0x08
#define AOPOBJ_SETUP_COMPLETE 0x10
#define AOPOBJ_SINGLE_DATUM 0x20
-#define AOPOBJ_INVALID 0x40 /* Used if host OS won't allow an op_region address */
/******************************************************************************
*
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h
index 16a9ca9a66e4..63f656ae3604 100644
--- a/drivers/acpi/acpica/acpredef.h
+++ b/drivers/acpi/acpica/acpredef.h
@@ -52,41 +52,44 @@
* 1) PTYPE1 packages do not contain sub-packages.
*
* ACPI_PTYPE1_FIXED: Fixed length, 1 or 2 object types:
- * object type
- * count
- * object type
- * count
+ * object type
+ * count
+ * object type
+ * count
*
* ACPI_PTYPE1_VAR: Variable length:
- * object type (Int/Buf/Ref)
+ * object type (Int/Buf/Ref)
*
- * ACPI_PTYPE1_OPTION: Package has some required and some optional elements:
- * Used for _PRW
+ * ACPI_PTYPE1_OPTION: Package has some required and some optional elements
+ * (Used for _PRW)
*
*
* 2) PTYPE2 packages contain a variable number of sub-packages. Each of the
* different types describe the contents of each of the sub-packages.
*
* ACPI_PTYPE2: Each subpackage contains 1 or 2 object types:
- * object type
- * count
- * object type
- * count
+ * object type
+ * count
+ * object type
+ * count
+ * (Used for _ALR,_MLS,_PSS,_TRT,_TSS)
*
* ACPI_PTYPE2_COUNT: Each subpackage has a count as first element:
- * object type
+ * object type
+ * (Used for _CSD,_PSD,_TSD)
*
* ACPI_PTYPE2_PKG_COUNT: Count of subpackages at start, 1 or 2 object types:
- * object type
- * count
- * object type
- * count
+ * object type
+ * count
+ * object type
+ * count
+ * (Used for _CST)
*
- * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length:
- * Used for _PRT
+ * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length
+ * (Used for _PRT)
*
* ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length
- * Used for _HPX
+ * (Used for _HPX)
*
*****************************************************************************/
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index 7ce6e33c7f78..01c76b8ea7ba 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -49,7 +49,7 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count);
/*
* tbfadt - FADT parse/convert/validate
*/
-void acpi_tb_parse_fadt(u32 table_index, u8 flags);
+void acpi_tb_parse_fadt(u32 table_index);
void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
@@ -79,7 +79,7 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc);
void acpi_tb_terminate(void);
-void acpi_tb_delete_namespace_by_owner(u32 table_index);
+acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index);
acpi_status acpi_tb_allocate_owner_id(u32 table_index);
@@ -109,9 +109,8 @@ acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length);
void
acpi_tb_install_table(acpi_physical_address address,
- u8 flags, char *signature, u32 table_index);
+ char *signature, u32 table_index);
-acpi_status
-acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags);
+acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address);
#endif /* __ACTABLES_H__ */
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h
index 80d8813484fe..897810ba0ccc 100644
--- a/drivers/acpi/acpica/acutils.h
+++ b/drivers/acpi/acpica/acutils.h
@@ -346,6 +346,21 @@ acpi_status
acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest);
/*
+ * utlock - reader/writer locks
+ */
+acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock);
+
+void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock);
+
+void acpi_ut_release_write_lock(struct acpi_rw_lock *lock);
+
+/*
* utobject - internal object create/delete/cache routines
*/
union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c
index eb144b13d8fa..3aae13f30c5e 100644
--- a/drivers/acpi/acpica/dsinit.c
+++ b/drivers/acpi/acpica/dsinit.c
@@ -180,11 +180,23 @@ acpi_ds_initialize_objects(u32 table_index,
/* Walk entire namespace from the supplied root */
- status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
- acpi_ds_init_one_object, &info, NULL);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ /*
+ * We don't use acpi_walk_namespace since we do not want to acquire
+ * the namespace reader lock.
+ */
+ status =
+ acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object,
+ &info, NULL);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
}
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
status = acpi_get_table_by_index(table_index, &table);
if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c
index da0f5468184c..22b1a3ce2c94 100644
--- a/drivers/acpi/acpica/dsmthdat.c
+++ b/drivers/acpi/acpica/dsmthdat.c
@@ -713,6 +713,6 @@ acpi_ds_method_data_get_type(u16 opcode,
/* Get the object type */
- return_VALUE(ACPI_GET_OBJECT_TYPE(object));
+ return_VALUE(object->type);
}
#endif
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c
index 15c628e6aa00..dab3f48f0b42 100644
--- a/drivers/acpi/acpica/dsobject.c
+++ b/drivers/acpi/acpica/dsobject.c
@@ -565,7 +565,7 @@ acpi_ds_create_node(struct acpi_walk_state *walk_state,
/* Re-type the object according to its argument */
- node->type = ACPI_GET_OBJECT_TYPE(obj_desc);
+ node->type = obj_desc->common.type;
/* Attach obj to node */
@@ -619,7 +619,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
/* Perform per-object initialization */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_BUFFER:
/*
@@ -803,7 +803,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
default:
ACPI_ERROR((AE_INFO, "Unimplemented data type: %X",
- ACPI_GET_OBJECT_TYPE(obj_desc)));
+ obj_desc->common.type));
status = AE_AML_OPERAND_TYPE;
break;
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index 0c3b4dd60e8a..b4c87b5053e6 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -397,30 +397,6 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
extra_desc->extra.aml_length,
extra_desc->extra.aml_start);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
-
- /* Validate the region address/length via the host OS */
-
- status = acpi_os_validate_address(obj_desc->region.space_id,
- obj_desc->region.address,
- (acpi_size) obj_desc->region.length,
- acpi_ut_get_node_name(node));
-
- if (ACPI_FAILURE(status)) {
- /*
- * Invalid address/length. We will emit an error message and mark
- * the region as invalid, so that it will cause an additional error if
- * it is ever used. Then return AE_OK.
- */
- ACPI_EXCEPTION((AE_INFO, status,
- "During address validation of OpRegion [%4.4s]",
- node->name.ascii));
- obj_desc->common.flags |= AOPOBJ_INVALID;
- status = AE_OK;
- }
-
return_ACPI_STATUS(status);
}
@@ -484,7 +460,7 @@ acpi_ds_init_buffer_field(u16 aml_opcode,
/* Host object must be a Buffer */
- if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) {
+ if (buffer_desc->common.type != ACPI_TYPE_BUFFER) {
ACPI_ERROR((AE_INFO,
"Target of Create Field is not a Buffer object - %s",
acpi_ut_get_object_type_name(buffer_desc)));
@@ -1365,10 +1341,8 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
if ((ACPI_GET_DESCRIPTOR_TYPE
(walk_state->results->results.obj_desc[0]) ==
ACPI_DESC_TYPE_OPERAND)
- &&
- (ACPI_GET_OBJECT_TYPE
- (walk_state->results->results.obj_desc[0]) ==
- ACPI_TYPE_LOCAL_REFERENCE)
+ && ((walk_state->results->results.obj_desc[0])->
+ common.type == ACPI_TYPE_LOCAL_REFERENCE)
&& ((walk_state->results->results.obj_desc[0])->
reference.class != ACPI_REFCLASS_INDEX)) {
status =
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c
index dabc23a46176..dfa104102926 100644
--- a/drivers/acpi/acpica/dsutils.c
+++ b/drivers/acpi/acpica/dsutils.c
@@ -816,7 +816,7 @@ acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state)
goto push_result;
}
- type = ACPI_GET_OBJECT_TYPE(*operand);
+ type = (*operand)->common.type;
status = acpi_ex_resolve_to_value(operand, walk_state);
if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c
index 350e6656bc89..f0280856dc0e 100644
--- a/drivers/acpi/acpica/dswexec.c
+++ b/drivers/acpi/acpica/dswexec.c
@@ -138,11 +138,10 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state,
goto cleanup;
}
- if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) {
+ if (local_obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X",
- obj_desc, walk_state,
- ACPI_GET_OBJECT_TYPE(obj_desc)));
+ obj_desc, walk_state, obj_desc->common.type));
status = AE_AML_OPERAND_TYPE;
goto cleanup;
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c
index 803edd9e3f6a..cd55c774e882 100644
--- a/drivers/acpi/acpica/evevent.c
+++ b/drivers/acpi/acpica/evevent.c
@@ -183,7 +183,7 @@ acpi_status acpi_ev_install_xrupt_handlers(void)
*
* RETURN: Status
*
- * DESCRIPTION: Install the fixed event handlers and enable the fixed events.
+ * DESCRIPTION: Install the fixed event handlers and disable all fixed events.
*
******************************************************************************/
@@ -200,12 +200,13 @@ static acpi_status acpi_ev_fixed_event_initialize(void)
acpi_gbl_fixed_event_handlers[i].handler = NULL;
acpi_gbl_fixed_event_handlers[i].context = NULL;
- /* Enable the fixed event */
+ /* Disable the fixed event */
if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
status =
- acpi_set_register(acpi_gbl_fixed_event_info[i].
- enable_register_id, 0);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info
+ [i].enable_register_id,
+ ACPI_DISABLE_EVENT);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -288,16 +289,17 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event)
/* Clear the status bit */
- (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
- status_register_id, 1);
+ (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ status_register_id, ACPI_CLEAR_STATUS);
/*
* Make sure we've got a handler. If not, report an error. The event is
* disabled to prevent further interrupts.
*/
if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
- (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, 0);
+ (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id,
+ ACPI_DISABLE_EVENT);
ACPI_ERROR((AE_INFO,
"No installed handler for fixed event [%08X]",
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index f345ced36477..b9d8ee69ca6c 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -88,10 +88,10 @@ acpi_ev_set_gpe_type(struct acpi_gpe_event_info *gpe_event_info, u8 type)
status = acpi_ev_disable_gpe(gpe_event_info);
- /* Type was validated above */
+ /* Clear the type bits and insert the new Type */
- gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; /* Clear type bits */
- gpe_event_info->flags |= type; /* Insert type */
+ gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK;
+ gpe_event_info->flags |= type;
return_ACPI_STATUS(status);
}
@@ -122,6 +122,7 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info,
if (!gpe_register_info) {
return_ACPI_STATUS(AE_NOT_EXIST);
}
+
register_bit = (u8)
(1 <<
(gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index 484cc0565d5b..7b3463639422 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -104,9 +104,9 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
while (gpe_block) {
if ((&gpe_block->event_info[0] <= gpe_event_info) &&
- (&gpe_block->
- event_info[((acpi_size) gpe_block->
- register_count) * 8] >
+ (&gpe_block->event_info[((acpi_size)
+ gpe_block->
+ register_count) * 8] >
gpe_event_info)) {
return (TRUE);
}
@@ -210,10 +210,9 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
/* Now look at the individual GPEs in this byte register */
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
- gpe_event_info =
- &gpe_block->
- event_info[((acpi_size) i *
- ACPI_GPE_REGISTER_WIDTH) + j];
+ gpe_event_info = &gpe_block->event_info[((acpi_size) i *
+ ACPI_GPE_REGISTER_WIDTH)
+ + j];
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_HANDLER) {
@@ -293,8 +292,8 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
/* Unknown method type, just ignore it! */
ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
- "Ignoring unknown GPE method type: %s (name not of form _Lxx or _Exx)",
- name));
+ "Ignoring unknown GPE method type: %s "
+ "(name not of form _Lxx or _Exx)", name));
return_ACPI_STATUS(AE_OK);
}
@@ -306,17 +305,16 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
/* Conversion failed; invalid method, just ignore it */
ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
- "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)",
- name));
+ "Could not extract GPE number from name: %s "
+ "(name is not of form _Lxx or _Exx)", name));
return_ACPI_STATUS(AE_OK);
}
/* Ensure that we have a valid GPE number for this GPE block */
if ((gpe_number < gpe_block->block_base_number) ||
- (gpe_number >=
- (gpe_block->block_base_number +
- (gpe_block->register_count * 8)))) {
+ (gpe_number >= (gpe_block->block_base_number +
+ (gpe_block->register_count * 8)))) {
/*
* Not valid for this GPE block, just ignore it. However, it may be
* valid for a different GPE block, since GPE0 and GPE1 methods both
@@ -408,7 +406,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
*/
obj_desc = pkg_desc->package.elements[0];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
/* Use FADT-defined GPE device (from definition of _PRW) */
@@ -417,15 +415,15 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
/* Integer is the GPE number in the FADT described GPE blocks */
gpe_number = (u32) obj_desc->integer.value;
- } else if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+ } else if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
/* Package contains a GPE reference and GPE number within a GPE block */
if ((obj_desc->package.count < 2) ||
- (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[0]) !=
- ACPI_TYPE_LOCAL_REFERENCE)
- || (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[1]) !=
- ACPI_TYPE_INTEGER)) {
+ ((obj_desc->package.elements[0])->common.type !=
+ ACPI_TYPE_LOCAL_REFERENCE) ||
+ ((obj_desc->package.elements[1])->common.type !=
+ ACPI_TYPE_INTEGER)) {
goto cleanup;
}
@@ -450,11 +448,11 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
*/
if ((gpe_device == target_gpe_device) &&
(gpe_number >= gpe_block->block_base_number) &&
- (gpe_number <
- gpe_block->block_base_number + (gpe_block->register_count * 8))) {
- gpe_event_info =
- &gpe_block->event_info[gpe_number -
- gpe_block->block_base_number];
+ (gpe_number < gpe_block->block_base_number +
+ (gpe_block->register_count * 8))) {
+ gpe_event_info = &gpe_block->event_info[gpe_number -
+ gpe_block->
+ block_base_number];
/* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
@@ -1033,8 +1031,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
* 1) are "runtime" or "run/wake" GPEs, and
* 2) have a corresponding _Lxx or _Exx method
*
- * Any other GPEs within this block must be enabled via the acpi_enable_gpe()
- * external interface.
+ * Any other GPEs within this block must be enabled via the
+ * acpi_enable_gpe() external interface.
*/
wake_gpe_count = 0;
gpe_enabled_count = 0;
@@ -1044,14 +1042,13 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
/* Get the info block for this particular GPE */
- gpe_event_info =
- &gpe_block->
- event_info[((acpi_size) i *
- ACPI_GPE_REGISTER_WIDTH) + j];
+ gpe_event_info = &gpe_block->event_info[((acpi_size) i *
+ ACPI_GPE_REGISTER_WIDTH)
+ + j];
if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
- ACPI_GPE_DISPATCH_METHOD)
- && (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
+ ACPI_GPE_DISPATCH_METHOD) &&
+ (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
gpe_enabled_count++;
}
@@ -1105,8 +1102,8 @@ acpi_status acpi_ev_gpe_initialize(void)
/*
* Initialize the GPE Block(s) defined in the FADT
*
- * Why the GPE register block lengths are divided by 2: From the ACPI Spec,
- * section "General-Purpose Event Registers", we have:
+ * Why the GPE register block lengths are divided by 2: From the ACPI
+ * Spec, section "General-Purpose Event Registers", we have:
*
* "Each register block contains two registers of equal length
* GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
@@ -1163,7 +1160,8 @@ acpi_status acpi_ev_gpe_initialize(void)
if ((register_count0) &&
(gpe_number_max >= acpi_gbl_FADT.gpe1_base)) {
ACPI_ERROR((AE_INFO,
- "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1",
+ "GPE0 block (GPE 0 to %d) overlaps the GPE1 block "
+ "(GPE %d to %d) - Ignoring GPE1",
gpe_number_max, acpi_gbl_FADT.gpe1_base,
acpi_gbl_FADT.gpe1_base +
((register_count1 *
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c
index 5f893057bcc6..ce224e1eaa89 100644
--- a/drivers/acpi/acpica/evmisc.c
+++ b/drivers/acpi/acpica/evmisc.c
@@ -163,10 +163,10 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
* 2) Global device notify handler
* 3) Per-device notify handler
*/
- if ((acpi_gbl_system_notify.handler
- && (notify_value <= ACPI_MAX_SYS_NOTIFY))
- || (acpi_gbl_device_notify.handler
- && (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
+ if ((acpi_gbl_system_notify.handler &&
+ (notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
+ (acpi_gbl_device_notify.handler &&
+ (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
notify_info = acpi_ut_create_generic_state();
if (!notify_info) {
return (AE_NO_MEMORY);
@@ -174,7 +174,8 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
if (!handler_obj) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Executing system notify handler for Notify (%4.4s, %X) node %p\n",
+ "Executing system notify handler for Notify (%4.4s, %X) "
+ "node %p\n",
acpi_ut_get_node_name(node),
notify_value, node));
}
@@ -534,8 +535,9 @@ acpi_status acpi_ev_release_global_lock(void)
*/
if (pending) {
status =
- acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
- 1);
+ acpi_write_bit_register
+ (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
+ ACPI_ENABLE_EVENT);
}
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c
index 665c0887ab4d..538d63264555 100644
--- a/drivers/acpi/acpica/evregion.c
+++ b/drivers/acpi/acpica/evregion.c
@@ -691,7 +691,7 @@ acpi_ev_install_handler(acpi_handle obj_handle,
/* Devices are handled different than regions */
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_DEVICE) {
+ if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
/* Check if this Device already has a handler for this address space */
@@ -703,7 +703,8 @@ acpi_ev_install_handler(acpi_handle obj_handle,
if (next_handler_obj->address_space.space_id ==
handler_obj->address_space.space_id) {
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
- "Found handler for region [%s] in device %p(%p) handler %p\n",
+ "Found handler for region [%s] in device %p(%p) "
+ "handler %p\n",
acpi_ut_get_region_name
(handler_obj->address_space.
space_id), obj_desc,
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c
index f3f1fb45c3dc..284a7becbe96 100644
--- a/drivers/acpi/acpica/evrgnini.c
+++ b/drivers/acpi/acpica/evrgnini.c
@@ -241,7 +241,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
status = AE_OK;
} else {
ACPI_EXCEPTION((AE_INFO, status,
- "Could not install PciConfig handler for Root Bridge %4.4s",
+ "Could not install PciConfig handler "
+ "for Root Bridge %4.4s",
acpi_ut_get_node_name
(pci_root_node)));
}
@@ -293,9 +294,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
* Get the PCI device and function numbers from the _ADR object contained
* in the parent's scope.
*/
- status =
- acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node,
- &pci_value);
+ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
+ pci_device_node, &pci_value);
/*
* The default is zero, and since the allocation above zeroed the data,
@@ -308,18 +308,16 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
/* The PCI segment number comes from the _SEG method */
- status =
- acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, pci_root_node,
- &pci_value);
+ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG,
+ pci_root_node, &pci_value);
if (ACPI_SUCCESS(status)) {
pci_id->segment = ACPI_LOWORD(pci_value);
}
/* The PCI bus number comes from the _BBN method */
- status =
- acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, pci_root_node,
- &pci_value);
+ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN,
+ pci_root_node, &pci_value);
if (ACPI_SUCCESS(status)) {
pci_id->bus = ACPI_LOWORD(pci_value);
}
@@ -632,8 +630,8 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
acpi_ns_locked);
/*
- * Tell all users that this region is usable by running the _REG
- * method
+ * Tell all users that this region is usable by
+ * running the _REG method
*/
if (acpi_ns_locked) {
status =
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index 3aca9010a11e..10b8543dd466 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -631,7 +631,8 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
/* Setup up dispatch flags to indicate handler (vs. method) */
- gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* Clear bits */
+ gpe_event_info->flags &=
+ ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index 35485e4b60a6..d0a080747ec3 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -172,8 +172,8 @@ acpi_status acpi_enable_event(u32 event, u32 flags)
* register bit)
*/
status =
- acpi_set_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, 1);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, ACPI_ENABLE_EVENT);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -181,8 +181,8 @@ acpi_status acpi_enable_event(u32 event, u32 flags)
/* Make sure that the hardware responded */
status =
- acpi_get_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, &value);
+ acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, &value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -354,15 +354,15 @@ acpi_status acpi_disable_event(u32 event, u32 flags)
* register bit)
*/
status =
- acpi_set_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, 0);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, ACPI_DISABLE_EVENT);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
status =
- acpi_get_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, &value);
+ acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, &value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -407,8 +407,8 @@ acpi_status acpi_clear_event(u32 event)
* register bit)
*/
status =
- acpi_set_register(acpi_gbl_fixed_event_info[event].
- status_register_id, 1);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ status_register_id, ACPI_CLEAR_STATUS);
return_ACPI_STATUS(status);
}
@@ -495,7 +495,7 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
/* Get the status of the requested fixed event */
status =
- acpi_get_register(acpi_gbl_fixed_event_info[event].
+ acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
enable_register_id, &value);
if (ACPI_FAILURE(status))
return_ACPI_STATUS(status);
@@ -503,7 +503,7 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
*event_status = value;
status =
- acpi_get_register(acpi_gbl_fixed_event_info[event].
+ acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
status_register_id, &value);
if (ACPI_FAILURE(status))
return_ACPI_STATUS(status);
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c
index 479e7a3721be..7c3d2d356ffb 100644
--- a/drivers/acpi/acpica/evxfregn.c
+++ b/drivers/acpi/acpica/evxfregn.c
@@ -193,7 +193,8 @@ acpi_remove_address_space_handler(acpi_handle device,
/* Matched space_id, first dereference this in the Regions */
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
- "Removing address handler %p(%p) for region %s on Device %p(%p)\n",
+ "Removing address handler %p(%p) for region %s "
+ "on Device %p(%p)\n",
handler_obj, handler,
acpi_ut_get_region_name(space_id),
node, obj_desc));
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index 932bbc26aa04..3deb20a126b2 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -291,7 +291,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
/* Source Object can be either an op_region or a Buffer/Field */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_REGION:
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
@@ -501,7 +501,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
*/
if ((!ddb_handle) ||
(ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
- (ACPI_GET_OBJECT_TYPE(ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) {
+ (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
@@ -520,13 +520,14 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
}
}
- /*
- * Delete the entire namespace under this table Node
- * (Offset contains the table_id)
- */
- acpi_tb_delete_namespace_by_owner(table_index);
- (void)acpi_tb_release_owner_id(table_index);
+ /* Delete the portion of the namespace owned by this table */
+
+ status = acpi_tb_delete_namespace_by_owner(table_index);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+ (void)acpi_tb_release_owner_id(table_index);
acpi_tb_set_table_loaded_flag(table_index, FALSE);
/* Table unloaded, remove a reference to the ddb_handle object */
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c
index 0be10188316e..37d0d39e60a6 100644
--- a/drivers/acpi/acpica/exconvrt.c
+++ b/drivers/acpi/acpica/exconvrt.c
@@ -82,7 +82,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc);
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
/* No conversion necessary */
@@ -116,7 +116,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
/* String conversion is different than Buffer conversion */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_STRING:
/*
@@ -206,7 +206,7 @@ acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc);
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_BUFFER:
/* No conversion necessary */
@@ -409,7 +409,7 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc);
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_STRING:
/* No conversion necessary */
@@ -605,8 +605,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
default:
/* No conversion allowed for these types */
- if (destination_type !=
- ACPI_GET_OBJECT_TYPE(source_desc)) {
+ if (destination_type != source_desc->common.type) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Explicit operator, will store (%s) over existing type (%s)\n",
acpi_ut_get_object_type_name
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c
index aa313574b0df..89d141fdae0b 100644
--- a/drivers/acpi/acpica/exdump.c
+++ b/drivers/acpi/acpica/exdump.c
@@ -350,6 +350,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
break;
case ACPI_EXD_TYPE:
+
acpi_ex_out_string("Type",
acpi_ut_get_object_type_name
(obj_desc));
@@ -422,6 +423,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
break;
default:
+
acpi_os_printf("**** Invalid table opcode [%X] ****\n",
info->opcode);
return;
@@ -492,7 +494,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
/* Decode object type */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
acpi_os_printf("Reference: [%s] ",
@@ -527,44 +529,16 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
type));
break;
- case ACPI_REFCLASS_ARG:
-
- acpi_os_printf("%X", obj_desc->reference.value);
-
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
-
- /* Value is an Integer */
-
- acpi_os_printf(" value is [%8.8X%8.8x]",
- ACPI_FORMAT_UINT64(obj_desc->
- integer.
- value));
- }
+ case ACPI_REFCLASS_NAME:
- acpi_os_printf("\n");
+ acpi_os_printf("- [%4.4s]\n",
+ obj_desc->reference.node->name.ascii);
break;
+ case ACPI_REFCLASS_ARG:
case ACPI_REFCLASS_LOCAL:
- acpi_os_printf("%X", obj_desc->reference.value);
-
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
-
- /* Value is an Integer */
-
- acpi_os_printf(" value is [%8.8X%8.8x]",
- ACPI_FORMAT_UINT64(obj_desc->
- integer.
- value));
- }
-
- acpi_os_printf("\n");
- break;
-
- case ACPI_REFCLASS_NAME:
-
- acpi_os_printf("- [%4.4s]\n",
- obj_desc->reference.node->name.ascii);
+ acpi_os_printf("%X\n", obj_desc->reference.value);
break;
default: /* Unknown reference class */
@@ -661,8 +635,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
case ACPI_TYPE_LOCAL_REGION_FIELD:
acpi_os_printf
- ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n",
- obj_desc->field.bit_length,
+ ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at "
+ "byte=%X bit=%X of below:\n", obj_desc->field.bit_length,
obj_desc->field.access_byte_width,
obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
@@ -686,9 +660,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
if (!obj_desc->buffer_field.buffer_obj) {
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n"));
- } else
- if (ACPI_GET_OBJECT_TYPE(obj_desc->buffer_field.buffer_obj)
- != ACPI_TYPE_BUFFER) {
+ } else if ((obj_desc->buffer_field.buffer_obj)->common.type !=
+ ACPI_TYPE_BUFFER) {
acpi_os_printf("*not a Buffer*\n");
} else {
acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj,
@@ -737,8 +710,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
default:
/* Unknown Type */
- acpi_os_printf("Unknown Type %X\n",
- ACPI_GET_OBJECT_TYPE(obj_desc));
+ acpi_os_printf("Unknown Type %X\n", obj_desc->common.type);
break;
}
@@ -939,7 +911,7 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
/* Packages may only contain a few object types */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
acpi_os_printf("[Integer] = %8.8X%8.8X\n",
@@ -990,8 +962,7 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
default:
- acpi_os_printf("[Unknown Type] %X\n",
- ACPI_GET_OBJECT_TYPE(obj_desc));
+ acpi_os_printf("[Unknown Type] %X\n", obj_desc->common.type);
break;
}
}
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
index a352d0233857..546dcdd86785 100644
--- a/drivers/acpi/acpica/exfield.c
+++ b/drivers/acpi/acpica/exfield.c
@@ -84,7 +84,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+ if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
/*
* If the buffer_field arguments have not been previously evaluated,
* evaluate them now and save the results.
@@ -95,9 +95,8 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(status);
}
}
- } else
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
- && (obj_desc->field.region_obj->region.space_id ==
+ } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+ (obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_SMBUS)) {
/*
* This is an SMBus read. We must create a buffer to hold the data
@@ -163,7 +162,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"FieldRead [TO]: Obj %p, Type %X, Buf %p, ByteLen %X\n",
- obj_desc, ACPI_GET_OBJECT_TYPE(obj_desc), buffer,
+ obj_desc, obj_desc->common.type, buffer,
(u32) length));
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n",
@@ -222,7 +221,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
return_ACPI_STATUS(AE_AML_NO_OPERAND);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+ if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
/*
* If the buffer_field arguments have not been previously evaluated,
* evaluate them now and save the results.
@@ -233,9 +232,8 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
return_ACPI_STATUS(status);
}
}
- } else
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
- && (obj_desc->field.region_obj->region.space_id ==
+ } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+ (obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_SMBUS)) {
/*
* This is an SMBus write. We will bypass the entire field mechanism
@@ -243,7 +241,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
*
* Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE).
*/
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+ if (source_desc->common.type != ACPI_TYPE_BUFFER) {
ACPI_ERROR((AE_INFO,
"SMBus write requires Buffer, found type %s",
acpi_ut_get_object_type_name(source_desc)));
@@ -291,7 +289,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
/* Get a pointer to the data to be written */
- switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+ switch (source_desc->common.type) {
case ACPI_TYPE_INTEGER:
buffer = &source_desc->integer.value;
length = sizeof(source_desc->integer.value);
@@ -314,15 +312,14 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
source_desc,
- acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
- (source_desc)),
- ACPI_GET_OBJECT_TYPE(source_desc), buffer, length));
+ acpi_ut_get_type_name(source_desc->common.type),
+ source_desc->common.type, buffer, length));
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"FieldWrite [TO]: Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n",
obj_desc,
- acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)),
- ACPI_GET_OBJECT_TYPE(obj_desc),
+ acpi_ut_get_type_name(obj_desc->common.type),
+ obj_desc->common.type,
obj_desc->common_field.bit_length,
obj_desc->common_field.start_field_bit_offset,
obj_desc->common_field.base_byte_offset));
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c
index ef58ac4e687b..99cee61e655d 100644
--- a/drivers/acpi/acpica/exfldio.c
+++ b/drivers/acpi/acpica/exfldio.c
@@ -94,9 +94,9 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
/* We must have a valid region */
- if (ACPI_GET_OBJECT_TYPE(rgn_desc) != ACPI_TYPE_REGION) {
+ if (rgn_desc->common.type != ACPI_TYPE_REGION) {
ACPI_ERROR((AE_INFO, "Needed Region, found type %X (%s)",
- ACPI_GET_OBJECT_TYPE(rgn_desc),
+ rgn_desc->common.type,
acpi_ut_get_object_type_name(rgn_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -113,12 +113,6 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
}
}
- /* Exit if Address/Length have been disallowed by the host OS */
-
- if (rgn_desc->common.flags & AOPOBJ_INVALID) {
- return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
- }
-
/*
* Exit now for SMBus address space, it has a non-linear address space
* and the request cannot be directly validated
@@ -390,7 +384,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
* index_field - Write to an Index Register, then read/write from/to a
* Data Register
*/
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_BUFFER_FIELD:
/*
* If the buffer_field arguments have not been previously evaluated,
@@ -527,7 +521,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
default:
ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %X",
- ACPI_GET_OBJECT_TYPE(obj_desc)));
+ obj_desc->common.type));
status = AE_AML_INTERNAL;
break;
}
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c
index 6b0747ac683b..998eac329937 100644
--- a/drivers/acpi/acpica/exmisc.c
+++ b/drivers/acpi/acpica/exmisc.c
@@ -80,7 +80,7 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
case ACPI_DESC_TYPE_OPERAND:
- if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) {
+ if (obj_desc->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
@@ -260,7 +260,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
* guaranteed to be either Integer/String/Buffer by the operand
* resolution mechanism.
*/
- switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+ switch (operand0->common.type) {
case ACPI_TYPE_INTEGER:
status =
acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
@@ -277,7 +277,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
default:
ACPI_ERROR((AE_INFO, "Invalid object type: %X",
- ACPI_GET_OBJECT_TYPE(operand0)));
+ operand0->common.type));
status = AE_AML_INTERNAL;
}
@@ -298,7 +298,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
* 2) Two Strings concatenated to produce a new String
* 3) Two Buffers concatenated to produce a new Buffer
*/
- switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+ switch (operand0->common.type) {
case ACPI_TYPE_INTEGER:
/* Result of two Integers is a Buffer */
@@ -379,7 +379,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
/* Invalid object type, should not happen here */
ACPI_ERROR((AE_INFO, "Invalid object type: %X",
- ACPI_GET_OBJECT_TYPE(operand0)));
+ operand0->common.type));
status = AE_AML_INTERNAL;
goto cleanup;
}
@@ -581,7 +581,7 @@ acpi_ex_do_logical_op(u16 opcode,
* guaranteed to be either Integer/String/Buffer by the operand
* resolution mechanism.
*/
- switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+ switch (operand0->common.type) {
case ACPI_TYPE_INTEGER:
status =
acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
@@ -608,7 +608,7 @@ acpi_ex_do_logical_op(u16 opcode,
/*
* Two cases: 1) Both Integers, 2) Both Strings or Buffers
*/
- if (ACPI_GET_OBJECT_TYPE(operand0) == ACPI_TYPE_INTEGER) {
+ if (operand0->common.type == ACPI_TYPE_INTEGER) {
/*
* 1) Both operands are of type integer
* Note: local_operand1 may have changed above
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c
index b530480cc7d5..9635d21e568d 100644
--- a/drivers/acpi/acpica/exoparg1.c
+++ b/drivers/acpi/acpica/exoparg1.c
@@ -807,11 +807,9 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
acpi_namespace_node *)
operand[0]);
if (temp_desc
- &&
- ((ACPI_GET_OBJECT_TYPE(temp_desc) ==
- ACPI_TYPE_STRING)
- || (ACPI_GET_OBJECT_TYPE(temp_desc) ==
- ACPI_TYPE_LOCAL_REFERENCE))) {
+ && ((temp_desc->common.type == ACPI_TYPE_STRING)
+ || (temp_desc->common.type ==
+ ACPI_TYPE_LOCAL_REFERENCE))) {
operand[0] = temp_desc;
acpi_ut_add_reference(temp_desc);
} else {
@@ -819,7 +817,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
goto cleanup;
}
} else {
- switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+ switch ((operand[0])->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
/*
* This is a deref_of (local_x | arg_x)
@@ -877,8 +875,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) !=
ACPI_DESC_TYPE_NAMED) {
- if (ACPI_GET_OBJECT_TYPE(operand[0]) ==
- ACPI_TYPE_STRING) {
+ if ((operand[0])->common.type == ACPI_TYPE_STRING) {
/*
* This is a deref_of (String). The string is a reference
* to a named ACPI object.
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c
index 0b4f513ca885..85d95c92dfd3 100644
--- a/drivers/acpi/acpica/exoparg2.c
+++ b/drivers/acpi/acpica/exoparg2.c
@@ -399,7 +399,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
* At this point, the Source operand is a String, Buffer, or Package.
* Verify that the index is within range.
*/
- switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+ switch ((operand[0])->common.type) {
case ACPI_TYPE_STRING:
if (index >= operand[0]->string.length) {
diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c
index c6520bbf882b..253f9e122584 100644
--- a/drivers/acpi/acpica/exoparg3.c
+++ b/drivers/acpi/acpica/exoparg3.c
@@ -161,9 +161,8 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
* Create the return object. The Source operand is guaranteed to be
* either a String or a Buffer, so just use its type.
*/
- return_desc =
- acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
- (operand[0]));
+ return_desc = acpi_ut_create_internal_object((operand[0])->
+ common.type);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -191,7 +190,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
/* Strings always have a sub-pointer, not so for buffers */
- switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+ switch ((operand[0])->common.type) {
case ACPI_TYPE_STRING:
/* Always allocate a new buffer for the String */
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c
index a226f74d4a5c..52fec07064f0 100644
--- a/drivers/acpi/acpica/exprep.c
+++ b/drivers/acpi/acpica/exprep.c
@@ -279,7 +279,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
return_UINT32(0);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+ if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
/*
* buffer_field access can be on any byte boundary, so the
* byte_alignment is always 1 byte -- regardless of any byte_alignment
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c
index 76ec8ff903b8..3a54b737d2da 100644
--- a/drivers/acpi/acpica/exregion.c
+++ b/drivers/acpi/acpica/exregion.c
@@ -294,14 +294,14 @@ acpi_ex_system_io_space_handler(u32 function,
switch (function) {
case ACPI_READ:
- status = acpi_os_read_port((acpi_io_address) address,
+ status = acpi_hw_read_port((acpi_io_address) address,
&value32, bit_width);
*value = value32;
break;
case ACPI_WRITE:
- status = acpi_os_write_port((acpi_io_address) address,
+ status = acpi_hw_write_port((acpi_io_address) address,
(u32) * value, bit_width);
break;
diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c
index a063a74006f6..607958ff467c 100644
--- a/drivers/acpi/acpica/exresnte.c
+++ b/drivers/acpi/acpica/exresnte.c
@@ -136,7 +136,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
switch (entry_type) {
case ACPI_TYPE_PACKAGE:
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_PACKAGE) {
+ if (source_desc->common.type != ACPI_TYPE_PACKAGE) {
ACPI_ERROR((AE_INFO, "Object not a Package, type %s",
acpi_ut_get_object_type_name(source_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -154,7 +154,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
case ACPI_TYPE_BUFFER:
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+ if (source_desc->common.type != ACPI_TYPE_BUFFER) {
ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s",
acpi_ut_get_object_type_name(source_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -172,7 +172,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
case ACPI_TYPE_STRING:
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) {
+ if (source_desc->common.type != ACPI_TYPE_STRING) {
ACPI_ERROR((AE_INFO, "Object not a String, type %s",
acpi_ut_get_object_type_name(source_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -186,7 +186,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
case ACPI_TYPE_INTEGER:
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) {
+ if (source_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO, "Object not a Integer, type %s",
acpi_ut_get_object_type_name(source_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c
index f6105a6d6126..c93b54ce7f78 100644
--- a/drivers/acpi/acpica/exresolv.c
+++ b/drivers/acpi/acpica/exresolv.c
@@ -149,7 +149,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
/* This is a union acpi_operand_object */
- switch (ACPI_GET_OBJECT_TYPE(stack_desc)) {
+ switch (stack_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
ref_type = stack_desc->reference.class;
@@ -297,8 +297,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"FieldRead SourceDesc=%p Type=%X\n",
- stack_desc,
- ACPI_GET_OBJECT_TYPE(stack_desc)));
+ stack_desc, stack_desc->common.type));
status =
acpi_ex_read_data_from_field(walk_state, stack_desc,
@@ -386,7 +385,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
* specification of the object_type and size_of operators). This means
* traversing the list of possibly many nested references.
*/
- while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
+ while (obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
switch (obj_desc->reference.class) {
case ACPI_REFCLASS_REFOF:
case ACPI_REFCLASS_NAME:
@@ -518,7 +517,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
* Now we are guaranteed to have an object that has not been created
* via the ref_of or Index operators.
*/
- type = ACPI_GET_OBJECT_TYPE(obj_desc);
+ type = obj_desc->common.type;
exit:
/* Convert internal types to external types */
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c
index 3c3802764bfb..5c729a9e9131 100644
--- a/drivers/acpi/acpica/exresop.c
+++ b/drivers/acpi/acpica/exresop.c
@@ -212,7 +212,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* ACPI internal object */
- object_type = ACPI_GET_OBJECT_TYPE(obj_desc);
+ object_type = obj_desc->common.type;
/* Check for bad acpi_object_type */
@@ -287,8 +287,7 @@ acpi_ex_resolve_operands(u16 opcode,
if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
ACPI_DESC_TYPE_OPERAND)
- && (ACPI_GET_OBJECT_TYPE(obj_desc) ==
- ACPI_TYPE_STRING)) {
+ && (obj_desc->common.type == ACPI_TYPE_STRING)) {
/*
* String found - the string references a named object and
* must be resolved to a node
@@ -336,7 +335,7 @@ acpi_ex_resolve_operands(u16 opcode,
* -- All others must be resolved below.
*/
if ((opcode == AML_STORE_OP) &&
- (ACPI_GET_OBJECT_TYPE(*stack_ptr) ==
+ ((*stack_ptr)->common.type ==
ACPI_TYPE_LOCAL_REFERENCE)
&& ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) {
goto next_operand;
@@ -490,7 +489,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Need an operand of type INTEGER, STRING or BUFFER */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -512,7 +511,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Need an operand of type STRING or BUFFER */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -553,7 +552,7 @@ acpi_ex_resolve_operands(u16 opcode,
* The only reference allowed here is a direct reference to
* a namespace node.
*/
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_PACKAGE:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -576,7 +575,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Need a buffer or package or (ACPI 2.0) String */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_PACKAGE:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -598,7 +597,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_BUFFER:
case ACPI_TYPE_REGION:
@@ -619,7 +618,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Used by the Store() operator only */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
case ACPI_TYPE_PACKAGE:
case ACPI_TYPE_STRING:
@@ -677,8 +676,8 @@ acpi_ex_resolve_operands(u16 opcode,
* required object type (Simple cases only).
*/
status = acpi_ex_check_object_type(type_needed,
- ACPI_GET_OBJECT_TYPE
- (*stack_ptr), *stack_ptr);
+ (*stack_ptr)->common.type,
+ *stack_ptr);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c
index e35e9b4f6a4e..90d606196c99 100644
--- a/drivers/acpi/acpica/exstore.c
+++ b/drivers/acpi/acpica/exstore.c
@@ -129,7 +129,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
/* source_desc is of type ACPI_DESC_TYPE_OPERAND */
- switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+ switch (source_desc->common.type) {
case ACPI_TYPE_INTEGER:
/* Output correct integer width */
@@ -324,7 +324,7 @@ acpi_ex_store(union acpi_operand_object *source_desc,
/* Destination object must be a Reference or a Constant object */
- switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+ switch (dest_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
break;
@@ -460,9 +460,8 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
*/
obj_desc = *(index_desc->reference.where);
- if (ACPI_GET_OBJECT_TYPE(source_desc) ==
- ACPI_TYPE_LOCAL_REFERENCE
- && source_desc->reference.class == ACPI_REFCLASS_TABLE) {
+ if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
+ source_desc->reference.class == ACPI_REFCLASS_TABLE) {
/* This is a DDBHandle, just add a reference to it */
@@ -520,8 +519,8 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
* by the INDEX_OP code.
*/
obj_desc = index_desc->reference.object;
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_BUFFER) &&
- (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_STRING)) {
+ if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
+ (obj_desc->common.type != ACPI_TYPE_STRING)) {
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
@@ -529,7 +528,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
* The assignment of the individual elements will be slightly
* different for each source type.
*/
- switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+ switch (source_desc->common.type) {
case ACPI_TYPE_INTEGER:
/* Use the least-significant byte of the integer */
@@ -707,8 +706,7 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
/* No conversions for all other types. Just attach the source object */
status = acpi_ns_attach_object(node, source_desc,
- ACPI_GET_OBJECT_TYPE
- (source_desc));
+ source_desc->common.type);
break;
}
diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c
index 145d15305f70..608e838d537e 100644
--- a/drivers/acpi/acpica/exstoren.c
+++ b/drivers/acpi/acpica/exstoren.c
@@ -96,8 +96,7 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
* are all essentially the same. This case handles the
* "interchangeable" types Integer, String, and Buffer.
*/
- if (ACPI_GET_OBJECT_TYPE(source_desc) ==
- ACPI_TYPE_LOCAL_REFERENCE) {
+ if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
/* Resolve a reference object first */
@@ -117,13 +116,11 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
/* Must have a Integer, Buffer, or String */
- if ((ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) &&
- (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) &&
- (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) &&
- !((ACPI_GET_OBJECT_TYPE(source_desc) ==
- ACPI_TYPE_LOCAL_REFERENCE)
- && (source_desc->reference.class ==
- ACPI_REFCLASS_TABLE))) {
+ if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&
+ (source_desc->common.type != ACPI_TYPE_BUFFER) &&
+ (source_desc->common.type != ACPI_TYPE_STRING) &&
+ !((source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
+ (source_desc->reference.class == ACPI_REFCLASS_TABLE))) {
/* Conversion successful but still not a valid type */
@@ -218,8 +215,7 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
return_ACPI_STATUS(status);
}
- if (ACPI_GET_OBJECT_TYPE(source_desc) !=
- ACPI_GET_OBJECT_TYPE(dest_desc)) {
+ if (source_desc->common.type != dest_desc->common.type) {
/*
* The source type does not match the type of the destination.
* Perform the "implicit conversion" of the source to the current type
@@ -229,11 +225,10 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
* Otherwise, actual_src_desc is a temporary object to hold the
* converted object.
*/
- status =
- acpi_ex_convert_to_target_type(ACPI_GET_OBJECT_TYPE
- (dest_desc), source_desc,
- &actual_src_desc,
- walk_state);
+ status = acpi_ex_convert_to_target_type(dest_desc->common.type,
+ source_desc,
+ &actual_src_desc,
+ walk_state);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -252,7 +247,7 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
* We now have two objects of identical types, and we can perform a
* copy of the *value* of the source object.
*/
- switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+ switch (dest_desc->common.type) {
case ACPI_TYPE_INTEGER:
dest_desc->integer.value = actual_src_desc->integer.value;
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c
index 32b85d68e756..87730e944132 100644
--- a/drivers/acpi/acpica/exutils.c
+++ b/drivers/acpi/acpica/exutils.c
@@ -221,7 +221,7 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
*/
if ((!obj_desc) ||
(ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) ||
- (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
+ (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
return;
}
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c
index a9d4fea4167f..9af361a191e7 100644
--- a/drivers/acpi/acpica/hwacpi.c
+++ b/drivers/acpi/acpica/hwacpi.c
@@ -86,7 +86,8 @@ acpi_status acpi_hw_set_mode(u32 mode)
*/
if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
ACPI_ERROR((AE_INFO,
- "No ACPI mode transition supported in this system (enable/disable both zero)"));
+ "No ACPI mode transition supported in this system "
+ "(enable/disable both zero)"));
return_ACPI_STATUS(AE_OK);
}
@@ -95,7 +96,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
/* BIOS should have disabled ALL fixed and GP events */
- status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+ status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.acpi_enable, 8);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Attempting to enable ACPI mode\n"));
@@ -107,7 +108,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
* BIOS should clear all fixed status bits and restore fixed event
* enable bits to default
*/
- status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+ status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.acpi_disable,
8);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -172,7 +173,7 @@ u32 acpi_hw_get_mode(void)
return_UINT32(ACPI_SYS_MODE_ACPI);
}
- status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value);
+ status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
if (ACPI_FAILURE(status)) {
return_UINT32(ACPI_SYS_MODE_LEGACY);
}
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index 2013b66745d2..d3b7e37c9eed 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -89,10 +89,9 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
/* Clear just the bit that corresponds to this GPE */
- ACPI_CLEAR_BIT(enable_mask,
- ((u32) 1 <<
- (gpe_event_info->gpe_number -
- gpe_register_info->base_gpe_number)));
+ ACPI_CLEAR_BIT(enable_mask, ((u32)1 <<
+ (gpe_event_info->gpe_number -
+ gpe_register_info->base_gpe_number)));
/* Write the updated enable mask */
@@ -156,10 +155,9 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
ACPI_FUNCTION_ENTRY();
- register_bit = (u8)
- (1 <<
- (gpe_event_info->gpe_number -
- gpe_event_info->register_info->base_gpe_number));
+ register_bit = (u8)(1 <<
+ (gpe_event_info->gpe_number -
+ gpe_event_info->register_info->base_gpe_number));
/*
* Write a one to the appropriate bit in the status register to
@@ -206,10 +204,9 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
/* Get the register bitmask for this GPE */
- register_bit = (u8)
- (1 <<
- (gpe_event_info->gpe_number -
- gpe_event_info->register_info->base_gpe_number));
+ register_bit = (u8)(1 <<
+ (gpe_event_info->gpe_number -
+ gpe_event_info->register_info->base_gpe_number));
/* GPE currently enabled? (enabled for runtime?) */
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c
index 4dc43b018517..7b2fb602b5cb 100644
--- a/drivers/acpi/acpica/hwregs.c
+++ b/drivers/acpi/acpica/hwregs.c
@@ -51,6 +51,17 @@
#define _COMPONENT ACPI_HARDWARE
ACPI_MODULE_NAME("hwregs")
+/* Local Prototypes */
+static acpi_status
+acpi_hw_read_multiple(u32 *value,
+ struct acpi_generic_address *register_a,
+ struct acpi_generic_address *register_b);
+
+static acpi_status
+acpi_hw_write_multiple(u32 value,
+ struct acpi_generic_address *register_a,
+ struct acpi_generic_address *register_b);
+
/*******************************************************************************
*
* FUNCTION: acpi_hw_clear_acpi_status
@@ -60,9 +71,9 @@ ACPI_MODULE_NAME("hwregs")
* RETURN: Status
*
* DESCRIPTION: Clears all fixed and general purpose status bits
- * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
*
******************************************************************************/
+
acpi_status acpi_hw_clear_acpi_status(void)
{
acpi_status status;
@@ -70,28 +81,20 @@ acpi_status acpi_hw_clear_acpi_status(void)
ACPI_FUNCTION_TRACE(hw_clear_acpi_status);
- ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n",
+ ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n",
ACPI_BITMASK_ALL_FIXED_STATUS,
- (u16) acpi_gbl_FADT.xpm1a_event_block.address));
+ acpi_gbl_xpm1a_status.address));
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
+ /* Clear the fixed events in PM1 A/B */
+
status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
ACPI_BITMASK_ALL_FIXED_STATUS);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
- /* Clear the fixed events */
-
- if (acpi_gbl_FADT.xpm1b_event_block.address) {
- status = acpi_write(ACPI_BITMASK_ALL_FIXED_STATUS,
- &acpi_gbl_FADT.xpm1b_event_block);
- if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
- }
- }
-
/* Clear the GPE Bits in all GPE registers in all GPE blocks */
status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
@@ -128,6 +131,42 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
/******************************************************************************
*
+ * FUNCTION: acpi_hw_write_pm1_control
+ *
+ * PARAMETERS: pm1a_control - Value to be written to PM1A control
+ * pm1b_control - Value to be written to PM1B control
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write the PM1 A/B control registers. These registers are
+ * different than than the PM1 A/B status and enable registers
+ * in that different values can be written to the A/B registers.
+ * Most notably, the SLP_TYP bits can be different, as per the
+ * values returned from the _Sx predefined methods.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(hw_write_pm1_control);
+
+ status = acpi_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ if (acpi_gbl_FADT.xpm1b_control_block.address) {
+ status =
+ acpi_write(pm1b_control,
+ &acpi_gbl_FADT.xpm1b_control_block);
+ }
+ return_ACPI_STATUS(status);
+}
+
+/******************************************************************************
+ *
* FUNCTION: acpi_hw_register_read
*
* PARAMETERS: register_id - ACPI Register ID
@@ -141,64 +180,56 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
acpi_status
acpi_hw_register_read(u32 register_id, u32 * return_value)
{
- u32 value1 = 0;
- u32 value2 = 0;
+ u32 value = 0;
acpi_status status;
ACPI_FUNCTION_TRACE(hw_register_read);
switch (register_id) {
- case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
-
- status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_event_block);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* PM1B is optional */
+ case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
- status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_event_block);
- value1 |= value2;
+ status = acpi_hw_read_multiple(&value,
+ &acpi_gbl_xpm1a_status,
+ &acpi_gbl_xpm1b_status);
break;
- case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
+ case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */
- status = acpi_read(&value1, &acpi_gbl_xpm1a_enable);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* PM1B is optional */
-
- status = acpi_read(&value2, &acpi_gbl_xpm1b_enable);
- value1 |= value2;
+ status = acpi_hw_read_multiple(&value,
+ &acpi_gbl_xpm1a_enable,
+ &acpi_gbl_xpm1b_enable);
break;
- case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
+ case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
- status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_control_block);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
+ status = acpi_hw_read_multiple(&value,
+ &acpi_gbl_FADT.
+ xpm1a_control_block,
+ &acpi_gbl_FADT.
+ xpm1b_control_block);
- status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_control_block);
- value1 |= value2;
+ /*
+ * Zero the write-only bits. From the ACPI specification, "Hardware
+ * Write-Only Bits": "Upon reads to registers with write-only bits,
+ * software masks out all write-only bits."
+ */
+ value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
break;
case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
- status = acpi_read(&value1, &acpi_gbl_FADT.xpm2_control_block);
+ status = acpi_read(&value, &acpi_gbl_FADT.xpm2_control_block);
break;
case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
- status = acpi_read(&value1, &acpi_gbl_FADT.xpm_timer_block);
+ status = acpi_read(&value, &acpi_gbl_FADT.xpm_timer_block);
break;
case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
status =
- acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8);
+ acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8);
break;
default:
@@ -207,10 +238,8 @@ acpi_hw_register_read(u32 register_id, u32 * return_value)
break;
}
- exit:
-
if (ACPI_SUCCESS(status)) {
- *return_value = value1;
+ *return_value = value;
}
return_ACPI_STATUS(status);
@@ -250,52 +279,42 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
ACPI_FUNCTION_TRACE(hw_register_write);
switch (register_id) {
- case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
-
- /* Perform a read first to preserve certain bits (per ACPI spec) */
-
- status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
- &read_value);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* Insert the bits to be preserved */
-
- ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS,
- read_value);
-
- /* Now we can write the data */
-
- status = acpi_write(value, &acpi_gbl_FADT.xpm1a_event_block);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* PM1B is optional */
+ case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
+ /*
+ * Handle the "ignored" bit in PM1 Status. According to the ACPI
+ * specification, ignored bits are to be preserved when writing.
+ * Normally, this would mean a read/modify/write sequence. However,
+ * preserving a bit in the status register is different. Writing a
+ * one clears the status, and writing a zero preserves the status.
+ * Therefore, we must always write zero to the ignored bit.
+ *
+ * This behavior is clarified in the ACPI 4.0 specification.
+ */
+ value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
- status = acpi_write(value, &acpi_gbl_FADT.xpm1b_event_block);
+ status = acpi_hw_write_multiple(value,
+ &acpi_gbl_xpm1a_status,
+ &acpi_gbl_xpm1b_status);
break;
- case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
+ case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access */
- status = acpi_write(value, &acpi_gbl_xpm1a_enable);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* PM1B is optional */
-
- status = acpi_write(value, &acpi_gbl_xpm1b_enable);
+ status = acpi_hw_write_multiple(value,
+ &acpi_gbl_xpm1a_enable,
+ &acpi_gbl_xpm1b_enable);
break;
- case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
+ case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
/*
* Perform a read first to preserve certain bits (per ACPI spec)
+ * Note: This includes SCI_EN, we never want to change this bit
*/
- status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
- &read_value);
+ status = acpi_hw_read_multiple(&read_value,
+ &acpi_gbl_FADT.
+ xpm1a_control_block,
+ &acpi_gbl_FADT.
+ xpm1b_control_block);
if (ACPI_FAILURE(status)) {
goto exit;
}
@@ -307,25 +326,29 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
/* Now we can write the data */
- status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
+ status = acpi_hw_write_multiple(value,
+ &acpi_gbl_FADT.
+ xpm1a_control_block,
+ &acpi_gbl_FADT.
+ xpm1b_control_block);
break;
- case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */
-
- status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
- break;
+ case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
- case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */
+ /*
+ * For control registers, all reserved bits must be preserved,
+ * as per the ACPI spec.
+ */
+ status =
+ acpi_read(&read_value, &acpi_gbl_FADT.xpm2_control_block);
+ if (ACPI_FAILURE(status)) {
+ goto exit;
+ }
- status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
- break;
+ /* Insert the bits to be preserved */
- case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
+ ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS,
+ read_value);
status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block);
break;
@@ -340,10 +363,11 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
/* SMI_CMD is currently always in IO space */
status =
- acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8);
+ acpi_hw_write_port(acpi_gbl_FADT.smi_command, value, 8);
break;
default:
+ ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id));
status = AE_BAD_PARAMETER;
break;
}
@@ -351,3 +375,103 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
exit:
return_ACPI_STATUS(status);
}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_read_multiple
+ *
+ * PARAMETERS: Value - Where the register value is returned
+ * register_a - First ACPI register (required)
+ * register_b - Second ACPI register (optional)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_read_multiple(u32 *value,
+ struct acpi_generic_address *register_a,
+ struct acpi_generic_address *register_b)
+{
+ u32 value_a = 0;
+ u32 value_b = 0;
+ acpi_status status;
+
+ /* The first register is always required */
+
+ status = acpi_read(&value_a, register_a);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ /* Second register is optional */
+
+ if (register_b->address) {
+ status = acpi_read(&value_b, register_b);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+ }
+
+ /*
+ * OR the two return values together. No shifting or masking is necessary,
+ * because of how the PM1 registers are defined in the ACPI specification:
+ *
+ * "Although the bits can be split between the two register blocks (each
+ * register block has a unique pointer within the FADT), the bit positions
+ * are maintained. The register block with unimplemented bits (that is,
+ * those implemented in the other register block) always returns zeros,
+ * and writes have no side effects"
+ */
+ *value = (value_a | value_b);
+ return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_write_multiple
+ *
+ * PARAMETERS: Value - The value to write
+ * register_a - First ACPI register (required)
+ * register_b - Second ACPI register (optional)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_write_multiple(u32 value,
+ struct acpi_generic_address *register_a,
+ struct acpi_generic_address *register_b)
+{
+ acpi_status status;
+
+ /* The first register is always required */
+
+ status = acpi_write(value, register_a);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ /*
+ * Second register is optional
+ *
+ * No bit shifting or clearing is necessary, because of how the PM1
+ * registers are defined in the ACPI specification:
+ *
+ * "Although the bits can be split between the two register blocks (each
+ * register block has a unique pointer within the FADT), the bit positions
+ * are maintained. The register block with unimplemented bits (that is,
+ * those implemented in the other register block) always returns zeros,
+ * and writes have no side effects"
+ */
+ if (register_b->address) {
+ status = acpi_write(value, register_b);
+ }
+
+ return (status);
+}
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
index a2af2a4f2f26..baa5fc05e124 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -90,6 +90,7 @@ acpi_set_firmware_waking_vector(u32 physical_address)
ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
+#if ACPI_MACHINE_WIDTH == 64
/*******************************************************************************
*
* FUNCTION: acpi_set_firmware_waking_vector64
@@ -100,7 +101,8 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
* RETURN: Status
*
* DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if
- * it exists in the table.
+ * it exists in the table. This function is intended for use with
+ * 64-bit host operating systems.
*
******************************************************************************/
acpi_status
@@ -124,6 +126,7 @@ acpi_set_firmware_waking_vector64(u64 physical_address)
}
ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64)
+#endif
/*******************************************************************************
*
@@ -147,9 +150,8 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
- /*
- * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
- */
+ /* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */
+
status = acpi_get_sleep_type_data(sleep_state,
&acpi_gbl_sleep_type_a,
&acpi_gbl_sleep_type_b);
@@ -223,8 +225,8 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
******************************************************************************/
acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
{
- u32 PM1Acontrol;
- u32 PM1Bcontrol;
+ u32 pm1a_control;
+ u32 pm1b_control;
struct acpi_bit_register_info *sleep_type_reg_info;
struct acpi_bit_register_info *sleep_enable_reg_info;
u32 in_value;
@@ -242,13 +244,14 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
}
sleep_type_reg_info =
- acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+ acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
sleep_enable_reg_info =
acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
/* Clear wake status */
- status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+ status =
+ acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -289,24 +292,25 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Get current value of PM1A control */
- status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+ status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
+ &pm1a_control);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
ACPI_DEBUG_PRINT((ACPI_DB_INIT,
"Entering sleep state [S%d]\n", sleep_state));
- /* Clear SLP_EN and SLP_TYP fields */
+ /* Clear the SLP_EN and SLP_TYP fields */
- PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
- sleep_enable_reg_info->access_bit_mask);
- PM1Bcontrol = PM1Acontrol;
+ pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
+ sleep_enable_reg_info->access_bit_mask);
+ pm1b_control = pm1a_control;
- /* Insert SLP_TYP bits */
+ /* Insert the SLP_TYP bits */
- PM1Acontrol |=
+ pm1a_control |=
(acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
- PM1Bcontrol |=
+ pm1b_control |=
(acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
/*
@@ -314,37 +318,25 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
* poorly implemented hardware.
*/
- /* Write #1: fill in SLP_TYP data */
+ /* Write #1: write the SLP_TYP data to the PM1 Control registers */
- status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
- PM1Acontrol);
+ status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
- PM1Bcontrol);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
+ /* Insert the sleep enable (SLP_EN) bit */
- /* Insert SLP_ENABLE bit */
+ pm1a_control |= sleep_enable_reg_info->access_bit_mask;
+ pm1b_control |= sleep_enable_reg_info->access_bit_mask;
- PM1Acontrol |= sleep_enable_reg_info->access_bit_mask;
- PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask;
-
- /* Write #2: SLP_TYP + SLP_EN */
+ /* Flush caches, as per ACPI specification */
ACPI_FLUSH_CPU_CACHE();
- status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
- PM1Acontrol);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
+ /* Write #2: Write both SLP_TYP + SLP_EN */
- status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
- PM1Bcontrol);
+ status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -357,8 +349,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
* Wait ten seconds, then try again. This is to get S4/S5 to work on
* all machines.
*
- * We wait so long to allow chipsets that poll this reg very slowly to
- * still read the right value. Ideally, this block would go
+ * We wait so long to allow chipsets that poll this reg very slowly
+ * to still read the right value. Ideally, this block would go
* away entirely.
*/
acpi_os_stall(10000000);
@@ -374,7 +366,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Wait until we enter sleep state */
do {
- status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
+ status = acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS,
&in_value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
@@ -408,7 +400,10 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
- status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+ /* Clear the wake status bit (PM1) */
+
+ status =
+ acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -435,12 +430,13 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
ACPI_FLUSH_CPU_CACHE();
- status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+ status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.S4bios_request, 8);
do {
acpi_os_stall(1000);
- status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
+ status =
+ acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -471,8 +467,8 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
acpi_status status;
struct acpi_bit_register_info *sleep_type_reg_info;
struct acpi_bit_register_info *sleep_enable_reg_info;
- u32 PM1Acontrol;
- u32 PM1Bcontrol;
+ u32 pm1a_control;
+ u32 pm1b_control;
ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
@@ -486,38 +482,34 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
&acpi_gbl_sleep_type_b);
if (ACPI_SUCCESS(status)) {
sleep_type_reg_info =
- acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+ acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
sleep_enable_reg_info =
acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
/* Get current value of PM1A control */
status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
- &PM1Acontrol);
+ &pm1a_control);
if (ACPI_SUCCESS(status)) {
- /* Clear SLP_EN and SLP_TYP fields */
+ /* Clear the SLP_EN and SLP_TYP fields */
- PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
- sleep_enable_reg_info->
- access_bit_mask);
- PM1Bcontrol = PM1Acontrol;
+ pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
+ sleep_enable_reg_info->
+ access_bit_mask);
+ pm1b_control = pm1a_control;
- /* Insert SLP_TYP bits */
+ /* Insert the SLP_TYP bits */
- PM1Acontrol |=
- (acpi_gbl_sleep_type_a << sleep_type_reg_info->
- bit_position);
- PM1Bcontrol |=
- (acpi_gbl_sleep_type_b << sleep_type_reg_info->
- bit_position);
+ pm1a_control |= (acpi_gbl_sleep_type_a <<
+ sleep_type_reg_info->bit_position);
+ pm1b_control |= (acpi_gbl_sleep_type_b <<
+ sleep_type_reg_info->bit_position);
- /* Just ignore any errors */
+ /* Write the control registers and ignore any errors */
- (void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
- PM1Acontrol);
- (void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
- PM1Bcontrol);
+ (void)acpi_hw_write_pm1_control(pm1a_control,
+ pm1b_control);
}
}
@@ -603,19 +595,21 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
* it to determine whether the system is rebooting or resuming. Clear
* it for compatibility.
*/
- acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+ acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1);
acpi_gbl_system_awake_and_running = TRUE;
/* Enable power button */
(void)
- acpi_set_register(acpi_gbl_fixed_event_info
- [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info
+ [ACPI_EVENT_POWER_BUTTON].
+ enable_register_id, ACPI_ENABLE_EVENT);
(void)
- acpi_set_register(acpi_gbl_fixed_event_info
- [ACPI_EVENT_POWER_BUTTON].status_register_id, 1);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info
+ [ACPI_EVENT_POWER_BUTTON].
+ status_register_id, ACPI_CLEAR_STATUS);
arg.integer.value = ACPI_SST_WORKING;
status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
new file mode 100644
index 000000000000..bd3c937b0ac0
--- /dev/null
+++ b/drivers/acpi/acpica/hwvalid.c
@@ -0,0 +1,258 @@
+
+/******************************************************************************
+ *
+ * Module Name: hwvalid - I/O request validation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2009, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT ACPI_HARDWARE
+ACPI_MODULE_NAME("hwvalid")
+
+/* Local prototypes */
+static acpi_status
+acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width);
+
+/*
+ * Protected I/O ports. Some ports are always illegal, and some are
+ * conditionally illegal. This table must remain ordered by port address.
+ *
+ * The table is used to implement the Microsoft port access rules that
+ * first appeared in Windows XP. Some ports are always illegal, and some
+ * ports are only illegal if the BIOS calls _OSI with a win_xP string or
+ * later (meaning that the BIOS itelf is post-XP.)
+ *
+ * This provides ACPICA with the desired port protections and
+ * Microsoft compatibility.
+ *
+ * Description of port entries:
+ * DMA: DMA controller
+ * PIC0: Programmable Interrupt Controller (8259_a)
+ * PIT1: System Timer 1
+ * PIT2: System Timer 2 failsafe
+ * RTC: Real-time clock
+ * CMOS: Extended CMOS
+ * DMA1: DMA 1 page registers
+ * DMA1L: DMA 1 Ch 0 low page
+ * DMA2: DMA 2 page registers
+ * DMA2L: DMA 2 low page refresh
+ * ARBC: Arbitration control
+ * SETUP: Reserved system board setup
+ * POS: POS channel select
+ * PIC1: Cascaded PIC
+ * IDMA: ISA DMA
+ * ELCR: PIC edge/level registers
+ * PCI: PCI configuration space
+ */
+static const struct acpi_port_info acpi_protected_ports[] = {
+ {"DMA", 0x0000, 0x000F, ACPI_OSI_WIN_XP},
+ {"PIC0", 0x0020, 0x0021, ACPI_ALWAYS_ILLEGAL},
+ {"PIT1", 0x0040, 0x0043, ACPI_OSI_WIN_XP},
+ {"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP},
+ {"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP},
+ {"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP},
+ {"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP},
+ {"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP},
+ {"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP},
+ {"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP},
+ {"ARBC", 0x0090, 0x0091, ACPI_OSI_WIN_XP},
+ {"SETUP", 0x0093, 0x0094, ACPI_OSI_WIN_XP},
+ {"POS", 0x0096, 0x0097, ACPI_OSI_WIN_XP},
+ {"PIC1", 0x00A0, 0x00A1, ACPI_ALWAYS_ILLEGAL},
+ {"IDMA", 0x00C0, 0x00DF, ACPI_OSI_WIN_XP},
+ {"ELCR", 0x04D0, 0x04D1, ACPI_ALWAYS_ILLEGAL},
+ {"PCI", 0x0CF8, 0x0CFF, ACPI_OSI_WIN_XP}
+};
+
+#define ACPI_PORT_INFO_ENTRIES ACPI_ARRAY_LENGTH (acpi_protected_ports)
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_validate_io_request
+ *
+ * PARAMETERS: Address Address of I/O port/register
+ * bit_width Number of bits (8,16,32)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Validates an I/O request (address/length). Certain ports are
+ * always illegal and some ports are only illegal depending on
+ * the requests the BIOS AML code makes to the predefined
+ * _OSI method.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
+{
+ u32 i;
+ u32 byte_width;
+ acpi_io_address last_address;
+ const struct acpi_port_info *port_info;
+
+ ACPI_FUNCTION_TRACE(hw_validate_io_request);
+
+ /* Supported widths are 8/16/32 */
+
+ if ((bit_width != 8) && (bit_width != 16) && (bit_width != 32)) {
+ return AE_BAD_PARAMETER;
+ }
+
+ port_info = acpi_protected_ports;
+ byte_width = ACPI_DIV_8(bit_width);
+ last_address = address + byte_width - 1;
+
+ ACPI_DEBUG_PRINT((ACPI_DB_IO, "Address %p LastAddress %p Length %X",
+ ACPI_CAST_PTR(void, address), ACPI_CAST_PTR(void,
+ last_address),
+ byte_width));
+
+ /* Maximum 16-bit address in I/O space */
+
+ if (last_address > ACPI_UINT16_MAX) {
+ ACPI_ERROR((AE_INFO,
+ "Illegal I/O port address/length above 64K: 0x%p/%X",
+ ACPI_CAST_PTR(void, address), byte_width));
+ return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+ }
+
+ /* Exit if requested address is not within the protected port table */
+
+ if (address > acpi_protected_ports[ACPI_PORT_INFO_ENTRIES - 1].end) {
+ return_ACPI_STATUS(AE_OK);
+ }
+
+ /* Check request against the list of protected I/O ports */
+
+ for (i = 0; i < ACPI_PORT_INFO_ENTRIES; i++, port_info++) {
+ /*
+ * Check if the requested address range will write to a reserved
+ * port. Four cases to consider:
+ *
+ * 1) Address range is contained completely in the port address range
+ * 2) Address range overlaps port range at the port range start
+ * 3) Address range overlaps port range at the port range end
+ * 4) Address range completely encompasses the port range
+ */
+ if ((address <= port_info->end)
+ && (last_address >= port_info->start)) {
+
+ /* Port illegality may depend on the _OSI calls made by the BIOS */
+
+ if (acpi_gbl_osi_data >= port_info->osi_dependency) {
+ ACPI_ERROR((AE_INFO,
+ "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)",
+ ACPI_CAST_PTR(void, address),
+ byte_width, port_info->name,
+ port_info->start, port_info->end));
+
+ return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+ }
+ }
+
+ /* Finished if address range ends before the end of this port */
+
+ if (last_address <= port_info->end) {
+ break;
+ }
+ }
+
+ return_ACPI_STATUS(AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_read_port
+ *
+ * PARAMETERS: Address Address of I/O port/register to read
+ * Value Where value is placed
+ * Width Number of bits
+ *
+ * RETURN: Value read from port
+ *
+ * DESCRIPTION: Read data from an I/O port or register. This is a front-end
+ * to acpi_os_read_port that performs validation on both the port
+ * address and the length.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
+{
+ acpi_status status;
+
+ status = acpi_hw_validate_io_request(address, width);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ status = acpi_os_read_port(address, value, width);
+ return status;
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_write_port
+ *
+ * PARAMETERS: Address Address of I/O port/register to write
+ * Value Value to write
+ * Width Number of bits
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Write data to an I/O port or register. This is a front-end
+ * to acpi_os_write_port that performs validation on both the port
+ * address and the length.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
+{
+ acpi_status status;
+
+ status = acpi_hw_validate_io_request(address, width);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ status = acpi_os_write_port(address, value, width);
+ return status;
+}
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index ae597c0ab53f..9829979f2bdd 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -107,19 +107,18 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg)
ACPI_FUNCTION_NAME(acpi_read);
/*
- * Must have a valid pointer to a GAS structure, and
- * a non-zero address within. However, don't return an error
- * because the PM1A/B code must not fail if B isn't present.
+ * Must have a valid pointer to a GAS structure, and a non-zero address
+ * within.
*/
if (!reg) {
- return (AE_OK);
+ return (AE_BAD_PARAMETER);
}
/* Get a local copy of the address. Handles possible alignment issues */
ACPI_MOVE_64_TO_64(&address, &reg->address);
if (!address) {
- return (AE_OK);
+ return (AE_BAD_ADDRESS);
}
/* Supported widths are 8/16/32 */
@@ -134,8 +133,8 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg)
*value = 0;
/*
- * Two address spaces supported: Memory or IO.
- * PCI_Config is not supported here because the GAS struct is insufficient
+ * Two address spaces supported: Memory or IO. PCI_Config is
+ * not supported here because the GAS structure is insufficient
*/
switch (reg->space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
@@ -147,7 +146,7 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg)
case ACPI_ADR_SPACE_SYSTEM_IO:
status =
- acpi_os_read_port((acpi_io_address) address, value, width);
+ acpi_hw_read_port((acpi_io_address) address, value, width);
break;
default:
@@ -187,19 +186,18 @@ acpi_status acpi_write(u32 value, struct acpi_generic_address *reg)
ACPI_FUNCTION_NAME(acpi_write);
/*
- * Must have a valid pointer to a GAS structure, and
- * a non-zero address within. However, don't return an error
- * because the PM1A/B code must not fail if B isn't present.
+ * Must have a valid pointer to a GAS structure, and a non-zero address
+ * within.
*/
if (!reg) {
- return (AE_OK);
+ return (AE_BAD_PARAMETER);
}
/* Get a local copy of the address. Handles possible alignment issues */
ACPI_MOVE_64_TO_64(&address, &reg->address);
if (!address) {
- return (AE_OK);
+ return (AE_BAD_ADDRESS);
}
/* Supported widths are 8/16/32 */
@@ -222,7 +220,7 @@ acpi_status acpi_write(u32 value, struct acpi_generic_address *reg)
case ACPI_ADR_SPACE_SYSTEM_IO:
- status = acpi_os_write_port((acpi_io_address) address, value,
+ status = acpi_hw_write_port((acpi_io_address) address, value,
width);
break;
@@ -244,24 +242,36 @@ ACPI_EXPORT_SYMBOL(acpi_write)
/*******************************************************************************
*
- * FUNCTION: acpi_get_register_unlocked
+ * FUNCTION: acpi_read_bit_register
*
- * PARAMETERS: register_id - ID of ACPI bit_register to access
- * return_value - Value that was read from the register
+ * PARAMETERS: register_id - ID of ACPI Bit Register to access
+ * return_value - Value that was read from the register,
+ * normalized to bit position zero.
*
- * RETURN: Status and the value read from specified Register. Value
+ * RETURN: Status and the value read from the specified Register. Value
* returned is normalized to bit0 (is shifted all the way right)
*
* DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock.
*
+ * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ * PM2 Control.
+ *
+ * Note: The hardware lock is not required when reading the ACPI bit registers
+ * since almost all of them are single bit and it does not matter that
+ * the parent hardware register can be split across two physical
+ * registers. The only multi-bit field is SLP_TYP in the PM1 control
+ * register, but this field does not cross an 8-bit boundary (nor does
+ * it make much sense to actually read this field.)
+ *
******************************************************************************/
-acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value)
+acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value)
{
- u32 register_value = 0;
struct acpi_bit_register_info *bit_reg_info;
+ u32 register_value;
+ u32 value;
acpi_status status;
- ACPI_FUNCTION_TRACE(acpi_get_register_unlocked);
+ ACPI_FUNCTION_TRACE_U32(acpi_read_bit_register, register_id);
/* Get the info structure corresponding to the requested ACPI Register */
@@ -270,209 +280,133 @@ acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value)
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- /* Read from the register */
+ /* Read the entire parent register */
status = acpi_hw_register_read(bit_reg_info->parent_register,
&register_value);
-
- if (ACPI_SUCCESS(status)) {
-
- /* Normalize the value that was read */
-
- register_value =
- ((register_value & bit_reg_info->access_bit_mask)
- >> bit_reg_info->bit_position);
-
- *return_value = register_value;
-
- ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n",
- register_value,
- bit_reg_info->parent_register));
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- return_ACPI_STATUS(status);
-}
+ /* Normalize the value that was read, mask off other bits */
-ACPI_EXPORT_SYMBOL(acpi_get_register_unlocked)
+ value = ((register_value & bit_reg_info->access_bit_mask)
+ >> bit_reg_info->bit_position);
-/*******************************************************************************
- *
- * FUNCTION: acpi_get_register
- *
- * PARAMETERS: register_id - ID of ACPI bit_register to access
- * return_value - Value that was read from the register
- *
- * RETURN: Status and the value read from specified Register. Value
- * returned is normalized to bit0 (is shifted all the way right)
- *
- * DESCRIPTION: ACPI bit_register read function.
- *
- ******************************************************************************/
-acpi_status acpi_get_register(u32 register_id, u32 *return_value)
-{
- acpi_status status;
- acpi_cpu_flags flags;
-
- flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
- status = acpi_get_register_unlocked(register_id, return_value);
- acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
+ ACPI_DEBUG_PRINT((ACPI_DB_IO,
+ "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
+ register_id, bit_reg_info->parent_register,
+ register_value, value));
- return (status);
+ *return_value = value;
+ return_ACPI_STATUS(AE_OK);
}
-ACPI_EXPORT_SYMBOL(acpi_get_register)
+ACPI_EXPORT_SYMBOL(acpi_read_bit_register)
/*******************************************************************************
*
- * FUNCTION: acpi_set_register
+ * FUNCTION: acpi_write_bit_register
*
- * PARAMETERS: register_id - ID of ACPI bit_register to access
- * Value - (only used on write) value to write to the
- * Register, NOT pre-normalized to the bit pos
+ * PARAMETERS: register_id - ID of ACPI Bit Register to access
+ * Value - Value to write to the register, in bit
+ * position zero. The bit is automaticallly
+ * shifted to the correct position.
*
* RETURN: Status
*
- * DESCRIPTION: ACPI Bit Register write function.
+ * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
+ * since most operations require a read/modify/write sequence.
+ *
+ * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ * PM2 Control.
+ *
+ * Note that at this level, the fact that there may be actually two
+ * hardware registers (A and B - and B may not exist) is abstracted.
*
******************************************************************************/
-acpi_status acpi_set_register(u32 register_id, u32 value)
+acpi_status acpi_write_bit_register(u32 register_id, u32 value)
{
- u32 register_value = 0;
struct acpi_bit_register_info *bit_reg_info;
- acpi_status status;
acpi_cpu_flags lock_flags;
+ u32 register_value;
+ acpi_status status = AE_OK;
- ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id);
+ ACPI_FUNCTION_TRACE_U32(acpi_write_bit_register, register_id);
/* Get the info structure corresponding to the requested ACPI Register */
bit_reg_info = acpi_hw_get_bit_register_info(register_id);
if (!bit_reg_info) {
- ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X",
- register_id));
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
- /* Always do a register read first so we can insert the new bits */
-
- status = acpi_hw_register_read(bit_reg_info->parent_register,
- &register_value);
- if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
- }
-
/*
- * Decode the Register ID
- * Register ID = [Register block ID] | [bit ID]
- *
- * Check bit ID to fine locate Register offset.
- * Check Mask to determine Register offset, and then read-write.
+ * At this point, we know that the parent register is one of the
+ * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control
*/
- switch (bit_reg_info->parent_register) {
- case ACPI_REGISTER_PM1_STATUS:
-
+ if (bit_reg_info->parent_register != ACPI_REGISTER_PM1_STATUS) {
/*
- * Status Registers are different from the rest. Clear by
- * writing 1, and writing 0 has no effect. So, the only relevant
- * information is the single bit we're interested in, all others should
- * be written as 0 so they will be left unchanged.
+ * 1) Case for PM1 Enable, PM1 Control, and PM2 Control
+ *
+ * Perform a register read to preserve the bits that we are not
+ * interested in
*/
- value = ACPI_REGISTER_PREPARE_BITS(value,
- bit_reg_info->bit_position,
- bit_reg_info->
- access_bit_mask);
- if (value) {
- status =
- acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
- (u16) value);
- register_value = 0;
- }
- break;
-
- case ACPI_REGISTER_PM1_ENABLE:
-
- ACPI_REGISTER_INSERT_VALUE(register_value,
- bit_reg_info->bit_position,
- bit_reg_info->access_bit_mask,
- value);
-
- status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
- (u16) register_value);
- break;
-
- case ACPI_REGISTER_PM1_CONTROL:
-
- /*
- * Write the PM1 Control register.
- * Note that at this level, the fact that there are actually TWO
- * registers (A and B - and B may not exist) is abstracted.
- */
- ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n",
- register_value));
-
- ACPI_REGISTER_INSERT_VALUE(register_value,
- bit_reg_info->bit_position,
- bit_reg_info->access_bit_mask,
- value);
-
- status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
- (u16) register_value);
- break;
-
- case ACPI_REGISTER_PM2_CONTROL:
-
- status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
+ status = acpi_hw_register_read(bit_reg_info->parent_register,
&register_value);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
- ACPI_DEBUG_PRINT((ACPI_DB_IO,
- "PM2 control: Read %X from %8.8X%8.8X\n",
- register_value,
- ACPI_FORMAT_UINT64(acpi_gbl_FADT.
- xpm2_control_block.
- address)));
-
+ /*
+ * Insert the input bit into the value that was just read
+ * and write the register
+ */
ACPI_REGISTER_INSERT_VALUE(register_value,
bit_reg_info->bit_position,
bit_reg_info->access_bit_mask,
value);
- ACPI_DEBUG_PRINT((ACPI_DB_IO,
- "About to write %4.4X to %8.8X%8.8X\n",
- register_value,
- ACPI_FORMAT_UINT64(acpi_gbl_FADT.
- xpm2_control_block.
- address)));
+ status = acpi_hw_register_write(bit_reg_info->parent_register,
+ register_value);
+ } else {
+ /*
+ * 2) Case for PM1 Status
+ *
+ * The Status register is different from the rest. Clear an event
+ * by writing 1, writing 0 has no effect. So, the only relevant
+ * information is the single bit we're interested in, all others
+ * should be written as 0 so they will be left unchanged.
+ */
+ register_value = ACPI_REGISTER_PREPARE_BITS(value,
+ bit_reg_info->
+ bit_position,
+ bit_reg_info->
+ access_bit_mask);
- status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
- (u8) (register_value));
- break;
+ /* No need to write the register if value is all zeros */
- default:
- break;
+ if (register_value) {
+ status =
+ acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
+ register_value);
+ }
}
- unlock_and_exit:
-
- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
-
- /* Normalize the value that was read */
+ ACPI_DEBUG_PRINT((ACPI_DB_IO,
+ "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
+ register_id, bit_reg_info->parent_register, value,
+ register_value));
- ACPI_DEBUG_EXEC(register_value =
- ((register_value & bit_reg_info->access_bit_mask) >>
- bit_reg_info->bit_position));
+unlock_and_exit:
- ACPI_DEBUG_PRINT((ACPI_DB_IO,
- "Set bits: %8.8X actual %8.8X register %X\n", value,
- register_value, bit_reg_info->parent_register));
+ acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
return_ACPI_STATUS(status);
}
-ACPI_EXPORT_SYMBOL(acpi_set_register)
+ACPI_EXPORT_SYMBOL(acpi_write_bit_register)
/*******************************************************************************
*
@@ -534,7 +468,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
/* It must be of type Package */
- else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) {
+ else if (info->return_object->common.type != ACPI_TYPE_PACKAGE) {
ACPI_ERROR((AE_INFO,
"Sleep State return object is not a Package"));
status = AE_AML_OPERAND_TYPE;
@@ -555,12 +489,13 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
/* The first two elements must both be of type Integer */
- else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0])
+ else if (((info->return_object->package.elements[0])->common.type
!= ACPI_TYPE_INTEGER) ||
- (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1])
+ ((info->return_object->package.elements[1])->common.type
!= ACPI_TYPE_INTEGER)) {
ACPI_ERROR((AE_INFO,
- "Sleep State return package elements are not both Integers (%s, %s)",
+ "Sleep State return package elements are not both Integers "
+ "(%s, %s)",
acpi_ut_get_object_type_name(info->return_object->
package.elements[0]),
acpi_ut_get_object_type_name(info->return_object->
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c
index 88303ebe924c..9c3cdbe2d82a 100644
--- a/drivers/acpi/acpica/nsaccess.c
+++ b/drivers/acpi/acpica/nsaccess.c
@@ -118,9 +118,8 @@ acpi_status acpi_ns_root_initialize(void)
}
/*
- * Name entered successfully.
- * If entry in pre_defined_names[] specifies an
- * initial value, create the initial value.
+ * Name entered successfully. If entry in pre_defined_names[] specifies
+ * an initial value, create the initial value.
*/
if (init_val->val) {
status = acpi_os_predefined_override(init_val, &val);
@@ -178,9 +177,8 @@ acpi_status acpi_ns_root_initialize(void)
case ACPI_TYPE_STRING:
- /*
- * Build an object around the static string
- */
+ /* Build an object around the static string */
+
obj_desc->string.length =
(u32) ACPI_STRLEN(val);
obj_desc->string.pointer = val;
@@ -234,8 +232,7 @@ acpi_status acpi_ns_root_initialize(void)
/* Store pointer to value descriptor in the Node */
status = acpi_ns_attach_object(new_node, obj_desc,
- ACPI_GET_OBJECT_TYPE
- (obj_desc));
+ obj_desc->common.type);
/* Remove local reference to the object */
@@ -315,10 +312,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
return_ACPI_STATUS(AE_NO_NAMESPACE);
}
- /*
- * Get the prefix scope.
- * A null scope means use the root scope
- */
+ /* Get the prefix scope. A null scope means use the root scope */
+
if ((!scope_info) || (!scope_info->scope.node)) {
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
"Null scope prefix, using root node (%p)\n",
@@ -338,8 +333,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) {
/*
* This node might not be a actual "scope" node (such as a
- * Device/Method, etc.) It could be a Package or other object node.
- * Backup up the tree to find the containing scope node.
+ * Device/Method, etc.) It could be a Package or other object
+ * node. Backup up the tree to find the containing scope node.
*/
while (!acpi_ns_opens_scope(prefix_node->type) &&
prefix_node->type != ACPI_TYPE_ANY) {
@@ -349,7 +344,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
}
}
- /* Save type TBD: may be no longer necessary */
+ /* Save type. TBD: may be no longer necessary */
type_to_check_for = type;
@@ -414,6 +409,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
/* Name is fully qualified, no search rules apply */
search_parent_flag = ACPI_NS_NO_UPSEARCH;
+
/*
* Point past this prefix to the name segment
* part or the next Parent Prefix
@@ -429,7 +425,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
/* Current scope has no parent scope */
ACPI_ERROR((AE_INFO,
- "ACPI path has too many parent prefixes (^) - reached beyond root node"));
+ "ACPI path has too many parent prefixes (^) "
+ "- reached beyond root node"));
return_ACPI_STATUS(AE_NOT_FOUND);
}
}
@@ -531,9 +528,9 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
while (num_segments && current_node) {
num_segments--;
if (!num_segments) {
- /*
- * This is the last segment, enable typechecking
- */
+
+ /* This is the last segment, enable typechecking */
+
this_search_type = type;
/*
@@ -584,9 +581,9 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
if (num_segments > 0) {
/*
* If we have an alias to an object that opens a scope (such as a
- * device or processor), we need to dereference the alias here so that
- * we can access any children of the original node (via the remaining
- * segments).
+ * device or processor), we need to dereference the alias here so
+ * that we can access any children of the original node (via the
+ * remaining segments).
*/
if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
if (!this_node->object) {
@@ -594,8 +591,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
}
if (acpi_ns_opens_scope
- (((struct acpi_namespace_node *)this_node->
- object)->type)) {
+ (((struct acpi_namespace_node *)
+ this_node->object)->type)) {
this_node =
(struct acpi_namespace_node *)
this_node->object;
@@ -639,8 +636,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
/*
* If this is the last name segment and we are not looking for a
- * specific type, but the type of found object is known, use that type
- * to (later) see if it opens a scope.
+ * specific type, but the type of found object is known, use that
+ * type to (later) see if it opens a scope.
*/
if (type == ACPI_TYPE_ANY) {
type = this_node->type;
@@ -653,9 +650,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
current_node = this_node;
}
- /*
- * Always check if we need to open a new scope
- */
+ /* Always check if we need to open a new scope */
+
if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) {
/*
* If entry is a type which opens a scope, push the new scope on the
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c
index f976d848fe82..aceb93111967 100644
--- a/drivers/acpi/acpica/nsalloc.c
+++ b/drivers/acpi/acpica/nsalloc.c
@@ -76,8 +76,7 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name)
ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++);
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
- temp =
- acpi_gbl_ns_node_list->total_allocated -
+ temp = acpi_gbl_ns_node_list->total_allocated -
acpi_gbl_ns_node_list->total_freed;
if (temp > acpi_gbl_ns_node_list->max_occupied) {
acpi_gbl_ns_node_list->max_occupied = temp;
@@ -145,9 +144,8 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)
ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
- /*
- * Detach an object if there is one, then delete the node
- */
+ /* Detach an object if there is one, then delete the node */
+
acpi_ns_detach_object(node);
(void)acpi_os_release_object(acpi_gbl_namespace_cache, node);
return_VOID;
@@ -183,9 +181,8 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp
ACPI_FUNCTION_TRACE(ns_install_node);
/*
- * Get the owner ID from the Walk state
- * The owner ID is used to track table deletion and
- * deletion of objects created by methods
+ * Get the owner ID from the Walk state. The owner ID is used to track
+ * table deletion and deletion of objects created by methods.
*/
if (walk_state) {
owner_id = walk_state->owner_id;
@@ -260,9 +257,8 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
return_VOID;
}
- /*
- * Deallocate all children at this level
- */
+ /* Deallocate all children at this level */
+
do {
/* Get the things we need */
@@ -285,9 +281,8 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
"Object %p, Remaining %X\n", child_node,
acpi_gbl_current_node_count));
- /*
- * Detach an object if there is one, then free the child node
- */
+ /* Detach an object if there is one, then free the child node */
+
acpi_ns_detach_object(child_node);
/* Now we can delete the node */
@@ -304,7 +299,6 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
/* Clear the parent's child pointer */
parent_node->child = NULL;
-
return_VOID;
}
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
index 0da33c8e9ba2..2bad613db73a 100644
--- a/drivers/acpi/acpica/nsdump.c
+++ b/drivers/acpi/acpica/nsdump.c
@@ -181,6 +181,12 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
}
this_node = acpi_ns_map_handle_to_node(obj_handle);
+ if (!this_node) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n",
+ obj_handle));
+ return (AE_OK);
+ }
+
type = this_node->type;
/* Check if the owner matches */
@@ -214,9 +220,8 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node));
}
- /*
- * Now we can print out the pertinent information
- */
+ /* Now we can print out the pertinent information */
+
acpi_os_printf(" %-12s %p %2.2X ",
acpi_ut_get_type_name(type), this_node,
this_node->owner_id);
@@ -509,7 +514,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
case ACPI_DESC_TYPE_OPERAND:
- obj_type = ACPI_GET_OBJECT_TYPE(obj_desc);
+ obj_type = obj_desc->common.type;
if (obj_type > ACPI_TYPE_LOCAL_MAX) {
acpi_os_printf
@@ -539,9 +544,8 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
goto cleanup;
}
- /*
- * Valid object, get the pointer to next level, if any
- */
+ /* Valid object, get the pointer to next level, if any */
+
switch (obj_type) {
case ACPI_TYPE_BUFFER:
case ACPI_TYPE_STRING:
@@ -602,14 +606,14 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
* display_type - 0 or ACPI_DISPLAY_SUMMARY
* max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX
* for an effectively unlimited depth.
- * owner_id - Dump only objects owned by this ID. Use
+ * owner_id - Dump only objects owned by this ID. Use
* ACPI_UINT32_MAX to match all owners.
* start_handle - Where in namespace to start/end search
*
* RETURN: None
*
- * DESCRIPTION: Dump typed objects within the loaded namespace.
- * Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
+ * DESCRIPTION: Dump typed objects within the loaded namespace. Uses
+ * acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c
index 0f3d5f9b5966..8e7dec1176c9 100644
--- a/drivers/acpi/acpica/nseval.c
+++ b/drivers/acpi/acpica/nseval.c
@@ -155,7 +155,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
}
- ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:",
+ ACPI_DUMP_PATHNAME(info->resolved_node, "ACPI: Execute Method",
ACPI_LV_INFO, _COMPONENT);
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c
index 13501cb81863..2adfcf329e15 100644
--- a/drivers/acpi/acpica/nsinit.c
+++ b/drivers/acpi/acpica/nsinit.c
@@ -103,7 +103,8 @@ acpi_status acpi_ns_initialize_objects(void)
}
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
- "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n",
+ "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd "
+ "Buffers %hd/%hd Packages (%hd nodes)\n",
info.op_region_init, info.op_region_count,
info.field_init, info.field_count,
info.buffer_init, info.buffer_count,
@@ -148,7 +149,8 @@ acpi_status acpi_ns_initialize_devices(void)
info.num_INI = 0;
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
- "Initializing Device/Processor/Thermal objects by executing _INI methods:"));
+ "Initializing Device/Processor/Thermal objects "
+ "by executing _INI methods:"));
/* Tree analysis: find all subtrees that contain _INI methods */
@@ -180,7 +182,8 @@ acpi_status acpi_ns_initialize_devices(void)
}
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
- "\nExecuted %hd _INI methods requiring %hd _STA executions (examined %hd objects)\n",
+ "\nExecuted %hd _INI methods requiring %hd _STA executions "
+ "(examined %hd objects)\n",
info.num_INI, info.num_STA, info.device_count));
return_ACPI_STATUS(status);
@@ -263,16 +266,14 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
return (AE_OK);
}
- /*
- * If the object is already initialized, nothing else to do
- */
+ /* If the object is already initialized, nothing else to do */
+
if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
return (AE_OK);
}
- /*
- * Must lock the interpreter before executing AML code
- */
+ /* Must lock the interpreter before executing AML code */
+
acpi_ex_enter_interpreter();
/*
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c
index a0ba9e12379e..dcd7a6adbbbc 100644
--- a/drivers/acpi/acpica/nsload.c
+++ b/drivers/acpi/acpica/nsload.c
@@ -128,12 +128,12 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
* parse trees.
*/
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "**** Begin Table Method Parsing and Object Initialization ****\n"));
+ "**** Begin Table Method Parsing and Object Initialization\n"));
status = acpi_ds_initialize_objects(table_index, node);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "**** Completed Table Method Parsing and Object Initialization ****\n"));
+ "**** Completed Table Method Parsing and Object Initialization\n"));
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c
index 08a97a57f8f9..3eb20bfda9d8 100644
--- a/drivers/acpi/acpica/nsobject.c
+++ b/drivers/acpi/acpica/nsobject.c
@@ -209,8 +209,7 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node)
obj_desc = node->object;
- if (!obj_desc ||
- (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA)) {
+ if (!obj_desc || (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
return_VOID;
}
@@ -220,8 +219,7 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node)
if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) {
node->object = obj_desc->common.next_object;
if (node->object &&
- (ACPI_GET_OBJECT_TYPE(node->object) !=
- ACPI_TYPE_LOCAL_DATA)) {
+ ((node->object)->common.type != ACPI_TYPE_LOCAL_DATA)) {
node->object = node->object->common.next_object;
}
}
@@ -267,7 +265,7 @@ union acpi_operand_object *acpi_ns_get_attached_object(struct
((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND)
&& (ACPI_GET_DESCRIPTOR_TYPE(node->object) !=
ACPI_DESC_TYPE_NAMED))
- || (ACPI_GET_OBJECT_TYPE(node->object) == ACPI_TYPE_LOCAL_DATA)) {
+ || ((node->object)->common.type == ACPI_TYPE_LOCAL_DATA)) {
return_PTR(NULL);
}
@@ -294,9 +292,9 @@ union acpi_operand_object *acpi_ns_get_secondary_object(union
ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc);
if ((!obj_desc) ||
- (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) ||
+ (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) ||
(!obj_desc->common.next_object) ||
- (ACPI_GET_OBJECT_TYPE(obj_desc->common.next_object) ==
+ ((obj_desc->common.next_object)->common.type ==
ACPI_TYPE_LOCAL_DATA)) {
return_PTR(NULL);
}
@@ -331,7 +329,7 @@ acpi_ns_attach_data(struct acpi_namespace_node *node,
prev_obj_desc = NULL;
obj_desc = node->object;
while (obj_desc) {
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+ if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
(obj_desc->data.handler == handler)) {
return (AE_ALREADY_EXISTS);
}
@@ -385,7 +383,7 @@ acpi_ns_detach_data(struct acpi_namespace_node * node,
prev_obj_desc = NULL;
obj_desc = node->object;
while (obj_desc) {
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+ if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
(obj_desc->data.handler == handler)) {
if (prev_obj_desc) {
prev_obj_desc->common.next_object =
@@ -428,7 +426,7 @@ acpi_ns_get_attached_data(struct acpi_namespace_node * node,
obj_desc = node->object;
while (obj_desc) {
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+ if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
(obj_desc->data.handler == handler)) {
*data = obj_desc->data.pointer;
return (AE_OK);
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c
index b9e8d0070b6f..662a4bd5b621 100644
--- a/drivers/acpi/acpica/nsparse.c
+++ b/drivers/acpi/acpica/nsparse.c
@@ -176,9 +176,8 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
* performs another complete parse of the AML.
*/
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
- status =
- acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index,
- start_node);
+ status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
+ table_index, start_node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -193,9 +192,8 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
* parse objects are all cached.
*/
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
- status =
- acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index,
- start_node);
+ status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
+ table_index, start_node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index 452703290d35..d9e8cbc6e679 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -79,7 +79,9 @@ acpi_ns_check_package(char *pathname,
static acpi_status
acpi_ns_check_package_elements(char *pathname,
union acpi_operand_object **elements,
- u8 type1, u32 count1, u8 type2, u32 count2);
+ u8 type1,
+ u32 count1,
+ u8 type2, u32 count2, u32 start_index);
static acpi_status
acpi_ns_check_object_type(char *pathname,
@@ -221,7 +223,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
/* For returned Package objects, check the type of all sub-objects */
- if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) {
+ if (return_object->common.type == ACPI_TYPE_PACKAGE) {
status =
acpi_ns_check_package(pathname, return_object_ptr,
predefined);
@@ -302,7 +304,8 @@ acpi_ns_check_parameter_count(char *pathname,
if ((user_param_count != required_params_current) &&
(user_param_count != required_params_old)) {
ACPI_WARNING((AE_INFO,
- "%s: Parameter count mismatch - caller passed %d, ACPI requires %d",
+ "%s: Parameter count mismatch - "
+ "caller passed %d, ACPI requires %d",
pathname, user_param_count,
required_params_current));
}
@@ -472,7 +475,7 @@ acpi_ns_check_package(char *pathname,
package->ret_info.
object_type2,
package->ret_info.
- count2);
+ count2, 0);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -623,7 +626,7 @@ acpi_ns_check_package(char *pathname,
object_type2,
package->
ret_info.
- count2);
+ count2, 0);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -672,7 +675,8 @@ acpi_ns_check_package(char *pathname,
object_type1,
sub_package->
package.
- count, 0, 0);
+ count, 0, 0,
+ 0);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -710,7 +714,8 @@ acpi_ns_check_package(char *pathname,
ret_info.
object_type1,
(expected_count
- - 1), 0, 0);
+ - 1), 0, 0,
+ 1);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -758,6 +763,7 @@ acpi_ns_check_package(char *pathname,
* Count1 - Count for first group
* Type2 - Object type for second group
* Count2 - Count for second group
+ * start_index - Start of the first group of elements
*
* RETURN: Status
*
@@ -769,7 +775,9 @@ acpi_ns_check_package(char *pathname,
static acpi_status
acpi_ns_check_package_elements(char *pathname,
union acpi_operand_object **elements,
- u8 type1, u32 count1, u8 type2, u32 count2)
+ u8 type1,
+ u32 count1,
+ u8 type2, u32 count2, u32 start_index)
{
union acpi_operand_object **this_element = elements;
acpi_status status;
@@ -782,7 +790,7 @@ acpi_ns_check_package_elements(char *pathname,
*/
for (i = 0; i < count1; i++) {
status = acpi_ns_check_object_type(pathname, this_element,
- type1, i);
+ type1, i + start_index);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -791,7 +799,8 @@ acpi_ns_check_package_elements(char *pathname,
for (i = 0; i < count2; i++) {
status = acpi_ns_check_object_type(pathname, this_element,
- type2, (i + count1));
+ type2,
+ (i + count1 + start_index));
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -858,7 +867,7 @@ acpi_ns_check_object_type(char *pathname,
* from all of the predefined names (including elements of returned
* packages)
*/
- switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+ switch (return_object->common.type) {
case ACPI_TYPE_INTEGER:
return_btype = ACPI_RTYPE_INTEGER;
break;
@@ -901,7 +910,7 @@ acpi_ns_check_object_type(char *pathname,
/* For reference objects, check that the reference type is correct */
- if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) {
+ if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
status = acpi_ns_check_reference(pathname, return_object);
}
@@ -974,7 +983,8 @@ acpi_ns_check_reference(char *pathname,
}
ACPI_WARNING((AE_INFO,
- "%s: Return type mismatch - unexpected reference object type [%s] %2.2X",
+ "%s: Return type mismatch - "
+ "unexpected reference object type [%s] %2.2X",
pathname, acpi_ut_get_reference_name(return_object),
return_object->reference.class));
@@ -1006,7 +1016,7 @@ acpi_ns_repair_object(u32 expected_btypes,
union acpi_operand_object *new_object;
acpi_size length;
- switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+ switch (return_object->common.type) {
case ACPI_TYPE_BUFFER:
if (!(expected_btypes & ACPI_RTYPE_STRING)) {
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c
index 6fea13f3f52d..f9b4f51bf8f2 100644
--- a/drivers/acpi/acpica/nssearch.c
+++ b/drivers/acpi/acpica/nssearch.c
@@ -167,7 +167,8 @@ acpi_ns_search_one_scope(u32 target_name,
/* Searched entire namespace level, not found */
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
- "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
+ "Name [%4.4s] (%s) not found in search in scope [%4.4s] "
+ "%p first child %p\n",
ACPI_CAST_PTR(char, &target_name),
acpi_ut_get_type_name(type),
acpi_ut_get_node_name(parent_node), parent_node,
@@ -239,9 +240,8 @@ acpi_ns_search_parent_tree(u32 target_name,
acpi_ut_get_node_name(parent_node),
ACPI_CAST_PTR(char, &target_name)));
- /*
- * Search parents until target is found or we have backed up to the root
- */
+ /* Search parents until target is found or we have backed up to the root */
+
while (parent_node) {
/*
* Search parent scope. Use TYPE_ANY because we don't care about the
@@ -395,9 +395,9 @@ acpi_ns_search_and_enter(u32 target_name,
return_ACPI_STATUS(AE_NO_MEMORY);
}
#ifdef ACPI_ASL_COMPILER
- /*
- * Node is an object defined by an External() statement
- */
+
+ /* Node is an object defined by an External() statement */
+
if (flags & ACPI_NS_EXTERNAL) {
new_node->flags |= ANOBJ_IS_EXTERNAL;
}
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c
index 3e1149bf4aa5..78277ed08339 100644
--- a/drivers/acpi/acpica/nsutils.c
+++ b/drivers/acpi/acpica/nsutils.c
@@ -325,9 +325,8 @@ void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
next_external_char++;
}
} else {
- /*
- * Handle Carat prefixes
- */
+ /* Handle Carat prefixes */
+
while (*next_external_char == '^') {
info->num_carats++;
next_external_char++;
@@ -552,9 +551,8 @@ acpi_ns_externalize_name(u32 internal_name_length,
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- /*
- * Check for a prefix (one '\' | one or more '^').
- */
+ /* Check for a prefix (one '\' | one or more '^') */
+
switch (internal_name[0]) {
case '\\':
prefix_length = 1;
@@ -580,7 +578,7 @@ acpi_ns_externalize_name(u32 internal_name_length,
}
/*
- * Check for object names. Note that there could be 0-255 of these
+ * Check for object names. Note that there could be 0-255 of these
* 4-byte elements.
*/
if (prefix_length < internal_name_length) {
@@ -637,9 +635,8 @@ acpi_ns_externalize_name(u32 internal_name_length,
return_ACPI_STATUS(AE_BAD_PATHNAME);
}
- /*
- * Build converted_name
- */
+ /* Build the converted_name */
+
*converted_name = ACPI_ALLOCATE_ZEROED(required_length);
if (!(*converted_name)) {
return_ACPI_STATUS(AE_NO_MEMORY);
@@ -685,6 +682,9 @@ acpi_ns_externalize_name(u32 internal_name_length,
* and keep all pointers within this subsystem - however this introduces
* more (and perhaps unnecessary) overhead.
*
+ * The current implemenation is basically a placeholder until such time comes
+ * that it is needed.
+ *
******************************************************************************/
struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
@@ -692,9 +692,8 @@ struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
ACPI_FUNCTION_ENTRY();
- /*
- * Simple implementation
- */
+ /* Parameter validation */
+
if ((!handle) || (handle == ACPI_ROOT_OBJECT)) {
return (acpi_gbl_root_node);
}
@@ -872,7 +871,7 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
(flags | ACPI_NS_DONT_OPEN_SCOPE), NULL,
return_node);
if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n",
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s, %s\n",
pathname, acpi_format_exception(status)));
}
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c
index 200895fa2728..83e3aa6d4b9b 100644
--- a/drivers/acpi/acpica/nswalk.c
+++ b/drivers/acpi/acpica/nswalk.c
@@ -135,8 +135,8 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct
* starting (and ending) at the node specified by start_handle.
* The user_function is called whenever a node that matches
* the type parameter is found. If the user function returns
- * a non-zero value, the search is terminated immediately and this
- * value is returned to the caller.
+ * a non-zero value, the search is terminated immediately and
+ * this value is returned to the caller.
*
* The point of this procedure is to provide a generic namespace
* walk routine that can be called from multiple places to
@@ -200,10 +200,10 @@ acpi_ns_walk_namespace(acpi_object_type type,
/*
* Ignore all temporary namespace nodes (created during control
* method execution) unless told otherwise. These temporary nodes
- * can cause a race condition because they can be deleted during the
- * execution of the user function (if the namespace is unlocked before
- * invocation of the user function.) Only the debugger namespace dump
- * will examine the temporary nodes.
+ * can cause a race condition because they can be deleted during
+ * the execution of the user function (if the namespace is
+ * unlocked before invocation of the user function.) Only the
+ * debugger namespace dump will examine the temporary nodes.
*/
if ((child_node->flags & ANOBJ_TEMPORARY) &&
!(flags & ACPI_NS_WALK_TEMP_NODES)) {
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c
index 22a7171ac1ed..045054037c2d 100644
--- a/drivers/acpi/acpica/nsxfeval.c
+++ b/drivers/acpi/acpica/nsxfeval.c
@@ -387,8 +387,7 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
/* We are interested in reference objects only */
- if (ACPI_GET_OBJECT_TYPE(info->return_object) !=
- ACPI_TYPE_LOCAL_REFERENCE) {
+ if ((info->return_object)->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
return;
}
@@ -476,21 +475,40 @@ acpi_walk_namespace(acpi_object_type type,
}
/*
- * Lock the namespace around the walk.
- * The namespace will be unlocked/locked around each call
- * to the user function - since this function
- * must be allowed to make Acpi calls itself.
+ * Need to acquire the namespace reader lock to prevent interference
+ * with any concurrent table unloads (which causes the deletion of
+ * namespace objects). We cannot allow the deletion of a namespace node
+ * while the user function is using it. The exception to this are the
+ * nodes created and deleted during control method execution -- these
+ * nodes are marked as temporary nodes and are ignored by the namespace
+ * walk. Thus, control methods can be executed while holding the
+ * namespace deletion lock (and the user function can execute control
+ * methods.)
+ */
+ status = acpi_ut_acquire_read_lock(&acpi_gbl_namespace_rw_lock);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ /*
+ * Lock the namespace around the walk. The namespace will be
+ * unlocked/locked around each call to the user function - since the user
+ * function must be allowed to make ACPICA calls itself (for example, it
+ * will typically execute control methods during device enumeration.)
*/
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto unlock_and_exit;
}
status = acpi_ns_walk_namespace(type, start_object, max_depth,
- ACPI_NS_WALK_UNLOCK,
- user_function, context, return_value);
+ ACPI_NS_WALK_UNLOCK, user_function,
+ context, return_value);
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+ unlock_and_exit:
+ (void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock);
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c
index 52865ee6bc77..b6667ff059e5 100644
--- a/drivers/acpi/acpica/rscalc.c
+++ b/drivers/acpi/acpica/rscalc.c
@@ -557,9 +557,9 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
table_index++) {
if (*sub_object_list && /* Null object allowed */
((ACPI_TYPE_STRING ==
- ACPI_GET_OBJECT_TYPE(*sub_object_list)) ||
+ (*sub_object_list)->common.type) ||
((ACPI_TYPE_LOCAL_REFERENCE ==
- ACPI_GET_OBJECT_TYPE(*sub_object_list)) &&
+ (*sub_object_list)->common.type) &&
((*sub_object_list)->reference.class ==
ACPI_REFCLASS_NAME)))) {
name_found = TRUE;
@@ -575,8 +575,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
/* Was a String type found? */
if (name_found) {
- if (ACPI_GET_OBJECT_TYPE(*sub_object_list) ==
- ACPI_TYPE_STRING) {
+ if ((*sub_object_list)->common.type == ACPI_TYPE_STRING) {
/*
* The length String.Length field does not include the
* terminating NULL, add 1
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c
index 61566b1a0616..663f692fffcf 100644
--- a/drivers/acpi/acpica/rscreate.c
+++ b/drivers/acpi/acpica/rscreate.c
@@ -212,7 +212,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* Each element of the top-level package must also be a package */
- if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) {
+ if ((*top_object_list)->common.type != ACPI_TYPE_PACKAGE) {
ACPI_ERROR((AE_INFO,
"(PRT[%X]) Need sub-package, found %s",
index,
@@ -240,7 +240,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 1) First subobject: Dereference the PRT.Address */
obj_desc = sub_object_list[0];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].Address) Need Integer, found %s",
index,
@@ -253,7 +253,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 2) Second subobject: Dereference the PRT.Pin */
obj_desc = sub_object_list[1];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].Pin) Need Integer, found %s",
index,
@@ -265,7 +265,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
* If BIOS erroneously reversed the _PRT source_name and source_index,
* then reverse them back.
*/
- if (ACPI_GET_OBJECT_TYPE(sub_object_list[3]) !=
+ if ((sub_object_list[3])->common.type !=
ACPI_TYPE_INTEGER) {
if (acpi_gbl_enable_interpreter_slack) {
source_name_index = 3;
@@ -291,8 +291,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
* other ACPI implementations.
*/
obj_desc = sub_object_list[3];
- if (!obj_desc
- || (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
+ if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
sub_object_list[3] = sub_object_list[2];
sub_object_list[2] = obj_desc;
@@ -307,7 +306,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
*/
obj_desc = sub_object_list[source_name_index];
if (obj_desc) {
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
if (obj_desc->reference.class !=
@@ -380,7 +379,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 4) Fourth subobject: Dereference the PRT.source_index */
obj_desc = sub_object_list[source_index_index];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].SourceIndex) Need Integer, found %s",
index,
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 3636e4f8fb73..71e655d14cb0 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -57,6 +57,8 @@ static void acpi_tb_convert_fadt(void);
static void acpi_tb_validate_fadt(void);
+static void acpi_tb_setup_fadt_registers(void);
+
/* Table for conversion of FADT to common internal format and FADT validation */
typedef struct acpi_fadt_info {
@@ -130,7 +132,38 @@ static struct acpi_fadt_info fadt_info_table[] = {
ACPI_FADT_SEPARATE_LENGTH}
};
-#define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
+#define ACPI_FADT_INFO_ENTRIES \
+ (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
+
+/* Table used to split Event Blocks into separate status/enable registers */
+
+typedef struct acpi_fadt_pm_info {
+ struct acpi_generic_address *target;
+ u8 source;
+ u8 register_num;
+
+} acpi_fadt_pm_info;
+
+static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
+ {&acpi_gbl_xpm1a_status,
+ ACPI_FADT_OFFSET(xpm1a_event_block),
+ 0},
+
+ {&acpi_gbl_xpm1a_enable,
+ ACPI_FADT_OFFSET(xpm1a_event_block),
+ 1},
+
+ {&acpi_gbl_xpm1b_status,
+ ACPI_FADT_OFFSET(xpm1b_event_block),
+ 0},
+
+ {&acpi_gbl_xpm1b_enable,
+ ACPI_FADT_OFFSET(xpm1b_event_block),
+ 1}
+};
+
+#define ACPI_FADT_PM_INFO_ENTRIES \
+ (sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info))
/*******************************************************************************
*
@@ -172,7 +205,6 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
* FUNCTION: acpi_tb_parse_fadt
*
* PARAMETERS: table_index - Index for the FADT
- * Flags - Flags
*
* RETURN: None
*
@@ -181,7 +213,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
*
******************************************************************************/
-void acpi_tb_parse_fadt(u32 table_index, u8 flags)
+void acpi_tb_parse_fadt(u32 table_index)
{
u32 length;
struct acpi_table_header *table;
@@ -208,7 +240,7 @@ void acpi_tb_parse_fadt(u32 table_index, u8 flags)
*/
(void)acpi_tb_verify_checksum(table, length);
- /* Obtain a local copy of the FADT in common ACPI 2.0+ format */
+ /* Create a local copy of the FADT in common ACPI 2.0+ format */
acpi_tb_create_local_fadt(table, length);
@@ -219,10 +251,10 @@ void acpi_tb_parse_fadt(u32 table_index, u8 flags)
/* Obtain the DSDT and FACS tables via their addresses within the FADT */
acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
- flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
+ ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs,
- flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
+ ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
}
/*******************************************************************************
@@ -266,11 +298,17 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
ACPI_MEMCPY(&acpi_gbl_FADT, table,
ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
- /*
- * 1) Convert the local copy of the FADT to the common internal format
- * 2) Validate some of the important values within the FADT
- */
+ /* Convert the local copy of the FADT to the common internal format */
+
acpi_tb_convert_fadt();
+
+ /* Validate FADT values now, before we make any changes */
+
+ acpi_tb_validate_fadt();
+
+ /* Initialize the global ACPI register structures */
+
+ acpi_tb_setup_fadt_registers();
}
/*******************************************************************************
@@ -282,31 +320,35 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
* RETURN: None
*
* DESCRIPTION: Converts all versions of the FADT to a common internal format.
- * Expand all 32-bit addresses to 64-bit.
+ * Expand 32-bit addresses to 64-bit as necessary.
*
* NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt),
* and must contain a copy of the actual FADT.
*
- * ACPICA will use the "X" fields of the FADT for all addresses.
+ * Notes on 64-bit register addresses:
+ *
+ * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
+ * fields of the FADT for all ACPI register addresses.
*
- * "X" fields are optional extensions to the original V1.0 fields. Even if
- * they are present in the structure, they can be optionally not used by
- * setting them to zero. Therefore, we must selectively expand V1.0 fields
- * if the corresponding X field is zero.
+ * The 64-bit "X" fields are optional extensions to the original 32-bit FADT
+ * V1.0 fields. Even if they are present in the FADT, they are optional and
+ * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
+ * 32-bit V1.0 fields if the corresponding X field is zero.
*
- * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding
- * "X" fields.
+ * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the
+ * corresponding "X" fields in the internal FADT.
*
- * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by
- * expanding the corresponding ACPI 1.0 field.
+ * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
+ * to the corresponding 64-bit X fields. For compatibility with other ACPI
+ * implementations, we ignore the 64-bit field if the 32-bit field is valid,
+ * regardless of whether the host OS is 32-bit or 64-bit.
*
******************************************************************************/
static void acpi_tb_convert_fadt(void)
{
- u8 pm1_register_bit_width;
- u8 pm1_register_byte_width;
- struct acpi_generic_address *target64;
+ struct acpi_generic_address *address64;
+ u32 address32;
u32 i;
/* Update the local FADT table header length */
@@ -355,140 +397,56 @@ static void acpi_tb_convert_fadt(void)
* Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
* generic address structures as necessary. Later code will always use
* the 64-bit address structures.
+ *
+ * March 2009:
+ * We now always use the 32-bit address if it is valid (non-null). This
+ * is not in accordance with the ACPI specification which states that
+ * the 64-bit address supersedes the 32-bit version, but we do this for
+ * compatibility with other ACPI implementations. Most notably, in the
+ * case where both the 32 and 64 versions are non-null, we use the 32-bit
+ * version. This is the only address that is guaranteed to have been
+ * tested by the BIOS manufacturer.
*/
for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
- target64 =
- ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
- fadt_info_table[i].address64);
+ address32 = *ACPI_ADD_PTR(u32,
+ &acpi_gbl_FADT,
+ fadt_info_table[i].address32);
- /* Expand only if the 64-bit X target is null */
+ address64 = ACPI_ADD_PTR(struct acpi_generic_address,
+ &acpi_gbl_FADT,
+ fadt_info_table[i].address64);
- if (!target64->address) {
+ /*
+ * If both 32- and 64-bit addresses are valid (non-zero),
+ * they must match.
+ */
+ if (address64->address && address32 &&
+ (address64->address != (u64) address32)) {
+ ACPI_ERROR((AE_INFO,
+ "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 32",
+ fadt_info_table[i].name, address32,
+ ACPI_FORMAT_UINT64(address64->address)));
+ }
- /* The space_id is always I/O for the 32-bit legacy address fields */
+ /* Always use 32-bit address if it is valid (non-null) */
- acpi_tb_init_generic_address(target64,
+ if (address32) {
+ /*
+ * Copy the 32-bit address to the 64-bit GAS structure. The
+ * Space ID is always I/O for 32-bit legacy address fields
+ */
+ acpi_tb_init_generic_address(address64,
ACPI_ADR_SPACE_SYSTEM_IO,
*ACPI_ADD_PTR(u8,
&acpi_gbl_FADT,
fadt_info_table
[i].length),
- (u64) * ACPI_ADD_PTR(u32,
- &acpi_gbl_FADT,
- fadt_info_table
- [i].
- address32));
- }
- }
-
- /* Validate FADT values now, before we make any changes */
-
- acpi_tb_validate_fadt();
-
- /*
- * Optionally check all register lengths against the default values and
- * update them if they are incorrect.
- */
- if (acpi_gbl_use_default_register_widths) {
- for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
- target64 =
- ACPI_ADD_PTR(struct acpi_generic_address,
- &acpi_gbl_FADT,
- fadt_info_table[i].address64);
-
- /*
- * If a valid register (Address != 0) and the (default_length > 0)
- * (Not a GPE register), then check the width against the default.
- */
- if ((target64->address) &&
- (fadt_info_table[i].default_length > 0) &&
- (fadt_info_table[i].default_length !=
- target64->bit_width)) {
- ACPI_WARNING((AE_INFO,
- "Invalid length for %s: %d, using default %d",
- fadt_info_table[i].name,
- target64->bit_width,
- fadt_info_table[i].
- default_length));
-
- /* Incorrect size, set width to the default */
-
- target64->bit_width =
- fadt_info_table[i].default_length;
- }
+ address32);
}
}
-
- /*
- * Get the length of the individual PM1 registers (enable and status).
- * Each register is defined to be (event block length / 2).
- */
- pm1_register_bit_width =
- (u8)ACPI_DIV_2(acpi_gbl_FADT.xpm1a_event_block.bit_width);
- pm1_register_byte_width = (u8)ACPI_DIV_8(pm1_register_bit_width);
-
- /*
- * Adjust the lengths of the PM1 Event Blocks so that they can be used to
- * access the PM1 status register(s). Use (width / 2)
- */
- acpi_gbl_FADT.xpm1a_event_block.bit_width = pm1_register_bit_width;
- acpi_gbl_FADT.xpm1b_event_block.bit_width = pm1_register_bit_width;
-
- /*
- * Calculate separate GAS structs for the PM1 Enable registers.
- * These addresses do not appear (directly) in the FADT, so it is
- * useful to calculate them once, here.
- *
- * The PM event blocks are split into two register blocks, first is the
- * PM Status Register block, followed immediately by the PM Enable
- * Register block. Each is of length (xpm1x_event_block.bit_width/2).
- *
- * On various systems the v2 fields (and particularly the bit widths)
- * cannot be relied upon, though. Hence resort to using the v1 length
- * here (and warn about the inconsistency).
- */
- if (acpi_gbl_FADT.xpm1a_event_block.bit_width
- != acpi_gbl_FADT.pm1_event_length * 8)
- printk(KERN_WARNING "FADT: "
- "X_PM1a_EVT_BLK.bit_width (%u) does not match"
- " PM1_EVT_LEN (%u)\n",
- acpi_gbl_FADT.xpm1a_event_block.bit_width,
- acpi_gbl_FADT.pm1_event_length);
-
- /* The PM1A register block is required */
-
- acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
- acpi_gbl_FADT.xpm1a_event_block.space_id,
- pm1_register_byte_width,
- (acpi_gbl_FADT.xpm1a_event_block.address +
- pm1_register_byte_width));
- /* Don't forget to copy space_id of the GAS */
- acpi_gbl_xpm1a_enable.space_id =
- acpi_gbl_FADT.xpm1a_event_block.space_id;
-
- /* The PM1B register block is optional, ignore if not present */
-
- if (acpi_gbl_FADT.xpm1b_event_block.address) {
- if (acpi_gbl_FADT.xpm1b_event_block.bit_width
- != acpi_gbl_FADT.pm1_event_length * 8)
- printk(KERN_WARNING "FADT: "
- "X_PM1b_EVT_BLK.bit_width (%u) does not match"
- " PM1_EVT_LEN (%u)\n",
- acpi_gbl_FADT.xpm1b_event_block.bit_width,
- acpi_gbl_FADT.pm1_event_length);
- acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
- acpi_gbl_FADT.xpm1b_event_block.space_id,
- pm1_register_byte_width,
- (acpi_gbl_FADT.xpm1b_event_block.
- address + pm1_register_byte_width));
- /* Don't forget to copy space_id of the GAS */
- acpi_gbl_xpm1b_enable.space_id =
- acpi_gbl_FADT.xpm1b_event_block.space_id;
-
- }
}
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_tb_validate_fadt
*
@@ -525,18 +483,22 @@ static void acpi_tb_validate_fadt(void)
(acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) {
ACPI_WARNING((AE_INFO,
"32/64X FACS address mismatch in FADT - "
- "two FACS tables! %8.8X/%8.8X%8.8X",
+ "%8.8X/%8.8X%8.8X, using 32",
acpi_gbl_FADT.facs,
ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs)));
+
+ acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs;
}
if (acpi_gbl_FADT.dsdt &&
(acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) {
ACPI_WARNING((AE_INFO,
"32/64X DSDT address mismatch in FADT - "
- "two DSDT tables! %8.8X/%8.8X%8.8X",
+ "%8.8X/%8.8X%8.8X, using 32",
acpi_gbl_FADT.dsdt,
ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt)));
+
+ acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt;
}
/* Examine all of the 64-bit extended address fields (X fields) */
@@ -561,7 +523,8 @@ static void acpi_tb_validate_fadt(void)
* For each extended field, check for length mismatch between the
* legacy length field and the corresponding 64-bit X length field.
*/
- if (address64 && (address64->bit_width != ACPI_MUL_8(length))) {
+ if (address64->address &&
+ (address64->bit_width != ACPI_MUL_8(length))) {
ACPI_WARNING((AE_INFO,
"32/64X length mismatch in %s: %d/%d",
name, ACPI_MUL_8(length),
@@ -575,7 +538,8 @@ static void acpi_tb_validate_fadt(void)
*/
if (!address64->address || !length) {
ACPI_ERROR((AE_INFO,
- "Required field %s has zero address and/or length: %8.8X%8.8X/%X",
+ "Required field %s has zero address and/or length:"
+ " %8.8X%8.8X/%X",
name,
ACPI_FORMAT_UINT64(address64->
address),
@@ -584,27 +548,112 @@ static void acpi_tb_validate_fadt(void)
} else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) {
/*
* Field is optional (PM2Control, GPE0, GPE1) AND has its own
- * length field. If present, both the address and length must be valid.
+ * length field. If present, both the address and length must
+ * be valid.
*/
- if ((address64->address && !length)
- || (!address64->address && length)) {
+ if ((address64->address && !length) ||
+ (!address64->address && length)) {
ACPI_WARNING((AE_INFO,
- "Optional field %s has zero address or length: %8.8X%8.8X/%X",
+ "Optional field %s has zero address or length: "
+ "%8.8X%8.8X/%X",
name,
ACPI_FORMAT_UINT64(address64->
address),
length));
}
}
+ }
+}
- /* If both 32- and 64-bit addresses are valid (non-zero), they must match */
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_tb_setup_fadt_registers
+ *
+ * PARAMETERS: None, uses acpi_gbl_FADT.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
+ * force FADT register definitions to their default lengths.
+ *
+ ******************************************************************************/
- if (address64->address && *address32 &&
- (address64->address != (u64) * address32)) {
- ACPI_ERROR((AE_INFO,
- "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 64X",
- name, *address32,
- ACPI_FORMAT_UINT64(address64->address)));
+static void acpi_tb_setup_fadt_registers(void)
+{
+ struct acpi_generic_address *target64;
+ struct acpi_generic_address *source64;
+ u8 pm1_register_byte_width;
+ u32 i;
+
+ /*
+ * Optionally check all register lengths against the default values and
+ * update them if they are incorrect.
+ */
+ if (acpi_gbl_use_default_register_widths) {
+ for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
+ target64 =
+ ACPI_ADD_PTR(struct acpi_generic_address,
+ &acpi_gbl_FADT,
+ fadt_info_table[i].address64);
+
+ /*
+ * If a valid register (Address != 0) and the (default_length > 0)
+ * (Not a GPE register), then check the width against the default.
+ */
+ if ((target64->address) &&
+ (fadt_info_table[i].default_length > 0) &&
+ (fadt_info_table[i].default_length !=
+ target64->bit_width)) {
+ ACPI_WARNING((AE_INFO,
+ "Invalid length for %s: %d, using default %d",
+ fadt_info_table[i].name,
+ target64->bit_width,
+ fadt_info_table[i].
+ default_length));
+
+ /* Incorrect size, set width to the default */
+
+ target64->bit_width =
+ fadt_info_table[i].default_length;
+ }
+ }
+ }
+
+ /*
+ * Get the length of the individual PM1 registers (enable and status).
+ * Each register is defined to be (event block length / 2). Extra divide
+ * by 8 converts bits to bytes.
+ */
+ pm1_register_byte_width = (u8)
+ ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width);
+
+ /*
+ * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
+ * registers. These addresses do not appear (directly) in the FADT, so it
+ * is useful to pre-calculate them from the PM1 Event Block definitions.
+ *
+ * The PM event blocks are split into two register blocks, first is the
+ * PM Status Register block, followed immediately by the PM Enable
+ * Register block. Each is of length (pm1_event_length/2)
+ *
+ * Note: The PM1A event block is required by the ACPI specification.
+ * However, the PM1B event block is optional and is rarely, if ever,
+ * used.
+ */
+
+ for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) {
+ source64 =
+ ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
+ fadt_pm_info_table[i].source);
+
+ if (source64->address) {
+ acpi_tb_init_generic_address(fadt_pm_info_table[i].
+ target, source64->space_id,
+ pm1_register_byte_width,
+ source64->address +
+ (fadt_pm_info_table[i].
+ register_num *
+ pm1_register_byte_width));
}
}
}
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 37374b21969d..f865d5a096de 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -103,7 +103,9 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
*
* RETURN: Status
*
- * DESCRIPTION: This function is called to add the ACPI table
+ * DESCRIPTION: This function is called to add an ACPI table. It is used to
+ * dynamically load tables via the Load and load_table AML
+ * operators.
*
******************************************************************************/
@@ -112,6 +114,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
{
u32 i;
acpi_status status = AE_OK;
+ struct acpi_table_header *override_table = NULL;
ACPI_FUNCTION_TRACE(tb_add_table);
@@ -201,6 +204,29 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
}
}
+ /*
+ * ACPI Table Override:
+ * Allow the host to override dynamically loaded tables.
+ */
+ status = acpi_os_table_override(table_desc->pointer, &override_table);
+ if (ACPI_SUCCESS(status) && override_table) {
+ ACPI_INFO((AE_INFO,
+ "%4.4s @ 0x%p Table override, replaced with:",
+ table_desc->pointer->signature,
+ ACPI_CAST_PTR(void, table_desc->address)));
+
+ /* We can delete the table that was passed as a parameter */
+
+ acpi_tb_delete_table(table_desc);
+
+ /* Setup descriptor for the new table */
+
+ table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table);
+ table_desc->pointer = override_table;
+ table_desc->length = override_table->length;
+ table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+ }
+
/* Add the table to the global root table list */
status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
@@ -247,8 +273,9 @@ acpi_status acpi_tb_resize_root_table_list(void)
/* Increase the Table Array size */
tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
- size + ACPI_ROOT_TABLE_SIZE_INCREMENT)
- * sizeof(struct acpi_table_desc));
+ size +
+ ACPI_ROOT_TABLE_SIZE_INCREMENT) *
+ sizeof(struct acpi_table_desc));
if (!tables) {
ACPI_ERROR((AE_INFO,
"Could not allocate new root table array"));
@@ -407,27 +434,56 @@ void acpi_tb_terminate(void)
*
* PARAMETERS: table_index - Table index
*
- * RETURN: None
+ * RETURN: Status
*
* DESCRIPTION: Delete all namespace objects created when this table was loaded.
*
******************************************************************************/
-void acpi_tb_delete_namespace_by_owner(u32 table_index)
+acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
{
acpi_owner_id owner_id;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ if (table_index >= acpi_gbl_root_table_list.count) {
+
+ /* The table index does not exist */
- (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
- if (table_index < acpi_gbl_root_table_list.count) {
- owner_id =
- acpi_gbl_root_table_list.tables[table_index].owner_id;
- } else {
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
- return;
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
+ /* Get the owner ID for this table, used to delete namespace nodes */
+
+ owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+
+ /*
+ * Need to acquire the namespace writer lock to prevent interference
+ * with any concurrent namespace walks. The interpreter must be
+ * released during the deletion since the acquisition of the deletion
+ * lock may block, and also since the execution of a namespace walk
+ * must be allowed to use the interpreter.
+ */
+ acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
+ status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
+
acpi_ns_delete_namespace_by_owner(owner_id);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
+ return_ACPI_STATUS(status);
}
/*******************************************************************************
@@ -535,8 +591,8 @@ u8 acpi_tb_is_table_loaded(u32 table_index)
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
if (table_index < acpi_gbl_root_table_list.count) {
is_loaded = (u8)
- (acpi_gbl_root_table_list.tables[table_index].
- flags & ACPI_TABLE_IS_LOADED);
+ (acpi_gbl_root_table_list.tables[table_index].flags &
+ ACPI_TABLE_IS_LOADED);
}
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 22ce48985720..ef7d2c2d8f0b 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -177,19 +177,23 @@ acpi_tb_print_table_header(acpi_physical_address address,
struct acpi_table_header *header)
{
+ /*
+ * The reason that the Address is cast to a void pointer is so that we
+ * can use %p which will work properly on both 32-bit and 64-bit hosts.
+ */
if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
- /* FACS only has signature and length fields of common table header */
+ /* FACS only has signature and length fields */
- ACPI_INFO((AE_INFO, "%4.4s %08lX, %04X",
- header->signature, (unsigned long)address,
+ ACPI_INFO((AE_INFO, "%4.4s %p %05X",
+ header->signature, ACPI_CAST_PTR(void, address),
header->length));
} else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
/* RSDP has no common fields */
- ACPI_INFO((AE_INFO, "RSDP %08lX, %04X (r%d %6.6s)",
- (unsigned long)address,
+ ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
+ ACPI_CAST_PTR (void, address),
(ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
revision >
0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
@@ -202,8 +206,8 @@ acpi_tb_print_table_header(acpi_physical_address address,
/* Standard ACPI table with full common header */
ACPI_INFO((AE_INFO,
- "%4.4s %08lX, %04X (r%d %6.6s %8.8s %8X %4.4s %8X)",
- header->signature, (unsigned long)address,
+ "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
+ header->signature, ACPI_CAST_PTR (void, address),
header->length, header->revision, header->oem_id,
header->oem_table_id, header->oem_revision,
header->asl_compiler_id,
@@ -280,22 +284,28 @@ u8 acpi_tb_checksum(u8 *buffer, u32 length)
* FUNCTION: acpi_tb_install_table
*
* PARAMETERS: Address - Physical address of DSDT or FACS
- * Flags - Flags
* Signature - Table signature, NULL if no need to
* match
* table_index - Index into root table array
*
* RETURN: None
*
- * DESCRIPTION: Install an ACPI table into the global data structure.
+ * DESCRIPTION: Install an ACPI table into the global data structure. The
+ * table override mechanism is implemented here to allow the host
+ * OS to replace any table before it is installed in the root
+ * table array.
*
******************************************************************************/
void
acpi_tb_install_table(acpi_physical_address address,
- u8 flags, char *signature, u32 table_index)
+ char *signature, u32 table_index)
{
- struct acpi_table_header *table;
+ u8 flags;
+ acpi_status status;
+ struct acpi_table_header *table_to_install;
+ struct acpi_table_header *mapped_table;
+ struct acpi_table_header *override_table = NULL;
if (!address) {
ACPI_ERROR((AE_INFO,
@@ -306,41 +316,69 @@ acpi_tb_install_table(acpi_physical_address address,
/* Map just the table header */
- table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
- if (!table) {
+ mapped_table =
+ acpi_os_map_memory(address, sizeof(struct acpi_table_header));
+ if (!mapped_table) {
return;
}
- /* If a particular signature is expected, signature must match */
+ /* If a particular signature is expected (DSDT/FACS), it must match */
- if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
+ if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) {
ACPI_ERROR((AE_INFO,
- "Invalid signature 0x%X for ACPI table [%s]",
- *ACPI_CAST_PTR(u32, table->signature), signature));
+ "Invalid signature 0x%X for ACPI table, expected [%s]",
+ *ACPI_CAST_PTR(u32, mapped_table->signature),
+ signature));
goto unmap_and_exit;
}
+ /*
+ * ACPI Table Override:
+ *
+ * Before we install the table, let the host OS override it with a new
+ * one if desired. Any table within the RSDT/XSDT can be replaced,
+ * including the DSDT which is pointed to by the FADT.
+ */
+ status = acpi_os_table_override(mapped_table, &override_table);
+ if (ACPI_SUCCESS(status) && override_table) {
+ ACPI_INFO((AE_INFO,
+ "%4.4s @ 0x%p Table override, replaced with:",
+ mapped_table->signature, ACPI_CAST_PTR(void,
+ address)));
+
+ acpi_gbl_root_table_list.tables[table_index].pointer =
+ override_table;
+ address = ACPI_PTR_TO_PHYSADDR(override_table);
+
+ table_to_install = override_table;
+ flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+ } else {
+ table_to_install = mapped_table;
+ flags = ACPI_TABLE_ORIGIN_MAPPED;
+ }
+
/* Initialize the table entry */
acpi_gbl_root_table_list.tables[table_index].address = address;
- acpi_gbl_root_table_list.tables[table_index].length = table->length;
+ acpi_gbl_root_table_list.tables[table_index].length =
+ table_to_install->length;
acpi_gbl_root_table_list.tables[table_index].flags = flags;
ACPI_MOVE_32_TO_32(&
(acpi_gbl_root_table_list.tables[table_index].
- signature), table->signature);
+ signature), table_to_install->signature);
- acpi_tb_print_table_header(address, table);
+ acpi_tb_print_table_header(address, table_to_install);
if (table_index == ACPI_TABLE_INDEX_DSDT) {
/* Global integer width is based upon revision of the DSDT */
- acpi_ut_set_integer_width(table->revision);
+ acpi_ut_set_integer_width(table_to_install->revision);
}
unmap_and_exit:
- acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+ acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
}
/*******************************************************************************
@@ -379,7 +417,8 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
} else {
/*
* 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
- * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit
+ * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
+ * return 64-bit
*/
ACPI_MOVE_64_TO_64(&address64, table_entry);
@@ -389,7 +428,8 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
/* Will truncate 64-bit address to 32 bits, issue warning */
ACPI_WARNING((AE_INFO,
- "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating",
+ "64-bit Physical Address in XSDT is too large (%8.8X%8.8X),"
+ " truncating",
ACPI_FORMAT_UINT64(address64)));
}
#endif
@@ -402,7 +442,6 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
* FUNCTION: acpi_tb_parse_root_table
*
* PARAMETERS: Rsdp - Pointer to the RSDP
- * Flags - Flags
*
* RETURN: Status
*
@@ -416,7 +455,7 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
******************************************************************************/
acpi_status __init
-acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
+acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
{
struct acpi_table_rsdp *rsdp;
u32 table_entry_size;
@@ -513,13 +552,12 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
/* Calculate the number of tables described in the root table */
- table_count =
- (u32) ((table->length -
- sizeof(struct acpi_table_header)) / table_entry_size);
-
+ table_count = (u32)((table->length - sizeof(struct acpi_table_header)) /
+ table_entry_size);
/*
- * First two entries in the table array are reserved for the DSDT and FACS,
- * which are not actually present in the RSDT/XSDT - they come from the FADT
+ * First two entries in the table array are reserved for the DSDT
+ * and FACS, which are not actually present in the RSDT/XSDT - they
+ * come from the FADT
*/
table_entry =
ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
@@ -567,14 +605,14 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
*/
for (i = 2; i < acpi_gbl_root_table_list.count; i++) {
acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
- address, flags, NULL, i);
+ address, NULL, i);
/* Special case for FADT - get the DSDT and FACS */
if (ACPI_COMPARE_NAME
(&acpi_gbl_root_table_list.tables[i].signature,
ACPI_SIG_FADT)) {
- acpi_tb_parse_fadt(i, flags);
+ acpi_tb_parse_fadt(i);
}
}
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index ab0aff3c7d6a..a88f02bd6c94 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -150,8 +150,7 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
* Root Table Array. This array contains the information of the RSDT/XSDT
* in a common, more useable format.
*/
- status =
- acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED);
+ status = acpi_tb_parse_root_table(rsdp_address);
return_ACPI_STATUS(status);
}
@@ -247,7 +246,7 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
ACPI_EXPORT_SYMBOL(acpi_load_table)
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_get_table_header
*
@@ -262,7 +261,7 @@ ACPI_EXPORT_SYMBOL(acpi_load_table)
* NOTE: Caller is responsible in unmapping the header with
* acpi_os_unmap_memory
*
- *****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_get_table_header(char *signature,
u32 instance, struct acpi_table_header *out_table_header)
@@ -277,9 +276,8 @@ acpi_get_table_header(char *signature,
return (AE_BAD_PARAMETER);
}
- /*
- * Walk the root table list
- */
+ /* Walk the root table list */
+
for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
if (!ACPI_COMPARE_NAME
(&(acpi_gbl_root_table_list.tables[i].signature),
@@ -292,8 +290,8 @@ acpi_get_table_header(char *signature,
}
if (!acpi_gbl_root_table_list.tables[i].pointer) {
- if ((acpi_gbl_root_table_list.tables[i].
- flags & ACPI_TABLE_ORIGIN_MASK) ==
+ if ((acpi_gbl_root_table_list.tables[i].flags &
+ ACPI_TABLE_ORIGIN_MASK) ==
ACPI_TABLE_ORIGIN_MAPPED) {
header =
acpi_os_map_memory(acpi_gbl_root_table_list.
@@ -324,7 +322,7 @@ acpi_get_table_header(char *signature,
ACPI_EXPORT_SYMBOL(acpi_get_table_header)
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_unload_table_id
*
@@ -375,7 +373,7 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
*
* DESCRIPTION: Finds and verifies an ACPI table.
*
- *****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_get_table_with_size(char *signature,
u32 instance, struct acpi_table_header **out_table,
@@ -391,9 +389,8 @@ acpi_get_table_with_size(char *signature,
return (AE_BAD_PARAMETER);
}
- /*
- * Walk the root table list
- */
+ /* Walk the root table list */
+
for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
if (!ACPI_COMPARE_NAME
(&(acpi_gbl_root_table_list.tables[i].signature),
@@ -502,7 +499,6 @@ ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
static acpi_status acpi_tb_load_namespace(void)
{
acpi_status status;
- struct acpi_table_header *table;
u32 i;
ACPI_FUNCTION_TRACE(tb_load_namespace);
@@ -526,58 +522,28 @@ static acpi_status acpi_tb_load_namespace(void)
goto unlock_and_exit;
}
- /*
- * Find DSDT table
- */
- status =
- acpi_os_table_override(acpi_gbl_root_table_list.
- tables[ACPI_TABLE_INDEX_DSDT].pointer,
- &table);
- if (ACPI_SUCCESS(status) && table) {
- /*
- * DSDT table has been found
- */
- acpi_tb_delete_table(&acpi_gbl_root_table_list.
- tables[ACPI_TABLE_INDEX_DSDT]);
- acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
- table;
- acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
- table->length;
- acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
- ACPI_TABLE_ORIGIN_UNKNOWN;
-
- ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
- acpi_tb_print_table_header(0, table);
-
- if (no_auto_ssdt == 0) {
- printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
- }
- }
+ /* A valid DSDT is required */
status =
acpi_tb_verify_table(&acpi_gbl_root_table_list.
tables[ACPI_TABLE_INDEX_DSDT]);
if (ACPI_FAILURE(status)) {
- /* A valid DSDT is required */
-
status = AE_NO_ACPI_TABLES;
goto unlock_and_exit;
}
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
- /*
- * Load and parse tables.
- */
+ /* Load and parse tables */
+
status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- /*
- * Load any SSDT or PSDT tables. Note: Loop leaves tables locked
- */
+ /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
+
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
if ((!ACPI_COMPARE_NAME
@@ -630,9 +596,8 @@ acpi_status acpi_load_tables(void)
ACPI_FUNCTION_TRACE(acpi_load_tables);
- /*
- * Load the namespace from the tables
- */
+ /* Load the namespace from the tables */
+
status = acpi_tb_load_namespace();
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c
index b7fc8dd43341..85ea834199e2 100644
--- a/drivers/acpi/acpica/tbxfroot.c
+++ b/drivers/acpi/acpica/tbxfroot.c
@@ -75,8 +75,8 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
* Note: Sometimes there exists more than one RSDP in memory; the valid
* RSDP has a valid checksum, all others have an invalid checksum.
*/
- if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)
- != 0) {
+ if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP,
+ sizeof(ACPI_SIG_RSDP) - 1) != 0) {
/* Nope, BAD Signature */
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c
index b0dcfd3c872a..919624f123d5 100644
--- a/drivers/acpi/acpica/utcopy.c
+++ b/drivers/acpi/acpica/utcopy.c
@@ -135,11 +135,11 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
* In general, the external object will be the same type as
* the internal object
*/
- external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+ external_object->type = internal_object->common.type;
/* However, only a limited number of external types are supported */
- switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
+ switch (internal_object->common.type) {
case ACPI_TYPE_STRING:
external_object->string.pointer = (char *)data_space;
@@ -222,8 +222,8 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
*/
ACPI_ERROR((AE_INFO,
"Unsupported object type, cannot convert to external object: %s",
- acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
- (internal_object))));
+ acpi_ut_get_type_name(internal_object->common.
+ type)));
return_ACPI_STATUS(AE_SUPPORT);
}
@@ -355,7 +355,7 @@ acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
info.object_space = 0;
info.num_packages = 1;
- external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+ external_object->type = internal_object->common.type;
external_object->package.count = internal_object->package.count;
external_object->package.elements = ACPI_CAST_PTR(union acpi_object,
info.free_space);
@@ -399,7 +399,7 @@ acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object,
ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);
- if (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE) {
+ if (internal_object->common.type == ACPI_TYPE_PACKAGE) {
/*
* Package object: Copy all subobjects (including
* nested packages)
@@ -496,8 +496,9 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
case ACPI_TYPE_STRING:
internal_object->string.pointer =
- ACPI_ALLOCATE_ZEROED((acpi_size) external_object->string.
- length + 1);
+ ACPI_ALLOCATE_ZEROED((acpi_size)
+ external_object->string.length + 1);
+
if (!internal_object->string.pointer) {
goto error_exit;
}
@@ -697,7 +698,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
/* Handle the objects with extra data */
- switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+ switch (dest_desc->common.type) {
case ACPI_TYPE_BUFFER:
/*
* Allocate and copy the actual buffer if and only if:
@@ -814,8 +815,8 @@ acpi_ut_copy_ielement_to_ielement(u8 object_type,
* This is a simple object, just copy it
*/
target_object =
- acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
- (source_object));
+ acpi_ut_create_internal_object(source_object->
+ common.type);
if (!target_object) {
return (AE_NO_MEMORY);
}
@@ -892,7 +893,7 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);
- dest_obj->common.type = ACPI_GET_OBJECT_TYPE(source_obj);
+ dest_obj->common.type = source_obj->common.type;
dest_obj->common.flags = source_obj->common.flags;
dest_obj->package.count = source_obj->package.count;
@@ -950,15 +951,14 @@ acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
/* Create the top level object */
- *dest_desc =
- acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE(source_desc));
+ *dest_desc = acpi_ut_create_internal_object(source_desc->common.type);
if (!*dest_desc) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Copy the object and possible subobjects */
- if (ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_PACKAGE) {
+ if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
status =
acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
walk_state);
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c
index a0be9e39531e..a5ee23bc4f55 100644
--- a/drivers/acpi/acpica/utdelete.c
+++ b/drivers/acpi/acpica/utdelete.c
@@ -86,7 +86,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
* Must delete or free any pointers within the object that are not
* actual ACPI objects (for example, a raw buffer pointer).
*/
- switch (ACPI_GET_OBJECT_TYPE(object)) {
+ switch (object->common.type) {
case ACPI_TYPE_STRING:
ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
@@ -382,7 +382,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
object, new_count));
}
- if (ACPI_GET_OBJECT_TYPE(object) == ACPI_TYPE_METHOD) {
+ if (object->common.type == ACPI_TYPE_METHOD) {
ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
"Method Obj %p Refs=%X, [Decremented]\n",
object, new_count));
@@ -469,7 +469,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
* All sub-objects must have their reference count incremented also.
* Different object types have different subobjects.
*/
- switch (ACPI_GET_OBJECT_TYPE(object)) {
+ switch (object->common.type) {
case ACPI_TYPE_DEVICE:
case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_POWER:
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c
index 9c9897dbe907..006b16c26017 100644
--- a/drivers/acpi/acpica/uteval.c
+++ b/drivers/acpi/acpica/uteval.c
@@ -59,26 +59,35 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
/*
* Strings supported by the _OSI predefined (internal) method.
+ *
+ * March 2009: Removed "Linux" as this host no longer wants to respond true
+ * for this string. Basically, the only safe OS strings are windows-related
+ * and in many or most cases represent the only test path within the
+ * BIOS-provided ASL code.
+ *
+ * The second element of each entry is used to track the newest version of
+ * Windows that the BIOS has requested.
*/
-static char *acpi_interfaces_supported[] = {
+static struct acpi_interface_info acpi_interfaces_supported[] = {
/* Operating System Vendor Strings */
- "Windows 2000", /* Windows 2000 */
- "Windows 2001", /* Windows XP */
- "Windows 2001 SP1", /* Windows XP SP1 */
- "Windows 2001 SP2", /* Windows XP SP2 */
- "Windows 2001.1", /* Windows Server 2003 */
- "Windows 2001.1 SP1", /* Windows Server 2003 SP1 - Added 03/2006 */
- "Windows 2006", /* Windows Vista - Added 03/2006 */
+ {"Windows 2000", ACPI_OSI_WIN_2000}, /* Windows 2000 */
+ {"Windows 2001", ACPI_OSI_WIN_XP}, /* Windows XP */
+ {"Windows 2001 SP1", ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */
+ {"Windows 2001.1", ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */
+ {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */
+ {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */
+ {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */
/* Feature Group Strings */
- "Extended Address Space Descriptor"
- /*
- * All "optional" feature group strings (features that are implemented
- * by the host) should be implemented in the host version of
- * acpi_os_validate_interface and should not be added here.
- */
+ {"Extended Address Space Descriptor", 0}
+
+ /*
+ * All "optional" feature group strings (features that are implemented
+ * by the host) should be implemented in the host version of
+ * acpi_os_validate_interface and should not be added here.
+ */
};
/*******************************************************************************
@@ -98,6 +107,7 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
acpi_status status;
union acpi_operand_object *string_desc;
union acpi_operand_object *return_desc;
+ u32 return_value;
u32 i;
ACPI_FUNCTION_TRACE(ut_osi_implementation);
@@ -116,19 +126,28 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
return_ACPI_STATUS(AE_NO_MEMORY);
}
- /* Default return value is 0, NOT-SUPPORTED */
+ /* Default return value is 0, NOT SUPPORTED */
- return_desc->integer.value = 0;
- walk_state->return_desc = return_desc;
+ return_value = 0;
/* Compare input string to static table of supported interfaces */
for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
- if (!ACPI_STRCMP
- (string_desc->string.pointer,
- acpi_interfaces_supported[i])) {
- return_desc->integer.value = ACPI_UINT32_MAX;
- goto done;
+ if (!ACPI_STRCMP(string_desc->string.pointer,
+ acpi_interfaces_supported[i].name)) {
+ /*
+ * The interface is supported.
+ * Update the osi_data if necessary. We keep track of the latest
+ * version of Windows that has been requested by the BIOS.
+ */
+ if (acpi_interfaces_supported[i].value >
+ acpi_gbl_osi_data) {
+ acpi_gbl_osi_data =
+ acpi_interfaces_supported[i].value;
+ }
+
+ return_value = ACPI_UINT32_MAX;
+ goto exit;
}
}
@@ -139,15 +158,22 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
*/
status = acpi_os_validate_interface(string_desc->string.pointer);
if (ACPI_SUCCESS(status)) {
- return_desc->integer.value = ACPI_UINT32_MAX;
+
+ /* The interface is supported */
+
+ return_value = ACPI_UINT32_MAX;
}
-done:
- ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n",
- string_desc->string.pointer,
- return_desc->integer.value == 0 ? "not-" : ""));
+exit:
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
+ "ACPI: BIOS _OSI(%s) is %ssupported\n",
+ string_desc->string.pointer, return_value == 0 ? "not " : ""));
- return_ACPI_STATUS(AE_OK);
+ /* Complete the return value */
+
+ return_desc->integer.value = return_value;
+ walk_state->return_desc = return_desc;
+ return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
@@ -167,8 +193,8 @@ acpi_status acpi_osi_invalidate(char *interface)
int i;
for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
- if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) {
- *acpi_interfaces_supported[i] = '\0';
+ if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) {
+ *acpi_interfaces_supported[i].name = '\0';
return AE_OK;
}
}
@@ -248,7 +274,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
/* Map the return object type to the bitmapped type */
- switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
+ switch ((info->return_object)->common.type) {
case ACPI_TYPE_INTEGER:
return_btype = ACPI_BTYPE_INTEGER;
break;
@@ -418,7 +444,7 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
return_ACPI_STATUS(status);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
/* Convert the Numeric HID to string */
@@ -459,7 +485,7 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
struct acpi_compatible_id *one_cid)
{
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
/* Convert the Numeric CID to string */
@@ -527,7 +553,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
/* Get the number of _CIDs returned */
count = 1;
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+ if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
count = obj_desc->package.count;
}
@@ -555,7 +581,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
/* The _CID object can be either a single CID or a package (list) of CIDs */
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+ if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
/* Translate each package element */
@@ -620,7 +646,7 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
return_ACPI_STATUS(status);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
/* Convert the Numeric UID to string */
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c
index a3ab9d9da299..59e46f257c02 100644
--- a/drivers/acpi/acpica/utglobal.c
+++ b/drivers/acpi/acpica/utglobal.c
@@ -294,12 +294,9 @@ struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = {
/* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL,
ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE,
ACPI_BITMASK_GLOBAL_LOCK_RELEASE},
- /* ACPI_BITREG_SLEEP_TYPE_A */ {ACPI_REGISTER_PM1_CONTROL,
- ACPI_BITPOSITION_SLEEP_TYPE_X,
- ACPI_BITMASK_SLEEP_TYPE_X},
- /* ACPI_BITREG_SLEEP_TYPE_B */ {ACPI_REGISTER_PM1_CONTROL,
- ACPI_BITPOSITION_SLEEP_TYPE_X,
- ACPI_BITMASK_SLEEP_TYPE_X},
+ /* ACPI_BITREG_SLEEP_TYPE */ {ACPI_REGISTER_PM1_CONTROL,
+ ACPI_BITPOSITION_SLEEP_TYPE,
+ ACPI_BITMASK_SLEEP_TYPE},
/* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL,
ACPI_BITPOSITION_SLEEP_ENABLE,
ACPI_BITMASK_SLEEP_ENABLE},
@@ -476,7 +473,7 @@ char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
return ("[NULL Object Descriptor]");
}
- return (acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)));
+ return (acpi_ut_get_type_name(obj_desc->common.type));
}
/*******************************************************************************
@@ -749,7 +746,10 @@ acpi_status acpi_ut_init_globals(void)
for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
acpi_gbl_owner_id_mask[i] = 0;
}
- acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; /* Last ID is never valid */
+
+ /* Last owner_iD is never valid */
+
+ acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
/* GPE support */
@@ -789,6 +789,7 @@ acpi_status acpi_ut_init_globals(void)
acpi_gbl_trace_dbg_layer = 0;
acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
+ acpi_gbl_osi_data = 0;
/* Hardware oriented */
diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c
new file mode 100644
index 000000000000..25e03120686d
--- /dev/null
+++ b/drivers/acpi/acpica/utlock.c
@@ -0,0 +1,175 @@
+/******************************************************************************
+ *
+ * Module Name: utlock - Reader/Writer lock interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2009, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT ACPI_UTILITIES
+ACPI_MODULE_NAME("utlock")
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_rw_lock
+ * acpi_ut_delete_rw_lock
+ *
+ * PARAMETERS: Lock - Pointer to a valid RW lock
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Reader/writer lock creation and deletion interfaces.
+ *
+ ******************************************************************************/
+acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock)
+{
+ acpi_status status;
+
+ lock->num_readers = 0;
+ status = acpi_os_create_mutex(&lock->reader_mutex);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ status = acpi_os_create_mutex(&lock->writer_mutex);
+ return status;
+}
+
+void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock)
+{
+
+ acpi_os_delete_mutex(lock->reader_mutex);
+ acpi_os_delete_mutex(lock->writer_mutex);
+
+ lock->num_readers = 0;
+ lock->reader_mutex = NULL;
+ lock->writer_mutex = NULL;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_acquire_read_lock
+ * acpi_ut_release_read_lock
+ *
+ * PARAMETERS: Lock - Pointer to a valid RW lock
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition,
+ * only the first reader acquires the write mutex. On release,
+ * only the last reader releases the write mutex. Although this
+ * algorithm can in theory starve writers, this should not be a
+ * problem with ACPICA since the subsystem is infrequently used
+ * in comparison to (for example) an I/O system.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock)
+{
+ acpi_status status;
+
+ status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ /* Acquire the write lock only for the first reader */
+
+ lock->num_readers++;
+ if (lock->num_readers == 1) {
+ status =
+ acpi_os_acquire_mutex(lock->writer_mutex,
+ ACPI_WAIT_FOREVER);
+ }
+
+ acpi_os_release_mutex(lock->reader_mutex);
+ return status;
+}
+
+acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock)
+{
+ acpi_status status;
+
+ status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ /* Release the write lock only for the very last reader */
+
+ lock->num_readers--;
+ if (lock->num_readers == 0) {
+ acpi_os_release_mutex(lock->writer_mutex);
+ }
+
+ acpi_os_release_mutex(lock->reader_mutex);
+ return status;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_acquire_write_lock
+ * acpi_ut_release_write_lock
+ *
+ * PARAMETERS: Lock - Pointer to a valid RW lock
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or
+ * release the writer mutex associated with the lock. Acquisition
+ * of the lock is fully exclusive and will block all readers and
+ * writers until it is released.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock)
+{
+ acpi_status status;
+
+ status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER);
+ return status;
+}
+
+void acpi_ut_release_write_lock(struct acpi_rw_lock *lock)
+{
+
+ acpi_os_release_mutex(lock->writer_mutex);
+}
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c
index c1f7f4e1a72d..1c9e250caefb 100644
--- a/drivers/acpi/acpica/utmisc.c
+++ b/drivers/acpi/acpica/utmisc.c
@@ -938,8 +938,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
if ((!this_source_obj) ||
(ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
ACPI_DESC_TYPE_OPERAND)
- || (ACPI_GET_OBJECT_TYPE(this_source_obj) !=
- ACPI_TYPE_PACKAGE)) {
+ || (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) {
status =
walk_callback(ACPI_COPY_TYPE_SIMPLE,
this_source_obj, state, context);
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index 14eb52c4d647..26c93a748e64 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -60,7 +60,8 @@ static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
*
* RETURN: Status
*
- * DESCRIPTION: Create the system mutex objects.
+ * DESCRIPTION: Create the system mutex objects. This includes mutexes,
+ * spin locks, and reader/writer locks.
*
******************************************************************************/
@@ -71,9 +72,8 @@ acpi_status acpi_ut_mutex_initialize(void)
ACPI_FUNCTION_TRACE(ut_mutex_initialize);
- /*
- * Create each of the predefined mutex objects
- */
+ /* Create each of the predefined mutex objects */
+
for (i = 0; i < ACPI_NUM_MUTEX; i++) {
status = acpi_ut_create_mutex(i);
if (ACPI_FAILURE(status)) {
@@ -86,6 +86,9 @@ acpi_status acpi_ut_mutex_initialize(void)
spin_lock_init(acpi_gbl_gpe_lock);
spin_lock_init(acpi_gbl_hardware_lock);
+ /* Create the reader/writer lock for namespace access */
+
+ status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
return_ACPI_STATUS(status);
}
@@ -97,7 +100,8 @@ acpi_status acpi_ut_mutex_initialize(void)
*
* RETURN: None.
*
- * DESCRIPTION: Delete all of the system mutex objects.
+ * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
+ * spin locks, and reader/writer locks.
*
******************************************************************************/
@@ -107,9 +111,8 @@ void acpi_ut_mutex_terminate(void)
ACPI_FUNCTION_TRACE(ut_mutex_terminate);
- /*
- * Delete each predefined mutex object
- */
+ /* Delete each predefined mutex object */
+
for (i = 0; i < ACPI_NUM_MUTEX; i++) {
(void)acpi_ut_delete_mutex(i);
}
@@ -118,6 +121,10 @@ void acpi_ut_mutex_terminate(void)
acpi_os_delete_lock(acpi_gbl_gpe_lock);
acpi_os_delete_lock(acpi_gbl_hardware_lock);
+
+ /* Delete the reader/writer lock */
+
+ acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
return_VOID;
}
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c
index fd5ea7543e5b..0207b625274a 100644
--- a/drivers/acpi/acpica/utobject.c
+++ b/drivers/acpi/acpica/utobject.c
@@ -310,7 +310,7 @@ u8 acpi_ut_valid_internal_object(void *object)
/* Check for a null pointer */
if (!object) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Null Object Ptr\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
return (FALSE);
}
@@ -324,7 +324,7 @@ u8 acpi_ut_valid_internal_object(void *object)
return (TRUE);
default:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"%p is not not an ACPI operand obj [%s]\n",
object, acpi_ut_get_descriptor_name(object)));
break;
@@ -457,7 +457,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
* must be accessed bytewise or there may be alignment problems on
* certain processors
*/
- switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
+ switch (internal_object->common.type) {
case ACPI_TYPE_STRING:
length += (acpi_size) internal_object->string.length + 1;
@@ -518,8 +518,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
ACPI_ERROR((AE_INFO, "Cannot convert to external object - "
"unsupported type [%s] %X in object %p",
acpi_ut_get_object_type_name(internal_object),
- ACPI_GET_OBJECT_TYPE(internal_object),
- internal_object));
+ internal_object->common.type, internal_object));
status = AE_TYPE;
break;
}
@@ -664,7 +663,7 @@ acpi_ut_get_object_size(union acpi_operand_object *internal_object,
if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) ==
ACPI_DESC_TYPE_OPERAND)
- && (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE)) {
+ && (internal_object->common.type == ACPI_TYPE_PACKAGE)) {
status =
acpi_ut_get_package_object_size(internal_object,
obj_length);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 69cbc57c2d1c..b0de6312919a 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/jiffies.h>
+#include <linux/async.h>
#ifdef CONFIG_ACPI_PROCFS_POWER
#include <linux/proc_fs.h>
@@ -92,7 +93,7 @@ struct acpi_battery {
#endif
struct acpi_device *device;
unsigned long update_time;
- int current_now;
+ int rate_now;
int capacity_now;
int voltage_now;
int design_capacity;
@@ -196,7 +197,8 @@ static int acpi_battery_get_property(struct power_supply *psy,
val->intval = battery->voltage_now * 1000;
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
- val->intval = battery->current_now * 1000;
+ case POWER_SUPPLY_PROP_POWER_NOW:
+ val->intval = battery->rate_now * 1000;
break;
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
@@ -247,6 +249,7 @@ static enum power_supply_property energy_battery_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_POWER_NOW,
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_FULL,
POWER_SUPPLY_PROP_ENERGY_NOW,
@@ -273,7 +276,7 @@ struct acpi_offsets {
static struct acpi_offsets state_offsets[] = {
{offsetof(struct acpi_battery, state), 0},
- {offsetof(struct acpi_battery, current_now), 0},
+ {offsetof(struct acpi_battery, rate_now), 0},
{offsetof(struct acpi_battery, capacity_now), 0},
{offsetof(struct acpi_battery, voltage_now), 0},
};
@@ -605,11 +608,11 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
else
seq_printf(seq, "charging state: charged\n");
- if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
+ if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "present rate: unknown\n");
else
seq_printf(seq, "present rate: %d %s\n",
- battery->current_now, acpi_battery_units(battery));
+ battery->rate_now, acpi_battery_units(battery));
if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "remaining capacity: unknown\n");
@@ -740,7 +743,7 @@ DECLARE_FILE_FUNCTIONS(alarm);
static struct battery_file {
struct file_operations ops;
mode_t mode;
- char *name;
+ const char *name;
} acpi_battery_file[] = {
FILE_DESCRIPTION_RO(info),
FILE_DESCRIPTION_RO(state),
@@ -760,7 +763,6 @@ static int acpi_battery_add_fs(struct acpi_device *device)
acpi_battery_dir);
if (!acpi_device_dir(device))
return -ENODEV;
- acpi_device_dir(device)->owner = THIS_MODULE;
}
for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
@@ -901,21 +903,27 @@ static struct acpi_driver acpi_battery_driver = {
},
};
-static int __init acpi_battery_init(void)
+static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
{
if (acpi_disabled)
- return -ENODEV;
+ return;
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_battery_dir = acpi_lock_battery_dir();
if (!acpi_battery_dir)
- return -ENODEV;
+ return;
#endif
if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_unlock_battery_dir(acpi_battery_dir);
#endif
- return -ENODEV;
+ return;
}
+ return;
+}
+
+static int __init acpi_battery_init(void)
+{
+ async_schedule(acpi_battery_init_async, NULL);
return 0;
}
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index bee64b73c919..e8f7b64e92da 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -39,6 +39,8 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
+#include "internal.h"
+
#define _COMPONENT ACPI_BUS_COMPONENT
ACPI_MODULE_NAME("bus");
@@ -846,6 +848,7 @@ static int __init acpi_init(void)
acpi_kobj = NULL;
}
+ init_acpi_device_notify();
result = acpi_bus_init();
if (!result) {
@@ -860,11 +863,23 @@ static int __init acpi_init(void)
}
} else
disable_acpi();
+
+ if (acpi_disabled)
+ return result;
+
/*
* If the laptop falls into the DMI check table, the power state check
* will be disabled in the course of device power transistion.
*/
dmi_check_system(power_nocheck_dmi_table);
+
+ acpi_scan_init();
+ acpi_ec_init();
+ acpi_power_init();
+ acpi_system_init();
+ acpi_debug_init();
+ acpi_sleep_proc_init();
+ acpi_wakeup_device_init();
return result;
}
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 171fd914f435..d73c94b8441d 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -78,6 +78,7 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);
static int acpi_button_add(struct acpi_device *device);
static int acpi_button_remove(struct acpi_device *device, int type);
static int acpi_button_resume(struct acpi_device *device);
+static void acpi_button_notify(struct acpi_device *device, u32 event);
static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
@@ -89,6 +90,7 @@ static struct acpi_driver acpi_button_driver = {
.add = acpi_button_add,
.resume = acpi_button_resume,
.remove = acpi_button_remove,
+ .notify = acpi_button_notify,
},
};
@@ -200,12 +202,10 @@ static int acpi_button_add_fs(struct acpi_device *device)
if (!entry)
return -ENODEV;
- entry->owner = THIS_MODULE;
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry);
if (!acpi_device_dir(device))
return -ENODEV;
- acpi_device_dir(device)->owner = THIS_MODULE;
/* 'info' [R] */
entry = proc_create_data(ACPI_BUTTON_FILE_INFO,
@@ -265,15 +265,18 @@ static int acpi_lid_send_state(struct acpi_button *button)
return 0;
}
-static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_button_notify(struct acpi_device *device, u32 event)
{
- struct acpi_button *button = data;
+ struct acpi_button *button = acpi_driver_data(device);
struct input_dev *input;
if (!button || !button->device)
return;
switch (event) {
+ case ACPI_FIXED_HARDWARE_EVENT:
+ event = ACPI_BUTTON_NOTIFY_STATUS;
+ /* fall through */
case ACPI_BUTTON_NOTIFY_STATUS:
input = button->input;
if (button->type == ACPI_BUTTON_TYPE_LID) {
@@ -300,46 +303,6 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
return;
}
-static acpi_status acpi_button_notify_fixed(void *data)
-{
- struct acpi_button *button = data;
-
- if (!button)
- return AE_BAD_PARAMETER;
-
- acpi_button_notify(button->device->handle, ACPI_BUTTON_NOTIFY_STATUS, button);
-
- return AE_OK;
-}
-
-static int acpi_button_install_notify_handlers(struct acpi_button *button)
-{
- acpi_status status;
-
- switch (button->type) {
- case ACPI_BUTTON_TYPE_POWERF:
- status =
- acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
- acpi_button_notify_fixed,
- button);
- break;
- case ACPI_BUTTON_TYPE_SLEEPF:
- status =
- acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
- acpi_button_notify_fixed,
- button);
- break;
- default:
- status = acpi_install_notify_handler(button->device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_button_notify,
- button);
- break;
- }
-
- return ACPI_FAILURE(status) ? -ENODEV : 0;
-}
-
static int acpi_button_resume(struct acpi_device *device)
{
struct acpi_button *button;
@@ -351,25 +314,6 @@ static int acpi_button_resume(struct acpi_device *device)
return 0;
}
-static void acpi_button_remove_notify_handlers(struct acpi_button *button)
-{
- switch (button->type) {
- case ACPI_BUTTON_TYPE_POWERF:
- acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
- acpi_button_notify_fixed);
- break;
- case ACPI_BUTTON_TYPE_SLEEPF:
- acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
- acpi_button_notify_fixed);
- break;
- default:
- acpi_remove_notify_handler(button->device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_button_notify);
- break;
- }
-}
-
static int acpi_button_add(struct acpi_device *device)
{
int error;
@@ -434,10 +378,6 @@ static int acpi_button_add(struct acpi_device *device)
if (error)
goto err_free_input;
- error = acpi_button_install_notify_handlers(button);
- if (error)
- goto err_remove_fs;
-
snprintf(button->phys, sizeof(button->phys),
"%s/button/input0", acpi_device_hid(device));
@@ -468,7 +408,7 @@ static int acpi_button_add(struct acpi_device *device)
error = input_register_device(input);
if (error)
- goto err_remove_handlers;
+ goto err_remove_fs;
if (button->type == ACPI_BUTTON_TYPE_LID)
acpi_lid_send_state(button);
@@ -487,8 +427,6 @@ static int acpi_button_add(struct acpi_device *device)
return 0;
- err_remove_handlers:
- acpi_button_remove_notify_handlers(button);
err_remove_fs:
acpi_button_remove_fs(device);
err_free_input:
@@ -507,7 +445,6 @@ static int acpi_button_remove(struct acpi_device *device, int type)
button = acpi_driver_data(device);
- acpi_button_remove_notify_handlers(button);
acpi_button_remove_fs(device);
input_unregister_device(button->input);
kfree(button);
@@ -522,7 +459,6 @@ static int __init acpi_button_init(void)
acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
if (!acpi_button_dir)
return -ENODEV;
- acpi_button_dir->owner = THIS_MODULE;
result = acpi_bus_register_driver(&acpi_button_driver);
if (result < 0) {
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index 20223cbd0d1c..a8287be0870e 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -13,11 +13,6 @@
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("debug");
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
-
struct acpi_dlayer {
const char *name;
unsigned long value;
@@ -297,17 +292,15 @@ acpi_system_write_debug(struct file *file,
return count;
}
+#endif
-static int __init acpi_debug_init(void)
+int __init acpi_debug_init(void)
{
+#ifdef CONFIG_ACPI_PROCFS
struct proc_dir_entry *entry;
int error = 0;
char *name;
-
- if (acpi_disabled)
- return 0;
-
/* 'debug_layer' [R/W] */
name = ACPI_SYSTEM_FILE_DEBUG_LAYER;
entry =
@@ -338,7 +331,7 @@ static int __init acpi_debug_init(void)
remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir);
error = -ENODEV;
goto Done;
-}
-
-subsys_initcall(acpi_debug_init);
+#else
+ return 0;
#endif
+}
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 35094f230b1e..efb959d6c8a9 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -977,7 +977,7 @@ static int dock_add(acpi_handle handle)
sizeof(struct dock_station *));
/* we want the dock device to send uevents */
- dock_device->dev.uevent_suppress = 0;
+ dev_set_uevent_suppress(&dock_device->dev, 0);
if (is_dock(handle))
dock_station->flags |= DOCK_IS_DOCK;
@@ -1146,9 +1146,10 @@ static int __init dock_init(void)
static void __exit dock_exit(void)
{
struct dock_station *dock_station;
+ struct dock_station *tmp;
unregister_acpi_bus_notifier(&dock_acpi_notifier);
- list_for_each_entry(dock_station, &dock_stations, sibiling)
+ list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling)
dock_remove(dock_station);
}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 2fe15060dcdc..04e90443eff7 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -67,7 +67,7 @@ enum ec_command {
#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */
#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
-#define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */
+#define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */
#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts
per one transaction */
@@ -236,13 +236,23 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
return 0;
}
+static void ec_delay(void)
+{
+ /* EC in MSI notebooks don't tolerate delays other than 550 usec */
+ if (EC_FLAGS_MSI)
+ udelay(ACPI_EC_DELAY);
+ else
+ /* Use shortest sleep available */
+ msleep(1);
+}
+
static int ec_poll(struct acpi_ec *ec)
{
unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
- udelay(ACPI_EC_UDELAY);
+ udelay(ACPI_EC_CDELAY);
while (time_before(jiffies, delay)) {
gpe_transaction(ec, acpi_ec_read_status(ec));
- udelay(ACPI_EC_UDELAY);
+ ec_delay();
if (ec_transaction_done(ec))
return 0;
}
@@ -672,7 +682,7 @@ static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_ec_read_info, PDE(inode)->data);
}
-static struct file_operations acpi_ec_info_ops = {
+static const struct file_operations acpi_ec_info_ops = {
.open = acpi_ec_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -755,6 +765,10 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
unsigned long long tmp = 0;
struct acpi_ec *ec = context;
+
+ /* clear addr values, ec_parse_io_ports depend on it */
+ ec->command_addr = ec->data_addr = 0;
+
status = acpi_walk_resources(handle, METHOD_NAME__CRS,
ec_parse_io_ports, ec);
if (ACPI_FAILURE(status))
@@ -804,11 +818,11 @@ static int acpi_ec_add(struct acpi_device *device)
ec = make_acpi_ec();
if (!ec)
return -ENOMEM;
- if (ec_parse_device(device->handle, 0, ec, NULL) !=
- AE_CTRL_TERMINATE) {
+ }
+ if (ec_parse_device(device->handle, 0, ec, NULL) !=
+ AE_CTRL_TERMINATE) {
kfree(ec);
return -EINVAL;
- }
}
ec->handle = device->handle;
@@ -986,12 +1000,12 @@ int __init acpi_ec_ecdt_probe(void)
boot_ec->handle = ACPI_ROOT_OBJECT;
acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
/* Don't trust ECDT, which comes from ASUSTek */
- if (!dmi_name_in_vendors("ASUS"))
+ if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0)
goto install;
saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!saved_ec)
return -ENOMEM;
- memcpy(saved_ec, boot_ec, sizeof(*saved_ec));
+ memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec));
/* fall through */
}
/* This workaround is needed only on some broken machines,
@@ -1069,13 +1083,10 @@ static struct acpi_driver acpi_ec_driver = {
},
};
-static int __init acpi_ec_init(void)
+int __init acpi_ec_init(void)
{
int result = 0;
- if (acpi_disabled)
- return 0;
-
acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
if (!acpi_ec_dir)
return -ENODEV;
@@ -1090,8 +1101,6 @@ static int __init acpi_ec_init(void)
return result;
}
-subsys_initcall(acpi_ec_init);
-
/* EC driver currently not unloadable */
#if 0
static void __exit acpi_ec_exit(void)
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index 0c24bd4d6562..aeb7e5fb4a04 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -235,11 +235,7 @@ int acpi_bus_generate_netlink_event(const char *device_class,
return result;
}
- result =
- genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC);
- if (result)
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Failed to send a Genetlink message!\n"));
+ genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC);
return 0;
}
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index eaaee1660bdf..53698ea08371 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -68,31 +68,35 @@ static struct acpi_driver acpi_fan_driver = {
};
/* thermal cooling device callbacks */
-static int fan_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
+ *state)
{
/* ACPI fan device only support two states: ON/OFF */
- return sprintf(buf, "1\n");
+ *state = 1;
+ return 0;
}
-static int fan_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
+ *state)
{
struct acpi_device *device = cdev->devdata;
- int state;
int result;
+ int acpi_state;
if (!device)
return -EINVAL;
- result = acpi_bus_get_power(device->handle, &state);
+ result = acpi_bus_get_power(device->handle, &acpi_state);
if (result)
return result;
- return sprintf(buf, "%s\n", state == ACPI_STATE_D3 ? "0" :
- (state == ACPI_STATE_D0 ? "1" : "unknown"));
+ *state = (acpi_state == ACPI_STATE_D3 ? 0 :
+ (acpi_state == ACPI_STATE_D0 ? 1 : -1));
+ return 0;
}
static int
-fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
{
struct acpi_device *device = cdev->devdata;
int result;
@@ -193,7 +197,6 @@ static int acpi_fan_add_fs(struct acpi_device *device)
acpi_fan_dir);
if (!acpi_device_dir(device))
return -ENODEV;
- acpi_device_dir(device)->owner = THIS_MODULE;
}
/* 'status' [R/W] */
@@ -347,7 +350,6 @@ static int __init acpi_fan_init(void)
acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir);
if (!acpi_fan_dir)
return -ENODEV;
- acpi_fan_dir->owner = THIS_MODULE;
#endif
result = acpi_bus_register_driver(&acpi_fan_driver);
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 5479b9f42513..8bd2c2a6884d 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -286,10 +286,8 @@ static int acpi_platform_notify_remove(struct device *dev)
return 0;
}
-static int __init init_acpi_device_notify(void)
+int __init init_acpi_device_notify(void)
{
- if (acpi_disabled)
- return 0;
if (platform_notify || platform_notify_remove) {
printk(KERN_ERR PREFIX "Can't use platform_notify\n");
return 0;
@@ -298,5 +296,3 @@ static int __init init_acpi_device_notify(void)
platform_notify_remove = acpi_platform_notify_remove;
return 0;
}
-
-arch_initcall(init_acpi_device_notify);
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
new file mode 100644
index 000000000000..11a69b53004e
--- /dev/null
+++ b/drivers/acpi/internal.h
@@ -0,0 +1,43 @@
+/* For use by Linux/ACPI infrastructure, not drivers */
+
+int init_acpi_device_notify(void);
+int acpi_scan_init(void);
+int acpi_system_init(void);
+
+#ifdef CONFIG_ACPI_DEBUG
+int acpi_debug_init(void);
+#else
+static inline int acpi_debug_init(void) { return 0; }
+#endif
+
+/* --------------------------------------------------------------------------
+ Power Resource
+ -------------------------------------------------------------------------- */
+int acpi_power_init(void);
+int acpi_device_sleep_wake(struct acpi_device *dev,
+ int enable, int sleep_state, int dev_state);
+int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state);
+int acpi_disable_wakeup_device_power(struct acpi_device *dev);
+int acpi_power_get_inferred_state(struct acpi_device *device);
+int acpi_power_transition(struct acpi_device *device, int state);
+extern int acpi_power_nocheck;
+
+int acpi_wakeup_device_init(void);
+
+/* --------------------------------------------------------------------------
+ Embedded Controller
+ -------------------------------------------------------------------------- */
+int acpi_ec_init(void);
+int acpi_ec_ecdt_probe(void);
+int acpi_boot_ec_enable(void);
+
+/*--------------------------------------------------------------------------
+ Suspend/Resume
+ -------------------------------------------------------------------------- */
+extern int acpi_sleep_init(void);
+
+#ifdef CONFIG_ACPI_SLEEP
+int acpi_sleep_proc_init(void);
+#else
+static inline int acpi_sleep_proc_init(void) { return 0; }
+#endif
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 3a0d8ef25c75..d440ccd27d91 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -131,6 +131,21 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
#endif /* ACPI_DEBUG_OUTPUT */
break;
+ case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
+#ifdef ACPI_DEBUG_OUTPUT
+ {
+ struct acpi_srat_x2apic_cpu_affinity *p =
+ (struct acpi_srat_x2apic_cpu_affinity *)header;
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "SRAT Processor (x2apicid[0x%08x]) in"
+ " proximity domain %d %s\n",
+ p->apic_id,
+ p->proximity_domain,
+ (p->flags & ACPI_SRAT_CPU_ENABLED) ?
+ "enabled" : "disabled"));
+ }
+#endif /* ACPI_DEBUG_OUTPUT */
+ break;
default:
printk(KERN_WARNING PREFIX
"Found unsupported SRAT entry (type = 0x%x)\n",
@@ -180,8 +195,35 @@ static int __init acpi_parse_slit(struct acpi_table_header *table)
return 0;
}
+void __init __attribute__ ((weak))
+acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
+{
+ printk(KERN_WARNING PREFIX
+ "Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id);
+ return;
+}
+
+
+static int __init
+acpi_parse_x2apic_affinity(struct acpi_subtable_header *header,
+ const unsigned long end)
+{
+ struct acpi_srat_x2apic_cpu_affinity *processor_affinity;
+
+ processor_affinity = (struct acpi_srat_x2apic_cpu_affinity *)header;
+ if (!processor_affinity)
+ return -EINVAL;
+
+ acpi_table_print_srat_entry(header);
+
+ /* let architecture-dependent part to do it */
+ acpi_numa_x2apic_affinity_init(processor_affinity);
+
+ return 0;
+}
+
static int __init
-acpi_parse_processor_affinity(struct acpi_subtable_header * header,
+acpi_parse_processor_affinity(struct acpi_subtable_header *header,
const unsigned long end)
{
struct acpi_srat_cpu_affinity *processor_affinity;
@@ -241,6 +283,8 @@ int __init acpi_numa_init(void)
{
/* SRAT: Static Resource Affinity Table */
if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
+ acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY,
+ acpi_parse_x2apic_affinity, NR_CPUS);
acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
acpi_parse_processor_affinity, NR_CPUS);
acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index eb8980d67368..d59f08ecaf16 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1070,9 +1070,9 @@ __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
* in arbitrary AML code and can interfere with legacy drivers.
* acpi_enforce_resources= can be set to:
*
- * - strict (2)
+ * - strict (default) (2)
* -> further driver trying to access the resources will not load
- * - lax (default) (1)
+ * - lax (1)
* -> further driver trying to access the resources will load, but you
* get a system message that something might go wrong...
*
@@ -1084,7 +1084,7 @@ __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
#define ENFORCE_RESOURCES_LAX 1
#define ENFORCE_RESOURCES_NO 0
-static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_LAX;
+static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
static int __init acpi_enforce_resources_setup(char *str)
{
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 891bdf6679f3..51b9f8280f88 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -86,7 +86,7 @@ static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(struct pci_dev *dev,
}
/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */
-static struct dmi_system_id medion_md9580[] = {
+static const struct dmi_system_id medion_md9580[] = {
{
.ident = "Medion MD9580-F laptop",
.matches = {
@@ -98,7 +98,7 @@ static struct dmi_system_id medion_md9580[] = {
};
/* http://bugzilla.kernel.org/show_bug.cgi?id=5044 */
-static struct dmi_system_id dell_optiplex[] = {
+static const struct dmi_system_id dell_optiplex[] = {
{
.ident = "Dell Optiplex GX1",
.matches = {
@@ -110,7 +110,7 @@ static struct dmi_system_id dell_optiplex[] = {
};
/* http://bugzilla.kernel.org/show_bug.cgi?id=10138 */
-static struct dmi_system_id hp_t5710[] = {
+static const struct dmi_system_id hp_t5710[] = {
{
.ident = "HP t5710",
.matches = {
@@ -123,13 +123,13 @@ static struct dmi_system_id hp_t5710[] = {
};
struct prt_quirk {
- struct dmi_system_id *system;
+ const struct dmi_system_id *system;
unsigned int segment;
unsigned int bus;
unsigned int device;
unsigned char pin;
- char *source; /* according to BIOS */
- char *actual_source;
+ const char *source; /* according to BIOS */
+ const char *actual_source;
};
#define PCI_INTX_PIN(c) (c - 'A' + 1)
@@ -139,7 +139,7 @@ struct prt_quirk {
* interrupt at the listed segment/bus/device/pin is connected to the first
* link device, but it is actually connected to the second.
*/
-static struct prt_quirk prt_quirks[] = {
+static const struct prt_quirk prt_quirks[] = {
{ medion_md9580, 0, 0, 9, PCI_INTX_PIN('A'),
"\\_SB_.PCI0.ISA_.LNKA",
"\\_SB_.PCI0.ISA_.LNKB"},
@@ -155,7 +155,7 @@ static void do_prt_fixups(struct acpi_prt_entry *entry,
struct acpi_pci_routing_table *prt)
{
int i;
- struct prt_quirk *quirk;
+ const struct prt_quirk *quirk;
for (i = 0; i < ARRAY_SIZE(prt_quirks); i++) {
quirk = &prt_quirks[i];
@@ -319,7 +319,7 @@ static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
*/
bridge = dev->bus->self;
while (bridge) {
- pin = (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1;
+ pin = pci_swizzle_interrupt_pin(dev, pin);
if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
/* PC card has the same IRQ as its cardbridge */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 6c772ca76bd1..16e0f9d3d17c 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -43,13 +43,14 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-#define _COMPONENT ACPI_PCI_COMPONENT
+#define _COMPONENT ACPI_PCI_COMPONENT
ACPI_MODULE_NAME("pci_link");
#define ACPI_PCI_LINK_CLASS "pci_irq_routing"
#define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link"
#define ACPI_PCI_LINK_FILE_INFO "info"
#define ACPI_PCI_LINK_FILE_STATUS "state"
-#define ACPI_PCI_LINK_MAX_POSSIBLE 16
+#define ACPI_PCI_LINK_MAX_POSSIBLE 16
+
static int acpi_pci_link_add(struct acpi_device *device);
static int acpi_pci_link_remove(struct acpi_device *device, int type);
@@ -66,7 +67,7 @@ static struct acpi_driver acpi_pci_link_driver = {
.ops = {
.add = acpi_pci_link_add,
.remove = acpi_pci_link_remove,
- },
+ },
};
/*
@@ -76,7 +77,7 @@ static struct acpi_driver acpi_pci_link_driver = {
struct acpi_pci_link_irq {
u8 active; /* Current IRQ */
u8 triggering; /* All IRQs */
- u8 polarity; /* All IRQs */
+ u8 polarity; /* All IRQs */
u8 resource_type;
u8 possible_count;
u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
@@ -85,16 +86,13 @@ struct acpi_pci_link_irq {
};
struct acpi_pci_link {
- struct list_head node;
- struct acpi_device *device;
- struct acpi_pci_link_irq irq;
- int refcnt;
+ struct list_head list;
+ struct acpi_device *device;
+ struct acpi_pci_link_irq irq;
+ int refcnt;
};
-static struct {
- int count;
- struct list_head entries;
-} acpi_link;
+static LIST_HEAD(acpi_link_list);
static DEFINE_MUTEX(acpi_link_lock);
/* --------------------------------------------------------------------------
@@ -104,12 +102,11 @@ static DEFINE_MUTEX(acpi_link_lock);
/*
* set context (link) possible list from resource list
*/
-static acpi_status
-acpi_pci_link_check_possible(struct acpi_resource *resource, void *context)
+static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,
+ void *context)
{
struct acpi_pci_link *link = context;
- u32 i = 0;
-
+ u32 i;
switch (resource->type) {
case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -179,10 +176,6 @@ static int acpi_pci_link_get_possible(struct acpi_pci_link *link)
{
acpi_status status;
-
- if (!link)
- return -EINVAL;
-
status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS,
acpi_pci_link_check_possible, link);
if (ACPI_FAILURE(status)) {
@@ -197,11 +190,10 @@ static int acpi_pci_link_get_possible(struct acpi_pci_link *link)
return 0;
}
-static acpi_status
-acpi_pci_link_check_current(struct acpi_resource *resource, void *context)
+static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource,
+ void *context)
{
- int *irq = (int *)context;
-
+ int *irq = context;
switch (resource->type) {
case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -258,12 +250,9 @@ acpi_pci_link_check_current(struct acpi_resource *resource, void *context)
static int acpi_pci_link_get_current(struct acpi_pci_link *link)
{
int result = 0;
- acpi_status status = AE_OK;
+ acpi_status status;
int irq = 0;
- if (!link)
- return -EINVAL;
-
link->irq.active = 0;
/* in practice, status disabled is meaningless, ignore it */
@@ -308,16 +297,15 @@ static int acpi_pci_link_get_current(struct acpi_pci_link *link)
static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
{
- int result = 0;
- acpi_status status = AE_OK;
+ int result;
+ acpi_status status;
struct {
struct acpi_resource res;
struct acpi_resource end;
} *resource;
struct acpi_buffer buffer = { 0, NULL };
-
- if (!link || !irq)
+ if (!irq)
return -EINVAL;
resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
@@ -479,30 +467,22 @@ static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ9 PCI, often acpi */
PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ10 PCI */
PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ11 PCI */
- PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */
- PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */
- PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */
- PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */
+ PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */
+ PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */
+ PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */
+ PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */
/* >IRQ15 */
};
int __init acpi_irq_penalty_init(void)
{
- struct list_head *node = NULL;
- struct acpi_pci_link *link = NULL;
- int i = 0;
-
+ struct acpi_pci_link *link;
+ int i;
/*
* Update penalties to facilitate IRQ balancing.
*/
- list_for_each(node, &acpi_link.entries) {
-
- link = list_entry(node, struct acpi_pci_link, node);
- if (!link) {
- printk(KERN_ERR PREFIX "Invalid link context\n");
- continue;
- }
+ list_for_each_entry(link, &acpi_link_list, list) {
/*
* reflect the possible and active irqs in the penalty table --
@@ -527,7 +507,6 @@ int __init acpi_irq_penalty_init(void)
}
/* Add a penalty for the SCI */
acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING;
-
return 0;
}
@@ -538,7 +517,6 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
int irq;
int i;
-
if (link->irq.initialized) {
if (link->refcnt == 0)
/* This means the link is disabled but initialized */
@@ -566,11 +544,10 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
/*
* if active found, use it; else pick entry from end of possible list.
*/
- if (link->irq.active) {
+ if (link->irq.active)
irq = link->irq.active;
- } else {
+ else
irq = link->irq.possible[link->irq.possible_count - 1];
- }
if (acpi_irq_balance || !link->irq.active) {
/*
@@ -599,7 +576,6 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
}
link->irq.initialized = 1;
-
return 0;
}
@@ -608,16 +584,12 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
* success: return IRQ >= 0
* failure: return -1
*/
-
-int
-acpi_pci_link_allocate_irq(acpi_handle handle,
- int index,
- int *triggering, int *polarity, char **name)
+int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
+ int *polarity, char **name)
{
- int result = 0;
- struct acpi_device *device = NULL;
- struct acpi_pci_link *link = NULL;
-
+ int result;
+ struct acpi_device *device;
+ struct acpi_pci_link *link;
result = acpi_bus_get_device(handle, &device);
if (result) {
@@ -669,11 +641,10 @@ acpi_pci_link_allocate_irq(acpi_handle handle,
*/
int acpi_pci_link_free_irq(acpi_handle handle)
{
- struct acpi_device *device = NULL;
- struct acpi_pci_link *link = NULL;
+ struct acpi_device *device;
+ struct acpi_pci_link *link;
acpi_status result;
-
result = acpi_bus_get_device(handle, &device);
if (result) {
printk(KERN_ERR PREFIX "Invalid link device\n");
@@ -708,9 +679,9 @@ int acpi_pci_link_free_irq(acpi_handle handle)
"Link %s is dereferenced\n",
acpi_device_bid(link->device)));
- if (link->refcnt == 0) {
+ if (link->refcnt == 0)
acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);
- }
+
mutex_unlock(&acpi_link_lock);
return (link->irq.active);
}
@@ -721,15 +692,11 @@ int acpi_pci_link_free_irq(acpi_handle handle)
static int acpi_pci_link_add(struct acpi_device *device)
{
- int result = 0;
- struct acpi_pci_link *link = NULL;
- int i = 0;
+ int result;
+ struct acpi_pci_link *link;
+ int i;
int found = 0;
-
- if (!device)
- return -EINVAL;
-
link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
if (!link)
return -ENOMEM;
@@ -767,9 +734,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
printk("\n");
- /* TBD: Acquire/release lock */
- list_add_tail(&link->node, &acpi_link.entries);
- acpi_link.count++;
+ list_add_tail(&link->list, &acpi_link_list);
end:
/* disable all links -- to be activated on use */
@@ -784,24 +749,17 @@ static int acpi_pci_link_add(struct acpi_device *device)
static int acpi_pci_link_resume(struct acpi_pci_link *link)
{
-
if (link->refcnt && link->irq.active && link->irq.initialized)
return (acpi_pci_link_set(link, link->irq.active));
- else
- return 0;
+
+ return 0;
}
static int irqrouter_resume(struct sys_device *dev)
{
- struct list_head *node = NULL;
- struct acpi_pci_link *link = NULL;
+ struct acpi_pci_link *link;
- list_for_each(node, &acpi_link.entries) {
- link = list_entry(node, struct acpi_pci_link, node);
- if (!link) {
- printk(KERN_ERR PREFIX "Invalid link context\n");
- continue;
- }
+ list_for_each_entry(link, &acpi_link_list, list) {
acpi_pci_link_resume(link);
}
return 0;
@@ -809,20 +767,15 @@ static int irqrouter_resume(struct sys_device *dev)
static int acpi_pci_link_remove(struct acpi_device *device, int type)
{
- struct acpi_pci_link *link = NULL;
-
-
- if (!device || !acpi_driver_data(device))
- return -EINVAL;
+ struct acpi_pci_link *link;
link = acpi_driver_data(device);
mutex_lock(&acpi_link_lock);
- list_del(&link->node);
+ list_del(&link->list);
mutex_unlock(&acpi_link_lock);
kfree(link);
-
return 0;
}
@@ -931,7 +884,6 @@ static int __init irqrouter_init_sysfs(void)
{
int error;
-
if (acpi_disabled || acpi_noirq)
return 0;
@@ -957,9 +909,6 @@ static int __init acpi_pci_link_init(void)
acpi_irq_balance = 0;
}
- acpi_link.count = 0;
- INIT_LIST_HEAD(&acpi_link.entries);
-
if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0)
return -ENODEV;
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 5b38a026d122..196f97d00956 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -66,11 +66,18 @@ struct acpi_pci_root {
struct acpi_device * device;
struct acpi_pci_id id;
struct pci_bus *bus;
+
+ u32 osc_support_set; /* _OSC state of support bits */
+ u32 osc_control_set; /* _OSC state of control bits */
+ u32 osc_control_qry; /* the latest _OSC query result */
+
+ u32 osc_queried:1; /* has _OSC control been queried? */
};
static LIST_HEAD(acpi_pci_roots);
static struct acpi_pci_driver *sub_driver;
+static DEFINE_MUTEX(osc_lock);
int acpi_pci_register_driver(struct acpi_pci_driver *driver)
{
@@ -185,6 +192,175 @@ static void acpi_pci_bridge_scan(struct acpi_device *device)
}
}
+static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40,
+ 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
+
+static acpi_status acpi_pci_run_osc(acpi_handle handle,
+ const u32 *capbuf, u32 *retval)
+{
+ acpi_status status;
+ struct acpi_object_list input;
+ union acpi_object in_params[4];
+ struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+ union acpi_object *out_obj;
+ u32 errors;
+
+ /* Setting up input parameters */
+ input.count = 4;
+ input.pointer = in_params;
+ in_params[0].type = ACPI_TYPE_BUFFER;
+ in_params[0].buffer.length = 16;
+ in_params[0].buffer.pointer = OSC_UUID;
+ in_params[1].type = ACPI_TYPE_INTEGER;
+ in_params[1].integer.value = 1;
+ in_params[2].type = ACPI_TYPE_INTEGER;
+ in_params[2].integer.value = 3;
+ in_params[3].type = ACPI_TYPE_BUFFER;
+ in_params[3].buffer.length = 12;
+ in_params[3].buffer.pointer = (u8 *)capbuf;
+
+ status = acpi_evaluate_object(handle, "_OSC", &input, &output);
+ if (ACPI_FAILURE(status))
+ return status;
+
+ if (!output.length)
+ return AE_NULL_OBJECT;
+
+ out_obj = output.pointer;
+ if (out_obj->type != ACPI_TYPE_BUFFER) {
+ printk(KERN_DEBUG "_OSC evaluation returned wrong type\n");
+ status = AE_TYPE;
+ goto out_kfree;
+ }
+ /* Need to ignore the bit0 in result code */
+ errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
+ if (errors) {
+ if (errors & OSC_REQUEST_ERROR)
+ printk(KERN_DEBUG "_OSC request failed\n");
+ if (errors & OSC_INVALID_UUID_ERROR)
+ printk(KERN_DEBUG "_OSC invalid UUID\n");
+ if (errors & OSC_INVALID_REVISION_ERROR)
+ printk(KERN_DEBUG "_OSC invalid revision\n");
+ if (errors & OSC_CAPABILITIES_MASK_ERROR) {
+ if (capbuf[OSC_QUERY_TYPE] & OSC_QUERY_ENABLE)
+ goto out_success;
+ printk(KERN_DEBUG
+ "Firmware did not grant requested _OSC control\n");
+ status = AE_SUPPORT;
+ goto out_kfree;
+ }
+ status = AE_ERROR;
+ goto out_kfree;
+ }
+out_success:
+ *retval = *((u32 *)(out_obj->buffer.pointer + 8));
+ status = AE_OK;
+
+out_kfree:
+ kfree(output.pointer);
+ return status;
+}
+
+static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags)
+{
+ acpi_status status;
+ u32 support_set, result, capbuf[3];
+
+ /* do _OSC query for all possible controls */
+ support_set = root->osc_support_set | (flags & OSC_SUPPORT_MASKS);
+ capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
+ capbuf[OSC_SUPPORT_TYPE] = support_set;
+ capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
+
+ status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
+ if (ACPI_SUCCESS(status)) {
+ root->osc_support_set = support_set;
+ root->osc_control_qry = result;
+ root->osc_queried = 1;
+ }
+ return status;
+}
+
+static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
+{
+ acpi_status status;
+ acpi_handle tmp;
+
+ status = acpi_get_handle(root->device->handle, "_OSC", &tmp);
+ if (ACPI_FAILURE(status))
+ return status;
+ mutex_lock(&osc_lock);
+ status = acpi_pci_query_osc(root, flags);
+ mutex_unlock(&osc_lock);
+ return status;
+}
+
+static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
+{
+ struct acpi_pci_root *root;
+ list_for_each_entry(root, &acpi_pci_roots, node) {
+ if (root->device->handle == handle)
+ return root;
+ }
+ return NULL;
+}
+
+/**
+ * acpi_pci_osc_control_set - commit requested control to Firmware
+ * @handle: acpi_handle for the target ACPI object
+ * @flags: driver's requested control bits
+ *
+ * Attempt to take control from Firmware on requested control bits.
+ **/
+acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags)
+{
+ acpi_status status;
+ u32 control_req, result, capbuf[3];
+ acpi_handle tmp;
+ struct acpi_pci_root *root;
+
+ status = acpi_get_handle(handle, "_OSC", &tmp);
+ if (ACPI_FAILURE(status))
+ return status;
+
+ control_req = (flags & OSC_CONTROL_MASKS);
+ if (!control_req)
+ return AE_TYPE;
+
+ root = acpi_pci_find_root(handle);
+ if (!root)
+ return AE_NOT_EXIST;
+
+ mutex_lock(&osc_lock);
+ /* No need to evaluate _OSC if the control was already granted. */
+ if ((root->osc_control_set & control_req) == control_req)
+ goto out;
+
+ /* Need to query controls first before requesting them */
+ if (!root->osc_queried) {
+ status = acpi_pci_query_osc(root, root->osc_support_set);
+ if (ACPI_FAILURE(status))
+ goto out;
+ }
+ if ((root->osc_control_qry & control_req) != control_req) {
+ printk(KERN_DEBUG
+ "Firmware did not grant requested _OSC control\n");
+ status = AE_SUPPORT;
+ goto out;
+ }
+
+ capbuf[OSC_QUERY_TYPE] = 0;
+ capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set;
+ capbuf[OSC_CONTROL_TYPE] = root->osc_control_set | control_req;
+ status = acpi_pci_run_osc(handle, capbuf, &result);
+ if (ACPI_SUCCESS(status))
+ root->osc_control_set = result;
+out:
+ mutex_unlock(&osc_lock);
+ return status;
+}
+EXPORT_SYMBOL(acpi_pci_osc_control_set);
+
static int __devinit acpi_pci_root_add(struct acpi_device *device)
{
int result = 0;
@@ -217,7 +393,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
* PCI domains, so we indicate this in _OSC support capabilities.
*/
flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
- pci_acpi_osc_support(device->handle, flags);
+ acpi_pci_osc_support(root, flags);
/*
* Segment
@@ -353,7 +529,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
if (pci_msi_enabled())
flags |= OSC_MSI_SUPPORT;
if (flags != base_flags)
- pci_acpi_osc_support(device->handle, flags);
+ acpi_pci_osc_support(root, flags);
end:
if (result) {
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index c926e7d4a0d6..56665a63bf19 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -54,10 +54,6 @@ ACPI_MODULE_NAME("power");
#define ACPI_POWER_RESOURCE_STATE_ON 0x01
#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
int acpi_power_nocheck;
module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
@@ -773,14 +769,10 @@ static int acpi_power_resume(struct acpi_device *device)
return 0;
}
-static int __init acpi_power_init(void)
+int __init acpi_power_init(void)
{
int result = 0;
-
- if (acpi_disabled)
- return 0;
-
INIT_LIST_HEAD(&acpi_power_resource_list);
acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir);
@@ -795,5 +787,3 @@ static int __init acpi_power_init(void)
return 0;
}
-
-subsys_initcall(acpi_power_init);
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index 428c911dba08..05dfdc96802e 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -496,11 +496,8 @@ static u32 rtc_handler(void *context)
}
#endif /* HAVE_ACPI_LEGACY_ALARM */
-static int __init acpi_sleep_proc_init(void)
+int __init acpi_sleep_proc_init(void)
{
- if (acpi_disabled)
- return 0;
-
#ifdef CONFIG_ACPI_PROCFS
/* 'sleep' [R/W] */
proc_create("sleep", S_IFREG | S_IRUGO | S_IWUSR,
@@ -527,5 +524,3 @@ static int __init acpi_sleep_proc_init(void)
return 0;
}
-
-late_initcall(acpi_sleep_proc_init);
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 0cc2fd31e376..45ad3288c5ff 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -82,7 +82,7 @@ static int acpi_processor_add(struct acpi_device *device);
static int acpi_processor_start(struct acpi_device *device);
static int acpi_processor_remove(struct acpi_device *device, int type);
static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
-static void acpi_processor_notify(acpi_handle handle, u32 event, void *data);
+static void acpi_processor_notify(struct acpi_device *device, u32 event);
static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
static int acpi_processor_handle_eject(struct acpi_processor *pr);
@@ -104,6 +104,7 @@ static struct acpi_driver acpi_processor_driver = {
.start = acpi_processor_start,
.suspend = acpi_processor_suspend,
.resume = acpi_processor_resume,
+ .notify = acpi_processor_notify,
},
};
@@ -359,7 +360,6 @@ static int acpi_processor_add_fs(struct acpi_device *device)
if (!acpi_device_dir(device))
return -ENODEV;
}
- acpi_device_dir(device)->owner = THIS_MODULE;
/* 'info' [R] */
entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO,
@@ -427,6 +427,29 @@ static int map_lapic_id(struct acpi_subtable_header *entry,
return 0;
}
+static int map_x2apic_id(struct acpi_subtable_header *entry,
+ int device_declaration, u32 acpi_id, int *apic_id)
+{
+ struct acpi_madt_local_x2apic *apic =
+ (struct acpi_madt_local_x2apic *)entry;
+ u32 tmp = apic->local_apic_id;
+
+ /* Only check enabled APICs*/
+ if (!(apic->lapic_flags & ACPI_MADT_ENABLED))
+ return 0;
+
+ /* Device statement declaration type */
+ if (device_declaration) {
+ if (apic->uid == acpi_id)
+ goto found;
+ }
+
+ return 0;
+found:
+ *apic_id = tmp;
+ return 1;
+}
+
static int map_lsapic_id(struct acpi_subtable_header *entry,
int device_declaration, u32 acpi_id, int *apic_id)
{
@@ -476,6 +499,9 @@ static int map_madt_entry(int type, u32 acpi_id)
if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
if (map_lapic_id(header, acpi_id, &apic_id))
break;
+ } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
+ if (map_x2apic_id(header, type, acpi_id, &apic_id))
+ break;
} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
if (map_lsapic_id(header, type, acpi_id, &apic_id))
break;
@@ -666,7 +692,6 @@ static DEFINE_PER_CPU(void *, processor_device_array);
static int __cpuinit acpi_processor_start(struct acpi_device *device)
{
int result = 0;
- acpi_status status = AE_OK;
struct acpi_processor *pr;
struct sys_device *sysdev;
@@ -703,9 +728,6 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev"))
return -EFAULT;
- status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
- acpi_processor_notify, pr);
-
/* _PDC call should be done before doing anything else (if reqd.). */
arch_acpi_processor_init_pdc(pr);
acpi_processor_set_pdc(pr);
@@ -751,18 +773,14 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
return result;
}
-static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_processor_notify(struct acpi_device *device, u32 event)
{
- struct acpi_processor *pr = data;
- struct acpi_device *device = NULL;
+ struct acpi_processor *pr = acpi_driver_data(device);
int saved;
if (!pr)
return;
- if (acpi_bus_get_device(pr->handle, &device))
- return;
-
switch (event) {
case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
saved = pr->performance_platform_limit;
@@ -841,7 +859,6 @@ static int acpi_processor_add(struct acpi_device *device)
static int acpi_processor_remove(struct acpi_device *device, int type)
{
- acpi_status status = AE_OK;
struct acpi_processor *pr = NULL;
@@ -860,9 +877,6 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
acpi_processor_power_exit(pr, device);
- status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
- acpi_processor_notify);
-
sysfs_remove_link(&device->dev.kobj, "sysdev");
acpi_processor_remove_fs(device);
@@ -1137,7 +1151,6 @@ static int __init acpi_processor_init(void)
acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
if (!acpi_processor_dir)
return -ENOMEM;
- acpi_processor_dir->owner = THIS_MODULE;
/*
* Check whether the system is DMI table. If yes, OSPM
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 7bc22a471fe3..4e6e758bd397 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -64,7 +64,6 @@
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_idle");
#define ACPI_PROCESSOR_FILE_POWER "power"
-#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
#define C2_OVERHEAD 1 /* 1us */
#define C3_OVERHEAD 1 /* 1us */
@@ -78,6 +77,10 @@ module_param(nocst, uint, 0000);
static unsigned int latency_factor __read_mostly = 2;
module_param(latency_factor, uint, 0644);
+static s64 us_to_pm_timer_ticks(s64 t)
+{
+ return div64_u64(t * PM_TIMER_FREQUENCY, 1000000);
+}
/*
* IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
* For now disable this. Probably a bug somewhere else.
@@ -101,57 +104,6 @@ static int set_max_cstate(const struct dmi_system_id *id)
/* Actually this shouldn't be __cpuinitdata, would be better to fix the
callers to only run once -AK */
static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET70WW")}, (void *)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1},
- { set_max_cstate, "Medion 41700", {
- DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
- DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1},
{ set_max_cstate, "Clevo 5600D", {
DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
@@ -159,25 +111,6 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
{},
};
-static inline u32 ticks_elapsed(u32 t1, u32 t2)
-{
- if (t2 >= t1)
- return (t2 - t1);
- else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
- return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
- else
- return ((0xFFFFFFFF - t1) + t2);
-}
-
-static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
-{
- if (t2 >= t1)
- return PM_TIMER_TICKS_TO_US(t2 - t1);
- else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
- return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
- else
- return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
-}
/*
* Callers should disable interrupts before the call and enable
@@ -630,7 +563,7 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
* In either case, the proper way to
* handle BM_RLD is to set it and leave it set.
*/
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
+ acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
return;
}
@@ -800,9 +733,9 @@ static int acpi_idle_bm_check(void)
{
u32 bm_status = 0;
- acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
+ acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
if (bm_status)
- acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
+ acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
/*
* PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
* the true state of bus mastering activity; forcing us to
@@ -853,7 +786,8 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
static int acpi_idle_enter_c1(struct cpuidle_device *dev,
struct cpuidle_state *state)
{
- u32 t1, t2;
+ ktime_t kt1, kt2;
+ s64 idle_time;
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
@@ -871,14 +805,15 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
return 0;
}
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt1 = ktime_get_real();
acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt2 = ktime_get_real();
+ idle_time = ktime_to_us(ktime_sub(kt2, kt1));
local_irq_enable();
cx->usage++;
- return ticks_elapsed_in_us(t1, t2);
+ return idle_time;
}
/**
@@ -891,8 +826,9 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
{
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
- u32 t1, t2;
- int sleep_ticks = 0;
+ ktime_t kt1, kt2;
+ s64 idle_time;
+ s64 sleep_ticks = 0;
pr = __get_cpu_var(processors);
@@ -925,18 +861,19 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
if (cx->type == ACPI_STATE_C3)
ACPI_FLUSH_CPU_CACHE();
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt1 = ktime_get_real();
/* Tell the scheduler that we are going deep-idle: */
sched_clock_idle_sleep_event();
acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt2 = ktime_get_real();
+ idle_time = ktime_to_us(ktime_sub(kt2, kt1));
#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
/* TSC could halt in idle, so notify users */
if (tsc_halts_in_c(cx->type))
mark_tsc_unstable("TSC halts in idle");;
#endif
- sleep_ticks = ticks_elapsed(t1, t2);
+ sleep_ticks = us_to_pm_timer_ticks(idle_time);
/* Tell the scheduler how much we idled: */
sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
@@ -948,7 +885,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
acpi_state_timer_broadcast(pr, cx, 0);
cx->time += sleep_ticks;
- return ticks_elapsed_in_us(t1, t2);
+ return idle_time;
}
static int c3_cpu_count;
@@ -966,8 +903,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
{
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
- u32 t1, t2;
- int sleep_ticks = 0;
+ ktime_t kt1, kt2;
+ s64 idle_time;
+ s64 sleep_ticks = 0;
+
pr = __get_cpu_var(processors);
@@ -1028,20 +967,21 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
c3_cpu_count++;
/* Disable bus master arbitration when all CPUs are in C3 */
if (c3_cpu_count == num_online_cpus())
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+ acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
spin_unlock(&c3_lock);
} else if (!pr->flags.bm_check) {
ACPI_FLUSH_CPU_CACHE();
}
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt1 = ktime_get_real();
acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt2 = ktime_get_real();
+ idle_time = ktime_to_us(ktime_sub(kt2, kt1));
/* Re-enable bus master arbitration */
if (pr->flags.bm_check && pr->flags.bm_control) {
spin_lock(&c3_lock);
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+ acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
c3_cpu_count--;
spin_unlock(&c3_lock);
}
@@ -1051,7 +991,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
if (tsc_halts_in_c(ACPI_STATE_C3))
mark_tsc_unstable("TSC halts in idle");
#endif
- sleep_ticks = ticks_elapsed(t1, t2);
+ sleep_ticks = us_to_pm_timer_ticks(idle_time);
/* Tell the scheduler how much we idled: */
sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
@@ -1062,7 +1002,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
acpi_state_timer_broadcast(pr, cx, 0);
cx->time += sleep_ticks;
- return ticks_elapsed_in_us(t1, t2);
+ return idle_time;
}
struct cpuidle_driver acpi_idle_driver = {
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 68fd3d292799..cafb41000f6b 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -479,6 +479,13 @@ static int acpi_processor_get_psd(struct acpi_processor *pr)
goto end;
}
+ if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
+ pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
+ pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
+ printk(KERN_ERR PREFIX "Invalid _PSD:coord_type\n");
+ result = -EFAULT;
+ goto end;
+ }
end:
kfree(buffer.pointer);
return result;
@@ -501,9 +508,10 @@ int acpi_processor_preregister_performance(
mutex_lock(&performance_mutex);
- retval = 0;
-
- /* Call _PSD for all CPUs */
+ /*
+ * Check if another driver has already registered, and abort before
+ * changing pr->performance if it has. Check input data as well.
+ */
for_each_possible_cpu(i) {
pr = per_cpu(processors, i);
if (!pr) {
@@ -513,13 +521,20 @@ int acpi_processor_preregister_performance(
if (pr->performance) {
retval = -EBUSY;
- continue;
+ goto err_out;
}
if (!performance || !per_cpu_ptr(performance, i)) {
retval = -EINVAL;
- continue;
+ goto err_out;
}
+ }
+
+ /* Call _PSD for all CPUs */
+ for_each_possible_cpu(i) {
+ pr = per_cpu(processors, i);
+ if (!pr)
+ continue;
pr->performance = per_cpu_ptr(performance, i);
cpumask_set_cpu(i, pr->performance->shared_cpu_map);
@@ -535,26 +550,6 @@ int acpi_processor_preregister_performance(
* Now that we have _PSD data from all CPUs, lets setup P-state
* domain info.
*/
- for_each_possible_cpu(i) {
- pr = per_cpu(processors, i);
- if (!pr)
- continue;
-
- /* Basic validity check for domain info */
- pdomain = &(pr->performance->domain_info);
- if ((pdomain->revision != ACPI_PSD_REV0_REVISION) ||
- (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES)) {
- retval = -EINVAL;
- goto err_ret;
- }
- if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
- pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
- pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
- retval = -EINVAL;
- goto err_ret;
- }
- }
-
cpumask_clear(covered_cpus);
for_each_possible_cpu(i) {
pr = per_cpu(processors, i);
@@ -643,6 +638,7 @@ err_ret:
pr->performance = NULL; /* Will be set for real in register */
}
+err_out:
mutex_unlock(&performance_mutex);
free_cpumask_var(covered_cpus);
return retval;
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index b1eb376fae45..39838c666032 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -373,7 +373,8 @@ static int acpi_processor_max_state(struct acpi_processor *pr)
return max_state;
}
static int
-processor_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+processor_get_max_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr = acpi_driver_data(device);
@@ -381,28 +382,29 @@ processor_get_max_state(struct thermal_cooling_device *cdev, char *buf)
if (!device || !pr)
return -EINVAL;
- return sprintf(buf, "%d\n", acpi_processor_max_state(pr));
+ *state = acpi_processor_max_state(pr);
+ return 0;
}
static int
-processor_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+processor_get_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long *cur_state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr = acpi_driver_data(device);
- int cur_state;
if (!device || !pr)
return -EINVAL;
- cur_state = cpufreq_get_cur_state(pr->id);
+ *cur_state = cpufreq_get_cur_state(pr->id);
if (pr->flags.throttling)
- cur_state += pr->throttling.state;
-
- return sprintf(buf, "%d\n", cur_state);
+ *cur_state += pr->throttling.state;
+ return 0;
}
static int
-processor_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+processor_set_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr = acpi_driver_data(device);
@@ -507,7 +509,7 @@ static ssize_t acpi_processor_write_limit(struct file * file,
return count;
}
-struct file_operations acpi_processor_limit_fops = {
+const struct file_operations acpi_processor_limit_fops = {
.owner = THIS_MODULE,
.open = acpi_processor_limit_open_fs,
.read = seq_read,
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index d27838171f4a..d0d1f4d50434 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -783,11 +783,9 @@ static int acpi_get_throttling_state(struct acpi_processor *pr,
(struct acpi_processor_tx_tss *)&(pr->throttling.
states_tss[i]);
if (tx->control == value)
- break;
+ return i;
}
- if (i > pr->throttling.state_count)
- i = -1;
- return i;
+ return -1;
}
static int acpi_get_throttling_value(struct acpi_processor *pr,
@@ -1291,7 +1289,7 @@ static ssize_t acpi_processor_write_throttling(struct file *file,
return count;
}
-struct file_operations acpi_processor_throttling_fops = {
+const struct file_operations acpi_processor_throttling_fops = {
.owner = THIS_MODULE,
.open = acpi_processor_throttling_open_fs,
.read = seq_read,
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 6050ce481873..4b214b74ebaa 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -102,8 +102,8 @@ struct acpi_battery {
u16 cycle_count;
u16 temp_now;
u16 voltage_now;
- s16 current_now;
- s16 current_avg;
+ s16 rate_now;
+ s16 rate_avg;
u16 capacity_now;
u16 state_of_charge;
u16 state;
@@ -202,9 +202,9 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
return -ENODEV;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
- if (battery->current_now < 0)
+ if (battery->rate_now < 0)
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
- else if (battery->current_now > 0)
+ else if (battery->rate_now > 0)
val->intval = POWER_SUPPLY_STATUS_CHARGING;
else
val->intval = POWER_SUPPLY_STATUS_FULL;
@@ -224,11 +224,13 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
acpi_battery_vscale(battery) * 1000;
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
- val->intval = abs(battery->current_now) *
+ case POWER_SUPPLY_PROP_POWER_NOW:
+ val->intval = abs(battery->rate_now) *
acpi_battery_ipscale(battery) * 1000;
break;
case POWER_SUPPLY_PROP_CURRENT_AVG:
- val->intval = abs(battery->current_avg) *
+ case POWER_SUPPLY_PROP_POWER_AVG:
+ val->intval = abs(battery->rate_avg) *
acpi_battery_ipscale(battery) * 1000;
break;
case POWER_SUPPLY_PROP_CAPACITY:
@@ -293,6 +295,8 @@ static enum power_supply_property sbs_energy_battery_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CURRENT_AVG,
+ POWER_SUPPLY_PROP_POWER_NOW,
+ POWER_SUPPLY_PROP_POWER_AVG,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_FULL,
@@ -301,6 +305,7 @@ static enum power_supply_property sbs_energy_battery_props[] = {
POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_MANUFACTURER,
};
+
#endif
/* --------------------------------------------------------------------------
@@ -330,8 +335,8 @@ static struct acpi_battery_reader info_readers[] = {
static struct acpi_battery_reader state_readers[] = {
{0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
{0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
- {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
- {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
+ {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_now)},
+ {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_avg)},
{0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
{0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
{0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
@@ -479,16 +484,15 @@ static int
acpi_sbs_add_fs(struct proc_dir_entry **dir,
struct proc_dir_entry *parent_dir,
char *dir_name,
- struct file_operations *info_fops,
- struct file_operations *state_fops,
- struct file_operations *alarm_fops, void *data)
+ const struct file_operations *info_fops,
+ const struct file_operations *state_fops,
+ const struct file_operations *alarm_fops, void *data)
{
if (!*dir) {
*dir = proc_mkdir(dir_name, parent_dir);
if (!*dir) {
return -ENODEV;
}
- (*dir)->owner = THIS_MODULE;
}
/* 'info' [R] */
@@ -589,9 +593,9 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
seq_printf(seq, "capacity state: %s\n",
(battery->state & 0x0010) ? "critical" : "ok");
seq_printf(seq, "charging state: %s\n",
- (battery->current_now < 0) ? "discharging" :
- ((battery->current_now > 0) ? "charging" : "charged"));
- rate = abs(battery->current_now) * acpi_battery_ipscale(battery);
+ (battery->rate_now < 0) ? "discharging" :
+ ((battery->rate_now > 0) ? "charging" : "charged"));
+ rate = abs(battery->rate_now) * acpi_battery_ipscale(battery);
rate *= (acpi_battery_mode(battery))?(battery->voltage_now *
acpi_battery_vscale(battery)/1000):1;
seq_printf(seq, "present rate: %d%s\n", rate,
@@ -677,7 +681,7 @@ static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
}
-static struct file_operations acpi_battery_info_fops = {
+static const struct file_operations acpi_battery_info_fops = {
.open = acpi_battery_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -685,7 +689,7 @@ static struct file_operations acpi_battery_info_fops = {
.owner = THIS_MODULE,
};
-static struct file_operations acpi_battery_state_fops = {
+static const struct file_operations acpi_battery_state_fops = {
.open = acpi_battery_state_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -693,7 +697,7 @@ static struct file_operations acpi_battery_state_fops = {
.owner = THIS_MODULE,
};
-static struct file_operations acpi_battery_alarm_fops = {
+static const struct file_operations acpi_battery_alarm_fops = {
.open = acpi_battery_alarm_open_fs,
.read = seq_read,
.write = acpi_battery_write_alarm,
@@ -725,7 +729,7 @@ static int acpi_ac_state_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_ac_read_state, PDE(inode)->data);
}
-static struct file_operations acpi_ac_state_fops = {
+static const struct file_operations acpi_ac_state_fops = {
.open = acpi_ac_state_open_fs,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index c54d7b6c4066..20c23c049207 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -11,6 +11,8 @@
#include <acpi/acpi_drivers.h>
+#include "internal.h"
+
#define _COMPONENT ACPI_BUS_COMPONENT
ACPI_MODULE_NAME("scan");
#define STRUCT_TO_INT(s) (*((int*)&s))
@@ -357,6 +359,61 @@ static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0;
}
+static void acpi_device_notify(acpi_handle handle, u32 event, void *data)
+{
+ struct acpi_device *device = data;
+
+ device->driver->ops.notify(device, event);
+}
+
+static acpi_status acpi_device_notify_fixed(void *data)
+{
+ struct acpi_device *device = data;
+
+ acpi_device_notify(device->handle, ACPI_FIXED_HARDWARE_EVENT, device);
+ return AE_OK;
+}
+
+static int acpi_device_install_notify_handler(struct acpi_device *device)
+{
+ acpi_status status;
+ char *hid;
+
+ hid = acpi_device_hid(device);
+ if (!strcmp(hid, ACPI_BUTTON_HID_POWERF))
+ status =
+ acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+ acpi_device_notify_fixed,
+ device);
+ else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEPF))
+ status =
+ acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+ acpi_device_notify_fixed,
+ device);
+ else
+ status = acpi_install_notify_handler(device->handle,
+ ACPI_DEVICE_NOTIFY,
+ acpi_device_notify,
+ device);
+
+ if (ACPI_FAILURE(status))
+ return -EINVAL;
+ return 0;
+}
+
+static void acpi_device_remove_notify_handler(struct acpi_device *device)
+{
+ if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF))
+ acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+ acpi_device_notify_fixed);
+ else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF))
+ acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+ acpi_device_notify_fixed);
+ else
+ acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+ acpi_device_notify);
+}
+
static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
static int acpi_start_single_object(struct acpi_device *);
static int acpi_device_probe(struct device * dev)
@@ -369,6 +426,20 @@ static int acpi_device_probe(struct device * dev)
if (!ret) {
if (acpi_dev->bus_ops.acpi_op_start)
acpi_start_single_object(acpi_dev);
+
+ if (acpi_drv->ops.notify) {
+ ret = acpi_device_install_notify_handler(acpi_dev);
+ if (ret) {
+ if (acpi_drv->ops.stop)
+ acpi_drv->ops.stop(acpi_dev,
+ acpi_dev->removal_type);
+ if (acpi_drv->ops.remove)
+ acpi_drv->ops.remove(acpi_dev,
+ acpi_dev->removal_type);
+ return ret;
+ }
+ }
+
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Found driver [%s] for device [%s]\n",
acpi_drv->name, acpi_dev->pnp.bus_id));
@@ -383,6 +454,8 @@ static int acpi_device_remove(struct device * dev)
struct acpi_driver *acpi_drv = acpi_dev->driver;
if (acpi_drv) {
+ if (acpi_drv->ops.notify)
+ acpi_device_remove_notify_handler(acpi_dev);
if (acpi_drv->ops.stop)
acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type);
if (acpi_drv->ops.remove)
@@ -395,22 +468,10 @@ static int acpi_device_remove(struct device * dev)
return 0;
}
-static void acpi_device_shutdown(struct device *dev)
-{
- struct acpi_device *acpi_dev = to_acpi_device(dev);
- struct acpi_driver *acpi_drv = acpi_dev->driver;
-
- if (acpi_drv && acpi_drv->ops.shutdown)
- acpi_drv->ops.shutdown(acpi_dev);
-
- return ;
-}
-
struct bus_type acpi_bus_type = {
.name = "acpi",
.suspend = acpi_device_suspend,
.resume = acpi_device_resume,
- .shutdown = acpi_device_shutdown,
.match = acpi_bus_match,
.probe = acpi_device_probe,
.remove = acpi_device_remove,
@@ -1524,16 +1585,11 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
return result;
}
-
-static int __init acpi_scan_init(void)
+int __init acpi_scan_init(void)
{
int result;
struct acpi_bus_ops ops;
-
- if (acpi_disabled)
- return 0;
-
memset(&ops, 0, sizeof(ops));
ops.acpi_op_add = 1;
ops.acpi_op_start = 1;
@@ -1566,5 +1622,3 @@ static int __init acpi_scan_init(void)
Done:
return result;
}
-
-subsys_initcall(acpi_scan_init);
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 00456fccfa38..779e4e500df4 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -21,6 +21,8 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
+
+#include "internal.h"
#include "sleep.h"
u8 sleep_states[ACPI_S_STATE_COUNT];
@@ -248,7 +250,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
/* If ACPI is not enabled by the BIOS, we need to enable it here. */
if (set_sci_en_on_resume)
- acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1);
+ acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
else
acpi_enable();
@@ -394,6 +396,15 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"),
},
},
+ {
+ .callback = init_old_suspend_ordering,
+ .ident = "Panasonic CF51-2L",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR,
+ "Matsushita Electric Industrial Co.,Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
+ },
+ },
{},
};
#endif /* CONFIG_SUSPEND */
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 391d0358a592..da51f05ef8d8 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -33,10 +33,6 @@
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("system");
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
#define ACPI_SYSTEM_CLASS "system"
#define ACPI_SYSTEM_DEVICE_NAME "System"
@@ -62,6 +58,7 @@ module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
-------------------------------------------------------------------------- */
static LIST_HEAD(acpi_table_attr_list);
static struct kobject *tables_kobj;
+static struct kobject *dynamic_tables_kobj;
struct acpi_table_attr {
struct bin_attribute attr;
@@ -128,6 +125,40 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
return;
}
+static acpi_status
+acpi_sysfs_table_handler(u32 event, void *table, void *context)
+{
+ struct acpi_table_attr *table_attr;
+
+ switch (event) {
+ case ACPI_TABLE_EVENT_LOAD:
+ table_attr =
+ kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
+ if (!table_attr)
+ return AE_NO_MEMORY;
+
+ acpi_table_attr_init(table_attr, table);
+ if (sysfs_create_bin_file(dynamic_tables_kobj,
+ &table_attr->attr)) {
+ kfree(table_attr);
+ return AE_ERROR;
+ } else
+ list_add_tail(&table_attr->node,
+ &acpi_table_attr_list);
+ break;
+ case ACPI_TABLE_EVENT_UNLOAD:
+ /*
+ * we do not need to do anything right now
+ * because the table is not deleted from the
+ * global table list when unloading it.
+ */
+ break;
+ default:
+ return AE_BAD_PARAMETER;
+ }
+ return AE_OK;
+}
+
static int acpi_system_sysfs_init(void)
{
struct acpi_table_attr *table_attr;
@@ -137,7 +168,11 @@ static int acpi_system_sysfs_init(void)
tables_kobj = kobject_create_and_add("tables", acpi_kobj);
if (!tables_kobj)
- return -ENOMEM;
+ goto err;
+
+ dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj);
+ if (!dynamic_tables_kobj)
+ goto err_dynamic_tables;
do {
result = acpi_get_table_by_index(table_index, &table_header);
@@ -162,8 +197,14 @@ static int acpi_system_sysfs_init(void)
}
} while (!result);
kobject_uevent(tables_kobj, KOBJ_ADD);
-
- return 0;
+ kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
+ result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
+
+ return result == AE_OK ? 0 : -EINVAL;
+err_dynamic_tables:
+ kobject_put(tables_kobj);
+err:
+ return -ENOMEM;
}
/*
@@ -571,12 +612,9 @@ static int acpi_system_procfs_init(void)
}
#endif
-static int __init acpi_system_init(void)
+int __init acpi_system_init(void)
{
- int result = 0;
-
- if (acpi_disabled)
- return 0;
+ int result;
result = acpi_system_procfs_init();
if (result)
@@ -586,5 +624,3 @@ static int __init acpi_system_init(void)
return result;
}
-
-subsys_initcall(acpi_system_init);
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index fec1ae36d431..646d39c031ca 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -62,6 +62,18 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
}
break;
+ case ACPI_MADT_TYPE_LOCAL_X2APIC:
+ {
+ struct acpi_madt_local_x2apic *p =
+ (struct acpi_madt_local_x2apic *)header;
+ printk(KERN_INFO PREFIX
+ "X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n",
+ p->local_apic_id, p->uid,
+ (p->lapic_flags & ACPI_MADT_ENABLED) ?
+ "enabled" : "disabled");
+ }
+ break;
+
case ACPI_MADT_TYPE_IO_APIC:
{
struct acpi_madt_io_apic *p =
@@ -116,6 +128,24 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
}
break;
+ case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
+ {
+ u16 polarity, trigger;
+ struct acpi_madt_local_x2apic_nmi *p =
+ (struct acpi_madt_local_x2apic_nmi *)header;
+
+ polarity = p->inti_flags & ACPI_MADT_POLARITY_MASK;
+ trigger = (p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2;
+
+ printk(KERN_INFO PREFIX
+ "X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n",
+ p->uid,
+ mps_inti_flags_polarity[polarity],
+ mps_inti_flags_trigger[trigger],
+ p->lint);
+ }
+ break;
+
case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
{
struct acpi_madt_local_apic_override *p =
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 99e6f1f8ea45..e8c143caf0fd 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -37,11 +37,11 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
-#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/kmod.h>
#include <linux/seq_file.h>
#include <linux/reboot.h>
+#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/thermal.h>
#include <acpi/acpi_bus.h>
@@ -190,7 +190,6 @@ struct acpi_thermal {
struct acpi_thermal_state state;
struct acpi_thermal_trips trips;
struct acpi_handle_list devices;
- struct timer_list timer;
struct thermal_zone_device *thermal_zone;
int tz_enabled;
struct mutex lock;
@@ -290,6 +289,11 @@ static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */
+ tz->thermal_zone->polling_delay = seconds * 1000;
+
+ if (tz->tz_enabled)
+ thermal_zone_device_update(tz->thermal_zone);
+
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Polling frequency set to %lu seconds\n",
tz->polling_frequency/10));
@@ -367,7 +371,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
/*
* Treat freezing temperatures as invalid as well; some
* BIOSes return really low values and cause reboots at startup.
- * Below zero (Celcius) values clearly aren't right for sure..
+ * Below zero (Celsius) values clearly aren't right for sure..
* ... so lets discard those as invalid.
*/
if (ACPI_FAILURE(status) ||
@@ -569,392 +573,18 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
}
-static int acpi_thermal_critical(struct acpi_thermal *tz)
-{
- if (!tz || !tz->trips.critical.flags.valid)
- return -EINVAL;
-
- if (tz->temperature >= tz->trips.critical.temperature) {
- printk(KERN_WARNING PREFIX "Critical trip point\n");
- tz->trips.critical.flags.enabled = 1;
- } else if (tz->trips.critical.flags.enabled)
- tz->trips.critical.flags.enabled = 0;
-
- acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
- tz->trips.critical.flags.enabled);
- acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
- dev_name(&tz->device->dev),
- ACPI_THERMAL_NOTIFY_CRITICAL,
- tz->trips.critical.flags.enabled);
-
- /* take no action if nocrt is set */
- if(!nocrt) {
- printk(KERN_EMERG
- "Critical temperature reached (%ld C), shutting down.\n",
- KELVIN_TO_CELSIUS(tz->temperature));
- orderly_poweroff(true);
- }
-
- return 0;
-}
-
-static int acpi_thermal_hot(struct acpi_thermal *tz)
-{
- if (!tz || !tz->trips.hot.flags.valid)
- return -EINVAL;
-
- if (tz->temperature >= tz->trips.hot.temperature) {
- printk(KERN_WARNING PREFIX "Hot trip point\n");
- tz->trips.hot.flags.enabled = 1;
- } else if (tz->trips.hot.flags.enabled)
- tz->trips.hot.flags.enabled = 0;
-
- acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
- tz->trips.hot.flags.enabled);
- acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
- dev_name(&tz->device->dev),
- ACPI_THERMAL_NOTIFY_HOT,
- tz->trips.hot.flags.enabled);
-
- /* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */
-
- return 0;
-}
-
-static void acpi_thermal_passive(struct acpi_thermal *tz)
-{
- int result = 1;
- struct acpi_thermal_passive *passive = NULL;
- int trend = 0;
- int i = 0;
-
-
- if (!tz || !tz->trips.passive.flags.valid)
- return;
-
- passive = &(tz->trips.passive);
-
- /*
- * Above Trip?
- * -----------
- * Calculate the thermal trend (using the passive cooling equation)
- * and modify the performance limit for all passive cooling devices
- * accordingly. Note that we assume symmetry.
- */
- if (tz->temperature >= passive->temperature) {
- trend =
- (passive->tc1 * (tz->temperature - tz->last_temperature)) +
- (passive->tc2 * (tz->temperature - passive->temperature));
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n",
- trend, passive->tc1, tz->temperature,
- tz->last_temperature, passive->tc2,
- tz->temperature, passive->temperature));
- passive->flags.enabled = 1;
- /* Heating up? */
- if (trend > 0)
- for (i = 0; i < passive->devices.count; i++)
- acpi_processor_set_thermal_limit(passive->
- devices.
- handles[i],
- ACPI_PROCESSOR_LIMIT_INCREMENT);
- /* Cooling off? */
- else if (trend < 0) {
- for (i = 0; i < passive->devices.count; i++)
- /*
- * assume that we are on highest
- * freq/lowest thrott and can leave
- * passive mode, even in error case
- */
- if (!acpi_processor_set_thermal_limit
- (passive->devices.handles[i],
- ACPI_PROCESSOR_LIMIT_DECREMENT))
- result = 0;
- /*
- * Leave cooling mode, even if the temp might
- * higher than trip point This is because some
- * machines might have long thermal polling
- * frequencies (tsp) defined. We will fall back
- * into passive mode in next cycle (probably quicker)
- */
- if (result) {
- passive->flags.enabled = 0;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Disabling passive cooling, still above threshold,"
- " but we are cooling down\n"));
- }
- }
- return;
- }
-
- /*
- * Below Trip?
- * -----------
- * Implement passive cooling hysteresis to slowly increase performance
- * and avoid thrashing around the passive trip point. Note that we
- * assume symmetry.
- */
- if (!passive->flags.enabled)
- return;
- for (i = 0; i < passive->devices.count; i++)
- if (!acpi_processor_set_thermal_limit
- (passive->devices.handles[i],
- ACPI_PROCESSOR_LIMIT_DECREMENT))
- result = 0;
- if (result) {
- passive->flags.enabled = 0;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Disabling passive cooling (zone is cool)\n"));
- }
-}
-
-static void acpi_thermal_active(struct acpi_thermal *tz)
-{
- int result = 0;
- struct acpi_thermal_active *active = NULL;
- int i = 0;
- int j = 0;
- unsigned long maxtemp = 0;
-
-
- if (!tz)
- return;
-
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
- active = &(tz->trips.active[i]);
- if (!active || !active->flags.valid)
- break;
- if (tz->temperature >= active->temperature) {
- /*
- * Above Threshold?
- * ----------------
- * If not already enabled, turn ON all cooling devices
- * associated with this active threshold.
- */
- if (active->temperature > maxtemp)
- tz->state.active_index = i;
- maxtemp = active->temperature;
- if (active->flags.enabled)
- continue;
- for (j = 0; j < active->devices.count; j++) {
- result =
- acpi_bus_set_power(active->devices.
- handles[j],
- ACPI_STATE_D0);
- if (result) {
- printk(KERN_WARNING PREFIX
- "Unable to turn cooling device [%p] 'on'\n",
- active->devices.
- handles[j]);
- continue;
- }
- active->flags.enabled = 1;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Cooling device [%p] now 'on'\n",
- active->devices.handles[j]));
- }
- continue;
- }
- if (!active->flags.enabled)
- continue;
- /*
- * Below Threshold?
- * ----------------
- * Turn OFF all cooling devices associated with this
- * threshold.
- */
- for (j = 0; j < active->devices.count; j++) {
- result = acpi_bus_set_power(active->devices.handles[j],
- ACPI_STATE_D3);
- if (result) {
- printk(KERN_WARNING PREFIX
- "Unable to turn cooling device [%p] 'off'\n",
- active->devices.handles[j]);
- continue;
- }
- active->flags.enabled = 0;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Cooling device [%p] now 'off'\n",
- active->devices.handles[j]));
- }
- }
-}
-
-static void acpi_thermal_check(void *context);
-
-static void acpi_thermal_run(unsigned long data)
-{
- struct acpi_thermal *tz = (struct acpi_thermal *)data;
- if (!tz->zombie)
- acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data);
-}
-
-static void acpi_thermal_active_off(void *data)
-{
- int result = 0;
- struct acpi_thermal *tz = data;
- int i = 0;
- int j = 0;
- struct acpi_thermal_active *active = NULL;
-
- if (!tz) {
- printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
- return;
- }
-
- result = acpi_thermal_get_temperature(tz);
- if (result)
- return;
-
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
- active = &(tz->trips.active[i]);
- if (!active || !active->flags.valid)
- break;
- if (tz->temperature >= active->temperature) {
- /*
- * If the thermal temperature is greater than the
- * active threshod, unnecessary to turn off the
- * the active cooling device.
- */
- continue;
- }
- /*
- * Below Threshold?
- * ----------------
- * Turn OFF all cooling devices associated with this
- * threshold.
- */
- for (j = 0; j < active->devices.count; j++)
- result = acpi_bus_set_power(active->devices.handles[j],
- ACPI_STATE_D3);
- }
-}
-
static void acpi_thermal_check(void *data)
{
- int result = 0;
struct acpi_thermal *tz = data;
- unsigned long sleep_time = 0;
- unsigned long timeout_jiffies = 0;
- int i = 0;
- struct acpi_thermal_state state;
-
-
- if (!tz) {
- printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
- return;
- }
-
- /* Check if someone else is already running */
- if (!mutex_trylock(&tz->lock))
- return;
-
- state = tz->state;
-
- result = acpi_thermal_get_temperature(tz);
- if (result)
- goto unlock;
-
- if (!tz->tz_enabled)
- goto unlock;
-
- memset(&tz->state, 0, sizeof(tz->state));
-
- /*
- * Check Trip Points
- * -----------------
- * Compare the current temperature to the trip point values to see
- * if we've entered one of the thermal policy states. Note that
- * this function determines when a state is entered, but the
- * individual policy decides when it is exited (e.g. hysteresis).
- */
- if (tz->trips.critical.flags.valid)
- state.critical |=
- (tz->temperature >= tz->trips.critical.temperature);
- if (tz->trips.hot.flags.valid)
- state.hot |= (tz->temperature >= tz->trips.hot.temperature);
- if (tz->trips.passive.flags.valid)
- state.passive |=
- (tz->temperature >= tz->trips.passive.temperature);
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
- if (tz->trips.active[i].flags.valid)
- state.active |=
- (tz->temperature >=
- tz->trips.active[i].temperature);
-
- /*
- * Invoke Policy
- * -------------
- * Separated from the above check to allow individual policy to
- * determine when to exit a given state.
- */
- if (state.critical)
- acpi_thermal_critical(tz);
- if (state.hot)
- acpi_thermal_hot(tz);
- if (state.passive)
- acpi_thermal_passive(tz);
- if (state.active)
- acpi_thermal_active(tz);
-
- /*
- * Calculate State
- * ---------------
- * Again, separated from the above two to allow independent policy
- * decisions.
- */
- tz->state.critical = tz->trips.critical.flags.enabled;
- tz->state.hot = tz->trips.hot.flags.enabled;
- tz->state.passive = tz->trips.passive.flags.enabled;
- tz->state.active = 0;
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
- tz->state.active |= tz->trips.active[i].flags.enabled;
-
- /*
- * Calculate Sleep Time
- * --------------------
- * If we're in the passive state, use _TSP's value. Otherwise
- * use the default polling frequency (e.g. _TZP). If no polling
- * frequency is specified then we'll wait forever (at least until
- * a thermal event occurs). Note that _TSP and _TZD values are
- * given in 1/10th seconds (we must covert to milliseconds).
- */
- if (tz->state.passive) {
- sleep_time = tz->trips.passive.tsp * 100;
- timeout_jiffies = jiffies + (HZ * sleep_time) / 1000;
- } else if (tz->polling_frequency > 0) {
- sleep_time = tz->polling_frequency * 100;
- timeout_jiffies = round_jiffies(jiffies + (HZ * sleep_time) / 1000);
- }
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
- tz->name, tz->temperature, sleep_time));
-
- /*
- * Schedule Next Poll
- * ------------------
- */
- if (!sleep_time) {
- if (timer_pending(&(tz->timer)))
- del_timer(&(tz->timer));
- } else {
- if (timer_pending(&(tz->timer)))
- mod_timer(&(tz->timer), timeout_jiffies);
- else {
- tz->timer.data = (unsigned long)tz;
- tz->timer.function = acpi_thermal_run;
- tz->timer.expires = timeout_jiffies;
- add_timer(&(tz->timer));
- }
- }
- unlock:
- mutex_unlock(&tz->lock);
+ thermal_zone_device_update(tz->thermal_zone);
}
/* sys I/F for generic thermal sysfs support */
#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
-static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
+static int thermal_get_temp(struct thermal_zone_device *thermal,
+ unsigned long *temp)
{
struct acpi_thermal *tz = thermal->devdata;
int result;
@@ -966,25 +596,28 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
if (result)
return result;
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
+ *temp = KELVIN_TO_MILLICELSIUS(tz->temperature);
+ return 0;
}
static const char enabled[] = "kernel";
static const char disabled[] = "user";
static int thermal_get_mode(struct thermal_zone_device *thermal,
- char *buf)
+ enum thermal_device_mode *mode)
{
struct acpi_thermal *tz = thermal->devdata;
if (!tz)
return -EINVAL;
- return sprintf(buf, "%s\n", tz->tz_enabled ?
- enabled : disabled);
+ *mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED :
+ THERMAL_DEVICE_DISABLED;
+
+ return 0;
}
static int thermal_set_mode(struct thermal_zone_device *thermal,
- const char *buf)
+ enum thermal_device_mode mode)
{
struct acpi_thermal *tz = thermal->devdata;
int enable;
@@ -995,9 +628,9 @@ static int thermal_set_mode(struct thermal_zone_device *thermal,
/*
* enable/disable thermal management from ACPI thermal driver
*/
- if (!strncmp(buf, enabled, sizeof enabled - 1))
+ if (mode == THERMAL_DEVICE_ENABLED)
enable = 1;
- else if (!strncmp(buf, disabled, sizeof disabled - 1))
+ else if (mode == THERMAL_DEVICE_DISABLED)
enable = 0;
else
return -EINVAL;
@@ -1013,7 +646,7 @@ static int thermal_set_mode(struct thermal_zone_device *thermal,
}
static int thermal_get_trip_type(struct thermal_zone_device *thermal,
- int trip, char *buf)
+ int trip, enum thermal_trip_type *type)
{
struct acpi_thermal *tz = thermal->devdata;
int i;
@@ -1022,27 +655,35 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal,
return -EINVAL;
if (tz->trips.critical.flags.valid) {
- if (!trip)
- return sprintf(buf, "critical\n");
+ if (!trip) {
+ *type = THERMAL_TRIP_CRITICAL;
+ return 0;
+ }
trip--;
}
if (tz->trips.hot.flags.valid) {
- if (!trip)
- return sprintf(buf, "hot\n");
+ if (!trip) {
+ *type = THERMAL_TRIP_HOT;
+ return 0;
+ }
trip--;
}
if (tz->trips.passive.flags.valid) {
- if (!trip)
- return sprintf(buf, "passive\n");
+ if (!trip) {
+ *type = THERMAL_TRIP_PASSIVE;
+ return 0;
+ }
trip--;
}
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
tz->trips.active[i].flags.valid; i++) {
- if (!trip)
- return sprintf(buf, "active%d\n", i);
+ if (!trip) {
+ *type = THERMAL_TRIP_ACTIVE;
+ return 0;
+ }
trip--;
}
@@ -1050,7 +691,7 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal,
}
static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
- int trip, char *buf)
+ int trip, unsigned long *temp)
{
struct acpi_thermal *tz = thermal->devdata;
int i;
@@ -1059,31 +700,39 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
return -EINVAL;
if (tz->trips.critical.flags.valid) {
- if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
- tz->trips.critical.temperature));
+ if (!trip) {
+ *temp = KELVIN_TO_MILLICELSIUS(
+ tz->trips.critical.temperature);
+ return 0;
+ }
trip--;
}
if (tz->trips.hot.flags.valid) {
- if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
- tz->trips.hot.temperature));
+ if (!trip) {
+ *temp = KELVIN_TO_MILLICELSIUS(
+ tz->trips.hot.temperature);
+ return 0;
+ }
trip--;
}
if (tz->trips.passive.flags.valid) {
- if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
- tz->trips.passive.temperature));
+ if (!trip) {
+ *temp = KELVIN_TO_MILLICELSIUS(
+ tz->trips.passive.temperature);
+ return 0;
+ }
trip--;
}
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
tz->trips.active[i].flags.valid; i++) {
- if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
- tz->trips.active[i].temperature));
+ if (!trip) {
+ *temp = KELVIN_TO_MILLICELSIUS(
+ tz->trips.active[i].temperature);
+ return 0;
+ }
trip--;
}
@@ -1102,6 +751,29 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
return -EINVAL;
}
+static int thermal_notify(struct thermal_zone_device *thermal, int trip,
+ enum thermal_trip_type trip_type)
+{
+ u8 type = 0;
+ struct acpi_thermal *tz = thermal->devdata;
+
+ if (trip_type == THERMAL_TRIP_CRITICAL)
+ type = ACPI_THERMAL_NOTIFY_CRITICAL;
+ else if (trip_type == THERMAL_TRIP_HOT)
+ type = ACPI_THERMAL_NOTIFY_HOT;
+ else
+ return 0;
+
+ acpi_bus_generate_proc_event(tz->device, type, 1);
+ acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
+ dev_name(&tz->device->dev), type, 1);
+
+ if (trip_type == THERMAL_TRIP_CRITICAL && nocrt)
+ return 1;
+
+ return 0;
+}
+
typedef int (*cb)(struct thermal_zone_device *, int,
struct thermal_cooling_device *);
static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
@@ -1194,6 +866,7 @@ static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
.get_trip_type = thermal_get_trip_type,
.get_trip_temp = thermal_get_trip_temp,
.get_crit_temp = thermal_get_crit_temp,
+ .notify = thermal_notify,
};
static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
@@ -1214,8 +887,21 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
tz->trips.active[i].flags.valid; i++, trips++);
- tz->thermal_zone = thermal_zone_device_register("acpitz",
- trips, tz, &acpi_thermal_zone_ops);
+
+ if (tz->trips.passive.flags.valid)
+ tz->thermal_zone =
+ thermal_zone_device_register("acpitz", trips, tz,
+ &acpi_thermal_zone_ops,
+ tz->trips.passive.tc1,
+ tz->trips.passive.tc2,
+ tz->trips.passive.tsp*100,
+ tz->polling_frequency*100);
+ else
+ tz->thermal_zone =
+ thermal_zone_device_register("acpitz", trips, tz,
+ &acpi_thermal_zone_ops,
+ 0, 0, 0,
+ tz->polling_frequency);
if (IS_ERR(tz->thermal_zone))
return -ENODEV;
@@ -1447,13 +1133,13 @@ static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
if (!tz)
goto end;
- if (!tz->polling_frequency) {
+ if (!tz->thermal_zone->polling_delay) {
seq_puts(seq, "<polling disabled>\n");
goto end;
}
- seq_printf(seq, "polling frequency: %lu seconds\n",
- (tz->polling_frequency / 10));
+ seq_printf(seq, "polling frequency: %d seconds\n",
+ (tz->thermal_zone->polling_delay / 1000));
end:
return 0;
@@ -1506,7 +1192,6 @@ static int acpi_thermal_add_fs(struct acpi_device *device)
acpi_thermal_dir);
if (!acpi_device_dir(device))
return -ENODEV;
- acpi_device_dir(device)->owner = THIS_MODULE;
}
/* 'state' [R] */
@@ -1683,12 +1368,6 @@ static int acpi_thermal_add(struct acpi_device *device)
if (result)
goto unregister_thermal_zone;
- init_timer(&tz->timer);
-
- acpi_thermal_active_off(tz);
-
- acpi_thermal_check(tz);
-
status = acpi_install_notify_handler(device->handle,
ACPI_DEVICE_NOTIFY,
acpi_thermal_notify, tz);
@@ -1717,36 +1396,15 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
acpi_status status = AE_OK;
struct acpi_thermal *tz = NULL;
-
if (!device || !acpi_driver_data(device))
return -EINVAL;
tz = acpi_driver_data(device);
- /* avoid timer adding new defer task */
- tz->zombie = 1;
- /* wait for running timer (on other CPUs) finish */
- del_timer_sync(&(tz->timer));
- /* synchronize deferred task */
- acpi_os_wait_events_complete(NULL);
- /* deferred task may reinsert timer */
- del_timer_sync(&(tz->timer));
-
status = acpi_remove_notify_handler(device->handle,
ACPI_DEVICE_NOTIFY,
acpi_thermal_notify);
- /* Terminate policy */
- if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {
- tz->trips.passive.flags.enabled = 0;
- acpi_thermal_passive(tz);
- }
- if (tz->trips.active[0].flags.valid
- && tz->trips.active[0].flags.enabled) {
- tz->trips.active[0].flags.enabled = 0;
- acpi_thermal_active(tz);
- }
-
acpi_thermal_remove_fs(device);
acpi_thermal_unregister_thermal_zone(tz);
mutex_destroy(&tz->lock);
@@ -1875,7 +1533,6 @@ static int __init acpi_thermal_init(void)
acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
if (!acpi_thermal_dir)
return -ENODEV;
- acpi_thermal_dir->owner = THIS_MODULE;
result = acpi_bus_register_driver(&acpi_thermal_driver);
if (result < 0) {
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index bb5ed059114a..ab06143672bc 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -37,6 +37,8 @@
#include <linux/thermal.h>
#include <linux/video_output.h>
#include <linux/sort.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
#include <asm/uaccess.h>
#include <acpi/acpi_bus.h>
@@ -162,16 +164,26 @@ struct acpi_video_device_cap {
u8 _BCL:1; /*Query list of brightness control levels supported */
u8 _BCM:1; /*Set the brightness level */
u8 _BQC:1; /* Get current brightness level */
+ u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */
u8 _DDC:1; /*Return the EDID for this device */
u8 _DCS:1; /*Return status of output device */
u8 _DGS:1; /*Query graphics state */
u8 _DSS:1; /*Device state set */
};
+struct acpi_video_brightness_flags {
+ u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */
+ u8 _BCL_reversed:1; /* _BCL package is in a reversed order*/
+ u8 _BCL_use_index:1; /* levels in _BCL are index values */
+ u8 _BCM_use_index:1; /* input of _BCM is an index value */
+ u8 _BQC_use_index:1; /* _BQC returns an index value */
+};
+
struct acpi_video_device_brightness {
int curr;
int count;
int *levels;
+ struct acpi_video_brightness_flags flags;
};
struct acpi_video_device {
@@ -189,7 +201,7 @@ struct acpi_video_device {
/* bus */
static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_info_fops = {
+static const struct file_operations acpi_video_bus_info_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_info_open_fs,
.read = seq_read,
@@ -198,7 +210,7 @@ static struct file_operations acpi_video_bus_info_fops = {
};
static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_ROM_fops = {
+static const struct file_operations acpi_video_bus_ROM_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_ROM_open_fs,
.read = seq_read,
@@ -208,7 +220,7 @@ static struct file_operations acpi_video_bus_ROM_fops = {
static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
struct file *file);
-static struct file_operations acpi_video_bus_POST_info_fops = {
+static const struct file_operations acpi_video_bus_POST_info_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_POST_info_open_fs,
.read = seq_read,
@@ -217,19 +229,25 @@ static struct file_operations acpi_video_bus_POST_info_fops = {
};
static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_POST_fops = {
+static ssize_t acpi_video_bus_write_POST(struct file *file,
+ const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_bus_POST_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_POST_open_fs,
.read = seq_read,
+ .write = acpi_video_bus_write_POST,
.llseek = seq_lseek,
.release = single_release,
};
static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_DOS_fops = {
+static ssize_t acpi_video_bus_write_DOS(struct file *file,
+ const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_bus_DOS_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_DOS_open_fs,
.read = seq_read,
+ .write = acpi_video_bus_write_DOS,
.llseek = seq_lseek,
.release = single_release,
};
@@ -237,7 +255,7 @@ static struct file_operations acpi_video_bus_DOS_fops = {
/* device */
static int acpi_video_device_info_open_fs(struct inode *inode,
struct file *file);
-static struct file_operations acpi_video_device_info_fops = {
+static const struct file_operations acpi_video_device_info_fops = {
.owner = THIS_MODULE,
.open = acpi_video_device_info_open_fs,
.read = seq_read,
@@ -247,27 +265,33 @@ static struct file_operations acpi_video_device_info_fops = {
static int acpi_video_device_state_open_fs(struct inode *inode,
struct file *file);
-static struct file_operations acpi_video_device_state_fops = {
+static ssize_t acpi_video_device_write_state(struct file *file,
+ const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_device_state_fops = {
.owner = THIS_MODULE,
.open = acpi_video_device_state_open_fs,
.read = seq_read,
+ .write = acpi_video_device_write_state,
.llseek = seq_lseek,
.release = single_release,
};
static int acpi_video_device_brightness_open_fs(struct inode *inode,
struct file *file);
+static ssize_t acpi_video_device_write_brightness(struct file *file,
+ const char __user *buffer, size_t count, loff_t *data);
static struct file_operations acpi_video_device_brightness_fops = {
.owner = THIS_MODULE,
.open = acpi_video_device_brightness_open_fs,
.read = seq_read,
+ .write = acpi_video_device_write_brightness,
.llseek = seq_lseek,
.release = single_release,
};
static int acpi_video_device_EDID_open_fs(struct inode *inode,
struct file *file);
-static struct file_operations acpi_video_device_EDID_fops = {
+static const struct file_operations acpi_video_device_EDID_fops = {
.owner = THIS_MODULE,
.open = acpi_video_device_EDID_open_fs,
.read = seq_read,
@@ -275,7 +299,7 @@ static struct file_operations acpi_video_device_EDID_fops = {
.release = single_release,
};
-static char device_decode[][30] = {
+static const char device_decode[][30] = {
"motherboard VGA device",
"PCI VGA device",
"AGP VGA device",
@@ -294,7 +318,7 @@ static int acpi_video_device_lcd_get_level_current(
unsigned long long *level);
static int acpi_video_get_next_level(struct acpi_video_device *device,
u32 level_current, u32 event);
-static void acpi_video_switch_brightness(struct acpi_video_device *device,
+static int acpi_video_switch_brightness(struct acpi_video_device *device,
int event);
static int acpi_video_device_get_state(struct acpi_video_device *device,
unsigned long long *state);
@@ -308,7 +332,9 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
int i;
struct acpi_video_device *vd =
(struct acpi_video_device *)bl_get_data(bd);
- acpi_video_device_lcd_get_level_current(vd, &cur_level);
+
+ if (acpi_video_device_lcd_get_level_current(vd, &cur_level))
+ return -EINVAL;
for (i = 2; i < vd->brightness->count; i++) {
if (vd->brightness->levels[i] == cur_level)
/* The first two entries are special - see page 575
@@ -320,12 +346,12 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
static int acpi_video_set_brightness(struct backlight_device *bd)
{
- int request_level = bd->props.brightness+2;
+ int request_level = bd->props.brightness + 2;
struct acpi_video_device *vd =
(struct acpi_video_device *)bl_get_data(bd);
- acpi_video_device_lcd_set_level(vd,
- vd->brightness->levels[request_level]);
- return 0;
+
+ return acpi_video_device_lcd_set_level(vd,
+ vd->brightness->levels[request_level]);
}
static struct backlight_ops acpi_backlight_ops = {
@@ -358,32 +384,37 @@ static struct output_properties acpi_output_properties = {
/* thermal cooling device callbacks */
-static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned
+ long *state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_video_device *video = acpi_driver_data(device);
- return sprintf(buf, "%d\n", video->brightness->count - 3);
+ *state = video->brightness->count - 3;
+ return 0;
}
-static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned
+ long *state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_video_device *video = acpi_driver_data(device);
unsigned long long level;
- int state;
+ int offset;
- acpi_video_device_lcd_get_level_current(video, &level);
- for (state = 2; state < video->brightness->count; state++)
- if (level == video->brightness->levels[state])
- return sprintf(buf, "%d\n",
- video->brightness->count - state - 1);
+ if (acpi_video_device_lcd_get_level_current(video, &level))
+ return -EINVAL;
+ for (offset = 2; offset < video->brightness->count; offset++)
+ if (level == video->brightness->levels[offset]) {
+ *state = video->brightness->count - offset - 1;
+ return 0;
+ }
return -EINVAL;
}
static int
-video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_video_device *video = acpi_driver_data(device);
@@ -479,34 +510,68 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
static int
acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
{
- int status = AE_OK;
+ int status;
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list args = { 1, &arg0 };
int state;
-
arg0.integer.value = level;
- if (device->cap._BCM)
- status = acpi_evaluate_object(device->dev->handle, "_BCM",
- &args, NULL);
+ status = acpi_evaluate_object(device->dev->handle, "_BCM",
+ &args, NULL);
+ if (ACPI_FAILURE(status)) {
+ ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
+ return -EIO;
+ }
+
device->brightness->curr = level;
for (state = 2; state < device->brightness->count; state++)
- if (level == device->brightness->levels[state])
- device->backlight->props.brightness = state - 2;
+ if (level == device->brightness->levels[state]) {
+ if (device->backlight)
+ device->backlight->props.brightness = state - 2;
+ return 0;
+ }
- return status;
+ ACPI_ERROR((AE_INFO, "Current brightness invalid"));
+ return -EINVAL;
}
static int
acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
unsigned long long *level)
{
- if (device->cap._BQC)
- return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
- level);
+ acpi_status status = AE_OK;
+
+ if (device->cap._BQC || device->cap._BCQ) {
+ char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
+
+ status = acpi_evaluate_integer(device->dev->handle, buf,
+ NULL, level);
+ if (ACPI_SUCCESS(status)) {
+ if (device->brightness->flags._BQC_use_index) {
+ if (device->brightness->flags._BCL_reversed)
+ *level = device->brightness->count
+ - 3 - (*level);
+ *level = device->brightness->levels[*level + 2];
+
+ }
+ device->brightness->curr = *level;
+ return 0;
+ } else {
+ /* Fixme:
+ * should we return an error or ignore this failure?
+ * dev->brightness->curr is a cached value which stores
+ * the correct current backlight level in most cases.
+ * ACPI video backlight still works w/ buggy _BQC.
+ * http://bugzilla.kernel.org/show_bug.cgi?id=12233
+ */
+ ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf));
+ device->cap._BQC = device->cap._BCQ = 0;
+ }
+ }
+
*level = device->brightness->curr;
- return AE_OK;
+ return 0;
}
static int
@@ -655,9 +720,11 @@ static int
acpi_video_init_brightness(struct acpi_video_device *device)
{
union acpi_object *obj = NULL;
- int i, max_level = 0, count = 0;
+ int i, max_level = 0, count = 0, level_ac_battery = 0;
+ unsigned long long level, level_old;
union acpi_object *o;
struct acpi_video_device_brightness *br = NULL;
+ int result = -EINVAL;
if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
@@ -671,13 +738,16 @@ acpi_video_init_brightness(struct acpi_video_device *device)
br = kzalloc(sizeof(*br), GFP_KERNEL);
if (!br) {
printk(KERN_ERR "can't allocate memory\n");
+ result = -ENOMEM;
goto out;
}
- br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
+ br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels),
GFP_KERNEL);
- if (!br->levels)
+ if (!br->levels) {
+ result = -ENOMEM;
goto out_free;
+ }
for (i = 0; i < obj->package.count; i++) {
o = (union acpi_object *)&obj->package.elements[i];
@@ -692,18 +762,86 @@ acpi_video_init_brightness(struct acpi_video_device *device)
count++;
}
- /* don't sort the first two brightness levels */
- sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
- acpi_video_cmp_level, NULL);
-
- if (count < 2)
- goto out_free_levels;
+ /*
+ * some buggy BIOS don't export the levels
+ * when machine is on AC/Battery in _BCL package.
+ * In this case, the first two elements in _BCL packages
+ * are also supported brightness levels that OS should take care of.
+ */
+ for (i = 2; i < count; i++)
+ if (br->levels[i] == br->levels[0] ||
+ br->levels[i] == br->levels[1])
+ level_ac_battery++;
+
+ if (level_ac_battery < 2) {
+ level_ac_battery = 2 - level_ac_battery;
+ br->flags._BCL_no_ac_battery_levels = 1;
+ for (i = (count - 1 + level_ac_battery); i >= 2; i--)
+ br->levels[i] = br->levels[i - level_ac_battery];
+ count += level_ac_battery;
+ } else if (level_ac_battery > 2)
+ ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n"));
+
+ /* Check if the _BCL package is in a reversed order */
+ if (max_level == br->levels[2]) {
+ br->flags._BCL_reversed = 1;
+ sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
+ acpi_video_cmp_level, NULL);
+ } else if (max_level != br->levels[count - 1])
+ ACPI_ERROR((AE_INFO,
+ "Found unordered _BCL package\n"));
br->count = count;
device->brightness = br;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
+
+ /* Check the input/output of _BQC/_BCL/_BCM */
+ if ((max_level < 100) && (max_level <= (count - 2)))
+ br->flags._BCL_use_index = 1;
+
+ /*
+ * _BCM is always consistent with _BCL,
+ * at least for all the laptops we have ever seen.
+ */
+ br->flags._BCM_use_index = br->flags._BCL_use_index;
+
+ /* _BQC uses INDEX while _BCL uses VALUE in some laptops */
+ br->curr = max_level;
+ result = acpi_video_device_lcd_get_level_current(device, &level_old);
+ if (result)
+ goto out_free_levels;
+
+ result = acpi_video_device_lcd_set_level(device, br->curr);
+ if (result)
+ goto out_free_levels;
+
+ result = acpi_video_device_lcd_get_level_current(device, &level);
+ if (result)
+ goto out_free_levels;
+
+ if ((level != level_old) && !br->flags._BCM_use_index) {
+ /* Note:
+ * This piece of code does not work correctly if the current
+ * brightness levels is 0.
+ * But I guess boxes that boot with such a dark screen are rare
+ * and no more code is needed to cover this specifial case.
+ */
+
+ if (level_ac_battery != 2) {
+ /*
+ * For now, we don't support the _BCL like this:
+ * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16
+ * because we may mess up the index returned by _BQC.
+ * Plus: we have not got a box like this.
+ */
+ ACPI_ERROR((AE_INFO, "_BCL not supported\n"));
+ }
+ br->flags._BQC_use_index = 1;
+ }
+
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "found %d brightness levels\n", count - 2));
kfree(obj);
- return max_level;
+ return result;
out_free_levels:
kfree(br->levels);
@@ -712,7 +850,7 @@ out_free:
out:
device->brightness = NULL;
kfree(obj);
- return 0;
+ return result;
}
/*
@@ -729,7 +867,6 @@ out:
static void acpi_video_device_find_cap(struct acpi_video_device *device)
{
acpi_handle h_dummy1;
- u32 max_level = 0;
memset(&device->cap, 0, sizeof(device->cap));
@@ -745,6 +882,12 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
}
if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
device->cap._BQC = 1;
+ else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ",
+ &h_dummy1))) {
+ printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n");
+ device->cap._BCQ = 1;
+ }
+
if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
device->cap._DDC = 1;
}
@@ -758,13 +901,14 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
device->cap._DSS = 1;
}
- if (acpi_video_backlight_support())
- max_level = acpi_video_init_brightness(device);
-
- if (device->cap._BCL && device->cap._BCM && max_level > 0) {
+ if (acpi_video_backlight_support()) {
int result;
static int count = 0;
char *name;
+
+ result = acpi_video_init_brightness(device);
+ if (result)
+ return;
name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
if (!name)
return;
@@ -773,18 +917,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
device->backlight = backlight_device_register(name,
NULL, device, &acpi_backlight_ops);
device->backlight->props.max_brightness = device->brightness->count-3;
- /*
- * If there exists the _BQC object, the _BQC object will be
- * called to get the current backlight brightness. Otherwise
- * the brightness will be set to the maximum.
- */
- if (device->cap._BQC)
- device->backlight->props.brightness =
- acpi_video_get_brightness(device->backlight);
- else
- device->backlight->props.brightness =
- device->backlight->props.max_brightness;
- backlight_update_status(device->backlight);
kfree(name);
device->cdev = thermal_cooling_device_register("LCD",
@@ -1061,13 +1193,12 @@ acpi_video_device_write_brightness(struct file *file,
/* validate through the list of available levels */
for (i = 2; i < dev->brightness->count; i++)
if (level == dev->brightness->levels[i]) {
- if (ACPI_SUCCESS
- (acpi_video_device_lcd_set_level(dev, level)))
- dev->brightness->curr = level;
+ if (!acpi_video_device_lcd_set_level(dev, level))
+ return count;
break;
}
- return count;
+ return -EINVAL;
}
static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
@@ -1125,8 +1256,6 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
if (!device_dir)
return -ENOMEM;
- device_dir->owner = THIS_MODULE;
-
/* 'info' [R] */
entry = proc_create_data("info", S_IRUGO, device_dir,
&acpi_video_device_info_fops, acpi_driver_data(device));
@@ -1134,7 +1263,6 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
goto err_remove_dir;
/* 'state' [R/W] */
- acpi_video_device_state_fops.write = acpi_video_device_write_state;
entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR,
device_dir,
&acpi_video_device_state_fops,
@@ -1143,8 +1271,6 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
goto err_remove_info;
/* 'brightness' [R/W] */
- acpi_video_device_brightness_fops.write =
- acpi_video_device_write_brightness;
entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR,
device_dir,
&acpi_video_device_brightness_fops,
@@ -1403,8 +1529,6 @@ static int acpi_video_bus_add_fs(struct acpi_device *device)
if (!device_dir)
return -ENOMEM;
- device_dir->owner = THIS_MODULE;
-
/* 'info' [R] */
entry = proc_create_data("info", S_IRUGO, device_dir,
&acpi_video_bus_info_fops,
@@ -1427,7 +1551,6 @@ static int acpi_video_bus_add_fs(struct acpi_device *device)
goto err_remove_rom;
/* 'POST' [R/W] */
- acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
device_dir,
&acpi_video_bus_POST_fops,
@@ -1436,7 +1559,6 @@ static int acpi_video_bus_add_fs(struct acpi_device *device)
goto err_remove_post_info;
/* 'DOS' [R/W] */
- acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
device_dir,
&acpi_video_bus_DOS_fops,
@@ -1749,15 +1871,29 @@ acpi_video_get_next_level(struct acpi_video_device *device,
}
}
-static void
+static int
acpi_video_switch_brightness(struct acpi_video_device *device, int event)
{
unsigned long long level_current, level_next;
+ int result = -EINVAL;
+
if (!device->brightness)
- return;
- acpi_video_device_lcd_get_level_current(device, &level_current);
+ goto out;
+
+ result = acpi_video_device_lcd_get_level_current(device,
+ &level_current);
+ if (result)
+ goto out;
+
level_next = acpi_video_get_next_level(device, level_current, event);
- acpi_video_device_lcd_set_level(device, level_next);
+
+ result = acpi_video_device_lcd_set_level(device, level_next);
+
+out:
+ if (result)
+ printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
+
+ return result;
}
static int
@@ -2124,14 +2260,33 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
return 0;
}
-static int __init acpi_video_init(void)
+static int __init intel_opregion_present(void)
+{
+#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
+ struct pci_dev *dev = NULL;
+ u32 address;
+
+ for_each_pci_dev(dev) {
+ if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+ continue;
+ if (dev->vendor != PCI_VENDOR_ID_INTEL)
+ continue;
+ pci_read_config_dword(dev, 0xfc, &address);
+ if (!address)
+ continue;
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+int acpi_video_register(void)
{
int result = 0;
acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
if (!acpi_video_dir)
return -ENODEV;
- acpi_video_dir->owner = THIS_MODULE;
result = acpi_bus_register_driver(&acpi_video_bus);
if (result < 0) {
@@ -2141,6 +2296,22 @@ static int __init acpi_video_init(void)
return 0;
}
+EXPORT_SYMBOL(acpi_video_register);
+
+/*
+ * This is kind of nasty. Hardware using Intel chipsets may require
+ * the video opregion code to be run first in order to initialise
+ * state before any ACPI video calls are made. To handle this we defer
+ * registration of the video class until the opregion code has run.
+ */
+
+static int __init acpi_video_init(void)
+{
+ if (intel_opregion_present())
+ return 0;
+
+ return acpi_video_register();
+}
static void __exit acpi_video_exit(void)
{
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 50e3d2dbf3af..09737275e25f 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -55,6 +55,9 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
"support\n"));
*cap |= ACPI_VIDEO_BACKLIGHT;
+ if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy)))
+ printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness "
+ "control misses _BQC function\n");
/* We have backlight support, no need to scan further */
return AE_CTRL_TERMINATE;
}
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index 2d34806d45dd..5aee8c26cc9f 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -8,6 +8,8 @@
#include <acpi/acpi_drivers.h>
#include <linux/kernel.h>
#include <linux/types.h>
+
+#include "internal.h"
#include "sleep.h"
#define _COMPONENT ACPI_SYSTEM_COMPONENT
@@ -136,13 +138,10 @@ void acpi_disable_wakeup_device(u8 sleep_state)
spin_unlock(&acpi_device_lock);
}
-static int __init acpi_wakeup_device_init(void)
+int __init acpi_wakeup_device_init(void)
{
struct list_head *node, *next;
- if (acpi_disabled)
- return 0;
-
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev = container_of(node,
@@ -163,5 +162,3 @@ static int __init acpi_wakeup_device_init(void)
spin_unlock(&acpi_device_lock);
return 0;
}
-
-late_initcall(acpi_wakeup_device_init);
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 00c46e0b40e4..3d763fdf99b7 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -210,7 +210,7 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
dev->dev.release = amba_device_release;
dev->dev.bus = &amba_bustype;
dev->dev.dma_mask = &dev->dma_mask;
- dev->res.name = dev->dev.bus_id;
+ dev->res.name = dev_name(&dev->dev);
if (!dev->dev.coherent_dma_mask && dev->dma_mask)
dev_warn(&dev->dev, "coherent dma mask is unset\n");
@@ -294,7 +294,7 @@ static int amba_find_match(struct device *dev, void *data)
if (d->parent)
r &= d->parent == dev->parent;
if (d->busid)
- r &= strcmp(dev->bus_id, d->busid) == 0;
+ r &= strcmp(dev_name(dev), d->busid) == 0;
if (r) {
get_device(dev);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 0bcf26464670..9120717c0701 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -86,7 +86,7 @@ config ATA_SFF
For users with exclusively modern controllers like AHCI,
Silicon Image 3124, or Marvell 6440, you may choose to
- disable this uneeded SFF support.
+ disable this unneeded SFF support.
If unsure, say Y.
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 66e012cd3271..788bba2b1e17 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -404,7 +404,7 @@ static const struct ata_port_info ahci_port_info[] = {
/* board_ahci */
{
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
@@ -412,7 +412,7 @@ static const struct ata_port_info ahci_port_info[] = {
{
AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_vt8251_ops,
},
@@ -420,7 +420,7 @@ static const struct ata_port_info ahci_port_info[] = {
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR),
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
@@ -430,7 +430,7 @@ static const struct ata_port_info ahci_port_info[] = {
AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
AHCI_HFLAG_SECT255),
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_sb600_ops,
},
@@ -440,7 +440,7 @@ static const struct ata_port_info ahci_port_info[] = {
AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP),
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
@@ -448,7 +448,7 @@ static const struct ata_port_info ahci_port_info[] = {
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL),
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_sb600_ops,
},
@@ -456,7 +456,7 @@ static const struct ata_port_info ahci_port_info[] = {
{
AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ),
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
@@ -464,7 +464,7 @@ static const struct ata_port_info ahci_port_info[] = {
{
AHCI_HFLAGS (AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
@@ -1348,7 +1348,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
writel(message[1], mmio + hpriv->em_loc+4);
/* save off new led state for port/slot */
- emp->led_state = message[1];
+ emp->led_state = state;
/*
* tell hardware to transmit the message
@@ -2565,6 +2565,15 @@ static bool ahci_broken_system_poweroff(struct pci_dev *pdev)
/* PCI slot number of the controller */
.driver_data = (void *)0x1FUL,
},
+ {
+ .ident = "HP Compaq 6720s",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6720s"),
+ },
+ /* PCI slot number of the controller */
+ .driver_data = (void *)0x1FUL,
+ },
{ } /* terminate list */
};
@@ -2647,8 +2656,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
- if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
- pci_intx(pdev, 1);
+ if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
+ pci_enable_msi(pdev);
/* save initial config */
ahci_save_initial_config(pdev, hpriv);
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index dc48a6398abe..ecfd22b4f1ce 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -118,8 +118,8 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
u16 command;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &generic_port_ops
};
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index ef8b30d577bd..e5cbe80ce172 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -446,34 +446,34 @@ static struct ata_port_info piix_port_info[] = {
[piix_pata_mwdma] = /* PIIX3 MWDMA only */
{
.flags = PIIX_PATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
.port_ops = &piix_pata_ops,
},
[piix_pata_33] = /* PIIX4 at 33MHz */
{
.flags = PIIX_PATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
- .udma_mask = ATA_UDMA_MASK_40C,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
+ .udma_mask = ATA_UDMA2,
.port_ops = &piix_pata_ops,
},
[ich_pata_33] = /* ICH0 - ICH at 33Mhz*/
{
.flags = PIIX_PATA_FLAGS,
- .pio_mask = 0x1f, /* pio 0-4 */
- .mwdma_mask = 0x06, /* Check: maybe 0x07 */
- .udma_mask = ATA_UDMA2, /* UDMA33 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY, /* Check: maybe MWDMA0 is ok */
+ .udma_mask = ATA_UDMA2,
.port_ops = &ich_pata_ops,
},
[ich_pata_66] = /* ICH controllers up to 66MHz */
{
.flags = PIIX_PATA_FLAGS,
- .pio_mask = 0x1f, /* pio 0-4 */
- .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY, /* MWDMA0 is broken on chip */
.udma_mask = ATA_UDMA4,
.port_ops = &ich_pata_ops,
},
@@ -481,17 +481,17 @@ static struct ata_port_info piix_port_info[] = {
[ich_pata_100] =
{
.flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x06, /* mwdma1-2 */
- .udma_mask = ATA_UDMA5, /* udma0-5 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY,
+ .udma_mask = ATA_UDMA5,
.port_ops = &ich_pata_ops,
},
[ich5_sata] =
{
.flags = PIIX_SATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -499,8 +499,8 @@ static struct ata_port_info piix_port_info[] = {
[ich6_sata] =
{
.flags = PIIX_SATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -508,8 +508,8 @@ static struct ata_port_info piix_port_info[] = {
[ich6m_sata] =
{
.flags = PIIX_SATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -517,8 +517,8 @@ static struct ata_port_info piix_port_info[] = {
[ich8_sata] =
{
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -526,8 +526,8 @@ static struct ata_port_info piix_port_info[] = {
[ich8_2port_sata] =
{
.flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -535,8 +535,8 @@ static struct ata_port_info piix_port_info[] = {
[tolapai_sata] =
{
.flags = PIIX_SATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -544,8 +544,8 @@ static struct ata_port_info piix_port_info[] = {
[ich8m_apple_sata] =
{
.flags = PIIX_SATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
@@ -553,9 +553,9 @@ static struct ata_port_info piix_port_info[] = {
[piix_pata_vmw] =
{
.flags = PIIX_PATA_FLAGS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
- .udma_mask = ATA_UDMA_MASK_40C,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
+ .udma_mask = ATA_UDMA2,
.port_ops = &piix_vmw_ops,
},
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 060bcd601f57..e7ea77cf6069 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -57,6 +57,7 @@
#include <linux/scatterlist.h>
#include <linux/io.h>
#include <linux/async.h>
+#include <linux/log2.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h>
@@ -2389,6 +2390,7 @@ int ata_dev_configure(struct ata_device *dev)
dev->cylinders = 0;
dev->heads = 0;
dev->sectors = 0;
+ dev->multi_count = 0;
/*
* common ATA, ATAPI feature tests
@@ -2426,8 +2428,15 @@ int ata_dev_configure(struct ata_device *dev)
dev->n_sectors = ata_id_n_sectors(id);
- if (dev->id[59] & 0x100)
- dev->multi_count = dev->id[59] & 0xff;
+ /* get current R/W Multiple count setting */
+ if ((dev->id[47] >> 8) == 0x80 && (dev->id[59] & 0x100)) {
+ unsigned int max = dev->id[47] & 0xff;
+ unsigned int cnt = dev->id[59] & 0xff;
+ /* only recognize/allow powers of two here */
+ if (is_power_of_2(max) && is_power_of_2(cnt))
+ if (cnt <= max)
+ dev->multi_count = cnt;
+ }
if (ata_id_has_lba(id)) {
const char *lba_desc;
@@ -6709,6 +6718,7 @@ EXPORT_SYMBOL_GPL(ata_id_c_string);
EXPORT_SYMBOL_GPL(ata_do_dev_read_id);
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
+EXPORT_SYMBOL_GPL(ata_pio_queue_task);
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
EXPORT_SYMBOL_GPL(ata_timing_find_mode);
EXPORT_SYMBOL_GPL(ata_timing_compute);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index ea890911d4fa..01831312c360 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -547,7 +547,7 @@ void ata_scsi_error(struct Scsi_Host *host)
/* For new EH, all qcs are finished in one of three ways -
* normal completion, error completion, and SCSI timeout.
- * Both cmpletions can race against SCSI timeout. When normal
+ * Both completions can race against SCSI timeout. When normal
* completion wins, the qc never reaches EH. When error
* completion wins, the qc has ATA_QCFLAG_FAILED set.
*
@@ -562,7 +562,19 @@ void ata_scsi_error(struct Scsi_Host *host)
int nr_timedout = 0;
spin_lock_irqsave(ap->lock, flags);
-
+
+ /* This must occur under the ap->lock as we don't want
+ a polled recovery to race the real interrupt handler
+
+ The lost_interrupt handler checks for any completed but
+ non-notified command and completes much like an IRQ handler.
+
+ We then fall into the error recovery code which will treat
+ this as if normal completion won the race */
+
+ if (ap->ops->lost_interrupt)
+ ap->ops->lost_interrupt(ap);
+
list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) {
struct ata_queued_cmd *qc;
@@ -606,6 +618,9 @@ void ata_scsi_error(struct Scsi_Host *host)
ap->eh_tries = ATA_EH_MAX_TRIES;
} else
spin_unlock_wait(ap->lock);
+
+ /* If we timed raced normal completion and there is nothing to
+ recover nr_timedout == 0 why exactly are we doing error recovery ? */
repeat:
/* invoke error handler */
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index f93dc029dfde..8332e97a9de3 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -52,6 +52,7 @@ const struct ata_port_operations ata_sff_port_ops = {
.softreset = ata_sff_softreset,
.hardreset = sata_sff_hardreset,
.postreset = ata_sff_postreset,
+ .drain_fifo = ata_sff_drain_fifo,
.error_handler = ata_sff_error_handler,
.post_internal_cmd = ata_sff_post_internal_cmd,
@@ -64,6 +65,8 @@ const struct ata_port_operations ata_sff_port_ops = {
.sff_irq_on = ata_sff_irq_on,
.sff_irq_clear = ata_sff_irq_clear,
+ .lost_interrupt = ata_sff_lost_interrupt,
+
.port_start = ata_sff_port_start,
};
EXPORT_SYMBOL_GPL(ata_sff_port_ops);
@@ -1646,7 +1649,7 @@ EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf);
* RETURNS:
* One if interrupt was handled, zero if not (shared irq).
*/
-inline unsigned int ata_sff_host_intr(struct ata_port *ap,
+unsigned int ata_sff_host_intr(struct ata_port *ap,
struct ata_queued_cmd *qc)
{
struct ata_eh_info *ehi = &ap->link.eh_info;
@@ -1775,6 +1778,48 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
EXPORT_SYMBOL_GPL(ata_sff_interrupt);
/**
+ * ata_sff_lost_interrupt - Check for an apparent lost interrupt
+ * @ap: port that appears to have timed out
+ *
+ * Called from the libata error handlers when the core code suspects
+ * an interrupt has been lost. If it has complete anything we can and
+ * then return. Interface must support altstatus for this faster
+ * recovery to occur.
+ *
+ * Locking:
+ * Caller holds host lock
+ */
+
+void ata_sff_lost_interrupt(struct ata_port *ap)
+{
+ u8 status;
+ struct ata_queued_cmd *qc;
+
+ /* Only one outstanding command per SFF channel */
+ qc = ata_qc_from_tag(ap, ap->link.active_tag);
+ /* Check we have a live one.. */
+ if (qc == NULL || !(qc->flags & ATA_QCFLAG_ACTIVE))
+ return;
+ /* We cannot lose an interrupt on a polled command */
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ return;
+ /* See if the controller thinks it is still busy - if so the command
+ isn't a lost IRQ but is still in progress */
+ status = ata_sff_altstatus(ap);
+ if (status & ATA_BUSY)
+ return;
+
+ /* There was a command running, we are no longer busy and we have
+ no interrupt. */
+ ata_port_printk(ap, KERN_WARNING, "lost interrupt (Status 0x%x)\n",
+ status);
+ /* Run the host interrupt logic as if the interrupt had not been
+ lost */
+ ata_sff_host_intr(ap, qc);
+}
+EXPORT_SYMBOL_GPL(ata_sff_lost_interrupt);
+
+/**
* ata_sff_freeze - Freeze SFF controller port
* @ap: port to freeze
*
@@ -2199,6 +2244,39 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes)
EXPORT_SYMBOL_GPL(ata_sff_postreset);
/**
+ * ata_sff_drain_fifo - Stock FIFO drain logic for SFF controllers
+ * @qc: command
+ *
+ * Drain the FIFO and device of any stuck data following a command
+ * failing to complete. In some cases this is neccessary before a
+ * reset will recover the device.
+ *
+ */
+
+void ata_sff_drain_fifo(struct ata_queued_cmd *qc)
+{
+ int count;
+ struct ata_port *ap;
+
+ /* We only need to flush incoming data when a command was running */
+ if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
+ return;
+
+ ap = qc->ap;
+ /* Drain up to 64K of data before we give up this recovery method */
+ for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
+ && count < 32768; count++)
+ ioread16(ap->ioaddr.data_addr);
+
+ /* Can become DEBUG later */
+ if (count)
+ ata_port_printk(ap, KERN_DEBUG,
+ "drained %d bytes to clear DRQ.\n", count);
+
+}
+EXPORT_SYMBOL_GPL(ata_sff_drain_fifo);
+
+/**
* ata_sff_error_handler - Stock error handler for BMDMA controller
* @ap: port to handle error for
*
@@ -2239,7 +2317,8 @@ void ata_sff_error_handler(struct ata_port *ap)
* really a timeout event, adjust error mask and
* cancel frozen state.
*/
- if (qc->err_mask == AC_ERR_TIMEOUT && (host_stat & ATA_DMA_ERR)) {
+ if (qc->err_mask == AC_ERR_TIMEOUT
+ && (host_stat & ATA_DMA_ERR)) {
qc->err_mask = AC_ERR_HOST_BUS;
thaw = 1;
}
@@ -2250,6 +2329,13 @@ void ata_sff_error_handler(struct ata_port *ap)
ata_sff_sync(ap); /* FIXME: We don't need this */
ap->ops->sff_check_status(ap);
ap->ops->sff_irq_clear(ap);
+ /* We *MUST* do FIFO draining before we issue a reset as several
+ * devices helpfully clear their internal state and will lock solid
+ * if we touch the data port post reset. Pass qc in case anyone wants
+ * to do different PIO/DMA recovery or has per command fixups
+ */
+ if (ap->ops->drain_fifo)
+ ap->ops->drain_fifo(qc);
spin_unlock_irqrestore(ap->lock, flags);
@@ -2959,4 +3045,3 @@ out:
EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
#endif /* CONFIG_PCI */
-
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index cea8014cd87e..89a1e0018e71 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -79,8 +79,6 @@ extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
u64 block, u32 n_block, unsigned int tf_flags,
unsigned int tag);
extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev);
-extern void ata_pio_queue_task(struct ata_port *ap, void *data,
- unsigned long delay);
extern void ata_port_flush_task(struct ata_port *ap);
extern unsigned ata_exec_internal(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb,
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index 8b77a9802df1..d8f35fe44421 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -246,9 +246,9 @@ static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x7f,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
.port_ops = &pacpi_ops,
};
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index eb99dbe78081..751b7ea4816c 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -492,53 +492,53 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info_early = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &ali_early_port_ops
};
/* Revision 0x20 added DMA */
static const struct ata_port_info info_20 = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &ali_20_port_ops
};
/* Revision 0x20 with support logic added UDMA */
static const struct ata_port_info info_20_udma = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x07, /* UDMA33 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &ali_20_port_ops
};
/* Revision 0xC2 adds UDMA66 */
static const struct ata_port_info info_c2 = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &ali_c2_port_ops
};
/* Revision 0xC3 is UDMA66 for now */
static const struct ata_port_info info_c3 = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &ali_c2_port_ops
};
/* Revision 0xC4 is UDMA100 */
static const struct ata_port_info info_c4 = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &ali_c4_port_ops
};
/* Revision 0xC5 is UDMA133 with LBA48 DMA */
static const struct ata_port_info info_c5 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &ali_c5_port_ops
};
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 115b1cd6dcf5..33a74f11171c 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -455,74 +455,74 @@ static void amd_clear_fifo(struct pci_dev *pdev)
static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info[10] = {
- { /* 0: AMD 7401 */
+ { /* 0: AMD 7401 - no swdma */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07, /* No SWDMA */
- .udma_mask = 0x07, /* UDMA 33 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &amd33_port_ops
},
{ /* 1: Early AMD7409 - no swdma */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA4, /* UDMA 66 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA4,
.port_ops = &amd66_port_ops
},
- { /* 2: AMD 7409, no swdma errata */
+ { /* 2: AMD 7409 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA4, /* UDMA 66 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA4,
.port_ops = &amd66_port_ops
},
{ /* 3: AMD 7411 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA5, /* UDMA 100 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &amd100_port_ops
},
{ /* 4: AMD 7441 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA5, /* UDMA 100 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &amd100_port_ops
},
- { /* 5: AMD 8111*/
+ { /* 5: AMD 8111 - no swdma */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
.port_ops = &amd133_port_ops
},
- { /* 6: AMD 8111 UDMA 100 (Serenade) */
+ { /* 6: AMD 8111 UDMA 100 (Serenade) - no swdma */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA5, /* UDMA 100, no swdma */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &amd133_port_ops
},
{ /* 7: Nvidia Nforce */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA5, /* UDMA 100 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &nv100_port_ops
},
- { /* 8: Nvidia Nforce2 and later */
+ { /* 8: Nvidia Nforce2 and later - no swdma */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA6, /* UDMA 133, no swdma */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
.port_ops = &nv133_port_ops
},
{ /* 9: AMD CS5536 (Geode companion) */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA5, /* UDMA 100 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &amd100_port_ops
}
};
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 6b3092c75ffe..d332cfdb0f30 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -12,7 +12,6 @@
* performance Alessandro Zummo <alessandro.zummo@towertech.it>
*
* TODO
- * 850 serialization once the core supports it
* Investigate no_dsc on 850R
* Clock detect
*/
@@ -29,7 +28,7 @@
#include <linux/ata.h>
#define DRV_NAME "pata_artop"
-#define DRV_VERSION "0.4.4"
+#define DRV_VERSION "0.4.5"
/*
* The ARTOP has 33 Mhz and "over clocked" timing tables. Until we
@@ -283,6 +282,31 @@ static void artop6260_set_dmamode (struct ata_port *ap, struct ata_device *adev)
pci_write_config_byte(pdev, 0x44 + ap->port_no, ultra);
}
+/**
+ * artop_6210_qc_defer - implement serialization
+ * @qc: command
+ *
+ * Issue commands per host on this chip.
+ */
+
+static int artop6210_qc_defer(struct ata_queued_cmd *qc)
+{
+ struct ata_host *host = qc->ap->host;
+ struct ata_port *alt = host->ports[1 ^ qc->ap->port_no];
+ int rc;
+
+ /* First apply the usual rules */
+ rc = ata_std_qc_defer(qc);
+ if (rc != 0)
+ return rc;
+
+ /* Now apply serialization rules. Only allow a command if the
+ other channel state machine is idle */
+ if (alt && alt->qc_active)
+ return ATA_DEFER_PORT;
+ return 0;
+}
+
static struct scsi_host_template artop_sht = {
ATA_BMDMA_SHT(DRV_NAME),
};
@@ -293,6 +317,7 @@ static struct ata_port_operations artop6210_ops = {
.set_piomode = artop6210_set_piomode,
.set_dmamode = artop6210_set_dmamode,
.prereset = artop6210_pre_reset,
+ .qc_defer = artop6210_qc_defer,
};
static struct ata_port_operations artop6260_ops = {
@@ -323,29 +348,29 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
static int printed_version;
static const struct ata_port_info info_6210 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
.port_ops = &artop6210_ops,
};
static const struct ata_port_info info_626x = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &artop6260_ops,
};
static const struct ata_port_info info_628x = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &artop6260_ops,
};
static const struct ata_port_info info_628x_fast = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &artop6260_ops,
};
@@ -362,12 +387,8 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
if (id->driver_data == 0) { /* 6210 variant */
ppi[0] = &info_6210;
- ppi[1] = &ata_dummy_port_info;
/* BIOS may have left us in UDMA, clear it before libata probe */
pci_write_config_byte(pdev, 0x54, 0);
- /* For the moment (also lacks dsc) */
- printk(KERN_WARNING "ARTOP 6210 requires serialize functionality not yet supported by libata.\n");
- printk(KERN_WARNING "Secondary ATA ports will not be activated.\n");
}
else if (id->driver_data == 1) /* 6260 */
ppi[0] = &info_626x;
diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c
index ab61095093b9..5c129f99a7e3 100644
--- a/drivers/ata/pata_at32.c
+++ b/drivers/ata/pata_at32.c
@@ -67,7 +67,9 @@
*
* Alter PIO_MASK below according to table to set maximal PIO mode.
*/
-#define PIO_MASK (0x1f)
+enum {
+ PIO_MASK = ATA_PIO4,
+};
/*
* Struct containing private information about device.
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 506adde8ebb3..bec0b8ade66d 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -220,9 +220,9 @@ static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x06, /* No MWDMA0 support */
- .udma_mask = 0x3F,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY,
+ .udma_mask = ATA_UDMA5,
.port_ops = &atiixp_port_ops
};
static const struct pci_bits atiixp_enable_bits[] = {
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c
index 1050fed96b2b..c4b47a3e5446 100644
--- a/drivers/ata/pata_bf54x.c
+++ b/drivers/ata/pata_bf54x.c
@@ -1502,7 +1502,7 @@ static struct ata_port_info bfin_port_info[] = {
.flags = ATA_FLAG_SLAVE_POSS
| ATA_FLAG_MMIO
| ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.mwdma_mask = 0,
.udma_mask = 0,
.port_ops = &bfin_pata_ops,
diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c
index 34a394264c3d..5acf9fa9b39f 100644
--- a/drivers/ata/pata_cmd640.c
+++ b/drivers/ata/pata_cmd640.c
@@ -211,7 +211,7 @@ static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &cmd640_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 3167d8fed2f2..f98dffedf4bc 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -299,40 +299,40 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static const struct ata_port_info cmd_info[6] = {
{ /* CMD 643 - no UDMA */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &cmd64x_port_ops
},
{ /* CMD 646 with broken UDMA */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &cmd64x_port_ops
},
{ /* CMD 646 with working UDMA */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
.port_ops = &cmd64x_port_ops
},
{ /* CMD 646 rev 1 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &cmd646r1_port_ops
},
{ /* CMD 648 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &cmd648_port_ops
},
{ /* CMD 649 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &cmd648_port_ops
}
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 1186bcd2781c..db6a96984f3f 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -158,7 +158,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
static const unsigned int ctl_port[] = { 0x3F6, 0x376 };
struct ata_port_info pi = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &cs5520_port_ops,
};
const struct ata_port_info *ppi[2];
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index bba453381f44..c974b05e4129 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -298,15 +298,15 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &cs5530_port_ops
};
/* The docking connector doesn't do UDMA, and it seems not MWDMA */
static const struct ata_port_info info_palmax_secondary = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &cs5530_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index 8b236af84c2e..d33aa28239a9 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -181,8 +181,8 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &cs5535_port_ops
};
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c
index afed92976198..6da4cb486c8d 100644
--- a/drivers/ata/pata_cs5536.c
+++ b/drivers/ata/pata_cs5536.c
@@ -241,8 +241,8 @@ static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &cs5536_port_ops,
};
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index d546425cd380..8fb040bf7361 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -124,8 +124,8 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &cy82c693_port_ops
};
const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index ac6392ea35b0..2085e0a3a05a 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -251,9 +251,9 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma1-2 */
- .udma_mask = 0x0f, /* UDMA 66 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA4,
.port_ops = &efar_ops,
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index 65c28e5a6cd7..d7f2da127d13 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -336,8 +336,8 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info_hpt366 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &hpt366_port_ops
};
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 42163998de9a..81ab57003aba 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -753,55 +753,55 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* HPT370 - UDMA100 */
static const struct ata_port_info info_hpt370 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt370_port_ops
};
/* HPT370A - UDMA100 */
static const struct ata_port_info info_hpt370a = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt370a_port_ops
};
/* HPT370 - UDMA100 */
static const struct ata_port_info info_hpt370_33 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt370_port_ops
};
/* HPT370A - UDMA100 */
static const struct ata_port_info info_hpt370a_33 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt370a_port_ops
};
/* HPT371, 372 and friends - UDMA133 */
static const struct ata_port_info info_hpt372 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &hpt372_port_ops
};
/* HPT374 - UDMA100, function 1 uses different prereset method */
static const struct ata_port_info info_hpt374_fn0 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt372_port_ops
};
static const struct ata_port_info info_hpt374_fn1 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &hpt374_fn1_port_ops
};
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index d5c9fd7b82bb..3d59fe0a408d 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -441,8 +441,8 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* HPT372N and friends - UDMA133 */
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &hpt3x2n_port_ops
};
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index f19cc645881a..7e310253b36b 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -188,11 +188,11 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
#if defined(CONFIG_PATA_HPT3X3_DMA)
/* Further debug needed */
- .mwdma_mask = 0x07,
- .udma_mask = 0x07,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
#endif
.port_ops = &hpt3x3_port_ops
};
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index cf9e9848f8b5..b663b7ffae4b 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -45,8 +45,6 @@ static const struct portinfo pata_icside_portinfo_v6_2 = {
.stepping = 6,
};
-#define PATA_ICSIDE_MAX_SG 128
-
struct pata_icside_state {
void __iomem *irq_port;
void __iomem *ioc_base;
@@ -57,7 +55,6 @@ struct pata_icside_state {
u8 disabled;
unsigned int speed[ATA_MAX_DEVICES];
} port[2];
- struct scatterlist sg[PATA_ICSIDE_MAX_SG];
};
struct pata_icside_info {
@@ -222,9 +219,7 @@ static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct pata_icside_state *state = ap->host->private_data;
- struct scatterlist *sg, *rsg = state->sg;
unsigned int write = qc->tf.flags & ATA_TFLAG_WRITE;
- unsigned int si;
/*
* We are simplex; BUG if we try to fiddle with DMA
@@ -233,20 +228,12 @@ static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc)
BUG_ON(dma_channel_active(state->dma));
/*
- * Copy ATAs scattered sg list into a contiguous array of sg
- */
- for_each_sg(qc->sg, sg, qc->n_elem, si) {
- memcpy(rsg, sg, sizeof(*sg));
- rsg++;
- }
-
- /*
* Route the DMA signals to the correct interface
*/
writeb(state->port[ap->port_no].port_sel, state->ioc_base);
set_dma_speed(state->dma, state->port[ap->port_no].speed[qc->dev->devno]);
- set_dma_sg(state->dma, state->sg, rsg - state->sg);
+ set_dma_sg(state->dma, qc->sg, qc->n_elem);
set_dma_mode(state->dma, write ? DMA_MODE_WRITE : DMA_MODE_READ);
/* issue r/w command */
@@ -297,7 +284,7 @@ static int icside_dma_init(struct pata_icside_info *info)
if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) {
state->dma = ec->dma;
- info->mwdma_mask = 0x07; /* MW0..2 */
+ info->mwdma_mask = ATA_MWDMA2;
}
return 0;
@@ -306,8 +293,8 @@ static int icside_dma_init(struct pata_icside_info *info)
static struct scsi_host_template pata_icside_sht = {
ATA_BASE_SHT(DRV_NAME),
- .sg_tablesize = PATA_ICSIDE_MAX_SG,
- .dma_boundary = ~0, /* no dma boundaries */
+ .sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS,
+ .dma_boundary = IOMD_DMA_BOUNDARY,
};
static void pata_icside_postreset(struct ata_link *link, unsigned int *classes)
@@ -473,7 +460,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info)
for (i = 0; i < info->nr_ports; i++) {
struct ata_port *ap = host->ports[i];
- ap->pio_mask = 0x1f;
+ ap->pio_mask = ATA_PIO4;
ap->mwdma_mask = info->mwdma_mask;
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ops = &pata_icside_port_ops;
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index 15cdb9148aab..4bceb8803a10 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -17,7 +17,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_isapnp"
-#define DRV_VERSION "0.2.2"
+#define DRV_VERSION "0.2.5"
static struct scsi_host_template isapnp_sht = {
ATA_PIO_SHT(DRV_NAME),
@@ -28,6 +28,13 @@ static struct ata_port_operations isapnp_port_ops = {
.cable_detect = ata_cable_40wire,
};
+static struct ata_port_operations isapnp_noalt_port_ops = {
+ .inherits = &ata_sff_port_ops,
+ .cable_detect = ata_cable_40wire,
+ /* No altstatus so we don't want to use the lost interrupt poll */
+ .lost_interrupt = ATA_OP_NULL,
+};
+
/**
* isapnp_init_one - attach an isapnp interface
* @idev: PnP device
@@ -65,8 +72,8 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
ap = host->ports[0];
- ap->ops = &isapnp_port_ops;
- ap->pio_mask = 1;
+ ap->ops = &isapnp_noalt_port_ops;
+ ap->pio_mask = ATA_PIO0;
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ioaddr.cmd_addr = cmd_addr;
@@ -76,6 +83,7 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
pnp_port_start(idev, 1), 1);
ap->ioaddr.altstatus_addr = ctl_addr;
ap->ioaddr.ctl_addr = ctl_addr;
+ ap->ops = &isapnp_port_ops;
}
ata_sff_std_ports(&ap->ioaddr);
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c
index c113d7c079c8..f156da8076f7 100644
--- a/drivers/ata/pata_it8213.c
+++ b/drivers/ata/pata_it8213.c
@@ -262,8 +262,8 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4, /* FIXME: want UDMA 100? */
.port_ops = &it8213_ops,
};
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index b05b86a912c5..188bc2fcd22c 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -875,29 +875,29 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static const struct ata_port_info info_smart = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &it821x_smart_port_ops
};
static const struct ata_port_info info_passthru = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &it821x_passthru_port_ops
};
static const struct ata_port_info info_rdc = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &it821x_rdc_port_ops
};
static const struct ata_port_info info_rdc_11 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
/* No UDMA */
.port_ops = &it821x_rdc_port_ops
};
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index b173c157ab00..19fdecf319a6 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -176,7 +176,7 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
ap = host->ports[0];
ap->ops = &ixp4xx_port_ops;
- ap->pio_mask = 0x1f; /* PIO4 */
+ ap->pio_mask = ATA_PIO4;
ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;
ixp4xx_setup_port(ap, data, cs0->start, cs1->start);
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 38cf1ab2d289..3a1474ac8838 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -136,8 +136,8 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &jmicron_ops,
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index e3bc1b436284..3f830f0fe2cc 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -129,7 +129,7 @@ static int qdi; /* Set to probe QDI controllers */
static int winbond; /* Set to probe Winbond controllers,
give I/O port if non standard */
static int autospeed; /* Chip present which snoops speed changes */
-static int pio_mask = 0x1F; /* PIO range for autospeed devices */
+static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */
static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */
/**
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index 76e399bf8c1b..2096fb737f82 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -126,8 +126,8 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &marvell_ops,
@@ -136,8 +136,8 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
/* Slave possible as its magically mapped not real */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &marvell_ops,
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index 50ae6d13078a..68d27bc70d06 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -737,10 +737,10 @@ mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match)
*/
prop = of_get_property(op->node, "mwdma-mode", &proplen);
if ((prop) && (proplen >= 4))
- mwdma_mask = 0x7 & ((1 << (*prop + 1)) - 1);
+ mwdma_mask = ATA_MWDMA2 & ((1 << (*prop + 1)) - 1);
prop = of_get_property(op->node, "udma-mode", &proplen);
if ((prop) && (proplen >= 4))
- udma_mask = 0x7 & ((1 << (*prop + 1)) - 1);
+ udma_mask = ATA_UDMA2 & ((1 << (*prop + 1)) - 1);
ata_irq = irq_of_parse_and_map(op->node, 0);
if (ata_irq == NO_IRQ) {
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index aa576cac4d17..b21f0021f54a 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -200,7 +200,7 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
the MPIIX your box goes castors up */
ap->ops = &mpiix_port_ops;
- ap->pio_mask = 0x1F;
+ ap->pio_mask = ATA_PIO4;
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ioaddr.cmd_addr = cmd_addr;
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index 9dc05e1656a8..bdb236957cb9 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -51,8 +51,8 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
.flags = ATA_FLAG_SLAVE_POSS,
/* Actually we don't really care about these as the
firmware deals with it */
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5, /* UDMA 133 */
.port_ops = &netcell_ops,
};
diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c
index 4dd9a3b031e4..0fb6b1b1e634 100644
--- a/drivers/ata/pata_ninja32.c
+++ b/drivers/ata/pata_ninja32.c
@@ -136,7 +136,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (!base)
return -ENOMEM;
ap->ops = &ninja32_port_ops;
- ap->pio_mask = 0x1F;
+ ap->pio_mask = ATA_PIO4;
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ioaddr.cmd_addr = base + 0x10;
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index 40d411c460de..ca53fac06717 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -144,7 +144,7 @@ static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x0F,
+ .pio_mask = ATA_PIO3,
.port_ops = &ns87410_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c
index 89bf5f865d6a..773b1590b492 100644
--- a/drivers/ata/pata_ns87415.c
+++ b/drivers/ata/pata_ns87415.c
@@ -346,8 +346,8 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *e
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &ns87415_pata_ops,
};
const struct ata_port_info *ppi[] = { &info, NULL };
@@ -355,8 +355,8 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *e
#if defined(CONFIG_SUPERIO)
static const struct ata_port_info info87560 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &ns87560_pata_ops,
};
diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c
index 0fe4ef309c62..efe2c1985af3 100644
--- a/drivers/ata/pata_octeon_cf.c
+++ b/drivers/ata/pata_octeon_cf.c
@@ -871,7 +871,7 @@ static int __devinit octeon_cf_probe(struct platform_device *pdev)
ap->private_data = cf_port;
cf_port->ap = ap;
ap->ops = &octeon_cf_ops;
- ap->pio_mask = 0x7f; /* Support PIO 0-6 */
+ ap->pio_mask = ATA_PIO6;
ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY
| ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING;
@@ -900,7 +900,7 @@ static int __devinit octeon_cf_probe(struct platform_device *pdev)
ap->ioaddr.ctl_addr = cs1 + (6 << 1) + 1;
octeon_cf_ops.sff_data_xfer = octeon_cf_data_xfer16;
- ap->mwdma_mask = 0x1f; /* Support MWDMA 0-4 */
+ ap->mwdma_mask = ATA_MWDMA4;
irq = platform_get_irq(pdev, 0);
irq_handler = octeon_cf_interrupt;
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 2c1a91c40c1a..84ac5033ac89 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -238,8 +238,8 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma1-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &oldpiix_pata_ops,
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index e4fa4d565e96..99eddda2d2e5 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -163,7 +163,7 @@ static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &opti_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index 93bb6e91973f..86885a445f97 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -399,15 +399,15 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info_82c700 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &optidma_port_ops
};
static const struct ata_port_info info_82c700_udma = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &optiplus_port_ops
};
const struct ata_port_info *ppi[] = { &info_82c700, NULL };
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 64b2e2281ee7..f4d009ed50ac 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -42,7 +42,7 @@
#define DRV_NAME "pata_pcmcia"
-#define DRV_VERSION "0.3.3"
+#define DRV_VERSION "0.3.5"
/*
* Private data structure to glue stuff together
@@ -126,6 +126,37 @@ static unsigned int ata_data_xfer_8bit(struct ata_device *dev,
return buflen;
}
+/**
+ * pcmcia_8bit_drain_fifo - Stock FIFO drain logic for SFF controllers
+ * @qc: command
+ *
+ * Drain the FIFO and device of any stuck data following a command
+ * failing to complete. In some cases this is neccessary before a
+ * reset will recover the device.
+ *
+ */
+
+void pcmcia_8bit_drain_fifo(struct ata_queued_cmd *qc)
+{
+ int count;
+ struct ata_port *ap;
+
+ /* We only need to flush incoming data when a command was running */
+ if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
+ return;
+
+ ap = qc->ap;
+
+ /* Drain up to 64K of data before we give up this recovery method */
+ for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
+ && count++ < 65536;)
+ ioread8(ap->ioaddr.data_addr);
+
+ if (count)
+ ata_port_printk(ap, KERN_WARNING, "drained %d bytes to clear DRQ.\n",
+ count);
+
+}
static struct scsi_host_template pcmcia_sht = {
ATA_PIO_SHT(DRV_NAME),
@@ -143,6 +174,7 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
.sff_data_xfer = ata_data_xfer_8bit,
.cable_detect = ata_cable_40wire,
.set_mode = pcmcia_set_mode_8bit,
+ .drain_fifo = pcmcia_8bit_drain_fifo,
};
#define CS_CHECK(fn, ret) \
@@ -299,7 +331,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
ap = host->ports[p];
ap->ops = ops;
- ap->pio_mask = 1; /* ISA so PIO 0 cycles */
+ ap->pio_mask = ATA_PIO0; /* ISA so PIO 0 cycles */
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ioaddr.cmd_addr = io_addr + 0x10 * p;
ap->ioaddr.altstatus_addr = ctl_addr + 0x10 * p;
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index e94efccaa482..ca5cad0fd80b 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -152,18 +152,18 @@ static struct ata_port_info pdc2027x_port_info[] = {
{
.flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
ATA_FLAG_MMIO,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = ATA_UDMA5, /* udma0-5 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &pdc2027x_pata100_ops,
},
/* PDC_UDMA_133 */
{
.flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
ATA_FLAG_MMIO,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = ATA_UDMA6, /* udma0-6 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA6,
.port_ops = &pdc2027x_pata133_ops,
},
};
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index 799a6a098712..5fedb3d4032b 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -291,22 +291,22 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
static const struct ata_port_info info[3] = {
{
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
.port_ops = &pdc2024x_port_ops
},
{
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &pdc2026x_port_ops
},
{
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &pdc2026x_port_ops
}
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index f1b26f7c8e4d..45879dc6fa41 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -212,11 +212,11 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
if (type == 6580) {
ap->ops = &qdi6580_port_ops;
- ap->pio_mask = 0x1F;
+ ap->pio_mask = ATA_PIO4;
ap->flags |= ATA_FLAG_SLAVE_POSS;
} else {
ap->ops = &qdi6500_port_ops;
- ap->pio_mask = 0x07; /* Actually PIO3 !IORDY is possible */
+ ap->pio_mask = ATA_PIO2; /* Actually PIO3 !IORDY is possible */
ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY;
}
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index 695d44ae52c6..4401b332eaab 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -216,9 +216,9 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma1-2 */
- .udma_mask = 0x14, /* UDMA33/66 only */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA12_ONLY,
+ .udma_mask = ATA_UDMA24_ONLY,
.port_ops = &radisys_pata_ops,
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c
index ebfcda26d639..8e3cdef8a25f 100644
--- a/drivers/ata/pata_rb532_cf.c
+++ b/drivers/ata/pata_rb532_cf.c
@@ -48,63 +48,11 @@
struct rb532_cf_info {
void __iomem *iobase;
unsigned int gpio_line;
- int frozen;
unsigned int irq;
};
/* ------------------------------------------------------------------------ */
-static inline void rb532_pata_finish_io(struct ata_port *ap)
-{
- struct ata_host *ah = ap->host;
- struct rb532_cf_info *info = ah->private_data;
-
- /* FIXME: Keep previous delay. If this is merely a fence then
- ata_sff_sync might be sufficient. */
- ata_sff_dma_pause(ap);
- ndelay(RB500_CF_IO_DELAY);
-}
-
-static void rb532_pata_exec_command(struct ata_port *ap,
- const struct ata_taskfile *tf)
-{
- writeb(tf->command, ap->ioaddr.command_addr);
- rb532_pata_finish_io(ap);
-}
-
-static unsigned int rb532_pata_data_xfer(struct ata_device *adev, unsigned char *buf,
- unsigned int buflen, int write_data)
-{
- struct ata_port *ap = adev->link->ap;
- void __iomem *ioaddr = ap->ioaddr.data_addr;
- int retlen = buflen;
-
- if (write_data) {
- for (; buflen > 0; buflen--, buf++)
- writeb(*buf, ioaddr);
- } else {
- for (; buflen > 0; buflen--, buf++)
- *buf = readb(ioaddr);
- }
-
- rb532_pata_finish_io(adev->link->ap);
- return retlen;
-}
-
-static void rb532_pata_freeze(struct ata_port *ap)
-{
- struct rb532_cf_info *info = ap->host->private_data;
-
- info->frozen = 1;
-}
-
-static void rb532_pata_thaw(struct ata_port *ap)
-{
- struct rb532_cf_info *info = ap->host->private_data;
-
- info->frozen = 0;
-}
-
static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance)
{
struct ata_host *ah = dev_instance;
@@ -112,8 +60,7 @@ static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance)
if (gpio_get_value(info->gpio_line)) {
set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW);
- if (!info->frozen)
- ata_sff_interrupt(info->irq, dev_instance);
+ ata_sff_interrupt(info->irq, dev_instance);
} else {
set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
}
@@ -123,10 +70,7 @@ static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance)
static struct ata_port_operations rb532_pata_port_ops = {
.inherits = &ata_sff_port_ops,
- .sff_exec_command = rb532_pata_exec_command,
- .sff_data_xfer = rb532_pata_data_xfer,
- .freeze = rb532_pata_freeze,
- .thaw = rb532_pata_thaw,
+ .sff_data_xfer = ata_sff_data_xfer32,
};
/* ------------------------------------------------------------------------ */
@@ -145,7 +89,7 @@ static void rb532_pata_setup_ports(struct ata_host *ah)
ap = ah->ports[0];
ap->ops = &rb532_pata_port_ops;
- ap->pio_mask = 0x1f; /* PIO4 */
+ ap->pio_mask = ATA_PIO4;
ap->flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO;
ap->ioaddr.cmd_addr = info->iobase + RB500_CF_REG_BASE;
@@ -160,7 +104,7 @@ static void rb532_pata_setup_ports(struct ata_host *ah)
static __devinit int rb532_pata_driver_probe(struct platform_device *pdev)
{
- unsigned int irq;
+ int irq;
int gpio;
struct resource *res;
struct ata_host *ah;
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index 46d6bc1bf1e9..0c574c065c62 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -88,7 +88,7 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
static int printed_version;
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &rz1000_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 9a4bdca54616..f49814d6fd2e 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -2,7 +2,6 @@
* New ATA layer SC1200 driver Alan Cox <alan@lxorguk.ukuu.org.uk>
*
* TODO: Mode selection filtering
- * TODO: Can't enable second channel until ATA core has serialize
* TODO: Needs custom DMA cleanup code
*
* Based very heavily on
@@ -178,6 +177,31 @@ static unsigned int sc1200_qc_issue(struct ata_queued_cmd *qc)
return ata_sff_qc_issue(qc);
}
+/**
+ * sc1200_qc_defer - implement serialization
+ * @qc: command
+ *
+ * Serialize command issue on this controller.
+ */
+
+static int sc1200_qc_defer(struct ata_queued_cmd *qc)
+{
+ struct ata_host *host = qc->ap->host;
+ struct ata_port *alt = host->ports[1 ^ qc->ap->port_no];
+ int rc;
+
+ /* First apply the usual rules */
+ rc = ata_std_qc_defer(qc);
+ if (rc != 0)
+ return rc;
+
+ /* Now apply serialization rules. Only allow a command if the
+ other channel state machine is idle */
+ if (alt && alt->qc_active)
+ return ATA_DEFER_PORT;
+ return 0;
+}
+
static struct scsi_host_template sc1200_sht = {
ATA_BMDMA_SHT(DRV_NAME),
.sg_tablesize = LIBATA_DUMB_MAX_PRD,
@@ -187,6 +211,7 @@ static struct ata_port_operations sc1200_port_ops = {
.inherits = &ata_bmdma_port_ops,
.qc_prep = ata_sff_dumb_qc_prep,
.qc_issue = sc1200_qc_issue,
+ .qc_defer = sc1200_qc_defer,
.cable_detect = ata_cable_40wire,
.set_piomode = sc1200_set_piomode,
.set_dmamode = sc1200_set_dmamode,
@@ -205,13 +230,13 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &sc1200_port_ops
};
/* Can't enable port 2 yet, see top comments */
- const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
+ const struct ata_port_info *ppi[] = { &info, };
return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL);
}
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index d447f1cb46ec..4257d6b40af4 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -1001,8 +1001,8 @@ static struct ata_port_operations scc_pata_ops = {
static struct ata_port_info scc_port_info[] = {
{
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x00,
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA6,
.port_ops = &scc_pata_ops,
},
diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c
index 6aeeeeb34124..99cceb458e2a 100644
--- a/drivers/ata/pata_sch.c
+++ b/drivers/ata/pata_sch.c
@@ -84,9 +84,9 @@ static struct ata_port_operations sch_pata_ops = {
static struct ata_port_info sch_port_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = ATA_PIO4, /* pio0-4 */
- .mwdma_mask = ATA_MWDMA2, /* mwdma0-2 */
- .udma_mask = ATA_UDMA5, /* udma0-5 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &sch_pata_ops,
};
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index 8d2fd9dd40c7..beaed12d50e4 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -398,26 +398,26 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
static const struct ata_port_info info[4] = {
{ /* OSB4 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &serverworks_osb4_port_ops
}, { /* OSB4 no UDMA */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
- .udma_mask = 0x00,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ /* No UDMA */
.port_ops = &serverworks_osb4_port_ops
}, { /* CSB5 */
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &serverworks_csb_port_ops
}, { /* CSB5 - later revisions*/
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &serverworks_csb_port_ops
}
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 9e764e5747e6..4cb649d8d38c 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -282,15 +282,15 @@ static int __devinit sil680_init_one(struct pci_dev *pdev,
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &sil680_port_ops
};
static const struct ata_port_info info_slow = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &sil680_port_ops
};
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index 27ceb42a774b..488e77bcd22b 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -552,51 +552,57 @@ static struct ata_port_operations sis_old_ops = {
static const struct ata_port_info sis_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07,
- .udma_mask = 0,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ /* No UDMA */
.port_ops = &sis_old_ops,
};
static const struct ata_port_info sis_info33 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07,
- .udma_mask = ATA_UDMA2, /* UDMA 33 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
.port_ops = &sis_old_ops,
};
static const struct ata_port_info sis_info66 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = ATA_UDMA4, /* UDMA 66 */
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
+ .udma_mask = ATA_UDMA4,
.port_ops = &sis_66_ops,
};
static const struct ata_port_info sis_info100 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA5,
.port_ops = &sis_100_ops,
};
static const struct ata_port_info sis_info100_early = {
.flags = ATA_FLAG_SLAVE_POSS,
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA5,
- .pio_mask = 0x1f, /* pio0-4 */
.port_ops = &sis_66_ops,
};
static const struct ata_port_info sis_info133 = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA6,
.port_ops = &sis_133_ops,
};
const struct ata_port_info sis_info133_for_sata = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA6,
.port_ops = &sis_133_for_sata_ops,
};
static const struct ata_port_info sis_info133_early = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA6,
.port_ops = &sis_133_early_ops,
};
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index 1b0e7b6d8ef5..29f733c32066 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -283,13 +283,13 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id
{
static const struct ata_port_info info_dma = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &sl82c105_port_ops
};
static const struct ata_port_info info_early = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
+ .pio_mask = ATA_PIO4,
.port_ops = &sl82c105_port_ops
};
/* for now use only the first port */
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index ef9597517cdd..f1f13ff222fd 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -191,8 +191,8 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &triflex_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index ba556d3e6963..b08e6e0f82b6 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -422,46 +422,46 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Early VIA without UDMA support */
static const struct ata_port_info via_mwdma_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &via_port_ops
};
/* Ditto with IRQ masking required */
static const struct ata_port_info via_mwdma_info_borked = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.port_ops = &via_port_ops_noirq,
};
/* VIA UDMA 33 devices (and borked 66) */
static const struct ata_port_info via_udma33_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
.port_ops = &via_port_ops
};
/* VIA UDMA 66 devices */
static const struct ata_port_info via_udma66_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
.port_ops = &via_port_ops
};
/* VIA UDMA 100 devices */
static const struct ata_port_info via_udma100_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &via_port_ops
};
/* UDMA133 with bad AST (All current 133) */
static const struct ata_port_info via_udma133_info = {
.flags = ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6, /* FIXME: should check north bridge */
.port_ops = &via_port_ops
};
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c
index 319e164a3d74..6d8619b6f670 100644
--- a/drivers/ata/pata_winbond.c
+++ b/drivers/ata/pata_winbond.c
@@ -193,7 +193,7 @@ static __init int winbond_init_one(unsigned long port)
ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", cmd_port, ctl_port);
ap->ops = &winbond_port_ops;
- ap->pio_mask = 0x1F;
+ ap->pio_mask = ATA_PIO4;
ap->flags |= ATA_FLAG_SLAVE_POSS;
ap->ioaddr.cmd_addr = cmd_addr;
ap->ioaddr.altstatus_addr = ctl_addr;
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index be53545c9f64..39588178d028 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -148,6 +148,8 @@ static struct scsi_host_template adma_ata_sht = {
static struct ata_port_operations adma_ata_ops = {
.inherits = &ata_sff_port_ops,
+ .lost_interrupt = ATA_OP_NULL,
+
.check_atapi_dma = adma_check_atapi_dma,
.qc_prep = adma_qc_prep,
.qc_issue = adma_qc_issue,
@@ -166,7 +168,7 @@ static struct ata_port_info adma_port_info[] = {
.flags = ATA_FLAG_SLAVE_POSS |
ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO |
ATA_FLAG_PIO_POLLING,
- .pio_mask = 0x10, /* pio4 */
+ .pio_mask = ATA_PIO4_ONLY,
.udma_mask = ATA_UDMA4,
.port_ops = &adma_ata_ops,
},
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index 55bc88c1707b..c2e90e1fece0 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -1279,8 +1279,8 @@ static struct ata_port_operations sata_fsl_ops = {
static const struct ata_port_info sata_fsl_port_info[] = {
{
.flags = SATA_FSL_HOST_FLAGS,
- .pio_mask = 0x1f, /* pio 0-4 */
- .udma_mask = 0x7f, /* udma 0-6 */
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
.port_ops = &sata_fsl_ops,
},
};
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index fbbd87c96f10..305a4f825f53 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -744,8 +744,8 @@ static struct ata_port_operations inic_port_ops = {
static struct ata_port_info inic_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &inic_port_ops
};
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 74b1080d116d..a377226b81c8 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1,10 +1,13 @@
/*
* sata_mv.c - Marvell SATA support
*
- * Copyright 2008: Marvell Corporation, all rights reserved.
+ * Copyright 2008-2009: Marvell Corporation, all rights reserved.
* Copyright 2005: EMC Corporation, all rights reserved.
* Copyright 2005 Red Hat, Inc. All rights reserved.
*
+ * Originally written by Brett Russ.
+ * Extensive overhaul and enhancement by Mark Lord <mlord@pobox.com>.
+ *
* Please ALWAYS copy linux-ide@vger.kernel.org on emails.
*
* This program is free software; you can redistribute it and/or modify
@@ -25,20 +28,13 @@
/*
* sata_mv TODO list:
*
- * --> Errata workaround for NCQ device errors.
- *
* --> More errata workarounds for PCI-X.
*
* --> Complete a full errata audit for all chipsets to identify others.
*
- * --> ATAPI support (Marvell claims the 60xx/70xx chips can do it).
- *
* --> Develop a low-power-consumption strategy, and implement it.
*
- * --> [Experiment, low priority] Investigate interrupt coalescing.
- * Quite often, especially with PCI Message Signalled Interrupts (MSI),
- * the overhead reduced by interrupt mitigation is quite often not
- * worth the latency cost.
+ * --> Add sysfs attributes for per-chip / per-HC IRQ coalescing thresholds.
*
* --> [Experiment, Marvell value added] Is it possible to use target
* mode to cross-connect two Linux boxes with Marvell cards? If so,
@@ -68,7 +64,27 @@
#include <linux/libata.h>
#define DRV_NAME "sata_mv"
-#define DRV_VERSION "1.25"
+#define DRV_VERSION "1.27"
+
+/*
+ * module options
+ */
+
+static int msi;
+#ifdef CONFIG_PCI
+module_param(msi, int, S_IRUGO);
+MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)");
+#endif
+
+static int irq_coalescing_io_count;
+module_param(irq_coalescing_io_count, int, S_IRUGO);
+MODULE_PARM_DESC(irq_coalescing_io_count,
+ "IRQ coalescing I/O count threshold (0..255)");
+
+static int irq_coalescing_usecs;
+module_param(irq_coalescing_usecs, int, S_IRUGO);
+MODULE_PARM_DESC(irq_coalescing_usecs,
+ "IRQ coalescing time threshold in usecs");
enum {
/* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -79,13 +95,32 @@ enum {
MV_MAJOR_REG_AREA_SZ = 0x10000, /* 64KB */
MV_MINOR_REG_AREA_SZ = 0x2000, /* 8KB */
+ /* For use with both IRQ coalescing methods ("all ports" or "per-HC" */
+ COAL_CLOCKS_PER_USEC = 150, /* for calculating COAL_TIMEs */
+ MAX_COAL_TIME_THRESHOLD = ((1 << 24) - 1), /* internal clocks count */
+ MAX_COAL_IO_COUNT = 255, /* completed I/O count */
+
MV_PCI_REG_BASE = 0,
- MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */
- MV_IRQ_COAL_CAUSE = (MV_IRQ_COAL_REG_BASE + 0x08),
- MV_IRQ_COAL_CAUSE_LO = (MV_IRQ_COAL_REG_BASE + 0x88),
- MV_IRQ_COAL_CAUSE_HI = (MV_IRQ_COAL_REG_BASE + 0x8c),
- MV_IRQ_COAL_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xcc),
- MV_IRQ_COAL_TIME_THRESHOLD = (MV_IRQ_COAL_REG_BASE + 0xd0),
+
+ /*
+ * Per-chip ("all ports") interrupt coalescing feature.
+ * This is only for GEN_II / GEN_IIE hardware.
+ *
+ * Coalescing defers the interrupt until either the IO_THRESHOLD
+ * (count of completed I/Os) is met, or the TIME_THRESHOLD is met.
+ */
+ MV_COAL_REG_BASE = 0x18000,
+ MV_IRQ_COAL_CAUSE = (MV_COAL_REG_BASE + 0x08),
+ ALL_PORTS_COAL_IRQ = (1 << 4), /* all ports irq event */
+
+ MV_IRQ_COAL_IO_THRESHOLD = (MV_COAL_REG_BASE + 0xcc),
+ MV_IRQ_COAL_TIME_THRESHOLD = (MV_COAL_REG_BASE + 0xd0),
+
+ /*
+ * Registers for the (unused here) transaction coalescing feature:
+ */
+ MV_TRAN_COAL_CAUSE_LO = (MV_COAL_REG_BASE + 0x88),
+ MV_TRAN_COAL_CAUSE_HI = (MV_COAL_REG_BASE + 0x8c),
MV_SATAHC0_REG_BASE = 0x20000,
MV_FLASH_CTL_OFS = 0x1046c,
@@ -117,17 +152,16 @@ enum {
/* Host Flags */
MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */
- MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */
MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
- ATA_FLAG_PIO_POLLING,
+ ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
+
+ MV_GEN_I_FLAGS = MV_COMMON_FLAGS | ATA_FLAG_NO_ATAPI,
- MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE,
+ MV_GEN_II_FLAGS = MV_COMMON_FLAGS | ATA_FLAG_NCQ |
+ ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA,
- MV_GENIIE_FLAGS = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
- ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
- ATA_FLAG_NCQ | ATA_FLAG_AN,
+ MV_GEN_IIE_FLAGS = MV_GEN_II_FLAGS | ATA_FLAG_AN,
CRQB_FLAG_READ = (1 << 0),
CRQB_TAG_SHIFT = 1,
@@ -180,16 +214,18 @@ enum {
PCI_HC_MAIN_IRQ_MASK_OFS = 0x1d64,
SOC_HC_MAIN_IRQ_CAUSE_OFS = 0x20020,
SOC_HC_MAIN_IRQ_MASK_OFS = 0x20024,
- ERR_IRQ = (1 << 0), /* shift by port # */
- DONE_IRQ = (1 << 1), /* shift by port # */
+ ERR_IRQ = (1 << 0), /* shift by (2 * port #) */
+ DONE_IRQ = (1 << 1), /* shift by (2 * port #) */
HC0_IRQ_PEND = 0x1ff, /* bits 0-8 = HC0's ports */
HC_SHIFT = 9, /* bits 9-17 = HC1's ports */
+ DONE_IRQ_0_3 = 0x000000aa, /* DONE_IRQ ports 0,1,2,3 */
+ DONE_IRQ_4_7 = (DONE_IRQ_0_3 << HC_SHIFT), /* 4,5,6,7 */
PCI_ERR = (1 << 18),
- TRAN_LO_DONE = (1 << 19), /* 6xxx: IRQ coalescing */
- TRAN_HI_DONE = (1 << 20), /* 6xxx: IRQ coalescing */
- PORTS_0_3_COAL_DONE = (1 << 8),
- PORTS_4_7_COAL_DONE = (1 << 17),
- PORTS_0_7_COAL_DONE = (1 << 21), /* 6xxx: IRQ coalescing */
+ TRAN_COAL_LO_DONE = (1 << 19), /* transaction coalescing */
+ TRAN_COAL_HI_DONE = (1 << 20), /* transaction coalescing */
+ PORTS_0_3_COAL_DONE = (1 << 8), /* HC0 IRQ coalescing */
+ PORTS_4_7_COAL_DONE = (1 << 17), /* HC1 IRQ coalescing */
+ ALL_PORTS_COAL_DONE = (1 << 21), /* GEN_II(E) IRQ coalescing */
GPIO_INT = (1 << 22),
SELF_INT = (1 << 23),
TWSI_INT = (1 << 24),
@@ -205,6 +241,21 @@ enum {
HC_COAL_IRQ = (1 << 4), /* IRQ coalescing */
DEV_IRQ = (1 << 8), /* shift by port # */
+ /*
+ * Per-HC (Host-Controller) interrupt coalescing feature.
+ * This is present on all chip generations.
+ *
+ * Coalescing defers the interrupt until either the IO_THRESHOLD
+ * (count of completed I/Os) is met, or the TIME_THRESHOLD is met.
+ */
+ HC_IRQ_COAL_IO_THRESHOLD_OFS = 0x000c,
+ HC_IRQ_COAL_TIME_THRESHOLD_OFS = 0x0010,
+
+ SOC_LED_CTRL_OFS = 0x2c,
+ SOC_LED_CTRL_BLINK = (1 << 0), /* Active LED blink */
+ SOC_LED_CTRL_ACT_PRESENCE = (1 << 2), /* Multiplex dev presence */
+ /* with dev activity LED */
+
/* Shadow block registers */
SHD_BLK_OFS = 0x100,
SHD_CTL_AST_OFS = 0x20, /* ofs from SHD_BLK_OFS */
@@ -346,6 +397,12 @@ enum {
EDMA_ARB_CFG_OFS = 0x38,
EDMA_HALTCOND_OFS = 0x60, /* GenIIe halt conditions */
+ EDMA_UNKNOWN_RSVD_OFS = 0x6C, /* GenIIe unknown/reserved */
+
+ BMDMA_CMD_OFS = 0x224, /* bmdma command register */
+ BMDMA_STATUS_OFS = 0x228, /* bmdma status register */
+ BMDMA_PRD_LOW_OFS = 0x22c, /* bmdma PRD addr 31:0 */
+ BMDMA_PRD_HIGH_OFS = 0x230, /* bmdma PRD addr 63:32 */
/* Host private flags (hp_flags) */
MV_HP_FLAG_MSI = (1 << 0),
@@ -359,12 +416,14 @@ enum {
MV_HP_PCIE = (1 << 9), /* PCIe bus/regs: 7042 */
MV_HP_CUT_THROUGH = (1 << 10), /* can use EDMA cut-through */
MV_HP_FLAG_SOC = (1 << 11), /* SystemOnChip, no PCI */
+ MV_HP_QUIRK_LED_BLINK_EN = (1 << 12), /* is led blinking enabled? */
/* Port private flags (pp_flags) */
MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */
MV_PP_FLAG_NCQ_EN = (1 << 1), /* is EDMA set up for NCQ? */
MV_PP_FLAG_FBS_EN = (1 << 2), /* is EDMA set up for FBS? */
MV_PP_FLAG_DELAYED_EH = (1 << 3), /* delayed dev err handling */
+ MV_PP_FLAG_FAKE_ATA_BUSY = (1 << 4), /* ignore initial ATA_DRDY */
};
#define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I)
@@ -433,6 +492,18 @@ struct mv_sg {
__le32 reserved;
};
+/*
+ * We keep a local cache of a few frequently accessed port
+ * registers here, to avoid having to read them (very slow)
+ * when switching between EDMA and non-EDMA modes.
+ */
+struct mv_cached_regs {
+ u32 fiscfg;
+ u32 ltmode;
+ u32 haltcond;
+ u32 unknown_rsvd;
+};
+
struct mv_port_priv {
struct mv_crqb *crqb;
dma_addr_t crqb_dma;
@@ -445,6 +516,7 @@ struct mv_port_priv {
unsigned int resp_idx;
u32 pp_flags;
+ struct mv_cached_regs cached;
unsigned int delayed_eh_pmp_map;
};
@@ -535,7 +607,7 @@ static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int port_no);
static int mv_stop_edma(struct ata_port *ap);
static int mv_stop_edma_engine(void __iomem *port_mmio);
-static void mv_edma_cfg(struct ata_port *ap, int want_ncq);
+static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma);
static void mv_pmp_select(struct ata_port *ap, int pmp);
static int mv_pmp_hardreset(struct ata_link *link, unsigned int *class,
@@ -546,6 +618,14 @@ static void mv_pmp_error_handler(struct ata_port *ap);
static void mv_process_crpb_entries(struct ata_port *ap,
struct mv_port_priv *pp);
+static void mv_sff_irq_clear(struct ata_port *ap);
+static int mv_check_atapi_dma(struct ata_queued_cmd *qc);
+static void mv_bmdma_setup(struct ata_queued_cmd *qc);
+static void mv_bmdma_start(struct ata_queued_cmd *qc);
+static void mv_bmdma_stop(struct ata_queued_cmd *qc);
+static u8 mv_bmdma_status(struct ata_port *ap);
+static u8 mv_sff_check_status(struct ata_port *ap);
+
/* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below
* because we have to allow room for worst case splitting of
* PRDs for 64K boundaries in mv_fill_sg().
@@ -566,6 +646,8 @@ static struct scsi_host_template mv6_sht = {
static struct ata_port_operations mv5_ops = {
.inherits = &ata_sff_port_ops,
+ .lost_interrupt = ATA_OP_NULL,
+
.qc_defer = mv_qc_defer,
.qc_prep = mv_qc_prep,
.qc_issue = mv_qc_issue,
@@ -593,6 +675,14 @@ static struct ata_port_operations mv6_ops = {
.pmp_softreset = mv_softreset,
.softreset = mv_softreset,
.error_handler = mv_pmp_error_handler,
+
+ .sff_check_status = mv_sff_check_status,
+ .sff_irq_clear = mv_sff_irq_clear,
+ .check_atapi_dma = mv_check_atapi_dma,
+ .bmdma_setup = mv_bmdma_setup,
+ .bmdma_start = mv_bmdma_start,
+ .bmdma_stop = mv_bmdma_stop,
+ .bmdma_status = mv_bmdma_status,
};
static struct ata_port_operations mv_iie_ops = {
@@ -603,53 +693,49 @@ static struct ata_port_operations mv_iie_ops = {
static const struct ata_port_info mv_port_info[] = {
{ /* chip_504x */
- .flags = MV_COMMON_FLAGS,
+ .flags = MV_GEN_I_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_508x */
- .flags = MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
+ .flags = MV_GEN_I_FLAGS | MV_FLAG_DUAL_HC,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_5080 */
- .flags = MV_COMMON_FLAGS | MV_FLAG_DUAL_HC,
+ .flags = MV_GEN_I_FLAGS | MV_FLAG_DUAL_HC,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv5_ops,
},
{ /* chip_604x */
- .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
- ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
- ATA_FLAG_NCQ,
+ .flags = MV_GEN_II_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv6_ops,
},
{ /* chip_608x */
- .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
- ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
- ATA_FLAG_NCQ | MV_FLAG_DUAL_HC,
+ .flags = MV_GEN_II_FLAGS | MV_FLAG_DUAL_HC,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv6_ops,
},
{ /* chip_6042 */
- .flags = MV_GENIIE_FLAGS,
+ .flags = MV_GEN_IIE_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
},
{ /* chip_7042 */
- .flags = MV_GENIIE_FLAGS,
+ .flags = MV_GEN_IIE_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
},
{ /* chip_soc */
- .flags = MV_GENIIE_FLAGS,
+ .flags = MV_GEN_IIE_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
@@ -794,6 +880,44 @@ static inline int mv_get_hc_count(unsigned long port_flags)
return ((port_flags & MV_FLAG_DUAL_HC) ? 2 : 1);
}
+/**
+ * mv_save_cached_regs - (re-)initialize cached port registers
+ * @ap: the port whose registers we are caching
+ *
+ * Initialize the local cache of port registers,
+ * so that reading them over and over again can
+ * be avoided on the hotter paths of this driver.
+ * This saves a few microseconds each time we switch
+ * to/from EDMA mode to perform (eg.) a drive cache flush.
+ */
+static void mv_save_cached_regs(struct ata_port *ap)
+{
+ void __iomem *port_mmio = mv_ap_base(ap);
+ struct mv_port_priv *pp = ap->private_data;
+
+ pp->cached.fiscfg = readl(port_mmio + FISCFG_OFS);
+ pp->cached.ltmode = readl(port_mmio + LTMODE_OFS);
+ pp->cached.haltcond = readl(port_mmio + EDMA_HALTCOND_OFS);
+ pp->cached.unknown_rsvd = readl(port_mmio + EDMA_UNKNOWN_RSVD_OFS);
+}
+
+/**
+ * mv_write_cached_reg - write to a cached port register
+ * @addr: hardware address of the register
+ * @old: pointer to cached value of the register
+ * @new: new value for the register
+ *
+ * Write a new value to a cached register,
+ * but only if the value is different from before.
+ */
+static inline void mv_write_cached_reg(void __iomem *addr, u32 *old, u32 new)
+{
+ if (new != *old) {
+ *old = new;
+ writel(new, addr);
+ }
+}
+
static void mv_set_edma_ptrs(void __iomem *port_mmio,
struct mv_host_priv *hpriv,
struct mv_port_priv *pp)
@@ -825,6 +949,23 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio,
port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
}
+static void mv_write_main_irq_mask(u32 mask, struct mv_host_priv *hpriv)
+{
+ /*
+ * When writing to the main_irq_mask in hardware,
+ * we must ensure exclusivity between the interrupt coalescing bits
+ * and the corresponding individual port DONE_IRQ bits.
+ *
+ * Note that this register is really an "IRQ enable" register,
+ * not an "IRQ mask" register as Marvell's naming might suggest.
+ */
+ if (mask & (ALL_PORTS_COAL_DONE | PORTS_0_3_COAL_DONE))
+ mask &= ~DONE_IRQ_0_3;
+ if (mask & (ALL_PORTS_COAL_DONE | PORTS_4_7_COAL_DONE))
+ mask &= ~DONE_IRQ_4_7;
+ writelfl(mask, hpriv->main_irq_mask_addr);
+}
+
static void mv_set_main_irq_mask(struct ata_host *host,
u32 disable_bits, u32 enable_bits)
{
@@ -835,7 +976,7 @@ static void mv_set_main_irq_mask(struct ata_host *host,
new_mask = (old_mask & ~disable_bits) | enable_bits;
if (new_mask != old_mask) {
hpriv->main_irq_mask = new_mask;
- writelfl(new_mask, hpriv->main_irq_mask_addr);
+ mv_write_main_irq_mask(new_mask, hpriv);
}
}
@@ -852,8 +993,94 @@ static void mv_enable_port_irqs(struct ata_port *ap,
mv_set_main_irq_mask(ap->host, disable_bits, enable_bits);
}
+static void mv_clear_and_enable_port_irqs(struct ata_port *ap,
+ void __iomem *port_mmio,
+ unsigned int port_irqs)
+{
+ struct mv_host_priv *hpriv = ap->host->private_data;
+ int hardport = mv_hardport_from_port(ap->port_no);
+ void __iomem *hc_mmio = mv_hc_base_from_port(
+ mv_host_base(ap->host), ap->port_no);
+ u32 hc_irq_cause;
+
+ /* clear EDMA event indicators, if any */
+ writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
+
+ /* clear pending irq events */
+ hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
+ writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
+
+ /* clear FIS IRQ Cause */
+ if (IS_GEN_IIE(hpriv))
+ writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
+
+ mv_enable_port_irqs(ap, port_irqs);
+}
+
+static void mv_set_irq_coalescing(struct ata_host *host,
+ unsigned int count, unsigned int usecs)
+{
+ struct mv_host_priv *hpriv = host->private_data;
+ void __iomem *mmio = hpriv->base, *hc_mmio;
+ u32 coal_enable = 0;
+ unsigned long flags;
+ unsigned int clks, is_dual_hc = hpriv->n_ports > MV_PORTS_PER_HC;
+ const u32 coal_disable = PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE |
+ ALL_PORTS_COAL_DONE;
+
+ /* Disable IRQ coalescing if either threshold is zero */
+ if (!usecs || !count) {
+ clks = count = 0;
+ } else {
+ /* Respect maximum limits of the hardware */
+ clks = usecs * COAL_CLOCKS_PER_USEC;
+ if (clks > MAX_COAL_TIME_THRESHOLD)
+ clks = MAX_COAL_TIME_THRESHOLD;
+ if (count > MAX_COAL_IO_COUNT)
+ count = MAX_COAL_IO_COUNT;
+ }
+
+ spin_lock_irqsave(&host->lock, flags);
+ mv_set_main_irq_mask(host, coal_disable, 0);
+
+ if (is_dual_hc && !IS_GEN_I(hpriv)) {
+ /*
+ * GEN_II/GEN_IIE with dual host controllers:
+ * one set of global thresholds for the entire chip.
+ */
+ writel(clks, mmio + MV_IRQ_COAL_TIME_THRESHOLD);
+ writel(count, mmio + MV_IRQ_COAL_IO_THRESHOLD);
+ /* clear leftover coal IRQ bit */
+ writel(~ALL_PORTS_COAL_IRQ, mmio + MV_IRQ_COAL_CAUSE);
+ if (count)
+ coal_enable = ALL_PORTS_COAL_DONE;
+ clks = count = 0; /* force clearing of regular regs below */
+ }
+
+ /*
+ * All chips: independent thresholds for each HC on the chip.
+ */
+ hc_mmio = mv_hc_base_from_port(mmio, 0);
+ writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS);
+ writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS);
+ writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE_OFS);
+ if (count)
+ coal_enable |= PORTS_0_3_COAL_DONE;
+ if (is_dual_hc) {
+ hc_mmio = mv_hc_base_from_port(mmio, MV_PORTS_PER_HC);
+ writel(clks, hc_mmio + HC_IRQ_COAL_TIME_THRESHOLD_OFS);
+ writel(count, hc_mmio + HC_IRQ_COAL_IO_THRESHOLD_OFS);
+ writel(~HC_COAL_IRQ, hc_mmio + HC_IRQ_CAUSE_OFS);
+ if (count)
+ coal_enable |= PORTS_4_7_COAL_DONE;
+ }
+
+ mv_set_main_irq_mask(host, 0, coal_enable);
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
/**
- * mv_start_dma - Enable eDMA engine
+ * mv_start_edma - Enable eDMA engine
* @base: port base address
* @pp: port private data
*
@@ -863,7 +1090,7 @@ static void mv_enable_port_irqs(struct ata_port *ap,
* LOCKING:
* Inherited from caller.
*/
-static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
+static void mv_start_edma(struct ata_port *ap, void __iomem *port_mmio,
struct mv_port_priv *pp, u8 protocol)
{
int want_ncq = (protocol == ATA_PROT_NCQ);
@@ -875,26 +1102,11 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
}
if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) {
struct mv_host_priv *hpriv = ap->host->private_data;
- int hardport = mv_hardport_from_port(ap->port_no);
- void __iomem *hc_mmio = mv_hc_base_from_port(
- mv_host_base(ap->host), ap->port_no);
- u32 hc_irq_cause;
-
- /* clear EDMA event indicators, if any */
- writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
- /* clear pending irq events */
- hc_irq_cause = ~((DEV_IRQ | DMA_IRQ) << hardport);
- writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
-
- mv_edma_cfg(ap, want_ncq);
-
- /* clear FIS IRQ Cause */
- if (IS_GEN_IIE(hpriv))
- writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
+ mv_edma_cfg(ap, want_ncq, 1);
mv_set_edma_ptrs(port_mmio, hpriv, pp);
- mv_enable_port_irqs(ap, DONE_IRQ|ERR_IRQ);
+ mv_clear_and_enable_port_irqs(ap, port_mmio, DONE_IRQ|ERR_IRQ);
writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS);
pp->pp_flags |= MV_PP_FLAG_EDMA_EN;
@@ -952,6 +1164,7 @@ static int mv_stop_edma(struct ata_port *ap)
{
void __iomem *port_mmio = mv_ap_base(ap);
struct mv_port_priv *pp = ap->private_data;
+ int err = 0;
if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN))
return 0;
@@ -959,9 +1172,10 @@ static int mv_stop_edma(struct ata_port *ap)
mv_wait_for_edma_empty_idle(ap);
if (mv_stop_edma_engine(port_mmio)) {
ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
- return -EIO;
+ err = -EIO;
}
- return 0;
+ mv_edma_cfg(ap, 0, 0);
+ return err;
}
#ifdef ATA_DEBUG
@@ -1130,35 +1344,33 @@ static int mv_qc_defer(struct ata_queued_cmd *qc)
return ATA_DEFER_PORT;
}
-static void mv_config_fbs(void __iomem *port_mmio, int want_ncq, int want_fbs)
+static void mv_config_fbs(struct ata_port *ap, int want_ncq, int want_fbs)
{
- u32 new_fiscfg, old_fiscfg;
- u32 new_ltmode, old_ltmode;
- u32 new_haltcond, old_haltcond;
+ struct mv_port_priv *pp = ap->private_data;
+ void __iomem *port_mmio;
- old_fiscfg = readl(port_mmio + FISCFG_OFS);
- old_ltmode = readl(port_mmio + LTMODE_OFS);
- old_haltcond = readl(port_mmio + EDMA_HALTCOND_OFS);
+ u32 fiscfg, *old_fiscfg = &pp->cached.fiscfg;
+ u32 ltmode, *old_ltmode = &pp->cached.ltmode;
+ u32 haltcond, *old_haltcond = &pp->cached.haltcond;
- new_fiscfg = old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR);
- new_ltmode = old_ltmode & ~LTMODE_BIT8;
- new_haltcond = old_haltcond | EDMA_ERR_DEV;
+ ltmode = *old_ltmode & ~LTMODE_BIT8;
+ haltcond = *old_haltcond | EDMA_ERR_DEV;
if (want_fbs) {
- new_fiscfg = old_fiscfg | FISCFG_SINGLE_SYNC;
- new_ltmode = old_ltmode | LTMODE_BIT8;
+ fiscfg = *old_fiscfg | FISCFG_SINGLE_SYNC;
+ ltmode = *old_ltmode | LTMODE_BIT8;
if (want_ncq)
- new_haltcond &= ~EDMA_ERR_DEV;
+ haltcond &= ~EDMA_ERR_DEV;
else
- new_fiscfg |= FISCFG_WAIT_DEV_ERR;
+ fiscfg |= FISCFG_WAIT_DEV_ERR;
+ } else {
+ fiscfg = *old_fiscfg & ~(FISCFG_SINGLE_SYNC | FISCFG_WAIT_DEV_ERR);
}
- if (new_fiscfg != old_fiscfg)
- writelfl(new_fiscfg, port_mmio + FISCFG_OFS);
- if (new_ltmode != old_ltmode)
- writelfl(new_ltmode, port_mmio + LTMODE_OFS);
- if (new_haltcond != old_haltcond)
- writelfl(new_haltcond, port_mmio + EDMA_HALTCOND_OFS);
+ port_mmio = mv_ap_base(ap);
+ mv_write_cached_reg(port_mmio + FISCFG_OFS, old_fiscfg, fiscfg);
+ mv_write_cached_reg(port_mmio + LTMODE_OFS, old_ltmode, ltmode);
+ mv_write_cached_reg(port_mmio + EDMA_HALTCOND_OFS, old_haltcond, haltcond);
}
static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq)
@@ -1176,7 +1388,86 @@ static void mv_60x1_errata_sata25(struct ata_port *ap, int want_ncq)
writel(new, hpriv->base + MV_GPIO_PORT_CTL_OFS);
}
-static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
+/**
+ * mv_bmdma_enable - set a magic bit on GEN_IIE to allow bmdma
+ * @ap: Port being initialized
+ *
+ * There are two DMA modes on these chips: basic DMA, and EDMA.
+ *
+ * Bit-0 of the "EDMA RESERVED" register enables/disables use
+ * of basic DMA on the GEN_IIE versions of the chips.
+ *
+ * This bit survives EDMA resets, and must be set for basic DMA
+ * to function, and should be cleared when EDMA is active.
+ */
+static void mv_bmdma_enable_iie(struct ata_port *ap, int enable_bmdma)
+{
+ struct mv_port_priv *pp = ap->private_data;
+ u32 new, *old = &pp->cached.unknown_rsvd;
+
+ if (enable_bmdma)
+ new = *old | 1;
+ else
+ new = *old & ~1;
+ mv_write_cached_reg(mv_ap_base(ap) + EDMA_UNKNOWN_RSVD_OFS, old, new);
+}
+
+/*
+ * SOC chips have an issue whereby the HDD LEDs don't always blink
+ * during I/O when NCQ is enabled. Enabling a special "LED blink" mode
+ * of the SOC takes care of it, generating a steady blink rate when
+ * any drive on the chip is active.
+ *
+ * Unfortunately, the blink mode is a global hardware setting for the SOC,
+ * so we must use it whenever at least one port on the SOC has NCQ enabled.
+ *
+ * We turn "LED blink" off when NCQ is not in use anywhere, because the normal
+ * LED operation works then, and provides better (more accurate) feedback.
+ *
+ * Note that this code assumes that an SOC never has more than one HC onboard.
+ */
+static void mv_soc_led_blink_enable(struct ata_port *ap)
+{
+ struct ata_host *host = ap->host;
+ struct mv_host_priv *hpriv = host->private_data;
+ void __iomem *hc_mmio;
+ u32 led_ctrl;
+
+ if (hpriv->hp_flags & MV_HP_QUIRK_LED_BLINK_EN)
+ return;
+ hpriv->hp_flags |= MV_HP_QUIRK_LED_BLINK_EN;
+ hc_mmio = mv_hc_base_from_port(mv_host_base(host), ap->port_no);
+ led_ctrl = readl(hc_mmio + SOC_LED_CTRL_OFS);
+ writel(led_ctrl | SOC_LED_CTRL_BLINK, hc_mmio + SOC_LED_CTRL_OFS);
+}
+
+static void mv_soc_led_blink_disable(struct ata_port *ap)
+{
+ struct ata_host *host = ap->host;
+ struct mv_host_priv *hpriv = host->private_data;
+ void __iomem *hc_mmio;
+ u32 led_ctrl;
+ unsigned int port;
+
+ if (!(hpriv->hp_flags & MV_HP_QUIRK_LED_BLINK_EN))
+ return;
+
+ /* disable led-blink only if no ports are using NCQ */
+ for (port = 0; port < hpriv->n_ports; port++) {
+ struct ata_port *this_ap = host->ports[port];
+ struct mv_port_priv *pp = this_ap->private_data;
+
+ if (pp->pp_flags & MV_PP_FLAG_NCQ_EN)
+ return;
+ }
+
+ hpriv->hp_flags &= ~MV_HP_QUIRK_LED_BLINK_EN;
+ hc_mmio = mv_hc_base_from_port(mv_host_base(host), ap->port_no);
+ led_ctrl = readl(hc_mmio + SOC_LED_CTRL_OFS);
+ writel(led_ctrl & ~SOC_LED_CTRL_BLINK, hc_mmio + SOC_LED_CTRL_OFS);
+}
+
+static void mv_edma_cfg(struct ata_port *ap, int want_ncq, int want_edma)
{
u32 cfg;
struct mv_port_priv *pp = ap->private_data;
@@ -1185,7 +1476,8 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
/* set up non-NCQ EDMA configuration */
cfg = EDMA_CFG_Q_DEPTH; /* always 0x1f for *all* chips */
- pp->pp_flags &= ~MV_PP_FLAG_FBS_EN;
+ pp->pp_flags &=
+ ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN | MV_PP_FLAG_FAKE_ATA_BUSY);
if (IS_GEN_I(hpriv))
cfg |= (1 << 8); /* enab config burst size mask */
@@ -1206,7 +1498,7 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
*/
want_fbs &= want_ncq;
- mv_config_fbs(port_mmio, want_ncq, want_fbs);
+ mv_config_fbs(ap, want_ncq, want_fbs);
if (want_fbs) {
pp->pp_flags |= MV_PP_FLAG_FBS_EN;
@@ -1214,18 +1506,27 @@ static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
}
cfg |= (1 << 23); /* do not mask PM field in rx'd FIS */
- cfg |= (1 << 22); /* enab 4-entry host queue cache */
- if (!IS_SOC(hpriv))
- cfg |= (1 << 18); /* enab early completion */
+ if (want_edma) {
+ cfg |= (1 << 22); /* enab 4-entry host queue cache */
+ if (!IS_SOC(hpriv))
+ cfg |= (1 << 18); /* enab early completion */
+ }
if (hpriv->hp_flags & MV_HP_CUT_THROUGH)
cfg |= (1 << 17); /* enab cut-thru (dis stor&forwrd) */
+ mv_bmdma_enable_iie(ap, !want_edma);
+
+ if (IS_SOC(hpriv)) {
+ if (want_ncq)
+ mv_soc_led_blink_enable(ap);
+ else
+ mv_soc_led_blink_disable(ap);
+ }
}
if (want_ncq) {
cfg |= EDMA_CFG_NCQ;
pp->pp_flags |= MV_PP_FLAG_NCQ_EN;
- } else
- pp->pp_flags &= ~MV_PP_FLAG_NCQ_EN;
+ }
writelfl(cfg, port_mmio + EDMA_CFG_OFS);
}
@@ -1309,6 +1610,8 @@ static int mv_port_start(struct ata_port *ap)
pp->sg_tbl_dma[tag] = pp->sg_tbl_dma[0];
}
}
+ mv_save_cached_regs(ap);
+ mv_edma_cfg(ap, 0, 0);
return 0;
out_port_free_dma_mem:
@@ -1357,12 +1660,13 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
u32 offset = addr & 0xffff;
u32 len = sg_len;
- if ((offset + sg_len > 0x10000))
+ if (offset + len > 0x10000)
len = 0x10000 - offset;
mv_sg->addr = cpu_to_le32(addr & 0xffffffff);
mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
mv_sg->flags_size = cpu_to_le32(len & 0xffff);
+ mv_sg->reserved = 0;
sg_len -= len;
addr += len;
@@ -1374,6 +1678,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
if (likely(last_sg))
last_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
+ mb(); /* ensure data structure is visible to the chipset */
}
static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
@@ -1384,6 +1689,147 @@ static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
}
/**
+ * mv_sff_irq_clear - Clear hardware interrupt after DMA.
+ * @ap: Port associated with this ATA transaction.
+ *
+ * We need this only for ATAPI bmdma transactions,
+ * as otherwise we experience spurious interrupts
+ * after libata-sff handles the bmdma interrupts.
+ */
+static void mv_sff_irq_clear(struct ata_port *ap)
+{
+ mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), ERR_IRQ);
+}
+
+/**
+ * mv_check_atapi_dma - Filter ATAPI cmds which are unsuitable for DMA.
+ * @qc: queued command to check for chipset/DMA compatibility.
+ *
+ * The bmdma engines cannot handle speculative data sizes
+ * (bytecount under/over flow). So only allow DMA for
+ * data transfer commands with known data sizes.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static int mv_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ struct scsi_cmnd *scmd = qc->scsicmd;
+
+ if (scmd) {
+ switch (scmd->cmnd[0]) {
+ case READ_6:
+ case READ_10:
+ case READ_12:
+ case WRITE_6:
+ case WRITE_10:
+ case WRITE_12:
+ case GPCMD_READ_CD:
+ case GPCMD_SEND_DVD_STRUCTURE:
+ case GPCMD_SEND_CUE_SHEET:
+ return 0; /* DMA is safe */
+ }
+ }
+ return -EOPNOTSUPP; /* use PIO instead */
+}
+
+/**
+ * mv_bmdma_setup - Set up BMDMA transaction
+ * @qc: queued command to prepare DMA for.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_bmdma_setup(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *port_mmio = mv_ap_base(ap);
+ struct mv_port_priv *pp = ap->private_data;
+
+ mv_fill_sg(qc);
+
+ /* clear all DMA cmd bits */
+ writel(0, port_mmio + BMDMA_CMD_OFS);
+
+ /* load PRD table addr. */
+ writel((pp->sg_tbl_dma[qc->tag] >> 16) >> 16,
+ port_mmio + BMDMA_PRD_HIGH_OFS);
+ writelfl(pp->sg_tbl_dma[qc->tag],
+ port_mmio + BMDMA_PRD_LOW_OFS);
+
+ /* issue r/w command */
+ ap->ops->sff_exec_command(ap, &qc->tf);
+}
+
+/**
+ * mv_bmdma_start - Start a BMDMA transaction
+ * @qc: queued command to start DMA on.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_bmdma_start(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *port_mmio = mv_ap_base(ap);
+ unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
+ u32 cmd = (rw ? 0 : ATA_DMA_WR) | ATA_DMA_START;
+
+ /* start host DMA transaction */
+ writelfl(cmd, port_mmio + BMDMA_CMD_OFS);
+}
+
+/**
+ * mv_bmdma_stop - Stop BMDMA transfer
+ * @qc: queued command to stop DMA on.
+ *
+ * Clears the ATA_DMA_START flag in the bmdma control register
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void mv_bmdma_stop(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *port_mmio = mv_ap_base(ap);
+ u32 cmd;
+
+ /* clear start/stop bit */
+ cmd = readl(port_mmio + BMDMA_CMD_OFS);
+ cmd &= ~ATA_DMA_START;
+ writelfl(cmd, port_mmio + BMDMA_CMD_OFS);
+
+ /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
+ ata_sff_dma_pause(ap);
+}
+
+/**
+ * mv_bmdma_status - Read BMDMA status
+ * @ap: port for which to retrieve DMA status.
+ *
+ * Read and return equivalent of the sff BMDMA status register.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static u8 mv_bmdma_status(struct ata_port *ap)
+{
+ void __iomem *port_mmio = mv_ap_base(ap);
+ u32 reg, status;
+
+ /*
+ * Other bits are valid only if ATA_DMA_ACTIVE==0,
+ * and the ATA_DMA_INTR bit doesn't exist.
+ */
+ reg = readl(port_mmio + BMDMA_STATUS_OFS);
+ if (reg & ATA_DMA_ACTIVE)
+ status = ATA_DMA_ACTIVE;
+ else
+ status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR;
+ return status;
+}
+
+/**
* mv_qc_prep - Host specific command preparation.
* @qc: queued command to prepare
*
@@ -1545,6 +1991,132 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
}
/**
+ * mv_sff_check_status - fetch device status, if valid
+ * @ap: ATA port to fetch status from
+ *
+ * When using command issue via mv_qc_issue_fis(),
+ * the initial ATA_BUSY state does not show up in the
+ * ATA status (shadow) register. This can confuse libata!
+ *
+ * So we have a hook here to fake ATA_BUSY for that situation,
+ * until the first time a BUSY, DRQ, or ERR bit is seen.
+ *
+ * The rest of the time, it simply returns the ATA status register.
+ */
+static u8 mv_sff_check_status(struct ata_port *ap)
+{
+ u8 stat = ioread8(ap->ioaddr.status_addr);
+ struct mv_port_priv *pp = ap->private_data;
+
+ if (pp->pp_flags & MV_PP_FLAG_FAKE_ATA_BUSY) {
+ if (stat & (ATA_BUSY | ATA_DRQ | ATA_ERR))
+ pp->pp_flags &= ~MV_PP_FLAG_FAKE_ATA_BUSY;
+ else
+ stat = ATA_BUSY;
+ }
+ return stat;
+}
+
+/**
+ * mv_send_fis - Send a FIS, using the "Vendor-Unique FIS" register
+ * @fis: fis to be sent
+ * @nwords: number of 32-bit words in the fis
+ */
+static unsigned int mv_send_fis(struct ata_port *ap, u32 *fis, int nwords)
+{
+ void __iomem *port_mmio = mv_ap_base(ap);
+ u32 ifctl, old_ifctl, ifstat;
+ int i, timeout = 200, final_word = nwords - 1;
+
+ /* Initiate FIS transmission mode */
+ old_ifctl = readl(port_mmio + SATA_IFCTL_OFS);
+ ifctl = 0x100 | (old_ifctl & 0xf);
+ writelfl(ifctl, port_mmio + SATA_IFCTL_OFS);
+
+ /* Send all words of the FIS except for the final word */
+ for (i = 0; i < final_word; ++i)
+ writel(fis[i], port_mmio + VENDOR_UNIQUE_FIS_OFS);
+
+ /* Flag end-of-transmission, and then send the final word */
+ writelfl(ifctl | 0x200, port_mmio + SATA_IFCTL_OFS);
+ writelfl(fis[final_word], port_mmio + VENDOR_UNIQUE_FIS_OFS);
+
+ /*
+ * Wait for FIS transmission to complete.
+ * This typically takes just a single iteration.
+ */
+ do {
+ ifstat = readl(port_mmio + SATA_IFSTAT_OFS);
+ } while (!(ifstat & 0x1000) && --timeout);
+
+ /* Restore original port configuration */
+ writelfl(old_ifctl, port_mmio + SATA_IFCTL_OFS);
+
+ /* See if it worked */
+ if ((ifstat & 0x3000) != 0x1000) {
+ ata_port_printk(ap, KERN_WARNING,
+ "%s transmission error, ifstat=%08x\n",
+ __func__, ifstat);
+ return AC_ERR_OTHER;
+ }
+ return 0;
+}
+
+/**
+ * mv_qc_issue_fis - Issue a command directly as a FIS
+ * @qc: queued command to start
+ *
+ * Note that the ATA shadow registers are not updated
+ * after command issue, so the device will appear "READY"
+ * if polled, even while it is BUSY processing the command.
+ *
+ * So we use a status hook to fake ATA_BUSY until the drive changes state.
+ *
+ * Note: we don't get updated shadow regs on *completion*
+ * of non-data commands. So avoid sending them via this function,
+ * as they will appear to have completed immediately.
+ *
+ * GEN_IIE has special registers that we could get the result tf from,
+ * but earlier chipsets do not. For now, we ignore those registers.
+ */
+static unsigned int mv_qc_issue_fis(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct mv_port_priv *pp = ap->private_data;
+ struct ata_link *link = qc->dev->link;
+ u32 fis[5];
+ int err = 0;
+
+ ata_tf_to_fis(&qc->tf, link->pmp, 1, (void *)fis);
+ err = mv_send_fis(ap, fis, sizeof(fis) / sizeof(fis[0]));
+ if (err)
+ return err;
+
+ switch (qc->tf.protocol) {
+ case ATAPI_PROT_PIO:
+ pp->pp_flags |= MV_PP_FLAG_FAKE_ATA_BUSY;
+ /* fall through */
+ case ATAPI_PROT_NODATA:
+ ap->hsm_task_state = HSM_ST_FIRST;
+ break;
+ case ATA_PROT_PIO:
+ pp->pp_flags |= MV_PP_FLAG_FAKE_ATA_BUSY;
+ if (qc->tf.flags & ATA_TFLAG_WRITE)
+ ap->hsm_task_state = HSM_ST_FIRST;
+ else
+ ap->hsm_task_state = HSM_ST;
+ break;
+ default:
+ ap->hsm_task_state = HSM_ST_LAST;
+ break;
+ }
+
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_pio_queue_task(ap, qc, 0);
+ return 0;
+}
+
+/**
* mv_qc_issue - Initiate a command to the host
* @qc: queued command to start
*
@@ -1558,14 +2130,28 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
*/
static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
{
+ static int limit_warnings = 10;
struct ata_port *ap = qc->ap;
void __iomem *port_mmio = mv_ap_base(ap);
struct mv_port_priv *pp = ap->private_data;
u32 in_index;
+ unsigned int port_irqs;
- if ((qc->tf.protocol != ATA_PROT_DMA) &&
- (qc->tf.protocol != ATA_PROT_NCQ)) {
- static int limit_warnings = 10;
+ pp->pp_flags &= ~MV_PP_FLAG_FAKE_ATA_BUSY; /* paranoia */
+
+ switch (qc->tf.protocol) {
+ case ATA_PROT_DMA:
+ case ATA_PROT_NCQ:
+ mv_start_edma(ap, port_mmio, pp, qc->tf.protocol);
+ pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK;
+ in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT;
+
+ /* Write the request in pointer to kick the EDMA to life */
+ writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index,
+ port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+ return 0;
+
+ case ATA_PROT_PIO:
/*
* Errata SATA#16, SATA#24: warn if multiple DRQs expected.
*
@@ -1583,27 +2169,46 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
": attempting PIO w/multiple DRQ: "
"this may fail due to h/w errata\n");
}
- /*
- * We're about to send a non-EDMA capable command to the
- * port. Turn off EDMA so there won't be problems accessing
- * shadow block, etc registers.
- */
- mv_stop_edma(ap);
- mv_enable_port_irqs(ap, ERR_IRQ);
- mv_pmp_select(ap, qc->dev->link->pmp);
- return ata_sff_qc_issue(qc);
+ /* drop through */
+ case ATA_PROT_NODATA:
+ case ATAPI_PROT_PIO:
+ case ATAPI_PROT_NODATA:
+ if (ap->flags & ATA_FLAG_PIO_POLLING)
+ qc->tf.flags |= ATA_TFLAG_POLLING;
+ break;
}
- mv_start_dma(ap, port_mmio, pp, qc->tf.protocol);
-
- pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK;
- in_index = pp->req_idx << EDMA_REQ_Q_PTR_SHIFT;
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ port_irqs = ERR_IRQ; /* mask device interrupt when polling */
+ else
+ port_irqs = ERR_IRQ | DONE_IRQ; /* unmask all interrupts */
- /* and write the request in pointer to kick the EDMA to life */
- writelfl((pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK) | in_index,
- port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+ /*
+ * We're about to send a non-EDMA capable command to the
+ * port. Turn off EDMA so there won't be problems accessing
+ * shadow block, etc registers.
+ */
+ mv_stop_edma(ap);
+ mv_clear_and_enable_port_irqs(ap, mv_ap_base(ap), port_irqs);
+ mv_pmp_select(ap, qc->dev->link->pmp);
- return 0;
+ if (qc->tf.command == ATA_CMD_READ_LOG_EXT) {
+ struct mv_host_priv *hpriv = ap->host->private_data;
+ /*
+ * Workaround for 88SX60x1 FEr SATA#25 (part 2).
+ *
+ * After any NCQ error, the READ_LOG_EXT command
+ * from libata-eh *must* use mv_qc_issue_fis().
+ * Otherwise it might fail, due to chip errata.
+ *
+ * Rather than special-case it, we'll just *always*
+ * use this method here for READ_LOG_EXT, making for
+ * easier testing.
+ */
+ if (IS_GEN_II(hpriv))
+ return mv_qc_issue_fis(qc);
+ }
+ return ata_sff_qc_issue(qc);
}
static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap)
@@ -1614,8 +2219,12 @@ static struct ata_queued_cmd *mv_get_active_qc(struct ata_port *ap)
if (pp->pp_flags & MV_PP_FLAG_NCQ_EN)
return NULL;
qc = ata_qc_from_tag(ap, ap->link.active_tag);
- if (qc && (qc->tf.flags & ATA_TFLAG_POLLING))
- qc = NULL;
+ if (qc) {
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ qc = NULL;
+ else if (!(qc->flags & ATA_QCFLAG_ACTIVE))
+ qc = NULL;
+ }
return qc;
}
@@ -2084,6 +2693,10 @@ static int mv_host_intr(struct ata_host *host, u32 main_irq_cause)
void __iomem *mmio = hpriv->base, *hc_mmio;
unsigned int handled = 0, port;
+ /* If asserted, clear the "all ports" IRQ coalescing bit */
+ if (main_irq_cause & ALL_PORTS_COAL_DONE)
+ writel(~ALL_PORTS_COAL_IRQ, mmio + MV_IRQ_COAL_CAUSE);
+
for (port = 0; port < hpriv->n_ports; port++) {
struct ata_port *ap = host->ports[port];
unsigned int p, shift, hardport, port_cause;
@@ -2116,6 +2729,8 @@ static int mv_host_intr(struct ata_host *host, u32 main_irq_cause)
* to ack (only) those ports via hc_irq_cause.
*/
ack_irqs = 0;
+ if (hc_cause & PORTS_0_3_COAL_DONE)
+ ack_irqs = HC_COAL_IRQ;
for (p = 0; p < MV_PORTS_PER_HC; ++p) {
if ((port + p) >= hpriv->n_ports)
break;
@@ -2204,7 +2819,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
/* for MSI: block new interrupts while in here */
if (using_msi)
- writel(0, hpriv->main_irq_mask_addr);
+ mv_write_main_irq_mask(0, hpriv);
main_irq_cause = readl(hpriv->main_irq_cause_addr);
pending_irqs = main_irq_cause & hpriv->main_irq_mask;
@@ -2221,7 +2836,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
/* for MSI: unmask; interrupt cause bits will retrigger now */
if (using_msi)
- writel(hpriv->main_irq_mask, hpriv->main_irq_mask_addr);
+ mv_write_main_irq_mask(hpriv->main_irq_mask, hpriv);
spin_unlock(&host->lock);
@@ -2774,6 +3389,8 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class,
mv_reset_channel(hpriv, mmio, ap->port_no);
pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+ pp->pp_flags &=
+ ~(MV_PP_FLAG_FBS_EN | MV_PP_FLAG_NCQ_EN | MV_PP_FLAG_FAKE_ATA_BUSY);
/* Workaround for errata FEr SATA#10 (part 2) */
do {
@@ -2793,6 +3410,8 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class,
extra = HZ; /* only extend it once, max */
}
} while (sstatus != 0x0 && sstatus != 0x113 && sstatus != 0x123);
+ mv_save_cached_regs(ap);
+ mv_edma_cfg(ap, 0, 0);
return rc;
}
@@ -3126,6 +3745,8 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
* The per-port interrupts get done later as ports are set up.
*/
mv_set_main_irq_mask(host, 0, PCI_ERR);
+ mv_set_irq_coalescing(host, irq_coalescing_io_count,
+ irq_coalescing_usecs);
done:
return rc;
}
@@ -3287,12 +3908,6 @@ static struct pci_driver mv_pci_driver = {
.remove = ata_pci_remove_one,
};
-/*
- * module options
- */
-static int msi; /* Use PCI msi; either zero (off, default) or non-zero */
-
-
/* move to PCI layer or libata core? */
static int pci_go_64(struct pci_dev *pdev)
{
@@ -3474,10 +4089,5 @@ MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("platform:" DRV_NAME);
-#ifdef CONFIG_PCI
-module_param(msi, int, 0444);
-MODULE_PARM_DESC(msi, "Enable use of PCI MSI (0=off, 1=on)");
-#endif
-
module_init(mv_init);
module_exit(mv_exit);
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index f65b53785a8f..6cda12ba8122 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -57,9 +57,9 @@ enum {
NV_MMIO_BAR = 5,
NV_PORTS = 2,
- NV_PIO_MASK = 0x1f,
- NV_MWDMA_MASK = 0x07,
- NV_UDMA_MASK = 0x7f,
+ NV_PIO_MASK = ATA_PIO4,
+ NV_MWDMA_MASK = ATA_MWDMA2,
+ NV_UDMA_MASK = ATA_UDMA6,
NV_PORT0_SCR_REG_OFFSET = 0x00,
NV_PORT1_SCR_REG_OFFSET = 0x40,
@@ -408,6 +408,7 @@ static struct scsi_host_template nv_swncq_sht = {
static struct ata_port_operations nv_common_ops = {
.inherits = &ata_bmdma_port_ops,
+ .lost_interrupt = ATA_OP_NULL,
.scr_read = nv_scr_read,
.scr_write = nv_scr_write,
};
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index ba9a2570a742..b1fd7d62071a 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -176,7 +176,9 @@ static const struct ata_port_operations pdc_common_ops = {
.check_atapi_dma = pdc_check_atapi_dma,
.qc_prep = pdc_qc_prep,
.qc_issue = pdc_qc_issue,
+
.sff_irq_clear = pdc_irq_clear,
+ .lost_interrupt = ATA_OP_NULL,
.post_internal_cmd = pdc_post_internal_cmd,
.error_handler = pdc_error_handler,
@@ -213,8 +215,8 @@ static const struct ata_port_info pdc_port_info[] = {
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
PDC_FLAG_SATA_PATA,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_old_sata_ops,
},
@@ -222,8 +224,8 @@ static const struct ata_port_info pdc_port_info[] = {
[board_2037x_pata] =
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_pata_ops,
},
@@ -232,8 +234,8 @@ static const struct ata_port_info pdc_port_info[] = {
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
PDC_FLAG_4_PORTS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_old_sata_ops,
},
@@ -242,8 +244,8 @@ static const struct ata_port_info pdc_port_info[] = {
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
PDC_FLAG_4_PORTS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_pata_ops,
},
@@ -252,8 +254,8 @@ static const struct ata_port_info pdc_port_info[] = {
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_sata_ops,
},
@@ -262,8 +264,8 @@ static const struct ata_port_info pdc_port_info[] = {
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
PDC_FLAG_GEN_II,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_pata_ops,
},
@@ -272,8 +274,8 @@ static const struct ata_port_info pdc_port_info[] = {
{
.flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_sata_ops,
},
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index a000c86ac859..c3936d35cdac 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -147,6 +147,7 @@ static struct ata_port_operations qs_ata_ops = {
.softreset = ATA_OP_NULL,
.error_handler = qs_error_handler,
.post_internal_cmd = ATA_OP_NULL,
+ .lost_interrupt = ATA_OP_NULL,
.scr_read = qs_scr_read,
.scr_write = qs_scr_write,
@@ -160,7 +161,7 @@ static const struct ata_port_info qs_port_info[] = {
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING,
- .pio_mask = 0x10, /* pio4 */
+ .pio_mask = ATA_PIO4_ONLY,
.udma_mask = ATA_UDMA6,
.port_ops = &qs_ata_ops,
},
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index d0091609e210..e67ce8e5caa5 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -200,8 +200,8 @@ static const struct ata_port_info sil_port_info[] = {
/* sil_3112 */
{
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &sil_ops,
},
@@ -209,24 +209,24 @@ static const struct ata_port_info sil_port_info[] = {
{
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE |
SIL_FLAG_NO_SATA_IRQ,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &sil_ops,
},
/* sil_3512 */
{
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &sil_ops,
},
/* sil_3114 */
{
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
.port_ops = &sil_ops,
},
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 2590c2279fa7..0d8990dcdfcd 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -429,25 +429,25 @@ static const struct ata_port_info sil24_port_info[] = {
{
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
SIL24_FLAG_PCIX_IRQ_WOC,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = ATA_UDMA5, /* udma0-5 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &sil24_ops,
},
/* sil_3132 */
{
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = ATA_UDMA5, /* udma0-5 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &sil24_ops,
},
/* sil_3131/sil_3531 */
{
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = ATA_UDMA5, /* udma0-5 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA5,
.port_ops = &sil24_ops,
},
};
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 9c43b4e7c4a6..8f9833228619 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -97,8 +97,8 @@ static struct ata_port_operations sis_ops = {
static const struct ata_port_info sis_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x7,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &sis_ops,
};
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index 609d147813ae..7257f2d5c52c 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -361,8 +361,8 @@ static const struct ata_port_info k2_port_info[] = {
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
@@ -371,8 +371,8 @@ static const struct ata_port_info k2_port_info[] = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA |
K2_FLAG_SATA_8_PORTS,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
@@ -380,8 +380,8 @@ static const struct ata_port_info k2_port_info[] = {
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | K2_FLAG_BAR_POS_3,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
@@ -389,8 +389,8 @@ static const struct ata_port_info k2_port_info[] = {
{
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &k2_sata_ops,
},
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index ec04b8d3c791..dce3dccced3f 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -265,8 +265,8 @@ static const struct ata_port_info pdc_port_info[] = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_SRST | ATA_FLAG_MMIO |
ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &pdc_20621_ops,
},
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index 019575bb3e08..e5bff47e8aa1 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -89,7 +89,7 @@ static struct ata_port_operations uli_ops = {
static const struct ata_port_info uli_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_IGN_SIMPLEX,
- .pio_mask = 0x1f, /* pio0-4 */
+ .pio_mask = ATA_PIO4,
.udma_mask = ATA_UDMA6,
.port_ops = &uli_ops,
};
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 5c62da9cd491..98e8c50703b3 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -146,24 +146,24 @@ static struct ata_port_operations vt8251_ops = {
static const struct ata_port_info vt6420_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &vt6420_sata_ops,
};
static struct ata_port_info vt6421_sport_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &vt6421_sata_ops,
};
static struct ata_port_info vt6421_pport_info = {
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f,
- .mwdma_mask = 0,
+ .pio_mask = ATA_PIO4,
+ /* No MWDMA */
.udma_mask = ATA_UDMA6,
.port_ops = &vt6421_pata_ops,
};
@@ -171,8 +171,8 @@ static struct ata_port_info vt6421_pport_info = {
static struct ata_port_info vt8251_port_info = {
.flags = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS |
ATA_FLAG_NO_LEGACY,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &vt8251_ops,
};
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index c57cdff9e6bd..ed70bd28fa2c 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -308,6 +308,9 @@ static struct scsi_host_template vsc_sata_sht = {
static struct ata_port_operations vsc_sata_ops = {
.inherits = &ata_bmdma_port_ops,
+ /* The IRQ handling is not quite standard SFF behaviour so we
+ cannot use the default lost interrupt handler */
+ .lost_interrupt = ATA_OP_NULL,
.sff_tf_load = vsc_sata_tf_load,
.sff_tf_read = vsc_sata_tf_read,
.freeze = vsc_freeze,
@@ -345,8 +348,8 @@ static int __devinit vsc_sata_init_one(struct pci_dev *pdev,
static const struct ata_port_info pi = {
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO,
- .pio_mask = 0x1f,
- .mwdma_mask = 0x07,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA6,
.port_ops = &vsc_sata_ops,
};
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 98099f526d82..b119640e1ee9 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1690,17 +1690,17 @@ static int __devinit fs_init (struct fs_dev *dev)
| (0 * SARMODE0_SHADEN) /* We don't use shadow registers. */
| (1 * SARMODE0_INTMODE_READCLEAR)
| (1 * SARMODE0_CWRE)
- | IS_FS50(dev)?SARMODE0_PRPWT_FS50_5:
- SARMODE0_PRPWT_FS155_3
+ | (IS_FS50(dev) ? SARMODE0_PRPWT_FS50_5:
+ SARMODE0_PRPWT_FS155_3)
| (1 * SARMODE0_CALSUP_1)
- | IS_FS50 (dev)?(0
+ | (IS_FS50(dev) ? (0
| SARMODE0_RXVCS_32
| SARMODE0_ABRVCS_32
| SARMODE0_TXVCS_32):
(0
| SARMODE0_RXVCS_1k
| SARMODE0_ABRVCS_1k
- | SARMODE0_TXVCS_1k));
+ | SARMODE0_TXVCS_1k)));
/* 10ms * 100 is 1 second. That should be enough, as AN3:9 says it takes
1ms. */
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index e1c7611e9144..78c9736c3579 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -977,9 +977,7 @@ static void xdump( u_char* cp, int length, char* prefix )
else
pBuf += sprintf( pBuf, "." );
}
- sprintf( pBuf, "\n" );
- // SPrint(prntBuf);
- printk(prntBuf);
+ printk("%s\n", prntBuf);
count += col;
pBuf = prntBuf;
}
diff --git a/drivers/atm/solos-attrlist.c b/drivers/atm/solos-attrlist.c
new file mode 100644
index 000000000000..efa2808dd94d
--- /dev/null
+++ b/drivers/atm/solos-attrlist.c
@@ -0,0 +1,70 @@
+SOLOS_ATTR_RO(DriverVersion)
+SOLOS_ATTR_RO(APIVersion)
+SOLOS_ATTR_RO(FirmwareVersion)
+// SOLOS_ATTR_RO(DspVersion)
+// SOLOS_ATTR_RO(CommonHandshake)
+SOLOS_ATTR_RO(Connected)
+SOLOS_ATTR_RO(OperationalMode)
+SOLOS_ATTR_RO(State)
+SOLOS_ATTR_RO(Watchdog)
+SOLOS_ATTR_RO(OperationProgress)
+SOLOS_ATTR_RO(LastFailed)
+SOLOS_ATTR_RO(TxBitRate)
+SOLOS_ATTR_RO(RxBitRate)
+// SOLOS_ATTR_RO(DeltACTATPds)
+// SOLOS_ATTR_RO(DeltACTATPus)
+SOLOS_ATTR_RO(TxATTNDR)
+SOLOS_ATTR_RO(RxATTNDR)
+SOLOS_ATTR_RO(AnnexType)
+SOLOS_ATTR_RO(GeneralFailure)
+SOLOS_ATTR_RO(InterleaveDpDn)
+SOLOS_ATTR_RO(InterleaveDpUp)
+SOLOS_ATTR_RO(RSCorrectedErrorsDn)
+SOLOS_ATTR_RO(RSUnCorrectedErrorsDn)
+SOLOS_ATTR_RO(RSCorrectedErrorsUp)
+SOLOS_ATTR_RO(RSUnCorrectedErrorsUp)
+SOLOS_ATTR_RO(InterleaveRDn)
+SOLOS_ATTR_RO(InterleaveRUp)
+SOLOS_ATTR_RO(ShowtimeStart)
+SOLOS_ATTR_RO(ATURVendor)
+SOLOS_ATTR_RO(ATUCCountry)
+SOLOS_ATTR_RO(ATURANSIRev)
+SOLOS_ATTR_RO(ATURANSISTD)
+SOLOS_ATTR_RO(ATUCANSIRev)
+SOLOS_ATTR_RO(ATUCANSIId)
+SOLOS_ATTR_RO(ATUCANSISTD)
+SOLOS_ATTR_RO(DataBoost)
+SOLOS_ATTR_RO(LocalITUCountryCode)
+SOLOS_ATTR_RO(LocalSEF)
+SOLOS_ATTR_RO(LocalEndLOS)
+SOLOS_ATTR_RO(LocalSNRMargin)
+SOLOS_ATTR_RO(LocalLineAttn)
+SOLOS_ATTR_RO(RawAttn)
+SOLOS_ATTR_RO(LocalTxPower)
+SOLOS_ATTR_RO(RemoteTxPower)
+SOLOS_ATTR_RO(RemoteSEF)
+SOLOS_ATTR_RO(RemoteLOS)
+SOLOS_ATTR_RO(RemoteLineAttn)
+SOLOS_ATTR_RO(RemoteSNRMargin)
+SOLOS_ATTR_RO(LineUpCount)
+SOLOS_ATTR_RO(SRACnt)
+SOLOS_ATTR_RO(SRACntUp)
+SOLOS_ATTR_RO(ProfileStatus)
+SOLOS_ATTR_RW(Action)
+SOLOS_ATTR_RW(ActivateLine)
+SOLOS_ATTR_RO(LineStatus)
+SOLOS_ATTR_RW(HostControl)
+SOLOS_ATTR_RW(AutoStart)
+SOLOS_ATTR_RW(Failsafe)
+SOLOS_ATTR_RW(ShowtimeLed)
+SOLOS_ATTR_RW(Retrain)
+SOLOS_ATTR_RW(Defaults)
+SOLOS_ATTR_RW(LineMode)
+SOLOS_ATTR_RW(Profile)
+SOLOS_ATTR_RW(DetectNoise)
+SOLOS_ATTR_RO(SupportedAnnexes)
+SOLOS_ATTR_RO(Status)
+SOLOS_ATTR_RO(TotalStart)
+SOLOS_ATTR_RO(RecentShowtimeStart)
+SOLOS_ATTR_RO(TotalRxBlocks)
+SOLOS_ATTR_RO(TotalTxBlocks)
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 89d7a6e94c9c..be204308cc1b 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -9,6 +9,7 @@
*
* Authors: Nathan Williams <nathan@traverse.com.au>
* David Woodhouse <dwmw2@infradead.org>
+ * Treker Chen <treker@xrio.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -36,8 +37,11 @@
#include <linux/sysfs.h>
#include <linux/device.h>
#include <linux/kobject.h>
+#include <linux/firmware.h>
+#include <linux/ctype.h>
+#include <linux/swab.h>
-#define VERSION "0.04"
+#define VERSION "0.07"
#define PTAG "solos-pci"
#define CONFIG_RAM_SIZE 128
@@ -45,16 +49,31 @@
#define IRQ_EN_ADDR 0x78
#define FPGA_VER 0x74
#define IRQ_CLEAR 0x70
-#define BUG_FLAG 0x6C
+#define WRITE_FLASH 0x6C
+#define PORTS 0x68
+#define FLASH_BLOCK 0x64
+#define FLASH_BUSY 0x60
+#define FPGA_MODE 0x5C
+#define FLASH_MODE 0x58
+#define TX_DMA_ADDR(port) (0x40 + (4 * (port)))
+#define RX_DMA_ADDR(port) (0x30 + (4 * (port)))
#define DATA_RAM_SIZE 32768
#define BUF_SIZE 4096
+#define FPGA_PAGE 528 /* FPGA flash page size*/
+#define SOLOS_PAGE 512 /* Solos flash page size*/
+#define FPGA_BLOCK (FPGA_PAGE * 8) /* FPGA flash block size*/
+#define SOLOS_BLOCK (SOLOS_PAGE * 8) /* Solos flash block size*/
#define RX_BUF(card, nr) ((card->buffers) + (nr)*BUF_SIZE*2)
#define TX_BUF(card, nr) ((card->buffers) + (nr)*BUF_SIZE*2 + BUF_SIZE)
-static int debug = 0;
+#define RX_DMA_SIZE 2048
+
+static int reset = 0;
static int atmdebug = 0;
+static int firmware_upgrade = 0;
+static int fpga_upgrade = 0;
struct pkt_hdr {
__le16 size;
@@ -63,23 +82,48 @@ struct pkt_hdr {
__le16 type;
};
+struct solos_skb_cb {
+ struct atm_vcc *vcc;
+ uint32_t dma_addr;
+};
+
+
+#define SKB_CB(skb) ((struct solos_skb_cb *)skb->cb)
+
#define PKT_DATA 0
#define PKT_COMMAND 1
#define PKT_POPEN 3
#define PKT_PCLOSE 4
+#define PKT_STATUS 5
struct solos_card {
void __iomem *config_regs;
void __iomem *buffers;
int nr_ports;
+ int tx_mask;
struct pci_dev *dev;
struct atm_dev *atmdev[4];
struct tasklet_struct tlet;
spinlock_t tx_lock;
spinlock_t tx_queue_lock;
spinlock_t cli_queue_lock;
+ spinlock_t param_queue_lock;
+ struct list_head param_queue;
struct sk_buff_head tx_queue[4];
struct sk_buff_head cli_queue[4];
+ struct sk_buff *tx_skb[4];
+ struct sk_buff *rx_skb[4];
+ wait_queue_head_t param_wq;
+ wait_queue_head_t fw_wq;
+ int using_dma;
+};
+
+
+struct solos_param {
+ struct list_head list;
+ pid_t pid;
+ int port;
+ struct sk_buff *response;
};
#define SOLOS_CHAN(atmdev) ((int)(unsigned long)(atmdev)->phy_data)
@@ -88,19 +132,22 @@ MODULE_AUTHOR("Traverse Technologies <support@traverse.com.au>");
MODULE_DESCRIPTION("Solos PCI driver");
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
-MODULE_PARM_DESC(debug, "Enable Loopback");
+MODULE_PARM_DESC(reset, "Reset Solos chips on startup");
MODULE_PARM_DESC(atmdebug, "Print ATM data");
-module_param(debug, int, 0444);
-module_param(atmdebug, int, 0444);
-
-static int opens;
+MODULE_PARM_DESC(firmware_upgrade, "Initiate Solos firmware upgrade");
+MODULE_PARM_DESC(fpga_upgrade, "Initiate FPGA upgrade");
+module_param(reset, int, 0444);
+module_param(atmdebug, int, 0644);
+module_param(firmware_upgrade, int, 0444);
+module_param(fpga_upgrade, int, 0444);
static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
struct atm_vcc *vcc);
-static int fpga_tx(struct solos_card *);
+static uint32_t fpga_tx(struct solos_card *);
static irqreturn_t solos_irq(int irq, void *dev_id);
static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
static int list_vccs(int vci);
+static void release_vccs(struct atm_dev *dev);
static int atm_init(struct solos_card *);
static void atm_remove(struct solos_card *);
static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
@@ -115,6 +162,264 @@ static inline void solos_pop(struct atm_vcc *vcc, struct sk_buff *skb)
dev_kfree_skb_any(skb);
}
+static ssize_t solos_param_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev);
+ struct solos_card *card = atmdev->dev_data;
+ struct solos_param prm;
+ struct sk_buff *skb;
+ struct pkt_hdr *header;
+ int buflen;
+
+ buflen = strlen(attr->attr.name) + 10;
+
+ skb = alloc_skb(sizeof(*header) + buflen, GFP_KERNEL);
+ if (!skb) {
+ dev_warn(&card->dev->dev, "Failed to allocate sk_buff in solos_param_show()\n");
+ return -ENOMEM;
+ }
+
+ header = (void *)skb_put(skb, sizeof(*header));
+
+ buflen = snprintf((void *)&header[1], buflen - 1,
+ "L%05d\n%s\n", current->pid, attr->attr.name);
+ skb_put(skb, buflen);
+
+ header->size = cpu_to_le16(buflen);
+ header->vpi = cpu_to_le16(0);
+ header->vci = cpu_to_le16(0);
+ header->type = cpu_to_le16(PKT_COMMAND);
+
+ prm.pid = current->pid;
+ prm.response = NULL;
+ prm.port = SOLOS_CHAN(atmdev);
+
+ spin_lock_irq(&card->param_queue_lock);
+ list_add(&prm.list, &card->param_queue);
+ spin_unlock_irq(&card->param_queue_lock);
+
+ fpga_queue(card, prm.port, skb, NULL);
+
+ wait_event_timeout(card->param_wq, prm.response, 5 * HZ);
+
+ spin_lock_irq(&card->param_queue_lock);
+ list_del(&prm.list);
+ spin_unlock_irq(&card->param_queue_lock);
+
+ if (!prm.response)
+ return -EIO;
+
+ buflen = prm.response->len;
+ memcpy(buf, prm.response->data, buflen);
+ kfree_skb(prm.response);
+
+ return buflen;
+}
+
+static ssize_t solos_param_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev);
+ struct solos_card *card = atmdev->dev_data;
+ struct solos_param prm;
+ struct sk_buff *skb;
+ struct pkt_hdr *header;
+ int buflen;
+ ssize_t ret;
+
+ buflen = strlen(attr->attr.name) + 11 + count;
+
+ skb = alloc_skb(sizeof(*header) + buflen, GFP_KERNEL);
+ if (!skb) {
+ dev_warn(&card->dev->dev, "Failed to allocate sk_buff in solos_param_store()\n");
+ return -ENOMEM;
+ }
+
+ header = (void *)skb_put(skb, sizeof(*header));
+
+ buflen = snprintf((void *)&header[1], buflen - 1,
+ "L%05d\n%s\n%s\n", current->pid, attr->attr.name, buf);
+
+ skb_put(skb, buflen);
+ header->size = cpu_to_le16(buflen);
+ header->vpi = cpu_to_le16(0);
+ header->vci = cpu_to_le16(0);
+ header->type = cpu_to_le16(PKT_COMMAND);
+
+ prm.pid = current->pid;
+ prm.response = NULL;
+ prm.port = SOLOS_CHAN(atmdev);
+
+ spin_lock_irq(&card->param_queue_lock);
+ list_add(&prm.list, &card->param_queue);
+ spin_unlock_irq(&card->param_queue_lock);
+
+ fpga_queue(card, prm.port, skb, NULL);
+
+ wait_event_timeout(card->param_wq, prm.response, 5 * HZ);
+
+ spin_lock_irq(&card->param_queue_lock);
+ list_del(&prm.list);
+ spin_unlock_irq(&card->param_queue_lock);
+
+ skb = prm.response;
+
+ if (!skb)
+ return -EIO;
+
+ buflen = skb->len;
+
+ /* Sometimes it has a newline, sometimes it doesn't. */
+ if (skb->data[buflen - 1] == '\n')
+ buflen--;
+
+ if (buflen == 2 && !strncmp(skb->data, "OK", 2))
+ ret = count;
+ else if (buflen == 5 && !strncmp(skb->data, "ERROR", 5))
+ ret = -EIO;
+ else {
+ /* We know we have enough space allocated for this; we allocated
+ it ourselves */
+ skb->data[buflen] = 0;
+
+ dev_warn(&card->dev->dev, "Unexpected parameter response: '%s'\n",
+ skb->data);
+ ret = -EIO;
+ }
+ kfree_skb(skb);
+
+ return ret;
+}
+
+static char *next_string(struct sk_buff *skb)
+{
+ int i = 0;
+ char *this = skb->data;
+
+ for (i = 0; i < skb->len; i++) {
+ if (this[i] == '\n') {
+ this[i] = 0;
+ skb_pull(skb, i + 1);
+ return this;
+ }
+ if (!isprint(this[i]))
+ return NULL;
+ }
+ return NULL;
+}
+
+/*
+ * Status packet has fields separated by \n, starting with a version number
+ * for the information therein. Fields are....
+ *
+ * packet version
+ * RxBitRate (version >= 1)
+ * TxBitRate (version >= 1)
+ * State (version >= 1)
+ * LocalSNRMargin (version >= 1)
+ * LocalLineAttn (version >= 1)
+ */
+static int process_status(struct solos_card *card, int port, struct sk_buff *skb)
+{
+ char *str, *end, *state_str, *snr, *attn;
+ int ver, rate_up, rate_down;
+
+ if (!card->atmdev[port])
+ return -ENODEV;
+
+ str = next_string(skb);
+ if (!str)
+ return -EIO;
+
+ ver = simple_strtol(str, NULL, 10);
+ if (ver < 1) {
+ dev_warn(&card->dev->dev, "Unexpected status interrupt version %d\n",
+ ver);
+ return -EIO;
+ }
+
+ str = next_string(skb);
+ if (!str)
+ return -EIO;
+ if (!strcmp(str, "ERROR")) {
+ dev_dbg(&card->dev->dev, "Status packet indicated Solos error on port %d (starting up?)\n",
+ port);
+ return 0;
+ }
+
+ rate_down = simple_strtol(str, &end, 10);
+ if (*end)
+ return -EIO;
+
+ str = next_string(skb);
+ if (!str)
+ return -EIO;
+ rate_up = simple_strtol(str, &end, 10);
+ if (*end)
+ return -EIO;
+
+ state_str = next_string(skb);
+ if (!state_str)
+ return -EIO;
+
+ /* Anything but 'Showtime' is down */
+ if (strcmp(state_str, "Showtime")) {
+ card->atmdev[port]->signal = ATM_PHY_SIG_LOST;
+ release_vccs(card->atmdev[port]);
+ dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str);
+ return 0;
+ }
+
+ snr = next_string(skb);
+ if (!str)
+ return -EIO;
+ attn = next_string(skb);
+ if (!attn)
+ return -EIO;
+
+ dev_info(&card->dev->dev, "Port %d: %s @%d/%d kb/s%s%s%s%s\n",
+ port, state_str, rate_down/1000, rate_up/1000,
+ snr[0]?", SNR ":"", snr, attn[0]?", Attn ":"", attn);
+
+ card->atmdev[port]->link_rate = rate_down / 424;
+ card->atmdev[port]->signal = ATM_PHY_SIG_FOUND;
+
+ return 0;
+}
+
+static int process_command(struct solos_card *card, int port, struct sk_buff *skb)
+{
+ struct solos_param *prm;
+ unsigned long flags;
+ int cmdpid;
+ int found = 0;
+
+ if (skb->len < 7)
+ return 0;
+
+ if (skb->data[0] != 'L' || !isdigit(skb->data[1]) ||
+ !isdigit(skb->data[2]) || !isdigit(skb->data[3]) ||
+ !isdigit(skb->data[4]) || !isdigit(skb->data[5]) ||
+ skb->data[6] != '\n')
+ return 0;
+
+ cmdpid = simple_strtol(&skb->data[1], NULL, 10);
+
+ spin_lock_irqsave(&card->param_queue_lock, flags);
+ list_for_each_entry(prm, &card->param_queue, list) {
+ if (prm->port == port && prm->pid == cmdpid) {
+ prm->response = skb;
+ skb_pull(skb, 7);
+ wake_up(&card->param_wq);
+ found = 1;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&card->param_queue_lock, flags);
+ return found;
+}
+
static ssize_t console_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -140,8 +445,6 @@ static int send_command(struct solos_card *card, int dev, const char *buf, size_
struct sk_buff *skb;
struct pkt_hdr *header;
-// dev_dbg(&card->dev->dev, "size: %d\n", size);
-
if (size > (BUF_SIZE - sizeof(*header))) {
dev_dbg(&card->dev->dev, "Command is too big. Dropping request\n");
return 0;
@@ -180,82 +483,181 @@ static ssize_t console_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(console, 0644, console_show, console_store);
+
+#define SOLOS_ATTR_RO(x) static DEVICE_ATTR(x, 0444, solos_param_show, NULL);
+#define SOLOS_ATTR_RW(x) static DEVICE_ATTR(x, 0644, solos_param_show, solos_param_store);
+
+#include "solos-attrlist.c"
+
+#undef SOLOS_ATTR_RO
+#undef SOLOS_ATTR_RW
+
+#define SOLOS_ATTR_RO(x) &dev_attr_##x.attr,
+#define SOLOS_ATTR_RW(x) &dev_attr_##x.attr,
+
+static struct attribute *solos_attrs[] = {
+#include "solos-attrlist.c"
+ NULL
+};
+
+static struct attribute_group solos_attr_group = {
+ .attrs = solos_attrs,
+ .name = "parameters",
+};
+
+static int flash_upgrade(struct solos_card *card, int chip)
+{
+ const struct firmware *fw;
+ const char *fw_name;
+ uint32_t data32 = 0;
+ int blocksize = 0;
+ int numblocks = 0;
+ int offset;
+
+ if (chip == 0) {
+ fw_name = "solos-FPGA.bin";
+ blocksize = FPGA_BLOCK;
+ } else {
+ fw_name = "solos-Firmware.bin";
+ blocksize = SOLOS_BLOCK;
+ }
+
+ if (request_firmware(&fw, fw_name, &card->dev->dev))
+ return -ENOENT;
+
+ dev_info(&card->dev->dev, "Flash upgrade starting\n");
+
+ numblocks = fw->size / blocksize;
+ dev_info(&card->dev->dev, "Firmware size: %zd\n", fw->size);
+ dev_info(&card->dev->dev, "Number of blocks: %d\n", numblocks);
+
+ dev_info(&card->dev->dev, "Changing FPGA to Update mode\n");
+ iowrite32(1, card->config_regs + FPGA_MODE);
+ data32 = ioread32(card->config_regs + FPGA_MODE);
+
+ /* Set mode to Chip Erase */
+ dev_info(&card->dev->dev, "Set FPGA Flash mode to %s Chip Erase\n",
+ chip?"Solos":"FPGA");
+ iowrite32((chip * 2), card->config_regs + FLASH_MODE);
+
+
+ iowrite32(1, card->config_regs + WRITE_FLASH);
+ wait_event(card->fw_wq, !ioread32(card->config_regs + FLASH_BUSY));
+
+ for (offset = 0; offset < fw->size; offset += blocksize) {
+ int i;
+
+ /* Clear write flag */
+ iowrite32(0, card->config_regs + WRITE_FLASH);
+
+ /* Set mode to Block Write */
+ /* dev_info(&card->dev->dev, "Set FPGA Flash mode to Block Write\n"); */
+ iowrite32(((chip * 2) + 1), card->config_regs + FLASH_MODE);
+
+ /* Copy block to buffer, swapping each 16 bits */
+ for(i = 0; i < blocksize; i += 4) {
+ uint32_t word = swahb32p((uint32_t *)(fw->data + offset + i));
+ iowrite32(word, RX_BUF(card, 3) + i);
+ }
+
+ /* Specify block number and then trigger flash write */
+ iowrite32(offset / blocksize, card->config_regs + FLASH_BLOCK);
+ iowrite32(1, card->config_regs + WRITE_FLASH);
+ wait_event(card->fw_wq, !ioread32(card->config_regs + FLASH_BUSY));
+ }
+
+ release_firmware(fw);
+ iowrite32(0, card->config_regs + WRITE_FLASH);
+ iowrite32(0, card->config_regs + FPGA_MODE);
+ iowrite32(0, card->config_regs + FLASH_MODE);
+ dev_info(&card->dev->dev, "Returning FPGA to Data mode\n");
+ return 0;
+}
+
static irqreturn_t solos_irq(int irq, void *dev_id)
{
struct solos_card *card = dev_id;
int handled = 1;
- //ACK IRQ
iowrite32(0, card->config_regs + IRQ_CLEAR);
- //Disable IRQs from FPGA
- iowrite32(0, card->config_regs + IRQ_EN_ADDR);
- /* If we only do it when the device is open, we lose console
- messages */
- if (1 || opens)
+ /* If we're up and running, just kick the tasklet to process TX/RX */
+ if (card->atmdev[0])
tasklet_schedule(&card->tlet);
+ else
+ wake_up(&card->fw_wq);
- //Enable IRQs from FPGA
- iowrite32(1, card->config_regs + IRQ_EN_ADDR);
return IRQ_RETVAL(handled);
}
void solos_bh(unsigned long card_arg)
{
struct solos_card *card = (void *)card_arg;
- int port;
uint32_t card_flags;
- uint32_t tx_mask;
uint32_t rx_done = 0;
+ int port;
- card_flags = ioread32(card->config_regs + FLAGS_ADDR);
-
- /* The TX bits are set if the channel is busy; clear if not. We want to
- invoke fpga_tx() unless _all_ the bits for active channels are set */
- tx_mask = (1 << card->nr_ports) - 1;
- if ((card_flags & tx_mask) != tx_mask)
- fpga_tx(card);
+ /*
+ * Since fpga_tx() is going to need to read the flags under its lock,
+ * it can return them to us so that we don't have to hit PCI MMIO
+ * again for the same information
+ */
+ card_flags = fpga_tx(card);
for (port = 0; port < card->nr_ports; port++) {
if (card_flags & (0x10 << port)) {
- struct pkt_hdr header;
+ struct pkt_hdr _hdr, *header;
struct sk_buff *skb;
struct atm_vcc *vcc;
int size;
- rx_done |= 0x10 << port;
+ if (card->using_dma) {
+ skb = card->rx_skb[port];
+ card->rx_skb[port] = NULL;
- memcpy_fromio(&header, RX_BUF(card, port), sizeof(header));
+ pci_unmap_single(card->dev, SKB_CB(skb)->dma_addr,
+ RX_DMA_SIZE, PCI_DMA_FROMDEVICE);
- size = le16_to_cpu(header.size);
+ header = (void *)skb->data;
+ size = le16_to_cpu(header->size);
+ skb_put(skb, size + sizeof(*header));
+ skb_pull(skb, sizeof(*header));
+ } else {
+ header = &_hdr;
- skb = alloc_skb(size, GFP_ATOMIC);
- if (!skb) {
- if (net_ratelimit())
- dev_warn(&card->dev->dev, "Failed to allocate sk_buff for RX\n");
- continue;
- }
+ rx_done |= 0x10 << port;
+
+ memcpy_fromio(header, RX_BUF(card, port), sizeof(*header));
- memcpy_fromio(skb_put(skb, size),
- RX_BUF(card, port) + sizeof(header),
- size);
+ size = le16_to_cpu(header->size);
+ skb = alloc_skb(size + 1, GFP_ATOMIC);
+ if (!skb) {
+ if (net_ratelimit())
+ dev_warn(&card->dev->dev, "Failed to allocate sk_buff for RX\n");
+ continue;
+ }
+
+ memcpy_fromio(skb_put(skb, size),
+ RX_BUF(card, port) + sizeof(*header),
+ size);
+ }
if (atmdebug) {
dev_info(&card->dev->dev, "Received: device %d\n", port);
dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
- size, le16_to_cpu(header.vpi),
- le16_to_cpu(header.vci));
+ size, le16_to_cpu(header->vpi),
+ le16_to_cpu(header->vci));
print_buffer(skb);
}
- switch (le16_to_cpu(header.type)) {
+ switch (le16_to_cpu(header->type)) {
case PKT_DATA:
- vcc = find_vcc(card->atmdev[port], le16_to_cpu(header.vpi),
- le16_to_cpu(header.vci));
+ vcc = find_vcc(card->atmdev[port], le16_to_cpu(header->vpi),
+ le16_to_cpu(header->vci));
if (!vcc) {
if (net_ratelimit())
dev_warn(&card->dev->dev, "Received packet for unknown VCI.VPI %d.%d on port %d\n",
- le16_to_cpu(header.vci), le16_to_cpu(header.vpi),
+ le16_to_cpu(header->vci), le16_to_cpu(header->vpi),
port);
continue;
}
@@ -264,19 +666,50 @@ void solos_bh(unsigned long card_arg)
atomic_inc(&vcc->stats->rx);
break;
+ case PKT_STATUS:
+ if (process_status(card, port, skb) &&
+ net_ratelimit()) {
+ dev_warn(&card->dev->dev, "Bad status packet of %d bytes on port %d:\n", skb->len, port);
+ print_buffer(skb);
+ }
+ dev_kfree_skb_any(skb);
+ break;
+
case PKT_COMMAND:
default: /* FIXME: Not really, surely? */
+ if (process_command(card, port, skb))
+ break;
spin_lock(&card->cli_queue_lock);
if (skb_queue_len(&card->cli_queue[port]) > 10) {
if (net_ratelimit())
dev_warn(&card->dev->dev, "Dropping console response on port %d\n",
port);
+ dev_kfree_skb_any(skb);
} else
skb_queue_tail(&card->cli_queue[port], skb);
spin_unlock(&card->cli_queue_lock);
break;
}
}
+ /* Allocate RX skbs for any ports which need them */
+ if (card->using_dma && card->atmdev[port] &&
+ !card->rx_skb[port]) {
+ struct sk_buff *skb = alloc_skb(RX_DMA_SIZE, GFP_ATOMIC);
+ if (skb) {
+ SKB_CB(skb)->dma_addr =
+ pci_map_single(card->dev, skb->data,
+ RX_DMA_SIZE, PCI_DMA_FROMDEVICE);
+ iowrite32(SKB_CB(skb)->dma_addr,
+ card->config_regs + RX_DMA_ADDR(port));
+ card->rx_skb[port] = skb;
+ } else {
+ if (net_ratelimit())
+ dev_warn(&card->dev->dev, "Failed to allocate RX skb");
+
+ /* We'll have to try again later */
+ tasklet_schedule(&card->tlet);
+ }
+ }
}
if (rx_done)
iowrite32(rx_done, card->config_regs + FLAGS_ADDR);
@@ -326,7 +759,7 @@ static int list_vccs(int vci)
vcc->vci);
}
} else {
- for(i=0; i<32; i++){
+ for(i = 0; i < VCC_HTABLE_SIZE; i++){
head = &vcc_hash[i];
sk_for_each(s, node, head) {
num_found ++;
@@ -342,6 +775,28 @@ static int list_vccs(int vci)
return num_found;
}
+static void release_vccs(struct atm_dev *dev)
+{
+ int i;
+
+ write_lock_irq(&vcc_sklist_lock);
+ for (i = 0; i < VCC_HTABLE_SIZE; i++) {
+ struct hlist_head *head = &vcc_hash[i];
+ struct hlist_node *node, *tmp;
+ struct sock *s;
+ struct atm_vcc *vcc;
+
+ sk_for_each_safe(s, node, tmp, head) {
+ vcc = atm_sk(s);
+ if (vcc->dev == dev) {
+ vcc_release_async(vcc, -EPIPE);
+ sk_del_node_init(s);
+ }
+ }
+ }
+ write_unlock_irq(&vcc_sklist_lock);
+}
+
static int popen(struct atm_vcc *vcc)
{
@@ -349,6 +804,12 @@ static int popen(struct atm_vcc *vcc)
struct sk_buff *skb;
struct pkt_hdr *header;
+ if (vcc->qos.aal != ATM_AAL5) {
+ dev_warn(&card->dev->dev, "Unsupported ATM type %d\n",
+ vcc->qos.aal);
+ return -EINVAL;
+ }
+
skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
if (!skb && net_ratelimit()) {
dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n");
@@ -356,22 +817,17 @@ static int popen(struct atm_vcc *vcc)
}
header = (void *)skb_put(skb, sizeof(*header));
- header->size = cpu_to_le16(sizeof(*header));
+ header->size = cpu_to_le16(0);
header->vpi = cpu_to_le16(vcc->vpi);
header->vci = cpu_to_le16(vcc->vci);
header->type = cpu_to_le16(PKT_POPEN);
fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL);
-// dev_dbg(&card->dev->dev, "Open for vpi %d and vci %d on interface %d\n", vcc->vpi, vcc->vci, SOLOS_CHAN(vcc->dev));
- set_bit(ATM_VF_ADDR, &vcc->flags); // accept the vpi / vci
+ set_bit(ATM_VF_ADDR, &vcc->flags);
set_bit(ATM_VF_READY, &vcc->flags);
list_vccs(0);
- if (!opens)
- iowrite32(1, card->config_regs + IRQ_EN_ADDR);
-
- opens++; //count open PVCs
return 0;
}
@@ -389,17 +845,13 @@ static void pclose(struct atm_vcc *vcc)
}
header = (void *)skb_put(skb, sizeof(*header));
- header->size = cpu_to_le16(sizeof(*header));
+ header->size = cpu_to_le16(0);
header->vpi = cpu_to_le16(vcc->vpi);
header->vci = cpu_to_le16(vcc->vci);
header->type = cpu_to_le16(PKT_PCLOSE);
fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL);
-// dev_dbg(&card->dev->dev, "Close for vpi %d and vci %d on interface %d\n", vcc->vpi, vcc->vci, SOLOS_CHAN(vcc->dev));
- if (!--opens)
- iowrite32(0, card->config_regs + IRQ_EN_ADDR);
-
clear_bit(ATM_VF_ADDR, &vcc->flags);
clear_bit(ATM_VF_READY, &vcc->flags);
@@ -439,22 +891,26 @@ static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
struct atm_vcc *vcc)
{
int old_len;
+ unsigned long flags;
- *(void **)skb->cb = vcc;
+ SKB_CB(skb)->vcc = vcc;
- spin_lock(&card->tx_queue_lock);
+ spin_lock_irqsave(&card->tx_queue_lock, flags);
old_len = skb_queue_len(&card->tx_queue[port]);
skb_queue_tail(&card->tx_queue[port], skb);
- spin_unlock(&card->tx_queue_lock);
+ if (!old_len)
+ card->tx_mask |= (1 << port);
+ spin_unlock_irqrestore(&card->tx_queue_lock, flags);
- /* If TX might need to be started, do so */
+ /* Theoretically we could just schedule the tasklet here, but
+ that introduces latency we don't want -- it's noticeable */
if (!old_len)
fpga_tx(card);
}
-static int fpga_tx(struct solos_card *card)
+static uint32_t fpga_tx(struct solos_card *card)
{
- uint32_t tx_pending;
+ uint32_t tx_pending, card_flags;
uint32_t tx_started = 0;
struct sk_buff *skb;
struct atm_vcc *vcc;
@@ -462,69 +918,77 @@ static int fpga_tx(struct solos_card *card)
unsigned long flags;
spin_lock_irqsave(&card->tx_lock, flags);
-
- tx_pending = ioread32(card->config_regs + FLAGS_ADDR);
-
- dev_vdbg(&card->dev->dev, "TX Flags are %X\n", tx_pending);
-
- for (port = 0; port < card->nr_ports; port++) {
- if (!(tx_pending & (1 << port))) {
+
+ card_flags = ioread32(card->config_regs + FLAGS_ADDR);
+ /*
+ * The queue lock is required for _writing_ to tx_mask, but we're
+ * OK to read it here without locking. The only potential update
+ * that we could race with is in fpga_queue() where it sets a bit
+ * for a new port... but it's going to call this function again if
+ * it's doing that, anyway.
+ */
+ tx_pending = card->tx_mask & ~card_flags;
+
+ for (port = 0; tx_pending; tx_pending >>= 1, port++) {
+ if (tx_pending & 1) {
+ struct sk_buff *oldskb = card->tx_skb[port];
+ if (oldskb)
+ pci_unmap_single(card->dev, SKB_CB(oldskb)->dma_addr,
+ oldskb->len, PCI_DMA_TODEVICE);
spin_lock(&card->tx_queue_lock);
skb = skb_dequeue(&card->tx_queue[port]);
+ if (!skb)
+ card->tx_mask &= ~(1 << port);
spin_unlock(&card->tx_queue_lock);
- if (!skb)
+ if (skb && !card->using_dma) {
+ memcpy_toio(TX_BUF(card, port), skb->data, skb->len);
+ tx_started |= 1 << port;
+ oldskb = skb; /* We're done with this skb already */
+ } else if (skb && card->using_dma) {
+ SKB_CB(skb)->dma_addr = pci_map_single(card->dev, skb->data,
+ skb->len, PCI_DMA_TODEVICE);
+ iowrite32(SKB_CB(skb)->dma_addr,
+ card->config_regs + TX_DMA_ADDR(port));
+ }
+
+ if (!oldskb)
continue;
+ /* Clean up and free oldskb now it's gone */
if (atmdebug) {
dev_info(&card->dev->dev, "Transmitted: port %d\n",
port);
- print_buffer(skb);
+ print_buffer(oldskb);
}
- memcpy_toio(TX_BUF(card, port), skb->data, skb->len);
- vcc = *(void **)skb->cb;
+ vcc = SKB_CB(oldskb)->vcc;
if (vcc) {
atomic_inc(&vcc->stats->tx);
- solos_pop(vcc, skb);
+ solos_pop(vcc, oldskb);
} else
- dev_kfree_skb_irq(skb);
+ dev_kfree_skb_irq(oldskb);
- tx_started |= 1 << port; //Set TX full flag
}
}
+ /* For non-DMA TX, write the 'TX start' bit for all four ports simultaneously */
if (tx_started)
iowrite32(tx_started, card->config_regs + FLAGS_ADDR);
spin_unlock_irqrestore(&card->tx_lock, flags);
- return 0;
+ return card_flags;
}
static int psend(struct atm_vcc *vcc, struct sk_buff *skb)
{
struct solos_card *card = vcc->dev->dev_data;
- struct sk_buff *skb2 = NULL;
struct pkt_hdr *header;
+ int pktlen;
- //dev_dbg(&card->dev->dev, "psend called.\n");
- //dev_dbg(&card->dev->dev, "dev,vpi,vci = %d,%d,%d\n",SOLOS_CHAN(vcc->dev),vcc->vpi,vcc->vci);
-
- if (debug) {
- skb2 = atm_alloc_charge(vcc, skb->len, GFP_ATOMIC);
- if (skb2) {
- memcpy(skb2->data, skb->data, skb->len);
- skb_put(skb2, skb->len);
- vcc->push(vcc, skb2);
- atomic_inc(&vcc->stats->rx);
- }
- atomic_inc(&vcc->stats->tx);
- solos_pop(vcc, skb);
- return 0;
- }
-
- if (skb->len > (BUF_SIZE - sizeof(*header))) {
+ pktlen = skb->len;
+ if (pktlen > (BUF_SIZE - sizeof(*header))) {
dev_warn(&card->dev->dev, "Length of PDU is too large. Dropping PDU.\n");
solos_pop(vcc, skb);
return 0;
@@ -539,6 +1003,7 @@ static int psend(struct atm_vcc *vcc, struct sk_buff *skb)
ret = pskb_expand_head(skb, expand_by, 0, GFP_ATOMIC);
if (ret) {
+ dev_warn(&card->dev->dev, "pskb_expand_head failed.\n");
solos_pop(vcc, skb);
return ret;
}
@@ -546,7 +1011,8 @@ static int psend(struct atm_vcc *vcc, struct sk_buff *skb)
header = (void *)skb_push(skb, sizeof(*header));
- header->size = cpu_to_le16(skb->len);
+ /* This does _not_ include the size of the header */
+ header->size = cpu_to_le16(pktlen);
header->vpi = cpu_to_le16(vcc->vpi);
header->vci = cpu_to_le16(vcc->vci);
header->type = cpu_to_le16(PKT_DATA);
@@ -573,20 +1039,19 @@ static struct atmdev_ops fpga_ops = {
static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
- int err, i;
+ int err;
uint16_t fpga_ver;
uint8_t major_ver, minor_ver;
uint32_t data32;
struct solos_card *card;
- if (debug)
- return 0;
-
card = kzalloc(sizeof(*card), GFP_KERNEL);
if (!card)
return -ENOMEM;
card->dev = dev;
+ init_waitqueue_head(&card->fw_wq);
+ init_waitqueue_head(&card->param_wq);
err = pci_enable_device(dev);
if (err) {
@@ -594,6 +1059,12 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
goto out;
}
+ err = pci_set_dma_mask(dev, DMA_32BIT_MASK);
+ if (err) {
+ dev_warn(&dev->dev, "Failed to set 32-bit DMA mask\n");
+ goto out;
+ }
+
err = pci_request_regions(dev, "solos");
if (err) {
dev_warn(&dev->dev, "Failed to request regions\n");
@@ -611,17 +1082,13 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
goto out_unmap_config;
}
-// for(i=0;i<64 ;i+=4){
-// data32=ioread32(card->buffers + i);
-// dev_dbg(&card->dev->dev, "%08lX\n",(unsigned long)data32);
-// }
-
- //Fill Config Mem with zeros
- for(i = 0; i < 128; i += 4)
- iowrite32(0, card->config_regs + i);
+ if (reset) {
+ iowrite32(1, card->config_regs + FPGA_MODE);
+ data32 = ioread32(card->config_regs + FPGA_MODE);
- //Set RX empty flags
- iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
+ iowrite32(0, card->config_regs + FPGA_MODE);
+ data32 = ioread32(card->config_regs + FPGA_MODE);
+ }
data32 = ioread32(card->config_regs + FPGA_VER);
fpga_ver = (data32 & 0x0000FFFF);
@@ -630,55 +1097,53 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n",
major_ver, minor_ver, fpga_ver);
- card->nr_ports = 2; /* FIXME: Detect daughterboard */
+ if (0 && fpga_ver > 27)
+ card->using_dma = 1;
+ else {
+ /* Set RX empty flag for all ports */
+ iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
+ }
- err = atm_init(card);
- if (err)
- goto out_unmap_both;
+ data32 = ioread32(card->config_regs + PORTS);
+ card->nr_ports = (data32 & 0x000000FF);
pci_set_drvdata(dev, card);
+
tasklet_init(&card->tlet, solos_bh, (unsigned long)card);
spin_lock_init(&card->tx_lock);
spin_lock_init(&card->tx_queue_lock);
spin_lock_init(&card->cli_queue_lock);
-/*
- // Set Loopback mode
- data32 = 0x00010000;
- iowrite32(data32,card->config_regs + FLAGS_ADDR);
-*/
-/*
- // Fill Buffers with zeros
- for (i = 0; i < BUF_SIZE * 8; i += 4)
- iowrite32(0, card->buffers + i);
-*/
-/*
- for(i = 0; i < (BUF_SIZE * 1); i += 4)
- iowrite32(0x12345678, card->buffers + i + (0*BUF_SIZE));
- for(i = 0; i < (BUF_SIZE * 1); i += 4)
- iowrite32(0xabcdef98, card->buffers + i + (1*BUF_SIZE));
-
- // Read Config Memory
- printk(KERN_DEBUG "Reading Config MEM\n");
- i = 0;
- for(i = 0; i < 16; i++) {
- data32=ioread32(card->buffers + i*(BUF_SIZE/2));
- printk(KERN_ALERT "Addr: %lX Data: %08lX\n",
- (unsigned long)(addr_start + i*(BUF_SIZE/2)),
- (unsigned long)data32);
- }
-*/
- //dev_dbg(&card->dev->dev, "Requesting IRQ: %d\n",dev->irq);
- err = request_irq(dev->irq, solos_irq, IRQF_DISABLED|IRQF_SHARED,
+ spin_lock_init(&card->param_queue_lock);
+ INIT_LIST_HEAD(&card->param_queue);
+
+ err = request_irq(dev->irq, solos_irq, IRQF_SHARED,
"solos-pci", card);
- if (err)
+ if (err) {
dev_dbg(&card->dev->dev, "Failed to request interrupt IRQ: %d\n", dev->irq);
+ goto out_unmap_both;
+ }
- // Enable IRQs
iowrite32(1, card->config_regs + IRQ_EN_ADDR);
+ if (fpga_upgrade)
+ flash_upgrade(card, 0);
+
+ if (firmware_upgrade)
+ flash_upgrade(card, 1);
+
+ err = atm_init(card);
+ if (err)
+ goto out_free_irq;
+
return 0;
+ out_free_irq:
+ iowrite32(0, card->config_regs + IRQ_EN_ADDR);
+ free_irq(dev->irq, card);
+ tasklet_kill(&card->tlet);
+
out_unmap_both:
+ pci_set_drvdata(dev, NULL);
pci_iounmap(dev, card->config_regs);
out_unmap_config:
pci_iounmap(dev, card->buffers);
@@ -693,9 +1158,10 @@ static int atm_init(struct solos_card *card)
{
int i;
- opens = 0;
-
for (i = 0; i < card->nr_ports; i++) {
+ struct sk_buff *skb;
+ struct pkt_hdr *header;
+
skb_queue_head_init(&card->tx_queue[i]);
skb_queue_head_init(&card->cli_queue[i]);
@@ -707,6 +1173,8 @@ static int atm_init(struct solos_card *card)
}
if (device_create_file(&card->atmdev[i]->class_dev, &dev_attr_console))
dev_err(&card->dev->dev, "Could not register console for ATM device %d\n", i);
+ if (sysfs_create_group(&card->atmdev[i]->class_dev.kobj, &solos_attr_group))
+ dev_err(&card->dev->dev, "Could not register parameter group for ATM device %d\n", i);
dev_info(&card->dev->dev, "Registered ATM device %d\n", card->atmdev[i]->number);
@@ -714,6 +1182,22 @@ static int atm_init(struct solos_card *card)
card->atmdev[i]->ci_range.vci_bits = 16;
card->atmdev[i]->dev_data = card;
card->atmdev[i]->phy_data = (void *)(unsigned long)i;
+ card->atmdev[i]->signal = ATM_PHY_SIG_UNKNOWN;
+
+ skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
+ if (!skb) {
+ dev_warn(&card->dev->dev, "Failed to allocate sk_buff in atm_init()\n");
+ continue;
+ }
+
+ header = (void *)skb_put(skb, sizeof(*header));
+
+ header->size = cpu_to_le16(0);
+ header->vpi = cpu_to_le16(0);
+ header->vci = cpu_to_le16(0);
+ header->type = cpu_to_le16(PKT_STATUS);
+
+ fpga_queue(card, i, skb, NULL);
}
return 0;
}
@@ -724,8 +1208,28 @@ static void atm_remove(struct solos_card *card)
for (i = 0; i < card->nr_ports; i++) {
if (card->atmdev[i]) {
+ struct sk_buff *skb;
+
dev_info(&card->dev->dev, "Unregistering ATM device %d\n", card->atmdev[i]->number);
+
+ sysfs_remove_group(&card->atmdev[i]->class_dev.kobj, &solos_attr_group);
atm_dev_deregister(card->atmdev[i]);
+
+ skb = card->rx_skb[i];
+ if (skb) {
+ pci_unmap_single(card->dev, SKB_CB(skb)->dma_addr,
+ RX_DMA_SIZE, PCI_DMA_FROMDEVICE);
+ dev_kfree_skb(skb);
+ }
+ skb = card->tx_skb[i];
+ if (skb) {
+ pci_unmap_single(card->dev, SKB_CB(skb)->dma_addr,
+ skb->len, PCI_DMA_TODEVICE);
+ dev_kfree_skb(skb);
+ }
+ while ((skb = skb_dequeue(&card->tx_queue[i])))
+ dev_kfree_skb(skb);
+
}
}
}
@@ -733,31 +1237,31 @@ static void atm_remove(struct solos_card *card)
static void fpga_remove(struct pci_dev *dev)
{
struct solos_card *card = pci_get_drvdata(dev);
+
+ /* Disable IRQs */
+ iowrite32(0, card->config_regs + IRQ_EN_ADDR);
- if (debug)
- return;
+ /* Reset FPGA */
+ iowrite32(1, card->config_regs + FPGA_MODE);
+ (void)ioread32(card->config_regs + FPGA_MODE);
atm_remove(card);
- dev_vdbg(&dev->dev, "Freeing IRQ\n");
- // Disable IRQs from FPGA
- iowrite32(0, card->config_regs + IRQ_EN_ADDR);
free_irq(dev->irq, card);
tasklet_kill(&card->tlet);
- // iowrite32(0x01,pciregs);
- dev_vdbg(&dev->dev, "Unmapping PCI resource\n");
+ /* Release device from reset */
+ iowrite32(0, card->config_regs + FPGA_MODE);
+ (void)ioread32(card->config_regs + FPGA_MODE);
+
pci_iounmap(dev, card->buffers);
pci_iounmap(dev, card->config_regs);
- dev_vdbg(&dev->dev, "Releasing PCI Region\n");
pci_release_regions(dev);
pci_disable_device(dev);
pci_set_drvdata(dev, NULL);
kfree(card);
-// dev_dbg(&card->dev->dev, "fpga_remove\n");
- return;
}
static struct pci_device_id fpga_pci_tbl[] __devinitdata = {
diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
index 14b9d5f4c203..c07e725ea93d 100644
--- a/drivers/auxdisplay/Kconfig
+++ b/drivers/auxdisplay/Kconfig
@@ -6,7 +6,6 @@
#
menuconfig AUXDISPLAY
- depends on PARPORT
bool "Auxiliary Display support"
---help---
Say Y here to get to see options for auxiliary display drivers.
@@ -14,7 +13,7 @@ menuconfig AUXDISPLAY
If you say N, all options in this submenu will be skipped and disabled.
-if AUXDISPLAY && PARPORT
+if AUXDISPLAY
config KS0108
tristate "KS0108 LCD Controller"
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 9f50f1b545dc..ddc97496db4a 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -63,6 +63,32 @@ struct class_private {
#define to_class(obj) \
container_of(obj, struct class_private, class_subsys.kobj)
+/**
+ * struct device_private - structure to hold the private to the driver core portions of the device structure.
+ *
+ * @klist_children - klist containing all children of this device
+ * @knode_parent - node in sibling list
+ * @knode_driver - node in driver list
+ * @knode_bus - node in bus list
+ * @device - pointer back to the struct class that this structure is
+ * associated with.
+ *
+ * Nothing outside of the driver core should ever touch these fields.
+ */
+struct device_private {
+ struct klist klist_children;
+ struct klist_node knode_parent;
+ struct klist_node knode_driver;
+ struct klist_node knode_bus;
+ struct device *device;
+};
+#define to_device_private_parent(obj) \
+ container_of(obj, struct device_private, knode_parent)
+#define to_device_private_driver(obj) \
+ container_of(obj, struct device_private, knode_driver)
+#define to_device_private_bus(obj) \
+ container_of(obj, struct device_private, knode_bus)
+
/* initialisation functions */
extern int devices_init(void);
extern int buses_init(void);
@@ -86,6 +112,11 @@ extern void bus_remove_driver(struct device_driver *drv);
extern void driver_detach(struct device_driver *drv);
extern int driver_probe_device(struct device_driver *drv, struct device *dev);
+static inline int driver_match_device(struct device_driver *drv,
+ struct device *dev)
+{
+ return drv->bus->match && drv->bus->match(dev, drv);
+}
extern void sysdev_shutdown(void);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 83f32b891fa9..dc030f1f00f1 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -198,7 +198,7 @@ static ssize_t driver_bind(struct device_driver *drv,
int err = -ENODEV;
dev = bus_find_device_by_name(bus, NULL, buf);
- if (dev && dev->driver == NULL) {
+ if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
@@ -253,7 +253,14 @@ static ssize_t store_drivers_probe(struct bus_type *bus,
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
- return n ? container_of(n, struct device, knode_bus) : NULL;
+ struct device *dev = NULL;
+ struct device_private *dev_prv;
+
+ if (n) {
+ dev_prv = to_device_private_bus(n);
+ dev = dev_prv->device;
+ }
+ return dev;
}
/**
@@ -286,7 +293,7 @@ int bus_for_each_dev(struct bus_type *bus, struct device *start,
return -EINVAL;
klist_iter_init_node(&bus->p->klist_devices, &i,
- (start ? &start->knode_bus : NULL));
+ (start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
@@ -320,7 +327,7 @@ struct device *bus_find_device(struct bus_type *bus,
return NULL;
klist_iter_init_node(&bus->p->klist_devices, &i,
- (start ? &start->knode_bus : NULL));
+ (start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
break;
@@ -507,7 +514,8 @@ void bus_attach_device(struct device *dev)
ret = device_attach(dev);
WARN_ON(ret < 0);
if (ret >= 0)
- klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);
+ klist_add_tail(&dev->p->knode_bus,
+ &bus->p->klist_devices);
}
}
@@ -528,8 +536,8 @@ void bus_remove_device(struct device *dev)
sysfs_remove_link(&dev->bus->p->devices_kset->kobj,
dev_name(dev));
device_remove_attrs(dev->bus, dev);
- if (klist_node_attached(&dev->knode_bus))
- klist_del(&dev->knode_bus);
+ if (klist_node_attached(&dev->p->knode_bus))
+ klist_del(&dev->p->knode_bus);
pr_debug("bus: '%s': remove device %s\n",
dev->bus->name, dev_name(dev));
@@ -831,14 +839,16 @@ static void bus_remove_attrs(struct bus_type *bus)
static void klist_devices_get(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_bus);
+ struct device_private *dev_prv = to_device_private_bus(n);
+ struct device *dev = dev_prv->device;
get_device(dev);
}
static void klist_devices_put(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_bus);
+ struct device_private *dev_prv = to_device_private_bus(n);
+ struct device *dev = dev_prv->device;
put_device(dev);
}
@@ -932,6 +942,7 @@ bus_uevent_fail:
kset_unregister(&bus->p->subsys);
kfree(bus->p);
out:
+ bus->p = NULL;
return retval;
}
EXPORT_SYMBOL_GPL(bus_register);
@@ -953,6 +964,7 @@ void bus_unregister(struct bus_type *bus)
bus_remove_file(bus, &bus_attr_uevent);
kset_unregister(&bus->p->subsys);
kfree(bus->p);
+ bus->p = NULL;
}
EXPORT_SYMBOL_GPL(bus_unregister);
@@ -993,18 +1005,20 @@ static void device_insertion_sort_klist(struct device *a, struct list_head *list
{
struct list_head *pos;
struct klist_node *n;
+ struct device_private *dev_prv;
struct device *b;
list_for_each(pos, list) {
n = container_of(pos, struct klist_node, n_node);
- b = container_of(n, struct device, knode_bus);
+ dev_prv = to_device_private_bus(n);
+ b = dev_prv->device;
if (compare(a, b) <= 0) {
- list_move_tail(&a->knode_bus.n_node,
- &b->knode_bus.n_node);
+ list_move_tail(&a->p->knode_bus.n_node,
+ &b->p->knode_bus.n_node);
return;
}
}
- list_move_tail(&a->knode_bus.n_node, list);
+ list_move_tail(&a->p->knode_bus.n_node, list);
}
void bus_sort_breadthfirst(struct bus_type *bus,
@@ -1014,6 +1028,7 @@ void bus_sort_breadthfirst(struct bus_type *bus,
LIST_HEAD(sorted_devices);
struct list_head *pos, *tmp;
struct klist_node *n;
+ struct device_private *dev_prv;
struct device *dev;
struct klist *device_klist;
@@ -1022,7 +1037,8 @@ void bus_sort_breadthfirst(struct bus_type *bus,
spin_lock(&device_klist->k_lock);
list_for_each_safe(pos, tmp, &device_klist->k_list) {
n = container_of(pos, struct klist_node, n_node);
- dev = container_of(n, struct device, knode_bus);
+ dev_prv = to_device_private_bus(n);
+ dev = dev_prv->device;
device_insertion_sort_klist(dev, &sorted_devices, compare);
}
list_splice(&sorted_devices, &device_klist->k_list);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index f3eae630e589..e73c92d13a23 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -109,6 +109,7 @@ static struct sysfs_ops dev_sysfs_ops = {
static void device_release(struct kobject *kobj)
{
struct device *dev = to_dev(kobj);
+ struct device_private *p = dev->p;
if (dev->release)
dev->release(dev);
@@ -120,6 +121,7 @@ static void device_release(struct kobject *kobj)
WARN(1, KERN_ERR "Device '%s' does not have a release() "
"function, it is broken and must be fixed.\n",
dev_name(dev));
+ kfree(p);
}
static struct kobj_type device_ktype = {
@@ -134,8 +136,6 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
if (ktype == &device_ktype) {
struct device *dev = to_dev(kobj);
- if (dev->uevent_suppress)
- return 0;
if (dev->bus)
return 1;
if (dev->class)
@@ -507,14 +507,16 @@ EXPORT_SYMBOL_GPL(device_schedule_callback_owner);
static void klist_children_get(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_parent);
+ struct device_private *p = to_device_private_parent(n);
+ struct device *dev = p->device;
get_device(dev);
}
static void klist_children_put(struct klist_node *n)
{
- struct device *dev = container_of(n, struct device, knode_parent);
+ struct device_private *p = to_device_private_parent(n);
+ struct device *dev = p->device;
put_device(dev);
}
@@ -538,8 +540,6 @@ void device_initialize(struct device *dev)
{
dev->kobj.kset = devices_kset;
kobject_init(&dev->kobj, &device_ktype);
- klist_init(&dev->klist_children, klist_children_get,
- klist_children_put);
INIT_LIST_HEAD(&dev->dma_pools);
init_MUTEX(&dev->sem);
spin_lock_init(&dev->devres_lock);
@@ -777,17 +777,12 @@ static void device_remove_class_symlinks(struct device *dev)
int dev_set_name(struct device *dev, const char *fmt, ...)
{
va_list vargs;
- char *s;
+ int err;
va_start(vargs, fmt);
- vsnprintf(dev->bus_id, sizeof(dev->bus_id), fmt, vargs);
+ err = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
va_end(vargs);
-
- /* ewww... some of these buggers have / in the name... */
- while ((s = strchr(dev->bus_id, '/')))
- *s = '!';
-
- return 0;
+ return err;
}
EXPORT_SYMBOL_GPL(dev_set_name);
@@ -864,12 +859,26 @@ int device_add(struct device *dev)
if (!dev)
goto done;
- /* Temporarily support init_name if it is set.
- * It will override bus_id for now */
- if (dev->init_name)
- dev_set_name(dev, "%s", dev->init_name);
+ dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
+ if (!dev->p) {
+ error = -ENOMEM;
+ goto done;
+ }
+ dev->p->device = dev;
+ klist_init(&dev->p->klist_children, klist_children_get,
+ klist_children_put);
+
+ /*
+ * for statically allocated devices, which should all be converted
+ * some day, we need to initialize the name. We prevent reading back
+ * the name, and force the use of dev_name()
+ */
+ if (dev->init_name) {
+ dev_set_name(dev, dev->init_name);
+ dev->init_name = NULL;
+ }
- if (!strlen(dev->bus_id))
+ if (!dev_name(dev))
goto done;
pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
@@ -928,7 +937,8 @@ int device_add(struct device *dev)
kobject_uevent(&dev->kobj, KOBJ_ADD);
bus_attach_device(dev);
if (parent)
- klist_add_tail(&dev->knode_parent, &parent->klist_children);
+ klist_add_tail(&dev->p->knode_parent,
+ &parent->p->klist_children);
if (dev->class) {
mutex_lock(&dev->class->p->class_mutex);
@@ -1042,7 +1052,7 @@ void device_del(struct device *dev)
device_pm_remove(dev);
dpm_sysfs_remove(dev);
if (parent)
- klist_del(&dev->knode_parent);
+ klist_del(&dev->p->knode_parent);
if (MAJOR(dev->devt)) {
device_remove_sys_dev_entry(dev);
device_remove_file(dev, &devt_attr);
@@ -1103,7 +1113,14 @@ void device_unregister(struct device *dev)
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
- return n ? container_of(n, struct device, knode_parent) : NULL;
+ struct device *dev = NULL;
+ struct device_private *p;
+
+ if (n) {
+ p = to_device_private_parent(n);
+ dev = p->device;
+ }
+ return dev;
}
/**
@@ -1125,7 +1142,7 @@ int device_for_each_child(struct device *parent, void *data,
struct device *child;
int error = 0;
- klist_iter_init(&parent->klist_children, &i);
+ klist_iter_init(&parent->p->klist_children, &i);
while ((child = next_device(&i)) && !error)
error = fn(child, data);
klist_iter_exit(&i);
@@ -1156,7 +1173,7 @@ struct device *device_find_child(struct device *parent, void *data,
if (!parent)
return NULL;
- klist_iter_init(&parent->klist_children, &i);
+ klist_iter_init(&parent->p->klist_children, &i);
while ((child = next_device(&i)))
if (match(child, data) && get_device(child))
break;
@@ -1348,7 +1365,10 @@ struct device *device_create_vargs(struct class *class, struct device *parent,
dev->release = device_create_release;
dev_set_drvdata(dev, drvdata);
- vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args);
+ retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
+ if (retval)
+ goto error;
+
retval = device_register(dev);
if (retval)
goto error;
@@ -1452,19 +1472,15 @@ int device_rename(struct device *dev, char *new_name)
old_class_name = make_class_name(dev->class->name, &dev->kobj);
#endif
- old_device_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL);
+ old_device_name = kstrdup(dev_name(dev), GFP_KERNEL);
if (!old_device_name) {
error = -ENOMEM;
goto out;
}
- strlcpy(old_device_name, dev->bus_id, BUS_ID_SIZE);
- strlcpy(dev->bus_id, new_name, BUS_ID_SIZE);
error = kobject_rename(&dev->kobj, new_name);
- if (error) {
- strlcpy(dev->bus_id, old_device_name, BUS_ID_SIZE);
+ if (error)
goto out;
- }
#ifdef CONFIG_SYSFS_DEPRECATED
if (old_class_name) {
@@ -1545,8 +1561,10 @@ out:
* device_move - moves a device to a new parent
* @dev: the pointer to the struct device to be moved
* @new_parent: the new parent of the device (can by NULL)
+ * @dpm_order: how to reorder the dpm_list
*/
-int device_move(struct device *dev, struct device *new_parent)
+int device_move(struct device *dev, struct device *new_parent,
+ enum dpm_order dpm_order)
{
int error;
struct device *old_parent;
@@ -1556,6 +1574,7 @@ int device_move(struct device *dev, struct device *new_parent)
if (!dev)
return -EINVAL;
+ device_pm_lock();
new_parent = get_device(new_parent);
new_parent_kobj = get_device_parent(dev, new_parent);
@@ -1570,9 +1589,10 @@ int device_move(struct device *dev, struct device *new_parent)
old_parent = dev->parent;
dev->parent = new_parent;
if (old_parent)
- klist_remove(&dev->knode_parent);
+ klist_remove(&dev->p->knode_parent);
if (new_parent) {
- klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
+ klist_add_tail(&dev->p->knode_parent,
+ &new_parent->p->klist_children);
set_dev_node(dev, dev_to_node(new_parent));
}
@@ -1584,11 +1604,11 @@ int device_move(struct device *dev, struct device *new_parent)
device_move_class_links(dev, new_parent, old_parent);
if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
if (new_parent)
- klist_remove(&dev->knode_parent);
+ klist_remove(&dev->p->knode_parent);
dev->parent = old_parent;
if (old_parent) {
- klist_add_tail(&dev->knode_parent,
- &old_parent->klist_children);
+ klist_add_tail(&dev->p->knode_parent,
+ &old_parent->p->klist_children);
set_dev_node(dev, dev_to_node(old_parent));
}
}
@@ -1596,9 +1616,23 @@ int device_move(struct device *dev, struct device *new_parent)
put_device(new_parent);
goto out;
}
+ switch (dpm_order) {
+ case DPM_ORDER_NONE:
+ break;
+ case DPM_ORDER_DEV_AFTER_PARENT:
+ device_pm_move_after(dev, new_parent);
+ break;
+ case DPM_ORDER_PARENT_BEFORE_DEV:
+ device_pm_move_before(new_parent, dev);
+ break;
+ case DPM_ORDER_DEV_LAST:
+ device_pm_move_last(dev);
+ break;
+ }
out_put:
put_device(old_parent);
out:
+ device_pm_unlock();
put_device(dev);
return error;
}
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 5b257a57bc57..e62a4ccea54d 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -119,7 +119,7 @@ static ssize_t print_cpus_map(char *buf, const struct cpumask *map)
#define print_cpus_func(type) \
static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \
{ \
- return print_cpus_map(buf, &cpu_##type##_map); \
+ return print_cpus_map(buf, cpu_##type##_mask); \
} \
static struct sysdev_class_attribute attr_##type##_map = \
_SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 135231239103..f17c3266a0e0 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -30,7 +30,7 @@
static void driver_bound(struct device *dev)
{
- if (klist_node_attached(&dev->knode_driver)) {
+ if (klist_node_attached(&dev->p->knode_driver)) {
printk(KERN_WARNING "%s: device %s already bound\n",
__func__, kobject_name(&dev->kobj));
return;
@@ -43,7 +43,7 @@ static void driver_bound(struct device *dev)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_BOUND_DRIVER, dev);
- klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices);
+ klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
}
static int driver_sysfs_add(struct device *dev)
@@ -172,16 +172,12 @@ int driver_probe_done(void)
/**
* wait_for_device_probe
* Wait for device probing to be completed.
- *
- * Note: this function polls at 100 msec intervals.
*/
-int wait_for_device_probe(void)
+void wait_for_device_probe(void)
{
/* wait for the known devices to complete their probing */
- while (driver_probe_done() != 0)
- msleep(100);
+ wait_event(probe_waitqueue, atomic_read(&probe_count) == 0);
async_synchronize_full();
- return 0;
}
/**
@@ -189,14 +185,8 @@ int wait_for_device_probe(void)
* @drv: driver to bind a device to
* @dev: device to try to bind to the driver
*
- * First, we call the bus's match function, if one present, which should
- * compare the device IDs the driver supports with the device IDs of the
- * device. Note we don't do this ourselves because we don't know the
- * format of the ID structures, nor what is to be considered a match and
- * what is not.
- *
- * This function returns 1 if a match is found, -ENODEV if the device is
- * not registered, and 0 otherwise.
+ * This function returns -ENODEV if the device is not registered,
+ * 1 if the device is bound sucessfully and 0 otherwise.
*
* This function must be called with @dev->sem held. When called for a
* USB interface, @dev->parent->sem must be held as well.
@@ -207,21 +197,22 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
if (!device_is_registered(dev))
return -ENODEV;
- if (drv->bus->match && !drv->bus->match(dev, drv))
- goto done;
pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
drv->bus->name, __func__, dev_name(dev), drv->name);
ret = really_probe(dev, drv);
-done:
return ret;
}
static int __device_attach(struct device_driver *drv, void *data)
{
struct device *dev = data;
+
+ if (!driver_match_device(drv, dev))
+ return 0;
+
return driver_probe_device(drv, dev);
}
@@ -274,7 +265,7 @@ static int __driver_attach(struct device *dev, void *data)
* is an error.
*/
- if (drv->bus->match && !drv->bus->match(dev, drv))
+ if (!driver_match_device(drv, dev))
return 0;
if (dev->parent) /* Needed for USB */
@@ -327,7 +318,7 @@ static void __device_release_driver(struct device *dev)
drv->remove(dev);
devres_release_all(dev);
dev->driver = NULL;
- klist_remove(&dev->knode_driver);
+ klist_remove(&dev->p->knode_driver);
}
}
@@ -357,6 +348,7 @@ EXPORT_SYMBOL_GPL(device_release_driver);
*/
void driver_detach(struct device_driver *drv)
{
+ struct device_private *dev_prv;
struct device *dev;
for (;;) {
@@ -365,8 +357,10 @@ void driver_detach(struct device_driver *drv)
spin_unlock(&drv->p->klist_devices.k_lock);
break;
}
- dev = list_entry(drv->p->klist_devices.k_list.prev,
- struct device, knode_driver.n_node);
+ dev_prv = list_entry(drv->p->klist_devices.k_list.prev,
+ struct device_private,
+ knode_driver.n_node);
+ dev = dev_prv->device;
get_device(dev);
spin_unlock(&drv->p->klist_devices.k_lock);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 1e2bda780e48..c51f11bb29ae 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -19,7 +19,14 @@
static struct device *next_device(struct klist_iter *i)
{
struct klist_node *n = klist_next(i);
- return n ? container_of(n, struct device, knode_driver) : NULL;
+ struct device *dev = NULL;
+ struct device_private *dev_prv;
+
+ if (n) {
+ dev_prv = to_device_private_driver(n);
+ dev = dev_prv->device;
+ }
+ return dev;
}
/**
@@ -42,7 +49,7 @@ int driver_for_each_device(struct device_driver *drv, struct device *start,
return -EINVAL;
klist_iter_init_node(&drv->p->klist_devices, &i,
- start ? &start->knode_driver : NULL);
+ start ? &start->p->knode_driver : NULL);
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
@@ -76,7 +83,7 @@ struct device *driver_find_device(struct device_driver *drv,
return NULL;
klist_iter_init_node(&drv->p->klist_devices, &i,
- (start ? &start->knode_driver : NULL));
+ (start ? &start->p->knode_driver : NULL));
while ((dev = next_device(&i)))
if (match(dev, data) && get_device(dev))
break;
@@ -216,6 +223,8 @@ int driver_register(struct device_driver *drv)
int ret;
struct device_driver *other;
+ BUG_ON(!drv->bus->p);
+
if ((drv->bus->probe && drv->probe) ||
(drv->bus->remove && drv->remove) ||
(drv->bus->shutdown && drv->shutdown))
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 44699d9dd85c..d3a59c688fe4 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -319,7 +319,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
f_dev->parent = device;
f_dev->class = &firmware_class;
dev_set_drvdata(f_dev, fw_priv);
- f_dev->uevent_suppress = 1;
+ dev_set_uevent_suppress(f_dev, 1);
retval = device_register(f_dev);
if (retval) {
dev_err(device, "%s: device_register failed\n", __func__);
@@ -366,7 +366,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
}
if (uevent)
- f_dev->uevent_suppress = 0;
+ dev_set_uevent_suppress(f_dev, 0);
*dev_p = f_dev;
goto out;
diff --git a/drivers/base/iommu.c b/drivers/base/iommu.c
index 5e039d4f877c..9f0e672f4be8 100644
--- a/drivers/base/iommu.c
+++ b/drivers/base/iommu.c
@@ -31,7 +31,7 @@ void register_iommu(struct iommu_ops *ops)
iommu_ops = ops;
}
-bool iommu_found()
+bool iommu_found(void)
{
return iommu_ops != NULL;
}
@@ -98,3 +98,10 @@ phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
return iommu_ops->iova_to_phys(domain, iova);
}
EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
+
+int iommu_domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap)
+{
+ return iommu_ops->domain_has_cap(domain, cap);
+}
+EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
diff --git a/drivers/base/node.c b/drivers/base/node.c
index f8f578a71b25..40b809742a1c 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -24,7 +24,7 @@ static struct sysdev_class node_class = {
static ssize_t node_read_cpumap(struct sys_device *dev, int type, char *buf)
{
struct node *node_dev = to_node(dev);
- node_to_cpumask_ptr(mask, node_dev->sysdev.id);
+ const struct cpumask *mask = cpumask_of_node(node_dev->sysdev.id);
int len;
/* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 349a1013603f..d2198f64ad4e 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -217,6 +217,7 @@ int platform_device_add_data(struct platform_device *pdev, const void *data,
if (d) {
memcpy(d, data, size);
pdev->dev.platform_data = d;
+ pdev->platform_data = d;
}
return d ? 0 : -ENOMEM;
}
@@ -246,6 +247,21 @@ int platform_device_add(struct platform_device *pdev)
else
dev_set_name(&pdev->dev, pdev->name);
+ /* We will remove platform_data field from struct device
+ * if all platform devices pass its platform specific data
+ * from platform_device. The conversion is going to be a
+ * long time, so we allow the two cases coexist to make
+ * this kind of fix more easily*/
+ if (pdev->platform_data && pdev->dev.platform_data) {
+ printk(KERN_ERR
+ "%s: use which platform_data?\n",
+ dev_name(&pdev->dev));
+ } else if (pdev->platform_data) {
+ pdev->dev.platform_data = pdev->platform_data;
+ } else if (pdev->dev.platform_data) {
+ pdev->platform_data = pdev->dev.platform_data;
+ }
+
for (i = 0; i < pdev->num_resources; i++) {
struct resource *p, *r = &pdev->resource[i];
@@ -584,10 +600,25 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct platform_device *pdev = to_platform_device(dev);
- add_uevent_var(env, "MODALIAS=platform:%s", pdev->name);
+ add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
+ (pdev->id_entry) ? pdev->id_entry->name : pdev->name);
return 0;
}
+static const struct platform_device_id *platform_match_id(
+ struct platform_device_id *id,
+ struct platform_device *pdev)
+{
+ while (id->name[0]) {
+ if (strcmp(pdev->name, id->name) == 0) {
+ pdev->id_entry = id;
+ return id;
+ }
+ id++;
+ }
+ return NULL;
+}
+
/**
* platform_match - bind platform device to platform driver.
* @dev: device.
@@ -603,9 +634,14 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
*/
static int platform_match(struct device *dev, struct device_driver *drv)
{
- struct platform_device *pdev;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct platform_driver *pdrv = to_platform_driver(drv);
- pdev = container_of(dev, struct platform_device, dev);
+ /* match against the id table first */
+ if (pdrv->id_table)
+ return platform_match_id(pdrv->id_table, pdev) != NULL;
+
+ /* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
}
@@ -623,26 +659,24 @@ static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg)
{
- struct platform_driver *drv = to_platform_driver(dev->driver);
- struct platform_device *pdev;
+ struct platform_driver *pdrv = to_platform_driver(dev->driver);
+ struct platform_device *pdev = to_platform_device(dev);
int ret = 0;
- pdev = container_of(dev, struct platform_device, dev);
- if (dev->driver && drv->suspend_late)
- ret = drv->suspend_late(pdev, mesg);
+ if (dev->driver && pdrv->suspend_late)
+ ret = pdrv->suspend_late(pdev, mesg);
return ret;
}
static int platform_legacy_resume_early(struct device *dev)
{
- struct platform_driver *drv = to_platform_driver(dev->driver);
- struct platform_device *pdev;
+ struct platform_driver *pdrv = to_platform_driver(dev->driver);
+ struct platform_device *pdev = to_platform_device(dev);
int ret = 0;
- pdev = container_of(dev, struct platform_device, dev);
- if (dev->driver && drv->resume_early)
- ret = drv->resume_early(pdev);
+ if (dev->driver && pdrv->resume_early)
+ ret = pdrv->resume_early(pdev);
return ret;
}
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 2d14f4ae6c01..69b4ddb7de3b 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -23,6 +23,7 @@
#include <linux/pm.h>
#include <linux/resume-trace.h>
#include <linux/rwsem.h>
+#include <linux/interrupt.h>
#include "../base.h"
#include "power.h"
@@ -107,6 +108,50 @@ void device_pm_remove(struct device *dev)
}
/**
+ * device_pm_move_before - move device in dpm_list
+ * @deva: Device to move in dpm_list
+ * @devb: Device @deva should come before
+ */
+void device_pm_move_before(struct device *deva, struct device *devb)
+{
+ pr_debug("PM: Moving %s:%s before %s:%s\n",
+ deva->bus ? deva->bus->name : "No Bus",
+ kobject_name(&deva->kobj),
+ devb->bus ? devb->bus->name : "No Bus",
+ kobject_name(&devb->kobj));
+ /* Delete deva from dpm_list and reinsert before devb. */
+ list_move_tail(&deva->power.entry, &devb->power.entry);
+}
+
+/**
+ * device_pm_move_after - move device in dpm_list
+ * @deva: Device to move in dpm_list
+ * @devb: Device @deva should come after
+ */
+void device_pm_move_after(struct device *deva, struct device *devb)
+{
+ pr_debug("PM: Moving %s:%s after %s:%s\n",
+ deva->bus ? deva->bus->name : "No Bus",
+ kobject_name(&deva->kobj),
+ devb->bus ? devb->bus->name : "No Bus",
+ kobject_name(&devb->kobj));
+ /* Delete deva from dpm_list and reinsert after devb. */
+ list_move(&deva->power.entry, &devb->power.entry);
+}
+
+/**
+ * device_pm_move_last - move device to end of dpm_list
+ * @dev: Device to move in dpm_list
+ */
+void device_pm_move_last(struct device *dev)
+{
+ pr_debug("PM: Moving %s:%s to end of list\n",
+ dev->bus ? dev->bus->name : "No Bus",
+ kobject_name(&dev->kobj));
+ list_move_tail(&dev->power.entry, &dpm_list);
+}
+
+/**
* pm_op - execute the PM operation appropiate for given PM event
* @dev: Device.
* @ops: PM operations to choose from.
@@ -305,7 +350,8 @@ static int resume_device_noirq(struct device *dev, pm_message_t state)
* Execute the appropriate "noirq resume" callback for all devices marked
* as DPM_OFF_IRQ.
*
- * Must be called with interrupts disabled and only one CPU running.
+ * Must be called under dpm_list_mtx. Device drivers should not receive
+ * interrupts while it's being executed.
*/
static void dpm_power_up(pm_message_t state)
{
@@ -326,14 +372,13 @@ static void dpm_power_up(pm_message_t state)
* device_power_up - Turn on all devices that need special attention.
* @state: PM transition of the system being carried out.
*
- * Power on system devices, then devices that required we shut them down
- * with interrupts disabled.
- *
- * Must be called with interrupts disabled.
+ * Call the "early" resume handlers and enable device drivers to receive
+ * interrupts.
*/
void device_power_up(pm_message_t state)
{
dpm_power_up(state);
+ resume_device_irqs();
}
EXPORT_SYMBOL_GPL(device_power_up);
@@ -558,16 +603,17 @@ static int suspend_device_noirq(struct device *dev, pm_message_t state)
* device_power_down - Shut down special devices.
* @state: PM transition of the system being carried out.
*
- * Power down devices that require interrupts to be disabled.
- * Then power down system devices.
+ * Prevent device drivers from receiving interrupts and call the "late"
+ * suspend handlers.
*
- * Must be called with interrupts disabled and only one CPU running.
+ * Must be called under dpm_list_mtx.
*/
int device_power_down(pm_message_t state)
{
struct device *dev;
int error = 0;
+ suspend_device_irqs();
list_for_each_entry_reverse(dev, &dpm_list, power.entry) {
error = suspend_device_noirq(dev, state);
if (error) {
@@ -577,7 +623,7 @@ int device_power_down(pm_message_t state)
dev->power.status = DPM_OFF_IRQ;
}
if (error)
- dpm_power_up(resume_event(state));
+ device_power_up(resume_event(state));
return error;
}
EXPORT_SYMBOL_GPL(device_power_down);
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index 41f51fae042f..c7cb4fc3735c 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -18,11 +18,19 @@ static inline struct device *to_device(struct list_head *entry)
extern void device_pm_add(struct device *);
extern void device_pm_remove(struct device *);
+extern void device_pm_move_before(struct device *, struct device *);
+extern void device_pm_move_after(struct device *, struct device *);
+extern void device_pm_move_last(struct device *);
#else /* CONFIG_PM_SLEEP */
static inline void device_pm_add(struct device *dev) {}
static inline void device_pm_remove(struct device *dev) {}
+static inline void device_pm_move_before(struct device *deva,
+ struct device *devb) {}
+static inline void device_pm_move_after(struct device *deva,
+ struct device *devb) {}
+static inline void device_pm_move_last(struct device *dev) {}
#endif
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index b428c8c4bc64..3236b434b964 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -22,6 +22,7 @@
#include <linux/pm.h>
#include <linux/device.h>
#include <linux/mutex.h>
+#include <linux/interrupt.h>
#include "base.h"
@@ -30,10 +31,10 @@
static ssize_t
-sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
+sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer)
{
- struct sys_device * sysdev = to_sysdev(kobj);
- struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
+ struct sys_device *sysdev = to_sysdev(kobj);
+ struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
if (sysdev_attr->show)
return sysdev_attr->show(sysdev, sysdev_attr, buffer);
@@ -42,11 +43,11 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
static ssize_t
-sysdev_store(struct kobject * kobj, struct attribute * attr,
- const char * buffer, size_t count)
+sysdev_store(struct kobject *kobj, struct attribute *attr,
+ const char *buffer, size_t count)
{
- struct sys_device * sysdev = to_sysdev(kobj);
- struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
+ struct sys_device *sysdev = to_sysdev(kobj);
+ struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr);
if (sysdev_attr->store)
return sysdev_attr->store(sysdev, sysdev_attr, buffer, count);
@@ -63,13 +64,13 @@ static struct kobj_type ktype_sysdev = {
};
-int sysdev_create_file(struct sys_device * s, struct sysdev_attribute * a)
+int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a)
{
return sysfs_create_file(&s->kobj, &a->attr);
}
-void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a)
+void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a)
{
sysfs_remove_file(&s->kobj, &a->attr);
}
@@ -84,7 +85,7 @@ EXPORT_SYMBOL_GPL(sysdev_remove_file);
static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
char *buffer)
{
- struct sysdev_class * class = to_sysdev_class(kobj);
+ struct sysdev_class *class = to_sysdev_class(kobj);
struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
if (class_attr->show)
@@ -95,8 +96,8 @@ static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr,
const char *buffer, size_t count)
{
- struct sysdev_class * class = to_sysdev_class(kobj);
- struct sysdev_class_attribute * class_attr = to_sysdev_class_attr(attr);
+ struct sysdev_class *class = to_sysdev_class(kobj);
+ struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
if (class_attr->store)
return class_attr->store(class, buffer, count);
@@ -128,7 +129,7 @@ EXPORT_SYMBOL_GPL(sysdev_class_remove_file);
static struct kset *system_kset;
-int sysdev_class_register(struct sysdev_class * cls)
+int sysdev_class_register(struct sysdev_class *cls)
{
pr_debug("Registering sysdev class '%s'\n", cls->name);
@@ -141,7 +142,7 @@ int sysdev_class_register(struct sysdev_class * cls)
return kset_register(&cls->kset);
}
-void sysdev_class_unregister(struct sysdev_class * cls)
+void sysdev_class_unregister(struct sysdev_class *cls)
{
pr_debug("Unregistering sysdev class '%s'\n",
kobject_name(&cls->kset.kobj));
@@ -203,8 +204,8 @@ int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv)
* @cls: Class driver belongs to.
* @drv: Driver.
*/
-void sysdev_driver_unregister(struct sysdev_class * cls,
- struct sysdev_driver * drv)
+void sysdev_driver_unregister(struct sysdev_class *cls,
+ struct sysdev_driver *drv)
{
mutex_lock(&sysdev_drivers_lock);
list_del_init(&drv->entry);
@@ -229,10 +230,10 @@ EXPORT_SYMBOL_GPL(sysdev_driver_unregister);
* @sysdev: device in question
*
*/
-int sysdev_register(struct sys_device * sysdev)
+int sysdev_register(struct sys_device *sysdev)
{
int error;
- struct sysdev_class * cls = sysdev->cls;
+ struct sysdev_class *cls = sysdev->cls;
if (!cls)
return -EINVAL;
@@ -252,7 +253,7 @@ int sysdev_register(struct sys_device * sysdev)
sysdev->id);
if (!error) {
- struct sysdev_driver * drv;
+ struct sysdev_driver *drv;
pr_debug("Registering sys device '%s'\n",
kobject_name(&sysdev->kobj));
@@ -274,9 +275,9 @@ int sysdev_register(struct sys_device * sysdev)
return error;
}
-void sysdev_unregister(struct sys_device * sysdev)
+void sysdev_unregister(struct sys_device *sysdev)
{
- struct sysdev_driver * drv;
+ struct sysdev_driver *drv;
mutex_lock(&sysdev_drivers_lock);
list_for_each_entry(drv, &sysdev->cls->drivers, entry) {
@@ -299,25 +300,25 @@ void sysdev_unregister(struct sys_device * sysdev)
* and the class driver.
*
* Note: The list is iterated in reverse order, so that we shut down
- * child devices before we shut down thier parents. The list ordering
+ * child devices before we shut down their parents. The list ordering
* is guaranteed by virtue of the fact that child devices are registered
* after their parents.
*/
void sysdev_shutdown(void)
{
- struct sysdev_class * cls;
+ struct sysdev_class *cls;
pr_debug("Shutting Down System Devices\n");
mutex_lock(&sysdev_drivers_lock);
list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
- struct sys_device * sysdev;
+ struct sys_device *sysdev;
pr_debug("Shutting down type '%s':\n",
kobject_name(&cls->kset.kobj));
list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
- struct sysdev_driver * drv;
+ struct sysdev_driver *drv;
pr_debug(" %s\n", kobject_name(&sysdev->kobj));
/* Call auxillary drivers first */
@@ -364,11 +365,18 @@ static void __sysdev_resume(struct sys_device *dev)
*/
int sysdev_suspend(pm_message_t state)
{
- struct sysdev_class * cls;
+ struct sysdev_class *cls;
struct sys_device *sysdev, *err_dev;
struct sysdev_driver *drv, *err_drv;
int ret;
+ pr_debug("Checking wake-up interrupts\n");
+
+ /* Return error code if there are any wake-up interrupts pending */
+ ret = check_wakeup_irqs();
+ if (ret)
+ return ret;
+
pr_debug("Suspending System Devices\n");
list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
@@ -442,12 +450,12 @@ EXPORT_SYMBOL_GPL(sysdev_suspend);
*/
int sysdev_resume(void)
{
- struct sysdev_class * cls;
+ struct sysdev_class *cls;
pr_debug("Resuming System Devices\n");
list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) {
- struct sys_device * sysdev;
+ struct sys_device *sysdev;
pr_debug("Resuming type '%s':\n",
kobject_name(&cls->kset.kobj));
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 0344a8a8321d..e7b8aa0cb47c 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -45,6 +45,13 @@ config MAC_FLOPPY
If you have a SWIM-3 (Super Woz Integrated Machine 3; from Apple)
floppy controller, say Y here. Most commonly found in PowerMacs.
+config BLK_DEV_SWIM
+ tristate "Support for SWIM Macintosh floppy"
+ depends on M68K && MAC
+ help
+ You should select this option if you want floppy support
+ and you don't have a II, IIfx, Q900, Q950 or AV series.
+
config AMIGA_Z2RAM
tristate "Amiga Zorro II ramdisk support"
depends on ZORRO
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 87e120e0a79c..3145141cef72 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -6,6 +6,7 @@
#
obj-$(CONFIG_MAC_FLOPPY) += swim3.o
+obj-$(CONFIG_BLK_DEV_SWIM) += swim_mod.o
obj-$(CONFIG_BLK_DEV_FD) += floppy.o
obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o
obj-$(CONFIG_PS3_DISK) += ps3disk.o
@@ -33,3 +34,5 @@ obj-$(CONFIG_BLK_DEV_UB) += ub.o
obj-$(CONFIG_BLK_DEV_HD) += hd.o
obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o
+
+swim_mod-objs := swim.o swim_asm.o
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 45c5a33daf49..31693bc24444 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -4,6 +4,7 @@
* Filesystem request handling methods
*/
+#include <linux/ata.h>
#include <linux/hdreg.h>
#include <linux/blkdev.h>
#include <linux/skbuff.h>
@@ -267,7 +268,7 @@ aoecmd_ata_rw(struct aoedev *d)
writebit = 0;
}
- ah->cmdstat = WIN_READ | writebit | extbit;
+ ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit;
/* mark all tracking fields and load out */
buf->nframesout += 1;
@@ -362,10 +363,10 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
switch (ah->cmdstat) {
default:
break;
- case WIN_READ:
- case WIN_READ_EXT:
- case WIN_WRITE:
- case WIN_WRITE_EXT:
+ case ATA_CMD_PIO_READ:
+ case ATA_CMD_PIO_READ_EXT:
+ case ATA_CMD_PIO_WRITE:
+ case ATA_CMD_PIO_WRITE_EXT:
put_lba(ah, f->lba);
n = f->bcnt;
@@ -812,8 +813,8 @@ aoecmd_ata_rsp(struct sk_buff *skb)
d->htgt = NULL;
n = ahout->scnt << 9;
switch (ahout->cmdstat) {
- case WIN_READ:
- case WIN_READ_EXT:
+ case ATA_CMD_PIO_READ:
+ case ATA_CMD_PIO_READ_EXT:
if (skb->len - sizeof *hin - sizeof *ahin < n) {
printk(KERN_ERR
"aoe: %s. skb->len=%d need=%ld\n",
@@ -823,8 +824,8 @@ aoecmd_ata_rsp(struct sk_buff *skb)
return;
}
memcpy(f->bufaddr, ahin+1, n);
- case WIN_WRITE:
- case WIN_WRITE_EXT:
+ case ATA_CMD_PIO_WRITE:
+ case ATA_CMD_PIO_WRITE_EXT:
ifp = getif(t, skb->dev);
if (ifp) {
ifp->lost = 0;
@@ -838,7 +839,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
goto xmit;
}
break;
- case WIN_IDENTIFY:
+ case ATA_CMD_ID_ATA:
if (skb->len - sizeof *hin - sizeof *ahin < 512) {
printk(KERN_INFO
"aoe: runt data size in ataid. skb->len=%d\n",
@@ -914,7 +915,7 @@ aoecmd_ata_id(struct aoedev *d)
/* set up ata header */
ah->scnt = 1;
- ah->cmdstat = WIN_IDENTIFY;
+ ah->cmdstat = ATA_CMD_ID_ATA;
ah->lba3 = 0xa0;
skb->dev = t->ifp->nd;
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c
index c6099ba9a4b8..ce0d62cd71b2 100644
--- a/drivers/block/aoe/aoenet.c
+++ b/drivers/block/aoe/aoenet.c
@@ -151,7 +151,7 @@ exit:
return 0;
}
-static struct packet_type aoe_pt = {
+static struct packet_type aoe_pt __read_mostly = {
.type = __constant_htons(ETH_P_AOE),
.func = aoenet_rcv,
};
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 4f9b6d792017..5d0e135824f9 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3898,6 +3898,13 @@ static struct pci_driver cciss_pci_driver = {
*/
static int __init cciss_init(void)
{
+ /*
+ * The hardware requires that commands are aligned on a 64-bit
+ * boundary. Given that we use pci_alloc_consistent() to allocate an
+ * array of them, the size must be a multiple of 8 bytes.
+ */
+ BUILD_BUG_ON(sizeof(CommandList_struct) % 8);
+
printk(KERN_INFO DRIVER_NAME "\n");
/* Register for our PCI devices */
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 5d39df14ed90..ca268ca11159 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -617,6 +617,7 @@ static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
int i;
c->pci_dev = pdev;
+ pci_set_master(pdev);
if (pci_enable_device(pdev)) {
printk(KERN_ERR "cpqarray: Unable to Enable PCI device\n");
return -1;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 83d8ed39433d..1300df6f1642 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -177,6 +177,7 @@ static int print_unex = 1;
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/mod_devicetable.h>
#include <linux/buffer_head.h> /* for invalidate_buffers() */
#include <linux/mutex.h>
@@ -4135,10 +4136,9 @@ static int have_no_fdc = -ENODEV;
static ssize_t floppy_cmos_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct platform_device *p;
+ struct platform_device *p = to_platform_device(dev);
int drive;
- p = container_of(dev, struct platform_device,dev);
drive = p->id;
return sprintf(buf, "%X\n", UDP->cmos);
}
@@ -4598,6 +4598,13 @@ MODULE_AUTHOR("Alain L. Knaff");
MODULE_SUPPORTED_DEVICE("fd");
MODULE_LICENSE("GPL");
+/* This doesn't actually get used other than for module information */
+static const struct pnp_device_id floppy_pnpids[] = {
+ { "PNP0700", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(pnp, floppy_pnpids);
+
#else
__setup("floppy=", floppy_setup);
diff --git a/drivers/block/hd.c b/drivers/block/hd.c
index 482c0c4b964f..3c11f062a18c 100644
--- a/drivers/block/hd.c
+++ b/drivers/block/hd.c
@@ -42,6 +42,8 @@
#include <linux/ata.h>
#include <linux/hdreg.h>
+#define HD_IRQ 14
+
#define REALLY_SLOW_IO
#include <asm/system.h>
#include <asm/io.h>
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index bf0345577672..40b17d3b55a1 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -474,10 +474,35 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
int ret;
pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
- if (bio_rw(bio) == WRITE)
+
+ if (bio_rw(bio) == WRITE) {
+ int barrier = bio_barrier(bio);
+ struct file *file = lo->lo_backing_file;
+
+ if (barrier) {
+ if (unlikely(!file->f_op->fsync)) {
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
+ ret = vfs_fsync(file, file->f_path.dentry, 0);
+ if (unlikely(ret)) {
+ ret = -EIO;
+ goto out;
+ }
+ }
+
ret = lo_send(lo, bio, pos);
- else
+
+ if (barrier && !ret) {
+ ret = vfs_fsync(file, file->f_path.dentry, 0);
+ if (unlikely(ret))
+ ret = -EIO;
+ }
+ } else
ret = lo_receive(lo, bio, lo->lo_blocksize, pos);
+
+out:
return ret;
}
@@ -826,6 +851,9 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
lo->lo_queue->queuedata = lo;
lo->lo_queue->unplug_fn = loop_unplug;
+ if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync)
+ blk_queue_ordered(lo->lo_queue, QUEUE_ORDERED_DRAIN, NULL);
+
set_capacity(lo->lo_disk, size);
bd_set_size(bdev, size << 9);
@@ -941,11 +969,18 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
bd_set_size(bdev, 0);
mapping_set_gfp_mask(filp->f_mapping, gfp);
lo->lo_state = Lo_unbound;
- fput(filp);
/* This is safe: open() is still holding a reference. */
module_put(THIS_MODULE);
if (max_part > 0)
ioctl_by_bdev(bdev, BLKRRPART, 0);
+ mutex_unlock(&lo->lo_ctl_mutex);
+ /*
+ * Need not hold lo_ctl_mutex to fput backing file.
+ * Calling fput holding lo_ctl_mutex triggers a circular
+ * lock dependency possibility warning as fput can take
+ * bd_mutex which is usually taken before lo_ctl_mutex.
+ */
+ fput(filp);
return 0;
}
@@ -1157,13 +1192,37 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) {
return err;
}
+static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
+{
+ int err;
+ sector_t sec;
+ loff_t sz;
+
+ err = -ENXIO;
+ if (unlikely(lo->lo_state != Lo_bound))
+ goto out;
+ err = figure_loop_size(lo);
+ if (unlikely(err))
+ goto out;
+ sec = get_capacity(lo->lo_disk);
+ /* the width of sector_t may be narrow for bit-shift */
+ sz = sec;
+ sz <<= 9;
+ mutex_lock(&bdev->bd_mutex);
+ bd_set_size(bdev, sz);
+ mutex_unlock(&bdev->bd_mutex);
+
+ out:
+ return err;
+}
+
static int lo_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
struct loop_device *lo = bdev->bd_disk->private_data;
int err;
- mutex_lock(&lo->lo_ctl_mutex);
+ mutex_lock_nested(&lo->lo_ctl_mutex, 1);
switch (cmd) {
case LOOP_SET_FD:
err = loop_set_fd(lo, mode, bdev, arg);
@@ -1172,7 +1231,10 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
err = loop_change_fd(lo, bdev, arg);
break;
case LOOP_CLR_FD:
+ /* loop_clr_fd would have unlocked lo_ctl_mutex on success */
err = loop_clr_fd(lo, bdev);
+ if (!err)
+ goto out_unlocked;
break;
case LOOP_SET_STATUS:
err = loop_set_status_old(lo, (struct loop_info __user *) arg);
@@ -1186,10 +1248,17 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
case LOOP_GET_STATUS64:
err = loop_get_status64(lo, (struct loop_info64 __user *) arg);
break;
+ case LOOP_SET_CAPACITY:
+ err = -EPERM;
+ if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
+ err = loop_set_capacity(lo, bdev);
+ break;
default:
err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
}
mutex_unlock(&lo->lo_ctl_mutex);
+
+out_unlocked:
return err;
}
@@ -1331,6 +1400,7 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode,
lo, (struct compat_loop_info __user *) arg);
mutex_unlock(&lo->lo_ctl_mutex);
break;
+ case LOOP_SET_CAPACITY:
case LOOP_CLR_FD:
case LOOP_GET_STATUS64:
case LOOP_SET_STATUS64:
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 8299e2d3b611..4d6de4f15ccb 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -4,7 +4,7 @@
* Note that you can not swap over this thing, yet. Seems to work but
* deadlocks sometimes - you can not swap over TCP in general.
*
- * Copyright 1997-2000 Pavel Machek <pavel@ucw.cz>
+ * Copyright 1997-2000, 2008 Pavel Machek <pavel@suse.cz>
* Parts copyright 2001 Steven Whitehouse <steve@chygwyn.com>
*
* This file is released under GPLv2 or later.
@@ -276,7 +276,7 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req)
return 0;
error_out:
- return 1;
+ return -EIO;
}
static struct request *nbd_find_request(struct nbd_device *lo,
@@ -467,9 +467,7 @@ static void nbd_handle_req(struct nbd_device *lo, struct request *req)
mutex_unlock(&lo->tx_lock);
printk(KERN_ERR "%s: Attempted send on closed socket\n",
lo->disk->disk_name);
- req->errors++;
- nbd_end_request(req);
- return;
+ goto error_out;
}
lo->active_req = req;
@@ -531,7 +529,7 @@ static int nbd_thread(void *data)
* { printk( "Warning: Ignoring result!\n"); nbd_end_request( req ); }
*/
-static void do_nbd_request(struct request_queue * q)
+static void do_nbd_request(struct request_queue *q)
{
struct request *req;
@@ -568,27 +566,17 @@ static void do_nbd_request(struct request_queue * q)
}
}
-static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
-{
- struct nbd_device *lo = bdev->bd_disk->private_data;
- struct file *file;
- int error;
- struct request sreq ;
- struct task_struct *thread;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- BUG_ON(lo->magic != LO_MAGIC);
-
- /* Anyone capable of this syscall can do *real bad* things */
- dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n",
- lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg);
+/* Must be called with tx_lock held */
+static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo,
+ unsigned int cmd, unsigned long arg)
+{
switch (cmd) {
- case NBD_DISCONNECT:
+ case NBD_DISCONNECT: {
+ struct request sreq;
+
printk(KERN_INFO "%s: NBD_DISCONNECT\n", lo->disk->disk_name);
+
blk_rq_init(NULL, &sreq);
sreq.cmd_type = REQ_TYPE_SPECIAL;
nbd_cmd(&sreq) = NBD_CMD_DISC;
@@ -599,29 +587,29 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
*/
sreq.sector = 0;
sreq.nr_sectors = 0;
- if (!lo->sock)
+ if (!lo->sock)
return -EINVAL;
- mutex_lock(&lo->tx_lock);
- nbd_send_req(lo, &sreq);
- mutex_unlock(&lo->tx_lock);
+ nbd_send_req(lo, &sreq);
return 0;
+ }
- case NBD_CLEAR_SOCK:
- error = 0;
- mutex_lock(&lo->tx_lock);
+ case NBD_CLEAR_SOCK: {
+ struct file *file;
+
lo->sock = NULL;
- mutex_unlock(&lo->tx_lock);
file = lo->file;
lo->file = NULL;
nbd_clear_que(lo);
BUG_ON(!list_empty(&lo->queue_head));
if (file)
fput(file);
- return error;
- case NBD_SET_SOCK:
+ return 0;
+ }
+
+ case NBD_SET_SOCK: {
+ struct file *file;
if (lo->file)
return -EBUSY;
- error = -EINVAL;
file = fget(arg);
if (file) {
struct inode *inode = file->f_path.dentry->d_inode;
@@ -630,12 +618,14 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
lo->sock = SOCKET_I(inode);
if (max_part > 0)
bdev->bd_invalidated = 1;
- error = 0;
+ return 0;
} else {
fput(file);
}
}
- return error;
+ return -EINVAL;
+ }
+
case NBD_SET_BLKSIZE:
lo->blksize = arg;
lo->bytesize &= ~(lo->blksize-1);
@@ -643,35 +633,50 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
set_blocksize(bdev, lo->blksize);
set_capacity(lo->disk, lo->bytesize >> 9);
return 0;
+
case NBD_SET_SIZE:
lo->bytesize = arg & ~(lo->blksize-1);
bdev->bd_inode->i_size = lo->bytesize;
set_blocksize(bdev, lo->blksize);
set_capacity(lo->disk, lo->bytesize >> 9);
return 0;
+
case NBD_SET_TIMEOUT:
lo->xmit_timeout = arg * HZ;
return 0;
+
case NBD_SET_SIZE_BLOCKS:
lo->bytesize = ((u64) arg) * lo->blksize;
bdev->bd_inode->i_size = lo->bytesize;
set_blocksize(bdev, lo->blksize);
set_capacity(lo->disk, lo->bytesize >> 9);
return 0;
- case NBD_DO_IT:
+
+ case NBD_DO_IT: {
+ struct task_struct *thread;
+ struct file *file;
+ int error;
+
if (lo->pid)
return -EBUSY;
if (!lo->file)
return -EINVAL;
+
+ mutex_unlock(&lo->tx_lock);
+
thread = kthread_create(nbd_thread, lo, lo->disk->disk_name);
- if (IS_ERR(thread))
+ if (IS_ERR(thread)) {
+ mutex_lock(&lo->tx_lock);
return PTR_ERR(thread);
+ }
wake_up_process(thread);
error = nbd_do_it(lo);
kthread_stop(thread);
+
+ mutex_lock(&lo->tx_lock);
if (error)
return error;
- sock_shutdown(lo, 1);
+ sock_shutdown(lo, 0);
file = lo->file;
lo->file = NULL;
nbd_clear_que(lo);
@@ -684,6 +689,8 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
if (max_part > 0)
ioctl_by_bdev(bdev, BLKRRPART, 0);
return lo->harderror;
+ }
+
case NBD_CLEAR_QUE:
/*
* This is for compatibility only. The queue is always cleared
@@ -691,6 +698,7 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
*/
BUG_ON(!lo->sock && !list_empty(&lo->queue_head));
return 0;
+
case NBD_PRINT_DEBUG:
printk(KERN_INFO "%s: next = %p, prev = %p, head = %p\n",
bdev->bd_disk->disk_name,
@@ -698,7 +706,29 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
&lo->queue_head);
return 0;
}
- return -EINVAL;
+ return -ENOTTY;
+}
+
+static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+{
+ struct nbd_device *lo = bdev->bd_disk->private_data;
+ int error;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ BUG_ON(lo->magic != LO_MAGIC);
+
+ /* Anyone capable of this syscall can do *real bad* things */
+ dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n",
+ lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg);
+
+ mutex_lock(&lo->tx_lock);
+ error = __nbd_ioctl(bdev, lo, cmd, arg);
+ mutex_unlock(&lo->tx_lock);
+
+ return error;
}
static struct block_device_operations nbd_fops =
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index 393ed6760d78..8eddef373a91 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -551,8 +551,6 @@ static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev)
dev_warn(&dev->core, "failed to create /proc entry\n");
return;
}
-
- pde->owner = THIS_MODULE;
pde->data = priv;
}
diff --git a/drivers/block/swim.c b/drivers/block/swim.c
new file mode 100644
index 000000000000..d22cc3856937
--- /dev/null
+++ b/drivers/block/swim.c
@@ -0,0 +1,995 @@
+/*
+ * Driver for SWIM (Sander Woz Integrated Machine) floppy controller
+ *
+ * Copyright (C) 2004,2008 Laurent Vivier <Laurent@lvivier.info>
+ *
+ * based on Alastair Bridgewater SWIM analysis, 2001
+ * based on SWIM3 driver (c) Paul Mackerras, 1996
+ * based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * 2004-08-21 (lv) - Initial implementation
+ * 2008-10-30 (lv) - Port to 2.6
+ */
+
+#include <linux/module.h>
+#include <linux/fd.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <asm/macintosh.h>
+#include <asm/mac_via.h>
+
+#define CARDNAME "swim"
+
+struct sector_header {
+ unsigned char side;
+ unsigned char track;
+ unsigned char sector;
+ unsigned char size;
+ unsigned char crc0;
+ unsigned char crc1;
+} __attribute__((packed));
+
+#define DRIVER_VERSION "Version 0.2 (2008-10-30)"
+
+#define REG(x) unsigned char x, x ## _pad[0x200 - 1];
+
+struct swim {
+ REG(write_data)
+ REG(write_mark)
+ REG(write_CRC)
+ REG(write_parameter)
+ REG(write_phase)
+ REG(write_setup)
+ REG(write_mode0)
+ REG(write_mode1)
+
+ REG(read_data)
+ REG(read_mark)
+ REG(read_error)
+ REG(read_parameter)
+ REG(read_phase)
+ REG(read_setup)
+ REG(read_status)
+ REG(read_handshake)
+} __attribute__((packed));
+
+#define swim_write(base, reg, v) out_8(&(base)->write_##reg, (v))
+#define swim_read(base, reg) in_8(&(base)->read_##reg)
+
+/* IWM registers */
+
+struct iwm {
+ REG(ph0L)
+ REG(ph0H)
+ REG(ph1L)
+ REG(ph1H)
+ REG(ph2L)
+ REG(ph2H)
+ REG(ph3L)
+ REG(ph3H)
+ REG(mtrOff)
+ REG(mtrOn)
+ REG(intDrive)
+ REG(extDrive)
+ REG(q6L)
+ REG(q6H)
+ REG(q7L)
+ REG(q7H)
+} __attribute__((packed));
+
+#define iwm_write(base, reg, v) out_8(&(base)->reg, (v))
+#define iwm_read(base, reg) in_8(&(base)->reg)
+
+/* bits in phase register */
+
+#define SEEK_POSITIVE 0x070
+#define SEEK_NEGATIVE 0x074
+#define STEP 0x071
+#define MOTOR_ON 0x072
+#define MOTOR_OFF 0x076
+#define INDEX 0x073
+#define EJECT 0x077
+#define SETMFM 0x171
+#define SETGCR 0x175
+
+#define RELAX 0x033
+#define LSTRB 0x008
+
+#define CA_MASK 0x077
+
+/* Select values for swim_select and swim_readbit */
+
+#define READ_DATA_0 0x074
+#define TWOMEG_DRIVE 0x075
+#define SINGLE_SIDED 0x076
+#define DRIVE_PRESENT 0x077
+#define DISK_IN 0x170
+#define WRITE_PROT 0x171
+#define TRACK_ZERO 0x172
+#define TACHO 0x173
+#define READ_DATA_1 0x174
+#define MFM_MODE 0x175
+#define SEEK_COMPLETE 0x176
+#define ONEMEG_MEDIA 0x177
+
+/* Bits in handshake register */
+
+#define MARK_BYTE 0x01
+#define CRC_ZERO 0x02
+#define RDDATA 0x04
+#define SENSE 0x08
+#define MOTEN 0x10
+#define ERROR 0x20
+#define DAT2BYTE 0x40
+#define DAT1BYTE 0x80
+
+/* bits in setup register */
+
+#define S_INV_WDATA 0x01
+#define S_3_5_SELECT 0x02
+#define S_GCR 0x04
+#define S_FCLK_DIV2 0x08
+#define S_ERROR_CORR 0x10
+#define S_IBM_DRIVE 0x20
+#define S_GCR_WRITE 0x40
+#define S_TIMEOUT 0x80
+
+/* bits in mode register */
+
+#define CLFIFO 0x01
+#define ENBL1 0x02
+#define ENBL2 0x04
+#define ACTION 0x08
+#define WRITE_MODE 0x10
+#define HEDSEL 0x20
+#define MOTON 0x80
+
+/*----------------------------------------------------------------------------*/
+
+enum drive_location {
+ INTERNAL_DRIVE = 0x02,
+ EXTERNAL_DRIVE = 0x04,
+};
+
+enum media_type {
+ DD_MEDIA,
+ HD_MEDIA,
+};
+
+struct floppy_state {
+
+ /* physical properties */
+
+ enum drive_location location; /* internal or external drive */
+ int head_number; /* single- or double-sided drive */
+
+ /* media */
+
+ int disk_in;
+ int ejected;
+ enum media_type type;
+ int write_protected;
+
+ int total_secs;
+ int secpercyl;
+ int secpertrack;
+
+ /* in-use information */
+
+ int track;
+ int ref_count;
+
+ struct gendisk *disk;
+
+ /* parent controller */
+
+ struct swim_priv *swd;
+};
+
+enum motor_action {
+ OFF,
+ ON,
+};
+
+enum head {
+ LOWER_HEAD = 0,
+ UPPER_HEAD = 1,
+};
+
+#define FD_MAX_UNIT 2
+
+struct swim_priv {
+ struct swim __iomem *base;
+ spinlock_t lock;
+ struct request_queue *queue;
+ int floppy_count;
+ struct floppy_state unit[FD_MAX_UNIT];
+};
+
+extern int swim_read_sector_header(struct swim __iomem *base,
+ struct sector_header *header);
+extern int swim_read_sector_data(struct swim __iomem *base,
+ unsigned char *data);
+
+static inline void set_swim_mode(struct swim __iomem *base, int enable)
+{
+ struct iwm __iomem *iwm_base;
+ unsigned long flags;
+
+ if (!enable) {
+ swim_write(base, mode0, 0xf8);
+ return;
+ }
+
+ iwm_base = (struct iwm __iomem *)base;
+ local_irq_save(flags);
+
+ iwm_read(iwm_base, q7L);
+ iwm_read(iwm_base, mtrOff);
+ iwm_read(iwm_base, q6H);
+
+ iwm_write(iwm_base, q7H, 0x57);
+ iwm_write(iwm_base, q7H, 0x17);
+ iwm_write(iwm_base, q7H, 0x57);
+ iwm_write(iwm_base, q7H, 0x57);
+
+ local_irq_restore(flags);
+}
+
+static inline int get_swim_mode(struct swim __iomem *base)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ swim_write(base, phase, 0xf5);
+ if (swim_read(base, phase) != 0xf5)
+ goto is_iwm;
+ swim_write(base, phase, 0xf6);
+ if (swim_read(base, phase) != 0xf6)
+ goto is_iwm;
+ swim_write(base, phase, 0xf7);
+ if (swim_read(base, phase) != 0xf7)
+ goto is_iwm;
+ local_irq_restore(flags);
+ return 1;
+is_iwm:
+ local_irq_restore(flags);
+ return 0;
+}
+
+static inline void swim_select(struct swim __iomem *base, int sel)
+{
+ swim_write(base, phase, RELAX);
+
+ via1_set_head(sel & 0x100);
+
+ swim_write(base, phase, sel & CA_MASK);
+}
+
+static inline void swim_action(struct swim __iomem *base, int action)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ swim_select(base, action);
+ udelay(1);
+ swim_write(base, phase, (LSTRB<<4) | LSTRB);
+ udelay(1);
+ swim_write(base, phase, (LSTRB<<4) | ((~LSTRB) & 0x0F));
+ udelay(1);
+
+ local_irq_restore(flags);
+}
+
+static inline int swim_readbit(struct swim __iomem *base, int bit)
+{
+ int stat;
+
+ swim_select(base, bit);
+
+ udelay(10);
+
+ stat = swim_read(base, handshake);
+
+ return (stat & SENSE) == 0;
+}
+
+static inline void swim_drive(struct swim __iomem *base,
+ enum drive_location location)
+{
+ if (location == INTERNAL_DRIVE) {
+ swim_write(base, mode0, EXTERNAL_DRIVE); /* clear drive 1 bit */
+ swim_write(base, mode1, INTERNAL_DRIVE); /* set drive 0 bit */
+ } else if (location == EXTERNAL_DRIVE) {
+ swim_write(base, mode0, INTERNAL_DRIVE); /* clear drive 0 bit */
+ swim_write(base, mode1, EXTERNAL_DRIVE); /* set drive 1 bit */
+ }
+}
+
+static inline void swim_motor(struct swim __iomem *base,
+ enum motor_action action)
+{
+ if (action == ON) {
+ int i;
+
+ swim_action(base, MOTOR_ON);
+
+ for (i = 0; i < 2*HZ; i++) {
+ swim_select(base, RELAX);
+ if (swim_readbit(base, MOTOR_ON))
+ break;
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
+ }
+ } else if (action == OFF) {
+ swim_action(base, MOTOR_OFF);
+ swim_select(base, RELAX);
+ }
+}
+
+static inline void swim_eject(struct swim __iomem *base)
+{
+ int i;
+
+ swim_action(base, EJECT);
+
+ for (i = 0; i < 2*HZ; i++) {
+ swim_select(base, RELAX);
+ if (!swim_readbit(base, DISK_IN))
+ break;
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
+ }
+ swim_select(base, RELAX);
+}
+
+static inline void swim_head(struct swim __iomem *base, enum head head)
+{
+ /* wait drive is ready */
+
+ if (head == UPPER_HEAD)
+ swim_select(base, READ_DATA_1);
+ else if (head == LOWER_HEAD)
+ swim_select(base, READ_DATA_0);
+}
+
+static inline int swim_step(struct swim __iomem *base)
+{
+ int wait;
+
+ swim_action(base, STEP);
+
+ for (wait = 0; wait < HZ; wait++) {
+
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
+
+ swim_select(base, RELAX);
+ if (!swim_readbit(base, STEP))
+ return 0;
+ }
+ return -1;
+}
+
+static inline int swim_track00(struct swim __iomem *base)
+{
+ int try;
+
+ swim_action(base, SEEK_NEGATIVE);
+
+ for (try = 0; try < 100; try++) {
+
+ swim_select(base, RELAX);
+ if (swim_readbit(base, TRACK_ZERO))
+ break;
+
+ if (swim_step(base))
+ return -1;
+ }
+
+ if (swim_readbit(base, TRACK_ZERO))
+ return 0;
+
+ return -1;
+}
+
+static inline int swim_seek(struct swim __iomem *base, int step)
+{
+ if (step == 0)
+ return 0;
+
+ if (step < 0) {
+ swim_action(base, SEEK_NEGATIVE);
+ step = -step;
+ } else
+ swim_action(base, SEEK_POSITIVE);
+
+ for ( ; step > 0; step--) {
+ if (swim_step(base))
+ return -1;
+ }
+
+ return 0;
+}
+
+static inline int swim_track(struct floppy_state *fs, int track)
+{
+ struct swim __iomem *base = fs->swd->base;
+ int ret;
+
+ ret = swim_seek(base, track - fs->track);
+
+ if (ret == 0)
+ fs->track = track;
+ else {
+ swim_track00(base);
+ fs->track = 0;
+ }
+
+ return ret;
+}
+
+static int floppy_eject(struct floppy_state *fs)
+{
+ struct swim __iomem *base = fs->swd->base;
+
+ swim_drive(base, fs->location);
+ swim_motor(base, OFF);
+ swim_eject(base);
+
+ fs->disk_in = 0;
+ fs->ejected = 1;
+
+ return 0;
+}
+
+static inline int swim_read_sector(struct floppy_state *fs,
+ int side, int track,
+ int sector, unsigned char *buffer)
+{
+ struct swim __iomem *base = fs->swd->base;
+ unsigned long flags;
+ struct sector_header header;
+ int ret = -1;
+ short i;
+
+ swim_track(fs, track);
+
+ swim_write(base, mode1, MOTON);
+ swim_head(base, side);
+ swim_write(base, mode0, side);
+
+ local_irq_save(flags);
+ for (i = 0; i < 36; i++) {
+ ret = swim_read_sector_header(base, &header);
+ if (!ret && (header.sector == sector)) {
+ /* found */
+
+ ret = swim_read_sector_data(base, buffer);
+ break;
+ }
+ }
+ local_irq_restore(flags);
+
+ swim_write(base, mode0, MOTON);
+
+ if ((header.side != side) || (header.track != track) ||
+ (header.sector != sector))
+ return 0;
+
+ return ret;
+}
+
+static int floppy_read_sectors(struct floppy_state *fs,
+ int req_sector, int sectors_nb,
+ unsigned char *buffer)
+{
+ struct swim __iomem *base = fs->swd->base;
+ int ret;
+ int side, track, sector;
+ int i, try;
+
+
+ swim_drive(base, fs->location);
+ for (i = req_sector; i < req_sector + sectors_nb; i++) {
+ int x;
+ track = i / fs->secpercyl;
+ x = i % fs->secpercyl;
+ side = x / fs->secpertrack;
+ sector = x % fs->secpertrack + 1;
+
+ try = 5;
+ do {
+ ret = swim_read_sector(fs, side, track, sector,
+ buffer);
+ if (try-- == 0)
+ return -1;
+ } while (ret != 512);
+
+ buffer += ret;
+ }
+
+ return 0;
+}
+
+static void redo_fd_request(struct request_queue *q)
+{
+ struct request *req;
+ struct floppy_state *fs;
+
+ while ((req = elv_next_request(q))) {
+
+ fs = req->rq_disk->private_data;
+ if (req->sector < 0 || req->sector >= fs->total_secs) {
+ end_request(req, 0);
+ continue;
+ }
+ if (req->current_nr_sectors == 0) {
+ end_request(req, 1);
+ continue;
+ }
+ if (!fs->disk_in) {
+ end_request(req, 0);
+ continue;
+ }
+ if (rq_data_dir(req) == WRITE) {
+ if (fs->write_protected) {
+ end_request(req, 0);
+ continue;
+ }
+ }
+ switch (rq_data_dir(req)) {
+ case WRITE:
+ /* NOT IMPLEMENTED */
+ end_request(req, 0);
+ break;
+ case READ:
+ if (floppy_read_sectors(fs, req->sector,
+ req->current_nr_sectors,
+ req->buffer)) {
+ end_request(req, 0);
+ continue;
+ }
+ req->nr_sectors -= req->current_nr_sectors;
+ req->sector += req->current_nr_sectors;
+ req->buffer += req->current_nr_sectors * 512;
+ end_request(req, 1);
+ break;
+ }
+ }
+}
+
+static void do_fd_request(struct request_queue *q)
+{
+ redo_fd_request(q);
+}
+
+static struct floppy_struct floppy_type[4] = {
+ { 0, 0, 0, 0, 0, 0x00, 0x00, 0x00, 0x00, NULL }, /* no testing */
+ { 720, 9, 1, 80, 0, 0x2A, 0x02, 0xDF, 0x50, NULL }, /* 360KB SS 3.5"*/
+ { 1440, 9, 2, 80, 0, 0x2A, 0x02, 0xDF, 0x50, NULL }, /* 720KB 3.5" */
+ { 2880, 18, 2, 80, 0, 0x1B, 0x00, 0xCF, 0x6C, NULL }, /* 1.44MB 3.5" */
+};
+
+static int get_floppy_geometry(struct floppy_state *fs, int type,
+ struct floppy_struct **g)
+{
+ if (type >= ARRAY_SIZE(floppy_type))
+ return -EINVAL;
+
+ if (type)
+ *g = &floppy_type[type];
+ else if (fs->type == HD_MEDIA) /* High-Density media */
+ *g = &floppy_type[3];
+ else if (fs->head_number == 2) /* double-sided */
+ *g = &floppy_type[2];
+ else
+ *g = &floppy_type[1];
+
+ return 0;
+}
+
+static void setup_medium(struct floppy_state *fs)
+{
+ struct swim __iomem *base = fs->swd->base;
+
+ if (swim_readbit(base, DISK_IN)) {
+ struct floppy_struct *g;
+ fs->disk_in = 1;
+ fs->write_protected = swim_readbit(base, WRITE_PROT);
+ fs->type = swim_readbit(base, ONEMEG_MEDIA);
+
+ if (swim_track00(base))
+ printk(KERN_ERR
+ "SWIM: cannot move floppy head to track 0\n");
+
+ swim_track00(base);
+
+ get_floppy_geometry(fs, 0, &g);
+ fs->total_secs = g->size;
+ fs->secpercyl = g->head * g->sect;
+ fs->secpertrack = g->sect;
+ fs->track = 0;
+ } else {
+ fs->disk_in = 0;
+ }
+}
+
+static int floppy_open(struct block_device *bdev, fmode_t mode)
+{
+ struct floppy_state *fs = bdev->bd_disk->private_data;
+ struct swim __iomem *base = fs->swd->base;
+ int err;
+
+ if (fs->ref_count == -1 || (fs->ref_count && mode & FMODE_EXCL))
+ return -EBUSY;
+
+ if (mode & FMODE_EXCL)
+ fs->ref_count = -1;
+ else
+ fs->ref_count++;
+
+ swim_write(base, setup, S_IBM_DRIVE | S_FCLK_DIV2);
+ udelay(10);
+ swim_drive(base, INTERNAL_DRIVE);
+ swim_motor(base, ON);
+ swim_action(base, SETMFM);
+ if (fs->ejected)
+ setup_medium(fs);
+ if (!fs->disk_in) {
+ err = -ENXIO;
+ goto out;
+ }
+
+ if (mode & FMODE_NDELAY)
+ return 0;
+
+ if (mode & (FMODE_READ|FMODE_WRITE)) {
+ check_disk_change(bdev);
+ if ((mode & FMODE_WRITE) && fs->write_protected) {
+ err = -EROFS;
+ goto out;
+ }
+ }
+ return 0;
+out:
+ if (fs->ref_count < 0)
+ fs->ref_count = 0;
+ else if (fs->ref_count > 0)
+ --fs->ref_count;
+
+ if (fs->ref_count == 0)
+ swim_motor(base, OFF);
+ return err;
+}
+
+static int floppy_release(struct gendisk *disk, fmode_t mode)
+{
+ struct floppy_state *fs = disk->private_data;
+ struct swim __iomem *base = fs->swd->base;
+
+ if (fs->ref_count < 0)
+ fs->ref_count = 0;
+ else if (fs->ref_count > 0)
+ --fs->ref_count;
+
+ if (fs->ref_count == 0)
+ swim_motor(base, OFF);
+
+ return 0;
+}
+
+static int floppy_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long param)
+{
+ struct floppy_state *fs = bdev->bd_disk->private_data;
+ int err;
+
+ if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ switch (cmd) {
+ case FDEJECT:
+ if (fs->ref_count != 1)
+ return -EBUSY;
+ err = floppy_eject(fs);
+ return err;
+
+ case FDGETPRM:
+ if (copy_to_user((void __user *) param, (void *) &floppy_type,
+ sizeof(struct floppy_struct)))
+ return -EFAULT;
+ break;
+
+ default:
+ printk(KERN_DEBUG "SWIM floppy_ioctl: unknown cmd %d\n",
+ cmd);
+ return -ENOSYS;
+ }
+ return 0;
+}
+
+static int floppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+ struct floppy_state *fs = bdev->bd_disk->private_data;
+ struct floppy_struct *g;
+ int ret;
+
+ ret = get_floppy_geometry(fs, 0, &g);
+ if (ret)
+ return ret;
+
+ geo->heads = g->head;
+ geo->sectors = g->sect;
+ geo->cylinders = g->track;
+
+ return 0;
+}
+
+static int floppy_check_change(struct gendisk *disk)
+{
+ struct floppy_state *fs = disk->private_data;
+
+ return fs->ejected;
+}
+
+static int floppy_revalidate(struct gendisk *disk)
+{
+ struct floppy_state *fs = disk->private_data;
+ struct swim __iomem *base = fs->swd->base;
+
+ swim_drive(base, fs->location);
+
+ if (fs->ejected)
+ setup_medium(fs);
+
+ if (!fs->disk_in)
+ swim_motor(base, OFF);
+ else
+ fs->ejected = 0;
+
+ return !fs->disk_in;
+}
+
+static struct block_device_operations floppy_fops = {
+ .owner = THIS_MODULE,
+ .open = floppy_open,
+ .release = floppy_release,
+ .locked_ioctl = floppy_ioctl,
+ .getgeo = floppy_getgeo,
+ .media_changed = floppy_check_change,
+ .revalidate_disk = floppy_revalidate,
+};
+
+static struct kobject *floppy_find(dev_t dev, int *part, void *data)
+{
+ struct swim_priv *swd = data;
+ int drive = (*part & 3);
+
+ if (drive > swd->floppy_count)
+ return NULL;
+
+ *part = 0;
+ return get_disk(swd->unit[drive].disk);
+}
+
+static int __devinit swim_add_floppy(struct swim_priv *swd,
+ enum drive_location location)
+{
+ struct floppy_state *fs = &swd->unit[swd->floppy_count];
+ struct swim __iomem *base = swd->base;
+
+ fs->location = location;
+
+ swim_drive(base, location);
+
+ swim_motor(base, OFF);
+
+ if (swim_readbit(base, SINGLE_SIDED))
+ fs->head_number = 1;
+ else
+ fs->head_number = 2;
+ fs->ref_count = 0;
+ fs->ejected = 1;
+
+ swd->floppy_count++;
+
+ return 0;
+}
+
+static int __devinit swim_floppy_init(struct swim_priv *swd)
+{
+ int err;
+ int drive;
+ struct swim __iomem *base = swd->base;
+
+ /* scan floppy drives */
+
+ swim_drive(base, INTERNAL_DRIVE);
+ if (swim_readbit(base, DRIVE_PRESENT))
+ swim_add_floppy(swd, INTERNAL_DRIVE);
+ swim_drive(base, EXTERNAL_DRIVE);
+ if (swim_readbit(base, DRIVE_PRESENT))
+ swim_add_floppy(swd, EXTERNAL_DRIVE);
+
+ /* register floppy drives */
+
+ err = register_blkdev(FLOPPY_MAJOR, "fd");
+ if (err) {
+ printk(KERN_ERR "Unable to get major %d for SWIM floppy\n",
+ FLOPPY_MAJOR);
+ return -EBUSY;
+ }
+
+ for (drive = 0; drive < swd->floppy_count; drive++) {
+ swd->unit[drive].disk = alloc_disk(1);
+ if (swd->unit[drive].disk == NULL) {
+ err = -ENOMEM;
+ goto exit_put_disks;
+ }
+ swd->unit[drive].swd = swd;
+ }
+
+ swd->queue = blk_init_queue(do_fd_request, &swd->lock);
+ if (!swd->queue) {
+ err = -ENOMEM;
+ goto exit_put_disks;
+ }
+
+ for (drive = 0; drive < swd->floppy_count; drive++) {
+ swd->unit[drive].disk->flags = GENHD_FL_REMOVABLE;
+ swd->unit[drive].disk->major = FLOPPY_MAJOR;
+ swd->unit[drive].disk->first_minor = drive;
+ sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive);
+ swd->unit[drive].disk->fops = &floppy_fops;
+ swd->unit[drive].disk->private_data = &swd->unit[drive];
+ swd->unit[drive].disk->queue = swd->queue;
+ set_capacity(swd->unit[drive].disk, 2880);
+ add_disk(swd->unit[drive].disk);
+ }
+
+ blk_register_region(MKDEV(FLOPPY_MAJOR, 0), 256, THIS_MODULE,
+ floppy_find, NULL, swd);
+
+ return 0;
+
+exit_put_disks:
+ unregister_blkdev(FLOPPY_MAJOR, "fd");
+ while (drive--)
+ put_disk(swd->unit[drive].disk);
+ return err;
+}
+
+static int __devinit swim_probe(struct platform_device *dev)
+{
+ struct resource *res;
+ struct swim __iomem *swim_base;
+ struct swim_priv *swd;
+ int ret;
+
+ res = platform_get_resource_byname(dev, IORESOURCE_MEM, "swim-regs");
+ if (!res) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (!request_mem_region(res->start, resource_size(res), CARDNAME)) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ swim_base = ioremap(res->start, resource_size(res));
+ if (!swim_base) {
+ return -ENOMEM;
+ goto out_release_io;
+ }
+
+ /* probe device */
+
+ set_swim_mode(swim_base, 1);
+ if (!get_swim_mode(swim_base)) {
+ printk(KERN_INFO "SWIM device not found !\n");
+ ret = -ENODEV;
+ goto out_iounmap;
+ }
+
+ /* set platform driver data */
+
+ swd = kzalloc(sizeof(struct swim_priv), GFP_KERNEL);
+ if (!swd) {
+ ret = -ENOMEM;
+ goto out_iounmap;
+ }
+ platform_set_drvdata(dev, swd);
+
+ swd->base = swim_base;
+
+ ret = swim_floppy_init(swd);
+ if (ret)
+ goto out_kfree;
+
+ return 0;
+
+out_kfree:
+ platform_set_drvdata(dev, NULL);
+ kfree(swd);
+out_iounmap:
+ iounmap(swim_base);
+out_release_io:
+ release_mem_region(res->start, resource_size(res));
+out:
+ return ret;
+}
+
+static int __devexit swim_remove(struct platform_device *dev)
+{
+ struct swim_priv *swd = platform_get_drvdata(dev);
+ int drive;
+ struct resource *res;
+
+ blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
+
+ for (drive = 0; drive < swd->floppy_count; drive++) {
+ del_gendisk(swd->unit[drive].disk);
+ put_disk(swd->unit[drive].disk);
+ }
+
+ unregister_blkdev(FLOPPY_MAJOR, "fd");
+
+ blk_cleanup_queue(swd->queue);
+
+ /* eject floppies */
+
+ for (drive = 0; drive < swd->floppy_count; drive++)
+ floppy_eject(&swd->unit[drive]);
+
+ iounmap(swd->base);
+
+ res = platform_get_resource_byname(dev, IORESOURCE_MEM, "swim-regs");
+ if (res)
+ release_mem_region(res->start, resource_size(res));
+
+ platform_set_drvdata(dev, NULL);
+ kfree(swd);
+
+ return 0;
+}
+
+static struct platform_driver swim_driver = {
+ .probe = swim_probe,
+ .remove = __devexit_p(swim_remove),
+ .driver = {
+ .name = CARDNAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init swim_init(void)
+{
+ printk(KERN_INFO "SWIM floppy driver %s\n", DRIVER_VERSION);
+
+ return platform_driver_register(&swim_driver);
+}
+module_init(swim_init);
+
+static void __exit swim_exit(void)
+{
+ platform_driver_unregister(&swim_driver);
+}
+module_exit(swim_exit);
+
+MODULE_DESCRIPTION("Driver for SWIM floppy controller");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Laurent Vivier <laurent@lvivier.info>");
+MODULE_ALIAS_BLOCKDEV_MAJOR(FLOPPY_MAJOR);
diff --git a/drivers/block/swim_asm.S b/drivers/block/swim_asm.S
new file mode 100644
index 000000000000..c9668206857b
--- /dev/null
+++ b/drivers/block/swim_asm.S
@@ -0,0 +1,247 @@
+/*
+ * low-level functions for the SWIM floppy controller
+ *
+ * needs assembly language because is very timing dependent
+ * this controller exists only on macintosh 680x0 based
+ *
+ * Copyright (C) 2004,2008 Laurent Vivier <Laurent@lvivier.info>
+ *
+ * based on Alastair Bridgewater SWIM analysis, 2001
+ * based on netBSD IWM driver (c) 1997, 1998 Hauke Fath.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * 2004-08-21 (lv) - Initial implementation
+ * 2008-11-05 (lv) - add get_swim_mode
+ */
+
+ .equ write_data, 0x0000
+ .equ write_mark, 0x0200
+ .equ write_CRC, 0x0400
+ .equ write_parameter,0x0600
+ .equ write_phase, 0x0800
+ .equ write_setup, 0x0a00
+ .equ write_mode0, 0x0c00
+ .equ write_mode1, 0x0e00
+ .equ read_data, 0x1000
+ .equ read_mark, 0x1200
+ .equ read_error, 0x1400
+ .equ read_parameter, 0x1600
+ .equ read_phase, 0x1800
+ .equ read_setup, 0x1a00
+ .equ read_status, 0x1c00
+ .equ read_handshake, 0x1e00
+
+ .equ o_side, 0
+ .equ o_track, 1
+ .equ o_sector, 2
+ .equ o_size, 3
+ .equ o_crc0, 4
+ .equ o_crc1, 5
+
+ .equ seek_time, 30000
+ .equ max_retry, 40
+ .equ sector_size, 512
+
+ .global swim_read_sector_header
+swim_read_sector_header:
+ link %a6, #0
+ moveml %d1-%d5/%a0-%a4,%sp@-
+ movel %a6@(0x0c), %a4
+ bsr mfm_read_addrmark
+ moveml %sp@+, %d1-%d5/%a0-%a4
+ unlk %a6
+ rts
+
+sector_address_mark:
+ .byte 0xa1, 0xa1, 0xa1, 0xfe
+sector_data_mark:
+ .byte 0xa1, 0xa1, 0xa1, 0xfb
+
+mfm_read_addrmark:
+ movel %a6@(0x08), %a3
+ lea %a3@(read_handshake), %a2
+ lea %a3@(read_mark), %a3
+ moveq #-1, %d0
+ movew #seek_time, %d2
+
+wait_header_init:
+ tstb %a3@(read_error - read_mark)
+ moveb #0x18, %a3@(write_mode0 - read_mark)
+ moveb #0x01, %a3@(write_mode1 - read_mark)
+ moveb #0x01, %a3@(write_mode0 - read_mark)
+ tstb %a3@(read_error - read_mark)
+ moveb #0x08, %a3@(write_mode1 - read_mark)
+
+ lea sector_address_mark, %a0
+ moveq #3, %d1
+
+wait_addr_mark_byte:
+
+ tstb %a2@
+ dbmi %d2, wait_addr_mark_byte
+ bpl header_exit
+
+ moveb %a3@, %d3
+ cmpb %a0@+, %d3
+ dbne %d1, wait_addr_mark_byte
+ bne wait_header_init
+
+ moveq #max_retry, %d2
+
+amark0: tstb %a2@
+ dbmi %d2, amark0
+ bpl signal_nonyb
+
+ moveb %a3@, %a4@(o_track)
+
+ moveq #max_retry, %d2
+
+amark1: tstb %a2@
+ dbmi %d2, amark1
+ bpl signal_nonyb
+
+ moveb %a3@, %a4@(o_side)
+
+ moveq #max_retry, %d2
+
+amark2: tstb %a2@
+ dbmi %d2, amark2
+ bpl signal_nonyb
+
+ moveb %a3@, %a4@(o_sector)
+
+ moveq #max_retry, %d2
+
+amark3: tstb %a2@
+ dbmi %d2, amark3
+ bpl signal_nonyb
+
+ moveb %a3@, %a4@(o_size)
+
+ moveq #max_retry, %d2
+
+crc0: tstb %a2@
+ dbmi %d2, crc0
+ bpl signal_nonyb
+
+ moveb %a3@, %a4@(o_crc0)
+
+ moveq #max_retry, %d2
+
+crc1: tstb %a2@
+ dbmi %d2, crc1
+ bpl signal_nonyb
+
+ moveb %a3@, %a4@(o_crc1)
+
+ tstb %a3@(read_error - read_mark)
+
+header_exit:
+ moveq #0, %d0
+ moveb #0x18, %a3@(write_mode0 - read_mark)
+ rts
+signal_nonyb:
+ moveq #-1, %d0
+ moveb #0x18, %a3@(write_mode0 - read_mark)
+ rts
+
+ .global swim_read_sector_data
+swim_read_sector_data:
+ link %a6, #0
+ moveml %d1-%d5/%a0-%a5,%sp@-
+ movel %a6@(0x0c), %a4
+ bsr mfm_read_data
+ moveml %sp@+, %d1-%d5/%a0-%a5
+ unlk %a6
+ rts
+
+mfm_read_data:
+ movel %a6@(0x08), %a3
+ lea %a3@(read_handshake), %a2
+ lea %a3@(read_data), %a5
+ lea %a3@(read_mark), %a3
+ movew #seek_time, %d2
+
+wait_data_init:
+ tstb %a3@(read_error - read_mark)
+ moveb #0x18, %a3@(write_mode0 - read_mark)
+ moveb #0x01, %a3@(write_mode1 - read_mark)
+ moveb #0x01, %a3@(write_mode0 - read_mark)
+ tstb %a3@(read_error - read_mark)
+ moveb #0x08, %a3@(write_mode1 - read_mark)
+
+ lea sector_data_mark, %a0
+ moveq #3, %d1
+
+ /* wait data address mark */
+
+wait_data_mark_byte:
+
+ tstb %a2@
+ dbmi %d2, wait_data_mark_byte
+ bpl data_exit
+
+ moveb %a3@, %d3
+ cmpb %a0@+, %d3
+ dbne %d1, wait_data_mark_byte
+ bne wait_data_init
+
+ /* read data */
+
+ tstb %a3@(read_error - read_mark)
+
+ movel #sector_size-1, %d4 /* sector size */
+read_new_data:
+ movew #max_retry, %d2
+read_data_loop:
+ moveb %a2@, %d5
+ andb #0xc0, %d5
+ dbne %d2, read_data_loop
+ beq data_exit
+ moveb %a5@, %a4@+
+ andb #0x40, %d5
+ dbne %d4, read_new_data
+ beq exit_loop
+ moveb %a5@, %a4@+
+ dbra %d4, read_new_data
+exit_loop:
+
+ /* read CRC */
+
+ movew #max_retry, %d2
+data_crc0:
+
+ tstb %a2@
+ dbmi %d2, data_crc0
+ bpl data_exit
+
+ moveb %a3@, %d5
+
+ moveq #max_retry, %d2
+
+data_crc1:
+
+ tstb %a2@
+ dbmi %d2, data_crc1
+ bpl data_exit
+
+ moveb %a3@, %d5
+
+ tstb %a3@(read_error - read_mark)
+
+ moveb #0x18, %a3@(write_mode0 - read_mark)
+
+ /* return number of bytes read */
+
+ movel #sector_size, %d0
+ addw #1, %d4
+ subl %d4, %d0
+ rts
+data_exit:
+ moveb #0x18, %a3@(write_mode0 - read_mark)
+ moveq #-1, %d0
+ rts
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 12fb816db7b0..69b7f8e77596 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -391,7 +391,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum);
*/
#ifdef CONFIG_USB_LIBUSUAL
-#define ub_usb_ids storage_usb_ids
+#define ub_usb_ids usb_storage_usb_ids
#else
static struct usb_device_id ub_usb_ids[] = {
@@ -2146,10 +2146,9 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
ep = &altsetting->endpoint[i].desc;
/* Is it a BULK endpoint? */
- if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
- == USB_ENDPOINT_XFER_BULK) {
+ if (usb_endpoint_xfer_bulk(ep)) {
/* BULK in or out? */
- if (ep->bEndpointAddress & USB_DIR_IN) {
+ if (usb_endpoint_dir_in(ep)) {
if (ep_in == NULL)
ep_in = ep;
} else {
@@ -2168,9 +2167,9 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,
sc->send_ctrl_pipe = usb_sndctrlpipe(dev, 0);
sc->recv_ctrl_pipe = usb_rcvctrlpipe(dev, 0);
sc->send_bulk_pipe = usb_sndbulkpipe(dev,
- ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ usb_endpoint_num(ep_out));
sc->recv_bulk_pipe = usb_rcvbulkpipe(dev,
- ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ usb_endpoint_num(ep_in));
return 0;
}
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 119be3442f28..6cccdc3f5220 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -89,6 +89,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
+#include <linux/ata.h>
#include <linux/hdreg.h>
#include <linux/platform_device.h>
#if defined(CONFIG_OF)
@@ -208,7 +209,7 @@ struct ace_device {
struct gendisk *gd;
/* Inserted CF card parameters */
- struct hd_driveid cf_id;
+ u16 cf_id[ATA_ID_WORDS];
};
static int ace_major;
@@ -402,21 +403,14 @@ static void ace_dump_regs(struct ace_device *ace)
ace_in32(ace, ACE_CFGLBA), ace_in(ace, ACE_FATSTAT));
}
-void ace_fix_driveid(struct hd_driveid *id)
+void ace_fix_driveid(u16 *id)
{
#if defined(__BIG_ENDIAN)
- u16 *buf = (void *)id;
int i;
/* All half words have wrong byte order; swap the bytes */
- for (i = 0; i < sizeof(struct hd_driveid); i += 2, buf++)
- *buf = le16_to_cpu(*buf);
-
- /* Some of the data values are 32bit; swap the half words */
- id->lba_capacity = ((id->lba_capacity >> 16) & 0x0000FFFF) |
- ((id->lba_capacity << 16) & 0xFFFF0000);
- id->spg = ((id->spg >> 16) & 0x0000FFFF) |
- ((id->spg << 16) & 0xFFFF0000);
+ for (i = 0; i < ATA_ID_WORDS; i++, id++)
+ *id = le16_to_cpu(*id);
#endif
}
@@ -614,7 +608,7 @@ static void ace_fsm_dostate(struct ace_device *ace)
break;
case ACE_FSM_STATE_IDENTIFY_COMPLETE:
- ace_fix_driveid(&ace->cf_id);
+ ace_fix_driveid(&ace->cf_id[0]);
ace_dump_mem(&ace->cf_id, 512); /* Debug: Dump out disk ID */
if (ace->data_result) {
@@ -627,9 +621,10 @@ static void ace_fsm_dostate(struct ace_device *ace)
ace->media_change = 0;
/* Record disk parameters */
- set_capacity(ace->gd, ace->cf_id.lba_capacity);
+ set_capacity(ace->gd,
+ ata_id_u32(&ace->cf_id, ATA_ID_LBA_CAPACITY));
dev_info(ace->dev, "capacity: %i sectors\n",
- ace->cf_id.lba_capacity);
+ ata_id_u32(&ace->cf_id, ATA_ID_LBA_CAPACITY));
}
/* We're done, drop to IDLE state and notify waiters */
@@ -928,12 +923,13 @@ static int ace_release(struct gendisk *disk, fmode_t mode)
static int ace_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
struct ace_device *ace = bdev->bd_disk->private_data;
+ u16 *cf_id = &ace->cf_id[0];
dev_dbg(ace->dev, "ace_getgeo()\n");
- geo->heads = ace->cf_id.heads;
- geo->sectors = ace->cf_id.sectors;
- geo->cylinders = ace->cf_id.cyls;
+ geo->heads = cf_id[ATA_ID_HEADS];
+ geo->sectors = cf_id[ATA_ID_SECTORS];
+ geo->cylinders = cf_id[ATA_ID_CYLS];
return 0;
}
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index d3f14bee0f19..2a00707aba3b 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -257,8 +257,7 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch
if (hdr & 0x10) {
BT_ERR("%s error in block", data->hdev->name);
- if (data->reassembly)
- kfree_skb(data->reassembly);
+ kfree_skb(data->reassembly);
data->reassembly = NULL;
return -EIO;
}
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index ff195c230825..d58e22b9f06a 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -359,9 +359,9 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
BT_ERR("Very strange (stat=0x%04x)", stat);
} else if ((stat & 0xff) != 0xff) {
if (stat & 0x0020) {
- int stat = bt3c_read(iobase, 0x7002) & 0x10;
+ int status = bt3c_read(iobase, 0x7002) & 0x10;
BT_INFO("%s: Antenna %s", info->hdev->name,
- stat ? "out" : "in");
+ status ? "out" : "in");
}
if (stat & 0x0001)
bt3c_receive(info);
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index b5fbda6d490a..e70c57ee4221 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -35,7 +35,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
-#define VERSION "0.4"
+#define VERSION "0.5"
static int ignore_dga;
static int ignore_csr;
@@ -171,6 +171,7 @@ struct btusb_data {
__u8 cmdreq_type;
+ unsigned int sco_num;
int isoc_altsetting;
int suspend_count;
};
@@ -496,11 +497,23 @@ static int btusb_open(struct hci_dev *hdev)
return 0;
err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
+ if (err < 0)
+ goto failed;
+
+ err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
if (err < 0) {
- clear_bit(BTUSB_INTR_RUNNING, &data->flags);
- clear_bit(HCI_RUNNING, &hdev->flags);
+ usb_kill_anchored_urbs(&data->intr_anchor);
+ goto failed;
}
+ set_bit(BTUSB_BULK_RUNNING, &data->flags);
+ btusb_submit_bulk_urb(hdev, GFP_KERNEL);
+
+ return 0;
+
+failed:
+ clear_bit(BTUSB_INTR_RUNNING, &data->flags);
+ clear_bit(HCI_RUNNING, &hdev->flags);
return err;
}
@@ -655,19 +668,10 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
BT_DBG("%s evt %d", hdev->name, evt);
- if (hdev->conn_hash.acl_num > 0) {
- if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
- if (btusb_submit_bulk_urb(hdev, GFP_ATOMIC) < 0)
- clear_bit(BTUSB_BULK_RUNNING, &data->flags);
- else
- btusb_submit_bulk_urb(hdev, GFP_ATOMIC);
- }
- } else {
- clear_bit(BTUSB_BULK_RUNNING, &data->flags);
- usb_unlink_anchored_urbs(&data->bulk_anchor);
+ if (hdev->conn_hash.sco_num != data->sco_num) {
+ data->sco_num = hdev->conn_hash.sco_num;
+ schedule_work(&data->work);
}
-
- schedule_work(&data->work);
}
static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
@@ -982,9 +986,11 @@ static int btusb_resume(struct usb_interface *intf)
}
if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
- if (btusb_submit_bulk_urb(hdev, GFP_NOIO) < 0)
+ err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
+ if (err < 0) {
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
- else
+ return err;
+ } else
btusb_submit_bulk_urb(hdev, GFP_NOIO);
}
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index b0fafb055996..c0ce8134814e 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -102,8 +102,7 @@ static int h4_close(struct hci_uart *hu)
skb_queue_purge(&h4->txq);
- if (h4->rx_skb)
- kfree_skb(h4->rx_skb);
+ kfree_skb(h4->rx_skb);
hu->priv = NULL;
kfree(h4);
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index b91d45a41b2f..5c65014635be 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -163,8 +163,7 @@ static int ll_close(struct hci_uart *hu)
skb_queue_purge(&ll->tx_wait_q);
skb_queue_purge(&ll->txq);
- if (ll->rx_skb)
- kfree_skb(ll->rx_skb);
+ kfree_skb(ll->rx_skb);
hu->priv = NULL;
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 4373adb2119a..9d9490e22e07 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -26,6 +26,10 @@
#define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12
#define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC
#define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE
+#define PCI_DEVICE_ID_INTEL_IGDGM_HB 0xA010
+#define PCI_DEVICE_ID_INTEL_IGDGM_IG 0xA011
+#define PCI_DEVICE_ID_INTEL_IGDG_HB 0xA000
+#define PCI_DEVICE_ID_INTEL_IGDG_IG 0xA001
#define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0
#define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2
#define PCI_DEVICE_ID_INTEL_Q35_HB 0x29B0
@@ -60,7 +64,12 @@
#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB)
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB)
+
+#define IS_IGD (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB)
#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
@@ -510,7 +519,7 @@ static void intel_i830_init_gtt_entries(void)
size = 512;
}
size += 4; /* add in BIOS popup space */
- } else if (IS_G33) {
+ } else if (IS_G33 && !IS_IGD) {
/* G33's GTT size defined in gmch_ctrl */
switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
case G33_PGETBL_SIZE_1M:
@@ -526,7 +535,7 @@ static void intel_i830_init_gtt_entries(void)
size = 512;
}
size += 4;
- } else if (IS_G4X) {
+ } else if (IS_G4X || IS_IGD) {
/* On 4 series hardware, GTT stolen is separate from graphics
* stolen, ignore it in stolen gtt entries counting. However,
* 4KB of the stolen memory doesn't get mapped to the GTT.
@@ -2161,6 +2170,10 @@ static const struct intel_driver_description {
NULL, &intel_g33_driver },
{ PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33",
NULL, &intel_g33_driver },
+ { PCI_DEVICE_ID_INTEL_IGDGM_HB, PCI_DEVICE_ID_INTEL_IGDGM_IG, 0, "IGD",
+ NULL, &intel_g33_driver },
+ { PCI_DEVICE_ID_INTEL_IGDG_HB, PCI_DEVICE_ID_INTEL_IGDG_IG, 0, "IGD",
+ NULL, &intel_g33_driver },
{ PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0,
"Mobile Intel® GM45 Express", NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0,
@@ -2355,6 +2368,8 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_82945G_HB),
ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
+ ID(PCI_DEVICE_ID_INTEL_IGDGM_HB),
+ ID(PCI_DEVICE_ID_INTEL_IGDG_HB),
ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
ID(PCI_DEVICE_ID_INTEL_82G35_HB),
ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index a58869ea8513..fd3ebd1be570 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -79,6 +79,7 @@ static char *serial_version = "4.30";
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/bitops.h>
@@ -1825,14 +1826,13 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
* /proc fs routines....
*/
-static inline int line_info(char *buf, struct serial_state *state)
+static inline void line_info(struct seq_file *m, struct serial_state *state)
{
struct async_struct *info = state->info, scr_info;
char stat_buf[30], control, status;
- int ret;
unsigned long flags;
- ret = sprintf(buf, "%d: uart:amiga_builtin",state->line);
+ seq_printf(m, "%d: uart:amiga_builtin",state->line);
/*
* Figure out the current RS-232 lines
@@ -1864,55 +1864,49 @@ static inline int line_info(char *buf, struct serial_state *state)
strcat(stat_buf, "|CD");
if (info->quot) {
- ret += sprintf(buf+ret, " baud:%d",
- state->baud_base / info->quot);
+ seq_printf(m, " baud:%d", state->baud_base / info->quot);
}
- ret += sprintf(buf+ret, " tx:%d rx:%d",
- state->icount.tx, state->icount.rx);
+ seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx);
if (state->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+ seq_printf(m, " fe:%d", state->icount.frame);
if (state->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+ seq_printf(m, " pe:%d", state->icount.parity);
if (state->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", state->icount.brk);
+ seq_printf(m, " brk:%d", state->icount.brk);
if (state->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+ seq_printf(m, " oe:%d", state->icount.overrun);
/*
* Last thing is the RS-232 status lines
*/
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
- return ret;
+ seq_printf(m, " %s\n", stat_buf+1);
}
-static int rs_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int rs_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
-
- len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
- l = line_info(page + len, &rs_table[0]);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
+ seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version);
+ line_info(m, &rs_table[0]);
+ return 0;
}
+static int rs_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, rs_proc_show, NULL);
+}
+
+static const struct file_operations rs_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = rs_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*
* ---------------------------------------------------------------------
* rs_init() and friends
@@ -1951,9 +1945,9 @@ static const struct tty_operations serial_ops = {
.break_ctl = rs_break,
.send_xchar = rs_send_xchar,
.wait_until_sent = rs_wait_until_sent,
- .read_proc = rs_read_proc,
.tiocmget = rs_tiocmget,
.tiocmset = rs_tiocmset,
+ .proc_fops = &rs_proc_fops,
};
/*
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 05674febb0c6..73a0765344b6 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -75,6 +75,7 @@ MODULE_DEVICE_TABLE(pci, applicom_pci_tbl);
MODULE_AUTHOR("David Woodhouse & Applicom International");
MODULE_DESCRIPTION("Driver for Applicom Profibus card");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(AC_MINOR);
MODULE_SUPPORTED_DEVICE("ac");
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index f6094ae0ef33..140ea10ecb88 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -140,7 +140,7 @@ static int bsr_open(struct inode * inode, struct file * filp)
return 0;
}
-const static struct file_operations bsr_fops = {
+static const struct file_operations bsr_fops = {
.owner = THIS_MODULE,
.mmap = bsr_mmap,
.open = bsr_open,
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 6a59f72a9c21..1fdb9f657d8f 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -646,6 +646,7 @@
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/firmware.h>
+#include <linux/device.h>
#include <asm/system.h>
#include <linux/io.h>
@@ -657,6 +658,7 @@
#include <linux/stat.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
static void cy_throttle(struct tty_struct *tty);
static void cy_send_xchar(struct tty_struct *tty, char ch);
@@ -868,8 +870,6 @@ static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32);
static unsigned detect_isa_irq(void __iomem *);
#endif /* CONFIG_ISA */
-static int cyclades_get_proc_info(char *, char **, off_t, int, int *, void *);
-
#ifndef CONFIG_CYZ_INTR
static void cyz_poll(unsigned long);
@@ -5216,31 +5216,22 @@ static struct pci_driver cy_pci_driver = {
};
#endif
-static int
-cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
- int *eof, void *data)
+static int cyclades_proc_show(struct seq_file *m, void *v)
{
struct cyclades_port *info;
unsigned int i, j;
- int len = 0;
- off_t begin = 0;
- off_t pos = 0;
- int size;
__u32 cur_jifs = jiffies;
- size = sprintf(buf, "Dev TimeOpen BytesOut IdleOut BytesIn "
+ seq_puts(m, "Dev TimeOpen BytesOut IdleOut BytesIn "
"IdleIn Overruns Ldisc\n");
- pos += size;
- len += size;
-
/* Output one line for each known port */
for (i = 0; i < NR_CARDS; i++)
for (j = 0; j < cy_card[i].nports; j++) {
info = &cy_card[i].ports[j];
if (info->port.count)
- size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+ seq_printf(m, "%3d %8lu %10lu %8lu "
"%10lu %8lu %9lu %6ld\n", info->line,
(cur_jifs - info->idle_stats.in_use) /
HZ, info->idle_stats.xmit_bytes,
@@ -5251,30 +5242,26 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
/* FIXME: double check locking */
(long)info->port.tty->ldisc.ops->num);
else
- size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+ seq_printf(m, "%3d %8lu %10lu %8lu "
"%10lu %8lu %9lu %6ld\n",
info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
- len += size;
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- goto done;
}
- *eof = 1;
-done:
- *start = buf + (offset - begin); /* Start of wanted data */
- len -= (offset - begin); /* Start slop */
- if (len > length)
- len = length; /* Ending slop */
- if (len < 0)
- len = 0;
- return len;
+ return 0;
+}
+
+static int cyclades_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, cyclades_proc_show, NULL);
}
+static const struct file_operations cyclades_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = cyclades_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/* The serial driver boot-time initialization code!
Hardware I/O ports are mapped to character special devices on a
first found, first allocated manner. That is, this code searches
@@ -5311,9 +5298,9 @@ static const struct tty_operations cy_ops = {
.hangup = cy_hangup,
.break_ctl = cy_break,
.wait_until_sent = cy_wait_until_sent,
- .read_proc = cyclades_get_proc_info,
.tiocmget = cy_tiocmget,
.tiocmset = cy_tiocmset,
+ .proc_fops = &cyclades_proc_fops,
};
static int __init cy_init(void)
@@ -5422,3 +5409,4 @@ module_exit(cy_cleanup_module);
MODULE_LICENSE("GPL");
MODULE_VERSION(CY_VERSION);
+MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR);
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 32b8bbf5003e..50dfa3bc71ce 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -713,7 +713,7 @@ static struct ctl_table_header *sysctl_header;
*/
#define TICK_CALIBRATE (1000UL)
-static unsigned long hpet_calibrate(struct hpets *hpetp)
+static unsigned long __hpet_calibrate(struct hpets *hpetp)
{
struct hpet_timer __iomem *timer = NULL;
unsigned long t, m, count, i, flags, start;
@@ -750,6 +750,26 @@ static unsigned long hpet_calibrate(struct hpets *hpetp)
return (m - start) / i;
}
+static unsigned long hpet_calibrate(struct hpets *hpetp)
+{
+ unsigned long ret = -1;
+ unsigned long tmp;
+
+ /*
+ * Try to calibrate until return value becomes stable small value.
+ * If SMI interruption occurs in calibration loop, the return value
+ * will be big. This avoids its impact.
+ */
+ for ( ; ; ) {
+ tmp = __hpet_calibrate(hpetp);
+ if (ret <= tmp)
+ break;
+ ret = tmp;
+ }
+
+ return ret;
+}
+
int hpet_alloc(struct hpet_data *hdp)
{
u64 cap, mcfg;
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c
index a53496828b76..54481a887769 100644
--- a/drivers/char/hvc_iucv.c
+++ b/drivers/char/hvc_iucv.c
@@ -13,10 +13,11 @@
#include <linux/types.h>
#include <asm/ebcdic.h>
+#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/mempool.h>
-#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/tty.h>
#include <linux/wait.h>
#include <net/iucv/iucv.h>
@@ -95,6 +96,12 @@ static unsigned long hvc_iucv_devices = 1;
/* Array of allocated hvc iucv tty lines... */
static struct hvc_iucv_private *hvc_iucv_table[MAX_HVC_IUCV_LINES];
#define IUCV_HVC_CON_IDX (0)
+/* List of z/VM user ID filter entries (struct iucv_vmid_filter) */
+#define MAX_VMID_FILTER (500)
+static size_t hvc_iucv_filter_size;
+static void *hvc_iucv_filter;
+static const char *hvc_iucv_filter_string;
+static DEFINE_RWLOCK(hvc_iucv_filter_lock);
/* Kmem cache and mempool for iucv_tty_buffer elements */
static struct kmem_cache *hvc_iucv_buffer_cache;
@@ -618,6 +625,27 @@ static void hvc_iucv_notifier_del(struct hvc_struct *hp, int id)
}
/**
+ * hvc_iucv_filter_connreq() - Filter connection request based on z/VM user ID
+ * @ipvmid: Originating z/VM user ID (right padded with blanks)
+ *
+ * Returns 0 if the z/VM user ID @ipvmid is allowed to connection, otherwise
+ * non-zero.
+ */
+static int hvc_iucv_filter_connreq(u8 ipvmid[8])
+{
+ size_t i;
+
+ /* Note: default policy is ACCEPT if no filter is set */
+ if (!hvc_iucv_filter_size)
+ return 0;
+
+ for (i = 0; i < hvc_iucv_filter_size; i++)
+ if (0 == memcmp(ipvmid, hvc_iucv_filter + (8 * i), 8))
+ return 0;
+ return 1;
+}
+
+/**
* hvc_iucv_path_pending() - IUCV handler to process a connection request.
* @path: Pending path (struct iucv_path)
* @ipvmid: z/VM system identifier of originator
@@ -641,6 +669,7 @@ static int hvc_iucv_path_pending(struct iucv_path *path,
{
struct hvc_iucv_private *priv;
u8 nuser_data[16];
+ u8 vm_user_id[9];
int i, rc;
priv = NULL;
@@ -653,6 +682,20 @@ static int hvc_iucv_path_pending(struct iucv_path *path,
if (!priv)
return -ENODEV;
+ /* Enforce that ipvmid is allowed to connect to us */
+ read_lock(&hvc_iucv_filter_lock);
+ rc = hvc_iucv_filter_connreq(ipvmid);
+ read_unlock(&hvc_iucv_filter_lock);
+ if (rc) {
+ iucv_path_sever(path, ipuser);
+ iucv_path_free(path);
+ memcpy(vm_user_id, ipvmid, 8);
+ vm_user_id[8] = 0;
+ pr_info("A connection request from z/VM user ID %s "
+ "was refused\n", vm_user_id);
+ return 0;
+ }
+
spin_lock(&priv->lock);
/* If the terminal is already connected or being severed, then sever
@@ -877,6 +920,171 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console)
}
/**
+ * hvc_iucv_parse_filter() - Parse filter for a single z/VM user ID
+ * @filter: String containing a comma-separated list of z/VM user IDs
+ */
+static const char *hvc_iucv_parse_filter(const char *filter, char *dest)
+{
+ const char *nextdelim, *residual;
+ size_t len;
+
+ nextdelim = strchr(filter, ',');
+ if (nextdelim) {
+ len = nextdelim - filter;
+ residual = nextdelim + 1;
+ } else {
+ len = strlen(filter);
+ residual = filter + len;
+ }
+
+ if (len == 0)
+ return ERR_PTR(-EINVAL);
+
+ /* check for '\n' (if called from sysfs) */
+ if (filter[len - 1] == '\n')
+ len--;
+
+ if (len > 8)
+ return ERR_PTR(-EINVAL);
+
+ /* pad with blanks and save upper case version of user ID */
+ memset(dest, ' ', 8);
+ while (len--)
+ dest[len] = toupper(filter[len]);
+ return residual;
+}
+
+/**
+ * hvc_iucv_setup_filter() - Set up z/VM user ID filter
+ * @filter: String consisting of a comma-separated list of z/VM user IDs
+ *
+ * The function parses the @filter string and creates an array containing
+ * the list of z/VM user ID filter entries.
+ * Return code 0 means success, -EINVAL if the filter is syntactically
+ * incorrect, -ENOMEM if there was not enough memory to allocate the
+ * filter list array, or -ENOSPC if too many z/VM user IDs have been specified.
+ */
+static int hvc_iucv_setup_filter(const char *val)
+{
+ const char *residual;
+ int err;
+ size_t size, count;
+ void *array, *old_filter;
+
+ count = strlen(val);
+ if (count == 0 || (count == 1 && val[0] == '\n')) {
+ size = 0;
+ array = NULL;
+ goto out_replace_filter; /* clear filter */
+ }
+
+ /* count user IDs in order to allocate sufficient memory */
+ size = 1;
+ residual = val;
+ while ((residual = strchr(residual, ',')) != NULL) {
+ residual++;
+ size++;
+ }
+
+ /* check if the specified list exceeds the filter limit */
+ if (size > MAX_VMID_FILTER)
+ return -ENOSPC;
+
+ array = kzalloc(size * 8, GFP_KERNEL);
+ if (!array)
+ return -ENOMEM;
+
+ count = size;
+ residual = val;
+ while (*residual && count) {
+ residual = hvc_iucv_parse_filter(residual,
+ array + ((size - count) * 8));
+ if (IS_ERR(residual)) {
+ err = PTR_ERR(residual);
+ kfree(array);
+ goto out_err;
+ }
+ count--;
+ }
+
+out_replace_filter:
+ write_lock_bh(&hvc_iucv_filter_lock);
+ old_filter = hvc_iucv_filter;
+ hvc_iucv_filter_size = size;
+ hvc_iucv_filter = array;
+ write_unlock_bh(&hvc_iucv_filter_lock);
+ kfree(old_filter);
+
+ err = 0;
+out_err:
+ return err;
+}
+
+/**
+ * param_set_vmidfilter() - Set z/VM user ID filter parameter
+ * @val: String consisting of a comma-separated list of z/VM user IDs
+ * @kp: Kernel parameter pointing to hvc_iucv_filter array
+ *
+ * The function sets up the z/VM user ID filter specified as comma-separated
+ * list of user IDs in @val.
+ * Note: If it is called early in the boot process, @val is stored and
+ * parsed later in hvc_iucv_init().
+ */
+static int param_set_vmidfilter(const char *val, struct kernel_param *kp)
+{
+ int rc;
+
+ if (!MACHINE_IS_VM || !hvc_iucv_devices)
+ return -ENODEV;
+
+ if (!val)
+ return -EINVAL;
+
+ rc = 0;
+ if (slab_is_available())
+ rc = hvc_iucv_setup_filter(val);
+ else
+ hvc_iucv_filter_string = val; /* defer... */
+ return rc;
+}
+
+/**
+ * param_get_vmidfilter() - Get z/VM user ID filter
+ * @buffer: Buffer to store z/VM user ID filter,
+ * (buffer size assumption PAGE_SIZE)
+ * @kp: Kernel parameter pointing to the hvc_iucv_filter array
+ *
+ * The function stores the filter as a comma-separated list of z/VM user IDs
+ * in @buffer. Typically, sysfs routines call this function for attr show.
+ */
+static int param_get_vmidfilter(char *buffer, struct kernel_param *kp)
+{
+ int rc;
+ size_t index, len;
+ void *start, *end;
+
+ if (!MACHINE_IS_VM || !hvc_iucv_devices)
+ return -ENODEV;
+
+ rc = 0;
+ read_lock_bh(&hvc_iucv_filter_lock);
+ for (index = 0; index < hvc_iucv_filter_size; index++) {
+ start = hvc_iucv_filter + (8 * index);
+ end = memchr(start, ' ', 8);
+ len = (end) ? end - start : 8;
+ memcpy(buffer + rc, start, len);
+ rc += len;
+ buffer[rc++] = ',';
+ }
+ read_unlock_bh(&hvc_iucv_filter_lock);
+ if (rc)
+ buffer[--rc] = '\0'; /* replace last comma and update rc */
+ return rc;
+}
+
+#define param_check_vmidfilter(name, p) __param_check(name, p, void)
+
+/**
* hvc_iucv_init() - z/VM IUCV HVC device driver initialization
*/
static int __init hvc_iucv_init(void)
@@ -884,24 +1092,53 @@ static int __init hvc_iucv_init(void)
int rc;
unsigned int i;
+ if (!hvc_iucv_devices)
+ return -ENODEV;
+
if (!MACHINE_IS_VM) {
- pr_info("The z/VM IUCV HVC device driver cannot "
+ pr_notice("The z/VM IUCV HVC device driver cannot "
"be used without z/VM\n");
- return -ENODEV;
+ rc = -ENODEV;
+ goto out_error;
}
- if (!hvc_iucv_devices)
- return -ENODEV;
+ if (hvc_iucv_devices > MAX_HVC_IUCV_LINES) {
+ pr_err("%lu is not a valid value for the hvc_iucv= "
+ "kernel parameter\n", hvc_iucv_devices);
+ rc = -EINVAL;
+ goto out_error;
+ }
- if (hvc_iucv_devices > MAX_HVC_IUCV_LINES)
- return -EINVAL;
+ /* parse hvc_iucv_allow string and create z/VM user ID filter list */
+ if (hvc_iucv_filter_string) {
+ rc = hvc_iucv_setup_filter(hvc_iucv_filter_string);
+ switch (rc) {
+ case 0:
+ break;
+ case -ENOMEM:
+ pr_err("Allocating memory failed with "
+ "reason code=%d\n", 3);
+ goto out_error;
+ case -EINVAL:
+ pr_err("hvc_iucv_allow= does not specify a valid "
+ "z/VM user ID list\n");
+ goto out_error;
+ case -ENOSPC:
+ pr_err("hvc_iucv_allow= specifies too many "
+ "z/VM user IDs\n");
+ goto out_error;
+ default:
+ goto out_error;
+ }
+ }
hvc_iucv_buffer_cache = kmem_cache_create(KMSG_COMPONENT,
sizeof(struct iucv_tty_buffer),
0, 0, NULL);
if (!hvc_iucv_buffer_cache) {
pr_err("Allocating memory failed with reason code=%d\n", 1);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto out_error;
}
hvc_iucv_mempool = mempool_create_slab_pool(MEMPOOL_MIN_NR,
@@ -909,7 +1146,8 @@ static int __init hvc_iucv_init(void)
if (!hvc_iucv_mempool) {
pr_err("Allocating memory failed with reason code=%d\n", 2);
kmem_cache_destroy(hvc_iucv_buffer_cache);
- return -ENOMEM;
+ rc = -ENOMEM;
+ goto out_error;
}
/* register the first terminal device as console
@@ -953,6 +1191,8 @@ out_error_hvc:
out_error_memory:
mempool_destroy(hvc_iucv_mempool);
kmem_cache_destroy(hvc_iucv_buffer_cache);
+out_error:
+ hvc_iucv_devices = 0; /* ensure that we do not provide any device */
return rc;
}
@@ -968,3 +1208,4 @@ static int __init hvc_iucv_config(char *val)
device_initcall(hvc_iucv_init);
__setup("hvc_iucv=", hvc_iucv_config);
+core_param(hvc_iucv_allow, hvc_iucv_filter, vmidfilter, 0640);
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 8822eca58ffa..5fab6470f4b2 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -20,6 +20,20 @@ config HW_RANDOM
If unsure, say Y.
+config HW_RANDOM_TIMERIOMEM
+ tristate "Timer IOMEM HW Random Number Generator support"
+ depends on HW_RANDOM && HAS_IOMEM
+ ---help---
+ This driver provides kernel-side support for a generic Random
+ Number Generator used by reading a 'dumb' iomem address that
+ is to be read no faster than, for example, once a second;
+ the default FPGA bitstream on the TS-7800 has such functionality.
+
+ To compile this driver as a module, choose M here: the
+ module will be called timeriomem-rng.
+
+ If unsure, say Y.
+
config HW_RANDOM_INTEL
tristate "Intel HW Random Number Generator support"
depends on HW_RANDOM && (X86 || IA64) && PCI
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index b6effb7522c2..e81d21a5f28f 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -4,6 +4,7 @@
obj-$(CONFIG_HW_RANDOM) += rng-core.o
rng-core-y := core.o
+obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o
obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index ba68a4671cb5..538313f9e7ac 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -102,7 +102,7 @@ static int __init omap_rng_probe(struct platform_device *pdev)
return -EBUSY;
if (cpu_is_omap24xx()) {
- rng_ick = clk_get(&pdev->dev, "rng_ick");
+ rng_ick = clk_get(&pdev->dev, "ick");
if (IS_ERR(rng_ick)) {
dev_err(&pdev->dev, "Could not get rng_ick\n");
ret = PTR_ERR(rng_ick);
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c
new file mode 100644
index 000000000000..dcd352ad0e7f
--- /dev/null
+++ b/drivers/char/hw_random/timeriomem-rng.c
@@ -0,0 +1,182 @@
+/*
+ * drivers/char/hw_random/timeriomem-rng.c
+ *
+ * Copyright (C) 2009 Alexander Clouter <alex@digriz.org.uk>
+ *
+ * Derived from drivers/char/hw_random/omap-rng.c
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Overview:
+ * This driver is useful for platforms that have an IO range that provides
+ * periodic random data from a single IO memory address. All the platform
+ * has to do is provide the address and 'wait time' that new data becomes
+ * available.
+ *
+ * TODO: add support for reading sizes other than 32bits and masking
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/timeriomem-rng.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/completion.h>
+
+static struct timeriomem_rng_data *timeriomem_rng_data;
+
+static void timeriomem_rng_trigger(unsigned long);
+static DEFINE_TIMER(timeriomem_rng_timer, timeriomem_rng_trigger, 0, 0);
+
+/*
+ * have data return 1, however return 0 if we have nothing
+ */
+static int timeriomem_rng_data_present(struct hwrng *rng, int wait)
+{
+ if (rng->priv == 0)
+ return 1;
+
+ if (!wait || timeriomem_rng_data->present)
+ return timeriomem_rng_data->present;
+
+ wait_for_completion(&timeriomem_rng_data->completion);
+
+ return 1;
+}
+
+static int timeriomem_rng_data_read(struct hwrng *rng, u32 *data)
+{
+ unsigned long cur;
+ s32 delay;
+
+ *data = readl(timeriomem_rng_data->address);
+
+ if (rng->priv != 0) {
+ cur = jiffies;
+
+ delay = cur - timeriomem_rng_timer.expires;
+ delay = rng->priv - (delay % rng->priv);
+
+ timeriomem_rng_timer.expires = cur + delay;
+ timeriomem_rng_data->present = 0;
+
+ init_completion(&timeriomem_rng_data->completion);
+ add_timer(&timeriomem_rng_timer);
+ }
+
+ return 4;
+}
+
+static void timeriomem_rng_trigger(unsigned long dummy)
+{
+ timeriomem_rng_data->present = 1;
+ complete(&timeriomem_rng_data->completion);
+}
+
+static struct hwrng timeriomem_rng_ops = {
+ .name = "timeriomem",
+ .data_present = timeriomem_rng_data_present,
+ .data_read = timeriomem_rng_data_read,
+ .priv = 0,
+};
+
+static int __init timeriomem_rng_probe(struct platform_device *pdev)
+{
+ struct resource *res, *mem;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (!res)
+ return -ENOENT;
+
+ mem = request_mem_region(res->start, res->end - res->start + 1,
+ pdev->name);
+ if (mem == NULL)
+ return -EBUSY;
+
+ dev_set_drvdata(&pdev->dev, mem);
+
+ timeriomem_rng_data = pdev->dev.platform_data;
+
+ timeriomem_rng_data->address = ioremap(res->start,
+ res->end - res->start + 1);
+ if (!timeriomem_rng_data->address) {
+ ret = -ENOMEM;
+ goto err_ioremap;
+ }
+
+ if (timeriomem_rng_data->period != 0
+ && usecs_to_jiffies(timeriomem_rng_data->period) > 0) {
+ timeriomem_rng_timer.expires = jiffies;
+
+ timeriomem_rng_ops.priv = usecs_to_jiffies(
+ timeriomem_rng_data->period);
+ }
+ timeriomem_rng_data->present = 1;
+
+ ret = hwrng_register(&timeriomem_rng_ops);
+ if (ret)
+ goto err_register;
+
+ dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n",
+ timeriomem_rng_data->address,
+ timeriomem_rng_data->period);
+
+ return 0;
+
+err_register:
+ dev_err(&pdev->dev, "problem registering\n");
+ iounmap(timeriomem_rng_data->address);
+err_ioremap:
+ release_resource(mem);
+
+ return ret;
+}
+
+static int __devexit timeriomem_rng_remove(struct platform_device *pdev)
+{
+ struct resource *mem = dev_get_drvdata(&pdev->dev);
+
+ del_timer_sync(&timeriomem_rng_timer);
+ hwrng_unregister(&timeriomem_rng_ops);
+
+ iounmap(timeriomem_rng_data->address);
+ release_resource(mem);
+
+ return 0;
+}
+
+static struct platform_driver timeriomem_rng_driver = {
+ .driver = {
+ .name = "timeriomem_rng",
+ .owner = THIS_MODULE,
+ },
+ .probe = timeriomem_rng_probe,
+ .remove = __devexit_p(timeriomem_rng_remove),
+};
+
+static int __init timeriomem_rng_init(void)
+{
+ return platform_driver_register(&timeriomem_rng_driver);
+}
+
+static void __exit timeriomem_rng_exit(void)
+{
+ platform_driver_unregister(&timeriomem_rng_driver);
+}
+
+module_init(timeriomem_rng_init);
+module_exit(timeriomem_rng_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
+MODULE_DESCRIPTION("Timer IOMEM H/W RNG driver");
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 70e0ebc30bd0..afd9247cf082 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -139,7 +139,7 @@
#include <linux/seq_file.h>
static const struct file_operations ip2mem_proc_fops;
-static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
+static const struct file_operations ip2_proc_fops;
/********************/
/* Type Definitions */
@@ -446,9 +446,9 @@ static const struct tty_operations ip2_ops = {
.stop = ip2_stop,
.start = ip2_start,
.hangup = ip2_hangup,
- .read_proc = ip2_read_proc,
.tiocmget = ip2_tiocmget,
.tiocmset = ip2_tiocmset,
+ .proc_fops = &ip2_proc_fops,
};
/******************************************************************************/
@@ -3029,19 +3029,17 @@ static const struct file_operations ip2mem_proc_fops = {
* different sources including ip2mkdev.c and a couple of other drivers.
* The bugs are all mine. :-) =mhw=
*/
-static int ip2_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static int ip2_proc_show(struct seq_file *m, void *v)
{
int i, j, box;
- int len = 0;
int boxes = 0;
int ports = 0;
int tports = 0;
- off_t begin = 0;
i2eBordStrPtr pB;
+ char *sep;
- len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion );
- len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
+ seq_printf(m, "ip2info: 1.0 driver: %s\n", pcVersion);
+ seq_printf(m, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
@@ -3053,7 +3051,8 @@ static int ip2_read_proc(char *page, char **start, off_t off,
switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED )
{
case POR_ID_FIIEX:
- len += sprintf( page+len, "Board %d: EX ports=", i );
+ seq_printf(m, "Board %d: EX ports=", i);
+ sep = "";
for( box = 0; box < ABS_MAX_BOXES; ++box )
{
ports = 0;
@@ -3065,79 +3064,74 @@ static int ip2_read_proc(char *page, char **start, off_t off,
++ports;
}
}
- len += sprintf( page+len, "%d,", ports );
+ seq_printf(m, "%s%d", sep, ports);
+ sep = ",";
tports += ports;
}
-
- --len; /* Backup over that last comma */
-
- len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 );
+ seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8);
break;
case POR_ID_II_4:
- len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i );
+ seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i);
tports = ports = 4;
break;
case POR_ID_II_8:
- len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i );
+ seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i);
tports = ports = 8;
break;
case POR_ID_II_8R:
- len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i );
+ seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i);
tports = ports = 8;
break;
default:
- len += sprintf(page+len, "Board %d: unknown", i );
+ seq_printf(m, "Board %d: unknown", i);
/* Don't try and probe for minor numbers */
tports = ports = 0;
}
} else {
/* Don't try and probe for minor numbers */
- len += sprintf(page+len, "Board %d: vacant", i );
+ seq_printf(m, "Board %d: vacant", i);
tports = ports = 0;
}
if( tports ) {
- len += sprintf(page+len, " minors=" );
-
+ seq_puts(m, " minors=");
+ sep = "";
for ( box = 0; box < ABS_MAX_BOXES; ++box )
{
for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
{
if ( pB->i2eChannelMap[box] & (1 << j) )
{
- len += sprintf (page+len,"%d,",
+ seq_printf(m, "%s%d", sep,
j + ABS_BIGGEST_BOX *
(box+i*ABS_MAX_BOXES));
+ sep = ",";
}
}
}
-
- page[ len - 1 ] = '\n'; /* Overwrite that last comma */
- } else {
- len += sprintf (page+len,"\n" );
- }
-
- if (len+begin > off+count)
- break;
- if (len+begin < off) {
- begin += len;
- len = 0;
}
+ seq_putc(m, '\n');
}
+ return 0;
+ }
- if (i >= IP2_MAX_BOARDS)
- *eof = 1;
- if (off >= len+begin)
- return 0;
+static int ip2_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ip2_proc_show, NULL);
+}
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
- }
+static const struct file_operations ip2_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ip2_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
/******************************************************************************/
/* Function: ip2trace() */
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 7a88dfd4427b..e93fc8d22fb2 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -1944,7 +1944,7 @@ static int stat_file_read_proc(char *page, char **start, off_t off,
int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
read_proc_t *read_proc,
- void *data, struct module *owner)
+ void *data)
{
int rv = 0;
#ifdef CONFIG_PROC_FS
@@ -1970,7 +1970,6 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
} else {
file->data = data;
file->read_proc = read_proc;
- file->owner = owner;
mutex_lock(&smi->proc_entry_lock);
/* Stick it on the list. */
@@ -1993,23 +1992,21 @@ static int add_proc_entries(ipmi_smi_t smi, int num)
smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root);
if (!smi->proc_dir)
rv = -ENOMEM;
- else
- smi->proc_dir->owner = THIS_MODULE;
if (rv == 0)
rv = ipmi_smi_add_proc_entry(smi, "stats",
stat_file_read_proc,
- smi, THIS_MODULE);
+ smi);
if (rv == 0)
rv = ipmi_smi_add_proc_entry(smi, "ipmb",
ipmb_file_read_proc,
- smi, THIS_MODULE);
+ smi);
if (rv == 0)
rv = ipmi_smi_add_proc_entry(smi, "version",
version_file_read_proc,
- smi, THIS_MODULE);
+ smi);
#endif /* CONFIG_PROC_FS */
return rv;
@@ -4265,7 +4262,6 @@ static int ipmi_init_msghandler(void)
return -ENOMEM;
}
- proc_ipmi_root->owner = THIS_MODULE;
#endif /* CONFIG_PROC_FS */
setup_timer(&ipmi_timer, ipmi_timeout, 0);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 3000135f2ead..e58ea4cd55ce 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -2899,7 +2899,7 @@ static int try_smi_init(struct smi_info *new_smi)
rv = ipmi_smi_add_proc_entry(new_smi->intf, "type",
type_file_read_proc,
- new_smi, THIS_MODULE);
+ new_smi);
if (rv) {
printk(KERN_ERR
"ipmi_si: Unable to create proc entry: %d\n",
@@ -2909,7 +2909,7 @@ static int try_smi_init(struct smi_info *new_smi)
rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats",
stat_file_read_proc,
- new_smi, THIS_MODULE);
+ new_smi);
if (rv) {
printk(KERN_ERR
"ipmi_si: Unable to create proc entry: %d\n",
@@ -2919,7 +2919,7 @@ static int try_smi_init(struct smi_info *new_smi)
rv = ipmi_smi_add_proc_entry(new_smi->intf, "params",
param_read_proc,
- new_smi, THIS_MODULE);
+ new_smi);
if (rv) {
printk(KERN_ERR
"ipmi_si: Unable to create proc entry: %d\n",
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 24aa6e88e223..a59eac584d16 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -925,6 +925,7 @@ static void isicom_shutdown_port(struct isi_port *port)
if (!card->count)
isicom_shutdown_board(card);
}
+ tty_kref_put(tty);
}
static void isicom_flush_buffer(struct tty_struct *tty)
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 5c3dc6b8411c..fff19f7e29d2 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -24,6 +24,7 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
+#include <linux/seq_file.h>
#include <linux/cdk.h>
#include <linux/comstats.h>
#include <linux/istallion.h>
@@ -613,7 +614,6 @@ static int stli_breakctl(struct tty_struct *tty, int state);
static void stli_waituntilsent(struct tty_struct *tty, int timeout);
static void stli_sendxchar(struct tty_struct *tty, char ch);
static void stli_hangup(struct tty_struct *tty);
-static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos);
static int stli_brdinit(struct stlibrd *brdp);
static int stli_startbrd(struct stlibrd *brdp);
@@ -1893,20 +1893,10 @@ static void stli_sendxchar(struct tty_struct *tty, char ch)
stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
}
-/*****************************************************************************/
-
-#define MAXLINE 80
-
-/*
- * Format info for a specified port. The line is deliberately limited
- * to 80 characters. (If it is too long it will be truncated, if too
- * short then padded with spaces).
- */
-
-static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos)
+static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stliport *portp, int portnr)
{
- char *sp, *uart;
- int rc, cnt;
+ char *uart;
+ int rc;
rc = stli_portcmdstats(NULL, portp);
@@ -1918,44 +1908,50 @@ static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portn
default:uart = "CD1400"; break;
}
}
-
- sp = pos;
- sp += sprintf(sp, "%d: uart:%s ", portnr, uart);
+ seq_printf(m, "%d: uart:%s ", portnr, uart);
if ((brdp->state & BST_STARTED) && (rc >= 0)) {
- sp += sprintf(sp, "tx:%d rx:%d", (int) stli_comstats.txtotal,
+ char sep;
+
+ seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal,
(int) stli_comstats.rxtotal);
if (stli_comstats.rxframing)
- sp += sprintf(sp, " fe:%d",
+ seq_printf(m, " fe:%d",
(int) stli_comstats.rxframing);
if (stli_comstats.rxparity)
- sp += sprintf(sp, " pe:%d",
+ seq_printf(m, " pe:%d",
(int) stli_comstats.rxparity);
if (stli_comstats.rxbreaks)
- sp += sprintf(sp, " brk:%d",
+ seq_printf(m, " brk:%d",
(int) stli_comstats.rxbreaks);
if (stli_comstats.rxoverrun)
- sp += sprintf(sp, " oe:%d",
+ seq_printf(m, " oe:%d",
(int) stli_comstats.rxoverrun);
- cnt = sprintf(sp, "%s%s%s%s%s ",
- (stli_comstats.signals & TIOCM_RTS) ? "|RTS" : "",
- (stli_comstats.signals & TIOCM_CTS) ? "|CTS" : "",
- (stli_comstats.signals & TIOCM_DTR) ? "|DTR" : "",
- (stli_comstats.signals & TIOCM_CD) ? "|DCD" : "",
- (stli_comstats.signals & TIOCM_DSR) ? "|DSR" : "");
- *sp = ' ';
- sp += cnt;
+ sep = ' ';
+ if (stli_comstats.signals & TIOCM_RTS) {
+ seq_printf(m, "%c%s", sep, "RTS");
+ sep = '|';
+ }
+ if (stli_comstats.signals & TIOCM_CTS) {
+ seq_printf(m, "%c%s", sep, "CTS");
+ sep = '|';
+ }
+ if (stli_comstats.signals & TIOCM_DTR) {
+ seq_printf(m, "%c%s", sep, "DTR");
+ sep = '|';
+ }
+ if (stli_comstats.signals & TIOCM_CD) {
+ seq_printf(m, "%c%s", sep, "DCD");
+ sep = '|';
+ }
+ if (stli_comstats.signals & TIOCM_DSR) {
+ seq_printf(m, "%c%s", sep, "DSR");
+ sep = '|';
+ }
}
-
- for (cnt = (sp - pos); (cnt < (MAXLINE - 1)); cnt++)
- *sp++ = ' ';
- if (cnt >= MAXLINE)
- pos[(MAXLINE - 2)] = '+';
- pos[(MAXLINE - 1)] = '\n';
-
- return(MAXLINE);
+ seq_putc(m, '\n');
}
/*****************************************************************************/
@@ -1964,26 +1960,15 @@ static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portn
* Port info, read from the /proc file system.
*/
-static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int stli_proc_show(struct seq_file *m, void *v)
{
struct stlibrd *brdp;
struct stliport *portp;
unsigned int brdnr, portnr, totalport;
- int curoff, maxoff;
- char *pos;
- pos = page;
totalport = 0;
- curoff = 0;
-
- if (off == 0) {
- pos += sprintf(pos, "%s: version %s", stli_drvtitle,
- stli_drvversion);
- while (pos < (page + MAXLINE - 1))
- *pos++ = ' ';
- *pos++ = '\n';
- }
- curoff = MAXLINE;
+
+ seq_printf(m, "%s: version %s\n", stli_drvtitle, stli_drvversion);
/*
* We scan through for each board, panel and port. The offset is
@@ -1996,33 +1981,31 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo
if (brdp->state == 0)
continue;
- maxoff = curoff + (brdp->nrports * MAXLINE);
- if (off >= maxoff) {
- curoff = maxoff;
- continue;
- }
-
totalport = brdnr * STL_MAXPORTS;
for (portnr = 0; (portnr < brdp->nrports); portnr++,
totalport++) {
portp = brdp->ports[portnr];
if (portp == NULL)
continue;
- if (off >= (curoff += MAXLINE))
- continue;
- if ((pos - page + MAXLINE) > count)
- goto stli_readdone;
- pos += stli_portinfo(brdp, portp, totalport, pos);
+ stli_portinfo(m, brdp, portp, totalport);
}
}
+ return 0;
+}
- *eof = 1;
-
-stli_readdone:
- *start = page;
- return(pos - page);
+static int stli_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, stli_proc_show, NULL);
}
+static const struct file_operations stli_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = stli_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*****************************************************************************/
/*
@@ -4427,9 +4410,9 @@ static const struct tty_operations stli_ops = {
.break_ctl = stli_breakctl,
.wait_until_sent = stli_waituntilsent,
.send_xchar = stli_sendxchar,
- .read_proc = stli_readproc,
.tiocmget = stli_tiocmget,
.tiocmset = stli_tiocmset,
+ .proc_fops = &stli_proc_fops,
};
static const struct tty_port_operations stli_port_ops = {
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 8b0da97d5293..4a4cab73d0be 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -1486,11 +1486,11 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
}
if (!handle) /* nothing else to do */
- return 0;
+ goto put;
intr = readw(ip); /* port irq status */
if (intr == 0)
- return 0;
+ goto put;
writew(0, ip); /* ACK port */
ofsAddr = p->tableAddr;
@@ -1499,16 +1499,17 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
ofsAddr + HostStat);
if (!inited)
- return 0;
+ goto put;
if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */
tty_insert_flip_char(tty, 0, TTY_BREAK);
tty_schedule_flip(tty);
}
- tty_kref_put(tty);
if (intr & IntrLine)
moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state);
+put:
+ tty_kref_put(tty);
return 0;
}
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 402c9f217f83..a420e8d437dd 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -820,7 +820,6 @@ static void mxser_check_modem_status(struct tty_struct *tty,
wake_up_interruptible(&port->port.open_wait);
}
- tty = tty_port_tty_get(&port->port);
if (port->port.flags & ASYNC_CTS_FLOW) {
if (tty->hw_stopped) {
if (status & UART_MSR_CTS) {
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index dc073e167abc..19d79fc54461 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -51,6 +51,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
@@ -2619,13 +2620,12 @@ cleanup:
* /proc fs routines....
*/
-static inline int line_info(char *buf, MGSLPC_INFO *info)
+static inline void line_info(struct seq_file *m, MGSLPC_INFO *info)
{
char stat_buf[30];
- int ret;
unsigned long flags;
- ret = sprintf(buf, "%s:io:%04X irq:%d",
+ seq_printf(m, "%s:io:%04X irq:%d",
info->device_name, info->io_base, info->irq_level);
/* output current serial signal states */
@@ -2649,75 +2649,70 @@ static inline int line_info(char *buf, MGSLPC_INFO *info)
strcat(stat_buf, "|RI");
if (info->params.mode == MGSL_MODE_HDLC) {
- ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d",
+ seq_printf(m, " HDLC txok:%d rxok:%d",
info->icount.txok, info->icount.rxok);
if (info->icount.txunder)
- ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+ seq_printf(m, " txunder:%d", info->icount.txunder);
if (info->icount.txabort)
- ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+ seq_printf(m, " txabort:%d", info->icount.txabort);
if (info->icount.rxshort)
- ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+ seq_printf(m, " rxshort:%d", info->icount.rxshort);
if (info->icount.rxlong)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+ seq_printf(m, " rxlong:%d", info->icount.rxlong);
if (info->icount.rxover)
- ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+ seq_printf(m, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+ seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
} else {
- ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d",
+ seq_printf(m, " ASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
if (info->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+ seq_printf(m, " fe:%d", info->icount.frame);
if (info->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+ seq_printf(m, " pe:%d", info->icount.parity);
if (info->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+ seq_printf(m, " brk:%d", info->icount.brk);
if (info->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+ seq_printf(m, " oe:%d", info->icount.overrun);
}
/* Append serial signal status to end */
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+ seq_printf(m, " %s\n", stat_buf+1);
- ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+ seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
info->tx_active,info->bh_requested,info->bh_running,
info->pending_bh);
-
- return ret;
}
/* Called to print information about devices
*/
-static int mgslpc_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int mgslpc_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
MGSLPC_INFO *info;
- len += sprintf(page, "synclink driver:%s\n", driver_version);
+ seq_printf(m, "synclink driver:%s\n", driver_version);
info = mgslpc_device_list;
while( info ) {
- l = line_info(page + len, info);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
+ line_info(m, info);
info = info->next_device;
}
+ return 0;
+}
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
+static int mgslpc_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mgslpc_proc_show, NULL);
}
+static const struct file_operations mgslpc_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = mgslpc_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static int rx_alloc_buffers(MGSLPC_INFO *info)
{
/* each buffer has header and data */
@@ -2861,13 +2856,13 @@ static const struct tty_operations mgslpc_ops = {
.send_xchar = mgslpc_send_xchar,
.break_ctl = mgslpc_break,
.wait_until_sent = mgslpc_wait_until_sent,
- .read_proc = mgslpc_read_proc,
.set_termios = mgslpc_set_termios,
.stop = tx_pause,
.start = tx_release,
.hangup = mgslpc_hangup,
.tiocmget = tiocmget,
.tiocmset = tiocmset,
+ .proc_fops = &mgslpc_proc_fops,
};
static void synclink_cs_cleanup(void)
@@ -4311,10 +4306,17 @@ static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size)
dev->stats.rx_bytes += size;
netif_rx(skb);
-
- dev->last_rx = jiffies;
}
+static const struct net_device_ops hdlcdev_ops = {
+ .ndo_open = hdlcdev_open,
+ .ndo_stop = hdlcdev_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = hdlcdev_ioctl,
+ .ndo_tx_timeout = hdlcdev_tx_timeout,
+};
+
/**
* called by device driver when adding device instance
* do generic HDLC initialization
@@ -4341,11 +4343,8 @@ static int hdlcdev_init(MGSLPC_INFO *info)
dev->irq = info->irq_level;
/* network layer callbacks and settings */
- dev->do_ioctl = hdlcdev_ioctl;
- dev->open = hdlcdev_open;
- dev->stop = hdlcdev_close;
- dev->tx_timeout = hdlcdev_tx_timeout;
- dev->watchdog_timeo = 10*HZ;
+ dev->netdev_ops = &hdlcdev_ops;
+ dev->watchdog_timeo = 10 * HZ;
dev->tx_queue_len = 50;
/* generic HDLC layer callbacks and settings */
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 7c13581ca9cd..f824ef8a9273 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -241,6 +241,10 @@
#include <linux/percpu.h>
#include <linux/cryptohash.h>
+#ifdef CONFIG_GENERIC_HARDIRQS
+# include <linux/irq.h>
+#endif
+
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
@@ -558,7 +562,7 @@ struct timer_rand_state {
unsigned dont_count_entropy:1;
};
-#ifndef CONFIG_SPARSE_IRQ
+#ifndef CONFIG_GENERIC_HARDIRQS
static struct timer_rand_state *irq_timer_state[NR_IRQS];
@@ -1484,7 +1488,8 @@ static void rekey_seq_generator(struct work_struct *work)
keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS;
smp_wmb();
ip_cnt++;
- schedule_delayed_work(&rekey_work, REKEY_INTERVAL);
+ schedule_delayed_work(&rekey_work,
+ round_jiffies_relative(REKEY_INTERVAL));
}
static inline struct keydata *get_keyptr(void)
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 96adf28a17e4..20d90e6a6e50 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -90,6 +90,7 @@ out1:
blkdev_put(bdev, filp->f_mode);
out:
mutex_unlock(&raw_mutex);
+ unlock_kernel();
return err;
}
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 2e8a6eed34be..ce81da5b2da9 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -333,7 +333,7 @@ void rio_copy_to_card(void *from, void __iomem *to, int len)
int rio_minor(struct tty_struct *tty)
{
- return tty->index + (tty->driver == rio_driver) ? 0 : 256;
+ return tty->index + ((tty->driver == rio_driver) ? 0 : 256);
}
static int rio_set_real_termios(void *ptr)
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 9af8d74875bc..217660451237 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -48,6 +48,7 @@
#include <linux/delay.h>
#include <linux/tty_flip.h>
#include <linux/spinlock.h>
+#include <linux/device.h>
#include <linux/uaccess.h>
@@ -1524,6 +1525,7 @@ module_param(iobase2, int, 0);
module_param(iobase3, int, 0);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(RISCOM8_NORMAL_MAJOR);
#endif /* MODULE */
/*
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index f4374437a033..fd3dced97776 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -888,12 +888,7 @@ found:
static int sonypi_misc_fasync(int fd, struct file *filp, int on)
{
- int retval;
-
- retval = fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
- if (retval < 0)
- return retval;
- return 0;
+ return fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
}
static int sonypi_misc_release(struct inode *inode, struct file *file)
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 3c67c3d83de9..e72be4190a44 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -2365,3 +2365,4 @@ module_init(specialix_init_module);
module_exit(specialix_exit_module);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(SPECIALIX_NORMAL_MAJOR);
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index e1e0dd89ac9a..2ad813a801dc 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -32,6 +32,7 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
+#include <linux/seq_file.h>
#include <linux/cd1400.h>
#include <linux/sc26198.h>
#include <linux/comstats.h>
@@ -1379,52 +1380,47 @@ static void stl_sendxchar(struct tty_struct *tty, char ch)
stl_putchar(tty, ch);
}
-/*****************************************************************************/
-
-#define MAXLINE 80
-
-/*
- * Format info for a specified port. The line is deliberately limited
- * to 80 characters. (If it is too long it will be truncated, if too
- * short then padded with spaces).
- */
-
-static int stl_portinfo(struct stlport *portp, int portnr, char *pos)
+static void stl_portinfo(struct seq_file *m, struct stlport *portp, int portnr)
{
- char *sp;
- int sigs, cnt;
+ int sigs;
+ char sep;
- sp = pos;
- sp += sprintf(sp, "%d: uart:%s tx:%d rx:%d",
+ seq_printf(m, "%d: uart:%s tx:%d rx:%d",
portnr, (portp->hwid == 1) ? "SC26198" : "CD1400",
(int) portp->stats.txtotal, (int) portp->stats.rxtotal);
if (portp->stats.rxframing)
- sp += sprintf(sp, " fe:%d", (int) portp->stats.rxframing);
+ seq_printf(m, " fe:%d", (int) portp->stats.rxframing);
if (portp->stats.rxparity)
- sp += sprintf(sp, " pe:%d", (int) portp->stats.rxparity);
+ seq_printf(m, " pe:%d", (int) portp->stats.rxparity);
if (portp->stats.rxbreaks)
- sp += sprintf(sp, " brk:%d", (int) portp->stats.rxbreaks);
+ seq_printf(m, " brk:%d", (int) portp->stats.rxbreaks);
if (portp->stats.rxoverrun)
- sp += sprintf(sp, " oe:%d", (int) portp->stats.rxoverrun);
+ seq_printf(m, " oe:%d", (int) portp->stats.rxoverrun);
sigs = stl_getsignals(portp);
- cnt = sprintf(sp, "%s%s%s%s%s ",
- (sigs & TIOCM_RTS) ? "|RTS" : "",
- (sigs & TIOCM_CTS) ? "|CTS" : "",
- (sigs & TIOCM_DTR) ? "|DTR" : "",
- (sigs & TIOCM_CD) ? "|DCD" : "",
- (sigs & TIOCM_DSR) ? "|DSR" : "");
- *sp = ' ';
- sp += cnt;
-
- for (cnt = sp - pos; cnt < (MAXLINE - 1); cnt++)
- *sp++ = ' ';
- if (cnt >= MAXLINE)
- pos[(MAXLINE - 2)] = '+';
- pos[(MAXLINE - 1)] = '\n';
-
- return MAXLINE;
+ sep = ' ';
+ if (sigs & TIOCM_RTS) {
+ seq_printf(m, "%c%s", sep, "RTS");
+ sep = '|';
+ }
+ if (sigs & TIOCM_CTS) {
+ seq_printf(m, "%c%s", sep, "CTS");
+ sep = '|';
+ }
+ if (sigs & TIOCM_DTR) {
+ seq_printf(m, "%c%s", sep, "DTR");
+ sep = '|';
+ }
+ if (sigs & TIOCM_CD) {
+ seq_printf(m, "%c%s", sep, "DCD");
+ sep = '|';
+ }
+ if (sigs & TIOCM_DSR) {
+ seq_printf(m, "%c%s", sep, "DSR");
+ sep = '|';
+ }
+ seq_putc(m, '\n');
}
/*****************************************************************************/
@@ -1433,30 +1429,17 @@ static int stl_portinfo(struct stlport *portp, int portnr, char *pos)
* Port info, read from the /proc file system.
*/
-static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int stl_proc_show(struct seq_file *m, void *v)
{
struct stlbrd *brdp;
struct stlpanel *panelp;
struct stlport *portp;
unsigned int brdnr, panelnr, portnr;
- int totalport, curoff, maxoff;
- char *pos;
+ int totalport;
- pr_debug("stl_readproc(page=%p,start=%p,off=%lx,count=%d,eof=%p,"
- "data=%p\n", page, start, off, count, eof, data);
-
- pos = page;
totalport = 0;
- curoff = 0;
-
- if (off == 0) {
- pos += sprintf(pos, "%s: version %s", stl_drvtitle,
- stl_drvversion);
- while (pos < (page + MAXLINE - 1))
- *pos++ = ' ';
- *pos++ = '\n';
- }
- curoff = MAXLINE;
+
+ seq_printf(m, "%s: version %s\n", stl_drvtitle, stl_drvversion);
/*
* We scan through for each board, panel and port. The offset is
@@ -1469,46 +1452,37 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof
if (brdp->state == 0)
continue;
- maxoff = curoff + (brdp->nrports * MAXLINE);
- if (off >= maxoff) {
- curoff = maxoff;
- continue;
- }
-
totalport = brdnr * STL_MAXPORTS;
for (panelnr = 0; panelnr < brdp->nrpanels; panelnr++) {
panelp = brdp->panels[panelnr];
if (panelp == NULL)
continue;
- maxoff = curoff + (panelp->nrports * MAXLINE);
- if (off >= maxoff) {
- curoff = maxoff;
- totalport += panelp->nrports;
- continue;
- }
-
for (portnr = 0; portnr < panelp->nrports; portnr++,
totalport++) {
portp = panelp->ports[portnr];
if (portp == NULL)
continue;
- if (off >= (curoff += MAXLINE))
- continue;
- if ((pos - page + MAXLINE) > count)
- goto stl_readdone;
- pos += stl_portinfo(portp, totalport, pos);
+ stl_portinfo(m, portp, totalport);
}
}
}
+ return 0;
+}
- *eof = 1;
-
-stl_readdone:
- *start = page;
- return pos - page;
+static int stl_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, stl_proc_show, NULL);
}
+static const struct file_operations stl_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = stl_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*****************************************************************************/
/*
@@ -2566,9 +2540,9 @@ static const struct tty_operations stl_ops = {
.break_ctl = stl_breakctl,
.wait_until_sent = stl_waituntilsent,
.send_xchar = stl_sendxchar,
- .read_proc = stl_readproc,
.tiocmget = stl_tiocmget,
.tiocmset = stl_tiocmset,
+ .proc_fops = &stl_proc_fops,
};
static const struct tty_port_operations stl_port_ops = {
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index b8063d4cad32..afd0b26ca056 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -79,6 +79,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
@@ -3459,18 +3460,17 @@ cleanup:
* /proc fs routines....
*/
-static inline int line_info(char *buf, struct mgsl_struct *info)
+static inline void line_info(struct seq_file *m, struct mgsl_struct *info)
{
char stat_buf[30];
- int ret;
unsigned long flags;
if (info->bus_type == MGSL_BUS_TYPE_PCI) {
- ret = sprintf(buf, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
+ seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
info->device_name, info->io_base, info->irq_level,
info->phys_memory_base, info->phys_lcr_base);
} else {
- ret = sprintf(buf, "%s:(E)ISA io:%04X irq:%d dma:%d",
+ seq_printf(m, "%s:(E)ISA io:%04X irq:%d dma:%d",
info->device_name, info->io_base,
info->irq_level, info->dma_level);
}
@@ -3497,37 +3497,37 @@ static inline int line_info(char *buf, struct mgsl_struct *info)
if (info->params.mode == MGSL_MODE_HDLC ||
info->params.mode == MGSL_MODE_RAW ) {
- ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d",
+ seq_printf(m, " HDLC txok:%d rxok:%d",
info->icount.txok, info->icount.rxok);
if (info->icount.txunder)
- ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+ seq_printf(m, " txunder:%d", info->icount.txunder);
if (info->icount.txabort)
- ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+ seq_printf(m, " txabort:%d", info->icount.txabort);
if (info->icount.rxshort)
- ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+ seq_printf(m, " rxshort:%d", info->icount.rxshort);
if (info->icount.rxlong)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+ seq_printf(m, " rxlong:%d", info->icount.rxlong);
if (info->icount.rxover)
- ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+ seq_printf(m, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+ seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
} else {
- ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d",
+ seq_printf(m, " ASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
if (info->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+ seq_printf(m, " fe:%d", info->icount.frame);
if (info->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+ seq_printf(m, " pe:%d", info->icount.parity);
if (info->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+ seq_printf(m, " brk:%d", info->icount.brk);
if (info->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+ seq_printf(m, " oe:%d", info->icount.overrun);
}
/* Append serial signal status to end */
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+ seq_printf(m, " %s\n", stat_buf+1);
- ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+ seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
info->tx_active,info->bh_requested,info->bh_running,
info->pending_bh);
@@ -3544,60 +3544,40 @@ static inline int line_info(char *buf, struct mgsl_struct *info)
u16 Tmr = usc_InReg( info, TMR );
u16 Tccr = usc_InReg( info, TCCR );
u16 Ccar = inw( info->io_base + CCAR );
- ret += sprintf(buf+ret, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n"
+ seq_printf(m, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n"
"ricr=%04X icr =%04X dccr=%04X tmr=%04X tccr=%04X ccar=%04X\n",
Tcsr,Tdmr,Ticr,Rscr,Rdmr,Ricr,Icr,Dccr,Tmr,Tccr,Ccar );
}
spin_unlock_irqrestore(&info->irq_spinlock,flags);
-
- return ret;
-
-} /* end of line_info() */
+}
-/* mgsl_read_proc()
- *
- * Called to print information about devices
- *
- * Arguments:
- * page page of memory to hold returned info
- * start
- * off
- * count
- * eof
- * data
- *
- * Return Value:
- */
-static int mgsl_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+/* Called to print information about devices */
+static int mgsl_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
struct mgsl_struct *info;
- len += sprintf(page, "synclink driver:%s\n", driver_version);
+ seq_printf(m, "synclink driver:%s\n", driver_version);
info = mgsl_device_list;
while( info ) {
- l = line_info(page + len, info);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
+ line_info(m, info);
info = info->next_device;
}
+ return 0;
+}
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
-
-} /* end of mgsl_read_proc() */
+static int mgsl_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mgsl_proc_show, NULL);
+}
+
+static const struct file_operations mgsl_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = mgsl_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
/* mgsl_allocate_dma_buffers()
*
@@ -4335,13 +4315,13 @@ static const struct tty_operations mgsl_ops = {
.send_xchar = mgsl_send_xchar,
.break_ctl = mgsl_break,
.wait_until_sent = mgsl_wait_until_sent,
- .read_proc = mgsl_read_proc,
.set_termios = mgsl_set_termios,
.stop = mgsl_stop,
.start = mgsl_start,
.hangup = mgsl_hangup,
.tiocmget = tiocmget,
.tiocmset = tiocmset,
+ .proc_fops = &mgsl_proc_fops,
};
/*
@@ -8007,10 +7987,17 @@ static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size)
dev->stats.rx_bytes += size;
netif_rx(skb);
-
- dev->last_rx = jiffies;
}
+static const struct net_device_ops hdlcdev_ops = {
+ .ndo_open = hdlcdev_open,
+ .ndo_stop = hdlcdev_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = hdlcdev_ioctl,
+ .ndo_tx_timeout = hdlcdev_tx_timeout,
+};
+
/**
* called by device driver when adding device instance
* do generic HDLC initialization
@@ -8038,11 +8025,8 @@ static int hdlcdev_init(struct mgsl_struct *info)
dev->dma = info->dma_level;
/* network layer callbacks and settings */
- dev->do_ioctl = hdlcdev_ioctl;
- dev->open = hdlcdev_open;
- dev->stop = hdlcdev_close;
- dev->tx_timeout = hdlcdev_tx_timeout;
- dev->watchdog_timeo = 10*HZ;
+ dev->netdev_ops = &hdlcdev_ops;
+ dev->watchdog_timeo = 10 * HZ;
dev->tx_queue_len = 50;
/* generic HDLC layer callbacks and settings */
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index f329f459817c..5e256494686a 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -60,6 +60,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
@@ -154,7 +155,6 @@ static void tx_hold(struct tty_struct *tty);
static void tx_release(struct tty_struct *tty);
static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static int read_proc(char *page, char **start, off_t off, int count,int *eof, void *data);
static int chars_in_buffer(struct tty_struct *tty);
static void throttle(struct tty_struct * tty);
static void unthrottle(struct tty_struct * tty);
@@ -298,6 +298,7 @@ struct slgt_info {
unsigned int rbuf_fill_level;
unsigned int if_mode;
+ unsigned int base_clock;
/* device status */
@@ -1156,22 +1157,26 @@ static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *ne
return -EFAULT;
spin_lock(&info->lock);
- info->params.mode = tmp_params.mode;
- info->params.loopback = tmp_params.loopback;
- info->params.flags = tmp_params.flags;
- info->params.encoding = tmp_params.encoding;
- info->params.clock_speed = tmp_params.clock_speed;
- info->params.addr_filter = tmp_params.addr_filter;
- info->params.crc_type = tmp_params.crc_type;
- info->params.preamble_length = tmp_params.preamble_length;
- info->params.preamble = tmp_params.preamble;
- info->params.data_rate = tmp_params.data_rate;
- info->params.data_bits = tmp_params.data_bits;
- info->params.stop_bits = tmp_params.stop_bits;
- info->params.parity = tmp_params.parity;
+ if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) {
+ info->base_clock = tmp_params.clock_speed;
+ } else {
+ info->params.mode = tmp_params.mode;
+ info->params.loopback = tmp_params.loopback;
+ info->params.flags = tmp_params.flags;
+ info->params.encoding = tmp_params.encoding;
+ info->params.clock_speed = tmp_params.clock_speed;
+ info->params.addr_filter = tmp_params.addr_filter;
+ info->params.crc_type = tmp_params.crc_type;
+ info->params.preamble_length = tmp_params.preamble_length;
+ info->params.preamble = tmp_params.preamble;
+ info->params.data_rate = tmp_params.data_rate;
+ info->params.data_bits = tmp_params.data_bits;
+ info->params.stop_bits = tmp_params.stop_bits;
+ info->params.parity = tmp_params.parity;
+ }
spin_unlock(&info->lock);
- change_params(info);
+ program_hw(info);
return 0;
}
@@ -1229,13 +1234,12 @@ static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file,
/*
* proc fs support
*/
-static inline int line_info(char *buf, struct slgt_info *info)
+static inline void line_info(struct seq_file *m, struct slgt_info *info)
{
char stat_buf[30];
- int ret;
unsigned long flags;
- ret = sprintf(buf, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n",
+ seq_printf(m, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n",
info->device_name, info->phys_reg_addr,
info->irq_level, info->max_frame_size);
@@ -1260,75 +1264,70 @@ static inline int line_info(char *buf, struct slgt_info *info)
strcat(stat_buf, "|RI");
if (info->params.mode != MGSL_MODE_ASYNC) {
- ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d",
+ seq_printf(m, "\tHDLC txok:%d rxok:%d",
info->icount.txok, info->icount.rxok);
if (info->icount.txunder)
- ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+ seq_printf(m, " txunder:%d", info->icount.txunder);
if (info->icount.txabort)
- ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+ seq_printf(m, " txabort:%d", info->icount.txabort);
if (info->icount.rxshort)
- ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+ seq_printf(m, " rxshort:%d", info->icount.rxshort);
if (info->icount.rxlong)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+ seq_printf(m, " rxlong:%d", info->icount.rxlong);
if (info->icount.rxover)
- ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+ seq_printf(m, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+ seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
} else {
- ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d",
+ seq_printf(m, "\tASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
if (info->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+ seq_printf(m, " fe:%d", info->icount.frame);
if (info->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+ seq_printf(m, " pe:%d", info->icount.parity);
if (info->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+ seq_printf(m, " brk:%d", info->icount.brk);
if (info->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+ seq_printf(m, " oe:%d", info->icount.overrun);
}
/* Append serial signal status to end */
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+ seq_printf(m, " %s\n", stat_buf+1);
- ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+ seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
info->tx_active,info->bh_requested,info->bh_running,
info->pending_bh);
-
- return ret;
}
/* Called to print information about devices
*/
-static int read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int synclink_gt_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
struct slgt_info *info;
- len += sprintf(page, "synclink_gt driver\n");
+ seq_puts(m, "synclink_gt driver\n");
info = slgt_device_list;
while( info ) {
- l = line_info(page + len, info);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
+ line_info(m, info);
info = info->next_device;
}
+ return 0;
+}
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
+static int synclink_gt_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, synclink_gt_proc_show, NULL);
}
+static const struct file_operations synclink_gt_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = synclink_gt_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*
* return count of bytes in transmit buffer
*/
@@ -1763,10 +1762,17 @@ static void hdlcdev_rx(struct slgt_info *info, char *buf, int size)
dev->stats.rx_bytes += size;
netif_rx(skb);
-
- dev->last_rx = jiffies;
}
+static const struct net_device_ops hdlcdev_ops = {
+ .ndo_open = hdlcdev_open,
+ .ndo_stop = hdlcdev_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = hdlcdev_ioctl,
+ .ndo_tx_timeout = hdlcdev_tx_timeout,
+};
+
/**
* called by device driver when adding device instance
* do generic HDLC initialization
@@ -1794,11 +1800,8 @@ static int hdlcdev_init(struct slgt_info *info)
dev->irq = info->irq_level;
/* network layer callbacks and settings */
- dev->do_ioctl = hdlcdev_ioctl;
- dev->open = hdlcdev_open;
- dev->stop = hdlcdev_close;
- dev->tx_timeout = hdlcdev_tx_timeout;
- dev->watchdog_timeo = 10*HZ;
+ dev->netdev_ops = &hdlcdev_ops;
+ dev->watchdog_timeo = 10 * HZ;
dev->tx_queue_len = 50;
/* generic HDLC layer callbacks and settings */
@@ -2561,10 +2564,13 @@ static int set_params(struct slgt_info *info, MGSL_PARAMS __user *new_params)
return -EFAULT;
spin_lock_irqsave(&info->lock, flags);
- memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS));
+ if (tmp_params.mode == MGSL_MODE_BASE_CLOCK)
+ info->base_clock = tmp_params.clock_speed;
+ else
+ memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS));
spin_unlock_irqrestore(&info->lock, flags);
- change_params(info);
+ program_hw(info);
return 0;
}
@@ -3434,6 +3440,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
info->magic = MGSL_MAGIC;
INIT_WORK(&info->task, bh_handler);
info->max_frame_size = 4096;
+ info->base_clock = 14745600;
info->rbuf_fill_level = DMABUFSIZE;
info->port.close_delay = 5*HZ/10;
info->port.closing_wait = 30*HZ;
@@ -3558,13 +3565,13 @@ static const struct tty_operations ops = {
.send_xchar = send_xchar,
.break_ctl = set_break,
.wait_until_sent = wait_until_sent,
- .read_proc = read_proc,
.set_termios = set_termios,
.stop = tx_hold,
.start = tx_release,
.hangup = hangup,
.tiocmget = tiocmget,
.tiocmset = tiocmset,
+ .proc_fops = &synclink_gt_proc_fops,
};
static void slgt_cleanup(void)
@@ -3781,7 +3788,7 @@ static void enable_loopback(struct slgt_info *info)
static void set_rate(struct slgt_info *info, u32 rate)
{
unsigned int div;
- static unsigned int osc = 14745600;
+ unsigned int osc = info->base_clock;
/* div = osc/rate - 1
*
@@ -4085,18 +4092,27 @@ static void async_mode(struct slgt_info *info)
* 06 CTS IRQ enable
* 05 DCD IRQ enable
* 04 RI IRQ enable
- * 03 reserved, must be zero
+ * 03 0=16x sampling, 1=8x sampling
* 02 1=txd->rxd internal loopback enable
* 01 reserved, must be zero
* 00 1=master IRQ enable
*/
val = BIT15 + BIT14 + BIT0;
+ /* JCR[8] : 1 = x8 async mode feature available */
+ if ((rd_reg32(info, JCR) & BIT8) && info->params.data_rate &&
+ ((info->base_clock < (info->params.data_rate * 16)) ||
+ (info->base_clock % (info->params.data_rate * 16)))) {
+ /* use 8x sampling */
+ val |= BIT3;
+ set_rate(info, info->params.data_rate * 8);
+ } else {
+ /* use 16x sampling */
+ set_rate(info, info->params.data_rate * 16);
+ }
wr_reg16(info, SCR, val);
slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER);
- set_rate(info, info->params.data_rate * 16);
-
if (info->params.loopback)
enable_loopback(info);
}
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 7b0c5b2dd263..26de60efe4b2 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -50,6 +50,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
@@ -520,7 +521,6 @@ static void tx_hold(struct tty_struct *tty);
static void tx_release(struct tty_struct *tty);
static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static int read_proc(char *page, char **start, off_t off, int count,int *eof, void *data);
static int chars_in_buffer(struct tty_struct *tty);
static void throttle(struct tty_struct * tty);
static void unthrottle(struct tty_struct * tty);
@@ -1354,13 +1354,12 @@ static int ioctl(struct tty_struct *tty, struct file *file,
* /proc fs routines....
*/
-static inline int line_info(char *buf, SLMP_INFO *info)
+static inline void line_info(struct seq_file *m, SLMP_INFO *info)
{
char stat_buf[30];
- int ret;
unsigned long flags;
- ret = sprintf(buf, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n"
+ seq_printf(m, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n"
"\tIRQ=%d MaxFrameSize=%u\n",
info->device_name,
info->phys_sca_base,
@@ -1391,75 +1390,70 @@ static inline int line_info(char *buf, SLMP_INFO *info)
strcat(stat_buf, "|RI");
if (info->params.mode == MGSL_MODE_HDLC) {
- ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d",
+ seq_printf(m, "\tHDLC txok:%d rxok:%d",
info->icount.txok, info->icount.rxok);
if (info->icount.txunder)
- ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+ seq_printf(m, " txunder:%d", info->icount.txunder);
if (info->icount.txabort)
- ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+ seq_printf(m, " txabort:%d", info->icount.txabort);
if (info->icount.rxshort)
- ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+ seq_printf(m, " rxshort:%d", info->icount.rxshort);
if (info->icount.rxlong)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+ seq_printf(m, " rxlong:%d", info->icount.rxlong);
if (info->icount.rxover)
- ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+ seq_printf(m, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxcrc);
+ seq_printf(m, " rxlong:%d", info->icount.rxcrc);
} else {
- ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d",
+ seq_printf(m, "\tASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
if (info->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+ seq_printf(m, " fe:%d", info->icount.frame);
if (info->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+ seq_printf(m, " pe:%d", info->icount.parity);
if (info->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+ seq_printf(m, " brk:%d", info->icount.brk);
if (info->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+ seq_printf(m, " oe:%d", info->icount.overrun);
}
/* Append serial signal status to end */
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+ seq_printf(m, " %s\n", stat_buf+1);
- ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+ seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
info->tx_active,info->bh_requested,info->bh_running,
info->pending_bh);
-
- return ret;
}
/* Called to print information about devices
*/
-static int read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int synclinkmp_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
SLMP_INFO *info;
- len += sprintf(page, "synclinkmp driver:%s\n", driver_version);
+ seq_printf(m, "synclinkmp driver:%s\n", driver_version);
info = synclinkmp_device_list;
while( info ) {
- l = line_info(page + len, info);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
+ line_info(m, info);
info = info->next_device;
}
+ return 0;
+}
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
+static int synclinkmp_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, synclinkmp_proc_show, NULL);
}
+static const struct file_operations synclinkmp_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = synclinkmp_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/* Return the count of bytes in transmit buffer
*/
static int chars_in_buffer(struct tty_struct *tty)
@@ -1907,10 +1901,17 @@ static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size)
dev->stats.rx_bytes += size;
netif_rx(skb);
-
- dev->last_rx = jiffies;
}
+static const struct net_device_ops hdlcdev_ops = {
+ .ndo_open = hdlcdev_open,
+ .ndo_stop = hdlcdev_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = hdlcdev_ioctl,
+ .ndo_tx_timeout = hdlcdev_tx_timeout,
+};
+
/**
* called by device driver when adding device instance
* do generic HDLC initialization
@@ -1938,11 +1939,8 @@ static int hdlcdev_init(SLMP_INFO *info)
dev->irq = info->irq_level;
/* network layer callbacks and settings */
- dev->do_ioctl = hdlcdev_ioctl;
- dev->open = hdlcdev_open;
- dev->stop = hdlcdev_close;
- dev->tx_timeout = hdlcdev_tx_timeout;
- dev->watchdog_timeo = 10*HZ;
+ dev->netdev_ops = &hdlcdev_ops;
+ dev->watchdog_timeo = 10 * HZ;
dev->tx_queue_len = 50;
/* generic HDLC layer callbacks and settings */
@@ -3901,13 +3899,13 @@ static const struct tty_operations ops = {
.send_xchar = send_xchar,
.break_ctl = set_break,
.wait_until_sent = wait_until_sent,
- .read_proc = read_proc,
.set_termios = set_termios,
.stop = tx_hold,
.start = tx_release,
.hangup = hangup,
.tiocmget = tiocmget,
.tiocmset = tiocmset,
+ .proc_fops = &synclinkmp_proc_fops,
};
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 30659ce9bcf4..6de020d078e1 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -35,7 +35,7 @@
#include <linux/vt_kern.h>
#include <linux/workqueue.h>
#include <linux/kexec.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
#include <linux/hrtimer.h>
#include <linux/oom.h>
@@ -346,6 +346,19 @@ static struct sysrq_key_op sysrq_moom_op = {
.enable_mask = SYSRQ_ENABLE_SIGNAL,
};
+#ifdef CONFIG_BLOCK
+static void sysrq_handle_thaw(int key, struct tty_struct *tty)
+{
+ emergency_thaw_all();
+}
+static struct sysrq_key_op sysrq_thaw_op = {
+ .handler = sysrq_handle_thaw,
+ .help_msg = "thaw-filesystems(J)",
+ .action_msg = "Emergency Thaw of all frozen filesystems",
+ .enable_mask = SYSRQ_ENABLE_SIGNAL,
+};
+#endif
+
static void sysrq_handle_kill(int key, struct tty_struct *tty)
{
send_sig_all(SIGKILL);
@@ -396,9 +409,13 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
&sysrq_moom_op, /* f */
/* g: May be registered by ppc for kgdb */
NULL, /* g */
- NULL, /* h */
+ NULL, /* h - reserved for help */
&sysrq_kill_op, /* i */
+#ifdef CONFIG_BLOCK
+ &sysrq_thaw_op, /* j */
+#else
NULL, /* j */
+#endif
&sysrq_SAK_op, /* k */
#ifdef CONFIG_SMP
&sysrq_showallcpus_op, /* l */
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 9c47dc48c9fd..ccdd828adcef 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -429,134 +429,148 @@ out:
#define TPM_DIGEST_SIZE 20
#define TPM_ERROR_SIZE 10
#define TPM_RET_CODE_IDX 6
-#define TPM_GET_CAP_RET_SIZE_IDX 10
-#define TPM_GET_CAP_RET_UINT32_1_IDX 14
-#define TPM_GET_CAP_RET_UINT32_2_IDX 18
-#define TPM_GET_CAP_RET_UINT32_3_IDX 22
-#define TPM_GET_CAP_RET_UINT32_4_IDX 26
-#define TPM_GET_CAP_PERM_DISABLE_IDX 16
-#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
-#define TPM_GET_CAP_RET_BOOL_1_IDX 14
-#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
-
-#define TPM_CAP_IDX 13
-#define TPM_CAP_SUBCAP_IDX 21
enum tpm_capabilities {
- TPM_CAP_FLAG = 4,
- TPM_CAP_PROP = 5,
+ TPM_CAP_FLAG = cpu_to_be32(4),
+ TPM_CAP_PROP = cpu_to_be32(5),
+ CAP_VERSION_1_1 = cpu_to_be32(0x06),
+ CAP_VERSION_1_2 = cpu_to_be32(0x1A)
};
enum tpm_sub_capabilities {
- TPM_CAP_PROP_PCR = 0x1,
- TPM_CAP_PROP_MANUFACTURER = 0x3,
- TPM_CAP_FLAG_PERM = 0x8,
- TPM_CAP_FLAG_VOL = 0x9,
- TPM_CAP_PROP_OWNER = 0x11,
- TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
- TPM_CAP_PROP_TIS_DURATION = 0x20,
-};
+ TPM_CAP_PROP_PCR = cpu_to_be32(0x101),
+ TPM_CAP_PROP_MANUFACTURER = cpu_to_be32(0x103),
+ TPM_CAP_FLAG_PERM = cpu_to_be32(0x108),
+ TPM_CAP_FLAG_VOL = cpu_to_be32(0x109),
+ TPM_CAP_PROP_OWNER = cpu_to_be32(0x111),
+ TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
+ TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
-/*
- * This is a semi generic GetCapability command for use
- * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
- * and their associated sub_capabilities.
- */
-
-static const u8 tpm_cap[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 22, /* length */
- 0, 0, 0, 101, /* TPM_ORD_GetCapability */
- 0, 0, 0, 0, /* TPM_CAP_<TYPE> */
- 0, 0, 0, 4, /* TPM_CAP_SUB_<TYPE> size */
- 0, 0, 1, 0 /* TPM_CAP_SUB_<TYPE> */
};
-static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
- char *desc)
+static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
+ int len, const char *desc)
{
int err;
- len = tpm_transmit(chip, data, len);
+ len = tpm_transmit(chip,(u8 *) cmd, len);
if (len < 0)
return len;
if (len == TPM_ERROR_SIZE) {
- err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
+ err = be32_to_cpu(cmd->header.out.return_code);
dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
return err;
}
return 0;
}
+#define TPM_INTERNAL_RESULT_SIZE 200
+#define TPM_TAG_RQU_COMMAND cpu_to_be16(193)
+#define TPM_ORD_GET_CAP cpu_to_be32(101)
+
+static const struct tpm_input_header tpm_getcap_header = {
+ .tag = TPM_TAG_RQU_COMMAND,
+ .length = cpu_to_be32(22),
+ .ordinal = TPM_ORD_GET_CAP
+};
+
+ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap,
+ const char *desc)
+{
+ struct tpm_cmd_t tpm_cmd;
+ int rc;
+ struct tpm_chip *chip = dev_get_drvdata(dev);
+
+ tpm_cmd.header.in = tpm_getcap_header;
+ if (subcap_id == CAP_VERSION_1_1 || subcap_id == CAP_VERSION_1_2) {
+ tpm_cmd.params.getcap_in.cap = subcap_id;
+ /*subcap field not necessary */
+ tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(0);
+ tpm_cmd.header.in.length -= cpu_to_be32(sizeof(__be32));
+ } else {
+ if (subcap_id == TPM_CAP_FLAG_PERM ||
+ subcap_id == TPM_CAP_FLAG_VOL)
+ tpm_cmd.params.getcap_in.cap = TPM_CAP_FLAG;
+ else
+ tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+ tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ tpm_cmd.params.getcap_in.subcap = subcap_id;
+ }
+ rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc);
+ if (!rc)
+ *cap = tpm_cmd.params.getcap_out.cap;
+ return rc;
+}
+
void tpm_gen_interrupt(struct tpm_chip *chip)
{
- u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
+ struct tpm_cmd_t tpm_cmd;
ssize_t rc;
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+ tpm_cmd.header.in = tpm_getcap_header;
+ tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+ tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
- rc = transmit_cmd(chip, data, sizeof(data),
+ rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
"attempting to determine the timeouts");
}
EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
void tpm_get_timeouts(struct tpm_chip *chip)
{
- u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
+ struct tpm_cmd_t tpm_cmd;
+ struct timeout_t *timeout_cap;
+ struct duration_t *duration_cap;
ssize_t rc;
u32 timeout;
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+ tpm_cmd.header.in = tpm_getcap_header;
+ tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+ tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
- rc = transmit_cmd(chip, data, sizeof(data),
+ rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
"attempting to determine the timeouts");
if (rc)
goto duration;
- if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
+ if (be32_to_cpu(tpm_cmd.header.out.length)
!= 4 * sizeof(u32))
goto duration;
+ timeout_cap = &tpm_cmd.params.getcap_out.cap.timeout;
/* Don't overwrite default if value is 0 */
- timeout =
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
+ timeout = be32_to_cpu(timeout_cap->a);
if (timeout)
chip->vendor.timeout_a = usecs_to_jiffies(timeout);
- timeout =
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
+ timeout = be32_to_cpu(timeout_cap->b);
if (timeout)
chip->vendor.timeout_b = usecs_to_jiffies(timeout);
- timeout =
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
+ timeout = be32_to_cpu(timeout_cap->c);
if (timeout)
chip->vendor.timeout_c = usecs_to_jiffies(timeout);
- timeout =
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
+ timeout = be32_to_cpu(timeout_cap->d);
if (timeout)
chip->vendor.timeout_d = usecs_to_jiffies(timeout);
duration:
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
+ tpm_cmd.header.in = tpm_getcap_header;
+ tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+ tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION;
- rc = transmit_cmd(chip, data, sizeof(data),
+ rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
"attempting to determine the durations");
if (rc)
return;
- if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
+ if (be32_to_cpu(tpm_cmd.header.out.return_code)
!= 3 * sizeof(u32))
return;
-
+ duration_cap = &tpm_cmd.params.getcap_out.cap.duration;
chip->vendor.duration[TPM_SHORT] =
- usecs_to_jiffies(be32_to_cpu
- (*((__be32 *) (data +
- TPM_GET_CAP_RET_UINT32_1_IDX))));
+ usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short));
/* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
* value wrong and apparently reports msecs rather than usecs. So we
* fix up the resulting too-small TPM_SHORT value to make things work.
@@ -565,13 +579,9 @@ duration:
chip->vendor.duration[TPM_SHORT] = HZ;
chip->vendor.duration[TPM_MEDIUM] =
- usecs_to_jiffies(be32_to_cpu
- (*((__be32 *) (data +
- TPM_GET_CAP_RET_UINT32_2_IDX))));
+ usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_medium));
chip->vendor.duration[TPM_LONG] =
- usecs_to_jiffies(be32_to_cpu
- (*((__be32 *) (data +
- TPM_GET_CAP_RET_UINT32_3_IDX))));
+ usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_long));
}
EXPORT_SYMBOL_GPL(tpm_get_timeouts);
@@ -587,36 +597,18 @@ void tpm_continue_selftest(struct tpm_chip *chip)
}
EXPORT_SYMBOL_GPL(tpm_continue_selftest);
-#define TPM_INTERNAL_RESULT_SIZE 200
-
ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
char *buf)
{
- u8 *data;
+ cap_t cap;
ssize_t rc;
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_FLAG;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
-
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
- "attemtping to determine the permanent enabled state");
- if (rc) {
- kfree(data);
+ rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
+ "attempting to determine the permanent enabled state");
+ if (rc)
return 0;
- }
-
- rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
- kfree(data);
+ rc = sprintf(buf, "%d\n", !cap.perm_flags.disable);
return rc;
}
EXPORT_SYMBOL_GPL(tpm_show_enabled);
@@ -624,31 +616,15 @@ EXPORT_SYMBOL_GPL(tpm_show_enabled);
ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
char *buf)
{
- u8 *data;
+ cap_t cap;
ssize_t rc;
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_FLAG;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
-
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
- "attemtping to determine the permanent active state");
- if (rc) {
- kfree(data);
+ rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
+ "attempting to determine the permanent active state");
+ if (rc)
return 0;
- }
- rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
-
- kfree(data);
+ rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated);
return rc;
}
EXPORT_SYMBOL_GPL(tpm_show_active);
@@ -656,31 +632,15 @@ EXPORT_SYMBOL_GPL(tpm_show_active);
ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
char *buf)
{
- u8 *data;
+ cap_t cap;
ssize_t rc;
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
-
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
- "attempting to determine the owner state");
- if (rc) {
- kfree(data);
+ rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap,
+ "attempting to determine the owner state");
+ if (rc)
return 0;
- }
-
- rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
- kfree(data);
+ rc = sprintf(buf, "%d\n", cap.owned);
return rc;
}
EXPORT_SYMBOL_GPL(tpm_show_owned);
@@ -688,116 +648,180 @@ EXPORT_SYMBOL_GPL(tpm_show_owned);
ssize_t tpm_show_temp_deactivated(struct device * dev,
struct device_attribute * attr, char *buf)
{
- u8 *data;
+ cap_t cap;
ssize_t rc;
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
+ rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap,
+ "attempting to determine the temporary state");
+ if (rc)
+ return 0;
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
+ rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_FLAG;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
+/*
+ * tpm_chip_find_get - return tpm_chip for given chip number
+ */
+static struct tpm_chip *tpm_chip_find_get(int chip_num)
+{
+ struct tpm_chip *pos, *chip = NULL;
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
- "attempting to determine the temporary state");
- if (rc) {
- kfree(data);
- return 0;
+ rcu_read_lock();
+ list_for_each_entry_rcu(pos, &tpm_chip_list, list) {
+ if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num)
+ continue;
+
+ if (try_module_get(pos->dev->driver->owner)) {
+ chip = pos;
+ break;
+ }
}
+ rcu_read_unlock();
+ return chip;
+}
- rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
+#define TPM_ORDINAL_PCRREAD cpu_to_be32(21)
+#define READ_PCR_RESULT_SIZE 30
+static struct tpm_input_header pcrread_header = {
+ .tag = TPM_TAG_RQU_COMMAND,
+ .length = cpu_to_be32(14),
+ .ordinal = TPM_ORDINAL_PCRREAD
+};
- kfree(data);
+int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+{
+ int rc;
+ struct tpm_cmd_t cmd;
+
+ cmd.header.in = pcrread_header;
+ cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
+ BUILD_BUG_ON(cmd.header.in.length > READ_PCR_RESULT_SIZE);
+ rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
+ "attempting to read a pcr value");
+
+ if (rc == 0)
+ memcpy(res_buf, cmd.params.pcrread_out.pcr_result,
+ TPM_DIGEST_SIZE);
return rc;
}
-EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
-static const u8 pcrread[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 14, /* length */
- 0, 0, 0, 21, /* TPM_ORD_PcrRead */
- 0, 0, 0, 0 /* PCR index */
+/**
+ * tpm_pcr_read - read a pcr value
+ * @chip_num: tpm idx # or ANY
+ * @pcr_idx: pcr idx to retrieve
+ * @res_buf: TPM_PCR value
+ * size of res_buf is 20 bytes (or NULL if you don't care)
+ *
+ * The TPM driver should be built-in, but for whatever reason it
+ * isn't, protect against the chip disappearing, by incrementing
+ * the module usage count.
+ */
+int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf)
+{
+ struct tpm_chip *chip;
+ int rc;
+
+ chip = tpm_chip_find_get(chip_num);
+ if (chip == NULL)
+ return -ENODEV;
+ rc = __tpm_pcr_read(chip, pcr_idx, res_buf);
+ module_put(chip->dev->driver->owner);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_pcr_read);
+
+/**
+ * tpm_pcr_extend - extend pcr value with hash
+ * @chip_num: tpm idx # or AN&
+ * @pcr_idx: pcr idx to extend
+ * @hash: hash value used to extend pcr value
+ *
+ * The TPM driver should be built-in, but for whatever reason it
+ * isn't, protect against the chip disappearing, by incrementing
+ * the module usage count.
+ */
+#define TPM_ORD_PCR_EXTEND cpu_to_be32(20)
+#define EXTEND_PCR_SIZE 34
+static struct tpm_input_header pcrextend_header = {
+ .tag = TPM_TAG_RQU_COMMAND,
+ .length = cpu_to_be32(34),
+ .ordinal = TPM_ORD_PCR_EXTEND
};
+int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
+{
+ struct tpm_cmd_t cmd;
+ int rc;
+ struct tpm_chip *chip;
+
+ chip = tpm_chip_find_get(chip_num);
+ if (chip == NULL)
+ return -ENODEV;
+
+ cmd.header.in = pcrextend_header;
+ BUILD_BUG_ON(be32_to_cpu(cmd.header.in.length) > EXTEND_PCR_SIZE);
+ cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
+ memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
+ rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
+ "attempting extend a PCR value");
+
+ module_put(chip->dev->driver->owner);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_pcr_extend);
+
ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
char *buf)
{
- u8 *data;
+ cap_t cap;
+ u8 digest[TPM_DIGEST_SIZE];
ssize_t rc;
int i, j, num_pcrs;
- __be32 index;
char *str = buf;
-
struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
-
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
+ rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap,
"attempting to determine the number of PCRS");
- if (rc) {
- kfree(data);
+ if (rc)
return 0;
- }
- num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
+ num_pcrs = be32_to_cpu(cap.num_pcrs);
for (i = 0; i < num_pcrs; i++) {
- memcpy(data, pcrread, sizeof(pcrread));
- index = cpu_to_be32(i);
- memcpy(data + 10, &index, 4);
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
- "attempting to read a PCR");
+ rc = __tpm_pcr_read(chip, i, digest);
if (rc)
- goto out;
+ break;
str += sprintf(str, "PCR-%02d: ", i);
for (j = 0; j < TPM_DIGEST_SIZE; j++)
- str += sprintf(str, "%02X ", *(data + 10 + j));
+ str += sprintf(str, "%02X ", digest[j]);
str += sprintf(str, "\n");
}
-out:
- kfree(data);
return str - buf;
}
EXPORT_SYMBOL_GPL(tpm_show_pcrs);
#define READ_PUBEK_RESULT_SIZE 314
-static const u8 readpubek[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 30, /* length */
- 0, 0, 0, 124, /* TPM_ORD_ReadPubek */
+#define TPM_ORD_READPUBEK cpu_to_be32(124)
+struct tpm_input_header tpm_readpubek_header = {
+ .tag = TPM_TAG_RQU_COMMAND,
+ .length = cpu_to_be32(30),
+ .ordinal = TPM_ORD_READPUBEK
};
ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
char *buf)
{
u8 *data;
+ struct tpm_cmd_t tpm_cmd;
ssize_t err;
int i, rc;
char *str = buf;
struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
- data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, readpubek, sizeof(readpubek));
-
- err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
+ tpm_cmd.header.in = tpm_readpubek_header;
+ err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
"attempting to read the PUBEK");
if (err)
goto out;
@@ -812,7 +836,7 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
256 byte modulus
ignore checksum 20 bytes
*/
-
+ data = tpm_cmd.params.readpubek_out_buffer;
str +=
sprintf(str,
"Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
@@ -832,65 +856,33 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
}
out:
rc = str - buf;
- kfree(data);
return rc;
}
EXPORT_SYMBOL_GPL(tpm_show_pubek);
-#define CAP_VERSION_1_1 6
-#define CAP_VERSION_1_2 0x1A
-#define CAP_VERSION_IDX 13
-static const u8 cap_version[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 18, /* length */
- 0, 0, 0, 101, /* TPM_ORD_GetCapability */
- 0, 0, 0, 0,
- 0, 0, 0, 0
-};
ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
char *buf)
{
- u8 *data;
+ cap_t cap;
ssize_t rc;
char *str = buf;
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
-
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
+ rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap,
"attempting to determine the manufacturer");
- if (rc) {
- kfree(data);
+ if (rc)
return 0;
- }
-
str += sprintf(str, "Manufacturer: 0x%x\n",
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
+ be32_to_cpu(cap.manufacturer_id));
- memcpy(data, cap_version, sizeof(cap_version));
- data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
- rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
- "attempting to determine the 1.1 version");
+ rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap,
+ "attempting to determine the 1.1 version");
if (rc)
- goto out;
-
+ return 0;
str += sprintf(str,
"TCG version: %d.%d\nFirmware version: %d.%d\n",
- (int) data[14], (int) data[15], (int) data[16],
- (int) data[17]);
-
-out:
- kfree(data);
+ cap.tpm_version.Major, cap.tpm_version.Minor,
+ cap.tpm_version.revMajor, cap.tpm_version.revMinor);
return str - buf;
}
EXPORT_SYMBOL_GPL(tpm_show_caps);
@@ -898,51 +890,25 @@ EXPORT_SYMBOL_GPL(tpm_show_caps);
ssize_t tpm_show_caps_1_2(struct device * dev,
struct device_attribute * attr, char *buf)
{
- u8 *data;
- ssize_t len;
+ cap_t cap;
+ ssize_t rc;
char *str = buf;
- struct tpm_chip *chip = dev_get_drvdata(dev);
- if (chip == NULL)
- return -ENODEV;
-
- data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- memcpy(data, tpm_cap, sizeof(tpm_cap));
- data[TPM_CAP_IDX] = TPM_CAP_PROP;
- data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
-
- len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE);
- if (len <= TPM_ERROR_SIZE) {
- dev_dbg(chip->dev, "A TPM error (%d) occurred "
- "attempting to determine the manufacturer\n",
- be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
- kfree(data);
+ rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap,
+ "attempting to determine the manufacturer");
+ if (rc)
return 0;
- }
-
str += sprintf(str, "Manufacturer: 0x%x\n",
- be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
-
- memcpy(data, cap_version, sizeof(cap_version));
- data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
-
- len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE);
- if (len <= TPM_ERROR_SIZE) {
- dev_err(chip->dev, "A TPM error (%d) occurred "
- "attempting to determine the 1.2 version\n",
- be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
- goto out;
- }
+ be32_to_cpu(cap.manufacturer_id));
+ rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap,
+ "attempting to determine the 1.2 version");
+ if (rc)
+ return 0;
str += sprintf(str,
"TCG version: %d.%d\nFirmware version: %d.%d\n",
- (int) data[16], (int) data[17], (int) data[18],
- (int) data[19]);
-
-out:
- kfree(data);
+ cap.tpm_version_1_2.Major, cap.tpm_version_1_2.Minor,
+ cap.tpm_version_1_2.revMajor,
+ cap.tpm_version_1_2.revMinor);
return str - buf;
}
EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 8e30df4a4388..8e00b4ddd083 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -26,6 +26,7 @@
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/tpm.h>
enum tpm_timeout {
TPM_TIMEOUT = 5, /* msecs */
@@ -123,6 +124,147 @@ static inline void tpm_write_index(int base, int index, int value)
outb(index, base);
outb(value & 0xFF, base+1);
}
+struct tpm_input_header {
+ __be16 tag;
+ __be32 length;
+ __be32 ordinal;
+}__attribute__((packed));
+
+struct tpm_output_header {
+ __be16 tag;
+ __be32 length;
+ __be32 return_code;
+}__attribute__((packed));
+
+struct stclear_flags_t {
+ __be16 tag;
+ u8 deactivated;
+ u8 disableForceClear;
+ u8 physicalPresence;
+ u8 physicalPresenceLock;
+ u8 bGlobalLock;
+}__attribute__((packed));
+
+struct tpm_version_t {
+ u8 Major;
+ u8 Minor;
+ u8 revMajor;
+ u8 revMinor;
+}__attribute__((packed));
+
+struct tpm_version_1_2_t {
+ __be16 tag;
+ u8 Major;
+ u8 Minor;
+ u8 revMajor;
+ u8 revMinor;
+}__attribute__((packed));
+
+struct timeout_t {
+ __be32 a;
+ __be32 b;
+ __be32 c;
+ __be32 d;
+}__attribute__((packed));
+
+struct duration_t {
+ __be32 tpm_short;
+ __be32 tpm_medium;
+ __be32 tpm_long;
+}__attribute__((packed));
+
+struct permanent_flags_t {
+ __be16 tag;
+ u8 disable;
+ u8 ownership;
+ u8 deactivated;
+ u8 readPubek;
+ u8 disableOwnerClear;
+ u8 allowMaintenance;
+ u8 physicalPresenceLifetimeLock;
+ u8 physicalPresenceHWEnable;
+ u8 physicalPresenceCMDEnable;
+ u8 CEKPUsed;
+ u8 TPMpost;
+ u8 TPMpostLock;
+ u8 FIPS;
+ u8 operator;
+ u8 enableRevokeEK;
+ u8 nvLocked;
+ u8 readSRKPub;
+ u8 tpmEstablished;
+ u8 maintenanceDone;
+ u8 disableFullDALogicInfo;
+}__attribute__((packed));
+
+typedef union {
+ struct permanent_flags_t perm_flags;
+ struct stclear_flags_t stclear_flags;
+ bool owned;
+ __be32 num_pcrs;
+ struct tpm_version_t tpm_version;
+ struct tpm_version_1_2_t tpm_version_1_2;
+ __be32 manufacturer_id;
+ struct timeout_t timeout;
+ struct duration_t duration;
+} cap_t;
+
+struct tpm_getcap_params_in {
+ __be32 cap;
+ __be32 subcap_size;
+ __be32 subcap;
+}__attribute__((packed));
+
+struct tpm_getcap_params_out {
+ __be32 cap_size;
+ cap_t cap;
+}__attribute__((packed));
+
+struct tpm_readpubek_params_out {
+ u8 algorithm[4];
+ u8 encscheme[2];
+ u8 sigscheme[2];
+ u8 parameters[12]; /*assuming RSA*/
+ __be32 keysize;
+ u8 modulus[256];
+ u8 checksum[20];
+}__attribute__((packed));
+
+typedef union {
+ struct tpm_input_header in;
+ struct tpm_output_header out;
+} tpm_cmd_header;
+
+#define TPM_DIGEST_SIZE 20
+struct tpm_pcrread_out {
+ u8 pcr_result[TPM_DIGEST_SIZE];
+}__attribute__((packed));
+
+struct tpm_pcrread_in {
+ __be32 pcr_idx;
+}__attribute__((packed));
+
+struct tpm_pcrextend_in {
+ __be32 pcr_idx;
+ u8 hash[TPM_DIGEST_SIZE];
+}__attribute__((packed));
+
+typedef union {
+ struct tpm_getcap_params_out getcap_out;
+ struct tpm_readpubek_params_out readpubek_out;
+ u8 readpubek_out_buffer[sizeof(struct tpm_readpubek_params_out)];
+ struct tpm_getcap_params_in getcap_in;
+ struct tpm_pcrread_in pcrread_in;
+ struct tpm_pcrread_out pcrread_out;
+ struct tpm_pcrextend_in pcrextend_in;
+} tpm_cmd_params;
+
+struct tpm_cmd_t {
+ tpm_cmd_header header;
+ tpm_cmd_params params;
+}__attribute__((packed));
+
+ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *);
extern void tpm_get_timeouts(struct tpm_chip *);
extern void tpm_gen_interrupt(struct tpm_chip *);
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index d0e7926eb486..c64a1bc65349 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -168,12 +168,22 @@ static void atml_plat_remove(void)
}
}
-static struct device_driver atml_drv = {
- .name = "tpm_atmel",
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
+static int tpm_atml_suspend(struct platform_device *dev, pm_message_t msg)
+{
+ return tpm_pm_suspend(&dev->dev, msg);
+}
+
+static int tpm_atml_resume(struct platform_device *dev)
+{
+ return tpm_pm_resume(&dev->dev);
+}
+static struct platform_driver atml_drv = {
+ .driver = {
+ .name = "tpm_atmel",
+ .owner = THIS_MODULE,
+ },
+ .suspend = tpm_atml_suspend,
+ .resume = tpm_atml_resume,
};
static int __init init_atmel(void)
@@ -184,7 +194,7 @@ static int __init init_atmel(void)
unsigned long base;
struct tpm_chip *chip;
- rc = driver_register(&atml_drv);
+ rc = platform_driver_register(&atml_drv);
if (rc)
return rc;
@@ -223,13 +233,13 @@ err_rel_reg:
atmel_release_region(base,
region_size);
err_unreg_drv:
- driver_unregister(&atml_drv);
+ platform_driver_unregister(&atml_drv);
return rc;
}
static void __exit cleanup_atmel(void)
{
- driver_unregister(&atml_drv);
+ platform_driver_unregister(&atml_drv);
atml_plat_remove();
}
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 717af7ad1bdf..aec1931608aa 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -654,12 +654,22 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
-static struct device_driver tis_drv = {
- .name = "tpm_tis",
- .bus = &platform_bus_type,
- .owner = THIS_MODULE,
- .suspend = tpm_pm_suspend,
- .resume = tpm_pm_resume,
+static int tpm_tis_suspend(struct platform_device *dev, pm_message_t msg)
+{
+ return tpm_pm_suspend(&dev->dev, msg);
+}
+
+static int tpm_tis_resume(struct platform_device *dev)
+{
+ return tpm_pm_resume(&dev->dev);
+}
+static struct platform_driver tis_drv = {
+ .driver = {
+ .name = "tpm_tis",
+ .owner = THIS_MODULE,
+ },
+ .suspend = tpm_tis_suspend,
+ .resume = tpm_tis_resume,
};
static struct platform_device *pdev;
@@ -672,14 +682,14 @@ static int __init init_tis(void)
int rc;
if (force) {
- rc = driver_register(&tis_drv);
+ rc = platform_driver_register(&tis_drv);
if (rc < 0)
return rc;
if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
return PTR_ERR(pdev);
if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) {
platform_device_unregister(pdev);
- driver_unregister(&tis_drv);
+ platform_driver_unregister(&tis_drv);
}
return rc;
}
@@ -711,7 +721,7 @@ static void __exit cleanup_tis(void)
if (force) {
platform_device_unregister(pdev);
- driver_unregister(&tis_drv);
+ platform_driver_unregister(&tis_drv);
} else
pnp_unregister_driver(&tis_pnp_driver);
}
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c
index 34ab6d798f81..55ba6f142883 100644
--- a/drivers/char/tty_audit.c
+++ b/drivers/char/tty_audit.c
@@ -10,8 +10,6 @@
*/
#include <linux/audit.h>
-#include <linux/file.h>
-#include <linux/fdtable.h>
#include <linux/tty.h>
struct tty_audit_buf {
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index bc84e125c6bc..66b99a2049e3 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -464,7 +464,7 @@ void tty_wakeup(struct tty_struct *tty)
tty_ldisc_deref(ld);
}
}
- wake_up_interruptible(&tty->write_wait);
+ wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
}
EXPORT_SYMBOL_GPL(tty_wakeup);
@@ -587,8 +587,8 @@ static void do_tty_hangup(struct work_struct *work)
* FIXME: Once we trust the LDISC code better we can wait here for
* ldisc completion and fix the driver call race
*/
- wake_up_interruptible(&tty->write_wait);
- wake_up_interruptible(&tty->read_wait);
+ wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
+ wake_up_interruptible_poll(&tty->read_wait, POLLIN);
/*
* Shutdown the current line discipline, and reset it to
* N_TTY.
@@ -879,7 +879,7 @@ void stop_tty(struct tty_struct *tty)
if (tty->link && tty->link->packet) {
tty->ctrl_status &= ~TIOCPKT_START;
tty->ctrl_status |= TIOCPKT_STOP;
- wake_up_interruptible(&tty->link->read_wait);
+ wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
}
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
if (tty->ops->stop)
@@ -913,7 +913,7 @@ void start_tty(struct tty_struct *tty)
if (tty->link && tty->link->packet) {
tty->ctrl_status &= ~TIOCPKT_STOP;
tty->ctrl_status |= TIOCPKT_START;
- wake_up_interruptible(&tty->link->read_wait);
+ wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
}
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
if (tty->ops->start)
@@ -970,7 +970,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
void tty_write_unlock(struct tty_struct *tty)
{
mutex_unlock(&tty->atomic_write_lock);
- wake_up_interruptible(&tty->write_wait);
+ wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
}
int tty_write_lock(struct tty_struct *tty, int ndelay)
@@ -1623,21 +1623,21 @@ void tty_release_dev(struct file *filp)
if (tty_closing) {
if (waitqueue_active(&tty->read_wait)) {
- wake_up(&tty->read_wait);
+ wake_up_poll(&tty->read_wait, POLLIN);
do_sleep++;
}
if (waitqueue_active(&tty->write_wait)) {
- wake_up(&tty->write_wait);
+ wake_up_poll(&tty->write_wait, POLLOUT);
do_sleep++;
}
}
if (o_tty_closing) {
if (waitqueue_active(&o_tty->read_wait)) {
- wake_up(&o_tty->read_wait);
+ wake_up_poll(&o_tty->read_wait, POLLIN);
do_sleep++;
}
if (waitqueue_active(&o_tty->write_wait)) {
- wake_up(&o_tty->write_wait);
+ wake_up_poll(&o_tty->write_wait, POLLOUT);
do_sleep++;
}
}
@@ -1758,7 +1758,7 @@ static int __tty_open(struct inode *inode, struct file *filp)
struct tty_driver *driver;
int index;
dev_t device = inode->i_rdev;
- unsigned short saved_flags = filp->f_flags;
+ unsigned saved_flags = filp->f_flags;
nonseekable_open(inode, filp);
@@ -2162,13 +2162,12 @@ static int fionbio(struct file *file, int __user *p)
if (get_user(nonblock, p))
return -EFAULT;
- /* file->f_flags is still BKL protected in the fs layer - vomit */
- lock_kernel();
+ spin_lock(&file->f_lock);
if (nonblock)
file->f_flags |= O_NONBLOCK;
else
file->f_flags &= ~O_NONBLOCK;
- unlock_kernel();
+ spin_unlock(&file->f_lock);
return 0;
}
@@ -2682,7 +2681,7 @@ void __do_SAK(struct tty_struct *tty)
/* Kill the entire session */
do_each_pid_task(session, PIDTYPE_SID, p) {
printk(KERN_NOTICE "SAK: killed process %d"
- " (%s): task_session_nr(p)==tty->session\n",
+ " (%s): task_session(p)==tty->session\n",
task_pid_nr(p), p->comm);
send_sig(SIGKILL, p, 1);
} while_each_pid_task(session, PIDTYPE_SID, p);
@@ -2692,7 +2691,7 @@ void __do_SAK(struct tty_struct *tty)
do_each_thread(g, p) {
if (p->signal->tty == tty) {
printk(KERN_NOTICE "SAK: killed process %d"
- " (%s): task_session_nr(p)==tty->session\n",
+ " (%s): task_session(p)==tty->session\n",
task_pid_nr(p), p->comm);
send_sig(SIGKILL, p, 1);
continue;
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index 7a84b406a952..f78f5b0127a8 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -10,7 +10,6 @@
#include <linux/tty_flip.h>
#include <linux/devpts_fs.h>
#include <linux/file.h>
-#include <linux/fdtable.h>
#include <linux/console.h>
#include <linux/timer.h>
#include <linux/ctype.h>
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 4f3b3f95fc42..d94d25c12aa8 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -479,18 +479,18 @@ static const struct file_operations vcs_fops = {
static struct class *vc_class;
-void vcs_make_sysfs(struct tty_struct *tty)
+void vcs_make_sysfs(int index)
{
- device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), NULL,
- "vcs%u", tty->index + 1);
- device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), NULL,
- "vcsa%u", tty->index + 1);
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL,
+ "vcs%u", index + 1);
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL,
+ "vcsa%u", index + 1);
}
-void vcs_remove_sysfs(struct tty_struct *tty)
+void vcs_remove_sysfs(int index)
{
- device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1));
- device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129));
+ device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 1));
+ device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 129));
}
int __init vcs_init(void)
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 7900bd63b36d..2c1d133819b5 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -778,6 +778,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
}
vc->vc_kmalloced = 1;
vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
+ vcs_make_sysfs(currcons);
atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
}
return 0;
@@ -987,7 +988,9 @@ void vc_deallocate(unsigned int currcons)
if (vc_cons_allocated(currcons)) {
struct vc_data *vc = vc_cons[currcons].d;
struct vt_notifier_param param = { .vc = vc };
+
atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
+ vcs_remove_sysfs(currcons);
vc->vc_sw->con_deinit(vc);
put_pid(vc->vt_pid);
module_put(vc->vc_sw->owner);
@@ -2775,7 +2778,6 @@ static int con_open(struct tty_struct *tty, struct file *filp)
tty->termios->c_iflag |= IUTF8;
else
tty->termios->c_iflag &= ~IUTF8;
- vcs_make_sysfs(tty);
release_console_sem();
return ret;
}
@@ -2795,7 +2797,6 @@ static void con_shutdown(struct tty_struct *tty)
BUG_ON(vc == NULL);
acquire_console_sem();
vc->vc_tty = NULL;
- vcs_remove_sysfs(tty);
release_console_sem();
tty_shutdown(tty);
}
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 1525882190fd..1efb2879a94f 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o
obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o
obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o
+obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
new file mode 100644
index 000000000000..1c92c39a53aa
--- /dev/null
+++ b/drivers/clocksource/sh_cmt.c
@@ -0,0 +1,614 @@
+/*
+ * SuperH Timer Support - CMT
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/sh_cmt.h>
+
+struct sh_cmt_priv {
+ void __iomem *mapbase;
+ struct clk *clk;
+ unsigned long width; /* 16 or 32 bit version of hardware block */
+ unsigned long overflow_bit;
+ unsigned long clear_bits;
+ struct irqaction irqaction;
+ struct platform_device *pdev;
+
+ unsigned long flags;
+ unsigned long match_value;
+ unsigned long next_match_value;
+ unsigned long max_match_value;
+ unsigned long rate;
+ spinlock_t lock;
+ struct clock_event_device ced;
+ unsigned long total_cycles;
+};
+
+static DEFINE_SPINLOCK(sh_cmt_lock);
+
+#define CMSTR -1 /* shared register */
+#define CMCSR 0 /* channel register */
+#define CMCNT 1 /* channel register */
+#define CMCOR 2 /* channel register */
+
+static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr)
+{
+ struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ void __iomem *base = p->mapbase;
+ unsigned long offs;
+
+ if (reg_nr == CMSTR) {
+ offs = 0;
+ base -= cfg->channel_offset;
+ } else
+ offs = reg_nr;
+
+ if (p->width == 16)
+ offs <<= 1;
+ else {
+ offs <<= 2;
+ if ((reg_nr == CMCNT) || (reg_nr == CMCOR))
+ return ioread32(base + offs);
+ }
+
+ return ioread16(base + offs);
+}
+
+static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr,
+ unsigned long value)
+{
+ struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ void __iomem *base = p->mapbase;
+ unsigned long offs;
+
+ if (reg_nr == CMSTR) {
+ offs = 0;
+ base -= cfg->channel_offset;
+ } else
+ offs = reg_nr;
+
+ if (p->width == 16)
+ offs <<= 1;
+ else {
+ offs <<= 2;
+ if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) {
+ iowrite32(value, base + offs);
+ return;
+ }
+ }
+
+ iowrite16(value, base + offs);
+}
+
+static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
+ int *has_wrapped)
+{
+ unsigned long v1, v2, v3;
+
+ /* Make sure the timer value is stable. Stolen from acpi_pm.c */
+ do {
+ v1 = sh_cmt_read(p, CMCNT);
+ v2 = sh_cmt_read(p, CMCNT);
+ v3 = sh_cmt_read(p, CMCNT);
+ } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
+ || (v3 > v1 && v3 < v2)));
+
+ *has_wrapped = sh_cmt_read(p, CMCSR) & p->overflow_bit;
+ return v2;
+}
+
+
+static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start)
+{
+ struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ unsigned long flags, value;
+
+ /* start stop register shared by multiple timer channels */
+ spin_lock_irqsave(&sh_cmt_lock, flags);
+ value = sh_cmt_read(p, CMSTR);
+
+ if (start)
+ value |= 1 << cfg->timer_bit;
+ else
+ value &= ~(1 << cfg->timer_bit);
+
+ sh_cmt_write(p, CMSTR, value);
+ spin_unlock_irqrestore(&sh_cmt_lock, flags);
+}
+
+static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate)
+{
+ struct sh_cmt_config *cfg = p->pdev->dev.platform_data;
+ int ret;
+
+ /* enable clock */
+ ret = clk_enable(p->clk);
+ if (ret) {
+ pr_err("sh_cmt: cannot enable clock \"%s\"\n", cfg->clk);
+ return ret;
+ }
+ *rate = clk_get_rate(p->clk) / 8;
+
+ /* make sure channel is disabled */
+ sh_cmt_start_stop_ch(p, 0);
+
+ /* configure channel, periodic mode and maximum timeout */
+ if (p->width == 16)
+ sh_cmt_write(p, CMCSR, 0);
+ else
+ sh_cmt_write(p, CMCSR, 0x01a4);
+
+ sh_cmt_write(p, CMCOR, 0xffffffff);
+ sh_cmt_write(p, CMCNT, 0);
+
+ /* enable channel */
+ sh_cmt_start_stop_ch(p, 1);
+ return 0;
+}
+
+static void sh_cmt_disable(struct sh_cmt_priv *p)
+{
+ /* disable channel */
+ sh_cmt_start_stop_ch(p, 0);
+
+ /* stop clock */
+ clk_disable(p->clk);
+}
+
+/* private flags */
+#define FLAG_CLOCKEVENT (1 << 0)
+#define FLAG_CLOCKSOURCE (1 << 1)
+#define FLAG_REPROGRAM (1 << 2)
+#define FLAG_SKIPEVENT (1 << 3)
+#define FLAG_IRQCONTEXT (1 << 4)
+
+static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
+ int absolute)
+{
+ unsigned long new_match;
+ unsigned long value = p->next_match_value;
+ unsigned long delay = 0;
+ unsigned long now = 0;
+ int has_wrapped;
+
+ now = sh_cmt_get_counter(p, &has_wrapped);
+ p->flags |= FLAG_REPROGRAM; /* force reprogram */
+
+ if (has_wrapped) {
+ /* we're competing with the interrupt handler.
+ * -> let the interrupt handler reprogram the timer.
+ * -> interrupt number two handles the event.
+ */
+ p->flags |= FLAG_SKIPEVENT;
+ return;
+ }
+
+ if (absolute)
+ now = 0;
+
+ do {
+ /* reprogram the timer hardware,
+ * but don't save the new match value yet.
+ */
+ new_match = now + value + delay;
+ if (new_match > p->max_match_value)
+ new_match = p->max_match_value;
+
+ sh_cmt_write(p, CMCOR, new_match);
+
+ now = sh_cmt_get_counter(p, &has_wrapped);
+ if (has_wrapped && (new_match > p->match_value)) {
+ /* we are changing to a greater match value,
+ * so this wrap must be caused by the counter
+ * matching the old value.
+ * -> first interrupt reprograms the timer.
+ * -> interrupt number two handles the event.
+ */
+ p->flags |= FLAG_SKIPEVENT;
+ break;
+ }
+
+ if (has_wrapped) {
+ /* we are changing to a smaller match value,
+ * so the wrap must be caused by the counter
+ * matching the new value.
+ * -> save programmed match value.
+ * -> let isr handle the event.
+ */
+ p->match_value = new_match;
+ break;
+ }
+
+ /* be safe: verify hardware settings */
+ if (now < new_match) {
+ /* timer value is below match value, all good.
+ * this makes sure we won't miss any match events.
+ * -> save programmed match value.
+ * -> let isr handle the event.
+ */
+ p->match_value = new_match;
+ break;
+ }
+
+ /* the counter has reached a value greater
+ * than our new match value. and since the
+ * has_wrapped flag isn't set we must have
+ * programmed a too close event.
+ * -> increase delay and retry.
+ */
+ if (delay)
+ delay <<= 1;
+ else
+ delay = 1;
+
+ if (!delay)
+ pr_warning("sh_cmt: too long delay\n");
+
+ } while (delay);
+}
+
+static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
+{
+ unsigned long flags;
+
+ if (delta > p->max_match_value)
+ pr_warning("sh_cmt: delta out of range\n");
+
+ spin_lock_irqsave(&p->lock, flags);
+ p->next_match_value = delta;
+ sh_cmt_clock_event_program_verify(p, 0);
+ spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
+{
+ struct sh_cmt_priv *p = dev_id;
+
+ /* clear flags */
+ sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits);
+
+ /* update clock source counter to begin with if enabled
+ * the wrap flag should be cleared by the timer specific
+ * isr before we end up here.
+ */
+ if (p->flags & FLAG_CLOCKSOURCE)
+ p->total_cycles += p->match_value;
+
+ if (!(p->flags & FLAG_REPROGRAM))
+ p->next_match_value = p->max_match_value;
+
+ p->flags |= FLAG_IRQCONTEXT;
+
+ if (p->flags & FLAG_CLOCKEVENT) {
+ if (!(p->flags & FLAG_SKIPEVENT)) {
+ if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) {
+ p->next_match_value = p->max_match_value;
+ p->flags |= FLAG_REPROGRAM;
+ }
+
+ p->ced.event_handler(&p->ced);
+ }
+ }
+
+ p->flags &= ~FLAG_SKIPEVENT;
+
+ if (p->flags & FLAG_REPROGRAM) {
+ p->flags &= ~FLAG_REPROGRAM;
+ sh_cmt_clock_event_program_verify(p, 1);
+
+ if (p->flags & FLAG_CLOCKEVENT)
+ if ((p->ced.mode == CLOCK_EVT_MODE_SHUTDOWN)
+ || (p->match_value == p->next_match_value))
+ p->flags &= ~FLAG_REPROGRAM;
+ }
+
+ p->flags &= ~FLAG_IRQCONTEXT;
+
+ return IRQ_HANDLED;
+}
+
+static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&p->lock, flags);
+
+ if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+ ret = sh_cmt_enable(p, &p->rate);
+
+ if (ret)
+ goto out;
+ p->flags |= flag;
+
+ /* setup timeout if no clockevent */
+ if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT)))
+ sh_cmt_set_next(p, p->max_match_value);
+ out:
+ spin_unlock_irqrestore(&p->lock, flags);
+
+ return ret;
+}
+
+static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
+{
+ unsigned long flags;
+ unsigned long f;
+
+ spin_lock_irqsave(&p->lock, flags);
+
+ f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE);
+ p->flags &= ~flag;
+
+ if (f && !(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
+ sh_cmt_disable(p);
+
+ /* adjust the timeout to maximum if only clocksource left */
+ if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE))
+ sh_cmt_set_next(p, p->max_match_value);
+
+ spin_unlock_irqrestore(&p->lock, flags);
+}
+
+static struct sh_cmt_priv *ced_to_sh_cmt(struct clock_event_device *ced)
+{
+ return container_of(ced, struct sh_cmt_priv, ced);
+}
+
+static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic)
+{
+ struct clock_event_device *ced = &p->ced;
+
+ sh_cmt_start(p, FLAG_CLOCKEVENT);
+
+ /* TODO: calculate good shift from rate and counter bit width */
+
+ ced->shift = 32;
+ ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
+ ced->max_delta_ns = clockevent_delta2ns(p->max_match_value, ced);
+ ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
+
+ if (periodic)
+ sh_cmt_set_next(p, (p->rate + HZ/2) / HZ);
+ else
+ sh_cmt_set_next(p, p->max_match_value);
+}
+
+static void sh_cmt_clock_event_mode(enum clock_event_mode mode,
+ struct clock_event_device *ced)
+{
+ struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+
+ /* deal with old setting first */
+ switch (ced->mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ case CLOCK_EVT_MODE_ONESHOT:
+ sh_cmt_stop(p, FLAG_CLOCKEVENT);
+ break;
+ default:
+ break;
+ }
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ pr_info("sh_cmt: %s used for periodic clock events\n",
+ ced->name);
+ sh_cmt_clock_event_start(p, 1);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ pr_info("sh_cmt: %s used for oneshot clock events\n",
+ ced->name);
+ sh_cmt_clock_event_start(p, 0);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ sh_cmt_stop(p, FLAG_CLOCKEVENT);
+ break;
+ default:
+ break;
+ }
+}
+
+static int sh_cmt_clock_event_next(unsigned long delta,
+ struct clock_event_device *ced)
+{
+ struct sh_cmt_priv *p = ced_to_sh_cmt(ced);
+
+ BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT);
+ if (likely(p->flags & FLAG_IRQCONTEXT))
+ p->next_match_value = delta;
+ else
+ sh_cmt_set_next(p, delta);
+
+ return 0;
+}
+
+static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
+ char *name, unsigned long rating)
+{
+ struct clock_event_device *ced = &p->ced;
+
+ memset(ced, 0, sizeof(*ced));
+
+ ced->name = name;
+ ced->features = CLOCK_EVT_FEAT_PERIODIC;
+ ced->features |= CLOCK_EVT_FEAT_ONESHOT;
+ ced->rating = rating;
+ ced->cpumask = cpumask_of(0);
+ ced->set_next_event = sh_cmt_clock_event_next;
+ ced->set_mode = sh_cmt_clock_event_mode;
+
+ pr_info("sh_cmt: %s used for clock events\n", ced->name);
+ clockevents_register_device(ced);
+}
+
+int sh_cmt_register(struct sh_cmt_priv *p, char *name,
+ unsigned long clockevent_rating,
+ unsigned long clocksource_rating)
+{
+ if (p->width == (sizeof(p->max_match_value) * 8))
+ p->max_match_value = ~0;
+ else
+ p->max_match_value = (1 << p->width) - 1;
+
+ p->match_value = p->max_match_value;
+ spin_lock_init(&p->lock);
+
+ if (clockevent_rating)
+ sh_cmt_register_clockevent(p, name, clockevent_rating);
+
+ return 0;
+}
+
+static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
+{
+ struct sh_cmt_config *cfg = pdev->dev.platform_data;
+ struct resource *res;
+ int irq, ret;
+ ret = -ENXIO;
+
+ memset(p, 0, sizeof(*p));
+ p->pdev = pdev;
+
+ if (!cfg) {
+ dev_err(&p->pdev->dev, "missing platform data\n");
+ goto err0;
+ }
+
+ platform_set_drvdata(pdev, p);
+
+ res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&p->pdev->dev, "failed to get I/O memory\n");
+ goto err0;
+ }
+
+ irq = platform_get_irq(p->pdev, 0);
+ if (irq < 0) {
+ dev_err(&p->pdev->dev, "failed to get irq\n");
+ goto err0;
+ }
+
+ /* map memory, let mapbase point to our channel */
+ p->mapbase = ioremap_nocache(res->start, resource_size(res));
+ if (p->mapbase == NULL) {
+ pr_err("sh_cmt: failed to remap I/O memory\n");
+ goto err0;
+ }
+
+ /* request irq using setup_irq() (too early for request_irq()) */
+ p->irqaction.name = cfg->name;
+ p->irqaction.handler = sh_cmt_interrupt;
+ p->irqaction.dev_id = p;
+ p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
+ p->irqaction.mask = CPU_MASK_NONE;
+ ret = setup_irq(irq, &p->irqaction);
+ if (ret) {
+ pr_err("sh_cmt: failed to request irq %d\n", irq);
+ goto err1;
+ }
+
+ /* get hold of clock */
+ p->clk = clk_get(&p->pdev->dev, cfg->clk);
+ if (IS_ERR(p->clk)) {
+ pr_err("sh_cmt: cannot get clock \"%s\"\n", cfg->clk);
+ ret = PTR_ERR(p->clk);
+ goto err2;
+ }
+
+ if (resource_size(res) == 6) {
+ p->width = 16;
+ p->overflow_bit = 0x80;
+ p->clear_bits = ~0xc0;
+ } else {
+ p->width = 32;
+ p->overflow_bit = 0x8000;
+ p->clear_bits = ~0xc000;
+ }
+
+ return sh_cmt_register(p, cfg->name,
+ cfg->clockevent_rating,
+ cfg->clocksource_rating);
+ err2:
+ remove_irq(irq, &p->irqaction);
+ err1:
+ iounmap(p->mapbase);
+ err0:
+ return ret;
+}
+
+static int __devinit sh_cmt_probe(struct platform_device *pdev)
+{
+ struct sh_cmt_priv *p = platform_get_drvdata(pdev);
+ int ret;
+
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (p == NULL) {
+ dev_err(&pdev->dev, "failed to allocate driver data\n");
+ return -ENOMEM;
+ }
+
+ ret = sh_cmt_setup(p, pdev);
+ if (ret) {
+ kfree(p);
+
+ platform_set_drvdata(pdev, NULL);
+ }
+ return ret;
+}
+
+static int __devexit sh_cmt_remove(struct platform_device *pdev)
+{
+ return -EBUSY; /* cannot unregister clockevent and clocksource */
+}
+
+static struct platform_driver sh_cmt_device_driver = {
+ .probe = sh_cmt_probe,
+ .remove = __devexit_p(sh_cmt_remove),
+ .driver = {
+ .name = "sh_cmt",
+ }
+};
+
+static int __init sh_cmt_init(void)
+{
+ return platform_driver_register(&sh_cmt_device_driver);
+}
+
+static void __exit sh_cmt_exit(void)
+{
+ platform_driver_unregister(&sh_cmt_device_driver);
+}
+
+module_init(sh_cmt_init);
+module_exit(sh_cmt_exit);
+
+MODULE_AUTHOR("Magnus Damm");
+MODULE_DESCRIPTION("SuperH CMT Timer Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
index b6fe7e7a2c2f..c769ef269fb5 100644
--- a/drivers/connector/cn_queue.c
+++ b/drivers/connector/cn_queue.c
@@ -1,9 +1,9 @@
/*
* cn_queue.c
- *
+ *
* 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
* All rights reserved.
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -31,6 +31,48 @@
#include <linux/connector.h>
#include <linux/delay.h>
+
+/*
+ * This job is sent to the kevent workqueue.
+ * While no event is once sent to any callback, the connector workqueue
+ * is not created to avoid a useless waiting kernel task.
+ * Once the first event is received, we create this dedicated workqueue which
+ * is necessary because the flow of data can be high and we don't want
+ * to encumber keventd with that.
+ */
+static void cn_queue_create(struct work_struct *work)
+{
+ struct cn_queue_dev *dev;
+
+ dev = container_of(work, struct cn_queue_dev, wq_creation);
+
+ dev->cn_queue = create_singlethread_workqueue(dev->name);
+ /* If we fail, we will use keventd for all following connector jobs */
+ WARN_ON(!dev->cn_queue);
+}
+
+/*
+ * Queue a data sent to a callback.
+ * If the connector workqueue is already created, we queue the job on it.
+ * Otherwise, we queue the job to kevent and queue the connector workqueue
+ * creation too.
+ */
+int queue_cn_work(struct cn_callback_entry *cbq, struct work_struct *work)
+{
+ struct cn_queue_dev *pdev = cbq->pdev;
+
+ if (likely(pdev->cn_queue))
+ return queue_work(pdev->cn_queue, work);
+
+ /* Don't create the connector workqueue twice */
+ if (atomic_inc_return(&pdev->wq_requested) == 1)
+ schedule_work(&pdev->wq_creation);
+ else
+ atomic_dec(&pdev->wq_requested);
+
+ return schedule_work(work);
+}
+
void cn_queue_wrapper(struct work_struct *work)
{
struct cn_callback_entry *cbq =
@@ -58,14 +100,17 @@ static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struc
snprintf(cbq->id.name, sizeof(cbq->id.name), "%s", name);
memcpy(&cbq->id.id, id, sizeof(struct cb_id));
cbq->data.callback = callback;
-
+
INIT_WORK(&cbq->work, &cn_queue_wrapper);
return cbq;
}
static void cn_queue_free_callback(struct cn_callback_entry *cbq)
{
- flush_workqueue(cbq->pdev->cn_queue);
+ /* The first jobs have been sent to kevent, flush them too */
+ flush_scheduled_work();
+ if (cbq->pdev->cn_queue)
+ flush_workqueue(cbq->pdev->cn_queue);
kfree(cbq);
}
@@ -143,14 +188,11 @@ struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *nls)
atomic_set(&dev->refcnt, 0);
INIT_LIST_HEAD(&dev->queue_list);
spin_lock_init(&dev->queue_lock);
+ init_waitqueue_head(&dev->wq_created);
dev->nls = nls;
- dev->cn_queue = create_singlethread_workqueue(dev->name);
- if (!dev->cn_queue) {
- kfree(dev);
- return NULL;
- }
+ INIT_WORK(&dev->wq_creation, cn_queue_create);
return dev;
}
@@ -158,9 +200,25 @@ struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *nls)
void cn_queue_free_dev(struct cn_queue_dev *dev)
{
struct cn_callback_entry *cbq, *n;
+ long timeout;
+ DEFINE_WAIT(wait);
+
+ /* Flush the first pending jobs queued on kevent */
+ flush_scheduled_work();
+
+ /* If the connector workqueue creation is still pending, wait for it */
+ prepare_to_wait(&dev->wq_created, &wait, TASK_UNINTERRUPTIBLE);
+ if (atomic_read(&dev->wq_requested) && !dev->cn_queue) {
+ timeout = schedule_timeout(HZ * 2);
+ if (!timeout && !dev->cn_queue)
+ WARN_ON(1);
+ }
+ finish_wait(&dev->wq_created, &wait);
- flush_workqueue(dev->cn_queue);
- destroy_workqueue(dev->cn_queue);
+ if (dev->cn_queue) {
+ flush_workqueue(dev->cn_queue);
+ destroy_workqueue(dev->cn_queue);
+ }
spin_lock_bh(&dev->queue_lock);
list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry)
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index bf4830082a13..fd336c5a9057 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -1,9 +1,9 @@
/*
* connector.c
- *
+ *
* 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
* All rights reserved.
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -145,14 +145,13 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
__cbq->data.ddata = data;
__cbq->data.destruct_data = destruct_data;
- if (queue_work(dev->cbdev->cn_queue,
- &__cbq->work))
+ if (queue_cn_work(__cbq, &__cbq->work))
err = 0;
else
err = -EINVAL;
} else {
struct cn_callback_data *d;
-
+
err = -ENOMEM;
__new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
if (__new_cbq) {
@@ -163,10 +162,12 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
d->destruct_data = destruct_data;
d->free = __new_cbq;
+ __new_cbq->pdev = __cbq->pdev;
+
INIT_WORK(&__new_cbq->work,
&cn_queue_wrapper);
- if (queue_work(dev->cbdev->cn_queue,
+ if (queue_cn_work(__new_cbq,
&__new_cbq->work))
err = 0;
else {
@@ -237,7 +238,7 @@ static void cn_notify(struct cb_id *id, u32 notify_event)
req = (struct cn_notify_req *)ctl->data;
for (i = 0; i < ctl->idx_notify_num; ++i, ++req) {
- if (id->idx >= req->first &&
+ if (id->idx >= req->first &&
id->idx < req->first + req->range) {
idx_found = 1;
break;
@@ -245,7 +246,7 @@ static void cn_notify(struct cb_id *id, u32 notify_event)
}
for (i = 0; i < ctl->val_notify_num; ++i, ++req) {
- if (id->val >= req->first &&
+ if (id->val >= req->first &&
id->val < req->first + req->range) {
val_found = 1;
break;
@@ -459,7 +460,7 @@ static int __devinit cn_init(void)
netlink_kernel_release(dev->nls);
return -EINVAL;
}
-
+
cn_already_initialized = 1;
err = cn_add_callback(&dev->id, "connector", &cn_callback);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index d6daf3c507d3..d270e8eb3e67 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -104,7 +104,8 @@ EXPORT_SYMBOL_GPL(unlock_policy_rwsem_write);
/* internal prototypes */
-static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
+static int __cpufreq_governor(struct cpufreq_policy *policy,
+ unsigned int event);
static unsigned int __cpufreq_get(unsigned int cpu);
static void handle_update(struct work_struct *work);
@@ -128,7 +129,7 @@ static int __init init_cpufreq_transition_notifier_list(void)
pure_initcall(init_cpufreq_transition_notifier_list);
static LIST_HEAD(cpufreq_governor_list);
-static DEFINE_MUTEX (cpufreq_governor_mutex);
+static DEFINE_MUTEX(cpufreq_governor_mutex);
struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
{
@@ -371,7 +372,7 @@ static struct cpufreq_governor *__find_governor(const char *str_governor)
struct cpufreq_governor *t;
list_for_each_entry(t, &cpufreq_governor_list, governor_list)
- if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN))
+ if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
return t;
return NULL;
@@ -429,15 +430,11 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
mutex_unlock(&cpufreq_governor_mutex);
}
- out:
+out:
return err;
}
-/* drivers/base/cpu.c */
-extern struct sysdev_class cpu_sysdev_class;
-
-
/**
* cpufreq_per_cpu_attr_read() / show_##file_name() -
* print out cpufreq information
@@ -450,11 +447,12 @@ extern struct sysdev_class cpu_sysdev_class;
static ssize_t show_##file_name \
(struct cpufreq_policy *policy, char *buf) \
{ \
- return sprintf (buf, "%u\n", policy->object); \
+ return sprintf(buf, "%u\n", policy->object); \
}
show_one(cpuinfo_min_freq, cpuinfo.min_freq);
show_one(cpuinfo_max_freq, cpuinfo.max_freq);
+show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
show_one(scaling_min_freq, min);
show_one(scaling_max_freq, max);
show_one(scaling_cur_freq, cur);
@@ -476,7 +474,7 @@ static ssize_t store_##file_name \
if (ret) \
return -EINVAL; \
\
- ret = sscanf (buf, "%u", &new_policy.object); \
+ ret = sscanf(buf, "%u", &new_policy.object); \
if (ret != 1) \
return -EINVAL; \
\
@@ -486,8 +484,8 @@ static ssize_t store_##file_name \
return ret ? ret : count; \
}
-store_one(scaling_min_freq,min);
-store_one(scaling_max_freq,max);
+store_one(scaling_min_freq, min);
+store_one(scaling_max_freq, max);
/**
* show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
@@ -507,12 +505,13 @@ static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
*/
static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
{
- if(policy->policy == CPUFREQ_POLICY_POWERSAVE)
+ if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
return sprintf(buf, "powersave\n");
else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
return sprintf(buf, "performance\n");
else if (policy->governor)
- return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", policy->governor->name);
+ return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n",
+ policy->governor->name);
return -EINVAL;
}
@@ -531,7 +530,7 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
if (ret)
return ret;
- ret = sscanf (buf, "%15s", str_governor);
+ ret = sscanf(buf, "%15s", str_governor);
if (ret != 1)
return -EINVAL;
@@ -575,7 +574,8 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
}
list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
- if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2)))
+ if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
+ - (CPUFREQ_NAME_LEN + 2)))
goto out;
i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
}
@@ -594,7 +594,7 @@ static ssize_t show_cpus(const struct cpumask *mask, char *buf)
i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
if (i >= (PAGE_SIZE - 5))
- break;
+ break;
}
i += sprintf(&buf[i], "\n");
return i;
@@ -660,6 +660,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name)
define_one_ro0400(cpuinfo_cur_freq);
define_one_ro(cpuinfo_min_freq);
define_one_ro(cpuinfo_max_freq);
+define_one_ro(cpuinfo_transition_latency);
define_one_ro(scaling_available_governors);
define_one_ro(scaling_driver);
define_one_ro(scaling_cur_freq);
@@ -673,6 +674,7 @@ define_one_rw(scaling_setspeed);
static struct attribute *default_attrs[] = {
&cpuinfo_min_freq.attr,
&cpuinfo_max_freq.attr,
+ &cpuinfo_transition_latency.attr,
&scaling_min_freq.attr,
&scaling_max_freq.attr,
&affected_cpus.attr,
@@ -684,10 +686,10 @@ static struct attribute *default_attrs[] = {
NULL
};
-#define to_policy(k) container_of(k,struct cpufreq_policy,kobj)
-#define to_attr(a) container_of(a,struct freq_attr,attr)
+#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
+#define to_attr(a) container_of(a, struct freq_attr, attr)
-static ssize_t show(struct kobject *kobj, struct attribute *attr ,char *buf)
+static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct cpufreq_policy *policy = to_policy(kobj);
struct freq_attr *fattr = to_attr(attr);
@@ -853,10 +855,10 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
if (cpu == j)
continue;
- /* check for existing affected CPUs. They may not be aware
- * of it due to CPU Hotplug.
+ /* Check for existing affected CPUs.
+ * They may not be aware of it due to CPU Hotplug.
*/
- managed_policy = cpufreq_cpu_get(j); // FIXME: Where is this released? What about error paths?
+ managed_policy = cpufreq_cpu_get(j); /* FIXME: Where is this released? What about error paths? */
if (unlikely(managed_policy)) {
/* Set proper policy_cpu */
@@ -1127,8 +1129,8 @@ static void handle_update(struct work_struct *work)
* @old_freq: CPU frequency the kernel thinks the CPU runs at
* @new_freq: CPU frequency the CPU actually runs at
*
- * We adjust to current frequency first, and need to clean up later. So either call
- * to cpufreq_update_policy() or schedule handle_update()).
+ * We adjust to current frequency first, and need to clean up later.
+ * So either call to cpufreq_update_policy() or schedule handle_update()).
*/
static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
unsigned int new_freq)
@@ -1610,7 +1612,8 @@ EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
/**
* cpufreq_get_policy - get the current cpufreq_policy
- * @policy: struct cpufreq_policy into which the current cpufreq_policy is written
+ * @policy: struct cpufreq_policy into which the current cpufreq_policy
+ * is written
*
* Reads the current cpufreq policy.
*/
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 0320962c4ec5..2ecd95e4ab1a 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -4,7 +4,7 @@
* Copyright (C) 2001 Russell King
* (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
* Jun Nakajima <jun.nakajima@intel.com>
- * (C) 2004 Alexander Clouter <alex-kernel@digriz.org.uk>
+ * (C) 2009 Alexander Clouter <alex@digriz.org.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -13,22 +13,17 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/smp.h>
#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ctype.h>
#include <linux/cpufreq.h>
-#include <linux/sysctl.h>
-#include <linux/types.h>
-#include <linux/fs.h>
-#include <linux/sysfs.h>
#include <linux/cpu.h>
-#include <linux/kmod.h>
-#include <linux/workqueue.h>
#include <linux/jiffies.h>
#include <linux/kernel_stat.h>
-#include <linux/percpu.h>
#include <linux/mutex.h>
+#include <linux/hrtimer.h>
+#include <linux/tick.h>
+#include <linux/ktime.h>
+#include <linux/sched.h>
+
/*
* dbs is used in this file as a shortform for demandbased switching
* It helps to keep variable names smaller, simpler
@@ -43,19 +38,31 @@
* latency of the processor. The governor will work on any processor with
* transition latency <= 10mS, using appropriate sampling
* rate.
- * For CPUs with transition latency > 10mS (mostly drivers
- * with CPUFREQ_ETERNAL), this governor will not work.
+ * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL)
+ * this governor will not work.
* All times here are in uS.
*/
static unsigned int def_sampling_rate;
#define MIN_SAMPLING_RATE_RATIO (2)
/* for correct statistics, we need at least 10 ticks between each measure */
-#define MIN_STAT_SAMPLING_RATE \
+#define MIN_STAT_SAMPLING_RATE \
(MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
#define MIN_SAMPLING_RATE \
(def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
+/* Above MIN_SAMPLING_RATE will vanish with its sysfs file soon
+ * Define the minimal settable sampling rate to the greater of:
+ * - "HW transition latency" * 100 (same as default sampling / 10)
+ * - MIN_STAT_SAMPLING_RATE
+ * To avoid that userspace shoots itself.
+*/
+static unsigned int minimum_sampling_rate(void)
+{
+ return max(def_sampling_rate / 10, MIN_STAT_SAMPLING_RATE);
+}
+
+/* This will also vanish soon with removing sampling_rate_max */
#define MAX_SAMPLING_RATE (500 * def_sampling_rate)
-#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000)
+#define LATENCY_MULTIPLIER (1000)
#define DEF_SAMPLING_DOWN_FACTOR (1)
#define MAX_SAMPLING_DOWN_FACTOR (10)
#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000)
@@ -63,12 +70,15 @@ static unsigned int def_sampling_rate;
static void do_dbs_timer(struct work_struct *work);
struct cpu_dbs_info_s {
+ cputime64_t prev_cpu_idle;
+ cputime64_t prev_cpu_wall;
+ cputime64_t prev_cpu_nice;
struct cpufreq_policy *cur_policy;
- unsigned int prev_cpu_idle_up;
- unsigned int prev_cpu_idle_down;
- unsigned int enable;
+ struct delayed_work work;
unsigned int down_skip;
unsigned int requested_freq;
+ int cpu;
+ unsigned int enable:1;
};
static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
@@ -82,19 +92,18 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */
* cpu_hotplug lock should be taken before that. Note that cpu_hotplug lock
* is recursive for the same process. -Venki
*/
-static DEFINE_MUTEX (dbs_mutex);
-static DECLARE_DELAYED_WORK(dbs_work, do_dbs_timer);
+static DEFINE_MUTEX(dbs_mutex);
-struct dbs_tuners {
+static struct workqueue_struct *kconservative_wq;
+
+static struct dbs_tuners {
unsigned int sampling_rate;
unsigned int sampling_down_factor;
unsigned int up_threshold;
unsigned int down_threshold;
unsigned int ignore_nice;
unsigned int freq_step;
-};
-
-static struct dbs_tuners dbs_tuners_ins = {
+} dbs_tuners_ins = {
.up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
.down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD,
.sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
@@ -102,18 +111,37 @@ static struct dbs_tuners dbs_tuners_ins = {
.freq_step = 5,
};
-static inline unsigned int get_cpu_idle_time(unsigned int cpu)
+static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
+ cputime64_t *wall)
{
- unsigned int add_nice = 0, ret;
+ cputime64_t idle_time;
+ cputime64_t cur_wall_time;
+ cputime64_t busy_time;
- if (dbs_tuners_ins.ignore_nice)
- add_nice = kstat_cpu(cpu).cpustat.nice;
+ cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
+ busy_time = cputime64_add(kstat_cpu(cpu).cpustat.user,
+ kstat_cpu(cpu).cpustat.system);
+
+ busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.irq);
+ busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.softirq);
+ busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.steal);
+ busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.nice);
+
+ idle_time = cputime64_sub(cur_wall_time, busy_time);
+ if (wall)
+ *wall = cur_wall_time;
+
+ return idle_time;
+}
+
+static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
+{
+ u64 idle_time = get_cpu_idle_time_us(cpu, wall);
- ret = kstat_cpu(cpu).cpustat.idle +
- kstat_cpu(cpu).cpustat.iowait +
- add_nice;
+ if (idle_time == -1ULL)
+ return get_cpu_idle_time_jiffy(cpu, wall);
- return ret;
+ return idle_time;
}
/* keep track of frequency transitions */
@@ -125,10 +153,21 @@ dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info,
freq->cpu);
+ struct cpufreq_policy *policy;
+
if (!this_dbs_info->enable)
return 0;
- this_dbs_info->requested_freq = freq->new;
+ policy = this_dbs_info->cur_policy;
+
+ /*
+ * we only care if our internally tracked freq moves outside
+ * the 'valid' ranges of freqency available to us otherwise
+ * we do not change it
+ */
+ if (this_dbs_info->requested_freq > policy->max
+ || this_dbs_info->requested_freq < policy->min)
+ this_dbs_info->requested_freq = freq->new;
return 0;
}
@@ -140,16 +179,31 @@ static struct notifier_block dbs_cpufreq_notifier_block = {
/************************** sysfs interface ************************/
static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
{
- return sprintf (buf, "%u\n", MAX_SAMPLING_RATE);
+ static int print_once;
+
+ if (!print_once) {
+ printk(KERN_INFO "CPUFREQ: conservative sampling_rate_max "
+ "sysfs file is deprecated - used by: %s\n",
+ current->comm);
+ print_once = 1;
+ }
+ return sprintf(buf, "%u\n", MAX_SAMPLING_RATE);
}
static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
{
- return sprintf (buf, "%u\n", MIN_SAMPLING_RATE);
+ static int print_once;
+
+ if (!print_once) {
+ printk(KERN_INFO "CPUFREQ: conservative sampling_rate_max "
+ "sysfs file is deprecated - used by: %s\n", current->comm);
+ print_once = 1;
+ }
+ return sprintf(buf, "%u\n", MIN_SAMPLING_RATE);
}
-#define define_one_ro(_name) \
-static struct freq_attr _name = \
+#define define_one_ro(_name) \
+static struct freq_attr _name = \
__ATTR(_name, 0444, show_##_name, NULL)
define_one_ro(sampling_rate_max);
@@ -174,7 +228,8 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused,
{
unsigned int input;
int ret;
- ret = sscanf (buf, "%u", &input);
+ ret = sscanf(buf, "%u", &input);
+
if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1)
return -EINVAL;
@@ -190,15 +245,13 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
{
unsigned int input;
int ret;
- ret = sscanf (buf, "%u", &input);
+ ret = sscanf(buf, "%u", &input);
- mutex_lock(&dbs_mutex);
- if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) {
- mutex_unlock(&dbs_mutex);
+ if (ret != 1)
return -EINVAL;
- }
- dbs_tuners_ins.sampling_rate = input;
+ mutex_lock(&dbs_mutex);
+ dbs_tuners_ins.sampling_rate = max(input, minimum_sampling_rate());
mutex_unlock(&dbs_mutex);
return count;
@@ -209,10 +262,11 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
{
unsigned int input;
int ret;
- ret = sscanf (buf, "%u", &input);
+ ret = sscanf(buf, "%u", &input);
mutex_lock(&dbs_mutex);
- if (ret != 1 || input > 100 || input <= dbs_tuners_ins.down_threshold) {
+ if (ret != 1 || input > 100 ||
+ input <= dbs_tuners_ins.down_threshold) {
mutex_unlock(&dbs_mutex);
return -EINVAL;
}
@@ -228,10 +282,12 @@ static ssize_t store_down_threshold(struct cpufreq_policy *unused,
{
unsigned int input;
int ret;
- ret = sscanf (buf, "%u", &input);
+ ret = sscanf(buf, "%u", &input);
mutex_lock(&dbs_mutex);
- if (ret != 1 || input > 100 || input >= dbs_tuners_ins.up_threshold) {
+ /* cannot be lower than 11 otherwise freq will not fall */
+ if (ret != 1 || input < 11 || input > 100 ||
+ input >= dbs_tuners_ins.up_threshold) {
mutex_unlock(&dbs_mutex);
return -EINVAL;
}
@@ -264,12 +320,14 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
}
dbs_tuners_ins.ignore_nice = input;
- /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */
+ /* we need to re-evaluate prev_cpu_idle */
for_each_online_cpu(j) {
- struct cpu_dbs_info_s *j_dbs_info;
- j_dbs_info = &per_cpu(cpu_dbs_info, j);
- j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j);
- j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up;
+ struct cpu_dbs_info_s *dbs_info;
+ dbs_info = &per_cpu(cpu_dbs_info, j);
+ dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
+ &dbs_info->prev_cpu_wall);
+ if (dbs_tuners_ins.ignore_nice)
+ dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice;
}
mutex_unlock(&dbs_mutex);
@@ -281,7 +339,6 @@ static ssize_t store_freq_step(struct cpufreq_policy *policy,
{
unsigned int input;
int ret;
-
ret = sscanf(buf, "%u", &input);
if (ret != 1)
@@ -310,7 +367,7 @@ define_one_rw(down_threshold);
define_one_rw(ignore_nice_load);
define_one_rw(freq_step);
-static struct attribute * dbs_attributes[] = {
+static struct attribute *dbs_attributes[] = {
&sampling_rate_max.attr,
&sampling_rate_min.attr,
&sampling_rate.attr,
@@ -329,55 +386,78 @@ static struct attribute_group dbs_attr_group = {
/************************** sysfs end ************************/
-static void dbs_check_cpu(int cpu)
+static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
{
- unsigned int idle_ticks, up_idle_ticks, down_idle_ticks;
- unsigned int tmp_idle_ticks, total_idle_ticks;
+ unsigned int load = 0;
unsigned int freq_target;
- unsigned int freq_down_sampling_rate;
- struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
- struct cpufreq_policy *policy;
- if (!this_dbs_info->enable)
- return;
+ struct cpufreq_policy *policy;
+ unsigned int j;
policy = this_dbs_info->cur_policy;
/*
- * The default safe range is 20% to 80%
- * Every sampling_rate, we check
- * - If current idle time is less than 20%, then we try to
- * increase frequency
- * Every sampling_rate*sampling_down_factor, we check
- * - If current idle time is more than 80%, then we try to
- * decrease frequency
+ * Every sampling_rate, we check, if current idle time is less
+ * than 20% (default), then we try to increase frequency
+ * Every sampling_rate*sampling_down_factor, we check, if current
+ * idle time is more than 80%, then we try to decrease frequency
*
* Any frequency increase takes it to the maximum frequency.
* Frequency reduction happens at minimum steps of
- * 5% (default) of max_frequency
+ * 5% (default) of maximum frequency
*/
- /* Check for frequency increase */
- idle_ticks = UINT_MAX;
+ /* Get Absolute Load */
+ for_each_cpu(j, policy->cpus) {
+ struct cpu_dbs_info_s *j_dbs_info;
+ cputime64_t cur_wall_time, cur_idle_time;
+ unsigned int idle_time, wall_time;
- /* Check for frequency increase */
- total_idle_ticks = get_cpu_idle_time(cpu);
- tmp_idle_ticks = total_idle_ticks -
- this_dbs_info->prev_cpu_idle_up;
- this_dbs_info->prev_cpu_idle_up = total_idle_ticks;
+ j_dbs_info = &per_cpu(cpu_dbs_info, j);
+
+ cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
+
+ wall_time = (unsigned int) cputime64_sub(cur_wall_time,
+ j_dbs_info->prev_cpu_wall);
+ j_dbs_info->prev_cpu_wall = cur_wall_time;
+
+ idle_time = (unsigned int) cputime64_sub(cur_idle_time,
+ j_dbs_info->prev_cpu_idle);
+ j_dbs_info->prev_cpu_idle = cur_idle_time;
+
+ if (dbs_tuners_ins.ignore_nice) {
+ cputime64_t cur_nice;
+ unsigned long cur_nice_jiffies;
+
+ cur_nice = cputime64_sub(kstat_cpu(j).cpustat.nice,
+ j_dbs_info->prev_cpu_nice);
+ /*
+ * Assumption: nice time between sampling periods will
+ * be less than 2^32 jiffies for 32 bit sys
+ */
+ cur_nice_jiffies = (unsigned long)
+ cputime64_to_jiffies64(cur_nice);
- if (tmp_idle_ticks < idle_ticks)
- idle_ticks = tmp_idle_ticks;
+ j_dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice;
+ idle_time += jiffies_to_usecs(cur_nice_jiffies);
+ }
+
+ if (unlikely(!wall_time || wall_time < idle_time))
+ continue;
+
+ load = 100 * (wall_time - idle_time) / wall_time;
+ }
- /* Scale idle ticks by 100 and compare with up and down ticks */
- idle_ticks *= 100;
- up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) *
- usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+ /*
+ * break out if we 'cannot' reduce the speed as the user might
+ * want freq_step to be zero
+ */
+ if (dbs_tuners_ins.freq_step == 0)
+ return;
- if (idle_ticks < up_idle_ticks) {
+ /* Check for frequency increase */
+ if (load > dbs_tuners_ins.up_threshold) {
this_dbs_info->down_skip = 0;
- this_dbs_info->prev_cpu_idle_down =
- this_dbs_info->prev_cpu_idle_up;
/* if we are already at full speed then break out early */
if (this_dbs_info->requested_freq == policy->max)
@@ -398,49 +478,24 @@ static void dbs_check_cpu(int cpu)
return;
}
- /* Check for frequency decrease */
- this_dbs_info->down_skip++;
- if (this_dbs_info->down_skip < dbs_tuners_ins.sampling_down_factor)
- return;
-
- /* Check for frequency decrease */
- total_idle_ticks = this_dbs_info->prev_cpu_idle_up;
- tmp_idle_ticks = total_idle_ticks -
- this_dbs_info->prev_cpu_idle_down;
- this_dbs_info->prev_cpu_idle_down = total_idle_ticks;
-
- if (tmp_idle_ticks < idle_ticks)
- idle_ticks = tmp_idle_ticks;
-
- /* Scale idle ticks by 100 and compare with up and down ticks */
- idle_ticks *= 100;
- this_dbs_info->down_skip = 0;
-
- freq_down_sampling_rate = dbs_tuners_ins.sampling_rate *
- dbs_tuners_ins.sampling_down_factor;
- down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) *
- usecs_to_jiffies(freq_down_sampling_rate);
-
- if (idle_ticks > down_idle_ticks) {
- /*
- * if we are already at the lowest speed then break out early
- * or if we 'cannot' reduce the speed as the user might want
- * freq_target to be zero
- */
- if (this_dbs_info->requested_freq == policy->min
- || dbs_tuners_ins.freq_step == 0)
- return;
-
+ /*
+ * The optimal frequency is the frequency that is the lowest that
+ * can support the current CPU usage without triggering the up
+ * policy. To be safe, we focus 10 points under the threshold.
+ */
+ if (load < (dbs_tuners_ins.down_threshold - 10)) {
freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100;
- /* max freq cannot be less than 100. But who knows.... */
- if (unlikely(freq_target == 0))
- freq_target = 5;
-
this_dbs_info->requested_freq -= freq_target;
if (this_dbs_info->requested_freq < policy->min)
this_dbs_info->requested_freq = policy->min;
+ /*
+ * if we cannot reduce the frequency anymore, break out early
+ */
+ if (policy->cur == policy->min)
+ return;
+
__cpufreq_driver_target(policy, this_dbs_info->requested_freq,
CPUFREQ_RELATION_H);
return;
@@ -449,27 +504,45 @@ static void dbs_check_cpu(int cpu)
static void do_dbs_timer(struct work_struct *work)
{
- int i;
- mutex_lock(&dbs_mutex);
- for_each_online_cpu(i)
- dbs_check_cpu(i);
- schedule_delayed_work(&dbs_work,
- usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
- mutex_unlock(&dbs_mutex);
+ struct cpu_dbs_info_s *dbs_info =
+ container_of(work, struct cpu_dbs_info_s, work.work);
+ unsigned int cpu = dbs_info->cpu;
+
+ /* We want all CPUs to do sampling nearly on same jiffy */
+ int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+
+ delay -= jiffies % delay;
+
+ if (lock_policy_rwsem_write(cpu) < 0)
+ return;
+
+ if (!dbs_info->enable) {
+ unlock_policy_rwsem_write(cpu);
+ return;
+ }
+
+ dbs_check_cpu(dbs_info);
+
+ queue_delayed_work_on(cpu, kconservative_wq, &dbs_info->work, delay);
+ unlock_policy_rwsem_write(cpu);
}
-static inline void dbs_timer_init(void)
+static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
{
- init_timer_deferrable(&dbs_work.timer);
- schedule_delayed_work(&dbs_work,
- usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
- return;
+ /* We want all CPUs to do sampling nearly on same jiffy */
+ int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate);
+ delay -= jiffies % delay;
+
+ dbs_info->enable = 1;
+ INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
+ queue_delayed_work_on(dbs_info->cpu, kconservative_wq, &dbs_info->work,
+ delay);
}
-static inline void dbs_timer_exit(void)
+static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
{
- cancel_delayed_work(&dbs_work);
- return;
+ dbs_info->enable = 0;
+ cancel_delayed_work(&dbs_info->work);
}
static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
@@ -503,11 +576,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
j_dbs_info = &per_cpu(cpu_dbs_info, j);
j_dbs_info->cur_policy = policy;
- j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(cpu);
- j_dbs_info->prev_cpu_idle_down
- = j_dbs_info->prev_cpu_idle_up;
+ j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
+ &j_dbs_info->prev_cpu_wall);
+ if (dbs_tuners_ins.ignore_nice) {
+ j_dbs_info->prev_cpu_nice =
+ kstat_cpu(j).cpustat.nice;
+ }
}
- this_dbs_info->enable = 1;
this_dbs_info->down_skip = 0;
this_dbs_info->requested_freq = policy->cur;
@@ -523,38 +598,36 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
if (latency == 0)
latency = 1;
- def_sampling_rate = 10 * latency *
- DEF_SAMPLING_RATE_LATENCY_MULTIPLIER;
-
- if (def_sampling_rate < MIN_STAT_SAMPLING_RATE)
- def_sampling_rate = MIN_STAT_SAMPLING_RATE;
+ def_sampling_rate =
+ max(latency * LATENCY_MULTIPLIER,
+ MIN_STAT_SAMPLING_RATE);
dbs_tuners_ins.sampling_rate = def_sampling_rate;
- dbs_timer_init();
cpufreq_register_notifier(
&dbs_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
}
+ dbs_timer_init(this_dbs_info);
mutex_unlock(&dbs_mutex);
+
break;
case CPUFREQ_GOV_STOP:
mutex_lock(&dbs_mutex);
- this_dbs_info->enable = 0;
+ dbs_timer_exit(this_dbs_info);
sysfs_remove_group(&policy->kobj, &dbs_attr_group);
dbs_enable--;
+
/*
* Stop the timerschedule work, when this governor
* is used for first time
*/
- if (dbs_enable == 0) {
- dbs_timer_exit();
+ if (dbs_enable == 0)
cpufreq_unregister_notifier(
&dbs_cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
- }
mutex_unlock(&dbs_mutex);
@@ -571,6 +644,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
this_dbs_info->cur_policy,
policy->min, CPUFREQ_RELATION_L);
mutex_unlock(&dbs_mutex);
+
break;
}
return 0;
@@ -588,23 +662,33 @@ struct cpufreq_governor cpufreq_gov_conservative = {
static int __init cpufreq_gov_dbs_init(void)
{
- return cpufreq_register_governor(&cpufreq_gov_conservative);
+ int err;
+
+ kconservative_wq = create_workqueue("kconservative");
+ if (!kconservative_wq) {
+ printk(KERN_ERR "Creation of kconservative failed\n");
+ return -EFAULT;
+ }
+
+ err = cpufreq_register_governor(&cpufreq_gov_conservative);
+ if (err)
+ destroy_workqueue(kconservative_wq);
+
+ return err;
}
static void __exit cpufreq_gov_dbs_exit(void)
{
- /* Make sure that the scheduled work is indeed not running */
- flush_scheduled_work();
-
cpufreq_unregister_governor(&cpufreq_gov_conservative);
+ destroy_workqueue(kconservative_wq);
}
-MODULE_AUTHOR ("Alexander Clouter <alex-kernel@digriz.org.uk>");
-MODULE_DESCRIPTION ("'cpufreq_conservative' - A dynamic cpufreq governor for "
+MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
+MODULE_DESCRIPTION("'cpufreq_conservative' - A dynamic cpufreq governor for "
"Low Latency Frequency Transition capable processors "
"optimised for use in a battery environment");
-MODULE_LICENSE ("GPL");
+MODULE_LICENSE("GPL");
#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
fs_initcall(cpufreq_gov_dbs_init);
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 6f45b1658a67..338f428a15b7 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -21,6 +21,7 @@
#include <linux/hrtimer.h>
#include <linux/tick.h>
#include <linux/ktime.h>
+#include <linux/sched.h>
/*
* dbs is used in this file as a shortform for demandbased switching
@@ -51,8 +52,20 @@ static unsigned int def_sampling_rate;
(MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
#define MIN_SAMPLING_RATE \
(def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
+/* Above MIN_SAMPLING_RATE will vanish with its sysfs file soon
+ * Define the minimal settable sampling rate to the greater of:
+ * - "HW transition latency" * 100 (same as default sampling / 10)
+ * - MIN_STAT_SAMPLING_RATE
+ * To avoid that userspace shoots itself.
+*/
+static unsigned int minimum_sampling_rate(void)
+{
+ return max(def_sampling_rate / 10, MIN_STAT_SAMPLING_RATE);
+}
+
+/* This will also vanish soon with removing sampling_rate_max */
#define MAX_SAMPLING_RATE (500 * def_sampling_rate)
-#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000)
+#define LATENCY_MULTIPLIER (1000)
#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000)
static void do_dbs_timer(struct work_struct *work);
@@ -65,14 +78,14 @@ struct cpu_dbs_info_s {
cputime64_t prev_cpu_wall;
cputime64_t prev_cpu_nice;
struct cpufreq_policy *cur_policy;
- struct delayed_work work;
+ struct delayed_work work;
struct cpufreq_frequency_table *freq_table;
unsigned int freq_lo;
unsigned int freq_lo_jiffies;
unsigned int freq_hi_jiffies;
int cpu;
unsigned int enable:1,
- sample_type:1;
+ sample_type:1;
};
static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
@@ -203,12 +216,28 @@ static void ondemand_powersave_bias_init(void)
/************************** sysfs interface ************************/
static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
{
- return sprintf (buf, "%u\n", MAX_SAMPLING_RATE);
+ static int print_once;
+
+ if (!print_once) {
+ printk(KERN_INFO "CPUFREQ: ondemand sampling_rate_max "
+ "sysfs file is deprecated - used by: %s\n",
+ current->comm);
+ print_once = 1;
+ }
+ return sprintf(buf, "%u\n", MAX_SAMPLING_RATE);
}
static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
{
- return sprintf (buf, "%u\n", MIN_SAMPLING_RATE);
+ static int print_once;
+
+ if (!print_once) {
+ printk(KERN_INFO "CPUFREQ: ondemand sampling_rate_min "
+ "sysfs file is deprecated - used by: %s\n",
+ current->comm);
+ print_once = 1;
+ }
+ return sprintf(buf, "%u\n", MIN_SAMPLING_RATE);
}
#define define_one_ro(_name) \
@@ -238,13 +267,11 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
ret = sscanf(buf, "%u", &input);
mutex_lock(&dbs_mutex);
- if (ret != 1 || input > MAX_SAMPLING_RATE
- || input < MIN_SAMPLING_RATE) {
+ if (ret != 1) {
mutex_unlock(&dbs_mutex);
return -EINVAL;
}
-
- dbs_tuners_ins.sampling_rate = input;
+ dbs_tuners_ins.sampling_rate = max(input, minimum_sampling_rate());
mutex_unlock(&dbs_mutex);
return count;
@@ -279,14 +306,14 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
unsigned int j;
ret = sscanf(buf, "%u", &input);
- if ( ret != 1 )
+ if (ret != 1)
return -EINVAL;
- if ( input > 1 )
+ if (input > 1)
input = 1;
mutex_lock(&dbs_mutex);
- if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */
+ if (input == dbs_tuners_ins.ignore_nice) { /* nothing to do */
mutex_unlock(&dbs_mutex);
return count;
}
@@ -337,7 +364,7 @@ define_one_rw(up_threshold);
define_one_rw(ignore_nice_load);
define_one_rw(powersave_bias);
-static struct attribute * dbs_attributes[] = {
+static struct attribute *dbs_attributes[] = {
&sampling_rate_max.attr,
&sampling_rate_min.attr,
&sampling_rate.attr,
@@ -512,8 +539,7 @@ static void do_dbs_timer(struct work_struct *work)
}
} else {
__cpufreq_driver_target(dbs_info->cur_policy,
- dbs_info->freq_lo,
- CPUFREQ_RELATION_H);
+ dbs_info->freq_lo, CPUFREQ_RELATION_H);
}
queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay);
unlock_policy_rwsem_write(cpu);
@@ -530,7 +556,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
dbs_info->sample_type = DBS_NORMAL_SAMPLE;
INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work,
- delay);
+ delay);
}
static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info)
@@ -591,11 +617,9 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
if (latency == 0)
latency = 1;
- def_sampling_rate = latency *
- DEF_SAMPLING_RATE_LATENCY_MULTIPLIER;
-
- if (def_sampling_rate < MIN_STAT_SAMPLING_RATE)
- def_sampling_rate = MIN_STAT_SAMPLING_RATE;
+ def_sampling_rate =
+ max(latency * LATENCY_MULTIPLIER,
+ MIN_STAT_SAMPLING_RATE);
dbs_tuners_ins.sampling_rate = def_sampling_rate;
}
@@ -617,12 +641,10 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
mutex_lock(&dbs_mutex);
if (policy->max < this_dbs_info->cur_policy->cur)
__cpufreq_driver_target(this_dbs_info->cur_policy,
- policy->max,
- CPUFREQ_RELATION_H);
+ policy->max, CPUFREQ_RELATION_H);
else if (policy->min > this_dbs_info->cur_policy->cur)
__cpufreq_driver_target(this_dbs_info->cur_policy,
- policy->min,
- CPUFREQ_RELATION_L);
+ policy->min, CPUFREQ_RELATION_L);
mutex_unlock(&dbs_mutex);
break;
}
@@ -677,7 +699,7 @@ static void __exit cpufreq_gov_dbs_exit(void)
MODULE_AUTHOR("Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>");
MODULE_AUTHOR("Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>");
MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for "
- "Low Latency Frequency Transition capable processors");
+ "Low Latency Frequency Transition capable processors");
MODULE_LICENSE("GPL");
#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index c0ff97d375d7..5a62d678dd19 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -2,7 +2,7 @@
* drivers/cpufreq/cpufreq_stats.c
*
* Copyright (C) 2003-2004 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
- * (C) 2004 Zou Nan hai <nanhai.zou@intel.com>.
+ * (C) 2004 Zou Nan hai <nanhai.zou@intel.com>.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -23,7 +23,7 @@
static spinlock_t cpufreq_stats_lock;
-#define CPUFREQ_STATDEVICE_ATTR(_name,_mode,_show) \
+#define CPUFREQ_STATDEVICE_ATTR(_name, _mode, _show) \
static struct freq_attr _attr_##_name = {\
.attr = {.name = __stringify(_name), .mode = _mode, }, \
.show = _show,\
@@ -50,8 +50,7 @@ struct cpufreq_stats_attribute {
ssize_t(*show) (struct cpufreq_stats *, char *);
};
-static int
-cpufreq_stats_update (unsigned int cpu)
+static int cpufreq_stats_update(unsigned int cpu)
{
struct cpufreq_stats *stat;
unsigned long long cur_time;
@@ -68,8 +67,7 @@ cpufreq_stats_update (unsigned int cpu)
return 0;
}
-static ssize_t
-show_total_trans(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf)
{
struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu);
if (!stat)
@@ -78,8 +76,7 @@ show_total_trans(struct cpufreq_policy *policy, char *buf)
per_cpu(cpufreq_stats_table, stat->cpu)->total_trans);
}
-static ssize_t
-show_time_in_state(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf)
{
ssize_t len = 0;
int i;
@@ -89,14 +86,14 @@ show_time_in_state(struct cpufreq_policy *policy, char *buf)
cpufreq_stats_update(stat->cpu);
for (i = 0; i < stat->state_num; i++) {
len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i],
- (unsigned long long)cputime64_to_clock_t(stat->time_in_state[i]));
+ (unsigned long long)
+ cputime64_to_clock_t(stat->time_in_state[i]));
}
return len;
}
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
-static ssize_t
-show_trans_table(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
{
ssize_t len = 0;
int i, j;
@@ -139,11 +136,11 @@ show_trans_table(struct cpufreq_policy *policy, char *buf)
return PAGE_SIZE;
return len;
}
-CPUFREQ_STATDEVICE_ATTR(trans_table,0444,show_trans_table);
+CPUFREQ_STATDEVICE_ATTR(trans_table, 0444, show_trans_table);
#endif
-CPUFREQ_STATDEVICE_ATTR(total_trans,0444,show_total_trans);
-CPUFREQ_STATDEVICE_ATTR(time_in_state,0444,show_time_in_state);
+CPUFREQ_STATDEVICE_ATTR(total_trans, 0444, show_total_trans);
+CPUFREQ_STATDEVICE_ATTR(time_in_state, 0444, show_time_in_state);
static struct attribute *default_attrs[] = {
&_attr_total_trans.attr,
@@ -158,8 +155,7 @@ static struct attribute_group stats_attr_group = {
.name = "stats"
};
-static int
-freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
+static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq)
{
int index;
for (index = 0; index < stat->max_state; index++)
@@ -183,8 +179,7 @@ static void cpufreq_stats_free_table(unsigned int cpu)
cpufreq_cpu_put(policy);
}
-static int
-cpufreq_stats_create_table (struct cpufreq_policy *policy,
+static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table)
{
unsigned int i, j, count = 0, ret = 0;
@@ -194,7 +189,8 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
unsigned int cpu = policy->cpu;
if (per_cpu(cpufreq_stats_table, cpu))
return -EBUSY;
- if ((stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL)) == NULL)
+ stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL);
+ if ((stat) == NULL)
return -ENOMEM;
data = cpufreq_cpu_get(cpu);
@@ -203,13 +199,14 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
goto error_get_fail;
}
- if ((ret = sysfs_create_group(&data->kobj, &stats_attr_group)))
+ ret = sysfs_create_group(&data->kobj, &stats_attr_group);
+ if (ret)
goto error_out;
stat->cpu = cpu;
per_cpu(cpufreq_stats_table, cpu) = stat;
- for (i=0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
unsigned int freq = table[i].frequency;
if (freq == CPUFREQ_ENTRY_INVALID)
continue;
@@ -255,9 +252,8 @@ error_get_fail:
return ret;
}
-static int
-cpufreq_stat_notifier_policy (struct notifier_block *nb, unsigned long val,
- void *data)
+static int cpufreq_stat_notifier_policy(struct notifier_block *nb,
+ unsigned long val, void *data)
{
int ret;
struct cpufreq_policy *policy = data;
@@ -268,14 +264,14 @@ cpufreq_stat_notifier_policy (struct notifier_block *nb, unsigned long val,
table = cpufreq_frequency_get_table(cpu);
if (!table)
return 0;
- if ((ret = cpufreq_stats_create_table(policy, table)))
+ ret = cpufreq_stats_create_table(policy, table);
+ if (ret)
return ret;
return 0;
}
-static int
-cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val,
- void *data)
+static int cpufreq_stat_notifier_trans(struct notifier_block *nb,
+ unsigned long val, void *data)
{
struct cpufreq_freqs *freq = data;
struct cpufreq_stats *stat;
@@ -340,19 +336,20 @@ static struct notifier_block notifier_trans_block = {
.notifier_call = cpufreq_stat_notifier_trans
};
-static int
-__init cpufreq_stats_init(void)
+static int __init cpufreq_stats_init(void)
{
int ret;
unsigned int cpu;
spin_lock_init(&cpufreq_stats_lock);
- if ((ret = cpufreq_register_notifier(&notifier_policy_block,
- CPUFREQ_POLICY_NOTIFIER)))
+ ret = cpufreq_register_notifier(&notifier_policy_block,
+ CPUFREQ_POLICY_NOTIFIER);
+ if (ret)
return ret;
- if ((ret = cpufreq_register_notifier(&notifier_trans_block,
- CPUFREQ_TRANSITION_NOTIFIER))) {
+ ret = cpufreq_register_notifier(&notifier_trans_block,
+ CPUFREQ_TRANSITION_NOTIFIER);
+ if (ret) {
cpufreq_unregister_notifier(&notifier_policy_block,
CPUFREQ_POLICY_NOTIFIER);
return ret;
@@ -364,8 +361,7 @@ __init cpufreq_stats_init(void)
}
return 0;
}
-static void
-__exit cpufreq_stats_exit(void)
+static void __exit cpufreq_stats_exit(void)
{
unsigned int cpu;
@@ -379,10 +375,10 @@ __exit cpufreq_stats_exit(void)
}
}
-MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>");
-MODULE_DESCRIPTION ("'cpufreq_stats' - A driver to export cpufreq stats "
+MODULE_AUTHOR("Zou Nan hai <nanhai.zou@intel.com>");
+MODULE_DESCRIPTION("'cpufreq_stats' - A driver to export cpufreq stats "
"through sysfs filesystem");
-MODULE_LICENSE ("GPL");
+MODULE_LICENSE("GPL");
module_init(cpufreq_stats_init);
module_exit(cpufreq_stats_exit);
diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c
index 1442bbada053..66d2d1d6c80f 100644
--- a/drivers/cpufreq/cpufreq_userspace.c
+++ b/drivers/cpufreq/cpufreq_userspace.c
@@ -24,9 +24,6 @@
#include <linux/sysfs.h>
#include <linux/mutex.h>
-#include <asm/uaccess.h>
-
-
/**
* A few values needed by the userspace governor
*/
@@ -37,7 +34,7 @@ static DEFINE_PER_CPU(unsigned int, cpu_set_freq); /* CPU freq desired by
userspace */
static DEFINE_PER_CPU(unsigned int, cpu_is_managed);
-static DEFINE_MUTEX (userspace_mutex);
+static DEFINE_MUTEX(userspace_mutex);
static int cpus_using_userspace_governor;
#define dprintk(msg...) \
@@ -46,9 +43,9 @@ static int cpus_using_userspace_governor;
/* keep track of frequency transitions */
static int
userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
- void *data)
+ void *data)
{
- struct cpufreq_freqs *freq = data;
+ struct cpufreq_freqs *freq = data;
if (!per_cpu(cpu_is_managed, freq->cpu))
return 0;
@@ -57,11 +54,11 @@ userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
freq->cpu, freq->new);
per_cpu(cpu_cur_freq, freq->cpu) = freq->new;
- return 0;
+ return 0;
}
static struct notifier_block userspace_cpufreq_notifier_block = {
- .notifier_call = userspace_cpufreq_notifier
+ .notifier_call = userspace_cpufreq_notifier
};
@@ -93,8 +90,11 @@ static int cpufreq_set(struct cpufreq_policy *policy, unsigned int freq)
* We're safe from concurrent calls to ->target() here
* as we hold the userspace_mutex lock. If we were calling
* cpufreq_driver_target, a deadlock situation might occur:
- * A: cpufreq_set (lock userspace_mutex) -> cpufreq_driver_target(lock policy->lock)
- * B: cpufreq_set_policy(lock policy->lock) -> __cpufreq_governor -> cpufreq_governor_userspace (lock userspace_mutex)
+ * A: cpufreq_set (lock userspace_mutex) ->
+ * cpufreq_driver_target(lock policy->lock)
+ * B: cpufreq_set_policy(lock policy->lock) ->
+ * __cpufreq_governor ->
+ * cpufreq_governor_userspace (lock userspace_mutex)
*/
ret = __cpufreq_driver_target(policy, freq, CPUFREQ_RELATION_L);
@@ -210,9 +210,10 @@ static void __exit cpufreq_gov_userspace_exit(void)
}
-MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>, Russell King <rmk@arm.linux.org.uk>");
-MODULE_DESCRIPTION ("CPUfreq policy governor 'userspace'");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>, "
+ "Russell King <rmk@arm.linux.org.uk>");
+MODULE_DESCRIPTION("CPUfreq policy governor 'userspace'");
+MODULE_LICENSE("GPL");
#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE
fs_initcall(cpufreq_gov_userspace_init);
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index 9071d80fbba2..a9bd3a05a684 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -28,7 +28,7 @@ int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
unsigned int max_freq = 0;
unsigned int i;
- for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
unsigned int freq = table[i].frequency;
if (freq == CPUFREQ_ENTRY_INVALID) {
dprintk("table entry %u is invalid, skipping\n", i);
@@ -70,7 +70,7 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
policy->cpuinfo.max_freq);
- for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
unsigned int freq = table[i].frequency;
if (freq == CPUFREQ_ENTRY_INVALID)
continue;
@@ -125,13 +125,13 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
if (!cpu_online(policy->cpu))
return -EINVAL;
- for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
unsigned int freq = table[i].frequency;
if (freq == CPUFREQ_ENTRY_INVALID)
continue;
if ((freq < policy->min) || (freq > policy->max))
continue;
- switch(relation) {
+ switch (relation) {
case CPUFREQ_RELATION_H:
if (freq <= target_freq) {
if (freq >= optimal.frequency) {
@@ -178,7 +178,7 @@ static DEFINE_PER_CPU(struct cpufreq_frequency_table *, show_table);
/**
* show_available_freqs - show available frequencies for the specified CPU
*/
-static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf)
+static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf)
{
unsigned int i = 0;
unsigned int cpu = policy->cpu;
@@ -190,7 +190,7 @@ static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf)
table = per_cpu(show_table, cpu);
- for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
+ for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
continue;
count += sprintf(&buf[count], "%d ", table[i].frequency);
@@ -234,6 +234,6 @@ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
-MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION ("CPUfreq frequency table helpers");
-MODULE_LICENSE ("GPL");
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("CPUfreq frequency table helpers");
+MODULE_LICENSE("GPL");
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index e522144cba3a..01afd758072f 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -86,7 +86,7 @@ config ZCRYPT_MONOLITHIC
config CRYPTO_SHA1_S390
tristate "SHA1 digest algorithm"
depends on S390
- select CRYPTO_ALGAPI
+ select CRYPTO_HASH
help
This is the s390 hardware accelerated implementation of the
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
@@ -94,7 +94,7 @@ config CRYPTO_SHA1_S390
config CRYPTO_SHA256_S390
tristate "SHA256 digest algorithm"
depends on S390
- select CRYPTO_ALGAPI
+ select CRYPTO_HASH
help
This is the s390 hardware accelerated implementation of the
SHA256 secure hash standard (DFIPS 180-2).
@@ -105,7 +105,7 @@ config CRYPTO_SHA256_S390
config CRYPTO_SHA512_S390
tristate "SHA384 and SHA512 digest algorithm"
depends on S390
- select CRYPTO_ALGAPI
+ select CRYPTO_HASH
help
This is the s390 hardware accelerated implementation of the
SHA512 secure hash standard.
@@ -200,4 +200,13 @@ config CRYPTO_DEV_IXP4XX
help
Driver for the IXP4xx NPE crypto engine.
+config CRYPTO_DEV_PPC4XX
+ tristate "Driver AMCC PPC4xx crypto accelerator"
+ depends on PPC && 4xx
+ select CRYPTO_HASH
+ select CRYPTO_ALGAPI
+ select CRYPTO_BLKCIPHER
+ help
+ This option allows you to have support for AMCC crypto acceleration.
+
endif # CRYPTO_HW
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 73557b2968d3..9bf4a2bc8846 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o
obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o
obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
+obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
diff --git a/drivers/crypto/amcc/Makefile b/drivers/crypto/amcc/Makefile
new file mode 100644
index 000000000000..aa376e8d5ed5
--- /dev/null
+++ b/drivers/crypto/amcc/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += crypto4xx.o
+crypto4xx-objs := crypto4xx_core.o crypto4xx_alg.o crypto4xx_sa.o
diff --git a/drivers/crypto/amcc/crypto4xx_alg.c b/drivers/crypto/amcc/crypto4xx_alg.c
new file mode 100644
index 000000000000..61b6e1bec8c6
--- /dev/null
+++ b/drivers/crypto/amcc/crypto4xx_alg.c
@@ -0,0 +1,293 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This file implements the Linux crypto algorithms.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock_types.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+#include <linux/hash.h>
+#include <crypto/internal/hash.h>
+#include <linux/dma-mapping.h>
+#include <crypto/algapi.h>
+#include <crypto/aes.h>
+#include <crypto/sha.h>
+#include "crypto4xx_reg_def.h"
+#include "crypto4xx_sa.h"
+#include "crypto4xx_core.h"
+
+void set_dynamic_sa_command_0(struct dynamic_sa_ctl *sa, u32 save_h,
+ u32 save_iv, u32 ld_h, u32 ld_iv, u32 hdr_proc,
+ u32 h, u32 c, u32 pad_type, u32 op_grp, u32 op,
+ u32 dir)
+{
+ sa->sa_command_0.w = 0;
+ sa->sa_command_0.bf.save_hash_state = save_h;
+ sa->sa_command_0.bf.save_iv = save_iv;
+ sa->sa_command_0.bf.load_hash_state = ld_h;
+ sa->sa_command_0.bf.load_iv = ld_iv;
+ sa->sa_command_0.bf.hdr_proc = hdr_proc;
+ sa->sa_command_0.bf.hash_alg = h;
+ sa->sa_command_0.bf.cipher_alg = c;
+ sa->sa_command_0.bf.pad_type = pad_type & 3;
+ sa->sa_command_0.bf.extend_pad = pad_type >> 2;
+ sa->sa_command_0.bf.op_group = op_grp;
+ sa->sa_command_0.bf.opcode = op;
+ sa->sa_command_0.bf.dir = dir;
+}
+
+void set_dynamic_sa_command_1(struct dynamic_sa_ctl *sa, u32 cm, u32 hmac_mc,
+ u32 cfb, u32 esn, u32 sn_mask, u32 mute,
+ u32 cp_pad, u32 cp_pay, u32 cp_hdr)
+{
+ sa->sa_command_1.w = 0;
+ sa->sa_command_1.bf.crypto_mode31 = (cm & 4) >> 2;
+ sa->sa_command_1.bf.crypto_mode9_8 = cm & 3;
+ sa->sa_command_1.bf.feedback_mode = cfb,
+ sa->sa_command_1.bf.sa_rev = 1;
+ sa->sa_command_1.bf.extended_seq_num = esn;
+ sa->sa_command_1.bf.seq_num_mask = sn_mask;
+ sa->sa_command_1.bf.mutable_bit_proc = mute;
+ sa->sa_command_1.bf.copy_pad = cp_pad;
+ sa->sa_command_1.bf.copy_payload = cp_pay;
+ sa->sa_command_1.bf.copy_hdr = cp_hdr;
+}
+
+int crypto4xx_encrypt(struct ablkcipher_request *req)
+{
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+
+ ctx->direction = DIR_OUTBOUND;
+ ctx->hash_final = 0;
+ ctx->is_hash = 0;
+ ctx->pd_ctl = 0x1;
+
+ return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
+ req->nbytes, req->info,
+ get_dynamic_sa_iv_size(ctx));
+}
+
+int crypto4xx_decrypt(struct ablkcipher_request *req)
+{
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+
+ ctx->direction = DIR_INBOUND;
+ ctx->hash_final = 0;
+ ctx->is_hash = 0;
+ ctx->pd_ctl = 1;
+
+ return crypto4xx_build_pd(&req->base, ctx, req->src, req->dst,
+ req->nbytes, req->info,
+ get_dynamic_sa_iv_size(ctx));
+}
+
+/**
+ * AES Functions
+ */
+static int crypto4xx_setkey_aes(struct crypto_ablkcipher *cipher,
+ const u8 *key,
+ unsigned int keylen,
+ unsigned char cm,
+ u8 fb)
+{
+ struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct dynamic_sa_ctl *sa;
+ int rc;
+
+ if (keylen != AES_KEYSIZE_256 &&
+ keylen != AES_KEYSIZE_192 && keylen != AES_KEYSIZE_128) {
+ crypto_ablkcipher_set_flags(cipher,
+ CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+ }
+
+ /* Create SA */
+ if (ctx->sa_in_dma_addr || ctx->sa_out_dma_addr)
+ crypto4xx_free_sa(ctx);
+
+ rc = crypto4xx_alloc_sa(ctx, SA_AES128_LEN + (keylen-16) / 4);
+ if (rc)
+ return rc;
+
+ if (ctx->state_record_dma_addr == 0) {
+ rc = crypto4xx_alloc_state_record(ctx);
+ if (rc) {
+ crypto4xx_free_sa(ctx);
+ return rc;
+ }
+ }
+ /* Setup SA */
+ sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+ ctx->hash_final = 0;
+
+ set_dynamic_sa_command_0(sa, SA_NOT_SAVE_HASH, SA_NOT_SAVE_IV,
+ SA_LOAD_HASH_FROM_SA, SA_LOAD_IV_FROM_STATE,
+ SA_NO_HEADER_PROC, SA_HASH_ALG_NULL,
+ SA_CIPHER_ALG_AES, SA_PAD_TYPE_ZERO,
+ SA_OP_GROUP_BASIC, SA_OPCODE_DECRYPT,
+ DIR_INBOUND);
+
+ set_dynamic_sa_command_1(sa, cm, SA_HASH_MODE_HASH,
+ fb, SA_EXTENDED_SN_OFF,
+ SA_SEQ_MASK_OFF, SA_MC_ENABLE,
+ SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD,
+ SA_NOT_COPY_HDR);
+ crypto4xx_memcpy_le(ctx->sa_in + get_dynamic_sa_offset_key_field(ctx),
+ key, keylen);
+ sa->sa_contents = SA_AES_CONTENTS | (keylen << 2);
+ sa->sa_command_1.bf.key_len = keylen >> 3;
+ ctx->is_hash = 0;
+ ctx->direction = DIR_INBOUND;
+ memcpy(ctx->sa_in + get_dynamic_sa_offset_state_ptr_field(ctx),
+ (void *)&ctx->state_record_dma_addr, 4);
+ ctx->offset_to_sr_ptr = get_dynamic_sa_offset_state_ptr_field(ctx);
+
+ memcpy(ctx->sa_out, ctx->sa_in, ctx->sa_len * 4);
+ sa = (struct dynamic_sa_ctl *) ctx->sa_out;
+ sa->sa_command_0.bf.dir = DIR_OUTBOUND;
+
+ return 0;
+}
+
+int crypto4xx_setkey_aes_cbc(struct crypto_ablkcipher *cipher,
+ const u8 *key, unsigned int keylen)
+{
+ return crypto4xx_setkey_aes(cipher, key, keylen, CRYPTO_MODE_CBC,
+ CRYPTO_FEEDBACK_MODE_NO_FB);
+}
+
+/**
+ * HASH SHA1 Functions
+ */
+static int crypto4xx_hash_alg_init(struct crypto_tfm *tfm,
+ unsigned int sa_len,
+ unsigned char ha,
+ unsigned char hm)
+{
+ struct crypto_alg *alg = tfm->__crt_alg;
+ struct crypto4xx_alg *my_alg = crypto_alg_to_crypto4xx_alg(alg);
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct dynamic_sa_ctl *sa;
+ struct dynamic_sa_hash160 *sa_in;
+ int rc;
+
+ ctx->dev = my_alg->dev;
+ ctx->is_hash = 1;
+ ctx->hash_final = 0;
+
+ /* Create SA */
+ if (ctx->sa_in_dma_addr || ctx->sa_out_dma_addr)
+ crypto4xx_free_sa(ctx);
+
+ rc = crypto4xx_alloc_sa(ctx, sa_len);
+ if (rc)
+ return rc;
+
+ if (ctx->state_record_dma_addr == 0) {
+ crypto4xx_alloc_state_record(ctx);
+ if (!ctx->state_record_dma_addr) {
+ crypto4xx_free_sa(ctx);
+ return -ENOMEM;
+ }
+ }
+
+ tfm->crt_ahash.reqsize = sizeof(struct crypto4xx_ctx);
+ sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+ set_dynamic_sa_command_0(sa, SA_SAVE_HASH, SA_NOT_SAVE_IV,
+ SA_NOT_LOAD_HASH, SA_LOAD_IV_FROM_SA,
+ SA_NO_HEADER_PROC, ha, SA_CIPHER_ALG_NULL,
+ SA_PAD_TYPE_ZERO, SA_OP_GROUP_BASIC,
+ SA_OPCODE_HASH, DIR_INBOUND);
+ set_dynamic_sa_command_1(sa, 0, SA_HASH_MODE_HASH,
+ CRYPTO_FEEDBACK_MODE_NO_FB, SA_EXTENDED_SN_OFF,
+ SA_SEQ_MASK_OFF, SA_MC_ENABLE,
+ SA_NOT_COPY_PAD, SA_NOT_COPY_PAYLOAD,
+ SA_NOT_COPY_HDR);
+ ctx->direction = DIR_INBOUND;
+ sa->sa_contents = SA_HASH160_CONTENTS;
+ sa_in = (struct dynamic_sa_hash160 *) ctx->sa_in;
+ /* Need to zero hash digest in SA */
+ memset(sa_in->inner_digest, 0, sizeof(sa_in->inner_digest));
+ memset(sa_in->outer_digest, 0, sizeof(sa_in->outer_digest));
+ sa_in->state_ptr = ctx->state_record_dma_addr;
+ ctx->offset_to_sr_ptr = get_dynamic_sa_offset_state_ptr_field(ctx);
+
+ return 0;
+}
+
+int crypto4xx_hash_init(struct ahash_request *req)
+{
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+ int ds;
+ struct dynamic_sa_ctl *sa;
+
+ sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+ ds = crypto_ahash_digestsize(
+ __crypto_ahash_cast(req->base.tfm));
+ sa->sa_command_0.bf.digest_len = ds >> 2;
+ sa->sa_command_0.bf.load_hash_state = SA_LOAD_HASH_FROM_SA;
+ ctx->is_hash = 1;
+ ctx->direction = DIR_INBOUND;
+
+ return 0;
+}
+
+int crypto4xx_hash_update(struct ahash_request *req)
+{
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+
+ ctx->is_hash = 1;
+ ctx->hash_final = 0;
+ ctx->pd_ctl = 0x11;
+ ctx->direction = DIR_INBOUND;
+
+ return crypto4xx_build_pd(&req->base, ctx, req->src,
+ (struct scatterlist *) req->result,
+ req->nbytes, NULL, 0);
+}
+
+int crypto4xx_hash_final(struct ahash_request *req)
+{
+ return 0;
+}
+
+int crypto4xx_hash_digest(struct ahash_request *req)
+{
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+
+ ctx->hash_final = 1;
+ ctx->pd_ctl = 0x11;
+ ctx->direction = DIR_INBOUND;
+
+ return crypto4xx_build_pd(&req->base, ctx, req->src,
+ (struct scatterlist *) req->result,
+ req->nbytes, NULL, 0);
+}
+
+/**
+ * SHA1 Algorithm
+ */
+int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm)
+{
+ return crypto4xx_hash_alg_init(tfm, SA_HASH160_LEN, SA_HASH_ALG_SHA1,
+ SA_HASH_MODE_HASH);
+}
+
+
diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c
new file mode 100644
index 000000000000..4c0dfb2b872e
--- /dev/null
+++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -0,0 +1,1310 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This file implements AMCC crypto offload Linux device driver for use with
+ * Linux CryptoAPI.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock_types.h>
+#include <linux/random.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <asm/dcr.h>
+#include <asm/dcr-regs.h>
+#include <asm/cacheflush.h>
+#include <crypto/internal/hash.h>
+#include <crypto/algapi.h>
+#include <crypto/aes.h>
+#include <crypto/sha.h>
+#include "crypto4xx_reg_def.h"
+#include "crypto4xx_core.h"
+#include "crypto4xx_sa.h"
+
+#define PPC4XX_SEC_VERSION_STR "0.5"
+
+/**
+ * PPC4xx Crypto Engine Initialization Routine
+ */
+static void crypto4xx_hw_init(struct crypto4xx_device *dev)
+{
+ union ce_ring_size ring_size;
+ union ce_ring_contol ring_ctrl;
+ union ce_part_ring_size part_ring_size;
+ union ce_io_threshold io_threshold;
+ u32 rand_num;
+ union ce_pe_dma_cfg pe_dma_cfg;
+
+ writel(PPC4XX_BYTE_ORDER, dev->ce_base + CRYPTO4XX_BYTE_ORDER_CFG);
+ /* setup pe dma, include reset sg, pdr and pe, then release reset */
+ pe_dma_cfg.w = 0;
+ pe_dma_cfg.bf.bo_sgpd_en = 1;
+ pe_dma_cfg.bf.bo_data_en = 0;
+ pe_dma_cfg.bf.bo_sa_en = 1;
+ pe_dma_cfg.bf.bo_pd_en = 1;
+ pe_dma_cfg.bf.dynamic_sa_en = 1;
+ pe_dma_cfg.bf.reset_sg = 1;
+ pe_dma_cfg.bf.reset_pdr = 1;
+ pe_dma_cfg.bf.reset_pe = 1;
+ writel(pe_dma_cfg.w, dev->ce_base + CRYPTO4XX_PE_DMA_CFG);
+ /* un reset pe,sg and pdr */
+ pe_dma_cfg.bf.pe_mode = 0;
+ pe_dma_cfg.bf.reset_sg = 0;
+ pe_dma_cfg.bf.reset_pdr = 0;
+ pe_dma_cfg.bf.reset_pe = 0;
+ pe_dma_cfg.bf.bo_td_en = 0;
+ writel(pe_dma_cfg.w, dev->ce_base + CRYPTO4XX_PE_DMA_CFG);
+ writel(dev->pdr_pa, dev->ce_base + CRYPTO4XX_PDR_BASE);
+ writel(dev->pdr_pa, dev->ce_base + CRYPTO4XX_RDR_BASE);
+ writel(PPC4XX_PRNG_CTRL_AUTO_EN, dev->ce_base + CRYPTO4XX_PRNG_CTRL);
+ get_random_bytes(&rand_num, sizeof(rand_num));
+ writel(rand_num, dev->ce_base + CRYPTO4XX_PRNG_SEED_L);
+ get_random_bytes(&rand_num, sizeof(rand_num));
+ writel(rand_num, dev->ce_base + CRYPTO4XX_PRNG_SEED_H);
+ ring_size.w = 0;
+ ring_size.bf.ring_offset = PPC4XX_PD_SIZE;
+ ring_size.bf.ring_size = PPC4XX_NUM_PD;
+ writel(ring_size.w, dev->ce_base + CRYPTO4XX_RING_SIZE);
+ ring_ctrl.w = 0;
+ writel(ring_ctrl.w, dev->ce_base + CRYPTO4XX_RING_CTRL);
+ writel(PPC4XX_DC_3DES_EN, dev->ce_base + CRYPTO4XX_DEVICE_CTRL);
+ writel(dev->gdr_pa, dev->ce_base + CRYPTO4XX_GATH_RING_BASE);
+ writel(dev->sdr_pa, dev->ce_base + CRYPTO4XX_SCAT_RING_BASE);
+ part_ring_size.w = 0;
+ part_ring_size.bf.sdr_size = PPC4XX_SDR_SIZE;
+ part_ring_size.bf.gdr_size = PPC4XX_GDR_SIZE;
+ writel(part_ring_size.w, dev->ce_base + CRYPTO4XX_PART_RING_SIZE);
+ writel(PPC4XX_SD_BUFFER_SIZE, dev->ce_base + CRYPTO4XX_PART_RING_CFG);
+ io_threshold.w = 0;
+ io_threshold.bf.output_threshold = PPC4XX_OUTPUT_THRESHOLD;
+ io_threshold.bf.input_threshold = PPC4XX_INPUT_THRESHOLD;
+ writel(io_threshold.w, dev->ce_base + CRYPTO4XX_IO_THRESHOLD);
+ writel(0, dev->ce_base + CRYPTO4XX_PDR_BASE_UADDR);
+ writel(0, dev->ce_base + CRYPTO4XX_RDR_BASE_UADDR);
+ writel(0, dev->ce_base + CRYPTO4XX_PKT_SRC_UADDR);
+ writel(0, dev->ce_base + CRYPTO4XX_PKT_DEST_UADDR);
+ writel(0, dev->ce_base + CRYPTO4XX_SA_UADDR);
+ writel(0, dev->ce_base + CRYPTO4XX_GATH_RING_BASE_UADDR);
+ writel(0, dev->ce_base + CRYPTO4XX_SCAT_RING_BASE_UADDR);
+ /* un reset pe,sg and pdr */
+ pe_dma_cfg.bf.pe_mode = 1;
+ pe_dma_cfg.bf.reset_sg = 0;
+ pe_dma_cfg.bf.reset_pdr = 0;
+ pe_dma_cfg.bf.reset_pe = 0;
+ pe_dma_cfg.bf.bo_td_en = 0;
+ writel(pe_dma_cfg.w, dev->ce_base + CRYPTO4XX_PE_DMA_CFG);
+ /*clear all pending interrupt*/
+ writel(PPC4XX_INTERRUPT_CLR, dev->ce_base + CRYPTO4XX_INT_CLR);
+ writel(PPC4XX_INT_DESCR_CNT, dev->ce_base + CRYPTO4XX_INT_DESCR_CNT);
+ writel(PPC4XX_INT_DESCR_CNT, dev->ce_base + CRYPTO4XX_INT_DESCR_CNT);
+ writel(PPC4XX_INT_CFG, dev->ce_base + CRYPTO4XX_INT_CFG);
+ writel(PPC4XX_PD_DONE_INT, dev->ce_base + CRYPTO4XX_INT_EN);
+}
+
+int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size)
+{
+ ctx->sa_in = dma_alloc_coherent(ctx->dev->core_dev->device, size * 4,
+ &ctx->sa_in_dma_addr, GFP_ATOMIC);
+ if (ctx->sa_in == NULL)
+ return -ENOMEM;
+
+ ctx->sa_out = dma_alloc_coherent(ctx->dev->core_dev->device, size * 4,
+ &ctx->sa_out_dma_addr, GFP_ATOMIC);
+ if (ctx->sa_out == NULL) {
+ dma_free_coherent(ctx->dev->core_dev->device,
+ ctx->sa_len * 4,
+ ctx->sa_in, ctx->sa_in_dma_addr);
+ return -ENOMEM;
+ }
+
+ memset(ctx->sa_in, 0, size * 4);
+ memset(ctx->sa_out, 0, size * 4);
+ ctx->sa_len = size;
+
+ return 0;
+}
+
+void crypto4xx_free_sa(struct crypto4xx_ctx *ctx)
+{
+ if (ctx->sa_in != NULL)
+ dma_free_coherent(ctx->dev->core_dev->device, ctx->sa_len * 4,
+ ctx->sa_in, ctx->sa_in_dma_addr);
+ if (ctx->sa_out != NULL)
+ dma_free_coherent(ctx->dev->core_dev->device, ctx->sa_len * 4,
+ ctx->sa_out, ctx->sa_out_dma_addr);
+
+ ctx->sa_in_dma_addr = 0;
+ ctx->sa_out_dma_addr = 0;
+ ctx->sa_len = 0;
+}
+
+u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx)
+{
+ ctx->state_record = dma_alloc_coherent(ctx->dev->core_dev->device,
+ sizeof(struct sa_state_record),
+ &ctx->state_record_dma_addr, GFP_ATOMIC);
+ if (!ctx->state_record_dma_addr)
+ return -ENOMEM;
+ memset(ctx->state_record, 0, sizeof(struct sa_state_record));
+
+ return 0;
+}
+
+void crypto4xx_free_state_record(struct crypto4xx_ctx *ctx)
+{
+ if (ctx->state_record != NULL)
+ dma_free_coherent(ctx->dev->core_dev->device,
+ sizeof(struct sa_state_record),
+ ctx->state_record,
+ ctx->state_record_dma_addr);
+ ctx->state_record_dma_addr = 0;
+}
+
+/**
+ * alloc memory for the gather ring
+ * no need to alloc buf for the ring
+ * gdr_tail, gdr_head and gdr_count are initialized by this function
+ */
+static u32 crypto4xx_build_pdr(struct crypto4xx_device *dev)
+{
+ int i;
+ struct pd_uinfo *pd_uinfo;
+ dev->pdr = dma_alloc_coherent(dev->core_dev->device,
+ sizeof(struct ce_pd) * PPC4XX_NUM_PD,
+ &dev->pdr_pa, GFP_ATOMIC);
+ if (!dev->pdr)
+ return -ENOMEM;
+
+ dev->pdr_uinfo = kzalloc(sizeof(struct pd_uinfo) * PPC4XX_NUM_PD,
+ GFP_KERNEL);
+ if (!dev->pdr_uinfo) {
+ dma_free_coherent(dev->core_dev->device,
+ sizeof(struct ce_pd) * PPC4XX_NUM_PD,
+ dev->pdr,
+ dev->pdr_pa);
+ return -ENOMEM;
+ }
+ memset(dev->pdr, 0, sizeof(struct ce_pd) * PPC4XX_NUM_PD);
+ dev->shadow_sa_pool = dma_alloc_coherent(dev->core_dev->device,
+ 256 * PPC4XX_NUM_PD,
+ &dev->shadow_sa_pool_pa,
+ GFP_ATOMIC);
+ if (!dev->shadow_sa_pool)
+ return -ENOMEM;
+
+ dev->shadow_sr_pool = dma_alloc_coherent(dev->core_dev->device,
+ sizeof(struct sa_state_record) * PPC4XX_NUM_PD,
+ &dev->shadow_sr_pool_pa, GFP_ATOMIC);
+ if (!dev->shadow_sr_pool)
+ return -ENOMEM;
+ for (i = 0; i < PPC4XX_NUM_PD; i++) {
+ pd_uinfo = (struct pd_uinfo *) (dev->pdr_uinfo +
+ sizeof(struct pd_uinfo) * i);
+
+ /* alloc 256 bytes which is enough for any kind of dynamic sa */
+ pd_uinfo->sa_va = dev->shadow_sa_pool + 256 * i;
+ pd_uinfo->sa_pa = dev->shadow_sa_pool_pa + 256 * i;
+
+ /* alloc state record */
+ pd_uinfo->sr_va = dev->shadow_sr_pool +
+ sizeof(struct sa_state_record) * i;
+ pd_uinfo->sr_pa = dev->shadow_sr_pool_pa +
+ sizeof(struct sa_state_record) * i;
+ }
+
+ return 0;
+}
+
+static void crypto4xx_destroy_pdr(struct crypto4xx_device *dev)
+{
+ if (dev->pdr != NULL)
+ dma_free_coherent(dev->core_dev->device,
+ sizeof(struct ce_pd) * PPC4XX_NUM_PD,
+ dev->pdr, dev->pdr_pa);
+ if (dev->shadow_sa_pool)
+ dma_free_coherent(dev->core_dev->device, 256 * PPC4XX_NUM_PD,
+ dev->shadow_sa_pool, dev->shadow_sa_pool_pa);
+ if (dev->shadow_sr_pool)
+ dma_free_coherent(dev->core_dev->device,
+ sizeof(struct sa_state_record) * PPC4XX_NUM_PD,
+ dev->shadow_sr_pool, dev->shadow_sr_pool_pa);
+
+ kfree(dev->pdr_uinfo);
+}
+
+static u32 crypto4xx_get_pd_from_pdr_nolock(struct crypto4xx_device *dev)
+{
+ u32 retval;
+ u32 tmp;
+
+ retval = dev->pdr_head;
+ tmp = (dev->pdr_head + 1) % PPC4XX_NUM_PD;
+
+ if (tmp == dev->pdr_tail)
+ return ERING_WAS_FULL;
+
+ dev->pdr_head = tmp;
+
+ return retval;
+}
+
+static u32 crypto4xx_put_pd_to_pdr(struct crypto4xx_device *dev, u32 idx)
+{
+ struct pd_uinfo *pd_uinfo;
+ unsigned long flags;
+
+ pd_uinfo = (struct pd_uinfo *)(dev->pdr_uinfo +
+ sizeof(struct pd_uinfo) * idx);
+ spin_lock_irqsave(&dev->core_dev->lock, flags);
+ if (dev->pdr_tail != PPC4XX_LAST_PD)
+ dev->pdr_tail++;
+ else
+ dev->pdr_tail = 0;
+ pd_uinfo->state = PD_ENTRY_FREE;
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+
+ return 0;
+}
+
+static struct ce_pd *crypto4xx_get_pdp(struct crypto4xx_device *dev,
+ dma_addr_t *pd_dma, u32 idx)
+{
+ *pd_dma = dev->pdr_pa + sizeof(struct ce_pd) * idx;
+
+ return dev->pdr + sizeof(struct ce_pd) * idx;
+}
+
+/**
+ * alloc memory for the gather ring
+ * no need to alloc buf for the ring
+ * gdr_tail, gdr_head and gdr_count are initialized by this function
+ */
+static u32 crypto4xx_build_gdr(struct crypto4xx_device *dev)
+{
+ dev->gdr = dma_alloc_coherent(dev->core_dev->device,
+ sizeof(struct ce_gd) * PPC4XX_NUM_GD,
+ &dev->gdr_pa, GFP_ATOMIC);
+ if (!dev->gdr)
+ return -ENOMEM;
+
+ memset(dev->gdr, 0, sizeof(struct ce_gd) * PPC4XX_NUM_GD);
+
+ return 0;
+}
+
+static inline void crypto4xx_destroy_gdr(struct crypto4xx_device *dev)
+{
+ dma_free_coherent(dev->core_dev->device,
+ sizeof(struct ce_gd) * PPC4XX_NUM_GD,
+ dev->gdr, dev->gdr_pa);
+}
+
+/*
+ * when this function is called.
+ * preemption or interrupt must be disabled
+ */
+u32 crypto4xx_get_n_gd(struct crypto4xx_device *dev, int n)
+{
+ u32 retval;
+ u32 tmp;
+ if (n >= PPC4XX_NUM_GD)
+ return ERING_WAS_FULL;
+
+ retval = dev->gdr_head;
+ tmp = (dev->gdr_head + n) % PPC4XX_NUM_GD;
+ if (dev->gdr_head > dev->gdr_tail) {
+ if (tmp < dev->gdr_head && tmp >= dev->gdr_tail)
+ return ERING_WAS_FULL;
+ } else if (dev->gdr_head < dev->gdr_tail) {
+ if (tmp < dev->gdr_head || tmp >= dev->gdr_tail)
+ return ERING_WAS_FULL;
+ }
+ dev->gdr_head = tmp;
+
+ return retval;
+}
+
+static u32 crypto4xx_put_gd_to_gdr(struct crypto4xx_device *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->core_dev->lock, flags);
+ if (dev->gdr_tail == dev->gdr_head) {
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+ return 0;
+ }
+
+ if (dev->gdr_tail != PPC4XX_LAST_GD)
+ dev->gdr_tail++;
+ else
+ dev->gdr_tail = 0;
+
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+
+ return 0;
+}
+
+static inline struct ce_gd *crypto4xx_get_gdp(struct crypto4xx_device *dev,
+ dma_addr_t *gd_dma, u32 idx)
+{
+ *gd_dma = dev->gdr_pa + sizeof(struct ce_gd) * idx;
+
+ return (struct ce_gd *) (dev->gdr + sizeof(struct ce_gd) * idx);
+}
+
+/**
+ * alloc memory for the scatter ring
+ * need to alloc buf for the ring
+ * sdr_tail, sdr_head and sdr_count are initialized by this function
+ */
+static u32 crypto4xx_build_sdr(struct crypto4xx_device *dev)
+{
+ int i;
+ struct ce_sd *sd_array;
+
+ /* alloc memory for scatter descriptor ring */
+ dev->sdr = dma_alloc_coherent(dev->core_dev->device,
+ sizeof(struct ce_sd) * PPC4XX_NUM_SD,
+ &dev->sdr_pa, GFP_ATOMIC);
+ if (!dev->sdr)
+ return -ENOMEM;
+
+ dev->scatter_buffer_size = PPC4XX_SD_BUFFER_SIZE;
+ dev->scatter_buffer_va =
+ dma_alloc_coherent(dev->core_dev->device,
+ dev->scatter_buffer_size * PPC4XX_NUM_SD,
+ &dev->scatter_buffer_pa, GFP_ATOMIC);
+ if (!dev->scatter_buffer_va) {
+ dma_free_coherent(dev->core_dev->device,
+ sizeof(struct ce_sd) * PPC4XX_NUM_SD,
+ dev->sdr, dev->sdr_pa);
+ return -ENOMEM;
+ }
+
+ sd_array = dev->sdr;
+
+ for (i = 0; i < PPC4XX_NUM_SD; i++) {
+ sd_array[i].ptr = dev->scatter_buffer_pa +
+ dev->scatter_buffer_size * i;
+ }
+
+ return 0;
+}
+
+static void crypto4xx_destroy_sdr(struct crypto4xx_device *dev)
+{
+ if (dev->sdr != NULL)
+ dma_free_coherent(dev->core_dev->device,
+ sizeof(struct ce_sd) * PPC4XX_NUM_SD,
+ dev->sdr, dev->sdr_pa);
+
+ if (dev->scatter_buffer_va != NULL)
+ dma_free_coherent(dev->core_dev->device,
+ dev->scatter_buffer_size * PPC4XX_NUM_SD,
+ dev->scatter_buffer_va,
+ dev->scatter_buffer_pa);
+}
+
+/*
+ * when this function is called.
+ * preemption or interrupt must be disabled
+ */
+static u32 crypto4xx_get_n_sd(struct crypto4xx_device *dev, int n)
+{
+ u32 retval;
+ u32 tmp;
+
+ if (n >= PPC4XX_NUM_SD)
+ return ERING_WAS_FULL;
+
+ retval = dev->sdr_head;
+ tmp = (dev->sdr_head + n) % PPC4XX_NUM_SD;
+ if (dev->sdr_head > dev->gdr_tail) {
+ if (tmp < dev->sdr_head && tmp >= dev->sdr_tail)
+ return ERING_WAS_FULL;
+ } else if (dev->sdr_head < dev->sdr_tail) {
+ if (tmp < dev->sdr_head || tmp >= dev->sdr_tail)
+ return ERING_WAS_FULL;
+ } /* the head = tail, or empty case is already take cared */
+ dev->sdr_head = tmp;
+
+ return retval;
+}
+
+static u32 crypto4xx_put_sd_to_sdr(struct crypto4xx_device *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->core_dev->lock, flags);
+ if (dev->sdr_tail == dev->sdr_head) {
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+ return 0;
+ }
+ if (dev->sdr_tail != PPC4XX_LAST_SD)
+ dev->sdr_tail++;
+ else
+ dev->sdr_tail = 0;
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+
+ return 0;
+}
+
+static inline struct ce_sd *crypto4xx_get_sdp(struct crypto4xx_device *dev,
+ dma_addr_t *sd_dma, u32 idx)
+{
+ *sd_dma = dev->sdr_pa + sizeof(struct ce_sd) * idx;
+
+ return (struct ce_sd *)(dev->sdr + sizeof(struct ce_sd) * idx);
+}
+
+static u32 crypto4xx_fill_one_page(struct crypto4xx_device *dev,
+ dma_addr_t *addr, u32 *length,
+ u32 *idx, u32 *offset, u32 *nbytes)
+{
+ u32 len;
+
+ if (*length > dev->scatter_buffer_size) {
+ memcpy(phys_to_virt(*addr),
+ dev->scatter_buffer_va +
+ *idx * dev->scatter_buffer_size + *offset,
+ dev->scatter_buffer_size);
+ *offset = 0;
+ *length -= dev->scatter_buffer_size;
+ *nbytes -= dev->scatter_buffer_size;
+ if (*idx == PPC4XX_LAST_SD)
+ *idx = 0;
+ else
+ (*idx)++;
+ *addr = *addr + dev->scatter_buffer_size;
+ return 1;
+ } else if (*length < dev->scatter_buffer_size) {
+ memcpy(phys_to_virt(*addr),
+ dev->scatter_buffer_va +
+ *idx * dev->scatter_buffer_size + *offset, *length);
+ if ((*offset + *length) == dev->scatter_buffer_size) {
+ if (*idx == PPC4XX_LAST_SD)
+ *idx = 0;
+ else
+ (*idx)++;
+ *nbytes -= *length;
+ *offset = 0;
+ } else {
+ *nbytes -= *length;
+ *offset += *length;
+ }
+
+ return 0;
+ } else {
+ len = (*nbytes <= dev->scatter_buffer_size) ?
+ (*nbytes) : dev->scatter_buffer_size;
+ memcpy(phys_to_virt(*addr),
+ dev->scatter_buffer_va +
+ *idx * dev->scatter_buffer_size + *offset,
+ len);
+ *offset = 0;
+ *nbytes -= len;
+
+ if (*idx == PPC4XX_LAST_SD)
+ *idx = 0;
+ else
+ (*idx)++;
+
+ return 0;
+ }
+}
+
+static void crypto4xx_copy_pkt_to_dst(struct crypto4xx_device *dev,
+ struct ce_pd *pd,
+ struct pd_uinfo *pd_uinfo,
+ u32 nbytes,
+ struct scatterlist *dst)
+{
+ dma_addr_t addr;
+ u32 this_sd;
+ u32 offset;
+ u32 len;
+ u32 i;
+ u32 sg_len;
+ struct scatterlist *sg;
+
+ this_sd = pd_uinfo->first_sd;
+ offset = 0;
+ i = 0;
+
+ while (nbytes) {
+ sg = &dst[i];
+ sg_len = sg->length;
+ addr = dma_map_page(dev->core_dev->device, sg_page(sg),
+ sg->offset, sg->length, DMA_TO_DEVICE);
+
+ if (offset == 0) {
+ len = (nbytes <= sg->length) ? nbytes : sg->length;
+ while (crypto4xx_fill_one_page(dev, &addr, &len,
+ &this_sd, &offset, &nbytes))
+ ;
+ if (!nbytes)
+ return;
+ i++;
+ } else {
+ len = (nbytes <= (dev->scatter_buffer_size - offset)) ?
+ nbytes : (dev->scatter_buffer_size - offset);
+ len = (sg->length < len) ? sg->length : len;
+ while (crypto4xx_fill_one_page(dev, &addr, &len,
+ &this_sd, &offset, &nbytes))
+ ;
+ if (!nbytes)
+ return;
+ sg_len -= len;
+ if (sg_len) {
+ addr += len;
+ while (crypto4xx_fill_one_page(dev, &addr,
+ &sg_len, &this_sd, &offset, &nbytes))
+ ;
+ }
+ i++;
+ }
+ }
+}
+
+static u32 crypto4xx_copy_digest_to_dst(struct pd_uinfo *pd_uinfo,
+ struct crypto4xx_ctx *ctx)
+{
+ struct dynamic_sa_ctl *sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+ struct sa_state_record *state_record =
+ (struct sa_state_record *) pd_uinfo->sr_va;
+
+ if (sa->sa_command_0.bf.hash_alg == SA_HASH_ALG_SHA1) {
+ memcpy((void *) pd_uinfo->dest_va, state_record->save_digest,
+ SA_HASH_ALG_SHA1_DIGEST_SIZE);
+ }
+
+ return 0;
+}
+
+static void crypto4xx_ret_sg_desc(struct crypto4xx_device *dev,
+ struct pd_uinfo *pd_uinfo)
+{
+ int i;
+ if (pd_uinfo->num_gd) {
+ for (i = 0; i < pd_uinfo->num_gd; i++)
+ crypto4xx_put_gd_to_gdr(dev);
+ pd_uinfo->first_gd = 0xffffffff;
+ pd_uinfo->num_gd = 0;
+ }
+ if (pd_uinfo->num_sd) {
+ for (i = 0; i < pd_uinfo->num_sd; i++)
+ crypto4xx_put_sd_to_sdr(dev);
+
+ pd_uinfo->first_sd = 0xffffffff;
+ pd_uinfo->num_sd = 0;
+ }
+}
+
+static u32 crypto4xx_ablkcipher_done(struct crypto4xx_device *dev,
+ struct pd_uinfo *pd_uinfo,
+ struct ce_pd *pd)
+{
+ struct crypto4xx_ctx *ctx;
+ struct ablkcipher_request *ablk_req;
+ struct scatterlist *dst;
+ dma_addr_t addr;
+
+ ablk_req = ablkcipher_request_cast(pd_uinfo->async_req);
+ ctx = crypto_tfm_ctx(ablk_req->base.tfm);
+
+ if (pd_uinfo->using_sd) {
+ crypto4xx_copy_pkt_to_dst(dev, pd, pd_uinfo, ablk_req->nbytes,
+ ablk_req->dst);
+ } else {
+ dst = pd_uinfo->dest_va;
+ addr = dma_map_page(dev->core_dev->device, sg_page(dst),
+ dst->offset, dst->length, DMA_FROM_DEVICE);
+ }
+ crypto4xx_ret_sg_desc(dev, pd_uinfo);
+ if (ablk_req->base.complete != NULL)
+ ablk_req->base.complete(&ablk_req->base, 0);
+
+ return 0;
+}
+
+static u32 crypto4xx_ahash_done(struct crypto4xx_device *dev,
+ struct pd_uinfo *pd_uinfo)
+{
+ struct crypto4xx_ctx *ctx;
+ struct ahash_request *ahash_req;
+
+ ahash_req = ahash_request_cast(pd_uinfo->async_req);
+ ctx = crypto_tfm_ctx(ahash_req->base.tfm);
+
+ crypto4xx_copy_digest_to_dst(pd_uinfo,
+ crypto_tfm_ctx(ahash_req->base.tfm));
+ crypto4xx_ret_sg_desc(dev, pd_uinfo);
+ /* call user provided callback function x */
+ if (ahash_req->base.complete != NULL)
+ ahash_req->base.complete(&ahash_req->base, 0);
+
+ return 0;
+}
+
+static u32 crypto4xx_pd_done(struct crypto4xx_device *dev, u32 idx)
+{
+ struct ce_pd *pd;
+ struct pd_uinfo *pd_uinfo;
+
+ pd = dev->pdr + sizeof(struct ce_pd)*idx;
+ pd_uinfo = dev->pdr_uinfo + sizeof(struct pd_uinfo)*idx;
+ if (crypto_tfm_alg_type(pd_uinfo->async_req->tfm) ==
+ CRYPTO_ALG_TYPE_ABLKCIPHER)
+ return crypto4xx_ablkcipher_done(dev, pd_uinfo, pd);
+ else
+ return crypto4xx_ahash_done(dev, pd_uinfo);
+}
+
+/**
+ * Note: Only use this function to copy items that is word aligned.
+ */
+void crypto4xx_memcpy_le(unsigned int *dst,
+ const unsigned char *buf,
+ int len)
+{
+ u8 *tmp;
+ for (; len >= 4; buf += 4, len -= 4)
+ *dst++ = cpu_to_le32(*(unsigned int *) buf);
+
+ tmp = (u8 *)dst;
+ switch (len) {
+ case 3:
+ *tmp++ = 0;
+ *tmp++ = *(buf+2);
+ *tmp++ = *(buf+1);
+ *tmp++ = *buf;
+ break;
+ case 2:
+ *tmp++ = 0;
+ *tmp++ = 0;
+ *tmp++ = *(buf+1);
+ *tmp++ = *buf;
+ break;
+ case 1:
+ *tmp++ = 0;
+ *tmp++ = 0;
+ *tmp++ = 0;
+ *tmp++ = *buf;
+ break;
+ default:
+ break;
+ }
+}
+
+static void crypto4xx_stop_all(struct crypto4xx_core_device *core_dev)
+{
+ crypto4xx_destroy_pdr(core_dev->dev);
+ crypto4xx_destroy_gdr(core_dev->dev);
+ crypto4xx_destroy_sdr(core_dev->dev);
+ dev_set_drvdata(core_dev->device, NULL);
+ iounmap(core_dev->dev->ce_base);
+ kfree(core_dev->dev);
+ kfree(core_dev);
+}
+
+void crypto4xx_return_pd(struct crypto4xx_device *dev,
+ u32 pd_entry, struct ce_pd *pd,
+ struct pd_uinfo *pd_uinfo)
+{
+ /* irq should be already disabled */
+ dev->pdr_head = pd_entry;
+ pd->pd_ctl.w = 0;
+ pd->pd_ctl_len.w = 0;
+ pd_uinfo->state = PD_ENTRY_FREE;
+}
+
+/*
+ * derive number of elements in scatterlist
+ * Shamlessly copy from talitos.c
+ */
+static int get_sg_count(struct scatterlist *sg_list, int nbytes)
+{
+ struct scatterlist *sg = sg_list;
+ int sg_nents = 0;
+
+ while (nbytes) {
+ sg_nents++;
+ if (sg->length > nbytes)
+ break;
+ nbytes -= sg->length;
+ sg = sg_next(sg);
+ }
+
+ return sg_nents;
+}
+
+static u32 get_next_gd(u32 current)
+{
+ if (current != PPC4XX_LAST_GD)
+ return current + 1;
+ else
+ return 0;
+}
+
+static u32 get_next_sd(u32 current)
+{
+ if (current != PPC4XX_LAST_SD)
+ return current + 1;
+ else
+ return 0;
+}
+
+u32 crypto4xx_build_pd(struct crypto_async_request *req,
+ struct crypto4xx_ctx *ctx,
+ struct scatterlist *src,
+ struct scatterlist *dst,
+ unsigned int datalen,
+ void *iv, u32 iv_len)
+{
+ struct crypto4xx_device *dev = ctx->dev;
+ dma_addr_t addr, pd_dma, sd_dma, gd_dma;
+ struct dynamic_sa_ctl *sa;
+ struct scatterlist *sg;
+ struct ce_gd *gd;
+ struct ce_pd *pd;
+ u32 num_gd, num_sd;
+ u32 fst_gd = 0xffffffff;
+ u32 fst_sd = 0xffffffff;
+ u32 pd_entry;
+ unsigned long flags;
+ struct pd_uinfo *pd_uinfo = NULL;
+ unsigned int nbytes = datalen, idx;
+ unsigned int ivlen = 0;
+ u32 gd_idx = 0;
+
+ /* figure how many gd is needed */
+ num_gd = get_sg_count(src, datalen);
+ if (num_gd == 1)
+ num_gd = 0;
+
+ /* figure how many sd is needed */
+ if (sg_is_last(dst) || ctx->is_hash) {
+ num_sd = 0;
+ } else {
+ if (datalen > PPC4XX_SD_BUFFER_SIZE) {
+ num_sd = datalen / PPC4XX_SD_BUFFER_SIZE;
+ if (datalen % PPC4XX_SD_BUFFER_SIZE)
+ num_sd++;
+ } else {
+ num_sd = 1;
+ }
+ }
+
+ /*
+ * The follow section of code needs to be protected
+ * The gather ring and scatter ring needs to be consecutive
+ * In case of run out of any kind of descriptor, the descriptor
+ * already got must be return the original place.
+ */
+ spin_lock_irqsave(&dev->core_dev->lock, flags);
+ if (num_gd) {
+ fst_gd = crypto4xx_get_n_gd(dev, num_gd);
+ if (fst_gd == ERING_WAS_FULL) {
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+ return -EAGAIN;
+ }
+ }
+ if (num_sd) {
+ fst_sd = crypto4xx_get_n_sd(dev, num_sd);
+ if (fst_sd == ERING_WAS_FULL) {
+ if (num_gd)
+ dev->gdr_head = fst_gd;
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+ return -EAGAIN;
+ }
+ }
+ pd_entry = crypto4xx_get_pd_from_pdr_nolock(dev);
+ if (pd_entry == ERING_WAS_FULL) {
+ if (num_gd)
+ dev->gdr_head = fst_gd;
+ if (num_sd)
+ dev->sdr_head = fst_sd;
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+ return -EAGAIN;
+ }
+ spin_unlock_irqrestore(&dev->core_dev->lock, flags);
+
+ pd_uinfo = (struct pd_uinfo *)(dev->pdr_uinfo +
+ sizeof(struct pd_uinfo) * pd_entry);
+ pd = crypto4xx_get_pdp(dev, &pd_dma, pd_entry);
+ pd_uinfo->async_req = req;
+ pd_uinfo->num_gd = num_gd;
+ pd_uinfo->num_sd = num_sd;
+
+ if (iv_len || ctx->is_hash) {
+ ivlen = iv_len;
+ pd->sa = pd_uinfo->sa_pa;
+ sa = (struct dynamic_sa_ctl *) pd_uinfo->sa_va;
+ if (ctx->direction == DIR_INBOUND)
+ memcpy(sa, ctx->sa_in, ctx->sa_len * 4);
+ else
+ memcpy(sa, ctx->sa_out, ctx->sa_len * 4);
+
+ memcpy((void *) sa + ctx->offset_to_sr_ptr,
+ &pd_uinfo->sr_pa, 4);
+
+ if (iv_len)
+ crypto4xx_memcpy_le(pd_uinfo->sr_va, iv, iv_len);
+ } else {
+ if (ctx->direction == DIR_INBOUND) {
+ pd->sa = ctx->sa_in_dma_addr;
+ sa = (struct dynamic_sa_ctl *) ctx->sa_in;
+ } else {
+ pd->sa = ctx->sa_out_dma_addr;
+ sa = (struct dynamic_sa_ctl *) ctx->sa_out;
+ }
+ }
+ pd->sa_len = ctx->sa_len;
+ if (num_gd) {
+ /* get first gd we are going to use */
+ gd_idx = fst_gd;
+ pd_uinfo->first_gd = fst_gd;
+ pd_uinfo->num_gd = num_gd;
+ gd = crypto4xx_get_gdp(dev, &gd_dma, gd_idx);
+ pd->src = gd_dma;
+ /* enable gather */
+ sa->sa_command_0.bf.gather = 1;
+ idx = 0;
+ src = &src[0];
+ /* walk the sg, and setup gather array */
+ while (nbytes) {
+ sg = &src[idx];
+ addr = dma_map_page(dev->core_dev->device, sg_page(sg),
+ sg->offset, sg->length, DMA_TO_DEVICE);
+ gd->ptr = addr;
+ gd->ctl_len.len = sg->length;
+ gd->ctl_len.done = 0;
+ gd->ctl_len.ready = 1;
+ if (sg->length >= nbytes)
+ break;
+ nbytes -= sg->length;
+ gd_idx = get_next_gd(gd_idx);
+ gd = crypto4xx_get_gdp(dev, &gd_dma, gd_idx);
+ idx++;
+ }
+ } else {
+ pd->src = (u32)dma_map_page(dev->core_dev->device, sg_page(src),
+ src->offset, src->length, DMA_TO_DEVICE);
+ /*
+ * Disable gather in sa command
+ */
+ sa->sa_command_0.bf.gather = 0;
+ /*
+ * Indicate gather array is not used
+ */
+ pd_uinfo->first_gd = 0xffffffff;
+ pd_uinfo->num_gd = 0;
+ }
+ if (ctx->is_hash || sg_is_last(dst)) {
+ /*
+ * we know application give us dst a whole piece of memory
+ * no need to use scatter ring.
+ * In case of is_hash, the icv is always at end of src data.
+ */
+ pd_uinfo->using_sd = 0;
+ pd_uinfo->first_sd = 0xffffffff;
+ pd_uinfo->num_sd = 0;
+ pd_uinfo->dest_va = dst;
+ sa->sa_command_0.bf.scatter = 0;
+ if (ctx->is_hash)
+ pd->dest = virt_to_phys((void *)dst);
+ else
+ pd->dest = (u32)dma_map_page(dev->core_dev->device,
+ sg_page(dst), dst->offset,
+ dst->length, DMA_TO_DEVICE);
+ } else {
+ struct ce_sd *sd = NULL;
+ u32 sd_idx = fst_sd;
+ nbytes = datalen;
+ sa->sa_command_0.bf.scatter = 1;
+ pd_uinfo->using_sd = 1;
+ pd_uinfo->dest_va = dst;
+ pd_uinfo->first_sd = fst_sd;
+ pd_uinfo->num_sd = num_sd;
+ sd = crypto4xx_get_sdp(dev, &sd_dma, sd_idx);
+ pd->dest = sd_dma;
+ /* setup scatter descriptor */
+ sd->ctl.done = 0;
+ sd->ctl.rdy = 1;
+ /* sd->ptr should be setup by sd_init routine*/
+ idx = 0;
+ if (nbytes >= PPC4XX_SD_BUFFER_SIZE)
+ nbytes -= PPC4XX_SD_BUFFER_SIZE;
+ else
+ nbytes = 0;
+ while (nbytes) {
+ sd_idx = get_next_sd(sd_idx);
+ sd = crypto4xx_get_sdp(dev, &sd_dma, sd_idx);
+ /* setup scatter descriptor */
+ sd->ctl.done = 0;
+ sd->ctl.rdy = 1;
+ if (nbytes >= PPC4XX_SD_BUFFER_SIZE)
+ nbytes -= PPC4XX_SD_BUFFER_SIZE;
+ else
+ /*
+ * SD entry can hold PPC4XX_SD_BUFFER_SIZE,
+ * which is more than nbytes, so done.
+ */
+ nbytes = 0;
+ }
+ }
+
+ sa->sa_command_1.bf.hash_crypto_offset = 0;
+ pd->pd_ctl.w = ctx->pd_ctl;
+ pd->pd_ctl_len.w = 0x00400000 | (ctx->bypass << 24) | datalen;
+ pd_uinfo->state = PD_ENTRY_INUSE;
+ wmb();
+ /* write any value to push engine to read a pd */
+ writel(1, dev->ce_base + CRYPTO4XX_INT_DESCR_RD);
+ return -EINPROGRESS;
+}
+
+/**
+ * Algorithm Registration Functions
+ */
+static int crypto4xx_alg_init(struct crypto_tfm *tfm)
+{
+ struct crypto_alg *alg = tfm->__crt_alg;
+ struct crypto4xx_alg *amcc_alg = crypto_alg_to_crypto4xx_alg(alg);
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ ctx->dev = amcc_alg->dev;
+ ctx->sa_in = NULL;
+ ctx->sa_out = NULL;
+ ctx->sa_in_dma_addr = 0;
+ ctx->sa_out_dma_addr = 0;
+ ctx->sa_len = 0;
+
+ if (alg->cra_type == &crypto_ablkcipher_type)
+ tfm->crt_ablkcipher.reqsize = sizeof(struct crypto4xx_ctx);
+ else if (alg->cra_type == &crypto_ahash_type)
+ tfm->crt_ahash.reqsize = sizeof(struct crypto4xx_ctx);
+
+ return 0;
+}
+
+static void crypto4xx_alg_exit(struct crypto_tfm *tfm)
+{
+ struct crypto4xx_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ crypto4xx_free_sa(ctx);
+ crypto4xx_free_state_record(ctx);
+}
+
+int crypto4xx_register_alg(struct crypto4xx_device *sec_dev,
+ struct crypto_alg *crypto_alg, int array_size)
+{
+ struct crypto4xx_alg *alg;
+ int i;
+ int rc = 0;
+
+ for (i = 0; i < array_size; i++) {
+ alg = kzalloc(sizeof(struct crypto4xx_alg), GFP_KERNEL);
+ if (!alg)
+ return -ENOMEM;
+
+ alg->alg = crypto_alg[i];
+ INIT_LIST_HEAD(&alg->alg.cra_list);
+ if (alg->alg.cra_init == NULL)
+ alg->alg.cra_init = crypto4xx_alg_init;
+ if (alg->alg.cra_exit == NULL)
+ alg->alg.cra_exit = crypto4xx_alg_exit;
+ alg->dev = sec_dev;
+ rc = crypto_register_alg(&alg->alg);
+ if (rc) {
+ list_del(&alg->entry);
+ kfree(alg);
+ } else {
+ list_add_tail(&alg->entry, &sec_dev->alg_list);
+ }
+ }
+
+ return 0;
+}
+
+static void crypto4xx_unregister_alg(struct crypto4xx_device *sec_dev)
+{
+ struct crypto4xx_alg *alg, *tmp;
+
+ list_for_each_entry_safe(alg, tmp, &sec_dev->alg_list, entry) {
+ list_del(&alg->entry);
+ crypto_unregister_alg(&alg->alg);
+ kfree(alg);
+ }
+}
+
+static void crypto4xx_bh_tasklet_cb(unsigned long data)
+{
+ struct device *dev = (struct device *)data;
+ struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
+ struct pd_uinfo *pd_uinfo;
+ struct ce_pd *pd;
+ u32 tail;
+
+ while (core_dev->dev->pdr_head != core_dev->dev->pdr_tail) {
+ tail = core_dev->dev->pdr_tail;
+ pd_uinfo = core_dev->dev->pdr_uinfo +
+ sizeof(struct pd_uinfo)*tail;
+ pd = core_dev->dev->pdr + sizeof(struct ce_pd) * tail;
+ if ((pd_uinfo->state == PD_ENTRY_INUSE) &&
+ pd->pd_ctl.bf.pe_done &&
+ !pd->pd_ctl.bf.host_ready) {
+ pd->pd_ctl.bf.pe_done = 0;
+ crypto4xx_pd_done(core_dev->dev, tail);
+ crypto4xx_put_pd_to_pdr(core_dev->dev, tail);
+ pd_uinfo->state = PD_ENTRY_FREE;
+ } else {
+ /* if tail not done, break */
+ break;
+ }
+ }
+}
+
+/**
+ * Top Half of isr.
+ */
+static irqreturn_t crypto4xx_ce_interrupt_handler(int irq, void *data)
+{
+ struct device *dev = (struct device *)data;
+ struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
+
+ if (core_dev->dev->ce_base == 0)
+ return 0;
+
+ writel(PPC4XX_INTERRUPT_CLR,
+ core_dev->dev->ce_base + CRYPTO4XX_INT_CLR);
+ tasklet_schedule(&core_dev->tasklet);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * Supported Crypto Algorithms
+ */
+struct crypto_alg crypto4xx_alg[] = {
+ /* Crypto AES modes */
+ {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "cbc-aes-ppc4xx",
+ .cra_priority = CRYPTO4XX_CRYPTO_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto4xx_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
+ .ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_IV_SIZE,
+ .setkey = crypto4xx_setkey_aes_cbc,
+ .encrypt = crypto4xx_encrypt,
+ .decrypt = crypto4xx_decrypt,
+ }
+ }
+ },
+ /* Hash SHA1 */
+ {
+ .cra_name = "sha1",
+ .cra_driver_name = "sha1-ppc4xx",
+ .cra_priority = CRYPTO4XX_CRYPTO_PRIORITY,
+ .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC,
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct crypto4xx_ctx),
+ .cra_alignmask = 0,
+ .cra_type = &crypto_ahash_type,
+ .cra_init = crypto4xx_sha1_alg_init,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
+ .ahash = {
+ .digestsize = SHA1_DIGEST_SIZE,
+ .init = crypto4xx_hash_init,
+ .update = crypto4xx_hash_update,
+ .final = crypto4xx_hash_final,
+ .digest = crypto4xx_hash_digest,
+ }
+ }
+ },
+};
+
+/**
+ * Module Initialization Routine
+ */
+static int __init crypto4xx_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ int rc;
+ struct resource res;
+ struct device *dev = &ofdev->dev;
+ struct crypto4xx_core_device *core_dev;
+
+ rc = of_address_to_resource(ofdev->node, 0, &res);
+ if (rc)
+ return -ENODEV;
+
+ if (of_find_compatible_node(NULL, NULL, "amcc,ppc460ex-crypto")) {
+ mtdcri(SDR0, PPC460EX_SDR0_SRST,
+ mfdcri(SDR0, PPC460EX_SDR0_SRST) | PPC460EX_CE_RESET);
+ mtdcri(SDR0, PPC460EX_SDR0_SRST,
+ mfdcri(SDR0, PPC460EX_SDR0_SRST) & ~PPC460EX_CE_RESET);
+ } else if (of_find_compatible_node(NULL, NULL,
+ "amcc,ppc405ex-crypto")) {
+ mtdcri(SDR0, PPC405EX_SDR0_SRST,
+ mfdcri(SDR0, PPC405EX_SDR0_SRST) | PPC405EX_CE_RESET);
+ mtdcri(SDR0, PPC405EX_SDR0_SRST,
+ mfdcri(SDR0, PPC405EX_SDR0_SRST) & ~PPC405EX_CE_RESET);
+ } else if (of_find_compatible_node(NULL, NULL,
+ "amcc,ppc460sx-crypto")) {
+ mtdcri(SDR0, PPC460SX_SDR0_SRST,
+ mfdcri(SDR0, PPC460SX_SDR0_SRST) | PPC460SX_CE_RESET);
+ mtdcri(SDR0, PPC460SX_SDR0_SRST,
+ mfdcri(SDR0, PPC460SX_SDR0_SRST) & ~PPC460SX_CE_RESET);
+ } else {
+ printk(KERN_ERR "Crypto Function Not supported!\n");
+ return -EINVAL;
+ }
+
+ core_dev = kzalloc(sizeof(struct crypto4xx_core_device), GFP_KERNEL);
+ if (!core_dev)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, core_dev);
+ core_dev->ofdev = ofdev;
+ core_dev->dev = kzalloc(sizeof(struct crypto4xx_device), GFP_KERNEL);
+ if (!core_dev->dev)
+ goto err_alloc_dev;
+
+ core_dev->dev->core_dev = core_dev;
+ core_dev->device = dev;
+ spin_lock_init(&core_dev->lock);
+ INIT_LIST_HEAD(&core_dev->dev->alg_list);
+ rc = crypto4xx_build_pdr(core_dev->dev);
+ if (rc)
+ goto err_build_pdr;
+
+ rc = crypto4xx_build_gdr(core_dev->dev);
+ if (rc)
+ goto err_build_gdr;
+
+ rc = crypto4xx_build_sdr(core_dev->dev);
+ if (rc)
+ goto err_build_sdr;
+
+ /* Init tasklet for bottom half processing */
+ tasklet_init(&core_dev->tasklet, crypto4xx_bh_tasklet_cb,
+ (unsigned long) dev);
+
+ /* Register for Crypto isr, Crypto Engine IRQ */
+ core_dev->irq = irq_of_parse_and_map(ofdev->node, 0);
+ rc = request_irq(core_dev->irq, crypto4xx_ce_interrupt_handler, 0,
+ core_dev->dev->name, dev);
+ if (rc)
+ goto err_request_irq;
+
+ core_dev->dev->ce_base = of_iomap(ofdev->node, 0);
+ if (!core_dev->dev->ce_base) {
+ dev_err(dev, "failed to of_iomap\n");
+ goto err_iomap;
+ }
+
+ /* need to setup pdr, rdr, gdr and sdr before this */
+ crypto4xx_hw_init(core_dev->dev);
+
+ /* Register security algorithms with Linux CryptoAPI */
+ rc = crypto4xx_register_alg(core_dev->dev, crypto4xx_alg,
+ ARRAY_SIZE(crypto4xx_alg));
+ if (rc)
+ goto err_start_dev;
+
+ return 0;
+
+err_start_dev:
+ iounmap(core_dev->dev->ce_base);
+err_iomap:
+ free_irq(core_dev->irq, dev);
+ irq_dispose_mapping(core_dev->irq);
+ tasklet_kill(&core_dev->tasklet);
+err_request_irq:
+ crypto4xx_destroy_sdr(core_dev->dev);
+err_build_sdr:
+ crypto4xx_destroy_gdr(core_dev->dev);
+err_build_gdr:
+ crypto4xx_destroy_pdr(core_dev->dev);
+err_build_pdr:
+ kfree(core_dev->dev);
+err_alloc_dev:
+ kfree(core_dev);
+
+ return rc;
+}
+
+static int __exit crypto4xx_remove(struct of_device *ofdev)
+{
+ struct device *dev = &ofdev->dev;
+ struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
+
+ free_irq(core_dev->irq, dev);
+ irq_dispose_mapping(core_dev->irq);
+
+ tasklet_kill(&core_dev->tasklet);
+ /* Un-register with Linux CryptoAPI */
+ crypto4xx_unregister_alg(core_dev->dev);
+ /* Free all allocated memory */
+ crypto4xx_stop_all(core_dev);
+
+ return 0;
+}
+
+static struct of_device_id crypto4xx_match[] = {
+ { .compatible = "amcc,ppc4xx-crypto",},
+ { },
+};
+
+static struct of_platform_driver crypto4xx_driver = {
+ .name = "crypto4xx",
+ .match_table = crypto4xx_match,
+ .probe = crypto4xx_probe,
+ .remove = crypto4xx_remove,
+};
+
+static int __init crypto4xx_init(void)
+{
+ return of_register_platform_driver(&crypto4xx_driver);
+}
+
+static void __exit crypto4xx_exit(void)
+{
+ of_unregister_platform_driver(&crypto4xx_driver);
+}
+
+module_init(crypto4xx_init);
+module_exit(crypto4xx_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("James Hsiao <jhsiao@amcc.com>");
+MODULE_DESCRIPTION("Driver for AMCC PPC4xx crypto accelerator");
+
diff --git a/drivers/crypto/amcc/crypto4xx_core.h b/drivers/crypto/amcc/crypto4xx_core.h
new file mode 100644
index 000000000000..1ef103449364
--- /dev/null
+++ b/drivers/crypto/amcc/crypto4xx_core.h
@@ -0,0 +1,177 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This is the header file for AMCC Crypto offload Linux device driver for
+ * use with Linux CryptoAPI.
+
+ */
+
+#ifndef __CRYPTO4XX_CORE_H__
+#define __CRYPTO4XX_CORE_H__
+
+#define PPC460SX_SDR0_SRST 0x201
+#define PPC405EX_SDR0_SRST 0x200
+#define PPC460EX_SDR0_SRST 0x201
+#define PPC460EX_CE_RESET 0x08000000
+#define PPC460SX_CE_RESET 0x20000000
+#define PPC405EX_CE_RESET 0x00000008
+
+#define CRYPTO4XX_CRYPTO_PRIORITY 300
+#define PPC4XX_LAST_PD 63
+#define PPC4XX_NUM_PD 64
+#define PPC4XX_LAST_GD 1023
+#define PPC4XX_NUM_GD 1024
+#define PPC4XX_LAST_SD 63
+#define PPC4XX_NUM_SD 64
+#define PPC4XX_SD_BUFFER_SIZE 2048
+
+#define PD_ENTRY_INUSE 1
+#define PD_ENTRY_FREE 0
+#define ERING_WAS_FULL 0xffffffff
+
+struct crypto4xx_device;
+
+struct pd_uinfo {
+ struct crypto4xx_device *dev;
+ u32 state;
+ u32 using_sd;
+ u32 first_gd; /* first gather discriptor
+ used by this packet */
+ u32 num_gd; /* number of gather discriptor
+ used by this packet */
+ u32 first_sd; /* first scatter discriptor
+ used by this packet */
+ u32 num_sd; /* number of scatter discriptors
+ used by this packet */
+ void *sa_va; /* shadow sa, when using cp from ctx->sa */
+ u32 sa_pa;
+ void *sr_va; /* state record for shadow sa */
+ u32 sr_pa;
+ struct scatterlist *dest_va;
+ struct crypto_async_request *async_req; /* base crypto request
+ for this packet */
+};
+
+struct crypto4xx_device {
+ struct crypto4xx_core_device *core_dev;
+ char *name;
+ u64 ce_phy_address;
+ void __iomem *ce_base;
+
+ void *pdr; /* base address of packet
+ descriptor ring */
+ dma_addr_t pdr_pa; /* physical address used to
+ program ce pdr_base_register */
+ void *gdr; /* gather descriptor ring */
+ dma_addr_t gdr_pa; /* physical address used to
+ program ce gdr_base_register */
+ void *sdr; /* scatter descriptor ring */
+ dma_addr_t sdr_pa; /* physical address used to
+ program ce sdr_base_register */
+ void *scatter_buffer_va;
+ dma_addr_t scatter_buffer_pa;
+ u32 scatter_buffer_size;
+
+ void *shadow_sa_pool; /* pool of memory for sa in pd_uinfo */
+ dma_addr_t shadow_sa_pool_pa;
+ void *shadow_sr_pool; /* pool of memory for sr in pd_uinfo */
+ dma_addr_t shadow_sr_pool_pa;
+ u32 pdr_tail;
+ u32 pdr_head;
+ u32 gdr_tail;
+ u32 gdr_head;
+ u32 sdr_tail;
+ u32 sdr_head;
+ void *pdr_uinfo;
+ struct list_head alg_list; /* List of algorithm supported
+ by this device */
+};
+
+struct crypto4xx_core_device {
+ struct device *device;
+ struct of_device *ofdev;
+ struct crypto4xx_device *dev;
+ u32 int_status;
+ u32 irq;
+ struct tasklet_struct tasklet;
+ spinlock_t lock;
+};
+
+struct crypto4xx_ctx {
+ struct crypto4xx_device *dev;
+ void *sa_in;
+ dma_addr_t sa_in_dma_addr;
+ void *sa_out;
+ dma_addr_t sa_out_dma_addr;
+ void *state_record;
+ dma_addr_t state_record_dma_addr;
+ u32 sa_len;
+ u32 offset_to_sr_ptr; /* offset to state ptr, in dynamic sa */
+ u32 direction;
+ u32 next_hdr;
+ u32 save_iv;
+ u32 pd_ctl_len;
+ u32 pd_ctl;
+ u32 bypass;
+ u32 is_hash;
+ u32 hash_final;
+};
+
+struct crypto4xx_req_ctx {
+ struct crypto4xx_device *dev; /* Device in which
+ operation to send to */
+ void *sa;
+ u32 sa_dma_addr;
+ u16 sa_len;
+};
+
+struct crypto4xx_alg {
+ struct list_head entry;
+ struct crypto_alg alg;
+ struct crypto4xx_device *dev;
+};
+
+#define crypto_alg_to_crypto4xx_alg(x) \
+ container_of(x, struct crypto4xx_alg, alg)
+
+extern int crypto4xx_alloc_sa(struct crypto4xx_ctx *ctx, u32 size);
+extern void crypto4xx_free_sa(struct crypto4xx_ctx *ctx);
+extern u32 crypto4xx_alloc_sa_rctx(struct crypto4xx_ctx *ctx,
+ struct crypto4xx_ctx *rctx);
+extern void crypto4xx_free_sa_rctx(struct crypto4xx_ctx *rctx);
+extern void crypto4xx_free_ctx(struct crypto4xx_ctx *ctx);
+extern u32 crypto4xx_alloc_state_record(struct crypto4xx_ctx *ctx);
+extern u32 get_dynamic_sa_offset_state_ptr_field(struct crypto4xx_ctx *ctx);
+extern u32 get_dynamic_sa_offset_key_field(struct crypto4xx_ctx *ctx);
+extern u32 get_dynamic_sa_iv_size(struct crypto4xx_ctx *ctx);
+extern void crypto4xx_memcpy_le(unsigned int *dst,
+ const unsigned char *buf, int len);
+extern u32 crypto4xx_build_pd(struct crypto_async_request *req,
+ struct crypto4xx_ctx *ctx,
+ struct scatterlist *src,
+ struct scatterlist *dst,
+ unsigned int datalen,
+ void *iv, u32 iv_len);
+extern int crypto4xx_setkey_aes_cbc(struct crypto_ablkcipher *cipher,
+ const u8 *key, unsigned int keylen);
+extern int crypto4xx_encrypt(struct ablkcipher_request *req);
+extern int crypto4xx_decrypt(struct ablkcipher_request *req);
+extern int crypto4xx_sha1_alg_init(struct crypto_tfm *tfm);
+extern int crypto4xx_hash_digest(struct ahash_request *req);
+extern int crypto4xx_hash_final(struct ahash_request *req);
+extern int crypto4xx_hash_update(struct ahash_request *req);
+extern int crypto4xx_hash_init(struct ahash_request *req);
+#endif
diff --git a/drivers/crypto/amcc/crypto4xx_reg_def.h b/drivers/crypto/amcc/crypto4xx_reg_def.h
new file mode 100644
index 000000000000..7d4edb002619
--- /dev/null
+++ b/drivers/crypto/amcc/crypto4xx_reg_def.h
@@ -0,0 +1,284 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This filr defines the register set for Security Subsystem
+ */
+
+#ifndef __CRYPTO4XX_REG_DEF_H__
+#define __CRYPTO4XX_REG_DEF_H__
+
+/* CRYPTO4XX Register offset */
+#define CRYPTO4XX_DESCRIPTOR 0x00000000
+#define CRYPTO4XX_CTRL_STAT 0x00000000
+#define CRYPTO4XX_SOURCE 0x00000004
+#define CRYPTO4XX_DEST 0x00000008
+#define CRYPTO4XX_SA 0x0000000C
+#define CRYPTO4XX_SA_LENGTH 0x00000010
+#define CRYPTO4XX_LENGTH 0x00000014
+
+#define CRYPTO4XX_PE_DMA_CFG 0x00000040
+#define CRYPTO4XX_PE_DMA_STAT 0x00000044
+#define CRYPTO4XX_PDR_BASE 0x00000048
+#define CRYPTO4XX_RDR_BASE 0x0000004c
+#define CRYPTO4XX_RING_SIZE 0x00000050
+#define CRYPTO4XX_RING_CTRL 0x00000054
+#define CRYPTO4XX_INT_RING_STAT 0x00000058
+#define CRYPTO4XX_EXT_RING_STAT 0x0000005c
+#define CRYPTO4XX_IO_THRESHOLD 0x00000060
+#define CRYPTO4XX_GATH_RING_BASE 0x00000064
+#define CRYPTO4XX_SCAT_RING_BASE 0x00000068
+#define CRYPTO4XX_PART_RING_SIZE 0x0000006c
+#define CRYPTO4XX_PART_RING_CFG 0x00000070
+
+#define CRYPTO4XX_PDR_BASE_UADDR 0x00000080
+#define CRYPTO4XX_RDR_BASE_UADDR 0x00000084
+#define CRYPTO4XX_PKT_SRC_UADDR 0x00000088
+#define CRYPTO4XX_PKT_DEST_UADDR 0x0000008c
+#define CRYPTO4XX_SA_UADDR 0x00000090
+#define CRYPTO4XX_GATH_RING_BASE_UADDR 0x000000A0
+#define CRYPTO4XX_SCAT_RING_BASE_UADDR 0x000000A4
+
+#define CRYPTO4XX_SEQ_RD 0x00000408
+#define CRYPTO4XX_SEQ_MASK_RD 0x0000040C
+
+#define CRYPTO4XX_SA_CMD_0 0x00010600
+#define CRYPTO4XX_SA_CMD_1 0x00010604
+
+#define CRYPTO4XX_STATE_PTR 0x000106dc
+#define CRYPTO4XX_STATE_IV 0x00010700
+#define CRYPTO4XX_STATE_HASH_BYTE_CNT_0 0x00010710
+#define CRYPTO4XX_STATE_HASH_BYTE_CNT_1 0x00010714
+
+#define CRYPTO4XX_STATE_IDIGEST_0 0x00010718
+#define CRYPTO4XX_STATE_IDIGEST_1 0x0001071c
+
+#define CRYPTO4XX_DATA_IN 0x00018000
+#define CRYPTO4XX_DATA_OUT 0x0001c000
+
+#define CRYPTO4XX_INT_UNMASK_STAT 0x000500a0
+#define CRYPTO4XX_INT_MASK_STAT 0x000500a4
+#define CRYPTO4XX_INT_CLR 0x000500a4
+#define CRYPTO4XX_INT_EN 0x000500a8
+
+#define CRYPTO4XX_INT_PKA 0x00000002
+#define CRYPTO4XX_INT_PDR_DONE 0x00008000
+#define CRYPTO4XX_INT_MA_WR_ERR 0x00020000
+#define CRYPTO4XX_INT_MA_RD_ERR 0x00010000
+#define CRYPTO4XX_INT_PE_ERR 0x00000200
+#define CRYPTO4XX_INT_USER_DMA_ERR 0x00000040
+#define CRYPTO4XX_INT_SLAVE_ERR 0x00000010
+#define CRYPTO4XX_INT_MASTER_ERR 0x00000008
+#define CRYPTO4XX_INT_ERROR 0x00030258
+
+#define CRYPTO4XX_INT_CFG 0x000500ac
+#define CRYPTO4XX_INT_DESCR_RD 0x000500b0
+#define CRYPTO4XX_INT_DESCR_CNT 0x000500b4
+#define CRYPTO4XX_INT_TIMEOUT_CNT 0x000500b8
+
+#define CRYPTO4XX_DEVICE_CTRL 0x00060080
+#define CRYPTO4XX_DEVICE_ID 0x00060084
+#define CRYPTO4XX_DEVICE_INFO 0x00060088
+#define CRYPTO4XX_DMA_USER_SRC 0x00060094
+#define CRYPTO4XX_DMA_USER_DEST 0x00060098
+#define CRYPTO4XX_DMA_USER_CMD 0x0006009C
+
+#define CRYPTO4XX_DMA_CFG 0x000600d4
+#define CRYPTO4XX_BYTE_ORDER_CFG 0x000600d8
+#define CRYPTO4XX_ENDIAN_CFG 0x000600d8
+
+#define CRYPTO4XX_PRNG_STAT 0x00070000
+#define CRYPTO4XX_PRNG_CTRL 0x00070004
+#define CRYPTO4XX_PRNG_SEED_L 0x00070008
+#define CRYPTO4XX_PRNG_SEED_H 0x0007000c
+
+#define CRYPTO4XX_PRNG_RES_0 0x00070020
+#define CRYPTO4XX_PRNG_RES_1 0x00070024
+#define CRYPTO4XX_PRNG_RES_2 0x00070028
+#define CRYPTO4XX_PRNG_RES_3 0x0007002C
+
+#define CRYPTO4XX_PRNG_LFSR_L 0x00070030
+#define CRYPTO4XX_PRNG_LFSR_H 0x00070034
+
+/**
+ * Initilize CRYPTO ENGINE registers, and memory bases.
+ */
+#define PPC4XX_PDR_POLL 0x3ff
+#define PPC4XX_OUTPUT_THRESHOLD 2
+#define PPC4XX_INPUT_THRESHOLD 2
+#define PPC4XX_PD_SIZE 6
+#define PPC4XX_CTX_DONE_INT 0x2000
+#define PPC4XX_PD_DONE_INT 0x8000
+#define PPC4XX_BYTE_ORDER 0x22222
+#define PPC4XX_INTERRUPT_CLR 0x3ffff
+#define PPC4XX_PRNG_CTRL_AUTO_EN 0x3
+#define PPC4XX_DC_3DES_EN 1
+#define PPC4XX_INT_DESCR_CNT 4
+#define PPC4XX_INT_TIMEOUT_CNT 0
+#define PPC4XX_INT_CFG 1
+/**
+ * all follow define are ad hoc
+ */
+#define PPC4XX_RING_RETRY 100
+#define PPC4XX_RING_POLL 100
+#define PPC4XX_SDR_SIZE PPC4XX_NUM_SD
+#define PPC4XX_GDR_SIZE PPC4XX_NUM_GD
+
+/**
+ * Generic Security Association (SA) with all possible fields. These will
+ * never likely used except for reference purpose. These structure format
+ * can be not changed as the hardware expects them to be layout as defined.
+ * Field can be removed or reduced but ordering can not be changed.
+ */
+#define CRYPTO4XX_DMA_CFG_OFFSET 0x40
+union ce_pe_dma_cfg {
+ struct {
+ u32 rsv:7;
+ u32 dir_host:1;
+ u32 rsv1:2;
+ u32 bo_td_en:1;
+ u32 dis_pdr_upd:1;
+ u32 bo_sgpd_en:1;
+ u32 bo_data_en:1;
+ u32 bo_sa_en:1;
+ u32 bo_pd_en:1;
+ u32 rsv2:4;
+ u32 dynamic_sa_en:1;
+ u32 pdr_mode:2;
+ u32 pe_mode:1;
+ u32 rsv3:5;
+ u32 reset_sg:1;
+ u32 reset_pdr:1;
+ u32 reset_pe:1;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define CRYPTO4XX_PDR_BASE_OFFSET 0x48
+#define CRYPTO4XX_RDR_BASE_OFFSET 0x4c
+#define CRYPTO4XX_RING_SIZE_OFFSET 0x50
+union ce_ring_size {
+ struct {
+ u32 ring_offset:16;
+ u32 rsv:6;
+ u32 ring_size:10;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define CRYPTO4XX_RING_CONTROL_OFFSET 0x54
+union ce_ring_contol {
+ struct {
+ u32 continuous:1;
+ u32 rsv:5;
+ u32 ring_retry_divisor:10;
+ u32 rsv1:4;
+ u32 ring_poll_divisor:10;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define CRYPTO4XX_IO_THRESHOLD_OFFSET 0x60
+union ce_io_threshold {
+ struct {
+ u32 rsv:6;
+ u32 output_threshold:10;
+ u32 rsv1:6;
+ u32 input_threshold:10;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define CRYPTO4XX_GATHER_RING_BASE_OFFSET 0x64
+#define CRYPTO4XX_SCATTER_RING_BASE_OFFSET 0x68
+
+union ce_part_ring_size {
+ struct {
+ u32 sdr_size:16;
+ u32 gdr_size:16;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define MAX_BURST_SIZE_32 0
+#define MAX_BURST_SIZE_64 1
+#define MAX_BURST_SIZE_128 2
+#define MAX_BURST_SIZE_256 3
+
+/* gather descriptor control length */
+struct gd_ctl_len {
+ u32 len:16;
+ u32 rsv:14;
+ u32 done:1;
+ u32 ready:1;
+} __attribute__((packed));
+
+struct ce_gd {
+ u32 ptr;
+ struct gd_ctl_len ctl_len;
+} __attribute__((packed));
+
+struct sd_ctl {
+ u32 ctl:30;
+ u32 done:1;
+ u32 rdy:1;
+} __attribute__((packed));
+
+struct ce_sd {
+ u32 ptr;
+ struct sd_ctl ctl;
+} __attribute__((packed));
+
+#define PD_PAD_CTL_32 0x10
+#define PD_PAD_CTL_64 0x20
+#define PD_PAD_CTL_128 0x40
+#define PD_PAD_CTL_256 0x80
+union ce_pd_ctl {
+ struct {
+ u32 pd_pad_ctl:8;
+ u32 status:8;
+ u32 next_hdr:8;
+ u32 rsv:2;
+ u32 cached_sa:1;
+ u32 hash_final:1;
+ u32 init_arc4:1;
+ u32 rsv1:1;
+ u32 pe_done:1;
+ u32 host_ready:1;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+union ce_pd_ctl_len {
+ struct {
+ u32 bypass:8;
+ u32 pe_done:1;
+ u32 host_ready:1;
+ u32 rsv:2;
+ u32 pkt_len:20;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+struct ce_pd {
+ union ce_pd_ctl pd_ctl;
+ u32 src;
+ u32 dest;
+ u32 sa; /* get from ctx->sa_dma_addr */
+ u32 sa_len; /* only if dynamic sa is used */
+ union ce_pd_ctl_len pd_ctl_len;
+
+} __attribute__((packed));
+#endif
diff --git a/drivers/crypto/amcc/crypto4xx_sa.c b/drivers/crypto/amcc/crypto4xx_sa.c
new file mode 100644
index 000000000000..466fd94cd4a3
--- /dev/null
+++ b/drivers/crypto/amcc/crypto4xx_sa.c
@@ -0,0 +1,108 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * @file crypto4xx_sa.c
+ *
+ * This file implements the security context
+ * assoicate format.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mod_devicetable.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock_types.h>
+#include <linux/highmem.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+#include <crypto/algapi.h>
+#include <crypto/des.h>
+#include "crypto4xx_reg_def.h"
+#include "crypto4xx_sa.h"
+#include "crypto4xx_core.h"
+
+u32 get_dynamic_sa_offset_iv_field(struct crypto4xx_ctx *ctx)
+{
+ u32 offset;
+ union dynamic_sa_contents cts;
+
+ if (ctx->direction == DIR_INBOUND)
+ cts.w = ((struct dynamic_sa_ctl *)(ctx->sa_in))->sa_contents;
+ else
+ cts.w = ((struct dynamic_sa_ctl *)(ctx->sa_out))->sa_contents;
+ offset = cts.bf.key_size
+ + cts.bf.inner_size
+ + cts.bf.outer_size
+ + cts.bf.spi
+ + cts.bf.seq_num0
+ + cts.bf.seq_num1
+ + cts.bf.seq_num_mask0
+ + cts.bf.seq_num_mask1
+ + cts.bf.seq_num_mask2
+ + cts.bf.seq_num_mask3;
+
+ return sizeof(struct dynamic_sa_ctl) + offset * 4;
+}
+
+u32 get_dynamic_sa_offset_state_ptr_field(struct crypto4xx_ctx *ctx)
+{
+ u32 offset;
+ union dynamic_sa_contents cts;
+
+ if (ctx->direction == DIR_INBOUND)
+ cts.w = ((struct dynamic_sa_ctl *) ctx->sa_in)->sa_contents;
+ else
+ cts.w = ((struct dynamic_sa_ctl *) ctx->sa_out)->sa_contents;
+ offset = cts.bf.key_size
+ + cts.bf.inner_size
+ + cts.bf.outer_size
+ + cts.bf.spi
+ + cts.bf.seq_num0
+ + cts.bf.seq_num1
+ + cts.bf.seq_num_mask0
+ + cts.bf.seq_num_mask1
+ + cts.bf.seq_num_mask2
+ + cts.bf.seq_num_mask3
+ + cts.bf.iv0
+ + cts.bf.iv1
+ + cts.bf.iv2
+ + cts.bf.iv3;
+
+ return sizeof(struct dynamic_sa_ctl) + offset * 4;
+}
+
+u32 get_dynamic_sa_iv_size(struct crypto4xx_ctx *ctx)
+{
+ union dynamic_sa_contents cts;
+
+ if (ctx->direction == DIR_INBOUND)
+ cts.w = ((struct dynamic_sa_ctl *) ctx->sa_in)->sa_contents;
+ else
+ cts.w = ((struct dynamic_sa_ctl *) ctx->sa_out)->sa_contents;
+ return (cts.bf.iv0 + cts.bf.iv1 + cts.bf.iv2 + cts.bf.iv3) * 4;
+}
+
+u32 get_dynamic_sa_offset_key_field(struct crypto4xx_ctx *ctx)
+{
+ union dynamic_sa_contents cts;
+
+ if (ctx->direction == DIR_INBOUND)
+ cts.w = ((struct dynamic_sa_ctl *) ctx->sa_in)->sa_contents;
+ else
+ cts.w = ((struct dynamic_sa_ctl *) ctx->sa_out)->sa_contents;
+
+ return sizeof(struct dynamic_sa_ctl);
+}
diff --git a/drivers/crypto/amcc/crypto4xx_sa.h b/drivers/crypto/amcc/crypto4xx_sa.h
new file mode 100644
index 000000000000..4b83ed7e5570
--- /dev/null
+++ b/drivers/crypto/amcc/crypto4xx_sa.h
@@ -0,0 +1,243 @@
+/**
+ * AMCC SoC PPC4xx Crypto Driver
+ *
+ * Copyright (c) 2008 Applied Micro Circuits Corporation.
+ * All rights reserved. James Hsiao <jhsiao@amcc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This file defines the security context
+ * assoicate format.
+ */
+
+#ifndef __CRYPTO4XX_SA_H__
+#define __CRYPTO4XX_SA_H__
+
+#define AES_IV_SIZE 16
+
+/**
+ * Contents of Dynamic Security Association (SA) with all possible fields
+ */
+union dynamic_sa_contents {
+ struct {
+ u32 arc4_state_ptr:1;
+ u32 arc4_ij_ptr:1;
+ u32 state_ptr:1;
+ u32 iv3:1;
+ u32 iv2:1;
+ u32 iv1:1;
+ u32 iv0:1;
+ u32 seq_num_mask3:1;
+ u32 seq_num_mask2:1;
+ u32 seq_num_mask1:1;
+ u32 seq_num_mask0:1;
+ u32 seq_num1:1;
+ u32 seq_num0:1;
+ u32 spi:1;
+ u32 outer_size:5;
+ u32 inner_size:5;
+ u32 key_size:4;
+ u32 cmd_size:4;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define DIR_OUTBOUND 0
+#define DIR_INBOUND 1
+#define SA_OP_GROUP_BASIC 0
+#define SA_OPCODE_ENCRYPT 0
+#define SA_OPCODE_DECRYPT 0
+#define SA_OPCODE_HASH 3
+#define SA_CIPHER_ALG_DES 0
+#define SA_CIPHER_ALG_3DES 1
+#define SA_CIPHER_ALG_ARC4 2
+#define SA_CIPHER_ALG_AES 3
+#define SA_CIPHER_ALG_KASUMI 4
+#define SA_CIPHER_ALG_NULL 15
+
+#define SA_HASH_ALG_MD5 0
+#define SA_HASH_ALG_SHA1 1
+#define SA_HASH_ALG_NULL 15
+#define SA_HASH_ALG_SHA1_DIGEST_SIZE 20
+
+#define SA_LOAD_HASH_FROM_SA 0
+#define SA_LOAD_HASH_FROM_STATE 2
+#define SA_NOT_LOAD_HASH 3
+#define SA_LOAD_IV_FROM_SA 0
+#define SA_LOAD_IV_FROM_INPUT 1
+#define SA_LOAD_IV_FROM_STATE 2
+#define SA_LOAD_IV_GEN_IV 3
+
+#define SA_PAD_TYPE_CONSTANT 2
+#define SA_PAD_TYPE_ZERO 3
+#define SA_PAD_TYPE_TLS 5
+#define SA_PAD_TYPE_DTLS 5
+#define SA_NOT_SAVE_HASH 0
+#define SA_SAVE_HASH 1
+#define SA_NOT_SAVE_IV 0
+#define SA_SAVE_IV 1
+#define SA_HEADER_PROC 1
+#define SA_NO_HEADER_PROC 0
+
+union sa_command_0 {
+ struct {
+ u32 scatter:1;
+ u32 gather:1;
+ u32 save_hash_state:1;
+ u32 save_iv:1;
+ u32 load_hash_state:2;
+ u32 load_iv:2;
+ u32 digest_len:4;
+ u32 hdr_proc:1;
+ u32 extend_pad:1;
+ u32 stream_cipher_pad:1;
+ u32 rsv:1;
+ u32 hash_alg:4;
+ u32 cipher_alg:4;
+ u32 pad_type:2;
+ u32 op_group:2;
+ u32 dir:1;
+ u32 opcode:3;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+#define CRYPTO_MODE_ECB 0
+#define CRYPTO_MODE_CBC 1
+
+#define CRYPTO_FEEDBACK_MODE_NO_FB 0
+#define CRYPTO_FEEDBACK_MODE_64BIT_OFB 0
+#define CRYPTO_FEEDBACK_MODE_8BIT_CFB 1
+#define CRYPTO_FEEDBACK_MODE_1BIT_CFB 2
+#define CRYPTO_FEEDBACK_MODE_128BIT_CFB 3
+
+#define SA_AES_KEY_LEN_128 2
+#define SA_AES_KEY_LEN_192 3
+#define SA_AES_KEY_LEN_256 4
+
+#define SA_REV2 1
+/**
+ * The follow defines bits sa_command_1
+ * In Basic hash mode this bit define simple hash or hmac.
+ * In IPsec mode, this bit define muting control.
+ */
+#define SA_HASH_MODE_HASH 0
+#define SA_HASH_MODE_HMAC 1
+#define SA_MC_ENABLE 0
+#define SA_MC_DISABLE 1
+#define SA_NOT_COPY_HDR 0
+#define SA_COPY_HDR 1
+#define SA_NOT_COPY_PAD 0
+#define SA_COPY_PAD 1
+#define SA_NOT_COPY_PAYLOAD 0
+#define SA_COPY_PAYLOAD 1
+#define SA_EXTENDED_SN_OFF 0
+#define SA_EXTENDED_SN_ON 1
+#define SA_SEQ_MASK_OFF 0
+#define SA_SEQ_MASK_ON 1
+
+union sa_command_1 {
+ struct {
+ u32 crypto_mode31:1;
+ u32 save_arc4_state:1;
+ u32 arc4_stateful:1;
+ u32 key_len:5;
+ u32 hash_crypto_offset:8;
+ u32 sa_rev:2;
+ u32 byte_offset:1;
+ u32 hmac_muting:1;
+ u32 feedback_mode:2;
+ u32 crypto_mode9_8:2;
+ u32 extended_seq_num:1;
+ u32 seq_num_mask:1;
+ u32 mutable_bit_proc:1;
+ u32 ip_version:1;
+ u32 copy_pad:1;
+ u32 copy_payload:1;
+ u32 copy_hdr:1;
+ u32 rsv1:1;
+ } bf;
+ u32 w;
+} __attribute__((packed));
+
+struct dynamic_sa_ctl {
+ u32 sa_contents;
+ union sa_command_0 sa_command_0;
+ union sa_command_1 sa_command_1;
+} __attribute__((packed));
+
+/**
+ * State Record for Security Association (SA)
+ */
+struct sa_state_record {
+ u32 save_iv[4];
+ u32 save_hash_byte_cnt[2];
+ u32 save_digest[16];
+} __attribute__((packed));
+
+/**
+ * Security Association (SA) for AES128
+ *
+ */
+struct dynamic_sa_aes128 {
+ struct dynamic_sa_ctl ctrl;
+ u32 key[4];
+ u32 iv[4]; /* for CBC, OFC, and CFB mode */
+ u32 state_ptr;
+ u32 reserved;
+} __attribute__((packed));
+
+#define SA_AES128_LEN (sizeof(struct dynamic_sa_aes128)/4)
+#define SA_AES128_CONTENTS 0x3e000042
+
+/*
+ * Security Association (SA) for AES192
+ */
+struct dynamic_sa_aes192 {
+ struct dynamic_sa_ctl ctrl;
+ u32 key[6];
+ u32 iv[4]; /* for CBC, OFC, and CFB mode */
+ u32 state_ptr;
+ u32 reserved;
+} __attribute__((packed));
+
+#define SA_AES192_LEN (sizeof(struct dynamic_sa_aes192)/4)
+#define SA_AES192_CONTENTS 0x3e000062
+
+/**
+ * Security Association (SA) for AES256
+ */
+struct dynamic_sa_aes256 {
+ struct dynamic_sa_ctl ctrl;
+ u32 key[8];
+ u32 iv[4]; /* for CBC, OFC, and CFB mode */
+ u32 state_ptr;
+ u32 reserved;
+} __attribute__((packed));
+
+#define SA_AES256_LEN (sizeof(struct dynamic_sa_aes256)/4)
+#define SA_AES256_CONTENTS 0x3e000082
+#define SA_AES_CONTENTS 0x3e000002
+
+/**
+ * Security Association (SA) for HASH160: HMAC-SHA1
+ */
+struct dynamic_sa_hash160 {
+ struct dynamic_sa_ctl ctrl;
+ u32 inner_digest[5];
+ u32 outer_digest[5];
+ u32 state_ptr;
+ u32 reserved;
+} __attribute__((packed));
+#define SA_HASH160_LEN (sizeof(struct dynamic_sa_hash160)/4)
+#define SA_HASH160_CONTENTS 0x2000a502
+
+#endif
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index 0c79fe7f1567..4d85402a9e4a 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -1882,7 +1882,7 @@ static void hifn_clear_rings(struct hifn_device *dev, int error)
static void hifn_work(struct work_struct *work)
{
- struct delayed_work *dw = container_of(work, struct delayed_work, work);
+ struct delayed_work *dw = to_delayed_work(work);
struct hifn_device *dev = container_of(dw, struct hifn_device, work);
unsigned long flags;
int reset = 0;
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index d9e751be8c5f..af9761ccf9f1 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -101,6 +101,7 @@ struct buffer_desc {
u32 phys_addr;
u32 __reserved[4];
struct buffer_desc *next;
+ enum dma_data_direction dir;
};
struct crypt_ctl {
@@ -132,14 +133,10 @@ struct crypt_ctl {
struct ablk_ctx {
struct buffer_desc *src;
struct buffer_desc *dst;
- unsigned src_nents;
- unsigned dst_nents;
};
struct aead_ctx {
struct buffer_desc *buffer;
- unsigned short assoc_nents;
- unsigned short src_nents;
struct scatterlist ivlist;
/* used when the hmac is not on one sg entry */
u8 *hmac_virt;
@@ -312,7 +309,7 @@ static struct crypt_ctl *get_crypt_desc_emerg(void)
}
}
-static void free_buf_chain(struct buffer_desc *buf, u32 phys)
+static void free_buf_chain(struct device *dev, struct buffer_desc *buf,u32 phys)
{
while (buf) {
struct buffer_desc *buf1;
@@ -320,6 +317,7 @@ static void free_buf_chain(struct buffer_desc *buf, u32 phys)
buf1 = buf->next;
phys1 = buf->phys_next;
+ dma_unmap_single(dev, buf->phys_next, buf->buf_len, buf->dir);
dma_pool_free(buffer_pool, buf, phys);
buf = buf1;
phys = phys1;
@@ -348,7 +346,6 @@ static void one_packet(dma_addr_t phys)
struct crypt_ctl *crypt;
struct ixp_ctx *ctx;
int failed;
- enum dma_data_direction src_direction = DMA_BIDIRECTIONAL;
failed = phys & 0x1 ? -EBADMSG : 0;
phys &= ~0x3;
@@ -358,13 +355,8 @@ static void one_packet(dma_addr_t phys)
case CTL_FLAG_PERFORM_AEAD: {
struct aead_request *req = crypt->data.aead_req;
struct aead_ctx *req_ctx = aead_request_ctx(req);
- dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents,
- DMA_TO_DEVICE);
- dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
- dma_unmap_sg(dev, req->src, req_ctx->src_nents,
- DMA_BIDIRECTIONAL);
- free_buf_chain(req_ctx->buffer, crypt->src_buf);
+ free_buf_chain(dev, req_ctx->buffer, crypt->src_buf);
if (req_ctx->hmac_virt) {
finish_scattered_hmac(crypt);
}
@@ -374,16 +366,11 @@ static void one_packet(dma_addr_t phys)
case CTL_FLAG_PERFORM_ABLK: {
struct ablkcipher_request *req = crypt->data.ablk_req;
struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req);
- int nents;
+
if (req_ctx->dst) {
- nents = req_ctx->dst_nents;
- dma_unmap_sg(dev, req->dst, nents, DMA_FROM_DEVICE);
- free_buf_chain(req_ctx->dst, crypt->dst_buf);
- src_direction = DMA_TO_DEVICE;
+ free_buf_chain(dev, req_ctx->dst, crypt->dst_buf);
}
- nents = req_ctx->src_nents;
- dma_unmap_sg(dev, req->src, nents, src_direction);
- free_buf_chain(req_ctx->src, crypt->src_buf);
+ free_buf_chain(dev, req_ctx->src, crypt->src_buf);
req->base.complete(&req->base, failed);
break;
}
@@ -750,56 +737,35 @@ static int setup_cipher(struct crypto_tfm *tfm, int encrypt,
return 0;
}
-static int count_sg(struct scatterlist *sg, int nbytes)
+static struct buffer_desc *chainup_buffers(struct device *dev,
+ struct scatterlist *sg, unsigned nbytes,
+ struct buffer_desc *buf, gfp_t flags,
+ enum dma_data_direction dir)
{
- int i;
- for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
- nbytes -= sg->length;
- return i;
-}
-
-static struct buffer_desc *chainup_buffers(struct scatterlist *sg,
- unsigned nbytes, struct buffer_desc *buf, gfp_t flags)
-{
- int nents = 0;
-
- while (nbytes > 0) {
+ for (;nbytes > 0; sg = scatterwalk_sg_next(sg)) {
+ unsigned len = min(nbytes, sg->length);
struct buffer_desc *next_buf;
u32 next_buf_phys;
- unsigned len = min(nbytes, sg_dma_len(sg));
+ void *ptr;
- nents++;
nbytes -= len;
- if (!buf->phys_addr) {
- buf->phys_addr = sg_dma_address(sg);
- buf->buf_len = len;
- buf->next = NULL;
- buf->phys_next = 0;
- goto next;
- }
- /* Two consecutive chunks on one page may be handled by the old
- * buffer descriptor, increased by the length of the new one
- */
- if (sg_dma_address(sg) == buf->phys_addr + buf->buf_len) {
- buf->buf_len += len;
- goto next;
- }
+ ptr = page_address(sg_page(sg)) + sg->offset;
next_buf = dma_pool_alloc(buffer_pool, flags, &next_buf_phys);
- if (!next_buf)
- return NULL;
+ if (!next_buf) {
+ buf = NULL;
+ break;
+ }
+ sg_dma_address(sg) = dma_map_single(dev, ptr, len, dir);
buf->next = next_buf;
buf->phys_next = next_buf_phys;
-
buf = next_buf;
- buf->next = NULL;
- buf->phys_next = 0;
+
buf->phys_addr = sg_dma_address(sg);
buf->buf_len = len;
-next:
- if (nbytes > 0) {
- sg = sg_next(sg);
- }
+ buf->dir = dir;
}
+ buf->next = NULL;
+ buf->phys_next = 0;
return buf;
}
@@ -860,12 +826,12 @@ static int ablk_perform(struct ablkcipher_request *req, int encrypt)
struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
struct ixp_ctx *ctx = crypto_ablkcipher_ctx(tfm);
unsigned ivsize = crypto_ablkcipher_ivsize(tfm);
- int ret = -ENOMEM;
struct ix_sa_dir *dir;
struct crypt_ctl *crypt;
- unsigned int nbytes = req->nbytes, nents;
+ unsigned int nbytes = req->nbytes;
enum dma_data_direction src_direction = DMA_BIDIRECTIONAL;
struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req);
+ struct buffer_desc src_hook;
gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
GFP_KERNEL : GFP_ATOMIC;
@@ -878,7 +844,7 @@ static int ablk_perform(struct ablkcipher_request *req, int encrypt)
crypt = get_crypt_desc();
if (!crypt)
- return ret;
+ return -ENOMEM;
crypt->data.ablk_req = req;
crypt->crypto_ctx = dir->npe_ctx_phys;
@@ -891,53 +857,41 @@ static int ablk_perform(struct ablkcipher_request *req, int encrypt)
BUG_ON(ivsize && !req->info);
memcpy(crypt->iv, req->info, ivsize);
if (req->src != req->dst) {
+ struct buffer_desc dst_hook;
crypt->mode |= NPE_OP_NOT_IN_PLACE;
- nents = count_sg(req->dst, nbytes);
/* This was never tested by Intel
* for more than one dst buffer, I think. */
- BUG_ON(nents != 1);
- req_ctx->dst_nents = nents;
- dma_map_sg(dev, req->dst, nents, DMA_FROM_DEVICE);
- req_ctx->dst = dma_pool_alloc(buffer_pool, flags,&crypt->dst_buf);
- if (!req_ctx->dst)
- goto unmap_sg_dest;
- req_ctx->dst->phys_addr = 0;
- if (!chainup_buffers(req->dst, nbytes, req_ctx->dst, flags))
+ BUG_ON(req->dst->length < nbytes);
+ req_ctx->dst = NULL;
+ if (!chainup_buffers(dev, req->dst, nbytes, &dst_hook,
+ flags, DMA_FROM_DEVICE))
goto free_buf_dest;
src_direction = DMA_TO_DEVICE;
+ req_ctx->dst = dst_hook.next;
+ crypt->dst_buf = dst_hook.phys_next;
} else {
req_ctx->dst = NULL;
- req_ctx->dst_nents = 0;
}
- nents = count_sg(req->src, nbytes);
- req_ctx->src_nents = nents;
- dma_map_sg(dev, req->src, nents, src_direction);
-
- req_ctx->src = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf);
- if (!req_ctx->src)
- goto unmap_sg_src;
- req_ctx->src->phys_addr = 0;
- if (!chainup_buffers(req->src, nbytes, req_ctx->src, flags))
+ req_ctx->src = NULL;
+ if (!chainup_buffers(dev, req->src, nbytes, &src_hook,
+ flags, src_direction))
goto free_buf_src;
+ req_ctx->src = src_hook.next;
+ crypt->src_buf = src_hook.phys_next;
crypt->ctl_flags |= CTL_FLAG_PERFORM_ABLK;
qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt));
BUG_ON(qmgr_stat_overflow(SEND_QID));
return -EINPROGRESS;
free_buf_src:
- free_buf_chain(req_ctx->src, crypt->src_buf);
-unmap_sg_src:
- dma_unmap_sg(dev, req->src, req_ctx->src_nents, src_direction);
+ free_buf_chain(dev, req_ctx->src, crypt->src_buf);
free_buf_dest:
if (req->src != req->dst) {
- free_buf_chain(req_ctx->dst, crypt->dst_buf);
-unmap_sg_dest:
- dma_unmap_sg(dev, req->src, req_ctx->dst_nents,
- DMA_FROM_DEVICE);
+ free_buf_chain(dev, req_ctx->dst, crypt->dst_buf);
}
crypt->ctl_flags = CTL_FLAG_UNUSED;
- return ret;
+ return -ENOMEM;
}
static int ablk_encrypt(struct ablkcipher_request *req)
@@ -985,7 +939,7 @@ static int hmac_inconsistent(struct scatterlist *sg, unsigned start,
break;
offset += sg->length;
- sg = sg_next(sg);
+ sg = scatterwalk_sg_next(sg);
}
return (start + nbytes > offset + sg->length);
}
@@ -997,11 +951,10 @@ static int aead_perform(struct aead_request *req, int encrypt,
struct ixp_ctx *ctx = crypto_aead_ctx(tfm);
unsigned ivsize = crypto_aead_ivsize(tfm);
unsigned authsize = crypto_aead_authsize(tfm);
- int ret = -ENOMEM;
struct ix_sa_dir *dir;
struct crypt_ctl *crypt;
- unsigned int cryptlen, nents;
- struct buffer_desc *buf;
+ unsigned int cryptlen;
+ struct buffer_desc *buf, src_hook;
struct aead_ctx *req_ctx = aead_request_ctx(req);
gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
GFP_KERNEL : GFP_ATOMIC;
@@ -1022,7 +975,7 @@ static int aead_perform(struct aead_request *req, int encrypt,
}
crypt = get_crypt_desc();
if (!crypt)
- return ret;
+ return -ENOMEM;
crypt->data.aead_req = req;
crypt->crypto_ctx = dir->npe_ctx_phys;
@@ -1041,31 +994,27 @@ static int aead_perform(struct aead_request *req, int encrypt,
BUG(); /* -ENOTSUP because of my lazyness */
}
- req_ctx->buffer = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf);
- if (!req_ctx->buffer)
- goto out;
- req_ctx->buffer->phys_addr = 0;
/* ASSOC data */
- nents = count_sg(req->assoc, req->assoclen);
- req_ctx->assoc_nents = nents;
- dma_map_sg(dev, req->assoc, nents, DMA_TO_DEVICE);
- buf = chainup_buffers(req->assoc, req->assoclen, req_ctx->buffer,flags);
+ buf = chainup_buffers(dev, req->assoc, req->assoclen, &src_hook,
+ flags, DMA_TO_DEVICE);
+ req_ctx->buffer = src_hook.next;
+ crypt->src_buf = src_hook.phys_next;
if (!buf)
- goto unmap_sg_assoc;
+ goto out;
/* IV */
sg_init_table(&req_ctx->ivlist, 1);
sg_set_buf(&req_ctx->ivlist, iv, ivsize);
- dma_map_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
- buf = chainup_buffers(&req_ctx->ivlist, ivsize, buf, flags);
+ buf = chainup_buffers(dev, &req_ctx->ivlist, ivsize, buf, flags,
+ DMA_BIDIRECTIONAL);
if (!buf)
- goto unmap_sg_iv;
+ goto free_chain;
if (unlikely(hmac_inconsistent(req->src, cryptlen, authsize))) {
/* The 12 hmac bytes are scattered,
* we need to copy them into a safe buffer */
req_ctx->hmac_virt = dma_pool_alloc(buffer_pool, flags,
&crypt->icv_rev_aes);
if (unlikely(!req_ctx->hmac_virt))
- goto unmap_sg_iv;
+ goto free_chain;
if (!encrypt) {
scatterwalk_map_and_copy(req_ctx->hmac_virt,
req->src, cryptlen, authsize, 0);
@@ -1075,33 +1024,28 @@ static int aead_perform(struct aead_request *req, int encrypt,
req_ctx->hmac_virt = NULL;
}
/* Crypt */
- nents = count_sg(req->src, cryptlen + authsize);
- req_ctx->src_nents = nents;
- dma_map_sg(dev, req->src, nents, DMA_BIDIRECTIONAL);
- buf = chainup_buffers(req->src, cryptlen + authsize, buf, flags);
+ buf = chainup_buffers(dev, req->src, cryptlen + authsize, buf, flags,
+ DMA_BIDIRECTIONAL);
if (!buf)
- goto unmap_sg_src;
+ goto free_hmac_virt;
if (!req_ctx->hmac_virt) {
crypt->icv_rev_aes = buf->phys_addr + buf->buf_len - authsize;
}
+
crypt->ctl_flags |= CTL_FLAG_PERFORM_AEAD;
qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt));
BUG_ON(qmgr_stat_overflow(SEND_QID));
return -EINPROGRESS;
-unmap_sg_src:
- dma_unmap_sg(dev, req->src, req_ctx->src_nents, DMA_BIDIRECTIONAL);
+free_hmac_virt:
if (req_ctx->hmac_virt) {
dma_pool_free(buffer_pool, req_ctx->hmac_virt,
crypt->icv_rev_aes);
}
-unmap_sg_iv:
- dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
-unmap_sg_assoc:
- dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents, DMA_TO_DEVICE);
- free_buf_chain(req_ctx->buffer, crypt->src_buf);
+free_chain:
+ free_buf_chain(dev, req_ctx->buffer, crypt->src_buf);
out:
crypt->ctl_flags = CTL_FLAG_UNUSED;
- return ret;
+ return -ENOMEM;
}
static int aead_setup(struct crypto_aead *tfm, unsigned int authsize)
diff --git a/drivers/dca/dca-sysfs.c b/drivers/dca/dca-sysfs.c
index bb538b9690e0..ee916c9857ee 100644
--- a/drivers/dca/dca-sysfs.c
+++ b/drivers/dca/dca-sysfs.c
@@ -1,3 +1,24 @@
+/*
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called COPYING.
+ */
+
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/device.h>
diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c
index 10c3c498358c..55dd88d82d6d 100644
--- a/drivers/dio/dio.c
+++ b/drivers/dio/dio.c
@@ -182,7 +182,7 @@ static int __init dio_init(void)
/* Initialize the DIO bus */
INIT_LIST_HEAD(&dio_bus.devices);
- strcpy(dio_bus.dev.bus_id, "dio");
+ dev_set_name(&dio_bus.dev, "dio");
error = device_register(&dio_bus.dev);
if (error) {
pr_err("DIO: Error registering dio_bus\n");
@@ -237,7 +237,7 @@ static int __init dio_init(void)
dev->scode = scode;
dev->resource.start = pa;
dev->resource.end = pa + DIO_SIZE(scode, va);
- sprintf(dev->dev.bus_id,"%02x", scode);
+ dev_set_name(&dev->dev, "%02x", scode);
/* read the ID byte(s) and encode if necessary. */
prid = DIO_ID(va);
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 48ea59e79672..3b3c01b6f1ee 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -98,6 +98,17 @@ config NET_DMA
Say Y here if you enabled INTEL_IOATDMA or FSL_DMA, otherwise
say N.
+config ASYNC_TX_DMA
+ bool "Async_tx: Offload support for the async_tx api"
+ depends on DMA_ENGINE
+ help
+ This allows the async_tx api to take advantage of offload engines for
+ memcpy, memset, xor, and raid6 p+q operations. If your platform has
+ a dma engine that can perform raid operations and you have enabled
+ MD_RAID456 say Y.
+
+ If unsure, say N.
+
config DMATEST
tristate "DMA Test client"
depends on DMA_ENGINE
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 280a9d263eb3..92438e9dacc3 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -507,6 +507,7 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v
* published in the general-purpose allocator
*/
dma_cap_set(DMA_PRIVATE, device->cap_mask);
+ device->privatecnt++;
err = dma_chan_get(chan);
if (err == -ENODEV) {
@@ -518,6 +519,8 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v
dma_chan_name(chan), err);
else
break;
+ if (--device->privatecnt == 0)
+ dma_cap_clear(DMA_PRIVATE, device->cap_mask);
chan->private = NULL;
chan = NULL;
}
@@ -537,6 +540,9 @@ void dma_release_channel(struct dma_chan *chan)
WARN_ONCE(chan->client_count != 1,
"chan reference count %d != 1\n", chan->client_count);
dma_chan_put(chan);
+ /* drop PRIVATE cap enabled by __dma_request_channel() */
+ if (--chan->device->privatecnt == 0)
+ dma_cap_clear(DMA_PRIVATE, chan->device->cap_mask);
chan->private = NULL;
mutex_unlock(&dma_list_mutex);
}
@@ -602,6 +608,24 @@ void dmaengine_put(void)
}
EXPORT_SYMBOL(dmaengine_put);
+static int get_dma_id(struct dma_device *device)
+{
+ int rc;
+
+ idr_retry:
+ if (!idr_pre_get(&dma_idr, GFP_KERNEL))
+ return -ENOMEM;
+ mutex_lock(&dma_list_mutex);
+ rc = idr_get_new(&dma_idr, NULL, &device->dev_id);
+ mutex_unlock(&dma_list_mutex);
+ if (rc == -EAGAIN)
+ goto idr_retry;
+ else if (rc != 0)
+ return rc;
+
+ return 0;
+}
+
/**
* dma_async_device_register - registers DMA devices found
* @device: &dma_device
@@ -640,27 +664,25 @@ int dma_async_device_register(struct dma_device *device)
idr_ref = kmalloc(sizeof(*idr_ref), GFP_KERNEL);
if (!idr_ref)
return -ENOMEM;
- atomic_set(idr_ref, 0);
- idr_retry:
- if (!idr_pre_get(&dma_idr, GFP_KERNEL))
- return -ENOMEM;
- mutex_lock(&dma_list_mutex);
- rc = idr_get_new(&dma_idr, NULL, &device->dev_id);
- mutex_unlock(&dma_list_mutex);
- if (rc == -EAGAIN)
- goto idr_retry;
- else if (rc != 0)
+ rc = get_dma_id(device);
+ if (rc != 0) {
+ kfree(idr_ref);
return rc;
+ }
+
+ atomic_set(idr_ref, 0);
/* represent channels in sysfs. Probably want devs too */
list_for_each_entry(chan, &device->channels, device_node) {
+ rc = -ENOMEM;
chan->local = alloc_percpu(typeof(*chan->local));
if (chan->local == NULL)
- continue;
+ goto err_out;
chan->dev = kzalloc(sizeof(*chan->dev), GFP_KERNEL);
if (chan->dev == NULL) {
free_percpu(chan->local);
- continue;
+ chan->local = NULL;
+ goto err_out;
}
chan->chan_id = chancnt++;
@@ -677,6 +699,8 @@ int dma_async_device_register(struct dma_device *device)
if (rc) {
free_percpu(chan->local);
chan->local = NULL;
+ kfree(chan->dev);
+ atomic_dec(idr_ref);
goto err_out;
}
chan->client_count = 0;
@@ -701,12 +725,23 @@ int dma_async_device_register(struct dma_device *device)
}
}
list_add_tail_rcu(&device->global_node, &dma_device_list);
+ if (dma_has_cap(DMA_PRIVATE, device->cap_mask))
+ device->privatecnt++; /* Always private */
dma_channel_rebalance();
mutex_unlock(&dma_list_mutex);
return 0;
err_out:
+ /* if we never registered a channel just release the idr */
+ if (atomic_read(idr_ref) == 0) {
+ mutex_lock(&dma_list_mutex);
+ idr_remove(&dma_idr, device->dev_id);
+ mutex_unlock(&dma_list_mutex);
+ kfree(idr_ref);
+ return rc;
+ }
+
list_for_each_entry(chan, &device->channels, device_node) {
if (chan->local == NULL)
continue;
@@ -893,6 +928,7 @@ void dma_async_tx_descriptor_init(struct dma_async_tx_descriptor *tx,
{
tx->chan = chan;
spin_lock_init(&tx->lock);
+ INIT_LIST_HEAD(&tx->tx_list);
}
EXPORT_SYMBOL(dma_async_tx_descriptor_init);
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index e190d8b30700..a27c0fb1bc11 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -38,6 +38,11 @@ module_param(max_channels, uint, S_IRUGO);
MODULE_PARM_DESC(max_channels,
"Maximum number of channels to use (default: all)");
+static unsigned int xor_sources = 3;
+module_param(xor_sources, uint, S_IRUGO);
+MODULE_PARM_DESC(xor_sources,
+ "Number of xor source buffers (default: 3)");
+
/*
* Initialization patterns. All bytes in the source buffer has bit 7
* set, all bytes in the destination buffer has bit 7 cleared.
@@ -59,8 +64,9 @@ struct dmatest_thread {
struct list_head node;
struct task_struct *task;
struct dma_chan *chan;
- u8 *srcbuf;
- u8 *dstbuf;
+ u8 **srcs;
+ u8 **dsts;
+ enum dma_transaction_type type;
};
struct dmatest_chan {
@@ -98,30 +104,37 @@ static unsigned long dmatest_random(void)
return buf;
}
-static void dmatest_init_srcbuf(u8 *buf, unsigned int start, unsigned int len)
+static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len)
{
unsigned int i;
-
- for (i = 0; i < start; i++)
- buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
- for ( ; i < start + len; i++)
- buf[i] = PATTERN_SRC | PATTERN_COPY
- | (~i & PATTERN_COUNT_MASK);;
- for ( ; i < test_buf_size; i++)
- buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+ u8 *buf;
+
+ for (; (buf = *bufs); bufs++) {
+ for (i = 0; i < start; i++)
+ buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+ for ( ; i < start + len; i++)
+ buf[i] = PATTERN_SRC | PATTERN_COPY
+ | (~i & PATTERN_COUNT_MASK);;
+ for ( ; i < test_buf_size; i++)
+ buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+ buf++;
+ }
}
-static void dmatest_init_dstbuf(u8 *buf, unsigned int start, unsigned int len)
+static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len)
{
unsigned int i;
-
- for (i = 0; i < start; i++)
- buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
- for ( ; i < start + len; i++)
- buf[i] = PATTERN_DST | PATTERN_OVERWRITE
- | (~i & PATTERN_COUNT_MASK);
- for ( ; i < test_buf_size; i++)
- buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+ u8 *buf;
+
+ for (; (buf = *bufs); bufs++) {
+ for (i = 0; i < start; i++)
+ buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+ for ( ; i < start + len; i++)
+ buf[i] = PATTERN_DST | PATTERN_OVERWRITE
+ | (~i & PATTERN_COUNT_MASK);
+ for ( ; i < test_buf_size; i++)
+ buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+ }
}
static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
@@ -150,23 +163,30 @@ static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
thread_name, index, expected, actual);
}
-static unsigned int dmatest_verify(u8 *buf, unsigned int start,
+static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
unsigned int end, unsigned int counter, u8 pattern,
bool is_srcbuf)
{
unsigned int i;
unsigned int error_count = 0;
u8 actual;
-
- for (i = start; i < end; i++) {
- actual = buf[i];
- if (actual != (pattern | (~counter & PATTERN_COUNT_MASK))) {
- if (error_count < 32)
- dmatest_mismatch(actual, pattern, i, counter,
- is_srcbuf);
- error_count++;
+ u8 expected;
+ u8 *buf;
+ unsigned int counter_orig = counter;
+
+ for (; (buf = *bufs); bufs++) {
+ counter = counter_orig;
+ for (i = start; i < end; i++) {
+ actual = buf[i];
+ expected = pattern | (~counter & PATTERN_COUNT_MASK);
+ if (actual != expected) {
+ if (error_count < 32)
+ dmatest_mismatch(actual, pattern, i,
+ counter, is_srcbuf);
+ error_count++;
+ }
+ counter++;
}
- counter++;
}
if (error_count > 32)
@@ -176,12 +196,17 @@ static unsigned int dmatest_verify(u8 *buf, unsigned int start,
return error_count;
}
+static void dmatest_callback(void *completion)
+{
+ complete(completion);
+}
+
/*
* This function repeatedly tests DMA transfers of various lengths and
- * offsets until it is told to exit by kthread_stop(). There may be
- * multiple threads running this function in parallel for a single
- * channel, and there may be multiple channels being tested in
- * parallel.
+ * offsets for a given operation type until it is told to exit by
+ * kthread_stop(). There may be multiple threads running this function
+ * in parallel for a single channel, and there may be multiple channels
+ * being tested in parallel.
*
* Before each test, the source and destination buffer is initialized
* with a known pattern. This pattern is different depending on
@@ -201,25 +226,57 @@ static int dmatest_func(void *data)
unsigned int total_tests = 0;
dma_cookie_t cookie;
enum dma_status status;
+ enum dma_ctrl_flags flags;
int ret;
+ int src_cnt;
+ int dst_cnt;
+ int i;
thread_name = current->comm;
ret = -ENOMEM;
- thread->srcbuf = kmalloc(test_buf_size, GFP_KERNEL);
- if (!thread->srcbuf)
- goto err_srcbuf;
- thread->dstbuf = kmalloc(test_buf_size, GFP_KERNEL);
- if (!thread->dstbuf)
- goto err_dstbuf;
smp_rmb();
chan = thread->chan;
+ if (thread->type == DMA_MEMCPY)
+ src_cnt = dst_cnt = 1;
+ else if (thread->type == DMA_XOR) {
+ src_cnt = xor_sources | 1; /* force odd to ensure dst = src */
+ dst_cnt = 1;
+ } else
+ goto err_srcs;
+
+ thread->srcs = kcalloc(src_cnt+1, sizeof(u8 *), GFP_KERNEL);
+ if (!thread->srcs)
+ goto err_srcs;
+ for (i = 0; i < src_cnt; i++) {
+ thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL);
+ if (!thread->srcs[i])
+ goto err_srcbuf;
+ }
+ thread->srcs[i] = NULL;
+
+ thread->dsts = kcalloc(dst_cnt+1, sizeof(u8 *), GFP_KERNEL);
+ if (!thread->dsts)
+ goto err_dsts;
+ for (i = 0; i < dst_cnt; i++) {
+ thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL);
+ if (!thread->dsts[i])
+ goto err_dstbuf;
+ }
+ thread->dsts[i] = NULL;
+
+ set_user_nice(current, 10);
+
+ flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT;
while (!kthread_should_stop()) {
struct dma_device *dev = chan->device;
- struct dma_async_tx_descriptor *tx;
- dma_addr_t dma_src, dma_dest;
+ struct dma_async_tx_descriptor *tx = NULL;
+ dma_addr_t dma_srcs[src_cnt];
+ dma_addr_t dma_dsts[dst_cnt];
+ struct completion cmp;
+ unsigned long tmo = msecs_to_jiffies(3000);
total_tests++;
@@ -227,22 +284,41 @@ static int dmatest_func(void *data)
src_off = dmatest_random() % (test_buf_size - len + 1);
dst_off = dmatest_random() % (test_buf_size - len + 1);
- dmatest_init_srcbuf(thread->srcbuf, src_off, len);
- dmatest_init_dstbuf(thread->dstbuf, dst_off, len);
+ dmatest_init_srcs(thread->srcs, src_off, len);
+ dmatest_init_dsts(thread->dsts, dst_off, len);
- dma_src = dma_map_single(dev->dev, thread->srcbuf + src_off,
- len, DMA_TO_DEVICE);
+ for (i = 0; i < src_cnt; i++) {
+ u8 *buf = thread->srcs[i] + src_off;
+
+ dma_srcs[i] = dma_map_single(dev->dev, buf, len,
+ DMA_TO_DEVICE);
+ }
/* map with DMA_BIDIRECTIONAL to force writeback/invalidate */
- dma_dest = dma_map_single(dev->dev, thread->dstbuf,
- test_buf_size, DMA_BIDIRECTIONAL);
+ for (i = 0; i < dst_cnt; i++) {
+ dma_dsts[i] = dma_map_single(dev->dev, thread->dsts[i],
+ test_buf_size,
+ DMA_BIDIRECTIONAL);
+ }
+
+ if (thread->type == DMA_MEMCPY)
+ tx = dev->device_prep_dma_memcpy(chan,
+ dma_dsts[0] + dst_off,
+ dma_srcs[0], len,
+ flags);
+ else if (thread->type == DMA_XOR)
+ tx = dev->device_prep_dma_xor(chan,
+ dma_dsts[0] + dst_off,
+ dma_srcs, xor_sources,
+ len, flags);
- tx = dev->device_prep_dma_memcpy(chan, dma_dest + dst_off,
- dma_src, len,
- DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP);
if (!tx) {
- dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
- dma_unmap_single(dev->dev, dma_dest,
- test_buf_size, DMA_BIDIRECTIONAL);
+ for (i = 0; i < src_cnt; i++)
+ dma_unmap_single(dev->dev, dma_srcs[i], len,
+ DMA_TO_DEVICE);
+ for (i = 0; i < dst_cnt; i++)
+ dma_unmap_single(dev->dev, dma_dsts[i],
+ test_buf_size,
+ DMA_BIDIRECTIONAL);
pr_warning("%s: #%u: prep error with src_off=0x%x "
"dst_off=0x%x len=0x%x\n",
thread_name, total_tests - 1,
@@ -251,7 +327,10 @@ static int dmatest_func(void *data)
failed_tests++;
continue;
}
- tx->callback = NULL;
+
+ init_completion(&cmp);
+ tx->callback = dmatest_callback;
+ tx->callback_param = &cmp;
cookie = tx->tx_submit(tx);
if (dma_submit_error(cookie)) {
@@ -263,44 +342,50 @@ static int dmatest_func(void *data)
failed_tests++;
continue;
}
- dma_async_memcpy_issue_pending(chan);
+ dma_async_issue_pending(chan);
- do {
- msleep(1);
- status = dma_async_memcpy_complete(
- chan, cookie, NULL, NULL);
- } while (status == DMA_IN_PROGRESS);
+ tmo = wait_for_completion_timeout(&cmp, tmo);
+ status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
- if (status == DMA_ERROR) {
- pr_warning("%s: #%u: error during copy\n",
- thread_name, total_tests - 1);
+ if (tmo == 0) {
+ pr_warning("%s: #%u: test timed out\n",
+ thread_name, total_tests - 1);
+ failed_tests++;
+ continue;
+ } else if (status != DMA_SUCCESS) {
+ pr_warning("%s: #%u: got completion callback,"
+ " but status is \'%s\'\n",
+ thread_name, total_tests - 1,
+ status == DMA_ERROR ? "error" : "in progress");
failed_tests++;
continue;
}
+
/* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */
- dma_unmap_single(dev->dev, dma_dest,
- test_buf_size, DMA_BIDIRECTIONAL);
+ for (i = 0; i < dst_cnt; i++)
+ dma_unmap_single(dev->dev, dma_dsts[i], test_buf_size,
+ DMA_BIDIRECTIONAL);
error_count = 0;
pr_debug("%s: verifying source buffer...\n", thread_name);
- error_count += dmatest_verify(thread->srcbuf, 0, src_off,
+ error_count += dmatest_verify(thread->srcs, 0, src_off,
0, PATTERN_SRC, true);
- error_count += dmatest_verify(thread->srcbuf, src_off,
+ error_count += dmatest_verify(thread->srcs, src_off,
src_off + len, src_off,
PATTERN_SRC | PATTERN_COPY, true);
- error_count += dmatest_verify(thread->srcbuf, src_off + len,
+ error_count += dmatest_verify(thread->srcs, src_off + len,
test_buf_size, src_off + len,
PATTERN_SRC, true);
pr_debug("%s: verifying dest buffer...\n",
thread->task->comm);
- error_count += dmatest_verify(thread->dstbuf, 0, dst_off,
+ error_count += dmatest_verify(thread->dsts, 0, dst_off,
0, PATTERN_DST, false);
- error_count += dmatest_verify(thread->dstbuf, dst_off,
+ error_count += dmatest_verify(thread->dsts, dst_off,
dst_off + len, src_off,
PATTERN_SRC | PATTERN_COPY, false);
- error_count += dmatest_verify(thread->dstbuf, dst_off + len,
+ error_count += dmatest_verify(thread->dsts, dst_off + len,
test_buf_size, dst_off + len,
PATTERN_DST, false);
@@ -319,10 +404,16 @@ static int dmatest_func(void *data)
}
ret = 0;
- kfree(thread->dstbuf);
+ for (i = 0; thread->dsts[i]; i++)
+ kfree(thread->dsts[i]);
err_dstbuf:
- kfree(thread->srcbuf);
+ kfree(thread->dsts);
+err_dsts:
+ for (i = 0; thread->srcs[i]; i++)
+ kfree(thread->srcs[i]);
err_srcbuf:
+ kfree(thread->srcs);
+err_srcs:
pr_notice("%s: terminating after %u tests, %u failures (status %d)\n",
thread_name, total_tests, failed_tests, ret);
return ret;
@@ -344,35 +435,36 @@ static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
kfree(dtc);
}
-static int dmatest_add_channel(struct dma_chan *chan)
+static int dmatest_add_threads(struct dmatest_chan *dtc, enum dma_transaction_type type)
{
- struct dmatest_chan *dtc;
- struct dmatest_thread *thread;
- unsigned int i;
-
- dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
- if (!dtc) {
- pr_warning("dmatest: No memory for %s\n", dma_chan_name(chan));
- return -ENOMEM;
- }
+ struct dmatest_thread *thread;
+ struct dma_chan *chan = dtc->chan;
+ char *op;
+ unsigned int i;
- dtc->chan = chan;
- INIT_LIST_HEAD(&dtc->threads);
+ if (type == DMA_MEMCPY)
+ op = "copy";
+ else if (type == DMA_XOR)
+ op = "xor";
+ else
+ return -EINVAL;
for (i = 0; i < threads_per_chan; i++) {
thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL);
if (!thread) {
- pr_warning("dmatest: No memory for %s-test%u\n",
- dma_chan_name(chan), i);
+ pr_warning("dmatest: No memory for %s-%s%u\n",
+ dma_chan_name(chan), op, i);
+
break;
}
thread->chan = dtc->chan;
+ thread->type = type;
smp_wmb();
- thread->task = kthread_run(dmatest_func, thread, "%s-test%u",
- dma_chan_name(chan), i);
+ thread->task = kthread_run(dmatest_func, thread, "%s-%s%u",
+ dma_chan_name(chan), op, i);
if (IS_ERR(thread->task)) {
- pr_warning("dmatest: Failed to run thread %s-test%u\n",
- dma_chan_name(chan), i);
+ pr_warning("dmatest: Failed to run thread %s-%s%u\n",
+ dma_chan_name(chan), op, i);
kfree(thread);
break;
}
@@ -382,7 +474,36 @@ static int dmatest_add_channel(struct dma_chan *chan)
list_add_tail(&thread->node, &dtc->threads);
}
- pr_info("dmatest: Started %u threads using %s\n", i, dma_chan_name(chan));
+ return i;
+}
+
+static int dmatest_add_channel(struct dma_chan *chan)
+{
+ struct dmatest_chan *dtc;
+ struct dma_device *dma_dev = chan->device;
+ unsigned int thread_count = 0;
+ unsigned int cnt;
+
+ dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
+ if (!dtc) {
+ pr_warning("dmatest: No memory for %s\n", dma_chan_name(chan));
+ return -ENOMEM;
+ }
+
+ dtc->chan = chan;
+ INIT_LIST_HEAD(&dtc->threads);
+
+ if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
+ cnt = dmatest_add_threads(dtc, DMA_MEMCPY);
+ thread_count += cnt > 0 ?: 0;
+ }
+ if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
+ cnt = dmatest_add_threads(dtc, DMA_XOR);
+ thread_count += cnt > 0 ?: 0;
+ }
+
+ pr_info("dmatest: Started %u threads using %s\n",
+ thread_count, dma_chan_name(chan));
list_add_tail(&dtc->node, &dmatest_channels);
nr_channels++;
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index a97c07eef7ec..98c9a847bf51 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -363,6 +363,82 @@ static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc)
dwc_descriptor_complete(dwc, bad_desc);
}
+/* --------------------- Cyclic DMA API extensions -------------------- */
+
+inline dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ return channel_readl(dwc, SAR);
+}
+EXPORT_SYMBOL(dw_dma_get_src_addr);
+
+inline dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ return channel_readl(dwc, DAR);
+}
+EXPORT_SYMBOL(dw_dma_get_dst_addr);
+
+/* called with dwc->lock held and all DMAC interrupts disabled */
+static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
+ u32 status_block, u32 status_err, u32 status_xfer)
+{
+ if (status_block & dwc->mask) {
+ void (*callback)(void *param);
+ void *callback_param;
+
+ dev_vdbg(chan2dev(&dwc->chan), "new cyclic period llp 0x%08x\n",
+ channel_readl(dwc, LLP));
+ dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+
+ callback = dwc->cdesc->period_callback;
+ callback_param = dwc->cdesc->period_callback_param;
+ if (callback) {
+ spin_unlock(&dwc->lock);
+ callback(callback_param);
+ spin_lock(&dwc->lock);
+ }
+ }
+
+ /*
+ * Error and transfer complete are highly unlikely, and will most
+ * likely be due to a configuration error by the user.
+ */
+ if (unlikely(status_err & dwc->mask) ||
+ unlikely(status_xfer & dwc->mask)) {
+ int i;
+
+ dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s "
+ "interrupt, stopping DMA transfer\n",
+ status_xfer ? "xfer" : "error");
+ dev_err(chan2dev(&dwc->chan),
+ " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+ channel_readl(dwc, SAR),
+ channel_readl(dwc, DAR),
+ channel_readl(dwc, LLP),
+ channel_readl(dwc, CTL_HI),
+ channel_readl(dwc, CTL_LO));
+
+ channel_clear_bit(dw, CH_EN, dwc->mask);
+ while (dma_readl(dw, CH_EN) & dwc->mask)
+ cpu_relax();
+
+ /* make sure DMA does not restart by loading a new list */
+ channel_writel(dwc, LLP, 0);
+ channel_writel(dwc, CTL_LO, 0);
+ channel_writel(dwc, CTL_HI, 0);
+
+ dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+ dma_writel(dw, CLEAR.ERROR, dwc->mask);
+ dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+ for (i = 0; i < dwc->cdesc->periods; i++)
+ dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
static void dw_dma_tasklet(unsigned long data)
{
struct dw_dma *dw = (struct dw_dma *)data;
@@ -382,7 +458,10 @@ static void dw_dma_tasklet(unsigned long data)
for (i = 0; i < dw->dma.chancnt; i++) {
dwc = &dw->chan[i];
spin_lock(&dwc->lock);
- if (status_err & (1 << i))
+ if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags))
+ dwc_handle_cyclic(dw, dwc, status_block, status_err,
+ status_xfer);
+ else if (status_err & (1 << i))
dwc_handle_error(dw, dwc);
else if ((status_block | status_xfer) & (1 << i))
dwc_scan_descriptors(dw, dwc);
@@ -826,7 +905,6 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
dma_async_tx_descriptor_init(&desc->txd, chan);
desc->txd.tx_submit = dwc_tx_submit;
desc->txd.flags = DMA_CTRL_ACK;
- INIT_LIST_HEAD(&desc->txd.tx_list);
desc->txd.phys = dma_map_single(chan2parent(chan), &desc->lli,
sizeof(desc->lli), DMA_TO_DEVICE);
dwc_desc_put(dwc, desc);
@@ -884,6 +962,257 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
dev_vdbg(chan2dev(chan), "free_chan_resources done\n");
}
+/* --------------------- Cyclic DMA API extensions -------------------- */
+
+/**
+ * dw_dma_cyclic_start - start the cyclic DMA transfer
+ * @chan: the DMA channel to start
+ *
+ * Must be called with soft interrupts disabled. Returns zero on success or
+ * -errno on failure.
+ */
+int dw_dma_cyclic_start(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+
+ if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
+ dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n");
+ return -ENODEV;
+ }
+
+ spin_lock(&dwc->lock);
+
+ /* assert channel is idle */
+ if (dma_readl(dw, CH_EN) & dwc->mask) {
+ dev_err(chan2dev(&dwc->chan),
+ "BUG: Attempted to start non-idle channel\n");
+ dev_err(chan2dev(&dwc->chan),
+ " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+ channel_readl(dwc, SAR),
+ channel_readl(dwc, DAR),
+ channel_readl(dwc, LLP),
+ channel_readl(dwc, CTL_HI),
+ channel_readl(dwc, CTL_LO));
+ spin_unlock(&dwc->lock);
+ return -EBUSY;
+ }
+
+ dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+ dma_writel(dw, CLEAR.ERROR, dwc->mask);
+ dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+ /* setup DMAC channel registers */
+ channel_writel(dwc, LLP, dwc->cdesc->desc[0]->txd.phys);
+ channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
+ channel_writel(dwc, CTL_HI, 0);
+
+ channel_set_bit(dw, CH_EN, dwc->mask);
+
+ spin_unlock(&dwc->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(dw_dma_cyclic_start);
+
+/**
+ * dw_dma_cyclic_stop - stop the cyclic DMA transfer
+ * @chan: the DMA channel to stop
+ *
+ * Must be called with soft interrupts disabled.
+ */
+void dw_dma_cyclic_stop(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+
+ spin_lock(&dwc->lock);
+
+ channel_clear_bit(dw, CH_EN, dwc->mask);
+ while (dma_readl(dw, CH_EN) & dwc->mask)
+ cpu_relax();
+
+ spin_unlock(&dwc->lock);
+}
+EXPORT_SYMBOL(dw_dma_cyclic_stop);
+
+/**
+ * dw_dma_cyclic_prep - prepare the cyclic DMA transfer
+ * @chan: the DMA channel to prepare
+ * @buf_addr: physical DMA address where the buffer starts
+ * @buf_len: total number of bytes for the entire buffer
+ * @period_len: number of bytes for each period
+ * @direction: transfer direction, to or from device
+ *
+ * Must be called before trying to start the transfer. Returns a valid struct
+ * dw_cyclic_desc if successful or an ERR_PTR(-errno) if not successful.
+ */
+struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
+ dma_addr_t buf_addr, size_t buf_len, size_t period_len,
+ enum dma_data_direction direction)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_cyclic_desc *cdesc;
+ struct dw_cyclic_desc *retval = NULL;
+ struct dw_desc *desc;
+ struct dw_desc *last = NULL;
+ struct dw_dma_slave *dws = chan->private;
+ unsigned long was_cyclic;
+ unsigned int reg_width;
+ unsigned int periods;
+ unsigned int i;
+
+ spin_lock_bh(&dwc->lock);
+ if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) {
+ spin_unlock_bh(&dwc->lock);
+ dev_dbg(chan2dev(&dwc->chan),
+ "queue and/or active list are not empty\n");
+ return ERR_PTR(-EBUSY);
+ }
+
+ was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+ spin_unlock_bh(&dwc->lock);
+ if (was_cyclic) {
+ dev_dbg(chan2dev(&dwc->chan),
+ "channel already prepared for cyclic DMA\n");
+ return ERR_PTR(-EBUSY);
+ }
+
+ retval = ERR_PTR(-EINVAL);
+ reg_width = dws->reg_width;
+ periods = buf_len / period_len;
+
+ /* Check for too big/unaligned periods and unaligned DMA buffer. */
+ if (period_len > (DWC_MAX_COUNT << reg_width))
+ goto out_err;
+ if (unlikely(period_len & ((1 << reg_width) - 1)))
+ goto out_err;
+ if (unlikely(buf_addr & ((1 << reg_width) - 1)))
+ goto out_err;
+ if (unlikely(!(direction & (DMA_TO_DEVICE | DMA_FROM_DEVICE))))
+ goto out_err;
+
+ retval = ERR_PTR(-ENOMEM);
+
+ if (periods > NR_DESCS_PER_CHANNEL)
+ goto out_err;
+
+ cdesc = kzalloc(sizeof(struct dw_cyclic_desc), GFP_KERNEL);
+ if (!cdesc)
+ goto out_err;
+
+ cdesc->desc = kzalloc(sizeof(struct dw_desc *) * periods, GFP_KERNEL);
+ if (!cdesc->desc)
+ goto out_err_alloc;
+
+ for (i = 0; i < periods; i++) {
+ desc = dwc_desc_get(dwc);
+ if (!desc)
+ goto out_err_desc_get;
+
+ switch (direction) {
+ case DMA_TO_DEVICE:
+ desc->lli.dar = dws->tx_reg;
+ desc->lli.sar = buf_addr + (period_len * i);
+ desc->lli.ctllo = (DWC_DEFAULT_CTLLO
+ | DWC_CTLL_DST_WIDTH(reg_width)
+ | DWC_CTLL_SRC_WIDTH(reg_width)
+ | DWC_CTLL_DST_FIX
+ | DWC_CTLL_SRC_INC
+ | DWC_CTLL_FC_M2P
+ | DWC_CTLL_INT_EN);
+ break;
+ case DMA_FROM_DEVICE:
+ desc->lli.dar = buf_addr + (period_len * i);
+ desc->lli.sar = dws->rx_reg;
+ desc->lli.ctllo = (DWC_DEFAULT_CTLLO
+ | DWC_CTLL_SRC_WIDTH(reg_width)
+ | DWC_CTLL_DST_WIDTH(reg_width)
+ | DWC_CTLL_DST_INC
+ | DWC_CTLL_SRC_FIX
+ | DWC_CTLL_FC_P2M
+ | DWC_CTLL_INT_EN);
+ break;
+ default:
+ break;
+ }
+
+ desc->lli.ctlhi = (period_len >> reg_width);
+ cdesc->desc[i] = desc;
+
+ if (last) {
+ last->lli.llp = desc->txd.phys;
+ dma_sync_single_for_device(chan2parent(chan),
+ last->txd.phys, sizeof(last->lli),
+ DMA_TO_DEVICE);
+ }
+
+ last = desc;
+ }
+
+ /* lets make a cyclic list */
+ last->lli.llp = cdesc->desc[0]->txd.phys;
+ dma_sync_single_for_device(chan2parent(chan), last->txd.phys,
+ sizeof(last->lli), DMA_TO_DEVICE);
+
+ dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%08x len %zu "
+ "period %zu periods %d\n", buf_addr, buf_len,
+ period_len, periods);
+
+ cdesc->periods = periods;
+ dwc->cdesc = cdesc;
+
+ return cdesc;
+
+out_err_desc_get:
+ while (i--)
+ dwc_desc_put(dwc, cdesc->desc[i]);
+out_err_alloc:
+ kfree(cdesc);
+out_err:
+ clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+ return (struct dw_cyclic_desc *)retval;
+}
+EXPORT_SYMBOL(dw_dma_cyclic_prep);
+
+/**
+ * dw_dma_cyclic_free - free a prepared cyclic DMA transfer
+ * @chan: the DMA channel to free
+ */
+void dw_dma_cyclic_free(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+ struct dw_cyclic_desc *cdesc = dwc->cdesc;
+ int i;
+
+ dev_dbg(chan2dev(&dwc->chan), "cyclic free\n");
+
+ if (!cdesc)
+ return;
+
+ spin_lock_bh(&dwc->lock);
+
+ channel_clear_bit(dw, CH_EN, dwc->mask);
+ while (dma_readl(dw, CH_EN) & dwc->mask)
+ cpu_relax();
+
+ dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+ dma_writel(dw, CLEAR.ERROR, dwc->mask);
+ dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+ spin_unlock_bh(&dwc->lock);
+
+ for (i = 0; i < cdesc->periods; i++)
+ dwc_desc_put(dwc, cdesc->desc[i]);
+
+ kfree(cdesc->desc);
+ kfree(cdesc);
+
+ clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+}
+EXPORT_SYMBOL(dw_dma_cyclic_free);
+
/*----------------------------------------------------------------------*/
static void dw_dma_off(struct dw_dma *dw)
@@ -1011,7 +1340,7 @@ static int __init dw_probe(struct platform_device *pdev)
dma_writel(dw, CFG, DW_CFG_DMA_EN);
printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n",
- pdev->dev.bus_id, dw->dma.chancnt);
+ dev_name(&pdev->dev), dw->dma.chancnt);
dma_async_device_register(&dw->dma);
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index b252b202c5cf..13a580767031 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -126,6 +126,10 @@ struct dw_dma_regs {
#define DW_REGLEN 0x400
+enum dw_dmac_flags {
+ DW_DMA_IS_CYCLIC = 0,
+};
+
struct dw_dma_chan {
struct dma_chan chan;
void __iomem *ch_regs;
@@ -134,10 +138,12 @@ struct dw_dma_chan {
spinlock_t lock;
/* these other elements are all protected by lock */
+ unsigned long flags;
dma_cookie_t completed;
struct list_head active_list;
struct list_head queue;
struct list_head free_list;
+ struct dw_cyclic_desc *cdesc;
unsigned int descs_allocated;
};
@@ -158,7 +164,6 @@ static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan)
return container_of(chan, struct dw_dma_chan, chan);
}
-
struct dw_dma {
struct dma_device dma;
void __iomem *regs;
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 86d6da47f558..da8a8ed9e411 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -354,7 +354,6 @@ static struct fsl_desc_sw *fsl_dma_alloc_descriptor(
dma_async_tx_descriptor_init(&desc_sw->async_tx,
&fsl_chan->common);
desc_sw->async_tx.tx_submit = fsl_dma_tx_submit;
- INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
desc_sw->async_tx.phys = pdesc;
}
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index 5905cd36bcd2..e4fc33c1c32f 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -693,7 +693,6 @@ static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
desc_sw->async_tx.tx_submit = ioat2_tx_submit;
break;
}
- INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
desc_sw->hw = desc;
desc_sw->async_tx.phys = phys;
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 16adbe61cfb2..2f052265122f 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -498,7 +498,6 @@ static int iop_adma_alloc_chan_resources(struct dma_chan *chan)
slot->async_tx.tx_submit = iop_adma_tx_submit;
INIT_LIST_HEAD(&slot->chain_node);
INIT_LIST_HEAD(&slot->slot_node);
- INIT_LIST_HEAD(&slot->async_tx.tx_list);
hw_desc = (char *) iop_chan->device->dma_desc_pool;
slot->async_tx.phys =
(dma_addr_t) &hw_desc[idx * IOP_ADMA_SLOT_SIZE];
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index ae50a9d1a4e6..e202a6ce5573 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -28,6 +28,9 @@
#define FS_VF_IN_VALID 0x00000002
#define FS_ENC_IN_VALID 0x00000001
+static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
+ bool wait_for_stop);
+
/*
* There can be only one, we could allocate it dynamically, but then we'd have
* to add an extra parameter to some functions, and use something as ugly as
@@ -107,7 +110,7 @@ static uint32_t bytes_per_pixel(enum pixel_fmt fmt)
}
}
-/* Enable / disable direct write to memory by the Camera Sensor Interface */
+/* Enable direct write to memory by the Camera Sensor Interface */
static void ipu_ic_enable_task(struct ipu *ipu, enum ipu_channel channel)
{
uint32_t ic_conf, mask;
@@ -126,6 +129,7 @@ static void ipu_ic_enable_task(struct ipu *ipu, enum ipu_channel channel)
idmac_write_icreg(ipu, ic_conf, IC_CONF);
}
+/* Called under spin_lock_irqsave(&ipu_data.lock) */
static void ipu_ic_disable_task(struct ipu *ipu, enum ipu_channel channel)
{
uint32_t ic_conf, mask;
@@ -422,7 +426,7 @@ static void ipu_ch_param_set_size(union chan_param_mem *params,
break;
default:
dev_err(ipu_data.dev,
- "mxc ipu: unimplemented pixel format %d\n", pixel_fmt);
+ "mx3 ipu: unimplemented pixel format %d\n", pixel_fmt);
break;
}
@@ -433,20 +437,20 @@ static void ipu_ch_param_set_burst_size(union chan_param_mem *params,
uint16_t burst_pixels)
{
params->pp.npb = burst_pixels - 1;
-};
+}
static void ipu_ch_param_set_buffer(union chan_param_mem *params,
dma_addr_t buf0, dma_addr_t buf1)
{
params->pp.eba0 = buf0;
params->pp.eba1 = buf1;
-};
+}
static void ipu_ch_param_set_rotation(union chan_param_mem *params,
enum ipu_rotate_mode rotate)
{
params->pp.bam = rotate;
-};
+}
static void ipu_write_param_mem(uint32_t addr, uint32_t *data,
uint32_t num_words)
@@ -571,7 +575,7 @@ static uint32_t dma_param_addr(uint32_t dma_ch)
{
/* Channel Parameter Memory */
return 0x10000 | (dma_ch << 4);
-};
+}
static void ipu_channel_set_priority(struct ipu *ipu, enum ipu_channel channel,
bool prio)
@@ -611,7 +615,8 @@ static uint32_t ipu_channel_conf_mask(enum ipu_channel channel)
/**
* ipu_enable_channel() - enable an IPU channel.
- * @channel: channel ID.
+ * @idmac: IPU DMAC context.
+ * @ichan: IDMAC channel.
* @return: 0 on success or negative error code on failure.
*/
static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan)
@@ -649,7 +654,7 @@ static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan)
/**
* ipu_init_channel_buffer() - initialize a buffer for logical IPU channel.
- * @channel: channel ID.
+ * @ichan: IDMAC channel.
* @pixel_fmt: pixel format of buffer. Pixel format is a FOURCC ASCII code.
* @width: width of buffer in pixels.
* @height: height of buffer in pixels.
@@ -687,7 +692,7 @@ static int ipu_init_channel_buffer(struct idmac_channel *ichan,
}
/* IC channel's stride must be a multiple of 8 pixels */
- if ((channel <= 13) && (stride % 8)) {
+ if ((channel <= IDMAC_IC_13) && (stride % 8)) {
dev_err(ipu->dev, "Stride must be 8 pixel multiple\n");
return -EINVAL;
}
@@ -752,7 +757,7 @@ static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
/**
* ipu_update_channel_buffer() - update physical address of a channel buffer.
- * @channel: channel ID.
+ * @ichan: IDMAC channel.
* @buffer_n: buffer number to update.
* 0 or 1 are the only valid values.
* @phyaddr: buffer physical address.
@@ -760,9 +765,10 @@ static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
* function will fail if the buffer is set to ready.
*/
/* Called under spin_lock(_irqsave)(&ichan->lock) */
-static int ipu_update_channel_buffer(enum ipu_channel channel,
+static int ipu_update_channel_buffer(struct idmac_channel *ichan,
int buffer_n, dma_addr_t phyaddr)
{
+ enum ipu_channel channel = ichan->dma_chan.chan_id;
uint32_t reg;
unsigned long flags;
@@ -771,8 +777,8 @@ static int ipu_update_channel_buffer(enum ipu_channel channel,
if (buffer_n == 0) {
reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
if (reg & (1UL << channel)) {
- spin_unlock_irqrestore(&ipu_data.lock, flags);
- return -EACCES;
+ ipu_ic_disable_task(&ipu_data, channel);
+ ichan->status = IPU_CHANNEL_READY;
}
/* 44.3.3.1.9 - Row Number 1 (WORD1, offset 0) */
@@ -782,8 +788,8 @@ static int ipu_update_channel_buffer(enum ipu_channel channel,
} else {
reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
if (reg & (1UL << channel)) {
- spin_unlock_irqrestore(&ipu_data.lock, flags);
- return -EACCES;
+ ipu_ic_disable_task(&ipu_data, channel);
+ ichan->status = IPU_CHANNEL_READY;
}
/* Check if double-buffering is already enabled */
@@ -805,6 +811,39 @@ static int ipu_update_channel_buffer(enum ipu_channel channel,
}
/* Called under spin_lock_irqsave(&ichan->lock) */
+static int ipu_submit_buffer(struct idmac_channel *ichan,
+ struct idmac_tx_desc *desc, struct scatterlist *sg, int buf_idx)
+{
+ unsigned int chan_id = ichan->dma_chan.chan_id;
+ struct device *dev = &ichan->dma_chan.dev->device;
+ int ret;
+
+ if (async_tx_test_ack(&desc->txd))
+ return -EINTR;
+
+ /*
+ * On first invocation this shouldn't be necessary, the call to
+ * ipu_init_channel_buffer() above will set addresses for us, so we
+ * could make it conditional on status >= IPU_CHANNEL_ENABLED, but
+ * doing it again shouldn't hurt either.
+ */
+ ret = ipu_update_channel_buffer(ichan, buf_idx,
+ sg_dma_address(sg));
+
+ if (ret < 0) {
+ dev_err(dev, "Updating sg %p on channel 0x%x buffer %d failed!\n",
+ sg, chan_id, buf_idx);
+ return ret;
+ }
+
+ ipu_select_buffer(chan_id, buf_idx);
+ dev_dbg(dev, "Updated sg %p on channel 0x%x buffer %d\n",
+ sg, chan_id, buf_idx);
+
+ return 0;
+}
+
+/* Called under spin_lock_irqsave(&ichan->lock) */
static int ipu_submit_channel_buffers(struct idmac_channel *ichan,
struct idmac_tx_desc *desc)
{
@@ -815,20 +854,10 @@ static int ipu_submit_channel_buffers(struct idmac_channel *ichan,
if (!ichan->sg[i]) {
ichan->sg[i] = sg;
- /*
- * On first invocation this shouldn't be necessary, the
- * call to ipu_init_channel_buffer() above will set
- * addresses for us, so we could make it conditional
- * on status >= IPU_CHANNEL_ENABLED, but doing it again
- * shouldn't hurt either.
- */
- ret = ipu_update_channel_buffer(ichan->dma_chan.chan_id, i,
- sg_dma_address(sg));
+ ret = ipu_submit_buffer(ichan, desc, sg, i);
if (ret < 0)
return ret;
- ipu_select_buffer(ichan->dma_chan.chan_id, i);
-
sg = sg_next(sg);
}
}
@@ -842,19 +871,22 @@ static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
struct idmac_channel *ichan = to_idmac_chan(tx->chan);
struct idmac *idmac = to_idmac(tx->chan->device);
struct ipu *ipu = to_ipu(idmac);
+ struct device *dev = &ichan->dma_chan.dev->device;
dma_cookie_t cookie;
unsigned long flags;
+ int ret;
/* Sanity check */
if (!list_empty(&desc->list)) {
/* The descriptor doesn't belong to client */
- dev_err(&ichan->dma_chan.dev->device,
- "Descriptor %p not prepared!\n", tx);
+ dev_err(dev, "Descriptor %p not prepared!\n", tx);
return -EBUSY;
}
mutex_lock(&ichan->chan_mutex);
+ async_tx_clear_ack(tx);
+
if (ichan->status < IPU_CHANNEL_READY) {
struct idmac_video_param *video = &ichan->params.video;
/*
@@ -878,16 +910,7 @@ static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
goto out;
}
- /* ipu->lock can be taken under ichan->lock, but not v.v. */
- spin_lock_irqsave(&ichan->lock, flags);
-
- /* submit_buffers() atomically verifies and fills empty sg slots */
- cookie = ipu_submit_channel_buffers(ichan, desc);
-
- spin_unlock_irqrestore(&ichan->lock, flags);
-
- if (cookie < 0)
- goto out;
+ dev_dbg(dev, "Submitting sg %p\n", &desc->sg[0]);
cookie = ichan->dma_chan.cookie;
@@ -897,24 +920,40 @@ static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
/* from dmaengine.h: "last cookie value returned to client" */
ichan->dma_chan.cookie = cookie;
tx->cookie = cookie;
+
+ /* ipu->lock can be taken under ichan->lock, but not v.v. */
spin_lock_irqsave(&ichan->lock, flags);
+
list_add_tail(&desc->list, &ichan->queue);
+ /* submit_buffers() atomically verifies and fills empty sg slots */
+ ret = ipu_submit_channel_buffers(ichan, desc);
+
spin_unlock_irqrestore(&ichan->lock, flags);
+ if (ret < 0) {
+ cookie = ret;
+ goto dequeue;
+ }
+
if (ichan->status < IPU_CHANNEL_ENABLED) {
- int ret = ipu_enable_channel(idmac, ichan);
+ ret = ipu_enable_channel(idmac, ichan);
if (ret < 0) {
cookie = ret;
- spin_lock_irqsave(&ichan->lock, flags);
- list_del_init(&desc->list);
- spin_unlock_irqrestore(&ichan->lock, flags);
- tx->cookie = cookie;
- ichan->dma_chan.cookie = cookie;
+ goto dequeue;
}
}
dump_idmac_reg(ipu);
+dequeue:
+ if (cookie < 0) {
+ spin_lock_irqsave(&ichan->lock, flags);
+ list_del_init(&desc->list);
+ spin_unlock_irqrestore(&ichan->lock, flags);
+ tx->cookie = cookie;
+ ichan->dma_chan.cookie = cookie;
+ }
+
out:
mutex_unlock(&ichan->chan_mutex);
@@ -944,8 +983,6 @@ static int idmac_desc_alloc(struct idmac_channel *ichan, int n)
memset(txd, 0, sizeof(*txd));
dma_async_tx_descriptor_init(txd, &ichan->dma_chan);
txd->tx_submit = idmac_tx_submit;
- txd->chan = &ichan->dma_chan;
- INIT_LIST_HEAD(&txd->tx_list);
list_add(&desc->list, &ichan->free_list);
@@ -1161,6 +1198,24 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
return 0;
}
+static struct scatterlist *idmac_sg_next(struct idmac_channel *ichan,
+ struct idmac_tx_desc **desc, struct scatterlist *sg)
+{
+ struct scatterlist *sgnew = sg ? sg_next(sg) : NULL;
+
+ if (sgnew)
+ /* next sg-element in this list */
+ return sgnew;
+
+ if ((*desc)->list.next == &ichan->queue)
+ /* No more descriptors on the queue */
+ return NULL;
+
+ /* Fetch next descriptor */
+ *desc = list_entry((*desc)->list.next, struct idmac_tx_desc, list);
+ return (*desc)->sg;
+}
+
/*
* We have several possibilities here:
* current BUF next BUF
@@ -1176,23 +1231,46 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
static irqreturn_t idmac_interrupt(int irq, void *dev_id)
{
struct idmac_channel *ichan = dev_id;
+ struct device *dev = &ichan->dma_chan.dev->device;
unsigned int chan_id = ichan->dma_chan.chan_id;
struct scatterlist **sg, *sgnext, *sgnew = NULL;
/* Next transfer descriptor */
- struct idmac_tx_desc *desc = NULL, *descnew;
+ struct idmac_tx_desc *desc, *descnew;
dma_async_tx_callback callback;
void *callback_param;
bool done = false;
- u32 ready0 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY),
- ready1 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY),
- curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+ u32 ready0, ready1, curbuf, err;
+ unsigned long flags;
/* IDMAC has cleared the respective BUFx_RDY bit, we manage the buffer */
- pr_debug("IDMAC irq %d\n", irq);
+ dev_dbg(dev, "IDMAC irq %d, buf %d\n", irq, ichan->active_buffer);
+
+ spin_lock_irqsave(&ipu_data.lock, flags);
+
+ ready0 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
+ ready1 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
+ curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+ err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4);
+
+ if (err & (1 << chan_id)) {
+ idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4);
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
+ /*
+ * Doing this
+ * ichan->sg[0] = ichan->sg[1] = NULL;
+ * you can force channel re-enable on the next tx_submit(), but
+ * this is dirty - think about descriptors with multiple
+ * sg elements.
+ */
+ dev_warn(dev, "NFB4EOF on channel %d, ready %x, %x, cur %x\n",
+ chan_id, ready0, ready1, curbuf);
+ return IRQ_HANDLED;
+ }
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
+
/* Other interrupts do not interfere with this channel */
spin_lock(&ichan->lock);
-
if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 &&
((curbuf >> chan_id) & 1) == ichan->active_buffer)) {
int i = 100;
@@ -1207,19 +1285,23 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
if (!i) {
spin_unlock(&ichan->lock);
- dev_dbg(ichan->dma_chan.device->dev,
+ dev_dbg(dev,
"IRQ on active buffer on channel %x, active "
"%d, ready %x, %x, current %x!\n", chan_id,
ichan->active_buffer, ready0, ready1, curbuf);
return IRQ_NONE;
- }
+ } else
+ dev_dbg(dev,
+ "Buffer deactivated on channel %x, active "
+ "%d, ready %x, %x, current %x, rest %d!\n", chan_id,
+ ichan->active_buffer, ready0, ready1, curbuf, i);
}
if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) ||
(!ichan->active_buffer && (ready0 >> chan_id) & 1)
)) {
spin_unlock(&ichan->lock);
- dev_dbg(ichan->dma_chan.device->dev,
+ dev_dbg(dev,
"IRQ with active buffer still ready on channel %x, "
"active %d, ready %x, %x!\n", chan_id,
ichan->active_buffer, ready0, ready1);
@@ -1227,8 +1309,9 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
}
if (unlikely(list_empty(&ichan->queue))) {
+ ichan->sg[ichan->active_buffer] = NULL;
spin_unlock(&ichan->lock);
- dev_err(ichan->dma_chan.device->dev,
+ dev_err(dev,
"IRQ without queued buffers on channel %x, active %d, "
"ready %x, %x!\n", chan_id,
ichan->active_buffer, ready0, ready1);
@@ -1243,40 +1326,44 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
sg = &ichan->sg[ichan->active_buffer];
sgnext = ichan->sg[!ichan->active_buffer];
+ if (!*sg) {
+ spin_unlock(&ichan->lock);
+ return IRQ_HANDLED;
+ }
+
+ desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
+ descnew = desc;
+
+ dev_dbg(dev, "IDMAC irq %d, dma 0x%08x, next dma 0x%08x, current %d, curbuf 0x%08x\n",
+ irq, sg_dma_address(*sg), sgnext ? sg_dma_address(sgnext) : 0, ichan->active_buffer, curbuf);
+
+ /* Find the descriptor of sgnext */
+ sgnew = idmac_sg_next(ichan, &descnew, *sg);
+ if (sgnext != sgnew)
+ dev_err(dev, "Submitted buffer %p, next buffer %p\n", sgnext, sgnew);
+
/*
* if sgnext == NULL sg must be the last element in a scatterlist and
* queue must be empty
*/
if (unlikely(!sgnext)) {
- if (unlikely(sg_next(*sg))) {
- dev_err(ichan->dma_chan.device->dev,
- "Broken buffer-update locking on channel %x!\n",
- chan_id);
- /* We'll let the user catch up */
+ if (!WARN_ON(sg_next(*sg)))
+ dev_dbg(dev, "Underrun on channel %x\n", chan_id);
+ ichan->sg[!ichan->active_buffer] = sgnew;
+
+ if (unlikely(sgnew)) {
+ ipu_submit_buffer(ichan, descnew, sgnew, !ichan->active_buffer);
} else {
- /* Underrun */
+ spin_lock_irqsave(&ipu_data.lock, flags);
ipu_ic_disable_task(&ipu_data, chan_id);
- dev_dbg(ichan->dma_chan.device->dev,
- "Underrun on channel %x\n", chan_id);
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
ichan->status = IPU_CHANNEL_READY;
/* Continue to check for complete descriptor */
}
}
- desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
-
- /* First calculate and submit the next sg element */
- if (likely(sgnext))
- sgnew = sg_next(sgnext);
-
- if (unlikely(!sgnew)) {
- /* Start a new scatterlist, if any queued */
- if (likely(desc->list.next != &ichan->queue)) {
- descnew = list_entry(desc->list.next,
- struct idmac_tx_desc, list);
- sgnew = &descnew->sg[0];
- }
- }
+ /* Calculate and submit the next sg element */
+ sgnew = idmac_sg_next(ichan, &descnew, sgnew);
if (unlikely(!sg_next(*sg)) || !sgnext) {
/*
@@ -1289,17 +1376,13 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
*sg = sgnew;
- if (likely(sgnew)) {
- int ret;
-
- ret = ipu_update_channel_buffer(chan_id, ichan->active_buffer,
- sg_dma_address(*sg));
- if (ret < 0)
- dev_err(ichan->dma_chan.device->dev,
- "Failed to update buffer on channel %x buffer %d!\n",
- chan_id, ichan->active_buffer);
- else
- ipu_select_buffer(chan_id, ichan->active_buffer);
+ if (likely(sgnew) &&
+ ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) {
+ callback = desc->txd.callback;
+ callback_param = desc->txd.callback_param;
+ spin_unlock(&ichan->lock);
+ callback(callback_param);
+ spin_lock(&ichan->lock);
}
/* Flip the active buffer - even if update above failed */
@@ -1327,13 +1410,20 @@ static void ipu_gc_tasklet(unsigned long arg)
struct idmac_channel *ichan = ipu->channel + i;
struct idmac_tx_desc *desc;
unsigned long flags;
- int j;
+ struct scatterlist *sg;
+ int j, k;
for (j = 0; j < ichan->n_tx_desc; j++) {
desc = ichan->desc + j;
spin_lock_irqsave(&ichan->lock, flags);
if (async_tx_test_ack(&desc->txd)) {
list_move(&desc->list, &ichan->free_list);
+ for_each_sg(desc->sg, sg, desc->sg_len, k) {
+ if (ichan->sg[0] == sg)
+ ichan->sg[0] = NULL;
+ else if (ichan->sg[1] == sg)
+ ichan->sg[1] = NULL;
+ }
async_tx_clear_ack(&desc->txd);
}
spin_unlock_irqrestore(&ichan->lock, flags);
@@ -1341,13 +1431,7 @@ static void ipu_gc_tasklet(unsigned long arg)
}
}
-/*
- * At the time .device_alloc_chan_resources() method is called, we cannot know,
- * whether the client will accept the channel. Thus we must only check, if we
- * can satisfy client's request but the only real criterion to verify, whether
- * the client has accepted our offer is the client_count. That's why we have to
- * perform the rest of our allocation tasks on the first call to this function.
- */
+/* Allocate and initialise a transfer descriptor. */
static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan,
struct scatterlist *sgl, unsigned int sg_len,
enum dma_data_direction direction, unsigned long tx_flags)
@@ -1358,8 +1442,8 @@ static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan
unsigned long flags;
/* We only can handle these three channels so far */
- if (ichan->dma_chan.chan_id != IDMAC_SDC_0 && ichan->dma_chan.chan_id != IDMAC_SDC_1 &&
- ichan->dma_chan.chan_id != IDMAC_IC_7)
+ if (chan->chan_id != IDMAC_SDC_0 && chan->chan_id != IDMAC_SDC_1 &&
+ chan->chan_id != IDMAC_IC_7)
return NULL;
if (direction != DMA_FROM_DEVICE && direction != DMA_TO_DEVICE) {
@@ -1400,7 +1484,7 @@ static void idmac_issue_pending(struct dma_chan *chan)
/* This is not always needed, but doesn't hurt either */
spin_lock_irqsave(&ipu->lock, flags);
- ipu_select_buffer(ichan->dma_chan.chan_id, ichan->active_buffer);
+ ipu_select_buffer(chan->chan_id, ichan->active_buffer);
spin_unlock_irqrestore(&ipu->lock, flags);
/*
@@ -1432,8 +1516,7 @@ static void __idmac_terminate_all(struct dma_chan *chan)
struct idmac_tx_desc *desc = ichan->desc + i;
if (list_empty(&desc->list))
/* Descriptor was prepared, but not submitted */
- list_add(&desc->list,
- &ichan->free_list);
+ list_add(&desc->list, &ichan->free_list);
async_tx_clear_ack(&desc->txd);
}
@@ -1458,6 +1541,28 @@ static void idmac_terminate_all(struct dma_chan *chan)
mutex_unlock(&ichan->chan_mutex);
}
+#ifdef DEBUG
+static irqreturn_t ic_sof_irq(int irq, void *dev_id)
+{
+ struct idmac_channel *ichan = dev_id;
+ printk(KERN_DEBUG "Got SOF IRQ %d on Channel %d\n",
+ irq, ichan->dma_chan.chan_id);
+ disable_irq(irq);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t ic_eof_irq(int irq, void *dev_id)
+{
+ struct idmac_channel *ichan = dev_id;
+ printk(KERN_DEBUG "Got EOF IRQ %d on Channel %d\n",
+ irq, ichan->dma_chan.chan_id);
+ disable_irq(irq);
+ return IRQ_HANDLED;
+}
+
+static int ic_sof = -EINVAL, ic_eof = -EINVAL;
+#endif
+
static int idmac_alloc_chan_resources(struct dma_chan *chan)
{
struct idmac_channel *ichan = to_idmac_chan(chan);
@@ -1471,31 +1576,49 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan)
chan->cookie = 1;
ichan->completed = -ENXIO;
- ret = ipu_irq_map(ichan->dma_chan.chan_id);
+ ret = ipu_irq_map(chan->chan_id);
if (ret < 0)
goto eimap;
ichan->eof_irq = ret;
+
+ /*
+ * Important to first disable the channel, because maybe someone
+ * used it before us, e.g., the bootloader
+ */
+ ipu_disable_channel(idmac, ichan, true);
+
+ ret = ipu_init_channel(idmac, ichan);
+ if (ret < 0)
+ goto eichan;
+
ret = request_irq(ichan->eof_irq, idmac_interrupt, 0,
ichan->eof_name, ichan);
if (ret < 0)
goto erirq;
- ret = ipu_init_channel(idmac, ichan);
- if (ret < 0)
- goto eichan;
+#ifdef DEBUG
+ if (chan->chan_id == IDMAC_IC_7) {
+ ic_sof = ipu_irq_map(69);
+ if (ic_sof > 0)
+ request_irq(ic_sof, ic_sof_irq, 0, "IC SOF", ichan);
+ ic_eof = ipu_irq_map(70);
+ if (ic_eof > 0)
+ request_irq(ic_eof, ic_eof_irq, 0, "IC EOF", ichan);
+ }
+#endif
ichan->status = IPU_CHANNEL_INITIALIZED;
- dev_dbg(&ichan->dma_chan.dev->device, "Found channel 0x%x, irq %d\n",
- ichan->dma_chan.chan_id, ichan->eof_irq);
+ dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
+ chan->chan_id, ichan->eof_irq);
return ret;
-eichan:
- free_irq(ichan->eof_irq, ichan);
erirq:
- ipu_irq_unmap(ichan->dma_chan.chan_id);
+ ipu_uninit_channel(idmac, ichan);
+eichan:
+ ipu_irq_unmap(chan->chan_id);
eimap:
return ret;
}
@@ -1510,8 +1633,22 @@ static void idmac_free_chan_resources(struct dma_chan *chan)
__idmac_terminate_all(chan);
if (ichan->status > IPU_CHANNEL_FREE) {
+#ifdef DEBUG
+ if (chan->chan_id == IDMAC_IC_7) {
+ if (ic_sof > 0) {
+ free_irq(ic_sof, ichan);
+ ipu_irq_unmap(69);
+ ic_sof = -EINVAL;
+ }
+ if (ic_eof > 0) {
+ free_irq(ic_eof, ichan);
+ ipu_irq_unmap(70);
+ ic_eof = -EINVAL;
+ }
+ }
+#endif
free_irq(ichan->eof_irq, ichan);
- ipu_irq_unmap(ichan->dma_chan.chan_id);
+ ipu_irq_unmap(chan->chan_id);
}
ichan->status = IPU_CHANNEL_FREE;
@@ -1573,7 +1710,7 @@ static int __init ipu_idmac_init(struct ipu *ipu)
dma_chan->device = &idmac->dma;
dma_chan->cookie = 1;
dma_chan->chan_id = i;
- list_add_tail(&ichan->dma_chan.device_node, &dma->channels);
+ list_add_tail(&dma_chan->device_node, &dma->channels);
}
idmac_write_icreg(ipu, 0x00000070, IDMAC_CONF);
@@ -1581,7 +1718,7 @@ static int __init ipu_idmac_init(struct ipu *ipu)
return dma_async_device_register(&idmac->dma);
}
-static void ipu_idmac_exit(struct ipu *ipu)
+static void __exit ipu_idmac_exit(struct ipu *ipu)
{
int i;
struct idmac *idmac = &ipu->idmac;
@@ -1600,7 +1737,7 @@ static void ipu_idmac_exit(struct ipu *ipu)
* IPU common probe / remove
*/
-static int ipu_probe(struct platform_device *pdev)
+static int __init ipu_probe(struct platform_device *pdev)
{
struct ipu_platform_data *pdata = pdev->dev.platform_data;
struct resource *mem_ipu, *mem_ic;
@@ -1649,7 +1786,7 @@ static int ipu_probe(struct platform_device *pdev)
}
/* Get IPU clock */
- ipu_data.ipu_clk = clk_get(&pdev->dev, "ipu_clk");
+ ipu_data.ipu_clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(ipu_data.ipu_clk)) {
ret = PTR_ERR(ipu_data.ipu_clk);
goto err_clk_get;
@@ -1700,7 +1837,7 @@ err_noirq:
return ret;
}
-static int ipu_remove(struct platform_device *pdev)
+static int __exit ipu_remove(struct platform_device *pdev)
{
struct ipu *ipu = platform_get_drvdata(pdev);
@@ -1725,7 +1862,7 @@ static struct platform_driver ipu_platform_driver = {
.name = "ipu-core",
.owner = THIS_MODULE,
},
- .remove = ipu_remove,
+ .remove = __exit_p(ipu_remove),
};
static int __init ipu_init(void)
diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
index 83f532cc767f..dd8ebc75b667 100644
--- a/drivers/dma/ipu/ipu_irq.c
+++ b/drivers/dma/ipu/ipu_irq.c
@@ -352,7 +352,7 @@ static struct irq_chip ipu_irq_chip = {
};
/* Install the IRQ handler */
-int ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
+int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
{
struct ipu_platform_data *pdata = dev->dev.platform_data;
unsigned int irq, irq_base, i;
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index cb7f26fb9f18..ddab94f51224 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -632,7 +632,6 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
slot->async_tx.tx_submit = mv_xor_tx_submit;
INIT_LIST_HEAD(&slot->chain_node);
INIT_LIST_HEAD(&slot->slot_node);
- INIT_LIST_HEAD(&slot->async_tx.tx_list);
hw_desc = (char *) mv_chan->device->dma_desc_pool;
slot->async_tx.phys =
(dma_addr_t) &hw_desc[idx * MV_XOR_SLOT_SIZE];
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index eee47fd16d79..e5f5c5a8ba6c 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -1,13 +1,12 @@
#
# EDAC Kconfig
-# Copyright (c) 2003 Linux Networx
+# Copyright (c) 2008 Doug Thompson www.softwarebitmaker.com
# Licensed and distributed under the GPL
#
menuconfig EDAC
- bool "EDAC - error detection and reporting (EXPERIMENTAL)"
+ bool "EDAC - error detection and reporting"
depends on HAS_IOMEM
- depends on EXPERIMENTAL
depends on X86 || PPC
help
EDAC is designed to report errors in the core system.
@@ -40,6 +39,14 @@ config EDAC_DEBUG
there're four debug levels (x=0,1,2,3 from low to high).
Usually you should select 'N'.
+config EDAC_DEBUG_VERBOSE
+ bool "More verbose debugging"
+ depends on EDAC_DEBUG
+ help
+ This option makes debugging information more verbose.
+ Source file name and line number where debugging message
+ printed will be added to debugging message.
+
config EDAC_MM_EDAC
tristate "Main Memory EDAC (Error Detection And Correction) reporting"
default y
@@ -174,4 +181,27 @@ config EDAC_CELL
Cell Broadband Engine internal memory controller
on platform without a hypervisor
+config EDAC_PPC4XX
+ tristate "PPC4xx IBM DDR2 Memory Controller"
+ depends on EDAC_MM_EDAC && 4xx
+ help
+ This enables support for EDAC on the ECC memory used
+ with the IBM DDR2 memory controller found in various
+ PowerPC 4xx embedded processors such as the 405EX[r],
+ 440SP, 440SPe, 460EX, 460GT and 460SX.
+
+config EDAC_AMD8131
+ tristate "AMD8131 HyperTransport PCI-X Tunnel"
+ depends on EDAC_MM_EDAC && PCI
+ help
+ Support for error detection and correction on the
+ AMD8131 HyperTransport PCI-X Tunnel chip.
+
+config EDAC_AMD8111
+ tristate "AMD8111 HyperTransport I/O Hub"
+ depends on EDAC_MM_EDAC && PCI
+ help
+ Support for error detection and correction on the
+ AMD8111 HyperTransport I/O Hub chip.
+
endif # EDAC
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index b75196927de3..a5fdcf02f591 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -34,4 +34,4 @@ obj-$(CONFIG_EDAC_PASEMI) += pasemi_edac.o
obj-$(CONFIG_EDAC_MPC85XX) += mpc85xx_edac.o
obj-$(CONFIG_EDAC_MV64X60) += mv64x60_edac.o
obj-$(CONFIG_EDAC_CELL) += cell_edac.o
-
+obj-$(CONFIG_EDAC_PPC4XX) += ppc4xx_edac.o
diff --git a/drivers/edac/amd8111_edac.c b/drivers/edac/amd8111_edac.c
new file mode 100644
index 000000000000..614692181120
--- /dev/null
+++ b/drivers/edac/amd8111_edac.c
@@ -0,0 +1,595 @@
+/*
+ * amd8111_edac.c, AMD8111 Hyper Transport chip EDAC kernel module
+ *
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors: Cao Qingtao <qingtao.cao@windriver.com>
+ * Benjamin Walsh <benjamin.walsh@windriver.com>
+ * Hu Yongqi <yongqi.hu@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/edac.h>
+#include <linux/pci_ids.h>
+#include <asm/io.h>
+
+#include "edac_core.h"
+#include "edac_module.h"
+#include "amd8111_edac.h"
+
+#define AMD8111_EDAC_REVISION " Ver: 1.0.0 " __DATE__
+#define AMD8111_EDAC_MOD_STR "amd8111_edac"
+
+#define PCI_DEVICE_ID_AMD_8111_PCI 0x7460
+static int edac_dev_idx;
+
+enum amd8111_edac_devs {
+ LPC_BRIDGE = 0,
+};
+
+enum amd8111_edac_pcis {
+ PCI_BRIDGE = 0,
+};
+
+/* Wrapper functions for accessing PCI configuration space */
+static int edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32)
+{
+ int ret;
+
+ ret = pci_read_config_dword(dev, reg, val32);
+ if (ret != 0)
+ printk(KERN_ERR AMD8111_EDAC_MOD_STR
+ " PCI Access Read Error at 0x%x\n", reg);
+
+ return ret;
+}
+
+static void edac_pci_read_byte(struct pci_dev *dev, int reg, u8 *val8)
+{
+ int ret;
+
+ ret = pci_read_config_byte(dev, reg, val8);
+ if (ret != 0)
+ printk(KERN_ERR AMD8111_EDAC_MOD_STR
+ " PCI Access Read Error at 0x%x\n", reg);
+}
+
+static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32)
+{
+ int ret;
+
+ ret = pci_write_config_dword(dev, reg, val32);
+ if (ret != 0)
+ printk(KERN_ERR AMD8111_EDAC_MOD_STR
+ " PCI Access Write Error at 0x%x\n", reg);
+}
+
+static void edac_pci_write_byte(struct pci_dev *dev, int reg, u8 val8)
+{
+ int ret;
+
+ ret = pci_write_config_byte(dev, reg, val8);
+ if (ret != 0)
+ printk(KERN_ERR AMD8111_EDAC_MOD_STR
+ " PCI Access Write Error at 0x%x\n", reg);
+}
+
+/*
+ * device-specific methods for amd8111 PCI Bridge Controller
+ *
+ * Error Reporting and Handling for amd8111 chipset could be found
+ * in its datasheet 3.1.2 section, P37
+ */
+static void amd8111_pci_bridge_init(struct amd8111_pci_info *pci_info)
+{
+ u32 val32;
+ struct pci_dev *dev = pci_info->dev;
+
+ /* First clear error detection flags on the host interface */
+
+ /* Clear SSE/SMA/STA flags in the global status register*/
+ edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
+ if (val32 & PCI_STSCMD_CLEAR_MASK)
+ edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
+
+ /* Clear CRC and Link Fail flags in HT Link Control reg */
+ edac_pci_read_dword(dev, REG_HT_LINK, &val32);
+ if (val32 & HT_LINK_CLEAR_MASK)
+ edac_pci_write_dword(dev, REG_HT_LINK, val32);
+
+ /* Second clear all fault on the secondary interface */
+
+ /* Clear error flags in the memory-base limit reg. */
+ edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
+ if (val32 & MEM_LIMIT_CLEAR_MASK)
+ edac_pci_write_dword(dev, REG_MEM_LIM, val32);
+
+ /* Clear Discard Timer Expired flag in Interrupt/Bridge Control reg */
+ edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
+ if (val32 & PCI_INTBRG_CTRL_CLEAR_MASK)
+ edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
+
+ /* Last enable error detections */
+ if (edac_op_state == EDAC_OPSTATE_POLL) {
+ /* Enable System Error reporting in global status register */
+ edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
+ val32 |= PCI_STSCMD_SERREN;
+ edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
+
+ /* Enable CRC Sync flood packets to HyperTransport Link */
+ edac_pci_read_dword(dev, REG_HT_LINK, &val32);
+ val32 |= HT_LINK_CRCFEN;
+ edac_pci_write_dword(dev, REG_HT_LINK, val32);
+
+ /* Enable SSE reporting etc in Interrupt control reg */
+ edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
+ val32 |= PCI_INTBRG_CTRL_POLL_MASK;
+ edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
+ }
+}
+
+static void amd8111_pci_bridge_exit(struct amd8111_pci_info *pci_info)
+{
+ u32 val32;
+ struct pci_dev *dev = pci_info->dev;
+
+ if (edac_op_state == EDAC_OPSTATE_POLL) {
+ /* Disable System Error reporting */
+ edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
+ val32 &= ~PCI_STSCMD_SERREN;
+ edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
+
+ /* Disable CRC flood packets */
+ edac_pci_read_dword(dev, REG_HT_LINK, &val32);
+ val32 &= ~HT_LINK_CRCFEN;
+ edac_pci_write_dword(dev, REG_HT_LINK, val32);
+
+ /* Disable DTSERREN/MARSP/SERREN in Interrupt Control reg */
+ edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
+ val32 &= ~PCI_INTBRG_CTRL_POLL_MASK;
+ edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
+ }
+}
+
+static void amd8111_pci_bridge_check(struct edac_pci_ctl_info *edac_dev)
+{
+ struct amd8111_pci_info *pci_info = edac_dev->pvt_info;
+ struct pci_dev *dev = pci_info->dev;
+ u32 val32;
+
+ /* Check out PCI Bridge Status and Command Register */
+ edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
+ if (val32 & PCI_STSCMD_CLEAR_MASK) {
+ printk(KERN_INFO "Error(s) in PCI bridge status and command"
+ "register on device %s\n", pci_info->ctl_name);
+ printk(KERN_INFO "SSE: %d, RMA: %d, RTA: %d\n",
+ (val32 & PCI_STSCMD_SSE) != 0,
+ (val32 & PCI_STSCMD_RMA) != 0,
+ (val32 & PCI_STSCMD_RTA) != 0);
+
+ val32 |= PCI_STSCMD_CLEAR_MASK;
+ edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+
+ /* Check out HyperTransport Link Control Register */
+ edac_pci_read_dword(dev, REG_HT_LINK, &val32);
+ if (val32 & HT_LINK_LKFAIL) {
+ printk(KERN_INFO "Error(s) in hypertransport link control"
+ "register on device %s\n", pci_info->ctl_name);
+ printk(KERN_INFO "LKFAIL: %d\n",
+ (val32 & HT_LINK_LKFAIL) != 0);
+
+ val32 |= HT_LINK_LKFAIL;
+ edac_pci_write_dword(dev, REG_HT_LINK, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+
+ /* Check out PCI Interrupt and Bridge Control Register */
+ edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
+ if (val32 & PCI_INTBRG_CTRL_DTSTAT) {
+ printk(KERN_INFO "Error(s) in PCI interrupt and bridge control"
+ "register on device %s\n", pci_info->ctl_name);
+ printk(KERN_INFO "DTSTAT: %d\n",
+ (val32 & PCI_INTBRG_CTRL_DTSTAT) != 0);
+
+ val32 |= PCI_INTBRG_CTRL_DTSTAT;
+ edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+
+ /* Check out PCI Bridge Memory Base-Limit Register */
+ edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
+ if (val32 & MEM_LIMIT_CLEAR_MASK) {
+ printk(KERN_INFO
+ "Error(s) in mem limit register on %s device\n",
+ pci_info->ctl_name);
+ printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n"
+ "RTA: %d, STA: %d, MDPE: %d\n",
+ (val32 & MEM_LIMIT_DPE) != 0,
+ (val32 & MEM_LIMIT_RSE) != 0,
+ (val32 & MEM_LIMIT_RMA) != 0,
+ (val32 & MEM_LIMIT_RTA) != 0,
+ (val32 & MEM_LIMIT_STA) != 0,
+ (val32 & MEM_LIMIT_MDPE) != 0);
+
+ val32 |= MEM_LIMIT_CLEAR_MASK;
+ edac_pci_write_dword(dev, REG_MEM_LIM, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+}
+
+static struct resource *legacy_io_res;
+static int at_compat_reg_broken;
+#define LEGACY_NR_PORTS 1
+
+/* device-specific methods for amd8111 LPC Bridge device */
+static void amd8111_lpc_bridge_init(struct amd8111_dev_info *dev_info)
+{
+ u8 val8;
+ struct pci_dev *dev = dev_info->dev;
+
+ /* First clear REG_AT_COMPAT[SERR, IOCHK] if necessary */
+ legacy_io_res = request_region(REG_AT_COMPAT, LEGACY_NR_PORTS,
+ AMD8111_EDAC_MOD_STR);
+ if (!legacy_io_res)
+ printk(KERN_INFO "%s: failed to request legacy I/O region "
+ "start %d, len %d\n", __func__,
+ REG_AT_COMPAT, LEGACY_NR_PORTS);
+ else {
+ val8 = __do_inb(REG_AT_COMPAT);
+ if (val8 == 0xff) { /* buggy port */
+ printk(KERN_INFO "%s: port %d is buggy, not supported"
+ " by hardware?\n", __func__, REG_AT_COMPAT);
+ at_compat_reg_broken = 1;
+ release_region(REG_AT_COMPAT, LEGACY_NR_PORTS);
+ legacy_io_res = NULL;
+ } else {
+ u8 out8 = 0;
+ if (val8 & AT_COMPAT_SERR)
+ out8 = AT_COMPAT_CLRSERR;
+ if (val8 & AT_COMPAT_IOCHK)
+ out8 |= AT_COMPAT_CLRIOCHK;
+ if (out8 > 0)
+ __do_outb(out8, REG_AT_COMPAT);
+ }
+ }
+
+ /* Second clear error flags on LPC bridge */
+ edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8);
+ if (val8 & IO_CTRL_1_CLEAR_MASK)
+ edac_pci_write_byte(dev, REG_IO_CTRL_1, val8);
+}
+
+static void amd8111_lpc_bridge_exit(struct amd8111_dev_info *dev_info)
+{
+ if (legacy_io_res)
+ release_region(REG_AT_COMPAT, LEGACY_NR_PORTS);
+}
+
+static void amd8111_lpc_bridge_check(struct edac_device_ctl_info *edac_dev)
+{
+ struct amd8111_dev_info *dev_info = edac_dev->pvt_info;
+ struct pci_dev *dev = dev_info->dev;
+ u8 val8;
+
+ edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8);
+ if (val8 & IO_CTRL_1_CLEAR_MASK) {
+ printk(KERN_INFO
+ "Error(s) in IO control register on %s device\n",
+ dev_info->ctl_name);
+ printk(KERN_INFO "LPC ERR: %d, PW2LPC: %d\n",
+ (val8 & IO_CTRL_1_LPC_ERR) != 0,
+ (val8 & IO_CTRL_1_PW2LPC) != 0);
+
+ val8 |= IO_CTRL_1_CLEAR_MASK;
+ edac_pci_write_byte(dev, REG_IO_CTRL_1, val8);
+
+ edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
+ }
+
+ if (at_compat_reg_broken == 0) {
+ u8 out8 = 0;
+ val8 = __do_inb(REG_AT_COMPAT);
+ if (val8 & AT_COMPAT_SERR)
+ out8 = AT_COMPAT_CLRSERR;
+ if (val8 & AT_COMPAT_IOCHK)
+ out8 |= AT_COMPAT_CLRIOCHK;
+ if (out8 > 0) {
+ __do_outb(out8, REG_AT_COMPAT);
+ edac_device_handle_ue(edac_dev, 0, 0,
+ edac_dev->ctl_name);
+ }
+ }
+}
+
+/* General devices represented by edac_device_ctl_info */
+static struct amd8111_dev_info amd8111_devices[] = {
+ [LPC_BRIDGE] = {
+ .err_dev = PCI_DEVICE_ID_AMD_8111_LPC,
+ .ctl_name = "lpc",
+ .init = amd8111_lpc_bridge_init,
+ .exit = amd8111_lpc_bridge_exit,
+ .check = amd8111_lpc_bridge_check,
+ },
+ {0},
+};
+
+/* PCI controllers represented by edac_pci_ctl_info */
+static struct amd8111_pci_info amd8111_pcis[] = {
+ [PCI_BRIDGE] = {
+ .err_dev = PCI_DEVICE_ID_AMD_8111_PCI,
+ .ctl_name = "AMD8111_PCI_Controller",
+ .init = amd8111_pci_bridge_init,
+ .exit = amd8111_pci_bridge_exit,
+ .check = amd8111_pci_bridge_check,
+ },
+ {0},
+};
+
+static int amd8111_dev_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data];
+
+ dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
+ dev_info->err_dev, NULL);
+
+ if (!dev_info->dev) {
+ printk(KERN_ERR "EDAC device not found:"
+ "vendor %x, device %x, name %s\n",
+ PCI_VENDOR_ID_AMD, dev_info->err_dev,
+ dev_info->ctl_name);
+ return -ENODEV;
+ }
+
+ if (pci_enable_device(dev_info->dev)) {
+ pci_dev_put(dev_info->dev);
+ printk(KERN_ERR "failed to enable:"
+ "vendor %x, device %x, name %s\n",
+ PCI_VENDOR_ID_AMD, dev_info->err_dev,
+ dev_info->ctl_name);
+ return -ENODEV;
+ }
+
+ /*
+ * we do not allocate extra private structure for
+ * edac_device_ctl_info, but make use of existing
+ * one instead.
+ */
+ dev_info->edac_idx = edac_dev_idx++;
+ dev_info->edac_dev =
+ edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1,
+ NULL, 0, 0,
+ NULL, 0, dev_info->edac_idx);
+ if (!dev_info->edac_dev)
+ return -ENOMEM;
+
+ dev_info->edac_dev->pvt_info = dev_info;
+ dev_info->edac_dev->dev = &dev_info->dev->dev;
+ dev_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
+ dev_info->edac_dev->ctl_name = dev_info->ctl_name;
+ dev_info->edac_dev->dev_name = dev_info->dev->dev.bus_id;
+
+ if (edac_op_state == EDAC_OPSTATE_POLL)
+ dev_info->edac_dev->edac_check = dev_info->check;
+
+ if (dev_info->init)
+ dev_info->init(dev_info);
+
+ if (edac_device_add_device(dev_info->edac_dev) > 0) {
+ printk(KERN_ERR "failed to add edac_dev for %s\n",
+ dev_info->ctl_name);
+ edac_device_free_ctl_info(dev_info->edac_dev);
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "added one edac_dev on AMD8111 "
+ "vendor %x, device %x, name %s\n",
+ PCI_VENDOR_ID_AMD, dev_info->err_dev,
+ dev_info->ctl_name);
+
+ return 0;
+}
+
+static void amd8111_dev_remove(struct pci_dev *dev)
+{
+ struct amd8111_dev_info *dev_info;
+
+ for (dev_info = amd8111_devices; dev_info->err_dev; dev_info++)
+ if (dev_info->dev->device == dev->device)
+ break;
+
+ if (!dev_info->err_dev) /* should never happen */
+ return;
+
+ if (dev_info->edac_dev) {
+ edac_device_del_device(dev_info->edac_dev->dev);
+ edac_device_free_ctl_info(dev_info->edac_dev);
+ }
+
+ if (dev_info->exit)
+ dev_info->exit(dev_info);
+
+ pci_dev_put(dev_info->dev);
+}
+
+static int amd8111_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct amd8111_pci_info *pci_info = &amd8111_pcis[id->driver_data];
+
+ pci_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
+ pci_info->err_dev, NULL);
+
+ if (!pci_info->dev) {
+ printk(KERN_ERR "EDAC device not found:"
+ "vendor %x, device %x, name %s\n",
+ PCI_VENDOR_ID_AMD, pci_info->err_dev,
+ pci_info->ctl_name);
+ return -ENODEV;
+ }
+
+ if (pci_enable_device(pci_info->dev)) {
+ pci_dev_put(pci_info->dev);
+ printk(KERN_ERR "failed to enable:"
+ "vendor %x, device %x, name %s\n",
+ PCI_VENDOR_ID_AMD, pci_info->err_dev,
+ pci_info->ctl_name);
+ return -ENODEV;
+ }
+
+ /*
+ * we do not allocate extra private structure for
+ * edac_pci_ctl_info, but make use of existing
+ * one instead.
+ */
+ pci_info->edac_idx = edac_pci_alloc_index();
+ pci_info->edac_dev = edac_pci_alloc_ctl_info(0, pci_info->ctl_name);
+ if (!pci_info->edac_dev)
+ return -ENOMEM;
+
+ pci_info->edac_dev->pvt_info = pci_info;
+ pci_info->edac_dev->dev = &pci_info->dev->dev;
+ pci_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
+ pci_info->edac_dev->ctl_name = pci_info->ctl_name;
+ pci_info->edac_dev->dev_name = pci_info->dev->dev.bus_id;
+
+ if (edac_op_state == EDAC_OPSTATE_POLL)
+ pci_info->edac_dev->edac_check = pci_info->check;
+
+ if (pci_info->init)
+ pci_info->init(pci_info);
+
+ if (edac_pci_add_device(pci_info->edac_dev, pci_info->edac_idx) > 0) {
+ printk(KERN_ERR "failed to add edac_pci for %s\n",
+ pci_info->ctl_name);
+ edac_pci_free_ctl_info(pci_info->edac_dev);
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "added one edac_pci on AMD8111 "
+ "vendor %x, device %x, name %s\n",
+ PCI_VENDOR_ID_AMD, pci_info->err_dev,
+ pci_info->ctl_name);
+
+ return 0;
+}
+
+static void amd8111_pci_remove(struct pci_dev *dev)
+{
+ struct amd8111_pci_info *pci_info;
+
+ for (pci_info = amd8111_pcis; pci_info->err_dev; pci_info++)
+ if (pci_info->dev->device == dev->device)
+ break;
+
+ if (!pci_info->err_dev) /* should never happen */
+ return;
+
+ if (pci_info->edac_dev) {
+ edac_pci_del_device(pci_info->edac_dev->dev);
+ edac_pci_free_ctl_info(pci_info->edac_dev);
+ }
+
+ if (pci_info->exit)
+ pci_info->exit(pci_info);
+
+ pci_dev_put(pci_info->dev);
+}
+
+/* PCI Device ID talbe for general EDAC device */
+static const struct pci_device_id amd8111_edac_dev_tbl[] = {
+ {
+ PCI_VEND_DEV(AMD, 8111_LPC),
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .class = 0,
+ .class_mask = 0,
+ .driver_data = LPC_BRIDGE,
+ },
+ {
+ 0,
+ } /* table is NULL-terminated */
+};
+MODULE_DEVICE_TABLE(pci, amd8111_edac_dev_tbl);
+
+static struct pci_driver amd8111_edac_dev_driver = {
+ .name = "AMD8111_EDAC_DEV",
+ .probe = amd8111_dev_probe,
+ .remove = amd8111_dev_remove,
+ .id_table = amd8111_edac_dev_tbl,
+};
+
+/* PCI Device ID table for EDAC PCI controller */
+static const struct pci_device_id amd8111_edac_pci_tbl[] = {
+ {
+ PCI_VEND_DEV(AMD, 8111_PCI),
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .class = 0,
+ .class_mask = 0,
+ .driver_data = PCI_BRIDGE,
+ },
+ {
+ 0,
+ } /* table is NULL-terminated */
+};
+MODULE_DEVICE_TABLE(pci, amd8111_edac_pci_tbl);
+
+static struct pci_driver amd8111_edac_pci_driver = {
+ .name = "AMD8111_EDAC_PCI",
+ .probe = amd8111_pci_probe,
+ .remove = amd8111_pci_remove,
+ .id_table = amd8111_edac_pci_tbl,
+};
+
+static int __init amd8111_edac_init(void)
+{
+ int val;
+
+ printk(KERN_INFO "AMD8111 EDAC driver " AMD8111_EDAC_REVISION "\n");
+ printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n");
+
+ /* Only POLL mode supported so far */
+ edac_op_state = EDAC_OPSTATE_POLL;
+
+ val = pci_register_driver(&amd8111_edac_dev_driver);
+ val |= pci_register_driver(&amd8111_edac_pci_driver);
+
+ return val;
+}
+
+static void __exit amd8111_edac_exit(void)
+{
+ pci_unregister_driver(&amd8111_edac_pci_driver);
+ pci_unregister_driver(&amd8111_edac_dev_driver);
+}
+
+
+module_init(amd8111_edac_init);
+module_exit(amd8111_edac_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Cao Qingtao <qingtao.cao@windriver.com>\n");
+MODULE_DESCRIPTION("AMD8111 HyperTransport I/O Hub EDAC kernel module");
diff --git a/drivers/edac/amd8111_edac.h b/drivers/edac/amd8111_edac.h
new file mode 100644
index 000000000000..35794331debc
--- /dev/null
+++ b/drivers/edac/amd8111_edac.h
@@ -0,0 +1,130 @@
+/*
+ * amd8111_edac.h, EDAC defs for AMD8111 hypertransport chip
+ *
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors: Cao Qingtao <qingtao.cao@windriver.com>
+ * Benjamin Walsh <benjamin.walsh@windriver.com>
+ * Hu Yongqi <yongqi.hu@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _AMD8111_EDAC_H_
+#define _AMD8111_EDAC_H_
+
+/************************************************************
+ * PCI Bridge Status and Command Register, DevA:0x04
+ ************************************************************/
+#define REG_PCI_STSCMD 0x04
+enum pci_stscmd_bits {
+ PCI_STSCMD_SSE = BIT(30),
+ PCI_STSCMD_RMA = BIT(29),
+ PCI_STSCMD_RTA = BIT(28),
+ PCI_STSCMD_SERREN = BIT(8),
+ PCI_STSCMD_CLEAR_MASK = (PCI_STSCMD_SSE |
+ PCI_STSCMD_RMA |
+ PCI_STSCMD_RTA)
+};
+
+/************************************************************
+ * PCI Bridge Memory Base-Limit Register, DevA:0x1c
+ ************************************************************/
+#define REG_MEM_LIM 0x1c
+enum mem_limit_bits {
+ MEM_LIMIT_DPE = BIT(31),
+ MEM_LIMIT_RSE = BIT(30),
+ MEM_LIMIT_RMA = BIT(29),
+ MEM_LIMIT_RTA = BIT(28),
+ MEM_LIMIT_STA = BIT(27),
+ MEM_LIMIT_MDPE = BIT(24),
+ MEM_LIMIT_CLEAR_MASK = (MEM_LIMIT_DPE |
+ MEM_LIMIT_RSE |
+ MEM_LIMIT_RMA |
+ MEM_LIMIT_RTA |
+ MEM_LIMIT_STA |
+ MEM_LIMIT_MDPE)
+};
+
+/************************************************************
+ * HyperTransport Link Control Register, DevA:0xc4
+ ************************************************************/
+#define REG_HT_LINK 0xc4
+enum ht_link_bits {
+ HT_LINK_LKFAIL = BIT(4),
+ HT_LINK_CRCFEN = BIT(1),
+ HT_LINK_CLEAR_MASK = (HT_LINK_LKFAIL)
+};
+
+/************************************************************
+ * PCI Bridge Interrupt and Bridge Control, DevA:0x3c
+ ************************************************************/
+#define REG_PCI_INTBRG_CTRL 0x3c
+enum pci_intbrg_ctrl_bits {
+ PCI_INTBRG_CTRL_DTSERREN = BIT(27),
+ PCI_INTBRG_CTRL_DTSTAT = BIT(26),
+ PCI_INTBRG_CTRL_MARSP = BIT(21),
+ PCI_INTBRG_CTRL_SERREN = BIT(17),
+ PCI_INTBRG_CTRL_PEREN = BIT(16),
+ PCI_INTBRG_CTRL_CLEAR_MASK = (PCI_INTBRG_CTRL_DTSTAT),
+ PCI_INTBRG_CTRL_POLL_MASK = (PCI_INTBRG_CTRL_DTSERREN |
+ PCI_INTBRG_CTRL_MARSP |
+ PCI_INTBRG_CTRL_SERREN)
+};
+
+/************************************************************
+ * I/O Control 1 Register, DevB:0x40
+ ************************************************************/
+#define REG_IO_CTRL_1 0x40
+enum io_ctrl_1_bits {
+ IO_CTRL_1_NMIONERR = BIT(7),
+ IO_CTRL_1_LPC_ERR = BIT(6),
+ IO_CTRL_1_PW2LPC = BIT(1),
+ IO_CTRL_1_CLEAR_MASK = (IO_CTRL_1_LPC_ERR | IO_CTRL_1_PW2LPC)
+};
+
+/************************************************************
+ * Legacy I/O Space Registers
+ ************************************************************/
+#define REG_AT_COMPAT 0x61
+enum at_compat_bits {
+ AT_COMPAT_SERR = BIT(7),
+ AT_COMPAT_IOCHK = BIT(6),
+ AT_COMPAT_CLRIOCHK = BIT(3),
+ AT_COMPAT_CLRSERR = BIT(2),
+};
+
+struct amd8111_dev_info {
+ u16 err_dev; /* PCI Device ID */
+ struct pci_dev *dev;
+ int edac_idx; /* device index */
+ char *ctl_name;
+ struct edac_device_ctl_info *edac_dev;
+ void (*init)(struct amd8111_dev_info *dev_info);
+ void (*exit)(struct amd8111_dev_info *dev_info);
+ void (*check)(struct edac_device_ctl_info *edac_dev);
+};
+
+struct amd8111_pci_info {
+ u16 err_dev; /* PCI Device ID */
+ struct pci_dev *dev;
+ int edac_idx; /* pci index */
+ const char *ctl_name;
+ struct edac_pci_ctl_info *edac_dev;
+ void (*init)(struct amd8111_pci_info *dev_info);
+ void (*exit)(struct amd8111_pci_info *dev_info);
+ void (*check)(struct edac_pci_ctl_info *edac_dev);
+};
+
+#endif /* _AMD8111_EDAC_H_ */
diff --git a/drivers/edac/amd8131_edac.c b/drivers/edac/amd8131_edac.c
new file mode 100644
index 000000000000..c083b31cac5a
--- /dev/null
+++ b/drivers/edac/amd8131_edac.c
@@ -0,0 +1,379 @@
+/*
+ * amd8131_edac.c, AMD8131 hypertransport chip EDAC kernel module
+ *
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors: Cao Qingtao <qingtao.cao@windriver.com>
+ * Benjamin Walsh <benjamin.walsh@windriver.com>
+ * Hu Yongqi <yongqi.hu@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/edac.h>
+#include <linux/pci_ids.h>
+
+#include "edac_core.h"
+#include "edac_module.h"
+#include "amd8131_edac.h"
+
+#define AMD8131_EDAC_REVISION " Ver: 1.0.0 " __DATE__
+#define AMD8131_EDAC_MOD_STR "amd8131_edac"
+
+/* Wrapper functions for accessing PCI configuration space */
+static void edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32)
+{
+ int ret;
+
+ ret = pci_read_config_dword(dev, reg, val32);
+ if (ret != 0)
+ printk(KERN_ERR AMD8131_EDAC_MOD_STR
+ " PCI Access Read Error at 0x%x\n", reg);
+}
+
+static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32)
+{
+ int ret;
+
+ ret = pci_write_config_dword(dev, reg, val32);
+ if (ret != 0)
+ printk(KERN_ERR AMD8131_EDAC_MOD_STR
+ " PCI Access Write Error at 0x%x\n", reg);
+}
+
+static char * const bridge_str[] = {
+ [NORTH_A] = "NORTH A",
+ [NORTH_B] = "NORTH B",
+ [SOUTH_A] = "SOUTH A",
+ [SOUTH_B] = "SOUTH B",
+ [NO_BRIDGE] = "NO BRIDGE",
+};
+
+/* Support up to two AMD8131 chipsets on a platform */
+static struct amd8131_dev_info amd8131_devices[] = {
+ {
+ .inst = NORTH_A,
+ .devfn = DEVFN_PCIX_BRIDGE_NORTH_A,
+ .ctl_name = "AMD8131_PCIX_NORTH_A",
+ },
+ {
+ .inst = NORTH_B,
+ .devfn = DEVFN_PCIX_BRIDGE_NORTH_B,
+ .ctl_name = "AMD8131_PCIX_NORTH_B",
+ },
+ {
+ .inst = SOUTH_A,
+ .devfn = DEVFN_PCIX_BRIDGE_SOUTH_A,
+ .ctl_name = "AMD8131_PCIX_SOUTH_A",
+ },
+ {
+ .inst = SOUTH_B,
+ .devfn = DEVFN_PCIX_BRIDGE_SOUTH_B,
+ .ctl_name = "AMD8131_PCIX_SOUTH_B",
+ },
+ {.inst = NO_BRIDGE,},
+};
+
+static void amd8131_pcix_init(struct amd8131_dev_info *dev_info)
+{
+ u32 val32;
+ struct pci_dev *dev = dev_info->dev;
+
+ /* First clear error detection flags */
+ edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
+ if (val32 & MEM_LIMIT_MASK)
+ edac_pci_write_dword(dev, REG_MEM_LIM, val32);
+
+ /* Clear Discard Timer Timedout flag */
+ edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
+ if (val32 & INT_CTLR_DTS)
+ edac_pci_write_dword(dev, REG_INT_CTLR, val32);
+
+ /* Clear CRC Error flag on link side A */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
+ if (val32 & LNK_CTRL_CRCERR_A)
+ edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
+
+ /* Clear CRC Error flag on link side B */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
+ if (val32 & LNK_CTRL_CRCERR_B)
+ edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
+
+ /*
+ * Then enable all error detections.
+ *
+ * Setup Discard Timer Sync Flood Enable,
+ * System Error Enable and Parity Error Enable.
+ */
+ edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
+ val32 |= INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE;
+ edac_pci_write_dword(dev, REG_INT_CTLR, val32);
+
+ /* Enable overall SERR Error detection */
+ edac_pci_read_dword(dev, REG_STS_CMD, &val32);
+ val32 |= STS_CMD_SERREN;
+ edac_pci_write_dword(dev, REG_STS_CMD, val32);
+
+ /* Setup CRC Flood Enable for link side A */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
+ val32 |= LNK_CTRL_CRCFEN;
+ edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
+
+ /* Setup CRC Flood Enable for link side B */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
+ val32 |= LNK_CTRL_CRCFEN;
+ edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
+}
+
+static void amd8131_pcix_exit(struct amd8131_dev_info *dev_info)
+{
+ u32 val32;
+ struct pci_dev *dev = dev_info->dev;
+
+ /* Disable SERR, PERR and DTSE Error detection */
+ edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
+ val32 &= ~(INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE);
+ edac_pci_write_dword(dev, REG_INT_CTLR, val32);
+
+ /* Disable overall System Error detection */
+ edac_pci_read_dword(dev, REG_STS_CMD, &val32);
+ val32 &= ~STS_CMD_SERREN;
+ edac_pci_write_dword(dev, REG_STS_CMD, val32);
+
+ /* Disable CRC Sync Flood on link side A */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
+ val32 &= ~LNK_CTRL_CRCFEN;
+ edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
+
+ /* Disable CRC Sync Flood on link side B */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
+ val32 &= ~LNK_CTRL_CRCFEN;
+ edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
+}
+
+static void amd8131_pcix_check(struct edac_pci_ctl_info *edac_dev)
+{
+ struct amd8131_dev_info *dev_info = edac_dev->pvt_info;
+ struct pci_dev *dev = dev_info->dev;
+ u32 val32;
+
+ /* Check PCI-X Bridge Memory Base-Limit Register for errors */
+ edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
+ if (val32 & MEM_LIMIT_MASK) {
+ printk(KERN_INFO "Error(s) in mem limit register "
+ "on %s bridge\n", dev_info->ctl_name);
+ printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n"
+ "RTA: %d, STA: %d, MDPE: %d\n",
+ val32 & MEM_LIMIT_DPE,
+ val32 & MEM_LIMIT_RSE,
+ val32 & MEM_LIMIT_RMA,
+ val32 & MEM_LIMIT_RTA,
+ val32 & MEM_LIMIT_STA,
+ val32 & MEM_LIMIT_MDPE);
+
+ val32 |= MEM_LIMIT_MASK;
+ edac_pci_write_dword(dev, REG_MEM_LIM, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+
+ /* Check if Discard Timer timed out */
+ edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
+ if (val32 & INT_CTLR_DTS) {
+ printk(KERN_INFO "Error(s) in interrupt and control register "
+ "on %s bridge\n", dev_info->ctl_name);
+ printk(KERN_INFO "DTS: %d\n", val32 & INT_CTLR_DTS);
+
+ val32 |= INT_CTLR_DTS;
+ edac_pci_write_dword(dev, REG_INT_CTLR, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+
+ /* Check if CRC error happens on link side A */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
+ if (val32 & LNK_CTRL_CRCERR_A) {
+ printk(KERN_INFO "Error(s) in link conf and control register "
+ "on %s bridge\n", dev_info->ctl_name);
+ printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_A);
+
+ val32 |= LNK_CTRL_CRCERR_A;
+ edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+
+ /* Check if CRC error happens on link side B */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
+ if (val32 & LNK_CTRL_CRCERR_B) {
+ printk(KERN_INFO "Error(s) in link conf and control register "
+ "on %s bridge\n", dev_info->ctl_name);
+ printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_B);
+
+ val32 |= LNK_CTRL_CRCERR_B;
+ edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+}
+
+static struct amd8131_info amd8131_chipset = {
+ .err_dev = PCI_DEVICE_ID_AMD_8131_APIC,
+ .devices = amd8131_devices,
+ .init = amd8131_pcix_init,
+ .exit = amd8131_pcix_exit,
+ .check = amd8131_pcix_check,
+};
+
+/*
+ * There are 4 PCIX Bridges on ATCA-6101 that share the same PCI Device ID,
+ * so amd8131_probe() would be called by kernel 4 times, with different
+ * address of pci_dev for each of them each time.
+ */
+static int amd8131_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ struct amd8131_dev_info *dev_info;
+
+ for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE;
+ dev_info++)
+ if (dev_info->devfn == dev->devfn)
+ break;
+
+ if (dev_info->inst == NO_BRIDGE) /* should never happen */
+ return -ENODEV;
+
+ /*
+ * We can't call pci_get_device() as we are used to do because
+ * there are 4 of them but pci_dev_get() instead.
+ */
+ dev_info->dev = pci_dev_get(dev);
+
+ if (pci_enable_device(dev_info->dev)) {
+ pci_dev_put(dev_info->dev);
+ printk(KERN_ERR "failed to enable:"
+ "vendor %x, device %x, devfn %x, name %s\n",
+ PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev,
+ dev_info->devfn, dev_info->ctl_name);
+ return -ENODEV;
+ }
+
+ /*
+ * we do not allocate extra private structure for
+ * edac_pci_ctl_info, but make use of existing
+ * one instead.
+ */
+ dev_info->edac_idx = edac_pci_alloc_index();
+ dev_info->edac_dev = edac_pci_alloc_ctl_info(0, dev_info->ctl_name);
+ if (!dev_info->edac_dev)
+ return -ENOMEM;
+
+ dev_info->edac_dev->pvt_info = dev_info;
+ dev_info->edac_dev->dev = &dev_info->dev->dev;
+ dev_info->edac_dev->mod_name = AMD8131_EDAC_MOD_STR;
+ dev_info->edac_dev->ctl_name = dev_info->ctl_name;
+ dev_info->edac_dev->dev_name = dev_info->dev->dev.bus_id;
+
+ if (edac_op_state == EDAC_OPSTATE_POLL)
+ dev_info->edac_dev->edac_check = amd8131_chipset.check;
+
+ if (amd8131_chipset.init)
+ amd8131_chipset.init(dev_info);
+
+ if (edac_pci_add_device(dev_info->edac_dev, dev_info->edac_idx) > 0) {
+ printk(KERN_ERR "failed edac_pci_add_device() for %s\n",
+ dev_info->ctl_name);
+ edac_pci_free_ctl_info(dev_info->edac_dev);
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "added one device on AMD8131 "
+ "vendor %x, device %x, devfn %x, name %s\n",
+ PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev,
+ dev_info->devfn, dev_info->ctl_name);
+
+ return 0;
+}
+
+static void amd8131_remove(struct pci_dev *dev)
+{
+ struct amd8131_dev_info *dev_info;
+
+ for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE;
+ dev_info++)
+ if (dev_info->devfn == dev->devfn)
+ break;
+
+ if (dev_info->inst == NO_BRIDGE) /* should never happen */
+ return;
+
+ if (dev_info->edac_dev) {
+ edac_pci_del_device(dev_info->edac_dev->dev);
+ edac_pci_free_ctl_info(dev_info->edac_dev);
+ }
+
+ if (amd8131_chipset.exit)
+ amd8131_chipset.exit(dev_info);
+
+ pci_dev_put(dev_info->dev);
+}
+
+static const struct pci_device_id amd8131_edac_pci_tbl[] = {
+ {
+ PCI_VEND_DEV(AMD, 8131_BRIDGE),
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .class = 0,
+ .class_mask = 0,
+ .driver_data = 0,
+ },
+ {
+ 0,
+ } /* table is NULL-terminated */
+};
+MODULE_DEVICE_TABLE(pci, amd8131_edac_pci_tbl);
+
+static struct pci_driver amd8131_edac_driver = {
+ .name = AMD8131_EDAC_MOD_STR,
+ .probe = amd8131_probe,
+ .remove = amd8131_remove,
+ .id_table = amd8131_edac_pci_tbl,
+};
+
+static int __init amd8131_edac_init(void)
+{
+ printk(KERN_INFO "AMD8131 EDAC driver " AMD8131_EDAC_REVISION "\n");
+ printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n");
+
+ /* Only POLL mode supported so far */
+ edac_op_state = EDAC_OPSTATE_POLL;
+
+ return pci_register_driver(&amd8131_edac_driver);
+}
+
+static void __exit amd8131_edac_exit(void)
+{
+ pci_unregister_driver(&amd8131_edac_driver);
+}
+
+module_init(amd8131_edac_init);
+module_exit(amd8131_edac_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Cao Qingtao <qingtao.cao@windriver.com>\n");
+MODULE_DESCRIPTION("AMD8131 HyperTransport PCI-X Tunnel EDAC kernel module");
diff --git a/drivers/edac/amd8131_edac.h b/drivers/edac/amd8131_edac.h
new file mode 100644
index 000000000000..60e0d1c72dee
--- /dev/null
+++ b/drivers/edac/amd8131_edac.h
@@ -0,0 +1,119 @@
+/*
+ * amd8131_edac.h, EDAC defs for AMD8131 hypertransport chip
+ *
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors: Cao Qingtao <qingtao.cao@windriver.com>
+ * Benjamin Walsh <benjamin.walsh@windriver.com>
+ * Hu Yongqi <yongqi.hu@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _AMD8131_EDAC_H_
+#define _AMD8131_EDAC_H_
+
+#define DEVFN_PCIX_BRIDGE_NORTH_A 8
+#define DEVFN_PCIX_BRIDGE_NORTH_B 16
+#define DEVFN_PCIX_BRIDGE_SOUTH_A 24
+#define DEVFN_PCIX_BRIDGE_SOUTH_B 32
+
+/************************************************************
+ * PCI-X Bridge Status and Command Register, DevA:0x04
+ ************************************************************/
+#define REG_STS_CMD 0x04
+enum sts_cmd_bits {
+ STS_CMD_SSE = BIT(30),
+ STS_CMD_SERREN = BIT(8)
+};
+
+/************************************************************
+ * PCI-X Bridge Interrupt and Bridge Control Register,
+ ************************************************************/
+#define REG_INT_CTLR 0x3c
+enum int_ctlr_bits {
+ INT_CTLR_DTSE = BIT(27),
+ INT_CTLR_DTS = BIT(26),
+ INT_CTLR_SERR = BIT(17),
+ INT_CTLR_PERR = BIT(16)
+};
+
+/************************************************************
+ * PCI-X Bridge Memory Base-Limit Register, DevA:0x1C
+ ************************************************************/
+#define REG_MEM_LIM 0x1c
+enum mem_limit_bits {
+ MEM_LIMIT_DPE = BIT(31),
+ MEM_LIMIT_RSE = BIT(30),
+ MEM_LIMIT_RMA = BIT(29),
+ MEM_LIMIT_RTA = BIT(28),
+ MEM_LIMIT_STA = BIT(27),
+ MEM_LIMIT_MDPE = BIT(24),
+ MEM_LIMIT_MASK = MEM_LIMIT_DPE|MEM_LIMIT_RSE|MEM_LIMIT_RMA|
+ MEM_LIMIT_RTA|MEM_LIMIT_STA|MEM_LIMIT_MDPE
+};
+
+/************************************************************
+ * Link Configuration And Control Register, side A
+ ************************************************************/
+#define REG_LNK_CTRL_A 0xc4
+
+/************************************************************
+ * Link Configuration And Control Register, side B
+ ************************************************************/
+#define REG_LNK_CTRL_B 0xc8
+
+enum lnk_ctrl_bits {
+ LNK_CTRL_CRCERR_A = BIT(9),
+ LNK_CTRL_CRCERR_B = BIT(8),
+ LNK_CTRL_CRCFEN = BIT(1)
+};
+
+enum pcix_bridge_inst {
+ NORTH_A = 0,
+ NORTH_B = 1,
+ SOUTH_A = 2,
+ SOUTH_B = 3,
+ NO_BRIDGE = 4
+};
+
+struct amd8131_dev_info {
+ int devfn;
+ enum pcix_bridge_inst inst;
+ struct pci_dev *dev;
+ int edac_idx; /* pci device index */
+ char *ctl_name;
+ struct edac_pci_ctl_info *edac_dev;
+};
+
+/*
+ * AMD8131 chipset has two pairs of PCIX Bridge and related IOAPIC
+ * Controler, and ATCA-6101 has two AMD8131 chipsets, so there are
+ * four PCIX Bridges on ATCA-6101 altogether.
+ *
+ * These PCIX Bridges share the same PCI Device ID and are all of
+ * Function Zero, they could be discrimated by their pci_dev->devfn.
+ * They share the same set of init/check/exit methods, and their
+ * private structures are collected in the devices[] array.
+ */
+struct amd8131_info {
+ u16 err_dev; /* PCI Device ID for AMD8131 APIC*/
+ struct amd8131_dev_info *devices;
+ void (*init)(struct amd8131_dev_info *dev_info);
+ void (*exit)(struct amd8131_dev_info *dev_info);
+ void (*check)(struct edac_pci_ctl_info *edac_dev);
+};
+
+#endif /* _AMD8131_EDAC_H_ */
+
diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c
index 24f3ca851523..cb0f639f049d 100644
--- a/drivers/edac/cell_edac.c
+++ b/drivers/edac/cell_edac.c
@@ -198,7 +198,7 @@ static int __devinit cell_edac_probe(struct platform_device *pdev)
mci->edac_cap = EDAC_FLAG_EC | EDAC_FLAG_SECDED;
mci->mod_name = "cell_edac";
mci->ctl_name = "MIC";
- mci->dev_name = pdev->dev.bus_id;
+ mci->dev_name = dev_name(&pdev->dev);
mci->edac_check = cell_edac_check;
cell_edac_init_csrows(mci);
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index 4b55ec607a88..28f2c3f959b5 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -49,6 +49,10 @@
#define edac_printk(level, prefix, fmt, arg...) \
printk(level "EDAC " prefix ": " fmt, ##arg)
+#define edac_printk_verbose(level, prefix, fmt, arg...) \
+ printk(level "EDAC " prefix ": " "in %s, line at %d: " fmt, \
+ __FILE__, __LINE__, ##arg)
+
#define edac_mc_printk(mci, level, fmt, arg...) \
printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg)
@@ -71,11 +75,20 @@
#ifdef CONFIG_EDAC_DEBUG
extern int edac_debug_level;
+#ifndef CONFIG_EDAC_DEBUG_VERBOSE
#define edac_debug_printk(level, fmt, arg...) \
do { \
if (level <= edac_debug_level) \
edac_printk(KERN_DEBUG, EDAC_DEBUG, fmt, ##arg); \
- } while(0)
+ } while (0)
+#else /* CONFIG_EDAC_DEBUG_VERBOSE */
+#define edac_debug_printk(level, fmt, arg...) \
+ do { \
+ if (level <= edac_debug_level) \
+ edac_printk_verbose(KERN_DEBUG, EDAC_DEBUG, fmt, \
+ ##arg); \
+ } while (0)
+#endif
#define debugf0( ... ) edac_debug_printk(0, __VA_ARGS__ )
#define debugf1( ... ) edac_debug_printk(1, __VA_ARGS__ )
@@ -831,6 +844,7 @@ extern void edac_pci_free_ctl_info(struct edac_pci_ctl_info *pci);
extern void edac_pci_reset_delay_period(struct edac_pci_ctl_info *pci,
unsigned long value);
+extern int edac_pci_alloc_index(void);
extern int edac_pci_add_device(struct edac_pci_ctl_info *pci, int edac_idx);
extern struct edac_pci_ctl_info *edac_pci_del_device(struct device *dev);
diff --git a/drivers/edac/edac_pci.c b/drivers/edac/edac_pci.c
index 5d3c8083a40e..5b150aea703a 100644
--- a/drivers/edac/edac_pci.c
+++ b/drivers/edac/edac_pci.c
@@ -30,6 +30,7 @@
static DEFINE_MUTEX(edac_pci_ctls_mutex);
static LIST_HEAD(edac_pci_list);
+static atomic_t pci_indexes = ATOMIC_INIT(0);
/*
* edac_pci_alloc_ctl_info
@@ -318,6 +319,19 @@ void edac_pci_reset_delay_period(struct edac_pci_ctl_info *pci,
EXPORT_SYMBOL_GPL(edac_pci_reset_delay_period);
/*
+ * edac_pci_alloc_index: Allocate a unique PCI index number
+ *
+ * Return:
+ * allocated index number
+ *
+ */
+int edac_pci_alloc_index(void)
+{
+ return atomic_inc_return(&pci_indexes) - 1;
+}
+EXPORT_SYMBOL_GPL(edac_pci_alloc_index);
+
+/*
* edac_pci_add_device: Insert the 'edac_dev' structure into the
* edac_pci global list and create sysfs entries associated with
* edac_pci structure.
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 853ef37ec006..4637a4a757df 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -218,7 +218,7 @@ static int __devinit mpc85xx_pci_err_probe(struct of_device *op,
pci->dev = &op->dev;
pci->mod_name = EDAC_MOD_STR;
pci->ctl_name = pdata->name;
- pci->dev_name = op->dev.bus_id;
+ pci->dev_name = dev_name(&op->dev);
if (edac_op_state == EDAC_OPSTATE_POLL)
pci->edac_check = mpc85xx_pci_check;
diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c
index 083ce8d0c63d..5131aaae8e03 100644
--- a/drivers/edac/mv64x60_edac.c
+++ b/drivers/edac/mv64x60_edac.c
@@ -121,7 +121,7 @@ static int __devinit mv64x60_pci_err_probe(struct platform_device *pdev)
pdata->irq = NO_IRQ;
platform_set_drvdata(pdev, pci);
pci->dev = &pdev->dev;
- pci->dev_name = pdev->dev.bus_id;
+ pci->dev_name = dev_name(&pdev->dev);
pci->mod_name = EDAC_MOD_STR;
pci->ctl_name = pdata->name;
@@ -294,7 +294,7 @@ static int __devinit mv64x60_sram_err_probe(struct platform_device *pdev)
pdata->irq = NO_IRQ;
edac_dev->dev = &pdev->dev;
platform_set_drvdata(pdev, edac_dev);
- edac_dev->dev_name = pdev->dev.bus_id;
+ edac_dev->dev_name = dev_name(&pdev->dev);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
@@ -462,7 +462,7 @@ static int __devinit mv64x60_cpu_err_probe(struct platform_device *pdev)
pdata->irq = NO_IRQ;
edac_dev->dev = &pdev->dev;
platform_set_drvdata(pdev, edac_dev);
- edac_dev->dev_name = pdev->dev.bus_id;
+ edac_dev->dev_name = dev_name(&pdev->dev);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
@@ -713,7 +713,7 @@ static int __devinit mv64x60_mc_err_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, mci);
pdata->name = "mv64x60_mc_err";
pdata->irq = NO_IRQ;
- mci->dev_name = pdev->dev.bus_id;
+ mci->dev_name = dev_name(&pdev->dev);
pdata->edac_idx = edac_mc_idx++;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c
new file mode 100644
index 000000000000..11f2172aa1e6
--- /dev/null
+++ b/drivers/edac/ppc4xx_edac.c
@@ -0,0 +1,1448 @@
+/*
+ * Copyright (c) 2008 Nuovation System Designs, LLC
+ * Grant Erickson <gerickson@nuovations.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/edac.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/types.h>
+
+#include <asm/dcr.h>
+
+#include "edac_core.h"
+#include "ppc4xx_edac.h"
+
+/*
+ * This file implements a driver for monitoring and handling events
+ * associated with the IMB DDR2 ECC controller found in the AMCC/IBM
+ * 405EX[r], 440SP, 440SPe, 460EX, 460GT and 460SX.
+ *
+ * As realized in the 405EX[r], this controller features:
+ *
+ * - Support for registered- and non-registered DDR1 and DDR2 memory.
+ * - 32-bit or 16-bit memory interface with optional ECC.
+ *
+ * o ECC support includes:
+ *
+ * - 4-bit SEC/DED
+ * - Aligned-nibble error detect
+ * - Bypass mode
+ *
+ * - Two (2) memory banks/ranks.
+ * - Up to 1 GiB per bank/rank in 32-bit mode and up to 512 MiB per
+ * bank/rank in 16-bit mode.
+ *
+ * As realized in the 440SP and 440SPe, this controller changes/adds:
+ *
+ * - 64-bit or 32-bit memory interface with optional ECC.
+ *
+ * o ECC support includes:
+ *
+ * - 8-bit SEC/DED
+ * - Aligned-nibble error detect
+ * - Bypass mode
+ *
+ * - Up to 4 GiB per bank/rank in 64-bit mode and up to 2 GiB
+ * per bank/rank in 32-bit mode.
+ *
+ * As realized in the 460EX and 460GT, this controller changes/adds:
+ *
+ * - 64-bit or 32-bit memory interface with optional ECC.
+ *
+ * o ECC support includes:
+ *
+ * - 8-bit SEC/DED
+ * - Aligned-nibble error detect
+ * - Bypass mode
+ *
+ * - Four (4) memory banks/ranks.
+ * - Up to 16 GiB per bank/rank in 64-bit mode and up to 8 GiB
+ * per bank/rank in 32-bit mode.
+ *
+ * At present, this driver has ONLY been tested against the controller
+ * realization in the 405EX[r] on the AMCC Kilauea and Haleakala
+ * boards (256 MiB w/o ECC memory soldered onto the board) and a
+ * proprietary board based on those designs (128 MiB ECC memory, also
+ * soldered onto the board).
+ *
+ * Dynamic feature detection and handling needs to be added for the
+ * other realizations of this controller listed above.
+ *
+ * Eventually, this driver will likely be adapted to the above variant
+ * realizations of this controller as well as broken apart to handle
+ * the other known ECC-capable controllers prevalent in other 4xx
+ * processors:
+ *
+ * - IBM SDRAM (405GP, 405CR and 405EP) "ibm,sdram-4xx"
+ * - IBM DDR1 (440GP, 440GX, 440EP and 440GR) "ibm,sdram-4xx-ddr"
+ * - Denali DDR1/DDR2 (440EPX and 440GRX) "denali,sdram-4xx-ddr2"
+ *
+ * For this controller, unfortunately, correctable errors report
+ * nothing more than the beat/cycle and byte/lane the correction
+ * occurred on and the check bit group that covered the error.
+ *
+ * In contrast, uncorrectable errors also report the failing address,
+ * the bus master and the transaction direction (i.e. read or write)
+ *
+ * Regardless of whether the error is a CE or a UE, we report the
+ * following pieces of information in the driver-unique message to the
+ * EDAC subsystem:
+ *
+ * - Device tree path
+ * - Bank(s)
+ * - Check bit error group
+ * - Beat(s)/lane(s)
+ */
+
+/* Preprocessor Definitions */
+
+#define EDAC_OPSTATE_INT_STR "interrupt"
+#define EDAC_OPSTATE_POLL_STR "polled"
+#define EDAC_OPSTATE_UNKNOWN_STR "unknown"
+
+#define PPC4XX_EDAC_MODULE_NAME "ppc4xx_edac"
+#define PPC4XX_EDAC_MODULE_REVISION "v1.0.0 " __DATE__
+
+#define PPC4XX_EDAC_MESSAGE_SIZE 256
+
+/*
+ * Kernel logging without an EDAC instance
+ */
+#define ppc4xx_edac_printk(level, fmt, arg...) \
+ edac_printk(level, "PPC4xx MC", fmt, ##arg)
+
+/*
+ * Kernel logging with an EDAC instance
+ */
+#define ppc4xx_edac_mc_printk(level, mci, fmt, arg...) \
+ edac_mc_chipset_printk(mci, level, "PPC4xx", fmt, ##arg)
+
+/*
+ * Macros to convert bank configuration size enumerations into MiB and
+ * page values.
+ */
+#define SDRAM_MBCF_SZ_MiB_MIN 4
+#define SDRAM_MBCF_SZ_TO_MiB(n) (SDRAM_MBCF_SZ_MiB_MIN \
+ << (SDRAM_MBCF_SZ_DECODE(n)))
+#define SDRAM_MBCF_SZ_TO_PAGES(n) (SDRAM_MBCF_SZ_MiB_MIN \
+ << (20 - PAGE_SHIFT + \
+ SDRAM_MBCF_SZ_DECODE(n)))
+
+/*
+ * The ibm,sdram-4xx-ddr2 Device Control Registers (DCRs) are
+ * indirectly acccessed and have a base and length defined by the
+ * device tree. The base can be anything; however, we expect the
+ * length to be precisely two registers, the first for the address
+ * window and the second for the data window.
+ */
+#define SDRAM_DCR_RESOURCE_LEN 2
+#define SDRAM_DCR_ADDR_OFFSET 0
+#define SDRAM_DCR_DATA_OFFSET 1
+
+/*
+ * Device tree interrupt indices
+ */
+#define INTMAP_ECCDED_INDEX 0 /* Double-bit Error Detect */
+#define INTMAP_ECCSEC_INDEX 1 /* Single-bit Error Correct */
+
+/* Type Definitions */
+
+/*
+ * PPC4xx SDRAM memory controller private instance data
+ */
+struct ppc4xx_edac_pdata {
+ dcr_host_t dcr_host; /* Indirect DCR address/data window mapping */
+ struct {
+ int sec; /* Single-bit correctable error IRQ assigned */
+ int ded; /* Double-bit detectable error IRQ assigned */
+ } irqs;
+};
+
+/*
+ * Various status data gathered and manipulated when checking and
+ * reporting ECC status.
+ */
+struct ppc4xx_ecc_status {
+ u32 ecces;
+ u32 besr;
+ u32 bearh;
+ u32 bearl;
+ u32 wmirq;
+};
+
+/* Function Prototypes */
+
+static int ppc4xx_edac_probe(struct of_device *device,
+ const struct of_device_id *device_id);
+static int ppc4xx_edac_remove(struct of_device *device);
+
+/* Global Variables */
+
+/*
+ * Device tree node type and compatible tuples this driver can match
+ * on.
+ */
+static struct of_device_id ppc4xx_edac_match[] = {
+ {
+ .compatible = "ibm,sdram-4xx-ddr2"
+ },
+ { }
+};
+
+static struct of_platform_driver ppc4xx_edac_driver = {
+ .match_table = ppc4xx_edac_match,
+ .probe = ppc4xx_edac_probe,
+ .remove = ppc4xx_edac_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = PPC4XX_EDAC_MODULE_NAME
+ }
+};
+
+/*
+ * TODO: The row and channel parameters likely need to be dynamically
+ * set based on the aforementioned variant controller realizations.
+ */
+static const unsigned ppc4xx_edac_nr_csrows = 2;
+static const unsigned ppc4xx_edac_nr_chans = 1;
+
+/*
+ * Strings associated with PLB master IDs capable of being posted in
+ * SDRAM_BESR or SDRAM_WMIRQ on uncorrectable ECC errors.
+ */
+static const char * const ppc4xx_plb_masters[9] = {
+ [SDRAM_PLB_M0ID_ICU] = "ICU",
+ [SDRAM_PLB_M0ID_PCIE0] = "PCI-E 0",
+ [SDRAM_PLB_M0ID_PCIE1] = "PCI-E 1",
+ [SDRAM_PLB_M0ID_DMA] = "DMA",
+ [SDRAM_PLB_M0ID_DCU] = "DCU",
+ [SDRAM_PLB_M0ID_OPB] = "OPB",
+ [SDRAM_PLB_M0ID_MAL] = "MAL",
+ [SDRAM_PLB_M0ID_SEC] = "SEC",
+ [SDRAM_PLB_M0ID_AHB] = "AHB"
+};
+
+/**
+ * mfsdram - read and return controller register data
+ * @dcr_host: A pointer to the DCR mapping.
+ * @idcr_n: The indirect DCR register to read.
+ *
+ * This routine reads and returns the data associated with the
+ * controller's specified indirect DCR register.
+ *
+ * Returns the read data.
+ */
+static inline u32
+mfsdram(const dcr_host_t *dcr_host, unsigned int idcr_n)
+{
+ return __mfdcri(dcr_host->base + SDRAM_DCR_ADDR_OFFSET,
+ dcr_host->base + SDRAM_DCR_DATA_OFFSET,
+ idcr_n);
+}
+
+/**
+ * mtsdram - write controller register data
+ * @dcr_host: A pointer to the DCR mapping.
+ * @idcr_n: The indirect DCR register to write.
+ * @value: The data to write.
+ *
+ * This routine writes the provided data to the controller's specified
+ * indirect DCR register.
+ */
+static inline void
+mtsdram(const dcr_host_t *dcr_host, unsigned int idcr_n, u32 value)
+{
+ return __mtdcri(dcr_host->base + SDRAM_DCR_ADDR_OFFSET,
+ dcr_host->base + SDRAM_DCR_DATA_OFFSET,
+ idcr_n,
+ value);
+}
+
+/**
+ * ppc4xx_edac_check_bank_error - check a bank for an ECC bank error
+ * @status: A pointer to the ECC status structure to check for an
+ * ECC bank error.
+ * @bank: The bank to check for an ECC error.
+ *
+ * This routine determines whether the specified bank has an ECC
+ * error.
+ *
+ * Returns true if the specified bank has an ECC error; otherwise,
+ * false.
+ */
+static bool
+ppc4xx_edac_check_bank_error(const struct ppc4xx_ecc_status *status,
+ unsigned int bank)
+{
+ switch (bank) {
+ case 0:
+ return status->ecces & SDRAM_ECCES_BK0ER;
+ case 1:
+ return status->ecces & SDRAM_ECCES_BK1ER;
+ default:
+ return false;
+ }
+}
+
+/**
+ * ppc4xx_edac_generate_bank_message - generate interpretted bank status message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ * with the bank message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ * message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ * message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the ECCESS[BKNER]
+ * field of the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_bank_message(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status,
+ char *buffer,
+ size_t size)
+{
+ int n, total = 0;
+ unsigned int row, rows;
+
+ n = snprintf(buffer, size, "%s: Banks: ", mci->dev_name);
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ for (rows = 0, row = 0; row < mci->nr_csrows; row++) {
+ if (ppc4xx_edac_check_bank_error(status, row)) {
+ n = snprintf(buffer, size, "%s%u",
+ (rows++ ? ", " : ""), row);
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+ }
+ }
+
+ n = snprintf(buffer, size, "%s; ", rows ? "" : "None");
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ fail:
+ return total;
+}
+
+/**
+ * ppc4xx_edac_generate_checkbit_message - generate interpretted checkbit message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ * with the checkbit message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ * message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ * message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the ECCESS[CKBER]
+ * field of the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_checkbit_message(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status,
+ char *buffer,
+ size_t size)
+{
+ const struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+ const char *ckber = NULL;
+
+ switch (status->ecces & SDRAM_ECCES_CKBER_MASK) {
+ case SDRAM_ECCES_CKBER_NONE:
+ ckber = "None";
+ break;
+ case SDRAM_ECCES_CKBER_32_ECC_0_3:
+ ckber = "ECC0:3";
+ break;
+ case SDRAM_ECCES_CKBER_32_ECC_4_8:
+ switch (mfsdram(&pdata->dcr_host, SDRAM_MCOPT1) &
+ SDRAM_MCOPT1_WDTH_MASK) {
+ case SDRAM_MCOPT1_WDTH_16:
+ ckber = "ECC0:3";
+ break;
+ case SDRAM_MCOPT1_WDTH_32:
+ ckber = "ECC4:8";
+ break;
+ default:
+ ckber = "Unknown";
+ break;
+ }
+ break;
+ case SDRAM_ECCES_CKBER_32_ECC_0_8:
+ ckber = "ECC0:8";
+ break;
+ default:
+ ckber = "Unknown";
+ break;
+ }
+
+ return snprintf(buffer, size, "Checkbit Error: %s", ckber);
+}
+
+/**
+ * ppc4xx_edac_generate_lane_message - generate interpretted byte lane message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ * with the byte lane message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ * message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ * message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the ECCESS[BNCE]
+ * field of the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_lane_message(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status,
+ char *buffer,
+ size_t size)
+{
+ int n, total = 0;
+ unsigned int lane, lanes;
+ const unsigned int first_lane = 0;
+ const unsigned int lane_count = 16;
+
+ n = snprintf(buffer, size, "; Byte Lane Errors: ");
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ for (lanes = 0, lane = first_lane; lane < lane_count; lane++) {
+ if ((status->ecces & SDRAM_ECCES_BNCE_ENCODE(lane)) != 0) {
+ n = snprintf(buffer, size,
+ "%s%u",
+ (lanes++ ? ", " : ""), lane);
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+ }
+ }
+
+ n = snprintf(buffer, size, "%s; ", lanes ? "" : "None");
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ fail:
+ return total;
+}
+
+/**
+ * ppc4xx_edac_generate_ecc_message - generate interpretted ECC status message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ * with the ECCES message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ * message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ * message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the ECCESS register of
+ * the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_ecc_message(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status,
+ char *buffer,
+ size_t size)
+{
+ int n, total = 0;
+
+ n = ppc4xx_edac_generate_bank_message(mci, status, buffer, size);
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ n = ppc4xx_edac_generate_checkbit_message(mci, status, buffer, size);
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ n = ppc4xx_edac_generate_lane_message(mci, status, buffer, size);
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ fail:
+ return total;
+}
+
+/**
+ * ppc4xx_edac_generate_plb_message - generate interpretted PLB status message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ * with the PLB message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ * message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ * message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the PLB-related BESR
+ * and/or WMIRQ registers of the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_plb_message(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status,
+ char *buffer,
+ size_t size)
+{
+ unsigned int master;
+ bool read;
+
+ if ((status->besr & SDRAM_BESR_MASK) == 0)
+ return 0;
+
+ if ((status->besr & SDRAM_BESR_M0ET_MASK) == SDRAM_BESR_M0ET_NONE)
+ return 0;
+
+ read = ((status->besr & SDRAM_BESR_M0RW_MASK) == SDRAM_BESR_M0RW_READ);
+
+ master = SDRAM_BESR_M0ID_DECODE(status->besr);
+
+ return snprintf(buffer, size,
+ "%s error w/ PLB master %u \"%s\"; ",
+ (read ? "Read" : "Write"),
+ master,
+ (((master >= SDRAM_PLB_M0ID_FIRST) &&
+ (master <= SDRAM_PLB_M0ID_LAST)) ?
+ ppc4xx_plb_masters[master] : "UNKNOWN"));
+}
+
+/**
+ * ppc4xx_edac_generate_message - generate interpretted status message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ * with the driver-unique message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ * message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ * message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the driver-unique
+ * EDAC report message from the specified ECC status.
+ */
+static void
+ppc4xx_edac_generate_message(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status,
+ char *buffer,
+ size_t size)
+{
+ int n;
+
+ if (buffer == NULL || size == 0)
+ return;
+
+ n = ppc4xx_edac_generate_ecc_message(mci, status, buffer, size);
+
+ if (n < 0 || n >= size)
+ return;
+
+ buffer += n;
+ size -= n;
+
+ ppc4xx_edac_generate_plb_message(mci, status, buffer, size);
+}
+
+#ifdef DEBUG
+/**
+ * ppc4xx_ecc_dump_status - dump controller ECC status registers
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the status being dumped.
+ * @status: A pointer to the ECC status structure to generate the
+ * dump from.
+ *
+ * This routine dumps to the kernel log buffer the raw and
+ * interpretted specified ECC status.
+ */
+static void
+ppc4xx_ecc_dump_status(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status)
+{
+ char message[PPC4XX_EDAC_MESSAGE_SIZE];
+
+ ppc4xx_edac_generate_message(mci, status, message, sizeof(message));
+
+ ppc4xx_edac_mc_printk(KERN_INFO, mci,
+ "\n"
+ "\tECCES: 0x%08x\n"
+ "\tWMIRQ: 0x%08x\n"
+ "\tBESR: 0x%08x\n"
+ "\tBEAR: 0x%08x%08x\n"
+ "\t%s\n",
+ status->ecces,
+ status->wmirq,
+ status->besr,
+ status->bearh,
+ status->bearl,
+ message);
+}
+#endif /* DEBUG */
+
+/**
+ * ppc4xx_ecc_get_status - get controller ECC status
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the status being retrieved.
+ * @status: A pointer to the ECC status structure to populate the
+ * ECC status with.
+ *
+ * This routine reads and masks, as appropriate, all the relevant
+ * status registers that deal with ibm,sdram-4xx-ddr2 ECC errors.
+ * While we read all of them, for correctable errors, we only expect
+ * to deal with ECCES. For uncorrectable errors, we expect to deal
+ * with all of them.
+ */
+static void
+ppc4xx_ecc_get_status(const struct mem_ctl_info *mci,
+ struct ppc4xx_ecc_status *status)
+{
+ const struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+ const dcr_host_t *dcr_host = &pdata->dcr_host;
+
+ status->ecces = mfsdram(dcr_host, SDRAM_ECCES) & SDRAM_ECCES_MASK;
+ status->wmirq = mfsdram(dcr_host, SDRAM_WMIRQ) & SDRAM_WMIRQ_MASK;
+ status->besr = mfsdram(dcr_host, SDRAM_BESR) & SDRAM_BESR_MASK;
+ status->bearl = mfsdram(dcr_host, SDRAM_BEARL);
+ status->bearh = mfsdram(dcr_host, SDRAM_BEARH);
+}
+
+/**
+ * ppc4xx_ecc_clear_status - clear controller ECC status
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the status being cleared.
+ * @status: A pointer to the ECC status structure containing the
+ * values to write to clear the ECC status.
+ *
+ * This routine clears--by writing the masked (as appropriate) status
+ * values back to--the status registers that deal with
+ * ibm,sdram-4xx-ddr2 ECC errors.
+ */
+static void
+ppc4xx_ecc_clear_status(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status)
+{
+ const struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+ const dcr_host_t *dcr_host = &pdata->dcr_host;
+
+ mtsdram(dcr_host, SDRAM_ECCES, status->ecces & SDRAM_ECCES_MASK);
+ mtsdram(dcr_host, SDRAM_WMIRQ, status->wmirq & SDRAM_WMIRQ_MASK);
+ mtsdram(dcr_host, SDRAM_BESR, status->besr & SDRAM_BESR_MASK);
+ mtsdram(dcr_host, SDRAM_BEARL, 0);
+ mtsdram(dcr_host, SDRAM_BEARH, 0);
+}
+
+/**
+ * ppc4xx_edac_handle_ce - handle controller correctable ECC error (CE)
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the correctable error being handled and reported.
+ * @status: A pointer to the ECC status structure associated with
+ * the correctable error being handled and reported.
+ *
+ * This routine handles an ibm,sdram-4xx-ddr2 controller ECC
+ * correctable error. Per the aforementioned discussion, there's not
+ * enough status available to use the full EDAC correctable error
+ * interface, so we just pass driver-unique message to the "no info"
+ * interface.
+ */
+static void
+ppc4xx_edac_handle_ce(struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status)
+{
+ int row;
+ char message[PPC4XX_EDAC_MESSAGE_SIZE];
+
+ ppc4xx_edac_generate_message(mci, status, message, sizeof(message));
+
+ for (row = 0; row < mci->nr_csrows; row++)
+ if (ppc4xx_edac_check_bank_error(status, row))
+ edac_mc_handle_ce_no_info(mci, message);
+}
+
+/**
+ * ppc4xx_edac_handle_ue - handle controller uncorrectable ECC error (UE)
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the uncorrectable error being handled and
+ * reported.
+ * @status: A pointer to the ECC status structure associated with
+ * the uncorrectable error being handled and reported.
+ *
+ * This routine handles an ibm,sdram-4xx-ddr2 controller ECC
+ * uncorrectable error.
+ */
+static void
+ppc4xx_edac_handle_ue(struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status)
+{
+ const u64 bear = ((u64)status->bearh << 32 | status->bearl);
+ const unsigned long page = bear >> PAGE_SHIFT;
+ const unsigned long offset = bear & ~PAGE_MASK;
+ int row;
+ char message[PPC4XX_EDAC_MESSAGE_SIZE];
+
+ ppc4xx_edac_generate_message(mci, status, message, sizeof(message));
+
+ for (row = 0; row < mci->nr_csrows; row++)
+ if (ppc4xx_edac_check_bank_error(status, row))
+ edac_mc_handle_ue(mci, page, offset, row, message);
+}
+
+/**
+ * ppc4xx_edac_check - check controller for ECC errors
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the ibm,sdram-4xx-ddr2 controller being
+ * checked.
+ *
+ * This routine is used to check and post ECC errors and is called by
+ * both the EDAC polling thread and this driver's CE and UE interrupt
+ * handler.
+ */
+static void
+ppc4xx_edac_check(struct mem_ctl_info *mci)
+{
+#ifdef DEBUG
+ static unsigned int count;
+#endif
+ struct ppc4xx_ecc_status status;
+
+ ppc4xx_ecc_get_status(mci, &status);
+
+#ifdef DEBUG
+ if (count++ % 30 == 0)
+ ppc4xx_ecc_dump_status(mci, &status);
+#endif
+
+ if (status.ecces & SDRAM_ECCES_UE)
+ ppc4xx_edac_handle_ue(mci, &status);
+
+ if (status.ecces & SDRAM_ECCES_CE)
+ ppc4xx_edac_handle_ce(mci, &status);
+
+ ppc4xx_ecc_clear_status(mci, &status);
+}
+
+/**
+ * ppc4xx_edac_isr - SEC (CE) and DED (UE) interrupt service routine
+ * @irq: The virtual interrupt number being serviced.
+ * @dev_id: A pointer to the EDAC memory controller instance
+ * associated with the interrupt being handled.
+ *
+ * This routine implements the interrupt handler for both correctable
+ * (CE) and uncorrectable (UE) ECC errors for the ibm,sdram-4xx-ddr2
+ * controller. It simply calls through to the same routine used during
+ * polling to check, report and clear the ECC status.
+ *
+ * Unconditionally returns IRQ_HANDLED.
+ */
+static irqreturn_t
+ppc4xx_edac_isr(int irq, void *dev_id)
+{
+ struct mem_ctl_info *mci = dev_id;
+
+ ppc4xx_edac_check(mci);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * ppc4xx_edac_get_dtype - return the controller memory width
+ * @mcopt1: The 32-bit Memory Controller Option 1 register value
+ * currently set for the controller, from which the width
+ * is derived.
+ *
+ * This routine returns the EDAC device type width appropriate for the
+ * current controller configuration.
+ *
+ * TODO: This needs to be conditioned dynamically through feature
+ * flags or some such when other controller variants are supported as
+ * the 405EX[r] is 16-/32-bit and the others are 32-/64-bit with the
+ * 16- and 64-bit field definition/value/enumeration (b1) overloaded
+ * among them.
+ *
+ * Returns a device type width enumeration.
+ */
+static enum dev_type __devinit
+ppc4xx_edac_get_dtype(u32 mcopt1)
+{
+ switch (mcopt1 & SDRAM_MCOPT1_WDTH_MASK) {
+ case SDRAM_MCOPT1_WDTH_16:
+ return DEV_X2;
+ case SDRAM_MCOPT1_WDTH_32:
+ return DEV_X4;
+ default:
+ return DEV_UNKNOWN;
+ }
+}
+
+/**
+ * ppc4xx_edac_get_mtype - return controller memory type
+ * @mcopt1: The 32-bit Memory Controller Option 1 register value
+ * currently set for the controller, from which the memory type
+ * is derived.
+ *
+ * This routine returns the EDAC memory type appropriate for the
+ * current controller configuration.
+ *
+ * Returns a memory type enumeration.
+ */
+static enum mem_type __devinit
+ppc4xx_edac_get_mtype(u32 mcopt1)
+{
+ bool rden = ((mcopt1 & SDRAM_MCOPT1_RDEN_MASK) == SDRAM_MCOPT1_RDEN);
+
+ switch (mcopt1 & SDRAM_MCOPT1_DDR_TYPE_MASK) {
+ case SDRAM_MCOPT1_DDR2_TYPE:
+ return rden ? MEM_RDDR2 : MEM_DDR2;
+ case SDRAM_MCOPT1_DDR1_TYPE:
+ return rden ? MEM_RDDR : MEM_DDR;
+ default:
+ return MEM_UNKNOWN;
+ }
+}
+
+/**
+ * ppc4xx_edac_init_csrows - intialize driver instance rows
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the ibm,sdram-4xx-ddr2 controller for which
+ * the csrows (i.e. banks/ranks) are being initialized.
+ * @mcopt1: The 32-bit Memory Controller Option 1 register value
+ * currently set for the controller, from which bank width
+ * and memory typ information is derived.
+ *
+ * This routine intializes the virtual "chip select rows" associated
+ * with the EDAC memory controller instance. An ibm,sdram-4xx-ddr2
+ * controller bank/rank is mapped to a row.
+ *
+ * Returns 0 if OK; otherwise, -EINVAL if the memory bank size
+ * configuration cannot be determined.
+ */
+static int __devinit
+ppc4xx_edac_init_csrows(struct mem_ctl_info *mci, u32 mcopt1)
+{
+ const struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+ int status = 0;
+ enum mem_type mtype;
+ enum dev_type dtype;
+ enum edac_type edac_mode;
+ int row;
+ u32 mbxcf, size;
+ static u32 ppc4xx_last_page;
+
+ /* Establish the memory type and width */
+
+ mtype = ppc4xx_edac_get_mtype(mcopt1);
+ dtype = ppc4xx_edac_get_dtype(mcopt1);
+
+ /* Establish EDAC mode */
+
+ if (mci->edac_cap & EDAC_FLAG_SECDED)
+ edac_mode = EDAC_SECDED;
+ else if (mci->edac_cap & EDAC_FLAG_EC)
+ edac_mode = EDAC_EC;
+ else
+ edac_mode = EDAC_NONE;
+
+ /*
+ * Initialize each chip select row structure which correspond
+ * 1:1 with a controller bank/rank.
+ */
+
+ for (row = 0; row < mci->nr_csrows; row++) {
+ struct csrow_info *csi = &mci->csrows[row];
+
+ /*
+ * Get the configuration settings for this
+ * row/bank/rank and skip disabled banks.
+ */
+
+ mbxcf = mfsdram(&pdata->dcr_host, SDRAM_MBXCF(row));
+
+ if ((mbxcf & SDRAM_MBCF_BE_MASK) != SDRAM_MBCF_BE_ENABLE)
+ continue;
+
+ /* Map the bank configuration size setting to pages. */
+
+ size = mbxcf & SDRAM_MBCF_SZ_MASK;
+
+ switch (size) {
+ case SDRAM_MBCF_SZ_4MB:
+ case SDRAM_MBCF_SZ_8MB:
+ case SDRAM_MBCF_SZ_16MB:
+ case SDRAM_MBCF_SZ_32MB:
+ case SDRAM_MBCF_SZ_64MB:
+ case SDRAM_MBCF_SZ_128MB:
+ case SDRAM_MBCF_SZ_256MB:
+ case SDRAM_MBCF_SZ_512MB:
+ case SDRAM_MBCF_SZ_1GB:
+ case SDRAM_MBCF_SZ_2GB:
+ case SDRAM_MBCF_SZ_4GB:
+ case SDRAM_MBCF_SZ_8GB:
+ csi->nr_pages = SDRAM_MBCF_SZ_TO_PAGES(size);
+ break;
+ default:
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Unrecognized memory bank %d "
+ "size 0x%08x\n",
+ row, SDRAM_MBCF_SZ_DECODE(size));
+ status = -EINVAL;
+ goto done;
+ }
+
+ csi->first_page = ppc4xx_last_page;
+ csi->last_page = csi->first_page + csi->nr_pages - 1;
+ csi->page_mask = 0;
+
+ /*
+ * It's unclear exactly what grain should be set to
+ * here. The SDRAM_ECCES register allows resolution of
+ * an error down to a nibble which would potentially
+ * argue for a grain of '1' byte, even though we only
+ * know the associated address for uncorrectable
+ * errors. This value is not used at present for
+ * anything other than error reporting so getting it
+ * wrong should be of little consequence. Other
+ * possible values would be the PLB width (16), the
+ * page size (PAGE_SIZE) or the memory width (2 or 4).
+ */
+
+ csi->grain = 1;
+
+ csi->mtype = mtype;
+ csi->dtype = dtype;
+
+ csi->edac_mode = edac_mode;
+
+ ppc4xx_last_page += csi->nr_pages;
+ }
+
+ done:
+ return status;
+}
+
+/**
+ * ppc4xx_edac_mc_init - intialize driver instance
+ * @mci: A pointer to the EDAC memory controller instance being
+ * initialized.
+ * @op: A pointer to the OpenFirmware device tree node associated
+ * with the controller this EDAC instance is bound to.
+ * @match: A pointer to the OpenFirmware device tree match
+ * information associated with the controller this EDAC instance
+ * is bound to.
+ * @dcr_host: A pointer to the DCR data containing the DCR mapping
+ * for this controller instance.
+ * @mcopt1: The 32-bit Memory Controller Option 1 register value
+ * currently set for the controller, from which ECC capabilities
+ * and scrub mode are derived.
+ *
+ * This routine performs initialization of the EDAC memory controller
+ * instance and related driver-private data associated with the
+ * ibm,sdram-4xx-ddr2 memory controller the instance is bound to.
+ *
+ * Returns 0 if OK; otherwise, < 0 on error.
+ */
+static int __devinit
+ppc4xx_edac_mc_init(struct mem_ctl_info *mci,
+ struct of_device *op,
+ const struct of_device_id *match,
+ const dcr_host_t *dcr_host,
+ u32 mcopt1)
+{
+ int status = 0;
+ const u32 memcheck = (mcopt1 & SDRAM_MCOPT1_MCHK_MASK);
+ struct ppc4xx_edac_pdata *pdata = NULL;
+ const struct device_node *np = op->node;
+
+ if (match == NULL)
+ return -EINVAL;
+
+ /* Initial driver pointers and private data */
+
+ mci->dev = &op->dev;
+
+ dev_set_drvdata(mci->dev, mci);
+
+ pdata = mci->pvt_info;
+
+ pdata->dcr_host = *dcr_host;
+ pdata->irqs.sec = NO_IRQ;
+ pdata->irqs.ded = NO_IRQ;
+
+ /* Initialize controller capabilities and configuration */
+
+ mci->mtype_cap = (MEM_FLAG_DDR | MEM_FLAG_RDDR |
+ MEM_FLAG_DDR2 | MEM_FLAG_RDDR2);
+
+ mci->edac_ctl_cap = (EDAC_FLAG_NONE |
+ EDAC_FLAG_EC |
+ EDAC_FLAG_SECDED);
+
+ mci->scrub_cap = SCRUB_NONE;
+ mci->scrub_mode = SCRUB_NONE;
+
+ /*
+ * Update the actual capabilites based on the MCOPT1[MCHK]
+ * settings. Scrubbing is only useful if reporting is enabled.
+ */
+
+ switch (memcheck) {
+ case SDRAM_MCOPT1_MCHK_CHK:
+ mci->edac_cap = EDAC_FLAG_EC;
+ break;
+ case SDRAM_MCOPT1_MCHK_CHK_REP:
+ mci->edac_cap = (EDAC_FLAG_EC | EDAC_FLAG_SECDED);
+ mci->scrub_mode = SCRUB_SW_SRC;
+ break;
+ default:
+ mci->edac_cap = EDAC_FLAG_NONE;
+ break;
+ }
+
+ /* Initialize strings */
+
+ mci->mod_name = PPC4XX_EDAC_MODULE_NAME;
+ mci->mod_ver = PPC4XX_EDAC_MODULE_REVISION;
+ mci->ctl_name = match->compatible,
+ mci->dev_name = np->full_name;
+
+ /* Initialize callbacks */
+
+ mci->edac_check = ppc4xx_edac_check;
+ mci->ctl_page_to_phys = NULL;
+
+ /* Initialize chip select rows */
+
+ status = ppc4xx_edac_init_csrows(mci, mcopt1);
+
+ if (status)
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Failed to initialize rows!\n");
+
+ return status;
+}
+
+/**
+ * ppc4xx_edac_register_irq - setup and register controller interrupts
+ * @op: A pointer to the OpenFirmware device tree node associated
+ * with the controller this EDAC instance is bound to.
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the ibm,sdram-4xx-ddr2 controller for which
+ * interrupts are being registered.
+ *
+ * This routine parses the correctable (CE) and uncorrectable error (UE)
+ * interrupts from the device tree node and maps and assigns them to
+ * the associated EDAC memory controller instance.
+ *
+ * Returns 0 if OK; otherwise, -ENODEV if the interrupts could not be
+ * mapped and assigned.
+ */
+static int __devinit
+ppc4xx_edac_register_irq(struct of_device *op, struct mem_ctl_info *mci)
+{
+ int status = 0;
+ int ded_irq, sec_irq;
+ struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+ struct device_node *np = op->node;
+
+ ded_irq = irq_of_parse_and_map(np, INTMAP_ECCDED_INDEX);
+ sec_irq = irq_of_parse_and_map(np, INTMAP_ECCSEC_INDEX);
+
+ if (ded_irq == NO_IRQ || sec_irq == NO_IRQ) {
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Unable to map interrupts.\n");
+ status = -ENODEV;
+ goto fail;
+ }
+
+ status = request_irq(ded_irq,
+ ppc4xx_edac_isr,
+ IRQF_DISABLED,
+ "[EDAC] MC ECCDED",
+ mci);
+
+ if (status < 0) {
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Unable to request irq %d for ECC DED",
+ ded_irq);
+ status = -ENODEV;
+ goto fail1;
+ }
+
+ status = request_irq(sec_irq,
+ ppc4xx_edac_isr,
+ IRQF_DISABLED,
+ "[EDAC] MC ECCSEC",
+ mci);
+
+ if (status < 0) {
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Unable to request irq %d for ECC SEC",
+ sec_irq);
+ status = -ENODEV;
+ goto fail2;
+ }
+
+ ppc4xx_edac_mc_printk(KERN_INFO, mci, "ECCDED irq is %d\n", ded_irq);
+ ppc4xx_edac_mc_printk(KERN_INFO, mci, "ECCSEC irq is %d\n", sec_irq);
+
+ pdata->irqs.ded = ded_irq;
+ pdata->irqs.sec = sec_irq;
+
+ return 0;
+
+ fail2:
+ free_irq(sec_irq, mci);
+
+ fail1:
+ free_irq(ded_irq, mci);
+
+ fail:
+ return status;
+}
+
+/**
+ * ppc4xx_edac_map_dcrs - locate and map controller registers
+ * @np: A pointer to the device tree node containing the DCR
+ * resources to map.
+ * @dcr_host: A pointer to the DCR data to populate with the
+ * DCR mapping.
+ *
+ * This routine attempts to locate in the device tree and map the DCR
+ * register resources associated with the controller's indirect DCR
+ * address and data windows.
+ *
+ * Returns 0 if the DCRs were successfully mapped; otherwise, < 0 on
+ * error.
+ */
+static int __devinit
+ppc4xx_edac_map_dcrs(const struct device_node *np, dcr_host_t *dcr_host)
+{
+ unsigned int dcr_base, dcr_len;
+
+ if (np == NULL || dcr_host == NULL)
+ return -EINVAL;
+
+ /* Get the DCR resource extent and sanity check the values. */
+
+ dcr_base = dcr_resource_start(np, 0);
+ dcr_len = dcr_resource_len(np, 0);
+
+ if (dcr_base == 0 || dcr_len == 0) {
+ ppc4xx_edac_printk(KERN_ERR,
+ "Failed to obtain DCR property.\n");
+ return -ENODEV;
+ }
+
+ if (dcr_len != SDRAM_DCR_RESOURCE_LEN) {
+ ppc4xx_edac_printk(KERN_ERR,
+ "Unexpected DCR length %d, expected %d.\n",
+ dcr_len, SDRAM_DCR_RESOURCE_LEN);
+ return -ENODEV;
+ }
+
+ /* Attempt to map the DCR extent. */
+
+ *dcr_host = dcr_map(np, dcr_base, dcr_len);
+
+ if (!DCR_MAP_OK(*dcr_host)) {
+ ppc4xx_edac_printk(KERN_INFO, "Failed to map DCRs.\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/**
+ * ppc4xx_edac_probe - check controller and bind driver
+ * @op: A pointer to the OpenFirmware device tree node associated
+ * with the controller being probed for driver binding.
+ * @match: A pointer to the OpenFirmware device tree match
+ * information associated with the controller being probed
+ * for driver binding.
+ *
+ * This routine probes a specific ibm,sdram-4xx-ddr2 controller
+ * instance for binding with the driver.
+ *
+ * Returns 0 if the controller instance was successfully bound to the
+ * driver; otherwise, < 0 on error.
+ */
+static int __devinit
+ppc4xx_edac_probe(struct of_device *op, const struct of_device_id *match)
+{
+ int status = 0;
+ u32 mcopt1, memcheck;
+ dcr_host_t dcr_host;
+ const struct device_node *np = op->node;
+ struct mem_ctl_info *mci = NULL;
+ static int ppc4xx_edac_instance;
+
+ /*
+ * At this point, we only support the controller realized on
+ * the AMCC PPC 405EX[r]. Reject anything else.
+ */
+
+ if (!of_device_is_compatible(np, "ibm,sdram-405ex") &&
+ !of_device_is_compatible(np, "ibm,sdram-405exr")) {
+ ppc4xx_edac_printk(KERN_NOTICE,
+ "Only the PPC405EX[r] is supported.\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Next, get the DCR property and attempt to map it so that we
+ * can probe the controller.
+ */
+
+ status = ppc4xx_edac_map_dcrs(np, &dcr_host);
+
+ if (status)
+ return status;
+
+ /*
+ * First determine whether ECC is enabled at all. If not,
+ * there is no useful checking or monitoring that can be done
+ * for this controller.
+ */
+
+ mcopt1 = mfsdram(&dcr_host, SDRAM_MCOPT1);
+ memcheck = (mcopt1 & SDRAM_MCOPT1_MCHK_MASK);
+
+ if (memcheck == SDRAM_MCOPT1_MCHK_NON) {
+ ppc4xx_edac_printk(KERN_INFO, "%s: No ECC memory detected or "
+ "ECC is disabled.\n", np->full_name);
+ status = -ENODEV;
+ goto done;
+ }
+
+ /*
+ * At this point, we know ECC is enabled, allocate an EDAC
+ * controller instance and perform the appropriate
+ * initialization.
+ */
+
+ mci = edac_mc_alloc(sizeof(struct ppc4xx_edac_pdata),
+ ppc4xx_edac_nr_csrows,
+ ppc4xx_edac_nr_chans,
+ ppc4xx_edac_instance);
+
+ if (mci == NULL) {
+ ppc4xx_edac_printk(KERN_ERR, "%s: "
+ "Failed to allocate EDAC MC instance!\n",
+ np->full_name);
+ status = -ENOMEM;
+ goto done;
+ }
+
+ status = ppc4xx_edac_mc_init(mci, op, match, &dcr_host, mcopt1);
+
+ if (status) {
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Failed to initialize instance!\n");
+ goto fail;
+ }
+
+ /*
+ * We have a valid, initialized EDAC instance bound to the
+ * controller. Attempt to register it with the EDAC subsystem
+ * and, if necessary, register interrupts.
+ */
+
+ if (edac_mc_add_mc(mci)) {
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Failed to add instance!\n");
+ status = -ENODEV;
+ goto fail;
+ }
+
+ if (edac_op_state == EDAC_OPSTATE_INT) {
+ status = ppc4xx_edac_register_irq(op, mci);
+
+ if (status)
+ goto fail1;
+ }
+
+ ppc4xx_edac_instance++;
+
+ return 0;
+
+ fail1:
+ edac_mc_del_mc(mci->dev);
+
+ fail:
+ edac_mc_free(mci);
+
+ done:
+ return status;
+}
+
+/**
+ * ppc4xx_edac_remove - unbind driver from controller
+ * @op: A pointer to the OpenFirmware device tree node associated
+ * with the controller this EDAC instance is to be unbound/removed
+ * from.
+ *
+ * This routine unbinds the EDAC memory controller instance associated
+ * with the specified ibm,sdram-4xx-ddr2 controller described by the
+ * OpenFirmware device tree node passed as a parameter.
+ *
+ * Unconditionally returns 0.
+ */
+static int
+ppc4xx_edac_remove(struct of_device *op)
+{
+ struct mem_ctl_info *mci = dev_get_drvdata(&op->dev);
+ struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+
+ if (edac_op_state == EDAC_OPSTATE_INT) {
+ free_irq(pdata->irqs.sec, mci);
+ free_irq(pdata->irqs.ded, mci);
+ }
+
+ dcr_unmap(pdata->dcr_host, SDRAM_DCR_RESOURCE_LEN);
+
+ edac_mc_del_mc(mci->dev);
+ edac_mc_free(mci);
+
+ return 0;
+}
+
+/**
+ * ppc4xx_edac_opstate_init - initialize EDAC reporting method
+ *
+ * This routine ensures that the EDAC memory controller reporting
+ * method is mapped to a sane value as the EDAC core defines the value
+ * to EDAC_OPSTATE_INVAL by default. We don't call the global
+ * opstate_init as that defaults to polling and we want interrupt as
+ * the default.
+ */
+static inline void __init
+ppc4xx_edac_opstate_init(void)
+{
+ switch (edac_op_state) {
+ case EDAC_OPSTATE_POLL:
+ case EDAC_OPSTATE_INT:
+ break;
+ default:
+ edac_op_state = EDAC_OPSTATE_INT;
+ break;
+ }
+
+ ppc4xx_edac_printk(KERN_INFO, "Reporting type: %s\n",
+ ((edac_op_state == EDAC_OPSTATE_POLL) ?
+ EDAC_OPSTATE_POLL_STR :
+ ((edac_op_state == EDAC_OPSTATE_INT) ?
+ EDAC_OPSTATE_INT_STR :
+ EDAC_OPSTATE_UNKNOWN_STR)));
+}
+
+/**
+ * ppc4xx_edac_init - driver/module insertion entry point
+ *
+ * This routine is the driver/module insertion entry point. It
+ * initializes the EDAC memory controller reporting state and
+ * registers the driver as an OpenFirmware device tree platform
+ * driver.
+ */
+static int __init
+ppc4xx_edac_init(void)
+{
+ ppc4xx_edac_printk(KERN_INFO, PPC4XX_EDAC_MODULE_REVISION "\n");
+
+ ppc4xx_edac_opstate_init();
+
+ return of_register_platform_driver(&ppc4xx_edac_driver);
+}
+
+/**
+ * ppc4xx_edac_exit - driver/module removal entry point
+ *
+ * This routine is the driver/module removal entry point. It
+ * unregisters the driver as an OpenFirmware device tree platform
+ * driver.
+ */
+static void __exit
+ppc4xx_edac_exit(void)
+{
+ of_unregister_platform_driver(&ppc4xx_edac_driver);
+}
+
+module_init(ppc4xx_edac_init);
+module_exit(ppc4xx_edac_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Grant Erickson <gerickson@nuovations.com>");
+MODULE_DESCRIPTION("EDAC MC Driver for the PPC4xx IBM DDR2 Memory Controller");
+module_param(edac_op_state, int, 0444);
+MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting State: "
+ "0=" EDAC_OPSTATE_POLL_STR ", 2=" EDAC_OPSTATE_INT_STR);
diff --git a/drivers/edac/ppc4xx_edac.h b/drivers/edac/ppc4xx_edac.h
new file mode 100644
index 000000000000..d3154764c449
--- /dev/null
+++ b/drivers/edac/ppc4xx_edac.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2008 Nuovation System Designs, LLC
+ * Grant Erickson <gerickson@nuovations.com>
+ *
+ * This file defines processor mnemonics for accessing and managing
+ * the IBM DDR1/DDR2 ECC controller found in the 405EX[r], 440SP,
+ * 440SPe, 460EX, 460GT and 460SX.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#ifndef __PPC4XX_EDAC_H
+#define __PPC4XX_EDAC_H
+
+#include <linux/types.h>
+
+/*
+ * Macro for generating register field mnemonics
+ */
+#define PPC_REG_BITS 32
+#define PPC_REG_VAL(bit, val) ((val) << ((PPC_REG_BITS - 1) - (bit)))
+#define PPC_REG_DECODE(bit, val) ((val) >> ((PPC_REG_BITS - 1) - (bit)))
+
+/*
+ * IBM 4xx DDR1/DDR2 SDRAM memory controller registers (at least those
+ * relevant to ECC)
+ */
+#define SDRAM_BESR 0x00 /* Error status (read/clear) */
+#define SDRAM_BESRT 0x01 /* Error statuss (test/set) */
+#define SDRAM_BEARL 0x02 /* Error address low */
+#define SDRAM_BEARH 0x03 /* Error address high */
+#define SDRAM_WMIRQ 0x06 /* Write master (read/clear) */
+#define SDRAM_WMIRQT 0x07 /* Write master (test/set) */
+#define SDRAM_MCOPT1 0x20 /* Controller options 1 */
+#define SDRAM_MBXCF_BASE 0x40 /* Bank n configuration base */
+#define SDRAM_MBXCF(n) (SDRAM_MBXCF_BASE + (4 * (n)))
+#define SDRAM_MB0CF SDRAM_MBXCF(0)
+#define SDRAM_MB1CF SDRAM_MBXCF(1)
+#define SDRAM_MB2CF SDRAM_MBXCF(2)
+#define SDRAM_MB3CF SDRAM_MBXCF(3)
+#define SDRAM_ECCCR 0x98 /* ECC error status */
+#define SDRAM_ECCES SDRAM_ECCCR
+
+/*
+ * PLB Master IDs
+ */
+#define SDRAM_PLB_M0ID_FIRST 0
+#define SDRAM_PLB_M0ID_ICU SDRAM_PLB_M0ID_FIRST
+#define SDRAM_PLB_M0ID_PCIE0 1
+#define SDRAM_PLB_M0ID_PCIE1 2
+#define SDRAM_PLB_M0ID_DMA 3
+#define SDRAM_PLB_M0ID_DCU 4
+#define SDRAM_PLB_M0ID_OPB 5
+#define SDRAM_PLB_M0ID_MAL 6
+#define SDRAM_PLB_M0ID_SEC 7
+#define SDRAM_PLB_M0ID_AHB 8
+#define SDRAM_PLB_M0ID_LAST SDRAM_PLB_M0ID_AHB
+#define SDRAM_PLB_M0ID_COUNT (SDRAM_PLB_M0ID_LAST - \
+ SDRAM_PLB_M0ID_FIRST + 1)
+
+/*
+ * Memory Controller Bus Error Status Register
+ */
+#define SDRAM_BESR_MASK PPC_REG_VAL(7, 0xFF)
+#define SDRAM_BESR_M0ID_MASK PPC_REG_VAL(3, 0xF)
+#define SDRAM_BESR_M0ID_DECODE(n) PPC_REG_DECODE(3, n)
+#define SDRAM_BESR_M0ID_ICU PPC_REG_VAL(3, SDRAM_PLB_M0ID_ICU)
+#define SDRAM_BESR_M0ID_PCIE0 PPC_REG_VAL(3, SDRAM_PLB_M0ID_PCIE0)
+#define SDRAM_BESR_M0ID_PCIE1 PPC_REG_VAL(3, SDRAM_PLB_M0ID_PCIE1)
+#define SDRAM_BESR_M0ID_DMA PPC_REG_VAL(3, SDRAM_PLB_M0ID_DMA)
+#define SDRAM_BESR_M0ID_DCU PPC_REG_VAL(3, SDRAM_PLB_M0ID_DCU)
+#define SDRAM_BESR_M0ID_OPB PPC_REG_VAL(3, SDRAM_PLB_M0ID_OPB)
+#define SDRAM_BESR_M0ID_MAL PPC_REG_VAL(3, SDRAM_PLB_M0ID_MAL)
+#define SDRAM_BESR_M0ID_SEC PPC_REG_VAL(3, SDRAM_PLB_M0ID_SEC)
+#define SDRAM_BESR_M0ID_AHB PPC_REG_VAL(3, SDRAM_PLB_M0ID_AHB)
+#define SDRAM_BESR_M0ET_MASK PPC_REG_VAL(6, 0x7)
+#define SDRAM_BESR_M0ET_NONE PPC_REG_VAL(6, 0)
+#define SDRAM_BESR_M0ET_ECC PPC_REG_VAL(6, 1)
+#define SDRAM_BESR_M0RW_MASK PPC_REG_VAL(7, 1)
+#define SDRAM_BESR_M0RW_WRITE PPC_REG_VAL(7, 0)
+#define SDRAM_BESR_M0RW_READ PPC_REG_VAL(7, 1)
+
+/*
+ * Memory Controller PLB Write Master Interrupt Register
+ */
+#define SDRAM_WMIRQ_MASK PPC_REG_VAL(8, 0x1FF)
+#define SDRAM_WMIRQ_ENCODE(id) PPC_REG_VAL((id % \
+ SDRAM_PLB_M0ID_COUNT), 1)
+#define SDRAM_WMIRQ_ICU PPC_REG_VAL(SDRAM_PLB_M0ID_ICU, 1)
+#define SDRAM_WMIRQ_PCIE0 PPC_REG_VAL(SDRAM_PLB_M0ID_PCIE0, 1)
+#define SDRAM_WMIRQ_PCIE1 PPC_REG_VAL(SDRAM_PLB_M0ID_PCIE1, 1)
+#define SDRAM_WMIRQ_DMA PPC_REG_VAL(SDRAM_PLB_M0ID_DMA, 1)
+#define SDRAM_WMIRQ_DCU PPC_REG_VAL(SDRAM_PLB_M0ID_DCU, 1)
+#define SDRAM_WMIRQ_OPB PPC_REG_VAL(SDRAM_PLB_M0ID_OPB, 1)
+#define SDRAM_WMIRQ_MAL PPC_REG_VAL(SDRAM_PLB_M0ID_MAL, 1)
+#define SDRAM_WMIRQ_SEC PPC_REG_VAL(SDRAM_PLB_M0ID_SEC, 1)
+#define SDRAM_WMIRQ_AHB PPC_REG_VAL(SDRAM_PLB_M0ID_AHB, 1)
+
+/*
+ * Memory Controller Options 1 Register
+ */
+#define SDRAM_MCOPT1_MCHK_MASK PPC_REG_VAL(3, 0x3) /* ECC mask */
+#define SDRAM_MCOPT1_MCHK_NON PPC_REG_VAL(3, 0x0) /* No ECC gen */
+#define SDRAM_MCOPT1_MCHK_GEN PPC_REG_VAL(3, 0x2) /* ECC gen */
+#define SDRAM_MCOPT1_MCHK_CHK PPC_REG_VAL(3, 0x1) /* ECC gen and chk */
+#define SDRAM_MCOPT1_MCHK_CHK_REP PPC_REG_VAL(3, 0x3) /* ECC gen/chk/rpt */
+#define SDRAM_MCOPT1_MCHK_DECODE(n) ((((u32)(n)) >> 28) & 0x3)
+#define SDRAM_MCOPT1_RDEN_MASK PPC_REG_VAL(4, 0x1) /* Rgstrd DIMM mask */
+#define SDRAM_MCOPT1_RDEN PPC_REG_VAL(4, 0x1) /* Rgstrd DIMM enbl */
+#define SDRAM_MCOPT1_WDTH_MASK PPC_REG_VAL(7, 0x1) /* Width mask */
+#define SDRAM_MCOPT1_WDTH_32 PPC_REG_VAL(7, 0x0) /* 32 bits */
+#define SDRAM_MCOPT1_WDTH_16 PPC_REG_VAL(7, 0x1) /* 16 bits */
+#define SDRAM_MCOPT1_DDR_TYPE_MASK PPC_REG_VAL(11, 0x1) /* DDR type mask */
+#define SDRAM_MCOPT1_DDR1_TYPE PPC_REG_VAL(11, 0x0) /* DDR1 type */
+#define SDRAM_MCOPT1_DDR2_TYPE PPC_REG_VAL(11, 0x1) /* DDR2 type */
+
+/*
+ * Memory Bank 0 - n Configuration Register
+ */
+#define SDRAM_MBCF_BA_MASK PPC_REG_VAL(12, 0x1FFF)
+#define SDRAM_MBCF_SZ_MASK PPC_REG_VAL(19, 0xF)
+#define SDRAM_MBCF_SZ_DECODE(mbxcf) PPC_REG_DECODE(19, mbxcf)
+#define SDRAM_MBCF_SZ_4MB PPC_REG_VAL(19, 0x0)
+#define SDRAM_MBCF_SZ_8MB PPC_REG_VAL(19, 0x1)
+#define SDRAM_MBCF_SZ_16MB PPC_REG_VAL(19, 0x2)
+#define SDRAM_MBCF_SZ_32MB PPC_REG_VAL(19, 0x3)
+#define SDRAM_MBCF_SZ_64MB PPC_REG_VAL(19, 0x4)
+#define SDRAM_MBCF_SZ_128MB PPC_REG_VAL(19, 0x5)
+#define SDRAM_MBCF_SZ_256MB PPC_REG_VAL(19, 0x6)
+#define SDRAM_MBCF_SZ_512MB PPC_REG_VAL(19, 0x7)
+#define SDRAM_MBCF_SZ_1GB PPC_REG_VAL(19, 0x8)
+#define SDRAM_MBCF_SZ_2GB PPC_REG_VAL(19, 0x9)
+#define SDRAM_MBCF_SZ_4GB PPC_REG_VAL(19, 0xA)
+#define SDRAM_MBCF_SZ_8GB PPC_REG_VAL(19, 0xB)
+#define SDRAM_MBCF_AM_MASK PPC_REG_VAL(23, 0xF)
+#define SDRAM_MBCF_AM_MODE0 PPC_REG_VAL(23, 0x0)
+#define SDRAM_MBCF_AM_MODE1 PPC_REG_VAL(23, 0x1)
+#define SDRAM_MBCF_AM_MODE2 PPC_REG_VAL(23, 0x2)
+#define SDRAM_MBCF_AM_MODE3 PPC_REG_VAL(23, 0x3)
+#define SDRAM_MBCF_AM_MODE4 PPC_REG_VAL(23, 0x4)
+#define SDRAM_MBCF_AM_MODE5 PPC_REG_VAL(23, 0x5)
+#define SDRAM_MBCF_AM_MODE6 PPC_REG_VAL(23, 0x6)
+#define SDRAM_MBCF_AM_MODE7 PPC_REG_VAL(23, 0x7)
+#define SDRAM_MBCF_AM_MODE8 PPC_REG_VAL(23, 0x8)
+#define SDRAM_MBCF_AM_MODE9 PPC_REG_VAL(23, 0x9)
+#define SDRAM_MBCF_BE_MASK PPC_REG_VAL(31, 0x1)
+#define SDRAM_MBCF_BE_DISABLE PPC_REG_VAL(31, 0x0)
+#define SDRAM_MBCF_BE_ENABLE PPC_REG_VAL(31, 0x1)
+
+/*
+ * ECC Error Status
+ */
+#define SDRAM_ECCES_MASK PPC_REG_VAL(21, 0x3FFFFF)
+#define SDRAM_ECCES_BNCE_MASK PPC_REG_VAL(15, 0xFFFF)
+#define SDRAM_ECCES_BNCE_ENCODE(lane) PPC_REG_VAL(((lane) & 0xF), 1)
+#define SDRAM_ECCES_CKBER_MASK PPC_REG_VAL(17, 0x3)
+#define SDRAM_ECCES_CKBER_NONE PPC_REG_VAL(17, 0)
+#define SDRAM_ECCES_CKBER_16_ECC_0_3 PPC_REG_VAL(17, 2)
+#define SDRAM_ECCES_CKBER_32_ECC_0_3 PPC_REG_VAL(17, 1)
+#define SDRAM_ECCES_CKBER_32_ECC_4_8 PPC_REG_VAL(17, 2)
+#define SDRAM_ECCES_CKBER_32_ECC_0_8 PPC_REG_VAL(17, 3)
+#define SDRAM_ECCES_CE PPC_REG_VAL(18, 1)
+#define SDRAM_ECCES_UE PPC_REG_VAL(19, 1)
+#define SDRAM_ECCES_BKNER_MASK PPC_REG_VAL(21, 0x3)
+#define SDRAM_ECCES_BK0ER PPC_REG_VAL(20, 1)
+#define SDRAM_ECCES_BK1ER PPC_REG_VAL(21, 1)
+
+#endif /* __PPC4XX_EDAC_H */
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
index c950bf8606d9..66958b3f10b4 100644
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -200,7 +200,7 @@ static int __init eisa_init_device (struct eisa_root_device *root,
edev->dev.bus = &eisa_bus_type;
edev->dev.dma_mask = &edev->dma_mask;
edev->dev.coherent_dma_mask = edev->dma_mask;
- sprintf (edev->dev.bus_id, "%02X:%02X", root->bus_nr, slot);
+ dev_set_name(&edev->dev, "%02X:%02X", root->bus_nr, slot);
for (i = 0; i < EISA_MAX_RESOURCES; i++) {
#ifdef CONFIG_EISA_NAMES
@@ -301,7 +301,7 @@ static int __init eisa_probe (struct eisa_root_device *root)
struct eisa_device *edev;
printk (KERN_INFO "EISA: Probing bus %d at %s\n",
- root->bus_nr, root->dev->bus_id);
+ root->bus_nr, dev_name(root->dev));
/* First try to get hold of slot 0. If there is no device
* here, simply fail, unless root->force_probe is set. */
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index a5dd7a665aa8..8b8c8c22f0fc 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -63,8 +63,7 @@ static int descriptor_count;
#define BIB_CMC ((1) << 30)
#define BIB_IMC ((1) << 31)
-static u32 *
-generate_config_rom(struct fw_card *card, size_t *config_rom_length)
+static u32 *generate_config_rom(struct fw_card *card, size_t *config_rom_length)
{
struct fw_descriptor *desc;
static u32 config_rom[256];
@@ -128,8 +127,7 @@ generate_config_rom(struct fw_card *card, size_t *config_rom_length)
return config_rom;
}
-static void
-update_config_roms(void)
+static void update_config_roms(void)
{
struct fw_card *card;
u32 *config_rom;
@@ -141,8 +139,7 @@ update_config_roms(void)
}
}
-int
-fw_core_add_descriptor(struct fw_descriptor *desc)
+int fw_core_add_descriptor(struct fw_descriptor *desc)
{
size_t i;
@@ -171,8 +168,7 @@ fw_core_add_descriptor(struct fw_descriptor *desc)
return 0;
}
-void
-fw_core_remove_descriptor(struct fw_descriptor *desc)
+void fw_core_remove_descriptor(struct fw_descriptor *desc)
{
mutex_lock(&card_mutex);
@@ -185,12 +181,30 @@ fw_core_remove_descriptor(struct fw_descriptor *desc)
mutex_unlock(&card_mutex);
}
+static int set_broadcast_channel(struct device *dev, void *data)
+{
+ fw_device_set_broadcast_channel(fw_device(dev), (long)data);
+ return 0;
+}
+
+static void allocate_broadcast_channel(struct fw_card *card, int generation)
+{
+ int channel, bandwidth = 0;
+
+ fw_iso_resource_manage(card, generation, 1ULL << 31,
+ &channel, &bandwidth, true);
+ if (channel == 31) {
+ card->broadcast_channel_allocated = true;
+ device_for_each_child(card->device, (void *)(long)generation,
+ set_broadcast_channel);
+ }
+}
+
static const char gap_count_table[] = {
63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40
};
-void
-fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
+void fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
{
int scheduled;
@@ -200,37 +214,38 @@ fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
fw_card_put(card);
}
-static void
-fw_card_bm_work(struct work_struct *work)
+static void fw_card_bm_work(struct work_struct *work)
{
struct fw_card *card = container_of(work, struct fw_card, work.work);
struct fw_device *root_device;
- struct fw_node *root_node, *local_node;
+ struct fw_node *root_node;
unsigned long flags;
- int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode;
+ int root_id, new_root_id, irm_id, local_id;
+ int gap_count, generation, grace, rcode;
bool do_reset = false;
bool root_device_is_running;
bool root_device_is_cmc;
__be32 lock_data[2];
spin_lock_irqsave(&card->lock, flags);
- local_node = card->local_node;
- root_node = card->root_node;
- if (local_node == NULL) {
+ if (card->local_node == NULL) {
spin_unlock_irqrestore(&card->lock, flags);
goto out_put_card;
}
- fw_node_get(local_node);
- fw_node_get(root_node);
generation = card->generation;
+ root_node = card->root_node;
+ fw_node_get(root_node);
root_device = root_node->data;
root_device_is_running = root_device &&
atomic_read(&root_device->state) == FW_DEVICE_RUNNING;
root_device_is_cmc = root_device && root_device->cmc;
- root_id = root_node->node_id;
- grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10));
+ root_id = root_node->node_id;
+ irm_id = card->irm_node->node_id;
+ local_id = card->local_node->node_id;
+
+ grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 8));
if (is_next_generation(generation, card->bm_generation) ||
(card->bm_generation != generation && grace)) {
@@ -246,16 +261,15 @@ fw_card_bm_work(struct work_struct *work)
* next generation.
*/
- irm_id = card->irm_node->node_id;
if (!card->irm_node->link_on) {
- new_root_id = local_node->node_id;
+ new_root_id = local_id;
fw_notify("IRM has link off, making local node (%02x) root.\n",
new_root_id);
goto pick_me;
}
lock_data[0] = cpu_to_be32(0x3f);
- lock_data[1] = cpu_to_be32(local_node->node_id);
+ lock_data[1] = cpu_to_be32(local_id);
spin_unlock_irqrestore(&card->lock, flags);
@@ -269,9 +283,14 @@ fw_card_bm_work(struct work_struct *work)
goto out;
if (rcode == RCODE_COMPLETE &&
- lock_data[0] != cpu_to_be32(0x3f))
- /* Somebody else is BM, let them do the work. */
+ lock_data[0] != cpu_to_be32(0x3f)) {
+
+ /* Somebody else is BM. Only act as IRM. */
+ if (local_id == irm_id)
+ allocate_broadcast_channel(card, generation);
+
goto out;
+ }
spin_lock_irqsave(&card->lock, flags);
@@ -282,19 +301,18 @@ fw_card_bm_work(struct work_struct *work)
* do a bus reset and pick the local node as
* root, and thus, IRM.
*/
- new_root_id = local_node->node_id;
+ new_root_id = local_id;
fw_notify("BM lock failed, making local node (%02x) root.\n",
new_root_id);
goto pick_me;
}
} else if (card->bm_generation != generation) {
/*
- * OK, we weren't BM in the last generation, and it's
- * less than 100ms since last bus reset. Reschedule
- * this task 100ms from now.
+ * We weren't BM in the last generation, and the last
+ * bus reset is less than 125ms ago. Reschedule this job.
*/
spin_unlock_irqrestore(&card->lock, flags);
- fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 10));
+ fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 8));
goto out;
}
@@ -310,7 +328,7 @@ fw_card_bm_work(struct work_struct *work)
* Either link_on is false, or we failed to read the
* config rom. In either case, pick another root.
*/
- new_root_id = local_node->node_id;
+ new_root_id = local_id;
} else if (!root_device_is_running) {
/*
* If we haven't probed this device yet, bail out now
@@ -332,7 +350,7 @@ fw_card_bm_work(struct work_struct *work)
* successfully read the config rom, but it's not
* cycle master capable.
*/
- new_root_id = local_node->node_id;
+ new_root_id = local_id;
}
pick_me:
@@ -363,25 +381,28 @@ fw_card_bm_work(struct work_struct *work)
card->index, new_root_id, gap_count);
fw_send_phy_config(card, new_root_id, generation, gap_count);
fw_core_initiate_bus_reset(card, 1);
+ /* Will allocate broadcast channel after the reset. */
+ } else {
+ if (local_id == irm_id)
+ allocate_broadcast_channel(card, generation);
}
+
out:
fw_node_put(root_node);
- fw_node_put(local_node);
out_put_card:
fw_card_put(card);
}
-static void
-flush_timer_callback(unsigned long data)
+static void flush_timer_callback(unsigned long data)
{
struct fw_card *card = (struct fw_card *)data;
fw_flush_transactions(card);
}
-void
-fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
- struct device *device)
+void fw_card_initialize(struct fw_card *card,
+ const struct fw_card_driver *driver,
+ struct device *device)
{
static atomic_t index = ATOMIC_INIT(-1);
@@ -406,13 +427,12 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
}
EXPORT_SYMBOL(fw_card_initialize);
-int
-fw_card_add(struct fw_card *card,
- u32 max_receive, u32 link_speed, u64 guid)
+int fw_card_add(struct fw_card *card,
+ u32 max_receive, u32 link_speed, u64 guid)
{
u32 *config_rom;
size_t length;
- int err;
+ int ret;
card->max_receive = max_receive;
card->link_speed = link_speed;
@@ -423,13 +443,14 @@ fw_card_add(struct fw_card *card,
list_add_tail(&card->link, &card_list);
mutex_unlock(&card_mutex);
- err = card->driver->enable(card, config_rom, length);
- if (err < 0) {
+ ret = card->driver->enable(card, config_rom, length);
+ if (ret < 0) {
mutex_lock(&card_mutex);
list_del(&card->link);
mutex_unlock(&card_mutex);
}
- return err;
+
+ return ret;
}
EXPORT_SYMBOL(fw_card_add);
@@ -442,23 +463,20 @@ EXPORT_SYMBOL(fw_card_add);
* dummy driver just fails all IO.
*/
-static int
-dummy_enable(struct fw_card *card, u32 *config_rom, size_t length)
+static int dummy_enable(struct fw_card *card, u32 *config_rom, size_t length)
{
BUG();
return -1;
}
-static int
-dummy_update_phy_reg(struct fw_card *card, int address,
- int clear_bits, int set_bits)
+static int dummy_update_phy_reg(struct fw_card *card, int address,
+ int clear_bits, int set_bits)
{
return -ENODEV;
}
-static int
-dummy_set_config_rom(struct fw_card *card,
- u32 *config_rom, size_t length)
+static int dummy_set_config_rom(struct fw_card *card,
+ u32 *config_rom, size_t length)
{
/*
* We take the card out of card_list before setting the dummy
@@ -468,27 +486,23 @@ dummy_set_config_rom(struct fw_card *card,
return -1;
}
-static void
-dummy_send_request(struct fw_card *card, struct fw_packet *packet)
+static void dummy_send_request(struct fw_card *card, struct fw_packet *packet)
{
packet->callback(packet, card, -ENODEV);
}
-static void
-dummy_send_response(struct fw_card *card, struct fw_packet *packet)
+static void dummy_send_response(struct fw_card *card, struct fw_packet *packet)
{
packet->callback(packet, card, -ENODEV);
}
-static int
-dummy_cancel_packet(struct fw_card *card, struct fw_packet *packet)
+static int dummy_cancel_packet(struct fw_card *card, struct fw_packet *packet)
{
return -ENOENT;
}
-static int
-dummy_enable_phys_dma(struct fw_card *card,
- int node_id, int generation)
+static int dummy_enable_phys_dma(struct fw_card *card,
+ int node_id, int generation)
{
return -ENODEV;
}
@@ -503,16 +517,14 @@ static struct fw_card_driver dummy_driver = {
.enable_phys_dma = dummy_enable_phys_dma,
};
-void
-fw_card_release(struct kref *kref)
+void fw_card_release(struct kref *kref)
{
struct fw_card *card = container_of(kref, struct fw_card, kref);
complete(&card->done);
}
-void
-fw_core_remove_card(struct fw_card *card)
+void fw_core_remove_card(struct fw_card *card)
{
card->driver->update_phy_reg(card, 4,
PHY_LINK_ACTIVE | PHY_CONTENDER, 0);
@@ -536,8 +548,7 @@ fw_core_remove_card(struct fw_card *card)
}
EXPORT_SYMBOL(fw_core_remove_card);
-int
-fw_core_initiate_bus_reset(struct fw_card *card, int short_reset)
+int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset)
{
int reg = short_reset ? 5 : 1;
int bit = short_reset ? PHY_BUS_SHORT_RESET : PHY_BUS_RESET;
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index ed03234cbea8..7eb6594cc3e5 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -18,87 +18,162 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/errno.h>
+#include <linux/compat.h>
+#include <linux/delay.h>
#include <linux/device.h>
-#include <linux/vmalloc.h>
+#include <linux/errno.h>
+#include <linux/firewire-cdev.h>
+#include <linux/idr.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/kref.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/poll.h>
#include <linux/preempt.h>
+#include <linux/spinlock.h>
#include <linux/time.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/idr.h>
-#include <linux/compat.h>
-#include <linux/firewire-cdev.h>
+#include <linux/vmalloc.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
#include <asm/system.h>
#include <asm/uaccess.h>
-#include "fw-transaction.h"
-#include "fw-topology.h"
+
#include "fw-device.h"
+#include "fw-topology.h"
+#include "fw-transaction.h"
+
+struct client {
+ u32 version;
+ struct fw_device *device;
+
+ spinlock_t lock;
+ bool in_shutdown;
+ struct idr resource_idr;
+ struct list_head event_list;
+ wait_queue_head_t wait;
+ u64 bus_reset_closure;
+
+ struct fw_iso_context *iso_context;
+ u64 iso_closure;
+ struct fw_iso_buffer buffer;
+ unsigned long vm_start;
-struct client;
-struct client_resource {
struct list_head link;
- void (*release)(struct client *client, struct client_resource *r);
- u32 handle;
+ struct kref kref;
};
+static inline void client_get(struct client *client)
+{
+ kref_get(&client->kref);
+}
+
+static void client_release(struct kref *kref)
+{
+ struct client *client = container_of(kref, struct client, kref);
+
+ fw_device_put(client->device);
+ kfree(client);
+}
+
+static void client_put(struct client *client)
+{
+ kref_put(&client->kref, client_release);
+}
+
+struct client_resource;
+typedef void (*client_resource_release_fn_t)(struct client *,
+ struct client_resource *);
+struct client_resource {
+ client_resource_release_fn_t release;
+ int handle;
+};
+
+struct address_handler_resource {
+ struct client_resource resource;
+ struct fw_address_handler handler;
+ __u64 closure;
+ struct client *client;
+};
+
+struct outbound_transaction_resource {
+ struct client_resource resource;
+ struct fw_transaction transaction;
+};
+
+struct inbound_transaction_resource {
+ struct client_resource resource;
+ struct fw_request *request;
+ void *data;
+ size_t length;
+};
+
+struct descriptor_resource {
+ struct client_resource resource;
+ struct fw_descriptor descriptor;
+ u32 data[0];
+};
+
+struct iso_resource {
+ struct client_resource resource;
+ struct client *client;
+ /* Schedule work and access todo only with client->lock held. */
+ struct delayed_work work;
+ enum {ISO_RES_ALLOC, ISO_RES_REALLOC, ISO_RES_DEALLOC,
+ ISO_RES_ALLOC_ONCE, ISO_RES_DEALLOC_ONCE,} todo;
+ int generation;
+ u64 channels;
+ s32 bandwidth;
+ struct iso_resource_event *e_alloc, *e_dealloc;
+};
+
+static void schedule_iso_resource(struct iso_resource *);
+static void release_iso_resource(struct client *, struct client_resource *);
+
/*
* dequeue_event() just kfree()'s the event, so the event has to be
- * the first field in the struct.
+ * the first field in a struct XYZ_event.
*/
-
struct event {
struct { void *data; size_t size; } v[2];
struct list_head link;
};
-struct bus_reset {
+struct bus_reset_event {
struct event event;
struct fw_cdev_event_bus_reset reset;
};
-struct response {
+struct outbound_transaction_event {
struct event event;
- struct fw_transaction transaction;
struct client *client;
- struct client_resource resource;
+ struct outbound_transaction_resource r;
struct fw_cdev_event_response response;
};
-struct iso_interrupt {
+struct inbound_transaction_event {
struct event event;
- struct fw_cdev_event_iso_interrupt interrupt;
+ struct fw_cdev_event_request request;
};
-struct client {
- u32 version;
- struct fw_device *device;
- spinlock_t lock;
- u32 resource_handle;
- struct list_head resource_list;
- struct list_head event_list;
- wait_queue_head_t wait;
- u64 bus_reset_closure;
-
- struct fw_iso_context *iso_context;
- u64 iso_closure;
- struct fw_iso_buffer buffer;
- unsigned long vm_start;
+struct iso_interrupt_event {
+ struct event event;
+ struct fw_cdev_event_iso_interrupt interrupt;
+};
- struct list_head link;
+struct iso_resource_event {
+ struct event event;
+ struct fw_cdev_event_iso_resource resource;
};
-static inline void __user *
-u64_to_uptr(__u64 value)
+static inline void __user *u64_to_uptr(__u64 value)
{
return (void __user *)(unsigned long)value;
}
-static inline __u64
-uptr_to_u64(void __user *ptr)
+static inline __u64 uptr_to_u64(void __user *ptr)
{
return (__u64)(unsigned long)ptr;
}
@@ -107,7 +182,6 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
{
struct fw_device *device;
struct client *client;
- unsigned long flags;
device = fw_device_get_by_devt(inode->i_rdev);
if (device == NULL)
@@ -125,16 +199,17 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
}
client->device = device;
- INIT_LIST_HEAD(&client->event_list);
- INIT_LIST_HEAD(&client->resource_list);
spin_lock_init(&client->lock);
+ idr_init(&client->resource_idr);
+ INIT_LIST_HEAD(&client->event_list);
init_waitqueue_head(&client->wait);
+ kref_init(&client->kref);
file->private_data = client;
- spin_lock_irqsave(&device->card->lock, flags);
+ mutex_lock(&device->client_list_mutex);
list_add_tail(&client->link, &device->client_list);
- spin_unlock_irqrestore(&device->card->lock, flags);
+ mutex_unlock(&device->client_list_mutex);
return 0;
}
@@ -150,68 +225,69 @@ static void queue_event(struct client *client, struct event *event,
event->v[1].size = size1;
spin_lock_irqsave(&client->lock, flags);
- list_add_tail(&event->link, &client->event_list);
+ if (client->in_shutdown)
+ kfree(event);
+ else
+ list_add_tail(&event->link, &client->event_list);
spin_unlock_irqrestore(&client->lock, flags);
wake_up_interruptible(&client->wait);
}
-static int
-dequeue_event(struct client *client, char __user *buffer, size_t count)
+static int dequeue_event(struct client *client,
+ char __user *buffer, size_t count)
{
- unsigned long flags;
struct event *event;
size_t size, total;
- int i, retval;
+ int i, ret;
- retval = wait_event_interruptible(client->wait,
- !list_empty(&client->event_list) ||
- fw_device_is_shutdown(client->device));
- if (retval < 0)
- return retval;
+ ret = wait_event_interruptible(client->wait,
+ !list_empty(&client->event_list) ||
+ fw_device_is_shutdown(client->device));
+ if (ret < 0)
+ return ret;
if (list_empty(&client->event_list) &&
fw_device_is_shutdown(client->device))
return -ENODEV;
- spin_lock_irqsave(&client->lock, flags);
- event = container_of(client->event_list.next, struct event, link);
+ spin_lock_irq(&client->lock);
+ event = list_first_entry(&client->event_list, struct event, link);
list_del(&event->link);
- spin_unlock_irqrestore(&client->lock, flags);
+ spin_unlock_irq(&client->lock);
total = 0;
for (i = 0; i < ARRAY_SIZE(event->v) && total < count; i++) {
size = min(event->v[i].size, count - total);
if (copy_to_user(buffer + total, event->v[i].data, size)) {
- retval = -EFAULT;
+ ret = -EFAULT;
goto out;
}
total += size;
}
- retval = total;
+ ret = total;
out:
kfree(event);
- return retval;
+ return ret;
}
-static ssize_t
-fw_device_op_read(struct file *file,
- char __user *buffer, size_t count, loff_t *offset)
+static ssize_t fw_device_op_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *offset)
{
struct client *client = file->private_data;
return dequeue_event(client, buffer, count);
}
-/* caller must hold card->lock so that node pointers can be dereferenced here */
-static void
-fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
- struct client *client)
+static void fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
+ struct client *client)
{
struct fw_card *card = client->device->card;
+ spin_lock_irq(&card->lock);
+
event->closure = client->bus_reset_closure;
event->type = FW_CDEV_EVENT_BUS_RESET;
event->generation = client->device->generation;
@@ -220,39 +296,49 @@ fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
event->bm_node_id = 0; /* FIXME: We don't track the BM. */
event->irm_node_id = card->irm_node->node_id;
event->root_node_id = card->root_node->node_id;
+
+ spin_unlock_irq(&card->lock);
}
-static void
-for_each_client(struct fw_device *device,
- void (*callback)(struct client *client))
+static void for_each_client(struct fw_device *device,
+ void (*callback)(struct client *client))
{
- struct fw_card *card = device->card;
struct client *c;
- unsigned long flags;
-
- spin_lock_irqsave(&card->lock, flags);
+ mutex_lock(&device->client_list_mutex);
list_for_each_entry(c, &device->client_list, link)
callback(c);
+ mutex_unlock(&device->client_list_mutex);
+}
+
+static int schedule_reallocations(int id, void *p, void *data)
+{
+ struct client_resource *r = p;
- spin_unlock_irqrestore(&card->lock, flags);
+ if (r->release == release_iso_resource)
+ schedule_iso_resource(container_of(r,
+ struct iso_resource, resource));
+ return 0;
}
-static void
-queue_bus_reset_event(struct client *client)
+static void queue_bus_reset_event(struct client *client)
{
- struct bus_reset *bus_reset;
+ struct bus_reset_event *e;
- bus_reset = kzalloc(sizeof(*bus_reset), GFP_ATOMIC);
- if (bus_reset == NULL) {
+ e = kzalloc(sizeof(*e), GFP_KERNEL);
+ if (e == NULL) {
fw_notify("Out of memory when allocating bus reset event\n");
return;
}
- fill_bus_reset_event(&bus_reset->reset, client);
+ fill_bus_reset_event(&e->reset, client);
+
+ queue_event(client, &e->event,
+ &e->reset, sizeof(e->reset), NULL, 0);
- queue_event(client, &bus_reset->event,
- &bus_reset->reset, sizeof(bus_reset->reset), NULL, 0);
+ spin_lock_irq(&client->lock);
+ idr_for_each(&client->resource_idr, schedule_reallocations, client);
+ spin_unlock_irq(&client->lock);
}
void fw_device_cdev_update(struct fw_device *device)
@@ -274,11 +360,11 @@ static int ioctl_get_info(struct client *client, void *buffer)
{
struct fw_cdev_get_info *get_info = buffer;
struct fw_cdev_event_bus_reset bus_reset;
- struct fw_card *card = client->device->card;
unsigned long ret = 0;
client->version = get_info->version;
get_info->version = FW_CDEV_VERSION;
+ get_info->card = client->device->card->index;
down_read(&fw_device_rwsem);
@@ -300,49 +386,61 @@ static int ioctl_get_info(struct client *client, void *buffer)
client->bus_reset_closure = get_info->bus_reset_closure;
if (get_info->bus_reset != 0) {
void __user *uptr = u64_to_uptr(get_info->bus_reset);
- unsigned long flags;
- spin_lock_irqsave(&card->lock, flags);
fill_bus_reset_event(&bus_reset, client);
- spin_unlock_irqrestore(&card->lock, flags);
-
if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset)))
return -EFAULT;
}
- get_info->card = card->index;
-
return 0;
}
-static void
-add_client_resource(struct client *client, struct client_resource *resource)
+static int add_client_resource(struct client *client,
+ struct client_resource *resource, gfp_t gfp_mask)
{
unsigned long flags;
+ int ret;
+
+ retry:
+ if (idr_pre_get(&client->resource_idr, gfp_mask) == 0)
+ return -ENOMEM;
spin_lock_irqsave(&client->lock, flags);
- list_add_tail(&resource->link, &client->resource_list);
- resource->handle = client->resource_handle++;
+ if (client->in_shutdown)
+ ret = -ECANCELED;
+ else
+ ret = idr_get_new(&client->resource_idr, resource,
+ &resource->handle);
+ if (ret >= 0) {
+ client_get(client);
+ if (resource->release == release_iso_resource)
+ schedule_iso_resource(container_of(resource,
+ struct iso_resource, resource));
+ }
spin_unlock_irqrestore(&client->lock, flags);
+
+ if (ret == -EAGAIN)
+ goto retry;
+
+ return ret < 0 ? ret : 0;
}
-static int
-release_client_resource(struct client *client, u32 handle,
- struct client_resource **resource)
+static int release_client_resource(struct client *client, u32 handle,
+ client_resource_release_fn_t release,
+ struct client_resource **resource)
{
struct client_resource *r;
- unsigned long flags;
- spin_lock_irqsave(&client->lock, flags);
- list_for_each_entry(r, &client->resource_list, link) {
- if (r->handle == handle) {
- list_del(&r->link);
- break;
- }
- }
- spin_unlock_irqrestore(&client->lock, flags);
+ spin_lock_irq(&client->lock);
+ if (client->in_shutdown)
+ r = NULL;
+ else
+ r = idr_find(&client->resource_idr, handle);
+ if (r && r->release == release)
+ idr_remove(&client->resource_idr, handle);
+ spin_unlock_irq(&client->lock);
- if (&r->link == &client->resource_list)
+ if (!(r && r->release == release))
return -EINVAL;
if (resource)
@@ -350,203 +448,239 @@ release_client_resource(struct client *client, u32 handle,
else
r->release(client, r);
+ client_put(client);
+
return 0;
}
-static void
-release_transaction(struct client *client, struct client_resource *resource)
+static void release_transaction(struct client *client,
+ struct client_resource *resource)
{
- struct response *response =
- container_of(resource, struct response, resource);
+ struct outbound_transaction_resource *r = container_of(resource,
+ struct outbound_transaction_resource, resource);
- fw_cancel_transaction(client->device->card, &response->transaction);
+ fw_cancel_transaction(client->device->card, &r->transaction);
}
-static void
-complete_transaction(struct fw_card *card, int rcode,
- void *payload, size_t length, void *data)
+static void complete_transaction(struct fw_card *card, int rcode,
+ void *payload, size_t length, void *data)
{
- struct response *response = data;
- struct client *client = response->client;
+ struct outbound_transaction_event *e = data;
+ struct fw_cdev_event_response *rsp = &e->response;
+ struct client *client = e->client;
unsigned long flags;
- struct fw_cdev_event_response *r = &response->response;
- if (length < r->length)
- r->length = length;
+ if (length < rsp->length)
+ rsp->length = length;
if (rcode == RCODE_COMPLETE)
- memcpy(r->data, payload, r->length);
+ memcpy(rsp->data, payload, rsp->length);
spin_lock_irqsave(&client->lock, flags);
- list_del(&response->resource.link);
+ /*
+ * 1. If called while in shutdown, the idr tree must be left untouched.
+ * The idr handle will be removed and the client reference will be
+ * dropped later.
+ * 2. If the call chain was release_client_resource ->
+ * release_transaction -> complete_transaction (instead of a normal
+ * conclusion of the transaction), i.e. if this resource was already
+ * unregistered from the idr, the client reference will be dropped
+ * by release_client_resource and we must not drop it here.
+ */
+ if (!client->in_shutdown &&
+ idr_find(&client->resource_idr, e->r.resource.handle)) {
+ idr_remove(&client->resource_idr, e->r.resource.handle);
+ /* Drop the idr's reference */
+ client_put(client);
+ }
spin_unlock_irqrestore(&client->lock, flags);
- r->type = FW_CDEV_EVENT_RESPONSE;
- r->rcode = rcode;
+ rsp->type = FW_CDEV_EVENT_RESPONSE;
+ rsp->rcode = rcode;
/*
- * In the case that sizeof(*r) doesn't align with the position of the
+ * In the case that sizeof(*rsp) doesn't align with the position of the
* data, and the read is short, preserve an extra copy of the data
* to stay compatible with a pre-2.6.27 bug. Since the bug is harmless
* for short reads and some apps depended on it, this is both safe
* and prudent for compatibility.
*/
- if (r->length <= sizeof(*r) - offsetof(typeof(*r), data))
- queue_event(client, &response->event, r, sizeof(*r),
- r->data, r->length);
+ if (rsp->length <= sizeof(*rsp) - offsetof(typeof(*rsp), data))
+ queue_event(client, &e->event, rsp, sizeof(*rsp),
+ rsp->data, rsp->length);
else
- queue_event(client, &response->event, r, sizeof(*r) + r->length,
+ queue_event(client, &e->event, rsp, sizeof(*rsp) + rsp->length,
NULL, 0);
+
+ /* Drop the transaction callback's reference */
+ client_put(client);
}
-static int ioctl_send_request(struct client *client, void *buffer)
+static int init_request(struct client *client,
+ struct fw_cdev_send_request *request,
+ int destination_id, int speed)
{
- struct fw_device *device = client->device;
- struct fw_cdev_send_request *request = buffer;
- struct response *response;
+ struct outbound_transaction_event *e;
+ int ret;
- /* What is the biggest size we'll accept, really? */
- if (request->length > 4096)
- return -EINVAL;
+ if (request->tcode != TCODE_STREAM_DATA &&
+ (request->length > 4096 || request->length > 512 << speed))
+ return -EIO;
- response = kmalloc(sizeof(*response) + request->length, GFP_KERNEL);
- if (response == NULL)
+ e = kmalloc(sizeof(*e) + request->length, GFP_KERNEL);
+ if (e == NULL)
return -ENOMEM;
- response->client = client;
- response->response.length = request->length;
- response->response.closure = request->closure;
+ e->client = client;
+ e->response.length = request->length;
+ e->response.closure = request->closure;
if (request->data &&
- copy_from_user(response->response.data,
+ copy_from_user(e->response.data,
u64_to_uptr(request->data), request->length)) {
- kfree(response);
- return -EFAULT;
+ ret = -EFAULT;
+ goto failed;
}
- response->resource.release = release_transaction;
- add_client_resource(client, &response->resource);
+ e->r.resource.release = release_transaction;
+ ret = add_client_resource(client, &e->r.resource, GFP_KERNEL);
+ if (ret < 0)
+ goto failed;
- fw_send_request(device->card, &response->transaction,
- request->tcode & 0x1f,
- device->node->node_id,
- request->generation,
- device->max_speed,
- request->offset,
- response->response.data, request->length,
- complete_transaction, response);
+ /* Get a reference for the transaction callback */
+ client_get(client);
- if (request->data)
- return sizeof(request) + request->length;
- else
- return sizeof(request);
+ fw_send_request(client->device->card, &e->r.transaction,
+ request->tcode, destination_id, request->generation,
+ speed, request->offset, e->response.data,
+ request->length, complete_transaction, e);
+ return 0;
+
+ failed:
+ kfree(e);
+
+ return ret;
}
-struct address_handler {
- struct fw_address_handler handler;
- __u64 closure;
- struct client *client;
- struct client_resource resource;
-};
+static int ioctl_send_request(struct client *client, void *buffer)
+{
+ struct fw_cdev_send_request *request = buffer;
-struct request {
- struct fw_request *request;
- void *data;
- size_t length;
- struct client_resource resource;
-};
+ switch (request->tcode) {
+ case TCODE_WRITE_QUADLET_REQUEST:
+ case TCODE_WRITE_BLOCK_REQUEST:
+ case TCODE_READ_QUADLET_REQUEST:
+ case TCODE_READ_BLOCK_REQUEST:
+ case TCODE_LOCK_MASK_SWAP:
+ case TCODE_LOCK_COMPARE_SWAP:
+ case TCODE_LOCK_FETCH_ADD:
+ case TCODE_LOCK_LITTLE_ADD:
+ case TCODE_LOCK_BOUNDED_ADD:
+ case TCODE_LOCK_WRAP_ADD:
+ case TCODE_LOCK_VENDOR_DEPENDENT:
+ break;
+ default:
+ return -EINVAL;
+ }
-struct request_event {
- struct event event;
- struct fw_cdev_event_request request;
-};
+ return init_request(client, request, client->device->node_id,
+ client->device->max_speed);
+}
-static void
-release_request(struct client *client, struct client_resource *resource)
+static void release_request(struct client *client,
+ struct client_resource *resource)
{
- struct request *request =
- container_of(resource, struct request, resource);
+ struct inbound_transaction_resource *r = container_of(resource,
+ struct inbound_transaction_resource, resource);
- fw_send_response(client->device->card, request->request,
+ fw_send_response(client->device->card, r->request,
RCODE_CONFLICT_ERROR);
- kfree(request);
+ kfree(r);
}
-static void
-handle_request(struct fw_card *card, struct fw_request *r,
- int tcode, int destination, int source,
- int generation, int speed,
- unsigned long long offset,
- void *payload, size_t length, void *callback_data)
+static void handle_request(struct fw_card *card, struct fw_request *request,
+ int tcode, int destination, int source,
+ int generation, int speed,
+ unsigned long long offset,
+ void *payload, size_t length, void *callback_data)
{
- struct address_handler *handler = callback_data;
- struct request *request;
- struct request_event *e;
- struct client *client = handler->client;
+ struct address_handler_resource *handler = callback_data;
+ struct inbound_transaction_resource *r;
+ struct inbound_transaction_event *e;
+ int ret;
- request = kmalloc(sizeof(*request), GFP_ATOMIC);
+ r = kmalloc(sizeof(*r), GFP_ATOMIC);
e = kmalloc(sizeof(*e), GFP_ATOMIC);
- if (request == NULL || e == NULL) {
- kfree(request);
- kfree(e);
- fw_send_response(card, r, RCODE_CONFLICT_ERROR);
- return;
- }
+ if (r == NULL || e == NULL)
+ goto failed;
- request->request = r;
- request->data = payload;
- request->length = length;
+ r->request = request;
+ r->data = payload;
+ r->length = length;
- request->resource.release = release_request;
- add_client_resource(client, &request->resource);
+ r->resource.release = release_request;
+ ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC);
+ if (ret < 0)
+ goto failed;
e->request.type = FW_CDEV_EVENT_REQUEST;
e->request.tcode = tcode;
e->request.offset = offset;
e->request.length = length;
- e->request.handle = request->resource.handle;
+ e->request.handle = r->resource.handle;
e->request.closure = handler->closure;
- queue_event(client, &e->event,
+ queue_event(handler->client, &e->event,
&e->request, sizeof(e->request), payload, length);
+ return;
+
+ failed:
+ kfree(r);
+ kfree(e);
+ fw_send_response(card, request, RCODE_CONFLICT_ERROR);
}
-static void
-release_address_handler(struct client *client,
- struct client_resource *resource)
+static void release_address_handler(struct client *client,
+ struct client_resource *resource)
{
- struct address_handler *handler =
- container_of(resource, struct address_handler, resource);
+ struct address_handler_resource *r =
+ container_of(resource, struct address_handler_resource, resource);
- fw_core_remove_address_handler(&handler->handler);
- kfree(handler);
+ fw_core_remove_address_handler(&r->handler);
+ kfree(r);
}
static int ioctl_allocate(struct client *client, void *buffer)
{
struct fw_cdev_allocate *request = buffer;
- struct address_handler *handler;
+ struct address_handler_resource *r;
struct fw_address_region region;
+ int ret;
- handler = kmalloc(sizeof(*handler), GFP_KERNEL);
- if (handler == NULL)
+ r = kmalloc(sizeof(*r), GFP_KERNEL);
+ if (r == NULL)
return -ENOMEM;
region.start = request->offset;
region.end = request->offset + request->length;
- handler->handler.length = request->length;
- handler->handler.address_callback = handle_request;
- handler->handler.callback_data = handler;
- handler->closure = request->closure;
- handler->client = client;
-
- if (fw_core_add_address_handler(&handler->handler, &region) < 0) {
- kfree(handler);
- return -EBUSY;
+ r->handler.length = request->length;
+ r->handler.address_callback = handle_request;
+ r->handler.callback_data = r;
+ r->closure = request->closure;
+ r->client = client;
+
+ ret = fw_core_add_address_handler(&r->handler, &region);
+ if (ret < 0) {
+ kfree(r);
+ return ret;
}
- handler->resource.release = release_address_handler;
- add_client_resource(client, &handler->resource);
- request->handle = handler->resource.handle;
+ r->resource.release = release_address_handler;
+ ret = add_client_resource(client, &r->resource, GFP_KERNEL);
+ if (ret < 0) {
+ release_address_handler(client, &r->resource);
+ return ret;
+ }
+ request->handle = r->resource.handle;
return 0;
}
@@ -555,18 +689,22 @@ static int ioctl_deallocate(struct client *client, void *buffer)
{
struct fw_cdev_deallocate *request = buffer;
- return release_client_resource(client, request->handle, NULL);
+ return release_client_resource(client, request->handle,
+ release_address_handler, NULL);
}
static int ioctl_send_response(struct client *client, void *buffer)
{
struct fw_cdev_send_response *request = buffer;
struct client_resource *resource;
- struct request *r;
+ struct inbound_transaction_resource *r;
- if (release_client_resource(client, request->handle, &resource) < 0)
+ if (release_client_resource(client, request->handle,
+ release_request, &resource) < 0)
return -EINVAL;
- r = container_of(resource, struct request, resource);
+
+ r = container_of(resource, struct inbound_transaction_resource,
+ resource);
if (request->length < r->length)
r->length = request->length;
if (copy_from_user(r->data, u64_to_uptr(request->data), r->length))
@@ -588,85 +726,92 @@ static int ioctl_initiate_bus_reset(struct client *client, void *buffer)
return fw_core_initiate_bus_reset(client->device->card, short_reset);
}
-struct descriptor {
- struct fw_descriptor d;
- struct client_resource resource;
- u32 data[0];
-};
-
static void release_descriptor(struct client *client,
struct client_resource *resource)
{
- struct descriptor *descriptor =
- container_of(resource, struct descriptor, resource);
+ struct descriptor_resource *r =
+ container_of(resource, struct descriptor_resource, resource);
- fw_core_remove_descriptor(&descriptor->d);
- kfree(descriptor);
+ fw_core_remove_descriptor(&r->descriptor);
+ kfree(r);
}
static int ioctl_add_descriptor(struct client *client, void *buffer)
{
struct fw_cdev_add_descriptor *request = buffer;
- struct descriptor *descriptor;
- int retval;
+ struct fw_card *card = client->device->card;
+ struct descriptor_resource *r;
+ int ret;
+
+ /* Access policy: Allow this ioctl only on local nodes' device files. */
+ spin_lock_irq(&card->lock);
+ ret = client->device->node_id != card->local_node->node_id;
+ spin_unlock_irq(&card->lock);
+ if (ret)
+ return -ENOSYS;
if (request->length > 256)
return -EINVAL;
- descriptor =
- kmalloc(sizeof(*descriptor) + request->length * 4, GFP_KERNEL);
- if (descriptor == NULL)
+ r = kmalloc(sizeof(*r) + request->length * 4, GFP_KERNEL);
+ if (r == NULL)
return -ENOMEM;
- if (copy_from_user(descriptor->data,
+ if (copy_from_user(r->data,
u64_to_uptr(request->data), request->length * 4)) {
- kfree(descriptor);
- return -EFAULT;
+ ret = -EFAULT;
+ goto failed;
}
- descriptor->d.length = request->length;
- descriptor->d.immediate = request->immediate;
- descriptor->d.key = request->key;
- descriptor->d.data = descriptor->data;
+ r->descriptor.length = request->length;
+ r->descriptor.immediate = request->immediate;
+ r->descriptor.key = request->key;
+ r->descriptor.data = r->data;
- retval = fw_core_add_descriptor(&descriptor->d);
- if (retval < 0) {
- kfree(descriptor);
- return retval;
- }
+ ret = fw_core_add_descriptor(&r->descriptor);
+ if (ret < 0)
+ goto failed;
- descriptor->resource.release = release_descriptor;
- add_client_resource(client, &descriptor->resource);
- request->handle = descriptor->resource.handle;
+ r->resource.release = release_descriptor;
+ ret = add_client_resource(client, &r->resource, GFP_KERNEL);
+ if (ret < 0) {
+ fw_core_remove_descriptor(&r->descriptor);
+ goto failed;
+ }
+ request->handle = r->resource.handle;
return 0;
+ failed:
+ kfree(r);
+
+ return ret;
}
static int ioctl_remove_descriptor(struct client *client, void *buffer)
{
struct fw_cdev_remove_descriptor *request = buffer;
- return release_client_resource(client, request->handle, NULL);
+ return release_client_resource(client, request->handle,
+ release_descriptor, NULL);
}
-static void
-iso_callback(struct fw_iso_context *context, u32 cycle,
- size_t header_length, void *header, void *data)
+static void iso_callback(struct fw_iso_context *context, u32 cycle,
+ size_t header_length, void *header, void *data)
{
struct client *client = data;
- struct iso_interrupt *irq;
+ struct iso_interrupt_event *e;
- irq = kzalloc(sizeof(*irq) + header_length, GFP_ATOMIC);
- if (irq == NULL)
+ e = kzalloc(sizeof(*e) + header_length, GFP_ATOMIC);
+ if (e == NULL)
return;
- irq->interrupt.type = FW_CDEV_EVENT_ISO_INTERRUPT;
- irq->interrupt.closure = client->iso_closure;
- irq->interrupt.cycle = cycle;
- irq->interrupt.header_length = header_length;
- memcpy(irq->interrupt.header, header, header_length);
- queue_event(client, &irq->event, &irq->interrupt,
- sizeof(irq->interrupt) + header_length, NULL, 0);
+ e->interrupt.type = FW_CDEV_EVENT_ISO_INTERRUPT;
+ e->interrupt.closure = client->iso_closure;
+ e->interrupt.cycle = cycle;
+ e->interrupt.header_length = header_length;
+ memcpy(e->interrupt.header, header, header_length);
+ queue_event(client, &e->event, &e->interrupt,
+ sizeof(e->interrupt) + header_length, NULL, 0);
}
static int ioctl_create_iso_context(struct client *client, void *buffer)
@@ -871,6 +1016,261 @@ static int ioctl_get_cycle_timer(struct client *client, void *buffer)
return 0;
}
+static void iso_resource_work(struct work_struct *work)
+{
+ struct iso_resource_event *e;
+ struct iso_resource *r =
+ container_of(work, struct iso_resource, work.work);
+ struct client *client = r->client;
+ int generation, channel, bandwidth, todo;
+ bool skip, free, success;
+
+ spin_lock_irq(&client->lock);
+ generation = client->device->generation;
+ todo = r->todo;
+ /* Allow 1000ms grace period for other reallocations. */
+ if (todo == ISO_RES_ALLOC &&
+ time_is_after_jiffies(client->device->card->reset_jiffies + HZ)) {
+ if (schedule_delayed_work(&r->work, DIV_ROUND_UP(HZ, 3)))
+ client_get(client);
+ skip = true;
+ } else {
+ /* We could be called twice within the same generation. */
+ skip = todo == ISO_RES_REALLOC &&
+ r->generation == generation;
+ }
+ free = todo == ISO_RES_DEALLOC ||
+ todo == ISO_RES_ALLOC_ONCE ||
+ todo == ISO_RES_DEALLOC_ONCE;
+ r->generation = generation;
+ spin_unlock_irq(&client->lock);
+
+ if (skip)
+ goto out;
+
+ bandwidth = r->bandwidth;
+
+ fw_iso_resource_manage(client->device->card, generation,
+ r->channels, &channel, &bandwidth,
+ todo == ISO_RES_ALLOC ||
+ todo == ISO_RES_REALLOC ||
+ todo == ISO_RES_ALLOC_ONCE);
+ /*
+ * Is this generation outdated already? As long as this resource sticks
+ * in the idr, it will be scheduled again for a newer generation or at
+ * shutdown.
+ */
+ if (channel == -EAGAIN &&
+ (todo == ISO_RES_ALLOC || todo == ISO_RES_REALLOC))
+ goto out;
+
+ success = channel >= 0 || bandwidth > 0;
+
+ spin_lock_irq(&client->lock);
+ /*
+ * Transit from allocation to reallocation, except if the client
+ * requested deallocation in the meantime.
+ */
+ if (r->todo == ISO_RES_ALLOC)
+ r->todo = ISO_RES_REALLOC;
+ /*
+ * Allocation or reallocation failure? Pull this resource out of the
+ * idr and prepare for deletion, unless the client is shutting down.
+ */
+ if (r->todo == ISO_RES_REALLOC && !success &&
+ !client->in_shutdown &&
+ idr_find(&client->resource_idr, r->resource.handle)) {
+ idr_remove(&client->resource_idr, r->resource.handle);
+ client_put(client);
+ free = true;
+ }
+ spin_unlock_irq(&client->lock);
+
+ if (todo == ISO_RES_ALLOC && channel >= 0)
+ r->channels = 1ULL << channel;
+
+ if (todo == ISO_RES_REALLOC && success)
+ goto out;
+
+ if (todo == ISO_RES_ALLOC || todo == ISO_RES_ALLOC_ONCE) {
+ e = r->e_alloc;
+ r->e_alloc = NULL;
+ } else {
+ e = r->e_dealloc;
+ r->e_dealloc = NULL;
+ }
+ e->resource.handle = r->resource.handle;
+ e->resource.channel = channel;
+ e->resource.bandwidth = bandwidth;
+
+ queue_event(client, &e->event,
+ &e->resource, sizeof(e->resource), NULL, 0);
+
+ if (free) {
+ cancel_delayed_work(&r->work);
+ kfree(r->e_alloc);
+ kfree(r->e_dealloc);
+ kfree(r);
+ }
+ out:
+ client_put(client);
+}
+
+static void schedule_iso_resource(struct iso_resource *r)
+{
+ client_get(r->client);
+ if (!schedule_delayed_work(&r->work, 0))
+ client_put(r->client);
+}
+
+static void release_iso_resource(struct client *client,
+ struct client_resource *resource)
+{
+ struct iso_resource *r =
+ container_of(resource, struct iso_resource, resource);
+
+ spin_lock_irq(&client->lock);
+ r->todo = ISO_RES_DEALLOC;
+ schedule_iso_resource(r);
+ spin_unlock_irq(&client->lock);
+}
+
+static int init_iso_resource(struct client *client,
+ struct fw_cdev_allocate_iso_resource *request, int todo)
+{
+ struct iso_resource_event *e1, *e2;
+ struct iso_resource *r;
+ int ret;
+
+ if ((request->channels == 0 && request->bandwidth == 0) ||
+ request->bandwidth > BANDWIDTH_AVAILABLE_INITIAL ||
+ request->bandwidth < 0)
+ return -EINVAL;
+
+ r = kmalloc(sizeof(*r), GFP_KERNEL);
+ e1 = kmalloc(sizeof(*e1), GFP_KERNEL);
+ e2 = kmalloc(sizeof(*e2), GFP_KERNEL);
+ if (r == NULL || e1 == NULL || e2 == NULL) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ INIT_DELAYED_WORK(&r->work, iso_resource_work);
+ r->client = client;
+ r->todo = todo;
+ r->generation = -1;
+ r->channels = request->channels;
+ r->bandwidth = request->bandwidth;
+ r->e_alloc = e1;
+ r->e_dealloc = e2;
+
+ e1->resource.closure = request->closure;
+ e1->resource.type = FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED;
+ e2->resource.closure = request->closure;
+ e2->resource.type = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED;
+
+ if (todo == ISO_RES_ALLOC) {
+ r->resource.release = release_iso_resource;
+ ret = add_client_resource(client, &r->resource, GFP_KERNEL);
+ if (ret < 0)
+ goto fail;
+ } else {
+ r->resource.release = NULL;
+ r->resource.handle = -1;
+ schedule_iso_resource(r);
+ }
+ request->handle = r->resource.handle;
+
+ return 0;
+ fail:
+ kfree(r);
+ kfree(e1);
+ kfree(e2);
+
+ return ret;
+}
+
+static int ioctl_allocate_iso_resource(struct client *client, void *buffer)
+{
+ struct fw_cdev_allocate_iso_resource *request = buffer;
+
+ return init_iso_resource(client, request, ISO_RES_ALLOC);
+}
+
+static int ioctl_deallocate_iso_resource(struct client *client, void *buffer)
+{
+ struct fw_cdev_deallocate *request = buffer;
+
+ return release_client_resource(client, request->handle,
+ release_iso_resource, NULL);
+}
+
+static int ioctl_allocate_iso_resource_once(struct client *client, void *buffer)
+{
+ struct fw_cdev_allocate_iso_resource *request = buffer;
+
+ return init_iso_resource(client, request, ISO_RES_ALLOC_ONCE);
+}
+
+static int ioctl_deallocate_iso_resource_once(struct client *client, void *buffer)
+{
+ struct fw_cdev_allocate_iso_resource *request = buffer;
+
+ return init_iso_resource(client, request, ISO_RES_DEALLOC_ONCE);
+}
+
+/*
+ * Returns a speed code: Maximum speed to or from this device,
+ * limited by the device's link speed, the local node's link speed,
+ * and all PHY port speeds between the two links.
+ */
+static int ioctl_get_speed(struct client *client, void *buffer)
+{
+ return client->device->max_speed;
+}
+
+static int ioctl_send_broadcast_request(struct client *client, void *buffer)
+{
+ struct fw_cdev_send_request *request = buffer;
+
+ switch (request->tcode) {
+ case TCODE_WRITE_QUADLET_REQUEST:
+ case TCODE_WRITE_BLOCK_REQUEST:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Security policy: Only allow accesses to Units Space. */
+ if (request->offset < CSR_REGISTER_BASE + CSR_CONFIG_ROM_END)
+ return -EACCES;
+
+ return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100);
+}
+
+static int ioctl_send_stream_packet(struct client *client, void *buffer)
+{
+ struct fw_cdev_send_stream_packet *p = buffer;
+ struct fw_cdev_send_request request;
+ int dest;
+
+ if (p->speed > client->device->card->link_speed ||
+ p->length > 1024 << p->speed)
+ return -EIO;
+
+ if (p->tag > 3 || p->channel > 63 || p->sy > 15)
+ return -EINVAL;
+
+ dest = fw_stream_packet_destination_id(p->tag, p->channel, p->sy);
+ request.tcode = TCODE_STREAM_DATA;
+ request.length = p->length;
+ request.closure = p->closure;
+ request.data = p->data;
+ request.generation = p->generation;
+
+ return init_request(client, &request, dest, p->speed);
+}
+
static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
ioctl_get_info,
ioctl_send_request,
@@ -885,13 +1285,20 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
ioctl_start_iso,
ioctl_stop_iso,
ioctl_get_cycle_timer,
+ ioctl_allocate_iso_resource,
+ ioctl_deallocate_iso_resource,
+ ioctl_allocate_iso_resource_once,
+ ioctl_deallocate_iso_resource_once,
+ ioctl_get_speed,
+ ioctl_send_broadcast_request,
+ ioctl_send_stream_packet,
};
-static int
-dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg)
+static int dispatch_ioctl(struct client *client,
+ unsigned int cmd, void __user *arg)
{
char buffer[256];
- int retval;
+ int ret;
if (_IOC_TYPE(cmd) != '#' ||
_IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers))
@@ -903,9 +1310,9 @@ dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg)
return -EFAULT;
}
- retval = ioctl_handlers[_IOC_NR(cmd)](client, buffer);
- if (retval < 0)
- return retval;
+ ret = ioctl_handlers[_IOC_NR(cmd)](client, buffer);
+ if (ret < 0)
+ return ret;
if (_IOC_DIR(cmd) & _IOC_READ) {
if (_IOC_SIZE(cmd) > sizeof(buffer) ||
@@ -913,12 +1320,11 @@ dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg)
return -EFAULT;
}
- return retval;
+ return ret;
}
-static long
-fw_device_op_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
+static long fw_device_op_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
{
struct client *client = file->private_data;
@@ -929,9 +1335,8 @@ fw_device_op_ioctl(struct file *file,
}
#ifdef CONFIG_COMPAT
-static long
-fw_device_op_compat_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
+static long fw_device_op_compat_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
{
struct client *client = file->private_data;
@@ -947,7 +1352,7 @@ static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma)
struct client *client = file->private_data;
enum dma_data_direction direction;
unsigned long size;
- int page_count, retval;
+ int page_count, ret;
if (fw_device_is_shutdown(client->device))
return -ENODEV;
@@ -973,48 +1378,57 @@ static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma)
else
direction = DMA_FROM_DEVICE;
- retval = fw_iso_buffer_init(&client->buffer, client->device->card,
- page_count, direction);
- if (retval < 0)
- return retval;
+ ret = fw_iso_buffer_init(&client->buffer, client->device->card,
+ page_count, direction);
+ if (ret < 0)
+ return ret;
- retval = fw_iso_buffer_map(&client->buffer, vma);
- if (retval < 0)
+ ret = fw_iso_buffer_map(&client->buffer, vma);
+ if (ret < 0)
fw_iso_buffer_destroy(&client->buffer, client->device->card);
- return retval;
+ return ret;
+}
+
+static int shutdown_resource(int id, void *p, void *data)
+{
+ struct client_resource *r = p;
+ struct client *client = data;
+
+ r->release(client, r);
+ client_put(client);
+
+ return 0;
}
static int fw_device_op_release(struct inode *inode, struct file *file)
{
struct client *client = file->private_data;
struct event *e, *next_e;
- struct client_resource *r, *next_r;
- unsigned long flags;
- if (client->buffer.pages)
- fw_iso_buffer_destroy(&client->buffer, client->device->card);
+ mutex_lock(&client->device->client_list_mutex);
+ list_del(&client->link);
+ mutex_unlock(&client->device->client_list_mutex);
if (client->iso_context)
fw_iso_context_destroy(client->iso_context);
- list_for_each_entry_safe(r, next_r, &client->resource_list, link)
- r->release(client, r);
+ if (client->buffer.pages)
+ fw_iso_buffer_destroy(&client->buffer, client->device->card);
- /*
- * FIXME: We should wait for the async tasklets to stop
- * running before freeing the memory.
- */
+ /* Freeze client->resource_idr and client->event_list */
+ spin_lock_irq(&client->lock);
+ client->in_shutdown = true;
+ spin_unlock_irq(&client->lock);
+
+ idr_for_each(&client->resource_idr, shutdown_resource, client);
+ idr_remove_all(&client->resource_idr);
+ idr_destroy(&client->resource_idr);
list_for_each_entry_safe(e, next_e, &client->event_list, link)
kfree(e);
- spin_lock_irqsave(&client->device->card->lock, flags);
- list_del(&client->link);
- spin_unlock_irqrestore(&client->device->card->lock, flags);
-
- fw_device_put(client->device);
- kfree(client);
+ client_put(client);
return 0;
}
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index bf53acb45652..a47e2129d83d 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -18,22 +18,26 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include <linux/module.h>
-#include <linux/wait.h>
-#include <linux/errno.h>
-#include <linux/kthread.h>
-#include <linux/device.h>
+#include <linux/ctype.h>
#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
#include <linux/idr.h>
#include <linux/jiffies.h>
-#include <linux/string.h>
+#include <linux/kobject.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
#include <linux/rwsem.h>
#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/workqueue.h>
+
#include <asm/system.h>
-#include <linux/ctype.h>
-#include "fw-transaction.h"
-#include "fw-topology.h"
+
#include "fw-device.h"
+#include "fw-topology.h"
+#include "fw-transaction.h"
void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 * p)
{
@@ -132,8 +136,7 @@ static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
vendor, model, specifier_id, version);
}
-static int
-fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct fw_unit *unit = fw_unit(dev);
char modalias[64];
@@ -152,27 +155,6 @@ struct bus_type fw_bus_type = {
};
EXPORT_SYMBOL(fw_bus_type);
-static void fw_device_release(struct device *dev)
-{
- struct fw_device *device = fw_device(dev);
- struct fw_card *card = device->card;
- unsigned long flags;
-
- /*
- * Take the card lock so we don't set this to NULL while a
- * FW_NODE_UPDATED callback is being handled or while the
- * bus manager work looks at this node.
- */
- spin_lock_irqsave(&card->lock, flags);
- device->node->data = NULL;
- spin_unlock_irqrestore(&card->lock, flags);
-
- fw_node_put(device->node);
- kfree(device->config_rom);
- kfree(device);
- fw_card_put(card);
-}
-
int fw_device_enable_phys_dma(struct fw_device *device)
{
int generation = device->generation;
@@ -191,8 +173,8 @@ struct config_rom_attribute {
u32 key;
};
-static ssize_t
-show_immediate(struct device *dev, struct device_attribute *dattr, char *buf)
+static ssize_t show_immediate(struct device *dev,
+ struct device_attribute *dattr, char *buf)
{
struct config_rom_attribute *attr =
container_of(dattr, struct config_rom_attribute, attr);
@@ -223,8 +205,8 @@ show_immediate(struct device *dev, struct device_attribute *dattr, char *buf)
#define IMMEDIATE_ATTR(name, key) \
{ __ATTR(name, S_IRUGO, show_immediate, NULL), key }
-static ssize_t
-show_text_leaf(struct device *dev, struct device_attribute *dattr, char *buf)
+static ssize_t show_text_leaf(struct device *dev,
+ struct device_attribute *dattr, char *buf)
{
struct config_rom_attribute *attr =
container_of(dattr, struct config_rom_attribute, attr);
@@ -293,10 +275,9 @@ static struct config_rom_attribute config_rom_attributes[] = {
TEXT_LEAF_ATTR(hardware_version_name, CSR_HARDWARE_VERSION),
};
-static void
-init_fw_attribute_group(struct device *dev,
- struct device_attribute *attrs,
- struct fw_attribute_group *group)
+static void init_fw_attribute_group(struct device *dev,
+ struct device_attribute *attrs,
+ struct fw_attribute_group *group)
{
struct device_attribute *attr;
int i, j;
@@ -319,9 +300,8 @@ init_fw_attribute_group(struct device *dev,
dev->groups = group->groups;
}
-static ssize_t
-modalias_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t modalias_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct fw_unit *unit = fw_unit(dev);
int length;
@@ -332,9 +312,8 @@ modalias_show(struct device *dev,
return length + 1;
}
-static ssize_t
-rom_index_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t rom_index_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct fw_device *device = fw_device(dev->parent);
struct fw_unit *unit = fw_unit(dev);
@@ -349,8 +328,8 @@ static struct device_attribute fw_unit_attributes[] = {
__ATTR_NULL,
};
-static ssize_t
-config_rom_show(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t config_rom_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct fw_device *device = fw_device(dev);
size_t length;
@@ -363,8 +342,8 @@ config_rom_show(struct device *dev, struct device_attribute *attr, char *buf)
return length;
}
-static ssize_t
-guid_show(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t guid_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct fw_device *device = fw_device(dev);
int ret;
@@ -383,8 +362,8 @@ static struct device_attribute fw_device_attributes[] = {
__ATTR_NULL,
};
-static int
-read_rom(struct fw_device *device, int generation, int index, u32 *data)
+static int read_rom(struct fw_device *device,
+ int generation, int index, u32 *data)
{
int rcode;
@@ -539,7 +518,7 @@ static int read_bus_info_block(struct fw_device *device, int generation)
kfree(old_rom);
ret = 0;
- device->cmc = rom[2] & 1 << 30;
+ device->cmc = rom[2] >> 30 & 1;
out:
kfree(rom);
@@ -679,11 +658,53 @@ static void fw_device_shutdown(struct work_struct *work)
fw_device_put(device);
}
+static void fw_device_release(struct device *dev)
+{
+ struct fw_device *device = fw_device(dev);
+ struct fw_card *card = device->card;
+ unsigned long flags;
+
+ /*
+ * Take the card lock so we don't set this to NULL while a
+ * FW_NODE_UPDATED callback is being handled or while the
+ * bus manager work looks at this node.
+ */
+ spin_lock_irqsave(&card->lock, flags);
+ device->node->data = NULL;
+ spin_unlock_irqrestore(&card->lock, flags);
+
+ fw_node_put(device->node);
+ kfree(device->config_rom);
+ kfree(device);
+ fw_card_put(card);
+}
+
static struct device_type fw_device_type = {
- .release = fw_device_release,
+ .release = fw_device_release,
};
-static void fw_device_update(struct work_struct *work);
+static int update_unit(struct device *dev, void *data)
+{
+ struct fw_unit *unit = fw_unit(dev);
+ struct fw_driver *driver = (struct fw_driver *)dev->driver;
+
+ if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) {
+ down(&dev->sem);
+ driver->update(unit);
+ up(&dev->sem);
+ }
+
+ return 0;
+}
+
+static void fw_device_update(struct work_struct *work)
+{
+ struct fw_device *device =
+ container_of(work, struct fw_device, work.work);
+
+ fw_device_cdev_update(device);
+ device_for_each_child(&device->device, NULL, update_unit);
+}
/*
* If a device was pending for deletion because its node went away but its
@@ -735,12 +756,50 @@ static int lookup_existing_device(struct device *dev, void *data)
return match;
}
+enum { BC_UNKNOWN = 0, BC_UNIMPLEMENTED, BC_IMPLEMENTED, };
+
+void fw_device_set_broadcast_channel(struct fw_device *device, int generation)
+{
+ struct fw_card *card = device->card;
+ __be32 data;
+ int rcode;
+
+ if (!card->broadcast_channel_allocated)
+ return;
+
+ if (device->bc_implemented == BC_UNKNOWN) {
+ rcode = fw_run_transaction(card, TCODE_READ_QUADLET_REQUEST,
+ device->node_id, generation, device->max_speed,
+ CSR_REGISTER_BASE + CSR_BROADCAST_CHANNEL,
+ &data, 4);
+ switch (rcode) {
+ case RCODE_COMPLETE:
+ if (data & cpu_to_be32(1 << 31)) {
+ device->bc_implemented = BC_IMPLEMENTED;
+ break;
+ }
+ /* else fall through to case address error */
+ case RCODE_ADDRESS_ERROR:
+ device->bc_implemented = BC_UNIMPLEMENTED;
+ }
+ }
+
+ if (device->bc_implemented == BC_IMPLEMENTED) {
+ data = cpu_to_be32(BROADCAST_CHANNEL_INITIAL |
+ BROADCAST_CHANNEL_VALID);
+ fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST,
+ device->node_id, generation, device->max_speed,
+ CSR_REGISTER_BASE + CSR_BROADCAST_CHANNEL,
+ &data, 4);
+ }
+}
+
static void fw_device_init(struct work_struct *work)
{
struct fw_device *device =
container_of(work, struct fw_device, work.work);
struct device *revived_dev;
- int minor, err;
+ int minor, ret;
/*
* All failure paths here set node->data to NULL, so that we
@@ -776,12 +835,12 @@ static void fw_device_init(struct work_struct *work)
fw_device_get(device);
down_write(&fw_device_rwsem);
- err = idr_pre_get(&fw_device_idr, GFP_KERNEL) ?
+ ret = idr_pre_get(&fw_device_idr, GFP_KERNEL) ?
idr_get_new(&fw_device_idr, device, &minor) :
-ENOMEM;
up_write(&fw_device_rwsem);
- if (err < 0)
+ if (ret < 0)
goto error;
device->device.bus = &fw_bus_type;
@@ -828,6 +887,8 @@ static void fw_device_init(struct work_struct *work)
device->config_rom[3], device->config_rom[4],
1 << device->max_speed);
device->config_rom_retries = 0;
+
+ fw_device_set_broadcast_channel(device, device->generation);
}
/*
@@ -851,29 +912,6 @@ static void fw_device_init(struct work_struct *work)
put_device(&device->device); /* our reference */
}
-static int update_unit(struct device *dev, void *data)
-{
- struct fw_unit *unit = fw_unit(dev);
- struct fw_driver *driver = (struct fw_driver *)dev->driver;
-
- if (is_fw_unit(dev) && driver != NULL && driver->update != NULL) {
- down(&dev->sem);
- driver->update(unit);
- up(&dev->sem);
- }
-
- return 0;
-}
-
-static void fw_device_update(struct work_struct *work)
-{
- struct fw_device *device =
- container_of(work, struct fw_device, work.work);
-
- fw_device_cdev_update(device);
- device_for_each_child(&device->device, NULL, update_unit);
-}
-
enum {
REREAD_BIB_ERROR,
REREAD_BIB_GONE,
@@ -894,7 +932,7 @@ static int reread_bus_info_block(struct fw_device *device, int generation)
if (i == 0 && q == 0)
return REREAD_BIB_GONE;
- if (i > device->config_rom_length || q != device->config_rom[i])
+ if (q != device->config_rom[i])
return REREAD_BIB_CHANGED;
}
@@ -1004,6 +1042,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
device->node = fw_node_get(node);
device->node_id = node->node_id;
device->generation = card->generation;
+ mutex_init(&device->client_list_mutex);
INIT_LIST_HEAD(&device->client_list);
/*
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h
index 8ef6ec2ca21c..97588937c018 100644
--- a/drivers/firewire/fw-device.h
+++ b/drivers/firewire/fw-device.h
@@ -19,10 +19,17 @@
#ifndef __fw_device_h
#define __fw_device_h
+#include <linux/device.h>
#include <linux/fs.h>
-#include <linux/cdev.h>
#include <linux/idr.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
#include <linux/rwsem.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
#include <asm/atomic.h>
enum fw_device_state {
@@ -38,6 +45,9 @@ struct fw_attribute_group {
struct attribute *attrs[11];
};
+struct fw_node;
+struct fw_card;
+
/*
* Note, fw_device.generation always has to be read before fw_device.node_id.
* Use SMP memory barriers to ensure this. Otherwise requests will be sent
@@ -61,13 +71,18 @@ struct fw_device {
int node_id;
int generation;
unsigned max_speed;
- bool cmc;
struct fw_card *card;
struct device device;
+
+ struct mutex client_list_mutex;
struct list_head client_list;
+
u32 *config_rom;
size_t config_rom_length;
int config_rom_retries;
+ unsigned cmc:1;
+ unsigned bc_implemented:2;
+
struct delayed_work work;
struct fw_attribute_group attribute_group;
};
@@ -96,6 +111,7 @@ static inline void fw_device_put(struct fw_device *device)
struct fw_device *fw_device_get_by_devt(dev_t devt);
int fw_device_enable_phys_dma(struct fw_device *device);
+void fw_device_set_broadcast_channel(struct fw_device *device, int generation);
void fw_device_cdev_update(struct fw_device *device);
void fw_device_cdev_remove(struct fw_device *device);
@@ -176,8 +192,7 @@ struct fw_driver {
const struct fw_device_id *id_table;
};
-static inline struct fw_driver *
-fw_driver(struct device_driver *drv)
+static inline struct fw_driver *fw_driver(struct device_driver *drv)
{
return container_of(drv, struct fw_driver, driver);
}
diff --git a/drivers/firewire/fw-iso.c b/drivers/firewire/fw-iso.c
index e14c03dc0065..2baf1007253e 100644
--- a/drivers/firewire/fw-iso.c
+++ b/drivers/firewire/fw-iso.c
@@ -1,5 +1,7 @@
/*
- * Isochronous IO functionality
+ * Isochronous I/O functionality:
+ * - Isochronous DMA context management
+ * - Isochronous bus resource management (channels, bandwidth), client side
*
* Copyright (C) 2006 Kristian Hoegsberg <krh@bitplanet.net>
*
@@ -18,21 +20,25 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#include <linux/kernel.h>
-#include <linux/module.h>
#include <linux/dma-mapping.h>
-#include <linux/vmalloc.h>
+#include <linux/errno.h>
+#include <linux/firewire-constants.h>
+#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/vmalloc.h>
-#include "fw-transaction.h"
#include "fw-topology.h"
-#include "fw-device.h"
+#include "fw-transaction.h"
-int
-fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card,
- int page_count, enum dma_data_direction direction)
+/*
+ * Isochronous DMA context management
+ */
+
+int fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card,
+ int page_count, enum dma_data_direction direction)
{
- int i, j, retval = -ENOMEM;
+ int i, j;
dma_addr_t address;
buffer->page_count = page_count;
@@ -69,19 +75,21 @@ fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card,
kfree(buffer->pages);
out:
buffer->pages = NULL;
- return retval;
+
+ return -ENOMEM;
}
int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma)
{
unsigned long uaddr;
- int i, retval;
+ int i, err;
uaddr = vma->vm_start;
for (i = 0; i < buffer->page_count; i++) {
- retval = vm_insert_page(vma, uaddr, buffer->pages[i]);
- if (retval)
- return retval;
+ err = vm_insert_page(vma, uaddr, buffer->pages[i]);
+ if (err)
+ return err;
+
uaddr += PAGE_SIZE;
}
@@ -105,14 +113,14 @@ void fw_iso_buffer_destroy(struct fw_iso_buffer *buffer,
buffer->pages = NULL;
}
-struct fw_iso_context *
-fw_iso_context_create(struct fw_card *card, int type,
- int channel, int speed, size_t header_size,
- fw_iso_callback_t callback, void *callback_data)
+struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
+ int type, int channel, int speed, size_t header_size,
+ fw_iso_callback_t callback, void *callback_data)
{
struct fw_iso_context *ctx;
- ctx = card->driver->allocate_iso_context(card, type, header_size);
+ ctx = card->driver->allocate_iso_context(card,
+ type, channel, header_size);
if (IS_ERR(ctx))
return ctx;
@@ -134,25 +142,186 @@ void fw_iso_context_destroy(struct fw_iso_context *ctx)
card->driver->free_iso_context(ctx);
}
-int
-fw_iso_context_start(struct fw_iso_context *ctx, int cycle, int sync, int tags)
+int fw_iso_context_start(struct fw_iso_context *ctx,
+ int cycle, int sync, int tags)
{
return ctx->card->driver->start_iso(ctx, cycle, sync, tags);
}
-int
-fw_iso_context_queue(struct fw_iso_context *ctx,
- struct fw_iso_packet *packet,
- struct fw_iso_buffer *buffer,
- unsigned long payload)
+int fw_iso_context_queue(struct fw_iso_context *ctx,
+ struct fw_iso_packet *packet,
+ struct fw_iso_buffer *buffer,
+ unsigned long payload)
{
struct fw_card *card = ctx->card;
return card->driver->queue_iso(ctx, packet, buffer, payload);
}
-int
-fw_iso_context_stop(struct fw_iso_context *ctx)
+int fw_iso_context_stop(struct fw_iso_context *ctx)
{
return ctx->card->driver->stop_iso(ctx);
}
+
+/*
+ * Isochronous bus resource management (channels, bandwidth), client side
+ */
+
+static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
+ int bandwidth, bool allocate)
+{
+ __be32 data[2];
+ int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0;
+
+ /*
+ * On a 1394a IRM with low contention, try < 1 is enough.
+ * On a 1394-1995 IRM, we need at least try < 2.
+ * Let's just do try < 5.
+ */
+ for (try = 0; try < 5; try++) {
+ new = allocate ? old - bandwidth : old + bandwidth;
+ if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL)
+ break;
+
+ data[0] = cpu_to_be32(old);
+ data[1] = cpu_to_be32(new);
+ switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
+ irm_id, generation, SCODE_100,
+ CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE,
+ data, sizeof(data))) {
+ case RCODE_GENERATION:
+ /* A generation change frees all bandwidth. */
+ return allocate ? -EAGAIN : bandwidth;
+
+ case RCODE_COMPLETE:
+ if (be32_to_cpup(data) == old)
+ return bandwidth;
+
+ old = be32_to_cpup(data);
+ /* Fall through. */
+ }
+ }
+
+ return -EIO;
+}
+
+static int manage_channel(struct fw_card *card, int irm_id, int generation,
+ u32 channels_mask, u64 offset, bool allocate)
+{
+ __be32 data[2], c, all, old;
+ int i, retry = 5;
+
+ old = all = allocate ? cpu_to_be32(~0) : 0;
+
+ for (i = 0; i < 32; i++) {
+ if (!(channels_mask & 1 << i))
+ continue;
+
+ c = cpu_to_be32(1 << (31 - i));
+ if ((old & c) != (all & c))
+ continue;
+
+ data[0] = old;
+ data[1] = old ^ c;
+ switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
+ irm_id, generation, SCODE_100,
+ offset, data, sizeof(data))) {
+ case RCODE_GENERATION:
+ /* A generation change frees all channels. */
+ return allocate ? -EAGAIN : i;
+
+ case RCODE_COMPLETE:
+ if (data[0] == old)
+ return i;
+
+ old = data[0];
+
+ /* Is the IRM 1394a-2000 compliant? */
+ if ((data[0] & c) == (data[1] & c))
+ continue;
+
+ /* 1394-1995 IRM, fall through to retry. */
+ default:
+ if (retry--)
+ i--;
+ }
+ }
+
+ return -EIO;
+}
+
+static void deallocate_channel(struct fw_card *card, int irm_id,
+ int generation, int channel)
+{
+ u32 mask;
+ u64 offset;
+
+ mask = channel < 32 ? 1 << channel : 1 << (channel - 32);
+ offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI :
+ CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO;
+
+ manage_channel(card, irm_id, generation, mask, offset, false);
+}
+
+/**
+ * fw_iso_resource_manage - Allocate or deallocate a channel and/or bandwidth
+ *
+ * In parameters: card, generation, channels_mask, bandwidth, allocate
+ * Out parameters: channel, bandwidth
+ * This function blocks (sleeps) during communication with the IRM.
+ *
+ * Allocates or deallocates at most one channel out of channels_mask.
+ * channels_mask is a bitfield with MSB for channel 63 and LSB for channel 0.
+ * (Note, the IRM's CHANNELS_AVAILABLE is a big-endian bitfield with MSB for
+ * channel 0 and LSB for channel 63.)
+ * Allocates or deallocates as many bandwidth allocation units as specified.
+ *
+ * Returns channel < 0 if no channel was allocated or deallocated.
+ * Returns bandwidth = 0 if no bandwidth was allocated or deallocated.
+ *
+ * If generation is stale, deallocations succeed but allocations fail with
+ * channel = -EAGAIN.
+ *
+ * If channel allocation fails, no bandwidth will be allocated either.
+ * If bandwidth allocation fails, no channel will be allocated either.
+ * But deallocations of channel and bandwidth are tried independently
+ * of each other's success.
+ */
+void fw_iso_resource_manage(struct fw_card *card, int generation,
+ u64 channels_mask, int *channel, int *bandwidth,
+ bool allocate)
+{
+ u32 channels_hi = channels_mask; /* channels 31...0 */
+ u32 channels_lo = channels_mask >> 32; /* channels 63...32 */
+ int irm_id, ret, c = -EINVAL;
+
+ spin_lock_irq(&card->lock);
+ irm_id = card->irm_node->node_id;
+ spin_unlock_irq(&card->lock);
+
+ if (channels_hi)
+ c = manage_channel(card, irm_id, generation, channels_hi,
+ CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI, allocate);
+ if (channels_lo && c < 0) {
+ c = manage_channel(card, irm_id, generation, channels_lo,
+ CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO, allocate);
+ if (c >= 0)
+ c += 32;
+ }
+ *channel = c;
+
+ if (allocate && channels_mask != 0 && c < 0)
+ *bandwidth = 0;
+
+ if (*bandwidth == 0)
+ return;
+
+ ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate);
+ if (ret < 0)
+ *bandwidth = 0;
+
+ if (allocate && ret < 0 && c >= 0) {
+ deallocate_channel(card, irm_id, generation, c);
+ *channel = ret;
+ }
+}
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 6d19828a93a5..1180d0be0bb4 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -205,6 +205,7 @@ struct fw_ohci {
u32 it_context_mask;
struct iso_context *it_context_list;
+ u64 ir_context_channels;
u32 ir_context_mask;
struct iso_context *ir_context_list;
};
@@ -441,9 +442,8 @@ static inline void flush_writes(const struct fw_ohci *ohci)
reg_read(ohci, OHCI1394_Version);
}
-static int
-ohci_update_phy_reg(struct fw_card *card, int addr,
- int clear_bits, int set_bits)
+static int ohci_update_phy_reg(struct fw_card *card, int addr,
+ int clear_bits, int set_bits)
{
struct fw_ohci *ohci = fw_ohci(card);
u32 val, old;
@@ -658,8 +658,8 @@ static void ar_context_tasklet(unsigned long data)
}
}
-static int
-ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, u32 regs)
+static int ar_context_init(struct ar_context *ctx,
+ struct fw_ohci *ohci, u32 regs)
{
struct ar_buffer ab;
@@ -690,8 +690,7 @@ static void ar_context_run(struct ar_context *ctx)
flush_writes(ctx->ohci);
}
-static struct descriptor *
-find_branch_descriptor(struct descriptor *d, int z)
+static struct descriptor *find_branch_descriptor(struct descriptor *d, int z)
{
int b, key;
@@ -751,8 +750,7 @@ static void context_tasklet(unsigned long data)
* Allocate a new buffer and add it to the list of free buffers for this
* context. Must be called with ohci->lock held.
*/
-static int
-context_add_buffer(struct context *ctx)
+static int context_add_buffer(struct context *ctx)
{
struct descriptor_buffer *desc;
dma_addr_t uninitialized_var(bus_addr);
@@ -781,9 +779,8 @@ context_add_buffer(struct context *ctx)
return 0;
}
-static int
-context_init(struct context *ctx, struct fw_ohci *ohci,
- u32 regs, descriptor_callback_t callback)
+static int context_init(struct context *ctx, struct fw_ohci *ohci,
+ u32 regs, descriptor_callback_t callback)
{
ctx->ohci = ohci;
ctx->regs = regs;
@@ -814,8 +811,7 @@ context_init(struct context *ctx, struct fw_ohci *ohci,
return 0;
}
-static void
-context_release(struct context *ctx)
+static void context_release(struct context *ctx)
{
struct fw_card *card = &ctx->ohci->card;
struct descriptor_buffer *desc, *tmp;
@@ -827,8 +823,8 @@ context_release(struct context *ctx)
}
/* Must be called with ohci->lock held */
-static struct descriptor *
-context_get_descriptors(struct context *ctx, int z, dma_addr_t *d_bus)
+static struct descriptor *context_get_descriptors(struct context *ctx,
+ int z, dma_addr_t *d_bus)
{
struct descriptor *d = NULL;
struct descriptor_buffer *desc = ctx->buffer_tail;
@@ -912,8 +908,8 @@ struct driver_data {
* Must always be called with the ochi->lock held to ensure proper
* generation handling and locking around packet queue manipulation.
*/
-static int
-at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
+static int at_context_queue_packet(struct context *ctx,
+ struct fw_packet *packet)
{
struct fw_ohci *ohci = ctx->ohci;
dma_addr_t d_bus, uninitialized_var(payload_bus);
@@ -940,7 +936,9 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
*/
header = (__le32 *) &d[1];
- if (packet->header_length > 8) {
+ switch (packet->header_length) {
+ case 16:
+ case 12:
header[0] = cpu_to_le32((packet->header[0] & 0xffff) |
(packet->speed << 16));
header[1] = cpu_to_le32((packet->header[1] & 0xffff) |
@@ -954,12 +952,27 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
header[3] = (__force __le32) packet->header[3];
d[0].req_count = cpu_to_le16(packet->header_length);
- } else {
+ break;
+
+ case 8:
header[0] = cpu_to_le32((OHCI1394_phy_tcode << 4) |
(packet->speed << 16));
header[1] = cpu_to_le32(packet->header[0]);
header[2] = cpu_to_le32(packet->header[1]);
d[0].req_count = cpu_to_le16(12);
+ break;
+
+ case 4:
+ header[0] = cpu_to_le32((packet->header[0] & 0xffff) |
+ (packet->speed << 16));
+ header[1] = cpu_to_le32(packet->header[0] & 0xffff0000);
+ d[0].req_count = cpu_to_le16(8);
+ break;
+
+ default:
+ /* BUG(); */
+ packet->ack = RCODE_SEND_ERROR;
+ return -1;
}
driver_data = (struct driver_data *) &d[3];
@@ -1095,8 +1108,8 @@ static int handle_at_packet(struct context *context,
#define HEADER_GET_DATA_LENGTH(q) (((q) >> 16) & 0xffff)
#define HEADER_GET_EXTENDED_TCODE(q) (((q) >> 0) & 0xffff)
-static void
-handle_local_rom(struct fw_ohci *ohci, struct fw_packet *packet, u32 csr)
+static void handle_local_rom(struct fw_ohci *ohci,
+ struct fw_packet *packet, u32 csr)
{
struct fw_packet response;
int tcode, length, i;
@@ -1122,8 +1135,8 @@ handle_local_rom(struct fw_ohci *ohci, struct fw_packet *packet, u32 csr)
fw_core_handle_response(&ohci->card, &response);
}
-static void
-handle_local_lock(struct fw_ohci *ohci, struct fw_packet *packet, u32 csr)
+static void handle_local_lock(struct fw_ohci *ohci,
+ struct fw_packet *packet, u32 csr)
{
struct fw_packet response;
int tcode, length, ext_tcode, sel;
@@ -1164,8 +1177,7 @@ handle_local_lock(struct fw_ohci *ohci, struct fw_packet *packet, u32 csr)
fw_core_handle_response(&ohci->card, &response);
}
-static void
-handle_local_request(struct context *ctx, struct fw_packet *packet)
+static void handle_local_request(struct context *ctx, struct fw_packet *packet)
{
u64 offset;
u32 csr;
@@ -1205,11 +1217,10 @@ handle_local_request(struct context *ctx, struct fw_packet *packet)
}
}
-static void
-at_context_transmit(struct context *ctx, struct fw_packet *packet)
+static void at_context_transmit(struct context *ctx, struct fw_packet *packet)
{
unsigned long flags;
- int retval;
+ int ret;
spin_lock_irqsave(&ctx->ohci->lock, flags);
@@ -1220,10 +1231,10 @@ at_context_transmit(struct context *ctx, struct fw_packet *packet)
return;
}
- retval = at_context_queue_packet(ctx, packet);
+ ret = at_context_queue_packet(ctx, packet);
spin_unlock_irqrestore(&ctx->ohci->lock, flags);
- if (retval < 0)
+ if (ret < 0)
packet->callback(packet, &ctx->ohci->card, packet->ack);
}
@@ -1590,12 +1601,12 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
return 0;
}
-static int
-ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length)
+static int ohci_set_config_rom(struct fw_card *card,
+ u32 *config_rom, size_t length)
{
struct fw_ohci *ohci;
unsigned long flags;
- int retval = -EBUSY;
+ int ret = -EBUSY;
__be32 *next_config_rom;
dma_addr_t uninitialized_var(next_config_rom_bus);
@@ -1649,7 +1660,7 @@ ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length)
reg_write(ohci, OHCI1394_ConfigROMmap,
ohci->next_config_rom_bus);
- retval = 0;
+ ret = 0;
}
spin_unlock_irqrestore(&ohci->lock, flags);
@@ -1661,13 +1672,13 @@ ohci_set_config_rom(struct fw_card *card, u32 *config_rom, size_t length)
* controller could need to access it before the bus reset
* takes effect.
*/
- if (retval == 0)
+ if (ret == 0)
fw_core_initiate_bus_reset(&ohci->card, 1);
else
dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
next_config_rom, next_config_rom_bus);
- return retval;
+ return ret;
}
static void ohci_send_request(struct fw_card *card, struct fw_packet *packet)
@@ -1689,7 +1700,7 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet)
struct fw_ohci *ohci = fw_ohci(card);
struct context *ctx = &ohci->at_request_ctx;
struct driver_data *driver_data = packet->driver_data;
- int retval = -ENOENT;
+ int ret = -ENOENT;
tasklet_disable(&ctx->tasklet);
@@ -1704,23 +1715,22 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet)
driver_data->packet = NULL;
packet->ack = RCODE_CANCELLED;
packet->callback(packet, &ohci->card, packet->ack);
- retval = 0;
-
+ ret = 0;
out:
tasklet_enable(&ctx->tasklet);
- return retval;
+ return ret;
}
-static int
-ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
+static int ohci_enable_phys_dma(struct fw_card *card,
+ int node_id, int generation)
{
#ifdef CONFIG_FIREWIRE_OHCI_REMOTE_DMA
return 0;
#else
struct fw_ohci *ohci = fw_ohci(card);
unsigned long flags;
- int n, retval = 0;
+ int n, ret = 0;
/*
* FIXME: Make sure this bitmask is cleared when we clear the busReset
@@ -1730,7 +1740,7 @@ ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
spin_lock_irqsave(&ohci->lock, flags);
if (ohci->generation != generation) {
- retval = -ESTALE;
+ ret = -ESTALE;
goto out;
}
@@ -1748,12 +1758,12 @@ ohci_enable_phys_dma(struct fw_card *card, int node_id, int generation)
flush_writes(ohci);
out:
spin_unlock_irqrestore(&ohci->lock, flags);
- return retval;
+
+ return ret;
#endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */
}
-static u64
-ohci_get_bus_time(struct fw_card *card)
+static u64 ohci_get_bus_time(struct fw_card *card)
{
struct fw_ohci *ohci = fw_ohci(card);
u32 cycle_time;
@@ -1765,6 +1775,28 @@ ohci_get_bus_time(struct fw_card *card)
return bus_time;
}
+static void copy_iso_headers(struct iso_context *ctx, void *p)
+{
+ int i = ctx->header_length;
+
+ if (i + ctx->base.header_size > PAGE_SIZE)
+ return;
+
+ /*
+ * The iso header is byteswapped to little endian by
+ * the controller, but the remaining header quadlets
+ * are big endian. We want to present all the headers
+ * as big endian, so we have to swap the first quadlet.
+ */
+ if (ctx->base.header_size > 0)
+ *(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4));
+ if (ctx->base.header_size > 4)
+ *(u32 *) (ctx->header + i + 4) = __swab32(*(u32 *) p);
+ if (ctx->base.header_size > 8)
+ memcpy(ctx->header + i + 8, p + 8, ctx->base.header_size - 8);
+ ctx->header_length += ctx->base.header_size;
+}
+
static int handle_ir_dualbuffer_packet(struct context *context,
struct descriptor *d,
struct descriptor *last)
@@ -1775,7 +1807,6 @@ static int handle_ir_dualbuffer_packet(struct context *context,
__le32 *ir_header;
size_t header_length;
void *p, *end;
- int i;
if (db->first_res_count != 0 && db->second_res_count != 0) {
if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) {
@@ -1788,25 +1819,14 @@ static int handle_ir_dualbuffer_packet(struct context *context,
header_length = le16_to_cpu(db->first_req_count) -
le16_to_cpu(db->first_res_count);
- i = ctx->header_length;
p = db + 1;
end = p + header_length;
- while (p < end && i + ctx->base.header_size <= PAGE_SIZE) {
- /*
- * The iso header is byteswapped to little endian by
- * the controller, but the remaining header quadlets
- * are big endian. We want to present all the headers
- * as big endian, so we have to swap the first
- * quadlet.
- */
- *(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4));
- memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
- i += ctx->base.header_size;
+ while (p < end) {
+ copy_iso_headers(ctx, p);
ctx->excess_bytes +=
(le32_to_cpu(*(__le32 *)(p + 4)) >> 16) & 0xffff;
- p += ctx->base.header_size + 4;
+ p += max(ctx->base.header_size, (size_t)8);
}
- ctx->header_length = i;
ctx->excess_bytes -= le16_to_cpu(db->second_req_count) -
le16_to_cpu(db->second_res_count);
@@ -1832,7 +1852,6 @@ static int handle_ir_packet_per_buffer(struct context *context,
struct descriptor *pd;
__le32 *ir_header;
void *p;
- int i;
for (pd = d; pd <= last; pd++) {
if (pd->transfer_status)
@@ -1842,21 +1861,8 @@ static int handle_ir_packet_per_buffer(struct context *context,
/* Descriptor(s) not done yet, stop iteration */
return 0;
- i = ctx->header_length;
- p = last + 1;
-
- if (ctx->base.header_size > 0 &&
- i + ctx->base.header_size <= PAGE_SIZE) {
- /*
- * The iso header is byteswapped to little endian by
- * the controller, but the remaining header quadlets
- * are big endian. We want to present all the headers
- * as big endian, so we have to swap the first quadlet.
- */
- *(u32 *) (ctx->header + i) = __swab32(*(u32 *) (p + 4));
- memcpy(ctx->header + i + 4, p + 8, ctx->base.header_size - 4);
- ctx->header_length += ctx->base.header_size;
- }
+ p = last + 1;
+ copy_iso_headers(ctx, p);
if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) {
ir_header = (__le32 *) p;
@@ -1888,21 +1894,24 @@ static int handle_it_packet(struct context *context,
return 1;
}
-static struct fw_iso_context *
-ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size)
+static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card,
+ int type, int channel, size_t header_size)
{
struct fw_ohci *ohci = fw_ohci(card);
struct iso_context *ctx, *list;
descriptor_callback_t callback;
+ u64 *channels, dont_care = ~0ULL;
u32 *mask, regs;
unsigned long flags;
- int index, retval = -ENOMEM;
+ int index, ret = -ENOMEM;
if (type == FW_ISO_CONTEXT_TRANSMIT) {
+ channels = &dont_care;
mask = &ohci->it_context_mask;
list = ohci->it_context_list;
callback = handle_it_packet;
} else {
+ channels = &ohci->ir_context_channels;
mask = &ohci->ir_context_mask;
list = ohci->ir_context_list;
if (ohci->use_dualbuffer)
@@ -1912,9 +1921,11 @@ ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size)
}
spin_lock_irqsave(&ohci->lock, flags);
- index = ffs(*mask) - 1;
- if (index >= 0)
+ index = *channels & 1ULL << channel ? ffs(*mask) - 1 : -1;
+ if (index >= 0) {
+ *channels &= ~(1ULL << channel);
*mask &= ~(1 << index);
+ }
spin_unlock_irqrestore(&ohci->lock, flags);
if (index < 0)
@@ -1932,8 +1943,8 @@ ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size)
if (ctx->header == NULL)
goto out;
- retval = context_init(&ctx->context, ohci, regs, callback);
- if (retval < 0)
+ ret = context_init(&ctx->context, ohci, regs, callback);
+ if (ret < 0)
goto out_with_header;
return &ctx->base;
@@ -1945,7 +1956,7 @@ ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size)
*mask |= 1 << index;
spin_unlock_irqrestore(&ohci->lock, flags);
- return ERR_PTR(retval);
+ return ERR_PTR(ret);
}
static int ohci_start_iso(struct fw_iso_context *base,
@@ -2024,16 +2035,16 @@ static void ohci_free_iso_context(struct fw_iso_context *base)
} else {
index = ctx - ohci->ir_context_list;
ohci->ir_context_mask |= 1 << index;
+ ohci->ir_context_channels |= 1ULL << base->channel;
}
spin_unlock_irqrestore(&ohci->lock, flags);
}
-static int
-ohci_queue_iso_transmit(struct fw_iso_context *base,
- struct fw_iso_packet *packet,
- struct fw_iso_buffer *buffer,
- unsigned long payload)
+static int ohci_queue_iso_transmit(struct fw_iso_context *base,
+ struct fw_iso_packet *packet,
+ struct fw_iso_buffer *buffer,
+ unsigned long payload)
{
struct iso_context *ctx = container_of(base, struct iso_context, base);
struct descriptor *d, *last, *pd;
@@ -2128,11 +2139,10 @@ ohci_queue_iso_transmit(struct fw_iso_context *base,
return 0;
}
-static int
-ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
- struct fw_iso_packet *packet,
- struct fw_iso_buffer *buffer,
- unsigned long payload)
+static int ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
+ struct fw_iso_packet *packet,
+ struct fw_iso_buffer *buffer,
+ unsigned long payload)
{
struct iso_context *ctx = container_of(base, struct iso_context, base);
struct db_descriptor *db = NULL;
@@ -2151,11 +2161,11 @@ ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
z = 2;
/*
- * The OHCI controller puts the status word in the header
- * buffer too, so we need 4 extra bytes per packet.
+ * The OHCI controller puts the isochronous header and trailer in the
+ * buffer, so we need at least 8 bytes.
*/
packet_count = p->header_length / ctx->base.header_size;
- header_size = packet_count * (ctx->base.header_size + 4);
+ header_size = packet_count * max(ctx->base.header_size, (size_t)8);
/* Get header size in number of descriptors. */
header_z = DIV_ROUND_UP(header_size, sizeof(*d));
@@ -2173,7 +2183,8 @@ ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
db = (struct db_descriptor *) d;
db->control = cpu_to_le16(DESCRIPTOR_STATUS |
DESCRIPTOR_BRANCH_ALWAYS);
- db->first_size = cpu_to_le16(ctx->base.header_size + 4);
+ db->first_size =
+ cpu_to_le16(max(ctx->base.header_size, (size_t)8));
if (p->skip && rest == p->payload_length) {
db->control |= cpu_to_le16(DESCRIPTOR_WAIT);
db->first_req_count = db->first_size;
@@ -2208,11 +2219,10 @@ ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base,
return 0;
}
-static int
-ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base,
- struct fw_iso_packet *packet,
- struct fw_iso_buffer *buffer,
- unsigned long payload)
+static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base,
+ struct fw_iso_packet *packet,
+ struct fw_iso_buffer *buffer,
+ unsigned long payload)
{
struct iso_context *ctx = container_of(base, struct iso_context, base);
struct descriptor *d = NULL, *pd = NULL;
@@ -2223,11 +2233,11 @@ ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base,
int page, offset, packet_count, header_size, payload_per_buffer;
/*
- * The OHCI controller puts the status word in the
- * buffer too, so we need 4 extra bytes per packet.
+ * The OHCI controller puts the isochronous header and trailer in the
+ * buffer, so we need at least 8 bytes.
*/
packet_count = p->header_length / ctx->base.header_size;
- header_size = ctx->base.header_size + 4;
+ header_size = max(ctx->base.header_size, (size_t)8);
/* Get header size in number of descriptors. */
header_z = DIV_ROUND_UP(header_size, sizeof(*d));
@@ -2286,29 +2296,27 @@ ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base,
return 0;
}
-static int
-ohci_queue_iso(struct fw_iso_context *base,
- struct fw_iso_packet *packet,
- struct fw_iso_buffer *buffer,
- unsigned long payload)
+static int ohci_queue_iso(struct fw_iso_context *base,
+ struct fw_iso_packet *packet,
+ struct fw_iso_buffer *buffer,
+ unsigned long payload)
{
struct iso_context *ctx = container_of(base, struct iso_context, base);
unsigned long flags;
- int retval;
+ int ret;
spin_lock_irqsave(&ctx->context.ohci->lock, flags);
if (base->type == FW_ISO_CONTEXT_TRANSMIT)
- retval = ohci_queue_iso_transmit(base, packet, buffer, payload);
+ ret = ohci_queue_iso_transmit(base, packet, buffer, payload);
else if (ctx->context.ohci->use_dualbuffer)
- retval = ohci_queue_iso_receive_dualbuffer(base, packet,
- buffer, payload);
+ ret = ohci_queue_iso_receive_dualbuffer(base, packet,
+ buffer, payload);
else
- retval = ohci_queue_iso_receive_packet_per_buffer(base, packet,
- buffer,
- payload);
+ ret = ohci_queue_iso_receive_packet_per_buffer(base, packet,
+ buffer, payload);
spin_unlock_irqrestore(&ctx->context.ohci->lock, flags);
- return retval;
+ return ret;
}
static const struct fw_card_driver ohci_driver = {
@@ -2357,8 +2365,8 @@ static void ohci_pmac_off(struct pci_dev *dev)
#define ohci_pmac_off(dev)
#endif /* CONFIG_PPC_PMAC */
-static int __devinit
-pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
+static int __devinit pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *ent)
{
struct fw_ohci *ohci;
u32 bus_options, max_receive, link_speed, version;
@@ -2440,6 +2448,7 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
ohci->it_context_list = kzalloc(size, GFP_KERNEL);
reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0);
+ ohci->ir_context_channels = ~0ULL;
ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet);
reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0);
size = sizeof(struct iso_context) * hweight32(ohci->ir_context_mask);
@@ -2467,11 +2476,12 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
reg_read(ohci, OHCI1394_GUIDLo);
err = fw_card_add(&ohci->card, max_receive, link_speed, guid);
- if (err < 0)
+ if (err)
goto fail_self_id;
fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n",
dev_name(&dev->dev), version >> 16, version & 0xff);
+
return 0;
fail_self_id:
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index c71c4419d9e8..2bcf51557c72 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -392,20 +392,18 @@ static const struct {
}
};
-static void
-free_orb(struct kref *kref)
+static void free_orb(struct kref *kref)
{
struct sbp2_orb *orb = container_of(kref, struct sbp2_orb, kref);
kfree(orb);
}
-static void
-sbp2_status_write(struct fw_card *card, struct fw_request *request,
- int tcode, int destination, int source,
- int generation, int speed,
- unsigned long long offset,
- void *payload, size_t length, void *callback_data)
+static void sbp2_status_write(struct fw_card *card, struct fw_request *request,
+ int tcode, int destination, int source,
+ int generation, int speed,
+ unsigned long long offset,
+ void *payload, size_t length, void *callback_data)
{
struct sbp2_logical_unit *lu = callback_data;
struct sbp2_orb *orb;
@@ -451,9 +449,8 @@ sbp2_status_write(struct fw_card *card, struct fw_request *request,
fw_send_response(card, request, RCODE_COMPLETE);
}
-static void
-complete_transaction(struct fw_card *card, int rcode,
- void *payload, size_t length, void *data)
+static void complete_transaction(struct fw_card *card, int rcode,
+ void *payload, size_t length, void *data)
{
struct sbp2_orb *orb = data;
unsigned long flags;
@@ -482,9 +479,8 @@ complete_transaction(struct fw_card *card, int rcode,
kref_put(&orb->kref, free_orb);
}
-static void
-sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
- int node_id, int generation, u64 offset)
+static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
+ int node_id, int generation, u64 offset)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
unsigned long flags;
@@ -531,8 +527,8 @@ static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu)
return retval;
}
-static void
-complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
+static void complete_management_orb(struct sbp2_orb *base_orb,
+ struct sbp2_status *status)
{
struct sbp2_management_orb *orb =
container_of(base_orb, struct sbp2_management_orb, base);
@@ -542,10 +538,9 @@ complete_management_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
complete(&orb->done);
}
-static int
-sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
- int generation, int function, int lun_or_login_id,
- void *response)
+static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
+ int generation, int function,
+ int lun_or_login_id, void *response)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct sbp2_management_orb *orb;
@@ -652,9 +647,8 @@ static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
&d, sizeof(d));
}
-static void
-complete_agent_reset_write_no_wait(struct fw_card *card, int rcode,
- void *payload, size_t length, void *data)
+static void complete_agent_reset_write_no_wait(struct fw_card *card,
+ int rcode, void *payload, size_t length, void *data)
{
kfree(data);
}
@@ -1299,8 +1293,7 @@ static void sbp2_unmap_scatterlist(struct device *card_device,
sizeof(orb->page_table), DMA_TO_DEVICE);
}
-static unsigned int
-sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data)
+static unsigned int sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data)
{
int sam_status;
@@ -1337,8 +1330,8 @@ sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data)
}
}
-static void
-complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
+static void complete_command_orb(struct sbp2_orb *base_orb,
+ struct sbp2_status *status)
{
struct sbp2_command_orb *orb =
container_of(base_orb, struct sbp2_command_orb, base);
@@ -1384,9 +1377,8 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
orb->done(orb->cmd);
}
-static int
-sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
- struct sbp2_logical_unit *lu)
+static int sbp2_map_scatterlist(struct sbp2_command_orb *orb,
+ struct fw_device *device, struct sbp2_logical_unit *lu)
{
struct scatterlist *sg = scsi_sglist(orb->cmd);
int i, n;
@@ -1584,9 +1576,8 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd)
* This is the concatenation of target port identifier and logical unit
* identifier as per SAM-2...SAM-4 annex A.
*/
-static ssize_t
-sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr,
- char *buf)
+static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct scsi_device *sdev = to_scsi_device(dev);
struct sbp2_logical_unit *lu;
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index 8dd6703b55cd..d0deecc4de93 100644
--- a/drivers/firewire/fw-topology.c
+++ b/drivers/firewire/fw-topology.c
@@ -314,9 +314,8 @@ typedef void (*fw_node_callback_t)(struct fw_card * card,
struct fw_node * node,
struct fw_node * parent);
-static void
-for_each_fw_node(struct fw_card *card, struct fw_node *root,
- fw_node_callback_t callback)
+static void for_each_fw_node(struct fw_card *card, struct fw_node *root,
+ fw_node_callback_t callback)
{
struct list_head list;
struct fw_node *node, *next, *child, *parent;
@@ -349,9 +348,8 @@ for_each_fw_node(struct fw_card *card, struct fw_node *root,
fw_node_put(node);
}
-static void
-report_lost_node(struct fw_card *card,
- struct fw_node *node, struct fw_node *parent)
+static void report_lost_node(struct fw_card *card,
+ struct fw_node *node, struct fw_node *parent)
{
fw_node_event(card, node, FW_NODE_DESTROYED);
fw_node_put(node);
@@ -360,9 +358,8 @@ report_lost_node(struct fw_card *card,
card->bm_retries = 0;
}
-static void
-report_found_node(struct fw_card *card,
- struct fw_node *node, struct fw_node *parent)
+static void report_found_node(struct fw_card *card,
+ struct fw_node *node, struct fw_node *parent)
{
int b_path = (node->phy_speed == SCODE_BETA);
@@ -415,8 +412,7 @@ static void move_tree(struct fw_node *node0, struct fw_node *node1, int port)
* found, lost or updated. Update the nodes in the card topology tree
* as we go.
*/
-static void
-update_tree(struct fw_card *card, struct fw_node *root)
+static void update_tree(struct fw_card *card, struct fw_node *root)
{
struct list_head list0, list1;
struct fw_node *node0, *node1, *next1;
@@ -497,8 +493,8 @@ update_tree(struct fw_card *card, struct fw_node *root)
}
}
-static void
-update_topology_map(struct fw_card *card, u32 *self_ids, int self_id_count)
+static void update_topology_map(struct fw_card *card,
+ u32 *self_ids, int self_id_count)
{
int node_count;
@@ -510,10 +506,8 @@ update_topology_map(struct fw_card *card, u32 *self_ids, int self_id_count)
fw_compute_block_crc(card->topology_map);
}
-void
-fw_core_handle_bus_reset(struct fw_card *card,
- int node_id, int generation,
- int self_id_count, u32 * self_ids)
+void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
+ int self_id_count, u32 *self_ids)
{
struct fw_node *local_node;
unsigned long flags;
@@ -532,6 +526,7 @@ fw_core_handle_bus_reset(struct fw_card *card,
spin_lock_irqsave(&card->lock, flags);
+ card->broadcast_channel_allocated = false;
card->node_id = node_id;
/*
* Update node_id before generation to prevent anybody from using
diff --git a/drivers/firewire/fw-topology.h b/drivers/firewire/fw-topology.h
index addb9f8ea776..3c497bb4fae4 100644
--- a/drivers/firewire/fw-topology.h
+++ b/drivers/firewire/fw-topology.h
@@ -19,6 +19,11 @@
#ifndef __fw_topology_h
#define __fw_topology_h
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#include <asm/atomic.h>
+
enum {
FW_NODE_CREATED,
FW_NODE_UPDATED,
@@ -51,26 +56,22 @@ struct fw_node {
struct fw_node *ports[0];
};
-static inline struct fw_node *
-fw_node_get(struct fw_node *node)
+static inline struct fw_node *fw_node_get(struct fw_node *node)
{
atomic_inc(&node->ref_count);
return node;
}
-static inline void
-fw_node_put(struct fw_node *node)
+static inline void fw_node_put(struct fw_node *node)
{
if (atomic_dec_and_test(&node->ref_count))
kfree(node);
}
-void
-fw_destroy_nodes(struct fw_card *card);
-
-int
-fw_compute_block_crc(u32 *block);
+struct fw_card;
+void fw_destroy_nodes(struct fw_card *card);
+int fw_compute_block_crc(u32 *block);
#endif /* __fw_topology_h */
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index 699ac041f39a..283dac6d327d 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -64,10 +64,8 @@
#define PHY_CONFIG_ROOT_ID(node_id) ((((node_id) & 0x3f) << 24) | (1 << 23))
#define PHY_IDENTIFIER(id) ((id) << 30)
-static int
-close_transaction(struct fw_transaction *transaction,
- struct fw_card *card, int rcode,
- u32 *payload, size_t length)
+static int close_transaction(struct fw_transaction *transaction,
+ struct fw_card *card, int rcode)
{
struct fw_transaction *t;
unsigned long flags;
@@ -83,7 +81,7 @@ close_transaction(struct fw_transaction *transaction,
spin_unlock_irqrestore(&card->lock, flags);
if (&t->link != &card->transaction_list) {
- t->callback(card, rcode, payload, length, t->callback_data);
+ t->callback(card, rcode, NULL, 0, t->callback_data);
return 0;
}
@@ -94,9 +92,8 @@ close_transaction(struct fw_transaction *transaction,
* Only valid for transactions that are potentially pending (ie have
* been sent).
*/
-int
-fw_cancel_transaction(struct fw_card *card,
- struct fw_transaction *transaction)
+int fw_cancel_transaction(struct fw_card *card,
+ struct fw_transaction *transaction)
{
/*
* Cancel the packet transmission if it's still queued. That
@@ -112,20 +109,19 @@ fw_cancel_transaction(struct fw_card *card,
* if the transaction is still pending and remove it in that case.
*/
- return close_transaction(transaction, card, RCODE_CANCELLED, NULL, 0);
+ return close_transaction(transaction, card, RCODE_CANCELLED);
}
EXPORT_SYMBOL(fw_cancel_transaction);
-static void
-transmit_complete_callback(struct fw_packet *packet,
- struct fw_card *card, int status)
+static void transmit_complete_callback(struct fw_packet *packet,
+ struct fw_card *card, int status)
{
struct fw_transaction *t =
container_of(packet, struct fw_transaction, packet);
switch (status) {
case ACK_COMPLETE:
- close_transaction(t, card, RCODE_COMPLETE, NULL, 0);
+ close_transaction(t, card, RCODE_COMPLETE);
break;
case ACK_PENDING:
t->timestamp = packet->timestamp;
@@ -133,31 +129,42 @@ transmit_complete_callback(struct fw_packet *packet,
case ACK_BUSY_X:
case ACK_BUSY_A:
case ACK_BUSY_B:
- close_transaction(t, card, RCODE_BUSY, NULL, 0);
+ close_transaction(t, card, RCODE_BUSY);
break;
case ACK_DATA_ERROR:
- close_transaction(t, card, RCODE_DATA_ERROR, NULL, 0);
+ close_transaction(t, card, RCODE_DATA_ERROR);
break;
case ACK_TYPE_ERROR:
- close_transaction(t, card, RCODE_TYPE_ERROR, NULL, 0);
+ close_transaction(t, card, RCODE_TYPE_ERROR);
break;
default:
/*
* In this case the ack is really a juju specific
* rcode, so just forward that to the callback.
*/
- close_transaction(t, card, status, NULL, 0);
+ close_transaction(t, card, status);
break;
}
}
-static void
-fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
+static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
int destination_id, int source_id, int generation, int speed,
unsigned long long offset, void *payload, size_t length)
{
int ext_tcode;
+ if (tcode == TCODE_STREAM_DATA) {
+ packet->header[0] =
+ HEADER_DATA_LENGTH(length) |
+ destination_id |
+ HEADER_TCODE(TCODE_STREAM_DATA);
+ packet->header_length = 4;
+ packet->payload = payload;
+ packet->payload_length = length;
+
+ goto common;
+ }
+
if (tcode > 0x10) {
ext_tcode = tcode & ~0x10;
tcode = TCODE_LOCK_REQUEST;
@@ -204,7 +211,7 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
packet->payload_length = 0;
break;
}
-
+ common:
packet->speed = speed;
packet->generation = generation;
packet->ack = 0;
@@ -246,13 +253,14 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
* @param callback function to be called when the transaction is completed
* @param callback_data pointer to arbitrary data, which will be
* passed to the callback
+ *
+ * In case of asynchronous stream packets i.e. TCODE_STREAM_DATA, the caller
+ * needs to synthesize @destination_id with fw_stream_packet_destination_id().
*/
-void
-fw_send_request(struct fw_card *card, struct fw_transaction *t,
- int tcode, int destination_id, int generation, int speed,
- unsigned long long offset,
- void *payload, size_t length,
- fw_transaction_callback_t callback, void *callback_data)
+void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode,
+ int destination_id, int generation, int speed,
+ unsigned long long offset, void *payload, size_t length,
+ fw_transaction_callback_t callback, void *callback_data)
{
unsigned long flags;
int tlabel;
@@ -322,16 +330,16 @@ static void transaction_callback(struct fw_card *card, int rcode,
* Returns the RCODE.
*/
int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
- int generation, int speed, unsigned long long offset,
- void *data, size_t length)
+ int generation, int speed, unsigned long long offset,
+ void *payload, size_t length)
{
struct transaction_callback_data d;
struct fw_transaction t;
init_completion(&d.done);
- d.payload = data;
+ d.payload = payload;
fw_send_request(card, &t, tcode, destination_id, generation, speed,
- offset, data, length, transaction_callback, &d);
+ offset, payload, length, transaction_callback, &d);
wait_for_completion(&d.done);
return d.rcode;
@@ -399,9 +407,8 @@ void fw_flush_transactions(struct fw_card *card)
}
}
-static struct fw_address_handler *
-lookup_overlapping_address_handler(struct list_head *list,
- unsigned long long offset, size_t length)
+static struct fw_address_handler *lookup_overlapping_address_handler(
+ struct list_head *list, unsigned long long offset, size_t length)
{
struct fw_address_handler *handler;
@@ -414,9 +421,8 @@ lookup_overlapping_address_handler(struct list_head *list,
return NULL;
}
-static struct fw_address_handler *
-lookup_enclosing_address_handler(struct list_head *list,
- unsigned long long offset, size_t length)
+static struct fw_address_handler *lookup_enclosing_address_handler(
+ struct list_head *list, unsigned long long offset, size_t length)
{
struct fw_address_handler *handler;
@@ -449,36 +455,44 @@ const struct fw_address_region fw_unit_space_region =
#endif /* 0 */
/**
- * Allocate a range of addresses in the node space of the OHCI
- * controller. When a request is received that falls within the
- * specified address range, the specified callback is invoked. The
- * parameters passed to the callback give the details of the
- * particular request.
+ * fw_core_add_address_handler - register for incoming requests
+ * @handler: callback
+ * @region: region in the IEEE 1212 node space address range
+ *
+ * region->start, ->end, and handler->length have to be quadlet-aligned.
+ *
+ * When a request is received that falls within the specified address range,
+ * the specified callback is invoked. The parameters passed to the callback
+ * give the details of the particular request.
*
* Return value: 0 on success, non-zero otherwise.
* The start offset of the handler's address region is determined by
* fw_core_add_address_handler() and is returned in handler->offset.
- * The offset is quadlet-aligned.
*/
-int
-fw_core_add_address_handler(struct fw_address_handler *handler,
- const struct fw_address_region *region)
+int fw_core_add_address_handler(struct fw_address_handler *handler,
+ const struct fw_address_region *region)
{
struct fw_address_handler *other;
unsigned long flags;
int ret = -EBUSY;
+ if (region->start & 0xffff000000000003ULL ||
+ region->end & 0xffff000000000003ULL ||
+ region->start >= region->end ||
+ handler->length & 3 ||
+ handler->length == 0)
+ return -EINVAL;
+
spin_lock_irqsave(&address_handler_lock, flags);
- handler->offset = roundup(region->start, 4);
+ handler->offset = region->start;
while (handler->offset + handler->length <= region->end) {
other =
lookup_overlapping_address_handler(&address_handler_list,
handler->offset,
handler->length);
if (other != NULL) {
- handler->offset =
- roundup(other->offset + other->length, 4);
+ handler->offset += other->length;
} else {
list_add_tail(&handler->link, &address_handler_list);
ret = 0;
@@ -493,12 +507,7 @@ fw_core_add_address_handler(struct fw_address_handler *handler,
EXPORT_SYMBOL(fw_core_add_address_handler);
/**
- * Deallocate a range of addresses allocated with fw_allocate. This
- * will call the associated callback one last time with a the special
- * tcode TCODE_DEALLOCATE, to let the client destroy the registered
- * callback data. For convenience, the callback parameters offset and
- * length are set to the start and the length respectively for the
- * deallocated region, payload is set to NULL.
+ * fw_core_remove_address_handler - unregister an address handler
*/
void fw_core_remove_address_handler(struct fw_address_handler *handler)
{
@@ -518,9 +527,8 @@ struct fw_request {
u32 data[0];
};
-static void
-free_response_callback(struct fw_packet *packet,
- struct fw_card *card, int status)
+static void free_response_callback(struct fw_packet *packet,
+ struct fw_card *card, int status)
{
struct fw_request *request;
@@ -528,9 +536,8 @@ free_response_callback(struct fw_packet *packet,
kfree(request);
}
-void
-fw_fill_response(struct fw_packet *response, u32 *request_header,
- int rcode, void *payload, size_t length)
+void fw_fill_response(struct fw_packet *response, u32 *request_header,
+ int rcode, void *payload, size_t length)
{
int tcode, tlabel, extended_tcode, source, destination;
@@ -588,8 +595,7 @@ fw_fill_response(struct fw_packet *response, u32 *request_header,
}
EXPORT_SYMBOL(fw_fill_response);
-static struct fw_request *
-allocate_request(struct fw_packet *p)
+static struct fw_request *allocate_request(struct fw_packet *p)
{
struct fw_request *request;
u32 *data, length;
@@ -649,8 +655,8 @@ allocate_request(struct fw_packet *p)
return request;
}
-void
-fw_send_response(struct fw_card *card, struct fw_request *request, int rcode)
+void fw_send_response(struct fw_card *card,
+ struct fw_request *request, int rcode)
{
/* unified transaction or broadcast transaction: don't respond */
if (request->ack != ACK_PENDING ||
@@ -670,8 +676,7 @@ fw_send_response(struct fw_card *card, struct fw_request *request, int rcode)
}
EXPORT_SYMBOL(fw_send_response);
-void
-fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
+void fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
{
struct fw_address_handler *handler;
struct fw_request *request;
@@ -719,8 +724,7 @@ fw_core_handle_request(struct fw_card *card, struct fw_packet *p)
}
EXPORT_SYMBOL(fw_core_handle_request);
-void
-fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
+void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
{
struct fw_transaction *t;
unsigned long flags;
@@ -793,12 +797,10 @@ static const struct fw_address_region topology_map_region =
{ .start = CSR_REGISTER_BASE | CSR_TOPOLOGY_MAP,
.end = CSR_REGISTER_BASE | CSR_TOPOLOGY_MAP_END, };
-static void
-handle_topology_map(struct fw_card *card, struct fw_request *request,
- int tcode, int destination, int source,
- int generation, int speed,
- unsigned long long offset,
- void *payload, size_t length, void *callback_data)
+static void handle_topology_map(struct fw_card *card, struct fw_request *request,
+ int tcode, int destination, int source, int generation,
+ int speed, unsigned long long offset,
+ void *payload, size_t length, void *callback_data)
{
int i, start, end;
__be32 *map;
@@ -832,12 +834,10 @@ static const struct fw_address_region registers_region =
{ .start = CSR_REGISTER_BASE,
.end = CSR_REGISTER_BASE | CSR_CONFIG_ROM, };
-static void
-handle_registers(struct fw_card *card, struct fw_request *request,
- int tcode, int destination, int source,
- int generation, int speed,
- unsigned long long offset,
- void *payload, size_t length, void *callback_data)
+static void handle_registers(struct fw_card *card, struct fw_request *request,
+ int tcode, int destination, int source, int generation,
+ int speed, unsigned long long offset,
+ void *payload, size_t length, void *callback_data)
{
int reg = offset & ~CSR_REGISTER_BASE;
unsigned long long bus_time;
@@ -939,11 +939,11 @@ static struct fw_descriptor model_id_descriptor = {
static int __init fw_core_init(void)
{
- int retval;
+ int ret;
- retval = bus_register(&fw_bus_type);
- if (retval < 0)
- return retval;
+ ret = bus_register(&fw_bus_type);
+ if (ret < 0)
+ return ret;
fw_cdev_major = register_chrdev(0, "firewire", &fw_device_ops);
if (fw_cdev_major < 0) {
@@ -951,19 +951,10 @@ static int __init fw_core_init(void)
return fw_cdev_major;
}
- retval = fw_core_add_address_handler(&topology_map,
- &topology_map_region);
- BUG_ON(retval < 0);
-
- retval = fw_core_add_address_handler(&registers,
- &registers_region);
- BUG_ON(retval < 0);
-
- /* Add the vendor textual descriptor. */
- retval = fw_core_add_descriptor(&vendor_id_descriptor);
- BUG_ON(retval < 0);
- retval = fw_core_add_descriptor(&model_id_descriptor);
- BUG_ON(retval < 0);
+ fw_core_add_address_handler(&topology_map, &topology_map_region);
+ fw_core_add_address_handler(&registers, &registers_region);
+ fw_core_add_descriptor(&vendor_id_descriptor);
+ fw_core_add_descriptor(&model_id_descriptor);
return 0;
}
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index 1d78e9cc5940..dfa799068f89 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -82,14 +82,14 @@
#define CSR_SPEED_MAP 0x2000
#define CSR_SPEED_MAP_END 0x3000
+#define BANDWIDTH_AVAILABLE_INITIAL 4915
#define BROADCAST_CHANNEL_INITIAL (1 << 31 | 31)
#define BROADCAST_CHANNEL_VALID (1 << 30)
#define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args)
#define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args)
-static inline void
-fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
+static inline void fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
{
u32 *dst = _dst;
__be32 *src = _src;
@@ -99,8 +99,7 @@ fw_memcpy_from_be32(void *_dst, void *_src, size_t size)
dst[i] = be32_to_cpu(src[i]);
}
-static inline void
-fw_memcpy_to_be32(void *_dst, void *_src, size_t size)
+static inline void fw_memcpy_to_be32(void *_dst, void *_src, size_t size)
{
fw_memcpy_from_be32(_dst, _src, size);
}
@@ -125,8 +124,7 @@ typedef void (*fw_packet_callback_t)(struct fw_packet *packet,
struct fw_card *card, int status);
typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode,
- void *data,
- size_t length,
+ void *data, size_t length,
void *callback_data);
/*
@@ -141,12 +139,6 @@ typedef void (*fw_address_callback_t)(struct fw_card *card,
void *data, size_t length,
void *callback_data);
-typedef void (*fw_bus_reset_callback_t)(struct fw_card *handle,
- int node_id, int generation,
- u32 *self_ids,
- int self_id_count,
- void *callback_data);
-
struct fw_packet {
int speed;
int generation;
@@ -187,12 +179,6 @@ struct fw_transaction {
void *callback_data;
};
-static inline struct fw_packet *
-fw_packet(struct list_head *l)
-{
- return list_entry(l, struct fw_packet, link);
-}
-
struct fw_address_handler {
u64 offset;
size_t length;
@@ -201,7 +187,6 @@ struct fw_address_handler {
struct list_head link;
};
-
struct fw_address_region {
u64 start;
u64 end;
@@ -255,6 +240,7 @@ struct fw_card {
int bm_retries;
int bm_generation;
+ bool broadcast_channel_allocated;
u32 broadcast_channel;
u32 topology_map[(CSR_TOPOLOGY_MAP_END - CSR_TOPOLOGY_MAP) / 4];
};
@@ -315,10 +301,8 @@ struct fw_iso_packet {
struct fw_iso_context;
typedef void (*fw_iso_callback_t)(struct fw_iso_context *context,
- u32 cycle,
- size_t header_length,
- void *header,
- void *data);
+ u32 cycle, size_t header_length,
+ void *header, void *data);
/*
* An iso buffer is just a set of pages mapped for DMA in the
@@ -344,36 +328,25 @@ struct fw_iso_context {
void *callback_data;
};
-int
-fw_iso_buffer_init(struct fw_iso_buffer *buffer,
- struct fw_card *card,
- int page_count,
- enum dma_data_direction direction);
-int
-fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma);
-void
-fw_iso_buffer_destroy(struct fw_iso_buffer *buffer, struct fw_card *card);
-
-struct fw_iso_context *
-fw_iso_context_create(struct fw_card *card, int type,
- int channel, int speed, size_t header_size,
- fw_iso_callback_t callback, void *callback_data);
-
-void
-fw_iso_context_destroy(struct fw_iso_context *ctx);
-
-int
-fw_iso_context_queue(struct fw_iso_context *ctx,
- struct fw_iso_packet *packet,
- struct fw_iso_buffer *buffer,
- unsigned long payload);
-
-int
-fw_iso_context_start(struct fw_iso_context *ctx,
- int cycle, int sync, int tags);
-
-int
-fw_iso_context_stop(struct fw_iso_context *ctx);
+int fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card,
+ int page_count, enum dma_data_direction direction);
+int fw_iso_buffer_map(struct fw_iso_buffer *buffer, struct vm_area_struct *vma);
+void fw_iso_buffer_destroy(struct fw_iso_buffer *buffer, struct fw_card *card);
+
+struct fw_iso_context *fw_iso_context_create(struct fw_card *card,
+ int type, int channel, int speed, size_t header_size,
+ fw_iso_callback_t callback, void *callback_data);
+int fw_iso_context_queue(struct fw_iso_context *ctx,
+ struct fw_iso_packet *packet,
+ struct fw_iso_buffer *buffer,
+ unsigned long payload);
+int fw_iso_context_start(struct fw_iso_context *ctx,
+ int cycle, int sync, int tags);
+int fw_iso_context_stop(struct fw_iso_context *ctx);
+void fw_iso_context_destroy(struct fw_iso_context *ctx);
+
+void fw_iso_resource_manage(struct fw_card *card, int generation,
+ u64 channels_mask, int *channel, int *bandwidth, bool allocate);
struct fw_card_driver {
/*
@@ -415,7 +388,7 @@ struct fw_card_driver {
struct fw_iso_context *
(*allocate_iso_context)(struct fw_card *card,
- int type, size_t header_size);
+ int type, int channel, size_t header_size);
void (*free_iso_context)(struct fw_iso_context *ctx);
int (*start_iso)(struct fw_iso_context *ctx,
@@ -429,54 +402,45 @@ struct fw_card_driver {
int (*stop_iso)(struct fw_iso_context *ctx);
};
-int
-fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
+int fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
-void
-fw_send_request(struct fw_card *card, struct fw_transaction *t,
+void fw_send_request(struct fw_card *card, struct fw_transaction *t,
int tcode, int destination_id, int generation, int speed,
- unsigned long long offset, void *data, size_t length,
+ unsigned long long offset, void *payload, size_t length,
fw_transaction_callback_t callback, void *callback_data);
-
-int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
- int generation, int speed, unsigned long long offset,
- void *data, size_t length);
-
int fw_cancel_transaction(struct fw_card *card,
struct fw_transaction *transaction);
-
void fw_flush_transactions(struct fw_card *card);
-
+int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
+ int generation, int speed, unsigned long long offset,
+ void *payload, size_t length);
void fw_send_phy_config(struct fw_card *card,
int node_id, int generation, int gap_count);
+static inline int fw_stream_packet_destination_id(int tag, int channel, int sy)
+{
+ return tag << 14 | channel << 8 | sy;
+}
+
/*
* Called by the topology code to inform the device code of node
* activity; found, lost, or updated nodes.
*/
-void
-fw_node_event(struct fw_card *card, struct fw_node *node, int event);
+void fw_node_event(struct fw_card *card, struct fw_node *node, int event);
/* API used by card level drivers */
-void
-fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
- struct device *device);
-int
-fw_card_add(struct fw_card *card,
- u32 max_receive, u32 link_speed, u64 guid);
-
-void
-fw_core_remove_card(struct fw_card *card);
-
-void
-fw_core_handle_bus_reset(struct fw_card *card,
- int node_id, int generation,
- int self_id_count, u32 *self_ids);
-void
-fw_core_handle_request(struct fw_card *card, struct fw_packet *request);
-
-void
-fw_core_handle_response(struct fw_card *card, struct fw_packet *packet);
+void fw_card_initialize(struct fw_card *card,
+ const struct fw_card_driver *driver, struct device *device);
+int fw_card_add(struct fw_card *card,
+ u32 max_receive, u32 link_speed, u64 guid);
+void fw_core_remove_card(struct fw_card *card);
+void fw_core_handle_bus_reset(struct fw_card *card, int node_id,
+ int generation, int self_id_count, u32 *self_ids);
+void fw_core_handle_request(struct fw_card *card, struct fw_packet *request);
+void fw_core_handle_response(struct fw_card *card, struct fw_packet *packet);
+
+extern int fw_irm_set_broadcast_channel_register(struct device *dev,
+ void *data);
#endif /* __fw_transaction_h */
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 8f0f7c449305..5f1b5400d96a 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -68,7 +68,8 @@ static char * __init dmi_string(const struct dmi_header *dm, u8 s)
* pointing to completely the wrong place for example
*/
static void dmi_table(u8 *buf, int len, int num,
- void (*decode)(const struct dmi_header *))
+ void (*decode)(const struct dmi_header *, void *),
+ void *private_data)
{
u8 *data = buf;
int i = 0;
@@ -89,7 +90,7 @@ static void dmi_table(u8 *buf, int len, int num,
while ((data - buf < len - 1) && (data[0] || data[1]))
data++;
if (data - buf < len - 1)
- decode(dm);
+ decode(dm, private_data);
data += 2;
i++;
}
@@ -99,7 +100,8 @@ static u32 dmi_base;
static u16 dmi_len;
static u16 dmi_num;
-static int __init dmi_walk_early(void (*decode)(const struct dmi_header *))
+static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
+ void *))
{
u8 *buf;
@@ -107,7 +109,7 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *))
if (buf == NULL)
return -1;
- dmi_table(buf, dmi_len, dmi_num, decode);
+ dmi_table(buf, dmi_len, dmi_num, decode, NULL);
dmi_iounmap(buf, dmi_len);
return 0;
@@ -295,7 +297,7 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm)
* and machine entries. For 2.5 we should pull the smbus controller info
* out of here.
*/
-static void __init dmi_decode(const struct dmi_header *dm)
+static void __init dmi_decode(const struct dmi_header *dm, void *dummy)
{
switch(dm->type) {
case 0: /* BIOS Information */
@@ -598,10 +600,12 @@ int dmi_get_year(int field)
/**
* dmi_walk - Walk the DMI table and get called back for every record
* @decode: Callback function
+ * @private_data: Private data to be passed to the callback function
*
* Returns -1 when the DMI table can't be reached, 0 on success.
*/
-int dmi_walk(void (*decode)(const struct dmi_header *))
+int dmi_walk(void (*decode)(const struct dmi_header *, void *),
+ void *private_data)
{
u8 *buf;
@@ -612,7 +616,7 @@ int dmi_walk(void (*decode)(const struct dmi_header *))
if (buf == NULL)
return -1;
- dmi_table(buf, dmi_len, dmi_num, decode);
+ dmi_table(buf, dmi_len, dmi_num, decode, private_data);
iounmap(buf);
return 0;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 3d2565441b36..edb02530e461 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -42,9 +42,9 @@ config DEBUG_GPIO
depends on DEBUG_KERNEL
help
Say Y here to add some extra checks and diagnostics to GPIO calls.
- The checks help ensure that GPIOs have been properly initialized
- before they are used and that sleeping calls aren not made from
- nonsleeping contexts. They can make bitbanged serial protocols
+ These checks help ensure that GPIOs have been properly initialized
+ before they are used, and that sleeping calls are not made from
+ non-sleeping contexts. They can make bitbanged serial protocols
slower. The diagnostics help catch the type of setup errors
that are most common when setting up new platforms or boards.
diff --git a/drivers/gpio/bt8xxgpio.c b/drivers/gpio/bt8xxgpio.c
index 7a1168249dd5..984b587f0f96 100644
--- a/drivers/gpio/bt8xxgpio.c
+++ b/drivers/gpio/bt8xxgpio.c
@@ -160,7 +160,7 @@ static void bt8xxgpio_gpio_setup(struct bt8xxgpio *bg)
{
struct gpio_chip *c = &bg->gpio;
- c->label = bg->pdev->dev.bus_id;
+ c->label = dev_name(&bg->pdev->dev);
c->owner = THIS_MODULE;
c->direction_input = bt8xxgpio_gpio_direction_input;
c->get = bt8xxgpio_gpio_get;
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 42fb2fd24c0c..51a8d4103be5 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -69,20 +69,24 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label)
* those calls have no teeth) we can't avoid autorequesting. This nag
* message should motivate switching to explicit requests... so should
* the weaker cleanup after faults, compared to gpio_request().
+ *
+ * NOTE: the autorequest mechanism is going away; at this point it's
+ * only "legal" in the sense that (old) code using it won't break yet,
+ * but instead only triggers a WARN() stack dump.
*/
static int gpio_ensure_requested(struct gpio_desc *desc, unsigned offset)
{
- if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
- struct gpio_chip *chip = desc->chip;
- int gpio = chip->base + offset;
+ const struct gpio_chip *chip = desc->chip;
+ const int gpio = chip->base + offset;
+ if (WARN(test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0,
+ "autorequest GPIO-%d\n", gpio)) {
if (!try_module_get(chip->owner)) {
pr_err("GPIO-%d: module can't be gotten \n", gpio);
clear_bit(FLAG_REQUESTED, &desc->flags);
/* lose */
return -EIO;
}
- pr_warning("GPIO-%d autorequested\n", gpio);
desc_set_label(desc, "[auto]");
/* caller must chip->request() w/o spinlock */
if (chip->request)
@@ -438,6 +442,7 @@ int gpio_export(unsigned gpio, bool direction_may_change)
unsigned long flags;
struct gpio_desc *desc;
int status = -EINVAL;
+ char *ioname = NULL;
/* can't export until sysfs is available ... */
if (!gpio_class.p) {
@@ -461,11 +466,14 @@ int gpio_export(unsigned gpio, bool direction_may_change)
}
spin_unlock_irqrestore(&gpio_lock, flags);
+ if (desc->chip->names && desc->chip->names[gpio - desc->chip->base])
+ ioname = desc->chip->names[gpio - desc->chip->base];
+
if (status == 0) {
struct device *dev;
dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
- desc, "gpio%d", gpio);
+ desc, ioname ? ioname : "gpio%d", gpio);
if (dev) {
if (direction_may_change)
status = sysfs_create_group(&dev->kobj,
@@ -513,6 +521,7 @@ void gpio_unexport(unsigned gpio)
mutex_lock(&sysfs_lock);
desc = &gpio_desc[gpio];
+
if (test_bit(FLAG_EXPORT, &desc->flags)) {
struct device *dev = NULL;
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 30022c4a5c12..4ec5061fa584 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -10,7 +10,8 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
- drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o
+ drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o \
+ drm_info.o drm_debugfs.o
drm-$(CONFIG_COMPAT) += drm_ioc32.o
diff --git a/drivers/gpu/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c
index c533d0c9ec61..628eae3e9b83 100644
--- a/drivers/gpu/drm/ati_pcigart.c
+++ b/drivers/gpu/drm/ati_pcigart.c
@@ -77,7 +77,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info
if (!entry->busaddr[i])
break;
pci_unmap_page(dev->pdev, entry->busaddr[i],
- PAGE_SIZE, PCI_DMA_TODEVICE);
+ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
}
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
@@ -95,13 +95,14 @@ EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info)
{
+ struct drm_local_map *map = &gart_info->mapping;
struct drm_sg_mem *entry = dev->sg;
void *address = NULL;
unsigned long pages;
- u32 *pci_gart, page_base;
+ u32 *pci_gart = NULL, page_base, gart_idx;
dma_addr_t bus_address = 0;
int i, j, ret = 0;
- int max_pages;
+ int max_ati_pages, max_real_pages;
if (!entry) {
DRM_ERROR("no scatter/gather memory!\n");
@@ -117,6 +118,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
goto done;
}
+ pci_gart = gart_info->table_handle->vaddr;
address = gart_info->table_handle->vaddr;
bus_address = gart_info->table_handle->busaddr;
} else {
@@ -127,18 +129,23 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
(unsigned long)address);
}
- pci_gart = (u32 *) address;
- max_pages = (gart_info->table_size / sizeof(u32));
- pages = (entry->pages <= max_pages)
- ? entry->pages : max_pages;
+ max_ati_pages = (gart_info->table_size / sizeof(u32));
+ max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE);
+ pages = (entry->pages <= max_real_pages)
+ ? entry->pages : max_real_pages;
- memset(pci_gart, 0, max_pages * sizeof(u32));
+ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
+ memset(pci_gart, 0, max_ati_pages * sizeof(u32));
+ } else {
+ memset_io((void __iomem *)map->handle, 0, max_ati_pages * sizeof(u32));
+ }
+ gart_idx = 0;
for (i = 0; i < pages; i++) {
/* we need to support large memory configurations */
entry->busaddr[i] = pci_map_page(dev->pdev, entry->pagelist[i],
- 0, PAGE_SIZE, PCI_DMA_TODEVICE);
+ 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
if (entry->busaddr[i] == 0) {
DRM_ERROR("unable to map PCIGART pages!\n");
drm_ati_pcigart_cleanup(dev, gart_info);
@@ -149,19 +156,26 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
page_base = (u32) entry->busaddr[i];
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
+ u32 val;
+
switch(gart_info->gart_reg_if) {
case DRM_ATI_GART_IGP:
- *pci_gart = cpu_to_le32((page_base) | 0xc);
+ val = page_base | 0xc;
break;
case DRM_ATI_GART_PCIE:
- *pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
+ val = (page_base >> 8) | 0xc;
break;
default:
case DRM_ATI_GART_PCI:
- *pci_gart = cpu_to_le32(page_base);
+ val = page_base;
break;
}
- pci_gart++;
+ if (gart_info->gart_table_location ==
+ DRM_ATI_GART_MAIN)
+ pci_gart[gart_idx] = cpu_to_le32(val);
+ else
+ DRM_WRITE32(map, gart_idx * sizeof(u32), val);
+ gart_idx++;
page_base += ATI_PCIGART_PAGE_SIZE;
}
}
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 12715d3c078d..6d80d17f1e96 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -34,15 +34,17 @@
*/
#include <linux/vmalloc.h>
+#include <linux/log2.h>
+#include <asm/shmparam.h>
#include "drmP.h"
-unsigned long drm_get_resource_start(struct drm_device *dev, unsigned int resource)
+resource_size_t drm_get_resource_start(struct drm_device *dev, unsigned int resource)
{
return pci_resource_start(dev->pdev, resource);
}
EXPORT_SYMBOL(drm_get_resource_start);
-unsigned long drm_get_resource_len(struct drm_device *dev, unsigned int resource)
+resource_size_t drm_get_resource_len(struct drm_device *dev, unsigned int resource)
{
return pci_resource_len(dev->pdev, resource);
}
@@ -50,24 +52,44 @@ unsigned long drm_get_resource_len(struct drm_device *dev, unsigned int resource
EXPORT_SYMBOL(drm_get_resource_len);
static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
- drm_local_map_t *map)
+ struct drm_local_map *map)
{
struct drm_map_list *entry;
list_for_each_entry(entry, &dev->maplist, head) {
- if (entry->map && (entry->master == dev->primary->master) && (map->type == entry->map->type) &&
- ((entry->map->offset == map->offset) ||
- ((map->type == _DRM_SHM) && (map->flags&_DRM_CONTAINS_LOCK)))) {
+ /*
+ * Because the kernel-userspace ABI is fixed at a 32-bit offset
+ * while PCI resources may live above that, we ignore the map
+ * offset for maps of type _DRM_FRAMEBUFFER or _DRM_REGISTERS.
+ * It is assumed that each driver will have only one resource of
+ * each type.
+ */
+ if (!entry->map ||
+ map->type != entry->map->type ||
+ entry->master != dev->primary->master)
+ continue;
+ switch (map->type) {
+ case _DRM_SHM:
+ if (map->flags != _DRM_CONTAINS_LOCK)
+ break;
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
return entry;
+ default: /* Make gcc happy */
+ ;
}
+ if (entry->map->offset == map->offset)
+ return entry;
}
return NULL;
}
static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
- unsigned long user_token, int hashed_handle)
+ unsigned long user_token, int hashed_handle, int shm)
{
- int use_hashed_handle;
+ int use_hashed_handle, shift;
+ unsigned long add;
+
#if (BITS_PER_LONG == 64)
use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle);
#elif (BITS_PER_LONG == 32)
@@ -83,30 +105,47 @@ static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
if (ret != -EINVAL)
return ret;
}
+
+ shift = 0;
+ add = DRM_MAP_HASH_OFFSET >> PAGE_SHIFT;
+ if (shm && (SHMLBA > PAGE_SIZE)) {
+ int bits = ilog2(SHMLBA >> PAGE_SHIFT) + 1;
+
+ /* For shared memory, we have to preserve the SHMLBA
+ * bits of the eventual vma->vm_pgoff value during
+ * mmap(). Otherwise we run into cache aliasing problems
+ * on some platforms. On these platforms, the pgoff of
+ * a mmap() request is used to pick a suitable virtual
+ * address for the mmap() region such that it will not
+ * cause cache aliasing problems.
+ *
+ * Therefore, make sure the SHMLBA relevant bits of the
+ * hash value we use are equal to those in the original
+ * kernel virtual address.
+ */
+ shift = bits;
+ add |= ((user_token >> PAGE_SHIFT) & ((1UL << bits) - 1UL));
+ }
+
return drm_ht_just_insert_please(&dev->map_hash, hash,
user_token, 32 - PAGE_SHIFT - 3,
- 0, DRM_MAP_HASH_OFFSET >> PAGE_SHIFT);
+ shift, add);
}
/**
- * Ioctl to specify a range of memory that is available for mapping by a non-root process.
- *
- * \param inode device inode.
- * \param file_priv DRM file private.
- * \param cmd command.
- * \param arg pointer to a drm_map structure.
- * \return zero on success or a negative value on error.
+ * Core function to create a range of memory available for mapping by a
+ * non-root process.
*
* Adjusts the memory offset to its absolute value according to the mapping
* type. Adds the map to the map list drm_device::maplist. Adds MTRR's where
* applicable and if supported by the kernel.
*/
-static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
+static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
unsigned int size, enum drm_map_type type,
enum drm_map_flags flags,
struct drm_map_list ** maplist)
{
- struct drm_map *map;
+ struct drm_local_map *map;
struct drm_map_list *list;
drm_dma_handle_t *dmah;
unsigned long user_token;
@@ -129,9 +168,9 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
}
- DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n",
- map->offset, map->size, map->type);
- if ((map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK))) {
+ DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n",
+ (unsigned long long)map->offset, map->size, map->type);
+ if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) {
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
}
@@ -259,7 +298,8 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EPERM;
}
- DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size);
+ DRM_DEBUG("AGP offset = 0x%08llx, size = 0x%08lx\n",
+ (unsigned long long)map->offset, map->size);
break;
case _DRM_GEM:
@@ -309,7 +349,8 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
/* We do it here so that dev->struct_mutex protects the increment */
user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle :
map->offset;
- ret = drm_map_handle(dev, &list->hash, user_token, 0);
+ ret = drm_map_handle(dev, &list->hash, user_token, 0,
+ (map->type == _DRM_SHM));
if (ret) {
if (map->type == _DRM_REGISTERS)
iounmap(map->handle);
@@ -327,9 +368,9 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
return 0;
}
-int drm_addmap(struct drm_device * dev, unsigned int offset,
+int drm_addmap(struct drm_device * dev, resource_size_t offset,
unsigned int size, enum drm_map_type type,
- enum drm_map_flags flags, drm_local_map_t ** map_ptr)
+ enum drm_map_flags flags, struct drm_local_map ** map_ptr)
{
struct drm_map_list *list;
int rc;
@@ -342,6 +383,17 @@ int drm_addmap(struct drm_device * dev, unsigned int offset,
EXPORT_SYMBOL(drm_addmap);
+/**
+ * Ioctl to specify a range of memory that is available for mapping by a
+ * non-root process.
+ *
+ * \param inode device inode.
+ * \param file_priv DRM file private.
+ * \param cmd command.
+ * \param arg pointer to a drm_map structure.
+ * \return zero on success or a negative value on error.
+ *
+ */
int drm_addmap_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
@@ -367,19 +419,13 @@ int drm_addmap_ioctl(struct drm_device *dev, void *data,
* Remove a map private from list and deallocate resources if the mapping
* isn't in use.
*
- * \param inode device inode.
- * \param file_priv DRM file private.
- * \param cmd command.
- * \param arg pointer to a struct drm_map structure.
- * \return zero on success or a negative value on error.
- *
* Searches the map on drm_device::maplist, removes it from the list, see if
* its being used, and free any associate resource (such as MTRR's) if it's not
* being on use.
*
* \sa drm_addmap
*/
-int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
+int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map)
{
struct drm_map_list *r_list = NULL, *list_t;
drm_dma_handle_t dmah;
@@ -442,7 +488,7 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
}
EXPORT_SYMBOL(drm_rmmap_locked);
-int drm_rmmap(struct drm_device *dev, drm_local_map_t *map)
+int drm_rmmap(struct drm_device *dev, struct drm_local_map *map)
{
int ret;
@@ -462,12 +508,18 @@ EXPORT_SYMBOL(drm_rmmap);
* One use case might be after addmap is allowed for normal users for SHM and
* gets used by drivers that the server doesn't need to care about. This seems
* unlikely.
+ *
+ * \param inode device inode.
+ * \param file_priv DRM file private.
+ * \param cmd command.
+ * \param arg pointer to a struct drm_map structure.
+ * \return zero on success or a negative value on error.
*/
int drm_rmmap_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_map *request = data;
- drm_local_map_t *map = NULL;
+ struct drm_local_map *map = NULL;
struct drm_map_list *r_list;
int ret;
@@ -1534,7 +1586,7 @@ int drm_mapbufs(struct drm_device *dev, void *data,
&& (dma->flags & _DRM_DMA_USE_SG))
|| (drm_core_check_feature(dev, DRIVER_FB_DMA)
&& (dma->flags & _DRM_DMA_USE_FB))) {
- struct drm_map *map = dev->agp_buffer_map;
+ struct drm_local_map *map = dev->agp_buffer_map;
unsigned long token = dev->agp_buffer_token;
if (!map) {
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index 809ec0f03452..7d1e53c10d4b 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -143,7 +143,7 @@ int drm_getsareactx(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_ctx_priv_map *request = data;
- struct drm_map *map;
+ struct drm_local_map *map;
struct drm_map_list *_entry;
mutex_lock(&dev->struct_mutex);
@@ -186,7 +186,7 @@ int drm_setsareactx(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_ctx_priv_map *request = data;
- struct drm_map *map = NULL;
+ struct drm_local_map *map = NULL;
struct drm_map_list *r_list = NULL;
mutex_lock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 1c3a8c557140..a04639dc633d 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -42,6 +42,26 @@ static struct drm_display_mode std_modes[] = {
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
};
+static void drm_mode_validate_flag(struct drm_connector *connector,
+ int flags)
+{
+ struct drm_display_mode *mode, *t;
+
+ if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
+ return;
+
+ list_for_each_entry_safe(mode, t, &connector->modes, head) {
+ if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
+ !(flags & DRM_MODE_FLAG_INTERLACE))
+ mode->status = MODE_NO_INTERLACE;
+ if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
+ !(flags & DRM_MODE_FLAG_DBLSCAN))
+ mode->status = MODE_NO_DBLESCAN;
+ }
+
+ return;
+}
+
/**
* drm_helper_probe_connector_modes - get complete set of display modes
* @dev: DRM device
@@ -72,6 +92,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
struct drm_connector_helper_funcs *connector_funcs =
connector->helper_private;
int count = 0;
+ int mode_flags = 0;
DRM_DEBUG("%s\n", drm_get_connector_name(connector));
/* set all modes to the unverified state */
@@ -96,6 +117,13 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
if (maxX && maxY)
drm_mode_validate_size(dev, &connector->modes, maxX,
maxY, 0);
+
+ if (connector->interlace_allowed)
+ mode_flags |= DRM_MODE_FLAG_INTERLACE;
+ if (connector->doublescan_allowed)
+ mode_flags |= DRM_MODE_FLAG_DBLSCAN;
+ drm_mode_validate_flag(connector, mode_flags);
+
list_for_each_entry_safe(mode, t, &connector->modes, head) {
if (mode->status == MODE_OK)
mode->status = connector_funcs->mode_valid(connector,
@@ -885,7 +913,6 @@ bool drm_helper_plugged_event(struct drm_device *dev)
/**
* drm_initial_config - setup a sane initial connector configuration
* @dev: DRM device
- * @can_grow: this configuration is growable
*
* LOCKING:
* Called at init time, must take mode config lock.
@@ -897,7 +924,7 @@ bool drm_helper_plugged_event(struct drm_device *dev)
* RETURNS:
* Zero if everything went ok, nonzero otherwise.
*/
-bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
+bool drm_helper_initial_config(struct drm_device *dev)
{
struct drm_connector *connector;
int count = 0;
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
new file mode 100644
index 000000000000..c77c6c6d9d2c
--- /dev/null
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -0,0 +1,235 @@
+/**
+ * \file drm_debugfs.c
+ * debugfs support for DRM
+ *
+ * \author Ben Gamari <bgamari@gmail.com>
+ */
+
+/*
+ * Created: Sun Dec 21 13:08:50 2008 by bgamari@gmail.com
+ *
+ * Copyright 2008 Ben Gamari <bgamari@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include "drmP.h"
+
+#if defined(CONFIG_DEBUG_FS)
+
+/***************************************************
+ * Initialization, etc.
+ **************************************************/
+
+static struct drm_info_list drm_debugfs_list[] = {
+ {"name", drm_name_info, 0},
+ {"vm", drm_vm_info, 0},
+ {"clients", drm_clients_info, 0},
+ {"queues", drm_queues_info, 0},
+ {"bufs", drm_bufs_info, 0},
+ {"gem_names", drm_gem_name_info, DRIVER_GEM},
+ {"gem_objects", drm_gem_object_info, DRIVER_GEM},
+#if DRM_DEBUG_CODE
+ {"vma", drm_vma_info, 0},
+#endif
+};
+#define DRM_DEBUGFS_ENTRIES ARRAY_SIZE(drm_debugfs_list)
+
+
+static int drm_debugfs_open(struct inode *inode, struct file *file)
+{
+ struct drm_info_node *node = inode->i_private;
+
+ return single_open(file, node->info_ent->show, node);
+}
+
+
+static const struct file_operations drm_debugfs_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_debugfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+
+/**
+ * Initialize a given set of debugfs files for a device
+ *
+ * \param files The array of files to create
+ * \param count The number of files given
+ * \param root DRI debugfs dir entry.
+ * \param minor device minor number
+ * \return Zero on success, non-zero on failure
+ *
+ * Create a given set of debugfs files represented by an array of
+ * gdm_debugfs_lists in the given root directory.
+ */
+int drm_debugfs_create_files(struct drm_info_list *files, int count,
+ struct dentry *root, struct drm_minor *minor)
+{
+ struct drm_device *dev = minor->dev;
+ struct dentry *ent;
+ struct drm_info_node *tmp;
+ char name[64];
+ int i, ret;
+
+ for (i = 0; i < count; i++) {
+ u32 features = files[i].driver_features;
+
+ if (features != 0 &&
+ (dev->driver->driver_features & features) != features)
+ continue;
+
+ tmp = drm_alloc(sizeof(struct drm_info_node),
+ _DRM_DRIVER);
+ ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO,
+ root, tmp, &drm_debugfs_fops);
+ if (!ent) {
+ DRM_ERROR("Cannot create /debugfs/dri/%s/%s\n",
+ name, files[i].name);
+ drm_free(tmp, sizeof(struct drm_info_node),
+ _DRM_DRIVER);
+ ret = -1;
+ goto fail;
+ }
+
+ tmp->minor = minor;
+ tmp->dent = ent;
+ tmp->info_ent = &files[i];
+ list_add(&(tmp->list), &(minor->debugfs_nodes.list));
+ }
+ return 0;
+
+fail:
+ drm_debugfs_remove_files(files, count, minor);
+ return ret;
+}
+EXPORT_SYMBOL(drm_debugfs_create_files);
+
+/**
+ * Initialize the DRI debugfs filesystem for a device
+ *
+ * \param dev DRM device
+ * \param minor device minor number
+ * \param root DRI debugfs dir entry.
+ *
+ * Create the DRI debugfs root entry "/debugfs/dri", the device debugfs root entry
+ * "/debugfs/dri/%minor%/", and each entry in debugfs_list as
+ * "/debugfs/dri/%minor%/%name%".
+ */
+int drm_debugfs_init(struct drm_minor *minor, int minor_id,
+ struct dentry *root)
+{
+ struct drm_device *dev = minor->dev;
+ char name[64];
+ int ret;
+
+ INIT_LIST_HEAD(&minor->debugfs_nodes.list);
+ sprintf(name, "%d", minor_id);
+ minor->debugfs_root = debugfs_create_dir(name, root);
+ if (!minor->debugfs_root) {
+ DRM_ERROR("Cannot create /debugfs/dri/%s\n", name);
+ return -1;
+ }
+
+ ret = drm_debugfs_create_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES,
+ minor->debugfs_root, minor);
+ if (ret) {
+ debugfs_remove(minor->debugfs_root);
+ minor->debugfs_root = NULL;
+ DRM_ERROR("Failed to create core drm debugfs files\n");
+ return ret;
+ }
+
+ if (dev->driver->debugfs_init) {
+ ret = dev->driver->debugfs_init(minor);
+ if (ret) {
+ DRM_ERROR("DRM: Driver failed to initialize "
+ "/debugfs/dri.\n");
+ return ret;
+ }
+ }
+ return 0;
+}
+
+
+/**
+ * Remove a list of debugfs files
+ *
+ * \param files The list of files
+ * \param count The number of files
+ * \param minor The minor of which we should remove the files
+ * \return always zero.
+ *
+ * Remove all debugfs entries created by debugfs_init().
+ */
+int drm_debugfs_remove_files(struct drm_info_list *files, int count,
+ struct drm_minor *minor)
+{
+ struct list_head *pos, *q;
+ struct drm_info_node *tmp;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ list_for_each_safe(pos, q, &minor->debugfs_nodes.list) {
+ tmp = list_entry(pos, struct drm_info_node, list);
+ if (tmp->info_ent == &files[i]) {
+ debugfs_remove(tmp->dent);
+ list_del(pos);
+ drm_free(tmp, sizeof(struct drm_info_node),
+ _DRM_DRIVER);
+ }
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL(drm_debugfs_remove_files);
+
+/**
+ * Cleanup the debugfs filesystem resources.
+ *
+ * \param minor device minor number.
+ * \return always zero.
+ *
+ * Remove all debugfs entries created by debugfs_init().
+ */
+int drm_debugfs_cleanup(struct drm_minor *minor)
+{
+ struct drm_device *dev = minor->dev;
+
+ if (!minor->debugfs_root)
+ return 0;
+
+ if (dev->driver->debugfs_cleanup)
+ dev->driver->debugfs_cleanup(minor);
+
+ drm_debugfs_remove_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES, minor);
+
+ debugfs_remove(minor->debugfs_root);
+ minor->debugfs_root = NULL;
+
+ return 0;
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 14c7a23dc157..c4ada8b6295b 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -46,9 +46,11 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <linux/debugfs.h>
#include "drmP.h"
#include "drm_core.h"
+
static int drm_version(struct drm_device *dev, void *data,
struct drm_file *file_priv);
@@ -178,7 +180,7 @@ int drm_lastclose(struct drm_device * dev)
/* Clear AGP information */
if (drm_core_has_AGP(dev) && dev->agp &&
- !drm_core_check_feature(dev, DRIVER_MODESET)) {
+ !drm_core_check_feature(dev, DRIVER_MODESET)) {
struct drm_agp_mem *entry, *tempe;
/* Remove AGP resources, but leave dev->agp
@@ -252,15 +254,19 @@ int drm_lastclose(struct drm_device * dev)
int drm_init(struct drm_driver *driver)
{
struct pci_dev *pdev = NULL;
- struct pci_device_id *pid;
+ const struct pci_device_id *pid;
int i;
DRM_DEBUG("\n");
INIT_LIST_HEAD(&driver->device_list);
+ if (driver->driver_features & DRIVER_MODESET)
+ return pci_register_driver(&driver->pci_driver);
+
+ /* If not using KMS, fall back to stealth mode manual scanning. */
for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
- pid = (struct pci_device_id *)&driver->pci_driver.id_table[i];
+ pid = &driver->pci_driver.id_table[i];
/* Loop around setting up a DRM device for each PCI device
* matching our ID and device class. If we had the internal
@@ -285,68 +291,17 @@ int drm_init(struct drm_driver *driver)
EXPORT_SYMBOL(drm_init);
-/**
- * Called via cleanup_module() at module unload time.
- *
- * Cleans up all DRM device, calling drm_lastclose().
- *
- * \sa drm_init
- */
-static void drm_cleanup(struct drm_device * dev)
-{
- struct drm_map_list *r_list, *list_temp;
- DRM_DEBUG("\n");
-
- if (!dev) {
- DRM_ERROR("cleanup called no dev\n");
- return;
- }
-
- drm_vblank_cleanup(dev);
-
- drm_lastclose(dev);
-
- if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
- dev->agp && dev->agp->agp_mtrr >= 0) {
- int retval;
- retval = mtrr_del(dev->agp->agp_mtrr,
- dev->agp->agp_info.aper_base,
- dev->agp->agp_info.aper_size * 1024 * 1024);
- DRM_DEBUG("mtrr_del=%d\n", retval);
- }
-
- if (dev->driver->unload)
- dev->driver->unload(dev);
-
- if (drm_core_has_AGP(dev) && dev->agp) {
- drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
- dev->agp = NULL;
- }
-
- drm_ht_remove(&dev->map_hash);
- drm_ctxbitmap_cleanup(dev);
-
- list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
- drm_rmmap(dev, r_list->map);
-
- if (drm_core_check_feature(dev, DRIVER_MODESET))
- drm_put_minor(&dev->control);
-
- if (dev->driver->driver_features & DRIVER_GEM)
- drm_gem_destroy(dev);
-
- drm_put_minor(&dev->primary);
- if (drm_put_dev(dev))
- DRM_ERROR("Cannot unload module\n");
-}
-
void drm_exit(struct drm_driver *driver)
{
struct drm_device *dev, *tmp;
DRM_DEBUG("\n");
- list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item)
- drm_cleanup(dev);
+ if (driver->driver_features & DRIVER_MODESET) {
+ pci_unregister_driver(&driver->pci_driver);
+ } else {
+ list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item)
+ drm_put_dev(dev);
+ }
DRM_INFO("Module unloaded\n");
}
@@ -382,6 +337,13 @@ static int __init drm_core_init(void)
goto err_p3;
}
+ drm_debugfs_root = debugfs_create_dir("dri", NULL);
+ if (!drm_debugfs_root) {
+ DRM_ERROR("Cannot create /debugfs/dri\n");
+ ret = -1;
+ goto err_p3;
+ }
+
drm_mem_init();
DRM_INFO("Initialized %s %d.%d.%d %s\n",
@@ -400,6 +362,7 @@ err_p1:
static void __exit drm_core_exit(void)
{
remove_proc_entry("dri", NULL);
+ debugfs_remove(drm_debugfs_root);
drm_sysfs_destroy();
unregister_chrdev(DRM_MAJOR, "drm");
@@ -458,6 +421,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
drm_ioctl_t *func;
unsigned int nr = DRM_IOCTL_NR(cmd);
int retcode = -EINVAL;
+ char stack_kdata[128];
char *kdata = NULL;
atomic_inc(&dev->ioctl_count);
@@ -496,10 +460,14 @@ int drm_ioctl(struct inode *inode, struct file *filp,
retcode = -EACCES;
} else {
if (cmd & (IOC_IN | IOC_OUT)) {
- kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
- if (!kdata) {
- retcode = -ENOMEM;
- goto err_i1;
+ if (_IOC_SIZE(cmd) <= sizeof(stack_kdata)) {
+ kdata = stack_kdata;
+ } else {
+ kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
+ if (!kdata) {
+ retcode = -ENOMEM;
+ goto err_i1;
+ }
}
}
@@ -520,7 +488,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
}
err_i1:
- if (kdata)
+ if (kdata != stack_kdata)
kfree(kdata);
atomic_dec(&dev->ioctl_count);
if (retcode)
@@ -530,7 +498,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
EXPORT_SYMBOL(drm_ioctl);
-drm_local_map_t *drm_getsarea(struct drm_device *dev)
+struct drm_local_map *drm_getsarea(struct drm_device *dev)
{
struct drm_map_list *entry;
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a839a28d8ee6..ca9c61656714 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -125,10 +125,8 @@ static bool edid_is_valid(struct edid *edid)
DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
goto bad;
}
- if (edid->revision > 3) {
- DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision);
- goto bad;
- }
+ if (edid->revision > 4)
+ DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
for (i = 0; i < EDID_LENGTH; i++)
csum += raw_edid[i];
@@ -162,7 +160,7 @@ static bool edid_vendor(struct edid *edid, char *vendor)
edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@';
edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) |
((edid->mfg_id[1] & 0xe0) >> 5)) + '@';
- edid_vendor[2] = (edid->mfg_id[2] & 0x1f) + '@';
+ edid_vendor[2] = (edid->mfg_id[1] & 0x1f) + '@';
return !strncmp(edid_vendor, vendor, 3);
}
@@ -550,11 +548,20 @@ static int add_detailed_info(struct drm_connector *connector,
}
#define DDC_ADDR 0x50
-
-unsigned char *drm_do_probe_ddc_edid(struct i2c_adapter *adapter)
+/**
+ * Get EDID information via I2C.
+ *
+ * \param adapter : i2c device adaptor
+ * \param buf : EDID data buffer to be filled
+ * \param len : EDID data buffer length
+ * \return 0 on success or -1 on failure.
+ *
+ * Try to fetch EDID information by calling i2c driver function.
+ */
+int drm_do_probe_ddc_edid(struct i2c_adapter *adapter,
+ unsigned char *buf, int len)
{
unsigned char start = 0x0;
- unsigned char *buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
struct i2c_msg msgs[] = {
{
.addr = DDC_ADDR,
@@ -564,31 +571,36 @@ unsigned char *drm_do_probe_ddc_edid(struct i2c_adapter *adapter)
}, {
.addr = DDC_ADDR,
.flags = I2C_M_RD,
- .len = EDID_LENGTH,
+ .len = len,
.buf = buf,
}
};
- if (!buf) {
- dev_warn(&adapter->dev, "unable to allocate memory for EDID "
- "block.\n");
- return NULL;
- }
-
if (i2c_transfer(adapter, msgs, 2) == 2)
- return buf;
+ return 0;
dev_info(&adapter->dev, "unable to read EDID block.\n");
- kfree(buf);
- return NULL;
+ return -1;
}
EXPORT_SYMBOL(drm_do_probe_ddc_edid);
-static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
+/**
+ * Get EDID information.
+ *
+ * \param adapter : i2c device adaptor.
+ * \param buf : EDID data buffer to be filled
+ * \param len : EDID data buffer length
+ * \return 0 on success or -1 on failure.
+ *
+ * Initialize DDC, then fetch EDID information
+ * by calling drm_do_probe_ddc_edid function.
+ */
+static int drm_ddc_read(struct i2c_adapter *adapter,
+ unsigned char *buf, int len)
{
struct i2c_algo_bit_data *algo_data = adapter->algo_data;
- unsigned char *edid = NULL;
int i, j;
+ int ret = -1;
algo_data->setscl(algo_data->data, 1);
@@ -616,7 +628,7 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
msleep(15);
/* Do the real work */
- edid = drm_do_probe_ddc_edid(adapter);
+ ret = drm_do_probe_ddc_edid(adapter, buf, len);
algo_data->setsda(algo_data->data, 0);
algo_data->setscl(algo_data->data, 0);
msleep(15);
@@ -632,7 +644,7 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
msleep(15);
algo_data->setscl(algo_data->data, 0);
algo_data->setsda(algo_data->data, 0);
- if (edid)
+ if (ret == 0)
break;
}
/* Release the DDC lines when done or the Apple Cinema HD display
@@ -641,9 +653,31 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
algo_data->setsda(algo_data->data, 1);
algo_data->setscl(algo_data->data, 1);
- return edid;
+ return ret;
}
+static int drm_ddc_read_edid(struct drm_connector *connector,
+ struct i2c_adapter *adapter,
+ char *buf, int len)
+{
+ int ret;
+
+ ret = drm_ddc_read(adapter, buf, len);
+ if (ret != 0) {
+ dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
+ drm_get_connector_name(connector));
+ goto end;
+ }
+ if (!edid_is_valid((struct edid *)buf)) {
+ dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
+ drm_get_connector_name(connector));
+ ret = -1;
+ }
+end:
+ return ret;
+}
+
+#define MAX_EDID_EXT_NUM 4
/**
* drm_get_edid - get EDID data, if available
* @connector: connector we're probing
@@ -656,27 +690,118 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter)
{
+ int ret;
struct edid *edid;
- edid = (struct edid *)drm_ddc_read(adapter);
- if (!edid) {
- dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
- drm_get_connector_name(connector));
- return NULL;
+ edid = kmalloc(EDID_LENGTH * (MAX_EDID_EXT_NUM + 1),
+ GFP_KERNEL);
+ if (edid == NULL) {
+ dev_warn(&connector->dev->pdev->dev,
+ "Failed to allocate EDID\n");
+ goto end;
}
- if (!edid_is_valid(edid)) {
- dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
- drm_get_connector_name(connector));
- kfree(edid);
- return NULL;
+
+ /* Read first EDID block */
+ ret = drm_ddc_read_edid(connector, adapter,
+ (unsigned char *)edid, EDID_LENGTH);
+ if (ret != 0)
+ goto clean_up;
+
+ /* There are EDID extensions to be read */
+ if (edid->extensions != 0) {
+ int edid_ext_num = edid->extensions;
+
+ if (edid_ext_num > MAX_EDID_EXT_NUM) {
+ dev_warn(&connector->dev->pdev->dev,
+ "The number of extension(%d) is "
+ "over max (%d), actually read number (%d)\n",
+ edid_ext_num, MAX_EDID_EXT_NUM,
+ MAX_EDID_EXT_NUM);
+ /* Reset EDID extension number to be read */
+ edid_ext_num = MAX_EDID_EXT_NUM;
+ }
+ /* Read EDID including extensions too */
+ ret = drm_ddc_read_edid(connector, adapter, (char *)edid,
+ EDID_LENGTH * (edid_ext_num + 1));
+ if (ret != 0)
+ goto clean_up;
+
}
connector->display_info.raw_edid = (char *)edid;
+ goto end;
+clean_up:
+ kfree(edid);
+ edid = NULL;
+end:
return edid;
+
}
EXPORT_SYMBOL(drm_get_edid);
+#define HDMI_IDENTIFIER 0x000C03
+#define VENDOR_BLOCK 0x03
+/**
+ * drm_detect_hdmi_monitor - detect whether monitor is hdmi.
+ * @edid: monitor EDID information
+ *
+ * Parse the CEA extension according to CEA-861-B.
+ * Return true if HDMI, false if not or unknown.
+ */
+bool drm_detect_hdmi_monitor(struct edid *edid)
+{
+ char *edid_ext = NULL;
+ int i, hdmi_id, edid_ext_num;
+ int start_offset, end_offset;
+ bool is_hdmi = false;
+
+ /* No EDID or EDID extensions */
+ if (edid == NULL || edid->extensions == 0)
+ goto end;
+
+ /* Chose real EDID extension number */
+ edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ?
+ MAX_EDID_EXT_NUM : edid->extensions;
+
+ /* Find CEA extension */
+ for (i = 0; i < edid_ext_num; i++) {
+ edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
+ /* This block is CEA extension */
+ if (edid_ext[0] == 0x02)
+ break;
+ }
+
+ if (i == edid_ext_num)
+ goto end;
+
+ /* Data block offset in CEA extension block */
+ start_offset = 4;
+ end_offset = edid_ext[2];
+
+ /*
+ * Because HDMI identifier is in Vendor Specific Block,
+ * search it from all data blocks of CEA extension.
+ */
+ for (i = start_offset; i < end_offset;
+ /* Increased by data block len */
+ i += ((edid_ext[i] & 0x1f) + 1)) {
+ /* Find vendor specific block */
+ if ((edid_ext[i] >> 5) == VENDOR_BLOCK) {
+ hdmi_id = edid_ext[i + 1] | (edid_ext[i + 2] << 8) |
+ edid_ext[i + 3] << 16;
+ /* Find HDMI identifier */
+ if (hdmi_id == HDMI_IDENTIFIER)
+ is_hdmi = true;
+ break;
+ }
+ }
+
+end:
+ return is_hdmi;
+}
+EXPORT_SYMBOL(drm_detect_hdmi_monitor);
+
/**
* drm_add_edid_modes - add modes from EDID data, if available
* @connector: connector we're probing
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index f52663ebe016..09a3571c9908 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -274,6 +274,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
/* create a new master */
priv->minor->master = drm_master_create(priv->minor);
if (!priv->minor->master) {
+ mutex_unlock(&dev->struct_mutex);
ret = -ENOMEM;
goto out_free;
}
@@ -337,14 +338,10 @@ int drm_fasync(int fd, struct file *filp, int on)
{
struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->minor->dev;
- int retcode;
DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
(long)old_encode_dev(priv->minor->device));
- retcode = fasync_helper(fd, filp, on, &dev->buf_async);
- if (retcode < 0)
- return retcode;
- return 0;
+ return fasync_helper(fd, filp, on, &dev->buf_async);
}
EXPORT_SYMBOL(drm_fasync);
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 88d3368ffddd..4984aa89cf3d 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -502,10 +502,9 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->minor->dev;
struct drm_gem_mm *mm = dev->mm_private;
- struct drm_map *map = NULL;
+ struct drm_local_map *map = NULL;
struct drm_gem_object *obj;
struct drm_hash_item *hash;
- unsigned long prot;
int ret = 0;
mutex_lock(&dev->struct_mutex);
@@ -538,11 +537,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_ops = obj->dev->driver->gem_vm_ops;
vma->vm_private_data = map->handle;
/* FIXME: use pgprot_writecombine when available */
- prot = pgprot_val(vma->vm_page_prot);
-#ifdef CONFIG_X86
- prot |= _PAGE_CACHE_WC;
-#endif
- vma->vm_page_prot = __pgprot(prot);
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
/* Take a ref for this mapping of the object, so that the fault
* handler can dereference the mmap offset's pointer to the object.
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
new file mode 100644
index 000000000000..f0f6c6b93f3a
--- /dev/null
+++ b/drivers/gpu/drm/drm_info.c
@@ -0,0 +1,328 @@
+/**
+ * \file drm_info.c
+ * DRM info file implementations
+ *
+ * \author Ben Gamari <bgamari@gmail.com>
+ */
+
+/*
+ * Created: Sun Dec 21 13:09:50 2008 by bgamari@gmail.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * Copyright 2008 Ben Gamari <bgamari@gmail.com>
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/seq_file.h>
+#include "drmP.h"
+
+/**
+ * Called when "/proc/dri/.../name" is read.
+ *
+ * Prints the device name together with the bus id if available.
+ */
+int drm_name_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_minor *minor = node->minor;
+ struct drm_device *dev = minor->dev;
+ struct drm_master *master = minor->master;
+
+ if (!master)
+ return 0;
+
+ if (master->unique) {
+ seq_printf(m, "%s %s %s\n",
+ dev->driver->pci_driver.name,
+ pci_name(dev->pdev), master->unique);
+ } else {
+ seq_printf(m, "%s %s\n", dev->driver->pci_driver.name,
+ pci_name(dev->pdev));
+ }
+
+ return 0;
+}
+
+/**
+ * Called when "/proc/dri/.../vm" is read.
+ *
+ * Prints information about all mappings in drm_device::maplist.
+ */
+int drm_vm_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_local_map *map;
+ struct drm_map_list *r_list;
+
+ /* Hardcoded from _DRM_FRAME_BUFFER,
+ _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
+ _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
+ const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
+ const char *type;
+ int i;
+
+ mutex_lock(&dev->struct_mutex);
+ seq_printf(m, "slot offset size type flags address mtrr\n\n");
+ i = 0;
+ list_for_each_entry(r_list, &dev->maplist, head) {
+ map = r_list->map;
+ if (!map)
+ continue;
+ if (map->type < 0 || map->type > 5)
+ type = "??";
+ else
+ type = types[map->type];
+
+ seq_printf(m, "%4d 0x%016llx 0x%08lx %4.4s 0x%02x 0x%08lx ",
+ i,
+ (unsigned long long)map->offset,
+ map->size, type, map->flags,
+ (unsigned long) r_list->user_token);
+ if (map->mtrr < 0)
+ seq_printf(m, "none\n");
+ else
+ seq_printf(m, "%4d\n", map->mtrr);
+ i++;
+ }
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+}
+
+/**
+ * Called when "/proc/dri/.../queues" is read.
+ */
+int drm_queues_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ int i;
+ struct drm_queue *q;
+
+ mutex_lock(&dev->struct_mutex);
+ seq_printf(m, " ctx/flags use fin"
+ " blk/rw/rwf wait flushed queued"
+ " locks\n\n");
+ for (i = 0; i < dev->queue_count; i++) {
+ q = dev->queuelist[i];
+ atomic_inc(&q->use_count);
+ seq_printf(m, "%5d/0x%03x %5d %5d"
+ " %5d/%c%c/%c%c%c %5Zd\n",
+ i,
+ q->flags,
+ atomic_read(&q->use_count),
+ atomic_read(&q->finalization),
+ atomic_read(&q->block_count),
+ atomic_read(&q->block_read) ? 'r' : '-',
+ atomic_read(&q->block_write) ? 'w' : '-',
+ waitqueue_active(&q->read_queue) ? 'r' : '-',
+ waitqueue_active(&q->write_queue) ? 'w' : '-',
+ waitqueue_active(&q->flush_queue) ? 'f' : '-',
+ DRM_BUFCOUNT(&q->waitlist));
+ atomic_dec(&q->use_count);
+ }
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+}
+
+/**
+ * Called when "/proc/dri/.../bufs" is read.
+ */
+int drm_bufs_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_device_dma *dma;
+ int i, seg_pages;
+
+ mutex_lock(&dev->struct_mutex);
+ dma = dev->dma;
+ if (!dma) {
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+ }
+
+ seq_printf(m, " o size count free segs pages kB\n\n");
+ for (i = 0; i <= DRM_MAX_ORDER; i++) {
+ if (dma->bufs[i].buf_count) {
+ seg_pages = dma->bufs[i].seg_count * (1 << dma->bufs[i].page_order);
+ seq_printf(m, "%2d %8d %5d %5d %5d %5d %5ld\n",
+ i,
+ dma->bufs[i].buf_size,
+ dma->bufs[i].buf_count,
+ atomic_read(&dma->bufs[i].freelist.count),
+ dma->bufs[i].seg_count,
+ seg_pages,
+ seg_pages * PAGE_SIZE / 1024);
+ }
+ }
+ seq_printf(m, "\n");
+ for (i = 0; i < dma->buf_count; i++) {
+ if (i && !(i % 32))
+ seq_printf(m, "\n");
+ seq_printf(m, " %d", dma->buflist[i]->list);
+ }
+ seq_printf(m, "\n");
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+}
+
+/**
+ * Called when "/proc/dri/.../vblank" is read.
+ */
+int drm_vblank_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ int crtc;
+
+ mutex_lock(&dev->struct_mutex);
+ for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
+ seq_printf(m, "CRTC %d enable: %d\n",
+ crtc, atomic_read(&dev->vblank_refcount[crtc]));
+ seq_printf(m, "CRTC %d counter: %d\n",
+ crtc, drm_vblank_count(dev, crtc));
+ seq_printf(m, "CRTC %d last wait: %d\n",
+ crtc, dev->last_vblank_wait[crtc]);
+ seq_printf(m, "CRTC %d in modeset: %d\n",
+ crtc, dev->vblank_inmodeset[crtc]);
+ }
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+}
+
+/**
+ * Called when "/proc/dri/.../clients" is read.
+ *
+ */
+int drm_clients_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_file *priv;
+
+ mutex_lock(&dev->struct_mutex);
+ seq_printf(m, "a dev pid uid magic ioctls\n\n");
+ list_for_each_entry(priv, &dev->filelist, lhead) {
+ seq_printf(m, "%c %3d %5d %5d %10u %10lu\n",
+ priv->authenticated ? 'y' : 'n',
+ priv->minor->index,
+ priv->pid,
+ priv->uid, priv->magic, priv->ioctl_count);
+ }
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+}
+
+
+int drm_gem_one_name_info(int id, void *ptr, void *data)
+{
+ struct drm_gem_object *obj = ptr;
+ struct seq_file *m = data;
+
+ seq_printf(m, "name %d size %zd\n", obj->name, obj->size);
+
+ seq_printf(m, "%6d %8zd %7d %8d\n",
+ obj->name, obj->size,
+ atomic_read(&obj->handlecount.refcount),
+ atomic_read(&obj->refcount.refcount));
+ return 0;
+}
+
+int drm_gem_name_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+
+ seq_printf(m, " name size handles refcount\n");
+ idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, m);
+ return 0;
+}
+
+int drm_gem_object_info(struct seq_file *m, void* data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+
+ seq_printf(m, "%d objects\n", atomic_read(&dev->object_count));
+ seq_printf(m, "%d object bytes\n", atomic_read(&dev->object_memory));
+ seq_printf(m, "%d pinned\n", atomic_read(&dev->pin_count));
+ seq_printf(m, "%d pin bytes\n", atomic_read(&dev->pin_memory));
+ seq_printf(m, "%d gtt bytes\n", atomic_read(&dev->gtt_memory));
+ seq_printf(m, "%d gtt total\n", dev->gtt_total);
+ return 0;
+}
+
+#if DRM_DEBUG_CODE
+
+int drm_vma_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ struct drm_vma_entry *pt;
+ struct vm_area_struct *vma;
+#if defined(__i386__)
+ unsigned int pgprot;
+#endif
+
+ mutex_lock(&dev->struct_mutex);
+ seq_printf(m, "vma use count: %d, high_memory = %p, 0x%08llx\n",
+ atomic_read(&dev->vma_count),
+ high_memory, (u64)virt_to_phys(high_memory));
+
+ list_for_each_entry(pt, &dev->vmalist, head) {
+ vma = pt->vma;
+ if (!vma)
+ continue;
+ seq_printf(m,
+ "\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000",
+ pt->pid, vma->vm_start, vma->vm_end,
+ vma->vm_flags & VM_READ ? 'r' : '-',
+ vma->vm_flags & VM_WRITE ? 'w' : '-',
+ vma->vm_flags & VM_EXEC ? 'x' : '-',
+ vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
+ vma->vm_flags & VM_LOCKED ? 'l' : '-',
+ vma->vm_flags & VM_IO ? 'i' : '-',
+ vma->vm_pgoff);
+
+#if defined(__i386__)
+ pgprot = pgprot_val(vma->vm_page_prot);
+ seq_printf(m, " %c%c%c%c%c%c%c%c%c",
+ pgprot & _PAGE_PRESENT ? 'p' : '-',
+ pgprot & _PAGE_RW ? 'w' : 'r',
+ pgprot & _PAGE_USER ? 'u' : 's',
+ pgprot & _PAGE_PWT ? 't' : 'b',
+ pgprot & _PAGE_PCD ? 'u' : 'c',
+ pgprot & _PAGE_ACCESSED ? 'a' : '-',
+ pgprot & _PAGE_DIRTY ? 'd' : '-',
+ pgprot & _PAGE_PSE ? 'm' : 'k',
+ pgprot & _PAGE_GLOBAL ? 'g' : 'l');
+#endif
+ seq_printf(m, "\n");
+ }
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+}
+
+#endif
+
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c
index 920b72fbc958..282d9fdf9f4e 100644
--- a/drivers/gpu/drm/drm_ioc32.c
+++ b/drivers/gpu/drm/drm_ioc32.c
@@ -954,6 +954,7 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd,
DRM_IOCTL_SG_FREE, (unsigned long)request);
}
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
typedef struct drm_update_draw32 {
drm_drawable_t handle;
unsigned int type;
@@ -984,6 +985,7 @@ static int compat_drm_update_draw(struct file *file, unsigned int cmd,
DRM_IOCTL_UPDATE_DRAW, (unsigned long)request);
return err;
}
+#endif
struct drm_wait_vblank_request32 {
enum drm_vblank_seq_type type;
@@ -1066,7 +1068,9 @@ drm_ioctl_compat_t *drm_compat_ioctls[] = {
#endif
[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc,
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free,
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
[DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw,
+#endif
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank,
};
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
index bcc869bc4092..0c707f533eab 100644
--- a/drivers/gpu/drm/drm_memory.c
+++ b/drivers/gpu/drm/drm_memory.c
@@ -159,7 +159,7 @@ static inline void *agp_remap(unsigned long offset, unsigned long size,
#endif /* debug_memory */
-void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
+void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev)
{
if (drm_core_has_AGP(dev) &&
dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
@@ -169,7 +169,7 @@ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
}
EXPORT_SYMBOL(drm_core_ioremap);
-void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev)
+void drm_core_ioremap_wc(struct drm_local_map *map, struct drm_device *dev)
{
if (drm_core_has_AGP(dev) &&
dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
@@ -179,7 +179,7 @@ void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev)
}
EXPORT_SYMBOL(drm_core_ioremap_wc);
-void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
+void drm_core_ioremapfree(struct drm_local_map *map, struct drm_device *dev)
{
if (!map->handle || !map->size)
return;
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
index b756f043a5f4..bae5391165ac 100644
--- a/drivers/gpu/drm/drm_proc.c
+++ b/drivers/gpu/drm/drm_proc.c
@@ -37,697 +37,195 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
+#include <linux/seq_file.h>
#include "drmP.h"
-static int drm_name_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-static int drm_vm_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-static int drm_clients_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-static int drm_queues_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-static int drm_bufs_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-static int drm_vblank_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-static int drm_gem_name_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-static int drm_gem_object_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-#if DRM_DEBUG_CODE
-static int drm_vma_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data);
-#endif
+/***************************************************
+ * Initialization, etc.
+ **************************************************/
/**
* Proc file list.
*/
-static struct drm_proc_list {
- const char *name; /**< file name */
- int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/
- u32 driver_features; /**< Required driver features for this entry */
-} drm_proc_list[] = {
+static struct drm_info_list drm_proc_list[] = {
{"name", drm_name_info, 0},
- {"mem", drm_mem_info, 0},
{"vm", drm_vm_info, 0},
{"clients", drm_clients_info, 0},
{"queues", drm_queues_info, 0},
{"bufs", drm_bufs_info, 0},
- {"vblank", drm_vblank_info, 0},
{"gem_names", drm_gem_name_info, DRIVER_GEM},
{"gem_objects", drm_gem_object_info, DRIVER_GEM},
#if DRM_DEBUG_CODE
- {"vma", drm_vma_info},
+ {"vma", drm_vma_info, 0},
#endif
};
-
#define DRM_PROC_ENTRIES ARRAY_SIZE(drm_proc_list)
+static int drm_proc_open(struct inode *inode, struct file *file)
+{
+ struct drm_info_node* node = PDE(inode)->data;
+
+ return single_open(file, node->info_ent->show, node);
+}
+
+static const struct file_operations drm_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+
/**
- * Initialize the DRI proc filesystem for a device.
+ * Initialize a given set of proc files for a device
*
- * \param dev DRM device.
- * \param minor device minor number.
+ * \param files The array of files to create
+ * \param count The number of files given
* \param root DRI proc dir entry.
- * \param dev_root resulting DRI device proc dir entry.
- * \return root entry pointer on success, or NULL on failure.
+ * \param minor device minor number
+ * \return Zero on success, non-zero on failure
*
- * Create the DRI proc root entry "/proc/dri", the device proc root entry
- * "/proc/dri/%minor%/", and each entry in proc_list as
- * "/proc/dri/%minor%/%name%".
+ * Create a given set of proc files represented by an array of
+ * gdm_proc_lists in the given root directory.
*/
-int drm_proc_init(struct drm_minor *minor, int minor_id,
- struct proc_dir_entry *root)
+int drm_proc_create_files(struct drm_info_list *files, int count,
+ struct proc_dir_entry *root, struct drm_minor *minor)
{
struct drm_device *dev = minor->dev;
struct proc_dir_entry *ent;
- int i, j, ret;
+ struct drm_info_node *tmp;
char name[64];
+ int i, ret;
- sprintf(name, "%d", minor_id);
- minor->dev_root = proc_mkdir(name, root);
- if (!minor->dev_root) {
- DRM_ERROR("Cannot create /proc/dri/%s\n", name);
- return -1;
- }
-
- for (i = 0; i < DRM_PROC_ENTRIES; i++) {
- u32 features = drm_proc_list[i].driver_features;
+ for (i = 0; i < count; i++) {
+ u32 features = files[i].driver_features;
if (features != 0 &&
(dev->driver->driver_features & features) != features)
continue;
- ent = create_proc_entry(drm_proc_list[i].name,
- S_IFREG | S_IRUGO, minor->dev_root);
+ tmp = drm_alloc(sizeof(struct drm_info_node), _DRM_DRIVER);
+ ent = create_proc_entry(files[i].name, S_IFREG | S_IRUGO, root);
if (!ent) {
DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
- name, drm_proc_list[i].name);
+ name, files[i].name);
+ drm_free(tmp, sizeof(struct drm_info_node),
+ _DRM_DRIVER);
ret = -1;
goto fail;
}
- ent->read_proc = drm_proc_list[i].f;
- ent->data = minor;
- }
- if (dev->driver->proc_init) {
- ret = dev->driver->proc_init(minor);
- if (ret) {
- DRM_ERROR("DRM: Driver failed to initialize "
- "/proc/dri.\n");
- goto fail;
- }
+ ent->proc_fops = &drm_proc_fops;
+ ent->data = tmp;
+ tmp->minor = minor;
+ tmp->info_ent = &files[i];
+ list_add(&(tmp->list), &(minor->proc_nodes.list));
}
-
return 0;
- fail:
- for (j = 0; j < i; j++)
- remove_proc_entry(drm_proc_list[i].name,
- minor->dev_root);
- remove_proc_entry(name, root);
- minor->dev_root = NULL;
+fail:
+ for (i = 0; i < count; i++)
+ remove_proc_entry(drm_proc_list[i].name, minor->proc_root);
return ret;
}
/**
- * Cleanup the proc filesystem resources.
+ * Initialize the DRI proc filesystem for a device
*
- * \param minor device minor number.
+ * \param dev DRM device
+ * \param minor device minor number
* \param root DRI proc dir entry.
- * \param dev_root DRI device proc dir entry.
- * \return always zero.
+ * \param dev_root resulting DRI device proc dir entry.
+ * \return root entry pointer on success, or NULL on failure.
*
- * Remove all proc entries created by proc_init().
+ * Create the DRI proc root entry "/proc/dri", the device proc root entry
+ * "/proc/dri/%minor%/", and each entry in proc_list as
+ * "/proc/dri/%minor%/%name%".
*/
-int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
+int drm_proc_init(struct drm_minor *minor, int minor_id,
+ struct proc_dir_entry *root)
{
struct drm_device *dev = minor->dev;
- int i;
char name[64];
+ int ret;
- if (!root || !minor->dev_root)
- return 0;
-
- if (dev->driver->proc_cleanup)
- dev->driver->proc_cleanup(minor);
-
- for (i = 0; i < DRM_PROC_ENTRIES; i++)
- remove_proc_entry(drm_proc_list[i].name, minor->dev_root);
- sprintf(name, "%d", minor->index);
- remove_proc_entry(name, root);
-
- return 0;
-}
-
-/**
- * Called when "/proc/dri/.../name" is read.
- *
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- *
- * Prints the device name together with the bus id if available.
- */
-static int drm_name_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_master *master = minor->master;
- struct drm_device *dev = minor->dev;
- int len = 0;
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
+ INIT_LIST_HEAD(&minor->proc_nodes.list);
+ sprintf(name, "%d", minor_id);
+ minor->proc_root = proc_mkdir(name, root);
+ if (!minor->proc_root) {
+ DRM_ERROR("Cannot create /proc/dri/%s\n", name);
+ return -1;
}
- if (!master)
- return 0;
-
- *start = &buf[offset];
- *eof = 0;
-
- if (master->unique) {
- DRM_PROC_PRINT("%s %s %s\n",
- dev->driver->pci_driver.name,
- pci_name(dev->pdev), master->unique);
- } else {
- DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name,
- pci_name(dev->pdev));
+ ret = drm_proc_create_files(drm_proc_list, DRM_PROC_ENTRIES,
+ minor->proc_root, minor);
+ if (ret) {
+ remove_proc_entry(name, root);
+ minor->proc_root = NULL;
+ DRM_ERROR("Failed to create core drm proc files\n");
+ return ret;
}
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-/**
- * Called when "/proc/dri/.../vm" is read.
- *
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- *
- * Prints information about all mappings in drm_device::maplist.
- */
-static int drm__vm_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- int len = 0;
- struct drm_map *map;
- struct drm_map_list *r_list;
-
- /* Hardcoded from _DRM_FRAME_BUFFER,
- _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
- _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
- const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
- const char *type;
- int i;
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
- }
-
- *start = &buf[offset];
- *eof = 0;
-
- DRM_PROC_PRINT("slot offset size type flags "
- "address mtrr\n\n");
- i = 0;
- list_for_each_entry(r_list, &dev->maplist, head) {
- map = r_list->map;
- if (!map)
- continue;
- if (map->type < 0 || map->type > 5)
- type = "??";
- else
- type = types[map->type];
- DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
- i,
- map->offset,
- map->size, type, map->flags,
- (unsigned long) r_list->user_token);
- if (map->mtrr < 0) {
- DRM_PROC_PRINT("none\n");
- } else {
- DRM_PROC_PRINT("%4d\n", map->mtrr);
+ if (dev->driver->proc_init) {
+ ret = dev->driver->proc_init(minor);
+ if (ret) {
+ DRM_ERROR("DRM: Driver failed to initialize "
+ "/proc/dri.\n");
+ return ret;
}
- i++;
- }
-
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-/**
- * Simply calls _vm_info() while holding the drm_device::struct_mutex lock.
- */
-static int drm_vm_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- ret = drm__vm_info(buf, start, offset, request, eof, data);
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-
-/**
- * Called when "/proc/dri/.../queues" is read.
- *
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- */
-static int drm__queues_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- int len = 0;
- int i;
- struct drm_queue *q;
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
}
-
- *start = &buf[offset];
- *eof = 0;
-
- DRM_PROC_PRINT(" ctx/flags use fin"
- " blk/rw/rwf wait flushed queued"
- " locks\n\n");
- for (i = 0; i < dev->queue_count; i++) {
- q = dev->queuelist[i];
- atomic_inc(&q->use_count);
- DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
- "%5d/0x%03x %5d %5d"
- " %5d/%c%c/%c%c%c %5Zd\n",
- i,
- q->flags,
- atomic_read(&q->use_count),
- atomic_read(&q->finalization),
- atomic_read(&q->block_count),
- atomic_read(&q->block_read) ? 'r' : '-',
- atomic_read(&q->block_write) ? 'w' : '-',
- waitqueue_active(&q->read_queue) ? 'r' : '-',
- waitqueue_active(&q->
- write_queue) ? 'w' : '-',
- waitqueue_active(&q->
- flush_queue) ? 'f' : '-',
- DRM_BUFCOUNT(&q->waitlist));
- atomic_dec(&q->use_count);
- }
-
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-/**
- * Simply calls _queues_info() while holding the drm_device::struct_mutex lock.
- */
-static int drm_queues_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- ret = drm__queues_info(buf, start, offset, request, eof, data);
- mutex_unlock(&dev->struct_mutex);
- return ret;
+ return 0;
}
-/**
- * Called when "/proc/dri/.../bufs" is read.
- *
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- */
-static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
+int drm_proc_remove_files(struct drm_info_list *files, int count,
+ struct drm_minor *minor)
{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- int len = 0;
- struct drm_device_dma *dma = dev->dma;
+ struct list_head *pos, *q;
+ struct drm_info_node *tmp;
int i;
- if (!dma || offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
- }
-
- *start = &buf[offset];
- *eof = 0;
-
- DRM_PROC_PRINT(" o size count free segs pages kB\n\n");
- for (i = 0; i <= DRM_MAX_ORDER; i++) {
- if (dma->bufs[i].buf_count)
- DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
- i,
- dma->bufs[i].buf_size,
- dma->bufs[i].buf_count,
- atomic_read(&dma->bufs[i]
- .freelist.count),
- dma->bufs[i].seg_count,
- dma->bufs[i].seg_count
- * (1 << dma->bufs[i].page_order),
- (dma->bufs[i].seg_count
- * (1 << dma->bufs[i].page_order))
- * PAGE_SIZE / 1024);
- }
- DRM_PROC_PRINT("\n");
- for (i = 0; i < dma->buf_count; i++) {
- if (i && !(i % 32))
- DRM_PROC_PRINT("\n");
- DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
+ for (i = 0; i < count; i++) {
+ list_for_each_safe(pos, q, &minor->proc_nodes.list) {
+ tmp = list_entry(pos, struct drm_info_node, list);
+ if (tmp->info_ent == &files[i]) {
+ remove_proc_entry(files[i].name,
+ minor->proc_root);
+ list_del(pos);
+ drm_free(tmp, sizeof(struct drm_info_node),
+ _DRM_DRIVER);
+ }
+ }
}
- DRM_PROC_PRINT("\n");
-
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-/**
- * Simply calls _bufs_info() while holding the drm_device::struct_mutex lock.
- */
-static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- ret = drm__bufs_info(buf, start, offset, request, eof, data);
- mutex_unlock(&dev->struct_mutex);
- return ret;
+ return 0;
}
/**
- * Called when "/proc/dri/.../vblank" is read.
+ * Cleanup the proc filesystem resources.
*
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
- */
-static int drm__vblank_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- int len = 0;
- int crtc;
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
- }
-
- *start = &buf[offset];
- *eof = 0;
-
- for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
- DRM_PROC_PRINT("CRTC %d enable: %d\n",
- crtc, atomic_read(&dev->vblank_refcount[crtc]));
- DRM_PROC_PRINT("CRTC %d counter: %d\n",
- crtc, drm_vblank_count(dev, crtc));
- DRM_PROC_PRINT("CRTC %d last wait: %d\n",
- crtc, dev->last_vblank_wait[crtc]);
- DRM_PROC_PRINT("CRTC %d in modeset: %d\n",
- crtc, dev->vblank_inmodeset[crtc]);
- }
-
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-/**
- * Simply calls _vblank_info() while holding the drm_device::struct_mutex lock.
- */
-static int drm_vblank_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- ret = drm__vblank_info(buf, start, offset, request, eof, data);
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-
-/**
- * Called when "/proc/dri/.../clients" is read.
+ * \param minor device minor number.
+ * \param root DRI proc dir entry.
+ * \param dev_root DRI device proc dir entry.
+ * \return always zero.
*
- * \param buf output buffer.
- * \param start start of output data.
- * \param offset requested start offset.
- * \param request requested number of bytes.
- * \param eof whether there is no more data to return.
- * \param data private data.
- * \return number of written bytes.
+ * Remove all proc entries created by proc_init().
*/
-static int drm__clients_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
+int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
{
- struct drm_minor *minor = (struct drm_minor *) data;
struct drm_device *dev = minor->dev;
- int len = 0;
- struct drm_file *priv;
+ char name[64];
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
+ if (!root || !minor->proc_root)
return 0;
- }
-
- *start = &buf[offset];
- *eof = 0;
-
- DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n");
- list_for_each_entry(priv, &dev->filelist, lhead) {
- DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
- priv->authenticated ? 'y' : 'n',
- priv->minor->index,
- priv->pid,
- priv->uid, priv->magic, priv->ioctl_count);
- }
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-/**
- * Simply calls _clients_info() while holding the drm_device::struct_mutex lock.
- */
-static int drm_clients_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- ret = drm__clients_info(buf, start, offset, request, eof, data);
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-
-struct drm_gem_name_info_data {
- int len;
- char *buf;
- int eof;
-};
+ if (dev->driver->proc_cleanup)
+ dev->driver->proc_cleanup(minor);
-static int drm_gem_one_name_info(int id, void *ptr, void *data)
-{
- struct drm_gem_object *obj = ptr;
- struct drm_gem_name_info_data *nid = data;
+ drm_proc_remove_files(drm_proc_list, DRM_PROC_ENTRIES, minor);
- DRM_INFO("name %d size %zd\n", obj->name, obj->size);
- if (nid->eof)
- return 0;
+ sprintf(name, "%d", minor->index);
+ remove_proc_entry(name, root);
- nid->len += sprintf(&nid->buf[nid->len],
- "%6d %8zd %7d %8d\n",
- obj->name, obj->size,
- atomic_read(&obj->handlecount.refcount),
- atomic_read(&obj->refcount.refcount));
- if (nid->len > DRM_PROC_LIMIT) {
- nid->eof = 1;
- return 0;
- }
return 0;
}
-static int drm_gem_name_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- struct drm_gem_name_info_data nid;
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
- }
-
- nid.len = sprintf(buf, " name size handles refcount\n");
- nid.buf = buf;
- nid.eof = 0;
- idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid);
-
- *start = &buf[offset];
- *eof = 0;
- if (nid.len > request + offset)
- return request;
- *eof = 1;
- return nid.len - offset;
-}
-
-static int drm_gem_object_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- int len = 0;
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
- }
-
- *start = &buf[offset];
- *eof = 0;
- DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count));
- DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory));
- DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count));
- DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory));
- DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory));
- DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total);
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-#if DRM_DEBUG_CODE
-
-static int drm__vma_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- int len = 0;
- struct drm_vma_entry *pt;
- struct vm_area_struct *vma;
-#if defined(__i386__)
- unsigned int pgprot;
-#endif
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
- }
-
- *start = &buf[offset];
- *eof = 0;
-
- DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%llx\n",
- atomic_read(&dev->vma_count),
- high_memory, (u64)virt_to_phys(high_memory));
- list_for_each_entry(pt, &dev->vmalist, head) {
- if (!(vma = pt->vma))
- continue;
- DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000",
- pt->pid,
- vma->vm_start,
- vma->vm_end,
- vma->vm_flags & VM_READ ? 'r' : '-',
- vma->vm_flags & VM_WRITE ? 'w' : '-',
- vma->vm_flags & VM_EXEC ? 'x' : '-',
- vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
- vma->vm_flags & VM_LOCKED ? 'l' : '-',
- vma->vm_flags & VM_IO ? 'i' : '-',
- vma->vm_pgoff);
-
-#if defined(__i386__)
- pgprot = pgprot_val(vma->vm_page_prot);
- DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
- pgprot & _PAGE_PRESENT ? 'p' : '-',
- pgprot & _PAGE_RW ? 'w' : 'r',
- pgprot & _PAGE_USER ? 'u' : 's',
- pgprot & _PAGE_PWT ? 't' : 'b',
- pgprot & _PAGE_PCD ? 'u' : 'c',
- pgprot & _PAGE_ACCESSED ? 'a' : '-',
- pgprot & _PAGE_DIRTY ? 'd' : '-',
- pgprot & _PAGE_PSE ? 'm' : 'k',
- pgprot & _PAGE_GLOBAL ? 'g' : 'l');
-#endif
- DRM_PROC_PRINT("\n");
- }
-
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-static int drm_vma_info(char *buf, char **start, off_t offset, int request,
- int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- ret = drm__vma_info(buf, start, offset, request, eof, data);
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-#endif
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 7c8b15b22bf2..d009661781bc 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -50,6 +50,7 @@ struct idr drm_minors_idr;
struct class *drm_class;
struct proc_dir_entry *drm_proc_root;
+struct dentry *drm_debugfs_root;
static int drm_minor_get_id(struct drm_device *dev, int type)
{
@@ -313,7 +314,15 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t
goto err_mem;
}
} else
- new_minor->dev_root = NULL;
+ new_minor->proc_root = NULL;
+
+#if defined(CONFIG_DEBUG_FS)
+ ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root);
+ if (ret) {
+ DRM_ERROR("DRM: Failed to initialize /debugfs/dri.\n");
+ goto err_g2;
+ }
+#endif
ret = drm_sysfs_device_add(new_minor);
if (ret) {
@@ -372,6 +381,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
}
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ pci_set_drvdata(pdev, dev);
ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
if (ret)
goto err_g2;
@@ -395,9 +405,9 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
list_add_tail(&dev->driver_item, &driver->device_list);
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+ DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel,
- driver->date, dev->primary->index);
+ driver->date, pci_name(pdev), dev->primary->index);
return 0;
@@ -409,29 +419,7 @@ err_g1:
drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
return ret;
}
-
-/**
- * Put a device minor number.
- *
- * \param dev device data structure
- * \return always zero
- *
- * Cleans up the proc resources. If it is the last minor then release the foreign
- * "drm" data, otherwise unregisters the "drm" data, frees the dev list and
- * unregisters the character device.
- */
-int drm_put_dev(struct drm_device * dev)
-{
- DRM_DEBUG("release primary %s\n", dev->driver->pci_driver.name);
-
- if (dev->devname) {
- drm_free(dev->devname, strlen(dev->devname) + 1,
- DRM_MEM_DRIVER);
- dev->devname = NULL;
- }
- drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
- return 0;
-}
+EXPORT_SYMBOL(drm_get_dev);
/**
* Put a secondary minor number.
@@ -451,6 +439,10 @@ int drm_put_minor(struct drm_minor **minor_p)
if (minor->type == DRM_MINOR_LEGACY)
drm_proc_cleanup(minor, drm_proc_root);
+#if defined(CONFIG_DEBUG_FS)
+ drm_debugfs_cleanup(minor);
+#endif
+
drm_sysfs_device_remove(minor);
idr_remove(&drm_minors_idr, minor->index);
@@ -459,3 +451,67 @@ int drm_put_minor(struct drm_minor **minor_p)
*minor_p = NULL;
return 0;
}
+
+/**
+ * Called via drm_exit() at module unload time or when pci device is
+ * unplugged.
+ *
+ * Cleans up all DRM device, calling drm_lastclose().
+ *
+ * \sa drm_init
+ */
+void drm_put_dev(struct drm_device *dev)
+{
+ struct drm_driver *driver = dev->driver;
+ struct drm_map_list *r_list, *list_temp;
+
+ DRM_DEBUG("\n");
+
+ if (!dev) {
+ DRM_ERROR("cleanup called no dev\n");
+ return;
+ }
+
+ drm_vblank_cleanup(dev);
+
+ drm_lastclose(dev);
+
+ if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
+ dev->agp && dev->agp->agp_mtrr >= 0) {
+ int retval;
+ retval = mtrr_del(dev->agp->agp_mtrr,
+ dev->agp->agp_info.aper_base,
+ dev->agp->agp_info.aper_size * 1024 * 1024);
+ DRM_DEBUG("mtrr_del=%d\n", retval);
+ }
+
+ if (dev->driver->unload)
+ dev->driver->unload(dev);
+
+ if (drm_core_has_AGP(dev) && dev->agp) {
+ drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
+ dev->agp = NULL;
+ }
+
+ drm_ht_remove(&dev->map_hash);
+ drm_ctxbitmap_cleanup(dev);
+
+ list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
+ drm_rmmap(dev, r_list->map);
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_put_minor(&dev->control);
+
+ if (driver->driver_features & DRIVER_GEM)
+ drm_gem_destroy(dev);
+
+ drm_put_minor(&dev->primary);
+
+ if (dev->devname) {
+ drm_free(dev->devname, strlen(dev->devname) + 1,
+ DRM_MEM_DRIVER);
+ dev->devname = NULL;
+ }
+ drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
+}
+EXPORT_SYMBOL(drm_put_dev);
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 5aa6780652aa..bc0c6849360c 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -35,7 +35,9 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
struct drm_minor *drm_minor = to_drm_minor(dev);
struct drm_device *drm_dev = drm_minor->dev;
- if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->suspend)
+ if (drm_minor->type == DRM_MINOR_LEGACY &&
+ !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
+ drm_dev->driver->suspend)
return drm_dev->driver->suspend(drm_dev, state);
return 0;
@@ -53,7 +55,9 @@ static int drm_sysfs_resume(struct device *dev)
struct drm_minor *drm_minor = to_drm_minor(dev);
struct drm_device *drm_dev = drm_minor->dev;
- if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->resume)
+ if (drm_minor->type == DRM_MINOR_LEGACY &&
+ !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
+ drm_dev->driver->resume)
return drm_dev->driver->resume(drm_dev);
return 0;
@@ -118,20 +122,6 @@ void drm_sysfs_destroy(void)
class_destroy(drm_class);
}
-static ssize_t show_dri(struct device *device, struct device_attribute *attr,
- char *buf)
-{
- struct drm_minor *drm_minor = to_drm_minor(device);
- struct drm_device *drm_dev = drm_minor->dev;
- if (drm_dev->driver->dri_library_name)
- return drm_dev->driver->dri_library_name(drm_dev, buf);
- return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name);
-}
-
-static struct device_attribute device_attrs[] = {
- __ATTR(dri_library_name, S_IRUGO, show_dri, NULL),
-};
-
/**
* drm_sysfs_device_release - do nothing
* @dev: Linux device
@@ -359,8 +349,8 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
DRM_DEBUG("adding \"%s\" to sysfs\n",
drm_get_connector_name(connector));
- snprintf(connector->kdev.bus_id, BUS_ID_SIZE, "card%d-%s",
- dev->primary->index, drm_get_connector_name(connector));
+ dev_set_name(&connector->kdev, "card%d-%s",
+ dev->primary->index, drm_get_connector_name(connector));
ret = device_register(&connector->kdev);
if (ret) {
@@ -461,6 +451,7 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp);
}
+EXPORT_SYMBOL(drm_sysfs_hotplug_event);
/**
* drm_sysfs_device_add - adds a class device to sysfs for a character driver
@@ -474,7 +465,6 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
int drm_sysfs_device_add(struct drm_minor *minor)
{
int err;
- int i, j;
char *minor_str;
minor->kdev.parent = &minor->dev->pdev->dev;
@@ -496,18 +486,8 @@ int drm_sysfs_device_add(struct drm_minor *minor)
goto err_out;
}
- for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
- err = device_create_file(&minor->kdev, &device_attrs[i]);
- if (err)
- goto err_out_files;
- }
-
return 0;
-err_out_files:
- if (i > 0)
- for (j = 0; j < i; j++)
- device_remove_file(&minor->kdev, &device_attrs[j]);
device_unregister(&minor->kdev);
err_out:
@@ -523,9 +503,5 @@ err_out:
*/
void drm_sysfs_device_remove(struct drm_minor *minor)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
- device_remove_file(&minor->kdev, &device_attrs[i]);
device_unregister(&minor->kdev);
}
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c
index 3ffae021d280..22f76567ac7d 100644
--- a/drivers/gpu/drm/drm_vm.c
+++ b/drivers/gpu/drm/drm_vm.c
@@ -91,7 +91,7 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->minor->dev;
- struct drm_map *map = NULL;
+ struct drm_local_map *map = NULL;
struct drm_map_list *r_list;
struct drm_hash_item *hash;
@@ -115,9 +115,9 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
* Using vm_pgoff as a selector forces us to use this unusual
* addressing scheme.
*/
- unsigned long offset = (unsigned long)vmf->virtual_address -
- vma->vm_start;
- unsigned long baddr = map->offset + offset;
+ resource_size_t offset = (unsigned long)vmf->virtual_address -
+ vma->vm_start;
+ resource_size_t baddr = map->offset + offset;
struct drm_agp_mem *agpmem;
struct page *page;
@@ -149,8 +149,10 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
vmf->page = page;
DRM_DEBUG
- ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
- baddr, __va(agpmem->memory->memory[offset]), offset,
+ ("baddr = 0x%llx page = 0x%p, offset = 0x%llx, count=%d\n",
+ (unsigned long long)baddr,
+ __va(agpmem->memory->memory[offset]),
+ (unsigned long long)offset,
page_count(page));
return 0;
}
@@ -176,7 +178,7 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
*/
static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- struct drm_map *map = (struct drm_map *) vma->vm_private_data;
+ struct drm_local_map *map = vma->vm_private_data;
unsigned long offset;
unsigned long i;
struct page *page;
@@ -209,7 +211,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->minor->dev;
struct drm_vma_entry *pt, *temp;
- struct drm_map *map;
+ struct drm_local_map *map;
struct drm_map_list *r_list;
int found_maps = 0;
@@ -322,7 +324,7 @@ static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
*/
static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- struct drm_map *map = (struct drm_map *) vma->vm_private_data;
+ struct drm_local_map *map = vma->vm_private_data;
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->minor->dev;
struct drm_sg_mem *entry = dev->sg;
@@ -512,14 +514,14 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
return 0;
}
-unsigned long drm_core_get_map_ofs(struct drm_map * map)
+resource_size_t drm_core_get_map_ofs(struct drm_local_map * map)
{
return map->offset;
}
EXPORT_SYMBOL(drm_core_get_map_ofs);
-unsigned long drm_core_get_reg_ofs(struct drm_device *dev)
+resource_size_t drm_core_get_reg_ofs(struct drm_device *dev)
{
#ifdef __alpha__
return dev->hose->dense_mem_base - dev->hose->mem_space->start;
@@ -547,8 +549,8 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
{
struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->minor->dev;
- struct drm_map *map = NULL;
- unsigned long offset = 0;
+ struct drm_local_map *map = NULL;
+ resource_size_t offset = 0;
struct drm_hash_item *hash;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
@@ -623,9 +625,9 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
vma->vm_page_prot))
return -EAGAIN;
DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
- " offset = 0x%lx\n",
+ " offset = 0x%llx\n",
map->type,
- vma->vm_start, vma->vm_end, map->offset + offset);
+ vma->vm_start, vma->vm_end, (unsigned long long)(map->offset + offset));
vma->vm_ops = &drm_vm_ops;
break;
case _DRM_CONSISTENT:
diff --git a/drivers/gpu/drm/i810/i810_drv.h b/drivers/gpu/drm/i810/i810_drv.h
index 0118849a5672..21e2691f28f9 100644
--- a/drivers/gpu/drm/i810/i810_drv.h
+++ b/drivers/gpu/drm/i810/i810_drv.h
@@ -77,8 +77,8 @@ typedef struct _drm_i810_ring_buffer {
} drm_i810_ring_buffer_t;
typedef struct drm_i810_private {
- struct drm_map *sarea_map;
- struct drm_map *mmio_map;
+ struct drm_local_map *sarea_map;
+ struct drm_local_map *mmio_map;
drm_i810_sarea_t *sarea_priv;
drm_i810_ring_buffer_t ring;
diff --git a/drivers/gpu/drm/i830/i830_drv.h b/drivers/gpu/drm/i830/i830_drv.h
index b5bf8cc0fdaa..da82afe4ded5 100644
--- a/drivers/gpu/drm/i830/i830_drv.h
+++ b/drivers/gpu/drm/i830/i830_drv.h
@@ -84,8 +84,8 @@ typedef struct _drm_i830_ring_buffer {
} drm_i830_ring_buffer_t;
typedef struct drm_i830_private {
- struct drm_map *sarea_map;
- struct drm_map *mmio_map;
+ struct drm_local_map *sarea_map;
+ struct drm_local_map *mmio_map;
drm_i830_sarea_t *sarea_priv;
drm_i830_ring_buffer_t ring;
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 793cba39d832..51c5a050aa73 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -7,7 +7,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
i915_suspend.o \
i915_gem.o \
i915_gem_debug.o \
- i915_gem_proc.o \
+ i915_gem_debugfs.o \
i915_gem_tiling.o \
intel_display.o \
intel_crt.o \
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 6d21b9e48b89..a000cf028826 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -41,7 +41,6 @@
int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
u32 last_acthd = I915_READ(acthd_reg);
@@ -58,8 +57,12 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
if (ring->space >= n)
return 0;
- if (master_priv->sarea_priv)
- master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
+ if (dev->primary->master) {
+ struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
+ if (master_priv->sarea_priv)
+ master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
+ }
+
if (ring->head != last_head)
i = 0;
@@ -356,7 +359,7 @@ static int validate_cmd(int cmd)
return ret;
}
-static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwords)
+static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords)
{
drm_i915_private_t *dev_priv = dev->dev_private;
int i;
@@ -370,8 +373,7 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor
for (i = 0; i < dwords;) {
int cmd, sz;
- if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd)))
- return -EINVAL;
+ cmd = buffer[i];
if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)
return -EINVAL;
@@ -379,11 +381,7 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor
OUT_RING(cmd);
while (++i, --sz) {
- if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i],
- sizeof(cmd))) {
- return -EINVAL;
- }
- OUT_RING(cmd);
+ OUT_RING(buffer[i]);
}
}
@@ -397,17 +395,13 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor
int
i915_emit_box(struct drm_device *dev,
- struct drm_clip_rect __user *boxes,
+ struct drm_clip_rect *boxes,
int i, int DR1, int DR4)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_clip_rect box;
+ struct drm_clip_rect box = boxes[i];
RING_LOCALS;
- if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) {
- return -EFAULT;
- }
-
if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
DRM_ERROR("Bad box %d,%d..%d,%d\n",
box.x1, box.y1, box.x2, box.y2);
@@ -460,7 +454,9 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
}
static int i915_dispatch_cmdbuffer(struct drm_device * dev,
- drm_i915_cmdbuffer_t * cmd)
+ drm_i915_cmdbuffer_t *cmd,
+ struct drm_clip_rect *cliprects,
+ void *cmdbuf)
{
int nbox = cmd->num_cliprects;
int i = 0, count, ret;
@@ -476,13 +472,13 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev,
for (i = 0; i < count; i++) {
if (i < nbox) {
- ret = i915_emit_box(dev, cmd->cliprects, i,
+ ret = i915_emit_box(dev, cliprects, i,
cmd->DR1, cmd->DR4);
if (ret)
return ret;
}
- ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4);
+ ret = i915_emit_cmds(dev, cmdbuf, cmd->sz / 4);
if (ret)
return ret;
}
@@ -492,10 +488,10 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev,
}
static int i915_dispatch_batchbuffer(struct drm_device * dev,
- drm_i915_batchbuffer_t * batch)
+ drm_i915_batchbuffer_t * batch,
+ struct drm_clip_rect *cliprects)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_clip_rect __user *boxes = batch->cliprects;
int nbox = batch->num_cliprects;
int i = 0, count;
RING_LOCALS;
@@ -511,7 +507,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
for (i = 0; i < count; i++) {
if (i < nbox) {
- int ret = i915_emit_box(dev, boxes, i,
+ int ret = i915_emit_box(dev, cliprects, i,
batch->DR1, batch->DR4);
if (ret)
return ret;
@@ -626,6 +622,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
master_priv->sarea_priv;
drm_i915_batchbuffer_t *batch = data;
int ret;
+ struct drm_clip_rect *cliprects = NULL;
if (!dev_priv->allow_batchbuffer) {
DRM_ERROR("Batchbuffer ioctl disabled\n");
@@ -637,17 +634,35 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
- if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
- batch->num_cliprects *
- sizeof(struct drm_clip_rect)))
- return -EFAULT;
+ if (batch->num_cliprects < 0)
+ return -EINVAL;
+
+ if (batch->num_cliprects) {
+ cliprects = drm_calloc(batch->num_cliprects,
+ sizeof(struct drm_clip_rect),
+ DRM_MEM_DRIVER);
+ if (cliprects == NULL)
+ return -ENOMEM;
+
+ ret = copy_from_user(cliprects, batch->cliprects,
+ batch->num_cliprects *
+ sizeof(struct drm_clip_rect));
+ if (ret != 0)
+ goto fail_free;
+ }
mutex_lock(&dev->struct_mutex);
- ret = i915_dispatch_batchbuffer(dev, batch);
+ ret = i915_dispatch_batchbuffer(dev, batch, cliprects);
mutex_unlock(&dev->struct_mutex);
if (sarea_priv)
sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
+
+fail_free:
+ drm_free(cliprects,
+ batch->num_cliprects * sizeof(struct drm_clip_rect),
+ DRM_MEM_DRIVER);
+
return ret;
}
@@ -659,6 +674,8 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
master_priv->sarea_priv;
drm_i915_cmdbuffer_t *cmdbuf = data;
+ struct drm_clip_rect *cliprects = NULL;
+ void *batch_data;
int ret;
DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
@@ -666,25 +683,50 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
- if (cmdbuf->num_cliprects &&
- DRM_VERIFYAREA_READ(cmdbuf->cliprects,
- cmdbuf->num_cliprects *
- sizeof(struct drm_clip_rect))) {
- DRM_ERROR("Fault accessing cliprects\n");
- return -EFAULT;
+ if (cmdbuf->num_cliprects < 0)
+ return -EINVAL;
+
+ batch_data = drm_alloc(cmdbuf->sz, DRM_MEM_DRIVER);
+ if (batch_data == NULL)
+ return -ENOMEM;
+
+ ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz);
+ if (ret != 0)
+ goto fail_batch_free;
+
+ if (cmdbuf->num_cliprects) {
+ cliprects = drm_calloc(cmdbuf->num_cliprects,
+ sizeof(struct drm_clip_rect),
+ DRM_MEM_DRIVER);
+ if (cliprects == NULL)
+ goto fail_batch_free;
+
+ ret = copy_from_user(cliprects, cmdbuf->cliprects,
+ cmdbuf->num_cliprects *
+ sizeof(struct drm_clip_rect));
+ if (ret != 0)
+ goto fail_clip_free;
}
mutex_lock(&dev->struct_mutex);
- ret = i915_dispatch_cmdbuffer(dev, cmdbuf);
+ ret = i915_dispatch_cmdbuffer(dev, cmdbuf, cliprects, batch_data);
mutex_unlock(&dev->struct_mutex);
if (ret) {
DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
- return ret;
+ goto fail_batch_free;
}
if (sarea_priv)
sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
- return 0;
+
+fail_batch_free:
+ drm_free(batch_data, cmdbuf->sz, DRM_MEM_DRIVER);
+fail_clip_free:
+ drm_free(cliprects,
+ cmdbuf->num_cliprects * sizeof(struct drm_clip_rect),
+ DRM_MEM_DRIVER);
+
+ return ret;
}
static int i915_flip_bufs(struct drm_device *dev, void *data,
@@ -880,7 +922,7 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size,
* Some of the preallocated space is taken by the GTT
* and popup. GTT is 1K per MB of aperture size, and popup is 4K.
*/
- if (IS_G4X(dev))
+ if (IS_G4X(dev) || IS_IGD(dev))
overhead = 4096;
else
overhead = (*aperture_size / 1024) + 4096;
@@ -988,13 +1030,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret)
goto destroy_ringbuffer;
- /* FIXME: re-add hotplug support */
-#if 0
- ret = drm_hotplug_init(dev);
- if (ret)
- goto destroy_ringbuffer;
-#endif
-
/* Always safe in the mode setting case. */
/* FIXME: do pre/post-mode set stuff in core KMS code */
dev->vblank_disable_allowed = 1;
@@ -1007,7 +1042,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
intel_modeset_init(dev);
- drm_helper_initial_config(dev, false);
+ drm_helper_initial_config(dev);
return 0;
@@ -1057,7 +1092,7 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
int i915_driver_load(struct drm_device *dev, unsigned long flags)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long base, size;
+ resource_size_t base, size;
int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
/* i915 has 4 more counters */
@@ -1144,8 +1179,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (!IS_I945G(dev) && !IS_I945GM(dev))
pci_enable_msi(dev->pdev);
- intel_opregion_init(dev);
-
spin_lock_init(&dev_priv->user_irq_lock);
dev_priv->user_irq_refcount = 0;
@@ -1164,6 +1197,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
}
}
+ /* Must be done after probing outputs */
+ intel_opregion_init(dev, 0);
+
return 0;
out_iomapfree:
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index b293ef0bae71..6503e2210f65 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -42,6 +42,8 @@ module_param_named(modeset, i915_modeset, int, 0400);
unsigned int i915_fbpercrtc = 0;
module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
+static struct drm_driver driver;
+
static struct pci_device_id pciidlist[] = {
i915_PCI_IDS
};
@@ -99,7 +101,7 @@ static int i915_resume(struct drm_device *dev)
i915_restore_state(dev);
- intel_opregion_init(dev);
+ intel_opregion_init(dev, 1);
/* KMS EnterVT equivalent */
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
@@ -117,6 +119,36 @@ static int i915_resume(struct drm_device *dev)
return ret;
}
+static int __devinit
+i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ return drm_get_dev(pdev, ent, &driver);
+}
+
+static void
+i915_pci_remove(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+
+ drm_put_dev(dev);
+}
+
+static int
+i915_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+
+ return i915_suspend(dev, state);
+}
+
+static int
+i915_pci_resume(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+
+ return i915_resume(dev);
+}
+
static struct vm_operations_struct i915_gem_vm_ops = {
.fault = i915_gem_fault,
.open = drm_gem_vm_open,
@@ -150,8 +182,10 @@ static struct drm_driver driver = {
.get_reg_ofs = drm_core_get_reg_ofs,
.master_create = i915_master_create,
.master_destroy = i915_master_destroy,
- .proc_init = i915_gem_proc_init,
- .proc_cleanup = i915_gem_proc_cleanup,
+#if defined(CONFIG_DEBUG_FS)
+ .debugfs_init = i915_gem_debugfs_init,
+ .debugfs_cleanup = i915_gem_debugfs_cleanup,
+#endif
.gem_init_object = i915_gem_init_object,
.gem_free_object = i915_gem_free_object,
.gem_vm_ops = &i915_gem_vm_ops,
@@ -172,6 +206,12 @@ static struct drm_driver driver = {
.pci_driver = {
.name = DRIVER_NAME,
.id_table = pciidlist,
+ .probe = i915_pci_probe,
+ .remove = i915_pci_remove,
+#ifdef CONFIG_PM
+ .resume = i915_pci_resume,
+ .suspend = i915_pci_suspend,
+#endif
},
.name = DRIVER_NAME,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d6cc9861e0a1..3750d8003048 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -159,6 +159,9 @@ typedef struct drm_i915_private {
u32 irq_mask_reg;
u32 pipestat[2];
+ u32 hotplug_supported_mask;
+ struct work_struct hotplug_work;
+
int tex_lru_log_granularity;
int allow_batchbuffer;
struct mem_block *agp_heap;
@@ -297,6 +300,7 @@ typedef struct drm_i915_private {
*
* A reference is held on the buffer while on this list.
*/
+ spinlock_t active_list_lock;
struct list_head active_list;
/**
@@ -404,7 +408,8 @@ struct drm_i915_gem_object {
/** AGP memory structure for our GTT binding. */
DRM_AGP_MEM *agp_mem;
- struct page **page_list;
+ struct page **pages;
+ int pages_refcount;
/**
* Current offset of the object in GTT space.
@@ -519,7 +524,7 @@ extern int i915_driver_device_is_agp(struct drm_device * dev);
extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
extern int i915_emit_box(struct drm_device *dev,
- struct drm_clip_rect __user *boxes,
+ struct drm_clip_rect *boxes,
int i, int DR1, int DR4);
/* i915_irq.c */
@@ -604,8 +609,6 @@ int i915_gem_get_tiling(struct drm_device *dev, void *data,
int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
void i915_gem_load(struct drm_device *dev);
-int i915_gem_proc_init(struct drm_minor *minor);
-void i915_gem_proc_cleanup(struct drm_minor *minor);
int i915_gem_init_object(struct drm_gem_object *obj);
void i915_gem_free_object(struct drm_gem_object *obj);
int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
@@ -649,6 +652,10 @@ void i915_gem_dump_object(struct drm_gem_object *obj, int len,
const char *where, uint32_t mark);
void i915_dump_lru(struct drm_device *dev, const char *where);
+/* i915_debugfs.c */
+int i915_gem_debugfs_init(struct drm_minor *minor);
+void i915_gem_debugfs_cleanup(struct drm_minor *minor);
+
/* i915_suspend.c */
extern int i915_save_state(struct drm_device *dev);
extern int i915_restore_state(struct drm_device *dev);
@@ -659,12 +666,12 @@ extern int i915_restore_state(struct drm_device *dev);
#ifdef CONFIG_ACPI
/* i915_opregion.c */
-extern int intel_opregion_init(struct drm_device *dev);
+extern int intel_opregion_init(struct drm_device *dev, int resume);
extern void intel_opregion_free(struct drm_device *dev);
extern void opregion_asle_intr(struct drm_device *dev);
extern void opregion_enable_asle(struct drm_device *dev);
#else
-static inline int intel_opregion_init(struct drm_device *dev) { return 0; }
+static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; }
static inline void intel_opregion_free(struct drm_device *dev) { return; }
static inline void opregion_asle_intr(struct drm_device *dev) { return; }
static inline void opregion_enable_asle(struct drm_device *dev) { return; }
@@ -784,15 +791,21 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
(dev)->pci_device == 0x2E22 || \
IS_GM45(dev))
+#define IS_IGDG(dev) ((dev)->pci_device == 0xa001)
+#define IS_IGDGM(dev) ((dev)->pci_device == 0xa011)
+#define IS_IGD(dev) (IS_IGDG(dev) || IS_IGDGM(dev))
+
#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \
(dev)->pci_device == 0x29B2 || \
- (dev)->pci_device == 0x29D2)
+ (dev)->pci_device == 0x29D2 || \
+ (IS_IGD(dev)))
#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev))
#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
- IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev))
+ IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev) || \
+ IS_IGD(dev))
#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev))
/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte
@@ -801,6 +814,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \
IS_I915GM(dev)))
#define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev))
+#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 37427e4016cb..1449b452cc63 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -43,8 +43,8 @@ static int i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
uint64_t offset,
uint64_t size);
static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj);
-static int i915_gem_object_get_page_list(struct drm_gem_object *obj);
-static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
+static int i915_gem_object_get_pages(struct drm_gem_object *obj);
+static void i915_gem_object_put_pages(struct drm_gem_object *obj);
static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj,
unsigned alignment);
@@ -136,6 +136,224 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
return 0;
}
+static inline int
+fast_shmem_read(struct page **pages,
+ loff_t page_base, int page_offset,
+ char __user *data,
+ int length)
+{
+ char __iomem *vaddr;
+ int ret;
+
+ vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT], KM_USER0);
+ if (vaddr == NULL)
+ return -ENOMEM;
+ ret = __copy_to_user_inatomic(data, vaddr + page_offset, length);
+ kunmap_atomic(vaddr, KM_USER0);
+
+ return ret;
+}
+
+static inline int
+slow_shmem_copy(struct page *dst_page,
+ int dst_offset,
+ struct page *src_page,
+ int src_offset,
+ int length)
+{
+ char *dst_vaddr, *src_vaddr;
+
+ dst_vaddr = kmap_atomic(dst_page, KM_USER0);
+ if (dst_vaddr == NULL)
+ return -ENOMEM;
+
+ src_vaddr = kmap_atomic(src_page, KM_USER1);
+ if (src_vaddr == NULL) {
+ kunmap_atomic(dst_vaddr, KM_USER0);
+ return -ENOMEM;
+ }
+
+ memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length);
+
+ kunmap_atomic(src_vaddr, KM_USER1);
+ kunmap_atomic(dst_vaddr, KM_USER0);
+
+ return 0;
+}
+
+/**
+ * This is the fast shmem pread path, which attempts to copy_from_user directly
+ * from the backing pages of the object to the user's address space. On a
+ * fault, it fails so we can fall back to i915_gem_shmem_pwrite_slow().
+ */
+static int
+i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,
+ struct drm_i915_gem_pread *args,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ ssize_t remain;
+ loff_t offset, page_base;
+ char __user *user_data;
+ int page_offset, page_length;
+ int ret;
+
+ user_data = (char __user *) (uintptr_t) args->data_ptr;
+ remain = args->size;
+
+ mutex_lock(&dev->struct_mutex);
+
+ ret = i915_gem_object_get_pages(obj);
+ if (ret != 0)
+ goto fail_unlock;
+
+ ret = i915_gem_object_set_cpu_read_domain_range(obj, args->offset,
+ args->size);
+ if (ret != 0)
+ goto fail_put_pages;
+
+ obj_priv = obj->driver_private;
+ offset = args->offset;
+
+ while (remain > 0) {
+ /* Operation in this page
+ *
+ * page_base = page offset within aperture
+ * page_offset = offset within page
+ * page_length = bytes to copy for this page
+ */
+ page_base = (offset & ~(PAGE_SIZE-1));
+ page_offset = offset & (PAGE_SIZE-1);
+ page_length = remain;
+ if ((page_offset + remain) > PAGE_SIZE)
+ page_length = PAGE_SIZE - page_offset;
+
+ ret = fast_shmem_read(obj_priv->pages,
+ page_base, page_offset,
+ user_data, page_length);
+ if (ret)
+ goto fail_put_pages;
+
+ remain -= page_length;
+ user_data += page_length;
+ offset += page_length;
+ }
+
+fail_put_pages:
+ i915_gem_object_put_pages(obj);
+fail_unlock:
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+/**
+ * This is the fallback shmem pread path, which allocates temporary storage
+ * in kernel space to copy_to_user into outside of the struct_mutex, so we
+ * can copy out of the object's backing pages while holding the struct mutex
+ * and not take page faults.
+ */
+static int
+i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
+ struct drm_i915_gem_pread *args,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct mm_struct *mm = current->mm;
+ struct page **user_pages;
+ ssize_t remain;
+ loff_t offset, pinned_pages, i;
+ loff_t first_data_page, last_data_page, num_pages;
+ int shmem_page_index, shmem_page_offset;
+ int data_page_index, data_page_offset;
+ int page_length;
+ int ret;
+ uint64_t data_ptr = args->data_ptr;
+
+ remain = args->size;
+
+ /* Pin the user pages containing the data. We can't fault while
+ * holding the struct mutex, yet we want to hold it while
+ * dereferencing the user data.
+ */
+ first_data_page = data_ptr / PAGE_SIZE;
+ last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE;
+ num_pages = last_data_page - first_data_page + 1;
+
+ user_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL);
+ if (user_pages == NULL)
+ return -ENOMEM;
+
+ down_read(&mm->mmap_sem);
+ pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr,
+ num_pages, 0, 0, user_pages, NULL);
+ up_read(&mm->mmap_sem);
+ if (pinned_pages < num_pages) {
+ ret = -EFAULT;
+ goto fail_put_user_pages;
+ }
+
+ mutex_lock(&dev->struct_mutex);
+
+ ret = i915_gem_object_get_pages(obj);
+ if (ret != 0)
+ goto fail_unlock;
+
+ ret = i915_gem_object_set_cpu_read_domain_range(obj, args->offset,
+ args->size);
+ if (ret != 0)
+ goto fail_put_pages;
+
+ obj_priv = obj->driver_private;
+ offset = args->offset;
+
+ while (remain > 0) {
+ /* Operation in this page
+ *
+ * shmem_page_index = page number within shmem file
+ * shmem_page_offset = offset within page in shmem file
+ * data_page_index = page number in get_user_pages return
+ * data_page_offset = offset with data_page_index page.
+ * page_length = bytes to copy for this page
+ */
+ shmem_page_index = offset / PAGE_SIZE;
+ shmem_page_offset = offset & ~PAGE_MASK;
+ data_page_index = data_ptr / PAGE_SIZE - first_data_page;
+ data_page_offset = data_ptr & ~PAGE_MASK;
+
+ page_length = remain;
+ if ((shmem_page_offset + page_length) > PAGE_SIZE)
+ page_length = PAGE_SIZE - shmem_page_offset;
+ if ((data_page_offset + page_length) > PAGE_SIZE)
+ page_length = PAGE_SIZE - data_page_offset;
+
+ ret = slow_shmem_copy(user_pages[data_page_index],
+ data_page_offset,
+ obj_priv->pages[shmem_page_index],
+ shmem_page_offset,
+ page_length);
+ if (ret)
+ goto fail_put_pages;
+
+ remain -= page_length;
+ data_ptr += page_length;
+ offset += page_length;
+ }
+
+fail_put_pages:
+ i915_gem_object_put_pages(obj);
+fail_unlock:
+ mutex_unlock(&dev->struct_mutex);
+fail_put_user_pages:
+ for (i = 0; i < pinned_pages; i++) {
+ SetPageDirty(user_pages[i]);
+ page_cache_release(user_pages[i]);
+ }
+ kfree(user_pages);
+
+ return ret;
+}
+
/**
* Reads data from the object referenced by handle.
*
@@ -148,8 +366,6 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
struct drm_i915_gem_pread *args = data;
struct drm_gem_object *obj;
struct drm_i915_gem_object *obj_priv;
- ssize_t read;
- loff_t offset;
int ret;
obj = drm_gem_object_lookup(dev, file_priv, args->handle);
@@ -167,33 +383,13 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
return -EINVAL;
}
- mutex_lock(&dev->struct_mutex);
-
- ret = i915_gem_object_set_cpu_read_domain_range(obj, args->offset,
- args->size);
- if (ret != 0) {
- drm_gem_object_unreference(obj);
- mutex_unlock(&dev->struct_mutex);
- return ret;
- }
-
- offset = args->offset;
-
- read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr,
- args->size, &offset);
- if (read != args->size) {
- drm_gem_object_unreference(obj);
- mutex_unlock(&dev->struct_mutex);
- if (read < 0)
- return read;
- else
- return -EINVAL;
- }
+ ret = i915_gem_shmem_pread_fast(dev, obj, args, file_priv);
+ if (ret != 0)
+ ret = i915_gem_shmem_pread_slow(dev, obj, args, file_priv);
drm_gem_object_unreference(obj);
- mutex_unlock(&dev->struct_mutex);
- return 0;
+ return ret;
}
/* This is the fast write path which cannot handle
@@ -223,29 +419,54 @@ fast_user_write(struct io_mapping *mapping,
*/
static inline int
-slow_user_write(struct io_mapping *mapping,
- loff_t page_base, int page_offset,
- char __user *user_data,
- int length)
+slow_kernel_write(struct io_mapping *mapping,
+ loff_t gtt_base, int gtt_offset,
+ struct page *user_page, int user_offset,
+ int length)
+{
+ char *src_vaddr, *dst_vaddr;
+ unsigned long unwritten;
+
+ dst_vaddr = io_mapping_map_atomic_wc(mapping, gtt_base);
+ src_vaddr = kmap_atomic(user_page, KM_USER1);
+ unwritten = __copy_from_user_inatomic_nocache(dst_vaddr + gtt_offset,
+ src_vaddr + user_offset,
+ length);
+ kunmap_atomic(src_vaddr, KM_USER1);
+ io_mapping_unmap_atomic(dst_vaddr);
+ if (unwritten)
+ return -EFAULT;
+ return 0;
+}
+
+static inline int
+fast_shmem_write(struct page **pages,
+ loff_t page_base, int page_offset,
+ char __user *data,
+ int length)
{
char __iomem *vaddr;
unsigned long unwritten;
- vaddr = io_mapping_map_wc(mapping, page_base);
+ vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT], KM_USER0);
if (vaddr == NULL)
- return -EFAULT;
- unwritten = __copy_from_user(vaddr + page_offset,
- user_data, length);
- io_mapping_unmap(vaddr);
+ return -ENOMEM;
+ unwritten = __copy_from_user_inatomic(vaddr + page_offset, data, length);
+ kunmap_atomic(vaddr, KM_USER0);
+
if (unwritten)
return -EFAULT;
return 0;
}
+/**
+ * This is the fast pwrite path, where we copy the data directly from the
+ * user into the GTT, uncached.
+ */
static int
-i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
- struct drm_i915_gem_pwrite *args,
- struct drm_file *file_priv)
+i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
+ struct drm_i915_gem_pwrite *args,
+ struct drm_file *file_priv)
{
struct drm_i915_gem_object *obj_priv = obj->driver_private;
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -273,7 +494,6 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
obj_priv = obj->driver_private;
offset = obj_priv->gtt_offset + args->offset;
- obj_priv->dirty = 1;
while (remain > 0) {
/* Operation in this page
@@ -292,16 +512,11 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
page_offset, user_data, page_length);
/* If we get a fault while copying data, then (presumably) our
- * source page isn't available. In this case, use the
- * non-atomic function
+ * source page isn't available. Return the error and we'll
+ * retry in the slow path.
*/
- if (ret) {
- ret = slow_user_write (dev_priv->mm.gtt_mapping,
- page_base, page_offset,
- user_data, page_length);
- if (ret)
- goto fail;
- }
+ if (ret)
+ goto fail;
remain -= page_length;
user_data += page_length;
@@ -315,39 +530,284 @@ fail:
return ret;
}
+/**
+ * This is the fallback GTT pwrite path, which uses get_user_pages to pin
+ * the memory and maps it using kmap_atomic for copying.
+ *
+ * This code resulted in x11perf -rgb10text consuming about 10% more CPU
+ * than using i915_gem_gtt_pwrite_fast on a G45 (32-bit).
+ */
static int
-i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
- struct drm_i915_gem_pwrite *args,
- struct drm_file *file_priv)
+i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
+ struct drm_i915_gem_pwrite *args,
+ struct drm_file *file_priv)
{
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ ssize_t remain;
+ loff_t gtt_page_base, offset;
+ loff_t first_data_page, last_data_page, num_pages;
+ loff_t pinned_pages, i;
+ struct page **user_pages;
+ struct mm_struct *mm = current->mm;
+ int gtt_page_offset, data_page_offset, data_page_index, page_length;
int ret;
- loff_t offset;
- ssize_t written;
+ uint64_t data_ptr = args->data_ptr;
+
+ remain = args->size;
+
+ /* Pin the user pages containing the data. We can't fault while
+ * holding the struct mutex, and all of the pwrite implementations
+ * want to hold it while dereferencing the user data.
+ */
+ first_data_page = data_ptr / PAGE_SIZE;
+ last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE;
+ num_pages = last_data_page - first_data_page + 1;
+
+ user_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL);
+ if (user_pages == NULL)
+ return -ENOMEM;
+
+ down_read(&mm->mmap_sem);
+ pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr,
+ num_pages, 0, 0, user_pages, NULL);
+ up_read(&mm->mmap_sem);
+ if (pinned_pages < num_pages) {
+ ret = -EFAULT;
+ goto out_unpin_pages;
+ }
+
+ mutex_lock(&dev->struct_mutex);
+ ret = i915_gem_object_pin(obj, 0);
+ if (ret)
+ goto out_unlock;
+
+ ret = i915_gem_object_set_to_gtt_domain(obj, 1);
+ if (ret)
+ goto out_unpin_object;
+
+ obj_priv = obj->driver_private;
+ offset = obj_priv->gtt_offset + args->offset;
+
+ while (remain > 0) {
+ /* Operation in this page
+ *
+ * gtt_page_base = page offset within aperture
+ * gtt_page_offset = offset within page in aperture
+ * data_page_index = page number in get_user_pages return
+ * data_page_offset = offset with data_page_index page.
+ * page_length = bytes to copy for this page
+ */
+ gtt_page_base = offset & PAGE_MASK;
+ gtt_page_offset = offset & ~PAGE_MASK;
+ data_page_index = data_ptr / PAGE_SIZE - first_data_page;
+ data_page_offset = data_ptr & ~PAGE_MASK;
+
+ page_length = remain;
+ if ((gtt_page_offset + page_length) > PAGE_SIZE)
+ page_length = PAGE_SIZE - gtt_page_offset;
+ if ((data_page_offset + page_length) > PAGE_SIZE)
+ page_length = PAGE_SIZE - data_page_offset;
+
+ ret = slow_kernel_write(dev_priv->mm.gtt_mapping,
+ gtt_page_base, gtt_page_offset,
+ user_pages[data_page_index],
+ data_page_offset,
+ page_length);
+
+ /* If we get a fault while copying data, then (presumably) our
+ * source page isn't available. Return the error and we'll
+ * retry in the slow path.
+ */
+ if (ret)
+ goto out_unpin_object;
+
+ remain -= page_length;
+ offset += page_length;
+ data_ptr += page_length;
+ }
+
+out_unpin_object:
+ i915_gem_object_unpin(obj);
+out_unlock:
+ mutex_unlock(&dev->struct_mutex);
+out_unpin_pages:
+ for (i = 0; i < pinned_pages; i++)
+ page_cache_release(user_pages[i]);
+ kfree(user_pages);
+
+ return ret;
+}
+
+/**
+ * This is the fast shmem pwrite path, which attempts to directly
+ * copy_from_user into the kmapped pages backing the object.
+ */
+static int
+i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
+ struct drm_i915_gem_pwrite *args,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ ssize_t remain;
+ loff_t offset, page_base;
+ char __user *user_data;
+ int page_offset, page_length;
+ int ret;
+
+ user_data = (char __user *) (uintptr_t) args->data_ptr;
+ remain = args->size;
mutex_lock(&dev->struct_mutex);
+ ret = i915_gem_object_get_pages(obj);
+ if (ret != 0)
+ goto fail_unlock;
+
ret = i915_gem_object_set_to_cpu_domain(obj, 1);
- if (ret) {
- mutex_unlock(&dev->struct_mutex);
- return ret;
+ if (ret != 0)
+ goto fail_put_pages;
+
+ obj_priv = obj->driver_private;
+ offset = args->offset;
+ obj_priv->dirty = 1;
+
+ while (remain > 0) {
+ /* Operation in this page
+ *
+ * page_base = page offset within aperture
+ * page_offset = offset within page
+ * page_length = bytes to copy for this page
+ */
+ page_base = (offset & ~(PAGE_SIZE-1));
+ page_offset = offset & (PAGE_SIZE-1);
+ page_length = remain;
+ if ((page_offset + remain) > PAGE_SIZE)
+ page_length = PAGE_SIZE - page_offset;
+
+ ret = fast_shmem_write(obj_priv->pages,
+ page_base, page_offset,
+ user_data, page_length);
+ if (ret)
+ goto fail_put_pages;
+
+ remain -= page_length;
+ user_data += page_length;
+ offset += page_length;
+ }
+
+fail_put_pages:
+ i915_gem_object_put_pages(obj);
+fail_unlock:
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+/**
+ * This is the fallback shmem pwrite path, which uses get_user_pages to pin
+ * the memory and maps it using kmap_atomic for copying.
+ *
+ * This avoids taking mmap_sem for faulting on the user's address while the
+ * struct_mutex is held.
+ */
+static int
+i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
+ struct drm_i915_gem_pwrite *args,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct mm_struct *mm = current->mm;
+ struct page **user_pages;
+ ssize_t remain;
+ loff_t offset, pinned_pages, i;
+ loff_t first_data_page, last_data_page, num_pages;
+ int shmem_page_index, shmem_page_offset;
+ int data_page_index, data_page_offset;
+ int page_length;
+ int ret;
+ uint64_t data_ptr = args->data_ptr;
+
+ remain = args->size;
+
+ /* Pin the user pages containing the data. We can't fault while
+ * holding the struct mutex, and all of the pwrite implementations
+ * want to hold it while dereferencing the user data.
+ */
+ first_data_page = data_ptr / PAGE_SIZE;
+ last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE;
+ num_pages = last_data_page - first_data_page + 1;
+
+ user_pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL);
+ if (user_pages == NULL)
+ return -ENOMEM;
+
+ down_read(&mm->mmap_sem);
+ pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr,
+ num_pages, 0, 0, user_pages, NULL);
+ up_read(&mm->mmap_sem);
+ if (pinned_pages < num_pages) {
+ ret = -EFAULT;
+ goto fail_put_user_pages;
}
+ mutex_lock(&dev->struct_mutex);
+
+ ret = i915_gem_object_get_pages(obj);
+ if (ret != 0)
+ goto fail_unlock;
+
+ ret = i915_gem_object_set_to_cpu_domain(obj, 1);
+ if (ret != 0)
+ goto fail_put_pages;
+
+ obj_priv = obj->driver_private;
offset = args->offset;
+ obj_priv->dirty = 1;
- written = vfs_write(obj->filp,
- (char __user *)(uintptr_t) args->data_ptr,
- args->size, &offset);
- if (written != args->size) {
- mutex_unlock(&dev->struct_mutex);
- if (written < 0)
- return written;
- else
- return -EINVAL;
+ while (remain > 0) {
+ /* Operation in this page
+ *
+ * shmem_page_index = page number within shmem file
+ * shmem_page_offset = offset within page in shmem file
+ * data_page_index = page number in get_user_pages return
+ * data_page_offset = offset with data_page_index page.
+ * page_length = bytes to copy for this page
+ */
+ shmem_page_index = offset / PAGE_SIZE;
+ shmem_page_offset = offset & ~PAGE_MASK;
+ data_page_index = data_ptr / PAGE_SIZE - first_data_page;
+ data_page_offset = data_ptr & ~PAGE_MASK;
+
+ page_length = remain;
+ if ((shmem_page_offset + page_length) > PAGE_SIZE)
+ page_length = PAGE_SIZE - shmem_page_offset;
+ if ((data_page_offset + page_length) > PAGE_SIZE)
+ page_length = PAGE_SIZE - data_page_offset;
+
+ ret = slow_shmem_copy(obj_priv->pages[shmem_page_index],
+ shmem_page_offset,
+ user_pages[data_page_index],
+ data_page_offset,
+ page_length);
+ if (ret)
+ goto fail_put_pages;
+
+ remain -= page_length;
+ data_ptr += page_length;
+ offset += page_length;
}
+fail_put_pages:
+ i915_gem_object_put_pages(obj);
+fail_unlock:
mutex_unlock(&dev->struct_mutex);
+fail_put_user_pages:
+ for (i = 0; i < pinned_pages; i++)
+ page_cache_release(user_pages[i]);
+ kfree(user_pages);
- return 0;
+ return ret;
}
/**
@@ -388,10 +848,19 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
if (obj_priv->phys_obj)
ret = i915_gem_phys_pwrite(dev, obj, args, file_priv);
else if (obj_priv->tiling_mode == I915_TILING_NONE &&
- dev->gtt_total != 0)
- ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv);
- else
- ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv);
+ dev->gtt_total != 0) {
+ ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file_priv);
+ if (ret == -EFAULT) {
+ ret = i915_gem_gtt_pwrite_slow(dev, obj, args,
+ file_priv);
+ }
+ } else {
+ ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file_priv);
+ if (ret == -EFAULT) {
+ ret = i915_gem_shmem_pwrite_slow(dev, obj, args,
+ file_priv);
+ }
+ }
#if WATCH_PWRITE
if (ret)
@@ -603,6 +1072,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
case -EAGAIN:
return VM_FAULT_OOM;
case -EFAULT:
+ case -EINVAL:
return VM_FAULT_SIGBUS;
default:
return VM_FAULT_NOPAGE;
@@ -627,7 +1097,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj)
struct drm_gem_mm *mm = dev->mm_private;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
struct drm_map_list *list;
- struct drm_map *map;
+ struct drm_local_map *map;
int ret = 0;
/* Set the object up for mmap'ing */
@@ -816,29 +1286,30 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
}
static void
-i915_gem_object_free_page_list(struct drm_gem_object *obj)
+i915_gem_object_put_pages(struct drm_gem_object *obj)
{
struct drm_i915_gem_object *obj_priv = obj->driver_private;
int page_count = obj->size / PAGE_SIZE;
int i;
- if (obj_priv->page_list == NULL)
- return;
+ BUG_ON(obj_priv->pages_refcount == 0);
+ if (--obj_priv->pages_refcount != 0)
+ return;
for (i = 0; i < page_count; i++)
- if (obj_priv->page_list[i] != NULL) {
+ if (obj_priv->pages[i] != NULL) {
if (obj_priv->dirty)
- set_page_dirty(obj_priv->page_list[i]);
- mark_page_accessed(obj_priv->page_list[i]);
- page_cache_release(obj_priv->page_list[i]);
+ set_page_dirty(obj_priv->pages[i]);
+ mark_page_accessed(obj_priv->pages[i]);
+ page_cache_release(obj_priv->pages[i]);
}
obj_priv->dirty = 0;
- drm_free(obj_priv->page_list,
+ drm_free(obj_priv->pages,
page_count * sizeof(struct page *),
DRM_MEM_DRIVER);
- obj_priv->page_list = NULL;
+ obj_priv->pages = NULL;
}
static void
@@ -854,8 +1325,10 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno)
obj_priv->active = 1;
}
/* Move from whatever list we were on to the tail of execution. */
+ spin_lock(&dev_priv->mm.active_list_lock);
list_move_tail(&obj_priv->list,
&dev_priv->mm.active_list);
+ spin_unlock(&dev_priv->mm.active_list_lock);
obj_priv->last_rendering_seqno = seqno;
}
@@ -997,6 +1470,7 @@ i915_gem_retire_request(struct drm_device *dev,
/* Move any buffers on the active list that are no longer referenced
* by the ringbuffer to the flushing/inactive lists as appropriate.
*/
+ spin_lock(&dev_priv->mm.active_list_lock);
while (!list_empty(&dev_priv->mm.active_list)) {
struct drm_gem_object *obj;
struct drm_i915_gem_object *obj_priv;
@@ -1011,7 +1485,7 @@ i915_gem_retire_request(struct drm_device *dev,
* this seqno.
*/
if (obj_priv->last_rendering_seqno != request->seqno)
- return;
+ goto out;
#if WATCH_LRU
DRM_INFO("%s: retire %d moves to inactive list %p\n",
@@ -1023,6 +1497,8 @@ i915_gem_retire_request(struct drm_device *dev,
else
i915_gem_object_move_to_inactive(obj);
}
+out:
+ spin_unlock(&dev_priv->mm.active_list_lock);
}
/**
@@ -1290,7 +1766,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
i915_gem_clear_fence_reg(obj);
- i915_gem_object_free_page_list(obj);
+ i915_gem_object_put_pages(obj);
if (obj_priv->gtt_space) {
atomic_dec(&dev->gtt_count);
@@ -1409,7 +1885,7 @@ i915_gem_evict_everything(struct drm_device *dev)
}
static int
-i915_gem_object_get_page_list(struct drm_gem_object *obj)
+i915_gem_object_get_pages(struct drm_gem_object *obj)
{
struct drm_i915_gem_object *obj_priv = obj->driver_private;
int page_count, i;
@@ -1418,18 +1894,19 @@ i915_gem_object_get_page_list(struct drm_gem_object *obj)
struct page *page;
int ret;
- if (obj_priv->page_list)
+ if (obj_priv->pages_refcount++ != 0)
return 0;
/* Get the list of pages out of our struct file. They'll be pinned
* at this point until we release them.
*/
page_count = obj->size / PAGE_SIZE;
- BUG_ON(obj_priv->page_list != NULL);
- obj_priv->page_list = drm_calloc(page_count, sizeof(struct page *),
- DRM_MEM_DRIVER);
- if (obj_priv->page_list == NULL) {
+ BUG_ON(obj_priv->pages != NULL);
+ obj_priv->pages = drm_calloc(page_count, sizeof(struct page *),
+ DRM_MEM_DRIVER);
+ if (obj_priv->pages == NULL) {
DRM_ERROR("Faled to allocate page list\n");
+ obj_priv->pages_refcount--;
return -ENOMEM;
}
@@ -1440,10 +1917,10 @@ i915_gem_object_get_page_list(struct drm_gem_object *obj)
if (IS_ERR(page)) {
ret = PTR_ERR(page);
DRM_ERROR("read_mapping_page failed: %d\n", ret);
- i915_gem_object_free_page_list(obj);
+ i915_gem_object_put_pages(obj);
return ret;
}
- obj_priv->page_list[i] = page;
+ obj_priv->pages[i] = page;
}
return 0;
}
@@ -1519,20 +1996,23 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
int regnum = obj_priv->fence_reg;
uint32_t val;
uint32_t pitch_val;
+ uint32_t fence_size_bits;
- if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) ||
+ if ((obj_priv->gtt_offset & ~I830_FENCE_START_MASK) ||
(obj_priv->gtt_offset & (obj->size - 1))) {
- WARN(1, "%s: object 0x%08x not 1M or size aligned\n",
+ WARN(1, "%s: object 0x%08x not 512K or size aligned\n",
__func__, obj_priv->gtt_offset);
return;
}
pitch_val = (obj_priv->stride / 128) - 1;
-
+ WARN_ON(pitch_val & ~0x0000000f);
val = obj_priv->gtt_offset;
if (obj_priv->tiling_mode == I915_TILING_Y)
val |= 1 << I830_FENCE_TILING_Y_SHIFT;
- val |= I830_FENCE_SIZE_BITS(obj->size);
+ fence_size_bits = I830_FENCE_SIZE_BITS(obj->size);
+ WARN_ON(fence_size_bits & ~0x00000f00);
+ val |= fence_size_bits;
val |= pitch_val << I830_FENCE_PITCH_SHIFT;
val |= I830_FENCE_REG_VALID;
@@ -1723,7 +2203,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
return -EBUSY;
if (alignment == 0)
alignment = i915_gem_get_gtt_alignment(obj);
- if (alignment & (PAGE_SIZE - 1)) {
+ if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) {
DRM_ERROR("Invalid object alignment requested %u\n", alignment);
return -EINVAL;
}
@@ -1740,15 +2220,20 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
}
}
if (obj_priv->gtt_space == NULL) {
+ bool lists_empty;
+
/* If the gtt is empty and we're still having trouble
* fitting our object in, we're out of memory.
*/
#if WATCH_LRU
DRM_INFO("%s: GTT full, evicting something\n", __func__);
#endif
- if (list_empty(&dev_priv->mm.inactive_list) &&
- list_empty(&dev_priv->mm.flushing_list) &&
- list_empty(&dev_priv->mm.active_list)) {
+ spin_lock(&dev_priv->mm.active_list_lock);
+ lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
+ list_empty(&dev_priv->mm.flushing_list) &&
+ list_empty(&dev_priv->mm.active_list));
+ spin_unlock(&dev_priv->mm.active_list_lock);
+ if (lists_empty) {
DRM_ERROR("GTT full, but LRU list empty\n");
return -ENOMEM;
}
@@ -1766,7 +2251,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
DRM_INFO("Binding object of size %d at 0x%08x\n",
obj->size, obj_priv->gtt_offset);
#endif
- ret = i915_gem_object_get_page_list(obj);
+ ret = i915_gem_object_get_pages(obj);
if (ret) {
drm_mm_put_block(obj_priv->gtt_space);
obj_priv->gtt_space = NULL;
@@ -1778,12 +2263,12 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
* into the GTT.
*/
obj_priv->agp_mem = drm_agp_bind_pages(dev,
- obj_priv->page_list,
+ obj_priv->pages,
page_count,
obj_priv->gtt_offset,
obj_priv->agp_type);
if (obj_priv->agp_mem == NULL) {
- i915_gem_object_free_page_list(obj);
+ i915_gem_object_put_pages(obj);
drm_mm_put_block(obj_priv->gtt_space);
obj_priv->gtt_space = NULL;
return -ENOMEM;
@@ -1810,10 +2295,10 @@ i915_gem_clflush_object(struct drm_gem_object *obj)
* to GPU, and we can ignore the cache flush because it'll happen
* again at bind time.
*/
- if (obj_priv->page_list == NULL)
+ if (obj_priv->pages == NULL)
return;
- drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE);
+ drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE);
}
/** Flushes any GPU write domain for the object if it's dirty. */
@@ -1913,7 +2398,6 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
static int
i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
{
- struct drm_device *dev = obj->dev;
int ret;
i915_gem_object_flush_gpu_write_domain(obj);
@@ -1932,7 +2416,6 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
/* Flush the CPU cache if it's still invalid. */
if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) {
i915_gem_clflush_object(obj);
- drm_agp_chipset_flush(dev);
obj->read_domains |= I915_GEM_DOMAIN_CPU;
}
@@ -2144,7 +2627,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
static void
i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj)
{
- struct drm_device *dev = obj->dev;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
if (!obj_priv->page_cpu_valid)
@@ -2158,9 +2640,8 @@ i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj)
for (i = 0; i <= (obj->size - 1) / PAGE_SIZE; i++) {
if (obj_priv->page_cpu_valid[i])
continue;
- drm_clflush_pages(obj_priv->page_list + i, 1);
+ drm_clflush_pages(obj_priv->pages + i, 1);
}
- drm_agp_chipset_flush(dev);
}
/* Free the page_cpu_valid mappings which are now stale, whether
@@ -2224,7 +2705,7 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
if (obj_priv->page_cpu_valid[i])
continue;
- drm_clflush_pages(obj_priv->page_list + i, 1);
+ drm_clflush_pages(obj_priv->pages + i, 1);
obj_priv->page_cpu_valid[i] = 1;
}
@@ -2245,12 +2726,11 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
static int
i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
struct drm_file *file_priv,
- struct drm_i915_gem_exec_object *entry)
+ struct drm_i915_gem_exec_object *entry,
+ struct drm_i915_gem_relocation_entry *relocs)
{
struct drm_device *dev = obj->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_relocation_entry reloc;
- struct drm_i915_gem_relocation_entry __user *relocs;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
int i, ret;
void __iomem *reloc_page;
@@ -2262,25 +2742,18 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
entry->offset = obj_priv->gtt_offset;
- relocs = (struct drm_i915_gem_relocation_entry __user *)
- (uintptr_t) entry->relocs_ptr;
/* Apply the relocations, using the GTT aperture to avoid cache
* flushing requirements.
*/
for (i = 0; i < entry->relocation_count; i++) {
+ struct drm_i915_gem_relocation_entry *reloc= &relocs[i];
struct drm_gem_object *target_obj;
struct drm_i915_gem_object *target_obj_priv;
uint32_t reloc_val, reloc_offset;
uint32_t __iomem *reloc_entry;
- ret = copy_from_user(&reloc, relocs + i, sizeof(reloc));
- if (ret != 0) {
- i915_gem_object_unpin(obj);
- return ret;
- }
-
target_obj = drm_gem_object_lookup(obj->dev, file_priv,
- reloc.target_handle);
+ reloc->target_handle);
if (target_obj == NULL) {
i915_gem_object_unpin(obj);
return -EBADF;
@@ -2292,53 +2765,53 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
*/
if (target_obj_priv->gtt_space == NULL) {
DRM_ERROR("No GTT space found for object %d\n",
- reloc.target_handle);
+ reloc->target_handle);
drm_gem_object_unreference(target_obj);
i915_gem_object_unpin(obj);
return -EINVAL;
}
- if (reloc.offset > obj->size - 4) {
+ if (reloc->offset > obj->size - 4) {
DRM_ERROR("Relocation beyond object bounds: "
"obj %p target %d offset %d size %d.\n",
- obj, reloc.target_handle,
- (int) reloc.offset, (int) obj->size);
+ obj, reloc->target_handle,
+ (int) reloc->offset, (int) obj->size);
drm_gem_object_unreference(target_obj);
i915_gem_object_unpin(obj);
return -EINVAL;
}
- if (reloc.offset & 3) {
+ if (reloc->offset & 3) {
DRM_ERROR("Relocation not 4-byte aligned: "
"obj %p target %d offset %d.\n",
- obj, reloc.target_handle,
- (int) reloc.offset);
+ obj, reloc->target_handle,
+ (int) reloc->offset);
drm_gem_object_unreference(target_obj);
i915_gem_object_unpin(obj);
return -EINVAL;
}
- if (reloc.write_domain & I915_GEM_DOMAIN_CPU ||
- reloc.read_domains & I915_GEM_DOMAIN_CPU) {
+ if (reloc->write_domain & I915_GEM_DOMAIN_CPU ||
+ reloc->read_domains & I915_GEM_DOMAIN_CPU) {
DRM_ERROR("reloc with read/write CPU domains: "
"obj %p target %d offset %d "
"read %08x write %08x",
- obj, reloc.target_handle,
- (int) reloc.offset,
- reloc.read_domains,
- reloc.write_domain);
+ obj, reloc->target_handle,
+ (int) reloc->offset,
+ reloc->read_domains,
+ reloc->write_domain);
drm_gem_object_unreference(target_obj);
i915_gem_object_unpin(obj);
return -EINVAL;
}
- if (reloc.write_domain && target_obj->pending_write_domain &&
- reloc.write_domain != target_obj->pending_write_domain) {
+ if (reloc->write_domain && target_obj->pending_write_domain &&
+ reloc->write_domain != target_obj->pending_write_domain) {
DRM_ERROR("Write domain conflict: "
"obj %p target %d offset %d "
"new %08x old %08x\n",
- obj, reloc.target_handle,
- (int) reloc.offset,
- reloc.write_domain,
+ obj, reloc->target_handle,
+ (int) reloc->offset,
+ reloc->write_domain,
target_obj->pending_write_domain);
drm_gem_object_unreference(target_obj);
i915_gem_object_unpin(obj);
@@ -2351,22 +2824,22 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
"presumed %08x delta %08x\n",
__func__,
obj,
- (int) reloc.offset,
- (int) reloc.target_handle,
- (int) reloc.read_domains,
- (int) reloc.write_domain,
+ (int) reloc->offset,
+ (int) reloc->target_handle,
+ (int) reloc->read_domains,
+ (int) reloc->write_domain,
(int) target_obj_priv->gtt_offset,
- (int) reloc.presumed_offset,
- reloc.delta);
+ (int) reloc->presumed_offset,
+ reloc->delta);
#endif
- target_obj->pending_read_domains |= reloc.read_domains;
- target_obj->pending_write_domain |= reloc.write_domain;
+ target_obj->pending_read_domains |= reloc->read_domains;
+ target_obj->pending_write_domain |= reloc->write_domain;
/* If the relocation already has the right value in it, no
* more work needs to be done.
*/
- if (target_obj_priv->gtt_offset == reloc.presumed_offset) {
+ if (target_obj_priv->gtt_offset == reloc->presumed_offset) {
drm_gem_object_unreference(target_obj);
continue;
}
@@ -2381,32 +2854,26 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
/* Map the page containing the relocation we're going to
* perform.
*/
- reloc_offset = obj_priv->gtt_offset + reloc.offset;
+ reloc_offset = obj_priv->gtt_offset + reloc->offset;
reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
(reloc_offset &
~(PAGE_SIZE - 1)));
reloc_entry = (uint32_t __iomem *)(reloc_page +
(reloc_offset & (PAGE_SIZE - 1)));
- reloc_val = target_obj_priv->gtt_offset + reloc.delta;
+ reloc_val = target_obj_priv->gtt_offset + reloc->delta;
#if WATCH_BUF
DRM_INFO("Applied relocation: %p@0x%08x %08x -> %08x\n",
- obj, (unsigned int) reloc.offset,
+ obj, (unsigned int) reloc->offset,
readl(reloc_entry), reloc_val);
#endif
writel(reloc_val, reloc_entry);
io_mapping_unmap_atomic(reloc_page);
- /* Write the updated presumed offset for this entry back out
- * to the user.
+ /* The updated presumed offset for this entry will be
+ * copied back out to the user.
*/
- reloc.presumed_offset = target_obj_priv->gtt_offset;
- ret = copy_to_user(relocs + i, &reloc, sizeof(reloc));
- if (ret != 0) {
- drm_gem_object_unreference(target_obj);
- i915_gem_object_unpin(obj);
- return ret;
- }
+ reloc->presumed_offset = target_obj_priv->gtt_offset;
drm_gem_object_unreference(target_obj);
}
@@ -2423,11 +2890,10 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
static int
i915_dispatch_gem_execbuffer(struct drm_device *dev,
struct drm_i915_gem_execbuffer *exec,
+ struct drm_clip_rect *cliprects,
uint64_t exec_offset)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_clip_rect __user *boxes = (struct drm_clip_rect __user *)
- (uintptr_t) exec->cliprects_ptr;
int nbox = exec->num_cliprects;
int i = 0, count;
uint32_t exec_start, exec_len;
@@ -2448,7 +2914,7 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev,
for (i = 0; i < count; i++) {
if (i < nbox) {
- int ret = i915_emit_box(dev, boxes, i,
+ int ret = i915_emit_box(dev, cliprects, i,
exec->DR1, exec->DR4);
if (ret)
return ret;
@@ -2504,6 +2970,75 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv)
return ret;
}
+static int
+i915_gem_get_relocs_from_user(struct drm_i915_gem_exec_object *exec_list,
+ uint32_t buffer_count,
+ struct drm_i915_gem_relocation_entry **relocs)
+{
+ uint32_t reloc_count = 0, reloc_index = 0, i;
+ int ret;
+
+ *relocs = NULL;
+ for (i = 0; i < buffer_count; i++) {
+ if (reloc_count + exec_list[i].relocation_count < reloc_count)
+ return -EINVAL;
+ reloc_count += exec_list[i].relocation_count;
+ }
+
+ *relocs = drm_calloc(reloc_count, sizeof(**relocs), DRM_MEM_DRIVER);
+ if (*relocs == NULL)
+ return -ENOMEM;
+
+ for (i = 0; i < buffer_count; i++) {
+ struct drm_i915_gem_relocation_entry __user *user_relocs;
+
+ user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr;
+
+ ret = copy_from_user(&(*relocs)[reloc_index],
+ user_relocs,
+ exec_list[i].relocation_count *
+ sizeof(**relocs));
+ if (ret != 0) {
+ drm_free(*relocs, reloc_count * sizeof(**relocs),
+ DRM_MEM_DRIVER);
+ *relocs = NULL;
+ return ret;
+ }
+
+ reloc_index += exec_list[i].relocation_count;
+ }
+
+ return ret;
+}
+
+static int
+i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object *exec_list,
+ uint32_t buffer_count,
+ struct drm_i915_gem_relocation_entry *relocs)
+{
+ uint32_t reloc_count = 0, i;
+ int ret;
+
+ for (i = 0; i < buffer_count; i++) {
+ struct drm_i915_gem_relocation_entry __user *user_relocs;
+
+ user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr;
+
+ if (ret == 0) {
+ ret = copy_to_user(user_relocs,
+ &relocs[reloc_count],
+ exec_list[i].relocation_count *
+ sizeof(*relocs));
+ }
+
+ reloc_count += exec_list[i].relocation_count;
+ }
+
+ drm_free(relocs, reloc_count * sizeof(*relocs), DRM_MEM_DRIVER);
+
+ return ret;
+}
+
int
i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_file *file_priv)
@@ -2515,9 +3050,11 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
struct drm_gem_object **object_list = NULL;
struct drm_gem_object *batch_obj;
struct drm_i915_gem_object *obj_priv;
- int ret, i, pinned = 0;
+ struct drm_clip_rect *cliprects = NULL;
+ struct drm_i915_gem_relocation_entry *relocs;
+ int ret, ret2, i, pinned = 0;
uint64_t exec_offset;
- uint32_t seqno, flush_domains;
+ uint32_t seqno, flush_domains, reloc_index;
int pin_tries;
#if WATCH_EXEC
@@ -2551,6 +3088,28 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
goto pre_mutex_err;
}
+ if (args->num_cliprects != 0) {
+ cliprects = drm_calloc(args->num_cliprects, sizeof(*cliprects),
+ DRM_MEM_DRIVER);
+ if (cliprects == NULL)
+ goto pre_mutex_err;
+
+ ret = copy_from_user(cliprects,
+ (struct drm_clip_rect __user *)
+ (uintptr_t) args->cliprects_ptr,
+ sizeof(*cliprects) * args->num_cliprects);
+ if (ret != 0) {
+ DRM_ERROR("copy %d cliprects failed: %d\n",
+ args->num_cliprects, ret);
+ goto pre_mutex_err;
+ }
+ }
+
+ ret = i915_gem_get_relocs_from_user(exec_list, args->buffer_count,
+ &relocs);
+ if (ret != 0)
+ goto pre_mutex_err;
+
mutex_lock(&dev->struct_mutex);
i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -2593,15 +3152,19 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
/* Pin and relocate */
for (pin_tries = 0; ; pin_tries++) {
ret = 0;
+ reloc_index = 0;
+
for (i = 0; i < args->buffer_count; i++) {
object_list[i]->pending_read_domains = 0;
object_list[i]->pending_write_domain = 0;
ret = i915_gem_object_pin_and_relocate(object_list[i],
file_priv,
- &exec_list[i]);
+ &exec_list[i],
+ &relocs[reloc_index]);
if (ret)
break;
pinned = i + 1;
+ reloc_index += exec_list[i].relocation_count;
}
/* success */
if (ret == 0)
@@ -2687,7 +3250,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
#endif
/* Exec the batchbuffer */
- ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset);
+ ret = i915_dispatch_gem_execbuffer(dev, args, cliprects, exec_offset);
if (ret) {
DRM_ERROR("dispatch failed %d\n", ret);
goto err;
@@ -2751,11 +3314,27 @@ err:
args->buffer_count, ret);
}
+ /* Copy the updated relocations out regardless of current error
+ * state. Failure to update the relocs would mean that the next
+ * time userland calls execbuf, it would do so with presumed offset
+ * state that didn't match the actual object state.
+ */
+ ret2 = i915_gem_put_relocs_to_user(exec_list, args->buffer_count,
+ relocs);
+ if (ret2 != 0) {
+ DRM_ERROR("Failed to copy relocations back out: %d\n", ret2);
+
+ if (ret == 0)
+ ret = ret2;
+ }
+
pre_mutex_err:
drm_free(object_list, sizeof(*object_list) * args->buffer_count,
DRM_MEM_DRIVER);
drm_free(exec_list, sizeof(*exec_list) * args->buffer_count,
DRM_MEM_DRIVER);
+ drm_free(cliprects, sizeof(*cliprects) * args->num_cliprects,
+ DRM_MEM_DRIVER);
return ret;
}
@@ -3110,6 +3689,7 @@ i915_gem_idle(struct drm_device *dev)
i915_gem_retire_requests(dev);
+ spin_lock(&dev_priv->mm.active_list_lock);
if (!dev_priv->mm.wedged) {
/* Active and flushing should now be empty as we've
* waited for a sequence higher than any pending execbuffer
@@ -3136,6 +3716,7 @@ i915_gem_idle(struct drm_device *dev)
obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS;
i915_gem_object_move_to_inactive(obj_priv->obj);
}
+ spin_unlock(&dev_priv->mm.active_list_lock);
while (!list_empty(&dev_priv->mm.flushing_list)) {
struct drm_i915_gem_object *obj_priv;
@@ -3192,7 +3773,7 @@ i915_gem_init_hws(struct drm_device *dev)
dev_priv->status_gfx_addr = obj_priv->gtt_offset;
- dev_priv->hw_status_page = kmap(obj_priv->page_list[0]);
+ dev_priv->hw_status_page = kmap(obj_priv->pages[0]);
if (dev_priv->hw_status_page == NULL) {
DRM_ERROR("Failed to map status page.\n");
memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
@@ -3222,7 +3803,7 @@ i915_gem_cleanup_hws(struct drm_device *dev)
obj = dev_priv->hws_obj;
obj_priv = obj->driver_private;
- kunmap(obj_priv->page_list[0]);
+ kunmap(obj_priv->pages[0]);
i915_gem_object_unpin(obj);
drm_gem_object_unreference(obj);
dev_priv->hws_obj = NULL;
@@ -3384,7 +3965,10 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
if (ret != 0)
return ret;
+ spin_lock(&dev_priv->mm.active_list_lock);
BUG_ON(!list_empty(&dev_priv->mm.active_list));
+ spin_unlock(&dev_priv->mm.active_list_lock);
+
BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
BUG_ON(!list_empty(&dev_priv->mm.request_list));
@@ -3428,6 +4012,7 @@ i915_gem_load(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
+ spin_lock_init(&dev_priv->mm.active_list_lock);
INIT_LIST_HEAD(&dev_priv->mm.active_list);
INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
@@ -3525,20 +4110,20 @@ void i915_gem_detach_phys_object(struct drm_device *dev,
if (!obj_priv->phys_obj)
return;
- ret = i915_gem_object_get_page_list(obj);
+ ret = i915_gem_object_get_pages(obj);
if (ret)
goto out;
page_count = obj->size / PAGE_SIZE;
for (i = 0; i < page_count; i++) {
- char *dst = kmap_atomic(obj_priv->page_list[i], KM_USER0);
+ char *dst = kmap_atomic(obj_priv->pages[i], KM_USER0);
char *src = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE);
memcpy(dst, src, PAGE_SIZE);
kunmap_atomic(dst, KM_USER0);
}
- drm_clflush_pages(obj_priv->page_list, page_count);
+ drm_clflush_pages(obj_priv->pages, page_count);
drm_agp_chipset_flush(dev);
out:
obj_priv->phys_obj->cur_obj = NULL;
@@ -3581,7 +4166,7 @@ i915_gem_attach_phys_object(struct drm_device *dev,
obj_priv->phys_obj = dev_priv->mm.phys_objs[id - 1];
obj_priv->phys_obj->cur_obj = obj;
- ret = i915_gem_object_get_page_list(obj);
+ ret = i915_gem_object_get_pages(obj);
if (ret) {
DRM_ERROR("failed to get page list\n");
goto out;
@@ -3590,7 +4175,7 @@ i915_gem_attach_phys_object(struct drm_device *dev,
page_count = obj->size / PAGE_SIZE;
for (i = 0; i < page_count; i++) {
- char *src = kmap_atomic(obj_priv->page_list[i], KM_USER0);
+ char *src = kmap_atomic(obj_priv->pages[i], KM_USER0);
char *dst = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE);
memcpy(dst, src, PAGE_SIZE);
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c
index 131c088f8c8a..8d0b943e2c5a 100644
--- a/drivers/gpu/drm/i915/i915_gem_debug.c
+++ b/drivers/gpu/drm/i915/i915_gem_debug.c
@@ -105,12 +105,14 @@ i915_dump_lru(struct drm_device *dev, const char *where)
struct drm_i915_gem_object *obj_priv;
DRM_INFO("active list %s {\n", where);
+ spin_lock(&dev_priv->mm.active_list_lock);
list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
list)
{
DRM_INFO(" %p: %08x\n", obj_priv,
obj_priv->last_rendering_seqno);
}
+ spin_unlock(&dev_priv->mm.active_list_lock);
DRM_INFO("}\n");
DRM_INFO("flushing list %s {\n", where);
list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c
new file mode 100644
index 000000000000..a1ac0c5e7307
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ * Keith Packard <keithp@keithp.com>
+ *
+ */
+
+#include <linux/seq_file.h>
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+#define DRM_I915_RING_DEBUG 1
+
+
+#if defined(CONFIG_DEBUG_FS)
+
+#define ACTIVE_LIST 1
+#define FLUSHING_LIST 2
+#define INACTIVE_LIST 3
+
+static const char *get_pin_flag(struct drm_i915_gem_object *obj_priv)
+{
+ if (obj_priv->user_pin_count > 0)
+ return "P";
+ else if (obj_priv->pin_count > 0)
+ return "p";
+ else
+ return " ";
+}
+
+static const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv)
+{
+ switch (obj_priv->tiling_mode) {
+ default:
+ case I915_TILING_NONE: return " ";
+ case I915_TILING_X: return "X";
+ case I915_TILING_Y: return "Y";
+ }
+}
+
+static int i915_gem_object_list_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ uintptr_t list = (uintptr_t) node->info_ent->data;
+ struct list_head *head;
+ struct drm_device *dev = node->minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj_priv;
+ spinlock_t *lock = NULL;
+
+ switch (list) {
+ case ACTIVE_LIST:
+ seq_printf(m, "Active:\n");
+ lock = &dev_priv->mm.active_list_lock;
+ spin_lock(lock);
+ head = &dev_priv->mm.active_list;
+ break;
+ case INACTIVE_LIST:
+ seq_printf(m, "Inctive:\n");
+ head = &dev_priv->mm.inactive_list;
+ break;
+ case FLUSHING_LIST:
+ seq_printf(m, "Flushing:\n");
+ head = &dev_priv->mm.flushing_list;
+ break;
+ default:
+ DRM_INFO("Ooops, unexpected list\n");
+ return 0;
+ }
+
+ list_for_each_entry(obj_priv, head, list)
+ {
+ struct drm_gem_object *obj = obj_priv->obj;
+
+ seq_printf(m, " %p: %s %08x %08x %d",
+ obj,
+ get_pin_flag(obj_priv),
+ obj->read_domains, obj->write_domain,
+ obj_priv->last_rendering_seqno);
+
+ if (obj->name)
+ seq_printf(m, " (name: %d)", obj->name);
+ if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
+ seq_printf(m, " (fence: %d\n", obj_priv->fence_reg);
+ seq_printf(m, "\n");
+ }
+
+ if (lock)
+ spin_unlock(lock);
+ return 0;
+}
+
+static int i915_gem_request_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_request *gem_request;
+
+ seq_printf(m, "Request:\n");
+ list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) {
+ seq_printf(m, " %d @ %d\n",
+ gem_request->seqno,
+ (int) (jiffies - gem_request->emitted_jiffies));
+ }
+ return 0;
+}
+
+static int i915_gem_seqno_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+
+ if (dev_priv->hw_status_page != NULL) {
+ seq_printf(m, "Current sequence: %d\n",
+ i915_get_gem_seqno(dev));
+ } else {
+ seq_printf(m, "Current sequence: hws uninitialized\n");
+ }
+ seq_printf(m, "Waiter sequence: %d\n",
+ dev_priv->mm.waiting_gem_seqno);
+ seq_printf(m, "IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno);
+ return 0;
+}
+
+
+static int i915_interrupt_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+
+ seq_printf(m, "Interrupt enable: %08x\n",
+ I915_READ(IER));
+ seq_printf(m, "Interrupt identity: %08x\n",
+ I915_READ(IIR));
+ seq_printf(m, "Interrupt mask: %08x\n",
+ I915_READ(IMR));
+ seq_printf(m, "Pipe A stat: %08x\n",
+ I915_READ(PIPEASTAT));
+ seq_printf(m, "Pipe B stat: %08x\n",
+ I915_READ(PIPEBSTAT));
+ seq_printf(m, "Interrupts received: %d\n",
+ atomic_read(&dev_priv->irq_received));
+ if (dev_priv->hw_status_page != NULL) {
+ seq_printf(m, "Current sequence: %d\n",
+ i915_get_gem_seqno(dev));
+ } else {
+ seq_printf(m, "Current sequence: hws uninitialized\n");
+ }
+ seq_printf(m, "Waiter sequence: %d\n",
+ dev_priv->mm.waiting_gem_seqno);
+ seq_printf(m, "IRQ sequence: %d\n",
+ dev_priv->mm.irq_gem_seqno);
+ return 0;
+}
+
+static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ int i;
+
+ seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start);
+ seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs);
+ for (i = 0; i < dev_priv->num_fence_regs; i++) {
+ struct drm_gem_object *obj = dev_priv->fence_regs[i].obj;
+
+ if (obj == NULL) {
+ seq_printf(m, "Fenced object[%2d] = unused\n", i);
+ } else {
+ struct drm_i915_gem_object *obj_priv;
+
+ obj_priv = obj->driver_private;
+ seq_printf(m, "Fenced object[%2d] = %p: %s "
+ "%08x %08zx %08x %s %08x %08x %d",
+ i, obj, get_pin_flag(obj_priv),
+ obj_priv->gtt_offset,
+ obj->size, obj_priv->stride,
+ get_tiling_flag(obj_priv),
+ obj->read_domains, obj->write_domain,
+ obj_priv->last_rendering_seqno);
+ if (obj->name)
+ seq_printf(m, " (name: %d)", obj->name);
+ seq_printf(m, "\n");
+ }
+ }
+
+ return 0;
+}
+
+static int i915_hws_info(struct seq_file *m, void *data)
+{
+ struct drm_info_node *node = (struct drm_info_node *) m->private;
+ struct drm_device *dev = node->minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ int i;
+ volatile u32 *hws;
+
+ hws = (volatile u32 *)dev_priv->hw_status_page;
+ if (hws == NULL)
+ return 0;
+
+ for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) {
+ seq_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ i * 4,
+ hws[i], hws[i + 1], hws[i + 2], hws[i + 3]);
+ }
+ return 0;
+}
+
+static struct drm_info_list i915_gem_debugfs_list[] = {
+ {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
+ {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
+ {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
+ {"i915_gem_request", i915_gem_request_info, 0},
+ {"i915_gem_seqno", i915_gem_seqno_info, 0},
+ {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
+ {"i915_gem_interrupt", i915_interrupt_info, 0},
+ {"i915_gem_hws", i915_hws_info, 0},
+};
+#define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list)
+
+int i915_gem_debugfs_init(struct drm_minor *minor)
+{
+ return drm_debugfs_create_files(i915_gem_debugfs_list,
+ I915_GEM_DEBUGFS_ENTRIES,
+ minor->debugfs_root, minor);
+}
+
+void i915_gem_debugfs_cleanup(struct drm_minor *minor)
+{
+ drm_debugfs_remove_files(i915_gem_debugfs_list,
+ I915_GEM_DEBUGFS_ENTRIES, minor);
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
diff --git a/drivers/gpu/drm/i915/i915_gem_proc.c b/drivers/gpu/drm/i915/i915_gem_proc.c
deleted file mode 100644
index 4d1b9de0cd8b..000000000000
--- a/drivers/gpu/drm/i915/i915_gem_proc.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright © 2008 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- * Eric Anholt <eric@anholt.net>
- * Keith Packard <keithp@keithp.com>
- *
- */
-
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
-#include "i915_drv.h"
-
-static int i915_gem_active_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv;
- int len = 0;
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
- }
-
- *start = &buf[offset];
- *eof = 0;
- DRM_PROC_PRINT("Active:\n");
- list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
- list)
- {
- struct drm_gem_object *obj = obj_priv->obj;
- if (obj->name) {
- DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
- obj, obj->name,
- obj->read_domains, obj->write_domain,
- obj_priv->last_rendering_seqno);
- } else {
- DRM_PROC_PRINT(" %p: %08x %08x %d\n",
- obj,
- obj->read_domains, obj->write_domain,
- obj_priv->last_rendering_seqno);
- }
- }
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-static int i915_gem_flushing_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv;
- int len = 0;
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
- }
-
- *start = &buf[offset];
- *eof = 0;
- DRM_PROC_PRINT("Flushing:\n");
- list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
- list)
- {
- struct drm_gem_object *obj = obj_priv->obj;
- if (obj->name) {
- DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
- obj, obj->name,
- obj->read_domains, obj->write_domain,
- obj_priv->last_rendering_seqno);
- } else {
- DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
- obj->read_domains, obj->write_domain,
- obj_priv->last_rendering_seqno);
- }
- }
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-static int i915_gem_inactive_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_object *obj_priv;
- int len = 0;
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
- }
-
- *start = &buf[offset];
- *eof = 0;
- DRM_PROC_PRINT("Inactive:\n");
- list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list,
- list)
- {
- struct drm_gem_object *obj = obj_priv->obj;
- if (obj->name) {
- DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
- obj, obj->name,
- obj->read_domains, obj->write_domain,
- obj_priv->last_rendering_seqno);
- } else {
- DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
- obj->read_domains, obj->write_domain,
- obj_priv->last_rendering_seqno);
- }
- }
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-static int i915_gem_request_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
- struct drm_i915_gem_request *gem_request;
- int len = 0;
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
- }
-
- *start = &buf[offset];
- *eof = 0;
- DRM_PROC_PRINT("Request:\n");
- list_for_each_entry(gem_request, &dev_priv->mm.request_list,
- list)
- {
- DRM_PROC_PRINT(" %d @ %d\n",
- gem_request->seqno,
- (int) (jiffies - gem_request->emitted_jiffies));
- }
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-static int i915_gem_seqno_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
- int len = 0;
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
- }
-
- *start = &buf[offset];
- *eof = 0;
- if (dev_priv->hw_status_page != NULL) {
- DRM_PROC_PRINT("Current sequence: %d\n",
- i915_get_gem_seqno(dev));
- } else {
- DRM_PROC_PRINT("Current sequence: hws uninitialized\n");
- }
- DRM_PROC_PRINT("Waiter sequence: %d\n",
- dev_priv->mm.waiting_gem_seqno);
- DRM_PROC_PRINT("IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno);
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-
-static int i915_interrupt_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
- int len = 0;
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
- }
-
- *start = &buf[offset];
- *eof = 0;
- DRM_PROC_PRINT("Interrupt enable: %08x\n",
- I915_READ(IER));
- DRM_PROC_PRINT("Interrupt identity: %08x\n",
- I915_READ(IIR));
- DRM_PROC_PRINT("Interrupt mask: %08x\n",
- I915_READ(IMR));
- DRM_PROC_PRINT("Pipe A stat: %08x\n",
- I915_READ(PIPEASTAT));
- DRM_PROC_PRINT("Pipe B stat: %08x\n",
- I915_READ(PIPEBSTAT));
- DRM_PROC_PRINT("Interrupts received: %d\n",
- atomic_read(&dev_priv->irq_received));
- if (dev_priv->hw_status_page != NULL) {
- DRM_PROC_PRINT("Current sequence: %d\n",
- i915_get_gem_seqno(dev));
- } else {
- DRM_PROC_PRINT("Current sequence: hws uninitialized\n");
- }
- DRM_PROC_PRINT("Waiter sequence: %d\n",
- dev_priv->mm.waiting_gem_seqno);
- DRM_PROC_PRINT("IRQ sequence: %d\n",
- dev_priv->mm.irq_gem_seqno);
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-static int i915_hws_info(char *buf, char **start, off_t offset,
- int request, int *eof, void *data)
-{
- struct drm_minor *minor = (struct drm_minor *) data;
- struct drm_device *dev = minor->dev;
- drm_i915_private_t *dev_priv = dev->dev_private;
- int len = 0, i;
- volatile u32 *hws;
-
- if (offset > DRM_PROC_LIMIT) {
- *eof = 1;
- return 0;
- }
-
- hws = (volatile u32 *)dev_priv->hw_status_page;
- if (hws == NULL) {
- *eof = 1;
- return 0;
- }
-
- *start = &buf[offset];
- *eof = 0;
- for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) {
- DRM_PROC_PRINT("0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
- i * 4,
- hws[i], hws[i + 1], hws[i + 2], hws[i + 3]);
- }
- if (len > request + offset)
- return request;
- *eof = 1;
- return len - offset;
-}
-
-static struct drm_proc_list {
- /** file name */
- const char *name;
- /** proc callback*/
- int (*f) (char *, char **, off_t, int, int *, void *);
-} i915_gem_proc_list[] = {
- {"i915_gem_active", i915_gem_active_info},
- {"i915_gem_flushing", i915_gem_flushing_info},
- {"i915_gem_inactive", i915_gem_inactive_info},
- {"i915_gem_request", i915_gem_request_info},
- {"i915_gem_seqno", i915_gem_seqno_info},
- {"i915_gem_interrupt", i915_interrupt_info},
- {"i915_gem_hws", i915_hws_info},
-};
-
-#define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list)
-
-int i915_gem_proc_init(struct drm_minor *minor)
-{
- struct proc_dir_entry *ent;
- int i, j;
-
- for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) {
- ent = create_proc_entry(i915_gem_proc_list[i].name,
- S_IFREG | S_IRUGO, minor->dev_root);
- if (!ent) {
- DRM_ERROR("Cannot create /proc/dri/.../%s\n",
- i915_gem_proc_list[i].name);
- for (j = 0; j < i; j++)
- remove_proc_entry(i915_gem_proc_list[i].name,
- minor->dev_root);
- return -1;
- }
- ent->read_proc = i915_gem_proc_list[i].f;
- ent->data = minor;
- }
- return 0;
-}
-
-void i915_gem_proc_cleanup(struct drm_minor *minor)
-{
- int i;
-
- if (!minor->dev_root)
- return;
-
- for (i = 0; i < I915_GEM_PROC_ENTRIES; i++)
- remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root);
-}
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 7fb4191ef934..6be3f927c86a 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -96,16 +96,16 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
*/
swizzle_x = I915_BIT_6_SWIZZLE_NONE;
swizzle_y = I915_BIT_6_SWIZZLE_NONE;
- } else if ((!IS_I965G(dev) && !IS_G33(dev)) || IS_I965GM(dev) ||
- IS_GM45(dev)) {
+ } else if (IS_MOBILE(dev)) {
uint32_t dcc;
- /* On 915-945 and GM965, channel interleave by the CPU is
- * determined by DCC. The CPU will alternate based on bit 6
- * in interleaved mode, and the GPU will then also alternate
- * on bit 6, 9, and 10 for X, but the CPU may also optionally
- * alternate based on bit 17 (XOR not disabled and XOR
- * bit == 17).
+ /* On mobile 9xx chipsets, channel interleave by the CPU is
+ * determined by DCC. For single-channel, neither the CPU
+ * nor the GPU do swizzling. For dual channel interleaved,
+ * the GPU's interleave is bit 9 and 10 for X tiled, and bit
+ * 9 for Y tiled. The CPU's interleave is independent, and
+ * can be based on either bit 11 (haven't seen this yet) or
+ * bit 17 (common).
*/
dcc = I915_READ(DCC);
switch (dcc & DCC_ADDRESSING_MODE_MASK) {
@@ -115,19 +115,18 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
swizzle_y = I915_BIT_6_SWIZZLE_NONE;
break;
case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
- if (IS_I915G(dev) || IS_I915GM(dev) ||
- dcc & DCC_CHANNEL_XOR_DISABLE) {
+ if (dcc & DCC_CHANNEL_XOR_DISABLE) {
+ /* This is the base swizzling by the GPU for
+ * tiled buffers.
+ */
swizzle_x = I915_BIT_6_SWIZZLE_9_10;
swizzle_y = I915_BIT_6_SWIZZLE_9;
- } else if ((IS_I965GM(dev) || IS_GM45(dev)) &&
- (dcc & DCC_CHANNEL_XOR_BIT_17) == 0) {
- /* GM965/GM45 does either bit 11 or bit 17
- * swizzling.
- */
+ } else if ((dcc & DCC_CHANNEL_XOR_BIT_17) == 0) {
+ /* Bit 11 swizzling by the CPU in addition. */
swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
swizzle_y = I915_BIT_6_SWIZZLE_9_11;
} else {
- /* Bit 17 or perhaps other swizzling */
+ /* Bit 17 swizzling by the CPU in addition. */
swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
}
@@ -217,6 +216,22 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
else
tile_width = 512;
+ /* check maximum stride & object size */
+ if (IS_I965G(dev)) {
+ /* i965 stores the end address of the gtt mapping in the fence
+ * reg, so dont bother to check the size */
+ if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
+ return false;
+ } else if (IS_I9XX(dev)) {
+ if (stride / tile_width > I830_FENCE_MAX_PITCH_VAL ||
+ size > (I830_FENCE_MAX_SIZE_VAL << 20))
+ return false;
+ } else {
+ if (stride / 128 > I830_FENCE_MAX_PITCH_VAL ||
+ size > (I830_FENCE_MAX_SIZE_VAL << 19))
+ return false;
+ }
+
/* 965+ just needs multiples of tile width */
if (IS_I965G(dev)) {
if (stride & (tile_width - 1))
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 87b6b603469e..ee7ce7b78cf7 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -48,10 +48,6 @@
/** Interrupts that we mask and unmask at runtime. */
#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
-/** These are all of the interrupts used by the driver */
-#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
- I915_INTERRUPT_ENABLE_VAR)
-
#define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\
PIPE_VBLANK_INTERRUPT_STATUS)
@@ -187,6 +183,19 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
return I915_READ(reg);
}
+/*
+ * Handle hotplug events outside the interrupt handler proper.
+ */
+static void i915_hotplug_work_func(struct work_struct *work)
+{
+ drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
+ hotplug_work);
+ struct drm_device *dev = dev_priv->dev;
+
+ /* Just fire off a uevent and let userspace tell us what to do */
+ drm_sysfs_hotplug_event(dev);
+}
+
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
@@ -244,6 +253,20 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
ret = IRQ_HANDLED;
+ /* Consume port. Then clear IIR or we'll miss events */
+ if ((I915_HAS_HOTPLUG(dev)) &&
+ (iir & I915_DISPLAY_PORT_INTERRUPT)) {
+ u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
+
+ DRM_DEBUG("hotplug event received, stat 0x%08x\n",
+ hotplug_status);
+ if (hotplug_status & dev_priv->hotplug_supported_mask)
+ schedule_work(&dev_priv->hotplug_work);
+
+ I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
+ I915_READ(PORT_HOTPLUG_STAT);
+ }
+
I915_WRITE(IIR, iir);
new_iir = I915_READ(IIR); /* Flush posted writes */
@@ -528,17 +551,24 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
atomic_set(&dev_priv->irq_received, 0);
+ if (I915_HAS_HOTPLUG(dev)) {
+ I915_WRITE(PORT_HOTPLUG_EN, 0);
+ I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
+ }
+
I915_WRITE(HWSTAM, 0xeffe);
I915_WRITE(PIPEASTAT, 0);
I915_WRITE(PIPEBSTAT, 0);
I915_WRITE(IMR, 0xffffffff);
I915_WRITE(IER, 0x0);
(void) I915_READ(IER);
+ INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
}
int i915_driver_irq_postinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR;
dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
@@ -550,13 +580,35 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
dev_priv->pipestat[0] = 0;
dev_priv->pipestat[1] = 0;
+ if (I915_HAS_HOTPLUG(dev)) {
+ u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN);
+
+ /* Leave other bits alone */
+ hotplug_en |= HOTPLUG_EN_MASK;
+ I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
+
+ dev_priv->hotplug_supported_mask = CRT_HOTPLUG_INT_STATUS |
+ TV_HOTPLUG_INT_STATUS | SDVOC_HOTPLUG_INT_STATUS |
+ SDVOB_HOTPLUG_INT_STATUS;
+ if (IS_G4X(dev)) {
+ dev_priv->hotplug_supported_mask |=
+ HDMIB_HOTPLUG_INT_STATUS |
+ HDMIC_HOTPLUG_INT_STATUS |
+ HDMID_HOTPLUG_INT_STATUS;
+ }
+ /* Enable in IER... */
+ enable_mask |= I915_DISPLAY_PORT_INTERRUPT;
+ /* and unmask in IMR */
+ i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT);
+ }
+
/* Disable pipe interrupt enables, clear pending pipe status */
I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
/* Clear pending interrupt status */
I915_WRITE(IIR, I915_READ(IIR));
- I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
+ I915_WRITE(IER, enable_mask);
I915_WRITE(IMR, dev_priv->irq_mask_reg);
(void) I915_READ(IER);
@@ -575,6 +627,11 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
dev_priv->vblank_pipe = 0;
+ if (I915_HAS_HOTPLUG(dev)) {
+ I915_WRITE(PORT_HOTPLUG_EN, 0);
+ I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
+ }
+
I915_WRITE(HWSTAM, 0xffffffff);
I915_WRITE(PIPEASTAT, 0);
I915_WRITE(PIPEBSTAT, 0);
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index ff012835a386..69427722d20e 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -26,6 +26,7 @@
*/
#include <linux/acpi.h>
+#include <acpi/video.h>
#include "drmP.h"
#include "i915_drm.h"
@@ -136,6 +137,12 @@ struct opregion_asle {
#define ASLE_CBLV_VALID (1<<31)
+#define ACPI_OTHER_OUTPUT (0<<8)
+#define ACPI_VGA_OUTPUT (1<<8)
+#define ACPI_TV_OUTPUT (2<<8)
+#define ACPI_DIGITAL_OUTPUT (3<<8)
+#define ACPI_LVDS_OUTPUT (4<<8)
+
static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -282,7 +289,58 @@ static struct notifier_block intel_opregion_notifier = {
.notifier_call = intel_opregion_video_event,
};
-int intel_opregion_init(struct drm_device *dev)
+/*
+ * Initialise the DIDL field in opregion. This passes a list of devices to
+ * the firmware. Values are defined by section B.4.2 of the ACPI specification
+ * (version 3)
+ */
+
+static void intel_didl_outputs(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_opregion *opregion = &dev_priv->opregion;
+ struct drm_connector *connector;
+ int i = 0;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ int output_type = ACPI_OTHER_OUTPUT;
+ if (i >= 8) {
+ dev_printk (KERN_ERR, &dev->pdev->dev,
+ "More than 8 outputs detected\n");
+ return;
+ }
+ switch (connector->connector_type) {
+ case DRM_MODE_CONNECTOR_VGA:
+ case DRM_MODE_CONNECTOR_DVIA:
+ output_type = ACPI_VGA_OUTPUT;
+ break;
+ case DRM_MODE_CONNECTOR_Composite:
+ case DRM_MODE_CONNECTOR_SVIDEO:
+ case DRM_MODE_CONNECTOR_Component:
+ case DRM_MODE_CONNECTOR_9PinDIN:
+ output_type = ACPI_TV_OUTPUT;
+ break;
+ case DRM_MODE_CONNECTOR_DVII:
+ case DRM_MODE_CONNECTOR_DVID:
+ case DRM_MODE_CONNECTOR_DisplayPort:
+ case DRM_MODE_CONNECTOR_HDMIA:
+ case DRM_MODE_CONNECTOR_HDMIB:
+ output_type = ACPI_DIGITAL_OUTPUT;
+ break;
+ case DRM_MODE_CONNECTOR_LVDS:
+ output_type = ACPI_LVDS_OUTPUT;
+ break;
+ }
+ opregion->acpi->didl[i] |= (1<<31) | output_type | i;
+ i++;
+ }
+
+ /* If fewer than 8 outputs, the list must be null terminated */
+ if (i < 8)
+ opregion->acpi->didl[i] = 0;
+}
+
+int intel_opregion_init(struct drm_device *dev, int resume)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_opregion *opregion = &dev_priv->opregion;
@@ -312,6 +370,11 @@ int intel_opregion_init(struct drm_device *dev)
if (mboxes & MBOX_ACPI) {
DRM_DEBUG("Public ACPI methods supported\n");
opregion->acpi = base + OPREGION_ACPI_OFFSET;
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ intel_didl_outputs(dev);
+ if (!resume)
+ acpi_video_register();
+ }
} else {
DRM_DEBUG("Public ACPI methods not supported\n");
err = -ENOTSUPP;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 90600d899413..e805b590ae71 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -190,6 +190,8 @@
#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8)
#define I830_FENCE_PITCH_SHIFT 4
#define I830_FENCE_REG_VALID (1<<0)
+#define I830_FENCE_MAX_PITCH_VAL 0x10
+#define I830_FENCE_MAX_SIZE_VAL (1<<8)
#define I915_FENCE_START_MASK 0x0ff00000
#define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8)
@@ -198,6 +200,7 @@
#define I965_FENCE_PITCH_SHIFT 2
#define I965_FENCE_TILING_Y_SHIFT 1
#define I965_FENCE_REG_VALID (1<<0)
+#define I965_FENCE_MAX_PITCH_VAL 0x0400
/*
* Instruction and interrupt control regs
@@ -359,6 +362,7 @@
#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
+#define DPLL_FPA01_P1_POST_DIV_MASK_IGD 0x00ff8000 /* IGD */
#define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
#define I915_CRC_ERROR_ENABLE (1UL<<29)
@@ -435,6 +439,7 @@
*/
#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
#define DPLL_FPA01_P1_POST_DIV_SHIFT 16
+#define DPLL_FPA01_P1_POST_DIV_SHIFT_IGD 15
/* i830, required in DVO non-gang */
#define PLL_P2_DIVIDE_BY_4 (1 << 23)
#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
@@ -501,10 +506,12 @@
#define FPB0 0x06048
#define FPB1 0x0604c
#define FP_N_DIV_MASK 0x003f0000
+#define FP_N_IGD_DIV_MASK 0x00ff0000
#define FP_N_DIV_SHIFT 16
#define FP_M1_DIV_MASK 0x00003f00
#define FP_M1_DIV_SHIFT 8
#define FP_M2_DIV_MASK 0x0000003f
+#define FP_M2_IGD_DIV_MASK 0x000000ff
#define FP_M2_DIV_SHIFT 0
#define DPLL_TEST 0x606c
#define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
@@ -629,6 +636,30 @@
#define TV_HOTPLUG_INT_EN (1 << 18)
#define CRT_HOTPLUG_INT_EN (1 << 9)
#define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
+#define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8)
+/* must use period 64 on GM45 according to docs */
+#define CRT_HOTPLUG_ACTIVATION_PERIOD_64 (1 << 8)
+#define CRT_HOTPLUG_DAC_ON_TIME_2M (0 << 7)
+#define CRT_HOTPLUG_DAC_ON_TIME_4M (1 << 7)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_40 (0 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_50 (1 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_60 (2 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_70 (3 << 5)
+#define CRT_HOTPLUG_VOLTAGE_COMPARE_MASK (3 << 5)
+#define CRT_HOTPLUG_DETECT_DELAY_1G (0 << 4)
+#define CRT_HOTPLUG_DETECT_DELAY_2G (1 << 4)
+#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2)
+#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2)
+#define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */
+#define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f
+#define HOTPLUG_EN_MASK (HDMIB_HOTPLUG_INT_EN | \
+ HDMIC_HOTPLUG_INT_EN | \
+ HDMID_HOTPLUG_INT_EN | \
+ SDVOB_HOTPLUG_INT_EN | \
+ SDVOC_HOTPLUG_INT_EN | \
+ TV_HOTPLUG_INT_EN | \
+ CRT_HOTPLUG_INT_EN)
+
#define PORT_HOTPLUG_STAT 0x61114
#define HDMIB_HOTPLUG_INT_STATUS (1 << 29)
@@ -856,7 +887,7 @@
*/
# define TV_ENC_C0_FIX (1 << 10)
/** Bits that must be preserved by software */
-# define TV_CTL_SAVE ((3 << 8) | (3 << 6))
+# define TV_CTL_SAVE ((1 << 11) | (3 << 9) | (7 << 6) | 0xf)
# define TV_FUSE_STATE_MASK (3 << 4)
/** Read-only state that reports all features enabled */
# define TV_FUSE_STATE_ENABLED (0 << 4)
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 5ea715ace3a0..de621aad85b5 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -162,13 +162,13 @@ struct bdb_lvds_options {
u8 panel_type;
u8 rsvd1;
/* LVDS capabilities, stored in a dword */
- u8 rsvd2:1;
- u8 lvds_edid:1;
- u8 pixel_dither:1;
- u8 pfit_ratio_auto:1;
- u8 pfit_gfx_mode_enhanced:1;
- u8 pfit_text_mode_enhanced:1;
u8 pfit_mode:2;
+ u8 pfit_text_mode_enhanced:1;
+ u8 pfit_gfx_mode_enhanced:1;
+ u8 pfit_ratio_auto:1;
+ u8 pixel_dither:1;
+ u8 lvds_edid:1;
+ u8 rsvd2:1;
u8 rsvd4;
} __attribute__((packed));
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index dcaed3466e83..9bdd959260a5 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -41,7 +41,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
temp = I915_READ(ADPA);
temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
- temp &= ~ADPA_DAC_ENABLE;
+ temp |= ADPA_DAC_ENABLE;
switch(mode) {
case DRM_MODE_DPMS_ON:
@@ -64,11 +64,21 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
static int intel_crt_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
+ struct drm_device *dev = connector->dev;
+
+ int max_clock = 0;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
- if (mode->clock > 400000 || mode->clock < 25000)
- return MODE_CLOCK_RANGE;
+ if (mode->clock < 25000)
+ return MODE_CLOCK_LOW;
+
+ if (!IS_I9XX(dev))
+ max_clock = 350000;
+ else
+ max_clock = 400000;
+ if (mode->clock > max_clock)
+ return MODE_CLOCK_HIGH;
return MODE_OK;
}
@@ -113,10 +123,13 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
adpa |= ADPA_VSYNC_ACTIVE_HIGH;
- if (intel_crtc->pipe == 0)
+ if (intel_crtc->pipe == 0) {
adpa |= ADPA_PIPE_A_SELECT;
- else
+ I915_WRITE(BCLRPAT_A, 0);
+ } else {
adpa |= ADPA_PIPE_B_SELECT;
+ I915_WRITE(BCLRPAT_B, 0);
+ }
I915_WRITE(ADPA, adpa);
}
@@ -133,20 +146,39 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- u32 temp;
-
- unsigned long timeout = jiffies + msecs_to_jiffies(1000);
-
- temp = I915_READ(PORT_HOTPLUG_EN);
-
- I915_WRITE(PORT_HOTPLUG_EN,
- temp | CRT_HOTPLUG_FORCE_DETECT | (1 << 5));
+ u32 hotplug_en;
+ int i, tries = 0;
+ /*
+ * On 4 series desktop, CRT detect sequence need to be done twice
+ * to get a reliable result.
+ */
- do {
- if (!(I915_READ(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT))
- break;
- msleep(1);
- } while (time_after(timeout, jiffies));
+ if (IS_G4X(dev) && !IS_GM45(dev))
+ tries = 2;
+ else
+ tries = 1;
+ hotplug_en = I915_READ(PORT_HOTPLUG_EN);
+ hotplug_en &= CRT_FORCE_HOTPLUG_MASK;
+ hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
+
+ if (IS_GM45(dev))
+ hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
+
+ hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50;
+
+ for (i = 0; i < tries ; i++) {
+ unsigned long timeout;
+ /* turn on the FORCE_DETECT */
+ I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
+ timeout = jiffies + msecs_to_jiffies(1000);
+ /* wait for FORCE_DETECT to go off */
+ do {
+ if (!(I915_READ(PORT_HOTPLUG_EN) &
+ CRT_HOTPLUG_FORCE_DETECT))
+ break;
+ msleep(1);
+ } while (time_after(timeout, jiffies));
+ }
if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
CRT_HOTPLUG_MONITOR_COLOR)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a2834276cb38..64773ce52964 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -56,11 +56,13 @@ typedef struct {
} intel_p2_t;
#define INTEL_P2_NUM 2
-
-typedef struct {
+typedef struct intel_limit intel_limit_t;
+struct intel_limit {
intel_range_t dot, vco, n, m, m1, m2, p, p1;
intel_p2_t p2;
-} intel_limit_t;
+ bool (* find_pll)(const intel_limit_t *, struct drm_crtc *,
+ int, int, intel_clock_t *);
+};
#define I8XX_DOT_MIN 25000
#define I8XX_DOT_MAX 350000
@@ -90,18 +92,32 @@ typedef struct {
#define I9XX_DOT_MAX 400000
#define I9XX_VCO_MIN 1400000
#define I9XX_VCO_MAX 2800000
+#define IGD_VCO_MIN 1700000
+#define IGD_VCO_MAX 3500000
#define I9XX_N_MIN 1
#define I9XX_N_MAX 6
+/* IGD's Ncounter is a ring counter */
+#define IGD_N_MIN 3
+#define IGD_N_MAX 6
#define I9XX_M_MIN 70
#define I9XX_M_MAX 120
+#define IGD_M_MIN 2
+#define IGD_M_MAX 256
#define I9XX_M1_MIN 10
#define I9XX_M1_MAX 22
#define I9XX_M2_MIN 5
#define I9XX_M2_MAX 9
+/* IGD M1 is reserved, and must be 0 */
+#define IGD_M1_MIN 0
+#define IGD_M1_MAX 0
+#define IGD_M2_MIN 0
+#define IGD_M2_MAX 254
#define I9XX_P_SDVO_DAC_MIN 5
#define I9XX_P_SDVO_DAC_MAX 80
#define I9XX_P_LVDS_MIN 7
#define I9XX_P_LVDS_MAX 98
+#define IGD_P_LVDS_MIN 7
+#define IGD_P_LVDS_MAX 112
#define I9XX_P1_MIN 1
#define I9XX_P1_MAX 8
#define I9XX_P2_SDVO_DAC_SLOW 10
@@ -115,6 +131,97 @@ typedef struct {
#define INTEL_LIMIT_I8XX_LVDS 1
#define INTEL_LIMIT_I9XX_SDVO_DAC 2
#define INTEL_LIMIT_I9XX_LVDS 3
+#define INTEL_LIMIT_G4X_SDVO 4
+#define INTEL_LIMIT_G4X_HDMI_DAC 5
+#define INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS 6
+#define INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS 7
+#define INTEL_LIMIT_IGD_SDVO_DAC 8
+#define INTEL_LIMIT_IGD_LVDS 9
+
+/*The parameter is for SDVO on G4x platform*/
+#define G4X_DOT_SDVO_MIN 25000
+#define G4X_DOT_SDVO_MAX 270000
+#define G4X_VCO_MIN 1750000
+#define G4X_VCO_MAX 3500000
+#define G4X_N_SDVO_MIN 1
+#define G4X_N_SDVO_MAX 4
+#define G4X_M_SDVO_MIN 104
+#define G4X_M_SDVO_MAX 138
+#define G4X_M1_SDVO_MIN 17
+#define G4X_M1_SDVO_MAX 23
+#define G4X_M2_SDVO_MIN 5
+#define G4X_M2_SDVO_MAX 11
+#define G4X_P_SDVO_MIN 10
+#define G4X_P_SDVO_MAX 30
+#define G4X_P1_SDVO_MIN 1
+#define G4X_P1_SDVO_MAX 3
+#define G4X_P2_SDVO_SLOW 10
+#define G4X_P2_SDVO_FAST 10
+#define G4X_P2_SDVO_LIMIT 270000
+
+/*The parameter is for HDMI_DAC on G4x platform*/
+#define G4X_DOT_HDMI_DAC_MIN 22000
+#define G4X_DOT_HDMI_DAC_MAX 400000
+#define G4X_N_HDMI_DAC_MIN 1
+#define G4X_N_HDMI_DAC_MAX 4
+#define G4X_M_HDMI_DAC_MIN 104
+#define G4X_M_HDMI_DAC_MAX 138
+#define G4X_M1_HDMI_DAC_MIN 16
+#define G4X_M1_HDMI_DAC_MAX 23
+#define G4X_M2_HDMI_DAC_MIN 5
+#define G4X_M2_HDMI_DAC_MAX 11
+#define G4X_P_HDMI_DAC_MIN 5
+#define G4X_P_HDMI_DAC_MAX 80
+#define G4X_P1_HDMI_DAC_MIN 1
+#define G4X_P1_HDMI_DAC_MAX 8
+#define G4X_P2_HDMI_DAC_SLOW 10
+#define G4X_P2_HDMI_DAC_FAST 5
+#define G4X_P2_HDMI_DAC_LIMIT 165000
+
+/*The parameter is for SINGLE_CHANNEL_LVDS on G4x platform*/
+#define G4X_DOT_SINGLE_CHANNEL_LVDS_MIN 20000
+#define G4X_DOT_SINGLE_CHANNEL_LVDS_MAX 115000
+#define G4X_N_SINGLE_CHANNEL_LVDS_MIN 1
+#define G4X_N_SINGLE_CHANNEL_LVDS_MAX 3
+#define G4X_M_SINGLE_CHANNEL_LVDS_MIN 104
+#define G4X_M_SINGLE_CHANNEL_LVDS_MAX 138
+#define G4X_M1_SINGLE_CHANNEL_LVDS_MIN 17
+#define G4X_M1_SINGLE_CHANNEL_LVDS_MAX 23
+#define G4X_M2_SINGLE_CHANNEL_LVDS_MIN 5
+#define G4X_M2_SINGLE_CHANNEL_LVDS_MAX 11
+#define G4X_P_SINGLE_CHANNEL_LVDS_MIN 28
+#define G4X_P_SINGLE_CHANNEL_LVDS_MAX 112
+#define G4X_P1_SINGLE_CHANNEL_LVDS_MIN 2
+#define G4X_P1_SINGLE_CHANNEL_LVDS_MAX 8
+#define G4X_P2_SINGLE_CHANNEL_LVDS_SLOW 14
+#define G4X_P2_SINGLE_CHANNEL_LVDS_FAST 14
+#define G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT 0
+
+/*The parameter is for DUAL_CHANNEL_LVDS on G4x platform*/
+#define G4X_DOT_DUAL_CHANNEL_LVDS_MIN 80000
+#define G4X_DOT_DUAL_CHANNEL_LVDS_MAX 224000
+#define G4X_N_DUAL_CHANNEL_LVDS_MIN 1
+#define G4X_N_DUAL_CHANNEL_LVDS_MAX 3
+#define G4X_M_DUAL_CHANNEL_LVDS_MIN 104
+#define G4X_M_DUAL_CHANNEL_LVDS_MAX 138
+#define G4X_M1_DUAL_CHANNEL_LVDS_MIN 17
+#define G4X_M1_DUAL_CHANNEL_LVDS_MAX 23
+#define G4X_M2_DUAL_CHANNEL_LVDS_MIN 5
+#define G4X_M2_DUAL_CHANNEL_LVDS_MAX 11
+#define G4X_P_DUAL_CHANNEL_LVDS_MIN 14
+#define G4X_P_DUAL_CHANNEL_LVDS_MAX 42
+#define G4X_P1_DUAL_CHANNEL_LVDS_MIN 2
+#define G4X_P1_DUAL_CHANNEL_LVDS_MAX 6
+#define G4X_P2_DUAL_CHANNEL_LVDS_SLOW 7
+#define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7
+#define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0
+
+static bool
+intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+ int target, int refclk, intel_clock_t *best_clock);
+static bool
+intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+ int target, int refclk, intel_clock_t *best_clock);
static const intel_limit_t intel_limits[] = {
{ /* INTEL_LIMIT_I8XX_DVO_DAC */
@@ -128,6 +235,7 @@ static const intel_limit_t intel_limits[] = {
.p1 = { .min = I8XX_P1_MIN, .max = I8XX_P1_MAX },
.p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
.p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST },
+ .find_pll = intel_find_best_PLL,
},
{ /* INTEL_LIMIT_I8XX_LVDS */
.dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
@@ -140,6 +248,7 @@ static const intel_limit_t intel_limits[] = {
.p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX },
.p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
.p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST },
+ .find_pll = intel_find_best_PLL,
},
{ /* INTEL_LIMIT_I9XX_SDVO_DAC */
.dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
@@ -152,6 +261,7 @@ static const intel_limit_t intel_limits[] = {
.p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
.p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
.p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
+ .find_pll = intel_find_best_PLL,
},
{ /* INTEL_LIMIT_I9XX_LVDS */
.dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
@@ -167,19 +277,157 @@ static const intel_limit_t intel_limits[] = {
*/
.p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
.p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST },
+ .find_pll = intel_find_best_PLL,
+ },
+ /* below parameter and function is for G4X Chipset Family*/
+ { /* INTEL_LIMIT_G4X_SDVO */
+ .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX },
+ .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX},
+ .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX },
+ .m = { .min = G4X_M_SDVO_MIN, .max = G4X_M_SDVO_MAX },
+ .m1 = { .min = G4X_M1_SDVO_MIN, .max = G4X_M1_SDVO_MAX },
+ .m2 = { .min = G4X_M2_SDVO_MIN, .max = G4X_M2_SDVO_MAX },
+ .p = { .min = G4X_P_SDVO_MIN, .max = G4X_P_SDVO_MAX },
+ .p1 = { .min = G4X_P1_SDVO_MIN, .max = G4X_P1_SDVO_MAX},
+ .p2 = { .dot_limit = G4X_P2_SDVO_LIMIT,
+ .p2_slow = G4X_P2_SDVO_SLOW,
+ .p2_fast = G4X_P2_SDVO_FAST
+ },
+ .find_pll = intel_g4x_find_best_PLL,
+ },
+ { /* INTEL_LIMIT_G4X_HDMI_DAC */
+ .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX },
+ .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX},
+ .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX },
+ .m = { .min = G4X_M_HDMI_DAC_MIN, .max = G4X_M_HDMI_DAC_MAX },
+ .m1 = { .min = G4X_M1_HDMI_DAC_MIN, .max = G4X_M1_HDMI_DAC_MAX },
+ .m2 = { .min = G4X_M2_HDMI_DAC_MIN, .max = G4X_M2_HDMI_DAC_MAX },
+ .p = { .min = G4X_P_HDMI_DAC_MIN, .max = G4X_P_HDMI_DAC_MAX },
+ .p1 = { .min = G4X_P1_HDMI_DAC_MIN, .max = G4X_P1_HDMI_DAC_MAX},
+ .p2 = { .dot_limit = G4X_P2_HDMI_DAC_LIMIT,
+ .p2_slow = G4X_P2_HDMI_DAC_SLOW,
+ .p2_fast = G4X_P2_HDMI_DAC_FAST
+ },
+ .find_pll = intel_g4x_find_best_PLL,
+ },
+ { /* INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS */
+ .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN,
+ .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX },
+ .vco = { .min = G4X_VCO_MIN,
+ .max = G4X_VCO_MAX },
+ .n = { .min = G4X_N_SINGLE_CHANNEL_LVDS_MIN,
+ .max = G4X_N_SINGLE_CHANNEL_LVDS_MAX },
+ .m = { .min = G4X_M_SINGLE_CHANNEL_LVDS_MIN,
+ .max = G4X_M_SINGLE_CHANNEL_LVDS_MAX },
+ .m1 = { .min = G4X_M1_SINGLE_CHANNEL_LVDS_MIN,
+ .max = G4X_M1_SINGLE_CHANNEL_LVDS_MAX },
+ .m2 = { .min = G4X_M2_SINGLE_CHANNEL_LVDS_MIN,
+ .max = G4X_M2_SINGLE_CHANNEL_LVDS_MAX },
+ .p = { .min = G4X_P_SINGLE_CHANNEL_LVDS_MIN,
+ .max = G4X_P_SINGLE_CHANNEL_LVDS_MAX },
+ .p1 = { .min = G4X_P1_SINGLE_CHANNEL_LVDS_MIN,
+ .max = G4X_P1_SINGLE_CHANNEL_LVDS_MAX },
+ .p2 = { .dot_limit = G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT,
+ .p2_slow = G4X_P2_SINGLE_CHANNEL_LVDS_SLOW,
+ .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST
+ },
+ .find_pll = intel_g4x_find_best_PLL,
+ },
+ { /* INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS */
+ .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN,
+ .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX },
+ .vco = { .min = G4X_VCO_MIN,
+ .max = G4X_VCO_MAX },
+ .n = { .min = G4X_N_DUAL_CHANNEL_LVDS_MIN,
+ .max = G4X_N_DUAL_CHANNEL_LVDS_MAX },
+ .m = { .min = G4X_M_DUAL_CHANNEL_LVDS_MIN,
+ .max = G4X_M_DUAL_CHANNEL_LVDS_MAX },
+ .m1 = { .min = G4X_M1_DUAL_CHANNEL_LVDS_MIN,
+ .max = G4X_M1_DUAL_CHANNEL_LVDS_MAX },
+ .m2 = { .min = G4X_M2_DUAL_CHANNEL_LVDS_MIN,
+ .max = G4X_M2_DUAL_CHANNEL_LVDS_MAX },
+ .p = { .min = G4X_P_DUAL_CHANNEL_LVDS_MIN,
+ .max = G4X_P_DUAL_CHANNEL_LVDS_MAX },
+ .p1 = { .min = G4X_P1_DUAL_CHANNEL_LVDS_MIN,
+ .max = G4X_P1_DUAL_CHANNEL_LVDS_MAX },
+ .p2 = { .dot_limit = G4X_P2_DUAL_CHANNEL_LVDS_LIMIT,
+ .p2_slow = G4X_P2_DUAL_CHANNEL_LVDS_SLOW,
+ .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST
+ },
+ .find_pll = intel_g4x_find_best_PLL,
+ },
+ { /* INTEL_LIMIT_IGD_SDVO */
+ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
+ .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX },
+ .n = { .min = IGD_N_MIN, .max = IGD_N_MAX },
+ .m = { .min = IGD_M_MIN, .max = IGD_M_MAX },
+ .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX },
+ .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX },
+ .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX },
+ .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
+ .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
+ .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
},
+ { /* INTEL_LIMIT_IGD_LVDS */
+ .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
+ .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX },
+ .n = { .min = IGD_N_MIN, .max = IGD_N_MAX },
+ .m = { .min = IGD_M_MIN, .max = IGD_M_MAX },
+ .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX },
+ .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX },
+ .p = { .min = IGD_P_LVDS_MIN, .max = IGD_P_LVDS_MAX },
+ .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
+ /* IGD only supports single-channel mode. */
+ .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
+ .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW },
+ },
+
};
+static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ const intel_limit_t *limit;
+
+ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+ if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
+ LVDS_CLKB_POWER_UP)
+ /* LVDS with dual channel */
+ limit = &intel_limits
+ [INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS];
+ else
+ /* LVDS with dual channel */
+ limit = &intel_limits
+ [INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS];
+ } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) ||
+ intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) {
+ limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC];
+ } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) {
+ limit = &intel_limits[INTEL_LIMIT_G4X_SDVO];
+ } else /* The option is for other outputs */
+ limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
+
+ return limit;
+}
+
static const intel_limit_t *intel_limit(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
const intel_limit_t *limit;
- if (IS_I9XX(dev)) {
+ if (IS_G4X(dev)) {
+ limit = intel_g4x_limit(crtc);
+ } else if (IS_I9XX(dev) && !IS_IGD(dev)) {
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS];
else
limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
+ } else if (IS_IGD(dev)) {
+ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
+ limit = &intel_limits[INTEL_LIMIT_IGD_LVDS];
+ else
+ limit = &intel_limits[INTEL_LIMIT_IGD_SDVO_DAC];
} else {
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS];
@@ -189,8 +437,21 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc)
return limit;
}
-static void intel_clock(int refclk, intel_clock_t *clock)
+/* m1 is reserved as 0 in IGD, n is a ring counter */
+static void igd_clock(int refclk, intel_clock_t *clock)
+{
+ clock->m = clock->m2 + 2;
+ clock->p = clock->p1 * clock->p2;
+ clock->vco = refclk * clock->m / clock->n;
+ clock->dot = clock->vco / clock->p;
+}
+
+static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock)
{
+ if (IS_IGD(dev)) {
+ igd_clock(refclk, clock);
+ return;
+ }
clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
clock->p = clock->p1 * clock->p2;
clock->vco = refclk * clock->m / (clock->n + 2);
@@ -226,6 +487,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock)
{
const intel_limit_t *limit = intel_limit (crtc);
+ struct drm_device *dev = crtc->dev;
if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
INTELPllInvalid ("p1 out of range\n");
@@ -235,7 +497,7 @@ static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock)
INTELPllInvalid ("m2 out of range\n");
if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
INTELPllInvalid ("m1 out of range\n");
- if (clock->m1 <= clock->m2)
+ if (clock->m1 <= clock->m2 && !IS_IGD(dev))
INTELPllInvalid ("m1 <= m2\n");
if (clock->m < limit->m.min || limit->m.max < clock->m)
INTELPllInvalid ("m out of range\n");
@@ -252,18 +514,14 @@ static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock)
return true;
}
-/**
- * Returns a set of divisors for the desired target clock with the given
- * refclk, or FALSE. The returned values represent the clock equation:
- * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
- */
-static bool intel_find_best_PLL(struct drm_crtc *crtc, int target,
- int refclk, intel_clock_t *best_clock)
+static bool
+intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+ int target, int refclk, intel_clock_t *best_clock)
+
{
struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
intel_clock_t clock;
- const intel_limit_t *limit = intel_limit(crtc);
int err = target;
if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
@@ -289,15 +547,17 @@ static bool intel_find_best_PLL(struct drm_crtc *crtc, int target,
memset (best_clock, 0, sizeof (*best_clock));
for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
- for (clock.m2 = limit->m2.min; clock.m2 < clock.m1 &&
- clock.m2 <= limit->m2.max; clock.m2++) {
+ for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
+ /* m1 is always 0 in IGD */
+ if (clock.m2 >= clock.m1 && !IS_IGD(dev))
+ break;
for (clock.n = limit->n.min; clock.n <= limit->n.max;
clock.n++) {
for (clock.p1 = limit->p1.min;
clock.p1 <= limit->p1.max; clock.p1++) {
int this_err;
- intel_clock(refclk, &clock);
+ intel_clock(dev, refclk, &clock);
if (!intel_PLL_is_valid(crtc, &clock))
continue;
@@ -315,11 +575,68 @@ static bool intel_find_best_PLL(struct drm_crtc *crtc, int target,
return (err != target);
}
+static bool
+intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+ int target, int refclk, intel_clock_t *best_clock)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ intel_clock_t clock;
+ int max_n;
+ bool found;
+ /* approximately equals target * 0.00488 */
+ int err_most = (target >> 8) + (target >> 10);
+ found = false;
+
+ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+ if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
+ LVDS_CLKB_POWER_UP)
+ clock.p2 = limit->p2.p2_fast;
+ else
+ clock.p2 = limit->p2.p2_slow;
+ } else {
+ if (target < limit->p2.dot_limit)
+ clock.p2 = limit->p2.p2_slow;
+ else
+ clock.p2 = limit->p2.p2_fast;
+ }
+
+ memset(best_clock, 0, sizeof(*best_clock));
+ max_n = limit->n.max;
+ /* based on hardware requriment prefer smaller n to precision */
+ for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
+ /* based on hardware requirment prefere larger m1,m2, p1 */
+ for (clock.m1 = limit->m1.max;
+ clock.m1 >= limit->m1.min; clock.m1--) {
+ for (clock.m2 = limit->m2.max;
+ clock.m2 >= limit->m2.min; clock.m2--) {
+ for (clock.p1 = limit->p1.max;
+ clock.p1 >= limit->p1.min; clock.p1--) {
+ int this_err;
+
+ intel_clock(dev, refclk, &clock);
+ if (!intel_PLL_is_valid(crtc, &clock))
+ continue;
+ this_err = abs(clock.dot - target) ;
+ if (this_err < err_most) {
+ *best_clock = clock;
+ err_most = this_err;
+ max_n = clock.n;
+ found = true;
+ }
+ }
+ }
+ }
+ }
+
+ return found;
+}
+
void
intel_wait_for_vblank(struct drm_device *dev)
{
/* Wait for 20ms, i.e. one cycle at 50hz. */
- udelay(20000);
+ mdelay(20);
}
static int
@@ -634,7 +951,7 @@ static int intel_get_core_clock_speed(struct drm_device *dev)
return 400000;
else if (IS_I915G(dev))
return 333000;
- else if (IS_I945GM(dev) || IS_845G(dev))
+ else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev))
return 200000;
else if (IS_I915GM(dev)) {
u16 gcfgc = 0;
@@ -733,6 +1050,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
bool is_crt = false, is_lvds = false, is_tv = false;
struct drm_mode_config *mode_config = &dev->mode_config;
struct drm_connector *connector;
+ const intel_limit_t *limit;
int ret;
drm_vblank_pre_modeset(dev, pipe);
@@ -776,13 +1094,42 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
refclk = 48000;
}
- ok = intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock);
+ /*
+ * Returns a set of divisors for the desired target clock with the given
+ * refclk, or FALSE. The returned values represent the clock equation:
+ * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+ */
+ limit = intel_limit(crtc);
+ ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock);
if (!ok) {
DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL;
}
- fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
+ /* SDVO TV has fixed PLL values depend on its clock range,
+ this mirrors vbios setting. */
+ if (is_sdvo && is_tv) {
+ if (adjusted_mode->clock >= 100000
+ && adjusted_mode->clock < 140500) {
+ clock.p1 = 2;
+ clock.p2 = 10;
+ clock.n = 3;
+ clock.m1 = 16;
+ clock.m2 = 8;
+ } else if (adjusted_mode->clock >= 140500
+ && adjusted_mode->clock <= 200000) {
+ clock.p1 = 1;
+ clock.p2 = 10;
+ clock.n = 6;
+ clock.m1 = 12;
+ clock.m2 = 8;
+ }
+ }
+
+ if (IS_IGD(dev))
+ fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
+ else
+ fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
dpll = DPLL_VGA_MODE_DIS;
if (IS_I9XX(dev)) {
@@ -799,7 +1146,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
}
/* compute bitmask from p1 value */
- dpll |= (1 << (clock.p1 - 1)) << 16;
+ if (IS_IGD(dev))
+ dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_IGD;
+ else
+ dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
switch (clock.p2) {
case 5:
dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
@@ -1279,10 +1629,20 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
fp = I915_READ((pipe == 0) ? FPA1 : FPB1);
clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
- clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
- clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
+ if (IS_IGD(dev)) {
+ clock.n = ffs((fp & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1;
+ clock.m2 = (fp & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT;
+ } else {
+ clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
+ clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
+ }
+
if (IS_I9XX(dev)) {
- clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
+ if (IS_IGD(dev))
+ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_IGD) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT_IGD);
+ else
+ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
DPLL_FPA01_P1_POST_DIV_SHIFT);
switch (dpll & DPLL_MODE_MASK) {
@@ -1301,7 +1661,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
}
/* XXX: Handle the 100Mhz refclk */
- intel_clock(96000, &clock);
+ intel_clock(dev, 96000, &clock);
} else {
bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN);
@@ -1313,9 +1673,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
if ((dpll & PLL_REF_INPUT_MASK) ==
PLLB_REF_INPUT_SPREADSPECTRUMIN) {
/* XXX: might not be 66MHz */
- intel_clock(66000, &clock);
+ intel_clock(dev, 66000, &clock);
} else
- intel_clock(48000, &clock);
+ intel_clock(dev, 48000, &clock);
} else {
if (dpll & PLL_P1_DIVIDE_BY_TWO)
clock.p1 = 2;
@@ -1328,7 +1688,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
else
clock.p2 = 2;
- intel_clock(48000, &clock);
+ intel_clock(dev, 48000, &clock);
}
}
@@ -1474,13 +1834,21 @@ static void intel_setup_outputs(struct drm_device *dev)
if (IS_I9XX(dev)) {
int found;
+ u32 reg;
if (I915_READ(SDVOB) & SDVO_DETECTED) {
found = intel_sdvo_init(dev, SDVOB);
if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
intel_hdmi_init(dev, SDVOB);
}
- if (!IS_G4X(dev) || (I915_READ(SDVOB) & SDVO_DETECTED)) {
+
+ /* Before G4X SDVOC doesn't have its own detect register */
+ if (IS_G4X(dev))
+ reg = SDVOC;
+ else
+ reg = SDVOB;
+
+ if (I915_READ(reg) & SDVO_DETECTED) {
found = intel_sdvo_init(dev, SDVOC);
if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
intel_hdmi_init(dev, SDVOC);
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 0d211af98854..6619f26e46a5 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -265,7 +265,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
pfit_control = 0;
if (!IS_I965G(dev)) {
- if (dev_priv->panel_wants_dither)
+ if (dev_priv->panel_wants_dither || dev_priv->lvds_dither)
pfit_control |= PANEL_8TO6_DITHER_ENABLE;
}
else
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c
index e42019e5d661..07d7ec976168 100644
--- a/drivers/gpu/drm/i915/intel_modes.c
+++ b/drivers/gpu/drm/i915/intel_modes.c
@@ -76,6 +76,7 @@ int intel_ddc_get_modes(struct intel_output *intel_output)
drm_mode_connector_update_edid_property(&intel_output->base,
edid);
ret = drm_add_edid_modes(&intel_output->base, edid);
+ intel_output->base.display_info.raw_edid = NULL;
kfree(edid);
}
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index fbe6f3931b1b..7b31f55f55c8 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -273,20 +273,20 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
int i;
- DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
+ printk(KERN_DEBUG "%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
for (i = 0; i < args_len; i++)
- printk("%02X ", ((u8 *)args)[i]);
+ printk(KERN_DEBUG "%02X ", ((u8 *)args)[i]);
for (; i < 8; i++)
- printk(" ");
+ printk(KERN_DEBUG " ");
for (i = 0; i < sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); i++) {
if (cmd == sdvo_cmd_names[i].cmd) {
- printk("(%s)", sdvo_cmd_names[i].name);
+ printk(KERN_DEBUG "(%s)", sdvo_cmd_names[i].name);
break;
}
}
if (i == sizeof(sdvo_cmd_names)/ sizeof(sdvo_cmd_names[0]))
- printk("(%02X)",cmd);
- printk("\n");
+ printk(KERN_DEBUG "(%02X)", cmd);
+ printk(KERN_DEBUG "\n");
}
#else
#define intel_sdvo_debug_write(o, c, a, l)
@@ -323,17 +323,18 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output,
u8 status)
{
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ int i;
- DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv));
+ printk(KERN_DEBUG "%s: R: ", SDVO_NAME(sdvo_priv));
for (i = 0; i < response_len; i++)
- printk("%02X ", ((u8 *)response)[i]);
+ printk(KERN_DEBUG "%02X ", ((u8 *)response)[i]);
for (; i < 8; i++)
- printk(" ");
+ printk(KERN_DEBUG " ");
if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
- printk("(%s)", cmd_status_names[status]);
+ printk(KERN_DEBUG "(%s)", cmd_status_names[status]);
else
- printk("(??? %d)", status);
- printk("\n");
+ printk(KERN_DEBUG "(??? %d)", status);
+ printk(KERN_DEBUG "\n");
}
#else
#define intel_sdvo_debug_response(o, r, l, s)
@@ -588,9 +589,12 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output,
struct intel_sdvo_preferred_input_timing_args args;
uint8_t status;
+ memset(&args, 0, sizeof(args));
args.clock = clock;
args.width = width;
args.height = height;
+ args.interlace = 0;
+ args.scaled = 0;
intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
&args, sizeof(args));
status = intel_sdvo_read_response(output, NULL, 0);
@@ -683,7 +687,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
dtd->part1.v_high = (((height >> 8) & 0xf) << 4) |
((v_blank_len >> 8) & 0xf);
- dtd->part2.h_sync_off = h_sync_offset;
+ dtd->part2.h_sync_off = h_sync_offset & 0xff;
dtd->part2.h_sync_width = h_sync_len & 0xff;
dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
(v_sync_len & 0xf);
@@ -705,27 +709,10 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
struct intel_sdvo_dtd *dtd)
{
- uint16_t width, height;
- uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
- uint16_t h_sync_offset, v_sync_offset;
-
- width = mode->crtc_hdisplay;
- height = mode->crtc_vdisplay;
-
- /* do some mode translations */
- h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
- h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
-
- v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
- v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
-
- h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
- v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
-
mode->hdisplay = dtd->part1.h_active;
mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off;
- mode->hsync_start += (dtd->part2.sync_off_width_high & 0xa0) << 2;
+ mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2;
mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width;
mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4;
mode->htotal = mode->hdisplay + dtd->part1.h_blank;
@@ -735,7 +722,7 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8;
mode->vsync_start = mode->vdisplay;
mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf;
- mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0a) << 2;
+ mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2;
mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0;
mode->vsync_end = mode->vsync_start +
(dtd->part2.v_sync_off_width & 0xf);
@@ -745,7 +732,7 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
mode->clock = dtd->part1.clock * 10;
- mode->flags &= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+ mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
if (dtd->part2.dtd_flags & 0x2)
mode->flags |= DRM_MODE_FLAG_PHSYNC;
if (dtd->part2.dtd_flags & 0x4)
@@ -924,6 +911,27 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
SDVO_HBUF_TX_VSYNC);
}
+static void intel_sdvo_set_tv_format(struct intel_output *output)
+{
+ struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+ struct intel_sdvo_tv_format *format, unset;
+ u8 status;
+
+ format = &sdvo_priv->tv_format;
+ memset(&unset, 0, sizeof(unset));
+ if (memcmp(format, &unset, sizeof(*format))) {
+ DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n",
+ SDVO_NAME(sdvo_priv));
+ format->ntsc_m = 1;
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, format,
+ sizeof(*format));
+ status = intel_sdvo_read_response(output, NULL, 0);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ DRM_DEBUG("%s: Failed to set TV format\n",
+ SDVO_NAME(sdvo_priv));
+ }
+}
+
static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -968,6 +976,12 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
&input_dtd);
intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
+ drm_mode_set_crtcinfo(adjusted_mode, 0);
+
+ mode->clock = adjusted_mode->clock;
+
+ adjusted_mode->clock *=
+ intel_sdvo_get_pixel_multiplier(mode);
} else {
return false;
}
@@ -1012,7 +1026,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
sdvox |= SDVO_AUDIO_ENABLE;
}
- intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
+ /* We have tried to get input timing in mode_fixup, and filled into
+ adjusted_mode */
+ if (sdvo_priv->is_tv)
+ intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
+ else
+ intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
/* If it's a TV, we already set the output timing in mode_fixup.
* Otherwise, the output timing is equal to the input timing.
@@ -1027,6 +1046,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
/* Set the input timing to the screen. Assume always input 0. */
intel_sdvo_set_target_input(output, true, false);
+ if (sdvo_priv->is_tv)
+ intel_sdvo_set_tv_format(output);
+
/* We would like to use intel_sdvo_create_preferred_input_timing() to
* provide the device with a timing it can support, if it supports that
* feature. However, presumably we would need to adjust the CRTC to
@@ -1395,7 +1417,7 @@ static void
intel_sdvo_check_tv_format(struct intel_output *output)
{
struct intel_sdvo_priv *dev_priv = output->dev_priv;
- struct intel_sdvo_tv_format format, unset;
+ struct intel_sdvo_tv_format format;
uint8_t status;
intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0);
@@ -1403,15 +1425,7 @@ intel_sdvo_check_tv_format(struct intel_output *output)
if (status != SDVO_CMD_STATUS_SUCCESS)
return;
- memset(&unset, 0, sizeof(unset));
- if (memcmp(&format, &unset, sizeof(format))) {
- DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n",
- SDVO_NAME(dev_priv));
-
- format.ntsc_m = true;
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, NULL, 0);
- status = intel_sdvo_read_response(output, NULL, 0);
- }
+ memcpy(&dev_priv->tv_format, &format, sizeof(format));
}
/*
@@ -1420,68 +1434,70 @@ intel_sdvo_check_tv_format(struct intel_output *output)
* XXX: all 60Hz refresh?
*/
struct drm_display_mode sdvo_tv_modes[] = {
- { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815680, 321, 384, 416,
- 200, 0, 232, 201, 233, 4196112, 0,
+ { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815, 320, 321, 384,
+ 416, 0, 200, 201, 232, 233, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814080, 321, 384, 416,
- 240, 0, 272, 241, 273, 4196112, 0,
+ { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814, 320, 321, 384,
+ 416, 0, 240, 241, 272, 273, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910080, 401, 464, 496,
- 300, 0, 332, 301, 333, 4196112, 0,
+ { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910, 400, 401, 464,
+ 496, 0, 300, 301, 332, 333, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913280, 641, 704, 736,
- 350, 0, 382, 351, 383, 4196112, 0,
+ { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913, 640, 641, 704,
+ 736, 0, 350, 351, 382, 383, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736,
- 400, 0, 432, 401, 433, 4196112, 0,
+ { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121, 640, 641, 704,
+ 736, 0, 400, 401, 432, 433, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736,
- 400, 0, 432, 401, 433, 4196112, 0,
+ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 22654, 640, 641, 704,
+ 736, 0, 480, 481, 512, 513, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624000, 705, 768, 800,
- 480, 0, 512, 481, 513, 4196112, 0,
+ { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624, 704, 705, 768,
+ 800, 0, 480, 481, 512, 513, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232000, 705, 768, 800,
- 576, 0, 608, 577, 609, 4196112, 0,
+ { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232, 704, 705, 768,
+ 800, 0, 576, 577, 608, 609, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751680, 721, 784, 816,
- 350, 0, 382, 351, 383, 4196112, 0,
+ { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751, 720, 721, 784,
+ 816, 0, 350, 351, 382, 383, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199680, 721, 784, 816,
- 400, 0, 432, 401, 433, 4196112, 0,
+ { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199, 720, 721, 784,
+ 816, 0, 400, 401, 432, 433, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116480, 721, 784, 816,
- 480, 0, 512, 481, 513, 4196112, 0,
+ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116, 720, 721, 784,
+ 816, 0, 480, 481, 512, 513, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054080, 721, 784, 816,
- 540, 0, 572, 541, 573, 4196112, 0,
+ { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054, 720, 721, 784,
+ 816, 0, 540, 541, 572, 573, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816640, 721, 784, 816,
- 576, 0, 608, 577, 609, 4196112, 0,
+ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816, 720, 721, 784,
+ 816, 0, 576, 577, 608, 609, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570560, 769, 832, 864,
- 576, 0, 608, 577, 609, 4196112, 0,
+ { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570, 768, 769, 832,
+ 864, 0, 576, 577, 608, 609, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030080, 801, 864, 896,
- 600, 0, 632, 601, 633, 4196112, 0,
+ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030, 800, 801, 864,
+ 896, 0, 600, 601, 632, 633, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581760, 833, 896, 928,
- 624, 0, 656, 625, 657, 4196112, 0,
+ { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581, 832, 833, 896,
+ 928, 0, 624, 625, 656, 657, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707040, 921, 984, 1016,
- 766, 0, 798, 767, 799, 4196112, 0,
+ { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707, 920, 921, 984,
+ 1016, 0, 766, 767, 798, 799, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827200, 1025, 1088, 1120,
- 768, 0, 800, 769, 801, 4196112, 0,
+ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827, 1024, 1025, 1088,
+ 1120, 0, 768, 769, 800, 801, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265920, 1281, 1344, 1376,
- 1024, 0, 1056, 1025, 1057, 4196112, 0,
+ { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265, 1280, 1281, 1344,
+ 1376, 0, 1024, 1025, 1056, 1057, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
};
static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
{
struct intel_output *output = to_intel_output(connector);
+ struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+ struct intel_sdvo_sdtv_resolution_request tv_res;
uint32_t reply = 0;
uint8_t status;
int i = 0;
@@ -1491,15 +1507,22 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
/* Read the list of supported input resolutions for the selected TV
* format.
*/
+ memset(&tv_res, 0, sizeof(tv_res));
+ memcpy(&tv_res, &sdvo_priv->tv_format, sizeof(tv_res));
intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
- NULL, 0);
+ &tv_res, sizeof(tv_res));
status = intel_sdvo_read_response(output, &reply, 3);
if (status != SDVO_CMD_STATUS_SUCCESS)
return;
for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++)
- if (reply & (1 << i))
- drm_mode_probed_add(connector, &sdvo_tv_modes[i]);
+ if (reply & (1 << i)) {
+ struct drm_display_mode *nmode;
+ nmode = drm_mode_duplicate(connector->dev,
+ &sdvo_tv_modes[i]);
+ if (nmode)
+ drm_mode_probed_add(connector, nmode);
+ }
}
static int intel_sdvo_get_modes(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h
index 1117b9c151a6..193938b7d7f9 100644
--- a/drivers/gpu/drm/i915/intel_sdvo_regs.h
+++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h
@@ -100,6 +100,9 @@ struct intel_sdvo_preferred_input_timing_args {
u16 clock;
u16 width;
u16 height;
+ u8 interlace:1;
+ u8 scaled:1;
+ u8 pad:6;
} __attribute__((packed));
/* I2C registers for SDVO */
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 56485d67369b..d2c32983242d 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -217,8 +217,8 @@ static const u32 filter_table[] = {
*/
static const struct color_conversion ntsc_m_csc_composite = {
.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
- .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00,
- .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00,
+ .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
+ .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
};
static const struct video_levels ntsc_m_levels_composite = {
@@ -226,9 +226,9 @@ static const struct video_levels ntsc_m_levels_composite = {
};
static const struct color_conversion ntsc_m_csc_svideo = {
- .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134,
- .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00,
- .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00,
+ .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
+ .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
+ .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
};
static const struct video_levels ntsc_m_levels_svideo = {
@@ -237,8 +237,8 @@ static const struct video_levels ntsc_m_levels_svideo = {
static const struct color_conversion ntsc_j_csc_composite = {
.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119,
- .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0f00,
- .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0f00,
+ .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0200,
+ .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0200,
};
static const struct video_levels ntsc_j_levels_composite = {
@@ -247,8 +247,8 @@ static const struct video_levels ntsc_j_levels_composite = {
static const struct color_conversion ntsc_j_csc_svideo = {
.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c,
- .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0f00,
- .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0f00,
+ .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0200,
+ .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0200,
};
static const struct video_levels ntsc_j_levels_svideo = {
@@ -257,8 +257,8 @@ static const struct video_levels ntsc_j_levels_svideo = {
static const struct color_conversion pal_csc_composite = {
.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113,
- .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0f00,
- .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0f00,
+ .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0200,
+ .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0200,
};
static const struct video_levels pal_levels_composite = {
@@ -267,8 +267,8 @@ static const struct video_levels pal_levels_composite = {
static const struct color_conversion pal_csc_svideo = {
.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
- .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0f00,
- .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0f00,
+ .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0200,
+ .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0200,
};
static const struct video_levels pal_levels_svideo = {
@@ -277,8 +277,8 @@ static const struct video_levels pal_levels_svideo = {
static const struct color_conversion pal_m_csc_composite = {
.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
- .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00,
- .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00,
+ .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
+ .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
};
static const struct video_levels pal_m_levels_composite = {
@@ -286,9 +286,9 @@ static const struct video_levels pal_m_levels_composite = {
};
static const struct color_conversion pal_m_csc_svideo = {
- .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134,
- .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00,
- .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00,
+ .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
+ .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
+ .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
};
static const struct video_levels pal_m_levels_svideo = {
@@ -297,8 +297,8 @@ static const struct video_levels pal_m_levels_svideo = {
static const struct color_conversion pal_n_csc_composite = {
.ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
- .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00,
- .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00,
+ .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0200,
+ .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0200,
};
static const struct video_levels pal_n_levels_composite = {
@@ -306,9 +306,9 @@ static const struct video_levels pal_n_levels_composite = {
};
static const struct color_conversion pal_n_csc_svideo = {
- .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134,
- .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00,
- .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00,
+ .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0133,
+ .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0200,
+ .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0200,
};
static const struct video_levels pal_n_levels_svideo = {
@@ -319,9 +319,9 @@ static const struct video_levels pal_n_levels_svideo = {
* Component connections
*/
static const struct color_conversion sdtv_csc_yprpb = {
- .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0146,
- .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0f00,
- .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0f00,
+ .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
+ .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0200,
+ .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0200,
};
static const struct color_conversion sdtv_csc_rgb = {
@@ -331,9 +331,9 @@ static const struct color_conversion sdtv_csc_rgb = {
};
static const struct color_conversion hdtv_csc_yprpb = {
- .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0146,
- .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0f00,
- .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0f00,
+ .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0145,
+ .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0200,
+ .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0200,
};
static const struct color_conversion hdtv_csc_rgb = {
@@ -414,7 +414,7 @@ struct tv_mode {
static const struct tv_mode tv_modes[] = {
{
.name = "NTSC-M",
- .clock = 107520,
+ .clock = 108000,
.refresh = 29970,
.oversample = TV_OVERSAMPLE_8X,
.component_only = 0,
@@ -442,8 +442,8 @@ static const struct tv_mode tv_modes[] = {
.vburst_start_f4 = 10, .vburst_end_f4 = 240,
/* desired 3.5800000 actual 3.5800000 clock 107.52 */
- .dda1_inc = 136,
- .dda2_inc = 7624, .dda2_size = 20013,
+ .dda1_inc = 135,
+ .dda2_inc = 20800, .dda2_size = 27456,
.dda3_inc = 0, .dda3_size = 0,
.sc_reset = TV_SC_RESET_EVERY_4,
.pal_burst = false,
@@ -457,7 +457,7 @@ static const struct tv_mode tv_modes[] = {
},
{
.name = "NTSC-443",
- .clock = 107520,
+ .clock = 108000,
.refresh = 29970,
.oversample = TV_OVERSAMPLE_8X,
.component_only = 0,
@@ -485,10 +485,10 @@ static const struct tv_mode tv_modes[] = {
/* desired 4.4336180 actual 4.4336180 clock 107.52 */
.dda1_inc = 168,
- .dda2_inc = 18557, .dda2_size = 20625,
- .dda3_inc = 0, .dda3_size = 0,
- .sc_reset = TV_SC_RESET_EVERY_8,
- .pal_burst = true,
+ .dda2_inc = 4093, .dda2_size = 27456,
+ .dda3_inc = 310, .dda3_size = 525,
+ .sc_reset = TV_SC_RESET_NEVER,
+ .pal_burst = false,
.composite_levels = &ntsc_m_levels_composite,
.composite_color = &ntsc_m_csc_composite,
@@ -499,7 +499,7 @@ static const struct tv_mode tv_modes[] = {
},
{
.name = "NTSC-J",
- .clock = 107520,
+ .clock = 108000,
.refresh = 29970,
.oversample = TV_OVERSAMPLE_8X,
.component_only = 0,
@@ -527,8 +527,8 @@ static const struct tv_mode tv_modes[] = {
.vburst_start_f4 = 10, .vburst_end_f4 = 240,
/* desired 3.5800000 actual 3.5800000 clock 107.52 */
- .dda1_inc = 136,
- .dda2_inc = 7624, .dda2_size = 20013,
+ .dda1_inc = 135,
+ .dda2_inc = 20800, .dda2_size = 27456,
.dda3_inc = 0, .dda3_size = 0,
.sc_reset = TV_SC_RESET_EVERY_4,
.pal_burst = false,
@@ -542,7 +542,7 @@ static const struct tv_mode tv_modes[] = {
},
{
.name = "PAL-M",
- .clock = 107520,
+ .clock = 108000,
.refresh = 29970,
.oversample = TV_OVERSAMPLE_8X,
.component_only = 0,
@@ -570,11 +570,11 @@ static const struct tv_mode tv_modes[] = {
.vburst_start_f4 = 10, .vburst_end_f4 = 240,
/* desired 3.5800000 actual 3.5800000 clock 107.52 */
- .dda1_inc = 136,
- .dda2_inc = 7624, .dda2_size = 20013,
+ .dda1_inc = 135,
+ .dda2_inc = 16704, .dda2_size = 27456,
.dda3_inc = 0, .dda3_size = 0,
- .sc_reset = TV_SC_RESET_EVERY_4,
- .pal_burst = false,
+ .sc_reset = TV_SC_RESET_EVERY_8,
+ .pal_burst = true,
.composite_levels = &pal_m_levels_composite,
.composite_color = &pal_m_csc_composite,
@@ -586,7 +586,7 @@ static const struct tv_mode tv_modes[] = {
{
/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
.name = "PAL-N",
- .clock = 107520,
+ .clock = 108000,
.refresh = 25000,
.oversample = TV_OVERSAMPLE_8X,
.component_only = 0,
@@ -615,9 +615,9 @@ static const struct tv_mode tv_modes[] = {
/* desired 4.4336180 actual 4.4336180 clock 107.52 */
- .dda1_inc = 168,
- .dda2_inc = 18557, .dda2_size = 20625,
- .dda3_inc = 0, .dda3_size = 0,
+ .dda1_inc = 135,
+ .dda2_inc = 23578, .dda2_size = 27648,
+ .dda3_inc = 134, .dda3_size = 625,
.sc_reset = TV_SC_RESET_EVERY_8,
.pal_burst = true,
@@ -631,12 +631,12 @@ static const struct tv_mode tv_modes[] = {
{
/* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
.name = "PAL",
- .clock = 107520,
+ .clock = 108000,
.refresh = 25000,
.oversample = TV_OVERSAMPLE_8X,
.component_only = 0,
- .hsync_end = 64, .hblank_end = 128,
+ .hsync_end = 64, .hblank_end = 142,
.hblank_start = 844, .htotal = 863,
.progressive = false, .trilevel_sync = false,
@@ -659,8 +659,8 @@ static const struct tv_mode tv_modes[] = {
/* desired 4.4336180 actual 4.4336180 clock 107.52 */
.dda1_inc = 168,
- .dda2_inc = 18557, .dda2_size = 20625,
- .dda3_inc = 0, .dda3_size = 0,
+ .dda2_inc = 4122, .dda2_size = 27648,
+ .dda3_inc = 67, .dda3_size = 625,
.sc_reset = TV_SC_RESET_EVERY_8,
.pal_burst = true,
@@ -689,7 +689,7 @@ static const struct tv_mode tv_modes[] = {
.veq_ena = false,
.vi_end_f1 = 44, .vi_end_f2 = 44,
- .nbr_end = 496,
+ .nbr_end = 479,
.burst_ena = false,
@@ -713,7 +713,7 @@ static const struct tv_mode tv_modes[] = {
.veq_ena = false,
.vi_end_f1 = 44, .vi_end_f2 = 44,
- .nbr_end = 496,
+ .nbr_end = 479,
.burst_ena = false,
@@ -876,7 +876,7 @@ static const struct tv_mode tv_modes[] = {
.component_only = 1,
.hsync_end = 88, .hblank_end = 235,
- .hblank_start = 2155, .htotal = 2200,
+ .hblank_start = 2155, .htotal = 2201,
.progressive = false, .trilevel_sync = true,
@@ -1082,7 +1082,7 @@ intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mo
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
/* Ensure TV refresh is close to desired refresh */
- if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 1)
+ if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 10)
return MODE_OK;
return MODE_CLOCK_RANGE;
}
@@ -1135,7 +1135,8 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
if (!tv_mode)
return; /* can't happen (mode_prepare prevents this) */
- tv_ctl = 0;
+ tv_ctl = I915_READ(TV_CTL);
+ tv_ctl &= TV_CTL_SAVE;
switch (tv_priv->type) {
default:
@@ -1215,7 +1216,6 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
/* dda1 implies valid video levels */
if (tv_mode->dda1_inc) {
scctl1 |= TV_SC_DDA1_EN;
- scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
}
if (tv_mode->dda2_inc)
@@ -1225,6 +1225,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
scctl1 |= TV_SC_DDA3_EN;
scctl1 |= tv_mode->sc_reset;
+ scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
@@ -1266,7 +1267,11 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
color_conversion->av);
}
- I915_WRITE(TV_CLR_KNOBS, 0x00606000);
+ if (IS_I965G(dev))
+ I915_WRITE(TV_CLR_KNOBS, 0x00404000);
+ else
+ I915_WRITE(TV_CLR_KNOBS, 0x00606000);
+
if (video_levels)
I915_WRITE(TV_CLR_LEVEL,
((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
@@ -1401,6 +1406,7 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
tv_dac = I915_READ(TV_DAC);
I915_WRITE(TV_DAC, save_tv_dac);
I915_WRITE(TV_CTL, save_tv_ctl);
+ intel_wait_for_vblank(dev);
}
/*
* A B C
@@ -1451,7 +1457,7 @@ intel_tv_detect(struct drm_connector *connector)
mode = reported_modes[0];
drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
- if (encoder->crtc) {
+ if (encoder->crtc && encoder->crtc->enabled) {
type = intel_tv_detect_type(encoder->crtc, intel_output);
} else {
crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode);
@@ -1462,6 +1468,8 @@ intel_tv_detect(struct drm_connector *connector)
type = -1;
}
+ tv_priv->type = type;
+
if (type < 0)
return connector_status_disconnected;
@@ -1495,7 +1503,8 @@ intel_tv_get_modes(struct drm_connector *connector)
struct drm_display_mode *mode_ptr;
struct intel_output *intel_output = to_intel_output(connector);
const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
- int j;
+ int j, count = 0;
+ u64 tmp;
for (j = 0; j < sizeof(input_res_table) / sizeof(input_res_table[0]);
j++) {
@@ -1510,8 +1519,9 @@ intel_tv_get_modes(struct drm_connector *connector)
&& !tv_mode->component_only))
continue;
- mode_ptr = drm_calloc(1, sizeof(struct drm_display_mode),
- DRM_MEM_DRIVER);
+ mode_ptr = drm_mode_create(connector->dev);
+ if (!mode_ptr)
+ continue;
strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN);
mode_ptr->hdisplay = hactive_s;
@@ -1528,15 +1538,17 @@ intel_tv_get_modes(struct drm_connector *connector)
mode_ptr->vsync_end = mode_ptr->vsync_start + 1;
mode_ptr->vtotal = vactive_s + 33;
- mode_ptr->clock = (int) (tv_mode->refresh *
- mode_ptr->vtotal *
- mode_ptr->htotal / 1000) / 1000;
+ tmp = (u64) tv_mode->refresh * mode_ptr->vtotal;
+ tmp *= mode_ptr->htotal;
+ tmp = div_u64(tmp, 1000000);
+ mode_ptr->clock = (int) tmp;
mode_ptr->type = DRM_MODE_TYPE_DRIVER;
drm_mode_probed_add(connector, mode_ptr);
+ count++;
}
- return 0;
+ return count;
}
static void
@@ -1558,33 +1570,49 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
struct drm_device *dev = connector->dev;
struct intel_output *intel_output = to_intel_output(connector);
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+ struct drm_encoder *encoder = &intel_output->enc;
+ struct drm_crtc *crtc = encoder->crtc;
int ret = 0;
+ bool changed = false;
ret = drm_connector_property_set_value(connector, property, val);
if (ret < 0)
goto out;
- if (property == dev->mode_config.tv_left_margin_property)
+ if (property == dev->mode_config.tv_left_margin_property &&
+ tv_priv->margin[TV_MARGIN_LEFT] != val) {
tv_priv->margin[TV_MARGIN_LEFT] = val;
- else if (property == dev->mode_config.tv_right_margin_property)
+ changed = true;
+ } else if (property == dev->mode_config.tv_right_margin_property &&
+ tv_priv->margin[TV_MARGIN_RIGHT] != val) {
tv_priv->margin[TV_MARGIN_RIGHT] = val;
- else if (property == dev->mode_config.tv_top_margin_property)
+ changed = true;
+ } else if (property == dev->mode_config.tv_top_margin_property &&
+ tv_priv->margin[TV_MARGIN_TOP] != val) {
tv_priv->margin[TV_MARGIN_TOP] = val;
- else if (property == dev->mode_config.tv_bottom_margin_property)
+ changed = true;
+ } else if (property == dev->mode_config.tv_bottom_margin_property &&
+ tv_priv->margin[TV_MARGIN_BOTTOM] != val) {
tv_priv->margin[TV_MARGIN_BOTTOM] = val;
- else if (property == dev->mode_config.tv_mode_property) {
+ changed = true;
+ } else if (property == dev->mode_config.tv_mode_property) {
if (val >= NUM_TV_MODES) {
ret = -EINVAL;
goto out;
}
+ if (!strcmp(tv_priv->tv_format, tv_modes[val].name))
+ goto out;
+
tv_priv->tv_format = tv_modes[val].name;
- intel_tv_mode_set(&intel_output->enc, NULL, NULL);
+ changed = true;
} else {
ret = -EINVAL;
goto out;
}
- intel_tv_mode_set(&intel_output->enc, NULL, NULL);
+ if (changed && crtc)
+ drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
+ crtc->y, crtc->fb);
out:
return ret;
}
diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c
index b49c5ff29585..7a6bf9ffc5a3 100644
--- a/drivers/gpu/drm/mga/mga_dma.c
+++ b/drivers/gpu/drm/mga/mga_dma.c
@@ -148,8 +148,8 @@ void mga_do_dma_flush(drm_mga_private_t * dev_priv)
primary->space = head - tail;
}
- DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset);
- DRM_DEBUG(" tail = 0x%06lx\n", tail - dev_priv->primary->offset);
+ DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset));
+ DRM_DEBUG(" tail = 0x%06lx\n", (unsigned long)(tail - dev_priv->primary->offset));
DRM_DEBUG(" space = 0x%06x\n", primary->space);
mga_flush_write_combine();
@@ -187,7 +187,7 @@ void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv)
primary->space = head - dev_priv->primary->offset;
}
- DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset);
+ DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset));
DRM_DEBUG(" tail = 0x%06x\n", primary->tail);
DRM_DEBUG(" wrap = %d\n", primary->last_wrap);
DRM_DEBUG(" space = 0x%06x\n", primary->space);
@@ -239,7 +239,7 @@ static void mga_freelist_print(struct drm_device * dev)
for (entry = dev_priv->head->next; entry; entry = entry->next) {
DRM_INFO(" %p idx=%2d age=0x%x 0x%06lx\n",
entry, entry->buf->idx, entry->age.head,
- entry->age.head - dev_priv->primary->offset);
+ (unsigned long)(entry->age.head - dev_priv->primary->offset));
}
DRM_INFO("\n");
}
@@ -340,10 +340,10 @@ static struct drm_buf *mga_freelist_get(struct drm_device * dev)
DRM_DEBUG(" tail=0x%06lx %d\n",
tail->age.head ?
- tail->age.head - dev_priv->primary->offset : 0,
+ (unsigned long)(tail->age.head - dev_priv->primary->offset) : 0,
tail->age.wrap);
DRM_DEBUG(" head=0x%06lx %d\n",
- head - dev_priv->primary->offset, wrap);
+ (unsigned long)(head - dev_priv->primary->offset), wrap);
if (TEST_AGE(&tail->age, head, wrap)) {
prev = dev_priv->tail->prev;
@@ -366,8 +366,9 @@ int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf)
drm_mga_freelist_t *head, *entry, *prev;
DRM_DEBUG("age=0x%06lx wrap=%d\n",
- buf_priv->list_entry->age.head -
- dev_priv->primary->offset, buf_priv->list_entry->age.wrap);
+ (unsigned long)(buf_priv->list_entry->age.head -
+ dev_priv->primary->offset),
+ buf_priv->list_entry->age.wrap);
entry = buf_priv->list_entry;
head = dev_priv->head;
diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h
index 88257c276eb9..3d264f288237 100644
--- a/drivers/gpu/drm/mga/mga_drv.h
+++ b/drivers/gpu/drm/mga/mga_drv.h
@@ -113,8 +113,8 @@ typedef struct drm_mga_private {
* \sa drm_mga_private_t::mmio
*/
/*@{ */
- u32 mmio_base; /**< Bus address of base of MMIO. */
- u32 mmio_size; /**< Size of the MMIO region. */
+ resource_size_t mmio_base; /**< Bus address of base of MMIO. */
+ resource_size_t mmio_size; /**< Size of the MMIO region. */
/*@} */
u32 clear_cmd;
@@ -317,8 +317,8 @@ do { \
DRM_INFO( "\n" ); \
DRM_INFO( " tail=0x%06x head=0x%06lx\n", \
dev_priv->prim.tail, \
- MGA_READ( MGA_PRIMADDRESS ) - \
- dev_priv->primary->offset ); \
+ (unsigned long)(MGA_READ(MGA_PRIMADDRESS) - \
+ dev_priv->primary->offset)); \
} \
if ( !test_bit( 0, &dev_priv->prim.wrapped ) ) { \
if ( dev_priv->prim.space < \
diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c
index c31afbde62e7..32de4cedc363 100644
--- a/drivers/gpu/drm/r128/r128_cce.c
+++ b/drivers/gpu/drm/r128/r128_cce.c
@@ -525,11 +525,12 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
} else
#endif
{
- dev_priv->cce_ring->handle = (void *)dev_priv->cce_ring->offset;
+ dev_priv->cce_ring->handle =
+ (void *)(unsigned long)dev_priv->cce_ring->offset;
dev_priv->ring_rptr->handle =
- (void *)dev_priv->ring_rptr->offset;
+ (void *)(unsigned long)dev_priv->ring_rptr->offset;
dev->agp_buffer_map->handle =
- (void *)dev->agp_buffer_map->offset;
+ (void *)(unsigned long)dev->agp_buffer_map->offset;
}
#if __OS_HAS_AGP
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index feb521ebc393..52ce439a0f2e 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -3,7 +3,7 @@
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
ccflags-y := -Iinclude/drm
-radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
+radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o r600_cp.o
radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c
index cace3964feeb..cb2e470f97d4 100644
--- a/drivers/gpu/drm/radeon/r300_cmdbuf.c
+++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c
@@ -37,6 +37,8 @@
#include "radeon_drv.h"
#include "r300_reg.h"
+#include <asm/unaligned.h>
+
#define R300_SIMULTANEOUS_CLIPRECTS 4
/* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects
@@ -205,6 +207,10 @@ void r300_init_reg_flags(struct drm_device *dev)
ADD_RANGE(0x42C0, 2);
ADD_RANGE(R300_RS_CNTL_0, 2);
+ ADD_RANGE(R300_SU_REG_DEST, 1);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530)
+ ADD_RANGE(RV530_FG_ZBREG_DEST, 1);
+
ADD_RANGE(R300_SC_HYPERZ, 2);
ADD_RANGE(0x43E8, 1);
@@ -230,6 +236,7 @@ void r300_init_reg_flags(struct drm_device *dev)
ADD_RANGE(R300_ZB_DEPTHPITCH, 1);
ADD_RANGE(R300_ZB_DEPTHCLEARVALUE, 1);
ADD_RANGE(R300_ZB_ZMASK_OFFSET, 13);
+ ADD_RANGE(R300_ZB_ZPASS_DATA, 2); /* ZB_ZPASS_DATA, ZB_ZPASS_ADDR */
ADD_RANGE(R300_TX_FILTER_0, 16);
ADD_RANGE(R300_TX_FILTER1_0, 16);
@@ -917,6 +924,7 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,
{
u32 *ref_age_base;
u32 i, buf_idx, h_pending;
+ u64 ptr_addr;
RING_LOCALS;
if (cmdbuf->bufsz <
@@ -930,7 +938,8 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,
dev_priv->scratch_ages[header.scratch.reg]++;
- ref_age_base = (u32 *)(unsigned long)*((uint64_t *)cmdbuf->buf);
+ ptr_addr = get_unaligned((u64 *)cmdbuf->buf);
+ ref_age_base = (u32 *)(unsigned long)ptr_addr;
cmdbuf->buf += sizeof(u64);
cmdbuf->bufsz -= sizeof(u64);
diff --git a/drivers/gpu/drm/radeon/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h
index ee6f811599a3..bdbc95fa6721 100644
--- a/drivers/gpu/drm/radeon/r300_reg.h
+++ b/drivers/gpu/drm/radeon/r300_reg.h
@@ -1770,4 +1770,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R500_RB3D_COLOR_CLEAR_VALUE_AR 0x46c0
#define R500_RB3D_CONSTANT_COLOR_AR 0x4ef8
+#define R300_SU_REG_DEST 0x42c8
+#define RV530_FG_ZBREG_DEST 0x4be8
+#define R300_ZB_ZPASS_DATA 0x4f58
+#define R300_ZB_ZPASS_ADDR 0x4f5c
+
#endif /* _R300_REG_H */
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c
new file mode 100644
index 000000000000..bc9d09dfa8e7
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_cp.c
@@ -0,0 +1,2253 @@
+/*
+ * Copyright 2008-2009 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Dave Airlie <airlied@redhat.com>
+ * Alex Deucher <alexander.deucher@amd.com>
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_drv.h"
+
+#include "r600_microcode.h"
+
+# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
+# define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1))
+
+#define R600_PTE_VALID (1 << 0)
+#define R600_PTE_SYSTEM (1 << 1)
+#define R600_PTE_SNOOPED (1 << 2)
+#define R600_PTE_READABLE (1 << 5)
+#define R600_PTE_WRITEABLE (1 << 6)
+
+/* MAX values used for gfx init */
+#define R6XX_MAX_SH_GPRS 256
+#define R6XX_MAX_TEMP_GPRS 16
+#define R6XX_MAX_SH_THREADS 256
+#define R6XX_MAX_SH_STACK_ENTRIES 4096
+#define R6XX_MAX_BACKENDS 8
+#define R6XX_MAX_BACKENDS_MASK 0xff
+#define R6XX_MAX_SIMDS 8
+#define R6XX_MAX_SIMDS_MASK 0xff
+#define R6XX_MAX_PIPES 8
+#define R6XX_MAX_PIPES_MASK 0xff
+
+#define R7XX_MAX_SH_GPRS 256
+#define R7XX_MAX_TEMP_GPRS 16
+#define R7XX_MAX_SH_THREADS 256
+#define R7XX_MAX_SH_STACK_ENTRIES 4096
+#define R7XX_MAX_BACKENDS 8
+#define R7XX_MAX_BACKENDS_MASK 0xff
+#define R7XX_MAX_SIMDS 16
+#define R7XX_MAX_SIMDS_MASK 0xffff
+#define R7XX_MAX_PIPES 8
+#define R7XX_MAX_PIPES_MASK 0xff
+
+static int r600_do_wait_for_fifo(drm_radeon_private_t *dev_priv, int entries)
+{
+ int i;
+
+ dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ int slots;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+ slots = (RADEON_READ(R600_GRBM_STATUS)
+ & R700_CMDFIFO_AVAIL_MASK);
+ else
+ slots = (RADEON_READ(R600_GRBM_STATUS)
+ & R600_CMDFIFO_AVAIL_MASK);
+ if (slots >= entries)
+ return 0;
+ DRM_UDELAY(1);
+ }
+ DRM_INFO("wait for fifo failed status : 0x%08X 0x%08X\n",
+ RADEON_READ(R600_GRBM_STATUS),
+ RADEON_READ(R600_GRBM_STATUS2));
+
+ return -EBUSY;
+}
+
+static int r600_do_wait_for_idle(drm_radeon_private_t *dev_priv)
+{
+ int i, ret;
+
+ dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+ ret = r600_do_wait_for_fifo(dev_priv, 8);
+ else
+ ret = r600_do_wait_for_fifo(dev_priv, 16);
+ if (ret)
+ return ret;
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(RADEON_READ(R600_GRBM_STATUS) & R600_GUI_ACTIVE))
+ return 0;
+ DRM_UDELAY(1);
+ }
+ DRM_INFO("wait idle failed status : 0x%08X 0x%08X\n",
+ RADEON_READ(R600_GRBM_STATUS),
+ RADEON_READ(R600_GRBM_STATUS2));
+
+ return -EBUSY;
+}
+
+void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info)
+{
+ struct drm_sg_mem *entry = dev->sg;
+ int max_pages;
+ int pages;
+ int i;
+
+ if (!entry)
+ return;
+
+ if (gart_info->bus_addr) {
+ max_pages = (gart_info->table_size / sizeof(u64));
+ pages = (entry->pages <= max_pages)
+ ? entry->pages : max_pages;
+
+ for (i = 0; i < pages; i++) {
+ if (!entry->busaddr[i])
+ break;
+ pci_unmap_page(dev->pdev, entry->busaddr[i],
+ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+ }
+ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
+ gart_info->bus_addr = 0;
+ }
+}
+
+/* R600 has page table setup */
+int r600_page_table_init(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info;
+ struct drm_local_map *map = &gart_info->mapping;
+ struct drm_sg_mem *entry = dev->sg;
+ int ret = 0;
+ int i, j;
+ int pages;
+ u64 page_base;
+ dma_addr_t entry_addr;
+ int max_ati_pages, max_real_pages, gart_idx;
+
+ /* okay page table is available - lets rock */
+ max_ati_pages = (gart_info->table_size / sizeof(u64));
+ max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE);
+
+ pages = (entry->pages <= max_real_pages) ?
+ entry->pages : max_real_pages;
+
+ memset_io((void __iomem *)map->handle, 0, max_ati_pages * sizeof(u64));
+
+ gart_idx = 0;
+ for (i = 0; i < pages; i++) {
+ entry->busaddr[i] = pci_map_page(dev->pdev,
+ entry->pagelist[i], 0,
+ PAGE_SIZE,
+ PCI_DMA_BIDIRECTIONAL);
+ if (entry->busaddr[i] == 0) {
+ DRM_ERROR("unable to map PCIGART pages!\n");
+ r600_page_table_cleanup(dev, gart_info);
+ goto done;
+ }
+ entry_addr = entry->busaddr[i];
+ for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
+ page_base = (u64) entry_addr & ATI_PCIGART_PAGE_MASK;
+ page_base |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED;
+ page_base |= R600_PTE_READABLE | R600_PTE_WRITEABLE;
+
+ DRM_WRITE64(map, gart_idx * sizeof(u64), page_base);
+
+ gart_idx++;
+
+ if ((i % 128) == 0)
+ DRM_DEBUG("page entry %d: 0x%016llx\n",
+ i, (unsigned long long)page_base);
+ entry_addr += ATI_PCIGART_PAGE_SIZE;
+ }
+ }
+ ret = 1;
+done:
+ return ret;
+}
+
+static void r600_vm_flush_gart_range(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ u32 resp, countdown = 1000;
+ RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR, dev_priv->gart_vm_start >> 12);
+ RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+ RADEON_WRITE(R600_VM_CONTEXT0_REQUEST_RESPONSE, 2);
+
+ do {
+ resp = RADEON_READ(R600_VM_CONTEXT0_REQUEST_RESPONSE);
+ countdown--;
+ DRM_UDELAY(1);
+ } while (((resp & 0xf0) == 0) && countdown);
+}
+
+static void r600_vm_init(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ /* initialise the VM to use the page table we constructed up there */
+ u32 vm_c0, i;
+ u32 mc_rd_a;
+ u32 vm_l2_cntl, vm_l2_cntl3;
+ /* okay set up the PCIE aperture type thingo */
+ RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12);
+ RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+ RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+
+ /* setup MC RD a */
+ mc_rd_a = R600_MCD_L1_TLB | R600_MCD_L1_FRAG_PROC | R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS |
+ R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | R600_MCD_EFFECTIVE_L1_TLB_SIZE(5) |
+ R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(5) | R600_MCD_WAIT_L2_QUERY;
+
+ RADEON_WRITE(R600_MCD_RD_A_CNTL, mc_rd_a);
+ RADEON_WRITE(R600_MCD_RD_B_CNTL, mc_rd_a);
+
+ RADEON_WRITE(R600_MCD_WR_A_CNTL, mc_rd_a);
+ RADEON_WRITE(R600_MCD_WR_B_CNTL, mc_rd_a);
+
+ RADEON_WRITE(R600_MCD_RD_GFX_CNTL, mc_rd_a);
+ RADEON_WRITE(R600_MCD_WR_GFX_CNTL, mc_rd_a);
+
+ RADEON_WRITE(R600_MCD_RD_SYS_CNTL, mc_rd_a);
+ RADEON_WRITE(R600_MCD_WR_SYS_CNTL, mc_rd_a);
+
+ RADEON_WRITE(R600_MCD_RD_HDP_CNTL, mc_rd_a | R600_MCD_L1_STRICT_ORDERING);
+ RADEON_WRITE(R600_MCD_WR_HDP_CNTL, mc_rd_a /*| R600_MCD_L1_STRICT_ORDERING*/);
+
+ RADEON_WRITE(R600_MCD_RD_PDMA_CNTL, mc_rd_a);
+ RADEON_WRITE(R600_MCD_WR_PDMA_CNTL, mc_rd_a);
+
+ RADEON_WRITE(R600_MCD_RD_SEM_CNTL, mc_rd_a | R600_MCD_SEMAPHORE_MODE);
+ RADEON_WRITE(R600_MCD_WR_SEM_CNTL, mc_rd_a);
+
+ vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W;
+ vm_l2_cntl |= R600_VM_L2_CNTL_QUEUE_SIZE(7);
+ RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl);
+
+ RADEON_WRITE(R600_VM_L2_CNTL2, 0);
+ vm_l2_cntl3 = (R600_VM_L2_CNTL3_BANK_SELECT_0(0) |
+ R600_VM_L2_CNTL3_BANK_SELECT_1(1) |
+ R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(2));
+ RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3);
+
+ vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT;
+
+ RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0);
+
+ vm_c0 &= ~R600_VM_ENABLE_CONTEXT;
+
+ /* disable all other contexts */
+ for (i = 1; i < 8; i++)
+ RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0);
+
+ RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12);
+ RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12);
+ RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+
+ r600_vm_flush_gart_range(dev);
+}
+
+/* load r600 microcode */
+static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv)
+{
+ int i;
+
+ r600_do_cp_stop(dev_priv);
+
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ R600_RB_NO_UPDATE |
+ R600_RB_BLKSZ(15) |
+ R600_RB_BUFSZ(3));
+
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
+ RADEON_READ(R600_GRBM_SOFT_RESET);
+ DRM_UDELAY(15000);
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
+
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600)) {
+ DRM_INFO("Loading R600 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ R600_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ R600_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ R600_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading R600 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, R600_pfp_microcode[i]);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610)) {
+ DRM_INFO("Loading RV610 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV610_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV610_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV610_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV610 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV610_pfp_microcode[i]);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) {
+ DRM_INFO("Loading RV630 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV630_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV630_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV630_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV630 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV630_pfp_microcode[i]);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620)) {
+ DRM_INFO("Loading RV620 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV620_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV620_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV620_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV620 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV620_pfp_microcode[i]);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) {
+ DRM_INFO("Loading RV635 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV635_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV635_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV635_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV635 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV635_pfp_microcode[i]);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670)) {
+ DRM_INFO("Loading RV670 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV670_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV670_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV670_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV670 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) {
+ DRM_INFO("Loading RS780 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RS780_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RS780_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RS780_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RS780 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RS780_pfp_microcode[i]);
+ }
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+ RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0);
+
+}
+
+static void r700_vm_init(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ /* initialise the VM to use the page table we constructed up there */
+ u32 vm_c0, i;
+ u32 mc_vm_md_l1;
+ u32 vm_l2_cntl, vm_l2_cntl3;
+ /* okay set up the PCIE aperture type thingo */
+ RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12);
+ RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+ RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+
+ mc_vm_md_l1 = R700_ENABLE_L1_TLB |
+ R700_ENABLE_L1_FRAGMENT_PROCESSING |
+ R700_SYSTEM_ACCESS_MODE_IN_SYS |
+ R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
+ R700_EFFECTIVE_L1_TLB_SIZE(5) |
+ R700_EFFECTIVE_L1_QUEUE_SIZE(5);
+
+ RADEON_WRITE(R700_MC_VM_MD_L1_TLB0_CNTL, mc_vm_md_l1);
+ RADEON_WRITE(R700_MC_VM_MD_L1_TLB1_CNTL, mc_vm_md_l1);
+ RADEON_WRITE(R700_MC_VM_MD_L1_TLB2_CNTL, mc_vm_md_l1);
+ RADEON_WRITE(R700_MC_VM_MB_L1_TLB0_CNTL, mc_vm_md_l1);
+ RADEON_WRITE(R700_MC_VM_MB_L1_TLB1_CNTL, mc_vm_md_l1);
+ RADEON_WRITE(R700_MC_VM_MB_L1_TLB2_CNTL, mc_vm_md_l1);
+ RADEON_WRITE(R700_MC_VM_MB_L1_TLB3_CNTL, mc_vm_md_l1);
+
+ vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W;
+ vm_l2_cntl |= R700_VM_L2_CNTL_QUEUE_SIZE(7);
+ RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl);
+
+ RADEON_WRITE(R600_VM_L2_CNTL2, 0);
+ vm_l2_cntl3 = R700_VM_L2_CNTL3_BANK_SELECT(0) | R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(2);
+ RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3);
+
+ vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT;
+
+ RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0);
+
+ vm_c0 &= ~R600_VM_ENABLE_CONTEXT;
+
+ /* disable all other contexts */
+ for (i = 1; i < 8; i++)
+ RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0);
+
+ RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12);
+ RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12);
+ RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+
+ r600_vm_flush_gart_range(dev);
+}
+
+/* load r600 microcode */
+static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv)
+{
+ int i;
+
+ r600_do_cp_stop(dev_priv);
+
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ R600_RB_NO_UPDATE |
+ (15 << 8) |
+ (3 << 0));
+
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
+ RADEON_READ(R600_GRBM_SOFT_RESET);
+ DRM_UDELAY(15000);
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
+
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)) {
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV770 PFP Microcode\n");
+ for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV770_pfp_microcode[i]);
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+ DRM_INFO("Loading RV770 CP Microcode\n");
+ for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_ME_RAM_DATA, RV770_cp_microcode[i]);
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV730)) {
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV730 PFP Microcode\n");
+ for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV730_pfp_microcode[i]);
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+ DRM_INFO("Loading RV730 CP Microcode\n");
+ for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_ME_RAM_DATA, RV730_cp_microcode[i]);
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) {
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV710 PFP Microcode\n");
+ for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV710_pfp_microcode[i]);
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+ DRM_INFO("Loading RV710 CP Microcode\n");
+ for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_ME_RAM_DATA, RV710_cp_microcode[i]);
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+
+ }
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+ RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0);
+
+}
+
+static void r600_test_writeback(drm_radeon_private_t *dev_priv)
+{
+ u32 tmp;
+
+ /* Start with assuming that writeback doesn't work */
+ dev_priv->writeback_works = 0;
+
+ /* Writeback doesn't seem to work everywhere, test it here and possibly
+ * enable it if it appears to work
+ */
+ radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0);
+
+ RADEON_WRITE(R600_SCRATCH_REG1, 0xdeadbeef);
+
+ for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
+ u32 val;
+
+ val = radeon_read_ring_rptr(dev_priv, R600_SCRATCHOFF(1));
+ if (val == 0xdeadbeef)
+ break;
+ DRM_UDELAY(1);
+ }
+
+ if (tmp < dev_priv->usec_timeout) {
+ dev_priv->writeback_works = 1;
+ DRM_INFO("writeback test succeeded in %d usecs\n", tmp);
+ } else {
+ dev_priv->writeback_works = 0;
+ DRM_INFO("writeback test failed\n");
+ }
+ if (radeon_no_wb == 1) {
+ dev_priv->writeback_works = 0;
+ DRM_INFO("writeback forced off\n");
+ }
+
+ if (!dev_priv->writeback_works) {
+ /* Disable writeback to avoid unnecessary bus master transfer */
+ RADEON_WRITE(R600_CP_RB_CNTL, RADEON_READ(R600_CP_RB_CNTL) |
+ RADEON_RB_NO_UPDATE);
+ RADEON_WRITE(R600_SCRATCH_UMSK, 0);
+ }
+}
+
+int r600_do_engine_reset(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ u32 cp_ptr, cp_me_cntl, cp_rb_cntl;
+
+ DRM_INFO("Resetting GPU\n");
+
+ cp_ptr = RADEON_READ(R600_CP_RB_WPTR);
+ cp_me_cntl = RADEON_READ(R600_CP_ME_CNTL);
+ RADEON_WRITE(R600_CP_ME_CNTL, R600_CP_ME_HALT);
+
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0x7fff);
+ RADEON_READ(R600_GRBM_SOFT_RESET);
+ DRM_UDELAY(50);
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
+ RADEON_READ(R600_GRBM_SOFT_RESET);
+
+ RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0);
+ cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL);
+ RADEON_WRITE(R600_CP_RB_CNTL, R600_RB_RPTR_WR_ENA);
+
+ RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr);
+ RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr);
+ RADEON_WRITE(R600_CP_RB_CNTL, cp_rb_cntl);
+ RADEON_WRITE(R600_CP_ME_CNTL, cp_me_cntl);
+
+ /* Reset the CP ring */
+ r600_do_cp_reset(dev_priv);
+
+ /* The CP is no longer running after an engine reset */
+ dev_priv->cp_running = 0;
+
+ /* Reset any pending vertex, indirect buffers */
+ radeon_freelist_reset(dev);
+
+ return 0;
+
+}
+
+static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
+ u32 num_backends,
+ u32 backend_disable_mask)
+{
+ u32 backend_map = 0;
+ u32 enabled_backends_mask;
+ u32 enabled_backends_count;
+ u32 cur_pipe;
+ u32 swizzle_pipe[R6XX_MAX_PIPES];
+ u32 cur_backend;
+ u32 i;
+
+ if (num_tile_pipes > R6XX_MAX_PIPES)
+ num_tile_pipes = R6XX_MAX_PIPES;
+ if (num_tile_pipes < 1)
+ num_tile_pipes = 1;
+ if (num_backends > R6XX_MAX_BACKENDS)
+ num_backends = R6XX_MAX_BACKENDS;
+ if (num_backends < 1)
+ num_backends = 1;
+
+ enabled_backends_mask = 0;
+ enabled_backends_count = 0;
+ for (i = 0; i < R6XX_MAX_BACKENDS; ++i) {
+ if (((backend_disable_mask >> i) & 1) == 0) {
+ enabled_backends_mask |= (1 << i);
+ ++enabled_backends_count;
+ }
+ if (enabled_backends_count == num_backends)
+ break;
+ }
+
+ if (enabled_backends_count == 0) {
+ enabled_backends_mask = 1;
+ enabled_backends_count = 1;
+ }
+
+ if (enabled_backends_count != num_backends)
+ num_backends = enabled_backends_count;
+
+ memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES);
+ switch (num_tile_pipes) {
+ case 1:
+ swizzle_pipe[0] = 0;
+ break;
+ case 2:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 1;
+ break;
+ case 3:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 1;
+ swizzle_pipe[2] = 2;
+ break;
+ case 4:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 1;
+ swizzle_pipe[2] = 2;
+ swizzle_pipe[3] = 3;
+ break;
+ case 5:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 1;
+ swizzle_pipe[2] = 2;
+ swizzle_pipe[3] = 3;
+ swizzle_pipe[4] = 4;
+ break;
+ case 6:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 5;
+ swizzle_pipe[4] = 1;
+ swizzle_pipe[5] = 3;
+ break;
+ case 7:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 6;
+ swizzle_pipe[4] = 1;
+ swizzle_pipe[5] = 3;
+ swizzle_pipe[6] = 5;
+ break;
+ case 8:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 6;
+ swizzle_pipe[4] = 1;
+ swizzle_pipe[5] = 3;
+ swizzle_pipe[6] = 5;
+ swizzle_pipe[7] = 7;
+ break;
+ }
+
+ cur_backend = 0;
+ for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) {
+ while (((1 << cur_backend) & enabled_backends_mask) == 0)
+ cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
+
+ backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2)));
+
+ cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
+ }
+
+ return backend_map;
+}
+
+static int r600_count_pipe_bits(uint32_t val)
+{
+ int i, ret = 0;
+ for (i = 0; i < 32; i++) {
+ ret += val & 1;
+ val >>= 1;
+ }
+ return ret;
+}
+
+static void r600_gfx_init(struct drm_device *dev,
+ drm_radeon_private_t *dev_priv)
+{
+ int i, j, num_qd_pipes;
+ u32 sx_debug_1;
+ u32 tc_cntl;
+ u32 arb_pop;
+ u32 num_gs_verts_per_thread;
+ u32 vgt_gs_per_es;
+ u32 gs_prim_buffer_depth = 0;
+ u32 sq_ms_fifo_sizes;
+ u32 sq_config;
+ u32 sq_gpr_resource_mgmt_1 = 0;
+ u32 sq_gpr_resource_mgmt_2 = 0;
+ u32 sq_thread_resource_mgmt = 0;
+ u32 sq_stack_resource_mgmt_1 = 0;
+ u32 sq_stack_resource_mgmt_2 = 0;
+ u32 hdp_host_path_cntl;
+ u32 backend_map;
+ u32 gb_tiling_config = 0;
+ u32 cc_rb_backend_disable = 0;
+ u32 cc_gc_shader_pipe_config = 0;
+ u32 ramcfg;
+
+ /* setup chip specs */
+ switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+ case CHIP_R600:
+ dev_priv->r600_max_pipes = 4;
+ dev_priv->r600_max_tile_pipes = 8;
+ dev_priv->r600_max_simds = 4;
+ dev_priv->r600_max_backends = 4;
+ dev_priv->r600_max_gprs = 256;
+ dev_priv->r600_max_threads = 192;
+ dev_priv->r600_max_stack_entries = 256;
+ dev_priv->r600_max_hw_contexts = 8;
+ dev_priv->r600_max_gs_threads = 16;
+ dev_priv->r600_sx_max_export_size = 128;
+ dev_priv->r600_sx_max_export_pos_size = 16;
+ dev_priv->r600_sx_max_export_smx_size = 128;
+ dev_priv->r600_sq_num_cf_insts = 2;
+ break;
+ case CHIP_RV630:
+ case CHIP_RV635:
+ dev_priv->r600_max_pipes = 2;
+ dev_priv->r600_max_tile_pipes = 2;
+ dev_priv->r600_max_simds = 3;
+ dev_priv->r600_max_backends = 1;
+ dev_priv->r600_max_gprs = 128;
+ dev_priv->r600_max_threads = 192;
+ dev_priv->r600_max_stack_entries = 128;
+ dev_priv->r600_max_hw_contexts = 8;
+ dev_priv->r600_max_gs_threads = 4;
+ dev_priv->r600_sx_max_export_size = 128;
+ dev_priv->r600_sx_max_export_pos_size = 16;
+ dev_priv->r600_sx_max_export_smx_size = 128;
+ dev_priv->r600_sq_num_cf_insts = 2;
+ break;
+ case CHIP_RV610:
+ case CHIP_RS780:
+ case CHIP_RV620:
+ dev_priv->r600_max_pipes = 1;
+ dev_priv->r600_max_tile_pipes = 1;
+ dev_priv->r600_max_simds = 2;
+ dev_priv->r600_max_backends = 1;
+ dev_priv->r600_max_gprs = 128;
+ dev_priv->r600_max_threads = 192;
+ dev_priv->r600_max_stack_entries = 128;
+ dev_priv->r600_max_hw_contexts = 4;
+ dev_priv->r600_max_gs_threads = 4;
+ dev_priv->r600_sx_max_export_size = 128;
+ dev_priv->r600_sx_max_export_pos_size = 16;
+ dev_priv->r600_sx_max_export_smx_size = 128;
+ dev_priv->r600_sq_num_cf_insts = 1;
+ break;
+ case CHIP_RV670:
+ dev_priv->r600_max_pipes = 4;
+ dev_priv->r600_max_tile_pipes = 4;
+ dev_priv->r600_max_simds = 4;
+ dev_priv->r600_max_backends = 4;
+ dev_priv->r600_max_gprs = 192;
+ dev_priv->r600_max_threads = 192;
+ dev_priv->r600_max_stack_entries = 256;
+ dev_priv->r600_max_hw_contexts = 8;
+ dev_priv->r600_max_gs_threads = 16;
+ dev_priv->r600_sx_max_export_size = 128;
+ dev_priv->r600_sx_max_export_pos_size = 16;
+ dev_priv->r600_sx_max_export_smx_size = 128;
+ dev_priv->r600_sq_num_cf_insts = 2;
+ break;
+ default:
+ break;
+ }
+
+ /* Initialize HDP */
+ j = 0;
+ for (i = 0; i < 32; i++) {
+ RADEON_WRITE((0x2c14 + j), 0x00000000);
+ RADEON_WRITE((0x2c18 + j), 0x00000000);
+ RADEON_WRITE((0x2c1c + j), 0x00000000);
+ RADEON_WRITE((0x2c20 + j), 0x00000000);
+ RADEON_WRITE((0x2c24 + j), 0x00000000);
+ j += 0x18;
+ }
+
+ RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff));
+
+ /* setup tiling, simd, pipe config */
+ ramcfg = RADEON_READ(R600_RAMCFG);
+
+ switch (dev_priv->r600_max_tile_pipes) {
+ case 1:
+ gb_tiling_config |= R600_PIPE_TILING(0);
+ break;
+ case 2:
+ gb_tiling_config |= R600_PIPE_TILING(1);
+ break;
+ case 4:
+ gb_tiling_config |= R600_PIPE_TILING(2);
+ break;
+ case 8:
+ gb_tiling_config |= R600_PIPE_TILING(3);
+ break;
+ default:
+ break;
+ }
+
+ gb_tiling_config |= R600_BANK_TILING((ramcfg >> R600_NOOFBANK_SHIFT) & R600_NOOFBANK_MASK);
+
+ gb_tiling_config |= R600_GROUP_SIZE(0);
+
+ if (((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK) > 3) {
+ gb_tiling_config |= R600_ROW_TILING(3);
+ gb_tiling_config |= R600_SAMPLE_SPLIT(3);
+ } else {
+ gb_tiling_config |=
+ R600_ROW_TILING(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK));
+ gb_tiling_config |=
+ R600_SAMPLE_SPLIT(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK));
+ }
+
+ gb_tiling_config |= R600_BANK_SWAPS(1);
+
+ backend_map = r600_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes,
+ dev_priv->r600_max_backends,
+ (0xff << dev_priv->r600_max_backends) & 0xff);
+ gb_tiling_config |= R600_BACKEND_MAP(backend_map);
+
+ cc_gc_shader_pipe_config =
+ R600_INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R6XX_MAX_PIPES_MASK);
+ cc_gc_shader_pipe_config |=
+ R600_INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R6XX_MAX_SIMDS_MASK);
+
+ cc_rb_backend_disable =
+ R600_BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R6XX_MAX_BACKENDS_MASK);
+
+ RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config);
+ RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
+ RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff));
+
+ RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
+ RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+ RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+
+ num_qd_pipes =
+ R6XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK);
+ RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK);
+ RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK);
+
+ /* set HW defaults for 3D engine */
+ RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) |
+ R600_ROQ_IB2_START(0x2b)));
+
+ RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, (R600_MEQ_END(0x40) |
+ R600_ROQ_END(0x40)));
+
+ RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO |
+ R600_SYNC_GRADIENT |
+ R600_SYNC_WALKER |
+ R600_SYNC_ALIGNER));
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670)
+ RADEON_WRITE(R600_ARB_GDEC_RD_CNTL, 0x00000021);
+
+ sx_debug_1 = RADEON_READ(R600_SX_DEBUG_1);
+ sx_debug_1 |= R600_SMX_EVENT_RELEASE;
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600))
+ sx_debug_1 |= R600_ENABLE_NEW_SMX_ADDRESS;
+ RADEON_WRITE(R600_SX_DEBUG_1, sx_debug_1);
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780))
+ RADEON_WRITE(R600_DB_DEBUG, R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE);
+ else
+ RADEON_WRITE(R600_DB_DEBUG, 0);
+
+ RADEON_WRITE(R600_DB_WATERMARKS, (R600_DEPTH_FREE(4) |
+ R600_DEPTH_FLUSH(16) |
+ R600_DEPTH_PENDING_FREE(4) |
+ R600_DEPTH_CACHELINE_FREE(16)));
+ RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0);
+ RADEON_WRITE(R600_VGT_NUM_INSTANCES, 0);
+
+ RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0));
+ RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(0));
+
+ sq_ms_fifo_sizes = RADEON_READ(R600_SQ_MS_FIFO_SIZES);
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) {
+ sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(0xa) |
+ R600_FETCH_FIFO_HIWATER(0xa) |
+ R600_DONE_FIFO_HIWATER(0xe0) |
+ R600_ALU_UPDATE_FIFO_HIWATER(0x8));
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) {
+ sq_ms_fifo_sizes &= ~R600_DONE_FIFO_HIWATER(0xff);
+ sq_ms_fifo_sizes |= R600_DONE_FIFO_HIWATER(0x4);
+ }
+ RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes);
+
+ /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
+ * should be adjusted as needed by the 2D/3D drivers. This just sets default values
+ */
+ sq_config = RADEON_READ(R600_SQ_CONFIG);
+ sq_config &= ~(R600_PS_PRIO(3) |
+ R600_VS_PRIO(3) |
+ R600_GS_PRIO(3) |
+ R600_ES_PRIO(3));
+ sq_config |= (R600_DX9_CONSTS |
+ R600_VC_ENABLE |
+ R600_PS_PRIO(0) |
+ R600_VS_PRIO(1) |
+ R600_GS_PRIO(2) |
+ R600_ES_PRIO(3));
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) {
+ sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(124) |
+ R600_NUM_VS_GPRS(124) |
+ R600_NUM_CLAUSE_TEMP_GPRS(4));
+ sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(0) |
+ R600_NUM_ES_GPRS(0));
+ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(136) |
+ R600_NUM_VS_THREADS(48) |
+ R600_NUM_GS_THREADS(4) |
+ R600_NUM_ES_THREADS(4));
+ sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(128) |
+ R600_NUM_VS_STACK_ENTRIES(128));
+ sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(0) |
+ R600_NUM_ES_STACK_ENTRIES(0));
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) {
+ /* no vertex cache */
+ sq_config &= ~R600_VC_ENABLE;
+
+ sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) |
+ R600_NUM_VS_GPRS(44) |
+ R600_NUM_CLAUSE_TEMP_GPRS(2));
+ sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) |
+ R600_NUM_ES_GPRS(17));
+ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) |
+ R600_NUM_VS_THREADS(78) |
+ R600_NUM_GS_THREADS(4) |
+ R600_NUM_ES_THREADS(31));
+ sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) |
+ R600_NUM_VS_STACK_ENTRIES(40));
+ sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) |
+ R600_NUM_ES_STACK_ENTRIES(16));
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) {
+ sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) |
+ R600_NUM_VS_GPRS(44) |
+ R600_NUM_CLAUSE_TEMP_GPRS(2));
+ sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(18) |
+ R600_NUM_ES_GPRS(18));
+ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) |
+ R600_NUM_VS_THREADS(78) |
+ R600_NUM_GS_THREADS(4) |
+ R600_NUM_ES_THREADS(31));
+ sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) |
+ R600_NUM_VS_STACK_ENTRIES(40));
+ sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) |
+ R600_NUM_ES_STACK_ENTRIES(16));
+ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) {
+ sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) |
+ R600_NUM_VS_GPRS(44) |
+ R600_NUM_CLAUSE_TEMP_GPRS(2));
+ sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) |
+ R600_NUM_ES_GPRS(17));
+ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) |
+ R600_NUM_VS_THREADS(78) |
+ R600_NUM_GS_THREADS(4) |
+ R600_NUM_ES_THREADS(31));
+ sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(64) |
+ R600_NUM_VS_STACK_ENTRIES(64));
+ sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(64) |
+ R600_NUM_ES_STACK_ENTRIES(64));
+ }
+
+ RADEON_WRITE(R600_SQ_CONFIG, sq_config);
+ RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1);
+ RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2);
+ RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
+ RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1);
+ RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2);
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780))
+ RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_TC_ONLY));
+ else
+ RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_VC_AND_TC));
+
+ RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_2S, (R600_S0_X(0xc) |
+ R600_S0_Y(0x4) |
+ R600_S1_X(0x4) |
+ R600_S1_Y(0xc)));
+ RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_4S, (R600_S0_X(0xe) |
+ R600_S0_Y(0xe) |
+ R600_S1_X(0x2) |
+ R600_S1_Y(0x2) |
+ R600_S2_X(0xa) |
+ R600_S2_Y(0x6) |
+ R600_S3_X(0x6) |
+ R600_S3_Y(0xa)));
+ RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0, (R600_S0_X(0xe) |
+ R600_S0_Y(0xb) |
+ R600_S1_X(0x4) |
+ R600_S1_Y(0xc) |
+ R600_S2_X(0x1) |
+ R600_S2_Y(0x6) |
+ R600_S3_X(0xa) |
+ R600_S3_Y(0xe)));
+ RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1, (R600_S4_X(0x6) |
+ R600_S4_Y(0x1) |
+ R600_S5_X(0x0) |
+ R600_S5_Y(0x0) |
+ R600_S6_X(0xb) |
+ R600_S6_Y(0x4) |
+ R600_S7_X(0x7) |
+ R600_S7_Y(0x8)));
+
+
+ switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+ case CHIP_R600:
+ case CHIP_RV630:
+ case CHIP_RV635:
+ gs_prim_buffer_depth = 0;
+ break;
+ case CHIP_RV610:
+ case CHIP_RS780:
+ case CHIP_RV620:
+ gs_prim_buffer_depth = 32;
+ break;
+ case CHIP_RV670:
+ gs_prim_buffer_depth = 128;
+ break;
+ default:
+ break;
+ }
+
+ num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16;
+ vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread;
+ /* Max value for this is 256 */
+ if (vgt_gs_per_es > 256)
+ vgt_gs_per_es = 256;
+
+ RADEON_WRITE(R600_VGT_ES_PER_GS, 128);
+ RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es);
+ RADEON_WRITE(R600_VGT_GS_PER_VS, 2);
+ RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16);
+
+ /* more default values. 2D/3D driver should adjust as needed */
+ RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0);
+ RADEON_WRITE(R600_VGT_STRMOUT_EN, 0);
+ RADEON_WRITE(R600_SX_MISC, 0);
+ RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0);
+ RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0);
+ RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0);
+ RADEON_WRITE(R600_SPI_INPUT_Z, 0);
+ RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2));
+ RADEON_WRITE(R600_CB_COLOR7_FRAG, 0);
+
+ /* clear render buffer base addresses */
+ RADEON_WRITE(R600_CB_COLOR0_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR1_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR2_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR3_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR4_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR5_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR6_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR7_BASE, 0);
+
+ switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+ case CHIP_RV610:
+ case CHIP_RS780:
+ case CHIP_RV620:
+ tc_cntl = R600_TC_L2_SIZE(8);
+ break;
+ case CHIP_RV630:
+ case CHIP_RV635:
+ tc_cntl = R600_TC_L2_SIZE(4);
+ break;
+ case CHIP_R600:
+ tc_cntl = R600_TC_L2_SIZE(0) | R600_L2_DISABLE_LATE_HIT;
+ break;
+ default:
+ tc_cntl = R600_TC_L2_SIZE(0);
+ break;
+ }
+
+ RADEON_WRITE(R600_TC_CNTL, tc_cntl);
+
+ hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL);
+ RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
+
+ arb_pop = RADEON_READ(R600_ARB_POP);
+ arb_pop |= R600_ENABLE_TC128;
+ RADEON_WRITE(R600_ARB_POP, arb_pop);
+
+ RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0);
+ RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA |
+ R600_NUM_CLIP_SEQ(3)));
+ RADEON_WRITE(R600_PA_SC_ENHANCE, R600_FORCE_EOV_MAX_CLK_CNT(4095));
+
+}
+
+static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
+ u32 num_backends,
+ u32 backend_disable_mask)
+{
+ u32 backend_map = 0;
+ u32 enabled_backends_mask;
+ u32 enabled_backends_count;
+ u32 cur_pipe;
+ u32 swizzle_pipe[R7XX_MAX_PIPES];
+ u32 cur_backend;
+ u32 i;
+
+ if (num_tile_pipes > R7XX_MAX_PIPES)
+ num_tile_pipes = R7XX_MAX_PIPES;
+ if (num_tile_pipes < 1)
+ num_tile_pipes = 1;
+ if (num_backends > R7XX_MAX_BACKENDS)
+ num_backends = R7XX_MAX_BACKENDS;
+ if (num_backends < 1)
+ num_backends = 1;
+
+ enabled_backends_mask = 0;
+ enabled_backends_count = 0;
+ for (i = 0; i < R7XX_MAX_BACKENDS; ++i) {
+ if (((backend_disable_mask >> i) & 1) == 0) {
+ enabled_backends_mask |= (1 << i);
+ ++enabled_backends_count;
+ }
+ if (enabled_backends_count == num_backends)
+ break;
+ }
+
+ if (enabled_backends_count == 0) {
+ enabled_backends_mask = 1;
+ enabled_backends_count = 1;
+ }
+
+ if (enabled_backends_count != num_backends)
+ num_backends = enabled_backends_count;
+
+ memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES);
+ switch (num_tile_pipes) {
+ case 1:
+ swizzle_pipe[0] = 0;
+ break;
+ case 2:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 1;
+ break;
+ case 3:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 1;
+ break;
+ case 4:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 3;
+ swizzle_pipe[3] = 1;
+ break;
+ case 5:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 1;
+ swizzle_pipe[4] = 3;
+ break;
+ case 6:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 5;
+ swizzle_pipe[4] = 3;
+ swizzle_pipe[5] = 1;
+ break;
+ case 7:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 6;
+ swizzle_pipe[4] = 3;
+ swizzle_pipe[5] = 1;
+ swizzle_pipe[6] = 5;
+ break;
+ case 8:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 6;
+ swizzle_pipe[4] = 3;
+ swizzle_pipe[5] = 1;
+ swizzle_pipe[6] = 7;
+ swizzle_pipe[7] = 5;
+ break;
+ }
+
+ cur_backend = 0;
+ for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) {
+ while (((1 << cur_backend) & enabled_backends_mask) == 0)
+ cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS;
+
+ backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2)));
+
+ cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS;
+ }
+
+ return backend_map;
+}
+
+static void r700_gfx_init(struct drm_device *dev,
+ drm_radeon_private_t *dev_priv)
+{
+ int i, j, num_qd_pipes;
+ u32 sx_debug_1;
+ u32 smx_dc_ctl0;
+ u32 num_gs_verts_per_thread;
+ u32 vgt_gs_per_es;
+ u32 gs_prim_buffer_depth = 0;
+ u32 sq_ms_fifo_sizes;
+ u32 sq_config;
+ u32 sq_thread_resource_mgmt;
+ u32 hdp_host_path_cntl;
+ u32 sq_dyn_gpr_size_simd_ab_0;
+ u32 backend_map;
+ u32 gb_tiling_config = 0;
+ u32 cc_rb_backend_disable = 0;
+ u32 cc_gc_shader_pipe_config = 0;
+ u32 mc_arb_ramcfg;
+ u32 db_debug4;
+
+ /* setup chip specs */
+ switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+ case CHIP_RV770:
+ dev_priv->r600_max_pipes = 4;
+ dev_priv->r600_max_tile_pipes = 8;
+ dev_priv->r600_max_simds = 10;
+ dev_priv->r600_max_backends = 4;
+ dev_priv->r600_max_gprs = 256;
+ dev_priv->r600_max_threads = 248;
+ dev_priv->r600_max_stack_entries = 512;
+ dev_priv->r600_max_hw_contexts = 8;
+ dev_priv->r600_max_gs_threads = 16 * 2;
+ dev_priv->r600_sx_max_export_size = 128;
+ dev_priv->r600_sx_max_export_pos_size = 16;
+ dev_priv->r600_sx_max_export_smx_size = 112;
+ dev_priv->r600_sq_num_cf_insts = 2;
+
+ dev_priv->r700_sx_num_of_sets = 7;
+ dev_priv->r700_sc_prim_fifo_size = 0xF9;
+ dev_priv->r700_sc_hiz_tile_fifo_size = 0x30;
+ dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130;
+ break;
+ case CHIP_RV730:
+ dev_priv->r600_max_pipes = 2;
+ dev_priv->r600_max_tile_pipes = 4;
+ dev_priv->r600_max_simds = 8;
+ dev_priv->r600_max_backends = 2;
+ dev_priv->r600_max_gprs = 128;
+ dev_priv->r600_max_threads = 248;
+ dev_priv->r600_max_stack_entries = 256;
+ dev_priv->r600_max_hw_contexts = 8;
+ dev_priv->r600_max_gs_threads = 16 * 2;
+ dev_priv->r600_sx_max_export_size = 256;
+ dev_priv->r600_sx_max_export_pos_size = 32;
+ dev_priv->r600_sx_max_export_smx_size = 224;
+ dev_priv->r600_sq_num_cf_insts = 2;
+
+ dev_priv->r700_sx_num_of_sets = 7;
+ dev_priv->r700_sc_prim_fifo_size = 0xf9;
+ dev_priv->r700_sc_hiz_tile_fifo_size = 0x30;
+ dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130;
+ break;
+ case CHIP_RV710:
+ dev_priv->r600_max_pipes = 2;
+ dev_priv->r600_max_tile_pipes = 2;
+ dev_priv->r600_max_simds = 2;
+ dev_priv->r600_max_backends = 1;
+ dev_priv->r600_max_gprs = 256;
+ dev_priv->r600_max_threads = 192;
+ dev_priv->r600_max_stack_entries = 256;
+ dev_priv->r600_max_hw_contexts = 4;
+ dev_priv->r600_max_gs_threads = 8 * 2;
+ dev_priv->r600_sx_max_export_size = 128;
+ dev_priv->r600_sx_max_export_pos_size = 16;
+ dev_priv->r600_sx_max_export_smx_size = 112;
+ dev_priv->r600_sq_num_cf_insts = 1;
+
+ dev_priv->r700_sx_num_of_sets = 7;
+ dev_priv->r700_sc_prim_fifo_size = 0x40;
+ dev_priv->r700_sc_hiz_tile_fifo_size = 0x30;
+ dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130;
+ break;
+ default:
+ break;
+ }
+
+ /* Initialize HDP */
+ j = 0;
+ for (i = 0; i < 32; i++) {
+ RADEON_WRITE((0x2c14 + j), 0x00000000);
+ RADEON_WRITE((0x2c18 + j), 0x00000000);
+ RADEON_WRITE((0x2c1c + j), 0x00000000);
+ RADEON_WRITE((0x2c20 + j), 0x00000000);
+ RADEON_WRITE((0x2c24 + j), 0x00000000);
+ j += 0x18;
+ }
+
+ RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff));
+
+ /* setup tiling, simd, pipe config */
+ mc_arb_ramcfg = RADEON_READ(R700_MC_ARB_RAMCFG);
+
+ switch (dev_priv->r600_max_tile_pipes) {
+ case 1:
+ gb_tiling_config |= R600_PIPE_TILING(0);
+ break;
+ case 2:
+ gb_tiling_config |= R600_PIPE_TILING(1);
+ break;
+ case 4:
+ gb_tiling_config |= R600_PIPE_TILING(2);
+ break;
+ case 8:
+ gb_tiling_config |= R600_PIPE_TILING(3);
+ break;
+ default:
+ break;
+ }
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)
+ gb_tiling_config |= R600_BANK_TILING(1);
+ else
+ gb_tiling_config |= R600_BANK_TILING((mc_arb_ramcfg >> R700_NOOFBANK_SHIFT) & R700_NOOFBANK_MASK);
+
+ gb_tiling_config |= R600_GROUP_SIZE(0);
+
+ if (((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK) > 3) {
+ gb_tiling_config |= R600_ROW_TILING(3);
+ gb_tiling_config |= R600_SAMPLE_SPLIT(3);
+ } else {
+ gb_tiling_config |=
+ R600_ROW_TILING(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK));
+ gb_tiling_config |=
+ R600_SAMPLE_SPLIT(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK));
+ }
+
+ gb_tiling_config |= R600_BANK_SWAPS(1);
+
+ backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes,
+ dev_priv->r600_max_backends,
+ (0xff << dev_priv->r600_max_backends) & 0xff);
+ gb_tiling_config |= R600_BACKEND_MAP(backend_map);
+
+ cc_gc_shader_pipe_config =
+ R600_INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R7XX_MAX_PIPES_MASK);
+ cc_gc_shader_pipe_config |=
+ R600_INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R7XX_MAX_SIMDS_MASK);
+
+ cc_rb_backend_disable =
+ R600_BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R7XX_MAX_BACKENDS_MASK);
+
+ RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config);
+ RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
+ RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff));
+
+ RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
+ RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+ RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+
+ RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
+ RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0);
+ RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0);
+ RADEON_WRITE(R700_CGTS_USER_SYS_TCC_DISABLE, 0);
+ RADEON_WRITE(R700_CGTS_USER_TCC_DISABLE, 0);
+
+ num_qd_pipes =
+ R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK);
+ RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK);
+ RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK);
+
+ /* set HW defaults for 3D engine */
+ RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) |
+ R600_ROQ_IB2_START(0x2b)));
+
+ RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, R700_STQ_SPLIT(0x30));
+
+ RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO |
+ R600_SYNC_GRADIENT |
+ R600_SYNC_WALKER |
+ R600_SYNC_ALIGNER));
+
+ sx_debug_1 = RADEON_READ(R700_SX_DEBUG_1);
+ sx_debug_1 |= R700_ENABLE_NEW_SMX_ADDRESS;
+ RADEON_WRITE(R700_SX_DEBUG_1, sx_debug_1);
+
+ smx_dc_ctl0 = RADEON_READ(R600_SMX_DC_CTL0);
+ smx_dc_ctl0 &= ~R700_CACHE_DEPTH(0x1ff);
+ smx_dc_ctl0 |= R700_CACHE_DEPTH((dev_priv->r700_sx_num_of_sets * 64) - 1);
+ RADEON_WRITE(R600_SMX_DC_CTL0, smx_dc_ctl0);
+
+ RADEON_WRITE(R700_SMX_EVENT_CTL, (R700_ES_FLUSH_CTL(4) |
+ R700_GS_FLUSH_CTL(4) |
+ R700_ACK_FLUSH_CTL(3) |
+ R700_SYNC_FLUSH_CTL));
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)
+ RADEON_WRITE(R700_DB_DEBUG3, R700_DB_CLK_OFF_DELAY(0x1f));
+ else {
+ db_debug4 = RADEON_READ(RV700_DB_DEBUG4);
+ db_debug4 |= RV700_DISABLE_TILE_COVERED_FOR_PS_ITER;
+ RADEON_WRITE(RV700_DB_DEBUG4, db_debug4);
+ }
+
+ RADEON_WRITE(R600_SX_EXPORT_BUFFER_SIZES, (R600_COLOR_BUFFER_SIZE((dev_priv->r600_sx_max_export_size / 4) - 1) |
+ R600_POSITION_BUFFER_SIZE((dev_priv->r600_sx_max_export_pos_size / 4) - 1) |
+ R600_SMX_BUFFER_SIZE((dev_priv->r600_sx_max_export_smx_size / 4) - 1)));
+
+ RADEON_WRITE(R700_PA_SC_FIFO_SIZE_R7XX, (R700_SC_PRIM_FIFO_SIZE(dev_priv->r700_sc_prim_fifo_size) |
+ R700_SC_HIZ_TILE_FIFO_SIZE(dev_priv->r700_sc_hiz_tile_fifo_size) |
+ R700_SC_EARLYZ_TILE_FIFO_SIZE(dev_priv->r700_sc_earlyz_tile_fifo_fize)));
+
+ RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0);
+
+ RADEON_WRITE(R600_VGT_NUM_INSTANCES, 1);
+
+ RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0));
+
+ RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(4));
+
+ RADEON_WRITE(R600_CP_PERFMON_CNTL, 0);
+
+ sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(16 * dev_priv->r600_sq_num_cf_insts) |
+ R600_DONE_FIFO_HIWATER(0xe0) |
+ R600_ALU_UPDATE_FIFO_HIWATER(0x8));
+ switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+ case CHIP_RV770:
+ sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x1);
+ break;
+ case CHIP_RV730:
+ case CHIP_RV710:
+ default:
+ sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x4);
+ break;
+ }
+ RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes);
+
+ /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
+ * should be adjusted as needed by the 2D/3D drivers. This just sets default values
+ */
+ sq_config = RADEON_READ(R600_SQ_CONFIG);
+ sq_config &= ~(R600_PS_PRIO(3) |
+ R600_VS_PRIO(3) |
+ R600_GS_PRIO(3) |
+ R600_ES_PRIO(3));
+ sq_config |= (R600_DX9_CONSTS |
+ R600_VC_ENABLE |
+ R600_EXPORT_SRC_C |
+ R600_PS_PRIO(0) |
+ R600_VS_PRIO(1) |
+ R600_GS_PRIO(2) |
+ R600_ES_PRIO(3));
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)
+ /* no vertex cache */
+ sq_config &= ~R600_VC_ENABLE;
+
+ RADEON_WRITE(R600_SQ_CONFIG, sq_config);
+
+ RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, (R600_NUM_PS_GPRS((dev_priv->r600_max_gprs * 24)/64) |
+ R600_NUM_VS_GPRS((dev_priv->r600_max_gprs * 24)/64) |
+ R600_NUM_CLAUSE_TEMP_GPRS(((dev_priv->r600_max_gprs * 24)/64)/2)));
+
+ RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, (R600_NUM_GS_GPRS((dev_priv->r600_max_gprs * 7)/64) |
+ R600_NUM_ES_GPRS((dev_priv->r600_max_gprs * 7)/64)));
+
+ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS((dev_priv->r600_max_threads * 4)/8) |
+ R600_NUM_VS_THREADS((dev_priv->r600_max_threads * 2)/8) |
+ R600_NUM_ES_THREADS((dev_priv->r600_max_threads * 1)/8));
+ if (((dev_priv->r600_max_threads * 1) / 8) > dev_priv->r600_max_gs_threads)
+ sq_thread_resource_mgmt |= R600_NUM_GS_THREADS(dev_priv->r600_max_gs_threads);
+ else
+ sq_thread_resource_mgmt |= R600_NUM_GS_THREADS((dev_priv->r600_max_gs_threads * 1)/8);
+ RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
+
+ RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, (R600_NUM_PS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) |
+ R600_NUM_VS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4)));
+
+ RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, (R600_NUM_GS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) |
+ R600_NUM_ES_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4)));
+
+ sq_dyn_gpr_size_simd_ab_0 = (R700_SIMDA_RING0((dev_priv->r600_max_gprs * 38)/64) |
+ R700_SIMDA_RING1((dev_priv->r600_max_gprs * 38)/64) |
+ R700_SIMDB_RING0((dev_priv->r600_max_gprs * 38)/64) |
+ R700_SIMDB_RING1((dev_priv->r600_max_gprs * 38)/64));
+
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0);
+
+ RADEON_WRITE(R700_PA_SC_FORCE_EOV_MAX_CNTS, (R700_FORCE_EOV_MAX_CLK_CNT(4095) |
+ R700_FORCE_EOV_MAX_REZ_CNT(255)));
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)
+ RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_TC_ONLY) |
+ R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO)));
+ else
+ RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_VC_AND_TC) |
+ R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO)));
+
+ switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+ case CHIP_RV770:
+ case CHIP_RV730:
+ gs_prim_buffer_depth = 384;
+ break;
+ case CHIP_RV710:
+ gs_prim_buffer_depth = 128;
+ break;
+ default:
+ break;
+ }
+
+ num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16;
+ vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread;
+ /* Max value for this is 256 */
+ if (vgt_gs_per_es > 256)
+ vgt_gs_per_es = 256;
+
+ RADEON_WRITE(R600_VGT_ES_PER_GS, 128);
+ RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es);
+ RADEON_WRITE(R600_VGT_GS_PER_VS, 2);
+
+ /* more default values. 2D/3D driver should adjust as needed */
+ RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16);
+ RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0);
+ RADEON_WRITE(R600_VGT_STRMOUT_EN, 0);
+ RADEON_WRITE(R600_SX_MISC, 0);
+ RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0);
+ RADEON_WRITE(R700_PA_SC_EDGERULE, 0xaaaaaaaa);
+ RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0);
+ RADEON_WRITE(R600_PA_SC_CLIPRECT_RULE, 0xffff);
+ RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0);
+ RADEON_WRITE(R600_SPI_INPUT_Z, 0);
+ RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2));
+ RADEON_WRITE(R600_CB_COLOR7_FRAG, 0);
+
+ /* clear render buffer base addresses */
+ RADEON_WRITE(R600_CB_COLOR0_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR1_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR2_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR3_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR4_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR5_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR6_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR7_BASE, 0);
+
+ RADEON_WRITE(R700_TCP_CNTL, 0);
+
+ hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL);
+ RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
+
+ RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0);
+
+ RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA |
+ R600_NUM_CLIP_SEQ(3)));
+
+}
+
+static void r600_cp_init_ring_buffer(struct drm_device *dev,
+ drm_radeon_private_t *dev_priv,
+ struct drm_file *file_priv)
+{
+ struct drm_radeon_master_private *master_priv;
+ u32 ring_start;
+ u64 rptr_addr;
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770))
+ r700_gfx_init(dev, dev_priv);
+ else
+ r600_gfx_init(dev, dev_priv);
+
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
+ RADEON_READ(R600_GRBM_SOFT_RESET);
+ DRM_UDELAY(15000);
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
+
+
+ /* Set ring buffer size */
+#ifdef __BIG_ENDIAN
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ RADEON_BUF_SWAP_32BIT |
+ RADEON_RB_NO_UPDATE |
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
+#else
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ RADEON_RB_NO_UPDATE |
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
+#endif
+
+ RADEON_WRITE(R600_CP_SEM_WAIT_TIMER, 0x4);
+
+ /* Set the write pointer delay */
+ RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0);
+
+#ifdef __BIG_ENDIAN
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ RADEON_BUF_SWAP_32BIT |
+ RADEON_RB_NO_UPDATE |
+ RADEON_RB_RPTR_WR_ENA |
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
+#else
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ RADEON_RB_NO_UPDATE |
+ RADEON_RB_RPTR_WR_ENA |
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
+#endif
+
+ /* Initialize the ring buffer's read and write pointers */
+ RADEON_WRITE(R600_CP_RB_RPTR_WR, 0);
+ RADEON_WRITE(R600_CP_RB_WPTR, 0);
+ SET_RING_HEAD(dev_priv, 0);
+ dev_priv->ring.tail = 0;
+
+#if __OS_HAS_AGP
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ rptr_addr = dev_priv->ring_rptr->offset
+ - dev->agp->base +
+ dev_priv->gart_vm_start;
+ } else
+#endif
+ {
+ rptr_addr = dev_priv->ring_rptr->offset
+ - ((unsigned long) dev->sg->virtual)
+ + dev_priv->gart_vm_start;
+ }
+ RADEON_WRITE(R600_CP_RB_RPTR_ADDR,
+ rptr_addr & 0xffffffff);
+ RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI,
+ upper_32_bits(rptr_addr));
+
+#ifdef __BIG_ENDIAN
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ RADEON_BUF_SWAP_32BIT |
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
+#else
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
+#endif
+
+#if __OS_HAS_AGP
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ /* XXX */
+ radeon_write_agp_base(dev_priv, dev->agp->base);
+
+ /* XXX */
+ radeon_write_agp_location(dev_priv,
+ (((dev_priv->gart_vm_start - 1 +
+ dev_priv->gart_size) & 0xffff0000) |
+ (dev_priv->gart_vm_start >> 16)));
+
+ ring_start = (dev_priv->cp_ring->offset
+ - dev->agp->base
+ + dev_priv->gart_vm_start);
+ } else
+#endif
+ ring_start = (dev_priv->cp_ring->offset
+ - (unsigned long)dev->sg->virtual
+ + dev_priv->gart_vm_start);
+
+ RADEON_WRITE(R600_CP_RB_BASE, ring_start >> 8);
+
+ RADEON_WRITE(R600_CP_ME_CNTL, 0xff);
+
+ RADEON_WRITE(R600_CP_DEBUG, (1 << 27) | (1 << 28));
+
+ /* Initialize the scratch register pointer. This will cause
+ * the scratch register values to be written out to memory
+ * whenever they are updated.
+ *
+ * We simply put this behind the ring read pointer, this works
+ * with PCI GART as well as (whatever kind of) AGP GART
+ */
+ {
+ u64 scratch_addr;
+
+ scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR);
+ scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32;
+ scratch_addr += R600_SCRATCH_REG_OFFSET;
+ scratch_addr >>= 8;
+ scratch_addr &= 0xffffffff;
+
+ RADEON_WRITE(R600_SCRATCH_ADDR, (uint32_t)scratch_addr);
+ }
+
+ RADEON_WRITE(R600_SCRATCH_UMSK, 0x7);
+
+ /* Turn on bus mastering */
+ radeon_enable_bm(dev_priv);
+
+ radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(0), 0);
+ RADEON_WRITE(R600_LAST_FRAME_REG, 0);
+
+ radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0);
+ RADEON_WRITE(R600_LAST_DISPATCH_REG, 0);
+
+ radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(2), 0);
+ RADEON_WRITE(R600_LAST_CLEAR_REG, 0);
+
+ /* reset sarea copies of these */
+ master_priv = file_priv->master->driver_priv;
+ if (master_priv->sarea_priv) {
+ master_priv->sarea_priv->last_frame = 0;
+ master_priv->sarea_priv->last_dispatch = 0;
+ master_priv->sarea_priv->last_clear = 0;
+ }
+
+ r600_do_wait_for_idle(dev_priv);
+
+}
+
+int r600_do_cleanup_cp(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG("\n");
+
+ /* Make sure interrupts are disabled here because the uninstall ioctl
+ * may not have been called from userspace and after dev_private
+ * is freed, it's too late.
+ */
+ if (dev->irq_enabled)
+ drm_irq_uninstall(dev);
+
+#if __OS_HAS_AGP
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ if (dev_priv->cp_ring != NULL) {
+ drm_core_ioremapfree(dev_priv->cp_ring, dev);
+ dev_priv->cp_ring = NULL;
+ }
+ if (dev_priv->ring_rptr != NULL) {
+ drm_core_ioremapfree(dev_priv->ring_rptr, dev);
+ dev_priv->ring_rptr = NULL;
+ }
+ if (dev->agp_buffer_map != NULL) {
+ drm_core_ioremapfree(dev->agp_buffer_map, dev);
+ dev->agp_buffer_map = NULL;
+ }
+ } else
+#endif
+ {
+
+ if (dev_priv->gart_info.bus_addr)
+ r600_page_table_cleanup(dev, &dev_priv->gart_info);
+
+ if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) {
+ drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
+ dev_priv->gart_info.addr = NULL;
+ }
+ }
+ /* only clear to the start of flags */
+ memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
+
+ return 0;
+}
+
+int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
+ struct drm_file *file_priv)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
+
+ DRM_DEBUG("\n");
+
+ /* if we require new memory map but we don't have it fail */
+ if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) {
+ DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) {
+ DRM_DEBUG("Forcing AGP card to PCI mode\n");
+ dev_priv->flags &= ~RADEON_IS_AGP;
+ /* The writeback test succeeds, but when writeback is enabled,
+ * the ring buffer read ptr update fails after first 128 bytes.
+ */
+ radeon_no_wb = 1;
+ } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE))
+ && !init->is_pci) {
+ DRM_DEBUG("Restoring AGP flag\n");
+ dev_priv->flags |= RADEON_IS_AGP;
+ }
+
+ dev_priv->usec_timeout = init->usec_timeout;
+ if (dev_priv->usec_timeout < 1 ||
+ dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) {
+ DRM_DEBUG("TIMEOUT problem!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ /* Enable vblank on CRTC1 for older X servers
+ */
+ dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1;
+
+ dev_priv->cp_mode = init->cp_mode;
+
+ /* We don't support anything other than bus-mastering ring mode,
+ * but the ring can be in either AGP or PCI space for the ring
+ * read pointer.
+ */
+ if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) &&
+ (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) {
+ DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode);
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ switch (init->fb_bpp) {
+ case 16:
+ dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565;
+ break;
+ case 32:
+ default:
+ dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888;
+ break;
+ }
+ dev_priv->front_offset = init->front_offset;
+ dev_priv->front_pitch = init->front_pitch;
+ dev_priv->back_offset = init->back_offset;
+ dev_priv->back_pitch = init->back_pitch;
+
+ dev_priv->ring_offset = init->ring_offset;
+ dev_priv->ring_rptr_offset = init->ring_rptr_offset;
+ dev_priv->buffers_offset = init->buffers_offset;
+ dev_priv->gart_textures_offset = init->gart_textures_offset;
+
+ master_priv->sarea = drm_getsarea(dev);
+ if (!master_priv->sarea) {
+ DRM_ERROR("could not find sarea!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
+ if (!dev_priv->cp_ring) {
+ DRM_ERROR("could not find cp ring region!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+ dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
+ if (!dev_priv->ring_rptr) {
+ DRM_ERROR("could not find ring read pointer!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+ dev->agp_buffer_token = init->buffers_offset;
+ dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
+ if (!dev->agp_buffer_map) {
+ DRM_ERROR("could not find dma buffer region!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ if (init->gart_textures_offset) {
+ dev_priv->gart_textures =
+ drm_core_findmap(dev, init->gart_textures_offset);
+ if (!dev_priv->gart_textures) {
+ DRM_ERROR("could not find GART texture region!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+ }
+
+#if __OS_HAS_AGP
+ /* XXX */
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ drm_core_ioremap_wc(dev_priv->cp_ring, dev);
+ drm_core_ioremap_wc(dev_priv->ring_rptr, dev);
+ drm_core_ioremap_wc(dev->agp_buffer_map, dev);
+ if (!dev_priv->cp_ring->handle ||
+ !dev_priv->ring_rptr->handle ||
+ !dev->agp_buffer_map->handle) {
+ DRM_ERROR("could not find ioremap agp regions!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+ } else
+#endif
+ {
+ dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
+ dev_priv->ring_rptr->handle =
+ (void *)dev_priv->ring_rptr->offset;
+ dev->agp_buffer_map->handle =
+ (void *)dev->agp_buffer_map->offset;
+
+ DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
+ dev_priv->cp_ring->handle);
+ DRM_DEBUG("dev_priv->ring_rptr->handle %p\n",
+ dev_priv->ring_rptr->handle);
+ DRM_DEBUG("dev->agp_buffer_map->handle %p\n",
+ dev->agp_buffer_map->handle);
+ }
+
+ dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 24;
+ dev_priv->fb_size =
+ (((radeon_read_fb_location(dev_priv) & 0xffff0000u) << 8) + 0x1000000)
+ - dev_priv->fb_location;
+
+ dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) |
+ ((dev_priv->front_offset
+ + dev_priv->fb_location) >> 10));
+
+ dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) |
+ ((dev_priv->back_offset
+ + dev_priv->fb_location) >> 10));
+
+ dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) |
+ ((dev_priv->depth_offset
+ + dev_priv->fb_location) >> 10));
+
+ dev_priv->gart_size = init->gart_size;
+
+ /* New let's set the memory map ... */
+ if (dev_priv->new_memmap) {
+ u32 base = 0;
+
+ DRM_INFO("Setting GART location based on new memory map\n");
+
+ /* If using AGP, try to locate the AGP aperture at the same
+ * location in the card and on the bus, though we have to
+ * align it down.
+ */
+#if __OS_HAS_AGP
+ /* XXX */
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ base = dev->agp->base;
+ /* Check if valid */
+ if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location &&
+ base < (dev_priv->fb_location + dev_priv->fb_size - 1)) {
+ DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n",
+ dev->agp->base);
+ base = 0;
+ }
+ }
+#endif
+ /* If not or if AGP is at 0 (Macs), try to put it elsewhere */
+ if (base == 0) {
+ base = dev_priv->fb_location + dev_priv->fb_size;
+ if (base < dev_priv->fb_location ||
+ ((base + dev_priv->gart_size) & 0xfffffffful) < base)
+ base = dev_priv->fb_location
+ - dev_priv->gart_size;
+ }
+ dev_priv->gart_vm_start = base & 0xffc00000u;
+ if (dev_priv->gart_vm_start != base)
+ DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n",
+ base, dev_priv->gart_vm_start);
+ }
+
+#if __OS_HAS_AGP
+ /* XXX */
+ if (dev_priv->flags & RADEON_IS_AGP)
+ dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
+ - dev->agp->base
+ + dev_priv->gart_vm_start);
+ else
+#endif
+ dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
+ - (unsigned long)dev->sg->virtual
+ + dev_priv->gart_vm_start);
+
+ DRM_DEBUG("fb 0x%08x size %d\n",
+ (unsigned int) dev_priv->fb_location,
+ (unsigned int) dev_priv->fb_size);
+ DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size);
+ DRM_DEBUG("dev_priv->gart_vm_start 0x%08x\n",
+ (unsigned int) dev_priv->gart_vm_start);
+ DRM_DEBUG("dev_priv->gart_buffers_offset 0x%08lx\n",
+ dev_priv->gart_buffers_offset);
+
+ dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle;
+ dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle
+ + init->ring_size / sizeof(u32));
+ dev_priv->ring.size = init->ring_size;
+ dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
+
+ dev_priv->ring.rptr_update = /* init->rptr_update */ 4096;
+ dev_priv->ring.rptr_update_l2qw = drm_order(/* init->rptr_update */ 4096 / 8);
+
+ dev_priv->ring.fetch_size = /* init->fetch_size */ 32;
+ dev_priv->ring.fetch_size_l2ow = drm_order(/* init->fetch_size */ 32 / 16);
+
+ dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
+
+ dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
+
+#if __OS_HAS_AGP
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ /* XXX turn off pcie gart */
+ } else
+#endif
+ {
+ dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
+ /* if we have an offset set from userspace */
+ if (!dev_priv->pcigart_offset_set) {
+ DRM_ERROR("Need gart offset from userspace\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ DRM_DEBUG("Using gart offset 0x%08lx\n", dev_priv->pcigart_offset);
+
+ dev_priv->gart_info.bus_addr =
+ dev_priv->pcigart_offset + dev_priv->fb_location;
+ dev_priv->gart_info.mapping.offset =
+ dev_priv->pcigart_offset + dev_priv->fb_aper_offset;
+ dev_priv->gart_info.mapping.size =
+ dev_priv->gart_info.table_size;
+
+ drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev);
+ if (!dev_priv->gart_info.mapping.handle) {
+ DRM_ERROR("ioremap failed.\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ dev_priv->gart_info.addr =
+ dev_priv->gart_info.mapping.handle;
+
+ DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n",
+ dev_priv->gart_info.addr,
+ dev_priv->pcigart_offset);
+
+ if (!r600_page_table_init(dev)) {
+ DRM_ERROR("Failed to init GART table\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770))
+ r700_vm_init(dev);
+ else
+ r600_vm_init(dev);
+ }
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770))
+ r700_cp_load_microcode(dev_priv);
+ else
+ r600_cp_load_microcode(dev_priv);
+
+ r600_cp_init_ring_buffer(dev, dev_priv, file_priv);
+
+ dev_priv->last_buf = 0;
+
+ r600_do_engine_reset(dev);
+ r600_test_writeback(dev_priv);
+
+ return 0;
+}
+
+int r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ DRM_DEBUG("\n");
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) {
+ r700_vm_init(dev);
+ r700_cp_load_microcode(dev_priv);
+ } else {
+ r600_vm_init(dev);
+ r600_cp_load_microcode(dev_priv);
+ }
+ r600_cp_init_ring_buffer(dev, dev_priv, file_priv);
+ r600_do_engine_reset(dev);
+
+ return 0;
+}
+
+/* Wait for the CP to go idle.
+ */
+int r600_do_cp_idle(drm_radeon_private_t *dev_priv)
+{
+ RING_LOCALS;
+ DRM_DEBUG("\n");
+
+ BEGIN_RING(5);
+ OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
+ OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT);
+ /* wait for 3D idle clean */
+ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
+ OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2);
+ OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN);
+
+ ADVANCE_RING();
+ COMMIT_RING();
+
+ return r600_do_wait_for_idle(dev_priv);
+}
+
+/* Start the Command Processor.
+ */
+void r600_do_cp_start(drm_radeon_private_t *dev_priv)
+{
+ u32 cp_me;
+ RING_LOCALS;
+ DRM_DEBUG("\n");
+
+ BEGIN_RING(7);
+ OUT_RING(CP_PACKET3(R600_IT_ME_INITIALIZE, 5));
+ OUT_RING(0x00000001);
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770))
+ OUT_RING(0x00000003);
+ else
+ OUT_RING(0x00000000);
+ OUT_RING((dev_priv->r600_max_hw_contexts - 1));
+ OUT_RING(R600_ME_INITIALIZE_DEVICE_ID(1));
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000);
+ ADVANCE_RING();
+ COMMIT_RING();
+
+ /* set the mux and reset the halt bit */
+ cp_me = 0xff;
+ RADEON_WRITE(R600_CP_ME_CNTL, cp_me);
+
+ dev_priv->cp_running = 1;
+
+}
+
+void r600_do_cp_reset(drm_radeon_private_t *dev_priv)
+{
+ u32 cur_read_ptr;
+ DRM_DEBUG("\n");
+
+ cur_read_ptr = RADEON_READ(R600_CP_RB_RPTR);
+ RADEON_WRITE(R600_CP_RB_WPTR, cur_read_ptr);
+ SET_RING_HEAD(dev_priv, cur_read_ptr);
+ dev_priv->ring.tail = cur_read_ptr;
+}
+
+void r600_do_cp_stop(drm_radeon_private_t *dev_priv)
+{
+ uint32_t cp_me;
+
+ DRM_DEBUG("\n");
+
+ cp_me = 0xff | R600_CP_ME_HALT;
+
+ RADEON_WRITE(R600_CP_ME_CNTL, cp_me);
+
+ dev_priv->cp_running = 0;
+}
+
+int r600_cp_dispatch_indirect(struct drm_device *dev,
+ struct drm_buf *buf, int start, int end)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ RING_LOCALS;
+
+ if (start != end) {
+ unsigned long offset = (dev_priv->gart_buffers_offset
+ + buf->offset + start);
+ int dwords = (end - start + 3) / sizeof(u32);
+
+ DRM_DEBUG("dwords:%d\n", dwords);
+ DRM_DEBUG("offset 0x%lx\n", offset);
+
+
+ /* Indirect buffer data must be a multiple of 16 dwords.
+ * pad the data with a Type-2 CP packet.
+ */
+ while (dwords & 0xf) {
+ u32 *data = (u32 *)
+ ((char *)dev->agp_buffer_map->handle
+ + buf->offset + start);
+ data[dwords++] = RADEON_CP_PACKET2;
+ }
+
+ /* Fire off the indirect buffer */
+ BEGIN_RING(4);
+ OUT_RING(CP_PACKET3(R600_IT_INDIRECT_BUFFER, 2));
+ OUT_RING((offset & 0xfffffffc));
+ OUT_RING((upper_32_bits(offset) & 0xff));
+ OUT_RING(dwords);
+ ADVANCE_RING();
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/radeon/r600_microcode.h b/drivers/gpu/drm/radeon/r600_microcode.h
new file mode 100644
index 000000000000..778c8b4b2fd9
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_microcode.h
@@ -0,0 +1,23297 @@
+/*
+ * Copyright 2008-2009 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef R600_MICROCODE_H
+#define R600_MICROCODE_H
+
+static const int ME_JUMP_TABLE_START = 1764;
+static const int ME_JUMP_TABLE_END = 1792;
+
+#define PFP_UCODE_SIZE 576
+#define PM4_UCODE_SIZE 1792
+#define R700_PFP_UCODE_SIZE 848
+#define R700_PM4_UCODE_SIZE 1360
+
+static const u32 R600_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x614 },
+ { 0x00000000, 0x00600000, 0x5b2 },
+ { 0x00000000, 0x00600000, 0x5c5 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000020, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000031, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000021, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x0000001d, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x0000001d, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000030, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x00000010, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000030, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000032, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x0000002d, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x080 },
+ { 0x0000002e, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x081 },
+ { 0x00000000, 0x00400000, 0x087 },
+ { 0x0000002d, 0x00203623, 0x000 },
+ { 0x0000002e, 0x00203624, 0x000 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x087 },
+ { 0x00000000, 0x00600000, 0x5ed },
+ { 0x00000000, 0x00600000, 0x5e1 },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08a },
+ { 0x00000018, 0xc0403620, 0x090 },
+ { 0x00000000, 0x2ee00000, 0x08e },
+ { 0x00000000, 0x2ce00000, 0x08d },
+ { 0x00000002, 0x00400e2d, 0x08f },
+ { 0x00000003, 0x00400e2d, 0x08f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000018, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x095 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x09d },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09b },
+ { 0x00000000, 0x2ce00000, 0x09a },
+ { 0x00000002, 0x00400e2d, 0x09c },
+ { 0x00000003, 0x00400e2d, 0x09c },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a4 },
+ { 0x0000001c, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x0000001b, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0db },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x28c },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x128 },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0c5 },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0d6 },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0d4 },
+ { 0x00000013, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0cf },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ce },
+ { 0x00003f00, 0x00400c11, 0x0d0 },
+ { 0x00001f00, 0x00400c11, 0x0d0 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0d6 },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00284a22, 0x000 },
+ { 0x00000030, 0x00200e2d, 0x000 },
+ { 0x0000002e, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e3 },
+ { 0x00000000, 0x00600000, 0x5e7 },
+ { 0x00000000, 0x00400000, 0x0e4 },
+ { 0x00000000, 0x00600000, 0x5ea },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x0000001d, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f1 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f1 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x0000001a, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f6 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x104 },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000013, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0fd },
+ { 0xffffffff, 0x00404811, 0x104 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x100 },
+ { 0x0000ffff, 0x00404811, 0x104 },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x103 },
+ { 0x000000ff, 0x00404811, 0x104 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000019, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x10d },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000019, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x114 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x110 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x127 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x614 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x613 },
+ { 0x00000004, 0x00404c11, 0x12e },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x2fe },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x19f },
+ { 0x00000000, 0x00600000, 0x151 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2a4 },
+ { 0x0001a1fd, 0x00604411, 0x2c9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x138 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x2fe },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x19f },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x151 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2a4 },
+ { 0x0001a1fd, 0x00604411, 0x2c9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x149 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x17c },
+ { 0x00000000, 0x00600000, 0x18d },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x189 },
+ { 0x00000000, 0x00600000, 0x2a4 },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x28c },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x173 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x16f },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x184 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000013, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2e4 },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x165 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x2fe },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x181 },
+ { 0x0000001b, 0xc0203620, 0x000 },
+ { 0x0000001c, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x19f },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x188 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000032, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x00000011, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x128 },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00600e2d, 0x1aa },
+ { 0x0000001c, 0x00600e2d, 0x1aa },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x0000001d, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1a6 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000020, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x2fe },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x19f },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000019, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1cd },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1c9 },
+ { 0x00000000, 0x00600000, 0x1d6 },
+ { 0x00000001, 0x00531e27, 0x1c5 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1be },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1d6 },
+ { 0x00000001, 0x00531e27, 0x1d2 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2a4 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e5 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x1f2 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x1f2 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x613 },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x2fe },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x19f },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2a4 },
+ { 0x0001a1fd, 0x00604411, 0x2c9 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x206 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x1ff },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x5c5 },
+ { 0x00000000, 0x0040040f, 0x200 },
+ { 0x00000000, 0x00600000, 0x5b2 },
+ { 0x00000000, 0x00600000, 0x5c5 },
+ { 0x00000210, 0x00600411, 0x2fe },
+ { 0x00000000, 0x00600000, 0x18d },
+ { 0x00000000, 0x00600000, 0x189 },
+ { 0x00000000, 0x00600000, 0x2a4 },
+ { 0x00000000, 0x00600000, 0x28c },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x21f },
+ { 0x00000000, 0xc0404800, 0x21c },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2e4 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x5b2 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x235 },
+ { 0x0000001a, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x0000001a, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x23a },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x2fe },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x19f },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x265 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x253 },
+ { 0x00000018, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x248 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x24b },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000018, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x250 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x253 },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2aa },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25b },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25a },
+ { 0x00000016, 0x00404811, 0x25f },
+ { 0x00000018, 0x00404811, 0x25f },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25e },
+ { 0x00000017, 0x00404811, 0x25f },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2d2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x23f },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x614 },
+ { 0x00000000, 0x00600000, 0x5b2 },
+ { 0x00000000, 0xc0600000, 0x28c },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x00000034, 0x00201a2d, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x00000033, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x27b },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000034, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x128 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x286 },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000024, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000032, 0x00203622, 0x000 },
+ { 0x00000031, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000029, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000029, 0x00203627, 0x000 },
+ { 0x0000002a, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x0000002a, 0x00203627, 0x000 },
+ { 0x0000002b, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x0000002b, 0x00203627, 0x000 },
+ { 0x0000002c, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x0000002c, 0x00803627, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x0000002a, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x0000002b, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x0000002c, 0x00803627, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00203628, 0x000 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2c5 },
+ { 0x00000000, 0x00400000, 0x2c2 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00203628, 0x000 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2c2 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2c5 },
+ { 0x0000002b, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2c5 },
+ { 0x00000029, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2c5 },
+ { 0x0000002c, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2c5 },
+ { 0x0000002a, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2c5 },
+ { 0x00000000, 0x00600000, 0x5ed },
+ { 0x00000000, 0x00600000, 0x29e },
+ { 0x00000000, 0x00400000, 0x2c7 },
+ { 0x00000000, 0x00600000, 0x29e },
+ { 0x00000000, 0x00600000, 0x5e4 },
+ { 0x00000000, 0x00400000, 0x2c7 },
+ { 0x00000000, 0x00600000, 0x290 },
+ { 0x00000000, 0x00400000, 0x2c7 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000023, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x0000001d, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x301 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x0000001a, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x5c5 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x334 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x614 },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x33d },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x351 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000016, 0x00604811, 0x35e },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x355 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00404811, 0x349 },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x349 },
+ { 0x00002104, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x00000035, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x360 },
+ { 0x00000035, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x376 },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x380 },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x38c },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x398 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x398 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x39a },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x39f },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000015, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x614 },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x382 },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x614 },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x38e },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00404811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000016, 0x00604811, 0x35e },
+ { 0x00000016, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3b9 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x614 },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3ab },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3be },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x614 },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3cc },
+ { 0x00000000, 0xc0401800, 0x3cf },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x614 },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3d2 },
+ { 0x00000000, 0xc0401c00, 0x3d5 },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x614 },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x3fd },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3e2 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3ea },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x3fd },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x3fd },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3e5 },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3e5 },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3e5 },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3e5 },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3e5 },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3e5 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x614 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x42e },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x43c },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x444 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x614 },
+ { 0x00000000, 0x00400000, 0x44d },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x449 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x44c },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x454 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x46d },
+ { 0x00000000, 0x00400000, 0x47a },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x459 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x46d },
+ { 0x00000000, 0x00400000, 0x47a },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x45e },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x46d },
+ { 0x00000000, 0x00400000, 0x47a },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x463 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46d },
+ { 0x00000000, 0x00400000, 0x47a },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x468 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x46d },
+ { 0x00000000, 0x00400000, 0x47a },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46d },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x46d },
+ { 0x00000000, 0x00400000, 0x47a },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x477 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x480 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x43c },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x48a },
+ { 0x00040000, 0xc0494a20, 0x48b },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x497 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x493 },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x491 },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4ae },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x4a9 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x4ac },
+ { 0x00000000, 0x00400000, 0x4b2 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x614 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4b9 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x614 },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4bb },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4eb },
+ { 0x00000035, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4da },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4ce },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000036, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x491 },
+ { 0x00000035, 0xc0203620, 0x000 },
+ { 0x00000036, 0xc0403620, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0xe0000000, 0xc0484a20, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4f2 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x4f6 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x50b },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0x00000034, 0x00203623, 0x000 },
+ { 0x00000032, 0x00203623, 0x000 },
+ { 0x00000031, 0x00203623, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x0000002d, 0x00203623, 0x000 },
+ { 0x0000002e, 0x00203623, 0x000 },
+ { 0x0000001b, 0x00203623, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x0000002a, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x0000002c, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000033, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000027, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000028, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x00000026, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x602 },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x541 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x614 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x549 },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x55b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x549 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x614 },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x55b },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x54d },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x55b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x559 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x554 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x557 },
+ { 0x00000000, 0x00401c10, 0x55b },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x55d },
+ { 0x00000000, 0x00600000, 0x5a4 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56d },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x614 },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x56b },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x57d },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x614 },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x57b },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x58d },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x614 },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x58b },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x614 },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x599 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x59f },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5a4 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x5b7 },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x00000034, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x5bb },
+ { 0x00000000, 0x00600000, 0x5a4 },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5bb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x0000217a, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x5e1 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000016, 0x00604811, 0x35e },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x614 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x5dc },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x0000001d, 0x00803627, 0x000 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x0000001d, 0x00803627, 0x000 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x0000001d, 0x00803627, 0x000 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x0000001d, 0x00803627, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000016, 0x00604811, 0x35e },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0x00ffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x614 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x613 },
+ { 0x00000010, 0x00404c11, 0x5f9 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x00000025, 0x00200a2d, 0x000 },
+ { 0x00000026, 0x00200e2d, 0x000 },
+ { 0x00000027, 0x0020122d, 0x000 },
+ { 0x00000028, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x612 },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x00000027, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x614 },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x617 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x2fe },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x19f },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000029, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x0000002c, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000002a, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000002b, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x013304ef, 0x059b0239, 0x000 },
+ { 0x01b00159, 0x0425059b, 0x000 },
+ { 0x021201f6, 0x02390142, 0x000 },
+ { 0x0210022e, 0x0289022a, 0x000 },
+ { 0x03c2059b, 0x059b059b, 0x000 },
+ { 0x05cd05ce, 0x0308059b, 0x000 },
+ { 0x059b05a0, 0x03090329, 0x000 },
+ { 0x0313026b, 0x032b031d, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x059b052c, 0x059b059b, 0x000 },
+ { 0x03a5059b, 0x04a2032d, 0x000 },
+ { 0x04810433, 0x0423059b, 0x000 },
+ { 0x04bb04ed, 0x042704c8, 0x000 },
+ { 0x043304f4, 0x033a0365, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x059b059b, 0x05b905a2, 0x000 },
+ { 0x059b059b, 0x0007059b, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x03e303d8, 0x03f303f1, 0x000 },
+ { 0x03f903f5, 0x03f703fb, 0x000 },
+ { 0x04070403, 0x040f040b, 0x000 },
+ { 0x04170413, 0x041f041b, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x00020600, 0x06190006, 0x000 },
+};
+
+static const u32 R600_pfp_microcode[] = {
+0xd40071,
+0xd40072,
+0xca0400,
+0xa00000,
+0x7e828b,
+0x800003,
+0xca0400,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581a8,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0fff0,
+0x042c04,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255403,
+0x7cd580,
+0x259c03,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d4,
+0xd5c01e,
+0xca0800,
+0x80001b,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000d,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000d,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800054,
+0xd40073,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xd48060,
+0xd4401e,
+0x800002,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800002,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001b9,
+0xd4c01e,
+0xc6083e,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800002,
+0x062001,
+0xc6083e,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x80007a,
+0xd42013,
+0xc6083e,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x80008e,
+0x000000,
+0xc41432,
+0xc6183e,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800002,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xd40073,
+0xe4015e,
+0xd4001e,
+0x8001b9,
+0x062001,
+0x0a2001,
+0xd60074,
+0xc40836,
+0xc61040,
+0x988007,
+0xcc3835,
+0x95010f,
+0xd4001f,
+0xd46062,
+0x800002,
+0xd42062,
+0xcc1433,
+0x8401bc,
+0xd40070,
+0xd5401e,
+0x800002,
+0xee001e,
+0xca0c00,
+0xca1000,
+0xd4c01a,
+0x8401bc,
+0xd5001a,
+0xcc0443,
+0x35101f,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001b9,
+0xd4006d,
+0x344401,
+0xcc0c44,
+0x98403a,
+0xcc2c46,
+0x958004,
+0xcc0445,
+0x8001b9,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x8400f3,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x8400f3,
+0xcc1003,
+0x988017,
+0x043808,
+0x8400f3,
+0xcc1003,
+0x988013,
+0x043804,
+0x8400f3,
+0xcc1003,
+0x988014,
+0xcc1047,
+0x9a8009,
+0xcc1448,
+0x9840da,
+0xd4006d,
+0xcc1844,
+0xd5001a,
+0xd5401a,
+0x8000cc,
+0xd5801a,
+0x96c0d3,
+0xd4006d,
+0x8001b9,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800002,
+0xec007f,
+0x9ac0ca,
+0xd4006d,
+0x8001b9,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001b9,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809c,
+0xd4006d,
+0x98409a,
+0xd4006e,
+0xcc0847,
+0xcc0c48,
+0xcc1044,
+0xd4801a,
+0xd4c01a,
+0x800104,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482d8,
+0xca0c00,
+0xd4401e,
+0x800002,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800002,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x9882bc,
+0x000000,
+0x8401bc,
+0xd7806f,
+0x800002,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x9902af,
+0x7c738b,
+0x8401bc,
+0xd7806f,
+0x800002,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984296,
+0x000000,
+0x800164,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800002,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc1049,
+0x990004,
+0xd40071,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800002,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x95001f,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x7d8380,
+0xd5806f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0x8001b9,
+0xd60074,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800002,
+0xee001e,
+0x800002,
+0xee001f,
+0xd4001f,
+0x800002,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010174,
+0x02017b,
+0x030090,
+0x040080,
+0x050005,
+0x060040,
+0x070033,
+0x08012f,
+0x090047,
+0x0a0037,
+0x1001b7,
+0x1700a4,
+0x22013d,
+0x23014c,
+0x2000b5,
+0x240128,
+0x27004e,
+0x28006b,
+0x2a0061,
+0x2b0053,
+0x2f0066,
+0x320088,
+0x340182,
+0x3c0159,
+0x3f0073,
+0x41018f,
+0x440131,
+0x550176,
+0x56017d,
+0x60000c,
+0x610035,
+0x620039,
+0x630039,
+0x640039,
+0x650039,
+0x660039,
+0x670039,
+0x68003b,
+0x690042,
+0x6a0049,
+0x6b0049,
+0x6c0049,
+0x6d0049,
+0x6e0049,
+0x6f0049,
+0x7301b7,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+};
+
+static const u32 RV610_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000018, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000028, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000019, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x00000017, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000027, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x0000000e, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x0000000f, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000029, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000030, 0x0020162d, 0x000 },
+ { 0x00000002, 0x00291625, 0x000 },
+ { 0x00000030, 0x00203625, 0x000 },
+ { 0x00000025, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x083 },
+ { 0x00000026, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x084 },
+ { 0x00000000, 0x00400000, 0x08a },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203624, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x08a },
+ { 0x00000000, 0x00600000, 0x668 },
+ { 0x00000000, 0x00600000, 0x65c },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08d },
+ { 0x00000012, 0xc0403620, 0x093 },
+ { 0x00000000, 0x2ee00000, 0x091 },
+ { 0x00000000, 0x2ce00000, 0x090 },
+ { 0x00000002, 0x00400e2d, 0x092 },
+ { 0x00000003, 0x00400e2d, 0x092 },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000012, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x098 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x0a0 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09e },
+ { 0x00000000, 0x2ce00000, 0x09d },
+ { 0x00000002, 0x00400e2d, 0x09f },
+ { 0x00000003, 0x00400e2d, 0x09f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0aa },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e1 },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x0b3 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x12f },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0cb },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0dc },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0da },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d5 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d4 },
+ { 0x00003f00, 0x00400c11, 0x0d6 },
+ { 0x00001f00, 0x00400c11, 0x0d6 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0dc },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00280e22, 0x000 },
+ { 0x00000080, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00200e2d, 0x000 },
+ { 0x00000026, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ea },
+ { 0x00000000, 0x00600000, 0x662 },
+ { 0x00000000, 0x00400000, 0x0eb },
+ { 0x00000000, 0x00600000, 0x665 },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f8 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f8 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0fd },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x104 },
+ { 0xffffffff, 0x00404811, 0x10b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x107 },
+ { 0x0000ffff, 0x00404811, 0x10b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x10a },
+ { 0x000000ff, 0x00404811, 0x10b },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x112 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x114 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x11b },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x117 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x12e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x68c },
+ { 0x00000004, 0x00404c11, 0x135 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000001c, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x13c },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x147 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x158 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x18f },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x181 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x186 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x186 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x182 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x197 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000011, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2fb },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x174 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x194 },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x19b },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000029, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x0000000f, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x12f },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x00000015, 0x00600e2d, 0x1bd },
+ { 0x00000016, 0x00600e2d, 0x1bd },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1b9 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000018, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000013, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e0 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1dc },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1d8 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1d1 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1e5 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2bb },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1f8 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x205 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x205 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x68c },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x219 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x212 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000000, 0x0040040f, 0x213 },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00000000, 0x00600000, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x232 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x236 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x236 },
+ { 0x00000000, 0xc0404800, 0x233 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2fb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x24c },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x251 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x315 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x27c },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x26a },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25f },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x262 },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x267 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x26a },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2c1 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x272 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x271 },
+ { 0x00000016, 0x00404811, 0x276 },
+ { 0x00000018, 0x00404811, 0x276 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x275 },
+ { 0x00000017, 0x00404811, 0x276 },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2e9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x256 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x00000000, 0xc0600000, 0x2a3 },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x0000002b, 0x00201a2d, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x0000002a, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x292 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x12f },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x29d },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000001c, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000029, 0x00203622, 0x000 },
+ { 0x00000028, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000021, 0x00203627, 0x000 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2dc },
+ { 0x00000000, 0x00400000, 0x2d9 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2d9 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2dc },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000000, 0x00600000, 0x668 },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00600000, 0x65f },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2a7 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x0000001a, 0x00201e2d, 0x000 },
+ { 0x0000001b, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000017, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x318 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x34b },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x354 },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x364 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00604802, 0x36e },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x36a },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5c0 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x0000002c, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x370 },
+ { 0x0000002c, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x386 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b1 },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b5 },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x39c },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x390 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x392 },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x39e },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x80000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000010, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3ae },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3ce },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3c0 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3d3 },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x68d },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e1 },
+ { 0x00000000, 0xc0401800, 0x3e4 },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x68d },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e7 },
+ { 0x00000000, 0xc0401c00, 0x3ea },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x68d },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3f7 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3ff },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3fa },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3fa },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3fa },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3fa },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3fa },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3fa },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x01182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0218a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0318c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0418f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0518f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0618e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0718f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0818f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000030, 0x00200a2d, 0x000 },
+ { 0x00000000, 0xc0290c40, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000018, 0x40210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x445 },
+ { 0x00800000, 0xc0494a20, 0x446 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x44b },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x459 },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x461 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x68d },
+ { 0x00000000, 0x00400000, 0x466 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00604805, 0x692 },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46d },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x472 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x477 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x47c },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x481 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x486 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x490 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x499 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x459 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4a3 },
+ { 0x00040000, 0xc0494a20, 0x4a4 },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4b0 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4ac },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4aa },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4c3 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x692 },
+ { 0x00000000, 0x00400000, 0x4c7 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x68d },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4ce },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4d0 },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x500 },
+ { 0x0000002c, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4ef },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4e3 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000002d, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4aa },
+ { 0x0000002c, 0xc0203620, 0x000 },
+ { 0x0000002d, 0xc0403620, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x505 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xb5000000, 0x00204411, 0x000 },
+ { 0x00002000, 0x00204811, 0x000 },
+ { 0xb6000000, 0x00204411, 0x000 },
+ { 0x0000a000, 0x00204811, 0x000 },
+ { 0xb7000000, 0x00204411, 0x000 },
+ { 0x0000c000, 0x00204811, 0x000 },
+ { 0xb8000000, 0x00204411, 0x000 },
+ { 0x0000f8e0, 0x00204811, 0x000 },
+ { 0xb9000000, 0x00204411, 0x000 },
+ { 0x0000f880, 0x00204811, 0x000 },
+ { 0xba000000, 0x00204411, 0x000 },
+ { 0x0000e000, 0x00204811, 0x000 },
+ { 0xbb000000, 0x00204411, 0x000 },
+ { 0x0000f000, 0x00204811, 0x000 },
+ { 0xbc000000, 0x00204411, 0x000 },
+ { 0x0000f3fc, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x519 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x52e },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x00000028, 0x00203623, 0x000 },
+ { 0x00000017, 0x00203623, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203623, 0x000 },
+ { 0x00000015, 0x00203623, 0x000 },
+ { 0x00000016, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x00000023, 0x00203623, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000002a, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x0000001f, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000020, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x0000001e, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x67b },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x566 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68d },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56e },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x57c },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68d },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x57c },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x572 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x57c },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x57a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x692 },
+ { 0x00000000, 0x00401c10, 0x57c },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x57e },
+ { 0x00000000, 0x00600000, 0x5c9 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x58f },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x58d },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5a0 },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x59e },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5b1 },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5af },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5be },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x5c4 },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5c9 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000002c, 0x00203621, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5d0 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000030, 0x00403621, 0x5e3 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x5e3 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a092, 0x00604411, 0x68d },
+ { 0x00000031, 0x00203630, 0x000 },
+ { 0x0004a093, 0x00604411, 0x68d },
+ { 0x00000032, 0x00203630, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68d },
+ { 0x00000033, 0x00203630, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68d },
+ { 0x00000034, 0x00203630, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68d },
+ { 0x00000035, 0x00203630, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68d },
+ { 0x00000036, 0x00203630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000001, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62c },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62c },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x605 },
+ { 0x0000a092, 0x00204411, 0x000 },
+ { 0x00000031, 0x00204a2d, 0x000 },
+ { 0x0000a093, 0x00204411, 0x000 },
+ { 0x00000032, 0x00204a2d, 0x000 },
+ { 0x0000a2b6, 0x00204411, 0x000 },
+ { 0x00000033, 0x00204a2d, 0x000 },
+ { 0x0000a2ba, 0x00204411, 0x000 },
+ { 0x00000034, 0x00204a2d, 0x000 },
+ { 0x0000a2be, 0x00204411, 0x000 },
+ { 0x00000035, 0x00204a2d, 0x000 },
+ { 0x0000a2c2, 0x00204411, 0x000 },
+ { 0x00000036, 0x00204a2d, 0x000 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x000001ff, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62b },
+ { 0x00000000, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x60e },
+ { 0x0004a003, 0x00604411, 0x68d },
+ { 0x0000a003, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x14c00000, 0x613 },
+ { 0x0004a010, 0x00604411, 0x68d },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62b },
+ { 0x0004a011, 0x00604411, 0x68d },
+ { 0x0000a011, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a012, 0x00604411, 0x68d },
+ { 0x0000a012, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a013, 0x00604411, 0x68d },
+ { 0x0000a013, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a014, 0x00604411, 0x68d },
+ { 0x0000a014, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a015, 0x00604411, 0x68d },
+ { 0x0000a015, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a016, 0x00604411, 0x68d },
+ { 0x0000a016, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a017, 0x00604411, 0x68d },
+ { 0x0000a017, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000002c, 0x0080062d, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x63d },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000002, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x63b },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x0000002b, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x641 },
+ { 0x00000000, 0x00600000, 0x5c9 },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x641 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00404811, 0x62d },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x62d },
+ { 0x00000000, 0x00600000, 0x65c },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x656 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x68c },
+ { 0x00000010, 0x00404c11, 0x672 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x0000001d, 0x00200a2d, 0x000 },
+ { 0x0000001e, 0x00200e2d, 0x000 },
+ { 0x0000001f, 0x0020122d, 0x000 },
+ { 0x00000020, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x68b },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x0000001f, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x68d },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x690 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x692 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x695 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000024, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000022, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x01420502, 0x05c00250, 0x000 },
+ { 0x01c30168, 0x043f05c0, 0x000 },
+ { 0x02250209, 0x02500151, 0x000 },
+ { 0x02230245, 0x02a00241, 0x000 },
+ { 0x03d705c0, 0x05c005c0, 0x000 },
+ { 0x0649064a, 0x031f05c0, 0x000 },
+ { 0x05c005c5, 0x03200340, 0x000 },
+ { 0x032a0282, 0x03420334, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c00551, 0x05c005c0, 0x000 },
+ { 0x03ba05c0, 0x04bb0344, 0x000 },
+ { 0x049a0450, 0x043d05c0, 0x000 },
+ { 0x04d005c0, 0x044104dd, 0x000 },
+ { 0x04500507, 0x03510375, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x063f05c7, 0x000 },
+ { 0x05c005c0, 0x000705c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x03f803ed, 0x04080406, 0x000 },
+ { 0x040e040a, 0x040c0410, 0x000 },
+ { 0x041c0418, 0x04240420, 0x000 },
+ { 0x042c0428, 0x04340430, 0x000 },
+ { 0x05c005c0, 0x043805c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x00020679, 0x06970006, 0x000 },
+};
+
+static const u32 RV610_pfp_microcode[] = {
+0xca0400,
+0xa00000,
+0x7e828b,
+0x7c038b,
+0x8001b8,
+0x7c038b,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581a8,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0fff0,
+0x042c04,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255403,
+0x7cd580,
+0x259c03,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d3,
+0xd5c01e,
+0xca0800,
+0x80001a,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800053,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xd48060,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001b8,
+0xd4c01e,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800000,
+0x062001,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x800079,
+0xd42013,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x80008d,
+0x000000,
+0xc41432,
+0xc61843,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800000,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xe4015e,
+0xd4001e,
+0x800000,
+0x062001,
+0xca1800,
+0x0a2001,
+0xd60076,
+0xc40836,
+0x988007,
+0xc61045,
+0x950110,
+0xd4001f,
+0xd46062,
+0x800000,
+0xd42062,
+0xcc3835,
+0xcc1433,
+0x8401bb,
+0xd40072,
+0xd5401e,
+0x800000,
+0xee001e,
+0xe2001a,
+0x8401bb,
+0xe2001a,
+0xcc104b,
+0xcc0447,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001b8,
+0xd4006d,
+0x344401,
+0xcc0c48,
+0x98403a,
+0xcc2c4a,
+0x958004,
+0xcc0449,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x8400f0,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x8400f0,
+0xcc1003,
+0x988017,
+0x043808,
+0x8400f0,
+0xcc1003,
+0x988013,
+0x043804,
+0x8400f0,
+0xcc1003,
+0x988014,
+0xcc104c,
+0x9a8009,
+0xcc144d,
+0x9840dc,
+0xd4006d,
+0xcc1848,
+0xd5001a,
+0xd5401a,
+0x8000c9,
+0xd5801a,
+0x96c0d5,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800000,
+0xec007f,
+0x9ac0cc,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809e,
+0xd4006d,
+0x98409c,
+0xd4006e,
+0xcc084c,
+0xcc0c4d,
+0xcc1048,
+0xd4801a,
+0xd4c01a,
+0x800101,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482d9,
+0xca0c00,
+0xd4401e,
+0x800000,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800000,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x9882bd,
+0x000000,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x9902b0,
+0x7c738b,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984297,
+0x000000,
+0x800161,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc104e,
+0x990004,
+0xd40073,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x950021,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x042802,
+0x7d8380,
+0xd5a86f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0xc82402,
+0x8001b8,
+0xd60076,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800000,
+0xee001e,
+0x800000,
+0xee001f,
+0xd4001f,
+0x800000,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010171,
+0x020178,
+0x03008f,
+0x04007f,
+0x050003,
+0x06003f,
+0x070032,
+0x08012c,
+0x090046,
+0x0a0036,
+0x1001b6,
+0x1700a2,
+0x22013a,
+0x230149,
+0x2000b4,
+0x240125,
+0x27004d,
+0x28006a,
+0x2a0060,
+0x2b0052,
+0x2f0065,
+0x320087,
+0x34017f,
+0x3c0156,
+0x3f0072,
+0x41018c,
+0x44012e,
+0x550173,
+0x56017a,
+0x60000b,
+0x610034,
+0x620038,
+0x630038,
+0x640038,
+0x650038,
+0x660038,
+0x670038,
+0x68003a,
+0x690041,
+0x6a0048,
+0x6b0048,
+0x6c0048,
+0x6d0048,
+0x6e0048,
+0x6f0048,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+};
+
+static const u32 RV620_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000018, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000028, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000019, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x00000017, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000027, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x0000000e, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x0000000f, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000029, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000030, 0x0020162d, 0x000 },
+ { 0x00000002, 0x00291625, 0x000 },
+ { 0x00000030, 0x00203625, 0x000 },
+ { 0x00000025, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x083 },
+ { 0x00000026, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x084 },
+ { 0x00000000, 0x00400000, 0x08a },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203624, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x08a },
+ { 0x00000000, 0x00600000, 0x668 },
+ { 0x00000000, 0x00600000, 0x65c },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08d },
+ { 0x00000012, 0xc0403620, 0x093 },
+ { 0x00000000, 0x2ee00000, 0x091 },
+ { 0x00000000, 0x2ce00000, 0x090 },
+ { 0x00000002, 0x00400e2d, 0x092 },
+ { 0x00000003, 0x00400e2d, 0x092 },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000012, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x098 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x0a0 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09e },
+ { 0x00000000, 0x2ce00000, 0x09d },
+ { 0x00000002, 0x00400e2d, 0x09f },
+ { 0x00000003, 0x00400e2d, 0x09f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0aa },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e1 },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x0b3 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x12f },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0cb },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0dc },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0da },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d5 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d4 },
+ { 0x00003f00, 0x00400c11, 0x0d6 },
+ { 0x00001f00, 0x00400c11, 0x0d6 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0dc },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00280e22, 0x000 },
+ { 0x00000080, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00200e2d, 0x000 },
+ { 0x00000026, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ea },
+ { 0x00000000, 0x00600000, 0x662 },
+ { 0x00000000, 0x00400000, 0x0eb },
+ { 0x00000000, 0x00600000, 0x665 },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f8 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f8 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0fd },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x104 },
+ { 0xffffffff, 0x00404811, 0x10b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x107 },
+ { 0x0000ffff, 0x00404811, 0x10b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x10a },
+ { 0x000000ff, 0x00404811, 0x10b },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x112 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x114 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x11b },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x117 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x12e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x68c },
+ { 0x00000004, 0x00404c11, 0x135 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000001c, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x13c },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x147 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x158 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x18f },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x181 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x186 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x186 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x182 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x197 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000011, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2fb },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x174 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x194 },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x19b },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000029, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x0000000f, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x12f },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x00000015, 0x00600e2d, 0x1bd },
+ { 0x00000016, 0x00600e2d, 0x1bd },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1b9 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000018, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000013, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e0 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1dc },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1d8 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1d1 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1e5 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2bb },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1f8 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x205 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x205 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x68c },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x219 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x212 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000000, 0x0040040f, 0x213 },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00000000, 0x00600000, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x232 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x236 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x236 },
+ { 0x00000000, 0xc0404800, 0x233 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2fb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x24c },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x251 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x315 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x27c },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x26a },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25f },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x262 },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x267 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x26a },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2c1 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x272 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x271 },
+ { 0x00000016, 0x00404811, 0x276 },
+ { 0x00000018, 0x00404811, 0x276 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x275 },
+ { 0x00000017, 0x00404811, 0x276 },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2e9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x256 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x00000000, 0xc0600000, 0x2a3 },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x0000002b, 0x00201a2d, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x0000002a, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x292 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x12f },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x29d },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000001c, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000029, 0x00203622, 0x000 },
+ { 0x00000028, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000021, 0x00203627, 0x000 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2dc },
+ { 0x00000000, 0x00400000, 0x2d9 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2d9 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2dc },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000000, 0x00600000, 0x668 },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00600000, 0x65f },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2a7 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x0000001a, 0x00201e2d, 0x000 },
+ { 0x0000001b, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000017, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x318 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x34b },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x354 },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x364 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00604802, 0x36e },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x36a },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5c0 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x0000002c, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x370 },
+ { 0x0000002c, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x386 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b1 },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b5 },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x39c },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x390 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x392 },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x39e },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x80000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000010, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3ae },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3ce },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3c0 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3d3 },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x68d },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e1 },
+ { 0x00000000, 0xc0401800, 0x3e4 },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x68d },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e7 },
+ { 0x00000000, 0xc0401c00, 0x3ea },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x68d },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3f7 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3ff },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3fa },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3fa },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3fa },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3fa },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3fa },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3fa },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x01182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0218a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0318c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0418f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0518f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0618e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0718f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0818f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000030, 0x00200a2d, 0x000 },
+ { 0x00000000, 0xc0290c40, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000018, 0x40210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x445 },
+ { 0x00800000, 0xc0494a20, 0x446 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x44b },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x459 },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x461 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x68d },
+ { 0x00000000, 0x00400000, 0x466 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00604805, 0x692 },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46d },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x472 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x477 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x47c },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x481 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x486 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x490 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x499 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x459 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4a3 },
+ { 0x00040000, 0xc0494a20, 0x4a4 },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4b0 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4ac },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4aa },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4c3 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x692 },
+ { 0x00000000, 0x00400000, 0x4c7 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x68d },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4ce },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4d0 },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x500 },
+ { 0x0000002c, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4ef },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4e3 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000002d, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4aa },
+ { 0x0000002c, 0xc0203620, 0x000 },
+ { 0x0000002d, 0xc0403620, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x505 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xb5000000, 0x00204411, 0x000 },
+ { 0x00002000, 0x00204811, 0x000 },
+ { 0xb6000000, 0x00204411, 0x000 },
+ { 0x0000a000, 0x00204811, 0x000 },
+ { 0xb7000000, 0x00204411, 0x000 },
+ { 0x0000c000, 0x00204811, 0x000 },
+ { 0xb8000000, 0x00204411, 0x000 },
+ { 0x0000f8e0, 0x00204811, 0x000 },
+ { 0xb9000000, 0x00204411, 0x000 },
+ { 0x0000f880, 0x00204811, 0x000 },
+ { 0xba000000, 0x00204411, 0x000 },
+ { 0x0000e000, 0x00204811, 0x000 },
+ { 0xbb000000, 0x00204411, 0x000 },
+ { 0x0000f000, 0x00204811, 0x000 },
+ { 0xbc000000, 0x00204411, 0x000 },
+ { 0x0000f3fc, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x519 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x52e },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x00000028, 0x00203623, 0x000 },
+ { 0x00000017, 0x00203623, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203623, 0x000 },
+ { 0x00000015, 0x00203623, 0x000 },
+ { 0x00000016, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x00000023, 0x00203623, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000002a, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x0000001f, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000020, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x0000001e, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x67b },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x566 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68d },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56e },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x57c },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68d },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x57c },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x572 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x57c },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x57a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x692 },
+ { 0x00000000, 0x00401c10, 0x57c },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x57e },
+ { 0x00000000, 0x00600000, 0x5c9 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x58f },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x58d },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5a0 },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x59e },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5b1 },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5af },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5be },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x5c4 },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5c9 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000002c, 0x00203621, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5d0 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000030, 0x00403621, 0x5e3 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x5e3 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a092, 0x00604411, 0x68d },
+ { 0x00000031, 0x00203630, 0x000 },
+ { 0x0004a093, 0x00604411, 0x68d },
+ { 0x00000032, 0x00203630, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68d },
+ { 0x00000033, 0x00203630, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68d },
+ { 0x00000034, 0x00203630, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68d },
+ { 0x00000035, 0x00203630, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68d },
+ { 0x00000036, 0x00203630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000001, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62c },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62c },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x605 },
+ { 0x0000a092, 0x00204411, 0x000 },
+ { 0x00000031, 0x00204a2d, 0x000 },
+ { 0x0000a093, 0x00204411, 0x000 },
+ { 0x00000032, 0x00204a2d, 0x000 },
+ { 0x0000a2b6, 0x00204411, 0x000 },
+ { 0x00000033, 0x00204a2d, 0x000 },
+ { 0x0000a2ba, 0x00204411, 0x000 },
+ { 0x00000034, 0x00204a2d, 0x000 },
+ { 0x0000a2be, 0x00204411, 0x000 },
+ { 0x00000035, 0x00204a2d, 0x000 },
+ { 0x0000a2c2, 0x00204411, 0x000 },
+ { 0x00000036, 0x00204a2d, 0x000 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x000001ff, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62b },
+ { 0x00000000, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x60e },
+ { 0x0004a003, 0x00604411, 0x68d },
+ { 0x0000a003, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x14c00000, 0x613 },
+ { 0x0004a010, 0x00604411, 0x68d },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62b },
+ { 0x0004a011, 0x00604411, 0x68d },
+ { 0x0000a011, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a012, 0x00604411, 0x68d },
+ { 0x0000a012, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a013, 0x00604411, 0x68d },
+ { 0x0000a013, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a014, 0x00604411, 0x68d },
+ { 0x0000a014, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a015, 0x00604411, 0x68d },
+ { 0x0000a015, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a016, 0x00604411, 0x68d },
+ { 0x0000a016, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a017, 0x00604411, 0x68d },
+ { 0x0000a017, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000002c, 0x0080062d, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x63d },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000002, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x63b },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x0000002b, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x641 },
+ { 0x00000000, 0x00600000, 0x5c9 },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x641 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00404811, 0x62d },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x62d },
+ { 0x00000000, 0x00600000, 0x65c },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x656 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x68c },
+ { 0x00000010, 0x00404c11, 0x672 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x0000001d, 0x00200a2d, 0x000 },
+ { 0x0000001e, 0x00200e2d, 0x000 },
+ { 0x0000001f, 0x0020122d, 0x000 },
+ { 0x00000020, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x68b },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x0000001f, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x68d },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x690 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x692 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x695 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000024, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000022, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x01420502, 0x05c00250, 0x000 },
+ { 0x01c30168, 0x043f05c0, 0x000 },
+ { 0x02250209, 0x02500151, 0x000 },
+ { 0x02230245, 0x02a00241, 0x000 },
+ { 0x03d705c0, 0x05c005c0, 0x000 },
+ { 0x0649064a, 0x031f05c0, 0x000 },
+ { 0x05c005c5, 0x03200340, 0x000 },
+ { 0x032a0282, 0x03420334, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c00551, 0x05c005c0, 0x000 },
+ { 0x03ba05c0, 0x04bb0344, 0x000 },
+ { 0x049a0450, 0x043d05c0, 0x000 },
+ { 0x04d005c0, 0x044104dd, 0x000 },
+ { 0x04500507, 0x03510375, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x063f05c7, 0x000 },
+ { 0x05c005c0, 0x000705c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x03f803ed, 0x04080406, 0x000 },
+ { 0x040e040a, 0x040c0410, 0x000 },
+ { 0x041c0418, 0x04240420, 0x000 },
+ { 0x042c0428, 0x04340430, 0x000 },
+ { 0x05c005c0, 0x043805c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x00020679, 0x06970006, 0x000 },
+};
+
+static const u32 RV620_pfp_microcode[] = {
+0xca0400,
+0xa00000,
+0x7e828b,
+0x7c038b,
+0x8001b8,
+0x7c038b,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581a8,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0fff0,
+0x042c04,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255403,
+0x7cd580,
+0x259c03,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d3,
+0xd5c01e,
+0xca0800,
+0x80001a,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800053,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xd48060,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001b8,
+0xd4c01e,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800000,
+0x062001,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x800079,
+0xd42013,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x80008d,
+0x000000,
+0xc41432,
+0xc61843,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800000,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xe4015e,
+0xd4001e,
+0x800000,
+0x062001,
+0xca1800,
+0x0a2001,
+0xd60076,
+0xc40836,
+0x988007,
+0xc61045,
+0x950110,
+0xd4001f,
+0xd46062,
+0x800000,
+0xd42062,
+0xcc3835,
+0xcc1433,
+0x8401bb,
+0xd40072,
+0xd5401e,
+0x800000,
+0xee001e,
+0xe2001a,
+0x8401bb,
+0xe2001a,
+0xcc104b,
+0xcc0447,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001b8,
+0xd4006d,
+0x344401,
+0xcc0c48,
+0x98403a,
+0xcc2c4a,
+0x958004,
+0xcc0449,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x8400f0,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x8400f0,
+0xcc1003,
+0x988017,
+0x043808,
+0x8400f0,
+0xcc1003,
+0x988013,
+0x043804,
+0x8400f0,
+0xcc1003,
+0x988014,
+0xcc104c,
+0x9a8009,
+0xcc144d,
+0x9840dc,
+0xd4006d,
+0xcc1848,
+0xd5001a,
+0xd5401a,
+0x8000c9,
+0xd5801a,
+0x96c0d5,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800000,
+0xec007f,
+0x9ac0cc,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809e,
+0xd4006d,
+0x98409c,
+0xd4006e,
+0xcc084c,
+0xcc0c4d,
+0xcc1048,
+0xd4801a,
+0xd4c01a,
+0x800101,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482d9,
+0xca0c00,
+0xd4401e,
+0x800000,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800000,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x9882bd,
+0x000000,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x9902b0,
+0x7c738b,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984297,
+0x000000,
+0x800161,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc104e,
+0x990004,
+0xd40073,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x950021,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x042802,
+0x7d8380,
+0xd5a86f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0xc82402,
+0x8001b8,
+0xd60076,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800000,
+0xee001e,
+0x800000,
+0xee001f,
+0xd4001f,
+0x800000,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010171,
+0x020178,
+0x03008f,
+0x04007f,
+0x050003,
+0x06003f,
+0x070032,
+0x08012c,
+0x090046,
+0x0a0036,
+0x1001b6,
+0x1700a2,
+0x22013a,
+0x230149,
+0x2000b4,
+0x240125,
+0x27004d,
+0x28006a,
+0x2a0060,
+0x2b0052,
+0x2f0065,
+0x320087,
+0x34017f,
+0x3c0156,
+0x3f0072,
+0x41018c,
+0x44012e,
+0x550173,
+0x56017a,
+0x60000b,
+0x610034,
+0x620038,
+0x630038,
+0x640038,
+0x650038,
+0x660038,
+0x670038,
+0x68003a,
+0x690041,
+0x6a0048,
+0x6b0048,
+0x6c0048,
+0x6d0048,
+0x6e0048,
+0x6f0048,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+};
+
+static const u32 RV630_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000018, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000028, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000019, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x00000017, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000027, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x0000000e, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x0000000f, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000029, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000030, 0x0020162d, 0x000 },
+ { 0x00000002, 0x00291625, 0x000 },
+ { 0x00000030, 0x00203625, 0x000 },
+ { 0x00000025, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x083 },
+ { 0x00000026, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x084 },
+ { 0x00000000, 0x00400000, 0x08a },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203624, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x08a },
+ { 0x00000000, 0x00600000, 0x665 },
+ { 0x00000000, 0x00600000, 0x659 },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08d },
+ { 0x00000012, 0xc0403620, 0x093 },
+ { 0x00000000, 0x2ee00000, 0x091 },
+ { 0x00000000, 0x2ce00000, 0x090 },
+ { 0x00000002, 0x00400e2d, 0x092 },
+ { 0x00000003, 0x00400e2d, 0x092 },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000012, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x098 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x0a0 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09e },
+ { 0x00000000, 0x2ce00000, 0x09d },
+ { 0x00000002, 0x00400e2d, 0x09f },
+ { 0x00000003, 0x00400e2d, 0x09f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0aa },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e1 },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x0b3 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x12f },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0cb },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0dc },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0da },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d5 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d4 },
+ { 0x00003f00, 0x00400c11, 0x0d6 },
+ { 0x00001f00, 0x00400c11, 0x0d6 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0dc },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00280e22, 0x000 },
+ { 0x00000080, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00200e2d, 0x000 },
+ { 0x00000026, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ea },
+ { 0x00000000, 0x00600000, 0x65f },
+ { 0x00000000, 0x00400000, 0x0eb },
+ { 0x00000000, 0x00600000, 0x662 },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f8 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f8 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0fd },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x104 },
+ { 0xffffffff, 0x00404811, 0x10b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x107 },
+ { 0x0000ffff, 0x00404811, 0x10b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x10a },
+ { 0x000000ff, 0x00404811, 0x10b },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x112 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x114 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x11b },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x117 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x12e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x689 },
+ { 0x00000004, 0x00404c11, 0x135 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000001c, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x13c },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x147 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x158 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x18f },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x181 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x186 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x186 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x182 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x197 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000011, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2fb },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x174 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x194 },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x19b },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000029, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x0000000f, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x12f },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x00000015, 0x00600e2d, 0x1bd },
+ { 0x00000016, 0x00600e2d, 0x1bd },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1b9 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000018, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000013, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e0 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1dc },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1d8 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1d1 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1e5 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2bb },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1f8 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x205 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x205 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x689 },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x219 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x212 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000000, 0x0040040f, 0x213 },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00000000, 0x00600000, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x232 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x236 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x236 },
+ { 0x00000000, 0xc0404800, 0x233 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2fb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x24c },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x251 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x315 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x27c },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x26a },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25f },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x262 },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x267 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x26a },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2c1 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x272 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x271 },
+ { 0x00000016, 0x00404811, 0x276 },
+ { 0x00000018, 0x00404811, 0x276 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x275 },
+ { 0x00000017, 0x00404811, 0x276 },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2e9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x256 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x00000000, 0xc0600000, 0x2a3 },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x0000002b, 0x00201a2d, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x0000002a, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x292 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x12f },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x29d },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000001c, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000029, 0x00203622, 0x000 },
+ { 0x00000028, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000021, 0x00203627, 0x000 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2dc },
+ { 0x00000000, 0x00400000, 0x2d9 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2d9 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2dc },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000000, 0x00600000, 0x665 },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00600000, 0x65c },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2a7 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x0000001a, 0x00201e2d, 0x000 },
+ { 0x0000001b, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000017, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x318 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x34b },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x354 },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x364 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00604802, 0x36e },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x36a },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5bd },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x0000002c, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x370 },
+ { 0x0000002c, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x386 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b1 },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b5 },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x39c },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x390 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x392 },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x39e },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x80000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000010, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3ae },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3ce },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3c0 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3d3 },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x68a },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e1 },
+ { 0x00000000, 0xc0401800, 0x3e4 },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x68a },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e7 },
+ { 0x00000000, 0xc0401c00, 0x3ea },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x68a },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3f7 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3ff },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3fa },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3fa },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3fa },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3fa },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3fa },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3fa },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x01182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0218a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0318c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0418f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0518f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0618e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0718f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0818f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000030, 0x00200a2d, 0x000 },
+ { 0x00000000, 0xc0290c40, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x448 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x456 },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x45e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x68a },
+ { 0x00000000, 0x00400000, 0x463 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00604805, 0x68f },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46a },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46f },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x474 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x479 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x47e },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x483 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x48d },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x496 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x456 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4a0 },
+ { 0x00040000, 0xc0494a20, 0x4a1 },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4ad },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4a9 },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4a7 },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4c0 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x68f },
+ { 0x00000000, 0x00400000, 0x4c4 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x68a },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4cb },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4cd },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4fd },
+ { 0x0000002c, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4ec },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4e0 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000002d, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4a7 },
+ { 0x0000002c, 0xc0203620, 0x000 },
+ { 0x0000002d, 0xc0403620, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x502 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xb5000000, 0x00204411, 0x000 },
+ { 0x00002000, 0x00204811, 0x000 },
+ { 0xb6000000, 0x00204411, 0x000 },
+ { 0x0000a000, 0x00204811, 0x000 },
+ { 0xb7000000, 0x00204411, 0x000 },
+ { 0x0000c000, 0x00204811, 0x000 },
+ { 0xb8000000, 0x00204411, 0x000 },
+ { 0x0000f8e0, 0x00204811, 0x000 },
+ { 0xb9000000, 0x00204411, 0x000 },
+ { 0x0000f880, 0x00204811, 0x000 },
+ { 0xba000000, 0x00204411, 0x000 },
+ { 0x0000e000, 0x00204811, 0x000 },
+ { 0xbb000000, 0x00204411, 0x000 },
+ { 0x0000f000, 0x00204811, 0x000 },
+ { 0xbc000000, 0x00204411, 0x000 },
+ { 0x0000f3fc, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x516 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x52b },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x00000028, 0x00203623, 0x000 },
+ { 0x00000017, 0x00203623, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203623, 0x000 },
+ { 0x00000015, 0x00203623, 0x000 },
+ { 0x00000016, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x00000023, 0x00203623, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000002a, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x0000001f, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000020, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x0000001e, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x678 },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x563 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68a },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56b },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x579 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56b },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68a },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x579 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56f },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x579 },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x577 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x68f },
+ { 0x00000000, 0x00401c10, 0x579 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x57b },
+ { 0x00000000, 0x00600000, 0x5c6 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x58c },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x58a },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x59d },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x59b },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5ae },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5ac },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5bb },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x5c1 },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5c6 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000002c, 0x00203621, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5cd },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000030, 0x00403621, 0x5e0 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x5e0 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a092, 0x00604411, 0x68a },
+ { 0x00000031, 0x00203630, 0x000 },
+ { 0x0004a093, 0x00604411, 0x68a },
+ { 0x00000032, 0x00203630, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68a },
+ { 0x00000033, 0x00203630, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68a },
+ { 0x00000034, 0x00203630, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68a },
+ { 0x00000035, 0x00203630, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68a },
+ { 0x00000036, 0x00203630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000001, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x629 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x629 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x602 },
+ { 0x0000a092, 0x00204411, 0x000 },
+ { 0x00000031, 0x00204a2d, 0x000 },
+ { 0x0000a093, 0x00204411, 0x000 },
+ { 0x00000032, 0x00204a2d, 0x000 },
+ { 0x0000a2b6, 0x00204411, 0x000 },
+ { 0x00000033, 0x00204a2d, 0x000 },
+ { 0x0000a2ba, 0x00204411, 0x000 },
+ { 0x00000034, 0x00204a2d, 0x000 },
+ { 0x0000a2be, 0x00204411, 0x000 },
+ { 0x00000035, 0x00204a2d, 0x000 },
+ { 0x0000a2c2, 0x00204411, 0x000 },
+ { 0x00000036, 0x00204a2d, 0x000 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x000001ff, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x628 },
+ { 0x00000000, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x60b },
+ { 0x0004a003, 0x00604411, 0x68a },
+ { 0x0000a003, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x14c00000, 0x610 },
+ { 0x0004a010, 0x00604411, 0x68a },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x628 },
+ { 0x0004a011, 0x00604411, 0x68a },
+ { 0x0000a011, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a012, 0x00604411, 0x68a },
+ { 0x0000a012, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a013, 0x00604411, 0x68a },
+ { 0x0000a013, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a014, 0x00604411, 0x68a },
+ { 0x0000a014, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a015, 0x00604411, 0x68a },
+ { 0x0000a015, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a016, 0x00604411, 0x68a },
+ { 0x0000a016, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a017, 0x00604411, 0x68a },
+ { 0x0000a017, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000002c, 0x0080062d, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x63a },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000002, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x638 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x0000002b, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x63e },
+ { 0x00000000, 0x00600000, 0x5c6 },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x63e },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00404811, 0x62a },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x62a },
+ { 0x00000000, 0x00600000, 0x659 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x653 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x689 },
+ { 0x00000010, 0x00404c11, 0x66f },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x0000001d, 0x00200a2d, 0x000 },
+ { 0x0000001e, 0x00200e2d, 0x000 },
+ { 0x0000001f, 0x0020122d, 0x000 },
+ { 0x00000020, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x688 },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x0000001f, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x68a },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x68d },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x68f },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x692 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000024, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000022, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x014204ff, 0x05bd0250, 0x000 },
+ { 0x01c30168, 0x043f05bd, 0x000 },
+ { 0x02250209, 0x02500151, 0x000 },
+ { 0x02230245, 0x02a00241, 0x000 },
+ { 0x03d705bd, 0x05bd05bd, 0x000 },
+ { 0x06460647, 0x031f05bd, 0x000 },
+ { 0x05bd05c2, 0x03200340, 0x000 },
+ { 0x032a0282, 0x03420334, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd054e, 0x05bd05bd, 0x000 },
+ { 0x03ba05bd, 0x04b80344, 0x000 },
+ { 0x0497044d, 0x043d05bd, 0x000 },
+ { 0x04cd05bd, 0x044104da, 0x000 },
+ { 0x044d0504, 0x03510375, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x063c05c4, 0x000 },
+ { 0x05bd05bd, 0x000705bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x03f803ed, 0x04080406, 0x000 },
+ { 0x040e040a, 0x040c0410, 0x000 },
+ { 0x041c0418, 0x04240420, 0x000 },
+ { 0x042c0428, 0x04340430, 0x000 },
+ { 0x05bd05bd, 0x043805bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x00020676, 0x06940006, 0x000 },
+};
+
+static const u32 RV630_pfp_microcode[] = {
+0xca0400,
+0xa00000,
+0x7e828b,
+0x7c038b,
+0x8001b8,
+0x7c038b,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581a8,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0fff0,
+0x042c04,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255403,
+0x7cd580,
+0x259c03,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d3,
+0xd5c01e,
+0xca0800,
+0x80001a,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800053,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xd48060,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001b8,
+0xd4c01e,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800000,
+0x062001,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x800079,
+0xd42013,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x80008d,
+0x000000,
+0xc41432,
+0xc61843,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800000,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xe4015e,
+0xd4001e,
+0x800000,
+0x062001,
+0xca1800,
+0x0a2001,
+0xd60076,
+0xc40836,
+0x988007,
+0xc61045,
+0x950110,
+0xd4001f,
+0xd46062,
+0x800000,
+0xd42062,
+0xcc3835,
+0xcc1433,
+0x8401bb,
+0xd40072,
+0xd5401e,
+0x800000,
+0xee001e,
+0xe2001a,
+0x8401bb,
+0xe2001a,
+0xcc104b,
+0xcc0447,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001b8,
+0xd4006d,
+0x344401,
+0xcc0c48,
+0x98403a,
+0xcc2c4a,
+0x958004,
+0xcc0449,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x8400f0,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x8400f0,
+0xcc1003,
+0x988017,
+0x043808,
+0x8400f0,
+0xcc1003,
+0x988013,
+0x043804,
+0x8400f0,
+0xcc1003,
+0x988014,
+0xcc104c,
+0x9a8009,
+0xcc144d,
+0x9840dc,
+0xd4006d,
+0xcc1848,
+0xd5001a,
+0xd5401a,
+0x8000c9,
+0xd5801a,
+0x96c0d5,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800000,
+0xec007f,
+0x9ac0cc,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809e,
+0xd4006d,
+0x98409c,
+0xd4006e,
+0xcc084c,
+0xcc0c4d,
+0xcc1048,
+0xd4801a,
+0xd4c01a,
+0x800101,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482d9,
+0xca0c00,
+0xd4401e,
+0x800000,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800000,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x9882bd,
+0x000000,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x9902b0,
+0x7c738b,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984297,
+0x000000,
+0x800161,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc104e,
+0x990004,
+0xd40073,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x950021,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x042802,
+0x7d8380,
+0xd5a86f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0xc82402,
+0x8001b8,
+0xd60076,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800000,
+0xee001e,
+0x800000,
+0xee001f,
+0xd4001f,
+0x800000,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010171,
+0x020178,
+0x03008f,
+0x04007f,
+0x050003,
+0x06003f,
+0x070032,
+0x08012c,
+0x090046,
+0x0a0036,
+0x1001b6,
+0x1700a2,
+0x22013a,
+0x230149,
+0x2000b4,
+0x240125,
+0x27004d,
+0x28006a,
+0x2a0060,
+0x2b0052,
+0x2f0065,
+0x320087,
+0x34017f,
+0x3c0156,
+0x3f0072,
+0x41018c,
+0x44012e,
+0x550173,
+0x56017a,
+0x60000b,
+0x610034,
+0x620038,
+0x630038,
+0x640038,
+0x650038,
+0x660038,
+0x670038,
+0x68003a,
+0x690041,
+0x6a0048,
+0x6b0048,
+0x6c0048,
+0x6d0048,
+0x6e0048,
+0x6f0048,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+};
+
+static const u32 RV635_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000018, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000028, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000019, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x00000017, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000027, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x0000000e, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x0000000f, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000029, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000030, 0x0020162d, 0x000 },
+ { 0x00000002, 0x00291625, 0x000 },
+ { 0x00000030, 0x00203625, 0x000 },
+ { 0x00000025, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x083 },
+ { 0x00000026, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x084 },
+ { 0x00000000, 0x00400000, 0x08a },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203624, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x08a },
+ { 0x00000000, 0x00600000, 0x665 },
+ { 0x00000000, 0x00600000, 0x659 },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08d },
+ { 0x00000012, 0xc0403620, 0x093 },
+ { 0x00000000, 0x2ee00000, 0x091 },
+ { 0x00000000, 0x2ce00000, 0x090 },
+ { 0x00000002, 0x00400e2d, 0x092 },
+ { 0x00000003, 0x00400e2d, 0x092 },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000012, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x098 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x0a0 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09e },
+ { 0x00000000, 0x2ce00000, 0x09d },
+ { 0x00000002, 0x00400e2d, 0x09f },
+ { 0x00000003, 0x00400e2d, 0x09f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0aa },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e1 },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x0b3 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x12f },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0cb },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0dc },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0da },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d5 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d4 },
+ { 0x00003f00, 0x00400c11, 0x0d6 },
+ { 0x00001f00, 0x00400c11, 0x0d6 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0dc },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00280e22, 0x000 },
+ { 0x00000080, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00200e2d, 0x000 },
+ { 0x00000026, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ea },
+ { 0x00000000, 0x00600000, 0x65f },
+ { 0x00000000, 0x00400000, 0x0eb },
+ { 0x00000000, 0x00600000, 0x662 },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f8 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f8 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0fd },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x104 },
+ { 0xffffffff, 0x00404811, 0x10b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x107 },
+ { 0x0000ffff, 0x00404811, 0x10b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x10a },
+ { 0x000000ff, 0x00404811, 0x10b },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x112 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x114 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x11b },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x117 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x12e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x689 },
+ { 0x00000004, 0x00404c11, 0x135 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000001c, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x13c },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x147 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x158 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x18f },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x181 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x186 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x186 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x182 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x197 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000011, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2fb },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x174 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x194 },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x19b },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000029, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x0000000f, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x12f },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x00000015, 0x00600e2d, 0x1bd },
+ { 0x00000016, 0x00600e2d, 0x1bd },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1b9 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000018, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000013, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e0 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1dc },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1d8 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1d1 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1e5 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2bb },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1f8 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x205 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x205 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x689 },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x219 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x212 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000000, 0x0040040f, 0x213 },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00000000, 0x00600000, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x232 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x236 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x236 },
+ { 0x00000000, 0xc0404800, 0x233 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2fb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x24c },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x251 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x315 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x27c },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x26a },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25f },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x262 },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x267 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x26a },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2c1 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x272 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x271 },
+ { 0x00000016, 0x00404811, 0x276 },
+ { 0x00000018, 0x00404811, 0x276 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x275 },
+ { 0x00000017, 0x00404811, 0x276 },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2e9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x256 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x00000000, 0xc0600000, 0x2a3 },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x0000002b, 0x00201a2d, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x0000002a, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x292 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x12f },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x29d },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000001c, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000029, 0x00203622, 0x000 },
+ { 0x00000028, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000021, 0x00203627, 0x000 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2dc },
+ { 0x00000000, 0x00400000, 0x2d9 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2d9 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2dc },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000000, 0x00600000, 0x665 },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00600000, 0x65c },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2a7 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x0000001a, 0x00201e2d, 0x000 },
+ { 0x0000001b, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000017, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x318 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x34b },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x354 },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x364 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00604802, 0x36e },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x36a },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5bd },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x0000002c, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x370 },
+ { 0x0000002c, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x386 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b1 },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b5 },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x39c },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x390 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x392 },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x39e },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x80000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000010, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3ae },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3ce },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3c0 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3d3 },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x68a },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e1 },
+ { 0x00000000, 0xc0401800, 0x3e4 },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x68a },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e7 },
+ { 0x00000000, 0xc0401c00, 0x3ea },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x68a },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3f7 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3ff },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3fa },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3fa },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3fa },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3fa },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3fa },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3fa },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x01182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0218a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0318c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0418f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0518f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0618e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0718f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0818f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000030, 0x00200a2d, 0x000 },
+ { 0x00000000, 0xc0290c40, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x448 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x456 },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x45e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x68a },
+ { 0x00000000, 0x00400000, 0x463 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00604805, 0x68f },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46a },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46f },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x474 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x479 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x47e },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x483 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x48d },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x496 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x456 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4a0 },
+ { 0x00040000, 0xc0494a20, 0x4a1 },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4ad },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4a9 },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4a7 },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4c0 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x68f },
+ { 0x00000000, 0x00400000, 0x4c4 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x68a },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4cb },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4cd },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4fd },
+ { 0x0000002c, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4ec },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4e0 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000002d, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4a7 },
+ { 0x0000002c, 0xc0203620, 0x000 },
+ { 0x0000002d, 0xc0403620, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x502 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xb5000000, 0x00204411, 0x000 },
+ { 0x00002000, 0x00204811, 0x000 },
+ { 0xb6000000, 0x00204411, 0x000 },
+ { 0x0000a000, 0x00204811, 0x000 },
+ { 0xb7000000, 0x00204411, 0x000 },
+ { 0x0000c000, 0x00204811, 0x000 },
+ { 0xb8000000, 0x00204411, 0x000 },
+ { 0x0000f8e0, 0x00204811, 0x000 },
+ { 0xb9000000, 0x00204411, 0x000 },
+ { 0x0000f880, 0x00204811, 0x000 },
+ { 0xba000000, 0x00204411, 0x000 },
+ { 0x0000e000, 0x00204811, 0x000 },
+ { 0xbb000000, 0x00204411, 0x000 },
+ { 0x0000f000, 0x00204811, 0x000 },
+ { 0xbc000000, 0x00204411, 0x000 },
+ { 0x0000f3fc, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x516 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x52b },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x00000028, 0x00203623, 0x000 },
+ { 0x00000017, 0x00203623, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203623, 0x000 },
+ { 0x00000015, 0x00203623, 0x000 },
+ { 0x00000016, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x00000023, 0x00203623, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000002a, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x0000001f, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000020, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x0000001e, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x678 },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x563 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68a },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56b },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x579 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56b },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68a },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x579 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56f },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x579 },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x577 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x68f },
+ { 0x00000000, 0x00401c10, 0x579 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x57b },
+ { 0x00000000, 0x00600000, 0x5c6 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x58c },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x58a },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x59d },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x59b },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5ae },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5ac },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5bb },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x5c1 },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5c6 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000002c, 0x00203621, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5cd },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000030, 0x00403621, 0x5e0 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x5e0 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a092, 0x00604411, 0x68a },
+ { 0x00000031, 0x00203630, 0x000 },
+ { 0x0004a093, 0x00604411, 0x68a },
+ { 0x00000032, 0x00203630, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68a },
+ { 0x00000033, 0x00203630, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68a },
+ { 0x00000034, 0x00203630, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68a },
+ { 0x00000035, 0x00203630, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68a },
+ { 0x00000036, 0x00203630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000001, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x629 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x629 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x602 },
+ { 0x0000a092, 0x00204411, 0x000 },
+ { 0x00000031, 0x00204a2d, 0x000 },
+ { 0x0000a093, 0x00204411, 0x000 },
+ { 0x00000032, 0x00204a2d, 0x000 },
+ { 0x0000a2b6, 0x00204411, 0x000 },
+ { 0x00000033, 0x00204a2d, 0x000 },
+ { 0x0000a2ba, 0x00204411, 0x000 },
+ { 0x00000034, 0x00204a2d, 0x000 },
+ { 0x0000a2be, 0x00204411, 0x000 },
+ { 0x00000035, 0x00204a2d, 0x000 },
+ { 0x0000a2c2, 0x00204411, 0x000 },
+ { 0x00000036, 0x00204a2d, 0x000 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x000001ff, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x628 },
+ { 0x00000000, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x60b },
+ { 0x0004a003, 0x00604411, 0x68a },
+ { 0x0000a003, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x14c00000, 0x610 },
+ { 0x0004a010, 0x00604411, 0x68a },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x628 },
+ { 0x0004a011, 0x00604411, 0x68a },
+ { 0x0000a011, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a012, 0x00604411, 0x68a },
+ { 0x0000a012, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a013, 0x00604411, 0x68a },
+ { 0x0000a013, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a014, 0x00604411, 0x68a },
+ { 0x0000a014, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a015, 0x00604411, 0x68a },
+ { 0x0000a015, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a016, 0x00604411, 0x68a },
+ { 0x0000a016, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a017, 0x00604411, 0x68a },
+ { 0x0000a017, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000002c, 0x0080062d, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x63a },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000002, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x638 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x0000002b, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x63e },
+ { 0x00000000, 0x00600000, 0x5c6 },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x63e },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00404811, 0x62a },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x62a },
+ { 0x00000000, 0x00600000, 0x659 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x653 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x689 },
+ { 0x00000010, 0x00404c11, 0x66f },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x0000001d, 0x00200a2d, 0x000 },
+ { 0x0000001e, 0x00200e2d, 0x000 },
+ { 0x0000001f, 0x0020122d, 0x000 },
+ { 0x00000020, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x688 },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x0000001f, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x68a },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x68d },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x68f },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x692 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000024, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000022, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x014204ff, 0x05bd0250, 0x000 },
+ { 0x01c30168, 0x043f05bd, 0x000 },
+ { 0x02250209, 0x02500151, 0x000 },
+ { 0x02230245, 0x02a00241, 0x000 },
+ { 0x03d705bd, 0x05bd05bd, 0x000 },
+ { 0x06460647, 0x031f05bd, 0x000 },
+ { 0x05bd05c2, 0x03200340, 0x000 },
+ { 0x032a0282, 0x03420334, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd054e, 0x05bd05bd, 0x000 },
+ { 0x03ba05bd, 0x04b80344, 0x000 },
+ { 0x0497044d, 0x043d05bd, 0x000 },
+ { 0x04cd05bd, 0x044104da, 0x000 },
+ { 0x044d0504, 0x03510375, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x063c05c4, 0x000 },
+ { 0x05bd05bd, 0x000705bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x03f803ed, 0x04080406, 0x000 },
+ { 0x040e040a, 0x040c0410, 0x000 },
+ { 0x041c0418, 0x04240420, 0x000 },
+ { 0x042c0428, 0x04340430, 0x000 },
+ { 0x05bd05bd, 0x043805bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x00020676, 0x06940006, 0x000 },
+};
+
+static const u32 RV635_pfp_microcode[] = {
+0xca0400,
+0xa00000,
+0x7e828b,
+0x7c038b,
+0x8001b8,
+0x7c038b,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581a8,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0fff0,
+0x042c04,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255403,
+0x7cd580,
+0x259c03,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d3,
+0xd5c01e,
+0xca0800,
+0x80001a,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800053,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xd48060,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001b8,
+0xd4c01e,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800000,
+0x062001,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x800079,
+0xd42013,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x80008d,
+0x000000,
+0xc41432,
+0xc61843,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800000,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xe4015e,
+0xd4001e,
+0x800000,
+0x062001,
+0xca1800,
+0x0a2001,
+0xd60076,
+0xc40836,
+0x988007,
+0xc61045,
+0x950110,
+0xd4001f,
+0xd46062,
+0x800000,
+0xd42062,
+0xcc3835,
+0xcc1433,
+0x8401bb,
+0xd40072,
+0xd5401e,
+0x800000,
+0xee001e,
+0xe2001a,
+0x8401bb,
+0xe2001a,
+0xcc104b,
+0xcc0447,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001b8,
+0xd4006d,
+0x344401,
+0xcc0c48,
+0x98403a,
+0xcc2c4a,
+0x958004,
+0xcc0449,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x8400f0,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x8400f0,
+0xcc1003,
+0x988017,
+0x043808,
+0x8400f0,
+0xcc1003,
+0x988013,
+0x043804,
+0x8400f0,
+0xcc1003,
+0x988014,
+0xcc104c,
+0x9a8009,
+0xcc144d,
+0x9840dc,
+0xd4006d,
+0xcc1848,
+0xd5001a,
+0xd5401a,
+0x8000c9,
+0xd5801a,
+0x96c0d5,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800000,
+0xec007f,
+0x9ac0cc,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809e,
+0xd4006d,
+0x98409c,
+0xd4006e,
+0xcc084c,
+0xcc0c4d,
+0xcc1048,
+0xd4801a,
+0xd4c01a,
+0x800101,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482d9,
+0xca0c00,
+0xd4401e,
+0x800000,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800000,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x9882bd,
+0x000000,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x9902b0,
+0x7c738b,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984297,
+0x000000,
+0x800161,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc104e,
+0x990004,
+0xd40073,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x950021,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x042802,
+0x7d8380,
+0xd5a86f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0xc82402,
+0x8001b8,
+0xd60076,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800000,
+0xee001e,
+0x800000,
+0xee001f,
+0xd4001f,
+0x800000,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010171,
+0x020178,
+0x03008f,
+0x04007f,
+0x050003,
+0x06003f,
+0x070032,
+0x08012c,
+0x090046,
+0x0a0036,
+0x1001b6,
+0x1700a2,
+0x22013a,
+0x230149,
+0x2000b4,
+0x240125,
+0x27004d,
+0x28006a,
+0x2a0060,
+0x2b0052,
+0x2f0065,
+0x320087,
+0x34017f,
+0x3c0156,
+0x3f0072,
+0x41018c,
+0x44012e,
+0x550173,
+0x56017a,
+0x60000b,
+0x610034,
+0x620038,
+0x630038,
+0x640038,
+0x650038,
+0x660038,
+0x670038,
+0x68003a,
+0x690041,
+0x6a0048,
+0x6b0048,
+0x6c0048,
+0x6d0048,
+0x6e0048,
+0x6f0048,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+};
+
+static const u32 RV670_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x00000000, 0x00600000, 0x624 },
+ { 0x00000000, 0x00600000, 0x638 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000018, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000028, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000019, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x00000017, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000027, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x0000000e, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x0000000f, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000029, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000030, 0x0020162d, 0x000 },
+ { 0x00000002, 0x00291625, 0x000 },
+ { 0x00000030, 0x00203625, 0x000 },
+ { 0x00000025, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x083 },
+ { 0x00000026, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x084 },
+ { 0x00000000, 0x00400000, 0x08a },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203624, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x08a },
+ { 0x00000000, 0x00600000, 0x659 },
+ { 0x00000000, 0x00600000, 0x64d },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08d },
+ { 0x00000012, 0xc0403620, 0x093 },
+ { 0x00000000, 0x2ee00000, 0x091 },
+ { 0x00000000, 0x2ce00000, 0x090 },
+ { 0x00000002, 0x00400e2d, 0x092 },
+ { 0x00000003, 0x00400e2d, 0x092 },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000012, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x098 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x0a0 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09e },
+ { 0x00000000, 0x2ce00000, 0x09d },
+ { 0x00000002, 0x00400e2d, 0x09f },
+ { 0x00000003, 0x00400e2d, 0x09f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0aa },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e1 },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x0b3 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x12f },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0cb },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0dc },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0da },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d5 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d4 },
+ { 0x00003f00, 0x00400c11, 0x0d6 },
+ { 0x00001f00, 0x00400c11, 0x0d6 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0dc },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00280e22, 0x000 },
+ { 0x00000080, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00200e2d, 0x000 },
+ { 0x00000026, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ea },
+ { 0x00000000, 0x00600000, 0x653 },
+ { 0x00000000, 0x00400000, 0x0eb },
+ { 0x00000000, 0x00600000, 0x656 },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f8 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f8 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0fd },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x104 },
+ { 0xffffffff, 0x00404811, 0x10b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x107 },
+ { 0x0000ffff, 0x00404811, 0x10b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x10a },
+ { 0x000000ff, 0x00404811, 0x10b },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x112 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x114 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x11b },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x117 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x12e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x67c },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x67b },
+ { 0x00000004, 0x00404c11, 0x135 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000001c, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x67c },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x13c },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x147 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x158 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x18f },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x181 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x186 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x186 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x182 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x197 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000011, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2fb },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x174 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x194 },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x19b },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000029, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x0000000f, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x12f },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x00000015, 0x00600e2d, 0x1bd },
+ { 0x00000016, 0x00600e2d, 0x1bd },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1b9 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000018, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000013, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e0 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1dc },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1d8 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1d1 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1e5 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2bb },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1f8 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x205 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x205 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x67b },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x219 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x212 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x638 },
+ { 0x00000000, 0x0040040f, 0x213 },
+ { 0x00000000, 0x00600000, 0x624 },
+ { 0x00000000, 0x00600000, 0x638 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00000000, 0x00600000, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x232 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x236 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x236 },
+ { 0x00000000, 0xc0404800, 0x233 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2fb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x624 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x24c },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x251 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x315 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x27c },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x26a },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25f },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x262 },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x267 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x26a },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2c1 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x272 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x271 },
+ { 0x00000016, 0x00404811, 0x276 },
+ { 0x00000018, 0x00404811, 0x276 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x275 },
+ { 0x00000017, 0x00404811, 0x276 },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2e9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x256 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x00000000, 0x00600000, 0x624 },
+ { 0x00000000, 0xc0600000, 0x2a3 },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x0000002b, 0x00201a2d, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x0000002a, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x292 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x12f },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x29d },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000001c, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000029, 0x00203622, 0x000 },
+ { 0x00000028, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000021, 0x00203627, 0x000 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2dc },
+ { 0x00000000, 0x00400000, 0x2d9 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2d9 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2dc },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000000, 0x00600000, 0x659 },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00600000, 0x650 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2a7 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x0000001a, 0x00201e2d, 0x000 },
+ { 0x0000001b, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000017, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x318 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x638 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x34b },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x67c },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x354 },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x362 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00604802, 0x36a },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x366 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35d },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5b3 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35d },
+ { 0x0000002c, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x36c },
+ { 0x0000002c, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x382 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3ad },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3af },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x398 },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a4 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a4 },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x38c },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x67c },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x38e },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x67c },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x39a },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x80000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000010, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3aa },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36a },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3c4 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x67c },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3b8 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3c9 },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x67c },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3d7 },
+ { 0x00000000, 0xc0401800, 0x3da },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x67c },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3dd },
+ { 0x00000000, 0xc0401c00, 0x3e0 },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x67c },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x408 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3ed },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3f5 },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x408 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x408 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3f0 },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3f0 },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3f0 },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3f0 },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3f0 },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3f0 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x01182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0218a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0318c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0418f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0518f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0618e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0718f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0818f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000030, 0x00200a2d, 0x000 },
+ { 0x00000000, 0xc0290c40, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x67c },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x43e },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x44c },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x454 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x67c },
+ { 0x00000000, 0x00400000, 0x459 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00604805, 0x681 },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x460 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x479 },
+ { 0x00000000, 0x00400000, 0x486 },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x465 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x479 },
+ { 0x00000000, 0x00400000, 0x486 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46a },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x479 },
+ { 0x00000000, 0x00400000, 0x486 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46f },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x479 },
+ { 0x00000000, 0x00400000, 0x486 },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x474 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x479 },
+ { 0x00000000, 0x00400000, 0x486 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x479 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x479 },
+ { 0x00000000, 0x00400000, 0x486 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x483 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x48c },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x44c },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x496 },
+ { 0x00040000, 0xc0494a20, 0x497 },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4a3 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x49f },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x49d },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4b6 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x681 },
+ { 0x00000000, 0x00400000, 0x4ba },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x67c },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4c1 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x67c },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4c3 },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4f3 },
+ { 0x0000002c, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4e2 },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4d6 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000002d, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x49d },
+ { 0x0000002c, 0xc0203620, 0x000 },
+ { 0x0000002d, 0xc0403620, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4f8 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xb5000000, 0x00204411, 0x000 },
+ { 0x00002000, 0x00204811, 0x000 },
+ { 0xb6000000, 0x00204411, 0x000 },
+ { 0x0000a000, 0x00204811, 0x000 },
+ { 0xb7000000, 0x00204411, 0x000 },
+ { 0x0000c000, 0x00204811, 0x000 },
+ { 0xb8000000, 0x00204411, 0x000 },
+ { 0x0000f8e0, 0x00204811, 0x000 },
+ { 0xb9000000, 0x00204411, 0x000 },
+ { 0x0000f880, 0x00204811, 0x000 },
+ { 0xba000000, 0x00204411, 0x000 },
+ { 0x0000e000, 0x00204811, 0x000 },
+ { 0xbb000000, 0x00204411, 0x000 },
+ { 0x0000f000, 0x00204811, 0x000 },
+ { 0xbc000000, 0x00204411, 0x000 },
+ { 0x0000f3fc, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x50c },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x521 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x00000028, 0x00203623, 0x000 },
+ { 0x00000017, 0x00203623, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203623, 0x000 },
+ { 0x00000015, 0x00203623, 0x000 },
+ { 0x00000016, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x00000023, 0x00203623, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000002a, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x0000001f, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000020, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x0000001e, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x66a },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x559 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x67c },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x561 },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x56f },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x561 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x67c },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x56f },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x565 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x56f },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56d },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x681 },
+ { 0x00000000, 0x00401c10, 0x56f },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x571 },
+ { 0x00000000, 0x00600000, 0x5bc },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x582 },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x67c },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x580 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x593 },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x67c },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x591 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5a4 },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x67c },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5a2 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x67c },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5b1 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x5b7 },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5bc },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000002c, 0x00203621, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5c3 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000030, 0x00403621, 0x5d6 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x5d6 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a092, 0x00604411, 0x67c },
+ { 0x00000031, 0x00203630, 0x000 },
+ { 0x0004a093, 0x00604411, 0x67c },
+ { 0x00000032, 0x00203630, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x67c },
+ { 0x00000033, 0x00203630, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x67c },
+ { 0x00000034, 0x00203630, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x67c },
+ { 0x00000035, 0x00203630, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x67c },
+ { 0x00000036, 0x00203630, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000001, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x61f },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x61f },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x5f8 },
+ { 0x0000a092, 0x00204411, 0x000 },
+ { 0x00000031, 0x00204a2d, 0x000 },
+ { 0x0000a093, 0x00204411, 0x000 },
+ { 0x00000032, 0x00204a2d, 0x000 },
+ { 0x0000a2b6, 0x00204411, 0x000 },
+ { 0x00000033, 0x00204a2d, 0x000 },
+ { 0x0000a2ba, 0x00204411, 0x000 },
+ { 0x00000034, 0x00204a2d, 0x000 },
+ { 0x0000a2be, 0x00204411, 0x000 },
+ { 0x00000035, 0x00204a2d, 0x000 },
+ { 0x0000a2c2, 0x00204411, 0x000 },
+ { 0x00000036, 0x00204a2d, 0x000 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x000001ff, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x61e },
+ { 0x00000000, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x601 },
+ { 0x0004a003, 0x00604411, 0x67c },
+ { 0x0000a003, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x14c00000, 0x606 },
+ { 0x0004a010, 0x00604411, 0x67c },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x61e },
+ { 0x0004a011, 0x00604411, 0x67c },
+ { 0x0000a011, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a012, 0x00604411, 0x67c },
+ { 0x0000a012, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a013, 0x00604411, 0x67c },
+ { 0x0000a013, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a014, 0x00604411, 0x67c },
+ { 0x0000a014, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a015, 0x00604411, 0x67c },
+ { 0x0000a015, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a016, 0x00604411, 0x67c },
+ { 0x0000a016, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a017, 0x00604411, 0x67c },
+ { 0x0000a017, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x0000002c, 0x0080062d, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x630 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000002, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x0000002b, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x634 },
+ { 0x00000000, 0x00600000, 0x5bc },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x634 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00404811, 0x620 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x620 },
+ { 0x00000000, 0x00600000, 0x64d },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36a },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x67c },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x647 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36a },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x67c },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x67b },
+ { 0x00000010, 0x00404c11, 0x661 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x0000001d, 0x00200a2d, 0x000 },
+ { 0x0000001e, 0x00200e2d, 0x000 },
+ { 0x0000001f, 0x0020122d, 0x000 },
+ { 0x00000020, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x67a },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x0000001f, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x67c },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x67f },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x681 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x684 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000024, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000022, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x014204f5, 0x05b30250, 0x000 },
+ { 0x01c30168, 0x043505b3, 0x000 },
+ { 0x02250209, 0x02500151, 0x000 },
+ { 0x02230245, 0x02a00241, 0x000 },
+ { 0x03cd05b3, 0x05b305b3, 0x000 },
+ { 0x063c063d, 0x031f05b3, 0x000 },
+ { 0x05b305b8, 0x03200340, 0x000 },
+ { 0x032a0282, 0x03420334, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x05b30544, 0x05b305b3, 0x000 },
+ { 0x03b205b3, 0x04ae0344, 0x000 },
+ { 0x048d0443, 0x043305b3, 0x000 },
+ { 0x04c305b3, 0x043704d0, 0x000 },
+ { 0x044304fa, 0x03510371, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x05b305b3, 0x063205ba, 0x000 },
+ { 0x05b305b3, 0x000705b3, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x03ee03e3, 0x03fe03fc, 0x000 },
+ { 0x04040400, 0x04020406, 0x000 },
+ { 0x0412040e, 0x041a0416, 0x000 },
+ { 0x0422041e, 0x042a0426, 0x000 },
+ { 0x05b305b3, 0x042e05b3, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x00020668, 0x06860006, 0x000 },
+};
+
+static const u32 RV670_pfp_microcode[] = {
+0xca0400,
+0xa00000,
+0x7e828b,
+0x7c038b,
+0x8001b8,
+0x7c038b,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581a8,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0fff0,
+0x042c04,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255403,
+0x7cd580,
+0x259c03,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d3,
+0xd5c01e,
+0xca0800,
+0x80001a,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800053,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xd48060,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001b8,
+0xd4c01e,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800000,
+0x062001,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x800079,
+0xd42013,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x80008d,
+0x000000,
+0xc41432,
+0xc61843,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800000,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xe4015e,
+0xd4001e,
+0x800000,
+0x062001,
+0xca1800,
+0x0a2001,
+0xd60076,
+0xc40836,
+0x988007,
+0xc61045,
+0x950110,
+0xd4001f,
+0xd46062,
+0x800000,
+0xd42062,
+0xcc3835,
+0xcc1433,
+0x8401bb,
+0xd40072,
+0xd5401e,
+0x800000,
+0xee001e,
+0xe2001a,
+0x8401bb,
+0xe2001a,
+0xcc104b,
+0xcc0447,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001b8,
+0xd4006d,
+0x344401,
+0xcc0c48,
+0x98403a,
+0xcc2c4a,
+0x958004,
+0xcc0449,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x8400f0,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x8400f0,
+0xcc1003,
+0x988017,
+0x043808,
+0x8400f0,
+0xcc1003,
+0x988013,
+0x043804,
+0x8400f0,
+0xcc1003,
+0x988014,
+0xcc104c,
+0x9a8009,
+0xcc144d,
+0x9840dc,
+0xd4006d,
+0xcc1848,
+0xd5001a,
+0xd5401a,
+0x8000c9,
+0xd5801a,
+0x96c0d5,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800000,
+0xec007f,
+0x9ac0cc,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809e,
+0xd4006d,
+0x98409c,
+0xd4006e,
+0xcc084c,
+0xcc0c4d,
+0xcc1048,
+0xd4801a,
+0xd4c01a,
+0x800101,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482d9,
+0xca0c00,
+0xd4401e,
+0x800000,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800000,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x9882bd,
+0x000000,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x9902b0,
+0x7c738b,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984297,
+0x000000,
+0x800161,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc104e,
+0x990004,
+0xd40073,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x950021,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x042802,
+0x7d8380,
+0xd5a86f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0xc82402,
+0x8001b8,
+0xd60076,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800000,
+0xee001e,
+0x800000,
+0xee001f,
+0xd4001f,
+0x800000,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010171,
+0x020178,
+0x03008f,
+0x04007f,
+0x050003,
+0x06003f,
+0x070032,
+0x08012c,
+0x090046,
+0x0a0036,
+0x1001b6,
+0x1700a2,
+0x22013a,
+0x230149,
+0x2000b4,
+0x240125,
+0x27004d,
+0x28006a,
+0x2a0060,
+0x2b0052,
+0x2f0065,
+0x320087,
+0x34017f,
+0x3c0156,
+0x3f0072,
+0x41018c,
+0x44012e,
+0x550173,
+0x56017a,
+0x60000b,
+0x610034,
+0x620038,
+0x630038,
+0x640038,
+0x650038,
+0x660038,
+0x670038,
+0x68003a,
+0x690041,
+0x6a0048,
+0x6b0048,
+0x6c0048,
+0x6d0048,
+0x6e0048,
+0x6f0048,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+};
+
+static const u32 RS780_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x622 },
+ { 0x00000000, 0x00600000, 0x5d1 },
+ { 0x00000000, 0x00600000, 0x5de },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000018, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000028, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000019, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x00000017, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000027, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x0000000e, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x0000000f, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000029, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000030, 0x0020162d, 0x000 },
+ { 0x00000002, 0x00291625, 0x000 },
+ { 0x00000030, 0x00203625, 0x000 },
+ { 0x00000025, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x083 },
+ { 0x00000026, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x084 },
+ { 0x00000000, 0x00400000, 0x08a },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203624, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x08a },
+ { 0x00000000, 0x00600000, 0x5ff },
+ { 0x00000000, 0x00600000, 0x5f3 },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08d },
+ { 0x00000012, 0xc0403620, 0x093 },
+ { 0x00000000, 0x2ee00000, 0x091 },
+ { 0x00000000, 0x2ce00000, 0x090 },
+ { 0x00000002, 0x00400e2d, 0x092 },
+ { 0x00000003, 0x00400e2d, 0x092 },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000012, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x098 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x0a0 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09e },
+ { 0x00000000, 0x2ce00000, 0x09d },
+ { 0x00000002, 0x00400e2d, 0x09f },
+ { 0x00000003, 0x00400e2d, 0x09f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0aa },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e1 },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x0b3 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x12f },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0cb },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0dc },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0da },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d5 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d4 },
+ { 0x00003f00, 0x00400c11, 0x0d6 },
+ { 0x00001f00, 0x00400c11, 0x0d6 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0dc },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00280e22, 0x000 },
+ { 0x00000080, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00200e2d, 0x000 },
+ { 0x00000026, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ea },
+ { 0x00000000, 0x00600000, 0x5f9 },
+ { 0x00000000, 0x00400000, 0x0eb },
+ { 0x00000000, 0x00600000, 0x5fc },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f8 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f8 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0fd },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x104 },
+ { 0xffffffff, 0x00404811, 0x10b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x107 },
+ { 0x0000ffff, 0x00404811, 0x10b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x10a },
+ { 0x000000ff, 0x00404811, 0x10b },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x112 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x114 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x11b },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x117 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x12e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x622 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x621 },
+ { 0x00000004, 0x00404c11, 0x135 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000001c, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x622 },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x13c },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x147 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x158 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x18f },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x181 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x186 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x186 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x182 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x197 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000011, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2fb },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x174 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x194 },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x19b },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000029, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x0000000f, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x12f },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x00000015, 0x00600e2d, 0x1bd },
+ { 0x00000016, 0x00600e2d, 0x1bd },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1b9 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000018, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000013, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e0 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1dc },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1d8 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1d1 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1e5 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2bb },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1f8 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x205 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x205 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x621 },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x219 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x212 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x5de },
+ { 0x00000000, 0x0040040f, 0x213 },
+ { 0x00000000, 0x00600000, 0x5d1 },
+ { 0x00000000, 0x00600000, 0x5de },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00000000, 0x00600000, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x232 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x236 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x236 },
+ { 0x00000000, 0xc0404800, 0x233 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2fb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x5d1 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x24c },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x251 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x315 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x27c },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x26a },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25f },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x262 },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x267 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x26a },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2c1 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x272 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x271 },
+ { 0x00000016, 0x00404811, 0x276 },
+ { 0x00000018, 0x00404811, 0x276 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x275 },
+ { 0x00000017, 0x00404811, 0x276 },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2e9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x256 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x622 },
+ { 0x00000000, 0x00600000, 0x5d1 },
+ { 0x00000000, 0xc0600000, 0x2a3 },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x0000002b, 0x00201a2d, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x0000002a, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x292 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x12f },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x29d },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000001c, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000029, 0x00203622, 0x000 },
+ { 0x00000028, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000021, 0x00203627, 0x000 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2dc },
+ { 0x00000000, 0x00400000, 0x2d9 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2d9 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2dc },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000000, 0x00600000, 0x5ff },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00600000, 0x5f6 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2a7 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x0000001a, 0x00201e2d, 0x000 },
+ { 0x0000001b, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000017, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x318 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x5de },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x355 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x622 },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x35e },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x36c },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00604802, 0x374 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x370 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x367 },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5ba },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x367 },
+ { 0x0000002c, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x376 },
+ { 0x0000002c, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x38c },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b7 },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b9 },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a2 },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3ae },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3ae },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x396 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x622 },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x398 },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x622 },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3a4 },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x80000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000010, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3b4 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x374 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3ce },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x622 },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3c2 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3d3 },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x622 },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e1 },
+ { 0x00000000, 0xc0401800, 0x3e4 },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x622 },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e7 },
+ { 0x00000000, 0xc0401c00, 0x3ea },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x622 },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3f7 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3ff },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3fa },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3fa },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3fa },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3fa },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3fa },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3fa },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x01182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0218a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0318c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0418f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0518f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0618e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0718f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0818f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000033, 0xc0300a20, 0x000 },
+ { 0x00000000, 0xc0403440, 0x000 },
+ { 0x00000030, 0x00200a2d, 0x000 },
+ { 0x00000000, 0xc0290c40, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000018, 0x40210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x447 },
+ { 0x00800000, 0xc0494a20, 0x448 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x06e00000, 0x450 },
+ { 0x00000004, 0x00200811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x622 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x450 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x461 },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000004, 0x002f0228, 0x000 },
+ { 0x00000000, 0x06e00000, 0x461 },
+ { 0x00000004, 0x00202011, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x469 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x622 },
+ { 0x00000000, 0x00400000, 0x46e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00604805, 0x627 },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x475 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x48e },
+ { 0x00000000, 0x00400000, 0x49b },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x47a },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x48e },
+ { 0x00000000, 0x00400000, 0x49b },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x47f },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x48e },
+ { 0x00000000, 0x00400000, 0x49b },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x484 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x48e },
+ { 0x00000000, 0x00400000, 0x49b },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x489 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x48e },
+ { 0x00000000, 0x00400000, 0x49b },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x48e },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x48e },
+ { 0x00000000, 0x00400000, 0x49b },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x498 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x4a1 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x461 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4ab },
+ { 0x00040000, 0xc0494a20, 0x4ac },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4b8 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4b4 },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4b2 },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4cb },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x627 },
+ { 0x00000000, 0x00400000, 0x4cf },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x622 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4d6 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x622 },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4d8 },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x508 },
+ { 0x0000002c, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4f7 },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4eb },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000002d, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4b2 },
+ { 0x0000002c, 0xc0203620, 0x000 },
+ { 0x0000002d, 0xc0403620, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x50d },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xb5000000, 0x00204411, 0x000 },
+ { 0x00002000, 0x00204811, 0x000 },
+ { 0xb6000000, 0x00204411, 0x000 },
+ { 0x0000a000, 0x00204811, 0x000 },
+ { 0xb7000000, 0x00204411, 0x000 },
+ { 0x0000c000, 0x00204811, 0x000 },
+ { 0xb8000000, 0x00204411, 0x000 },
+ { 0x0000f8e0, 0x00204811, 0x000 },
+ { 0xb9000000, 0x00204411, 0x000 },
+ { 0x0000f880, 0x00204811, 0x000 },
+ { 0xba000000, 0x00204411, 0x000 },
+ { 0x0000e000, 0x00204811, 0x000 },
+ { 0xbb000000, 0x00204411, 0x000 },
+ { 0x0000f000, 0x00204811, 0x000 },
+ { 0xbc000000, 0x00204411, 0x000 },
+ { 0x0000f3fc, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x521 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x536 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x00000028, 0x00203623, 0x000 },
+ { 0x00000017, 0x00203623, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203623, 0x000 },
+ { 0x00000015, 0x00203623, 0x000 },
+ { 0x00000016, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x00000023, 0x00203623, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000002a, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x0000001f, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000020, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x0000001e, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x610 },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x56c },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x622 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x574 },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x582 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x574 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x622 },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x582 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x578 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x582 },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x580 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x627 },
+ { 0x00000000, 0x00401c10, 0x582 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x584 },
+ { 0x00000000, 0x00600000, 0x5c3 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x592 },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x00000033, 0x0020262d, 0x000 },
+ { 0x0000001a, 0x00212229, 0x000 },
+ { 0x00000006, 0x00222629, 0x000 },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x590 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5a0 },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x00000034, 0x0020262d, 0x000 },
+ { 0x0000001a, 0x00212229, 0x000 },
+ { 0x00000006, 0x00222629, 0x000 },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x59e },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5ae },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x00000035, 0x0020262d, 0x000 },
+ { 0x0000001a, 0x00212229, 0x000 },
+ { 0x00000006, 0x00222629, 0x000 },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5ac },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x00000036, 0x0020262d, 0x000 },
+ { 0x0000001a, 0x00212229, 0x000 },
+ { 0x00000006, 0x00222629, 0x000 },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5b8 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x5be },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5c3 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x5d6 },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x0000002b, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x5da },
+ { 0x00000000, 0x00600000, 0x5c3 },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5da },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00404811, 0x5cd },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x5cd },
+ { 0x00000000, 0x00600000, 0x5f3 },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x374 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x622 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x5ed },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x374 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x622 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x621 },
+ { 0x00000010, 0x00404c11, 0x607 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x0000001d, 0x00200a2d, 0x000 },
+ { 0x0000001e, 0x00200e2d, 0x000 },
+ { 0x0000001f, 0x0020122d, 0x000 },
+ { 0x00000020, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x620 },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x0000001f, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x622 },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x625 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x627 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x62a },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000024, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000022, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x0142050a, 0x05ba0250, 0x000 },
+ { 0x01c30168, 0x044105ba, 0x000 },
+ { 0x02250209, 0x02500151, 0x000 },
+ { 0x02230245, 0x02a00241, 0x000 },
+ { 0x03d705ba, 0x05ba05ba, 0x000 },
+ { 0x05e205e3, 0x031f05ba, 0x000 },
+ { 0x032005bf, 0x0320034a, 0x000 },
+ { 0x03340282, 0x034c033e, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x05ba0557, 0x05ba032a, 0x000 },
+ { 0x03bc05ba, 0x04c3034e, 0x000 },
+ { 0x04a20455, 0x043f05ba, 0x000 },
+ { 0x04d805ba, 0x044304e5, 0x000 },
+ { 0x0455050f, 0x035b037b, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x05ba05ba, 0x05d805c1, 0x000 },
+ { 0x05ba05ba, 0x000705ba, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x03f803ed, 0x04080406, 0x000 },
+ { 0x040e040a, 0x040c0410, 0x000 },
+ { 0x041c0418, 0x04240420, 0x000 },
+ { 0x042c0428, 0x04340430, 0x000 },
+ { 0x05ba05ba, 0x043a0438, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x0002060e, 0x062c0006, 0x000 },
+};
+
+static const u32 RS780_pfp_microcode[] = {
+0xca0400,
+0xa00000,
+0x7e828b,
+0x7c038b,
+0x8001db,
+0x7c038b,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581cb,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0ffe0,
+0x042c08,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255407,
+0x7cd580,
+0x259c07,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d3,
+0xd5c01e,
+0xca0800,
+0x80001a,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xca0c00,
+0x8001db,
+0xd48024,
+0xca0800,
+0x7c00c0,
+0xc81425,
+0xc81824,
+0x7c9488,
+0x7c9880,
+0xc20003,
+0xd40075,
+0x7c744c,
+0x800064,
+0xd4401e,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800062,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c01,
+0xd48060,
+0x94c003,
+0x041001,
+0x041002,
+0xd50025,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001db,
+0xd4c01e,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800000,
+0x062001,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x80009c,
+0xd42013,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x8000b0,
+0x000000,
+0xc41432,
+0xc61843,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800000,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xe4015e,
+0xd4001e,
+0x800000,
+0x062001,
+0xca1800,
+0x0a2001,
+0xd60076,
+0xc40836,
+0x988007,
+0xc61045,
+0x950110,
+0xd4001f,
+0xd46062,
+0x800000,
+0xd42062,
+0xcc3835,
+0xcc1433,
+0x8401de,
+0xd40072,
+0xd5401e,
+0x800000,
+0xee001e,
+0xe2001a,
+0x8401de,
+0xe2001a,
+0xcc104b,
+0xcc0447,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001db,
+0xd4006d,
+0x344401,
+0xcc0c48,
+0x98403a,
+0xcc2c4a,
+0x958004,
+0xcc0449,
+0x8001db,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x840113,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x840113,
+0xcc1003,
+0x988017,
+0x043808,
+0x840113,
+0xcc1003,
+0x988013,
+0x043804,
+0x840113,
+0xcc1003,
+0x988014,
+0xcc104c,
+0x9a8009,
+0xcc144d,
+0x9840dc,
+0xd4006d,
+0xcc1848,
+0xd5001a,
+0xd5401a,
+0x8000ec,
+0xd5801a,
+0x96c0d5,
+0xd4006d,
+0x8001db,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800000,
+0xec007f,
+0x9ac0cc,
+0xd4006d,
+0x8001db,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001db,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809e,
+0xd4006d,
+0x98409c,
+0xd4006e,
+0xcc084c,
+0xcc0c4d,
+0xcc1048,
+0xd4801a,
+0xd4c01a,
+0x800124,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482b6,
+0xca0c00,
+0xd4401e,
+0x800000,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800000,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x98829a,
+0x000000,
+0x8401de,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x99028d,
+0x7c738b,
+0x8401de,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984274,
+0x000000,
+0x800184,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc104e,
+0x990004,
+0xd40073,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x950021,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x042802,
+0x7d8380,
+0xd5a86f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0xc82402,
+0x8001db,
+0xd60076,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800000,
+0xee001e,
+0x800000,
+0xee001f,
+0xd4001f,
+0x800000,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010194,
+0x02019b,
+0x0300b2,
+0x0400a2,
+0x050003,
+0x06003f,
+0x070032,
+0x08014f,
+0x090046,
+0x0a0036,
+0x1001d9,
+0x1700c5,
+0x22015d,
+0x23016c,
+0x2000d7,
+0x240148,
+0x26004d,
+0x27005c,
+0x28008d,
+0x290051,
+0x2a007e,
+0x2b0061,
+0x2f0088,
+0x3200aa,
+0x3401a2,
+0x36006f,
+0x3c0179,
+0x3f0095,
+0x4101af,
+0x440151,
+0x550196,
+0x56019d,
+0x60000b,
+0x610034,
+0x620038,
+0x630038,
+0x640038,
+0x650038,
+0x660038,
+0x670038,
+0x68003a,
+0x690041,
+0x6a0048,
+0x6b0048,
+0x6c0048,
+0x6d0048,
+0x6e0048,
+0x6f0048,
+0x7301d9,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+};
+
+static const u32 RV770_cp_microcode[] = {
+0xcc0003ea,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x80000001,
+0xd040007f,
+0x80000001,
+0xcc400041,
+0x7c40c000,
+0xc0160004,
+0x30d03fff,
+0x7d15000c,
+0xcc110000,
+0x28d8001e,
+0x31980001,
+0x28dc001f,
+0xc8200004,
+0x95c00006,
+0x7c424000,
+0xcc000062,
+0x7e56800c,
+0xcc290000,
+0xc8240004,
+0x7e26000b,
+0x95800006,
+0x7c42c000,
+0xcc000062,
+0x7ed7000c,
+0xcc310000,
+0xc82c0004,
+0x7e2e000c,
+0xcc000062,
+0x31103fff,
+0x80000001,
+0xce110000,
+0x7c40c000,
+0x80000001,
+0xcc400040,
+0x80000001,
+0xcc412257,
+0x7c418000,
+0xcc400045,
+0xcc400048,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xcc400045,
+0xcc400048,
+0x7c40c000,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xcc000045,
+0xcc000048,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x040ca1fd,
+0xc0120001,
+0xcc000045,
+0xcc000048,
+0x7cd0c00c,
+0xcc41225c,
+0xcc41a1fc,
+0xd04d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x80000001,
+0xcc41225d,
+0x7c408000,
+0x7c40c000,
+0xc02a0002,
+0x7c410000,
+0x7d29000c,
+0x30940001,
+0x30980006,
+0x309c0300,
+0x29dc0008,
+0x7c420000,
+0x7c424000,
+0x9540000f,
+0xc02e0004,
+0x05f02258,
+0x7f2f000c,
+0xcc310000,
+0xc8280004,
+0xccc12169,
+0xcd01216a,
+0xce81216b,
+0x0db40002,
+0xcc01216c,
+0x9740000e,
+0x0db40000,
+0x8000007b,
+0xc834000a,
+0x0db40002,
+0x97400009,
+0x0db40000,
+0xc02e0004,
+0x05f02258,
+0x7f2f000c,
+0xcc310000,
+0xc8280004,
+0x8000007b,
+0xc834000a,
+0x97400004,
+0x7e028000,
+0x8000007b,
+0xc834000a,
+0x0db40004,
+0x9740ff8c,
+0x00000000,
+0xce01216d,
+0xce41216e,
+0xc8280003,
+0xc834000a,
+0x9b400004,
+0x043c0005,
+0x8400026d,
+0xcc000062,
+0x0df40000,
+0x9740000b,
+0xc82c03e6,
+0xce81a2b7,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c4,
+0x80000001,
+0xcfc1a2d1,
+0x0df40001,
+0x9740000b,
+0xc82c03e7,
+0xce81a2bb,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c5,
+0x80000001,
+0xcfc1a2d2,
+0x0df40002,
+0x9740000b,
+0xc82c03e8,
+0xce81a2bf,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c6,
+0x80000001,
+0xcfc1a2d3,
+0xc82c03e9,
+0xce81a2c3,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c7,
+0x80000001,
+0xcfc1a2d4,
+0x80000001,
+0xcc400042,
+0x7c40c000,
+0x7c410000,
+0x2914001d,
+0x31540001,
+0x9940000d,
+0x31181000,
+0xc81c0011,
+0x09dc0001,
+0x95c0ffff,
+0xc81c0011,
+0xccc12100,
+0xcd012101,
+0xccc12102,
+0xcd012103,
+0x04180004,
+0x8000039f,
+0xcd81a2a4,
+0xc02a0004,
+0x95800008,
+0x36a821a3,
+0xcc290000,
+0xc8280004,
+0xc81c0011,
+0x0de40040,
+0x9640ffff,
+0xc81c0011,
+0xccc12170,
+0xcd012171,
+0xc8200012,
+0x96000000,
+0xc8200012,
+0x8000039f,
+0xcc000064,
+0x7c40c000,
+0x7c410000,
+0xcc000045,
+0xcc000048,
+0x40d40003,
+0xcd41225c,
+0xcd01a1fc,
+0xc01a0001,
+0x041ca1fd,
+0x7dd9c00c,
+0x7c420000,
+0x08cc0001,
+0x06240001,
+0x06280002,
+0xce1d0000,
+0xce5d0000,
+0x98c0fffa,
+0xce9d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0x30d00001,
+0x28cc0001,
+0x7c414000,
+0x95000006,
+0x7c418000,
+0xcd41216d,
+0xcd81216e,
+0x800000f3,
+0xc81c0003,
+0xc0220004,
+0x7e16000c,
+0xcc210000,
+0xc81c0004,
+0x7c424000,
+0x98c00004,
+0x7c428000,
+0x80000001,
+0xcde50000,
+0xce412169,
+0xce81216a,
+0xcdc1216b,
+0x80000001,
+0xcc01216c,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0x7c41c000,
+0x28a40008,
+0x326400ff,
+0x0e68003c,
+0x9680000a,
+0x7c020000,
+0x7c420000,
+0x1e300003,
+0xcc00006a,
+0x9b000003,
+0x42200005,
+0x04200040,
+0x80000110,
+0x7c024000,
+0x7e024000,
+0x9a400000,
+0x0a640001,
+0x30ec0010,
+0x9ac0000a,
+0xcc000062,
+0xc02a0004,
+0xc82c0021,
+0x7e92800c,
+0xcc000041,
+0xcc290000,
+0xcec00021,
+0x80000120,
+0xc8300004,
+0xcd01216d,
+0xcd41216e,
+0xc8300003,
+0x7f1f000b,
+0x30f40007,
+0x27780001,
+0x9740002a,
+0x07b80125,
+0x9f800000,
+0x00000000,
+0x80000135,
+0x7f1b8004,
+0x80000139,
+0x7f1b8005,
+0x8000013d,
+0x7f1b8002,
+0x80000141,
+0x7f1b8003,
+0x80000145,
+0x7f1b8007,
+0x80000149,
+0x7f1b8006,
+0x8000014e,
+0x28a40008,
+0x9b800019,
+0x28a40008,
+0x8000015e,
+0x326400ff,
+0x9b800015,
+0x28a40008,
+0x8000015e,
+0x326400ff,
+0x9b800011,
+0x28a40008,
+0x8000015e,
+0x326400ff,
+0x9b80000d,
+0x28a40008,
+0x8000015e,
+0x326400ff,
+0x9b800009,
+0x28a40008,
+0x8000015e,
+0x326400ff,
+0x9b800005,
+0x28a40008,
+0x8000015e,
+0x326400ff,
+0x28a40008,
+0x326400ff,
+0x0e68003c,
+0x9a80feb1,
+0x28ec0008,
+0x7c434000,
+0x7c438000,
+0x7c43c000,
+0x96c00007,
+0xcc000062,
+0xcf412169,
+0xcf81216a,
+0xcfc1216b,
+0x80000001,
+0xcc01216c,
+0x80000001,
+0xcff50000,
+0xcc00006b,
+0x840003a2,
+0x0e68003c,
+0x9a800004,
+0xc8280015,
+0x80000001,
+0xd040007f,
+0x9680ffab,
+0x7e024000,
+0x8400023b,
+0xc00e0002,
+0xcc000041,
+0x80000239,
+0xccc1304a,
+0x7c40c000,
+0x7c410000,
+0xc01e0001,
+0x29240012,
+0xc0220002,
+0x96400005,
+0xc0260004,
+0xc027fffb,
+0x7d25000b,
+0xc0260000,
+0x7dd2800b,
+0x7e12c00b,
+0x7d25000c,
+0x7c414000,
+0x7c418000,
+0xccc12169,
+0x9a80000a,
+0xcd01216a,
+0xcd41216b,
+0x96c0fe82,
+0xcd81216c,
+0xc8300018,
+0x97000000,
+0xc8300018,
+0x80000001,
+0xcc000018,
+0x840003a2,
+0xcc00007f,
+0xc8140013,
+0xc8180014,
+0xcd41216b,
+0x96c0fe76,
+0xcd81216c,
+0x80000182,
+0xc8300018,
+0xc80c0008,
+0x98c00000,
+0xc80c0008,
+0x7c410000,
+0x95000002,
+0x00000000,
+0x7c414000,
+0xc8200009,
+0xcc400043,
+0xce01a1f4,
+0xcc400044,
+0xc00e8000,
+0x7c424000,
+0x7c428000,
+0x2aac001f,
+0x96c0fe63,
+0xc035f000,
+0xce4003e2,
+0x32780003,
+0x267c0008,
+0x7ff7c00b,
+0x7ffbc00c,
+0x2a780018,
+0xcfc003e3,
+0xcf8003e4,
+0x26b00002,
+0x7f3f0000,
+0xcf0003e5,
+0x8000031f,
+0x7c80c000,
+0x7c40c000,
+0x28d00008,
+0x3110000f,
+0x9500000f,
+0x25280001,
+0x06a801b3,
+0x9e800000,
+0x00000000,
+0x800001d4,
+0xc0120800,
+0x800001e2,
+0xc814000f,
+0x800001e9,
+0xc8140010,
+0x800001f0,
+0xccc1a2a4,
+0x800001f9,
+0xc8140011,
+0x30d0003f,
+0x0d280015,
+0x9a800012,
+0x0d28001e,
+0x9a80001e,
+0x0d280020,
+0x9a800023,
+0x0d24000f,
+0x0d280010,
+0x7e6a800c,
+0x9a800026,
+0x0d200004,
+0x0d240014,
+0x0d280028,
+0x7e62400c,
+0x7ea6800c,
+0x9a80002a,
+0xc8140011,
+0x80000001,
+0xccc1a2a4,
+0xc0120800,
+0x7c414000,
+0x7d0cc00c,
+0xc0120008,
+0x29580003,
+0x295c000c,
+0x7c420000,
+0x7dd1c00b,
+0x26200014,
+0x7e1e400c,
+0x7e4e800c,
+0xce81a2a4,
+0x80000001,
+0xcd81a1fe,
+0xc814000f,
+0x0410210e,
+0x95400000,
+0xc814000f,
+0xd0510000,
+0x80000001,
+0xccc1a2a4,
+0xc8140010,
+0x04102108,
+0x95400000,
+0xc8140010,
+0xd0510000,
+0x80000001,
+0xccc1a2a4,
+0xccc1a2a4,
+0x04100001,
+0xcd000019,
+0x840003a2,
+0xcc00007f,
+0xc8100019,
+0x99000000,
+0xc8100019,
+0x80000002,
+0x7c408000,
+0x04102100,
+0x09540001,
+0x9540ffff,
+0xc8140011,
+0xd0510000,
+0x8000039f,
+0xccc1a2a4,
+0x7c40c000,
+0xcc40000d,
+0x94c0fdff,
+0xcc40000e,
+0x7c410000,
+0x95000005,
+0x08cc0001,
+0xc8140005,
+0x99400014,
+0x00000000,
+0x98c0fffb,
+0x7c410000,
+0x80000002,
+0x7d008000,
+0xc8140005,
+0x7c40c000,
+0x9940000c,
+0xc818000c,
+0x7c410000,
+0x9580fdee,
+0xc820000e,
+0xc81c000d,
+0x66200020,
+0x7e1e002c,
+0x25240002,
+0x7e624020,
+0x80000001,
+0xcce60000,
+0x7c410000,
+0xcc00006c,
+0xcc00006d,
+0xc818001f,
+0xc81c001e,
+0x65980020,
+0x7dd9c02c,
+0x7cd4c00c,
+0xccde0000,
+0x45dc0004,
+0xc8280017,
+0x9680000f,
+0xc00e0001,
+0x28680008,
+0x2aac0016,
+0x32a800ff,
+0x0eb00049,
+0x7f2f000b,
+0x97000006,
+0x00000000,
+0xc8140005,
+0x7c40c000,
+0x80000223,
+0x7c410000,
+0x80000226,
+0xd040007f,
+0x8400023b,
+0xcc000041,
+0xccc1304a,
+0x94000000,
+0xc83c001a,
+0x043c0005,
+0xcfc1a2a4,
+0xc0361f90,
+0xc0387fff,
+0x7c03c010,
+0x7f7b400c,
+0xcf41217c,
+0xcfc1217d,
+0xcc01217e,
+0xc03a0004,
+0x0434217f,
+0x7f7b400c,
+0xcc350000,
+0xc83c0004,
+0x2bfc001f,
+0x04380020,
+0x97c00005,
+0xcc000062,
+0x9b800000,
+0x0bb80001,
+0x80000247,
+0xcc000071,
+0xcc01a1f4,
+0x04380016,
+0xc0360002,
+0xcf81a2a4,
+0x88000000,
+0xcf412010,
+0x7c40c000,
+0x28d0001c,
+0x95000005,
+0x04d40001,
+0xcd400065,
+0x80000001,
+0xcd400068,
+0x09540002,
+0x80000001,
+0xcd400066,
+0x8400026c,
+0xc81803ea,
+0x7c40c000,
+0x9980fd9d,
+0xc8140016,
+0x08d00001,
+0x9940002b,
+0xcd000068,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x043c0005,
+0xcfc1a2a4,
+0xcc01a1f4,
+0x840003a2,
+0xcc000046,
+0x88000000,
+0xcc00007f,
+0x8400027e,
+0xc81803ea,
+0x7c40c000,
+0x9980fd8b,
+0xc8140016,
+0x08d00001,
+0x99400019,
+0xcd000068,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x043c0022,
+0xcfc1a2a4,
+0x840003a2,
+0xcc000047,
+0x88000000,
+0xcc00007f,
+0xc8100016,
+0x9900000d,
+0xcc400067,
+0x80000002,
+0x7c408000,
+0xc81803ea,
+0x9980fd77,
+0x7c40c000,
+0x94c00003,
+0xc8100016,
+0x99000004,
+0xccc00068,
+0x80000002,
+0x7c408000,
+0x8400023b,
+0xc0148000,
+0xcc000041,
+0xcd41304a,
+0xc0148000,
+0x99000000,
+0xc8100016,
+0x80000002,
+0x7c408000,
+0xc0120001,
+0x7c51400c,
+0x80000001,
+0xd0550000,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0x291c001f,
+0xccc0004a,
+0xcd00004b,
+0x95c00003,
+0xc01c8000,
+0xcdc12010,
+0xdd830000,
+0x055c2000,
+0xcc000062,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc0004c,
+0xcd00004d,
+0xdd830000,
+0x055ca000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc0004e,
+0xcd00004f,
+0xdd830000,
+0x055cc000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00050,
+0xcd000051,
+0xdd830000,
+0x055cf8e0,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00052,
+0xcd000053,
+0xdd830000,
+0x055cf880,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00054,
+0xcd000055,
+0xdd830000,
+0x055ce000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00056,
+0xcd000057,
+0xdd830000,
+0x055cf000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00058,
+0xcd000059,
+0xdd830000,
+0x055cf3fc,
+0x80000001,
+0xd81f4100,
+0xd0432000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043a000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043c000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f8e0,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f880,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043e000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f3fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xc81403e0,
+0xcc430000,
+0xcc430000,
+0xcc430000,
+0x7d45c000,
+0xcdc30000,
+0xd0430000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0xc81003e2,
+0xc81403e5,
+0xc81803e3,
+0xc81c03e4,
+0xcd812169,
+0xcdc1216a,
+0xccc1216b,
+0xcc01216c,
+0x04200004,
+0x7da18000,
+0x7d964002,
+0x9640fcd7,
+0xcd8003e3,
+0x31280003,
+0xc02df000,
+0x25180008,
+0x7dad800b,
+0x7da9800c,
+0x80000001,
+0xcd8003e3,
+0x308cffff,
+0xd04d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0x7c410000,
+0x29240018,
+0x32640001,
+0x9a400013,
+0xc8140020,
+0x15580002,
+0x9580ffff,
+0xc8140020,
+0xcc00006e,
+0xccc12180,
+0xcd01218d,
+0xcc412181,
+0x2914001f,
+0x34588000,
+0xcd81218c,
+0x9540fcb9,
+0xcc412182,
+0xc8140020,
+0x9940ffff,
+0xc8140020,
+0x80000002,
+0x7c408000,
+0x7c414000,
+0x7c418000,
+0x7c41c000,
+0x65b40020,
+0x7f57402c,
+0xd4378100,
+0x47740004,
+0xd4378100,
+0x47740004,
+0xd4378100,
+0x47740004,
+0x09dc0004,
+0xd4378100,
+0x99c0fff8,
+0x47740004,
+0x2924001f,
+0xc0380019,
+0x9640fca1,
+0xc03e0004,
+0xcf8121f8,
+0x37e021f9,
+0xcc210000,
+0xc8200004,
+0x2a200018,
+0x32200001,
+0x9a00fffb,
+0xcf8121f8,
+0x80000002,
+0x7c408000,
+0x7c40c000,
+0x28d00018,
+0x31100001,
+0xc0160080,
+0x95000003,
+0xc02a0004,
+0x7cd4c00c,
+0xccc1217c,
+0xcc41217d,
+0xcc41217e,
+0x7c418000,
+0x1db00003,
+0x36a0217f,
+0x9b000003,
+0x419c0005,
+0x041c0040,
+0x99c00000,
+0x09dc0001,
+0xcc210000,
+0xc8240004,
+0x2a6c001f,
+0x419c0005,
+0x9ac0fffa,
+0xcc800062,
+0x80000002,
+0x7c408000,
+0x7c40c000,
+0x04d403e6,
+0x80000001,
+0xcc540000,
+0x8000039f,
+0xcc4003ea,
+0xc01c8000,
+0x044ca000,
+0xcdc12010,
+0x7c410000,
+0xc8140009,
+0x04180000,
+0x041c0008,
+0xcd800071,
+0x09dc0001,
+0x05980001,
+0xcd0d0000,
+0x99c0fffc,
+0xcc800062,
+0x8000039f,
+0xcd400071,
+0xc00e0100,
+0xcc000041,
+0xccc1304a,
+0xc83c007f,
+0xcc00007f,
+0x80000001,
+0xcc00007f,
+0xcc00007f,
+0x88000000,
+0xcc00007f,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00010333,
+0x00100004,
+0x00170006,
+0x00210008,
+0x00270028,
+0x00280023,
+0x00290029,
+0x002a0026,
+0x002b0029,
+0x002d0038,
+0x002e003f,
+0x002f004a,
+0x0034004c,
+0x00360030,
+0x003900af,
+0x003a00d0,
+0x003b00e5,
+0x003c00fd,
+0x003d016c,
+0x003f00ad,
+0x00410338,
+0x0043036c,
+0x0044018f,
+0x004500fd,
+0x004601ad,
+0x004701ad,
+0x00480200,
+0x0049020e,
+0x004a0257,
+0x004b0284,
+0x00520261,
+0x00530273,
+0x00540289,
+0x0057029b,
+0x0060029f,
+0x006102ae,
+0x006202b8,
+0x006302c2,
+0x006402cc,
+0x006502d6,
+0x006602e0,
+0x006702ea,
+0x006802f4,
+0x006902f8,
+0x006a02fc,
+0x006b0300,
+0x006c0304,
+0x006d0308,
+0x006e030c,
+0x006f0310,
+0x00700314,
+0x00720386,
+0x0074038c,
+0x0079038a,
+0x007c031e,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+};
+
+static const u32 RV770_pfp_microcode[] = {
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x80000000,
+0xdc030000,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xc818000e,
+0x31980001,
+0x7c424000,
+0x95800252,
+0x7c428000,
+0xc81c001c,
+0xc037c000,
+0x7c40c000,
+0x7c410000,
+0x7cb4800b,
+0xc0360003,
+0x99c00000,
+0xc81c001c,
+0x7cb4800c,
+0x24d40002,
+0x7d654000,
+0xcd400043,
+0xce800043,
+0xcd000043,
+0xcc800040,
+0xce400040,
+0xce800040,
+0xccc00040,
+0xdc3a0000,
+0x9780ffde,
+0xcd000040,
+0x7c40c000,
+0x80000018,
+0x7c410000,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xc818000e,
+0x8000000c,
+0x31980002,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xc818000e,
+0x288c0008,
+0x30cc000f,
+0x34100001,
+0x7d0d0008,
+0x8000000c,
+0x7d91800b,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xcc4003f9,
+0x80000261,
+0xcc4003f8,
+0xc82003f8,
+0xc81c03f9,
+0xc81803fb,
+0xc037ffff,
+0x7c414000,
+0xcf41a29e,
+0x66200020,
+0x7de1c02c,
+0x7d58c008,
+0x7cdcc020,
+0x68d00020,
+0xc0360003,
+0xcc000054,
+0x7cb4800c,
+0x8000006a,
+0xcc800040,
+0x7c418000,
+0xcd81a29e,
+0xcc800040,
+0xcd800040,
+0x80000068,
+0xcc000054,
+0xc019ffff,
+0xcc800040,
+0xcd81a29e,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0xccc1a1fa,
+0xcd01a1f9,
+0xcd41a29d,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xcc400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xcc000054,
+0xcc800040,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0xccc1a1fa,
+0xcd01a1f9,
+0xcd41a29d,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x7c40c000,
+0x30d00001,
+0xccc1a29f,
+0x95000003,
+0x04140001,
+0x04140002,
+0xcd4003fb,
+0xcc800040,
+0x80000000,
+0xccc00040,
+0x7c40c000,
+0xcc800040,
+0xccc1a2a2,
+0x80000000,
+0xccc00040,
+0x7c40c000,
+0x28d4001f,
+0xcc800040,
+0x95400003,
+0x7c410000,
+0xccc00057,
+0x2918001f,
+0xccc00040,
+0x95800003,
+0xcd000040,
+0xcd000058,
+0x80000261,
+0xcc00007f,
+0xc8200017,
+0xc8300022,
+0x9a000006,
+0x0e280001,
+0xc824001e,
+0x0a640001,
+0xd4001240,
+0xce400040,
+0xc036c000,
+0x96800007,
+0x37747900,
+0x041c0001,
+0xcf400040,
+0xcdc00040,
+0xcf0003fa,
+0x7c030000,
+0xca0c0010,
+0x7c410000,
+0x94c00004,
+0x7c414000,
+0xd42002c4,
+0xcde00044,
+0x9b00000b,
+0x7c418000,
+0xcc00004b,
+0xcda00049,
+0xcd200041,
+0xcd600041,
+0xcda00041,
+0x06200001,
+0xce000056,
+0x80000261,
+0xcc00007f,
+0xc8280020,
+0xc82c0021,
+0xcc000063,
+0x7eea4001,
+0x65740020,
+0x7f53402c,
+0x269c0002,
+0x7df5c020,
+0x69f80020,
+0xce80004b,
+0xce600049,
+0xcde00041,
+0xcfa00041,
+0xce600041,
+0x271c0002,
+0x7df5c020,
+0x69f80020,
+0x7db24001,
+0xcf00004b,
+0xce600049,
+0xcde00041,
+0xcfa00041,
+0x800000bd,
+0xce600041,
+0xc8200017,
+0xc8300022,
+0x9a000006,
+0x0e280001,
+0xc824001e,
+0x0a640001,
+0xd4001240,
+0xce400040,
+0xca0c0010,
+0x7c410000,
+0x94c0000b,
+0xc036c000,
+0x96800007,
+0x37747900,
+0x041c0001,
+0xcf400040,
+0xcdc00040,
+0xcf0003fa,
+0x7c030000,
+0x800000b6,
+0x7c414000,
+0xcc000048,
+0x800000ef,
+0x00000000,
+0xc8200017,
+0xc81c0023,
+0x0e240002,
+0x99c00015,
+0x7c418000,
+0x0a200001,
+0xce000056,
+0xd4000440,
+0xcc000040,
+0xc036c000,
+0xca140013,
+0x96400007,
+0x37747900,
+0xcf400040,
+0xcc000040,
+0xc83003fa,
+0x80000104,
+0xcf000022,
+0xcc000022,
+0x9540015d,
+0xcc00007f,
+0xcca00046,
+0x80000000,
+0xcc200046,
+0x80000261,
+0xcc000064,
+0xc8200017,
+0xc810001f,
+0x96000005,
+0x09100001,
+0xd4000440,
+0xcd000040,
+0xcd000022,
+0xcc800040,
+0xd0400040,
+0xc80c0025,
+0x94c0feeb,
+0xc8100008,
+0xcd000040,
+0xd4000fc0,
+0x80000000,
+0xd4000fa2,
+0x7c40c000,
+0x7c410000,
+0xccc003fd,
+0xcd0003fc,
+0xccc00042,
+0xcd000042,
+0x2914001f,
+0x29180010,
+0x31980007,
+0x3b5c0001,
+0x7d76000b,
+0x99800005,
+0x7d5e400b,
+0xcc000042,
+0x80000261,
+0xcc00004d,
+0x29980001,
+0x292c0008,
+0x9980003d,
+0x32ec0001,
+0x96000004,
+0x2930000c,
+0x80000261,
+0xcc000042,
+0x04140010,
+0xcd400042,
+0x33300001,
+0x34280001,
+0x8400015e,
+0xc8140003,
+0x9b40001b,
+0x0438000c,
+0x8400015e,
+0xc8140003,
+0x9b400017,
+0x04380008,
+0x8400015e,
+0xc8140003,
+0x9b400013,
+0x04380004,
+0x8400015e,
+0xc8140003,
+0x9b400015,
+0xc80c03fd,
+0x9a800009,
+0xc81003fc,
+0x9b000118,
+0xcc00004d,
+0x04140010,
+0xccc00042,
+0xcd000042,
+0x80000136,
+0xcd400042,
+0x96c00111,
+0xcc00004d,
+0x80000261,
+0xcc00004e,
+0x9ac00003,
+0xcc00004d,
+0xcc00004e,
+0xdf830000,
+0x80000000,
+0xd80301ff,
+0x9ac00107,
+0xcc00004d,
+0x80000261,
+0xcc00004e,
+0xc8180003,
+0xc81c0003,
+0xc8200003,
+0x7d5d4003,
+0x7da1c003,
+0x7d5d400c,
+0x2a10001f,
+0x299c001f,
+0x7d1d000b,
+0x7d17400b,
+0x88000000,
+0x7e92800b,
+0x96400004,
+0xcc00004e,
+0x80000261,
+0xcc000042,
+0x04380008,
+0xcf800042,
+0xc8080003,
+0xc80c0003,
+0xc8100003,
+0xc8140003,
+0xc8180003,
+0xc81c0003,
+0xc8240003,
+0xc8280003,
+0x29fc001f,
+0x2ab0001f,
+0x7ff3c00b,
+0x28f0001f,
+0x7ff3c00b,
+0x2970001f,
+0x7ff3c00b,
+0x7d888001,
+0x7dccc001,
+0x7e510001,
+0x7e954001,
+0x7c908002,
+0x7cd4c002,
+0x7cbc800b,
+0x9ac00003,
+0x7c8f400b,
+0x38b40001,
+0x9b4000d8,
+0xcc00004d,
+0x9bc000d6,
+0xcc00004e,
+0xc80c03fd,
+0xc81003fc,
+0xccc00042,
+0x8000016f,
+0xcd000042,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xcc400040,
+0xcc400040,
+0xcc400040,
+0x7c40c000,
+0xccc00040,
+0xccc0000d,
+0x80000000,
+0xd0400040,
+0x7c40c000,
+0x7c410000,
+0x65140020,
+0x7d4d402c,
+0x24580002,
+0x7d598020,
+0x7c41c000,
+0xcd800042,
+0x69980020,
+0xcd800042,
+0xcdc00042,
+0xc023c000,
+0x05e40002,
+0x7ca0800b,
+0x26640010,
+0x7ca4800c,
+0xcc800040,
+0xcdc00040,
+0xccc00040,
+0x95c0000e,
+0xcd000040,
+0x09dc0001,
+0xc8280003,
+0x96800008,
+0xce800040,
+0xc834001d,
+0x97400000,
+0xc834001d,
+0x26a80008,
+0x84000264,
+0xcc2b0000,
+0x99c0fff7,
+0x09dc0001,
+0xdc3a0000,
+0x97800004,
+0x7c418000,
+0x800001a3,
+0x25980002,
+0xa0000000,
+0x7d808000,
+0xc818001d,
+0x7c40c000,
+0x64d00008,
+0x95800000,
+0xc818001d,
+0xcc130000,
+0xcc800040,
+0xccc00040,
+0x80000000,
+0xcc400040,
+0xc810001f,
+0x7c40c000,
+0xcc800040,
+0x7cd1400c,
+0xcd400040,
+0x05180001,
+0x80000000,
+0xcd800022,
+0x7c40c000,
+0x64500020,
+0x84000264,
+0xcc000061,
+0x7cd0c02c,
+0xc8200017,
+0xc8d60000,
+0x99400008,
+0x7c438000,
+0xdf830000,
+0xcfa0004f,
+0x84000264,
+0xcc000062,
+0x80000000,
+0xd040007f,
+0x80000261,
+0xcc000062,
+0x84000264,
+0xcc000061,
+0xc8200017,
+0x7c40c000,
+0xc036ff00,
+0xc810000d,
+0xc0303fff,
+0x7cf5400b,
+0x7d51800b,
+0x7d81800f,
+0x99800008,
+0x7cf3800b,
+0xdf830000,
+0xcfa0004f,
+0x84000264,
+0xcc000062,
+0x80000000,
+0xd040007f,
+0x80000261,
+0xcc000062,
+0x84000264,
+0x7c40c000,
+0x28dc0008,
+0x95c00019,
+0x30dc0010,
+0x7c410000,
+0x99c00004,
+0x64540020,
+0x80000209,
+0xc91d0000,
+0x7d15002c,
+0xc91e0000,
+0x7c420000,
+0x7c424000,
+0x7c418000,
+0x7de5c00b,
+0x7de28007,
+0x9a80000e,
+0x41ac0005,
+0x9ac00000,
+0x0aec0001,
+0x30dc0010,
+0x99c00004,
+0x00000000,
+0x8000020c,
+0xc91d0000,
+0x8000020c,
+0xc91e0000,
+0xcc800040,
+0xccc00040,
+0xd0400040,
+0xc80c0025,
+0x94c0fde3,
+0xc8100008,
+0xcd000040,
+0xd4000fc0,
+0x80000000,
+0xd4000fa2,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x7c40c000,
+0x30d00006,
+0x0d100006,
+0x99000007,
+0xc8140015,
+0x99400005,
+0xcc000052,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xccc00040,
+0x80000000,
+0xd0400040,
+0x7c40c000,
+0xcc4d0000,
+0xdc3a0000,
+0x9780fdbc,
+0x04cc0001,
+0x80000243,
+0xcc4d0000,
+0x7c40c000,
+0x7c410000,
+0x29240018,
+0x32640001,
+0x9640000f,
+0xcc800040,
+0x7c414000,
+0x7c418000,
+0x7c41c000,
+0xccc00043,
+0xcd000043,
+0x31dc7fff,
+0xcdc00043,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xcd800040,
+0x80000000,
+0xcdc00040,
+0xccc00040,
+0xcd000040,
+0x80000000,
+0xd0400040,
+0x80000000,
+0xd040007f,
+0xcc00007f,
+0x80000000,
+0xcc00007f,
+0xcc00007f,
+0x88000000,
+0xcc00007f,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00030223,
+0x0004022b,
+0x000500a0,
+0x00020003,
+0x0006003c,
+0x00070027,
+0x00080192,
+0x00090044,
+0x000a002d,
+0x0010025f,
+0x001700f1,
+0x002201d8,
+0x002301e9,
+0x0026004c,
+0x0027005f,
+0x0020011b,
+0x00280093,
+0x0029004f,
+0x002a0084,
+0x002b0065,
+0x002f008e,
+0x003200d9,
+0x00340233,
+0x00360075,
+0x0039010b,
+0x003c01fd,
+0x003f00a0,
+0x00410248,
+0x00440195,
+0x0048019e,
+0x004901c6,
+0x004a01d0,
+0x00550226,
+0x0056022e,
+0x0060000a,
+0x0061002a,
+0x00620030,
+0x00630030,
+0x00640030,
+0x00650030,
+0x00660030,
+0x00670030,
+0x00680037,
+0x0069003f,
+0x006a0047,
+0x006b0047,
+0x006c0047,
+0x006d0047,
+0x006e0047,
+0x006f0047,
+0x00700047,
+0x0073025f,
+0x007b0241,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+};
+
+static const u32 RV730_pfp_microcode[] = {
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x80000000,
+0xdc030000,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xc818000e,
+0x31980001,
+0x7c424000,
+0x9580023a,
+0x7c428000,
+0xc81c001c,
+0xc037c000,
+0x7c40c000,
+0x7c410000,
+0x7cb4800b,
+0xc0360003,
+0x99c00000,
+0xc81c001c,
+0x7cb4800c,
+0x24d40002,
+0x7d654000,
+0xcd400043,
+0xce800043,
+0xcd000043,
+0xcc800040,
+0xce400040,
+0xce800040,
+0xccc00040,
+0xdc3a0000,
+0x9780ffde,
+0xcd000040,
+0x7c40c000,
+0x80000018,
+0x7c410000,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xc818000e,
+0x8000000c,
+0x31980002,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xc818000e,
+0x288c0008,
+0x30cc000f,
+0x34100001,
+0x7d0d0008,
+0x8000000c,
+0x7d91800b,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xcc4003f9,
+0x80000249,
+0xcc4003f8,
+0xc037ffff,
+0x7c414000,
+0xcf41a29e,
+0xc82003f8,
+0xc81c03f9,
+0x66200020,
+0xc81803fb,
+0x7de1c02c,
+0x7d58c008,
+0x7cdcc020,
+0x69100020,
+0xc0360003,
+0xcc000054,
+0x7cb4800c,
+0x80000069,
+0xcc800040,
+0x7c418000,
+0xcd81a29e,
+0xcc800040,
+0x80000067,
+0xcd800040,
+0xc019ffff,
+0xcc800040,
+0xcd81a29e,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0xccc1a1fa,
+0xcd01a1f9,
+0xcd41a29d,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xcc400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xcc000054,
+0xcc800040,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0xccc1a1fa,
+0xcd01a1f9,
+0xcd41a29d,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x7c40c000,
+0x30d00001,
+0xccc1a29f,
+0x95000003,
+0x04140001,
+0x04140002,
+0xcd4003fb,
+0xcc800040,
+0x80000000,
+0xccc00040,
+0x7c40c000,
+0xcc800040,
+0xccc1a2a2,
+0x80000000,
+0xccc00040,
+0x7c40c000,
+0x28d4001f,
+0xcc800040,
+0x95400003,
+0x7c410000,
+0xccc00057,
+0x2918001f,
+0xccc00040,
+0x95800003,
+0xcd000040,
+0xcd000058,
+0x80000249,
+0xcc00007f,
+0xc8200017,
+0xc8300022,
+0x9a000006,
+0x0e280001,
+0xc824001e,
+0x0a640001,
+0xd4001240,
+0xce400040,
+0xc036c000,
+0x96800007,
+0x37747900,
+0x041c0001,
+0xcf400040,
+0xcdc00040,
+0xcf0003fa,
+0x7c030000,
+0xca0c0010,
+0x7c410000,
+0x94c00004,
+0x7c414000,
+0xd42002c4,
+0xcde00044,
+0x9b00000b,
+0x7c418000,
+0xcc00004b,
+0xcda00049,
+0xcd200041,
+0xcd600041,
+0xcda00041,
+0x06200001,
+0xce000056,
+0x80000249,
+0xcc00007f,
+0xc8280020,
+0xc82c0021,
+0xcc000063,
+0x7eea4001,
+0x65740020,
+0x7f53402c,
+0x269c0002,
+0x7df5c020,
+0x69f80020,
+0xce80004b,
+0xce600049,
+0xcde00041,
+0xcfa00041,
+0xce600041,
+0x271c0002,
+0x7df5c020,
+0x69f80020,
+0x7db24001,
+0xcf00004b,
+0xce600049,
+0xcde00041,
+0xcfa00041,
+0x800000bc,
+0xce600041,
+0xc8200017,
+0xc8300022,
+0x9a000006,
+0x0e280001,
+0xc824001e,
+0x0a640001,
+0xd4001240,
+0xce400040,
+0xca0c0010,
+0x7c410000,
+0x94c0000b,
+0xc036c000,
+0x96800007,
+0x37747900,
+0x041c0001,
+0xcf400040,
+0xcdc00040,
+0xcf0003fa,
+0x7c030000,
+0x800000b5,
+0x7c414000,
+0xcc000048,
+0x800000ee,
+0x00000000,
+0xc8200017,
+0xc81c0023,
+0x0e240002,
+0x99c00015,
+0x7c418000,
+0x0a200001,
+0xce000056,
+0xd4000440,
+0xcc000040,
+0xc036c000,
+0xca140013,
+0x96400007,
+0x37747900,
+0xcf400040,
+0xcc000040,
+0xc83003fa,
+0x80000103,
+0xcf000022,
+0xcc000022,
+0x95400146,
+0xcc00007f,
+0xcca00046,
+0x80000000,
+0xcc200046,
+0x80000249,
+0xcc000064,
+0xc8200017,
+0xc810001f,
+0x96000005,
+0x09100001,
+0xd4000440,
+0xcd000040,
+0xcd000022,
+0xcc800040,
+0xd0400040,
+0xc80c0025,
+0x94c0feec,
+0xc8100008,
+0xcd000040,
+0xd4000fc0,
+0x80000000,
+0xd4000fa2,
+0x7c40c000,
+0x7c410000,
+0xccc003fd,
+0xcd0003fc,
+0xccc00042,
+0xcd000042,
+0x2914001f,
+0x29180010,
+0x31980007,
+0x3b5c0001,
+0x7d76000b,
+0x99800005,
+0x7d5e400b,
+0xcc000042,
+0x80000249,
+0xcc00004d,
+0x29980001,
+0x292c0008,
+0x9980003d,
+0x32ec0001,
+0x96000004,
+0x2930000c,
+0x80000249,
+0xcc000042,
+0x04140010,
+0xcd400042,
+0x33300001,
+0x34280001,
+0x8400015d,
+0xc8140003,
+0x9b40001b,
+0x0438000c,
+0x8400015d,
+0xc8140003,
+0x9b400017,
+0x04380008,
+0x8400015d,
+0xc8140003,
+0x9b400013,
+0x04380004,
+0x8400015d,
+0xc8140003,
+0x9b400015,
+0xc80c03fd,
+0x9a800009,
+0xc81003fc,
+0x9b000101,
+0xcc00004d,
+0x04140010,
+0xccc00042,
+0xcd000042,
+0x80000135,
+0xcd400042,
+0x96c000fa,
+0xcc00004d,
+0x80000249,
+0xcc00004e,
+0x9ac00003,
+0xcc00004d,
+0xcc00004e,
+0xdf830000,
+0x80000000,
+0xd80301ff,
+0x9ac000f0,
+0xcc00004d,
+0x80000249,
+0xcc00004e,
+0xc8180003,
+0xc81c0003,
+0xc8200003,
+0x7d5d4003,
+0x7da1c003,
+0x7d5d400c,
+0x2a10001f,
+0x299c001f,
+0x7d1d000b,
+0x7d17400b,
+0x88000000,
+0x7e92800b,
+0x96400004,
+0xcc00004e,
+0x80000249,
+0xcc000042,
+0x04380008,
+0xcf800042,
+0xc8080003,
+0xc80c0003,
+0xc8100003,
+0xc8140003,
+0xc8180003,
+0xc81c0003,
+0xc8240003,
+0xc8280003,
+0x29fc001f,
+0x2ab0001f,
+0x7ff3c00b,
+0x28f0001f,
+0x7ff3c00b,
+0x2970001f,
+0x7ff3c00b,
+0x7d888001,
+0x7dccc001,
+0x7e510001,
+0x7e954001,
+0x7c908002,
+0x7cd4c002,
+0x7cbc800b,
+0x9ac00003,
+0x7c8f400b,
+0x38b40001,
+0x9b4000c1,
+0xcc00004d,
+0x9bc000bf,
+0xcc00004e,
+0xc80c03fd,
+0xc81003fc,
+0xccc00042,
+0x8000016e,
+0xcd000042,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xcc400040,
+0xcc400040,
+0xcc400040,
+0x7c40c000,
+0xccc00040,
+0xccc0000d,
+0x80000000,
+0xd0400040,
+0x7c40c000,
+0x7c410000,
+0x65140020,
+0x7d4d402c,
+0x24580002,
+0x7d598020,
+0x7c41c000,
+0xcd800042,
+0x69980020,
+0xcd800042,
+0xcdc00042,
+0xc023c000,
+0x05e40002,
+0x7ca0800b,
+0x26640010,
+0x7ca4800c,
+0xcc800040,
+0xcdc00040,
+0xccc00040,
+0x95c0000e,
+0xcd000040,
+0x09dc0001,
+0xc8280003,
+0x96800008,
+0xce800040,
+0xc834001d,
+0x97400000,
+0xc834001d,
+0x26a80008,
+0x8400024c,
+0xcc2b0000,
+0x99c0fff7,
+0x09dc0001,
+0xdc3a0000,
+0x97800004,
+0x7c418000,
+0x800001a2,
+0x25980002,
+0xa0000000,
+0x7d808000,
+0xc818001d,
+0x7c40c000,
+0x64d00008,
+0x95800000,
+0xc818001d,
+0xcc130000,
+0xcc800040,
+0xccc00040,
+0x80000000,
+0xcc400040,
+0xc810001f,
+0x7c40c000,
+0xcc800040,
+0x7cd1400c,
+0xcd400040,
+0x05180001,
+0x80000000,
+0xcd800022,
+0x7c40c000,
+0x64500020,
+0x8400024c,
+0xcc000061,
+0x7cd0c02c,
+0xc8200017,
+0xc8d60000,
+0x99400008,
+0x7c438000,
+0xdf830000,
+0xcfa0004f,
+0x8400024c,
+0xcc000062,
+0x80000000,
+0xd040007f,
+0x80000249,
+0xcc000062,
+0x8400024c,
+0xcc000061,
+0xc8200017,
+0x7c40c000,
+0xc036ff00,
+0xc810000d,
+0xc0303fff,
+0x7cf5400b,
+0x7d51800b,
+0x7d81800f,
+0x99800008,
+0x7cf3800b,
+0xdf830000,
+0xcfa0004f,
+0x8400024c,
+0xcc000062,
+0x80000000,
+0xd040007f,
+0x80000249,
+0xcc000062,
+0x8400024c,
+0x7c40c000,
+0x28dc0008,
+0x95c00019,
+0x30dc0010,
+0x7c410000,
+0x99c00004,
+0x64540020,
+0x80000208,
+0xc91d0000,
+0x7d15002c,
+0xc91e0000,
+0x7c420000,
+0x7c424000,
+0x7c418000,
+0x7de5c00b,
+0x7de28007,
+0x9a80000e,
+0x41ac0005,
+0x9ac00000,
+0x0aec0001,
+0x30dc0010,
+0x99c00004,
+0x00000000,
+0x8000020b,
+0xc91d0000,
+0x8000020b,
+0xc91e0000,
+0xcc800040,
+0xccc00040,
+0xd0400040,
+0xc80c0025,
+0x94c0fde4,
+0xc8100008,
+0xcd000040,
+0xd4000fc0,
+0x80000000,
+0xd4000fa2,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x7c40c000,
+0x30d00006,
+0x0d100006,
+0x99000007,
+0xc8140015,
+0x99400005,
+0xcc000052,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xccc00040,
+0x80000000,
+0xd0400040,
+0x7c40c000,
+0xcc4d0000,
+0xdc3a0000,
+0x9780fdbd,
+0x04cc0001,
+0x80000242,
+0xcc4d0000,
+0x80000000,
+0xd040007f,
+0xcc00007f,
+0x80000000,
+0xcc00007f,
+0xcc00007f,
+0x88000000,
+0xcc00007f,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00030222,
+0x0004022a,
+0x0005009f,
+0x00020003,
+0x0006003c,
+0x00070027,
+0x00080191,
+0x00090044,
+0x000a002d,
+0x00100247,
+0x001700f0,
+0x002201d7,
+0x002301e8,
+0x0026004c,
+0x0027005f,
+0x0020011a,
+0x00280092,
+0x0029004f,
+0x002a0083,
+0x002b0064,
+0x002f008d,
+0x003200d8,
+0x00340232,
+0x00360074,
+0x0039010a,
+0x003c01fc,
+0x003f009f,
+0x00410005,
+0x00440194,
+0x0048019d,
+0x004901c5,
+0x004a01cf,
+0x00550225,
+0x0056022d,
+0x0060000a,
+0x0061002a,
+0x00620030,
+0x00630030,
+0x00640030,
+0x00650030,
+0x00660030,
+0x00670030,
+0x00680037,
+0x0069003f,
+0x006a0047,
+0x006b0047,
+0x006c0047,
+0x006d0047,
+0x006e0047,
+0x006f0047,
+0x00700047,
+0x00730247,
+0x007b0240,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+};
+
+static const u32 RV730_cp_microcode[] = {
+0xcc0003ea,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x80000001,
+0xd040007f,
+0x80000001,
+0xcc400041,
+0x7c40c000,
+0xc0160004,
+0x30d03fff,
+0x7d15000c,
+0xcc110000,
+0x28d8001e,
+0x31980001,
+0x28dc001f,
+0xc8200004,
+0x95c00006,
+0x7c424000,
+0xcc000062,
+0x7e56800c,
+0xcc290000,
+0xc8240004,
+0x7e26000b,
+0x95800006,
+0x7c42c000,
+0xcc000062,
+0x7ed7000c,
+0xcc310000,
+0xc82c0004,
+0x7e2e000c,
+0xcc000062,
+0x31103fff,
+0x80000001,
+0xce110000,
+0x7c40c000,
+0x80000001,
+0xcc400040,
+0x80000001,
+0xcc412257,
+0x7c418000,
+0xcc400045,
+0xcc400048,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xcc400045,
+0xcc400048,
+0x7c40c000,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xcc000045,
+0xcc000048,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x040ca1fd,
+0xc0120001,
+0xcc000045,
+0xcc000048,
+0x7cd0c00c,
+0xcc41225c,
+0xcc41a1fc,
+0xd04d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x80000001,
+0xcc41225d,
+0x7c408000,
+0x7c40c000,
+0xc02a0002,
+0x7c410000,
+0x7d29000c,
+0x30940001,
+0x30980006,
+0x309c0300,
+0x29dc0008,
+0x7c420000,
+0x7c424000,
+0x9540000f,
+0xc02e0004,
+0x05f02258,
+0x7f2f000c,
+0xcc310000,
+0xc8280004,
+0xccc12169,
+0xcd01216a,
+0xce81216b,
+0x0db40002,
+0xcc01216c,
+0x9740000e,
+0x0db40000,
+0x8000007b,
+0xc834000a,
+0x0db40002,
+0x97400009,
+0x0db40000,
+0xc02e0004,
+0x05f02258,
+0x7f2f000c,
+0xcc310000,
+0xc8280004,
+0x8000007b,
+0xc834000a,
+0x97400004,
+0x7e028000,
+0x8000007b,
+0xc834000a,
+0x0db40004,
+0x9740ff8c,
+0x00000000,
+0xce01216d,
+0xce41216e,
+0xc8280003,
+0xc834000a,
+0x9b400004,
+0x043c0005,
+0x8400026b,
+0xcc000062,
+0x0df40000,
+0x9740000b,
+0xc82c03e6,
+0xce81a2b7,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c4,
+0x80000001,
+0xcfc1a2d1,
+0x0df40001,
+0x9740000b,
+0xc82c03e7,
+0xce81a2bb,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c5,
+0x80000001,
+0xcfc1a2d2,
+0x0df40002,
+0x9740000b,
+0xc82c03e8,
+0xce81a2bf,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c6,
+0x80000001,
+0xcfc1a2d3,
+0xc82c03e9,
+0xce81a2c3,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c7,
+0x80000001,
+0xcfc1a2d4,
+0x80000001,
+0xcc400042,
+0x7c40c000,
+0x7c410000,
+0x2914001d,
+0x31540001,
+0x9940000c,
+0x31181000,
+0xc81c0011,
+0x95c00000,
+0xc81c0011,
+0xccc12100,
+0xcd012101,
+0xccc12102,
+0xcd012103,
+0x04180004,
+0x8000037c,
+0xcd81a2a4,
+0xc02a0004,
+0x95800008,
+0x36a821a3,
+0xcc290000,
+0xc8280004,
+0xc81c0011,
+0x0de40040,
+0x9640ffff,
+0xc81c0011,
+0xccc12170,
+0xcd012171,
+0xc8200012,
+0x96000000,
+0xc8200012,
+0x8000037c,
+0xcc000064,
+0x7c40c000,
+0x7c410000,
+0xcc000045,
+0xcc000048,
+0x40d40003,
+0xcd41225c,
+0xcd01a1fc,
+0xc01a0001,
+0x041ca1fd,
+0x7dd9c00c,
+0x7c420000,
+0x08cc0001,
+0x06240001,
+0x06280002,
+0xce1d0000,
+0xce5d0000,
+0x98c0fffa,
+0xce9d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0x30d00001,
+0x28cc0001,
+0x7c414000,
+0x95000006,
+0x7c418000,
+0xcd41216d,
+0xcd81216e,
+0x800000f2,
+0xc81c0003,
+0xc0220004,
+0x7e16000c,
+0xcc210000,
+0xc81c0004,
+0x7c424000,
+0x98c00004,
+0x7c428000,
+0x80000001,
+0xcde50000,
+0xce412169,
+0xce81216a,
+0xcdc1216b,
+0x80000001,
+0xcc01216c,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0x7c41c000,
+0x28a40008,
+0x326400ff,
+0x0e68003c,
+0x9680000a,
+0x7c020000,
+0x7c420000,
+0x1e300003,
+0xcc00006a,
+0x9b000003,
+0x42200005,
+0x04200040,
+0x8000010f,
+0x7c024000,
+0x7e024000,
+0x9a400000,
+0x0a640001,
+0x30ec0010,
+0x9ac0000a,
+0xcc000062,
+0xc02a0004,
+0xc82c0021,
+0x7e92800c,
+0xcc000041,
+0xcc290000,
+0xcec00021,
+0x8000011f,
+0xc8300004,
+0xcd01216d,
+0xcd41216e,
+0xc8300003,
+0x7f1f000b,
+0x30f40007,
+0x27780001,
+0x9740002a,
+0x07b80124,
+0x9f800000,
+0x00000000,
+0x80000134,
+0x7f1b8004,
+0x80000138,
+0x7f1b8005,
+0x8000013c,
+0x7f1b8002,
+0x80000140,
+0x7f1b8003,
+0x80000144,
+0x7f1b8007,
+0x80000148,
+0x7f1b8006,
+0x8000014d,
+0x28a40008,
+0x9b800019,
+0x28a40008,
+0x8000015d,
+0x326400ff,
+0x9b800015,
+0x28a40008,
+0x8000015d,
+0x326400ff,
+0x9b800011,
+0x28a40008,
+0x8000015d,
+0x326400ff,
+0x9b80000d,
+0x28a40008,
+0x8000015d,
+0x326400ff,
+0x9b800009,
+0x28a40008,
+0x8000015d,
+0x326400ff,
+0x9b800005,
+0x28a40008,
+0x8000015d,
+0x326400ff,
+0x28a40008,
+0x326400ff,
+0x0e68003c,
+0x9a80feb2,
+0x28ec0008,
+0x7c434000,
+0x7c438000,
+0x7c43c000,
+0x96c00007,
+0xcc000062,
+0xcf412169,
+0xcf81216a,
+0xcfc1216b,
+0x80000001,
+0xcc01216c,
+0x80000001,
+0xcff50000,
+0xcc00006b,
+0x8400037f,
+0x0e68003c,
+0x9a800004,
+0xc8280015,
+0x80000001,
+0xd040007f,
+0x9680ffab,
+0x7e024000,
+0x84000239,
+0xc00e0002,
+0xcc000041,
+0x80000237,
+0xccc1304a,
+0x7c40c000,
+0x7c410000,
+0xc01e0001,
+0x29240012,
+0xc0220002,
+0x96400005,
+0xc0260004,
+0xc027fffb,
+0x7d25000b,
+0xc0260000,
+0x7dd2800b,
+0x7e12c00b,
+0x7d25000c,
+0x7c414000,
+0x7c418000,
+0xccc12169,
+0x9a80000a,
+0xcd01216a,
+0xcd41216b,
+0x96c0fe83,
+0xcd81216c,
+0xc8300018,
+0x97000000,
+0xc8300018,
+0x80000001,
+0xcc000018,
+0x8400037f,
+0xcc00007f,
+0xc8140013,
+0xc8180014,
+0xcd41216b,
+0x96c0fe77,
+0xcd81216c,
+0x80000181,
+0xc8300018,
+0xc80c0008,
+0x98c00000,
+0xc80c0008,
+0x7c410000,
+0x95000002,
+0x00000000,
+0x7c414000,
+0xc8200009,
+0xcc400043,
+0xce01a1f4,
+0xcc400044,
+0xc00e8000,
+0x7c424000,
+0x7c428000,
+0x2aac001f,
+0x96c0fe64,
+0xc035f000,
+0xce4003e2,
+0x32780003,
+0x267c0008,
+0x7ff7c00b,
+0x7ffbc00c,
+0x2a780018,
+0xcfc003e3,
+0xcf8003e4,
+0x26b00002,
+0x7f3f0000,
+0xcf0003e5,
+0x8000031d,
+0x7c80c000,
+0x7c40c000,
+0x28d00008,
+0x3110000f,
+0x9500000f,
+0x25280001,
+0x06a801b2,
+0x9e800000,
+0x00000000,
+0x800001d3,
+0xc0120800,
+0x800001e1,
+0xc814000f,
+0x800001e8,
+0xc8140010,
+0x800001ef,
+0xccc1a2a4,
+0x800001f8,
+0xc8140011,
+0x30d0003f,
+0x0d280015,
+0x9a800012,
+0x0d28001e,
+0x9a80001e,
+0x0d280020,
+0x9a800023,
+0x0d24000f,
+0x0d280010,
+0x7e6a800c,
+0x9a800026,
+0x0d200004,
+0x0d240014,
+0x0d280028,
+0x7e62400c,
+0x7ea6800c,
+0x9a80002a,
+0xc8140011,
+0x80000001,
+0xccc1a2a4,
+0xc0120800,
+0x7c414000,
+0x7d0cc00c,
+0xc0120008,
+0x29580003,
+0x295c000c,
+0x7c420000,
+0x7dd1c00b,
+0x26200014,
+0x7e1e400c,
+0x7e4e800c,
+0xce81a2a4,
+0x80000001,
+0xcd81a1fe,
+0xc814000f,
+0x0410210e,
+0x95400000,
+0xc814000f,
+0xd0510000,
+0x80000001,
+0xccc1a2a4,
+0xc8140010,
+0x04102108,
+0x95400000,
+0xc8140010,
+0xd0510000,
+0x80000001,
+0xccc1a2a4,
+0xccc1a2a4,
+0x04100001,
+0xcd000019,
+0x8400037f,
+0xcc00007f,
+0xc8100019,
+0x99000000,
+0xc8100019,
+0x80000002,
+0x7c408000,
+0x04102100,
+0x95400000,
+0xc8140011,
+0xd0510000,
+0x8000037c,
+0xccc1a2a4,
+0x7c40c000,
+0xcc40000d,
+0x94c0fe01,
+0xcc40000e,
+0x7c410000,
+0x95000005,
+0x08cc0001,
+0xc8140005,
+0x99400014,
+0x00000000,
+0x98c0fffb,
+0x7c410000,
+0x80000002,
+0x7d008000,
+0xc8140005,
+0x7c40c000,
+0x9940000c,
+0xc818000c,
+0x7c410000,
+0x9580fdf0,
+0xc820000e,
+0xc81c000d,
+0x66200020,
+0x7e1e002c,
+0x25240002,
+0x7e624020,
+0x80000001,
+0xcce60000,
+0x7c410000,
+0xcc00006c,
+0xcc00006d,
+0xc818001f,
+0xc81c001e,
+0x65980020,
+0x7dd9c02c,
+0x7cd4c00c,
+0xccde0000,
+0x45dc0004,
+0xc8280017,
+0x9680000f,
+0xc00e0001,
+0x28680008,
+0x2aac0016,
+0x32a800ff,
+0x0eb00049,
+0x7f2f000b,
+0x97000006,
+0x00000000,
+0xc8140005,
+0x7c40c000,
+0x80000221,
+0x7c410000,
+0x80000224,
+0xd040007f,
+0x84000239,
+0xcc000041,
+0xccc1304a,
+0x94000000,
+0xc83c001a,
+0x043c0005,
+0xcfc1a2a4,
+0xc0361f90,
+0xc0387fff,
+0x7c03c010,
+0x7f7b400c,
+0xcf41217c,
+0xcfc1217d,
+0xcc01217e,
+0xc03a0004,
+0x0434217f,
+0x7f7b400c,
+0xcc350000,
+0xc83c0004,
+0x2bfc001f,
+0x04380020,
+0x97c00005,
+0xcc000062,
+0x9b800000,
+0x0bb80001,
+0x80000245,
+0xcc000071,
+0xcc01a1f4,
+0x04380016,
+0xc0360002,
+0xcf81a2a4,
+0x88000000,
+0xcf412010,
+0x7c40c000,
+0x28d0001c,
+0x95000005,
+0x04d40001,
+0xcd400065,
+0x80000001,
+0xcd400068,
+0x09540002,
+0x80000001,
+0xcd400066,
+0x8400026a,
+0xc81803ea,
+0x7c40c000,
+0x9980fd9f,
+0xc8140016,
+0x08d00001,
+0x9940002b,
+0xcd000068,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x043c0005,
+0xcfc1a2a4,
+0xcc01a1f4,
+0x8400037f,
+0xcc000046,
+0x88000000,
+0xcc00007f,
+0x8400027c,
+0xc81803ea,
+0x7c40c000,
+0x9980fd8d,
+0xc8140016,
+0x08d00001,
+0x99400019,
+0xcd000068,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x043c0022,
+0xcfc1a2a4,
+0x8400037f,
+0xcc000047,
+0x88000000,
+0xcc00007f,
+0xc8100016,
+0x9900000d,
+0xcc400067,
+0x80000002,
+0x7c408000,
+0xc81803ea,
+0x9980fd79,
+0x7c40c000,
+0x94c00003,
+0xc8100016,
+0x99000004,
+0xccc00068,
+0x80000002,
+0x7c408000,
+0x84000239,
+0xc0148000,
+0xcc000041,
+0xcd41304a,
+0xc0148000,
+0x99000000,
+0xc8100016,
+0x80000002,
+0x7c408000,
+0xc0120001,
+0x7c51400c,
+0x80000001,
+0xd0550000,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0x291c001f,
+0xccc0004a,
+0xcd00004b,
+0x95c00003,
+0xc01c8000,
+0xcdc12010,
+0xdd830000,
+0x055c2000,
+0xcc000062,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc0004c,
+0xcd00004d,
+0xdd830000,
+0x055ca000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc0004e,
+0xcd00004f,
+0xdd830000,
+0x055cc000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00050,
+0xcd000051,
+0xdd830000,
+0x055cf8e0,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00052,
+0xcd000053,
+0xdd830000,
+0x055cf880,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00054,
+0xcd000055,
+0xdd830000,
+0x055ce000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00056,
+0xcd000057,
+0xdd830000,
+0x055cf000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00058,
+0xcd000059,
+0xdd830000,
+0x055cf3fc,
+0x80000001,
+0xd81f4100,
+0xd0432000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043a000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043c000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f8e0,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f880,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043e000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f3fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xc81403e0,
+0xcc430000,
+0xcc430000,
+0xcc430000,
+0x7d45c000,
+0xcdc30000,
+0xd0430000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0xc81003e2,
+0xc81403e5,
+0xc81803e3,
+0xc81c03e4,
+0xcd812169,
+0xcdc1216a,
+0xccc1216b,
+0xcc01216c,
+0x04200004,
+0x7da18000,
+0x7d964002,
+0x9640fcd9,
+0xcd8003e3,
+0x31280003,
+0xc02df000,
+0x25180008,
+0x7dad800b,
+0x7da9800c,
+0x80000001,
+0xcd8003e3,
+0x308cffff,
+0xd04d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xc8140020,
+0x15580002,
+0x9580ffff,
+0xc8140020,
+0xcc00006e,
+0xcc412180,
+0x7c40c000,
+0xccc1218d,
+0xcc412181,
+0x28d0001f,
+0x34588000,
+0xcd81218c,
+0x9500fcbf,
+0xcc412182,
+0xc8140020,
+0x9940ffff,
+0xc8140020,
+0x80000002,
+0x7c408000,
+0x7c40c000,
+0x28d00018,
+0x31100001,
+0xc0160080,
+0x95000003,
+0xc02a0004,
+0x7cd4c00c,
+0xccc1217c,
+0xcc41217d,
+0xcc41217e,
+0x7c418000,
+0x1db00003,
+0x36a0217f,
+0x9b000003,
+0x419c0005,
+0x041c0040,
+0x99c00000,
+0x09dc0001,
+0xcc210000,
+0xc8240004,
+0x2a6c001f,
+0x419c0005,
+0x9ac0fffa,
+0xcc800062,
+0x80000002,
+0x7c408000,
+0x7c40c000,
+0x04d403e6,
+0x80000001,
+0xcc540000,
+0x8000037c,
+0xcc4003ea,
+0xc01c8000,
+0x044ca000,
+0xcdc12010,
+0x7c410000,
+0xc8140009,
+0x04180000,
+0x041c0008,
+0xcd800071,
+0x09dc0001,
+0x05980001,
+0xcd0d0000,
+0x99c0fffc,
+0xcc800062,
+0x8000037c,
+0xcd400071,
+0xc00e0100,
+0xcc000041,
+0xccc1304a,
+0xc83c007f,
+0xcc00007f,
+0x80000001,
+0xcc00007f,
+0xcc00007f,
+0x88000000,
+0xcc00007f,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00010331,
+0x00100004,
+0x00170006,
+0x00210008,
+0x00270028,
+0x00280023,
+0x00290029,
+0x002a0026,
+0x002b0029,
+0x002d0038,
+0x002e003f,
+0x002f004a,
+0x0034004c,
+0x00360030,
+0x003900af,
+0x003a00cf,
+0x003b00e4,
+0x003c00fc,
+0x003d016b,
+0x003f00ad,
+0x00410336,
+0x00430349,
+0x0044018e,
+0x004500fc,
+0x004601ac,
+0x004701ac,
+0x004801fe,
+0x0049020c,
+0x004a0255,
+0x004b0282,
+0x0052025f,
+0x00530271,
+0x00540287,
+0x00570299,
+0x0060029d,
+0x006102ac,
+0x006202b6,
+0x006302c0,
+0x006402ca,
+0x006502d4,
+0x006602de,
+0x006702e8,
+0x006802f2,
+0x006902f6,
+0x006a02fa,
+0x006b02fe,
+0x006c0302,
+0x006d0306,
+0x006e030a,
+0x006f030e,
+0x00700312,
+0x00720363,
+0x00740369,
+0x00790367,
+0x007c031c,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+};
+
+static const u32 RV710_pfp_microcode[] = {
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x80000000,
+0xdc030000,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xc818000e,
+0x31980001,
+0x7c424000,
+0x9580023a,
+0x7c428000,
+0xc81c001c,
+0xc037c000,
+0x7c40c000,
+0x7c410000,
+0x7cb4800b,
+0xc0360003,
+0x99c00000,
+0xc81c001c,
+0x7cb4800c,
+0x24d40002,
+0x7d654000,
+0xcd400043,
+0xce800043,
+0xcd000043,
+0xcc800040,
+0xce400040,
+0xce800040,
+0xccc00040,
+0xdc3a0000,
+0x9780ffde,
+0xcd000040,
+0x7c40c000,
+0x80000018,
+0x7c410000,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xc818000e,
+0x8000000c,
+0x31980002,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xc818000e,
+0x288c0008,
+0x30cc000f,
+0x34100001,
+0x7d0d0008,
+0x8000000c,
+0x7d91800b,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xcc4003f9,
+0x80000249,
+0xcc4003f8,
+0xc037ffff,
+0x7c414000,
+0xcf41a29e,
+0xc82003f8,
+0xc81c03f9,
+0x66200020,
+0xc81803fb,
+0x7de1c02c,
+0x7d58c008,
+0x7cdcc020,
+0x69100020,
+0xc0360003,
+0xcc000054,
+0x7cb4800c,
+0x80000069,
+0xcc800040,
+0x7c418000,
+0xcd81a29e,
+0xcc800040,
+0x80000067,
+0xcd800040,
+0xc019ffff,
+0xcc800040,
+0xcd81a29e,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0xccc1a1fa,
+0xcd01a1f9,
+0xcd41a29d,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xcc400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xcc000054,
+0xcc800040,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0xccc1a1fa,
+0xcd01a1f9,
+0xcd41a29d,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x7c40c000,
+0x30d00001,
+0xccc1a29f,
+0x95000003,
+0x04140001,
+0x04140002,
+0xcd4003fb,
+0xcc800040,
+0x80000000,
+0xccc00040,
+0x7c40c000,
+0xcc800040,
+0xccc1a2a2,
+0x80000000,
+0xccc00040,
+0x7c40c000,
+0x28d4001f,
+0xcc800040,
+0x95400003,
+0x7c410000,
+0xccc00057,
+0x2918001f,
+0xccc00040,
+0x95800003,
+0xcd000040,
+0xcd000058,
+0x80000249,
+0xcc00007f,
+0xc8200017,
+0xc8300022,
+0x9a000006,
+0x0e280001,
+0xc824001e,
+0x0a640001,
+0xd4001240,
+0xce400040,
+0xc036c000,
+0x96800007,
+0x37747900,
+0x041c0001,
+0xcf400040,
+0xcdc00040,
+0xcf0003fa,
+0x7c030000,
+0xca0c0010,
+0x7c410000,
+0x94c00004,
+0x7c414000,
+0xd42002c4,
+0xcde00044,
+0x9b00000b,
+0x7c418000,
+0xcc00004b,
+0xcda00049,
+0xcd200041,
+0xcd600041,
+0xcda00041,
+0x06200001,
+0xce000056,
+0x80000249,
+0xcc00007f,
+0xc8280020,
+0xc82c0021,
+0xcc000063,
+0x7eea4001,
+0x65740020,
+0x7f53402c,
+0x269c0002,
+0x7df5c020,
+0x69f80020,
+0xce80004b,
+0xce600049,
+0xcde00041,
+0xcfa00041,
+0xce600041,
+0x271c0002,
+0x7df5c020,
+0x69f80020,
+0x7db24001,
+0xcf00004b,
+0xce600049,
+0xcde00041,
+0xcfa00041,
+0x800000bc,
+0xce600041,
+0xc8200017,
+0xc8300022,
+0x9a000006,
+0x0e280001,
+0xc824001e,
+0x0a640001,
+0xd4001240,
+0xce400040,
+0xca0c0010,
+0x7c410000,
+0x94c0000b,
+0xc036c000,
+0x96800007,
+0x37747900,
+0x041c0001,
+0xcf400040,
+0xcdc00040,
+0xcf0003fa,
+0x7c030000,
+0x800000b5,
+0x7c414000,
+0xcc000048,
+0x800000ee,
+0x00000000,
+0xc8200017,
+0xc81c0023,
+0x0e240002,
+0x99c00015,
+0x7c418000,
+0x0a200001,
+0xce000056,
+0xd4000440,
+0xcc000040,
+0xc036c000,
+0xca140013,
+0x96400007,
+0x37747900,
+0xcf400040,
+0xcc000040,
+0xc83003fa,
+0x80000103,
+0xcf000022,
+0xcc000022,
+0x95400146,
+0xcc00007f,
+0xcca00046,
+0x80000000,
+0xcc200046,
+0x80000249,
+0xcc000064,
+0xc8200017,
+0xc810001f,
+0x96000005,
+0x09100001,
+0xd4000440,
+0xcd000040,
+0xcd000022,
+0xcc800040,
+0xd0400040,
+0xc80c0025,
+0x94c0feec,
+0xc8100008,
+0xcd000040,
+0xd4000fc0,
+0x80000000,
+0xd4000fa2,
+0x7c40c000,
+0x7c410000,
+0xccc003fd,
+0xcd0003fc,
+0xccc00042,
+0xcd000042,
+0x2914001f,
+0x29180010,
+0x31980007,
+0x3b5c0001,
+0x7d76000b,
+0x99800005,
+0x7d5e400b,
+0xcc000042,
+0x80000249,
+0xcc00004d,
+0x29980001,
+0x292c0008,
+0x9980003d,
+0x32ec0001,
+0x96000004,
+0x2930000c,
+0x80000249,
+0xcc000042,
+0x04140010,
+0xcd400042,
+0x33300001,
+0x34280001,
+0x8400015d,
+0xc8140003,
+0x9b40001b,
+0x0438000c,
+0x8400015d,
+0xc8140003,
+0x9b400017,
+0x04380008,
+0x8400015d,
+0xc8140003,
+0x9b400013,
+0x04380004,
+0x8400015d,
+0xc8140003,
+0x9b400015,
+0xc80c03fd,
+0x9a800009,
+0xc81003fc,
+0x9b000101,
+0xcc00004d,
+0x04140010,
+0xccc00042,
+0xcd000042,
+0x80000135,
+0xcd400042,
+0x96c000fa,
+0xcc00004d,
+0x80000249,
+0xcc00004e,
+0x9ac00003,
+0xcc00004d,
+0xcc00004e,
+0xdf830000,
+0x80000000,
+0xd80301ff,
+0x9ac000f0,
+0xcc00004d,
+0x80000249,
+0xcc00004e,
+0xc8180003,
+0xc81c0003,
+0xc8200003,
+0x7d5d4003,
+0x7da1c003,
+0x7d5d400c,
+0x2a10001f,
+0x299c001f,
+0x7d1d000b,
+0x7d17400b,
+0x88000000,
+0x7e92800b,
+0x96400004,
+0xcc00004e,
+0x80000249,
+0xcc000042,
+0x04380008,
+0xcf800042,
+0xc8080003,
+0xc80c0003,
+0xc8100003,
+0xc8140003,
+0xc8180003,
+0xc81c0003,
+0xc8240003,
+0xc8280003,
+0x29fc001f,
+0x2ab0001f,
+0x7ff3c00b,
+0x28f0001f,
+0x7ff3c00b,
+0x2970001f,
+0x7ff3c00b,
+0x7d888001,
+0x7dccc001,
+0x7e510001,
+0x7e954001,
+0x7c908002,
+0x7cd4c002,
+0x7cbc800b,
+0x9ac00003,
+0x7c8f400b,
+0x38b40001,
+0x9b4000c1,
+0xcc00004d,
+0x9bc000bf,
+0xcc00004e,
+0xc80c03fd,
+0xc81003fc,
+0xccc00042,
+0x8000016e,
+0xcd000042,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xcc400040,
+0xcc400040,
+0xcc400040,
+0x7c40c000,
+0xccc00040,
+0xccc0000d,
+0x80000000,
+0xd0400040,
+0x7c40c000,
+0x7c410000,
+0x65140020,
+0x7d4d402c,
+0x24580002,
+0x7d598020,
+0x7c41c000,
+0xcd800042,
+0x69980020,
+0xcd800042,
+0xcdc00042,
+0xc023c000,
+0x05e40002,
+0x7ca0800b,
+0x26640010,
+0x7ca4800c,
+0xcc800040,
+0xcdc00040,
+0xccc00040,
+0x95c0000e,
+0xcd000040,
+0x09dc0001,
+0xc8280003,
+0x96800008,
+0xce800040,
+0xc834001d,
+0x97400000,
+0xc834001d,
+0x26a80008,
+0x8400024c,
+0xcc2b0000,
+0x99c0fff7,
+0x09dc0001,
+0xdc3a0000,
+0x97800004,
+0x7c418000,
+0x800001a2,
+0x25980002,
+0xa0000000,
+0x7d808000,
+0xc818001d,
+0x7c40c000,
+0x64d00008,
+0x95800000,
+0xc818001d,
+0xcc130000,
+0xcc800040,
+0xccc00040,
+0x80000000,
+0xcc400040,
+0xc810001f,
+0x7c40c000,
+0xcc800040,
+0x7cd1400c,
+0xcd400040,
+0x05180001,
+0x80000000,
+0xcd800022,
+0x7c40c000,
+0x64500020,
+0x8400024c,
+0xcc000061,
+0x7cd0c02c,
+0xc8200017,
+0xc8d60000,
+0x99400008,
+0x7c438000,
+0xdf830000,
+0xcfa0004f,
+0x8400024c,
+0xcc000062,
+0x80000000,
+0xd040007f,
+0x80000249,
+0xcc000062,
+0x8400024c,
+0xcc000061,
+0xc8200017,
+0x7c40c000,
+0xc036ff00,
+0xc810000d,
+0xc0303fff,
+0x7cf5400b,
+0x7d51800b,
+0x7d81800f,
+0x99800008,
+0x7cf3800b,
+0xdf830000,
+0xcfa0004f,
+0x8400024c,
+0xcc000062,
+0x80000000,
+0xd040007f,
+0x80000249,
+0xcc000062,
+0x8400024c,
+0x7c40c000,
+0x28dc0008,
+0x95c00019,
+0x30dc0010,
+0x7c410000,
+0x99c00004,
+0x64540020,
+0x80000208,
+0xc91d0000,
+0x7d15002c,
+0xc91e0000,
+0x7c420000,
+0x7c424000,
+0x7c418000,
+0x7de5c00b,
+0x7de28007,
+0x9a80000e,
+0x41ac0005,
+0x9ac00000,
+0x0aec0001,
+0x30dc0010,
+0x99c00004,
+0x00000000,
+0x8000020b,
+0xc91d0000,
+0x8000020b,
+0xc91e0000,
+0xcc800040,
+0xccc00040,
+0xd0400040,
+0xc80c0025,
+0x94c0fde4,
+0xc8100008,
+0xcd000040,
+0xd4000fc0,
+0x80000000,
+0xd4000fa2,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x7c40c000,
+0x30d00006,
+0x0d100006,
+0x99000007,
+0xc8140015,
+0x99400005,
+0xcc000052,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xccc00040,
+0x80000000,
+0xd0400040,
+0x7c40c000,
+0xcc4d0000,
+0xdc3a0000,
+0x9780fdbd,
+0x04cc0001,
+0x80000242,
+0xcc4d0000,
+0x80000000,
+0xd040007f,
+0xcc00007f,
+0x80000000,
+0xcc00007f,
+0xcc00007f,
+0x88000000,
+0xcc00007f,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00030222,
+0x0004022a,
+0x0005009f,
+0x00020003,
+0x0006003c,
+0x00070027,
+0x00080191,
+0x00090044,
+0x000a002d,
+0x00100247,
+0x001700f0,
+0x002201d7,
+0x002301e8,
+0x0026004c,
+0x0027005f,
+0x0020011a,
+0x00280092,
+0x0029004f,
+0x002a0083,
+0x002b0064,
+0x002f008d,
+0x003200d8,
+0x00340232,
+0x00360074,
+0x0039010a,
+0x003c01fc,
+0x003f009f,
+0x00410005,
+0x00440194,
+0x0048019d,
+0x004901c5,
+0x004a01cf,
+0x00550225,
+0x0056022d,
+0x0060000a,
+0x0061002a,
+0x00620030,
+0x00630030,
+0x00640030,
+0x00650030,
+0x00660030,
+0x00670030,
+0x00680037,
+0x0069003f,
+0x006a0047,
+0x006b0047,
+0x006c0047,
+0x006d0047,
+0x006e0047,
+0x006f0047,
+0x00700047,
+0x00730247,
+0x007b0240,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+};
+
+static const u32 RV710_cp_microcode[] = {
+0xcc0003ea,
+0x04080003,
+0xcc800043,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x80000003,
+0xd040007f,
+0x80000003,
+0xcc400041,
+0x7c40c000,
+0xc0160004,
+0x30d03fff,
+0x7d15000c,
+0xcc110000,
+0x28d8001e,
+0x31980001,
+0x28dc001f,
+0xc8200004,
+0x95c00006,
+0x7c424000,
+0xcc000062,
+0x7e56800c,
+0xcc290000,
+0xc8240004,
+0x7e26000b,
+0x95800006,
+0x7c42c000,
+0xcc000062,
+0x7ed7000c,
+0xcc310000,
+0xc82c0004,
+0x7e2e000c,
+0xcc000062,
+0x31103fff,
+0x80000003,
+0xce110000,
+0x7c40c000,
+0x80000003,
+0xcc400040,
+0x80000003,
+0xcc412257,
+0x7c418000,
+0xcc400045,
+0xcc400048,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xcc400045,
+0xcc400048,
+0x7c40c000,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xcc000045,
+0xcc000048,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x040ca1fd,
+0xc0120001,
+0xcc000045,
+0xcc000048,
+0x7cd0c00c,
+0xcc41225c,
+0xcc41a1fc,
+0xd04d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x80000003,
+0xcc41225d,
+0x7c408000,
+0x7c40c000,
+0xc02a0002,
+0x7c410000,
+0x7d29000c,
+0x30940001,
+0x30980006,
+0x309c0300,
+0x29dc0008,
+0x7c420000,
+0x7c424000,
+0x9540000f,
+0xc02e0004,
+0x05f02258,
+0x7f2f000c,
+0xcc310000,
+0xc8280004,
+0xccc12169,
+0xcd01216a,
+0xce81216b,
+0x0db40002,
+0xcc01216c,
+0x9740000e,
+0x0db40000,
+0x8000007d,
+0xc834000a,
+0x0db40002,
+0x97400009,
+0x0db40000,
+0xc02e0004,
+0x05f02258,
+0x7f2f000c,
+0xcc310000,
+0xc8280004,
+0x8000007d,
+0xc834000a,
+0x97400004,
+0x7e028000,
+0x8000007d,
+0xc834000a,
+0x0db40004,
+0x9740ff8c,
+0x00000000,
+0xce01216d,
+0xce41216e,
+0xc8280003,
+0xc834000a,
+0x9b400004,
+0x043c0005,
+0x8400026d,
+0xcc000062,
+0x0df40000,
+0x9740000b,
+0xc82c03e6,
+0xce81a2b7,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c4,
+0x80000003,
+0xcfc1a2d1,
+0x0df40001,
+0x9740000b,
+0xc82c03e7,
+0xce81a2bb,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c5,
+0x80000003,
+0xcfc1a2d2,
+0x0df40002,
+0x9740000b,
+0xc82c03e8,
+0xce81a2bf,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c6,
+0x80000003,
+0xcfc1a2d3,
+0xc82c03e9,
+0xce81a2c3,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c7,
+0x80000003,
+0xcfc1a2d4,
+0x80000003,
+0xcc400042,
+0x7c40c000,
+0x7c410000,
+0x2914001d,
+0x31540001,
+0x9940000c,
+0x31181000,
+0xc81c0011,
+0x95c00000,
+0xc81c0011,
+0xccc12100,
+0xcd012101,
+0xccc12102,
+0xcd012103,
+0x04180004,
+0x8000037e,
+0xcd81a2a4,
+0xc02a0004,
+0x95800008,
+0x36a821a3,
+0xcc290000,
+0xc8280004,
+0xc81c0011,
+0x0de40040,
+0x9640ffff,
+0xc81c0011,
+0xccc12170,
+0xcd012171,
+0xc8200012,
+0x96000000,
+0xc8200012,
+0x8000037e,
+0xcc000064,
+0x7c40c000,
+0x7c410000,
+0xcc000045,
+0xcc000048,
+0x40d40003,
+0xcd41225c,
+0xcd01a1fc,
+0xc01a0001,
+0x041ca1fd,
+0x7dd9c00c,
+0x7c420000,
+0x08cc0001,
+0x06240001,
+0x06280002,
+0xce1d0000,
+0xce5d0000,
+0x98c0fffa,
+0xce9d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0x30d00001,
+0x28cc0001,
+0x7c414000,
+0x95000006,
+0x7c418000,
+0xcd41216d,
+0xcd81216e,
+0x800000f4,
+0xc81c0003,
+0xc0220004,
+0x7e16000c,
+0xcc210000,
+0xc81c0004,
+0x7c424000,
+0x98c00004,
+0x7c428000,
+0x80000003,
+0xcde50000,
+0xce412169,
+0xce81216a,
+0xcdc1216b,
+0x80000003,
+0xcc01216c,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0x7c41c000,
+0x28a40008,
+0x326400ff,
+0x0e68003c,
+0x9680000a,
+0x7c020000,
+0x7c420000,
+0x1e300003,
+0xcc00006a,
+0x9b000003,
+0x42200005,
+0x04200040,
+0x80000111,
+0x7c024000,
+0x7e024000,
+0x9a400000,
+0x0a640001,
+0x30ec0010,
+0x9ac0000a,
+0xcc000062,
+0xc02a0004,
+0xc82c0021,
+0x7e92800c,
+0xcc000041,
+0xcc290000,
+0xcec00021,
+0x80000121,
+0xc8300004,
+0xcd01216d,
+0xcd41216e,
+0xc8300003,
+0x7f1f000b,
+0x30f40007,
+0x27780001,
+0x9740002a,
+0x07b80126,
+0x9f800000,
+0x00000000,
+0x80000136,
+0x7f1b8004,
+0x8000013a,
+0x7f1b8005,
+0x8000013e,
+0x7f1b8002,
+0x80000142,
+0x7f1b8003,
+0x80000146,
+0x7f1b8007,
+0x8000014a,
+0x7f1b8006,
+0x8000014f,
+0x28a40008,
+0x9b800019,
+0x28a40008,
+0x8000015f,
+0x326400ff,
+0x9b800015,
+0x28a40008,
+0x8000015f,
+0x326400ff,
+0x9b800011,
+0x28a40008,
+0x8000015f,
+0x326400ff,
+0x9b80000d,
+0x28a40008,
+0x8000015f,
+0x326400ff,
+0x9b800009,
+0x28a40008,
+0x8000015f,
+0x326400ff,
+0x9b800005,
+0x28a40008,
+0x8000015f,
+0x326400ff,
+0x28a40008,
+0x326400ff,
+0x0e68003c,
+0x9a80feb2,
+0x28ec0008,
+0x7c434000,
+0x7c438000,
+0x7c43c000,
+0x96c00007,
+0xcc000062,
+0xcf412169,
+0xcf81216a,
+0xcfc1216b,
+0x80000003,
+0xcc01216c,
+0x80000003,
+0xcff50000,
+0xcc00006b,
+0x84000381,
+0x0e68003c,
+0x9a800004,
+0xc8280015,
+0x80000003,
+0xd040007f,
+0x9680ffab,
+0x7e024000,
+0x8400023b,
+0xc00e0002,
+0xcc000041,
+0x80000239,
+0xccc1304a,
+0x7c40c000,
+0x7c410000,
+0xc01e0001,
+0x29240012,
+0xc0220002,
+0x96400005,
+0xc0260004,
+0xc027fffb,
+0x7d25000b,
+0xc0260000,
+0x7dd2800b,
+0x7e12c00b,
+0x7d25000c,
+0x7c414000,
+0x7c418000,
+0xccc12169,
+0x9a80000a,
+0xcd01216a,
+0xcd41216b,
+0x96c0fe83,
+0xcd81216c,
+0xc8300018,
+0x97000000,
+0xc8300018,
+0x80000003,
+0xcc000018,
+0x84000381,
+0xcc00007f,
+0xc8140013,
+0xc8180014,
+0xcd41216b,
+0x96c0fe77,
+0xcd81216c,
+0x80000183,
+0xc8300018,
+0xc80c0008,
+0x98c00000,
+0xc80c0008,
+0x7c410000,
+0x95000002,
+0x00000000,
+0x7c414000,
+0xc8200009,
+0xcc400043,
+0xce01a1f4,
+0xcc400044,
+0xc00e8000,
+0x7c424000,
+0x7c428000,
+0x2aac001f,
+0x96c0fe64,
+0xc035f000,
+0xce4003e2,
+0x32780003,
+0x267c0008,
+0x7ff7c00b,
+0x7ffbc00c,
+0x2a780018,
+0xcfc003e3,
+0xcf8003e4,
+0x26b00002,
+0x7f3f0000,
+0xcf0003e5,
+0x8000031f,
+0x7c80c000,
+0x7c40c000,
+0x28d00008,
+0x3110000f,
+0x9500000f,
+0x25280001,
+0x06a801b4,
+0x9e800000,
+0x00000000,
+0x800001d5,
+0xc0120800,
+0x800001e3,
+0xc814000f,
+0x800001ea,
+0xc8140010,
+0x800001f1,
+0xccc1a2a4,
+0x800001fa,
+0xc8140011,
+0x30d0003f,
+0x0d280015,
+0x9a800012,
+0x0d28001e,
+0x9a80001e,
+0x0d280020,
+0x9a800023,
+0x0d24000f,
+0x0d280010,
+0x7e6a800c,
+0x9a800026,
+0x0d200004,
+0x0d240014,
+0x0d280028,
+0x7e62400c,
+0x7ea6800c,
+0x9a80002a,
+0xc8140011,
+0x80000003,
+0xccc1a2a4,
+0xc0120800,
+0x7c414000,
+0x7d0cc00c,
+0xc0120008,
+0x29580003,
+0x295c000c,
+0x7c420000,
+0x7dd1c00b,
+0x26200014,
+0x7e1e400c,
+0x7e4e800c,
+0xce81a2a4,
+0x80000003,
+0xcd81a1fe,
+0xc814000f,
+0x0410210e,
+0x95400000,
+0xc814000f,
+0xd0510000,
+0x80000003,
+0xccc1a2a4,
+0xc8140010,
+0x04102108,
+0x95400000,
+0xc8140010,
+0xd0510000,
+0x80000003,
+0xccc1a2a4,
+0xccc1a2a4,
+0x04100001,
+0xcd000019,
+0x84000381,
+0xcc00007f,
+0xc8100019,
+0x99000000,
+0xc8100019,
+0x80000004,
+0x7c408000,
+0x04102100,
+0x95400000,
+0xc8140011,
+0xd0510000,
+0x8000037e,
+0xccc1a2a4,
+0x7c40c000,
+0xcc40000d,
+0x94c0fe01,
+0xcc40000e,
+0x7c410000,
+0x95000005,
+0x08cc0001,
+0xc8140005,
+0x99400014,
+0x00000000,
+0x98c0fffb,
+0x7c410000,
+0x80000004,
+0x7d008000,
+0xc8140005,
+0x7c40c000,
+0x9940000c,
+0xc818000c,
+0x7c410000,
+0x9580fdf0,
+0xc820000e,
+0xc81c000d,
+0x66200020,
+0x7e1e002c,
+0x25240002,
+0x7e624020,
+0x80000003,
+0xcce60000,
+0x7c410000,
+0xcc00006c,
+0xcc00006d,
+0xc818001f,
+0xc81c001e,
+0x65980020,
+0x7dd9c02c,
+0x7cd4c00c,
+0xccde0000,
+0x45dc0004,
+0xc8280017,
+0x9680000f,
+0xc00e0001,
+0x28680008,
+0x2aac0016,
+0x32a800ff,
+0x0eb00049,
+0x7f2f000b,
+0x97000006,
+0x00000000,
+0xc8140005,
+0x7c40c000,
+0x80000223,
+0x7c410000,
+0x80000226,
+0xd040007f,
+0x8400023b,
+0xcc000041,
+0xccc1304a,
+0x94000000,
+0xc83c001a,
+0x043c0005,
+0xcfc1a2a4,
+0xc0361f90,
+0xc0387fff,
+0x7c03c010,
+0x7f7b400c,
+0xcf41217c,
+0xcfc1217d,
+0xcc01217e,
+0xc03a0004,
+0x0434217f,
+0x7f7b400c,
+0xcc350000,
+0xc83c0004,
+0x2bfc001f,
+0x04380020,
+0x97c00005,
+0xcc000062,
+0x9b800000,
+0x0bb80001,
+0x80000247,
+0xcc000071,
+0xcc01a1f4,
+0x04380016,
+0xc0360002,
+0xcf81a2a4,
+0x88000000,
+0xcf412010,
+0x7c40c000,
+0x28d0001c,
+0x95000005,
+0x04d40001,
+0xcd400065,
+0x80000003,
+0xcd400068,
+0x09540002,
+0x80000003,
+0xcd400066,
+0x8400026c,
+0xc81803ea,
+0x7c40c000,
+0x9980fd9f,
+0xc8140016,
+0x08d00001,
+0x9940002b,
+0xcd000068,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x043c0005,
+0xcfc1a2a4,
+0xcc01a1f4,
+0x84000381,
+0xcc000046,
+0x88000000,
+0xcc00007f,
+0x8400027e,
+0xc81803ea,
+0x7c40c000,
+0x9980fd8d,
+0xc8140016,
+0x08d00001,
+0x99400019,
+0xcd000068,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x043c0022,
+0xcfc1a2a4,
+0x84000381,
+0xcc000047,
+0x88000000,
+0xcc00007f,
+0xc8100016,
+0x9900000d,
+0xcc400067,
+0x80000004,
+0x7c408000,
+0xc81803ea,
+0x9980fd79,
+0x7c40c000,
+0x94c00003,
+0xc8100016,
+0x99000004,
+0xccc00068,
+0x80000004,
+0x7c408000,
+0x8400023b,
+0xc0148000,
+0xcc000041,
+0xcd41304a,
+0xc0148000,
+0x99000000,
+0xc8100016,
+0x80000004,
+0x7c408000,
+0xc0120001,
+0x7c51400c,
+0x80000003,
+0xd0550000,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0x291c001f,
+0xccc0004a,
+0xcd00004b,
+0x95c00003,
+0xc01c8000,
+0xcdc12010,
+0xdd830000,
+0x055c2000,
+0xcc000062,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc0004c,
+0xcd00004d,
+0xdd830000,
+0x055ca000,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc0004e,
+0xcd00004f,
+0xdd830000,
+0x055cc000,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00050,
+0xcd000051,
+0xdd830000,
+0x055cf8e0,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00052,
+0xcd000053,
+0xdd830000,
+0x055cf880,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00054,
+0xcd000055,
+0xdd830000,
+0x055ce000,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00056,
+0xcd000057,
+0xdd830000,
+0x055cf000,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00058,
+0xcd000059,
+0xdd830000,
+0x055cf3fc,
+0x80000003,
+0xd81f4100,
+0xd0432000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043a000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043c000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f8e0,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f880,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043e000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f3fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xc81403e0,
+0xcc430000,
+0xcc430000,
+0xcc430000,
+0x7d45c000,
+0xcdc30000,
+0xd0430000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0xc81003e2,
+0xc81403e5,
+0xc81803e3,
+0xc81c03e4,
+0xcd812169,
+0xcdc1216a,
+0xccc1216b,
+0xcc01216c,
+0x04200004,
+0x7da18000,
+0x7d964002,
+0x9640fcd9,
+0xcd8003e3,
+0x31280003,
+0xc02df000,
+0x25180008,
+0x7dad800b,
+0x7da9800c,
+0x80000003,
+0xcd8003e3,
+0x308cffff,
+0xd04d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xc8140020,
+0x15580002,
+0x9580ffff,
+0xc8140020,
+0xcc00006e,
+0xcc412180,
+0x7c40c000,
+0xccc1218d,
+0xcc412181,
+0x28d0001f,
+0x34588000,
+0xcd81218c,
+0x9500fcbf,
+0xcc412182,
+0xc8140020,
+0x9940ffff,
+0xc8140020,
+0x80000004,
+0x7c408000,
+0x7c40c000,
+0x28d00018,
+0x31100001,
+0xc0160080,
+0x95000003,
+0xc02a0004,
+0x7cd4c00c,
+0xccc1217c,
+0xcc41217d,
+0xcc41217e,
+0x7c418000,
+0x1db00003,
+0x36a0217f,
+0x9b000003,
+0x419c0005,
+0x041c0040,
+0x99c00000,
+0x09dc0001,
+0xcc210000,
+0xc8240004,
+0x2a6c001f,
+0x419c0005,
+0x9ac0fffa,
+0xcc800062,
+0x80000004,
+0x7c408000,
+0x7c40c000,
+0x04d403e6,
+0x80000003,
+0xcc540000,
+0x8000037e,
+0xcc4003ea,
+0xc01c8000,
+0x044ca000,
+0xcdc12010,
+0x7c410000,
+0xc8140009,
+0x04180000,
+0x041c0008,
+0xcd800071,
+0x09dc0001,
+0x05980001,
+0xcd0d0000,
+0x99c0fffc,
+0xcc800062,
+0x8000037e,
+0xcd400071,
+0xc00e0100,
+0xcc000041,
+0xccc1304a,
+0xc83c007f,
+0xcc00007f,
+0x80000003,
+0xcc00007f,
+0xcc00007f,
+0x88000000,
+0xcc00007f,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00010333,
+0x00100006,
+0x00170008,
+0x0021000a,
+0x0027002a,
+0x00280025,
+0x0029002b,
+0x002a0028,
+0x002b002b,
+0x002d003a,
+0x002e0041,
+0x002f004c,
+0x0034004e,
+0x00360032,
+0x003900b1,
+0x003a00d1,
+0x003b00e6,
+0x003c00fe,
+0x003d016d,
+0x003f00af,
+0x00410338,
+0x0043034b,
+0x00440190,
+0x004500fe,
+0x004601ae,
+0x004701ae,
+0x00480200,
+0x0049020e,
+0x004a0257,
+0x004b0284,
+0x00520261,
+0x00530273,
+0x00540289,
+0x0057029b,
+0x0060029f,
+0x006102ae,
+0x006202b8,
+0x006302c2,
+0x006402cc,
+0x006502d6,
+0x006602e0,
+0x006702ea,
+0x006802f4,
+0x006902f8,
+0x006a02fc,
+0x006b0300,
+0x006c0304,
+0x006d0308,
+0x006e030c,
+0x006f0310,
+0x00700314,
+0x00720365,
+0x0074036b,
+0x00790369,
+0x007c031e,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+};
+
+#endif
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index 92965dbb3c14..77a7a4d84650 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -43,6 +43,78 @@
static int radeon_do_cleanup_cp(struct drm_device * dev);
static void radeon_do_cp_start(drm_radeon_private_t * dev_priv);
+u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off)
+{
+ u32 val;
+
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ val = DRM_READ32(dev_priv->ring_rptr, off);
+ } else {
+ val = *(((volatile u32 *)
+ dev_priv->ring_rptr->handle) +
+ (off / sizeof(u32)));
+ val = le32_to_cpu(val);
+ }
+ return val;
+}
+
+u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv)
+{
+ if (dev_priv->writeback_works)
+ return radeon_read_ring_rptr(dev_priv, 0);
+ else {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return RADEON_READ(R600_CP_RB_RPTR);
+ else
+ return RADEON_READ(RADEON_CP_RB_RPTR);
+ }
+}
+
+void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val)
+{
+ if (dev_priv->flags & RADEON_IS_AGP)
+ DRM_WRITE32(dev_priv->ring_rptr, off, val);
+ else
+ *(((volatile u32 *) dev_priv->ring_rptr->handle) +
+ (off / sizeof(u32))) = cpu_to_le32(val);
+}
+
+void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val)
+{
+ radeon_write_ring_rptr(dev_priv, 0, val);
+}
+
+u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index)
+{
+ if (dev_priv->writeback_works) {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return radeon_read_ring_rptr(dev_priv,
+ R600_SCRATCHOFF(index));
+ else
+ return radeon_read_ring_rptr(dev_priv,
+ RADEON_SCRATCHOFF(index));
+ } else {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return RADEON_READ(R600_SCRATCH_REG0 + 4*index);
+ else
+ return RADEON_READ(RADEON_SCRATCH_REG0 + 4*index);
+ }
+}
+
+u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr)
+{
+ u32 ret;
+
+ if (addr < 0x10000)
+ ret = DRM_READ32(dev_priv->mmio, addr);
+ else {
+ DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, addr);
+ ret = DRM_READ32(dev_priv->mmio, RADEON_MM_DATA);
+ }
+
+ return ret;
+}
+
static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
{
u32 ret;
@@ -70,11 +142,22 @@ static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
return ret;
}
+static u32 RS600_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+{
+ u32 ret;
+ RADEON_WRITE(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) |
+ RS600_MC_IND_CITF_ARB0));
+ ret = RADEON_READ(RS600_MC_DATA);
+ return ret;
+}
+
static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
{
if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
return RS690_READ_MCIND(dev_priv, addr);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ return RS600_READ_MCIND(dev_priv, addr);
else
return RS480_READ_MCIND(dev_priv, addr);
}
@@ -82,11 +165,17 @@ static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
{
- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+ return RADEON_READ(R700_MC_VM_FB_LOCATION);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return RADEON_READ(R600_MC_VM_FB_LOCATION);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ return RS600_READ_MCIND(dev_priv, RS600_MC_FB_LOCATION);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
else
@@ -95,42 +184,66 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
{
- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+ RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ RS600_WRITE_MCIND(RS600_MC_FB_LOCATION, fb_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
else
RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
}
-static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
+void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
{
- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ /*R6xx/R7xx: AGP_TOP and BOT are actually 18 bits each */
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) {
+ RADEON_WRITE(R700_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */
+ RADEON_WRITE(R700_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff);
+ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+ RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */
+ RADEON_WRITE(R600_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff);
+ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ RS600_WRITE_MCIND(RS600_MC_AGP_LOCATION, agp_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
else
RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc);
}
-static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
+void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
{
u32 agp_base_hi = upper_32_bits(agp_base);
u32 agp_base_lo = agp_base & 0xffffffff;
-
- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) {
+ u32 r6xx_agp_base = (agp_base >> 22) & 0x3ffff;
+
+ /* R6xx/R7xx must be aligned to a 4MB boundry */
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+ RADEON_WRITE(R700_MC_VM_AGP_BASE, r6xx_agp_base);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ RADEON_WRITE(R600_MC_VM_AGP_BASE, r6xx_agp_base);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) {
R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo);
R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi);
} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo);
RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi);
+ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
+ RS600_WRITE_MCIND(RS600_AGP_BASE, agp_base_lo);
+ RS600_WRITE_MCIND(RS600_AGP_BASE_2, agp_base_hi);
} else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) {
R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo);
R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi);
@@ -145,6 +258,25 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
}
}
+void radeon_enable_bm(struct drm_radeon_private *dev_priv)
+{
+ u32 tmp;
+ /* Turn on bus mastering */
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
+ /* rs600/rs690/rs740 */
+ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
+ RADEON_WRITE(RADEON_BUS_CNTL, tmp);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
+ /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
+ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
+ RADEON_WRITE(RADEON_BUS_CNTL, tmp);
+ } /* PCIE cards appears to not need this */
+}
+
static int RADEON_READ_PLL(struct drm_device * dev, int addr)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -302,7 +434,7 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
- RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1));
+ RADEON_WRITE(R300_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1));
}
RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config);
radeon_do_wait_for_idle(dev_priv);
@@ -382,6 +514,14 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
RS690_cp_microcode[i][0]);
}
+ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
+ DRM_INFO("Loading RS600 Microcode\n");
+ for (i = 0; i < 256; i++) {
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
+ RS600_cp_microcode[i][1]);
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
+ RS600_cp_microcode[i][0]);
+ }
} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) ||
@@ -562,7 +702,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
{
struct drm_radeon_master_private *master_priv;
u32 ring_start, cur_read_ptr;
- u32 tmp;
/* Initialize the memory controller. With new memory map, the fb location
* is not changed, it should have been properly initialized already. Part
@@ -611,17 +750,10 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
} else
#endif
{
- struct drm_sg_mem *entry = dev->sg;
- unsigned long tmp_ofs, page_ofs;
-
- tmp_ofs = dev_priv->ring_rptr->offset -
- (unsigned long)dev->sg->virtual;
- page_ofs = tmp_ofs >> PAGE_SHIFT;
-
- RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]);
- DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n",
- (unsigned long)entry->busaddr[page_ofs],
- entry->handle + tmp_ofs);
+ RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
+ dev_priv->ring_rptr->offset
+ - ((unsigned long) dev->sg->virtual)
+ + dev_priv->gart_vm_start);
}
/* Set ring buffer size */
@@ -649,34 +781,17 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR)
+ RADEON_SCRATCH_REG_OFFSET);
- dev_priv->scratch = ((__volatile__ u32 *)
- dev_priv->ring_rptr->handle +
- (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
-
RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
- /* Turn on bus mastering */
- if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
- /* rs600/rs690/rs740 */
- tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
- RADEON_WRITE(RADEON_BUS_CNTL, tmp);
- } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) ||
- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
- /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
- tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
- RADEON_WRITE(RADEON_BUS_CNTL, tmp);
- } /* PCIE cards appears to not need this */
+ radeon_enable_bm(dev_priv);
- dev_priv->scratch[0] = 0;
+ radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(0), 0);
RADEON_WRITE(RADEON_LAST_FRAME_REG, 0);
- dev_priv->scratch[1] = 0;
+ radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0);
RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0);
- dev_priv->scratch[2] = 0;
+ radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(2), 0);
RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0);
/* reset sarea copies of these */
@@ -708,12 +823,15 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
/* Writeback doesn't seem to work everywhere, test it here and possibly
* enable it if it appears to work
*/
- DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0);
+ radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0);
+
RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef);
for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
- if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) ==
- 0xdeadbeef)
+ u32 val;
+
+ val = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1));
+ if (val == 0xdeadbeef)
break;
DRM_UDELAY(1);
}
@@ -809,6 +927,82 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
}
}
+/* Enable or disable IGP GART on the chip */
+static void rs600_set_igpgart(drm_radeon_private_t *dev_priv, int on)
+{
+ u32 temp;
+ int i;
+
+ if (on) {
+ DRM_DEBUG("programming igp gart %08X %08lX %08X\n",
+ dev_priv->gart_vm_start,
+ (long)dev_priv->gart_info.bus_addr,
+ dev_priv->gart_size);
+
+ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) |
+ RS600_EFFECTIVE_L2_QUEUE_SIZE(6)));
+
+ for (i = 0; i < 19; i++)
+ IGP_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i,
+ (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE |
+ RS600_SYSTEM_ACCESS_MODE_IN_SYS |
+ RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH |
+ RS600_EFFECTIVE_L1_CACHE_SIZE(3) |
+ RS600_ENABLE_FRAGMENT_PROCESSING |
+ RS600_EFFECTIVE_L1_QUEUE_SIZE(3)));
+
+ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE |
+ RS600_PAGE_TABLE_TYPE_FLAT));
+
+ /* disable all other contexts */
+ for (i = 1; i < 8; i++)
+ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL + i, 0);
+
+ /* setup the page table aperture */
+ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR,
+ dev_priv->gart_info.bus_addr);
+ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR,
+ dev_priv->gart_vm_start);
+ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR,
+ (dev_priv->gart_vm_start + dev_priv->gart_size - 1));
+ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0);
+
+ /* setup the system aperture */
+ IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR,
+ dev_priv->gart_vm_start);
+ IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR,
+ (dev_priv->gart_vm_start + dev_priv->gart_size - 1));
+
+ /* enable page tables */
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT));
+
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1);
+ IGP_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES));
+
+ /* invalidate the cache */
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+
+ temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE);
+ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp);
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+
+ temp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE;
+ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp);
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+
+ temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE);
+ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp);
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+
+ } else {
+ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, 0);
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1);
+ temp &= ~RS600_ENABLE_PAGE_TABLES;
+ IGP_WRITE_MCIND(RS600_MC_CNTL1, temp);
+ }
+}
+
static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
@@ -850,6 +1044,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
return;
}
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
+ rs600_set_igpgart(dev_priv, on);
+ return;
+ }
+
if (dev_priv->flags & RADEON_IS_PCIE) {
radeon_set_pciegart(dev_priv, on);
return;
@@ -881,6 +1080,46 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
}
}
+static int radeon_setup_pcigart_surface(drm_radeon_private_t *dev_priv)
+{
+ struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info;
+ struct radeon_virt_surface *vp;
+ int i;
+
+ for (i = 0; i < RADEON_MAX_SURFACES * 2; i++) {
+ if (!dev_priv->virt_surfaces[i].file_priv ||
+ dev_priv->virt_surfaces[i].file_priv == PCIGART_FILE_PRIV)
+ break;
+ }
+ if (i >= 2 * RADEON_MAX_SURFACES)
+ return -ENOMEM;
+ vp = &dev_priv->virt_surfaces[i];
+
+ for (i = 0; i < RADEON_MAX_SURFACES; i++) {
+ struct radeon_surface *sp = &dev_priv->surfaces[i];
+ if (sp->refcount)
+ continue;
+
+ vp->surface_index = i;
+ vp->lower = gart_info->bus_addr;
+ vp->upper = vp->lower + gart_info->table_size;
+ vp->flags = 0;
+ vp->file_priv = PCIGART_FILE_PRIV;
+
+ sp->refcount = 1;
+ sp->lower = vp->lower;
+ sp->upper = vp->upper;
+ sp->flags = 0;
+
+ RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, sp->flags);
+ RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * i, sp->lower);
+ RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * i, sp->upper);
+ return 0;
+ }
+
+ return -ENOMEM;
+}
+
static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
struct drm_file *file_priv)
{
@@ -1062,11 +1301,12 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
} else
#endif
{
- dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
+ dev_priv->cp_ring->handle =
+ (void *)(unsigned long)dev_priv->cp_ring->offset;
dev_priv->ring_rptr->handle =
- (void *)dev_priv->ring_rptr->offset;
+ (void *)(unsigned long)dev_priv->ring_rptr->offset;
dev->agp_buffer_map->handle =
- (void *)dev->agp_buffer_map->offset;
+ (void *)(unsigned long)dev->agp_buffer_map->offset;
DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
dev_priv->cp_ring->handle);
@@ -1173,11 +1413,14 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
} else
#endif
{
+ u32 sctrl;
+ int ret;
+
dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
/* if we have an offset set from userspace */
if (dev_priv->pcigart_offset_set) {
dev_priv->gart_info.bus_addr =
- dev_priv->pcigart_offset + dev_priv->fb_location;
+ (resource_size_t)dev_priv->pcigart_offset + dev_priv->fb_location;
dev_priv->gart_info.mapping.offset =
dev_priv->pcigart_offset + dev_priv->fb_aper_offset;
dev_priv->gart_info.mapping.size =
@@ -1214,12 +1457,31 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
}
}
- if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
+ sctrl = RADEON_READ(RADEON_SURFACE_CNTL);
+ RADEON_WRITE(RADEON_SURFACE_CNTL, 0);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ ret = r600_page_table_init(dev);
+ else
+ ret = drm_ati_pcigart_init(dev, &dev_priv->gart_info);
+ RADEON_WRITE(RADEON_SURFACE_CNTL, sctrl);
+
+ if (!ret) {
DRM_ERROR("failed to init PCI GART!\n");
radeon_do_cleanup_cp(dev);
return -ENOMEM;
}
+ ret = radeon_setup_pcigart_surface(dev_priv);
+ if (ret) {
+ DRM_ERROR("failed to setup GART surface!\n");
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ r600_page_table_cleanup(dev, &dev_priv->gart_info);
+ else
+ drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info);
+ radeon_do_cleanup_cp(dev);
+ return ret;
+ }
+
/* Turn on PCI GART */
radeon_set_pcigart(dev_priv, 1);
}
@@ -1268,14 +1530,18 @@ static int radeon_do_cleanup_cp(struct drm_device * dev)
if (dev_priv->gart_info.bus_addr) {
/* Turn off PCI GART */
radeon_set_pcigart(dev_priv, 0);
- if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
- DRM_ERROR("failed to cleanup PCI GART!\n");
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ r600_page_table_cleanup(dev, &dev_priv->gart_info);
+ else {
+ if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
+ DRM_ERROR("failed to cleanup PCI GART!\n");
+ }
}
if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
{
drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
- dev_priv->gart_info.addr = 0;
+ dev_priv->gart_info.addr = NULL;
}
}
/* only clear to the start of flags */
@@ -1326,6 +1592,7 @@ static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_pri
int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_init_t *init = data;
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1338,8 +1605,13 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri
case RADEON_INIT_R200_CP:
case RADEON_INIT_R300_CP:
return radeon_do_init_cp(dev, init, file_priv);
+ case RADEON_INIT_R600_CP:
+ return r600_do_init_cp(dev, init, file_priv);
case RADEON_CLEANUP_CP:
- return radeon_do_cleanup_cp(dev);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return r600_do_cleanup_cp(dev);
+ else
+ return radeon_do_cleanup_cp(dev);
}
return -EINVAL;
@@ -1362,7 +1634,10 @@ int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_pr
return 0;
}
- radeon_do_cp_start(dev_priv);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ r600_do_cp_start(dev_priv);
+ else
+ radeon_do_cp_start(dev_priv);
return 0;
}
@@ -1393,7 +1668,10 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri
* code so that the DRM ioctl wrapper can try again.
*/
if (stop->idle) {
- ret = radeon_do_cp_idle(dev_priv);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ ret = r600_do_cp_idle(dev_priv);
+ else
+ ret = radeon_do_cp_idle(dev_priv);
if (ret)
return ret;
}
@@ -1402,10 +1680,16 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri
* we will get some dropped triangles as they won't be fully
* rendered before the CP is shut down.
*/
- radeon_do_cp_stop(dev_priv);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ r600_do_cp_stop(dev_priv);
+ else
+ radeon_do_cp_stop(dev_priv);
/* Reset the engine */
- radeon_do_engine_reset(dev);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ r600_do_engine_reset(dev);
+ else
+ radeon_do_engine_reset(dev);
return 0;
}
@@ -1418,29 +1702,47 @@ void radeon_do_release(struct drm_device * dev)
if (dev_priv) {
if (dev_priv->cp_running) {
/* Stop the cp */
- while ((ret = radeon_do_cp_idle(dev_priv)) != 0) {
- DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+ while ((ret = r600_do_cp_idle(dev_priv)) != 0) {
+ DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
+#ifdef __linux__
+ schedule();
+#else
+ tsleep(&ret, PZERO, "rdnrel", 1);
+#endif
+ }
+ } else {
+ while ((ret = radeon_do_cp_idle(dev_priv)) != 0) {
+ DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
#ifdef __linux__
- schedule();
+ schedule();
#else
- tsleep(&ret, PZERO, "rdnrel", 1);
+ tsleep(&ret, PZERO, "rdnrel", 1);
#endif
+ }
+ }
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+ r600_do_cp_stop(dev_priv);
+ r600_do_engine_reset(dev);
+ } else {
+ radeon_do_cp_stop(dev_priv);
+ radeon_do_engine_reset(dev);
}
- radeon_do_cp_stop(dev_priv);
- radeon_do_engine_reset(dev);
}
- /* Disable *all* interrupts */
- if (dev_priv->mmio) /* remove this after permanent addmaps */
- RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
-
- if (dev_priv->mmio) { /* remove all surfaces */
- for (i = 0; i < RADEON_MAX_SURFACES; i++) {
- RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0);
- RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND +
- 16 * i, 0);
- RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND +
- 16 * i, 0);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) {
+ /* Disable *all* interrupts */
+ if (dev_priv->mmio) /* remove this after permanent addmaps */
+ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
+
+ if (dev_priv->mmio) { /* remove all surfaces */
+ for (i = 0; i < RADEON_MAX_SURFACES; i++) {
+ RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0);
+ RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND +
+ 16 * i, 0);
+ RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND +
+ 16 * i, 0);
+ }
}
}
@@ -1449,7 +1751,10 @@ void radeon_do_release(struct drm_device * dev)
radeon_mem_takedown(&(dev_priv->fb_heap));
/* deallocate kernel resources */
- radeon_do_cleanup_cp(dev);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ r600_do_cleanup_cp(dev);
+ else
+ radeon_do_cleanup_cp(dev);
}
}
@@ -1467,7 +1772,10 @@ int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_pr
return -EINVAL;
}
- radeon_do_cp_reset(dev_priv);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ r600_do_cp_reset(dev_priv);
+ else
+ radeon_do_cp_reset(dev_priv);
/* The CP is no longer running after an engine reset */
dev_priv->cp_running = 0;
@@ -1482,23 +1790,36 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri
LOCK_TEST_WITH_RETURN(dev, file_priv);
- return radeon_do_cp_idle(dev_priv);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return r600_do_cp_idle(dev_priv);
+ else
+ return radeon_do_cp_idle(dev_priv);
}
/* Added by Charl P. Botha to call radeon_do_resume_cp().
*/
int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- return radeon_do_resume_cp(dev, file_priv);
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG("\n");
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return r600_do_resume_cp(dev, file_priv);
+ else
+ return radeon_do_resume_cp(dev, file_priv);
}
int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
- return radeon_do_engine_reset(dev);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return r600_do_engine_reset(dev);
+ else
+ return radeon_do_engine_reset(dev);
}
/* ================================================================
@@ -1548,7 +1869,7 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
start = dev_priv->last_buf;
for (t = 0; t < dev_priv->usec_timeout; t++) {
- u32 done_age = GET_SCRATCH(1);
+ u32 done_age = GET_SCRATCH(dev_priv, 1);
DRM_DEBUG("done_age = %d\n", done_age);
for (i = start; i < dma->buf_count; i++) {
buf = dma->buflist[i];
@@ -1582,8 +1903,9 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
struct drm_buf *buf;
int i, t;
int start;
- u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1));
+ u32 done_age;
+ done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1));
if (++dev_priv->last_buf >= dma->buf_count)
dev_priv->last_buf = 0;
@@ -1854,3 +2176,41 @@ int radeon_driver_unload(struct drm_device *dev)
dev->dev_private = NULL;
return 0;
}
+
+void radeon_commit_ring(drm_radeon_private_t *dev_priv)
+{
+ int i;
+ u32 *ring;
+ int tail_aligned;
+
+ /* check if the ring is padded out to 16-dword alignment */
+
+ tail_aligned = dev_priv->ring.tail & 0xf;
+ if (tail_aligned) {
+ int num_p2 = 16 - tail_aligned;
+
+ ring = dev_priv->ring.start;
+ /* pad with some CP_PACKET2 */
+ for (i = 0; i < num_p2; i++)
+ ring[dev_priv->ring.tail + i] = CP_PACKET2();
+
+ dev_priv->ring.tail += i;
+
+ dev_priv->ring.space -= num_p2 * sizeof(u32);
+ }
+
+ dev_priv->ring.tail &= dev_priv->ring.tail_mask;
+
+ DRM_MEMORYBARRIER();
+ GET_RING_HEAD( dev_priv );
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+ RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail);
+ /* read from PCI bus to ensure correct posting */
+ RADEON_READ(R600_CP_RB_RPTR);
+ } else {
+ RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail);
+ /* read from PCI bus to ensure correct posting */
+ RADEON_READ(RADEON_CP_RB_RPTR);
+ }
+}
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index fef207881f45..13a60f4d4227 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -41,23 +41,15 @@ int radeon_no_wb;
MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
module_param_named(no_wb, radeon_no_wb, int, 0444);
-static int dri_library_name(struct drm_device *dev, char *buf)
-{
- drm_radeon_private_t *dev_priv = dev->dev_private;
- int family = dev_priv->flags & RADEON_FAMILY_MASK;
-
- return snprintf(buf, PAGE_SIZE, "%s\n",
- (family < CHIP_R200) ? "radeon" :
- ((family < CHIP_R300) ? "r200" :
- "r300"));
-}
-
static int radeon_suspend(struct drm_device *dev, pm_message_t state)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return 0;
+
/* Disable *all* interrupts */
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
return 0;
@@ -67,8 +59,11 @@ static int radeon_resume(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return 0;
+
/* Restore interrupt registers */
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg);
RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
return 0;
@@ -95,7 +90,6 @@ static struct drm_driver driver = {
.get_vblank_counter = radeon_get_vblank_counter,
.enable_vblank = radeon_enable_vblank,
.disable_vblank = radeon_disable_vblank,
- .dri_library_name = dri_library_name,
.master_create = radeon_master_create,
.master_destroy = radeon_master_destroy,
.irq_preinstall = radeon_driver_irq_preinstall,
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index 490bc7ceef60..ed4d27e6ee6f 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -126,6 +126,7 @@ enum radeon_family {
CHIP_RV410,
CHIP_RS400,
CHIP_RS480,
+ CHIP_RS600,
CHIP_RS690,
CHIP_RS740,
CHIP_RV515,
@@ -134,6 +135,16 @@ enum radeon_family {
CHIP_RV560,
CHIP_RV570,
CHIP_R580,
+ CHIP_R600,
+ CHIP_RV610,
+ CHIP_RV630,
+ CHIP_RV620,
+ CHIP_RV635,
+ CHIP_RV670,
+ CHIP_RS780,
+ CHIP_RV770,
+ CHIP_RV730,
+ CHIP_RV710,
CHIP_LAST,
};
@@ -160,10 +171,6 @@ enum radeon_chip_flags {
RADEON_IS_IGPGART = 0x01000000UL,
};
-#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
- DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR))
-#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
-
typedef struct drm_radeon_freelist {
unsigned int age;
struct drm_buf *buf;
@@ -221,10 +228,11 @@ struct radeon_virt_surface {
u32 upper;
u32 flags;
struct drm_file *file_priv;
+#define PCIGART_FILE_PRIV ((void *) -1L)
};
-#define RADEON_FLUSH_EMITED (1 < 0)
-#define RADEON_PURGE_EMITED (1 < 1)
+#define RADEON_FLUSH_EMITED (1 << 0)
+#define RADEON_PURGE_EMITED (1 << 1)
struct drm_radeon_master_private {
drm_local_map_t *sarea;
@@ -248,7 +256,6 @@ typedef struct drm_radeon_private {
drm_radeon_freelist_t *head;
drm_radeon_freelist_t *tail;
int last_buf;
- volatile u32 *scratch;
int writeback_works;
int usec_timeout;
@@ -316,11 +323,31 @@ typedef struct drm_radeon_private {
/* starting from here on, data is preserved accross an open */
uint32_t flags; /* see radeon_chip_flags */
- unsigned long fb_aper_offset;
+ resource_size_t fb_aper_offset;
int num_gb_pipes;
int track_flush;
drm_local_map_t *mmio;
+
+ /* r6xx/r7xx pipe/shader config */
+ int r600_max_pipes;
+ int r600_max_tile_pipes;
+ int r600_max_simds;
+ int r600_max_backends;
+ int r600_max_gprs;
+ int r600_max_threads;
+ int r600_max_stack_entries;
+ int r600_max_hw_contexts;
+ int r600_max_gs_threads;
+ int r600_sx_max_export_size;
+ int r600_sx_max_export_pos_size;
+ int r600_sx_max_export_smx_size;
+ int r600_sq_num_cf_insts;
+ int r700_sx_num_of_sets;
+ int r700_sc_prim_fifo_size;
+ int r700_sc_hiz_tile_fifo_size;
+ int r700_sc_earlyz_tile_fifo_fize;
+
} drm_radeon_private_t;
typedef struct drm_radeon_buf_priv {
@@ -338,6 +365,12 @@ extern int radeon_no_wb;
extern struct drm_ioctl_desc radeon_ioctls[];
extern int radeon_max_ioctl;
+extern u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv);
+extern void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val);
+
+#define GET_RING_HEAD(dev_priv) radeon_get_ring_head(dev_priv)
+#define SET_RING_HEAD(dev_priv, val) radeon_set_ring_head(dev_priv, val)
+
/* Check whether the given hardware address is inside the framebuffer or the
* GART area.
*/
@@ -364,6 +397,9 @@ extern int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_fi
extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv);
+extern void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc);
+extern void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base);
+extern u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr);
extern void radeon_freelist_reset(struct drm_device * dev);
extern struct drm_buf *radeon_freelist_get(struct drm_device * dev);
@@ -383,6 +419,10 @@ extern void radeon_mem_takedown(struct mem_block **heap);
extern void radeon_mem_release(struct drm_file *file_priv,
struct mem_block *heap);
+extern void radeon_enable_bm(struct drm_radeon_private *dev_priv);
+extern u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off);
+extern void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val);
+
/* radeon_irq.c */
extern void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state);
extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv);
@@ -423,6 +463,21 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
struct drm_file *file_priv,
drm_radeon_kcmd_buffer_t *cmdbuf);
+/* r600_cp.c */
+extern int r600_do_engine_reset(struct drm_device *dev);
+extern int r600_do_cleanup_cp(struct drm_device *dev);
+extern int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
+ struct drm_file *file_priv);
+extern int r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv);
+extern int r600_do_cp_idle(drm_radeon_private_t *dev_priv);
+extern void r600_do_cp_start(drm_radeon_private_t *dev_priv);
+extern void r600_do_cp_reset(drm_radeon_private_t *dev_priv);
+extern void r600_do_cp_stop(drm_radeon_private_t *dev_priv);
+extern int r600_cp_dispatch_indirect(struct drm_device *dev,
+ struct drm_buf *buf, int start, int end);
+extern int r600_page_table_init(struct drm_device *dev);
+extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info);
+
/* Flags for stats.boxes
*/
#define RADEON_BOX_DMA_IDLE 0x1
@@ -434,6 +489,8 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
/* Register definitions, register access macros and drmAddMap constants
* for Radeon kernel driver.
*/
+#define RADEON_MM_INDEX 0x0000
+#define RADEON_MM_DATA 0x0004
#define RADEON_AGP_COMMAND 0x0f60
#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */
@@ -556,6 +613,56 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RS690_MC_AGP_BASE 0x102
#define RS690_MC_AGP_BASE_2 0x103
+#define RS600_MC_INDEX 0x70
+# define RS600_MC_ADDR_MASK 0xffff
+# define RS600_MC_IND_SEQ_RBS_0 (1 << 16)
+# define RS600_MC_IND_SEQ_RBS_1 (1 << 17)
+# define RS600_MC_IND_SEQ_RBS_2 (1 << 18)
+# define RS600_MC_IND_SEQ_RBS_3 (1 << 19)
+# define RS600_MC_IND_AIC_RBS (1 << 20)
+# define RS600_MC_IND_CITF_ARB0 (1 << 21)
+# define RS600_MC_IND_CITF_ARB1 (1 << 22)
+# define RS600_MC_IND_WR_EN (1 << 23)
+#define RS600_MC_DATA 0x74
+
+#define RS600_MC_STATUS 0x0
+# define RS600_MC_IDLE (1 << 1)
+#define RS600_MC_FB_LOCATION 0x4
+#define RS600_MC_AGP_LOCATION 0x5
+#define RS600_AGP_BASE 0x6
+#define RS600_AGP_BASE_2 0x7
+#define RS600_MC_CNTL1 0x9
+# define RS600_ENABLE_PAGE_TABLES (1 << 26)
+#define RS600_MC_PT0_CNTL 0x100
+# define RS600_ENABLE_PT (1 << 0)
+# define RS600_EFFECTIVE_L2_CACHE_SIZE(x) ((x) << 15)
+# define RS600_EFFECTIVE_L2_QUEUE_SIZE(x) ((x) << 21)
+# define RS600_INVALIDATE_ALL_L1_TLBS (1 << 28)
+# define RS600_INVALIDATE_L2_CACHE (1 << 29)
+#define RS600_MC_PT0_CONTEXT0_CNTL 0x102
+# define RS600_ENABLE_PAGE_TABLE (1 << 0)
+# define RS600_PAGE_TABLE_TYPE_FLAT (0 << 1)
+#define RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR 0x112
+#define RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR 0x114
+#define RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR 0x11c
+#define RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR 0x12c
+#define RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR 0x13c
+#define RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR 0x14c
+#define RS600_MC_PT0_CLIENT0_CNTL 0x16c
+# define RS600_ENABLE_TRANSLATION_MODE_OVERRIDE (1 << 0)
+# define RS600_TRANSLATION_MODE_OVERRIDE (1 << 1)
+# define RS600_SYSTEM_ACCESS_MODE_MASK (3 << 8)
+# define RS600_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 8)
+# define RS600_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 8)
+# define RS600_SYSTEM_ACCESS_MODE_IN_SYS (2 << 8)
+# define RS600_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 8)
+# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH (0 << 10)
+# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 10)
+# define RS600_EFFECTIVE_L1_CACHE_SIZE(x) ((x) << 11)
+# define RS600_ENABLE_FRAGMENT_PROCESSING (1 << 14)
+# define RS600_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15)
+# define RS600_INVALIDATE_L1_TLB (1 << 20)
+
#define R520_MC_IND_INDEX 0x70
#define R520_MC_IND_WR_EN (1 << 24)
#define R520_MC_IND_DATA 0x74
@@ -580,7 +687,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
/* pipe config regs */
#define R400_GB_PIPE_SELECT 0x402c
#define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */
-#define R500_SU_REG_DEST 0x42c8
#define R300_GB_TILE_CONFIG 0x4018
# define R300_ENABLE_TILING (1 << 0)
# define R300_PIPE_COUNT_RV350 (0 << 1)
@@ -639,9 +745,22 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x))
-#define GET_SCRATCH( x ) (dev_priv->writeback_works \
- ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
- : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
+extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
+
+#define GET_SCRATCH(dev_priv, x) radeon_get_scratch(dev_priv, x)
+
+#define R600_SCRATCH_REG0 0x8500
+#define R600_SCRATCH_REG1 0x8504
+#define R600_SCRATCH_REG2 0x8508
+#define R600_SCRATCH_REG3 0x850c
+#define R600_SCRATCH_REG4 0x8510
+#define R600_SCRATCH_REG5 0x8514
+#define R600_SCRATCH_REG6 0x8518
+#define R600_SCRATCH_REG7 0x851c
+#define R600_SCRATCH_UMSK 0x8540
+#define R600_SCRATCH_ADDR 0x8544
+
+#define R600_SCRATCHOFF(x) (R600_SCRATCH_REG_OFFSET + 4*(x))
#define RADEON_GEN_INT_CNTL 0x0040
# define RADEON_CRTC_VBLANK_MASK (1 << 0)
@@ -922,6 +1041,7 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_CP_RB_CNTL 0x0704
# define RADEON_BUF_SWAP_32BIT (2 << 16)
# define RADEON_RB_NO_UPDATE (1 << 27)
+# define RADEON_RB_RPTR_WR_ENA (1 << 31)
#define RADEON_CP_RB_RPTR_ADDR 0x070c
#define RADEON_CP_RB_RPTR 0x0710
#define RADEON_CP_RB_WPTR 0x0714
@@ -983,6 +1103,14 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
# define RADEON_CNTL_BITBLT_MULTI 0x00009B00
# define RADEON_CNTL_SET_SCISSORS 0xC0001E00
+# define R600_IT_INDIRECT_BUFFER 0x00003200
+# define R600_IT_ME_INITIALIZE 0x00004400
+# define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16)
+# define R600_IT_EVENT_WRITE 0x00004600
+# define R600_IT_SET_CONFIG_REG 0x00006800
+# define R600_SET_CONFIG_REG_OFFSET 0x00008000
+# define R600_SET_CONFIG_REG_END 0x0000ac00
+
#define RADEON_CP_PACKET_MASK 0xC0000000
#define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000
#define RADEON_CP_PACKET0_REG_MASK 0x000007ff
@@ -1181,6 +1309,422 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define R500_D1_VBLANK_INTERRUPT (1 << 4)
#define R500_D2_VBLANK_INTERRUPT (1 << 5)
+/* R6xx/R7xx registers */
+#define R600_MC_VM_FB_LOCATION 0x2180
+#define R600_MC_VM_AGP_TOP 0x2184
+#define R600_MC_VM_AGP_BOT 0x2188
+#define R600_MC_VM_AGP_BASE 0x218c
+#define R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2190
+#define R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2194
+#define R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x2198
+
+#define R700_MC_VM_FB_LOCATION 0x2024
+#define R700_MC_VM_AGP_TOP 0x2028
+#define R700_MC_VM_AGP_BOT 0x202c
+#define R700_MC_VM_AGP_BASE 0x2030
+#define R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034
+#define R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038
+#define R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203c
+
+#define R600_MCD_RD_A_CNTL 0x219c
+#define R600_MCD_RD_B_CNTL 0x21a0
+
+#define R600_MCD_WR_A_CNTL 0x21a4
+#define R600_MCD_WR_B_CNTL 0x21a8
+
+#define R600_MCD_RD_SYS_CNTL 0x2200
+#define R600_MCD_WR_SYS_CNTL 0x2214
+
+#define R600_MCD_RD_GFX_CNTL 0x21fc
+#define R600_MCD_RD_HDP_CNTL 0x2204
+#define R600_MCD_RD_PDMA_CNTL 0x2208
+#define R600_MCD_RD_SEM_CNTL 0x220c
+#define R600_MCD_WR_GFX_CNTL 0x2210
+#define R600_MCD_WR_HDP_CNTL 0x2218
+#define R600_MCD_WR_PDMA_CNTL 0x221c
+#define R600_MCD_WR_SEM_CNTL 0x2220
+
+# define R600_MCD_L1_TLB (1 << 0)
+# define R600_MCD_L1_FRAG_PROC (1 << 1)
+# define R600_MCD_L1_STRICT_ORDERING (1 << 2)
+
+# define R600_MCD_SYSTEM_ACCESS_MODE_MASK (3 << 6)
+# define R600_MCD_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 6)
+# define R600_MCD_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 6)
+# define R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS (2 << 6)
+# define R600_MCD_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 6)
+
+# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 8)
+# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 8)
+
+# define R600_MCD_SEMAPHORE_MODE (1 << 10)
+# define R600_MCD_WAIT_L2_QUERY (1 << 11)
+# define R600_MCD_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 12)
+# define R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15)
+
+#define R700_MC_VM_MD_L1_TLB0_CNTL 0x2654
+#define R700_MC_VM_MD_L1_TLB1_CNTL 0x2658
+#define R700_MC_VM_MD_L1_TLB2_CNTL 0x265c
+
+#define R700_MC_VM_MB_L1_TLB0_CNTL 0x2234
+#define R700_MC_VM_MB_L1_TLB1_CNTL 0x2238
+#define R700_MC_VM_MB_L1_TLB2_CNTL 0x223c
+#define R700_MC_VM_MB_L1_TLB3_CNTL 0x2240
+
+# define R700_ENABLE_L1_TLB (1 << 0)
+# define R700_ENABLE_L1_FRAGMENT_PROCESSING (1 << 1)
+# define R700_SYSTEM_ACCESS_MODE_IN_SYS (2 << 3)
+# define R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5)
+# define R700_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 15)
+# define R700_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 18)
+
+#define R700_MC_ARB_RAMCFG 0x2760
+# define R700_NOOFBANK_SHIFT 0
+# define R700_NOOFBANK_MASK 0x3
+# define R700_NOOFRANK_SHIFT 2
+# define R700_NOOFRANK_MASK 0x1
+# define R700_NOOFROWS_SHIFT 3
+# define R700_NOOFROWS_MASK 0x7
+# define R700_NOOFCOLS_SHIFT 6
+# define R700_NOOFCOLS_MASK 0x3
+# define R700_CHANSIZE_SHIFT 8
+# define R700_CHANSIZE_MASK 0x1
+# define R700_BURSTLENGTH_SHIFT 9
+# define R700_BURSTLENGTH_MASK 0x1
+#define R600_RAMCFG 0x2408
+# define R600_NOOFBANK_SHIFT 0
+# define R600_NOOFBANK_MASK 0x1
+# define R600_NOOFRANK_SHIFT 1
+# define R600_NOOFRANK_MASK 0x1
+# define R600_NOOFROWS_SHIFT 2
+# define R600_NOOFROWS_MASK 0x7
+# define R600_NOOFCOLS_SHIFT 5
+# define R600_NOOFCOLS_MASK 0x3
+# define R600_CHANSIZE_SHIFT 7
+# define R600_CHANSIZE_MASK 0x1
+# define R600_BURSTLENGTH_SHIFT 8
+# define R600_BURSTLENGTH_MASK 0x1
+
+#define R600_VM_L2_CNTL 0x1400
+# define R600_VM_L2_CACHE_EN (1 << 0)
+# define R600_VM_L2_FRAG_PROC (1 << 1)
+# define R600_VM_ENABLE_PTE_CACHE_LRU_W (1 << 9)
+# define R600_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 13)
+# define R700_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 14)
+
+#define R600_VM_L2_CNTL2 0x1404
+# define R600_VM_L2_CNTL2_INVALIDATE_ALL_L1_TLBS (1 << 0)
+# define R600_VM_L2_CNTL2_INVALIDATE_L2_CACHE (1 << 1)
+#define R600_VM_L2_CNTL3 0x1408
+# define R600_VM_L2_CNTL3_BANK_SELECT_0(x) ((x) << 0)
+# define R600_VM_L2_CNTL3_BANK_SELECT_1(x) ((x) << 5)
+# define R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 10)
+# define R700_VM_L2_CNTL3_BANK_SELECT(x) ((x) << 0)
+# define R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 6)
+
+#define R600_VM_L2_STATUS 0x140c
+
+#define R600_VM_CONTEXT0_CNTL 0x1410
+# define R600_VM_ENABLE_CONTEXT (1 << 0)
+# define R600_VM_PAGE_TABLE_DEPTH_FLAT (0 << 1)
+
+#define R600_VM_CONTEXT0_CNTL2 0x1430
+#define R600_VM_CONTEXT0_REQUEST_RESPONSE 0x1470
+#define R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR 0x1490
+#define R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR 0x14b0
+#define R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x1574
+#define R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x1594
+#define R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x15b4
+
+#define R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153c
+#define R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155c
+#define R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157c
+
+#define R600_HDP_HOST_PATH_CNTL 0x2c00
+
+#define R600_GRBM_CNTL 0x8000
+# define R600_GRBM_READ_TIMEOUT(x) ((x) << 0)
+
+#define R600_GRBM_STATUS 0x8010
+# define R600_CMDFIFO_AVAIL_MASK 0x1f
+# define R700_CMDFIFO_AVAIL_MASK 0xf
+# define R600_GUI_ACTIVE (1 << 31)
+#define R600_GRBM_STATUS2 0x8014
+#define R600_GRBM_SOFT_RESET 0x8020
+# define R600_SOFT_RESET_CP (1 << 0)
+#define R600_WAIT_UNTIL 0x8040
+
+#define R600_CP_SEM_WAIT_TIMER 0x85bc
+#define R600_CP_ME_CNTL 0x86d8
+# define R600_CP_ME_HALT (1 << 28)
+#define R600_CP_QUEUE_THRESHOLDS 0x8760
+# define R600_ROQ_IB1_START(x) ((x) << 0)
+# define R600_ROQ_IB2_START(x) ((x) << 8)
+#define R600_CP_MEQ_THRESHOLDS 0x8764
+# define R700_STQ_SPLIT(x) ((x) << 0)
+# define R600_MEQ_END(x) ((x) << 16)
+# define R600_ROQ_END(x) ((x) << 24)
+#define R600_CP_PERFMON_CNTL 0x87fc
+#define R600_CP_RB_BASE 0xc100
+#define R600_CP_RB_CNTL 0xc104
+# define R600_RB_BUFSZ(x) ((x) << 0)
+# define R600_RB_BLKSZ(x) ((x) << 8)
+# define R600_RB_NO_UPDATE (1 << 27)
+# define R600_RB_RPTR_WR_ENA (1 << 31)
+#define R600_CP_RB_RPTR_WR 0xc108
+#define R600_CP_RB_RPTR_ADDR 0xc10c
+#define R600_CP_RB_RPTR_ADDR_HI 0xc110
+#define R600_CP_RB_WPTR 0xc114
+#define R600_CP_RB_WPTR_ADDR 0xc118
+#define R600_CP_RB_WPTR_ADDR_HI 0xc11c
+#define R600_CP_RB_RPTR 0x8700
+#define R600_CP_RB_WPTR_DELAY 0x8704
+#define R600_CP_PFP_UCODE_ADDR 0xc150
+#define R600_CP_PFP_UCODE_DATA 0xc154
+#define R600_CP_ME_RAM_RADDR 0xc158
+#define R600_CP_ME_RAM_WADDR 0xc15c
+#define R600_CP_ME_RAM_DATA 0xc160
+#define R600_CP_DEBUG 0xc1fc
+
+#define R600_PA_CL_ENHANCE 0x8a14
+# define R600_CLIP_VTX_REORDER_ENA (1 << 0)
+# define R600_NUM_CLIP_SEQ(x) ((x) << 1)
+#define R600_PA_SC_LINE_STIPPLE_STATE 0x8b10
+#define R600_PA_SC_MULTI_CHIP_CNTL 0x8b20
+#define R700_PA_SC_FORCE_EOV_MAX_CNTS 0x8b24
+# define R700_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0)
+# define R700_FORCE_EOV_MAX_REZ_CNT(x) ((x) << 16)
+#define R600_PA_SC_AA_SAMPLE_LOCS_2S 0x8b40
+#define R600_PA_SC_AA_SAMPLE_LOCS_4S 0x8b44
+#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0 0x8b48
+#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1 0x8b4c
+# define R600_S0_X(x) ((x) << 0)
+# define R600_S0_Y(x) ((x) << 4)
+# define R600_S1_X(x) ((x) << 8)
+# define R600_S1_Y(x) ((x) << 12)
+# define R600_S2_X(x) ((x) << 16)
+# define R600_S2_Y(x) ((x) << 20)
+# define R600_S3_X(x) ((x) << 24)
+# define R600_S3_Y(x) ((x) << 28)
+# define R600_S4_X(x) ((x) << 0)
+# define R600_S4_Y(x) ((x) << 4)
+# define R600_S5_X(x) ((x) << 8)
+# define R600_S5_Y(x) ((x) << 12)
+# define R600_S6_X(x) ((x) << 16)
+# define R600_S6_Y(x) ((x) << 20)
+# define R600_S7_X(x) ((x) << 24)
+# define R600_S7_Y(x) ((x) << 28)
+#define R600_PA_SC_FIFO_SIZE 0x8bd0
+# define R600_SC_PRIM_FIFO_SIZE(x) ((x) << 0)
+# define R600_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 8)
+# define R600_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 16)
+#define R700_PA_SC_FIFO_SIZE_R7XX 0x8bcc
+# define R700_SC_PRIM_FIFO_SIZE(x) ((x) << 0)
+# define R700_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12)
+# define R700_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20)
+#define R600_PA_SC_ENHANCE 0x8bf0
+# define R600_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0)
+# define R600_FORCE_EOV_MAX_TILE_CNT(x) ((x) << 12)
+#define R600_PA_SC_CLIPRECT_RULE 0x2820c
+#define R700_PA_SC_EDGERULE 0x28230
+#define R600_PA_SC_LINE_STIPPLE 0x28a0c
+#define R600_PA_SC_MODE_CNTL 0x28a4c
+#define R600_PA_SC_AA_CONFIG 0x28c04
+
+#define R600_SX_EXPORT_BUFFER_SIZES 0x900c
+# define R600_COLOR_BUFFER_SIZE(x) ((x) << 0)
+# define R600_POSITION_BUFFER_SIZE(x) ((x) << 8)
+# define R600_SMX_BUFFER_SIZE(x) ((x) << 16)
+#define R600_SX_DEBUG_1 0x9054
+# define R600_SMX_EVENT_RELEASE (1 << 0)
+# define R600_ENABLE_NEW_SMX_ADDRESS (1 << 16)
+#define R700_SX_DEBUG_1 0x9058
+# define R700_ENABLE_NEW_SMX_ADDRESS (1 << 16)
+#define R600_SX_MISC 0x28350
+
+#define R600_DB_DEBUG 0x9830
+# define R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31)
+#define R600_DB_WATERMARKS 0x9838
+# define R600_DEPTH_FREE(x) ((x) << 0)
+# define R600_DEPTH_FLUSH(x) ((x) << 5)
+# define R600_DEPTH_PENDING_FREE(x) ((x) << 15)
+# define R600_DEPTH_CACHELINE_FREE(x) ((x) << 20)
+#define R700_DB_DEBUG3 0x98b0
+# define R700_DB_CLK_OFF_DELAY(x) ((x) << 11)
+#define RV700_DB_DEBUG4 0x9b8c
+# define RV700_DISABLE_TILE_COVERED_FOR_PS_ITER (1 << 6)
+
+#define R600_VGT_CACHE_INVALIDATION 0x88c4
+# define R600_CACHE_INVALIDATION(x) ((x) << 0)
+# define R600_VC_ONLY 0
+# define R600_TC_ONLY 1
+# define R600_VC_AND_TC 2
+# define R700_AUTO_INVLD_EN(x) ((x) << 6)
+# define R700_NO_AUTO 0
+# define R700_ES_AUTO 1
+# define R700_GS_AUTO 2
+# define R700_ES_AND_GS_AUTO 3
+#define R600_VGT_GS_PER_ES 0x88c8
+#define R600_VGT_ES_PER_GS 0x88cc
+#define R600_VGT_GS_PER_VS 0x88e8
+#define R600_VGT_GS_VERTEX_REUSE 0x88d4
+#define R600_VGT_NUM_INSTANCES 0x8974
+#define R600_VGT_STRMOUT_EN 0x28ab0
+#define R600_VGT_EVENT_INITIATOR 0x28a90
+# define R600_CACHE_FLUSH_AND_INV_EVENT (0x16 << 0)
+#define R600_VGT_VERTEX_REUSE_BLOCK_CNTL 0x28c58
+# define R600_VTX_REUSE_DEPTH_MASK 0xff
+#define R600_VGT_OUT_DEALLOC_CNTL 0x28c5c
+# define R600_DEALLOC_DIST_MASK 0x7f
+
+#define R600_CB_COLOR0_BASE 0x28040
+#define R600_CB_COLOR1_BASE 0x28044
+#define R600_CB_COLOR2_BASE 0x28048
+#define R600_CB_COLOR3_BASE 0x2804c
+#define R600_CB_COLOR4_BASE 0x28050
+#define R600_CB_COLOR5_BASE 0x28054
+#define R600_CB_COLOR6_BASE 0x28058
+#define R600_CB_COLOR7_BASE 0x2805c
+#define R600_CB_COLOR7_FRAG 0x280fc
+
+#define R600_TC_CNTL 0x9608
+# define R600_TC_L2_SIZE(x) ((x) << 5)
+# define R600_L2_DISABLE_LATE_HIT (1 << 9)
+
+#define R600_ARB_POP 0x2418
+# define R600_ENABLE_TC128 (1 << 30)
+#define R600_ARB_GDEC_RD_CNTL 0x246c
+
+#define R600_TA_CNTL_AUX 0x9508
+# define R600_DISABLE_CUBE_WRAP (1 << 0)
+# define R600_DISABLE_CUBE_ANISO (1 << 1)
+# define R700_GETLOD_SELECT(x) ((x) << 2)
+# define R600_SYNC_GRADIENT (1 << 24)
+# define R600_SYNC_WALKER (1 << 25)
+# define R600_SYNC_ALIGNER (1 << 26)
+# define R600_BILINEAR_PRECISION_6_BIT (0 << 31)
+# define R600_BILINEAR_PRECISION_8_BIT (1 << 31)
+
+#define R700_TCP_CNTL 0x9610
+
+#define R600_SMX_DC_CTL0 0xa020
+# define R700_USE_HASH_FUNCTION (1 << 0)
+# define R700_CACHE_DEPTH(x) ((x) << 1)
+# define R700_FLUSH_ALL_ON_EVENT (1 << 10)
+# define R700_STALL_ON_EVENT (1 << 11)
+#define R700_SMX_EVENT_CTL 0xa02c
+# define R700_ES_FLUSH_CTL(x) ((x) << 0)
+# define R700_GS_FLUSH_CTL(x) ((x) << 3)
+# define R700_ACK_FLUSH_CTL(x) ((x) << 6)
+# define R700_SYNC_FLUSH_CTL (1 << 8)
+
+#define R600_SQ_CONFIG 0x8c00
+# define R600_VC_ENABLE (1 << 0)
+# define R600_EXPORT_SRC_C (1 << 1)
+# define R600_DX9_CONSTS (1 << 2)
+# define R600_ALU_INST_PREFER_VECTOR (1 << 3)
+# define R600_DX10_CLAMP (1 << 4)
+# define R600_CLAUSE_SEQ_PRIO(x) ((x) << 8)
+# define R600_PS_PRIO(x) ((x) << 24)
+# define R600_VS_PRIO(x) ((x) << 26)
+# define R600_GS_PRIO(x) ((x) << 28)
+# define R600_ES_PRIO(x) ((x) << 30)
+#define R600_SQ_GPR_RESOURCE_MGMT_1 0x8c04
+# define R600_NUM_PS_GPRS(x) ((x) << 0)
+# define R600_NUM_VS_GPRS(x) ((x) << 16)
+# define R700_DYN_GPR_ENABLE (1 << 27)
+# define R600_NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28)
+#define R600_SQ_GPR_RESOURCE_MGMT_2 0x8c08
+# define R600_NUM_GS_GPRS(x) ((x) << 0)
+# define R600_NUM_ES_GPRS(x) ((x) << 16)
+#define R600_SQ_THREAD_RESOURCE_MGMT 0x8c0c
+# define R600_NUM_PS_THREADS(x) ((x) << 0)
+# define R600_NUM_VS_THREADS(x) ((x) << 8)
+# define R600_NUM_GS_THREADS(x) ((x) << 16)
+# define R600_NUM_ES_THREADS(x) ((x) << 24)
+#define R600_SQ_STACK_RESOURCE_MGMT_1 0x8c10
+# define R600_NUM_PS_STACK_ENTRIES(x) ((x) << 0)
+# define R600_NUM_VS_STACK_ENTRIES(x) ((x) << 16)
+#define R600_SQ_STACK_RESOURCE_MGMT_2 0x8c14
+# define R600_NUM_GS_STACK_ENTRIES(x) ((x) << 0)
+# define R600_NUM_ES_STACK_ENTRIES(x) ((x) << 16)
+#define R600_SQ_MS_FIFO_SIZES 0x8cf0
+# define R600_CACHE_FIFO_SIZE(x) ((x) << 0)
+# define R600_FETCH_FIFO_HIWATER(x) ((x) << 8)
+# define R600_DONE_FIFO_HIWATER(x) ((x) << 16)
+# define R600_ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24)
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_0 0x8db0
+# define R700_SIMDA_RING0(x) ((x) << 0)
+# define R700_SIMDA_RING1(x) ((x) << 8)
+# define R700_SIMDB_RING0(x) ((x) << 16)
+# define R700_SIMDB_RING1(x) ((x) << 24)
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_1 0x8db4
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_2 0x8db8
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_3 0x8dbc
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_4 0x8dc0
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_5 0x8dc4
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_6 0x8dc8
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_7 0x8dcc
+
+#define R600_SPI_PS_IN_CONTROL_0 0x286cc
+# define R600_NUM_INTERP(x) ((x) << 0)
+# define R600_POSITION_ENA (1 << 8)
+# define R600_POSITION_CENTROID (1 << 9)
+# define R600_POSITION_ADDR(x) ((x) << 10)
+# define R600_PARAM_GEN(x) ((x) << 15)
+# define R600_PARAM_GEN_ADDR(x) ((x) << 19)
+# define R600_BARYC_SAMPLE_CNTL(x) ((x) << 26)
+# define R600_PERSP_GRADIENT_ENA (1 << 28)
+# define R600_LINEAR_GRADIENT_ENA (1 << 29)
+# define R600_POSITION_SAMPLE (1 << 30)
+# define R600_BARYC_AT_SAMPLE_ENA (1 << 31)
+#define R600_SPI_PS_IN_CONTROL_1 0x286d0
+# define R600_GEN_INDEX_PIX (1 << 0)
+# define R600_GEN_INDEX_PIX_ADDR(x) ((x) << 1)
+# define R600_FRONT_FACE_ENA (1 << 8)
+# define R600_FRONT_FACE_CHAN(x) ((x) << 9)
+# define R600_FRONT_FACE_ALL_BITS (1 << 11)
+# define R600_FRONT_FACE_ADDR(x) ((x) << 12)
+# define R600_FOG_ADDR(x) ((x) << 17)
+# define R600_FIXED_PT_POSITION_ENA (1 << 24)
+# define R600_FIXED_PT_POSITION_ADDR(x) ((x) << 25)
+# define R700_POSITION_ULC (1 << 30)
+#define R600_SPI_INPUT_Z 0x286d8
+
+#define R600_SPI_CONFIG_CNTL 0x9100
+# define R600_GPR_WRITE_PRIORITY(x) ((x) << 0)
+# define R600_DISABLE_INTERP_1 (1 << 5)
+#define R600_SPI_CONFIG_CNTL_1 0x913c
+# define R600_VTX_DONE_DELAY(x) ((x) << 0)
+# define R600_INTERP_ONE_PRIM_PER_ROW (1 << 4)
+
+#define R600_GB_TILING_CONFIG 0x98f0
+# define R600_PIPE_TILING(x) ((x) << 1)
+# define R600_BANK_TILING(x) ((x) << 4)
+# define R600_GROUP_SIZE(x) ((x) << 6)
+# define R600_ROW_TILING(x) ((x) << 8)
+# define R600_BANK_SWAPS(x) ((x) << 11)
+# define R600_SAMPLE_SPLIT(x) ((x) << 14)
+# define R600_BACKEND_MAP(x) ((x) << 16)
+#define R600_DCP_TILING_CONFIG 0x6ca0
+#define R600_HDP_TILING_CONFIG 0x2f3c
+
+#define R600_CC_RB_BACKEND_DISABLE 0x98f4
+#define R700_CC_SYS_RB_BACKEND_DISABLE 0x3f88
+# define R600_BACKEND_DISABLE(x) ((x) << 16)
+
+#define R600_CC_GC_SHADER_PIPE_CONFIG 0x8950
+#define R600_GC_USER_SHADER_PIPE_CONFIG 0x8954
+# define R600_INACTIVE_QD_PIPES(x) ((x) << 8)
+# define R600_INACTIVE_QD_PIPES_MASK (0xff << 8)
+# define R600_INACTIVE_SIMDS(x) ((x) << 16)
+# define R600_INACTIVE_SIMDS_MASK (0xff << 16)
+
+#define R700_CGTS_SYS_TCC_DISABLE 0x3f90
+#define R700_CGTS_USER_SYS_TCC_DISABLE 0x3f94
+#define R700_CGTS_TCC_DISABLE 0x9148
+#define R700_CGTS_USER_TCC_DISABLE 0x914c
+
/* Constants */
#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
@@ -1190,6 +1734,11 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_LAST_SWI_REG RADEON_SCRATCH_REG3
#define RADEON_LAST_DISPATCH 1
+#define R600_LAST_FRAME_REG R600_SCRATCH_REG0
+#define R600_LAST_DISPATCH_REG R600_SCRATCH_REG1
+#define R600_LAST_CLEAR_REG R600_SCRATCH_REG2
+#define R600_LAST_SWI_REG R600_SCRATCH_REG3
+
#define RADEON_MAX_VB_AGE 0x7fffffff
#define RADEON_MAX_VB_VERTS (0xffff)
@@ -1198,7 +1747,15 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_PCIGART_TABLE_SIZE (32*1024)
#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
-#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
+#define RADEON_WRITE(reg, val) \
+do { \
+ if (reg < 0x10000) { \
+ DRM_WRITE32(dev_priv->mmio, (reg), (val)); \
+ } else { \
+ DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, (reg)); \
+ DRM_WRITE32(dev_priv->mmio, RADEON_MM_DATA, (val)); \
+ } \
+} while (0)
#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) )
@@ -1238,11 +1795,19 @@ do { \
RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \
} while (0)
+#define RS600_WRITE_MCIND(addr, val) \
+do { \
+ RADEON_WRITE(RS600_MC_INDEX, RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 | ((addr) & RS600_MC_ADDR_MASK)); \
+ RADEON_WRITE(RS600_MC_DATA, val); \
+} while (0)
+
#define IGP_WRITE_MCIND(addr, val) \
do { \
if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \
RS690_WRITE_MCIND(addr, val); \
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) \
+ RS600_WRITE_MCIND(addr, val); \
else \
RS480_WRITE_MCIND(addr, val); \
} while (0)
@@ -1346,7 +1911,11 @@ do { \
struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; \
drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; \
if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \
- int __ret = radeon_do_cp_idle( dev_priv ); \
+ int __ret; \
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) \
+ __ret = r600_do_cp_idle(dev_priv); \
+ else \
+ __ret = radeon_do_cp_idle(dev_priv); \
if ( __ret ) return __ret; \
sarea_priv->last_dispatch = 0; \
radeon_freelist_reset( dev ); \
@@ -1368,21 +1937,40 @@ do { \
OUT_RING( age ); \
} while (0)
+#define R600_DISPATCH_AGE(age) do { \
+ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \
+ OUT_RING((R600_LAST_DISPATCH_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \
+ OUT_RING(age); \
+} while (0)
+
+#define R600_FRAME_AGE(age) do { \
+ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \
+ OUT_RING((R600_LAST_FRAME_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \
+ OUT_RING(age); \
+} while (0)
+
+#define R600_CLEAR_AGE(age) do { \
+ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \
+ OUT_RING((R600_LAST_CLEAR_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \
+ OUT_RING(age); \
+} while (0)
+
/* ================================================================
* Ring control
*/
#define RADEON_VERBOSE 0
-#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring;
+#define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring;
#define BEGIN_RING( n ) do { \
if ( RADEON_VERBOSE ) { \
DRM_INFO( "BEGIN_RING( %d )\n", (n)); \
} \
- if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
+ _align_nr = (n + 0xf) & ~0xf; \
+ if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \
COMMIT_RING(); \
- radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \
+ radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \
} \
_nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \
ring = dev_priv->ring.start; \
@@ -1399,19 +1987,16 @@ do { \
DRM_ERROR( \
"ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \
((dev_priv->ring.tail + _nr) & mask), \
- write, __LINE__); \
+ write, __LINE__); \
} else \
dev_priv->ring.tail = write; \
} while (0)
+extern void radeon_commit_ring(drm_radeon_private_t *dev_priv);
+
#define COMMIT_RING() do { \
- /* Flush writes to ring */ \
- DRM_MEMORYBARRIER(); \
- GET_RING_HEAD( dev_priv ); \
- RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \
- /* read from PCI bus to ensure correct posting */ \
- RADEON_READ( RADEON_CP_RB_RPTR ); \
-} while (0)
+ radeon_commit_ring(dev_priv); \
+ } while(0)
#define OUT_RING( x ) do { \
if ( RADEON_VERBOSE ) { \
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c
index 8289e16419a8..9836c705a952 100644
--- a/drivers/gpu/drm/radeon/radeon_irq.c
+++ b/drivers/gpu/drm/radeon/radeon_irq.c
@@ -65,7 +65,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
switch (crtc) {
case 0:
r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1);
@@ -100,7 +100,7 @@ void radeon_disable_vblank(struct drm_device *dev, int crtc)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
switch (crtc) {
case 0:
r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0);
@@ -135,7 +135,7 @@ static inline u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r
u32 irq_mask = RADEON_SW_INT_TEST;
*r500_disp_int = 0;
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
/* vbl interrupts in a different place */
if (irqs & R500_DISPLAY_INT_STATUS) {
@@ -202,7 +202,7 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
DRM_WAKEUP(&dev_priv->swi_queue);
/* VBLANK interrupt */
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
if (r500_disp_int & R500_D1_VBLANK_INTERRUPT)
drm_handle_vblank(dev, 0);
if (r500_disp_int & R500_D2_VBLANK_INTERRUPT)
@@ -265,7 +265,7 @@ u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
return -EINVAL;
}
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
if (crtc == 0)
return RADEON_READ(R500_D1CRTC_FRAME_COUNT);
else
@@ -327,7 +327,7 @@ void radeon_driver_irq_preinstall(struct drm_device * dev)
u32 dummy;
/* Disable *all* interrupts */
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
@@ -357,7 +357,7 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
if (!dev_priv)
return;
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
/* Disable *all* interrupts */
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c
index ef940a079dcb..fa728ec6ed34 100644
--- a/drivers/gpu/drm/radeon/radeon_state.c
+++ b/drivers/gpu/drm/radeon/radeon_state.c
@@ -1556,9 +1556,15 @@ static void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *
buf_priv->age = ++master_priv->sarea_priv->last_dispatch;
/* Emit the vertex buffer age */
- BEGIN_RING(2);
- RADEON_DISPATCH_AGE(buf_priv->age);
- ADVANCE_RING();
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+ BEGIN_RING(3);
+ R600_DISPATCH_AGE(buf_priv->age);
+ ADVANCE_RING();
+ } else {
+ BEGIN_RING(2);
+ RADEON_DISPATCH_AGE(buf_priv->age);
+ ADVANCE_RING();
+ }
buf->pending = 1;
buf->used = 0;
@@ -1980,7 +1986,7 @@ static int alloc_surface(drm_radeon_surface_alloc_t *new,
/* find a virtual surface */
for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++)
- if (dev_priv->virt_surfaces[i].file_priv == 0)
+ if (dev_priv->virt_surfaces[i].file_priv == NULL)
break;
if (i == 2 * RADEON_MAX_SURFACES) {
return -1;
@@ -2473,24 +2479,25 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil
buf->used = indirect->end;
- /* Wait for the 3D stream to idle before the indirect buffer
- * containing 2D acceleration commands is processed.
- */
- BEGIN_RING(2);
-
- RADEON_WAIT_UNTIL_3D_IDLE();
-
- ADVANCE_RING();
-
/* Dispatch the indirect buffer full of commands from the
* X server. This is insecure and is thus only available to
* privileged clients.
*/
- radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
- if (indirect->discard) {
- radeon_cp_discard_buffer(dev, file_priv->master, buf);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ r600_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
+ else {
+ /* Wait for the 3D stream to idle before the indirect buffer
+ * containing 2D acceleration commands is processed.
+ */
+ BEGIN_RING(2);
+ RADEON_WAIT_UNTIL_3D_IDLE();
+ ADVANCE_RING();
+ radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
}
+ if (indirect->discard)
+ radeon_cp_discard_buffer(dev, file_priv->master, buf);
+
COMMIT_RING();
return 0;
}
@@ -3010,14 +3017,14 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
break;
case RADEON_PARAM_LAST_FRAME:
dev_priv->stats.last_frame_reads++;
- value = GET_SCRATCH(0);
+ value = GET_SCRATCH(dev_priv, 0);
break;
case RADEON_PARAM_LAST_DISPATCH:
- value = GET_SCRATCH(1);
+ value = GET_SCRATCH(dev_priv, 1);
break;
case RADEON_PARAM_LAST_CLEAR:
dev_priv->stats.last_clear_reads++;
- value = GET_SCRATCH(2);
+ value = GET_SCRATCH(dev_priv, 2);
break;
case RADEON_PARAM_IRQ_NR:
value = drm_dev_to_irq(dev);
@@ -3052,7 +3059,10 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
case RADEON_PARAM_SCRATCH_OFFSET:
if (!dev_priv->writeback_works)
return -EINVAL;
- value = RADEON_SCRATCH_REG_OFFSET;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ value = R600_SCRATCH_REG_OFFSET;
+ else
+ value = RADEON_SCRATCH_REG_OFFSET;
break;
case RADEON_PARAM_CARD_TYPE:
if (dev_priv->flags & RADEON_IS_PCIE)
@@ -3155,6 +3165,7 @@ void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
void radeon_driver_lastclose(struct drm_device *dev)
{
+ radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private);
radeon_do_release(dev);
}
diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c
index d465b2f9c1cd..456cd040f31a 100644
--- a/drivers/gpu/drm/savage/savage_bci.c
+++ b/drivers/gpu/drm/savage/savage_bci.c
@@ -599,8 +599,8 @@ int savage_driver_firstopen(struct drm_device *dev)
drm_mtrr_add(dev_priv->mtrr[2].base,
dev_priv->mtrr[2].size, DRM_MTRR_WC);
} else {
- DRM_ERROR("strange pci_resource_len %08lx\n",
- drm_get_resource_len(dev, 0));
+ DRM_ERROR("strange pci_resource_len %08llx\n",
+ (unsigned long long)drm_get_resource_len(dev, 0));
}
} else if (dev_priv->chipset != S3_SUPERSAVAGE &&
dev_priv->chipset != S3_SAVAGE2000) {
@@ -620,8 +620,8 @@ int savage_driver_firstopen(struct drm_device *dev)
drm_mtrr_add(dev_priv->mtrr[0].base,
dev_priv->mtrr[0].size, DRM_MTRR_WC);
} else {
- DRM_ERROR("strange pci_resource_len %08lx\n",
- drm_get_resource_len(dev, 1));
+ DRM_ERROR("strange pci_resource_len %08llx\n",
+ (unsigned long long)drm_get_resource_len(dev, 1));
}
} else {
mmio_base = drm_get_resource_start(dev, 0);
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c
index 0993b441fc42..bc2f51843005 100644
--- a/drivers/gpu/drm/via/via_drv.c
+++ b/drivers/gpu/drm/via/via_drv.c
@@ -28,11 +28,6 @@
#include "drm_pciids.h"
-static int dri_library_name(struct drm_device *dev, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "unichrome");
-}
-
static struct pci_device_id pciidlist[] = {
viadrv_PCI_IDS
};
@@ -52,7 +47,6 @@ static struct drm_driver driver = {
.irq_uninstall = via_driver_irq_uninstall,
.irq_handler = via_driver_irq_handler,
.dma_quiescent = via_driver_dma_quiescent,
- .dri_library_name = dri_library_name,
.reclaim_buffers = drm_core_reclaim_buffers,
.reclaim_buffers_locked = NULL,
.reclaim_buffers_idlelocked = via_reclaim_buffers_locked,
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index e85c8fe9ffcf..7e67dcb3d4f6 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -29,11 +29,11 @@ config HID
For docs and specs, see http://www.usb.org/developers/hidpage/
- If unsure, say Y
+ If unsure, say Y.
config HID_DEBUG
bool "HID debugging support"
- default y if !EMBEDDED
+ default y
depends on HID
---help---
This option lets the HID layer output diagnostics about its internal
@@ -44,7 +44,7 @@ config HID_DEBUG
This feature is useful for those who are either debugging the HID parser
or any HID hardware device.
- If unsure, say N
+ If unsure, say Y.
config HIDRAW
bool "/dev/hidraw raw HID device support"
@@ -70,18 +70,6 @@ source "drivers/hid/usbhid/Kconfig"
menu "Special HID drivers"
depends on HID
-config HID_COMPAT
- bool "Load all HID drivers on hid core load"
- default y
- ---help---
- Compatible option for older userspace. If you have system without udev
- support of module loading through aliases and also old
- module-init-tools which can't handle hid bus, choose Y here. Otherwise
- say N. If you say N and your userspace is old enough, the only
- functionality you lose is modules autoloading.
-
- If unsure, say Y.
-
config HID_A4TECH
tristate "A4 tech" if EMBEDDED
depends on USB_HID
@@ -128,6 +116,14 @@ config HID_CYPRESS
---help---
Support for cypress mouse and barcode readers.
+config DRAGONRISE_FF
+ tristate "DragonRise Inc. force feedback support"
+ depends on USB_HID
+ select INPUT_FF_MEMLESS
+ ---help---
+ Say Y here if you want to enable force feedback support for DragonRise Inc.
+ game controllers.
+
config HID_EZKEY
tristate "Ezkey" if EMBEDDED
depends on USB_HID
@@ -135,6 +131,13 @@ config HID_EZKEY
---help---
Support for Ezkey BTC 8193 keyboard.
+config HID_KYE
+ tristate "Kye" if EMBEDDED
+ depends on USB_HID
+ default !EMBEDDED
+ ---help---
+ Support for Kye/Genius Ergo Mouse.
+
config HID_GYRATION
tristate "Gyration" if EMBEDDED
depends on USB_HID
@@ -142,6 +145,13 @@ config HID_GYRATION
---help---
Support for Gyration remote control.
+config HID_KENSINGTON
+ tristate "Kensington" if EMBEDDED
+ depends on USB_HID
+ default !EMBEDDED
+ ---help---
+ Support for Kensington Slimblade Trackball.
+
config HID_LOGITECH
tristate "Logitech" if EMBEDDED
depends on USB_HID
@@ -243,7 +253,7 @@ config GREENASIA_FF
select INPUT_FF_MEMLESS
---help---
Say Y here if you have a GreenAsia (Product ID 0x12) based game controller
- (like MANTA Warior MM816 and SpeedLink Strike2 SL-6635) or adapter
+ (like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter
and want to enable force feedback support for it.
config HID_TOPSEED
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index fbd021f153f1..1f7cb0fd4505 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -8,10 +8,6 @@ obj-$(CONFIG_HID) += hid.o
hid-$(CONFIG_HID_DEBUG) += hid-debug.o
hid-$(CONFIG_HIDRAW) += hidraw.o
-ifdef CONFIG_HID_COMPAT
-obj-m += hid-dummy.o
-endif
-
hid-logitech-objs := hid-lg.o
ifdef CONFIG_LOGITECH_FF
hid-logitech-objs += hid-lgff.o
@@ -26,8 +22,11 @@ obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
obj-$(CONFIG_HID_CHERRY) += hid-cherry.o
obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
+obj-$(CONFIG_DRAGONRISE_FF) += hid-drff.o
obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
+obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
+obj-$(CONFIG_HID_KYE) += hid-kye.o
obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c
index ebca00e6c103..42ea359e94cf 100644
--- a/drivers/hid/hid-a4tech.c
+++ b/drivers/hid/hid-a4tech.c
@@ -158,5 +158,3 @@ static void a4_exit(void)
module_init(a4_init);
module_exit(a4_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(a4tech);
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index aa28aed0e46c..7359d9d88e46 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -53,7 +53,7 @@ struct apple_key_translation {
u8 flags;
};
-static struct apple_key_translation apple_fn_keys[] = {
+static const struct apple_key_translation apple_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_ENTER, KEY_INSERT },
{ KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
@@ -75,7 +75,7 @@ static struct apple_key_translation apple_fn_keys[] = {
{ }
};
-static struct apple_key_translation powerbook_fn_keys[] = {
+static const struct apple_key_translation powerbook_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
{ KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
@@ -94,7 +94,7 @@ static struct apple_key_translation powerbook_fn_keys[] = {
{ }
};
-static struct apple_key_translation powerbook_numlock_keys[] = {
+static const struct apple_key_translation powerbook_numlock_keys[] = {
{ KEY_J, KEY_KP1 },
{ KEY_K, KEY_KP2 },
{ KEY_L, KEY_KP3 },
@@ -117,16 +117,16 @@ static struct apple_key_translation powerbook_numlock_keys[] = {
{ }
};
-static struct apple_key_translation apple_iso_keyboard[] = {
+static const struct apple_key_translation apple_iso_keyboard[] = {
{ KEY_GRAVE, KEY_102ND },
{ KEY_102ND, KEY_GRAVE },
{ }
};
-static struct apple_key_translation *apple_find_translation(
- struct apple_key_translation *table, u16 from)
+static const struct apple_key_translation *apple_find_translation(
+ const struct apple_key_translation *table, u16 from)
{
- struct apple_key_translation *trans;
+ const struct apple_key_translation *trans;
/* Look for the translation */
for (trans = table; trans->from; trans++)
@@ -140,7 +140,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
struct hid_usage *usage, __s32 value)
{
struct apple_sc *asc = hid_get_drvdata(hid);
- struct apple_key_translation *trans;
+ const struct apple_key_translation *trans;
if (usage->code == KEY_FN) {
asc->fn_on = !!value;
@@ -253,7 +253,7 @@ static void apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
static void apple_setup_input(struct input_dev *input)
{
- struct apple_key_translation *trans;
+ const struct apple_key_translation *trans;
set_bit(KEY_NUMLOCK, input->keybit);
@@ -387,6 +387,12 @@ static const struct hid_device_id apple_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS),
+ .driver_data = APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI),
.driver_data = APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO),
@@ -468,5 +474,3 @@ static void apple_exit(void)
module_init(apple_init);
module_exit(apple_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(apple);
diff --git a/drivers/hid/hid-belkin.c b/drivers/hid/hid-belkin.c
index 12c8a9ba6ed6..2f6723133a4b 100644
--- a/drivers/hid/hid-belkin.c
+++ b/drivers/hid/hid-belkin.c
@@ -101,5 +101,3 @@ static void belkin_exit(void)
module_init(belkin_init);
module_exit(belkin_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(belkin);
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c
index b833b9769aba..ab8209e7e45c 100644
--- a/drivers/hid/hid-cherry.c
+++ b/drivers/hid/hid-cherry.c
@@ -83,5 +83,3 @@ static void ch_exit(void)
module_init(ch_init);
module_exit(ch_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(cherry);
diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c
index a54d4096e0f7..7f91076d8493 100644
--- a/drivers/hid/hid-chicony.c
+++ b/drivers/hid/hid-chicony.c
@@ -76,5 +76,3 @@ static void ch_exit(void)
module_init(ch_init);
module_exit(ch_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(chicony);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 1cc967448f4d..5746a5903bce 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1236,6 +1236,9 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) },
@@ -1262,6 +1265,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
@@ -1269,6 +1273,8 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
@@ -1813,14 +1819,21 @@ void hid_unregister_driver(struct hid_driver *hdrv)
}
EXPORT_SYMBOL_GPL(hid_unregister_driver);
-#ifdef CONFIG_HID_COMPAT
-static void hid_compat_load(struct work_struct *ws)
+int hid_check_keys_pressed(struct hid_device *hid)
{
- request_module("hid-dummy");
+ struct hid_input *hidinput;
+ int i;
+
+ list_for_each_entry(hidinput, &hid->inputs, list) {
+ for (i = 0; i < BITS_TO_LONGS(KEY_MAX); i++)
+ if (hidinput->input->key[i])
+ return 1;
+ }
+
+ return 0;
}
-static DECLARE_WORK(hid_compat_work, hid_compat_load);
-static struct workqueue_struct *hid_compat_wq;
-#endif
+
+EXPORT_SYMBOL_GPL(hid_check_keys_pressed);
static int __init hid_init(void)
{
@@ -1836,15 +1849,6 @@ static int __init hid_init(void)
if (ret)
goto err_bus;
-#ifdef CONFIG_HID_COMPAT
- hid_compat_wq = create_singlethread_workqueue("hid_compat");
- if (!hid_compat_wq) {
- hidraw_exit();
- goto err;
- }
- queue_work(hid_compat_wq, &hid_compat_work);
-#endif
-
return 0;
err_bus:
bus_unregister(&hid_bus_type);
@@ -1854,9 +1858,6 @@ err:
static void __exit hid_exit(void)
{
-#ifdef CONFIG_HID_COMPAT
- destroy_workqueue(hid_compat_wq);
-#endif
hidraw_exit();
bus_unregister(&hid_bus_type);
}
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
index 5d69d27b935d..9d6d3b91773b 100644
--- a/drivers/hid/hid-cypress.c
+++ b/drivers/hid/hid-cypress.c
@@ -154,5 +154,3 @@ static void cp_exit(void)
module_init(cp_init);
module_exit(cp_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(cypress);
diff --git a/drivers/hid/hid-drff.c b/drivers/hid/hid-drff.c
new file mode 100644
index 000000000000..34f3eb65100b
--- /dev/null
+++ b/drivers/hid/hid-drff.c
@@ -0,0 +1,188 @@
+/*
+ * Force feedback support for DragonRise Inc. game controllers
+ *
+ * From what I have gathered, these devices are mass produced in China and are
+ * distributed under several vendors. They often share the same design as
+ * the original PlayStation DualShock controller.
+ *
+ * 0079:0006 "DragonRise Inc. Generic USB Joystick "
+ * - tested with a Tesun USB-703 game controller.
+ *
+ * Copyright (c) 2009 Richard Walmsley <richwalm@gmail.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/hid.h>
+
+#include "hid-ids.h"
+#include "usbhid/usbhid.h"
+
+struct drff_device {
+ struct hid_report *report;
+};
+
+static int drff_play(struct input_dev *dev, void *data,
+ struct ff_effect *effect)
+{
+ struct hid_device *hid = input_get_drvdata(dev);
+ struct drff_device *drff = data;
+ int strong, weak;
+
+ strong = effect->u.rumble.strong_magnitude;
+ weak = effect->u.rumble.weak_magnitude;
+
+ dbg_hid("called with 0x%04x 0x%04x", strong, weak);
+
+ if (strong || weak) {
+ strong = strong * 0xff / 0xffff;
+ weak = weak * 0xff / 0xffff;
+
+ /* While reverse engineering this device, I found that when
+ this value is set, it causes the strong rumble to function
+ at a near maximum speed, so we'll bypass it. */
+ if (weak == 0x0a)
+ weak = 0x0b;
+
+ drff->report->field[0]->value[0] = 0x51;
+ drff->report->field[0]->value[1] = 0x00;
+ drff->report->field[0]->value[2] = weak;
+ drff->report->field[0]->value[4] = strong;
+ usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+ drff->report->field[0]->value[0] = 0xfa;
+ drff->report->field[0]->value[1] = 0xfe;
+ } else {
+ drff->report->field[0]->value[0] = 0xf3;
+ drff->report->field[0]->value[1] = 0x00;
+ }
+
+ drff->report->field[0]->value[2] = 0x00;
+ drff->report->field[0]->value[4] = 0x00;
+ dbg_hid("running with 0x%02x 0x%02x", strong, weak);
+ usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+ return 0;
+}
+
+static int drff_init(struct hid_device *hid)
+{
+ struct drff_device *drff;
+ struct hid_report *report;
+ struct hid_input *hidinput = list_first_entry(&hid->inputs,
+ struct hid_input, list);
+ struct list_head *report_list =
+ &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+ int error;
+
+ if (list_empty(report_list)) {
+ dev_err(&hid->dev, "no output reports found\n");
+ return -ENODEV;
+ }
+
+ report = list_first_entry(report_list, struct hid_report, list);
+ if (report->maxfield < 1) {
+ dev_err(&hid->dev, "no fields in the report\n");
+ return -ENODEV;
+ }
+
+ if (report->field[0]->report_count < 7) {
+ dev_err(&hid->dev, "not enough values in the field\n");
+ return -ENODEV;
+ }
+
+ drff = kzalloc(sizeof(struct drff_device), GFP_KERNEL);
+ if (!drff)
+ return -ENOMEM;
+
+ set_bit(FF_RUMBLE, dev->ffbit);
+
+ error = input_ff_create_memless(dev, drff, drff_play);
+ if (error) {
+ kfree(drff);
+ return error;
+ }
+
+ drff->report = report;
+ drff->report->field[0]->value[0] = 0xf3;
+ drff->report->field[0]->value[1] = 0x00;
+ drff->report->field[0]->value[2] = 0x00;
+ drff->report->field[0]->value[3] = 0x00;
+ drff->report->field[0]->value[4] = 0x00;
+ drff->report->field[0]->value[5] = 0x00;
+ drff->report->field[0]->value[6] = 0x00;
+ usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+ dev_info(&hid->dev, "Force Feedback for DragonRise Inc. game "
+ "controllers by Richard Walmsley <richwalm@gmail.com>\n");
+
+ return 0;
+}
+
+static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+ int ret;
+
+ dev_dbg(&hdev->dev, "DragonRise Inc. HID hardware probe...");
+
+ ret = hid_parse(hdev);
+ if (ret) {
+ dev_err(&hdev->dev, "parse failed\n");
+ goto err;
+ }
+
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
+ if (ret) {
+ dev_err(&hdev->dev, "hw start failed\n");
+ goto err;
+ }
+
+ drff_init(hdev);
+
+ return 0;
+err:
+ return ret;
+}
+
+static const struct hid_device_id dr_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006), },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, dr_devices);
+
+static struct hid_driver dr_driver = {
+ .name = "dragonrise",
+ .id_table = dr_devices,
+ .probe = dr_probe,
+};
+
+static int __init dr_init(void)
+{
+ return hid_register_driver(&dr_driver);
+}
+
+static void __exit dr_exit(void)
+{
+ hid_unregister_driver(&dr_driver);
+}
+
+module_init(dr_init);
+module_exit(dr_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c
deleted file mode 100644
index b4cc0f743d63..000000000000
--- a/drivers/hid/hid-dummy.c
+++ /dev/null
@@ -1,78 +0,0 @@
-#include <linux/autoconf.h>
-#include <linux/module.h>
-#include <linux/hid.h>
-
-static int __init hid_dummy_init(void)
-{
-#ifdef CONFIG_HID_A4TECH_MODULE
- HID_COMPAT_CALL_DRIVER(a4tech);
-#endif
-#ifdef CONFIG_HID_APPLE_MODULE
- HID_COMPAT_CALL_DRIVER(apple);
-#endif
-#ifdef CONFIG_HID_BELKIN_MODULE
- HID_COMPAT_CALL_DRIVER(belkin);
-#endif
-#ifdef CONFIG_HID_BRIGHT_MODULE
- HID_COMPAT_CALL_DRIVER(bright);
-#endif
-#ifdef CONFIG_HID_CHERRY_MODULE
- HID_COMPAT_CALL_DRIVER(cherry);
-#endif
-#ifdef CONFIG_HID_CHICONY_MODULE
- HID_COMPAT_CALL_DRIVER(chicony);
-#endif
-#ifdef CONFIG_HID_CYPRESS_MODULE
- HID_COMPAT_CALL_DRIVER(cypress);
-#endif
-#ifdef CONFIG_HID_DELL_MODULE
- HID_COMPAT_CALL_DRIVER(dell);
-#endif
-#ifdef CONFIG_HID_EZKEY_MODULE
- HID_COMPAT_CALL_DRIVER(ezkey);
-#endif
-#ifdef CONFIG_HID_GYRATION_MODULE
- HID_COMPAT_CALL_DRIVER(gyration);
-#endif
-#ifdef CONFIG_HID_LOGITECH_MODULE
- HID_COMPAT_CALL_DRIVER(logitech);
-#endif
-#ifdef CONFIG_HID_MICROSOFT_MODULE
- HID_COMPAT_CALL_DRIVER(microsoft);
-#endif
-#ifdef CONFIG_HID_MONTEREY_MODULE
- HID_COMPAT_CALL_DRIVER(monterey);
-#endif
-#ifdef CONFIG_HID_NTRIG_MODULE
- HID_COMPAT_CALL_DRIVER(ntrig);
-#endif
-#ifdef CONFIG_HID_PANTHERLORD_MODULE
- HID_COMPAT_CALL_DRIVER(pantherlord);
-#endif
-#ifdef CONFIG_HID_PETALYNX_MODULE
- HID_COMPAT_CALL_DRIVER(petalynx);
-#endif
-#ifdef CONFIG_HID_SAMSUNG_MODULE
- HID_COMPAT_CALL_DRIVER(samsung);
-#endif
-#ifdef CONFIG_HID_SONY_MODULE
- HID_COMPAT_CALL_DRIVER(sony);
-#endif
-#ifdef CONFIG_HID_SUNPLUS_MODULE
- HID_COMPAT_CALL_DRIVER(sunplus);
-#endif
-#ifdef CONFIG_GREENASIA_FF_MODULE
- HID_COMPAT_CALL_DRIVER(greenasia);
-#endif
-#ifdef CONFIG_THRUSTMASTER_FF_MODULE
- HID_COMPAT_CALL_DRIVER(thrustmaster);
-#endif
-#ifdef CONFIG_ZEROPLUS_FF_MODULE
- HID_COMPAT_CALL_DRIVER(zeroplus);
-#endif
-
- return -EIO;
-}
-module_init(hid_dummy_init);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-ezkey.c b/drivers/hid/hid-ezkey.c
index deb42f931b7e..0a1fe054799b 100644
--- a/drivers/hid/hid-ezkey.c
+++ b/drivers/hid/hid-ezkey.c
@@ -91,5 +91,3 @@ static void ez_exit(void)
module_init(ez_init);
module_exit(ez_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(ezkey);
diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c
index 71211f6a4f02..510ad3ab8d33 100644
--- a/drivers/hid/hid-gaff.c
+++ b/drivers/hid/hid-gaff.c
@@ -181,5 +181,3 @@ static void __exit ga_exit(void)
module_init(ga_init);
module_exit(ga_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(greenasia);
diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c
index 04a0afec52ac..d42d222097a8 100644
--- a/drivers/hid/hid-gyration.c
+++ b/drivers/hid/hid-gyration.c
@@ -94,5 +94,3 @@ static void gyration_exit(void)
module_init(gyration_init);
module_exit(gyration_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(gyration);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 88511970508d..bdeda4c7cc13 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -67,6 +67,9 @@
#define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a
#define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b
#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c
+#define USB_DEVICE_ID_APPLE_ALU_MINI_ANSI 0x021d
+#define USB_DEVICE_ID_APPLE_ALU_MINI_ISO 0x021e
+#define USB_DEVICE_ID_APPLE_ALU_MINI_JIS 0x021f
#define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220
#define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221
#define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222
@@ -148,6 +151,8 @@
#define USB_VENDOR_ID_DMI 0x0c0b
#define USB_DEVICE_ID_DMI_ENC 0x5fab
+#define USB_VENDOR_ID_DRAGONRISE 0x0079
+
#define USB_VENDOR_ID_ELO 0x04E7
#define USB_DEVICE_ID_ELO_TS2700 0x0020
@@ -272,6 +277,9 @@
#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030
#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
+#define USB_VENDOR_ID_KENSINGTON 0x047d
+#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041
+
#define USB_VENDOR_ID_LOGITECH 0x046d
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
@@ -418,6 +426,8 @@
#define USB_VENDOR_ID_ZEROPLUS 0x0c12
#define USB_VENDOR_ID_KYE 0x0458
+#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
+
#endif
diff --git a/drivers/hid/hid-kensington.c b/drivers/hid/hid-kensington.c
new file mode 100644
index 000000000000..7353bd79cbe9
--- /dev/null
+++ b/drivers/hid/hid-kensington.c
@@ -0,0 +1,63 @@
+/*
+ * HID driver for Kensigton Slimblade Trackball
+ *
+ * Copyright (c) 2009 Jiri Kosina
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+#define ks_map_key(c) hid_map_usage(hi, usage, bit, max, EV_KEY, (c))
+
+static int ks_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+ struct hid_field *field, struct hid_usage *usage,
+ unsigned long **bit, int *max)
+{
+ if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
+ return 0;
+
+ switch (usage->hid & HID_USAGE) {
+ case 0x01: ks_map_key(BTN_MIDDLE); break;
+ case 0x02: ks_map_key(BTN_SIDE); break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+static const struct hid_device_id ks_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, ks_devices);
+
+static struct hid_driver ks_driver = {
+ .name = "kensington",
+ .id_table = ks_devices,
+ .input_mapping = ks_input_mapping,
+};
+
+static int ks_init(void)
+{
+ return hid_register_driver(&ks_driver);
+}
+
+static void ks_exit(void)
+{
+ hid_unregister_driver(&ks_driver);
+}
+
+module_init(ks_init);
+module_exit(ks_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c
new file mode 100644
index 000000000000..72ee3fec56d9
--- /dev/null
+++ b/drivers/hid/hid-kye.c
@@ -0,0 +1,69 @@
+/*
+ * HID driver for Kye/Genius devices not fully compliant with HID standard
+ *
+ * Copyright (c) 2009 Jiri Kosina
+ * Copyright (c) 2009 Tomas Hanak
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+/* the fixups that need to be done:
+ * - change led usage page to button for extra buttons
+ * - report size 8 count 1 must be size 1 count 8 for button bitfield
+ * - change the button usage range to 4-7 for the extra buttons
+ */
+static void kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int rsize)
+{
+ if (rsize >= 74 &&
+ rdesc[61] == 0x05 && rdesc[62] == 0x08 &&
+ rdesc[63] == 0x19 && rdesc[64] == 0x08 &&
+ rdesc[65] == 0x29 && rdesc[66] == 0x0f &&
+ rdesc[71] == 0x75 && rdesc[72] == 0x08 &&
+ rdesc[73] == 0x95 && rdesc[74] == 0x01) {
+ dev_info(&hdev->dev, "fixing up Kye/Genius Ergo Mouse report "
+ "descriptor\n");
+ rdesc[62] = 0x09;
+ rdesc[64] = 0x04;
+ rdesc[66] = 0x07;
+ rdesc[72] = 0x01;
+ rdesc[74] = 0x08;
+ }
+}
+
+static const struct hid_device_id kye_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, kye_devices);
+
+static struct hid_driver kye_driver = {
+ .name = "kye",
+ .id_table = kye_devices,
+ .report_fixup = kye_report_fixup,
+};
+
+static int kye_init(void)
+{
+ return hid_register_driver(&kye_driver);
+}
+
+static void kye_exit(void)
+{
+ hid_unregister_driver(&kye_driver);
+}
+
+module_init(kye_init);
+module_exit(kye_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 83e07c9f4144..7b80cb694982 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -326,5 +326,3 @@ static void lg_exit(void)
module_init(lg_init);
module_exit(lg_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(logitech);
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 25b10dcad90d..5e9e37a0506d 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -210,5 +210,3 @@ static void ms_exit(void)
module_init(ms_init);
module_exit(ms_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(microsoft);
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c
index f3a85a065f18..240f87618be6 100644
--- a/drivers/hid/hid-monterey.c
+++ b/drivers/hid/hid-monterey.c
@@ -78,5 +78,3 @@ static void mr_exit(void)
module_init(mr_init);
module_exit(mr_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(monterey);
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index db44fbd7bdf6..c5b252be9c21 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -78,5 +78,3 @@ static void ntrig_exit(void)
module_init(ntrig_init);
module_exit(ntrig_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(ntrig);
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c
index 10945fe12d50..2e83e8ff891a 100644
--- a/drivers/hid/hid-petalynx.c
+++ b/drivers/hid/hid-petalynx.c
@@ -118,5 +118,3 @@ static void pl_exit(void)
module_init(pl_init);
module_exit(pl_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(petalynx);
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
index 46941f979b9d..4db9a3483760 100644
--- a/drivers/hid/hid-pl.c
+++ b/drivers/hid/hid-pl.c
@@ -9,9 +9,12 @@
* - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT)
*
* 0e8f:0003 "GreenAsia Inc. USB Joystick "
- * - tested with K??ng Gaming gamepad
+ * - tested with Knig Gaming gamepad
*
- * Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
+ * 0e8f:0003 "GASIA USB Gamepad"
+ * - another version of the Knig gamepad
+ *
+ * Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com>
*/
/*
@@ -46,6 +49,8 @@
struct plff_device {
struct hid_report *report;
+ s32 *strong;
+ s32 *weak;
};
static int hid_plff_play(struct input_dev *dev, void *data,
@@ -62,8 +67,8 @@ static int hid_plff_play(struct input_dev *dev, void *data,
left = left * 0x7f / 0xffff;
right = right * 0x7f / 0xffff;
- plff->report->field[0]->value[2] = left;
- plff->report->field[0]->value[3] = right;
+ *plff->strong = left;
+ *plff->weak = right;
debug("running with 0x%02x 0x%02x", left, right);
usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
@@ -80,6 +85,8 @@ static int plff_init(struct hid_device *hid)
struct list_head *report_ptr = report_list;
struct input_dev *dev;
int error;
+ s32 *strong;
+ s32 *weak;
/* The device contains one output report per physical device, all
containing 1 field, which contains 4 ff00.0002 usages and 4 16bit
@@ -87,7 +94,12 @@ static int plff_init(struct hid_device *hid)
The input reports also contain a field which contains
8 ff00.0001 usages and 8 boolean values. Their meaning is
- currently unknown. */
+ currently unknown.
+
+ A version of the 0e8f:0003 exists that has all the values in
+ separate fields and misses the extra input field, thus resembling
+ Zeroplus (hid-zpff) devices.
+ */
if (list_empty(report_list)) {
dev_err(&hid->dev, "no output reports found\n");
@@ -110,8 +122,21 @@ static int plff_init(struct hid_device *hid)
return -ENODEV;
}
- if (report->field[0]->report_count < 4) {
- dev_err(&hid->dev, "not enough values in the field\n");
+ if (report->field[0]->report_count >= 4) {
+ report->field[0]->value[0] = 0x00;
+ report->field[0]->value[1] = 0x00;
+ strong = &report->field[0]->value[2];
+ weak = &report->field[0]->value[3];
+ debug("detected single-field device");
+ } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 &&
+ report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) {
+ report->field[0]->value[0] = 0x00;
+ report->field[1]->value[0] = 0x00;
+ strong = &report->field[2]->value[0];
+ weak = &report->field[3]->value[0];
+ debug("detected 4-field device");
+ } else {
+ dev_err(&hid->dev, "not enough fields or values\n");
return -ENODEV;
}
@@ -130,10 +155,11 @@ static int plff_init(struct hid_device *hid)
}
plff->report = report;
- plff->report->field[0]->value[0] = 0x00;
- plff->report->field[0]->value[1] = 0x00;
- plff->report->field[0]->value[2] = 0x00;
- plff->report->field[0]->value[3] = 0x00;
+ plff->strong = strong;
+ plff->weak = weak;
+
+ *strong = 0x00;
+ *weak = 0x00;
usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
}
@@ -180,7 +206,7 @@ static const struct hid_device_id pl_devices[] = {
.driver_data = 1 }, /* Twin USB Joystick */
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR),
.driver_data = 1 }, /* Twin USB Joystick */
- { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, /* GreenAsia Inc. USB Joystick */
+ { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), },
{ }
};
MODULE_DEVICE_TABLE(hid, pl_devices);
@@ -204,5 +230,3 @@ static void pl_exit(void)
module_init(pl_init);
module_exit(pl_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(pantherlord);
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
index 15f3c0492450..07083aa6c19a 100644
--- a/drivers/hid/hid-samsung.c
+++ b/drivers/hid/hid-samsung.c
@@ -96,5 +96,3 @@ static void samsung_exit(void)
module_init(samsung_init);
module_exit(samsung_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(samsung);
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index dd5a3979a4de..c2599388a350 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -148,5 +148,3 @@ static void sony_exit(void)
module_init(sony_init);
module_exit(sony_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(sony);
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c
index 5ba68f7dbb78..e0a8fd36a85b 100644
--- a/drivers/hid/hid-sunplus.c
+++ b/drivers/hid/hid-sunplus.c
@@ -78,5 +78,3 @@ static void sp_exit(void)
module_init(sp_init);
module_exit(sp_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(sunplus);
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index 1b7cba0f7e1f..7c1f7b50330c 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -265,5 +265,3 @@ static void tm_exit(void)
module_init(tm_init);
module_exit(tm_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(thrustmaster);
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c
index cca64a0564a9..152ccfabeba5 100644
--- a/drivers/hid/hid-topseed.c
+++ b/drivers/hid/hid-topseed.c
@@ -73,5 +73,3 @@ static void ts_exit(void)
module_init(ts_init);
module_exit(ts_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(topseed);
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
index ea82f3718b21..85a198a18537 100644
--- a/drivers/hid/hid-zpff.c
+++ b/drivers/hid/hid-zpff.c
@@ -158,5 +158,3 @@ static void zp_exit(void)
module_init(zp_init);
module_exit(zp_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(zeroplus);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 02b19db5442e..e263d4731179 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -181,9 +181,17 @@ static int hidraw_open(struct inode *inode, struct file *file)
dev = hidraw_table[minor];
if (!dev->open++) {
+ if (dev->hid->ll_driver->power) {
+ err = dev->hid->ll_driver->power(dev->hid, PM_HINT_FULLON);
+ if (err < 0)
+ goto out_unlock;
+ }
err = dev->hid->ll_driver->open(dev->hid);
- if (err < 0)
+ if (err < 0) {
+ if (dev->hid->ll_driver->power)
+ dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
dev->open--;
+ }
}
out_unlock:
@@ -209,10 +217,13 @@ static int hidraw_release(struct inode * inode, struct file * file)
list_del(&list->node);
dev = hidraw_table[minor];
if (!--dev->open) {
- if (list->hidraw->exist)
+ if (list->hidraw->exist) {
+ if (dev->hid->ll_driver->power)
+ dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
dev->hid->ll_driver->close(dev->hid);
- else
+ } else {
kfree(list->hidraw);
+ }
}
kfree(list);
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index f0a0f72238ab..4306cb1b8ce5 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -5,6 +5,7 @@
* Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
* Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
* Copyright (c) 2006-2008 Jiri Kosina
+ * Copyright (c) 2007-2008 Oliver Neukum
*/
/*
@@ -27,6 +28,7 @@
#include <asm/byteorder.h>
#include <linux/input.h>
#include <linux/wait.h>
+#include <linux/workqueue.h>
#include <linux/usb.h>
@@ -53,6 +55,10 @@ static unsigned int hid_mousepoll_interval;
module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
+static unsigned int ignoreled;
+module_param_named(ignoreled, ignoreled, uint, 0644);
+MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds");
+
/* Quirks specified at module load time */
static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
module_param_array_named(quirks, quirks_param, charp, NULL, 0444);
@@ -63,8 +69,13 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
/*
* Input submission and I/O error handler.
*/
+static DEFINE_MUTEX(hid_open_mut);
+static struct workqueue_struct *resumption_waker;
static void hid_io_error(struct hid_device *hid);
+static int hid_submit_out(struct hid_device *hid);
+static int hid_submit_ctrl(struct hid_device *hid);
+static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid);
/* Start up the input URB */
static int hid_start_in(struct hid_device *hid)
@@ -73,15 +84,16 @@ static int hid_start_in(struct hid_device *hid)
int rc = 0;
struct usbhid_device *usbhid = hid->driver_data;
- spin_lock_irqsave(&usbhid->inlock, flags);
- if (hid->open > 0 && !test_bit(HID_SUSPENDED, &usbhid->iofl) &&
+ spin_lock_irqsave(&usbhid->lock, flags);
+ if (hid->open > 0 &&
!test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
+ !test_bit(HID_REPORTED_IDLE, &usbhid->iofl) &&
!test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
if (rc != 0)
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
}
- spin_unlock_irqrestore(&usbhid->inlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
return rc;
}
@@ -145,7 +157,7 @@ static void hid_io_error(struct hid_device *hid)
unsigned long flags;
struct usbhid_device *usbhid = hid->driver_data;
- spin_lock_irqsave(&usbhid->inlock, flags);
+ spin_lock_irqsave(&usbhid->lock, flags);
/* Stop when disconnected */
if (test_bit(HID_DISCONNECTED, &usbhid->iofl))
@@ -175,7 +187,51 @@ static void hid_io_error(struct hid_device *hid)
mod_timer(&usbhid->io_retry,
jiffies + msecs_to_jiffies(usbhid->retry_delay));
done:
- spin_unlock_irqrestore(&usbhid->inlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
+}
+
+static void usbhid_mark_busy(struct usbhid_device *usbhid)
+{
+ struct usb_interface *intf = usbhid->intf;
+
+ usb_mark_last_busy(interface_to_usbdev(intf));
+}
+
+static int usbhid_restart_out_queue(struct usbhid_device *usbhid)
+{
+ struct hid_device *hid = usb_get_intfdata(usbhid->intf);
+ int kicked;
+
+ if (!hid)
+ return 0;
+
+ if ((kicked = (usbhid->outhead != usbhid->outtail))) {
+ dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail);
+ if (hid_submit_out(hid)) {
+ clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
+ wake_up(&usbhid->wait);
+ }
+ }
+ return kicked;
+}
+
+static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid)
+{
+ struct hid_device *hid = usb_get_intfdata(usbhid->intf);
+ int kicked;
+
+ WARN_ON(hid == NULL);
+ if (!hid)
+ return 0;
+
+ if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) {
+ dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail);
+ if (hid_submit_ctrl(hid)) {
+ clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+ wake_up(&usbhid->wait);
+ }
+ }
+ return kicked;
}
/*
@@ -190,12 +246,23 @@ static void hid_irq_in(struct urb *urb)
switch (urb->status) {
case 0: /* success */
+ usbhid_mark_busy(usbhid);
usbhid->retry_delay = 0;
hid_input_report(urb->context, HID_INPUT_REPORT,
urb->transfer_buffer,
urb->actual_length, 1);
+ /*
+ * autosuspend refused while keys are pressed
+ * because most keyboards don't wake up when
+ * a key is released
+ */
+ if (hid_check_keys_pressed(hid))
+ set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
+ else
+ clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
break;
case -EPIPE: /* stall */
+ usbhid_mark_busy(usbhid);
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
set_bit(HID_CLEAR_HALT, &usbhid->iofl);
schedule_work(&usbhid->reset_work);
@@ -209,6 +276,7 @@ static void hid_irq_in(struct urb *urb)
case -EPROTO: /* protocol error or unplug */
case -ETIME: /* protocol error or unplug */
case -ETIMEDOUT: /* Should never happen, but... */
+ usbhid_mark_busy(usbhid);
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
hid_io_error(hid);
return;
@@ -239,16 +307,25 @@ static int hid_submit_out(struct hid_device *hid)
report = usbhid->out[usbhid->outtail].report;
raw_report = usbhid->out[usbhid->outtail].raw_report;
- usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
- usbhid->urbout->dev = hid_to_usb_dev(hid);
- memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length);
- kfree(raw_report);
+ if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
+ usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+ usbhid->urbout->dev = hid_to_usb_dev(hid);
+ memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length);
+ kfree(raw_report);
- dbg_hid("submitting out urb\n");
+ dbg_hid("submitting out urb\n");
- if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
- err_hid("usb_submit_urb(out) failed");
- return -1;
+ if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
+ err_hid("usb_submit_urb(out) failed");
+ return -1;
+ }
+ } else {
+ /*
+ * queue work to wake up the device.
+ * as the work queue is freezeable, this is safe
+ * with respect to STD and STR
+ */
+ queue_work(resumption_waker, &usbhid->restart_work);
}
return 0;
@@ -266,41 +343,50 @@ static int hid_submit_ctrl(struct hid_device *hid)
raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
dir = usbhid->ctrl[usbhid->ctrltail].dir;
- len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
- if (dir == USB_DIR_OUT) {
- usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
- usbhid->urbctrl->transfer_buffer_length = len;
- memcpy(usbhid->ctrlbuf, raw_report, len);
- kfree(raw_report);
- } else {
- int maxpacket, padlen;
-
- usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
- maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
- if (maxpacket > 0) {
- padlen = DIV_ROUND_UP(len, maxpacket);
- padlen *= maxpacket;
- if (padlen > usbhid->bufsize)
- padlen = usbhid->bufsize;
- } else
- padlen = 0;
- usbhid->urbctrl->transfer_buffer_length = padlen;
- }
- usbhid->urbctrl->dev = hid_to_usb_dev(hid);
+ if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
+ len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+ if (dir == USB_DIR_OUT) {
+ usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
+ usbhid->urbctrl->transfer_buffer_length = len;
+ memcpy(usbhid->ctrlbuf, raw_report, len);
+ kfree(raw_report);
+ } else {
+ int maxpacket, padlen;
+
+ usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
+ maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
+ if (maxpacket > 0) {
+ padlen = DIV_ROUND_UP(len, maxpacket);
+ padlen *= maxpacket;
+ if (padlen > usbhid->bufsize)
+ padlen = usbhid->bufsize;
+ } else
+ padlen = 0;
+ usbhid->urbctrl->transfer_buffer_length = padlen;
+ }
+ usbhid->urbctrl->dev = hid_to_usb_dev(hid);
- usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
- usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
- usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
- usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
- usbhid->cr->wLength = cpu_to_le16(len);
+ usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
+ usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
+ usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
+ usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
+ usbhid->cr->wLength = cpu_to_le16(len);
- dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
- usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
- usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
+ dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
+ usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
+ usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
- if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
- err_hid("usb_submit_urb(ctrl) failed");
- return -1;
+ if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
+ err_hid("usb_submit_urb(ctrl) failed");
+ return -1;
+ }
+ } else {
+ /*
+ * queue work to wake up the device.
+ * as the work queue is freezeable, this is safe
+ * with respect to STD and STR
+ */
+ queue_work(resumption_waker, &usbhid->restart_work);
}
return 0;
@@ -332,7 +418,7 @@ static void hid_irq_out(struct urb *urb)
"received\n", urb->status);
}
- spin_lock_irqsave(&usbhid->outlock, flags);
+ spin_lock_irqsave(&usbhid->lock, flags);
if (unplug)
usbhid->outtail = usbhid->outhead;
@@ -344,12 +430,12 @@ static void hid_irq_out(struct urb *urb)
clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
wake_up(&usbhid->wait);
}
- spin_unlock_irqrestore(&usbhid->outlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
return;
}
clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
- spin_unlock_irqrestore(&usbhid->outlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
wake_up(&usbhid->wait);
}
@@ -361,12 +447,11 @@ static void hid_ctrl(struct urb *urb)
{
struct hid_device *hid = urb->context;
struct usbhid_device *usbhid = hid->driver_data;
- unsigned long flags;
- int unplug = 0;
+ int unplug = 0, status = urb->status;
- spin_lock_irqsave(&usbhid->ctrllock, flags);
+ spin_lock(&usbhid->lock);
- switch (urb->status) {
+ switch (status) {
case 0: /* success */
if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
hid_input_report(urb->context,
@@ -383,7 +468,7 @@ static void hid_ctrl(struct urb *urb)
break;
default: /* error */
dev_warn(&urb->dev->dev, "ctrl urb status %d "
- "received\n", urb->status);
+ "received\n", status);
}
if (unplug)
@@ -396,19 +481,18 @@ static void hid_ctrl(struct urb *urb)
clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
wake_up(&usbhid->wait);
}
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+ spin_unlock(&usbhid->lock);
return;
}
clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+ spin_unlock(&usbhid->lock);
wake_up(&usbhid->wait);
}
-void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
{
int head;
- unsigned long flags;
struct usbhid_device *usbhid = hid->driver_data;
int len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
@@ -416,18 +500,13 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
return;
if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
-
- spin_lock_irqsave(&usbhid->outlock, flags);
-
if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) {
- spin_unlock_irqrestore(&usbhid->outlock, flags);
dev_warn(&hid->dev, "output queue full\n");
return;
}
usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
if (!usbhid->out[usbhid->outhead].raw_report) {
- spin_unlock_irqrestore(&usbhid->outlock, flags);
dev_warn(&hid->dev, "output queueing failed\n");
return;
}
@@ -438,15 +517,10 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl))
if (hid_submit_out(hid))
clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
-
- spin_unlock_irqrestore(&usbhid->outlock, flags);
return;
}
- spin_lock_irqsave(&usbhid->ctrllock, flags);
-
if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) {
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
dev_warn(&hid->dev, "control queue full\n");
return;
}
@@ -454,7 +528,6 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
if (dir == USB_DIR_OUT) {
usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
dev_warn(&hid->dev, "control queueing failed\n");
return;
}
@@ -467,15 +540,25 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl))
if (hid_submit_ctrl(hid))
clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+}
+
+void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+ unsigned long flags;
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+ spin_lock_irqsave(&usbhid->lock, flags);
+ __usbhid_submit_report(hid, report, dir);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
}
EXPORT_SYMBOL_GPL(usbhid_submit_report);
static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
struct hid_device *hid = input_get_drvdata(dev);
+ struct usbhid_device *usbhid = hid->driver_data;
struct hid_field *field;
+ unsigned long flags;
int offset;
if (type == EV_FF)
@@ -490,6 +573,15 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un
}
hid_set_field(field, offset, value);
+ if (value) {
+ spin_lock_irqsave(&usbhid->lock, flags);
+ usbhid->ledcount++;
+ spin_unlock_irqrestore(&usbhid->lock, flags);
+ } else {
+ spin_lock_irqsave(&usbhid->lock, flags);
+ usbhid->ledcount--;
+ spin_unlock_irqrestore(&usbhid->lock, flags);
+ }
usbhid_submit_report(hid, field->report, USB_DIR_OUT);
return 0;
@@ -538,15 +630,22 @@ int usbhid_open(struct hid_device *hid)
struct usbhid_device *usbhid = hid->driver_data;
int res;
+ mutex_lock(&hid_open_mut);
if (!hid->open++) {
res = usb_autopm_get_interface(usbhid->intf);
+ /* the device must be awake to reliable request remote wakeup */
if (res < 0) {
hid->open--;
+ mutex_unlock(&hid_open_mut);
return -EIO;
}
+ usbhid->intf->needs_remote_wakeup = 1;
+ if (hid_start_in(hid))
+ hid_io_error(hid);
+
+ usb_autopm_put_interface(usbhid->intf);
}
- if (hid_start_in(hid))
- hid_io_error(hid);
+ mutex_unlock(&hid_open_mut);
return 0;
}
@@ -554,10 +653,22 @@ void usbhid_close(struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;
+ mutex_lock(&hid_open_mut);
+
+ /* protecting hid->open to make sure we don't restart
+ * data acquistion due to a resumption we no longer
+ * care about
+ */
+ spin_lock_irq(&usbhid->lock);
if (!--hid->open) {
+ spin_unlock_irq(&usbhid->lock);
usb_kill_urb(usbhid->urbin);
- usb_autopm_put_interface(usbhid->intf);
+ flush_scheduled_work();
+ usbhid->intf->needs_remote_wakeup = 0;
+ } else {
+ spin_unlock_irq(&usbhid->lock);
}
+ mutex_unlock(&hid_open_mut);
}
/*
@@ -687,6 +798,25 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
return ret;
}
+static void usbhid_restart_queues(struct usbhid_device *usbhid)
+{
+ if (usbhid->urbout)
+ usbhid_restart_out_queue(usbhid);
+ usbhid_restart_ctrl_queue(usbhid);
+}
+
+static void __usbhid_restart_queues(struct work_struct *work)
+{
+ struct usbhid_device *usbhid =
+ container_of(work, struct usbhid_device, restart_work);
+ int r;
+
+ r = usb_autopm_get_interface(usbhid->intf);
+ if (r < 0)
+ return;
+ usb_autopm_put_interface(usbhid->intf);
+}
+
static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;
@@ -711,6 +841,9 @@ static int usbhid_parse(struct hid_device *hid)
quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
+ if (quirks & HID_QUIRK_IGNORE)
+ return -ENODEV;
+
/* Many keyboards and mice don't like to be polled for reports,
* so we will always set the HID_QUIRK_NOGET flag for them. */
if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
@@ -850,11 +983,11 @@ static int usbhid_start(struct hid_device *hid)
init_waitqueue_head(&usbhid->wait);
INIT_WORK(&usbhid->reset_work, hid_reset);
+ INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
- spin_lock_init(&usbhid->inlock);
- spin_lock_init(&usbhid->outlock);
- spin_lock_init(&usbhid->ctrllock);
+ spin_lock_init(&usbhid->lock);
+ spin_lock_init(&usbhid->lock);
usbhid->intf = intf;
usbhid->ifnum = interface->desc.bInterfaceNumber;
@@ -906,15 +1039,14 @@ static void usbhid_stop(struct hid_device *hid)
return;
clear_bit(HID_STARTED, &usbhid->iofl);
- spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
+ spin_lock_irq(&usbhid->lock); /* Sync with error handler */
set_bit(HID_DISCONNECTED, &usbhid->iofl);
- spin_unlock_irq(&usbhid->inlock);
+ spin_unlock_irq(&usbhid->lock);
usb_kill_urb(usbhid->urbin);
usb_kill_urb(usbhid->urbout);
usb_kill_urb(usbhid->urbctrl);
- del_timer_sync(&usbhid->io_retry);
- cancel_work_sync(&usbhid->reset_work);
+ hid_cancel_delayed_stuff(usbhid);
if (hid->claimed & HID_CLAIMED_INPUT)
hidinput_disconnect(hid);
@@ -935,12 +1067,28 @@ static void usbhid_stop(struct hid_device *hid)
hid_free_buffers(hid_to_usb_dev(hid), hid);
}
+static int usbhid_power(struct hid_device *hid, int lvl)
+{
+ int r = 0;
+
+ switch (lvl) {
+ case PM_HINT_FULLON:
+ r = usbhid_get_power(hid);
+ break;
+ case PM_HINT_NORMAL:
+ usbhid_put_power(hid);
+ break;
+ }
+ return r;
+}
+
static struct hid_ll_driver usb_hid_driver = {
.parse = usbhid_parse,
.start = usbhid_start,
.stop = usbhid_stop,
.open = usbhid_open,
.close = usbhid_close,
+ .power = usbhid_power,
.hidinput_input_event = usb_hidinput_input_event,
};
@@ -1049,19 +1197,126 @@ static void hid_disconnect(struct usb_interface *intf)
kfree(usbhid);
}
+static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
+{
+ del_timer_sync(&usbhid->io_retry);
+ cancel_work_sync(&usbhid->restart_work);
+ cancel_work_sync(&usbhid->reset_work);
+}
+
+static void hid_cease_io(struct usbhid_device *usbhid)
+{
+ del_timer(&usbhid->io_retry);
+ usb_kill_urb(usbhid->urbin);
+ usb_kill_urb(usbhid->urbctrl);
+ usb_kill_urb(usbhid->urbout);
+}
+
+/* Treat USB reset pretty much the same as suspend/resume */
+static int hid_pre_reset(struct usb_interface *intf)
+{
+ struct hid_device *hid = usb_get_intfdata(intf);
+ struct usbhid_device *usbhid = hid->driver_data;
+
+ spin_lock_irq(&usbhid->lock);
+ set_bit(HID_RESET_PENDING, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ cancel_work_sync(&usbhid->restart_work);
+ hid_cease_io(usbhid);
+
+ return 0;
+}
+
+/* Same routine used for post_reset and reset_resume */
+static int hid_post_reset(struct usb_interface *intf)
+{
+ struct usb_device *dev = interface_to_usbdev (intf);
+ struct hid_device *hid = usb_get_intfdata(intf);
+ struct usbhid_device *usbhid = hid->driver_data;
+ int status;
+
+ spin_lock_irq(&usbhid->lock);
+ clear_bit(HID_RESET_PENDING, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
+ /* FIXME: Any more reinitialization needed? */
+ status = hid_start_in(hid);
+ if (status < 0)
+ hid_io_error(hid);
+ usbhid_restart_queues(usbhid);
+
+ return 0;
+}
+
+int usbhid_get_power(struct hid_device *hid)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+
+ return usb_autopm_get_interface(usbhid->intf);
+}
+
+void usbhid_put_power(struct hid_device *hid)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+
+ usb_autopm_put_interface(usbhid->intf);
+}
+
+
+#ifdef CONFIG_PM
static int hid_suspend(struct usb_interface *intf, pm_message_t message)
{
- struct hid_device *hid = usb_get_intfdata (intf);
+ struct hid_device *hid = usb_get_intfdata(intf);
struct usbhid_device *usbhid = hid->driver_data;
+ struct usb_device *udev = interface_to_usbdev(intf);
+ int status;
- if (!test_bit(HID_STARTED, &usbhid->iofl))
- return 0;
+ if (udev->auto_pm) {
+ spin_lock_irq(&usbhid->lock); /* Sync with error handler */
+ if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
+ && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
+ && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)
+ && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl)
+ && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl)
+ && (!usbhid->ledcount || ignoreled))
+ {
+ set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ } else {
+ usbhid_mark_busy(usbhid);
+ spin_unlock_irq(&usbhid->lock);
+ return -EBUSY;
+ }
- spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
- set_bit(HID_SUSPENDED, &usbhid->iofl);
- spin_unlock_irq(&usbhid->inlock);
- del_timer_sync(&usbhid->io_retry);
- usb_kill_urb(usbhid->urbin);
+ } else {
+ spin_lock_irq(&usbhid->lock);
+ set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ if (usbhid_wait_io(hid) < 0)
+ return -EIO;
+ }
+
+ if (!ignoreled && udev->auto_pm) {
+ spin_lock_irq(&usbhid->lock);
+ if (test_bit(HID_LED_ON, &usbhid->iofl)) {
+ spin_unlock_irq(&usbhid->lock);
+ usbhid_mark_busy(usbhid);
+ return -EBUSY;
+ }
+ spin_unlock_irq(&usbhid->lock);
+ }
+
+ hid_cancel_delayed_stuff(usbhid);
+ hid_cease_io(usbhid);
+
+ if (udev->auto_pm && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
+ /* lost race against keypresses */
+ status = hid_start_in(hid);
+ if (status < 0)
+ hid_io_error(hid);
+ usbhid_mark_busy(usbhid);
+ return -EBUSY;
+ }
dev_dbg(&intf->dev, "suspend\n");
return 0;
}
@@ -1075,32 +1330,33 @@ static int hid_resume(struct usb_interface *intf)
if (!test_bit(HID_STARTED, &usbhid->iofl))
return 0;
- clear_bit(HID_SUSPENDED, &usbhid->iofl);
+ clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ usbhid_mark_busy(usbhid);
+
+ if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
+ test_bit(HID_RESET_PENDING, &usbhid->iofl))
+ schedule_work(&usbhid->reset_work);
usbhid->retry_delay = 0;
status = hid_start_in(hid);
- dev_dbg(&intf->dev, "resume status %d\n", status);
- return status;
-}
+ if (status < 0)
+ hid_io_error(hid);
+ usbhid_restart_queues(usbhid);
-/* Treat USB reset pretty much the same as suspend/resume */
-static int hid_pre_reset(struct usb_interface *intf)
-{
- /* FIXME: What if the interface is already suspended? */
- hid_suspend(intf, PMSG_ON);
+ dev_dbg(&intf->dev, "resume status %d\n", status);
return 0;
}
-/* Same routine used for post_reset and reset_resume */
-static int hid_post_reset(struct usb_interface *intf)
+static int hid_reset_resume(struct usb_interface *intf)
{
- struct usb_device *dev = interface_to_usbdev (intf);
-
- hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
- /* FIXME: Any more reinitialization needed? */
+ struct hid_device *hid = usb_get_intfdata(intf);
+ struct usbhid_device *usbhid = hid->driver_data;
- return hid_resume(intf);
+ clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ return hid_post_reset(intf);
}
+#endif /* CONFIG_PM */
+
static struct usb_device_id hid_usb_ids [] = {
{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
.bInterfaceClass = USB_INTERFACE_CLASS_HID },
@@ -1113,9 +1369,11 @@ static struct usb_driver hid_driver = {
.name = "usbhid",
.probe = hid_probe,
.disconnect = hid_disconnect,
+#ifdef CONFIG_PM
.suspend = hid_suspend,
.resume = hid_resume,
- .reset_resume = hid_post_reset,
+ .reset_resume = hid_reset_resume,
+#endif
.pre_reset = hid_pre_reset,
.post_reset = hid_post_reset,
.id_table = hid_usb_ids,
@@ -1134,7 +1392,11 @@ static struct hid_driver hid_usb_driver = {
static int __init hid_init(void)
{
- int retval;
+ int retval = -ENOMEM;
+
+ resumption_waker = create_freezeable_workqueue("usbhid_resumer");
+ if (!resumption_waker)
+ goto no_queue;
retval = hid_register_driver(&hid_usb_driver);
if (retval)
goto hid_register_fail;
@@ -1158,6 +1420,8 @@ hiddev_init_fail:
usbhid_quirks_init_fail:
hid_unregister_driver(&hid_usb_driver);
hid_register_fail:
+ destroy_workqueue(resumption_waker);
+no_queue:
return retval;
}
@@ -1167,6 +1431,7 @@ static void __exit hid_exit(void)
hiddev_exit();
usbhid_quirks_exit();
hid_unregister_driver(&hid_usb_driver);
+ destroy_workqueue(resumption_waker);
}
module_init(hid_init);
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 1f5b5d4c3c34..e9b436d2d944 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -227,12 +227,9 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
*/
static int hiddev_fasync(int fd, struct file *file, int on)
{
- int retval;
struct hiddev_list *list = file->private_data;
- retval = fasync_helper(fd, file, on, &list->fasync);
-
- return retval < 0 ? retval : 0;
+ return fasync_helper(fd, file, on, &list->fasync);
}
@@ -249,10 +246,12 @@ static int hiddev_release(struct inode * inode, struct file * file)
spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
if (!--list->hiddev->open) {
- if (list->hiddev->exist)
+ if (list->hiddev->exist) {
usbhid_close(list->hiddev->hid);
- else
+ usbhid_put_power(list->hiddev->hid);
+ } else {
kfree(list->hiddev);
+ }
}
kfree(list);
@@ -303,6 +302,17 @@ static int hiddev_open(struct inode *inode, struct file *file)
list_add_tail(&list->node, &hiddev_table[i]->list);
spin_unlock_irq(&list->hiddev->list_lock);
+ if (!list->hiddev->open++)
+ if (list->hiddev->exist) {
+ struct hid_device *hid = hiddev_table[i]->hid;
+ res = usbhid_get_power(hid);
+ if (res < 0) {
+ res = -EIO;
+ goto bail;
+ }
+ usbhid_open(hid);
+ }
+
return 0;
bail:
file->private_data = NULL;
@@ -878,16 +888,21 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
hiddev->hid = hid;
hiddev->exist = 1;
+ /* when lock_kernel() usage is fixed in usb_open(),
+ * we could also fix it here */
+ lock_kernel();
retval = usb_register_dev(usbhid->intf, &hiddev_class);
if (retval) {
err_hid("Not able to get a minor for this device.");
hid->hiddev = NULL;
+ unlock_kernel();
kfree(hiddev);
return -1;
} else {
hid->minor = usbhid->intf->minor;
hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
}
+ unlock_kernel();
return 0;
}
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
index 9eb30564be9c..08f505ca2e3d 100644
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -38,7 +38,10 @@ int usbhid_wait_io(struct hid_device* hid);
void usbhid_close(struct hid_device *hid);
int usbhid_open(struct hid_device *hid);
void usbhid_init_reports(struct hid_device *hid);
-void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir);
+void usbhid_submit_report
+(struct hid_device *hid, struct hid_report *report, unsigned char dir);
+int usbhid_get_power(struct hid_device *hid);
+void usbhid_put_power(struct hid_device *hid);
/* iofl flags */
#define HID_CTRL_RUNNING 1
@@ -49,6 +52,9 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
#define HID_CLEAR_HALT 6
#define HID_DISCONNECTED 7
#define HID_STARTED 8
+#define HID_REPORTED_IDLE 9
+#define HID_KEYS_PRESSED 10
+#define HID_LED_ON 11
/*
* USB-specific HID struct, to be pointed to
@@ -66,7 +72,6 @@ struct usbhid_device {
struct urb *urbin; /* Input URB */
char *inbuf; /* Input buffer */
dma_addr_t inbuf_dma; /* Input buffer dma */
- spinlock_t inlock; /* Input fifo spinlock */
struct urb *urbctrl; /* Control URB */
struct usb_ctrlrequest *cr; /* Control request struct */
@@ -75,21 +80,22 @@ struct usbhid_device {
unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */
char *ctrlbuf; /* Control buffer */
dma_addr_t ctrlbuf_dma; /* Control buffer dma */
- spinlock_t ctrllock; /* Control fifo spinlock */
struct urb *urbout; /* Output URB */
struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */
unsigned char outhead, outtail; /* Output pipe fifo head & tail */
char *outbuf; /* Output buffer */
dma_addr_t outbuf_dma; /* Output buffer dma */
- spinlock_t outlock; /* Output fifo spinlock */
+ spinlock_t lock; /* fifo spinlock */
unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
struct timer_list io_retry; /* Retry timer */
unsigned long stop_retry; /* Time to give up, in jiffies */
unsigned int retry_delay; /* Delay length in ms */
struct work_struct reset_work; /* Task context for resets */
+ struct work_struct restart_work; /* waking up for output to be done in a task */
wait_queue_head_t wait; /* For sleeping */
+ int ledcount; /* counting the number of active leds */
};
#define hid_to_usb_dev(hid_dev) \
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index b4eea0292c1a..ce52bf2f235e 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -343,12 +343,13 @@ config SENSORS_FSCPOS
will be called fscpos.
config SENSORS_FSCHMD
- tristate "FSC Poseidon, Scylla, Hermes, Heimdall and Heracles"
+ tristate "Fujitsu Siemens Computers sensor chips"
depends on X86 && I2C
help
- If you say yes here you get support for various Fujitsu Siemens
- Computers sensor chips, including support for the integrated
- watchdog.
+ If you say yes here you get support for the following Fujitsu
+ Siemens Computers (FSC) sensor chips: Poseidon, Scylla, Hermes,
+ Heimdall, Heracles, Hades and Syleus including support for the
+ integrated watchdog.
This is a merged driver for FSC sensor chips replacing the fscpos,
fscscy and fscher drivers and adding support for several other FSC
@@ -570,6 +571,17 @@ config SENSORS_LM93
This driver can also be built as a module. If so, the module
will be called lm93.
+config SENSORS_LTC4215
+ tristate "Linear Technology LTC4215"
+ depends on I2C && EXPERIMENTAL
+ default n
+ help
+ If you say yes here you get support for Linear Technology LTC4215
+ Hot Swap Controller I2C interface.
+
+ This driver can also be built as a module. If so, the module will
+ be called ltc4215.
+
config SENSORS_LTC4245
tristate "Linear Technology LTC4245"
depends on I2C && EXPERIMENTAL
@@ -581,6 +593,15 @@ config SENSORS_LTC4245
This driver can also be built as a module. If so, the module will
be called ltc4245.
+config SENSORS_LM95241
+ tristate "National Semiconductor LM95241 sensor chip"
+ depends on I2C
+ help
+ If you say yes here you get support for LM95241 sensor chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm95241.
+
config SENSORS_MAX1111
tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip"
depends on SPI_MASTER
@@ -635,6 +656,20 @@ config SENSORS_PC87427
This driver can also be built as a module. If so, the module
will be called pc87427.
+config SENSORS_PCF8591
+ tristate "Philips PCF8591 ADC/DAC"
+ depends on I2C
+ default n
+ help
+ If you say yes here you get support for Philips PCF8591 4-channel
+ ADC, 1-channel DAC chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called pcf8591.
+
+ These devices are hard to detect and rarely found on mainstream
+ hardware. If unsure, say N.
+
config SENSORS_SIS5595
tristate "Silicon Integrated Systems Corp. SiS5595"
depends on PCI
@@ -827,7 +862,7 @@ config SENSORS_W83627HF
will be called w83627hf.
config SENSORS_W83627EHF
- tristate "Winbond W83627EHF/DHG"
+ tristate "Winbond W83627EHF/EHG/DHG, W83667HG"
select HWMON_VID
help
If you say yes here you get support for the hardware
@@ -838,6 +873,8 @@ config SENSORS_W83627EHF
chip suited for specific Intel processors that use PECI such as
the Core 2 Duo.
+ This driver also supports the W83667HG chip.
+
This driver can also be built as a module. If so, the module
will be called w83627ehf.
@@ -895,6 +932,22 @@ config SENSORS_LIS3LV02D
Say Y here if you have an applicable laptop and want to experience
the awesome power of lis3lv02d.
+config SENSORS_LIS3_SPI
+ tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)"
+ depends on !ACPI && SPI_MASTER && INPUT
+ default n
+ help
+ This driver provides support for the LIS3LV02Dx accelerometer connected
+ via SPI. The accelerometer data is readable via
+ /sys/devices/platform/lis3lv02d.
+
+ This driver also provides an absolute input class device, allowing
+ the laptop to act as a pinball machine-esque joystick.
+
+ This driver can also be built as modules. If so, the core module
+ will be called lis3lv02d and a specific module for the SPI transport
+ is called lis3lv02d_spi.
+
config SENSORS_APPLESMC
tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
depends on INPUT && X86
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 2e80f37f39eb..3a6b1f06f8f4 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o
obj-$(CONFIG_SENSORS_IT87) += it87.o
obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o
obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o
+obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d.o lis3lv02d_spi.o
obj-$(CONFIG_SENSORS_LM63) += lm63.o
obj-$(CONFIG_SENSORS_LM70) += lm70.o
obj-$(CONFIG_SENSORS_LM75) += lm75.o
@@ -64,12 +65,15 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o
obj-$(CONFIG_SENSORS_LM90) += lm90.o
obj-$(CONFIG_SENSORS_LM92) += lm92.o
obj-$(CONFIG_SENSORS_LM93) += lm93.o
+obj-$(CONFIG_SENSORS_LM95241) += lm95241.o
+obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o
obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o
obj-$(CONFIG_SENSORS_MAX1111) += max1111.o
obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
+obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index 7415381601c3..53f88f511816 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -81,71 +81,84 @@ struct ds1621_data {
u8 conf; /* Register encoding, combined */
};
-static int ds1621_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int ds1621_detect(struct i2c_client *client, int kind,
- struct i2c_board_info *info);
-static void ds1621_init_client(struct i2c_client *client);
-static int ds1621_remove(struct i2c_client *client);
-static struct ds1621_data *ds1621_update_client(struct device *dev);
-
-static const struct i2c_device_id ds1621_id[] = {
- { "ds1621", ds1621 },
- { "ds1625", ds1621 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ds1621_id);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver ds1621_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "ds1621",
- },
- .probe = ds1621_probe,
- .remove = ds1621_remove,
- .id_table = ds1621_id,
- .detect = ds1621_detect,
- .address_data = &addr_data,
-};
-
-/* All registers are word-sized, except for the configuration register.
+/* Temperature registers are word-sized.
DS1621 uses a high-byte first convention, which is exactly opposite to
the SMBus standard. */
-static int ds1621_read_value(struct i2c_client *client, u8 reg)
+static int ds1621_read_temp(struct i2c_client *client, u8 reg)
{
- if (reg == DS1621_REG_CONF)
- return i2c_smbus_read_byte_data(client, reg);
- else
- return swab16(i2c_smbus_read_word_data(client, reg));
+ int ret;
+
+ ret = i2c_smbus_read_word_data(client, reg);
+ if (ret < 0)
+ return ret;
+ return swab16(ret);
}
-static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value)
+static int ds1621_write_temp(struct i2c_client *client, u8 reg, u16 value)
{
- if (reg == DS1621_REG_CONF)
- return i2c_smbus_write_byte_data(client, reg, value);
- else
- return i2c_smbus_write_word_data(client, reg, swab16(value));
+ return i2c_smbus_write_word_data(client, reg, swab16(value));
}
static void ds1621_init_client(struct i2c_client *client)
{
- int reg = ds1621_read_value(client, DS1621_REG_CONF);
+ u8 conf, new_conf;
+
+ new_conf = conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
/* switch to continuous conversion mode */
- reg &= ~ DS1621_REG_CONFIG_1SHOT;
+ new_conf &= ~DS1621_REG_CONFIG_1SHOT;
/* setup output polarity */
if (polarity == 0)
- reg &= ~DS1621_REG_CONFIG_POLARITY;
+ new_conf &= ~DS1621_REG_CONFIG_POLARITY;
else if (polarity == 1)
- reg |= DS1621_REG_CONFIG_POLARITY;
+ new_conf |= DS1621_REG_CONFIG_POLARITY;
- ds1621_write_value(client, DS1621_REG_CONF, reg);
+ if (conf != new_conf)
+ i2c_smbus_write_byte_data(client, DS1621_REG_CONF, new_conf);
/* start conversion */
i2c_smbus_write_byte(client, DS1621_COM_START);
}
+static struct ds1621_data *ds1621_update_client(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ds1621_data *data = i2c_get_clientdata(client);
+ u8 new_conf;
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ int i;
+
+ dev_dbg(&client->dev, "Starting ds1621 update\n");
+
+ data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
+
+ for (i = 0; i < ARRAY_SIZE(data->temp); i++)
+ data->temp[i] = ds1621_read_temp(client,
+ DS1621_REG_TEMP[i]);
+
+ /* reset alarms if necessary */
+ new_conf = data->conf;
+ if (data->temp[0] > data->temp[1]) /* input > min */
+ new_conf &= ~DS1621_ALARM_TEMP_LOW;
+ if (data->temp[0] < data->temp[2]) /* input < max */
+ new_conf &= ~DS1621_ALARM_TEMP_HIGH;
+ if (data->conf != new_conf)
+ i2c_smbus_write_byte_data(client, DS1621_REG_CONF,
+ new_conf);
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
static ssize_t show_temp(struct device *dev, struct device_attribute *da,
char *buf)
{
@@ -160,13 +173,13 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
- struct ds1621_data *data = ds1621_update_client(dev);
+ struct ds1621_data *data = i2c_get_clientdata(client);
u16 val = LM75_TEMP_TO_REG(simple_strtol(buf, NULL, 10));
mutex_lock(&data->update_lock);
data->temp[attr->index] = val;
- ds1621_write_value(client, DS1621_REG_TEMP[attr->index],
- data->temp[attr->index]);
+ ds1621_write_temp(client, DS1621_REG_TEMP[attr->index],
+ data->temp[attr->index]);
mutex_unlock(&data->update_lock);
return count;
}
@@ -228,13 +241,14 @@ static int ds1621_detect(struct i2c_client *client, int kind,
/* The NVB bit should be low if no EEPROM write has been
requested during the latest 10ms, which is highly
improbable in our case. */
- conf = ds1621_read_value(client, DS1621_REG_CONF);
- if (conf & DS1621_REG_CONFIG_NVB)
+ conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
+ if (conf < 0 || conf & DS1621_REG_CONFIG_NVB)
return -ENODEV;
/* The 7 lowest bits of a temperature should always be 0. */
for (i = 0; i < ARRAY_SIZE(DS1621_REG_TEMP); i++) {
- temp = ds1621_read_value(client, DS1621_REG_TEMP[i]);
- if (temp & 0x007f)
+ temp = i2c_smbus_read_word_data(client,
+ DS1621_REG_TEMP[i]);
+ if (temp < 0 || (temp & 0x7f00))
return -ENODEV;
}
}
@@ -294,45 +308,25 @@ static int ds1621_remove(struct i2c_client *client)
return 0;
}
+static const struct i2c_device_id ds1621_id[] = {
+ { "ds1621", ds1621 },
+ { "ds1625", ds1621 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ds1621_id);
-static struct ds1621_data *ds1621_update_client(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct ds1621_data *data = i2c_get_clientdata(client);
- u8 new_conf;
-
- mutex_lock(&data->update_lock);
-
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
- int i;
-
- dev_dbg(&client->dev, "Starting ds1621 update\n");
-
- data->conf = ds1621_read_value(client, DS1621_REG_CONF);
-
- for (i = 0; i < ARRAY_SIZE(data->temp); i++)
- data->temp[i] = ds1621_read_value(client,
- DS1621_REG_TEMP[i]);
-
- /* reset alarms if necessary */
- new_conf = data->conf;
- if (data->temp[0] > data->temp[1]) /* input > min */
- new_conf &= ~DS1621_ALARM_TEMP_LOW;
- if (data->temp[0] < data->temp[2]) /* input < max */
- new_conf &= ~DS1621_ALARM_TEMP_HIGH;
- if (data->conf != new_conf)
- ds1621_write_value(client, DS1621_REG_CONF,
- new_conf);
-
- data->last_updated = jiffies;
- data->valid = 1;
- }
-
- mutex_unlock(&data->update_lock);
-
- return data;
-}
+/* This is the driver that will be inserted */
+static struct i2c_driver ds1621_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "ds1621",
+ },
+ .probe = ds1621_probe,
+ .remove = ds1621_remove,
+ .id_table = ds1621_id,
+ .detect = ds1621_detect,
+ .address_data = &addr_data,
+};
static int __init ds1621_init(void)
{
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 18a1ba888165..e2107e533ede 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -1,7 +1,7 @@
/*
* f75375s.c - driver for the Fintek F75375/SP and F75373
* hardware monitoring features
- * Copyright (C) 2006-2007 Riku Voipio <riku.voipio@movial.fi>
+ * Copyright (C) 2006-2007 Riku Voipio
*
* Datasheets available at:
*
@@ -721,7 +721,7 @@ static void __exit sensors_f75375_exit(void)
i2c_del_driver(&f75375_driver);
}
-MODULE_AUTHOR("Riku Voipio <riku.voipio@movial.fi>");
+MODULE_AUTHOR("Riku Voipio");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("F75373/F75375 hardware monitoring driver");
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index d07f4ef75092..ea955edde87e 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -1,6 +1,6 @@
/* fschmd.c
*
- * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com>
+ * Copyright (C) 2007 - 2009 Hans de Goede <hdegoede@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
/*
* Merged Fujitsu Siemens hwmon driver, supporting the Poseidon, Hermes,
- * Scylla, Heracles and Heimdall chips
+ * Scylla, Heracles, Heimdall, Hades and Syleus chips
*
* Based on the original 2.4 fscscy, 2.6 fscpos, 2.6 fscher and 2.6
* (candidate) fschmd drivers:
@@ -56,7 +56,7 @@ static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
+I2C_CLIENT_INSMOD_7(fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl);
/*
* The FSCHMD registers and other defines
@@ -75,9 +75,12 @@ I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
#define FSCHMD_CONTROL_ALERT_LED 0x01
/* watchdog */
-#define FSCHMD_REG_WDOG_PRESET 0x28
-#define FSCHMD_REG_WDOG_STATE 0x23
-#define FSCHMD_REG_WDOG_CONTROL 0x21
+static const u8 FSCHMD_REG_WDOG_CONTROL[7] =
+ { 0x21, 0x21, 0x21, 0x21, 0x21, 0x28, 0x28 };
+static const u8 FSCHMD_REG_WDOG_STATE[7] =
+ { 0x23, 0x23, 0x23, 0x23, 0x23, 0x29, 0x29 };
+static const u8 FSCHMD_REG_WDOG_PRESET[7] =
+ { 0x28, 0x28, 0x28, 0x28, 0x28, 0x2a, 0x2a };
#define FSCHMD_WDOG_CONTROL_TRIGGER 0x10
#define FSCHMD_WDOG_CONTROL_STARTED 0x10 /* the same as trigger */
@@ -87,70 +90,95 @@ I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
#define FSCHMD_WDOG_STATE_CARDRESET 0x02
/* voltages, weird order is to keep the same order as the old drivers */
-static const u8 FSCHMD_REG_VOLT[3] = { 0x45, 0x42, 0x48 };
+static const u8 FSCHMD_REG_VOLT[7][6] = {
+ { 0x45, 0x42, 0x48 }, /* pos */
+ { 0x45, 0x42, 0x48 }, /* her */
+ { 0x45, 0x42, 0x48 }, /* scy */
+ { 0x45, 0x42, 0x48 }, /* hrc */
+ { 0x45, 0x42, 0x48 }, /* hmd */
+ { 0x21, 0x20, 0x22 }, /* hds */
+ { 0x21, 0x20, 0x22, 0x23, 0x24, 0x25 }, /* syl */
+};
+
+static const int FSCHMD_NO_VOLT_SENSORS[7] = { 3, 3, 3, 3, 3, 3, 6 };
/* minimum pwm at which the fan is driven (pwm can by increased depending on
the temp. Notice that for the scy some fans share there minimum speed.
Also notice that with the scy the sensor order is different than with the
other chips, this order was in the 2.4 driver and kept for consistency. */
-static const u8 FSCHMD_REG_FAN_MIN[5][6] = {
+static const u8 FSCHMD_REG_FAN_MIN[7][7] = {
{ 0x55, 0x65 }, /* pos */
{ 0x55, 0x65, 0xb5 }, /* her */
{ 0x65, 0x65, 0x55, 0xa5, 0x55, 0xa5 }, /* scy */
{ 0x55, 0x65, 0xa5, 0xb5 }, /* hrc */
{ 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hmd */
+ { 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hds */
+ { 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb4 }, /* syl */
};
/* actual fan speed */
-static const u8 FSCHMD_REG_FAN_ACT[5][6] = {
+static const u8 FSCHMD_REG_FAN_ACT[7][7] = {
{ 0x0e, 0x6b, 0xab }, /* pos */
{ 0x0e, 0x6b, 0xbb }, /* her */
{ 0x6b, 0x6c, 0x0e, 0xab, 0x5c, 0xbb }, /* scy */
{ 0x0e, 0x6b, 0xab, 0xbb }, /* hrc */
{ 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hmd */
+ { 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hds */
+ { 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7 }, /* syl */
};
/* fan status registers */
-static const u8 FSCHMD_REG_FAN_STATE[5][6] = {
+static const u8 FSCHMD_REG_FAN_STATE[7][7] = {
{ 0x0d, 0x62, 0xa2 }, /* pos */
{ 0x0d, 0x62, 0xb2 }, /* her */
{ 0x62, 0x61, 0x0d, 0xa2, 0x52, 0xb2 }, /* scy */
{ 0x0d, 0x62, 0xa2, 0xb2 }, /* hrc */
{ 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hmd */
+ { 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hds */
+ { 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0 }, /* syl */
};
/* fan ripple / divider registers */
-static const u8 FSCHMD_REG_FAN_RIPPLE[5][6] = {
+static const u8 FSCHMD_REG_FAN_RIPPLE[7][7] = {
{ 0x0f, 0x6f, 0xaf }, /* pos */
{ 0x0f, 0x6f, 0xbf }, /* her */
{ 0x6f, 0x6f, 0x0f, 0xaf, 0x0f, 0xbf }, /* scy */
{ 0x0f, 0x6f, 0xaf, 0xbf }, /* hrc */
{ 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hmd */
+ { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hds */
+ { 0x56, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6 }, /* syl */
};
-static const int FSCHMD_NO_FAN_SENSORS[5] = { 3, 3, 6, 4, 5 };
+static const int FSCHMD_NO_FAN_SENSORS[7] = { 3, 3, 6, 4, 5, 5, 7 };
/* Fan status register bitmasks */
#define FSCHMD_FAN_ALARM 0x04 /* called fault by FSC! */
-#define FSCHMD_FAN_NOT_PRESENT 0x08 /* not documented */
+#define FSCHMD_FAN_NOT_PRESENT 0x08
+#define FSCHMD_FAN_DISABLED 0x80
/* actual temperature registers */
-static const u8 FSCHMD_REG_TEMP_ACT[5][5] = {
+static const u8 FSCHMD_REG_TEMP_ACT[7][11] = {
{ 0x64, 0x32, 0x35 }, /* pos */
{ 0x64, 0x32, 0x35 }, /* her */
{ 0x64, 0xD0, 0x32, 0x35 }, /* scy */
{ 0x64, 0x32, 0x35 }, /* hrc */
{ 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hmd */
+ { 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hds */
+ { 0x58, 0x68, 0x78, 0x88, 0x98, 0xa8, /* syl */
+ 0xb8, 0xc8, 0xd8, 0xe8, 0xf8 },
};
/* temperature state registers */
-static const u8 FSCHMD_REG_TEMP_STATE[5][5] = {
+static const u8 FSCHMD_REG_TEMP_STATE[7][11] = {
{ 0x71, 0x81, 0x91 }, /* pos */
{ 0x71, 0x81, 0x91 }, /* her */
{ 0x71, 0xd1, 0x81, 0x91 }, /* scy */
{ 0x71, 0x81, 0x91 }, /* hrc */
{ 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hmd */
+ { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hds */
+ { 0x59, 0x69, 0x79, 0x89, 0x99, 0xa9, /* syl */
+ 0xb9, 0xc9, 0xd9, 0xe9, 0xf9 },
};
/* temperature high limit registers, FSC does not document these. Proven to be
@@ -158,24 +186,31 @@ static const u8 FSCHMD_REG_TEMP_STATE[5][5] = {
in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers
at these addresses, but doesn't want to confirm they are the same as with
the fscher?? */
-static const u8 FSCHMD_REG_TEMP_LIMIT[5][5] = {
+static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = {
{ 0, 0, 0 }, /* pos */
{ 0x76, 0x86, 0x96 }, /* her */
{ 0x76, 0xd6, 0x86, 0x96 }, /* scy */
{ 0x76, 0x86, 0x96 }, /* hrc */
{ 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hmd */
+ { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hds */
+ { 0x5a, 0x6a, 0x7a, 0x8a, 0x9a, 0xaa, /* syl */
+ 0xba, 0xca, 0xda, 0xea, 0xfa },
};
/* These were found through experimenting with an fscher, currently they are
not used, but we keep them around for future reference.
+ On the fscsyl AUTOP1 lives at 0x#c (so 0x5c for fan1, 0x6c for fan2, etc),
+ AUTOP2 lives at 0x#e, and 0x#1 is a bitmask defining which temps influence
+ the fan speed.
static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 };
static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */
-static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 };
+static const int FSCHMD_NO_TEMP_SENSORS[7] = { 3, 3, 4, 3, 5, 5, 11 };
/* temp status register bitmasks */
#define FSCHMD_TEMP_WORKING 0x01
#define FSCHMD_TEMP_ALERT 0x02
+#define FSCHMD_TEMP_DISABLED 0x80
/* there only really is an alarm if the sensor is working and alert == 1 */
#define FSCHMD_TEMP_ALARM_MASK \
(FSCHMD_TEMP_WORKING | FSCHMD_TEMP_ALERT)
@@ -201,6 +236,8 @@ static const struct i2c_device_id fschmd_id[] = {
{ "fscscy", fscscy },
{ "fschrc", fschrc },
{ "fschmd", fschmd },
+ { "fschds", fschds },
+ { "fscsyl", fscsyl },
{ }
};
MODULE_DEVICE_TABLE(i2c, fschmd_id);
@@ -242,14 +279,14 @@ struct fschmd_data {
u8 watchdog_control; /* watchdog control register */
u8 watchdog_state; /* watchdog status register */
u8 watchdog_preset; /* watchdog counter preset on trigger val */
- u8 volt[3]; /* 12, 5, battery voltage */
- u8 temp_act[5]; /* temperature */
- u8 temp_status[5]; /* status of sensor */
- u8 temp_max[5]; /* high temp limit, notice: undocumented! */
- u8 fan_act[6]; /* fans revolutions per second */
- u8 fan_status[6]; /* fan status */
- u8 fan_min[6]; /* fan min value for rps */
- u8 fan_ripple[6]; /* divider for rps */
+ u8 volt[6]; /* voltage */
+ u8 temp_act[11]; /* temperature */
+ u8 temp_status[11]; /* status of sensor */
+ u8 temp_max[11]; /* high temp limit, notice: undocumented! */
+ u8 fan_act[7]; /* fans revolutions per second */
+ u8 fan_status[7]; /* fan status */
+ u8 fan_min[7]; /* fan min value for rps */
+ u8 fan_ripple[7]; /* divider for rps */
};
/* Global variables to hold information read from special DMI tables, which are
@@ -257,8 +294,8 @@ struct fschmd_data {
protect these with a lock as they are only modified from our attach function
which always gets called with the i2c-core lock held and never accessed
before the attach function is done with them. */
-static int dmi_mult[3] = { 490, 200, 100 };
-static int dmi_offset[3] = { 0, 0, 0 };
+static int dmi_mult[6] = { 490, 200, 100, 100, 200, 100 };
+static int dmi_offset[6] = { 0, 0, 0, 0, 0, 0 };
static int dmi_vref = -1;
/* Somewhat ugly :( global data pointer list with all fschmd devices, so that
@@ -450,10 +487,11 @@ static ssize_t show_pwm_auto_point1_pwm(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
- int val = fschmd_update_device(dev)->fan_min[index];
+ struct fschmd_data *data = fschmd_update_device(dev);
+ int val = data->fan_min[index];
- /* 0 = allow turning off, 1-255 = 50-100% */
- if (val)
+ /* 0 = allow turning off (except on the syl), 1-255 = 50-100% */
+ if (val || data->kind == fscsyl - 1)
val = val / 2 + 128;
return sprintf(buf, "%d\n", val);
@@ -466,8 +504,8 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
struct fschmd_data *data = dev_get_drvdata(dev);
unsigned long v = simple_strtoul(buf, NULL, 10);
- /* register: 0 = allow turning off, 1-255 = 50-100% */
- if (v) {
+ /* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */
+ if (v || data->kind == fscsyl - 1) {
v = SENSORS_LIMIT(v, 128, 255);
v = (v - 128) * 2 + 1;
}
@@ -522,11 +560,15 @@ static ssize_t store_alert_led(struct device *dev,
return count;
}
+static DEVICE_ATTR(alert_led, 0644, show_alert_led, store_alert_led);
+
static struct sensor_device_attribute fschmd_attr[] = {
SENSOR_ATTR(in0_input, 0444, show_in_value, NULL, 0),
SENSOR_ATTR(in1_input, 0444, show_in_value, NULL, 1),
SENSOR_ATTR(in2_input, 0444, show_in_value, NULL, 2),
- SENSOR_ATTR(alert_led, 0644, show_alert_led, store_alert_led, 0),
+ SENSOR_ATTR(in3_input, 0444, show_in_value, NULL, 3),
+ SENSOR_ATTR(in4_input, 0444, show_in_value, NULL, 4),
+ SENSOR_ATTR(in5_input, 0444, show_in_value, NULL, 5),
};
static struct sensor_device_attribute fschmd_temp_attr[] = {
@@ -550,6 +592,30 @@ static struct sensor_device_attribute fschmd_temp_attr[] = {
SENSOR_ATTR(temp5_max, 0644, show_temp_max, store_temp_max, 4),
SENSOR_ATTR(temp5_fault, 0444, show_temp_fault, NULL, 4),
SENSOR_ATTR(temp5_alarm, 0444, show_temp_alarm, NULL, 4),
+ SENSOR_ATTR(temp6_input, 0444, show_temp_value, NULL, 5),
+ SENSOR_ATTR(temp6_max, 0644, show_temp_max, store_temp_max, 5),
+ SENSOR_ATTR(temp6_fault, 0444, show_temp_fault, NULL, 5),
+ SENSOR_ATTR(temp6_alarm, 0444, show_temp_alarm, NULL, 5),
+ SENSOR_ATTR(temp7_input, 0444, show_temp_value, NULL, 6),
+ SENSOR_ATTR(temp7_max, 0644, show_temp_max, store_temp_max, 6),
+ SENSOR_ATTR(temp7_fault, 0444, show_temp_fault, NULL, 6),
+ SENSOR_ATTR(temp7_alarm, 0444, show_temp_alarm, NULL, 6),
+ SENSOR_ATTR(temp8_input, 0444, show_temp_value, NULL, 7),
+ SENSOR_ATTR(temp8_max, 0644, show_temp_max, store_temp_max, 7),
+ SENSOR_ATTR(temp8_fault, 0444, show_temp_fault, NULL, 7),
+ SENSOR_ATTR(temp8_alarm, 0444, show_temp_alarm, NULL, 7),
+ SENSOR_ATTR(temp9_input, 0444, show_temp_value, NULL, 8),
+ SENSOR_ATTR(temp9_max, 0644, show_temp_max, store_temp_max, 8),
+ SENSOR_ATTR(temp9_fault, 0444, show_temp_fault, NULL, 8),
+ SENSOR_ATTR(temp9_alarm, 0444, show_temp_alarm, NULL, 8),
+ SENSOR_ATTR(temp10_input, 0444, show_temp_value, NULL, 9),
+ SENSOR_ATTR(temp10_max, 0644, show_temp_max, store_temp_max, 9),
+ SENSOR_ATTR(temp10_fault, 0444, show_temp_fault, NULL, 9),
+ SENSOR_ATTR(temp10_alarm, 0444, show_temp_alarm, NULL, 9),
+ SENSOR_ATTR(temp11_input, 0444, show_temp_value, NULL, 10),
+ SENSOR_ATTR(temp11_max, 0644, show_temp_max, store_temp_max, 10),
+ SENSOR_ATTR(temp11_fault, 0444, show_temp_fault, NULL, 10),
+ SENSOR_ATTR(temp11_alarm, 0444, show_temp_alarm, NULL, 10),
};
static struct sensor_device_attribute fschmd_fan_attr[] = {
@@ -589,6 +655,12 @@ static struct sensor_device_attribute fschmd_fan_attr[] = {
SENSOR_ATTR(fan6_fault, 0444, show_fan_fault, NULL, 5),
SENSOR_ATTR(pwm6_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
store_pwm_auto_point1_pwm, 5),
+ SENSOR_ATTR(fan7_input, 0444, show_fan_value, NULL, 6),
+ SENSOR_ATTR(fan7_div, 0644, show_fan_div, store_fan_div, 6),
+ SENSOR_ATTR(fan7_alarm, 0444, show_fan_alarm, NULL, 6),
+ SENSOR_ATTR(fan7_fault, 0444, show_fan_fault, NULL, 6),
+ SENSOR_ATTR(pwm7_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
+ store_pwm_auto_point1_pwm, 6),
};
@@ -624,10 +696,11 @@ static int watchdog_set_timeout(struct fschmd_data *data, int timeout)
data->watchdog_preset = DIV_ROUND_UP(timeout, resolution);
/* Write new timeout value */
- i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_PRESET,
- data->watchdog_preset);
+ i2c_smbus_write_byte_data(data->client,
+ FSCHMD_REG_WDOG_PRESET[data->kind], data->watchdog_preset);
/* Write new control register, do not trigger! */
- i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
+ i2c_smbus_write_byte_data(data->client,
+ FSCHMD_REG_WDOG_CONTROL[data->kind],
data->watchdog_control & ~FSCHMD_WDOG_CONTROL_TRIGGER);
ret = data->watchdog_preset * resolution;
@@ -662,8 +735,9 @@ static int watchdog_trigger(struct fschmd_data *data)
}
data->watchdog_control |= FSCHMD_WDOG_CONTROL_TRIGGER;
- i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
- data->watchdog_control);
+ i2c_smbus_write_byte_data(data->client,
+ FSCHMD_REG_WDOG_CONTROL[data->kind],
+ data->watchdog_control);
leave:
mutex_unlock(&data->watchdog_lock);
return ret;
@@ -682,7 +756,8 @@ static int watchdog_stop(struct fschmd_data *data)
data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_STARTED;
/* Don't store the stop flag in our watchdog control register copy, as
its a write only bit (read always returns 0) */
- i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
+ i2c_smbus_write_byte_data(data->client,
+ FSCHMD_REG_WDOG_CONTROL[data->kind],
data->watchdog_control | FSCHMD_WDOG_CONTROL_STOP);
leave:
mutex_unlock(&data->watchdog_lock);
@@ -856,7 +931,7 @@ static struct file_operations watchdog_fops = {
/* DMI decode routine to read voltage scaling factors from special DMI tables,
which are available on FSC machines with an fscher or later chip. */
-static void fschmd_dmi_decode(const struct dmi_header *header)
+static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy)
{
int i, mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0;
@@ -912,6 +987,15 @@ static void fschmd_dmi_decode(const struct dmi_header *header)
dmi_mult[i] = mult[i] * 10;
dmi_offset[i] = offset[i] * 10;
}
+ /* According to the docs there should be separate dmi entries
+ for the mult's and offsets of in3-5 of the syl, but on
+ my test machine these are not present */
+ dmi_mult[3] = dmi_mult[2];
+ dmi_mult[4] = dmi_mult[1];
+ dmi_mult[5] = dmi_mult[2];
+ dmi_offset[3] = dmi_offset[2];
+ dmi_offset[4] = dmi_offset[1];
+ dmi_offset[5] = dmi_offset[2];
dmi_vref = vref;
}
}
@@ -920,8 +1004,6 @@ static int fschmd_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_adapter *adapter = client->adapter;
- const char * const client_names[5] = { "fscpos", "fscher", "fscscy",
- "fschrc", "fschmd" };
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
@@ -948,11 +1030,15 @@ static int fschmd_detect(struct i2c_client *client, int kind,
kind = fschrc;
else if (!strcmp(id, "HMD"))
kind = fschmd;
+ else if (!strcmp(id, "HDS"))
+ kind = fschds;
+ else if (!strcmp(id, "SYL"))
+ kind = fscsyl;
else
return -ENODEV;
}
- strlcpy(info->type, client_names[kind - 1], I2C_NAME_SIZE);
+ strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE);
return 0;
}
@@ -961,8 +1047,8 @@ static int fschmd_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct fschmd_data *data;
- const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
- "Heracles", "Heimdall" };
+ const char * const names[7] = { "Poseidon", "Hermes", "Scylla",
+ "Heracles", "Heimdall", "Hades", "Syleus" };
const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 };
int i, err;
enum chips kind = id->driver_data;
@@ -991,7 +1077,7 @@ static int fschmd_probe(struct i2c_client *client,
/* Read the special DMI table for fscher and newer chips */
if ((kind == fscher || kind >= fschrc) && dmi_vref == -1) {
- dmi_walk(fschmd_dmi_decode);
+ dmi_walk(fschmd_dmi_decode, NULL);
if (dmi_vref == -1) {
dev_warn(&client->dev,
"Couldn't get voltage scaling factors from "
@@ -1000,21 +1086,25 @@ static int fschmd_probe(struct i2c_client *client,
}
}
+ /* i2c kind goes from 1-6, we want from 0-5 to address arrays */
+ data->kind = kind - 1;
+
/* Read in some never changing registers */
data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION);
data->global_control = i2c_smbus_read_byte_data(client,
FSCHMD_REG_CONTROL);
data->watchdog_control = i2c_smbus_read_byte_data(client,
- FSCHMD_REG_WDOG_CONTROL);
+ FSCHMD_REG_WDOG_CONTROL[data->kind]);
data->watchdog_state = i2c_smbus_read_byte_data(client,
- FSCHMD_REG_WDOG_STATE);
+ FSCHMD_REG_WDOG_STATE[data->kind]);
data->watchdog_preset = i2c_smbus_read_byte_data(client,
- FSCHMD_REG_WDOG_PRESET);
+ FSCHMD_REG_WDOG_PRESET[data->kind]);
- /* i2c kind goes from 1-5, we want from 0-4 to address arrays */
- data->kind = kind - 1;
+ err = device_create_file(&client->dev, &dev_attr_alert_led);
+ if (err)
+ goto exit_detach;
- for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) {
+ for (i = 0; i < FSCHMD_NO_VOLT_SENSORS[data->kind]; i++) {
err = device_create_file(&client->dev,
&fschmd_attr[i].dev_attr);
if (err)
@@ -1027,6 +1117,16 @@ static int fschmd_probe(struct i2c_client *client,
show_temp_max)
continue;
+ if (kind == fscsyl) {
+ if (i % 4 == 0)
+ data->temp_status[i / 4] =
+ i2c_smbus_read_byte_data(client,
+ FSCHMD_REG_TEMP_STATE
+ [data->kind][i / 4]);
+ if (data->temp_status[i / 4] & FSCHMD_TEMP_DISABLED)
+ continue;
+ }
+
err = device_create_file(&client->dev,
&fschmd_temp_attr[i].dev_attr);
if (err)
@@ -1040,6 +1140,16 @@ static int fschmd_probe(struct i2c_client *client,
"pwm3_auto_point1_pwm"))
continue;
+ if (kind == fscsyl) {
+ if (i % 5 == 0)
+ data->fan_status[i / 5] =
+ i2c_smbus_read_byte_data(client,
+ FSCHMD_REG_FAN_STATE
+ [data->kind][i / 5]);
+ if (data->fan_status[i / 5] & FSCHMD_FAN_DISABLED)
+ continue;
+ }
+
err = device_create_file(&client->dev,
&fschmd_fan_attr[i].dev_attr);
if (err)
@@ -1126,7 +1236,8 @@ static int fschmd_remove(struct i2c_client *client)
if (data->hwmon_dev)
hwmon_device_unregister(data->hwmon_dev);
- for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++)
+ device_remove_file(&client->dev, &dev_attr_alert_led);
+ for (i = 0; i < (FSCHMD_NO_VOLT_SENSORS[data->kind]); i++)
device_remove_file(&client->dev, &fschmd_attr[i].dev_attr);
for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++)
device_remove_file(&client->dev,
@@ -1171,7 +1282,7 @@ static struct fschmd_data *fschmd_update_device(struct device *dev)
data->temp_act[i] < data->temp_max[i])
i2c_smbus_write_byte_data(client,
FSCHMD_REG_TEMP_STATE[data->kind][i],
- FSCHMD_TEMP_ALERT);
+ data->temp_status[i]);
}
for (i = 0; i < FSCHMD_NO_FAN_SENSORS[data->kind]; i++) {
@@ -1193,12 +1304,12 @@ static struct fschmd_data *fschmd_update_device(struct device *dev)
data->fan_act[i])
i2c_smbus_write_byte_data(client,
FSCHMD_REG_FAN_STATE[data->kind][i],
- FSCHMD_FAN_ALARM);
+ data->fan_status[i]);
}
- for (i = 0; i < 3; i++)
+ for (i = 0; i < FSCHMD_NO_VOLT_SENSORS[data->kind]; i++)
data->volt[i] = i2c_smbus_read_byte_data(client,
- FSCHMD_REG_VOLT[i]);
+ FSCHMD_REG_VOLT[data->kind][i]);
data->last_updated = jiffies;
data->valid = 1;
@@ -1220,8 +1331,8 @@ static void __exit fschmd_exit(void)
}
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
-MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles and "
- "Heimdall driver");
+MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles, Heimdall, Hades "
+ "and Syleus driver");
MODULE_LICENSE("GPL");
module_init(fschmd_init);
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index a4d92d246d52..d3612a1f1981 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -65,6 +65,10 @@
#define HDAPS_INPUT_FUZZ 4 /* input event threshold */
#define HDAPS_INPUT_FLAT 4
+#define HDAPS_X_AXIS (1 << 0)
+#define HDAPS_Y_AXIS (1 << 1)
+#define HDAPS_BOTH_AXES (HDAPS_X_AXIS | HDAPS_Y_AXIS)
+
static struct platform_device *pdev;
static struct input_polled_dev *hdaps_idev;
static unsigned int hdaps_invert;
@@ -182,11 +186,11 @@ static int __hdaps_read_pair(unsigned int port1, unsigned int port2,
km_activity = inb(HDAPS_PORT_KMACT);
__device_complete();
- /* if hdaps_invert is set, negate the two values */
- if (hdaps_invert) {
+ /* hdaps_invert is a bitvector to negate the axes */
+ if (hdaps_invert & HDAPS_X_AXIS)
*x = -*x;
+ if (hdaps_invert & HDAPS_Y_AXIS)
*y = -*y;
- }
return 0;
}
@@ -436,7 +440,8 @@ static ssize_t hdaps_invert_store(struct device *dev,
{
int invert;
- if (sscanf(buf, "%d", &invert) != 1 || (invert != 1 && invert != 0))
+ if (sscanf(buf, "%d", &invert) != 1 ||
+ invert < 0 || invert > HDAPS_BOTH_AXES)
return -EINVAL;
hdaps_invert = invert;
@@ -483,56 +488,52 @@ static int __init hdaps_dmi_match(const struct dmi_system_id *id)
/* hdaps_dmi_match_invert - found an inverted match. */
static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id)
{
- hdaps_invert = 1;
- printk(KERN_INFO "hdaps: inverting axis readings.\n");
+ hdaps_invert = (unsigned long)id->driver_data;
+ printk(KERN_INFO "hdaps: inverting axis (%u) readings.\n",
+ hdaps_invert);
return hdaps_dmi_match(id);
}
-#define HDAPS_DMI_MATCH_NORMAL(vendor, model) { \
- .ident = vendor " " model, \
- .callback = hdaps_dmi_match, \
- .matches = { \
- DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
- DMI_MATCH(DMI_PRODUCT_VERSION, model) \
- } \
-}
-
-#define HDAPS_DMI_MATCH_INVERT(vendor, model) { \
+#define HDAPS_DMI_MATCH_INVERT(vendor, model, axes) { \
.ident = vendor " " model, \
.callback = hdaps_dmi_match_invert, \
+ .driver_data = (void *)axes, \
.matches = { \
DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
DMI_MATCH(DMI_PRODUCT_VERSION, model) \
} \
}
+#define HDAPS_DMI_MATCH_NORMAL(vendor, model) \
+ HDAPS_DMI_MATCH_INVERT(vendor, model, 0)
+
/* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match
"ThinkPad T42p", so the order of the entries matters.
If your ThinkPad is not recognized, please update to latest
BIOS. This is especially the case for some R52 ThinkPads. */
static struct dmi_system_id __initdata hdaps_whitelist[] = {
- HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p"),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61"),
- HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"),
- HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61"),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"),
- HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61"),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad X41", HDAPS_Y_AXIS),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p"),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p", HDAPS_BOTH_AXES),
{ .ident = NULL }
};
@@ -627,8 +628,9 @@ static void __exit hdaps_exit(void)
module_init(hdaps_init);
module_exit(hdaps_exit);
-module_param_named(invert, hdaps_invert, bool, 0);
-MODULE_PARM_DESC(invert, "invert data along each axis");
+module_param_named(invert, hdaps_invert, int, 0);
+MODULE_PARM_DESC(invert, "invert data along each axis. 1 invert x-axis, "
+ "2 invert y-axis, 3 invert both axes.");
MODULE_AUTHOR("Robert Love");
MODULE_DESCRIPTION("IBM Hard Drive Active Protection System (HDAPS) driver");
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index 29c83b5b9697..55d3dc565be6 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -85,25 +85,31 @@ MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids);
/**
* lis3lv02d_acpi_init - ACPI _INI method: initialize the device.
- * @handle: the handle of the device
+ * @lis3: pointer to the device struct
*
- * Returns AE_OK on success.
+ * Returns 0 on success.
*/
-acpi_status lis3lv02d_acpi_init(acpi_handle handle)
+int lis3lv02d_acpi_init(struct lis3lv02d *lis3)
{
- return acpi_evaluate_object(handle, METHOD_NAME__INI, NULL, NULL);
+ struct acpi_device *dev = lis3->bus_priv;
+ if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI,
+ NULL, NULL) != AE_OK)
+ return -EINVAL;
+
+ return 0;
}
/**
* lis3lv02d_acpi_read - ACPI ALRD method: read a register
- * @handle: the handle of the device
+ * @lis3: pointer to the device struct
* @reg: the register to read
* @ret: result of the operation
*
- * Returns AE_OK on success.
+ * Returns 0 on success.
*/
-acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret)
+int lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret)
{
+ struct acpi_device *dev = lis3->bus_priv;
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list args = { 1, &arg0 };
unsigned long long lret;
@@ -111,21 +117,22 @@ acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret)
arg0.integer.value = reg;
- status = acpi_evaluate_integer(handle, "ALRD", &args, &lret);
+ status = acpi_evaluate_integer(dev->handle, "ALRD", &args, &lret);
*ret = lret;
- return status;
+ return (status != AE_OK) ? -EINVAL : 0;
}
/**
* lis3lv02d_acpi_write - ACPI ALWR method: write to a register
- * @handle: the handle of the device
+ * @lis3: pointer to the device struct
* @reg: the register to write to
* @val: the value to write
*
- * Returns AE_OK on success.
+ * Returns 0 on success.
*/
-acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val)
+int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val)
{
+ struct acpi_device *dev = lis3->bus_priv;
unsigned long long ret; /* Not used when writting */
union acpi_object in_obj[2];
struct acpi_object_list args = { 2, in_obj };
@@ -135,12 +142,15 @@ acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val)
in_obj[1].type = ACPI_TYPE_INTEGER;
in_obj[1].integer.value = val;
- return acpi_evaluate_integer(handle, "ALWR", &args, &ret);
+ if (acpi_evaluate_integer(dev->handle, "ALWR", &args, &ret) != AE_OK)
+ return -EINVAL;
+
+ return 0;
}
static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi)
{
- adev.ac = *((struct axis_conversion *)dmi->driver_data);
+ lis3_dev.ac = *((struct axis_conversion *)dmi->driver_data);
printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident);
return 1;
@@ -187,6 +197,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted),
AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted),
AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left),
+ AXIS_DMI_MATCH("HP2140", "HP 2140", xy_swap_inverted),
AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd),
AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd),
AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right),
@@ -201,6 +212,8 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
PRODUCT_NAME, "HP Pavilion dv5",
BOARD_NAME, "3600",
y_inverted),
+ AXIS_DMI_MATCH("DV7", "HP Pavilion dv7", x_inverted),
+ AXIS_DMI_MATCH("HP8710", "HP Compaq 8710", y_inverted),
{ NULL, }
/* Laptop models without axis info (yet):
* "NC6910" "HP Compaq 6910"
@@ -214,7 +227,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness value)
{
- acpi_handle handle = adev.device->handle;
+ struct acpi_device *dev = lis3_dev.bus_priv;
unsigned long long ret; /* Not used when writing */
union acpi_object in_obj[1];
struct acpi_object_list args = { 1, in_obj };
@@ -222,7 +235,7 @@ static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness
in_obj[0].type = ACPI_TYPE_INTEGER;
in_obj[0].integer.value = !!value;
- acpi_evaluate_integer(handle, "ALED", &args, &ret);
+ acpi_evaluate_integer(dev->handle, "ALED", &args, &ret);
}
static struct delayed_led_classdev hpled_led = {
@@ -254,28 +267,11 @@ static void lis3lv02d_enum_resources(struct acpi_device *device)
acpi_status status;
status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
- lis3lv02d_get_resource, &adev.irq);
+ lis3lv02d_get_resource, &lis3_dev.irq);
if (ACPI_FAILURE(status))
printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n");
}
-static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
-{
- u8 lo, hi;
-
- adev.read(handle, reg - 1, &lo);
- adev.read(handle, reg, &hi);
- /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
- return (s16)((hi << 8) | lo);
-}
-
-static s16 lis3lv02d_read_8(acpi_handle handle, int reg)
-{
- s8 lo;
- adev.read(handle, reg, &lo);
- return lo;
-}
-
static int lis3lv02d_add(struct acpi_device *device)
{
int ret;
@@ -283,51 +279,35 @@ static int lis3lv02d_add(struct acpi_device *device)
if (!device)
return -EINVAL;
- adev.device = device;
- adev.init = lis3lv02d_acpi_init;
- adev.read = lis3lv02d_acpi_read;
- adev.write = lis3lv02d_acpi_write;
+ lis3_dev.bus_priv = device;
+ lis3_dev.init = lis3lv02d_acpi_init;
+ lis3_dev.read = lis3lv02d_acpi_read;
+ lis3_dev.write = lis3lv02d_acpi_write;
strcpy(acpi_device_name(device), DRIVER_NAME);
strcpy(acpi_device_class(device), ACPI_MDPS_CLASS);
- device->driver_data = &adev;
-
- lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami);
- switch (adev.whoami) {
- case LIS_DOUBLE_ID:
- printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n");
- adev.read_data = lis3lv02d_read_16;
- adev.mdps_max_val = 2048;
- break;
- case LIS_SINGLE_ID:
- printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n");
- adev.read_data = lis3lv02d_read_8;
- adev.mdps_max_val = 128;
- break;
- default:
- printk(KERN_ERR DRIVER_NAME
- ": unknown sensor type 0x%X\n", adev.whoami);
- return -EINVAL;
- }
+ device->driver_data = &lis3_dev;
+
+ /* obtain IRQ number of our device from ACPI */
+ lis3lv02d_enum_resources(device);
/* If possible use a "standard" axes order */
if (dmi_check_system(lis3lv02d_dmi_ids) == 0) {
printk(KERN_INFO DRIVER_NAME ": laptop model unknown, "
"using default axes configuration\n");
- adev.ac = lis3lv02d_axis_normal;
+ lis3_dev.ac = lis3lv02d_axis_normal;
}
- INIT_WORK(&hpled_led.work, delayed_set_status_worker);
- ret = led_classdev_register(NULL, &hpled_led.led_classdev);
+ /* call the core layer do its init */
+ ret = lis3lv02d_init_device(&lis3_dev);
if (ret)
return ret;
- /* obtain IRQ number of our device from ACPI */
- lis3lv02d_enum_resources(adev.device);
-
- ret = lis3lv02d_init_device(&adev);
+ INIT_WORK(&hpled_led.work, delayed_set_status_worker);
+ ret = led_classdev_register(NULL, &hpled_led.led_classdev);
if (ret) {
+ lis3lv02d_joystick_disable();
+ lis3lv02d_poweroff(&lis3_dev);
flush_work(&hpled_led.work);
- led_classdev_unregister(&hpled_led.led_classdev);
return ret;
}
@@ -340,7 +320,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type)
return -EINVAL;
lis3lv02d_joystick_disable();
- lis3lv02d_poweroff(device->handle);
+ lis3lv02d_poweroff(&lis3_dev);
flush_work(&hpled_led.work);
led_classdev_unregister(&hpled_led.led_classdev);
@@ -353,19 +333,19 @@ static int lis3lv02d_remove(struct acpi_device *device, int type)
static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state)
{
/* make sure the device is off when we suspend */
- lis3lv02d_poweroff(device->handle);
+ lis3lv02d_poweroff(&lis3_dev);
return 0;
}
static int lis3lv02d_resume(struct acpi_device *device)
{
/* put back the device in the right state (ACPI might turn it on) */
- mutex_lock(&adev.lock);
- if (adev.usage > 0)
- lis3lv02d_poweron(device->handle);
+ mutex_lock(&lis3_dev.lock);
+ if (lis3_dev.usage > 0)
+ lis3lv02d_poweron(&lis3_dev);
else
- lis3lv02d_poweroff(device->handle);
- mutex_unlock(&adev.lock);
+ lis3lv02d_poweroff(&lis3_dev);
+ mutex_unlock(&lis3_dev.lock);
return 0;
}
#else
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 8bb2158f0453..778eb7795983 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -36,7 +36,6 @@
#include <linux/freezer.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
-#include <acpi/acpi_drivers.h>
#include <asm/atomic.h>
#include "lis3lv02d.h"
@@ -53,13 +52,30 @@
* joystick.
*/
-struct acpi_lis3lv02d adev = {
- .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait),
+struct lis3lv02d lis3_dev = {
+ .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
};
-EXPORT_SYMBOL_GPL(adev);
+EXPORT_SYMBOL_GPL(lis3_dev);
-static int lis3lv02d_add_fs(struct acpi_device *device);
+static s16 lis3lv02d_read_8(struct lis3lv02d *lis3, int reg)
+{
+ s8 lo;
+ if (lis3->read(lis3, reg, &lo) < 0)
+ return 0;
+
+ return lo;
+}
+
+static s16 lis3lv02d_read_16(struct lis3lv02d *lis3, int reg)
+{
+ u8 lo, hi;
+
+ lis3->read(lis3, reg - 1, &lo);
+ lis3->read(lis3, reg, &hi);
+ /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
+ return (s16)((hi << 8) | lo);
+}
/**
* lis3lv02d_get_axis - For the given axis, give the value converted
@@ -78,36 +94,36 @@ static inline int lis3lv02d_get_axis(s8 axis, int hw_values[3])
/**
* lis3lv02d_get_xyz - Get X, Y and Z axis values from the accelerometer
- * @handle: the handle to the device
- * @x: where to store the X axis value
- * @y: where to store the Y axis value
- * @z: where to store the Z axis value
+ * @lis3: pointer to the device struct
+ * @x: where to store the X axis value
+ * @y: where to store the Y axis value
+ * @z: where to store the Z axis value
*
* Note that 40Hz input device can eat up about 10% CPU at 800MHZ
*/
-static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z)
+static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
{
int position[3];
- position[0] = adev.read_data(handle, OUTX);
- position[1] = adev.read_data(handle, OUTY);
- position[2] = adev.read_data(handle, OUTZ);
+ position[0] = lis3_dev.read_data(lis3, OUTX);
+ position[1] = lis3_dev.read_data(lis3, OUTY);
+ position[2] = lis3_dev.read_data(lis3, OUTZ);
- *x = lis3lv02d_get_axis(adev.ac.x, position);
- *y = lis3lv02d_get_axis(adev.ac.y, position);
- *z = lis3lv02d_get_axis(adev.ac.z, position);
+ *x = lis3lv02d_get_axis(lis3_dev.ac.x, position);
+ *y = lis3lv02d_get_axis(lis3_dev.ac.y, position);
+ *z = lis3lv02d_get_axis(lis3_dev.ac.z, position);
}
-void lis3lv02d_poweroff(acpi_handle handle)
+void lis3lv02d_poweroff(struct lis3lv02d *lis3)
{
- adev.is_on = 0;
+ lis3_dev.is_on = 0;
}
EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
-void lis3lv02d_poweron(acpi_handle handle)
+void lis3lv02d_poweron(struct lis3lv02d *lis3)
{
- adev.is_on = 1;
- adev.init(handle);
+ lis3_dev.is_on = 1;
+ lis3_dev.init(lis3);
}
EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
@@ -116,13 +132,13 @@ EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
* device will always be on until a call to lis3lv02d_decrease_use(). Not to be
* used from interrupt context.
*/
-static void lis3lv02d_increase_use(struct acpi_lis3lv02d *dev)
+static void lis3lv02d_increase_use(struct lis3lv02d *dev)
{
mutex_lock(&dev->lock);
dev->usage++;
if (dev->usage == 1) {
if (!dev->is_on)
- lis3lv02d_poweron(dev->device->handle);
+ lis3lv02d_poweron(dev);
}
mutex_unlock(&dev->lock);
}
@@ -131,12 +147,12 @@ static void lis3lv02d_increase_use(struct acpi_lis3lv02d *dev)
* To be called whenever a usage of the device is stopped.
* It will make sure to turn off the device when there is not usage.
*/
-static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev)
+static void lis3lv02d_decrease_use(struct lis3lv02d *dev)
{
mutex_lock(&dev->lock);
dev->usage--;
if (dev->usage == 0)
- lis3lv02d_poweroff(dev->device->handle);
+ lis3lv02d_poweroff(dev);
mutex_unlock(&dev->lock);
}
@@ -147,10 +163,10 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
* the lid is closed. This leads to interrupts as soon as a little move
* is done.
*/
- atomic_inc(&adev.count);
+ atomic_inc(&lis3_dev.count);
- wake_up_interruptible(&adev.misc_wait);
- kill_fasync(&adev.async_queue, SIGIO, POLL_IN);
+ wake_up_interruptible(&lis3_dev.misc_wait);
+ kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
return IRQ_HANDLED;
}
@@ -158,10 +174,10 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
{
int ret;
- if (test_and_set_bit(0, &adev.misc_opened))
+ if (test_and_set_bit(0, &lis3_dev.misc_opened))
return -EBUSY; /* already open */
- atomic_set(&adev.count, 0);
+ atomic_set(&lis3_dev.count, 0);
/*
* The sensor can generate interrupts for free-fall and direction
@@ -174,25 +190,25 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
* io-apic is not configurable (and generates a warning) but I keep it
* in case of support for other hardware.
*/
- ret = request_irq(adev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING,
- DRIVER_NAME, &adev);
+ ret = request_irq(lis3_dev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING,
+ DRIVER_NAME, &lis3_dev);
if (ret) {
- clear_bit(0, &adev.misc_opened);
- printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", adev.irq);
+ clear_bit(0, &lis3_dev.misc_opened);
+ printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", lis3_dev.irq);
return -EBUSY;
}
- lis3lv02d_increase_use(&adev);
- printk("lis3: registered interrupt %d\n", adev.irq);
+ lis3lv02d_increase_use(&lis3_dev);
+ printk("lis3: registered interrupt %d\n", lis3_dev.irq);
return 0;
}
static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
{
- fasync_helper(-1, file, 0, &adev.async_queue);
- lis3lv02d_decrease_use(&adev);
- free_irq(adev.irq, &adev);
- clear_bit(0, &adev.misc_opened); /* release the device */
+ fasync_helper(-1, file, 0, &lis3_dev.async_queue);
+ lis3lv02d_decrease_use(&lis3_dev);
+ free_irq(lis3_dev.irq, &lis3_dev);
+ clear_bit(0, &lis3_dev.misc_opened); /* release the device */
return 0;
}
@@ -207,10 +223,10 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
if (count < 1)
return -EINVAL;
- add_wait_queue(&adev.misc_wait, &wait);
+ add_wait_queue(&lis3_dev.misc_wait, &wait);
while (true) {
set_current_state(TASK_INTERRUPTIBLE);
- data = atomic_xchg(&adev.count, 0);
+ data = atomic_xchg(&lis3_dev.count, 0);
if (data)
break;
@@ -240,22 +256,22 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
out:
__set_current_state(TASK_RUNNING);
- remove_wait_queue(&adev.misc_wait, &wait);
+ remove_wait_queue(&lis3_dev.misc_wait, &wait);
return retval;
}
static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait)
{
- poll_wait(file, &adev.misc_wait, wait);
- if (atomic_read(&adev.count))
+ poll_wait(file, &lis3_dev.misc_wait, wait);
+ if (atomic_read(&lis3_dev.count))
return POLLIN | POLLRDNORM;
return 0;
}
static int lis3lv02d_misc_fasync(int fd, struct file *file, int on)
{
- return fasync_helper(fd, file, on, &adev.async_queue);
+ return fasync_helper(fd, file, on, &lis3_dev.async_queue);
}
static const struct file_operations lis3lv02d_misc_fops = {
@@ -283,12 +299,12 @@ static int lis3lv02d_joystick_kthread(void *data)
int x, y, z;
while (!kthread_should_stop()) {
- lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z);
- input_report_abs(adev.idev, ABS_X, x - adev.xcalib);
- input_report_abs(adev.idev, ABS_Y, y - adev.ycalib);
- input_report_abs(adev.idev, ABS_Z, z - adev.zcalib);
+ lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
+ input_report_abs(lis3_dev.idev, ABS_X, x - lis3_dev.xcalib);
+ input_report_abs(lis3_dev.idev, ABS_Y, y - lis3_dev.ycalib);
+ input_report_abs(lis3_dev.idev, ABS_Z, z - lis3_dev.zcalib);
- input_sync(adev.idev);
+ input_sync(lis3_dev.idev);
try_to_freeze();
msleep_interruptible(MDPS_POLL_INTERVAL);
@@ -299,11 +315,11 @@ static int lis3lv02d_joystick_kthread(void *data)
static int lis3lv02d_joystick_open(struct input_dev *input)
{
- lis3lv02d_increase_use(&adev);
- adev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d");
- if (IS_ERR(adev.kthread)) {
- lis3lv02d_decrease_use(&adev);
- return PTR_ERR(adev.kthread);
+ lis3lv02d_increase_use(&lis3_dev);
+ lis3_dev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d");
+ if (IS_ERR(lis3_dev.kthread)) {
+ lis3lv02d_decrease_use(&lis3_dev);
+ return PTR_ERR(lis3_dev.kthread);
}
return 0;
@@ -311,45 +327,46 @@ static int lis3lv02d_joystick_open(struct input_dev *input)
static void lis3lv02d_joystick_close(struct input_dev *input)
{
- kthread_stop(adev.kthread);
- lis3lv02d_decrease_use(&adev);
+ kthread_stop(lis3_dev.kthread);
+ lis3lv02d_decrease_use(&lis3_dev);
}
static inline void lis3lv02d_calibrate_joystick(void)
{
- lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib);
+ lis3lv02d_get_xyz(&lis3_dev,
+ &lis3_dev.xcalib, &lis3_dev.ycalib, &lis3_dev.zcalib);
}
int lis3lv02d_joystick_enable(void)
{
int err;
- if (adev.idev)
+ if (lis3_dev.idev)
return -EINVAL;
- adev.idev = input_allocate_device();
- if (!adev.idev)
+ lis3_dev.idev = input_allocate_device();
+ if (!lis3_dev.idev)
return -ENOMEM;
lis3lv02d_calibrate_joystick();
- adev.idev->name = "ST LIS3LV02DL Accelerometer";
- adev.idev->phys = DRIVER_NAME "/input0";
- adev.idev->id.bustype = BUS_HOST;
- adev.idev->id.vendor = 0;
- adev.idev->dev.parent = &adev.pdev->dev;
- adev.idev->open = lis3lv02d_joystick_open;
- adev.idev->close = lis3lv02d_joystick_close;
+ lis3_dev.idev->name = "ST LIS3LV02DL Accelerometer";
+ lis3_dev.idev->phys = DRIVER_NAME "/input0";
+ lis3_dev.idev->id.bustype = BUS_HOST;
+ lis3_dev.idev->id.vendor = 0;
+ lis3_dev.idev->dev.parent = &lis3_dev.pdev->dev;
+ lis3_dev.idev->open = lis3lv02d_joystick_open;
+ lis3_dev.idev->close = lis3lv02d_joystick_close;
- set_bit(EV_ABS, adev.idev->evbit);
- input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
- input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
- input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
+ set_bit(EV_ABS, lis3_dev.idev->evbit);
+ input_set_abs_params(lis3_dev.idev, ABS_X, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
+ input_set_abs_params(lis3_dev.idev, ABS_Y, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
+ input_set_abs_params(lis3_dev.idev, ABS_Z, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
- err = input_register_device(adev.idev);
+ err = input_register_device(lis3_dev.idev);
if (err) {
- input_free_device(adev.idev);
- adev.idev = NULL;
+ input_free_device(lis3_dev.idev);
+ lis3_dev.idev = NULL;
}
return err;
@@ -358,71 +375,40 @@ EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable);
void lis3lv02d_joystick_disable(void)
{
- if (!adev.idev)
+ if (!lis3_dev.idev)
return;
misc_deregister(&lis3lv02d_misc_device);
- input_unregister_device(adev.idev);
- adev.idev = NULL;
+ input_unregister_device(lis3_dev.idev);
+ lis3_dev.idev = NULL;
}
EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
-/*
- * Initialise the accelerometer and the various subsystems.
- * Should be rather independant of the bus system.
- */
-int lis3lv02d_init_device(struct acpi_lis3lv02d *dev)
-{
- mutex_init(&dev->lock);
- lis3lv02d_add_fs(dev->device);
- lis3lv02d_increase_use(dev);
-
- if (lis3lv02d_joystick_enable())
- printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
-
- printk("lis3_init_device: irq %d\n", dev->irq);
-
- /* if we did not get an IRQ from ACPI - we have nothing more to do */
- if (!dev->irq) {
- printk(KERN_ERR DRIVER_NAME
- ": No IRQ in ACPI. Disabling /dev/freefall\n");
- goto out;
- }
-
- printk("lis3: registering device\n");
- if (misc_register(&lis3lv02d_misc_device))
- printk(KERN_ERR DRIVER_NAME ": misc_register failed\n");
-out:
- lis3lv02d_decrease_use(dev);
- return 0;
-}
-EXPORT_SYMBOL_GPL(lis3lv02d_init_device);
-
/* Sysfs stuff */
static ssize_t lis3lv02d_position_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int x, y, z;
- lis3lv02d_increase_use(&adev);
- lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z);
- lis3lv02d_decrease_use(&adev);
+ lis3lv02d_increase_use(&lis3_dev);
+ lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
+ lis3lv02d_decrease_use(&lis3_dev);
return sprintf(buf, "(%d,%d,%d)\n", x, y, z);
}
static ssize_t lis3lv02d_calibrate_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "(%d,%d,%d)\n", adev.xcalib, adev.ycalib, adev.zcalib);
+ return sprintf(buf, "(%d,%d,%d)\n", lis3_dev.xcalib, lis3_dev.ycalib, lis3_dev.zcalib);
}
static ssize_t lis3lv02d_calibrate_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- lis3lv02d_increase_use(&adev);
+ lis3lv02d_increase_use(&lis3_dev);
lis3lv02d_calibrate_joystick();
- lis3lv02d_decrease_use(&adev);
+ lis3lv02d_decrease_use(&lis3_dev);
return count;
}
@@ -434,9 +420,9 @@ static ssize_t lis3lv02d_rate_show(struct device *dev,
u8 ctrl;
int val;
- lis3lv02d_increase_use(&adev);
- adev.read(adev.device->handle, CTRL_REG1, &ctrl);
- lis3lv02d_decrease_use(&adev);
+ lis3lv02d_increase_use(&lis3_dev);
+ lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
+ lis3lv02d_decrease_use(&lis3_dev);
val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4;
return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]);
}
@@ -458,23 +444,73 @@ static struct attribute_group lis3lv02d_attribute_group = {
};
-static int lis3lv02d_add_fs(struct acpi_device *device)
+static int lis3lv02d_add_fs(struct lis3lv02d *lis3)
{
- adev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
- if (IS_ERR(adev.pdev))
- return PTR_ERR(adev.pdev);
+ lis3_dev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
+ if (IS_ERR(lis3_dev.pdev))
+ return PTR_ERR(lis3_dev.pdev);
- return sysfs_create_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group);
+ return sysfs_create_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group);
}
int lis3lv02d_remove_fs(void)
{
- sysfs_remove_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group);
- platform_device_unregister(adev.pdev);
+ sysfs_remove_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group);
+ platform_device_unregister(lis3_dev.pdev);
return 0;
}
EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
+/*
+ * Initialise the accelerometer and the various subsystems.
+ * Should be rather independant of the bus system.
+ */
+int lis3lv02d_init_device(struct lis3lv02d *dev)
+{
+ dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
+
+ switch (dev->whoami) {
+ case LIS_DOUBLE_ID:
+ printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n");
+ dev->read_data = lis3lv02d_read_16;
+ dev->mdps_max_val = 2048;
+ break;
+ case LIS_SINGLE_ID:
+ printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n");
+ dev->read_data = lis3lv02d_read_8;
+ dev->mdps_max_val = 128;
+ break;
+ default:
+ printk(KERN_ERR DRIVER_NAME
+ ": unknown sensor type 0x%X\n", lis3_dev.whoami);
+ return -EINVAL;
+ }
+
+ mutex_init(&dev->lock);
+ lis3lv02d_add_fs(dev);
+ lis3lv02d_increase_use(dev);
+
+ if (lis3lv02d_joystick_enable())
+ printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
+
+ printk("lis3_init_device: irq %d\n", dev->irq);
+
+ /* bail if we did not get an IRQ from the bus layer */
+ if (!dev->irq) {
+ printk(KERN_ERR DRIVER_NAME
+ ": No IRQ. Disabling /dev/freefall\n");
+ goto out;
+ }
+
+ printk("lis3: registering device\n");
+ if (misc_register(&lis3lv02d_misc_device))
+ printk(KERN_ERR DRIVER_NAME ": misc_register failed\n");
+out:
+ lis3lv02d_decrease_use(dev);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(lis3lv02d_init_device);
+
MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver");
MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 75972bf372ff..745ec96806d4 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -159,14 +159,14 @@ struct axis_conversion {
s8 z;
};
-struct acpi_lis3lv02d {
- struct acpi_device *device; /* The ACPI device */
- acpi_status (*init) (acpi_handle handle);
- acpi_status (*write) (acpi_handle handle, int reg, u8 val);
- acpi_status (*read) (acpi_handle handle, int reg, u8 *ret);
+struct lis3lv02d {
+ void *bus_priv; /* used by the bus layer only */
+ int (*init) (struct lis3lv02d *lis3);
+ int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
+ int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
u8 whoami; /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */
- s16 (*read_data) (acpi_handle handle, int reg);
+ s16 (*read_data) (struct lis3lv02d *lis3, int reg);
int mdps_max_val;
struct input_dev *idev; /* input device */
@@ -187,11 +187,11 @@ struct acpi_lis3lv02d {
unsigned long misc_opened; /* bit0: whether the device is open */
};
-int lis3lv02d_init_device(struct acpi_lis3lv02d *dev);
+int lis3lv02d_init_device(struct lis3lv02d *lis3);
int lis3lv02d_joystick_enable(void);
void lis3lv02d_joystick_disable(void);
-void lis3lv02d_poweroff(acpi_handle handle);
-void lis3lv02d_poweron(acpi_handle handle);
+void lis3lv02d_poweroff(struct lis3lv02d *lis3);
+void lis3lv02d_poweron(struct lis3lv02d *lis3);
int lis3lv02d_remove_fs(void);
-extern struct acpi_lis3lv02d adev;
+extern struct lis3lv02d lis3_dev;
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c
new file mode 100644
index 000000000000..07ae74b0e191
--- /dev/null
+++ b/drivers/hwmon/lis3lv02d_spi.c
@@ -0,0 +1,114 @@
+/*
+ * lis3lv02d_spi - SPI glue layer for lis3lv02d
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+
+#include "lis3lv02d.h"
+
+#define DRV_NAME "lis3lv02d_spi"
+#define LIS3_SPI_READ 0x80
+
+static int lis3_spi_read(struct lis3lv02d *lis3, int reg, u8 *v)
+{
+ struct spi_device *spi = lis3->bus_priv;
+ int ret = spi_w8r8(spi, reg | LIS3_SPI_READ);
+ if (ret < 0)
+ return -EINVAL;
+
+ *v = (u8) ret;
+ return 0;
+}
+
+static int lis3_spi_write(struct lis3lv02d *lis3, int reg, u8 val)
+{
+ u8 tmp[2] = { reg, val };
+ struct spi_device *spi = lis3->bus_priv;
+ return spi_write(spi, tmp, sizeof(tmp));
+}
+
+static int lis3_spi_init(struct lis3lv02d *lis3)
+{
+ u8 reg;
+ int ret;
+
+ /* power up the device */
+ ret = lis3->read(lis3, CTRL_REG1, &reg);
+ if (ret < 0)
+ return ret;
+
+ reg |= CTRL1_PD0;
+ return lis3->write(lis3, CTRL_REG1, reg);
+}
+
+static struct axis_conversion lis3lv02d_axis_normal = { 1, 2, 3 };
+
+static int __devinit lis302dl_spi_probe(struct spi_device *spi)
+{
+ int ret;
+
+ spi->bits_per_word = 8;
+ spi->mode = SPI_MODE_0;
+ ret = spi_setup(spi);
+ if (ret < 0)
+ return ret;
+
+ lis3_dev.bus_priv = spi;
+ lis3_dev.init = lis3_spi_init;
+ lis3_dev.read = lis3_spi_read;
+ lis3_dev.write = lis3_spi_write;
+ lis3_dev.irq = spi->irq;
+ lis3_dev.ac = lis3lv02d_axis_normal;
+ spi_set_drvdata(spi, &lis3_dev);
+
+ ret = lis3lv02d_init_device(&lis3_dev);
+ return ret;
+}
+
+static int __devexit lis302dl_spi_remove(struct spi_device *spi)
+{
+ struct lis3lv02d *lis3 = spi_get_drvdata(spi);
+ lis3lv02d_joystick_disable();
+ lis3lv02d_poweroff(lis3);
+ return 0;
+}
+
+static struct spi_driver lis302dl_spi_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = lis302dl_spi_probe,
+ .remove = __devexit_p(lis302dl_spi_remove),
+};
+
+static int __init lis302dl_init(void)
+{
+ return spi_register_driver(&lis302dl_spi_driver);
+}
+
+static void __exit lis302dl_exit(void)
+{
+ spi_unregister_driver(&lis302dl_spi_driver);
+}
+
+module_init(lis302dl_init);
+module_exit(lis302dl_exit);
+
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_DESCRIPTION("lis3lv02d SPI glue layer");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c
new file mode 100644
index 000000000000..091d95f38aaa
--- /dev/null
+++ b/drivers/hwmon/lm95241.c
@@ -0,0 +1,527 @@
+/*
+ * lm95241.c - Part of lm_sensors, Linux kernel modules for hardware
+ * monitoring
+ * Copyright (C) 2008 Davide Rizzo <elpa-rizzo@gmail.com>
+ *
+ * Based on the max1619 driver. The LM95241 is a sensor chip made by National
+ * Semiconductors.
+ * It reports up to three temperatures (its own plus up to
+ * two external ones). Complete datasheet can be
+ * obtained from National's website at:
+ * http://www.national.com/ds.cgi/LM/LM95241.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/sysfs.h>
+
+static const unsigned short normal_i2c[] = {
+ 0x19, 0x2a, 0x2b, I2C_CLIENT_END};
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(lm95241);
+
+/* LM95241 registers */
+#define LM95241_REG_R_MAN_ID 0xFE
+#define LM95241_REG_R_CHIP_ID 0xFF
+#define LM95241_REG_R_STATUS 0x02
+#define LM95241_REG_RW_CONFIG 0x03
+#define LM95241_REG_RW_REM_FILTER 0x06
+#define LM95241_REG_RW_TRUTHERM 0x07
+#define LM95241_REG_W_ONE_SHOT 0x0F
+#define LM95241_REG_R_LOCAL_TEMPH 0x10
+#define LM95241_REG_R_REMOTE1_TEMPH 0x11
+#define LM95241_REG_R_REMOTE2_TEMPH 0x12
+#define LM95241_REG_R_LOCAL_TEMPL 0x20
+#define LM95241_REG_R_REMOTE1_TEMPL 0x21
+#define LM95241_REG_R_REMOTE2_TEMPL 0x22
+#define LM95241_REG_RW_REMOTE_MODEL 0x30
+
+/* LM95241 specific bitfields */
+#define CFG_STOP 0x40
+#define CFG_CR0076 0x00
+#define CFG_CR0182 0x10
+#define CFG_CR1000 0x20
+#define CFG_CR2700 0x30
+#define R1MS_SHIFT 0
+#define R2MS_SHIFT 2
+#define R1MS_MASK (0x01 << (R1MS_SHIFT))
+#define R2MS_MASK (0x01 << (R2MS_SHIFT))
+#define R1DF_SHIFT 1
+#define R2DF_SHIFT 2
+#define R1DF_MASK (0x01 << (R1DF_SHIFT))
+#define R2DF_MASK (0x01 << (R2DF_SHIFT))
+#define R1FE_MASK 0x01
+#define R2FE_MASK 0x05
+#define TT1_SHIFT 0
+#define TT2_SHIFT 4
+#define TT_OFF 0
+#define TT_ON 1
+#define TT_MASK 7
+#define MANUFACTURER_ID 0x01
+#define DEFAULT_REVISION 0xA4
+
+/* Conversions and various macros */
+#define TEMP_FROM_REG(val_h, val_l) (((val_h) & 0x80 ? (val_h) - 0x100 : \
+ (val_h)) * 1000 + (val_l) * 1000 / 256)
+
+/* Functions declaration */
+static int lm95241_attach_adapter(struct i2c_adapter *adapter);
+static int lm95241_detect(struct i2c_adapter *adapter, int address,
+ int kind);
+static void lm95241_init_client(struct i2c_client *client);
+static int lm95241_detach_client(struct i2c_client *client);
+static struct lm95241_data *lm95241_update_device(struct device *dev);
+
+/* Driver data (common to all clients) */
+static struct i2c_driver lm95241_driver = {
+ .driver = {
+ .name = "lm95241",
+ },
+ .attach_adapter = lm95241_attach_adapter,
+ .detach_client = lm95241_detach_client,
+};
+
+/* Client data (each client gets its own) */
+struct lm95241_data {
+ struct i2c_client client;
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ unsigned long last_updated, rate; /* in jiffies */
+ char valid; /* zero until following fields are valid */
+ /* registers values */
+ u8 local_h, local_l; /* local */
+ u8 remote1_h, remote1_l; /* remote1 */
+ u8 remote2_h, remote2_l; /* remote2 */
+ u8 config, model, trutherm;
+};
+
+/* Sysfs stuff */
+#define show_temp(value) \
+static ssize_t show_##value(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct lm95241_data *data = lm95241_update_device(dev); \
+ snprintf(buf, PAGE_SIZE - 1, "%d\n", \
+ TEMP_FROM_REG(data->value##_h, data->value##_l)); \
+ return strlen(buf); \
+}
+show_temp(local);
+show_temp(remote1);
+show_temp(remote2);
+
+static ssize_t show_rate(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct lm95241_data *data = lm95241_update_device(dev);
+
+ snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->rate / HZ);
+ return strlen(buf);
+}
+
+static ssize_t set_rate(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm95241_data *data = i2c_get_clientdata(client);
+
+ strict_strtol(buf, 10, &data->rate);
+ data->rate = data->rate * HZ / 1000;
+
+ return count;
+}
+
+#define show_type(flag) \
+static ssize_t show_type##flag(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct i2c_client *client = to_i2c_client(dev); \
+ struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+ snprintf(buf, PAGE_SIZE - 1, \
+ data->model & R##flag##MS_MASK ? "1\n" : "2\n"); \
+ return strlen(buf); \
+}
+show_type(1);
+show_type(2);
+
+#define show_min(flag) \
+static ssize_t show_min##flag(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct i2c_client *client = to_i2c_client(dev); \
+ struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+ snprintf(buf, PAGE_SIZE - 1, \
+ data->config & R##flag##DF_MASK ? \
+ "-127000\n" : "0\n"); \
+ return strlen(buf); \
+}
+show_min(1);
+show_min(2);
+
+#define show_max(flag) \
+static ssize_t show_max##flag(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct i2c_client *client = to_i2c_client(dev); \
+ struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+ snprintf(buf, PAGE_SIZE - 1, \
+ data->config & R##flag##DF_MASK ? \
+ "127000\n" : "255000\n"); \
+ return strlen(buf); \
+}
+show_max(1);
+show_max(2);
+
+#define set_type(flag) \
+static ssize_t set_type##flag(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t count) \
+{ \
+ struct i2c_client *client = to_i2c_client(dev); \
+ struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+ long val; \
+ strict_strtol(buf, 10, &val); \
+\
+ if ((val == 1) || (val == 2)) { \
+\
+ mutex_lock(&data->update_lock); \
+\
+ data->trutherm &= ~(TT_MASK << TT##flag##_SHIFT); \
+ if (val == 1) { \
+ data->model |= R##flag##MS_MASK; \
+ data->trutherm |= (TT_ON << TT##flag##_SHIFT); \
+ } \
+ else { \
+ data->model &= ~R##flag##MS_MASK; \
+ data->trutherm |= (TT_OFF << TT##flag##_SHIFT); \
+ } \
+\
+ data->valid = 0; \
+\
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, \
+ data->model); \
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, \
+ data->trutherm); \
+\
+ mutex_unlock(&data->update_lock); \
+\
+ } \
+ return count; \
+}
+set_type(1);
+set_type(2);
+
+#define set_min(flag) \
+static ssize_t set_min##flag(struct device *dev, \
+ struct device_attribute *devattr, const char *buf, size_t count) \
+{ \
+ struct i2c_client *client = to_i2c_client(dev); \
+ struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+ long val; \
+ strict_strtol(buf, 10, &val); \
+\
+ mutex_lock(&data->update_lock); \
+\
+ if (val < 0) \
+ data->config |= R##flag##DF_MASK; \
+ else \
+ data->config &= ~R##flag##DF_MASK; \
+\
+ data->valid = 0; \
+\
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \
+ data->config); \
+\
+ mutex_unlock(&data->update_lock); \
+\
+ return count; \
+}
+set_min(1);
+set_min(2);
+
+#define set_max(flag) \
+static ssize_t set_max##flag(struct device *dev, \
+ struct device_attribute *devattr, const char *buf, size_t count) \
+{ \
+ struct i2c_client *client = to_i2c_client(dev); \
+ struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+ long val; \
+ strict_strtol(buf, 10, &val); \
+\
+ mutex_lock(&data->update_lock); \
+\
+ if (val <= 127000) \
+ data->config |= R##flag##DF_MASK; \
+ else \
+ data->config &= ~R##flag##DF_MASK; \
+\
+ data->valid = 0; \
+\
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \
+ data->config); \
+\
+ mutex_unlock(&data->update_lock); \
+\
+ return count; \
+}
+set_max(1);
+set_max(2);
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_local, NULL);
+static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote1, NULL);
+static DEVICE_ATTR(temp3_input, S_IRUGO, show_remote2, NULL);
+static DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type1, set_type1);
+static DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type2, set_type2);
+static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min1, set_min1);
+static DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min2, set_min2);
+static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max1, set_max1);
+static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max2, set_max2);
+static DEVICE_ATTR(rate, S_IWUSR | S_IRUGO, show_rate, set_rate);
+
+static struct attribute *lm95241_attributes[] = {
+ &dev_attr_temp1_input.attr,
+ &dev_attr_temp2_input.attr,
+ &dev_attr_temp3_input.attr,
+ &dev_attr_temp2_type.attr,
+ &dev_attr_temp3_type.attr,
+ &dev_attr_temp2_min.attr,
+ &dev_attr_temp3_min.attr,
+ &dev_attr_temp2_max.attr,
+ &dev_attr_temp3_max.attr,
+ &dev_attr_rate.attr,
+ NULL
+};
+
+static const struct attribute_group lm95241_group = {
+ .attrs = lm95241_attributes,
+};
+
+/* Init/exit code */
+static int lm95241_attach_adapter(struct i2c_adapter *adapter)
+{
+ if (!(adapter->class & I2C_CLASS_HWMON))
+ return 0;
+ return i2c_probe(adapter, &addr_data, lm95241_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+ struct i2c_client *new_client;
+ struct lm95241_data *data;
+ int err = 0;
+ const char *name = "";
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ goto exit;
+
+ data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ /* The common I2C client data is placed right before the
+ LM95241-specific data. */
+ new_client = &data->client;
+ i2c_set_clientdata(new_client, data);
+ new_client->addr = address;
+ new_client->adapter = adapter;
+ new_client->driver = &lm95241_driver;
+ new_client->flags = 0;
+
+ /*
+ * Now we do the remaining detection. A negative kind means that
+ * the driver was loaded with no force parameter (default), so we
+ * must both detect and identify the chip. A zero kind means that
+ * the driver was loaded with the force parameter, the detection
+ * step shall be skipped. A positive kind means that the driver
+ * was loaded with the force parameter and a given kind of chip is
+ * requested, so both the detection and the identification steps
+ * are skipped.
+ */
+ if (kind < 0) { /* detection */
+ if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
+ != MANUFACTURER_ID)
+ || (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
+ < DEFAULT_REVISION)) {
+ dev_dbg(&adapter->dev,
+ "LM95241 detection failed at 0x%02x.\n",
+ address);
+ goto exit_free;
+ }
+ }
+
+ if (kind <= 0) { /* identification */
+ if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
+ == MANUFACTURER_ID)
+ && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
+ >= DEFAULT_REVISION)) {
+
+ kind = lm95241;
+
+ if (kind <= 0) { /* identification failed */
+ dev_info(&adapter->dev, "Unsupported chip\n");
+ goto exit_free;
+ }
+ }
+ }
+
+ if (kind == lm95241)
+ name = "lm95241";
+
+ /* We can fill in the remaining client fields */
+ strlcpy(new_client->name, name, I2C_NAME_SIZE);
+ data->valid = 0;
+ mutex_init(&data->update_lock);
+
+ /* Tell the I2C layer a new client has arrived */
+ err = i2c_attach_client(new_client);
+ if (err)
+ goto exit_free;
+
+ /* Initialize the LM95241 chip */
+ lm95241_init_client(new_client);
+
+ /* Register sysfs hooks */
+ err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group);
+ if (err)
+ goto exit_detach;
+
+ data->hwmon_dev = hwmon_device_register(&new_client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ err = PTR_ERR(data->hwmon_dev);
+ goto exit_remove_files;
+ }
+
+ return 0;
+
+exit_remove_files:
+ sysfs_remove_group(&new_client->dev.kobj, &lm95241_group);
+exit_detach:
+ i2c_detach_client(new_client);
+exit_free:
+ kfree(data);
+exit:
+ return err;
+}
+
+static void lm95241_init_client(struct i2c_client *client)
+{
+ struct lm95241_data *data = i2c_get_clientdata(client);
+
+ data->rate = HZ; /* 1 sec default */
+ data->valid = 0;
+ data->config = CFG_CR0076;
+ data->model = 0;
+ data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT);
+
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG,
+ data->config);
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER,
+ R1FE_MASK | R2FE_MASK);
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM,
+ data->trutherm);
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL,
+ data->model);
+}
+
+static int lm95241_detach_client(struct i2c_client *client)
+{
+ struct lm95241_data *data = i2c_get_clientdata(client);
+ int err;
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &lm95241_group);
+
+ err = i2c_detach_client(client);
+ if (err)
+ return err;
+
+ kfree(data);
+ return 0;
+}
+
+static struct lm95241_data *lm95241_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm95241_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + data->rate) ||
+ !data->valid) {
+ dev_dbg(&client->dev, "Updating lm95241 data.\n");
+ data->local_h =
+ i2c_smbus_read_byte_data(client,
+ LM95241_REG_R_LOCAL_TEMPH);
+ data->local_l =
+ i2c_smbus_read_byte_data(client,
+ LM95241_REG_R_LOCAL_TEMPL);
+ data->remote1_h =
+ i2c_smbus_read_byte_data(client,
+ LM95241_REG_R_REMOTE1_TEMPH);
+ data->remote1_l =
+ i2c_smbus_read_byte_data(client,
+ LM95241_REG_R_REMOTE1_TEMPL);
+ data->remote2_h =
+ i2c_smbus_read_byte_data(client,
+ LM95241_REG_R_REMOTE2_TEMPH);
+ data->remote2_l =
+ i2c_smbus_read_byte_data(client,
+ LM95241_REG_R_REMOTE2_TEMPL);
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static int __init sensors_lm95241_init(void)
+{
+ return i2c_add_driver(&lm95241_driver);
+}
+
+static void __exit sensors_lm95241_exit(void)
+{
+ i2c_del_driver(&lm95241_driver);
+}
+
+MODULE_AUTHOR("Davide Rizzo <elpa-rizzo@gmail.com>");
+MODULE_DESCRIPTION("LM95241 sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm95241_init);
+module_exit(sensors_lm95241_exit);
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c
new file mode 100644
index 000000000000..9386e2a39211
--- /dev/null
+++ b/drivers/hwmon/ltc4215.c
@@ -0,0 +1,364 @@
+/*
+ * Driver for Linear Technology LTC4215 I2C Hot Swap Controller
+ *
+ * Copyright (C) 2009 Ira W. Snyder <iws@ovro.caltech.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * Datasheet:
+ * http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1163,P17572,D12697
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+
+static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(ltc4215);
+
+/* Here are names of the chip's registers (a.k.a. commands) */
+enum ltc4215_cmd {
+ LTC4215_CONTROL = 0x00, /* rw */
+ LTC4215_ALERT = 0x01, /* rw */
+ LTC4215_STATUS = 0x02, /* ro */
+ LTC4215_FAULT = 0x03, /* rw */
+ LTC4215_SENSE = 0x04, /* rw */
+ LTC4215_SOURCE = 0x05, /* rw */
+ LTC4215_ADIN = 0x06, /* rw */
+};
+
+struct ltc4215_data {
+ struct device *hwmon_dev;
+
+ struct mutex update_lock;
+ bool valid;
+ unsigned long last_updated; /* in jiffies */
+
+ /* Registers */
+ u8 regs[7];
+};
+
+static struct ltc4215_data *ltc4215_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ltc4215_data *data = i2c_get_clientdata(client);
+ s32 val;
+ int i;
+
+ mutex_lock(&data->update_lock);
+
+ /* The chip's A/D updates 10 times per second */
+ if (time_after(jiffies, data->last_updated + HZ / 10) || !data->valid) {
+
+ dev_dbg(&client->dev, "Starting ltc4215 update\n");
+
+ /* Read all registers */
+ for (i = 0; i < ARRAY_SIZE(data->regs); i++) {
+ val = i2c_smbus_read_byte_data(client, i);
+ if (unlikely(val < 0))
+ data->regs[i] = 0;
+ else
+ data->regs[i] = val;
+ }
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+/* Return the voltage from the given register in millivolts */
+static int ltc4215_get_voltage(struct device *dev, u8 reg)
+{
+ struct ltc4215_data *data = ltc4215_update_device(dev);
+ const u8 regval = data->regs[reg];
+ u32 voltage = 0;
+
+ switch (reg) {
+ case LTC4215_SENSE:
+ /* 151 uV per increment */
+ voltage = regval * 151 / 1000;
+ break;
+ case LTC4215_SOURCE:
+ /* 60.5 mV per increment */
+ voltage = regval * 605 / 10;
+ break;
+ case LTC4215_ADIN:
+ /* The ADIN input is divided by 12.5, and has 4.82 mV
+ * per increment, so we have the additional multiply */
+ voltage = regval * 482 * 125 / 1000;
+ break;
+ default:
+ /* If we get here, the developer messed up */
+ WARN_ON_ONCE(1);
+ break;
+ }
+
+ return voltage;
+}
+
+/* Return the current from the sense resistor in mA */
+static unsigned int ltc4215_get_current(struct device *dev)
+{
+ struct ltc4215_data *data = ltc4215_update_device(dev);
+
+ /* The strange looking conversions that follow are fixed-point
+ * math, since we cannot do floating point in the kernel.
+ *
+ * Step 1: convert sense register to microVolts
+ * Step 2: convert voltage to milliAmperes
+ *
+ * If you play around with the V=IR equation, you come up with
+ * the following: X uV / Y mOhm == Z mA
+ *
+ * With the resistors that are fractions of a milliOhm, we multiply
+ * the voltage and resistance by 10, to shift the decimal point.
+ * Now we can use the normal division operator again.
+ */
+
+ /* Calculate voltage in microVolts (151 uV per increment) */
+ const unsigned int voltage = data->regs[LTC4215_SENSE] * 151;
+
+ /* Calculate current in milliAmperes (4 milliOhm sense resistor) */
+ const unsigned int curr = voltage / 4;
+
+ return curr;
+}
+
+static ssize_t ltc4215_show_voltage(struct device *dev,
+ struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ const int voltage = ltc4215_get_voltage(dev, attr->index);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", voltage);
+}
+
+static ssize_t ltc4215_show_current(struct device *dev,
+ struct device_attribute *da,
+ char *buf)
+{
+ const unsigned int curr = ltc4215_get_current(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", curr);
+}
+
+static ssize_t ltc4215_show_power(struct device *dev,
+ struct device_attribute *da,
+ char *buf)
+{
+ const unsigned int curr = ltc4215_get_current(dev);
+ const int output_voltage = ltc4215_get_voltage(dev, LTC4215_ADIN);
+
+ /* current in mA * voltage in mV == power in uW */
+ const unsigned int power = abs(output_voltage * curr);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", power);
+}
+
+static ssize_t ltc4215_show_alarm(struct device *dev,
+ struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da);
+ struct ltc4215_data *data = ltc4215_update_device(dev);
+ const u8 reg = data->regs[attr->index];
+ const u32 mask = attr->nr;
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0);
+}
+
+/* These macros are used below in constructing device attribute objects
+ * for use with sysfs_create_group() to make a sysfs device file
+ * for each register.
+ */
+
+#define LTC4215_VOLTAGE(name, ltc4215_cmd_idx) \
+ static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
+ ltc4215_show_voltage, NULL, ltc4215_cmd_idx)
+
+#define LTC4215_CURRENT(name) \
+ static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
+ ltc4215_show_current, NULL, 0);
+
+#define LTC4215_POWER(name) \
+ static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
+ ltc4215_show_power, NULL, 0);
+
+#define LTC4215_ALARM(name, mask, reg) \
+ static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, \
+ ltc4215_show_alarm, NULL, (mask), reg)
+
+/* Construct a sensor_device_attribute structure for each register */
+
+/* Current */
+LTC4215_CURRENT(curr1_input);
+LTC4215_ALARM(curr1_max_alarm, (1 << 2), LTC4215_STATUS);
+
+/* Power (virtual) */
+LTC4215_POWER(power1_input);
+LTC4215_ALARM(power1_alarm, (1 << 3), LTC4215_STATUS);
+
+/* Input Voltage */
+LTC4215_VOLTAGE(in1_input, LTC4215_ADIN);
+LTC4215_ALARM(in1_max_alarm, (1 << 0), LTC4215_STATUS);
+LTC4215_ALARM(in1_min_alarm, (1 << 1), LTC4215_STATUS);
+
+/* Output Voltage */
+LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE);
+
+/* Finally, construct an array of pointers to members of the above objects,
+ * as required for sysfs_create_group()
+ */
+static struct attribute *ltc4215_attributes[] = {
+ &sensor_dev_attr_curr1_input.dev_attr.attr,
+ &sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
+
+ &sensor_dev_attr_power1_input.dev_attr.attr,
+ &sensor_dev_attr_power1_alarm.dev_attr.attr,
+
+ &sensor_dev_attr_in1_input.dev_attr.attr,
+ &sensor_dev_attr_in1_max_alarm.dev_attr.attr,
+ &sensor_dev_attr_in1_min_alarm.dev_attr.attr,
+
+ &sensor_dev_attr_in2_input.dev_attr.attr,
+
+ NULL,
+};
+
+static const struct attribute_group ltc4215_group = {
+ .attrs = ltc4215_attributes,
+};
+
+static int ltc4215_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct ltc4215_data *data;
+ int ret;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto out_kzalloc;
+ }
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+
+ /* Initialize the LTC4215 chip */
+ /* TODO */
+
+ /* Register sysfs hooks */
+ ret = sysfs_create_group(&client->dev.kobj, &ltc4215_group);
+ if (ret)
+ goto out_sysfs_create_group;
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ ret = PTR_ERR(data->hwmon_dev);
+ goto out_hwmon_device_register;
+ }
+
+ return 0;
+
+out_hwmon_device_register:
+ sysfs_remove_group(&client->dev.kobj, &ltc4215_group);
+out_sysfs_create_group:
+ kfree(data);
+out_kzalloc:
+ return ret;
+}
+
+static int ltc4215_remove(struct i2c_client *client)
+{
+ struct ltc4215_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &ltc4215_group);
+
+ kfree(data);
+
+ return 0;
+}
+
+static int ltc4215_detect(struct i2c_client *client,
+ int kind,
+ struct i2c_board_info *info)
+{
+ struct i2c_adapter *adapter = client->adapter;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ if (kind < 0) { /* probed detection - check the chip type */
+ s32 v; /* 8 bits from the chip, or -ERRNO */
+
+ /*
+ * Register 0x01 bit b7 is reserved, expect 0
+ * Register 0x03 bit b6 and b7 are reserved, expect 0
+ */
+ v = i2c_smbus_read_byte_data(client, LTC4215_ALERT);
+ if (v < 0 || (v & (1 << 7)) != 0)
+ return -ENODEV;
+
+ v = i2c_smbus_read_byte_data(client, LTC4215_FAULT);
+ if (v < 0 || (v & ((1 << 6) | (1 << 7))) != 0)
+ return -ENODEV;
+ }
+
+ strlcpy(info->type, "ltc4215", I2C_NAME_SIZE);
+ dev_info(&adapter->dev, "ltc4215 %s at address 0x%02x\n",
+ kind < 0 ? "probed" : "forced",
+ client->addr);
+
+ return 0;
+}
+
+static const struct i2c_device_id ltc4215_id[] = {
+ { "ltc4215", ltc4215 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ltc4215_id);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver ltc4215_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "ltc4215",
+ },
+ .probe = ltc4215_probe,
+ .remove = ltc4215_remove,
+ .id_table = ltc4215_id,
+ .detect = ltc4215_detect,
+ .address_data = &addr_data,
+};
+
+static int __init ltc4215_init(void)
+{
+ return i2c_add_driver(&ltc4215_driver);
+}
+
+static void __exit ltc4215_exit(void)
+{
+ i2c_del_driver(&ltc4215_driver);
+}
+
+MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
+MODULE_DESCRIPTION("LTC4215 driver");
+MODULE_LICENSE("GPL");
+
+module_init(ltc4215_init);
+module_exit(ltc4215_exit);
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/hwmon/pcf8591.c
index 16ce3e193776..1d7ffebd679d 100644
--- a/drivers/i2c/chips/pcf8591.c
+++ b/drivers/hwmon/pcf8591.c
@@ -1,6 +1,6 @@
/*
Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net>
- Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
+ Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
the help of Jean Delvare <khali@linux-fr.org>
This program is free software; you can redistribute it and/or modify
@@ -41,13 +41,13 @@ MODULE_PARM_DESC(input_mode,
" 3 = two differential inputs\n");
/* The PCF8591 control byte
- 7 6 5 4 3 2 1 0
+ 7 6 5 4 3 2 1 0
| 0 |AOEF| AIP | 0 |AINC| AICH | */
/* Analog Output Enable Flag (analog output active if 1) */
#define PCF8591_CONTROL_AOEF 0x40
-
-/* Analog Input Programming
+
+/* Analog Input Programming
0x00 = four single ended inputs
0x10 = three differential inputs
0x20 = single ended and differential mixed
@@ -58,7 +58,7 @@ MODULE_PARM_DESC(input_mode,
#define PCF8591_CONTROL_AINC 0x04
/* Channel selection
- 0x00 = channel 0
+ 0x00 = channel 0
0x01 = channel 1
0x02 = channel 2
0x03 = channel 3 */
@@ -114,7 +114,7 @@ static ssize_t set_out0_output(struct device *dev, struct device_attribute *attr
return -EINVAL;
}
-static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO,
+static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO,
show_out0_ouput, set_out0_output);
static ssize_t show_out0_enable(struct device *dev, struct device_attribute *attr, char *buf)
@@ -139,7 +139,7 @@ static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr
return count;
}
-static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO,
+static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO,
show_out0_enable, set_out0_enable);
static struct attribute *pcf8591_attributes[] = {
@@ -196,7 +196,7 @@ static int pcf8591_probe(struct i2c_client *client,
err = -ENOMEM;
goto exit;
}
-
+
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
@@ -249,8 +249,8 @@ static void pcf8591_init_client(struct i2c_client *client)
data->aout = PCF8591_INIT_AOUT;
i2c_smbus_write_byte_data(client, data->control, data->aout);
-
- /* The first byte transmitted contains the conversion code of the
+
+ /* The first byte transmitted contains the conversion code of the
previous read cycle. FLUSH IT! */
i2c_smbus_read_byte(client);
}
@@ -267,8 +267,8 @@ static int pcf8591_read_channel(struct device *dev, int channel)
data->control = (data->control & ~PCF8591_CONTROL_AICH_MASK)
| channel;
i2c_smbus_write_byte(client, data->control);
-
- /* The first byte transmitted contains the conversion code of
+
+ /* The first byte transmitted contains the conversion code of
the previous read cycle. FLUSH IT! */
i2c_smbus_read_byte(client);
}
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index feae743ba991..e64b42058b21 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -36,6 +36,7 @@
w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3
0x8860 0xa1
w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3
+ w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3
*/
#include <linux/module.h>
@@ -52,12 +53,13 @@
#include <asm/io.h>
#include "lm75.h"
-enum kinds { w83627ehf, w83627dhg };
+enum kinds { w83627ehf, w83627dhg, w83667hg };
/* used to set data->name = w83627ehf_device_names[data->sio_kind] */
static const char * w83627ehf_device_names[] = {
"w83627ehf",
"w83627dhg",
+ "w83667hg",
};
static unsigned short force_id;
@@ -71,6 +73,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID");
*/
#define W83627EHF_LD_HWM 0x0b
+#define W83667HG_LD_VID 0x0d
#define SIO_REG_LDSEL 0x07 /* Logical device select */
#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
@@ -83,6 +86,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID");
#define SIO_W83627EHF_ID 0x8850
#define SIO_W83627EHG_ID 0x8860
#define SIO_W83627DHG_ID 0xa020
+#define SIO_W83667HG_ID 0xa510
#define SIO_ID_MASK 0xFFF0
static inline void
@@ -289,6 +293,7 @@ struct w83627ehf_data {
u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */
u8 pwm_enable[4]; /* 1->manual
2->thermal cruise (also called SmartFan I) */
+ u8 pwm_num; /* number of pwm */
u8 pwm[4];
u8 target_temp[4];
u8 tolerance[4];
@@ -298,6 +303,9 @@ struct w83627ehf_data {
u8 vid;
u8 vrm;
+
+ u8 temp3_disable;
+ u8 in6_skip;
};
struct w83627ehf_sio_data {
@@ -866,25 +874,37 @@ show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
return sprintf(buf, "%d\n", (int)data->temp_type[nr]);
}
-static struct sensor_device_attribute sda_temp[] = {
+static struct sensor_device_attribute sda_temp_input[] = {
SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0),
SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0),
SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 1),
+};
+
+static struct sensor_device_attribute sda_temp_max[] = {
SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1_max,
store_temp1_max, 0),
SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max,
store_temp_max, 0),
SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max,
store_temp_max, 1),
+};
+
+static struct sensor_device_attribute sda_temp_max_hyst[] = {
SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1_max_hyst,
store_temp1_max_hyst, 0),
SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
store_temp_max_hyst, 0),
SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
store_temp_max_hyst, 1),
+};
+
+static struct sensor_device_attribute sda_temp_alarm[] = {
SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4),
SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5),
SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13),
+};
+
+static struct sensor_device_attribute sda_temp_type[] = {
SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0),
SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1),
SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2),
@@ -1181,6 +1201,8 @@ static void w83627ehf_device_remove_files(struct device *dev)
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
for (i = 0; i < data->in_num; i++) {
+ if ((i == 6) && data->in6_skip)
+ continue;
device_remove_file(dev, &sda_in_input[i].dev_attr);
device_remove_file(dev, &sda_in_alarm[i].dev_attr);
device_remove_file(dev, &sda_in_min[i].dev_attr);
@@ -1192,15 +1214,22 @@ static void w83627ehf_device_remove_files(struct device *dev)
device_remove_file(dev, &sda_fan_div[i].dev_attr);
device_remove_file(dev, &sda_fan_min[i].dev_attr);
}
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < data->pwm_num; i++) {
device_remove_file(dev, &sda_pwm[i].dev_attr);
device_remove_file(dev, &sda_pwm_mode[i].dev_attr);
device_remove_file(dev, &sda_pwm_enable[i].dev_attr);
device_remove_file(dev, &sda_target_temp[i].dev_attr);
device_remove_file(dev, &sda_tolerance[i].dev_attr);
}
- for (i = 0; i < ARRAY_SIZE(sda_temp); i++)
- device_remove_file(dev, &sda_temp[i].dev_attr);
+ for (i = 0; i < 3; i++) {
+ if ((i == 2) && data->temp3_disable)
+ continue;
+ device_remove_file(dev, &sda_temp_input[i].dev_attr);
+ device_remove_file(dev, &sda_temp_max[i].dev_attr);
+ device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
+ device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
+ device_remove_file(dev, &sda_temp_type[i].dev_attr);
+ }
device_remove_file(dev, &dev_attr_name);
device_remove_file(dev, &dev_attr_cpu0_vid);
@@ -1222,6 +1251,8 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data)
for (i = 0; i < 2; i++) {
tmp = w83627ehf_read_value(data,
W83627EHF_REG_TEMP_CONFIG[i]);
+ if ((i == 1) && data->temp3_disable)
+ continue;
if (tmp & 0x01)
w83627ehf_write_value(data,
W83627EHF_REG_TEMP_CONFIG[i],
@@ -1272,8 +1303,17 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
data->name = w83627ehf_device_names[sio_data->kind];
platform_set_drvdata(pdev, data);
- /* 627EHG and 627EHF have 10 voltage inputs; DHG has 9 */
- data->in_num = (sio_data->kind == w83627dhg) ? 9 : 10;
+ /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
+ data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9;
+ /* 667HG has 3 pwms */
+ data->pwm_num = (sio_data->kind == w83667hg) ? 3 : 4;
+
+ /* Check temp3 configuration bit for 667HG */
+ if (sio_data->kind == w83667hg) {
+ data->temp3_disable = w83627ehf_read_value(data,
+ W83627EHF_REG_TEMP_CONFIG[1]) & 0x01;
+ data->in6_skip = !data->temp3_disable;
+ }
/* Initialize the chip */
w83627ehf_init_device(data);
@@ -1281,44 +1321,64 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
data->vrm = vid_which_vrm();
superio_enter(sio_data->sioreg);
/* Read VID value */
- superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
- if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
- /* Set VID input sensibility if needed. In theory the BIOS
- should have set it, but in practice it's not always the
- case. We only do it for the W83627EHF/EHG because the
- W83627DHG is more complex in this respect. */
- if (sio_data->kind == w83627ehf) {
- en_vrm10 = superio_inb(sio_data->sioreg,
- SIO_REG_EN_VRM10);
- if ((en_vrm10 & 0x08) && data->vrm == 90) {
- dev_warn(dev, "Setting VID input voltage to "
- "TTL\n");
- superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
- en_vrm10 & ~0x08);
- } else if (!(en_vrm10 & 0x08) && data->vrm == 100) {
- dev_warn(dev, "Setting VID input voltage to "
- "VRM10\n");
- superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
- en_vrm10 | 0x08);
- }
- }
-
- data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA);
- if (sio_data->kind == w83627ehf) /* 6 VID pins only */
- data->vid &= 0x3f;
-
+ if (sio_data->kind == w83667hg) {
+ /* W83667HG has different pins for VID input and output, so
+ we can get the VID input values directly at logical device D
+ 0xe3. */
+ superio_select(sio_data->sioreg, W83667HG_LD_VID);
+ data->vid = superio_inb(sio_data->sioreg, 0xe3);
err = device_create_file(dev, &dev_attr_cpu0_vid);
if (err)
goto exit_release;
} else {
- dev_info(dev, "VID pins in output mode, CPU VID not "
- "available\n");
+ superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
+ if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
+ /* Set VID input sensibility if needed. In theory the
+ BIOS should have set it, but in practice it's not
+ always the case. We only do it for the W83627EHF/EHG
+ because the W83627DHG is more complex in this
+ respect. */
+ if (sio_data->kind == w83627ehf) {
+ en_vrm10 = superio_inb(sio_data->sioreg,
+ SIO_REG_EN_VRM10);
+ if ((en_vrm10 & 0x08) && data->vrm == 90) {
+ dev_warn(dev, "Setting VID input "
+ "voltage to TTL\n");
+ superio_outb(sio_data->sioreg,
+ SIO_REG_EN_VRM10,
+ en_vrm10 & ~0x08);
+ } else if (!(en_vrm10 & 0x08)
+ && data->vrm == 100) {
+ dev_warn(dev, "Setting VID input "
+ "voltage to VRM10\n");
+ superio_outb(sio_data->sioreg,
+ SIO_REG_EN_VRM10,
+ en_vrm10 | 0x08);
+ }
+ }
+
+ data->vid = superio_inb(sio_data->sioreg,
+ SIO_REG_VID_DATA);
+ if (sio_data->kind == w83627ehf) /* 6 VID pins only */
+ data->vid &= 0x3f;
+
+ err = device_create_file(dev, &dev_attr_cpu0_vid);
+ if (err)
+ goto exit_release;
+ } else {
+ dev_info(dev, "VID pins in output mode, CPU VID not "
+ "available\n");
+ }
}
/* fan4 and fan5 share some pins with the GPIO and serial flash */
-
- fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2;
- fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6;
+ if (sio_data->kind == w83667hg) {
+ fan5pin = superio_inb(sio_data->sioreg, 0x27) & 0x20;
+ fan4pin = superio_inb(sio_data->sioreg, 0x27) & 0x40;
+ } else {
+ fan5pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x02);
+ fan4pin = !(superio_inb(sio_data->sioreg, 0x29) & 0x06);
+ }
superio_exit(sio_data->sioreg);
/* It looks like fan4 and fan5 pins can be alternatively used
@@ -1329,9 +1389,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
data->has_fan = 0x07; /* fan1, fan2 and fan3 */
i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1);
- if ((i & (1 << 2)) && (!fan4pin))
+ if ((i & (1 << 2)) && fan4pin)
data->has_fan |= (1 << 3);
- if (!(i & (1 << 1)) && (!fan5pin))
+ if (!(i & (1 << 1)) && fan5pin)
data->has_fan |= (1 << 4);
/* Read fan clock dividers immediately */
@@ -1344,14 +1404,16 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
goto exit_remove;
/* if fan4 is enabled create the sf3 files for it */
- if (data->has_fan & (1 << 3))
+ if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4)
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
if ((err = device_create_file(dev,
&sda_sf3_arrays_fan4[i].dev_attr)))
goto exit_remove;
}
- for (i = 0; i < data->in_num; i++)
+ for (i = 0; i < data->in_num; i++) {
+ if ((i == 6) && data->in6_skip)
+ continue;
if ((err = device_create_file(dev, &sda_in_input[i].dev_attr))
|| (err = device_create_file(dev,
&sda_in_alarm[i].dev_attr))
@@ -1360,6 +1422,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
|| (err = device_create_file(dev,
&sda_in_max[i].dev_attr)))
goto exit_remove;
+ }
for (i = 0; i < 5; i++) {
if (data->has_fan & (1 << i)) {
@@ -1372,7 +1435,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
|| (err = device_create_file(dev,
&sda_fan_min[i].dev_attr)))
goto exit_remove;
- if (i < 4 && /* w83627ehf only has 4 pwm */
+ if (i < data->pwm_num &&
((err = device_create_file(dev,
&sda_pwm[i].dev_attr))
|| (err = device_create_file(dev,
@@ -1387,9 +1450,21 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
}
}
- for (i = 0; i < ARRAY_SIZE(sda_temp); i++)
- if ((err = device_create_file(dev, &sda_temp[i].dev_attr)))
+ for (i = 0; i < 3; i++) {
+ if ((i == 2) && data->temp3_disable)
+ continue;
+ if ((err = device_create_file(dev,
+ &sda_temp_input[i].dev_attr))
+ || (err = device_create_file(dev,
+ &sda_temp_max[i].dev_attr))
+ || (err = device_create_file(dev,
+ &sda_temp_max_hyst[i].dev_attr))
+ || (err = device_create_file(dev,
+ &sda_temp_alarm[i].dev_attr))
+ || (err = device_create_file(dev,
+ &sda_temp_type[i].dev_attr)))
goto exit_remove;
+ }
err = device_create_file(dev, &dev_attr_name);
if (err)
@@ -1442,6 +1517,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
static const char __initdata sio_name_W83627EHF[] = "W83627EHF";
static const char __initdata sio_name_W83627EHG[] = "W83627EHG";
static const char __initdata sio_name_W83627DHG[] = "W83627DHG";
+ static const char __initdata sio_name_W83667HG[] = "W83667HG";
u16 val;
const char *sio_name;
@@ -1466,6 +1542,10 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
sio_data->kind = w83627dhg;
sio_name = sio_name_W83627DHG;
break;
+ case SIO_W83667HG_ID:
+ sio_data->kind = w83667hg;
+ sio_name = sio_name_W83667HG;
+ break;
default:
if (val != 0xffff)
pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n",
diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig
index b788579b8227..7b2ce4a08524 100644
--- a/drivers/i2c/algos/Kconfig
+++ b/drivers/i2c/algos/Kconfig
@@ -14,8 +14,4 @@ config I2C_ALGOPCF
config I2C_ALGOPCA
tristate "I2C PCA 9564 interfaces"
-config I2C_ALGO_SGI
- tristate
- depends on SGI_IP22 || SGI_IP32 || X86_VISWS
-
endmenu
diff --git a/drivers/i2c/algos/Makefile b/drivers/i2c/algos/Makefile
index cac1051bd4f1..18b3e962ec09 100644
--- a/drivers/i2c/algos/Makefile
+++ b/drivers/i2c/algos/Makefile
@@ -5,7 +5,6 @@
obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o
obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o
obj-$(CONFIG_I2C_ALGOPCA) += i2c-algo-pca.o
-obj-$(CONFIG_I2C_ALGO_SGI) += i2c-algo-sgi.o
ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
index eb8f72ca02f4..d420cc5f5633 100644
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -604,9 +604,7 @@ static int i2c_bit_prepare_bus(struct i2c_adapter *adap)
/* register new adapter to i2c module... */
adap->algo = &i2c_bit_algo;
-
- adap->timeout = 100; /* default values, should */
- adap->retries = 3; /* be replaced by defines */
+ adap->retries = 3;
return 0;
}
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
index d50b329a3c94..f68e5f8e23ee 100644
--- a/drivers/i2c/algos/i2c-algo-pca.c
+++ b/drivers/i2c/algos/i2c-algo-pca.c
@@ -22,14 +22,18 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-pca.h>
-#define DEB1(fmt, args...) do { if (i2c_debug>=1) printk(fmt, ## args); } while(0)
-#define DEB2(fmt, args...) do { if (i2c_debug>=2) printk(fmt, ## args); } while(0)
-#define DEB3(fmt, args...) do { if (i2c_debug>=3) printk(fmt, ## args); } while(0)
+#define DEB1(fmt, args...) do { if (i2c_debug >= 1) \
+ printk(KERN_DEBUG fmt, ## args); } while (0)
+#define DEB2(fmt, args...) do { if (i2c_debug >= 2) \
+ printk(KERN_DEBUG fmt, ## args); } while (0)
+#define DEB3(fmt, args...) do { if (i2c_debug >= 3) \
+ printk(KERN_DEBUG fmt, ## args); } while (0)
static int i2c_debug;
@@ -43,19 +47,27 @@ static int i2c_debug;
#define pca_wait(adap) adap->wait_for_completion(adap->data)
#define pca_reset(adap) adap->reset_chip(adap->data)
+static void pca9665_reset(void *pd)
+{
+ struct i2c_algo_pca_data *adap = pd;
+ pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET);
+ pca_outw(adap, I2C_PCA_IND, 0xA5);
+ pca_outw(adap, I2C_PCA_IND, 0x5A);
+}
+
/*
* Generate a start condition on the i2c bus.
*
* returns after the start condition has occurred
*/
-static void pca_start(struct i2c_algo_pca_data *adap)
+static int pca_start(struct i2c_algo_pca_data *adap)
{
int sta = pca_get_con(adap);
DEB2("=== START\n");
sta |= I2C_PCA_CON_STA;
sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI);
pca_set_con(adap, sta);
- pca_wait(adap);
+ return pca_wait(adap);
}
/*
@@ -63,14 +75,14 @@ static void pca_start(struct i2c_algo_pca_data *adap)
*
* return after the repeated start condition has occurred
*/
-static void pca_repeated_start(struct i2c_algo_pca_data *adap)
+static int pca_repeated_start(struct i2c_algo_pca_data *adap)
{
int sta = pca_get_con(adap);
DEB2("=== REPEATED START\n");
sta |= I2C_PCA_CON_STA;
sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI);
pca_set_con(adap, sta);
- pca_wait(adap);
+ return pca_wait(adap);
}
/*
@@ -96,7 +108,7 @@ static void pca_stop(struct i2c_algo_pca_data *adap)
*
* returns after the address has been sent
*/
-static void pca_address(struct i2c_algo_pca_data *adap,
+static int pca_address(struct i2c_algo_pca_data *adap,
struct i2c_msg *msg)
{
int sta = pca_get_con(adap);
@@ -113,7 +125,7 @@ static void pca_address(struct i2c_algo_pca_data *adap,
sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
pca_set_con(adap, sta);
- pca_wait(adap);
+ return pca_wait(adap);
}
/*
@@ -121,7 +133,7 @@ static void pca_address(struct i2c_algo_pca_data *adap,
*
* Returns after the byte has been transmitted
*/
-static void pca_tx_byte(struct i2c_algo_pca_data *adap,
+static int pca_tx_byte(struct i2c_algo_pca_data *adap,
__u8 b)
{
int sta = pca_get_con(adap);
@@ -131,7 +143,7 @@ static void pca_tx_byte(struct i2c_algo_pca_data *adap,
sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI);
pca_set_con(adap, sta);
- pca_wait(adap);
+ return pca_wait(adap);
}
/*
@@ -151,7 +163,7 @@ static void pca_rx_byte(struct i2c_algo_pca_data *adap,
*
* Returns after next byte has arrived.
*/
-static void pca_rx_ack(struct i2c_algo_pca_data *adap,
+static int pca_rx_ack(struct i2c_algo_pca_data *adap,
int ack)
{
int sta = pca_get_con(adap);
@@ -162,7 +174,7 @@ static void pca_rx_ack(struct i2c_algo_pca_data *adap,
sta |= I2C_PCA_CON_AA;
pca_set_con(adap, sta);
- pca_wait(adap);
+ return pca_wait(adap);
}
static int pca_xfer(struct i2c_adapter *i2c_adap,
@@ -175,14 +187,17 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
int numbytes = 0;
int state;
int ret;
- int timeout = i2c_adap->timeout;
-
- while ((state = pca_status(adap)) != 0xf8 && timeout--) {
- msleep(10);
- }
- if (state != 0xf8) {
- dev_dbg(&i2c_adap->dev, "bus is not idle. status is %#04x\n", state);
- return -EAGAIN;
+ int completed = 1;
+ unsigned long timeout = jiffies + i2c_adap->timeout;
+
+ while (pca_status(adap) != 0xf8) {
+ if (time_before(jiffies, timeout)) {
+ msleep(10);
+ } else {
+ dev_dbg(&i2c_adap->dev, "bus is not idle. status is "
+ "%#04x\n", state);
+ return -EAGAIN;
+ }
}
DEB1("{{{ XFER %d messages\n", num);
@@ -218,18 +233,19 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
switch (state) {
case 0xf8: /* On reset or stop the bus is idle */
- pca_start(adap);
+ completed = pca_start(adap);
break;
case 0x08: /* A START condition has been transmitted */
case 0x10: /* A repeated start condition has been transmitted */
- pca_address(adap, msg);
+ completed = pca_address(adap, msg);
break;
case 0x18: /* SLA+W has been transmitted; ACK has been received */
case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */
if (numbytes < msg->len) {
- pca_tx_byte(adap, msg->buf[numbytes]);
+ completed = pca_tx_byte(adap,
+ msg->buf[numbytes]);
numbytes++;
break;
}
@@ -237,7 +253,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
if (curmsg == num)
pca_stop(adap);
else
- pca_repeated_start(adap);
+ completed = pca_repeated_start(adap);
break;
case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */
@@ -246,21 +262,22 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
goto out;
case 0x40: /* SLA+R has been transmitted; ACK has been received */
- pca_rx_ack(adap, msg->len > 1);
+ completed = pca_rx_ack(adap, msg->len > 1);
break;
case 0x50: /* Data bytes has been received; ACK has been returned */
if (numbytes < msg->len) {
pca_rx_byte(adap, &msg->buf[numbytes], 1);
numbytes++;
- pca_rx_ack(adap, numbytes < msg->len - 1);
+ completed = pca_rx_ack(adap,
+ numbytes < msg->len - 1);
break;
}
curmsg++; numbytes = 0;
if (curmsg == num)
pca_stop(adap);
else
- pca_repeated_start(adap);
+ completed = pca_repeated_start(adap);
break;
case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */
@@ -283,7 +300,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
if (curmsg == num)
pca_stop(adap);
else
- pca_repeated_start(adap);
+ completed = pca_repeated_start(adap);
} else {
DEB2("NOT ACK sent after data byte received. "
"Not final byte. numbytes %d. len %d\n",
@@ -309,11 +326,13 @@ static int pca_xfer(struct i2c_adapter *i2c_adap,
break;
}
+ if (!completed)
+ goto out;
}
ret = curmsg;
out:
- DEB1(KERN_CRIT "}}} transfered %d/%d messages. "
+ DEB1("}}} transfered %d/%d messages. "
"status is %#04x. control is %#04x\n",
curmsg, num, pca_status(adap),
pca_get_con(adap));
@@ -330,26 +349,171 @@ static const struct i2c_algorithm pca_algo = {
.functionality = pca_func,
};
-static int pca_init(struct i2c_adapter *adap)
+static unsigned int pca_probe_chip(struct i2c_adapter *adap)
{
- static int freqs[] = {330,288,217,146,88,59,44,36};
- int clock;
struct i2c_algo_pca_data *pca_data = adap->algo_data;
-
- if (pca_data->i2c_clock > 7) {
- printk(KERN_WARNING "%s: Invalid I2C clock speed selected. Trying default.\n",
- adap->name);
- pca_data->i2c_clock = I2C_PCA_CON_59kHz;
+ /* The trick here is to check if there is an indirect register
+ * available. If there is one, we will read the value we first
+ * wrote on I2C_PCA_IADR. Otherwise, we will read the last value
+ * we wrote on I2C_PCA_ADR
+ */
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
+ pca_outw(pca_data, I2C_PCA_IND, 0xAA);
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ITO);
+ pca_outw(pca_data, I2C_PCA_IND, 0x00);
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
+ if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) {
+ printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name);
+ return I2C_PCA_CHIP_9665;
+ } else {
+ printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name);
+ return I2C_PCA_CHIP_9564;
}
+}
+
+static int pca_init(struct i2c_adapter *adap)
+{
+ struct i2c_algo_pca_data *pca_data = adap->algo_data;
adap->algo = &pca_algo;
- pca_reset(pca_data);
+ if (pca_probe_chip(adap) == I2C_PCA_CHIP_9564) {
+ static int freqs[] = {330, 288, 217, 146, 88, 59, 44, 36};
+ int clock;
+
+ if (pca_data->i2c_clock > 7) {
+ switch (pca_data->i2c_clock) {
+ case 330000:
+ pca_data->i2c_clock = I2C_PCA_CON_330kHz;
+ break;
+ case 288000:
+ pca_data->i2c_clock = I2C_PCA_CON_288kHz;
+ break;
+ case 217000:
+ pca_data->i2c_clock = I2C_PCA_CON_217kHz;
+ break;
+ case 146000:
+ pca_data->i2c_clock = I2C_PCA_CON_146kHz;
+ break;
+ case 88000:
+ pca_data->i2c_clock = I2C_PCA_CON_88kHz;
+ break;
+ case 59000:
+ pca_data->i2c_clock = I2C_PCA_CON_59kHz;
+ break;
+ case 44000:
+ pca_data->i2c_clock = I2C_PCA_CON_44kHz;
+ break;
+ case 36000:
+ pca_data->i2c_clock = I2C_PCA_CON_36kHz;
+ break;
+ default:
+ printk(KERN_WARNING
+ "%s: Invalid I2C clock speed selected."
+ " Using default 59kHz.\n", adap->name);
+ pca_data->i2c_clock = I2C_PCA_CON_59kHz;
+ }
+ } else {
+ printk(KERN_WARNING "%s: "
+ "Choosing the clock frequency based on "
+ "index is deprecated."
+ " Use the nominal frequency.\n", adap->name);
+ }
+
+ pca_reset(pca_data);
+
+ clock = pca_clock(pca_data);
+ printk(KERN_INFO "%s: Clock frequency is %dkHz\n",
+ adap->name, freqs[clock]);
+
+ pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
+ } else {
+ int clock;
+ int mode;
+ int tlow, thi;
+ /* Values can be found on PCA9665 datasheet section 7.3.2.6 */
+ int min_tlow, min_thi;
+ /* These values are the maximum raise and fall values allowed
+ * by the I2C operation mode (Standard, Fast or Fast+)
+ * They are used (added) below to calculate the clock dividers
+ * of PCA9665. Note that they are slightly different of the
+ * real maximum, to allow the change on mode exactly on the
+ * maximum clock rate for each mode
+ */
+ int raise_fall_time;
+
+ struct i2c_algo_pca_data *pca_data = adap->algo_data;
+
+ /* Ignore the reset function from the module,
+ * we can use the parallel bus reset
+ */
+ pca_data->reset_chip = pca9665_reset;
+
+ if (pca_data->i2c_clock > 1265800) {
+ printk(KERN_WARNING "%s: I2C clock speed too high."
+ " Using 1265.8kHz.\n", adap->name);
+ pca_data->i2c_clock = 1265800;
+ }
+
+ if (pca_data->i2c_clock < 60300) {
+ printk(KERN_WARNING "%s: I2C clock speed too low."
+ " Using 60.3kHz.\n", adap->name);
+ pca_data->i2c_clock = 60300;
+ }
- clock = pca_clock(pca_data);
- DEB1(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]);
+ /* To avoid integer overflow, use clock/100 for calculations */
+ clock = pca_clock(pca_data) / 100;
+
+ if (pca_data->i2c_clock > 10000) {
+ mode = I2C_PCA_MODE_TURBO;
+ min_tlow = 14;
+ min_thi = 5;
+ raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */
+ } else if (pca_data->i2c_clock > 4000) {
+ mode = I2C_PCA_MODE_FASTP;
+ min_tlow = 17;
+ min_thi = 9;
+ raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */
+ } else if (pca_data->i2c_clock > 1000) {
+ mode = I2C_PCA_MODE_FAST;
+ min_tlow = 44;
+ min_thi = 20;
+ raise_fall_time = 58; /* Raise 29e-8s, Fall 29e-8s */
+ } else {
+ mode = I2C_PCA_MODE_STD;
+ min_tlow = 157;
+ min_thi = 134;
+ raise_fall_time = 127; /* Raise 29e-8s, Fall 98e-8s */
+ }
+
+ /* The minimum clock that respects the thi/tlow = 134/157 is
+ * 64800 Hz. Below that, we have to fix the tlow to 255 and
+ * calculate the thi factor.
+ */
+ if (clock < 648) {
+ tlow = 255;
+ thi = 1000000 - clock * raise_fall_time;
+ thi /= (I2C_PCA_OSC_PER * clock) - tlow;
+ } else {
+ tlow = (1000000 - clock * raise_fall_time) * min_tlow;
+ tlow /= I2C_PCA_OSC_PER * clock * (min_thi + min_tlow);
+ thi = tlow * min_thi / min_tlow;
+ }
- pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
+ pca_reset(pca_data);
+
+ printk(KERN_INFO
+ "%s: Clock frequency is %dHz\n", adap->name, clock * 100);
+
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IMODE);
+ pca_outw(pca_data, I2C_PCA_IND, mode);
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLL);
+ pca_outw(pca_data, I2C_PCA_IND, tlow);
+ pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLH);
+ pca_outw(pca_data, I2C_PCA_IND, thi);
+
+ pca_set_con(pca_data, I2C_PCA_CON_ENSIO);
+ }
udelay(500); /* 500 us for oscilator to stabilise */
return 0;
@@ -384,7 +548,7 @@ EXPORT_SYMBOL(i2c_pca_add_numbered_bus);
MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, "
"Wolfram Sang <w.sang@pengutronix.de>");
-MODULE_DESCRIPTION("I2C-Bus PCA9564 algorithm");
+MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm");
MODULE_LICENSE("GPL");
module_param(i2c_debug, int, 0);
diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c
index 3e01992230b8..7ce75775ec73 100644
--- a/drivers/i2c/algos/i2c-algo-pcf.c
+++ b/drivers/i2c/algos/i2c-algo-pcf.c
@@ -1,31 +1,30 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters */
-/* ------------------------------------------------------------------------- */
-/* Copyright (C) 1995-1997 Simon G. Vogl
- 1998-2000 Hans Berglund
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
- Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
- <mbailey@littlefeet-inc.com> */
-
-/* Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
- messages, proper stop/repstart signaling during receive,
- added detect code */
+/*
+ * i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters
+ *
+ * Copyright (C) 1995-1997 Simon G. Vogl
+ * 1998-2000 Hans Berglund
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
+ * Frodo Looijaard <frodol@dds.nl>, and also from Martin Bailey
+ * <mbailey@littlefeet-inc.com>
+ *
+ * Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
+ * messages, proper stop/repstart signaling during receive, added detect code
+ */
#include <linux/kernel.h>
#include <linux/module.h>
@@ -38,17 +37,18 @@
#include "i2c-algo-pcf.h"
-#define DEB2(x) if (i2c_debug>=2) x
-#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/
-#define DEBPROTO(x) if (i2c_debug>=9) x;
- /* debug the protocol by showing transferred bits */
+#define DEB2(x) if (i2c_debug >= 2) x
+#define DEB3(x) if (i2c_debug >= 3) x /* print several statistical values */
+#define DEBPROTO(x) if (i2c_debug >= 9) x;
+ /* debug the protocol by showing transferred bits */
#define DEF_TIMEOUT 16
-/* module parameters:
+/*
+ * module parameters:
*/
static int i2c_debug;
-/* --- setting states on the bus with the right timing: --------------- */
+/* setting states on the bus with the right timing: */
#define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val)
#define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl)
@@ -57,22 +57,21 @@ static int i2c_debug;
#define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val)
#define i2c_inb(adap) adap->getpcf(adap->data, 0)
-/* --- other auxiliary functions -------------------------------------- */
+/* other auxiliary functions */
-static void i2c_start(struct i2c_algo_pcf_data *adap)
+static void i2c_start(struct i2c_algo_pcf_data *adap)
{
- DEBPROTO(printk("S "));
+ DEBPROTO(printk(KERN_DEBUG "S "));
set_pcf(adap, 1, I2C_PCF_START);
}
-static void i2c_repstart(struct i2c_algo_pcf_data *adap)
+static void i2c_repstart(struct i2c_algo_pcf_data *adap)
{
DEBPROTO(printk(" Sr "));
set_pcf(adap, 1, I2C_PCF_REPSTART);
}
-
-static void i2c_stop(struct i2c_algo_pcf_data *adap)
+static void i2c_stop(struct i2c_algo_pcf_data *adap)
{
DEBPROTO(printk("P\n"));
set_pcf(adap, 1, I2C_PCF_STOP);
@@ -82,17 +81,17 @@ static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status)
{
DEB2(printk(KERN_INFO
"i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",
- *status));
-
- /* Cleanup from LAB -- reset and enable ESO.
+ *status));
+ /*
+ * Cleanup from LAB -- reset and enable ESO.
* This resets the PCF8584; since we've lost the bus, no
* further attempts should be made by callers to clean up
* (no i2c_stop() etc.)
*/
set_pcf(adap, 1, I2C_PCF_PIN);
set_pcf(adap, 1, I2C_PCF_ESO);
-
- /* We pause for a time period sufficient for any running
+ /*
+ * We pause for a time period sufficient for any running
* I2C transaction to complete -- the arbitration logic won't
* work properly until the next START is seen.
* It is assumed the bus driver or client has set a proper value.
@@ -108,48 +107,50 @@ static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status)
get_pcf(adap, 1)));
}
-static int wait_for_bb(struct i2c_algo_pcf_data *adap) {
+static int wait_for_bb(struct i2c_algo_pcf_data *adap)
+{
int timeout = DEF_TIMEOUT;
int status;
status = get_pcf(adap, 1);
-#ifndef STUB_I2C
- while (timeout-- && !(status & I2C_PCF_BB)) {
+
+ while (!(status & I2C_PCF_BB) && --timeout) {
udelay(100); /* wait for 100 us */
status = get_pcf(adap, 1);
}
-#endif
- if (timeout <= 0) {
+
+ if (timeout == 0) {
printk(KERN_ERR "Timeout waiting for Bus Busy\n");
+ return -ETIMEDOUT;
}
-
- return (timeout<=0);
-}
+ return 0;
+}
-static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) {
+static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status)
+{
int timeout = DEF_TIMEOUT;
*status = get_pcf(adap, 1);
-#ifndef STUB_I2C
- while (timeout-- && (*status & I2C_PCF_PIN)) {
+
+ while ((*status & I2C_PCF_PIN) && --timeout) {
adap->waitforpin(adap->data);
*status = get_pcf(adap, 1);
}
if (*status & I2C_PCF_LAB) {
handle_lab(adap, status);
- return(-EINTR);
+ return -EINTR;
}
-#endif
- if (timeout <= 0)
- return(-1);
- else
- return(0);
+
+ if (timeout == 0)
+ return -ETIMEDOUT;
+
+ return 0;
}
-/*
+/*
* This should perform the 'PCF8584 initialization sequence' as described
* in the Philips IC12 data book (1995, Aug 29).
* There should be a 30 clock cycle wait after reset, I assume this
@@ -164,18 +165,21 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
{
unsigned char temp;
- DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1)));
+ DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n",
+ get_pcf(adap, 1)));
/* S1=0x80: S0 selected, serial interface off */
set_pcf(adap, 1, I2C_PCF_PIN);
- /* check to see S1 now used as R/W ctrl -
- PCF8584 does that when ESO is zero */
+ /*
+ * check to see S1 now used as R/W ctrl -
+ * PCF8584 does that when ESO is zero
+ */
if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) {
DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
return -ENXIO; /* definetly not PCF8584 */
}
- /* load own address in S0, effective address is (own << 1) */
+ /* load own address in S0, effective address is (own << 1) */
i2c_outb(adap, get_own(adap));
/* check it's really written */
if ((temp = i2c_inb(adap)) != get_own(adap)) {
@@ -183,7 +187,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
return -ENXIO;
}
- /* S1=0xA0, next byte in S2 */
+ /* S1=0xA0, next byte in S2 */
set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
/* check to see S2 now selected */
if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) {
@@ -191,7 +195,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
return -ENXIO;
}
- /* load clock register S2 */
+ /* load clock register S2 */
i2c_outb(adap, get_clock(adap));
/* check it's really written, the only 5 lowest bits does matter */
if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
@@ -199,7 +203,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
return -ENXIO;
}
- /* Enable serial interface, idle, S0 selected */
+ /* Enable serial interface, idle, S0 selected */
set_pcf(adap, 1, I2C_PCF_IDLE);
/* check to see PCF is really idled and we can access status register */
@@ -207,57 +211,47 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
return -ENXIO;
}
-
+
printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n");
return 0;
}
-
-/* ----- Utility functions
- */
-
static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
- int count, int last)
+ int count, int last)
{
struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
int wrcount, status, timeout;
-
+
for (wrcount=0; wrcount<count; ++wrcount) {
DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n",
- buf[wrcount]&0xff));
+ buf[wrcount] & 0xff));
i2c_outb(adap, buf[wrcount]);
timeout = wait_for_pin(adap, &status);
if (timeout) {
- if (timeout == -EINTR) {
- /* arbitration lost */
- return -EINTR;
- }
+ if (timeout == -EINTR)
+ return -EINTR; /* arbitration lost */
+
i2c_stop(adap);
dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n");
return -EREMOTEIO; /* got a better one ?? */
}
-#ifndef STUB_I2C
if (status & I2C_PCF_LRB) {
i2c_stop(adap);
dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n");
return -EREMOTEIO; /* got a better one ?? */
}
-#endif
}
- if (last) {
+ if (last)
i2c_stop(adap);
- }
- else {
+ else
i2c_repstart(adap);
- }
- return (wrcount);
+ return wrcount;
}
-
static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
- int count, int last)
+ int count, int last)
{
int i, status;
struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
@@ -267,42 +261,36 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
for (i = 0; i <= count; i++) {
if ((wfp = wait_for_pin(adap, &status))) {
- if (wfp == -EINTR) {
- /* arbitration lost */
- return -EINTR;
- }
+ if (wfp == -EINTR)
+ return -EINTR; /* arbitration lost */
+
i2c_stop(adap);
dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n");
- return (-1);
+ return -1;
}
-#ifndef STUB_I2C
if ((status & I2C_PCF_LRB) && (i != count)) {
i2c_stop(adap);
dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n");
- return (-1);
+ return -1;
}
-#endif
-
+
if (i == count - 1) {
set_pcf(adap, 1, I2C_PCF_ESO);
- } else
- if (i == count) {
- if (last) {
+ } else if (i == count) {
+ if (last)
i2c_stop(adap);
- } else {
+ else
i2c_repstart(adap);
- }
- };
+ }
- if (i) {
+ if (i)
buf[i - 1] = i2c_inb(adap);
- } else {
+ else
i2c_inb(adap); /* dummy read */
- }
}
- return (i - 1);
+ return i - 1;
}
@@ -323,14 +311,14 @@ static int pcf_doAddress(struct i2c_algo_pcf_data *adap,
}
static int pcf_xfer(struct i2c_adapter *i2c_adap,
- struct i2c_msg *msgs,
+ struct i2c_msg *msgs,
int num)
{
struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
struct i2c_msg *pmsg;
int i;
int ret=0, timeout, status;
-
+
if (adap->xfer_begin)
adap->xfer_begin(adap->data);
@@ -338,25 +326,24 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
timeout = wait_for_bb(adap);
if (timeout) {
DEB2(printk(KERN_ERR "i2c-algo-pcf.o: "
- "Timeout waiting for BB in pcf_xfer\n");)
+ "Timeout waiting for BB in pcf_xfer\n");)
i = -EIO;
goto out;
}
-
+
for (i = 0;ret >= 0 && i < num; i++) {
pmsg = &msgs[i];
DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",
pmsg->flags & I2C_M_RD ? "read" : "write",
- pmsg->len, pmsg->addr, i + 1, num);)
-
+ pmsg->len, pmsg->addr, i + 1, num);)
+
ret = pcf_doAddress(adap, pmsg);
/* Send START */
- if (i == 0) {
- i2c_start(adap);
- }
-
+ if (i == 0)
+ i2c_start(adap);
+
/* Wait for PIN (pending interrupt NOT) */
timeout = wait_for_pin(adap, &status);
if (timeout) {
@@ -371,8 +358,7 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
i = -EREMOTEIO;
goto out;
}
-
-#ifndef STUB_I2C
+
/* Check LRB (last rcvd bit - slave ack) */
if (status & I2C_PCF_LRB) {
i2c_stop(adap);
@@ -380,27 +366,24 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
i = -EREMOTEIO;
goto out;
}
-#endif
-
+
DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
-
- /* Read */
+
if (pmsg->flags & I2C_M_RD) {
- /* read bytes into buffer*/
ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,
- (i + 1 == num));
-
+ (i + 1 == num));
+
if (ret != pmsg->len) {
DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
"only read %d bytes.\n",ret));
} else {
DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret));
}
- } else { /* Write */
+ } else {
ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
- (i + 1 == num));
-
+ (i + 1 == num));
+
if (ret != pmsg->len) {
DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
"only wrote %d bytes.\n",ret));
@@ -413,24 +396,23 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap,
out:
if (adap->xfer_end)
adap->xfer_end(adap->data);
- return (i);
+ return i;
}
static u32 pcf_func(struct i2c_adapter *adap)
{
- return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
I2C_FUNC_PROTOCOL_MANGLING;
}
-/* -----exported algorithm data: ------------------------------------- */
-
+/* exported algorithm data: */
static const struct i2c_algorithm pcf_algo = {
.master_xfer = pcf_xfer,
.functionality = pcf_func,
};
-/*
- * registering functions to load algorithms at runtime
+/*
+ * registering functions to load algorithms at runtime
*/
int i2c_pcf_add_bus(struct i2c_adapter *adap)
{
@@ -441,7 +423,6 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap)
/* register new adapter to i2c module... */
adap->algo = &pcf_algo;
- adap->timeout = 100;
if ((rval = pcf_init_8584(pcf_adap)))
return rval;
@@ -458,4 +439,4 @@ MODULE_LICENSE("GPL");
module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(i2c_debug,
- "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
+ "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
diff --git a/drivers/i2c/algos/i2c-algo-sgi.c b/drivers/i2c/algos/i2c-algo-sgi.c
deleted file mode 100644
index 6eaf145e1ada..000000000000
--- a/drivers/i2c/algos/i2c-algo-sgi.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * i2c-algo-sgi.c: i2c driver algorithm used by the VINO (SGI Indy) and
- * MACE (SGI O2) chips.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-sgi.h>
-
-
-#define SGI_I2C_FORCE_IDLE (0 << 0)
-#define SGI_I2C_NOT_IDLE (1 << 0)
-#define SGI_I2C_WRITE (0 << 1)
-#define SGI_I2C_READ (1 << 1)
-#define SGI_I2C_RELEASE_BUS (0 << 2)
-#define SGI_I2C_HOLD_BUS (1 << 2)
-#define SGI_I2C_XFER_DONE (0 << 4)
-#define SGI_I2C_XFER_BUSY (1 << 4)
-#define SGI_I2C_ACK (0 << 5)
-#define SGI_I2C_NACK (1 << 5)
-#define SGI_I2C_BUS_OK (0 << 7)
-#define SGI_I2C_BUS_ERR (1 << 7)
-
-#define get_control() adap->getctrl(adap->data)
-#define set_control(val) adap->setctrl(adap->data, val)
-#define read_data() adap->rdata(adap->data)
-#define write_data(val) adap->wdata(adap->data, val)
-
-
-static int wait_xfer_done(struct i2c_algo_sgi_data *adap)
-{
- int i;
-
- for (i = 0; i < adap->xfer_timeout; i++) {
- if ((get_control() & SGI_I2C_XFER_BUSY) == 0)
- return 0;
- udelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-static int wait_ack(struct i2c_algo_sgi_data *adap)
-{
- int i;
-
- if (wait_xfer_done(adap))
- return -ETIMEDOUT;
- for (i = 0; i < adap->ack_timeout; i++) {
- if ((get_control() & SGI_I2C_NACK) == 0)
- return 0;
- udelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-static int force_idle(struct i2c_algo_sgi_data *adap)
-{
- int i;
-
- set_control(SGI_I2C_FORCE_IDLE);
- for (i = 0; i < adap->xfer_timeout; i++) {
- if ((get_control() & SGI_I2C_NOT_IDLE) == 0)
- goto out;
- udelay(1);
- }
- return -ETIMEDOUT;
-out:
- if (get_control() & SGI_I2C_BUS_ERR)
- return -EIO;
- return 0;
-}
-
-static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr,
- int rd)
-{
- if (rd)
- set_control(SGI_I2C_NOT_IDLE);
- /* Check if bus is idle, eventually force it to do so */
- if (get_control() & SGI_I2C_NOT_IDLE)
- if (force_idle(adap))
- return -EIO;
- /* Write out the i2c chip address and specify operation */
- set_control(SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE);
- if (rd)
- addr |= 1;
- write_data(addr);
- if (wait_ack(adap))
- return -EIO;
- return 0;
-}
-
-static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf,
- unsigned int len)
-{
- int i;
-
- set_control(SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE);
- for (i = 0; i < len; i++) {
- if (wait_xfer_done(adap))
- return -EIO;
- buf[i] = read_data();
- }
- set_control(SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE);
-
- return 0;
-
-}
-
-static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf,
- unsigned int len)
-{
- int i;
-
- /* We are already in write state */
- for (i = 0; i < len; i++) {
- write_data(buf[i]);
- if (wait_ack(adap))
- return -EIO;
- }
- return 0;
-}
-
-static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
- int num)
-{
- struct i2c_algo_sgi_data *adap = i2c_adap->algo_data;
- struct i2c_msg *p;
- int i, err = 0;
-
- for (i = 0; !err && i < num; i++) {
- p = &msgs[i];
- err = do_address(adap, p->addr, p->flags & I2C_M_RD);
- if (err || !p->len)
- continue;
- if (p->flags & I2C_M_RD)
- err = i2c_read(adap, p->buf, p->len);
- else
- err = i2c_write(adap, p->buf, p->len);
- }
-
- return (err < 0) ? err : i;
-}
-
-static u32 sgi_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm sgi_algo = {
- .master_xfer = sgi_xfer,
- .functionality = sgi_func,
-};
-
-/*
- * registering functions to load algorithms at runtime
- */
-int i2c_sgi_add_bus(struct i2c_adapter *adap)
-{
- adap->algo = &sgi_algo;
-
- return i2c_add_adapter(adap);
-}
-EXPORT_SYMBOL(i2c_sgi_add_bus);
-
-MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
-MODULE_DESCRIPTION("I2C-Bus SGI algorithm");
-MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 7f95905bbb9d..da809ad0996a 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -132,6 +132,7 @@ config I2C_PIIX4
Serverworks CSB5
Serverworks CSB6
Serverworks HT-1000
+ Serverworks HT-1100
SMSC Victory66
This driver can also be built as a module. If so, the module
@@ -617,12 +618,12 @@ config I2C_ELEKTOR
will be called i2c-elektor.
config I2C_PCA_ISA
- tristate "PCA9564 on an ISA bus"
+ tristate "PCA9564/PCA9665 on an ISA bus"
depends on ISA
select I2C_ALGOPCA
default n
help
- This driver supports ISA boards using the Philips PCA9564
+ This driver supports ISA boards using the Philips PCA9564/PCA9665
parallel bus to I2C bus controller.
This driver can also be built as a module. If so, the module
@@ -634,11 +635,11 @@ config I2C_PCA_ISA
time). If unsure, say N.
config I2C_PCA_PLATFORM
- tristate "PCA9564 as platform device"
+ tristate "PCA9564/PCA9665 as platform device"
select I2C_ALGOPCA
default n
help
- This driver supports a memory mapped Philips PCA9564
+ This driver supports a memory mapped Philips PCA9564/PCA9665
parallel bus to I2C bus controller.
This driver can also be built as a module. If so, the module
diff --git a/drivers/i2c/busses/i2c-acorn.c b/drivers/i2c/busses/i2c-acorn.c
index 9aefb5e5864d..86796488ef4f 100644
--- a/drivers/i2c/busses/i2c-acorn.c
+++ b/drivers/i2c/busses/i2c-acorn.c
@@ -15,9 +15,9 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
+#include <linux/io.h>
#include <mach/hardware.h>
-#include <asm/io.h>
#include <asm/hardware/ioc.h>
#include <asm/system.h>
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 5d7789834b95..3fae3a91ce5b 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -216,7 +216,7 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev,
{
unsigned long timeout;
- timeout = jiffies + DAVINCI_I2C_TIMEOUT;
+ timeout = jiffies + dev->adapter.timeout;
while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG)
& DAVINCI_I2C_STR_BB) {
if (time_after(jiffies, timeout)) {
@@ -289,7 +289,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
- DAVINCI_I2C_TIMEOUT);
+ dev->adapter.timeout);
if (r == 0) {
dev_err(dev->dev, "controller timed out\n");
i2c_davinci_init(dev);
@@ -546,9 +546,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
strlcpy(adap->name, "DaVinci I2C adapter", sizeof(adap->name));
adap->algo = &i2c_davinci_algo;
adap->dev.parent = &pdev->dev;
-
- /* FIXME */
- adap->timeout = 1;
+ adap->timeout = DAVINCI_I2C_TIMEOUT;
adap->nr = pdev->id;
r = i2c_add_numbered_adapter(adap);
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 230238df56c4..10411848fd70 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -65,6 +65,7 @@
#include <linux/i2c.h>
#include <linux/acpi.h>
#include <linux/io.h>
+#include <linux/dmi.h>
/* I801 SMBus address offsets */
#define SMBHSTSTS (0 + i801_smba)
@@ -616,10 +617,81 @@ static void __init input_apanel_init(void)
static void __init input_apanel_init(void) {}
#endif
+#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
+struct dmi_onboard_device_info {
+ const char *name;
+ u8 type;
+ unsigned short i2c_addr;
+ const char *i2c_type;
+};
+
+static struct dmi_onboard_device_info __devinitdata dmi_devices[] = {
+ { "Syleus", DMI_DEV_TYPE_OTHER, 0x73, "fscsyl" },
+ { "Hermes", DMI_DEV_TYPE_OTHER, 0x73, "fscher" },
+ { "Hades", DMI_DEV_TYPE_OTHER, 0x73, "fschds" },
+};
+
+static void __devinit dmi_check_onboard_device(u8 type, const char *name,
+ struct i2c_adapter *adap)
+{
+ int i;
+ struct i2c_board_info info;
+
+ for (i = 0; i < ARRAY_SIZE(dmi_devices); i++) {
+ /* & ~0x80, ignore enabled/disabled bit */
+ if ((type & ~0x80) != dmi_devices[i].type)
+ continue;
+ if (strcmp(name, dmi_devices[i].name))
+ continue;
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ info.addr = dmi_devices[i].i2c_addr;
+ strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE);
+ i2c_new_device(adap, &info);
+ break;
+ }
+}
+
+/* We use our own function to check for onboard devices instead of
+ dmi_find_device() as some buggy BIOS's have the devices we are interested
+ in marked as disabled */
+static void __devinit dmi_check_onboard_devices(const struct dmi_header *dm,
+ void *adap)
+{
+ int i, count;
+
+ if (dm->type != 10)
+ return;
+
+ count = (dm->length - sizeof(struct dmi_header)) / 2;
+ for (i = 0; i < count; i++) {
+ const u8 *d = (char *)(dm + 1) + (i * 2);
+ const char *name = ((char *) dm) + dm->length;
+ u8 type = d[0];
+ u8 s = d[1];
+
+ if (!s)
+ continue;
+ s--;
+ while (s > 0 && name[0]) {
+ name += strlen(name) + 1;
+ s--;
+ }
+ if (name[0] == 0) /* Bogus string reference */
+ continue;
+
+ dmi_check_onboard_device(type, name, adap);
+ }
+}
+#endif
+
static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
unsigned char temp;
int err;
+#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
+ const char *vendor;
+#endif
I801_dev = dev;
i801_features = 0;
@@ -712,6 +784,11 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
i2c_new_device(&i801_adapter, &info);
}
#endif
+#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
+ vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
+ if (vendor && !strcmp(vendor, "FUJITSU SIEMENS"))
+ dmi_walk(dmi_check_onboard_devices, &i801_adapter);
+#endif
return 0;
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index 88f0db73b364..8b92a4666e02 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -415,7 +415,7 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){
if (dev->irq >= 0){
/* Interrupt mode */
ret = wait_event_interruptible_timeout(dev->wq,
- !(in_8(&iic->sts) & STS_PT), dev->adap.timeout * HZ);
+ !(in_8(&iic->sts) & STS_PT), dev->adap.timeout);
if (unlikely(ret < 0))
DBG("%d: wait interrupted\n", dev->idx);
@@ -426,7 +426,7 @@ static int iic_wait_for_tc(struct ibm_iic_private* dev){
}
else {
/* Polling mode */
- unsigned long x = jiffies + dev->adap.timeout * HZ;
+ unsigned long x = jiffies + dev->adap.timeout;
while (in_8(&iic->sts) & STS_PT){
if (unlikely(time_after(jiffies, x))){
@@ -748,7 +748,7 @@ static int __devinit iic_probe(struct of_device *ofdev,
i2c_set_adapdata(adap, dev);
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->algo = &iic_algo;
- adap->timeout = 1;
+ adap->timeout = HZ;
ret = i2c_add_adapter(adap);
if (ret < 0) {
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index 3190690c26ce..a75c75e77b92 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -488,7 +488,7 @@ iop3xx_i2c_probe(struct platform_device *pdev)
/*
* Default values...should these come in from board code?
*/
- new_adapter->timeout = 100;
+ new_adapter->timeout = HZ;
new_adapter->algo = &iop3xx_i2c_algo;
init_waitqueue_head(&adapter_data->waitq);
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index aedbbe6618db..26bf37010586 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -70,7 +70,7 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
/* Read again to allow register to stabilise */
i2c->interrupt = readb(i2c->base + MPC_I2C_SR);
writeb(0, i2c->base + MPC_I2C_SR);
- wake_up_interruptible(&i2c->queue);
+ wake_up(&i2c->queue);
}
return IRQ_HANDLED;
}
@@ -115,13 +115,10 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
writeb(0, i2c->base + MPC_I2C_SR);
} else {
/* Interrupt mode */
- result = wait_event_interruptible_timeout(i2c->queue,
- (i2c->interrupt & CSR_MIF), timeout * HZ);
+ result = wait_event_timeout(i2c->queue,
+ (i2c->interrupt & CSR_MIF), timeout);
- if (unlikely(result < 0)) {
- pr_debug("I2C: wait interrupted\n");
- writeccr(i2c, 0);
- } else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
+ if (unlikely(!(i2c->interrupt & CSR_MIF))) {
pr_debug("I2C: wait timeout\n");
writeccr(i2c, 0);
result = -ETIMEDOUT;
@@ -311,7 +308,7 @@ static struct i2c_adapter mpc_ops = {
.owner = THIS_MODULE,
.name = "MPC adapter",
.algo = &mpc_algo,
- .timeout = 1,
+ .timeout = HZ,
};
static int __devinit fsl_i2c_probe(struct of_device *op, const struct of_device_id *match)
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 7f186bbcb99d..5a4945d1dba4 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -358,7 +358,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
char abort = 0;
time_left = wait_event_interruptible_timeout(drv_data->waitq,
- !drv_data->block, msecs_to_jiffies(drv_data->adapter.timeout));
+ !drv_data->block, drv_data->adapter.timeout);
spin_lock_irqsave(&drv_data->lock, flags);
if (!time_left) { /* Timed out */
@@ -374,8 +374,7 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
spin_unlock_irqrestore(&drv_data->lock, flags);
time_left = wait_event_timeout(drv_data->waitq,
- !drv_data->block,
- msecs_to_jiffies(drv_data->adapter.timeout));
+ !drv_data->block, drv_data->adapter.timeout);
if ((time_left <= 0) && drv_data->block) {
drv_data->state = MV64XXX_I2C_STATE_IDLE;
@@ -530,7 +529,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
drv_data->adapter.algo = &mv64xxx_i2c_algo;
drv_data->adapter.owner = THIS_MODULE;
drv_data->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
- drv_data->adapter.timeout = pdata->timeout;
+ drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
drv_data->adapter.nr = pd->id;
platform_set_drvdata(pd, drv_data);
i2c_set_adapdata(&drv_data->adapter, drv_data);
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index 05af6cd7f270..2ff4683703a8 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -31,10 +31,14 @@
nForce3 250Gb MCP 00E4
nForce4 MCP 0052
nForce4 MCP-04 0034
- nForce4 MCP51 0264
- nForce4 MCP55 0368
+ nForce MCP51 0264
+ nForce MCP55 0368
nForce MCP61 03EB
nForce MCP65 0446
+ nForce MCP67 0542
+ nForce MCP73 07D8
+ nForce MCP78S 0752
+ nForce MCP79 0AA2
This driver supports the 2 SMBuses that are included in the MCP of the
nForce2/3/4/5xx chipsets.
@@ -315,6 +319,10 @@ static struct pci_device_id nforce2_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS) },
{ 0 }
};
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index be8ee2cac8bb..ece0125a1ee5 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -193,22 +193,24 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
{
- if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
- dev->iclk = clk_get(dev->dev, "i2c_ick");
- if (IS_ERR(dev->iclk)) {
- dev->iclk = NULL;
- return -ENODEV;
- }
+ int ret;
+
+ dev->iclk = clk_get(dev->dev, "ick");
+ if (IS_ERR(dev->iclk)) {
+ ret = PTR_ERR(dev->iclk);
+ dev->iclk = NULL;
+ return ret;
}
- dev->fclk = clk_get(dev->dev, "i2c_fck");
+ dev->fclk = clk_get(dev->dev, "fck");
if (IS_ERR(dev->fclk)) {
+ ret = PTR_ERR(dev->fclk);
if (dev->iclk != NULL) {
clk_put(dev->iclk);
dev->iclk = NULL;
}
dev->fclk = NULL;
- return -ENODEV;
+ return ret;
}
return 0;
@@ -218,18 +220,15 @@ static void omap_i2c_put_clocks(struct omap_i2c_dev *dev)
{
clk_put(dev->fclk);
dev->fclk = NULL;
- if (dev->iclk != NULL) {
- clk_put(dev->iclk);
- dev->iclk = NULL;
- }
+ clk_put(dev->iclk);
+ dev->iclk = NULL;
}
static void omap_i2c_unidle(struct omap_i2c_dev *dev)
{
WARN_ON(!dev->idle);
- if (dev->iclk != NULL)
- clk_enable(dev->iclk);
+ clk_enable(dev->iclk);
clk_enable(dev->fclk);
dev->idle = 0;
if (dev->iestate)
@@ -254,8 +253,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
}
dev->idle = 1;
clk_disable(dev->fclk);
- if (dev->iclk != NULL)
- clk_disable(dev->iclk);
+ clk_disable(dev->iclk);
}
static int omap_i2c_init(struct omap_i2c_dev *dev)
@@ -312,15 +310,14 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
if (cpu_class_is_omap1()) {
- struct clk *armxor_ck;
-
- armxor_ck = clk_get(NULL, "armxor_ck");
- if (IS_ERR(armxor_ck))
- dev_warn(dev->dev, "Could not get armxor_ck\n");
- else {
- fclk_rate = clk_get_rate(armxor_ck);
- clk_put(armxor_ck);
- }
+ /*
+ * The I2C functional clock is the armxor_ck, so there's
+ * no need to get "armxor_ck" separately. Now, if OMAP2420
+ * always returns 12MHz for the functional clock, we can
+ * do this bit unconditionally.
+ */
+ fclk_rate = clk_get_rate(dev->fclk);
+
/* TRM for 5912 says the I2C clock must be prescaled to be
* between 7 - 12 MHz. The XOR input clock is typically
* 12, 13 or 19.2 MHz. So we should have code that produces:
diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c
index 4aa8138cb0a9..0ed68e2ccd22 100644
--- a/drivers/i2c/busses/i2c-pca-isa.c
+++ b/drivers/i2c/busses/i2c-pca-isa.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
@@ -41,15 +42,17 @@ static int irq = -1;
/* Data sheet recommends 59kHz for 100kHz operation due to variation
* in the actual clock rate */
-static int clock = I2C_PCA_CON_59kHz;
+static int clock = 59000;
+static struct i2c_adapter pca_isa_ops;
static wait_queue_head_t pca_wait;
static void pca_isa_writebyte(void *pd, int reg, int val)
{
#ifdef DEBUG_IO
static char *names[] = { "T/O", "DAT", "ADR", "CON" };
- printk("*** write %s at %#lx <= %#04x\n", names[reg], base+reg, val);
+ printk(KERN_DEBUG "*** write %s at %#lx <= %#04x\n", names[reg],
+ base+reg, val);
#endif
outb(val, base+reg);
}
@@ -60,7 +63,7 @@ static int pca_isa_readbyte(void *pd, int reg)
#ifdef DEBUG_IO
{
static char *names[] = { "STA", "DAT", "ADR", "CON" };
- printk("*** read %s => %#04x\n", names[reg], res);
+ printk(KERN_DEBUG "*** read %s => %#04x\n", names[reg], res);
}
#endif
return res;
@@ -68,16 +71,22 @@ static int pca_isa_readbyte(void *pd, int reg)
static int pca_isa_waitforcompletion(void *pd)
{
- int ret = 0;
+ long ret = ~0;
+ unsigned long timeout;
if (irq > -1) {
- ret = wait_event_interruptible(pca_wait,
- pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI);
+ ret = wait_event_interruptible_timeout(pca_wait,
+ pca_isa_readbyte(pd, I2C_PCA_CON)
+ & I2C_PCA_CON_SI, pca_isa_ops.timeout);
} else {
- while ((pca_isa_readbyte(pd, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
+ /* Do polling */
+ timeout = jiffies + pca_isa_ops.timeout;
+ while (((pca_isa_readbyte(pd, I2C_PCA_CON)
+ & I2C_PCA_CON_SI) == 0)
+ && (ret = time_before(jiffies, timeout)))
udelay(100);
}
- return ret;
+ return ret > 0;
}
static void pca_isa_resetchip(void *pd)
@@ -102,8 +111,8 @@ static struct i2c_algo_pca_data pca_isa_data = {
static struct i2c_adapter pca_isa_ops = {
.owner = THIS_MODULE,
.algo_data = &pca_isa_data,
- .name = "PCA9564 ISA Adapter",
- .timeout = 100,
+ .name = "PCA9564/PCA9665 ISA Adapter",
+ .timeout = HZ,
};
static int __devinit pca_isa_match(struct device *dev, unsigned int id)
@@ -195,7 +204,7 @@ static void __exit pca_isa_exit(void)
}
MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>");
-MODULE_DESCRIPTION("ISA base PCA9564 driver");
+MODULE_DESCRIPTION("ISA base PCA9564/PCA9665 driver");
MODULE_LICENSE("GPL");
module_param(base, ulong, 0);
@@ -204,7 +213,13 @@ MODULE_PARM_DESC(base, "I/O base address");
module_param(irq, int, 0);
MODULE_PARM_DESC(irq, "IRQ");
module_param(clock, int, 0);
-MODULE_PARM_DESC(clock, "Clock rate as described in table 1 of PCA9564 datasheet");
+MODULE_PARM_DESC(clock, "Clock rate in hertz.\n\t\t"
+ "For PCA9564: 330000,288000,217000,146000,"
+ "88000,59000,44000,36000\n"
+ "\t\tFor PCA9665:\tStandard: 60300 - 100099\n"
+ "\t\t\t\tFast: 100100 - 400099\n"
+ "\t\t\t\tFast+: 400100 - 10000099\n"
+ "\t\t\t\tTurbo: Up to 1265800");
module_init(pca_isa_init);
module_exit(pca_isa_exit);
diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c
index 6bb15ad0a6b6..7b23891b7d59 100644
--- a/drivers/i2c/busses/i2c-pca-platform.c
+++ b/drivers/i2c/busses/i2c-pca-platform.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
@@ -81,24 +82,23 @@ static void i2c_pca_pf_writebyte32(void *pd, int reg, int val)
static int i2c_pca_pf_waitforcompletion(void *pd)
{
struct i2c_pca_pf_data *i2c = pd;
- int ret = 0;
+ long ret = ~0;
+ unsigned long timeout;
if (i2c->irq) {
- ret = wait_event_interruptible(i2c->wait,
+ ret = wait_event_interruptible_timeout(i2c->wait,
i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
- & I2C_PCA_CON_SI);
+ & I2C_PCA_CON_SI, i2c->adap.timeout);
} else {
- /*
- * Do polling...
- * XXX: Could get stuck in extreme cases!
- * Maybe add timeout, but using irqs is preferred anyhow.
- */
- while ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
+ /* Do polling */
+ timeout = jiffies + i2c->adap.timeout;
+ while (((i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
& I2C_PCA_CON_SI) == 0)
+ && (ret = time_before(jiffies, timeout)))
udelay(100);
}
- return ret;
+ return ret > 0;
}
static void i2c_pca_pf_dummyreset(void *pd)
@@ -172,14 +172,25 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
i2c->adap.nr = pdev->id >= 0 ? pdev->id : 0;
i2c->adap.owner = THIS_MODULE;
- snprintf(i2c->adap.name, sizeof(i2c->adap.name), "PCA9564 at 0x%08lx",
- (unsigned long) res->start);
+ snprintf(i2c->adap.name, sizeof(i2c->adap.name),
+ "PCA9564/PCA9665 at 0x%08lx",
+ (unsigned long) res->start);
i2c->adap.algo_data = &i2c->algo_data;
i2c->adap.dev.parent = &pdev->dev;
- i2c->adap.timeout = platform_data->timeout;
- i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed;
+ if (platform_data) {
+ i2c->adap.timeout = platform_data->timeout;
+ i2c->algo_data.i2c_clock = platform_data->i2c_clock_speed;
+ i2c->gpio = platform_data->gpio;
+ } else {
+ i2c->adap.timeout = HZ;
+ i2c->algo_data.i2c_clock = 59000;
+ i2c->gpio = -1;
+ }
+
i2c->algo_data.data = i2c;
+ i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion;
+ i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset;
switch (res->flags & IORESOURCE_MEM_TYPE_MASK) {
case IORESOURCE_MEM_32BIT:
@@ -197,11 +208,6 @@ static int __devinit i2c_pca_pf_probe(struct platform_device *pdev)
break;
}
- i2c->algo_data.wait_for_completion = i2c_pca_pf_waitforcompletion;
-
- i2c->gpio = platform_data->gpio;
- i2c->algo_data.reset_chip = i2c_pca_pf_dummyreset;
-
/* Use gpio_is_valid() when in mainline */
if (i2c->gpio > -1) {
ret = gpio_request(i2c->gpio, i2c->adap.name);
@@ -246,7 +252,7 @@ e_remap:
e_alloc:
release_mem_region(res->start, res_len(res));
e_print:
- printk(KERN_ERR "Registering PCA9564 FAILED! (%d)\n", ret);
+ printk(KERN_ERR "Registering PCA9564/PCA9665 FAILED! (%d)\n", ret);
return ret;
}
@@ -290,7 +296,7 @@ static void __exit i2c_pca_pf_exit(void)
}
MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
-MODULE_DESCRIPTION("I2C-PCA9564 platform driver");
+MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver");
MODULE_LICENSE("GPL");
module_init(i2c_pca_pf_init);
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 761f9dd53620..0249a7d762b9 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -20,7 +20,7 @@
/*
Supports:
Intel PIIX4, 440MX
- Serverworks OSB4, CSB5, CSB6, HT-1000
+ Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
ATI IXP200, IXP300, IXP400, SB600, SB700, SB800
SMSC Victory66
@@ -226,6 +226,70 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
return 0;
}
+static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,
+ const struct pci_device_id *id)
+{
+ unsigned short smba_idx = 0xcd6;
+ u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c;
+
+ /* SB800 SMBus does not support forcing address */
+ if (force || force_addr) {
+ dev_err(&PIIX4_dev->dev, "SB800 SMBus does not support "
+ "forcing address!\n");
+ return -EINVAL;
+ }
+
+ /* Determine the address of the SMBus areas */
+ if (!request_region(smba_idx, 2, "smba_idx")) {
+ dev_err(&PIIX4_dev->dev, "SMBus base address index region "
+ "0x%x already in use!\n", smba_idx);
+ return -EBUSY;
+ }
+ outb_p(smb_en, smba_idx);
+ smba_en_lo = inb_p(smba_idx + 1);
+ outb_p(smb_en + 1, smba_idx);
+ smba_en_hi = inb_p(smba_idx + 1);
+ release_region(smba_idx, 2);
+
+ if ((smba_en_lo & 1) == 0) {
+ dev_err(&PIIX4_dev->dev,
+ "Host SMBus controller not enabled!\n");
+ return -ENODEV;
+ }
+
+ piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
+ if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
+ return -EBUSY;
+
+ if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
+ dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
+ piix4_smba);
+ return -EBUSY;
+ }
+
+ /* Request the SMBus I2C bus config region */
+ if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) {
+ dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region "
+ "0x%x already in use!\n", piix4_smba + i2ccfg_offset);
+ release_region(piix4_smba, SMBIOSIZE);
+ piix4_smba = 0;
+ return -EBUSY;
+ }
+ i2ccfg = inb_p(piix4_smba + i2ccfg_offset);
+ release_region(piix4_smba + i2ccfg_offset, 1);
+
+ if (i2ccfg & 1)
+ dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus.\n");
+ else
+ dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus.\n");
+
+ dev_info(&PIIX4_dev->dev,
+ "SMBus Host Controller at 0x%x, revision %d\n",
+ piix4_smba, i2ccfg >> 4);
+
+ return 0;
+}
+
static int piix4_transaction(void)
{
int temp;
@@ -423,6 +487,8 @@ static struct pci_device_id piix4_ids[] = {
PCI_DEVICE_ID_SERVERWORKS_CSB6) },
{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
+ { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
+ PCI_DEVICE_ID_SERVERWORKS_HT1100LD) },
{ 0, }
};
@@ -433,7 +499,14 @@ static int __devinit piix4_probe(struct pci_dev *dev,
{
int retval;
- retval = piix4_setup(dev, id);
+ if ((dev->vendor == PCI_VENDOR_ID_ATI) &&
+ (dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) &&
+ (dev->revision >= 0x40))
+ /* base address location etc changed in SB800 */
+ retval = piix4_setup_sb800(dev, id);
+ else
+ retval = piix4_setup(dev, id);
+
if (retval)
return retval;
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index 60ca91745e55..3c9d71f60187 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -191,7 +191,8 @@ static int __devexit i2c_powermac_remove(struct platform_device *dev)
i2c_set_adapdata(adapter, NULL);
/* We aren't that prepared to deal with this... */
if (rc)
- printk("i2c-powermac.c: Failed to remove bus %s !\n",
+ printk(KERN_WARNING
+ "i2c-powermac.c: Failed to remove bus %s !\n",
adapter->name);
platform_set_drvdata(dev, NULL);
kfree(adapter);
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index bdb1f7510e91..c1405c8f6ba5 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -210,11 +210,12 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id);
static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
{
unsigned int i;
- printk("i2c: error: %s\n", why);
- printk("i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
+ printk(KERN_ERR "i2c: error: %s\n", why);
+ printk(KERN_ERR "i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
i2c->msg_num, i2c->msg_idx, i2c->msg_ptr);
- printk("i2c: ICR: %08x ISR: %08x\n"
- "i2c: log: ", readl(_ICR(i2c)), readl(_ISR(i2c)));
+ printk(KERN_ERR "i2c: ICR: %08x ISR: %08x\n",
+ readl(_ICR(i2c)), readl(_ISR(i2c)));
+ printk(KERN_DEBUG "i2c: log: ");
for (i = 0; i < i2c->irqlogidx; i++)
printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]);
printk("\n");
diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c
index 4678babd3ce6..fede619ba227 100644
--- a/drivers/i2c/busses/i2c-versatile.c
+++ b/drivers/i2c/busses/i2c-versatile.c
@@ -102,7 +102,13 @@ static int i2c_versatile_probe(struct platform_device *dev)
i2c->algo = i2c_versatile_algo;
i2c->algo.data = i2c;
- ret = i2c_bit_add_bus(&i2c->adap);
+ if (dev->id >= 0) {
+ /* static bus numbering */
+ i2c->adap.nr = dev->id;
+ ret = i2c_bit_add_numbered_bus(&i2c->adap);
+ } else
+ /* dynamic bus numbering */
+ ret = i2c_bit_add_bus(&i2c->adap);
if (ret >= 0) {
platform_set_drvdata(dev, i2c);
return 0;
@@ -146,7 +152,7 @@ static void __exit i2c_versatile_exit(void)
platform_driver_unregister(&i2c_versatile_driver);
}
-module_init(i2c_versatile_init);
+subsys_initcall(i2c_versatile_init);
module_exit(i2c_versatile_exit);
MODULE_DESCRIPTION("ARM Versatile I2C bus driver");
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index c80312c1f382..8f8c81eb0aee 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -64,19 +64,6 @@ config SENSORS_PCA9539
This driver is deprecated and will be dropped soon. Use
drivers/gpio/pca953x.c instead.
-config SENSORS_PCF8591
- tristate "Philips PCF8591"
- depends on EXPERIMENTAL
- default n
- help
- If you say yes here you get support for Philips PCF8591 chips.
-
- This driver can also be built as a module. If so, the module
- will be called pcf8591.
-
- These devices are hard to detect and rarely found on mainstream
- hardware. If unsure, say N.
-
config SENSORS_MAX6875
tristate "Maxim MAX6875 Power supply supervisor"
depends on EXPERIMENTAL
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index d142f238a2de..55a376037183 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -15,7 +15,6 @@ obj-$(CONFIG_SENSORS_MAX6875) += max6875.o
obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
obj-$(CONFIG_PCF8575) += pcf8575.o
-obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index e7d984866de0..b6f3a0de6ca2 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -152,7 +152,7 @@ static void i2c_device_shutdown(struct device *dev)
driver->shutdown(to_i2c_client(dev));
}
-static int i2c_device_suspend(struct device * dev, pm_message_t mesg)
+static int i2c_device_suspend(struct device *dev, pm_message_t mesg)
{
struct i2c_driver *driver;
@@ -164,7 +164,7 @@ static int i2c_device_suspend(struct device * dev, pm_message_t mesg)
return driver->suspend(to_i2c_client(dev), mesg);
}
-static int i2c_device_resume(struct device * dev)
+static int i2c_device_resume(struct device *dev)
{
struct i2c_driver *driver;
@@ -187,13 +187,15 @@ static void i2c_client_dev_release(struct device *dev)
kfree(to_i2c_client(dev));
}
-static ssize_t show_client_name(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t
+show_client_name(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
return sprintf(buf, "%s\n", client->name);
}
-static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t
+show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);
@@ -365,8 +367,7 @@ static struct i2c_driver dummy_driver = {
* This returns the new i2c client, which should be saved for later use with
* i2c_unregister_device(); or NULL to indicate an error.
*/
-struct i2c_client *
-i2c_new_dummy(struct i2c_adapter *adapter, u16 address)
+struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address)
{
struct i2c_board_info info = {
I2C_BOARD_INFO("dummy", address),
@@ -413,8 +414,8 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
if (devinfo->busnum == adapter->nr
&& !i2c_new_device(adapter,
&devinfo->board_info))
- printk(KERN_ERR "i2c-core: can't create i2c%d-%04x\n",
- i2c_adapter_id(adapter),
+ dev_err(&adapter->dev,
+ "Can't create device at 0x%02x\n",
devinfo->board_info.addr);
}
mutex_unlock(&__i2c_board_lock);
@@ -459,6 +460,11 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
pr_debug("I2C adapter driver [%s] forgot to specify "
"physical device\n", adap->name);
}
+
+ /* Set default timeout to 1 second if not already set */
+ if (adap->timeout == 0)
+ adap->timeout = HZ;
+
dev_set_name(&adap->dev, "i2c-%d", adap->nr);
adap->dev.release = &i2c_adapter_dev_release;
adap->dev.class = &i2c_adapter_class;
@@ -581,7 +587,8 @@ static int i2c_do_del_adapter(struct device_driver *d, void *data)
struct i2c_client *client, *_n;
int res;
- /* Remove the devices we created ourselves */
+ /* Remove the devices we created ourselves as the result of hardware
+ * probing (using a driver's detect method) */
list_for_each_entry_safe(client, _n, &driver->clients, detected) {
if (client->adapter == adapter) {
dev_dbg(&adapter->dev, "Removing %s at 0x%x\n",
@@ -749,6 +756,8 @@ static int __detach_adapter(struct device *dev, void *data)
struct i2c_driver *driver = data;
struct i2c_client *client, *_n;
+ /* Remove the devices we created ourselves as the result of hardware
+ * probing (using a driver's detect method) */
list_for_each_entry_safe(client, _n, &driver->clients, detected) {
dev_dbg(&adapter->dev, "Removing %s at 0x%x\n",
client->name, client->addr);
@@ -841,7 +850,7 @@ int i2c_attach_client(struct i2c_client *client)
if (client->driver && !is_newstyle_driver(client->driver)) {
client->dev.release = i2c_client_release;
- client->dev.uevent_suppress = 1;
+ dev_set_uevent_suppress(&client->dev, 1);
} else
client->dev.release = i2c_client_dev_release;
@@ -1012,7 +1021,7 @@ module_exit(i2c_exit);
* Note that there is no requirement that each message be sent to
* the same slave address, although that is the most common model.
*/
-int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
+int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
int ret;
@@ -1519,8 +1528,7 @@ EXPORT_SYMBOL(i2c_put_adapter);
/* The SMBus parts */
#define POLY (0x1070U << 3)
-static u8
-crc8(u16 data)
+static u8 crc8(u16 data)
{
int i;
@@ -1984,9 +1992,9 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
* This executes an SMBus protocol operation, and returns a negative
* errno code else zero on success.
*/
-s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
+s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
char read_write, u8 command, int protocol,
- union i2c_smbus_data * data)
+ union i2c_smbus_data *data)
{
s32 res;
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 5ea3bfad172a..cf06494bb744 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -56,8 +56,12 @@ if IDE
comment "Please see Documentation/ide/ide.txt for help/info on IDE drives"
+config IDE_XFER_MODE
+ bool
+
config IDE_TIMINGS
bool
+ select IDE_XFER_MODE
config IDE_ATAPI
bool
@@ -218,7 +222,8 @@ comment "IDE chipset support/bugfixes"
config IDE_GENERIC
tristate "generic/default IDE chipset support"
- depends on ALPHA || X86 || IA64 || M32R || MIPS
+ depends on ALPHA || X86 || IA64 || M32R || MIPS || ARCH_RPC || ARCH_SHARK
+ default ARM && (ARCH_RPC || ARCH_SHARK)
help
This is the generic IDE driver. This driver attaches to the
fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and
@@ -676,7 +681,7 @@ endif
# TODO: BLK_DEV_IDEDMA_PCI -> BLK_DEV_IDEDMA_SFF
config BLK_DEV_IDE_PMAC
tristate "PowerMac on-board IDE support"
- depends on PPC_PMAC && IDE=y
+ depends on PPC_PMAC
select IDE_TIMINGS
select BLK_DEV_IDEDMA_PCI
help
@@ -698,6 +703,7 @@ config BLK_DEV_IDE_PMAC_ATA100FIRST
config BLK_DEV_IDE_AU1XXX
bool "IDE for AMD Alchemy Au1200"
depends on SOC_AU1200
+ select IDE_XFER_MODE
choice
prompt "IDE Mode for AMD Alchemy Au1200"
default CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
@@ -726,11 +732,6 @@ config BLK_DEV_IDE_AT91
depends on ARM && ARCH_AT91 && !ARCH_AT91RM9200 && !ARCH_AT91X40
select IDE_TIMINGS
-config IDE_ARM
- tristate "ARM IDE support"
- depends on ARM && (ARCH_RPC || ARCH_SHARK)
- default y
-
config BLK_DEV_IDE_ICSIDE
tristate "ICS IDE interface support"
depends on ARM && ARCH_ACORN
@@ -769,27 +770,20 @@ config BLK_DEV_GAYLE
This includes on-board IDE interfaces on some Amiga models (A600,
A1200, A4000, and A4000T), and IDE interfaces on the Zorro expansion
bus (M-Tech E-Matrix 530 expansion card).
- Say Y if you have an Amiga with a Gayle IDE interface and want to use
- IDE devices (hard disks, CD-ROM drives, etc.) that are connected to
- it.
- Note that you also have to enable Zorro bus support if you want to
- use Gayle IDE interfaces on the Zorro expansion bus.
-config BLK_DEV_IDEDOUBLER
- bool "Amiga IDE Doubler support (EXPERIMENTAL)"
- depends on BLK_DEV_GAYLE && EXPERIMENTAL
- ---help---
- This feature provides support for the so-called `IDE doublers' (made
+ It also provides support for the so-called `IDE doublers' (made
by various manufacturers, e.g. Eyetech) that can be connected to
the on-board IDE interface of some Amiga models. Using such an IDE
doubler, you can connect up to four instead of two IDE devices to
- the Amiga's on-board IDE interface.
+ the Amiga's on-board IDE interface. The feature is enabled at kernel
+ runtime using the "gayle.doubler" kernel boot parameter.
- Note that the normal Amiga Gayle IDE driver may not work correctly
- if you have an IDE doubler and don't enable this feature!
+ Say Y if you have an Amiga with a Gayle IDE interface and want to use
+ IDE devices (hard disks, CD-ROM drives, etc.) that are connected to
+ it.
- Say Y if you have an IDE doubler. The feature is enabled at kernel
- runtime using the "gayle.doubler" kernel boot parameter.
+ Note that you also have to enable Zorro bus support if you want to
+ use Gayle IDE interfaces on the Zorro expansion bus.
config BLK_DEV_BUDDHA
tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
@@ -871,6 +865,7 @@ config BLK_DEV_ALI14XX
config BLK_DEV_DTC2278
tristate "DTC-2278 support"
+ select IDE_XFER_MODE
select IDE_LEGACY
help
This driver is enabled at runtime using the "dtc2278.probe" kernel
@@ -902,6 +897,7 @@ config BLK_DEV_QD65XX
config BLK_DEV_UMC8672
tristate "UMC-8672 support"
+ select IDE_XFER_MODE
select IDE_LEGACY
help
This driver is enabled at runtime using the "umc8672.probe" kernel
@@ -915,5 +911,6 @@ endif
config BLK_DEV_IDEDMA
def_bool BLK_DEV_IDEDMA_SFF || \
BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+ select IDE_XFER_MODE
endif # IDE
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 1c326d94aa6d..81df925f0e8b 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -5,9 +5,11 @@
EXTRA_CFLAGS += -Idrivers/ide
ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
- ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o
+ ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o \
+ ide-io-std.o ide-eh.o
# core IDE code
+ide-core-$(CONFIG_IDE_XFER_MODE) += ide-pio-blacklist.o ide-xfer-mode.o
ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o
ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o
ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o
@@ -19,8 +21,6 @@ ide-core-$(CONFIG_IDE_LEGACY) += ide-legacy.o
obj-$(CONFIG_IDE) += ide-core.o
-obj-$(CONFIG_IDE_ARM) += ide_arm.o
-
obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o
obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o
diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c
index 4485b9c6f0e6..878f8ec6dbe1 100644
--- a/drivers/ide/aec62xx.c
+++ b/drivers/ide/aec62xx.c
@@ -139,7 +139,7 @@ static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0);
}
-static unsigned int init_chipset_aec62xx(struct pci_dev *dev)
+static int init_chipset_aec62xx(struct pci_dev *dev)
{
/* These are necessary to get AEC6280 Macintosh cards to work */
if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) ||
@@ -156,7 +156,7 @@ static unsigned int init_chipset_aec62xx(struct pci_dev *dev)
pci_write_config_byte(dev, 0x4a, reg4ah | 0x80);
}
- return dev->irq;
+ return 0;
}
static u8 atp86x_cable_detect(ide_hwif_t *hwif)
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index 66f43083408b..537da1cde16d 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -189,19 +189,20 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
/**
- * ali15x3_dma_setup - begin a DMA phase
+ * ali_dma_check - DMA check
* @drive: target device
+ * @cmd: command
*
* Returns 1 if the DMA cannot be performed, zero on success.
*/
-static int ali15x3_dma_setup(ide_drive_t *drive)
+static int ali_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
{
if (m5229_revision < 0xC2 && drive->media != ide_disk) {
- if (rq_data_dir(drive->hwif->rq))
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
return 1; /* try PIO instead of DMA */
}
- return ide_dma_setup(drive);
+ return 0;
}
/**
@@ -212,7 +213,7 @@ static int ali15x3_dma_setup(ide_drive_t *drive)
* appropriate also sets up the 1533 southbridge.
*/
-static unsigned int init_chipset_ali15x3(struct pci_dev *dev)
+static int init_chipset_ali15x3(struct pci_dev *dev)
{
unsigned long flags;
u8 tmpbyte;
@@ -502,13 +503,13 @@ static const struct ide_port_ops ali_port_ops = {
static const struct ide_dma_ops ali_dma_ops = {
.dma_host_set = ide_dma_host_set,
- .dma_setup = ali15x3_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_setup = ide_dma_setup,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_check = ali_dma_check,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c
index 77267c859965..628cd2e5fed8 100644
--- a/drivers/ide/amd74xx.c
+++ b/drivers/ide/amd74xx.c
@@ -140,7 +140,7 @@ static void amd7411_cable_detect(struct pci_dev *dev)
* The initialization callback. Initialize drive independent registers.
*/
-static unsigned int init_chipset_amd74xx(struct pci_dev *dev)
+static int init_chipset_amd74xx(struct pci_dev *dev)
{
u8 t = 0, offset = amd_offset(dev);
@@ -172,7 +172,7 @@ static unsigned int init_chipset_amd74xx(struct pci_dev *dev)
t |= 0xf0;
pci_write_config_byte(dev, AMD_IDE_CONFIG + offset, t);
- return dev->irq;
+ return 0;
}
static u8 amd_cable_detect(ide_hwif_t *hwif)
@@ -183,14 +183,6 @@ static u8 amd_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA40;
}
-static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
-{
- struct pci_dev *dev = to_pci_dev(hwif->dev);
-
- if (hwif->irq == 0) /* 0 is bogus but will do for now */
- hwif->irq = pci_get_legacy_ide_irq(dev, hwif->channel);
-}
-
static const struct ide_port_ops amd_port_ops = {
.set_pio_mode = amd_set_pio_mode,
.set_dma_mode = amd_set_drive,
@@ -207,7 +199,6 @@ static const struct ide_port_ops amd_port_ops = {
{ \
.name = DRV_NAME, \
.init_chipset = init_chipset_amd74xx, \
- .init_hwif = init_hwif_amd74xx, \
.enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \
.port_ops = &amd_port_ops, \
.host_flags = IDE_HFLAGS_AMD, \
@@ -221,7 +212,6 @@ static const struct ide_port_ops amd_port_ops = {
{ \
.name = DRV_NAME, \
.init_chipset = init_chipset_amd74xx, \
- .init_hwif = init_hwif_amd74xx, \
.enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \
.port_ops = &amd_port_ops, \
.host_flags = IDE_HFLAGS_AMD, \
diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c
index 1bb50f46388d..8eda552326e9 100644
--- a/drivers/ide/at91_ide.c
+++ b/drivers/ide/at91_ide.c
@@ -143,7 +143,7 @@ static void apply_timings(const u8 chipselect, const u8 pio,
set_smc_timings(chipselect, cycle, setup, pulse, data_float, use_iordy);
}
-static void at91_ide_input_data(ide_drive_t *drive, struct request *rq,
+static void at91_ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
@@ -156,11 +156,11 @@ static void at91_ide_input_data(ide_drive_t *drive, struct request *rq,
len++;
enter_16bit(chipselect, mode);
- __ide_mm_insw((void __iomem *) io_ports->data_addr, buf, len / 2);
+ readsw((void __iomem *)io_ports->data_addr, buf, len / 2);
leave_16bit(chipselect, mode);
}
-static void at91_ide_output_data(ide_drive_t *drive, struct request *rq,
+static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
@@ -171,7 +171,7 @@ static void at91_ide_output_data(ide_drive_t *drive, struct request *rq,
pdbg("cs %u buf %p len %d\n", chipselect, buf, len);
enter_16bit(chipselect, mode);
- __ide_mm_outsw((void __iomem *) io_ports->data_addr, buf, len / 2);
+ writesw((void __iomem *)io_ports->data_addr, buf, len / 2);
leave_16bit(chipselect, mode);
}
@@ -185,91 +185,77 @@ static void ide_mm_outb(u8 value, unsigned long port)
writeb(value, (void __iomem *) port);
}
-static void at91_ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void at91_ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- at91_ide_output_data(drive, NULL, &data, 2);
- }
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
ide_mm_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
ide_mm_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
ide_mm_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
ide_mm_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
ide_mm_outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
ide_mm_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
ide_mm_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
ide_mm_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
ide_mm_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
ide_mm_outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
ide_mm_outb((tf->device & HIHI) | drive->select, io_ports->device_addr);
}
-static void at91_ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void at91_ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data;
-
- at91_ide_input_data(drive, NULL, &data, 2);
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
+ struct ide_taskfile *tf = &cmd->tf;
/* be sure we're looking at the low order bits */
- ide_mm_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ ide_mm_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = ide_mm_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = ide_mm_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = ide_mm_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = ide_mm_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = ide_mm_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = ide_mm_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = ide_mm_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- ide_mm_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = ide_mm_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ ide_mm_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = ide_mm_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr);
}
}
@@ -295,8 +281,9 @@ static const struct ide_tp_ops at91_ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
- .set_irq = ide_set_irq,
+ .write_devctl = ide_write_devctl,
+ .dev_select = ide_dev_select,
.tf_load = at91_ide_tf_load,
.tf_read = at91_ide_tf_read,
diff --git a/drivers/ide/atiixp.c b/drivers/ide/atiixp.c
index ecd1e62ca91a..923cbfe259d3 100644
--- a/drivers/ide/atiixp.c
+++ b/drivers/ide/atiixp.c
@@ -142,7 +142,6 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
.name = DRV_NAME,
.enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
.port_ops = &atiixp_port_ops,
- .host_flags = IDE_HFLAG_LEGACY_IRQS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -151,7 +150,7 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
.name = DRV_NAME,
.enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}},
.port_ops = &atiixp_port_ops,
- .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS,
+ .host_flags = IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c
index 79a2dfed8eb7..46013644c965 100644
--- a/drivers/ide/au1xxx-ide.c
+++ b/drivers/ide/au1xxx-ide.c
@@ -50,7 +50,7 @@ static _auide_hwif auide_hwif;
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
-void auide_insw(unsigned long port, void *addr, u32 count)
+static inline void auide_insw(unsigned long port, void *addr, u32 count)
{
_auide_hwif *ahwif = &auide_hwif;
chan_tab_t *ctp;
@@ -68,7 +68,7 @@ void auide_insw(unsigned long port, void *addr, u32 count)
ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
-void auide_outsw(unsigned long port, void *addr, u32 count)
+static inline void auide_outsw(unsigned long port, void *addr, u32 count)
{
_auide_hwif *ahwif = &auide_hwif;
chan_tab_t *ctp;
@@ -86,13 +86,13 @@ void auide_outsw(unsigned long port, void *addr, u32 count)
ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
-static void au1xxx_input_data(ide_drive_t *drive, struct request *rq,
+static void au1xxx_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
auide_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
}
-static void au1xxx_output_data(ide_drive_t *drive, struct request *rq,
+static void au1xxx_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
auide_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
@@ -209,23 +209,17 @@ static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed)
*/
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-static int auide_build_dmatable(ide_drive_t *drive)
+static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
- int i, iswrite, count = 0;
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
_auide_hwif *ahwif = &auide_hwif;
struct scatterlist *sg;
+ int i = cmd->sg_nents, count = 0;
+ int iswrite = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- iswrite = (rq_data_dir(rq) == WRITE);
/* Save for interrupt context */
ahwif->drive = drive;
- hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
- if (!i)
- return 0;
-
/* fill the descriptors */
sg = hwif->sg_table;
while (i && sg_dma_len(sg)) {
@@ -242,7 +236,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
if (++count >= PRD_ENTRIES) {
printk(KERN_WARNING "%s: DMA table too small\n",
drive->name);
- goto use_pio_instead;
+ return 0;
}
/* Lets enable intr for the last descriptor only */
@@ -278,21 +272,11 @@ static int auide_build_dmatable(ide_drive_t *drive)
if (count)
return 1;
- use_pio_instead:
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
static int auide_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
-
- if (hwif->sg_nents) {
- ide_destroy_dmatable(drive);
- hwif->sg_nents = 0;
- }
-
return 0;
}
@@ -301,23 +285,11 @@ static void auide_dma_start(ide_drive_t *drive )
}
-static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
+static int auide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
- /* issue cmd to drive */
- ide_execute_command(drive, command, &ide_dma_intr,
- (2*WAIT_CMD), NULL);
-}
-
-static int auide_dma_setup(ide_drive_t *drive)
-{
- struct request *rq = drive->hwif->rq;
-
- if (!auide_build_dmatable(drive)) {
- ide_map_sg(drive, rq);
+ if (auide_build_dmatable(drive, cmd) == 0)
return 1;
- }
- drive->waiting_for_dma = 1;
return 0;
}
@@ -342,16 +314,11 @@ static void auide_dma_host_set(ide_drive_t *drive, int on)
static void auide_ddma_tx_callback(int irq, void *param)
{
- _auide_hwif *ahwif = (_auide_hwif*)param;
- ahwif->drive->waiting_for_dma = 0;
}
static void auide_ddma_rx_callback(int irq, void *param)
{
- _auide_hwif *ahwif = (_auide_hwif*)param;
- ahwif->drive->waiting_for_dma = 0;
}
-
#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags)
@@ -369,12 +336,10 @@ static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 de
static const struct ide_dma_ops au1xxx_dma_ops = {
.dma_host_set = auide_dma_host_set,
.dma_setup = auide_dma_setup,
- .dma_exec_cmd = auide_dma_exec_cmd,
.dma_start = auide_dma_start,
.dma_end = auide_dma_end,
.dma_test_irq = auide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
};
static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
@@ -502,9 +467,9 @@ static const struct ide_tp_ops au1xxx_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
@@ -536,9 +501,8 @@ static const struct ide_port_info au1xxx_port_info = {
#endif
};
-static int au_ide_probe(struct device *dev)
+static int au_ide_probe(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
_auide_hwif *ahwif = &auide_hwif;
struct resource *res;
struct ide_host *host;
@@ -552,23 +516,23 @@ static int au_ide_probe(struct device *dev)
#endif
memset(&auide_hwif, 0, sizeof(_auide_hwif));
- ahwif->irq = platform_get_irq(pdev, 0);
+ ahwif->irq = platform_get_irq(dev, 0);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (res == NULL) {
- pr_debug("%s %d: no base address\n", DRV_NAME, pdev->id);
+ pr_debug("%s %d: no base address\n", DRV_NAME, dev->id);
ret = -ENODEV;
goto out;
}
if (ahwif->irq < 0) {
- pr_debug("%s %d: no IRQ\n", DRV_NAME, pdev->id);
+ pr_debug("%s %d: no IRQ\n", DRV_NAME, dev->id);
ret = -ENODEV;
goto out;
}
if (!request_mem_region(res->start, res->end - res->start + 1,
- pdev->name)) {
+ dev->name)) {
pr_debug("%s: request_mem_region failed\n", DRV_NAME);
ret = -EBUSY;
goto out;
@@ -583,7 +547,7 @@ static int au_ide_probe(struct device *dev)
memset(&hw, 0, sizeof(hw));
auide_setup_ports(&hw, ahwif);
hw.irq = ahwif->irq;
- hw.dev = dev;
+ hw.dev = &dev->dev;
hw.chipset = ide_au1xxx;
ret = ide_host_add(&au1xxx_port_info, hws, &host);
@@ -592,7 +556,7 @@ static int au_ide_probe(struct device *dev)
auide_hwif.hwif = host->ports[0];
- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);
printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
@@ -600,38 +564,39 @@ static int au_ide_probe(struct device *dev)
return ret;
}
-static int au_ide_remove(struct device *dev)
+static int au_ide_remove(struct platform_device *dev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct resource *res;
- struct ide_host *host = dev_get_drvdata(dev);
+ struct ide_host *host = platform_get_drvdata(dev);
_auide_hwif *ahwif = &auide_hwif;
ide_host_remove(host);
iounmap((void *)ahwif->regbase);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
release_mem_region(res->start, res->end - res->start + 1);
return 0;
}
-static struct device_driver au1200_ide_driver = {
- .name = "au1200-ide",
- .bus = &platform_bus_type,
+static struct platform_driver au1200_ide_driver = {
+ .driver = {
+ .name = "au1200-ide",
+ .owner = THIS_MODULE,
+ },
.probe = au_ide_probe,
.remove = au_ide_remove,
};
static int __init au_ide_init(void)
{
- return driver_register(&au1200_ide_driver);
+ return platform_driver_register(&au1200_ide_driver);
}
static void __exit au_ide_exit(void)
{
- driver_unregister(&au1200_ide_driver);
+ platform_driver_unregister(&au1200_ide_driver);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/buddha.c b/drivers/ide/buddha.c
index c5a3c9ef6a5d..d028f8864bc1 100644
--- a/drivers/ide/buddha.c
+++ b/drivers/ide/buddha.c
@@ -143,6 +143,11 @@ static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base,
hw->chipset = ide_generic;
}
+static const struct ide_port_info buddha_port_info = {
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
+};
+
/*
* Probe for a Buddha or Catweasel IDE interface
*/
@@ -172,10 +177,6 @@ static int __init buddha_init(void)
board = z->resource.start;
-/*
- * FIXME: we now have selectable mmio v/s iomio transports.
- */
-
if(type != BOARD_XSURF) {
if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE"))
continue;
@@ -224,7 +225,7 @@ fail_base2:
hws[i] = &hw[i];
}
- ide_host_add(NULL, hws, NULL);
+ ide_host_add(&buddha_port_info, hws, NULL);
}
return 0;
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 2f9688d87ecd..80b777e4247b 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -318,7 +318,6 @@ static int cmd646_1_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0;
- drive->waiting_for_dma = 0;
/* get DMA status */
dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
/* read DMA command state */
@@ -327,13 +326,11 @@ static int cmd646_1_dma_end(ide_drive_t *drive)
outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
/* clear the INTR & ERROR bits */
outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
- /* and free any DMA resources */
- ide_destroy_dmatable(drive);
/* verify good DMA status */
return (dma_stat & 7) != 4;
}
-static unsigned int init_chipset_cmd64x(struct pci_dev *dev)
+static int init_chipset_cmd64x(struct pci_dev *dev)
{
u8 mrdmode = 0;
@@ -379,36 +376,33 @@ static const struct ide_port_ops cmd64x_port_ops = {
static const struct ide_dma_ops cmd64x_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = cmd64x_dma_end,
.dma_test_irq = cmd64x_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops cmd646_rev1_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = cmd646_1_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops cmd648_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = cmd648_dma_end,
.dma_test_irq = cmd648_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/cs5520.c b/drivers/ide/cs5520.c
index d003bec56ff9..58fb90e5b763 100644
--- a/drivers/ide/cs5520.c
+++ b/drivers/ide/cs5520.c
@@ -133,7 +133,8 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
* do all the device setup for us
*/
- ide_pci_setup_ports(dev, d, 14, &hw[0], &hws[0]);
+ ide_pci_setup_ports(dev, d, &hw[0], &hws[0]);
+ hw[0].irq = 14;
return ide_host_add(d, hws, NULL);
}
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c
index d8ede85fe17f..40bf05eddf6e 100644
--- a/drivers/ide/cs5530.c
+++ b/drivers/ide/cs5530.c
@@ -92,8 +92,7 @@ static u8 cs5530_udma_filter(ide_drive_t *drive)
if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
(mateid[ATA_ID_UDMA_MODES] & 7))
goto out;
- if ((mateid[ATA_ID_FIELD_VALID] & 2) &&
- (mateid[ATA_ID_MWDMA_MODES] & 7))
+ if (mateid[ATA_ID_MWDMA_MODES] & 7)
mask = 0;
}
out:
@@ -135,7 +134,7 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
* Initialize the cs5530 bridge for reliable IDE DMA operation.
*/
-static unsigned int init_chipset_cs5530(struct pci_dev *dev)
+static int init_chipset_cs5530(struct pci_dev *dev)
{
struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
diff --git a/drivers/ide/cs5536.c b/drivers/ide/cs5536.c
index 7a62db719a46..353a35bbba63 100644
--- a/drivers/ide/cs5536.c
+++ b/drivers/ide/cs5536.c
@@ -231,12 +231,11 @@ static const struct ide_port_ops cs5536_port_ops = {
static const struct ide_dma_ops cs5536_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = cs5536_dma_start,
.dma_end = cs5536_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
};
static const struct ide_port_info cs5536_info = {
diff --git a/drivers/ide/delkin_cb.c b/drivers/ide/delkin_cb.c
index 8f1b2d9f0513..f153b95619bb 100644
--- a/drivers/ide/delkin_cb.c
+++ b/drivers/ide/delkin_cb.c
@@ -46,7 +46,7 @@ static const struct ide_port_ops delkin_cb_port_ops = {
.quirkproc = ide_undecoded_slave,
};
-static unsigned int delkin_cb_init_chipset(struct pci_dev *dev)
+static int delkin_cb_init_chipset(struct pci_dev *dev)
{
unsigned long base = pci_resource_start(dev, 0);
int i;
@@ -66,6 +66,7 @@ static const struct ide_port_info delkin_cb_port_info = {
.port_ops = &delkin_cb_port_ops,
.host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS |
IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
.init_chipset = delkin_cb_init_chipset,
};
diff --git a/drivers/ide/dtc2278.c b/drivers/ide/dtc2278.c
index 689b2e493413..c6b138122981 100644
--- a/drivers/ide/dtc2278.c
+++ b/drivers/ide/dtc2278.c
@@ -100,7 +100,8 @@ static const struct ide_port_info dtc2278_port_info __initdata = {
IDE_HFLAG_IO_32BIT |
/* disallow ->io_32bit changes */
IDE_HFLAG_NO_IO_32BIT |
- IDE_HFLAG_NO_DMA,
+ IDE_HFLAG_NO_DMA |
+ IDE_HFLAG_DTC2278,
.pio_mask = ATA_PIO4,
};
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c
index a638e952d67a..afa2af9a362b 100644
--- a/drivers/ide/falconide.c
+++ b/drivers/ide/falconide.c
@@ -40,29 +40,48 @@
* which is shared between several drivers.
*/
-int falconide_intr_lock;
-EXPORT_SYMBOL(falconide_intr_lock);
+static int falconide_intr_lock;
-static void falconide_input_data(ide_drive_t *drive, struct request *rq,
+static void falconide_release_lock(void)
+{
+ if (falconide_intr_lock == 0) {
+ printk(KERN_ERR "%s: bug\n", __func__);
+ return;
+ }
+ falconide_intr_lock = 0;
+ stdma_release();
+}
+
+static void falconide_get_lock(irq_handler_t handler, void *data)
+{
+ if (falconide_intr_lock == 0) {
+ if (in_interrupt() > 0)
+ panic("Falcon IDE hasn't ST-DMA lock in interrupt");
+ stdma_lock(handler, data);
+ falconide_intr_lock = 1;
+ }
+}
+
+static void falconide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
return insw(data_addr, buf, (len + 1) / 2);
- insw_swapw(data_addr, buf, (len + 1) / 2);
+ raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
-static void falconide_output_data(ide_drive_t *drive, struct request *rq,
+static void falconide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
return outsw(data_addr, buf, (len + 1) / 2);
- outsw_swapw(data_addr, buf, (len + 1) / 2);
+ raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
/* Atari has a byte-swapped IDE interface */
@@ -70,9 +89,9 @@ static const struct ide_tp_ops falconide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
@@ -81,8 +100,12 @@ static const struct ide_tp_ops falconide_tp_ops = {
};
static const struct ide_port_info falconide_port_info = {
+ .get_lock = falconide_get_lock,
+ .release_lock = falconide_release_lock,
.tp_ops = &falconide_tp_ops,
- .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_SERIALIZE,
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE |
+ IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
};
static void __init falconide_setup_ports(hw_regs_t *hw)
@@ -132,9 +155,9 @@ static int __init falconide_init(void)
goto err;
}
- ide_get_lock(NULL, NULL);
+ falconide_get_lock(NULL, NULL);
rc = ide_host_register(host, &falconide_port_info, hws);
- ide_release_lock();
+ falconide_release_lock();
if (rc)
goto err_free;
diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c
index 59bd0be9dcb3..c7119516c5a7 100644
--- a/drivers/ide/gayle.c
+++ b/drivers/ide/gayle.c
@@ -53,11 +53,6 @@
#define GAYLE_NEXT_PORT 0x1000
-#ifndef CONFIG_BLK_DEV_IDEDOUBLER
-#define GAYLE_NUM_HWIFS 1
-#define GAYLE_NUM_PROBE_HWIFS GAYLE_NUM_HWIFS
-#define GAYLE_HAS_CONTROL_REG 1
-#else /* CONFIG_BLK_DEV_IDEDOUBLER */
#define GAYLE_NUM_HWIFS 2
#define GAYLE_NUM_PROBE_HWIFS (ide_doubler ? GAYLE_NUM_HWIFS : \
GAYLE_NUM_HWIFS-1)
@@ -66,8 +61,6 @@
static int ide_doubler;
module_param_named(doubler, ide_doubler, bool, 0);
MODULE_PARM_DESC(doubler, "enable support for IDE doublers");
-#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
-
/*
* Check and acknowledge the interrupt status
@@ -118,7 +111,9 @@ static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base,
}
static const struct ide_port_info gayle_port_info = {
- .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA,
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE |
+ IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
};
/*
@@ -149,10 +144,7 @@ static int __init gayle_init(void)
found:
printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n",
a4000 ? 4000 : 1200,
-#ifdef CONFIG_BLK_DEV_IDEDOUBLER
- ide_doubler ? ", IDE doubler" :
-#endif
- "");
+ ide_doubler ? ", IDE doubler" : "");
if (a4000) {
phys_base = GAYLE_BASE_4000;
@@ -163,9 +155,6 @@ found:
irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200);
ack_intr = gayle_ack_intr_a1200;
}
-/*
- * FIXME: we now have selectable modes between mmio v/s iomio
- */
res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1);
res_n = GAYLE_IDEREG_SIZE;
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index 3eb9b5c63a0f..a0eb87f59134 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -835,12 +835,6 @@ static int hpt370_dma_end(ide_drive_t *drive)
return ide_dma_end(drive);
}
-static void hpt370_dma_timeout(ide_drive_t *drive)
-{
- hpt370_irq_timeout(drive);
- ide_dma_timeout(drive);
-}
-
/* returns 1 if DMA IRQ issued, 0 otherwise */
static int hpt374_dma_test_irq(ide_drive_t *drive)
{
@@ -995,7 +989,7 @@ static void hpt3xx_disable_fast_irq(struct pci_dev *dev, u8 mcr_addr)
pci_write_config_byte(dev, mcr_addr + 1, new_mcr);
}
-static unsigned int init_chipset_hpt366(struct pci_dev *dev)
+static int init_chipset_hpt366(struct pci_dev *dev)
{
unsigned long io_base = pci_resource_start(dev, 4);
struct hpt_info *info = hpt3xx_get_info(&dev->dev);
@@ -1237,7 +1231,7 @@ static unsigned int init_chipset_hpt366(struct pci_dev *dev)
hpt3xx_disable_fast_irq(dev, 0x50);
hpt3xx_disable_fast_irq(dev, 0x54);
- return dev->irq;
+ return 0;
}
static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
@@ -1418,36 +1412,34 @@ static const struct ide_port_ops hpt3xx_port_ops = {
static const struct ide_dma_ops hpt37x_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = hpt374_dma_end,
.dma_test_irq = hpt374_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops hpt370_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = hpt370_dma_start,
.dma_end = hpt370_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = hpt370_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
+ .dma_clear = hpt370_irq_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops hpt36x_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = hpt366_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/ht6560b.c b/drivers/ide/ht6560b.c
index c7e5c2246b79..2fb0f2965009 100644
--- a/drivers/ide/ht6560b.c
+++ b/drivers/ide/ht6560b.c
@@ -103,7 +103,7 @@
/*
* This routine is invoked from ide.c to prepare for access to a given drive.
*/
-static void ht6560b_selectproc (ide_drive_t *drive)
+static void ht6560b_dev_select(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
@@ -143,6 +143,8 @@ static void ht6560b_selectproc (ide_drive_t *drive)
#endif
}
local_irq_restore(flags);
+
+ outb(drive->select | ATA_DEVICE_OBS, hwif->io_ports.device_addr);
}
/*
@@ -305,15 +307,29 @@ static int probe_ht6560b;
module_param_named(probe, probe_ht6560b, bool, 0);
MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
+static const struct ide_tp_ops ht6560b_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
+
+ .dev_select = ht6560b_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
+};
+
static const struct ide_port_ops ht6560b_port_ops = {
.init_dev = ht6560b_init_dev,
.set_pio_mode = ht6560b_set_pio_mode,
- .selectproc = ht6560b_selectproc,
};
static const struct ide_port_info ht6560b_port_info __initdata = {
.name = DRV_NAME,
.chipset = ide_ht6560b,
+ .tp_ops = &ht6560b_tp_ops,
.port_ops = &ht6560b_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE | /* is this needed? */
IDE_HFLAG_NO_DMA |
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index 415d7e24f2b6..4e16ce68b063 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -287,13 +287,8 @@ static int icside_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
- drive->waiting_for_dma = 0;
-
disable_dma(ec->dma);
- /* Teardown mappings after DMA has completed. */
- ide_destroy_dmatable(drive);
-
return get_dma_residue(ec->dma) != 0;
}
@@ -307,15 +302,14 @@ static void icside_dma_start(ide_drive_t *drive)
enable_dma(ec->dma);
}
-static int icside_dma_setup(ide_drive_t *drive)
+static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
struct icside_state *state = ecard_get_drvdata(ec);
- struct request *rq = hwif->rq;
unsigned int dma_mode;
- if (rq_data_dir(rq))
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
dma_mode = DMA_MODE_WRITE;
else
dma_mode = DMA_MODE_READ;
@@ -325,8 +319,6 @@ static int icside_dma_setup(ide_drive_t *drive)
*/
BUG_ON(dma_channel_active(ec->dma));
- hwif->sg_nents = ide_build_sglist(drive, rq);
-
/*
* Ensure that we have the right interrupt routed.
*/
@@ -346,20 +338,12 @@ static int icside_dma_setup(ide_drive_t *drive)
* Tell the DMA engine about the SG table and
* data direction.
*/
- set_dma_sg(ec->dma, hwif->sg_table, hwif->sg_nents);
+ set_dma_sg(ec->dma, hwif->sg_table, cmd->sg_nents);
set_dma_mode(ec->dma, dma_mode);
- drive->waiting_for_dma = 1;
-
return 0;
}
-static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd)
-{
- /* issue cmd to drive */
- ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD, NULL);
-}
-
static int icside_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
@@ -383,11 +367,9 @@ static int icside_dma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
static const struct ide_dma_ops icside_v6_dma_ops = {
.dma_host_set = icside_dma_host_set,
.dma_setup = icside_dma_setup,
- .dma_exec_cmd = icside_dma_exec_cmd,
.dma_start = icside_dma_start,
.dma_end = icside_dma_end,
.dma_test_irq = icside_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
};
#else
@@ -419,6 +401,10 @@ static void icside_setup_ports(hw_regs_t *hw, void __iomem *base,
hw->chipset = ide_acorn;
}
+static const struct ide_port_info icside_v5_port_info = {
+ .host_flags = IDE_HFLAG_NO_DMA,
+};
+
static int __devinit
icside_register_v5(struct icside_state *state, struct expansion_card *ec)
{
@@ -445,7 +431,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec);
- host = ide_host_alloc(NULL, hws);
+ host = ide_host_alloc(&icside_v5_port_info, hws);
if (host == NULL)
return -ENODEV;
@@ -453,7 +439,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
ecard_set_drvdata(ec, state);
- ret = ide_host_register(host, NULL, hws);
+ ret = ide_host_register(host, &icside_v5_port_info, hws);
if (ret)
goto err_free;
diff --git a/drivers/ide/ide-4drives.c b/drivers/ide/ide-4drives.c
index 9e85b1ec9607..78aca75a2c48 100644
--- a/drivers/ide/ide-4drives.c
+++ b/drivers/ide/ide-4drives.c
@@ -23,7 +23,8 @@ static const struct ide_port_ops ide_4drives_port_ops = {
static const struct ide_port_info ide_4drives_port_info = {
.port_ops = &ide_4drives_port_ops,
- .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA,
+ .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA |
+ IDE_HFLAG_4DRIVES,
};
static int __init ide_4drives_init(void)
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index ec7d07fa570a..12f436951bff 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -20,9 +20,6 @@
#include <acpi/acpi_bus.h>
#define REGS_PER_GTF 7
-struct taskfile_array {
- u8 tfa[REGS_PER_GTF]; /* regs. 0x1f1 - 0x1f7 */
-};
struct GTM_buffer {
u32 PIO_speed0;
@@ -89,12 +86,8 @@ static const struct dmi_system_id ide_acpi_dmi_table[] = {
{ } /* terminate list */
};
-static int ide_acpi_blacklist(void)
+int ide_acpi_init(void)
{
- static int done;
- if (done)
- return 0;
- done = 1;
dmi_check_system(ide_acpi_dmi_table);
return 0;
}
@@ -202,40 +195,6 @@ static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif)
}
/**
- * ide_acpi_drive_get_handle - Get ACPI object handle for a given drive
- * @drive: device to locate
- *
- * Retrieves the object handle of a given drive. According to the ACPI
- * spec the drive is a child of the hwif.
- *
- * Returns handle on success, 0 on error.
- */
-static acpi_handle ide_acpi_drive_get_handle(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- int port;
- acpi_handle drive_handle;
-
- if (!hwif->acpidata)
- return NULL;
-
- if (!hwif->acpidata->obj_handle)
- return NULL;
-
- port = hwif->channel ? drive->dn - 2: drive->dn;
-
- DEBPRINT("ENTER: %s at channel#: %d port#: %d\n",
- drive->name, hwif->channel, port);
-
-
- /* TBD: could also check ACPI object VALID bits */
- drive_handle = acpi_get_child(hwif->acpidata->obj_handle, port);
- DEBPRINT("drive %s handle 0x%p\n", drive->name, drive_handle);
-
- return drive_handle;
-}
-
-/**
* do_drive_get_GTF - get the drive bootup default taskfile settings
* @drive: the drive for which the taskfile settings should be retrieved
* @gtf_length: number of bytes of _GTF data returned at @gtf_address
@@ -257,47 +216,15 @@ static int do_drive_get_GTF(ide_drive_t *drive,
acpi_status status;
struct acpi_buffer output;
union acpi_object *out_obj;
- ide_hwif_t *hwif = drive->hwif;
- struct device *dev = hwif->gendev.parent;
int err = -ENODEV;
- int port;
*gtf_length = 0;
*gtf_address = 0UL;
*obj_loc = 0UL;
- if (ide_noacpi)
- return 0;
-
- if (!dev) {
- DEBPRINT("no PCI device for %s\n", hwif->name);
- goto out;
- }
-
- if (!hwif->acpidata) {
- DEBPRINT("no ACPI data for %s\n", hwif->name);
- goto out;
- }
-
- port = hwif->channel ? drive->dn - 2: drive->dn;
-
- DEBPRINT("ENTER: %s at %s, port#: %d, hard_port#: %d\n",
- hwif->name, dev_name(dev), port, hwif->channel);
-
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) {
- DEBPRINT("%s drive %d:%d not present\n",
- hwif->name, hwif->channel, port);
- goto out;
- }
-
- /* Get this drive's _ADR info. if not already known. */
if (!drive->acpidata->obj_handle) {
- drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive);
- if (!drive->acpidata->obj_handle) {
- DEBPRINT("No ACPI object found for %s\n",
- drive->name);
- goto out;
- }
+ DEBPRINT("No ACPI object found for %s\n", drive->name);
+ goto out;
}
/* Setting up output buffer */
@@ -355,43 +282,6 @@ out:
}
/**
- * taskfile_load_raw - send taskfile registers to drive
- * @drive: drive to which output is sent
- * @gtf: raw ATA taskfile register set (0x1f1 - 0x1f7)
- *
- * Outputs IDE taskfile to the drive.
- */
-static int taskfile_load_raw(ide_drive_t *drive,
- const struct taskfile_array *gtf)
-{
- ide_task_t args;
- int err = 0;
-
- DEBPRINT("(0x1f1-1f7): hex: "
- "%02x %02x %02x %02x %02x %02x %02x\n",
- gtf->tfa[0], gtf->tfa[1], gtf->tfa[2],
- gtf->tfa[3], gtf->tfa[4], gtf->tfa[5], gtf->tfa[6]);
-
- memset(&args, 0, sizeof(ide_task_t));
-
- /* convert gtf to IDE Taskfile */
- memcpy(&args.tf_array[7], &gtf->tfa, 7);
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
-
- if (!ide_acpigtf) {
- DEBPRINT("_GTF execution disabled\n");
- return err;
- }
-
- err = ide_no_data_taskfile(drive, &args);
- if (err)
- printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n",
- __func__, err);
-
- return err;
-}
-
-/**
* do_drive_set_taskfiles - write the drive taskfile settings from _GTF
* @drive: the drive to which the taskfile command should be sent
* @gtf_length: total number of bytes of _GTF taskfiles
@@ -404,43 +294,41 @@ static int do_drive_set_taskfiles(ide_drive_t *drive,
unsigned int gtf_length,
unsigned long gtf_address)
{
- int rc = -ENODEV, err;
+ int rc = 0, err;
int gtf_count = gtf_length / REGS_PER_GTF;
int ix;
- struct taskfile_array *gtf;
-
- if (ide_noacpi)
- return 0;
-
- DEBPRINT("ENTER: %s, hard_port#: %d\n", drive->name, drive->dn);
-
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- goto out;
-
- if (!gtf_count) /* shouldn't be here */
- goto out;
DEBPRINT("total GTF bytes=%u (0x%x), gtf_count=%d, addr=0x%lx\n",
gtf_length, gtf_length, gtf_count, gtf_address);
- if (gtf_length % REGS_PER_GTF) {
- printk(KERN_ERR "%s: unexpected GTF length (%d)\n",
- __func__, gtf_length);
- goto out;
- }
-
- rc = 0;
+ /* send all taskfile registers (0x1f1-0x1f7) *in*that*order* */
for (ix = 0; ix < gtf_count; ix++) {
- gtf = (struct taskfile_array *)
- (gtf_address + ix * REGS_PER_GTF);
+ u8 *gtf = (u8 *)(gtf_address + ix * REGS_PER_GTF);
+ struct ide_cmd cmd;
- /* send all TaskFile registers (0x1f1-0x1f7) *in*that*order* */
- err = taskfile_load_raw(drive, gtf);
- if (err)
+ DEBPRINT("(0x1f1-1f7): "
+ "hex: %02x %02x %02x %02x %02x %02x %02x\n",
+ gtf[0], gtf[1], gtf[2],
+ gtf[3], gtf[4], gtf[5], gtf[6]);
+
+ if (!ide_acpigtf) {
+ DEBPRINT("_GTF execution disabled\n");
+ continue;
+ }
+
+ /* convert GTF to taskfile */
+ memset(&cmd, 0, sizeof(cmd));
+ memcpy(&cmd.tf_array[7], gtf, REGS_PER_GTF);
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ err = ide_no_data_taskfile(drive, &cmd);
+ if (err) {
+ printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n",
+ __func__, err);
rc = err;
+ }
}
-out:
return rc;
}
@@ -647,26 +535,23 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
DEBPRINT("no ACPI data for %s\n", hwif->name);
return;
}
+
/* channel first and then drives for power on and verse versa for power off */
if (on)
acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0);
- ide_port_for_each_dev(i, drive, hwif) {
- if (!drive->acpidata->obj_handle)
- drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive);
-
- if (drive->acpidata->obj_handle &&
- (drive->dev_flags & IDE_DFLAG_PRESENT)) {
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ if (drive->acpidata->obj_handle)
acpi_bus_set_power(drive->acpidata->obj_handle,
- on? ACPI_STATE_D0: ACPI_STATE_D3);
- }
+ on ? ACPI_STATE_D0 : ACPI_STATE_D3);
}
+
if (!on)
acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D3);
}
/**
- * ide_acpi_init - initialize the ACPI link for an IDE interface
+ * ide_acpi_init_port - initialize the ACPI link for an IDE interface
* @hwif: target IDE interface (channel)
*
* The ACPI spec is not quite clear when the drive identify buffer
@@ -676,10 +561,8 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
* So we get the information during startup; but this means that
* any changes during run-time will be lost after resume.
*/
-void ide_acpi_init(ide_hwif_t *hwif)
+void ide_acpi_init_port(ide_hwif_t *hwif)
{
- ide_acpi_blacklist();
-
hwif->acpidata = kzalloc(sizeof(struct ide_acpi_hwif_link), GFP_KERNEL);
if (!hwif->acpidata)
return;
@@ -708,15 +591,24 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif)
hwif->devices[0]->acpidata = &hwif->acpidata->master;
hwif->devices[1]->acpidata = &hwif->acpidata->slave;
- /*
- * Send IDENTIFY for each drive
- */
- ide_port_for_each_dev(i, drive, hwif) {
- memset(drive->acpidata, 0, sizeof(*drive->acpidata));
+ /* get _ADR info for each device */
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ acpi_handle dev_handle;
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- continue;
+ DEBPRINT("ENTER: %s at channel#: %d port#: %d\n",
+ drive->name, hwif->channel, drive->dn & 1);
+
+ /* TBD: could also check ACPI object VALID bits */
+ dev_handle = acpi_get_child(hwif->acpidata->obj_handle,
+ drive->dn & 1);
+
+ DEBPRINT("drive %s handle 0x%p\n", drive->name, dev_handle);
+
+ drive->acpidata->obj_handle = dev_handle;
+ }
+ /* send IDENTIFY for each device */
+ ide_port_for_each_present_dev(i, drive, hwif) {
err = taskfile_lib_get_identify(drive, drive->acpidata->idbuff);
if (err)
DEBPRINT("identify device %s failed (%d)\n",
@@ -736,9 +628,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif)
ide_acpi_get_timing(hwif);
ide_acpi_push_timing(hwif);
- ide_port_for_each_dev(i, drive, hwif) {
- if (drive->dev_flags & IDE_DFLAG_PRESENT)
- /* Execute ACPI startup code */
- ide_acpi_exec_tfs(drive);
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ ide_acpi_exec_tfs(drive);
}
}
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index e9d042dba0e0..3e43b889dd64 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -6,6 +6,8 @@
#include <linux/cdrom.h>
#include <linux/delay.h>
#include <linux/ide.h>
+#include <linux/scatterlist.h>
+
#include <scsi/scsi.h>
#ifdef DEBUG
@@ -69,56 +71,6 @@ int ide_check_atapi_device(ide_drive_t *drive, const char *s)
}
EXPORT_SYMBOL_GPL(ide_check_atapi_device);
-/* PIO data transfer routine using the scatter gather table. */
-int ide_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
- unsigned int bcount, int write)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data;
- struct scatterlist *sg = pc->sg;
- char *buf;
- int count, done = 0;
-
- while (bcount) {
- count = min(sg->length - pc->b_count, bcount);
-
- if (PageHighMem(sg_page(sg))) {
- unsigned long flags;
-
- local_irq_save(flags);
- buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
- xf(drive, NULL, buf + pc->b_count, count);
- kunmap_atomic(buf - sg->offset, KM_IRQ0);
- local_irq_restore(flags);
- } else {
- buf = sg_virt(sg);
- xf(drive, NULL, buf + pc->b_count, count);
- }
-
- bcount -= count;
- pc->b_count += count;
- done += count;
-
- if (pc->b_count == sg->length) {
- if (!--pc->sg_cnt)
- break;
- pc->sg = sg = sg_next(sg);
- pc->b_count = 0;
- }
- }
-
- if (bcount) {
- printk(KERN_ERR "%s: %d leftover bytes, %s\n", drive->name,
- bcount, write ? "padding with zeros"
- : "discarding data");
- ide_pad_transfer(drive, write, bcount);
- }
-
- return done;
-}
-EXPORT_SYMBOL_GPL(ide_io_buffers);
-
void ide_init_pc(struct ide_atapi_pc *pc)
{
memset(pc, 0, sizeof(*pc));
@@ -149,7 +101,10 @@ static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk,
memcpy(rq->cmd, pc->c, 12);
if (drive->media == ide_tape)
rq->cmd[13] = REQ_IDETAPE_PC1;
- ide_do_drive_cmd(drive, rq);
+
+ drive->hwif->rq = NULL;
+
+ elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
}
/*
@@ -297,6 +252,21 @@ int ide_cd_get_xferlen(struct request *rq)
}
EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);
+void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
+{
+ struct ide_cmd cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
+ IDE_TFLAG_IN_NSECT;
+
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
+
+ *bcount = (cmd.tf.lbah << 8) | cmd.tf.lbam;
+ *ireason = cmd.tf.nsect & 3;
+}
+EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
+
/*
* This is the usual interrupt handler which will be called during a packet
* command. We will transfer some of the data (as requested by the drive)
@@ -306,29 +276,31 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
{
struct ide_atapi_pc *pc = drive->pc;
ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
xfer_func_t *xferfunc;
- unsigned int timeout, temp;
+ unsigned int timeout, done;
u16 bcount;
u8 stat, ireason, dsc = 0;
+ u8 write = !!(pc->flags & PC_FLAG_WRITING);
debug_log("Enter %s - interrupt handler\n", __func__);
timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
: WAIT_TAPE_CMD;
- if (pc->flags & PC_FLAG_TIMEDOUT) {
- drive->pc_callback(drive, 0);
- return ide_stopped;
- }
-
/* Clear the interrupt */
stat = tp_ops->read_status(hwif);
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
- if (hwif->dma_ops->dma_end(drive) ||
- (drive->media == ide_tape && (stat & ATA_ERR))) {
+ int rc;
+
+ drive->waiting_for_dma = 0;
+ rc = hwif->dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
+
+ if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) {
if (drive->media == ide_floppy)
printk(KERN_ERR "%s: DMA %s error\n",
drive->name, rq_data_dir(pc->rq)
@@ -344,6 +316,9 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
/* No more interrupts */
if ((stat & ATA_DRQ) == 0) {
+ int uptodate, error;
+ unsigned int done;
+
debug_log("Packet command completed, %d bytes transferred\n",
pc->xferred);
@@ -382,8 +357,31 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
dsc = 1;
/* Command finished - Call the callback function */
- drive->pc_callback(drive, dsc);
+ uptodate = drive->pc_callback(drive, dsc);
+
+ if (uptodate == 0)
+ drive->failed_pc = NULL;
+
+ if (blk_special_request(rq)) {
+ rq->errors = 0;
+ done = blk_rq_bytes(rq);
+ error = 0;
+ } else {
+ if (blk_fs_request(rq) == 0 && uptodate <= 0) {
+ if (rq->errors == 0)
+ rq->errors = -EIO;
+ }
+
+ if (drive->media == ide_tape)
+ done = ide_rq_bytes(rq); /* FIXME */
+ else
+ done = blk_rq_bytes(rq);
+
+ error = uptodate ? 0 : -EIO;
+ }
+
+ ide_complete_rq(drive, error, done);
return ide_stopped;
}
@@ -403,8 +401,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
return ide_do_reset(drive);
}
- if (((ireason & ATAPI_IO) == ATAPI_IO) ==
- !!(pc->flags & PC_FLAG_WRITING)) {
+ if (((ireason & ATAPI_IO) == ATAPI_IO) == write) {
/* Hopefully, we will never get here */
printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
"to %s!\n", drive->name,
@@ -413,59 +410,57 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
return ide_do_reset(drive);
}
- if (!(pc->flags & PC_FLAG_WRITING)) {
- /* Reading - Check that we have enough space */
- temp = pc->xferred + bcount;
- if (temp > pc->req_xfer) {
- if (temp > pc->buf_size) {
- printk(KERN_ERR "%s: The device wants to send "
- "us more data than expected - "
- "discarding data\n",
- drive->name);
-
- ide_pad_transfer(drive, 0, bcount);
- goto next_irq;
- }
- debug_log("The device wants to send us more data than "
- "expected - allowing transfer\n");
- }
- xferfunc = tp_ops->input_data;
- } else
- xferfunc = tp_ops->output_data;
-
- if ((drive->media == ide_floppy && !pc->buf) ||
- (drive->media == ide_tape && pc->bh)) {
- int done = drive->pc_io_buffers(drive, pc, bcount,
- !!(pc->flags & PC_FLAG_WRITING));
+ xferfunc = write ? tp_ops->output_data : tp_ops->input_data;
- /* FIXME: don't do partial completions */
- if (drive->media == ide_floppy)
- ide_end_request(drive, 1, done >> 9);
- } else
- xferfunc(drive, NULL, pc->cur_pos, bcount);
+ if (drive->media == ide_floppy && pc->buf == NULL) {
+ done = min_t(unsigned int, bcount, cmd->nleft);
+ ide_pio_bytes(drive, cmd, write, done);
+ } else if (drive->media == ide_tape && pc->bh) {
+ done = drive->pc_io_buffers(drive, pc, bcount, write);
+ } else {
+ done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred);
+ xferfunc(drive, NULL, pc->cur_pos, done);
+ }
/* Update the current position */
- pc->xferred += bcount;
- pc->cur_pos += bcount;
+ pc->xferred += done;
+ pc->cur_pos += done;
+
+ bcount -= done;
+
+ if (bcount)
+ ide_pad_transfer(drive, write, bcount);
+
+ debug_log("[cmd %x] transferred %d bytes, padded %d bytes\n",
+ rq->cmd[0], done, bcount);
- debug_log("[cmd %x] transferred %d bytes on that intr.\n",
- rq->cmd[0], bcount);
-next_irq:
/* And set the interrupt handler again */
- ide_set_handler(drive, ide_pc_intr, timeout, NULL);
+ ide_set_handler(drive, ide_pc_intr, timeout);
return ide_started;
}
+static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags,
+ u16 bcount, u8 dma)
+{
+ cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO;
+ cmd->tf_flags |= IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM |
+ IDE_TFLAG_OUT_FEATURE | tf_flags;
+ cmd->tf.command = ATA_CMD_PACKET;
+ cmd->tf.feature = dma; /* Use PIO/DMA */
+ cmd->tf.lbam = bcount & 0xff;
+ cmd->tf.lbah = (bcount >> 8) & 0xff;
+}
+
static u8 ide_read_ireason(ide_drive_t *drive)
{
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_NSECT;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_IN_NSECT;
- drive->hwif->tp_ops->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
- return task.tf.nsect & 3;
+ return cmd.tf.nsect & 3;
}
static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
@@ -560,11 +555,17 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
}
}
+ hwif->expiry = expiry;
+
/* Set the interrupt routine */
ide_set_handler(drive,
(dev_is_idecd(drive) ? drive->irq_handler
: ide_pc_intr),
- timeout, expiry);
+ timeout);
+
+ /* Send the actual packet */
+ if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
+ hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
/* Begin DMA, if necessary */
if (dev_is_idecd(drive)) {
@@ -577,30 +578,28 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
}
}
- /* Send the actual packet */
- if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
- hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
-
return ide_started;
}
-ide_startstop_t ide_issue_pc(ide_drive_t *drive)
+ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_atapi_pc *pc;
ide_hwif_t *hwif = drive->hwif;
ide_expiry_t *expiry = NULL;
+ struct request *rq = hwif->rq;
unsigned int timeout;
u32 tf_flags;
u16 bcount;
+ u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT);
if (dev_is_idecd(drive)) {
tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
- bcount = ide_cd_get_xferlen(hwif->rq);
+ bcount = ide_cd_get_xferlen(rq);
expiry = ide_cd_expiry;
timeout = ATAPI_WAIT_PC;
if (drive->dma)
- drive->dma = !hwif->dma_ops->dma_setup(drive);
+ drive->dma = !ide_dma_prepare(drive, cmd);
} else {
pc = drive->pc;
@@ -618,9 +617,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive)
ide_dma_off(drive);
}
- if ((pc->flags & PC_FLAG_DMA_OK) &&
- (drive->dev_flags & IDE_DFLAG_USING_DMA))
- drive->dma = !hwif->dma_ops->dma_setup(drive);
+ if (pc->flags & PC_FLAG_DMA_OK)
+ drive->dma = !ide_dma_prepare(drive, cmd);
if (!drive->dma)
pc->flags &= ~PC_FLAG_DMA_OK;
@@ -629,18 +627,18 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive)
: WAIT_TAPE_CMD;
}
- ide_pktcmd_tf_load(drive, tf_flags, bcount, drive->dma);
+ ide_init_packet_cmd(cmd, tf_flags, bcount, drive->dma);
- /* Issue the packet command */
- if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
+ (void)do_rw_taskfile(drive, cmd);
+
+ if (drq_int) {
if (drive->dma)
drive->waiting_for_dma = 0;
- ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,
- timeout, expiry);
- return ide_started;
- } else {
- ide_execute_pkt_cmd(drive);
- return ide_transfer_pc(drive);
+ hwif->expiry = expiry;
}
+
+ ide_execute_command(drive, cmd, ide_transfer_pc, timeout);
+
+ return drq_int ? ide_started : ide_transfer_pc(drive);
}
EXPORT_SYMBOL_GPL(ide_issue_pc);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index ddfbea41d296..35729a47f797 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -4,7 +4,7 @@
* Copyright (C) 1994-1996 Scott Snyder <snyder@fnald0.fnal.gov>
* Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org>
* Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de>
- * Copyright (C) 2005, 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2005, 2007-2009 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
@@ -12,12 +12,9 @@
* See Documentation/cdrom/ide-cd for usage information.
*
* Suggestions are welcome. Patches that work are more welcome though. ;-)
- * For those wishing to work on this driver, please be sure you download
- * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI
- * (SFF-8020i rev 2.6) standards. These documents can be obtained by
- * anonymous ftp from:
- * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps
- * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf
+ *
+ * Documentation:
+ * Mt. Fuji (SFF8090 version 4) and ATAPI (SFF-8020i rev 2.6) standards.
*
* For historical changelog please see:
* Documentation/ide/ChangeLog.ide-cd.1994-2004
@@ -100,8 +97,7 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
{
int log = 0;
- ide_debug_log(IDE_DBG_SENSE, "Call %s, sense_key: 0x%x\n", __func__,
- sense->sense_key);
+ ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key);
if (!sense || !rq || (rq->cmd_flags & REQ_QUIET))
return 0;
@@ -151,13 +147,12 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
unsigned long bio_sectors;
struct cdrom_info *info = drive->driver_data;
- ide_debug_log(IDE_DBG_SENSE, "Call %s, error_code: 0x%x, "
- "sense_key: 0x%x\n", __func__, sense->error_code,
- sense->sense_key);
+ ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x",
+ sense->error_code, sense->sense_key);
if (failed_command)
- ide_debug_log(IDE_DBG_SENSE, "%s: failed cmd: 0x%x\n",
- __func__, failed_command->cmd[0]);
+ ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x",
+ failed_command->cmd[0]);
if (!cdrom_log_sense(drive, failed_command, sense))
return;
@@ -215,9 +210,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
struct request *failed_command)
{
struct cdrom_info *info = drive->driver_data;
- struct request *rq = &info->request_sense_request;
+ struct request *rq = &drive->request_sense_rq;
- ide_debug_log(IDE_DBG_SENSE, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_SENSE, "enter");
if (sense == NULL)
sense = &info->sense_data;
@@ -239,77 +234,42 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
rq->buffer = (void *) failed_command;
if (failed_command)
- ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n",
- failed_command->cmd[0]);
+ ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x",
+ failed_command->cmd[0]);
+
+ drive->hwif->rq = NULL;
- ide_do_drive_cmd(drive, rq);
+ elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
}
-static void cdrom_end_request(ide_drive_t *drive, int uptodate)
+static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
{
- struct request *rq = drive->hwif->rq;
- int nsectors = rq->hard_cur_sectors;
-
- ide_debug_log(IDE_DBG_FUNC, "Call %s, cmd: 0x%x, uptodate: 0x%x, "
- "nsectors: %d\n", __func__, rq->cmd[0], uptodate,
- nsectors);
-
- if (blk_sense_request(rq) && uptodate) {
- /*
- * For REQ_TYPE_SENSE, "rq->buffer" points to the original
- * failed request
- */
- struct request *failed = (struct request *) rq->buffer;
- struct cdrom_info *info = drive->driver_data;
- void *sense = &info->sense_data;
-
- if (failed) {
- if (failed->sense) {
- sense = failed->sense;
- failed->sense_len = rq->sense_len;
- }
- cdrom_analyze_sense_data(drive, failed, sense);
- /*
- * now end the failed request
- */
- if (blk_fs_request(failed)) {
- if (ide_end_dequeued_request(drive, failed, 0,
- failed->hard_nr_sectors))
- BUG();
- } else {
- if (blk_end_request(failed, -EIO,
- failed->data_len))
- BUG();
- }
- } else
- cdrom_analyze_sense_data(drive, NULL, sense);
- }
-
- if (!rq->current_nr_sectors && blk_fs_request(rq))
- uptodate = 1;
- /* make sure it's fully ended */
- if (blk_pc_request(rq))
- nsectors = (rq->data_len + 511) >> 9;
- if (!nsectors)
- nsectors = 1;
-
- ide_debug_log(IDE_DBG_FUNC, "Exit %s, uptodate: 0x%x, nsectors: %d\n",
- __func__, uptodate, nsectors);
+ /*
+ * For REQ_TYPE_SENSE, "rq->buffer" points to the original
+ * failed request
+ */
+ struct request *failed = (struct request *)rq->buffer;
+ struct cdrom_info *info = drive->driver_data;
+ void *sense = &info->sense_data;
- ide_end_request(drive, uptodate, nsectors);
-}
+ if (failed) {
+ if (failed->sense) {
+ sense = failed->sense;
+ failed->sense_len = rq->sense_len;
+ }
+ cdrom_analyze_sense_data(drive, failed, sense);
-static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st)
-{
- if (st & 0x80)
- return;
- ide_dump_status(drive, msg, st);
+ if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed)))
+ BUG();
+ } else
+ cdrom_analyze_sense_data(drive, NULL, sense);
}
/*
* Returns:
* 0: if the request should be continued.
- * 1: if the request was ended.
+ * 1: if the request will be going through error recovery.
+ * 2: if the request should be ended.
*/
static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
{
@@ -330,15 +290,10 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
err = ide_read_error(drive);
sense_key = err >> 4;
- if (rq == NULL) {
- printk(KERN_ERR PFX "%s: missing rq in %s\n",
- drive->name, __func__);
- return 1;
- }
-
- ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, "
- "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x\n",
- __func__, stat, good_stat, rq->cmd[0], rq->cmd_type, err);
+ ide_debug_log(IDE_DBG_RQ, "stat: 0x%x, good_stat: 0x%x, cmd[0]: 0x%x, "
+ "rq->cmd_type: 0x%x, err: 0x%x",
+ stat, good_stat, rq->cmd[0], rq->cmd_type,
+ err);
if (blk_sense_request(rq)) {
/*
@@ -347,10 +302,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
* Just give up.
*/
rq->cmd_flags |= REQ_FAILED;
- cdrom_end_request(drive, 0);
- ide_error(drive, "request sense failure", stat);
- return 1;
-
+ return 2;
} else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) {
/* All other functions, except for READ. */
@@ -453,21 +405,19 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
* No point in retrying after an illegal request or data
* protect error.
*/
- ide_dump_status_no_sense(drive, "command error", stat);
+ ide_dump_status(drive, "command error", stat);
do_end_request = 1;
} else if (sense_key == MEDIUM_ERROR) {
/*
* No point in re-trying a zillion times on a bad
* sector. If we got here the error is not correctable.
*/
- ide_dump_status_no_sense(drive,
- "media error (bad sector)",
- stat);
+ ide_dump_status(drive, "media error (bad sector)",
+ stat);
do_end_request = 1;
} else if (sense_key == BLANK_CHECK) {
/* disk appears blank ?? */
- ide_dump_status_no_sense(drive, "media error (blank)",
- stat);
+ ide_dump_status(drive, "media error (blank)", stat);
do_end_request = 1;
} else if ((err & ~ATA_ABORTED) != 0) {
/* go to the default handler for other errors */
@@ -492,14 +442,12 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
*/
if (stat & ATA_ERR)
cdrom_queue_request_sense(drive, NULL, NULL);
+ return 1;
} else {
blk_dump_rq_flags(rq, PFX "bad rq");
- cdrom_end_request(drive, 0);
+ return 2;
}
- /* retry, or handle the next request */
- return 1;
-
end_request:
if (stat & ATA_ERR) {
struct request_queue *q = drive->queue;
@@ -512,10 +460,9 @@ end_request:
hwif->rq = NULL;
cdrom_queue_request_sense(drive, rq->sense, rq);
+ return 1;
} else
- cdrom_end_request(drive, 0);
-
- return 1;
+ return 2;
}
/*
@@ -528,8 +475,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
{
ide_hwif_t *hwif = drive->hwif;
- ide_debug_log(IDE_DBG_FUNC, "Call %s, ireason: 0x%x, rw: 0x%x\n",
- __func__, ireason, rw);
+ ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw);
/*
* ireason == 0: the drive wants to receive data from us
@@ -560,115 +506,28 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
if (rq->cmd_type == REQ_TYPE_ATA_PC)
rq->cmd_flags |= REQ_FAILED;
- cdrom_end_request(drive, 0);
return -1;
}
-/*
- * Assume that the drive will always provide data in multiples of at least
- * SECTOR_SIZE, as it gets hairy to keep track of the transfers otherwise.
- */
-static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
-{
- ide_debug_log(IDE_DBG_FUNC, "Call %s, len: %d\n", __func__, len);
-
- if ((len % SECTOR_SIZE) == 0)
- return 0;
-
- printk(KERN_ERR PFX "%s: %s: Bad transfer size %d\n", drive->name,
- __func__, len);
-
- if (drive->atapi_flags & IDE_AFLAG_LIMIT_NFRAMES)
- printk(KERN_ERR PFX "This drive is not supported by this "
- "version of the driver\n");
- else {
- printk(KERN_ERR PFX "Trying to limit transfer sizes\n");
- drive->atapi_flags |= IDE_AFLAG_LIMIT_NFRAMES;
- }
-
- return 1;
-}
-
-static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
- struct request *rq)
+static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd)
{
- ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd_flags: 0x%x\n", __func__,
- rq->cmd_flags);
+ struct request *rq = cmd->rq;
- if (rq_data_dir(rq) == READ) {
- unsigned short sectors_per_frame =
- queue_hardsect_size(drive->queue) >> SECTOR_BITS;
- int nskip = rq->sector & (sectors_per_frame - 1);
-
- /*
- * If the requested sector doesn't start on a frame boundary,
- * we must adjust the start of the transfer so that it does,
- * and remember to skip the first few sectors.
- *
- * If the rq->current_nr_sectors field is larger than the size
- * of the buffer, it will mean that we're to skip a number of
- * sectors equal to the amount by which rq->current_nr_sectors
- * is larger than the buffer size.
- */
- if (nskip > 0) {
- /* sanity check... */
- if (rq->current_nr_sectors !=
- bio_cur_sectors(rq->bio)) {
- printk(KERN_ERR PFX "%s: %s: buffer botch (%u)\n",
- drive->name, __func__,
- rq->current_nr_sectors);
- cdrom_end_request(drive, 0);
- return ide_stopped;
- }
- rq->current_nr_sectors += nskip;
- }
- }
-
- /* set up the command */
- rq->timeout = ATAPI_WAIT_PC;
-
- return ide_started;
-}
-
-/*
- * Fix up a possibly partially-processed request so that we can start it over
- * entirely, or even put it back on the request queue.
- */
-static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq)
-{
-
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
- if (rq->buffer != bio_data(rq->bio)) {
- sector_t n =
- (rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE;
-
- rq->buffer = bio_data(rq->bio);
- rq->nr_sectors += n;
- rq->sector -= n;
- }
- rq->current_nr_sectors = bio_cur_sectors(rq->bio);
- rq->hard_cur_sectors = rq->current_nr_sectors;
- rq->hard_nr_sectors = rq->nr_sectors;
- rq->hard_sector = rq->sector;
- rq->q->prep_rq_fn(rq->q, rq);
-}
-
-static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq)
-{
- ide_debug_log(IDE_DBG_FUNC, "Call %s, rq->cmd[0]: 0x%x\n",
- __func__, rq->cmd[0]);
+ ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]);
/*
* Some of the trailing request sense fields are optional,
* and some drives don't send them. Sigh.
*/
if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
- rq->data_len > 0 && rq->data_len <= 5)
- while (rq->data_len > 0) {
- *(u8 *)rq->data++ = 0;
- --rq->data_len;
+ cmd->nleft > 0 && cmd->nleft <= 5) {
+ unsigned int ofs = cmd->nbytes - cmd->nleft;
+
+ while (cmd->nleft > 0) {
+ *((u8 *)rq->data + ofs++) = 0;
+ cmd->nleft--;
}
+ }
}
int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
@@ -684,9 +543,9 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
if (!sense)
sense = &local_sense;
- ide_debug_log(IDE_DBG_PC, "Call %s, cmd[0]: 0x%x, write: 0x%x, "
- "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write,
- timeout, cmd_flags);
+ ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, "
+ "cmd_flags: 0x%x",
+ cmd[0], write, timeout, cmd_flags);
/* start of retry loop */
do {
@@ -748,36 +607,40 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
return (flags & REQ_FAILED) ? -EIO : 0;
}
-/*
- * Called from blk_end_request_callback() after the data of the request is
- * completed and before the request itself is completed. By returning value '1',
- * blk_end_request_callback() returns immediately without completing it.
- */
-static int cdrom_newpc_intr_dummy_cb(struct request *rq)
+static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
{
- return 1;
+ unsigned int nr_bytes = cmd->nbytes - cmd->nleft;
+
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
+ nr_bytes -= cmd->last_xfer_len;
+
+ if (nr_bytes > 0)
+ ide_complete_rq(drive, 0, nr_bytes);
}
static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq;
- xfer_func_t *xferfunc;
ide_expiry_t *expiry = NULL;
int dma_error = 0, dma, stat, thislen, uptodate = 0;
- int write = (rq_data_dir(rq) == WRITE) ? 1 : 0;
+ int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors;
+ int sense = blk_sense_request(rq);
unsigned int timeout;
u16 len;
u8 ireason;
- ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x\n",
- __func__, rq->cmd[0], write);
+ ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x",
+ rq->cmd[0], write);
/* check for errors */
dma = drive->dma;
if (dma) {
drive->dma = 0;
+ drive->waiting_for_dma = 0;
dma_error = hwif->dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
if (dma_error) {
printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name,
write ? "write" : "read");
@@ -785,31 +648,29 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
}
}
- if (cdrom_decode_status(drive, 0, &stat))
+ rc = cdrom_decode_status(drive, 0, &stat);
+ if (rc) {
+ if (rc == 2)
+ goto out_end;
return ide_stopped;
+ }
/* using dma, transfer is complete now */
if (dma) {
if (dma_error)
return ide_error(drive, "dma error", stat);
- if (blk_fs_request(rq)) {
- ide_end_request(drive, 1, rq->nr_sectors);
- return ide_stopped;
- } else if (rq->cmd_type == REQ_TYPE_ATA_PC && !rq->bio) {
- ide_end_request(drive, 1, 1);
- return ide_stopped;
- }
- goto end_request;
+ uptodate = 1;
+ goto out_end;
}
ide_read_bcount_and_ireason(drive, &len, &ireason);
- thislen = blk_fs_request(rq) ? len : rq->data_len;
+ thislen = blk_fs_request(rq) ? len : cmd->nleft;
if (thislen > len)
thislen = len;
- ide_debug_log(IDE_DBG_PC, "%s: DRQ: stat: 0x%x, thislen: %d\n",
- __func__, stat, thislen);
+ ide_debug_log(IDE_DBG_PC, "DRQ: stat: 0x%x, thislen: %d",
+ stat, thislen);
/* If DRQ is clear, the command has completed. */
if ((stat & ATA_DRQ) == 0) {
@@ -819,135 +680,62 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
* Otherwise, complete the command normally.
*/
uptodate = 1;
- if (rq->current_nr_sectors > 0) {
+ if (cmd->nleft > 0) {
printk(KERN_ERR PFX "%s: %s: data underrun "
- "(%d blocks)\n",
- drive->name, __func__,
- rq->current_nr_sectors);
+ "(%u bytes)\n", drive->name, __func__,
+ cmd->nleft);
if (!write)
rq->cmd_flags |= REQ_FAILED;
uptodate = 0;
}
- cdrom_end_request(drive, uptodate);
- return ide_stopped;
} else if (!blk_pc_request(rq)) {
- ide_cd_request_sense_fixup(drive, rq);
+ ide_cd_request_sense_fixup(drive, cmd);
/* complain if we still have data left to transfer */
- uptodate = rq->data_len ? 0 : 1;
+ uptodate = cmd->nleft ? 0 : 1;
+ if (uptodate == 0)
+ rq->cmd_flags |= REQ_FAILED;
}
- goto end_request;
+ goto out_end;
}
/* check which way to transfer data */
- if (ide_cd_check_ireason(drive, rq, len, ireason, write))
- return ide_stopped;
+ rc = ide_cd_check_ireason(drive, rq, len, ireason, write);
+ if (rc)
+ goto out_end;
- if (blk_fs_request(rq)) {
- if (write == 0) {
- int nskip;
+ cmd->last_xfer_len = 0;
- if (ide_cd_check_transfer_size(drive, len)) {
- cdrom_end_request(drive, 0);
- return ide_stopped;
- }
-
- /*
- * First, figure out if we need to bit-bucket
- * any of the leading sectors.
- */
- nskip = min_t(int, rq->current_nr_sectors
- - bio_cur_sectors(rq->bio),
- thislen >> 9);
- if (nskip > 0) {
- ide_pad_transfer(drive, write, nskip << 9);
- rq->current_nr_sectors -= nskip;
- thislen -= (nskip << 9);
- }
- }
- }
-
- if (ireason == 0) {
- write = 1;
- xferfunc = hwif->tp_ops->output_data;
- } else {
- write = 0;
- xferfunc = hwif->tp_ops->input_data;
- }
-
- ide_debug_log(IDE_DBG_PC, "%s: data transfer, rq->cmd_type: 0x%x, "
- "ireason: 0x%x\n", __func__, rq->cmd_type, ireason);
+ ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, "
+ "ireason: 0x%x",
+ rq->cmd_type, ireason);
/* transfer data */
while (thislen > 0) {
- u8 *ptr = blk_fs_request(rq) ? NULL : rq->data;
- int blen = rq->data_len;
-
- /* bio backed? */
- if (rq->bio) {
- if (blk_fs_request(rq)) {
- ptr = rq->buffer;
- blen = rq->current_nr_sectors << 9;
- } else {
- ptr = bio_data(rq->bio);
- blen = bio_iovec(rq->bio)->bv_len;
- }
- }
+ int blen = min_t(int, thislen, cmd->nleft);
- if (!ptr) {
- if (blk_fs_request(rq) && !write)
- /*
- * If the buffers are full, pipe the rest into
- * oblivion.
- */
- ide_pad_transfer(drive, 0, thislen);
- else {
- printk(KERN_ERR PFX "%s: confused, missing data\n",
- drive->name);
- blk_dump_rq_flags(rq, rq_data_dir(rq)
- ? "cdrom_newpc_intr, write"
- : "cdrom_newpc_intr, read");
- }
+ if (cmd->nleft == 0)
break;
- }
- if (blen > thislen)
- blen = thislen;
-
- xferfunc(drive, NULL, ptr, blen);
+ ide_pio_bytes(drive, cmd, write, blen);
+ cmd->last_xfer_len += blen;
thislen -= blen;
len -= blen;
- if (blk_fs_request(rq)) {
- rq->buffer += blen;
- rq->nr_sectors -= (blen >> 9);
- rq->current_nr_sectors -= (blen >> 9);
- rq->sector += (blen >> 9);
-
- if (rq->current_nr_sectors == 0 && rq->nr_sectors)
- cdrom_end_request(drive, 1);
- } else {
- rq->data_len -= blen;
-
- /*
- * The request can't be completed until DRQ is cleared.
- * So complete the data, but don't complete the request
- * using the dummy function for the callback feature
- * of blk_end_request_callback().
- */
- if (rq->bio)
- blk_end_request_callback(rq, 0, blen,
- cdrom_newpc_intr_dummy_cb);
- else
- rq->data += blen;
- }
- if (!write && blk_sense_request(rq))
+ if (sense && write == 0)
rq->sense_len += blen;
}
/* pad, if necessary */
- if (!blk_fs_request(rq) && len > 0)
- ide_pad_transfer(drive, write, len);
+ if (len > 0) {
+ if (blk_fs_request(rq) == 0 || write == 0)
+ ide_pad_transfer(drive, write, len);
+ else {
+ printk(KERN_ERR PFX "%s: confused, missing data\n",
+ drive->name);
+ blk_dump_rq_flags(rq, "cdrom_newpc_intr");
+ }
+ }
if (blk_pc_request(rq)) {
timeout = rq->timeout;
@@ -957,24 +745,54 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
expiry = ide_cd_expiry;
}
- ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry);
+ hwif->expiry = expiry;
+ ide_set_handler(drive, cdrom_newpc_intr, timeout);
return ide_started;
-end_request:
- if (blk_pc_request(rq)) {
+out_end:
+ if (blk_pc_request(rq) && rc == 0) {
unsigned int dlen = rq->data_len;
- if (dma)
- rq->data_len = 0;
+ rq->data_len = 0;
if (blk_end_request(rq, 0, dlen))
BUG();
hwif->rq = NULL;
} else {
- if (!uptodate)
- rq->cmd_flags |= REQ_FAILED;
- cdrom_end_request(drive, uptodate);
+ if (sense && uptodate)
+ ide_cd_complete_failed_rq(drive, rq);
+
+ if (blk_fs_request(rq)) {
+ if (cmd->nleft == 0)
+ uptodate = 1;
+ } else {
+ if (uptodate <= 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ }
+
+ if (uptodate == 0)
+ ide_cd_error_cmd(drive, cmd);
+
+ /* make sure it's fully ended */
+ if (blk_pc_request(rq))
+ nsectors = (rq->data_len + 511) >> 9;
+ else
+ nsectors = rq->hard_nr_sectors;
+
+ if (nsectors == 0)
+ nsectors = 1;
+
+ if (blk_fs_request(rq) == 0) {
+ rq->data_len -= (cmd->nbytes - cmd->nleft);
+ if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE))
+ rq->data_len += cmd->last_xfer_len;
+ }
+
+ ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
+
+ if (sense && rc == 2)
+ ide_error(drive, "request sense failure", stat);
}
return ide_stopped;
}
@@ -982,51 +800,48 @@ end_request:
static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
{
struct cdrom_info *cd = drive->driver_data;
+ struct request_queue *q = drive->queue;
int write = rq_data_dir(rq) == WRITE;
unsigned short sectors_per_frame =
- queue_hardsect_size(drive->queue) >> SECTOR_BITS;
+ queue_hardsect_size(q) >> SECTOR_BITS;
- ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, "
- "secs_per_frame: %u\n",
- __func__, rq->cmd[0], write, sectors_per_frame);
+ ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, "
+ "secs_per_frame: %u",
+ rq->cmd[0], rq->cmd_flags, sectors_per_frame);
if (write) {
/* disk has become write protected */
- if (get_disk_ro(cd->disk)) {
- cdrom_end_request(drive, 0);
+ if (get_disk_ro(cd->disk))
return ide_stopped;
- }
} else {
/*
* We may be retrying this request after an error. Fix up any
* weirdness which might be present in the request packet.
*/
- ide_cd_restore_request(drive, rq);
+ q->prep_rq_fn(q, rq);
}
- /* use DMA, if possible / writes *must* be hardware frame aligned */
+ /* fs requests *must* be hardware frame aligned */
if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
- (rq->sector & (sectors_per_frame - 1))) {
- if (write) {
- cdrom_end_request(drive, 0);
- return ide_stopped;
- }
- drive->dma = 0;
- } else
- drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
+ (rq->sector & (sectors_per_frame - 1)))
+ return ide_stopped;
+
+ /* use DMA, if possible */
+ drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
if (write)
cd->devinfo.media_written = 1;
+ rq->timeout = ATAPI_WAIT_PC;
+
return ide_started;
}
static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
{
- ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, "
- "rq->cmd_type: 0x%x\n", __func__, rq->cmd[0],
- rq->cmd_type);
+ ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x",
+ rq->cmd[0], rq->cmd_type);
if (blk_pc_request(rq))
rq->cmd_flags |= REQ_QUIET;
@@ -1065,17 +880,18 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
sector_t block)
{
- ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, "
- "rq->cmd_type: 0x%x, block: %llu\n",
- __func__, rq->cmd[0], rq->cmd_type,
- (unsigned long long)block);
+ struct ide_cmd cmd;
+ int uptodate = 0, nsectors;
+
+ ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu",
+ rq->cmd[0], (unsigned long long)block);
+
+ if (drive->debug_mask & IDE_DBG_RQ)
+ blk_dump_rq_flags(rq, "ide_cd_do_request");
if (blk_fs_request(rq)) {
if (cdrom_start_rw(drive, rq) == ide_stopped)
- return ide_stopped;
-
- if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped)
- return ide_stopped;
+ goto out_end;
} else if (blk_sense_request(rq) || blk_pc_request(rq) ||
rq->cmd_type == REQ_TYPE_ATA_PC) {
if (!rq->timeout)
@@ -1084,15 +900,38 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
cdrom_do_block_pc(drive, rq);
} else if (blk_special_request(rq)) {
/* right now this can only be a reset... */
- cdrom_end_request(drive, 1);
- return ide_stopped;
+ uptodate = 1;
+ goto out_end;
} else {
blk_dump_rq_flags(rq, DRV_NAME " bad flags");
- cdrom_end_request(drive, 0);
- return ide_stopped;
+ if (rq->errors == 0)
+ rq->errors = -EIO;
+ goto out_end;
+ }
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ if (rq_data_dir(rq))
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+ cmd.rq = rq;
+
+ if (blk_fs_request(rq) || rq->data_len) {
+ ide_init_sg_cmd(&cmd, blk_fs_request(rq) ? (rq->nr_sectors << 9)
+ : rq->data_len);
+ ide_map_sg(drive, &cmd);
}
- return ide_issue_pc(drive);
+ return ide_issue_pc(drive, &cmd);
+out_end:
+ nsectors = rq->hard_nr_sectors;
+
+ if (nsectors == 0)
+ nsectors = 1;
+
+ ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
+
+ return ide_stopped;
}
/*
@@ -1117,7 +956,7 @@ int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
struct cdrom_device_info *cdi = &info->devinfo;
unsigned char cmd[BLK_MAX_CDB];
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
memset(cmd, 0, BLK_MAX_CDB);
cmd[0] = GPCMD_TEST_UNIT_READY;
@@ -1145,7 +984,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
unsigned len = sizeof(capbuf);
u32 blocklen;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
memset(cmd, 0, BLK_MAX_CDB);
cmd[0] = GPCMD_READ_CDVD_CAPACITY;
@@ -1177,8 +1016,8 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
*capacity = 1 + be32_to_cpu(capbuf.lba);
*sectors_per_frame = blocklen >> SECTOR_BITS;
- ide_debug_log(IDE_DBG_PROBE, "%s: cap: %lu, sectors_per_frame: %lu\n",
- __func__, *capacity, *sectors_per_frame);
+ ide_debug_log(IDE_DBG_PROBE, "cap: %lu, sectors_per_frame: %lu",
+ *capacity, *sectors_per_frame);
return 0;
}
@@ -1189,7 +1028,7 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
{
unsigned char cmd[BLK_MAX_CDB];
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
memset(cmd, 0, BLK_MAX_CDB);
@@ -1219,7 +1058,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
long last_written;
unsigned long sectors_per_frame = SECTORS_PER_FRAME;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
if (toc == NULL) {
/* try to allocate space */
@@ -1381,7 +1220,7 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
struct packet_command cgc;
int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0)
size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE;
@@ -1401,7 +1240,7 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
struct cdrom_info *cd = drive->driver_data;
u16 curspeed, maxspeed;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) {
curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]);
@@ -1411,8 +1250,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]);
}
- ide_debug_log(IDE_DBG_PROBE, "%s: curspeed: %u, maxspeed: %u\n",
- __func__, curspeed, maxspeed);
+ ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u",
+ curspeed, maxspeed);
cd->current_speed = (curspeed + (176/2)) / 176;
cd->max_speed = (maxspeed + (176/2)) / 176;
@@ -1446,7 +1285,7 @@ static int ide_cdrom_register(ide_drive_t *drive, int nslots)
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *devinfo = &info->devinfo;
- ide_debug_log(IDE_DBG_PROBE, "Call %s, nslots: %d\n", __func__, nslots);
+ ide_debug_log(IDE_DBG_PROBE, "nslots: %d", nslots);
devinfo->ops = &ide_cdrom_dops;
devinfo->speed = info->current_speed;
@@ -1469,9 +1308,8 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
mechtype_t mechtype;
int nslots = 1;
- ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->media: 0x%x, "
- "drive->atapi_flags: 0x%lx\n", __func__, drive->media,
- drive->atapi_flags);
+ ide_debug_log(IDE_DBG_PROBE, "media: 0x%x, atapi_flags: 0x%lx",
+ drive->media, drive->atapi_flags);
cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R |
CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO |
@@ -1685,9 +1523,6 @@ static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive)
#endif
static const struct cd_list_entry ide_cd_quirks_list[] = {
- /* Limit transfer size per interrupt. */
- { "SAMSUNG CD-ROM SCR-2430", NULL, IDE_AFLAG_LIMIT_NFRAMES },
- { "SAMSUNG CD-ROM SCR-2432", NULL, IDE_AFLAG_LIMIT_NFRAMES },
/* SCR-3231 doesn't support the SET_CD_SPEED command. */
{ "SAMSUNG CD-ROM SCR-3231", NULL, IDE_AFLAG_NO_SPEED_SELECT },
/* Old NEC260 (not R) was released before ATAPI 1.2 spec. */
@@ -1748,18 +1583,18 @@ static int ide_cdrom_setup(ide_drive_t *drive)
{
struct cdrom_info *cd = drive->driver_data;
struct cdrom_device_info *cdi = &cd->devinfo;
+ struct request_queue *q = drive->queue;
u16 *id = drive->id;
char *fw_rev = (char *)&id[ATA_ID_FW_REV];
int nslots;
- ide_debug_log(IDE_DBG_PROBE, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_PROBE, "enter");
- blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
- blk_queue_dma_alignment(drive->queue, 31);
- blk_queue_update_dma_pad(drive->queue, 15);
- drive->queue->unplug_delay = (1 * HZ) / 1000;
- if (!drive->queue->unplug_delay)
- drive->queue->unplug_delay = 1;
+ blk_queue_prep_rq(q, ide_cdrom_prep_fn);
+ blk_queue_dma_alignment(q, 31);
+ blk_queue_update_dma_pad(q, 15);
+
+ q->unplug_delay = max((1 * HZ) / 1000, 1);
drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id);
@@ -1777,8 +1612,7 @@ static int ide_cdrom_setup(ide_drive_t *drive)
nslots = ide_cdrom_probe_capabilities(drive);
- /* set correct block size */
- blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
+ blk_queue_hardsect_size(q, CD_FRAMESIZE);
if (ide_cdrom_register(drive, nslots)) {
printk(KERN_ERR PFX "%s: %s failed to register device with the"
@@ -1795,7 +1629,7 @@ static void ide_cd_remove(ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
ide_proc_unregister_driver(drive, info->driver);
device_del(&info->dev);
@@ -1813,7 +1647,7 @@ static void ide_cd_release(struct device *dev)
ide_drive_t *drive = info->drive;
struct gendisk *g = info->disk;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
kfree(info->toc);
if (devinfo->handle == drive)
@@ -1837,7 +1671,6 @@ static struct ide_driver ide_cdrom_driver = {
.remove = ide_cd_remove,
.version = IDECD_VERSION,
.do_request = ide_cd_do_request,
- .end_request = ide_end_request,
#ifdef CONFIG_IDE_PROC_FS
.proc_entries = ide_cd_proc_entries,
.proc_devsets = ide_cd_proc_devsets,
@@ -1958,9 +1791,6 @@ static struct block_device_operations idecd_ops = {
};
/* module options */
-static char *ignore;
-module_param(ignore, charp, 0400);
-
static unsigned long debug_mask;
module_param(debug_mask, ulong, 0644);
@@ -1972,9 +1802,8 @@ static int ide_cd_probe(ide_drive_t *drive)
struct gendisk *g;
struct request_sense sense;
- ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->driver_req: %s, "
- "drive->media: 0x%x\n", __func__, drive->driver_req,
- drive->media);
+ ide_debug_log(IDE_DBG_PROBE, "driver_req: %s, media: 0x%x",
+ drive->driver_req, drive->media);
if (!strstr("ide-cdrom", drive->driver_req))
goto failed;
@@ -1982,15 +1811,6 @@ static int ide_cd_probe(ide_drive_t *drive)
if (drive->media != ide_cdrom && drive->media != ide_optical)
goto failed;
- /* skip drives that we were told to ignore */
- if (ignore != NULL) {
- if (strstr(ignore, drive->name)) {
- printk(KERN_INFO PFX "ignoring drive %s\n",
- drive->name);
- goto failed;
- }
- }
-
drive->debug_mask = debug_mask;
drive->irq_handler = cdrom_newpc_intr;
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index c878bfcf1116..1d97101099ce 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -11,7 +11,7 @@
#define IDECD_DEBUG_LOG 0
#if IDECD_DEBUG_LOG
-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args)
#else
#define ide_debug_log(lvl, fmt, args...) do {} while (0)
#endif
@@ -91,8 +91,6 @@ struct cdrom_info {
on this device. */
struct request_sense sense_data;
- struct request request_sense_request;
-
u8 max_speed; /* Max speed of the drive. */
u8 current_speed; /* Current speed of the drive. */
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c
index f50210fe558f..9e47f3529d55 100644
--- a/drivers/ide/ide-cs.c
+++ b/drivers/ide/ide-cs.c
@@ -154,6 +154,7 @@ static const struct ide_port_ops idecs_port_ops = {
static const struct ide_port_info idecs_port_info = {
.port_ops = &idecs_port_ops,
.host_flags = IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
};
static struct ide_host *idecs_register(unsigned long io, unsigned long ctl,
diff --git a/drivers/ide/ide-devsets.c b/drivers/ide/ide-devsets.c
new file mode 100644
index 000000000000..5bf958e5b1d5
--- /dev/null
+++ b/drivers/ide/ide-devsets.c
@@ -0,0 +1,188 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+
+DEFINE_MUTEX(ide_setting_mtx);
+
+ide_devset_get(io_32bit, io_32bit);
+
+static int set_io_32bit(ide_drive_t *drive, int arg)
+{
+ if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT)
+ return -EPERM;
+
+ if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
+ return -EINVAL;
+
+ drive->io_32bit = arg;
+
+ return 0;
+}
+
+ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS);
+
+static int set_ksettings(ide_drive_t *drive, int arg)
+{
+ if (arg < 0 || arg > 1)
+ return -EINVAL;
+
+ if (arg)
+ drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS;
+ else
+ drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS;
+
+ return 0;
+}
+
+ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA);
+
+static int set_using_dma(ide_drive_t *drive, int arg)
+{
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ int err = -EPERM;
+
+ if (arg < 0 || arg > 1)
+ return -EINVAL;
+
+ if (ata_id_has_dma(drive->id) == 0)
+ goto out;
+
+ if (drive->hwif->dma_ops == NULL)
+ goto out;
+
+ err = 0;
+
+ if (arg) {
+ if (ide_set_dma(drive))
+ err = -EIO;
+ } else
+ ide_dma_off(drive);
+
+out:
+ return err;
+#else
+ if (arg < 0 || arg > 1)
+ return -EINVAL;
+
+ return -EPERM;
+#endif
+}
+
+/*
+ * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away
+ */
+static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio)
+{
+ switch (req_pio) {
+ case 202:
+ case 201:
+ case 200:
+ case 102:
+ case 101:
+ case 100:
+ return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0;
+ case 9:
+ case 8:
+ return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0;
+ case 7:
+ case 6:
+ return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0;
+ default:
+ return 0;
+ }
+}
+
+static int set_pio_mode(ide_drive_t *drive, int arg)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (arg < 0 || arg > 255)
+ return -EINVAL;
+
+ if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
+ (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
+ return -ENOSYS;
+
+ if (set_pio_mode_abuse(drive->hwif, arg)) {
+ if (arg == 8 || arg == 9) {
+ unsigned long flags;
+
+ /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
+ spin_lock_irqsave(&hwif->lock, flags);
+ port_ops->set_pio_mode(drive, arg);
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ } else
+ port_ops->set_pio_mode(drive, arg);
+ } else {
+ int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
+
+ ide_set_pio(drive, arg);
+
+ if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
+ if (keep_dma)
+ ide_dma_on(drive);
+ }
+ }
+
+ return 0;
+}
+
+ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK);
+
+static int set_unmaskirq(ide_drive_t *drive, int arg)
+{
+ if (drive->dev_flags & IDE_DFLAG_NO_UNMASK)
+ return -EPERM;
+
+ if (arg < 0 || arg > 1)
+ return -EINVAL;
+
+ if (arg)
+ drive->dev_flags |= IDE_DFLAG_UNMASK;
+ else
+ drive->dev_flags &= ~IDE_DFLAG_UNMASK;
+
+ return 0;
+}
+
+ide_ext_devset_rw_sync(io_32bit, io_32bit);
+ide_ext_devset_rw_sync(keepsettings, ksettings);
+ide_ext_devset_rw_sync(unmaskirq, unmaskirq);
+ide_ext_devset_rw_sync(using_dma, using_dma);
+__IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode);
+
+int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
+ int arg)
+{
+ struct request_queue *q = drive->queue;
+ struct request *rq;
+ int ret = 0;
+
+ if (!(setting->flags & DS_SYNC))
+ return setting->set(drive, arg);
+
+ rq = blk_get_request(q, READ, __GFP_WAIT);
+ rq->cmd_type = REQ_TYPE_SPECIAL;
+ rq->cmd_len = 5;
+ rq->cmd[0] = REQ_DEVSET_EXEC;
+ *(int *)&rq->cmd[1] = arg;
+ rq->special = setting->set;
+
+ if (blk_execute_rq(q, NULL, rq, 0))
+ ret = rq->errors;
+ blk_put_request(rq);
+
+ return ret;
+}
+
+ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq)
+{
+ int err, (*setfunc)(ide_drive_t *, int) = rq->special;
+
+ err = setfunc(drive, *(int *)&rq->cmd[1]);
+ if (err)
+ rq->errors = err;
+ ide_complete_rq(drive, err, ide_rq_bytes(rq));
+ return ide_stopped;
+}
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 806760d24cef..c998cf8e971a 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -28,7 +28,6 @@
#include <linux/mutex.h>
#include <linux/leds.h>
#include <linux/ide.h>
-#include <linux/hdreg.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
@@ -53,33 +52,26 @@ static const u8 ide_rw_cmds[] = {
ATA_CMD_WRITE_EXT,
};
-static const u8 ide_data_phases[] = {
- TASKFILE_MULTI_IN,
- TASKFILE_MULTI_OUT,
- TASKFILE_IN,
- TASKFILE_OUT,
- TASKFILE_IN_DMA,
- TASKFILE_OUT_DMA,
-};
-
-static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma)
+static void ide_tf_set_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 dma)
{
u8 index, lba48, write;
- lba48 = (task->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0;
- write = (task->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
+ lba48 = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0;
+ write = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
- if (dma)
+ if (dma) {
+ cmd->protocol = ATA_PROT_DMA;
index = 8;
- else
- index = drive->mult_count ? 0 : 4;
-
- task->tf.command = ide_rw_cmds[index + lba48 + write];
-
- if (dma)
- index = 8; /* fixup index */
+ } else {
+ cmd->protocol = ATA_PROT_PIO;
+ if (drive->mult_count) {
+ cmd->tf_flags |= IDE_TFLAG_MULTI_PIO;
+ index = 0;
+ } else
+ index = 4;
+ }
- task->data_phase = ide_data_phases[index / 2 + write];
+ cmd->tf.command = ide_rw_cmds[index + lba48 + write];
}
/*
@@ -93,8 +85,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
u16 nsectors = (u16)rq->nr_sectors;
u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
- ide_task_t task;
- struct ide_taskfile *tf = &task.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
ide_startstop_t rc;
if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) {
@@ -104,13 +96,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
lba48 = 0;
}
- if (!dma) {
- ide_init_sg_cmd(drive, rq);
- ide_map_sg(drive, rq);
- }
-
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (drive->dev_flags & IDE_DFLAG_LBA) {
if (lba48) {
@@ -129,7 +116,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
tf->lbam = (u8)(block >> 8);
tf->lbah = (u8)(block >> 16);
- task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+ cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
} else {
tf->nsect = nsectors & 0xff;
tf->lbal = block;
@@ -156,23 +143,27 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
tf->device = head;
}
+ cmd.tf_flags |= IDE_TFLAG_FS;
+
if (rq_data_dir(rq))
- task.tf_flags |= IDE_TFLAG_WRITE;
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+ ide_tf_set_cmd(drive, &cmd, dma);
+ cmd.rq = rq;
- ide_tf_set_cmd(drive, &task, dma);
- if (!dma)
- hwif->data_phase = task.data_phase;
- task.rq = rq;
+ if (dma == 0) {
+ ide_init_sg_cmd(&cmd, nsectors << 9);
+ ide_map_sg(drive, &cmd);
+ }
- rc = do_rw_taskfile(drive, &task);
+ rc = do_rw_taskfile(drive, &cmd);
if (rc == ide_stopped && dma) {
/* fallback to PIO */
- task.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK;
- ide_tf_set_cmd(drive, &task, 0);
- hwif->data_phase = task.data_phase;
- ide_init_sg_cmd(drive, rq);
- rc = do_rw_taskfile(drive, &task);
+ cmd.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK;
+ ide_tf_set_cmd(drive, &cmd, 0);
+ ide_init_sg_cmd(&cmd, nsectors << 9);
+ rc = do_rw_taskfile(drive, &cmd);
}
return rc;
@@ -193,7 +184,9 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
if (!blk_fs_request(rq)) {
blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command");
- ide_end_request(drive, 0, 0);
+ if (rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
return ide_stopped;
}
@@ -216,25 +209,25 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
*/
static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
u64 addr = 0;
- /* Create IDE/ATA command request structure */
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
if (lba48)
tf->command = ATA_CMD_READ_NATIVE_MAX_EXT;
else
tf->command = ATA_CMD_READ_NATIVE_MAX;
tf->device = ATA_LBA;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (lba48)
- args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
- /* submit command request */
- ide_no_data_taskfile(drive, &args);
+ cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+
+ ide_no_data_taskfile(drive, &cmd);
/* if OK, compute maximum address value */
- if ((tf->status & 0x01) == 0)
+ if (!(tf->status & ATA_ERR))
addr = ide_get_lba_addr(tf, lba48) + 1;
return addr;
@@ -246,13 +239,13 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
*/
static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
u64 addr_set = 0;
addr_req--;
- /* Create IDE/ATA command request structure */
- memset(&args, 0, sizeof(ide_task_t));
+
+ memset(&cmd, 0, sizeof(cmd));
tf->lbal = (addr_req >> 0) & 0xff;
tf->lbam = (addr_req >>= 8) & 0xff;
tf->lbah = (addr_req >>= 8) & 0xff;
@@ -266,13 +259,15 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
tf->command = ATA_CMD_SET_MAX;
}
tf->device |= ATA_LBA;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (lba48)
- args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
- /* submit command request */
- ide_no_data_taskfile(drive, &args);
+ cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+
+ ide_no_data_taskfile(drive, &cmd);
+
/* if OK, compute maximum address value */
- if ((tf->status & 0x01) == 0)
+ if (!(tf->status & ATA_ERR))
addr_set = ide_get_lba_addr(tf, lba48) + 1;
return addr_set;
@@ -389,24 +384,24 @@ static int ide_disk_get_capacity(ide_drive_t *drive)
static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
{
ide_drive_t *drive = q->queuedata;
- ide_task_t *task = kmalloc(sizeof(*task), GFP_ATOMIC);
+ struct ide_cmd *cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
/* FIXME: map struct ide_taskfile on rq->cmd[] */
- BUG_ON(task == NULL);
+ BUG_ON(cmd == NULL);
- memset(task, 0, sizeof(*task));
+ memset(cmd, 0, sizeof(*cmd));
if (ata_id_flush_ext_enabled(drive->id) &&
(drive->capacity64 >= (1UL << 28)))
- task->tf.command = ATA_CMD_FLUSH_EXT;
+ cmd->tf.command = ATA_CMD_FLUSH_EXT;
else
- task->tf.command = ATA_CMD_FLUSH;
- task->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
- IDE_TFLAG_DYN;
- task->data_phase = TASKFILE_NO_DATA;
+ cmd->tf.command = ATA_CMD_FLUSH;
+ cmd->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
+ IDE_TFLAG_DYN;
+ cmd->protocol = ATA_PROT_NODATA;
rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
rq->cmd_flags |= REQ_SOFTBARRIER;
- rq->special = task;
+ rq->special = cmd;
}
ide_devset_get(multcount, mult_count);
@@ -456,15 +451,15 @@ static int set_nowerr(ide_drive_t *drive, int arg)
static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect)
{
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
- task.tf.feature = feature;
- task.tf.nsect = nsect;
- task.tf.command = ATA_CMD_SET_FEATURES;
- task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf.feature = feature;
+ cmd.tf.nsect = nsect;
+ cmd.tf.command = ATA_CMD_SET_FEATURES;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- return ide_no_data_taskfile(drive, &task);
+ return ide_no_data_taskfile(drive, &cmd);
}
static void update_ordered(ide_drive_t *drive)
@@ -531,15 +526,16 @@ static int set_wcache(ide_drive_t *drive, int arg)
static int do_idedisk_flushcache(ide_drive_t *drive)
{
- ide_task_t args;
+ struct ide_cmd cmd;
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
if (ata_id_flush_ext_enabled(drive->id))
- args.tf.command = ATA_CMD_FLUSH_EXT;
+ cmd.tf.command = ATA_CMD_FLUSH_EXT;
else
- args.tf.command = ATA_CMD_FLUSH;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- return ide_no_data_taskfile(drive, &args);
+ cmd.tf.command = ATA_CMD_FLUSH;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ return ide_no_data_taskfile(drive, &cmd);
}
ide_devset_get(acoustic, acoustic);
@@ -711,17 +707,17 @@ static int ide_disk_init_media(ide_drive_t *drive, struct gendisk *disk)
static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk,
int on)
{
- ide_task_t task;
+ struct ide_cmd cmd;
int ret;
if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0)
return 0;
- memset(&task, 0, sizeof(task));
- task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
- task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- ret = ide_no_data_taskfile(drive, &task);
+ ret = ide_no_data_taskfile(drive, &cmd);
if (ret)
drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
@@ -737,6 +733,5 @@ const struct ide_disk_ops ide_ata_disk_ops = {
.init_media = ide_disk_init_media,
.set_doorlock = ide_disk_set_doorlock,
.do_request = ide_do_rw_disk,
- .end_request = ide_end_request,
.ioctl = ide_disk_ioctl,
};
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c
index 1f86dcbd2b1c..eaea3bef2073 100644
--- a/drivers/ide/ide-disk_proc.c
+++ b/drivers/ide/ide-disk_proc.c
@@ -1,38 +1,38 @@
#include <linux/kernel.h>
#include <linux/ide.h>
-#include <linux/hdreg.h>
#include "ide-disk.h"
static int smart_enable(ide_drive_t *drive)
{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
tf->feature = ATA_SMART_ENABLE;
tf->lbam = ATA_SMART_LBAM_PASS;
tf->lbah = ATA_SMART_LBAH_PASS;
tf->command = ATA_CMD_SMART;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- return ide_no_data_taskfile(drive, &args);
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ return ide_no_data_taskfile(drive, &cmd);
}
static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
tf->feature = sub_cmd;
tf->nsect = 0x01;
tf->lbam = ATA_SMART_LBAM_PASS;
tf->lbah = ATA_SMART_LBAH_PASS;
tf->command = ATA_CMD_SMART;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- args.data_phase = TASKFILE_IN;
- (void) smart_enable(drive);
- return ide_raw_taskfile(drive, &args, buf, 1);
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.protocol = ATA_PROT_PIO;
+
+ return ide_raw_taskfile(drive, &cmd, buf, 1);
}
static int proc_idedisk_read_cache
@@ -67,6 +67,8 @@ static int proc_idedisk_read_smart(char *page, char **start, off_t off,
ide_drive_t *drive = (ide_drive_t *)data;
int len = 0, i = 0;
+ (void)smart_enable(drive);
+
if (get_smart_data(drive, page, sub_cmd) == 0) {
unsigned short *val = (unsigned short *) page;
char *out = (char *)val + SECTOR_SIZE;
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index 123d393658af..16fc46edc32d 100644
--- a/drivers/ide/ide-dma-sff.c
+++ b/drivers/ide/ide-dma-sff.c
@@ -38,10 +38,9 @@ int config_drive_for_dma(ide_drive_t *drive)
* Enable DMA on any drive that has mode2 DMA
* (multi or single) enabled
*/
- if (id[ATA_ID_FIELD_VALID] & 2) /* regular DMA */
- if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
- (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
- return 1;
+ if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
+ (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
+ return 1;
/* Consult the list of known "good" drives */
if (ide_dma_good_drive(drive))
@@ -111,7 +110,7 @@ EXPORT_SYMBOL_GPL(ide_dma_host_set);
* May also be invoked from trm290.c
*/
-int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+int ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
__le32 *table = (__le32 *)hwif->dmatable_cpu;
@@ -120,11 +119,7 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
struct scatterlist *sg;
u8 is_trm290 = !!(hwif->host_flags & IDE_HFLAG_TRM290);
- hwif->sg_nents = ide_build_sglist(drive, rq);
- if (hwif->sg_nents == 0)
- return 0;
-
- for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
+ for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) {
u32 cur_addr, cur_len, xcount, bcount;
cur_addr = sg_dma_address(sg);
@@ -170,8 +165,6 @@ use_pio_instead:
printk(KERN_ERR "%s: %s\n", drive->name,
count ? "DMA table too small" : "empty DMA table?");
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
EXPORT_SYMBOL_GPL(ide_build_dmatable);
@@ -179,6 +172,7 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
/**
* ide_dma_setup - begin a DMA phase
* @drive: target device
+ * @cmd: command
*
* Build an IDE DMA PRD (IDE speak for scatter gather table)
* and then set up the DMA transfer registers for a device
@@ -189,17 +183,16 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
* is returned.
*/
-int ide_dma_setup(ide_drive_t *drive)
+int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
- unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR;
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+ u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
u8 dma_stat;
/* fall back to pio! */
- if (!ide_build_dmatable(drive, rq)) {
- ide_map_sg(drive, rq);
+ if (ide_build_dmatable(drive, cmd) == 0) {
+ ide_map_sg(drive, cmd);
return 1;
}
@@ -212,9 +205,9 @@ int ide_dma_setup(ide_drive_t *drive)
/* specify r/w */
if (mmio)
- writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+ writeb(rw, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
else
- outb(reading, hwif->dma_base + ATA_DMA_CMD);
+ outb(rw, hwif->dma_base + ATA_DMA_CMD);
/* read DMA status for INTR & ERROR flags */
dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
@@ -222,13 +215,12 @@ int ide_dma_setup(ide_drive_t *drive)
/* clear INTR & ERROR flags */
ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
- drive->waiting_for_dma = 1;
return 0;
}
EXPORT_SYMBOL_GPL(ide_dma_setup);
/**
- * dma_timer_expiry - handle a DMA timeout
+ * ide_dma_sff_timer_expiry - handle a DMA timeout
* @drive: Drive that timed out
*
* An IDE DMA transfer timed out. In the event of an error we ask
@@ -241,7 +233,7 @@ EXPORT_SYMBOL_GPL(ide_dma_setup);
* This can occur if an interrupt is lost or due to hang or bugs.
*/
-static int dma_timer_expiry(ide_drive_t *drive)
+int ide_dma_sff_timer_expiry(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
@@ -265,14 +257,7 @@ static int dma_timer_expiry(ide_drive_t *drive)
return 0; /* Status is unknown -- reset the bus */
}
-
-void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
- /* issue cmd to drive */
- ide_execute_command(drive, command, &ide_dma_intr, 2 * WAIT_CMD,
- dma_timer_expiry);
-}
-EXPORT_SYMBOL_GPL(ide_dma_exec_cmd);
+EXPORT_SYMBOL_GPL(ide_dma_sff_timer_expiry);
void ide_dma_start(ide_drive_t *drive)
{
@@ -303,8 +288,6 @@ int ide_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0, mask;
- drive->waiting_for_dma = 0;
-
/* stop DMA */
if (hwif->host_flags & IDE_HFLAG_MMIO) {
dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
@@ -321,8 +304,6 @@ int ide_dma_end(ide_drive_t *drive)
/* clear INTR & ERROR bits */
ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
wmb();
/* verify good DMA status */
@@ -346,12 +327,11 @@ EXPORT_SYMBOL_GPL(ide_dma_test_irq);
const struct ide_dma_ops sff_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
EXPORT_SYMBOL_GPL(sff_dma_ops);
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 059c90bb5ad2..a0b8cab1d9a6 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -89,16 +89,21 @@ static const struct drive_list_entry drive_blacklist[] = {
ide_startstop_t ide_dma_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd *cmd = &hwif->cmd;
u8 stat = 0, dma_stat = 0;
+ drive->waiting_for_dma = 0;
dma_stat = hwif->dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
stat = hwif->tp_ops->read_status(hwif);
if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) {
if (!dma_stat) {
- struct request *rq = hwif->rq;
-
- task_end_request(drive, rq, stat);
+ if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
+ ide_finish_cmd(drive, cmd, stat);
+ else
+ ide_complete_rq(drive, 0,
+ cmd->rq->nr_sectors << 9);
return ide_stopped;
}
printk(KERN_ERR "%s: %s: bad DMA status (0x%02x)\n",
@@ -106,7 +111,6 @@ ide_startstop_t ide_dma_intr(ide_drive_t *drive)
}
return ide_error(drive, "dma_intr", stat);
}
-EXPORT_SYMBOL_GPL(ide_dma_intr);
int ide_dma_good_drive(ide_drive_t *drive)
{
@@ -114,9 +118,9 @@ int ide_dma_good_drive(ide_drive_t *drive)
}
/**
- * ide_build_sglist - map IDE scatter gather for DMA I/O
- * @drive: the drive to build the DMA table for
- * @rq: the request holding the sg list
+ * ide_dma_map_sg - map IDE scatter gather for DMA I/O
+ * @drive: the drive to map the DMA table for
+ * @cmd: command
*
* Perform the DMA mapping magic necessary to access the source or
* target buffers of a request via DMA. The lower layers of the
@@ -124,31 +128,28 @@ int ide_dma_good_drive(ide_drive_t *drive)
* operate in a portable fashion.
*/
-int ide_build_sglist(ide_drive_t *drive, struct request *rq)
+static int ide_dma_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
int i;
- ide_map_sg(drive, rq);
-
- if (rq_data_dir(rq) == READ)
- hwif->sg_dma_direction = DMA_FROM_DEVICE;
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
+ cmd->sg_dma_direction = DMA_TO_DEVICE;
else
- hwif->sg_dma_direction = DMA_TO_DEVICE;
+ cmd->sg_dma_direction = DMA_FROM_DEVICE;
- i = dma_map_sg(hwif->dev, sg, hwif->sg_nents, hwif->sg_dma_direction);
+ i = dma_map_sg(hwif->dev, sg, cmd->sg_nents, cmd->sg_dma_direction);
if (i) {
- hwif->orig_sg_nents = hwif->sg_nents;
- hwif->sg_nents = i;
+ cmd->orig_sg_nents = cmd->sg_nents;
+ cmd->sg_nents = i;
}
return i;
}
-EXPORT_SYMBOL_GPL(ide_build_sglist);
/**
- * ide_destroy_dmatable - clean up DMA mapping
+ * ide_dma_unmap_sg - clean up DMA mapping
* @drive: The drive to unmap
*
* Teardown mappings after DMA has completed. This must be called
@@ -158,14 +159,14 @@ EXPORT_SYMBOL_GPL(ide_build_sglist);
* time.
*/
-void ide_destroy_dmatable(ide_drive_t *drive)
+void ide_dma_unmap_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
- dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->orig_sg_nents,
- hwif->sg_dma_direction);
+ dma_unmap_sg(hwif->dev, hwif->sg_table, cmd->orig_sg_nents,
+ cmd->sg_dma_direction);
}
-EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
+EXPORT_SYMBOL_GPL(ide_dma_unmap_sg);
/**
* ide_dma_off_quietly - Generic DMA kill
@@ -244,12 +245,11 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
case XFER_UDMA_0:
if ((id[ATA_ID_FIELD_VALID] & 4) == 0)
break;
-
+ mask = id[ATA_ID_UDMA_MODES];
if (port_ops && port_ops->udma_filter)
- mask = port_ops->udma_filter(drive);
+ mask &= port_ops->udma_filter(drive);
else
- mask = hwif->ultra_mask;
- mask &= id[ATA_ID_UDMA_MODES];
+ mask &= hwif->ultra_mask;
/*
* avoid false cable warning from eighty_ninty_three()
@@ -260,18 +260,23 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
}
break;
case XFER_MW_DMA_0:
- if ((id[ATA_ID_FIELD_VALID] & 2) == 0)
- break;
+ mask = id[ATA_ID_MWDMA_MODES];
+
+ /* Also look for the CF specific MWDMA modes... */
+ if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 0x38)) {
+ u8 mode = ((id[ATA_ID_CFA_MODES] & 0x38) >> 3) - 1;
+
+ mask |= ((2 << mode) - 1) << 3;
+ }
+
if (port_ops && port_ops->mdma_filter)
- mask = port_ops->mdma_filter(drive);
+ mask &= port_ops->mdma_filter(drive);
else
- mask = hwif->mwdma_mask;
- mask &= id[ATA_ID_MWDMA_MODES];
+ mask &= hwif->mwdma_mask;
break;
case XFER_SW_DMA_0:
- if (id[ATA_ID_FIELD_VALID] & 2) {
- mask = id[ATA_ID_SWDMA_MODES] & hwif->swdma_mask;
- } else if (id[ATA_ID_OLD_DMA_MODES] >> 8) {
+ mask = id[ATA_ID_SWDMA_MODES];
+ if (!(mask & ATA_SWDMA2) && (id[ATA_ID_OLD_DMA_MODES] >> 8)) {
u8 mode = id[ATA_ID_OLD_DMA_MODES] >> 8;
/*
@@ -279,8 +284,9 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
* (the maximum allowed mode is XFER_SW_DMA_2)
*/
if (mode <= 2)
- mask = ((2 << mode) - 1) & hwif->swdma_mask;
+ mask = (2 << mode) - 1;
}
+ mask &= hwif->swdma_mask;
break;
default:
BUG();
@@ -397,11 +403,10 @@ int ide_id_dma_bug(ide_drive_t *drive)
if ((id[ATA_ID_UDMA_MODES] >> 8) &&
(id[ATA_ID_MWDMA_MODES] >> 8))
goto err_out;
- } else if (id[ATA_ID_FIELD_VALID] & 2) {
- if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
- (id[ATA_ID_SWDMA_MODES] >> 8))
- goto err_out;
- }
+ } else if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
+ (id[ATA_ID_SWDMA_MODES] >> 8))
+ goto err_out;
+
return 0;
err_out:
printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name);
@@ -455,20 +460,75 @@ void ide_dma_lost_irq(ide_drive_t *drive)
}
EXPORT_SYMBOL_GPL(ide_dma_lost_irq);
-void ide_dma_timeout(ide_drive_t *drive)
+/*
+ * un-busy the port etc, and clear any pending DMA status. we want to
+ * retry the current request in pio mode instead of risking tossing it
+ * all away
+ */
+ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
{
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_dma_ops *dma_ops = hwif->dma_ops;
+ struct ide_cmd *cmd = &hwif->cmd;
+ struct request *rq;
+ ide_startstop_t ret = ide_stopped;
+
+ /*
+ * end current dma transaction
+ */
- printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
+ if (error < 0) {
+ printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
+ drive->waiting_for_dma = 0;
+ (void)dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
+ ret = ide_error(drive, "dma timeout error",
+ hwif->tp_ops->read_status(hwif));
+ } else {
+ printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
+ if (dma_ops->dma_clear)
+ dma_ops->dma_clear(drive);
+ printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
+ if (dma_ops->dma_test_irq(drive) == 0) {
+ ide_dump_status(drive, "DMA timeout",
+ hwif->tp_ops->read_status(hwif));
+ drive->waiting_for_dma = 0;
+ (void)dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
+ }
+ }
+
+ /*
+ * disable dma for now, but remember that we did so because of
+ * a timeout -- we'll reenable after we finish this next request
+ * (or rather the first chunk of it) in pio.
+ */
+ drive->dev_flags |= IDE_DFLAG_DMA_PIO_RETRY;
+ drive->retry_pio++;
+ ide_dma_off_quietly(drive);
+
+ /*
+ * un-busy drive etc and make sure request is sane
+ */
+
+ rq = hwif->rq;
+ if (!rq)
+ goto out;
- if (hwif->dma_ops->dma_test_irq(drive))
- return;
+ hwif->rq = NULL;
- ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif));
+ rq->errors = 0;
- hwif->dma_ops->dma_end(drive);
+ if (!rq->bio)
+ goto out;
+
+ rq->sector = rq->bio->bi_sector;
+ rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
+ rq->hard_cur_sectors = rq->current_nr_sectors;
+ rq->buffer = bio_data(rq->bio);
+out:
+ return ret;
}
-EXPORT_SYMBOL_GPL(ide_dma_timeout);
void ide_release_dma_engine(ide_hwif_t *hwif)
{
@@ -505,3 +565,25 @@ int ide_allocate_dma_engine(ide_hwif_t *hwif)
return 0;
}
EXPORT_SYMBOL_GPL(ide_allocate_dma_engine);
+
+int ide_dma_prepare(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+ const struct ide_dma_ops *dma_ops = drive->hwif->dma_ops;
+
+ if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
+ (dma_ops->dma_check && dma_ops->dma_check(drive, cmd)))
+ goto out;
+ ide_map_sg(drive, cmd);
+ if (ide_dma_map_sg(drive, cmd) == 0)
+ goto out_map;
+ if (dma_ops->dma_setup(drive, cmd))
+ goto out_dma_unmap;
+ drive->waiting_for_dma = 1;
+ return 0;
+out_dma_unmap:
+ ide_dma_unmap_sg(drive, cmd);
+out_map:
+ ide_map_sg(drive, cmd);
+out:
+ return 1;
+}
diff --git a/drivers/ide/ide-eh.c b/drivers/ide/ide-eh.c
new file mode 100644
index 000000000000..5d5fb961b5ce
--- /dev/null
+++ b/drivers/ide/ide-eh.c
@@ -0,0 +1,440 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+#include <linux/delay.h>
+
+static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq,
+ u8 stat, u8 err)
+{
+ ide_hwif_t *hwif = drive->hwif;
+
+ if ((stat & ATA_BUSY) ||
+ ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
+ /* other bits are useless when BUSY */
+ rq->errors |= ERROR_RESET;
+ } else if (stat & ATA_ERR) {
+ /* err has different meaning on cdrom and tape */
+ if (err == ATA_ABORTED) {
+ if ((drive->dev_flags & IDE_DFLAG_LBA) &&
+ /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */
+ hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS)
+ return ide_stopped;
+ } else if ((err & BAD_CRC) == BAD_CRC) {
+ /* UDMA crc error, just retry the operation */
+ drive->crc_count++;
+ } else if (err & (ATA_BBK | ATA_UNC)) {
+ /* retries won't help these */
+ rq->errors = ERROR_MAX;
+ } else if (err & ATA_TRK0NF) {
+ /* help it find track zero */
+ rq->errors |= ERROR_RECAL;
+ }
+ }
+
+ if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ &&
+ (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) {
+ int nsect = drive->mult_count ? drive->mult_count : 1;
+
+ ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE);
+ }
+
+ if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
+ ide_kill_rq(drive, rq);
+ return ide_stopped;
+ }
+
+ if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
+ rq->errors |= ERROR_RESET;
+
+ if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+ ++rq->errors;
+ return ide_do_reset(drive);
+ }
+
+ if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
+ drive->special.b.recalibrate = 1;
+
+ ++rq->errors;
+
+ return ide_stopped;
+}
+
+static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq,
+ u8 stat, u8 err)
+{
+ ide_hwif_t *hwif = drive->hwif;
+
+ if ((stat & ATA_BUSY) ||
+ ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
+ /* other bits are useless when BUSY */
+ rq->errors |= ERROR_RESET;
+ } else {
+ /* add decoding error stuff */
+ }
+
+ if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
+ /* force an abort */
+ hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);
+
+ if (rq->errors >= ERROR_MAX) {
+ ide_kill_rq(drive, rq);
+ } else {
+ if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
+ ++rq->errors;
+ return ide_do_reset(drive);
+ }
+ ++rq->errors;
+ }
+
+ return ide_stopped;
+}
+
+static ide_startstop_t __ide_error(ide_drive_t *drive, struct request *rq,
+ u8 stat, u8 err)
+{
+ if (drive->media == ide_disk)
+ return ide_ata_error(drive, rq, stat, err);
+ return ide_atapi_error(drive, rq, stat, err);
+}
+
+/**
+ * ide_error - handle an error on the IDE
+ * @drive: drive the error occurred on
+ * @msg: message to report
+ * @stat: status bits
+ *
+ * ide_error() takes action based on the error returned by the drive.
+ * For normal I/O that may well include retries. We deal with
+ * both new-style (taskfile) and old style command handling here.
+ * In the case of taskfile command handling there is work left to
+ * do
+ */
+
+ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat)
+{
+ struct request *rq;
+ u8 err;
+
+ err = ide_dump_status(drive, msg, stat);
+
+ rq = drive->hwif->rq;
+ if (rq == NULL)
+ return ide_stopped;
+
+ /* retry only "normal" I/O: */
+ if (!blk_fs_request(rq)) {
+ if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
+ struct ide_cmd *cmd = rq->special;
+
+ if (cmd)
+ ide_complete_cmd(drive, cmd, stat, err);
+ } else if (blk_pm_request(rq)) {
+ rq->errors = 1;
+ ide_complete_pm_rq(drive, rq);
+ return ide_stopped;
+ }
+ rq->errors = err;
+ ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
+ return ide_stopped;
+ }
+
+ return __ide_error(drive, rq, stat, err);
+}
+EXPORT_SYMBOL_GPL(ide_error);
+
+static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
+{
+ struct request *rq = drive->hwif->rq;
+
+ if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) {
+ if (err <= 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, err ? err : 0, ide_rq_bytes(rq));
+ }
+}
+
+/* needed below */
+static ide_startstop_t do_reset1(ide_drive_t *, int);
+
+/*
+ * atapi_reset_pollfunc() gets invoked to poll the interface for completion
+ * every 50ms during an atapi drive reset operation. If the drive has not yet
+ * responded, and we have not yet hit our maximum waiting time, then the timer
+ * is restarted for another 50ms.
+ */
+static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+ u8 stat;
+
+ tp_ops->dev_select(drive);
+ udelay(10);
+ stat = tp_ops->read_status(hwif);
+
+ if (OK_STAT(stat, 0, ATA_BUSY))
+ printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name);
+ else {
+ if (time_before(jiffies, hwif->poll_timeout)) {
+ ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20);
+ /* continue polling */
+ return ide_started;
+ }
+ /* end of polling */
+ hwif->polling = 0;
+ printk(KERN_ERR "%s: ATAPI reset timed-out, status=0x%02x\n",
+ drive->name, stat);
+ /* do it the old fashioned way */
+ return do_reset1(drive, 1);
+ }
+ /* done polling */
+ hwif->polling = 0;
+ ide_complete_drive_reset(drive, 0);
+ return ide_stopped;
+}
+
+static void ide_reset_report_error(ide_hwif_t *hwif, u8 err)
+{
+ static const char *err_master_vals[] =
+ { NULL, "passed", "formatter device error",
+ "sector buffer error", "ECC circuitry error",
+ "controlling MPU error" };
+
+ u8 err_master = err & 0x7f;
+
+ printk(KERN_ERR "%s: reset: master: ", hwif->name);
+ if (err_master && err_master < 6)
+ printk(KERN_CONT "%s", err_master_vals[err_master]);
+ else
+ printk(KERN_CONT "error (0x%02x?)", err);
+ if (err & 0x80)
+ printk(KERN_CONT "; slave: failed");
+ printk(KERN_CONT "\n");
+}
+
+/*
+ * reset_pollfunc() gets invoked to poll the interface for completion every 50ms
+ * during an ide reset operation. If the drives have not yet responded,
+ * and we have not yet hit our maximum waiting time, then the timer is restarted
+ * for another 50ms.
+ */
+static ide_startstop_t reset_pollfunc(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+ u8 tmp;
+ int err = 0;
+
+ if (port_ops && port_ops->reset_poll) {
+ err = port_ops->reset_poll(drive);
+ if (err) {
+ printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
+ hwif->name, drive->name);
+ goto out;
+ }
+ }
+
+ tmp = hwif->tp_ops->read_status(hwif);
+
+ if (!OK_STAT(tmp, 0, ATA_BUSY)) {
+ if (time_before(jiffies, hwif->poll_timeout)) {
+ ide_set_handler(drive, &reset_pollfunc, HZ/20);
+ /* continue polling */
+ return ide_started;
+ }
+ printk(KERN_ERR "%s: reset timed-out, status=0x%02x\n",
+ hwif->name, tmp);
+ drive->failures++;
+ err = -EIO;
+ } else {
+ tmp = ide_read_error(drive);
+
+ if (tmp == 1) {
+ printk(KERN_INFO "%s: reset: success\n", hwif->name);
+ drive->failures = 0;
+ } else {
+ ide_reset_report_error(hwif, tmp);
+ drive->failures++;
+ err = -EIO;
+ }
+ }
+out:
+ hwif->polling = 0; /* done polling */
+ ide_complete_drive_reset(drive, err);
+ return ide_stopped;
+}
+
+static void ide_disk_pre_reset(ide_drive_t *drive)
+{
+ int legacy = (drive->id[ATA_ID_CFS_ENABLE_2] & 0x0400) ? 0 : 1;
+
+ drive->special.all = 0;
+ drive->special.b.set_geometry = legacy;
+ drive->special.b.recalibrate = legacy;
+
+ drive->mult_count = 0;
+ drive->dev_flags &= ~IDE_DFLAG_PARKED;
+
+ if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 &&
+ (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0)
+ drive->mult_req = 0;
+
+ if (drive->mult_req != drive->mult_count)
+ drive->special.b.set_multmode = 1;
+}
+
+static void pre_reset(ide_drive_t *drive)
+{
+ const struct ide_port_ops *port_ops = drive->hwif->port_ops;
+
+ if (drive->media == ide_disk)
+ ide_disk_pre_reset(drive);
+ else
+ drive->dev_flags |= IDE_DFLAG_POST_RESET;
+
+ if (drive->dev_flags & IDE_DFLAG_USING_DMA) {
+ if (drive->crc_count)
+ ide_check_dma_crc(drive);
+ else
+ ide_dma_off(drive);
+ }
+
+ if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) {
+ if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) {
+ drive->dev_flags &= ~IDE_DFLAG_UNMASK;
+ drive->io_32bit = 0;
+ }
+ return;
+ }
+
+ if (port_ops && port_ops->pre_reset)
+ port_ops->pre_reset(drive);
+
+ if (drive->current_speed != 0xff)
+ drive->desired_speed = drive->current_speed;
+ drive->current_speed = 0xff;
+}
+
+/*
+ * do_reset1() attempts to recover a confused drive by resetting it.
+ * Unfortunately, resetting a disk drive actually resets all devices on
+ * the same interface, so it can really be thought of as resetting the
+ * interface rather than resetting the drive.
+ *
+ * ATAPI devices have their own reset mechanism which allows them to be
+ * individually reset without clobbering other devices on the same interface.
+ *
+ * Unfortunately, the IDE interface does not generate an interrupt to let
+ * us know when the reset operation has finished, so we must poll for this.
+ * Equally poor, though, is the fact that this may a very long time to complete,
+ * (up to 30 seconds worstcase). So, instead of busy-waiting here for it,
+ * we set a timer to poll at 50ms intervals.
+ */
+static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+ const struct ide_port_ops *port_ops;
+ ide_drive_t *tdrive;
+ unsigned long flags, timeout;
+ int i;
+ DEFINE_WAIT(wait);
+
+ spin_lock_irqsave(&hwif->lock, flags);
+
+ /* We must not reset with running handlers */
+ BUG_ON(hwif->handler != NULL);
+
+ /* For an ATAPI device, first try an ATAPI SRST. */
+ if (drive->media != ide_disk && !do_not_try_atapi) {
+ pre_reset(drive);
+ tp_ops->dev_select(drive);
+ udelay(20);
+ tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
+ ndelay(400);
+ hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
+ hwif->polling = 1;
+ __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20);
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ return ide_started;
+ }
+
+ /* We must not disturb devices in the IDE_DFLAG_PARKED state. */
+ do {
+ unsigned long now;
+
+ prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE);
+ timeout = jiffies;
+ ide_port_for_each_present_dev(i, tdrive, hwif) {
+ if ((tdrive->dev_flags & IDE_DFLAG_PARKED) &&
+ time_after(tdrive->sleep, timeout))
+ timeout = tdrive->sleep;
+ }
+
+ now = jiffies;
+ if (time_before_eq(timeout, now))
+ break;
+
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ timeout = schedule_timeout_uninterruptible(timeout - now);
+ spin_lock_irqsave(&hwif->lock, flags);
+ } while (timeout);
+ finish_wait(&ide_park_wq, &wait);
+
+ /*
+ * First, reset any device state data we were maintaining
+ * for any of the drives on this interface.
+ */
+ ide_port_for_each_dev(i, tdrive, hwif)
+ pre_reset(tdrive);
+
+ if (io_ports->ctl_addr == 0) {
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ ide_complete_drive_reset(drive, -ENXIO);
+ return ide_stopped;
+ }
+
+ /*
+ * Note that we also set nIEN while resetting the device,
+ * to mask unwanted interrupts from the interface during the reset.
+ * However, due to the design of PC hardware, this will cause an
+ * immediate interrupt due to the edge transition it produces.
+ * This single interrupt gives us a "fast poll" for drives that
+ * recover from reset very quickly, saving us the first 50ms wait time.
+ */
+ /* set SRST and nIEN */
+ tp_ops->write_devctl(hwif, ATA_SRST | ATA_NIEN | ATA_DEVCTL_OBS);
+ /* more than enough time */
+ udelay(10);
+ /* clear SRST, leave nIEN (unless device is on the quirk list) */
+ tp_ops->write_devctl(hwif, (drive->quirk_list == 2 ? 0 : ATA_NIEN) |
+ ATA_DEVCTL_OBS);
+ /* more than enough time */
+ udelay(10);
+ hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
+ hwif->polling = 1;
+ __ide_set_handler(drive, &reset_pollfunc, HZ/20);
+
+ /*
+ * Some weird controller like resetting themselves to a strange
+ * state when the disks are reset this way. At least, the Winbond
+ * 553 documentation says that
+ */
+ port_ops = hwif->port_ops;
+ if (port_ops && port_ops->resetproc)
+ port_ops->resetproc(drive);
+
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ return ide_started;
+}
+
+/*
+ * ide_do_reset() is the entry point to the drive/interface reset code.
+ */
+
+ide_startstop_t ide_do_reset(ide_drive_t *drive)
+{
+ return do_reset1(drive, 0);
+}
+EXPORT_SYMBOL(ide_do_reset);
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 317ec62c33d4..2b4868d95f8b 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -61,73 +61,20 @@
*/
#define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */
-/* Error code returned in rq->errors to the higher part of the driver. */
-#define IDEFLOPPY_ERROR_GENERAL 101
-
-/*
- * Used to finish servicing a request. For read/write requests, we will call
- * ide_end_request to pass to the next buffer.
- */
-static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
-{
- struct ide_disk_obj *floppy = drive->driver_data;
- struct request *rq = drive->hwif->rq;
- int error;
-
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
- switch (uptodate) {
- case 0:
- error = IDEFLOPPY_ERROR_GENERAL;
- break;
-
- case 1:
- error = 0;
- break;
-
- default:
- error = uptodate;
- }
-
- if (error)
- floppy->failed_pc = NULL;
- /* Why does this happen? */
- if (!rq)
- return 0;
- if (!blk_special_request(rq)) {
- /* our real local end request function */
- ide_end_request(drive, uptodate, nsecs);
- return 0;
- }
- rq->errors = error;
- /* fixme: need to move this local also */
- ide_end_drive_cmd(drive, 0, 0);
- return 0;
-}
-
-static void idefloppy_update_buffers(ide_drive_t *drive,
- struct ide_atapi_pc *pc)
-{
- struct request *rq = pc->rq;
- struct bio *bio = rq->bio;
-
- while ((bio = rq->bio) != NULL)
- ide_floppy_end_request(drive, 1, 0);
-}
-
-static void ide_floppy_callback(ide_drive_t *drive, int dsc)
+static int ide_floppy_callback(ide_drive_t *drive, int dsc)
{
struct ide_disk_obj *floppy = drive->driver_data;
struct ide_atapi_pc *pc = drive->pc;
+ struct request *rq = pc->rq;
int uptodate = pc->error ? 0 : 1;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
- if (floppy->failed_pc == pc)
- floppy->failed_pc = NULL;
+ if (drive->failed_pc == pc)
+ drive->failed_pc = NULL;
if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 ||
- (pc->rq && blk_pc_request(pc->rq)))
+ (rq && blk_pc_request(rq)))
uptodate = 1; /* FIXME */
else if (pc->c[0] == GPCMD_REQUEST_SENSE) {
u8 *buf = pc->buf;
@@ -139,19 +86,22 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc)
floppy->progress_indication = buf[15] & 0x80 ?
(u16)get_unaligned((u16 *)&buf[16]) : 0x10000;
- if (floppy->failed_pc)
- ide_debug_log(IDE_DBG_PC, "pc = %x, ",
- floppy->failed_pc->c[0]);
+ if (drive->failed_pc)
+ ide_debug_log(IDE_DBG_PC, "pc = %x",
+ drive->failed_pc->c[0]);
ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x,"
- "ascq = %x\n", floppy->sense_key,
+ "ascq = %x", floppy->sense_key,
floppy->asc, floppy->ascq);
} else
printk(KERN_ERR PFX "Error in REQUEST SENSE itself - "
"Aborting request!\n");
}
- ide_floppy_end_request(drive, uptodate, 0);
+ if (blk_special_request(rq))
+ rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
+
+ return uptodate;
}
static void ide_floppy_report_error(struct ide_disk_obj *floppy,
@@ -170,14 +120,15 @@ static void ide_floppy_report_error(struct ide_disk_obj *floppy,
}
-static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
- struct ide_atapi_pc *pc)
+static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive,
+ struct ide_cmd *cmd,
+ struct ide_atapi_pc *pc)
{
struct ide_disk_obj *floppy = drive->driver_data;
- if (floppy->failed_pc == NULL &&
+ if (drive->failed_pc == NULL &&
pc->c[0] != GPCMD_REQUEST_SENSE)
- floppy->failed_pc = pc;
+ drive->failed_pc = pc;
/* Set the current packet command */
drive->pc = pc;
@@ -186,18 +137,18 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR))
ide_floppy_report_error(floppy, pc);
/* Giving up */
- pc->error = IDEFLOPPY_ERROR_GENERAL;
+ pc->error = IDE_DRV_ERROR_GENERAL;
- floppy->failed_pc = NULL;
+ drive->failed_pc = NULL;
drive->pc_callback(drive, 0);
return ide_stopped;
}
- ide_debug_log(IDE_DBG_FUNC, "%s: Retry #%d\n", __func__, pc->retries);
+ ide_debug_log(IDE_DBG_FUNC, "retry #%d", pc->retries);
pc->retries++;
- return ide_issue_pc(drive);
+ return ide_issue_pc(drive, cmd);
}
void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
@@ -242,8 +193,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
int blocks = rq->nr_sectors / floppy->bs_factor;
int cmd = rq_data_dir(rq);
- ide_debug_log(IDE_DBG_FUNC, "%s: block: %d, blocks: %d\n", __func__,
- block, blocks);
+ ide_debug_log(IDE_DBG_FUNC, "block: %d, blocks: %d", block, blocks);
ide_init_pc(pc);
pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10;
@@ -253,7 +203,6 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
memcpy(rq->cmd, pc->c, 12);
pc->rq = rq;
- pc->b_count = 0;
if (rq->cmd_flags & REQ_RW)
pc->flags |= PC_FLAG_WRITING;
pc->buf = NULL;
@@ -267,7 +216,6 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy,
ide_init_pc(pc);
memcpy(pc->c, rq->cmd, sizeof(pc->c));
pc->rq = rq;
- pc->b_count = 0;
if (rq->data_len && rq_data_dir(rq) == WRITE)
pc->flags |= PC_FLAG_WRITING;
pc->buf = rq->data;
@@ -284,35 +232,36 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
struct request *rq, sector_t block)
{
struct ide_disk_obj *floppy = drive->driver_data;
- ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd cmd;
struct ide_atapi_pc *pc;
- ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, "
- "errors: %d\n",
- __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?",
- rq->cmd[0], rq->cmd_type, rq->errors);
+ ide_debug_log(IDE_DBG_FUNC, "enter, cmd: 0x%x\n", rq->cmd[0]);
- ide_debug_log(IDE_DBG_FUNC, "%s: sector: %ld, nr_sectors: %ld, "
- "current_nr_sectors: %d\n",
- __func__, (long)rq->sector, rq->nr_sectors,
- rq->current_nr_sectors);
+ if (drive->debug_mask & IDE_DBG_RQ)
+ blk_dump_rq_flags(rq, (rq->rq_disk
+ ? rq->rq_disk->disk_name
+ : "dev?"));
if (rq->errors >= ERROR_MAX) {
- if (floppy->failed_pc)
- ide_floppy_report_error(floppy, floppy->failed_pc);
- else
+ if (drive->failed_pc) {
+ ide_floppy_report_error(floppy, drive->failed_pc);
+ drive->failed_pc = NULL;
+ } else
printk(KERN_ERR PFX "%s: I/O error\n", drive->name);
- ide_floppy_end_request(drive, 0, 0);
- return ide_stopped;
+ if (blk_special_request(rq)) {
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
+ return ide_stopped;
+ } else
+ goto out_end;
}
if (blk_fs_request(rq)) {
if (((long)rq->sector % floppy->bs_factor) ||
(rq->nr_sectors % floppy->bs_factor)) {
printk(KERN_ERR PFX "%s: unsupported r/w rq size\n",
drive->name);
- ide_floppy_end_request(drive, 0, 0);
- return ide_stopped;
+ goto out_end;
}
pc = &floppy->queued_pc;
idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
@@ -323,21 +272,30 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
idefloppy_blockpc_cmd(floppy, pc, rq);
} else {
blk_dump_rq_flags(rq, PFX "unsupported command in queue");
- ide_floppy_end_request(drive, 0, 0);
- return ide_stopped;
+ goto out_end;
}
+ memset(&cmd, 0, sizeof(cmd));
+
+ if (rq_data_dir(rq))
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+ cmd.rq = rq;
+
if (blk_fs_request(rq) || pc->req_xfer) {
- ide_init_sg_cmd(drive, rq);
- ide_map_sg(drive, rq);
+ ide_init_sg_cmd(&cmd, pc->req_xfer);
+ ide_map_sg(drive, &cmd);
}
- pc->sg = hwif->sg_table;
- pc->sg_cnt = hwif->sg_nents;
-
pc->rq = rq;
- return idefloppy_issue_pc(drive, pc);
+ return ide_floppy_issue_pc(drive, &cmd, pc);
+out_end:
+ drive->failed_pc = NULL;
+ if (blk_fs_request(rq) == 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
+ return ide_stopped;
}
/*
@@ -413,9 +371,11 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
struct gendisk *disk = floppy->disk;
struct ide_atapi_pc pc;
u8 *cap_desc;
- u8 header_len, desc_cnt;
+ u8 pc_buf[256], header_len, desc_cnt;
int i, rc = 1, blocks, length;
+ ide_debug_log(IDE_DBG_FUNC, "enter");
+
drive->bios_cyl = 0;
drive->bios_head = drive->bios_sect = 0;
floppy->blocks = 0;
@@ -423,6 +383,9 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
drive->capacity64 = 0;
ide_floppy_create_read_capacity_cmd(&pc);
+ pc.buf = &pc_buf[0];
+ pc.buf_size = sizeof(pc_buf);
+
if (ide_queue_pc_tail(drive, disk, &pc)) {
printk(KERN_ERR PFX "Can't get floppy parameters\n");
return 1;
@@ -438,8 +401,9 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, "
- "%d sector size\n",
- i, blocks * length / 1024, blocks, length);
+ "%d sector size",
+ i, blocks * length / 1024,
+ blocks, length);
if (i)
continue;
@@ -495,8 +459,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
"in drive\n", drive->name);
break;
}
- ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d\n",
- pc.buf[desc_start + 4] & 0x03);
+ ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d",
+ pc.buf[desc_start + 4] & 0x03);
}
/* Clik! disk does not support get_flexible_disk_page */
@@ -512,8 +476,6 @@ static void ide_floppy_setup(ide_drive_t *drive)
u16 *id = drive->id;
drive->pc_callback = ide_floppy_callback;
- drive->pc_update_buffers = idefloppy_update_buffers;
- drive->pc_io_buffers = ide_io_buffers;
/*
* We used to check revisions here. At this point however I'm giving up.
@@ -575,6 +537,5 @@ const struct ide_disk_ops ide_atapi_disk_ops = {
.init_media = ide_floppy_init_media,
.set_doorlock = ide_set_media_lock,
.do_request = ide_floppy_do_request,
- .end_request = ide_floppy_end_request,
.ioctl = ide_floppy_ioctl,
};
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c
index 8f8be8546038..cd8a42027ede 100644
--- a/drivers/ide/ide-floppy_ioctl.c
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -36,9 +36,9 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
int __user *arg)
{
struct ide_disk_obj *floppy = drive->driver_data;
- u8 header_len, desc_cnt;
int i, blocks, length, u_array_size, u_index;
int __user *argp;
+ u8 pc_buf[256], header_len, desc_cnt;
if (get_user(u_array_size, arg))
return -EFAULT;
@@ -47,6 +47,9 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
return -EINVAL;
ide_floppy_create_read_capacity_cmd(pc);
+ pc->buf = &pc_buf[0];
+ pc->buf_size = sizeof(pc_buf);
+
if (ide_queue_pc_tail(drive, floppy->disk, pc)) {
printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
return -EIO;
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index 047109419902..1aebdf1a4f58 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -145,11 +145,6 @@ static ide_startstop_t ide_gd_do_request(ide_drive_t *drive,
return drive->disk_ops->do_request(drive, rq, sector);
}
-static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs)
-{
- return drive->disk_ops->end_request(drive, uptodate, nrsecs);
-}
-
static struct ide_driver ide_gd_driver = {
.gen_driver = {
.owner = THIS_MODULE,
@@ -162,7 +157,6 @@ static struct ide_driver ide_gd_driver = {
.shutdown = ide_gd_shutdown,
.version = IDE_GD_VERSION,
.do_request = ide_gd_do_request,
- .end_request = ide_gd_end_request,
#ifdef CONFIG_IDE_PROC_FS
.proc_entries = ide_disk_proc_entries,
.proc_devsets = ide_disk_proc_devsets,
@@ -182,7 +176,7 @@ static int ide_gd_open(struct block_device *bdev, fmode_t mode)
drive = idkp->drive;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
idkp->openers++;
@@ -232,7 +226,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode)
struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
if (idkp->openers == 1)
drive->disk_ops->flush(drive);
diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h
index b604bdd318a1..55970772bd04 100644
--- a/drivers/ide/ide-gd.h
+++ b/drivers/ide/ide-gd.h
@@ -8,7 +8,7 @@
#define IDE_GD_DEBUG_LOG 0
#if IDE_GD_DEBUG_LOG
-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args)
#else
#define ide_debug_log(lvl, fmt, args...) do {} while (0)
#endif
@@ -20,8 +20,6 @@ struct ide_disk_obj {
struct device dev;
unsigned int openers; /* protected by BKL for now */
- /* Last failed packet command */
- struct ide_atapi_pc *failed_pc;
/* used for blk_{fs,pc}_request() requests */
struct ide_atapi_pc queued_pc;
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
index 81a5282ce1eb..7812ca0be13b 100644
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -1,27 +1,22 @@
/*
* generic/default IDE host driver
*
- * Copyright (C) 2004, 2008 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2004, 2008-2009 Bartlomiej Zolnierkiewicz
* This code was split off from ide.c. See it for original copyrights.
*
* May be copied or modified under the terms of the GNU General Public License.
*/
-/*
- * For special cases new interfaces may be added using sysfs, i.e.
- *
- * echo -n "0x168:0x36e:10" > /sys/class/ide_generic/add
- *
- * will add an interface using I/O ports 0x168-0x16f/0x36e and IRQ 10.
- */
-
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ide.h>
#include <linux/pci_ids.h>
-/* FIXME: convert m32r to use ide_platform host driver */
+/* FIXME: convert arm and m32r to use ide_platform host driver */
+#ifdef CONFIG_ARM
+#include <asm/irq.h>
+#endif
#ifdef CONFIG_M32R
#include <asm/m32r.h>
#endif
@@ -32,62 +27,15 @@ static int probe_mask;
module_param(probe_mask, int, 0);
MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports");
-static ssize_t store_add(struct class *cls, const char *buf, size_t n)
-{
- unsigned int base, ctl;
- int irq, rc;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
-
- if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3)
- return -EINVAL;
-
- memset(&hw, 0, sizeof(hw));
- ide_std_init_ports(&hw, base, ctl);
- hw.irq = irq;
- hw.chipset = ide_generic;
-
- rc = ide_host_add(NULL, hws, NULL);
- if (rc)
- return rc;
-
- return n;
-};
-
-static struct class_attribute ide_generic_class_attrs[] = {
- __ATTR(add, S_IWUSR, NULL, store_add),
- __ATTR_NULL
+static const struct ide_port_info ide_generic_port_info = {
+ .host_flags = IDE_HFLAG_NO_DMA,
};
-static void ide_generic_class_release(struct class *cls)
-{
- kfree(cls);
-}
-
-static int __init ide_generic_sysfs_init(void)
-{
- struct class *cls;
- int rc;
-
- cls = kzalloc(sizeof(*cls), GFP_KERNEL);
- if (!cls)
- return -ENOMEM;
-
- cls->name = DRV_NAME;
- cls->owner = THIS_MODULE;
- cls->class_release = ide_generic_class_release;
- cls->class_attrs = ide_generic_class_attrs;
-
- rc = class_register(cls);
- if (rc) {
- kfree(cls);
- return rc;
- }
-
- return 0;
-}
-
-#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) \
- || defined(CONFIG_PLAT_OPSPUT)
+#ifdef CONFIG_ARM
+static const u16 legacy_bases[] = { 0x1f0 };
+static const int legacy_irqs[] = { IRQ_HARDDISK };
+#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || \
+ defined(CONFIG_PLAT_OPSPUT)
static const u16 legacy_bases[] = { 0x1f0 };
static const int legacy_irqs[] = { PLD_IRQ_CFIREQ };
#elif defined(CONFIG_PLAT_MAPPI3)
@@ -103,11 +51,11 @@ static const int legacy_irqs[] = { 14, 15, 11, 10, 8, 12 };
static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
{
+#ifdef CONFIG_PCI
struct pci_dev *p = NULL;
u16 val;
for_each_pci_dev(p) {
-
if (pci_resource_start(p, 0) == 0x1f0)
*primary = 1;
if (pci_resource_start(p, 2) == 0x170)
@@ -122,7 +70,6 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
/* Intel MPIIX - PIO ATA on non PCI side of bridge */
if (p->vendor == PCI_VENDOR_ID_INTEL &&
p->device == PCI_DEVICE_ID_INTEL_82371MX) {
-
pci_read_config_word(p, 0x6C, &val);
if (val & 0x8000) {
/* ATA port enabled */
@@ -133,6 +80,7 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
}
}
}
+#endif
}
static int __init ide_generic_init(void)
@@ -164,6 +112,7 @@ static int __init ide_generic_init(void)
printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX "
"not free.\n",
DRV_NAME, io_addr, io_addr + 7);
+ rc = -EBUSY;
continue;
}
@@ -172,6 +121,7 @@ static int __init ide_generic_init(void)
"not free.\n",
DRV_NAME, io_addr + 0x206);
release_region(io_addr, 8);
+ rc = -EBUSY;
continue;
}
@@ -184,7 +134,7 @@ static int __init ide_generic_init(void)
#endif
hw.chipset = ide_generic;
- rc = ide_host_add(NULL, hws, NULL);
+ rc = ide_host_add(&ide_generic_port_info, hws, NULL);
if (rc) {
release_region(io_addr + 0x206, 1);
release_region(io_addr, 8);
@@ -192,10 +142,6 @@ static int __init ide_generic_init(void)
}
}
- if (ide_generic_sysfs_init())
- printk(KERN_ERR DRV_NAME ": failed to create ide_generic "
- "class\n");
-
return rc;
}
diff --git a/drivers/ide/ide-h8300.c b/drivers/ide/ide-h8300.c
index 9270d3255ee0..dac9a6d44963 100644
--- a/drivers/ide/ide-h8300.c
+++ b/drivers/ide/ide-h8300.c
@@ -44,88 +44,78 @@ static u16 mm_inw(unsigned long a)
return r;
}
-static void h8300_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void h8300_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA)
- mm_outw((tf->hob_data << 8) | tf->data, io_ports->data_addr);
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
outb((tf->device & HIHI) | drive->select,
io_ports->device_addr);
}
-static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data = mm_inw(io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
+ struct ide_taskfile *tf = &cmd->tf;
/* be sure we're looking at the low order bits */
- outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = inb(io_ports->lbah_addr);
}
}
@@ -143,13 +133,13 @@ static void mm_insw(unsigned long addr, void *buf, u32 len)
*bp = bswap(*(volatile u16 *)addr);
}
-static void h8300_input_data(ide_drive_t *drive, struct request *rq,
+static void h8300_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
mm_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
}
-static void h8300_output_data(ide_drive_t *drive, struct request *rq,
+static void h8300_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
@@ -159,9 +149,9 @@ static const struct ide_tp_ops h8300_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = h8300_tf_load,
.tf_read = h8300_tf_read,
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c
new file mode 100644
index 000000000000..9cac281d82c4
--- /dev/null
+++ b/drivers/ide/ide-io-std.c
@@ -0,0 +1,301 @@
+
+#include <linux/kernel.h>
+#include <linux/ide.h>
+
+#if defined(CONFIG_ARM) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) || \
+ defined(CONFIG_PARISC) || defined(CONFIG_PPC) || defined(CONFIG_SPARC)
+#include <asm/ide.h>
+#else
+#include <asm-generic/ide_iops.h>
+#endif
+
+/*
+ * Conventional PIO operations for ATA devices
+ */
+
+static u8 ide_inb(unsigned long port)
+{
+ return (u8) inb(port);
+}
+
+static void ide_outb(u8 val, unsigned long port)
+{
+ outb(val, port);
+}
+
+/*
+ * MMIO operations, typically used for SATA controllers
+ */
+
+static u8 ide_mm_inb(unsigned long port)
+{
+ return (u8) readb((void __iomem *) port);
+}
+
+static void ide_mm_outb(u8 value, unsigned long port)
+{
+ writeb(value, (void __iomem *) port);
+}
+
+void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
+{
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
+ else
+ outb(cmd, hwif->io_ports.command_addr);
+}
+EXPORT_SYMBOL_GPL(ide_exec_command);
+
+u8 ide_read_status(ide_hwif_t *hwif)
+{
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ return readb((void __iomem *)hwif->io_ports.status_addr);
+ else
+ return inb(hwif->io_ports.status_addr);
+}
+EXPORT_SYMBOL_GPL(ide_read_status);
+
+u8 ide_read_altstatus(ide_hwif_t *hwif)
+{
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ return readb((void __iomem *)hwif->io_ports.ctl_addr);
+ else
+ return inb(hwif->io_ports.ctl_addr);
+}
+EXPORT_SYMBOL_GPL(ide_read_altstatus);
+
+void ide_write_devctl(ide_hwif_t *hwif, u8 ctl)
+{
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
+ else
+ outb(ctl, hwif->io_ports.ctl_addr);
+}
+EXPORT_SYMBOL_GPL(ide_write_devctl);
+
+void ide_dev_select(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 select = drive->select | ATA_DEVICE_OBS;
+
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ writeb(select, (void __iomem *)hwif->io_ports.device_addr);
+ else
+ outb(select, hwif->io_ports.device_addr);
+}
+EXPORT_SYMBOL_GPL(ide_dev_select);
+
+void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ struct ide_taskfile *tf = &cmd->tf;
+ void (*tf_outb)(u8 addr, unsigned long port);
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+ u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+
+ if (mmio)
+ tf_outb = ide_mm_outb;
+ else
+ tf_outb = ide_outb;
+
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
+ HIHI = 0xFF;
+
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ tf_outb(tf->hob_feature, io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ tf_outb(tf->hob_nsect, io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ tf_outb(tf->hob_lbal, io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ tf_outb(tf->hob_lbam, io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ tf_outb(tf->hob_lbah, io_ports->lbah_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ tf_outb(tf->feature, io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
+ tf_outb(tf->nsect, io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
+ tf_outb(tf->lbal, io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
+ tf_outb(tf->lbam, io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
+ tf_outb(tf->lbah, io_ports->lbah_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ tf_outb((tf->device & HIHI) | drive->select,
+ io_ports->device_addr);
+}
+EXPORT_SYMBOL_GPL(ide_tf_load);
+
+void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ struct ide_taskfile *tf = &cmd->tf;
+ void (*tf_outb)(u8 addr, unsigned long port);
+ u8 (*tf_inb)(unsigned long port);
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+ if (mmio) {
+ tf_outb = ide_mm_outb;
+ tf_inb = ide_mm_inb;
+ } else {
+ tf_outb = ide_outb;
+ tf_inb = ide_inb;
+ }
+
+ /* be sure we're looking at the low order bits */
+ tf_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = tf_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
+ tf->nsect = tf_inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
+ tf->lbal = tf_inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
+ tf->lbam = tf_inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
+ tf->lbah = tf_inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
+ tf->device = tf_inb(io_ports->device_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ tf_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = tf_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = tf_inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = tf_inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = tf_inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = tf_inb(io_ports->lbah_addr);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_tf_read);
+
+/*
+ * Some localbus EIDE interfaces require a special access sequence
+ * when using 32-bit I/O instructions to transfer data. We call this
+ * the "vlb_sync" sequence, which consists of three successive reads
+ * of the sector count register location, with interrupts disabled
+ * to ensure that the reads all happen together.
+ */
+static void ata_vlb_sync(unsigned long port)
+{
+ (void)inb(port);
+ (void)inb(port);
+ (void)inb(port);
+}
+
+/*
+ * This is used for most PIO data transfers *from* the IDE interface
+ *
+ * These routines will round up any request for an odd number of bytes,
+ * so if an odd len is specified, be sure that there's at least one
+ * extra byte allocated for the buffer.
+ */
+void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
+ unsigned int len)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ unsigned long data_addr = io_ports->data_addr;
+ unsigned int words = (len + 1) >> 1;
+ u8 io_32bit = drive->io_32bit;
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+ if (io_32bit) {
+ unsigned long uninitialized_var(flags);
+
+ if ((io_32bit & 2) && !mmio) {
+ local_irq_save(flags);
+ ata_vlb_sync(io_ports->nsect_addr);
+ }
+
+ words >>= 1;
+ if (mmio)
+ __ide_mm_insl((void __iomem *)data_addr, buf, words);
+ else
+ insl(data_addr, buf, words);
+
+ if ((io_32bit & 2) && !mmio)
+ local_irq_restore(flags);
+
+ if (((len + 1) & 3) < 2)
+ return;
+
+ buf += len & ~3;
+ words = 1;
+ }
+
+ if (mmio)
+ __ide_mm_insw((void __iomem *)data_addr, buf, words);
+ else
+ insw(data_addr, buf, words);
+}
+EXPORT_SYMBOL_GPL(ide_input_data);
+
+/*
+ * This is used for most PIO data transfers *to* the IDE interface
+ */
+void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
+ unsigned int len)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct ide_io_ports *io_ports = &hwif->io_ports;
+ unsigned long data_addr = io_ports->data_addr;
+ unsigned int words = (len + 1) >> 1;
+ u8 io_32bit = drive->io_32bit;
+ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+
+ if (io_32bit) {
+ unsigned long uninitialized_var(flags);
+
+ if ((io_32bit & 2) && !mmio) {
+ local_irq_save(flags);
+ ata_vlb_sync(io_ports->nsect_addr);
+ }
+
+ words >>= 1;
+ if (mmio)
+ __ide_mm_outsl((void __iomem *)data_addr, buf, words);
+ else
+ outsl(data_addr, buf, words);
+
+ if ((io_32bit & 2) && !mmio)
+ local_irq_restore(flags);
+
+ if (((len + 1) & 3) < 2)
+ return;
+
+ buf += len & ~3;
+ words = 1;
+ }
+
+ if (mmio)
+ __ide_mm_outsw((void __iomem *)data_addr, buf, words);
+ else
+ outsw(data_addr, buf, words);
+}
+EXPORT_SYMBOL_GPL(ide_output_data);
+
+const struct ide_tp_ops default_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
+
+ .dev_select = ide_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
+};
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index a9a6c208288a..1deb6d29b186 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -40,7 +40,6 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/ide.h>
-#include <linux/hdreg.h>
#include <linux/completion.h>
#include <linux/reboot.h>
#include <linux/cdrom.h>
@@ -55,25 +54,9 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-static int __ide_end_request(ide_drive_t *drive, struct request *rq,
- int uptodate, unsigned int nr_bytes, int dequeue)
+int ide_end_rq(ide_drive_t *drive, struct request *rq, int error,
+ unsigned int nr_bytes)
{
- int ret = 1;
- int error = 0;
-
- if (uptodate <= 0)
- error = uptodate ? uptodate : -EIO;
-
- /*
- * if failfast is set on a request, override number of sectors and
- * complete the whole request right now
- */
- if (blk_noretry_request(rq) && error)
- nr_bytes = rq->hard_nr_sectors << 9;
-
- if (!blk_fs_request(rq) && error && !rq->errors)
- rq->errors = -EIO;
-
/*
* decide whether to reenable DMA -- 3 is a random magic for now,
* if we DMA timeout more than 3 times, just stay in PIO
@@ -84,255 +67,97 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
ide_dma_on(drive);
}
- if (!blk_end_request(rq, error, nr_bytes))
- ret = 0;
-
- if (ret == 0 && dequeue)
- drive->hwif->rq = NULL;
-
- return ret;
+ return blk_end_request(rq, error, nr_bytes);
}
+EXPORT_SYMBOL_GPL(ide_end_rq);
-/**
- * ide_end_request - complete an IDE I/O
- * @drive: IDE device for the I/O
- * @uptodate:
- * @nr_sectors: number of sectors completed
- *
- * This is our end_request wrapper function. We complete the I/O
- * update random number input and dequeue the request, which if
- * it was tagged may be out of order.
- */
-
-int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
+void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
{
- unsigned int nr_bytes = nr_sectors << 9;
- struct request *rq = drive->hwif->rq;
+ const struct ide_tp_ops *tp_ops = drive->hwif->tp_ops;
+ struct ide_taskfile *tf = &cmd->tf;
+ struct request *rq = cmd->rq;
+ u8 tf_cmd = tf->command;
- if (!nr_bytes) {
- if (blk_pc_request(rq))
- nr_bytes = rq->data_len;
- else
- nr_bytes = rq->hard_cur_sectors << 9;
- }
+ tf->error = err;
+ tf->status = stat;
- return __ide_end_request(drive, rq, uptodate, nr_bytes, 1);
-}
-EXPORT_SYMBOL(ide_end_request);
+ if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
+ u8 data[2];
-/**
- * ide_end_dequeued_request - complete an IDE I/O
- * @drive: IDE device for the I/O
- * @uptodate:
- * @nr_sectors: number of sectors completed
- *
- * Complete an I/O that is no longer on the request queue. This
- * typically occurs when we pull the request and issue a REQUEST_SENSE.
- * We must still finish the old request but we must not tamper with the
- * queue in the meantime.
- *
- * NOTE: This path does not handle barrier, but barrier is not supported
- * on ide-cd anyway.
- */
-
-int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
- int uptodate, int nr_sectors)
-{
- BUG_ON(!blk_rq_started(rq));
+ tp_ops->input_data(drive, cmd, data, 2);
- return __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0);
-}
-EXPORT_SYMBOL_GPL(ide_end_dequeued_request);
-
-/**
- * ide_end_drive_cmd - end an explicit drive command
- * @drive: command
- * @stat: status bits
- * @err: error bits
- *
- * Clean up after success/failure of an explicit drive command.
- * These get thrown onto the queue so they are synchronized with
- * real I/O operations on the drive.
- *
- * In LBA48 mode we have to read the register set twice to get
- * all the extra information out.
- */
-
-void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
-
- if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
- ide_task_t *task = (ide_task_t *)rq->special;
-
- if (task) {
- struct ide_taskfile *tf = &task->tf;
-
- tf->error = err;
- tf->status = stat;
-
- drive->hwif->tp_ops->tf_read(drive, task);
+ tf->data = data[0];
+ tf->hob_data = data[1];
+ }
- if (task->tf_flags & IDE_TFLAG_DYN)
- kfree(task);
- }
- } else if (blk_pm_request(rq)) {
- struct request_pm_state *pm = rq->data;
+ tp_ops->tf_read(drive, cmd);
- ide_complete_power_step(drive, rq);
- if (pm->pm_step == IDE_PM_COMPLETED)
- ide_complete_pm_request(drive, rq);
- return;
+ if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) &&
+ tf_cmd == ATA_CMD_IDLEIMMEDIATE) {
+ if (tf->lbal != 0xc4) {
+ printk(KERN_ERR "%s: head unload failed!\n",
+ drive->name);
+ ide_tf_dump(drive->name, tf);
+ } else
+ drive->dev_flags |= IDE_DFLAG_PARKED;
}
- hwif->rq = NULL;
+ if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
+ memcpy(rq->special, cmd, sizeof(*cmd));
- rq->errors = err;
-
- if (unlikely(blk_end_request(rq, (rq->errors ? -EIO : 0),
- blk_rq_bytes(rq))))
- BUG();
+ if (cmd->tf_flags & IDE_TFLAG_DYN)
+ kfree(cmd);
}
-EXPORT_SYMBOL(ide_end_drive_cmd);
-static void ide_kill_rq(ide_drive_t *drive, struct request *rq)
+/* obsolete, blk_rq_bytes() should be used instead */
+unsigned int ide_rq_bytes(struct request *rq)
{
- if (rq->rq_disk) {
- struct ide_driver *drv;
-
- drv = *(struct ide_driver **)rq->rq_disk->private_data;
- drv->end_request(drive, 0, 0);
- } else
- ide_end_request(drive, 0, 0);
+ if (blk_pc_request(rq))
+ return rq->data_len;
+ else
+ return rq->hard_cur_sectors << 9;
}
+EXPORT_SYMBOL_GPL(ide_rq_bytes);
-static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
+int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes)
{
ide_hwif_t *hwif = drive->hwif;
+ struct request *rq = hwif->rq;
+ int rc;
- if ((stat & ATA_BUSY) ||
- ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
- /* other bits are useless when BUSY */
- rq->errors |= ERROR_RESET;
- } else if (stat & ATA_ERR) {
- /* err has different meaning on cdrom and tape */
- if (err == ATA_ABORTED) {
- if ((drive->dev_flags & IDE_DFLAG_LBA) &&
- /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */
- hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS)
- return ide_stopped;
- } else if ((err & BAD_CRC) == BAD_CRC) {
- /* UDMA crc error, just retry the operation */
- drive->crc_count++;
- } else if (err & (ATA_BBK | ATA_UNC)) {
- /* retries won't help these */
- rq->errors = ERROR_MAX;
- } else if (err & ATA_TRK0NF) {
- /* help it find track zero */
- rq->errors |= ERROR_RECAL;
- }
- }
-
- if ((stat & ATA_DRQ) && rq_data_dir(rq) == READ &&
- (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) {
- int nsect = drive->mult_count ? drive->mult_count : 1;
-
- ide_pad_transfer(drive, READ, nsect * SECTOR_SIZE);
- }
-
- if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) {
- ide_kill_rq(drive, rq);
- return ide_stopped;
- }
-
- if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
- rq->errors |= ERROR_RESET;
-
- if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
- ++rq->errors;
- return ide_do_reset(drive);
- }
-
- if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
- drive->special.b.recalibrate = 1;
+ /*
+ * if failfast is set on a request, override number of sectors
+ * and complete the whole request right now
+ */
+ if (blk_noretry_request(rq) && error <= 0)
+ nr_bytes = rq->hard_nr_sectors << 9;
- ++rq->errors;
+ rc = ide_end_rq(drive, rq, error, nr_bytes);
+ if (rc == 0)
+ hwif->rq = NULL;
- return ide_stopped;
+ return rc;
}
+EXPORT_SYMBOL(ide_complete_rq);
-static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
+void ide_kill_rq(ide_drive_t *drive, struct request *rq)
{
- ide_hwif_t *hwif = drive->hwif;
+ u8 drv_req = blk_special_request(rq) && rq->rq_disk;
+ u8 media = drive->media;
- if ((stat & ATA_BUSY) ||
- ((stat & ATA_DF) && (drive->dev_flags & IDE_DFLAG_NOWERR) == 0)) {
- /* other bits are useless when BUSY */
- rq->errors |= ERROR_RESET;
- } else {
- /* add decoding error stuff */
- }
-
- if (hwif->tp_ops->read_status(hwif) & (ATA_BUSY | ATA_DRQ))
- /* force an abort */
- hwif->tp_ops->exec_command(hwif, ATA_CMD_IDLEIMMEDIATE);
+ drive->failed_pc = NULL;
- if (rq->errors >= ERROR_MAX) {
- ide_kill_rq(drive, rq);
+ if ((media == ide_floppy || media == ide_tape) && drv_req) {
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
} else {
- if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
- ++rq->errors;
- return ide_do_reset(drive);
- }
- ++rq->errors;
- }
-
- return ide_stopped;
-}
-
-static ide_startstop_t
-__ide_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
-{
- if (drive->media == ide_disk)
- return ide_ata_error(drive, rq, stat, err);
- return ide_atapi_error(drive, rq, stat, err);
-}
-
-/**
- * ide_error - handle an error on the IDE
- * @drive: drive the error occurred on
- * @msg: message to report
- * @stat: status bits
- *
- * ide_error() takes action based on the error returned by the drive.
- * For normal I/O that may well include retries. We deal with
- * both new-style (taskfile) and old style command handling here.
- * In the case of taskfile command handling there is work left to
- * do
- */
-
-ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat)
-{
- struct request *rq;
- u8 err;
-
- err = ide_dump_status(drive, msg, stat);
-
- rq = drive->hwif->rq;
- if (rq == NULL)
- return ide_stopped;
-
- /* retry only "normal" I/O: */
- if (!blk_fs_request(rq)) {
- rq->errors = 1;
- ide_end_drive_cmd(drive, stat, err);
- return ide_stopped;
+ if (media == ide_tape)
+ rq->errors = IDE_DRV_ERROR_GENERAL;
+ else if (blk_fs_request(rq) == 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
}
-
- return __ide_error(drive, rq, stat, err);
}
-EXPORT_SYMBOL_GPL(ide_error);
static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
{
@@ -359,20 +184,20 @@ static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
static ide_startstop_t ide_disk_special(ide_drive_t *drive)
{
special_t *s = &drive->special;
- ide_task_t args;
+ struct ide_cmd cmd;
- memset(&args, 0, sizeof(ide_task_t));
- args.data_phase = TASKFILE_NO_DATA;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.protocol = ATA_PROT_NODATA;
if (s->b.set_geometry) {
s->b.set_geometry = 0;
- ide_tf_set_specify_cmd(drive, &args.tf);
+ ide_tf_set_specify_cmd(drive, &cmd.tf);
} else if (s->b.recalibrate) {
s->b.recalibrate = 0;
- ide_tf_set_restore_cmd(drive, &args.tf);
+ ide_tf_set_restore_cmd(drive, &cmd.tf);
} else if (s->b.set_multmode) {
s->b.set_multmode = 0;
- ide_tf_set_setmult_cmd(drive, &args.tf);
+ ide_tf_set_setmult_cmd(drive, &cmd.tf);
} else if (s->all) {
int special = s->all;
s->all = 0;
@@ -380,10 +205,10 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive)
return ide_stopped;
}
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE |
- IDE_TFLAG_CUSTOM_HANDLER;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE |
+ IDE_TFLAG_CUSTOM_HANDLER;
- do_rw_taskfile(drive, &args);
+ do_rw_taskfile(drive, &cmd);
return ide_started;
}
@@ -413,33 +238,29 @@ static ide_startstop_t do_special (ide_drive_t *drive)
return ide_stopped;
}
-void ide_map_sg(ide_drive_t *drive, struct request *rq)
+void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
+ struct request *rq = cmd->rq;
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
- hwif->sg_nents = 1;
+ cmd->sg_nents = 1;
} else if (!rq->bio) {
sg_init_one(sg, rq->data, rq->data_len);
- hwif->sg_nents = 1;
- } else {
- hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
- }
+ cmd->sg_nents = 1;
+ } else
+ cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
}
-
EXPORT_SYMBOL_GPL(ide_map_sg);
-void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq)
+void ide_init_sg_cmd(struct ide_cmd *cmd, unsigned int nr_bytes)
{
- ide_hwif_t *hwif = drive->hwif;
-
- hwif->nsect = hwif->nleft = rq->nr_sectors;
- hwif->cursg_ofs = 0;
- hwif->cursg = NULL;
+ cmd->nbytes = cmd->nleft = nr_bytes;
+ cmd->cursg_ofs = 0;
+ cmd->cursg = NULL;
}
-
EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
/**
@@ -457,24 +278,15 @@ EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
struct request *rq)
{
- ide_hwif_t *hwif = drive->hwif;
- ide_task_t *task = rq->special;
-
- if (task) {
- hwif->data_phase = task->data_phase;
-
- switch (hwif->data_phase) {
- case TASKFILE_MULTI_OUT:
- case TASKFILE_OUT:
- case TASKFILE_MULTI_IN:
- case TASKFILE_IN:
- ide_init_sg_cmd(drive, rq);
- ide_map_sg(drive, rq);
- default:
- break;
+ struct ide_cmd *cmd = rq->special;
+
+ if (cmd) {
+ if (cmd->protocol == ATA_PROT_PIO) {
+ ide_init_sg_cmd(cmd, rq->nr_sectors << 9);
+ ide_map_sg(drive, cmd);
}
- return do_rw_taskfile(drive, task);
+ return do_rw_taskfile(drive, cmd);
}
/*
@@ -484,83 +296,26 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
#ifdef DEBUG
printk("%s: DRIVE_CMD (null)\n", drive->name);
#endif
- ide_end_drive_cmd(drive, hwif->tp_ops->read_status(hwif),
- ide_read_error(drive));
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
return ide_stopped;
}
-int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
- int arg)
-{
- struct request_queue *q = drive->queue;
- struct request *rq;
- int ret = 0;
-
- if (!(setting->flags & DS_SYNC))
- return setting->set(drive, arg);
-
- rq = blk_get_request(q, READ, __GFP_WAIT);
- rq->cmd_type = REQ_TYPE_SPECIAL;
- rq->cmd_len = 5;
- rq->cmd[0] = REQ_DEVSET_EXEC;
- *(int *)&rq->cmd[1] = arg;
- rq->special = setting->set;
-
- if (blk_execute_rq(q, NULL, rq, 0))
- ret = rq->errors;
- blk_put_request(rq);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(ide_devset_execute);
-
static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
{
u8 cmd = rq->cmd[0];
- if (cmd == REQ_PARK_HEADS || cmd == REQ_UNPARK_HEADS) {
- ide_task_t task;
- struct ide_taskfile *tf = &task.tf;
-
- memset(&task, 0, sizeof(task));
- if (cmd == REQ_PARK_HEADS) {
- drive->sleep = *(unsigned long *)rq->special;
- drive->dev_flags |= IDE_DFLAG_SLEEPING;
- tf->command = ATA_CMD_IDLEIMMEDIATE;
- tf->feature = 0x44;
- tf->lbal = 0x4c;
- tf->lbam = 0x4e;
- tf->lbah = 0x55;
- task.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER;
- } else /* cmd == REQ_UNPARK_HEADS */
- tf->command = ATA_CMD_CHK_POWER;
-
- task.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- task.rq = rq;
- drive->hwif->data_phase = task.data_phase = TASKFILE_NO_DATA;
- return do_rw_taskfile(drive, &task);
- }
-
switch (cmd) {
+ case REQ_PARK_HEADS:
+ case REQ_UNPARK_HEADS:
+ return ide_do_park_unpark(drive, rq);
case REQ_DEVSET_EXEC:
- {
- int err, (*setfunc)(ide_drive_t *, int) = rq->special;
-
- err = setfunc(drive, *(int *)&rq->cmd[1]);
- if (err)
- rq->errors = err;
- else
- err = 1;
- ide_end_request(drive, err, 0);
- return ide_stopped;
- }
+ return ide_do_devset(drive, rq);
case REQ_DRIVE_RESET:
return ide_do_reset(drive);
default:
- blk_dump_rq_flags(rq, "ide_special_rq - bad request");
- ide_end_request(drive, 0, 0);
- return ide_stopped;
+ BUG();
}
}
@@ -593,7 +348,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
if (blk_pm_request(rq))
ide_check_pm_state(drive, rq);
- SELECT_DRIVE(drive);
+ drive->hwif->tp_ops->dev_select(drive);
if (ide_wait_stat(&startstop, drive, drive->ready_stat,
ATA_BUSY | ATA_DRQ, WAIT_READY)) {
printk(KERN_ERR "%s: drive not ready for command\n", drive->name);
@@ -620,7 +375,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
startstop = ide_start_power_step(drive, rq);
if (startstop == ide_stopped &&
pm->pm_step == IDE_PM_COMPLETED)
- ide_complete_pm_request(drive, rq);
+ ide_complete_pm_rq(drive, rq);
return startstop;
} else if (!rq->rq_disk && blk_special_request(rq))
/*
@@ -683,8 +438,8 @@ static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif)
if (host->host_flags & IDE_HFLAG_SERIALIZE) {
rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy);
if (rc == 0) {
- /* for atari only */
- ide_get_lock(ide_intr, hwif);
+ if (host->get_lock)
+ host->get_lock(ide_intr, hwif);
}
}
return rc;
@@ -693,8 +448,8 @@ static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif)
static inline void ide_unlock_host(struct ide_host *host)
{
if (host->host_flags & IDE_HFLAG_SERIALIZE) {
- /* for atari only */
- ide_release_lock();
+ if (host->release_lock)
+ host->release_lock();
clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy);
}
}
@@ -736,11 +491,10 @@ repeat:
prev_port = hwif->host->cur_port;
hwif->rq = NULL;
- if (drive->dev_flags & IDE_DFLAG_SLEEPING) {
- if (time_before(drive->sleep, jiffies)) {
- ide_unlock_port(hwif);
- goto plug_device;
- }
+ if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
+ time_after(drive->sleep, jiffies)) {
+ ide_unlock_port(hwif);
+ goto plug_device;
}
if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) &&
@@ -750,7 +504,9 @@ repeat:
* quirk_list may not like intr setups/cleanups
*/
if (prev_port && prev_port->cur_dev->quirk_list == 0)
- prev_port->tp_ops->set_irq(prev_port, 0);
+ prev_port->tp_ops->write_devctl(prev_port,
+ ATA_NIEN |
+ ATA_DEVCTL_OBS);
hwif->host->cur_port = hwif;
}
@@ -820,63 +576,6 @@ plug_device_2:
blk_plug_device(q);
}
-/*
- * un-busy the port etc, and clear any pending DMA status. we want to
- * retry the current request in pio mode instead of risking tossing it
- * all away
- */
-static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct request *rq;
- ide_startstop_t ret = ide_stopped;
-
- /*
- * end current dma transaction
- */
-
- if (error < 0) {
- printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
- (void)hwif->dma_ops->dma_end(drive);
- ret = ide_error(drive, "dma timeout error",
- hwif->tp_ops->read_status(hwif));
- } else {
- printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
- hwif->dma_ops->dma_timeout(drive);
- }
-
- /*
- * disable dma for now, but remember that we did so because of
- * a timeout -- we'll reenable after we finish this next request
- * (or rather the first chunk of it) in pio.
- */
- drive->dev_flags |= IDE_DFLAG_DMA_PIO_RETRY;
- drive->retry_pio++;
- ide_dma_off_quietly(drive);
-
- /*
- * un-busy drive etc and make sure request is sane
- */
-
- rq = hwif->rq;
- if (!rq)
- goto out;
-
- hwif->rq = NULL;
-
- rq->errors = 0;
-
- if (!rq->bio)
- goto out;
-
- rq->sector = rq->bio->bi_sector;
- rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
- rq->hard_cur_sectors = rq->current_nr_sectors;
- rq->buffer = bio_data(rq->bio);
-out:
- return ret;
-}
-
static void ide_plug_device(ide_drive_t *drive)
{
struct request_queue *q = drive->queue;
@@ -888,6 +587,29 @@ static void ide_plug_device(ide_drive_t *drive)
spin_unlock_irqrestore(q->queue_lock, flags);
}
+static int drive_is_ready(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 stat = 0;
+
+ if (drive->waiting_for_dma)
+ return hwif->dma_ops->dma_test_irq(drive);
+
+ if (hwif->io_ports.ctl_addr &&
+ (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0)
+ stat = hwif->tp_ops->read_altstatus(hwif);
+ else
+ /* Note: this may clear a pending IRQ!! */
+ stat = hwif->tp_ops->read_status(hwif);
+
+ if (stat & ATA_BUSY)
+ /* drive busy: definitely not interrupting */
+ return 0;
+
+ /* drive ready: *might* be interrupting */
+ return 1;
+}
+
/**
* ide_timer_expiry - handle lack of an IDE interrupt
* @data: timer callback magic (hwif)
@@ -940,6 +662,7 @@ void ide_timer_expiry (unsigned long data)
}
}
hwif->handler = NULL;
+ hwif->expiry = NULL;
/*
* We need to simulate a real interrupt when invoking
* the handler() function, which means we need to
@@ -955,7 +678,8 @@ void ide_timer_expiry (unsigned long data)
} else if (drive_is_ready(drive)) {
if (drive->waiting_for_dma)
hwif->dma_ops->dma_lost_irq(drive);
- (void)ide_ack_intr(hwif);
+ if (hwif->ack_intr)
+ hwif->ack_intr(hwif);
printk(KERN_WARNING "%s: lost interrupt\n",
drive->name);
startstop = handler(drive);
@@ -1056,6 +780,7 @@ static void unexpected_intr(int irq, ide_hwif_t *hwif)
irqreturn_t ide_intr (int irq, void *dev_id)
{
ide_hwif_t *hwif = (ide_hwif_t *)dev_id;
+ struct ide_host *host = hwif->host;
ide_drive_t *uninitialized_var(drive);
ide_handler_t *handler;
unsigned long flags;
@@ -1063,14 +788,14 @@ irqreturn_t ide_intr (int irq, void *dev_id)
irqreturn_t irq_ret = IRQ_NONE;
int plug_device = 0;
- if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) {
- if (hwif != hwif->host->cur_port)
+ if (host->host_flags & IDE_HFLAG_SERIALIZE) {
+ if (hwif != host->cur_port)
goto out_early;
}
spin_lock_irqsave(&hwif->lock, flags);
- if (!ide_ack_intr(hwif))
+ if (hwif->ack_intr && hwif->ack_intr(hwif) == 0)
goto out;
handler = hwif->handler;
@@ -1087,27 +812,19 @@ irqreturn_t ide_intr (int irq, void *dev_id)
*
* For PCI, we cannot tell the difference,
* so in that case we just ignore it and hope it goes away.
- *
- * FIXME: unexpected_intr should be hwif-> then we can
- * remove all the ifdef PCI crap
*/
-#ifdef CONFIG_BLK_DEV_IDEPCI
- if (hwif->chipset != ide_pci)
-#endif /* CONFIG_BLK_DEV_IDEPCI */
- {
+ if ((host->irq_flags & IRQF_SHARED) == 0) {
/*
* Probably not a shared PCI interrupt,
* so we can safely try to do something about it:
*/
unexpected_intr(irq, hwif);
-#ifdef CONFIG_BLK_DEV_IDEPCI
} else {
/*
* Whack the status register, just in case
* we have a leftover pending IRQ.
*/
(void)hwif->tp_ops->read_status(hwif);
-#endif /* CONFIG_BLK_DEV_IDEPCI */
}
goto out;
}
@@ -1125,6 +842,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
goto out;
hwif->handler = NULL;
+ hwif->expiry = NULL;
hwif->req_gen++;
del_timer(&hwif->timer);
spin_unlock(&hwif->lock);
@@ -1164,54 +882,6 @@ out_early:
}
EXPORT_SYMBOL_GPL(ide_intr);
-/**
- * ide_do_drive_cmd - issue IDE special command
- * @drive: device to issue command
- * @rq: request to issue
- *
- * This function issues a special IDE device request
- * onto the request queue.
- *
- * the rq is queued at the head of the request queue, displacing
- * the currently-being-processed request and this function
- * returns immediately without waiting for the new rq to be
- * completed. This is VERY DANGEROUS, and is intended for
- * careful use by the ATAPI tape/cdrom driver code.
- */
-
-void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq)
-{
- struct request_queue *q = drive->queue;
- unsigned long flags;
-
- drive->hwif->rq = NULL;
-
- spin_lock_irqsave(q->queue_lock, flags);
- __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
- spin_unlock_irqrestore(q->queue_lock, flags);
-}
-EXPORT_SYMBOL(ide_do_drive_cmd);
-
-void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma)
-{
- ide_hwif_t *hwif = drive->hwif;
- ide_task_t task;
-
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM |
- IDE_TFLAG_OUT_FEATURE | tf_flags;
- task.tf.feature = dma; /* Use PIO/DMA */
- task.tf.lbam = bcount & 0xff;
- task.tf.lbah = (bcount >> 8) & 0xff;
-
- ide_tf_dump(drive->name, &task.tf);
- hwif->tp_ops->set_irq(hwif, 1);
- SELECT_MASK(drive, 0);
- hwif->tp_ops->tf_load(drive, &task);
-}
-
-EXPORT_SYMBOL_GPL(ide_pktcmd_tf_load);
-
void ide_pad_transfer(ide_drive_t *drive, int write, int len)
{
ide_hwif_t *hwif = drive->hwif;
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index 1be263eb9c07..770142767437 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -111,13 +111,13 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg)
return 0;
}
-static int ide_cmd_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
+static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
{
u8 *buf = NULL;
int bufsize = 0, err = 0;
u8 args[4], xfer_rate = 0;
- ide_task_t tfargs;
- struct ide_taskfile *tf = &tfargs.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
u16 *id = drive->id;
if (NULL == (void *) arg) {
@@ -134,24 +134,24 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
if (copy_from_user(args, (void __user *)arg, 4))
return -EFAULT;
- memset(&tfargs, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
tf->feature = args[2];
if (args[0] == ATA_CMD_SMART) {
tf->nsect = args[3];
tf->lbal = args[1];
tf->lbam = 0x4f;
tf->lbah = 0xc2;
- tfargs.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT;
+ cmd.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT;
} else {
tf->nsect = args[1];
- tfargs.tf_flags = IDE_TFLAG_OUT_FEATURE |
- IDE_TFLAG_OUT_NSECT | IDE_TFLAG_IN_NSECT;
+ cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
+ IDE_TFLAG_IN_NSECT;
}
tf->command = args[0];
- tfargs.data_phase = args[3] ? TASKFILE_IN : TASKFILE_NO_DATA;
+ cmd.protocol = args[3] ? ATA_PROT_PIO : ATA_PROT_NODATA;
if (args[3]) {
- tfargs.tf_flags |= IDE_TFLAG_IO_16BIT;
+ cmd.tf_flags |= IDE_TFLAG_IO_16BIT;
bufsize = SECTOR_SIZE * args[3];
buf = kzalloc(bufsize, GFP_KERNEL);
if (buf == NULL)
@@ -172,7 +172,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
}
}
- err = ide_raw_taskfile(drive, &tfargs, buf, args[3]);
+ err = ide_raw_taskfile(drive, &cmd, buf, args[3]);
args[0] = tf->status;
args[1] = tf->error;
@@ -194,25 +194,25 @@ abort:
return err;
}
-static int ide_task_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
+static int ide_task_ioctl(ide_drive_t *drive, unsigned long arg)
{
void __user *p = (void __user *)arg;
int err = 0;
u8 args[7];
- ide_task_t task;
+ struct ide_cmd cmd;
if (copy_from_user(args, p, 7))
return -EFAULT;
- memset(&task, 0, sizeof(task));
- memcpy(&task.tf_array[7], &args[1], 6);
- task.tf.command = args[0];
- task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ memcpy(&cmd.tf_array[7], &args[1], 6);
+ cmd.tf.command = args[0];
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- err = ide_no_data_taskfile(drive, &task);
+ err = ide_no_data_taskfile(drive, &cmd);
- args[0] = task.tf.command;
- memcpy(&args[1], &task.tf_array[7], 6);
+ args[0] = cmd.tf.command;
+ memcpy(&args[1], &cmd.tf_array[7], 6);
if (copy_to_user(p, args, 7))
err = -EFAULT;
@@ -262,17 +262,17 @@ int generic_ide_ioctl(ide_drive_t *drive, struct block_device *bdev,
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
return -EACCES;
if (drive->media == ide_disk)
- return ide_taskfile_ioctl(drive, cmd, arg);
+ return ide_taskfile_ioctl(drive, arg);
return -ENOMSG;
#endif
case HDIO_DRIVE_CMD:
if (!capable(CAP_SYS_RAWIO))
return -EACCES;
- return ide_cmd_ioctl(drive, cmd, arg);
+ return ide_cmd_ioctl(drive, arg);
case HDIO_DRIVE_TASK:
if (!capable(CAP_SYS_RAWIO))
return -EACCES;
- return ide_task_ioctl(drive, cmd, arg);
+ return ide_task_ioctl(drive, arg);
case HDIO_DRIVE_RESET:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index b1892bd95c6f..27bb70ddd459 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -27,49 +27,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-/*
- * Conventional PIO operations for ATA devices
- */
-
-static u8 ide_inb (unsigned long port)
-{
- return (u8) inb(port);
-}
-
-static void ide_outb (u8 val, unsigned long port)
-{
- outb(val, port);
-}
-
-/*
- * MMIO operations, typically used for SATA controllers
- */
-
-static u8 ide_mm_inb (unsigned long port)
-{
- return (u8) readb((void __iomem *) port);
-}
-
-static void ide_mm_outb (u8 value, unsigned long port)
-{
- writeb(value, (void __iomem *) port);
-}
-
-void SELECT_DRIVE (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
- ide_task_t task;
-
- if (port_ops && port_ops->selectproc)
- port_ops->selectproc(drive);
-
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_OUT_DEVICE;
-
- drive->hwif->tp_ops->tf_load(drive, &task);
-}
-
void SELECT_MASK(ide_drive_t *drive, int mask)
{
const struct ide_port_ops *port_ops = drive->hwif->port_ops;
@@ -78,319 +35,19 @@ void SELECT_MASK(ide_drive_t *drive, int mask)
port_ops->maskproc(drive, mask);
}
-void ide_exec_command(ide_hwif_t *hwif, u8 cmd)
-{
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- writeb(cmd, (void __iomem *)hwif->io_ports.command_addr);
- else
- outb(cmd, hwif->io_ports.command_addr);
-}
-EXPORT_SYMBOL_GPL(ide_exec_command);
-
-u8 ide_read_status(ide_hwif_t *hwif)
-{
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- return readb((void __iomem *)hwif->io_ports.status_addr);
- else
- return inb(hwif->io_ports.status_addr);
-}
-EXPORT_SYMBOL_GPL(ide_read_status);
-
-u8 ide_read_altstatus(ide_hwif_t *hwif)
-{
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- return readb((void __iomem *)hwif->io_ports.ctl_addr);
- else
- return inb(hwif->io_ports.ctl_addr);
-}
-EXPORT_SYMBOL_GPL(ide_read_altstatus);
-
-void ide_set_irq(ide_hwif_t *hwif, int on)
-{
- u8 ctl = ATA_DEVCTL_OBS;
-
- if (on == 4) { /* hack for SRST */
- ctl |= 4;
- on &= ~4;
- }
-
- ctl |= on ? 0 : 2;
-
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
- else
- outb(ctl, hwif->io_ports.ctl_addr);
-}
-EXPORT_SYMBOL_GPL(ide_set_irq);
-
-void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- void (*tf_outb)(u8 addr, unsigned long port);
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
-
- if (mmio)
- tf_outb = ide_mm_outb;
- else
- tf_outb = ide_outb;
-
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
- HIHI = 0xFF;
-
- if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- if (mmio)
- writew(data, (void __iomem *)io_ports->data_addr);
- else
- outw(data, io_ports->data_addr);
- }
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
- tf_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
- tf_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
- tf_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
- tf_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
- tf_outb(tf->hob_lbah, io_ports->lbah_addr);
-
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
- tf_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
- tf_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
- tf_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
- tf_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
- tf_outb(tf->lbah, io_ports->lbah_addr);
-
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
- tf_outb((tf->device & HIHI) | drive->select,
- io_ports->device_addr);
-}
-EXPORT_SYMBOL_GPL(ide_tf_load);
-
-void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- void (*tf_outb)(u8 addr, unsigned long port);
- u8 (*tf_inb)(unsigned long port);
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
- if (mmio) {
- tf_outb = ide_mm_outb;
- tf_inb = ide_mm_inb;
- } else {
- tf_outb = ide_outb;
- tf_inb = ide_inb;
- }
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data;
-
- if (mmio)
- data = readw((void __iomem *)io_ports->data_addr);
- else
- data = inw(io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
-
- /* be sure we're looking at the low order bits */
- tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = tf_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
- tf->nsect = tf_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
- tf->lbal = tf_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
- tf->lbam = tf_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
- tf->lbah = tf_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
- tf->device = tf_inb(io_ports->device_addr);
-
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = tf_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tf_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tf_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tf_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tf_inb(io_ports->lbah_addr);
- }
-}
-EXPORT_SYMBOL_GPL(ide_tf_read);
-
-/*
- * Some localbus EIDE interfaces require a special access sequence
- * when using 32-bit I/O instructions to transfer data. We call this
- * the "vlb_sync" sequence, which consists of three successive reads
- * of the sector count register location, with interrupts disabled
- * to ensure that the reads all happen together.
- */
-static void ata_vlb_sync(unsigned long port)
-{
- (void)inb(port);
- (void)inb(port);
- (void)inb(port);
-}
-
-/*
- * This is used for most PIO data transfers *from* the IDE interface
- *
- * These routines will round up any request for an odd number of bytes,
- * so if an odd len is specified, be sure that there's at least one
- * extra byte allocated for the buffer.
- */
-void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf,
- unsigned int len)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- unsigned long data_addr = io_ports->data_addr;
- u8 io_32bit = drive->io_32bit;
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
- len++;
-
- if (io_32bit) {
- unsigned long uninitialized_var(flags);
-
- if ((io_32bit & 2) && !mmio) {
- local_irq_save(flags);
- ata_vlb_sync(io_ports->nsect_addr);
- }
-
- if (mmio)
- __ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
- else
- insl(data_addr, buf, len / 4);
-
- if ((io_32bit & 2) && !mmio)
- local_irq_restore(flags);
-
- if ((len & 3) >= 2) {
- if (mmio)
- __ide_mm_insw((void __iomem *)data_addr,
- (u8 *)buf + (len & ~3), 1);
- else
- insw(data_addr, (u8 *)buf + (len & ~3), 1);
- }
- } else {
- if (mmio)
- __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
- else
- insw(data_addr, buf, len / 2);
- }
-}
-EXPORT_SYMBOL_GPL(ide_input_data);
-
-/*
- * This is used for most PIO data transfers *to* the IDE interface
- */
-void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf,
- unsigned int len)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- unsigned long data_addr = io_ports->data_addr;
- u8 io_32bit = drive->io_32bit;
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-
- len++;
-
- if (io_32bit) {
- unsigned long uninitialized_var(flags);
-
- if ((io_32bit & 2) && !mmio) {
- local_irq_save(flags);
- ata_vlb_sync(io_ports->nsect_addr);
- }
-
- if (mmio)
- __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
- else
- outsl(data_addr, buf, len / 4);
-
- if ((io_32bit & 2) && !mmio)
- local_irq_restore(flags);
-
- if ((len & 3) >= 2) {
- if (mmio)
- __ide_mm_outsw((void __iomem *)data_addr,
- (u8 *)buf + (len & ~3), 1);
- else
- outsw(data_addr, (u8 *)buf + (len & ~3), 1);
- }
- } else {
- if (mmio)
- __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
- else
- outsw(data_addr, buf, len / 2);
- }
-}
-EXPORT_SYMBOL_GPL(ide_output_data);
-
u8 ide_read_error(ide_drive_t *drive)
{
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_FEATURE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_IN_ERROR;
- drive->hwif->tp_ops->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
- return task.tf.error;
+ return cmd.tf.error;
}
EXPORT_SYMBOL_GPL(ide_read_error);
-void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
-{
- ide_task_t task;
-
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
- IDE_TFLAG_IN_NSECT;
-
- drive->hwif->tp_ops->tf_read(drive, &task);
-
- *bcount = (task.tf.lbah << 8) | task.tf.lbam;
- *ireason = task.tf.nsect & 3;
-}
-EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
-
-const struct ide_tp_ops default_tp_ops = {
- .exec_command = ide_exec_command,
- .read_status = ide_read_status,
- .read_altstatus = ide_read_altstatus,
-
- .set_irq = ide_set_irq,
-
- .tf_load = ide_tf_load,
- .tf_read = ide_tf_read,
-
- .input_data = ide_input_data,
- .output_data = ide_output_data,
-};
-
void ide_fix_driveid(u16 *id)
{
#ifndef __LITTLE_ENDIAN
@@ -412,7 +69,7 @@ void ide_fix_driveid(u16 *id)
* returned by the ATA_CMD_ID_ATA[PI] commands.
*/
-void ide_fixstring (u8 *s, const int bytecount, const int byteswap)
+void ide_fixstring(u8 *s, const int bytecount, const int byteswap)
{
u8 *p, *end = &s[bytecount & ~1]; /* bytecount must be even */
@@ -435,44 +92,9 @@ void ide_fixstring (u8 *s, const int bytecount, const int byteswap)
while (p != end)
*p++ = '\0';
}
-
EXPORT_SYMBOL(ide_fixstring);
/*
- * Needed for PCI irq sharing
- */
-int drive_is_ready (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- u8 stat = 0;
-
- if (drive->waiting_for_dma)
- return hwif->dma_ops->dma_test_irq(drive);
-
- /*
- * We do a passive status test under shared PCI interrupts on
- * cards that truly share the ATA side interrupt, but may also share
- * an interrupt with another pci card/device. We make no assumptions
- * about possible isa-pnp and pci-pnp issues yet.
- */
- if (hwif->io_ports.ctl_addr &&
- (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0)
- stat = hwif->tp_ops->read_altstatus(hwif);
- else
- /* Note: this may clear a pending IRQ!! */
- stat = hwif->tp_ops->read_status(hwif);
-
- if (stat & ATA_BUSY)
- /* drive busy: definitely not interrupting */
- return 0;
-
- /* drive ready: *might* be interrupting */
- return 1;
-}
-
-EXPORT_SYMBOL(drive_is_ready);
-
-/*
* This routine busy-waits for the drive status to be not "busy".
* It then checks the status for all of the "good" bits and none
* of the "bad" bits, and if all is okay it returns 0. All other
@@ -483,7 +105,8 @@ EXPORT_SYMBOL(drive_is_ready);
* setting a timer to wake up at half second intervals thereafter,
* until timeout is achieved, before timing out.
*/
-static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat)
+static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
+ unsigned long timeout, u8 *rstat)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
@@ -541,7 +164,8 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti
* The caller should return the updated value of "startstop" in this case,
* "startstop" is unchanged when the function returns 0.
*/
-int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout)
+int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good,
+ u8 bad, unsigned long timeout)
{
int err;
u8 stat;
@@ -561,7 +185,6 @@ int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 ba
return err;
}
-
EXPORT_SYMBOL(ide_wait_stat);
/**
@@ -582,7 +205,6 @@ int ide_in_drive_list(u16 *id, const struct drive_list_entry *table)
return 1;
return 0;
}
-
EXPORT_SYMBOL_GPL(ide_in_drive_list);
/*
@@ -607,7 +229,7 @@ static const struct drive_list_entry ivb_list[] = {
* All hosts that use the 80c ribbon must use!
* The name is derived from upper byte of word 93 and the 80c ribbon.
*/
-u8 eighty_ninty_three (ide_drive_t *drive)
+u8 eighty_ninty_three(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
u16 *id = drive->id;
@@ -652,51 +274,24 @@ no_80w:
int ide_driveid_update(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
u16 *id;
- unsigned long flags;
- u8 stat;
-
- /*
- * Re-read drive->id for possible DMA mode
- * change (copied from ide-probe.c)
- */
+ int rc;
- SELECT_MASK(drive, 1);
- tp_ops->set_irq(hwif, 0);
- msleep(50);
- tp_ops->exec_command(hwif, ATA_CMD_ID_ATA);
-
- if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 1)) {
- SELECT_MASK(drive, 0);
+ id = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
+ if (id == NULL)
return 0;
- }
- msleep(50); /* wait for IRQ and ATA_DRQ */
- stat = tp_ops->read_status(hwif);
-
- if (!OK_STAT(stat, ATA_DRQ, BAD_R_STAT)) {
- SELECT_MASK(drive, 0);
- printk("%s: CHECK for good STATUS\n", drive->name);
- return 0;
- }
- local_irq_save(flags);
+ SELECT_MASK(drive, 1);
+ rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id);
SELECT_MASK(drive, 0);
- id = kmalloc(SECTOR_SIZE, GFP_ATOMIC);
- if (!id) {
- local_irq_restore(flags);
- return 0;
- }
- tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
- (void)tp_ops->read_status(hwif); /* clear drive IRQ */
- local_irq_enable();
- local_irq_restore(flags);
- ide_fix_driveid(id);
+
+ if (rc)
+ goto out_err;
drive->id[ATA_ID_UDMA_MODES] = id[ATA_ID_UDMA_MODES];
drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES];
drive->id[ATA_ID_SWDMA_MODES] = id[ATA_ID_SWDMA_MODES];
+ drive->id[ATA_ID_CFA_MODES] = id[ATA_ID_CFA_MODES];
/* anything more ? */
kfree(id);
@@ -705,6 +300,12 @@ int ide_driveid_update(ide_drive_t *drive)
ide_dma_off(drive);
return 1;
+out_err:
+ SELECT_MASK(drive, 0);
+ if (rc == 2)
+ printk(KERN_ERR "%s: %s: bad status\n", drive->name, __func__);
+ kfree(id);
+ return 0;
}
int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
@@ -714,7 +315,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
u16 *id = drive->id, i;
int error = 0;
u8 stat;
- ide_task_t task;
+ struct ide_cmd cmd;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_ops) /* check if host supports DMA */
@@ -731,35 +332,32 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
* but for some reason these don't work at
* this point (lost interrupt).
*/
- /*
- * Select the drive, and issue the SETFEATURES command
- */
- disable_irq_nosync(hwif->irq);
-
+
/*
* FIXME: we race against the running IRQ here if
* this is called from non IRQ context. If we use
* disable_irq() we hang on the error path. Work
* is needed.
*/
-
+ disable_irq_nosync(hwif->irq);
+
udelay(1);
- SELECT_DRIVE(drive);
+ tp_ops->dev_select(drive);
SELECT_MASK(drive, 1);
udelay(1);
- tp_ops->set_irq(hwif, 0);
+ tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT;
- task.tf.feature = SETFEATURES_XFER;
- task.tf.nsect = speed;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT;
+ cmd.tf.feature = SETFEATURES_XFER;
+ cmd.tf.nsect = speed;
- tp_ops->tf_load(drive, &task);
+ tp_ops->tf_load(drive, &cmd);
tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES);
if (drive->quirk_list == 2)
- tp_ops->set_irq(hwif, 1);
+ tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
error = __ide_wait_stat(drive, drive->ready_stat,
ATA_BUSY | ATA_DRQ | ATA_ERR,
@@ -774,9 +372,14 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
return error;
}
- id[ATA_ID_UDMA_MODES] &= ~0xFF00;
- id[ATA_ID_MWDMA_MODES] &= ~0x0F00;
- id[ATA_ID_SWDMA_MODES] &= ~0x0F00;
+ if (speed >= XFER_SW_DMA_0) {
+ id[ATA_ID_UDMA_MODES] &= ~0xFF00;
+ id[ATA_ID_MWDMA_MODES] &= ~0x0700;
+ id[ATA_ID_SWDMA_MODES] &= ~0x0700;
+ if (ata_id_is_cfa(id))
+ id[ATA_ID_CFA_MODES] &= ~0x0E00;
+ } else if (ata_id_is_cfa(id))
+ id[ATA_ID_CFA_MODES] &= ~0x01C0;
skip:
#ifdef CONFIG_BLK_DEV_IDEDMA
@@ -789,12 +392,18 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
if (speed >= XFER_UDMA_0) {
i = 1 << (speed - XFER_UDMA_0);
id[ATA_ID_UDMA_MODES] |= (i << 8 | i);
+ } else if (ata_id_is_cfa(id) && speed >= XFER_MW_DMA_3) {
+ i = speed - XFER_MW_DMA_2;
+ id[ATA_ID_CFA_MODES] |= i << 9;
} else if (speed >= XFER_MW_DMA_0) {
i = 1 << (speed - XFER_MW_DMA_0);
id[ATA_ID_MWDMA_MODES] |= (i << 8 | i);
} else if (speed >= XFER_SW_DMA_0) {
i = 1 << (speed - XFER_SW_DMA_0);
id[ATA_ID_SWDMA_MODES] |= (i << 8 | i);
+ } else if (ata_id_is_cfa(id) && speed >= XFER_PIO_5) {
+ i = speed - XFER_PIO_4;
+ id[ATA_ID_CFA_MODES] |= i << 6;
}
if (!drive->init_speed)
@@ -812,55 +421,55 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
*
* See also ide_execute_command
*/
-static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
- unsigned int timeout, ide_expiry_t *expiry)
+void __ide_set_handler(ide_drive_t *drive, ide_handler_t *handler,
+ unsigned int timeout)
{
ide_hwif_t *hwif = drive->hwif;
BUG_ON(hwif->handler);
hwif->handler = handler;
- hwif->expiry = expiry;
hwif->timer.expires = jiffies + timeout;
hwif->req_gen_timer = hwif->req_gen;
add_timer(&hwif->timer);
}
-void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
- unsigned int timeout, ide_expiry_t *expiry)
+void ide_set_handler(ide_drive_t *drive, ide_handler_t *handler,
+ unsigned int timeout)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
spin_lock_irqsave(&hwif->lock, flags);
- __ide_set_handler(drive, handler, timeout, expiry);
+ __ide_set_handler(drive, handler, timeout);
spin_unlock_irqrestore(&hwif->lock, flags);
}
-
EXPORT_SYMBOL(ide_set_handler);
-
+
/**
* ide_execute_command - execute an IDE command
* @drive: IDE drive to issue the command against
- * @command: command byte to write
+ * @cmd: command
* @handler: handler for next phase
* @timeout: timeout for command
- * @expiry: handler to run on timeout
*
* Helper function to issue an IDE command. This handles the
- * atomicity requirements, command timing and ensures that the
+ * atomicity requirements, command timing and ensures that the
* handler and IRQ setup do not race. All IDE command kick off
* should go via this function or do equivalent locking.
*/
-void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
- unsigned timeout, ide_expiry_t *expiry)
+void ide_execute_command(ide_drive_t *drive, struct ide_cmd *cmd,
+ ide_handler_t *handler, unsigned timeout)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
spin_lock_irqsave(&hwif->lock, flags);
- __ide_set_handler(drive, handler, timeout, expiry);
- hwif->tp_ops->exec_command(hwif, cmd);
+ if ((cmd->protocol != ATAPI_PROT_DMA &&
+ cmd->protocol != ATAPI_PROT_PIO) ||
+ (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT))
+ __ide_set_handler(drive, handler, timeout);
+ hwif->tp_ops->exec_command(hwif, cmd->tf.command);
/*
* Drive takes 400nS to respond, we must avoid the IRQ being
* serviced before that.
@@ -870,314 +479,6 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
ndelay(400);
spin_unlock_irqrestore(&hwif->lock, flags);
}
-EXPORT_SYMBOL(ide_execute_command);
-
-void ide_execute_pkt_cmd(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- unsigned long flags;
-
- spin_lock_irqsave(&hwif->lock, flags);
- hwif->tp_ops->exec_command(hwif, ATA_CMD_PACKET);
- ndelay(400);
- spin_unlock_irqrestore(&hwif->lock, flags);
-}
-EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd);
-
-static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
-{
- struct request *rq = drive->hwif->rq;
-
- if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET)
- ide_end_request(drive, err ? err : 1, 0);
-}
-
-/* needed below */
-static ide_startstop_t do_reset1 (ide_drive_t *, int);
-
-/*
- * atapi_reset_pollfunc() gets invoked to poll the interface for completion every 50ms
- * during an atapi drive reset operation. If the drive has not yet responded,
- * and we have not yet hit our maximum waiting time, then the timer is restarted
- * for another 50ms.
- */
-static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- u8 stat;
-
- SELECT_DRIVE(drive);
- udelay (10);
- stat = hwif->tp_ops->read_status(hwif);
-
- if (OK_STAT(stat, 0, ATA_BUSY))
- printk("%s: ATAPI reset complete\n", drive->name);
- else {
- if (time_before(jiffies, hwif->poll_timeout)) {
- ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
- /* continue polling */
- return ide_started;
- }
- /* end of polling */
- hwif->polling = 0;
- printk("%s: ATAPI reset timed-out, status=0x%02x\n",
- drive->name, stat);
- /* do it the old fashioned way */
- return do_reset1(drive, 1);
- }
- /* done polling */
- hwif->polling = 0;
- ide_complete_drive_reset(drive, 0);
- return ide_stopped;
-}
-
-static void ide_reset_report_error(ide_hwif_t *hwif, u8 err)
-{
- static const char *err_master_vals[] =
- { NULL, "passed", "formatter device error",
- "sector buffer error", "ECC circuitry error",
- "controlling MPU error" };
-
- u8 err_master = err & 0x7f;
-
- printk(KERN_ERR "%s: reset: master: ", hwif->name);
- if (err_master && err_master < 6)
- printk(KERN_CONT "%s", err_master_vals[err_master]);
- else
- printk(KERN_CONT "error (0x%02x?)", err);
- if (err & 0x80)
- printk(KERN_CONT "; slave: failed");
- printk(KERN_CONT "\n");
-}
-
-/*
- * reset_pollfunc() gets invoked to poll the interface for completion every 50ms
- * during an ide reset operation. If the drives have not yet responded,
- * and we have not yet hit our maximum waiting time, then the timer is restarted
- * for another 50ms.
- */
-static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
- u8 tmp;
- int err = 0;
-
- if (port_ops && port_ops->reset_poll) {
- err = port_ops->reset_poll(drive);
- if (err) {
- printk(KERN_ERR "%s: host reset_poll failure for %s.\n",
- hwif->name, drive->name);
- goto out;
- }
- }
-
- tmp = hwif->tp_ops->read_status(hwif);
-
- if (!OK_STAT(tmp, 0, ATA_BUSY)) {
- if (time_before(jiffies, hwif->poll_timeout)) {
- ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
- /* continue polling */
- return ide_started;
- }
- printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp);
- drive->failures++;
- err = -EIO;
- } else {
- tmp = ide_read_error(drive);
-
- if (tmp == 1) {
- printk(KERN_INFO "%s: reset: success\n", hwif->name);
- drive->failures = 0;
- } else {
- ide_reset_report_error(hwif, tmp);
- drive->failures++;
- err = -EIO;
- }
- }
-out:
- hwif->polling = 0; /* done polling */
- ide_complete_drive_reset(drive, err);
- return ide_stopped;
-}
-
-static void ide_disk_pre_reset(ide_drive_t *drive)
-{
- int legacy = (drive->id[ATA_ID_CFS_ENABLE_2] & 0x0400) ? 0 : 1;
-
- drive->special.all = 0;
- drive->special.b.set_geometry = legacy;
- drive->special.b.recalibrate = legacy;
-
- drive->mult_count = 0;
- drive->dev_flags &= ~IDE_DFLAG_PARKED;
-
- if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 &&
- (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0)
- drive->mult_req = 0;
-
- if (drive->mult_req != drive->mult_count)
- drive->special.b.set_multmode = 1;
-}
-
-static void pre_reset(ide_drive_t *drive)
-{
- const struct ide_port_ops *port_ops = drive->hwif->port_ops;
-
- if (drive->media == ide_disk)
- ide_disk_pre_reset(drive);
- else
- drive->dev_flags |= IDE_DFLAG_POST_RESET;
-
- if (drive->dev_flags & IDE_DFLAG_USING_DMA) {
- if (drive->crc_count)
- ide_check_dma_crc(drive);
- else
- ide_dma_off(drive);
- }
-
- if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) {
- if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) {
- drive->dev_flags &= ~IDE_DFLAG_UNMASK;
- drive->io_32bit = 0;
- }
- return;
- }
-
- if (port_ops && port_ops->pre_reset)
- port_ops->pre_reset(drive);
-
- if (drive->current_speed != 0xff)
- drive->desired_speed = drive->current_speed;
- drive->current_speed = 0xff;
-}
-
-/*
- * do_reset1() attempts to recover a confused drive by resetting it.
- * Unfortunately, resetting a disk drive actually resets all devices on
- * the same interface, so it can really be thought of as resetting the
- * interface rather than resetting the drive.
- *
- * ATAPI devices have their own reset mechanism which allows them to be
- * individually reset without clobbering other devices on the same interface.
- *
- * Unfortunately, the IDE interface does not generate an interrupt to let
- * us know when the reset operation has finished, so we must poll for this.
- * Equally poor, though, is the fact that this may a very long time to complete,
- * (up to 30 seconds worstcase). So, instead of busy-waiting here for it,
- * we set a timer to poll at 50ms intervals.
- */
-static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- const struct ide_port_ops *port_ops;
- ide_drive_t *tdrive;
- unsigned long flags, timeout;
- int i;
- DEFINE_WAIT(wait);
-
- spin_lock_irqsave(&hwif->lock, flags);
-
- /* We must not reset with running handlers */
- BUG_ON(hwif->handler != NULL);
-
- /* For an ATAPI device, first try an ATAPI SRST. */
- if (drive->media != ide_disk && !do_not_try_atapi) {
- pre_reset(drive);
- SELECT_DRIVE(drive);
- udelay (20);
- tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
- ndelay(400);
- hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
- hwif->polling = 1;
- __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
- spin_unlock_irqrestore(&hwif->lock, flags);
- return ide_started;
- }
-
- /* We must not disturb devices in the IDE_DFLAG_PARKED state. */
- do {
- unsigned long now;
-
- prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE);
- timeout = jiffies;
- ide_port_for_each_dev(i, tdrive, hwif) {
- if (tdrive->dev_flags & IDE_DFLAG_PRESENT &&
- tdrive->dev_flags & IDE_DFLAG_PARKED &&
- time_after(tdrive->sleep, timeout))
- timeout = tdrive->sleep;
- }
-
- now = jiffies;
- if (time_before_eq(timeout, now))
- break;
-
- spin_unlock_irqrestore(&hwif->lock, flags);
- timeout = schedule_timeout_uninterruptible(timeout - now);
- spin_lock_irqsave(&hwif->lock, flags);
- } while (timeout);
- finish_wait(&ide_park_wq, &wait);
-
- /*
- * First, reset any device state data we were maintaining
- * for any of the drives on this interface.
- */
- ide_port_for_each_dev(i, tdrive, hwif)
- pre_reset(tdrive);
-
- if (io_ports->ctl_addr == 0) {
- spin_unlock_irqrestore(&hwif->lock, flags);
- ide_complete_drive_reset(drive, -ENXIO);
- return ide_stopped;
- }
-
- /*
- * Note that we also set nIEN while resetting the device,
- * to mask unwanted interrupts from the interface during the reset.
- * However, due to the design of PC hardware, this will cause an
- * immediate interrupt due to the edge transition it produces.
- * This single interrupt gives us a "fast poll" for drives that
- * recover from reset very quickly, saving us the first 50ms wait time.
- *
- * TODO: add ->softreset method and stop abusing ->set_irq
- */
- /* set SRST and nIEN */
- tp_ops->set_irq(hwif, 4);
- /* more than enough time */
- udelay(10);
- /* clear SRST, leave nIEN (unless device is on the quirk list) */
- tp_ops->set_irq(hwif, drive->quirk_list == 2);
- /* more than enough time */
- udelay(10);
- hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
- hwif->polling = 1;
- __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
-
- /*
- * Some weird controller like resetting themselves to a strange
- * state when the disks are reset this way. At least, the Winbond
- * 553 documentation says that
- */
- port_ops = hwif->port_ops;
- if (port_ops && port_ops->resetproc)
- port_ops->resetproc(drive);
-
- spin_unlock_irqrestore(&hwif->lock, flags);
- return ide_started;
-}
-
-/*
- * ide_do_reset() is the entry point to the drive/interface reset code.
- */
-
-ide_startstop_t ide_do_reset (ide_drive_t *drive)
-{
- return do_reset1(drive, 0);
-}
-
-EXPORT_SYMBOL(ide_do_reset);
/*
* ide_wait_not_busy() waits for the currently selected device on the hwif
@@ -1187,7 +488,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout)
{
u8 stat = 0;
- while(timeout--) {
+ while (timeout--) {
/*
* Turn this into a schedule() sleep once I'm sure
* about locking issues (2.5 work ?).
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 09526a0de734..217b7fdf2b17 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -5,163 +5,6 @@
#include <linux/ide.h>
#include <linux/bitops.h>
-static const char *udma_str[] =
- { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44",
- "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
-static const char *mwdma_str[] =
- { "MWDMA0", "MWDMA1", "MWDMA2" };
-static const char *swdma_str[] =
- { "SWDMA0", "SWDMA1", "SWDMA2" };
-static const char *pio_str[] =
- { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" };
-
-/**
- * ide_xfer_verbose - return IDE mode names
- * @mode: transfer mode
- *
- * Returns a constant string giving the name of the mode
- * requested.
- */
-
-const char *ide_xfer_verbose(u8 mode)
-{
- const char *s;
- u8 i = mode & 0xf;
-
- if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
- s = udma_str[i];
- else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2)
- s = mwdma_str[i];
- else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
- s = swdma_str[i];
- else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5)
- s = pio_str[i & 0x7];
- else if (mode == XFER_PIO_SLOW)
- s = "PIO SLOW";
- else
- s = "XFER ERROR";
-
- return s;
-}
-EXPORT_SYMBOL(ide_xfer_verbose);
-
-/**
- * ide_rate_filter - filter transfer mode
- * @drive: IDE device
- * @speed: desired speed
- *
- * Given the available transfer modes this function returns
- * the best available speed at or below the speed requested.
- *
- * TODO: check device PIO capabilities
- */
-
-static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
-{
- ide_hwif_t *hwif = drive->hwif;
- u8 mode = ide_find_dma_mode(drive, speed);
-
- if (mode == 0) {
- if (hwif->pio_mask)
- mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0;
- else
- mode = XFER_PIO_4;
- }
-
-/* printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */
-
- return min(speed, mode);
-}
-
-/**
- * ide_get_best_pio_mode - get PIO mode from drive
- * @drive: drive to consider
- * @mode_wanted: preferred mode
- * @max_mode: highest allowed mode
- *
- * This routine returns the recommended PIO settings for a given drive,
- * based on the drive->id information and the ide_pio_blacklist[].
- *
- * Drive PIO mode is auto-selected if 255 is passed as mode_wanted.
- * This is used by most chipset support modules when "auto-tuning".
- */
-
-u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
-{
- u16 *id = drive->id;
- int pio_mode = -1, overridden = 0;
-
- if (mode_wanted != 255)
- return min_t(u8, mode_wanted, max_mode);
-
- if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0)
- pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]);
-
- if (pio_mode != -1) {
- printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name);
- } else {
- pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8;
- if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */
- pio_mode = 2;
- overridden = 1;
- }
-
- if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */
- if (ata_id_has_iordy(id)) {
- if (id[ATA_ID_PIO_MODES] & 7) {
- overridden = 0;
- if (id[ATA_ID_PIO_MODES] & 4)
- pio_mode = 5;
- else if (id[ATA_ID_PIO_MODES] & 2)
- pio_mode = 4;
- else
- pio_mode = 3;
- }
- }
- }
-
- if (overridden)
- printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
- drive->name);
- }
-
- if (pio_mode > max_mode)
- pio_mode = max_mode;
-
- return pio_mode;
-}
-EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
-
-/* req_pio == "255" for auto-tune */
-void ide_set_pio(ide_drive_t *drive, u8 req_pio)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
- u8 host_pio, pio;
-
- if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
- (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
- return;
-
- BUG_ON(hwif->pio_mask == 0x00);
-
- host_pio = fls(hwif->pio_mask) - 1;
-
- pio = ide_get_best_pio_mode(drive, req_pio, host_pio);
-
- /*
- * TODO:
- * - report device max PIO mode
- * - check req_pio != 255 against device max PIO mode
- */
- printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n",
- drive->name, host_pio, req_pio,
- req_pio == 255 ? "(auto-tune)" : "", pio);
-
- (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
-}
-EXPORT_SYMBOL_GPL(ide_set_pio);
-
/**
* ide_toggle_bounce - handle bounce buffering
* @drive: drive to update
@@ -188,105 +31,22 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
blk_queue_bounce_limit(drive->queue, addr);
}
-int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
-
- if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
- return 0;
-
- if (port_ops == NULL || port_ops->set_pio_mode == NULL)
- return -1;
-
- /*
- * TODO: temporary hack for some legacy host drivers that didn't
- * set transfer mode on the device in ->set_pio_mode method...
- */
- if (port_ops->set_dma_mode == NULL) {
- port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
- return 0;
- }
-
- if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
- if (ide_config_drive_speed(drive, mode))
- return -1;
- port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
- return 0;
- } else {
- port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
- return ide_config_drive_speed(drive, mode);
- }
-}
-
-int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
-
- if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
- return 0;
-
- if (port_ops == NULL || port_ops->set_dma_mode == NULL)
- return -1;
-
- if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
- if (ide_config_drive_speed(drive, mode))
- return -1;
- port_ops->set_dma_mode(drive, mode);
- return 0;
- } else {
- port_ops->set_dma_mode(drive, mode);
- return ide_config_drive_speed(drive, mode);
- }
-}
-EXPORT_SYMBOL_GPL(ide_set_dma_mode);
-
-/**
- * ide_set_xfer_rate - set transfer rate
- * @drive: drive to set
- * @rate: speed to attempt to set
- *
- * General helper for setting the speed of an IDE device. This
- * function knows about user enforced limits from the configuration
- * which ->set_pio_mode/->set_dma_mode does not.
- */
-
-int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
-
- if (port_ops == NULL || port_ops->set_dma_mode == NULL ||
- (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
- return -1;
-
- rate = ide_rate_filter(drive, rate);
-
- BUG_ON(rate < XFER_PIO_0);
-
- if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
- return ide_set_pio_mode(drive, rate);
-
- return ide_set_dma_mode(drive, rate);
-}
-
static void ide_dump_opcode(ide_drive_t *drive)
{
struct request *rq = drive->hwif->rq;
- ide_task_t *task = NULL;
+ struct ide_cmd *cmd = NULL;
if (!rq)
return;
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
- task = rq->special;
+ cmd = rq->special;
printk(KERN_ERR "ide: failed opcode was: ");
- if (task == NULL)
+ if (cmd == NULL)
printk(KERN_CONT "unknown\n");
else
- printk(KERN_CONT "0x%02x\n", task->tf.command);
+ printk(KERN_CONT "0x%02x\n", cmd->tf.command);
}
u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48)
@@ -306,18 +66,18 @@ EXPORT_SYMBOL_GPL(ide_get_lba_addr);
static void ide_dump_sector(ide_drive_t *drive)
{
- ide_task_t task;
- struct ide_taskfile *tf = &task.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
- memset(&task, 0, sizeof(task));
+ memset(&cmd, 0, sizeof(cmd));
if (lba48)
- task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA |
+ cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA |
IDE_TFLAG_LBA48;
else
- task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE;
+ cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE;
- drive->hwif->tp_ops->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
if (lba48 || (tf->device & ATA_LBA))
printk(KERN_CONT ", LBAsect=%llu",
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index c875a957596c..9490b446519f 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -60,6 +60,32 @@ out:
return;
}
+ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq)
+{
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
+
+ memset(&cmd, 0, sizeof(cmd));
+ if (rq->cmd[0] == REQ_PARK_HEADS) {
+ drive->sleep = *(unsigned long *)rq->special;
+ drive->dev_flags |= IDE_DFLAG_SLEEPING;
+ tf->command = ATA_CMD_IDLEIMMEDIATE;
+ tf->feature = 0x44;
+ tf->lbal = 0x4c;
+ tf->lbam = 0x4e;
+ tf->lbah = 0x55;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ } else /* cmd == REQ_UNPARK_HEADS */
+ tf->command = ATA_CMD_CHK_POWER;
+
+ cmd.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER;
+ cmd.protocol = ATA_PROT_NODATA;
+
+ cmd.rq = rq;
+
+ return do_rw_taskfile(drive, &cmd);
+}
+
ssize_t ide_park_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
diff --git a/drivers/ide/ide-pci-generic.c b/drivers/ide/ide-pci-generic.c
index bddae2b329a0..61111fd27130 100644
--- a/drivers/ide/ide-pci-generic.c
+++ b/drivers/ide/ide-pci-generic.c
@@ -33,8 +33,6 @@ static int ide_generic_all; /* Set to claim all devices */
module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
-#define IDE_HFLAGS_UMC (IDE_HFLAG_NO_DMA | IDE_HFLAG_FORCE_LEGACY_IRQS)
-
#define DECLARE_GENERIC_PCI_DEV(extra_flags) \
{ \
.name = DRV_NAME, \
@@ -61,7 +59,7 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
/* 2: SAMURAI / HT6565 / HINT_IDE */
DECLARE_GENERIC_PCI_DEV(0),
/* 3: UM8673F / UM8886A / UM8886BF */
- DECLARE_GENERIC_PCI_DEV(IDE_HFLAGS_UMC),
+ DECLARE_GENERIC_PCI_DEV(IDE_HFLAG_NO_DMA),
/* 4: VIA_IDE / OPTI621V / Piccolo010{2,3,5} */
DECLARE_GENERIC_PCI_DEV(IDE_HFLAG_NO_AUTODMA),
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c
index 60538d9c84ee..bb7858ebb7d1 100644
--- a/drivers/ide/ide-pm.c
+++ b/drivers/ide/ide-pm.c
@@ -1,6 +1,5 @@
#include <linux/kernel.h>
#include <linux/ide.h>
-#include <linux/hdreg.h>
int generic_ide_suspend(struct device *dev, pm_message_t mesg)
{
@@ -8,7 +7,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
ide_hwif_t *hwif = drive->hwif;
struct request *rq;
struct request_pm_state rqpm;
- ide_task_t args;
+ struct ide_cmd cmd;
int ret;
/* call ACPI _GTM only once */
@@ -16,10 +15,10 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
ide_acpi_get_timing(hwif);
memset(&rqpm, 0, sizeof(rqpm));
- memset(&args, 0, sizeof(args));
+ memset(&cmd, 0, sizeof(cmd));
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_PM_SUSPEND;
- rq->special = &args;
+ rq->special = &cmd;
rq->data = &rqpm;
rqpm.pm_step = IDE_PM_START_SUSPEND;
if (mesg.event == PM_EVENT_PRETHAW)
@@ -42,7 +41,7 @@ int generic_ide_resume(struct device *dev)
ide_hwif_t *hwif = drive->hwif;
struct request *rq;
struct request_pm_state rqpm;
- ide_task_t args;
+ struct ide_cmd cmd;
int err;
/* call ACPI _PS0 / _STM only once */
@@ -54,11 +53,11 @@ int generic_ide_resume(struct device *dev)
ide_acpi_exec_tfs(drive);
memset(&rqpm, 0, sizeof(rqpm));
- memset(&args, 0, sizeof(args));
+ memset(&cmd, 0, sizeof(cmd));
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_PM_RESUME;
rq->cmd_flags |= REQ_PREEMPT;
- rq->special = &args;
+ rq->special = &cmd;
rq->data = &rqpm;
rqpm.pm_step = IDE_PM_START_RESUME;
rqpm.pm_state = PM_EVENT_ON;
@@ -109,9 +108,9 @@ void ide_complete_power_step(ide_drive_t *drive, struct request *rq)
ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
{
struct request_pm_state *pm = rq->data;
- ide_task_t *args = rq->special;
+ struct ide_cmd *cmd = rq->special;
- memset(args, 0, sizeof(*args));
+ memset(cmd, 0, sizeof(*cmd));
switch (pm->pm_step) {
case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */
@@ -124,12 +123,12 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
return ide_stopped;
}
if (ata_id_flush_ext_enabled(drive->id))
- args->tf.command = ATA_CMD_FLUSH_EXT;
+ cmd->tf.command = ATA_CMD_FLUSH_EXT;
else
- args->tf.command = ATA_CMD_FLUSH;
+ cmd->tf.command = ATA_CMD_FLUSH;
goto out_do_tf;
case IDE_PM_STANDBY: /* Suspend step 2 (standby) */
- args->tf.command = ATA_CMD_STANDBYNOW1;
+ cmd->tf.command = ATA_CMD_STANDBYNOW1;
goto out_do_tf;
case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */
ide_set_max_pio(drive);
@@ -142,7 +141,7 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
ide_complete_power_step(drive, rq);
return ide_stopped;
case IDE_PM_IDLE: /* Resume step 2 (idle) */
- args->tf.command = ATA_CMD_IDLEIMMEDIATE;
+ cmd->tf.command = ATA_CMD_IDLEIMMEDIATE;
goto out_do_tf;
case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */
/*
@@ -160,27 +159,34 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
}
pm->pm_step = IDE_PM_COMPLETED;
+
return ide_stopped;
out_do_tf:
- args->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- args->data_phase = TASKFILE_NO_DATA;
- return do_rw_taskfile(drive, args);
+ cmd->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd->protocol = ATA_PROT_NODATA;
+
+ return do_rw_taskfile(drive, cmd);
}
/**
- * ide_complete_pm_request - end the current Power Management request
+ * ide_complete_pm_rq - end the current Power Management request
* @drive: target drive
* @rq: request
*
* This function cleans up the current PM request and stops the queue
* if necessary.
*/
-void ide_complete_pm_request(ide_drive_t *drive, struct request *rq)
+void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
{
struct request_queue *q = drive->queue;
+ struct request_pm_state *pm = rq->data;
unsigned long flags;
+ ide_complete_power_step(drive, rq);
+ if (pm->pm_step != IDE_PM_COMPLETED)
+ return;
+
#ifdef DEBUG_PM
printk("%s: completing PM request, %s\n", drive->name,
blk_pm_suspend_request(rq) ? "suspend" : "resume");
@@ -217,6 +223,7 @@ void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
* point.
*/
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
struct request_queue *q = drive->queue;
unsigned long flags;
int rc;
@@ -226,8 +233,8 @@ void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
rc = ide_wait_not_busy(hwif, 35000);
if (rc)
printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
- SELECT_DRIVE(drive);
- hwif->tp_ops->set_irq(hwif, 1);
+ tp_ops->dev_select(drive);
+ tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
rc = ide_wait_not_busy(hwif, 100000);
if (rc)
printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
index bac9b392b689..6e80b774e88a 100644
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -27,6 +27,10 @@ static struct pnp_device_id idepnp_devices[] = {
{.id = ""}
};
+static const struct ide_port_info ide_pnp_port_info = {
+ .host_flags = IDE_HFLAG_NO_DMA,
+};
+
static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
struct ide_host *host;
@@ -60,7 +64,7 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
hw.irq = pnp_irq(dev, 0);
hw.chipset = ide_generic;
- rc = ide_host_add(NULL, hws, &host);
+ rc = ide_host_add(&ide_pnp_port_info, hws, &host);
if (rc)
goto out;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index ee8e3e7cad51..d8c1c3e735bb 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -181,16 +181,16 @@ static void ide_classify_atapi_dev(ide_drive_t *drive)
* do_identify - identify a drive
* @drive: drive to identify
* @cmd: command used
+ * @id: buffer for IDENTIFY data
*
* Called when we have issued a drive identify command to
* read and parse the results. This function is run with
* interrupts disabled.
*/
-static void do_identify(ide_drive_t *drive, u8 cmd)
+static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
{
ide_hwif_t *hwif = drive->hwif;
- u16 *id = drive->id;
char *m = (char *)&id[ATA_ID_PROD];
unsigned long flags;
int bswap = 1;
@@ -228,43 +228,25 @@ static void do_identify(ide_drive_t *drive, u8 cmd)
m[ATA_ID_PROD_LEN - 1] = '\0';
if (strstr(m, "E X A B Y T E N E S T"))
- goto err_misc;
-
- drive->dev_flags |= IDE_DFLAG_PRESENT;
- drive->dev_flags &= ~IDE_DFLAG_DEAD;
-
- /*
- * Check for an ATAPI device
- */
- if (cmd == ATA_CMD_ID_ATAPI)
- ide_classify_atapi_dev(drive);
+ drive->dev_flags &= ~IDE_DFLAG_PRESENT;
else
- /*
- * Not an ATAPI device: looks like a "regular" hard disk
- */
- ide_classify_ata_dev(drive);
- return;
-err_misc:
- kfree(id);
- drive->dev_flags &= ~IDE_DFLAG_PRESENT;
+ drive->dev_flags |= IDE_DFLAG_PRESENT;
}
/**
- * actual_try_to_identify - send ata/atapi identify
+ * ide_dev_read_id - send ATA/ATAPI IDENTIFY command
* @drive: drive to identify
* @cmd: command to use
+ * @id: buffer for IDENTIFY data
*
- * try_to_identify() sends an ATA(PI) IDENTIFY request to a drive
- * and waits for a response. It also monitors irqs while this is
- * happening, in hope of automatically determining which one is
- * being used by the interface.
+ * Sends an ATA(PI) IDENTIFY request to a drive and waits for a response.
*
* Returns: 0 device was identified
* 1 device timed-out (no response to identify request)
* 2 device aborted the command (refused to identify itself)
*/
-static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
+int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
@@ -273,6 +255,13 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
unsigned long timeout;
u8 s = 0, a = 0;
+ /*
+ * Disable device IRQ. Otherwise we'll get spurious interrupts
+ * during the identify phase that the IRQ handler isn't expecting.
+ */
+ if (io_ports->ctl_addr)
+ tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
+
/* take a deep breath */
msleep(50);
@@ -294,13 +283,13 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
* identify command to be sure of reply
*/
if (cmd == ATA_CMD_ID_ATAPI) {
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
+ memset(&cmd, 0, sizeof(cmd));
/* disable DMA & overlap */
- task.tf_flags = IDE_TFLAG_OUT_FEATURE;
+ cmd.tf_flags = IDE_TFLAG_OUT_FEATURE;
- tp_ops->tf_load(drive, &task);
+ tp_ops->tf_load(drive, &cmd);
}
/* ask drive for ID */
@@ -317,7 +306,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
/* drive returned ID */
- do_identify(drive, cmd);
+ do_identify(drive, cmd, id);
/* drive responded with ID */
rc = 0;
/* clear drive IRQ */
@@ -329,63 +318,6 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
return rc;
}
-/**
- * try_to_identify - try to identify a drive
- * @drive: drive to probe
- * @cmd: command to use
- *
- * Issue the identify command and then do IRQ probing to
- * complete the identification when needed by finding the
- * IRQ the drive is attached to
- */
-
-static int try_to_identify (ide_drive_t *drive, u8 cmd)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- int retval;
- int autoprobe = 0;
- unsigned long cookie = 0;
-
- /*
- * Disable device irq unless we need to
- * probe for it. Otherwise we'll get spurious
- * interrupts during the identify-phase that
- * the irq handler isn't expecting.
- */
- if (hwif->io_ports.ctl_addr) {
- if (!hwif->irq) {
- autoprobe = 1;
- cookie = probe_irq_on();
- }
- tp_ops->set_irq(hwif, autoprobe);
- }
-
- retval = actual_try_to_identify(drive, cmd);
-
- if (autoprobe) {
- int irq;
-
- tp_ops->set_irq(hwif, 0);
- /* clear drive IRQ */
- (void)tp_ops->read_status(hwif);
- udelay(5);
- irq = probe_irq_off(cookie);
- if (!hwif->irq) {
- if (irq > 0) {
- hwif->irq = irq;
- } else {
- /* Mmmm.. multiple IRQs..
- * don't know which was ours
- */
- printk(KERN_ERR "%s: IRQ probe failed (0x%lx)\n",
- drive->name, cookie);
- }
- }
- }
- return retval;
-}
-
int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus)
{
u8 stat;
@@ -405,14 +337,14 @@ int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus)
static u8 ide_read_device(ide_drive_t *drive)
{
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_IN_DEVICE;
- drive->hwif->tp_ops->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
- return task.tf.device;
+ return cmd.tf.device;
}
/**
@@ -440,6 +372,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
+ u16 *id = drive->id;
int rc;
u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat;
@@ -457,13 +390,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
* (e.g. crw9624 as drive0 with disk as slave)
*/
msleep(50);
- SELECT_DRIVE(drive);
+ tp_ops->dev_select(drive);
msleep(50);
if (ide_read_device(drive) != drive->select && present == 0) {
if (drive->dn & 1) {
/* exit with drive0 selected */
- SELECT_DRIVE(hwif->devices[0]);
+ tp_ops->dev_select(hwif->devices[0]);
/* allow ATA_BUSY to assert & clear */
msleep(50);
}
@@ -475,11 +408,10 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
present || cmd == ATA_CMD_ID_ATAPI) {
- /* send cmd and wait */
- if ((rc = try_to_identify(drive, cmd))) {
+ rc = ide_dev_read_id(drive, cmd, id);
+ if (rc)
/* failed: try again */
- rc = try_to_identify(drive,cmd);
- }
+ rc = ide_dev_read_id(drive, cmd, id);
stat = tp_ops->read_status(hwif);
@@ -490,11 +422,11 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
printk(KERN_ERR "%s: no response (status = 0x%02x), "
"resetting drive\n", drive->name, stat);
msleep(50);
- SELECT_DRIVE(drive);
+ tp_ops->dev_select(drive);
msleep(50);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
(void)ide_busy_sleep(hwif, WAIT_WORSTCASE, 0);
- rc = try_to_identify(drive, cmd);
+ rc = ide_dev_read_id(drive, cmd, id);
}
/* ensure drive IRQ is clear */
@@ -509,7 +441,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
}
if (drive->dn & 1) {
/* exit with drive0 selected */
- SELECT_DRIVE(hwif->devices[0]);
+ tp_ops->dev_select(hwif->devices[0]);
msleep(50);
/* ensure drive irq is clear */
(void)tp_ops->read_status(hwif);
@@ -517,37 +449,6 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
return rc;
}
-/*
- *
- */
-static void enable_nest (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- u8 stat;
-
- printk(KERN_INFO "%s: enabling %s -- ",
- hwif->name, (char *)&drive->id[ATA_ID_PROD]);
-
- SELECT_DRIVE(drive);
- msleep(50);
- tp_ops->exec_command(hwif, ATA_EXABYTE_ENABLE_NEST);
-
- if (ide_busy_sleep(hwif, WAIT_WORSTCASE, 0)) {
- printk(KERN_CONT "failed (timeout)\n");
- return;
- }
-
- msleep(50);
-
- stat = tp_ops->read_status(hwif);
-
- if (!OK_STAT(stat, 0, BAD_STAT))
- printk(KERN_CONT "failed (status = 0x%02x)\n", stat);
- else
- printk(KERN_CONT "success\n");
-}
-
/**
* probe_for_drives - upper level drive probe
* @drive: drive to probe for
@@ -563,6 +464,8 @@ static void enable_nest (ide_drive_t *drive)
static u8 probe_for_drive(ide_drive_t *drive)
{
char *m;
+ int rc;
+ u8 cmd;
/*
* In order to keep things simple we have an id
@@ -586,20 +489,17 @@ static u8 probe_for_drive(ide_drive_t *drive)
/* skip probing? */
if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0) {
-retry:
/* if !(success||timed-out) */
- if (do_probe(drive, ATA_CMD_ID_ATA) >= 2)
+ cmd = ATA_CMD_ID_ATA;
+ rc = do_probe(drive, cmd);
+ if (rc >= 2) {
/* look for ATAPI device */
- (void)do_probe(drive, ATA_CMD_ID_ATAPI);
+ cmd = ATA_CMD_ID_ATAPI;
+ rc = do_probe(drive, cmd);
+ }
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- /* drive not found */
- return 0;
-
- if (strstr(m, "E X A B Y T E N E S T")) {
- enable_nest(drive);
- goto retry;
- }
+ goto out_free;
/* identification failed? */
if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
@@ -614,12 +514,16 @@ retry:
printk(KERN_WARNING "%s: Unknown device on bus refused identification. Ignoring.\n", drive->name);
drive->dev_flags &= ~IDE_DFLAG_PRESENT;
}
+ } else {
+ if (cmd == ATA_CMD_ID_ATAPI)
+ ide_classify_atapi_dev(drive);
+ else
+ ide_classify_ata_dev(drive);
}
- /* drive was found */
}
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- return 0;
+ goto out_free;
/* The drive wasn't being helpful. Add generic info only */
if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
@@ -632,7 +536,10 @@ retry:
ide_disk_init_mult_count(drive);
}
- return !!(drive->dev_flags & IDE_DFLAG_PRESENT);
+ return 1;
+out_free:
+ kfree(drive->id);
+ return 0;
}
static void hwif_release_dev(struct device *dev)
@@ -698,6 +605,7 @@ out:
static int ide_port_wait_ready(ide_hwif_t *hwif)
{
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
ide_drive_t *drive;
int i, rc;
@@ -720,8 +628,8 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
/* Ignore disks that we will not probe for later. */
if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 ||
(drive->dev_flags & IDE_DFLAG_PRESENT)) {
- SELECT_DRIVE(drive);
- hwif->tp_ops->set_irq(hwif, 1);
+ tp_ops->dev_select(drive);
+ tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
mdelay(2);
rc = ide_wait_not_busy(hwif, 35000);
if (rc)
@@ -733,7 +641,7 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
out:
/* Exit function with master reselected (let's be sane) */
if (i)
- SELECT_DRIVE(hwif->devices[0]);
+ tp_ops->dev_select(hwif->devices[0]);
return rc;
}
@@ -779,7 +687,6 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
static int ide_probe_port(ide_hwif_t *hwif)
{
ide_drive_t *drive;
- unsigned long flags;
unsigned int irqd;
int i, rc = -ENODEV;
@@ -797,9 +704,6 @@ static int ide_probe_port(ide_hwif_t *hwif)
if (irqd)
disable_irq(hwif->irq);
- local_save_flags(flags);
- local_irq_enable_in_hardirq();
-
if (ide_port_wait_ready(hwif) == -EBUSY)
printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
@@ -813,8 +717,6 @@ static int ide_probe_port(ide_hwif_t *hwif)
rc = 0;
}
- local_irq_restore(flags);
-
/*
* Use cached IRQ number. It might be (and is...) changed by probe
* code above
@@ -831,29 +733,18 @@ static void ide_port_tune_devices(ide_hwif_t *hwif)
ide_drive_t *drive;
int i;
- ide_port_for_each_dev(i, drive, hwif) {
- if (drive->dev_flags & IDE_DFLAG_PRESENT) {
- if (port_ops && port_ops->quirkproc)
- port_ops->quirkproc(drive);
- }
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ if (port_ops && port_ops->quirkproc)
+ port_ops->quirkproc(drive);
}
- ide_port_for_each_dev(i, drive, hwif) {
- if (drive->dev_flags & IDE_DFLAG_PRESENT) {
- ide_set_max_pio(drive);
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ ide_set_max_pio(drive);
- drive->dev_flags |= IDE_DFLAG_NICE1;
+ drive->dev_flags |= IDE_DFLAG_NICE1;
- if (hwif->dma_ops)
- ide_set_dma(drive);
- }
- }
-
- ide_port_for_each_dev(i, drive, hwif) {
- if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
- drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
- else
- drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT;
+ if (hwif->dma_ops)
+ ide_set_dma(drive);
}
}
@@ -924,10 +815,7 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
int i, j = 0;
mutex_lock(&ide_cfg_mtx);
- ide_port_for_each_dev(i, drive, hwif) {
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- continue;
-
+ ide_port_for_each_present_dev(i, drive, hwif) {
if (ide_init_queue(drive)) {
printk(KERN_ERR "ide: failed to init %s\n",
drive->name);
@@ -950,41 +838,19 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
static int init_irq (ide_hwif_t *hwif)
{
struct ide_io_ports *io_ports = &hwif->io_ports;
- irq_handler_t irq_handler;
- int sa = 0;
-
- mutex_lock(&ide_cfg_mtx);
- spin_lock_init(&hwif->lock);
-
- init_timer(&hwif->timer);
- hwif->timer.function = &ide_timer_expiry;
- hwif->timer.data = (unsigned long)hwif;
+ struct ide_host *host = hwif->host;
+ irq_handler_t irq_handler = host->irq_handler;
+ int sa = host->irq_flags;
- irq_handler = hwif->host->irq_handler;
if (irq_handler == NULL)
irq_handler = ide_intr;
-#if defined(__mc68000__)
- sa = IRQF_SHARED;
-#endif /* __mc68000__ */
-
- if (hwif->chipset == ide_pci)
- sa = IRQF_SHARED;
-
if (io_ports->ctl_addr)
- hwif->tp_ops->set_irq(hwif, 1);
+ hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
goto out_up;
- if (!hwif->rqsize) {
- if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
- (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
- hwif->rqsize = 256;
- else
- hwif->rqsize = 65536;
- }
-
#if !defined(__mc68000__)
printk(KERN_INFO "%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
io_ports->data_addr, io_ports->status_addr,
@@ -997,10 +863,8 @@ static int init_irq (ide_hwif_t *hwif)
printk(KERN_CONT " (serialized)");
printk(KERN_CONT "\n");
- mutex_unlock(&ide_cfg_mtx);
return 0;
out_up:
- mutex_unlock(&ide_cfg_mtx);
return 1;
}
@@ -1079,34 +943,25 @@ EXPORT_SYMBOL_GPL(ide_init_disk);
static void drive_release_dev (struct device *dev)
{
ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
- ide_hwif_t *hwif = drive->hwif;
ide_proc_unregister_device(drive);
- spin_lock_irq(&hwif->lock);
+ blk_cleanup_queue(drive->queue);
+ drive->queue = NULL;
+
kfree(drive->id);
drive->id = NULL;
+
drive->dev_flags &= ~IDE_DFLAG_PRESENT;
- /* Messed up locking ... */
- spin_unlock_irq(&hwif->lock);
- blk_cleanup_queue(drive->queue);
- spin_lock_irq(&hwif->lock);
- drive->queue = NULL;
- spin_unlock_irq(&hwif->lock);
complete(&drive->gendev_rel_comp);
}
static int hwif_init(ide_hwif_t *hwif)
{
- int old_irq;
-
if (!hwif->irq) {
- hwif->irq = __ide_default_irq(hwif->io_ports.data_addr);
- if (!hwif->irq) {
- printk(KERN_ERR "%s: disabled, no IRQ\n", hwif->name);
- return 0;
- }
+ printk(KERN_ERR "%s: disabled, no IRQ\n", hwif->name);
+ return 0;
}
if (register_blkdev(hwif->major, hwif->name))
@@ -1124,29 +979,12 @@ static int hwif_init(ide_hwif_t *hwif)
sg_init_table(hwif->sg_table, hwif->sg_max_nents);
- if (init_irq(hwif) == 0)
- goto done;
-
- old_irq = hwif->irq;
- /*
- * It failed to initialise. Find the default IRQ for
- * this port and try that.
- */
- hwif->irq = __ide_default_irq(hwif->io_ports.data_addr);
- if (!hwif->irq) {
- printk(KERN_ERR "%s: disabled, unable to get IRQ %d\n",
- hwif->name, old_irq);
- goto out;
- }
if (init_irq(hwif)) {
- printk(KERN_ERR "%s: probed IRQ %d and default IRQ %d failed\n",
- hwif->name, old_irq, hwif->irq);
+ printk(KERN_ERR "%s: disabled, unable to get IRQ %d\n",
+ hwif->name, hwif->irq);
goto out;
}
- printk(KERN_WARNING "%s: probed IRQ %d failed, using default\n",
- hwif->name, hwif->irq);
-done:
blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
THIS_MODULE, ata_probe, ata_lock, hwif);
return 1;
@@ -1161,13 +999,10 @@ static void hwif_register_devices(ide_hwif_t *hwif)
ide_drive_t *drive;
unsigned int i;
- ide_port_for_each_dev(i, drive, hwif) {
+ ide_port_for_each_present_dev(i, drive, hwif) {
struct device *dev = &drive->gendev;
int ret;
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- continue;
-
dev_set_name(dev, "%u.%u", hwif->index, i);
dev->parent = &hwif->gendev;
dev->bus = &ide_bus_type;
@@ -1192,6 +1027,8 @@ static void ide_port_init_devices(ide_hwif_t *hwif)
if (hwif->host_flags & IDE_HFLAG_IO_32BIT)
drive->io_32bit = 1;
+ if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
+ drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS)
drive->dev_flags |= IDE_DFLAG_UNMASK;
if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
@@ -1213,10 +1050,6 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
if (d->init_iops)
d->init_iops(hwif);
- if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
- (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
- hwif->irq = port ? 15 : 14;
-
/* ->host_flags may be set by ->init_iops (or even earlier...) */
hwif->host_flags |= d->host_flags;
hwif->pio_mask = d->pio_mask;
@@ -1225,7 +1058,7 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
hwif->tp_ops = d->tp_ops;
/* ->set_pio_mode for DTC2278 is currently limited to port 0 */
- if (hwif->chipset != ide_dtc2278 || hwif->channel == 0)
+ if ((hwif->host_flags & IDE_HFLAG_DTC2278) == 0 || hwif->channel == 0)
hwif->port_ops = d->port_ops;
hwif->swdma_mask = d->swdma_mask;
@@ -1259,6 +1092,13 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
if (d->max_sectors)
hwif->rqsize = d->max_sectors;
+ else {
+ if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
+ (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
+ hwif->rqsize = 256;
+ else
+ hwif->rqsize = 65536;
+ }
/* call chipset specific routine for each enabled port */
if (d->init_hwif)
@@ -1317,6 +1157,12 @@ static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
hwif->name[2] = 'e';
hwif->name[3] = '0' + index;
+ spin_lock_init(&hwif->lock);
+
+ init_timer(&hwif->timer);
+ hwif->timer.function = &ide_timer_expiry;
+ hwif->timer.data = (unsigned long)hwif;
+
init_completion(&hwif->gendev_rel_comp);
hwif->tp_ops = &default_tp_ops;
@@ -1465,6 +1311,8 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
if (d) {
host->init_chipset = d->init_chipset;
+ host->get_lock = d->get_lock;
+ host->release_lock = d->release_lock;
host->host_flags = d->host_flags;
}
@@ -1511,20 +1359,15 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
ide_init_port_hw(hwif, hws[i]);
ide_port_apply_params(hwif);
- if (d == NULL) {
- mate = NULL;
- } else {
- if ((i & 1) && mate) {
- hwif->mate = mate;
- mate->mate = hwif;
- }
-
- mate = (i & 1) ? NULL : hwif;
-
- ide_init_port(hwif, i & 1, d);
- ide_port_cable_detect(hwif);
+ if ((i & 1) && mate) {
+ hwif->mate = mate;
+ mate->mate = hwif;
}
+ mate = (i & 1) ? NULL : hwif;
+
+ ide_init_port(hwif, i & 1, d);
+ ide_port_cable_detect(hwif);
ide_port_init_devices(hwif);
}
@@ -1535,8 +1378,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
if (ide_probe_port(hwif) == 0)
hwif->present = 1;
- if (hwif->chipset != ide_4drives || !hwif->mate ||
- !hwif->mate->present) {
+ if ((hwif->host_flags & IDE_HFLAG_4DRIVES) == 0 ||
+ hwif->mate == NULL || hwif->mate->present == 0) {
if (ide_register_port(hwif)) {
ide_disable_port(hwif);
continue;
@@ -1567,7 +1410,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
j++;
- ide_acpi_init(hwif);
+ ide_acpi_init_port(hwif);
if (hwif->present)
ide_acpi_port_init_devices(hwif);
@@ -1624,11 +1467,9 @@ static void __ide_port_unregister_devices(ide_hwif_t *hwif)
ide_drive_t *drive;
int i;
- ide_port_for_each_dev(i, drive, hwif) {
- if (drive->dev_flags & IDE_DFLAG_PRESENT) {
- device_unregister(&drive->gendev);
- wait_for_completion(&drive->gendev_rel_comp);
- }
+ ide_port_for_each_present_dev(i, drive, hwif) {
+ device_unregister(&drive->gendev);
+ wait_for_completion(&drive->gendev_rel_comp);
}
}
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index a7b9287ee0d4..10a88bf3eefa 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -194,20 +194,20 @@ ide_devset_get(xfer_rate, current_speed);
static int set_xfer_rate (ide_drive_t *drive, int arg)
{
- ide_task_t task;
+ struct ide_cmd cmd;
int err;
if (arg < XFER_PIO_0 || arg > XFER_UDMA_6)
return -EINVAL;
- memset(&task, 0, sizeof(task));
- task.tf.command = ATA_CMD_SET_FEATURES;
- task.tf.feature = SETFEATURES_XFER;
- task.tf.nsect = (u8)arg;
- task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
- IDE_TFLAG_IN_NSECT;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf.command = ATA_CMD_SET_FEATURES;
+ cmd.tf.feature = SETFEATURES_XFER;
+ cmd.tf.nsect = (u8)arg;
+ cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
+ IDE_TFLAG_IN_NSECT;
- err = ide_no_data_taskfile(drive, &task);
+ err = ide_no_data_taskfile(drive, &cmd);
if (!err) {
ide_set_xfer_rate(drive, (u8) arg);
@@ -600,7 +600,7 @@ void ide_proc_port_register_devices(ide_hwif_t *hwif)
int i;
ide_port_for_each_dev(i, drive, hwif) {
- if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0 || drive->proc)
+ if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
continue;
drive->proc = proc_mkdir(drive->name, parent);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 4e6181c7bbda..cb942a9b580f 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -152,11 +152,6 @@ struct idetape_bh {
#define IDETAPE_LU_RETENSION_MASK 2
#define IDETAPE_LU_EOT_MASK 4
-/* Error codes returned in rq->errors to the higher part of the driver. */
-#define IDETAPE_ERROR_GENERAL 101
-#define IDETAPE_ERROR_FILEMARK 102
-#define IDETAPE_ERROR_EOD 103
-
/* Structures related to the SELECT SENSE / MODE SENSE packet commands. */
#define IDETAPE_BLOCK_DESCRIPTOR 0
#define IDETAPE_CAPABILITIES_PAGE 0x2a
@@ -171,14 +166,6 @@ typedef struct ide_tape_obj {
struct gendisk *disk;
struct device dev;
- /*
- * failed_pc points to the last failed packet command, or contains
- * NULL if we do not need to retry any packet command. This is
- * required since an additional packet command is needed before the
- * retry, to get detailed information on what went wrong.
- */
- /* Last failed packet command */
- struct ide_atapi_pc *failed_pc;
/* used by REQ_IDETAPE_{READ,WRITE} requests */
struct ide_atapi_pc queued_pc;
@@ -245,9 +232,6 @@ typedef struct ide_tape_obj {
/* Wasted space in each stage */
int excess_bh_size;
- /* protects the ide-tape queue */
- spinlock_t lock;
-
/* Measures average tape speed */
unsigned long avg_time;
int avg_size;
@@ -313,19 +297,15 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
return tape;
}
-static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount)
{
struct idetape_bh *bh = pc->bh;
int count;
while (bcount) {
- if (bh == NULL) {
- printk(KERN_ERR "ide-tape: bh == NULL in "
- "idetape_input_buffers\n");
- ide_pad_transfer(drive, 0, bcount);
- return;
- }
+ if (bh == NULL)
+ break;
count = min(
(unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
bcount);
@@ -339,21 +319,21 @@ static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
atomic_set(&bh->b_count, 0);
}
}
+
pc->bh = bh;
+
+ return bcount;
}
-static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount)
{
struct idetape_bh *bh = pc->bh;
int count;
while (bcount) {
- if (bh == NULL) {
- printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
- __func__);
- return;
- }
+ if (bh == NULL)
+ break;
count = min((unsigned int)pc->b_count, (unsigned int)bcount);
drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count);
bcount -= count;
@@ -368,6 +348,8 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
}
}
}
+
+ return bcount;
}
static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
@@ -400,7 +382,7 @@ static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
{
idetape_tape_t *tape = drive->driver_data;
- struct ide_atapi_pc *pc = tape->failed_pc;
+ struct ide_atapi_pc *pc = drive->failed_pc;
tape->sense_key = sense[2] & 0xF;
tape->asc = sense[12];
@@ -433,19 +415,19 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
}
}
if (pc->c[0] == READ_6 && (sense[2] & 0x80)) {
- pc->error = IDETAPE_ERROR_FILEMARK;
+ pc->error = IDE_DRV_ERROR_FILEMARK;
pc->flags |= PC_FLAG_ABORT;
}
if (pc->c[0] == WRITE_6) {
if ((sense[2] & 0x40) || (tape->sense_key == 0xd
&& tape->asc == 0x0 && tape->ascq == 0x2)) {
- pc->error = IDETAPE_ERROR_EOD;
+ pc->error = IDE_DRV_ERROR_EOD;
pc->flags |= PC_FLAG_ABORT;
}
}
if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
if (tape->sense_key == 8) {
- pc->error = IDETAPE_ERROR_EOD;
+ pc->error = IDE_DRV_ERROR_EOD;
pc->flags |= PC_FLAG_ABORT;
}
if (!(pc->flags & PC_FLAG_ABORT) &&
@@ -477,52 +459,23 @@ static void ide_tape_kfree_buffer(idetape_tape_t *tape)
}
}
-static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
-{
- struct request *rq = drive->hwif->rq;
- idetape_tape_t *tape = drive->driver_data;
- unsigned long flags;
- int error;
-
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
-
- switch (uptodate) {
- case 0: error = IDETAPE_ERROR_GENERAL; break;
- case 1: error = 0; break;
- default: error = uptodate;
- }
- rq->errors = error;
- if (error)
- tape->failed_pc = NULL;
-
- if (!blk_special_request(rq)) {
- ide_end_request(drive, uptodate, nr_sects);
- return 0;
- }
-
- spin_lock_irqsave(&tape->lock, flags);
-
- ide_end_drive_cmd(drive, 0, 0);
-
- spin_unlock_irqrestore(&tape->lock, flags);
- return 0;
-}
-
static void ide_tape_handle_dsc(ide_drive_t *);
-static void ide_tape_callback(ide_drive_t *drive, int dsc)
+static int ide_tape_callback(ide_drive_t *drive, int dsc)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc *pc = drive->pc;
+ struct request *rq = drive->hwif->rq;
int uptodate = pc->error ? 0 : 1;
+ int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
debug_log(DBG_PROCS, "Enter %s\n", __func__);
if (dsc)
ide_tape_handle_dsc(drive);
- if (tape->failed_pc == pc)
- tape->failed_pc = NULL;
+ if (drive->failed_pc == pc)
+ drive->failed_pc = NULL;
if (pc->c[0] == REQUEST_SENSE) {
if (uptodate)
@@ -531,7 +484,6 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
printk(KERN_ERR "ide-tape: Error in REQUEST SENSE "
"itself - Aborting request!\n");
} else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
- struct request *rq = drive->hwif->rq;
int blocks = pc->xferred / tape->blk_size;
tape->avg_size += blocks * tape->blk_size;
@@ -546,8 +498,10 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
tape->first_frame += blocks;
rq->current_nr_sectors -= blocks;
- if (pc->error)
- uptodate = pc->error;
+ if (pc->error) {
+ uptodate = 0;
+ err = pc->error;
+ }
} else if (pc->c[0] == READ_POSITION && uptodate) {
u8 *readpos = pc->buf;
@@ -561,6 +515,7 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
"to the tape\n");
clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
uptodate = 0;
+ err = IDE_DRV_ERROR_GENERAL;
} else {
debug_log(DBG_SENSE, "Block Location - %u\n",
be32_to_cpup((__be32 *)&readpos[4]));
@@ -571,7 +526,9 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
}
}
- idetape_end_request(drive, uptodate, 0);
+ rq->errors = err;
+
+ return uptodate;
}
/*
@@ -604,12 +561,14 @@ static void ide_tape_handle_dsc(ide_drive_t *drive)
static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount, int write)
{
+ unsigned int bleft;
+
if (write)
- idetape_output_buffers(drive, pc, bcount);
+ bleft = idetape_output_buffers(drive, pc, bcount);
else
- idetape_input_buffers(drive, pc, bcount);
+ bleft = idetape_input_buffers(drive, pc, bcount);
- return bcount;
+ return bcount - bleft;
}
/*
@@ -621,7 +580,7 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
*
* The handling will be done in three stages:
*
- * 1. idetape_issue_pc will send the packet command to the drive, and will set
+ * 1. ide_tape_issue_pc will send the packet command to the drive, and will set
* the interrupt handler to ide_pc_intr.
*
* 2. On each interrupt, ide_pc_intr will be called. This step will be
@@ -649,8 +608,9 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
* request.
*/
-static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
- struct ide_atapi_pc *pc)
+static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
+ struct ide_cmd *cmd,
+ struct ide_atapi_pc *pc)
{
idetape_tape_t *tape = drive->driver_data;
@@ -660,8 +620,8 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
"Two request sense in serial were issued\n");
}
- if (tape->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
- tape->failed_pc = pc;
+ if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
+ drive->failed_pc = pc;
/* Set the current packet command */
drive->pc = pc;
@@ -685,9 +645,9 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
tape->ascq);
}
/* Giving up */
- pc->error = IDETAPE_ERROR_GENERAL;
+ pc->error = IDE_DRV_ERROR_GENERAL;
}
- tape->failed_pc = NULL;
+ drive->failed_pc = NULL;
drive->pc_callback(drive, 0);
return ide_stopped;
}
@@ -695,7 +655,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
pc->retries++;
- return ide_issue_pc(drive);
+ return ide_issue_pc(drive, cmd);
}
/* A mode sense command is used to "sense" tape parameters. */
@@ -746,8 +706,8 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
}
pc->error = 0;
} else {
- pc->error = IDETAPE_ERROR_GENERAL;
- tape->failed_pc = NULL;
+ pc->error = IDE_DRV_ERROR_GENERAL;
+ drive->failed_pc = NULL;
}
drive->pc_callback(drive, 0);
return ide_stopped;
@@ -790,6 +750,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc *pc = NULL;
struct request *postponed_rq = tape->postponed_rq;
+ struct ide_cmd cmd;
u8 stat;
debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu,"
@@ -801,13 +762,15 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
/* We do not support buffer cache originated requests. */
printk(KERN_NOTICE "ide-tape: %s: Unsupported request in "
"request queue (%d)\n", drive->name, rq->cmd_type);
- ide_end_request(drive, 0, 0);
+ if (blk_fs_request(rq) == 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
return ide_stopped;
}
/* Retry a failed packet command */
- if (tape->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
- pc = tape->failed_pc;
+ if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
+ pc = drive->failed_pc;
goto out;
}
@@ -815,7 +778,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
if (rq != postponed_rq) {
printk(KERN_ERR "ide-tape: ide-tape.c bug - "
"Two DSC requests were queued\n");
- idetape_end_request(drive, 0, 0);
+ drive->failed_pc = NULL;
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
return ide_stopped;
}
@@ -881,7 +846,14 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
BUG();
out:
- return idetape_issue_pc(drive, pc);
+ memset(&cmd, 0, sizeof(cmd));
+
+ if (rq_data_dir(rq))
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+ cmd.rq = rq;
+
+ return ide_tape_issue_pc(drive, &cmd, pc);
}
/*
@@ -1226,7 +1198,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
if (tape->merge_bh)
idetape_init_merge_buffer(tape);
- if (errors == IDETAPE_ERROR_GENERAL)
+ if (errors == IDE_DRV_ERROR_GENERAL)
return -EIO;
return ret;
}
@@ -2042,9 +2014,13 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc pc;
+ u8 pc_buf[256];
char fw_rev[4], vendor_id[8], product_id[16];
idetape_create_inquiry_cmd(&pc);
+ pc.buf = &pc_buf[0];
+ pc.buf_size = sizeof(pc_buf);
+
if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n",
tape->name);
@@ -2192,8 +2168,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
drive->pc_update_buffers = idetape_update_buffers;
drive->pc_io_buffers = ide_tape_io_buffers;
- spin_lock_init(&tape->lock);
-
drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) {
@@ -2325,7 +2299,6 @@ static struct ide_driver idetape_driver = {
.remove = ide_tape_remove,
.version = IDETAPE_VERSION,
.do_request = idetape_do_request,
- .end_request = idetape_end_request,
#ifdef CONFIG_IDE_PROC_FS
.proc_entries = ide_tape_proc_entries,
.proc_devsets = ide_tape_proc_devsets,
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 16138bce84a7..243421ce40d0 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -39,88 +39,90 @@ void ide_tf_dump(const char *s, struct ide_taskfile *tf)
int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
{
- ide_task_t args;
+ struct ide_cmd cmd;
- memset(&args, 0, sizeof(ide_task_t));
- args.tf.nsect = 0x01;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf.nsect = 0x01;
if (drive->media == ide_disk)
- args.tf.command = ATA_CMD_ID_ATA;
+ cmd.tf.command = ATA_CMD_ID_ATA;
else
- args.tf.command = ATA_CMD_ID_ATAPI;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- args.data_phase = TASKFILE_IN;
- return ide_raw_taskfile(drive, &args, buf, 1);
+ cmd.tf.command = ATA_CMD_ID_ATAPI;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.protocol = ATA_PROT_PIO;
+
+ return ide_raw_taskfile(drive, &cmd, buf, 1);
}
static ide_startstop_t task_no_data_intr(ide_drive_t *);
-static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *);
-static ide_startstop_t task_in_intr(ide_drive_t *);
+static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct ide_cmd *);
+static ide_startstop_t task_pio_intr(ide_drive_t *);
-ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
+ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
{
ide_hwif_t *hwif = drive->hwif;
- struct ide_taskfile *tf = &task->tf;
+ struct ide_cmd *cmd = &hwif->cmd;
+ struct ide_taskfile *tf = &cmd->tf;
ide_handler_t *handler = NULL;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
const struct ide_dma_ops *dma_ops = hwif->dma_ops;
- if (task->data_phase == TASKFILE_MULTI_IN ||
- task->data_phase == TASKFILE_MULTI_OUT) {
- if (!drive->mult_count) {
- printk(KERN_ERR "%s: multimode not set!\n",
- drive->name);
- return ide_stopped;
- }
+ if (orig_cmd->protocol == ATA_PROT_PIO &&
+ (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) &&
+ drive->mult_count == 0) {
+ printk(KERN_ERR "%s: multimode not set!\n", drive->name);
+ return ide_stopped;
}
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
- task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS;
+ if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
+ orig_cmd->ftf_flags |= IDE_FTFLAG_SET_IN_FLAGS;
- memcpy(&hwif->task, task, sizeof(*task));
+ memcpy(cmd, orig_cmd, sizeof(*cmd));
- if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
+ if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
ide_tf_dump(drive->name, tf);
- tp_ops->set_irq(hwif, 1);
+ tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
SELECT_MASK(drive, 0);
- tp_ops->tf_load(drive, task);
+
+ if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
+ u8 data[2] = { tf->data, tf->hob_data };
+
+ tp_ops->output_data(drive, cmd, data, 2);
+ }
+ tp_ops->tf_load(drive, cmd);
}
- switch (task->data_phase) {
- case TASKFILE_MULTI_OUT:
- case TASKFILE_OUT:
- tp_ops->exec_command(hwif, tf->command);
- ndelay(400); /* FIXME */
- return pre_task_out_intr(drive, task->rq);
- case TASKFILE_MULTI_IN:
- case TASKFILE_IN:
- handler = task_in_intr;
+ switch (cmd->protocol) {
+ case ATA_PROT_PIO:
+ if (cmd->tf_flags & IDE_TFLAG_WRITE) {
+ tp_ops->exec_command(hwif, tf->command);
+ ndelay(400); /* FIXME */
+ return pre_task_out_intr(drive, cmd);
+ }
+ handler = task_pio_intr;
/* fall-through */
- case TASKFILE_NO_DATA:
+ case ATA_PROT_NODATA:
if (handler == NULL)
handler = task_no_data_intr;
- ide_execute_command(drive, tf->command, handler,
- WAIT_WORSTCASE, NULL);
+ ide_execute_command(drive, cmd, handler, WAIT_WORSTCASE);
return ide_started;
- default:
- if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
- dma_ops->dma_setup(drive))
+ case ATA_PROT_DMA:
+ if (ide_dma_prepare(drive, cmd))
return ide_stopped;
- dma_ops->dma_exec_cmd(drive, tf->command);
+ hwif->expiry = dma_ops->dma_timer_expiry;
+ ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD);
dma_ops->dma_start(drive);
+ default:
return ide_started;
}
}
EXPORT_SYMBOL_GPL(do_rw_taskfile);
-/*
- * Handler for commands without a data phase
- */
static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- ide_task_t *task = &hwif->task;
- struct ide_taskfile *tf = &task->tf;
- int custom = (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
+ struct ide_cmd *cmd = &hwif->cmd;
+ struct ide_taskfile *tf = &cmd->tf;
+ int custom = (cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ? 5 : 1;
u8 stat;
@@ -142,28 +144,26 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
} else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) {
if ((stat & (ATA_ERR | ATA_DRQ)) == 0) {
ide_set_handler(drive, &task_no_data_intr,
- WAIT_WORSTCASE, NULL);
+ WAIT_WORSTCASE);
return ide_started;
}
}
return ide_error(drive, "task_no_data_intr", stat);
- /* calls ide_end_drive_cmd */
}
- if (!custom)
- ide_end_drive_cmd(drive, stat, ide_read_error(drive));
- else if (tf->command == ATA_CMD_IDLEIMMEDIATE) {
- hwif->tp_ops->tf_read(drive, task);
- if (tf->lbal != 0xc4) {
- printk(KERN_ERR "%s: head unload failed!\n",
- drive->name);
- ide_tf_dump(drive->name, tf);
- } else
- drive->dev_flags |= IDE_DFLAG_PARKED;
- ide_end_drive_cmd(drive, stat, ide_read_error(drive));
- } else if (tf->command == ATA_CMD_SET_MULTI)
+ if (custom && tf->command == ATA_CMD_SET_MULTI)
drive->mult_count = drive->mult_req;
+ if (custom == 0 || tf->command == ATA_CMD_IDLEIMMEDIATE ||
+ tf->command == ATA_CMD_CHK_POWER) {
+ struct request *rq = hwif->rq;
+
+ if (blk_pm_request(rq))
+ ide_complete_pm_rq(drive, rq);
+ else
+ ide_finish_cmd(drive, cmd, stat);
+ }
+
return ide_stopped;
}
@@ -192,239 +192,188 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
return stat;
}
-static void ide_pio_sector(ide_drive_t *drive, struct request *rq,
- unsigned int write)
+void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
+ unsigned int write, unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
- struct scatterlist *cursg = hwif->cursg;
+ struct scatterlist *cursg = cmd->cursg;
struct page *page;
-#ifdef CONFIG_HIGHMEM
unsigned long flags;
-#endif
unsigned int offset;
u8 *buf;
- cursg = hwif->cursg;
- if (!cursg) {
- cursg = sg;
- hwif->cursg = sg;
- }
+ cursg = cmd->cursg;
+ if (cursg == NULL)
+ cursg = cmd->cursg = sg;
- page = sg_page(cursg);
- offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
+ while (len) {
+ unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
- /* get the current page and offset */
- page = nth_page(page, (offset >> PAGE_SHIFT));
- offset %= PAGE_SIZE;
+ if (nr_bytes > PAGE_SIZE)
+ nr_bytes = PAGE_SIZE;
-#ifdef CONFIG_HIGHMEM
- local_irq_save(flags);
-#endif
- buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
+ page = sg_page(cursg);
+ offset = cursg->offset + cmd->cursg_ofs;
- hwif->nleft--;
- hwif->cursg_ofs++;
+ /* get the current page and offset */
+ page = nth_page(page, (offset >> PAGE_SHIFT));
+ offset %= PAGE_SIZE;
- if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) {
- hwif->cursg = sg_next(hwif->cursg);
- hwif->cursg_ofs = 0;
- }
+ if (PageHighMem(page))
+ local_irq_save(flags);
- /* do the actual data transfer */
- if (write)
- hwif->tp_ops->output_data(drive, rq, buf, SECTOR_SIZE);
- else
- hwif->tp_ops->input_data(drive, rq, buf, SECTOR_SIZE);
+ buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
- kunmap_atomic(buf, KM_BIO_SRC_IRQ);
-#ifdef CONFIG_HIGHMEM
- local_irq_restore(flags);
-#endif
-}
+ cmd->nleft -= nr_bytes;
+ cmd->cursg_ofs += nr_bytes;
-static void ide_pio_multi(ide_drive_t *drive, struct request *rq,
- unsigned int write)
-{
- unsigned int nsect;
+ if (cmd->cursg_ofs == cursg->length) {
+ cursg = cmd->cursg = sg_next(cmd->cursg);
+ cmd->cursg_ofs = 0;
+ }
+
+ /* do the actual data transfer */
+ if (write)
+ hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes);
+ else
+ hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes);
+
+ kunmap_atomic(buf, KM_BIO_SRC_IRQ);
+
+ if (PageHighMem(page))
+ local_irq_restore(flags);
- nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count);
- while (nsect--)
- ide_pio_sector(drive, rq, write);
+ len -= nr_bytes;
+ }
}
+EXPORT_SYMBOL_GPL(ide_pio_bytes);
-static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
- unsigned int write)
+static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd,
+ unsigned int write)
{
- u8 saved_io_32bit = drive->io_32bit;
+ unsigned int nr_bytes;
- if (rq->bio) /* fs request */
- rq->errors = 0;
+ u8 saved_io_32bit = drive->io_32bit;
- if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
- ide_task_t *task = rq->special;
+ if (cmd->tf_flags & IDE_TFLAG_FS)
+ cmd->rq->errors = 0;
- if (task->tf_flags & IDE_TFLAG_IO_16BIT)
- drive->io_32bit = 0;
- }
+ if (cmd->tf_flags & IDE_TFLAG_IO_16BIT)
+ drive->io_32bit = 0;
touch_softlockup_watchdog();
- switch (drive->hwif->data_phase) {
- case TASKFILE_MULTI_IN:
- case TASKFILE_MULTI_OUT:
- ide_pio_multi(drive, rq, write);
- break;
- default:
- ide_pio_sector(drive, rq, write);
- break;
- }
+ if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
+ nr_bytes = min_t(unsigned, cmd->nleft, drive->mult_count << 9);
+ else
+ nr_bytes = SECTOR_SIZE;
+
+ ide_pio_bytes(drive, cmd, write, nr_bytes);
drive->io_32bit = saved_io_32bit;
}
-static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
- const char *s, u8 stat)
+static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
{
- if (rq->bio) {
- ide_hwif_t *hwif = drive->hwif;
- int sectors = hwif->nsect - hwif->nleft;
-
- switch (hwif->data_phase) {
- case TASKFILE_IN:
- if (hwif->nleft)
- break;
- /* fall through */
- case TASKFILE_OUT:
- sectors--;
- break;
- case TASKFILE_MULTI_IN:
- if (hwif->nleft)
- break;
- /* fall through */
- case TASKFILE_MULTI_OUT:
- sectors -= drive->mult_count;
- default:
- break;
+ if (cmd->tf_flags & IDE_TFLAG_FS) {
+ int nr_bytes = cmd->nbytes - cmd->nleft;
+
+ if (cmd->protocol == ATA_PROT_PIO &&
+ ((cmd->tf_flags & IDE_TFLAG_WRITE) || cmd->nleft == 0)) {
+ if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
+ nr_bytes -= drive->mult_count << 9;
+ else
+ nr_bytes -= SECTOR_SIZE;
}
- if (sectors > 0) {
- struct ide_driver *drv;
-
- drv = *(struct ide_driver **)rq->rq_disk->private_data;
- drv->end_request(drive, 1, sectors);
- }
+ if (nr_bytes > 0)
+ ide_complete_rq(drive, 0, nr_bytes);
}
- return ide_error(drive, s, stat);
}
-void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
+void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat)
{
- if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
- u8 err = ide_read_error(drive);
-
- ide_end_drive_cmd(drive, stat, err);
- return;
- }
-
- if (rq->rq_disk) {
- struct ide_driver *drv;
+ struct request *rq = drive->hwif->rq;
+ u8 err = ide_read_error(drive);
- drv = *(struct ide_driver **)rq->rq_disk->private_data;;
- drv->end_request(drive, 1, rq->nr_sectors);
- } else
- ide_end_request(drive, 1, rq->nr_sectors);
+ ide_complete_cmd(drive, cmd, stat, err);
+ rq->errors = err;
+ ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
}
/*
- * We got an interrupt on a task_in case, but no errors and no DRQ.
- *
- * It might be a spurious irq (shared irq), but it might be a
- * command that had no output.
+ * Handler for command with PIO data phase.
*/
-static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq, u8 stat)
-{
- /* Command all done? */
- if (OK_STAT(stat, ATA_DRDY, ATA_BUSY)) {
- task_end_request(drive, rq, stat);
- return ide_stopped;
- }
-
- /* Assume it was a spurious irq */
- ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
- return ide_started;
-}
-
-/*
- * Handler for command with PIO data-in phase (Read/Read Multiple).
- */
-static ide_startstop_t task_in_intr(ide_drive_t *drive)
+static ide_startstop_t task_pio_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
+ struct ide_cmd *cmd = &drive->hwif->cmd;
u8 stat = hwif->tp_ops->read_status(hwif);
+ u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- /* Error? */
- if (stat & ATA_ERR)
- return task_error(drive, rq, __func__, stat);
+ if (write == 0) {
+ /* Error? */
+ if (stat & ATA_ERR)
+ goto out_err;
- /* Didn't want any data? Odd. */
- if ((stat & ATA_DRQ) == 0)
- return task_in_unexpected(drive, rq, stat);
+ /* Didn't want any data? Odd. */
+ if ((stat & ATA_DRQ) == 0) {
+ /* Command all done? */
+ if (OK_STAT(stat, ATA_DRDY, ATA_BUSY))
+ goto out_end;
- ide_pio_datablock(drive, rq, 0);
+ /* Assume it was a spurious irq */
+ goto out_wait;
+ }
+ } else {
+ if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
+ goto out_err;
- /* Are we done? Check status and finish transfer. */
- if (!hwif->nleft) {
- stat = wait_drive_not_busy(drive);
- if (!OK_STAT(stat, 0, BAD_STAT))
- return task_error(drive, rq, __func__, stat);
- task_end_request(drive, rq, stat);
- return ide_stopped;
+ /* Deal with unexpected ATA data phase. */
+ if (((stat & ATA_DRQ) == 0) ^ (cmd->nleft == 0))
+ goto out_err;
}
- /* Still data left to transfer. */
- ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
-
- return ide_started;
-}
-
-/*
- * Handler for command with PIO data-out phase (Write/Write Multiple).
- */
-static ide_startstop_t task_out_intr (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
- u8 stat = hwif->tp_ops->read_status(hwif);
+ if (write && cmd->nleft == 0)
+ goto out_end;
- if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
- return task_error(drive, rq, __func__, stat);
+ /* Still data left to transfer. */
+ ide_pio_datablock(drive, cmd, write);
- /* Deal with unexpected ATA data phase. */
- if (((stat & ATA_DRQ) == 0) ^ !hwif->nleft)
- return task_error(drive, rq, __func__, stat);
+ /* Are we done? Check status and finish transfer. */
+ if (write == 0 && cmd->nleft == 0) {
+ stat = wait_drive_not_busy(drive);
+ if (!OK_STAT(stat, 0, BAD_STAT))
+ goto out_err;
- if (!hwif->nleft) {
- task_end_request(drive, rq, stat);
- return ide_stopped;
+ goto out_end;
}
-
+out_wait:
/* Still data left to transfer. */
- ide_pio_datablock(drive, rq, 1);
- ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
-
+ ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
return ide_started;
+out_end:
+ if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
+ ide_finish_cmd(drive, cmd, stat);
+ else
+ ide_complete_rq(drive, 0, cmd->rq->nr_sectors << 9);
+ return ide_stopped;
+out_err:
+ ide_error_cmd(drive, cmd);
+ return ide_error(drive, __func__, stat);
}
-static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
+static ide_startstop_t pre_task_out_intr(ide_drive_t *drive,
+ struct ide_cmd *cmd)
{
ide_startstop_t startstop;
if (ide_wait_stat(&startstop, drive, ATA_DRQ,
drive->bad_wstat, WAIT_DRQ)) {
printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
- drive->name, drive->hwif->data_phase ? "MULT" : "",
+ drive->name,
+ (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "",
(drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
return startstop;
}
@@ -432,13 +381,15 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0)
local_irq_disable();
- ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
- ide_pio_datablock(drive, rq, 1);
+ ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
+
+ ide_pio_datablock(drive, cmd, 1);
return ide_started;
}
-int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
+int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
+ u16 nsect)
{
struct request *rq;
int error;
@@ -456,11 +407,11 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
rq->hard_nr_sectors = rq->nr_sectors = nsect;
rq->hard_cur_sectors = rq->current_nr_sectors = nsect;
- if (task->tf_flags & IDE_TFLAG_WRITE)
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
rq->cmd_flags |= REQ_RW;
- rq->special = task;
- task->rq = rq;
+ rq->special = cmd;
+ cmd->rq = rq;
error = blk_execute_rq(drive->queue, NULL, rq, 0);
blk_put_request(rq);
@@ -470,19 +421,19 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
EXPORT_SYMBOL(ide_raw_taskfile);
-int ide_no_data_taskfile(ide_drive_t *drive, ide_task_t *task)
+int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd)
{
- task->data_phase = TASKFILE_NO_DATA;
+ cmd->protocol = ATA_PROT_NODATA;
- return ide_raw_taskfile(drive, task, NULL, 0);
+ return ide_raw_taskfile(drive, cmd, NULL, 0);
}
EXPORT_SYMBOL_GPL(ide_no_data_taskfile);
#ifdef CONFIG_IDE_TASK_IOCTL
-int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
+int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
{
ide_task_request_t *req_task;
- ide_task_t args;
+ struct ide_cmd cmd;
u8 *outbuf = NULL;
u8 *inbuf = NULL;
u8 *data_buf = NULL;
@@ -536,53 +487,63 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
}
}
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
- memcpy(&args.tf_array[0], req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2);
- memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
+ memcpy(&cmd.tf_array[0], req_task->hob_ports,
+ HDIO_DRIVE_HOB_HDR_SIZE - 2);
+ memcpy(&cmd.tf_array[6], req_task->io_ports,
+ HDIO_DRIVE_TASK_HDR_SIZE);
- args.data_phase = req_task->data_phase;
+ cmd.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
+ IDE_TFLAG_IN_TF;
- args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
- IDE_TFLAG_IN_TF;
if (drive->dev_flags & IDE_DFLAG_LBA48)
- args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
+ cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
if (req_task->out_flags.all) {
- args.tf_flags |= IDE_TFLAG_FLAGGED;
+ cmd.ftf_flags |= IDE_FTFLAG_FLAGGED;
if (req_task->out_flags.b.data)
- args.tf_flags |= IDE_TFLAG_OUT_DATA;
+ cmd.ftf_flags |= IDE_FTFLAG_OUT_DATA;
if (req_task->out_flags.b.nsector_hob)
- args.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT;
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT;
if (req_task->out_flags.b.sector_hob)
- args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL;
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL;
if (req_task->out_flags.b.lcyl_hob)
- args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM;
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM;
if (req_task->out_flags.b.hcyl_hob)
- args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH;
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH;
if (req_task->out_flags.b.error_feature)
- args.tf_flags |= IDE_TFLAG_OUT_FEATURE;
+ cmd.tf_flags |= IDE_TFLAG_OUT_FEATURE;
if (req_task->out_flags.b.nsector)
- args.tf_flags |= IDE_TFLAG_OUT_NSECT;
+ cmd.tf_flags |= IDE_TFLAG_OUT_NSECT;
if (req_task->out_flags.b.sector)
- args.tf_flags |= IDE_TFLAG_OUT_LBAL;
+ cmd.tf_flags |= IDE_TFLAG_OUT_LBAL;
if (req_task->out_flags.b.lcyl)
- args.tf_flags |= IDE_TFLAG_OUT_LBAM;
+ cmd.tf_flags |= IDE_TFLAG_OUT_LBAM;
if (req_task->out_flags.b.hcyl)
- args.tf_flags |= IDE_TFLAG_OUT_LBAH;
+ cmd.tf_flags |= IDE_TFLAG_OUT_LBAH;
} else {
- args.tf_flags |= IDE_TFLAG_OUT_TF;
- if (args.tf_flags & IDE_TFLAG_LBA48)
- args.tf_flags |= IDE_TFLAG_OUT_HOB;
+ cmd.tf_flags |= IDE_TFLAG_OUT_TF;
+ if (cmd.tf_flags & IDE_TFLAG_LBA48)
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB;
}
if (req_task->in_flags.b.data)
- args.tf_flags |= IDE_TFLAG_IN_DATA;
+ cmd.ftf_flags |= IDE_FTFLAG_IN_DATA;
+
+ if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE) {
+ /* fixup data phase if needed */
+ if (req_task->data_phase == TASKFILE_IN_DMAQ ||
+ req_task->data_phase == TASKFILE_IN_DMA)
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+ }
- switch(req_task->data_phase) {
+ cmd.protocol = ATA_PROT_DMA;
+
+ switch (req_task->data_phase) {
case TASKFILE_MULTI_OUT:
if (!drive->mult_count) {
/* (hs): give up if multcount is not set */
@@ -592,11 +553,14 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
err = -EPERM;
goto abort;
}
+ cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
/* fall through */
case TASKFILE_OUT:
+ cmd.protocol = ATA_PROT_PIO;
/* fall through */
case TASKFILE_OUT_DMAQ:
case TASKFILE_OUT_DMA:
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
nsect = taskout / SECTOR_SIZE;
data_buf = outbuf;
break;
@@ -609,8 +573,10 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
err = -EPERM;
goto abort;
}
+ cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
/* fall through */
case TASKFILE_IN:
+ cmd.protocol = ATA_PROT_PIO;
/* fall through */
case TASKFILE_IN_DMAQ:
case TASKFILE_IN_DMA:
@@ -618,6 +584,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
data_buf = inbuf;
break;
case TASKFILE_NO_DATA:
+ cmd.protocol = ATA_PROT_NODATA;
break;
default:
err = -EFAULT;
@@ -627,7 +594,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
nsect = 0;
else if (!nsect) {
- nsect = (args.tf.hob_nsect << 8) | args.tf.nsect;
+ nsect = (cmd.tf.hob_nsect << 8) | cmd.tf.nsect;
if (!nsect) {
printk(KERN_ERR "%s: in/out command without data\n",
@@ -637,15 +604,14 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
}
}
- if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE)
- args.tf_flags |= IDE_TFLAG_WRITE;
-
- err = ide_raw_taskfile(drive, &args, data_buf, nsect);
+ err = ide_raw_taskfile(drive, &cmd, data_buf, nsect);
- memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2);
- memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE);
+ memcpy(req_task->hob_ports, &cmd.tf_array[0],
+ HDIO_DRIVE_HOB_HDR_SIZE - 2);
+ memcpy(req_task->io_ports, &cmd.tf_array[6],
+ HDIO_DRIVE_TASK_HDR_SIZE);
- if ((args.tf_flags & IDE_TFLAG_FLAGGED_SET_IN_FLAGS) &&
+ if ((cmd.ftf_flags & IDE_FTFLAG_SET_IN_FLAGS) &&
req_task->in_flags.all == 0) {
req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
if (drive->dev_flags & IDE_DFLAG_LBA48)
diff --git a/drivers/ide/ide-timings.c b/drivers/ide/ide-timings.c
index 81f527af8fae..001a56365be5 100644
--- a/drivers/ide/ide-timings.c
+++ b/drivers/ide/ide-timings.c
@@ -43,6 +43,8 @@ static struct ide_timing ide_timing[] = {
{ XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 },
{ XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 },
+ { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 80, 0 },
+ { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 100, 0 },
{ XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 },
{ XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 },
{ XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 },
@@ -51,7 +53,8 @@ static struct ide_timing ide_timing[] = {
{ XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 },
{ XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 },
- { XFER_PIO_5, 20, 50, 30, 100, 50, 30, 100, 0 },
+ { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 80, 0 },
+ { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 100, 0 },
{ XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 },
{ XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 },
@@ -90,6 +93,10 @@ u16 ide_pio_cycle_time(ide_drive_t *drive, u8 pio)
/* conservative "downgrade" for all pre-ATA2 drives */
if (pio < 3 && cycle < t->cycle)
cycle = 0; /* use standard timing */
+
+ /* Use the standard timing for the CF specific modes too */
+ if (pio > 4 && ata_id_is_cfa(id))
+ cycle = 0;
}
return cycle ? cycle : t->cycle;
@@ -161,7 +168,8 @@ int ide_timing_compute(ide_drive_t *drive, u8 speed,
if (speed <= XFER_PIO_2)
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
- else if (speed <= XFER_PIO_5)
+ else if ((speed <= XFER_PIO_4) ||
+ (speed == XFER_PIO_5 && !ata_id_is_cfa(id)))
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY];
else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
p.cycle = id[ATA_ID_EIDE_DMA_MIN];
diff --git a/drivers/ide/ide-xfer-mode.c b/drivers/ide/ide-xfer-mode.c
new file mode 100644
index 000000000000..af44be9d546c
--- /dev/null
+++ b/drivers/ide/ide-xfer-mode.c
@@ -0,0 +1,249 @@
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/ide.h>
+#include <linux/bitops.h>
+
+static const char *udma_str[] =
+ { "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44",
+ "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
+static const char *mwdma_str[] =
+ { "MWDMA0", "MWDMA1", "MWDMA2", "MWDMA3", "MWDMA4" };
+static const char *swdma_str[] =
+ { "SWDMA0", "SWDMA1", "SWDMA2" };
+static const char *pio_str[] =
+ { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5", "PIO6" };
+
+/**
+ * ide_xfer_verbose - return IDE mode names
+ * @mode: transfer mode
+ *
+ * Returns a constant string giving the name of the mode
+ * requested.
+ */
+
+const char *ide_xfer_verbose(u8 mode)
+{
+ const char *s;
+ u8 i = mode & 0xf;
+
+ if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
+ s = udma_str[i];
+ else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_4)
+ s = mwdma_str[i];
+ else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
+ s = swdma_str[i];
+ else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_6)
+ s = pio_str[i & 0x7];
+ else if (mode == XFER_PIO_SLOW)
+ s = "PIO SLOW";
+ else
+ s = "XFER ERROR";
+
+ return s;
+}
+EXPORT_SYMBOL(ide_xfer_verbose);
+
+/**
+ * ide_get_best_pio_mode - get PIO mode from drive
+ * @drive: drive to consider
+ * @mode_wanted: preferred mode
+ * @max_mode: highest allowed mode
+ *
+ * This routine returns the recommended PIO settings for a given drive,
+ * based on the drive->id information and the ide_pio_blacklist[].
+ *
+ * Drive PIO mode is auto-selected if 255 is passed as mode_wanted.
+ * This is used by most chipset support modules when "auto-tuning".
+ */
+
+u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
+{
+ u16 *id = drive->id;
+ int pio_mode = -1, overridden = 0;
+
+ if (mode_wanted != 255)
+ return min_t(u8, mode_wanted, max_mode);
+
+ if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0)
+ pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]);
+
+ if (pio_mode != -1) {
+ printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name);
+ } else {
+ pio_mode = id[ATA_ID_OLD_PIO_MODES] >> 8;
+ if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */
+ pio_mode = 2;
+ overridden = 1;
+ }
+
+ if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */
+ if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 7))
+ pio_mode = 4 + min_t(int, 2,
+ id[ATA_ID_CFA_MODES] & 7);
+ else if (ata_id_has_iordy(id)) {
+ if (id[ATA_ID_PIO_MODES] & 7) {
+ overridden = 0;
+ if (id[ATA_ID_PIO_MODES] & 4)
+ pio_mode = 5;
+ else if (id[ATA_ID_PIO_MODES] & 2)
+ pio_mode = 4;
+ else
+ pio_mode = 3;
+ }
+ }
+ }
+
+ if (overridden)
+ printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
+ drive->name);
+ }
+
+ if (pio_mode > max_mode)
+ pio_mode = max_mode;
+
+ return pio_mode;
+}
+EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
+
+int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+ return 0;
+
+ if (port_ops == NULL || port_ops->set_pio_mode == NULL)
+ return -1;
+
+ /*
+ * TODO: temporary hack for some legacy host drivers that didn't
+ * set transfer mode on the device in ->set_pio_mode method...
+ */
+ if (port_ops->set_dma_mode == NULL) {
+ port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+ return 0;
+ }
+
+ if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
+ if (ide_config_drive_speed(drive, mode))
+ return -1;
+ port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+ return 0;
+ } else {
+ port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+ return ide_config_drive_speed(drive, mode);
+ }
+}
+
+int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+ return 0;
+
+ if (port_ops == NULL || port_ops->set_dma_mode == NULL)
+ return -1;
+
+ if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
+ if (ide_config_drive_speed(drive, mode))
+ return -1;
+ port_ops->set_dma_mode(drive, mode);
+ return 0;
+ } else {
+ port_ops->set_dma_mode(drive, mode);
+ return ide_config_drive_speed(drive, mode);
+ }
+}
+EXPORT_SYMBOL_GPL(ide_set_dma_mode);
+
+/* req_pio == "255" for auto-tune */
+void ide_set_pio(ide_drive_t *drive, u8 req_pio)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+ u8 host_pio, pio;
+
+ if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
+ (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
+ return;
+
+ BUG_ON(hwif->pio_mask == 0x00);
+
+ host_pio = fls(hwif->pio_mask) - 1;
+
+ pio = ide_get_best_pio_mode(drive, req_pio, host_pio);
+
+ /*
+ * TODO:
+ * - report device max PIO mode
+ * - check req_pio != 255 against device max PIO mode
+ */
+ printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n",
+ drive->name, host_pio, req_pio,
+ req_pio == 255 ? "(auto-tune)" : "", pio);
+
+ (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
+}
+EXPORT_SYMBOL_GPL(ide_set_pio);
+
+/**
+ * ide_rate_filter - filter transfer mode
+ * @drive: IDE device
+ * @speed: desired speed
+ *
+ * Given the available transfer modes this function returns
+ * the best available speed at or below the speed requested.
+ *
+ * TODO: check device PIO capabilities
+ */
+
+static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 mode = ide_find_dma_mode(drive, speed);
+
+ if (mode == 0) {
+ if (hwif->pio_mask)
+ mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0;
+ else
+ mode = XFER_PIO_4;
+ }
+
+/* printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */
+
+ return min(speed, mode);
+}
+
+/**
+ * ide_set_xfer_rate - set transfer rate
+ * @drive: drive to set
+ * @rate: speed to attempt to set
+ *
+ * General helper for setting the speed of an IDE device. This
+ * function knows about user enforced limits from the configuration
+ * which ->set_pio_mode/->set_dma_mode does not.
+ */
+
+int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ const struct ide_port_ops *port_ops = hwif->port_ops;
+
+ if (port_ops == NULL || port_ops->set_dma_mode == NULL ||
+ (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
+ return -1;
+
+ rate = ide_rate_filter(drive, rate);
+
+ BUG_ON(rate < XFER_PIO_0);
+
+ if (rate >= XFER_PIO_0 && rate <= XFER_PIO_6)
+ return ide_set_pio_mode(drive, rate);
+
+ return ide_set_dma_mode(drive, rate);
+}
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 0920e3b0c962..92c9b90931e7 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -62,160 +62,6 @@
struct class *ide_port_class;
-/*
- * Locks for IDE setting functionality
- */
-
-DEFINE_MUTEX(ide_setting_mtx);
-
-ide_devset_get(io_32bit, io_32bit);
-
-static int set_io_32bit(ide_drive_t *drive, int arg)
-{
- if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT)
- return -EPERM;
-
- if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
- return -EINVAL;
-
- drive->io_32bit = arg;
-
- return 0;
-}
-
-ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS);
-
-static int set_ksettings(ide_drive_t *drive, int arg)
-{
- if (arg < 0 || arg > 1)
- return -EINVAL;
-
- if (arg)
- drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS;
- else
- drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS;
-
- return 0;
-}
-
-ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA);
-
-static int set_using_dma(ide_drive_t *drive, int arg)
-{
-#ifdef CONFIG_BLK_DEV_IDEDMA
- int err = -EPERM;
-
- if (arg < 0 || arg > 1)
- return -EINVAL;
-
- if (ata_id_has_dma(drive->id) == 0)
- goto out;
-
- if (drive->hwif->dma_ops == NULL)
- goto out;
-
- err = 0;
-
- if (arg) {
- if (ide_set_dma(drive))
- err = -EIO;
- } else
- ide_dma_off(drive);
-
-out:
- return err;
-#else
- if (arg < 0 || arg > 1)
- return -EINVAL;
-
- return -EPERM;
-#endif
-}
-
-/*
- * handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away
- */
-static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio)
-{
- switch (req_pio) {
- case 202:
- case 201:
- case 200:
- case 102:
- case 101:
- case 100:
- return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0;
- case 9:
- case 8:
- return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0;
- case 7:
- case 6:
- return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0;
- default:
- return 0;
- }
-}
-
-static int set_pio_mode(ide_drive_t *drive, int arg)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
-
- if (arg < 0 || arg > 255)
- return -EINVAL;
-
- if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
- (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
- return -ENOSYS;
-
- if (set_pio_mode_abuse(drive->hwif, arg)) {
- if (arg == 8 || arg == 9) {
- unsigned long flags;
-
- /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
- spin_lock_irqsave(&hwif->lock, flags);
- port_ops->set_pio_mode(drive, arg);
- spin_unlock_irqrestore(&hwif->lock, flags);
- } else
- port_ops->set_pio_mode(drive, arg);
- } else {
- int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
-
- ide_set_pio(drive, arg);
-
- if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
- if (keep_dma)
- ide_dma_on(drive);
- }
- }
-
- return 0;
-}
-
-ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK);
-
-static int set_unmaskirq(ide_drive_t *drive, int arg)
-{
- if (drive->dev_flags & IDE_DFLAG_NO_UNMASK)
- return -EPERM;
-
- if (arg < 0 || arg > 1)
- return -EINVAL;
-
- if (arg)
- drive->dev_flags |= IDE_DFLAG_UNMASK;
- else
- drive->dev_flags &= ~IDE_DFLAG_UNMASK;
-
- return 0;
-}
-
-ide_ext_devset_rw_sync(io_32bit, io_32bit);
-ide_ext_devset_rw_sync(keepsettings, ksettings);
-ide_ext_devset_rw_sync(unmaskirq, unmaskirq);
-ide_ext_devset_rw_sync(using_dma, using_dma);
-__IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode);
-
/**
* ide_device_get - get an additional reference to a ide_drive_t
* @drive: device to get a reference to
@@ -527,6 +373,8 @@ static int __init ide_init(void)
goto out_port_class;
}
+ ide_acpi_init();
+
proc_ide_create();
return 0;
diff --git a/drivers/ide/ide_arm.c b/drivers/ide/ide_arm.c
deleted file mode 100644
index bdcac94d7c1f..000000000000
--- a/drivers/ide/ide_arm.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * ARM default IDE host driver
- *
- * Copyright (C) 2004 Bartlomiej Zolnierkiewicz
- * Based on code by: Russell King, Ian Molton and Alexander Schulz.
- *
- * May be copied or modified under the terms of the GNU General Public License.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ide.h>
-
-#include <asm/irq.h>
-
-#define DRV_NAME "ide_arm"
-
-#define IDE_ARM_IO 0x1f0
-#define IDE_ARM_IRQ IRQ_HARDDISK
-
-static int __init ide_arm_init(void)
-{
- unsigned long base = IDE_ARM_IO, ctl = IDE_ARM_IO + 0x206;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
-
- if (!request_region(base, 8, DRV_NAME)) {
- printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
- DRV_NAME, base, base + 7);
- return -EBUSY;
- }
-
- if (!request_region(ctl, 1, DRV_NAME)) {
- printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
- DRV_NAME, ctl);
- release_region(base, 8);
- return -EBUSY;
- }
-
- memset(&hw, 0, sizeof(hw));
- ide_std_init_ports(&hw, base, ctl);
- hw.irq = IDE_ARM_IRQ;
- hw.chipset = ide_generic;
-
- return ide_host_add(NULL, hws, NULL);
-}
-
-module_init(ide_arm_init);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c
index 13b8153112ed..51aa745246dc 100644
--- a/drivers/ide/it821x.c
+++ b/drivers/ide/it821x.c
@@ -508,12 +508,11 @@ static void it821x_quirkproc(ide_drive_t *drive)
static struct ide_dma_ops it821x_pass_through_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = it821x_dma_start,
.dma_end = it821x_dma_end,
.dma_test_irq = ide_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
@@ -603,7 +602,7 @@ static void it8212_disable_raid(struct pci_dev *dev)
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
}
-static unsigned int init_chipset_it821x(struct pci_dev *dev)
+static int init_chipset_it821x(struct pci_dev *dev)
{
u8 conf;
static char *mode[2] = { "pass through", "smart" };
diff --git a/drivers/ide/macide.c b/drivers/ide/macide.c
index 3c60064f1d4f..4b1718e83283 100644
--- a/drivers/ide/macide.c
+++ b/drivers/ide/macide.c
@@ -80,6 +80,11 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base,
hw->chipset = ide_generic;
}
+static const struct ide_port_info macide_port_info = {
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
+};
+
static const char *mac_ide_name[] =
{ "Quadra", "Powerbook", "Powerbook Baboon" };
@@ -122,7 +127,7 @@ static int __init macide_init(void)
macide_setup_ports(&hw, base, irq, ack_intr);
- return ide_host_add(NULL, hws, NULL);
+ return ide_host_add(&macide_port_info, hws, NULL);
}
module_init(macide_init);
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index 83643ed9a426..71a39fb3856f 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -61,57 +61,52 @@ static u8 superio_dma_sff_read_status(ide_hwif_t *hwif)
return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS);
}
-static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void superio_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data = inw(io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
+ struct ide_taskfile *tf = &cmd->tf;
/* be sure we're looking at the low order bits */
- outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = superio_ide_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = inb(io_ports->lbah_addr);
}
}
+static void ns87415_dev_select(ide_drive_t *drive);
+
static const struct ide_tp_ops superio_tp_ops = {
.exec_command = ide_exec_command,
.read_status = superio_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ns87415_dev_select,
.tf_load = ide_tf_load,
.tf_read = superio_tf_read,
@@ -190,10 +185,18 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
local_irq_restore(flags);
}
-static void ns87415_selectproc (ide_drive_t *drive)
+static void ns87415_dev_select(ide_drive_t *drive)
{
ns87415_prepare_drive(drive,
!!(drive->dev_flags & IDE_DFLAG_USING_DMA));
+
+ outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
+}
+
+static void ns87415_dma_start(ide_drive_t *drive)
+{
+ ns87415_prepare_drive(drive, 1);
+ ide_dma_start(drive);
}
static int ns87415_dma_end(ide_drive_t *drive)
@@ -201,7 +204,6 @@ static int ns87415_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0;
- drive->waiting_for_dma = 0;
dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
/* get DMA command mode */
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
@@ -210,21 +212,11 @@ static int ns87415_dma_end(ide_drive_t *drive)
/* from ERRATA: clear the INTR & ERROR bits */
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
outb(dma_cmd | 6, hwif->dma_base + ATA_DMA_CMD);
- /* and free any DMA resources */
- ide_destroy_dmatable(drive);
- /* verify good DMA status */
- return (dma_stat & 7) != 4;
-}
-static int ns87415_dma_setup(ide_drive_t *drive)
-{
- /* select DMA xfer */
- ns87415_prepare_drive(drive, 1);
- if (!ide_dma_setup(drive))
- return 0;
- /* DMA failed: select PIO xfer */
ns87415_prepare_drive(drive, 0);
- return 1;
+
+ /* verify good DMA status */
+ return (dma_stat & 7) != 4;
}
static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
@@ -242,7 +234,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
* Also, leave IRQ masked during drive probing, to prevent infinite
* interrupts from a potentially floating INTA..
*
- * IRQs get unmasked in selectproc when drive is first used.
+ * IRQs get unmasked in dev_select() when drive is first used.
*/
(void) pci_read_config_dword(dev, 0x40, &ctrl);
(void) pci_read_config_byte(dev, 0x09, &progif);
@@ -270,7 +262,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
#ifdef __sparc_v9__
/*
* XXX: Reset the device, if we don't it will not respond to
- * SELECT_DRIVE() properly during first ide_probe_port().
+ * dev_select() properly during first ide_probe_port().
*/
timeout = 10000;
outb(12, hwif->io_ports.ctl_addr);
@@ -286,9 +278,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
}
if (!using_inta)
- hwif->irq = __ide_default_irq(hwif->io_ports.data_addr);
- else if (!hwif->irq && hwif->mate && hwif->mate->irq)
- hwif->irq = hwif->mate->irq; /* share IRQ with mate */
+ hwif->irq = pci_get_legacy_ide_irq(dev, hwif->channel);
if (!hwif->dma_base)
return;
@@ -296,26 +286,35 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
outb(0x60, hwif->dma_base + ATA_DMA_STATUS);
}
-static const struct ide_port_ops ns87415_port_ops = {
- .selectproc = ns87415_selectproc,
+static const struct ide_tp_ops ns87415_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
+
+ .dev_select = ns87415_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
};
static const struct ide_dma_ops ns87415_dma_ops = {
.dma_host_set = ide_dma_host_set,
- .dma_setup = ns87415_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
- .dma_start = ide_dma_start,
+ .dma_setup = ide_dma_setup,
+ .dma_start = ns87415_dma_start,
.dma_end = ns87415_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = superio_dma_sff_read_status,
};
static const struct ide_port_info ns87415_chipset __devinitdata = {
.name = DRV_NAME,
.init_hwif = init_hwif_ns87415,
- .port_ops = &ns87415_port_ops,
+ .tp_ops = &ns87415_tp_ops,
.dma_ops = &ns87415_dma_ops,
.host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_NO_ATAPI_DMA,
diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c
index f38aac78044c..c7acca0b8733 100644
--- a/drivers/ide/palm_bk3710.c
+++ b/drivers/ide/palm_bk3710.c
@@ -347,7 +347,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
struct clk *clk;
struct resource *mem, *irq;
void __iomem *base;
- unsigned long rate;
+ unsigned long rate, mem_size;
int i, rc;
hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
@@ -374,13 +374,18 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
return -ENODEV;
}
- if (request_mem_region(mem->start, mem->end - mem->start + 1,
- "palm_bk3710") == NULL) {
+ mem_size = mem->end - mem->start + 1;
+ if (request_mem_region(mem->start, mem_size, "palm_bk3710") == NULL) {
printk(KERN_ERR "failed to request memory region\n");
return -EBUSY;
}
- base = IO_ADDRESS(mem->start);
+ base = ioremap(mem->start, mem_size);
+ if (!base) {
+ printk(KERN_ERR "failed to map IO memory\n");
+ release_mem_region(mem->start, mem_size);
+ return -ENOMEM;
+ }
/* Configure the Palm Chip controller */
palm_bk3710_chipinit(base);
diff --git a/drivers/ide/pdc202xx_new.c b/drivers/ide/pdc202xx_new.c
index f21290c4b447..b68906c3c17e 100644
--- a/drivers/ide/pdc202xx_new.c
+++ b/drivers/ide/pdc202xx_new.c
@@ -325,7 +325,7 @@ static void apple_kiwi_init(struct pci_dev *pdev)
}
#endif /* CONFIG_PPC_PMAC */
-static unsigned int init_chipset_pdcnew(struct pci_dev *dev)
+static int init_chipset_pdcnew(struct pci_dev *dev)
{
const char *name = DRV_NAME;
unsigned long dma_base = pci_resource_start(dev, 4);
@@ -444,7 +444,7 @@ static unsigned int init_chipset_pdcnew(struct pci_dev *dev)
#endif
out:
- return dev->irq;
+ return 0;
}
static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c
index 97193323aebf..248a54bd2386 100644
--- a/drivers/ide/pdc202xx_old.c
+++ b/drivers/ide/pdc202xx_old.c
@@ -258,13 +258,7 @@ static void pdc202xx_dma_lost_irq(ide_drive_t *drive)
ide_dma_lost_irq(drive);
}
-static void pdc202xx_dma_timeout(ide_drive_t *drive)
-{
- pdc202xx_reset(drive);
- ide_dma_timeout(drive);
-}
-
-static unsigned int init_chipset_pdc202xx(struct pci_dev *dev)
+static int init_chipset_pdc202xx(struct pci_dev *dev)
{
unsigned long dmabase = pci_resource_start(dev, 4);
u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0;
@@ -290,7 +284,7 @@ static unsigned int init_chipset_pdc202xx(struct pci_dev *dev)
printk("%sACTIVE\n", (inb(dmabase | 0x1f) & 1) ? "" : "IN");
}
out:
- return dev->irq;
+ return 0;
}
static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
@@ -331,24 +325,24 @@ static const struct ide_port_ops pdc2026x_port_ops = {
static const struct ide_dma_ops pdc20246_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = pdc202xx_dma_test_irq,
.dma_lost_irq = pdc202xx_dma_lost_irq,
- .dma_timeout = pdc202xx_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
+ .dma_clear = pdc202xx_reset,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops pdc2026x_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = pdc202xx_dma_start,
.dma_end = pdc202xx_dma_end,
.dma_test_irq = pdc202xx_dma_test_irq,
.dma_lost_irq = pdc202xx_dma_lost_irq,
- .dma_timeout = pdc202xx_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
+ .dma_clear = pdc202xx_reset,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c
index f1e2e4ef0d71..2aa699933064 100644
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -204,7 +204,7 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
* out to be nice and simple.
*/
-static unsigned int init_chipset_ich(struct pci_dev *dev)
+static int init_chipset_ich(struct pci_dev *dev)
{
u32 extra = 0;
@@ -318,19 +318,12 @@ static const struct ide_port_ops ich_port_ops = {
.cable_detect = piix_cable_detect,
};
-#ifndef CONFIG_IA64
- #define IDE_HFLAGS_PIIX IDE_HFLAG_LEGACY_IRQS
-#else
- #define IDE_HFLAGS_PIIX 0
-#endif
-
#define DECLARE_PIIX_DEV(udma) \
{ \
.name = DRV_NAME, \
.init_hwif = init_hwif_piix, \
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
.port_ops = &piix_port_ops, \
- .host_flags = IDE_HFLAGS_PIIX, \
.pio_mask = ATA_PIO4, \
.swdma_mask = ATA_SWDMA2_ONLY, \
.mwdma_mask = ATA_MWDMA12_ONLY, \
@@ -344,7 +337,6 @@ static const struct ide_port_ops ich_port_ops = {
.init_hwif = init_hwif_piix, \
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
.port_ops = &ich_port_ops, \
- .host_flags = IDE_HFLAGS_PIIX, \
.pio_mask = ATA_PIO4, \
.swdma_mask = ATA_SWDMA2_ONLY, \
.mwdma_mask = ATA_MWDMA12_ONLY, \
@@ -360,8 +352,7 @@ static const struct ide_port_info piix_pci_info[] __devinitdata = {
*/
.name = DRV_NAME,
.enablebits = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}},
- .host_flags = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA |
- IDE_HFLAGS_PIIX,
+ .host_flags = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA,
.pio_mask = ATA_PIO4,
/* This is a painful system best to let it self tune for now */
},
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c
index 74625e821a43..052b9bf1f8fb 100644
--- a/drivers/ide/pmac.c
+++ b/drivers/ide/pmac.c
@@ -404,9 +404,6 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
#define IDE_WAKEUP_DELAY (1*HZ)
static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *);
-static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq);
-static void pmac_ide_selectproc(ide_drive_t *drive);
-static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
#define PMAC_IDE_REG(x) \
((void __iomem *)((drive)->hwif->io_ports.data_addr + (x)))
@@ -416,8 +413,7 @@ static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
* timing register when selecting that unit. This version is for
* ASICs with a single timing register
*/
-static void
-pmac_ide_selectproc(ide_drive_t *drive)
+static void pmac_ide_apply_timings(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
@@ -435,8 +431,7 @@ pmac_ide_selectproc(ide_drive_t *drive)
* timing register when selecting that unit. This version is for
* ASICs with a dual timing register (Kauai)
*/
-static void
-pmac_ide_kauai_selectproc(ide_drive_t *drive)
+static void pmac_ide_kauai_apply_timings(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
@@ -465,9 +460,25 @@ pmac_ide_do_update_timings(ide_drive_t *drive)
if (pmif->kind == controller_sh_ata6 ||
pmif->kind == controller_un_ata6 ||
pmif->kind == controller_k2_ata6)
- pmac_ide_kauai_selectproc(drive);
+ pmac_ide_kauai_apply_timings(drive);
else
- pmac_ide_selectproc(drive);
+ pmac_ide_apply_timings(drive);
+}
+
+static void pmac_dev_select(ide_drive_t *drive)
+{
+ pmac_ide_apply_timings(drive);
+
+ writeb(drive->select | ATA_DEVICE_OBS,
+ (void __iomem *)drive->hwif->io_ports.device_addr);
+}
+
+static void pmac_kauai_dev_select(ide_drive_t *drive)
+{
+ pmac_ide_kauai_apply_timings(drive);
+
+ writeb(drive->select | ATA_DEVICE_OBS,
+ (void __iomem *)drive->hwif->io_ports.device_addr);
}
static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd)
@@ -477,17 +488,8 @@ static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd)
+ IDE_TIMING_CONFIG));
}
-static void pmac_set_irq(ide_hwif_t *hwif, int on)
+static void pmac_write_devctl(ide_hwif_t *hwif, u8 ctl)
{
- u8 ctl = ATA_DEVCTL_OBS;
-
- if (on == 4) { /* hack for SRST */
- ctl |= 4;
- on &= ~4;
- }
-
- ctl |= on ? 0 : 2;
-
writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
(void)readl((void __iomem *)(hwif->io_ports.data_addr
+ IDE_TIMING_CONFIG));
@@ -917,10 +919,18 @@ static u8 pmac_ide_cable_detect(ide_hwif_t *hwif)
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
struct device_node *np = pmif->node;
const char *cable = of_get_property(np, "cable-type", NULL);
+ struct device_node *root = of_find_node_by_path("/");
+ const char *model = of_get_property(root, "model", NULL);
/* Get cable type from device-tree. */
- if (cable && !strncmp(cable, "80-", 3))
- return ATA_CBL_PATA80;
+ if (cable && !strncmp(cable, "80-", 3)) {
+ /* Some drives fail to detect 80c cable in PowerBook */
+ /* These machine use proprietary short IDE cable anyway */
+ if (!strncmp(model, "PowerBook", 9))
+ return ATA_CBL_PATA40_SHORT;
+ else
+ return ATA_CBL_PATA80;
+ }
/*
* G5's seem to have incorrect cable type in device-tree.
@@ -955,9 +965,9 @@ static const struct ide_tp_ops pmac_tp_ops = {
.exec_command = pmac_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = pmac_write_devctl,
- .set_irq = pmac_set_irq,
-
+ .dev_select = pmac_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
@@ -965,19 +975,24 @@ static const struct ide_tp_ops pmac_tp_ops = {
.output_data = ide_output_data,
};
-static const struct ide_port_ops pmac_ide_ata6_port_ops = {
- .init_dev = pmac_ide_init_dev,
- .set_pio_mode = pmac_ide_set_pio_mode,
- .set_dma_mode = pmac_ide_set_dma_mode,
- .selectproc = pmac_ide_kauai_selectproc,
- .cable_detect = pmac_ide_cable_detect,
+static const struct ide_tp_ops pmac_ata6_tp_ops = {
+ .exec_command = pmac_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = pmac_write_devctl,
+
+ .dev_select = pmac_kauai_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
};
static const struct ide_port_ops pmac_ide_ata4_port_ops = {
.init_dev = pmac_ide_init_dev,
.set_pio_mode = pmac_ide_set_pio_mode,
.set_dma_mode = pmac_ide_set_dma_mode,
- .selectproc = pmac_ide_selectproc,
.cable_detect = pmac_ide_cable_detect,
};
@@ -985,7 +1000,6 @@ static const struct ide_port_ops pmac_ide_port_ops = {
.init_dev = pmac_ide_init_dev,
.set_pio_mode = pmac_ide_set_pio_mode,
.set_dma_mode = pmac_ide_set_dma_mode,
- .selectproc = pmac_ide_selectproc,
};
static const struct ide_dma_ops pmac_dma_ops;
@@ -1022,15 +1036,18 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw)
pmif->broken_dma = pmif->broken_dma_warn = 0;
if (of_device_is_compatible(np, "shasta-ata")) {
pmif->kind = controller_sh_ata6;
- d.port_ops = &pmac_ide_ata6_port_ops;
+ d.tp_ops = &pmac_ata6_tp_ops;
+ d.port_ops = &pmac_ide_ata4_port_ops;
d.udma_mask = ATA_UDMA6;
} else if (of_device_is_compatible(np, "kauai-ata")) {
pmif->kind = controller_un_ata6;
- d.port_ops = &pmac_ide_ata6_port_ops;
+ d.tp_ops = &pmac_ata6_tp_ops;
+ d.port_ops = &pmac_ide_ata4_port_ops;
d.udma_mask = ATA_UDMA5;
} else if (of_device_is_compatible(np, "K2-UATA")) {
pmif->kind = controller_k2_ata6;
- d.port_ops = &pmac_ide_ata6_port_ops;
+ d.tp_ops = &pmac_ata6_tp_ops;
+ d.port_ops = &pmac_ide_ata4_port_ops;
d.udma_mask = ATA_UDMA5;
} else if (of_device_is_compatible(np, "keylargo-ata")) {
if (strcmp(np->name, "ata-4") == 0) {
@@ -1422,17 +1439,16 @@ out:
* pmac_ide_build_dmatable builds the DBDMA command list
* for a transfer and sets the DBDMA channel to point to it.
*/
-static int
-pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
struct dbdma_cmd *table;
- int i, count = 0;
volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
struct scatterlist *sg;
- int wr = (rq_data_dir(rq) == WRITE);
+ int wr = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
+ int i = cmd->sg_nents, count = 0;
/* DMA table is already aligned */
table = (struct dbdma_cmd *) pmif->dma_table_cpu;
@@ -1442,11 +1458,6 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
while (readl(&dma->status) & RUN)
udelay(1);
- hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
- if (!i)
- return 0;
-
/* Build DBDMA commands list */
sg = hwif->sg_table;
while (i && sg_dma_len(sg)) {
@@ -1462,7 +1473,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
"switching to PIO on Ohare chipset\n", drive->name);
pmif->broken_dma_warn = 1;
}
- goto use_pio_instead;
+ return 0;
}
while (cur_len) {
unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
@@ -1470,7 +1481,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
if (count++ >= MAX_DCMDS) {
printk(KERN_WARNING "%s: DMA table too small\n",
drive->name);
- goto use_pio_instead;
+ return 0;
}
st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE);
st_le16(&table->req_count, tc);
@@ -1499,9 +1510,6 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
-use_pio_instead:
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
@@ -1509,39 +1517,27 @@ use_pio_instead:
* Prepare a DMA transfer. We build the DMA table, adjust the timings for
* a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
*/
-static int
-pmac_ide_dma_setup(ide_drive_t *drive)
+static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
- struct request *rq = hwif->rq;
u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4);
+ u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- if (!pmac_ide_build_dmatable(drive, rq)) {
- ide_map_sg(drive, rq);
+ if (pmac_ide_build_dmatable(drive, cmd) == 0)
return 1;
- }
/* Apple adds 60ns to wrDataSetup on reads */
if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
- writel(pmif->timings[unit] + (!rq_data_dir(rq) ? 0x00800000UL : 0),
+ writel(pmif->timings[unit] + (write ? 0 : 0x00800000UL),
PMAC_IDE_REG(IDE_TIMING_CONFIG));
(void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
}
- drive->waiting_for_dma = 1;
-
return 0;
}
-static void
-pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
- /* issue cmd to drive */
- ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL);
-}
-
/*
* Kick the DMA controller into life after the DMA command has been issued
* to the drive.
@@ -1573,12 +1569,9 @@ pmac_ide_dma_end (ide_drive_t *drive)
volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
u32 dstat;
- drive->waiting_for_dma = 0;
dstat = readl(&dma->status);
writel(((RUN|WAKE|DEAD) << 16), &dma->control);
- ide_destroy_dmatable(drive);
-
/* verify good dma status. we don't check for ACTIVE beeing 0. We should...
* in theory, but with ATAPI decices doing buffer underruns, that would
* cause us to disable DMA, which isn't what we want
@@ -1662,11 +1655,9 @@ pmac_ide_dma_lost_irq (ide_drive_t *drive)
static const struct ide_dma_ops pmac_dma_ops = {
.dma_host_set = pmac_ide_dma_host_set,
.dma_setup = pmac_ide_dma_setup,
- .dma_exec_cmd = pmac_ide_dma_exec_cmd,
.dma_start = pmac_ide_dma_start,
.dma_end = pmac_ide_dma_end,
.dma_test_irq = pmac_ide_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = pmac_ide_dma_lost_irq,
};
diff --git a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c
index 9f9c0b3cc3a3..d007e7f66598 100644
--- a/drivers/ide/q40ide.c
+++ b/drivers/ide/q40ide.c
@@ -72,26 +72,26 @@ static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base,
hw->chipset = ide_generic;
}
-static void q40ide_input_data(ide_drive_t *drive, struct request *rq,
+static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
return insw(data_addr, buf, (len + 1) / 2);
- insw_swapw(data_addr, buf, (len + 1) / 2);
+ raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
-static void q40ide_output_data(ide_drive_t *drive, struct request *rq,
+static void q40ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
return outsw(data_addr, buf, (len + 1) / 2);
- outsw_swapw(data_addr, buf, (len + 1) / 2);
+ raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
/* Q40 has a byte-swapped IDE interface */
@@ -99,9 +99,9 @@ static const struct ide_tp_ops q40ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
@@ -111,7 +111,8 @@ static const struct ide_tp_ops q40ide_tp_ops = {
static const struct ide_port_info q40ide_port_info = {
.tp_ops = &q40ide_tp_ops,
- .host_flags = IDE_HFLAG_NO_DMA,
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
};
/*
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c
index 08c4fa35e9b1..c9a134986891 100644
--- a/drivers/ide/qd65xx.c
+++ b/drivers/ide/qd65xx.c
@@ -90,13 +90,15 @@ static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
* This routine is invoked to prepare for access to a given drive.
*/
-static void qd65xx_select(ide_drive_t *drive)
+static void qd65xx_dev_select(ide_drive_t *drive)
{
u8 index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) |
(QD_TIMREG(drive) & 0x02);
if (timings[index] != QD_TIMING(drive))
outb(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
+
+ outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
}
/*
@@ -309,20 +311,33 @@ static void __init qd6580_init_dev(ide_drive_t *drive)
drive->drive_data = (drive->dn & 1) ? t2 : t1;
}
+static const struct ide_tp_ops qd65xx_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
+
+ .dev_select = qd65xx_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
+};
+
static const struct ide_port_ops qd6500_port_ops = {
.init_dev = qd6500_init_dev,
.set_pio_mode = qd6500_set_pio_mode,
- .selectproc = qd65xx_select,
};
static const struct ide_port_ops qd6580_port_ops = {
.init_dev = qd6580_init_dev,
.set_pio_mode = qd6580_set_pio_mode,
- .selectproc = qd65xx_select,
};
static const struct ide_port_info qd65xx_port_info __initdata = {
.name = DRV_NAME,
+ .tp_ops = &qd65xx_tp_ops,
.chipset = ide_qd65xx,
.host_flags = IDE_HFLAG_IO_32BIT |
IDE_HFLAG_NO_DMA,
diff --git a/drivers/ide/sc1200.c b/drivers/ide/sc1200.c
index dbdd2985a0d8..d467478d68da 100644
--- a/drivers/ide/sc1200.c
+++ b/drivers/ide/sc1200.c
@@ -115,8 +115,7 @@ static u8 sc1200_udma_filter(ide_drive_t *drive)
if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
(mateid[ATA_ID_UDMA_MODES] & 7))
goto out;
- if ((mateid[ATA_ID_FIELD_VALID] & 2) &&
- (mateid[ATA_ID_MWDMA_MODES] & 7))
+ if (mateid[ATA_ID_MWDMA_MODES] & 7)
mask = 0;
}
out:
@@ -183,9 +182,6 @@ static int sc1200_dma_end(ide_drive_t *drive)
outb(dma_stat|0x1b, dma_base+2); /* clear the INTR & ERROR bits */
outb(inb(dma_base)&~1, dma_base); /* !! DO THIS HERE !! stop DMA */
- drive->waiting_for_dma = 0;
- ide_destroy_dmatable(drive); /* purge DMA mappings */
-
return (dma_stat & 7) != 4; /* verify good DMA status */
}
@@ -286,12 +282,11 @@ static const struct ide_port_ops sc1200_port_ops = {
static const struct ide_dma_ops sc1200_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = sc1200_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c
index 8d2314b6327c..6d8dbd9c10bc 100644
--- a/drivers/ide/scc_pata.c
+++ b/drivers/ide/scc_pata.c
@@ -148,17 +148,8 @@ static u8 scc_dma_sff_read_status(ide_hwif_t *hwif)
return (u8)in_be32((void *)(hwif->dma_base + 4));
}
-static void scc_set_irq(ide_hwif_t *hwif, int on)
+static void scc_write_devctl(ide_hwif_t *hwif, u8 ctl)
{
- u8 ctl = ATA_DEVCTL_OBS;
-
- if (on == 4) { /* hack for SRST */
- ctl |= 4;
- on &= ~4;
- }
-
- ctl |= on ? 0 : 2;
-
out_be32((void *)hwif->io_ports.ctl_addr, ctl);
eieio();
in_be32((void *)(hwif->dma_base + 0x01c));
@@ -303,8 +294,9 @@ static void scc_dma_host_set(ide_drive_t *drive, int on)
}
/**
- * scc_ide_dma_setup - begin a DMA phase
+ * scc_dma_setup - begin a DMA phase
* @drive: target device
+ * @cmd: command
*
* Build an IDE DMA PRD (IDE speak for scatter gather table)
* and then set up the DMA transfer registers.
@@ -313,36 +305,28 @@ static void scc_dma_host_set(ide_drive_t *drive, int on)
* is returned.
*/
-static int scc_dma_setup(ide_drive_t *drive)
+static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
- unsigned int reading;
+ u32 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
u8 dma_stat;
- if (rq_data_dir(rq))
- reading = 0;
- else
- reading = 1 << 3;
-
/* fall back to pio! */
- if (!ide_build_dmatable(drive, rq)) {
- ide_map_sg(drive, rq);
+ if (ide_build_dmatable(drive, cmd) == 0)
return 1;
- }
/* PRD table */
out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma);
/* specify r/w */
- out_be32((void __iomem *)hwif->dma_base, reading);
+ out_be32((void __iomem *)hwif->dma_base, rw);
/* read DMA status for INTR & ERROR flags */
dma_stat = scc_dma_sff_read_status(hwif);
/* clear INTR & ERROR flags */
out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6);
- drive->waiting_for_dma = 1;
+
return 0;
}
@@ -361,7 +345,6 @@ static int __scc_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat, dma_cmd;
- drive->waiting_for_dma = 0;
/* get DMA command mode */
dma_cmd = scc_ide_inb(hwif->dma_base);
/* stop DMA */
@@ -370,8 +353,6 @@ static int __scc_dma_end(ide_drive_t *drive)
dma_stat = scc_dma_sff_read_status(hwif);
/* clear the INTR & ERROR bits */
scc_ide_outb(dma_stat | 6, hwif->dma_base + 4);
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
/* verify good DMA status */
wmb();
return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
@@ -666,91 +647,80 @@ static int __devinit init_setup_scc(struct pci_dev *dev,
return rc;
}
-static void scc_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void scc_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA)
- out_be32((void *)io_ports->data_addr,
- (tf->hob_data << 8) | tf->data);
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
scc_ide_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
scc_ide_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
scc_ide_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
scc_ide_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
scc_ide_outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
scc_ide_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
scc_ide_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
scc_ide_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
scc_ide_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
scc_ide_outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
scc_ide_outb((tf->device & HIHI) | drive->select,
io_ports->device_addr);
}
-static void scc_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data = (u16)in_be32((void *)io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
+ struct ide_taskfile *tf = &cmd->tf;
/* be sure we're looking at the low order bits */
- scc_ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ scc_ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = scc_ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = scc_ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = scc_ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = scc_ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = scc_ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = scc_ide_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = scc_ide_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- scc_ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = scc_ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ scc_ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = scc_ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr);
}
}
-static void scc_input_data(ide_drive_t *drive, struct request *rq,
+static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
@@ -766,7 +736,7 @@ static void scc_input_data(ide_drive_t *drive, struct request *rq,
scc_ide_insw(data_addr, buf, len / 2);
}
-static void scc_output_data(ide_drive_t *drive, struct request *rq,
+static void scc_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
@@ -853,9 +823,9 @@ static const struct ide_tp_ops scc_tp_ops = {
.exec_command = scc_exec_command,
.read_status = scc_read_status,
.read_altstatus = scc_read_altstatus,
+ .write_devctl = scc_write_devctl,
- .set_irq = scc_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = scc_tf_load,
.tf_read = scc_tf_read,
@@ -873,30 +843,25 @@ static const struct ide_port_ops scc_port_ops = {
static const struct ide_dma_ops scc_dma_ops = {
.dma_host_set = scc_dma_host_set,
.dma_setup = scc_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = scc_dma_start,
.dma_end = scc_dma_end,
.dma_test_irq = scc_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = scc_dma_sff_read_status,
};
-#define DECLARE_SCC_DEV(name_str) \
- { \
- .name = name_str, \
- .init_iops = init_iops_scc, \
- .init_dma = scc_init_dma, \
- .init_hwif = init_hwif_scc, \
- .tp_ops = &scc_tp_ops, \
- .port_ops = &scc_port_ops, \
- .dma_ops = &scc_dma_ops, \
- .host_flags = IDE_HFLAG_SINGLE, \
- .pio_mask = ATA_PIO4, \
- }
-
-static const struct ide_port_info scc_chipsets[] __devinitdata = {
- /* 0 */ DECLARE_SCC_DEV("sccIDE"),
+static const struct ide_port_info scc_chipset __devinitdata = {
+ .name = "sccIDE",
+ .init_iops = init_iops_scc,
+ .init_dma = scc_init_dma,
+ .init_hwif = init_hwif_scc,
+ .tp_ops = &scc_tp_ops,
+ .port_ops = &scc_port_ops,
+ .dma_ops = &scc_dma_ops,
+ .host_flags = IDE_HFLAG_SINGLE,
+ .irq_flags = IRQF_SHARED,
+ .pio_mask = ATA_PIO4,
};
/**
@@ -910,7 +875,7 @@ static const struct ide_port_info scc_chipsets[] __devinitdata = {
static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- return init_setup_scc(dev, &scc_chipsets[id->driver_data]);
+ return init_setup_scc(dev, &scc_chipset);
}
/**
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c
index 382102ba467b..b6554ef92716 100644
--- a/drivers/ide/serverworks.c
+++ b/drivers/ide/serverworks.c
@@ -175,7 +175,7 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x54, ultra_enable);
}
-static unsigned int init_chipset_svwks(struct pci_dev *dev)
+static int init_chipset_svwks(struct pci_dev *dev)
{
unsigned int reg;
u8 btr;
@@ -270,7 +270,7 @@ static unsigned int init_chipset_svwks(struct pci_dev *dev)
pci_write_config_byte(dev, 0x5A, btr);
}
- return dev->irq;
+ return 0;
}
static u8 ata66_svwks_svwks(ide_hwif_t *hwif)
@@ -353,14 +353,11 @@ static const struct ide_port_ops svwks_port_ops = {
.cable_detect = svwks_cable_detect,
};
-#define IDE_HFLAGS_SVWKS IDE_HFLAG_LEGACY_IRQS
-
static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
{ /* 0: OSB4 */
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &osb4_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = 0x00, /* UDMA is problematic on OSB4 */
@@ -369,7 +366,6 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &svwks_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -378,7 +374,6 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &svwks_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -387,7 +382,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &svwks_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE,
+ .host_flags = IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -396,7 +391,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
.port_ops = &svwks_port_ops,
- .host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE,
+ .host_flags = IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index e85d1ed29c2a..a19dbccd7617 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -305,7 +305,6 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *
* @dev: PCI device holding interface
* @d: IDE port info
* @port: port number
- * @irq: PCI IRQ
* @hw: hw_regs_t instance corresponding to this port
*
* Perform the initial set up for the hardware interface structure. This
@@ -316,7 +315,7 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *
*/
static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d,
- unsigned int port, int irq, hw_regs_t *hw)
+ unsigned int port, hw_regs_t *hw)
{
unsigned long ctl = 0, base = 0;
@@ -344,7 +343,6 @@ static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d,
}
memset(hw, 0, sizeof(*hw));
- hw->irq = irq;
hw->dev = &dev->dev;
hw->chipset = d->chipset ? d->chipset : ide_pci;
ide_std_init_ports(hw, base, ctl | 2);
@@ -448,7 +446,6 @@ out:
* ide_pci_setup_ports - configure ports/devices on PCI IDE
* @dev: PCI device
* @d: IDE port info
- * @pciirq: IRQ line
* @hw: hw_regs_t instances corresponding to this PCI IDE device
* @hws: hw_regs_t pointers table to update
*
@@ -462,7 +459,7 @@ out:
*/
void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d,
- int pciirq, hw_regs_t *hw, hw_regs_t **hws)
+ hw_regs_t *hw, hw_regs_t **hws)
{
int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port;
u8 tmp;
@@ -481,7 +478,7 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d,
continue; /* port not enabled */
}
- if (ide_hw_configure(dev, d, port, pciirq, hw + port))
+ if (ide_hw_configure(dev, d, port, hw + port))
continue;
*(hws + port) = hw + port;
@@ -524,7 +521,7 @@ static int do_ide_setup_pci_device(struct pci_dev *dev,
if (noisy)
printk(KERN_INFO "%s %s: not 100%% native mode: will "
"probe irqs later\n", d->name, pci_name(dev));
- pciirq = ret;
+ pciirq = 0;
} else if (!pciirq && noisy) {
printk(KERN_WARNING "%s %s: bad irq (%d): will probe later\n",
d->name, pci_name(dev), pciirq);
@@ -549,7 +546,7 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d,
if (ret < 0)
goto out;
- ide_pci_setup_ports(dev, d, 0, &hw[0], &hws[0]);
+ ide_pci_setup_ports(dev, d, &hw[0], &hws[0]);
host = ide_host_alloc(d, hws);
if (host == NULL) {
@@ -561,6 +558,8 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d,
host->host_priv = priv;
+ host->irq_flags = IRQF_SHARED;
+
pci_set_drvdata(dev, host);
ret = do_ide_setup_pci_device(dev, d, 1);
@@ -568,7 +567,11 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d,
goto out;
/* fixup IRQ */
- hw[1].irq = hw[0].irq = ret;
+ if (ide_pci_is_in_compatibility_mode(dev)) {
+ hw[0].irq = pci_get_legacy_ide_irq(dev, 0);
+ hw[1].irq = pci_get_legacy_ide_irq(dev, 1);
+ } else
+ hw[1].irq = hw[0].irq = ret;
ret = ide_host_register(host, d, hws);
if (ret)
@@ -591,7 +594,7 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
if (ret < 0)
goto out;
- ide_pci_setup_ports(pdev[i], d, 0, &hw[i*2], &hws[i*2]);
+ ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]);
}
host = ide_host_alloc(d, hws);
@@ -605,6 +608,8 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
host->host_priv = priv;
+ host->irq_flags = IRQF_SHARED;
+
pci_set_drvdata(pdev[0], host);
pci_set_drvdata(pdev[1], host);
@@ -619,7 +624,11 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
goto out;
/* fixup IRQ */
- hw[i*2 + 1].irq = hw[i*2].irq = ret;
+ if (ide_pci_is_in_compatibility_mode(pdev[i])) {
+ hw[i*2].irq = pci_get_legacy_ide_irq(pdev[i], 0);
+ hw[i*2 + 1].irq = pci_get_legacy_ide_irq(pdev[i], 1);
+ } else
+ hw[i*2 + 1].irq = hw[i*2].irq = ret;
}
ret = ide_host_register(host, d, hws);
diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c
index fdb9d7037694..e5d2a48a84de 100644
--- a/drivers/ide/sgiioc4.c
+++ b/drivers/ide/sgiioc4.c
@@ -258,9 +258,6 @@ static int sgiioc4_dma_end(ide_drive_t *drive)
}
}
- drive->waiting_for_dma = 0;
- ide_destroy_dmatable(drive);
-
return dma_stat;
}
@@ -280,10 +277,12 @@ static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
sgiioc4_clearirq(drive);
}
-static void
-sgiioc4_resetproc(ide_drive_t * drive)
+static void sgiioc4_resetproc(ide_drive_t *drive)
{
+ struct ide_cmd *cmd = &drive->hwif->cmd;
+
sgiioc4_dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
sgiioc4_clearirq(drive);
}
@@ -412,7 +411,6 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
writel(dma_direction, (void __iomem *)ioc4_dma_addr);
- drive->waiting_for_dma = 1;
}
/* IOC4 Scatter Gather list Format */
@@ -424,20 +422,13 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
/* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */
/* --------------------------------------------------------------------- */
/* Creates the scatter gather list, DMA Table */
-static unsigned int
-sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
+static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
unsigned int *table = hwif->dmatable_cpu;
- unsigned int count = 0, i = 1;
- struct scatterlist *sg;
-
- hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
- if (!i)
- return 0; /* sglist of length Zero */
+ unsigned int count = 0, i = cmd->sg_nents;
+ struct scatterlist *sg = hwif->sg_table;
- sg = hwif->sg_table;
while (i && sg_dma_len(sg)) {
dma_addr_t cur_addr;
int cur_len;
@@ -449,7 +440,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
printk(KERN_WARNING
"%s: DMA table too small\n",
drive->name);
- goto use_pio_instead;
+ return 0;
} else {
u32 bcount =
0x10000 - (cur_addr & 0xffff);
@@ -484,30 +475,19 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
return count;
}
-use_pio_instead:
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
-static int sgiioc4_dma_setup(ide_drive_t *drive)
+static int sgiioc4_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
- struct request *rq = drive->hwif->rq;
- unsigned int count = 0;
int ddir;
+ u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- if (rq_data_dir(rq))
- ddir = PCI_DMA_TODEVICE;
- else
- ddir = PCI_DMA_FROMDEVICE;
-
- if (!(count = sgiioc4_build_dma_table(drive, rq, ddir))) {
+ if (sgiioc4_build_dmatable(drive, cmd) == 0)
/* try PIO instead of DMA */
- ide_map_sg(drive, rq);
return 1;
- }
- if (rq_data_dir(rq))
+ if (write)
/* Writes TO the IOC4 FROM Main Memory */
ddir = IOC4_DMA_READ;
else
@@ -523,9 +503,9 @@ static const struct ide_tp_ops sgiioc4_tp_ops = {
.exec_command = ide_exec_command,
.read_status = sgiioc4_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
@@ -546,7 +526,6 @@ static const struct ide_dma_ops sgiioc4_dma_ops = {
.dma_end = sgiioc4_dma_end,
.dma_test_irq = sgiioc4_dma_test_irq,
.dma_lost_irq = sgiioc4_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
};
static const struct ide_port_info sgiioc4_port_info __devinitconst = {
@@ -557,6 +536,7 @@ static const struct ide_port_info sgiioc4_port_info __devinitconst = {
.port_ops = &sgiioc4_port_ops,
.dma_ops = &sgiioc4_dma_ops,
.host_flags = IDE_HFLAG_MMIO,
+ .irq_flags = IRQF_SHARED,
.mwdma_mask = ATA_MWDMA2_ONLY,
};
diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c
index cb2b352b876b..e4973cd1fba9 100644
--- a/drivers/ide/siimage.c
+++ b/drivers/ide/siimage.c
@@ -464,7 +464,7 @@ static void sil_sata_pre_reset(ide_drive_t *drive)
* to 133 MHz clocking if the system isn't already set up to do it.
*/
-static unsigned int init_chipset_siimage(struct pci_dev *dev)
+static int init_chipset_siimage(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
void __iomem *ioaddr = host->host_priv;
@@ -711,11 +711,10 @@ static const struct ide_port_ops sil_sata_port_ops = {
static const struct ide_dma_ops sil_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = siimage_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_lost_irq = ide_dma_lost_irq,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index 9ec1a4a4432c..afca22beaadf 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -447,7 +447,7 @@ static int __devinit sis_find_family(struct pci_dev *dev)
return chipset_family;
}
-static unsigned int init_chipset_sis5513(struct pci_dev *dev)
+static int init_chipset_sis5513(struct pci_dev *dev)
{
/* Make general config ops here
1/ tell IDE channels to operate in Compatibility mode only
@@ -563,7 +563,7 @@ static const struct ide_port_info sis5513_chipset __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_sis5513,
.enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} },
- .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA,
+ .host_flags = IDE_HFLAG_NO_AUTODMA,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
};
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index 6297956507c0..b0a460625335 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -61,7 +61,8 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
if (cmd_off == 0)
cmd_off = 1;
- if (pio > 2 || ata_id_has_iordy(drive->id))
+ if ((pio > 2 || ata_id_has_iordy(drive->id)) &&
+ !(pio > 4 && ata_id_is_cfa(drive->id)))
iordy = 0x40;
return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy;
@@ -189,14 +190,13 @@ static void sl82c105_dma_start(ide_drive_t *drive)
ide_dma_start(drive);
}
-static void sl82c105_dma_timeout(ide_drive_t *drive)
+static void sl82c105_dma_clear(ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
- DBG(("sl82c105_dma_timeout(drive:%s)\n", drive->name));
+ DBG(("sl82c105_dma_clear(drive:%s)\n", drive->name));
sl82c105_reset_host(dev);
- ide_dma_timeout(drive);
}
static int sl82c105_dma_end(ide_drive_t *drive)
@@ -271,7 +271,7 @@ static u8 sl82c105_bridge_revision(struct pci_dev *dev)
* channel 0 here at least, but channel 1 has to be enabled by
* firmware or arch code. We still set both to 16 bits mode.
*/
-static unsigned int init_chipset_sl82c105(struct pci_dev *dev)
+static int init_chipset_sl82c105(struct pci_dev *dev)
{
u32 val;
@@ -281,7 +281,7 @@ static unsigned int init_chipset_sl82c105(struct pci_dev *dev)
val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
pci_write_config_dword(dev, 0x40, val);
- return dev->irq;
+ return 0;
}
static const struct ide_port_ops sl82c105_port_ops = {
@@ -293,12 +293,12 @@ static const struct ide_port_ops sl82c105_port_ops = {
static const struct ide_dma_ops sl82c105_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = sl82c105_dma_start,
.dma_end = sl82c105_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = sl82c105_dma_lost_irq,
- .dma_timeout = sl82c105_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
+ .dma_clear = sl82c105_dma_clear,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c
index 40b4b94a4288..f55d7d6313e8 100644
--- a/drivers/ide/slc90e66.c
+++ b/drivers/ide/slc90e66.c
@@ -136,7 +136,6 @@ static const struct ide_port_info slc90e66_chipset __devinitdata = {
.name = DRV_NAME,
.enablebits = { {0x41, 0x80, 0x80}, {0x43, 0x80, 0x80} },
.port_ops = &slc90e66_port_ops,
- .host_flags = IDE_HFLAG_LEGACY_IRQS,
.pio_mask = ATA_PIO4,
.swdma_mask = ATA_SWDMA2_ONLY,
.mwdma_mask = ATA_MWDMA12_ONLY,
diff --git a/drivers/ide/tc86c001.c b/drivers/ide/tc86c001.c
index 84109f5a1632..b4cf42dc8a6f 100644
--- a/drivers/ide/tc86c001.c
+++ b/drivers/ide/tc86c001.c
@@ -182,12 +182,11 @@ static const struct ide_port_ops tc86c001_port_ops = {
static const struct ide_dma_ops tc86c001_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = tc86c001_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c
index b6a1285a4021..4b42ca091534 100644
--- a/drivers/ide/trm290.c
+++ b/drivers/ide/trm290.c
@@ -171,58 +171,51 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
local_irq_restore(flags);
}
-static void trm290_selectproc (ide_drive_t *drive)
+static void trm290_dev_select(ide_drive_t *drive)
{
trm290_prepare_drive(drive, !!(drive->dev_flags & IDE_DFLAG_USING_DMA));
-}
-static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
- ide_execute_command(drive, command, &ide_dma_intr, WAIT_CMD, NULL);
+ outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
}
-static int trm290_dma_setup(ide_drive_t *drive)
+static int trm290_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
{
- ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
- unsigned int count, rw;
-
- if (rq_data_dir(rq)) {
+ if (cmd->tf_flags & IDE_TFLAG_WRITE) {
#ifdef TRM290_NO_DMA_WRITES
/* always use PIO for writes */
- trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
#endif
- rw = 1;
- } else
- rw = 2;
+ }
+ return 0;
+}
+
+static int trm290_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ unsigned int count, rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 2;
- if (!(count = ide_build_dmatable(drive, rq))) {
+ count = ide_build_dmatable(drive, cmd);
+ if (count == 0)
/* try PIO instead of DMA */
- trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
- }
- /* select DMA xfer */
- trm290_prepare_drive(drive, 1);
+
outl(hwif->dmatable_dma | rw, hwif->dma_base);
- drive->waiting_for_dma = 1;
/* start DMA */
outw(count * 2 - 1, hwif->dma_base + 2);
+
return 0;
}
static void trm290_dma_start(ide_drive_t *drive)
{
+ trm290_prepare_drive(drive, 1);
}
static int trm290_dma_end(ide_drive_t *drive)
{
- u16 status;
+ u16 status = inw(drive->hwif->dma_base + 2);
- drive->waiting_for_dma = 0;
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
- status = inw(drive->hwif->dma_base + 2);
+ trm290_prepare_drive(drive, 0);
return status != 0x00ff;
}
@@ -277,9 +270,6 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
if (reg & 0x10)
/* legacy mode */
hwif->irq = hwif->channel ? 15 : 14;
- else if (!hwif->irq && hwif->mate && hwif->mate->irq)
- /* sharing IRQ with mate */
- hwif->irq = hwif->mate->irq;
#if 1
{
@@ -310,25 +300,34 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
#endif
}
-static const struct ide_port_ops trm290_port_ops = {
- .selectproc = trm290_selectproc,
+static const struct ide_tp_ops trm290_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
+
+ .dev_select = trm290_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
};
static struct ide_dma_ops trm290_dma_ops = {
.dma_host_set = trm290_dma_host_set,
.dma_setup = trm290_dma_setup,
- .dma_exec_cmd = trm290_dma_exec_cmd,
.dma_start = trm290_dma_start,
.dma_end = trm290_dma_end,
.dma_test_irq = trm290_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_check = trm290_dma_check,
};
static const struct ide_port_info trm290_chipset __devinitdata = {
.name = DRV_NAME,
.init_hwif = init_hwif_trm290,
- .port_ops = &trm290_port_ops,
+ .tp_ops = &trm290_tp_ops,
.dma_ops = &trm290_dma_ops,
.host_flags = IDE_HFLAG_TRM290 |
IDE_HFLAG_NO_ATAPI_DMA |
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c
index d9095345f7ca..4cb79c4c2604 100644
--- a/drivers/ide/tx4938ide.c
+++ b/drivers/ide/tx4938ide.c
@@ -15,6 +15,8 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+
+#include <asm/ide.h>
#include <asm/txx9/tx4938.h>
static void tx4938ide_tune_ebusc(unsigned int ebus_ch,
@@ -80,99 +82,82 @@ static void tx4938ide_outb(u8 value, unsigned long port)
__raw_writeb(value, (void __iomem *)port);
}
-static void tx4938ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void tx4938ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- /* no endian swap */
- __raw_writew(data, (void __iomem *)io_ports->data_addr);
- }
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
tx4938ide_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
tx4938ide_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
tx4938ide_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
tx4938ide_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
tx4938ide_outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
tx4938ide_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
tx4938ide_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
tx4938ide_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
tx4938ide_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
tx4938ide_outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
tx4938ide_outb((tf->device & HIHI) | drive->select,
io_ports->device_addr);
}
-static void tx4938ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void tx4938ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data;
-
- /* no endian swap */
- data = __raw_readw((void __iomem *)io_ports->data_addr);
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
+ struct ide_taskfile *tf = &cmd->tf;
/* be sure we're looking at the low order bits */
- tx4938ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ tx4938ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = tx4938ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = tx4938ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tx4938ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = tx4938ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = tx4938ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = tx4938ide_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = tx4938ide_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- tx4938ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature =
- tx4938ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ tx4938ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = tx4938ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr);
}
}
-static void tx4938ide_input_data_swap(ide_drive_t *drive, struct request *rq,
+static void tx4938ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long port = drive->hwif->io_ports.data_addr;
@@ -184,7 +169,7 @@ static void tx4938ide_input_data_swap(ide_drive_t *drive, struct request *rq,
__ide_flush_dcache_range((unsigned long)buf, roundup(len, 2));
}
-static void tx4938ide_output_data_swap(ide_drive_t *drive, struct request *rq,
+static void tx4938ide_output_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long port = drive->hwif->io_ports.data_addr;
@@ -202,9 +187,9 @@ static const struct ide_tp_ops tx4938ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = tx4938ide_tf_load,
.tf_read = tx4938ide_tf_read,
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index 40b0812a045c..0040a9a3e26e 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -18,6 +18,8 @@
#include <linux/io.h>
#include <linux/scatterlist.h>
+#include <asm/ide.h>
+
#define MODNAME "tx4939ide"
/* ATA Shadow Registers (8-bit except for Data which is 16-bit) */
@@ -230,7 +232,7 @@ static u8 tx4939ide_clear_dma_status(void __iomem *base)
#ifdef __BIG_ENDIAN
/* custom ide_build_dmatable to handle swapped layout */
-static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+static int tx4939ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
u32 *table = (u32 *)hwif->dmatable_cpu;
@@ -238,11 +240,7 @@ static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq)
int i;
struct scatterlist *sg;
- hwif->sg_nents = ide_build_sglist(drive, rq);
- if (hwif->sg_nents == 0)
- return 0;
-
- for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
+ for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) {
u32 cur_addr, cur_len, bcount;
cur_addr = sg_dma_address(sg);
@@ -281,48 +279,36 @@ use_pio_instead:
printk(KERN_ERR "%s: %s\n", drive->name,
count ? "DMA table too small" : "empty DMA table?");
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
#else
#define tx4939ide_build_dmatable ide_build_dmatable
#endif
-static int tx4939ide_dma_setup(ide_drive_t *drive)
+static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
void __iomem *base = TX4939IDE_BASE(hwif);
- struct request *rq = hwif->rq;
- u8 reading;
- int nent;
-
- if (rq_data_dir(rq))
- reading = 0;
- else
- reading = ATA_DMA_WR;
+ u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
/* fall back to PIO! */
- nent = tx4939ide_build_dmatable(drive, rq);
- if (!nent) {
- ide_map_sg(drive, rq);
+ if (tx4939ide_build_dmatable(drive, cmd) == 0)
return 1;
- }
/* PRD table */
tx4939ide_writel(hwif->dmatable_dma, base, TX4939IDE_PRD_Ptr);
/* specify r/w */
- tx4939ide_writeb(reading, base, TX4939IDE_DMA_Cmd);
+ tx4939ide_writeb(rw, base, TX4939IDE_DMA_Cmd);
/* clear INTR & ERROR flags */
tx4939ide_clear_dma_status(base);
- drive->waiting_for_dma = 1;
-
tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ?
TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1);
- tx4939ide_writew(rq->nr_sectors, base, TX4939IDE_Sec_Cnt);
+
+ tx4939ide_writew(cmd->rq->nr_sectors, base, TX4939IDE_Sec_Cnt);
+
return 0;
}
@@ -333,8 +319,6 @@ static int tx4939ide_dma_end(ide_drive_t *drive)
void __iomem *base = TX4939IDE_BASE(hwif);
u16 ctl = tx4939ide_readw(base, TX4939IDE_Int_Ctl);
- drive->waiting_for_dma = 0;
-
/* get DMA command mode */
dma_cmd = tx4939ide_readb(base, TX4939IDE_DMA_Cmd);
/* stop DMA */
@@ -343,11 +327,9 @@ static int tx4939ide_dma_end(ide_drive_t *drive)
/* read and clear the INTR & ERROR bits */
dma_stat = tx4939ide_clear_dma_status(base);
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
- /* verify good DMA status */
wmb();
+ /* verify good DMA status */
if ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == 0 &&
(ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) ==
(TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST))
@@ -437,7 +419,7 @@ static int tx4939ide_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
return ide_allocate_dma_engine(hwif);
}
-static void tx4939ide_tf_load_fixup(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_load_fixup(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
void __iomem *base = TX4939IDE_BASE(hwif);
@@ -447,7 +429,7 @@ static void tx4939ide_tf_load_fixup(ide_drive_t *drive, ide_task_t *task)
* Fix ATA100 CORE System Control Register. (The write to the
* Device/Head register may write wrong data to the System
* Control Register)
- * While Sys_Ctl is written here, selectproc is not needed.
+ * While Sys_Ctl is written here, dev_select() is not needed.
*/
tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl);
}
@@ -465,97 +447,80 @@ static void tx4939ide_outb(u8 value, unsigned long port)
__raw_writeb(value, (void __iomem *)port);
}
-static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- /* no endian swap */
- __raw_writew(data, (void __iomem *)io_ports->data_addr);
- }
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
tx4939ide_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
tx4939ide_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
tx4939ide_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
tx4939ide_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
tx4939ide_outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
tx4939ide_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
tx4939ide_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
tx4939ide_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
tx4939ide_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
tx4939ide_outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) {
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) {
tx4939ide_outb((tf->device & HIHI) | drive->select,
io_ports->device_addr);
- tx4939ide_tf_load_fixup(drive, task);
+ tx4939ide_tf_load_fixup(drive);
}
}
-static void tx4939ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data;
-
- /* no endian swap */
- data = __raw_readw((void __iomem *)io_ports->data_addr);
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
+ struct ide_taskfile *tf = &cmd->tf;
/* be sure we're looking at the low order bits */
- tx4939ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ tx4939ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = tx4939ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = tx4939ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tx4939ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = tx4939ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = tx4939ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = tx4939ide_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = tx4939ide_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- tx4939ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature =
- tx4939ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ tx4939ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = tx4939ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr);
}
}
@@ -589,9 +554,9 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = tx4939ide_tf_load,
.tf_read = tx4939ide_tf_read,
@@ -601,20 +566,21 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
#else /* __LITTLE_ENDIAN */
-static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
- ide_tf_load(drive, task);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
- tx4939ide_tf_load_fixup(drive, task);
+ ide_tf_load(drive, cmd);
+
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ tx4939ide_tf_load_fixup(drive);
}
static const struct ide_tp_ops tx4939ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = tx4939ide_tf_load,
.tf_read = ide_tf_read,
@@ -634,12 +600,11 @@ static const struct ide_port_ops tx4939ide_port_ops = {
static const struct ide_dma_ops tx4939ide_dma_ops = {
.dma_host_set = tx4939ide_dma_host_set,
.dma_setup = tx4939ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = tx4939ide_dma_end,
.dma_test_irq = tx4939ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = tx4939ide_dma_sff_read_status,
};
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index 6092fe3f409d..3ff7231e4858 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -267,7 +267,7 @@ static void via_cable_detect(struct via82cxxx_dev *vdev, u32 u)
* and initialize its drive independent registers.
*/
-static unsigned int init_chipset_via82cxxx(struct pci_dev *dev)
+static int init_chipset_via82cxxx(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
struct via82cxxx_dev *vdev = host->host_priv;
@@ -443,16 +443,6 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
if ((via_config->flags & VIA_NO_UNMASK) == 0)
d.host_flags |= IDE_HFLAG_UNMASK_IRQS;
-#ifdef CONFIG_PPC_CHRP
- if (machine_is(chrp) && _chrp_type == _CHRP_Pegasos)
- d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS;
-#endif
-
-#ifdef CONFIG_AMIGAONE
- if (machine_is(amigaone))
- d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS;
-#endif
-
d.udma_mask = via_config->udma_mask;
vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
diff --git a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c
index 31400c8ae051..d696f69ebce5 100644
--- a/drivers/ieee1394/csr.c
+++ b/drivers/ieee1394/csr.c
@@ -68,22 +68,22 @@ static struct hpsb_highlevel csr_highlevel = {
.host_reset = host_reset,
};
-const static struct hpsb_address_ops map_ops = {
+static const struct hpsb_address_ops map_ops = {
.read = read_maps,
};
-const static struct hpsb_address_ops fcp_ops = {
+static const struct hpsb_address_ops fcp_ops = {
.write = write_fcp,
};
-const static struct hpsb_address_ops reg_ops = {
+static const struct hpsb_address_ops reg_ops = {
.read = read_regs,
.write = write_regs,
.lock = lock_regs,
.lock64 = lock64_regs,
};
-const static struct hpsb_address_ops config_rom_ops = {
+static const struct hpsb_address_ops config_rom_ops = {
.read = read_config_rom,
};
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 3838bc4acaba..823a6297a1af 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -1325,11 +1325,7 @@ static int dv1394_fasync(int fd, struct file *file, int on)
struct video_card *video = file_to_video_card(file);
- int retval = fasync_helper(fd, file, on, &video->fasync);
-
- if (retval < 0)
- return retval;
- return 0;
+ return fasync_helper(fd, file, on, &video->fasync);
}
static ssize_t dv1394_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
@@ -2175,7 +2171,7 @@ static const struct file_operations dv1394_fops=
* Export information about protocols/devices supported by this driver.
*/
#ifdef MODULE
-static struct ieee1394_device_id dv1394_id_table[] = {
+static const struct ieee1394_device_id dv1394_id_table[] = {
{
.match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
.specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index 1a919df809f8..4ca103577c0a 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -181,7 +181,7 @@ static void ether1394_remove_host(struct hpsb_host *host);
static void ether1394_host_reset(struct hpsb_host *host);
/* Function for incoming 1394 packets */
-const static struct hpsb_address_ops addr_ops = {
+static const struct hpsb_address_ops addr_ops = {
.write = ether1394_write,
};
@@ -438,7 +438,7 @@ static int eth1394_update(struct unit_directory *ud)
return eth1394_new_node(hi, ud);
}
-static struct ieee1394_device_id eth1394_id_table[] = {
+static const struct ieee1394_device_id eth1394_id_table[] = {
{
.match_flags = (IEEE1394_MATCH_SPECIFIER_ID |
IEEE1394_MATCH_VERSION),
diff --git a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c
index 600e391c8fe7..4bc443546e04 100644
--- a/drivers/ieee1394/highlevel.c
+++ b/drivers/ieee1394/highlevel.c
@@ -478,7 +478,7 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host,
return retval;
}
-const static struct hpsb_address_ops dummy_ops;
+static const struct hpsb_address_ops dummy_ops;
/* dummy address spaces as lower and upper bounds of the host's a.s. list */
static void init_hpsb_highlevel(struct hpsb_host *host)
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 53aada5bbe1e..a6d55bebe61a 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -484,7 +484,7 @@ static struct device_attribute *const fw_host_attrs[] = {
static ssize_t fw_show_drv_device_ids(struct device_driver *drv, char *buf)
{
struct hpsb_protocol_driver *driver;
- struct ieee1394_device_id *id;
+ const struct ieee1394_device_id *id;
int length = 0;
char *scratch = buf;
@@ -658,7 +658,7 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
{
struct hpsb_protocol_driver *driver;
struct unit_directory *ud;
- struct ieee1394_device_id *id;
+ const struct ieee1394_device_id *id;
/* We only match unit directories */
if (dev->platform_data != &nodemgr_ud_platform_data)
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h
index ee5acdbd114a..749b271d3107 100644
--- a/drivers/ieee1394/nodemgr.h
+++ b/drivers/ieee1394/nodemgr.h
@@ -125,7 +125,7 @@ struct hpsb_protocol_driver {
* probe function below can implement further protocol
* dependent or vendor dependent checking.
*/
- struct ieee1394_device_id *id_table;
+ const struct ieee1394_device_id *id_table;
/*
* The update function is called when the node has just
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index bad66c65b0d6..da5f8829b503 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -90,7 +90,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
u16 flags);
-const static struct hpsb_address_ops arm_ops = {
+static const struct hpsb_address_ops arm_ops = {
.read = arm_read,
.write = arm_write,
.lock = arm_lock,
@@ -369,6 +369,7 @@ static const char __user *raw1394_compat_write(const char __user *buf)
{
struct compat_raw1394_req __user *cr = (typeof(cr)) buf;
struct raw1394_request __user *r;
+
r = compat_alloc_user_space(sizeof(struct raw1394_request));
#define C(x) __copy_in_user(&r->x, &cr->x, sizeof(r->x))
@@ -378,7 +379,8 @@ static const char __user *raw1394_compat_write(const char __user *buf)
C(tag) ||
C(sendb) ||
C(recvb))
- return ERR_PTR(-EFAULT);
+ return (__force const char __user *)ERR_PTR(-EFAULT);
+
return (const char __user *)r;
}
#undef C
@@ -389,6 +391,7 @@ static int
raw1394_compat_read(const char __user *buf, struct raw1394_request *r)
{
struct compat_raw1394_req __user *cr = (typeof(cr)) buf;
+
if (!access_ok(VERIFY_WRITE, cr, sizeof(struct compat_raw1394_req)) ||
P(type) ||
P(error) ||
@@ -400,6 +403,7 @@ raw1394_compat_read(const char __user *buf, struct raw1394_request *r)
P(sendb) ||
P(recvb))
return -EFAULT;
+
return sizeof(struct compat_raw1394_req);
}
#undef P
@@ -2249,8 +2253,8 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
sizeof(struct compat_raw1394_req) !=
sizeof(struct raw1394_request)) {
buffer = raw1394_compat_write(buffer);
- if (IS_ERR(buffer))
- return PTR_ERR(buffer);
+ if (IS_ERR((__force void *)buffer))
+ return PTR_ERR((__force void *)buffer);
} else
#endif
if (count != sizeof(struct raw1394_request)) {
@@ -2978,7 +2982,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
* Export information about protocols/devices supported by this driver.
*/
#ifdef MODULE
-static struct ieee1394_device_id raw1394_id_table[] = {
+static const struct ieee1394_device_id raw1394_id_table[] = {
{
.match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
.specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index f3fd8657ce4b..a51ab233342d 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -265,7 +265,7 @@ static struct hpsb_highlevel sbp2_highlevel = {
.host_reset = sbp2_host_reset,
};
-const static struct hpsb_address_ops sbp2_ops = {
+static const struct hpsb_address_ops sbp2_ops = {
.write = sbp2_handle_status_write
};
@@ -275,7 +275,7 @@ static int sbp2_handle_physdma_write(struct hpsb_host *, int, int, quadlet_t *,
static int sbp2_handle_physdma_read(struct hpsb_host *, int, quadlet_t *, u64,
size_t, u16);
-const static struct hpsb_address_ops sbp2_physdma_ops = {
+static const struct hpsb_address_ops sbp2_physdma_ops = {
.read = sbp2_handle_physdma_read,
.write = sbp2_handle_physdma_write,
};
@@ -285,7 +285,7 @@ const static struct hpsb_address_ops sbp2_physdma_ops = {
/*
* Interface to driver core and IEEE 1394 core
*/
-static struct ieee1394_device_id sbp2_id_table[] = {
+static const struct ieee1394_device_id sbp2_id_table[] = {
{
.match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
.specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
@@ -1413,8 +1413,7 @@ static void sbp2_parse_unit_directory(struct sbp2_lu *lu,
"(firmware_revision 0x%06x, vendor_id 0x%06x,"
" model_id 0x%06x)",
NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid),
- workarounds, firmware_revision,
- ud->vendor_id ? ud->vendor_id : ud->ne->vendor_id,
+ workarounds, firmware_revision, ud->vendor_id,
model);
/* We would need one SCSI host template for each target to adjust
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 679a918a5cc7..d287ba79821d 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -1294,7 +1294,7 @@ static const struct file_operations video1394_fops=
* Export information about protocols/devices supported by this driver.
*/
#ifdef MODULE
-static struct ieee1394_device_id video1394_id_table[] = {
+static const struct ieee1394_device_id video1394_id_table[] = {
{
.match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
.specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index f1e82a92e61e..5130fc55b8e2 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -927,8 +927,7 @@ int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask,
unsigned long flags;
int ret = 0;
- service_mask = service_mask ? service_mask :
- __constant_cpu_to_be64(~0ULL);
+ service_mask = service_mask ? service_mask : ~cpu_to_be64(0);
service_id &= service_mask;
if ((service_id & IB_SERVICE_ID_AGN_MASK) == IB_CM_ASSIGN_SERVICE_ID &&
(service_id != IB_CM_ASSIGN_SERVICE_ID))
@@ -954,7 +953,7 @@ int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask,
spin_lock_irqsave(&cm.lock, flags);
if (service_id == IB_CM_ASSIGN_SERVICE_ID) {
cm_id->service_id = cpu_to_be64(cm.listen_service_id++);
- cm_id->service_mask = __constant_cpu_to_be64(~0ULL);
+ cm_id->service_mask = ~cpu_to_be64(0);
} else {
cm_id->service_id = service_id;
cm_id->service_mask = service_mask;
@@ -1134,7 +1133,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
goto error1;
}
cm_id->service_id = param->service_id;
- cm_id->service_mask = __constant_cpu_to_be64(~0ULL);
+ cm_id->service_mask = ~cpu_to_be64(0);
cm_id_priv->timeout_ms = cm_convert_to_ms(
param->primary_path->packet_life_time) * 2 +
cm_convert_to_ms(
@@ -1545,7 +1544,7 @@ static int cm_req_handler(struct cm_work *work)
cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler;
cm_id_priv->id.context = listen_cm_id_priv->id.context;
cm_id_priv->id.service_id = req_msg->service_id;
- cm_id_priv->id.service_mask = __constant_cpu_to_be64(~0ULL);
+ cm_id_priv->id.service_mask = ~cpu_to_be64(0);
cm_process_routed_req(req_msg, work->mad_recv_wc->wc);
cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
@@ -2898,7 +2897,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,
goto out;
cm_id->service_id = param->service_id;
- cm_id->service_mask = __constant_cpu_to_be64(~0ULL);
+ cm_id->service_mask = ~cpu_to_be64(0);
cm_id_priv->timeout_ms = param->timeout_ms;
cm_id_priv->max_cm_retries = param->max_cm_retries;
ret = cm_alloc_msg(cm_id_priv, &msg);
@@ -2992,7 +2991,7 @@ static int cm_sidr_req_handler(struct cm_work *work)
cm_id_priv->id.cm_handler = cur_cm_id_priv->id.cm_handler;
cm_id_priv->id.context = cur_cm_id_priv->id.context;
cm_id_priv->id.service_id = sidr_req_msg->service_id;
- cm_id_priv->id.service_mask = __constant_cpu_to_be64(~0ULL);
+ cm_id_priv->id.service_mask = ~cpu_to_be64(0);
cm_format_sidr_req_event(work, &cur_cm_id_priv->id);
cm_process_work(cm_id_priv, work);
@@ -3789,7 +3788,7 @@ static int __init ib_cm_init(void)
rwlock_init(&cm.device_lock);
spin_lock_init(&cm.lock);
cm.listen_service_table = RB_ROOT;
- cm.listen_service_id = __constant_be64_to_cpu(IB_CM_ASSIGN_SERVICE_ID);
+ cm.listen_service_id = be64_to_cpu(IB_CM_ASSIGN_SERVICE_ID);
cm.remote_id_table = RB_ROOT;
cm.remote_qp_table = RB_ROOT;
cm.remote_sidr_table = RB_ROOT;
diff --git a/drivers/infiniband/core/cm_msgs.h b/drivers/infiniband/core/cm_msgs.h
index aec9c7af825d..7e63c08f697c 100644
--- a/drivers/infiniband/core/cm_msgs.h
+++ b/drivers/infiniband/core/cm_msgs.h
@@ -44,17 +44,17 @@
#define IB_CM_CLASS_VERSION 2 /* IB specification 1.2 */
-#define CM_REQ_ATTR_ID __constant_htons(0x0010)
-#define CM_MRA_ATTR_ID __constant_htons(0x0011)
-#define CM_REJ_ATTR_ID __constant_htons(0x0012)
-#define CM_REP_ATTR_ID __constant_htons(0x0013)
-#define CM_RTU_ATTR_ID __constant_htons(0x0014)
-#define CM_DREQ_ATTR_ID __constant_htons(0x0015)
-#define CM_DREP_ATTR_ID __constant_htons(0x0016)
-#define CM_SIDR_REQ_ATTR_ID __constant_htons(0x0017)
-#define CM_SIDR_REP_ATTR_ID __constant_htons(0x0018)
-#define CM_LAP_ATTR_ID __constant_htons(0x0019)
-#define CM_APR_ATTR_ID __constant_htons(0x001A)
+#define CM_REQ_ATTR_ID cpu_to_be16(0x0010)
+#define CM_MRA_ATTR_ID cpu_to_be16(0x0011)
+#define CM_REJ_ATTR_ID cpu_to_be16(0x0012)
+#define CM_REP_ATTR_ID cpu_to_be16(0x0013)
+#define CM_RTU_ATTR_ID cpu_to_be16(0x0014)
+#define CM_DREQ_ATTR_ID cpu_to_be16(0x0015)
+#define CM_DREP_ATTR_ID cpu_to_be16(0x0016)
+#define CM_SIDR_REQ_ATTR_ID cpu_to_be16(0x0017)
+#define CM_SIDR_REP_ATTR_ID cpu_to_be16(0x0018)
+#define CM_LAP_ATTR_ID cpu_to_be16(0x0019)
+#define CM_APR_ATTR_ID cpu_to_be16(0x001A)
enum cm_msg_sequence {
CM_MSG_SEQUENCE_REQ,
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 7913b804311e..d1fba4153332 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -193,7 +193,7 @@ void ib_dealloc_device(struct ib_device *device)
BUG_ON(device->reg_state != IB_DEV_UNREGISTERED);
- ib_device_unregister_sysfs(device);
+ kobject_put(&device->dev.kobj);
}
EXPORT_SYMBOL(ib_dealloc_device);
@@ -348,6 +348,8 @@ void ib_unregister_device(struct ib_device *device)
mutex_unlock(&device_mutex);
+ ib_device_unregister_sysfs(device);
+
spin_lock_irqsave(&device->client_data_lock, flags);
list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
kfree(context);
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 5c54fc2350be..de922a04ca2d 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -301,6 +301,16 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
mad_agent_priv->agent.context = context;
mad_agent_priv->agent.qp = port_priv->qp_info[qpn].qp;
mad_agent_priv->agent.port_num = port_num;
+ spin_lock_init(&mad_agent_priv->lock);
+ INIT_LIST_HEAD(&mad_agent_priv->send_list);
+ INIT_LIST_HEAD(&mad_agent_priv->wait_list);
+ INIT_LIST_HEAD(&mad_agent_priv->done_list);
+ INIT_LIST_HEAD(&mad_agent_priv->rmpp_list);
+ INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);
+ INIT_LIST_HEAD(&mad_agent_priv->local_list);
+ INIT_WORK(&mad_agent_priv->local_work, local_completions);
+ atomic_set(&mad_agent_priv->refcount, 1);
+ init_completion(&mad_agent_priv->comp);
spin_lock_irqsave(&port_priv->reg_lock, flags);
mad_agent_priv->agent.hi_tid = ++ib_mad_client_id;
@@ -350,17 +360,6 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
list_add_tail(&mad_agent_priv->agent_list, &port_priv->agent_list);
spin_unlock_irqrestore(&port_priv->reg_lock, flags);
- spin_lock_init(&mad_agent_priv->lock);
- INIT_LIST_HEAD(&mad_agent_priv->send_list);
- INIT_LIST_HEAD(&mad_agent_priv->wait_list);
- INIT_LIST_HEAD(&mad_agent_priv->done_list);
- INIT_LIST_HEAD(&mad_agent_priv->rmpp_list);
- INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);
- INIT_LIST_HEAD(&mad_agent_priv->local_list);
- INIT_WORK(&mad_agent_priv->local_work, local_completions);
- atomic_set(&mad_agent_priv->refcount, 1);
- init_completion(&mad_agent_priv->comp);
-
return &mad_agent_priv->agent;
error4:
@@ -743,9 +742,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
break;
case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED:
kmem_cache_free(ib_mad_cache, mad_priv);
- kfree(local);
- ret = 1;
- goto out;
+ break;
case IB_MAD_RESULT_SUCCESS:
/* Treat like an incoming receive MAD */
port_priv = ib_get_mad_port(mad_agent_priv->agent.device,
@@ -756,10 +753,12 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
&mad_priv->mad.mad);
}
if (!port_priv || !recv_mad_agent) {
+ /*
+ * No receiving agent so drop packet and
+ * generate send completion.
+ */
kmem_cache_free(ib_mad_cache, mad_priv);
- kfree(local);
- ret = 0;
- goto out;
+ break;
}
local->mad_priv = mad_priv;
local->recv_mad_agent = recv_mad_agent;
@@ -2356,7 +2355,7 @@ static void local_completions(struct work_struct *work)
struct ib_mad_local_private *local;
struct ib_mad_agent_private *recv_mad_agent;
unsigned long flags;
- int recv = 0;
+ int free_mad;
struct ib_wc wc;
struct ib_mad_send_wc mad_send_wc;
@@ -2370,14 +2369,15 @@ static void local_completions(struct work_struct *work)
completion_list);
list_del(&local->completion_list);
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+ free_mad = 0;
if (local->mad_priv) {
recv_mad_agent = local->recv_mad_agent;
if (!recv_mad_agent) {
printk(KERN_ERR PFX "No receive MAD agent for local completion\n");
+ free_mad = 1;
goto local_send_completion;
}
- recv = 1;
/*
* Defined behavior is to complete response
* before request
@@ -2422,7 +2422,7 @@ local_send_completion:
spin_lock_irqsave(&mad_agent_priv->lock, flags);
atomic_dec(&mad_agent_priv->refcount);
- if (!recv)
+ if (free_mad)
kmem_cache_free(ib_mad_cache, local->mad_priv);
kfree(local);
}
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index 3af2b84cd838..57a3c6f947b2 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -735,7 +735,7 @@ process_rmpp_data(struct ib_mad_agent_private *agent,
goto bad;
}
- if (rmpp_hdr->seg_num == __constant_htonl(1)) {
+ if (rmpp_hdr->seg_num == cpu_to_be32(1)) {
if (!(ib_get_rmpp_flags(rmpp_hdr) & IB_MGMT_RMPP_FLAG_FIRST)) {
rmpp_status = IB_MGMT_RMPP_STATUS_BAD_SEG;
goto bad;
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 7863a50d56f2..1865049e80f7 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -395,6 +395,8 @@ static void update_sm_ah(struct work_struct *work)
}
spin_lock_irq(&port->ah_lock);
+ if (port->sm_ah)
+ kref_put(&port->sm_ah->ref, free_sm_ah);
port->sm_ah = new_ah;
spin_unlock_irq(&port->ah_lock);
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index b43f7d3682d3..5c04cfb54cb9 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -66,11 +66,6 @@ struct port_table_attribute {
int index;
};
-static inline int ibdev_is_alive(const struct ib_device *dev)
-{
- return dev->reg_state == IB_DEV_REGISTERED;
-}
-
static ssize_t port_attr_show(struct kobject *kobj,
struct attribute *attr, char *buf)
{
@@ -80,8 +75,6 @@ static ssize_t port_attr_show(struct kobject *kobj,
if (!port_attr->show)
return -EIO;
- if (!ibdev_is_alive(p->ibdev))
- return -ENODEV;
return port_attr->show(p, port_attr, buf);
}
@@ -562,9 +555,6 @@ static ssize_t show_node_type(struct device *device,
{
struct ib_device *dev = container_of(device, struct ib_device, dev);
- if (!ibdev_is_alive(dev))
- return -ENODEV;
-
switch (dev->node_type) {
case RDMA_NODE_IB_CA: return sprintf(buf, "%d: CA\n", dev->node_type);
case RDMA_NODE_RNIC: return sprintf(buf, "%d: RNIC\n", dev->node_type);
@@ -581,9 +571,6 @@ static ssize_t show_sys_image_guid(struct device *device,
struct ib_device_attr attr;
ssize_t ret;
- if (!ibdev_is_alive(dev))
- return -ENODEV;
-
ret = ib_query_device(dev, &attr);
if (ret)
return ret;
@@ -600,9 +587,6 @@ static ssize_t show_node_guid(struct device *device,
{
struct ib_device *dev = container_of(device, struct ib_device, dev);
- if (!ibdev_is_alive(dev))
- return -ENODEV;
-
return sprintf(buf, "%04x:%04x:%04x:%04x\n",
be16_to_cpu(((__be16 *) &dev->node_guid)[0]),
be16_to_cpu(((__be16 *) &dev->node_guid)[1]),
@@ -848,6 +832,9 @@ void ib_device_unregister_sysfs(struct ib_device *device)
struct kobject *p, *t;
struct ib_port *port;
+ /* Hold kobject until ib_dealloc_device() */
+ kobject_get(&device->dev.kobj);
+
list_for_each_entry_safe(p, t, &device->port_list, entry) {
list_del(&p->entry);
port = container_of(p, struct ib_port, kobj);
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c
index 113f3c03c5b5..7d79aa361e26 100644
--- a/drivers/infiniband/hw/amso1100/c2.c
+++ b/drivers/infiniband/hw/amso1100/c2.c
@@ -76,7 +76,6 @@ static irqreturn_t c2_interrupt(int irq, void *dev_id);
static void c2_tx_timeout(struct net_device *netdev);
static int c2_change_mtu(struct net_device *netdev, int new_mtu);
static void c2_reset(struct c2_port *c2_port);
-static struct net_device_stats *c2_get_stats(struct net_device *netdev);
static struct pci_device_id c2_pci_table[] = {
{ PCI_DEVICE(0x18b8, 0xb001) },
@@ -349,7 +348,7 @@ static void c2_tx_clean(struct c2_port *c2_port)
elem->hw_desc + C2_TXP_ADDR);
__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_DONE),
elem->hw_desc + C2_TXP_FLAGS);
- c2_port->netstats.tx_dropped++;
+ c2_port->netdev->stats.tx_dropped++;
break;
} else {
__raw_writew(0,
@@ -457,7 +456,7 @@ static void c2_rx_error(struct c2_port *c2_port, struct c2_element *elem)
elem->hw_desc + C2_RXP_FLAGS);
pr_debug("packet dropped\n");
- c2_port->netstats.rx_dropped++;
+ c2_port->netdev->stats.rx_dropped++;
}
static void c2_rx_interrupt(struct net_device *netdev)
@@ -532,8 +531,8 @@ static void c2_rx_interrupt(struct net_device *netdev)
netif_rx(skb);
netdev->last_rx = jiffies;
- c2_port->netstats.rx_packets++;
- c2_port->netstats.rx_bytes += buflen;
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += buflen;
}
/* Save where we left off */
@@ -797,8 +796,8 @@ static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_READY),
elem->hw_desc + C2_TXP_FLAGS);
- c2_port->netstats.tx_packets++;
- c2_port->netstats.tx_bytes += maplen;
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += maplen;
/* Loop thru additional data fragments and queue them */
if (skb_shinfo(skb)->nr_frags) {
@@ -823,8 +822,8 @@ static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_READY),
elem->hw_desc + C2_TXP_FLAGS);
- c2_port->netstats.tx_packets++;
- c2_port->netstats.tx_bytes += maplen;
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += maplen;
}
}
@@ -845,13 +844,6 @@ static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_OK;
}
-static struct net_device_stats *c2_get_stats(struct net_device *netdev)
-{
- struct c2_port *c2_port = netdev_priv(netdev);
-
- return &c2_port->netstats;
-}
-
static void c2_tx_timeout(struct net_device *netdev)
{
struct c2_port *c2_port = netdev_priv(netdev);
@@ -880,6 +872,16 @@ static int c2_change_mtu(struct net_device *netdev, int new_mtu)
return ret;
}
+static const struct net_device_ops c2_netdev = {
+ .ndo_open = c2_up,
+ .ndo_stop = c2_down,
+ .ndo_start_xmit = c2_xmit_frame,
+ .ndo_tx_timeout = c2_tx_timeout,
+ .ndo_change_mtu = c2_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/* Initialize network device */
static struct net_device *c2_devinit(struct c2_dev *c2dev,
void __iomem * mmio_addr)
@@ -894,12 +896,7 @@ static struct net_device *c2_devinit(struct c2_dev *c2dev,
SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev);
- netdev->open = c2_up;
- netdev->stop = c2_down;
- netdev->hard_start_xmit = c2_xmit_frame;
- netdev->get_stats = c2_get_stats;
- netdev->tx_timeout = c2_tx_timeout;
- netdev->change_mtu = c2_change_mtu;
+ netdev->netdev_ops = &c2_netdev;
netdev->watchdog_timeo = C2_TX_TIMEOUT;
netdev->irq = c2dev->pcidev->irq;
diff --git a/drivers/infiniband/hw/amso1100/c2.h b/drivers/infiniband/hw/amso1100/c2.h
index d12a24a84fd9..f7ff66f98361 100644
--- a/drivers/infiniband/hw/amso1100/c2.h
+++ b/drivers/infiniband/hw/amso1100/c2.h
@@ -369,8 +369,6 @@ struct c2_port {
unsigned long mem_size;
u32 rx_buf_size;
-
- struct net_device_stats netstats;
};
/*
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c
index 5119d6508181..f1948fad85d7 100644
--- a/drivers/infiniband/hw/amso1100/c2_provider.c
+++ b/drivers/infiniband/hw/amso1100/c2_provider.c
@@ -708,26 +708,27 @@ static int c2_pseudo_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
static int c2_pseudo_change_mtu(struct net_device *netdev, int new_mtu)
{
- int ret = 0;
-
if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
return -EINVAL;
netdev->mtu = new_mtu;
/* TODO: Tell rnic about new rmda interface mtu */
- return ret;
+ return 0;
}
+static const struct net_device_ops c2_pseudo_netdev_ops = {
+ .ndo_open = c2_pseudo_up,
+ .ndo_stop = c2_pseudo_down,
+ .ndo_start_xmit = c2_pseudo_xmit_frame,
+ .ndo_change_mtu = c2_pseudo_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static void setup(struct net_device *netdev)
{
- netdev->open = c2_pseudo_up;
- netdev->stop = c2_pseudo_down;
- netdev->hard_start_xmit = c2_pseudo_xmit_frame;
- netdev->get_stats = NULL;
- netdev->tx_timeout = NULL;
- netdev->set_mac_address = NULL;
- netdev->change_mtu = c2_pseudo_change_mtu;
+ netdev->netdev_ops = &c2_pseudo_netdev_ops;
+
netdev->watchdog_timeo = 0;
netdev->type = ARPHRD_ETHER;
netdev->mtu = 1500;
@@ -735,7 +736,6 @@ static void setup(struct net_device *netdev)
netdev->addr_len = ETH_ALEN;
netdev->tx_queue_len = 0;
netdev->flags |= IFF_NOARP;
- return;
}
static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev)
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index 4dcf08b3fd83..a4a82bff7100 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -450,7 +450,7 @@ static int cqe_completes_wr(struct t3_cqe *cqe, struct t3_wq *wq)
if ((CQE_OPCODE(*cqe) == T3_READ_RESP) && SQ_TYPE(*cqe))
return 0;
- if ((CQE_OPCODE(*cqe) == T3_SEND) && RQ_TYPE(*cqe) &&
+ if (CQE_SEND_OPCODE(*cqe) && RQ_TYPE(*cqe) &&
Q_EMPTY(wq->rq_rptr, wq->rq_wptr))
return 0;
@@ -701,6 +701,9 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry,
u32 stag_idx;
u32 wptr;
+ if (rdev_p->flags)
+ return -EIO;
+
stag_state = stag_state > 0;
stag_idx = (*stag) >> 8;
@@ -938,6 +941,23 @@ int cxio_rdev_open(struct cxio_rdev *rdev_p)
if (!rdev_p->t3cdev_p)
rdev_p->t3cdev_p = dev2t3cdev(netdev_p);
rdev_p->t3cdev_p->ulp = (void *) rdev_p;
+
+ err = rdev_p->t3cdev_p->ctl(rdev_p->t3cdev_p, GET_EMBEDDED_INFO,
+ &(rdev_p->fw_info));
+ if (err) {
+ printk(KERN_ERR "%s t3cdev_p(%p)->ctl returned error %d.\n",
+ __func__, rdev_p->t3cdev_p, err);
+ goto err1;
+ }
+ if (G_FW_VERSION_MAJOR(rdev_p->fw_info.fw_vers) != CXIO_FW_MAJ) {
+ printk(KERN_ERR MOD "fatal firmware version mismatch: "
+ "need version %u but adapter has version %u\n",
+ CXIO_FW_MAJ,
+ G_FW_VERSION_MAJOR(rdev_p->fw_info.fw_vers));
+ err = -EINVAL;
+ goto err1;
+ }
+
err = rdev_p->t3cdev_p->ctl(rdev_p->t3cdev_p, RDMA_GET_PARAMS,
&(rdev_p->rnic_info));
if (err) {
@@ -1204,11 +1224,12 @@ int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
}
/* incoming SEND with no receive posted failures */
- if ((CQE_OPCODE(*hw_cqe) == T3_SEND) && RQ_TYPE(*hw_cqe) &&
+ if (CQE_SEND_OPCODE(*hw_cqe) && RQ_TYPE(*hw_cqe) &&
Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) {
ret = -1;
goto skip_cqe;
}
+ BUG_ON((*cqe_flushed == 0) && !SW_CQE(*hw_cqe));
goto proc_cqe;
}
@@ -1223,6 +1244,13 @@ int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
* then we complete this with TPT_ERR_MSN and mark the wq in
* error.
*/
+
+ if (Q_EMPTY(wq->rq_rptr, wq->rq_wptr)) {
+ wq->error = 1;
+ ret = -1;
+ goto skip_cqe;
+ }
+
if (unlikely((CQE_WRID_MSN(*hw_cqe) != (wq->rq_rptr + 1)))) {
wq->error = 1;
hw_cqe->header |= htonl(V_CQE_STATUS(TPT_ERR_MSN));
@@ -1277,6 +1305,7 @@ proc_cqe:
cxio_hal_pblpool_free(wq->rdev,
wq->rq[Q_PTR2IDX(wq->rq_rptr,
wq->rq_size_log2)].pbl_addr, T3_STAG0_PBL_SIZE);
+ BUG_ON(Q_EMPTY(wq->rq_rptr, wq->rq_wptr));
wq->rq_rptr++;
}
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h
index 656fe47bc84f..094a66d1480c 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h
@@ -61,6 +61,8 @@
#define T3_MAX_DEV_NAME_LEN 32
+#define CXIO_FW_MAJ 7
+
struct cxio_hal_ctrl_qp {
u32 wptr;
u32 rptr;
@@ -108,6 +110,9 @@ struct cxio_rdev {
struct gen_pool *pbl_pool;
struct gen_pool *rqt_pool;
struct list_head entry;
+ struct ch_embedded_info fw_info;
+ u32 flags;
+#define CXIO_ERROR_FATAL 1
};
static inline int cxio_num_stags(struct cxio_rdev *rdev_p)
diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h
index 04618f7bfbb3..ff9be1a13106 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_wr.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h
@@ -604,6 +604,12 @@ struct t3_cqe {
#define CQE_STATUS(x) (G_CQE_STATUS(be32_to_cpu((x).header)))
#define CQE_OPCODE(x) (G_CQE_OPCODE(be32_to_cpu((x).header)))
+#define CQE_SEND_OPCODE(x)( \
+ (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND) || \
+ (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_SE) || \
+ (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_INV) || \
+ (G_CQE_OPCODE(be32_to_cpu((x).header)) == T3_SEND_WITH_SE_INV))
+
#define CQE_LEN(x) (be32_to_cpu((x).len))
/* used for RQ completion processing */
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c
index 4489c89d6710..37a4fc264a07 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.c
+++ b/drivers/infiniband/hw/cxgb3/iwch.c
@@ -51,13 +51,15 @@ cxgb3_cpl_handler_func t3c_handlers[NUM_CPL_CMDS];
static void open_rnic_dev(struct t3cdev *);
static void close_rnic_dev(struct t3cdev *);
+static void iwch_err_handler(struct t3cdev *, u32, u32);
struct cxgb3_client t3c_client = {
.name = "iw_cxgb3",
.add = open_rnic_dev,
.remove = close_rnic_dev,
.handlers = t3c_handlers,
- .redirect = iwch_ep_redirect
+ .redirect = iwch_ep_redirect,
+ .err_handler = iwch_err_handler
};
static LIST_HEAD(dev_list);
@@ -160,6 +162,17 @@ static void close_rnic_dev(struct t3cdev *tdev)
mutex_unlock(&dev_mutex);
}
+static void iwch_err_handler(struct t3cdev *tdev, u32 status, u32 error)
+{
+ struct cxio_rdev *rdev = tdev->ulp;
+
+ if (status == OFFLOAD_STATUS_DOWN)
+ rdev->flags = CXIO_ERROR_FATAL;
+
+ return;
+
+}
+
static int __init iwch_init_module(void)
{
int err;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 44e936e48a31..8699947aaf6c 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -1678,6 +1678,9 @@ static int terminate(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
{
struct iwch_ep *ep = ctx;
+ if (state_read(&ep->com) != FPDU_MODE)
+ return CPL_RET_BUF_DONE;
+
PDBG("%s ep %p\n", __func__, ep);
skb_pull(skb, sizeof(struct cpl_rdma_terminate));
PDBG("%s saving %d bytes of term msg\n", __func__, skb->len);
diff --git a/drivers/infiniband/hw/cxgb3/iwch_ev.c b/drivers/infiniband/hw/cxgb3/iwch_ev.c
index 7b67a6771720..743c5d8b8806 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_ev.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_ev.c
@@ -179,11 +179,6 @@ void iwch_ev_dispatch(struct cxio_rdev *rdev_p, struct sk_buff *skb)
case TPT_ERR_BOUND:
case TPT_ERR_INVALIDATE_SHARED_MR:
case TPT_ERR_INVALIDATE_MR_WITH_MW_BOUND:
- printk(KERN_ERR "%s - CQE Err qpid 0x%x opcode %d status 0x%x "
- "type %d wrid.hi 0x%x wrid.lo 0x%x \n", __func__,
- CQE_QPID(rsp_msg->cqe), CQE_OPCODE(rsp_msg->cqe),
- CQE_STATUS(rsp_msg->cqe), CQE_TYPE(rsp_msg->cqe),
- CQE_WRID_HI(rsp_msg->cqe), CQE_WRID_LOW(rsp_msg->cqe));
(*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context);
post_qp_event(rnicp, chp, rsp_msg, IB_EVENT_QP_ACCESS_ERR, 1);
break;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index 19661b2f0406..c758fbd58478 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -99,8 +99,8 @@ static int build_rdma_write(union t3_wr *wqe, struct ib_send_wr *wr,
if (wr->opcode == IB_WR_RDMA_WRITE_WITH_IMM) {
plen = 4;
wqe->write.sgl[0].stag = wr->ex.imm_data;
- wqe->write.sgl[0].len = __constant_cpu_to_be32(0);
- wqe->write.num_sgle = __constant_cpu_to_be32(0);
+ wqe->write.sgl[0].len = cpu_to_be32(0);
+ wqe->write.num_sgle = cpu_to_be32(0);
*flit_cnt = 6;
} else {
plen = 0;
@@ -195,15 +195,12 @@ static int build_inv_stag(union t3_wr *wqe, struct ib_send_wr *wr,
return 0;
}
-/*
- * TBD: this is going to be moved to firmware. Missing pdid/qpid check for now.
- */
static int iwch_sgl2pbl_map(struct iwch_dev *rhp, struct ib_sge *sg_list,
u32 num_sgle, u32 * pbl_addr, u8 * page_size)
{
int i;
struct iwch_mr *mhp;
- u32 offset;
+ u64 offset;
for (i = 0; i < num_sgle; i++) {
mhp = get_mhp(rhp, (sg_list[i].lkey) >> 8);
@@ -235,8 +232,8 @@ static int iwch_sgl2pbl_map(struct iwch_dev *rhp, struct ib_sge *sg_list,
return -EINVAL;
}
offset = sg_list[i].addr - mhp->attr.va_fbo;
- offset += ((u32) mhp->attr.va_fbo) %
- (1UL << (12 + mhp->attr.page_size));
+ offset += mhp->attr.va_fbo &
+ ((1UL << (12 + mhp->attr.page_size)) - 1);
pbl_addr[i] = ((mhp->attr.pbl_addr -
rhp->rdev.rnic_info.pbl_base) >> 3) +
(offset >> (12 + mhp->attr.page_size));
@@ -266,8 +263,8 @@ static int build_rdma_recv(struct iwch_qp *qhp, union t3_wr *wqe,
wqe->recv.sgl[i].len = cpu_to_be32(wr->sg_list[i].length);
/* to in the WQE == the offset into the page */
- wqe->recv.sgl[i].to = cpu_to_be64(((u32) wr->sg_list[i].addr) %
- (1UL << (12 + page_size[i])));
+ wqe->recv.sgl[i].to = cpu_to_be64(((u32)wr->sg_list[i].addr) &
+ ((1UL << (12 + page_size[i])) - 1));
/* pbl_addr is the adapters address in the PBL */
wqe->recv.pbl_addr[i] = cpu_to_be32(pbl_addr[i]);
diff --git a/drivers/infiniband/hw/ehca/ehca_sqp.c b/drivers/infiniband/hw/ehca/ehca_sqp.c
index 44447aaa5501..c568b28f4e20 100644
--- a/drivers/infiniband/hw/ehca/ehca_sqp.c
+++ b/drivers/infiniband/hw/ehca/ehca_sqp.c
@@ -46,11 +46,11 @@
#include "ehca_iverbs.h"
#include "hcp_if.h"
-#define IB_MAD_STATUS_REDIRECT __constant_htons(0x0002)
-#define IB_MAD_STATUS_UNSUP_VERSION __constant_htons(0x0004)
-#define IB_MAD_STATUS_UNSUP_METHOD __constant_htons(0x0008)
+#define IB_MAD_STATUS_REDIRECT cpu_to_be16(0x0002)
+#define IB_MAD_STATUS_UNSUP_VERSION cpu_to_be16(0x0004)
+#define IB_MAD_STATUS_UNSUP_METHOD cpu_to_be16(0x0008)
-#define IB_PMA_CLASS_PORT_INFO __constant_htons(0x0001)
+#define IB_PMA_CLASS_PORT_INFO cpu_to_be16(0x0001)
/**
* ehca_define_sqp - Defines special queue pair 1 (GSI QP). When special queue
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index 69c0ce321b4e..cb9daa6ac029 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -2715,7 +2715,7 @@ static void ipath_hol_signal_up(struct ipath_devdata *dd)
* to prevent HoL blocking, then start the HoL timer that
* periodically continues, then stop procs, so they can detect
* link down if they want, and do something about it.
- * Timer may already be running, so use __mod_timer, not add_timer.
+ * Timer may already be running, so use mod_timer, not add_timer.
*/
void ipath_hol_down(struct ipath_devdata *dd)
{
@@ -2724,7 +2724,7 @@ void ipath_hol_down(struct ipath_devdata *dd)
dd->ipath_hol_next = IPATH_HOL_DOWNCONT;
dd->ipath_hol_timer.expires = jiffies +
msecs_to_jiffies(ipath_hol_timeout_ms);
- __mod_timer(&dd->ipath_hol_timer, dd->ipath_hol_timer.expires);
+ mod_timer(&dd->ipath_hol_timer, dd->ipath_hol_timer.expires);
}
/*
@@ -2763,7 +2763,7 @@ void ipath_hol_event(unsigned long opaque)
else {
dd->ipath_hol_timer.expires = jiffies +
msecs_to_jiffies(ipath_hol_timeout_ms);
- __mod_timer(&dd->ipath_hol_timer,
+ mod_timer(&dd->ipath_hol_timer,
dd->ipath_hol_timer.expires);
}
}
diff --git a/drivers/infiniband/hw/ipath/ipath_eeprom.c b/drivers/infiniband/hw/ipath/ipath_eeprom.c
index dc37277f1c80..fc7181985e8e 100644
--- a/drivers/infiniband/hw/ipath/ipath_eeprom.c
+++ b/drivers/infiniband/hw/ipath/ipath_eeprom.c
@@ -772,8 +772,8 @@ void ipath_get_eeprom_info(struct ipath_devdata *dd)
"0x%x, not 0x%x\n", csum, ifp->if_csum);
goto done;
}
- if (*(__be64 *) ifp->if_guid == 0ULL ||
- *(__be64 *) ifp->if_guid == __constant_cpu_to_be64(-1LL)) {
+ if (*(__be64 *) ifp->if_guid == cpu_to_be64(0) ||
+ *(__be64 *) ifp->if_guid == ~cpu_to_be64(0)) {
ipath_dev_err(dd, "Invalid GUID %llx from flash; "
"ignoring\n",
*(unsigned long long *) ifp->if_guid);
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c
index 64aeefbd2a5d..077879c0bdb5 100644
--- a/drivers/infiniband/hw/ipath/ipath_init_chip.c
+++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c
@@ -455,7 +455,7 @@ static void init_shadow_tids(struct ipath_devdata *dd)
if (!addrs) {
ipath_dev_err(dd, "failed to allocate shadow dma handle "
"array, no expected sends!\n");
- vfree(dd->ipath_pageshadow);
+ vfree(pages);
dd->ipath_pageshadow = NULL;
return;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c
index 17a123197477..16a702d46018 100644
--- a/drivers/infiniband/hw/ipath/ipath_mad.c
+++ b/drivers/infiniband/hw/ipath/ipath_mad.c
@@ -37,10 +37,10 @@
#include "ipath_verbs.h"
#include "ipath_common.h"
-#define IB_SMP_UNSUP_VERSION __constant_htons(0x0004)
-#define IB_SMP_UNSUP_METHOD __constant_htons(0x0008)
-#define IB_SMP_UNSUP_METH_ATTR __constant_htons(0x000C)
-#define IB_SMP_INVALID_FIELD __constant_htons(0x001C)
+#define IB_SMP_UNSUP_VERSION cpu_to_be16(0x0004)
+#define IB_SMP_UNSUP_METHOD cpu_to_be16(0x0008)
+#define IB_SMP_UNSUP_METH_ATTR cpu_to_be16(0x000C)
+#define IB_SMP_INVALID_FIELD cpu_to_be16(0x001C)
static int reply(struct ib_smp *smp)
{
@@ -789,12 +789,12 @@ static int recv_subn_set_pkeytable(struct ib_smp *smp,
return recv_subn_get_pkeytable(smp, ibdev);
}
-#define IB_PMA_CLASS_PORT_INFO __constant_htons(0x0001)
-#define IB_PMA_PORT_SAMPLES_CONTROL __constant_htons(0x0010)
-#define IB_PMA_PORT_SAMPLES_RESULT __constant_htons(0x0011)
-#define IB_PMA_PORT_COUNTERS __constant_htons(0x0012)
-#define IB_PMA_PORT_COUNTERS_EXT __constant_htons(0x001D)
-#define IB_PMA_PORT_SAMPLES_RESULT_EXT __constant_htons(0x001E)
+#define IB_PMA_CLASS_PORT_INFO cpu_to_be16(0x0001)
+#define IB_PMA_PORT_SAMPLES_CONTROL cpu_to_be16(0x0010)
+#define IB_PMA_PORT_SAMPLES_RESULT cpu_to_be16(0x0011)
+#define IB_PMA_PORT_COUNTERS cpu_to_be16(0x0012)
+#define IB_PMA_PORT_COUNTERS_EXT cpu_to_be16(0x001D)
+#define IB_PMA_PORT_SAMPLES_RESULT_EXT cpu_to_be16(0x001E)
struct ib_perf {
u8 base_version;
@@ -884,19 +884,19 @@ struct ib_pma_portcounters {
__be32 port_rcv_packets;
} __attribute__ ((packed));
-#define IB_PMA_SEL_SYMBOL_ERROR __constant_htons(0x0001)
-#define IB_PMA_SEL_LINK_ERROR_RECOVERY __constant_htons(0x0002)
-#define IB_PMA_SEL_LINK_DOWNED __constant_htons(0x0004)
-#define IB_PMA_SEL_PORT_RCV_ERRORS __constant_htons(0x0008)
-#define IB_PMA_SEL_PORT_RCV_REMPHYS_ERRORS __constant_htons(0x0010)
-#define IB_PMA_SEL_PORT_XMIT_DISCARDS __constant_htons(0x0040)
-#define IB_PMA_SEL_LOCAL_LINK_INTEGRITY_ERRORS __constant_htons(0x0200)
-#define IB_PMA_SEL_EXCESSIVE_BUFFER_OVERRUNS __constant_htons(0x0400)
-#define IB_PMA_SEL_PORT_VL15_DROPPED __constant_htons(0x0800)
-#define IB_PMA_SEL_PORT_XMIT_DATA __constant_htons(0x1000)
-#define IB_PMA_SEL_PORT_RCV_DATA __constant_htons(0x2000)
-#define IB_PMA_SEL_PORT_XMIT_PACKETS __constant_htons(0x4000)
-#define IB_PMA_SEL_PORT_RCV_PACKETS __constant_htons(0x8000)
+#define IB_PMA_SEL_SYMBOL_ERROR cpu_to_be16(0x0001)
+#define IB_PMA_SEL_LINK_ERROR_RECOVERY cpu_to_be16(0x0002)
+#define IB_PMA_SEL_LINK_DOWNED cpu_to_be16(0x0004)
+#define IB_PMA_SEL_PORT_RCV_ERRORS cpu_to_be16(0x0008)
+#define IB_PMA_SEL_PORT_RCV_REMPHYS_ERRORS cpu_to_be16(0x0010)
+#define IB_PMA_SEL_PORT_XMIT_DISCARDS cpu_to_be16(0x0040)
+#define IB_PMA_SEL_LOCAL_LINK_INTEGRITY_ERRORS cpu_to_be16(0x0200)
+#define IB_PMA_SEL_EXCESSIVE_BUFFER_OVERRUNS cpu_to_be16(0x0400)
+#define IB_PMA_SEL_PORT_VL15_DROPPED cpu_to_be16(0x0800)
+#define IB_PMA_SEL_PORT_XMIT_DATA cpu_to_be16(0x1000)
+#define IB_PMA_SEL_PORT_RCV_DATA cpu_to_be16(0x2000)
+#define IB_PMA_SEL_PORT_XMIT_PACKETS cpu_to_be16(0x4000)
+#define IB_PMA_SEL_PORT_RCV_PACKETS cpu_to_be16(0x8000)
struct ib_pma_portcounters_ext {
u8 reserved;
@@ -913,14 +913,14 @@ struct ib_pma_portcounters_ext {
__be64 port_multicast_rcv_packets;
} __attribute__ ((packed));
-#define IB_PMA_SELX_PORT_XMIT_DATA __constant_htons(0x0001)
-#define IB_PMA_SELX_PORT_RCV_DATA __constant_htons(0x0002)
-#define IB_PMA_SELX_PORT_XMIT_PACKETS __constant_htons(0x0004)
-#define IB_PMA_SELX_PORT_RCV_PACKETS __constant_htons(0x0008)
-#define IB_PMA_SELX_PORT_UNI_XMIT_PACKETS __constant_htons(0x0010)
-#define IB_PMA_SELX_PORT_UNI_RCV_PACKETS __constant_htons(0x0020)
-#define IB_PMA_SELX_PORT_MULTI_XMIT_PACKETS __constant_htons(0x0040)
-#define IB_PMA_SELX_PORT_MULTI_RCV_PACKETS __constant_htons(0x0080)
+#define IB_PMA_SELX_PORT_XMIT_DATA cpu_to_be16(0x0001)
+#define IB_PMA_SELX_PORT_RCV_DATA cpu_to_be16(0x0002)
+#define IB_PMA_SELX_PORT_XMIT_PACKETS cpu_to_be16(0x0004)
+#define IB_PMA_SELX_PORT_RCV_PACKETS cpu_to_be16(0x0008)
+#define IB_PMA_SELX_PORT_UNI_XMIT_PACKETS cpu_to_be16(0x0010)
+#define IB_PMA_SELX_PORT_UNI_RCV_PACKETS cpu_to_be16(0x0020)
+#define IB_PMA_SELX_PORT_MULTI_XMIT_PACKETS cpu_to_be16(0x0040)
+#define IB_PMA_SELX_PORT_MULTI_RCV_PACKETS cpu_to_be16(0x0080)
static int recv_pma_get_classportinfo(struct ib_perf *pmp)
{
@@ -933,7 +933,7 @@ static int recv_pma_get_classportinfo(struct ib_perf *pmp)
pmp->status |= IB_SMP_INVALID_FIELD;
/* Indicate AllPortSelect is valid (only one port anyway) */
- p->cap_mask = __constant_cpu_to_be16(1 << 8);
+ p->cap_mask = cpu_to_be16(1 << 8);
p->base_version = 1;
p->class_version = 1;
/*
@@ -951,12 +951,11 @@ static int recv_pma_get_classportinfo(struct ib_perf *pmp)
* We support 5 counters which only count the mandatory quantities.
*/
#define COUNTER_MASK(q, n) (q << ((9 - n) * 3))
-#define COUNTER_MASK0_9 \
- __constant_cpu_to_be32(COUNTER_MASK(1, 0) | \
- COUNTER_MASK(1, 1) | \
- COUNTER_MASK(1, 2) | \
- COUNTER_MASK(1, 3) | \
- COUNTER_MASK(1, 4))
+#define COUNTER_MASK0_9 cpu_to_be32(COUNTER_MASK(1, 0) | \
+ COUNTER_MASK(1, 1) | \
+ COUNTER_MASK(1, 2) | \
+ COUNTER_MASK(1, 3) | \
+ COUNTER_MASK(1, 4))
static int recv_pma_get_portsamplescontrol(struct ib_perf *pmp,
struct ib_device *ibdev, u8 port)
@@ -1137,7 +1136,7 @@ static int recv_pma_get_portsamplesresult_ext(struct ib_perf *pmp,
status = dev->pma_sample_status;
p->sample_status = cpu_to_be16(status);
/* 64 bits */
- p->extended_width = __constant_cpu_to_be32(0x80000000);
+ p->extended_width = cpu_to_be32(0x80000000);
for (i = 0; i < ARRAY_SIZE(dev->pma_counter_select); i++)
p->counter[i] = (status != IB_PMA_SAMPLE_STATUS_DONE) ? 0 :
cpu_to_be64(
@@ -1185,7 +1184,7 @@ static int recv_pma_get_portcounters(struct ib_perf *pmp,
pmp->status |= IB_SMP_INVALID_FIELD;
if (cntrs.symbol_error_counter > 0xFFFFUL)
- p->symbol_error_counter = __constant_cpu_to_be16(0xFFFF);
+ p->symbol_error_counter = cpu_to_be16(0xFFFF);
else
p->symbol_error_counter =
cpu_to_be16((u16)cntrs.symbol_error_counter);
@@ -1199,17 +1198,17 @@ static int recv_pma_get_portcounters(struct ib_perf *pmp,
else
p->link_downed_counter = (u8)cntrs.link_downed_counter;
if (cntrs.port_rcv_errors > 0xFFFFUL)
- p->port_rcv_errors = __constant_cpu_to_be16(0xFFFF);
+ p->port_rcv_errors = cpu_to_be16(0xFFFF);
else
p->port_rcv_errors =
cpu_to_be16((u16) cntrs.port_rcv_errors);
if (cntrs.port_rcv_remphys_errors > 0xFFFFUL)
- p->port_rcv_remphys_errors = __constant_cpu_to_be16(0xFFFF);
+ p->port_rcv_remphys_errors = cpu_to_be16(0xFFFF);
else
p->port_rcv_remphys_errors =
cpu_to_be16((u16)cntrs.port_rcv_remphys_errors);
if (cntrs.port_xmit_discards > 0xFFFFUL)
- p->port_xmit_discards = __constant_cpu_to_be16(0xFFFF);
+ p->port_xmit_discards = cpu_to_be16(0xFFFF);
else
p->port_xmit_discards =
cpu_to_be16((u16)cntrs.port_xmit_discards);
@@ -1220,24 +1219,24 @@ static int recv_pma_get_portcounters(struct ib_perf *pmp,
p->lli_ebor_errors = (cntrs.local_link_integrity_errors << 4) |
cntrs.excessive_buffer_overrun_errors;
if (cntrs.vl15_dropped > 0xFFFFUL)
- p->vl15_dropped = __constant_cpu_to_be16(0xFFFF);
+ p->vl15_dropped = cpu_to_be16(0xFFFF);
else
p->vl15_dropped = cpu_to_be16((u16)cntrs.vl15_dropped);
if (cntrs.port_xmit_data > 0xFFFFFFFFUL)
- p->port_xmit_data = __constant_cpu_to_be32(0xFFFFFFFF);
+ p->port_xmit_data = cpu_to_be32(0xFFFFFFFF);
else
p->port_xmit_data = cpu_to_be32((u32)cntrs.port_xmit_data);
if (cntrs.port_rcv_data > 0xFFFFFFFFUL)
- p->port_rcv_data = __constant_cpu_to_be32(0xFFFFFFFF);
+ p->port_rcv_data = cpu_to_be32(0xFFFFFFFF);
else
p->port_rcv_data = cpu_to_be32((u32)cntrs.port_rcv_data);
if (cntrs.port_xmit_packets > 0xFFFFFFFFUL)
- p->port_xmit_packets = __constant_cpu_to_be32(0xFFFFFFFF);
+ p->port_xmit_packets = cpu_to_be32(0xFFFFFFFF);
else
p->port_xmit_packets =
cpu_to_be32((u32)cntrs.port_xmit_packets);
if (cntrs.port_rcv_packets > 0xFFFFFFFFUL)
- p->port_rcv_packets = __constant_cpu_to_be32(0xFFFFFFFF);
+ p->port_rcv_packets = cpu_to_be32(0xFFFFFFFF);
else
p->port_rcv_packets =
cpu_to_be32((u32) cntrs.port_rcv_packets);
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
index 9170710b950d..79b3dbc97179 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -1744,7 +1744,7 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
/* Signal completion event if the solicited bit is set. */
ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
(ohdr->bth[0] &
- __constant_cpu_to_be32(1 << 23)) != 0);
+ cpu_to_be32(1 << 23)) != 0);
break;
case OP(RDMA_WRITE_FIRST):
diff --git a/drivers/infiniband/hw/ipath/ipath_sdma.c b/drivers/infiniband/hw/ipath/ipath_sdma.c
index 8e255adf5d9b..4b0698590850 100644
--- a/drivers/infiniband/hw/ipath/ipath_sdma.c
+++ b/drivers/infiniband/hw/ipath/ipath_sdma.c
@@ -781,10 +781,10 @@ retry:
descqp = &dd->ipath_sdma_descq[dd->ipath_sdma_descq_cnt].qw[0];
descqp -= 2;
/* SDmaLastDesc */
- descqp[0] |= __constant_cpu_to_le64(1ULL << 11);
+ descqp[0] |= cpu_to_le64(1ULL << 11);
if (tx->txreq.flags & IPATH_SDMA_TXREQ_F_INTREQ) {
/* SDmaIntReq */
- descqp[0] |= __constant_cpu_to_le64(1ULL << 15);
+ descqp[0] |= cpu_to_le64(1ULL << 15);
}
/* Commit writes to memory and advance the tail on the chip */
diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c b/drivers/infiniband/hw/ipath/ipath_uc.c
index 82cc588b8bf2..22e60998f1a7 100644
--- a/drivers/infiniband/hw/ipath/ipath_uc.c
+++ b/drivers/infiniband/hw/ipath/ipath_uc.c
@@ -419,7 +419,7 @@ void ipath_uc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
/* Signal completion event if the solicited bit is set. */
ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
(ohdr->bth[0] &
- __constant_cpu_to_be32(1 << 23)) != 0);
+ cpu_to_be32(1 << 23)) != 0);
break;
case OP(RDMA_WRITE_FIRST):
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c
index 91c74cc797ae..6076cb61bf6a 100644
--- a/drivers/infiniband/hw/ipath/ipath_ud.c
+++ b/drivers/infiniband/hw/ipath/ipath_ud.c
@@ -370,7 +370,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
*/
ohdr->bth[1] = ah_attr->dlid >= IPATH_MULTICAST_LID_BASE &&
ah_attr->dlid != IPATH_PERMISSIVE_LID ?
- __constant_cpu_to_be32(IPATH_MULTICAST_QPN) :
+ cpu_to_be32(IPATH_MULTICAST_QPN) :
cpu_to_be32(wqe->wr.wr.ud.remote_qpn);
ohdr->bth[2] = cpu_to_be32(qp->s_next_psn++ & IPATH_PSN_MASK);
/*
@@ -573,7 +573,7 @@ void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
/* Signal completion event if the solicited bit is set. */
ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc,
(ohdr->bth[0] &
- __constant_cpu_to_be32(1 << 23)) != 0);
+ cpu_to_be32(1 << 23)) != 0);
bail:;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c
index 0190edc8044e..855911e7396d 100644
--- a/drivers/infiniband/hw/ipath/ipath_user_pages.c
+++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c
@@ -209,20 +209,20 @@ void ipath_release_user_pages_on_close(struct page **p, size_t num_pages)
mm = get_task_mm(current);
if (!mm)
- goto bail;
+ return;
work = kmalloc(sizeof(*work), GFP_KERNEL);
if (!work)
goto bail_mm;
- goto bail;
-
INIT_WORK(&work->work, user_pages_account);
work->mm = mm;
work->num_pages = num_pages;
+ schedule_work(&work->work);
+ return;
+
bail_mm:
mmput(mm);
-bail:
return;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_user_sdma.c b/drivers/infiniband/hw/ipath/ipath_user_sdma.c
index 82d9a0b5ca2f..7bff4b9baa0a 100644
--- a/drivers/infiniband/hw/ipath/ipath_user_sdma.c
+++ b/drivers/infiniband/hw/ipath/ipath_user_sdma.c
@@ -667,13 +667,13 @@ static inline __le64 ipath_sdma_make_desc0(struct ipath_devdata *dd,
static inline __le64 ipath_sdma_make_first_desc0(__le64 descq)
{
- return descq | __constant_cpu_to_le64(1ULL << 12);
+ return descq | cpu_to_le64(1ULL << 12);
}
static inline __le64 ipath_sdma_make_last_desc0(__le64 descq)
{
/* last */ /* dma head */
- return descq | __constant_cpu_to_le64(1ULL << 11 | 1ULL << 13);
+ return descq | cpu_to_le64(1ULL << 11 | 1ULL << 13);
}
static inline __le64 ipath_sdma_make_desc1(u64 addr)
@@ -763,7 +763,7 @@ static int ipath_user_sdma_push_pkts(struct ipath_devdata *dd,
if (ofs >= IPATH_SMALLBUF_DWORDS) {
for (i = 0; i < pkt->naddr; i++) {
dd->ipath_sdma_descq[dtail].qw[0] |=
- __constant_cpu_to_le64(1ULL << 14);
+ cpu_to_le64(1ULL << 14);
if (++dtail == dd->ipath_sdma_descq_cnt)
dtail = 0;
}
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index cdf0e6abd34d..9289ab4b0ae8 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -1585,7 +1585,7 @@ static int ipath_query_port(struct ib_device *ibdev,
u64 ibcstat;
memset(props, 0, sizeof(*props));
- props->lid = lid ? lid : __constant_be16_to_cpu(IB_LID_PERMISSIVE);
+ props->lid = lid ? lid : be16_to_cpu(IB_LID_PERMISSIVE);
props->lmc = dd->ipath_lmc;
props->sm_lid = dev->sm_lid;
props->sm_sl = dev->sm_sl;
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h
index 11e3f613df93..ae6cff4abffc 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.h
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.h
@@ -86,11 +86,11 @@
#define IB_PMA_SAMPLE_STATUS_RUNNING 0x02
/* Mandatory IB performance counter select values. */
-#define IB_PMA_PORT_XMIT_DATA __constant_htons(0x0001)
-#define IB_PMA_PORT_RCV_DATA __constant_htons(0x0002)
-#define IB_PMA_PORT_XMIT_PKTS __constant_htons(0x0003)
-#define IB_PMA_PORT_RCV_PKTS __constant_htons(0x0004)
-#define IB_PMA_PORT_XMIT_WAIT __constant_htons(0x0005)
+#define IB_PMA_PORT_XMIT_DATA cpu_to_be16(0x0001)
+#define IB_PMA_PORT_RCV_DATA cpu_to_be16(0x0002)
+#define IB_PMA_PORT_XMIT_PKTS cpu_to_be16(0x0003)
+#define IB_PMA_PORT_RCV_PKTS cpu_to_be16(0x0004)
+#define IB_PMA_PORT_XMIT_WAIT cpu_to_be16(0x0005)
struct ib_reth {
__be64 vaddr;
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
index 606f1e2ef284..19e68ab66168 100644
--- a/drivers/infiniband/hw/mlx4/mad.c
+++ b/drivers/infiniband/hw/mlx4/mad.c
@@ -147,7 +147,8 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 port_num, u16 lid, u8 sl)
* Snoop SM MADs for port info and P_Key table sets, so we can
* synthesize LID change and P_Key change events.
*/
-static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad)
+static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad,
+ u16 prev_lid)
{
struct ib_event event;
@@ -157,6 +158,7 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad)
if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
struct ib_port_info *pinfo =
(struct ib_port_info *) ((struct ib_smp *) mad)->data;
+ u16 lid = be16_to_cpu(pinfo->lid);
update_sm_ah(to_mdev(ibdev), port_num,
be16_to_cpu(pinfo->sm_lid),
@@ -165,12 +167,15 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad)
event.device = ibdev;
event.element.port_num = port_num;
- if (pinfo->clientrereg_resv_subnetto & 0x80)
+ if (pinfo->clientrereg_resv_subnetto & 0x80) {
event.event = IB_EVENT_CLIENT_REREGISTER;
- else
- event.event = IB_EVENT_LID_CHANGE;
+ ib_dispatch_event(&event);
+ }
- ib_dispatch_event(&event);
+ if (prev_lid != lid) {
+ event.event = IB_EVENT_LID_CHANGE;
+ ib_dispatch_event(&event);
+ }
}
if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PKEY_TABLE) {
@@ -228,8 +233,9 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
struct ib_wc *in_wc, struct ib_grh *in_grh,
struct ib_mad *in_mad, struct ib_mad *out_mad)
{
- u16 slid;
+ u16 slid, prev_lid = 0;
int err;
+ struct ib_port_attr pattr;
slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
@@ -263,6 +269,13 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
} else
return IB_MAD_RESULT_SUCCESS;
+ if ((in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
+ in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
+ in_mad->mad_hdr.method == IB_MGMT_METHOD_SET &&
+ in_mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO &&
+ !ib_query_port(ibdev, port_num, &pattr))
+ prev_lid = pattr.lid;
+
err = mlx4_MAD_IFC(to_mdev(ibdev),
mad_flags & IB_MAD_IGNORE_MKEY,
mad_flags & IB_MAD_IGNORE_BKEY,
@@ -271,7 +284,7 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
return IB_MAD_RESULT_FAILURE;
if (!out_mad->mad_hdr.status) {
- smp_snoop(ibdev, port_num, in_mad);
+ smp_snoop(ibdev, port_num, in_mad, prev_lid);
node_desc_override(ibdev, out_mad);
}
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 61588bd273bd..2ccb9d31771f 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -699,11 +699,12 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
struct mlx4_ib_dev *ibdev = ibdev_ptr;
int p;
+ mlx4_ib_mad_cleanup(ibdev);
+ ib_unregister_device(&ibdev->ib_dev);
+
for (p = 1; p <= ibdev->num_ports; ++p)
mlx4_CLOSE_PORT(dev, p);
- mlx4_ib_mad_cleanup(ibdev);
- ib_unregister_device(&ibdev->ib_dev);
iounmap(ibdev->uar_map);
mlx4_uar_free(dev, &ibdev->priv_uar);
mlx4_pd_free(dev, ibdev->priv_pdn);
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index a91cb4c3fa5c..f385a24d31d2 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -71,17 +71,17 @@ enum {
};
static const __be32 mlx4_ib_opcode[] = {
- [IB_WR_SEND] = __constant_cpu_to_be32(MLX4_OPCODE_SEND),
- [IB_WR_LSO] = __constant_cpu_to_be32(MLX4_OPCODE_LSO),
- [IB_WR_SEND_WITH_IMM] = __constant_cpu_to_be32(MLX4_OPCODE_SEND_IMM),
- [IB_WR_RDMA_WRITE] = __constant_cpu_to_be32(MLX4_OPCODE_RDMA_WRITE),
- [IB_WR_RDMA_WRITE_WITH_IMM] = __constant_cpu_to_be32(MLX4_OPCODE_RDMA_WRITE_IMM),
- [IB_WR_RDMA_READ] = __constant_cpu_to_be32(MLX4_OPCODE_RDMA_READ),
- [IB_WR_ATOMIC_CMP_AND_SWP] = __constant_cpu_to_be32(MLX4_OPCODE_ATOMIC_CS),
- [IB_WR_ATOMIC_FETCH_AND_ADD] = __constant_cpu_to_be32(MLX4_OPCODE_ATOMIC_FA),
- [IB_WR_SEND_WITH_INV] = __constant_cpu_to_be32(MLX4_OPCODE_SEND_INVAL),
- [IB_WR_LOCAL_INV] = __constant_cpu_to_be32(MLX4_OPCODE_LOCAL_INVAL),
- [IB_WR_FAST_REG_MR] = __constant_cpu_to_be32(MLX4_OPCODE_FMR),
+ [IB_WR_SEND] = cpu_to_be32(MLX4_OPCODE_SEND),
+ [IB_WR_LSO] = cpu_to_be32(MLX4_OPCODE_LSO),
+ [IB_WR_SEND_WITH_IMM] = cpu_to_be32(MLX4_OPCODE_SEND_IMM),
+ [IB_WR_RDMA_WRITE] = cpu_to_be32(MLX4_OPCODE_RDMA_WRITE),
+ [IB_WR_RDMA_WRITE_WITH_IMM] = cpu_to_be32(MLX4_OPCODE_RDMA_WRITE_IMM),
+ [IB_WR_RDMA_READ] = cpu_to_be32(MLX4_OPCODE_RDMA_READ),
+ [IB_WR_ATOMIC_CMP_AND_SWP] = cpu_to_be32(MLX4_OPCODE_ATOMIC_CS),
+ [IB_WR_ATOMIC_FETCH_AND_ADD] = cpu_to_be32(MLX4_OPCODE_ATOMIC_FA),
+ [IB_WR_SEND_WITH_INV] = cpu_to_be32(MLX4_OPCODE_SEND_INVAL),
+ [IB_WR_LOCAL_INV] = cpu_to_be32(MLX4_OPCODE_LOCAL_INVAL),
+ [IB_WR_FAST_REG_MR] = cpu_to_be32(MLX4_OPCODE_FMR),
};
static struct mlx4_ib_sqp *to_msqp(struct mlx4_ib_qp *mqp)
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
index 640449582aba..5648659ff0b0 100644
--- a/drivers/infiniband/hw/mthca/mthca_mad.c
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c
@@ -104,7 +104,8 @@ static void update_sm_ah(struct mthca_dev *dev,
*/
static void smp_snoop(struct ib_device *ibdev,
u8 port_num,
- struct ib_mad *mad)
+ struct ib_mad *mad,
+ u16 prev_lid)
{
struct ib_event event;
@@ -114,6 +115,7 @@ static void smp_snoop(struct ib_device *ibdev,
if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO) {
struct ib_port_info *pinfo =
(struct ib_port_info *) ((struct ib_smp *) mad)->data;
+ u16 lid = be16_to_cpu(pinfo->lid);
mthca_update_rate(to_mdev(ibdev), port_num);
update_sm_ah(to_mdev(ibdev), port_num,
@@ -123,12 +125,15 @@ static void smp_snoop(struct ib_device *ibdev,
event.device = ibdev;
event.element.port_num = port_num;
- if (pinfo->clientrereg_resv_subnetto & 0x80)
+ if (pinfo->clientrereg_resv_subnetto & 0x80) {
event.event = IB_EVENT_CLIENT_REREGISTER;
- else
- event.event = IB_EVENT_LID_CHANGE;
+ ib_dispatch_event(&event);
+ }
- ib_dispatch_event(&event);
+ if (prev_lid != lid) {
+ event.event = IB_EVENT_LID_CHANGE;
+ ib_dispatch_event(&event);
+ }
}
if (mad->mad_hdr.attr_id == IB_SMP_ATTR_PKEY_TABLE) {
@@ -196,6 +201,8 @@ int mthca_process_mad(struct ib_device *ibdev,
int err;
u8 status;
u16 slid = in_wc ? in_wc->slid : be16_to_cpu(IB_LID_PERMISSIVE);
+ u16 prev_lid = 0;
+ struct ib_port_attr pattr;
/* Forward locally generated traps to the SM */
if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP &&
@@ -233,6 +240,12 @@ int mthca_process_mad(struct ib_device *ibdev,
return IB_MAD_RESULT_SUCCESS;
} else
return IB_MAD_RESULT_SUCCESS;
+ if ((in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED ||
+ in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) &&
+ in_mad->mad_hdr.method == IB_MGMT_METHOD_SET &&
+ in_mad->mad_hdr.attr_id == IB_SMP_ATTR_PORT_INFO &&
+ !ib_query_port(ibdev, port_num, &pattr))
+ prev_lid = pattr.lid;
err = mthca_MAD_IFC(to_mdev(ibdev),
mad_flags & IB_MAD_IGNORE_MKEY,
@@ -252,7 +265,7 @@ int mthca_process_mad(struct ib_device *ibdev,
}
if (!out_mad->mad_hdr.status) {
- smp_snoop(ibdev, port_num, in_mad);
+ smp_snoop(ibdev, port_num, in_mad, prev_lid);
node_desc_override(ibdev, out_mad);
}
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index b9611ade9eab..ca599767ffbd 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h
index 13a5bb1a7bcf..04b12ad23390 100644
--- a/drivers/infiniband/hw/nes/nes.h
+++ b/drivers/infiniband/hw/nes/nes.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 4a65b96db2c8..52425154acd4 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -103,6 +103,7 @@ static int nes_disconnect(struct nes_qp *nesqp, int abrupt);
static void nes_disconnect_worker(struct work_struct *work);
static int send_mpa_request(struct nes_cm_node *, struct sk_buff *);
+static int send_mpa_reject(struct nes_cm_node *);
static int send_syn(struct nes_cm_node *, u32, struct sk_buff *);
static int send_reset(struct nes_cm_node *, struct sk_buff *);
static int send_ack(struct nes_cm_node *cm_node, struct sk_buff *skb);
@@ -113,8 +114,7 @@ static void process_packet(struct nes_cm_node *, struct sk_buff *,
static void active_open_err(struct nes_cm_node *, struct sk_buff *, int);
static void passive_open_err(struct nes_cm_node *, struct sk_buff *, int);
static void cleanup_retrans_entry(struct nes_cm_node *);
-static void handle_rcv_mpa(struct nes_cm_node *, struct sk_buff *,
- enum nes_cm_event_type);
+static void handle_rcv_mpa(struct nes_cm_node *, struct sk_buff *);
static void free_retrans_entry(struct nes_cm_node *cm_node);
static int handle_tcp_options(struct nes_cm_node *cm_node, struct tcphdr *tcph,
struct sk_buff *skb, int optionsize, int passive);
@@ -124,6 +124,8 @@ static void cm_event_connected(struct nes_cm_event *);
static void cm_event_connect_error(struct nes_cm_event *);
static void cm_event_reset(struct nes_cm_event *);
static void cm_event_mpa_req(struct nes_cm_event *);
+static void cm_event_mpa_reject(struct nes_cm_event *);
+static void handle_recv_entry(struct nes_cm_node *cm_node, u32 rem_node);
static void print_core(struct nes_cm_core *core);
@@ -196,7 +198,6 @@ static struct nes_cm_event *create_event(struct nes_cm_node *cm_node,
*/
static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb)
{
- int ret;
if (!skb) {
nes_debug(NES_DBG_CM, "skb set to NULL\n");
return -1;
@@ -206,11 +207,27 @@ static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb)
form_cm_frame(skb, cm_node, NULL, 0, &cm_node->mpa_frame,
cm_node->mpa_frame_size, SET_ACK);
- ret = schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
- if (ret < 0)
- return ret;
+ return schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
+}
- return 0;
+
+
+static int send_mpa_reject(struct nes_cm_node *cm_node)
+{
+ struct sk_buff *skb = NULL;
+
+ skb = dev_alloc_skb(MAX_CM_BUFFER);
+ if (!skb) {
+ nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
+ return -ENOMEM;
+ }
+
+ /* send an MPA reject frame */
+ form_cm_frame(skb, cm_node, NULL, 0, &cm_node->mpa_frame,
+ cm_node->mpa_frame_size, SET_ACK | SET_FIN);
+
+ cm_node->state = NES_CM_STATE_FIN_WAIT1;
+ return schedule_nes_timer(cm_node, skb, NES_TIMER_TYPE_SEND, 1, 0);
}
@@ -218,14 +235,17 @@ static int send_mpa_request(struct nes_cm_node *cm_node, struct sk_buff *skb)
* recv_mpa - process a received TCP pkt, we are expecting an
* IETF MPA frame
*/
-static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 len)
+static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 *type,
+ u32 len)
{
struct ietf_mpa_frame *mpa_frame;
+ *type = NES_MPA_REQUEST_ACCEPT;
+
/* assume req frame is in tcp data payload */
if (len < sizeof(struct ietf_mpa_frame)) {
nes_debug(NES_DBG_CM, "The received ietf buffer was too small (%x)\n", len);
- return -1;
+ return -EINVAL;
}
mpa_frame = (struct ietf_mpa_frame *)buffer;
@@ -234,14 +254,25 @@ static int parse_mpa(struct nes_cm_node *cm_node, u8 *buffer, u32 len)
if (cm_node->mpa_frame_size + sizeof(struct ietf_mpa_frame) != len) {
nes_debug(NES_DBG_CM, "The received ietf buffer was not right"
" complete (%x + %x != %x)\n",
- cm_node->mpa_frame_size, (u32)sizeof(struct ietf_mpa_frame), len);
- return -1;
+ cm_node->mpa_frame_size,
+ (u32)sizeof(struct ietf_mpa_frame), len);
+ return -EINVAL;
+ }
+ /* make sure it does not exceed the max size */
+ if (len > MAX_CM_BUFFER) {
+ nes_debug(NES_DBG_CM, "The received ietf buffer was too large"
+ " (%x + %x != %x)\n",
+ cm_node->mpa_frame_size,
+ (u32)sizeof(struct ietf_mpa_frame), len);
+ return -EINVAL;
}
/* copy entire MPA frame to our cm_node's frame */
memcpy(cm_node->mpa_frame_buf, buffer + sizeof(struct ietf_mpa_frame),
cm_node->mpa_frame_size);
+ if (mpa_frame->flags & IETF_MPA_FLAGS_REJECT)
+ *type = NES_MPA_REQUEST_REJECT;
return 0;
}
@@ -380,7 +411,7 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC);
if (!new_send)
- return -1;
+ return -ENOMEM;
/* new_send->timetosend = currenttime */
new_send->retrycount = NES_DEFAULT_RETRYS;
@@ -394,9 +425,11 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
if (type == NES_TIMER_TYPE_CLOSE) {
new_send->timetosend += (HZ/10);
- spin_lock_irqsave(&cm_node->recv_list_lock, flags);
- list_add_tail(&new_send->list, &cm_node->recv_list);
- spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
+ if (cm_node->recv_entry) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ cm_node->recv_entry = new_send;
}
if (type == NES_TIMER_TYPE_SEND) {
@@ -435,24 +468,78 @@ int schedule_nes_timer(struct nes_cm_node *cm_node, struct sk_buff *skb,
return ret;
}
+static void nes_retrans_expired(struct nes_cm_node *cm_node)
+{
+ switch (cm_node->state) {
+ case NES_CM_STATE_SYN_RCVD:
+ case NES_CM_STATE_CLOSING:
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
+ break;
+ case NES_CM_STATE_LAST_ACK:
+ case NES_CM_STATE_FIN_WAIT1:
+ case NES_CM_STATE_MPAREJ_RCVD:
+ send_reset(cm_node, NULL);
+ break;
+ default:
+ create_event(cm_node, NES_CM_EVENT_ABORTED);
+ }
+}
+
+static void handle_recv_entry(struct nes_cm_node *cm_node, u32 rem_node)
+{
+ struct nes_timer_entry *recv_entry = cm_node->recv_entry;
+ struct iw_cm_id *cm_id = cm_node->cm_id;
+ struct nes_qp *nesqp;
+ unsigned long qplockflags;
+
+ if (!recv_entry)
+ return;
+ nesqp = (struct nes_qp *)recv_entry->skb;
+ if (nesqp) {
+ spin_lock_irqsave(&nesqp->lock, qplockflags);
+ if (nesqp->cm_id) {
+ nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
+ "refcount = %d: HIT A "
+ "NES_TIMER_TYPE_CLOSE with something "
+ "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
+ atomic_read(&nesqp->refcount));
+ nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
+ nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
+ nesqp->ibqp_state = IB_QPS_ERR;
+ spin_unlock_irqrestore(&nesqp->lock, qplockflags);
+ nes_cm_disconn(nesqp);
+ } else {
+ spin_unlock_irqrestore(&nesqp->lock, qplockflags);
+ nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
+ "refcount = %d: HIT A "
+ "NES_TIMER_TYPE_CLOSE with nothing "
+ "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
+ atomic_read(&nesqp->refcount));
+ }
+ } else if (rem_node) {
+ /* TIME_WAIT state */
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
+ }
+ if (cm_node->cm_id)
+ cm_id->rem_ref(cm_id);
+ kfree(recv_entry);
+ cm_node->recv_entry = NULL;
+}
/**
* nes_cm_timer_tick
*/
static void nes_cm_timer_tick(unsigned long pass)
{
- unsigned long flags, qplockflags;
+ unsigned long flags;
unsigned long nexttimeout = jiffies + NES_LONG_TIME;
- struct iw_cm_id *cm_id;
struct nes_cm_node *cm_node;
struct nes_timer_entry *send_entry, *recv_entry;
- struct list_head *list_core, *list_core_temp;
- struct list_head *list_node, *list_node_temp;
+ struct list_head *list_core_temp;
+ struct list_head *list_node;
struct nes_cm_core *cm_core = g_cm_core;
- struct nes_qp *nesqp;
u32 settimer = 0;
int ret = NETDEV_TX_OK;
- enum nes_cm_node_state last_state;
struct list_head timer_list;
INIT_LIST_HEAD(&timer_list);
@@ -461,7 +548,7 @@ static void nes_cm_timer_tick(unsigned long pass)
list_for_each_safe(list_node, list_core_temp,
&cm_core->connected_nodes) {
cm_node = container_of(list_node, struct nes_cm_node, list);
- if (!list_empty(&cm_node->recv_list) || (cm_node->send_entry)) {
+ if ((cm_node->recv_entry) || (cm_node->send_entry)) {
add_ref_cm_node(cm_node);
list_add(&cm_node->timer_entry, &timer_list);
}
@@ -471,54 +558,18 @@ static void nes_cm_timer_tick(unsigned long pass)
list_for_each_safe(list_node, list_core_temp, &timer_list) {
cm_node = container_of(list_node, struct nes_cm_node,
timer_entry);
- spin_lock_irqsave(&cm_node->recv_list_lock, flags);
- list_for_each_safe(list_core, list_node_temp,
- &cm_node->recv_list) {
- recv_entry = container_of(list_core,
- struct nes_timer_entry, list);
- if (!recv_entry)
- break;
+ recv_entry = cm_node->recv_entry;
+
+ if (recv_entry) {
if (time_after(recv_entry->timetosend, jiffies)) {
if (nexttimeout > recv_entry->timetosend ||
- !settimer) {
+ !settimer) {
nexttimeout = recv_entry->timetosend;
settimer = 1;
}
- continue;
- }
- list_del(&recv_entry->list);
- cm_id = cm_node->cm_id;
- spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
- nesqp = (struct nes_qp *)recv_entry->skb;
- spin_lock_irqsave(&nesqp->lock, qplockflags);
- if (nesqp->cm_id) {
- nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
- "refcount = %d: HIT A "
- "NES_TIMER_TYPE_CLOSE with something "
- "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
- atomic_read(&nesqp->refcount));
- nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
- nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
- nesqp->ibqp_state = IB_QPS_ERR;
- spin_unlock_irqrestore(&nesqp->lock,
- qplockflags);
- nes_cm_disconn(nesqp);
- } else {
- spin_unlock_irqrestore(&nesqp->lock,
- qplockflags);
- nes_debug(NES_DBG_CM, "QP%u: cm_id = %p, "
- "refcount = %d: HIT A "
- "NES_TIMER_TYPE_CLOSE with nothing "
- "to do!!!\n", nesqp->hwqp.qp_id, cm_id,
- atomic_read(&nesqp->refcount));
- }
- if (cm_id)
- cm_id->rem_ref(cm_id);
-
- kfree(recv_entry);
- spin_lock_irqsave(&cm_node->recv_list_lock, flags);
+ } else
+ handle_recv_entry(cm_node, 1);
}
- spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
spin_lock_irqsave(&cm_node->retrans_list_lock, flags);
do {
@@ -533,12 +584,11 @@ static void nes_cm_timer_tick(unsigned long pass)
nexttimeout =
send_entry->timetosend;
settimer = 1;
- break;
}
} else {
free_retrans_entry(cm_node);
- break;
}
+ break;
}
if ((cm_node->state == NES_CM_STATE_TSA) ||
@@ -550,16 +600,12 @@ static void nes_cm_timer_tick(unsigned long pass)
if (!send_entry->retranscount ||
!send_entry->retrycount) {
cm_packets_dropped++;
- last_state = cm_node->state;
- cm_node->state = NES_CM_STATE_CLOSED;
free_retrans_entry(cm_node);
+
spin_unlock_irqrestore(
&cm_node->retrans_list_lock, flags);
- if (last_state == NES_CM_STATE_SYN_RCVD)
- rem_ref_cm_node(cm_core, cm_node);
- else
- create_event(cm_node,
- NES_CM_EVENT_ABORTED);
+ nes_retrans_expired(cm_node);
+ cm_node->state = NES_CM_STATE_CLOSED;
spin_lock_irqsave(&cm_node->retrans_list_lock,
flags);
break;
@@ -714,7 +760,7 @@ static int send_reset(struct nes_cm_node *cm_node, struct sk_buff *skb)
skb = dev_alloc_skb(MAX_CM_BUFFER);
if (!skb) {
nes_debug(NES_DBG_CM, "Failed to get a Free pkt\n");
- return -1;
+ return -ENOMEM;
}
form_cm_frame(skb, cm_node, NULL, 0, NULL, 0, flags);
@@ -778,14 +824,10 @@ static struct nes_cm_node *find_node(struct nes_cm_core *cm_core,
unsigned long flags;
struct list_head *hte;
struct nes_cm_node *cm_node;
- __be32 tmp_addr = cpu_to_be32(loc_addr);
/* get a handle on the hte */
hte = &cm_core->connected_nodes;
- nes_debug(NES_DBG_CM, "Searching for an owner node: %pI4:%x from core %p->%p\n",
- &tmp_addr, loc_port, cm_core, hte);
-
/* walk list and find cm_node associated with this session ID */
spin_lock_irqsave(&cm_core->ht_lock, flags);
list_for_each_entry(cm_node, hte, list) {
@@ -875,7 +917,8 @@ static int add_hte_node(struct nes_cm_core *cm_core, struct nes_cm_node *cm_node
static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
struct nes_cm_listener *listener, int free_hanging_nodes)
{
- int ret = 1;
+ int ret = -EINVAL;
+ int err = 0;
unsigned long flags;
struct list_head *list_pos = NULL;
struct list_head *list_temp = NULL;
@@ -904,10 +947,60 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
list_for_each_safe(list_pos, list_temp, &reset_list) {
cm_node = container_of(list_pos, struct nes_cm_node,
- reset_entry);
- cleanup_retrans_entry(cm_node);
- send_reset(cm_node, NULL);
- rem_ref_cm_node(cm_node->cm_core, cm_node);
+ reset_entry);
+ {
+ struct nes_cm_node *loopback = cm_node->loopbackpartner;
+ if (NES_CM_STATE_FIN_WAIT1 <= cm_node->state) {
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
+ } else {
+ if (!loopback) {
+ cleanup_retrans_entry(cm_node);
+ err = send_reset(cm_node, NULL);
+ if (err) {
+ cm_node->state =
+ NES_CM_STATE_CLOSED;
+ WARN_ON(1);
+ } else {
+ cm_node->state =
+ NES_CM_STATE_CLOSED;
+ rem_ref_cm_node(
+ cm_node->cm_core,
+ cm_node);
+ }
+ } else {
+ struct nes_cm_event event;
+
+ event.cm_node = loopback;
+ event.cm_info.rem_addr =
+ loopback->rem_addr;
+ event.cm_info.loc_addr =
+ loopback->loc_addr;
+ event.cm_info.rem_port =
+ loopback->rem_port;
+ event.cm_info.loc_port =
+ loopback->loc_port;
+ event.cm_info.cm_id = loopback->cm_id;
+ cm_event_connect_error(&event);
+ loopback->state = NES_CM_STATE_CLOSED;
+
+ event.cm_node = cm_node;
+ event.cm_info.rem_addr =
+ cm_node->rem_addr;
+ event.cm_info.loc_addr =
+ cm_node->loc_addr;
+ event.cm_info.rem_port =
+ cm_node->rem_port;
+ event.cm_info.loc_port =
+ cm_node->loc_port;
+ event.cm_info.cm_id = cm_node->cm_id;
+ cm_event_reset(&event);
+
+ rem_ref_cm_node(cm_node->cm_core,
+ cm_node);
+
+ }
+ }
+ }
}
spin_lock_irqsave(&cm_core->listen_list_lock, flags);
@@ -968,6 +1061,7 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core,
if (cm_node->accept_pend) {
BUG_ON(!cm_node->listener);
atomic_dec(&cm_node->listener->pend_accepts_cnt);
+ cm_node->accept_pend = 0;
BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
}
@@ -994,7 +1088,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip)
memset(&fl, 0, sizeof fl);
fl.nl_u.ip4_u.daddr = htonl(dst_ip);
if (ip_route_output_key(&init_net, &rt, &fl)) {
- printk("%s: ip_route_output_key failed for 0x%08X\n",
+ printk(KERN_ERR "%s: ip_route_output_key failed for 0x%08X\n",
__func__, dst_ip);
return rc;
}
@@ -1057,8 +1151,6 @@ static struct nes_cm_node *make_cm_node(struct nes_cm_core *cm_core,
cm_node->cm_id);
spin_lock_init(&cm_node->retrans_list_lock);
- INIT_LIST_HEAD(&cm_node->recv_list);
- spin_lock_init(&cm_node->recv_list_lock);
cm_node->loopbackpartner = NULL;
atomic_set(&cm_node->ref_count, 1);
@@ -1126,10 +1218,7 @@ static int add_ref_cm_node(struct nes_cm_node *cm_node)
static int rem_ref_cm_node(struct nes_cm_core *cm_core,
struct nes_cm_node *cm_node)
{
- unsigned long flags, qplockflags;
- struct nes_timer_entry *recv_entry;
- struct iw_cm_id *cm_id;
- struct list_head *list_core, *list_node_temp;
+ unsigned long flags;
struct nes_qp *nesqp;
if (!cm_node)
@@ -1150,38 +1239,9 @@ static int rem_ref_cm_node(struct nes_cm_core *cm_core,
atomic_dec(&cm_node->listener->pend_accepts_cnt);
BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
}
- BUG_ON(cm_node->send_entry);
- spin_lock_irqsave(&cm_node->recv_list_lock, flags);
- list_for_each_safe(list_core, list_node_temp, &cm_node->recv_list) {
- recv_entry = container_of(list_core, struct nes_timer_entry,
- list);
- list_del(&recv_entry->list);
- cm_id = cm_node->cm_id;
- spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
- nesqp = (struct nes_qp *)recv_entry->skb;
- spin_lock_irqsave(&nesqp->lock, qplockflags);
- if (nesqp->cm_id) {
- nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
- "NES_TIMER_TYPE_CLOSE with something to do!\n",
- nesqp->hwqp.qp_id, cm_id);
- nesqp->hw_tcp_state = NES_AEQE_TCP_STATE_CLOSED;
- nesqp->last_aeq = NES_AEQE_AEID_RESET_SENT;
- nesqp->ibqp_state = IB_QPS_ERR;
- spin_unlock_irqrestore(&nesqp->lock, qplockflags);
- nes_cm_disconn(nesqp);
- } else {
- spin_unlock_irqrestore(&nesqp->lock, qplockflags);
- nes_debug(NES_DBG_CM, "QP%u: cm_id = %p: HIT A "
- "NES_TIMER_TYPE_CLOSE with nothing to do!\n",
- nesqp->hwqp.qp_id, cm_id);
- }
- cm_id->rem_ref(cm_id);
-
- kfree(recv_entry);
- spin_lock_irqsave(&cm_node->recv_list_lock, flags);
- }
- spin_unlock_irqrestore(&cm_node->recv_list_lock, flags);
-
+ WARN_ON(cm_node->send_entry);
+ if (cm_node->recv_entry)
+ handle_recv_entry(cm_node, 0);
if (cm_node->listener) {
mini_cm_dec_refcnt_listen(cm_core, cm_node->listener, 0);
} else {
@@ -1266,8 +1326,7 @@ static void drop_packet(struct sk_buff *skb)
dev_kfree_skb_any(skb);
}
-static void handle_fin_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
- struct tcphdr *tcph)
+static void handle_fin_pkt(struct nes_cm_node *cm_node)
{
nes_debug(NES_DBG_CM, "Received FIN, cm_node = %p, state = %u. "
"refcnt=%d\n", cm_node, cm_node->state,
@@ -1279,23 +1338,30 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
case NES_CM_STATE_SYN_SENT:
case NES_CM_STATE_ESTABLISHED:
case NES_CM_STATE_MPAREQ_SENT:
+ case NES_CM_STATE_MPAREJ_RCVD:
cm_node->state = NES_CM_STATE_LAST_ACK;
- send_fin(cm_node, skb);
+ send_fin(cm_node, NULL);
break;
case NES_CM_STATE_FIN_WAIT1:
cm_node->state = NES_CM_STATE_CLOSING;
- send_ack(cm_node, skb);
+ send_ack(cm_node, NULL);
+ /* Wait for ACK as this is simultanous close..
+ * After we receive ACK, do not send anything..
+ * Just rm the node.. Done.. */
break;
case NES_CM_STATE_FIN_WAIT2:
cm_node->state = NES_CM_STATE_TIME_WAIT;
- send_ack(cm_node, skb);
+ send_ack(cm_node, NULL);
+ schedule_nes_timer(cm_node, NULL, NES_TIMER_TYPE_CLOSE, 1, 0);
+ break;
+ case NES_CM_STATE_TIME_WAIT:
cm_node->state = NES_CM_STATE_CLOSED;
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
break;
case NES_CM_STATE_TSA:
default:
nes_debug(NES_DBG_CM, "Error Rcvd FIN for node-%p state = %d\n",
cm_node, cm_node->state);
- drop_packet(skb);
break;
}
}
@@ -1341,23 +1407,35 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
cleanup_retrans_entry(cm_node);
drop_packet(skb);
break;
+ case NES_CM_STATE_TIME_WAIT:
+ cleanup_retrans_entry(cm_node);
+ cm_node->state = NES_CM_STATE_CLOSED;
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
+ drop_packet(skb);
+ break;
+ case NES_CM_STATE_FIN_WAIT1:
+ cleanup_retrans_entry(cm_node);
+ nes_debug(NES_DBG_CM, "Bad state %s[%u]\n", __func__, __LINE__);
default:
drop_packet(skb);
break;
}
}
-static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb,
- enum nes_cm_event_type type)
+
+static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb)
{
- int ret;
+ int ret = 0;
int datasize = skb->len;
u8 *dataloc = skb->data;
- ret = parse_mpa(cm_node, dataloc, datasize);
- if (ret < 0) {
+
+ enum nes_cm_event_type type = NES_CM_EVENT_UNKNOWN;
+ u32 res_type;
+ ret = parse_mpa(cm_node, dataloc, &res_type, datasize);
+ if (ret) {
nes_debug(NES_DBG_CM, "didn't like MPA Request\n");
- if (type == NES_CM_EVENT_CONNECTED) {
+ if (cm_node->state == NES_CM_STATE_MPAREQ_SENT) {
nes_debug(NES_DBG_CM, "%s[%u] create abort for "
"cm_node=%p listener=%p state=%d\n", __func__,
__LINE__, cm_node, cm_node->listener,
@@ -1366,18 +1444,38 @@ static void handle_rcv_mpa(struct nes_cm_node *cm_node, struct sk_buff *skb,
} else {
passive_open_err(cm_node, skb, 1);
}
- } else {
- cleanup_retrans_entry(cm_node);
- dev_kfree_skb_any(skb);
- if (type == NES_CM_EVENT_CONNECTED)
+ return;
+ }
+
+ switch (cm_node->state) {
+ case NES_CM_STATE_ESTABLISHED:
+ if (res_type == NES_MPA_REQUEST_REJECT) {
+ /*BIG problem as we are receiving the MPA.. So should
+ * not be REJECT.. This is Passive Open.. We can
+ * only receive it Reject for Active Open...*/
+ WARN_ON(1);
+ }
+ cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
+ type = NES_CM_EVENT_MPA_REQ;
+ atomic_set(&cm_node->passive_state,
+ NES_PASSIVE_STATE_INDICATED);
+ break;
+ case NES_CM_STATE_MPAREQ_SENT:
+ if (res_type == NES_MPA_REQUEST_REJECT) {
+ type = NES_CM_EVENT_MPA_REJECT;
+ cm_node->state = NES_CM_STATE_MPAREJ_RCVD;
+ } else {
+ type = NES_CM_EVENT_CONNECTED;
cm_node->state = NES_CM_STATE_TSA;
- else
- atomic_set(&cm_node->passive_state,
- NES_PASSIVE_STATE_INDICATED);
- create_event(cm_node, type);
+ }
+ break;
+ default:
+ WARN_ON(1);
+ break;
}
- return ;
+ dev_kfree_skb_any(skb);
+ create_event(cm_node, type);
}
static void indicate_pkt_err(struct nes_cm_node *cm_node, struct sk_buff *skb)
@@ -1465,8 +1563,6 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
break;
case NES_CM_STATE_LISTENING:
/* Passive OPEN */
- cm_node->accept_pend = 1;
- atomic_inc(&cm_node->listener->pend_accepts_cnt);
if (atomic_read(&cm_node->listener->pend_accepts_cnt) >
cm_node->listener->backlog) {
nes_debug(NES_DBG_CM, "drop syn due to backlog "
@@ -1484,6 +1580,9 @@ static void handle_syn_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
}
cm_node->tcp_cntxt.rcv_nxt = inc_sequence + 1;
BUG_ON(cm_node->send_entry);
+ cm_node->accept_pend = 1;
+ atomic_inc(&cm_node->listener->pend_accepts_cnt);
+
cm_node->state = NES_CM_STATE_SYN_RCVD;
send_syn(cm_node, 1, skb);
break;
@@ -1518,6 +1617,7 @@ static void handle_synack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
inc_sequence = ntohl(tcph->seq);
switch (cm_node->state) {
case NES_CM_STATE_SYN_SENT:
+ cleanup_retrans_entry(cm_node);
/* active open */
if (check_syn(cm_node, tcph, skb))
return;
@@ -1567,10 +1667,7 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
u32 rem_seq;
int ret;
int optionsize;
- u32 temp_seq = cm_node->tcp_cntxt.loc_seq_num;
-
optionsize = (tcph->doff << 2) - sizeof(struct tcphdr);
- cm_node->tcp_cntxt.loc_seq_num = ntohl(tcph->ack_seq);
if (check_seq(cm_node, tcph, skb))
return;
@@ -1580,7 +1677,7 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
rem_seq = ntohl(tcph->seq);
rem_seq_ack = ntohl(tcph->ack_seq);
datasize = skb->len;
-
+ cleanup_retrans_entry(cm_node);
switch (cm_node->state) {
case NES_CM_STATE_SYN_RCVD:
/* Passive OPEN */
@@ -1588,7 +1685,6 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
if (ret)
break;
cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
- cm_node->tcp_cntxt.loc_seq_num = temp_seq;
if (cm_node->tcp_cntxt.rem_ack_num !=
cm_node->tcp_cntxt.loc_seq_num) {
nes_debug(NES_DBG_CM, "rem_ack_num != loc_seq_num\n");
@@ -1597,31 +1693,30 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
return;
}
cm_node->state = NES_CM_STATE_ESTABLISHED;
+ cleanup_retrans_entry(cm_node);
if (datasize) {
cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
- cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
- handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_MPA_REQ);
- } else { /* rcvd ACK only */
+ handle_rcv_mpa(cm_node, skb);
+ } else { /* rcvd ACK only */
dev_kfree_skb_any(skb);
cleanup_retrans_entry(cm_node);
}
break;
case NES_CM_STATE_ESTABLISHED:
/* Passive OPEN */
- /* We expect mpa frame to be received only */
+ cleanup_retrans_entry(cm_node);
if (datasize) {
cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
- cm_node->state = NES_CM_STATE_MPAREQ_RCVD;
- handle_rcv_mpa(cm_node, skb,
- NES_CM_EVENT_MPA_REQ);
+ handle_rcv_mpa(cm_node, skb);
} else
drop_packet(skb);
break;
case NES_CM_STATE_MPAREQ_SENT:
+ cleanup_retrans_entry(cm_node);
cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq);
if (datasize) {
cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize;
- handle_rcv_mpa(cm_node, skb, NES_CM_EVENT_CONNECTED);
+ handle_rcv_mpa(cm_node, skb);
} else { /* Could be just an ack pkt.. */
cleanup_retrans_entry(cm_node);
dev_kfree_skb_any(skb);
@@ -1632,13 +1727,24 @@ static void handle_ack_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb,
cleanup_retrans_entry(cm_node);
send_reset(cm_node, skb);
break;
+ case NES_CM_STATE_LAST_ACK:
+ cleanup_retrans_entry(cm_node);
+ cm_node->state = NES_CM_STATE_CLOSED;
+ cm_node->cm_id->rem_ref(cm_node->cm_id);
+ case NES_CM_STATE_CLOSING:
+ cleanup_retrans_entry(cm_node);
+ rem_ref_cm_node(cm_node->cm_core, cm_node);
+ drop_packet(skb);
+ break;
case NES_CM_STATE_FIN_WAIT1:
+ cleanup_retrans_entry(cm_node);
+ drop_packet(skb);
+ cm_node->state = NES_CM_STATE_FIN_WAIT2;
+ break;
case NES_CM_STATE_SYN_SENT:
case NES_CM_STATE_FIN_WAIT2:
case NES_CM_STATE_TSA:
case NES_CM_STATE_MPAREQ_RCVD:
- case NES_CM_STATE_LAST_ACK:
- case NES_CM_STATE_CLOSING:
case NES_CM_STATE_UNKNOWN:
default:
drop_packet(skb);
@@ -1748,6 +1854,7 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
{
enum nes_tcpip_pkt_type pkt_type = NES_PKT_TYPE_UNKNOWN;
struct tcphdr *tcph = tcp_hdr(skb);
+ u32 fin_set = 0;
skb_pull(skb, ip_hdr(skb)->ihl << 2);
nes_debug(NES_DBG_CM, "process_packet: cm_node=%p state =%d syn=%d "
@@ -1760,10 +1867,10 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
pkt_type = NES_PKT_TYPE_SYN;
if (tcph->ack)
pkt_type = NES_PKT_TYPE_SYNACK;
- } else if (tcph->fin)
- pkt_type = NES_PKT_TYPE_FIN;
- else if (tcph->ack)
+ } else if (tcph->ack)
pkt_type = NES_PKT_TYPE_ACK;
+ if (tcph->fin)
+ fin_set = 1;
switch (pkt_type) {
case NES_PKT_TYPE_SYN:
@@ -1774,15 +1881,16 @@ static void process_packet(struct nes_cm_node *cm_node, struct sk_buff *skb,
break;
case NES_PKT_TYPE_ACK:
handle_ack_pkt(cm_node, skb, tcph);
+ if (fin_set)
+ handle_fin_pkt(cm_node);
break;
case NES_PKT_TYPE_RST:
handle_rst_pkt(cm_node, skb, tcph);
break;
- case NES_PKT_TYPE_FIN:
- handle_fin_pkt(cm_node, skb, tcph);
- break;
default:
drop_packet(skb);
+ if (fin_set)
+ handle_fin_pkt(cm_node);
break;
}
}
@@ -1925,7 +2033,7 @@ static struct nes_cm_node *mini_cm_connect(struct nes_cm_core *cm_core,
loopbackremotenode->tcp_cntxt.rcv_wscale;
loopbackremotenode->tcp_cntxt.snd_wscale =
cm_node->tcp_cntxt.rcv_wscale;
-
+ loopbackremotenode->state = NES_CM_STATE_MPAREQ_RCVD;
create_event(loopbackremotenode, NES_CM_EVENT_MPA_REQ);
}
return cm_node;
@@ -1980,7 +2088,11 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
struct ietf_mpa_frame *mpa_frame, struct nes_cm_node *cm_node)
{
int ret = 0;
+ int err = 0;
int passive_state;
+ struct nes_cm_event event;
+ struct iw_cm_id *cm_id = cm_node->cm_id;
+ struct nes_cm_node *loopback = cm_node->loopbackpartner;
nes_debug(NES_DBG_CM, "%s cm_node=%p type=%d state=%d\n",
__func__, cm_node, cm_node->tcp_cntxt.client, cm_node->state);
@@ -1989,12 +2101,38 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
return ret;
cleanup_retrans_entry(cm_node);
- passive_state = atomic_add_return(1, &cm_node->passive_state);
- cm_node->state = NES_CM_STATE_CLOSED;
- if (passive_state == NES_SEND_RESET_EVENT)
+ if (!loopback) {
+ passive_state = atomic_add_return(1, &cm_node->passive_state);
+ if (passive_state == NES_SEND_RESET_EVENT) {
+ cm_node->state = NES_CM_STATE_CLOSED;
+ rem_ref_cm_node(cm_core, cm_node);
+ } else {
+ ret = send_mpa_reject(cm_node);
+ if (ret) {
+ cm_node->state = NES_CM_STATE_CLOSED;
+ err = send_reset(cm_node, NULL);
+ if (err)
+ WARN_ON(1);
+ } else
+ cm_id->add_ref(cm_id);
+ }
+ } else {
+ cm_node->cm_id = NULL;
+ event.cm_node = loopback;
+ event.cm_info.rem_addr = loopback->rem_addr;
+ event.cm_info.loc_addr = loopback->loc_addr;
+ event.cm_info.rem_port = loopback->rem_port;
+ event.cm_info.loc_port = loopback->loc_port;
+ event.cm_info.cm_id = loopback->cm_id;
+ cm_event_mpa_reject(&event);
rem_ref_cm_node(cm_core, cm_node);
- else
- ret = send_reset(cm_node, NULL);
+ loopback->state = NES_CM_STATE_CLOSING;
+
+ cm_id = loopback->cm_id;
+ rem_ref_cm_node(cm_core, loopback);
+ cm_id->rem_ref(cm_id);
+ }
+
return ret;
}
@@ -2031,6 +2169,7 @@ static int mini_cm_close(struct nes_cm_core *cm_core, struct nes_cm_node *cm_nod
case NES_CM_STATE_CLOSING:
ret = -1;
break;
+ case NES_CM_STATE_MPAREJ_RCVD:
case NES_CM_STATE_LISTENING:
case NES_CM_STATE_UNKNOWN:
case NES_CM_STATE_INITED:
@@ -2227,15 +2366,15 @@ static int mini_cm_set(struct nes_cm_core *cm_core, u32 type, u32 value)
int ret = 0;
switch (type) {
- case NES_CM_SET_PKT_SIZE:
- cm_core->mtu = value;
- break;
- case NES_CM_SET_FREE_PKT_Q_SIZE:
- cm_core->free_tx_pkt_max = value;
- break;
- default:
- /* unknown set option */
- ret = -EINVAL;
+ case NES_CM_SET_PKT_SIZE:
+ cm_core->mtu = value;
+ break;
+ case NES_CM_SET_FREE_PKT_Q_SIZE:
+ cm_core->free_tx_pkt_max = value;
+ break;
+ default:
+ /* unknown set option */
+ ret = -EINVAL;
}
return ret;
@@ -2654,9 +2793,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
NES_QPCONTEXT_ORDIRD_WRPDU);
} else {
nesqp->nesqp_context->ird_ord_sizes |=
- cpu_to_le32((NES_QPCONTEXT_ORDIRD_LSMM_PRESENT |
- NES_QPCONTEXT_ORDIRD_WRPDU |
- NES_QPCONTEXT_ORDIRD_ALSMM));
+ cpu_to_le32(NES_QPCONTEXT_ORDIRD_WRPDU);
}
nesqp->skip_lsmm = 1;
@@ -2778,23 +2915,35 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
int nes_reject(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len)
{
struct nes_cm_node *cm_node;
+ struct nes_cm_node *loopback;
+
struct nes_cm_core *cm_core;
atomic_inc(&cm_rejects);
cm_node = (struct nes_cm_node *) cm_id->provider_data;
+ loopback = cm_node->loopbackpartner;
cm_core = cm_node->cm_core;
+ cm_node->cm_id = cm_id;
cm_node->mpa_frame_size = sizeof(struct ietf_mpa_frame) + pdata_len;
+ if (cm_node->mpa_frame_size > MAX_CM_BUFFER)
+ return -EINVAL;
+
strcpy(&cm_node->mpa_frame.key[0], IEFT_MPA_KEY_REP);
- memcpy(&cm_node->mpa_frame.priv_data, pdata, pdata_len);
+ if (loopback) {
+ memcpy(&loopback->mpa_frame.priv_data, pdata, pdata_len);
+ loopback->mpa_frame.priv_data_len = pdata_len;
+ loopback->mpa_frame_size = sizeof(struct ietf_mpa_frame) +
+ pdata_len;
+ } else {
+ memcpy(&cm_node->mpa_frame.priv_data, pdata, pdata_len);
+ cm_node->mpa_frame.priv_data_len = cpu_to_be16(pdata_len);
+ }
- cm_node->mpa_frame.priv_data_len = cpu_to_be16(pdata_len);
cm_node->mpa_frame.rev = mpa_version;
cm_node->mpa_frame.flags = IETF_MPA_FLAGS_CRC | IETF_MPA_FLAGS_REJECT;
- cm_core->api->reject(cm_core, &cm_node->mpa_frame, cm_node);
-
- return 0;
+ return cm_core->api->reject(cm_core, &cm_node->mpa_frame, cm_node);
}
@@ -3303,13 +3452,56 @@ static void cm_event_mpa_req(struct nes_cm_event *event)
cm_event.remote_addr.sin_family = AF_INET;
cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port);
cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr);
+ cm_event.private_data = cm_node->mpa_frame_buf;
+ cm_event.private_data_len = (u8) cm_node->mpa_frame_size;
+
+ ret = cm_id->event_handler(cm_id, &cm_event);
+ if (ret)
+ printk(KERN_ERR "%s[%u] OFA CM event_handler returned, ret=%d\n",
+ __func__, __LINE__, ret);
+ return;
+}
+
+
+static void cm_event_mpa_reject(struct nes_cm_event *event)
+{
+ struct iw_cm_id *cm_id;
+ struct iw_cm_event cm_event;
+ struct nes_cm_node *cm_node;
+ int ret;
+
+ cm_node = event->cm_node;
+ if (!cm_node)
+ return;
+ cm_id = cm_node->cm_id;
+
+ atomic_inc(&cm_connect_reqs);
+ nes_debug(NES_DBG_CM, "cm_node = %p - cm_id = %p, jiffies = %lu\n",
+ cm_node, cm_id, jiffies);
+
+ cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
+ cm_event.status = -ECONNREFUSED;
+ cm_event.provider_data = cm_id->provider_data;
+
+ cm_event.local_addr.sin_family = AF_INET;
+ cm_event.local_addr.sin_port = htons(event->cm_info.loc_port);
+ cm_event.local_addr.sin_addr.s_addr = htonl(event->cm_info.loc_addr);
+
+ cm_event.remote_addr.sin_family = AF_INET;
+ cm_event.remote_addr.sin_port = htons(event->cm_info.rem_port);
+ cm_event.remote_addr.sin_addr.s_addr = htonl(event->cm_info.rem_addr);
- cm_event.private_data = cm_node->mpa_frame_buf;
- cm_event.private_data_len = (u8) cm_node->mpa_frame_size;
+ cm_event.private_data = cm_node->mpa_frame_buf;
+ cm_event.private_data_len = (u8) cm_node->mpa_frame_size;
+
+ nes_debug(NES_DBG_CM, "call CM_EVENT_MPA_REJECTED, local_addr=%08x, "
+ "remove_addr=%08x\n",
+ cm_event.local_addr.sin_addr.s_addr,
+ cm_event.remote_addr.sin_addr.s_addr);
ret = cm_id->event_handler(cm_id, &cm_event);
if (ret)
- printk("%s[%u] OFA CM event_handler returned, ret=%d\n",
+ printk(KERN_ERR "%s[%u] OFA CM event_handler returned, ret=%d\n",
__func__, __LINE__, ret);
return;
@@ -3374,6 +3566,14 @@ static void nes_cm_event_handler(struct work_struct *work)
cm_event_connected(event);
nes_debug(NES_DBG_CM, "CM Event: CONNECTED\n");
break;
+ case NES_CM_EVENT_MPA_REJECT:
+ if ((!event->cm_node->cm_id) ||
+ (event->cm_node->state == NES_CM_STATE_TSA))
+ break;
+ cm_event_mpa_reject(event);
+ nes_debug(NES_DBG_CM, "CM Event: REJECT\n");
+ break;
+
case NES_CM_EVENT_ABORTED:
if ((!event->cm_node->cm_id) ||
(event->cm_node->state == NES_CM_STATE_TSA))
diff --git a/drivers/infiniband/hw/nes/nes_cm.h b/drivers/infiniband/hw/nes/nes_cm.h
index fafa35042ebd..d5f778202eb7 100644
--- a/drivers/infiniband/hw/nes/nes_cm.h
+++ b/drivers/infiniband/hw/nes/nes_cm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -39,6 +39,9 @@
#define NES_MANAGE_APBVT_DEL 0
#define NES_MANAGE_APBVT_ADD 1
+#define NES_MPA_REQUEST_ACCEPT 1
+#define NES_MPA_REQUEST_REJECT 2
+
/* IETF MPA -- defines, enums, structs */
#define IEFT_MPA_KEY_REQ "MPA ID Req Frame"
#define IEFT_MPA_KEY_REP "MPA ID Rep Frame"
@@ -186,6 +189,7 @@ enum nes_cm_node_state {
NES_CM_STATE_ACCEPTING,
NES_CM_STATE_MPAREQ_SENT,
NES_CM_STATE_MPAREQ_RCVD,
+ NES_CM_STATE_MPAREJ_RCVD,
NES_CM_STATE_TSA,
NES_CM_STATE_FIN_WAIT1,
NES_CM_STATE_FIN_WAIT2,
@@ -278,13 +282,12 @@ struct nes_cm_node {
struct nes_timer_entry *send_entry;
spinlock_t retrans_list_lock;
- struct list_head recv_list;
- spinlock_t recv_list_lock;
+ struct nes_timer_entry *recv_entry;
int send_write0;
union {
struct ietf_mpa_frame mpa_frame;
- u8 mpa_frame_buf[NES_CM_DEFAULT_MTU];
+ u8 mpa_frame_buf[MAX_CM_BUFFER];
};
u16 mpa_frame_size;
struct iw_cm_id *cm_id;
@@ -326,6 +329,7 @@ enum nes_cm_event_type {
NES_CM_EVENT_MPA_REQ,
NES_CM_EVENT_MPA_CONNECT,
NES_CM_EVENT_MPA_ACCEPT,
+ NES_CM_EVENT_MPA_REJECT,
NES_CM_EVENT_MPA_ESTABLISHED,
NES_CM_EVENT_CONNECTED,
NES_CM_EVENT_CLOSED,
diff --git a/drivers/infiniband/hw/nes/nes_context.h b/drivers/infiniband/hw/nes/nes_context.h
index da9daba8e668..0fb8d81d9a62 100644
--- a/drivers/infiniband/hw/nes/nes_context.h
+++ b/drivers/infiniband/hw/nes/nes_context.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 5d139db1b771..52e734042b8e 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -254,6 +254,7 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
u32 adapter_size;
u32 arp_table_size;
u16 vendor_id;
+ u16 device_id;
u8 OneG_Mode;
u8 func_index;
@@ -356,6 +357,13 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
return NULL;
}
+ nesadapter->vendor_id = (((u32) nesadapter->mac_addr_high) << 8) |
+ (nesadapter->mac_addr_low >> 24);
+
+ pci_bus_read_config_word(nesdev->pcidev->bus, nesdev->pcidev->devfn,
+ PCI_DEVICE_ID, &device_id);
+ nesadapter->vendor_part_id = device_id;
+
if (nes_init_serdes(nesdev, hw_rev, port_count, nesadapter,
OneG_Mode)) {
kfree(nesadapter);
@@ -1636,7 +1644,6 @@ int nes_init_nic_qp(struct nes_device *nesdev, struct net_device *netdev)
nesvnic->post_cqp_request = nes_post_cqp_request;
nesvnic->mcrq_mcast_filter = NULL;
- spin_lock_init(&nesvnic->nic.sq_lock);
spin_lock_init(&nesvnic->nic.rq_lock);
/* setup the RQ */
@@ -2261,6 +2268,8 @@ static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq)
if (++head >= aeq_size)
head = 0;
+
+ nes_write32(nesdev->regs + NES_AEQ_ALLOC, 1 << 16);
}
while (1);
aeq->aeq_head = head;
@@ -2541,7 +2550,7 @@ static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic
{
struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq);
- netif_rx_schedule(&nesvnic->napi);
+ napi_schedule(&nesvnic->napi);
}
@@ -2622,9 +2631,9 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
} else
break;
}
- if (skb)
- dev_kfree_skb_any(skb);
}
+ if (skb)
+ dev_kfree_skb_any(skb);
nesnic->sq_tail++;
nesnic->sq_tail &= nesnic->sq_size-1;
if (sq_cqes > 128) {
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index bc0b4de04450..f41a8710d2a8 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+* Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -61,6 +61,7 @@ enum pci_regs {
NES_CQ_ACK = 0x0034,
NES_WQE_ALLOC = 0x0040,
NES_CQE_ALLOC = 0x0044,
+ NES_AEQ_ALLOC = 0x0048
};
enum indexed_regs {
@@ -875,7 +876,6 @@ struct nes_hw_nic {
u8 replenishing_rq;
u8 reserved;
- spinlock_t sq_lock;
spinlock_t rq_lock;
};
@@ -1147,7 +1147,6 @@ struct nes_ib_device;
struct nes_vnic {
struct nes_ib_device *nesibdev;
u64 sq_full;
- u64 sq_locked;
u64 tso_requests;
u64 segmented_tso_requests;
u64 linearized_skbs;
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index 57a47cf7e513..ecb1f6fd6276 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -111,7 +111,7 @@ static int nes_netdev_poll(struct napi_struct *napi, int budget)
nes_nic_ce_handler(nesdev, nescq);
if (nescq->cqes_pending == 0) {
- netif_rx_complete(napi);
+ napi_complete(napi);
/* clear out completed cqes and arm */
nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
nescq->cq_number | (nescq->cqe_allocs_pending << 16));
@@ -400,8 +400,7 @@ static int nes_nic_send(struct sk_buff *skb, struct net_device *netdev)
if (skb_headlen(skb) == skb->len) {
if (skb_headlen(skb) <= NES_FIRST_FRAG_SIZE) {
nic_sqe->wqe_words[NES_NIC_SQ_WQE_LENGTH_2_1_IDX] = 0;
- nesnic->tx_skb[nesnic->sq_head] = NULL;
- dev_kfree_skb(skb);
+ nesnic->tx_skb[nesnic->sq_head] = skb;
}
} else {
/* Deal with Fragments */
@@ -453,7 +452,6 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
u32 wqe_count=1;
u32 send_rc;
struct iphdr *iph;
- unsigned long flags;
__le16 *wqe_fragment_length;
u32 nr_frags;
u32 original_first_length;
@@ -480,13 +478,6 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
if (netif_queue_stopped(netdev))
return NETDEV_TX_BUSY;
- local_irq_save(flags);
- if (!spin_trylock(&nesnic->sq_lock)) {
- local_irq_restore(flags);
- nesvnic->sq_locked++;
- return NETDEV_TX_LOCKED;
- }
-
/* Check if SQ is full */
if ((((nesnic->sq_tail+(nesnic->sq_size*2))-nesnic->sq_head) & (nesnic->sq_size - 1)) == 1) {
if (!netif_queue_stopped(netdev)) {
@@ -498,7 +489,6 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, struct net_device *netdev)
}
}
nesvnic->sq_full++;
- spin_unlock_irqrestore(&nesnic->sq_lock, flags);
return NETDEV_TX_BUSY;
}
@@ -531,7 +521,6 @@ sq_no_longer_full:
}
}
nesvnic->sq_full++;
- spin_unlock_irqrestore(&nesnic->sq_lock, flags);
nes_debug(NES_DBG_NIC_TX, "%s: HNIC SQ full- TSO request has too many frags!\n",
netdev->name);
return NETDEV_TX_BUSY;
@@ -656,17 +645,13 @@ tso_sq_no_longer_full:
skb_set_transport_header(skb, hoffset);
skb_set_network_header(skb, nhoffset);
send_rc = nes_nic_send(skb, netdev);
- if (send_rc != NETDEV_TX_OK) {
- spin_unlock_irqrestore(&nesnic->sq_lock, flags);
+ if (send_rc != NETDEV_TX_OK)
return NETDEV_TX_OK;
- }
}
} else {
send_rc = nes_nic_send(skb, netdev);
- if (send_rc != NETDEV_TX_OK) {
- spin_unlock_irqrestore(&nesnic->sq_lock, flags);
+ if (send_rc != NETDEV_TX_OK)
return NETDEV_TX_OK;
- }
}
barrier();
@@ -676,7 +661,6 @@ tso_sq_no_longer_full:
(wqe_count << 24) | (1 << 23) | nesvnic->nic.qp_id);
netdev->trans_start = jiffies;
- spin_unlock_irqrestore(&nesnic->sq_lock, flags);
return NETDEV_TX_OK;
}
@@ -1012,7 +996,6 @@ static const char nes_ethtool_stringset[][ETH_GSTRING_LEN] = {
"Pause Frames Received",
"Internal Routing Errors",
"SQ SW Dropped SKBs",
- "SQ Locked",
"SQ Full",
"Segmented TSO Requests",
"Rx Symbol Errors",
@@ -1129,16 +1112,17 @@ static void nes_netdev_get_ethtool_stats(struct net_device *netdev,
struct nes_device *nesdev = nesvnic->nesdev;
u32 nic_count;
u32 u32temp;
+ u32 index = 0;
target_ethtool_stats->n_stats = NES_ETHTOOL_STAT_COUNT;
- target_stat_values[0] = nesvnic->nesdev->link_status_interrupts;
- target_stat_values[1] = nesvnic->linearized_skbs;
- target_stat_values[2] = nesvnic->tso_requests;
+ target_stat_values[index] = nesvnic->nesdev->link_status_interrupts;
+ target_stat_values[++index] = nesvnic->linearized_skbs;
+ target_stat_values[++index] = nesvnic->tso_requests;
u32temp = nes_read_indexed(nesdev,
NES_IDX_MAC_TX_PAUSE_FRAMES + (nesvnic->nesdev->mac_index*0x200));
nesvnic->nesdev->mac_pause_frames_sent += u32temp;
- target_stat_values[3] = nesvnic->nesdev->mac_pause_frames_sent;
+ target_stat_values[++index] = nesvnic->nesdev->mac_pause_frames_sent;
u32temp = nes_read_indexed(nesdev,
NES_IDX_MAC_RX_PAUSE_FRAMES + (nesvnic->nesdev->mac_index*0x200));
@@ -1209,60 +1193,59 @@ static void nes_netdev_get_ethtool_stats(struct net_device *netdev,
nesvnic->endnode_ipv4_tcp_retransmits += u32temp;
}
- target_stat_values[4] = nesvnic->nesdev->mac_pause_frames_received;
- target_stat_values[5] = nesdev->nesadapter->nic_rx_eth_route_err;
- target_stat_values[6] = nesvnic->tx_sw_dropped;
- target_stat_values[7] = nesvnic->sq_locked;
- target_stat_values[8] = nesvnic->sq_full;
- target_stat_values[9] = nesvnic->segmented_tso_requests;
- target_stat_values[10] = nesvnic->nesdev->mac_rx_symbol_err_frames;
- target_stat_values[11] = nesvnic->nesdev->mac_rx_jabber_frames;
- target_stat_values[12] = nesvnic->nesdev->mac_rx_oversized_frames;
- target_stat_values[13] = nesvnic->nesdev->mac_rx_short_frames;
- target_stat_values[14] = nesvnic->endnode_nstat_rx_discard;
- target_stat_values[15] = nesvnic->endnode_nstat_rx_octets;
- target_stat_values[16] = nesvnic->endnode_nstat_rx_frames;
- target_stat_values[17] = nesvnic->endnode_nstat_tx_octets;
- target_stat_values[18] = nesvnic->endnode_nstat_tx_frames;
- target_stat_values[19] = mh_detected;
- target_stat_values[20] = mh_pauses_sent;
- target_stat_values[21] = nesvnic->endnode_ipv4_tcp_retransmits;
- target_stat_values[22] = atomic_read(&cm_connects);
- target_stat_values[23] = atomic_read(&cm_accepts);
- target_stat_values[24] = atomic_read(&cm_disconnects);
- target_stat_values[25] = atomic_read(&cm_connecteds);
- target_stat_values[26] = atomic_read(&cm_connect_reqs);
- target_stat_values[27] = atomic_read(&cm_rejects);
- target_stat_values[28] = atomic_read(&mod_qp_timouts);
- target_stat_values[29] = atomic_read(&qps_created);
- target_stat_values[30] = atomic_read(&sw_qps_destroyed);
- target_stat_values[31] = atomic_read(&qps_destroyed);
- target_stat_values[32] = atomic_read(&cm_closes);
- target_stat_values[33] = cm_packets_sent;
- target_stat_values[34] = cm_packets_bounced;
- target_stat_values[35] = cm_packets_created;
- target_stat_values[36] = cm_packets_received;
- target_stat_values[37] = cm_packets_dropped;
- target_stat_values[38] = cm_packets_retrans;
- target_stat_values[39] = cm_listens_created;
- target_stat_values[40] = cm_listens_destroyed;
- target_stat_values[41] = cm_backlog_drops;
- target_stat_values[42] = atomic_read(&cm_loopbacks);
- target_stat_values[43] = atomic_read(&cm_nodes_created);
- target_stat_values[44] = atomic_read(&cm_nodes_destroyed);
- target_stat_values[45] = atomic_read(&cm_accel_dropped_pkts);
- target_stat_values[46] = atomic_read(&cm_resets_recvd);
- target_stat_values[47] = int_mod_timer_init;
- target_stat_values[48] = int_mod_cq_depth_1;
- target_stat_values[49] = int_mod_cq_depth_4;
- target_stat_values[50] = int_mod_cq_depth_16;
- target_stat_values[51] = int_mod_cq_depth_24;
- target_stat_values[52] = int_mod_cq_depth_32;
- target_stat_values[53] = int_mod_cq_depth_128;
- target_stat_values[54] = int_mod_cq_depth_256;
- target_stat_values[55] = nesvnic->lro_mgr.stats.aggregated;
- target_stat_values[56] = nesvnic->lro_mgr.stats.flushed;
- target_stat_values[57] = nesvnic->lro_mgr.stats.no_desc;
+ target_stat_values[++index] = nesvnic->nesdev->mac_pause_frames_received;
+ target_stat_values[++index] = nesdev->nesadapter->nic_rx_eth_route_err;
+ target_stat_values[++index] = nesvnic->tx_sw_dropped;
+ target_stat_values[++index] = nesvnic->sq_full;
+ target_stat_values[++index] = nesvnic->segmented_tso_requests;
+ target_stat_values[++index] = nesvnic->nesdev->mac_rx_symbol_err_frames;
+ target_stat_values[++index] = nesvnic->nesdev->mac_rx_jabber_frames;
+ target_stat_values[++index] = nesvnic->nesdev->mac_rx_oversized_frames;
+ target_stat_values[++index] = nesvnic->nesdev->mac_rx_short_frames;
+ target_stat_values[++index] = nesvnic->endnode_nstat_rx_discard;
+ target_stat_values[++index] = nesvnic->endnode_nstat_rx_octets;
+ target_stat_values[++index] = nesvnic->endnode_nstat_rx_frames;
+ target_stat_values[++index] = nesvnic->endnode_nstat_tx_octets;
+ target_stat_values[++index] = nesvnic->endnode_nstat_tx_frames;
+ target_stat_values[++index] = mh_detected;
+ target_stat_values[++index] = mh_pauses_sent;
+ target_stat_values[++index] = nesvnic->endnode_ipv4_tcp_retransmits;
+ target_stat_values[++index] = atomic_read(&cm_connects);
+ target_stat_values[++index] = atomic_read(&cm_accepts);
+ target_stat_values[++index] = atomic_read(&cm_disconnects);
+ target_stat_values[++index] = atomic_read(&cm_connecteds);
+ target_stat_values[++index] = atomic_read(&cm_connect_reqs);
+ target_stat_values[++index] = atomic_read(&cm_rejects);
+ target_stat_values[++index] = atomic_read(&mod_qp_timouts);
+ target_stat_values[++index] = atomic_read(&qps_created);
+ target_stat_values[++index] = atomic_read(&sw_qps_destroyed);
+ target_stat_values[++index] = atomic_read(&qps_destroyed);
+ target_stat_values[++index] = atomic_read(&cm_closes);
+ target_stat_values[++index] = cm_packets_sent;
+ target_stat_values[++index] = cm_packets_bounced;
+ target_stat_values[++index] = cm_packets_created;
+ target_stat_values[++index] = cm_packets_received;
+ target_stat_values[++index] = cm_packets_dropped;
+ target_stat_values[++index] = cm_packets_retrans;
+ target_stat_values[++index] = cm_listens_created;
+ target_stat_values[++index] = cm_listens_destroyed;
+ target_stat_values[++index] = cm_backlog_drops;
+ target_stat_values[++index] = atomic_read(&cm_loopbacks);
+ target_stat_values[++index] = atomic_read(&cm_nodes_created);
+ target_stat_values[++index] = atomic_read(&cm_nodes_destroyed);
+ target_stat_values[++index] = atomic_read(&cm_accel_dropped_pkts);
+ target_stat_values[++index] = atomic_read(&cm_resets_recvd);
+ target_stat_values[++index] = int_mod_timer_init;
+ target_stat_values[++index] = int_mod_cq_depth_1;
+ target_stat_values[++index] = int_mod_cq_depth_4;
+ target_stat_values[++index] = int_mod_cq_depth_16;
+ target_stat_values[++index] = int_mod_cq_depth_24;
+ target_stat_values[++index] = int_mod_cq_depth_32;
+ target_stat_values[++index] = int_mod_cq_depth_128;
+ target_stat_values[++index] = int_mod_cq_depth_256;
+ target_stat_values[++index] = nesvnic->lro_mgr.stats.aggregated;
+ target_stat_values[++index] = nesvnic->lro_mgr.stats.flushed;
+ target_stat_values[++index] = nesvnic->lro_mgr.stats.no_desc;
}
@@ -1568,6 +1551,19 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g
spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
}
+static const struct net_device_ops nes_netdev_ops = {
+ .ndo_open = nes_netdev_open,
+ .ndo_stop = nes_netdev_stop,
+ .ndo_start_xmit = nes_netdev_start_xmit,
+ .ndo_get_stats = nes_netdev_get_stats,
+ .ndo_tx_timeout = nes_netdev_tx_timeout,
+ .ndo_set_mac_address = nes_netdev_set_mac_address,
+ .ndo_set_multicast_list = nes_netdev_set_multicast_list,
+ .ndo_change_mtu = nes_netdev_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_vlan_rx_register = nes_netdev_vlan_rx_register,
+};
/**
* nes_netdev_init - initialize network device
@@ -1576,7 +1572,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
void __iomem *mmio_addr)
{
u64 u64temp;
- struct nes_vnic *nesvnic = NULL;
+ struct nes_vnic *nesvnic;
struct net_device *netdev;
struct nic_qp_map *curr_qp_map;
u32 u32temp;
@@ -1588,22 +1584,12 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
printk(KERN_ERR PFX "nesvnic etherdev alloc failed");
return NULL;
}
+ nesvnic = netdev_priv(netdev);
nes_debug(NES_DBG_INIT, "netdev = %p, %s\n", netdev, netdev->name);
SET_NETDEV_DEV(netdev, &nesdev->pcidev->dev);
- nesvnic = netdev_priv(netdev);
- memset(nesvnic, 0, sizeof(*nesvnic));
-
- netdev->open = nes_netdev_open;
- netdev->stop = nes_netdev_stop;
- netdev->hard_start_xmit = nes_netdev_start_xmit;
- netdev->get_stats = nes_netdev_get_stats;
- netdev->tx_timeout = nes_netdev_tx_timeout;
- netdev->set_mac_address = nes_netdev_set_mac_address;
- netdev->set_multicast_list = nes_netdev_set_multicast_list;
- netdev->change_mtu = nes_netdev_change_mtu;
netdev->watchdog_timeo = NES_TX_TIMEOUT;
netdev->irq = nesdev->pcidev->irq;
netdev->mtu = ETH_DATA_LEN;
@@ -1611,12 +1597,11 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
netdev->addr_len = ETH_ALEN;
netdev->type = ARPHRD_ETHER;
netdev->features = NETIF_F_HIGHDMA;
+ netdev->netdev_ops = &nes_netdev_ops;
netdev->ethtool_ops = &nes_ethtool_ops;
netif_napi_add(netdev, &nesvnic->napi, nes_netdev_poll, 128);
nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n");
netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- netdev->vlan_rx_register = nes_netdev_vlan_rx_register;
- netdev->features |= NETIF_F_LLTX;
/* Fill in the port structure */
nesvnic->netdev = netdev;
diff --git a/drivers/infiniband/hw/nes/nes_user.h b/drivers/infiniband/hw/nes/nes_user.h
index e64306bce80b..cc90c14b49eb 100644
--- a/drivers/infiniband/hw/nes/nes_user.h
+++ b/drivers/infiniband/hw/nes/nes_user.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
* Copyright (c) 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Cisco Systems. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c
index 6f3bc1b6bf22..a282031d15c7 100644
--- a/drivers/infiniband/hw/nes/nes_utils.c
+++ b/drivers/infiniband/hw/nes/nes_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index d93a6562817c..7e5b5ba13a74 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -551,6 +551,7 @@ static int nes_dealloc_fmr(struct ib_fmr *ibfmr)
struct nes_device *nesdev = nesvnic->nesdev;
struct nes_adapter *nesadapter = nesdev->nesadapter;
int i = 0;
+ int rc;
/* free the resources */
if (nesfmr->leaf_pbl_cnt == 0) {
@@ -572,7 +573,9 @@ static int nes_dealloc_fmr(struct ib_fmr *ibfmr)
nesmr->ibmw.rkey = ibfmr->rkey;
nesmr->ibmw.uobject = NULL;
- if (nesfmr->nesmr.pbls_used != 0) {
+ rc = nes_dealloc_mw(&nesmr->ibmw);
+
+ if ((rc == 0) && (nesfmr->nesmr.pbls_used != 0)) {
spin_lock_irqsave(&nesadapter->pbl_lock, flags);
if (nesfmr->nesmr.pbl_4k) {
nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used;
@@ -584,7 +587,7 @@ static int nes_dealloc_fmr(struct ib_fmr *ibfmr)
spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
}
- return nes_dealloc_mw(&nesmr->ibmw);
+ return rc;
}
@@ -1886,21 +1889,75 @@ static int nes_destroy_cq(struct ib_cq *ib_cq)
return ret;
}
+/**
+ * root_256
+ */
+static u32 root_256(struct nes_device *nesdev,
+ struct nes_root_vpbl *root_vpbl,
+ struct nes_root_vpbl *new_root,
+ u16 pbl_count_4k,
+ u16 pbl_count_256)
+{
+ u64 leaf_pbl;
+ int i, j, k;
+
+ if (pbl_count_4k == 1) {
+ new_root->pbl_vbase = pci_alloc_consistent(nesdev->pcidev,
+ 512, &new_root->pbl_pbase);
+
+ if (new_root->pbl_vbase == NULL)
+ return 0;
+
+ leaf_pbl = (u64)root_vpbl->pbl_pbase;
+ for (i = 0; i < 16; i++) {
+ new_root->pbl_vbase[i].pa_low =
+ cpu_to_le32((u32)leaf_pbl);
+ new_root->pbl_vbase[i].pa_high =
+ cpu_to_le32((u32)((((u64)leaf_pbl) >> 32)));
+ leaf_pbl += 256;
+ }
+ } else {
+ for (i = 3; i >= 0; i--) {
+ j = i * 16;
+ root_vpbl->pbl_vbase[j] = root_vpbl->pbl_vbase[i];
+ leaf_pbl = le32_to_cpu(root_vpbl->pbl_vbase[j].pa_low) +
+ (((u64)le32_to_cpu(root_vpbl->pbl_vbase[j].pa_high))
+ << 32);
+ for (k = 1; k < 16; k++) {
+ leaf_pbl += 256;
+ root_vpbl->pbl_vbase[j + k].pa_low =
+ cpu_to_le32((u32)leaf_pbl);
+ root_vpbl->pbl_vbase[j + k].pa_high =
+ cpu_to_le32((u32)((((u64)leaf_pbl) >> 32)));
+ }
+ }
+ }
+
+ return 1;
+}
+
/**
* nes_reg_mr
*/
static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
u32 stag, u64 region_length, struct nes_root_vpbl *root_vpbl,
- dma_addr_t single_buffer, u16 pbl_count, u16 residual_page_count,
- int acc, u64 *iova_start)
+ dma_addr_t single_buffer, u16 pbl_count_4k,
+ u16 residual_page_count_4k, int acc, u64 *iova_start,
+ u16 *actual_pbl_cnt, u8 *used_4k_pbls)
{
struct nes_hw_cqp_wqe *cqp_wqe;
struct nes_cqp_request *cqp_request;
unsigned long flags;
int ret;
struct nes_adapter *nesadapter = nesdev->nesadapter;
- /* int count; */
+ uint pg_cnt = 0;
+ u16 pbl_count_256;
+ u16 pbl_count = 0;
+ u8 use_256_pbls = 0;
+ u8 use_4k_pbls = 0;
+ u16 use_two_level = (pbl_count_4k > 1) ? 1 : 0;
+ struct nes_root_vpbl new_root = {0, 0, 0};
u32 opcode = 0;
u16 major_code;
@@ -1913,41 +1970,70 @@ static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
cqp_request->waiting = 1;
cqp_wqe = &cqp_request->cqp_wqe;
- spin_lock_irqsave(&nesadapter->pbl_lock, flags);
- /* track PBL resources */
- if (pbl_count != 0) {
- if (pbl_count > 1) {
- /* Two level PBL */
- if ((pbl_count+1) > nesadapter->free_4kpbl) {
- nes_debug(NES_DBG_MR, "Out of 4KB Pbls for two level request.\n");
- spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
- nes_free_cqp_request(nesdev, cqp_request);
- return -ENOMEM;
- } else {
- nesadapter->free_4kpbl -= pbl_count+1;
- }
- } else if (residual_page_count > 32) {
- if (pbl_count > nesadapter->free_4kpbl) {
- nes_debug(NES_DBG_MR, "Out of 4KB Pbls.\n");
- spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
- nes_free_cqp_request(nesdev, cqp_request);
- return -ENOMEM;
- } else {
- nesadapter->free_4kpbl -= pbl_count;
+ if (pbl_count_4k) {
+ spin_lock_irqsave(&nesadapter->pbl_lock, flags);
+
+ pg_cnt = ((pbl_count_4k - 1) * 512) + residual_page_count_4k;
+ pbl_count_256 = (pg_cnt + 31) / 32;
+ if (pg_cnt <= 32) {
+ if (pbl_count_256 <= nesadapter->free_256pbl)
+ use_256_pbls = 1;
+ else if (pbl_count_4k <= nesadapter->free_4kpbl)
+ use_4k_pbls = 1;
+ } else if (pg_cnt <= 2048) {
+ if (((pbl_count_4k + use_two_level) <= nesadapter->free_4kpbl) &&
+ (nesadapter->free_4kpbl > (nesadapter->max_4kpbl >> 1))) {
+ use_4k_pbls = 1;
+ } else if ((pbl_count_256 + 1) <= nesadapter->free_256pbl) {
+ use_256_pbls = 1;
+ use_two_level = 1;
+ } else if ((pbl_count_4k + use_two_level) <= nesadapter->free_4kpbl) {
+ use_4k_pbls = 1;
}
} else {
- if (pbl_count > nesadapter->free_256pbl) {
- nes_debug(NES_DBG_MR, "Out of 256B Pbls.\n");
- spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
- nes_free_cqp_request(nesdev, cqp_request);
- return -ENOMEM;
- } else {
- nesadapter->free_256pbl -= pbl_count;
- }
+ if ((pbl_count_4k + 1) <= nesadapter->free_4kpbl)
+ use_4k_pbls = 1;
}
+
+ if (use_256_pbls) {
+ pbl_count = pbl_count_256;
+ nesadapter->free_256pbl -= pbl_count + use_two_level;
+ } else if (use_4k_pbls) {
+ pbl_count = pbl_count_4k;
+ nesadapter->free_4kpbl -= pbl_count + use_two_level;
+ } else {
+ spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+ nes_debug(NES_DBG_MR, "Out of Pbls\n");
+ nes_free_cqp_request(nesdev, cqp_request);
+ return -ENOMEM;
+ }
+
+ spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
}
- spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+ if (use_256_pbls && use_two_level) {
+ if (root_256(nesdev, root_vpbl, &new_root, pbl_count_4k, pbl_count_256) == 1) {
+ if (new_root.pbl_pbase != 0)
+ root_vpbl = &new_root;
+ } else {
+ spin_lock_irqsave(&nesadapter->pbl_lock, flags);
+ nesadapter->free_256pbl += pbl_count_256 + use_two_level;
+ use_256_pbls = 0;
+
+ if (pbl_count_4k == 1)
+ use_two_level = 0;
+ pbl_count = pbl_count_4k;
+
+ if ((pbl_count_4k + use_two_level) <= nesadapter->free_4kpbl) {
+ nesadapter->free_4kpbl -= pbl_count + use_two_level;
+ use_4k_pbls = 1;
+ }
+ spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+
+ if (use_4k_pbls == 0)
+ return -ENOMEM;
+ }
+ }
opcode = NES_CQP_REGISTER_STAG | NES_CQP_STAG_RIGHTS_LOCAL_READ |
NES_CQP_STAG_VA_TO | NES_CQP_STAG_MR;
@@ -1976,10 +2062,9 @@ static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
} else {
set_wqe_64bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PA_LOW_IDX, root_vpbl->pbl_pbase);
set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_BLK_COUNT_IDX, pbl_count);
- set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_LEN_IDX,
- (((pbl_count - 1) * 4096) + (residual_page_count*8)));
+ set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_STAG_WQE_PBL_LEN_IDX, (pg_cnt * 8));
- if ((pbl_count > 1) || (residual_page_count > 32))
+ if (use_4k_pbls)
cqp_wqe->wqe_words[NES_CQP_WQE_OPCODE_IDX] |= cpu_to_le32(NES_CQP_STAG_PBL_BLK_SIZE);
}
barrier();
@@ -1996,13 +2081,25 @@ static int nes_reg_mr(struct nes_device *nesdev, struct nes_pd *nespd,
major_code = cqp_request->major_code;
nes_put_cqp_request(nesdev, cqp_request);
+ if ((!ret || major_code) && pbl_count != 0) {
+ spin_lock_irqsave(&nesadapter->pbl_lock, flags);
+ if (use_256_pbls)
+ nesadapter->free_256pbl += pbl_count + use_two_level;
+ else if (use_4k_pbls)
+ nesadapter->free_4kpbl += pbl_count + use_two_level;
+ spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+ }
+ if (new_root.pbl_pbase)
+ pci_free_consistent(nesdev->pcidev, 512, new_root.pbl_vbase,
+ new_root.pbl_pbase);
+
if (!ret)
return -ETIME;
else if (major_code)
return -EIO;
- else
- return 0;
+ *actual_pbl_cnt = pbl_count + use_two_level;
+ *used_4k_pbls = use_4k_pbls;
return 0;
}
@@ -2167,18 +2264,14 @@ static struct ib_mr *nes_reg_phys_mr(struct ib_pd *ib_pd,
pbl_count = root_pbl_index;
}
ret = nes_reg_mr(nesdev, nespd, stag, region_length, &root_vpbl,
- buffer_list[0].addr, pbl_count, (u16)cur_pbl_index, acc, iova_start);
+ buffer_list[0].addr, pbl_count, (u16)cur_pbl_index, acc, iova_start,
+ &nesmr->pbls_used, &nesmr->pbl_4k);
if (ret == 0) {
nesmr->ibmr.rkey = stag;
nesmr->ibmr.lkey = stag;
nesmr->mode = IWNES_MEMREG_TYPE_MEM;
ibmr = &nesmr->ibmr;
- nesmr->pbl_4k = ((pbl_count > 1) || (cur_pbl_index > 32)) ? 1 : 0;
- nesmr->pbls_used = pbl_count;
- if (pbl_count > 1) {
- nesmr->pbls_used++;
- }
} else {
kfree(nesmr);
ibmr = ERR_PTR(-ENOMEM);
@@ -2456,8 +2549,9 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
stag, (unsigned int)iova_start,
(unsigned int)region_length, stag_index,
(unsigned long long)region->length, pbl_count);
- ret = nes_reg_mr( nesdev, nespd, stag, region->length, &root_vpbl,
- first_dma_addr, pbl_count, (u16)cur_pbl_index, acc, &iova_start);
+ ret = nes_reg_mr(nesdev, nespd, stag, region->length, &root_vpbl,
+ first_dma_addr, pbl_count, (u16)cur_pbl_index, acc,
+ &iova_start, &nesmr->pbls_used, &nesmr->pbl_4k);
nes_debug(NES_DBG_MR, "ret=%d\n", ret);
@@ -2466,11 +2560,6 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
nesmr->ibmr.lkey = stag;
nesmr->mode = IWNES_MEMREG_TYPE_MEM;
ibmr = &nesmr->ibmr;
- nesmr->pbl_4k = ((pbl_count > 1) || (cur_pbl_index > 32)) ? 1 : 0;
- nesmr->pbls_used = pbl_count;
- if (pbl_count > 1) {
- nesmr->pbls_used++;
- }
} else {
ib_umem_release(region);
kfree(nesmr);
@@ -2609,24 +2698,6 @@ static int nes_dereg_mr(struct ib_mr *ib_mr)
cqp_request->waiting = 1;
cqp_wqe = &cqp_request->cqp_wqe;
- spin_lock_irqsave(&nesadapter->pbl_lock, flags);
- if (nesmr->pbls_used != 0) {
- if (nesmr->pbl_4k) {
- nesadapter->free_4kpbl += nesmr->pbls_used;
- if (nesadapter->free_4kpbl > nesadapter->max_4kpbl) {
- printk(KERN_ERR PFX "free 4KB PBLs(%u) has exceeded the max(%u)\n",
- nesadapter->free_4kpbl, nesadapter->max_4kpbl);
- }
- } else {
- nesadapter->free_256pbl += nesmr->pbls_used;
- if (nesadapter->free_256pbl > nesadapter->max_256pbl) {
- printk(KERN_ERR PFX "free 256B PBLs(%u) has exceeded the max(%u)\n",
- nesadapter->free_256pbl, nesadapter->max_256pbl);
- }
- }
- }
-
- spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
nes_fill_init_cqp_wqe(cqp_wqe, nesdev);
set_wqe_32bit_value(cqp_wqe->wqe_words, NES_CQP_WQE_OPCODE_IDX,
NES_CQP_DEALLOCATE_STAG | NES_CQP_STAG_VA_TO |
@@ -2644,11 +2715,6 @@ static int nes_dereg_mr(struct ib_mr *ib_mr)
" CQP Major:Minor codes = 0x%04X:0x%04X\n",
ib_mr->rkey, ret, cqp_request->major_code, cqp_request->minor_code);
- nes_free_resource(nesadapter, nesadapter->allocated_mrs,
- (ib_mr->rkey & 0x0fffff00) >> 8);
-
- kfree(nesmr);
-
major_code = cqp_request->major_code;
minor_code = cqp_request->minor_code;
@@ -2664,8 +2730,33 @@ static int nes_dereg_mr(struct ib_mr *ib_mr)
" to destroy STag, ib_mr=%p, rkey = 0x%08X\n",
major_code, minor_code, ib_mr, ib_mr->rkey);
return -EIO;
- } else
- return 0;
+ }
+
+ if (nesmr->pbls_used != 0) {
+ spin_lock_irqsave(&nesadapter->pbl_lock, flags);
+ if (nesmr->pbl_4k) {
+ nesadapter->free_4kpbl += nesmr->pbls_used;
+ if (nesadapter->free_4kpbl > nesadapter->max_4kpbl)
+ printk(KERN_ERR PFX "free 4KB PBLs(%u) has "
+ "exceeded the max(%u)\n",
+ nesadapter->free_4kpbl,
+ nesadapter->max_4kpbl);
+ } else {
+ nesadapter->free_256pbl += nesmr->pbls_used;
+ if (nesadapter->free_256pbl > nesadapter->max_256pbl)
+ printk(KERN_ERR PFX "free 256B PBLs(%u) has "
+ "exceeded the max(%u)\n",
+ nesadapter->free_256pbl,
+ nesadapter->max_256pbl);
+ }
+ spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);
+ }
+ nes_free_resource(nesadapter, nesadapter->allocated_mrs,
+ (ib_mr->rkey & 0x0fffff00) >> 8);
+
+ kfree(nesmr);
+
+ return 0;
}
diff --git a/drivers/infiniband/hw/nes/nes_verbs.h b/drivers/infiniband/hw/nes/nes_verbs.h
index ae0ca9bc83bd..5e48f67fbe8d 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.h
+++ b/drivers/infiniband/hw/nes/nes_verbs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006 - 2008 NetEffect, Inc. All rights reserved.
+ * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved.
* Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index a1925810be3c..da6082739839 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -446,11 +446,11 @@ poll_more:
if (dev->features & NETIF_F_LRO)
lro_flush_all(&priv->lro.lro_mgr);
- netif_rx_complete(napi);
+ napi_complete(napi);
if (unlikely(ib_req_notify_cq(priv->recv_cq,
IB_CQ_NEXT_COMP |
IB_CQ_REPORT_MISSED_EVENTS)) &&
- netif_rx_reschedule(napi))
+ napi_reschedule(napi))
goto poll_more;
}
@@ -462,7 +462,7 @@ void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
struct net_device *dev = dev_ptr;
struct ipoib_dev_priv *priv = netdev_priv(dev);
- netif_rx_schedule(&priv->napi);
+ napi_schedule(&priv->napi);
}
static void drain_tx_cq(struct net_device *dev)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 0bd2a4ff0842..421a6640c9bd 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -660,8 +660,12 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
path = __path_find(dev, phdr->hwaddr + 4);
if (!path || !path->valid) {
- if (!path)
+ int new_path = 0;
+
+ if (!path) {
path = path_rec_create(dev, phdr->hwaddr + 4);
+ new_path = 1;
+ }
if (path) {
/* put pseudoheader back on for next time */
skb_push(skb, sizeof *phdr);
@@ -669,7 +673,8 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
if (!path->query && path_rec_start(dev, path)) {
spin_unlock_irqrestore(&priv->lock, flags);
- path_free(dev, path);
+ if (new_path)
+ path_free(dev, path);
return;
} else
__path_add(dev, path);
@@ -1016,18 +1021,22 @@ static void ipoib_lro_setup(struct ipoib_dev_priv *priv)
priv->lro.lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
}
+static const struct net_device_ops ipoib_netdev_ops = {
+ .ndo_open = ipoib_open,
+ .ndo_stop = ipoib_stop,
+ .ndo_change_mtu = ipoib_change_mtu,
+ .ndo_start_xmit = ipoib_start_xmit,
+ .ndo_tx_timeout = ipoib_timeout,
+ .ndo_set_multicast_list = ipoib_set_mcast_list,
+ .ndo_neigh_setup = ipoib_neigh_setup_dev,
+};
+
static void ipoib_setup(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
- dev->open = ipoib_open;
- dev->stop = ipoib_stop;
- dev->change_mtu = ipoib_change_mtu;
- dev->hard_start_xmit = ipoib_start_xmit;
- dev->tx_timeout = ipoib_timeout;
+ dev->netdev_ops = &ipoib_netdev_ops;
dev->header_ops = &ipoib_header_ops;
- dev->set_multicast_list = ipoib_set_mcast_list;
- dev->neigh_setup = ipoib_neigh_setup_dev;
ipoib_set_ethtool_ops(dev);
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 12876392516e..13d7674b293d 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -168,7 +168,7 @@ iscsi_iser_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task)
{
int error = 0;
- debug_scsi("task deq [cid %d itt 0x%x]\n", conn->id, task->itt);
+ iser_dbg("task deq [cid %d itt 0x%x]\n", conn->id, task->itt);
error = iser_send_control(conn, task);
@@ -195,7 +195,7 @@ iscsi_iser_task_xmit_unsol_data(struct iscsi_conn *conn,
/* Send data-out PDUs while there's still unsolicited data to send */
while (iscsi_task_has_unsol_data(task)) {
iscsi_prep_data_out_pdu(task, r2t, &hdr);
- debug_scsi("Sending data-out: itt 0x%x, data count %d\n",
+ iser_dbg("Sending data-out: itt 0x%x, data count %d\n",
hdr.itt, r2t->data_count);
/* the buffer description has been passed with the command */
@@ -206,7 +206,7 @@ iscsi_iser_task_xmit_unsol_data(struct iscsi_conn *conn,
goto iscsi_iser_task_xmit_unsol_data_exit;
}
r2t->sent += r2t->data_count;
- debug_scsi("Need to send %d more as data-out PDUs\n",
+ iser_dbg("Need to send %d more as data-out PDUs\n",
r2t->data_length - r2t->sent);
}
@@ -227,12 +227,12 @@ iscsi_iser_task_xmit(struct iscsi_task *task)
if (task->sc->sc_data_direction == DMA_TO_DEVICE) {
BUG_ON(scsi_bufflen(task->sc) == 0);
- debug_scsi("cmd [itt %x total %d imm %d unsol_data %d\n",
+ iser_dbg("cmd [itt %x total %d imm %d unsol_data %d\n",
task->itt, scsi_bufflen(task->sc),
task->imm_count, task->unsol_r2t.data_length);
}
- debug_scsi("task deq [cid %d itt 0x%x]\n",
+ iser_dbg("task deq [cid %d itt 0x%x]\n",
conn->id, task->itt);
/* Send the cmd PDU */
@@ -397,14 +397,14 @@ static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
static struct iscsi_cls_session *
iscsi_iser_session_create(struct iscsi_endpoint *ep,
uint16_t cmds_max, uint16_t qdepth,
- uint32_t initial_cmdsn, uint32_t *hostno)
+ uint32_t initial_cmdsn)
{
struct iscsi_cls_session *cls_session;
struct iscsi_session *session;
struct Scsi_Host *shost;
struct iser_conn *ib_conn;
- shost = iscsi_host_alloc(&iscsi_iser_sht, 0, ISCSI_MAX_CMD_PER_LUN);
+ shost = iscsi_host_alloc(&iscsi_iser_sht, 0, 1);
if (!shost)
return NULL;
shost->transportt = iscsi_iser_scsi_transport;
@@ -423,7 +423,6 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
if (iscsi_host_add(shost,
ep ? ib_conn->device->ib_device->dma_device : NULL))
goto free_host;
- *hostno = shost->host_no;
/*
* we do not support setting can_queue cmd_per_lun from userspace yet
@@ -596,7 +595,7 @@ static struct scsi_host_template iscsi_iser_sht = {
.change_queue_depth = iscsi_change_queue_depth,
.sg_tablesize = ISCSI_ISER_SG_TABLESIZE,
.max_sectors = 1024,
- .cmd_per_lun = ISCSI_MAX_CMD_PER_LUN,
+ .cmd_per_lun = ISER_DEF_CMD_PER_LUN,
.eh_abort_handler = iscsi_eh_abort,
.eh_device_reset_handler= iscsi_eh_device_reset,
.eh_target_reset_handler= iscsi_eh_target_reset,
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index 861119593f2b..9d529cae1f0d 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -93,7 +93,7 @@
/* support upto 512KB in one RDMA */
#define ISCSI_ISER_SG_TABLESIZE (0x80000 >> SHIFT_4K)
-#define ISCSI_ISER_MAX_LUN 256
+#define ISER_DEF_CMD_PER_LUN 128
/* QP settings */
/* Maximal bounds on received asynchronous PDUs */
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index e209cb8dd948..9de640200ad3 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -661,7 +661,7 @@ void iser_snd_completion(struct iser_desc *tx_desc)
if (resume_tx) {
iser_dbg("%ld resuming tx\n",jiffies);
- scsi_queue_work(conn->session->host, &conn->xmitwork);
+ iscsi_conn_queue_work(conn);
}
if (tx_desc->type == ISCSI_TX_CONTROL) {
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 319b188145be..ea9e1556e0d6 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -401,13 +401,6 @@ static void iser_route_handler(struct rdma_cm_id *cma_id)
if (ret)
goto failure;
- iser_dbg("path.mtu is %d setting it to %d\n",
- cma_id->route.path_rec->mtu, IB_MTU_1024);
-
- /* we must set the MTU to 1024 as this is what the target is assuming */
- if (cma_id->route.path_rec->mtu > IB_MTU_1024)
- cma_id->route.path_rec->mtu = IB_MTU_1024;
-
memset(&conn_param, 0, sizeof conn_param);
conn_param.responder_resources = 4;
conn_param.initiator_depth = 1;
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 5f9d860925a1..cd50c00ab20f 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -143,7 +143,7 @@ config INPUT_APMPOWER
---help---
Say Y here if you want suspend key events to trigger a user
requested suspend through APM. This is useful on embedded
- systems where such behviour is desired without userspace
+ systems where such behaviour is desired without userspace
interaction. If unsure, say N.
To compile this driver as a module, choose M here: the
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index ed8baa0aec3c..7a7a026ba712 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -94,11 +94,8 @@ static void evdev_event(struct input_handle *handle,
static int evdev_fasync(int fd, struct file *file, int on)
{
struct evdev_client *client = file->private_data;
- int retval;
-
- retval = fasync_helper(fd, file, on, &client->fasync);
- return retval < 0 ? retval : 0;
+ return fasync_helper(fd, file, on, &client->fasync);
}
static int evdev_flush(struct file *file, fl_owner_t id)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 1730d7331a5d..ec3db3ade118 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -903,8 +903,6 @@ static int __init input_proc_init(void)
if (!proc_bus_input_dir)
return -ENOMEM;
- proc_bus_input_dir->owner = THIS_MODULE;
-
entry = proc_create("devices", 0, proc_bus_input_dir,
&input_devices_fileops);
if (!entry)
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 6f2366220a50..4224f0112849 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -159,12 +159,9 @@ static void joydev_event(struct input_handle *handle,
static int joydev_fasync(int fd, struct file *file, int on)
{
- int retval;
struct joydev_client *client = file->private_data;
- retval = fasync_helper(fd, file, on, &client->fasync);
-
- return retval < 0 ? retval : 0;
+ return fasync_helper(fd, file, on, &client->fasync);
}
static void joydev_free(struct device *dev)
diff --git a/drivers/input/joystick/maplecontrol.c b/drivers/input/joystick/maplecontrol.c
index e50047bfe938..77cfde571bd9 100644
--- a/drivers/input/joystick/maplecontrol.c
+++ b/drivers/input/joystick/maplecontrol.c
@@ -3,7 +3,7 @@
* Based on drivers/usb/iforce.c
*
* Copyright Yaegashi Takeshi, 2001
- * Adrian McMenamin, 2008
+ * Adrian McMenamin, 2008 - 2009
*/
#include <linux/kernel.h>
@@ -29,7 +29,7 @@ static void dc_pad_callback(struct mapleq *mq)
struct maple_device *mapledev = mq->dev;
struct dc_pad *pad = maple_get_drvdata(mapledev);
struct input_dev *dev = pad->dev;
- unsigned char *res = mq->recvbuf;
+ unsigned char *res = mq->recvbuf->buf;
buttons = ~le16_to_cpup((__le16 *)(res + 8));
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index abb04c82c622..634af6a8e6b3 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -21,8 +21,6 @@
#include <linux/slab.h>
#include <mach/corgi.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-gpio.h>
#include <asm/hardware/scoop.h>
diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c
index 22f17a593be7..5aa2361aef95 100644
--- a/drivers/input/keyboard/maple_keyb.c
+++ b/drivers/input/keyboard/maple_keyb.c
@@ -1,8 +1,8 @@
/*
* SEGA Dreamcast keyboard driver
* Based on drivers/usb/usbkbd.c
- * Copyright YAEGASHI Takeshi, 2001
- * Porting to 2.6 Copyright Adrian McMenamin, 2007, 2008
+ * Copyright (c) YAEGASHI Takeshi, 2001
+ * Porting to 2.6 Copyright (c) Adrian McMenamin, 2007 - 2009
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@ static DEFINE_MUTEX(maple_keyb_mutex);
#define NR_SCANCODES 256
-MODULE_AUTHOR("YAEGASHI Takeshi, Adrian McMenamin");
+MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk");
MODULE_DESCRIPTION("SEGA Dreamcast keyboard driver");
MODULE_LICENSE("GPL");
@@ -115,7 +115,7 @@ static void dc_scan_kbd(struct dc_kbd *kbd)
input_event(dev, EV_MSC, MSC_SCAN, code);
input_report_key(dev, keycode, 0);
} else
- printk(KERN_DEBUG "maple_keyb: "
+ dev_dbg(&dev->dev,
"Unknown key (scancode %#x) released.",
code);
}
@@ -127,7 +127,7 @@ static void dc_scan_kbd(struct dc_kbd *kbd)
input_event(dev, EV_MSC, MSC_SCAN, code);
input_report_key(dev, keycode, 1);
} else
- printk(KERN_DEBUG "maple_keyb: "
+ dev_dbg(&dev->dev,
"Unknown key (scancode %#x) pressed.",
code);
}
@@ -140,7 +140,7 @@ static void dc_kbd_callback(struct mapleq *mq)
{
struct maple_device *mapledev = mq->dev;
struct dc_kbd *kbd = maple_get_drvdata(mapledev);
- unsigned long *buf = mq->recvbuf;
+ unsigned long *buf = (unsigned long *)(mq->recvbuf->buf);
/*
* We should always get the lock because the only
@@ -159,22 +159,27 @@ static void dc_kbd_callback(struct mapleq *mq)
static int probe_maple_kbd(struct device *dev)
{
- struct maple_device *mdev = to_maple_dev(dev);
- struct maple_driver *mdrv = to_maple_driver(dev->driver);
+ struct maple_device *mdev;
+ struct maple_driver *mdrv;
int i, error;
struct dc_kbd *kbd;
struct input_dev *idev;
- if (!(mdev->function & MAPLE_FUNC_KEYBOARD))
- return -EINVAL;
+ mdev = to_maple_dev(dev);
+ mdrv = to_maple_driver(dev->driver);
kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL);
- idev = input_allocate_device();
- if (!kbd || !idev) {
+ if (!kbd) {
error = -ENOMEM;
goto fail;
}
+ idev = input_allocate_device();
+ if (!idev) {
+ error = -ENOMEM;
+ goto fail_idev_alloc;
+ }
+
kbd->dev = idev;
memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode));
@@ -195,7 +200,7 @@ static int probe_maple_kbd(struct device *dev)
error = input_register_device(idev);
if (error)
- goto fail;
+ goto fail_register;
/* Maple polling is locked to VBLANK - which may be just 50/s */
maple_getcond_callback(mdev, dc_kbd_callback, HZ/50,
@@ -207,10 +212,12 @@ static int probe_maple_kbd(struct device *dev)
return error;
-fail:
+fail_register:
+ maple_set_drvdata(mdev, NULL);
input_free_device(idev);
+fail_idev_alloc:
kfree(kbd);
- maple_set_drvdata(mdev, NULL);
+fail:
return error;
}
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index 5c8a1bcf7ca7..cea70e6a1031 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -219,6 +219,8 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
pdata->scan_timing, priv->iomem_base + KYCR1_OFFS);
iowrite16(0, priv->iomem_base + KYOUTDR_OFFS);
iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS);
+
+ device_init_wakeup(&pdev->dev, 1);
return 0;
err5:
free_irq(irq, pdev);
@@ -253,17 +255,48 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev)
return 0;
}
+static int sh_keysc_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
+ int irq = platform_get_irq(pdev, 0);
+ unsigned short value;
+
+ value = ioread16(priv->iomem_base + KYCR1_OFFS);
+
+ if (device_may_wakeup(dev)) {
+ value |= 0x80;
+ enable_irq_wake(irq);
+ }
+ else
+ value &= ~0x80;
+
+ iowrite16(value, priv->iomem_base + KYCR1_OFFS);
+ return 0;
+}
+
+static int sh_keysc_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ int irq = platform_get_irq(pdev, 0);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(irq);
-#define sh_keysc_suspend NULL
-#define sh_keysc_resume NULL
+ return 0;
+}
+
+static struct dev_pm_ops sh_keysc_dev_pm_ops = {
+ .suspend = sh_keysc_suspend,
+ .resume = sh_keysc_resume,
+};
struct platform_driver sh_keysc_device_driver = {
.probe = sh_keysc_probe,
.remove = __devexit_p(sh_keysc_remove),
- .suspend = sh_keysc_suspend,
- .resume = sh_keysc_resume,
.driver = {
.name = "sh_keysc",
+ .pm = &sh_keysc_dev_pm_ops,
}
};
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index 9d1781a618e9..13967422658c 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -21,8 +21,6 @@
#include <linux/slab.h>
#include <mach/spitz.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-gpio.h>
#define KB_ROWS 7
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c
index 0db8d16c5edd..5e5eb88d8d1e 100644
--- a/drivers/input/mouse/gpio_mouse.c
+++ b/drivers/input/mouse/gpio_mouse.c
@@ -18,7 +18,7 @@
/*
* Timer function which is run every scan_ms ms when the device is opened.
- * The dev input varaible is set to the the input_dev pointer.
+ * The dev input variable is set to the the input_dev pointer.
*/
static void gpio_mouse_scan(struct input_polled_dev *dev)
{
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
index 81e6ebf323e9..55cd0fa68339 100644
--- a/drivers/input/mouse/hgpk.c
+++ b/drivers/input/mouse/hgpk.c
@@ -381,7 +381,7 @@ static void hgpk_disconnect(struct psmouse *psmouse)
static void hgpk_recalib_work(struct work_struct *work)
{
- struct delayed_work *w = container_of(work, struct delayed_work, work);
+ struct delayed_work *w = to_delayed_work(work);
struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);
struct psmouse *psmouse = priv->psmouse;
diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c
index 56c079ef5018..272deddc8db6 100644
--- a/drivers/input/mouse/rpcmouse.c
+++ b/drivers/input/mouse/rpcmouse.c
@@ -22,10 +22,10 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/input.h>
+#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/irq.h>
-#include <asm/io.h>
#include <asm/hardware/iomd.h>
MODULE_AUTHOR("Vojtech Pavlik, Russell King");
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index ef99a7e6d40c..17fd6d46d082 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -403,12 +403,9 @@ static void mousedev_event(struct input_handle *handle,
static int mousedev_fasync(int fd, struct file *file, int on)
{
- int retval;
struct mousedev_client *client = file->private_data;
- retval = fasync_helper(fd, file, on, &client->fasync);
-
- return retval < 0 ? retval : 0;
+ return fasync_helper(fd, file, on, &client->fasync);
}
static void mousedev_free(struct device *dev)
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
index 7f36edd34f8b..ed045c99f84b 100644
--- a/drivers/input/serio/rpckbd.c
+++ b/drivers/input/serio/rpckbd.c
@@ -33,10 +33,10 @@
#include <linux/serio.h>
#include <linux/err.h>
#include <linux/platform_device.h>
+#include <linux/io.h>
#include <asm/irq.h>
#include <mach/hardware.h>
-#include <asm/io.h>
#include <asm/hardware/iomd.h>
#include <asm/system.h>
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 06bbd0e74c6f..b03009bb7468 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -58,10 +58,8 @@ static unsigned int serio_raw_no;
static int serio_raw_fasync(int fd, struct file *file, int on)
{
struct serio_raw_list *list = file->private_data;
- int retval;
- retval = fasync_helper(fd, file, on, &list->fasync);
- return retval < 0 ? retval : 0;
+ return fasync_helper(fd, file, on, &list->fasync);
}
static struct serio_raw *serio_raw_locate(int minor)
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 7c27c8b9b6d0..056ac77e2cf0 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -295,7 +295,7 @@ name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
-/* Sysfs conventions report temperatures in millidegrees Celcius.
+/* Sysfs conventions report temperatures in millidegrees Celsius.
* ADS7846 could use the low-accuracy two-sample scheme, but can't do the high
* accuracy scheme without calibration data. For now we won't try either;
* userspace sees raw sensor values, and must scale/calibrate appropriately.
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index 3fb51b54fe61..94a1919d439d 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -21,7 +21,6 @@
#include <mach/sharpsl.h>
#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-gpio.h>
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c
index 504ca11749a1..141dd584330e 100644
--- a/drivers/input/touchscreen/migor_ts.c
+++ b/drivers/input/touchscreen/migor_ts.c
@@ -198,6 +198,7 @@ static int migor_ts_probe(struct i2c_client *client,
goto err2;
}
+ device_init_wakeup(&client->dev, 1);
return 0;
err2:
@@ -224,6 +225,26 @@ static int migor_ts_remove(struct i2c_client *client)
return 0;
}
+static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
+
+ if (device_may_wakeup(&client->dev))
+ enable_irq_wake(priv->irq);
+
+ return 0;
+}
+
+static int migor_ts_resume(struct i2c_client *client)
+{
+ struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
+
+ if (device_may_wakeup(&client->dev))
+ disable_irq_wake(priv->irq);
+
+ return 0;
+}
+
static const struct i2c_device_id migor_ts_id[] = {
{ "migor_ts", 0 },
{ }
@@ -236,6 +257,8 @@ static struct i2c_driver migor_ts_driver = {
},
.probe = migor_ts_probe,
.remove = migor_ts_remove,
+ .suspend = migor_ts_suspend,
+ .resume = migor_ts_resume,
.id_table = migor_ts_id,
};
diff --git a/drivers/isdn/act2000/act2000_isa.c b/drivers/isdn/act2000/act2000_isa.c
index 1bd8960ead33..fea5b783335d 100644
--- a/drivers/isdn/act2000/act2000_isa.c
+++ b/drivers/isdn/act2000/act2000_isa.c
@@ -257,9 +257,9 @@ act2000_isa_receive(act2000_card *card)
printk(KERN_WARNING
"act2000_isa_receive: Invalid CAPI msg\n");
{
- int i; __u8 *p; __u8 *c; __u8 tmp[30];
- for (i = 0, p = (__u8 *)&card->idat.isa.rcvhdr, c = tmp; i < 8; i++)
- c += sprintf(c, "%02x ", *(p++));
+ int i; __u8 *p; __u8 *t; __u8 tmp[30];
+ for (i = 0, p = (__u8 *)&card->idat.isa.rcvhdr, t = tmp; i < 8; i++)
+ t += sprintf(t, "%02x ", *(p++));
printk(KERN_WARNING "act2000_isa_receive: %s\n", tmp);
}
}
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 1b5bf87c4cf4..2d8352419c0d 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -277,7 +277,7 @@ static void capiminor_free(struct capiminor *mp)
list_del(&mp->list);
write_unlock_irqrestore(&capiminor_list_lock, flags);
- if (mp->ttyskb) kfree_skb(mp->ttyskb);
+ kfree_skb(mp->ttyskb);
mp->ttyskb = NULL;
skb_queue_purge(&mp->inqueue);
skb_queue_purge(&mp->outqueue);
@@ -1331,12 +1331,6 @@ static void capinc_tty_send_xchar(struct tty_struct *tty, char ch)
#endif
}
-static int capinc_tty_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- return 0;
-}
-
static struct tty_driver *capinc_tty_driver;
static const struct tty_operations capinc_ops = {
@@ -1358,7 +1352,6 @@ static const struct tty_operations capinc_ops = {
.flush_buffer = capinc_tty_flush_buffer,
.set_ldisc = capinc_tty_set_ldisc,
.send_xchar = capinc_tty_send_xchar,
- .read_proc = capinc_tty_read_proc,
};
static int capinc_tty_init(void)
diff --git a/drivers/isdn/capi/kcapi_proc.c b/drivers/isdn/capi/kcapi_proc.c
index c29208bd7521..50ed778f63fc 100644
--- a/drivers/isdn/capi/kcapi_proc.c
+++ b/drivers/isdn/capi/kcapi_proc.c
@@ -239,6 +239,7 @@ static const struct file_operations proc_applstats_ops = {
// ---------------------------------------------------------------------------
static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
+ __acquires(&capi_drivers_list_lock)
{
read_lock(&capi_drivers_list_lock);
return seq_list_start(&capi_drivers, *pos);
@@ -250,6 +251,7 @@ static void *capi_driver_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void capi_driver_stop(struct seq_file *seq, void *v)
+ __releases(&capi_drivers_list_lock)
{
read_unlock(&capi_drivers_list_lock);
}
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig
index 0017e50c6948..9ca889adf120 100644
--- a/drivers/isdn/gigaset/Kconfig
+++ b/drivers/isdn/gigaset/Kconfig
@@ -1,5 +1,5 @@
menuconfig ISDN_DRV_GIGASET
- tristate "Siemens Gigaset support (isdn)"
+ tristate "Siemens Gigaset support"
select CRC_CCITT
select BITREVERSE
help
@@ -11,11 +11,11 @@ menuconfig ISDN_DRV_GIGASET
one of the connection specific parts that follow.
This will build a module called "gigaset".
-if ISDN_DRV_GIGASET!=n
+if ISDN_DRV_GIGASET
config GIGASET_BASE
tristate "Gigaset base station support"
- depends on ISDN_DRV_GIGASET && USB
+ depends on USB
help
Say M here if you want to use the USB interface of the Gigaset
base for connection to your system.
@@ -23,7 +23,7 @@ config GIGASET_BASE
config GIGASET_M105
tristate "Gigaset M105 support"
- depends on ISDN_DRV_GIGASET && USB
+ depends on USB
help
Say M here if you want to connect to the Gigaset base via DECT
using a Gigaset M105 (Sinus 45 Data 2) USB DECT device.
@@ -31,7 +31,6 @@ config GIGASET_M105
config GIGASET_M101
tristate "Gigaset M101 support"
- depends on ISDN_DRV_GIGASET
help
Say M here if you want to connect to the Gigaset base via DECT
using a Gigaset M101 (Sinus 45 Data 1) RS232 DECT device.
@@ -48,7 +47,6 @@ config GIGASET_UNDOCREQ
help
This enables support for USB requests we only know from
reverse engineering (currently M105 only). If you need
- features like configuration mode of M105, say yes. If you
- care about your device, say no.
+ features like configuration mode of M105, say yes.
-endif # ISDN_DRV_GIGASET != n
+endif # ISDN_DRV_GIGASET
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 18dd8aacbe8d..831ddce1467b 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -46,6 +46,9 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode");
/* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */
#define IF_WRITEBUF 264
+/* interrupt pipe message size according to ibid. ch. 2.2 */
+#define IP_MSGSIZE 3
+
/* Values for the Gigaset 307x */
#define USB_GIGA_VENDOR_ID 0x0681
#define USB_3070_PRODUCT_ID 0x0001
@@ -110,7 +113,7 @@ struct bas_cardstate {
unsigned char *rcvbuf; /* AT reply receive buffer */
struct urb *urb_int_in; /* URB for interrupt pipe */
- unsigned char int_in_buf[3];
+ unsigned char *int_in_buf;
spinlock_t lock; /* locks all following */
int basstate; /* bitmap (BS_*) */
@@ -657,7 +660,7 @@ static void read_int_callback(struct urb *urb)
}
/* drop incomplete packets even if the missing bytes wouldn't matter */
- if (unlikely(urb->actual_length < 3)) {
+ if (unlikely(urb->actual_length < IP_MSGSIZE)) {
dev_warn(cs->dev, "incomplete interrupt packet (%d bytes)\n",
urb->actual_length);
goto resubmit;
@@ -2127,6 +2130,7 @@ static void gigaset_reinitbcshw(struct bc_state *bcs)
static void gigaset_freecshw(struct cardstate *cs)
{
/* timers, URBs and rcvbuf are disposed of in disconnect */
+ kfree(cs->hw.bas->int_in_buf);
kfree(cs->hw.bas);
cs->hw.bas = NULL;
}
@@ -2140,6 +2144,12 @@ static int gigaset_initcshw(struct cardstate *cs)
pr_err("out of memory\n");
return 0;
}
+ ucs->int_in_buf = kmalloc(IP_MSGSIZE, GFP_KERNEL);
+ if (!ucs->int_in_buf) {
+ kfree(ucs);
+ pr_err("out of memory\n");
+ return 0;
+ }
ucs->urb_cmd_in = NULL;
ucs->urb_cmd_out = NULL;
@@ -2292,7 +2302,7 @@ static int gigaset_probe(struct usb_interface *interface,
usb_fill_int_urb(ucs->urb_int_in, udev,
usb_rcvintpipe(udev,
(endpoint->bEndpointAddress) & 0x0f),
- ucs->int_in_buf, 3, read_int_callback, cs,
+ ucs->int_in_buf, IP_MSGSIZE, read_int_callback, cs,
endpoint->bInterval);
if ((rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL)) != 0) {
dev_err(cs->dev, "could not submit interrupt URB: %s\n",
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index ac245e7e96a5..3071a52467ed 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -389,8 +389,7 @@ static void gigaset_freecshw(struct cardstate *cs)
static void gigaset_device_release(struct device *dev)
{
- struct platform_device *pdev =
- container_of(dev, struct platform_device, dev);
+ struct platform_device *pdev = to_platform_device(dev);
/* adapted from platform_device_release() in drivers/base/platform.c */
//FIXME is this actually necessary?
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index fba61f670527..d78385166099 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -278,17 +278,17 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
unsigned new_state)
{
- return -EINVAL;
+ return -ENOTTY;
}
static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
{
- return -EINVAL;
+ return -ENOTTY;
}
static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
{
- return -EINVAL;
+ return -ENOTTY;
}
#endif
@@ -577,7 +577,7 @@ static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,
0, 0, &buf, 6, 2000);
#else
- return -EINVAL;
+ return -ENOTTY;
#endif
}
diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c
index 84318ec8d13e..33ce89eed65b 100644
--- a/drivers/isdn/hardware/eicon/debug.c
+++ b/drivers/isdn/hardware/eicon/debug.c
@@ -1198,7 +1198,7 @@ int SuperTraceASSIGN (void* AdapterHandle, byte* data) {
pC->xbuffer[5] = (byte)(rx_dma_magic >> 8);
pC->xbuffer[6] = (byte)(rx_dma_magic >> 16);
pC->xbuffer[7] = (byte)(rx_dma_magic >> 24);
- pC->xbuffer[8] = (byte)DIVA_MAX_MANAGEMENT_TRANSFER_SIZE;
+ pC->xbuffer[8] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE & 0xFF);
pC->xbuffer[9] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE >> 8);
pC->xbuffer[10] = 0;
diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c
index f4969fe0a055..69e71ebe7841 100644
--- a/drivers/isdn/hardware/eicon/divasi.c
+++ b/drivers/isdn/hardware/eicon/divasi.c
@@ -118,7 +118,6 @@ static int DIVA_INIT_FUNCTION create_um_idi_proc(void)
return (0);
um_idi_proc_entry->read_proc = um_idi_proc_read;
- um_idi_proc_entry->owner = THIS_MODULE;
return (1);
}
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index 4cc94f200b72..31f91c18c698 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -1194,7 +1194,8 @@ static char hex_digit_table[0x10] =
/* translation function for each message */
/*------------------------------------------------------------------*/
-byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word ch;
word i;
@@ -1411,7 +1412,8 @@ byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return 2;
}
-byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word i, Info;
word Reject;
@@ -1567,13 +1569,15 @@ byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return 1;
}
-byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
dbug(1,dprintf("connect_a_res"));
return false;
}
-byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
word Info;
word i;
@@ -1628,7 +1632,8 @@ byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
return false;
}
-byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
dbug(1,dprintf("disconnect_res"));
if(plci)
@@ -1655,7 +1660,8 @@ byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
return 0;
}
-byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word Info;
byte i;
@@ -1704,7 +1710,8 @@ byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, A
return false;
}
-byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
word i;
API_PARSE * ai;
@@ -1813,13 +1820,15 @@ byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APP
return false;
}
-byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
dbug(1,dprintf("info_res"));
return false;
}
-byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
word Info;
byte ret;
@@ -1849,7 +1858,8 @@ byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, AP
return ret;
}
-byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
word Info = 0;
word i = 0;
@@ -2599,13 +2609,15 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return false;
}
-byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
dbug(1,dprintf("facility_res"));
return false;
}
-byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word Info = 0;
byte req;
@@ -2839,7 +2851,8 @@ byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
return false;
}
-byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word ncci;
API_PARSE * ncpi;
@@ -2954,7 +2967,8 @@ byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
return false;
}
-byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word ncci;
@@ -2974,7 +2988,8 @@ byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * p
return false;
}
-byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word Info;
word ncci;
@@ -3030,7 +3045,8 @@ byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI *
return false;
}
-byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word ncci;
word i;
@@ -3086,7 +3102,8 @@ byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI *
return false;
}
-byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
NCCI *ncci_ptr;
DATA_B3_DESC *data;
@@ -3163,7 +3180,8 @@ byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return false;
}
-byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word n;
word ncci;
@@ -3196,7 +3214,8 @@ byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return false;
}
-byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word Info;
word ncci;
@@ -3237,7 +3256,8 @@ byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return false;
}
-byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word ncci;
@@ -3261,7 +3281,8 @@ byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
return false;
}
-byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
+static byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *parms)
{
word ncci;
API_PARSE * ncpi;
@@ -3295,7 +3316,8 @@ byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI
}
-byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
+static byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
+ PLCI *plci, APPL *appl, API_PARSE *msg)
{
word Info=0;
word i;
@@ -8689,7 +8711,7 @@ static word add_modem_b23 (PLCI * plci, API_PARSE* bp_parms)
/* send a request for the signaling entity */
/*------------------------------------------------------------------*/
-void sig_req(PLCI * plci, byte req, byte Id)
+static void sig_req(PLCI *plci, byte req, byte Id)
{
if(!plci) return;
if(plci->adapter->adapter_disabled) return;
@@ -8789,7 +8811,7 @@ static void send_req(PLCI *plci)
dbug(1,dprintf("send_ok"));
}
-void send_data(PLCI * plci)
+static void send_data(PLCI *plci)
{
DIVA_CAPI_ADAPTER * a;
DATA_B3_DESC * data;
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index f0e14dfcf71d..641a9cd1a532 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -56,8 +56,8 @@ static const char *hfcpci_revision = "2.0";
static int HFC_cnt;
static uint debug;
static uint poll, tics;
-struct timer_list hfc_tl;
-u32 hfc_jiffies;
+static struct timer_list hfc_tl;
+static unsigned long hfc_jiffies;
MODULE_AUTHOR("Karsten Keil");
MODULE_LICENSE("GPL");
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index ba6925fbf38a..9c427fb204ee 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -35,7 +35,7 @@
#include <linux/mISDNhw.h>
#include "hfcsusb.h"
-const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";
+static const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";
static unsigned int debug;
static int poll = DEFAULT_TRANSP_BURST_SZ;
@@ -974,7 +974,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
spin_unlock(&hw->lock);
}
-void
+static void
fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
void *buf, int num_packets, int packet_size, int interval,
usb_complete_t complete, void *context)
@@ -1720,7 +1720,7 @@ hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel)
/* Hardware Initialization */
-int
+static int
setup_hfcsusb(struct hfcsusb *hw)
{
int err;
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.h b/drivers/isdn/hardware/mISDN/hfcsusb.h
index 098486b8e8d2..43efe7358fa3 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.h
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.h
@@ -198,7 +198,7 @@ validconf[][19] = {
};
/* string description of chosen config */
-char *conf_str[] = {
+static char *conf_str[] = {
"4 Interrupt IN + 3 Isochron OUT",
"3 Interrupt IN + 3 Isochron OUT",
"4 Isochron IN + 3 Isochron OUT",
@@ -316,7 +316,7 @@ struct hfcsusb_vdata {
#define HFC_MAX_TE_LAYER1_STATE 8
#define HFC_MAX_NT_LAYER1_STATE 4
-const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
+static const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
"TE F0 - Reset",
"TE F1 - Reset",
"TE F2 - Sensing",
@@ -328,7 +328,7 @@ const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
"TE F8 - Lost framing",
};
-const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = {
+static const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = {
"NT G0 - Reset",
"NT G1 - Deactive",
"NT G2 - Pending activation",
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c
index 7c56c44f0fd1..025a20d487c5 100644
--- a/drivers/isdn/hisax/callc.c
+++ b/drivers/isdn/hisax/callc.c
@@ -24,7 +24,6 @@
const char *lli_revision = "$Revision: 2.59.2.4 $";
extern struct IsdnCard cards[];
-extern int nrcards;
static int init_b_st(struct Channel *chanp, int incoming);
static void release_b_st(struct Channel *chanp);
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index ded9d0baf607..4fab18d4d02f 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -361,12 +361,6 @@ module_param_array(io1, int, NULL, 0);
int nrcards;
-extern const char *l1_revision;
-extern const char *l2_revision;
-extern const char *l3_revision;
-extern const char *lli_revision;
-extern const char *tei_revision;
-
char *HiSax_getrev(const char *revision)
{
char *rev;
diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c
index cf082665cc8b..20d7688b397b 100644
--- a/drivers/isdn/hisax/hfcscard.c
+++ b/drivers/isdn/hisax/hfcscard.c
@@ -16,8 +16,6 @@
#include "hfc_2bds0.h"
#include "isdnl1.h"
-extern const char *CardType[];
-
static const char *hfcs_revision = "$Revision: 1.10.2.4 $";
static irqreturn_t
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index e8d429fda846..f8527046f197 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -121,6 +121,15 @@
#ifdef __KERNEL__
+extern const char *CardType[];
+extern int nrcards;
+
+extern const char *l1_revision;
+extern const char *l2_revision;
+extern const char *l3_revision;
+extern const char *lli_revision;
+extern const char *tei_revision;
+
/* include l3dss1 & ni1 specific process structures, but no other defines */
#ifdef CONFIG_HISAX_EURO
#define l3dss1_process
diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c
index a14204ec88ee..317f16f516f2 100644
--- a/drivers/isdn/hisax/isdnl1.c
+++ b/drivers/isdn/hisax/isdnl1.c
@@ -18,12 +18,12 @@
*
*/
-const char *l1_revision = "$Revision: 2.46.2.5 $";
-
#include <linux/init.h>
#include "hisax.h"
#include "isdnl1.h"
+const char *l1_revision = "$Revision: 2.46.2.5 $";
+
#define TIMER3_VALUE 7000
static struct Fsm l1fsm_b;
diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c
index a10dfa82c734..5569a522e2a1 100644
--- a/drivers/isdn/hisax/sedlbauer.c
+++ b/drivers/isdn/hisax/sedlbauer.c
@@ -48,8 +48,6 @@
#include <linux/pci.h>
#include <linux/isapnp.h>
-extern const char *CardType[];
-
static const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $";
static const char *Sedlbauer_Types[] =
diff --git a/drivers/isdn/hisax/teles0.c b/drivers/isdn/hisax/teles0.c
index 48581335f43c..3ca0bed1b88c 100644
--- a/drivers/isdn/hisax/teles0.c
+++ b/drivers/isdn/hisax/teles0.c
@@ -21,8 +21,6 @@
#include "isac.h"
#include "hscx.h"
-extern const char *CardType[];
-
static const char *teles0_revision = "$Revision: 2.15.2.4 $";
#define TELES_IOMEM_SIZE 0x400
diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c
index 5dc9f1a43629..e9f5bb4cdffa 100644
--- a/drivers/isdn/hisax/teles3.c
+++ b/drivers/isdn/hisax/teles3.c
@@ -20,7 +20,6 @@
#include "hscx.h"
#include "isdnl1.h"
-extern const char *CardType[];
static const char *teles3_revision = "$Revision: 2.19.2.4 $";
#define byteout(addr,val) outb(val,addr)
diff --git a/drivers/isdn/mISDN/Kconfig b/drivers/isdn/mISDN/Kconfig
index 4938355c4072..1747a02a019a 100644
--- a/drivers/isdn/mISDN/Kconfig
+++ b/drivers/isdn/mISDN/Kconfig
@@ -14,13 +14,15 @@ config MISDN_DSP
depends on MISDN
help
Enable support for digital audio processing capability.
+
This module may be used for special applications that require
- cross connecting of bchannels, conferencing, dtmf decoding
+ cross connecting of bchannels, conferencing, dtmf decoding,
echo cancelation, tone generation, and Blowfish encryption and
- decryption.
- It may use hardware features if available.
+ decryption. It may use hardware features if available.
+
E.g. it is required for PBX4Linux. Go to http://isdn.eversberg.eu
- and get more informations about this module and it's usage.
+ and get more information about this module and its usage.
+
If unsure, say 'N'.
config MISDN_L1OIP
diff --git a/drivers/isdn/mISDN/clock.c b/drivers/isdn/mISDN/clock.c
index 44d9c3d5d33d..f1bbc88763b2 100644
--- a/drivers/isdn/mISDN/clock.c
+++ b/drivers/isdn/mISDN/clock.c
@@ -41,11 +41,11 @@
static u_int *debug;
static LIST_HEAD(iclock_list);
-DEFINE_RWLOCK(iclock_lock);
-u16 iclock_count; /* counter of last clock */
-struct timeval iclock_tv; /* time stamp of last clock */
-int iclock_tv_valid; /* already received one timestamp */
-struct mISDNclock *iclock_current;
+static DEFINE_RWLOCK(iclock_lock);
+static u16 iclock_count; /* counter of last clock */
+static struct timeval iclock_tv; /* time stamp of last clock */
+static int iclock_tv_valid; /* already received one timestamp */
+static struct mISDNclock *iclock_current;
void
mISDN_init_clock(u_int *dp)
diff --git a/drivers/isdn/mISDN/l1oip_codec.c b/drivers/isdn/mISDN/l1oip_codec.c
index 2ec4b28d9edc..e4ecba3d48df 100644
--- a/drivers/isdn/mISDN/l1oip_codec.c
+++ b/drivers/isdn/mISDN/l1oip_codec.c
@@ -331,7 +331,7 @@ l1oip_4bit_alloc(int ulaw)
/* alloc conversion tables */
table_com = vmalloc(65536);
table_dec = vmalloc(512);
- if (!table_com | !table_dec) {
+ if (!table_com || !table_dec) {
l1oip_4bit_free();
return -ENOMEM;
}
diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c
index f2b32186d4a1..bbd99d3282c0 100644
--- a/drivers/isdn/mISDN/timerdev.c
+++ b/drivers/isdn/mISDN/timerdev.c
@@ -152,8 +152,7 @@ dev_expire_timer(unsigned long data)
u_long flags;
spin_lock_irqsave(&timer->dev->lock, flags);
- list_del(&timer->list);
- list_add_tail(&timer->list, &timer->dev->expired);
+ list_move_tail(&timer->list, &timer->dev->expired);
spin_unlock_irqrestore(&timer->dev->lock, flags);
wake_up_interruptible(&timer->dev->wait);
}
diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c
index 5ba2a879df14..e075e8d2fce0 100644
--- a/drivers/isdn/pcbit/layer2.c
+++ b/drivers/isdn/pcbit/layer2.c
@@ -347,8 +347,7 @@ pcbit_receive(struct pcbit_dev *dev)
if (dev->read_frame) {
printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n");
/* discard previous queued frame */
- if (dev->read_frame->skb)
- kfree_skb(dev->read_frame->skb);
+ kfree_skb(dev->read_frame->skb);
kfree(dev->read_frame);
dev->read_frame = NULL;
}
@@ -601,8 +600,7 @@ pcbit_l2_err_recover(unsigned long data)
dev->w_busy = dev->r_busy = 1;
if (dev->read_frame) {
- if (dev->read_frame->skb)
- kfree_skb(dev->read_frame->skb);
+ kfree_skb(dev->read_frame->skb);
kfree(dev->read_frame);
dev->read_frame = NULL;
}
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 742713611bc5..9b60b6b684d9 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -31,6 +31,13 @@ config LEDS_LOCOMO
This option enables support for the LEDs on Sharp Locomo.
Zaurus models SL-5500 and SL-5600.
+config LEDS_MIKROTIK_RB532
+ tristate "LED Support for Mikrotik Routerboard 532"
+ depends on LEDS_CLASS && MIKROTIK_RB532
+ help
+ This option enables support for the so called "User LED" of
+ Mikrotik's Routerboard 532.
+
config LEDS_S3C24XX
tristate "LED Support for Samsung S3C24XX GPIO LEDs"
depends on LEDS_CLASS && ARCH_S3C2410
@@ -100,7 +107,7 @@ config LEDS_HP6XX
tristate "LED Support for the HP Jornada 6xx"
depends on LEDS_CLASS && SH_HP6XX
help
- This option enables led support for the handheld
+ This option enables LED support for the handheld
HP Jornada 620/660/680/690.
config LEDS_PCA9532
@@ -108,7 +115,7 @@ config LEDS_PCA9532
depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL
help
This option enables support for NXP pca9532
- led controller. It is generally only usefull
+ LED controller. It is generally only useful
as a platform driver
config LEDS_GPIO
@@ -117,11 +124,40 @@ config LEDS_GPIO
help
This option enables support for the LEDs connected to GPIO
outputs. To be useful the particular board must have LEDs
- and they must be connected to the GPIO lines.
+ and they must be connected to the GPIO lines. The LEDs must be
+ defined as platform devices and/or OpenFirmware platform devices.
+ The code to use these bindings can be selected below.
+
+config LEDS_GPIO_PLATFORM
+ bool "Platform device bindings for GPIO LEDs"
+ depends on LEDS_GPIO
+ default y
+ help
+ Let the leds-gpio driver drive LEDs which have been defined as
+ platform devices. If you don't know what this means, say yes.
+
+config LEDS_GPIO_OF
+ bool "OpenFirmware platform device bindings for GPIO LEDs"
+ depends on LEDS_GPIO && OF_DEVICE
+ default y
+ help
+ Let the leds-gpio driver drive LEDs which have been defined as
+ of_platform devices. For instance, LEDs which are listed in a "dts"
+ file.
+
+config LEDS_LP5521
+ tristate "LED Support for the LP5521 LEDs"
+ depends on LEDS_CLASS && I2C
+ help
+ If you say 'Y' here you get support for the National Semiconductor
+ LP5521 LED driver used in n8x0 boards.
+
+ This driver can be built as a module by choosing 'M'. The module
+ will be called leds-lp5521.
config LEDS_CLEVO_MAIL
- tristate "Mail LED on Clevo notebook (EXPERIMENTAL)"
- depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI && EXPERIMENTAL
+ tristate "Mail LED on Clevo notebook"
+ depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI
help
This driver makes the mail LED accessible from userspace
programs through the leds subsystem. This LED have three
@@ -144,7 +180,7 @@ config LEDS_CLEVO_MAIL
Positivo Mobile (Clevo M5x0V)
If your model is not listed here you can try the "nodetect"
- module paramter.
+ module parameter.
To compile this driver as a module, choose M here: the
module will be called leds-clevo-mail.
@@ -171,6 +207,26 @@ config LEDS_DA903X
This option enables support for on-chip LED drivers found
on Dialog Semiconductor DA9030/DA9034 PMICs.
+config LEDS_DAC124S085
+ tristate "LED Support for DAC124S085 SPI DAC"
+ depends on LEDS_CLASS && SPI
+ help
+ This option enables support for DAC124S085 SPI DAC from NatSemi,
+ which can be used to control up to four LEDs.
+
+config LEDS_PWM
+ tristate "PWM driven LED Support"
+ depends on LEDS_CLASS && HAVE_PWM
+ help
+ This option enables support for pwm driven LEDs
+
+config LEDS_BD2802
+ tristate "LED driver for BD2802 RGB LED"
+ depends on LEDS_CLASS && I2C
+ help
+ This option enables support for BD2802GU RGB LED driver chips
+ accessed via the I2C bus.
+
comment "LED Triggers"
config LEDS_TRIGGERS
@@ -216,6 +272,19 @@ config LEDS_TRIGGER_BACKLIGHT
If unsure, say N.
+config LEDS_TRIGGER_GPIO
+ tristate "LED GPIO Trigger"
+ depends on LEDS_TRIGGERS
+ depends on GPIOLIB
+ help
+ This allows LEDs to be controlled by gpio events. It's good
+ when using gpios as switches and triggering the needed LEDs
+ from there. One use case is n810's keypad LEDs that could
+ be triggered by this trigger when user slides up to show
+ keypad.
+
+ If unsure, say N.
+
config LEDS_TRIGGER_DEFAULT_ON
tristate "LED Default ON Trigger"
depends on LEDS_TRIGGERS
@@ -223,4 +292,7 @@ config LEDS_TRIGGER_DEFAULT_ON
This allows LEDs to be initialised in the ON state.
If unsure, say Y.
+comment "iptables trigger is under Netfilter config (LED target)"
+ depends on LEDS_TRIGGERS
+
endif # NEW_LEDS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 9d76f0f160a4..2d41c4dcf92f 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -6,7 +6,9 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
# LED Platform Drivers
obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o
+obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
+obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o
obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
@@ -24,10 +26,15 @@ obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o
obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o
obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o
+obj-$(CONFIG_LEDS_PWM) += leds-pwm.o
+
+# LED SPI Drivers
+obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
# LED Triggers
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
+obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o
obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 52f82e3ea13a..f2cc13d76810 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -64,7 +64,16 @@ static ssize_t led_brightness_store(struct device *dev,
return ret;
}
+static ssize_t led_max_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", led_cdev->max_brightness);
+}
+
static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
+static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL);
#ifdef CONFIG_LEDS_TRIGGERS
static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
#endif
@@ -138,6 +147,13 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
list_add_tail(&led_cdev->node, &leds_list);
up_write(&leds_list_lock);
+ if (!led_cdev->max_brightness)
+ led_cdev->max_brightness = LED_FULL;
+
+ rc = device_create_file(led_cdev->dev, &dev_attr_max_brightness);
+ if (rc)
+ goto err_out_attr_max;
+
led_update_brightness(led_cdev);
#ifdef CONFIG_LEDS_TRIGGERS
@@ -155,9 +171,11 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
#ifdef CONFIG_LEDS_TRIGGERS
err_out_led_list:
+ device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
+#endif
+err_out_attr_max:
device_remove_file(led_cdev->dev, &dev_attr_brightness);
list_del(&led_cdev->node);
-#endif
err_out:
device_unregister(led_cdev->dev);
return rc;
@@ -172,6 +190,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register);
*/
void led_classdev_unregister(struct led_classdev *led_cdev)
{
+ device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
device_remove_file(led_cdev->dev, &dev_attr_brightness);
#ifdef CONFIG_LEDS_TRIGGERS
device_remove_file(led_cdev->dev, &dev_attr_trigger);
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index f910eaffe3a6..d8ddd9ef8994 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -156,12 +156,20 @@ EXPORT_SYMBOL_GPL(led_trigger_set_default);
int led_trigger_register(struct led_trigger *trigger)
{
struct led_classdev *led_cdev;
+ struct led_trigger *trig;
rwlock_init(&trigger->leddev_list_lock);
INIT_LIST_HEAD(&trigger->led_cdevs);
- /* Add to the list of led triggers */
down_write(&triggers_list_lock);
+ /* Make sure the trigger's name isn't already in use */
+ list_for_each_entry(trig, &trigger_list, next_trig) {
+ if (!strcmp(trig->name, trigger->name)) {
+ up_write(&triggers_list_lock);
+ return -EEXIST;
+ }
+ }
+ /* Add to the list of led triggers */
list_add_tail(&trigger->next_trig, &trigger_list);
up_write(&triggers_list_lock);
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
new file mode 100644
index 000000000000..4149ecb3a9b2
--- /dev/null
+++ b/drivers/leds/leds-bd2802.c
@@ -0,0 +1,765 @@
+/*
+ * leds-bd2802.c - RGB LED Driver
+ *
+ * Copyright (C) 2009 Samsung Electronics
+ * Kim Kyuwon <q1.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Datasheet: http://www.rohm.com/products/databook/driver/pdf/bd2802gu-e.pdf
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/leds-bd2802.h>
+
+
+#define LED_CTL(rgb2en, rgb1en) ((rgb2en) << 4 | ((rgb1en) << 0))
+
+#define BD2802_LED_OFFSET 0xa
+#define BD2802_COLOR_OFFSET 0x3
+
+#define BD2802_REG_CLKSETUP 0x00
+#define BD2802_REG_CONTROL 0x01
+#define BD2802_REG_HOURSETUP 0x02
+#define BD2802_REG_CURRENT1SETUP 0x03
+#define BD2802_REG_CURRENT2SETUP 0x04
+#define BD2802_REG_WAVEPATTERN 0x05
+
+#define BD2802_CURRENT_032 0x10 /* 3.2mA */
+#define BD2802_CURRENT_000 0x00 /* 0.0mA */
+
+#define BD2802_PATTERN_FULL 0x07
+#define BD2802_PATTERN_HALF 0x03
+
+enum led_ids {
+ LED1,
+ LED2,
+ LED_NUM,
+};
+
+enum led_colors {
+ RED,
+ GREEN,
+ BLUE,
+};
+
+enum led_bits {
+ BD2802_OFF,
+ BD2802_BLINK,
+ BD2802_ON,
+};
+
+/*
+ * State '0' : 'off'
+ * State '1' : 'blink'
+ * State '2' : 'on'.
+ */
+struct led_state {
+ unsigned r:2;
+ unsigned g:2;
+ unsigned b:2;
+};
+
+struct bd2802_led {
+ struct bd2802_led_platform_data *pdata;
+ struct i2c_client *client;
+ struct rw_semaphore rwsem;
+ struct work_struct work;
+
+ struct led_state led[2];
+
+ /*
+ * Making led_classdev as array is not recommended, because array
+ * members prevent using 'container_of' macro. So repetitive works
+ * are needed.
+ */
+ struct led_classdev cdev_led1r;
+ struct led_classdev cdev_led1g;
+ struct led_classdev cdev_led1b;
+ struct led_classdev cdev_led2r;
+ struct led_classdev cdev_led2g;
+ struct led_classdev cdev_led2b;
+
+ /*
+ * Advanced Configuration Function(ADF) mode:
+ * In ADF mode, user can set registers of BD2802GU directly,
+ * therefore BD2802GU doesn't enter reset state.
+ */
+ int adf_on;
+
+ enum led_ids led_id;
+ enum led_colors color;
+ enum led_bits state;
+};
+
+
+/*--------------------------------------------------------------*/
+/* BD2802GU helper functions */
+/*--------------------------------------------------------------*/
+
+static inline int bd2802_is_rgb_off(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color)
+{
+ switch (color) {
+ case RED:
+ return !led->led[id].r;
+ case GREEN:
+ return !led->led[id].g;
+ case BLUE:
+ return !led->led[id].b;
+ default:
+ dev_err(&led->client->dev, "%s: Invalid color\n", __func__);
+ return -EINVAL;
+ }
+}
+
+static inline int bd2802_is_led_off(struct bd2802_led *led, enum led_ids id)
+{
+ if (led->led[id].r || led->led[id].g || led->led[id].b)
+ return 0;
+
+ return 1;
+}
+
+static inline int bd2802_is_all_off(struct bd2802_led *led)
+{
+ int i;
+
+ for (i = 0; i < LED_NUM; i++)
+ if (!bd2802_is_led_off(led, i))
+ return 0;
+
+ return 1;
+}
+
+static inline u8 bd2802_get_base_offset(enum led_ids id, enum led_colors color)
+{
+ return id * BD2802_LED_OFFSET + color * BD2802_COLOR_OFFSET;
+}
+
+static inline u8 bd2802_get_reg_addr(enum led_ids id, enum led_colors color,
+ u8 reg_offset)
+{
+ return reg_offset + bd2802_get_base_offset(id, color);
+}
+
+
+/*--------------------------------------------------------------*/
+/* BD2802GU core functions */
+/*--------------------------------------------------------------*/
+
+static int bd2802_write_byte(struct i2c_client *client, u8 reg, u8 val)
+{
+ int ret = i2c_smbus_write_byte_data(client, reg, val);
+ if (ret >= 0)
+ return 0;
+
+ dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n",
+ __func__, reg, val, ret);
+
+ return ret;
+}
+
+static void bd2802_update_state(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color, enum led_bits led_bit)
+{
+ int i;
+ u8 value;
+
+ for (i = 0; i < LED_NUM; i++) {
+ if (i == id) {
+ switch (color) {
+ case RED:
+ led->led[i].r = led_bit;
+ break;
+ case GREEN:
+ led->led[i].g = led_bit;
+ break;
+ case BLUE:
+ led->led[i].b = led_bit;
+ break;
+ default:
+ dev_err(&led->client->dev,
+ "%s: Invalid color\n", __func__);
+ return;
+ }
+ }
+ }
+
+ if (led_bit == BD2802_BLINK || led_bit == BD2802_ON)
+ return;
+
+ if (!bd2802_is_led_off(led, id))
+ return;
+
+ if (bd2802_is_all_off(led) && !led->adf_on) {
+ gpio_set_value(led->pdata->reset_gpio, 0);
+ return;
+ }
+
+ /*
+ * In this case, other led is turned on, and current led is turned
+ * off. So set RGB LED Control register to stop the current RGB LED
+ */
+ value = (id == LED1) ? LED_CTL(1, 0) : LED_CTL(0, 1);
+ bd2802_write_byte(led->client, BD2802_REG_CONTROL, value);
+}
+
+static void bd2802_configure(struct bd2802_led *led)
+{
+ struct bd2802_led_platform_data *pdata = led->pdata;
+ u8 reg;
+
+ reg = bd2802_get_reg_addr(LED1, RED, BD2802_REG_HOURSETUP);
+ bd2802_write_byte(led->client, reg, pdata->rgb_time);
+
+ reg = bd2802_get_reg_addr(LED2, RED, BD2802_REG_HOURSETUP);
+ bd2802_write_byte(led->client, reg, pdata->rgb_time);
+}
+
+static void bd2802_reset_cancel(struct bd2802_led *led)
+{
+ gpio_set_value(led->pdata->reset_gpio, 1);
+ udelay(100);
+ bd2802_configure(led);
+}
+
+static void bd2802_enable(struct bd2802_led *led, enum led_ids id)
+{
+ enum led_ids other_led = (id == LED1) ? LED2 : LED1;
+ u8 value, other_led_on;
+
+ other_led_on = !bd2802_is_led_off(led, other_led);
+ if (id == LED1)
+ value = LED_CTL(other_led_on, 1);
+ else
+ value = LED_CTL(1 , other_led_on);
+
+ bd2802_write_byte(led->client, BD2802_REG_CONTROL, value);
+}
+
+static void bd2802_set_on(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color)
+{
+ u8 reg;
+
+ if (bd2802_is_all_off(led) && !led->adf_on)
+ bd2802_reset_cancel(led);
+
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_032);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN);
+ bd2802_write_byte(led->client, reg, BD2802_PATTERN_FULL);
+
+ bd2802_enable(led, id);
+ bd2802_update_state(led, id, color, BD2802_ON);
+}
+
+static void bd2802_set_blink(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color)
+{
+ u8 reg;
+
+ if (bd2802_is_all_off(led) && !led->adf_on)
+ bd2802_reset_cancel(led);
+
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_032);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN);
+ bd2802_write_byte(led->client, reg, BD2802_PATTERN_HALF);
+
+ bd2802_enable(led, id);
+ bd2802_update_state(led, id, color, BD2802_BLINK);
+}
+
+static void bd2802_turn_on(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color, enum led_bits led_bit)
+{
+ if (led_bit == BD2802_OFF) {
+ dev_err(&led->client->dev,
+ "Only 'blink' and 'on' are allowed\n");
+ return;
+ }
+
+ if (led_bit == BD2802_BLINK)
+ bd2802_set_blink(led, id, color);
+ else
+ bd2802_set_on(led, id, color);
+}
+
+static void bd2802_turn_off(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color)
+{
+ u8 reg;
+
+ if (bd2802_is_rgb_off(led, id, color))
+ return;
+
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+
+ bd2802_update_state(led, id, color, BD2802_OFF);
+}
+
+static void bd2802_restore_state(struct bd2802_led *led)
+{
+ int i;
+
+ for (i = 0; i < LED_NUM; i++) {
+ if (led->led[i].r)
+ bd2802_turn_on(led, i, RED, led->led[i].r);
+ if (led->led[i].g)
+ bd2802_turn_on(led, i, GREEN, led->led[i].g);
+ if (led->led[i].b)
+ bd2802_turn_on(led, i, BLUE, led->led[i].b);
+ }
+}
+
+#define BD2802_SET_REGISTER(reg_addr, reg_name) \
+static ssize_t bd2802_store_reg##reg_addr(struct device *dev, \
+ struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+ struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\
+ unsigned long val; \
+ int ret; \
+ if (!count) \
+ return -EINVAL; \
+ ret = strict_strtoul(buf, 16, &val); \
+ if (ret) \
+ return ret; \
+ down_write(&led->rwsem); \
+ bd2802_write_byte(led->client, reg_addr, (u8) val); \
+ up_write(&led->rwsem); \
+ return count; \
+} \
+static struct device_attribute bd2802_reg##reg_addr##_attr = { \
+ .attr = {.name = reg_name, .mode = 0644, .owner = THIS_MODULE}, \
+ .store = bd2802_store_reg##reg_addr, \
+};
+
+BD2802_SET_REGISTER(0x00, "0x00");
+BD2802_SET_REGISTER(0x01, "0x01");
+BD2802_SET_REGISTER(0x02, "0x02");
+BD2802_SET_REGISTER(0x03, "0x03");
+BD2802_SET_REGISTER(0x04, "0x04");
+BD2802_SET_REGISTER(0x05, "0x05");
+BD2802_SET_REGISTER(0x06, "0x06");
+BD2802_SET_REGISTER(0x07, "0x07");
+BD2802_SET_REGISTER(0x08, "0x08");
+BD2802_SET_REGISTER(0x09, "0x09");
+BD2802_SET_REGISTER(0x0a, "0x0a");
+BD2802_SET_REGISTER(0x0b, "0x0b");
+BD2802_SET_REGISTER(0x0c, "0x0c");
+BD2802_SET_REGISTER(0x0d, "0x0d");
+BD2802_SET_REGISTER(0x0e, "0x0e");
+BD2802_SET_REGISTER(0x0f, "0x0f");
+BD2802_SET_REGISTER(0x10, "0x10");
+BD2802_SET_REGISTER(0x11, "0x11");
+BD2802_SET_REGISTER(0x12, "0x12");
+BD2802_SET_REGISTER(0x13, "0x13");
+BD2802_SET_REGISTER(0x14, "0x14");
+BD2802_SET_REGISTER(0x15, "0x15");
+
+static struct device_attribute *bd2802_addr_attributes[] = {
+ &bd2802_reg0x00_attr,
+ &bd2802_reg0x01_attr,
+ &bd2802_reg0x02_attr,
+ &bd2802_reg0x03_attr,
+ &bd2802_reg0x04_attr,
+ &bd2802_reg0x05_attr,
+ &bd2802_reg0x06_attr,
+ &bd2802_reg0x07_attr,
+ &bd2802_reg0x08_attr,
+ &bd2802_reg0x09_attr,
+ &bd2802_reg0x0a_attr,
+ &bd2802_reg0x0b_attr,
+ &bd2802_reg0x0c_attr,
+ &bd2802_reg0x0d_attr,
+ &bd2802_reg0x0e_attr,
+ &bd2802_reg0x0f_attr,
+ &bd2802_reg0x10_attr,
+ &bd2802_reg0x11_attr,
+ &bd2802_reg0x12_attr,
+ &bd2802_reg0x13_attr,
+ &bd2802_reg0x14_attr,
+ &bd2802_reg0x15_attr,
+};
+
+static void bd2802_enable_adv_conf(struct bd2802_led *led)
+{
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++) {
+ ret = device_create_file(&led->client->dev,
+ bd2802_addr_attributes[i]);
+ if (ret) {
+ dev_err(&led->client->dev, "failed to sysfs file %s\n",
+ bd2802_addr_attributes[i]->attr.name);
+ goto failed_remove_files;
+ }
+ }
+
+ if (bd2802_is_all_off(led))
+ bd2802_reset_cancel(led);
+
+ led->adf_on = 1;
+
+ return;
+
+failed_remove_files:
+ for (i--; i >= 0; i--)
+ device_remove_file(&led->client->dev,
+ bd2802_addr_attributes[i]);
+}
+
+static void bd2802_disable_adv_conf(struct bd2802_led *led)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++)
+ device_remove_file(&led->client->dev,
+ bd2802_addr_attributes[i]);
+
+ if (bd2802_is_all_off(led))
+ gpio_set_value(led->pdata->reset_gpio, 0);
+
+ led->adf_on = 0;
+}
+
+static ssize_t bd2802_show_adv_conf(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));
+ ssize_t ret;
+
+ down_read(&led->rwsem);
+ if (led->adf_on)
+ ret = sprintf(buf, "on\n");
+ else
+ ret = sprintf(buf, "off\n");
+ up_read(&led->rwsem);
+
+ return ret;
+}
+
+static ssize_t bd2802_store_adv_conf(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));
+
+ if (!count)
+ return -EINVAL;
+
+ down_write(&led->rwsem);
+ if (!led->adf_on && !strncmp(buf, "on", 2))
+ bd2802_enable_adv_conf(led);
+ else if (led->adf_on && !strncmp(buf, "off", 3))
+ bd2802_disable_adv_conf(led);
+ up_write(&led->rwsem);
+
+ return count;
+}
+
+static struct device_attribute bd2802_adv_conf_attr = {
+ .attr = {
+ .name = "advanced_configuration",
+ .mode = 0644,
+ .owner = THIS_MODULE
+ },
+ .show = bd2802_show_adv_conf,
+ .store = bd2802_store_adv_conf,
+};
+
+static void bd2802_led_work(struct work_struct *work)
+{
+ struct bd2802_led *led = container_of(work, struct bd2802_led, work);
+
+ if (led->state)
+ bd2802_turn_on(led, led->led_id, led->color, led->state);
+ else
+ bd2802_turn_off(led, led->led_id, led->color);
+}
+
+#define BD2802_CONTROL_RGBS(name, id, clr) \
+static void bd2802_set_##name##_brightness(struct led_classdev *led_cdev,\
+ enum led_brightness value) \
+{ \
+ struct bd2802_led *led = \
+ container_of(led_cdev, struct bd2802_led, cdev_##name); \
+ led->led_id = id; \
+ led->color = clr; \
+ if (value == LED_OFF) \
+ led->state = BD2802_OFF; \
+ else \
+ led->state = BD2802_ON; \
+ schedule_work(&led->work); \
+} \
+static int bd2802_set_##name##_blink(struct led_classdev *led_cdev, \
+ unsigned long *delay_on, unsigned long *delay_off) \
+{ \
+ struct bd2802_led *led = \
+ container_of(led_cdev, struct bd2802_led, cdev_##name); \
+ if (*delay_on == 0 || *delay_off == 0) \
+ return -EINVAL; \
+ led->led_id = id; \
+ led->color = clr; \
+ led->state = BD2802_BLINK; \
+ schedule_work(&led->work); \
+ return 0; \
+}
+
+BD2802_CONTROL_RGBS(led1r, LED1, RED);
+BD2802_CONTROL_RGBS(led1g, LED1, GREEN);
+BD2802_CONTROL_RGBS(led1b, LED1, BLUE);
+BD2802_CONTROL_RGBS(led2r, LED2, RED);
+BD2802_CONTROL_RGBS(led2g, LED2, GREEN);
+BD2802_CONTROL_RGBS(led2b, LED2, BLUE);
+
+static int bd2802_register_led_classdev(struct bd2802_led *led)
+{
+ int ret;
+
+ INIT_WORK(&led->work, bd2802_led_work);
+
+ led->cdev_led1r.name = "led1_R";
+ led->cdev_led1r.brightness = LED_OFF;
+ led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness;
+ led->cdev_led1r.blink_set = bd2802_set_led1r_blink;
+ led->cdev_led1r.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led1r);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led1r.name);
+ goto failed_unregister_led1_R;
+ }
+
+ led->cdev_led1g.name = "led1_G";
+ led->cdev_led1g.brightness = LED_OFF;
+ led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness;
+ led->cdev_led1g.blink_set = bd2802_set_led1g_blink;
+ led->cdev_led1g.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led1g);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led1g.name);
+ goto failed_unregister_led1_G;
+ }
+
+ led->cdev_led1b.name = "led1_B";
+ led->cdev_led1b.brightness = LED_OFF;
+ led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness;
+ led->cdev_led1b.blink_set = bd2802_set_led1b_blink;
+ led->cdev_led1b.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led1b);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led1b.name);
+ goto failed_unregister_led1_B;
+ }
+
+ led->cdev_led2r.name = "led2_R";
+ led->cdev_led2r.brightness = LED_OFF;
+ led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness;
+ led->cdev_led2r.blink_set = bd2802_set_led2r_blink;
+ led->cdev_led2r.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led2r);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led2r.name);
+ goto failed_unregister_led2_R;
+ }
+
+ led->cdev_led2g.name = "led2_G";
+ led->cdev_led2g.brightness = LED_OFF;
+ led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness;
+ led->cdev_led2g.blink_set = bd2802_set_led2g_blink;
+ led->cdev_led2g.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led2g);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led2g.name);
+ goto failed_unregister_led2_G;
+ }
+
+ led->cdev_led2b.name = "led2_B";
+ led->cdev_led2b.brightness = LED_OFF;
+ led->cdev_led2b.brightness_set = bd2802_set_led2b_brightness;
+ led->cdev_led2b.blink_set = bd2802_set_led2b_blink;
+ led->cdev_led2b.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led2b);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led2b.name);
+ goto failed_unregister_led2_B;
+ }
+
+ return 0;
+
+failed_unregister_led2_B:
+ led_classdev_unregister(&led->cdev_led2g);
+failed_unregister_led2_G:
+ led_classdev_unregister(&led->cdev_led2r);
+failed_unregister_led2_R:
+ led_classdev_unregister(&led->cdev_led1b);
+failed_unregister_led1_B:
+ led_classdev_unregister(&led->cdev_led1g);
+failed_unregister_led1_G:
+ led_classdev_unregister(&led->cdev_led1r);
+failed_unregister_led1_R:
+
+ return ret;
+}
+
+static void bd2802_unregister_led_classdev(struct bd2802_led *led)
+{
+ cancel_work_sync(&led->work);
+ led_classdev_unregister(&led->cdev_led1r);
+}
+
+static int __devinit bd2802_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct bd2802_led *led;
+ struct bd2802_led_platform_data *pdata;
+ int ret;
+
+ led = kzalloc(sizeof(struct bd2802_led), GFP_KERNEL);
+ if (!led) {
+ dev_err(&client->dev, "failed to allocate driver data\n");
+ return -ENOMEM;
+ }
+
+ led->client = client;
+ pdata = led->pdata = client->dev.platform_data;
+ i2c_set_clientdata(client, led);
+
+ /* Configure RESET GPIO (L: RESET, H: RESET cancel) */
+ gpio_request(pdata->reset_gpio, "RGB_RESETB");
+ gpio_direction_output(pdata->reset_gpio, 1);
+
+ /* Tacss = min 0.1ms */
+ udelay(100);
+
+ /* Detect BD2802GU */
+ ret = bd2802_write_byte(client, BD2802_REG_CLKSETUP, 0x00);
+ if (ret < 0) {
+ dev_err(&client->dev, "failed to detect device\n");
+ goto failed_free;
+ } else
+ dev_info(&client->dev, "return 0x%02x\n", ret);
+
+ /* To save the power, reset BD2802 after detecting */
+ gpio_set_value(led->pdata->reset_gpio, 0);
+
+ init_rwsem(&led->rwsem);
+
+ ret = device_create_file(&client->dev, &bd2802_adv_conf_attr);
+ if (ret) {
+ dev_err(&client->dev, "failed to create sysfs file %s\n",
+ bd2802_adv_conf_attr.attr.name);
+ goto failed_free;
+ }
+
+ ret = bd2802_register_led_classdev(led);
+ if (ret < 0)
+ goto failed_unregister_dev_file;
+
+ return 0;
+
+failed_unregister_dev_file:
+ device_remove_file(&client->dev, &bd2802_adv_conf_attr);
+failed_free:
+ i2c_set_clientdata(client, NULL);
+ kfree(led);
+
+ return ret;
+}
+
+static int __exit bd2802_remove(struct i2c_client *client)
+{
+ struct bd2802_led *led = i2c_get_clientdata(client);
+
+ bd2802_unregister_led_classdev(led);
+ gpio_set_value(led->pdata->reset_gpio, 0);
+ if (led->adf_on)
+ bd2802_disable_adv_conf(led);
+ device_remove_file(&client->dev, &bd2802_adv_conf_attr);
+ i2c_set_clientdata(client, NULL);
+ kfree(led);
+
+ return 0;
+}
+
+static int bd2802_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ struct bd2802_led *led = i2c_get_clientdata(client);
+
+ gpio_set_value(led->pdata->reset_gpio, 0);
+
+ return 0;
+}
+
+static int bd2802_resume(struct i2c_client *client)
+{
+ struct bd2802_led *led = i2c_get_clientdata(client);
+
+ if (!bd2802_is_all_off(led) || led->adf_on) {
+ gpio_set_value(led->pdata->reset_gpio, 1);
+ udelay(100);
+ bd2802_restore_state(led);
+ }
+
+ return 0;
+}
+
+static const struct i2c_device_id bd2802_id[] = {
+ { "BD2802", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, bd2802_id);
+
+static struct i2c_driver bd2802_i2c_driver = {
+ .driver = {
+ .name = "BD2802",
+ },
+ .probe = bd2802_probe,
+ .remove = __exit_p(bd2802_remove),
+ .suspend = bd2802_suspend,
+ .resume = bd2802_resume,
+ .id_table = bd2802_id,
+};
+
+static int __init bd2802_init(void)
+{
+ return i2c_add_driver(&bd2802_i2c_driver);
+}
+module_init(bd2802_init);
+
+static void __exit bd2802_exit(void)
+{
+ i2c_del_driver(&bd2802_i2c_driver);
+}
+module_exit(bd2802_exit);
+
+MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>");
+MODULE_DESCRIPTION("BD2802 LED driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-dac124s085.c b/drivers/leds/leds-dac124s085.c
new file mode 100644
index 000000000000..098d9aae7259
--- /dev/null
+++ b/drivers/leds/leds-dac124s085.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * LED driver for the DAC124S085 SPI DAC
+ */
+
+#include <linux/gfp.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+
+struct dac124s085_led {
+ struct led_classdev ldev;
+ struct spi_device *spi;
+ int id;
+ int brightness;
+ char name[sizeof("dac124s085-3")];
+
+ struct mutex mutex;
+ struct work_struct work;
+ spinlock_t lock;
+};
+
+struct dac124s085 {
+ struct dac124s085_led leds[4];
+};
+
+#define REG_WRITE (0 << 12)
+#define REG_WRITE_UPDATE (1 << 12)
+#define ALL_WRITE_UPDATE (2 << 12)
+#define POWER_DOWN_OUTPUT (3 << 12)
+
+static void dac124s085_led_work(struct work_struct *work)
+{
+ struct dac124s085_led *led = container_of(work, struct dac124s085_led,
+ work);
+ u16 word;
+
+ mutex_lock(&led->mutex);
+ word = cpu_to_le16(((led->id) << 14) | REG_WRITE_UPDATE |
+ (led->brightness & 0xfff));
+ spi_write(led->spi, (const u8 *)&word, sizeof(word));
+ mutex_unlock(&led->mutex);
+}
+
+static void dac124s085_set_brightness(struct led_classdev *ldev,
+ enum led_brightness brightness)
+{
+ struct dac124s085_led *led = container_of(ldev, struct dac124s085_led,
+ ldev);
+
+ spin_lock(&led->lock);
+ led->brightness = brightness;
+ schedule_work(&led->work);
+ spin_unlock(&led->lock);
+}
+
+static int dac124s085_probe(struct spi_device *spi)
+{
+ struct dac124s085 *dac;
+ struct dac124s085_led *led;
+ int i, ret;
+
+ dac = kzalloc(sizeof(*dac), GFP_KERNEL);
+ if (!dac)
+ return -ENOMEM;
+
+ spi->bits_per_word = 16;
+
+ for (i = 0; i < ARRAY_SIZE(dac->leds); i++) {
+ led = dac->leds + i;
+ led->id = i;
+ led->brightness = LED_OFF;
+ led->spi = spi;
+ snprintf(led->name, sizeof(led->name), "dac124s085-%d", i);
+ spin_lock_init(&led->lock);
+ INIT_WORK(&led->work, dac124s085_led_work);
+ mutex_init(&led->mutex);
+ led->ldev.name = led->name;
+ led->ldev.brightness = LED_OFF;
+ led->ldev.max_brightness = 0xfff;
+ led->ldev.brightness_set = dac124s085_set_brightness;
+ ret = led_classdev_register(&spi->dev, &led->ldev);
+ if (ret < 0)
+ goto eledcr;
+ }
+
+ spi_set_drvdata(spi, dac);
+
+ return 0;
+
+eledcr:
+ while (i--)
+ led_classdev_unregister(&dac->leds[i].ldev);
+
+ spi_set_drvdata(spi, NULL);
+ kfree(dac);
+ return ret;
+}
+
+static int dac124s085_remove(struct spi_device *spi)
+{
+ struct dac124s085 *dac = spi_get_drvdata(spi);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dac->leds); i++) {
+ led_classdev_unregister(&dac->leds[i].ldev);
+ cancel_work_sync(&dac->leds[i].work);
+ }
+
+ spi_set_drvdata(spi, NULL);
+ kfree(dac);
+
+ return 0;
+}
+
+static struct spi_driver dac124s085_driver = {
+ .probe = dac124s085_probe,
+ .remove = dac124s085_remove,
+ .driver = {
+ .name = "dac124s085",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init dac124s085_leds_init(void)
+{
+ return spi_register_driver(&dac124s085_driver);
+}
+
+static void __exit dac124s085_leds_exit(void)
+{
+ spi_unregister_driver(&dac124s085_driver);
+}
+
+module_init(dac124s085_leds_init);
+module_exit(dac124s085_leds_exit);
+
+MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
+MODULE_DESCRIPTION("DAC124S085 LED driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 2e3df08b649b..102ef4a14c5f 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2007 8D Technologies inc.
* Raphael Assenat <raph@8d.com>
+ * Copyright (C) 2008 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -71,11 +72,67 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
return led_dat->platform_gpio_blink_set(led_dat->gpio, delay_on, delay_off);
}
+static int __devinit create_gpio_led(const struct gpio_led *template,
+ struct gpio_led_data *led_dat, struct device *parent,
+ int (*blink_set)(unsigned, unsigned long *, unsigned long *))
+{
+ int ret;
+
+ /* skip leds that aren't available */
+ if (!gpio_is_valid(template->gpio)) {
+ printk(KERN_INFO "Skipping unavilable LED gpio %d (%s)\n",
+ template->gpio, template->name);
+ return;
+ }
+
+ ret = gpio_request(template->gpio, template->name);
+ if (ret < 0)
+ return ret;
+
+ led_dat->cdev.name = template->name;
+ led_dat->cdev.default_trigger = template->default_trigger;
+ led_dat->gpio = template->gpio;
+ led_dat->can_sleep = gpio_cansleep(template->gpio);
+ led_dat->active_low = template->active_low;
+ if (blink_set) {
+ led_dat->platform_gpio_blink_set = blink_set;
+ led_dat->cdev.blink_set = gpio_blink_set;
+ }
+ led_dat->cdev.brightness_set = gpio_led_set;
+ led_dat->cdev.brightness = LED_OFF;
+ if (!template->retain_state_suspended)
+ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = gpio_direction_output(led_dat->gpio, led_dat->active_low);
+ if (ret < 0)
+ goto err;
+
+ INIT_WORK(&led_dat->work, gpio_led_work);
+
+ ret = led_classdev_register(parent, &led_dat->cdev);
+ if (ret < 0)
+ goto err;
+
+ return 0;
+err:
+ gpio_free(led_dat->gpio);
+ return ret;
+}
+
+static void delete_gpio_led(struct gpio_led_data *led)
+{
+ if (!gpio_is_valid(led->gpio))
+ return;
+ led_classdev_unregister(&led->cdev);
+ cancel_work_sync(&led->work);
+ gpio_free(led->gpio);
+}
+
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
static int gpio_led_probe(struct platform_device *pdev)
{
struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
- struct gpio_led *cur_led;
- struct gpio_led_data *leds_data, *led_dat;
+ struct gpio_led_data *leds_data;
int i, ret = 0;
if (!pdata)
@@ -87,35 +144,10 @@ static int gpio_led_probe(struct platform_device *pdev)
return -ENOMEM;
for (i = 0; i < pdata->num_leds; i++) {
- cur_led = &pdata->leds[i];
- led_dat = &leds_data[i];
-
- ret = gpio_request(cur_led->gpio, cur_led->name);
+ ret = create_gpio_led(&pdata->leds[i], &leds_data[i],
+ &pdev->dev, pdata->gpio_blink_set);
if (ret < 0)
goto err;
-
- led_dat->cdev.name = cur_led->name;
- led_dat->cdev.default_trigger = cur_led->default_trigger;
- led_dat->gpio = cur_led->gpio;
- led_dat->can_sleep = gpio_cansleep(cur_led->gpio);
- led_dat->active_low = cur_led->active_low;
- if (pdata->gpio_blink_set) {
- led_dat->platform_gpio_blink_set = pdata->gpio_blink_set;
- led_dat->cdev.blink_set = gpio_blink_set;
- }
- led_dat->cdev.brightness_set = gpio_led_set;
- led_dat->cdev.brightness = LED_OFF;
- led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
-
- gpio_direction_output(led_dat->gpio, led_dat->active_low);
-
- INIT_WORK(&led_dat->work, gpio_led_work);
-
- ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
- if (ret < 0) {
- gpio_free(led_dat->gpio);
- goto err;
- }
}
platform_set_drvdata(pdev, leds_data);
@@ -123,13 +155,8 @@ static int gpio_led_probe(struct platform_device *pdev)
return 0;
err:
- if (i > 0) {
- for (i = i - 1; i >= 0; i--) {
- led_classdev_unregister(&leds_data[i].cdev);
- cancel_work_sync(&leds_data[i].work);
- gpio_free(leds_data[i].gpio);
- }
- }
+ for (i = i - 1; i >= 0; i--)
+ delete_gpio_led(&leds_data[i]);
kfree(leds_data);
@@ -144,11 +171,8 @@ static int __devexit gpio_led_remove(struct platform_device *pdev)
leds_data = platform_get_drvdata(pdev);
- for (i = 0; i < pdata->num_leds; i++) {
- led_classdev_unregister(&leds_data[i].cdev);
- cancel_work_sync(&leds_data[i].work);
- gpio_free(leds_data[i].gpio);
- }
+ for (i = 0; i < pdata->num_leds; i++)
+ delete_gpio_led(&leds_data[i]);
kfree(leds_data);
@@ -164,20 +188,133 @@ static struct platform_driver gpio_led_driver = {
},
};
+MODULE_ALIAS("platform:leds-gpio");
+#endif /* CONFIG_LEDS_GPIO_PLATFORM */
+
+/* Code to create from OpenFirmware platform devices */
+#ifdef CONFIG_LEDS_GPIO_OF
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+
+struct gpio_led_of_platform_data {
+ int num_leds;
+ struct gpio_led_data led_data[];
+};
+
+static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct device_node *np = ofdev->node, *child;
+ struct gpio_led led;
+ struct gpio_led_of_platform_data *pdata;
+ int count = 0, ret;
+
+ /* count LEDs defined by this device, so we know how much to allocate */
+ for_each_child_of_node(np, child)
+ count++;
+ if (!count)
+ return 0; /* or ENODEV? */
+
+ pdata = kzalloc(sizeof(*pdata) + sizeof(struct gpio_led_data) * count,
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ memset(&led, 0, sizeof(led));
+ for_each_child_of_node(np, child) {
+ enum of_gpio_flags flags;
+
+ led.gpio = of_get_gpio_flags(child, 0, &flags);
+ led.active_low = flags & OF_GPIO_ACTIVE_LOW;
+ led.name = of_get_property(child, "label", NULL) ? : child->name;
+ led.default_trigger =
+ of_get_property(child, "linux,default-trigger", NULL);
+
+ ret = create_gpio_led(&led, &pdata->led_data[pdata->num_leds++],
+ &ofdev->dev, NULL);
+ if (ret < 0) {
+ of_node_put(child);
+ goto err;
+ }
+ }
+
+ dev_set_drvdata(&ofdev->dev, pdata);
+
+ return 0;
+
+err:
+ for (count = pdata->num_leds - 2; count >= 0; count--)
+ delete_gpio_led(&pdata->led_data[count]);
+
+ kfree(pdata);
+
+ return ret;
+}
+
+static int __devexit of_gpio_leds_remove(struct of_device *ofdev)
+{
+ struct gpio_led_of_platform_data *pdata = dev_get_drvdata(&ofdev->dev);
+ int i;
+
+ for (i = 0; i < pdata->num_leds; i++)
+ delete_gpio_led(&pdata->led_data[i]);
+
+ kfree(pdata);
+
+ dev_set_drvdata(&ofdev->dev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id of_gpio_leds_match[] = {
+ { .compatible = "gpio-leds", },
+ {},
+};
+
+static struct of_platform_driver of_gpio_leds_driver = {
+ .driver = {
+ .name = "of_gpio_leds",
+ .owner = THIS_MODULE,
+ },
+ .match_table = of_gpio_leds_match,
+ .probe = of_gpio_leds_probe,
+ .remove = __devexit_p(of_gpio_leds_remove),
+};
+#endif
+
static int __init gpio_led_init(void)
{
- return platform_driver_register(&gpio_led_driver);
+ int ret;
+
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
+ ret = platform_driver_register(&gpio_led_driver);
+ if (ret)
+ return ret;
+#endif
+#ifdef CONFIG_LEDS_GPIO_OF
+ ret = of_register_platform_driver(&of_gpio_leds_driver);
+#endif
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
+ if (ret)
+ platform_driver_unregister(&gpio_led_driver);
+#endif
+
+ return ret;
}
static void __exit gpio_led_exit(void)
{
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
platform_driver_unregister(&gpio_led_driver);
+#endif
+#ifdef CONFIG_LEDS_GPIO_OF
+ of_unregister_platform_driver(&of_gpio_leds_driver);
+#endif
}
module_init(gpio_led_init);
module_exit(gpio_led_exit);
-MODULE_AUTHOR("Raphael Assenat <raph@8d.com>");
+MODULE_AUTHOR("Raphael Assenat <raph@8d.com>, Trent Piepho <tpiepho@freescale.com>");
MODULE_DESCRIPTION("GPIO LED driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:leds-gpio");
diff --git a/drivers/leds/leds-h1940.c b/drivers/leds/leds-h1940.c
index 11b77a70bbcb..1aa46a390a0d 100644
--- a/drivers/leds/leds-h1940.c
+++ b/drivers/leds/leds-h1940.c
@@ -104,7 +104,7 @@ static struct led_classdev h1940_blueled = {
.default_trigger = "h1940-bluetooth",
};
-static int __init h1940leds_probe(struct platform_device *pdev)
+static int __devinit h1940leds_probe(struct platform_device *pdev)
{
int ret;
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index 76ec7498e2d5..3937244fdcab 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -1,7 +1,7 @@
/*
* pca9532.c - 16-bit Led dimmer
*
- * Copyright (C) 2008 Riku Voipio <riku.voipio@movial.fi>
+ * Copyright (C) 2008 Riku Voipio
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -169,7 +169,7 @@ static int pca9532_event(struct input_dev *dev, unsigned int type,
{
struct pca9532_data *data = input_get_drvdata(dev);
- if (type != EV_SND && (code != SND_BELL || code != SND_TONE))
+ if (!(type == EV_SND && (code == SND_BELL || code == SND_TONE)))
return -1;
/* XXX: allow different kind of beeps with psc/pwm modifications */
@@ -367,7 +367,7 @@ static void __exit pca9532_exit(void)
i2c_del_driver(&pca9532_driver);
}
-MODULE_AUTHOR("Riku Voipio <riku.voipio@movial.fi>");
+MODULE_AUTHOR("Riku Voipio");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("PCA 9532 LED dimmer");
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
new file mode 100644
index 000000000000..cdfdc8714e10
--- /dev/null
+++ b/drivers/leds/leds-pwm.c
@@ -0,0 +1,153 @@
+/*
+ * linux/drivers/leds-pwm.c
+ *
+ * simple PWM based LED control
+ *
+ * Copyright 2009 Luotao Fu @ Pengutronix (l.fu@pengutronix.de)
+ *
+ * based on leds-gpio.c by Raphael Assenat <raph@8d.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <linux/pwm.h>
+#include <linux/leds_pwm.h>
+
+struct led_pwm_data {
+ struct led_classdev cdev;
+ struct pwm_device *pwm;
+ unsigned int active_low;
+ unsigned int period;
+ unsigned int max_brightness;
+};
+
+static void led_pwm_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct led_pwm_data *led_dat =
+ container_of(led_cdev, struct led_pwm_data, cdev);
+ unsigned int max = led_dat->max_brightness;
+ unsigned int period = led_dat->period;
+
+ if (brightness == 0) {
+ pwm_config(led_dat->pwm, 0, period);
+ pwm_disable(led_dat->pwm);
+ } else {
+ pwm_config(led_dat->pwm, brightness * period / max, period);
+ pwm_enable(led_dat->pwm);
+ }
+}
+
+static int led_pwm_probe(struct platform_device *pdev)
+{
+ struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
+ struct led_pwm *cur_led;
+ struct led_pwm_data *leds_data, *led_dat;
+ int i, ret = 0;
+
+ if (!pdata)
+ return -EBUSY;
+
+ leds_data = kzalloc(sizeof(struct led_pwm_data) * pdata->num_leds,
+ GFP_KERNEL);
+ if (!leds_data)
+ return -ENOMEM;
+
+ for (i = 0; i < pdata->num_leds; i++) {
+ cur_led = &pdata->leds[i];
+ led_dat = &leds_data[i];
+
+ led_dat->pwm = pwm_request(cur_led->pwm_id,
+ cur_led->name);
+ if (IS_ERR(led_dat->pwm)) {
+ dev_err(&pdev->dev, "unable to request PWM %d\n",
+ cur_led->pwm_id);
+ goto err;
+ }
+
+ led_dat->cdev.name = cur_led->name;
+ led_dat->cdev.default_trigger = cur_led->default_trigger;
+ led_dat->active_low = cur_led->active_low;
+ led_dat->max_brightness = cur_led->max_brightness;
+ led_dat->period = cur_led->pwm_period_ns;
+ led_dat->cdev.brightness_set = led_pwm_set;
+ led_dat->cdev.brightness = LED_OFF;
+ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
+ if (ret < 0) {
+ pwm_free(led_dat->pwm);
+ goto err;
+ }
+ }
+
+ platform_set_drvdata(pdev, leds_data);
+
+ return 0;
+
+err:
+ if (i > 0) {
+ for (i = i - 1; i >= 0; i--) {
+ led_classdev_unregister(&leds_data[i].cdev);
+ pwm_free(leds_data[i].pwm);
+ }
+ }
+
+ kfree(leds_data);
+
+ return ret;
+}
+
+static int __devexit led_pwm_remove(struct platform_device *pdev)
+{
+ int i;
+ struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
+ struct led_pwm_data *leds_data;
+
+ leds_data = platform_get_drvdata(pdev);
+
+ for (i = 0; i < pdata->num_leds; i++) {
+ led_classdev_unregister(&leds_data[i].cdev);
+ pwm_free(leds_data[i].pwm);
+ }
+
+ kfree(leds_data);
+
+ return 0;
+}
+
+static struct platform_driver led_pwm_driver = {
+ .probe = led_pwm_probe,
+ .remove = __devexit_p(led_pwm_remove),
+ .driver = {
+ .name = "leds_pwm",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init led_pwm_init(void)
+{
+ return platform_driver_register(&led_pwm_driver);
+}
+
+static void __exit led_pwm_exit(void)
+{
+ platform_driver_unregister(&led_pwm_driver);
+}
+
+module_init(led_pwm_init);
+module_exit(led_pwm_exit);
+
+MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
+MODULE_DESCRIPTION("PWM LED driver for PXA");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:leds-pwm");
diff --git a/drivers/leds/leds-rb532.c b/drivers/leds/leds-rb532.c
new file mode 100644
index 000000000000..c3525f37f73d
--- /dev/null
+++ b/drivers/leds/leds-rb532.c
@@ -0,0 +1,77 @@
+/*
+ * LEDs driver for the "User LED" on Routerboard532
+ *
+ * Copyright (C) 2009 Phil Sutter <n0-1@freewrt.org>
+ *
+ * Based on leds-cobalt-qube.c by Florian Fainelly and
+ * rb-diag.c (my own standalone driver for both LED and
+ * button of Routerboard532).
+ */
+
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-rc32434/gpio.h>
+#include <asm/mach-rc32434/rb.h>
+
+static void rb532_led_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ if (brightness)
+ set_latch_u5(LO_ULED, 0);
+
+ else
+ set_latch_u5(0, LO_ULED);
+}
+
+static enum led_brightness rb532_led_get(struct led_classdev *cdev)
+{
+ return (get_latch_u5() & LO_ULED) ? LED_FULL : LED_OFF;
+}
+
+static struct led_classdev rb532_uled = {
+ .name = "uled",
+ .brightness_set = rb532_led_set,
+ .brightness_get = rb532_led_get,
+ .default_trigger = "nand-disk",
+};
+
+static int __devinit rb532_led_probe(struct platform_device *pdev)
+{
+ return led_classdev_register(&pdev->dev, &rb532_uled);
+}
+
+static int __devexit rb532_led_remove(struct platform_device *pdev)
+{
+ led_classdev_unregister(&rb532_uled);
+ return 0;
+}
+
+static struct platform_driver rb532_led_driver = {
+ .probe = rb532_led_probe,
+ .remove = __devexit_p(rb532_led_remove),
+ .driver = {
+ .name = "rb532-led",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init rb532_led_init(void)
+{
+ return platform_driver_register(&rb532_led_driver);
+}
+
+static void __exit rb532_led_exit(void)
+{
+ platform_driver_unregister(&rb532_led_driver);
+}
+
+module_init(rb532_led_init);
+module_exit(rb532_led_exit);
+
+MODULE_ALIAS("platform:rb532-led");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("User LED support for Routerboard532");
+MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>");
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c
index 4d81131542ae..aa2e7ae0cdae 100644
--- a/drivers/leds/leds-s3c24xx.c
+++ b/drivers/leds/leds-s3c24xx.c
@@ -102,14 +102,11 @@ static int s3c24xx_led_probe(struct platform_device *dev)
ret = led_classdev_register(&dev->dev, &led->cdev);
if (ret < 0) {
dev_err(&dev->dev, "led_classdev_register failed\n");
- goto exit_err1;
+ kfree(led);
+ return ret;
}
return 0;
-
- exit_err1:
- kfree(led);
- return ret;
}
static struct platform_driver s3c24xx_led_driver = {
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index 5edbf52c4fa7..2dd8ecbfdc31 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -20,8 +20,8 @@
static inline void led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness value)
{
- if (value > LED_FULL)
- value = LED_FULL;
+ if (value > led_cdev->max_brightness)
+ value = led_cdev->max_brightness;
led_cdev->brightness = value;
if (!(led_cdev->flags & LED_SUSPENDED))
led_cdev->brightness_set(led_cdev, value);
diff --git a/drivers/leds/ledtrig-default-on.c b/drivers/leds/ledtrig-default-on.c
index 92995e40cfa4..a4ef54b9d508 100644
--- a/drivers/leds/ledtrig-default-on.c
+++ b/drivers/leds/ledtrig-default-on.c
@@ -19,7 +19,7 @@
static void defon_trig_activate(struct led_classdev *led_cdev)
{
- led_set_brightness(led_cdev, LED_FULL);
+ led_set_brightness(led_cdev, led_cdev->max_brightness);
}
static struct led_trigger defon_led_trigger = {
diff --git a/drivers/leds/ledtrig-gpio.c b/drivers/leds/ledtrig-gpio.c
new file mode 100644
index 000000000000..a247ae63374f
--- /dev/null
+++ b/drivers/leds/ledtrig-gpio.c
@@ -0,0 +1,239 @@
+/*
+ * ledtrig-gio.c - LED Trigger Based on GPIO events
+ *
+ * Copyright 2009 Felipe Balbi <me@felipebalbi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/leds.h>
+#include "leds.h"
+
+struct gpio_trig_data {
+ struct led_classdev *led;
+ struct work_struct work;
+
+ unsigned desired_brightness; /* desired brightness when led is on */
+ unsigned inverted; /* true when gpio is inverted */
+ unsigned gpio; /* gpio that triggers the leds */
+};
+
+static irqreturn_t gpio_trig_irq(int irq, void *_led)
+{
+ struct led_classdev *led = _led;
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ /* just schedule_work since gpio_get_value can sleep */
+ schedule_work(&gpio_data->work);
+
+ return IRQ_HANDLED;
+};
+
+static void gpio_trig_work(struct work_struct *work)
+{
+ struct gpio_trig_data *gpio_data = container_of(work,
+ struct gpio_trig_data, work);
+ int tmp;
+
+ if (!gpio_data->gpio)
+ return;
+
+ tmp = gpio_get_value(gpio_data->gpio);
+ if (gpio_data->inverted)
+ tmp = !tmp;
+
+ if (tmp) {
+ if (gpio_data->desired_brightness)
+ led_set_brightness(gpio_data->led,
+ gpio_data->desired_brightness);
+ else
+ led_set_brightness(gpio_data->led, LED_FULL);
+ } else {
+ led_set_brightness(gpio_data->led, LED_OFF);
+ }
+}
+
+static ssize_t gpio_trig_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ return sprintf(buf, "%u\n", gpio_data->desired_brightness);
+}
+
+static ssize_t gpio_trig_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t n)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+ unsigned desired_brightness;
+ int ret;
+
+ ret = sscanf(buf, "%u", &desired_brightness);
+ if (ret < 1 || desired_brightness > 255) {
+ dev_err(dev, "invalid value\n");
+ return -EINVAL;
+ }
+
+ gpio_data->desired_brightness = desired_brightness;
+
+ return n;
+}
+static DEVICE_ATTR(desired_brightness, 0644, gpio_trig_brightness_show,
+ gpio_trig_brightness_store);
+
+static ssize_t gpio_trig_inverted_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ return sprintf(buf, "%s\n", gpio_data->inverted ? "yes" : "no");
+}
+
+static ssize_t gpio_trig_inverted_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t n)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+ unsigned inverted;
+ int ret;
+
+ ret = sscanf(buf, "%u", &inverted);
+ if (ret < 1) {
+ dev_err(dev, "invalid value\n");
+ return -EINVAL;
+ }
+
+ gpio_data->inverted = !!inverted;
+
+ return n;
+}
+static DEVICE_ATTR(inverted, 0644, gpio_trig_inverted_show,
+ gpio_trig_inverted_store);
+
+static ssize_t gpio_trig_gpio_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ return sprintf(buf, "%u\n", gpio_data->gpio);
+}
+
+static ssize_t gpio_trig_gpio_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t n)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+ unsigned gpio;
+ int ret;
+
+ ret = sscanf(buf, "%u", &gpio);
+ if (ret < 1) {
+ dev_err(dev, "couldn't read gpio number\n");
+ flush_work(&gpio_data->work);
+ return -EINVAL;
+ }
+
+ if (!gpio) {
+ free_irq(gpio_to_irq(gpio_data->gpio), led);
+ return n;
+ }
+
+ if (gpio_data->gpio > 0 && gpio_data->gpio != gpio)
+ free_irq(gpio_to_irq(gpio_data->gpio), led);
+
+ gpio_data->gpio = gpio;
+ ret = request_irq(gpio_to_irq(gpio), gpio_trig_irq,
+ IRQF_SHARED | IRQF_TRIGGER_RISING
+ | IRQF_TRIGGER_FALLING, "ledtrig-gpio", led);
+ if (ret)
+ dev_err(dev, "request_irq failed with error %d\n", ret);
+
+ return ret ? ret : n;
+}
+static DEVICE_ATTR(gpio, 0644, gpio_trig_gpio_show, gpio_trig_gpio_store);
+
+static void gpio_trig_activate(struct led_classdev *led)
+{
+ struct gpio_trig_data *gpio_data;
+ int ret;
+
+ gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL);
+ if (!gpio_data)
+ return;
+
+ ret = device_create_file(led->dev, &dev_attr_gpio);
+ if (ret)
+ goto err_gpio;
+
+ ret = device_create_file(led->dev, &dev_attr_inverted);
+ if (ret)
+ goto err_inverted;
+
+ ret = device_create_file(led->dev, &dev_attr_desired_brightness);
+ if (ret)
+ goto err_brightness;
+
+ gpio_data->led = led;
+ led->trigger_data = gpio_data;
+ INIT_WORK(&gpio_data->work, gpio_trig_work);
+
+ return;
+
+err_brightness:
+ device_remove_file(led->dev, &dev_attr_inverted);
+
+err_inverted:
+ device_remove_file(led->dev, &dev_attr_gpio);
+
+err_gpio:
+ kfree(gpio_data);
+}
+
+static void gpio_trig_deactivate(struct led_classdev *led)
+{
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ if (gpio_data) {
+ device_remove_file(led->dev, &dev_attr_gpio);
+ device_remove_file(led->dev, &dev_attr_inverted);
+ device_remove_file(led->dev, &dev_attr_desired_brightness);
+ flush_work(&gpio_data->work);
+ free_irq(gpio_to_irq(gpio_data->gpio),led);
+ kfree(gpio_data);
+ }
+}
+
+static struct led_trigger gpio_led_trigger = {
+ .name = "gpio",
+ .activate = gpio_trig_activate,
+ .deactivate = gpio_trig_deactivate,
+};
+
+static int __init gpio_trig_init(void)
+{
+ return led_trigger_register(&gpio_led_trigger);
+}
+module_init(gpio_trig_init);
+
+static void __exit gpio_trig_exit(void)
+{
+ led_trigger_unregister(&gpio_led_trigger);
+}
+module_exit(gpio_trig_exit);
+
+MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
+MODULE_DESCRIPTION("GPIO LED trigger");
+MODULE_LICENSE("GPL");
diff --git a/drivers/leds/ledtrig-heartbeat.c b/drivers/leds/ledtrig-heartbeat.c
index 4bf8cec8b8c1..c1c1ea6f817b 100644
--- a/drivers/leds/ledtrig-heartbeat.c
+++ b/drivers/leds/ledtrig-heartbeat.c
@@ -47,7 +47,7 @@ static void led_heartbeat_function(unsigned long data)
msecs_to_jiffies(heartbeat_data->period);
delay = msecs_to_jiffies(70);
heartbeat_data->phase++;
- brightness = LED_FULL;
+ brightness = led_cdev->max_brightness;
break;
case 1:
delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
@@ -56,7 +56,7 @@ static void led_heartbeat_function(unsigned long data)
case 2:
delay = msecs_to_jiffies(70);
heartbeat_data->phase++;
- brightness = LED_FULL;
+ brightness = led_cdev->max_brightness;
break;
default:
delay = heartbeat_data->period - heartbeat_data->period / 4 -
diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c
index 883a577b1b97..ec099fcbcb00 100644
--- a/drivers/leds/ledtrig-ide-disk.c
+++ b/drivers/leds/ledtrig-ide-disk.c
@@ -37,7 +37,8 @@ static void ledtrig_ide_timerfunc(unsigned long data)
{
if (ide_lastactivity != ide_activity) {
ide_lastactivity = ide_activity;
- led_trigger_event(ledtrig_ide, LED_FULL);
+ /* INT_MAX will set each LED to its maximum brightness */
+ led_trigger_event(ledtrig_ide, INT_MAX);
mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
} else {
led_trigger_event(ledtrig_ide, LED_OFF);
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index 3d6531396dda..3b83406de752 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -166,7 +166,7 @@ static void timer_trig_activate(struct led_classdev *led_cdev)
timer_data->brightness_on = led_get_brightness(led_cdev);
if (timer_data->brightness_on == LED_OFF)
- timer_data->brightness_on = LED_FULL;
+ timer_data->brightness_on = led_cdev->max_brightness;
led_cdev->trigger_data = timer_data;
init_timer(&timer_data->timer);
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 60156dfdc608..4845fb3cf74b 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -152,8 +152,8 @@ static void unmap_switcher(void)
* code. We have to check that the range is below the pfn_limit the Launcher
* gave us. We have to make sure that addr + len doesn't give us a false
* positive by overflowing, too. */
-int lguest_address_ok(const struct lguest *lg,
- unsigned long addr, unsigned long len)
+bool lguest_address_ok(const struct lguest *lg,
+ unsigned long addr, unsigned long len)
{
return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr);
}
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index 415fab0125ac..6e99adbe1946 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -34,7 +34,7 @@ static int idt_type(u32 lo, u32 hi)
}
/* An IDT entry can't be used unless the "present" bit is set. */
-static int idt_present(u32 lo, u32 hi)
+static bool idt_present(u32 lo, u32 hi)
{
return (hi & 0x8000);
}
@@ -60,7 +60,8 @@ static void push_guest_stack(struct lg_cpu *cpu, unsigned long *gstack, u32 val)
* We set up the stack just like the CPU does for a real interrupt, so it's
* identical for the Guest (and the standard "iret" instruction will undo
* it). */
-static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi, int has_err)
+static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi,
+ bool has_err)
{
unsigned long gstack, origstack;
u32 eflags, ss, irq_enable;
@@ -184,7 +185,7 @@ void maybe_do_interrupt(struct lg_cpu *cpu)
/* set_guest_interrupt() takes the interrupt descriptor and a
* flag to say whether this interrupt pushes an error code onto
* the stack as well: virtual interrupts never do. */
- set_guest_interrupt(cpu, idt->a, idt->b, 0);
+ set_guest_interrupt(cpu, idt->a, idt->b, false);
}
/* Every time we deliver an interrupt, we update the timestamp in the
@@ -244,26 +245,26 @@ void free_interrupts(void)
/*H:220 Now we've got the routines to deliver interrupts, delivering traps like
* page fault is easy. The only trick is that Intel decided that some traps
* should have error codes: */
-static int has_err(unsigned int trap)
+static bool has_err(unsigned int trap)
{
return (trap == 8 || (trap >= 10 && trap <= 14) || trap == 17);
}
/* deliver_trap() returns true if it could deliver the trap. */
-int deliver_trap(struct lg_cpu *cpu, unsigned int num)
+bool deliver_trap(struct lg_cpu *cpu, unsigned int num)
{
/* Trap numbers are always 8 bit, but we set an impossible trap number
* for traps inside the Switcher, so check that here. */
if (num >= ARRAY_SIZE(cpu->arch.idt))
- return 0;
+ return false;
/* Early on the Guest hasn't set the IDT entries (or maybe it put a
* bogus one in): if we fail here, the Guest will be killed. */
if (!idt_present(cpu->arch.idt[num].a, cpu->arch.idt[num].b))
- return 0;
+ return false;
set_guest_interrupt(cpu, cpu->arch.idt[num].a,
cpu->arch.idt[num].b, has_err(num));
- return 1;
+ return true;
}
/*H:250 Here's the hard part: returning to the Host every time a trap happens
@@ -279,18 +280,19 @@ int deliver_trap(struct lg_cpu *cpu, unsigned int num)
*
* This routine indicates if a particular trap number could be delivered
* directly. */
-static int direct_trap(unsigned int num)
+static bool direct_trap(unsigned int num)
{
/* Hardware interrupts don't go to the Guest at all (except system
* call). */
if (num >= FIRST_EXTERNAL_VECTOR && !could_be_syscall(num))
- return 0;
+ return false;
/* The Host needs to see page faults (for shadow paging and to save the
* fault address), general protection faults (in/out emulation) and
- * device not available (TS handling), and of course, the hypercall
- * trap. */
- return num != 14 && num != 13 && num != 7 && num != LGUEST_TRAP_ENTRY;
+ * device not available (TS handling), invalid opcode fault (kvm hcall),
+ * and of course, the hypercall trap. */
+ return num != 14 && num != 13 && num != 7 &&
+ num != 6 && num != LGUEST_TRAP_ENTRY;
}
/*:*/
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index f2c641e0bdde..ac8a4a3741b8 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -109,8 +109,8 @@ struct lguest
extern struct mutex lguest_lock;
/* core.c: */
-int lguest_address_ok(const struct lguest *lg,
- unsigned long addr, unsigned long len);
+bool lguest_address_ok(const struct lguest *lg,
+ unsigned long addr, unsigned long len);
void __lgread(struct lg_cpu *, void *, unsigned long, unsigned);
void __lgwrite(struct lg_cpu *, unsigned long, const void *, unsigned);
@@ -140,7 +140,7 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user);
/* interrupts_and_traps.c: */
void maybe_do_interrupt(struct lg_cpu *cpu);
-int deliver_trap(struct lg_cpu *cpu, unsigned int num);
+bool deliver_trap(struct lg_cpu *cpu, unsigned int num);
void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int i,
u32 low, u32 hi);
void guest_set_stack(struct lg_cpu *cpu, u32 seg, u32 esp, unsigned int pages);
@@ -173,7 +173,7 @@ void guest_pagetable_flush_user(struct lg_cpu *cpu);
void guest_set_pte(struct lg_cpu *cpu, unsigned long gpgdir,
unsigned long vaddr, pte_t val);
void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages);
-int demand_page(struct lg_cpu *cpu, unsigned long cr2, int errcode);
+bool demand_page(struct lg_cpu *cpu, unsigned long cr2, int errcode);
void pin_page(struct lg_cpu *cpu, unsigned long vaddr);
unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr);
void page_table_guest_data_init(struct lg_cpu *cpu);
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index 8132533d71f9..df44d962626d 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -161,7 +161,7 @@ static void set_status(struct virtio_device *vdev, u8 status)
/* We set the status. */
to_lgdev(vdev)->desc->status = status;
- hcall(LHCALL_NOTIFY, (max_pfn<<PAGE_SHIFT) + offset, 0, 0);
+ kvm_hypercall1(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset);
}
static void lg_set_status(struct virtio_device *vdev, u8 status)
@@ -209,7 +209,7 @@ static void lg_notify(struct virtqueue *vq)
* virtqueue structure. */
struct lguest_vq_info *lvq = vq->priv;
- hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0);
+ kvm_hypercall1(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT);
}
/* An extern declaration inside a C file is bad form. Don't do it. */
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index 576a8318221c..a059cf9980f7 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -199,7 +199,7 @@ static void check_gpgd(struct lg_cpu *cpu, pgd_t gpgd)
*
* If we fixed up the fault (ie. we mapped the address), this routine returns
* true. Otherwise, it was a real fault and we need to tell the Guest. */
-int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
+bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
{
pgd_t gpgd;
pgd_t *spgd;
@@ -211,7 +211,7 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t);
/* Toplevel not present? We can't map it in. */
if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
- return 0;
+ return false;
/* Now look at the matching shadow entry. */
spgd = spgd_addr(cpu, cpu->cpu_pgd, vaddr);
@@ -222,7 +222,7 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
* simple for this corner case. */
if (!ptepage) {
kill_guest(cpu, "out of memory allocating pte page");
- return 0;
+ return false;
}
/* We check that the Guest pgd is OK. */
check_gpgd(cpu, gpgd);
@@ -238,16 +238,16 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
/* If this page isn't in the Guest page tables, we can't page it in. */
if (!(pte_flags(gpte) & _PAGE_PRESENT))
- return 0;
+ return false;
/* Check they're not trying to write to a page the Guest wants
* read-only (bit 2 of errcode == write). */
if ((errcode & 2) && !(pte_flags(gpte) & _PAGE_RW))
- return 0;
+ return false;
/* User access to a kernel-only page? (bit 3 == user access) */
if ((errcode & 4) && !(pte_flags(gpte) & _PAGE_USER))
- return 0;
+ return false;
/* Check that the Guest PTE flags are OK, and the page number is below
* the pfn_limit (ie. not mapping the Launcher binary). */
@@ -283,7 +283,7 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
* manipulated, the result returned and the code complete. A small
* delay and a trace of alliteration are the only indications the Guest
* has that a page fault occurred at all. */
- return 1;
+ return true;
}
/*H:360
@@ -296,7 +296,7 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
*
* This is a quick version which answers the question: is this virtual address
* mapped by the shadow page tables, and is it writable? */
-static int page_writable(struct lg_cpu *cpu, unsigned long vaddr)
+static bool page_writable(struct lg_cpu *cpu, unsigned long vaddr)
{
pgd_t *spgd;
unsigned long flags;
@@ -304,7 +304,7 @@ static int page_writable(struct lg_cpu *cpu, unsigned long vaddr)
/* Look at the current top level entry: is it present? */
spgd = spgd_addr(cpu, cpu->cpu_pgd, vaddr);
if (!(pgd_flags(*spgd) & _PAGE_PRESENT))
- return 0;
+ return false;
/* Check the flags on the pte entry itself: it must be present and
* writable. */
@@ -373,8 +373,10 @@ unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr)
/* First step: get the top-level Guest page table entry. */
gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t);
/* Toplevel not present? We can't map it in. */
- if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
+ if (!(pgd_flags(gpgd) & _PAGE_PRESENT)) {
kill_guest(cpu, "Bad address %#lx", vaddr);
+ return -1UL;
+ }
gpte = lgread(cpu, gpte_addr(gpgd, vaddr), pte_t);
if (!(pte_flags(gpte) & _PAGE_PRESENT))
diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c
index ec6aa3f1c36b..4f15439b7f12 100644
--- a/drivers/lguest/segments.c
+++ b/drivers/lguest/segments.c
@@ -45,7 +45,7 @@
* "Task State Segment" which controls all kinds of delicate things. The
* LGUEST_CS and LGUEST_DS entries are reserved for the Switcher, and the
* the Guest can't be trusted to deal with double faults. */
-static int ignored_gdt(unsigned int num)
+static bool ignored_gdt(unsigned int num)
{
return (num == GDT_ENTRY_TSS
|| num == GDT_ENTRY_LGUEST_CS
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index bf7942327bda..a6b717644be0 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -290,6 +290,57 @@ static int emulate_insn(struct lg_cpu *cpu)
return 1;
}
+/* Our hypercalls mechanism used to be based on direct software interrupts.
+ * After Anthony's "Refactor hypercall infrastructure" kvm patch, we decided to
+ * change over to using kvm hypercalls.
+ *
+ * KVM_HYPERCALL is actually a "vmcall" instruction, which generates an invalid
+ * opcode fault (fault 6) on non-VT cpus, so the easiest solution seemed to be
+ * an *emulation approach*: if the fault was really produced by an hypercall
+ * (is_hypercall() does exactly this check), we can just call the corresponding
+ * hypercall host implementation function.
+ *
+ * But these invalid opcode faults are notably slower than software interrupts.
+ * So we implemented the *patching (or rewriting) approach*: every time we hit
+ * the KVM_HYPERCALL opcode in Guest code, we patch it to the old "int 0x1f"
+ * opcode, so next time the Guest calls this hypercall it will use the
+ * faster trap mechanism.
+ *
+ * Matias even benchmarked it to convince you: this shows the average cycle
+ * cost of a hypercall. For each alternative solution mentioned above we've
+ * made 5 runs of the benchmark:
+ *
+ * 1) direct software interrupt: 2915, 2789, 2764, 2721, 2898
+ * 2) emulation technique: 3410, 3681, 3466, 3392, 3780
+ * 3) patching (rewrite) technique: 2977, 2975, 2891, 2637, 2884
+ *
+ * One two-line function is worth a 20% hypercall speed boost!
+ */
+static void rewrite_hypercall(struct lg_cpu *cpu)
+{
+ /* This are the opcodes we use to patch the Guest. The opcode for "int
+ * $0x1f" is "0xcd 0x1f" but vmcall instruction is 3 bytes long, so we
+ * complete the sequence with a NOP (0x90). */
+ u8 insn[3] = {0xcd, 0x1f, 0x90};
+
+ __lgwrite(cpu, guest_pa(cpu, cpu->regs->eip), insn, sizeof(insn));
+}
+
+static bool is_hypercall(struct lg_cpu *cpu)
+{
+ u8 insn[3];
+
+ /* This must be the Guest kernel trying to do something.
+ * The bottom two bits of the CS segment register are the privilege
+ * level. */
+ if ((cpu->regs->cs & 3) != GUEST_PL)
+ return false;
+
+ /* Is it a vmcall? */
+ __lgread(cpu, insn, guest_pa(cpu, cpu->regs->eip), sizeof(insn));
+ return insn[0] == 0x0f && insn[1] == 0x01 && insn[2] == 0xc1;
+}
+
/*H:050 Once we've re-enabled interrupts, we look at why the Guest exited. */
void lguest_arch_handle_trap(struct lg_cpu *cpu)
{
@@ -337,7 +388,7 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
break;
case 32 ... 255:
/* These values mean a real interrupt occurred, in which case
- * the Host handler has already been run. We just do a
+ * the Host handler has already been run. We just do a
* friendly check if another process should now be run, then
* return to run the Guest again */
cond_resched();
@@ -347,6 +398,15 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
* up the pointer now to indicate a hypercall is pending. */
cpu->hcall = (struct hcall_args *)cpu->regs;
return;
+ case 6:
+ /* kvm hypercalls trigger an invalid opcode fault (6).
+ * We need to check if ring == GUEST_PL and
+ * faulting instruction == vmcall. */
+ if (is_hypercall(cpu)) {
+ rewrite_hypercall(cpu);
+ return;
+ }
+ break;
}
/* We didn't handle the trap, so it needs to go to the Guest. */
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 82607add69a9..c0621d50c8a0 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -498,8 +498,8 @@ static ssize_t store_##name(struct device *dev, struct device_attribute *attr, c
#define BUILD_STORE_FUNC_INT(name, data) \
static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \
{ \
- u32 val; \
- val = simple_strtoul(buf, NULL, 10); \
+ int val; \
+ val = simple_strtol(buf, NULL, 10); \
if (val < 0 || val > 255) \
return -EINVAL; \
printk(KERN_INFO "Setting specified fan speed to %d\n", val); \
diff --git a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c
index ef2dbfe74714..ada5ebbaa255 100644
--- a/drivers/mca/mca-bus.c
+++ b/drivers/mca/mca-bus.c
@@ -110,7 +110,7 @@ int __init mca_register_device(int bus, struct mca_device *mca_dev)
mca_dev->dev.parent = &mca_bus->dev;
mca_dev->dev.bus = &mca_bus_type;
- sprintf (mca_dev->dev.bus_id, "%02d:%02X", bus, mca_dev->slot);
+ dev_set_name(&mca_dev->dev, "%02d:%02X", bus, mca_dev->slot);
mca_dev->dma_mask = mca_bus->default_dma_mask;
mca_dev->dev.dma_mask = &mca_dev->dma_mask;
mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask;
@@ -151,7 +151,7 @@ struct mca_bus * __devinit mca_attach_bus(int bus)
if (!mca_bus)
return NULL;
- sprintf(mca_bus->dev.bus_id,"mca%d",bus);
+ dev_set_name(&mca_bus->dev, "mca%d", bus);
sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary");
if (device_register(&mca_bus->dev)) {
kfree(mca_bus);
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 2281b5098e95..36e0675be9f7 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -121,6 +121,7 @@ config MD_RAID10
config MD_RAID456
tristate "RAID-4/RAID-5/RAID-6 mode"
depends on BLK_DEV_MD
+ select MD_RAID6_PQ
select ASYNC_MEMCPY
select ASYNC_XOR
---help---
@@ -151,34 +152,8 @@ config MD_RAID456
If unsure, say Y.
-config MD_RAID5_RESHAPE
- bool "Support adding drives to a raid-5 array"
- depends on MD_RAID456
- default y
- ---help---
- A RAID-5 set can be expanded by adding extra drives. This
- requires "restriping" the array which means (almost) every
- block must be written to a different place.
-
- This option allows such restriping to be done while the array
- is online.
-
- You will need mdadm version 2.4.1 or later to use this
- feature safely. During the early stage of reshape there is
- a critical section where live data is being over-written. A
- crash during this time needs extra care for recovery. The
- newer mdadm takes a copy of the data in the critical section
- and will restore it, if necessary, after a crash.
-
- The mdadm usage is e.g.
- mdadm --grow /dev/md1 --raid-disks=6
- to grow '/dev/md1' to having 6 disks.
-
- Note: The array can only be expanded, not contracted.
- There should be enough spares already present to make the new
- array workable.
-
- If unsure, say Y.
+config MD_RAID6_PQ
+ tristate
config MD_MULTIPATH
tristate "Multipath I/O support"
diff --git a/drivers/md/Makefile b/drivers/md/Makefile
index 72880b7e28d9..45cc5951d928 100644
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -2,20 +2,21 @@
# Makefile for the kernel software RAID and LVM drivers.
#
-dm-mod-objs := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
+dm-mod-y += dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
dm-ioctl.o dm-io.o dm-kcopyd.o dm-sysfs.o
-dm-multipath-objs := dm-path-selector.o dm-mpath.o
-dm-snapshot-objs := dm-snap.o dm-exception-store.o dm-snap-transient.o \
+dm-multipath-y += dm-path-selector.o dm-mpath.o
+dm-snapshot-y += dm-snap.o dm-exception-store.o dm-snap-transient.o \
dm-snap-persistent.o
-dm-mirror-objs := dm-raid1.o
-md-mod-objs := md.o bitmap.o
-raid456-objs := raid5.o raid6algos.o raid6recov.o raid6tables.o \
+dm-mirror-y += dm-raid1.o
+md-mod-y += md.o bitmap.o
+raid456-y += raid5.o
+raid6_pq-y += raid6algos.o raid6recov.o raid6tables.o \
raid6int1.o raid6int2.o raid6int4.o \
raid6int8.o raid6int16.o raid6int32.o \
raid6altivec1.o raid6altivec2.o raid6altivec4.o \
raid6altivec8.o \
raid6mmx.o raid6sse1.o raid6sse2.o
-hostprogs-y := mktables
+hostprogs-y += mktables
# Note: link order is important. All raid personalities
# and must come before md.o, as they each initialise
@@ -26,6 +27,7 @@ obj-$(CONFIG_MD_LINEAR) += linear.o
obj-$(CONFIG_MD_RAID0) += raid0.o
obj-$(CONFIG_MD_RAID1) += raid1.o
obj-$(CONFIG_MD_RAID10) += raid10.o
+obj-$(CONFIG_MD_RAID6_PQ) += raid6_pq.o
obj-$(CONFIG_MD_RAID456) += raid456.o
obj-$(CONFIG_MD_MULTIPATH) += multipath.o
obj-$(CONFIG_MD_FAULTY) += faulty.o
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 719943763391..f8a9f7ab2cb8 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -16,6 +16,7 @@
* wait if count gets too high, wake when it drops to half.
*/
+#include <linux/blkdev.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
@@ -26,8 +27,8 @@
#include <linux/file.h>
#include <linux/mount.h>
#include <linux/buffer_head.h>
-#include <linux/raid/md.h>
-#include <linux/raid/bitmap.h>
+#include "md.h"
+#include "bitmap.h"
/* debug macros */
@@ -111,9 +112,10 @@ static int bitmap_checkpage(struct bitmap *bitmap, unsigned long page, int creat
unsigned char *mappage;
if (page >= bitmap->pages) {
- printk(KERN_ALERT
- "%s: invalid bitmap page request: %lu (> %lu)\n",
- bmname(bitmap), page, bitmap->pages-1);
+ /* This can happen if bitmap_start_sync goes beyond
+ * End-of-device while looking for a whole page.
+ * It is harmless.
+ */
return -EINVAL;
}
@@ -265,7 +267,6 @@ static mdk_rdev_t *next_active_rdev(mdk_rdev_t *rdev, mddev_t *mddev)
list_for_each_continue_rcu(pos, &mddev->disks) {
rdev = list_entry(pos, mdk_rdev_t, same_set);
if (rdev->raid_disk >= 0 &&
- test_bit(In_sync, &rdev->flags) &&
!test_bit(Faulty, &rdev->flags)) {
/* this is a usable devices */
atomic_inc(&rdev->nr_pending);
@@ -297,7 +298,7 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
+ size/512 > 0)
/* bitmap runs in to metadata */
goto bad_alignment;
- if (rdev->data_offset + mddev->size*2
+ if (rdev->data_offset + mddev->dev_sectors
> rdev->sb_start + bitmap->offset)
/* data runs in to bitmap */
goto bad_alignment;
@@ -570,7 +571,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
reason = "unrecognized superblock version";
- else if (chunksize < PAGE_SIZE)
+ else if (chunksize < 512)
reason = "bitmap chunksize too small";
else if ((1 << ffz(~chunksize)) != chunksize)
reason = "bitmap chunksize not a power of 2";
@@ -1306,6 +1307,9 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
PRINTK(KERN_DEBUG "dec write-behind count %d/%d\n",
atomic_read(&bitmap->behind_writes), bitmap->max_write_behind);
}
+ if (bitmap->mddev->degraded)
+ /* Never clear bits or update events_cleared when degraded */
+ success = 0;
while (sectors) {
int blocks;
@@ -1345,8 +1349,8 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
}
}
-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
- int degraded)
+static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+ int degraded)
{
bitmap_counter_t *bmc;
int rv;
@@ -1374,6 +1378,29 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
return rv;
}
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+ int degraded)
+{
+ /* bitmap_start_sync must always report on multiples of whole
+ * pages, otherwise resync (which is very PAGE_SIZE based) will
+ * get confused.
+ * So call __bitmap_start_sync repeatedly (if needed) until
+ * At least PAGE_SIZE>>9 blocks are covered.
+ * Return the 'or' of the result.
+ */
+ int rv = 0;
+ int blocks1;
+
+ *blocks = 0;
+ while (*blocks < (PAGE_SIZE>>9)) {
+ rv |= __bitmap_start_sync(bitmap, offset,
+ &blocks1, degraded);
+ offset += blocks1;
+ *blocks += blocks1;
+ }
+ return rv;
+}
+
void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted)
{
bitmap_counter_t *bmc;
@@ -1443,6 +1470,8 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
wait_event(bitmap->mddev->recovery_wait,
atomic_read(&bitmap->mddev->recovery_active) == 0);
+ bitmap->mddev->curr_resync_completed = bitmap->mddev->curr_resync;
+ set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags);
sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1);
s = 0;
while (s < sector && s < bitmap->mddev->resync_max_sectors) {
diff --git a/include/linux/raid/bitmap.h b/drivers/md/bitmap.h
index e98900671ca9..e98900671ca9 100644
--- a/include/linux/raid/bitmap.h
+++ b/drivers/md/bitmap.h
diff --git a/drivers/md/dm-bio-list.h b/drivers/md/dm-bio-list.h
index d4509be0fe67..345098b4ca77 100644
--- a/drivers/md/dm-bio-list.h
+++ b/drivers/md/dm-bio-list.h
@@ -52,6 +52,16 @@ static inline void bio_list_add(struct bio_list *bl, struct bio *bio)
bl->tail = bio;
}
+static inline void bio_list_add_head(struct bio_list *bl, struct bio *bio)
+{
+ bio->bi_next = bl->head;
+
+ bl->head = bio;
+
+ if (!bl->tail)
+ bl->tail = bio;
+}
+
static inline void bio_list_merge(struct bio_list *bl, struct bio_list *bl2)
{
if (!bl2->head)
diff --git a/drivers/md/dm-bio-record.h b/drivers/md/dm-bio-record.h
index d3ec217847d6..3a8cfa2645c7 100644
--- a/drivers/md/dm-bio-record.h
+++ b/drivers/md/dm-bio-record.h
@@ -16,30 +16,56 @@
* functions in this file help the target record and restore the
* original bio state.
*/
+
+struct dm_bio_vec_details {
+#if PAGE_SIZE < 65536
+ __u16 bv_len;
+ __u16 bv_offset;
+#else
+ unsigned bv_len;
+ unsigned bv_offset;
+#endif
+};
+
struct dm_bio_details {
sector_t bi_sector;
struct block_device *bi_bdev;
unsigned int bi_size;
unsigned short bi_idx;
unsigned long bi_flags;
+ struct dm_bio_vec_details bi_io_vec[BIO_MAX_PAGES];
};
static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio)
{
+ unsigned i;
+
bd->bi_sector = bio->bi_sector;
bd->bi_bdev = bio->bi_bdev;
bd->bi_size = bio->bi_size;
bd->bi_idx = bio->bi_idx;
bd->bi_flags = bio->bi_flags;
+
+ for (i = 0; i < bio->bi_vcnt; i++) {
+ bd->bi_io_vec[i].bv_len = bio->bi_io_vec[i].bv_len;
+ bd->bi_io_vec[i].bv_offset = bio->bi_io_vec[i].bv_offset;
+ }
}
static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio)
{
+ unsigned i;
+
bio->bi_sector = bd->bi_sector;
bio->bi_bdev = bd->bi_bdev;
bio->bi_size = bd->bi_size;
bio->bi_idx = bd->bi_idx;
bio->bi_flags = bd->bi_flags;
+
+ for (i = 0; i < bio->bi_vcnt; i++) {
+ bio->bi_io_vec[i].bv_len = bd->bi_io_vec[i].bv_len;
+ bio->bi_io_vec[i].bv_offset = bd->bi_io_vec[i].bv_offset;
+ }
}
#endif
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index bfefd079a955..53394e863c74 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1156,8 +1156,7 @@ bad_ivmode:
crypto_free_ablkcipher(tfm);
bad_cipher:
/* Must zero key material before freeing */
- memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
- kfree(cc);
+ kzfree(cc);
return -EINVAL;
}
@@ -1183,8 +1182,7 @@ static void crypt_dtr(struct dm_target *ti)
dm_put_device(ti, cc->dev);
/* Must zero key material before freeing */
- memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
- kfree(cc);
+ kzfree(cc);
}
static int crypt_map(struct dm_target *ti, struct bio *bio,
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index dccbfb0e010f..a2e26c242141 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -7,6 +7,7 @@
#include "dm-exception-store.h"
+#include <linux/ctype.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/vmalloc.h>
@@ -14,6 +15,257 @@
#define DM_MSG_PREFIX "snapshot exception stores"
+static LIST_HEAD(_exception_store_types);
+static DEFINE_SPINLOCK(_lock);
+
+static struct dm_exception_store_type *__find_exception_store_type(const char *name)
+{
+ struct dm_exception_store_type *type;
+
+ list_for_each_entry(type, &_exception_store_types, list)
+ if (!strcmp(name, type->name))
+ return type;
+
+ return NULL;
+}
+
+static struct dm_exception_store_type *_get_exception_store_type(const char *name)
+{
+ struct dm_exception_store_type *type;
+
+ spin_lock(&_lock);
+
+ type = __find_exception_store_type(name);
+
+ if (type && !try_module_get(type->module))
+ type = NULL;
+
+ spin_unlock(&_lock);
+
+ return type;
+}
+
+/*
+ * get_type
+ * @type_name
+ *
+ * Attempt to retrieve the dm_exception_store_type by name. If not already
+ * available, attempt to load the appropriate module.
+ *
+ * Exstore modules are named "dm-exstore-" followed by the 'type_name'.
+ * Modules may contain multiple types.
+ * This function will first try the module "dm-exstore-<type_name>",
+ * then truncate 'type_name' on the last '-' and try again.
+ *
+ * For example, if type_name was "clustered-shared", it would search
+ * 'dm-exstore-clustered-shared' then 'dm-exstore-clustered'.
+ *
+ * 'dm-exception-store-<type_name>' is too long of a name in my
+ * opinion, which is why I've chosen to have the files
+ * containing exception store implementations be 'dm-exstore-<type_name>'.
+ * If you want your module to be autoloaded, you will follow this
+ * naming convention.
+ *
+ * Returns: dm_exception_store_type* on success, NULL on failure
+ */
+static struct dm_exception_store_type *get_type(const char *type_name)
+{
+ char *p, *type_name_dup;
+ struct dm_exception_store_type *type;
+
+ type = _get_exception_store_type(type_name);
+ if (type)
+ return type;
+
+ type_name_dup = kstrdup(type_name, GFP_KERNEL);
+ if (!type_name_dup) {
+ DMERR("No memory left to attempt load for \"%s\"", type_name);
+ return NULL;
+ }
+
+ while (request_module("dm-exstore-%s", type_name_dup) ||
+ !(type = _get_exception_store_type(type_name))) {
+ p = strrchr(type_name_dup, '-');
+ if (!p)
+ break;
+ p[0] = '\0';
+ }
+
+ if (!type)
+ DMWARN("Module for exstore type \"%s\" not found.", type_name);
+
+ kfree(type_name_dup);
+
+ return type;
+}
+
+static void put_type(struct dm_exception_store_type *type)
+{
+ spin_lock(&_lock);
+ module_put(type->module);
+ spin_unlock(&_lock);
+}
+
+int dm_exception_store_type_register(struct dm_exception_store_type *type)
+{
+ int r = 0;
+
+ spin_lock(&_lock);
+ if (!__find_exception_store_type(type->name))
+ list_add(&type->list, &_exception_store_types);
+ else
+ r = -EEXIST;
+ spin_unlock(&_lock);
+
+ return r;
+}
+EXPORT_SYMBOL(dm_exception_store_type_register);
+
+int dm_exception_store_type_unregister(struct dm_exception_store_type *type)
+{
+ spin_lock(&_lock);
+
+ if (!__find_exception_store_type(type->name)) {
+ spin_unlock(&_lock);
+ return -EINVAL;
+ }
+
+ list_del(&type->list);
+
+ spin_unlock(&_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(dm_exception_store_type_unregister);
+
+/*
+ * Round a number up to the nearest 'size' boundary. size must
+ * be a power of 2.
+ */
+static ulong round_up(ulong n, ulong size)
+{
+ size--;
+ return (n + size) & ~size;
+}
+
+static int set_chunk_size(struct dm_exception_store *store,
+ const char *chunk_size_arg, char **error)
+{
+ unsigned long chunk_size_ulong;
+ char *value;
+
+ chunk_size_ulong = simple_strtoul(chunk_size_arg, &value, 10);
+ if (*chunk_size_arg == '\0' || *value != '\0') {
+ *error = "Invalid chunk size";
+ return -EINVAL;
+ }
+
+ if (!chunk_size_ulong) {
+ store->chunk_size = store->chunk_mask = store->chunk_shift = 0;
+ return 0;
+ }
+
+ /*
+ * Chunk size must be multiple of page size. Silently
+ * round up if it's not.
+ */
+ chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9);
+
+ /* Check chunk_size is a power of 2 */
+ if (!is_power_of_2(chunk_size_ulong)) {
+ *error = "Chunk size is not a power of 2";
+ return -EINVAL;
+ }
+
+ /* Validate the chunk size against the device block size */
+ if (chunk_size_ulong % (bdev_hardsect_size(store->cow->bdev) >> 9)) {
+ *error = "Chunk size is not a multiple of device blocksize";
+ return -EINVAL;
+ }
+
+ store->chunk_size = chunk_size_ulong;
+ store->chunk_mask = chunk_size_ulong - 1;
+ store->chunk_shift = ffs(chunk_size_ulong) - 1;
+
+ return 0;
+}
+
+int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+ unsigned *args_used,
+ struct dm_exception_store **store)
+{
+ int r = 0;
+ struct dm_exception_store_type *type;
+ struct dm_exception_store *tmp_store;
+ char persistent;
+
+ if (argc < 3) {
+ ti->error = "Insufficient exception store arguments";
+ return -EINVAL;
+ }
+
+ tmp_store = kmalloc(sizeof(*tmp_store), GFP_KERNEL);
+ if (!tmp_store) {
+ ti->error = "Exception store allocation failed";
+ return -ENOMEM;
+ }
+
+ persistent = toupper(*argv[1]);
+ if (persistent != 'P' && persistent != 'N') {
+ ti->error = "Persistent flag is not P or N";
+ return -EINVAL;
+ }
+
+ type = get_type(argv[1]);
+ if (!type) {
+ ti->error = "Exception store type not recognised";
+ r = -EINVAL;
+ goto bad_type;
+ }
+
+ tmp_store->type = type;
+ tmp_store->ti = ti;
+
+ r = dm_get_device(ti, argv[0], 0, 0,
+ FMODE_READ | FMODE_WRITE, &tmp_store->cow);
+ if (r) {
+ ti->error = "Cannot get COW device";
+ goto bad_cow;
+ }
+
+ r = set_chunk_size(tmp_store, argv[2], &ti->error);
+ if (r)
+ goto bad_cow;
+
+ r = type->ctr(tmp_store, 0, NULL);
+ if (r) {
+ ti->error = "Exception store type constructor failed";
+ goto bad_ctr;
+ }
+
+ *args_used = 3;
+ *store = tmp_store;
+ return 0;
+
+bad_ctr:
+ dm_put_device(ti, tmp_store->cow);
+bad_cow:
+ put_type(type);
+bad_type:
+ kfree(tmp_store);
+ return r;
+}
+EXPORT_SYMBOL(dm_exception_store_create);
+
+void dm_exception_store_destroy(struct dm_exception_store *store)
+{
+ store->type->dtr(store);
+ dm_put_device(store->ti, store->cow);
+ put_type(store->type);
+ kfree(store);
+}
+EXPORT_SYMBOL(dm_exception_store_destroy);
+
int dm_exception_store_init(void)
{
int r;
diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h
index bb9f33d5daa2..0a2e6e7f67b3 100644
--- a/drivers/md/dm-exception-store.h
+++ b/drivers/md/dm-exception-store.h
@@ -37,11 +37,18 @@ struct dm_snap_exception {
* Abstraction to handle the meta/layout of exception stores (the
* COW device).
*/
-struct dm_exception_store {
+struct dm_exception_store;
+struct dm_exception_store_type {
+ const char *name;
+ struct module *module;
+
+ int (*ctr) (struct dm_exception_store *store,
+ unsigned argc, char **argv);
+
/*
* Destroys this object when you've finished with it.
*/
- void (*destroy) (struct dm_exception_store *store);
+ void (*dtr) (struct dm_exception_store *store);
/*
* The target shouldn't read the COW device until this is
@@ -72,8 +79,9 @@ struct dm_exception_store {
*/
void (*drop_snapshot) (struct dm_exception_store *store);
- int (*status) (struct dm_exception_store *store, status_type_t status,
- char *result, unsigned int maxlen);
+ unsigned (*status) (struct dm_exception_store *store,
+ status_type_t status, char *result,
+ unsigned maxlen);
/*
* Return how full the snapshot is.
@@ -82,7 +90,21 @@ struct dm_exception_store {
sector_t *numerator,
sector_t *denominator);
- struct dm_snapshot *snap;
+ /* For internal device-mapper use only. */
+ struct list_head list;
+};
+
+struct dm_exception_store {
+ struct dm_exception_store_type *type;
+ struct dm_target *ti;
+
+ struct dm_dev *cow;
+
+ /* Size of data blocks saved - must be a power of 2 */
+ chunk_t chunk_size;
+ chunk_t chunk_mask;
+ chunk_t chunk_shift;
+
void *context;
};
@@ -129,6 +151,28 @@ static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e)
# endif
+/*
+ * Return the number of sectors in the device.
+ */
+static inline sector_t get_dev_size(struct block_device *bdev)
+{
+ return bdev->bd_inode->i_size >> SECTOR_SHIFT;
+}
+
+static inline chunk_t sector_to_chunk(struct dm_exception_store *store,
+ sector_t sector)
+{
+ return (sector & ~store->chunk_mask) >> store->chunk_shift;
+}
+
+int dm_exception_store_type_register(struct dm_exception_store_type *type);
+int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
+
+int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+ unsigned *args_used,
+ struct dm_exception_store **store);
+void dm_exception_store_destroy(struct dm_exception_store *store);
+
int dm_exception_store_init(void);
void dm_exception_store_exit(void);
@@ -141,8 +185,4 @@ void dm_persistent_snapshot_exit(void);
int dm_transient_snapshot_init(void);
void dm_transient_snapshot_exit(void);
-int dm_create_persistent(struct dm_exception_store *store);
-
-int dm_create_transient(struct dm_exception_store *store);
-
#endif /* _LINUX_DM_EXCEPTION_STORE */
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 36e2b5e46a6b..e73aabd61cd7 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -370,16 +370,13 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,
while (1) {
set_current_state(TASK_UNINTERRUPTIBLE);
- if (!atomic_read(&io.count) || signal_pending(current))
+ if (!atomic_read(&io.count))
break;
io_schedule();
}
set_current_state(TASK_RUNNING);
- if (atomic_read(&io.count))
- return -EINTR;
-
if (error_bits)
*error_bits = io.error_bits;
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 737961f275c1..be233bc4d917 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -16,40 +16,29 @@
#define DM_MSG_PREFIX "dirty region log"
-struct dm_dirty_log_internal {
- struct dm_dirty_log_type *type;
-
- struct list_head list;
- long use;
-};
-
static LIST_HEAD(_log_types);
static DEFINE_SPINLOCK(_lock);
-static struct dm_dirty_log_internal *__find_dirty_log_type(const char *name)
+static struct dm_dirty_log_type *__find_dirty_log_type(const char *name)
{
- struct dm_dirty_log_internal *log_type;
+ struct dm_dirty_log_type *log_type;
list_for_each_entry(log_type, &_log_types, list)
- if (!strcmp(name, log_type->type->name))
+ if (!strcmp(name, log_type->name))
return log_type;
return NULL;
}
-static struct dm_dirty_log_internal *_get_dirty_log_type(const char *name)
+static struct dm_dirty_log_type *_get_dirty_log_type(const char *name)
{
- struct dm_dirty_log_internal *log_type;
+ struct dm_dirty_log_type *log_type;
spin_lock(&_lock);
log_type = __find_dirty_log_type(name);
- if (log_type) {
- if (!log_type->use && !try_module_get(log_type->type->module))
- log_type = NULL;
- else
- log_type->use++;
- }
+ if (log_type && !try_module_get(log_type->module))
+ log_type = NULL;
spin_unlock(&_lock);
@@ -76,14 +65,14 @@ static struct dm_dirty_log_internal *_get_dirty_log_type(const char *name)
static struct dm_dirty_log_type *get_type(const char *type_name)
{
char *p, *type_name_dup;
- struct dm_dirty_log_internal *log_type;
+ struct dm_dirty_log_type *log_type;
if (!type_name)
return NULL;
log_type = _get_dirty_log_type(type_name);
if (log_type)
- return log_type->type;
+ return log_type;
type_name_dup = kstrdup(type_name, GFP_KERNEL);
if (!type_name_dup) {
@@ -105,56 +94,33 @@ static struct dm_dirty_log_type *get_type(const char *type_name)
kfree(type_name_dup);
- return log_type ? log_type->type : NULL;
+ return log_type;
}
static void put_type(struct dm_dirty_log_type *type)
{
- struct dm_dirty_log_internal *log_type;
-
if (!type)
return;
spin_lock(&_lock);
- log_type = __find_dirty_log_type(type->name);
- if (!log_type)
+ if (!__find_dirty_log_type(type->name))
goto out;
- if (!--log_type->use)
- module_put(type->module);
-
- BUG_ON(log_type->use < 0);
+ module_put(type->module);
out:
spin_unlock(&_lock);
}
-static struct dm_dirty_log_internal *_alloc_dirty_log_type(struct dm_dirty_log_type *type)
-{
- struct dm_dirty_log_internal *log_type = kzalloc(sizeof(*log_type),
- GFP_KERNEL);
-
- if (log_type)
- log_type->type = type;
-
- return log_type;
-}
-
int dm_dirty_log_type_register(struct dm_dirty_log_type *type)
{
- struct dm_dirty_log_internal *log_type = _alloc_dirty_log_type(type);
int r = 0;
- if (!log_type)
- return -ENOMEM;
-
spin_lock(&_lock);
if (!__find_dirty_log_type(type->name))
- list_add(&log_type->list, &_log_types);
- else {
- kfree(log_type);
+ list_add(&type->list, &_log_types);
+ else
r = -EEXIST;
- }
spin_unlock(&_lock);
return r;
@@ -163,25 +129,16 @@ EXPORT_SYMBOL(dm_dirty_log_type_register);
int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type)
{
- struct dm_dirty_log_internal *log_type;
-
spin_lock(&_lock);
- log_type = __find_dirty_log_type(type->name);
- if (!log_type) {
+ if (!__find_dirty_log_type(type->name)) {
spin_unlock(&_lock);
return -EINVAL;
}
- if (log_type->use) {
- spin_unlock(&_lock);
- return -ETXTBSY;
- }
-
- list_del(&log_type->list);
+ list_del(&type->list);
spin_unlock(&_lock);
- kfree(log_type);
return 0;
}
diff --git a/drivers/md/dm-path-selector.c b/drivers/md/dm-path-selector.c
index 96ea226155b1..42c04f04a0c4 100644
--- a/drivers/md/dm-path-selector.c
+++ b/drivers/md/dm-path-selector.c
@@ -17,9 +17,7 @@
struct ps_internal {
struct path_selector_type pst;
-
struct list_head list;
- long use;
};
#define pst_to_psi(__pst) container_of((__pst), struct ps_internal, pst)
@@ -45,12 +43,8 @@ static struct ps_internal *get_path_selector(const char *name)
down_read(&_ps_lock);
psi = __find_path_selector_type(name);
- if (psi) {
- if ((psi->use == 0) && !try_module_get(psi->pst.module))
- psi = NULL;
- else
- psi->use++;
- }
+ if (psi && !try_module_get(psi->pst.module))
+ psi = NULL;
up_read(&_ps_lock);
return psi;
@@ -84,11 +78,7 @@ void dm_put_path_selector(struct path_selector_type *pst)
if (!psi)
goto out;
- if (--psi->use == 0)
- module_put(psi->pst.module);
-
- BUG_ON(psi->use < 0);
-
+ module_put(psi->pst.module);
out:
up_read(&_ps_lock);
}
@@ -136,11 +126,6 @@ int dm_unregister_path_selector(struct path_selector_type *pst)
return -EINVAL;
}
- if (psi->use) {
- up_write(&_ps_lock);
- return -ETXTBSY;
- }
-
list_del(&psi->list);
up_write(&_ps_lock);
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 4d6bc101962e..536ef0bef154 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -145,6 +145,8 @@ struct dm_raid1_read_record {
struct dm_bio_details details;
};
+static struct kmem_cache *_dm_raid1_read_record_cache;
+
/*
* Every mirror should look like this one.
*/
@@ -586,6 +588,9 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
int state;
struct bio *bio;
struct bio_list sync, nosync, recover, *this_list = NULL;
+ struct bio_list requeue;
+ struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
+ region_t region;
if (!writes->head)
return;
@@ -596,10 +601,18 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
bio_list_init(&sync);
bio_list_init(&nosync);
bio_list_init(&recover);
+ bio_list_init(&requeue);
while ((bio = bio_list_pop(writes))) {
- state = dm_rh_get_state(ms->rh,
- dm_rh_bio_to_region(ms->rh, bio), 1);
+ region = dm_rh_bio_to_region(ms->rh, bio);
+
+ if (log->type->is_remote_recovering &&
+ log->type->is_remote_recovering(log, region)) {
+ bio_list_add(&requeue, bio);
+ continue;
+ }
+
+ state = dm_rh_get_state(ms->rh, region, 1);
switch (state) {
case DM_RH_CLEAN:
case DM_RH_DIRTY:
@@ -619,6 +632,16 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
}
/*
+ * Add bios that are delayed due to remote recovery
+ * back on to the write queue
+ */
+ if (unlikely(requeue.head)) {
+ spin_lock_irq(&ms->lock);
+ bio_list_merge(&ms->writes, &requeue);
+ spin_unlock_irq(&ms->lock);
+ }
+
+ /*
* Increment the pending counts for any regions that will
* be written to (writes to recover regions are going to
* be delayed).
@@ -764,9 +787,9 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors,
atomic_set(&ms->suspend, 0);
atomic_set(&ms->default_mirror, DEFAULT_MIRROR);
- len = sizeof(struct dm_raid1_read_record);
- ms->read_record_pool = mempool_create_kmalloc_pool(MIN_READ_RECORDS,
- len);
+ ms->read_record_pool = mempool_create_slab_pool(MIN_READ_RECORDS,
+ _dm_raid1_read_record_cache);
+
if (!ms->read_record_pool) {
ti->error = "Error creating mirror read_record_pool";
kfree(ms);
@@ -1279,16 +1302,31 @@ static int __init dm_mirror_init(void)
{
int r;
+ _dm_raid1_read_record_cache = KMEM_CACHE(dm_raid1_read_record, 0);
+ if (!_dm_raid1_read_record_cache) {
+ DMERR("Can't allocate dm_raid1_read_record cache");
+ r = -ENOMEM;
+ goto bad_cache;
+ }
+
r = dm_register_target(&mirror_target);
- if (r < 0)
+ if (r < 0) {
DMERR("Failed to register mirror target");
+ goto bad_target;
+ }
+
+ return 0;
+bad_target:
+ kmem_cache_destroy(_dm_raid1_read_record_cache);
+bad_cache:
return r;
}
static void __exit dm_mirror_exit(void)
{
dm_unregister_target(&mirror_target);
+ kmem_cache_destroy(_dm_raid1_read_record_cache);
}
/* Module hooks */
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index 936b34e0959f..e75c6dd76a9a 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -6,7 +6,6 @@
*/
#include "dm-exception-store.h"
-#include "dm-snap.h"
#include <linux/mm.h>
#include <linux/pagemap.h>
@@ -89,7 +88,7 @@ struct commit_callback {
* The top level structure for a persistent exception store.
*/
struct pstore {
- struct dm_snapshot *snap; /* up pointer to my snapshot */
+ struct dm_exception_store *store;
int version;
int valid;
uint32_t exceptions_per_area;
@@ -141,7 +140,7 @@ static int alloc_area(struct pstore *ps)
int r = -ENOMEM;
size_t len;
- len = ps->snap->chunk_size << SECTOR_SHIFT;
+ len = ps->store->chunk_size << SECTOR_SHIFT;
/*
* Allocate the chunk_size block of memory that will hold
@@ -163,9 +162,12 @@ static int alloc_area(struct pstore *ps)
static void free_area(struct pstore *ps)
{
- vfree(ps->area);
+ if (ps->area)
+ vfree(ps->area);
ps->area = NULL;
- vfree(ps->zero_area);
+
+ if (ps->zero_area)
+ vfree(ps->zero_area);
ps->zero_area = NULL;
}
@@ -189,9 +191,9 @@ static void do_metadata(struct work_struct *work)
static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata)
{
struct dm_io_region where = {
- .bdev = ps->snap->cow->bdev,
- .sector = ps->snap->chunk_size * chunk,
- .count = ps->snap->chunk_size,
+ .bdev = ps->store->cow->bdev,
+ .sector = ps->store->chunk_size * chunk,
+ .count = ps->store->chunk_size,
};
struct dm_io_request io_req = {
.bi_rw = rw,
@@ -247,15 +249,15 @@ static int area_io(struct pstore *ps, int rw)
static void zero_memory_area(struct pstore *ps)
{
- memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
+ memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT);
}
static int zero_disk_area(struct pstore *ps, chunk_t area)
{
struct dm_io_region where = {
- .bdev = ps->snap->cow->bdev,
- .sector = ps->snap->chunk_size * area_location(ps, area),
- .count = ps->snap->chunk_size,
+ .bdev = ps->store->cow->bdev,
+ .sector = ps->store->chunk_size * area_location(ps, area),
+ .count = ps->store->chunk_size,
};
struct dm_io_request io_req = {
.bi_rw = WRITE,
@@ -278,15 +280,15 @@ static int read_header(struct pstore *ps, int *new_snapshot)
/*
* Use default chunk size (or hardsect_size, if larger) if none supplied
*/
- if (!ps->snap->chunk_size) {
- ps->snap->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
- bdev_hardsect_size(ps->snap->cow->bdev) >> 9);
- ps->snap->chunk_mask = ps->snap->chunk_size - 1;
- ps->snap->chunk_shift = ffs(ps->snap->chunk_size) - 1;
+ if (!ps->store->chunk_size) {
+ ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
+ bdev_hardsect_size(ps->store->cow->bdev) >> 9);
+ ps->store->chunk_mask = ps->store->chunk_size - 1;
+ ps->store->chunk_shift = ffs(ps->store->chunk_size) - 1;
chunk_size_supplied = 0;
}
- ps->io_client = dm_io_client_create(sectors_to_pages(ps->snap->
+ ps->io_client = dm_io_client_create(sectors_to_pages(ps->store->
chunk_size));
if (IS_ERR(ps->io_client))
return PTR_ERR(ps->io_client);
@@ -317,22 +319,22 @@ static int read_header(struct pstore *ps, int *new_snapshot)
ps->version = le32_to_cpu(dh->version);
chunk_size = le32_to_cpu(dh->chunk_size);
- if (!chunk_size_supplied || ps->snap->chunk_size == chunk_size)
+ if (!chunk_size_supplied || ps->store->chunk_size == chunk_size)
return 0;
DMWARN("chunk size %llu in device metadata overrides "
"table chunk size of %llu.",
(unsigned long long)chunk_size,
- (unsigned long long)ps->snap->chunk_size);
+ (unsigned long long)ps->store->chunk_size);
/* We had a bogus chunk_size. Fix stuff up. */
free_area(ps);
- ps->snap->chunk_size = chunk_size;
- ps->snap->chunk_mask = chunk_size - 1;
- ps->snap->chunk_shift = ffs(chunk_size) - 1;
+ ps->store->chunk_size = chunk_size;
+ ps->store->chunk_mask = chunk_size - 1;
+ ps->store->chunk_shift = ffs(chunk_size) - 1;
- r = dm_io_client_resize(sectors_to_pages(ps->snap->chunk_size),
+ r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size),
ps->io_client);
if (r)
return r;
@@ -349,13 +351,13 @@ static int write_header(struct pstore *ps)
{
struct disk_header *dh;
- memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
+ memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT);
dh = (struct disk_header *) ps->area;
dh->magic = cpu_to_le32(SNAP_MAGIC);
dh->valid = cpu_to_le32(ps->valid);
dh->version = cpu_to_le32(ps->version);
- dh->chunk_size = cpu_to_le32(ps->snap->chunk_size);
+ dh->chunk_size = cpu_to_le32(ps->store->chunk_size);
return chunk_io(ps, 0, WRITE, 1);
}
@@ -474,18 +476,25 @@ static struct pstore *get_info(struct dm_exception_store *store)
static void persistent_fraction_full(struct dm_exception_store *store,
sector_t *numerator, sector_t *denominator)
{
- *numerator = get_info(store)->next_free * store->snap->chunk_size;
- *denominator = get_dev_size(store->snap->cow->bdev);
+ *numerator = get_info(store)->next_free * store->chunk_size;
+ *denominator = get_dev_size(store->cow->bdev);
}
-static void persistent_destroy(struct dm_exception_store *store)
+static void persistent_dtr(struct dm_exception_store *store)
{
struct pstore *ps = get_info(store);
destroy_workqueue(ps->metadata_wq);
- dm_io_client_destroy(ps->io_client);
- vfree(ps->callbacks);
+
+ /* Created in read_header */
+ if (ps->io_client)
+ dm_io_client_destroy(ps->io_client);
free_area(ps);
+
+ /* Allocated in persistent_read_metadata */
+ if (ps->callbacks)
+ vfree(ps->callbacks);
+
kfree(ps);
}
@@ -507,7 +516,7 @@ static int persistent_read_metadata(struct dm_exception_store *store,
/*
* Now we know correct chunk_size, complete the initialisation.
*/
- ps->exceptions_per_area = (ps->snap->chunk_size << SECTOR_SHIFT) /
+ ps->exceptions_per_area = (ps->store->chunk_size << SECTOR_SHIFT) /
sizeof(struct disk_exception);
ps->callbacks = dm_vcalloc(ps->exceptions_per_area,
sizeof(*ps->callbacks));
@@ -564,10 +573,10 @@ static int persistent_prepare_exception(struct dm_exception_store *store,
struct pstore *ps = get_info(store);
uint32_t stride;
chunk_t next_free;
- sector_t size = get_dev_size(store->snap->cow->bdev);
+ sector_t size = get_dev_size(store->cow->bdev);
/* Is there enough room ? */
- if (size < ((ps->next_free + 1) * store->snap->chunk_size))
+ if (size < ((ps->next_free + 1) * store->chunk_size))
return -ENOSPC;
e->new_chunk = ps->next_free;
@@ -656,16 +665,17 @@ static void persistent_drop_snapshot(struct dm_exception_store *store)
DMWARN("write header failed");
}
-int dm_create_persistent(struct dm_exception_store *store)
+static int persistent_ctr(struct dm_exception_store *store,
+ unsigned argc, char **argv)
{
struct pstore *ps;
/* allocate the pstore */
- ps = kmalloc(sizeof(*ps), GFP_KERNEL);
+ ps = kzalloc(sizeof(*ps), GFP_KERNEL);
if (!ps)
return -ENOMEM;
- ps->snap = store->snap;
+ ps->store = store;
ps->valid = 1;
ps->version = SNAPSHOT_DISK_VERSION;
ps->area = NULL;
@@ -683,22 +693,77 @@ int dm_create_persistent(struct dm_exception_store *store)
return -ENOMEM;
}
- store->destroy = persistent_destroy;
- store->read_metadata = persistent_read_metadata;
- store->prepare_exception = persistent_prepare_exception;
- store->commit_exception = persistent_commit_exception;
- store->drop_snapshot = persistent_drop_snapshot;
- store->fraction_full = persistent_fraction_full;
store->context = ps;
return 0;
}
+static unsigned persistent_status(struct dm_exception_store *store,
+ status_type_t status, char *result,
+ unsigned maxlen)
+{
+ unsigned sz = 0;
+
+ switch (status) {
+ case STATUSTYPE_INFO:
+ break;
+ case STATUSTYPE_TABLE:
+ DMEMIT(" %s P %llu", store->cow->name,
+ (unsigned long long)store->chunk_size);
+ }
+
+ return sz;
+}
+
+static struct dm_exception_store_type _persistent_type = {
+ .name = "persistent",
+ .module = THIS_MODULE,
+ .ctr = persistent_ctr,
+ .dtr = persistent_dtr,
+ .read_metadata = persistent_read_metadata,
+ .prepare_exception = persistent_prepare_exception,
+ .commit_exception = persistent_commit_exception,
+ .drop_snapshot = persistent_drop_snapshot,
+ .fraction_full = persistent_fraction_full,
+ .status = persistent_status,
+};
+
+static struct dm_exception_store_type _persistent_compat_type = {
+ .name = "P",
+ .module = THIS_MODULE,
+ .ctr = persistent_ctr,
+ .dtr = persistent_dtr,
+ .read_metadata = persistent_read_metadata,
+ .prepare_exception = persistent_prepare_exception,
+ .commit_exception = persistent_commit_exception,
+ .drop_snapshot = persistent_drop_snapshot,
+ .fraction_full = persistent_fraction_full,
+ .status = persistent_status,
+};
+
int dm_persistent_snapshot_init(void)
{
- return 0;
+ int r;
+
+ r = dm_exception_store_type_register(&_persistent_type);
+ if (r) {
+ DMERR("Unable to register persistent exception store type");
+ return r;
+ }
+
+ r = dm_exception_store_type_register(&_persistent_compat_type);
+ if (r) {
+ DMERR("Unable to register old-style persistent exception "
+ "store type");
+ dm_exception_store_type_unregister(&_persistent_type);
+ return r;
+ }
+
+ return r;
}
void dm_persistent_snapshot_exit(void)
{
+ dm_exception_store_type_unregister(&_persistent_type);
+ dm_exception_store_type_unregister(&_persistent_compat_type);
}
diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c
index 7f6e2e6dcb0d..cde5aa558e6d 100644
--- a/drivers/md/dm-snap-transient.c
+++ b/drivers/md/dm-snap-transient.c
@@ -6,7 +6,6 @@
*/
#include "dm-exception-store.h"
-#include "dm-snap.h"
#include <linux/mm.h>
#include <linux/pagemap.h>
@@ -23,7 +22,7 @@ struct transient_c {
sector_t next_free;
};
-static void transient_destroy(struct dm_exception_store *store)
+static void transient_dtr(struct dm_exception_store *store)
{
kfree(store->context);
}
@@ -39,14 +38,14 @@ static int transient_read_metadata(struct dm_exception_store *store,
static int transient_prepare_exception(struct dm_exception_store *store,
struct dm_snap_exception *e)
{
- struct transient_c *tc = (struct transient_c *) store->context;
- sector_t size = get_dev_size(store->snap->cow->bdev);
+ struct transient_c *tc = store->context;
+ sector_t size = get_dev_size(store->cow->bdev);
- if (size < (tc->next_free + store->snap->chunk_size))
+ if (size < (tc->next_free + store->chunk_size))
return -1;
- e->new_chunk = sector_to_chunk(store->snap, tc->next_free);
- tc->next_free += store->snap->chunk_size;
+ e->new_chunk = sector_to_chunk(store, tc->next_free);
+ tc->next_free += store->chunk_size;
return 0;
}
@@ -64,20 +63,14 @@ static void transient_fraction_full(struct dm_exception_store *store,
sector_t *numerator, sector_t *denominator)
{
*numerator = ((struct transient_c *) store->context)->next_free;
- *denominator = get_dev_size(store->snap->cow->bdev);
+ *denominator = get_dev_size(store->cow->bdev);
}
-int dm_create_transient(struct dm_exception_store *store)
+static int transient_ctr(struct dm_exception_store *store,
+ unsigned argc, char **argv)
{
struct transient_c *tc;
- store->destroy = transient_destroy;
- store->read_metadata = transient_read_metadata;
- store->prepare_exception = transient_prepare_exception;
- store->commit_exception = transient_commit_exception;
- store->drop_snapshot = NULL;
- store->fraction_full = transient_fraction_full;
-
tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL);
if (!tc)
return -ENOMEM;
@@ -88,11 +81,70 @@ int dm_create_transient(struct dm_exception_store *store)
return 0;
}
+static unsigned transient_status(struct dm_exception_store *store,
+ status_type_t status, char *result,
+ unsigned maxlen)
+{
+ unsigned sz = 0;
+
+ switch (status) {
+ case STATUSTYPE_INFO:
+ break;
+ case STATUSTYPE_TABLE:
+ DMEMIT(" %s N %llu", store->cow->name,
+ (unsigned long long)store->chunk_size);
+ }
+
+ return sz;
+}
+
+static struct dm_exception_store_type _transient_type = {
+ .name = "transient",
+ .module = THIS_MODULE,
+ .ctr = transient_ctr,
+ .dtr = transient_dtr,
+ .read_metadata = transient_read_metadata,
+ .prepare_exception = transient_prepare_exception,
+ .commit_exception = transient_commit_exception,
+ .fraction_full = transient_fraction_full,
+ .status = transient_status,
+};
+
+static struct dm_exception_store_type _transient_compat_type = {
+ .name = "N",
+ .module = THIS_MODULE,
+ .ctr = transient_ctr,
+ .dtr = transient_dtr,
+ .read_metadata = transient_read_metadata,
+ .prepare_exception = transient_prepare_exception,
+ .commit_exception = transient_commit_exception,
+ .fraction_full = transient_fraction_full,
+ .status = transient_status,
+};
+
int dm_transient_snapshot_init(void)
{
- return 0;
+ int r;
+
+ r = dm_exception_store_type_register(&_transient_type);
+ if (r) {
+ DMWARN("Unable to register transient exception store type");
+ return r;
+ }
+
+ r = dm_exception_store_type_register(&_transient_compat_type);
+ if (r) {
+ DMWARN("Unable to register old-style transient "
+ "exception store type");
+ dm_exception_store_type_unregister(&_transient_type);
+ return r;
+ }
+
+ return r;
}
void dm_transient_snapshot_exit(void)
{
+ dm_exception_store_type_unregister(&_transient_type);
+ dm_exception_store_type_unregister(&_transient_compat_type);
}
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 65ff82ff124e..981a0413068f 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -7,7 +7,6 @@
*/
#include <linux/blkdev.h>
-#include <linux/ctype.h>
#include <linux/device-mapper.h>
#include <linux/delay.h>
#include <linux/fs.h>
@@ -20,9 +19,9 @@
#include <linux/vmalloc.h>
#include <linux/log2.h>
#include <linux/dm-kcopyd.h>
+#include <linux/workqueue.h>
#include "dm-exception-store.h"
-#include "dm-snap.h"
#include "dm-bio-list.h"
#define DM_MSG_PREFIX "snapshots"
@@ -47,9 +46,76 @@
*/
#define MIN_IOS 256
+#define DM_TRACKED_CHUNK_HASH_SIZE 16
+#define DM_TRACKED_CHUNK_HASH(x) ((unsigned long)(x) & \
+ (DM_TRACKED_CHUNK_HASH_SIZE - 1))
+
+struct exception_table {
+ uint32_t hash_mask;
+ unsigned hash_shift;
+ struct list_head *table;
+};
+
+struct dm_snapshot {
+ struct rw_semaphore lock;
+
+ struct dm_dev *origin;
+
+ /* List of snapshots per Origin */
+ struct list_head list;
+
+ /* You can't use a snapshot if this is 0 (e.g. if full) */
+ int valid;
+
+ /* Origin writes don't trigger exceptions until this is set */
+ int active;
+
+ mempool_t *pending_pool;
+
+ atomic_t pending_exceptions_count;
+
+ struct exception_table pending;
+ struct exception_table complete;
+
+ /*
+ * pe_lock protects all pending_exception operations and access
+ * as well as the snapshot_bios list.
+ */
+ spinlock_t pe_lock;
+
+ /* The on disk metadata handler */
+ struct dm_exception_store *store;
+
+ struct dm_kcopyd_client *kcopyd_client;
+
+ /* Queue of snapshot writes for ksnapd to flush */
+ struct bio_list queued_bios;
+ struct work_struct queued_bios_work;
+
+ /* Chunks with outstanding reads */
+ mempool_t *tracked_chunk_pool;
+ spinlock_t tracked_chunk_lock;
+ struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
+};
+
static struct workqueue_struct *ksnapd;
static void flush_queued_bios(struct work_struct *work);
+static sector_t chunk_to_sector(struct dm_exception_store *store,
+ chunk_t chunk)
+{
+ return chunk << store->chunk_shift;
+}
+
+static int bdev_equal(struct block_device *lhs, struct block_device *rhs)
+{
+ /*
+ * There is only ever one instance of a particular block
+ * device so we can compare pointers safely.
+ */
+ return lhs == rhs;
+}
+
struct dm_snap_pending_exception {
struct dm_snap_exception e;
@@ -476,11 +542,11 @@ static int init_hash_tables(struct dm_snapshot *s)
* Calculate based on the size of the original volume or
* the COW volume...
*/
- cow_dev_size = get_dev_size(s->cow->bdev);
+ cow_dev_size = get_dev_size(s->store->cow->bdev);
origin_dev_size = get_dev_size(s->origin->bdev);
max_buckets = calc_max_buckets();
- hash_size = min(origin_dev_size, cow_dev_size) >> s->chunk_shift;
+ hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift;
hash_size = min(hash_size, max_buckets);
hash_size = rounddown_pow_of_two(hash_size);
@@ -505,58 +571,6 @@ static int init_hash_tables(struct dm_snapshot *s)
}
/*
- * Round a number up to the nearest 'size' boundary. size must
- * be a power of 2.
- */
-static ulong round_up(ulong n, ulong size)
-{
- size--;
- return (n + size) & ~size;
-}
-
-static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg,
- char **error)
-{
- unsigned long chunk_size;
- char *value;
-
- chunk_size = simple_strtoul(chunk_size_arg, &value, 10);
- if (*chunk_size_arg == '\0' || *value != '\0') {
- *error = "Invalid chunk size";
- return -EINVAL;
- }
-
- if (!chunk_size) {
- s->chunk_size = s->chunk_mask = s->chunk_shift = 0;
- return 0;
- }
-
- /*
- * Chunk size must be multiple of page size. Silently
- * round up if it's not.
- */
- chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
-
- /* Check chunk_size is a power of 2 */
- if (!is_power_of_2(chunk_size)) {
- *error = "Chunk size is not a power of 2";
- return -EINVAL;
- }
-
- /* Validate the chunk size against the device block size */
- if (chunk_size % (bdev_hardsect_size(s->cow->bdev) >> 9)) {
- *error = "Chunk size is not a multiple of device blocksize";
- return -EINVAL;
- }
-
- s->chunk_size = chunk_size;
- s->chunk_mask = chunk_size - 1;
- s->chunk_shift = ffs(chunk_size) - 1;
-
- return 0;
-}
-
-/*
* Construct a snapshot mapping: <origin_dev> <COW-dev> <p/n> <chunk-size>
*/
static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
@@ -564,91 +578,68 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
struct dm_snapshot *s;
int i;
int r = -EINVAL;
- char persistent;
char *origin_path;
- char *cow_path;
+ struct dm_exception_store *store;
+ unsigned args_used;
if (argc != 4) {
ti->error = "requires exactly 4 arguments";
r = -EINVAL;
- goto bad1;
+ goto bad_args;
}
origin_path = argv[0];
- cow_path = argv[1];
- persistent = toupper(*argv[2]);
+ argv++;
+ argc--;
- if (persistent != 'P' && persistent != 'N') {
- ti->error = "Persistent flag is not P or N";
+ r = dm_exception_store_create(ti, argc, argv, &args_used, &store);
+ if (r) {
+ ti->error = "Couldn't create exception store";
r = -EINVAL;
- goto bad1;
+ goto bad_args;
}
+ argv += args_used;
+ argc -= args_used;
+
s = kmalloc(sizeof(*s), GFP_KERNEL);
- if (s == NULL) {
+ if (!s) {
ti->error = "Cannot allocate snapshot context private "
"structure";
r = -ENOMEM;
- goto bad1;
+ goto bad_snap;
}
r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin);
if (r) {
ti->error = "Cannot get origin device";
- goto bad2;
- }
-
- r = dm_get_device(ti, cow_path, 0, 0,
- FMODE_READ | FMODE_WRITE, &s->cow);
- if (r) {
- dm_put_device(ti, s->origin);
- ti->error = "Cannot get COW device";
- goto bad2;
+ goto bad_origin;
}
- r = set_chunk_size(s, argv[3], &ti->error);
- if (r)
- goto bad3;
-
- s->type = persistent;
-
+ s->store = store;
s->valid = 1;
s->active = 0;
atomic_set(&s->pending_exceptions_count, 0);
init_rwsem(&s->lock);
spin_lock_init(&s->pe_lock);
- s->ti = ti;
/* Allocate hash table for COW data */
if (init_hash_tables(s)) {
ti->error = "Unable to allocate hash table space";
r = -ENOMEM;
- goto bad3;
- }
-
- s->store.snap = s;
-
- if (persistent == 'P')
- r = dm_create_persistent(&s->store);
- else
- r = dm_create_transient(&s->store);
-
- if (r) {
- ti->error = "Couldn't create exception store";
- r = -EINVAL;
- goto bad4;
+ goto bad_hash_tables;
}
r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client);
if (r) {
ti->error = "Could not create kcopyd client";
- goto bad5;
+ goto bad_kcopyd;
}
s->pending_pool = mempool_create_slab_pool(MIN_IOS, pending_cache);
if (!s->pending_pool) {
ti->error = "Could not allocate mempool for pending exceptions";
- goto bad6;
+ goto bad_pending_pool;
}
s->tracked_chunk_pool = mempool_create_slab_pool(MIN_IOS,
@@ -665,7 +656,8 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
spin_lock_init(&s->tracked_chunk_lock);
/* Metadata must only be loaded into one table at once */
- r = s->store.read_metadata(&s->store, dm_add_exception, (void *)s);
+ r = s->store->type->read_metadata(s->store, dm_add_exception,
+ (void *)s);
if (r < 0) {
ti->error = "Failed to read snapshot metadata";
goto bad_load_and_register;
@@ -686,34 +678,33 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
ti->private = s;
- ti->split_io = s->chunk_size;
+ ti->split_io = s->store->chunk_size;
return 0;
- bad_load_and_register:
+bad_load_and_register:
mempool_destroy(s->tracked_chunk_pool);
- bad_tracked_chunk_pool:
+bad_tracked_chunk_pool:
mempool_destroy(s->pending_pool);
- bad6:
+bad_pending_pool:
dm_kcopyd_client_destroy(s->kcopyd_client);
- bad5:
- s->store.destroy(&s->store);
-
- bad4:
+bad_kcopyd:
exit_exception_table(&s->pending, pending_cache);
exit_exception_table(&s->complete, exception_cache);
- bad3:
- dm_put_device(ti, s->cow);
+bad_hash_tables:
dm_put_device(ti, s->origin);
- bad2:
+bad_origin:
kfree(s);
- bad1:
+bad_snap:
+ dm_exception_store_destroy(store);
+
+bad_args:
return r;
}
@@ -724,8 +715,6 @@ static void __free_exceptions(struct dm_snapshot *s)
exit_exception_table(&s->pending, pending_cache);
exit_exception_table(&s->complete, exception_cache);
-
- s->store.destroy(&s->store);
}
static void snapshot_dtr(struct dm_target *ti)
@@ -761,7 +750,8 @@ static void snapshot_dtr(struct dm_target *ti)
mempool_destroy(s->pending_pool);
dm_put_device(ti, s->origin);
- dm_put_device(ti, s->cow);
+
+ dm_exception_store_destroy(s->store);
kfree(s);
}
@@ -820,12 +810,12 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err)
else if (err == -ENOMEM)
DMERR("Invalidating snapshot: Unable to allocate exception.");
- if (s->store.drop_snapshot)
- s->store.drop_snapshot(&s->store);
+ if (s->store->type->drop_snapshot)
+ s->store->type->drop_snapshot(s->store);
s->valid = 0;
- dm_table_event(s->ti->table);
+ dm_table_event(s->store->ti->table);
}
static void get_pending_exception(struct dm_snap_pending_exception *pe)
@@ -943,8 +933,8 @@ static void copy_callback(int read_err, unsigned long write_err, void *context)
else
/* Update the metadata if we are persistent */
- s->store.commit_exception(&s->store, &pe->e, commit_callback,
- pe);
+ s->store->type->commit_exception(s->store, &pe->e,
+ commit_callback, pe);
}
/*
@@ -960,11 +950,11 @@ static void start_copy(struct dm_snap_pending_exception *pe)
dev_size = get_dev_size(bdev);
src.bdev = bdev;
- src.sector = chunk_to_sector(s, pe->e.old_chunk);
- src.count = min(s->chunk_size, dev_size - src.sector);
+ src.sector = chunk_to_sector(s->store, pe->e.old_chunk);
+ src.count = min(s->store->chunk_size, dev_size - src.sector);
- dest.bdev = s->cow->bdev;
- dest.sector = chunk_to_sector(s, pe->e.new_chunk);
+ dest.bdev = s->store->cow->bdev;
+ dest.sector = chunk_to_sector(s->store, pe->e.new_chunk);
dest.count = src.count;
/* Hand over to kcopyd */
@@ -972,6 +962,17 @@ static void start_copy(struct dm_snap_pending_exception *pe)
&src, 1, &dest, 0, copy_callback, pe);
}
+static struct dm_snap_pending_exception *
+__lookup_pending_exception(struct dm_snapshot *s, chunk_t chunk)
+{
+ struct dm_snap_exception *e = lookup_exception(&s->pending, chunk);
+
+ if (!e)
+ return NULL;
+
+ return container_of(e, struct dm_snap_pending_exception, e);
+}
+
/*
* Looks to see if this snapshot already has a pending exception
* for this chunk, otherwise it allocates a new one and inserts
@@ -981,40 +982,15 @@ static void start_copy(struct dm_snap_pending_exception *pe)
* this.
*/
static struct dm_snap_pending_exception *
-__find_pending_exception(struct dm_snapshot *s, struct bio *bio)
+__find_pending_exception(struct dm_snapshot *s,
+ struct dm_snap_pending_exception *pe, chunk_t chunk)
{
- struct dm_snap_exception *e;
- struct dm_snap_pending_exception *pe;
- chunk_t chunk = sector_to_chunk(s, bio->bi_sector);
+ struct dm_snap_pending_exception *pe2;
- /*
- * Is there a pending exception for this already ?
- */
- e = lookup_exception(&s->pending, chunk);
- if (e) {
- /* cast the exception to a pending exception */
- pe = container_of(e, struct dm_snap_pending_exception, e);
- goto out;
- }
-
- /*
- * Create a new pending exception, we don't want
- * to hold the lock while we do this.
- */
- up_write(&s->lock);
- pe = alloc_pending_exception(s);
- down_write(&s->lock);
-
- if (!s->valid) {
- free_pending_exception(pe);
- return NULL;
- }
-
- e = lookup_exception(&s->pending, chunk);
- if (e) {
+ pe2 = __lookup_pending_exception(s, chunk);
+ if (pe2) {
free_pending_exception(pe);
- pe = container_of(e, struct dm_snap_pending_exception, e);
- goto out;
+ return pe2;
}
pe->e.old_chunk = chunk;
@@ -1024,7 +1000,7 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
atomic_set(&pe->ref_count, 0);
pe->started = 0;
- if (s->store.prepare_exception(&s->store, &pe->e)) {
+ if (s->store->type->prepare_exception(s->store, &pe->e)) {
free_pending_exception(pe);
return NULL;
}
@@ -1032,17 +1008,18 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
get_pending_exception(pe);
insert_exception(&s->pending, &pe->e);
- out:
return pe;
}
static void remap_exception(struct dm_snapshot *s, struct dm_snap_exception *e,
struct bio *bio, chunk_t chunk)
{
- bio->bi_bdev = s->cow->bdev;
- bio->bi_sector = chunk_to_sector(s, dm_chunk_number(e->new_chunk) +
- (chunk - e->old_chunk)) +
- (bio->bi_sector & s->chunk_mask);
+ bio->bi_bdev = s->store->cow->bdev;
+ bio->bi_sector = chunk_to_sector(s->store,
+ dm_chunk_number(e->new_chunk) +
+ (chunk - e->old_chunk)) +
+ (bio->bi_sector &
+ s->store->chunk_mask);
}
static int snapshot_map(struct dm_target *ti, struct bio *bio,
@@ -1054,7 +1031,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
chunk_t chunk;
struct dm_snap_pending_exception *pe = NULL;
- chunk = sector_to_chunk(s, bio->bi_sector);
+ chunk = sector_to_chunk(s->store, bio->bi_sector);
/* Full snapshots are not usable */
/* To get here the table must be live so s->active is always set. */
@@ -1083,11 +1060,31 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
* writeable.
*/
if (bio_rw(bio) == WRITE) {
- pe = __find_pending_exception(s, bio);
+ pe = __lookup_pending_exception(s, chunk);
if (!pe) {
- __invalidate_snapshot(s, -ENOMEM);
- r = -EIO;
- goto out_unlock;
+ up_write(&s->lock);
+ pe = alloc_pending_exception(s);
+ down_write(&s->lock);
+
+ if (!s->valid) {
+ free_pending_exception(pe);
+ r = -EIO;
+ goto out_unlock;
+ }
+
+ e = lookup_exception(&s->complete, chunk);
+ if (e) {
+ free_pending_exception(pe);
+ remap_exception(s, e, bio, chunk);
+ goto out_unlock;
+ }
+
+ pe = __find_pending_exception(s, pe, chunk);
+ if (!pe) {
+ __invalidate_snapshot(s, -ENOMEM);
+ r = -EIO;
+ goto out_unlock;
+ }
}
remap_exception(s, &pe->e, bio, chunk);
@@ -1137,24 +1134,25 @@ static void snapshot_resume(struct dm_target *ti)
static int snapshot_status(struct dm_target *ti, status_type_t type,
char *result, unsigned int maxlen)
{
+ unsigned sz = 0;
struct dm_snapshot *snap = ti->private;
switch (type) {
case STATUSTYPE_INFO:
if (!snap->valid)
- snprintf(result, maxlen, "Invalid");
+ DMEMIT("Invalid");
else {
- if (snap->store.fraction_full) {
+ if (snap->store->type->fraction_full) {
sector_t numerator, denominator;
- snap->store.fraction_full(&snap->store,
- &numerator,
- &denominator);
- snprintf(result, maxlen, "%llu/%llu",
- (unsigned long long)numerator,
- (unsigned long long)denominator);
+ snap->store->type->fraction_full(snap->store,
+ &numerator,
+ &denominator);
+ DMEMIT("%llu/%llu",
+ (unsigned long long)numerator,
+ (unsigned long long)denominator);
}
else
- snprintf(result, maxlen, "Unknown");
+ DMEMIT("Unknown");
}
break;
@@ -1164,10 +1162,9 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
* to make private copies if the output is to
* make sense.
*/
- snprintf(result, maxlen, "%s %s %c %llu",
- snap->origin->name, snap->cow->name,
- snap->type,
- (unsigned long long)snap->chunk_size);
+ DMEMIT("%s", snap->origin->name);
+ snap->store->type->status(snap->store, type, result + sz,
+ maxlen - sz);
break;
}
@@ -1196,14 +1193,14 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
goto next_snapshot;
/* Nothing to do if writing beyond end of snapshot */
- if (bio->bi_sector >= dm_table_get_size(snap->ti->table))
+ if (bio->bi_sector >= dm_table_get_size(snap->store->ti->table))
goto next_snapshot;
/*
* Remember, different snapshots can have
* different chunk sizes.
*/
- chunk = sector_to_chunk(snap, bio->bi_sector);
+ chunk = sector_to_chunk(snap->store, bio->bi_sector);
/*
* Check exception table to see if block
@@ -1217,10 +1214,28 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
if (e)
goto next_snapshot;
- pe = __find_pending_exception(snap, bio);
+ pe = __lookup_pending_exception(snap, chunk);
if (!pe) {
- __invalidate_snapshot(snap, -ENOMEM);
- goto next_snapshot;
+ up_write(&snap->lock);
+ pe = alloc_pending_exception(snap);
+ down_write(&snap->lock);
+
+ if (!snap->valid) {
+ free_pending_exception(pe);
+ goto next_snapshot;
+ }
+
+ e = lookup_exception(&snap->complete, chunk);
+ if (e) {
+ free_pending_exception(pe);
+ goto next_snapshot;
+ }
+
+ pe = __find_pending_exception(snap, pe, chunk);
+ if (!pe) {
+ __invalidate_snapshot(snap, -ENOMEM);
+ goto next_snapshot;
+ }
}
if (!primary_pe) {
@@ -1360,7 +1375,8 @@ static void origin_resume(struct dm_target *ti)
o = __lookup_origin(dev->bdev);
if (o)
list_for_each_entry (snap, &o->snapshots, list)
- chunk_size = min_not_zero(chunk_size, snap->chunk_size);
+ chunk_size = min_not_zero(chunk_size,
+ snap->store->chunk_size);
up_read(&_origins_lock);
ti->split_io = chunk_size;
diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h
deleted file mode 100644
index d9e62b43cf85..000000000000
--- a/drivers/md/dm-snap.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
- *
- * This file is released under the GPL.
- */
-
-#ifndef DM_SNAPSHOT_H
-#define DM_SNAPSHOT_H
-
-#include <linux/device-mapper.h>
-#include "dm-exception-store.h"
-#include "dm-bio-list.h"
-#include <linux/blkdev.h>
-#include <linux/workqueue.h>
-
-struct exception_table {
- uint32_t hash_mask;
- unsigned hash_shift;
- struct list_head *table;
-};
-
-#define DM_TRACKED_CHUNK_HASH_SIZE 16
-#define DM_TRACKED_CHUNK_HASH(x) ((unsigned long)(x) & \
- (DM_TRACKED_CHUNK_HASH_SIZE - 1))
-
-struct dm_snapshot {
- struct rw_semaphore lock;
- struct dm_target *ti;
-
- struct dm_dev *origin;
- struct dm_dev *cow;
-
- /* List of snapshots per Origin */
- struct list_head list;
-
- /* Size of data blocks saved - must be a power of 2 */
- chunk_t chunk_size;
- chunk_t chunk_mask;
- chunk_t chunk_shift;
-
- /* You can't use a snapshot if this is 0 (e.g. if full) */
- int valid;
-
- /* Origin writes don't trigger exceptions until this is set */
- int active;
-
- /* Used for display of table */
- char type;
-
- mempool_t *pending_pool;
-
- atomic_t pending_exceptions_count;
-
- struct exception_table pending;
- struct exception_table complete;
-
- /*
- * pe_lock protects all pending_exception operations and access
- * as well as the snapshot_bios list.
- */
- spinlock_t pe_lock;
-
- /* The on disk metadata handler */
- struct dm_exception_store store;
-
- struct dm_kcopyd_client *kcopyd_client;
-
- /* Queue of snapshot writes for ksnapd to flush */
- struct bio_list queued_bios;
- struct work_struct queued_bios_work;
-
- /* Chunks with outstanding reads */
- mempool_t *tracked_chunk_pool;
- spinlock_t tracked_chunk_lock;
- struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
-};
-
-/*
- * Return the number of sectors in the device.
- */
-static inline sector_t get_dev_size(struct block_device *bdev)
-{
- return bdev->bd_inode->i_size >> SECTOR_SHIFT;
-}
-
-static inline chunk_t sector_to_chunk(struct dm_snapshot *s, sector_t sector)
-{
- return (sector & ~s->chunk_mask) >> s->chunk_shift;
-}
-
-static inline sector_t chunk_to_sector(struct dm_snapshot *s, chunk_t chunk)
-{
- return chunk << s->chunk_shift;
-}
-
-static inline int bdev_equal(struct block_device *lhs, struct block_device *rhs)
-{
- /*
- * There is only ever one instance of a particular block
- * device so we can compare pointers safely.
- */
- return lhs == rhs;
-}
-
-#endif
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 2fd66c30f7f8..e8361b191b9b 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -399,28 +399,30 @@ static int check_device_area(struct dm_dev_internal *dd, sector_t start,
}
/*
- * This upgrades the mode on an already open dm_dev. Being
+ * This upgrades the mode on an already open dm_dev, being
* careful to leave things as they were if we fail to reopen the
- * device.
+ * device and not to touch the existing bdev field in case
+ * it is accessed concurrently inside dm_table_any_congested().
*/
static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode,
struct mapped_device *md)
{
int r;
- struct dm_dev_internal dd_copy;
- dev_t dev = dd->dm_dev.bdev->bd_dev;
+ struct dm_dev_internal dd_new, dd_old;
- dd_copy = *dd;
+ dd_new = dd_old = *dd;
+
+ dd_new.dm_dev.mode |= new_mode;
+ dd_new.dm_dev.bdev = NULL;
+
+ r = open_dev(&dd_new, dd->dm_dev.bdev->bd_dev, md);
+ if (r)
+ return r;
dd->dm_dev.mode |= new_mode;
- dd->dm_dev.bdev = NULL;
- r = open_dev(dd, dev, md);
- if (!r)
- close_dev(&dd_copy, md);
- else
- *dd = dd_copy;
+ close_dev(&dd_old, md);
- return r;
+ return 0;
}
/*
diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c
index 7decf10006e4..04feccf2a997 100644
--- a/drivers/md/dm-target.c
+++ b/drivers/md/dm-target.c
@@ -14,45 +14,34 @@
#define DM_MSG_PREFIX "target"
-struct tt_internal {
- struct target_type tt;
-
- struct list_head list;
- long use;
-};
-
static LIST_HEAD(_targets);
static DECLARE_RWSEM(_lock);
#define DM_MOD_NAME_SIZE 32
-static inline struct tt_internal *__find_target_type(const char *name)
+static inline struct target_type *__find_target_type(const char *name)
{
- struct tt_internal *ti;
+ struct target_type *tt;
- list_for_each_entry (ti, &_targets, list)
- if (!strcmp(name, ti->tt.name))
- return ti;
+ list_for_each_entry(tt, &_targets, list)
+ if (!strcmp(name, tt->name))
+ return tt;
return NULL;
}
-static struct tt_internal *get_target_type(const char *name)
+static struct target_type *get_target_type(const char *name)
{
- struct tt_internal *ti;
+ struct target_type *tt;
down_read(&_lock);
- ti = __find_target_type(name);
- if (ti) {
- if ((ti->use == 0) && !try_module_get(ti->tt.module))
- ti = NULL;
- else
- ti->use++;
- }
+ tt = __find_target_type(name);
+ if (tt && !try_module_get(tt->module))
+ tt = NULL;
up_read(&_lock);
- return ti;
+ return tt;
}
static void load_module(const char *name)
@@ -62,92 +51,59 @@ static void load_module(const char *name)
struct target_type *dm_get_target_type(const char *name)
{
- struct tt_internal *ti = get_target_type(name);
+ struct target_type *tt = get_target_type(name);
- if (!ti) {
+ if (!tt) {
load_module(name);
- ti = get_target_type(name);
+ tt = get_target_type(name);
}
- return ti ? &ti->tt : NULL;
+ return tt;
}
-void dm_put_target_type(struct target_type *t)
+void dm_put_target_type(struct target_type *tt)
{
- struct tt_internal *ti = (struct tt_internal *) t;
-
down_read(&_lock);
- if (--ti->use == 0)
- module_put(ti->tt.module);
-
- BUG_ON(ti->use < 0);
+ module_put(tt->module);
up_read(&_lock);
-
- return;
-}
-
-static struct tt_internal *alloc_target(struct target_type *t)
-{
- struct tt_internal *ti = kzalloc(sizeof(*ti), GFP_KERNEL);
-
- if (ti)
- ti->tt = *t;
-
- return ti;
}
-
int dm_target_iterate(void (*iter_func)(struct target_type *tt,
void *param), void *param)
{
- struct tt_internal *ti;
+ struct target_type *tt;
down_read(&_lock);
- list_for_each_entry (ti, &_targets, list)
- iter_func(&ti->tt, param);
+ list_for_each_entry(tt, &_targets, list)
+ iter_func(tt, param);
up_read(&_lock);
return 0;
}
-int dm_register_target(struct target_type *t)
+int dm_register_target(struct target_type *tt)
{
int rv = 0;
- struct tt_internal *ti = alloc_target(t);
-
- if (!ti)
- return -ENOMEM;
down_write(&_lock);
- if (__find_target_type(t->name))
+ if (__find_target_type(tt->name))
rv = -EEXIST;
else
- list_add(&ti->list, &_targets);
+ list_add(&tt->list, &_targets);
up_write(&_lock);
- if (rv)
- kfree(ti);
return rv;
}
-void dm_unregister_target(struct target_type *t)
+void dm_unregister_target(struct target_type *tt)
{
- struct tt_internal *ti;
-
down_write(&_lock);
- if (!(ti = __find_target_type(t->name))) {
- DMCRIT("Unregistering unrecognised target: %s", t->name);
- BUG();
- }
-
- if (ti->use) {
- DMCRIT("Attempt to unregister target still in use: %s",
- t->name);
+ if (!__find_target_type(tt->name)) {
+ DMCRIT("Unregistering unrecognised target: %s", tt->name);
BUG();
}
- list_del(&ti->list);
- kfree(ti);
+ list_del(&tt->list);
up_write(&_lock);
}
@@ -156,17 +112,17 @@ void dm_unregister_target(struct target_type *t)
* io-err: always fails an io, useful for bringing
* up LVs that have holes in them.
*/
-static int io_err_ctr(struct dm_target *ti, unsigned int argc, char **args)
+static int io_err_ctr(struct dm_target *tt, unsigned int argc, char **args)
{
return 0;
}
-static void io_err_dtr(struct dm_target *ti)
+static void io_err_dtr(struct dm_target *tt)
{
/* empty */
}
-static int io_err_map(struct dm_target *ti, struct bio *bio,
+static int io_err_map(struct dm_target *tt, struct bio *bio,
union map_info *map_context)
{
return -EIO;
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 8d40f27cce89..788ba96a6256 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -99,19 +99,9 @@ union map_info *dm_get_mapinfo(struct bio *bio)
/*
* Work processed by per-device workqueue.
*/
-struct dm_wq_req {
- enum {
- DM_WQ_FLUSH_DEFERRED,
- } type;
- struct work_struct work;
- struct mapped_device *md;
- void *context;
-};
-
struct mapped_device {
struct rw_semaphore io_lock;
struct mutex suspend_lock;
- spinlock_t pushback_lock;
rwlock_t map_lock;
atomic_t holders;
atomic_t open_count;
@@ -129,8 +119,9 @@ struct mapped_device {
*/
atomic_t pending;
wait_queue_head_t wait;
+ struct work_struct work;
struct bio_list deferred;
- struct bio_list pushback;
+ spinlock_t deferred_lock;
/*
* Processing queue (flush/barriers)
@@ -453,7 +444,9 @@ static int queue_io(struct mapped_device *md, struct bio *bio)
return 1;
}
+ spin_lock_irq(&md->deferred_lock);
bio_list_add(&md->deferred, bio);
+ spin_unlock_irq(&md->deferred_lock);
up_write(&md->io_lock);
return 0; /* deferred successfully */
@@ -537,16 +530,14 @@ static void dec_pending(struct dm_io *io, int error)
if (io->error == DM_ENDIO_REQUEUE) {
/*
* Target requested pushing back the I/O.
- * This must be handled before the sleeper on
- * suspend queue merges the pushback list.
*/
- spin_lock_irqsave(&md->pushback_lock, flags);
+ spin_lock_irqsave(&md->deferred_lock, flags);
if (__noflush_suspending(md))
- bio_list_add(&md->pushback, io->bio);
+ bio_list_add(&md->deferred, io->bio);
else
/* noflush suspend was interrupted. */
io->error = -EIO;
- spin_unlock_irqrestore(&md->pushback_lock, flags);
+ spin_unlock_irqrestore(&md->deferred_lock, flags);
}
end_io_acct(io);
@@ -834,20 +825,22 @@ static int __clone_and_map(struct clone_info *ci)
}
/*
- * Split the bio into several clones.
+ * Split the bio into several clones and submit it to targets.
*/
-static int __split_bio(struct mapped_device *md, struct bio *bio)
+static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
{
struct clone_info ci;
int error = 0;
ci.map = dm_get_table(md);
- if (unlikely(!ci.map))
- return -EIO;
+ if (unlikely(!ci.map)) {
+ bio_io_error(bio);
+ return;
+ }
if (unlikely(bio_barrier(bio) && !dm_table_barrier_ok(ci.map))) {
dm_table_put(ci.map);
bio_endio(bio, -EOPNOTSUPP);
- return 0;
+ return;
}
ci.md = md;
ci.bio = bio;
@@ -867,8 +860,6 @@ static int __split_bio(struct mapped_device *md, struct bio *bio)
/* drop the extra reference count */
dec_pending(ci.io, error);
dm_table_put(ci.map);
-
- return 0;
}
/*-----------------------------------------------------------------
* CRUD END
@@ -959,8 +950,9 @@ static int dm_request(struct request_queue *q, struct bio *bio)
down_read(&md->io_lock);
}
- r = __split_bio(md, bio);
+ __split_and_process_bio(md, bio);
up_read(&md->io_lock);
+ return 0;
out_req:
if (r < 0)
@@ -1074,6 +1066,8 @@ out:
static struct block_device_operations dm_blk_dops;
+static void dm_wq_work(struct work_struct *work);
+
/*
* Allocate and initialise a blank device with a given minor.
*/
@@ -1101,7 +1095,7 @@ static struct mapped_device *alloc_dev(int minor)
init_rwsem(&md->io_lock);
mutex_init(&md->suspend_lock);
- spin_lock_init(&md->pushback_lock);
+ spin_lock_init(&md->deferred_lock);
rwlock_init(&md->map_lock);
atomic_set(&md->holders, 1);
atomic_set(&md->open_count, 0);
@@ -1118,6 +1112,7 @@ static struct mapped_device *alloc_dev(int minor)
md->queue->backing_dev_info.congested_fn = dm_any_congested;
md->queue->backing_dev_info.congested_data = md;
blk_queue_make_request(md->queue, dm_request);
+ blk_queue_ordered(md->queue, QUEUE_ORDERED_DRAIN, NULL);
blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
md->queue->unplug_fn = dm_unplug_all;
blk_queue_merge_bvec(md->queue, dm_merge_bvec);
@@ -1140,6 +1135,7 @@ static struct mapped_device *alloc_dev(int minor)
atomic_set(&md->pending, 0);
init_waitqueue_head(&md->wait);
+ INIT_WORK(&md->work, dm_wq_work);
init_waitqueue_head(&md->eventq);
md->disk->major = _major;
@@ -1379,18 +1375,24 @@ void dm_put(struct mapped_device *md)
}
EXPORT_SYMBOL_GPL(dm_put);
-static int dm_wait_for_completion(struct mapped_device *md)
+static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
{
int r = 0;
+ DECLARE_WAITQUEUE(wait, current);
+
+ dm_unplug_all(md->queue);
+
+ add_wait_queue(&md->wait, &wait);
while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
+ set_current_state(interruptible);
smp_mb();
if (!atomic_read(&md->pending))
break;
- if (signal_pending(current)) {
+ if (interruptible == TASK_INTERRUPTIBLE &&
+ signal_pending(current)) {
r = -EINTR;
break;
}
@@ -1399,67 +1401,40 @@ static int dm_wait_for_completion(struct mapped_device *md)
}
set_current_state(TASK_RUNNING);
+ remove_wait_queue(&md->wait, &wait);
+
return r;
}
/*
* Process the deferred bios
*/
-static void __flush_deferred_io(struct mapped_device *md)
+static void dm_wq_work(struct work_struct *work)
{
+ struct mapped_device *md = container_of(work, struct mapped_device,
+ work);
struct bio *c;
- while ((c = bio_list_pop(&md->deferred))) {
- if (__split_bio(md, c))
- bio_io_error(c);
- }
-
- clear_bit(DMF_BLOCK_IO, &md->flags);
-}
+ down_write(&md->io_lock);
-static void __merge_pushback_list(struct mapped_device *md)
-{
- unsigned long flags;
+next_bio:
+ spin_lock_irq(&md->deferred_lock);
+ c = bio_list_pop(&md->deferred);
+ spin_unlock_irq(&md->deferred_lock);
- spin_lock_irqsave(&md->pushback_lock, flags);
- clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
- bio_list_merge_head(&md->deferred, &md->pushback);
- bio_list_init(&md->pushback);
- spin_unlock_irqrestore(&md->pushback_lock, flags);
-}
+ if (c) {
+ __split_and_process_bio(md, c);
+ goto next_bio;
+ }
-static void dm_wq_work(struct work_struct *work)
-{
- struct dm_wq_req *req = container_of(work, struct dm_wq_req, work);
- struct mapped_device *md = req->md;
+ clear_bit(DMF_BLOCK_IO, &md->flags);
- down_write(&md->io_lock);
- switch (req->type) {
- case DM_WQ_FLUSH_DEFERRED:
- __flush_deferred_io(md);
- break;
- default:
- DMERR("dm_wq_work: unrecognised work type %d", req->type);
- BUG();
- }
up_write(&md->io_lock);
}
-static void dm_wq_queue(struct mapped_device *md, int type, void *context,
- struct dm_wq_req *req)
-{
- req->type = type;
- req->md = md;
- req->context = context;
- INIT_WORK(&req->work, dm_wq_work);
- queue_work(md->wq, &req->work);
-}
-
-static void dm_queue_flush(struct mapped_device *md, int type, void *context)
+static void dm_queue_flush(struct mapped_device *md)
{
- struct dm_wq_req req;
-
- dm_wq_queue(md, type, context, &req);
+ queue_work(md->wq, &md->work);
flush_workqueue(md->wq);
}
@@ -1534,7 +1509,6 @@ static void unlock_fs(struct mapped_device *md)
int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
{
struct dm_table *map = NULL;
- DECLARE_WAITQUEUE(wait, current);
int r = 0;
int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0;
int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0;
@@ -1584,28 +1558,22 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
down_write(&md->io_lock);
set_bit(DMF_BLOCK_IO, &md->flags);
- add_wait_queue(&md->wait, &wait);
up_write(&md->io_lock);
- /* unplug */
- if (map)
- dm_table_unplug_all(map);
-
/*
* Wait for the already-mapped ios to complete.
*/
- r = dm_wait_for_completion(md);
+ r = dm_wait_for_completion(md, TASK_INTERRUPTIBLE);
down_write(&md->io_lock);
- remove_wait_queue(&md->wait, &wait);
if (noflush)
- __merge_pushback_list(md);
+ clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
up_write(&md->io_lock);
/* were we interrupted ? */
if (r < 0) {
- dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL);
+ dm_queue_flush(md);
unlock_fs(md);
goto out; /* pushback list is already flushed, so skip flush */
@@ -1645,7 +1613,7 @@ int dm_resume(struct mapped_device *md)
if (r)
goto out;
- dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL);
+ dm_queue_flush(md);
unlock_fs(md);
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 20194e000c5a..b48397c0abbd 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -60,7 +60,7 @@ int dm_table_barrier_ok(struct dm_table *t);
int dm_target_init(void);
void dm_target_exit(void);
struct target_type *dm_get_target_type(const char *name);
-void dm_put_target_type(struct target_type *t);
+void dm_put_target_type(struct target_type *tt);
int dm_target_iterate(void (*iter_func)(struct target_type *tt,
void *param), void *param);
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 86d9adf90e79..8695809b24b0 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -62,7 +62,10 @@
#define ModeShift 5
#define MaxFault 50
-#include <linux/raid/md.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include "md.h"
+#include <linux/seq_file.h>
static void faulty_fail(struct bio *bio, int error)
@@ -280,6 +283,17 @@ static int reconfig(mddev_t *mddev, int layout, int chunk_size)
return 0;
}
+static sector_t faulty_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ WARN_ONCE(raid_disks,
+ "%s does not support generic reshape\n", __func__);
+
+ if (sectors == 0)
+ return mddev->dev_sectors;
+
+ return sectors;
+}
+
static int run(mddev_t *mddev)
{
mdk_rdev_t *rdev;
@@ -298,7 +312,7 @@ static int run(mddev_t *mddev)
list_for_each_entry(rdev, &mddev->disks, same_set)
conf->rdev = rdev;
- mddev->array_sectors = mddev->size * 2;
+ md_set_array_sectors(mddev, faulty_size(mddev, 0, 0));
mddev->private = conf;
reconfig(mddev, mddev->layout, -1);
@@ -325,6 +339,7 @@ static struct mdk_personality faulty_personality =
.stop = stop,
.status = status,
.reconfig = reconfig,
+ .size = faulty_size,
};
static int __init raid_init(void)
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 09658b218474..7a36e38393a1 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -16,7 +16,11 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/raid/linear.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "linear.h"
/*
* find which device holds a particular offset
@@ -97,6 +101,16 @@ static int linear_congested(void *data, int bits)
return ret;
}
+static sector_t linear_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ linear_conf_t *conf = mddev_to_conf(mddev);
+
+ WARN_ONCE(sectors || raid_disks,
+ "%s does not support generic reshape\n", __func__);
+
+ return conf->array_sectors;
+}
+
static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
{
linear_conf_t *conf;
@@ -135,8 +149,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
mddev->queue->max_sectors > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
- disk->num_sectors = rdev->size * 2;
- conf->array_sectors += rdev->size * 2;
+ disk->num_sectors = rdev->sectors;
+ conf->array_sectors += rdev->sectors;
cnt++;
}
@@ -249,7 +263,7 @@ static int linear_run (mddev_t *mddev)
if (!conf)
return 1;
mddev->private = conf;
- mddev->array_sectors = conf->array_sectors;
+ md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
mddev->queue->unplug_fn = linear_unplug;
@@ -283,7 +297,7 @@ static int linear_add(mddev_t *mddev, mdk_rdev_t *rdev)
newconf->prev = mddev_to_conf(mddev);
mddev->private = newconf;
mddev->raid_disks++;
- mddev->array_sectors = newconf->array_sectors;
+ md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
set_capacity(mddev->gendisk, mddev->array_sectors);
return 0;
}
@@ -381,6 +395,7 @@ static struct mdk_personality linear_personality =
.stop = linear_stop,
.status = linear_status,
.hot_add_disk = linear_add,
+ .size = linear_size,
};
static int __init linear_init (void)
diff --git a/include/linux/raid/linear.h b/drivers/md/linear.h
index f38b9c586afb..bf8179587f95 100644
--- a/include/linux/raid/linear.h
+++ b/drivers/md/linear.h
@@ -1,8 +1,6 @@
#ifndef _LINEAR_H
#define _LINEAR_H
-#include <linux/raid/md.h>
-
struct dev_info {
mdk_rdev_t *rdev;
sector_t num_sectors;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index a307f87eb90e..ed5727c089a9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -33,9 +33,9 @@
*/
#include <linux/kthread.h>
-#include <linux/raid/md.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
#include <linux/sysctl.h>
+#include <linux/seq_file.h>
#include <linux/buffer_head.h> /* for invalidate_bdev */
#include <linux/poll.h>
#include <linux/ctype.h>
@@ -45,11 +45,10 @@
#include <linux/reboot.h>
#include <linux/file.h>
#include <linux/delay.h>
-
-#define MAJOR_NR MD_MAJOR
-
-/* 63 partitions with the alternate major number (mdp) */
-#define MdpMinorShift 6
+#include <linux/raid/md_p.h>
+#include <linux/raid/md_u.h>
+#include "md.h"
+#include "bitmap.h"
#define DEBUG 0
#define dprintk(x...) ((void)(DEBUG && printk(x)))
@@ -202,12 +201,68 @@ static DEFINE_SPINLOCK(all_mddevs_lock);
)
-static int md_fail_request(struct request_queue *q, struct bio *bio)
+/* Rather than calling directly into the personality make_request function,
+ * IO requests come here first so that we can check if the device is
+ * being suspended pending a reconfiguration.
+ * We hold a refcount over the call to ->make_request. By the time that
+ * call has finished, the bio has been linked into some internal structure
+ * and so is visible to ->quiesce(), so we don't need the refcount any more.
+ */
+static int md_make_request(struct request_queue *q, struct bio *bio)
{
- bio_io_error(bio);
- return 0;
+ mddev_t *mddev = q->queuedata;
+ int rv;
+ if (mddev == NULL || mddev->pers == NULL) {
+ bio_io_error(bio);
+ return 0;
+ }
+ rcu_read_lock();
+ if (mddev->suspended) {
+ DEFINE_WAIT(__wait);
+ for (;;) {
+ prepare_to_wait(&mddev->sb_wait, &__wait,
+ TASK_UNINTERRUPTIBLE);
+ if (!mddev->suspended)
+ break;
+ rcu_read_unlock();
+ schedule();
+ rcu_read_lock();
+ }
+ finish_wait(&mddev->sb_wait, &__wait);
+ }
+ atomic_inc(&mddev->active_io);
+ rcu_read_unlock();
+ rv = mddev->pers->make_request(q, bio);
+ if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended)
+ wake_up(&mddev->sb_wait);
+
+ return rv;
+}
+
+static void mddev_suspend(mddev_t *mddev)
+{
+ BUG_ON(mddev->suspended);
+ mddev->suspended = 1;
+ synchronize_rcu();
+ wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
+ mddev->pers->quiesce(mddev, 1);
+ md_unregister_thread(mddev->thread);
+ mddev->thread = NULL;
+ /* we now know that no code is executing in the personality module,
+ * except possibly the tail end of a ->bi_end_io function, but that
+ * is certain to complete before the module has a chance to get
+ * unloaded
+ */
+}
+
+static void mddev_resume(mddev_t *mddev)
+{
+ mddev->suspended = 0;
+ wake_up(&mddev->sb_wait);
+ mddev->pers->quiesce(mddev, 0);
}
+
static inline mddev_t *mddev_get(mddev_t *mddev)
{
atomic_inc(&mddev->active);
@@ -310,6 +365,7 @@ static mddev_t * mddev_find(dev_t unit)
init_timer(&new->safemode_timer);
atomic_set(&new->active, 1);
atomic_set(&new->openers, 0);
+ atomic_set(&new->active_io, 0);
spin_lock_init(&new->write_lock);
init_waitqueue_head(&new->sb_wait);
init_waitqueue_head(&new->recovery_wait);
@@ -326,6 +382,11 @@ static inline int mddev_lock(mddev_t * mddev)
return mutex_lock_interruptible(&mddev->reconfig_mutex);
}
+static inline int mddev_is_locked(mddev_t *mddev)
+{
+ return mutex_is_locked(&mddev->reconfig_mutex);
+}
+
static inline int mddev_trylock(mddev_t * mddev)
{
return mutex_trylock(&mddev->reconfig_mutex);
@@ -409,7 +470,7 @@ static void free_disk_sb(mdk_rdev_t * rdev)
rdev->sb_loaded = 0;
rdev->sb_page = NULL;
rdev->sb_start = 0;
- rdev->size = 0;
+ rdev->sectors = 0;
}
}
@@ -775,9 +836,9 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version
else
ret = 0;
}
- rdev->size = calc_num_sectors(rdev, sb->chunk_size) / 2;
+ rdev->sectors = calc_num_sectors(rdev, sb->chunk_size);
- if (rdev->size < sb->size && sb->level > 1)
+ if (rdev->sectors < sb->size * 2 && sb->level > 1)
/* "this cannot possibly happen" ... */
ret = -EINVAL;
@@ -812,7 +873,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
mddev->clevel[0] = 0;
mddev->layout = sb->layout;
mddev->raid_disks = sb->raid_disks;
- mddev->size = sb->size;
+ mddev->dev_sectors = sb->size * 2;
mddev->events = ev1;
mddev->bitmap_offset = 0;
mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
@@ -926,7 +987,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
sb->ctime = mddev->ctime;
sb->level = mddev->level;
- sb->size = mddev->size;
+ sb->size = mddev->dev_sectors / 2;
sb->raid_disks = mddev->raid_disks;
sb->md_minor = mddev->md_minor;
sb->not_persistent = 0;
@@ -1024,7 +1085,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
static unsigned long long
super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
{
- if (num_sectors && num_sectors < rdev->mddev->size * 2)
+ if (num_sectors && num_sectors < rdev->mddev->dev_sectors)
return 0; /* component must fit device */
if (rdev->mddev->bitmap_offset)
return 0; /* can't move bitmap */
@@ -1180,16 +1241,17 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
ret = 0;
}
if (minor_version)
- rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2;
+ rdev->sectors = (rdev->bdev->bd_inode->i_size >> 9) -
+ le64_to_cpu(sb->data_offset);
else
- rdev->size = rdev->sb_start / 2;
- if (rdev->size < le64_to_cpu(sb->data_size)/2)
+ rdev->sectors = rdev->sb_start;
+ if (rdev->sectors < le64_to_cpu(sb->data_size))
return -EINVAL;
- rdev->size = le64_to_cpu(sb->data_size)/2;
+ rdev->sectors = le64_to_cpu(sb->data_size);
if (le32_to_cpu(sb->chunksize))
- rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1);
+ rdev->sectors &= ~((sector_t)le32_to_cpu(sb->chunksize) - 1);
- if (le64_to_cpu(sb->size) > rdev->size*2)
+ if (le64_to_cpu(sb->size) > rdev->sectors)
return -EINVAL;
return ret;
}
@@ -1216,7 +1278,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
mddev->clevel[0] = 0;
mddev->layout = le32_to_cpu(sb->layout);
mddev->raid_disks = le32_to_cpu(sb->raid_disks);
- mddev->size = le64_to_cpu(sb->size)/2;
+ mddev->dev_sectors = le64_to_cpu(sb->size);
mddev->events = ev1;
mddev->bitmap_offset = 0;
mddev->default_bitmap_offset = 1024 >> 9;
@@ -1312,7 +1374,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors));
sb->raid_disks = cpu_to_le32(mddev->raid_disks);
- sb->size = cpu_to_le64(mddev->size<<1);
+ sb->size = cpu_to_le64(mddev->dev_sectors);
if (mddev->bitmap && mddev->bitmap_file == NULL) {
sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
@@ -1320,10 +1382,15 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
}
if (rdev->raid_disk >= 0 &&
- !test_bit(In_sync, &rdev->flags) &&
- rdev->recovery_offset > 0) {
- sb->feature_map |= cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
- sb->recovery_offset = cpu_to_le64(rdev->recovery_offset);
+ !test_bit(In_sync, &rdev->flags)) {
+ if (mddev->curr_resync_completed > rdev->recovery_offset)
+ rdev->recovery_offset = mddev->curr_resync_completed;
+ if (rdev->recovery_offset > 0) {
+ sb->feature_map |=
+ cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
+ sb->recovery_offset =
+ cpu_to_le64(rdev->recovery_offset);
+ }
}
if (mddev->reshape_position != MaxSector) {
@@ -1365,7 +1432,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
{
struct mdp_superblock_1 *sb;
sector_t max_sectors;
- if (num_sectors && num_sectors < rdev->mddev->size * 2)
+ if (num_sectors && num_sectors < rdev->mddev->dev_sectors)
return 0; /* component must fit device */
if (rdev->sb_start < rdev->data_offset) {
/* minor versions 1 and 2; superblock before data */
@@ -1381,7 +1448,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
sector_t sb_start;
sb_start = (rdev->bdev->bd_inode->i_size >> 9) - 8*2;
sb_start &= ~(sector_t)(4*2 - 1);
- max_sectors = rdev->size * 2 + sb_start - rdev->sb_start;
+ max_sectors = rdev->sectors + sb_start - rdev->sb_start;
if (!num_sectors || num_sectors > max_sectors)
num_sectors = max_sectors;
rdev->sb_start = sb_start;
@@ -1433,6 +1500,38 @@ static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
static LIST_HEAD(pending_raid_disks);
+static void md_integrity_check(mdk_rdev_t *rdev, mddev_t *mddev)
+{
+ struct mdk_personality *pers = mddev->pers;
+ struct gendisk *disk = mddev->gendisk;
+ struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev);
+ struct blk_integrity *bi_mddev = blk_get_integrity(disk);
+
+ /* Data integrity passthrough not supported on RAID 4, 5 and 6 */
+ if (pers && pers->level >= 4 && pers->level <= 6)
+ return;
+
+ /* If rdev is integrity capable, register profile for mddev */
+ if (!bi_mddev && bi_rdev) {
+ if (blk_integrity_register(disk, bi_rdev))
+ printk(KERN_ERR "%s: %s Could not register integrity!\n",
+ __func__, disk->disk_name);
+ else
+ printk(KERN_NOTICE "Enabling data integrity on %s\n",
+ disk->disk_name);
+ return;
+ }
+
+ /* Check that mddev and rdev have matching profiles */
+ if (blk_integrity_compare(disk, rdev->bdev->bd_disk) < 0) {
+ printk(KERN_ERR "%s: %s/%s integrity mismatch!\n", __func__,
+ disk->disk_name, rdev->bdev->bd_disk->disk_name);
+ printk(KERN_NOTICE "Disabling data integrity on %s\n",
+ disk->disk_name);
+ blk_integrity_unregister(disk);
+ }
+}
+
static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
{
char b[BDEVNAME_SIZE];
@@ -1449,8 +1548,9 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
if (find_rdev(mddev, rdev->bdev->bd_dev))
return -EEXIST;
- /* make sure rdev->size exceeds mddev->size */
- if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
+ /* make sure rdev->sectors exceeds mddev->dev_sectors */
+ if (rdev->sectors && (mddev->dev_sectors == 0 ||
+ rdev->sectors < mddev->dev_sectors)) {
if (mddev->pers) {
/* Cannot change size, so fail
* If mddev->level <= 0, then we don't care
@@ -1459,7 +1559,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
if (mddev->level > 0)
return -ENOSPC;
} else
- mddev->size = rdev->size;
+ mddev->dev_sectors = rdev->sectors;
}
/* Verify rdev->desc_nr is unique.
@@ -1503,6 +1603,8 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
/* May as well allow recovery to be retried once */
mddev->recovery_disabled = 0;
+
+ md_integrity_check(rdev, mddev);
return 0;
fail:
@@ -1713,8 +1815,8 @@ static void print_sb_1(struct mdp_superblock_1 *sb)
static void print_rdev(mdk_rdev_t *rdev, int major_version)
{
char b[BDEVNAME_SIZE];
- printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n",
- bdevname(rdev->bdev,b), (unsigned long long)rdev->size,
+ printk(KERN_INFO "md: rdev %s, Sect:%08llu F:%d S:%d DN:%u\n",
+ bdevname(rdev->bdev, b), (unsigned long long)rdev->sectors,
test_bit(Faulty, &rdev->flags), test_bit(In_sync, &rdev->flags),
rdev->desc_nr);
if (rdev->sb_loaded) {
@@ -2153,7 +2255,7 @@ offset_store(mdk_rdev_t *rdev, const char *buf, size_t len)
return -EINVAL;
if (rdev->mddev->pers && rdev->raid_disk >= 0)
return -EBUSY;
- if (rdev->size && rdev->mddev->external)
+ if (rdev->sectors && rdev->mddev->external)
/* Must set offset before size, so overlap checks
* can be sane */
return -EBUSY;
@@ -2167,7 +2269,7 @@ __ATTR(offset, S_IRUGO|S_IWUSR, offset_show, offset_store);
static ssize_t
rdev_size_show(mdk_rdev_t *rdev, char *page)
{
- return sprintf(page, "%llu\n", (unsigned long long)rdev->size);
+ return sprintf(page, "%llu\n", (unsigned long long)rdev->sectors / 2);
}
static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2)
@@ -2180,34 +2282,52 @@ static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2)
return 1;
}
+static int strict_blocks_to_sectors(const char *buf, sector_t *sectors)
+{
+ unsigned long long blocks;
+ sector_t new;
+
+ if (strict_strtoull(buf, 10, &blocks) < 0)
+ return -EINVAL;
+
+ if (blocks & 1ULL << (8 * sizeof(blocks) - 1))
+ return -EINVAL; /* sector conversion overflow */
+
+ new = blocks * 2;
+ if (new != blocks * 2)
+ return -EINVAL; /* unsigned long long to sector_t overflow */
+
+ *sectors = new;
+ return 0;
+}
+
static ssize_t
rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
{
- unsigned long long size;
- unsigned long long oldsize = rdev->size;
mddev_t *my_mddev = rdev->mddev;
+ sector_t oldsectors = rdev->sectors;
+ sector_t sectors;
- if (strict_strtoull(buf, 10, &size) < 0)
+ if (strict_blocks_to_sectors(buf, &sectors) < 0)
return -EINVAL;
if (my_mddev->pers && rdev->raid_disk >= 0) {
if (my_mddev->persistent) {
- size = super_types[my_mddev->major_version].
- rdev_size_change(rdev, size * 2);
- if (!size)
+ sectors = super_types[my_mddev->major_version].
+ rdev_size_change(rdev, sectors);
+ if (!sectors)
return -EBUSY;
- } else if (!size) {
- size = (rdev->bdev->bd_inode->i_size >> 10);
- size -= rdev->data_offset/2;
- }
+ } else if (!sectors)
+ sectors = (rdev->bdev->bd_inode->i_size >> 9) -
+ rdev->data_offset;
}
- if (size < my_mddev->size)
+ if (sectors < my_mddev->dev_sectors)
return -EINVAL; /* component must fit device */
- rdev->size = size;
- if (size > oldsize && my_mddev->external) {
+ rdev->sectors = sectors;
+ if (sectors > oldsectors && my_mddev->external) {
/* need to check that all other rdevs with the same ->bdev
* do not overlap. We need to unlock the mddev to avoid
- * a deadlock. We have already changed rdev->size, and if
+ * a deadlock. We have already changed rdev->sectors, and if
* we have to change it back, we will have the lock again.
*/
mddev_t *mddev;
@@ -2223,9 +2343,9 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
if (test_bit(AllReserved, &rdev2->flags) ||
(rdev->bdev == rdev2->bdev &&
rdev != rdev2 &&
- overlaps(rdev->data_offset, rdev->size * 2,
+ overlaps(rdev->data_offset, rdev->sectors,
rdev2->data_offset,
- rdev2->size * 2))) {
+ rdev2->sectors))) {
overlap = 1;
break;
}
@@ -2239,11 +2359,11 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
if (overlap) {
/* Someone else could have slipped in a size
* change here, but doing so is just silly.
- * We put oldsize back because we *know* it is
+ * We put oldsectors back because we *know* it is
* safe, and trust userspace not to race with
* itself
*/
- rdev->size = oldsize;
+ rdev->sectors = oldsectors;
return -EBUSY;
}
}
@@ -2547,18 +2667,101 @@ level_show(mddev_t *mddev, char *page)
static ssize_t
level_store(mddev_t *mddev, const char *buf, size_t len)
{
+ char level[16];
ssize_t rv = len;
- if (mddev->pers)
+ struct mdk_personality *pers;
+ void *priv;
+
+ if (mddev->pers == NULL) {
+ if (len == 0)
+ return 0;
+ if (len >= sizeof(mddev->clevel))
+ return -ENOSPC;
+ strncpy(mddev->clevel, buf, len);
+ if (mddev->clevel[len-1] == '\n')
+ len--;
+ mddev->clevel[len] = 0;
+ mddev->level = LEVEL_NONE;
+ return rv;
+ }
+
+ /* request to change the personality. Need to ensure:
+ * - array is not engaged in resync/recovery/reshape
+ * - old personality can be suspended
+ * - new personality will access other array.
+ */
+
+ if (mddev->sync_thread || mddev->reshape_position != MaxSector)
return -EBUSY;
- if (len == 0)
- return 0;
- if (len >= sizeof(mddev->clevel))
- return -ENOSPC;
- strncpy(mddev->clevel, buf, len);
- if (mddev->clevel[len-1] == '\n')
+
+ if (!mddev->pers->quiesce) {
+ printk(KERN_WARNING "md: %s: %s does not support online personality change\n",
+ mdname(mddev), mddev->pers->name);
+ return -EINVAL;
+ }
+
+ /* Now find the new personality */
+ if (len == 0 || len >= sizeof(level))
+ return -EINVAL;
+ strncpy(level, buf, len);
+ if (level[len-1] == '\n')
len--;
- mddev->clevel[len] = 0;
- mddev->level = LEVEL_NONE;
+ level[len] = 0;
+
+ request_module("md-%s", level);
+ spin_lock(&pers_lock);
+ pers = find_pers(LEVEL_NONE, level);
+ if (!pers || !try_module_get(pers->owner)) {
+ spin_unlock(&pers_lock);
+ printk(KERN_WARNING "md: personality %s not loaded\n", level);
+ return -EINVAL;
+ }
+ spin_unlock(&pers_lock);
+
+ if (pers == mddev->pers) {
+ /* Nothing to do! */
+ module_put(pers->owner);
+ return rv;
+ }
+ if (!pers->takeover) {
+ module_put(pers->owner);
+ printk(KERN_WARNING "md: %s: %s does not support personality takeover\n",
+ mdname(mddev), level);
+ return -EINVAL;
+ }
+
+ /* ->takeover must set new_* and/or delta_disks
+ * if it succeeds, and may set them when it fails.
+ */
+ priv = pers->takeover(mddev);
+ if (IS_ERR(priv)) {
+ mddev->new_level = mddev->level;
+ mddev->new_layout = mddev->layout;
+ mddev->new_chunk = mddev->chunk_size;
+ mddev->raid_disks -= mddev->delta_disks;
+ mddev->delta_disks = 0;
+ module_put(pers->owner);
+ printk(KERN_WARNING "md: %s: %s would not accept array\n",
+ mdname(mddev), level);
+ return PTR_ERR(priv);
+ }
+
+ /* Looks like we have a winner */
+ mddev_suspend(mddev);
+ mddev->pers->stop(mddev);
+ module_put(mddev->pers->owner);
+ mddev->pers = pers;
+ mddev->private = priv;
+ strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
+ mddev->level = mddev->new_level;
+ mddev->layout = mddev->new_layout;
+ mddev->chunk_size = mddev->new_chunk;
+ mddev->delta_disks = 0;
+ pers->run(mddev);
+ mddev_resume(mddev);
+ set_bit(MD_CHANGE_DEVS, &mddev->flags);
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ md_wakeup_thread(mddev->thread);
return rv;
}
@@ -2586,12 +2789,18 @@ layout_store(mddev_t *mddev, const char *buf, size_t len)
if (!*buf || (*e && *e != '\n'))
return -EINVAL;
- if (mddev->pers)
- return -EBUSY;
- if (mddev->reshape_position != MaxSector)
+ if (mddev->pers) {
+ int err;
+ if (mddev->pers->reconfig == NULL)
+ return -EBUSY;
+ err = mddev->pers->reconfig(mddev, n, -1);
+ if (err)
+ return err;
+ } else {
mddev->new_layout = n;
- else
- mddev->layout = n;
+ if (mddev->reshape_position == MaxSector)
+ mddev->layout = n;
+ }
return len;
}
static struct md_sysfs_entry md_layout =
@@ -2648,19 +2857,24 @@ chunk_size_show(mddev_t *mddev, char *page)
static ssize_t
chunk_size_store(mddev_t *mddev, const char *buf, size_t len)
{
- /* can only set chunk_size if array is not yet active */
char *e;
unsigned long n = simple_strtoul(buf, &e, 10);
if (!*buf || (*e && *e != '\n'))
return -EINVAL;
- if (mddev->pers)
- return -EBUSY;
- else if (mddev->reshape_position != MaxSector)
+ if (mddev->pers) {
+ int err;
+ if (mddev->pers->reconfig == NULL)
+ return -EBUSY;
+ err = mddev->pers->reconfig(mddev, -1, n);
+ if (err)
+ return err;
+ } else {
mddev->new_chunk = n;
- else
- mddev->chunk_size = n;
+ if (mddev->reshape_position == MaxSector)
+ mddev->chunk_size = n;
+ }
return len;
}
static struct md_sysfs_entry md_chunk_size =
@@ -2669,6 +2883,8 @@ __ATTR(chunk_size, S_IRUGO|S_IWUSR, chunk_size_show, chunk_size_store);
static ssize_t
resync_start_show(mddev_t *mddev, char *page)
{
+ if (mddev->recovery_cp == MaxSector)
+ return sprintf(page, "none\n");
return sprintf(page, "%llu\n", (unsigned long long)mddev->recovery_cp);
}
@@ -2766,7 +2982,7 @@ array_state_show(mddev_t *mddev, char *page)
else {
if (list_empty(&mddev->disks) &&
mddev->raid_disks == 0 &&
- mddev->size == 0)
+ mddev->dev_sectors == 0)
st = clear;
else
st = inactive;
@@ -2973,7 +3189,8 @@ __ATTR(bitmap_set_bits, S_IWUSR, null_show, bitmap_store);
static ssize_t
size_show(mddev_t *mddev, char *page)
{
- return sprintf(page, "%llu\n", (unsigned long long)mddev->size);
+ return sprintf(page, "%llu\n",
+ (unsigned long long)mddev->dev_sectors / 2);
}
static int update_size(mddev_t *mddev, sector_t num_sectors);
@@ -2985,20 +3202,18 @@ size_store(mddev_t *mddev, const char *buf, size_t len)
* not increase it (except from 0).
* If array is active, we can try an on-line resize
*/
- char *e;
- int err = 0;
- unsigned long long size = simple_strtoull(buf, &e, 10);
- if (!*buf || *buf == '\n' ||
- (*e && *e != '\n'))
- return -EINVAL;
+ sector_t sectors;
+ int err = strict_blocks_to_sectors(buf, &sectors);
+ if (err < 0)
+ return err;
if (mddev->pers) {
- err = update_size(mddev, size * 2);
+ err = update_size(mddev, sectors);
md_update_sb(mddev, 1);
} else {
- if (mddev->size == 0 ||
- mddev->size > size)
- mddev->size = size;
+ if (mddev->dev_sectors == 0 ||
+ mddev->dev_sectors > sectors)
+ mddev->dev_sectors = sectors;
else
err = -ENOSPC;
}
@@ -3251,6 +3466,8 @@ static ssize_t
sync_speed_show(mddev_t *mddev, char *page)
{
unsigned long resync, dt, db;
+ if (mddev->curr_resync == 0)
+ return sprintf(page, "none\n");
resync = mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active);
dt = (jiffies - mddev->resync_mark) / HZ;
if (!dt) dt++;
@@ -3263,15 +3480,15 @@ static struct md_sysfs_entry md_sync_speed = __ATTR_RO(sync_speed);
static ssize_t
sync_completed_show(mddev_t *mddev, char *page)
{
- unsigned long max_blocks, resync;
+ unsigned long max_sectors, resync;
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
- max_blocks = mddev->resync_max_sectors;
+ max_sectors = mddev->resync_max_sectors;
else
- max_blocks = mddev->size << 1;
+ max_sectors = mddev->dev_sectors;
resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active));
- return sprintf(page, "%lu / %lu\n", resync, max_blocks);
+ return sprintf(page, "%lu / %lu\n", resync, max_sectors);
}
static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed);
@@ -3431,6 +3648,57 @@ static struct md_sysfs_entry md_reshape_position =
__ATTR(reshape_position, S_IRUGO|S_IWUSR, reshape_position_show,
reshape_position_store);
+static ssize_t
+array_size_show(mddev_t *mddev, char *page)
+{
+ if (mddev->external_size)
+ return sprintf(page, "%llu\n",
+ (unsigned long long)mddev->array_sectors/2);
+ else
+ return sprintf(page, "default\n");
+}
+
+static ssize_t
+array_size_store(mddev_t *mddev, const char *buf, size_t len)
+{
+ sector_t sectors;
+
+ if (strncmp(buf, "default", 7) == 0) {
+ if (mddev->pers)
+ sectors = mddev->pers->size(mddev, 0, 0);
+ else
+ sectors = mddev->array_sectors;
+
+ mddev->external_size = 0;
+ } else {
+ if (strict_blocks_to_sectors(buf, &sectors) < 0)
+ return -EINVAL;
+ if (mddev->pers && mddev->pers->size(mddev, 0, 0) < sectors)
+ return -EINVAL;
+
+ mddev->external_size = 1;
+ }
+
+ mddev->array_sectors = sectors;
+ set_capacity(mddev->gendisk, mddev->array_sectors);
+ if (mddev->pers) {
+ struct block_device *bdev = bdget_disk(mddev->gendisk, 0);
+
+ if (bdev) {
+ mutex_lock(&bdev->bd_inode->i_mutex);
+ i_size_write(bdev->bd_inode,
+ (loff_t)mddev->array_sectors << 9);
+ mutex_unlock(&bdev->bd_inode->i_mutex);
+ bdput(bdev);
+ }
+ }
+
+ return len;
+}
+
+static struct md_sysfs_entry md_array_size =
+__ATTR(array_size, S_IRUGO|S_IWUSR, array_size_show,
+ array_size_store);
static struct attribute *md_default_attrs[] = {
&md_level.attr,
@@ -3444,6 +3712,7 @@ static struct attribute *md_default_attrs[] = {
&md_safe_delay.attr,
&md_array_state.attr,
&md_reshape_position.attr,
+ &md_array_size.attr,
NULL,
};
@@ -3602,10 +3871,12 @@ static int md_alloc(dev_t dev, char *name)
mddev_put(mddev);
return -ENOMEM;
}
+ mddev->queue->queuedata = mddev;
+
/* Can be unlocked because the queue is new: no concurrency */
queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue);
- blk_queue_make_request(mddev->queue, md_fail_request);
+ blk_queue_make_request(mddev->queue, md_make_request);
disk = alloc_disk(1 << shift);
if (!disk) {
@@ -3731,13 +4002,13 @@ static int do_md_run(mddev_t * mddev)
list_for_each_entry(rdev, &mddev->disks, same_set) {
if (test_bit(Faulty, &rdev->flags))
continue;
- if (rdev->size < chunk_size / 1024) {
+ if (rdev->sectors < chunk_size / 512) {
printk(KERN_WARNING
"md: Dev %s smaller than chunk_size:"
- " %lluk < %dk\n",
+ " %llu < %d\n",
bdevname(rdev->bdev,b),
- (unsigned long long)rdev->size,
- chunk_size / 1024);
+ (unsigned long long)rdev->sectors,
+ chunk_size / 512);
return -EINVAL;
}
}
@@ -3761,11 +4032,11 @@ static int do_md_run(mddev_t * mddev)
/* perform some consistency tests on the device.
* We don't want the data to overlap the metadata,
- * Internal Bitmap issues has handled elsewhere.
+ * Internal Bitmap issues have been handled elsewhere.
*/
if (rdev->data_offset < rdev->sb_start) {
- if (mddev->size &&
- rdev->data_offset + mddev->size*2
+ if (mddev->dev_sectors &&
+ rdev->data_offset + mddev->dev_sectors
> rdev->sb_start) {
printk("md: %s: data overlaps metadata\n",
mdname(mddev));
@@ -3801,9 +4072,16 @@ static int do_md_run(mddev_t * mddev)
}
mddev->pers = pers;
spin_unlock(&pers_lock);
- mddev->level = pers->level;
+ if (mddev->level != pers->level) {
+ mddev->level = pers->level;
+ mddev->new_level = pers->level;
+ }
strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
+ if (pers->level >= 4 && pers->level <= 6)
+ /* Cannot support integrity (yet) */
+ blk_integrity_unregister(mddev->gendisk);
+
if (mddev->reshape_position != MaxSector &&
pers->start_reshape == NULL) {
/* This personality cannot handle reshaping... */
@@ -3843,7 +4121,9 @@ static int do_md_run(mddev_t * mddev)
}
mddev->recovery = 0;
- mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
+ /* may be over-ridden by personality */
+ mddev->resync_max_sectors = mddev->dev_sectors;
+
mddev->barriers_work = 1;
mddev->ok_start_degraded = start_dirty_degraded;
@@ -3853,7 +4133,17 @@ static int do_md_run(mddev_t * mddev)
err = mddev->pers->run(mddev);
if (err)
printk(KERN_ERR "md: pers->run() failed ...\n");
- else if (mddev->pers->sync_request) {
+ else if (mddev->pers->size(mddev, 0, 0) < mddev->array_sectors) {
+ WARN_ONCE(!mddev->external_size, "%s: default size too small,"
+ " but 'external_size' not in effect?\n", __func__);
+ printk(KERN_ERR
+ "md: invalid array_size %llu > default size %llu\n",
+ (unsigned long long)mddev->array_sectors / 2,
+ (unsigned long long)mddev->pers->size(mddev, 0, 0) / 2);
+ err = -EINVAL;
+ mddev->pers->stop(mddev);
+ }
+ if (err == 0 && mddev->pers->sync_request) {
err = bitmap_create(mddev);
if (err) {
printk(KERN_ERR "%s: failed to create bitmap (%d)\n",
@@ -3899,16 +4189,6 @@ static int do_md_run(mddev_t * mddev)
set_capacity(disk, mddev->array_sectors);
- /* If we call blk_queue_make_request here, it will
- * re-initialise max_sectors etc which may have been
- * refined inside -> run. So just set the bits we need to set.
- * Most initialisation happended when we called
- * blk_queue_make_request(..., md_fail_request)
- * earlier.
- */
- mddev->queue->queuedata = mddev;
- mddev->queue->make_request_fn = mddev->pers->make_request;
-
/* If there is a partially-recovered drive we need to
* start recovery here. If we leave it to md_check_recovery,
* it will remove the drives and not do the right thing
@@ -4038,7 +4318,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
md_super_wait(mddev);
if (mddev->ro)
set_disk_ro(disk, 0);
- blk_queue_make_request(mddev->queue, md_fail_request);
+
mddev->pers->stop(mddev);
mddev->queue->merge_bvec_fn = NULL;
mddev->queue->unplug_fn = NULL;
@@ -4095,7 +4375,8 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
export_array(mddev);
mddev->array_sectors = 0;
- mddev->size = 0;
+ mddev->external_size = 0;
+ mddev->dev_sectors = 0;
mddev->raid_disks = 0;
mddev->recovery_cp = 0;
mddev->resync_min = 0;
@@ -4135,6 +4416,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
printk(KERN_INFO "md: %s switched to read-only mode.\n",
mdname(mddev));
err = 0;
+ blk_integrity_unregister(disk);
md_new_event(mddev);
sysfs_notify_dirent(mddev->sysfs_state);
out:
@@ -4300,8 +4582,8 @@ static int get_array_info(mddev_t * mddev, void __user * arg)
info.patch_version = MD_PATCHLEVEL_VERSION;
info.ctime = mddev->ctime;
info.level = mddev->level;
- info.size = mddev->size;
- if (info.size != mddev->size) /* overflow */
+ info.size = mddev->dev_sectors / 2;
+ if (info.size != mddev->dev_sectors / 2) /* overflow */
info.size = -1;
info.nr_disks = nr;
info.raid_disks = mddev->raid_disks;
@@ -4480,6 +4762,8 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
clear_bit(In_sync, &rdev->flags); /* just to be sure */
if (info->state & (1<<MD_DISK_WRITEMOSTLY))
set_bit(WriteMostly, &rdev->flags);
+ else
+ clear_bit(WriteMostly, &rdev->flags);
rdev->raid_disk = -1;
err = bind_rdev_to_array(rdev, mddev);
@@ -4543,7 +4827,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
} else
rdev->sb_start = calc_dev_sboffset(rdev->bdev);
- rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2;
+ rdev->sectors = calc_num_sectors(rdev, mddev->chunk_size);
err = bind_rdev_to_array(rdev, mddev);
if (err) {
@@ -4613,7 +4897,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
else
rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
- rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2;
+ rdev->sectors = calc_num_sectors(rdev, mddev->chunk_size);
if (test_bit(Faulty, &rdev->flags)) {
printk(KERN_WARNING
@@ -4749,7 +5033,7 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
mddev->level = info->level;
mddev->clevel[0] = 0;
- mddev->size = info->size;
+ mddev->dev_sectors = 2 * (sector_t)info->size;
mddev->raid_disks = info->raid_disks;
/* don't set md_minor, it is determined by which /dev/md* was
* openned
@@ -4788,6 +5072,17 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
return 0;
}
+void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors)
+{
+ WARN(!mddev_is_locked(mddev), "%s: unlocked mddev!\n", __func__);
+
+ if (mddev->external_size)
+ return;
+
+ mddev->array_sectors = array_sectors;
+}
+EXPORT_SYMBOL(md_set_array_sectors);
+
static int update_size(mddev_t *mddev, sector_t num_sectors)
{
mdk_rdev_t *rdev;
@@ -4814,8 +5109,7 @@ static int update_size(mddev_t *mddev, sector_t num_sectors)
*/
return -EBUSY;
list_for_each_entry(rdev, &mddev->disks, same_set) {
- sector_t avail;
- avail = rdev->size * 2;
+ sector_t avail = rdev->sectors;
if (fit && (num_sectors == 0 || num_sectors > avail))
num_sectors = avail;
@@ -4887,12 +5181,18 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
)
return -EINVAL;
/* Check there is only one change */
- if (info->size >= 0 && mddev->size != info->size) cnt++;
- if (mddev->raid_disks != info->raid_disks) cnt++;
- if (mddev->layout != info->layout) cnt++;
- if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) cnt++;
- if (cnt == 0) return 0;
- if (cnt > 1) return -EINVAL;
+ if (info->size >= 0 && mddev->dev_sectors / 2 != info->size)
+ cnt++;
+ if (mddev->raid_disks != info->raid_disks)
+ cnt++;
+ if (mddev->layout != info->layout)
+ cnt++;
+ if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT))
+ cnt++;
+ if (cnt == 0)
+ return 0;
+ if (cnt > 1)
+ return -EINVAL;
if (mddev->layout != info->layout) {
/* Change layout
@@ -4904,7 +5204,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
else
return mddev->pers->reconfig(mddev, info->layout, -1);
}
- if (info->size >= 0 && mddev->size != info->size)
+ if (info->size >= 0 && mddev->dev_sectors / 2 != info->size)
rv = update_size(mddev, (sector_t)info->size * 2);
if (mddev->raid_disks != info->raid_disks)
@@ -5331,6 +5631,8 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
void md_unregister_thread(mdk_thread_t *thread)
{
+ if (!thread)
+ return;
dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
kthread_stop(thread->tsk);
@@ -5404,7 +5706,7 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev)
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
max_blocks = mddev->resync_max_sectors >> 1;
else
- max_blocks = mddev->size;
+ max_blocks = mddev->dev_sectors / 2;
/*
* Should not happen.
@@ -5537,7 +5839,7 @@ struct mdstat_info {
static int md_seq_show(struct seq_file *seq, void *v)
{
mddev_t *mddev = v;
- sector_t size;
+ sector_t sectors;
mdk_rdev_t *rdev;
struct mdstat_info *mi = seq->private;
struct bitmap *bitmap;
@@ -5573,7 +5875,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, " %s", mddev->pers->name);
}
- size = 0;
+ sectors = 0;
list_for_each_entry(rdev, &mddev->disks, same_set) {
char b[BDEVNAME_SIZE];
seq_printf(seq, " %s[%d]",
@@ -5585,7 +5887,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
continue;
} else if (rdev->raid_disk < 0)
seq_printf(seq, "(S)"); /* spare */
- size += rdev->size;
+ sectors += rdev->sectors;
}
if (!list_empty(&mddev->disks)) {
@@ -5595,7 +5897,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
mddev->array_sectors / 2);
else
seq_printf(seq, "\n %llu blocks",
- (unsigned long long)size);
+ (unsigned long long)sectors / 2);
}
if (mddev->persistent) {
if (mddev->major_version != 0 ||
@@ -5722,19 +6024,19 @@ int unregister_md_personality(struct mdk_personality *p)
return 0;
}
-static int is_mddev_idle(mddev_t *mddev)
+static int is_mddev_idle(mddev_t *mddev, int init)
{
mdk_rdev_t * rdev;
int idle;
- long curr_events;
+ int curr_events;
idle = 1;
rcu_read_lock();
rdev_for_each_rcu(rdev, mddev) {
struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
- curr_events = part_stat_read(&disk->part0, sectors[0]) +
- part_stat_read(&disk->part0, sectors[1]) -
- atomic_read(&disk->sync_io);
+ curr_events = (int)part_stat_read(&disk->part0, sectors[0]) +
+ (int)part_stat_read(&disk->part0, sectors[1]) -
+ atomic_read(&disk->sync_io);
/* sync IO will cause sync_io to increase before the disk_stats
* as sync_io is counted when a request starts, and
* disk_stats is counted when it completes.
@@ -5757,7 +6059,7 @@ static int is_mddev_idle(mddev_t *mddev)
* always make curr_events less than last_events.
*
*/
- if (curr_events - rdev->last_events > 4096) {
+ if (init || curr_events - rdev->last_events > 64) {
rdev->last_events = curr_events;
idle = 0;
}
@@ -5980,10 +6282,10 @@ void md_do_sync(mddev_t *mddev)
j = mddev->recovery_cp;
} else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
- max_sectors = mddev->size << 1;
+ max_sectors = mddev->dev_sectors;
else {
/* recovery follows the physical size of devices */
- max_sectors = mddev->size << 1;
+ max_sectors = mddev->dev_sectors;
j = MaxSector;
list_for_each_entry(rdev, &mddev->disks, same_set)
if (rdev->raid_disk >= 0 &&
@@ -6000,7 +6302,7 @@ void md_do_sync(mddev_t *mddev)
"(but not more than %d KB/sec) for %s.\n",
speed_max(mddev), desc);
- is_mddev_idle(mddev); /* this also initializes IO event counters */
+ is_mddev_idle(mddev, 1); /* this initializes IO event counters */
io_sectors = 0;
for (m = 0; m < SYNC_MARKS; m++) {
@@ -6040,6 +6342,18 @@ void md_do_sync(mddev_t *mddev)
}
if (kthread_should_stop())
goto interrupted;
+
+ if (mddev->curr_resync > mddev->curr_resync_completed &&
+ (mddev->curr_resync - mddev->curr_resync_completed)
+ > (max_sectors >> 4)) {
+ /* time to update curr_resync_completed */
+ blk_unplug(mddev->queue);
+ wait_event(mddev->recovery_wait,
+ atomic_read(&mddev->recovery_active) == 0);
+ mddev->curr_resync_completed =
+ mddev->curr_resync;
+ set_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ }
sectors = mddev->pers->sync_request(mddev, j, &skipped,
currspeed < speed_min(mddev));
if (sectors == 0) {
@@ -6102,7 +6416,7 @@ void md_do_sync(mddev_t *mddev)
if (currspeed > speed_min(mddev)) {
if ((currspeed > speed_max(mddev)) ||
- !is_mddev_idle(mddev)) {
+ !is_mddev_idle(mddev, 0)) {
msleep(500);
goto repeat;
}
@@ -6173,6 +6487,8 @@ static int remove_and_add_spares(mddev_t *mddev)
mdk_rdev_t *rdev;
int spares = 0;
+ mddev->curr_resync_completed = 0;
+
list_for_each_entry(rdev, &mddev->disks, same_set)
if (rdev->raid_disk >= 0 &&
!test_bit(Blocked, &rdev->flags) &&
@@ -6327,6 +6643,9 @@ void md_check_recovery(mddev_t *mddev)
sysfs_notify(&mddev->kobj, NULL,
"degraded");
}
+ if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
+ mddev->pers->finish_reshape)
+ mddev->pers->finish_reshape(mddev);
md_update_sb(mddev, 1);
/* if array is no-longer degraded, then any saved_raid_disk
@@ -6470,13 +6789,13 @@ static void md_geninit(void)
static int __init md_init(void)
{
- if (register_blkdev(MAJOR_NR, "md"))
+ if (register_blkdev(MD_MAJOR, "md"))
return -1;
if ((mdp_major=register_blkdev(0, "mdp"))<=0) {
- unregister_blkdev(MAJOR_NR, "md");
+ unregister_blkdev(MD_MAJOR, "md");
return -1;
}
- blk_register_region(MKDEV(MAJOR_NR, 0), 1UL<<MINORBITS, THIS_MODULE,
+ blk_register_region(MKDEV(MD_MAJOR, 0), 1UL<<MINORBITS, THIS_MODULE,
md_probe, NULL, NULL);
blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE,
md_probe, NULL, NULL);
@@ -6562,10 +6881,10 @@ static __exit void md_exit(void)
mddev_t *mddev;
struct list_head *tmp;
- blk_unregister_region(MKDEV(MAJOR_NR,0), 1U << MINORBITS);
+ blk_unregister_region(MKDEV(MD_MAJOR,0), 1U << MINORBITS);
blk_unregister_region(MKDEV(mdp_major,0), 1U << MINORBITS);
- unregister_blkdev(MAJOR_NR,"md");
+ unregister_blkdev(MD_MAJOR,"md");
unregister_blkdev(mdp_major, "mdp");
unregister_reboot_notifier(&md_notifier);
unregister_sysctl_table(raid_table_header);
diff --git a/include/linux/raid/md_k.h b/drivers/md/md.h
index 9743e4dbc918..e9b7f54c24d6 100644
--- a/include/linux/raid/md_k.h
+++ b/drivers/md/md.h
@@ -15,21 +15,8 @@
#ifndef _MD_K_H
#define _MD_K_H
-/* and dm-bio-list.h is not under include/linux because.... ??? */
-#include "../../../drivers/md/dm-bio-list.h"
-
#ifdef CONFIG_BLOCK
-#define LEVEL_MULTIPATH (-4)
-#define LEVEL_LINEAR (-1)
-#define LEVEL_FAULTY (-5)
-
-/* we need a value for 'no level specified' and 0
- * means 'raid0', so we need something else. This is
- * for internal use only
- */
-#define LEVEL_NONE (-1000000)
-
#define MaxSector (~(sector_t)0)
typedef struct mddev_s mddev_t;
@@ -49,9 +36,9 @@ struct mdk_rdev_s
{
struct list_head same_set; /* RAID devices within the same set */
- sector_t size; /* Device size (in blocks) */
+ sector_t sectors; /* Device size (in 512bytes sectors) */
mddev_t *mddev; /* RAID array if running */
- long last_events; /* IO event timestamp */
+ int last_events; /* IO event timestamp */
struct block_device *bdev; /* block device handle */
@@ -132,6 +119,8 @@ struct mddev_s
#define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */
#define MD_CHANGE_PENDING 2 /* superblock update in progress */
+ int suspended;
+ atomic_t active_io;
int ro;
struct gendisk *gendisk;
@@ -155,8 +144,11 @@ struct mddev_s
char clevel[16];
int raid_disks;
int max_disks;
- sector_t size; /* used size of component devices */
+ sector_t dev_sectors; /* used size of
+ * component devices */
sector_t array_sectors; /* exported array size */
+ int external_size; /* size managed
+ * externally */
__u64 events;
char uuid[16];
@@ -172,6 +164,13 @@ struct mddev_s
struct mdk_thread_s *thread; /* management thread */
struct mdk_thread_s *sync_thread; /* doing resync or reconstruct */
sector_t curr_resync; /* last block scheduled */
+ /* As resync requests can complete out of order, we cannot easily track
+ * how much resync has been completed. So we occasionally pause until
+ * everything completes, then set curr_resync_completed to curr_resync.
+ * As such it may be well behind the real resync mark, but it is a value
+ * we are certain of.
+ */
+ sector_t curr_resync_completed;
unsigned long resync_mark; /* a recent timestamp */
sector_t resync_mark_cnt;/* blocks written at resync_mark */
sector_t curr_mark_cnt; /* blocks scheduled now */
@@ -315,8 +314,10 @@ struct mdk_personality
int (*spare_active) (mddev_t *mddev);
sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster);
int (*resize) (mddev_t *mddev, sector_t sectors);
+ sector_t (*size) (mddev_t *mddev, sector_t sectors, int raid_disks);
int (*check_reshape) (mddev_t *mddev);
int (*start_reshape) (mddev_t *mddev);
+ void (*finish_reshape) (mddev_t *mddev);
int (*reconfig) (mddev_t *mddev, int layout, int chunk_size);
/* quiesce moves between quiescence states
* 0 - fully active
@@ -324,6 +325,16 @@ struct mdk_personality
* others - reserved
*/
void (*quiesce) (mddev_t *mddev, int state);
+ /* takeover is used to transition an array from one
+ * personality to another. The new personality must be able
+ * to handle the data in the current layout.
+ * e.g. 2drive raid1 -> 2drive raid5
+ * ndrive raid5 -> degraded n+1drive raid6 with special layout
+ * If the takeover succeeds, a new 'private' structure is returned.
+ * This needs to be installed and then ->run used to activate the
+ * array.
+ */
+ void *(*takeover) (mddev_t *mddev);
};
@@ -400,3 +411,26 @@ static inline void safe_put_page(struct page *p)
#endif /* CONFIG_BLOCK */
#endif
+
+extern int register_md_personality(struct mdk_personality *p);
+extern int unregister_md_personality(struct mdk_personality *p);
+extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev),
+ mddev_t *mddev, const char *name);
+extern void md_unregister_thread(mdk_thread_t *thread);
+extern void md_wakeup_thread(mdk_thread_t *thread);
+extern void md_check_recovery(mddev_t *mddev);
+extern void md_write_start(mddev_t *mddev, struct bio *bi);
+extern void md_write_end(mddev_t *mddev);
+extern void md_done_sync(mddev_t *mddev, int blocks, int ok);
+extern void md_error(mddev_t *mddev, mdk_rdev_t *rdev);
+
+extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
+ sector_t sector, int size, struct page *page);
+extern void md_super_wait(mddev_t *mddev);
+extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
+ struct page *page, int rw);
+extern void md_do_sync(mddev_t *mddev);
+extern void md_new_event(mddev_t *mddev);
+extern int md_allow_write(mddev_t *mddev);
+extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
+extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors);
diff --git a/drivers/md/mktables.c b/drivers/md/mktables.c
index b61d5767aae7..3b1500843bba 100644
--- a/drivers/md/mktables.c
+++ b/drivers/md/mktables.c
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
uint8_t v;
uint8_t exptbl[256], invtbl[256];
- printf("#include \"raid6.h\"\n");
+ printf("#include <linux/raid/pq.h>\n");
/* Compute multiplication table */
printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -76,6 +76,9 @@ int main(int argc, char *argv[])
printf("\t},\n");
}
printf("};\n");
+ printf("#ifdef __KERNEL__\n");
+ printf("EXPORT_SYMBOL(raid6_gfmul);\n");
+ printf("#endif\n");
/* Compute power-of-2 table (exponent) */
v = 1;
@@ -92,6 +95,9 @@ int main(int argc, char *argv[])
}
}
printf("};\n");
+ printf("#ifdef __KERNEL__\n");
+ printf("EXPORT_SYMBOL(raid6_gfexp);\n");
+ printf("#endif\n");
/* Compute inverse table x^-1 == x^254 */
printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -104,6 +110,9 @@ int main(int argc, char *argv[])
}
}
printf("};\n");
+ printf("#ifdef __KERNEL__\n");
+ printf("EXPORT_SYMBOL(raid6_gfinv);\n");
+ printf("#endif\n");
/* Compute inv(2^x + 1) (exponent-xor-inverse) table */
printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -115,6 +124,9 @@ int main(int argc, char *argv[])
(j == 7) ? '\n' : ' ');
}
printf("};\n");
+ printf("#ifdef __KERNEL__\n");
+ printf("EXPORT_SYMBOL(raid6_gfexi);\n");
+ printf("#endif\n");
return 0;
}
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index f6d08f241671..41ced0cbe823 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -19,7 +19,11 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/raid/multipath.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "multipath.h"
#define MAX_WORK_PER_DISK 128
@@ -402,6 +406,14 @@ static void multipathd (mddev_t *mddev)
spin_unlock_irqrestore(&conf->device_lock, flags);
}
+static sector_t multipath_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ WARN_ONCE(sectors || raid_disks,
+ "%s does not support generic reshape\n", __func__);
+
+ return mddev->dev_sectors;
+}
+
static int multipath_run (mddev_t *mddev)
{
multipath_conf_t *conf;
@@ -498,7 +510,7 @@ static int multipath_run (mddev_t *mddev)
/*
* Ok, everything is just fine now
*/
- mddev->array_sectors = mddev->size * 2;
+ md_set_array_sectors(mddev, multipath_size(mddev, 0, 0));
mddev->queue->unplug_fn = multipath_unplug;
mddev->queue->backing_dev_info.congested_fn = multipath_congested;
@@ -543,6 +555,7 @@ static struct mdk_personality multipath_personality =
.error_handler = multipath_error,
.hot_add_disk = multipath_add_disk,
.hot_remove_disk= multipath_remove_disk,
+ .size = multipath_size,
};
static int __init multipath_init (void)
diff --git a/include/linux/raid/multipath.h b/drivers/md/multipath.h
index 6f53fc177a47..6fa70b400cda 100644
--- a/include/linux/raid/multipath.h
+++ b/drivers/md/multipath.h
@@ -1,8 +1,6 @@
#ifndef _MULTIPATH_H
#define _MULTIPATH_H
-#include <linux/raid/md.h>
-
struct multipath_info {
mdk_rdev_t *rdev;
};
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index c605ba805586..c08d7559be55 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -18,7 +18,10 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/raid/raid0.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "raid0.h"
static void raid0_unplug(struct request_queue *q)
{
@@ -73,16 +76,15 @@ static int create_strip_zones (mddev_t *mddev)
list_for_each_entry(rdev2, &mddev->disks, same_set) {
printk(KERN_INFO "raid0: comparing %s(%llu)",
bdevname(rdev1->bdev,b),
- (unsigned long long)rdev1->size);
+ (unsigned long long)rdev1->sectors);
printk(KERN_INFO " with %s(%llu)\n",
bdevname(rdev2->bdev,b),
- (unsigned long long)rdev2->size);
+ (unsigned long long)rdev2->sectors);
if (rdev2 == rdev1) {
printk(KERN_INFO "raid0: END\n");
break;
}
- if (rdev2->size == rdev1->size)
- {
+ if (rdev2->sectors == rdev1->sectors) {
/*
* Not unique, don't count it as a new
* group
@@ -145,7 +147,7 @@ static int create_strip_zones (mddev_t *mddev)
mddev->queue->max_sectors > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
- if (!smallest || (rdev1->size <smallest->size))
+ if (!smallest || (rdev1->sectors < smallest->sectors))
smallest = rdev1;
cnt++;
}
@@ -155,10 +157,10 @@ static int create_strip_zones (mddev_t *mddev)
goto abort;
}
zone->nb_dev = cnt;
- zone->sectors = smallest->size * cnt * 2;
+ zone->sectors = smallest->sectors * cnt;
zone->zone_start = 0;
- current_start = smallest->size * 2;
+ current_start = smallest->sectors;
curr_zone_start = zone->sectors;
/* now do the other zones */
@@ -177,29 +179,29 @@ static int create_strip_zones (mddev_t *mddev)
rdev = conf->strip_zone[0].dev[j];
printk(KERN_INFO "raid0: checking %s ...",
bdevname(rdev->bdev, b));
- if (rdev->size > current_start / 2) {
- printk(KERN_INFO " contained as device %d\n",
- c);
- zone->dev[c] = rdev;
- c++;
- if (!smallest || (rdev->size <smallest->size)) {
- smallest = rdev;
- printk(KERN_INFO " (%llu) is smallest!.\n",
- (unsigned long long)rdev->size);
- }
- } else
+ if (rdev->sectors <= current_start) {
printk(KERN_INFO " nope.\n");
+ continue;
+ }
+ printk(KERN_INFO " contained as device %d\n", c);
+ zone->dev[c] = rdev;
+ c++;
+ if (!smallest || rdev->sectors < smallest->sectors) {
+ smallest = rdev;
+ printk(KERN_INFO " (%llu) is smallest!.\n",
+ (unsigned long long)rdev->sectors);
+ }
}
zone->nb_dev = c;
- zone->sectors = (smallest->size * 2 - current_start) * c;
+ zone->sectors = (smallest->sectors - current_start) * c;
printk(KERN_INFO "raid0: zone->nb_dev: %d, sectors: %llu\n",
zone->nb_dev, (unsigned long long)zone->sectors);
zone->zone_start = curr_zone_start;
curr_zone_start += zone->sectors;
- current_start = smallest->size * 2;
+ current_start = smallest->sectors;
printk(KERN_INFO "raid0: current zone start: %llu\n",
(unsigned long long)current_start);
}
@@ -261,12 +263,25 @@ static int raid0_mergeable_bvec(struct request_queue *q,
return max;
}
+static sector_t raid0_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ sector_t array_sectors = 0;
+ mdk_rdev_t *rdev;
+
+ WARN_ONCE(sectors || raid_disks,
+ "%s does not support generic reshape\n", __func__);
+
+ list_for_each_entry(rdev, &mddev->disks, same_set)
+ array_sectors += rdev->sectors;
+
+ return array_sectors;
+}
+
static int raid0_run (mddev_t *mddev)
{
unsigned cur=0, i=0, nb_zone;
s64 sectors;
raid0_conf_t *conf;
- mdk_rdev_t *rdev;
if (mddev->chunk_size == 0) {
printk(KERN_ERR "md/raid0: non-zero chunk size required.\n");
@@ -291,16 +306,14 @@ static int raid0_run (mddev_t *mddev)
goto out_free_conf;
/* calculate array device size */
- mddev->array_sectors = 0;
- list_for_each_entry(rdev, &mddev->disks, same_set)
- mddev->array_sectors += rdev->size * 2;
+ md_set_array_sectors(mddev, raid0_size(mddev, 0, 0));
printk(KERN_INFO "raid0 : md_size is %llu sectors.\n",
(unsigned long long)mddev->array_sectors);
printk(KERN_INFO "raid0 : conf->spacing is %llu sectors.\n",
(unsigned long long)conf->spacing);
{
- sector_t s = mddev->array_sectors;
+ sector_t s = raid0_size(mddev, 0, 0);
sector_t space = conf->spacing;
int round;
conf->sector_shift = 0;
@@ -509,6 +522,7 @@ static struct mdk_personality raid0_personality=
.run = raid0_run,
.stop = raid0_stop,
.status = raid0_status,
+ .size = raid0_size,
};
static int __init raid0_init (void)
diff --git a/include/linux/raid/raid0.h b/drivers/md/raid0.h
index fd42aa87c391..824b12eb1d4f 100644
--- a/include/linux/raid/raid0.h
+++ b/drivers/md/raid0.h
@@ -1,8 +1,6 @@
#ifndef _RAID0_H
#define _RAID0_H
-#include <linux/raid/md.h>
-
struct strip_zone
{
sector_t zone_start; /* Zone offset in md_dev (in sectors) */
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index e2466425d9ca..274b491a11c1 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -31,10 +31,13 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "dm-bio-list.h"
#include <linux/delay.h>
-#include <linux/raid/raid1.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "dm-bio-list.h"
+#include "raid1.h"
+#include "bitmap.h"
#define DEBUG 0
#if DEBUG
@@ -120,6 +123,7 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
goto out_free_pages;
bio->bi_io_vec[i].bv_page = page;
+ bio->bi_vcnt = i+1;
}
}
/* If not user-requests, copy the page pointers to all bios */
@@ -135,9 +139,9 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
return r1_bio;
out_free_pages:
- for (i=0; i < RESYNC_PAGES ; i++)
- for (j=0 ; j < pi->raid_disks; j++)
- safe_put_page(r1_bio->bios[j]->bi_io_vec[i].bv_page);
+ for (j=0 ; j < pi->raid_disks; j++)
+ for (i=0; i < r1_bio->bios[j]->bi_vcnt ; i++)
+ put_page(r1_bio->bios[j]->bi_io_vec[i].bv_page);
j = -1;
out_free_bio:
while ( ++j < pi->raid_disks )
@@ -582,7 +586,7 @@ static int raid1_congested(void *data, int bits)
/* Note the '|| 1' - when read_balance prefers
* non-congested targets, it can be removed
*/
- if ((bits & (1<<BDI_write_congested)) || 1)
+ if ((bits & (1<<BDI_async_congested)) || 1)
ret |= bdi_congested(&q->backing_dev_info, bits);
else
ret &= bdi_congested(&q->backing_dev_info, bits);
@@ -1723,7 +1727,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
return 0;
}
- max_sector = mddev->size << 1;
+ max_sector = mddev->dev_sectors;
if (sector_nr >= max_sector) {
/* If we aborted, we need to abort the
* sync on the 'current' bitmap chunk (there will
@@ -1919,6 +1923,14 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
return nr_sectors;
}
+static sector_t raid1_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ if (sectors)
+ return sectors;
+
+ return mddev->dev_sectors;
+}
+
static int run(mddev_t *mddev)
{
conf_t *conf;
@@ -2048,7 +2060,7 @@ static int run(mddev_t *mddev)
/*
* Ok, everything is just fine now
*/
- mddev->array_sectors = mddev->size * 2;
+ md_set_array_sectors(mddev, raid1_size(mddev, 0, 0));
mddev->queue->unplug_fn = raid1_unplug;
mddev->queue->backing_dev_info.congested_fn = raid1_congested;
@@ -2089,6 +2101,9 @@ static int stop(mddev_t *mddev)
/* need to kick something here to make sure I/O goes? */
}
+ raise_barrier(conf);
+ lower_barrier(conf);
+
md_unregister_thread(mddev->thread);
mddev->thread = NULL;
blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
@@ -2110,15 +2125,17 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors)
* any io in the removed space completes, but it hardly seems
* worth it.
*/
- mddev->array_sectors = sectors;
+ md_set_array_sectors(mddev, raid1_size(mddev, sectors, 0));
+ if (mddev->array_sectors > raid1_size(mddev, sectors, 0))
+ return -EINVAL;
set_capacity(mddev->gendisk, mddev->array_sectors);
mddev->changed = 1;
- if (mddev->array_sectors / 2 > mddev->size &&
+ if (sectors > mddev->dev_sectors &&
mddev->recovery_cp == MaxSector) {
- mddev->recovery_cp = mddev->size << 1;
+ mddev->recovery_cp = mddev->dev_sectors;
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
}
- mddev->size = mddev->array_sectors / 2;
+ mddev->dev_sectors = sectors;
mddev->resync_max_sectors = sectors;
return 0;
}
@@ -2264,6 +2281,7 @@ static struct mdk_personality raid1_personality =
.spare_active = raid1_spare_active,
.sync_request = sync_request,
.resize = raid1_resize,
+ .size = raid1_size,
.check_reshape = raid1_reshape,
.quiesce = raid1_quiesce,
};
diff --git a/include/linux/raid/raid1.h b/drivers/md/raid1.h
index 0a9ba7c3302e..1620eea3d57c 100644
--- a/include/linux/raid/raid1.h
+++ b/drivers/md/raid1.h
@@ -1,8 +1,6 @@
#ifndef _RAID1_H
#define _RAID1_H
-#include <linux/raid/md.h>
-
typedef struct mirror_info mirror_info_t;
struct mirror_info {
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 7301631abe04..e293d92641ac 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -18,10 +18,13 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "dm-bio-list.h"
#include <linux/delay.h>
-#include <linux/raid/raid10.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "dm-bio-list.h"
+#include "raid10.h"
+#include "bitmap.h"
/*
* RAID10 provides a combination of RAID0 and RAID1 functionality.
@@ -1695,7 +1698,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
return 0;
skipped:
- max_sector = mddev->size << 1;
+ max_sector = mddev->dev_sectors;
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
max_sector = mddev->resync_max_sectors;
if (sector_nr >= max_sector) {
@@ -2020,6 +2023,25 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
goto skipped;
}
+static sector_t
+raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ sector_t size;
+ conf_t *conf = mddev_to_conf(mddev);
+
+ if (!raid_disks)
+ raid_disks = mddev->raid_disks;
+ if (!sectors)
+ sectors = mddev->dev_sectors;
+
+ size = sectors >> conf->chunk_shift;
+ sector_div(size, conf->far_copies);
+ size = size * raid_disks;
+ sector_div(size, conf->near_copies);
+
+ return size << conf->chunk_shift;
+}
+
static int run(mddev_t *mddev)
{
conf_t *conf;
@@ -2076,7 +2098,7 @@ static int run(mddev_t *mddev)
conf->far_offset = fo;
conf->chunk_mask = (sector_t)(mddev->chunk_size>>9)-1;
conf->chunk_shift = ffz(~mddev->chunk_size) - 9;
- size = mddev->size >> (conf->chunk_shift-1);
+ size = mddev->dev_sectors >> conf->chunk_shift;
sector_div(size, fc);
size = size * conf->raid_disks;
sector_div(size, nc);
@@ -2089,7 +2111,7 @@ static int run(mddev_t *mddev)
*/
stride += conf->raid_disks - 1;
sector_div(stride, conf->raid_disks);
- mddev->size = stride << (conf->chunk_shift-1);
+ mddev->dev_sectors = stride << conf->chunk_shift;
if (fo)
stride = 1;
@@ -2171,8 +2193,8 @@ static int run(mddev_t *mddev)
/*
* Ok, everything is just fine now
*/
- mddev->array_sectors = size << conf->chunk_shift;
- mddev->resync_max_sectors = size << conf->chunk_shift;
+ md_set_array_sectors(mddev, raid10_size(mddev, 0, 0));
+ mddev->resync_max_sectors = raid10_size(mddev, 0, 0);
mddev->queue->unplug_fn = raid10_unplug;
mddev->queue->backing_dev_info.congested_fn = raid10_congested;
@@ -2208,6 +2230,9 @@ static int stop(mddev_t *mddev)
{
conf_t *conf = mddev_to_conf(mddev);
+ raise_barrier(conf, 0);
+ lower_barrier(conf);
+
md_unregister_thread(mddev->thread);
mddev->thread = NULL;
blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
@@ -2255,6 +2280,7 @@ static struct mdk_personality raid10_personality =
.spare_active = raid10_spare_active,
.sync_request = sync_request,
.quiesce = raid10_quiesce,
+ .size = raid10_size,
};
static int __init raid_init(void)
diff --git a/include/linux/raid/raid10.h b/drivers/md/raid10.h
index e9091cfeb286..244dbe507a54 100644
--- a/include/linux/raid/raid10.h
+++ b/drivers/md/raid10.h
@@ -1,8 +1,6 @@
#ifndef _RAID10_H
#define _RAID10_H
-#include <linux/raid/md.h>
-
typedef struct mirror_info mirror_info_t;
struct mirror_info {
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index a5ba080d303b..3bbc6d647044 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -43,11 +43,14 @@
* miss any bits.
*/
+#include <linux/blkdev.h>
#include <linux/kthread.h>
-#include "raid6.h"
-
-#include <linux/raid/bitmap.h>
+#include <linux/raid/pq.h>
#include <linux/async_tx.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "raid5.h"
+#include "bitmap.h"
/*
* Stripe cache
@@ -91,11 +94,6 @@
#define printk_rl(args...) ((void) (printk_ratelimit() && printk(args)))
-#if !RAID6_USE_EMPTY_ZERO_PAGE
-/* In .bss so it's zeroed */
-const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
-#endif
-
/*
* We maintain a biased count of active stripes in the bottom 16 bits of
* bi_phys_segments, and a count of processed stripes in the upper 16 bits
@@ -130,12 +128,42 @@ static inline void raid5_set_bi_hw_segments(struct bio *bio, unsigned int cnt)
bio->bi_phys_segments = raid5_bi_phys_segments(bio) || (cnt << 16);
}
+/* Find first data disk in a raid6 stripe */
+static inline int raid6_d0(struct stripe_head *sh)
+{
+ if (sh->ddf_layout)
+ /* ddf always start from first device */
+ return 0;
+ /* md starts just after Q block */
+ if (sh->qd_idx == sh->disks - 1)
+ return 0;
+ else
+ return sh->qd_idx + 1;
+}
static inline int raid6_next_disk(int disk, int raid_disks)
{
disk++;
return (disk < raid_disks) ? disk : 0;
}
+/* When walking through the disks in a raid5, starting at raid6_d0,
+ * We need to map each disk to a 'slot', where the data disks are slot
+ * 0 .. raid_disks-3, the parity disk is raid_disks-2 and the Q disk
+ * is raid_disks-1. This help does that mapping.
+ */
+static int raid6_idx_to_slot(int idx, struct stripe_head *sh,
+ int *count, int syndrome_disks)
+{
+ int slot;
+
+ if (idx == sh->pd_idx)
+ return syndrome_disks;
+ if (idx == sh->qd_idx)
+ return syndrome_disks + 1;
+ slot = (*count)++;
+ return slot;
+}
+
static void return_io(struct bio *return_bi)
{
struct bio *bi = return_bi;
@@ -193,6 +221,7 @@ static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh)
}
}
}
+
static void release_stripe(struct stripe_head *sh)
{
raid5_conf_t *conf = sh->raid_conf;
@@ -270,9 +299,11 @@ static int grow_buffers(struct stripe_head *sh, int num)
return 0;
}
-static void raid5_build_block(struct stripe_head *sh, int i);
+static void raid5_build_block(struct stripe_head *sh, int i, int previous);
+static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous,
+ struct stripe_head *sh);
-static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks)
+static void init_stripe(struct stripe_head *sh, sector_t sector, int previous)
{
raid5_conf_t *conf = sh->raid_conf;
int i;
@@ -287,11 +318,12 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int
remove_hash(sh);
+ sh->generation = conf->generation - previous;
+ sh->disks = previous ? conf->previous_raid_disks : conf->raid_disks;
sh->sector = sector;
- sh->pd_idx = pd_idx;
+ stripe_set_idx(sector, conf, previous, sh);
sh->state = 0;
- sh->disks = disks;
for (i = sh->disks; i--; ) {
struct r5dev *dev = &sh->dev[i];
@@ -305,12 +337,13 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int
BUG();
}
dev->flags = 0;
- raid5_build_block(sh, i);
+ raid5_build_block(sh, i, previous);
}
insert_hash(conf, sh);
}
-static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, int disks)
+static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector,
+ short generation)
{
struct stripe_head *sh;
struct hlist_node *hn;
@@ -318,7 +351,7 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, in
CHECK_DEVLOCK();
pr_debug("__find_stripe, sector %llu\n", (unsigned long long)sector);
hlist_for_each_entry(sh, hn, stripe_hash(conf, sector), hash)
- if (sh->sector == sector && sh->disks == disks)
+ if (sh->sector == sector && sh->generation == generation)
return sh;
pr_debug("__stripe %llu not in cache\n", (unsigned long long)sector);
return NULL;
@@ -327,8 +360,9 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, in
static void unplug_slaves(mddev_t *mddev);
static void raid5_unplug_device(struct request_queue *q);
-static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector, int disks,
- int pd_idx, int noblock)
+static struct stripe_head *
+get_active_stripe(raid5_conf_t *conf, sector_t sector,
+ int previous, int noblock)
{
struct stripe_head *sh;
@@ -340,7 +374,7 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
wait_event_lock_irq(conf->wait_for_stripe,
conf->quiesce == 0,
conf->device_lock, /* nothing */);
- sh = __find_stripe(conf, sector, disks);
+ sh = __find_stripe(conf, sector, conf->generation - previous);
if (!sh) {
if (!conf->inactive_blocked)
sh = get_free_stripe(conf);
@@ -358,10 +392,11 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
);
conf->inactive_blocked = 0;
} else
- init_stripe(sh, sector, pd_idx, disks);
+ init_stripe(sh, sector, previous);
} else {
if (atomic_read(&sh->count)) {
- BUG_ON(!list_empty(&sh->lru));
+ BUG_ON(!list_empty(&sh->lru)
+ && !test_bit(STRIPE_EXPANDING, &sh->state));
} else {
if (!test_bit(STRIPE_HANDLE, &sh->state))
atomic_inc(&conf->active_stripes);
@@ -895,8 +930,10 @@ static int grow_stripes(raid5_conf_t *conf, int num)
struct kmem_cache *sc;
int devs = conf->raid_disks;
- sprintf(conf->cache_name[0], "raid5-%s", mdname(conf->mddev));
- sprintf(conf->cache_name[1], "raid5-%s-alt", mdname(conf->mddev));
+ sprintf(conf->cache_name[0],
+ "raid%d-%s", conf->level, mdname(conf->mddev));
+ sprintf(conf->cache_name[1],
+ "raid%d-%s-alt", conf->level, mdname(conf->mddev));
conf->active_name = 0;
sc = kmem_cache_create(conf->cache_name[conf->active_name],
sizeof(struct stripe_head)+(devs-1)*sizeof(struct r5dev),
@@ -911,7 +948,6 @@ static int grow_stripes(raid5_conf_t *conf, int num)
return 0;
}
-#ifdef CONFIG_MD_RAID5_RESHAPE
static int resize_stripes(raid5_conf_t *conf, int newsize)
{
/* Make all the stripes able to hold 'newsize' devices.
@@ -1036,7 +1072,6 @@ static int resize_stripes(raid5_conf_t *conf, int newsize)
conf->pool_size = newsize;
return err;
}
-#endif
static int drop_one_stripe(raid5_conf_t *conf)
{
@@ -1066,7 +1101,7 @@ static void shrink_stripes(raid5_conf_t *conf)
static void raid5_end_read_request(struct bio * bi, int error)
{
- struct stripe_head *sh = bi->bi_private;
+ struct stripe_head *sh = bi->bi_private;
raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks, i;
int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1148,7 +1183,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
static void raid5_end_write_request(struct bio *bi, int error)
{
- struct stripe_head *sh = bi->bi_private;
+ struct stripe_head *sh = bi->bi_private;
raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks, i;
int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1176,9 +1211,9 @@ static void raid5_end_write_request(struct bio *bi, int error)
}
-static sector_t compute_blocknr(struct stripe_head *sh, int i);
+static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous);
-static void raid5_build_block(struct stripe_head *sh, int i)
+static void raid5_build_block(struct stripe_head *sh, int i, int previous)
{
struct r5dev *dev = &sh->dev[i];
@@ -1194,7 +1229,7 @@ static void raid5_build_block(struct stripe_head *sh, int i)
dev->req.bi_private = sh;
dev->flags = 0;
- dev->sector = compute_blocknr(sh, i);
+ dev->sector = compute_blocknr(sh, i, previous);
}
static void error(mddev_t *mddev, mdk_rdev_t *rdev)
@@ -1227,15 +1262,23 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
* Input: a 'big' sector number,
* Output: index of the data and parity disk, and the sector # in them.
*/
-static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
- unsigned int data_disks, unsigned int * dd_idx,
- unsigned int * pd_idx, raid5_conf_t *conf)
+static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
+ int previous, int *dd_idx,
+ struct stripe_head *sh)
{
long stripe;
unsigned long chunk_number;
unsigned int chunk_offset;
+ int pd_idx, qd_idx;
+ int ddf_layout = 0;
sector_t new_sector;
- int sectors_per_chunk = conf->chunk_size >> 9;
+ int algorithm = previous ? conf->prev_algo
+ : conf->algorithm;
+ int sectors_per_chunk = previous ? (conf->prev_chunk >> 9)
+ : (conf->chunk_size >> 9);
+ int raid_disks = previous ? conf->previous_raid_disks
+ : conf->raid_disks;
+ int data_disks = raid_disks - conf->max_degraded;
/* First compute the information on this sector */
@@ -1259,68 +1302,170 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
/*
* Select the parity disk based on the user selected algorithm.
*/
+ pd_idx = qd_idx = ~0;
switch(conf->level) {
case 4:
- *pd_idx = data_disks;
+ pd_idx = data_disks;
break;
case 5:
- switch (conf->algorithm) {
+ switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
- *pd_idx = data_disks - stripe % raid_disks;
- if (*dd_idx >= *pd_idx)
+ pd_idx = data_disks - stripe % raid_disks;
+ if (*dd_idx >= pd_idx)
(*dd_idx)++;
break;
case ALGORITHM_RIGHT_ASYMMETRIC:
- *pd_idx = stripe % raid_disks;
- if (*dd_idx >= *pd_idx)
+ pd_idx = stripe % raid_disks;
+ if (*dd_idx >= pd_idx)
(*dd_idx)++;
break;
case ALGORITHM_LEFT_SYMMETRIC:
- *pd_idx = data_disks - stripe % raid_disks;
- *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
+ pd_idx = data_disks - stripe % raid_disks;
+ *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
break;
case ALGORITHM_RIGHT_SYMMETRIC:
- *pd_idx = stripe % raid_disks;
- *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
+ pd_idx = stripe % raid_disks;
+ *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
+ break;
+ case ALGORITHM_PARITY_0:
+ pd_idx = 0;
+ (*dd_idx)++;
+ break;
+ case ALGORITHM_PARITY_N:
+ pd_idx = data_disks;
break;
default:
printk(KERN_ERR "raid5: unsupported algorithm %d\n",
- conf->algorithm);
+ algorithm);
+ BUG();
}
break;
case 6:
- /**** FIX THIS ****/
- switch (conf->algorithm) {
+ switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
- *pd_idx = raid_disks - 1 - (stripe % raid_disks);
- if (*pd_idx == raid_disks-1)
- (*dd_idx)++; /* Q D D D P */
- else if (*dd_idx >= *pd_idx)
+ pd_idx = raid_disks - 1 - (stripe % raid_disks);
+ qd_idx = pd_idx + 1;
+ if (pd_idx == raid_disks-1) {
+ (*dd_idx)++; /* Q D D D P */
+ qd_idx = 0;
+ } else if (*dd_idx >= pd_idx)
(*dd_idx) += 2; /* D D P Q D */
break;
case ALGORITHM_RIGHT_ASYMMETRIC:
- *pd_idx = stripe % raid_disks;
- if (*pd_idx == raid_disks-1)
- (*dd_idx)++; /* Q D D D P */
- else if (*dd_idx >= *pd_idx)
+ pd_idx = stripe % raid_disks;
+ qd_idx = pd_idx + 1;
+ if (pd_idx == raid_disks-1) {
+ (*dd_idx)++; /* Q D D D P */
+ qd_idx = 0;
+ } else if (*dd_idx >= pd_idx)
(*dd_idx) += 2; /* D D P Q D */
break;
case ALGORITHM_LEFT_SYMMETRIC:
- *pd_idx = raid_disks - 1 - (stripe % raid_disks);
- *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
+ pd_idx = raid_disks - 1 - (stripe % raid_disks);
+ qd_idx = (pd_idx + 1) % raid_disks;
+ *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
break;
case ALGORITHM_RIGHT_SYMMETRIC:
- *pd_idx = stripe % raid_disks;
- *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
+ pd_idx = stripe % raid_disks;
+ qd_idx = (pd_idx + 1) % raid_disks;
+ *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
+ break;
+
+ case ALGORITHM_PARITY_0:
+ pd_idx = 0;
+ qd_idx = 1;
+ (*dd_idx) += 2;
+ break;
+ case ALGORITHM_PARITY_N:
+ pd_idx = data_disks;
+ qd_idx = data_disks + 1;
break;
+
+ case ALGORITHM_ROTATING_ZERO_RESTART:
+ /* Exactly the same as RIGHT_ASYMMETRIC, but or
+ * of blocks for computing Q is different.
+ */
+ pd_idx = stripe % raid_disks;
+ qd_idx = pd_idx + 1;
+ if (pd_idx == raid_disks-1) {
+ (*dd_idx)++; /* Q D D D P */
+ qd_idx = 0;
+ } else if (*dd_idx >= pd_idx)
+ (*dd_idx) += 2; /* D D P Q D */
+ ddf_layout = 1;
+ break;
+
+ case ALGORITHM_ROTATING_N_RESTART:
+ /* Same a left_asymmetric, by first stripe is
+ * D D D P Q rather than
+ * Q D D D P
+ */
+ pd_idx = raid_disks - 1 - ((stripe + 1) % raid_disks);
+ qd_idx = pd_idx + 1;
+ if (pd_idx == raid_disks-1) {
+ (*dd_idx)++; /* Q D D D P */
+ qd_idx = 0;
+ } else if (*dd_idx >= pd_idx)
+ (*dd_idx) += 2; /* D D P Q D */
+ ddf_layout = 1;
+ break;
+
+ case ALGORITHM_ROTATING_N_CONTINUE:
+ /* Same as left_symmetric but Q is before P */
+ pd_idx = raid_disks - 1 - (stripe % raid_disks);
+ qd_idx = (pd_idx + raid_disks - 1) % raid_disks;
+ *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
+ ddf_layout = 1;
+ break;
+
+ case ALGORITHM_LEFT_ASYMMETRIC_6:
+ /* RAID5 left_asymmetric, with Q on last device */
+ pd_idx = data_disks - stripe % (raid_disks-1);
+ if (*dd_idx >= pd_idx)
+ (*dd_idx)++;
+ qd_idx = raid_disks - 1;
+ break;
+
+ case ALGORITHM_RIGHT_ASYMMETRIC_6:
+ pd_idx = stripe % (raid_disks-1);
+ if (*dd_idx >= pd_idx)
+ (*dd_idx)++;
+ qd_idx = raid_disks - 1;
+ break;
+
+ case ALGORITHM_LEFT_SYMMETRIC_6:
+ pd_idx = data_disks - stripe % (raid_disks-1);
+ *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
+ qd_idx = raid_disks - 1;
+ break;
+
+ case ALGORITHM_RIGHT_SYMMETRIC_6:
+ pd_idx = stripe % (raid_disks-1);
+ *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
+ qd_idx = raid_disks - 1;
+ break;
+
+ case ALGORITHM_PARITY_0_6:
+ pd_idx = 0;
+ (*dd_idx)++;
+ qd_idx = raid_disks - 1;
+ break;
+
+
default:
printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
- conf->algorithm);
+ algorithm);
+ BUG();
}
break;
}
+ if (sh) {
+ sh->pd_idx = pd_idx;
+ sh->qd_idx = qd_idx;
+ sh->ddf_layout = ddf_layout;
+ }
/*
* Finally, compute the new sector number
*/
@@ -1329,17 +1474,21 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
}
-static sector_t compute_blocknr(struct stripe_head *sh, int i)
+static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
{
raid5_conf_t *conf = sh->raid_conf;
int raid_disks = sh->disks;
int data_disks = raid_disks - conf->max_degraded;
sector_t new_sector = sh->sector, check;
- int sectors_per_chunk = conf->chunk_size >> 9;
+ int sectors_per_chunk = previous ? (conf->prev_chunk >> 9)
+ : (conf->chunk_size >> 9);
+ int algorithm = previous ? conf->prev_algo
+ : conf->algorithm;
sector_t stripe;
int chunk_offset;
- int chunk_number, dummy1, dummy2, dd_idx = i;
+ int chunk_number, dummy1, dd_idx = i;
sector_t r_sector;
+ struct stripe_head sh2;
chunk_offset = sector_div(new_sector, sectors_per_chunk);
@@ -1351,7 +1500,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
switch(conf->level) {
case 4: break;
case 5:
- switch (conf->algorithm) {
+ switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
case ALGORITHM_RIGHT_ASYMMETRIC:
if (i > sh->pd_idx)
@@ -1363,19 +1512,27 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
i += raid_disks;
i -= (sh->pd_idx + 1);
break;
+ case ALGORITHM_PARITY_0:
+ i -= 1;
+ break;
+ case ALGORITHM_PARITY_N:
+ break;
default:
printk(KERN_ERR "raid5: unsupported algorithm %d\n",
- conf->algorithm);
+ algorithm);
+ BUG();
}
break;
case 6:
- if (i == raid6_next_disk(sh->pd_idx, raid_disks))
+ if (i == sh->qd_idx)
return 0; /* It is the Q disk */
- switch (conf->algorithm) {
+ switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
case ALGORITHM_RIGHT_ASYMMETRIC:
- if (sh->pd_idx == raid_disks-1)
- i--; /* Q D D D P */
+ case ALGORITHM_ROTATING_ZERO_RESTART:
+ case ALGORITHM_ROTATING_N_RESTART:
+ if (sh->pd_idx == raid_disks-1)
+ i--; /* Q D D D P */
else if (i > sh->pd_idx)
i -= 2; /* D D P Q D */
break;
@@ -1390,9 +1547,35 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
i -= (sh->pd_idx + 2);
}
break;
+ case ALGORITHM_PARITY_0:
+ i -= 2;
+ break;
+ case ALGORITHM_PARITY_N:
+ break;
+ case ALGORITHM_ROTATING_N_CONTINUE:
+ if (sh->pd_idx == 0)
+ i--; /* P D D D Q */
+ else if (i > sh->pd_idx)
+ i -= 2; /* D D Q P D */
+ break;
+ case ALGORITHM_LEFT_ASYMMETRIC_6:
+ case ALGORITHM_RIGHT_ASYMMETRIC_6:
+ if (i > sh->pd_idx)
+ i--;
+ break;
+ case ALGORITHM_LEFT_SYMMETRIC_6:
+ case ALGORITHM_RIGHT_SYMMETRIC_6:
+ if (i < sh->pd_idx)
+ i += data_disks + 1;
+ i -= (sh->pd_idx + 1);
+ break;
+ case ALGORITHM_PARITY_0_6:
+ i -= 1;
+ break;
default:
printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
- conf->algorithm);
+ algorithm);
+ BUG();
}
break;
}
@@ -1400,8 +1583,10 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
chunk_number = stripe * data_disks + i;
r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
- check = raid5_compute_sector(r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
- if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
+ check = raid5_compute_sector(conf, r_sector,
+ previous, &dummy1, &sh2);
+ if (check != sh->sector || dummy1 != dd_idx || sh2.pd_idx != sh->pd_idx
+ || sh2.qd_idx != sh->qd_idx) {
printk(KERN_ERR "compute_blocknr: map not correct\n");
return 0;
}
@@ -1468,14 +1653,16 @@ static void copy_data(int frombio, struct bio *bio,
static void compute_parity6(struct stripe_head *sh, int method)
{
- raid6_conf_t *conf = sh->raid_conf;
- int i, pd_idx = sh->pd_idx, qd_idx, d0_idx, disks = sh->disks, count;
+ raid5_conf_t *conf = sh->raid_conf;
+ int i, pd_idx, qd_idx, d0_idx, disks = sh->disks, count;
+ int syndrome_disks = sh->ddf_layout ? disks : (disks - 2);
struct bio *chosen;
/**** FIX THIS: This could be very bad if disks is close to 256 ****/
- void *ptrs[disks];
+ void *ptrs[syndrome_disks+2];
- qd_idx = raid6_next_disk(pd_idx, disks);
- d0_idx = raid6_next_disk(qd_idx, disks);
+ pd_idx = sh->pd_idx;
+ qd_idx = sh->qd_idx;
+ d0_idx = raid6_d0(sh);
pr_debug("compute_parity, stripe %llu, method %d\n",
(unsigned long long)sh->sector, method);
@@ -1513,24 +1700,29 @@ static void compute_parity6(struct stripe_head *sh, int method)
set_bit(R5_UPTODATE, &sh->dev[i].flags);
}
-// switch(method) {
-// case RECONSTRUCT_WRITE:
-// case CHECK_PARITY:
-// case UPDATE_PARITY:
- /* Note that unlike RAID-5, the ordering of the disks matters greatly. */
- /* FIX: Is this ordering of drives even remotely optimal? */
- count = 0;
- i = d0_idx;
- do {
- ptrs[count++] = page_address(sh->dev[i].page);
- if (count <= disks-2 && !test_bit(R5_UPTODATE, &sh->dev[i].flags))
- printk("block %d/%d not uptodate on parity calc\n", i,count);
- i = raid6_next_disk(i, disks);
- } while ( i != d0_idx );
-// break;
-// }
-
- raid6_call.gen_syndrome(disks, STRIPE_SIZE, ptrs);
+ /* Note that unlike RAID-5, the ordering of the disks matters greatly.*/
+
+ for (i = 0; i < disks; i++)
+ ptrs[i] = (void *)raid6_empty_zero_page;
+
+ count = 0;
+ i = d0_idx;
+ do {
+ int slot = raid6_idx_to_slot(i, sh, &count, syndrome_disks);
+
+ ptrs[slot] = page_address(sh->dev[i].page);
+ if (slot < syndrome_disks &&
+ !test_bit(R5_UPTODATE, &sh->dev[i].flags)) {
+ printk(KERN_ERR "block %d/%d not uptodate "
+ "on parity calc\n", i, count);
+ BUG();
+ }
+
+ i = raid6_next_disk(i, disks);
+ } while (i != d0_idx);
+ BUG_ON(count != syndrome_disks);
+
+ raid6_call.gen_syndrome(syndrome_disks+2, STRIPE_SIZE, ptrs);
switch(method) {
case RECONSTRUCT_WRITE:
@@ -1552,8 +1744,7 @@ static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero)
{
int i, count, disks = sh->disks;
void *ptr[MAX_XOR_BLOCKS], *dest, *p;
- int pd_idx = sh->pd_idx;
- int qd_idx = raid6_next_disk(pd_idx, disks);
+ int qd_idx = sh->qd_idx;
pr_debug("compute_block_1, stripe %llu, idx %d\n",
(unsigned long long)sh->sector, dd_idx);
@@ -1589,63 +1780,65 @@ static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero)
static void compute_block_2(struct stripe_head *sh, int dd_idx1, int dd_idx2)
{
int i, count, disks = sh->disks;
- int pd_idx = sh->pd_idx;
- int qd_idx = raid6_next_disk(pd_idx, disks);
- int d0_idx = raid6_next_disk(qd_idx, disks);
- int faila, failb;
+ int syndrome_disks = sh->ddf_layout ? disks : disks-2;
+ int d0_idx = raid6_d0(sh);
+ int faila = -1, failb = -1;
+ /**** FIX THIS: This could be very bad if disks is close to 256 ****/
+ void *ptrs[syndrome_disks+2];
- /* faila and failb are disk numbers relative to d0_idx */
- /* pd_idx become disks-2 and qd_idx become disks-1 */
- faila = (dd_idx1 < d0_idx) ? dd_idx1+(disks-d0_idx) : dd_idx1-d0_idx;
- failb = (dd_idx2 < d0_idx) ? dd_idx2+(disks-d0_idx) : dd_idx2-d0_idx;
+ for (i = 0; i < disks ; i++)
+ ptrs[i] = (void *)raid6_empty_zero_page;
+ count = 0;
+ i = d0_idx;
+ do {
+ int slot = raid6_idx_to_slot(i, sh, &count, syndrome_disks);
+
+ ptrs[slot] = page_address(sh->dev[i].page);
+
+ if (i == dd_idx1)
+ faila = slot;
+ if (i == dd_idx2)
+ failb = slot;
+ i = raid6_next_disk(i, disks);
+ } while (i != d0_idx);
+ BUG_ON(count != syndrome_disks);
BUG_ON(faila == failb);
if ( failb < faila ) { int tmp = faila; faila = failb; failb = tmp; }
pr_debug("compute_block_2, stripe %llu, idx %d,%d (%d,%d)\n",
- (unsigned long long)sh->sector, dd_idx1, dd_idx2, faila, failb);
+ (unsigned long long)sh->sector, dd_idx1, dd_idx2,
+ faila, failb);
- if ( failb == disks-1 ) {
+ if (failb == syndrome_disks+1) {
/* Q disk is one of the missing disks */
- if ( faila == disks-2 ) {
+ if (faila == syndrome_disks) {
/* Missing P+Q, just recompute */
compute_parity6(sh, UPDATE_PARITY);
return;
} else {
/* We're missing D+Q; recompute D from P */
- compute_block_1(sh, (dd_idx1 == qd_idx) ? dd_idx2 : dd_idx1, 0);
+ compute_block_1(sh, ((dd_idx1 == sh->qd_idx) ?
+ dd_idx2 : dd_idx1),
+ 0);
compute_parity6(sh, UPDATE_PARITY); /* Is this necessary? */
return;
}
}
- /* We're missing D+P or D+D; build pointer table */
- {
- /**** FIX THIS: This could be very bad if disks is close to 256 ****/
- void *ptrs[disks];
-
- count = 0;
- i = d0_idx;
- do {
- ptrs[count++] = page_address(sh->dev[i].page);
- i = raid6_next_disk(i, disks);
- if (i != dd_idx1 && i != dd_idx2 &&
- !test_bit(R5_UPTODATE, &sh->dev[i].flags))
- printk("compute_2 with missing block %d/%d\n", count, i);
- } while ( i != d0_idx );
-
- if ( failb == disks-2 ) {
- /* We're missing D+P. */
- raid6_datap_recov(disks, STRIPE_SIZE, faila, ptrs);
- } else {
- /* We're missing D+D. */
- raid6_2data_recov(disks, STRIPE_SIZE, faila, failb, ptrs);
- }
-
- /* Both the above update both missing blocks */
- set_bit(R5_UPTODATE, &sh->dev[dd_idx1].flags);
- set_bit(R5_UPTODATE, &sh->dev[dd_idx2].flags);
+ /* We're missing D+P or D+D; */
+ if (failb == syndrome_disks) {
+ /* We're missing D+P. */
+ raid6_datap_recov(syndrome_disks+2, STRIPE_SIZE, faila, ptrs);
+ } else {
+ /* We're missing D+D. */
+ raid6_2data_recov(syndrome_disks+2, STRIPE_SIZE, faila, failb,
+ ptrs);
}
+
+ /* Both the above update both missing blocks */
+ set_bit(R5_UPTODATE, &sh->dev[dd_idx1].flags);
+ set_bit(R5_UPTODATE, &sh->dev[dd_idx2].flags);
}
static void
@@ -1800,17 +1993,21 @@ static int page_is_zero(struct page *p)
memcmp(a, a+4, STRIPE_SIZE-4)==0);
}
-static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks)
+static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous,
+ struct stripe_head *sh)
{
- int sectors_per_chunk = conf->chunk_size >> 9;
- int pd_idx, dd_idx;
+ int sectors_per_chunk =
+ previous ? (conf->prev_chunk >> 9)
+ : (conf->chunk_size >> 9);
+ int dd_idx;
int chunk_offset = sector_div(stripe, sectors_per_chunk);
+ int disks = previous ? conf->previous_raid_disks : conf->raid_disks;
- raid5_compute_sector(stripe * (disks - conf->max_degraded)
+ raid5_compute_sector(conf,
+ stripe * (disks - conf->max_degraded)
*sectors_per_chunk + chunk_offset,
- disks, disks - conf->max_degraded,
- &dd_idx, &pd_idx, conf);
- return pd_idx;
+ previous,
+ &dd_idx, sh);
}
static void
@@ -2181,7 +2378,7 @@ static void handle_stripe_dirtying6(raid5_conf_t *conf,
struct r6_state *r6s, int disks)
{
int rcw = 0, must_compute = 0, pd_idx = sh->pd_idx, i;
- int qd_idx = r6s->qd_idx;
+ int qd_idx = sh->qd_idx;
for (i = disks; i--; ) {
struct r5dev *dev = &sh->dev[i];
/* Would I have to read this buffer for reconstruct_write */
@@ -2371,7 +2568,7 @@ static void handle_parity_checks6(raid5_conf_t *conf, struct stripe_head *sh,
int update_p = 0, update_q = 0;
struct r5dev *dev;
int pd_idx = sh->pd_idx;
- int qd_idx = r6s->qd_idx;
+ int qd_idx = sh->qd_idx;
set_bit(STRIPE_HANDLE, &sh->state);
@@ -2467,17 +2664,14 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
struct dma_async_tx_descriptor *tx = NULL;
clear_bit(STRIPE_EXPAND_SOURCE, &sh->state);
for (i = 0; i < sh->disks; i++)
- if (i != sh->pd_idx && (!r6s || i != r6s->qd_idx)) {
- int dd_idx, pd_idx, j;
+ if (i != sh->pd_idx && i != sh->qd_idx) {
+ int dd_idx, j;
struct stripe_head *sh2;
- sector_t bn = compute_blocknr(sh, i);
- sector_t s = raid5_compute_sector(bn, conf->raid_disks,
- conf->raid_disks -
- conf->max_degraded, &dd_idx,
- &pd_idx, conf);
- sh2 = get_active_stripe(conf, s, conf->raid_disks,
- pd_idx, 1);
+ sector_t bn = compute_blocknr(sh, i, 1);
+ sector_t s = raid5_compute_sector(conf, bn, 0,
+ &dd_idx, NULL);
+ sh2 = get_active_stripe(conf, s, 0, 1);
if (sh2 == NULL)
/* so far only the early blocks of this stripe
* have been requested. When later blocks
@@ -2500,8 +2694,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
set_bit(R5_UPTODATE, &sh2->dev[dd_idx].flags);
for (j = 0; j < conf->raid_disks; j++)
if (j != sh2->pd_idx &&
- (!r6s || j != raid6_next_disk(sh2->pd_idx,
- sh2->disks)) &&
+ (!r6s || j != sh2->qd_idx) &&
!test_bit(R5_Expanded, &sh2->dev[j].flags))
break;
if (j == conf->raid_disks) {
@@ -2750,6 +2943,23 @@ static bool handle_stripe5(struct stripe_head *sh)
/* Finish reconstruct operations initiated by the expansion process */
if (sh->reconstruct_state == reconstruct_state_result) {
+ struct stripe_head *sh2
+ = get_active_stripe(conf, sh->sector, 1, 1);
+ if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
+ /* sh cannot be written until sh2 has been read.
+ * so arrange for sh to be delayed a little
+ */
+ set_bit(STRIPE_DELAYED, &sh->state);
+ set_bit(STRIPE_HANDLE, &sh->state);
+ if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE,
+ &sh2->state))
+ atomic_inc(&conf->preread_active_stripes);
+ release_stripe(sh2);
+ goto unlock;
+ }
+ if (sh2)
+ release_stripe(sh2);
+
sh->reconstruct_state = reconstruct_state_idle;
clear_bit(STRIPE_EXPANDING, &sh->state);
for (i = conf->raid_disks; i--; ) {
@@ -2763,8 +2973,7 @@ static bool handle_stripe5(struct stripe_head *sh)
!sh->reconstruct_state) {
/* Need to write out all blocks after computing parity */
sh->disks = conf->raid_disks;
- sh->pd_idx = stripe_to_pdidx(sh->sector, conf,
- conf->raid_disks);
+ stripe_set_idx(sh->sector, conf, 0, sh);
schedule_reconstruction5(sh, &s, 1, 1);
} else if (s.expanded && !sh->reconstruct_state && s.locked == 0) {
clear_bit(STRIPE_EXPAND_READY, &sh->state);
@@ -2796,20 +3005,19 @@ static bool handle_stripe5(struct stripe_head *sh)
static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
{
- raid6_conf_t *conf = sh->raid_conf;
+ raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks;
struct bio *return_bi = NULL;
- int i, pd_idx = sh->pd_idx;
+ int i, pd_idx = sh->pd_idx, qd_idx = sh->qd_idx;
struct stripe_head_state s;
struct r6_state r6s;
struct r5dev *dev, *pdev, *qdev;
mdk_rdev_t *blocked_rdev = NULL;
- r6s.qd_idx = raid6_next_disk(pd_idx, disks);
pr_debug("handling stripe %llu, state=%#lx cnt=%d, "
"pd_idx=%d, qd_idx=%d\n",
(unsigned long long)sh->sector, sh->state,
- atomic_read(&sh->count), pd_idx, r6s.qd_idx);
+ atomic_read(&sh->count), pd_idx, qd_idx);
memset(&s, 0, sizeof(s));
spin_lock(&sh->lock);
@@ -2920,9 +3128,9 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
pdev = &sh->dev[pd_idx];
r6s.p_failed = (s.failed >= 1 && r6s.failed_num[0] == pd_idx)
|| (s.failed >= 2 && r6s.failed_num[1] == pd_idx);
- qdev = &sh->dev[r6s.qd_idx];
- r6s.q_failed = (s.failed >= 1 && r6s.failed_num[0] == r6s.qd_idx)
- || (s.failed >= 2 && r6s.failed_num[1] == r6s.qd_idx);
+ qdev = &sh->dev[qd_idx];
+ r6s.q_failed = (s.failed >= 1 && r6s.failed_num[0] == qd_idx)
+ || (s.failed >= 2 && r6s.failed_num[1] == qd_idx);
if ( s.written &&
( r6s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
@@ -2980,10 +3188,26 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
}
if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state)) {
+ struct stripe_head *sh2
+ = get_active_stripe(conf, sh->sector, 1, 1);
+ if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
+ /* sh cannot be written until sh2 has been read.
+ * so arrange for sh to be delayed a little
+ */
+ set_bit(STRIPE_DELAYED, &sh->state);
+ set_bit(STRIPE_HANDLE, &sh->state);
+ if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE,
+ &sh2->state))
+ atomic_inc(&conf->preread_active_stripes);
+ release_stripe(sh2);
+ goto unlock;
+ }
+ if (sh2)
+ release_stripe(sh2);
+
/* Need to write out all blocks after computing P&Q */
sh->disks = conf->raid_disks;
- sh->pd_idx = stripe_to_pdidx(sh->sector, conf,
- conf->raid_disks);
+ stripe_set_idx(sh->sector, conf, 0, sh);
compute_parity6(sh, RECONSTRUCT_WRITE);
for (i = conf->raid_disks ; i-- ; ) {
set_bit(R5_LOCKED, &sh->dev[i].flags);
@@ -3134,6 +3358,8 @@ static int raid5_mergeable_bvec(struct request_queue *q,
if ((bvm->bi_rw & 1) == WRITE)
return biovec->bv_len; /* always allow writes to be mergeable */
+ if (mddev->new_chunk < mddev->chunk_size)
+ chunk_sectors = mddev->new_chunk >> 9;
max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9;
if (max < 0) max = 0;
if (max <= biovec->bv_len && bio_sectors == 0)
@@ -3149,6 +3375,8 @@ static int in_chunk_boundary(mddev_t *mddev, struct bio *bio)
unsigned int chunk_sectors = mddev->chunk_size >> 9;
unsigned int bio_sectors = bio->bi_size >> 9;
+ if (mddev->new_chunk < mddev->chunk_size)
+ chunk_sectors = mddev->new_chunk >> 9;
return chunk_sectors >=
((sector & (chunk_sectors - 1)) + bio_sectors);
}
@@ -3255,9 +3483,7 @@ static int chunk_aligned_read(struct request_queue *q, struct bio * raid_bio)
{
mddev_t *mddev = q->queuedata;
raid5_conf_t *conf = mddev_to_conf(mddev);
- const unsigned int raid_disks = conf->raid_disks;
- const unsigned int data_disks = raid_disks - conf->max_degraded;
- unsigned int dd_idx, pd_idx;
+ unsigned int dd_idx;
struct bio* align_bi;
mdk_rdev_t *rdev;
@@ -3266,7 +3492,7 @@ static int chunk_aligned_read(struct request_queue *q, struct bio * raid_bio)
return 0;
}
/*
- * use bio_clone to make a copy of the bio
+ * use bio_clone to make a copy of the bio
*/
align_bi = bio_clone(raid_bio, GFP_NOIO);
if (!align_bi)
@@ -3280,12 +3506,9 @@ static int chunk_aligned_read(struct request_queue *q, struct bio * raid_bio)
/*
* compute position
*/
- align_bi->bi_sector = raid5_compute_sector(raid_bio->bi_sector,
- raid_disks,
- data_disks,
- &dd_idx,
- &pd_idx,
- conf);
+ align_bi->bi_sector = raid5_compute_sector(conf, raid_bio->bi_sector,
+ 0,
+ &dd_idx, NULL);
rcu_read_lock();
rdev = rcu_dereference(conf->disks[dd_idx].rdev);
@@ -3377,7 +3600,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
{
mddev_t *mddev = q->queuedata;
raid5_conf_t *conf = mddev_to_conf(mddev);
- unsigned int dd_idx, pd_idx;
+ int dd_idx;
sector_t new_sector;
sector_t logical_sector, last_sector;
struct stripe_head *sh;
@@ -3400,7 +3623,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
if (rw == READ &&
mddev->reshape_position == MaxSector &&
chunk_aligned_read(q,bi))
- return 0;
+ return 0;
logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
last_sector = bi->bi_sector + (bi->bi_size>>9);
@@ -3410,26 +3633,31 @@ static int make_request(struct request_queue *q, struct bio * bi)
for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
DEFINE_WAIT(w);
int disks, data_disks;
+ int previous;
retry:
+ previous = 0;
+ disks = conf->raid_disks;
prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE);
- if (likely(conf->expand_progress == MaxSector))
- disks = conf->raid_disks;
- else {
- /* spinlock is needed as expand_progress may be
+ if (unlikely(conf->reshape_progress != MaxSector)) {
+ /* spinlock is needed as reshape_progress may be
* 64bit on a 32bit platform, and so it might be
* possible to see a half-updated value
- * Ofcourse expand_progress could change after
+ * Ofcourse reshape_progress could change after
* the lock is dropped, so once we get a reference
* to the stripe that we think it is, we will have
* to check again.
*/
spin_lock_irq(&conf->device_lock);
- disks = conf->raid_disks;
- if (logical_sector >= conf->expand_progress)
+ if (mddev->delta_disks < 0
+ ? logical_sector < conf->reshape_progress
+ : logical_sector >= conf->reshape_progress) {
disks = conf->previous_raid_disks;
- else {
- if (logical_sector >= conf->expand_lo) {
+ previous = 1;
+ } else {
+ if (mddev->delta_disks < 0
+ ? logical_sector < conf->reshape_safe
+ : logical_sector >= conf->reshape_safe) {
spin_unlock_irq(&conf->device_lock);
schedule();
goto retry;
@@ -3439,15 +3667,17 @@ static int make_request(struct request_queue *q, struct bio * bi)
}
data_disks = disks - conf->max_degraded;
- new_sector = raid5_compute_sector(logical_sector, disks, data_disks,
- &dd_idx, &pd_idx, conf);
+ new_sector = raid5_compute_sector(conf, logical_sector,
+ previous,
+ &dd_idx, NULL);
pr_debug("raid5: make_request, sector %llu logical %llu\n",
(unsigned long long)new_sector,
(unsigned long long)logical_sector);
- sh = get_active_stripe(conf, new_sector, disks, pd_idx, (bi->bi_rw&RWA_MASK));
+ sh = get_active_stripe(conf, new_sector, previous,
+ (bi->bi_rw&RWA_MASK));
if (sh) {
- if (unlikely(conf->expand_progress != MaxSector)) {
+ if (unlikely(previous)) {
/* expansion might have moved on while waiting for a
* stripe, so we must do the range check again.
* Expansion could still move past after this
@@ -3458,8 +3688,9 @@ static int make_request(struct request_queue *q, struct bio * bi)
*/
int must_retry = 0;
spin_lock_irq(&conf->device_lock);
- if (logical_sector < conf->expand_progress &&
- disks == conf->previous_raid_disks)
+ if (mddev->delta_disks < 0
+ ? logical_sector >= conf->reshape_progress
+ : logical_sector < conf->reshape_progress)
/* mismatch, need to try again */
must_retry = 1;
spin_unlock_irq(&conf->device_lock);
@@ -3514,6 +3745,8 @@ static int make_request(struct request_queue *q, struct bio * bi)
return 0;
}
+static sector_t raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks);
+
static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped)
{
/* reshaping is quite different to recovery/resync so it is
@@ -3527,61 +3760,118 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
*/
raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
struct stripe_head *sh;
- int pd_idx;
sector_t first_sector, last_sector;
int raid_disks = conf->previous_raid_disks;
int data_disks = raid_disks - conf->max_degraded;
int new_data_disks = conf->raid_disks - conf->max_degraded;
int i;
int dd_idx;
- sector_t writepos, safepos, gap;
-
- if (sector_nr == 0 &&
- conf->expand_progress != 0) {
- /* restarting in the middle, skip the initial sectors */
- sector_nr = conf->expand_progress;
+ sector_t writepos, readpos, safepos;
+ sector_t stripe_addr;
+ int reshape_sectors;
+ struct list_head stripes;
+
+ if (sector_nr == 0) {
+ /* If restarting in the middle, skip the initial sectors */
+ if (mddev->delta_disks < 0 &&
+ conf->reshape_progress < raid5_size(mddev, 0, 0)) {
+ sector_nr = raid5_size(mddev, 0, 0)
+ - conf->reshape_progress;
+ } else if (mddev->delta_disks > 0 &&
+ conf->reshape_progress > 0)
+ sector_nr = conf->reshape_progress;
sector_div(sector_nr, new_data_disks);
- *skipped = 1;
- return sector_nr;
+ if (sector_nr) {
+ *skipped = 1;
+ return sector_nr;
+ }
}
+ /* We need to process a full chunk at a time.
+ * If old and new chunk sizes differ, we need to process the
+ * largest of these
+ */
+ if (mddev->new_chunk > mddev->chunk_size)
+ reshape_sectors = mddev->new_chunk / 512;
+ else
+ reshape_sectors = mddev->chunk_size / 512;
+
/* we update the metadata when there is more than 3Meg
* in the block range (that is rather arbitrary, should
* probably be time based) or when the data about to be
* copied would over-write the source of the data at
* the front of the range.
- * i.e. one new_stripe forward from expand_progress new_maps
- * to after where expand_lo old_maps to
+ * i.e. one new_stripe along from reshape_progress new_maps
+ * to after where reshape_safe old_maps to
*/
- writepos = conf->expand_progress +
- conf->chunk_size/512*(new_data_disks);
+ writepos = conf->reshape_progress;
sector_div(writepos, new_data_disks);
- safepos = conf->expand_lo;
+ readpos = conf->reshape_progress;
+ sector_div(readpos, data_disks);
+ safepos = conf->reshape_safe;
sector_div(safepos, data_disks);
- gap = conf->expand_progress - conf->expand_lo;
+ if (mddev->delta_disks < 0) {
+ writepos -= reshape_sectors;
+ readpos += reshape_sectors;
+ safepos += reshape_sectors;
+ } else {
+ writepos += reshape_sectors;
+ readpos -= reshape_sectors;
+ safepos -= reshape_sectors;
+ }
- if (writepos >= safepos ||
- gap > (new_data_disks)*3000*2 /*3Meg*/) {
+ /* 'writepos' is the most advanced device address we might write.
+ * 'readpos' is the least advanced device address we might read.
+ * 'safepos' is the least address recorded in the metadata as having
+ * been reshaped.
+ * If 'readpos' is behind 'writepos', then there is no way that we can
+ * ensure safety in the face of a crash - that must be done by userspace
+ * making a backup of the data. So in that case there is no particular
+ * rush to update metadata.
+ * Otherwise if 'safepos' is behind 'writepos', then we really need to
+ * update the metadata to advance 'safepos' to match 'readpos' so that
+ * we can be safe in the event of a crash.
+ * So we insist on updating metadata if safepos is behind writepos and
+ * readpos is beyond writepos.
+ * In any case, update the metadata every 10 seconds.
+ * Maybe that number should be configurable, but I'm not sure it is
+ * worth it.... maybe it could be a multiple of safemode_delay???
+ */
+ if ((mddev->delta_disks < 0
+ ? (safepos > writepos && readpos < writepos)
+ : (safepos < writepos && readpos > writepos)) ||
+ time_after(jiffies, conf->reshape_checkpoint + 10*HZ)) {
/* Cannot proceed until we've updated the superblock... */
wait_event(conf->wait_for_overlap,
atomic_read(&conf->reshape_stripes)==0);
- mddev->reshape_position = conf->expand_progress;
+ mddev->reshape_position = conf->reshape_progress;
+ conf->reshape_checkpoint = jiffies;
set_bit(MD_CHANGE_DEVS, &mddev->flags);
md_wakeup_thread(mddev->thread);
wait_event(mddev->sb_wait, mddev->flags == 0 ||
kthread_should_stop());
spin_lock_irq(&conf->device_lock);
- conf->expand_lo = mddev->reshape_position;
+ conf->reshape_safe = mddev->reshape_position;
spin_unlock_irq(&conf->device_lock);
wake_up(&conf->wait_for_overlap);
}
- for (i=0; i < conf->chunk_size/512; i+= STRIPE_SECTORS) {
+ if (mddev->delta_disks < 0) {
+ BUG_ON(conf->reshape_progress == 0);
+ stripe_addr = writepos;
+ BUG_ON((mddev->dev_sectors &
+ ~((sector_t)reshape_sectors - 1))
+ - reshape_sectors - stripe_addr
+ != sector_nr);
+ } else {
+ BUG_ON(writepos != sector_nr + reshape_sectors);
+ stripe_addr = sector_nr;
+ }
+ INIT_LIST_HEAD(&stripes);
+ for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) {
int j;
int skipped = 0;
- pd_idx = stripe_to_pdidx(sector_nr+i, conf, conf->raid_disks);
- sh = get_active_stripe(conf, sector_nr+i,
- conf->raid_disks, pd_idx, 0);
+ sh = get_active_stripe(conf, stripe_addr+i, 0, 0);
set_bit(STRIPE_EXPANDING, &sh->state);
atomic_inc(&conf->reshape_stripes);
/* If any of this stripe is beyond the end of the old
@@ -3592,10 +3882,10 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
if (j == sh->pd_idx)
continue;
if (conf->level == 6 &&
- j == raid6_next_disk(sh->pd_idx, sh->disks))
+ j == sh->qd_idx)
continue;
- s = compute_blocknr(sh, j);
- if (s < mddev->array_sectors) {
+ s = compute_blocknr(sh, j, 0);
+ if (s < raid5_size(mddev, 0, 0)) {
skipped = 1;
continue;
}
@@ -3607,10 +3897,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
set_bit(STRIPE_EXPAND_READY, &sh->state);
set_bit(STRIPE_HANDLE, &sh->state);
}
- release_stripe(sh);
+ list_add(&sh->lru, &stripes);
}
spin_lock_irq(&conf->device_lock);
- conf->expand_progress = (sector_nr + i) * new_data_disks;
+ if (mddev->delta_disks < 0)
+ conf->reshape_progress -= reshape_sectors * new_data_disks;
+ else
+ conf->reshape_progress += reshape_sectors * new_data_disks;
spin_unlock_irq(&conf->device_lock);
/* Ok, those stripe are ready. We can start scheduling
* reads on the source stripes.
@@ -3618,46 +3911,50 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
* block on the destination stripes.
*/
first_sector =
- raid5_compute_sector(sector_nr*(new_data_disks),
- raid_disks, data_disks,
- &dd_idx, &pd_idx, conf);
+ raid5_compute_sector(conf, stripe_addr*(new_data_disks),
+ 1, &dd_idx, NULL);
last_sector =
- raid5_compute_sector((sector_nr+conf->chunk_size/512)
- *(new_data_disks) -1,
- raid_disks, data_disks,
- &dd_idx, &pd_idx, conf);
- if (last_sector >= (mddev->size<<1))
- last_sector = (mddev->size<<1)-1;
+ raid5_compute_sector(conf, ((stripe_addr+conf->chunk_size/512)
+ *(new_data_disks) - 1),
+ 1, &dd_idx, NULL);
+ if (last_sector >= mddev->dev_sectors)
+ last_sector = mddev->dev_sectors - 1;
while (first_sector <= last_sector) {
- pd_idx = stripe_to_pdidx(first_sector, conf,
- conf->previous_raid_disks);
- sh = get_active_stripe(conf, first_sector,
- conf->previous_raid_disks, pd_idx, 0);
+ sh = get_active_stripe(conf, first_sector, 1, 0);
set_bit(STRIPE_EXPAND_SOURCE, &sh->state);
set_bit(STRIPE_HANDLE, &sh->state);
release_stripe(sh);
first_sector += STRIPE_SECTORS;
}
+ /* Now that the sources are clearly marked, we can release
+ * the destination stripes
+ */
+ while (!list_empty(&stripes)) {
+ sh = list_entry(stripes.next, struct stripe_head, lru);
+ list_del_init(&sh->lru);
+ release_stripe(sh);
+ }
/* If this takes us to the resync_max point where we have to pause,
* then we need to write out the superblock.
*/
- sector_nr += conf->chunk_size>>9;
+ sector_nr += reshape_sectors;
if (sector_nr >= mddev->resync_max) {
/* Cannot proceed until we've updated the superblock... */
wait_event(conf->wait_for_overlap,
atomic_read(&conf->reshape_stripes) == 0);
- mddev->reshape_position = conf->expand_progress;
+ mddev->reshape_position = conf->reshape_progress;
+ conf->reshape_checkpoint = jiffies;
set_bit(MD_CHANGE_DEVS, &mddev->flags);
md_wakeup_thread(mddev->thread);
wait_event(mddev->sb_wait,
!test_bit(MD_CHANGE_DEVS, &mddev->flags)
|| kthread_should_stop());
spin_lock_irq(&conf->device_lock);
- conf->expand_lo = mddev->reshape_position;
+ conf->reshape_safe = mddev->reshape_position;
spin_unlock_irq(&conf->device_lock);
wake_up(&conf->wait_for_overlap);
}
- return conf->chunk_size>>9;
+ return reshape_sectors;
}
/* FIXME go_faster isn't used */
@@ -3665,9 +3962,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
{
raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
struct stripe_head *sh;
- int pd_idx;
- int raid_disks = conf->raid_disks;
- sector_t max_sector = mddev->size << 1;
+ sector_t max_sector = mddev->dev_sectors;
int sync_blocks;
int still_degraded = 0;
int i;
@@ -3675,6 +3970,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
if (sector_nr >= max_sector) {
/* just being told to finish up .. nothing much to do */
unplug_slaves(mddev);
+
if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) {
end_reshape(conf);
return 0;
@@ -3705,7 +4001,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
*/
if (mddev->degraded >= conf->max_degraded &&
test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
- sector_t rv = (mddev->size << 1) - sector_nr;
+ sector_t rv = mddev->dev_sectors - sector_nr;
*skipped = 1;
return rv;
}
@@ -3721,10 +4017,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
bitmap_cond_end_sync(mddev->bitmap, sector_nr);
- pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks);
- sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1);
+ sh = get_active_stripe(conf, sector_nr, 0, 1);
if (sh == NULL) {
- sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 0);
+ sh = get_active_stripe(conf, sector_nr, 0, 0);
/* make sure we don't swamp the stripe cache if someone else
* is trying to get access
*/
@@ -3766,19 +4061,15 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
* it will be only one 'dd_idx' and only need one call to raid5_compute_sector.
*/
struct stripe_head *sh;
- int dd_idx, pd_idx;
+ int dd_idx;
sector_t sector, logical_sector, last_sector;
int scnt = 0;
int remaining;
int handled = 0;
logical_sector = raid_bio->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
- sector = raid5_compute_sector( logical_sector,
- conf->raid_disks,
- conf->raid_disks - conf->max_degraded,
- &dd_idx,
- &pd_idx,
- conf);
+ sector = raid5_compute_sector(conf, logical_sector,
+ 0, &dd_idx, NULL);
last_sector = raid_bio->bi_sector + (raid_bio->bi_size>>9);
for (; logical_sector < last_sector;
@@ -3790,7 +4081,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
/* already done this stripe */
continue;
- sh = get_active_stripe(conf, sector, conf->raid_disks, pd_idx, 1);
+ sh = get_active_stripe(conf, sector, 0, 1);
if (!sh) {
/* failed to get a stripe - must wait */
@@ -3992,89 +4283,69 @@ static struct attribute_group raid5_attrs_group = {
.attrs = raid5_attrs,
};
-static int run(mddev_t *mddev)
+static sector_t
+raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+
+ if (!sectors)
+ sectors = mddev->dev_sectors;
+ if (!raid_disks) {
+ /* size is defined by the smallest of previous and new size */
+ if (conf->raid_disks < conf->previous_raid_disks)
+ raid_disks = conf->raid_disks;
+ else
+ raid_disks = conf->previous_raid_disks;
+ }
+
+ sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
+ sectors &= ~((sector_t)mddev->new_chunk/512 - 1);
+ return sectors * (raid_disks - conf->max_degraded);
+}
+
+static raid5_conf_t *setup_conf(mddev_t *mddev)
{
raid5_conf_t *conf;
int raid_disk, memory;
mdk_rdev_t *rdev;
struct disk_info *disk;
- int working_disks = 0;
- if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) {
+ if (mddev->new_level != 5
+ && mddev->new_level != 4
+ && mddev->new_level != 6) {
printk(KERN_ERR "raid5: %s: raid level not set to 4/5/6 (%d)\n",
- mdname(mddev), mddev->level);
- return -EIO;
+ mdname(mddev), mddev->new_level);
+ return ERR_PTR(-EIO);
}
-
- if (mddev->chunk_size < PAGE_SIZE) {
- printk(KERN_ERR "md/raid5: chunk_size must be at least "
- "PAGE_SIZE but %d < %ld\n",
- mddev->chunk_size, PAGE_SIZE);
- return -EINVAL;
+ if ((mddev->new_level == 5
+ && !algorithm_valid_raid5(mddev->new_layout)) ||
+ (mddev->new_level == 6
+ && !algorithm_valid_raid6(mddev->new_layout))) {
+ printk(KERN_ERR "raid5: %s: layout %d not supported\n",
+ mdname(mddev), mddev->new_layout);
+ return ERR_PTR(-EIO);
}
-
- if (mddev->reshape_position != MaxSector) {
- /* Check that we can continue the reshape.
- * Currently only disks can change, it must
- * increase, and we must be past the point where
- * a stripe over-writes itself
- */
- sector_t here_new, here_old;
- int old_disks;
- int max_degraded = (mddev->level == 5 ? 1 : 2);
-
- if (mddev->new_level != mddev->level ||
- mddev->new_layout != mddev->layout ||
- mddev->new_chunk != mddev->chunk_size) {
- printk(KERN_ERR "raid5: %s: unsupported reshape "
- "required - aborting.\n",
- mdname(mddev));
- return -EINVAL;
- }
- if (mddev->delta_disks <= 0) {
- printk(KERN_ERR "raid5: %s: unsupported reshape "
- "(reduce disks) required - aborting.\n",
- mdname(mddev));
- return -EINVAL;
- }
- old_disks = mddev->raid_disks - mddev->delta_disks;
- /* reshape_position must be on a new-stripe boundary, and one
- * further up in new geometry must map after here in old
- * geometry.
- */
- here_new = mddev->reshape_position;
- if (sector_div(here_new, (mddev->chunk_size>>9)*
- (mddev->raid_disks - max_degraded))) {
- printk(KERN_ERR "raid5: reshape_position not "
- "on a stripe boundary\n");
- return -EINVAL;
- }
- /* here_new is the stripe we will write to */
- here_old = mddev->reshape_position;
- sector_div(here_old, (mddev->chunk_size>>9)*
- (old_disks-max_degraded));
- /* here_old is the first stripe that we might need to read
- * from */
- if (here_new >= here_old) {
- /* Reading from the same stripe as writing to - bad */
- printk(KERN_ERR "raid5: reshape_position too early for "
- "auto-recovery - aborting.\n");
- return -EINVAL;
- }
- printk(KERN_INFO "raid5: reshape will continue\n");
- /* OK, we should be able to continue; */
+ if (mddev->new_level == 6 && mddev->raid_disks < 4) {
+ printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n",
+ mdname(mddev), mddev->raid_disks);
+ return ERR_PTR(-EINVAL);
}
+ if (!mddev->new_chunk || mddev->new_chunk % PAGE_SIZE) {
+ printk(KERN_ERR "raid5: invalid chunk size %d for %s\n",
+ mddev->new_chunk, mdname(mddev));
+ return ERR_PTR(-EINVAL);
+ }
- mddev->private = kzalloc(sizeof (raid5_conf_t), GFP_KERNEL);
- if ((conf = mddev->private) == NULL)
+ conf = kzalloc(sizeof(raid5_conf_t), GFP_KERNEL);
+ if (conf == NULL)
goto abort;
- if (mddev->reshape_position == MaxSector) {
- conf->previous_raid_disks = conf->raid_disks = mddev->raid_disks;
- } else {
- conf->raid_disks = mddev->raid_disks;
+
+ conf->raid_disks = mddev->raid_disks;
+ if (mddev->reshape_position == MaxSector)
+ conf->previous_raid_disks = mddev->raid_disks;
+ else
conf->previous_raid_disks = mddev->raid_disks - mddev->delta_disks;
- }
conf->disks = kzalloc(conf->raid_disks * sizeof(struct disk_info),
GFP_KERNEL);
@@ -4086,13 +4357,12 @@ static int run(mddev_t *mddev)
if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL)
goto abort;
- if (mddev->level == 6) {
+ if (mddev->new_level == 6) {
conf->spare_page = alloc_page(GFP_KERNEL);
if (!conf->spare_page)
goto abort;
}
spin_lock_init(&conf->device_lock);
- mddev->queue->queue_lock = &conf->device_lock;
init_waitqueue_head(&conf->wait_for_stripe);
init_waitqueue_head(&conf->wait_for_overlap);
INIT_LIST_HEAD(&conf->handle_list);
@@ -4121,47 +4391,134 @@ static int run(mddev_t *mddev)
printk(KERN_INFO "raid5: device %s operational as raid"
" disk %d\n", bdevname(rdev->bdev,b),
raid_disk);
- working_disks++;
} else
/* Cannot rely on bitmap to complete recovery */
conf->fullsync = 1;
}
- /*
- * 0 for a fully functional array, 1 or 2 for a degraded array.
- */
- mddev->degraded = conf->raid_disks - working_disks;
- conf->mddev = mddev;
- conf->chunk_size = mddev->chunk_size;
- conf->level = mddev->level;
+ conf->chunk_size = mddev->new_chunk;
+ conf->level = mddev->new_level;
if (conf->level == 6)
conf->max_degraded = 2;
else
conf->max_degraded = 1;
- conf->algorithm = mddev->layout;
+ conf->algorithm = mddev->new_layout;
conf->max_nr_stripes = NR_STRIPES;
- conf->expand_progress = mddev->reshape_position;
-
- /* device size must be a multiple of chunk size */
- mddev->size &= ~(mddev->chunk_size/1024 -1);
- mddev->resync_max_sectors = mddev->size << 1;
+ conf->reshape_progress = mddev->reshape_position;
+ if (conf->reshape_progress != MaxSector) {
+ conf->prev_chunk = mddev->chunk_size;
+ conf->prev_algo = mddev->layout;
+ }
- if (conf->level == 6 && conf->raid_disks < 4) {
- printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n",
- mdname(mddev), conf->raid_disks);
+ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
+ conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
+ if (grow_stripes(conf, conf->max_nr_stripes)) {
+ printk(KERN_ERR
+ "raid5: couldn't allocate %dkB for buffers\n", memory);
goto abort;
- }
- if (!conf->chunk_size || conf->chunk_size % 4) {
- printk(KERN_ERR "raid5: invalid chunk size %d for %s\n",
- conf->chunk_size, mdname(mddev));
+ } else
+ printk(KERN_INFO "raid5: allocated %dkB for %s\n",
+ memory, mdname(mddev));
+
+ conf->thread = md_register_thread(raid5d, mddev, "%s_raid5");
+ if (!conf->thread) {
+ printk(KERN_ERR
+ "raid5: couldn't allocate thread for %s\n",
+ mdname(mddev));
goto abort;
}
- if (conf->algorithm > ALGORITHM_RIGHT_SYMMETRIC) {
- printk(KERN_ERR
- "raid5: unsupported parity algorithm %d for %s\n",
- conf->algorithm, mdname(mddev));
- goto abort;
+
+ return conf;
+
+ abort:
+ if (conf) {
+ shrink_stripes(conf);
+ safe_put_page(conf->spare_page);
+ kfree(conf->disks);
+ kfree(conf->stripe_hashtbl);
+ kfree(conf);
+ return ERR_PTR(-EIO);
+ } else
+ return ERR_PTR(-ENOMEM);
+}
+
+static int run(mddev_t *mddev)
+{
+ raid5_conf_t *conf;
+ int working_disks = 0;
+ mdk_rdev_t *rdev;
+
+ if (mddev->reshape_position != MaxSector) {
+ /* Check that we can continue the reshape.
+ * Currently only disks can change, it must
+ * increase, and we must be past the point where
+ * a stripe over-writes itself
+ */
+ sector_t here_new, here_old;
+ int old_disks;
+ int max_degraded = (mddev->level == 6 ? 2 : 1);
+
+ if (mddev->new_level != mddev->level) {
+ printk(KERN_ERR "raid5: %s: unsupported reshape "
+ "required - aborting.\n",
+ mdname(mddev));
+ return -EINVAL;
+ }
+ old_disks = mddev->raid_disks - mddev->delta_disks;
+ /* reshape_position must be on a new-stripe boundary, and one
+ * further up in new geometry must map after here in old
+ * geometry.
+ */
+ here_new = mddev->reshape_position;
+ if (sector_div(here_new, (mddev->new_chunk>>9)*
+ (mddev->raid_disks - max_degraded))) {
+ printk(KERN_ERR "raid5: reshape_position not "
+ "on a stripe boundary\n");
+ return -EINVAL;
+ }
+ /* here_new is the stripe we will write to */
+ here_old = mddev->reshape_position;
+ sector_div(here_old, (mddev->chunk_size>>9)*
+ (old_disks-max_degraded));
+ /* here_old is the first stripe that we might need to read
+ * from */
+ if (here_new >= here_old) {
+ /* Reading from the same stripe as writing to - bad */
+ printk(KERN_ERR "raid5: reshape_position too early for "
+ "auto-recovery - aborting.\n");
+ return -EINVAL;
+ }
+ printk(KERN_INFO "raid5: reshape will continue\n");
+ /* OK, we should be able to continue; */
+ } else {
+ BUG_ON(mddev->level != mddev->new_level);
+ BUG_ON(mddev->layout != mddev->new_layout);
+ BUG_ON(mddev->chunk_size != mddev->new_chunk);
+ BUG_ON(mddev->delta_disks != 0);
}
+
+ if (mddev->private == NULL)
+ conf = setup_conf(mddev);
+ else
+ conf = mddev->private;
+
+ if (IS_ERR(conf))
+ return PTR_ERR(conf);
+
+ mddev->thread = conf->thread;
+ conf->thread = NULL;
+ mddev->private = conf;
+
+ /*
+ * 0 for a fully functional array, 1 or 2 for a degraded array.
+ */
+ list_for_each_entry(rdev, &mddev->disks, same_set)
+ if (rdev->raid_disk >= 0 &&
+ test_bit(In_sync, &rdev->flags))
+ working_disks++;
+
+ mddev->degraded = conf->raid_disks - working_disks;
+
if (mddev->degraded > conf->max_degraded) {
printk(KERN_ERR "raid5: not enough operational devices for %s"
" (%d/%d failed)\n",
@@ -4169,6 +4526,10 @@ static int run(mddev_t *mddev)
goto abort;
}
+ /* device size must be a multiple of chunk size */
+ mddev->dev_sectors &= ~(mddev->chunk_size / 512 - 1);
+ mddev->resync_max_sectors = mddev->dev_sectors;
+
if (mddev->degraded > 0 &&
mddev->recovery_cp != MaxSector) {
if (mddev->ok_start_degraded)
@@ -4184,43 +4545,22 @@ static int run(mddev_t *mddev)
}
}
- {
- mddev->thread = md_register_thread(raid5d, mddev, "%s_raid5");
- if (!mddev->thread) {
- printk(KERN_ERR
- "raid5: couldn't allocate thread for %s\n",
- mdname(mddev));
- goto abort;
- }
- }
- memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
- conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
- if (grow_stripes(conf, conf->max_nr_stripes)) {
- printk(KERN_ERR
- "raid5: couldn't allocate %dkB for buffers\n", memory);
- shrink_stripes(conf);
- md_unregister_thread(mddev->thread);
- goto abort;
- } else
- printk(KERN_INFO "raid5: allocated %dkB for %s\n",
- memory, mdname(mddev));
-
if (mddev->degraded == 0)
printk("raid5: raid level %d set %s active with %d out of %d"
- " devices, algorithm %d\n", conf->level, mdname(mddev),
- mddev->raid_disks-mddev->degraded, mddev->raid_disks,
- conf->algorithm);
+ " devices, algorithm %d\n", conf->level, mdname(mddev),
+ mddev->raid_disks-mddev->degraded, mddev->raid_disks,
+ mddev->new_layout);
else
printk(KERN_ALERT "raid5: raid level %d set %s active with %d"
" out of %d devices, algorithm %d\n", conf->level,
mdname(mddev), mddev->raid_disks - mddev->degraded,
- mddev->raid_disks, conf->algorithm);
+ mddev->raid_disks, mddev->new_layout);
print_raid5_conf(conf);
- if (conf->expand_progress != MaxSector) {
+ if (conf->reshape_progress != MaxSector) {
printk("...ok start reshape thread\n");
- conf->expand_lo = conf->expand_progress;
+ conf->reshape_safe = conf->reshape_progress;
atomic_set(&conf->reshape_stripes, 0);
clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
@@ -4247,18 +4587,22 @@ static int run(mddev_t *mddev)
"raid5: failed to create sysfs attributes for %s\n",
mdname(mddev));
+ mddev->queue->queue_lock = &conf->device_lock;
+
mddev->queue->unplug_fn = raid5_unplug_device;
mddev->queue->backing_dev_info.congested_data = mddev;
mddev->queue->backing_dev_info.congested_fn = raid5_congested;
- mddev->array_sectors = 2 * mddev->size * (conf->previous_raid_disks -
- conf->max_degraded);
+ md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));
blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec);
return 0;
abort:
+ md_unregister_thread(mddev->thread);
+ mddev->thread = NULL;
if (conf) {
+ shrink_stripes(conf);
print_raid5_conf(conf);
safe_put_page(conf->spare_page);
kfree(conf->disks);
@@ -4396,6 +4740,10 @@ static int raid5_remove_disk(mddev_t *mddev, int number)
print_raid5_conf(conf);
rdev = p->rdev;
if (rdev) {
+ if (number >= conf->raid_disks &&
+ conf->reshape_progress == MaxSector)
+ clear_bit(In_sync, &rdev->flags);
+
if (test_bit(In_sync, &rdev->flags) ||
atomic_read(&rdev->nr_pending)) {
err = -EBUSY;
@@ -4405,7 +4753,8 @@ static int raid5_remove_disk(mddev_t *mddev, int number)
* isn't possible.
*/
if (!test_bit(Faulty, &rdev->flags) &&
- mddev->degraded <= conf->max_degraded) {
+ mddev->degraded <= conf->max_degraded &&
+ number < conf->raid_disks) {
err = -EBUSY;
goto abort;
}
@@ -4472,36 +4821,48 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors)
* any io in the removed space completes, but it hardly seems
* worth it.
*/
- raid5_conf_t *conf = mddev_to_conf(mddev);
-
sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
- mddev->array_sectors = sectors * (mddev->raid_disks
- - conf->max_degraded);
+ md_set_array_sectors(mddev, raid5_size(mddev, sectors,
+ mddev->raid_disks));
+ if (mddev->array_sectors >
+ raid5_size(mddev, sectors, mddev->raid_disks))
+ return -EINVAL;
set_capacity(mddev->gendisk, mddev->array_sectors);
mddev->changed = 1;
- if (sectors/2 > mddev->size && mddev->recovery_cp == MaxSector) {
- mddev->recovery_cp = mddev->size << 1;
+ if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) {
+ mddev->recovery_cp = mddev->dev_sectors;
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
}
- mddev->size = sectors /2;
+ mddev->dev_sectors = sectors;
mddev->resync_max_sectors = sectors;
return 0;
}
-#ifdef CONFIG_MD_RAID5_RESHAPE
static int raid5_check_reshape(mddev_t *mddev)
{
raid5_conf_t *conf = mddev_to_conf(mddev);
- int err;
- if (mddev->delta_disks < 0 ||
- mddev->new_level != mddev->level)
- return -EINVAL; /* Cannot shrink array or change level yet */
- if (mddev->delta_disks == 0)
- return 0; /* nothing to do */
+ if (mddev->delta_disks == 0 &&
+ mddev->new_layout == mddev->layout &&
+ mddev->new_chunk == mddev->chunk_size)
+ return -EINVAL; /* nothing to do */
if (mddev->bitmap)
/* Cannot grow a bitmap yet */
return -EBUSY;
+ if (mddev->degraded > conf->max_degraded)
+ return -EINVAL;
+ if (mddev->delta_disks < 0) {
+ /* We might be able to shrink, but the devices must
+ * be made bigger first.
+ * For raid6, 4 is the minimum size.
+ * Otherwise 2 is the minimum
+ */
+ int min = 2;
+ if (mddev->level == 6)
+ min = 4;
+ if (mddev->raid_disks + mddev->delta_disks < min)
+ return -EINVAL;
+ }
/* Can only proceed if there are plenty of stripe_heads.
* We need a minimum of one full stripe,, and for sensible progress
@@ -4514,18 +4875,12 @@ static int raid5_check_reshape(mddev_t *mddev)
if ((mddev->chunk_size / STRIPE_SIZE) * 4 > conf->max_nr_stripes ||
(mddev->new_chunk / STRIPE_SIZE) * 4 > conf->max_nr_stripes) {
printk(KERN_WARNING "raid5: reshape: not enough stripes. Needed %lu\n",
- (mddev->chunk_size / STRIPE_SIZE)*4);
+ (max(mddev->chunk_size, mddev->new_chunk)
+ / STRIPE_SIZE)*4);
return -ENOSPC;
}
- err = resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
- if (err)
- return err;
-
- if (mddev->degraded > conf->max_degraded)
- return -EINVAL;
- /* looks like we might be able to manage this */
- return 0;
+ return resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
}
static int raid5_start_reshape(mddev_t *mddev)
@@ -4550,12 +4905,31 @@ static int raid5_start_reshape(mddev_t *mddev)
*/
return -EINVAL;
+ /* Refuse to reduce size of the array. Any reductions in
+ * array size must be through explicit setting of array_size
+ * attribute.
+ */
+ if (raid5_size(mddev, 0, conf->raid_disks + mddev->delta_disks)
+ < mddev->array_sectors) {
+ printk(KERN_ERR "md: %s: array size must be reduced "
+ "before number of disks\n", mdname(mddev));
+ return -EINVAL;
+ }
+
atomic_set(&conf->reshape_stripes, 0);
spin_lock_irq(&conf->device_lock);
conf->previous_raid_disks = conf->raid_disks;
conf->raid_disks += mddev->delta_disks;
- conf->expand_progress = 0;
- conf->expand_lo = 0;
+ conf->prev_chunk = conf->chunk_size;
+ conf->chunk_size = mddev->new_chunk;
+ conf->prev_algo = conf->algorithm;
+ conf->algorithm = mddev->new_layout;
+ if (mddev->delta_disks < 0)
+ conf->reshape_progress = raid5_size(mddev, 0, 0);
+ else
+ conf->reshape_progress = 0;
+ conf->reshape_safe = conf->reshape_progress;
+ conf->generation++;
spin_unlock_irq(&conf->device_lock);
/* Add some new drives, as many as will fit.
@@ -4580,9 +4954,12 @@ static int raid5_start_reshape(mddev_t *mddev)
break;
}
- spin_lock_irqsave(&conf->device_lock, flags);
- mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices;
- spin_unlock_irqrestore(&conf->device_lock, flags);
+ if (mddev->delta_disks > 0) {
+ spin_lock_irqsave(&conf->device_lock, flags);
+ mddev->degraded = (conf->raid_disks - conf->previous_raid_disks)
+ - added_devices;
+ spin_unlock_irqrestore(&conf->device_lock, flags);
+ }
mddev->raid_disks = conf->raid_disks;
mddev->reshape_position = 0;
set_bit(MD_CHANGE_DEVS, &mddev->flags);
@@ -4597,52 +4974,86 @@ static int raid5_start_reshape(mddev_t *mddev)
mddev->recovery = 0;
spin_lock_irq(&conf->device_lock);
mddev->raid_disks = conf->raid_disks = conf->previous_raid_disks;
- conf->expand_progress = MaxSector;
+ conf->reshape_progress = MaxSector;
spin_unlock_irq(&conf->device_lock);
return -EAGAIN;
}
+ conf->reshape_checkpoint = jiffies;
md_wakeup_thread(mddev->sync_thread);
md_new_event(mddev);
return 0;
}
-#endif
+/* This is called from the reshape thread and should make any
+ * changes needed in 'conf'
+ */
static void end_reshape(raid5_conf_t *conf)
{
- struct block_device *bdev;
if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
- conf->mddev->array_sectors = 2 * conf->mddev->size *
- (conf->raid_disks - conf->max_degraded);
- set_capacity(conf->mddev->gendisk, conf->mddev->array_sectors);
- conf->mddev->changed = 1;
-
- bdev = bdget_disk(conf->mddev->gendisk, 0);
- if (bdev) {
- mutex_lock(&bdev->bd_inode->i_mutex);
- i_size_write(bdev->bd_inode,
- (loff_t)conf->mddev->array_sectors << 9);
- mutex_unlock(&bdev->bd_inode->i_mutex);
- bdput(bdev);
- }
+
spin_lock_irq(&conf->device_lock);
- conf->expand_progress = MaxSector;
+ conf->previous_raid_disks = conf->raid_disks;
+ conf->reshape_progress = MaxSector;
spin_unlock_irq(&conf->device_lock);
- conf->mddev->reshape_position = MaxSector;
+ wake_up(&conf->wait_for_overlap);
/* read-ahead size must cover two whole stripes, which is
* 2 * (datadisks) * chunksize where 'n' is the number of raid devices
*/
{
- int data_disks = conf->previous_raid_disks - conf->max_degraded;
- int stripe = data_disks *
- (conf->mddev->chunk_size / PAGE_SIZE);
+ int data_disks = conf->raid_disks - conf->max_degraded;
+ int stripe = data_disks * (conf->chunk_size
+ / PAGE_SIZE);
if (conf->mddev->queue->backing_dev_info.ra_pages < 2 * stripe)
conf->mddev->queue->backing_dev_info.ra_pages = 2 * stripe;
}
}
}
+/* This is called from the raid5d thread with mddev_lock held.
+ * It makes config changes to the device.
+ */
+static void raid5_finish_reshape(mddev_t *mddev)
+{
+ struct block_device *bdev;
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+
+ if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
+
+ if (mddev->delta_disks > 0) {
+ md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));
+ set_capacity(mddev->gendisk, mddev->array_sectors);
+ mddev->changed = 1;
+
+ bdev = bdget_disk(mddev->gendisk, 0);
+ if (bdev) {
+ mutex_lock(&bdev->bd_inode->i_mutex);
+ i_size_write(bdev->bd_inode,
+ (loff_t)mddev->array_sectors << 9);
+ mutex_unlock(&bdev->bd_inode->i_mutex);
+ bdput(bdev);
+ }
+ } else {
+ int d;
+ mddev->degraded = conf->raid_disks;
+ for (d = 0; d < conf->raid_disks ; d++)
+ if (conf->disks[d].rdev &&
+ test_bit(In_sync,
+ &conf->disks[d].rdev->flags))
+ mddev->degraded--;
+ for (d = conf->raid_disks ;
+ d < conf->raid_disks - mddev->delta_disks;
+ d++)
+ raid5_remove_disk(mddev, d);
+ }
+ mddev->layout = conf->algorithm;
+ mddev->chunk_size = conf->chunk_size;
+ mddev->reshape_position = MaxSector;
+ mddev->delta_disks = 0;
+ }
+}
+
static void raid5_quiesce(mddev_t *mddev, int state)
{
raid5_conf_t *conf = mddev_to_conf(mddev);
@@ -4672,6 +5083,212 @@ static void raid5_quiesce(mddev_t *mddev, int state)
}
}
+
+static void *raid5_takeover_raid1(mddev_t *mddev)
+{
+ int chunksect;
+
+ if (mddev->raid_disks != 2 ||
+ mddev->degraded > 1)
+ return ERR_PTR(-EINVAL);
+
+ /* Should check if there are write-behind devices? */
+
+ chunksect = 64*2; /* 64K by default */
+
+ /* The array must be an exact multiple of chunksize */
+ while (chunksect && (mddev->array_sectors & (chunksect-1)))
+ chunksect >>= 1;
+
+ if ((chunksect<<9) < STRIPE_SIZE)
+ /* array size does not allow a suitable chunk size */
+ return ERR_PTR(-EINVAL);
+
+ mddev->new_level = 5;
+ mddev->new_layout = ALGORITHM_LEFT_SYMMETRIC;
+ mddev->new_chunk = chunksect << 9;
+
+ return setup_conf(mddev);
+}
+
+static void *raid5_takeover_raid6(mddev_t *mddev)
+{
+ int new_layout;
+
+ switch (mddev->layout) {
+ case ALGORITHM_LEFT_ASYMMETRIC_6:
+ new_layout = ALGORITHM_LEFT_ASYMMETRIC;
+ break;
+ case ALGORITHM_RIGHT_ASYMMETRIC_6:
+ new_layout = ALGORITHM_RIGHT_ASYMMETRIC;
+ break;
+ case ALGORITHM_LEFT_SYMMETRIC_6:
+ new_layout = ALGORITHM_LEFT_SYMMETRIC;
+ break;
+ case ALGORITHM_RIGHT_SYMMETRIC_6:
+ new_layout = ALGORITHM_RIGHT_SYMMETRIC;
+ break;
+ case ALGORITHM_PARITY_0_6:
+ new_layout = ALGORITHM_PARITY_0;
+ break;
+ case ALGORITHM_PARITY_N:
+ new_layout = ALGORITHM_PARITY_N;
+ break;
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+ mddev->new_level = 5;
+ mddev->new_layout = new_layout;
+ mddev->delta_disks = -1;
+ mddev->raid_disks -= 1;
+ return setup_conf(mddev);
+}
+
+
+static int raid5_reconfig(mddev_t *mddev, int new_layout, int new_chunk)
+{
+ /* For a 2-drive array, the layout and chunk size can be changed
+ * immediately as not restriping is needed.
+ * For larger arrays we record the new value - after validation
+ * to be used by a reshape pass.
+ */
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+
+ if (new_layout >= 0 && !algorithm_valid_raid5(new_layout))
+ return -EINVAL;
+ if (new_chunk > 0) {
+ if (new_chunk & (new_chunk-1))
+ /* not a power of 2 */
+ return -EINVAL;
+ if (new_chunk < PAGE_SIZE)
+ return -EINVAL;
+ if (mddev->array_sectors & ((new_chunk>>9)-1))
+ /* not factor of array size */
+ return -EINVAL;
+ }
+
+ /* They look valid */
+
+ if (mddev->raid_disks == 2) {
+
+ if (new_layout >= 0) {
+ conf->algorithm = new_layout;
+ mddev->layout = mddev->new_layout = new_layout;
+ }
+ if (new_chunk > 0) {
+ conf->chunk_size = new_chunk;
+ mddev->chunk_size = mddev->new_chunk = new_chunk;
+ }
+ set_bit(MD_CHANGE_DEVS, &mddev->flags);
+ md_wakeup_thread(mddev->thread);
+ } else {
+ if (new_layout >= 0)
+ mddev->new_layout = new_layout;
+ if (new_chunk > 0)
+ mddev->new_chunk = new_chunk;
+ }
+ return 0;
+}
+
+static int raid6_reconfig(mddev_t *mddev, int new_layout, int new_chunk)
+{
+ if (new_layout >= 0 && !algorithm_valid_raid6(new_layout))
+ return -EINVAL;
+ if (new_chunk > 0) {
+ if (new_chunk & (new_chunk-1))
+ /* not a power of 2 */
+ return -EINVAL;
+ if (new_chunk < PAGE_SIZE)
+ return -EINVAL;
+ if (mddev->array_sectors & ((new_chunk>>9)-1))
+ /* not factor of array size */
+ return -EINVAL;
+ }
+
+ /* They look valid */
+
+ if (new_layout >= 0)
+ mddev->new_layout = new_layout;
+ if (new_chunk > 0)
+ mddev->new_chunk = new_chunk;
+
+ return 0;
+}
+
+static void *raid5_takeover(mddev_t *mddev)
+{
+ /* raid5 can take over:
+ * raid0 - if all devices are the same - make it a raid4 layout
+ * raid1 - if there are two drives. We need to know the chunk size
+ * raid4 - trivial - just use a raid4 layout.
+ * raid6 - Providing it is a *_6 layout
+ *
+ * For now, just do raid1
+ */
+
+ if (mddev->level == 1)
+ return raid5_takeover_raid1(mddev);
+ if (mddev->level == 4) {
+ mddev->new_layout = ALGORITHM_PARITY_N;
+ mddev->new_level = 5;
+ return setup_conf(mddev);
+ }
+ if (mddev->level == 6)
+ return raid5_takeover_raid6(mddev);
+
+ return ERR_PTR(-EINVAL);
+}
+
+
+static struct mdk_personality raid5_personality;
+
+static void *raid6_takeover(mddev_t *mddev)
+{
+ /* Currently can only take over a raid5. We map the
+ * personality to an equivalent raid6 personality
+ * with the Q block at the end.
+ */
+ int new_layout;
+
+ if (mddev->pers != &raid5_personality)
+ return ERR_PTR(-EINVAL);
+ if (mddev->degraded > 1)
+ return ERR_PTR(-EINVAL);
+ if (mddev->raid_disks > 253)
+ return ERR_PTR(-EINVAL);
+ if (mddev->raid_disks < 3)
+ return ERR_PTR(-EINVAL);
+
+ switch (mddev->layout) {
+ case ALGORITHM_LEFT_ASYMMETRIC:
+ new_layout = ALGORITHM_LEFT_ASYMMETRIC_6;
+ break;
+ case ALGORITHM_RIGHT_ASYMMETRIC:
+ new_layout = ALGORITHM_RIGHT_ASYMMETRIC_6;
+ break;
+ case ALGORITHM_LEFT_SYMMETRIC:
+ new_layout = ALGORITHM_LEFT_SYMMETRIC_6;
+ break;
+ case ALGORITHM_RIGHT_SYMMETRIC:
+ new_layout = ALGORITHM_RIGHT_SYMMETRIC_6;
+ break;
+ case ALGORITHM_PARITY_0:
+ new_layout = ALGORITHM_PARITY_0_6;
+ break;
+ case ALGORITHM_PARITY_N:
+ new_layout = ALGORITHM_PARITY_N;
+ break;
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+ mddev->new_level = 6;
+ mddev->new_layout = new_layout;
+ mddev->delta_disks = 1;
+ mddev->raid_disks += 1;
+ return setup_conf(mddev);
+}
+
+
static struct mdk_personality raid6_personality =
{
.name = "raid6",
@@ -4687,11 +5304,13 @@ static struct mdk_personality raid6_personality =
.spare_active = raid5_spare_active,
.sync_request = sync_request,
.resize = raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+ .size = raid5_size,
.check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape,
-#endif
+ .finish_reshape = raid5_finish_reshape,
.quiesce = raid5_quiesce,
+ .takeover = raid6_takeover,
+ .reconfig = raid6_reconfig,
};
static struct mdk_personality raid5_personality =
{
@@ -4708,11 +5327,13 @@ static struct mdk_personality raid5_personality =
.spare_active = raid5_spare_active,
.sync_request = sync_request,
.resize = raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+ .size = raid5_size,
.check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape,
-#endif
+ .finish_reshape = raid5_finish_reshape,
.quiesce = raid5_quiesce,
+ .takeover = raid5_takeover,
+ .reconfig = raid5_reconfig,
};
static struct mdk_personality raid4_personality =
@@ -4730,20 +5351,15 @@ static struct mdk_personality raid4_personality =
.spare_active = raid5_spare_active,
.sync_request = sync_request,
.resize = raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+ .size = raid5_size,
.check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape,
-#endif
+ .finish_reshape = raid5_finish_reshape,
.quiesce = raid5_quiesce,
};
static int __init raid5_init(void)
{
- int e;
-
- e = raid6_select_algo();
- if ( e )
- return e;
register_md_personality(&raid6_personality);
register_md_personality(&raid5_personality);
register_md_personality(&raid4_personality);
diff --git a/include/linux/raid/raid5.h b/drivers/md/raid5.h
index 3b2672792457..52ba99954dec 100644
--- a/include/linux/raid/raid5.h
+++ b/drivers/md/raid5.h
@@ -1,7 +1,6 @@
#ifndef _RAID5_H
#define _RAID5_H
-#include <linux/raid/md.h>
#include <linux/raid/xor.h>
/*
@@ -197,15 +196,19 @@ enum reconstruct_states {
struct stripe_head {
struct hlist_node hash;
- struct list_head lru; /* inactive_list or handle_list */
- struct raid5_private_data *raid_conf;
- sector_t sector; /* sector of this row */
- int pd_idx; /* parity disk index */
- unsigned long state; /* state flags */
- atomic_t count; /* nr of active thread/requests */
+ struct list_head lru; /* inactive_list or handle_list */
+ struct raid5_private_data *raid_conf;
+ short generation; /* increments with every
+ * reshape */
+ sector_t sector; /* sector of this row */
+ short pd_idx; /* parity disk index */
+ short qd_idx; /* 'Q' disk index for raid6 */
+ short ddf_layout;/* use DDF ordering to calculate Q */
+ unsigned long state; /* state flags */
+ atomic_t count; /* nr of active thread/requests */
spinlock_t lock;
int bm_seq; /* sequence number for bitmap flushes */
- int disks; /* disks in stripe */
+ int disks; /* disks in stripe */
enum check_states check_state;
enum reconstruct_states reconstruct_state;
/* stripe_operations
@@ -238,7 +241,7 @@ struct stripe_head_state {
/* r6_state - extra state data only relevant to r6 */
struct r6_state {
- int p_failed, q_failed, qd_idx, failed_num[2];
+ int p_failed, q_failed, failed_num[2];
};
/* Flags */
@@ -268,6 +271,8 @@ struct r6_state {
#define READ_MODIFY_WRITE 2
/* not a write method, but a compute_parity mode */
#define CHECK_PARITY 3
+/* Additional compute_parity mode -- updates the parity w/o LOCKING */
+#define UPDATE_PARITY 4
/*
* Stripe state
@@ -319,7 +324,7 @@ struct r6_state {
* PREREAD_ACTIVE is set, else we set DELAYED which will send it to the delayed queue.
* HANDLE gets cleared if stripe_handle leave nothing locked.
*/
-
+
struct disk_info {
mdk_rdev_t *rdev;
@@ -334,12 +339,21 @@ struct raid5_private_data {
int raid_disks;
int max_nr_stripes;
- /* used during an expand */
- sector_t expand_progress; /* MaxSector when no expand happening */
- sector_t expand_lo; /* from here up to expand_progress it out-of-bounds
- * as we haven't flushed the metadata yet
- */
+ /* reshape_progress is the leading edge of a 'reshape'
+ * It has value MaxSector when no reshape is happening
+ * If delta_disks < 0, it is the last sector we started work on,
+ * else is it the next sector to work on.
+ */
+ sector_t reshape_progress;
+ /* reshape_safe is the trailing edge of a reshape. We know that
+ * before (or after) this address, all reshape has completed.
+ */
+ sector_t reshape_safe;
int previous_raid_disks;
+ int prev_chunk, prev_algo;
+ short generation; /* increments with every reshape */
+ unsigned long reshape_checkpoint; /* Time we last updated
+ * metadata */
struct list_head handle_list; /* stripes needing handling */
struct list_head hold_list; /* preread ready stripes */
@@ -385,6 +399,11 @@ struct raid5_private_data {
int pool_size; /* number of disks in stripeheads in pool */
spinlock_t device_lock;
struct disk_info *disks;
+
+ /* When taking over an array from a different personality, we store
+ * the new thread here until we fully activate the array.
+ */
+ struct mdk_thread_s *thread;
};
typedef struct raid5_private_data raid5_conf_t;
@@ -394,9 +413,62 @@ typedef struct raid5_private_data raid5_conf_t;
/*
* Our supported algorithms
*/
-#define ALGORITHM_LEFT_ASYMMETRIC 0
-#define ALGORITHM_RIGHT_ASYMMETRIC 1
-#define ALGORITHM_LEFT_SYMMETRIC 2
-#define ALGORITHM_RIGHT_SYMMETRIC 3
+#define ALGORITHM_LEFT_ASYMMETRIC 0 /* Rotating Parity N with Data Restart */
+#define ALGORITHM_RIGHT_ASYMMETRIC 1 /* Rotating Parity 0 with Data Restart */
+#define ALGORITHM_LEFT_SYMMETRIC 2 /* Rotating Parity N with Data Continuation */
+#define ALGORITHM_RIGHT_SYMMETRIC 3 /* Rotating Parity 0 with Data Continuation */
+
+/* Define non-rotating (raid4) algorithms. These allow
+ * conversion of raid4 to raid5.
+ */
+#define ALGORITHM_PARITY_0 4 /* P or P,Q are initial devices */
+#define ALGORITHM_PARITY_N 5 /* P or P,Q are final devices. */
+
+/* DDF RAID6 layouts differ from md/raid6 layouts in two ways.
+ * Firstly, the exact positioning of the parity block is slightly
+ * different between the 'LEFT_*' modes of md and the "_N_*" modes
+ * of DDF.
+ * Secondly, or order of datablocks over which the Q syndrome is computed
+ * is different.
+ * Consequently we have different layouts for DDF/raid6 than md/raid6.
+ * These layouts are from the DDFv1.2 spec.
+ * Interestingly DDFv1.2-Errata-A does not specify N_CONTINUE but
+ * leaves RLQ=3 as 'Vendor Specific'
+ */
+
+#define ALGORITHM_ROTATING_ZERO_RESTART 8 /* DDF PRL=6 RLQ=1 */
+#define ALGORITHM_ROTATING_N_RESTART 9 /* DDF PRL=6 RLQ=2 */
+#define ALGORITHM_ROTATING_N_CONTINUE 10 /*DDF PRL=6 RLQ=3 */
+
+
+/* For every RAID5 algorithm we define a RAID6 algorithm
+ * with exactly the same layout for data and parity, and
+ * with the Q block always on the last device (N-1).
+ * This allows trivial conversion from RAID5 to RAID6
+ */
+#define ALGORITHM_LEFT_ASYMMETRIC_6 16
+#define ALGORITHM_RIGHT_ASYMMETRIC_6 17
+#define ALGORITHM_LEFT_SYMMETRIC_6 18
+#define ALGORITHM_RIGHT_SYMMETRIC_6 19
+#define ALGORITHM_PARITY_0_6 20
+#define ALGORITHM_PARITY_N_6 ALGORITHM_PARITY_N
+
+static inline int algorithm_valid_raid5(int layout)
+{
+ return (layout >= 0) &&
+ (layout <= 5);
+}
+static inline int algorithm_valid_raid6(int layout)
+{
+ return (layout >= 0 && layout <= 5)
+ ||
+ (layout == 8 || layout == 10)
+ ||
+ (layout >= 16 && layout <= 20);
+}
+static inline int algorithm_is_DDF(int layout)
+{
+ return layout >= 8 && layout <= 10;
+}
#endif
diff --git a/drivers/md/raid6algos.c b/drivers/md/raid6algos.c
index 21987e3dbe6c..866215ac7f25 100644
--- a/drivers/md/raid6algos.c
+++ b/drivers/md/raid6algos.c
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -16,13 +16,20 @@
* Algorithm list and algorithm selection for RAID-6
*/
-#include "raid6.h"
+#include <linux/raid/pq.h>
#ifndef __KERNEL__
#include <sys/mman.h>
#include <stdio.h>
+#else
+#if !RAID6_USE_EMPTY_ZERO_PAGE
+/* In .bss so it's zeroed */
+const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
+EXPORT_SYMBOL(raid6_empty_zero_page);
+#endif
#endif
struct raid6_calls raid6_call;
+EXPORT_SYMBOL_GPL(raid6_call);
/* Various routine sets */
extern const struct raid6_calls raid6_intx1;
@@ -79,6 +86,7 @@ const struct raid6_calls * const raid6_algos[] = {
#else
/* Need more time to be stable in userspace */
#define RAID6_TIME_JIFFIES_LG2 9
+#define time_before(x, y) ((x) < (y))
#endif
/* Try to pick the best algorithm */
@@ -152,3 +160,12 @@ int __init raid6_select_algo(void)
return best ? 0 : -EINVAL;
}
+
+static void raid6_exit(void)
+{
+ do { } while (0);
+}
+
+subsys_initcall(raid6_select_algo);
+module_exit(raid6_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/md/raid6altivec.uc b/drivers/md/raid6altivec.uc
index b9afd35b8812..699dfeee4944 100644
--- a/drivers/md/raid6altivec.uc
+++ b/drivers/md/raid6altivec.uc
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -22,7 +22,7 @@
* bracked this with preempt_disable/enable or in a lock)
*/
-#include "raid6.h"
+#include <linux/raid/pq.h>
#ifdef CONFIG_ALTIVEC
diff --git a/drivers/md/raid6int.uc b/drivers/md/raid6int.uc
index ad004cee0e26..f9bf9cba357f 100644
--- a/drivers/md/raid6int.uc
+++ b/drivers/md/raid6int.uc
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
* This file is postprocessed using unroll.pl
*/
-#include "raid6.h"
+#include <linux/raid/pq.h>
/*
* This is the C data type to use
diff --git a/drivers/md/raid6mmx.c b/drivers/md/raid6mmx.c
index d4e4a1bd70ad..e7f6c13132bf 100644
--- a/drivers/md/raid6mmx.c
+++ b/drivers/md/raid6mmx.c
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
#if defined(__i386__) && !defined(__arch_um__)
-#include "raid6.h"
+#include <linux/raid/pq.h>
#include "raid6x86.h"
/* Shared with raid6sse1.c */
diff --git a/drivers/md/raid6recov.c b/drivers/md/raid6recov.c
index a8c4d9451bd9..2609f00e0d61 100644
--- a/drivers/md/raid6recov.c
+++ b/drivers/md/raid6recov.c
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
* the syndrome.)
*/
-#include "raid6.h"
+#include <linux/raid/pq.h>
/* Recover two failed data blocks. */
void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
@@ -63,9 +63,7 @@ void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
p++; q++;
}
}
-
-
-
+EXPORT_SYMBOL_GPL(raid6_2data_recov);
/* Recover failure of one data block plus the P block */
void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs)
@@ -97,9 +95,10 @@ void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs)
q++; dq++;
}
}
+EXPORT_SYMBOL_GPL(raid6_datap_recov);
-
-#ifndef __KERNEL__ /* Testing only */
+#ifndef __KERNEL__
+/* Testing only */
/* Recover two failed blocks. */
void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs)
diff --git a/drivers/md/raid6sse1.c b/drivers/md/raid6sse1.c
index 0666237276ff..b274dd5eab8f 100644
--- a/drivers/md/raid6sse1.c
+++ b/drivers/md/raid6sse1.c
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -23,7 +23,7 @@
#if defined(__i386__) && !defined(__arch_um__)
-#include "raid6.h"
+#include <linux/raid/pq.h>
#include "raid6x86.h"
/* Defined in raid6mmx.c */
diff --git a/drivers/md/raid6sse2.c b/drivers/md/raid6sse2.c
index b034ad868039..6ed6c6c0389f 100644
--- a/drivers/md/raid6sse2.c
+++ b/drivers/md/raid6sse2.c
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -19,7 +19,7 @@
#if (defined(__i386__) || defined(__x86_64__)) && !defined(__arch_um__)
-#include "raid6.h"
+#include <linux/raid/pq.h>
#include "raid6x86.h"
static const struct raid6_sse_constants {
diff --git a/drivers/md/raid6test/Makefile b/drivers/md/raid6test/Makefile
index 78e0396adf2a..58ffdf4f5161 100644
--- a/drivers/md/raid6test/Makefile
+++ b/drivers/md/raid6test/Makefile
@@ -5,7 +5,7 @@
CC = gcc
OPTFLAGS = -O2 # Adjust as desired
-CFLAGS = -I.. -g $(OPTFLAGS)
+CFLAGS = -I.. -I ../../../include -g $(OPTFLAGS)
LD = ld
PERL = perl
AR = ar
diff --git a/drivers/md/raid6test/test.c b/drivers/md/raid6test/test.c
index 559cc41b2585..7a930318b17d 100644
--- a/drivers/md/raid6test/test.c
+++ b/drivers/md/raid6test/test.c
@@ -17,7 +17,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include "raid6.h"
+#include <linux/raid/pq.h>
#define NDISKS 16 /* Including P and Q */
diff --git a/drivers/md/raid6x86.h b/drivers/md/raid6x86.h
index 99fea7a70ca7..4c22c1568558 100644
--- a/drivers/md/raid6x86.h
+++ b/drivers/md/raid6x86.h
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 93ea201f426c..223c36ede5ae 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -117,7 +117,7 @@ source "drivers/media/dvb/Kconfig"
config DAB
boolean "DAB adapters"
---help---
- Allow selecting support for for Digital Audio Broadcasting (DAB)
+ Allow selecting support for Digital Audio Broadcasting (DAB)
Receiver adapters.
if DAB
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index d8229a0e9a9c..3fe158ac7bbf 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -153,6 +153,65 @@ IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a);
+/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
+IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE] = {
+ [0x00] = KEY_POWER,
+ [0x01] = KEY_TUNER, /* TV/FM */
+ [0x03] = KEY_TEXT, /* Teletext */
+ [0x04] = KEY_EPG,
+ [0x05] = KEY_1,
+ [0x06] = KEY_2,
+ [0x07] = KEY_3,
+ [0x08] = KEY_AUDIO,
+ [0x09] = KEY_4,
+ [0x0a] = KEY_5,
+ [0x0b] = KEY_6,
+ [0x0c] = KEY_ZOOM, /* Full screen */
+ [0x0d] = KEY_7,
+ [0x0e] = KEY_8,
+ [0x0f] = KEY_9,
+ [0x10] = KEY_PAGEUP, /* 16-CH PREV */
+ [0x11] = KEY_0,
+ [0x12] = KEY_INFO,
+ [0x13] = KEY_AGAIN, /* CH RTN - channel return */
+ [0x14] = KEY_MUTE,
+ [0x15] = KEY_EDIT, /* Autoscan */
+ [0x17] = KEY_SAVE, /* Screenshot */
+ [0x18] = KEY_PLAYPAUSE,
+ [0x19] = KEY_RECORD,
+ [0x1a] = KEY_PLAY,
+ [0x1b] = KEY_STOP,
+ [0x1c] = KEY_FASTFORWARD,
+ [0x1d] = KEY_REWIND,
+ [0x1e] = KEY_VOLUMEDOWN,
+ [0x1f] = KEY_VOLUMEUP,
+ [0x22] = KEY_SLEEP, /* Sleep */
+ [0x23] = KEY_ZOOM, /* Aspect */
+ [0x26] = KEY_SCREEN, /* Pos */
+ [0x27] = KEY_ANGLE, /* Size */
+ [0x28] = KEY_SELECT, /* Select */
+ [0x29] = KEY_BLUE, /* Blue/Picture */
+ [0x2a] = KEY_BACKSPACE, /* Back */
+ [0x2b] = KEY_MEDIA, /* PIP (Picture-in-picture) */
+ [0x2c] = KEY_DOWN,
+ [0x2e] = KEY_DOT,
+ [0x2f] = KEY_TV, /* Live TV */
+ [0x32] = KEY_LEFT,
+ [0x33] = KEY_CLEAR, /* Clear */
+ [0x35] = KEY_RED, /* Red/TV */
+ [0x36] = KEY_UP,
+ [0x37] = KEY_HOME, /* Home */
+ [0x39] = KEY_GREEN, /* Green/Video */
+ [0x3d] = KEY_YELLOW, /* Yellow/Music */
+ [0x3e] = KEY_OK, /* Ok */
+ [0x3f] = KEY_RIGHT,
+ [0x40] = KEY_NEXT, /* Next */
+ [0x41] = KEY_PREVIOUS, /* Previous */
+ [0x42] = KEY_CHANNELDOWN, /* Channel down */
+ [0x43] = KEY_CHANNELUP /* Channel up */
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus);
+
/* Attila Kondoros <attila.kondoros@chello.hu> */
IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
@@ -2452,6 +2511,55 @@ IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog);
+/* Kaiomy TVnPC U2
+ Mauro Carvalho Chehab <mchehab@infradead.org>
+ */
+IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE] = {
+ [0x43] = KEY_POWER2,
+ [0x01] = KEY_LIST,
+ [0x0b] = KEY_ZOOM,
+ [0x03] = KEY_POWER,
+
+ [0x04] = KEY_1,
+ [0x08] = KEY_2,
+ [0x02] = KEY_3,
+
+ [0x0f] = KEY_4,
+ [0x05] = KEY_5,
+ [0x06] = KEY_6,
+
+ [0x0c] = KEY_7,
+ [0x0d] = KEY_8,
+ [0x0a] = KEY_9,
+
+ [0x11] = KEY_0,
+
+ [0x09] = KEY_CHANNELUP,
+ [0x07] = KEY_CHANNELDOWN,
+
+ [0x0e] = KEY_VOLUMEUP,
+ [0x13] = KEY_VOLUMEDOWN,
+
+ [0x10] = KEY_HOME,
+ [0x12] = KEY_ENTER,
+
+ [0x14] = KEY_RECORD,
+ [0x15] = KEY_STOP,
+ [0x16] = KEY_PLAY,
+ [0x17] = KEY_MUTE,
+
+ [0x18] = KEY_UP,
+ [0x19] = KEY_DOWN,
+ [0x1a] = KEY_LEFT,
+ [0x1b] = KEY_RIGHT,
+
+ [0x1c] = KEY_RED,
+ [0x1d] = KEY_GREEN,
+ [0x1e] = KEY_YELLOW,
+ [0x1f] = KEY_BLUE,
+};
+EXPORT_SYMBOL_GPL(ir_codes_kaiomy);
+
IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = {
[0x20] = KEY_LIST,
[0x00] = KEY_POWER,
@@ -2604,3 +2712,41 @@ IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600);
+
+/* DVBWorld remotes
+ Igor M. Liplianin <liplianin@me.by>
+ */
+IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE] = {
+ [0x0a] = KEY_Q, /*power*/
+ [0x0c] = KEY_M, /*mute*/
+ [0x11] = KEY_1,
+ [0x12] = KEY_2,
+ [0x13] = KEY_3,
+ [0x14] = KEY_4,
+ [0x15] = KEY_5,
+ [0x16] = KEY_6,
+ [0x17] = KEY_7,
+ [0x18] = KEY_8,
+ [0x19] = KEY_9,
+ [0x10] = KEY_0,
+ [0x1c] = KEY_PAGEUP, /*ch+*/
+ [0x0f] = KEY_PAGEDOWN, /*ch-*/
+ [0x1a] = KEY_O, /*vol+*/
+ [0x0e] = KEY_Z, /*vol-*/
+ [0x04] = KEY_R, /*rec*/
+ [0x09] = KEY_D, /*fav*/
+ [0x08] = KEY_BACKSPACE, /*rewind*/
+ [0x07] = KEY_A, /*fast*/
+ [0x0b] = KEY_P, /*pause*/
+ [0x02] = KEY_ESC, /*cancel*/
+ [0x03] = KEY_G, /*tab*/
+ [0x00] = KEY_UP, /*up*/
+ [0x1f] = KEY_ENTER, /*ok*/
+ [0x01] = KEY_DOWN, /*down*/
+ [0x05] = KEY_C, /*cap*/
+ [0x06] = KEY_S, /*stop*/
+ [0x40] = KEY_F, /*full*/
+ [0x1e] = KEY_W, /*tvmode*/
+ [0x1b] = KEY_B, /*recall*/
+};
+EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec);
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index d599d360da3f..982f000a57ff 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -452,8 +452,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device));
dev->ext = ext;
- pci_set_drvdata(pci, dev);
-
mutex_init(&dev->lock);
spin_lock_init(&dev->int_slock);
spin_lock_init(&dev->slock);
@@ -477,8 +475,12 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
if (ext->attach(dev, pci_ext)) {
DEB_D(("ext->attach() failed for %p. skipping device.\n",dev));
- goto err_unprobe;
+ goto err_free_i2c;
}
+ /* V4L extensions will set the pci drvdata to the v4l2_device in the
+ attach() above. So for those cards that do not use V4L we have to
+ set it explicitly. */
+ pci_set_drvdata(pci, &dev->v4l2_dev);
INIT_LIST_HEAD(&dev->item);
list_add_tail(&dev->item,&saa7146_devices);
@@ -488,8 +490,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
out:
return err;
-err_unprobe:
- pci_set_drvdata(pci, NULL);
err_free_i2c:
pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr,
dev->d_i2c.dma_handle);
@@ -514,7 +514,8 @@ err_free:
static void saa7146_remove_one(struct pci_dev *pdev)
{
- struct saa7146_dev* dev = pci_get_drvdata(pdev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
+ struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
struct {
void *addr;
dma_addr_t dma;
@@ -528,6 +529,8 @@ static void saa7146_remove_one(struct pci_dev *pdev)
DEB_EE(("dev:%p\n",dev));
dev->ext->detach(dev);
+ /* Zero the PCI drvdata after use. */
+ pci_set_drvdata(pdev, NULL);
/* shut down all video dma transfers */
saa7146_write(dev, MC1, 0x00ff0000);
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index cf06f4d10ad4..620f655fa9c5 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -308,14 +308,6 @@ static int fops_release(struct file *file)
return 0;
}
-static long fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-/*
- DEB_EE(("file:%p, cmd:%d, arg:%li\n", file, cmd, arg));
-*/
- return video_usercopy(file, cmd, arg, saa7146_video_do_ioctl);
-}
-
static int fops_mmap(struct file *file, struct vm_area_struct * vma)
{
struct saa7146_fh *fh = file->private_data;
@@ -425,7 +417,7 @@ static const struct v4l2_file_operations video_fops =
.write = fops_write,
.poll = fops_poll,
.mmap = fops_mmap,
- .ioctl = fops_ioctl,
+ .ioctl = video_ioctl2,
};
static void vv_callback(struct saa7146_dev *dev, unsigned long status)
@@ -452,19 +444,22 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status)
}
}
-static struct video_device device_template =
-{
- .fops = &video_fops,
- .minor = -1,
-};
-
int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
{
- struct saa7146_vv *vv = kzalloc (sizeof(struct saa7146_vv),GFP_KERNEL);
- if( NULL == vv ) {
+ struct saa7146_vv *vv;
+ int err;
+
+ err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
+ if (err)
+ return err;
+
+ vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL);
+ if (vv == NULL) {
ERR(("out of memory. aborting.\n"));
- return -1;
+ return -ENOMEM;
}
+ ext_vv->ops = saa7146_video_ioctl_ops;
+ ext_vv->core_ops = &saa7146_video_ioctl_ops;
DEB_EE(("dev:%p\n",dev));
@@ -507,6 +502,7 @@ int saa7146_vv_release(struct saa7146_dev* dev)
DEB_EE(("dev:%p\n",dev));
+ v4l2_device_unregister(&dev->v4l2_dev);
pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
kfree(vv);
dev->vv_data = NULL;
@@ -521,6 +517,8 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
{
struct saa7146_vv *vv = dev->vv_data;
struct video_device *vfd;
+ int err;
+ int i;
DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type));
@@ -529,16 +527,20 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
if (vfd == NULL)
return -ENOMEM;
- memcpy(vfd, &device_template, sizeof(struct video_device));
- strlcpy(vfd->name, name, sizeof(vfd->name));
+ vfd->fops = &video_fops;
+ vfd->ioctl_ops = &dev->ext_vv_data->ops;
vfd->release = video_device_release;
+ vfd->tvnorms = 0;
+ for (i = 0; i < dev->ext_vv_data->num_stds; i++)
+ vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
+ strlcpy(vfd->name, name, sizeof(vfd->name));
video_set_drvdata(vfd, dev);
- // fixme: -1 should be an insmod parameter *for the extension* (like "video_nr");
- if (video_register_device(vfd, type, -1) < 0) {
+ err = video_register_device(vfd, type, -1);
+ if (err < 0) {
ERR(("cannot register v4l2 device. skipping.\n"));
video_device_release(vfd);
- return -1;
+ return err;
}
if( VFL_TYPE_GRABBER == type ) {
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c
index c11da4d09cd0..7e8f56815998 100644
--- a/drivers/media/common/saa7146_i2c.c
+++ b/drivers/media/common/saa7146_i2c.c
@@ -293,7 +293,6 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m
int i = 0, count = 0;
__le32 *buffer = dev->d_i2c.cpu_addr;
int err = 0;
- int address_err = 0;
int short_delay = 0;
if (mutex_lock_interruptible(&dev->i2c_lock))
@@ -333,17 +332,10 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m
i2c address probing, however, and address errors indicate that a
device is really *not* there. retrying in that case
increases the time the device needs to probe greatly, so
- it should be avoided. because of the fact, that only
- analog based cards use irq based i2c transactions (for dvb
- cards, this screwes up other interrupt sources), we bail out
- completely for analog cards after an address error and trust
- the saa7146 address error detection. */
- if ( -EREMOTEIO == err ) {
- if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) {
- goto out;
- }
- address_err++;
- }
+ it should be avoided. So we bail out in irq mode after an
+ address error and trust the saa7146 address error detection. */
+ if (-EREMOTEIO == err && 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags))
+ goto out;
DEB_I2C(("error while sending message(s). starting again.\n"));
break;
}
@@ -358,10 +350,9 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m
} while (err != num && retries--);
- /* if every retry had an address error, exit right away */
- if (address_err == retries) {
+ /* quit if any error occurred */
+ if (err != num)
goto out;
- }
/* if any things had to be read, get the results */
if ( 0 != saa7146_i2c_msg_cleanup(msgs, num, buffer)) {
@@ -390,7 +381,8 @@ out:
/* utility functions */
static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
{
- struct saa7146_dev* dev = i2c_get_adapdata(adapter);
+ struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter);
+ struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
/* use helper function to transfer data */
return saa7146_i2c_transfer(dev, msg, num, adapter->retries);
@@ -417,9 +409,8 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c
dev->i2c_bitrate = bitrate;
saa7146_i2c_reset(dev);
- if( NULL != i2c_adapter ) {
- BUG_ON(!i2c_adapter->class);
- i2c_set_adapdata(i2c_adapter,dev);
+ if (i2c_adapter) {
+ i2c_set_adapdata(i2c_adapter, &dev->v4l2_dev);
i2c_adapter->dev.parent = &dev->pci->dev;
i2c_adapter->algo = &saa7146_algo;
i2c_adapter->algo_data = NULL;
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 47fee05eaefb..552dab442d78 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -1,4 +1,5 @@
#include <media/saa7146_vv.h>
+#include <media/v4l2-chip-ident.h>
static int max_memory = 32;
@@ -97,172 +98,13 @@ struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc)
return NULL;
}
-static int g_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
-{
- struct saa7146_dev *dev = fh->dev;
- DEB_EE(("dev:%p, fh:%p\n",dev,fh));
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- f->fmt.pix = fh->video_fmt;
- return 0;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- f->fmt.win = fh->ov.win;
- return 0;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- {
- f->fmt.vbi = fh->vbi_fmt;
- return 0;
- }
- default:
- DEB_D(("invalid format type '%d'.\n",f->type));
- return -EINVAL;
- }
-}
-
-static int try_win(struct saa7146_dev *dev, struct v4l2_window *win)
-{
- struct saa7146_vv *vv = dev->vv_data;
- enum v4l2_field field;
- int maxw, maxh;
-
- DEB_EE(("dev:%p\n",dev));
-
- if (NULL == vv->ov_fb.base) {
- DEB_D(("no fb base set.\n"));
- return -EINVAL;
- }
- if (NULL == vv->ov_fmt) {
- DEB_D(("no fb fmt set.\n"));
- return -EINVAL;
- }
- if (win->w.width < 48 || win->w.height < 32) {
- DEB_D(("min width/height. (%d,%d)\n",win->w.width,win->w.height));
- return -EINVAL;
- }
- if (win->clipcount > 16) {
- DEB_D(("clipcount too big.\n"));
- return -EINVAL;
- }
-
- field = win->field;
- maxw = vv->standard->h_max_out;
- maxh = vv->standard->v_max_out;
-
- if (V4L2_FIELD_ANY == field) {
- field = (win->w.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_TOP;
- }
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- case V4L2_FIELD_ALTERNATE:
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- break;
- default: {
- DEB_D(("no known field mode '%d'.\n",field));
- return -EINVAL;
- }
- }
-
- win->field = field;
- if (win->w.width > maxw)
- win->w.width = maxw;
- if (win->w.height > maxh)
- win->w.height = maxh;
-
- return 0;
-}
-
-static int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
-{
- struct saa7146_dev *dev = fh->dev;
- struct saa7146_vv *vv = dev->vv_data;
- int err;
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- {
- struct saa7146_format *fmt;
- enum v4l2_field field;
- int maxw, maxh;
- int calc_bpl;
-
- DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
-
- fmt = format_by_fourcc(dev,f->fmt.pix.pixelformat);
- if (NULL == fmt) {
- return -EINVAL;
- }
-
- field = f->fmt.pix.field;
- maxw = vv->standard->h_max_out;
- maxh = vv->standard->v_max_out;
-
- if (V4L2_FIELD_ANY == field) {
- field = (f->fmt.pix.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_BOTTOM;
- }
- switch (field) {
- case V4L2_FIELD_ALTERNATE: {
- vv->last_field = V4L2_FIELD_TOP;
- maxh = maxh / 2;
- break;
- }
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- vv->last_field = V4L2_FIELD_INTERLACED;
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- vv->last_field = V4L2_FIELD_INTERLACED;
- break;
- default: {
- DEB_D(("no known field mode '%d'.\n",field));
- return -EINVAL;
- }
- }
-
- f->fmt.pix.field = field;
- if (f->fmt.pix.width > maxw)
- f->fmt.pix.width = maxw;
- if (f->fmt.pix.height > maxh)
- f->fmt.pix.height = maxh;
-
- calc_bpl = (f->fmt.pix.width * fmt->depth)/8;
-
- if (f->fmt.pix.bytesperline < calc_bpl)
- f->fmt.pix.bytesperline = calc_bpl;
-
- if (f->fmt.pix.bytesperline > (2*PAGE_SIZE * fmt->depth)/8) /* arbitrary constraint */
- f->fmt.pix.bytesperline = calc_bpl;
-
- f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
- DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n",f->fmt.pix.width,f->fmt.pix.height,f->fmt.pix.bytesperline,f->fmt.pix.sizeimage));
-
- return 0;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh));
- err = try_win(dev,&f->fmt.win);
- if (0 != err) {
- return err;
- }
- return 0;
- default:
- DEB_EE(("unknown format type '%d'\n",f->type));
- return -EINVAL;
- }
-}
+static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f);
int saa7146_start_preview(struct saa7146_fh *fh)
{
struct saa7146_dev *dev = fh->dev;
struct saa7146_vv *vv = dev->vv_data;
+ struct v4l2_format fmt;
int ret = 0, err = 0;
DEB_EE(("dev:%p, fh:%p\n",dev,fh));
@@ -294,12 +136,13 @@ int saa7146_start_preview(struct saa7146_fh *fh)
return -EBUSY;
}
- err = try_win(dev,&fh->ov.win);
+ fmt.fmt.win = fh->ov.win;
+ err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt);
if (0 != err) {
saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
return -EBUSY;
}
-
+ fh->ov.win = fmt.fmt.win;
vv->ov_data = &fh->ov;
DEB_D(("%dx%d+%d+%d %s field=%s\n",
@@ -355,58 +198,6 @@ int saa7146_stop_preview(struct saa7146_fh *fh)
}
EXPORT_SYMBOL_GPL(saa7146_stop_preview);
-static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
-{
- struct saa7146_dev *dev = fh->dev;
- struct saa7146_vv *vv = dev->vv_data;
-
- int err;
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
- if (IS_CAPTURE_ACTIVE(fh) != 0) {
- DEB_EE(("streaming capture is active\n"));
- return -EBUSY;
- }
- err = try_fmt(fh,f);
- if (0 != err)
- return err;
- fh->video_fmt = f->fmt.pix;
- DEB_EE(("set to pixelformat '%4.4s'\n",(char *)&fh->video_fmt.pixelformat));
- return 0;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh));
- err = try_win(dev,&f->fmt.win);
- if (0 != err)
- return err;
- mutex_lock(&dev->lock);
- fh->ov.win = f->fmt.win;
- fh->ov.nclips = f->fmt.win.clipcount;
- if (fh->ov.nclips > 16)
- fh->ov.nclips = 16;
- if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) {
- mutex_unlock(&dev->lock);
- return -EFAULT;
- }
-
- /* fh->ov.fh is used to indicate that we have valid overlay informations, too */
- fh->ov.fh = fh;
-
- mutex_unlock(&dev->lock);
-
- /* check if our current overlay is active */
- if (IS_OVERLAY_ACTIVE(fh) != 0) {
- saa7146_stop_preview(fh);
- saa7146_start_preview(fh);
- }
- return 0;
- default:
- DEB_D(("unknown format type '%d'\n",f->type));
- return -EINVAL;
- }
-}
-
/********************************************************************************/
/* device controls */
@@ -419,6 +210,7 @@ static struct v4l2_queryctrl controls[] = {
.step = 1,
.default_value = 128,
.type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
},{
.id = V4L2_CID_CONTRAST,
.name = "Contrast",
@@ -427,6 +219,7 @@ static struct v4l2_queryctrl controls[] = {
.step = 1,
.default_value = 64,
.type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
},{
.id = V4L2_CID_SATURATION,
.name = "Saturation",
@@ -435,15 +228,16 @@ static struct v4l2_queryctrl controls[] = {
.step = 1,
.default_value = 64,
.type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
},{
.id = V4L2_CID_VFLIP,
- .name = "Vertical flip",
+ .name = "Vertical Flip",
.minimum = 0,
.maximum = 1,
.type = V4L2_CTRL_TYPE_BOOLEAN,
},{
.id = V4L2_CID_HFLIP,
- .name = "Horizontal flip",
+ .name = "Horizontal Flip",
.minimum = 0,
.maximum = 1,
.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -463,132 +257,6 @@ static struct v4l2_queryctrl* ctrl_by_id(int id)
return NULL;
}
-static int get_control(struct saa7146_fh *fh, struct v4l2_control *c)
-{
- struct saa7146_dev *dev = fh->dev;
- struct saa7146_vv *vv = dev->vv_data;
-
- const struct v4l2_queryctrl* ctrl;
- u32 value = 0;
-
- ctrl = ctrl_by_id(c->id);
- if (NULL == ctrl)
- return -EINVAL;
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- value = saa7146_read(dev, BCS_CTRL);
- c->value = 0xff & (value >> 24);
- DEB_D(("V4L2_CID_BRIGHTNESS: %d\n",c->value));
- break;
- case V4L2_CID_CONTRAST:
- value = saa7146_read(dev, BCS_CTRL);
- c->value = 0x7f & (value >> 16);
- DEB_D(("V4L2_CID_CONTRAST: %d\n",c->value));
- break;
- case V4L2_CID_SATURATION:
- value = saa7146_read(dev, BCS_CTRL);
- c->value = 0x7f & (value >> 0);
- DEB_D(("V4L2_CID_SATURATION: %d\n",c->value));
- break;
- case V4L2_CID_VFLIP:
- c->value = vv->vflip;
- DEB_D(("V4L2_CID_VFLIP: %d\n",c->value));
- break;
- case V4L2_CID_HFLIP:
- c->value = vv->hflip;
- DEB_D(("V4L2_CID_HFLIP: %d\n",c->value));
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
-{
- struct saa7146_dev *dev = fh->dev;
- struct saa7146_vv *vv = dev->vv_data;
-
- const struct v4l2_queryctrl* ctrl;
-
- ctrl = ctrl_by_id(c->id);
- if (NULL == ctrl) {
- DEB_D(("unknown control %d\n",c->id));
- return -EINVAL;
- }
-
- mutex_lock(&dev->lock);
-
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_BOOLEAN:
- case V4L2_CTRL_TYPE_MENU:
- case V4L2_CTRL_TYPE_INTEGER:
- if (c->value < ctrl->minimum)
- c->value = ctrl->minimum;
- if (c->value > ctrl->maximum)
- c->value = ctrl->maximum;
- break;
- default:
- /* nothing */;
- };
-
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS: {
- u32 value = saa7146_read(dev, BCS_CTRL);
- value &= 0x00ffffff;
- value |= (c->value << 24);
- saa7146_write(dev, BCS_CTRL, value);
- saa7146_write(dev, MC2, MASK_22 | MASK_06 );
- break;
- }
- case V4L2_CID_CONTRAST: {
- u32 value = saa7146_read(dev, BCS_CTRL);
- value &= 0xff00ffff;
- value |= (c->value << 16);
- saa7146_write(dev, BCS_CTRL, value);
- saa7146_write(dev, MC2, MASK_22 | MASK_06 );
- break;
- }
- case V4L2_CID_SATURATION: {
- u32 value = saa7146_read(dev, BCS_CTRL);
- value &= 0xffffff00;
- value |= (c->value << 0);
- saa7146_write(dev, BCS_CTRL, value);
- saa7146_write(dev, MC2, MASK_22 | MASK_06 );
- break;
- }
- case V4L2_CID_HFLIP:
- /* fixme: we can support changing VFLIP and HFLIP here... */
- if (IS_CAPTURE_ACTIVE(fh) != 0) {
- DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
- mutex_unlock(&dev->lock);
- return -EINVAL;
- }
- vv->hflip = c->value;
- break;
- case V4L2_CID_VFLIP:
- if (IS_CAPTURE_ACTIVE(fh) != 0) {
- DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
- mutex_unlock(&dev->lock);
- return -EINVAL;
- }
- vv->vflip = c->value;
- break;
- default: {
- mutex_unlock(&dev->lock);
- return -EINVAL;
- }
- }
- mutex_unlock(&dev->lock);
-
- if (IS_OVERLAY_ACTIVE(fh) != 0) {
- saa7146_stop_preview(fh);
- saa7146_start_preview(fh);
- }
- return 0;
-}
-
/********************************************************************************/
/* common pagetable functions */
@@ -829,231 +497,446 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
return 0;
}
-/*
- * This function is _not_ called directly, but from
- * video_generic_ioctl (and maybe others). userspace
- * copying is done already, arg is a kernel pointer.
- */
+static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+
+ strcpy((char *)cap->driver, "saa7146 v4l2");
+ strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
+ sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
+ cap->version = SAA7146_VERSION_CODE;
+ cap->capabilities =
+ V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_VIDEO_OVERLAY |
+ V4L2_CAP_READWRITE |
+ V4L2_CAP_STREAMING;
+ cap->capabilities |= dev->ext_vv_data->capabilities;
+ return 0;
+}
-long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
+static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
{
- struct saa7146_fh *fh = file->private_data;
- struct saa7146_dev *dev = fh->dev;
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+
+ *fb = vv->ov_fb;
+ fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
+ return 0;
+}
+
+static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct saa7146_vv *vv = dev->vv_data;
+ struct saa7146_format *fmt;
- long err = 0;
- int result = 0, ee = 0;
+ DEB_EE(("VIDIOC_S_FBUF\n"));
- struct saa7146_use_ops *ops;
- struct videobuf_queue *q;
+ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
+ return -EPERM;
- /* check if extension handles the command */
- for(ee = 0; dev->ext_vv_data->ioctls[ee].flags != 0; ee++) {
- if( cmd == dev->ext_vv_data->ioctls[ee].cmd )
- break;
+ /* check args */
+ fmt = format_by_fourcc(dev, fb->fmt.pixelformat);
+ if (NULL == fmt)
+ return -EINVAL;
+
+ /* planar formats are not allowed for overlay video, clipping and video dma would clash */
+ if (fmt->flags & FORMAT_IS_PLANAR)
+ DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",
+ (char *)&fmt->pixelformat));
+
+ /* check if overlay is running */
+ if (IS_OVERLAY_ACTIVE(fh) != 0) {
+ if (vv->video_fh != fh) {
+ DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n"));
+ return -EBUSY;
+ }
}
- if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) {
- DEB_D(("extension handles ioctl exclusive.\n"));
- result = dev->ext_vv_data->ioctl(fh, cmd, arg);
- return result;
+ mutex_lock(&dev->lock);
+
+ /* ok, accept it */
+ vv->ov_fb = *fb;
+ vv->ov_fmt = fmt;
+ if (0 == vv->ov_fb.fmt.bytesperline)
+ vv->ov_fb.fmt.bytesperline =
+ vv->ov_fb.fmt.width * fmt->depth / 8;
+
+ mutex_unlock(&dev->lock);
+ return 0;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+ if (f->index >= NUM_FORMATS)
+ return -EINVAL;
+ strlcpy((char *)f->description, formats[f->index].name,
+ sizeof(f->description));
+ f->pixelformat = formats[f->index].pixelformat;
+ return 0;
+}
+
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
+{
+ const struct v4l2_queryctrl *ctrl;
+
+ if ((c->id < V4L2_CID_BASE ||
+ c->id >= V4L2_CID_LASTP1) &&
+ (c->id < V4L2_CID_PRIVATE_BASE ||
+ c->id >= V4L2_CID_PRIVATE_LASTP1))
+ return -EINVAL;
+
+ ctrl = ctrl_by_id(c->id);
+ if (ctrl == NULL)
+ return -EINVAL;
+
+ DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n", c->id));
+ *c = *ctrl;
+ return 0;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ const struct v4l2_queryctrl *ctrl;
+ u32 value = 0;
+
+ ctrl = ctrl_by_id(c->id);
+ if (NULL == ctrl)
+ return -EINVAL;
+ switch (c->id) {
+ case V4L2_CID_BRIGHTNESS:
+ value = saa7146_read(dev, BCS_CTRL);
+ c->value = 0xff & (value >> 24);
+ DEB_D(("V4L2_CID_BRIGHTNESS: %d\n", c->value));
+ break;
+ case V4L2_CID_CONTRAST:
+ value = saa7146_read(dev, BCS_CTRL);
+ c->value = 0x7f & (value >> 16);
+ DEB_D(("V4L2_CID_CONTRAST: %d\n", c->value));
+ break;
+ case V4L2_CID_SATURATION:
+ value = saa7146_read(dev, BCS_CTRL);
+ c->value = 0x7f & (value >> 0);
+ DEB_D(("V4L2_CID_SATURATION: %d\n", c->value));
+ break;
+ case V4L2_CID_VFLIP:
+ c->value = vv->vflip;
+ DEB_D(("V4L2_CID_VFLIP: %d\n", c->value));
+ break;
+ case V4L2_CID_HFLIP:
+ c->value = vv->hflip;
+ DEB_D(("V4L2_CID_HFLIP: %d\n", c->value));
+ break;
+ default:
+ return -EINVAL;
}
- if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) {
- DEB_D(("extension handles ioctl before.\n"));
- result = dev->ext_vv_data->ioctl(fh, cmd, arg);
- if( -EAGAIN != result ) {
- return result;
- }
+ return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ const struct v4l2_queryctrl *ctrl;
+
+ ctrl = ctrl_by_id(c->id);
+ if (NULL == ctrl) {
+ DEB_D(("unknown control %d\n", c->id));
+ return -EINVAL;
}
- /* fixme: add handle "after" case (is it still needed?) */
+ mutex_lock(&dev->lock);
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- ops = &saa7146_video_uops;
- q = &fh->video_q;
+ switch (ctrl->type) {
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ case V4L2_CTRL_TYPE_MENU:
+ case V4L2_CTRL_TYPE_INTEGER:
+ if (c->value < ctrl->minimum)
+ c->value = ctrl->minimum;
+ if (c->value > ctrl->maximum)
+ c->value = ctrl->maximum;
break;
+ default:
+ /* nothing */;
+ }
+
+ switch (c->id) {
+ case V4L2_CID_BRIGHTNESS: {
+ u32 value = saa7146_read(dev, BCS_CTRL);
+ value &= 0x00ffffff;
+ value |= (c->value << 24);
+ saa7146_write(dev, BCS_CTRL, value);
+ saa7146_write(dev, MC2, MASK_22 | MASK_06);
+ break;
+ }
+ case V4L2_CID_CONTRAST: {
+ u32 value = saa7146_read(dev, BCS_CTRL);
+ value &= 0xff00ffff;
+ value |= (c->value << 16);
+ saa7146_write(dev, BCS_CTRL, value);
+ saa7146_write(dev, MC2, MASK_22 | MASK_06);
+ break;
+ }
+ case V4L2_CID_SATURATION: {
+ u32 value = saa7146_read(dev, BCS_CTRL);
+ value &= 0xffffff00;
+ value |= (c->value << 0);
+ saa7146_write(dev, BCS_CTRL, value);
+ saa7146_write(dev, MC2, MASK_22 | MASK_06);
+ break;
+ }
+ case V4L2_CID_HFLIP:
+ /* fixme: we can support changing VFLIP and HFLIP here... */
+ if (IS_CAPTURE_ACTIVE(fh) != 0) {
+ DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
+ mutex_unlock(&dev->lock);
+ return -EBUSY;
}
- case V4L2_BUF_TYPE_VBI_CAPTURE: {
- ops = &saa7146_vbi_uops;
- q = &fh->vbi_q;
+ vv->hflip = c->value;
break;
+ case V4L2_CID_VFLIP:
+ if (IS_CAPTURE_ACTIVE(fh) != 0) {
+ DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
+ mutex_unlock(&dev->lock);
+ return -EBUSY;
}
+ vv->vflip = c->value;
+ break;
default:
- BUG();
- return 0;
+ mutex_unlock(&dev->lock);
+ return -EINVAL;
}
+ mutex_unlock(&dev->lock);
- switch (cmd) {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *cap = arg;
- memset(cap,0,sizeof(*cap));
-
- DEB_EE(("VIDIOC_QUERYCAP\n"));
-
- strcpy((char *)cap->driver, "saa7146 v4l2");
- strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
- sprintf((char *)cap->bus_info,"PCI:%s", pci_name(dev->pci));
- cap->version = SAA7146_VERSION_CODE;
- cap->capabilities =
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_VIDEO_OVERLAY |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING;
- cap->capabilities |= dev->ext_vv_data->capabilities;
- return 0;
+ if (IS_OVERLAY_ACTIVE(fh) != 0) {
+ saa7146_stop_preview(fh);
+ saa7146_start_preview(fh);
}
- case VIDIOC_G_FBUF:
- {
- struct v4l2_framebuffer *fb = arg;
-
- DEB_EE(("VIDIOC_G_FBUF\n"));
+ return 0;
+}
- *fb = vv->ov_fb;
- fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
- return 0;
- }
- case VIDIOC_S_FBUF:
- {
- struct v4l2_framebuffer *fb = arg;
- struct saa7146_format *fmt;
+static int vidioc_g_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *parm)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
- DEB_EE(("VIDIOC_S_FBUF\n"));
+ parm->parm.capture.readbuffers = 1;
+ v4l2_video_std_frame_period(vv->standard->id,
+ &parm->parm.capture.timeperframe);
+ return 0;
+}
- if(!capable(CAP_SYS_ADMIN) &&
- !capable(CAP_SYS_RAWIO))
- return -EPERM;
+static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+ f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt;
+ return 0;
+}
- /* check args */
- fmt = format_by_fourcc(dev,fb->fmt.pixelformat);
- if (NULL == fmt) {
- return -EINVAL;
- }
+static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
+{
+ f->fmt.win = ((struct saa7146_fh *)fh)->ov.win;
+ return 0;
+}
- /* planar formats are not allowed for overlay video, clipping and video dma would clash */
- if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
- DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",(char *)&fmt->pixelformat));
- }
+static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+ f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt;
+ return 0;
+}
- /* check if overlay is running */
- if (IS_OVERLAY_ACTIVE(fh) != 0) {
- if (vv->video_fh != fh) {
- DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n"));
- return -EBUSY;
- }
- }
+static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ struct saa7146_format *fmt;
+ enum v4l2_field field;
+ int maxw, maxh;
+ int calc_bpl;
- mutex_lock(&dev->lock);
+ DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
- /* ok, accept it */
- vv->ov_fb = *fb;
- vv->ov_fmt = fmt;
- if (0 == vv->ov_fb.fmt.bytesperline)
- vv->ov_fb.fmt.bytesperline =
- vv->ov_fb.fmt.width*fmt->depth/8;
+ fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat);
+ if (NULL == fmt)
+ return -EINVAL;
- mutex_unlock(&dev->lock);
+ field = f->fmt.pix.field;
+ maxw = vv->standard->h_max_out;
+ maxh = vv->standard->v_max_out;
- return 0;
+ if (V4L2_FIELD_ANY == field) {
+ field = (f->fmt.pix.height > maxh / 2)
+ ? V4L2_FIELD_INTERLACED
+ : V4L2_FIELD_BOTTOM;
}
- case VIDIOC_ENUM_FMT:
- {
- struct v4l2_fmtdesc *f = arg;
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (f->index >= NUM_FORMATS)
- return -EINVAL;
- strlcpy((char *)f->description, formats[f->index].name,
- sizeof(f->description));
- f->pixelformat = formats[f->index].pixelformat;
- f->flags = 0;
- memset(f->reserved, 0, sizeof(f->reserved));
- break;
- default:
- return -EINVAL;
- }
-
- DEB_EE(("VIDIOC_ENUM_FMT: type:%d, index:%d\n",f->type,f->index));
- return 0;
+ switch (field) {
+ case V4L2_FIELD_ALTERNATE:
+ vv->last_field = V4L2_FIELD_TOP;
+ maxh = maxh / 2;
+ break;
+ case V4L2_FIELD_TOP:
+ case V4L2_FIELD_BOTTOM:
+ vv->last_field = V4L2_FIELD_INTERLACED;
+ maxh = maxh / 2;
+ break;
+ case V4L2_FIELD_INTERLACED:
+ vv->last_field = V4L2_FIELD_INTERLACED;
+ break;
+ default:
+ DEB_D(("no known field mode '%d'.\n", field));
+ return -EINVAL;
}
- case VIDIOC_QUERYCTRL:
- {
- const struct v4l2_queryctrl *ctrl;
- struct v4l2_queryctrl *c = arg;
- if ((c->id < V4L2_CID_BASE ||
- c->id >= V4L2_CID_LASTP1) &&
- (c->id < V4L2_CID_PRIVATE_BASE ||
- c->id >= V4L2_CID_PRIVATE_LASTP1))
- return -EINVAL;
+ f->fmt.pix.field = field;
+ if (f->fmt.pix.width > maxw)
+ f->fmt.pix.width = maxw;
+ if (f->fmt.pix.height > maxh)
+ f->fmt.pix.height = maxh;
- ctrl = ctrl_by_id(c->id);
- if( NULL == ctrl ) {
- return -EINVAL;
-/*
- c->flags = V4L2_CTRL_FLAG_DISABLED;
- return 0;
-*/
- }
+ calc_bpl = (f->fmt.pix.width * fmt->depth) / 8;
- DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n",c->id));
- *c = *ctrl;
- return 0;
+ if (f->fmt.pix.bytesperline < calc_bpl)
+ f->fmt.pix.bytesperline = calc_bpl;
+
+ if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */
+ f->fmt.pix.bytesperline = calc_bpl;
+
+ f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
+ DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", f->fmt.pix.width,
+ f->fmt.pix.height, f->fmt.pix.bytesperline, f->fmt.pix.sizeimage));
+
+ return 0;
+}
+
+
+static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ struct v4l2_window *win = &f->fmt.win;
+ enum v4l2_field field;
+ int maxw, maxh;
+
+ DEB_EE(("dev:%p\n", dev));
+
+ if (NULL == vv->ov_fb.base) {
+ DEB_D(("no fb base set.\n"));
+ return -EINVAL;
}
- case VIDIOC_G_CTRL: {
- DEB_EE(("VIDIOC_G_CTRL\n"));
- return get_control(fh,arg);
+ if (NULL == vv->ov_fmt) {
+ DEB_D(("no fb fmt set.\n"));
+ return -EINVAL;
}
- case VIDIOC_S_CTRL:
- {
- DEB_EE(("VIDIOC_S_CTRL\n"));
- err = set_control(fh,arg);
- return err;
+ if (win->w.width < 48 || win->w.height < 32) {
+ DEB_D(("min width/height. (%d,%d)\n", win->w.width, win->w.height));
+ return -EINVAL;
}
- case VIDIOC_G_PARM:
- {
- struct v4l2_streamparm *parm = arg;
- if( parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ) {
- return -EINVAL;
- }
- memset(&parm->parm.capture,0,sizeof(struct v4l2_captureparm));
- parm->parm.capture.readbuffers = 1;
- // fixme: only for PAL!
- parm->parm.capture.timeperframe.numerator = 1;
- parm->parm.capture.timeperframe.denominator = 25;
- return 0;
+ if (win->clipcount > 16) {
+ DEB_D(("clipcount too big.\n"));
+ return -EINVAL;
}
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *f = arg;
- DEB_EE(("VIDIOC_G_FMT\n"));
- return g_fmt(fh,f);
+
+ field = win->field;
+ maxw = vv->standard->h_max_out;
+ maxh = vv->standard->v_max_out;
+
+ if (V4L2_FIELD_ANY == field) {
+ field = (win->w.height > maxh / 2)
+ ? V4L2_FIELD_INTERLACED
+ : V4L2_FIELD_TOP;
+ }
+ switch (field) {
+ case V4L2_FIELD_TOP:
+ case V4L2_FIELD_BOTTOM:
+ case V4L2_FIELD_ALTERNATE:
+ maxh = maxh / 2;
+ break;
+ case V4L2_FIELD_INTERLACED:
+ break;
+ default:
+ DEB_D(("no known field mode '%d'.\n", field));
+ return -EINVAL;
}
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *f = arg;
- DEB_EE(("VIDIOC_S_FMT\n"));
- return s_fmt(fh,f);
+
+ win->field = field;
+ if (win->w.width > maxw)
+ win->w.width = maxw;
+ if (win->w.height > maxh)
+ win->w.height = maxh;
+
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f)
+{
+ struct saa7146_fh *fh = __fh;
+ struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ int err;
+
+ DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
+ if (IS_CAPTURE_ACTIVE(fh) != 0) {
+ DEB_EE(("streaming capture is active\n"));
+ return -EBUSY;
}
- case VIDIOC_TRY_FMT:
- {
- struct v4l2_format *f = arg;
- DEB_EE(("VIDIOC_TRY_FMT\n"));
- return try_fmt(fh,f);
+ err = vidioc_try_fmt_vid_cap(file, fh, f);
+ if (0 != err)
+ return err;
+ fh->video_fmt = f->fmt.pix;
+ DEB_EE(("set to pixelformat '%4.4s'\n", (char *)&fh->video_fmt.pixelformat));
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f)
+{
+ struct saa7146_fh *fh = __fh;
+ struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ int err;
+
+ DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh));
+ err = vidioc_try_fmt_vid_overlay(file, fh, f);
+ if (0 != err)
+ return err;
+ mutex_lock(&dev->lock);
+ fh->ov.win = f->fmt.win;
+ fh->ov.nclips = f->fmt.win.clipcount;
+ if (fh->ov.nclips > 16)
+ fh->ov.nclips = 16;
+ if (copy_from_user(fh->ov.clips, f->fmt.win.clips,
+ sizeof(struct v4l2_clip) * fh->ov.nclips)) {
+ mutex_unlock(&dev->lock);
+ return -EFAULT;
}
- case VIDIOC_G_STD:
- {
- v4l2_std_id *id = arg;
- DEB_EE(("VIDIOC_G_STD\n"));
- *id = vv->standard->id;
- return 0;
+
+ /* fh->ov.fh is used to indicate that we have valid overlay informations, too */
+ fh->ov.fh = fh;
+
+ mutex_unlock(&dev->lock);
+
+ /* check if our current overlay is active */
+ if (IS_OVERLAY_ACTIVE(fh) != 0) {
+ saa7146_stop_preview(fh);
+ saa7146_start_preview(fh);
}
+ return 0;
+}
+
+static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+
+ *norm = vv->standard->id;
+ return 0;
+}
+
/* the saa7146 supfhrts (used in conjunction with the saa7111a for example)
PAL / NTSC / SECAM. if your hardware does not (or does more)
-- override this function in your extension */
+/*
case VIDIOC_ENUMSTD:
{
struct v4l2_standard *e = arg;
@@ -1066,162 +949,245 @@ long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
}
return -EINVAL;
}
- case VIDIOC_S_STD:
- {
- v4l2_std_id *id = arg;
- int found = 0;
- int i;
-
- DEB_EE(("VIDIOC_S_STD\n"));
+ */
- if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
- DEB_D(("cannot change video standard while streaming capture is active\n"));
- return -EBUSY;
- }
+static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ int found = 0;
+ int err, i;
- if ((vv->video_status & STATUS_OVERLAY) != 0) {
- vv->ov_suspend = vv->video_fh;
- err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
- if (0 != err) {
- DEB_D(("suspending video failed. aborting\n"));
- return err;
- }
- }
+ DEB_EE(("VIDIOC_S_STD\n"));
- mutex_lock(&dev->lock);
+ if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
+ DEB_D(("cannot change video standard while streaming capture is active\n"));
+ return -EBUSY;
+ }
- for(i = 0; i < dev->ext_vv_data->num_stds; i++)
- if (*id & dev->ext_vv_data->stds[i].id)
- break;
- if (i != dev->ext_vv_data->num_stds) {
- vv->standard = &dev->ext_vv_data->stds[i];
- if( NULL != dev->ext_vv_data->std_callback )
- dev->ext_vv_data->std_callback(dev, vv->standard);
- found = 1;
+ if ((vv->video_status & STATUS_OVERLAY) != 0) {
+ vv->ov_suspend = vv->video_fh;
+ err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
+ if (0 != err) {
+ DEB_D(("suspending video failed. aborting\n"));
+ return err;
}
+ }
- mutex_unlock(&dev->lock);
+ mutex_lock(&dev->lock);
- if (vv->ov_suspend != NULL) {
- saa7146_start_preview(vv->ov_suspend);
- vv->ov_suspend = NULL;
- }
+ for (i = 0; i < dev->ext_vv_data->num_stds; i++)
+ if (*id & dev->ext_vv_data->stds[i].id)
+ break;
+ if (i != dev->ext_vv_data->num_stds) {
+ vv->standard = &dev->ext_vv_data->stds[i];
+ if (NULL != dev->ext_vv_data->std_callback)
+ dev->ext_vv_data->std_callback(dev, vv->standard);
+ found = 1;
+ }
- if( 0 == found ) {
- DEB_EE(("VIDIOC_S_STD: standard not found.\n"));
- return -EINVAL;
- }
+ mutex_unlock(&dev->lock);
- DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n",vv->standard->name));
- return 0;
+ if (vv->ov_suspend != NULL) {
+ saa7146_start_preview(vv->ov_suspend);
+ vv->ov_suspend = NULL;
}
- case VIDIOC_OVERLAY:
- {
- int on = *(int *)arg;
- DEB_D(("VIDIOC_OVERLAY on:%d\n",on));
- if (on != 0) {
- err = saa7146_start_preview(fh);
- } else {
- err = saa7146_stop_preview(fh);
- }
- return err;
- }
- case VIDIOC_REQBUFS: {
- struct v4l2_requestbuffers *req = arg;
- DEB_D(("VIDIOC_REQBUFS, type:%d\n",req->type));
- return videobuf_reqbufs(q,req);
- }
- case VIDIOC_QUERYBUF: {
- struct v4l2_buffer *buf = arg;
- DEB_D(("VIDIOC_QUERYBUF, type:%d, offset:%d\n",buf->type,buf->m.offset));
- return videobuf_querybuf(q,buf);
- }
- case VIDIOC_QBUF: {
- struct v4l2_buffer *buf = arg;
- int ret = 0;
- ret = videobuf_qbuf(q,buf);
- DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,buf->index));
- return ret;
- }
- case VIDIOC_DQBUF: {
- struct v4l2_buffer *buf = arg;
- int ret = 0;
- ret = videobuf_dqbuf(q,buf,file->f_flags & O_NONBLOCK);
- DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,buf->index));
- return ret;
+ if (!found) {
+ DEB_EE(("VIDIOC_S_STD: standard not found.\n"));
+ return -EINVAL;
}
- case VIDIOC_STREAMON: {
- int *type = arg;
- DEB_D(("VIDIOC_STREAMON, type:%d\n",*type));
- err = video_begin(fh);
- if( 0 != err) {
- return err;
- }
- err = videobuf_streamon(q);
- return err;
- }
- case VIDIOC_STREAMOFF: {
- int *type = arg;
+ DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name));
+ return 0;
+}
- DEB_D(("VIDIOC_STREAMOFF, type:%d\n",*type));
+static int vidioc_overlay(struct file *file, void *fh, unsigned int on)
+{
+ int err;
- /* ugly: we need to copy some checks from video_end(),
- because videobuf_streamoff() relies on the capture running.
- check and fix this */
- if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
- DEB_S(("not capturing.\n"));
- return 0;
- }
+ DEB_D(("VIDIOC_OVERLAY on:%d\n", on));
+ if (on)
+ err = saa7146_start_preview(fh);
+ else
+ err = saa7146_stop_preview(fh);
+ return err;
+}
- if (vv->video_fh != fh) {
- DEB_S(("capturing, but in another open.\n"));
- return -EBUSY;
- }
+static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b)
+{
+ struct saa7146_fh *fh = __fh;
- err = videobuf_streamoff(q);
- if (0 != err) {
- DEB_D(("warning: videobuf_streamoff() failed.\n"));
- video_end(fh, file);
- } else {
- err = video_end(fh, file);
- }
+ if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_reqbufs(&fh->video_q, b);
+ if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_reqbufs(&fh->vbi_q, b);
+ return -EINVAL;
+}
+
+static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct saa7146_fh *fh = __fh;
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_querybuf(&fh->video_q, buf);
+ if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_querybuf(&fh->vbi_q, buf);
+ return -EINVAL;
+}
+
+static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct saa7146_fh *fh = __fh;
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_qbuf(&fh->video_q, buf);
+ if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_qbuf(&fh->vbi_q, buf);
+ return -EINVAL;
+}
+
+static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct saa7146_fh *fh = __fh;
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK);
+ if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK);
+ return -EINVAL;
+}
+
+static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+ struct saa7146_fh *fh = __fh;
+ int err;
+
+ DEB_D(("VIDIOC_STREAMON, type:%d\n", type));
+
+ err = video_begin(fh);
+ if (err)
return err;
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_streamon(&fh->video_q);
+ if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_streamon(&fh->vbi_q);
+ return -EINVAL;
+}
+
+static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+ struct saa7146_fh *fh = __fh;
+ struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ int err;
+
+ DEB_D(("VIDIOC_STREAMOFF, type:%d\n", type));
+
+ /* ugly: we need to copy some checks from video_end(),
+ because videobuf_streamoff() relies on the capture running.
+ check and fix this */
+ if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
+ DEB_S(("not capturing.\n"));
+ return 0;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- case VIDIOCGMBUF:
- {
- struct video_mbuf *mbuf = arg;
- int i;
- /* fixme: number of capture buffers and sizes for v4l apps */
- int gbuffers = 2;
- int gbufsize = 768*576*4;
+ if (vv->video_fh != fh) {
+ DEB_S(("capturing, but in another open.\n"));
+ return -EBUSY;
+ }
- DEB_D(("VIDIOCGMBUF \n"));
+ err = -EINVAL;
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ err = videobuf_streamoff(&fh->video_q);
+ else if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ err = videobuf_streamoff(&fh->vbi_q);
+ if (0 != err) {
+ DEB_D(("warning: videobuf_streamoff() failed.\n"));
+ video_end(fh, file);
+ } else {
+ err = video_end(fh, file);
+ }
+ return err;
+}
- q = &fh->video_q;
- err = videobuf_mmap_setup(q,gbuffers,gbufsize,
- V4L2_MEMORY_MMAP);
- if (err < 0)
- return err;
+static int vidioc_g_chip_ident(struct file *file, void *__fh,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct saa7146_fh *fh = __fh;
+ struct saa7146_dev *dev = fh->dev;
- gbuffers = err;
- memset(mbuf,0,sizeof(*mbuf));
- mbuf->frames = gbuffers;
- mbuf->size = gbuffers * gbufsize;
- for (i = 0; i < gbuffers; i++)
- mbuf->offsets[i] = i * gbufsize;
+ chip->ident = V4L2_IDENT_NONE;
+ chip->revision = 0;
+ if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) {
+ chip->ident = V4L2_IDENT_SAA7146;
return 0;
}
-#endif
- default:
- return v4l_compat_translate_ioctl(file, cmd, arg,
- saa7146_video_do_ioctl);
- }
+ return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
+ core, g_chip_ident, chip);
+}
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf)
+{
+ struct saa7146_fh *fh = __fh;
+ struct videobuf_queue *q = &fh->video_q;
+ int err, i;
+
+ /* fixme: number of capture buffers and sizes for v4l apps */
+ int gbuffers = 2;
+ int gbufsize = 768 * 576 * 4;
+
+ DEB_D(("VIDIOCGMBUF \n"));
+
+ q = &fh->video_q;
+ err = videobuf_mmap_setup(q, gbuffers, gbufsize,
+ V4L2_MEMORY_MMAP);
+ if (err < 0)
+ return err;
+
+ gbuffers = err;
+ memset(mbuf, 0, sizeof(*mbuf));
+ mbuf->frames = gbuffers;
+ mbuf->size = gbuffers * gbufsize;
+ for (i = 0; i < gbuffers; i++)
+ mbuf->offsets[i] = i * gbufsize;
return 0;
}
+#endif
+
+const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+ .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
+ .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
+ .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
+ .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
+ .vidioc_g_chip_ident = vidioc_g_chip_ident,
+
+ .vidioc_overlay = vidioc_overlay,
+ .vidioc_g_fbuf = vidioc_g_fbuf,
+ .vidioc_s_fbuf = vidioc_s_fbuf,
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+ .vidioc_g_std = vidioc_g_std,
+ .vidioc_s_std = vidioc_s_std,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+ .vidioc_g_parm = vidioc_g_parm,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ .vidiocgmbuf = vidiocgmbuf,
+#endif
+};
/*********************************************************************************/
/* buffer handling functions */
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 6f92beaa5ac8..607d319ce8ed 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -21,16 +21,17 @@ config MEDIA_TUNER
tristate
default VIDEO_MEDIA && I2C
depends on VIDEO_MEDIA && I2C
- select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMIZE
-
-menuconfig MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
+
+menuconfig MEDIA_TUNER_CUSTOMISE
bool "Customize analog and hybrid tuner modules to build"
depends on MEDIA_TUNER
default n
@@ -43,13 +44,13 @@ menuconfig MEDIA_TUNER_CUSTOMIZE
If unsure say N.
-if MEDIA_TUNER_CUSTOMIZE
+if MEDIA_TUNER_CUSTOMISE
config MEDIA_TUNER_SIMPLE
tristate "Simple tuner support"
depends on VIDEO_MEDIA && I2C
select MEDIA_TUNER_TDA9887
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for various simple tuners.
@@ -58,28 +59,28 @@ config MEDIA_TUNER_TDA8290
depends on VIDEO_MEDIA && I2C
select MEDIA_TUNER_TDA827X
select MEDIA_TUNER_TDA18271
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for Philips TDA8290+8275(a) tuner.
config MEDIA_TUNER_TDA827X
tristate "Philips TDA827X silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A DVB-T silicon tuner module. Say Y when you want to support this tuner.
config MEDIA_TUNER_TDA18271
tristate "NXP TDA18271 silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A silicon tuner module. Say Y when you want to support this tuner.
config MEDIA_TUNER_TDA9887
tristate "TDA 9885/6/7 analog IF demodulator"
depends on VIDEO_MEDIA && I2C
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for Philips TDA9885/6/7
analog IF demodulator.
@@ -88,80 +89,87 @@ config MEDIA_TUNER_TEA5761
tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
depends on VIDEO_MEDIA && I2C
depends on EXPERIMENTAL
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for the Philips TEA5761 radio tuner.
config MEDIA_TUNER_TEA5767
tristate "TEA 5767 radio tuner"
depends on VIDEO_MEDIA && I2C
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for the Philips TEA5767 radio tuner.
config MEDIA_TUNER_MT20XX
tristate "Microtune 2032 / 2050 tuners"
depends on VIDEO_MEDIA && I2C
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for the MT2032 / MT2050 tuner.
config MEDIA_TUNER_MT2060
tristate "Microtune MT2060 silicon IF tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon IF tuner MT2060 from Microtune.
config MEDIA_TUNER_MT2266
tristate "Microtune MT2266 silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon baseband tuner MT2266 from Microtune.
config MEDIA_TUNER_MT2131
tristate "Microtune MT2131 silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon baseband tuner MT2131 from Microtune.
config MEDIA_TUNER_QT1010
tristate "Quantek QT1010 silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon tuner QT1010 from Quantek.
config MEDIA_TUNER_XC2028
tristate "XCeive xc2028/xc3028 tuners"
depends on VIDEO_MEDIA && I2C
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for the xc2028/xc3028 tuners.
config MEDIA_TUNER_XC5000
tristate "Xceive XC5000 silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon tuner XC5000 from Xceive.
- This device is only used inside a SiP called togther with a
+ This device is only used inside a SiP called together with a
demodulator for now.
config MEDIA_TUNER_MXL5005S
tristate "MaxLinear MSL5005S silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon tuner MXL5005S from MaxLinear.
config MEDIA_TUNER_MXL5007T
tristate "MaxLinear MxL5007T silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon tuner MxL5007T from MaxLinear.
-endif # MEDIA_TUNER_CUSTOMIZE
+config MEDIA_TUNER_MC44S803
+ tristate "Freescale MC44S803 Low Power CMOS Broadband tuners"
+ depends on VIDEO_MEDIA && I2C
+ default m if MEDIA_TUNER_CUSTOMISE
+ help
+ Say Y here to support the Freescale MC44S803 based tuners
+
+endif # MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 4dfbe5b8264f..4132b2be79e5 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
+obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/mc44s803.c b/drivers/media/common/tuners/mc44s803.c
new file mode 100644
index 000000000000..20c4485ce16a
--- /dev/null
+++ b/drivers/media/common/tuners/mc44s803.c
@@ -0,0 +1,371 @@
+/*
+ * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "mc44s803.h"
+#include "mc44s803_priv.h"
+
+#define mc_printk(level, format, arg...) \
+ printk(level "mc44s803: " format , ## arg)
+
+/* Writes a single register */
+static int mc44s803_writereg(struct mc44s803_priv *priv, u32 val)
+{
+ u8 buf[3];
+ struct i2c_msg msg = {
+ .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 3
+ };
+
+ buf[0] = (val & 0xff0000) >> 16;
+ buf[1] = (val & 0xff00) >> 8;
+ buf[2] = (val & 0xff);
+
+ if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+ mc_printk(KERN_WARNING, "I2C write failed\n");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+/* Reads a single register */
+static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val)
+{
+ u32 wval;
+ u8 buf[3];
+ int ret;
+ struct i2c_msg msg[] = {
+ { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
+ .buf = buf, .len = 3 },
+ };
+
+ wval = MC44S803_REG_SM(MC44S803_REG_DATAREG, MC44S803_ADDR) |
+ MC44S803_REG_SM(reg, MC44S803_D);
+
+ ret = mc44s803_writereg(priv, wval);
+ if (ret)
+ return ret;
+
+ if (i2c_transfer(priv->i2c, msg, 1) != 1) {
+ mc_printk(KERN_WARNING, "I2C read failed\n");
+ return -EREMOTEIO;
+ }
+
+ *val = (buf[0] << 16) | (buf[1] << 8) | buf[2];
+
+ return 0;
+}
+
+static int mc44s803_release(struct dvb_frontend *fe)
+{
+ struct mc44s803_priv *priv = fe->tuner_priv;
+
+ fe->tuner_priv = NULL;
+ kfree(priv);
+
+ return 0;
+}
+
+static int mc44s803_init(struct dvb_frontend *fe)
+{
+ struct mc44s803_priv *priv = fe->tuner_priv;
+ u32 val;
+ int err;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+/* Reset chip */
+ val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_RS);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+/* Power Up and Start Osc */
+
+ val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
+ MC44S803_REG_SM(0xC0, MC44S803_REFOSC) |
+ MC44S803_REG_SM(1, MC44S803_OSCSEL);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_POWER, MC44S803_ADDR) |
+ MC44S803_REG_SM(0x200, MC44S803_POWER);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ msleep(10);
+
+ val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
+ MC44S803_REG_SM(0x40, MC44S803_REFOSC) |
+ MC44S803_REG_SM(1, MC44S803_OSCSEL);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ msleep(20);
+
+/* Setup Mixer */
+
+ val = MC44S803_REG_SM(MC44S803_REG_MIXER, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_TRI_STATE) |
+ MC44S803_REG_SM(0x7F, MC44S803_MIXER_RES);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+/* Setup Cirquit Adjust */
+
+ val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_G1) |
+ MC44S803_REG_SM(1, MC44S803_G3) |
+ MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
+ MC44S803_REG_SM(1, MC44S803_G6) |
+ MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
+ MC44S803_REG_SM(0x3, MC44S803_LP) |
+ MC44S803_REG_SM(1, MC44S803_CLRF) |
+ MC44S803_REG_SM(1, MC44S803_CLIF);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_G1) |
+ MC44S803_REG_SM(1, MC44S803_G3) |
+ MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
+ MC44S803_REG_SM(1, MC44S803_G6) |
+ MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
+ MC44S803_REG_SM(0x3, MC44S803_LP);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+/* Setup Digtune */
+
+ val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+ MC44S803_REG_SM(3, MC44S803_XOD);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+/* Setup AGC */
+
+ val = MC44S803_REG_SM(MC44S803_REG_LNAAGC, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_AT1) |
+ MC44S803_REG_SM(1, MC44S803_AT2) |
+ MC44S803_REG_SM(1, MC44S803_AGC_AN_DIG) |
+ MC44S803_REG_SM(1, MC44S803_AGC_READ_EN) |
+ MC44S803_REG_SM(1, MC44S803_LNA0);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ return 0;
+
+exit:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ mc_printk(KERN_WARNING, "I/O Error\n");
+ return err;
+}
+
+static int mc44s803_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct mc44s803_priv *priv = fe->tuner_priv;
+ u32 r1, r2, n1, n2, lo1, lo2, freq, val;
+ int err;
+
+ priv->frequency = params->frequency;
+
+ r1 = MC44S803_OSC / 1000000;
+ r2 = MC44S803_OSC / 100000;
+
+ n1 = (params->frequency + MC44S803_IF1 + 500000) / 1000000;
+ freq = MC44S803_OSC / r1 * n1;
+ lo1 = ((60 * n1) + (r1 / 2)) / r1;
+ freq = freq - params->frequency;
+
+ n2 = (freq - MC44S803_IF2 + 50000) / 100000;
+ lo2 = ((60 * n2) + (r2 / 2)) / r2;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ val = MC44S803_REG_SM(MC44S803_REG_REFDIV, MC44S803_ADDR) |
+ MC44S803_REG_SM(r1-1, MC44S803_R1) |
+ MC44S803_REG_SM(r2-1, MC44S803_R2) |
+ MC44S803_REG_SM(1, MC44S803_REFBUF_EN);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_LO1, MC44S803_ADDR) |
+ MC44S803_REG_SM(n1-2, MC44S803_LO1);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_LO2, MC44S803_ADDR) |
+ MC44S803_REG_SM(n2-2, MC44S803_LO2);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_DA) |
+ MC44S803_REG_SM(lo1, MC44S803_LO_REF) |
+ MC44S803_REG_SM(1, MC44S803_AT);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+ MC44S803_REG_SM(2, MC44S803_DA) |
+ MC44S803_REG_SM(lo2, MC44S803_LO_REF) |
+ MC44S803_REG_SM(1, MC44S803_AT);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return 0;
+
+exit:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ mc_printk(KERN_WARNING, "I/O Error\n");
+ return err;
+}
+
+static int mc44s803_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct mc44s803_priv *priv = fe->tuner_priv;
+ *frequency = priv->frequency;
+ return 0;
+}
+
+static const struct dvb_tuner_ops mc44s803_tuner_ops = {
+ .info = {
+ .name = "Freescale MC44S803",
+ .frequency_min = 48000000,
+ .frequency_max = 1000000000,
+ .frequency_step = 100000,
+ },
+
+ .release = mc44s803_release,
+ .init = mc44s803_init,
+ .set_params = mc44s803_set_params,
+ .get_frequency = mc44s803_get_frequency
+};
+
+/* This functions tries to identify a MC44S803 tuner by reading the ID
+ register. This is hasty. */
+struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, struct mc44s803_config *cfg)
+{
+ struct mc44s803_priv *priv;
+ u32 reg;
+ u8 id;
+ int ret;
+
+ reg = 0;
+
+ priv = kzalloc(sizeof(struct mc44s803_priv), GFP_KERNEL);
+ if (priv == NULL)
+ return NULL;
+
+ priv->cfg = cfg;
+ priv->i2c = i2c;
+ priv->fe = fe;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = mc44s803_readreg(priv, MC44S803_REG_ID, &reg);
+ if (ret)
+ goto error;
+
+ id = MC44S803_REG_MS(reg, MC44S803_ID);
+
+ if (id != 0x14) {
+ mc_printk(KERN_ERR, "unsupported ID "
+ "(%x should be 0x14)\n", id);
+ goto error;
+ }
+
+ mc_printk(KERN_INFO, "successfully identified (ID = %x)\n", id);
+ memcpy(&fe->ops.tuner_ops, &mc44s803_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+
+ fe->tuner_priv = priv;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ return fe;
+
+error:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ kfree(priv);
+ return NULL;
+}
+EXPORT_SYMBOL(mc44s803_attach);
+
+MODULE_AUTHOR("Jochen Friedrich");
+MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/mc44s803.h b/drivers/media/common/tuners/mc44s803.h
new file mode 100644
index 000000000000..34f3892d3f6d
--- /dev/null
+++ b/drivers/media/common/tuners/mc44s803.h
@@ -0,0 +1,46 @@
+/*
+ * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef MC44S803_H
+#define MC44S803_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mc44s803_config {
+ u8 i2c_address;
+ u8 dig_out;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MC44S803) || \
+ (defined(CONFIG_MEDIA_TUNER_MC44S803_MODULE) && defined(MODULE))
+extern struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, struct mc44s803_config *cfg);
+#else
+static inline struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, struct mc44s803_config *cfg)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_MEDIA_TUNER_MC44S803 */
+
+#endif
diff --git a/drivers/media/common/tuners/mc44s803_priv.h b/drivers/media/common/tuners/mc44s803_priv.h
new file mode 100644
index 000000000000..14a92780906d
--- /dev/null
+++ b/drivers/media/common/tuners/mc44s803_priv.h
@@ -0,0 +1,208 @@
+/*
+ * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef MC44S803_PRIV_H
+#define MC44S803_PRIV_H
+
+/* This driver is based on the information available in the datasheet
+ http://www.freescale.com/files/rf_if/doc/data_sheet/MC44S803.pdf
+
+ SPI or I2C Address : 0xc0-0xc6
+
+ Reg.No | Function
+ -------------------------------------------
+ 00 | Power Down
+ 01 | Reference Oszillator
+ 02 | Reference Dividers
+ 03 | Mixer and Reference Buffer
+ 04 | Reset/Serial Out
+ 05 | LO 1
+ 06 | LO 2
+ 07 | Circuit Adjust
+ 08 | Test
+ 09 | Digital Tune
+ 0A | LNA AGC
+ 0B | Data Register Address
+ 0C | Regulator Test
+ 0D | VCO Test
+ 0E | LNA Gain/Input Power
+ 0F | ID Bits
+
+*/
+
+#define MC44S803_OSC 26000000 /* 26 MHz */
+#define MC44S803_IF1 1086000000 /* 1086 MHz */
+#define MC44S803_IF2 36125000 /* 36.125 MHz */
+
+#define MC44S803_REG_POWER 0
+#define MC44S803_REG_REFOSC 1
+#define MC44S803_REG_REFDIV 2
+#define MC44S803_REG_MIXER 3
+#define MC44S803_REG_RESET 4
+#define MC44S803_REG_LO1 5
+#define MC44S803_REG_LO2 6
+#define MC44S803_REG_CIRCADJ 7
+#define MC44S803_REG_TEST 8
+#define MC44S803_REG_DIGTUNE 9
+#define MC44S803_REG_LNAAGC 0x0A
+#define MC44S803_REG_DATAREG 0x0B
+#define MC44S803_REG_REGTEST 0x0C
+#define MC44S803_REG_VCOTEST 0x0D
+#define MC44S803_REG_LNAGAIN 0x0E
+#define MC44S803_REG_ID 0x0F
+
+/* Register definitions */
+#define MC44S803_ADDR 0x0F
+#define MC44S803_ADDR_S 0
+/* REG_POWER */
+#define MC44S803_POWER 0xFFFFF0
+#define MC44S803_POWER_S 4
+/* REG_REFOSC */
+#define MC44S803_REFOSC 0x1FF0
+#define MC44S803_REFOSC_S 4
+#define MC44S803_OSCSEL 0x2000
+#define MC44S803_OSCSEL_S 13
+/* REG_REFDIV */
+#define MC44S803_R2 0x1FF0
+#define MC44S803_R2_S 4
+#define MC44S803_REFBUF_EN 0x2000
+#define MC44S803_REFBUF_EN_S 13
+#define MC44S803_R1 0x7C000
+#define MC44S803_R1_S 14
+/* REG_MIXER */
+#define MC44S803_R3 0x70
+#define MC44S803_R3_S 4
+#define MC44S803_MUX3 0x80
+#define MC44S803_MUX3_S 7
+#define MC44S803_MUX4 0x100
+#define MC44S803_MUX4_S 8
+#define MC44S803_OSC_SCR 0x200
+#define MC44S803_OSC_SCR_S 9
+#define MC44S803_TRI_STATE 0x400
+#define MC44S803_TRI_STATE_S 10
+#define MC44S803_BUF_GAIN 0x800
+#define MC44S803_BUF_GAIN_S 11
+#define MC44S803_BUF_IO 0x1000
+#define MC44S803_BUF_IO_S 12
+#define MC44S803_MIXER_RES 0xFE000
+#define MC44S803_MIXER_RES_S 13
+/* REG_RESET */
+#define MC44S803_RS 0x10
+#define MC44S803_RS_S 4
+#define MC44S803_SO 0x20
+#define MC44S803_SO_S 5
+/* REG_LO1 */
+#define MC44S803_LO1 0xFFF0
+#define MC44S803_LO1_S 4
+/* REG_LO2 */
+#define MC44S803_LO2 0x7FFF0
+#define MC44S803_LO2_S 4
+/* REG_CIRCADJ */
+#define MC44S803_G1 0x20
+#define MC44S803_G1_S 5
+#define MC44S803_G3 0x80
+#define MC44S803_G3_S 7
+#define MC44S803_CIRCADJ_RES 0x300
+#define MC44S803_CIRCADJ_RES_S 8
+#define MC44S803_G6 0x400
+#define MC44S803_G6_S 10
+#define MC44S803_G7 0x800
+#define MC44S803_G7_S 11
+#define MC44S803_S1 0x1000
+#define MC44S803_S1_S 12
+#define MC44S803_LP 0x7E000
+#define MC44S803_LP_S 13
+#define MC44S803_CLRF 0x80000
+#define MC44S803_CLRF_S 19
+#define MC44S803_CLIF 0x100000
+#define MC44S803_CLIF_S 20
+/* REG_TEST */
+/* REG_DIGTUNE */
+#define MC44S803_DA 0xF0
+#define MC44S803_DA_S 4
+#define MC44S803_XOD 0x300
+#define MC44S803_XOD_S 8
+#define MC44S803_RST 0x10000
+#define MC44S803_RST_S 16
+#define MC44S803_LO_REF 0x1FFF00
+#define MC44S803_LO_REF_S 8
+#define MC44S803_AT 0x200000
+#define MC44S803_AT_S 21
+#define MC44S803_MT 0x400000
+#define MC44S803_MT_S 22
+/* REG_LNAAGC */
+#define MC44S803_G 0x3F0
+#define MC44S803_G_S 4
+#define MC44S803_AT1 0x400
+#define MC44S803_AT1_S 10
+#define MC44S803_AT2 0x800
+#define MC44S803_AT2_S 11
+#define MC44S803_HL_GR_EN 0x8000
+#define MC44S803_HL_GR_EN_S 15
+#define MC44S803_AGC_AN_DIG 0x10000
+#define MC44S803_AGC_AN_DIG_S 16
+#define MC44S803_ATTEN_EN 0x20000
+#define MC44S803_ATTEN_EN_S 17
+#define MC44S803_AGC_READ_EN 0x40000
+#define MC44S803_AGC_READ_EN_S 18
+#define MC44S803_LNA0 0x80000
+#define MC44S803_LNA0_S 19
+#define MC44S803_AGC_SEL 0x100000
+#define MC44S803_AGC_SEL_S 20
+#define MC44S803_AT0 0x200000
+#define MC44S803_AT0_S 21
+#define MC44S803_B 0xC00000
+#define MC44S803_B_S 22
+/* REG_DATAREG */
+#define MC44S803_D 0xF0
+#define MC44S803_D_S 4
+/* REG_REGTEST */
+/* REG_VCOTEST */
+/* REG_LNAGAIN */
+#define MC44S803_IF_PWR 0x700
+#define MC44S803_IF_PWR_S 8
+#define MC44S803_RF_PWR 0x3800
+#define MC44S803_RF_PWR_S 11
+#define MC44S803_LNA_GAIN 0xFC000
+#define MC44S803_LNA_GAIN_S 14
+/* REG_ID */
+#define MC44S803_ID 0x3E00
+#define MC44S803_ID_S 9
+
+/* Some macros to read/write fields */
+
+/* First shift, then mask */
+#define MC44S803_REG_SM(_val, _reg) \
+ (((_val) << _reg##_S) & (_reg))
+
+/* First mask, then shift */
+#define MC44S803_REG_MS(_val, _reg) \
+ (((_val) & (_reg)) >> _reg##_S)
+
+struct mc44s803_priv {
+ struct mc44s803_config *cfg;
+ struct i2c_adapter *i2c;
+ struct dvb_frontend *fe;
+
+ u32 frequency;
+};
+
+#endif
diff --git a/drivers/media/common/tuners/mt2060.c b/drivers/media/common/tuners/mt2060.c
index 12206d75dd4e..c7abe3d8f90e 100644
--- a/drivers/media/common/tuners/mt2060.c
+++ b/drivers/media/common/tuners/mt2060.c
@@ -278,7 +278,7 @@ static void mt2060_calibrate(struct mt2060_priv *priv)
while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0)
msleep(20);
- if (i < 10) {
+ if (i <= 10) {
mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :)
dprintk("calibration was successful: %d", (int)priv->fmfreq);
} else
diff --git a/drivers/media/common/tuners/mt20xx.c b/drivers/media/common/tuners/mt20xx.c
index 35b763a16d53..44608ad4e2d2 100644
--- a/drivers/media/common/tuners/mt20xx.c
+++ b/drivers/media/common/tuners/mt20xx.c
@@ -6,7 +6,7 @@
*/
#include <linux/delay.h>
#include <linux/i2c.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include "tuner-i2c.h"
#include "mt20xx.h"
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
index 31522d2e318e..0803dab58fff 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -4003,12 +4003,11 @@ static int mxl5005s_set_params(struct dvb_frontend *fe,
/* Change tuner for new modulation type if reqd */
if (req_mode != state->current_mode) {
switch (req_mode) {
- case VSB_8:
- case QAM_64:
- case QAM_256:
- case QAM_AUTO:
+ case MXL_ATSC:
+ case MXL_QAM:
req_bw = MXL5005S_BANDWIDTH_6MHZ;
break;
+ case MXL_DVBT:
default:
/* Assume DVB-T */
switch (params->u.ofdm.bandwidth) {
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
index 3ec28945c26f..2d02698d4f4f 100644
--- a/drivers/media/common/tuners/mxl5007t.c
+++ b/drivers/media/common/tuners/mxl5007t.c
@@ -1,7 +1,7 @@
/*
* mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner
*
- * Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.org>
+ * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -66,22 +66,17 @@ MODULE_PARM_DESC(debug, "set debug level");
#define MHz 1000000
enum mxl5007t_mode {
- MxL_MODE_OTA_DVBT_ATSC = 0,
- MxL_MODE_OTA_NTSC_PAL_GH = 1,
- MxL_MODE_OTA_PAL_IB = 2,
- MxL_MODE_OTA_PAL_D_SECAM_KL = 3,
- MxL_MODE_OTA_ISDBT = 4,
- MxL_MODE_CABLE_DIGITAL = 0x10,
- MxL_MODE_CABLE_NTSC_PAL_GH = 0x11,
- MxL_MODE_CABLE_PAL_IB = 0x12,
- MxL_MODE_CABLE_PAL_D_SECAM_KL = 0x13,
- MxL_MODE_CABLE_SCTE40 = 0x14,
+ MxL_MODE_ISDBT = 0,
+ MxL_MODE_DVBT = 1,
+ MxL_MODE_ATSC = 2,
+ MxL_MODE_CABLE = 0x10,
};
enum mxl5007t_chip_version {
MxL_UNKNOWN_ID = 0x00,
MxL_5007_V1_F1 = 0x11,
MxL_5007_V1_F2 = 0x12,
+ MxL_5007_V4 = 0x14,
MxL_5007_V2_100_F1 = 0x21,
MxL_5007_V2_100_F2 = 0x22,
MxL_5007_V2_200_F1 = 0x23,
@@ -96,67 +91,61 @@ struct reg_pair_t {
/* ------------------------------------------------------------------------- */
static struct reg_pair_t init_tab[] = {
- { 0x0b, 0x44 }, /* XTAL */
- { 0x0c, 0x60 }, /* IF */
- { 0x10, 0x00 }, /* MISC */
- { 0x12, 0xca }, /* IDAC */
- { 0x16, 0x90 }, /* MODE */
- { 0x32, 0x38 }, /* MODE Analog/Digital */
- { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
- { 0x2c, 0x34 }, /* OVERRIDE */
- { 0x4d, 0x40 }, /* OVERRIDE */
- { 0x7f, 0x02 }, /* OVERRIDE */
- { 0x9a, 0x52 }, /* OVERRIDE */
- { 0x48, 0x5a }, /* OVERRIDE */
- { 0x76, 0x1a }, /* OVERRIDE */
- { 0x6a, 0x48 }, /* OVERRIDE */
- { 0x64, 0x28 }, /* OVERRIDE */
- { 0x66, 0xe6 }, /* OVERRIDE */
- { 0x35, 0x0e }, /* OVERRIDE */
- { 0x7e, 0x01 }, /* OVERRIDE */
- { 0x83, 0x00 }, /* OVERRIDE */
- { 0x04, 0x0b }, /* OVERRIDE */
- { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
+ { 0x02, 0x06 },
+ { 0x03, 0x48 },
+ { 0x05, 0x04 },
+ { 0x06, 0x10 },
+ { 0x2e, 0x15 }, /* OVERRIDE */
+ { 0x30, 0x10 }, /* OVERRIDE */
+ { 0x45, 0x58 }, /* OVERRIDE */
+ { 0x48, 0x19 }, /* OVERRIDE */
+ { 0x52, 0x03 }, /* OVERRIDE */
+ { 0x53, 0x44 }, /* OVERRIDE */
+ { 0x6a, 0x4b }, /* OVERRIDE */
+ { 0x76, 0x00 }, /* OVERRIDE */
+ { 0x78, 0x18 }, /* OVERRIDE */
+ { 0x7a, 0x17 }, /* OVERRIDE */
+ { 0x85, 0x06 }, /* OVERRIDE */
+ { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
{ 0, 0 }
};
static struct reg_pair_t init_tab_cable[] = {
- { 0x0b, 0x44 }, /* XTAL */
- { 0x0c, 0x60 }, /* IF */
- { 0x10, 0x00 }, /* MISC */
- { 0x12, 0xca }, /* IDAC */
- { 0x16, 0x90 }, /* MODE */
- { 0x32, 0x38 }, /* MODE A/D */
- { 0x71, 0x3f }, /* TOP1 */
- { 0x72, 0x3f }, /* TOP2 */
- { 0x74, 0x3f }, /* TOP3 */
- { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
- { 0x2c, 0x34 }, /* OVERRIDE */
- { 0x4d, 0x40 }, /* OVERRIDE */
- { 0x7f, 0x02 }, /* OVERRIDE */
- { 0x9a, 0x52 }, /* OVERRIDE */
- { 0x48, 0x5a }, /* OVERRIDE */
- { 0x76, 0x1a }, /* OVERRIDE */
- { 0x6a, 0x48 }, /* OVERRIDE */
- { 0x64, 0x28 }, /* OVERRIDE */
- { 0x66, 0xe6 }, /* OVERRIDE */
- { 0x35, 0x0e }, /* OVERRIDE */
- { 0x7e, 0x01 }, /* OVERRIDE */
- { 0x04, 0x0b }, /* OVERRIDE */
- { 0x68, 0xb4 }, /* OVERRIDE */
- { 0x36, 0x00 }, /* OVERRIDE */
- { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
+ { 0x02, 0x06 },
+ { 0x03, 0x48 },
+ { 0x05, 0x04 },
+ { 0x06, 0x10 },
+ { 0x09, 0x3f },
+ { 0x0a, 0x3f },
+ { 0x0b, 0x3f },
+ { 0x2e, 0x15 }, /* OVERRIDE */
+ { 0x30, 0x10 }, /* OVERRIDE */
+ { 0x45, 0x58 }, /* OVERRIDE */
+ { 0x48, 0x19 }, /* OVERRIDE */
+ { 0x52, 0x03 }, /* OVERRIDE */
+ { 0x53, 0x44 }, /* OVERRIDE */
+ { 0x6a, 0x4b }, /* OVERRIDE */
+ { 0x76, 0x00 }, /* OVERRIDE */
+ { 0x78, 0x18 }, /* OVERRIDE */
+ { 0x7a, 0x17 }, /* OVERRIDE */
+ { 0x85, 0x06 }, /* OVERRIDE */
+ { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
{ 0, 0 }
};
/* ------------------------------------------------------------------------- */
static struct reg_pair_t reg_pair_rftune[] = {
- { 0x11, 0x00 }, /* abort tune */
- { 0x13, 0x15 },
- { 0x14, 0x40 },
- { 0x15, 0x0e },
- { 0x11, 0x02 }, /* start tune */
+ { 0x0f, 0x00 }, /* abort tune */
+ { 0x0c, 0x15 },
+ { 0x0d, 0x40 },
+ { 0x0e, 0x0e },
+ { 0x1f, 0x87 }, /* OVERRIDE */
+ { 0x20, 0x1f }, /* OVERRIDE */
+ { 0x21, 0x87 }, /* OVERRIDE */
+ { 0x22, 0x1f }, /* OVERRIDE */
+ { 0x80, 0x01 }, /* freq dependent */
+ { 0x0f, 0x01 }, /* start tune */
{ 0, 0 }
};
@@ -227,63 +216,20 @@ static void mxl5007t_set_mode_bits(struct mxl5007t_state *state,
s32 if_diff_out_level)
{
switch (mode) {
- case MxL_MODE_OTA_DVBT_ATSC:
- set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
- set_reg_bits(state->tab_init, 0x35, 0xff, 0x0e);
+ case MxL_MODE_ATSC:
+ set_reg_bits(state->tab_init, 0x06, 0x1f, 0x12);
break;
- case MxL_MODE_OTA_ISDBT:
- set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
- set_reg_bits(state->tab_init, 0x35, 0xff, 0x12);
+ case MxL_MODE_DVBT:
+ set_reg_bits(state->tab_init, 0x06, 0x1f, 0x11);
break;
- case MxL_MODE_OTA_NTSC_PAL_GH:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+ case MxL_MODE_ISDBT:
+ set_reg_bits(state->tab_init, 0x06, 0x1f, 0x10);
break;
- case MxL_MODE_OTA_PAL_IB:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- break;
- case MxL_MODE_OTA_PAL_D_SECAM_KL:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- break;
- case MxL_MODE_CABLE_DIGITAL:
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
- 8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
- break;
- case MxL_MODE_CABLE_NTSC_PAL_GH:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
- 8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
- break;
- case MxL_MODE_CABLE_PAL_IB:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+ case MxL_MODE_CABLE:
+ set_reg_bits(state->tab_init_cable, 0x09, 0xff, 0xc1);
+ set_reg_bits(state->tab_init_cable, 0x0a, 0xff,
8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
- break;
- case MxL_MODE_CABLE_PAL_D_SECAM_KL:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
- 8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
- break;
- case MxL_MODE_CABLE_SCTE40:
- set_reg_bits(state->tab_init_cable, 0x36, 0xff, 0x08);
- set_reg_bits(state->tab_init_cable, 0x68, 0xff, 0xbc);
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
- 8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+ set_reg_bits(state->tab_init_cable, 0x0b, 0xff, 0x17);
break;
default:
mxl_fail(-EINVAL);
@@ -302,43 +248,43 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
val = 0x00;
break;
case MxL_IF_4_5_MHZ:
- val = 0x20;
+ val = 0x02;
break;
case MxL_IF_4_57_MHZ:
- val = 0x30;
+ val = 0x03;
break;
case MxL_IF_5_MHZ:
- val = 0x40;
+ val = 0x04;
break;
case MxL_IF_5_38_MHZ:
- val = 0x50;
+ val = 0x05;
break;
case MxL_IF_6_MHZ:
- val = 0x60;
+ val = 0x06;
break;
case MxL_IF_6_28_MHZ:
- val = 0x70;
+ val = 0x07;
break;
case MxL_IF_9_1915_MHZ:
- val = 0x80;
+ val = 0x08;
break;
case MxL_IF_35_25_MHZ:
- val = 0x90;
+ val = 0x09;
break;
case MxL_IF_36_15_MHZ:
- val = 0xa0;
+ val = 0x0a;
break;
case MxL_IF_44_MHZ:
- val = 0xb0;
+ val = 0x0b;
break;
default:
mxl_fail(-EINVAL);
return;
}
- set_reg_bits(state->tab_init, 0x0c, 0xf0, val);
+ set_reg_bits(state->tab_init, 0x02, 0x0f, val);
/* set inverted IF or normal IF */
- set_reg_bits(state->tab_init, 0x0c, 0x08, invert_if ? 0x08 : 0x00);
+ set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00);
return;
}
@@ -346,56 +292,68 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state,
enum mxl5007t_xtal_freq xtal_freq)
{
- u8 val;
-
switch (xtal_freq) {
case MxL_XTAL_16_MHZ:
- val = 0x00; /* select xtal freq & Ref Freq */
+ /* select xtal freq & ref freq */
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x00);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x00);
break;
case MxL_XTAL_20_MHZ:
- val = 0x11;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x10);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x01);
break;
case MxL_XTAL_20_25_MHZ:
- val = 0x22;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x20);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x02);
break;
case MxL_XTAL_20_48_MHZ:
- val = 0x33;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x30);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x03);
break;
case MxL_XTAL_24_MHZ:
- val = 0x44;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x40);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x04);
break;
case MxL_XTAL_25_MHZ:
- val = 0x55;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x50);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x05);
break;
case MxL_XTAL_25_14_MHZ:
- val = 0x66;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x60);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x06);
break;
case MxL_XTAL_27_MHZ:
- val = 0x77;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x70);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x07);
break;
case MxL_XTAL_28_8_MHZ:
- val = 0x88;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x80);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x08);
break;
case MxL_XTAL_32_MHZ:
- val = 0x99;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x90);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x09);
break;
case MxL_XTAL_40_MHZ:
- val = 0xaa;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0xa0);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0a);
break;
case MxL_XTAL_44_MHZ:
- val = 0xbb;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0xb0);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0b);
break;
case MxL_XTAL_48_MHZ:
- val = 0xcc;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0xc0);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0c);
break;
case MxL_XTAL_49_3811_MHZ:
- val = 0xdd;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0xd0);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0d);
break;
default:
mxl_fail(-EINVAL);
return;
}
- set_reg_bits(state->tab_init, 0x0b, 0xff, val);
return;
}
@@ -412,16 +370,11 @@ static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state,
mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if);
mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz);
- set_reg_bits(state->tab_init, 0x10, 0x40, cfg->loop_thru_enable << 6);
-
- set_reg_bits(state->tab_init, 0xd8, 0x08, cfg->clk_out_enable << 3);
-
- set_reg_bits(state->tab_init, 0x10, 0x07, cfg->clk_out_amp);
+ set_reg_bits(state->tab_init, 0x04, 0x01, cfg->loop_thru_enable);
+ set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3);
+ set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp);
- /* set IDAC to automatic mode control by AGC */
- set_reg_bits(state->tab_init, 0x12, 0x80, 0x00);
-
- if (mode >= MxL_MODE_CABLE_DIGITAL) {
+ if (mode >= MxL_MODE_CABLE) {
copy_reg_bits(state->tab_init, state->tab_init_cable);
return state->tab_init_cable;
} else
@@ -447,7 +400,7 @@ static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
* and DIG_MODEINDEX_CSF */
break;
case MxL_BW_7MHz:
- val = 0x21;
+ val = 0x2a;
break;
case MxL_BW_8MHz:
val = 0x3f;
@@ -456,7 +409,7 @@ static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
mxl_fail(-EINVAL);
return;
}
- set_reg_bits(state->tab_rftune, 0x13, 0x3f, val);
+ set_reg_bits(state->tab_rftune, 0x0c, 0x3f, val);
return;
}
@@ -493,8 +446,11 @@ reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state,
if (temp > 7812)
dig_rf_freq++;
- set_reg_bits(state->tab_rftune, 0x14, 0xff, (u8)dig_rf_freq);
- set_reg_bits(state->tab_rftune, 0x15, 0xff, (u8)(dig_rf_freq >> 8));
+ set_reg_bits(state->tab_rftune, 0x0d, 0xff, (u8) dig_rf_freq);
+ set_reg_bits(state->tab_rftune, 0x0e, 0xff, (u8) (dig_rf_freq >> 8));
+
+ if (rf_freq >= 333000000)
+ set_reg_bits(state->tab_rftune, 0x80, 0x40, 0x40);
return state->tab_rftune;
}
@@ -551,9 +507,10 @@ static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val)
static int mxl5007t_soft_reset(struct mxl5007t_state *state)
{
u8 d = 0xff;
- struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
- .buf = &d, .len = 1 };
-
+ struct i2c_msg msg = {
+ .addr = state->i2c_props.addr, .flags = 0,
+ .buf = &d, .len = 1
+ };
int ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
if (ret != 1) {
@@ -580,9 +537,6 @@ static int mxl5007t_tuner_init(struct mxl5007t_state *state,
if (mxl_fail(ret))
goto fail;
mdelay(1);
-
- ret = mxl5007t_write_reg(state, 0x2c, 0x35);
- mxl_fail(ret);
fail:
return ret;
}
@@ -615,7 +569,7 @@ static int mxl5007t_synth_lock_status(struct mxl5007t_state *state,
*rf_locked = 0;
*ref_locked = 0;
- ret = mxl5007t_read_reg(state, 0xcf, &d);
+ ret = mxl5007t_read_reg(state, 0xd8, &d);
if (mxl_fail(ret))
goto fail;
@@ -628,37 +582,14 @@ fail:
return ret;
}
-static int mxl5007t_check_rf_input_power(struct mxl5007t_state *state,
- s32 *rf_input_level)
-{
- u8 d1, d2;
- int ret;
-
- ret = mxl5007t_read_reg(state, 0xb7, &d1);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl5007t_read_reg(state, 0xbf, &d2);
- if (mxl_fail(ret))
- goto fail;
-
- d2 = d2 >> 4;
- if (d2 > 7)
- d2 += 0xf0;
-
- *rf_input_level = (s32)(d1 + d2 - 113);
-fail:
- return ret;
-}
-
/* ------------------------------------------------------------------------- */
static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
{
struct mxl5007t_state *state = fe->tuner_priv;
- int rf_locked, ref_locked;
- s32 rf_input_level = 0;
- int ret;
+ int rf_locked, ref_locked, ret;
+
+ *status = 0;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@@ -669,10 +600,8 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
mxl_debug("%s%s", rf_locked ? "rf locked " : "",
ref_locked ? "ref locked" : "");
- ret = mxl5007t_check_rf_input_power(state, &rf_input_level);
- if (mxl_fail(ret))
- goto fail;
- mxl_debug("rf input power: %d", rf_input_level);
+ if ((rf_locked) || (ref_locked))
+ *status |= TUNER_STATUS_LOCKED;
fail:
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
@@ -695,11 +624,11 @@ static int mxl5007t_set_params(struct dvb_frontend *fe,
switch (params->u.vsb.modulation) {
case VSB_8:
case VSB_16:
- mode = MxL_MODE_OTA_DVBT_ATSC;
+ mode = MxL_MODE_ATSC;
break;
case QAM_64:
case QAM_256:
- mode = MxL_MODE_CABLE_DIGITAL;
+ mode = MxL_MODE_CABLE;
break;
default:
mxl_err("modulation not set!");
@@ -721,7 +650,7 @@ static int mxl5007t_set_params(struct dvb_frontend *fe,
mxl_err("bandwidth not set!");
return -EINVAL;
}
- mode = MxL_MODE_OTA_DVBT_ATSC;
+ mode = MxL_MODE_DVBT;
} else {
mxl_err("modulation type not supported!");
return -EINVAL;
@@ -752,96 +681,20 @@ fail:
return ret;
}
-static int mxl5007t_set_analog_params(struct dvb_frontend *fe,
- struct analog_parameters *params)
-{
- struct mxl5007t_state *state = fe->tuner_priv;
- enum mxl5007t_bw_mhz bw = 0; /* FIXME */
- enum mxl5007t_mode cbl_mode;
- enum mxl5007t_mode ota_mode;
- char *mode_name;
- int ret;
- u32 freq = params->frequency * 62500;
-
-#define cable 1
- if (params->std & V4L2_STD_MN) {
- cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
- ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
- mode_name = "MN";
- } else if (params->std & V4L2_STD_B) {
- cbl_mode = MxL_MODE_CABLE_PAL_IB;
- ota_mode = MxL_MODE_OTA_PAL_IB;
- mode_name = "B";
- } else if (params->std & V4L2_STD_GH) {
- cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
- ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
- mode_name = "GH";
- } else if (params->std & V4L2_STD_PAL_I) {
- cbl_mode = MxL_MODE_CABLE_PAL_IB;
- ota_mode = MxL_MODE_OTA_PAL_IB;
- mode_name = "I";
- } else if (params->std & V4L2_STD_DK) {
- cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
- ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
- mode_name = "DK";
- } else if (params->std & V4L2_STD_SECAM_L) {
- cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
- ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
- mode_name = "L";
- } else if (params->std & V4L2_STD_SECAM_LC) {
- cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
- ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
- mode_name = "L'";
- } else {
- mode_name = "xx";
- /* FIXME */
- cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
- ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
- }
- mxl_debug("setting mxl5007 to system %s", mode_name);
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
-
- mutex_lock(&state->lock);
-
- ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl5007t_tuner_rf_tune(state, freq, bw);
- if (mxl_fail(ret))
- goto fail;
-
- state->frequency = freq;
- state->bandwidth = 0;
-fail:
- mutex_unlock(&state->lock);
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 0);
-
- return ret;
-}
-
/* ------------------------------------------------------------------------- */
static int mxl5007t_init(struct dvb_frontend *fe)
{
struct mxl5007t_state *state = fe->tuner_priv;
int ret;
- u8 d;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- ret = mxl5007t_read_reg(state, 0x05, &d);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl5007t_write_reg(state, 0x05, d | 0x01);
+ /* wake from standby */
+ ret = mxl5007t_write_reg(state, 0x01, 0x01);
mxl_fail(ret);
-fail:
+
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
@@ -852,18 +705,16 @@ static int mxl5007t_sleep(struct dvb_frontend *fe)
{
struct mxl5007t_state *state = fe->tuner_priv;
int ret;
- u8 d;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- ret = mxl5007t_read_reg(state, 0x05, &d);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl5007t_write_reg(state, 0x05, d & ~0x01);
+ /* enter standby mode */
+ ret = mxl5007t_write_reg(state, 0x01, 0x00);
mxl_fail(ret);
-fail:
+ ret = mxl5007t_write_reg(state, 0x0f, 0x00);
+ mxl_fail(ret);
+
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
@@ -911,7 +762,6 @@ static struct dvb_tuner_ops mxl5007t_tuner_ops = {
.init = mxl5007t_init,
.sleep = mxl5007t_sleep,
.set_params = mxl5007t_set_params,
- .set_analog_params = mxl5007t_set_analog_params,
.get_status = mxl5007t_get_status,
.get_frequency = mxl5007t_get_frequency,
.get_bandwidth = mxl5007t_get_bandwidth,
@@ -924,7 +774,7 @@ static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
int ret;
u8 id;
- ret = mxl5007t_read_reg(state, 0xd3, &id);
+ ret = mxl5007t_read_reg(state, 0xd9, &id);
if (mxl_fail(ret))
goto fail;
@@ -947,8 +797,12 @@ static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
case MxL_5007_V2_200_F2:
name = "MxL5007.v2.200.f2";
break;
+ case MxL_5007_V4:
+ name = "MxL5007T.v4";
+ break;
default:
name = "MxL5007T";
+ printk(KERN_WARNING "%s: unknown rev (%02x)\n", __func__, id);
id = MxL_UNKNOWN_ID;
}
state->chip_id = id;
@@ -975,7 +829,7 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
mutex_lock(&mxl5007t_list_mutex);
instance = hybrid_tuner_request_state(struct mxl5007t_state, state,
hybrid_tuner_instance_list,
- i2c, addr, "mxl5007");
+ i2c, addr, "mxl5007t");
switch (instance) {
case 0:
goto fail;
@@ -1018,7 +872,7 @@ EXPORT_SYMBOL_GPL(mxl5007t_attach);
MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
MODULE_LICENSE("GPL");
-MODULE_VERSION("0.1");
+MODULE_VERSION("0.2");
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index 6fb5b4586569..fc76c30e24f1 100644
--- a/drivers/media/common/tuners/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
@@ -490,9 +490,9 @@ int tda18271_set_standby_mode(struct dvb_frontend *fe,
tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */
- regs[R_EP3] |= sm ? (1 << 7) : 0 |
- sm_lt ? (1 << 6) : 0 |
- sm_xt ? (1 << 5) : 0;
+ regs[R_EP3] |= (sm ? (1 << 7) : 0) |
+ (sm_lt ? (1 << 6) : 0) |
+ (sm_xt ? (1 << 5) : 0);
return tda18271_write_regs(fe, R_EP3, 1);
}
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index 1b48b5d0bf1e..b10935630154 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -818,6 +818,38 @@ fail:
return ret;
}
+/* ------------------------------------------------------------------ */
+
+static int tda18271_agc(struct dvb_frontend *fe)
+{
+ struct tda18271_priv *priv = fe->tuner_priv;
+ int ret = 0;
+
+ switch (priv->config) {
+ case 0:
+ /* no LNA */
+ tda_dbg("no agc configuration provided\n");
+ break;
+ case 3:
+ /* switch with GPIO of saa713x */
+ tda_dbg("invoking callback\n");
+ if (fe->callback)
+ ret = fe->callback(priv->i2c_props.adap->algo_data,
+ DVB_FRONTEND_COMPONENT_TUNER,
+ TDA18271_CALLBACK_CMD_AGC_ENABLE,
+ priv->mode);
+ break;
+ case 1:
+ case 2:
+ default:
+ /* n/a - currently not supported */
+ tda_err("unsupported configuration: %d\n", priv->config);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
static int tda18271_tune(struct dvb_frontend *fe,
struct tda18271_std_map_item *map, u32 freq, u32 bw)
{
@@ -827,6 +859,10 @@ static int tda18271_tune(struct dvb_frontend *fe,
tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n",
freq, map->if_freq, bw, map->agc_mode, map->std);
+ ret = tda18271_agc(fe);
+ if (tda_fail(ret))
+ tda_warn("failed to configure agc\n");
+
ret = tda18271_init(fe);
if (tda_fail(ret))
goto fail;
@@ -1159,6 +1195,7 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
/* new tuner instance */
priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
+ priv->config = (cfg) ? cfg->config : 0;
priv->cal_initialized = false;
mutex_init(&priv->lock);
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index 81a739365f8c..74beb28806f8 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
@@ -91,11 +91,6 @@ enum tda18271_pll {
TDA18271_CAL_PLL,
};
-enum tda18271_mode {
- TDA18271_ANALOG,
- TDA18271_DIGITAL,
-};
-
struct tda18271_map_layout;
enum tda18271_ver {
@@ -114,6 +109,7 @@ struct tda18271_priv {
enum tda18271_i2c_gate gate;
enum tda18271_ver id;
+ unsigned int config; /* interface to saa713x / tda829x */
unsigned int tm_rfcal;
unsigned int cal_initialized:1;
unsigned int small_i2c:1;
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h
index 7db9831c0cb0..53a9892a18d0 100644
--- a/drivers/media/common/tuners/tda18271.h
+++ b/drivers/media/common/tuners/tda18271.h
@@ -79,6 +79,16 @@ struct tda18271_config {
/* some i2c providers cant write all 39 registers at once */
unsigned int small_i2c:1;
+
+ /* interface to saa713x / tda829x */
+ unsigned int config;
+};
+
+#define TDA18271_CALLBACK_CMD_AGC_ENABLE 0
+
+enum tda18271_mode {
+ TDA18271_ANALOG = 0,
+ TDA18271_DIGITAL,
};
#if defined(CONFIG_MEDIA_TUNER_TDA18271) || (defined(CONFIG_MEDIA_TUNER_TDA18271_MODULE) && defined(MODULE))
diff --git a/drivers/media/common/tuners/tda827x.c b/drivers/media/common/tuners/tda827x.c
index f4d931f14fad..36a7bc7585ab 100644
--- a/drivers/media/common/tuners/tda827x.c
+++ b/drivers/media/common/tuners/tda827x.c
@@ -132,11 +132,31 @@ static const struct tda827x_data tda827x_table[] = {
{ .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
};
+static int tuner_transfer(struct dvb_frontend *fe,
+ struct i2c_msg *msg,
+ const int size)
+{
+ int rc;
+ struct tda827x_priv *priv = fe->tuner_priv;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ rc = i2c_transfer(priv->i2c_adap, msg, size);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ if (rc >= 0 && rc != size)
+ return -EIO;
+
+ return rc;
+}
+
static int tda827xo_set_params(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
struct tda827x_priv *priv = fe->tuner_priv;
u8 buf[14];
+ int rc;
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = buf, .len = sizeof(buf) };
@@ -183,27 +203,29 @@ static int tda827xo_set_params(struct dvb_frontend *fe,
buf[13] = 0x40;
msg.len = 14;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
- printk("%s: could not write to tuner at addr: 0x%02x\n",
- __func__, priv->i2c_addr << 1);
- return -EIO;
- }
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
+
msleep(500);
/* correct CP value */
buf[0] = 0x30;
buf[1] = 0x50 + tda827x_table[i].cp;
msg.len = 2;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
priv->frequency = params->frequency;
priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
return 0;
+
+err:
+ printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
+ __func__, priv->i2c_addr << 1);
+ return rc;
}
static int tda827xo_sleep(struct dvb_frontend *fe)
@@ -214,9 +236,7 @@ static int tda827xo_sleep(struct dvb_frontend *fe)
.buf = buf, .len = sizeof(buf) };
dprintk("%s:\n", __func__);
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
if (priv->cfg && priv->cfg->sleep)
priv->cfg->sleep(fe);
@@ -266,44 +286,44 @@ static int tda827xo_set_analog_params(struct dvb_frontend *fe,
msg.buf = tuner_reg;
msg.len = 8;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msg.buf = reg2;
msg.len = 2;
reg2[0] = 0x80;
reg2[1] = 0;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
reg2[0] = 0x60;
reg2[1] = 0xbf;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
reg2[0] = 0x30;
reg2[1] = tuner_reg[4] + 0x80;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msleep(1);
reg2[0] = 0x30;
reg2[1] = tuner_reg[4] + 4;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msleep(1);
reg2[0] = 0x30;
reg2[1] = tuner_reg[4];
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msleep(550);
reg2[0] = 0x30;
reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
reg2[0] = 0x60;
reg2[1] = 0x3f;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
reg2[0] = 0x80;
reg2[1] = 0x08; /* Vsync en */
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
priv->frequency = params->frequency;
@@ -317,7 +337,7 @@ static void tda827xo_agcf(struct dvb_frontend *fe)
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = data, .len = 2};
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
}
/* ------------------------------------------------------------------ */
@@ -331,7 +351,7 @@ struct tda827xa_data {
u8 gc3;
};
-static const struct tda827xa_data tda827xa_dvbt[] = {
+static struct tda827xa_data tda827xa_dvbt[] = {
{ .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
{ .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
{ .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
@@ -361,6 +381,36 @@ static const struct tda827xa_data tda827xa_dvbt[] = {
{ .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
};
+static struct tda827xa_data tda827xa_dvbc[] = {
+ { .lomax = 50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1},
+ { .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3},
+ { .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3},
+ { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1},
+ { .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
+ { .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
+ { .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1},
+ { .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
+ { .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1},
+ { .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+ { .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+ { .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+ { .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+ { .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+ { .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+ { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+ { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
+};
+
static struct tda827xa_data tda827xa_analog[] = {
{ .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
{ .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
@@ -398,13 +448,8 @@ static int tda827xa_sleep(struct dvb_frontend *fe)
.buf = buf, .len = sizeof(buf) };
dprintk("%s:\n", __func__);
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 0);
+ tuner_transfer(fe, &msg, 1);
if (priv->cfg && priv->cfg->sleep)
priv->cfg->sleep(fe);
@@ -455,7 +500,7 @@ static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
buf[1] = high ? 0 : 1;
if (priv->cfg->config == 2)
buf[1] = high ? 1 : 0;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
break;
case 3: /* switch with GPIO of saa713x */
if (fe->callback)
@@ -469,12 +514,13 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
struct tda827x_priv *priv = fe->tuner_priv;
+ struct tda827xa_data *frequency_map = tda827xa_dvbt;
u8 buf[11];
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = buf, .len = sizeof(buf) };
- int i, tuner_freq, if_freq;
+ int i, tuner_freq, if_freq, rc;
u32 N;
dprintk("%s:\n", __func__);
@@ -495,56 +541,58 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
}
tuner_freq = params->frequency + if_freq;
+ if (fe->ops.info.type == FE_QAM) {
+ dprintk("%s select tda827xa_dvbc\n", __func__);
+ frequency_map = tda827xa_dvbc;
+ }
+
i = 0;
- while (tda827xa_dvbt[i].lomax < tuner_freq) {
- if(tda827xa_dvbt[i + 1].lomax == 0)
+ while (frequency_map[i].lomax < tuner_freq) {
+ if (frequency_map[i + 1].lomax == 0)
break;
i++;
}
- N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd;
+ N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd;
buf[0] = 0; // subaddress
buf[1] = N >> 8;
buf[2] = N & 0xff;
buf[3] = 0;
buf[4] = 0x16;
- buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) +
- tda827xa_dvbt[i].sbs;
- buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4);
+ buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) +
+ frequency_map[i].sbs;
+ buf[6] = 0x4b + (frequency_map[i].gc3 << 4);
buf[7] = 0x1c;
buf[8] = 0x06;
buf[9] = 0x24;
buf[10] = 0x00;
msg.len = 11;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
- printk("%s: could not write to tuner at addr: 0x%02x\n",
- __func__, priv->i2c_addr << 1);
- return -EIO;
- }
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
+
buf[0] = 0x90;
buf[1] = 0xff;
buf[2] = 0x60;
buf[3] = 0x00;
buf[4] = 0x59; // lpsel, for 6MHz + 2
msg.len = 5;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
buf[0] = 0xa0;
buf[1] = 0x40;
msg.len = 2;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
msleep(11);
msg.flags = I2C_M_RD;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
msg.flags = 0;
buf[1] >>= 4;
@@ -553,49 +601,55 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
tda827xa_lna_gain(fe, 0, NULL);
buf[0] = 0x60;
buf[1] = 0x0c;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
}
buf[0] = 0xc0;
buf[1] = 0x99; // lpsel, for 6MHz + 2
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
buf[0] = 0x60;
buf[1] = 0x3c;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
/* correct CP value */
buf[0] = 0x30;
- buf[1] = 0x10 + tda827xa_dvbt[i].scr;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ buf[1] = 0x10 + frequency_map[i].scr;
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
msleep(163);
buf[0] = 0xc0;
buf[1] = 0x39; // lpsel, for 6MHz + 2
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
msleep(3);
/* freeze AGC1 */
buf[0] = 0x50;
- buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ buf[1] = 0x4f + (frequency_map[i].gc3 << 4);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
priv->frequency = params->frequency;
priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
+
return 0;
+
+err:
+ printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
+ __func__, priv->i2c_addr << 1);
+ return rc;
}
@@ -643,7 +697,7 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe,
tuner_reg[9] = 0x20;
tuner_reg[10] = 0x00;
msg.len = 11;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0x90;
tuner_reg[1] = 0xff;
@@ -651,19 +705,19 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe,
tuner_reg[3] = 0;
tuner_reg[4] = 0x99 + (priv->lpsel << 1);
msg.len = 5;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0xa0;
tuner_reg[1] = 0xc0;
msg.len = 2;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0x30;
tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msg.flags = I2C_M_RD;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msg.flags = 0;
tuner_reg[1] >>= 4;
dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
@@ -673,24 +727,24 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe,
msleep(100);
tuner_reg[0] = 0x60;
tuner_reg[1] = 0x3c;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msleep(163);
tuner_reg[0] = 0x50;
tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0x80;
tuner_reg[1] = 0x28;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0xb0;
tuner_reg[1] = 0x01;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0xc0;
tuner_reg[1] = 0x19 + (priv->lpsel << 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
priv->frequency = params->frequency;
@@ -703,7 +757,7 @@ static void tda827xa_agcf(struct dvb_frontend *fe)
unsigned char data[] = {0x80, 0x2c};
struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
.buf = data, .len = 2};
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
}
/* ------------------------------------------------------------------ */
@@ -792,16 +846,19 @@ static struct dvb_tuner_ops tda827xa_tuner_ops = {
};
static int tda827x_probe_version(struct dvb_frontend *fe)
-{ u8 data;
+{
+ u8 data;
+ int rc;
struct tda827x_priv *priv = fe->tuner_priv;
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
.buf = &data, .len = 1 };
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
+
+ rc = tuner_transfer(fe, &msg, 1);
+
+ if (rc < 0) {
printk("%s: could not read from tuner at addr: 0x%02x\n",
__func__, msg.addr << 1);
- return -EIO;
+ return rc;
}
if ((data & 0x3c) == 0) {
dprintk("tda827x tuner found\n");
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c
index 4b8662edb7cb..064d14c8d7b2 100644
--- a/drivers/media/common/tuners/tda8290.c
+++ b/drivers/media/common/tuners/tda8290.c
@@ -22,7 +22,7 @@
#include <linux/i2c.h>
#include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include "tuner-i2c.h"
#include "tda8290.h"
#include "tda827x.h"
@@ -566,8 +566,11 @@ static int tda829x_find_tuner(struct dvb_frontend *fe)
u8 data;
struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 };
- if (NULL == analog_ops->i2c_gate_ctrl)
+ if (!analog_ops->i2c_gate_ctrl) {
+ printk(KERN_ERR "tda8290: no gate control were provided!\n");
+
return -EINVAL;
+ }
analog_ops->i2c_gate_ctrl(fe, 1);
@@ -615,11 +618,13 @@ static int tda829x_find_tuner(struct dvb_frontend *fe)
if (ret != 1) {
tuner_warn("tuner access failed!\n");
+ analog_ops->i2c_gate_ctrl(fe, 0);
return -EREMOTEIO;
}
if ((data == 0x83) || (data == 0x84)) {
priv->ver |= TDA18271;
+ tda829x_tda18271_config.config = priv->cfg.config;
dvb_attach(tda18271_attach, fe, priv->tda827x_addr,
priv->i2c_props.adap, &tda829x_tda18271_config);
} else {
diff --git a/drivers/media/common/tuners/tea5761.c b/drivers/media/common/tuners/tea5761.c
index b23dadeecd05..60ed872f3d44 100644
--- a/drivers/media/common/tuners/tea5761.c
+++ b/drivers/media/common/tuners/tea5761.c
@@ -9,7 +9,7 @@
#include <linux/i2c.h>
#include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/tuner.h>
#include "tuner-i2c.h"
#include "tea5761.h"
diff --git a/drivers/media/common/tuners/tea5767.c b/drivers/media/common/tuners/tea5767.c
index 1f5646334a8f..223a226d20a1 100644
--- a/drivers/media/common/tuners/tea5767.c
+++ b/drivers/media/common/tuners/tea5767.c
@@ -12,7 +12,7 @@
#include <linux/i2c.h>
#include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include "tuner-i2c.h"
#include "tea5767.h"
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 493ce93caf43..b54598550dc4 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -739,7 +739,10 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
__func__, params->frequency);
- priv->rf_mode = XC_RF_MODE_CABLE; /* Fix me: it could be air. */
+ /* Fix me: it could be air. */
+ priv->rf_mode = params->mode;
+ if (params->mode > XC_RF_MODE_CABLE)
+ priv->rf_mode = XC_RF_MODE_CABLE;
/* params->frequency is in units of 62.5khz */
priv->freq_hz = params->frequency * 62500;
@@ -970,8 +973,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
case 1:
/* new tuner instance */
priv->bandwidth = BANDWIDTH_6_MHZ;
- priv->if_khz = cfg->if_khz;
-
fe->tuner_priv = priv;
break;
default:
@@ -980,6 +981,13 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
break;
}
+ if (priv->if_khz == 0) {
+ /* If the IF hasn't been set yet, use the value provided by
+ the caller (occurs in hybrid devices where the analog
+ call to xc5000_attach occurs before the digital side) */
+ priv->if_khz = cfg->if_khz;
+ }
+
/* Check if firmware has been loaded. It is possible that another
instance of the driver has loaded the firmware.
*/
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index a8c6249c4099..9e5781400744 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -13,7 +13,7 @@ config DVB_B2C2_FLEXCOP
select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE
select DVB_ISL6421 if !DVB_FE_CUSTOMISE
select DVB_CX24123 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
select DVB_TUNER_CX24113 if !DVB_FE_CUSTOMISE
help
Support for the digital TV receiver chip made by B2C2 Inc. included in
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
index d9db066f9854..b97cf7208a18 100644
--- a/drivers/media/dvb/b2c2/Makefile
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -2,7 +2,6 @@ b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
-
ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
b2c2-flexcop-objs += flexcop-dma.o
endif
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h
index 8ce06336e76f..3e1c472092ab 100644
--- a/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/drivers/media/dvb/b2c2/flexcop-common.h
@@ -28,11 +28,14 @@
/* Steal from usb.h */
#undef err
-#define err(format, arg...) printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
+#define err(format, arg...) \
+ printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
#undef info
-#define info(format, arg...) printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg)
+#define info(format, arg...) \
+ printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg)
#undef warn
-#define warn(format, arg...) printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
+#define warn(format, arg...) \
+ printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
struct flexcop_dma {
struct pci_dev *pdev;
@@ -91,16 +94,14 @@ struct flexcop_device {
int fullts_streaming_state;
/* bus specific callbacks */
- flexcop_ibi_value (*read_ibi_reg) (struct flexcop_device *, flexcop_ibi_register);
- int (*write_ibi_reg) (struct flexcop_device *, flexcop_ibi_register, flexcop_ibi_value);
-
-
- int (*i2c_request) (struct flexcop_i2c_adapter*,
+ flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *,
+ flexcop_ibi_register);
+ int (*write_ibi_reg) (struct flexcop_device *,
+ flexcop_ibi_register, flexcop_ibi_value);
+ int (*i2c_request) (struct flexcop_i2c_adapter *,
flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
- int (*stream_control) (struct flexcop_device*, int);
-
+ int (*stream_control) (struct flexcop_device *, int);
int (*get_mac_addr) (struct flexcop_device *fc, int extended);
-
void *bus_specific;
};
@@ -111,22 +112,28 @@ void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len);
void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no);
struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len);
-void flexcop_device_kfree(struct flexcop_device*);
+void flexcop_device_kfree(struct flexcop_device *);
-int flexcop_device_initialize(struct flexcop_device*);
+int flexcop_device_initialize(struct flexcop_device *);
void flexcop_device_exit(struct flexcop_device *fc);
-
void flexcop_reset_block_300(struct flexcop_device *fc);
/* from flexcop-dma.c */
-int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size);
+int flexcop_dma_allocate(struct pci_dev *pdev,
+ struct flexcop_dma *dma, u32 size);
void flexcop_dma_free(struct flexcop_dma *dma);
-int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
-int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
-int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx);
-int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff);
-int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles);
+int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
+ flexcop_dma_index_t no, int onoff);
+int flexcop_dma_control_size_irq(struct flexcop_device *fc,
+ flexcop_dma_index_t no, int onoff);
+int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma,
+ flexcop_dma_index_t dma_idx);
+int flexcop_dma_xfer_control(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index,
+ int onoff);
+int flexcop_dma_config_timer(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx, u8 cycles);
/* from flexcop-eeprom.c */
/* the PCI part uses this call to get the MAC address, the USB part has its own */
@@ -141,13 +148,15 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t,
u8 chipaddr, u8 addr, u8 *buf, u16 len);
/* from flexcop-sram.c */
-int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target);
+int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
+ flexcop_sram_dest_target_t target);
void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s);
-void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill);
+void flexcop_sram_ctrl(struct flexcop_device *fc,
+ int usb_wan, int sramdma, int maximumfill);
/* global prototypes for the flexcop-chip */
/* from flexcop-fe-tuner.c */
-int flexcop_frontend_init(struct flexcop_device *card);
+int flexcop_frontend_init(struct flexcop_device *fc);
void flexcop_frontend_exit(struct flexcop_device *fc);
/* from flexcop-i2c.c */
@@ -159,11 +168,14 @@ int flexcop_sram_init(struct flexcop_device *fc);
/* from flexcop-misc.c */
void flexcop_determine_revision(struct flexcop_device *fc);
-void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix);
-void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num);
+void flexcop_device_name(struct flexcop_device *fc,
+ const char *prefix, const char *suffix);
+void flexcop_dump_reg(struct flexcop_device *fc,
+ flexcop_ibi_register reg, int num);
/* from flexcop-hw-filter.c */
-int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff);
+int flexcop_pid_feed_control(struct flexcop_device *fc,
+ struct dvb_demux_feed *dvbdmxfeed, int onoff);
void flexcop_hw_filter_init(struct flexcop_device *fc);
void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff);
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c
index 26f0011a5078..2881e0d956ad 100644
--- a/drivers/media/dvb/b2c2/flexcop-dma.c
+++ b/drivers/media/dvb/b2c2/flexcop-dma.c
@@ -1,13 +1,12 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-dma.c - methods for configuring and controlling the DMA of the FlexCop.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-dma.c - configuring and controlling the DMA of the FlexCop
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
-int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size)
+int flexcop_dma_allocate(struct pci_dev *pdev,
+ struct flexcop_dma *dma, u32 size)
{
u8 *tcpu;
dma_addr_t tdma = 0;
@@ -32,7 +31,8 @@ EXPORT_SYMBOL(flexcop_dma_allocate);
void flexcop_dma_free(struct flexcop_dma *dma)
{
- pci_free_consistent(dma->pdev, dma->size*2,dma->cpu_addr0, dma->dma_addr0);
+ pci_free_consistent(dma->pdev, dma->size*2,
+ dma->cpu_addr0, dma->dma_addr0);
memset(dma,0,sizeof(struct flexcop_dma));
}
EXPORT_SYMBOL(flexcop_dma_free);
@@ -44,8 +44,8 @@ int flexcop_dma_config(struct flexcop_device *fc,
flexcop_ibi_value v0x0,v0x4,v0xc;
v0x0.raw = v0x4.raw = v0xc.raw = 0;
- v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
- v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
+ v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
+ v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
if ((dma_idx & FC_DMA_1) == dma_idx) {
@@ -57,7 +57,8 @@ int flexcop_dma_config(struct flexcop_device *fc,
fc->write_ibi_reg(fc,dma2_014,v0x4);
fc->write_ibi_reg(fc,dma2_01c,v0xc);
} else {
- err("either DMA1 or DMA2 can be configured at the within one flexcop_dma_config call.");
+ err("either DMA1 or DMA2 can be configured within one "
+ "flexcop_dma_config call.");
return -EINVAL;
}
@@ -81,7 +82,8 @@ int flexcop_dma_xfer_control(struct flexcop_device *fc,
r0x0 = dma2_010;
r0xc = dma2_01c;
} else {
- err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call.");
+ err("either transfer DMA1 or DMA2 can be started within one "
+ "flexcop_dma_xfer_control call.");
return -EINVAL;
}
@@ -154,8 +156,7 @@ EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
/* 1 cycles = 1.97 msec */
int flexcop_dma_config_timer(struct flexcop_device *fc,
- flexcop_dma_index_t dma_idx,
- u8 cycles)
+ flexcop_dma_index_t dma_idx, u8 cycles)
{
flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
diff --git a/drivers/media/dvb/b2c2/flexcop-eeprom.c b/drivers/media/dvb/b2c2/flexcop-eeprom.c
index 8a8ae8a3e6ba..a25373a9bd84 100644
--- a/drivers/media/dvb/b2c2/flexcop-eeprom.c
+++ b/drivers/media/dvb/b2c2/flexcop-eeprom.c
@@ -1,9 +1,7 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading is used)
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading)
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
@@ -14,17 +12,17 @@ static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
}
-static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries)
+static int eeprom_lrc_write(struct adapter *adapter, u32 addr,
+ u32 len, u8 *wbuf, u8 *rbuf, int retries)
{
- int i;
+int i;
- for (i = 0; i < retries; i++) {
- if (eeprom_write(adapter, addr, wbuf, len) == len) {
- if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
- return 1;
+for (i = 0; i < retries; i++) {
+ if (eeprom_write(adapter, addr, wbuf, len) == len) {
+ if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
+ return 1;
}
}
-
return 0;
}
@@ -39,12 +37,10 @@ static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
return 0;
memcpy(wbuf, key, len);
-
wbuf[16] = 0;
wbuf[17] = 0;
wbuf[18] = 0;
wbuf[19] = calc_lrc(wbuf, 19);
-
return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
}
@@ -59,7 +55,6 @@ static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
return 0;
memcpy(key, buf, len);
-
return 1;
}
@@ -74,9 +69,7 @@ static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
tmp[3] = mac[5];
tmp[4] = mac[6];
tmp[5] = mac[7];
-
} else {
-
tmp[0] = mac[0];
tmp[1] = mac[1];
tmp[2] = mac[2];
@@ -90,11 +83,11 @@ static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
return 1;
-
return 0;
}
-static int flexcop_eeprom_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len)
+static int flexcop_eeprom_read(struct flexcop_device *fc,
+ u16 addr, u8 *buf, u16 len)
{
return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len);
}
@@ -110,7 +103,8 @@ static u8 calc_lrc(u8 *buf, int len)
return sum;
}
-static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
+static int flexcop_eeprom_request(struct flexcop_device *fc,
+ flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
{
int i,ret = 0;
u8 chipaddr = 0x50 | ((addr >> 8) & 3);
@@ -123,7 +117,8 @@ static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t
return ret;
}
-static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len, int retries)
+static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr,
+ u8 *buf, u16 len, int retries)
{
int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries);
if (ret == 0)
@@ -133,8 +128,7 @@ static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf,
}
/* JJ's comment about extended == 1: it is not presently used anywhere but was
- * added to the low-level functions for possible support of EUI64
- */
+ * added to the low-level functions for possible support of EUI64 */
int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
{
u8 buf[8];
@@ -142,12 +136,9 @@ int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) {
if (extended != 0) {
- err("TODO: extended (EUI64) MAC addresses aren't completely supported yet");
+ err("TODO: extended (EUI64) MAC addresses aren't "
+ "completely supported yet");
ret = -EINVAL;
-/* memcpy(fc->dvb_adapter.proposed_mac,buf,3);
- mac[3] = 0xfe;
- mac[4] = 0xff;
- memcpy(&fc->dvb_adapter.proposed_mac[3],&buf[5],3); */
} else
memcpy(fc->dvb_adapter.proposed_mac,buf,6);
}
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 5cded3708541..f7afab5944cf 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -592,14 +592,14 @@ int flexcop_frontend_init(struct flexcop_device *fc)
fc->fe_sleep = ops->sleep;
ops->sleep = flexcop_sleep;
- fc->dev_type = FC_SKY;
+ fc->dev_type = FC_SKY_REV26;
goto fe_found;
}
/* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
if (fc->fe != NULL) {
- fc->dev_type = FC_AIR_DVB;
+ fc->dev_type = FC_AIR_DVBT;
fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
goto fe_found;
}
@@ -653,7 +653,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
fc->fe_sleep = ops->sleep;
ops->sleep = flexcop_sleep;
- fc->dev_type = FC_SKY_OLD;
+ fc->dev_type = FC_SKY_REV23;
goto fe_found;
}
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
index 451974ba32f3..77e45475f4c7 100644
--- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c
+++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
@@ -1,33 +1,30 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-hw-filter.c - pid and mac address filtering and corresponding control functions.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-hw-filter.c - pid and mac address filtering and control functions
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff);
-
- deb_ts("rcv_data is now: '%s'\n",onoff ? "on" : "off");
+ flexcop_set_ibi_value(ctrl_208, Rcv_Data_sig, onoff);
+ deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off");
}
void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,SMC_Enable_sig,onoff);
+ flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff);
}
static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,Null_filter_sig,onoff);
+ flexcop_set_ibi_value(ctrl_208, Null_filter_sig, onoff);
}
void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
{
- flexcop_ibi_value v418,v41c;
- v41c = fc->read_ibi_reg(fc,mac_address_41c);
+ flexcop_ibi_value v418, v41c;
+ v41c = fc->read_ibi_reg(fc, mac_address_41c);
v418.mac_address_418.MAC1 = mac[0];
v418.mac_address_418.MAC2 = mac[1];
@@ -36,27 +33,28 @@ void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
v41c.mac_address_41c.MAC7 = mac[4];
v41c.mac_address_41c.MAC8 = mac[5];
- fc->write_ibi_reg(fc,mac_address_418,v418);
- fc->write_ibi_reg(fc,mac_address_41c,v41c);
+ fc->write_ibi_reg(fc, mac_address_418, v418);
+ fc->write_ibi_reg(fc, mac_address_41c, v41c);
}
void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,MAC_filter_Mode_sig,onoff);
+ flexcop_set_ibi_value(ctrl_208, MAC_filter_Mode_sig, onoff);
}
-static void flexcop_pid_group_filter(struct flexcop_device *fc, u16 pid, u16 mask)
+static void flexcop_pid_group_filter(struct flexcop_device *fc,
+ u16 pid, u16 mask)
{
/* index_reg_310.extra_index_reg need to 0 or 7 to work */
flexcop_ibi_value v30c;
v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid;
v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask;
- fc->write_ibi_reg(fc,pid_filter_30c,v30c);
+ fc->write_ibi_reg(fc, pid_filter_30c, v30c);
}
static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,Mask_filter_sig,onoff);
+ flexcop_set_ibi_value(ctrl_208, Mask_filter_sig, onoff);
}
/* this fancy define reduces the code size of the quite similar PID controlling of
@@ -65,91 +63,112 @@ static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
#define pid_ctrl(vregname,field,enablefield,trans_field,transval) \
flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \
- v208 = fc->read_ibi_reg(fc, ctrl_208); \
-\
- vpid.vregname.field = onoff ? pid : 0x1fff; \
- vpid.vregname.trans_field = transval; \
- v208.ctrl_208.enablefield = onoff; \
-\
- fc->write_ibi_reg(fc,vregname,vpid); \
- fc->write_ibi_reg(fc,ctrl_208,v208);
+v208 = fc->read_ibi_reg(fc, ctrl_208); \
+vpid.vregname.field = onoff ? pid : 0x1fff; \
+vpid.vregname.trans_field = transval; \
+v208.ctrl_208.enablefield = onoff; \
+fc->write_ibi_reg(fc, vregname, vpid); \
+fc->write_ibi_reg(fc, ctrl_208, v208);
-static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_300,Stream1_PID,Stream1_filter_sig,Stream1_trans,0);
+ pid_ctrl(pid_filter_300, Stream1_PID, Stream1_filter_sig,
+ Stream1_trans, 0);
}
-static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_300,Stream2_PID,Stream2_filter_sig,Stream2_trans,0);
+ pid_ctrl(pid_filter_300, Stream2_PID, Stream2_filter_sig,
+ Stream2_trans, 0);
}
-static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_304,PCR_PID,PCR_filter_sig,PCR_trans,0);
+ pid_ctrl(pid_filter_304, PCR_PID, PCR_filter_sig, PCR_trans, 0);
}
-static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_304,PMT_PID,PMT_filter_sig,PMT_trans,0);
+ pid_ctrl(pid_filter_304, PMT_PID, PMT_filter_sig, PMT_trans, 0);
}
-static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_308,EMM_PID,EMM_filter_sig,EMM_trans,0);
+ pid_ctrl(pid_filter_308, EMM_PID, EMM_filter_sig, EMM_trans, 0);
}
-static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_308,ECM_PID,ECM_filter_sig,ECM_trans,0);
+ pid_ctrl(pid_filter_308, ECM_PID, ECM_filter_sig, ECM_trans, 0);
}
-static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,int onoff)
+static void flexcop_pid_control(struct flexcop_device *fc,
+ int index, u16 pid, int onoff)
{
if (pid == 0x2000)
return;
- deb_ts("setting pid: %5d %04x at index %d '%s'\n",pid,pid,index,onoff ? "on" : "off");
+ deb_ts("setting pid: %5d %04x at index %d '%s'\n",
+ pid, pid, index, onoff ? "on" : "off");
/* We could use bit magic here to reduce source code size.
* I decided against it, but to use the real register names */
switch (index) {
- case 0: flexcop_pid_Stream1_PID_ctrl(fc,pid,onoff); break;
- case 1: flexcop_pid_Stream2_PID_ctrl(fc,pid,onoff); break;
- case 2: flexcop_pid_PCR_PID_ctrl(fc,pid,onoff); break;
- case 3: flexcop_pid_PMT_PID_ctrl(fc,pid,onoff); break;
- case 4: flexcop_pid_EMM_PID_ctrl(fc,pid,onoff); break;
- case 5: flexcop_pid_ECM_PID_ctrl(fc,pid,onoff); break;
- default:
- if (fc->has_32_hw_pid_filter && index < 38) {
- flexcop_ibi_value vpid,vid;
-
- /* set the index */
- vid = fc->read_ibi_reg(fc,index_reg_310);
- vid.index_reg_310.index_reg = index - 6;
- fc->write_ibi_reg(fc,index_reg_310, vid);
-
- vpid = fc->read_ibi_reg(fc,pid_n_reg_314);
- vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
- vpid.pid_n_reg_314.PID_enable_bit = onoff;
- fc->write_ibi_reg(fc,pid_n_reg_314, vpid);
- }
- break;
+ case 0:
+ flexcop_pid_Stream1_PID_ctrl(fc, pid, onoff);
+ break;
+ case 1:
+ flexcop_pid_Stream2_PID_ctrl(fc, pid, onoff);
+ break;
+ case 2:
+ flexcop_pid_PCR_PID_ctrl(fc, pid, onoff);
+ break;
+ case 3:
+ flexcop_pid_PMT_PID_ctrl(fc, pid, onoff);
+ break;
+ case 4:
+ flexcop_pid_EMM_PID_ctrl(fc, pid, onoff);
+ break;
+ case 5:
+ flexcop_pid_ECM_PID_ctrl(fc, pid, onoff);
+ break;
+ default:
+ if (fc->has_32_hw_pid_filter && index < 38) {
+ flexcop_ibi_value vpid, vid;
+
+ /* set the index */
+ vid = fc->read_ibi_reg(fc, index_reg_310);
+ vid.index_reg_310.index_reg = index - 6;
+ fc->write_ibi_reg(fc, index_reg_310, vid);
+
+ vpid = fc->read_ibi_reg(fc, pid_n_reg_314);
+ vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
+ vpid.pid_n_reg_314.PID_enable_bit = onoff;
+ fc->write_ibi_reg(fc, pid_n_reg_314, vpid);
+ }
+ break;
}
}
-static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc,int onoff)
+static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff)
{
if (fc->fullts_streaming_state != onoff) {
deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling");
flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff));
- flexcop_pid_group_filter_ctrl(fc,onoff);
+ flexcop_pid_group_filter_ctrl(fc, onoff);
fc->fullts_streaming_state = onoff;
}
return 0;
}
-int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff)
+int flexcop_pid_feed_control(struct flexcop_device *fc,
+ struct dvb_demux_feed *dvbdmxfeed, int onoff)
{
int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
@@ -164,24 +183,25 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
* - or the requested pid is 0x2000 */
if (!fc->pid_filtering && fc->feedcount == onoff)
- flexcop_toggle_fullts_streaming(fc,onoff);
+ flexcop_toggle_fullts_streaming(fc, onoff);
if (fc->pid_filtering) {
- flexcop_pid_control(fc,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
+ flexcop_pid_control \
+ (fc, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
if (fc->extra_feedcount > 0)
- flexcop_toggle_fullts_streaming(fc,1);
+ flexcop_toggle_fullts_streaming(fc, 1);
else if (dvbdmxfeed->pid == 0x2000)
- flexcop_toggle_fullts_streaming(fc,onoff);
+ flexcop_toggle_fullts_streaming(fc, onoff);
else
- flexcop_toggle_fullts_streaming(fc,0);
+ flexcop_toggle_fullts_streaming(fc, 0);
}
/* if it was the first or last feed request change the stream-status */
if (fc->feedcount == onoff) {
- flexcop_rcv_data_ctrl(fc,onoff);
+ flexcop_rcv_data_ctrl(fc, onoff);
if (fc->stream_control) /* device specific stream control */
- fc->stream_control(fc,onoff);
+ fc->stream_control(fc, onoff);
/* feeding stopped -> reset the flexcop filter*/
if (onoff == 0) {
@@ -189,7 +209,6 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
flexcop_hw_filter_init(fc);
}
}
-
return 0;
}
EXPORT_SYMBOL(flexcop_pid_feed_control);
@@ -199,15 +218,15 @@ void flexcop_hw_filter_init(struct flexcop_device *fc)
int i;
flexcop_ibi_value v;
for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++)
- flexcop_pid_control(fc,i,0x1fff,0);
+ flexcop_pid_control(fc, i, 0x1fff, 0);
flexcop_pid_group_filter(fc, 0, 0x1fe0);
- flexcop_pid_group_filter_ctrl(fc,0);
+ flexcop_pid_group_filter_ctrl(fc, 0);
- v = fc->read_ibi_reg(fc,pid_filter_308);
+ v = fc->read_ibi_reg(fc, pid_filter_308);
v.pid_filter_308.EMM_filter_4 = 1;
v.pid_filter_308.EMM_filter_6 = 0;
- fc->write_ibi_reg(fc,pid_filter_308,v);
+ fc->write_ibi_reg(fc, pid_filter_308, v);
flexcop_null_filter_ctrl(fc, 1);
}
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c
index f13783f08f0f..e2bed5076485 100644
--- a/drivers/media/dvb/b2c2/flexcop-i2c.c
+++ b/drivers/media/dvb/b2c2/flexcop-i2c.c
@@ -1,17 +1,14 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
#define FC_MAX_I2C_RETRIES 100000
-/* #define DUMP_I2C_MESSAGES */
-
-static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r100)
+static int flexcop_i2c_operation(struct flexcop_device *fc,
+ flexcop_ibi_value *r100)
{
int i;
flexcop_ibi_value r;
@@ -26,7 +23,7 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r
r = fc->read_ibi_reg(fc, tw_sm_c_100);
if (!r.tw_sm_c_100.no_base_addr_ack_error) {
- if (r.tw_sm_c_100.st_done) { /* && !r.tw_sm_c_100.working_start */
+ if (r.tw_sm_c_100.st_done) {
*r100 = r;
deb_i2c("i2c success\n");
return 0;
@@ -36,17 +33,31 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r
return -EREMOTEIO;
}
}
- deb_i2c("tried %d times i2c operation, never finished or too many ack errors.\n",i);
+ deb_i2c("tried %d times i2c operation, "
+ "never finished or too many ack errors.\n", i);
return -EREMOTEIO;
}
static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
- flexcop_ibi_value r100, u8 *buf)
+ flexcop_ibi_value r100, u8 *buf)
{
flexcop_ibi_value r104;
- int len = r100.tw_sm_c_100.total_bytes, /* remember total_bytes is buflen-1 */
+ int len = r100.tw_sm_c_100.total_bytes,
+ /* remember total_bytes is buflen-1 */
ret;
+ /* work-around to have CableStar2 and SkyStar2 rev 2.7 work
+ * correctly:
+ *
+ * the ITD1000 is behind an i2c-gate which closes automatically
+ * after an i2c-transaction the STV0297 needs 2 consecutive reads
+ * one with no_base_addr = 0 and one with 1
+ *
+ * those two work-arounds are conflictin: we check for the card
+ * type, it is set when probing the ITD1000 */
+ if (i2c->fc->dev_type == FC_SKY_REV27)
+ r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
+
ret = flexcop_i2c_operation(i2c->fc, &r100);
if (ret != 0) {
deb_i2c("Retrying operation\n");
@@ -69,11 +80,11 @@ static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg;
if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg;
}
-
return 0;
}
-static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100, u8 *buf)
+static int flexcop_i2c_write4(struct flexcop_device *fc,
+ flexcop_ibi_value r100, u8 *buf)
{
flexcop_ibi_value r104;
int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */
@@ -81,7 +92,6 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100,
/* there is at least one byte, otherwise we wouldn't be here */
r100.tw_sm_c_100.data1_reg = buf[0];
-
r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0;
r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0;
r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0;
@@ -94,7 +104,7 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100,
}
int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
- flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+ flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
{
int ret;
@@ -117,7 +127,6 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
printk("rd(");
else
printk("wr(");
-
printk("%02x): %02x ", chipaddr, addr);
#endif
@@ -163,7 +172,8 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
EXPORT_SYMBOL(flexcop_i2c_request);
/* master xfer callback for demodulator */
-static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
+static int flexcop_master_xfer(struct i2c_adapter *i2c_adap,
+ struct i2c_msg msgs[], int num)
{
struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap);
int i, ret = 0;
@@ -182,12 +192,13 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs
/* reading */
if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) {
ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr,
- msgs[i].buf[0], msgs[i+1].buf, msgs[i+1].len);
+ msgs[i].buf[0], msgs[i+1].buf,
+ msgs[i+1].len);
i++; /* skip the following message */
} else /* writing */
ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr,
- msgs[i].buf[0], &msgs[i].buf[1],
- msgs[i].len - 1);
+ msgs[i].buf[0], &msgs[i].buf[1],
+ msgs[i].len - 1);
if (ret < 0) {
err("i2c master_xfer failed");
break;
@@ -214,23 +225,21 @@ static struct i2c_algorithm flexcop_algo = {
int flexcop_i2c_init(struct flexcop_device *fc)
{
int ret;
-
mutex_init(&fc->i2c_mutex);
fc->fc_i2c_adap[0].fc = fc;
fc->fc_i2c_adap[1].fc = fc;
fc->fc_i2c_adap[2].fc = fc;
-
fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD;
fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
- sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
+ sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
- sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
+ sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
- sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
+ sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
@@ -268,7 +277,6 @@ adap_2_failed:
i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
adap_1_failed:
i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
-
return ret;
}
@@ -279,6 +287,5 @@ void flexcop_i2c_exit(struct flexcop_device *fc)
i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
}
-
fc->init_state &= ~FC_STATE_I2C_INIT;
}
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index 93d20e56f909..e56627d2f0f4 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -1,9 +1,7 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-misc.c - miscellaneous functions.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-misc.c - miscellaneous functions
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
@@ -12,39 +10,43 @@ void flexcop_determine_revision(struct flexcop_device *fc)
flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204);
switch (v.misc_204.Rev_N_sig_revision_hi) {
- case 0x2:
- deb_info("found a FlexCopII.\n");
- fc->rev = FLEXCOP_II;
- break;
- case 0x3:
- deb_info("found a FlexCopIIb.\n");
- fc->rev = FLEXCOP_IIB;
- break;
- case 0x0:
- deb_info("found a FlexCopIII.\n");
- fc->rev = FLEXCOP_III;
- break;
- default:
- err("unkown FlexCop Revision: %x. Please report the linux-dvb@linuxtv.org.",v.misc_204.Rev_N_sig_revision_hi);
- break;
+ case 0x2:
+ deb_info("found a FlexCopII.\n");
+ fc->rev = FLEXCOP_II;
+ break;
+ case 0x3:
+ deb_info("found a FlexCopIIb.\n");
+ fc->rev = FLEXCOP_IIB;
+ break;
+ case 0x0:
+ deb_info("found a FlexCopIII.\n");
+ fc->rev = FLEXCOP_III;
+ break;
+ default:
+ err("unknown FlexCop Revision: %x. Please report this to "
+ "linux-dvb@linuxtv.org.",
+ v.misc_204.Rev_N_sig_revision_hi);
+ break;
}
if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps))
- deb_info("this FlexCop has the additional 32 hardware pid filter.\n");
+ deb_info("this FlexCop has "
+ "the additional 32 hardware pid filter.\n");
else
- deb_info("this FlexCop has only the 6 basic main hardware pid filter.\n");
+ deb_info("this FlexCop has "
+ "the 6 basic main hardware pid filter.\n");
/* bus parts have to decide if hw pid filtering is used or not. */
}
static const char *flexcop_revision_names[] = {
- "Unkown chip",
+ "Unknown chip",
"FlexCopII",
"FlexCopIIb",
"FlexCopIII",
};
static const char *flexcop_device_names[] = {
- "Unkown device",
+ "Unknown device",
"Air2PC/AirStar 2 DVB-T",
"Air2PC/AirStar 2 ATSC 1st generation",
"Air2PC/AirStar 2 ATSC 2nd generation",
@@ -61,21 +63,23 @@ static const char *flexcop_bus_names[] = {
"PCI",
};
-void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const
- char *suffix)
+void flexcop_device_name(struct flexcop_device *fc,
+ const char *prefix, const char *suffix)
{
- info("%s '%s' at the '%s' bus controlled by a '%s' %s",prefix,
- flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type],
- flexcop_revision_names[fc->rev],suffix);
+ info("%s '%s' at the '%s' bus controlled by a '%s' %s",
+ prefix, flexcop_device_names[fc->dev_type],
+ flexcop_bus_names[fc->bus_type],
+ flexcop_revision_names[fc->rev], suffix);
}
-void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num)
+void flexcop_dump_reg(struct flexcop_device *fc,
+ flexcop_ibi_register reg, int num)
{
flexcop_ibi_value v;
int i;
for (i = 0; i < num; i++) {
- v = fc->read_ibi_reg(fc,reg+4*i);
- deb_rdump("0x%03x: %08x, ",reg+4*i, v.raw);
+ v = fc->read_ibi_reg(fc, reg+4*i);
+ deb_rdump("0x%03x: %08x, ", reg+4*i, v.raw);
}
deb_rdump("\n");
}
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
index 76e37fd96bb6..227c0200b70a 100644
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -1,9 +1,7 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-pci.c - covers the PCI part including DMA transfers.
- *
- * see flexcop.c for copyright information.
+ * Linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-pci.c - covers the PCI part including DMA transfers
+ * see flexcop.c for copyright information
*/
#define FC_LOG_PREFIX "flexcop-pci"
@@ -11,7 +9,8 @@
static int enable_pid_filtering = 1;
module_param(enable_pid_filtering, int, 0444);
-MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
+MODULE_PARM_DESC(enable_pid_filtering,
+ "enable hardware pid filtering: supported values: 0 (fullts), 1");
static int irq_chk_intv = 100;
module_param(irq_chk_intv, int, 0644);
@@ -26,17 +25,17 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog.");
#define DEBSTATUS " (debugging is not enabled)"
#endif
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_reg(args...) dprintk(0x02,args)
-#define deb_ts(args...) dprintk(0x04,args)
-#define deb_irq(args...) dprintk(0x08,args)
-#define deb_chk(args...) dprintk(0x10,args)
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_reg(args...) dprintk(0x02, args)
+#define deb_ts(args...) dprintk(0x04, args)
+#define deb_irq(args...) dprintk(0x08, args)
+#define deb_chk(args...) dprintk(0x10, args)
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug,
"set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))."
- DEBSTATUS);
+ DEBSTATUS);
#define DRIVER_VERSION "0.1"
#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver"
@@ -51,30 +50,30 @@ struct flexcop_pci {
void __iomem *io_mem;
u32 irq;
-/* buffersize (at least for DMA1, need to be % 188 == 0,
- * this logic is required */
+ /* buffersize (at least for DMA1, need to be % 188 == 0,
+ * this logic is required */
#define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188)
#define FC_DEFAULT_DMA2_BUFSIZE (10 * 188)
struct flexcop_dma dma[2];
int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */
- u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */
+ u32 last_dma1_cur_pos;
+ /* position of the pointer last time the timer/packet irq occured */
int count;
int count_prev;
int stream_problem;
spinlock_t irq_lock;
-
unsigned long last_irq;
struct delayed_work irq_check_work;
-
struct flexcop_device *fc_dev;
};
-static int lastwreg,lastwval,lastrreg,lastrval;
+static int lastwreg, lastwval, lastrreg, lastrval;
-static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, flexcop_ibi_register r)
+static flexcop_ibi_value flexcop_pci_read_ibi_reg(struct flexcop_device *fc,
+ flexcop_ibi_register r)
{
struct flexcop_pci *fc_pci = fc->bus_specific;
flexcop_ibi_value v;
@@ -82,19 +81,20 @@ static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, fl
if (lastrreg != r || lastrval != v.raw) {
lastrreg = r; lastrval = v.raw;
- deb_reg("new rd: %3x: %08x\n",r,v.raw);
+ deb_reg("new rd: %3x: %08x\n", r, v.raw);
}
return v;
}
-static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register r, flexcop_ibi_value v)
+static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc,
+ flexcop_ibi_register r, flexcop_ibi_value v)
{
struct flexcop_pci *fc_pci = fc->bus_specific;
if (lastwreg != r || lastwval != v.raw) {
lastwreg = r; lastwval = v.raw;
- deb_reg("new wr: %3x: %08x\n",r,v.raw);
+ deb_reg("new wr: %3x: %08x\n", r, v.raw);
}
writel(v.raw, fc_pci->io_mem + r);
@@ -113,15 +113,16 @@ static void flexcop_pci_irq_check_work(struct work_struct *work)
deb_chk("no IRQ since the last check\n");
if (fc_pci->stream_problem++ == 3) {
struct dvb_demux_feed *feed;
+ deb_info("flexcop-pci: stream problem, resetting pid filter\n");
spin_lock_irq(&fc->demux.lock);
list_for_each_entry(feed, &fc->demux.feed_list,
- list_head) {
+ list_head) {
flexcop_pid_feed_control(fc, feed, 0);
}
list_for_each_entry(feed, &fc->demux.feed_list,
- list_head) {
+ list_head) {
flexcop_pid_feed_control(fc, feed, 1);
}
spin_unlock_irq(&fc->demux.lock);
@@ -149,11 +150,10 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
flexcop_ibi_value v;
irqreturn_t ret = IRQ_HANDLED;
- spin_lock_irqsave(&fc_pci->irq_lock,flags);
-
- v = fc->read_ibi_reg(fc,irq_20c);
+ spin_lock_irqsave(&fc_pci->irq_lock, flags);
+ v = fc->read_ibi_reg(fc, irq_20c);
- /* errors */
+ /* errors */
if (v.irq_20c.Data_receiver_error)
deb_chk("data receiver error\n");
if (v.irq_20c.Continuity_error_flag)
@@ -164,24 +164,29 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
deb_chk("Transport error\n");
if ((fc_pci->count % 1000) == 0)
- deb_chk("%d valid irq took place so far\n",fc_pci->count);
+ deb_chk("%d valid irq took place so far\n", fc_pci->count);
if (v.irq_20c.DMA1_IRQ_Status == 1) {
if (fc_pci->active_dma1_addr == 0)
- flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188);
+ flexcop_pass_dmx_packets(fc_pci->fc_dev,
+ fc_pci->dma[0].cpu_addr0,
+ fc_pci->dma[0].size / 188);
else
- flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr1,fc_pci->dma[0].size / 188);
+ flexcop_pass_dmx_packets(fc_pci->fc_dev,
+ fc_pci->dma[0].cpu_addr1,
+ fc_pci->dma[0].size / 188);
deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr);
fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr;
- } else if (v.irq_20c.DMA1_Timer_Status == 1) {
/* for the timer IRQ we only can use buffer dmx feeding, because we don't have
* complete TS packets when reading from the DMA memory */
+ } else if (v.irq_20c.DMA1_Timer_Status == 1) {
dma_addr_t cur_addr =
fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
- deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ",
+ deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, "
+ "last_cur_pos: %08x ",
jiffies_to_usecs(jiffies - fc_pci->last_irq),
v.raw, (unsigned long long)cur_addr, cur_pos,
fc_pci->last_dma1_cur_pos);
@@ -191,30 +196,36 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
* pass the data from last_cur_pos to the buffer end to the demux
*/
if (cur_pos < fc_pci->last_dma1_cur_pos) {
- deb_irq(" end was reached: passing %d bytes ",(fc_pci->dma[0].size*2 - 1) - fc_pci->last_dma1_cur_pos);
+ deb_irq(" end was reached: passing %d bytes ",
+ (fc_pci->dma[0].size*2 - 1) -
+ fc_pci->last_dma1_cur_pos);
flexcop_pass_dmx_data(fc_pci->fc_dev,
- fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
- (fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos);
+ fc_pci->dma[0].cpu_addr0 +
+ fc_pci->last_dma1_cur_pos,
+ (fc_pci->dma[0].size*2) -
+ fc_pci->last_dma1_cur_pos);
fc_pci->last_dma1_cur_pos = 0;
}
if (cur_pos > fc_pci->last_dma1_cur_pos) {
- deb_irq(" passing %d bytes ",cur_pos - fc_pci->last_dma1_cur_pos);
+ deb_irq(" passing %d bytes ",
+ cur_pos - fc_pci->last_dma1_cur_pos);
flexcop_pass_dmx_data(fc_pci->fc_dev,
- fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
- cur_pos - fc_pci->last_dma1_cur_pos);
+ fc_pci->dma[0].cpu_addr0 +
+ fc_pci->last_dma1_cur_pos,
+ cur_pos - fc_pci->last_dma1_cur_pos);
}
deb_irq("\n");
fc_pci->last_dma1_cur_pos = cur_pos;
fc_pci->count++;
} else {
- deb_irq("isr for flexcop called, apparently without reason (%08x)\n",v.raw);
+ deb_irq("isr for flexcop called, "
+ "apparently without reason (%08x)\n", v.raw);
ret = IRQ_NONE;
}
- spin_unlock_irqrestore(&fc_pci->irq_lock,flags);
-
+ spin_unlock_irqrestore(&fc_pci->irq_lock, flags);
return ret;
}
@@ -222,52 +233,48 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)
{
struct flexcop_pci *fc_pci = fc->bus_specific;
if (onoff) {
- flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1);
- flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2);
-
- flexcop_dma_config_timer(fc,FC_DMA_1,0);
-
- flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,1);
+ flexcop_dma_config(fc, &fc_pci->dma[0], FC_DMA_1);
+ flexcop_dma_config(fc, &fc_pci->dma[1], FC_DMA_2);
+ flexcop_dma_config_timer(fc, FC_DMA_1, 0);
+ flexcop_dma_xfer_control(fc, FC_DMA_1,
+ FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 1);
deb_irq("DMA xfer enabled\n");
fc_pci->last_dma1_cur_pos = 0;
- flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
+ flexcop_dma_control_timer_irq(fc, FC_DMA_1, 1);
deb_irq("IRQ enabled\n");
-
fc_pci->count_prev = fc_pci->count;
-
-// fc_pci->active_dma1_addr = 0;
-// flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
-
} else {
- flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
+ flexcop_dma_control_timer_irq(fc, FC_DMA_1, 0);
deb_irq("IRQ disabled\n");
-// flexcop_dma_control_size_irq(fc,FC_DMA_1,0);
-
- flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,0);
+ flexcop_dma_xfer_control(fc, FC_DMA_1,
+ FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 0);
deb_irq("DMA xfer disabled\n");
}
-
return 0;
}
static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci)
{
int ret;
- if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0)
+ ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[0],
+ FC_DEFAULT_DMA1_BUFSIZE);
+ if (ret != 0)
return ret;
- if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) {
+ ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[1],
+ FC_DEFAULT_DMA2_BUFSIZE);
+ if (ret != 0) {
flexcop_dma_free(&fc_pci->dma[0]);
return ret;
}
- flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
- flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
-
+ flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_MEDIA |
+ FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
+ flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_CAO |
+ FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
fc_pci->init_state |= FC_PCI_DMA_INIT;
-
return ret;
}
@@ -290,12 +297,8 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
if ((ret = pci_enable_device(fc_pci->pdev)) != 0)
return ret;
-
pci_set_master(fc_pci->pdev);
- /* enable interrupts */
- // pci_write_config_dword(pdev, 0x6c, 0x8000);
-
if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0)
goto err_pci_disable_device;
@@ -338,8 +341,8 @@ static void flexcop_pci_exit(struct flexcop_pci *fc_pci)
fc_pci->init_state &= ~FC_PCI_INIT;
}
-
-static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int flexcop_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct flexcop_device *fc;
struct flexcop_pci *fc_pci;
@@ -350,7 +353,7 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
return -ENOMEM;
}
-/* general flexcop init */
+ /* general flexcop init */
fc_pci = fc->bus_specific;
fc_pci->fc_dev = fc;
@@ -358,7 +361,6 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
fc->write_ibi_reg = flexcop_pci_write_ibi_reg;
fc->i2c_request = flexcop_i2c_request;
fc->get_mac_addr = flexcop_eeprom_check_mac_addr;
-
fc->stream_control = flexcop_pci_stream_control;
if (enable_pid_filtering)
@@ -368,29 +370,29 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
fc->pid_filtering = enable_pid_filtering;
fc->bus_type = FC_PCI;
-
fc->dev = &pdev->dev;
fc->owner = THIS_MODULE;
-/* bus specific part */
+ /* bus specific part */
fc_pci->pdev = pdev;
if ((ret = flexcop_pci_init(fc_pci)) != 0)
goto err_kfree;
-/* init flexcop */
+ /* init flexcop */
if ((ret = flexcop_device_initialize(fc)) != 0)
goto err_pci_exit;
-/* init dma */
+ /* init dma */
if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
goto err_fc_exit;
INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work);
- if (irq_chk_intv > 0)
- schedule_delayed_work(&fc_pci->irq_check_work,
- msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
-
+ if (irq_chk_intv > 0)
+ schedule_delayed_work(&fc_pci->irq_check_work,
+ msecs_to_jiffies(irq_chk_intv < 100 ?
+ 100 :
+ irq_chk_intv));
return ret;
err_fc_exit:
@@ -420,7 +422,6 @@ static void flexcop_pci_remove(struct pci_dev *pdev)
static struct pci_device_id flexcop_pci_tbl[] = {
{ PCI_DEVICE(0x13d0, 0x2103) },
-/* { PCI_DEVICE(0x13d0, 0x2200) }, ? */
{ },
};
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 7599fccc1a5b..dc4528dcbb98 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -1,14 +1,11 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
*/
#ifndef __FLEXCOP_REG_H__
#define __FLEXCOP_REG_H__
-
typedef enum {
FLEXCOP_UNK = 0,
FLEXCOP_II,
@@ -18,13 +15,13 @@ typedef enum {
typedef enum {
FC_UNK = 0,
- FC_AIR_DVB,
+ FC_CABLE,
+ FC_AIR_DVBT,
FC_AIR_ATSC1,
FC_AIR_ATSC2,
- FC_SKY,
- FC_SKY_OLD,
- FC_CABLE,
FC_AIR_ATSC3,
+ FC_SKY_REV23,
+ FC_SKY_REV26,
FC_SKY_REV27,
FC_SKY_REV28,
} flexcop_device_type_t;
@@ -36,12 +33,12 @@ typedef enum {
/* FlexCop IBI Registers */
#if defined(__LITTLE_ENDIAN)
- #include "flexcop_ibi_value_le.h"
+#include "flexcop_ibi_value_le.h"
#else
#if defined(__BIG_ENDIAN)
- #include "flexcop_ibi_value_be.h"
+#include "flexcop_ibi_value_be.h"
#else
- #error no endian defined
+#error no endian defined
#endif
#endif
diff --git a/drivers/media/dvb/b2c2/flexcop-sram.c b/drivers/media/dvb/b2c2/flexcop-sram.c
index cda69528548a..f2199e43e803 100644
--- a/drivers/media/dvb/b2c2/flexcop-sram.c
+++ b/drivers/media/dvb/b2c2/flexcop-sram.c
@@ -1,45 +1,43 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-sram.c - functions for controlling the SRAM.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-sram.c - functions for controlling the SRAM
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
-static void flexcop_sram_set_chip (struct flexcop_device *fc, flexcop_sram_type_t type)
+static void flexcop_sram_set_chip(struct flexcop_device *fc,
+ flexcop_sram_type_t type)
{
- flexcop_set_ibi_value(wan_ctrl_reg_71c,sram_chip,type);
+ flexcop_set_ibi_value(wan_ctrl_reg_71c, sram_chip, type);
}
int flexcop_sram_init(struct flexcop_device *fc)
{
switch (fc->rev) {
- case FLEXCOP_II:
- case FLEXCOP_IIB:
- flexcop_sram_set_chip(fc,FC_SRAM_1_32KB);
- break;
- case FLEXCOP_III:
- flexcop_sram_set_chip(fc,FC_SRAM_1_48KB);
- break;
- default:
- return -EINVAL;
+ case FLEXCOP_II:
+ case FLEXCOP_IIB:
+ flexcop_sram_set_chip(fc, FC_SRAM_1_32KB);
+ break;
+ case FLEXCOP_III:
+ flexcop_sram_set_chip(fc, FC_SRAM_1_48KB);
+ break;
+ default:
+ return -EINVAL;
}
return 0;
}
-int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target)
+int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
+ flexcop_sram_dest_target_t target)
{
flexcop_ibi_value v;
-
- v = fc->read_ibi_reg(fc,sram_dest_reg_714);
+ v = fc->read_ibi_reg(fc, sram_dest_reg_714);
if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) {
err("SRAM destination target to available on FlexCopII(b)\n");
return -EINVAL;
}
-
- deb_sram("sram dest: %x target: %x\n",dest, target);
+ deb_sram("sram dest: %x target: %x\n", dest, target);
if (dest & FC_SRAM_DEST_NET)
v.sram_dest_reg_714.NET_Dest = target;
@@ -154,14 +152,12 @@ static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len
else
bank = 0x10000000;
}
-
flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
}
static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
{
u32 bank;
-
bank = 0;
if (adapter->dw_sram_type == 0x20000) {
@@ -174,26 +170,22 @@ static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
else
bank = 0x10000000;
}
-
flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
}
static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
{
u32 length;
-
while (len != 0) {
length = len;
-
- // check if the address range belongs to the same
- // 32K memory chip. If not, the data is read from
- // one chip at a time.
+ /* check if the address range belongs to the same
+ * 32K memory chip. If not, the data is read
+ * from one chip at a time */
if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
}
sram_read_chunk(adapter, addr, buf, length);
-
addr = addr + length;
buf = buf + length;
len = len - length;
@@ -203,19 +195,17 @@ static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
{
u32 length;
-
while (len != 0) {
length = len;
- // check if the address range belongs to the same
- // 32K memory chip. If not, the data is written to
- // one chip at a time.
+ /* check if the address range belongs to the same
+ * 32K memory chip. If not, the data is
+ * written to one chip at a time */
if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
}
sram_write_chunk(adapter, addr, buf, length);
-
addr = addr + length;
buf = buf + length;
len = len - length;
@@ -224,39 +214,29 @@ static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
static void sram_set_size(struct adapter *adapter, u32 mask)
{
- write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
+ write_reg_dw(adapter, 0x71c,
+ (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
}
static void sram_init(struct adapter *adapter)
{
u32 tmp;
-
tmp = read_reg_dw(adapter, 0x71c);
-
write_reg_dw(adapter, 0x71c, 1);
if (read_reg_dw(adapter, 0x71c) != 0) {
write_reg_dw(adapter, 0x71c, tmp);
-
adapter->dw_sram_type = tmp & 0x30000;
-
ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
-
} else {
-
adapter->dw_sram_type = 0x10000;
-
ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
}
-
- /* return value is never used? */
-/* return adapter->dw_sram_type; */
}
static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
{
u8 tmp1, tmp2;
-
dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr);
sram_set_size(adapter, mask);
@@ -269,7 +249,6 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
sram_write(adapter, addr + 4, &tmp1, 1);
tmp2 = 0;
-
mdelay(20);
sram_read(adapter, addr, &tmp2, 1);
@@ -287,7 +266,6 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
sram_write(adapter, addr + 4, &tmp1, 1);
tmp2 = 0;
-
mdelay(20);
sram_read(adapter, addr, &tmp2, 1);
@@ -297,26 +275,24 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
if (tmp2 != 0x5a)
return 0;
-
return 1;
}
static u32 sram_length(struct adapter *adapter)
{
if (adapter->dw_sram_type == 0x10000)
- return 32768; // 32K
+ return 32768; /* 32K */
if (adapter->dw_sram_type == 0x00000)
- return 65536; // 64K
+ return 65536; /* 64K */
if (adapter->dw_sram_type == 0x20000)
- return 131072; // 128K
-
- return 32768; // 32K
+ return 131072; /* 128K */
+ return 32768; /* 32K */
}
/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
- - for 128K there are 4x32K chips at bank 0,1,2,3.
- - for 64K there are 2x32K chips at bank 1,2.
- - for 32K there is one 32K chip at bank 0.
+ - for 128K there are 4x32K chips at bank 0,1,2,3.
+ - for 64K there are 2x32K chips at bank 1,2.
+ - for 32K there is one 32K chip at bank 0.
FlexCop works only with one bank at a time. The bank is selected
by bits 28-29 of the 0x700 register.
@@ -324,24 +300,18 @@ static u32 sram_length(struct adapter *adapter)
bank 0 covers addresses 0x00000-0x07fff
bank 1 covers addresses 0x08000-0x0ffff
bank 2 covers addresses 0x10000-0x17fff
- bank 3 covers addresses 0x18000-0x1ffff
-*/
+ bank 3 covers addresses 0x18000-0x1ffff */
static int flexcop_sram_detect(struct flexcop_device *fc)
{
- flexcop_ibi_value r208,r71c_0,vr71c_1;
-
+ flexcop_ibi_value r208, r71c_0, vr71c_1;
r208 = fc->read_ibi_reg(fc, ctrl_208);
fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c);
-
write_reg_dw(adapter, 0x71c, 1);
-
tmp3 = read_reg_dw(adapter, 0x71c);
-
dprintk("%s: tmp3 = %x\n", __func__, tmp3);
-
write_reg_dw(adapter, 0x71c, tmp2);
// check for internal SRAM ???
@@ -350,9 +320,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x10000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 32K\n", __func__);
-
return 32;
}
@@ -360,9 +328,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x20000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 128K\n", __func__);
-
return 128;
}
@@ -370,9 +336,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x00000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 64K\n", __func__);
-
return 64;
}
@@ -380,18 +344,14 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x10000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 32K\n", __func__);
-
return 32;
}
sram_set_size(adapter, 0x10000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: SRAM detection failed. Set to 32K \n", __func__);
-
return 0;
}
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c
index ae0d76a5d51d..bedcfb671624 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -1,11 +1,8 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-usb.c - covers the USB part.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-usb.c - covers the USB part
+ * see flexcop.c for copyright information
*/
-
#define FC_LOG_PREFIX "flexcop_usb"
#include "flexcop-usb.h"
#include "flexcop-common.h"
@@ -18,42 +15,47 @@
/* debug */
#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
#define dprintk(level,args...) \
- do { if ((debug & level)) { printk(args); } } while (0)
-#define debug_dump(b,l,method) {\
+ do { if ((debug & level)) printk(args); } while (0)
+
+#define debug_dump(b, l, method) do {\
int i; \
- for (i = 0; i < l; i++) method("%02x ", b[i]); \
- method("\n");\
-}
+ for (i = 0; i < l; i++) \
+ method("%02x ", b[i]); \
+ method("\n"); \
+} while (0)
#define DEBSTATUS ""
#else
-#define dprintk(level,args...)
-#define debug_dump(b,l,method)
+#define dprintk(level, args...)
+#define debug_dump(b, l, method)
#define DEBSTATUS " (debugging is not enabled)"
#endif
static int debug;
module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,"
+ "ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS);
#undef DEBSTATUS
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_ts(args...) dprintk(0x02,args)
-#define deb_ctrl(args...) dprintk(0x04,args)
-#define deb_i2c(args...) dprintk(0x08,args)
-#define deb_v8(args...) dprintk(0x10,args)
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_ts(args...) dprintk(0x02, args)
+#define deb_ctrl(args...) dprintk(0x04, args)
+#define deb_i2c(args...) dprintk(0x08, args)
+#define deb_v8(args...) dprintk(0x10, args)
/* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits
* in the IBI address, to make the V8 code simpler.
- * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used)
+ * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (the six bits used)
* in general: 0000 0HHH 000L LL00
* IBI ADDRESS FORMAT: RHHH BLLL
*
* where R is the read(1)/write(0) bit, B is the busy bit
* and HHH and LLL are the two sets of three bits from the PCI address.
*/
-#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
-#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
+#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) \
+ (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
+#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) \
+ (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
/*
* DKT 020228
@@ -69,12 +71,13 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI,
struct flexcop_usb *fc_usb = fc->bus_specific;
u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG;
u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR;
- u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | (read ? 0x80 : 0);
+ u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) |
+ (read ? 0x80 : 0);
int len = usb_control_msg(fc_usb->udev,
read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT,
request,
- request_type, /* 0xc0 read or 0x40 write*/
+ request_type, /* 0xc0 read or 0x40 write */
wAddress,
0,
val,
@@ -82,55 +85,49 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI,
B2C2_WAIT_FOR_OPERATION_RDW * HZ);
if (len != sizeof(u32)) {
- err("error while %s dword from %d (%d).",read ? "reading" : "writing",
- wAddress,wRegOffsPCI);
+ err("error while %s dword from %d (%d).", read ? "reading" :
+ "writing", wAddress, wRegOffsPCI);
return -EIO;
}
return 0;
}
-
/*
* DKT 010817 - add support for V8 memory read/write and flash update
*/
static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
flexcop_usb_request_t req, u8 page, u16 wAddress,
- u8 *pbBuffer,u32 buflen)
+ u8 *pbBuffer, u32 buflen)
{
-// u8 dwRequestType;
u8 request_type = USB_TYPE_VENDOR;
u16 wIndex;
- int nWaitTime,pipe,len;
-
+ int nWaitTime, pipe, len;
wIndex = page << 8;
switch (req) {
- case B2C2_USB_READ_V8_MEM:
- nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
- request_type |= USB_DIR_IN;
-// dwRequestType = (u8) RTYPE_READ_V8_MEMORY;
- pipe = B2C2_USB_CTRL_PIPE_IN;
+ case B2C2_USB_READ_V8_MEM:
+ nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
+ request_type |= USB_DIR_IN;
+ pipe = B2C2_USB_CTRL_PIPE_IN;
break;
- case B2C2_USB_WRITE_V8_MEM:
- wIndex |= pbBuffer[0];
- request_type |= USB_DIR_OUT;
- nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
-// dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY;
- pipe = B2C2_USB_CTRL_PIPE_OUT;
+ case B2C2_USB_WRITE_V8_MEM:
+ wIndex |= pbBuffer[0];
+ request_type |= USB_DIR_OUT;
+ nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
+ pipe = B2C2_USB_CTRL_PIPE_OUT;
break;
- case B2C2_USB_FLASH_BLOCK:
- request_type |= USB_DIR_OUT;
- nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
-// dwRequestType = (u8) RTYPE_WRITE_V8_FLASH;
- pipe = B2C2_USB_CTRL_PIPE_OUT;
+ case B2C2_USB_FLASH_BLOCK:
+ request_type |= USB_DIR_OUT;
+ nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
+ pipe = B2C2_USB_CTRL_PIPE_OUT;
break;
- default:
- deb_info("unsupported request for v8_mem_req %x.\n",req);
+ default:
+ deb_info("unsupported request for v8_mem_req %x.\n", req);
return -EINVAL;
}
- deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n",request_type,req,
- wAddress,wIndex,buflen);
+ deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req,
+ wAddress, wIndex, buflen);
- len = usb_control_msg(fc_usb->udev,pipe,
+ len = usb_control_msg(fc_usb->udev, pipe,
req,
request_type,
wAddress,
@@ -139,39 +136,53 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
buflen,
nWaitTime * HZ);
- debug_dump(pbBuffer,len,deb_v8);
-
+ debug_dump(pbBuffer, len, deb_v8);
return len == buflen ? 0 : -EIO;
}
#define bytes_left_to_read_on_page(paddr,buflen) \
- ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
- ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
+ ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
+ ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
-static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request_t req,
- flexcop_usb_mem_page_t page_start, u32 addr, int extended, u8 *buf, u32 len)
+static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,
+ flexcop_usb_request_t req, flexcop_usb_mem_page_t page_start,
+ u32 addr, int extended, u8 *buf, u32 len)
{
int i,ret = 0;
u16 wMax;
u32 pagechunk = 0;
switch(req) {
- case B2C2_USB_READ_V8_MEM: wMax = USB_MEM_READ_MAX; break;
- case B2C2_USB_WRITE_V8_MEM: wMax = USB_MEM_WRITE_MAX; break;
- case B2C2_USB_FLASH_BLOCK: wMax = USB_FLASH_MAX; break;
- default:
- return -EINVAL;
+ case B2C2_USB_READ_V8_MEM:
+ wMax = USB_MEM_READ_MAX;
+ break;
+ case B2C2_USB_WRITE_V8_MEM:
+ wMax = USB_MEM_WRITE_MAX;
+ break;
+ case B2C2_USB_FLASH_BLOCK:
+ wMax = USB_FLASH_MAX;
+ break;
+ default:
+ return -EINVAL;
break;
}
for (i = 0; i < len;) {
- pagechunk = wMax < bytes_left_to_read_on_page(addr,len) ? wMax : bytes_left_to_read_on_page(addr,len);
- deb_info("%x\n",(addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended));
- if ((ret = flexcop_usb_v8_memory_req(fc_usb,req,
- page_start + (addr / V8_MEMORY_PAGE_SIZE), /* actual page */
- (addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended),
- &buf[i],pagechunk)) < 0)
+ pagechunk =
+ wMax < bytes_left_to_read_on_page(addr, len) ?
+ wMax :
+ bytes_left_to_read_on_page(addr, len);
+ deb_info("%x\n",
+ (addr & V8_MEMORY_PAGE_MASK) |
+ (V8_MEMORY_EXTENDED*extended));
+
+ ret = flexcop_usb_v8_memory_req(fc_usb, req,
+ page_start + (addr / V8_MEMORY_PAGE_SIZE),
+ (addr & V8_MEMORY_PAGE_MASK) |
+ (V8_MEMORY_EXTENDED*extended),
+ &buf[i], pagechunk);
+
+ if (ret < 0)
return ret;
-
addr += pagechunk;
len -= pagechunk;
}
@@ -180,8 +191,9 @@ static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request
static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended)
{
- return flexcop_usb_memory_req(fc->bus_specific,B2C2_USB_READ_V8_MEM,
- V8_MEMORY_PAGE_FLASH,0x1f010,1,fc->dvb_adapter.proposed_mac,6);
+ return flexcop_usb_memory_req(fc->bus_specific, B2C2_USB_READ_V8_MEM,
+ V8_MEMORY_PAGE_FLASH, 0x1f010, 1,
+ fc->dvb_adapter.proposed_mac, 6);
}
#if 0
@@ -191,11 +203,8 @@ static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set,
{
u16 wValue;
u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR;
-// u8 dwRequestType = (u8) RTYPE_GENERIC,
int nWaitTime = 2,
- pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN,
- len;
-
+ pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, len;
wValue = (func << 8) | extra;
len = usb_control_msg(fc_usb->udev,pipe,
@@ -218,36 +227,35 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
struct flexcop_usb *fc_usb = i2c->fc->bus_specific;
u16 wValue, wIndex;
int nWaitTime,pipe,len;
-// u8 dwRequestType;
u8 request_type = USB_TYPE_VENDOR;
switch (func) {
- case USB_FUNC_I2C_WRITE:
- case USB_FUNC_I2C_MULTIWRITE:
- case USB_FUNC_I2C_REPEATWRITE:
+ case USB_FUNC_I2C_WRITE:
+ case USB_FUNC_I2C_MULTIWRITE:
+ case USB_FUNC_I2C_REPEATWRITE:
/* DKT 020208 - add this to support special case of DiSEqC */
- case USB_FUNC_I2C_CHECKWRITE:
- pipe = B2C2_USB_CTRL_PIPE_OUT;
- nWaitTime = 2;
-// dwRequestType = (u8) RTYPE_GENERIC;
- request_type |= USB_DIR_OUT;
+ case USB_FUNC_I2C_CHECKWRITE:
+ pipe = B2C2_USB_CTRL_PIPE_OUT;
+ nWaitTime = 2;
+ request_type |= USB_DIR_OUT;
break;
- case USB_FUNC_I2C_READ:
- case USB_FUNC_I2C_REPEATREAD:
- pipe = B2C2_USB_CTRL_PIPE_IN;
- nWaitTime = 2;
-// dwRequestType = (u8) RTYPE_GENERIC;
- request_type |= USB_DIR_IN;
+ case USB_FUNC_I2C_READ:
+ case USB_FUNC_I2C_REPEATREAD:
+ pipe = B2C2_USB_CTRL_PIPE_IN;
+ nWaitTime = 2;
+ request_type |= USB_DIR_IN;
break;
- default:
- deb_info("unsupported function for i2c_req %x\n",func);
- return -EINVAL;
+ default:
+ deb_info("unsupported function for i2c_req %x\n", func);
+ return -EINVAL;
}
wValue = (func << 8) | (i2c->port << 4);
wIndex = (chipaddr << 8 ) | addr;
- deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req,
- wValue & 0xff, wValue >> 8, wIndex & 0xff, wIndex >> 8);
+ deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",
+ func, request_type, req,
+ wValue & 0xff, wValue >> 8,
+ wIndex & 0xff, wIndex >> 8);
len = usb_control_msg(fc_usb->udev,pipe,
req,
@@ -257,44 +265,49 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
buf,
buflen,
nWaitTime * HZ);
-
return len == buflen ? 0 : -EREMOTEIO;
}
-/* actual bus specific access functions, make sure prototype are/will be equal to pci */
-static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg)
+/* actual bus specific access functions,
+ make sure prototype are/will be equal to pci */
+static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc,
+ flexcop_ibi_register reg)
{
flexcop_ibi_value val;
val.raw = 0;
- flexcop_usb_readwrite_dw(fc,reg, &val.raw, 1);
+ flexcop_usb_readwrite_dw(fc, reg, &val.raw, 1);
return val;
}
-static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg, flexcop_ibi_value val)
+static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc,
+ flexcop_ibi_register reg, flexcop_ibi_value val)
{
- return flexcop_usb_readwrite_dw(fc,reg, &val.raw, 0);
+ return flexcop_usb_readwrite_dw(fc, reg, &val.raw, 0);
}
static int flexcop_usb_i2c_request(struct flexcop_i2c_adapter *i2c,
- flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+ flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
{
if (op == FC_READ)
return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
- USB_FUNC_I2C_READ, chipaddr, addr, buf, len);
+ USB_FUNC_I2C_READ, chipaddr, addr, buf, len);
else
return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
- USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len);
+ USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len);
}
-static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length)
+static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb,
+ u8 *buffer, int buffer_length)
{
u8 *b;
int l;
- deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", fc_usb->tmp_buffer_length, buffer_length);
+ deb_ts("tmp_buffer_length=%d, buffer_length=%d\n",
+ fc_usb->tmp_buffer_length, buffer_length);
if (fc_usb->tmp_buffer_length > 0) {
- memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, buffer_length);
+ memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer,
+ buffer_length);
fc_usb->tmp_buffer_length += buffer_length;
b = fc_usb->tmp_buffer;
l = fc_usb->tmp_buffer_length;
@@ -304,23 +317,26 @@ static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, in
}
while (l >= 190) {
- if (*b == 0xff)
+ if (*b == 0xff) {
switch (*(b+1) & 0x03) {
- case 0x01: /* media packet */
- if ( *(b+2) == 0x47 )
- flexcop_pass_dmx_packets(fc_usb->fc_dev, b+2, 1);
- else
- deb_ts("not ts packet %02x %02x %02x %02x \n", *(b+2), *(b+3), *(b+4), *(b+5) );
-
- b += 190;
- l -= 190;
+ case 0x01: /* media packet */
+ if (*(b+2) == 0x47)
+ flexcop_pass_dmx_packets(
+ fc_usb->fc_dev, b+2, 1);
+ else
+ deb_ts(
+ "not ts packet %02x %02x %02x %02x \n",
+ *(b+2), *(b+3),
+ *(b+4), *(b+5));
+ b += 190;
+ l -= 190;
break;
- default:
- deb_ts("wrong packet type\n");
- l = 0;
+ default:
+ deb_ts("wrong packet type\n");
+ l = 0;
break;
}
- else {
+ } else {
deb_ts("wrong header\n");
l = 0;
}
@@ -337,23 +353,26 @@ static void flexcop_usb_urb_complete(struct urb *urb)
int i;
if (urb->actual_length > 0)
- deb_ts("urb completed, bufsize: %d actlen; %d\n",urb->transfer_buffer_length, urb->actual_length);
+ deb_ts("urb completed, bufsize: %d actlen; %d\n",
+ urb->transfer_buffer_length, urb->actual_length);
for (i = 0; i < urb->number_of_packets; i++) {
if (urb->iso_frame_desc[i].status < 0) {
- err("iso frame descriptor %d has an error: %d\n",i,urb->iso_frame_desc[i].status);
+ err("iso frame descriptor %d has an error: %d\n", i,
+ urb->iso_frame_desc[i].status);
} else
if (urb->iso_frame_desc[i].actual_length > 0) {
- deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length);
+ deb_ts("passed %d bytes to the demux\n",
+ urb->iso_frame_desc[i].actual_length);
flexcop_usb_process_frame(fc_usb,
- urb->transfer_buffer + urb->iso_frame_desc[i].offset,
+ urb->transfer_buffer +
+ urb->iso_frame_desc[i].offset,
urb->iso_frame_desc[i].actual_length);
- }
+ }
urb->iso_frame_desc[i].status = 0;
urb->iso_frame_desc[i].actual_length = 0;
}
-
usb_submit_urb(urb,GFP_ATOMIC);
}
@@ -374,35 +393,47 @@ static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb)
}
if (fc_usb->iso_buffer != NULL)
- pci_free_consistent(NULL,fc_usb->buffer_size, fc_usb->iso_buffer, fc_usb->dma_addr);
+ pci_free_consistent(NULL,
+ fc_usb->buffer_size, fc_usb->iso_buffer,
+ fc_usb->dma_addr);
}
static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
{
- u16 frame_size = le16_to_cpu(fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
- int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret;
+ u16 frame_size = le16_to_cpu(
+ fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
+ int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO *
+ frame_size, i, j, ret;
int buffer_offset = 0;
- deb_ts("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n",
- B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize);
+ deb_ts("creating %d iso-urbs with %d frames "
+ "each of %d bytes size = %d.\n", B2C2_USB_NUM_ISO_URB,
+ B2C2_USB_FRAMES_PER_ISO, frame_size, bufsize);
- fc_usb->iso_buffer = pci_alloc_consistent(NULL,bufsize,&fc_usb->dma_addr);
+ fc_usb->iso_buffer = pci_alloc_consistent(NULL,
+ bufsize, &fc_usb->dma_addr);
if (fc_usb->iso_buffer == NULL)
return -ENOMEM;
+
memset(fc_usb->iso_buffer, 0, bufsize);
fc_usb->buffer_size = bufsize;
/* creating iso urbs */
- for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
- if (!(fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) {
+ for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
+ fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,
+ GFP_ATOMIC);
+ if (fc_usb->iso_urb[i] == NULL) {
ret = -ENOMEM;
goto urb_error;
}
+ }
+
/* initialising and submitting iso urbs */
for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
int frame_offset = 0;
struct urb *urb = fc_usb->iso_urb[i];
- deb_ts("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
+ deb_ts("initializing and submitting urb no. %d "
+ "(buf_offset: %d).\n", i, buffer_offset);
urb->dev = fc_usb->udev;
urb->context = fc_usb;
@@ -416,26 +447,26 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO;
for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) {
- deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset);
+ deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",
+ i, j, frame_offset);
urb->iso_frame_desc[j].offset = frame_offset;
urb->iso_frame_desc[j].length = frame_size;
frame_offset += frame_size;
}
if ((ret = usb_submit_urb(fc_usb->iso_urb[i],GFP_ATOMIC))) {
- err("submitting urb %d failed with %d.",i,ret);
+ err("submitting urb %d failed with %d.", i, ret);
goto urb_error;
}
deb_ts("submitted urb no. %d.\n",i);
}
-/* SRAM */
-
- flexcop_sram_set_dest(fc_usb->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET |
- FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_WAN_USB);
- flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS);
- flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1);
-
+ /* SRAM */
+ flexcop_sram_set_dest(fc_usb->fc_dev, FC_SRAM_DEST_MEDIA |
+ FC_SRAM_DEST_NET | FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI,
+ FC_SRAM_DEST_TARGET_WAN_USB);
+ flexcop_wan_set_speed(fc_usb->fc_dev, FC_WAN_SPEED_8MBITS);
+ flexcop_sram_ctrl(fc_usb->fc_dev, 1, 1, 1);
return 0;
urb_error:
@@ -448,20 +479,20 @@ static int flexcop_usb_init(struct flexcop_usb *fc_usb)
/* use the alternate setting with the larges buffer */
usb_set_interface(fc_usb->udev,0,1);
switch (fc_usb->udev->speed) {
- case USB_SPEED_LOW:
- err("cannot handle USB speed because it is to sLOW.");
- return -ENODEV;
- break;
- case USB_SPEED_FULL:
- info("running at FULL speed.");
- break;
- case USB_SPEED_HIGH:
- info("running at HIGH speed.");
- break;
- case USB_SPEED_UNKNOWN: /* fall through */
- default:
- err("cannot handle USB speed because it is unkown.");
- return -ENODEV;
+ case USB_SPEED_LOW:
+ err("cannot handle USB speed because it is too slow.");
+ return -ENODEV;
+ break;
+ case USB_SPEED_FULL:
+ info("running at FULL speed.");
+ break;
+ case USB_SPEED_HIGH:
+ info("running at HIGH speed.");
+ break;
+ case USB_SPEED_UNKNOWN: /* fall through */
+ default:
+ err("cannot handle USB speed because it is unknown.");
+ return -ENODEV;
}
usb_set_intfdata(fc_usb->uintf, fc_usb);
return 0;
@@ -485,7 +516,7 @@ static int flexcop_usb_probe(struct usb_interface *intf,
return -ENOMEM;
}
-/* general flexcop init */
+ /* general flexcop init */
fc_usb = fc->bus_specific;
fc_usb->fc_dev = fc;
@@ -502,21 +533,21 @@ static int flexcop_usb_probe(struct usb_interface *intf,
fc->dev = &udev->dev;
fc->owner = THIS_MODULE;
-/* bus specific part */
+ /* bus specific part */
fc_usb->udev = udev;
fc_usb->uintf = intf;
if ((ret = flexcop_usb_init(fc_usb)) != 0)
goto err_kfree;
-/* init flexcop */
+ /* init flexcop */
if ((ret = flexcop_device_initialize(fc)) != 0)
goto err_usb_exit;
-/* xfer init */
+ /* xfer init */
if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0)
goto err_fc_exit;
- info("%s successfully initialized and connected.",DRIVER_NAME);
+ info("%s successfully initialized and connected.", DRIVER_NAME);
return 0;
err_fc_exit:
@@ -535,12 +566,12 @@ static void flexcop_usb_disconnect(struct usb_interface *intf)
flexcop_device_exit(fc_usb->fc_dev);
flexcop_usb_exit(fc_usb);
flexcop_device_kfree(fc_usb->fc_dev);
- info("%s successfully deinitialized and disconnected.",DRIVER_NAME);
+ info("%s successfully deinitialized and disconnected.", DRIVER_NAME);
}
static struct usb_device_id flexcop_usb_table [] = {
- { USB_DEVICE(0x0af7, 0x0101) },
- { }
+ { USB_DEVICE(0x0af7, 0x0101) },
+ { }
};
MODULE_DEVICE_TABLE (usb, flexcop_usb_table);
@@ -557,10 +588,9 @@ static int __init flexcop_usb_module_init(void)
{
int result;
if ((result = usb_register(&flexcop_usb_driver))) {
- err("usb_register failed. (%d)",result);
+ err("usb_register failed. (%d)", result);
return result;
}
-
return 0;
}
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.h b/drivers/media/dvb/b2c2/flexcop-usb.h
index 630e647a2caa..92529a9c4475 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.h
+++ b/drivers/media/dvb/b2c2/flexcop-usb.h
@@ -1,15 +1,20 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-usb.h - header file for the USB part
+ * see flexcop.c for copyright information
+ */
#ifndef __FLEXCOP_USB_H_INCLUDED__
#define __FLEXCOP_USB_H_INCLUDED__
#include <linux/usb.h>
/* transfer parameters */
-#define B2C2_USB_FRAMES_PER_ISO 4
-#define B2C2_USB_NUM_ISO_URB 4
+#define B2C2_USB_FRAMES_PER_ISO 4
+#define B2C2_USB_NUM_ISO_URB 4
-#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev,0)
-#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev,0)
-#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev,0x81)
+#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev, 0)
+#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev, 0)
+#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev, 0x81)
struct flexcop_usb {
struct usb_device *udev;
@@ -18,8 +23,8 @@ struct flexcop_usb {
u8 *iso_buffer;
int buffer_size;
dma_addr_t dma_addr;
- struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
+ struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
struct flexcop_device *fc_dev;
u8 tmp_buffer[1023+190];
@@ -30,14 +35,6 @@ struct flexcop_usb {
/* request types TODO What is its use?*/
typedef enum {
-/* something is wrong with this part
- RTYPE_READ_DW = (1 << 6),
- RTYPE_WRITE_DW_1 = (3 << 6),
- RTYPE_READ_V8_MEMORY = (6 << 6),
- RTYPE_WRITE_V8_MEMORY = (7 << 6),
- RTYPE_WRITE_V8_FLASH = (8 << 6),
- RTYPE_GENERIC = (9 << 6),
-*/
} flexcop_usb_request_type_t;
#endif
@@ -47,7 +44,6 @@ typedef enum {
B2C2_USB_READ_V8_MEM = 0x05,
B2C2_USB_READ_REG = 0x08,
B2C2_USB_WRITE_REG = 0x0A,
-/* B2C2_USB_WRITEREGLO = 0x0A, */
B2C2_USB_WRITEREGHI = 0x0B,
B2C2_USB_FLASH_BLOCK = 0x10,
B2C2_USB_I2C_REQUEST = 0x11,
@@ -62,15 +58,13 @@ typedef enum {
USB_FUNC_I2C_REPEATWRITE = 0x04,
USB_FUNC_GET_DESCRIPTOR = 0x05,
USB_FUNC_I2C_REPEATREAD = 0x06,
-/* DKT 020208 - add this to support special case of DiSEqC */
+ /* DKT 020208 - add this to support special case of DiSEqC */
USB_FUNC_I2C_CHECKWRITE = 0x07,
USB_FUNC_I2C_CHECKRESULT = 0x08,
} flexcop_usb_i2c_function_t;
-/*
- * function definition for UTILITY request 0x12
- * DKT 020304 - new utility function
- */
+/* function definition for UTILITY request 0x12
+ * DKT 020304 - new utility function */
typedef enum {
UTILITY_SET_FILTER = 0x01,
UTILITY_DATA_ENABLE = 0x02,
@@ -84,7 +78,7 @@ typedef enum {
UTILITY_DATA_RESET = 0x0A,
UTILITY_GET_DATA_STATUS = 0x10,
UTILITY_GET_V8_REG = 0x11,
-/* DKT 020326 - add function for v1.14 */
+ /* DKT 020326 - add function for v1.14 */
UTILITY_SRAM_WRITE = 0x12,
UTILITY_SRAM_READ = 0x13,
UTILITY_SRAM_TESTFILL = 0x14,
@@ -92,13 +86,13 @@ typedef enum {
UTILITY_SRAM_TESTVERIFY = 0x16,
} flexcop_usb_utility_function_t;
-#define B2C2_WAIT_FOR_OPERATION_RW 1*HZ /* 1 s */
-#define B2C2_WAIT_FOR_OPERATION_RDW 3*HZ /* 3 s */
-#define B2C2_WAIT_FOR_OPERATION_WDW 1*HZ /* 1 s */
+#define B2C2_WAIT_FOR_OPERATION_RW (1*HZ)
+#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ)
-#define B2C2_WAIT_FOR_OPERATION_V8READ 3*HZ /* 3 s */
-#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3*HZ /* 3 s */
-#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3*HZ /* 3 s */
+#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ)
typedef enum {
V8_MEMORY_PAGE_DVB_CI = 0x20,
@@ -107,13 +101,11 @@ typedef enum {
V8_MEMORY_PAGE_FLASH = 0x80
} flexcop_usb_mem_page_t;
-#define V8_MEMORY_EXTENDED (1 << 15)
-
-#define USB_MEM_READ_MAX 32
-#define USB_MEM_WRITE_MAX 1
-#define USB_FLASH_MAX 8
-
-#define V8_MEMORY_PAGE_SIZE 0x8000 // 32K
-#define V8_MEMORY_PAGE_MASK 0x7FFF
+#define V8_MEMORY_EXTENDED (1 << 15)
+#define USB_MEM_READ_MAX 32
+#define USB_MEM_WRITE_MAX 1
+#define USB_FLASH_MAX 8
+#define V8_MEMORY_PAGE_SIZE 0x8000 /* 32K */
+#define V8_MEMORY_PAGE_MASK 0x7FFF
#endif
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
index 91068952b502..2df1b0214dcd 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -1,22 +1,20 @@
/*
- * flexcop.c - driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * Copyright (C) 2004-5 Patrick Boettcher <patrick.boettcher@desy.de>
- *
- * based on the skystar2-driver
- * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop.c - main module part
+ * Copyright (C) 2004-9 Patrick Boettcher <patrick.boettcher@desy.de>
+ * based on skystar2-driver Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
*
* Acknowledgements:
- * John Jurrius from BBTI, Inc. for extensive support with
- * code examples and data books
- *
- * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
+ * John Jurrius from BBTI, Inc. for extensive support
+ * with code examples and data books
+ * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
*
* Contributions to the skystar2-driver have been done by
- * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
- * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
- * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac filtering)
- *
+ * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
+ * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
+ * Uwe Bugla, uwe.bugla at gmx.de (doing tests, restyling code, writing docu)
+ * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac
+ * filtering)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -46,7 +44,10 @@
int b2c2_flexcop_debug;
module_param_named(debug, b2c2_flexcop_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS);
+MODULE_PARM_DESC(debug,
+ "set debug level (1=info,2=tuner,4=i2c,8=ts,"
+ "16=sram,32=reg (|-able))."
+ DEBSTATUS);
#undef DEBSTATUS
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
@@ -57,37 +58,36 @@ flexcop_ibi_value ibi_zero;
static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
{
struct flexcop_device *fc = dvbdmxfeed->demux->priv;
- return flexcop_pid_feed_control(fc,dvbdmxfeed,1);
+ return flexcop_pid_feed_control(fc, dvbdmxfeed, 1);
}
static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
{
struct flexcop_device *fc = dvbdmxfeed->demux->priv;
- return flexcop_pid_feed_control(fc,dvbdmxfeed,0);
+ return flexcop_pid_feed_control(fc, dvbdmxfeed, 0);
}
static int flexcop_dvb_init(struct flexcop_device *fc)
{
int ret = dvb_register_adapter(&fc->dvb_adapter,
- "FlexCop Digital TV device", fc->owner,
- fc->dev, adapter_nr);
+ "FlexCop Digital TV device", fc->owner,
+ fc->dev, adapter_nr);
if (ret < 0) {
err("error registering DVB adapter");
return ret;
}
fc->dvb_adapter.priv = fc;
- fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
+ fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING
+ | DMX_MEMORY_BASED_FILTERING);
fc->demux.priv = fc;
-
fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED;
-
fc->demux.start_feed = flexcop_dvb_start_feed;
fc->demux.stop_feed = flexcop_dvb_stop_feed;
fc->demux.write_to_decoder = NULL;
if ((ret = dvb_dmx_init(&fc->demux)) < 0) {
- err("dvb_dmx failed: error %d",ret);
+ err("dvb_dmx failed: error %d", ret);
goto err_dmx;
}
@@ -97,23 +97,23 @@ static int flexcop_dvb_init(struct flexcop_device *fc)
fc->dmxdev.demux = &fc->demux.dmx;
fc->dmxdev.capabilities = 0;
if ((ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter)) < 0) {
- err("dvb_dmxdev_init failed: error %d",ret);
+ err("dvb_dmxdev_init failed: error %d", ret);
goto err_dmx_dev;
}
if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) {
- err("adding hw_frontend to dmx failed: error %d",ret);
+ err("adding hw_frontend to dmx failed: error %d", ret);
goto err_dmx_add_hw_frontend;
}
fc->mem_frontend.source = DMX_MEMORY_FE;
if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend)) < 0) {
- err("adding mem_frontend to dmx failed: error %d",ret);
+ err("adding mem_frontend to dmx failed: error %d", ret);
goto err_dmx_add_mem_frontend;
}
if ((ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) {
- err("connect frontend failed: error %d",ret);
+ err("connect frontend failed: error %d", ret);
goto err_connect_frontend;
}
@@ -123,9 +123,9 @@ static int flexcop_dvb_init(struct flexcop_device *fc)
return 0;
err_connect_frontend:
- fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend);
+ fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->mem_frontend);
err_dmx_add_mem_frontend:
- fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend);
+ fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->hw_frontend);
err_dmx_add_hw_frontend:
dvb_dmxdev_release(&fc->dmxdev);
err_dmx_dev:
@@ -141,12 +141,13 @@ static void flexcop_dvb_exit(struct flexcop_device *fc)
dvb_net_release(&fc->dvbnet);
fc->demux.dmx.close(&fc->demux.dmx);
- fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend);
- fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend);
+ fc->demux.dmx.remove_frontend(&fc->demux.dmx,
+ &fc->mem_frontend);
+ fc->demux.dmx.remove_frontend(&fc->demux.dmx,
+ &fc->hw_frontend);
dvb_dmxdev_release(&fc->dmxdev);
dvb_dmx_release(&fc->demux);
dvb_unregister_adapter(&fc->dvb_adapter);
-
deb_info("deinitialized dvb stuff\n");
}
fc->init_state &= ~FC_STATE_DVB_INIT;
@@ -168,9 +169,9 @@ EXPORT_SYMBOL(flexcop_pass_dmx_packets);
static void flexcop_reset(struct flexcop_device *fc)
{
- flexcop_ibi_value v210,v204;
+ flexcop_ibi_value v210, v204;
-/* reset the flexcop itself */
+ /* reset the flexcop itself */
fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
v210.raw = 0;
@@ -183,13 +184,11 @@ static void flexcop_reset(struct flexcop_device *fc)
v210.sw_reset_210.reset_block_600 = 1;
v210.sw_reset_210.reset_block_700 = 1;
v210.sw_reset_210.Block_reset_enable = 0xb2;
-
v210.sw_reset_210.Special_controls = 0xc259;
-
fc->write_ibi_reg(fc,sw_reset_210,v210);
msleep(1);
-/* reset the periphical devices */
+ /* reset the periphical devices */
v204 = fc->read_ibi_reg(fc,misc_204);
v204.misc_204.Per_reset_sig = 0;
@@ -201,25 +200,24 @@ static void flexcop_reset(struct flexcop_device *fc)
void flexcop_reset_block_300(struct flexcop_device *fc)
{
- flexcop_ibi_value v208_save = fc->read_ibi_reg(fc,ctrl_208),
- v210 = fc->read_ibi_reg(fc,sw_reset_210);
-
- deb_rdump("208: %08x, 210: %08x\n",v208_save.raw,v210.raw);
+ flexcop_ibi_value v208_save = fc->read_ibi_reg(fc, ctrl_208),
+ v210 = fc->read_ibi_reg(fc, sw_reset_210);
+ deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw);
fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
v210.sw_reset_210.reset_block_300 = 1;
v210.sw_reset_210.Block_reset_enable = 0xb2;
fc->write_ibi_reg(fc,sw_reset_210,v210);
- udelay(1000);
fc->write_ibi_reg(fc,ctrl_208,v208_save);
}
struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
{
void *bus;
- struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device), GFP_KERNEL);
+ struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device),
+ GFP_KERNEL);
if (!fc) {
err("no memory");
return NULL;
@@ -254,7 +252,6 @@ int flexcop_device_initialize(struct flexcop_device *fc)
flexcop_determine_revision(fc);
flexcop_sram_init(fc);
flexcop_hw_filter_init(fc);
-
flexcop_smc_ctrl(fc, 0);
if ((ret = flexcop_dvb_init(fc)))
@@ -279,7 +276,6 @@ int flexcop_device_initialize(struct flexcop_device *fc)
goto error;
flexcop_device_name(fc,"initialization of","complete");
-
return 0;
error:
diff --git a/drivers/media/dvb/b2c2/flexcop.h b/drivers/media/dvb/b2c2/flexcop.h
index 0cebe1d92e0b..897b10c85ad9 100644
--- a/drivers/media/dvb/b2c2/flexcop.h
+++ b/drivers/media/dvb/b2c2/flexcop.h
@@ -1,9 +1,7 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop.h - private header file for all flexcop-chip-source files.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop.h - private header file for all flexcop-chip-source files
+ * see flexcop.c for copyright information
*/
#ifndef __FLEXCOP_H__
#define __FLEXCOP_H___
@@ -21,11 +19,11 @@ extern int b2c2_flexcop_debug;
#define dprintk(level,args...)
#endif
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_tuner(args...) dprintk(0x02,args)
-#define deb_i2c(args...) dprintk(0x04,args)
-#define deb_ts(args...) dprintk(0x08,args)
-#define deb_sram(args...) dprintk(0x10,args)
-#define deb_rdump(args...) dprintk(0x20,args)
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_tuner(args...) dprintk(0x02, args)
+#define deb_i2c(args...) dprintk(0x04, args)
+#define deb_ts(args...) dprintk(0x08, args)
+#define deb_sram(args...) dprintk(0x10, args)
+#define deb_rdump(args...) dprintk(0x20, args)
#endif
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
index ed9a6756b194..8f64bdbd72bb 100644
--- a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
@@ -1,10 +1,7 @@
-/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* register descriptions
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
*/
-
/* This file is automatically generated, do not edit things here. */
#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
#define __FLEXCOP_IBI_VALUE_INCLUDED__
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
index 49f2315b6e58..c75830d7d942 100644
--- a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
@@ -1,10 +1,7 @@
-/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* register descriptions
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
*/
-
/* This file is automatically generated, do not edit things here. */
#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
#define __FLEXCOP_IBI_VALUE_INCLUDED__
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index 27edb0ece587..8668e634c7ec 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -8,7 +8,7 @@ config DVB_BT8XX
select DVB_OR51211 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
help
Support for PCI cards based on the Bt8xx PCI bridge. Examples are
the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 0258451423ad..4601b059b2b2 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -552,16 +552,19 @@ free_mem_and_exit:
return result;
}
-static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg)
+static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioctl_arg)
{
- struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
- struct dst_state* state = (struct dst_state*) dvbdev->priv;
+ struct dvb_device *dvbdev;
+ struct dst_state *state;
struct ca_slot_info *p_ca_slot_info;
struct ca_caps *p_ca_caps;
struct ca_msg *p_ca_message;
void __user *arg = (void __user *)ioctl_arg;
int result = 0;
+ lock_kernel();
+ dvbdev = (struct dvb_device *)file->private_data;
+ state = (struct dst_state *)dvbdev->priv;
p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL);
p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL);
p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL);
@@ -647,6 +650,7 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
kfree (p_ca_slot_info);
kfree (p_ca_caps);
+ unlock_kernel();
return result;
}
@@ -682,9 +686,9 @@ static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t
return 0;
}
-static struct file_operations dst_ca_fops = {
+static const struct file_operations dst_ca_fops = {
.owner = THIS_MODULE,
- .ioctl = dst_ca_ioctl,
+ .unlocked_ioctl = dst_ca_ioctl,
.open = dst_ca_open,
.release = dst_ca_release,
.read = dst_ca_read,
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index 48762a2b9e42..b1857c19bbd2 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -814,7 +814,7 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub)
mutex_init(&card->lock);
card->bttv_nr = sub->core->nr;
- strncpy(card->card_name, sub->core->name, sizeof(sub->core->name));
+ strlcpy(card->card_name, sub->core->v4l2_dev.name, sizeof(card->card_name));
card->i2c_adapter = &sub->core->i2c_adap;
switch(sub->core->type) {
diff --git a/drivers/media/dvb/dm1105/Kconfig b/drivers/media/dvb/dm1105/Kconfig
index 43f4d44edca6..de3eeb0a8d6e 100644
--- a/drivers/media/dvb/dm1105/Kconfig
+++ b/drivers/media/dvb/dm1105/Kconfig
@@ -8,6 +8,7 @@ config DVB_DM1105
select DVB_STB6000 if !DVB_FE_CUSTOMISE
select DVB_CX24116 if !DVB_FE_CUSTOMISE
select DVB_SI21XX if !DVB_FE_CUSTOMISE
+ select VIDEO_IR
help
Support for cards based on the SDMC DM1105 PCI chip like
DvbWorld 2002
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index f48f73aff195..5b20cf5a29f0 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -156,46 +156,12 @@ MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-static u16 ir_codes_dm1105_nec[128] = {
- [0x0a] = KEY_Q, /*power*/
- [0x0c] = KEY_M, /*mute*/
- [0x11] = KEY_1,
- [0x12] = KEY_2,
- [0x13] = KEY_3,
- [0x14] = KEY_4,
- [0x15] = KEY_5,
- [0x16] = KEY_6,
- [0x17] = KEY_7,
- [0x18] = KEY_8,
- [0x19] = KEY_9,
- [0x10] = KEY_0,
- [0x1c] = KEY_PAGEUP, /*ch+*/
- [0x0f] = KEY_PAGEDOWN, /*ch-*/
- [0x1a] = KEY_O, /*vol+*/
- [0x0e] = KEY_Z, /*vol-*/
- [0x04] = KEY_R, /*rec*/
- [0x09] = KEY_D, /*fav*/
- [0x08] = KEY_BACKSPACE, /*rewind*/
- [0x07] = KEY_A, /*fast*/
- [0x0b] = KEY_P, /*pause*/
- [0x02] = KEY_ESC, /*cancel*/
- [0x03] = KEY_G, /*tab*/
- [0x00] = KEY_UP, /*up*/
- [0x1f] = KEY_ENTER, /*ok*/
- [0x01] = KEY_DOWN, /*down*/
- [0x05] = KEY_C, /*cap*/
- [0x06] = KEY_S, /*stop*/
- [0x40] = KEY_F, /*full*/
- [0x1e] = KEY_W, /*tvmode*/
- [0x1b] = KEY_B, /*recall*/
-};
-
/* infrared remote control */
struct infrared {
- u16 key_map[128];
struct input_dev *input_dev;
+ struct ir_input_state ir;
char input_phys[32];
- struct tasklet_struct ir_tasklet;
+ struct work_struct work;
u32 ir_command;
};
@@ -220,10 +186,14 @@ struct dm1105dvb {
/* i2c */
struct i2c_adapter i2c_adap;
+ /* irq */
+ struct work_struct work;
+
/* dma */
dma_addr_t dma_addr;
unsigned char *ts_buf;
u32 wrp;
+ u32 nextwrp;
u32 buffer_size;
unsigned int PacketErrorCount;
unsigned int dmarst;
@@ -233,8 +203,6 @@ struct dm1105dvb {
#define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg]))
-static struct dm1105dvb *dm1105dvb_local;
-
static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg *msgs, int num)
{
@@ -407,38 +375,61 @@ static int dm1105dvb_stop_feed(struct dvb_demux_feed *f)
return 0;
}
-/* ir tasklet */
-static void dm1105_emit_key(unsigned long parm)
+/* ir work handler */
+static void dm1105_emit_key(struct work_struct *work)
{
- struct infrared *ir = (struct infrared *) parm;
+ struct infrared *ir = container_of(work, struct infrared, work);
u32 ircom = ir->ir_command;
u8 data;
- u16 keycode;
+
+ if (ir_debug)
+ printk(KERN_INFO "%s: received byte 0x%04x\n", __func__, ircom);
data = (ircom >> 8) & 0x7f;
- input_event(ir->input_dev, EV_MSC, MSC_RAW, (0x0000f8 << 16) | data);
- input_event(ir->input_dev, EV_MSC, MSC_SCAN, data);
- keycode = ir->key_map[data];
+ ir_input_keydown(ir->input_dev, &ir->ir, data, data);
+ ir_input_nokey(ir->input_dev, &ir->ir);
+}
- if (!keycode)
- return;
+/* work handler */
+static void dm1105_dmx_buffer(struct work_struct *work)
+{
+ struct dm1105dvb *dm1105dvb =
+ container_of(work, struct dm1105dvb, work);
+ unsigned int nbpackets;
+ u32 oldwrp = dm1105dvb->wrp;
+ u32 nextwrp = dm1105dvb->nextwrp;
+
+ if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) &&
+ (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) &&
+ (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) {
+ dm1105dvb->PacketErrorCount++;
+ /* bad packet found */
+ if ((dm1105dvb->PacketErrorCount >= 2) &&
+ (dm1105dvb->dmarst == 0)) {
+ outb(1, dm_io_mem(DM1105_RST));
+ dm1105dvb->wrp = 0;
+ dm1105dvb->PacketErrorCount = 0;
+ dm1105dvb->dmarst = 0;
+ return;
+ }
+ }
- input_event(ir->input_dev, EV_KEY, keycode, 1);
- input_sync(ir->input_dev);
- input_event(ir->input_dev, EV_KEY, keycode, 0);
- input_sync(ir->input_dev);
+ if (nextwrp < oldwrp) {
+ memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size,
+ dm1105dvb->ts_buf, nextwrp);
+ nbpackets = ((dm1105dvb->buffer_size - oldwrp) + nextwrp) / 188;
+ } else
+ nbpackets = (nextwrp - oldwrp) / 188;
+ dm1105dvb->wrp = nextwrp;
+ dvb_dmx_swfilter_packets(&dm1105dvb->demux,
+ &dm1105dvb->ts_buf[oldwrp], nbpackets);
}
static irqreturn_t dm1105dvb_irq(int irq, void *dev_id)
{
struct dm1105dvb *dm1105dvb = dev_id;
- unsigned int piece;
- unsigned int nbpackets;
- u32 command;
- u32 nextwrp;
- u32 oldwrp;
/* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */
unsigned int intsts = inb(dm_io_mem(DM1105_INTSTS));
@@ -447,71 +438,25 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id)
switch (intsts) {
case INTSTS_TSIRQ:
case (INTSTS_TSIRQ | INTSTS_IR):
- nextwrp = inl(dm_io_mem(DM1105_WRP)) -
- inl(dm_io_mem(DM1105_STADR)) ;
- oldwrp = dm1105dvb->wrp;
- spin_lock(&dm1105dvb->lock);
- if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) &&
- (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) &&
- (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) {
- dm1105dvb->PacketErrorCount++;
- /* bad packet found */
- if ((dm1105dvb->PacketErrorCount >= 2) &&
- (dm1105dvb->dmarst == 0)) {
- outb(1, dm_io_mem(DM1105_RST));
- dm1105dvb->wrp = 0;
- dm1105dvb->PacketErrorCount = 0;
- dm1105dvb->dmarst = 0;
- spin_unlock(&dm1105dvb->lock);
- return IRQ_HANDLED;
- }
- }
- if (nextwrp < oldwrp) {
- piece = dm1105dvb->buffer_size - oldwrp;
- memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size, dm1105dvb->ts_buf, nextwrp);
- nbpackets = (piece + nextwrp)/188;
- } else {
- nbpackets = (nextwrp - oldwrp)/188;
- }
- dvb_dmx_swfilter_packets(&dm1105dvb->demux, &dm1105dvb->ts_buf[oldwrp], nbpackets);
- dm1105dvb->wrp = nextwrp;
- spin_unlock(&dm1105dvb->lock);
+ dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) -
+ inl(dm_io_mem(DM1105_STADR));
+ schedule_work(&dm1105dvb->work);
break;
case INTSTS_IR:
- command = inl(dm_io_mem(DM1105_IRCODE));
- if (ir_debug)
- printk("dm1105: received byte 0x%04x\n", command);
-
- dm1105dvb->ir.ir_command = command;
- tasklet_schedule(&dm1105dvb->ir.ir_tasklet);
+ dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE));
+ schedule_work(&dm1105dvb->ir.work);
break;
}
- return IRQ_HANDLED;
-
-
-}
-
-/* register with input layer */
-static void input_register_keys(struct infrared *ir)
-{
- int i;
- memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit));
-
- for (i = 0; i < ARRAY_SIZE(ir->key_map); i++)
- set_bit(ir->key_map[i], ir->input_dev->keybit);
-
- ir->input_dev->keycode = ir->key_map;
- ir->input_dev->keycodesize = sizeof(ir->key_map[0]);
- ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map);
+ return IRQ_HANDLED;
}
int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
{
struct input_dev *input_dev;
- int err;
-
- dm1105dvb_local = dm1105;
+ IR_KEYTAB_TYPE *ir_codes = ir_codes_dm1105_nec;
+ int ir_type = IR_TYPE_OTHER;
+ int err = -ENOMEM;
input_dev = input_allocate_device();
if (!input_dev)
@@ -521,12 +466,11 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
"pci-%s/ir0", pci_name(dm1105->pdev));
- input_dev->evbit[0] = BIT(EV_KEY);
+ ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes);
input_dev->name = "DVB on-card IR receiver";
-
input_dev->phys = dm1105->ir.input_phys;
input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 2;
+ input_dev->id.version = 1;
if (dm1105->pdev->subsystem_vendor) {
input_dev->id.vendor = dm1105->pdev->subsystem_vendor;
input_dev->id.product = dm1105->pdev->subsystem_device;
@@ -534,25 +478,22 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
input_dev->id.vendor = dm1105->pdev->vendor;
input_dev->id.product = dm1105->pdev->device;
}
+
input_dev->dev.parent = &dm1105->pdev->dev;
- /* initial keymap */
- memcpy(dm1105->ir.key_map, ir_codes_dm1105_nec, sizeof dm1105->ir.key_map);
- input_register_keys(&dm1105->ir);
+
+ INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
+
err = input_register_device(input_dev);
if (err) {
input_free_device(input_dev);
return err;
}
- tasklet_init(&dm1105->ir.ir_tasklet, dm1105_emit_key, (unsigned long) &dm1105->ir);
-
return 0;
}
-
void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105)
{
- tasklet_kill(&dm1105->ir.ir_tasklet);
input_unregister_device(dm1105->ir.input_dev);
}
@@ -710,7 +651,7 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL);
if (!dm1105dvb)
- goto out;
+ return -ENOMEM;
dm1105dvb->pdev = pdev;
dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES;
@@ -740,13 +681,9 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
spin_lock_init(&dm1105dvb->lock);
pci_set_drvdata(pdev, dm1105dvb);
- ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, DRIVER_NAME, dm1105dvb);
- if (ret < 0)
- goto err_pci_iounmap;
-
ret = dm1105dvb_hw_init(dm1105dvb);
if (ret < 0)
- goto err_free_irq;
+ goto err_pci_iounmap;
/* i2c */
i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb);
@@ -813,8 +750,15 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx);
dm1105_ir_init(dm1105dvb);
-out:
- return ret;
+
+ INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer);
+
+ ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED,
+ DRIVER_NAME, dm1105dvb);
+ if (ret < 0)
+ goto err_free_irq;
+
+ return 0;
err_disconnect_frontend:
dmx->disconnect_frontend(dmx);
@@ -843,7 +787,7 @@ err_pci_disable_device:
err_kfree:
pci_set_drvdata(pdev, NULL);
kfree(dm1105dvb);
- goto out;
+ return ret;
}
static void __devexit dm1105_remove(struct pci_dev *pdev)
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 069d847ba887..c35fbb8d8f4a 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -1024,7 +1024,7 @@ static int dvb_demux_release(struct inode *inode, struct file *file)
return ret;
}
-static struct file_operations dvb_demux_fops = {
+static const struct file_operations dvb_demux_fops = {
.owner = THIS_MODULE,
.read = dvb_demux_read,
.ioctl = dvb_demux_ioctl,
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 7e3aeaa7370f..cb22da53bfb0 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -1607,7 +1607,7 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait)
EXPORT_SYMBOL(dvb_ca_en50221_init);
-static struct file_operations dvb_ca_fops = {
+static const struct file_operations dvb_ca_fops = {
.owner = THIS_MODULE,
.read = dvb_ca_en50221_io_read,
.write = dvb_ca_en50221_io_write,
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 8dcb3fbf7acd..ebc78157b9b8 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1875,7 +1875,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
return ret;
}
-static struct file_operations dvb_frontend_fops = {
+static const struct file_operations dvb_frontend_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_generic_ioctl,
.poll = dvb_frontend_poll,
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index f6ba8468858e..8280f8d66a38 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1459,7 +1459,7 @@ static int dvb_net_close(struct inode *inode, struct file *file)
}
-static struct file_operations dvb_net_fops = {
+static const struct file_operations dvb_net_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_net_ioctl,
.open = dvb_generic_open,
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 6a32680dbb1b..a454ee8f1e43 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -228,8 +228,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvbdev->fops = dvbdevfops;
init_waitqueue_head (&dvbdev->wait_queue);
- memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
- dvbdev->fops->owner = adap->module;
+ memcpy(dvbdevfops, template->fops, sizeof(struct file_operations));
+ dvbdevfops->owner = adap->module;
list_add_tail (&dvbdev->list_head, &adap->device_list);
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index dca49cf962e8..79927305e84d 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -71,7 +71,7 @@ struct dvb_adapter {
struct dvb_device {
struct list_head list_head;
- struct file_operations *fops;
+ const struct file_operations *fops;
struct dvb_adapter *adapter;
int type;
int minor;
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 49f7b20c25d6..6103caad1644 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -25,7 +25,7 @@ config DVB_USB_A800
depends on DVB_USB
select DVB_DIB3000MC
select DVB_PLL if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
@@ -34,7 +34,7 @@ config DVB_USB_DIBUSB_MB
depends on DVB_USB
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_DIB3000MB
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
help
Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
@@ -55,7 +55,7 @@ config DVB_USB_DIBUSB_MC
tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
depends on DVB_USB
select DVB_DIB3000MC
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
help
Support for USB2.0 DVB-T receivers based on reference designs made by
DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
@@ -69,15 +69,17 @@ config DVB_USB_DIBUSB_MC
config DVB_USB_DIB0700
tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)"
depends on DVB_USB
- select DVB_DIB7000P
- select DVB_DIB7000M
- select DVB_DIB3000MC
+ select DVB_DIB7000P if !DVB_FE_CUSTOMISE
+ select DVB_DIB7000M if !DVB_FE_CUSTOMISE
+ select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select DVB_TUNER_DIB0070
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
+ select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
+ select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
help
Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
USB bridge is also present in devices having the DiB7700 DVB-T-USB
@@ -95,7 +97,8 @@ config DVB_USB_UMT_010
depends on DVB_USB
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_DIB3000MC
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+ select DVB_MT352 if !DVB_FE_CUSTOMISE
help
Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
@@ -108,10 +111,11 @@ config DVB_USB_CXUSB
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select DVB_DIB7000P if !DVB_FE_CUSTOMISE
+ select DVB_LGS8GL5 if !DVB_FE_CUSTOMISE
select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Conexant USB2.0 hybrid reference design.
Currently, only DVB and ATSC modes are supported, analog mode
@@ -125,8 +129,8 @@ config DVB_USB_M920X
depends on DVB_USB
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
Currently, only devices with a product id of
@@ -137,7 +141,7 @@ config DVB_USB_GL861
tristate "Genesys Logic GL861 USB2.0 support"
depends on DVB_USB
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
receiver with USB ID 0db0:5581.
@@ -146,7 +150,7 @@ config DVB_USB_AU6610
tristate "Alcor Micro AU6610 USB2.0 support"
depends on DVB_USB
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
@@ -199,7 +203,7 @@ config DVB_USB_NOVA_T_USB2
depends on DVB_USB
select DVB_DIB3000MC
select DVB_PLL if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
@@ -235,8 +239,8 @@ config DVB_USB_OPERA1
config DVB_USB_AF9005
tristate "Afatech AF9005 DVB-T USB1.1 support"
depends on DVB_USB && EXPERIMENTAL
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
and the TerraTec Cinergy T USB XE (Rev.1)
@@ -284,7 +288,7 @@ config DVB_USB_DTV5100
tristate "AME DTV-5100 USB2.0 DVB-T support"
depends on DVB_USB
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
@@ -293,9 +297,18 @@ config DVB_USB_AF9015
depends on DVB_USB && EXPERIMENTAL
select DVB_AF9013
select DVB_PLL if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
+
+config DVB_USB_CE6230
+ tristate "Intel CE6230 DVB-T USB2.0 support"
+ depends on DVB_USB && EXPERIMENTAL
+ select DVB_ZL10353
+ select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+ help
+ Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 3122b7cc2c23..f92734ed777a 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -76,6 +76,8 @@ obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o
obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
+dvb-usb-ce6230-objs = ce6230.o
+obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
# due to tuner-xc3028
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 6a97a40d3dfb..f0ba8b07b84f 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -27,9 +27,7 @@
#include "qt1010.h"
#include "tda18271.h"
#include "mxl5005s.h"
-#if 0
-#include "mc44s80x.h"
-#endif
+#include "mc44s803.h"
static int dvb_usb_af9015_debug;
module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
@@ -37,9 +35,6 @@ MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
static int dvb_usb_af9015_remote;
module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
MODULE_PARM_DESC(remote, "select remote");
-static int dvb_usb_af9015_dual_mode;
-module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644);
-MODULE_PARM_DESC(dual_mode, "enable dual mode");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static DEFINE_MUTEX(af9015_usb_mutex);
@@ -283,6 +278,21 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate.
req.data = &msg[i+1].buf[0];
ret = af9015_ctrl_msg(d, &req);
i += 2;
+ } else if (msg[i].flags & I2C_M_RD) {
+ ret = -EINVAL;
+ if (msg[i].addr ==
+ af9015_af9013_config[0].demod_address)
+ goto error;
+ else
+ req.cmd = READ_I2C;
+ req.i2c_addr = msg[i].addr;
+ req.addr = addr;
+ req.mbox = mbox;
+ req.addr_len = addr_len;
+ req.data_len = msg[i].len;
+ req.data = &msg[i].buf[0];
+ ret = af9015_ctrl_msg(d, &req);
+ i += 1;
} else {
if (msg[i].addr ==
af9015_af9013_config[0].demod_address)
@@ -748,6 +758,16 @@ static int af9015_read_config(struct usb_device *udev)
af9015_config.ir_table_size =
ARRAY_SIZE(af9015_ir_table_digittrade);
break;
+ case AF9015_REMOTE_AVERMEDIA_KS:
+ af9015_properties[i].rc_key_map =
+ af9015_rc_keys_avermedia;
+ af9015_properties[i].rc_key_map_size =
+ ARRAY_SIZE(af9015_rc_keys_avermedia);
+ af9015_config.ir_table =
+ af9015_ir_table_avermedia_ks;
+ af9015_config.ir_table_size =
+ ARRAY_SIZE(af9015_ir_table_avermedia_ks);
+ break;
}
} else {
switch (le16_to_cpu(udev->descriptor.idVendor)) {
@@ -836,9 +856,6 @@ static int af9015_read_config(struct usb_device *udev)
goto error;
af9015_config.dual_mode = val;
deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode);
- /* disable dual mode by default because it is buggy */
- if (!dvb_usb_af9015_dual_mode)
- af9015_config.dual_mode = 0;
/* Set adapter0 buffer size according to USB port speed, adapter1 buffer
size can be static because it is enabled only USB2.0 */
@@ -935,7 +952,6 @@ static int af9015_read_config(struct usb_device *udev)
switch (val) {
case AF9013_TUNER_ENV77H11D5:
case AF9013_TUNER_MT2060:
- case AF9013_TUNER_MC44S803:
case AF9013_TUNER_QT1010:
case AF9013_TUNER_UNKNOWN:
case AF9013_TUNER_MT2060_2:
@@ -948,6 +964,10 @@ static int af9015_read_config(struct usb_device *udev)
case AF9013_TUNER_MXL5005R:
af9015_af9013_config[i].rf_spec_inv = 0;
break;
+ case AF9013_TUNER_MC44S803:
+ af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
+ af9015_af9013_config[i].rf_spec_inv = 1;
+ break;
default:
warn("tuner id:%d not supported, please report!", val);
return -ENODEV;
@@ -1135,6 +1155,11 @@ static struct mxl5005s_config af9015_mxl5005_config = {
.AgcMasterByte = 0x00,
};
+static struct mc44s803_config af9015_mc44s803_config = {
+ .i2c_address = 0xc0,
+ .dig_out = 1,
+};
+
static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
{
struct af9015_state *state = adap->dev->priv;
@@ -1179,15 +1204,8 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_MC44S803:
-#if 0
- ret = dvb_attach(mc44s80x_attach, adap->fe, i2c_adap)
- == NULL ? -ENODEV : 0;
-#else
- ret = -ENODEV;
- info("Freescale MC44S803 tuner found but no driver for that" \
- "tuner. Look at the Linuxtv.org for tuner driver" \
- "status.");
-#endif
+ ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap,
+ &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_UNKNOWN:
default:
@@ -1218,6 +1236,7 @@ static struct usb_device_id af9015_usb_table[] = {
{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
+ {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
{0},
};
MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1417,7 +1436,8 @@ static struct dvb_usb_device_properties af9015_properties[] = {
{
.name = "KWorld USB DVB-T TV Stick II " \
"(VS-DVB-T 395U)",
- .cold_ids = {&af9015_usb_table[16], NULL},
+ .cold_ids = {&af9015_usb_table[16],
+ &af9015_usb_table[17], NULL},
.warm_ids = {NULL},
},
}
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index 21c7782f4889..00e25714662a 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -124,6 +124,7 @@ enum af9015_remote {
AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
AF9015_REMOTE_MYGICTV_U718,
AF9015_REMOTE_DIGITTRADE_DVB_T,
+ AF9015_REMOTE_AVERMEDIA_KS,
};
/* Leadtek WinFast DTV Dongle Gold */
@@ -597,6 +598,36 @@ static u8 af9015_ir_table_avermedia[] = {
0x03, 0xfc, 0x03, 0xfc, 0x0e, 0x05, 0x00,
};
+static u8 af9015_ir_table_avermedia_ks[] = {
+ 0x05, 0xfa, 0x01, 0xfe, 0x12, 0x05, 0x00,
+ 0x05, 0xfa, 0x02, 0xfd, 0x0e, 0x05, 0x00,
+ 0x05, 0xfa, 0x03, 0xfc, 0x0d, 0x05, 0x00,
+ 0x05, 0xfa, 0x04, 0xfb, 0x2e, 0x05, 0x00,
+ 0x05, 0xfa, 0x05, 0xfa, 0x2d, 0x05, 0x00,
+ 0x05, 0xfa, 0x06, 0xf9, 0x10, 0x05, 0x00,
+ 0x05, 0xfa, 0x07, 0xf8, 0x0f, 0x05, 0x00,
+ 0x05, 0xfa, 0x08, 0xf7, 0x3d, 0x05, 0x00,
+ 0x05, 0xfa, 0x09, 0xf6, 0x1e, 0x05, 0x00,
+ 0x05, 0xfa, 0x0a, 0xf5, 0x1f, 0x05, 0x00,
+ 0x05, 0xfa, 0x0b, 0xf4, 0x20, 0x05, 0x00,
+ 0x05, 0xfa, 0x0c, 0xf3, 0x21, 0x05, 0x00,
+ 0x05, 0xfa, 0x0d, 0xf2, 0x22, 0x05, 0x00,
+ 0x05, 0xfa, 0x0e, 0xf1, 0x23, 0x05, 0x00,
+ 0x05, 0xfa, 0x0f, 0xf0, 0x24, 0x05, 0x00,
+ 0x05, 0xfa, 0x10, 0xef, 0x25, 0x05, 0x00,
+ 0x05, 0xfa, 0x11, 0xee, 0x26, 0x05, 0x00,
+ 0x05, 0xfa, 0x12, 0xed, 0x27, 0x05, 0x00,
+ 0x05, 0xfa, 0x13, 0xec, 0x04, 0x05, 0x00,
+ 0x05, 0xfa, 0x15, 0xea, 0x0a, 0x05, 0x00,
+ 0x05, 0xfa, 0x16, 0xe9, 0x11, 0x05, 0x00,
+ 0x05, 0xfa, 0x17, 0xe8, 0x15, 0x05, 0x00,
+ 0x05, 0xfa, 0x18, 0xe7, 0x16, 0x05, 0x00,
+ 0x05, 0xfa, 0x1c, 0xe3, 0x05, 0x05, 0x00,
+ 0x05, 0xfa, 0x1d, 0xe2, 0x09, 0x05, 0x00,
+ 0x05, 0xfa, 0x4d, 0xb2, 0x3f, 0x05, 0x00,
+ 0x05, 0xfa, 0x56, 0xa9, 0x3e, 0x05, 0x00
+};
+
/* Digittrade DVB-T USB Stick */
static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = {
{ 0x01, 0x0f, KEY_LAST }, /* RETURN */
diff --git a/drivers/media/dvb/dvb-usb/ce6230.c b/drivers/media/dvb/dvb-usb/ce6230.c
new file mode 100644
index 000000000000..5862820f109f
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ce6230.c
@@ -0,0 +1,328 @@
+/*
+ * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "ce6230.h"
+#include "zl10353.h"
+#include "mxl5005s.h"
+
+/* debug */
+static int dvb_usb_ce6230_debug;
+module_param_named(debug, dvb_usb_ce6230_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static struct zl10353_config ce6230_zl10353_config;
+
+static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
+{
+ int ret;
+ unsigned int pipe;
+ u8 request;
+ u8 requesttype;
+ u16 value;
+ u16 index;
+ u8 buf[req->data_len];
+
+ request = req->cmd;
+ value = req->value;
+ index = req->index;
+
+ switch (req->cmd) {
+ case I2C_READ:
+ case DEMOD_READ:
+ case REG_READ:
+ requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+ break;
+ case I2C_WRITE:
+ case DEMOD_WRITE:
+ case REG_WRITE:
+ requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+ break;
+ default:
+ err("unknown command:%02x", req->cmd);
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
+ /* write */
+ memcpy(buf, req->data, req->data_len);
+ pipe = usb_sndctrlpipe(udev, 0);
+ } else {
+ /* read */
+ pipe = usb_rcvctrlpipe(udev, 0);
+ }
+
+ msleep(1); /* avoid I2C errors */
+
+ ret = usb_control_msg(udev, pipe, request, requesttype, value, index,
+ buf, sizeof(buf), CE6230_USB_TIMEOUT);
+
+ ce6230_debug_dump(request, requesttype, value, index, buf,
+ req->data_len, deb_xfer);
+
+ if (ret < 0)
+ deb_info("%s: usb_control_msg failed:%d\n", __func__, ret);
+ else
+ ret = 0;
+
+ /* read request, copy returned data to return buf */
+ if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
+ memcpy(req->data, buf, req->data_len);
+
+error:
+ return ret;
+}
+
+static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
+{
+ return ce6230_rw_udev(d->udev, req);
+}
+
+/* I2C */
+static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ int i = 0;
+ struct req_t req;
+ int ret = 0;
+ memset(&req, 0, sizeof(&req));
+
+ if (num > 2)
+ return -EINVAL;
+
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ while (i < num) {
+ if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+ if (msg[i].addr ==
+ ce6230_zl10353_config.demod_address) {
+ req.cmd = DEMOD_READ;
+ req.value = msg[i].addr >> 1;
+ req.index = msg[i].buf[0];
+ req.data_len = msg[i+1].len;
+ req.data = &msg[i+1].buf[0];
+ ret = ce6230_ctrl_msg(d, &req);
+ } else {
+ err("i2c read not implemented");
+ ret = -EPERM;
+ }
+ i += 2;
+ } else {
+ if (msg[i].addr ==
+ ce6230_zl10353_config.demod_address) {
+ req.cmd = DEMOD_WRITE;
+ req.value = msg[i].addr >> 1;
+ req.index = msg[i].buf[0];
+ req.data_len = msg[i].len-1;
+ req.data = &msg[i].buf[1];
+ ret = ce6230_ctrl_msg(d, &req);
+ } else {
+ req.cmd = I2C_WRITE;
+ req.value = 0x2000 + (msg[i].addr >> 1);
+ req.index = 0x0000;
+ req.data_len = msg[i].len;
+ req.data = &msg[i].buf[0];
+ ret = ce6230_ctrl_msg(d, &req);
+ }
+ i += 1;
+ }
+ if (ret)
+ break;
+ }
+
+ mutex_unlock(&d->i2c_mutex);
+ return ret ? ret : i;
+}
+
+static u32 ce6230_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm ce6230_i2c_algo = {
+ .master_xfer = ce6230_i2c_xfer,
+ .functionality = ce6230_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static struct zl10353_config ce6230_zl10353_config = {
+ .demod_address = 0x1e,
+ .adc_clock = 450000,
+ .if2 = 45700,
+ .no_tuner = 1,
+ .parallel_ts = 1,
+ .clock_ctl_1 = 0x34,
+ .pll_0 = 0x0e,
+};
+
+static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ deb_info("%s:\n", __func__);
+ adap->fe = dvb_attach(zl10353_attach, &ce6230_zl10353_config,
+ &adap->dev->i2c_adap);
+ if (adap->fe == NULL)
+ return -ENODEV;
+ return 0;
+}
+
+static struct mxl5005s_config ce6230_mxl5003s_config = {
+ .i2c_address = 0xc6,
+ .if_freq = IF_FREQ_4570000HZ,
+ .xtal_freq = CRYSTAL_FREQ_16000000HZ,
+ .agc_mode = MXL_SINGLE_AGC,
+ .tracking_filter = MXL_TF_DEFAULT,
+ .rssi_enable = MXL_RSSI_ENABLE,
+ .cap_select = MXL_CAP_SEL_ENABLE,
+ .div_out = MXL_DIV_OUT_4,
+ .clock_out = MXL_CLOCK_OUT_DISABLE,
+ .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+ .top = MXL5005S_TOP_25P2,
+ .mod_mode = MXL_DIGITAL_MODE,
+ .if_mode = MXL_ZERO_IF,
+ .AgcMasterByte = 0x00,
+};
+
+static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ int ret;
+ deb_info("%s:\n", __func__);
+ ret = dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap,
+ &ce6230_mxl5003s_config) == NULL ? -ENODEV : 0;
+ return ret;
+}
+
+static int ce6230_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ int ret;
+ deb_info("%s: onoff:%d\n", __func__, onoff);
+
+ /* InterfaceNumber 1 / AlternateSetting 0 idle
+ InterfaceNumber 1 / AlternateSetting 1 streaming */
+ ret = usb_set_interface(d->udev, 1, onoff);
+ if (ret)
+ err("usb_set_interface failed with error:%d", ret);
+
+ return ret;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties ce6230_properties;
+
+static int ce6230_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ int ret = 0;
+ struct dvb_usb_device *d = NULL;
+
+ deb_info("%s: interface:%d\n", __func__,
+ intf->cur_altsetting->desc.bInterfaceNumber);
+
+ if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
+ ret = dvb_usb_device_init(intf, &ce6230_properties, THIS_MODULE,
+ &d, adapter_nr);
+ if (ret)
+ err("init failed with error:%d\n", ret);
+ }
+
+ return ret;
+}
+
+static struct usb_device_id ce6230_table[] = {
+ { USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, ce6230_table);
+
+static struct dvb_usb_device_properties ce6230_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .no_reconnect = 1,
+
+ .size_of_priv = 0,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .frontend_attach = ce6230_zl10353_frontend_attach,
+ .tuner_attach = ce6230_mxl5003s_tuner_attach,
+ .stream = {
+ .type = USB_BULK,
+ .count = 6,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 512,
+ }
+ }
+ },
+ }
+ },
+
+ .power_ctrl = ce6230_power_ctrl,
+
+ .i2c_algo = &ce6230_i2c_algo,
+
+ .num_device_descs = 1,
+ .devices = {
+ {
+ .name = "Intel CE9500 reference design",
+ .cold_ids = {NULL},
+ .warm_ids = {&ce6230_table[0], NULL},
+ },
+ }
+};
+
+static struct usb_driver ce6230_driver = {
+ .name = "dvb_usb_ce6230",
+ .probe = ce6230_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = ce6230_table,
+};
+
+/* module stuff */
+static int __init ce6230_module_init(void)
+{
+ int ret;
+ deb_info("%s:\n", __func__);
+ ret = usb_register(&ce6230_driver);
+ if (ret)
+ err("usb_register failed with error:%d", ret);
+
+ return ret;
+}
+
+static void __exit ce6230_module_exit(void)
+{
+ deb_info("%s:\n", __func__);
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&ce6230_driver);
+}
+
+module_init(ce6230_module_init);
+module_exit(ce6230_module_exit);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Driver for Intel CE6230 DVB-T USB2.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ce6230.h b/drivers/media/dvb/dvb-usb/ce6230.h
new file mode 100644
index 000000000000..97c42482ccb3
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ce6230.h
@@ -0,0 +1,69 @@
+/*
+ * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _DVB_USB_CE6230_H_
+#define _DVB_USB_CE6230_H_
+
+#define DVB_USB_LOG_PREFIX "ce6230"
+#include "dvb-usb.h"
+
+#define deb_info(args...) dprintk(dvb_usb_ce6230_debug, 0x01, args)
+#define deb_rc(args...) dprintk(dvb_usb_ce6230_debug, 0x02, args)
+#define deb_xfer(args...) dprintk(dvb_usb_ce6230_debug, 0x04, args)
+#define deb_reg(args...) dprintk(dvb_usb_ce6230_debug, 0x08, args)
+#define deb_i2c(args...) dprintk(dvb_usb_ce6230_debug, 0x10, args)
+#define deb_fw(args...) dprintk(dvb_usb_ce6230_debug, 0x20, args)
+
+#define ce6230_debug_dump(r, t, v, i, b, l, func) { \
+ int loop_; \
+ func("%02x %02x %02x %02x %02x %02x %02x %02x", \
+ t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \
+ if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
+ func(" >>> "); \
+ else \
+ func(" <<< "); \
+ for (loop_ = 0; loop_ < l; loop_++) \
+ func("%02x ", b[loop_]); \
+ func("\n");\
+}
+
+#define CE6230_USB_TIMEOUT 1000
+
+struct req_t {
+ u8 cmd; /* [1] */
+ u16 value; /* [2|3] */
+ u16 index; /* [4|5] */
+ u16 data_len; /* [6|7] */
+ u8 *data;
+};
+
+enum ce6230_cmd {
+ CONFIG_READ = 0xd0, /* rd 0 (unclear) */
+ UNKNOWN_WRITE = 0xc7, /* wr 7 (unclear) */
+ I2C_READ = 0xd9, /* rd 9 (unclear) */
+ I2C_WRITE = 0xca, /* wr a */
+ DEMOD_READ = 0xdb, /* rd b */
+ DEMOD_WRITE = 0xcc, /* wr c */
+ REG_READ = 0xde, /* rd e */
+ REG_WRITE = 0xcf, /* wr f */
+};
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 200b215f4d8b..db7f7f79a66c 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -158,6 +158,10 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
err("i2c read error (status = %d)\n", result);
break;
}
+
+ deb_data("<<< ");
+ debug_dump(msg[i].buf, msg[i].len, deb_data);
+
} else {
/* Write request */
buf[0] = REQUEST_NEW_I2C_WRITE;
@@ -169,6 +173,9 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
/* The Actual i2c payload */
memcpy(&buf[4], msg[i].buf, msg[i].len);
+ deb_data(">>> ");
+ debug_dump(buf, msg[i].len + 4, deb_data);
+
result = usb_control_msg(d->udev,
usb_sndctrlpipe(d->udev, 0),
REQUEST_NEW_I2C_WRITE,
@@ -211,7 +218,8 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
/* special thing in the current firmware: when length is zero the read-failed */
if ((len = dib0700_ctrl_rd(d, buf, msg[i].len + 2, msg[i+1].buf, msg[i+1].len)) <= 0) {
- deb_info("I2C read failed on address %x\n", msg[i].addr);
+ deb_info("I2C read failed on address 0x%02x\n",
+ msg[i].addr);
break;
}
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 635d30a55078..8ddbadf62194 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -17,6 +17,8 @@
#include "xc5000.h"
#include "s5h1411.h"
#include "dib0070.h"
+#include "lgdt3305.h"
+#include "mxl5007t.h"
static int force_lna_activation;
module_param(force_lna_activation, int, 0644);
@@ -262,7 +264,12 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
msleep(10);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap,1,18,stk7700d_dib7000p_mt2266_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ stk7700d_dib7000p_mt2266_config)
+ != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
+ return -ENODEV;
+ }
}
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
@@ -284,7 +291,12 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap,2,18,stk7700d_dib7000p_mt2266_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+ stk7700d_dib7000p_mt2266_config)
+ != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
+ return -ENODEV;
+ }
}
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
@@ -421,8 +433,12 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
msleep(10);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
- &stk7700ph_dib7700_xc3028_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ &stk7700ph_dib7700_xc3028_config) != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ __func__);
+ return -ENODEV;
+ }
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
&stk7700ph_dib7700_xc3028_config);
@@ -1187,8 +1203,12 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
- &dib7070p_dib7000p_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ &dib7070p_dib7000p_config) != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ __func__);
+ return -ENODEV;
+ }
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
&dib7070p_dib7000p_config);
@@ -1244,7 +1264,12 @@ static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+ stk7070pd_dib7000p_config) != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ __func__);
+ return -ENODEV;
+ }
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
return adap->fe == NULL ? -ENODEV : 0;
@@ -1347,6 +1372,72 @@ static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
== NULL ? -ENODEV : 0;
}
+static struct lgdt3305_config hcw_lgdt3305_config = {
+ .i2c_addr = 0x0e,
+ .mpeg_mode = LGDT3305_MPEG_PARALLEL,
+ .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
+ .tpvalid_polarity = LGDT3305_TP_VALID_LOW,
+ .deny_i2c_rptr = 0,
+ .spectral_inversion = 1,
+ .qam_if_khz = 6000,
+ .vsb_if_khz = 6000,
+ .usref_8vsb = 0x0500,
+};
+
+static struct mxl5007t_config hcw_mxl5007t_config = {
+ .xtal_freq_hz = MxL_XTAL_25_MHZ,
+ .if_freq_hz = MxL_IF_6_MHZ,
+ .invert_if = 1,
+};
+
+/* TIGER-ATSC map:
+ GPIO0 - LNA_CTR (H: LNA power enabled, L: LNA power disabled)
+ GPIO1 - ANT_SEL (H: VPA, L: MCX)
+ GPIO4 - SCL2
+ GPIO6 - EN_TUNER
+ GPIO7 - SDA2
+ GPIO10 - DEM_RST
+
+ MXL is behind LG's i2c repeater. LG is on SCL2/SDA2 gpios on the DIB
+ */
+static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ struct dib0700_state *st = adap->dev->priv;
+
+ /* Make use of the new i2c functions from FW 1.20 */
+ st->fw_use_new_i2c_api = 1;
+
+ st->disable_streaming_master_mode = 1;
+
+ /* fe power enable */
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+ msleep(30);
+
+ /* demod reset */
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(30);
+
+ adap->fe = dvb_attach(lgdt3305_attach,
+ &hcw_lgdt3305_config,
+ &adap->dev->i2c_adap);
+
+ return adap->fe == NULL ? -ENODEV : 0;
+}
+
+static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ return dvb_attach(mxl5007t_attach, adap->fe,
+ &adap->dev->i2c_adap, 0x60,
+ &hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
+}
+
+
/* DVB-USB and USB stuff follows */
struct usb_device_id dib0700_usb_id_table[] = {
/* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) },
@@ -1396,6 +1487,12 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
{ USB_DEVICE(USB_VID_TERRATEC,
USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
+ { USB_DEVICE(USB_VID_SONY, USB_PID_SONY_PLAYTV) },
+/* 45 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_PD378S) },
+ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
+ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
+ { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) },
+ { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1595,7 +1692,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .num_device_descs = 9,
+ .num_device_descs = 11,
.devices = {
{ "DiBcom STK7070P reference design",
{ &dib0700_usb_id_table[15], NULL },
@@ -1633,6 +1730,14 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ &dib0700_usb_id_table[33], NULL },
{ NULL },
},
+ { "Elgato EyeTV DTT",
+ { &dib0700_usb_id_table[49], NULL },
+ { NULL },
+ },
+ { "Yuan PD378S",
+ { &dib0700_usb_id_table[45], NULL },
+ { NULL },
+ },
},
.rc_interval = DEFAULT_RC_INTERVAL,
@@ -1661,7 +1766,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
}
},
- .num_device_descs = 5,
+ .num_device_descs = 6,
.devices = {
{ "DiBcom STK7070PD reference design",
{ &dib0700_usb_id_table[17], NULL },
@@ -1682,8 +1787,16 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "Terratec Cinergy DT USB XS Diversity",
{ &dib0700_usb_id_table[43], NULL },
{ NULL },
+ },
+ { "Sony PlayTV",
+ { &dib0700_usb_id_table[44], NULL },
+ { NULL },
}
- }
+ },
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = dib0700_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
+ .rc_query = dib0700_rc_query
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@@ -1699,7 +1812,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .num_device_descs = 5,
+ .num_device_descs = 7,
.devices = {
{ "Terratec Cinergy HT USB XE",
{ &dib0700_usb_id_table[27], NULL },
@@ -1725,6 +1838,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ &dib0700_usb_id_table[39], NULL },
{ NULL },
},
+ { "YUAN High-Tech MC770",
+ { &dib0700_usb_id_table[48], NULL },
+ { NULL },
+ },
},
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dib0700_rc_keys,
@@ -1759,6 +1876,31 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_key_map = dib0700_rc_keys,
.rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
.rc_query = dib0700_rc_query
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .frontend_attach = lgdt3305_frontend_attach,
+ .tuner_attach = mxl5007t_tuner_attach,
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+ .size_of_priv = sizeof(struct
+ dib0700_adapter_state),
+ },
+ },
+
+ .num_device_descs = 2,
+ .devices = {
+ { "Hauppauge ATSC MiniCard (B200)",
+ { &dib0700_usb_id_table[46], NULL },
+ { NULL },
+ },
+ { "Hauppauge ATSC MiniCard (B210)",
+ { &dib0700_usb_id_table[47], NULL },
+ { NULL },
+ },
+ },
},
};
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 0db0c06ee6f2..dc7ea21cd139 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -27,12 +27,14 @@
#define USB_VID_DIBCOM 0x10b8
#define USB_VID_DPOSH 0x1498
#define USB_VID_DVICO 0x0fe9
+#define USB_VID_ELGATO 0x0fd9
#define USB_VID_EMPIA 0xeb1a
#define USB_VID_GENPIX 0x09c0
#define USB_VID_GRANDTEC 0x5032
#define USB_VID_HANFTEK 0x15f4
#define USB_VID_HAUPPAUGE 0x2040
#define USB_VID_HYPER_PALTEK 0x1025
+#define USB_VID_INTEL 0x8086
#define USB_VID_KWORLD 0xeb2a
#define USB_VID_KWORLD_2 0x1b80
#define USB_VID_KYE 0x0458
@@ -48,6 +50,7 @@
#define USB_VID_TERRATEC 0x0ccd
#define USB_VID_TELESTAR 0x10b9
#define USB_VID_VISIONPLUS 0x13d3
+#define USB_VID_SONY 0x1415
#define USB_VID_TWINHAN 0x1822
#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
#define USB_VID_UNIWILL 0x1584
@@ -95,8 +98,10 @@
#define USB_PID_UNIWILL_STK7700P 0x6003
#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
+#define USB_PID_INTEL_CE9500 0x9500
#define USB_PID_KWORLD_399U 0xe399
#define USB_PID_KWORLD_395U 0xe396
+#define USB_PID_KWORLD_395U_2 0xe39b
#define USB_PID_KWORLD_PC160_2T 0xc160
#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
@@ -149,6 +154,8 @@
#define USB_PID_HAUPPAUGE_MYTV_T 0x7080
#define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580
#define USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009 0x5200
+#define USB_PID_HAUPPAUGE_TIGER_ATSC 0xb200
+#define USB_PID_HAUPPAUGE_TIGER_ATSC_B210 0xb210
#define USB_PID_AVERMEDIA_EXPRESS 0xb568
#define USB_PID_AVERMEDIA_VOLAR 0xa807
#define USB_PID_AVERMEDIA_VOLAR_2 0xb808
@@ -232,9 +239,13 @@
#define USB_PID_ASUS_U3100 0x173f
#define USB_PID_YUAN_EC372S 0x1edc
#define USB_PID_YUAN_STK7700PH 0x1f08
+#define USB_PID_YUAN_PD378S 0x2edc
+#define USB_PID_YUAN_MC770 0x0871
#define USB_PID_DW2102 0x2102
#define USB_PID_XTENSIONS_XD_380 0x0381
#define USB_PID_TELESTAR_STARSTICK_2 0x8000
#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807
+#define USB_PID_SONY_PLAYTV 0x0003
+#define USB_PID_ELGATO_EYETV_DTT 0x0021
#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index b1de0f7e26e8..2d5352e54dc0 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -223,7 +223,7 @@ struct dvb_usb_device_properties {
int generic_bulk_ctrl_endpoint;
int num_device_descs;
- struct dvb_usb_device_description devices[9];
+ struct dvb_usb_device_description devices[11];
};
/**
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index b55d9ccaf33e..12f7730184ad 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -115,7 +115,7 @@ static const char *debug_fcp_ctype(unsigned int ctype)
}
static const char *debug_fcp_opcode(unsigned int opcode,
- const u8 *data, size_t length)
+ const u8 *data, int length)
{
switch (opcode) {
case AVC_OPCODE_VENDOR: break;
@@ -135,13 +135,14 @@ static const char *debug_fcp_opcode(unsigned int opcode,
case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL: return "RegisterRC";
case SFE_VENDOR_OPCODE_LNB_CONTROL: return "LNBControl";
case SFE_VENDOR_OPCODE_TUNE_QPSK: return "TuneQPSK";
+ case SFE_VENDOR_OPCODE_TUNE_QPSK2: return "TuneQPSK2";
case SFE_VENDOR_OPCODE_HOST2CA: return "Host2CA";
case SFE_VENDOR_OPCODE_CA2HOST: return "CA2Host";
}
return "Vendor";
}
-static void debug_fcp(const u8 *data, size_t length)
+static void debug_fcp(const u8 *data, int length)
{
unsigned int subunit_type, subunit_id, op;
const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> ";
@@ -150,7 +151,7 @@ static void debug_fcp(const u8 *data, size_t length)
subunit_type = data[1] >> 3;
subunit_id = data[1] & 7;
op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
- printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n",
+ printk(KERN_INFO "%ssu=%x.%x l=%zu: %-8s - %s\n",
prefix, subunit_type, subunit_id, length,
debug_fcp_ctype(data[0]),
debug_fcp_opcode(op, data, length));
@@ -266,7 +267,10 @@ static void avc_tuner_tuneqpsk(struct firedtv *fdtv,
c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
- c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK;
+ if (fdtv->type == FIREDTV_DVB_S2)
+ c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK2;
+ else
+ c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK;
c->operand[4] = (params->frequency >> 24) & 0xff;
c->operand[5] = (params->frequency >> 16) & 0xff;
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 00269560793a..a486a7f81fa9 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -1,17 +1,21 @@
-menu "Customise DVB Frontends"
- depends on DVB_CORE
-
config DVB_FE_CUSTOMISE
bool "Customise the frontend modules to build"
+ depends on DVB_CORE
default N
help
- This allows the user to deselect frontend drivers unnecessary
- for their hardware from the build. Use this option with care
- as deselecting frontends which are in fact necessary will result
- in DVB devices which cannot be tuned due to lack of driver support.
+ This allows the user to select/deselect frontend drivers for their
+ hardware from the build.
+
+ Use this option with care as deselecting frontends which are in fact
+ necessary will result in DVB devices which cannot be tuned due to lack
+ of driver support.
If unsure say N.
+if DVB_FE_CUSTOMISE
+
+menu "Customise DVB Frontends"
+
comment "Multistandard (satellite) frontends"
depends on DVB_CORE
@@ -55,6 +59,13 @@ config DVB_MT312
help
A DVB-S tuner module. Say Y when you want to support this frontend.
+config DVB_ZL10036
+ tristate "Zarlink ZL10036 silicon tuner"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S tuner module. Say Y when you want to support this frontend.
+
config DVB_S5H1420
tristate "Samsung S5H1420 based"
depends on DVB_CORE && I2C
@@ -83,6 +94,20 @@ config DVB_STV0299
help
A DVB-S tuner module. Say Y when you want to support this frontend.
+config DVB_STV6110
+ tristate "ST STV6110 silicon tuner"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S silicon tuner module. Say Y when you want to support this tuner.
+
+config DVB_STV0900
+ tristate "ST STV0900 based"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S/S2 demodulator. Say Y when you want to support this frontend.
+
config DVB_TDA8083
tristate "Philips TDA8083 based"
depends on DVB_CORE && I2C
@@ -288,6 +313,13 @@ config DVB_TDA10048
help
A DVB-T tuner module. Say Y when you want to support this frontend.
+config DVB_AF9013
+ tristate "Afatech AF9013 demodulator"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ Say Y when you want to support this frontend.
+
comment "DVB-C (cable) frontends"
depends on DVB_CORE
@@ -387,6 +419,14 @@ config DVB_LGDT3304
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
+config DVB_LGDT3305
+ tristate "LG Electronics LGDT3305 based"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+ to support this frontend.
+
config DVB_S5H1409
tristate "Samsung S5H1409 based"
depends on DVB_CORE && I2C
@@ -397,7 +437,7 @@ config DVB_S5H1409
config DVB_AU8522
tristate "Auvitek AU8522 based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && VIDEO_V4L2
default m if DVB_FE_CUSTOMISE
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
@@ -439,18 +479,18 @@ config DVB_TUNER_DIB0070
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon baseband tuner DiB0070 from DiBcom.
- This device is only used inside a SiP called togther with a
+ This device is only used inside a SiP called together with a
demodulator for now.
comment "SEC control devices for DVB-S"
depends on DVB_CORE
config DVB_LNBP21
- tristate "LNBP21 SEC controller"
+ tristate "LNBP21/LNBH24 SEC controllers"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
- An SEC control chip.
+ An SEC control chips.
config DVB_ISL6405
tristate "ISL6405 SEC controller"
@@ -478,11 +518,6 @@ comment "Tools to develop new frontends"
config DVB_DUMMY_FE
tristate "Dummy frontend driver"
default n
-
-config DVB_AF9013
- tristate "Afatech AF9013 demodulator"
- depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
- help
- Say Y when you want to support this frontend.
endmenu
+
+endif
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index af7bdf0ad4c7..65a336aa1db6 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -7,6 +7,8 @@ EXTRA_CFLAGS += -Idrivers/media/common/tuners/
s921-objs := s921_module.o s921_core.o
stb0899-objs = stb0899_drv.o stb0899_algo.o
+stv0900-objs = stv0900_core.o stv0900_sw.o
+au8522-objs = au8522_dig.o au8522_decoder.o
obj-$(CONFIG_DVB_PLL) += dvb-pll.o
obj-$(CONFIG_DVB_STV0299) += stv0299.o
@@ -28,6 +30,7 @@ obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
obj-$(CONFIG_DVB_SP887X) += sp887x.o
obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
obj-$(CONFIG_DVB_MT352) += mt352.o
+obj-$(CONFIG_DVB_ZL10036) += zl10036.o
obj-$(CONFIG_DVB_ZL10353) += zl10353.o
obj-$(CONFIG_DVB_CX22702) += cx22702.o
obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
@@ -41,6 +44,7 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
obj-$(CONFIG_DVB_LGDT3304) += lgdt3304.o
+obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
obj-$(CONFIG_DVB_CX24123) += cx24123.o
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
obj-$(CONFIG_DVB_ISL6405) += isl6405.o
@@ -64,4 +68,6 @@ obj-$(CONFIG_DVB_SI21XX) += si21xx.o
obj-$(CONFIG_DVB_STV0288) += stv0288.o
obj-$(CONFIG_DVB_STB6000) += stb6000.o
obj-$(CONFIG_DVB_S921) += s921.o
+obj-$(CONFIG_DVB_STV6110) += stv6110.o
+obj-$(CONFIG_DVB_STV0900) += stv0900.o
diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb/frontends/au8522.h
index 7b94f554a093..565dcf31af57 100644
--- a/drivers/media/dvb/frontends/au8522.h
+++ b/drivers/media/dvb/frontends/au8522.h
@@ -74,6 +74,22 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config,
}
#endif /* CONFIG_DVB_AU8522 */
+/* Other modes may need to be added later */
+enum au8522_video_input {
+ AU8522_COMPOSITE_CH1 = 1,
+ AU8522_COMPOSITE_CH2,
+ AU8522_COMPOSITE_CH3,
+ AU8522_COMPOSITE_CH4,
+ AU8522_COMPOSITE_CH4_SIF,
+ AU8522_SVIDEO_CH13,
+ AU8522_SVIDEO_CH24,
+};
+
+enum au8522_audio_input {
+ AU8522_AUDIO_NONE,
+ AU8522_AUDIO_SIF,
+};
+
#endif /* __AU8522_H__ */
/*
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
new file mode 100644
index 000000000000..d63e1527dc88
--- /dev/null
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -0,0 +1,835 @@
+/*
+ * Auvitek AU8522 QAM/8VSB demodulator driver and video decoder
+ *
+ * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
+ * Copyright (C) 2005-2008 Auvitek International, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * As published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/* Developer notes:
+ *
+ * VBI support is not yet working
+ * Saturation and hue setting are not yet working
+ * Enough is implemented here for CVBS and S-Video inputs, but the actual
+ * analog demodulator code isn't implemented (not needed for xc5000 since it
+ * has its own demodulator and outputs CVBS)
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
+#include <media/v4l2-device.h>
+#include "au8522.h"
+#include "au8522_priv.h"
+
+MODULE_AUTHOR("Devin Heitmueller");
+MODULE_LICENSE("GPL");
+
+static int au8522_analog_debug;
+
+
+module_param_named(analog_debug, au8522_analog_debug, int, 0644);
+
+MODULE_PARM_DESC(analog_debug,
+ "Analog debugging messages [0=Off (default) 1=On]");
+
+struct au8522_register_config {
+ u16 reg_name;
+ u8 reg_val[8];
+};
+
+
+/* Video Decoder Filter Coefficients
+ The values are as follows from left to right
+ 0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13"
+*/
+struct au8522_register_config filter_coef[] = {
+ {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40} },
+ {AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09} },
+ {AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38} },
+ {AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff} },
+ {AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7} },
+ {AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf} },
+ {AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06} },
+ {AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30} },
+ {AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01} },
+ {AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd} },
+ {AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf} },
+ {AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7} },
+ {AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb} },
+ {AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0} },
+ {AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f} },
+ {AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8} },
+ {AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb} },
+ {AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5} },
+ {AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e} },
+ {AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15} },
+ {AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34} },
+
+};
+#define NUM_FILTER_COEF (sizeof(filter_coef)\
+ / sizeof(struct au8522_register_config))
+
+
+/* Registers 0x060b through 0x0652 are the LP Filter coefficients
+ The values are as follows from left to right
+ 0="SIF" 1="ATVRF/ATVRF13"
+ Note: the "ATVRF/ATVRF13" mode has never been tested
+*/
+struct au8522_register_config lpfilter_coef[] = {
+ {0x060b, {0x21, 0x0b} },
+ {0x060c, {0xad, 0xad} },
+ {0x060d, {0x70, 0xf0} },
+ {0x060e, {0xea, 0xe9} },
+ {0x060f, {0xdd, 0xdd} },
+ {0x0610, {0x08, 0x64} },
+ {0x0611, {0x60, 0x60} },
+ {0x0612, {0xf8, 0xb2} },
+ {0x0613, {0x01, 0x02} },
+ {0x0614, {0xe4, 0xb4} },
+ {0x0615, {0x19, 0x02} },
+ {0x0616, {0xae, 0x2e} },
+ {0x0617, {0xee, 0xc5} },
+ {0x0618, {0x56, 0x56} },
+ {0x0619, {0x30, 0x58} },
+ {0x061a, {0xf9, 0xf8} },
+ {0x061b, {0x24, 0x64} },
+ {0x061c, {0x07, 0x07} },
+ {0x061d, {0x30, 0x30} },
+ {0x061e, {0xa9, 0xed} },
+ {0x061f, {0x09, 0x0b} },
+ {0x0620, {0x42, 0xc2} },
+ {0x0621, {0x1d, 0x2a} },
+ {0x0622, {0xd6, 0x56} },
+ {0x0623, {0x95, 0x8b} },
+ {0x0624, {0x2b, 0x2b} },
+ {0x0625, {0x30, 0x24} },
+ {0x0626, {0x3e, 0x3e} },
+ {0x0627, {0x62, 0xe2} },
+ {0x0628, {0xe9, 0xf5} },
+ {0x0629, {0x99, 0x19} },
+ {0x062a, {0xd4, 0x11} },
+ {0x062b, {0x03, 0x04} },
+ {0x062c, {0xb5, 0x85} },
+ {0x062d, {0x1e, 0x20} },
+ {0x062e, {0x2a, 0xea} },
+ {0x062f, {0xd7, 0xd2} },
+ {0x0630, {0x15, 0x15} },
+ {0x0631, {0xa3, 0xa9} },
+ {0x0632, {0x1f, 0x1f} },
+ {0x0633, {0xf9, 0xd1} },
+ {0x0634, {0xc0, 0xc3} },
+ {0x0635, {0x4d, 0x8d} },
+ {0x0636, {0x21, 0x31} },
+ {0x0637, {0x83, 0x83} },
+ {0x0638, {0x08, 0x8c} },
+ {0x0639, {0x19, 0x19} },
+ {0x063a, {0x45, 0xa5} },
+ {0x063b, {0xef, 0xec} },
+ {0x063c, {0x8a, 0x8a} },
+ {0x063d, {0xf4, 0xf6} },
+ {0x063e, {0x8f, 0x8f} },
+ {0x063f, {0x44, 0x0c} },
+ {0x0640, {0xef, 0xf0} },
+ {0x0641, {0x66, 0x66} },
+ {0x0642, {0xcc, 0xd2} },
+ {0x0643, {0x41, 0x41} },
+ {0x0644, {0x63, 0x93} },
+ {0x0645, {0x8e, 0x8e} },
+ {0x0646, {0xa2, 0x42} },
+ {0x0647, {0x7b, 0x7b} },
+ {0x0648, {0x04, 0x04} },
+ {0x0649, {0x00, 0x00} },
+ {0x064a, {0x40, 0x40} },
+ {0x064b, {0x8c, 0x98} },
+ {0x064c, {0x00, 0x00} },
+ {0x064d, {0x63, 0xc3} },
+ {0x064e, {0x04, 0x04} },
+ {0x064f, {0x20, 0x20} },
+ {0x0650, {0x00, 0x00} },
+ {0x0651, {0x40, 0x40} },
+ {0x0652, {0x01, 0x01} },
+};
+#define NUM_LPFILTER_COEF (sizeof(lpfilter_coef)\
+ / sizeof(struct au8522_register_config))
+
+static inline struct au8522_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct au8522_state, sd);
+}
+
+static void setup_vbi(struct au8522_state *state, int aud_input)
+{
+ int i;
+
+ /* These are set to zero regardless of what mode we're in */
+ au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H,
+ 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H,
+ 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H,
+ 0x00);
+
+ /* Setup the VBI registers */
+ for (i = 0x30; i < 0x60; i++)
+ au8522_writereg(state, i, 0x40);
+
+ /* For some reason, every register is 0x40 except register 0x44
+ (confirmed via the HVR-950q USB capture) */
+ au8522_writereg(state, 0x44, 0x60);
+
+ /* Enable VBI (we always do this regardless of whether the user is
+ viewing closed caption info) */
+ au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H,
+ AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON);
+
+}
+
+static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
+{
+ int i;
+ int filter_coef_type;
+
+ /* Provide reasonable defaults for picture tuning values */
+ au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07);
+ au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed);
+ state->brightness = 0xed - 128;
+ au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79);
+ state->contrast = 0x79;
+ au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
+ au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
+ au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
+
+ /* Other decoder registers */
+ au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
+
+ if (input_mode == 0x23) {
+ /* S-Video input mapping */
+ au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04);
+ } else {
+ /* All other modes (CVBS/ATVRF etc.) */
+ au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00);
+ }
+
+ au8522_writereg(state, AU8522_TVDEC_PGA_REG012H,
+ AU8522_TVDEC_PGA_REG012H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_MODE_REG015H,
+ AU8522_TVDEC_COMB_MODE_REG015H_CVBS);
+ au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
+ AU8522_TVDED_DBG_MODE_REG060H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
+ AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13);
+ au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
+ AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13);
+ au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
+ AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
+ AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR1_REG065H,
+ AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR2_REG066H,
+ AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR3_REG067H,
+ AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_NOTCH_THR_REG068H,
+ AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR1_REG069H,
+ AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR2_REG06AH,
+ AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
+ AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
+ AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
+ AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH,
+ AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH,
+ AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H,
+ AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS);
+ au8522_writereg(state, AU8522_REG071H, AU8522_REG071H_CVBS);
+ au8522_writereg(state, AU8522_REG072H, AU8522_REG072H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H,
+ AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS);
+ au8522_writereg(state, AU8522_REG074H, AU8522_REG074H_CVBS);
+ au8522_writereg(state, AU8522_REG075H, AU8522_REG075H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_DCAGC_CTRL_REG077H,
+ AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_PIC_START_ADJ_REG078H,
+ AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H,
+ AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH,
+ AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_INTRP_CTRL_REG07BH,
+ AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H,
+ AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS);
+ au8522_writereg(state, AU8522_TOREGAAGC_REG0E5H,
+ AU8522_TOREGAAGC_REG0E5H_CVBS);
+ au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS);
+
+ setup_vbi(state, 0);
+
+ if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
+ input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
+ /* Despite what the table says, for the HVR-950q we still need
+ to be in CVBS mode for the S-Video input (reason uknown). */
+ /* filter_coef_type = 3; */
+ filter_coef_type = 5;
+ } else {
+ filter_coef_type = 5;
+ }
+
+ /* Load the Video Decoder Filter Coefficients */
+ for (i = 0; i < NUM_FILTER_COEF; i++) {
+ au8522_writereg(state, filter_coef[i].reg_name,
+ filter_coef[i].reg_val[filter_coef_type]);
+ }
+
+ /* It's not clear what these registers are for, but they are always
+ set to the same value regardless of what mode we're in */
+ au8522_writereg(state, AU8522_REG42EH, 0x87);
+ au8522_writereg(state, AU8522_REG42FH, 0xa2);
+ au8522_writereg(state, AU8522_REG430H, 0xbf);
+ au8522_writereg(state, AU8522_REG431H, 0xcb);
+ au8522_writereg(state, AU8522_REG432H, 0xa1);
+ au8522_writereg(state, AU8522_REG433H, 0x41);
+ au8522_writereg(state, AU8522_REG434H, 0x88);
+ au8522_writereg(state, AU8522_REG435H, 0xc2);
+ au8522_writereg(state, AU8522_REG436H, 0x3c);
+}
+
+static void au8522_setup_cvbs_mode(struct au8522_state *state)
+{
+ /* here we're going to try the pre-programmed route */
+ au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+ AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
+
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
+ au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
+
+ au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+ AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
+
+ setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
+{
+ /* here we're going to try the pre-programmed route */
+ au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+ AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
+
+ /* It's not clear why they turn off the PGA before enabling the clamp
+ control, but the Windows trace does it so we will too... */
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
+
+ /* Enable clamping control */
+ au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
+
+ /* Turn on the PGA */
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
+
+ /* Set input mode to CVBS on channel 4 with SIF audio input enabled */
+ au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+ AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
+
+ setup_decoder_defaults(state,
+ AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+static void au8522_setup_svideo_mode(struct au8522_state *state)
+{
+ au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+ AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO);
+
+ /* Set input to Y on Channe1, C on Channel 3 */
+ au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+ AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
+
+ /* Disable clamping control (required for S-video) */
+ au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
+
+ setup_decoder_defaults(state,
+ AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static void disable_audio_input(struct au8522_state *state)
+{
+ /* This can probably be optimized */
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
+ au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
+ au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
+
+ au8522_writereg(state, AU8522_ENA_USB_REG101H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+ au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
+ au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x40);
+
+ au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x11);
+ msleep(5);
+ au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x00);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04);
+ au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
+ au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+/* 0=disable, 1=SIF */
+static void set_audio_input(struct au8522_state *state, int aud_input)
+{
+ int i;
+
+ /* Note that this function needs to be used in conjunction with setting
+ the input routing via register 0x81 */
+
+ if (aud_input == AU8522_AUDIO_NONE) {
+ disable_audio_input(state);
+ return;
+ }
+
+ if (aud_input != AU8522_AUDIO_SIF) {
+ /* The caller asked for a mode we don't currently support */
+ printk(KERN_ERR "Unsupported audio mode requested! mode=%d\n",
+ aud_input);
+ return;
+ }
+
+ /* Load the Audio Decoder Filter Coefficients */
+ for (i = 0; i < NUM_LPFILTER_COEF; i++) {
+ au8522_writereg(state, lpfilter_coef[i].reg_name,
+ lpfilter_coef[i].reg_val[0]);
+ }
+
+ /* Setup audio */
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
+ au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
+ au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
+ msleep(150);
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
+ msleep(1);
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d);
+ msleep(50);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff);
+ msleep(80);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+ au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
+ au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82);
+ msleep(70);
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09);
+ au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
+ au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct au8522_state *state = to_state(sd);
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ state->brightness = ctrl->value;
+ au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH,
+ ctrl->value - 128);
+ break;
+ case V4L2_CID_CONTRAST:
+ state->contrast = ctrl->value;
+ au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH,
+ ctrl->value);
+ break;
+ case V4L2_CID_SATURATION:
+ case V4L2_CID_HUE:
+ case V4L2_CID_AUDIO_VOLUME:
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ case V4L2_CID_AUDIO_BALANCE:
+ case V4L2_CID_AUDIO_MUTE:
+ /* Not yet implemented */
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct au8522_state *state = to_state(sd);
+
+ /* Note that we are using values cached in the state structure instead
+ of reading the registers due to issues with i2c reads not working
+ properly/consistently yet on the HVR-950q */
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = state->brightness;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = state->contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ case V4L2_CID_HUE:
+ case V4L2_CID_AUDIO_VOLUME:
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ case V4L2_CID_AUDIO_BALANCE:
+ case V4L2_CID_AUDIO_MUTE:
+ /* Not yet supported */
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ switch (fmt->type) {
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int au8522_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ switch (fmt->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ /* Not yet implemented */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int au8522_g_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct au8522_state *state = to_state(sd);
+
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ reg->val = au8522_readreg(state, reg->reg & 0xffff);
+ return 0;
+}
+
+static int au8522_s_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct au8522_state *state = to_state(sd);
+
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ au8522_writereg(state, reg->reg, reg->val & 0xff);
+ return 0;
+}
+#endif
+
+static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct au8522_state *state = to_state(sd);
+
+ if (enable) {
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ 0x01);
+ msleep(1);
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+ } else {
+ /* This does not completely power down the device
+ (it only reduces it from around 140ma to 80ma) */
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ 1 << 5);
+ }
+ return 0;
+}
+
+static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ switch (qc->id) {
+ case V4L2_CID_CONTRAST:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1,
+ AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+ case V4L2_CID_SATURATION:
+ case V4L2_CID_HUE:
+ /* Not yet implemented */
+ default:
+ break;
+ }
+
+ qc->type = 0;
+ return -EINVAL;
+}
+
+static int au8522_reset(struct v4l2_subdev *sd, u32 val)
+{
+ struct au8522_state *state = to_state(sd);
+
+ au8522_writereg(state, 0xa4, 1 << 5);
+
+ return 0;
+}
+
+static int au8522_s_video_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
+{
+ struct au8522_state *state = to_state(sd);
+
+ au8522_reset(sd, 0);
+
+ /* Jam open the i2c gate to the tuner. We do this here to handle the
+ case where the user went into digital mode (causing the gate to be
+ closed), and then came back to analog mode */
+ au8522_writereg(state, 0x106, 1);
+
+ if (route->input == AU8522_COMPOSITE_CH1) {
+ au8522_setup_cvbs_mode(state);
+ } else if (route->input == AU8522_SVIDEO_CH13) {
+ au8522_setup_svideo_mode(state);
+ } else if (route->input == AU8522_COMPOSITE_CH4_SIF) {
+ au8522_setup_cvbs_tuner_mode(state);
+ } else {
+ printk(KERN_ERR "au8522 mode not currently supported\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int au8522_s_audio_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
+{
+ struct au8522_state *state = to_state(sd);
+ set_audio_input(state, route->input);
+ return 0;
+}
+
+static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
+{
+ int val = 0;
+ struct au8522_state *state = to_state(sd);
+ u8 lock_status;
+
+ /* Interrogate the decoder to see if we are getting a real signal */
+ lock_status = au8522_readreg(state, 0x00);
+ if (lock_status == 0xa2)
+ vt->signal = 0x01;
+ else
+ vt->signal = 0x00;
+
+ vt->capability |=
+ V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
+ V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+
+ val = V4L2_TUNER_SUB_MONO;
+ vt->rxsubchans = val;
+ vt->audmode = V4L2_TUNER_MODE_STEREO;
+ return 0;
+}
+
+static int au8522_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct au8522_state *state = to_state(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
+}
+
+static int au8522_log_status(struct v4l2_subdev *sd)
+{
+ /* FIXME: Add some status info here */
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops au8522_core_ops = {
+ .log_status = au8522_log_status,
+ .g_chip_ident = au8522_g_chip_ident,
+ .g_ctrl = au8522_g_ctrl,
+ .s_ctrl = au8522_s_ctrl,
+ .queryctrl = au8522_queryctrl,
+ .reset = au8522_reset,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = au8522_g_register,
+ .s_register = au8522_s_register,
+#endif
+};
+
+static const struct v4l2_subdev_tuner_ops au8522_tuner_ops = {
+ .g_tuner = au8522_g_tuner,
+};
+
+static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
+ .s_routing = au8522_s_audio_routing,
+};
+
+static const struct v4l2_subdev_video_ops au8522_video_ops = {
+ .s_routing = au8522_s_video_routing,
+ .g_fmt = au8522_g_fmt,
+ .s_fmt = au8522_s_fmt,
+ .s_stream = au8522_s_stream,
+};
+
+static const struct v4l2_subdev_ops au8522_ops = {
+ .core = &au8522_core_ops,
+ .tuner = &au8522_tuner_ops,
+ .audio = &au8522_audio_ops,
+ .video = &au8522_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
+{
+ struct au8522_state *state;
+ struct v4l2_subdev *sd;
+ int instance;
+ struct au8522_config *demod_config;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA)) {
+ return -EIO;
+ }
+
+ /* allocate memory for the internal state */
+ instance = au8522_get_state(&state, client->adapter, client->addr);
+ switch (instance) {
+ case 0:
+ printk(KERN_ERR "au8522_decoder allocation failed\n");
+ return -EIO;
+ case 1:
+ /* new demod instance */
+ printk(KERN_INFO "au8522_decoder creating new instance...\n");
+ break;
+ default:
+ /* existing demod instance */
+ printk(KERN_INFO "au8522_decoder attach existing instance.\n");
+ break;
+ }
+
+ demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
+ demod_config->demod_address = 0x8e >> 1;
+
+ state->config = demod_config;
+ state->i2c = client->adapter;
+
+ sd = &state->sd;
+ v4l2_i2c_subdev_init(sd, client, &au8522_ops);
+
+ state->c = client;
+ state->vid_input = AU8522_COMPOSITE_CH1;
+ state->aud_input = AU8522_AUDIO_NONE;
+ state->id = 8522;
+ state->rev = 0;
+
+ /* Jam open the i2c gate to the tuner */
+ au8522_writereg(state, 0x106, 1);
+
+ return 0;
+}
+
+static int au8522_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ v4l2_device_unregister_subdev(sd);
+ au8522_release_state(to_state(sd));
+ return 0;
+}
+
+static const struct i2c_device_id au8522_id[] = {
+ {"au8522", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, au8522_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "au8522",
+ .probe = au8522_probe,
+ .remove = au8522_remove,
+ .id_table = au8522_id,
+};
diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522_dig.c
index eabf9a68e7ec..35731258bb0a 100644
--- a/drivers/media/dvb/frontends/au8522.c
+++ b/drivers/media/dvb/frontends/au8522_dig.c
@@ -27,35 +27,25 @@
#include <linux/delay.h>
#include "dvb_frontend.h"
#include "au8522.h"
-
-struct au8522_state {
-
- struct i2c_adapter *i2c;
-
- /* configuration settings */
- const struct au8522_config *config;
-
- struct dvb_frontend frontend;
-
- u32 current_frequency;
- fe_modulation_t current_modulation;
-
- u32 fe_status;
- unsigned int led_state;
-};
+#include "au8522_priv.h"
static int debug;
-#define dprintk(arg...) do { \
- if (debug) \
- printk(arg); \
+/* Despite the name "hybrid_tuner", the framework works just as well for
+ hybrid demodulators as well... */
+static LIST_HEAD(hybrid_tuner_instance_list);
+static DEFINE_MUTEX(au8522_list_mutex);
+
+#define dprintk(arg...)\
+ do { if (debug)\
+ printk(arg);\
} while (0)
/* 16 bit registers, 8 bit values */
-static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
+int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
{
int ret;
- u8 buf [] = { reg >> 8, reg & 0xff, data };
+ u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
struct i2c_msg msg = { .addr = state->config->demod_address,
.flags = 0, .buf = buf, .len = 3 };
@@ -69,13 +59,13 @@ static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
return (ret != 1) ? -1 : 0;
}
-static u8 au8522_readreg(struct au8522_state *state, u16 reg)
+u8 au8522_readreg(struct au8522_state *state, u16 reg)
{
int ret;
- u8 b0 [] = { reg >> 8, reg & 0xff };
- u8 b1 [] = { 0 };
+ u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff };
+ u8 b1[] = { 0 };
- struct i2c_msg msg [] = {
+ struct i2c_msg msg[] = {
{ .addr = state->config->demod_address, .flags = 0,
.buf = b0, .len = 2 },
{ .addr = state->config->demod_address, .flags = I2C_M_RD,
@@ -528,7 +518,7 @@ static int au8522_set_frontend(struct dvb_frontend *fe,
/* Reset the demod hardware and reset all of the configuration registers
to a default state. */
-static int au8522_init(struct dvb_frontend *fe)
+int au8522_init(struct dvb_frontend *fe)
{
struct au8522_state *state = fe->demodulator_priv;
dprintk("%s()\n", __func__);
@@ -624,7 +614,7 @@ static int au8522_led_ctrl(struct au8522_state *state, int led)
return 0;
}
-static int au8522_sleep(struct dvb_frontend *fe)
+int au8522_sleep(struct dvb_frontend *fe)
{
struct au8522_state *state = fe->demodulator_priv;
dprintk("%s()\n", __func__);
@@ -632,6 +622,9 @@ static int au8522_sleep(struct dvb_frontend *fe)
/* turn off led */
au8522_led_ctrl(state, 0);
+ /* Power down the chip */
+ au8522_writereg(state, 0xa4, 1 << 5);
+
state->current_frequency = 0;
return 0;
@@ -798,23 +791,58 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe,
return 0;
}
+static struct dvb_frontend_ops au8522_ops;
+
+int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
+ u8 client_address)
+{
+ int ret;
+
+ mutex_lock(&au8522_list_mutex);
+ ret = hybrid_tuner_request_state(struct au8522_state, (*state),
+ hybrid_tuner_instance_list,
+ i2c, client_address, "au8522");
+ mutex_unlock(&au8522_list_mutex);
+
+ return ret;
+}
+
+void au8522_release_state(struct au8522_state *state)
+{
+ mutex_lock(&au8522_list_mutex);
+ if (state != NULL)
+ hybrid_tuner_release_state(state);
+ mutex_unlock(&au8522_list_mutex);
+}
+
+
static void au8522_release(struct dvb_frontend *fe)
{
struct au8522_state *state = fe->demodulator_priv;
- kfree(state);
+ au8522_release_state(state);
}
-static struct dvb_frontend_ops au8522_ops;
-
struct dvb_frontend *au8522_attach(const struct au8522_config *config,
struct i2c_adapter *i2c)
{
struct au8522_state *state = NULL;
+ int instance;
/* allocate memory for the internal state */
- state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL);
- if (state == NULL)
- goto error;
+ instance = au8522_get_state(&state, i2c, config->demod_address);
+ switch (instance) {
+ case 0:
+ dprintk("%s state allocation failed\n", __func__);
+ break;
+ case 1:
+ /* new demod instance */
+ dprintk("%s using new instance\n", __func__);
+ break;
+ default:
+ /* existing demod instance */
+ dprintk("%s using existing instance\n", __func__);
+ break;
+ }
/* setup the state */
state->config = config;
@@ -836,7 +864,7 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config,
return &state->frontend;
error:
- kfree(state);
+ au8522_release_state(state);
return NULL;
}
EXPORT_SYMBOL(au8522_attach);
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h
new file mode 100644
index 000000000000..f328f2b3ad3d
--- /dev/null
+++ b/drivers/media/dvb/frontends/au8522_priv.h
@@ -0,0 +1,412 @@
+/*
+ Auvitek AU8522 QAM/8VSB demodulator driver
+
+ Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
+ Copyright (C) 2008 Devin Heitmueller <dheitmueller@linuxtv.org>
+ Copyright (C) 2005-2008 Auvitek International, Ltd.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+#include "au8522.h"
+#include "tuner-i2c.h"
+
+struct au8522_state {
+ struct i2c_client *c;
+ struct i2c_adapter *i2c;
+
+ /* Used for sharing of the state between analog and digital mode */
+ struct tuner_i2c_props i2c_props;
+ struct list_head hybrid_tuner_instance_list;
+
+ /* configuration settings */
+ const struct au8522_config *config;
+
+ struct dvb_frontend frontend;
+
+ u32 current_frequency;
+ fe_modulation_t current_modulation;
+
+ u32 fe_status;
+ unsigned int led_state;
+
+ /* Analog settings */
+ struct v4l2_subdev sd;
+ v4l2_std_id std;
+ int vid_input;
+ int aud_input;
+ u32 id;
+ u32 rev;
+ u8 brightness;
+ u8 contrast;
+};
+
+/* These are routines shared by both the VSB/QAM demodulator and the analog
+ decoder */
+int au8522_writereg(struct au8522_state *state, u16 reg, u8 data);
+u8 au8522_readreg(struct au8522_state *state, u16 reg);
+int au8522_init(struct dvb_frontend *fe);
+int au8522_sleep(struct dvb_frontend *fe);
+
+int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
+ u8 client_address);
+void au8522_release_state(struct au8522_state *state);
+
+/* REGISTERS */
+#define AU8522_INPUT_CONTROL_REG081H 0x081
+#define AU8522_PGA_CONTROL_REG082H 0x082
+#define AU8522_CLAMPING_CONTROL_REG083H 0x083
+
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H 0x0A3
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H 0x0A4
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H 0x0A5
+#define AU8522_AGC_CONTROL_RANGE_REG0A6H 0x0A6
+#define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H 0x0A7
+#define AU8522_TUNER_AGC_RF_STOP_REG0A8H 0x0A8
+#define AU8522_TUNER_AGC_RF_START_REG0A9H 0x0A9
+#define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH 0x0AA
+#define AU8522_TUNER_AGC_IF_STOP_REG0ABH 0x0AB
+#define AU8522_TUNER_AGC_IF_START_REG0ACH 0x0AC
+#define AU8522_TUNER_AGC_IF_DEFAULT_REG0ADH 0x0AD
+#define AU8522_TUNER_AGC_STEP_REG0AEH 0x0AE
+#define AU8522_TUNER_GAIN_STEP_REG0AFH 0x0AF
+
+/* Receiver registers */
+#define AU8522_FRMREGTHRD1_REG0B0H 0x0B0
+#define AU8522_FRMREGAGC1H_REG0B1H 0x0B1
+#define AU8522_FRMREGSHIFT1_REG0B2H 0x0B2
+#define AU8522_TOREGAGC1_REG0B3H 0x0B3
+#define AU8522_TOREGASHIFT1_REG0B4H 0x0B4
+#define AU8522_FRMREGBBH_REG0B5H 0x0B5
+#define AU8522_FRMREGBBM_REG0B6H 0x0B6
+#define AU8522_FRMREGBBL_REG0B7H 0x0B7
+/* 0xB8 TO 0xD7 are the filter coefficients */
+#define AU8522_FRMREGTHRD2_REG0D8H 0x0D8
+#define AU8522_FRMREGAGC2H_REG0D9H 0x0D9
+#define AU8522_TOREGAGC2_REG0DAH 0x0DA
+#define AU8522_TOREGSHIFT2_REG0DBH 0x0DB
+#define AU8522_FRMREGPILOTH_REG0DCH 0x0DC
+#define AU8522_FRMREGPILOTM_REG0DDH 0x0DD
+#define AU8522_FRMREGPILOTL_REG0DEH 0x0DE
+#define AU8522_TOREGFREQ_REG0DFH 0x0DF
+
+#define AU8522_RX_PGA_RFOUT_REG0EBH 0x0EB
+#define AU8522_RX_PGA_IFOUT_REG0ECH 0x0EC
+#define AU8522_RX_PGA_PGAOUT_REG0EDH 0x0ED
+
+#define AU8522_CHIP_MODE_REG0FEH 0x0FE
+
+/* I2C bus control registers */
+#define AU8522_I2C_CONTROL_REG0_REG090H 0x090
+#define AU8522_I2C_CONTROL_REG1_REG091H 0x091
+#define AU8522_I2C_STATUS_REG092H 0x092
+#define AU8522_I2C_WR_DATA0_REG093H 0x093
+#define AU8522_I2C_WR_DATA1_REG094H 0x094
+#define AU8522_I2C_WR_DATA2_REG095H 0x095
+#define AU8522_I2C_WR_DATA3_REG096H 0x096
+#define AU8522_I2C_WR_DATA4_REG097H 0x097
+#define AU8522_I2C_WR_DATA5_REG098H 0x098
+#define AU8522_I2C_WR_DATA6_REG099H 0x099
+#define AU8522_I2C_WR_DATA7_REG09AH 0x09A
+#define AU8522_I2C_RD_DATA0_REG09BH 0x09B
+#define AU8522_I2C_RD_DATA1_REG09CH 0x09C
+#define AU8522_I2C_RD_DATA2_REG09DH 0x09D
+#define AU8522_I2C_RD_DATA3_REG09EH 0x09E
+#define AU8522_I2C_RD_DATA4_REG09FH 0x09F
+#define AU8522_I2C_RD_DATA5_REG0A0H 0x0A0
+#define AU8522_I2C_RD_DATA6_REG0A1H 0x0A1
+#define AU8522_I2C_RD_DATA7_REG0A2H 0x0A2
+
+#define AU8522_ENA_USB_REG101H 0x101
+
+#define AU8522_I2S_CTRL_0_REG110H 0x110
+#define AU8522_I2S_CTRL_1_REG111H 0x111
+#define AU8522_I2S_CTRL_2_REG112H 0x112
+
+#define AU8522_FRMREGFFECONTROL_REG121H 0x121
+#define AU8522_FRMREGDFECONTROL_REG122H 0x122
+
+#define AU8522_CARRFREQOFFSET0_REG201H 0x201
+#define AU8522_CARRFREQOFFSET1_REG202H 0x202
+
+#define AU8522_DECIMATION_GAIN_REG21AH 0x21A
+#define AU8522_FRMREGIFSLP_REG21BH 0x21B
+#define AU8522_FRMREGTHRDL2_REG21CH 0x21C
+#define AU8522_FRMREGSTEP3DB_REG21DH 0x21D
+#define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH 0x21E
+#define AU8522_FRMREGPLLMODE_REG21FH 0x21F
+#define AU8522_FRMREGCSTHRD_REG220H 0x220
+#define AU8522_FRMREGCRLOCKDMAX_REG221H 0x221
+#define AU8522_FRMREGCRPERIODMASK_REG222H 0x222
+#define AU8522_FRMREGCRLOCK0THH_REG223H 0x223
+#define AU8522_FRMREGCRLOCK1THH_REG224H 0x224
+#define AU8522_FRMREGCRLOCK0THL_REG225H 0x225
+#define AU8522_FRMREGCRLOCK1THL_REG226H 0x226
+#define AU_FRMREGPLLACQPHASESCL_REG227H 0x227
+#define AU8522_FRMREGFREQFBCTRL_REG228H 0x228
+
+/* Analog TV Decoder */
+#define AU8522_TVDEC_STATUS_REG000H 0x000
+#define AU8522_TVDEC_INT_STATUS_REG001H 0x001
+#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 0x002
+#define AU8522_TVDEC_SHARPNESSREG009H 0x009
+#define AU8522_TVDEC_BRIGHTNESS_REG00AH 0x00A
+#define AU8522_TVDEC_CONTRAST_REG00BH 0x00B
+#define AU8522_TVDEC_SATURATION_CB_REG00CH 0x00C
+#define AU8522_TVDEC_SATURATION_CR_REG00DH 0x00D
+#define AU8522_TVDEC_HUE_H_REG00EH 0x00E
+#define AU8522_TVDEC_HUE_L_REG00FH 0x00F
+#define AU8522_TVDEC_INT_MASK_REG010H 0x010
+#define AU8522_VIDEO_MODE_REG011H 0x011
+#define AU8522_TVDEC_PGA_REG012H 0x012
+#define AU8522_TVDEC_COMB_MODE_REG015H 0x015
+#define AU8522_REG016H 0x016
+#define AU8522_TVDED_DBG_MODE_REG060H 0x060
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H 0x061
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H 0x062
+#define AU8522_TVDEC_VCR_DET_LLIM_REG063H 0x063
+#define AU8522_TVDEC_VCR_DET_HLIM_REG064H 0x064
+#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H 0x065
+#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H 0x066
+#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H 0x067
+#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H 0x068
+#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H 0x069
+#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH 0x06A
+#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH 0x06B
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH 0x06C
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 0x06D
+#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH 0x06E
+#define AU8522_TVDEC_UV_SEP_THR_REG06FH 0x06F
+#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H 0x070
+#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H 0x073
+#define AU8522_TVDEC_DCAGC_CTRL_REG077H 0x077
+#define AU8522_TVDEC_PIC_START_ADJ_REG078H 0x078
+#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H 0x079
+#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH 0x07A
+#define AU8522_TVDEC_INTRP_CTRL_REG07BH 0x07B
+#define AU8522_TVDEC_PLL_STATUS_REG07EH 0x07E
+#define AU8522_TVDEC_FSC_FREQ_REG07FH 0x07F
+
+#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H 0x0E4
+#define AU8522_TOREGAAGC_REG0E5H 0x0E5
+
+#define AU8522_TVDEC_CHROMA_AGC_REG401H 0x401
+#define AU8522_TVDEC_CHROMA_SFT_REG402H 0x402
+#define AU8522_FILTER_COEF_R410 0x410
+#define AU8522_FILTER_COEF_R411 0x411
+#define AU8522_FILTER_COEF_R412 0x412
+#define AU8522_FILTER_COEF_R413 0x413
+#define AU8522_FILTER_COEF_R414 0x414
+#define AU8522_FILTER_COEF_R415 0x415
+#define AU8522_FILTER_COEF_R416 0x416
+#define AU8522_FILTER_COEF_R417 0x417
+#define AU8522_FILTER_COEF_R418 0x418
+#define AU8522_FILTER_COEF_R419 0x419
+#define AU8522_FILTER_COEF_R41A 0x41A
+#define AU8522_FILTER_COEF_R41B 0x41B
+#define AU8522_FILTER_COEF_R41C 0x41C
+#define AU8522_FILTER_COEF_R41D 0x41D
+#define AU8522_FILTER_COEF_R41E 0x41E
+#define AU8522_FILTER_COEF_R41F 0x41F
+#define AU8522_FILTER_COEF_R420 0x420
+#define AU8522_FILTER_COEF_R421 0x421
+#define AU8522_FILTER_COEF_R422 0x422
+#define AU8522_FILTER_COEF_R423 0x423
+#define AU8522_FILTER_COEF_R424 0x424
+#define AU8522_FILTER_COEF_R425 0x425
+#define AU8522_FILTER_COEF_R426 0x426
+#define AU8522_FILTER_COEF_R427 0x427
+#define AU8522_FILTER_COEF_R428 0x428
+#define AU8522_FILTER_COEF_R429 0x429
+#define AU8522_FILTER_COEF_R42A 0x42A
+#define AU8522_FILTER_COEF_R42B 0x42B
+#define AU8522_FILTER_COEF_R42C 0x42C
+#define AU8522_FILTER_COEF_R42D 0x42D
+
+/* VBI Control Registers */
+#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H 0x004
+#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H 0x005
+#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H 0x006
+#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H 0x007
+#define AU8522_TVDEC_VBI_CTRL_H_REG017H 0x017
+#define AU8522_TVDEC_VBI_CTRL_L_REG018H 0x018
+#define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H 0x019
+#define AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH 0x01A
+#define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH 0x01B
+#define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH 0x01C
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH 0x01E
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH 0x01F
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H 0x020
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 0x021
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H 0x022
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H 0x023
+
+#define AU8522_REG071H 0x071
+#define AU8522_REG072H 0x072
+#define AU8522_REG074H 0x074
+#define AU8522_REG075H 0x075
+
+/* Digital Demodulator Registers */
+#define AU8522_FRAME_COUNT0_REG084H 0x084
+#define AU8522_RS_STATUS_G0_REG085H 0x085
+#define AU8522_RS_STATUS_B0_REG086H 0x086
+#define AU8522_RS_STATUS_E_REG087H 0x087
+#define AU8522_DEMODULATION_STATUS_REG088H 0x088
+#define AU8522_TOREGTRESTATUS_REG0E6H 0x0E6
+#define AU8522_TSPORT_CONTROL_REG10BH 0x10B
+#define AU8522_TSTHES_REG10CH 0x10C
+#define AU8522_FRMREGDFEKEEP_REG301H 0x301
+#define AU8522_DFE_AVERAGE_REG302H 0x302
+#define AU8522_FRMREGEQLERRWIN_REG303H 0x303
+#define AU8522_FRMREGFFEKEEP_REG304H 0x304
+#define AU8522_FRMREGDFECONTROL1_REG305H 0x305
+#define AU8522_FRMREGEQLERRLOW_REG306H 0x306
+
+#define AU8522_REG42EH 0x42E
+#define AU8522_REG42FH 0x42F
+#define AU8522_REG430H 0x430
+#define AU8522_REG431H 0x431
+#define AU8522_REG432H 0x432
+#define AU8522_REG433H 0x433
+#define AU8522_REG434H 0x434
+#define AU8522_REG435H 0x435
+#define AU8522_REG436H 0x436
+
+/* GPIO Registers */
+#define AU8522_GPIO_CONTROL_REG0E0H 0x0E0
+#define AU8522_GPIO_STATUS_REG0E1H 0x0E1
+#define AU8522_GPIO_DATA_REG0E2H 0x0E2
+
+/* Audio Control Registers */
+#define AU8522_AUDIOAGC_REG0EEH 0x0EE
+#define AU8522_AUDIO_STATUS_REG0F0H 0x0F0
+#define AU8522_AUDIO_MODE_REG0F1H 0x0F1
+#define AU8522_AUDIO_VOLUME_L_REG0F2H 0x0F2
+#define AU8522_AUDIO_VOLUME_R_REG0F3H 0x0F3
+#define AU8522_AUDIO_VOLUME_REG0F4H 0x0F4
+#define AU8522_FRMREGAUPHASE_REG0F7H 0x0F7
+#define AU8522_REG0F9H 0x0F9
+
+#define AU8522_AUDIOAGC2_REG605H 0x605
+#define AU8522_AUDIOFREQ_REG606H 0x606
+
+
+/**************************************************************/
+
+#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_ATVRF 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_ATVRF13 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_J83B64 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_J83B256 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_CVBS 0x20
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1 0xA2
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2 0xA0
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3 0x69
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4 0x68
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF 0x28
+/* CH1 AS Y,CH3 AS C */
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 0x23
+/* CH2 AS Y,CH4 AS C */
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24 0x20
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC 0x0C
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64 0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256 0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS 0x12
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF 0x1A
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13 0x1A
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO 0x02
+
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR 0x00
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO 0x9C
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS 0x9D
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC 0xE8
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64 0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF 0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13 0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL 0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM 0xDD
+
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC 0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64 0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC 0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256 0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64 0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR 0x00
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF 0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13 0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO 0x04
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS 0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM 0x03
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS 0x09
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL 0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM 0x01
+
+/* STILL NEED TO BE REFACTORED @@@@@@@@@@@@@@ */
+#define AU8522_TVDEC_CONTRAST_REG00BH_CVBS 0x79
+#define AU8522_TVDEC_SATURATION_CB_REG00CH_CVBS 0x80
+#define AU8522_TVDEC_SATURATION_CR_REG00DH_CVBS 0x80
+#define AU8522_TVDEC_HUE_H_REG00EH_CVBS 0x00
+#define AU8522_TVDEC_HUE_L_REG00FH_CVBS 0x00
+#define AU8522_TVDEC_PGA_REG012H_CVBS 0x0F
+#define AU8522_TVDEC_COMB_MODE_REG015H_CVBS 0x00
+#define AU8522_REG016H_CVBS 0x00
+#define AU8522_TVDED_DBG_MODE_REG060H_CVBS 0x00
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS 0x0B
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13 0x03
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13 0x00
+#define AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS 0x19
+#define AU8522_REG0F9H_AUDIO 0x20
+#define AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS 0xA7
+#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS 0x0A
+#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS 0x32
+#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS 0x19
+#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS 0x23
+#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS 0x41
+#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS 0x0A
+#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS 0x32
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS 0x34
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS 0x05
+#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS 0x6E
+#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS 0x0F
+#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS 0x80
+#define AU8522_REG071H_CVBS 0x18
+#define AU8522_REG072H_CVBS 0x30
+#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS 0xF0
+#define AU8522_REG074H_CVBS 0x80
+#define AU8522_REG075H_CVBS 0xF0
+#define AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS 0xFB
+#define AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS 0x04
+#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS 0x00
+#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS 0x00
+#define AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS 0xEE
+#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS 0xFE
+#define AU8522_TOREGAAGC_REG0E5H_CVBS 0x00
+#define AU8522_TVDEC_VBI6A_REG035H_CVBS 0x40
+
+/* Enables Closed captioning */
+#define AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON 0x21
diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c
index f6e7b0380a5a..e4fd533a427c 100644
--- a/drivers/media/dvb/frontends/cx24113.c
+++ b/drivers/media/dvb/frontends/cx24113.c
@@ -559,7 +559,7 @@ struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
kzalloc(sizeof(struct cx24113_state), GFP_KERNEL);
int rc;
if (state == NULL) {
- err("Unable to kmalloc\n");
+ err("Unable to kzalloc\n");
goto error;
}
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
index 28ad609e73f4..9b9f57264cef 100644
--- a/drivers/media/dvb/frontends/cx24116.c
+++ b/drivers/media/dvb/frontends/cx24116.c
@@ -15,6 +15,9 @@
September, 9th 2008
Fixed locking on high symbol rates (>30000).
Implement MPEG initialization parameter.
+ January, 17th 2009
+ Fill set_voltage with actually control voltage code.
+ Correct set tone to not affect voltage.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -146,7 +149,7 @@ enum cmds {
CMD_GETAGC = 0x19,
CMD_LNBCONFIG = 0x20,
CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */
- CMD_SET_TONEPRE = 0x22,
+ CMD_LNBDCLEVEL = 0x22,
CMD_SET_TONE = 0x23,
CMD_UPDFWVERS = 0x35,
CMD_TUNERSLEEP = 0x36,
@@ -667,16 +670,6 @@ static int cx24116_load_firmware(struct dvb_frontend *fe,
return 0;
}
-static int cx24116_set_voltage(struct dvb_frontend *fe,
- fe_sec_voltage_t voltage)
-{
- /* The isl6421 module will override this function in the fops. */
- dprintk("%s() This should never appear if the isl6421 module "
- "is loaded correctly\n", __func__);
-
- return -EOPNOTSUPP;
-}
-
static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct cx24116_state *state = fe->demodulator_priv;
@@ -837,6 +830,34 @@ static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
return -ETIMEDOUT; /* -EBUSY ? */
}
+static int cx24116_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
+{
+ struct cx24116_cmd cmd;
+ int ret;
+
+ dprintk("%s: %s\n", __func__,
+ voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
+ voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
+
+ /* Wait for LNB ready */
+ ret = cx24116_wait_for_lnb(fe);
+ if (ret != 0)
+ return ret;
+
+ /* Wait for voltage/min repeat delay */
+ msleep(100);
+
+ cmd.args[0x00] = CMD_LNBDCLEVEL;
+ cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
+ cmd.len = 0x02;
+
+ /* Min delay time before DiSEqC send */
+ msleep(15);
+
+ return cx24116_cmd_execute(fe, &cmd);
+}
+
static int cx24116_set_tone(struct dvb_frontend *fe,
fe_sec_tone_mode_t tone)
{
@@ -857,14 +878,6 @@ static int cx24116_set_tone(struct dvb_frontend *fe,
/* Min delay time after DiSEqC send */
msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
- /* This is always done before the tone is set */
- cmd.args[0x00] = CMD_SET_TONEPRE;
- cmd.args[0x01] = 0x00;
- cmd.len = 0x02;
- ret = cx24116_cmd_execute(fe, &cmd);
- if (ret != 0)
- return ret;
-
/* Now we set the tone */
cmd.args[0x00] = CMD_SET_TONE;
cmd.args[0x01] = 0x00;
@@ -1099,13 +1112,10 @@ struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
dprintk("%s\n", __func__);
/* allocate memory for the internal state */
- state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL);
+ state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL);
if (state == NULL)
goto error1;
- /* setup the state */
- memset(state, 0, sizeof(struct cx24116_state));
-
state->config = config;
state->i2c = i2c;
@@ -1154,7 +1164,12 @@ static int cx24116_initfe(struct dvb_frontend *fe)
if (ret != 0)
return ret;
- return cx24116_diseqc_init(fe);
+ ret = cx24116_diseqc_init(fe);
+ if (ret != 0)
+ return ret;
+
+ /* HVR-4000 needs this */
+ return cx24116_set_voltage(fe, SEC_VOLTAGE_13);
}
/*
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index 1a8c36f76061..0592f043ea64 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -1069,13 +1069,13 @@ static struct dvb_frontend_ops cx24123_ops;
struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
struct i2c_adapter *i2c)
{
+ /* allocate memory for the internal state */
struct cx24123_state *state =
kzalloc(sizeof(struct cx24123_state), GFP_KERNEL);
dprintk("\n");
- /* allocate memory for the internal state */
if (state == NULL) {
- err("Unable to kmalloc\n");
+ err("Unable to kzalloc\n");
goto error;
}
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h
index 21f2c5161af4..9670f5d20cfb 100644
--- a/drivers/media/dvb/frontends/dib0070.h
+++ b/drivers/media/dvb/frontends/dib0070.h
@@ -58,6 +58,4 @@ static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
}
#endif
-extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open);
-
#endif
diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h
index 4142ed7a47d0..d75ffad2d752 100644
--- a/drivers/media/dvb/frontends/dib3000mc.h
+++ b/drivers/media/dvb/frontends/dib3000mc.h
@@ -39,19 +39,43 @@ struct dib3000mc_config {
#define DEFAULT_DIB3000MC_I2C_ADDRESS 16
#define DEFAULT_DIB3000P_I2C_ADDRESS 24
-#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE))
-extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg);
+#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && \
+ defined(MODULE))
+extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap,
+ u8 i2c_addr,
+ struct dib3000mc_config *cfg);
+extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c,
+ int no_of_demods, u8 default_addr,
+ struct dib3000mc_config cfg[]);
+extern
+struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod,
+ int gating);
#else
-static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
+static inline
+struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
+ struct dib3000mc_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-#endif // CONFIG_DVB_DIB3000MC
-extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[]);
+static inline
+int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c,
+ int no_of_demods, u8 default_addr,
+ struct dib3000mc_config cfg[])
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return -ENODEV;
+}
-extern struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating);
+static inline
+struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod,
+ int gating)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif // CONFIG_DVB_DIB3000MC
extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff);
extern int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff);
diff --git a/drivers/media/dvb/frontends/dib7000m.h b/drivers/media/dvb/frontends/dib7000m.h
index 597e9cc2da62..113819ce9f0d 100644
--- a/drivers/media/dvb/frontends/dib7000m.h
+++ b/drivers/media/dvb/frontends/dib7000m.h
@@ -38,8 +38,32 @@ struct dib7000m_config {
#define DEFAULT_DIB7000M_I2C_ADDRESS 18
-extern struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg);
-extern struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
+#if defined(CONFIG_DVB_DIB7000M) || (defined(CONFIG_DVB_DIB7000M_MODULE) && \
+ defined(MODULE))
+extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
+ u8 i2c_addr,
+ struct dib7000m_config *cfg);
+extern struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *,
+ enum dibx000_i2c_interface,
+ int);
+#else
+static inline
+struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
+ u8 i2c_addr, struct dib7000m_config *cfg)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+
+static inline
+struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *demod,
+ enum dibx000_i2c_interface intf,
+ int gating)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
/* TODO
extern INT dib7000m_set_gpio(struct dibDemod *demod, UCHAR num, UCHAR dir, UCHAR val);
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
index aab8112e2db2..02a4c82f0c70 100644
--- a/drivers/media/dvb/frontends/dib7000p.h
+++ b/drivers/media/dvb/frontends/dib7000p.h
@@ -37,7 +37,8 @@ struct dib7000p_config {
#define DEFAULT_DIB7000P_I2C_ADDRESS 18
-#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && defined(MODULE))
+#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \
+ defined(MODULE))
extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
u8 i2c_addr,
struct dib7000p_config *cfg);
@@ -49,10 +50,11 @@ extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
struct dib7000p_config cfg[]);
extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
+extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
#else
-static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
- u8 i2c_addr,
- struct dib7000p_config *cfg)
+static inline
+struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
+ struct dib7000p_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
@@ -60,36 +62,39 @@ static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
static inline
struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe,
- enum dibx000_i2c_interface i, int x)
+ enum dibx000_i2c_interface i,
+ int x)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-static inline
-int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
- int no_of_demods, u8 default_addr,
- struct dib7000p_config cfg[])
+static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
+ int no_of_demods, u8 default_addr,
+ struct dib7000p_config cfg[])
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
-static inline
-int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+static inline int dib7000p_set_gpio(struct dvb_frontend *fe,
+ u8 num, u8 dir, u8 val)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
-static inline
-int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+static inline int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
-#endif
-extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
+static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return -ENODEV;
+}
+#endif
#endif
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index 1e81e713df63..172f1f928f02 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -74,7 +74,7 @@ static struct {
} fw[] = {
#define _FW_ENTRY(a, b, c) { \
.name = a, \
- .file = 0, \
+ .file = NULL, \
.lock = __RW_LOCK_UNLOCKED(fw[c].lock), \
.refcnt = 0, \
.data = { } }
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.h b/drivers/media/dvb/frontends/dvb_dummy_fe.h
index 8210f19d56ce..1fcb987d6386 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.h
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.h
@@ -25,8 +25,27 @@
#include <linux/dvb/frontend.h>
#include "dvb_frontend.h"
+#if defined(CONFIG_DVB_DUMMY_FE) || (defined(CONFIG_DVB_DUMMY_FE_MODULE) && \
+defined(MODULE))
extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);
+#else
+static inline struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+static inline struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+static inline struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_DUMMY_FE */
#endif // DVB_DUMMY_FE_H
diff --git a/drivers/media/dvb/frontends/itd1000_priv.h b/drivers/media/dvb/frontends/itd1000_priv.h
index 8cdc54e57903..08ca851223c9 100644
--- a/drivers/media/dvb/frontends/itd1000_priv.h
+++ b/drivers/media/dvb/frontends/itd1000_priv.h
@@ -31,7 +31,7 @@ struct itd1000_state {
/* ugly workaround for flexcop's incapable i2c-controller
* FIXME, if possible
*/
- u8 shadow[255];
+ u8 shadow[256];
};
enum itd1000_register {
diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c
index 3bb0c4394f8a..eb72a9866c93 100644
--- a/drivers/media/dvb/frontends/lgdt3304.c
+++ b/drivers/media/dvb/frontends/lgdt3304.c
@@ -363,7 +363,6 @@ struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
struct lgdt3304_state *state;
state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL);
- memset(state, 0x0, sizeof(struct lgdt3304_state));
state->addr = config->i2c_address;
state->i2c = i2c;
diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c
new file mode 100644
index 000000000000..d92d0557a80b
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3305.c
@@ -0,0 +1,1087 @@
+/*
+ * Support for LGDT3305 - VSB/QAM
+ *
+ * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/dvb/frontend.h>
+#include "dvb_math.h"
+#include "lgdt3305.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
+
+#define DBG_INFO 1
+#define DBG_REG 2
+
+#define lg_printk(kern, fmt, arg...) \
+ printk(kern "%s: " fmt, __func__, ##arg)
+
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3305: " fmt, ##arg)
+#define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg)
+#define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg)
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
+
+#define lg_fail(ret) \
+({ \
+ int __ret; \
+ __ret = (ret < 0); \
+ if (__ret) \
+ lg_err("error %d on line %d\n", ret, __LINE__); \
+ __ret; \
+})
+
+struct lgdt3305_state {
+ struct i2c_adapter *i2c_adap;
+ const struct lgdt3305_config *cfg;
+
+ struct dvb_frontend frontend;
+
+ fe_modulation_t current_modulation;
+ u32 current_frequency;
+ u32 snr;
+};
+
+/* ------------------------------------------------------------------------ */
+
+#define LGDT3305_GEN_CTRL_1 0x0000
+#define LGDT3305_GEN_CTRL_2 0x0001
+#define LGDT3305_GEN_CTRL_3 0x0002
+#define LGDT3305_GEN_STATUS 0x0003
+#define LGDT3305_GEN_CONTROL 0x0007
+#define LGDT3305_GEN_CTRL_4 0x000a
+#define LGDT3305_DGTL_AGC_REF_1 0x0012
+#define LGDT3305_DGTL_AGC_REF_2 0x0013
+#define LGDT3305_CR_CTR_FREQ_1 0x0106
+#define LGDT3305_CR_CTR_FREQ_2 0x0107
+#define LGDT3305_CR_CTR_FREQ_3 0x0108
+#define LGDT3305_CR_CTR_FREQ_4 0x0109
+#define LGDT3305_CR_MSE_1 0x011b
+#define LGDT3305_CR_MSE_2 0x011c
+#define LGDT3305_CR_LOCK_STATUS 0x011d
+#define LGDT3305_CR_CTRL_7 0x0126
+#define LGDT3305_AGC_POWER_REF_1 0x0300
+#define LGDT3305_AGC_POWER_REF_2 0x0301
+#define LGDT3305_AGC_DELAY_PT_1 0x0302
+#define LGDT3305_AGC_DELAY_PT_2 0x0303
+#define LGDT3305_RFAGC_LOOP_FLTR_BW_1 0x0306
+#define LGDT3305_RFAGC_LOOP_FLTR_BW_2 0x0307
+#define LGDT3305_IFBW_1 0x0308
+#define LGDT3305_IFBW_2 0x0309
+#define LGDT3305_AGC_CTRL_1 0x030c
+#define LGDT3305_AGC_CTRL_4 0x0314
+#define LGDT3305_EQ_MSE_1 0x0413
+#define LGDT3305_EQ_MSE_2 0x0414
+#define LGDT3305_EQ_MSE_3 0x0415
+#define LGDT3305_PT_MSE_1 0x0417
+#define LGDT3305_PT_MSE_2 0x0418
+#define LGDT3305_PT_MSE_3 0x0419
+#define LGDT3305_FEC_BLOCK_CTRL 0x0504
+#define LGDT3305_FEC_LOCK_STATUS 0x050a
+#define LGDT3305_FEC_PKT_ERR_1 0x050c
+#define LGDT3305_FEC_PKT_ERR_2 0x050d
+#define LGDT3305_TP_CTRL_1 0x050e
+#define LGDT3305_BERT_PERIOD 0x0801
+#define LGDT3305_BERT_ERROR_COUNT_1 0x080a
+#define LGDT3305_BERT_ERROR_COUNT_2 0x080b
+#define LGDT3305_BERT_ERROR_COUNT_3 0x080c
+#define LGDT3305_BERT_ERROR_COUNT_4 0x080d
+
+static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val)
+{
+ int ret;
+ u8 buf[] = { reg >> 8, reg & 0xff, val };
+ struct i2c_msg msg = {
+ .addr = state->cfg->i2c_addr, .flags = 0,
+ .buf = buf, .len = 3,
+ };
+
+ lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
+
+ ret = i2c_transfer(state->i2c_adap, &msg, 1);
+
+ if (ret != 1) {
+ lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
+ msg.buf[0], msg.buf[1], msg.buf[2], ret);
+ if (ret < 0)
+ return ret;
+ else
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val)
+{
+ int ret;
+ u8 reg_buf[] = { reg >> 8, reg & 0xff };
+ struct i2c_msg msg[] = {
+ { .addr = state->cfg->i2c_addr,
+ .flags = 0, .buf = reg_buf, .len = 2 },
+ { .addr = state->cfg->i2c_addr,
+ .flags = I2C_M_RD, .buf = val, .len = 1 },
+ };
+
+ lg_reg("reg: 0x%04x\n", reg);
+
+ ret = i2c_transfer(state->i2c_adap, msg, 2);
+
+ if (ret != 2) {
+ lg_err("error (addr %02x reg %04x error (ret == %i)\n",
+ state->cfg->i2c_addr, reg, ret);
+ if (ret < 0)
+ return ret;
+ else
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+#define read_reg(state, reg) \
+({ \
+ u8 __val; \
+ int ret = lgdt3305_read_reg(state, reg, &__val); \
+ if (lg_fail(ret)) \
+ __val = 0; \
+ __val; \
+})
+
+static int lgdt3305_set_reg_bit(struct lgdt3305_state *state,
+ u16 reg, int bit, int onoff)
+{
+ u8 val;
+ int ret;
+
+ lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
+
+ ret = lgdt3305_read_reg(state, reg, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ val &= ~(1 << bit);
+ val |= (onoff & 1) << bit;
+
+ ret = lgdt3305_write_reg(state, reg, val);
+fail:
+ return ret;
+}
+
+struct lgdt3305_reg {
+ u16 reg;
+ u8 val;
+};
+
+static int lgdt3305_write_regs(struct lgdt3305_state *state,
+ struct lgdt3305_reg *regs, int len)
+{
+ int i, ret;
+
+ lg_reg("writing %d registers...\n", len);
+
+ for (i = 0; i < len - 1; i++) {
+ ret = lgdt3305_write_reg(state, regs[i].reg, regs[i].val);
+ if (lg_fail(ret))
+ return ret;
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_soft_reset(struct lgdt3305_state *state)
+{
+ int ret;
+
+ lg_dbg("\n");
+
+ ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 0);
+ if (lg_fail(ret))
+ goto fail;
+
+ msleep(20);
+ ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 1);
+fail:
+ return ret;
+}
+
+static inline int lgdt3305_mpeg_mode(struct lgdt3305_state *state,
+ enum lgdt3305_mpeg_mode mode)
+{
+ lg_dbg("(%d)\n", mode);
+ return lgdt3305_set_reg_bit(state, LGDT3305_TP_CTRL_1, 5, mode);
+}
+
+static int lgdt3305_mpeg_mode_polarity(struct lgdt3305_state *state,
+ enum lgdt3305_tp_clock_edge edge,
+ enum lgdt3305_tp_valid_polarity valid)
+{
+ u8 val;
+ int ret;
+
+ lg_dbg("edge = %d, valid = %d\n", edge, valid);
+
+ ret = lgdt3305_read_reg(state, LGDT3305_TP_CTRL_1, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ val &= ~0x09;
+
+ if (edge)
+ val |= 0x08;
+ if (valid)
+ val |= 0x01;
+
+ ret = lgdt3305_write_reg(state, LGDT3305_TP_CTRL_1, val);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_soft_reset(state);
+fail:
+ return ret;
+}
+
+static int lgdt3305_set_modulation(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u8 opermode;
+ int ret;
+
+ lg_dbg("\n");
+
+ ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_1, &opermode);
+ if (lg_fail(ret))
+ goto fail;
+
+ opermode &= ~0x03;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ opermode |= 0x03;
+ break;
+ case QAM_64:
+ opermode |= 0x00;
+ break;
+ case QAM_256:
+ opermode |= 0x01;
+ break;
+ default:
+ return -EINVAL;
+ }
+ ret = lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_1, opermode);
+fail:
+ return ret;
+}
+
+static int lgdt3305_set_filter_extension(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ int val;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ val = 0;
+ break;
+ case QAM_64:
+ case QAM_256:
+ val = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ lg_dbg("val = %d\n", val);
+
+ return lgdt3305_set_reg_bit(state, 0x043f, 2, val);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u16 agc_ref;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ agc_ref = 0x32c4;
+ break;
+ case QAM_64:
+ agc_ref = 0x2a00;
+ break;
+ case QAM_256:
+ agc_ref = 0x2a80;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ lg_dbg("agc ref: 0x%04x\n", agc_ref);
+
+ lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_1, agc_ref >> 8);
+ lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_2, agc_ref & 0xff);
+
+ return 0;
+}
+
+static int lgdt3305_rfagc_loop(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u16 ifbw, rfbw, agcdelay;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ agcdelay = 0x04c0;
+ rfbw = 0x8000;
+ ifbw = 0x8000;
+ break;
+ case QAM_64:
+ case QAM_256:
+ agcdelay = 0x046b;
+ rfbw = 0x8889;
+ ifbw = 0x8888;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (state->cfg->rf_agc_loop) {
+ lg_dbg("agcdelay: 0x%04x, rfbw: 0x%04x\n", agcdelay, rfbw);
+
+ /* rf agc loop filter bandwidth */
+ lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_1,
+ agcdelay >> 8);
+ lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_2,
+ agcdelay & 0xff);
+
+ lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_1,
+ rfbw >> 8);
+ lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_2,
+ rfbw & 0xff);
+ } else {
+ lg_dbg("ifbw: 0x%04x\n", ifbw);
+
+ /* if agc loop filter bandwidth */
+ lgdt3305_write_reg(state, LGDT3305_IFBW_1, ifbw >> 8);
+ lgdt3305_write_reg(state, LGDT3305_IFBW_2, ifbw & 0xff);
+ }
+
+ return 0;
+}
+
+static int lgdt3305_agc_setup(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ int lockdten, acqen;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ lockdten = 0;
+ acqen = 0;
+ break;
+ case QAM_64:
+ case QAM_256:
+ lockdten = 1;
+ acqen = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen);
+
+ /* control agc function */
+ lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
+ lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
+
+ return lgdt3305_rfagc_loop(state, param);
+}
+
+static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u16 usref = 0;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ if (state->cfg->usref_8vsb)
+ usref = state->cfg->usref_8vsb;
+ break;
+ case QAM_64:
+ if (state->cfg->usref_qam64)
+ usref = state->cfg->usref_qam64;
+ break;
+ case QAM_256:
+ if (state->cfg->usref_qam256)
+ usref = state->cfg->usref_qam256;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (usref) {
+ lg_dbg("set manual mode: 0x%04x\n", usref);
+
+ lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 3, 1);
+
+ lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_1,
+ 0xff & (usref >> 8));
+ lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_2,
+ 0xff & (usref >> 0));
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_spectral_inversion(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param,
+ int inversion)
+{
+ int ret;
+
+ lg_dbg("(%d)\n", inversion);
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7,
+ inversion ? 0xf9 : 0x79);
+ break;
+ case QAM_64:
+ case QAM_256:
+ ret = lgdt3305_write_reg(state, LGDT3305_FEC_BLOCK_CTRL,
+ inversion ? 0xfd : 0xff);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+static int lgdt3305_set_if(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u16 if_freq_khz;
+ u8 nco1, nco2, nco3, nco4;
+ u64 nco;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ if_freq_khz = state->cfg->vsb_if_khz;
+ break;
+ case QAM_64:
+ case QAM_256:
+ if_freq_khz = state->cfg->qam_if_khz;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ nco = if_freq_khz / 10;
+
+#define LGDT3305_64BIT_DIVISION_ENABLED 0
+ /* FIXME: 64bit division disabled to avoid linking error:
+ * WARNING: "__udivdi3" [lgdt3305.ko] undefined!
+ */
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+#if LGDT3305_64BIT_DIVISION_ENABLED
+ nco <<= 24;
+ nco /= 625;
+#else
+ nco *= ((1 << 24) / 625);
+#endif
+ break;
+ case QAM_64:
+ case QAM_256:
+#if LGDT3305_64BIT_DIVISION_ENABLED
+ nco <<= 28;
+ nco /= 625;
+#else
+ nco *= ((1 << 28) / 625);
+#endif
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ nco1 = (nco >> 24) & 0x3f;
+ nco1 |= 0x40;
+ nco2 = (nco >> 16) & 0xff;
+ nco3 = (nco >> 8) & 0xff;
+ nco4 = nco & 0xff;
+
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, nco1);
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, nco2);
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, nco3);
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, nco4);
+
+ lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n",
+ if_freq_khz, nco1, nco2, nco3, nco4);
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+
+ if (state->cfg->deny_i2c_rptr)
+ return 0;
+
+ lg_dbg("(%d)\n", enable);
+
+ return lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_2, 5,
+ enable ? 0 : 1);
+}
+
+static int lgdt3305_sleep(struct dvb_frontend *fe)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ u8 gen_ctrl_3, gen_ctrl_4;
+
+ lg_dbg("\n");
+
+ gen_ctrl_3 = read_reg(state, LGDT3305_GEN_CTRL_3);
+ gen_ctrl_4 = read_reg(state, LGDT3305_GEN_CTRL_4);
+
+ /* hold in software reset while sleeping */
+ gen_ctrl_3 &= ~0x01;
+ /* tristate the IF-AGC pin */
+ gen_ctrl_3 |= 0x02;
+ /* tristate the RF-AGC pin */
+ gen_ctrl_3 |= 0x04;
+
+ /* disable vsb/qam module */
+ gen_ctrl_4 &= ~0x01;
+ /* disable adc module */
+ gen_ctrl_4 &= ~0x02;
+
+ lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_3, gen_ctrl_3);
+ lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_4, gen_ctrl_4);
+
+ return 0;
+}
+
+static int lgdt3305_init(struct dvb_frontend *fe)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ int ret;
+
+ static struct lgdt3305_reg lgdt3305_init_data[] = {
+ { .reg = LGDT3305_GEN_CTRL_1,
+ .val = 0x03, },
+ { .reg = LGDT3305_GEN_CTRL_2,
+ .val = 0xb0, },
+ { .reg = LGDT3305_GEN_CTRL_3,
+ .val = 0x01, },
+ { .reg = LGDT3305_GEN_CONTROL,
+ .val = 0x6f, },
+ { .reg = LGDT3305_GEN_CTRL_4,
+ .val = 0x03, },
+ { .reg = LGDT3305_DGTL_AGC_REF_1,
+ .val = 0x32, },
+ { .reg = LGDT3305_DGTL_AGC_REF_2,
+ .val = 0xc4, },
+ { .reg = LGDT3305_CR_CTR_FREQ_1,
+ .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_2,
+ .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_3,
+ .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_4,
+ .val = 0x00, },
+ { .reg = LGDT3305_CR_CTRL_7,
+ .val = 0x79, },
+ { .reg = LGDT3305_AGC_POWER_REF_1,
+ .val = 0x32, },
+ { .reg = LGDT3305_AGC_POWER_REF_2,
+ .val = 0xc4, },
+ { .reg = LGDT3305_AGC_DELAY_PT_1,
+ .val = 0x0d, },
+ { .reg = LGDT3305_AGC_DELAY_PT_2,
+ .val = 0x30, },
+ { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1,
+ .val = 0x80, },
+ { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2,
+ .val = 0x00, },
+ { .reg = LGDT3305_IFBW_1,
+ .val = 0x80, },
+ { .reg = LGDT3305_IFBW_2,
+ .val = 0x00, },
+ { .reg = LGDT3305_AGC_CTRL_1,
+ .val = 0x30, },
+ { .reg = LGDT3305_AGC_CTRL_4,
+ .val = 0x61, },
+ { .reg = LGDT3305_FEC_BLOCK_CTRL,
+ .val = 0xff, },
+ { .reg = LGDT3305_TP_CTRL_1,
+ .val = 0x1b, },
+ };
+
+ lg_dbg("\n");
+
+ ret = lgdt3305_write_regs(state, lgdt3305_init_data,
+ ARRAY_SIZE(lgdt3305_init_data));
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_soft_reset(state);
+fail:
+ return ret;
+}
+
+static int lgdt3305_set_parameters(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *param)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ int ret;
+
+ lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation);
+
+ if (fe->ops.tuner_ops.set_params) {
+ ret = fe->ops.tuner_ops.set_params(fe, param);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ if (lg_fail(ret))
+ goto fail;
+ state->current_frequency = param->frequency;
+ }
+
+ ret = lgdt3305_set_modulation(state, param);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_passband_digital_agc(state, param);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_set_agc_power_ref(state, param);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_agc_setup(state, param);
+ if (lg_fail(ret))
+ goto fail;
+
+ /* low if */
+ ret = lgdt3305_write_reg(state, LGDT3305_GEN_CONTROL, 0x2f);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_set_reg_bit(state, LGDT3305_CR_CTR_FREQ_1, 6, 1);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_set_if(state, param);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_spectral_inversion(state, param,
+ state->cfg->spectral_inversion
+ ? 1 : 0);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_set_filter_extension(state, param);
+ if (lg_fail(ret))
+ goto fail;
+
+ state->current_modulation = param->u.vsb.modulation;
+
+ ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
+ if (lg_fail(ret))
+ goto fail;
+
+ /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
+ ret = lgdt3305_mpeg_mode_polarity(state,
+ state->cfg->tpclk_edge,
+ state->cfg->tpvalid_polarity);
+fail:
+ return ret;
+}
+
+static int lgdt3305_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *param)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+
+ lg_dbg("\n");
+
+ param->u.vsb.modulation = state->current_modulation;
+ param->frequency = state->current_frequency;
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_read_cr_lock_status(struct lgdt3305_state *state,
+ int *locked)
+{
+ u8 val;
+ int ret;
+ char *cr_lock_state = "";
+
+ *locked = 0;
+
+ ret = lgdt3305_read_reg(state, LGDT3305_CR_LOCK_STATUS, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ switch (state->current_modulation) {
+ case QAM_256:
+ case QAM_64:
+ if (val & (1 << 1))
+ *locked = 1;
+
+ switch (val & 0x07) {
+ case 0:
+ cr_lock_state = "QAM UNLOCK";
+ break;
+ case 4:
+ cr_lock_state = "QAM 1stLock";
+ break;
+ case 6:
+ cr_lock_state = "QAM 2ndLock";
+ break;
+ case 7:
+ cr_lock_state = "QAM FinalLock";
+ break;
+ default:
+ cr_lock_state = "CLOCKQAM-INVALID!";
+ break;
+ }
+ break;
+ case VSB_8:
+ if (val & (1 << 7)) {
+ *locked = 1;
+ cr_lock_state = "CLOCKVSB";
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ lg_dbg("(%d) %s\n", *locked, cr_lock_state);
+fail:
+ return ret;
+}
+
+static int lgdt3305_read_fec_lock_status(struct lgdt3305_state *state,
+ int *locked)
+{
+ u8 val;
+ int ret, mpeg_lock, fec_lock, viterbi_lock;
+
+ *locked = 0;
+
+ switch (state->current_modulation) {
+ case QAM_256:
+ case QAM_64:
+ ret = lgdt3305_read_reg(state,
+ LGDT3305_FEC_LOCK_STATUS, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ mpeg_lock = (val & (1 << 0)) ? 1 : 0;
+ fec_lock = (val & (1 << 2)) ? 1 : 0;
+ viterbi_lock = (val & (1 << 3)) ? 1 : 0;
+
+ *locked = mpeg_lock && fec_lock && viterbi_lock;
+
+ lg_dbg("(%d) %s%s%s\n", *locked,
+ mpeg_lock ? "mpeg lock " : "",
+ fec_lock ? "fec lock " : "",
+ viterbi_lock ? "viterbi lock" : "");
+ break;
+ case VSB_8:
+ default:
+ ret = -EINVAL;
+ }
+fail:
+ return ret;
+}
+
+static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ u8 val;
+ int ret, signal, inlock, nofecerr, snrgood,
+ cr_lock, fec_lock, sync_lock;
+
+ *status = 0;
+
+ ret = lgdt3305_read_reg(state, LGDT3305_GEN_STATUS, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ signal = (val & (1 << 4)) ? 1 : 0;
+ inlock = (val & (1 << 3)) ? 0 : 1;
+ sync_lock = (val & (1 << 2)) ? 1 : 0;
+ nofecerr = (val & (1 << 1)) ? 1 : 0;
+ snrgood = (val & (1 << 0)) ? 1 : 0;
+
+ lg_dbg("%s%s%s%s%s\n",
+ signal ? "SIGNALEXIST " : "",
+ inlock ? "INLOCK " : "",
+ sync_lock ? "SYNCLOCK " : "",
+ nofecerr ? "NOFECERR " : "",
+ snrgood ? "SNRGOOD " : "");
+
+ ret = lgdt3305_read_cr_lock_status(state, &cr_lock);
+ if (lg_fail(ret))
+ goto fail;
+
+ if (signal)
+ *status |= FE_HAS_SIGNAL;
+ if (cr_lock)
+ *status |= FE_HAS_CARRIER;
+ if (nofecerr)
+ *status |= FE_HAS_VITERBI;
+ if (sync_lock)
+ *status |= FE_HAS_SYNC;
+
+ switch (state->current_modulation) {
+ case QAM_256:
+ case QAM_64:
+ ret = lgdt3305_read_fec_lock_status(state, &fec_lock);
+ if (lg_fail(ret))
+ goto fail;
+
+ if (fec_lock)
+ *status |= FE_HAS_LOCK;
+ break;
+ case VSB_8:
+ if (inlock)
+ *status |= FE_HAS_LOCK;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+fail:
+ return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* borrowed from lgdt330x.c */
+static u32 calculate_snr(u32 mse, u32 c)
+{
+ if (mse == 0) /* no signal */
+ return 0;
+
+ mse = intlog10(mse);
+ if (mse > c) {
+ /* Negative SNR, which is possible, but realisticly the
+ demod will lose lock before the signal gets this bad. The
+ API only allows for unsigned values, so just return 0 */
+ return 0;
+ }
+ return 10*(c - mse);
+}
+
+static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ u32 noise; /* noise value */
+ u32 c; /* per-modulation SNR calculation constant */
+
+ switch (state->current_modulation) {
+ case VSB_8:
+#ifdef USE_PTMSE
+ /* Use Phase Tracker Mean-Square Error Register */
+ /* SNR for ranges from -13.11 to +44.08 */
+ noise = ((read_reg(state, LGDT3305_PT_MSE_1) & 0x07) << 16) |
+ (read_reg(state, LGDT3305_PT_MSE_2) << 8) |
+ (read_reg(state, LGDT3305_PT_MSE_3) & 0xff);
+ c = 73957994; /* log10(25*32^2)*2^24 */
+#else
+ /* Use Equalizer Mean-Square Error Register */
+ /* SNR for ranges from -16.12 to +44.08 */
+ noise = ((read_reg(state, LGDT3305_EQ_MSE_1) & 0x0f) << 16) |
+ (read_reg(state, LGDT3305_EQ_MSE_2) << 8) |
+ (read_reg(state, LGDT3305_EQ_MSE_3) & 0xff);
+ c = 73957994; /* log10(25*32^2)*2^24 */
+#endif
+ break;
+ case QAM_64:
+ case QAM_256:
+ noise = (read_reg(state, LGDT3305_CR_MSE_1) << 8) |
+ (read_reg(state, LGDT3305_CR_MSE_2) & 0xff);
+
+ c = (state->current_modulation == QAM_64) ?
+ 97939837 : 98026066;
+ /* log10(688128)*2^24 and log10(696320)*2^24 */
+ break;
+ default:
+ return -EINVAL;
+ }
+ state->snr = calculate_snr(noise, c);
+ /* report SNR in dB * 10 */
+ *snr = (state->snr / ((1 << 24) / 10));
+ lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise,
+ state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
+
+ return 0;
+}
+
+static int lgdt3305_read_signal_strength(struct dvb_frontend *fe,
+ u16 *strength)
+{
+ /* borrowed from lgdt330x.c
+ *
+ * Calculate strength from SNR up to 35dB
+ * Even though the SNR can go higher than 35dB,
+ * there is some comfort factor in having a range of
+ * strong signals that can show at 100%
+ */
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ u16 snr;
+ int ret;
+
+ *strength = 0;
+
+ ret = fe->ops.read_snr(fe, &snr);
+ if (lg_fail(ret))
+ goto fail;
+ /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
+ /* scale the range 0 - 35*2^24 into 0 - 65535 */
+ if (state->snr >= 8960 * 0x10000)
+ *strength = 0xffff;
+ else
+ *strength = state->snr / 8960;
+fail:
+ return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ *ber = 0;
+ return 0;
+}
+
+static int lgdt3305_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+
+ *ucblocks =
+ (read_reg(state, LGDT3305_FEC_PKT_ERR_1) << 8) |
+ (read_reg(state, LGDT3305_FEC_PKT_ERR_2) & 0xff);
+
+ return 0;
+}
+
+static int lgdt3305_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings
+ *fe_tune_settings)
+{
+ fe_tune_settings->min_delay_ms = 500;
+ lg_dbg("\n");
+ return 0;
+}
+
+static void lgdt3305_release(struct dvb_frontend *fe)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ lg_dbg("\n");
+ kfree(state);
+}
+
+static struct dvb_frontend_ops lgdt3305_ops;
+
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+ struct i2c_adapter *i2c_adap)
+{
+ struct lgdt3305_state *state = NULL;
+ int ret;
+ u8 val;
+
+ lg_dbg("(%d-%04x)\n",
+ i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
+ config ? config->i2c_addr : 0);
+
+ state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL);
+ if (state == NULL)
+ goto fail;
+
+ state->cfg = config;
+ state->i2c_adap = i2c_adap;
+
+ memcpy(&state->frontend.ops, &lgdt3305_ops,
+ sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+
+ /* verify that we're talking to a lg dt3305 */
+ ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val);
+ if ((lg_fail(ret)) | (val == 0))
+ goto fail;
+ ret = lgdt3305_write_reg(state, 0x0808, 0x80);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_read_reg(state, 0x0808, &val);
+ if ((lg_fail(ret)) | (val != 0x80))
+ goto fail;
+ ret = lgdt3305_write_reg(state, 0x0808, 0x00);
+ if (lg_fail(ret))
+ goto fail;
+
+ state->current_frequency = -1;
+ state->current_modulation = -1;
+
+ return &state->frontend;
+fail:
+ lg_warn("unable to detect LGDT3305 hardware\n");
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(lgdt3305_attach);
+
+static struct dvb_frontend_ops lgdt3305_ops = {
+ .info = {
+ .name = "LG Electronics LGDT3305 VSB/QAM Frontend",
+ .type = FE_ATSC,
+ .frequency_min = 54000000,
+ .frequency_max = 858000000,
+ .frequency_stepsize = 62500,
+ .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+ },
+ .i2c_gate_ctrl = lgdt3305_i2c_gate_ctrl,
+ .init = lgdt3305_init,
+ .sleep = lgdt3305_sleep,
+ .set_frontend = lgdt3305_set_parameters,
+ .get_frontend = lgdt3305_get_frontend,
+ .get_tune_settings = lgdt3305_get_tune_settings,
+ .read_status = lgdt3305_read_status,
+ .read_ber = lgdt3305_read_ber,
+ .read_signal_strength = lgdt3305_read_signal_strength,
+ .read_snr = lgdt3305_read_snr,
+ .read_ucblocks = lgdt3305_read_ucblocks,
+ .release = lgdt3305_release,
+};
+
+MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/frontends/lgdt3305.h b/drivers/media/dvb/frontends/lgdt3305.h
new file mode 100644
index 000000000000..4fa6e52d1fe8
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3305.h
@@ -0,0 +1,85 @@
+/*
+ * Support for LGDT3305 - VSB/QAM
+ *
+ * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _LGDT3305_H_
+#define _LGDT3305_H_
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+
+enum lgdt3305_mpeg_mode {
+ LGDT3305_MPEG_PARALLEL = 0,
+ LGDT3305_MPEG_SERIAL = 1,
+};
+
+enum lgdt3305_tp_clock_edge {
+ LGDT3305_TPCLK_RISING_EDGE = 0,
+ LGDT3305_TPCLK_FALLING_EDGE = 1,
+};
+
+enum lgdt3305_tp_valid_polarity {
+ LGDT3305_TP_VALID_LOW = 0,
+ LGDT3305_TP_VALID_HIGH = 1,
+};
+
+struct lgdt3305_config {
+ u8 i2c_addr;
+
+ /* user defined IF frequency in KHz */
+ u16 qam_if_khz;
+ u16 vsb_if_khz;
+
+ /* AGC Power reference - defaults are used if left unset */
+ u16 usref_8vsb; /* default: 0x32c4 */
+ u16 usref_qam64; /* default: 0x5400 */
+ u16 usref_qam256; /* default: 0x2a80 */
+
+ /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
+ int deny_i2c_rptr:1;
+
+ /* spectral inversion - 0:disabled 1:enabled */
+ int spectral_inversion:1;
+
+ /* use RF AGC loop - 0:disabled 1:enabled */
+ int rf_agc_loop:1;
+
+ enum lgdt3305_mpeg_mode mpeg_mode;
+ enum lgdt3305_tp_clock_edge tpclk_edge;
+ enum lgdt3305_tp_valid_polarity tpvalid_polarity;
+};
+
+#if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \
+ defined(MODULE))
+extern
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+ struct i2c_adapter *i2c_adap);
+#else
+static inline
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+ struct i2c_adapter *i2c_adap)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_LGDT3305 */
+
+#endif /* _LGDT3305_H_ */
diff --git a/drivers/media/dvb/frontends/lnbh24.h b/drivers/media/dvb/frontends/lnbh24.h
new file mode 100644
index 000000000000..c059b165318f
--- /dev/null
+++ b/drivers/media/dvb/frontends/lnbh24.h
@@ -0,0 +1,55 @@
+/*
+ * lnbh24.h - driver for lnb supply and control ic lnbh24
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LNBH24_H
+#define _LNBH24_H
+
+/* system register bits */
+#define LNBH24_OLF 0x01
+#define LNBH24_OTF 0x02
+#define LNBH24_EN 0x04
+#define LNBH24_VSEL 0x08
+#define LNBH24_LLC 0x10
+#define LNBH24_TEN 0x20
+#define LNBH24_TTX 0x40
+#define LNBH24_PCL 0x80
+
+#include <linux/dvb/frontend.h>
+
+#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
+ && defined(MODULE))
+/* override_set and override_clear control which
+ system register bits (above) to always set & clear */
+extern struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear, u8 i2c_addr);
+#else
+static inline struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear, u8 i2c_addr)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c
index 76f935d9755a..1dcc56f32bff 100644
--- a/drivers/media/dvb/frontends/lnbp21.c
+++ b/drivers/media/dvb/frontends/lnbp21.c
@@ -1,7 +1,8 @@
/*
- * lnbp21.h - driver for lnb supply and control ic lnbp21
+ * lnbp21.c - driver for lnb supply and control ic lnbp21
*
* Copyright (C) 2006 Oliver Endriss
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -33,18 +34,21 @@
#include "dvb_frontend.h"
#include "lnbp21.h"
+#include "lnbh24.h"
struct lnbp21 {
u8 config;
u8 override_or;
u8 override_and;
struct i2c_adapter *i2c;
+ u8 i2c_addr;
};
-static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+static int lnbp21_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
{
struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
- struct i2c_msg msg = { .addr = 0x08, .flags = 0,
+ struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
.buf = &lnbp21->config,
.len = sizeof(lnbp21->config) };
@@ -72,7 +76,7 @@ static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
{
struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
- struct i2c_msg msg = { .addr = 0x08, .flags = 0,
+ struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
.buf = &lnbp21->config,
.len = sizeof(lnbp21->config) };
@@ -97,15 +101,18 @@ static void lnbp21_release(struct dvb_frontend *fe)
fe->sec_priv = NULL;
}
-struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
+static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear, u8 i2c_addr, u8 config)
{
struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
if (!lnbp21)
return NULL;
/* default configuration */
- lnbp21->config = LNBP21_ISEL;
+ lnbp21->config = config;
lnbp21->i2c = i2c;
+ lnbp21->i2c_addr = i2c_addr;
fe->sec_priv = lnbp21;
/* bits which should be forced to '1' */
@@ -126,11 +133,29 @@ struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *
/* override frontend ops */
fe->ops.set_voltage = lnbp21_set_voltage;
fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
+ printk(KERN_INFO "LNBx2x attached on addr=%x", lnbp21->i2c_addr);
return fe;
}
+
+struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear, u8 i2c_addr)
+{
+ return lnbx2x_attach(fe, i2c, override_set, override_clear,
+ i2c_addr, LNBH24_TTX);
+}
+EXPORT_SYMBOL(lnbh24_attach);
+
+struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear)
+{
+ return lnbx2x_attach(fe, i2c, override_set, override_clear,
+ 0x08, LNBP21_ISEL);
+}
EXPORT_SYMBOL(lnbp21_attach);
-MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21");
-MODULE_AUTHOR("Oliver Endriss");
+MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24");
+MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
index 8fe094bd9689..fcdf1c650dde 100644
--- a/drivers/media/dvb/frontends/lnbp21.h
+++ b/drivers/media/dvb/frontends/lnbp21.h
@@ -28,26 +28,48 @@
#define _LNBP21_H
/* system register bits */
+/* [RO] 0=OK; 1=over current limit flag */
#define LNBP21_OLF 0x01
+/* [RO] 0=OK; 1=over temperature flag (150 C) */
#define LNBP21_OTF 0x02
+/* [RW] 0=disable LNB power, enable loopthrough
+ 1=enable LNB power, disable loopthrough */
#define LNBP21_EN 0x04
+/* [RW] 0=low voltage (13/14V, vert pol)
+ 1=high voltage (18/19V,horiz pol) */
#define LNBP21_VSEL 0x08
+/* [RW] increase LNB voltage by 1V:
+ 0=13/18V; 1=14/19V */
#define LNBP21_LLC 0x10
+/* [RW] 0=tone controlled by DSQIN pin
+ 1=tone enable, disable DSQIN */
#define LNBP21_TEN 0x20
+/* [RW] current limit select:
+ 0:Iout=500-650mA Isc=300mA
+ 1:Iout=400-550mA Isc=200mA */
#define LNBP21_ISEL 0x40
+/* [RW] short-circuit protect:
+ 0=pulsed (dynamic) curr limiting
+ 1=static curr limiting */
#define LNBP21_PCL 0x80
#include <linux/dvb/frontend.h>
-#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) && defined(MODULE))
-/* override_set and override_clear control which system register bits (above) to always set & clear */
-extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear);
+#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
+ && defined(MODULE))
+/* override_set and override_clear control which
+ system register bits (above) to always set & clear */
+extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear);
#else
-static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
+static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-#endif // CONFIG_DVB_LNBP21
+#endif
-#endif // _LNBP21_H
+#endif
diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c
index 892af8c9ed57..3f5a0e1dfdf5 100644
--- a/drivers/media/dvb/frontends/s921_module.c
+++ b/drivers/media/dvb/frontends/s921_module.c
@@ -169,7 +169,6 @@ struct dvb_frontend* s921_attach(const struct s921_config *config,
struct s921_state *state;
state = kzalloc(sizeof(struct s921_state), GFP_KERNEL);
- memset(state, 0x0, sizeof(struct s921_state));
state->addr = config->i2c_address;
state->i2c = i2c;
diff --git a/drivers/media/dvb/frontends/stb6100_cfg.h b/drivers/media/dvb/frontends/stb6100_cfg.h
index d3133405dc03..6314d18c797a 100644
--- a/drivers/media/dvb/frontends/stb6100_cfg.h
+++ b/drivers/media/dvb/frontends/stb6100_cfg.h
@@ -36,7 +36,6 @@ static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
return err;
}
*frequency = t_state.frequency;
- printk("%s: Frequency=%d\n", __func__, t_state.frequency);
}
return 0;
}
@@ -59,7 +58,6 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
return err;
}
}
- printk("%s: Frequency=%d\n", __func__, t_state.frequency);
return 0;
}
@@ -81,7 +79,6 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
}
*bandwidth = t_state.bandwidth;
}
- printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
return 0;
}
@@ -103,6 +100,5 @@ static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
return err;
}
}
- printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
return 0;
}
diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h
new file mode 100644
index 000000000000..8a1332c2031d
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900.h
@@ -0,0 +1,62 @@
+/*
+ * stv0900.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0900_H
+#define STV0900_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+struct stv0900_config {
+ u8 demod_address;
+ u32 xtal;
+ u8 clkmode;/* 0 for CLKI, 2 for XTALI */
+
+ u8 diseqc_mode;
+
+ u8 path1_mode;
+ u8 path2_mode;
+
+ u8 tun1_maddress;/* 0, 1, 2, 3 for 0xc0, 0xc2, 0xc4, 0xc6 */
+ u8 tun2_maddress;
+ u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
+ u8 tun2_adc;
+};
+
+#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \
+ && defined(MODULE))
+extern struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+ struct i2c_adapter *i2c, int demod);
+#else
+static inline struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+ struct i2c_adapter *i2c, int demod)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif
+
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
new file mode 100644
index 000000000000..8499bcf7f251
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -0,0 +1,1949 @@
+/*
+ * stv0900_core.c
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+
+#include "stv0900.h"
+#include "stv0900_reg.h"
+#include "stv0900_priv.h"
+#include "stv0900_init.h"
+
+static int stvdebug = 1;
+module_param_named(debug, stvdebug, int, 0644);
+
+/* internal params node */
+struct stv0900_inode {
+ /* pointer for internal params, one for each pair of demods */
+ struct stv0900_internal *internal;
+ struct stv0900_inode *next_inode;
+};
+
+/* first internal params */
+static struct stv0900_inode *stv0900_first_inode;
+
+/* find chip by i2c adapter and i2c address */
+static struct stv0900_inode *find_inode(struct i2c_adapter *i2c_adap,
+ u8 i2c_addr)
+{
+ struct stv0900_inode *temp_chip = stv0900_first_inode;
+
+ if (temp_chip != NULL) {
+ /*
+ Search of the last stv0900 chip or
+ find it by i2c adapter and i2c address */
+ while ((temp_chip != NULL) &&
+ ((temp_chip->internal->i2c_adap != i2c_adap) ||
+ (temp_chip->internal->i2c_addr != i2c_addr)))
+
+ temp_chip = temp_chip->next_inode;
+
+ }
+
+ return temp_chip;
+}
+
+/* deallocating chip */
+static void remove_inode(struct stv0900_internal *internal)
+{
+ struct stv0900_inode *prev_node = stv0900_first_inode;
+ struct stv0900_inode *del_node = find_inode(internal->i2c_adap,
+ internal->i2c_addr);
+
+ if (del_node != NULL) {
+ if (del_node == stv0900_first_inode) {
+ stv0900_first_inode = del_node->next_inode;
+ } else {
+ while (prev_node->next_inode != del_node)
+ prev_node = prev_node->next_inode;
+
+ if (del_node->next_inode == NULL)
+ prev_node->next_inode = NULL;
+ else
+ prev_node->next_inode =
+ prev_node->next_inode->next_inode;
+ }
+
+ kfree(del_node);
+ }
+}
+
+/* allocating new chip */
+static struct stv0900_inode *append_internal(struct stv0900_internal *internal)
+{
+ struct stv0900_inode *new_node = stv0900_first_inode;
+
+ if (new_node == NULL) {
+ new_node = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL);
+ stv0900_first_inode = new_node;
+ } else {
+ while (new_node->next_inode != NULL)
+ new_node = new_node->next_inode;
+
+ new_node->next_inode = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL);
+ if (new_node->next_inode != NULL)
+ new_node = new_node->next_inode;
+ else
+ new_node = NULL;
+ }
+
+ if (new_node != NULL) {
+ new_node->internal = internal;
+ new_node->next_inode = NULL;
+ }
+
+ return new_node;
+}
+
+s32 ge2comp(s32 a, s32 width)
+{
+ if (width == 32)
+ return a;
+ else
+ return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a;
+}
+
+void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr,
+ u8 reg_data)
+{
+ u8 data[3];
+ int ret;
+ struct i2c_msg i2cmsg = {
+ .addr = i_params->i2c_addr,
+ .flags = 0,
+ .len = 3,
+ .buf = data,
+ };
+
+ data[0] = MSB(reg_addr);
+ data[1] = LSB(reg_addr);
+ data[2] = reg_data;
+
+ ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+ if (ret != 1)
+ dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+}
+
+u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg_addr)
+{
+ u8 data[2];
+ int ret;
+ struct i2c_msg i2cmsg = {
+ .addr = i_params->i2c_addr,
+ .flags = 0,
+ .len = 2,
+ .buf = data,
+ };
+
+ data[0] = MSB(reg_addr);
+ data[1] = LSB(reg_addr);
+
+ ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+ if (ret != 1)
+ dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+
+ i2cmsg.flags = I2C_M_RD;
+ i2cmsg.len = 1;
+ ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+ if (ret != 1)
+ dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+
+ return data[0];
+}
+
+void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
+{
+ u8 position = 0, i = 0;
+
+ (*mask) = label & 0xff;
+
+ while ((position == 0) && (i < 8)) {
+ position = ((*mask) >> i) & 0x01;
+ i++;
+ }
+
+ (*pos) = (i - 1);
+}
+
+void stv0900_write_bits(struct stv0900_internal *i_params, u32 label, u8 val)
+{
+ u8 reg, mask, pos;
+
+ reg = stv0900_read_reg(i_params, (label >> 16) & 0xffff);
+ extract_mask_pos(label, &mask, &pos);
+
+ val = mask & (val << pos);
+
+ reg = (reg & (~mask)) | val;
+ stv0900_write_reg(i_params, (label >> 16) & 0xffff, reg);
+
+}
+
+u8 stv0900_get_bits(struct stv0900_internal *i_params, u32 label)
+{
+ u8 val = 0xff;
+ u8 mask, pos;
+
+ extract_mask_pos(label, &mask, &pos);
+
+ val = stv0900_read_reg(i_params, label >> 16);
+ val = (val & mask) >> pos;
+
+ return val;
+}
+
+enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params)
+{
+ s32 i;
+ enum fe_stv0900_error error;
+
+ if (i_params != NULL) {
+ i_params->chip_id = stv0900_read_reg(i_params, R0900_MID);
+ if (i_params->errs == STV0900_NO_ERROR) {
+ /*Startup sequence*/
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5c);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5c);
+ stv0900_write_reg(i_params, R0900_P1_TNRCFG, 0x6c);
+ stv0900_write_reg(i_params, R0900_P2_TNRCFG, 0x6f);
+ stv0900_write_reg(i_params, R0900_P1_I2CRPT, 0x24);
+ stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x24);
+ stv0900_write_reg(i_params, R0900_NCOARSE, 0x13);
+ msleep(3);
+ stv0900_write_reg(i_params, R0900_I2CCFG, 0x08);
+
+ switch (i_params->clkmode) {
+ case 0:
+ case 2:
+ stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20
+ | i_params->clkmode);
+ break;
+ default:
+ /* preserve SELOSCI bit */
+ i = 0x02 & stv0900_read_reg(i_params, R0900_SYNTCTRL);
+ stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20 | i);
+ break;
+ }
+
+ msleep(3);
+ for (i = 0; i < 182; i++)
+ stv0900_write_reg(i_params, STV0900_InitVal[i][0], STV0900_InitVal[i][1]);
+
+ if (stv0900_read_reg(i_params, R0900_MID) >= 0x20) {
+ stv0900_write_reg(i_params, R0900_TSGENERAL, 0x0c);
+ for (i = 0; i < 32; i++)
+ stv0900_write_reg(i_params, STV0900_Cut20_AddOnVal[i][0], STV0900_Cut20_AddOnVal[i][1]);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_FSPYCFG, 0x6c);
+ stv0900_write_reg(i_params, R0900_P2_FSPYCFG, 0x6c);
+ stv0900_write_reg(i_params, R0900_TSTRES0, 0x80);
+ stv0900_write_reg(i_params, R0900_TSTRES0, 0x00);
+ }
+ error = i_params->errs;
+ } else
+ error = STV0900_INVALID_HANDLE;
+
+ return error;
+
+}
+
+u32 stv0900_get_mclk_freq(struct stv0900_internal *i_params, u32 ext_clk)
+{
+ u32 mclk = 90000000, div = 0, ad_div = 0;
+
+ div = stv0900_get_bits(i_params, F0900_M_DIV);
+ ad_div = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6);
+
+ mclk = (div + 1) * ext_clk / ad_div;
+
+ dprintk(KERN_INFO "%s: Calculated Mclk = %d\n", __func__, mclk);
+
+ return mclk;
+}
+
+enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *i_params, u32 mclk)
+{
+ enum fe_stv0900_error error = STV0900_NO_ERROR;
+ u32 m_div, clk_sel;
+
+ dprintk(KERN_INFO "%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
+ i_params->quartz);
+
+ if (i_params == NULL)
+ error = STV0900_INVALID_HANDLE;
+ else {
+ if (i_params->errs)
+ error = STV0900_I2C_ERROR;
+ else {
+ clk_sel = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6);
+ m_div = ((clk_sel * mclk) / i_params->quartz) - 1;
+ stv0900_write_bits(i_params, F0900_M_DIV, m_div);
+ i_params->mclk = stv0900_get_mclk_freq(i_params,
+ i_params->quartz);
+
+ /*Set the DiseqC frequency to 22KHz */
+ /*
+ Formula:
+ DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg)
+ DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg)
+ */
+ m_div = i_params->mclk / 704000;
+ stv0900_write_reg(i_params, R0900_P1_F22TX, m_div);
+ stv0900_write_reg(i_params, R0900_P1_F22RX, m_div);
+
+ stv0900_write_reg(i_params, R0900_P2_F22TX, m_div);
+ stv0900_write_reg(i_params, R0900_P2_F22RX, m_div);
+
+ if ((i_params->errs))
+ error = STV0900_I2C_ERROR;
+ }
+ }
+
+ return error;
+}
+
+u32 stv0900_get_err_count(struct stv0900_internal *i_params, int cntr,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 lsb, msb, hsb, err_val;
+ s32 err1field_hsb, err1field_msb, err1field_lsb;
+ s32 err2field_hsb, err2field_msb, err2field_lsb;
+
+ dmd_reg(err1field_hsb, F0900_P1_ERR_CNT12, F0900_P2_ERR_CNT12);
+ dmd_reg(err1field_msb, F0900_P1_ERR_CNT11, F0900_P2_ERR_CNT11);
+ dmd_reg(err1field_lsb, F0900_P1_ERR_CNT10, F0900_P2_ERR_CNT10);
+
+ dmd_reg(err2field_hsb, F0900_P1_ERR_CNT22, F0900_P2_ERR_CNT22);
+ dmd_reg(err2field_msb, F0900_P1_ERR_CNT21, F0900_P2_ERR_CNT21);
+ dmd_reg(err2field_lsb, F0900_P1_ERR_CNT20, F0900_P2_ERR_CNT20);
+
+ switch (cntr) {
+ case 0:
+ default:
+ hsb = stv0900_get_bits(i_params, err1field_hsb);
+ msb = stv0900_get_bits(i_params, err1field_msb);
+ lsb = stv0900_get_bits(i_params, err1field_lsb);
+ break;
+ case 1:
+ hsb = stv0900_get_bits(i_params, err2field_hsb);
+ msb = stv0900_get_bits(i_params, err2field_msb);
+ lsb = stv0900_get_bits(i_params, err2field_lsb);
+ break;
+ }
+
+ err_val = (hsb << 16) + (msb << 8) + (lsb);
+
+ return err_val;
+}
+
+static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ u32 fi2c;
+
+ dmd_reg(fi2c, F0900_P1_I2CT_ON, F0900_P2_I2CT_ON);
+ if (enable)
+ stv0900_write_bits(i_params, fi2c, 1);
+
+ return 0;
+}
+
+static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params,
+ enum fe_stv0900_clock_type path1_ts,
+ enum fe_stv0900_clock_type path2_ts)
+{
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (i_params->chip_id >= 0x20) {
+ switch (path1_ts) {
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ switch (path2_ts) {
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ stv0900_write_reg(i_params, R0900_TSGENERAL,
+ 0x00);
+ break;
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_reg(i_params, R0900_TSGENERAL,
+ 0x06);
+ stv0900_write_bits(i_params,
+ F0900_P1_TSFIFO_MANSPEED, 3);
+ stv0900_write_bits(i_params,
+ F0900_P2_TSFIFO_MANSPEED, 0);
+ stv0900_write_reg(i_params,
+ R0900_P1_TSSPEED, 0x14);
+ stv0900_write_reg(i_params,
+ R0900_P2_TSSPEED, 0x28);
+ break;
+ }
+ break;
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ switch (path2_ts) {
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ stv0900_write_reg(i_params,
+ R0900_TSGENERAL, 0x0C);
+ break;
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_reg(i_params,
+ R0900_TSGENERAL, 0x0A);
+ dprintk(KERN_INFO "%s: 0x0a\n", __func__);
+ break;
+ }
+ break;
+ }
+ } else {
+ switch (path1_ts) {
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ switch (path2_ts) {
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+ 0x10);
+ break;
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+ 0x16);
+ stv0900_write_bits(i_params,
+ F0900_P1_TSFIFO_MANSPEED, 3);
+ stv0900_write_bits(i_params,
+ F0900_P2_TSFIFO_MANSPEED, 0);
+ stv0900_write_reg(i_params, R0900_P1_TSSPEED,
+ 0x14);
+ stv0900_write_reg(i_params, R0900_P2_TSSPEED,
+ 0x28);
+ break;
+ }
+
+ break;
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ switch (path2_ts) {
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+ 0x14);
+ break;
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+ 0x12);
+ dprintk(KERN_INFO "%s: 0x12\n", __func__);
+ break;
+ }
+
+ break;
+ }
+ }
+
+ switch (path1_ts) {
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00);
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00);
+ break;
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00);
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01);
+ break;
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01);
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00);
+ break;
+ case STV0900_SERIAL_CONT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01);
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01);
+ break;
+ default:
+ break;
+ }
+
+ switch (path2_ts) {
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00);
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00);
+ break;
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00);
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01);
+ break;
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01);
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00);
+ break;
+ case STV0900_SERIAL_CONT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01);
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01);
+ break;
+ default:
+ break;
+ }
+
+ stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1);
+ stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 0);
+ stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1);
+ stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 0);
+}
+
+void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
+ u32 bandwidth)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+
+ if (tuner_ops->set_frequency) {
+ if ((tuner_ops->set_frequency(fe, frequency)) < 0)
+ dprintk("%s: Invalid parameter\n", __func__);
+ else
+ dprintk("%s: Frequency=%d\n", __func__, frequency);
+
+ }
+
+ if (tuner_ops->set_bandwidth) {
+ if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
+ dprintk("%s: Invalid parameter\n", __func__);
+ else
+ dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
+
+ }
+}
+
+void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+
+ if (tuner_ops->set_bandwidth) {
+ if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
+ dprintk("%s: Invalid parameter\n", __func__);
+ else
+ dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
+
+ }
+}
+
+static s32 stv0900_get_rf_level(struct stv0900_internal *i_params,
+ const struct stv0900_table *lookup,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 agc_gain = 0,
+ imin,
+ imax,
+ i,
+ rf_lvl = 0;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if ((lookup != NULL) && lookup->size) {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE1),
+ stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE0));
+ break;
+ case STV0900_DEMOD_2:
+ agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE1),
+ stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE0));
+ break;
+ }
+
+ imin = 0;
+ imax = lookup->size - 1;
+ if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[imax].regval)) {
+ while ((imax - imin) > 1) {
+ i = (imax + imin) >> 1;
+
+ if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[i].regval))
+ imax = i;
+ else
+ imin = i;
+ }
+
+ rf_lvl = (((s32)agc_gain - lookup->table[imin].regval)
+ * (lookup->table[imax].realval - lookup->table[imin].realval)
+ / (lookup->table[imax].regval - lookup->table[imin].regval))
+ + lookup->table[imin].realval;
+ } else if (agc_gain > lookup->table[0].regval)
+ rf_lvl = 5;
+ else if (agc_gain < lookup->table[lookup->size-1].regval)
+ rf_lvl = -100;
+
+ }
+
+ dprintk(KERN_INFO "%s: RFLevel = %d\n", __func__, rf_lvl);
+
+ return rf_lvl;
+}
+
+static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *internal = state->internal;
+ s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf,
+ state->demod);
+
+ *strength = (rflevel + 100) * (16383 / 105);
+
+ return 0;
+}
+
+
+static s32 stv0900_carr_get_quality(struct dvb_frontend *fe,
+ const struct stv0900_table *lookup)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ s32 c_n = -100,
+ regval, imin, imax,
+ i,
+ lock_flag_field,
+ noise_field1,
+ noise_field0;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF,
+ F0900_P2_LOCK_DEFINITIF);
+ if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) {
+ dmd_reg(noise_field1, F0900_P1_NOSPLHT_NORMED1,
+ F0900_P2_NOSPLHT_NORMED1);
+ dmd_reg(noise_field0, F0900_P1_NOSPLHT_NORMED0,
+ F0900_P2_NOSPLHT_NORMED0);
+ } else {
+ dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1,
+ F0900_P2_NOSDATAT_NORMED1);
+ dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0,
+ F0900_P2_NOSDATAT_NORMED0);
+ }
+
+ if (stv0900_get_bits(i_params, lock_flag_field)) {
+ if ((lookup != NULL) && lookup->size) {
+ regval = 0;
+ msleep(5);
+ for (i = 0; i < 16; i++) {
+ regval += MAKEWORD(stv0900_get_bits(i_params,
+ noise_field1),
+ stv0900_get_bits(i_params,
+ noise_field0));
+ msleep(1);
+ }
+
+ regval /= 16;
+ imin = 0;
+ imax = lookup->size - 1;
+ if (INRANGE(lookup->table[imin].regval,
+ regval,
+ lookup->table[imax].regval)) {
+ while ((imax - imin) > 1) {
+ i = (imax + imin) >> 1;
+ if (INRANGE(lookup->table[imin].regval,
+ regval,
+ lookup->table[i].regval))
+ imax = i;
+ else
+ imin = i;
+ }
+
+ c_n = ((regval - lookup->table[imin].regval)
+ * (lookup->table[imax].realval
+ - lookup->table[imin].realval)
+ / (lookup->table[imax].regval
+ - lookup->table[imin].regval))
+ + lookup->table[imin].realval;
+ } else if (regval < lookup->table[imin].regval)
+ c_n = 1000;
+ }
+ }
+
+ return c_n;
+}
+
+static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ *snr = stv0900_carr_get_quality(fe,
+ (const struct stv0900_table *)&stv0900_s2_cn);
+ *snr += 30;
+ *snr *= (16383 / 1030);
+
+ return 0;
+}
+
+static u32 stv0900_get_ber(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 ber = 10000000, i;
+ s32 dmd_state_reg;
+ s32 demod_state;
+ s32 vstatus_reg;
+ s32 prvit_field;
+ s32 pdel_status_reg;
+ s32 pdel_lock_field;
+
+ dmd_reg(dmd_state_reg, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(vstatus_reg, R0900_P1_VSTATUSVIT, R0900_P2_VSTATUSVIT);
+ dmd_reg(prvit_field, F0900_P1_PRFVIT, F0900_P2_PRFVIT);
+ dmd_reg(pdel_status_reg, R0900_P1_PDELSTATUS1, R0900_P2_PDELSTATUS1);
+ dmd_reg(pdel_lock_field, F0900_P1_PKTDELIN_LOCK,
+ F0900_P2_PKTDELIN_LOCK);
+
+ demod_state = stv0900_get_bits(i_params, dmd_state_reg);
+
+ switch (demod_state) {
+ case STV0900_SEARCH:
+ case STV0900_PLH_DETECTED:
+ default:
+ ber = 10000000;
+ break;
+ case STV0900_DVBS_FOUND:
+ ber = 0;
+ for (i = 0; i < 5; i++) {
+ msleep(5);
+ ber += stv0900_get_err_count(i_params, 0, demod);
+ }
+
+ ber /= 5;
+ if (stv0900_get_bits(i_params, prvit_field)) {
+ ber *= 9766;
+ ber = ber >> 13;
+ }
+
+ break;
+ case STV0900_DVBS2_FOUND:
+ ber = 0;
+ for (i = 0; i < 5; i++) {
+ msleep(5);
+ ber += stv0900_get_err_count(i_params, 0, demod);
+ }
+
+ ber /= 5;
+ if (stv0900_get_bits(i_params, pdel_lock_field)) {
+ ber *= 9766;
+ ber = ber >> 13;
+ }
+
+ break;
+ }
+
+ return ber;
+}
+
+static int stv0900_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *internal = state->internal;
+
+ *ber = stv0900_get_ber(internal, state->demod);
+
+ return 0;
+}
+
+int stv0900_get_demod_lock(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod, s32 time_out)
+{
+ s32 timer = 0,
+ lock = 0,
+ header_field,
+ lock_field;
+
+ enum fe_stv0900_search_state dmd_state;
+
+ dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF);
+ while ((timer < time_out) && (lock == 0)) {
+ dmd_state = stv0900_get_bits(i_params, header_field);
+ dprintk("Demod State = %d\n", dmd_state);
+ switch (dmd_state) {
+ case STV0900_SEARCH:
+ case STV0900_PLH_DETECTED:
+ default:
+ lock = 0;
+ break;
+ case STV0900_DVBS2_FOUND:
+ case STV0900_DVBS_FOUND:
+ lock = stv0900_get_bits(i_params, lock_field);
+ break;
+ }
+
+ if (lock == 0)
+ msleep(10);
+
+ timer += 10;
+ }
+
+ if (lock)
+ dprintk("DEMOD LOCK OK\n");
+ else
+ dprintk("DEMOD LOCK FAIL\n");
+
+ return lock;
+}
+
+void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 regflist,
+ i;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(regflist, R0900_P1_MODCODLST0, R0900_P2_MODCODLST0);
+
+ for (i = 0; i < 16; i++)
+ stv0900_write_reg(i_params, regflist + i, 0xff);
+}
+
+void stv0900_activate_s2_modcode(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 matype,
+ mod_code,
+ fmod,
+ reg_index,
+ field_index;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (i_params->chip_id <= 0x11) {
+ msleep(5);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ mod_code = stv0900_read_reg(i_params,
+ R0900_P1_PLHMODCOD);
+ matype = mod_code & 0x3;
+ mod_code = (mod_code & 0x7f) >> 2;
+
+ reg_index = R0900_P1_MODCODLSTF - mod_code / 2;
+ field_index = mod_code % 2;
+ break;
+ case STV0900_DEMOD_2:
+ mod_code = stv0900_read_reg(i_params,
+ R0900_P2_PLHMODCOD);
+ matype = mod_code & 0x3;
+ mod_code = (mod_code & 0x7f) >> 2;
+
+ reg_index = R0900_P2_MODCODLSTF - mod_code / 2;
+ field_index = mod_code % 2;
+ break;
+ }
+
+
+ switch (matype) {
+ case 0:
+ default:
+ fmod = 14;
+ break;
+ case 1:
+ fmod = 13;
+ break;
+ case 2:
+ fmod = 11;
+ break;
+ case 3:
+ fmod = 7;
+ break;
+ }
+
+ if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910))
+ && (matype <= 1)) {
+ if (field_index == 0)
+ stv0900_write_reg(i_params, reg_index,
+ 0xf0 | fmod);
+ else
+ stv0900_write_reg(i_params, reg_index,
+ (fmod << 4) | 0xf);
+ }
+ } else if (i_params->chip_id >= 0x12) {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ for (reg_index = 0; reg_index < 7; reg_index++)
+ stv0900_write_reg(i_params, R0900_P1_MODCODLST0 + reg_index, 0xff);
+
+ stv0900_write_reg(i_params, R0900_P1_MODCODLSTE, 0xff);
+ stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0xcf);
+ for (reg_index = 0; reg_index < 8; reg_index++)
+ stv0900_write_reg(i_params, R0900_P1_MODCODLST7 + reg_index, 0xcc);
+
+ break;
+ case STV0900_DEMOD_2:
+ for (reg_index = 0; reg_index < 7; reg_index++)
+ stv0900_write_reg(i_params, R0900_P2_MODCODLST0 + reg_index, 0xff);
+
+ stv0900_write_reg(i_params, R0900_P2_MODCODLSTE, 0xff);
+ stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0xcf);
+ for (reg_index = 0; reg_index < 8; reg_index++)
+ stv0900_write_reg(i_params, R0900_P2_MODCODLST7 + reg_index, 0xcc);
+
+ break;
+ }
+
+ }
+}
+
+void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 reg_index;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_reg(i_params, R0900_P1_MODCODLST0, 0xff);
+ stv0900_write_reg(i_params, R0900_P1_MODCODLST1, 0xf0);
+ stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0x0f);
+ for (reg_index = 0; reg_index < 13; reg_index++)
+ stv0900_write_reg(i_params,
+ R0900_P1_MODCODLST2 + reg_index, 0);
+
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_reg(i_params, R0900_P2_MODCODLST0, 0xff);
+ stv0900_write_reg(i_params, R0900_P2_MODCODLST1, 0xf0);
+ stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0x0f);
+ for (reg_index = 0; reg_index < 13; reg_index++)
+ stv0900_write_reg(i_params,
+ R0900_P2_MODCODLST2 + reg_index, 0);
+
+ break;
+ }
+}
+
+static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe)
+{
+ return DVBFE_ALGO_CUSTOM;
+}
+
+static int stb0900_set_property(struct dvb_frontend *fe,
+ struct dtv_property *tvp)
+{
+ dprintk(KERN_INFO "%s(..)\n", __func__);
+
+ return 0;
+}
+
+static int stb0900_get_property(struct dvb_frontend *fe,
+ struct dtv_property *tvp)
+{
+ dprintk(KERN_INFO "%s(..)\n", __func__);
+
+ return 0;
+}
+
+void stv0900_start_search(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1f);
+
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xaa);
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55);
+
+ if (i_params->dmd1_symbol_rate <= 5000000) {
+ stv0900_write_reg(i_params, R0900_P1_CARCFG, 0x44);
+ stv0900_write_reg(i_params, R0900_P1_CFRUP1, 0x0f);
+ stv0900_write_reg(i_params, R0900_P1_CFRUP0, 0xff);
+ stv0900_write_reg(i_params, R0900_P1_CFRLOW1, 0xf0);
+ stv0900_write_reg(i_params, R0900_P1_CFRLOW0, 0x00);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xc4);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41);
+
+ if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) {
+ stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82);
+ stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0);
+ }
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xe0);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xc0);
+ stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+ stv0900_write_bits(i_params, F0900_P1_S1S2_SEQUENTIAL, 0);
+ stv0900_write_reg(i_params, R0900_P1_RTC, 0x88);
+ if (i_params->chip_id >= 0x20) {
+ if (i_params->dmd1_symbol_rate < 2000000) {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x39);
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x40);
+ }
+
+ if (i_params->dmd1_symbol_rate < 10000000) {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4c);
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4b);
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20);
+ }
+
+ } else {
+ if (i_params->dmd1_symbol_rate < 10000000)
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xef);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
+ }
+
+ switch (i_params->dmd1_srch_algo) {
+ case STV0900_WARM_START:
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ break;
+ case STV0900_COLD_START:
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
+ break;
+ default:
+ break;
+ }
+
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1f);
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xaa);
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55);
+
+ if (i_params->dmd2_symbol_rate <= 5000000) {
+ stv0900_write_reg(i_params, R0900_P2_CARCFG, 0x44);
+ stv0900_write_reg(i_params, R0900_P2_CFRUP1, 0x0f);
+ stv0900_write_reg(i_params, R0900_P2_CFRUP0, 0xff);
+ stv0900_write_reg(i_params, R0900_P2_CFRLOW1, 0xf0);
+ stv0900_write_reg(i_params, R0900_P2_CFRLOW0, 0x00);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xc4);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44);
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41);
+ if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) {
+ stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82);
+ stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0);
+ }
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xe0);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xc0);
+ stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+ stv0900_write_bits(i_params, F0900_P2_S1S2_SEQUENTIAL, 0);
+ stv0900_write_reg(i_params, R0900_P2_RTC, 0x88);
+ if (i_params->chip_id >= 0x20) {
+ if (i_params->dmd2_symbol_rate < 2000000) {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x39);
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x40);
+ }
+
+ if (i_params->dmd2_symbol_rate < 10000000) {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4c);
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4b);
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20);
+ }
+
+ } else {
+ if (i_params->dmd2_symbol_rate < 10000000)
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xef);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
+ }
+
+ switch (i_params->dmd2_srch_algo) {
+ case STV0900_WARM_START:
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ break;
+ case STV0900_COLD_START:
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
+ break;
+ default:
+ break;
+ }
+
+ break;
+ }
+}
+
+u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode,
+ s32 pilot, u8 chip_id)
+{
+ u8 aclc_value = 0x29;
+ s32 i;
+ const struct stv0900_car_loop_optim *car_loop_s2;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (chip_id <= 0x12)
+ car_loop_s2 = FE_STV0900_S2CarLoop;
+ else if (chip_id == 0x20)
+ car_loop_s2 = FE_STV0900_S2CarLoopCut20;
+ else
+ car_loop_s2 = FE_STV0900_S2CarLoop;
+
+ if (modcode < STV0900_QPSK_12) {
+ i = 0;
+ while ((i < 3) && (modcode != FE_STV0900_S2LowQPCarLoopCut20[i].modcode))
+ i++;
+
+ if (i >= 3)
+ i = 2;
+ } else {
+ i = 0;
+ while ((i < 14) && (modcode != car_loop_s2[i].modcode))
+ i++;
+
+ if (i >= 14) {
+ i = 0;
+ while ((i < 11) && (modcode != FE_STV0900_S2APSKCarLoopCut20[i].modcode))
+ i++;
+
+ if (i >= 11)
+ i = 10;
+ }
+ }
+
+ if (modcode <= STV0900_QPSK_25) {
+ if (pilot) {
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_20;
+ else
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_30;
+ } else {
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_20;
+ else
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_30;
+ }
+
+ } else if (modcode <= STV0900_8PSK_910) {
+ if (pilot) {
+ if (srate <= 3000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_2;
+ else if (srate <= 7000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_5;
+ else if (srate <= 15000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_10;
+ else if (srate <= 25000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_20;
+ else
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_30;
+ } else {
+ if (srate <= 3000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_2;
+ else if (srate <= 7000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_5;
+ else if (srate <= 15000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_10;
+ else if (srate <= 25000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_20;
+ else
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_30;
+ }
+
+ } else {
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_20;
+ else
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_30;
+ }
+
+ return aclc_value;
+}
+
+u8 stv0900_get_optim_short_carr_loop(s32 srate, enum fe_stv0900_modulation modulation, u8 chip_id)
+{
+ s32 mod_index = 0;
+
+ u8 aclc_value = 0x0b;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (modulation) {
+ case STV0900_QPSK:
+ default:
+ mod_index = 0;
+ break;
+ case STV0900_8PSK:
+ mod_index = 1;
+ break;
+ case STV0900_16APSK:
+ mod_index = 2;
+ break;
+ case STV0900_32APSK:
+ mod_index = 3;
+ break;
+ }
+
+ switch (chip_id) {
+ case 0x20:
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_20;
+ else
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_30;
+
+ break;
+ case 0x12:
+ default:
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_20;
+ else
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_30;
+
+ break;
+ }
+
+ return aclc_value;
+}
+
+static enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_mode LDPC_Mode,
+ enum fe_stv0900_demod_num demod)
+{
+ enum fe_stv0900_error error = STV0900_NO_ERROR;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (LDPC_Mode) {
+ case STV0900_DUAL:
+ default:
+ if ((i_params->demod_mode != STV0900_DUAL)
+ || (stv0900_get_bits(i_params, F0900_DDEMOD) != 1)) {
+ stv0900_write_reg(i_params, R0900_GENCFG, 0x1d);
+
+ i_params->demod_mode = STV0900_DUAL;
+
+ stv0900_write_bits(i_params, F0900_FRESFEC, 1);
+ stv0900_write_bits(i_params, F0900_FRESFEC, 0);
+ }
+
+ break;
+ case STV0900_SINGLE:
+ if (demod == STV0900_DEMOD_2)
+ stv0900_write_reg(i_params, R0900_GENCFG, 0x06);
+ else
+ stv0900_write_reg(i_params, R0900_GENCFG, 0x04);
+
+ i_params->demod_mode = STV0900_SINGLE;
+
+ stv0900_write_bits(i_params, F0900_FRESFEC, 1);
+ stv0900_write_bits(i_params, F0900_FRESFEC, 0);
+ stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1);
+ stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0);
+ stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1);
+ stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0);
+ break;
+ }
+
+ return error;
+}
+
+static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
+ struct stv0900_init_params *p_init)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ enum fe_stv0900_error error = STV0900_NO_ERROR;
+ enum fe_stv0900_error demodError = STV0900_NO_ERROR;
+ int selosci;
+
+ struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
+ state->config->demod_address);
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (temp_int != NULL) {
+ state->internal = temp_int->internal;
+ (state->internal->dmds_used)++;
+ dprintk(KERN_INFO "%s: Find Internal Structure!\n", __func__);
+ return STV0900_NO_ERROR;
+ } else {
+ state->internal = kmalloc(sizeof(struct stv0900_internal), GFP_KERNEL);
+ temp_int = append_internal(state->internal);
+ state->internal->dmds_used = 1;
+ state->internal->i2c_adap = state->i2c_adap;
+ state->internal->i2c_addr = state->config->demod_address;
+ state->internal->clkmode = state->config->clkmode;
+ state->internal->errs = STV0900_NO_ERROR;
+ dprintk(KERN_INFO "%s: Create New Internal Structure!\n", __func__);
+ }
+
+ if (state->internal != NULL) {
+ demodError = stv0900_initialize(state->internal);
+ if (demodError == STV0900_NO_ERROR) {
+ error = STV0900_NO_ERROR;
+ } else {
+ if (demodError == STV0900_INVALID_HANDLE)
+ error = STV0900_INVALID_HANDLE;
+ else
+ error = STV0900_I2C_ERROR;
+ }
+
+ if (state->internal != NULL) {
+ if (error == STV0900_NO_ERROR) {
+ state->internal->demod_mode = p_init->demod_mode;
+
+ stv0900_st_dvbs2_single(state->internal, state->internal->demod_mode, STV0900_DEMOD_1);
+
+ state->internal->chip_id = stv0900_read_reg(state->internal, R0900_MID);
+ state->internal->rolloff = p_init->rolloff;
+ state->internal->quartz = p_init->dmd_ref_clk;
+
+ stv0900_write_bits(state->internal, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
+ stv0900_write_bits(state->internal, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
+
+ stv0900_set_ts_parallel_serial(state->internal, p_init->path1_ts_clock, p_init->path2_ts_clock);
+ stv0900_write_bits(state->internal, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
+ switch (p_init->tuner1_adc) {
+ case 1:
+ stv0900_write_reg(state->internal, R0900_TSTTNR1, 0x26);
+ break;
+ default:
+ break;
+ }
+
+ stv0900_write_bits(state->internal, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress);
+ switch (p_init->tuner2_adc) {
+ case 1:
+ stv0900_write_reg(state->internal, R0900_TSTTNR3, 0x26);
+ break;
+ default:
+ break;
+ }
+
+ stv0900_write_bits(state->internal, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inversion);
+ stv0900_write_bits(state->internal, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inversion);
+ stv0900_set_mclk(state->internal, 135000000);
+ msleep(3);
+
+ switch (state->internal->clkmode) {
+ case 0:
+ case 2:
+ stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | state->internal->clkmode);
+ break;
+ default:
+ selosci = 0x02 & stv0900_read_reg(state->internal, R0900_SYNTCTRL);
+ stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | selosci);
+ break;
+ }
+ msleep(3);
+
+ state->internal->mclk = stv0900_get_mclk_freq(state->internal, state->internal->quartz);
+ if (state->internal->errs)
+ error = STV0900_I2C_ERROR;
+ }
+ } else {
+ error = STV0900_INVALID_HANDLE;
+ }
+ }
+
+ return error;
+}
+
+static int stv0900_status(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ enum fe_stv0900_search_state demod_state;
+ s32 mode_field, delin_field, lock_field, fifo_field, lockedvit_field;
+ int locked = FALSE;
+
+ dmd_reg(mode_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF);
+ dmd_reg(delin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK);
+ dmd_reg(fifo_field, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK);
+ dmd_reg(lockedvit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT);
+
+ demod_state = stv0900_get_bits(i_params, mode_field);
+ switch (demod_state) {
+ case STV0900_SEARCH:
+ case STV0900_PLH_DETECTED:
+ default:
+ locked = FALSE;
+ break;
+ case STV0900_DVBS2_FOUND:
+ locked = stv0900_get_bits(i_params, lock_field) &&
+ stv0900_get_bits(i_params, delin_field) &&
+ stv0900_get_bits(i_params, fifo_field);
+ break;
+ case STV0900_DVBS_FOUND:
+ locked = stv0900_get_bits(i_params, lock_field) &&
+ stv0900_get_bits(i_params, lockedvit_field) &&
+ stv0900_get_bits(i_params, fifo_field);
+ break;
+ }
+
+ return locked;
+}
+
+static enum dvbfe_search stv0900_search(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ struct stv0900_search_params p_search;
+ struct stv0900_signal_info p_result;
+
+ enum fe_stv0900_error error = STV0900_NO_ERROR;
+
+ dprintk(KERN_INFO "%s: ", __func__);
+
+ p_result.locked = FALSE;
+ p_search.path = state->demod;
+ p_search.frequency = c->frequency;
+ p_search.symbol_rate = c->symbol_rate;
+ p_search.search_range = 10000000;
+ p_search.fec = STV0900_FEC_UNKNOWN;
+ p_search.standard = STV0900_AUTO_SEARCH;
+ p_search.iq_inversion = STV0900_IQ_AUTO;
+ p_search.search_algo = STV0900_BLIND_SEARCH;
+
+ if ((INRANGE(100000, p_search.symbol_rate, 70000000)) &&
+ (INRANGE(100000, p_search.search_range, 50000000))) {
+ switch (p_search.path) {
+ case STV0900_DEMOD_1:
+ default:
+ i_params->dmd1_srch_standard = p_search.standard;
+ i_params->dmd1_symbol_rate = p_search.symbol_rate;
+ i_params->dmd1_srch_range = p_search.search_range;
+ i_params->tuner1_freq = p_search.frequency;
+ i_params->dmd1_srch_algo = p_search.search_algo;
+ i_params->dmd1_srch_iq_inv = p_search.iq_inversion;
+ i_params->dmd1_fec = p_search.fec;
+ break;
+
+ case STV0900_DEMOD_2:
+ i_params->dmd2_srch_stndrd = p_search.standard;
+ i_params->dmd2_symbol_rate = p_search.symbol_rate;
+ i_params->dmd2_srch_range = p_search.search_range;
+ i_params->tuner2_freq = p_search.frequency;
+ i_params->dmd2_srch_algo = p_search.search_algo;
+ i_params->dmd2_srch_iq_inv = p_search.iq_inversion;
+ i_params->dmd2_fec = p_search.fec;
+ break;
+ }
+
+ if ((stv0900_algo(fe) == STV0900_RANGEOK) &&
+ (i_params->errs == STV0900_NO_ERROR)) {
+ switch (p_search.path) {
+ case STV0900_DEMOD_1:
+ default:
+ p_result.locked = i_params->dmd1_rslts.locked;
+ p_result.standard = i_params->dmd1_rslts.standard;
+ p_result.frequency = i_params->dmd1_rslts.frequency;
+ p_result.symbol_rate = i_params->dmd1_rslts.symbol_rate;
+ p_result.fec = i_params->dmd1_rslts.fec;
+ p_result.modcode = i_params->dmd1_rslts.modcode;
+ p_result.pilot = i_params->dmd1_rslts.pilot;
+ p_result.frame_length = i_params->dmd1_rslts.frame_length;
+ p_result.spectrum = i_params->dmd1_rslts.spectrum;
+ p_result.rolloff = i_params->dmd1_rslts.rolloff;
+ p_result.modulation = i_params->dmd1_rslts.modulation;
+ break;
+ case STV0900_DEMOD_2:
+ p_result.locked = i_params->dmd2_rslts.locked;
+ p_result.standard = i_params->dmd2_rslts.standard;
+ p_result.frequency = i_params->dmd2_rslts.frequency;
+ p_result.symbol_rate = i_params->dmd2_rslts.symbol_rate;
+ p_result.fec = i_params->dmd2_rslts.fec;
+ p_result.modcode = i_params->dmd2_rslts.modcode;
+ p_result.pilot = i_params->dmd2_rslts.pilot;
+ p_result.frame_length = i_params->dmd2_rslts.frame_length;
+ p_result.spectrum = i_params->dmd2_rslts.spectrum;
+ p_result.rolloff = i_params->dmd2_rslts.rolloff;
+ p_result.modulation = i_params->dmd2_rslts.modulation;
+ break;
+ }
+
+ } else {
+ p_result.locked = FALSE;
+ switch (p_search.path) {
+ case STV0900_DEMOD_1:
+ switch (i_params->dmd1_err) {
+ case STV0900_I2C_ERROR:
+ error = STV0900_I2C_ERROR;
+ break;
+ case STV0900_NO_ERROR:
+ default:
+ error = STV0900_SEARCH_FAILED;
+ break;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ switch (i_params->dmd2_err) {
+ case STV0900_I2C_ERROR:
+ error = STV0900_I2C_ERROR;
+ break;
+ case STV0900_NO_ERROR:
+ default:
+ error = STV0900_SEARCH_FAILED;
+ break;
+ }
+ break;
+ }
+ }
+
+ } else
+ error = STV0900_BAD_PARAMETER;
+
+ if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) {
+ dprintk(KERN_INFO "Search Success\n");
+ return DVBFE_ALGO_SEARCH_SUCCESS;
+ } else {
+ dprintk(KERN_INFO "Search Fail\n");
+ return DVBFE_ALGO_SEARCH_FAILED;
+ }
+
+ return DVBFE_ALGO_SEARCH_ERROR;
+}
+
+static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+
+ dprintk("%s: ", __func__);
+
+ if ((stv0900_status(state->internal, state->demod)) == TRUE) {
+ dprintk("DEMOD LOCK OK\n");
+ *status = FE_HAS_CARRIER
+ | FE_HAS_VITERBI
+ | FE_HAS_SYNC
+ | FE_HAS_LOCK;
+ } else
+ dprintk("DEMOD LOCK FAIL\n");
+
+ return 0;
+}
+
+static int stv0900_track(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ return 0;
+}
+
+static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts)
+{
+
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ s32 rst_field;
+
+ dmd_reg(rst_field, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE);
+
+ if (stop_ts == TRUE)
+ stv0900_write_bits(i_params, rst_field, 1);
+ else
+ stv0900_write_bits(i_params, rst_field, 0);
+
+ return 0;
+}
+
+static int stv0900_diseqc_init(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ s32 mode_field, reset_field;
+
+ dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
+ dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET);
+
+ stv0900_write_bits(i_params, mode_field, state->config->diseqc_mode);
+ stv0900_write_bits(i_params, reset_field, 1);
+ stv0900_write_bits(i_params, reset_field, 0);
+
+ return 0;
+}
+
+static int stv0900_init(struct dvb_frontend *fe)
+{
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ stv0900_stop_ts(fe, 1);
+ stv0900_diseqc_init(fe);
+
+ return 0;
+}
+
+static int stv0900_diseqc_send(struct stv0900_internal *i_params , u8 *Data,
+ u32 NbData, enum fe_stv0900_demod_num demod)
+{
+ s32 i = 0;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 1);
+ while (i < NbData) {
+ while (stv0900_get_bits(i_params, F0900_P1_FIFO_FULL))
+ ;/* checkpatch complains */
+ stv0900_write_reg(i_params, R0900_P1_DISTXDATA, Data[i]);
+ i++;
+ }
+
+ stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 0);
+ i = 0;
+ while ((stv0900_get_bits(i_params, F0900_P1_TX_IDLE) != 1) && (i < 10)) {
+ msleep(10);
+ i++;
+ }
+
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 1);
+
+ while (i < NbData) {
+ while (stv0900_get_bits(i_params, F0900_P2_FIFO_FULL))
+ ;/* checkpatch complains */
+ stv0900_write_reg(i_params, R0900_P2_DISTXDATA, Data[i]);
+ i++;
+ }
+
+ stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 0);
+ i = 0;
+ while ((stv0900_get_bits(i_params, F0900_P2_TX_IDLE) != 1) && (i < 10)) {
+ msleep(10);
+ i++;
+ }
+
+ break;
+ }
+
+ return 0;
+}
+
+static int stv0900_send_master_cmd(struct dvb_frontend *fe,
+ struct dvb_diseqc_master_cmd *cmd)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+
+ return stv0900_diseqc_send(state->internal,
+ cmd->msg,
+ cmd->msg_len,
+ state->demod);
+}
+
+static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ s32 mode_field;
+ u32 diseqc_fifo;
+
+ dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
+ dmd_reg(diseqc_fifo, R0900_P1_DISTXDATA, R0900_P2_DISTXDATA);
+
+ switch (burst) {
+ case SEC_MINI_A:
+ stv0900_write_bits(i_params, mode_field, 3);/* Unmodulated */
+ stv0900_write_reg(i_params, diseqc_fifo, 0x00);
+ break;
+ case SEC_MINI_B:
+ stv0900_write_bits(i_params, mode_field, 2);/* Modulated */
+ stv0900_write_reg(i_params, diseqc_fifo, 0xff);
+ break;
+ }
+
+ return 0;
+}
+
+static int stv0900_recv_slave_reply(struct dvb_frontend *fe,
+ struct dvb_diseqc_slave_reply *reply)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ s32 i = 0;
+
+ switch (state->demod) {
+ case STV0900_DEMOD_1:
+ default:
+ reply->msg_len = 0;
+
+ while ((stv0900_get_bits(i_params, F0900_P1_RX_END) != 1) && (i < 10)) {
+ msleep(10);
+ i++;
+ }
+
+ if (stv0900_get_bits(i_params, F0900_P1_RX_END)) {
+ reply->msg_len = stv0900_get_bits(i_params, F0900_P1_FIFO_BYTENBR);
+
+ for (i = 0; i < reply->msg_len; i++)
+ reply->msg[i] = stv0900_read_reg(i_params, R0900_P1_DISRXDATA);
+ }
+ break;
+ case STV0900_DEMOD_2:
+ reply->msg_len = 0;
+
+ while ((stv0900_get_bits(i_params, F0900_P2_RX_END) != 1) && (i < 10)) {
+ msleep(10);
+ i++;
+ }
+
+ if (stv0900_get_bits(i_params, F0900_P2_RX_END)) {
+ reply->msg_len = stv0900_get_bits(i_params, F0900_P2_FIFO_BYTENBR);
+
+ for (i = 0; i < reply->msg_len; i++)
+ reply->msg[i] = stv0900_read_reg(i_params, R0900_P2_DISRXDATA);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ s32 mode_field, reset_field;
+
+ dprintk(KERN_INFO "%s: %s\n", __func__, ((tone == 0) ? "Off" : "On"));
+
+ dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
+ dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET);
+
+ if (tone) {
+ /*Set the DiseqC mode to 22Khz continues tone*/
+ stv0900_write_bits(i_params, mode_field, 0);
+ stv0900_write_bits(i_params, reset_field, 1);
+ /*release DiseqC reset to enable the 22KHz tone*/
+ stv0900_write_bits(i_params, reset_field, 0);
+ } else {
+ stv0900_write_bits(i_params, mode_field, 0);
+ /*maintain the DiseqC reset to disable the 22KHz tone*/
+ stv0900_write_bits(i_params, reset_field, 1);
+ }
+
+ return 0;
+}
+
+static void stv0900_release(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if ((--(state->internal->dmds_used)) <= 0) {
+
+ dprintk(KERN_INFO "%s: Actually removing\n", __func__);
+
+ remove_inode(state->internal);
+ kfree(state->internal);
+ }
+
+ kfree(state);
+}
+
+static struct dvb_frontend_ops stv0900_ops = {
+
+ .info = {
+ .name = "STV0900 frontend",
+ .type = FE_QPSK,
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_stepsize = 125,
+ .frequency_tolerance = 0,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 45000000,
+ .symbol_rate_tolerance = 500,
+ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+ FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
+ FE_CAN_FEC_7_8 | FE_CAN_QPSK |
+ FE_CAN_2G_MODULATION |
+ FE_CAN_FEC_AUTO
+ },
+ .release = stv0900_release,
+ .init = stv0900_init,
+ .get_frontend_algo = stv0900_frontend_algo,
+ .i2c_gate_ctrl = stv0900_i2c_gate_ctrl,
+ .diseqc_send_master_cmd = stv0900_send_master_cmd,
+ .diseqc_send_burst = stv0900_send_burst,
+ .diseqc_recv_slave_reply = stv0900_recv_slave_reply,
+ .set_tone = stv0900_set_tone,
+ .set_property = stb0900_set_property,
+ .get_property = stb0900_get_property,
+ .search = stv0900_search,
+ .track = stv0900_track,
+ .read_status = stv0900_read_status,
+ .read_ber = stv0900_read_ber,
+ .read_signal_strength = stv0900_read_signal_strength,
+ .read_snr = stv0900_read_snr,
+};
+
+struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+ struct i2c_adapter *i2c,
+ int demod)
+{
+ struct stv0900_state *state = NULL;
+ struct stv0900_init_params init_params;
+ enum fe_stv0900_error err_stv0900;
+
+ state = kzalloc(sizeof(struct stv0900_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+
+ state->demod = demod;
+ state->config = config;
+ state->i2c_adap = i2c;
+
+ memcpy(&state->frontend.ops, &stv0900_ops,
+ sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+
+ switch (demod) {
+ case 0:
+ case 1:
+ init_params.dmd_ref_clk = config->xtal;
+ init_params.demod_mode = STV0900_DUAL;
+ init_params.rolloff = STV0900_35;
+ init_params.path1_ts_clock = config->path1_mode;
+ init_params.tun1_maddress = config->tun1_maddress;
+ init_params.tun1_iq_inversion = STV0900_IQ_NORMAL;
+ init_params.tuner1_adc = config->tun1_adc;
+ init_params.path2_ts_clock = config->path2_mode;
+ init_params.tun2_maddress = config->tun2_maddress;
+ init_params.tuner2_adc = config->tun2_adc;
+ init_params.tun2_iq_inversion = STV0900_IQ_SWAPPED;
+
+ err_stv0900 = stv0900_init_internal(&state->frontend,
+ &init_params);
+
+ if (err_stv0900)
+ goto error;
+
+ break;
+ default:
+ goto error;
+ break;
+ }
+
+ dprintk("%s: Attaching STV0900 demodulator(%d) \n", __func__, demod);
+ return &state->frontend;
+
+error:
+ dprintk("%s: Failed to attach STV0900 demodulator(%d) \n",
+ __func__, demod);
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(stv0900_attach);
+
+MODULE_PARM_DESC(debug, "Set debug");
+
+MODULE_AUTHOR("Igor M. Liplianin");
+MODULE_DESCRIPTION("ST STV0900 frontend");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv0900_init.h b/drivers/media/dvb/frontends/stv0900_init.h
new file mode 100644
index 000000000000..ff388b47a4e3
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_init.h
@@ -0,0 +1,441 @@
+/*
+ * stv0900_init.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0900_INIT_H
+#define STV0900_INIT_H
+
+#include "stv0900_priv.h"
+
+/* DVBS2 C/N Look-Up table */
+static const struct stv0900_table stv0900_s2_cn = {
+ 55,
+ {
+ { -30, 13348 }, /*C/N=-3dB*/
+ { -20, 12640 }, /*C/N=-2dB*/
+ { -10, 11883 }, /*C/N=-1dB*/
+ { 0, 11101 }, /*C/N=-0dB*/
+ { 5, 10718 }, /*C/N=0.5dB*/
+ { 10, 10339 }, /*C/N=1.0dB*/
+ { 15, 9947 }, /*C/N=1.5dB*/
+ { 20, 9552 }, /*C/N=2.0dB*/
+ { 25, 9183 }, /*C/N=2.5dB*/
+ { 30, 8799 }, /*C/N=3.0dB*/
+ { 35, 8422 }, /*C/N=3.5dB*/
+ { 40, 8062 }, /*C/N=4.0dB*/
+ { 45, 7707 }, /*C/N=4.5dB*/
+ { 50, 7353 }, /*C/N=5.0dB*/
+ { 55, 7025 }, /*C/N=5.5dB*/
+ { 60, 6684 }, /*C/N=6.0dB*/
+ { 65, 6331 }, /*C/N=6.5dB*/
+ { 70, 6036 }, /*C/N=7.0dB*/
+ { 75, 5727 }, /*C/N=7.5dB*/
+ { 80, 5437 }, /*C/N=8.0dB*/
+ { 85, 5164 }, /*C/N=8.5dB*/
+ { 90, 4902 }, /*C/N=9.0dB*/
+ { 95, 4653 }, /*C/N=9.5dB*/
+ { 100, 4408 }, /*C/N=10.0dB*/
+ { 105, 4187 }, /*C/N=10.5dB*/
+ { 110, 3961 }, /*C/N=11.0dB*/
+ { 115, 3751 }, /*C/N=11.5dB*/
+ { 120, 3558 }, /*C/N=12.0dB*/
+ { 125, 3368 }, /*C/N=12.5dB*/
+ { 130, 3191 }, /*C/N=13.0dB*/
+ { 135, 3017 }, /*C/N=13.5dB*/
+ { 140, 2862 }, /*C/N=14.0dB*/
+ { 145, 2710 }, /*C/N=14.5dB*/
+ { 150, 2565 }, /*C/N=15.0dB*/
+ { 160, 2300 }, /*C/N=16.0dB*/
+ { 170, 2058 }, /*C/N=17.0dB*/
+ { 180, 1849 }, /*C/N=18.0dB*/
+ { 190, 1663 }, /*C/N=19.0dB*/
+ { 200, 1495 }, /*C/N=20.0dB*/
+ { 210, 1349 }, /*C/N=21.0dB*/
+ { 220, 1222 }, /*C/N=22.0dB*/
+ { 230, 1110 }, /*C/N=23.0dB*/
+ { 240, 1011 }, /*C/N=24.0dB*/
+ { 250, 925 }, /*C/N=25.0dB*/
+ { 260, 853 }, /*C/N=26.0dB*/
+ { 270, 789 }, /*C/N=27.0dB*/
+ { 280, 734 }, /*C/N=28.0dB*/
+ { 290, 690 }, /*C/N=29.0dB*/
+ { 300, 650 }, /*C/N=30.0dB*/
+ { 310, 619 }, /*C/N=31.0dB*/
+ { 320, 593 }, /*C/N=32.0dB*/
+ { 330, 571 }, /*C/N=33.0dB*/
+ { 400, 498 }, /*C/N=40.0dB*/
+ { 450, 484 }, /*C/N=45.0dB*/
+ { 500, 481 } /*C/N=50.0dB*/
+ }
+};
+
+/* RF level C/N Look-Up table */
+static const struct stv0900_table stv0900_rf = {
+ 14,
+ {
+ { -5, 0xCAA1 }, /*-5dBm*/
+ { -10, 0xC229 }, /*-10dBm*/
+ { -15, 0xBB08 }, /*-15dBm*/
+ { -20, 0xB4BC }, /*-20dBm*/
+ { -25, 0xAD5A }, /*-25dBm*/
+ { -30, 0xA298 }, /*-30dBm*/
+ { -35, 0x98A8 }, /*-35dBm*/
+ { -40, 0x8389 }, /*-40dBm*/
+ { -45, 0x59BE }, /*-45dBm*/
+ { -50, 0x3A14 }, /*-50dBm*/
+ { -55, 0x2D11 }, /*-55dBm*/
+ { -60, 0x210D }, /*-60dBm*/
+ { -65, 0xA14F }, /*-65dBm*/
+ { -70, 0x7AA } /*-70dBm*/
+ }
+};
+
+struct stv0900_car_loop_optim {
+ enum fe_stv0900_modcode modcode;
+ u8 car_loop_pilots_on_2;
+ u8 car_loop_pilots_off_2;
+ u8 car_loop_pilots_on_5;
+ u8 car_loop_pilots_off_5;
+ u8 car_loop_pilots_on_10;
+ u8 car_loop_pilots_off_10;
+ u8 car_loop_pilots_on_20;
+ u8 car_loop_pilots_off_20;
+ u8 car_loop_pilots_on_30;
+ u8 car_loop_pilots_off_30;
+
+};
+
+struct stv0900_short_frames_car_loop_optim {
+ enum fe_stv0900_modulation modulation;
+ u8 car_loop_cut12_2; /* Cut 1.2, SR<=3msps */
+ u8 car_loop_cut20_2; /* Cut 2.0, SR<3msps */
+ u8 car_loop_cut12_5; /* Cut 1.2, 3<SR<=7msps */
+ u8 car_loop_cut20_5; /* Cut 2.0, 3<SR<=7msps */
+ u8 car_loop_cut12_10; /* Cut 1.2, 7<SR<=15msps */
+ u8 car_loop_cut20_10; /* Cut 2.0, 7<SR<=15msps */
+ u8 car_loop_cut12_20; /* Cut 1.2, 10<SR<=25msps */
+ u8 car_loop_cut20_20; /* Cut 2.0, 10<SR<=25msps */
+ u8 car_loop_cut12_30; /* Cut 1.2, 25<SR<=45msps */
+ u8 car_loop_cut20_30; /* Cut 2.0, 10<SR<=45msps */
+
+};
+
+/* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = {
+ /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV0900_QPSK_12, 0x1C, 0x0D, 0x1B, 0x2C, 0x3A, 0x1C, 0x2A, 0x3B, 0x2A, 0x1B },
+ { STV0900_QPSK_35, 0x2C, 0x0D, 0x2B, 0x2C, 0x3A, 0x0C, 0x3A, 0x2B, 0x2A, 0x0B },
+ { STV0900_QPSK_23, 0x2C, 0x0D, 0x2B, 0x2C, 0x0B, 0x0C, 0x3A, 0x1B, 0x2A, 0x3A },
+ { STV0900_QPSK_34, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_QPSK_45, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_QPSK_56, 0x0D, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_QPSK_89, 0x0D, 0x0D, 0x3B, 0x1C, 0x1B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_QPSK_910, 0x1D, 0x0D, 0x3B, 0x1C, 0x1B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_8PSK_35, 0x29, 0x3B, 0x09, 0x2B, 0x38, 0x0B, 0x18, 0x1A, 0x08, 0x0A },
+ { STV0900_8PSK_23, 0x0A, 0x3B, 0x29, 0x2B, 0x19, 0x0B, 0x38, 0x1A, 0x18, 0x0A },
+ { STV0900_8PSK_34, 0x3A, 0x3B, 0x2A, 0x2B, 0x39, 0x0B, 0x19, 0x1A, 0x38, 0x0A },
+ { STV0900_8PSK_56, 0x1B, 0x3B, 0x0B, 0x2B, 0x1A, 0x0B, 0x39, 0x1A, 0x19, 0x0A },
+ { STV0900_8PSK_89, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A, 0x0B, 0x39, 0x1A, 0x29, 0x39 },
+ { STV0900_8PSK_910, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A, 0x0B, 0x39, 0x1A, 0x29, 0x39 }
+};
+
+
+/* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
+ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV0900_QPSK_12, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D, 0x1F, 0x3D, 0x3E, 0x3D, 0x1E },
+ { STV0900_QPSK_35, 0x2F, 0x3F, 0x2E, 0x2F, 0x3D, 0x0F, 0x0E, 0x2E, 0x3D, 0x0E },
+ { STV0900_QPSK_23, 0x2F, 0x3F, 0x2E, 0x2F, 0x0E, 0x0F, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_34, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_45, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_56, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_89, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_910, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_8PSK_35, 0x3c, 0x0c, 0x1c, 0x3b, 0x0c, 0x3b, 0x2b, 0x2b, 0x1b, 0x2b },
+ { STV0900_8PSK_23, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x3b, 0x0c, 0x2b, 0x2b, 0x2b },
+ { STV0900_8PSK_34, 0x0e, 0x1c, 0x3d, 0x0c, 0x0d, 0x3b, 0x2c, 0x3b, 0x0c, 0x2b },
+ { STV0900_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d },
+ { STV0900_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d },
+ { STV0900_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d }
+};
+
+
+
+/* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = {
+ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV0900_16APSK_23, 0x0C, 0x0C, 0x0C, 0x0C, 0x1D, 0x0C, 0x3C, 0x0C, 0x2C, 0x0C },
+ { STV0900_16APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x0C, 0x2D, 0x0C, 0x1D, 0x0C },
+ { STV0900_16APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x0C, 0x3D, 0x0C, 0x2D, 0x0C },
+ { STV0900_16APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x0C, 0x3D, 0x0C, 0x2D, 0x0C },
+ { STV0900_16APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E, 0x0C, 0x0E, 0x0C, 0x3D, 0x0C },
+ { STV0900_16APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E, 0x0C, 0x0E, 0x0C, 0x3D, 0x0C },
+ { STV0900_32APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
+ { STV0900_32APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
+ { STV0900_32APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
+ { STV0900_32APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
+ { STV0900_32APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C }
+};
+
+
+/* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = {
+ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV0900_QPSK_14, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D, 0x2F, 0x2D, 0x1F, 0x3D, 0x3E },
+ { STV0900_QPSK_13, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D, 0x2F, 0x3D, 0x0F, 0x3D, 0x2E },
+ { STV0900_QPSK_25, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D, 0x1F, 0x3D, 0x3E, 0x3D, 0x2E }
+};
+
+
+/* Cut 2.0 Tracking carrier loop carrier short Frame, cut 1.2 and 2.0 */
+static const struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = {
+ /*Mod 2M_cut1.2 2M_cut2.0 5M_cut1.2 5M_cut2.0 10M_cut1.2 10M_cut2.0 20M_cut1.2 20M_cut2.0 30M_cut1.2 30M_cut2.0 */
+ { STV0900_QPSK, 0x3C, 0x2F, 0x2B, 0x2E, 0x0B, 0x0E, 0x3A, 0x0E, 0x2A, 0x3D },
+ { STV0900_8PSK, 0x0B, 0x3E, 0x2A, 0x0E, 0x0A, 0x2D, 0x19, 0x0D, 0x09, 0x3C },
+ { STV0900_16APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B, 0x1E, 0x3A, 0x3D, 0x2A, 0x2D },
+ { STV0900_32APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B, 0x1E, 0x3A, 0x3D, 0x2A, 0x2D }
+};
+
+static const u16 STV0900_InitVal[182][2] = {
+ { R0900_OUTCFG , 0x00 },
+ { R0900_MODECFG , 0xff },
+ { R0900_AGCRF1CFG , 0x11 },
+ { R0900_AGCRF2CFG , 0x13 },
+ { R0900_TSGENERAL1X , 0x14 },
+ { R0900_TSTTNR2 , 0x21 },
+ { R0900_TSTTNR4 , 0x21 },
+ { R0900_P2_DISTXCTL , 0x22 },
+ { R0900_P2_F22TX , 0xc0 },
+ { R0900_P2_F22RX , 0xc0 },
+ { R0900_P2_DISRXCTL , 0x00 },
+ { R0900_P2_TNRSTEPS , 0x87 },
+ { R0900_P2_TNRGAIN , 0x09 },
+ { R0900_P2_DMDCFGMD , 0xF9 },
+ { R0900_P2_DEMOD , 0x08 },
+ { R0900_P2_DMDCFG3 , 0xc4 },
+ { R0900_P2_CARFREQ , 0xed },
+ { R0900_P2_TNRCFG2 , 0x02 },
+ { R0900_P2_TNRCFG3 , 0x02 },
+ { R0900_P2_LDT , 0xd0 },
+ { R0900_P2_LDT2 , 0xb8 },
+ { R0900_P2_TMGCFG , 0xd2 },
+ { R0900_P2_TMGTHRISE , 0x20 },
+ { R0900_P2_TMGTHFALL , 0x00 },
+ { R0900_P2_FECSPY , 0x88 },
+ { R0900_P2_FSPYDATA , 0x3a },
+ { R0900_P2_FBERCPT4 , 0x00 },
+ { R0900_P2_FSPYBER , 0x10 },
+ { R0900_P2_ERRCTRL1 , 0x35 },
+ { R0900_P2_ERRCTRL2 , 0xc1 },
+ { R0900_P2_CFRICFG , 0xf8 },
+ { R0900_P2_NOSCFG , 0x1c },
+ { R0900_P2_DMDT0M , 0x20 },
+ { R0900_P2_CORRELMANT , 0x70 },
+ { R0900_P2_CORRELABS , 0x88 },
+ { R0900_P2_AGC2O , 0x5b },
+ { R0900_P2_AGC2REF , 0x38 },
+ { R0900_P2_CARCFG , 0xe4 },
+ { R0900_P2_ACLC , 0x1A },
+ { R0900_P2_BCLC , 0x09 },
+ { R0900_P2_CARHDR , 0x08 },
+ { R0900_P2_KREFTMG , 0xc1 },
+ { R0900_P2_SFRUPRATIO , 0xf0 },
+ { R0900_P2_SFRLOWRATIO , 0x70 },
+ { R0900_P2_SFRSTEP , 0x58 },
+ { R0900_P2_TMGCFG2 , 0x01 },
+ { R0900_P2_CAR2CFG , 0x26 },
+ { R0900_P2_BCLC2S2Q , 0x86 },
+ { R0900_P2_BCLC2S28 , 0x86 },
+ { R0900_P2_SMAPCOEF7 , 0x77 },
+ { R0900_P2_SMAPCOEF6 , 0x85 },
+ { R0900_P2_SMAPCOEF5 , 0x77 },
+ { R0900_P2_TSCFGL , 0x20 },
+ { R0900_P2_DMDCFG2 , 0x3b },
+ { R0900_P2_MODCODLST0 , 0xff },
+ { R0900_P2_MODCODLST1 , 0xff },
+ { R0900_P2_MODCODLST2 , 0xff },
+ { R0900_P2_MODCODLST3 , 0xff },
+ { R0900_P2_MODCODLST4 , 0xff },
+ { R0900_P2_MODCODLST5 , 0xff },
+ { R0900_P2_MODCODLST6 , 0xff },
+ { R0900_P2_MODCODLST7 , 0xcc },
+ { R0900_P2_MODCODLST8 , 0xcc },
+ { R0900_P2_MODCODLST9 , 0xcc },
+ { R0900_P2_MODCODLSTA , 0xcc },
+ { R0900_P2_MODCODLSTB , 0xcc },
+ { R0900_P2_MODCODLSTC , 0xcc },
+ { R0900_P2_MODCODLSTD , 0xcc },
+ { R0900_P2_MODCODLSTE , 0xcc },
+ { R0900_P2_MODCODLSTF , 0xcf },
+ { R0900_P1_DISTXCTL , 0x22 },
+ { R0900_P1_F22TX , 0xc0 },
+ { R0900_P1_F22RX , 0xc0 },
+ { R0900_P1_DISRXCTL , 0x00 },
+ { R0900_P1_TNRSTEPS , 0x87 },
+ { R0900_P1_TNRGAIN , 0x09 },
+ { R0900_P1_DMDCFGMD , 0xf9 },
+ { R0900_P1_DEMOD , 0x08 },
+ { R0900_P1_DMDCFG3 , 0xc4 },
+ { R0900_P1_DMDT0M , 0x20 },
+ { R0900_P1_CARFREQ , 0xed },
+ { R0900_P1_TNRCFG2 , 0x82 },
+ { R0900_P1_TNRCFG3 , 0x02 },
+ { R0900_P1_LDT , 0xd0 },
+ { R0900_P1_LDT2 , 0xb8 },
+ { R0900_P1_TMGCFG , 0xd2 },
+ { R0900_P1_TMGTHRISE , 0x20 },
+ { R0900_P1_TMGTHFALL , 0x00 },
+ { R0900_P1_SFRUPRATIO , 0xf0 },
+ { R0900_P1_SFRLOWRATIO , 0x70 },
+ { R0900_P1_TSCFGL , 0x20 },
+ { R0900_P1_FECSPY , 0x88 },
+ { R0900_P1_FSPYDATA , 0x3a },
+ { R0900_P1_FBERCPT4 , 0x00 },
+ { R0900_P1_FSPYBER , 0x10 },
+ { R0900_P1_ERRCTRL1 , 0x35 },
+ { R0900_P1_ERRCTRL2 , 0xc1 },
+ { R0900_P1_CFRICFG , 0xf8 },
+ { R0900_P1_NOSCFG , 0x1c },
+ { R0900_P1_CORRELMANT , 0x70 },
+ { R0900_P1_CORRELABS , 0x88 },
+ { R0900_P1_AGC2O , 0x5b },
+ { R0900_P1_AGC2REF , 0x38 },
+ { R0900_P1_CARCFG , 0xe4 },
+ { R0900_P1_ACLC , 0x1A },
+ { R0900_P1_BCLC , 0x09 },
+ { R0900_P1_CARHDR , 0x08 },
+ { R0900_P1_KREFTMG , 0xc1 },
+ { R0900_P1_SFRSTEP , 0x58 },
+ { R0900_P1_TMGCFG2 , 0x01 },
+ { R0900_P1_CAR2CFG , 0x26 },
+ { R0900_P1_BCLC2S2Q , 0x86 },
+ { R0900_P1_BCLC2S28 , 0x86 },
+ { R0900_P1_SMAPCOEF7 , 0x77 },
+ { R0900_P1_SMAPCOEF6 , 0x85 },
+ { R0900_P1_SMAPCOEF5 , 0x77 },
+ { R0900_P1_DMDCFG2 , 0x3b },
+ { R0900_P1_MODCODLST0 , 0xff },
+ { R0900_P1_MODCODLST1 , 0xff },
+ { R0900_P1_MODCODLST2 , 0xff },
+ { R0900_P1_MODCODLST3 , 0xff },
+ { R0900_P1_MODCODLST4 , 0xff },
+ { R0900_P1_MODCODLST5 , 0xff },
+ { R0900_P1_MODCODLST6 , 0xff },
+ { R0900_P1_MODCODLST7 , 0xcc },
+ { R0900_P1_MODCODLST8 , 0xcc },
+ { R0900_P1_MODCODLST9 , 0xcc },
+ { R0900_P1_MODCODLSTA , 0xcc },
+ { R0900_P1_MODCODLSTB , 0xcc },
+ { R0900_P1_MODCODLSTC , 0xcc },
+ { R0900_P1_MODCODLSTD , 0xcc },
+ { R0900_P1_MODCODLSTE , 0xcc },
+ { R0900_P1_MODCODLSTF , 0xcf },
+ { R0900_GENCFG , 0x1d },
+ { R0900_NBITER_NF4 , 0x37 },
+ { R0900_NBITER_NF5 , 0x29 },
+ { R0900_NBITER_NF6 , 0x37 },
+ { R0900_NBITER_NF7 , 0x33 },
+ { R0900_NBITER_NF8 , 0x31 },
+ { R0900_NBITER_NF9 , 0x2f },
+ { R0900_NBITER_NF10 , 0x39 },
+ { R0900_NBITER_NF11 , 0x3a },
+ { R0900_NBITER_NF12 , 0x29 },
+ { R0900_NBITER_NF13 , 0x37 },
+ { R0900_NBITER_NF14 , 0x33 },
+ { R0900_NBITER_NF15 , 0x2f },
+ { R0900_NBITER_NF16 , 0x39 },
+ { R0900_NBITER_NF17 , 0x3a },
+ { R0900_NBITERNOERR , 0x04 },
+ { R0900_GAINLLR_NF4 , 0x0C },
+ { R0900_GAINLLR_NF5 , 0x0F },
+ { R0900_GAINLLR_NF6 , 0x11 },
+ { R0900_GAINLLR_NF7 , 0x14 },
+ { R0900_GAINLLR_NF8 , 0x17 },
+ { R0900_GAINLLR_NF9 , 0x19 },
+ { R0900_GAINLLR_NF10 , 0x20 },
+ { R0900_GAINLLR_NF11 , 0x21 },
+ { R0900_GAINLLR_NF12 , 0x0D },
+ { R0900_GAINLLR_NF13 , 0x0F },
+ { R0900_GAINLLR_NF14 , 0x13 },
+ { R0900_GAINLLR_NF15 , 0x1A },
+ { R0900_GAINLLR_NF16 , 0x1F },
+ { R0900_GAINLLR_NF17 , 0x21 },
+ { R0900_RCCFGH , 0x20 },
+ { R0900_P1_FECM , 0x01 }, /*disable DSS modes*/
+ { R0900_P2_FECM , 0x01 }, /*disable DSS modes*/
+ { R0900_P1_PRVIT , 0x2F }, /*disable puncture rate 6/7*/
+ { R0900_P2_PRVIT , 0x2F }, /*disable puncture rate 6/7*/
+ { R0900_STROUT1CFG , 0x4c },
+ { R0900_STROUT2CFG , 0x4c },
+ { R0900_CLKOUT1CFG , 0x50 },
+ { R0900_CLKOUT2CFG , 0x50 },
+ { R0900_DPN1CFG , 0x4a },
+ { R0900_DPN2CFG , 0x4a },
+ { R0900_DATA71CFG , 0x52 },
+ { R0900_DATA72CFG , 0x52 },
+ { R0900_P1_TSCFGM , 0xc0 },
+ { R0900_P2_TSCFGM , 0xc0 },
+ { R0900_P1_TSCFGH , 0xe0 }, /* DVB-CI timings */
+ { R0900_P2_TSCFGH , 0xe0 }, /* DVB-CI timings */
+ { R0900_P1_TSSPEED , 0x40 },
+ { R0900_P2_TSSPEED , 0x40 },
+};
+
+static const u16 STV0900_Cut20_AddOnVal[32][2] = {
+ { R0900_P2_DMDCFG3 , 0xe8 },
+ { R0900_P2_DMDCFG4 , 0x10 },
+ { R0900_P2_CARFREQ , 0x38 },
+ { R0900_P2_CARHDR , 0x20 },
+ { R0900_P2_KREFTMG , 0x5a },
+ { R0900_P2_SMAPCOEF7 , 0x06 },
+ { R0900_P2_SMAPCOEF6 , 0x00 },
+ { R0900_P2_SMAPCOEF5 , 0x04 },
+ { R0900_P2_NOSCFG , 0x0c },
+ { R0900_P1_DMDCFG3 , 0xe8 },
+ { R0900_P1_DMDCFG4 , 0x10 },
+ { R0900_P1_CARFREQ , 0x38 },
+ { R0900_P1_CARHDR , 0x20 },
+ { R0900_P1_KREFTMG , 0x5a },
+ { R0900_P1_SMAPCOEF7 , 0x06 },
+ { R0900_P1_SMAPCOEF6 , 0x00 },
+ { R0900_P1_SMAPCOEF5 , 0x04 },
+ { R0900_P1_NOSCFG , 0x0c },
+ { R0900_GAINLLR_NF4 , 0x21 },
+ { R0900_GAINLLR_NF5 , 0x21 },
+ { R0900_GAINLLR_NF6 , 0x20 },
+ { R0900_GAINLLR_NF7 , 0x1F },
+ { R0900_GAINLLR_NF8 , 0x1E },
+ { R0900_GAINLLR_NF9 , 0x1E },
+ { R0900_GAINLLR_NF10 , 0x1D },
+ { R0900_GAINLLR_NF11 , 0x1B },
+ { R0900_GAINLLR_NF12 , 0x20 },
+ { R0900_GAINLLR_NF13 , 0x20 },
+ { R0900_GAINLLR_NF14 , 0x20 },
+ { R0900_GAINLLR_NF15 , 0x20 },
+ { R0900_GAINLLR_NF16 , 0x20 },
+ { R0900_GAINLLR_NF17 , 0x21 }
+
+};
+
+#endif
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h
new file mode 100644
index 000000000000..762d5af62d7a
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_priv.h
@@ -0,0 +1,430 @@
+/*
+ * stv0900_priv.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0900_PRIV_H
+#define STV0900_PRIV_H
+
+#include <linux/i2c.h>
+
+#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
+#define INRANGE(X, Y, Z) ((((X) <= (Y)) && ((Y) <= (Z))) \
+ || (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0)
+
+#ifndef MAKEWORD
+#define MAKEWORD(X, Y) (((X) << 8) + (Y))
+#endif
+
+#define LSB(X) (((X) & 0xFF))
+#define MSB(Y) (((Y) >> 8) & 0xFF)
+
+#ifndef TRUE
+#define TRUE (1 == 1)
+#endif
+#ifndef FALSE
+#define FALSE (!TRUE)
+#endif
+
+#define dmd_reg(a, b, c) \
+ do { \
+ a = 0; \
+ switch (demod) { \
+ case STV0900_DEMOD_1: \
+ default: \
+ a = b; \
+ break; \
+ case STV0900_DEMOD_2: \
+ a = c; \
+ break; \
+ } \
+ } while (0)
+
+#define dmd_choose(a, b) (demod = STV0900_DEMOD_2 ? b : a))
+
+static int stvdebug;
+
+#define dprintk(args...) \
+ do { \
+ if (stvdebug) \
+ printk(KERN_DEBUG args); \
+ } while (0)
+
+#define STV0900_MAXLOOKUPSIZE 500
+#define STV0900_BLIND_SEARCH_AGC2_TH 700
+
+/* One point of the lookup table */
+struct stv000_lookpoint {
+ s32 realval;/* real value */
+ s32 regval;/* binary value */
+};
+
+/* Lookup table definition */
+struct stv0900_table{
+ s32 size;/* Size of the lookup table */
+ struct stv000_lookpoint table[STV0900_MAXLOOKUPSIZE];/* Lookup table */
+};
+
+enum fe_stv0900_error {
+ STV0900_NO_ERROR = 0,
+ STV0900_INVALID_HANDLE,
+ STV0900_BAD_PARAMETER,
+ STV0900_I2C_ERROR,
+ STV0900_SEARCH_FAILED,
+};
+
+enum fe_stv0900_clock_type {
+ STV0900_USE_REGISTERS_DEFAULT,
+ STV0900_SERIAL_PUNCT_CLOCK,/*Serial punctured clock */
+ STV0900_SERIAL_CONT_CLOCK,/*Serial continues clock */
+ STV0900_PARALLEL_PUNCT_CLOCK,/*Parallel punctured clock */
+ STV0900_DVBCI_CLOCK/*Parallel continues clock : DVBCI */
+};
+
+enum fe_stv0900_search_state {
+ STV0900_SEARCH = 0,
+ STV0900_PLH_DETECTED,
+ STV0900_DVBS2_FOUND,
+ STV0900_DVBS_FOUND
+
+};
+
+enum fe_stv0900_ldpc_state {
+ STV0900_PATH1_OFF_PATH2_OFF = 0,
+ STV0900_PATH1_ON_PATH2_OFF = 1,
+ STV0900_PATH1_OFF_PATH2_ON = 2,
+ STV0900_PATH1_ON_PATH2_ON = 3
+};
+
+enum fe_stv0900_signal_type {
+ STV0900_NOAGC1 = 0,
+ STV0900_AGC1OK,
+ STV0900_NOTIMING,
+ STV0900_ANALOGCARRIER,
+ STV0900_TIMINGOK,
+ STV0900_NOAGC2,
+ STV0900_AGC2OK,
+ STV0900_NOCARRIER,
+ STV0900_CARRIEROK,
+ STV0900_NODATA,
+ STV0900_DATAOK,
+ STV0900_OUTOFRANGE,
+ STV0900_RANGEOK
+};
+
+enum fe_stv0900_demod_num {
+ STV0900_DEMOD_1,
+ STV0900_DEMOD_2
+};
+
+enum fe_stv0900_tracking_standard {
+ STV0900_DVBS1_STANDARD,/* Found Standard*/
+ STV0900_DVBS2_STANDARD,
+ STV0900_DSS_STANDARD,
+ STV0900_TURBOCODE_STANDARD,
+ STV0900_UNKNOWN_STANDARD
+};
+
+enum fe_stv0900_search_standard {
+ STV0900_AUTO_SEARCH,
+ STV0900_SEARCH_DVBS1,/* Search Standard*/
+ STV0900_SEARCH_DVBS2,
+ STV0900_SEARCH_DSS,
+ STV0900_SEARCH_TURBOCODE
+};
+
+enum fe_stv0900_search_algo {
+ STV0900_BLIND_SEARCH,/* offset freq and SR are Unknown */
+ STV0900_COLD_START,/* only the SR is known */
+ STV0900_WARM_START/* offset freq and SR are known */
+};
+
+enum fe_stv0900_modulation {
+ STV0900_QPSK,
+ STV0900_8PSK,
+ STV0900_16APSK,
+ STV0900_32APSK,
+ STV0900_UNKNOWN
+};
+
+enum fe_stv0900_modcode {
+ STV0900_DUMMY_PLF,
+ STV0900_QPSK_14,
+ STV0900_QPSK_13,
+ STV0900_QPSK_25,
+ STV0900_QPSK_12,
+ STV0900_QPSK_35,
+ STV0900_QPSK_23,
+ STV0900_QPSK_34,
+ STV0900_QPSK_45,
+ STV0900_QPSK_56,
+ STV0900_QPSK_89,
+ STV0900_QPSK_910,
+ STV0900_8PSK_35,
+ STV0900_8PSK_23,
+ STV0900_8PSK_34,
+ STV0900_8PSK_56,
+ STV0900_8PSK_89,
+ STV0900_8PSK_910,
+ STV0900_16APSK_23,
+ STV0900_16APSK_34,
+ STV0900_16APSK_45,
+ STV0900_16APSK_56,
+ STV0900_16APSK_89,
+ STV0900_16APSK_910,
+ STV0900_32APSK_34,
+ STV0900_32APSK_45,
+ STV0900_32APSK_56,
+ STV0900_32APSK_89,
+ STV0900_32APSK_910,
+ STV0900_MODCODE_UNKNOWN
+};
+
+enum fe_stv0900_fec {/*DVBS1, DSS and turbo code puncture rate*/
+ STV0900_FEC_1_2 = 0,
+ STV0900_FEC_2_3,
+ STV0900_FEC_3_4,
+ STV0900_FEC_4_5,/*for turbo code only*/
+ STV0900_FEC_5_6,
+ STV0900_FEC_6_7,/*for DSS only */
+ STV0900_FEC_7_8,
+ STV0900_FEC_8_9,/*for turbo code only*/
+ STV0900_FEC_UNKNOWN
+};
+
+enum fe_stv0900_frame_length {
+ STV0900_LONG_FRAME,
+ STV0900_SHORT_FRAME
+};
+
+enum fe_stv0900_pilot {
+ STV0900_PILOTS_OFF,
+ STV0900_PILOTS_ON
+};
+
+enum fe_stv0900_rolloff {
+ STV0900_35,
+ STV0900_25,
+ STV0900_20
+};
+
+enum fe_stv0900_search_iq {
+ STV0900_IQ_AUTO,
+ STV0900_IQ_AUTO_NORMAL_FIRST,
+ STV0900_IQ_FORCE_NORMAL,
+ STV0900_IQ_FORCE_SWAPPED
+};
+
+enum stv0900_iq_inversion {
+ STV0900_IQ_NORMAL,
+ STV0900_IQ_SWAPPED
+};
+
+enum fe_stv0900_diseqc_mode {
+ STV0900_22KHZ_Continues = 0,
+ STV0900_DISEQC_2_3_PWM = 2,
+ STV0900_DISEQC_3_3_PWM = 3,
+ STV0900_DISEQC_2_3_ENVELOP = 4,
+ STV0900_DISEQC_3_3_ENVELOP = 5
+};
+
+enum fe_stv0900_demod_mode {
+ STV0900_SINGLE = 0,
+ STV0900_DUAL
+};
+
+struct stv0900_init_params{
+ u32 dmd_ref_clk;/* Refrence,Input clock for the demod in Hz */
+
+ /* Demodulator Type (single demod or dual demod) */
+ enum fe_stv0900_demod_mode demod_mode;
+ enum fe_stv0900_rolloff rolloff;
+ enum fe_stv0900_clock_type path1_ts_clock;
+
+ u8 tun1_maddress;
+ int tuner1_adc;
+
+ /* IQ from the tuner1 to the demod */
+ enum stv0900_iq_inversion tun1_iq_inversion;
+ enum fe_stv0900_clock_type path2_ts_clock;
+
+ u8 tun2_maddress;
+ int tuner2_adc;
+
+ /* IQ from the tuner2 to the demod */
+ enum stv0900_iq_inversion tun2_iq_inversion;
+};
+
+struct stv0900_search_params {
+ enum fe_stv0900_demod_num path;/* Path Used demod1 or 2 */
+
+ u32 frequency;/* Transponder frequency (in KHz) */
+ u32 symbol_rate;/* Transponder symbol rate (in bds)*/
+ u32 search_range;/* Range of the search (in Hz) */
+
+ enum fe_stv0900_search_standard standard;
+ enum fe_stv0900_modulation modulation;
+ enum fe_stv0900_fec fec;
+ enum fe_stv0900_modcode modcode;
+ enum fe_stv0900_search_iq iq_inversion;
+ enum fe_stv0900_search_algo search_algo;
+
+};
+
+struct stv0900_signal_info {
+ int locked;/* Transponder locked */
+ u32 frequency;/* Transponder frequency (in KHz) */
+ u32 symbol_rate;/* Transponder symbol rate (in Mbds) */
+
+ enum fe_stv0900_tracking_standard standard;
+ enum fe_stv0900_fec fec;
+ enum fe_stv0900_modcode modcode;
+ enum fe_stv0900_modulation modulation;
+ enum fe_stv0900_pilot pilot;
+ enum fe_stv0900_frame_length frame_length;
+ enum stv0900_iq_inversion spectrum;
+ enum fe_stv0900_rolloff rolloff;
+
+ s32 Power;/* Power of the RF signal (dBm) */
+ s32 C_N;/* Carrier to noise ratio (dB x10)*/
+ u32 BER;/* Bit error rate (x10^7) */
+
+};
+
+struct stv0900_internal{
+ s32 quartz;
+ s32 mclk;
+ /* manual RollOff for DVBS1/DSS only */
+ enum fe_stv0900_rolloff rolloff;
+ /* Demodulator use for single demod or for dual demod) */
+ enum fe_stv0900_demod_mode demod_mode;
+
+ /*Demod 1*/
+ s32 tuner1_freq;
+ s32 tuner1_bw;
+ s32 dmd1_symbol_rate;
+ s32 dmd1_srch_range;
+
+ /* algorithm for search Blind, Cold or Warm*/
+ enum fe_stv0900_search_algo dmd1_srch_algo;
+ /* search standard: Auto, DVBS1/DSS only or DVBS2 only*/
+ enum fe_stv0900_search_standard dmd1_srch_standard;
+ /* inversion search : auto, auto norma first, normal or inverted */
+ enum fe_stv0900_search_iq dmd1_srch_iq_inv;
+ enum fe_stv0900_modcode dmd1_modcode;
+ enum fe_stv0900_modulation dmd1_modulation;
+ enum fe_stv0900_fec dmd1_fec;
+
+ struct stv0900_signal_info dmd1_rslts;
+ enum fe_stv0900_signal_type dmd1_state;
+
+ enum fe_stv0900_error dmd1_err;
+
+ /*Demod 2*/
+ s32 tuner2_freq;
+ s32 tuner2_bw;
+ s32 dmd2_symbol_rate;
+ s32 dmd2_srch_range;
+
+ enum fe_stv0900_search_algo dmd2_srch_algo;
+ enum fe_stv0900_search_standard dmd2_srch_stndrd;
+ /* inversion search : auto, auto normal first, normal or inverted */
+ enum fe_stv0900_search_iq dmd2_srch_iq_inv;
+ enum fe_stv0900_modcode dmd2_modcode;
+ enum fe_stv0900_modulation dmd2_modulation;
+ enum fe_stv0900_fec dmd2_fec;
+
+ /* results of the search*/
+ struct stv0900_signal_info dmd2_rslts;
+ /* current state of the search algorithm */
+ enum fe_stv0900_signal_type dmd2_state;
+
+ enum fe_stv0900_error dmd2_err;
+
+ struct i2c_adapter *i2c_adap;
+ u8 i2c_addr;
+ u8 clkmode;/* 0 for CLKI, 2 for XTALI */
+ u8 chip_id;
+ enum fe_stv0900_error errs;
+ int dmds_used;
+};
+
+/* state for each demod */
+struct stv0900_state {
+ /* pointer for internal params, one for each pair of demods */
+ struct stv0900_internal *internal;
+ struct i2c_adapter *i2c_adap;
+ const struct stv0900_config *config;
+ struct dvb_frontend frontend;
+ int demod;
+};
+
+extern s32 ge2comp(s32 a, s32 width);
+
+extern void stv0900_write_reg(struct stv0900_internal *i_params,
+ u16 reg_addr, u8 reg_data);
+
+extern u8 stv0900_read_reg(struct stv0900_internal *i_params,
+ u16 reg_addr);
+
+extern void stv0900_write_bits(struct stv0900_internal *i_params,
+ u32 label, u8 val);
+
+extern u8 stv0900_get_bits(struct stv0900_internal *i_params,
+ u32 label);
+
+extern int stv0900_get_demod_lock(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod, s32 time_out);
+extern int stv0900_check_signal_presence(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe);
+
+extern void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
+ u32 bandwidth);
+extern void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth);
+
+extern void stv0900_start_search(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern u8 stv0900_get_optim_carr_loop(s32 srate,
+ enum fe_stv0900_modcode modcode,
+ s32 pilot, u8 chip_id);
+
+extern u8 stv0900_get_optim_short_carr_loop(s32 srate,
+ enum fe_stv0900_modulation modulation,
+ u8 chip_id);
+
+extern void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern void stv0900_activate_s2_modcode(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
+ enum fe_stv0900_demod_num demod);
+
+#endif
diff --git a/drivers/media/dvb/frontends/stv0900_reg.h b/drivers/media/dvb/frontends/stv0900_reg.h
new file mode 100644
index 000000000000..264f9cf9a17e
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_reg.h
@@ -0,0 +1,3787 @@
+/*
+ * stv0900_reg.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0900_REG_H
+#define STV0900_REG_H
+
+/*MID*/
+#define R0900_MID 0xf100
+#define F0900_MCHIP_IDENT 0xf10000f0
+#define F0900_MRELEASE 0xf100000f
+
+/*DACR1*/
+#define R0900_DACR1 0xf113
+#define F0900_DAC_MODE 0xf11300e0
+#define F0900_DAC_VALUE1 0xf113000f
+
+/*DACR2*/
+#define R0900_DACR2 0xf114
+#define F0900_DAC_VALUE0 0xf11400ff
+
+/*OUTCFG*/
+#define R0900_OUTCFG 0xf11c
+#define F0900_INV_DATA6 0xf11c0080
+#define F0900_OUTSERRS1_HZ 0xf11c0040
+#define F0900_OUTSERRS2_HZ 0xf11c0020
+#define F0900_OUTSERRS3_HZ 0xf11c0010
+#define F0900_OUTPARRS3_HZ 0xf11c0008
+#define F0900_OUTHZ3_CONTROL 0xf11c0007
+
+/*MODECFG*/
+#define R0900_MODECFG 0xf11d
+#define F0900_FECSPY_SEL_2 0xf11d0020
+#define F0900_HWARE_SEL_2 0xf11d0010
+#define F0900_PKTDEL_SEL_2 0xf11d0008
+#define F0900_DISEQC_SEL_2 0xf11d0004
+#define F0900_VIT_SEL_2 0xf11d0002
+#define F0900_DEMOD_SEL_2 0xf11d0001
+
+/*IRQSTATUS3*/
+#define R0900_IRQSTATUS3 0xf120
+#define F0900_SPLL_LOCK 0xf1200020
+#define F0900_SSTREAM_LCK_3 0xf1200010
+#define F0900_SSTREAM_LCK_2 0xf1200008
+#define F0900_SSTREAM_LCK_1 0xf1200004
+#define F0900_SDVBS1_PRF_2 0xf1200002
+#define F0900_SDVBS1_PRF_1 0xf1200001
+
+/*IRQSTATUS2*/
+#define R0900_IRQSTATUS2 0xf121
+#define F0900_SSPY_ENDSIM_3 0xf1210080
+#define F0900_SSPY_ENDSIM_2 0xf1210040
+#define F0900_SSPY_ENDSIM_1 0xf1210020
+#define F0900_SPKTDEL_ERROR_2 0xf1210010
+#define F0900_SPKTDEL_LOCKB_2 0xf1210008
+#define F0900_SPKTDEL_LOCK_2 0xf1210004
+#define F0900_SPKTDEL_ERROR_1 0xf1210002
+#define F0900_SPKTDEL_LOCKB_1 0xf1210001
+
+/*IRQSTATUS1*/
+#define R0900_IRQSTATUS1 0xf122
+#define F0900_SPKTDEL_LOCK_1 0xf1220080
+#define F0900_SEXTPINB2 0xf1220040
+#define F0900_SEXTPIN2 0xf1220020
+#define F0900_SEXTPINB1 0xf1220010
+#define F0900_SEXTPIN1 0xf1220008
+#define F0900_SDEMOD_LOCKB_2 0xf1220004
+#define F0900_SDEMOD_LOCK_2 0xf1220002
+#define F0900_SDEMOD_IRQ_2 0xf1220001
+
+/*IRQSTATUS0*/
+#define R0900_IRQSTATUS0 0xf123
+#define F0900_SDEMOD_LOCKB_1 0xf1230080
+#define F0900_SDEMOD_LOCK_1 0xf1230040
+#define F0900_SDEMOD_IRQ_1 0xf1230020
+#define F0900_SBCH_ERRFLAG 0xf1230010
+#define F0900_SDISEQC2RX_IRQ 0xf1230008
+#define F0900_SDISEQC2TX_IRQ 0xf1230004
+#define F0900_SDISEQC1RX_IRQ 0xf1230002
+#define F0900_SDISEQC1TX_IRQ 0xf1230001
+
+/*IRQMASK3*/
+#define R0900_IRQMASK3 0xf124
+#define F0900_MPLL_LOCK 0xf1240020
+#define F0900_MSTREAM_LCK_3 0xf1240010
+#define F0900_MSTREAM_LCK_2 0xf1240008
+#define F0900_MSTREAM_LCK_1 0xf1240004
+#define F0900_MDVBS1_PRF_2 0xf1240002
+#define F0900_MDVBS1_PRF_1 0xf1240001
+
+/*IRQMASK2*/
+#define R0900_IRQMASK2 0xf125
+#define F0900_MSPY_ENDSIM_3 0xf1250080
+#define F0900_MSPY_ENDSIM_2 0xf1250040
+#define F0900_MSPY_ENDSIM_1 0xf1250020
+#define F0900_MPKTDEL_ERROR_2 0xf1250010
+#define F0900_MPKTDEL_LOCKB_2 0xf1250008
+#define F0900_MPKTDEL_LOCK_2 0xf1250004
+#define F0900_MPKTDEL_ERROR_1 0xf1250002
+#define F0900_MPKTDEL_LOCKB_1 0xf1250001
+
+/*IRQMASK1*/
+#define R0900_IRQMASK1 0xf126
+#define F0900_MPKTDEL_LOCK_1 0xf1260080
+#define F0900_MEXTPINB2 0xf1260040
+#define F0900_MEXTPIN2 0xf1260020
+#define F0900_MEXTPINB1 0xf1260010
+#define F0900_MEXTPIN1 0xf1260008
+#define F0900_MDEMOD_LOCKB_2 0xf1260004
+#define F0900_MDEMOD_LOCK_2 0xf1260002
+#define F0900_MDEMOD_IRQ_2 0xf1260001
+
+/*IRQMASK0*/
+#define R0900_IRQMASK0 0xf127
+#define F0900_MDEMOD_LOCKB_1 0xf1270080
+#define F0900_MDEMOD_LOCK_1 0xf1270040
+#define F0900_MDEMOD_IRQ_1 0xf1270020
+#define F0900_MBCH_ERRFLAG 0xf1270010
+#define F0900_MDISEQC2RX_IRQ 0xf1270008
+#define F0900_MDISEQC2TX_IRQ 0xf1270004
+#define F0900_MDISEQC1RX_IRQ 0xf1270002
+#define F0900_MDISEQC1TX_IRQ 0xf1270001
+
+/*I2CCFG*/
+#define R0900_I2CCFG 0xf129
+#define F0900_I2C2_FASTMODE 0xf1290080
+#define F0900_STATUS_WR2 0xf1290040
+#define F0900_I2C2ADDR_INC 0xf1290030
+#define F0900_I2C_FASTMODE 0xf1290008
+#define F0900_STATUS_WR 0xf1290004
+#define F0900_I2CADDR_INC 0xf1290003
+
+/*P1_I2CRPT*/
+#define R0900_P1_I2CRPT 0xf12a
+#define F0900_P1_I2CT_ON 0xf12a0080
+#define F0900_P1_ENARPT_LEVEL 0xf12a0070
+#define F0900_P1_SCLT_DELAY 0xf12a0008
+#define F0900_P1_STOP_ENABLE 0xf12a0004
+#define F0900_P1_STOP_SDAT2SDA 0xf12a0002
+
+/*P2_I2CRPT*/
+#define R0900_P2_I2CRPT 0xf12b
+#define F0900_P2_I2CT_ON 0xf12b0080
+#define F0900_P2_ENARPT_LEVEL 0xf12b0070
+#define F0900_P2_SCLT_DELAY 0xf12b0008
+#define F0900_P2_STOP_ENABLE 0xf12b0004
+#define F0900_P2_STOP_SDAT2SDA 0xf12b0002
+
+/*CLKI2CFG*/
+#define R0900_CLKI2CFG 0xf140
+#define F0900_CLKI2_OPD 0xf1400080
+#define F0900_CLKI2_CONFIG 0xf140007e
+#define F0900_CLKI2_XOR 0xf1400001
+
+/*GPIO1CFG*/
+#define R0900_GPIO1CFG 0xf141
+#define F0900_GPIO1_OPD 0xf1410080
+#define F0900_GPIO1_CONFIG 0xf141007e
+#define F0900_GPIO1_XOR 0xf1410001
+
+/*GPIO2CFG*/
+#define R0900_GPIO2CFG 0xf142
+#define F0900_GPIO2_OPD 0xf1420080
+#define F0900_GPIO2_CONFIG 0xf142007e
+#define F0900_GPIO2_XOR 0xf1420001
+
+/*GPIO3CFG*/
+#define R0900_GPIO3CFG 0xf143
+#define F0900_GPIO3_OPD 0xf1430080
+#define F0900_GPIO3_CONFIG 0xf143007e
+#define F0900_GPIO3_XOR 0xf1430001
+
+/*GPIO4CFG*/
+#define R0900_GPIO4CFG 0xf144
+#define F0900_GPIO4_OPD 0xf1440080
+#define F0900_GPIO4_CONFIG 0xf144007e
+#define F0900_GPIO4_XOR 0xf1440001
+
+/*GPIO5CFG*/
+#define R0900_GPIO5CFG 0xf145
+#define F0900_GPIO5_OPD 0xf1450080
+#define F0900_GPIO5_CONFIG 0xf145007e
+#define F0900_GPIO5_XOR 0xf1450001
+
+/*GPIO6CFG*/
+#define R0900_GPIO6CFG 0xf146
+#define F0900_GPIO6_OPD 0xf1460080
+#define F0900_GPIO6_CONFIG 0xf146007e
+#define F0900_GPIO6_XOR 0xf1460001
+
+/*GPIO7CFG*/
+#define R0900_GPIO7CFG 0xf147
+#define F0900_GPIO7_OPD 0xf1470080
+#define F0900_GPIO7_CONFIG 0xf147007e
+#define F0900_GPIO7_XOR 0xf1470001
+
+/*GPIO8CFG*/
+#define R0900_GPIO8CFG 0xf148
+#define F0900_GPIO8_OPD 0xf1480080
+#define F0900_GPIO8_CONFIG 0xf148007e
+#define F0900_GPIO8_XOR 0xf1480001
+
+/*GPIO9CFG*/
+#define R0900_GPIO9CFG 0xf149
+#define F0900_GPIO9_OPD 0xf1490080
+#define F0900_GPIO9_CONFIG 0xf149007e
+#define F0900_GPIO9_XOR 0xf1490001
+
+/*GPIO10CFG*/
+#define R0900_GPIO10CFG 0xf14a
+#define F0900_GPIO10_OPD 0xf14a0080
+#define F0900_GPIO10_CONFIG 0xf14a007e
+#define F0900_GPIO10_XOR 0xf14a0001
+
+/*GPIO11CFG*/
+#define R0900_GPIO11CFG 0xf14b
+#define F0900_GPIO11_OPD 0xf14b0080
+#define F0900_GPIO11_CONFIG 0xf14b007e
+#define F0900_GPIO11_XOR 0xf14b0001
+
+/*GPIO12CFG*/
+#define R0900_GPIO12CFG 0xf14c
+#define F0900_GPIO12_OPD 0xf14c0080
+#define F0900_GPIO12_CONFIG 0xf14c007e
+#define F0900_GPIO12_XOR 0xf14c0001
+
+/*GPIO13CFG*/
+#define R0900_GPIO13CFG 0xf14d
+#define F0900_GPIO13_OPD 0xf14d0080
+#define F0900_GPIO13_CONFIG 0xf14d007e
+#define F0900_GPIO13_XOR 0xf14d0001
+
+/*CS0CFG*/
+#define R0900_CS0CFG 0xf14e
+#define F0900_CS0_OPD 0xf14e0080
+#define F0900_CS0_CONFIG 0xf14e007e
+#define F0900_CS0_XOR 0xf14e0001
+
+/*CS1CFG*/
+#define R0900_CS1CFG 0xf14f
+#define F0900_CS1_OPD 0xf14f0080
+#define F0900_CS1_CONFIG 0xf14f007e
+#define F0900_CS1_XOR 0xf14f0001
+
+/*STDBYCFG*/
+#define R0900_STDBYCFG 0xf150
+#define F0900_STDBY_OPD 0xf1500080
+#define F0900_STDBY_CONFIG 0xf150007e
+#define F0900_STBDY_XOR 0xf1500001
+
+/*DIRCLKCFG*/
+#define R0900_DIRCLKCFG 0xf151
+#define F0900_DIRCLK_OPD 0xf1510080
+#define F0900_DIRCLK_CONFIG 0xf151007e
+#define F0900_DIRCLK_XOR 0xf1510001
+
+/*AGCRF1CFG*/
+#define R0900_AGCRF1CFG 0xf152
+#define F0900_AGCRF1_OPD 0xf1520080
+#define F0900_AGCRF1_CONFIG 0xf152007e
+#define F0900_AGCRF1_XOR 0xf1520001
+
+/*SDAT1CFG*/
+#define R0900_SDAT1CFG 0xf153
+#define F0900_SDAT1_OPD 0xf1530080
+#define F0900_SDAT1_CONFIG 0xf153007e
+#define F0900_SDAT1_XOR 0xf1530001
+
+/*SCLT1CFG*/
+#define R0900_SCLT1CFG 0xf154
+#define F0900_SCLT1_OPD 0xf1540080
+#define F0900_SCLT1_CONFIG 0xf154007e
+#define F0900_SCLT1_XOR 0xf1540001
+
+/*DISEQCO1CFG*/
+#define R0900_DISEQCO1CFG 0xf155
+#define F0900_DISEQCO1_OPD 0xf1550080
+#define F0900_DISEQCO1_CONFIG 0xf155007e
+#define F0900_DISEQC1_XOR 0xf1550001
+
+/*AGCRF2CFG*/
+#define R0900_AGCRF2CFG 0xf156
+#define F0900_AGCRF2_OPD 0xf1560080
+#define F0900_AGCRF2_CONFIG 0xf156007e
+#define F0900_AGCRF2_XOR 0xf1560001
+
+/*SDAT2CFG*/
+#define R0900_SDAT2CFG 0xf157
+#define F0900_SDAT2_OPD 0xf1570080
+#define F0900_SDAT2_CONFIG 0xf157007e
+#define F0900_SDAT2_XOR 0xf1570001
+
+/*SCLT2CFG*/
+#define R0900_SCLT2CFG 0xf158
+#define F0900_SCLT2_OPD 0xf1580080
+#define F0900_SCLT2_CONFIG 0xf158007e
+#define F0900_SCLT2_XOR 0xf1580001
+
+/*DISEQCO2CFG*/
+#define R0900_DISEQCO2CFG 0xf159
+#define F0900_DISEQCO2_OPD 0xf1590080
+#define F0900_DISEQCO2_CONFIG 0xf159007e
+#define F0900_DISEQC2_XOR 0xf1590001
+
+/*CLKOUT27CFG*/
+#define R0900_CLKOUT27CFG 0xf15a
+#define F0900_CLKOUT27_OPD 0xf15a0080
+#define F0900_CLKOUT27_CONFIG 0xf15a007e
+#define F0900_CLKOUT27_XOR 0xf15a0001
+
+/*ERROR1CFG*/
+#define R0900_ERROR1CFG 0xf15b
+#define F0900_ERROR1_OPD 0xf15b0080
+#define F0900_ERROR1_CONFIG 0xf15b007e
+#define F0900_ERROR1_XOR 0xf15b0001
+
+/*DPN1CFG*/
+#define R0900_DPN1CFG 0xf15c
+#define F0900_DPN1_OPD 0xf15c0080
+#define F0900_DPN1_CONFIG 0xf15c007e
+#define F0900_DPN1_XOR 0xf15c0001
+
+/*STROUT1CFG*/
+#define R0900_STROUT1CFG 0xf15d
+#define F0900_STROUT1_OPD 0xf15d0080
+#define F0900_STROUT1_CONFIG 0xf15d007e
+#define F0900_STROUT1_XOR 0xf15d0001
+
+/*CLKOUT1CFG*/
+#define R0900_CLKOUT1CFG 0xf15e
+#define F0900_CLKOUT1_OPD 0xf15e0080
+#define F0900_CLKOUT1_CONFIG 0xf15e007e
+#define F0900_CLKOUT1_XOR 0xf15e0001
+
+/*DATA71CFG*/
+#define R0900_DATA71CFG 0xf15f
+#define F0900_DATA71_OPD 0xf15f0080
+#define F0900_DATA71_CONFIG 0xf15f007e
+#define F0900_DATA71_XOR 0xf15f0001
+
+/*ERROR2CFG*/
+#define R0900_ERROR2CFG 0xf160
+#define F0900_ERROR2_OPD 0xf1600080
+#define F0900_ERROR2_CONFIG 0xf160007e
+#define F0900_ERROR2_XOR 0xf1600001
+
+/*DPN2CFG*/
+#define R0900_DPN2CFG 0xf161
+#define F0900_DPN2_OPD 0xf1610080
+#define F0900_DPN2_CONFIG 0xf161007e
+#define F0900_DPN2_XOR 0xf1610001
+
+/*STROUT2CFG*/
+#define R0900_STROUT2CFG 0xf162
+#define F0900_STROUT2_OPD 0xf1620080
+#define F0900_STROUT2_CONFIG 0xf162007e
+#define F0900_STROUT2_XOR 0xf1620001
+
+/*CLKOUT2CFG*/
+#define R0900_CLKOUT2CFG 0xf163
+#define F0900_CLKOUT2_OPD 0xf1630080
+#define F0900_CLKOUT2_CONFIG 0xf163007e
+#define F0900_CLKOUT2_XOR 0xf1630001
+
+/*DATA72CFG*/
+#define R0900_DATA72CFG 0xf164
+#define F0900_DATA72_OPD 0xf1640080
+#define F0900_DATA72_CONFIG 0xf164007e
+#define F0900_DATA72_XOR 0xf1640001
+
+/*ERROR3CFG*/
+#define R0900_ERROR3CFG 0xf165
+#define F0900_ERROR3_OPD 0xf1650080
+#define F0900_ERROR3_CONFIG 0xf165007e
+#define F0900_ERROR3_XOR 0xf1650001
+
+/*DPN3CFG*/
+#define R0900_DPN3CFG 0xf166
+#define F0900_DPN3_OPD 0xf1660080
+#define F0900_DPN3_CONFIG 0xf166007e
+#define F0900_DPN3_XOR 0xf1660001
+
+/*STROUT3CFG*/
+#define R0900_STROUT3CFG 0xf167
+#define F0900_STROUT3_OPD 0xf1670080
+#define F0900_STROUT3_CONFIG 0xf167007e
+#define F0900_STROUT3_XOR 0xf1670001
+
+/*CLKOUT3CFG*/
+#define R0900_CLKOUT3CFG 0xf168
+#define F0900_CLKOUT3_OPD 0xf1680080
+#define F0900_CLKOUT3_CONFIG 0xf168007e
+#define F0900_CLKOUT3_XOR 0xf1680001
+
+/*DATA73CFG*/
+#define R0900_DATA73CFG 0xf169
+#define F0900_DATA73_OPD 0xf1690080
+#define F0900_DATA73_CONFIG 0xf169007e
+#define F0900_DATA73_XOR 0xf1690001
+
+/*FSKTFC2*/
+#define R0900_FSKTFC2 0xf170
+#define F0900_FSKT_KMOD 0xf17000fc
+#define F0900_FSKT_CAR2 0xf1700003
+
+/*FSKTFC1*/
+#define R0900_FSKTFC1 0xf171
+#define F0900_FSKT_CAR1 0xf17100ff
+
+/*FSKTFC0*/
+#define R0900_FSKTFC0 0xf172
+#define F0900_FSKT_CAR0 0xf17200ff
+
+/*FSKTDELTAF1*/
+#define R0900_FSKTDELTAF1 0xf173
+#define F0900_FSKT_DELTAF1 0xf173000f
+
+/*FSKTDELTAF0*/
+#define R0900_FSKTDELTAF0 0xf174
+#define F0900_FSKT_DELTAF0 0xf17400ff
+
+/*FSKTCTRL*/
+#define R0900_FSKTCTRL 0xf175
+#define F0900_FSKT_EN_SGN 0xf1750040
+#define F0900_FSKT_MOD_SGN 0xf1750020
+#define F0900_FSKT_MOD_EN 0xf175001c
+#define F0900_FSKT_DACMODE 0xf1750003
+
+/*FSKRFC2*/
+#define R0900_FSKRFC2 0xf176
+#define F0900_FSKR_DETSGN 0xf1760040
+#define F0900_FSKR_OUTSGN 0xf1760020
+#define F0900_FSKR_KAGC 0xf176001c
+#define F0900_FSKR_CAR2 0xf1760003
+
+/*FSKRFC1*/
+#define R0900_FSKRFC1 0xf177
+#define F0900_FSKR_CAR1 0xf17700ff
+
+/*FSKRFC0*/
+#define R0900_FSKRFC0 0xf178
+#define F0900_FSKR_CAR0 0xf17800ff
+
+/*FSKRK1*/
+#define R0900_FSKRK1 0xf179
+#define F0900_FSKR_K1_EXP 0xf17900e0
+#define F0900_FSKR_K1_MANT 0xf179001f
+
+/*FSKRK2*/
+#define R0900_FSKRK2 0xf17a
+#define F0900_FSKR_K2_EXP 0xf17a00e0
+#define F0900_FSKR_K2_MANT 0xf17a001f
+
+/*FSKRAGCR*/
+#define R0900_FSKRAGCR 0xf17b
+#define F0900_FSKR_OUTCTL 0xf17b00c0
+#define F0900_FSKR_AGC_REF 0xf17b003f
+
+/*FSKRAGC*/
+#define R0900_FSKRAGC 0xf17c
+#define F0900_FSKR_AGC_ACCU 0xf17c00ff
+
+/*FSKRALPHA*/
+#define R0900_FSKRALPHA 0xf17d
+#define F0900_FSKR_ALPHA_EXP 0xf17d001c
+#define F0900_FSKR_ALPHA_M 0xf17d0003
+
+/*FSKRPLTH1*/
+#define R0900_FSKRPLTH1 0xf17e
+#define F0900_FSKR_BETA 0xf17e00f0
+#define F0900_FSKR_PLL_TRESH1 0xf17e000f
+
+/*FSKRPLTH0*/
+#define R0900_FSKRPLTH0 0xf17f
+#define F0900_FSKR_PLL_TRESH0 0xf17f00ff
+
+/*FSKRDF1*/
+#define R0900_FSKRDF1 0xf180
+#define F0900_FSKR_OUT 0xf1800080
+#define F0900_FSKR_DELTAF1 0xf180001f
+
+/*FSKRDF0*/
+#define R0900_FSKRDF0 0xf181
+#define F0900_FSKR_DELTAF0 0xf18100ff
+
+/*FSKRSTEPP*/
+#define R0900_FSKRSTEPP 0xf182
+#define F0900_FSKR_STEP_PLUS 0xf18200ff
+
+/*FSKRSTEPM*/
+#define R0900_FSKRSTEPM 0xf183
+#define F0900_FSKR_STEP_MINUS 0xf18300ff
+
+/*FSKRDET1*/
+#define R0900_FSKRDET1 0xf184
+#define F0900_FSKR_DETECT 0xf1840080
+#define F0900_FSKR_CARDET_ACCU1 0xf184000f
+
+/*FSKRDET0*/
+#define R0900_FSKRDET0 0xf185
+#define F0900_FSKR_CARDET_ACCU0 0xf18500ff
+
+/*FSKRDTH1*/
+#define R0900_FSKRDTH1 0xf186
+#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0
+#define F0900_FSKR_CARDET_THRESH1 0xf186000f
+
+/*FSKRDTH0*/
+#define R0900_FSKRDTH0 0xf187
+#define F0900_FSKR_CARDET_THRESH0 0xf18700ff
+
+/*FSKRLOSS*/
+#define R0900_FSKRLOSS 0xf188
+#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff
+
+/*P2_DISTXCTL*/
+#define R0900_P2_DISTXCTL 0xf190
+#define F0900_P2_TIM_OFF 0xf1900080
+#define F0900_P2_DISEQC_RESET 0xf1900040
+#define F0900_P2_TIM_CMD 0xf1900030
+#define F0900_P2_DIS_PRECHARGE 0xf1900008
+#define F0900_P2_DISTX_MODE 0xf1900007
+
+/*P2_DISRXCTL*/
+#define R0900_P2_DISRXCTL 0xf191
+#define F0900_P2_RECEIVER_ON 0xf1910080
+#define F0900_P2_IGNO_SHORT22K 0xf1910040
+#define F0900_P2_ONECHIP_TRX 0xf1910020
+#define F0900_P2_EXT_ENVELOP 0xf1910010
+#define F0900_P2_PIN_SELECT 0xf191000c
+#define F0900_P2_IRQ_RXEND 0xf1910002
+#define F0900_P2_IRQ_4NBYTES 0xf1910001
+
+/*P2_DISRX_ST0*/
+#define R0900_P2_DISRX_ST0 0xf194
+#define F0900_P2_RX_END 0xf1940080
+#define F0900_P2_RX_ACTIVE 0xf1940040
+#define F0900_P2_SHORT_22KHZ 0xf1940020
+#define F0900_P2_CONT_TONE 0xf1940010
+#define F0900_P2_FIFO_4BREADY 0xf1940008
+#define F0900_P2_FIFO_EMPTY 0xf1940004
+#define F0900_P2_ABORT_DISRX 0xf1940001
+
+/*P2_DISRX_ST1*/
+#define R0900_P2_DISRX_ST1 0xf195
+#define F0900_P2_RX_FAIL 0xf1950080
+#define F0900_P2_FIFO_PARITYFAIL 0xf1950040
+#define F0900_P2_RX_NONBYTE 0xf1950020
+#define F0900_P2_FIFO_OVERFLOW 0xf1950010
+#define F0900_P2_FIFO_BYTENBR 0xf195000f
+
+/*P2_DISRXDATA*/
+#define R0900_P2_DISRXDATA 0xf196
+#define F0900_P2_DISRX_DATA 0xf19600ff
+
+/*P2_DISTXDATA*/
+#define R0900_P2_DISTXDATA 0xf197
+#define F0900_P2_DISEQC_FIFO 0xf19700ff
+
+/*P2_DISTXSTATUS*/
+#define R0900_P2_DISTXSTATUS 0xf198
+#define F0900_P2_TX_FAIL 0xf1980080
+#define F0900_P2_FIFO_FULL 0xf1980040
+#define F0900_P2_TX_IDLE 0xf1980020
+#define F0900_P2_GAP_BURST 0xf1980010
+#define F0900_P2_TXFIFO_BYTES 0xf198000f
+
+/*P2_F22TX*/
+#define R0900_P2_F22TX 0xf199
+#define F0900_P2_F22_REG 0xf19900ff
+
+/*P2_F22RX*/
+#define R0900_P2_F22RX 0xf19a
+#define F0900_P2_F22RX_REG 0xf19a00ff
+
+/*P2_ACRPRESC*/
+#define R0900_P2_ACRPRESC 0xf19c
+#define F0900_P2_ACR_CODFRDY 0xf19c0008
+#define F0900_P2_ACR_PRESC 0xf19c0007
+
+/*P2_ACRDIV*/
+#define R0900_P2_ACRDIV 0xf19d
+#define F0900_P2_ACR_DIV 0xf19d00ff
+
+/*P1_DISTXCTL*/
+#define R0900_P1_DISTXCTL 0xf1a0
+#define F0900_P1_TIM_OFF 0xf1a00080
+#define F0900_P1_DISEQC_RESET 0xf1a00040
+#define F0900_P1_TIM_CMD 0xf1a00030
+#define F0900_P1_DIS_PRECHARGE 0xf1a00008
+#define F0900_P1_DISTX_MODE 0xf1a00007
+
+/*P1_DISRXCTL*/
+#define R0900_P1_DISRXCTL 0xf1a1
+#define F0900_P1_RECEIVER_ON 0xf1a10080
+#define F0900_P1_IGNO_SHORT22K 0xf1a10040
+#define F0900_P1_ONECHIP_TRX 0xf1a10020
+#define F0900_P1_EXT_ENVELOP 0xf1a10010
+#define F0900_P1_PIN_SELECT 0xf1a1000c
+#define F0900_P1_IRQ_RXEND 0xf1a10002
+#define F0900_P1_IRQ_4NBYTES 0xf1a10001
+
+/*P1_DISRX_ST0*/
+#define R0900_P1_DISRX_ST0 0xf1a4
+#define F0900_P1_RX_END 0xf1a40080
+#define F0900_P1_RX_ACTIVE 0xf1a40040
+#define F0900_P1_SHORT_22KHZ 0xf1a40020
+#define F0900_P1_CONT_TONE 0xf1a40010
+#define F0900_P1_FIFO_4BREADY 0xf1a40008
+#define F0900_P1_FIFO_EMPTY 0xf1a40004
+#define F0900_P1_ABORT_DISRX 0xf1a40001
+
+/*P1_DISRX_ST1*/
+#define R0900_P1_DISRX_ST1 0xf1a5
+#define F0900_P1_RX_FAIL 0xf1a50080
+#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040
+#define F0900_P1_RX_NONBYTE 0xf1a50020
+#define F0900_P1_FIFO_OVERFLOW 0xf1a50010
+#define F0900_P1_FIFO_BYTENBR 0xf1a5000f
+
+/*P1_DISRXDATA*/
+#define R0900_P1_DISRXDATA 0xf1a6
+#define F0900_P1_DISRX_DATA 0xf1a600ff
+
+/*P1_DISTXDATA*/
+#define R0900_P1_DISTXDATA 0xf1a7
+#define F0900_P1_DISEQC_FIFO 0xf1a700ff
+
+/*P1_DISTXSTATUS*/
+#define R0900_P1_DISTXSTATUS 0xf1a8
+#define F0900_P1_TX_FAIL 0xf1a80080
+#define F0900_P1_FIFO_FULL 0xf1a80040
+#define F0900_P1_TX_IDLE 0xf1a80020
+#define F0900_P1_GAP_BURST 0xf1a80010
+#define F0900_P1_TXFIFO_BYTES 0xf1a8000f
+
+/*P1_F22TX*/
+#define R0900_P1_F22TX 0xf1a9
+#define F0900_P1_F22_REG 0xf1a900ff
+
+/*P1_F22RX*/
+#define R0900_P1_F22RX 0xf1aa
+#define F0900_P1_F22RX_REG 0xf1aa00ff
+
+/*P1_ACRPRESC*/
+#define R0900_P1_ACRPRESC 0xf1ac
+#define F0900_P1_ACR_CODFRDY 0xf1ac0008
+#define F0900_P1_ACR_PRESC 0xf1ac0007
+
+/*P1_ACRDIV*/
+#define R0900_P1_ACRDIV 0xf1ad
+#define F0900_P1_ACR_DIV 0xf1ad00ff
+
+/*NCOARSE*/
+#define R0900_NCOARSE 0xf1b3
+#define F0900_M_DIV 0xf1b300ff
+
+/*SYNTCTRL*/
+#define R0900_SYNTCTRL 0xf1b6
+#define F0900_STANDBY 0xf1b60080
+#define F0900_BYPASSPLLCORE 0xf1b60040
+#define F0900_SELX1RATIO 0xf1b60020
+#define F0900_I2C_TUD 0xf1b60010
+#define F0900_STOP_PLL 0xf1b60008
+#define F0900_BYPASSPLLFSK 0xf1b60004
+#define F0900_SELOSCI 0xf1b60002
+#define F0900_BYPASSPLLADC 0xf1b60001
+
+/*FILTCTRL*/
+#define R0900_FILTCTRL 0xf1b7
+#define F0900_INV_CLK135 0xf1b70080
+#define F0900_PERM_BYPDIS 0xf1b70040
+#define F0900_SEL_FSKCKDIV 0xf1b70004
+#define F0900_INV_CLKFSK 0xf1b70002
+#define F0900_BYPASS_APPLI 0xf1b70001
+
+/*PLLSTAT*/
+#define R0900_PLLSTAT 0xf1b8
+#define F0900_ACM_SEL 0xf1b80080
+#define F0900_DTV_SEL 0xf1b80040
+#define F0900_PLLLOCK 0xf1b80001
+
+/*STOPCLK1*/
+#define R0900_STOPCLK1 0xf1c2
+#define F0900_STOP_CLKPKDT2 0xf1c20040
+#define F0900_STOP_CLKPKDT1 0xf1c20020
+#define F0900_STOP_CLKFEC 0xf1c20010
+#define F0900_STOP_CLKADCI2 0xf1c20008
+#define F0900_INV_CLKADCI2 0xf1c20004
+#define F0900_STOP_CLKADCI1 0xf1c20002
+#define F0900_INV_CLKADCI1 0xf1c20001
+
+/*STOPCLK2*/
+#define R0900_STOPCLK2 0xf1c3
+#define F0900_STOP_CLKSAMP2 0xf1c30010
+#define F0900_STOP_CLKSAMP1 0xf1c30008
+#define F0900_STOP_CLKVIT2 0xf1c30004
+#define F0900_STOP_CLKVIT1 0xf1c30002
+#define F0900_STOP_CLKTS 0xf1c30001
+
+/*TSTTNR0*/
+#define R0900_TSTTNR0 0xf1df
+#define F0900_SEL_FSK 0xf1df0080
+#define F0900_FSK_PON 0xf1df0004
+#define F0900_FSK_OPENLOOP 0xf1df0002
+
+/*TSTTNR1*/
+#define R0900_TSTTNR1 0xf1e0
+#define F0900_BYPASS_ADC1 0xf1e00080
+#define F0900_INVADC1_CKOUT 0xf1e00040
+#define F0900_SELIQSRC1 0xf1e00030
+#define F0900_ADC1_PON 0xf1e00002
+#define F0900_ADC1_INMODE 0xf1e00001
+
+/*TSTTNR2*/
+#define R0900_TSTTNR2 0xf1e1
+#define F0900_DISEQC1_PON 0xf1e10020
+#define F0900_DISEQC1_TEST 0xf1e1001f
+
+/*TSTTNR3*/
+#define R0900_TSTTNR3 0xf1e2
+#define F0900_BYPASS_ADC2 0xf1e20080
+#define F0900_INVADC2_CKOUT 0xf1e20040
+#define F0900_SELIQSRC2 0xf1e20030
+#define F0900_ADC2_PON 0xf1e20002
+#define F0900_ADC2_INMODE 0xf1e20001
+
+/*TSTTNR4*/
+#define R0900_TSTTNR4 0xf1e3
+#define F0900_DISEQC2_PON 0xf1e30020
+#define F0900_DISEQC2_TEST 0xf1e3001f
+
+/*P2_IQCONST*/
+#define R0900_P2_IQCONST 0xf200
+#define F0900_P2_CONSTEL_SELECT 0xf2000060
+#define F0900_P2_IQSYMB_SEL 0xf200001f
+
+/*P2_NOSCFG*/
+#define R0900_P2_NOSCFG 0xf201
+#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020
+#define F0900_P2_NOSPLH_BETA 0xf2010018
+#define F0900_P2_NOSDATA_BETA 0xf2010007
+
+/*P2_ISYMB*/
+#define R0900_P2_ISYMB 0xf202
+#define F0900_P2_I_SYMBOL 0xf20201ff
+
+/*P2_QSYMB*/
+#define R0900_P2_QSYMB 0xf203
+#define F0900_P2_Q_SYMBOL 0xf20301ff
+
+/*P2_AGC1CFG*/
+#define R0900_P2_AGC1CFG 0xf204
+#define F0900_P2_DC_FROZEN 0xf2040080
+#define F0900_P2_DC_CORRECT 0xf2040040
+#define F0900_P2_AMM_FROZEN 0xf2040020
+#define F0900_P2_AMM_CORRECT 0xf2040010
+#define F0900_P2_QUAD_FROZEN 0xf2040008
+#define F0900_P2_QUAD_CORRECT 0xf2040004
+#define F0900_P2_DCCOMP_SLOW 0xf2040002
+#define F0900_P2_IQMISM_SLOW 0xf2040001
+
+/*P2_AGC1CN*/
+#define R0900_P2_AGC1CN 0xf206
+#define F0900_P2_AGC1_LOCKED 0xf2060080
+#define F0900_P2_AGC1_OVERFLOW 0xf2060040
+#define F0900_P2_AGC1_NOSLOWLK 0xf2060020
+#define F0900_P2_AGC1_MINPOWER 0xf2060010
+#define F0900_P2_AGCOUT_FAST 0xf2060008
+#define F0900_P2_AGCIQ_BETA 0xf2060007
+
+/*P2_AGC1REF*/
+#define R0900_P2_AGC1REF 0xf207
+#define F0900_P2_AGCIQ_REF 0xf20700ff
+
+/*P2_IDCCOMP*/
+#define R0900_P2_IDCCOMP 0xf208
+#define F0900_P2_IAVERAGE_ADJ 0xf20801ff
+
+/*P2_QDCCOMP*/
+#define R0900_P2_QDCCOMP 0xf209
+#define F0900_P2_QAVERAGE_ADJ 0xf20901ff
+
+/*P2_POWERI*/
+#define R0900_P2_POWERI 0xf20a
+#define F0900_P2_POWER_I 0xf20a00ff
+
+/*P2_POWERQ*/
+#define R0900_P2_POWERQ 0xf20b
+#define F0900_P2_POWER_Q 0xf20b00ff
+
+/*P2_AGC1AMM*/
+#define R0900_P2_AGC1AMM 0xf20c
+#define F0900_P2_AMM_VALUE 0xf20c00ff
+
+/*P2_AGC1QUAD*/
+#define R0900_P2_AGC1QUAD 0xf20d
+#define F0900_P2_QUAD_VALUE 0xf20d01ff
+
+/*P2_AGCIQIN1*/
+#define R0900_P2_AGCIQIN1 0xf20e
+#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff
+
+/*P2_AGCIQIN0*/
+#define R0900_P2_AGCIQIN0 0xf20f
+#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff
+
+/*P2_DEMOD*/
+#define R0900_P2_DEMOD 0xf210
+#define F0900_P2_DEMOD_STOP 0xf2100040
+#define F0900_P2_SPECINV_CONTROL 0xf2100030
+#define F0900_P2_FORCE_ENASAMP 0xf2100008
+#define F0900_P2_MANUAL_ROLLOFF 0xf2100004
+#define F0900_P2_ROLLOFF_CONTROL 0xf2100003
+
+/*P2_DMDMODCOD*/
+#define R0900_P2_DMDMODCOD 0xf211
+#define F0900_P2_MANUAL_MODCOD 0xf2110080
+#define F0900_P2_DEMOD_MODCOD 0xf211007c
+#define F0900_P2_DEMOD_TYPE 0xf2110003
+
+/*P2_DSTATUS*/
+#define R0900_P2_DSTATUS 0xf212
+#define F0900_P2_CAR_LOCK 0xf2120080
+#define F0900_P2_TMGLOCK_QUALITY 0xf2120060
+#define F0900_P2_SDVBS1_ENABLE 0xf2120010
+#define F0900_P2_LOCK_DEFINITIF 0xf2120008
+#define F0900_P2_TIMING_IS_LOCKED 0xf2120004
+#define F0900_P2_COARSE_TMGLOCK 0xf2120002
+#define F0900_P2_COARSE_CARLOCK 0xf2120001
+
+/*P2_DSTATUS2*/
+#define R0900_P2_DSTATUS2 0xf213
+#define F0900_P2_DEMOD_DELOCK 0xf2130080
+#define F0900_P2_DEMOD_TIMEOUT 0xf2130040
+#define F0900_P2_MODCODRQ_SYNCTAG 0xf2130020
+#define F0900_P2_POLYPH_SATEVENT 0xf2130010
+#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008
+#define F0900_P2_AGC2_OVERFLOW 0xf2130004
+#define F0900_P2_CFR_OVERFLOW 0xf2130002
+#define F0900_P2_GAMMA_OVERUNDER 0xf2130001
+
+/*P2_DMDCFGMD*/
+#define R0900_P2_DMDCFGMD 0xf214
+#define F0900_P2_DVBS2_ENABLE 0xf2140080
+#define F0900_P2_DVBS1_ENABLE 0xf2140040
+#define F0900_P2_CFR_AUTOSCAN 0xf2140020
+#define F0900_P2_SCAN_ENABLE 0xf2140010
+#define F0900_P2_TUN_AUTOSCAN 0xf2140008
+#define F0900_P2_NOFORCE_RELOCK 0xf2140004
+#define F0900_P2_TUN_RNG 0xf2140003
+
+/*P2_DMDCFG2*/
+#define R0900_P2_DMDCFG2 0xf215
+#define F0900_P2_AGC1_WAITLOCK 0xf2150080
+#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040
+#define F0900_P2_OVERFLOW_TIMEOUT 0xf2150020
+#define F0900_P2_SCANFAIL_TIMEOUT 0xf2150010
+#define F0900_P2_DMDTOUT_BACK 0xf2150008
+#define F0900_P2_CARLOCK_S1ENABLE 0xf2150004
+#define F0900_P2_COARSE_LK3MODE 0xf2150002
+#define F0900_P2_COARSE_LK2MODE 0xf2150001
+
+/*P2_DMDISTATE*/
+#define R0900_P2_DMDISTATE 0xf216
+#define F0900_P2_I2C_NORESETDMODE 0xf2160080
+#define F0900_P2_FORCE_ETAPED 0xf2160040
+#define F0900_P2_SDMDRST_DIRCLK 0xf2160020
+#define F0900_P2_I2C_DEMOD_MODE 0xf216001f
+
+/*P2_DMDT0M*/
+#define R0900_P2_DMDT0M 0xf217
+#define F0900_P2_DMDT0_MIN 0xf21700ff
+
+/*P2_DMDSTATE*/
+#define R0900_P2_DMDSTATE 0xf21b
+#define F0900_P2_DEMOD_LOCKED 0xf21b0080
+#define F0900_P2_HEADER_MODE 0xf21b0060
+#define F0900_P2_DEMOD_MODE 0xf21b001f
+
+/*P2_DMDFLYW*/
+#define R0900_P2_DMDFLYW 0xf21c
+#define F0900_P2_I2C_IRQVAL 0xf21c00f0
+#define F0900_P2_FLYWHEEL_CPT 0xf21c000f
+
+/*P2_DSTATUS3*/
+#define R0900_P2_DSTATUS3 0xf21d
+#define F0900_P2_CFR_ZIGZAG 0xf21d0080
+#define F0900_P2_DEMOD_CFGMODE 0xf21d0060
+#define F0900_P2_GAMMA_LOWBAUDRATE 0xf21d0010
+#define F0900_P2_RELOCK_MODE 0xf21d0008
+#define F0900_P2_DEMOD_FAIL 0xf21d0004
+#define F0900_P2_ETAPE1A_DVBXMEM 0xf21d0003
+
+/*P2_DMDCFG3*/
+#define R0900_P2_DMDCFG3 0xf21e
+#define F0900_P2_DVBS1_TMGWAIT 0xf21e0080
+#define F0900_P2_NO_BWCENTERING 0xf21e0040
+#define F0900_P2_INV_SEQSRCH 0xf21e0020
+#define F0900_P2_DIS_SFRUPLOW_TRK 0xf21e0010
+#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008
+#define F0900_P2_LOCKTIME_MODE 0xf21e0007
+
+/*P2_DMDCFG4*/
+#define R0900_P2_DMDCFG4 0xf21f
+#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008
+#define F0900_P2_DIS_CLKENABLE 0xf21f0004
+#define F0900_P2_DIS_HDRDIVLOCK 0xf21f0002
+#define F0900_P2_NO_TNRWBINIT 0xf21f0001
+
+/*P2_CORRELMANT*/
+#define R0900_P2_CORRELMANT 0xf220
+#define F0900_P2_CORREL_MANT 0xf22000ff
+
+/*P2_CORRELABS*/
+#define R0900_P2_CORRELABS 0xf221
+#define F0900_P2_CORREL_ABS 0xf22100ff
+
+/*P2_CORRELEXP*/
+#define R0900_P2_CORRELEXP 0xf222
+#define F0900_P2_CORREL_ABSEXP 0xf22200f0
+#define F0900_P2_CORREL_EXP 0xf222000f
+
+/*P2_PLHMODCOD*/
+#define R0900_P2_PLHMODCOD 0xf224
+#define F0900_P2_SPECINV_DEMOD 0xf2240080
+#define F0900_P2_PLH_MODCOD 0xf224007c
+#define F0900_P2_PLH_TYPE 0xf2240003
+
+/*P2_AGCK32*/
+#define R0900_P2_AGCK32 0xf22b
+#define F0900_P2_R3ADJOFF_32APSK 0xf22b0080
+#define F0900_P2_R2ADJOFF_32APSK 0xf22b0040
+#define F0900_P2_R1ADJOFF_32APSK 0xf22b0020
+#define F0900_P2_RADJ_32APSK 0xf22b001f
+
+/*P2_AGC2O*/
+#define R0900_P2_AGC2O 0xf22c
+#define F0900_P2_AGC2REF_ADJUSTING 0xf22c0080
+#define F0900_P2_AGC2_COARSEFAST 0xf22c0040
+#define F0900_P2_AGC2_LKSQRT 0xf22c0020
+#define F0900_P2_AGC2_LKMODE 0xf22c0010
+#define F0900_P2_AGC2_LKEQUA 0xf22c0008
+#define F0900_P2_AGC2_COEF 0xf22c0007
+
+/*P2_AGC2REF*/
+#define R0900_P2_AGC2REF 0xf22d
+#define F0900_P2_AGC2_REF 0xf22d00ff
+
+/*P2_AGC1ADJ*/
+#define R0900_P2_AGC1ADJ 0xf22e
+#define F0900_P2_AGC1ADJ_MANUAL 0xf22e0080
+#define F0900_P2_AGC1_ADJUSTED 0xf22e017f
+
+/*P2_AGC2I1*/
+#define R0900_P2_AGC2I1 0xf236
+#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff
+
+/*P2_AGC2I0*/
+#define R0900_P2_AGC2I0 0xf237
+#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff
+
+/*P2_CARCFG*/
+#define R0900_P2_CARCFG 0xf238
+#define F0900_P2_CFRUPLOW_AUTO 0xf2380080
+#define F0900_P2_CFRUPLOW_TEST 0xf2380040
+#define F0900_P2_EN_CAR2CENTER 0xf2380020
+#define F0900_P2_CARHDR_NODIV8 0xf2380010
+#define F0900_P2_I2C_ROTA 0xf2380008
+#define F0900_P2_ROTAON 0xf2380004
+#define F0900_P2_PH_DET_ALGO 0xf2380003
+
+/*P2_ACLC*/
+#define R0900_P2_ACLC 0xf239
+#define F0900_P2_STOP_S2ALPHA 0xf23900c0
+#define F0900_P2_CAR_ALPHA_MANT 0xf2390030
+#define F0900_P2_CAR_ALPHA_EXP 0xf239000f
+
+/*P2_BCLC*/
+#define R0900_P2_BCLC 0xf23a
+#define F0900_P2_STOP_S2BETA 0xf23a00c0
+#define F0900_P2_CAR_BETA_MANT 0xf23a0030
+#define F0900_P2_CAR_BETA_EXP 0xf23a000f
+
+/*P2_CARFREQ*/
+#define R0900_P2_CARFREQ 0xf23d
+#define F0900_P2_KC_COARSE_EXP 0xf23d00f0
+#define F0900_P2_BETA_FREQ 0xf23d000f
+
+/*P2_CARHDR*/
+#define R0900_P2_CARHDR 0xf23e
+#define F0900_P2_K_FREQ_HDR 0xf23e00ff
+
+/*P2_LDT*/
+#define R0900_P2_LDT 0xf23f
+#define F0900_P2_CARLOCK_THRES 0xf23f01ff
+
+/*P2_LDT2*/
+#define R0900_P2_LDT2 0xf240
+#define F0900_P2_CARLOCK_THRES2 0xf24001ff
+
+/*P2_CFRICFG*/
+#define R0900_P2_CFRICFG 0xf241
+#define F0900_P2_CFRINIT_UNVALRNG 0xf2410080
+#define F0900_P2_CFRINIT_LUNVALCPT 0xf2410040
+#define F0900_P2_CFRINIT_ABORTDBL 0xf2410020
+#define F0900_P2_CFRINIT_ABORTPRED 0xf2410010
+#define F0900_P2_CFRINIT_UNVALSKIP 0xf2410008
+#define F0900_P2_CFRINIT_CSTINC 0xf2410004
+#define F0900_P2_NEG_CFRSTEP 0xf2410001
+
+/*P2_CFRUP1*/
+#define R0900_P2_CFRUP1 0xf242
+#define F0900_P2_CFR_UP1 0xf24201ff
+
+/*P2_CFRUP0*/
+#define R0900_P2_CFRUP0 0xf243
+#define F0900_P2_CFR_UP0 0xf24300ff
+
+/*P2_CFRLOW1*/
+#define R0900_P2_CFRLOW1 0xf246
+#define F0900_P2_CFR_LOW1 0xf24601ff
+
+/*P2_CFRLOW0*/
+#define R0900_P2_CFRLOW0 0xf247
+#define F0900_P2_CFR_LOW0 0xf24700ff
+
+/*P2_CFRINIT1*/
+#define R0900_P2_CFRINIT1 0xf248
+#define F0900_P2_CFR_INIT1 0xf24801ff
+
+/*P2_CFRINIT0*/
+#define R0900_P2_CFRINIT0 0xf249
+#define F0900_P2_CFR_INIT0 0xf24900ff
+
+/*P2_CFRINC1*/
+#define R0900_P2_CFRINC1 0xf24a
+#define F0900_P2_MANUAL_CFRINC 0xf24a0080
+#define F0900_P2_CFR_INC1 0xf24a017f
+
+/*P2_CFRINC0*/
+#define R0900_P2_CFRINC0 0xf24b
+#define F0900_P2_CFR_INC0 0xf24b00f0
+
+/*P2_CFR2*/
+#define R0900_P2_CFR2 0xf24c
+#define F0900_P2_CAR_FREQ2 0xf24c01ff
+
+/*P2_CFR1*/
+#define R0900_P2_CFR1 0xf24d
+#define F0900_P2_CAR_FREQ1 0xf24d00ff
+
+/*P2_CFR0*/
+#define R0900_P2_CFR0 0xf24e
+#define F0900_P2_CAR_FREQ0 0xf24e00ff
+
+/*P2_LDI*/
+#define R0900_P2_LDI 0xf24f
+#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff
+
+/*P2_TMGCFG*/
+#define R0900_P2_TMGCFG 0xf250
+#define F0900_P2_TMGLOCK_BETA 0xf25000c0
+#define F0900_P2_NOTMG_GROUPDELAY 0xf2500020
+#define F0900_P2_DO_TIMING_CORR 0xf2500010
+#define F0900_P2_MANUAL_SCAN 0xf250000c
+#define F0900_P2_TMG_MINFREQ 0xf2500003
+
+/*P2_RTC*/
+#define R0900_P2_RTC 0xf251
+#define F0900_P2_TMGALPHA_EXP 0xf25100f0
+#define F0900_P2_TMGBETA_EXP 0xf251000f
+
+/*P2_RTCS2*/
+#define R0900_P2_RTCS2 0xf252
+#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0
+#define F0900_P2_TMGBETAS2_EXP 0xf252000f
+
+/*P2_TMGTHRISE*/
+#define R0900_P2_TMGTHRISE 0xf253
+#define F0900_P2_TMGLOCK_THRISE 0xf25300ff
+
+/*P2_TMGTHFALL*/
+#define R0900_P2_TMGTHFALL 0xf254
+#define F0900_P2_TMGLOCK_THFALL 0xf25400ff
+
+/*P2_SFRUPRATIO*/
+#define R0900_P2_SFRUPRATIO 0xf255
+#define F0900_P2_SFR_UPRATIO 0xf25500ff
+
+/*P2_SFRLOWRATIO*/
+#define R0900_P2_SFRLOWRATIO 0xf256
+#define F0900_P2_SFR_LOWRATIO 0xf25600ff
+
+/*P2_KREFTMG*/
+#define R0900_P2_KREFTMG 0xf258
+#define F0900_P2_KREF_TMG 0xf25800ff
+
+/*P2_SFRSTEP*/
+#define R0900_P2_SFRSTEP 0xf259
+#define F0900_P2_SFR_SCANSTEP 0xf25900f0
+#define F0900_P2_SFR_CENTERSTEP 0xf259000f
+
+/*P2_TMGCFG2*/
+#define R0900_P2_TMGCFG2 0xf25a
+#define F0900_P2_DIS_AUTOSAMP 0xf25a0008
+#define F0900_P2_SCANINIT_QUART 0xf25a0004
+#define F0900_P2_NOTMG_DVBS1DERAT 0xf25a0002
+#define F0900_P2_SFRRATIO_FINE 0xf25a0001
+
+/*P2_SFRINIT1*/
+#define R0900_P2_SFRINIT1 0xf25e
+#define F0900_P2_SFR_INIT1 0xf25e00ff
+
+/*P2_SFRINIT0*/
+#define R0900_P2_SFRINIT0 0xf25f
+#define F0900_P2_SFR_INIT0 0xf25f00ff
+
+/*P2_SFRUP1*/
+#define R0900_P2_SFRUP1 0xf260
+#define F0900_P2_AUTO_GUP 0xf2600080
+#define F0900_P2_SYMB_FREQ_UP1 0xf260007f
+
+/*P2_SFRUP0*/
+#define R0900_P2_SFRUP0 0xf261
+#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff
+
+/*P2_SFRLOW1*/
+#define R0900_P2_SFRLOW1 0xf262
+#define F0900_P2_AUTO_GLOW 0xf2620080
+#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f
+
+/*P2_SFRLOW0*/
+#define R0900_P2_SFRLOW0 0xf263
+#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff
+
+/*P2_SFR3*/
+#define R0900_P2_SFR3 0xf264
+#define F0900_P2_SYMB_FREQ3 0xf26400ff
+
+/*P2_SFR2*/
+#define R0900_P2_SFR2 0xf265
+#define F0900_P2_SYMB_FREQ2 0xf26500ff
+
+/*P2_SFR1*/
+#define R0900_P2_SFR1 0xf266
+#define F0900_P2_SYMB_FREQ1 0xf26600ff
+
+/*P2_SFR0*/
+#define R0900_P2_SFR0 0xf267
+#define F0900_P2_SYMB_FREQ0 0xf26700ff
+
+/*P2_TMGREG2*/
+#define R0900_P2_TMGREG2 0xf268
+#define F0900_P2_TMGREG2 0xf26800ff
+
+/*P2_TMGREG1*/
+#define R0900_P2_TMGREG1 0xf269
+#define F0900_P2_TMGREG1 0xf26900ff
+
+/*P2_TMGREG0*/
+#define R0900_P2_TMGREG0 0xf26a
+#define F0900_P2_TMGREG0 0xf26a00ff
+
+/*P2_TMGLOCK1*/
+#define R0900_P2_TMGLOCK1 0xf26b
+#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff
+
+/*P2_TMGLOCK0*/
+#define R0900_P2_TMGLOCK0 0xf26c
+#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff
+
+/*P2_TMGOBS*/
+#define R0900_P2_TMGOBS 0xf26d
+#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0
+#define F0900_P2_SCAN_SIGN 0xf26d0030
+#define F0900_P2_TMG_SCANNING 0xf26d0008
+#define F0900_P2_CHCENTERING_MODE 0xf26d0004
+#define F0900_P2_TMG_SCANFAIL 0xf26d0002
+
+/*P2_EQUALCFG*/
+#define R0900_P2_EQUALCFG 0xf26f
+#define F0900_P2_NOTMG_NEGALWAIT 0xf26f0080
+#define F0900_P2_EQUAL_ON 0xf26f0040
+#define F0900_P2_SEL_EQUALCOR 0xf26f0038
+#define F0900_P2_MU_EQUALDFE 0xf26f0007
+
+/*P2_EQUAI1*/
+#define R0900_P2_EQUAI1 0xf270
+#define F0900_P2_EQUA_ACCI1 0xf27001ff
+
+/*P2_EQUAQ1*/
+#define R0900_P2_EQUAQ1 0xf271
+#define F0900_P2_EQUA_ACCQ1 0xf27101ff
+
+/*P2_EQUAI2*/
+#define R0900_P2_EQUAI2 0xf272
+#define F0900_P2_EQUA_ACCI2 0xf27201ff
+
+/*P2_EQUAQ2*/
+#define R0900_P2_EQUAQ2 0xf273
+#define F0900_P2_EQUA_ACCQ2 0xf27301ff
+
+/*P2_EQUAI3*/
+#define R0900_P2_EQUAI3 0xf274
+#define F0900_P2_EQUA_ACCI3 0xf27401ff
+
+/*P2_EQUAQ3*/
+#define R0900_P2_EQUAQ3 0xf275
+#define F0900_P2_EQUA_ACCQ3 0xf27501ff
+
+/*P2_EQUAI4*/
+#define R0900_P2_EQUAI4 0xf276
+#define F0900_P2_EQUA_ACCI4 0xf27601ff
+
+/*P2_EQUAQ4*/
+#define R0900_P2_EQUAQ4 0xf277
+#define F0900_P2_EQUA_ACCQ4 0xf27701ff
+
+/*P2_EQUAI5*/
+#define R0900_P2_EQUAI5 0xf278
+#define F0900_P2_EQUA_ACCI5 0xf27801ff
+
+/*P2_EQUAQ5*/
+#define R0900_P2_EQUAQ5 0xf279
+#define F0900_P2_EQUA_ACCQ5 0xf27901ff
+
+/*P2_EQUAI6*/
+#define R0900_P2_EQUAI6 0xf27a
+#define F0900_P2_EQUA_ACCI6 0xf27a01ff
+
+/*P2_EQUAQ6*/
+#define R0900_P2_EQUAQ6 0xf27b
+#define F0900_P2_EQUA_ACCQ6 0xf27b01ff
+
+/*P2_EQUAI7*/
+#define R0900_P2_EQUAI7 0xf27c
+#define F0900_P2_EQUA_ACCI7 0xf27c01ff
+
+/*P2_EQUAQ7*/
+#define R0900_P2_EQUAQ7 0xf27d
+#define F0900_P2_EQUA_ACCQ7 0xf27d01ff
+
+/*P2_EQUAI8*/
+#define R0900_P2_EQUAI8 0xf27e
+#define F0900_P2_EQUA_ACCI8 0xf27e01ff
+
+/*P2_EQUAQ8*/
+#define R0900_P2_EQUAQ8 0xf27f
+#define F0900_P2_EQUA_ACCQ8 0xf27f01ff
+
+/*P2_NNOSDATAT1*/
+#define R0900_P2_NNOSDATAT1 0xf280
+#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff
+
+/*P2_NNOSDATAT0*/
+#define R0900_P2_NNOSDATAT0 0xf281
+#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff
+
+/*P2_NNOSDATA1*/
+#define R0900_P2_NNOSDATA1 0xf282
+#define F0900_P2_NOSDATA_NORMED1 0xf28200ff
+
+/*P2_NNOSDATA0*/
+#define R0900_P2_NNOSDATA0 0xf283
+#define F0900_P2_NOSDATA_NORMED0 0xf28300ff
+
+/*P2_NNOSPLHT1*/
+#define R0900_P2_NNOSPLHT1 0xf284
+#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff
+
+/*P2_NNOSPLHT0*/
+#define R0900_P2_NNOSPLHT0 0xf285
+#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff
+
+/*P2_NNOSPLH1*/
+#define R0900_P2_NNOSPLH1 0xf286
+#define F0900_P2_NOSPLH_NORMED1 0xf28600ff
+
+/*P2_NNOSPLH0*/
+#define R0900_P2_NNOSPLH0 0xf287
+#define F0900_P2_NOSPLH_NORMED0 0xf28700ff
+
+/*P2_NOSDATAT1*/
+#define R0900_P2_NOSDATAT1 0xf288
+#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff
+
+/*P2_NOSDATAT0*/
+#define R0900_P2_NOSDATAT0 0xf289
+#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff
+
+/*P2_NOSDATA1*/
+#define R0900_P2_NOSDATA1 0xf28a
+#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff
+
+/*P2_NOSDATA0*/
+#define R0900_P2_NOSDATA0 0xf28b
+#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff
+
+/*P2_NOSPLHT1*/
+#define R0900_P2_NOSPLHT1 0xf28c
+#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff
+
+/*P2_NOSPLHT0*/
+#define R0900_P2_NOSPLHT0 0xf28d
+#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff
+
+/*P2_NOSPLH1*/
+#define R0900_P2_NOSPLH1 0xf28e
+#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff
+
+/*P2_NOSPLH0*/
+#define R0900_P2_NOSPLH0 0xf28f
+#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff
+
+/*P2_CAR2CFG*/
+#define R0900_P2_CAR2CFG 0xf290
+#define F0900_P2_DESCRAMB_OFF 0xf2900080
+#define F0900_P2_PN4_SELECT 0xf2900040
+#define F0900_P2_CFR2_STOPDVBS1 0xf2900020
+#define F0900_P2_STOP_CFR2UPDATE 0xf2900010
+#define F0900_P2_STOP_NCO2UPDATE 0xf2900008
+#define F0900_P2_ROTA2ON 0xf2900004
+#define F0900_P2_PH_DET_ALGO2 0xf2900003
+
+/*P2_ACLC2*/
+#define R0900_P2_ACLC2 0xf291
+#define F0900_P2_CAR2_PUNCT_ADERAT 0xf2910040
+#define F0900_P2_CAR2_ALPHA_MANT 0xf2910030
+#define F0900_P2_CAR2_ALPHA_EXP 0xf291000f
+
+/*P2_BCLC2*/
+#define R0900_P2_BCLC2 0xf292
+#define F0900_P2_DVBS2_NIP 0xf2920080
+#define F0900_P2_CAR2_PUNCT_BDERAT 0xf2920040
+#define F0900_P2_CAR2_BETA_MANT 0xf2920030
+#define F0900_P2_CAR2_BETA_EXP 0xf292000f
+
+/*P2_CFR22*/
+#define R0900_P2_CFR22 0xf293
+#define F0900_P2_CAR2_FREQ2 0xf29301ff
+
+/*P2_CFR21*/
+#define R0900_P2_CFR21 0xf294
+#define F0900_P2_CAR2_FREQ1 0xf29400ff
+
+/*P2_CFR20*/
+#define R0900_P2_CFR20 0xf295
+#define F0900_P2_CAR2_FREQ0 0xf29500ff
+
+/*P2_ACLC2S2Q*/
+#define R0900_P2_ACLC2S2Q 0xf297
+#define F0900_P2_ENAB_SPSKSYMB 0xf2970080
+#define F0900_P2_CAR2S2_QADERAT 0xf2970040
+#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030
+#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f
+
+/*P2_ACLC2S28*/
+#define R0900_P2_ACLC2S28 0xf298
+#define F0900_P2_OLDI3Q_MODE 0xf2980080
+#define F0900_P2_CAR2S2_8ADERAT 0xf2980040
+#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030
+#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f
+
+/*P2_ACLC2S216A*/
+#define R0900_P2_ACLC2S216A 0xf299
+#define F0900_P2_CAR2S2_16ADERAT 0xf2990040
+#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030
+#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f
+
+/*P2_ACLC2S232A*/
+#define R0900_P2_ACLC2S232A 0xf29a
+#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040
+#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030
+#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f
+
+/*P2_BCLC2S2Q*/
+#define R0900_P2_BCLC2S2Q 0xf29c
+#define F0900_P2_DVBS2S2Q_NIP 0xf29c0080
+#define F0900_P2_CAR2S2_QBDERAT 0xf29c0040
+#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030
+#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f
+
+/*P2_BCLC2S28*/
+#define R0900_P2_BCLC2S28 0xf29d
+#define F0900_P2_DVBS2S28_NIP 0xf29d0080
+#define F0900_P2_CAR2S2_8BDERAT 0xf29d0040
+#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030
+#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f
+
+/*P2_BCLC2S216A*/
+#define R0900_P2_BCLC2S216A 0xf29e
+#define F0900_P2_DVBS2S216A_NIP 0xf29e0080
+#define F0900_P2_CAR2S2_16BDERAT 0xf29e0040
+#define F0900_P2_CAR2S2_16A_BETA_M 0xf29e0030
+#define F0900_P2_CAR2S2_16A_BETA_E 0xf29e000f
+
+/*P2_BCLC2S232A*/
+#define R0900_P2_BCLC2S232A 0xf29f
+#define F0900_P2_DVBS2S232A_NIP 0xf29f0080
+#define F0900_P2_CAR2S2_32BDERAT 0xf29f0040
+#define F0900_P2_CAR2S2_32A_BETA_M 0xf29f0030
+#define F0900_P2_CAR2S2_32A_BETA_E 0xf29f000f
+
+/*P2_PLROOT2*/
+#define R0900_P2_PLROOT2 0xf2ac
+#define F0900_P2_SHORTFR_DISABLE 0xf2ac0080
+#define F0900_P2_LONGFR_DISABLE 0xf2ac0040
+#define F0900_P2_DUMMYPL_DISABLE 0xf2ac0020
+#define F0900_P2_SHORTFR_AVOID 0xf2ac0010
+#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c
+#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003
+
+/*P2_PLROOT1*/
+#define R0900_P2_PLROOT1 0xf2ad
+#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff
+
+/*P2_PLROOT0*/
+#define R0900_P2_PLROOT0 0xf2ae
+#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff
+
+/*P2_MODCODLST0*/
+#define R0900_P2_MODCODLST0 0xf2b0
+#define F0900_P2_EN_TOKEN31 0xf2b00080
+#define F0900_P2_SYNCTAG_SELECT 0xf2b00040
+#define F0900_P2_MODCODRQ_MODE 0xf2b00030
+
+/*P2_MODCODLST1*/
+#define R0900_P2_MODCODLST1 0xf2b1
+#define F0900_P2_DIS_MODCOD29 0xf2b100f0
+#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f
+
+/*P2_MODCODLST2*/
+#define R0900_P2_MODCODLST2 0xf2b2
+#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0
+#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f
+
+/*P2_MODCODLST3*/
+#define R0900_P2_MODCODLST3 0xf2b3
+#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0
+#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f
+
+/*P2_MODCODLST4*/
+#define R0900_P2_MODCODLST4 0xf2b4
+#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0
+#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f
+
+/*P2_MODCODLST5*/
+#define R0900_P2_MODCODLST5 0xf2b5
+#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0
+#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f
+
+/*P2_MODCODLST6*/
+#define R0900_P2_MODCODLST6 0xf2b6
+#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0
+#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f
+
+/*P2_MODCODLST7*/
+#define R0900_P2_MODCODLST7 0xf2b7
+#define F0900_P2_DIS_8P_9_10 0xf2b700f0
+#define F0900_P2_DIS_8P_8_9 0xf2b7000f
+
+/*P2_MODCODLST8*/
+#define R0900_P2_MODCODLST8 0xf2b8
+#define F0900_P2_DIS_8P_5_6 0xf2b800f0
+#define F0900_P2_DIS_8P_3_4 0xf2b8000f
+
+/*P2_MODCODLST9*/
+#define R0900_P2_MODCODLST9 0xf2b9
+#define F0900_P2_DIS_8P_2_3 0xf2b900f0
+#define F0900_P2_DIS_8P_3_5 0xf2b9000f
+
+/*P2_MODCODLSTA*/
+#define R0900_P2_MODCODLSTA 0xf2ba
+#define F0900_P2_DIS_QP_9_10 0xf2ba00f0
+#define F0900_P2_DIS_QP_8_9 0xf2ba000f
+
+/*P2_MODCODLSTB*/
+#define R0900_P2_MODCODLSTB 0xf2bb
+#define F0900_P2_DIS_QP_5_6 0xf2bb00f0
+#define F0900_P2_DIS_QP_4_5 0xf2bb000f
+
+/*P2_MODCODLSTC*/
+#define R0900_P2_MODCODLSTC 0xf2bc
+#define F0900_P2_DIS_QP_3_4 0xf2bc00f0
+#define F0900_P2_DIS_QP_2_3 0xf2bc000f
+
+/*P2_MODCODLSTD*/
+#define R0900_P2_MODCODLSTD 0xf2bd
+#define F0900_P2_DIS_QP_3_5 0xf2bd00f0
+#define F0900_P2_DIS_QP_1_2 0xf2bd000f
+
+/*P2_MODCODLSTE*/
+#define R0900_P2_MODCODLSTE 0xf2be
+#define F0900_P2_DIS_QP_2_5 0xf2be00f0
+#define F0900_P2_DIS_QP_1_3 0xf2be000f
+
+/*P2_MODCODLSTF*/
+#define R0900_P2_MODCODLSTF 0xf2bf
+#define F0900_P2_DIS_QP_1_4 0xf2bf00f0
+#define F0900_P2_DDEMOD_SET 0xf2bf0002
+#define F0900_P2_DDEMOD_MASK 0xf2bf0001
+
+/*P2_DMDRESCFG*/
+#define R0900_P2_DMDRESCFG 0xf2c6
+#define F0900_P2_DMDRES_RESET 0xf2c60080
+#define F0900_P2_DMDRES_NOISESQR 0xf2c60010
+#define F0900_P2_DMDRES_STRALL 0xf2c60008
+#define F0900_P2_DMDRES_NEWONLY 0xf2c60004
+#define F0900_P2_DMDRES_NOSTORE 0xf2c60002
+#define F0900_P2_DMDRES_AGC2MEM 0xf2c60001
+
+/*P2_DMDRESADR*/
+#define R0900_P2_DMDRESADR 0xf2c7
+#define F0900_P2_SUSP_PREDCANAL 0xf2c70080
+#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040
+#define F0900_P2_DMDRES_MEMFULL 0xf2c70030
+#define F0900_P2_DMDRES_RESNBR 0xf2c7000f
+
+/*P2_DMDRESDATA7*/
+#define R0900_P2_DMDRESDATA7 0xf2c8
+#define F0900_P2_DMDRES_DATA7 0xf2c800ff
+
+/*P2_DMDRESDATA6*/
+#define R0900_P2_DMDRESDATA6 0xf2c9
+#define F0900_P2_DMDRES_DATA6 0xf2c900ff
+
+/*P2_DMDRESDATA5*/
+#define R0900_P2_DMDRESDATA5 0xf2ca
+#define F0900_P2_DMDRES_DATA5 0xf2ca00ff
+
+/*P2_DMDRESDATA4*/
+#define R0900_P2_DMDRESDATA4 0xf2cb
+#define F0900_P2_DMDRES_DATA4 0xf2cb00ff
+
+/*P2_DMDRESDATA3*/
+#define R0900_P2_DMDRESDATA3 0xf2cc
+#define F0900_P2_DMDRES_DATA3 0xf2cc00ff
+
+/*P2_DMDRESDATA2*/
+#define R0900_P2_DMDRESDATA2 0xf2cd
+#define F0900_P2_DMDRES_DATA2 0xf2cd00ff
+
+/*P2_DMDRESDATA1*/
+#define R0900_P2_DMDRESDATA1 0xf2ce
+#define F0900_P2_DMDRES_DATA1 0xf2ce00ff
+
+/*P2_DMDRESDATA0*/
+#define R0900_P2_DMDRESDATA0 0xf2cf
+#define F0900_P2_DMDRES_DATA0 0xf2cf00ff
+
+/*P2_FFEI1*/
+#define R0900_P2_FFEI1 0xf2d0
+#define F0900_P2_FFE_ACCI1 0xf2d001ff
+
+/*P2_FFEQ1*/
+#define R0900_P2_FFEQ1 0xf2d1
+#define F0900_P2_FFE_ACCQ1 0xf2d101ff
+
+/*P2_FFEI2*/
+#define R0900_P2_FFEI2 0xf2d2
+#define F0900_P2_FFE_ACCI2 0xf2d201ff
+
+/*P2_FFEQ2*/
+#define R0900_P2_FFEQ2 0xf2d3
+#define F0900_P2_FFE_ACCQ2 0xf2d301ff
+
+/*P2_FFEI3*/
+#define R0900_P2_FFEI3 0xf2d4
+#define F0900_P2_FFE_ACCI3 0xf2d401ff
+
+/*P2_FFEQ3*/
+#define R0900_P2_FFEQ3 0xf2d5
+#define F0900_P2_FFE_ACCQ3 0xf2d501ff
+
+/*P2_FFEI4*/
+#define R0900_P2_FFEI4 0xf2d6
+#define F0900_P2_FFE_ACCI4 0xf2d601ff
+
+/*P2_FFEQ4*/
+#define R0900_P2_FFEQ4 0xf2d7
+#define F0900_P2_FFE_ACCQ4 0xf2d701ff
+
+/*P2_FFECFG*/
+#define R0900_P2_FFECFG 0xf2d8
+#define F0900_P2_EQUALFFE_ON 0xf2d80040
+#define F0900_P2_EQUAL_USEDSYMB 0xf2d80030
+#define F0900_P2_MU_EQUALFFE 0xf2d80007
+
+/*P2_TNRCFG*/
+#define R0900_P2_TNRCFG 0xf2e0
+#define F0900_P2_TUN_ACKFAIL 0xf2e00080
+#define F0900_P2_TUN_TYPE 0xf2e00070
+#define F0900_P2_TUN_SECSTOP 0xf2e00008
+#define F0900_P2_TUN_VCOSRCH 0xf2e00004
+#define F0900_P2_TUN_MADDRESS 0xf2e00003
+
+/*P2_TNRCFG2*/
+#define R0900_P2_TNRCFG2 0xf2e1
+#define F0900_P2_TUN_IQSWAP 0xf2e10080
+#define F0900_P2_STB6110_STEP2MHZ 0xf2e10040
+#define F0900_P2_STB6120_DBLI2C 0xf2e10020
+#define F0900_P2_DIS_FCCK 0xf2e10010
+#define F0900_P2_DIS_LPEN 0xf2e10008
+#define F0900_P2_DIS_BWCALC 0xf2e10004
+#define F0900_P2_SHORT_WAITSTATES 0xf2e10002
+#define F0900_P2_DIS_2BWAGC1 0xf2e10001
+
+/*P2_TNRXTAL*/
+#define R0900_P2_TNRXTAL 0xf2e4
+#define F0900_P2_TUN_MCLKDECIMAL 0xf2e400e0
+#define F0900_P2_TUN_XTALFREQ 0xf2e4001f
+
+/*P2_TNRSTEPS*/
+#define R0900_P2_TNRSTEPS 0xf2e7
+#define F0900_P2_TUNER_BW1P6 0xf2e70080
+#define F0900_P2_BWINC_OFFSET 0xf2e70070
+#define F0900_P2_SOFTSTEP_RNG 0xf2e70008
+#define F0900_P2_TUN_BWOFFSET 0xf2e70107
+
+/*P2_TNRGAIN*/
+#define R0900_P2_TNRGAIN 0xf2e8
+#define F0900_P2_TUN_KDIVEN 0xf2e800c0
+#define F0900_P2_STB6X00_OCK 0xf2e80030
+#define F0900_P2_TUN_GAIN 0xf2e8000f
+
+/*P2_TNRRF1*/
+#define R0900_P2_TNRRF1 0xf2e9
+#define F0900_P2_TUN_RFFREQ2 0xf2e900ff
+
+/*P2_TNRRF0*/
+#define R0900_P2_TNRRF0 0xf2ea
+#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff
+
+/*P2_TNRBW*/
+#define R0900_P2_TNRBW 0xf2eb
+#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0
+#define F0900_P2_TUN_BW 0xf2eb003f
+
+/*P2_TNRADJ*/
+#define R0900_P2_TNRADJ 0xf2ec
+#define F0900_P2_STB61X0_RCLK 0xf2ec0080
+#define F0900_P2_STB61X0_CALTIME 0xf2ec0040
+#define F0900_P2_STB6X00_DLB 0xf2ec0038
+#define F0900_P2_STB6000_FCL 0xf2ec0007
+
+/*P2_TNRCTL2*/
+#define R0900_P2_TNRCTL2 0xf2ed
+#define F0900_P2_STB61X0_LCP1_RCCKOFF 0xf2ed0080
+#define F0900_P2_STB61X0_LCP0 0xf2ed0040
+#define F0900_P2_STB61X0_XTOUT_RFOUTS 0xf2ed0020
+#define F0900_P2_STB61X0_XTON_MCKDV 0xf2ed0010
+#define F0900_P2_STB61X0_CALOFF_DCOFF 0xf2ed0008
+#define F0900_P2_STB6110_LPT 0xf2ed0004
+#define F0900_P2_STB6110_RX 0xf2ed0002
+#define F0900_P2_STB6110_SYN 0xf2ed0001
+
+/*P2_TNRCFG3*/
+#define R0900_P2_TNRCFG3 0xf2ee
+#define F0900_P2_STB6120_DISCTRL1 0xf2ee0080
+#define F0900_P2_STB6120_INVORDER 0xf2ee0040
+#define F0900_P2_STB6120_ENCTRL6 0xf2ee0020
+#define F0900_P2_TUN_PLLFREQ 0xf2ee001c
+#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003
+
+/*P2_TNRLAUNCH*/
+#define R0900_P2_TNRLAUNCH 0xf2f0
+
+/*P2_TNRLD*/
+#define R0900_P2_TNRLD 0xf2f0
+#define F0900_P2_TUNLD_VCOING 0xf2f00080
+#define F0900_P2_TUN_REG1FAIL 0xf2f00040
+#define F0900_P2_TUN_REG2FAIL 0xf2f00020
+#define F0900_P2_TUN_REG3FAIL 0xf2f00010
+#define F0900_P2_TUN_REG4FAIL 0xf2f00008
+#define F0900_P2_TUN_REG5FAIL 0xf2f00004
+#define F0900_P2_TUN_BWING 0xf2f00002
+#define F0900_P2_TUN_LOCKED 0xf2f00001
+
+/*P2_TNROBSL*/
+#define R0900_P2_TNROBSL 0xf2f6
+#define F0900_P2_TUN_I2CABORTED 0xf2f60080
+#define F0900_P2_TUN_LPEN 0xf2f60040
+#define F0900_P2_TUN_FCCK 0xf2f60020
+#define F0900_P2_TUN_I2CLOCKED 0xf2f60010
+#define F0900_P2_TUN_PROGDONE 0xf2f6000c
+#define F0900_P2_TUN_RFRESTE1 0xf2f60003
+
+/*P2_TNRRESTE*/
+#define R0900_P2_TNRRESTE 0xf2f7
+#define F0900_P2_TUN_RFRESTE0 0xf2f700ff
+
+/*P2_SMAPCOEF7*/
+#define R0900_P2_SMAPCOEF7 0xf300
+#define F0900_P2_DIS_QSCALE 0xf3000080
+#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f
+
+/*P2_SMAPCOEF6*/
+#define R0900_P2_SMAPCOEF6 0xf301
+#define F0900_P2_DIS_NEWSCALE 0xf3010008
+#define F0900_P2_ADJ_8PSKLLR1 0xf3010004
+#define F0900_P2_OLD_8PSKLLR1 0xf3010002
+#define F0900_P2_DIS_AB8PSK 0xf3010001
+
+/*P2_SMAPCOEF5*/
+#define R0900_P2_SMAPCOEF5 0xf302
+#define F0900_P2_DIS_8SCALE 0xf3020080
+#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f
+
+/*P2_DMDPLHSTAT*/
+#define R0900_P2_DMDPLHSTAT 0xf320
+#define F0900_P2_PLH_STATISTIC 0xf32000ff
+
+/*P2_LOCKTIME3*/
+#define R0900_P2_LOCKTIME3 0xf322
+#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff
+
+/*P2_LOCKTIME2*/
+#define R0900_P2_LOCKTIME2 0xf323
+#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff
+
+/*P2_LOCKTIME1*/
+#define R0900_P2_LOCKTIME1 0xf324
+#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff
+
+/*P2_LOCKTIME0*/
+#define R0900_P2_LOCKTIME0 0xf325
+#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff
+
+/*P2_VITSCALE*/
+#define R0900_P2_VITSCALE 0xf332
+#define F0900_P2_NVTH_NOSRANGE 0xf3320080
+#define F0900_P2_VERROR_MAXMODE 0xf3320040
+#define F0900_P2_KDIV_MODE 0xf3320030
+#define F0900_P2_NSLOWSN_LOCKED 0xf3320008
+#define F0900_P2_DELOCK_PRFLOSS 0xf3320004
+#define F0900_P2_DIS_RSFLOCK 0xf3320002
+
+/*P2_FECM*/
+#define R0900_P2_FECM 0xf333
+#define F0900_P2_DSS_DVB 0xf3330080
+#define F0900_P2_DEMOD_BYPASS 0xf3330040
+#define F0900_P2_CMP_SLOWMODE 0xf3330020
+#define F0900_P2_DSS_SRCH 0xf3330010
+#define F0900_P2_DIFF_MODEVIT 0xf3330004
+#define F0900_P2_SYNCVIT 0xf3330002
+#define F0900_P2_IQINV 0xf3330001
+
+/*P2_VTH12*/
+#define R0900_P2_VTH12 0xf334
+#define F0900_P2_VTH12 0xf33400ff
+
+/*P2_VTH23*/
+#define R0900_P2_VTH23 0xf335
+#define F0900_P2_VTH23 0xf33500ff
+
+/*P2_VTH34*/
+#define R0900_P2_VTH34 0xf336
+#define F0900_P2_VTH34 0xf33600ff
+
+/*P2_VTH56*/
+#define R0900_P2_VTH56 0xf337
+#define F0900_P2_VTH56 0xf33700ff
+
+/*P2_VTH67*/
+#define R0900_P2_VTH67 0xf338
+#define F0900_P2_VTH67 0xf33800ff
+
+/*P2_VTH78*/
+#define R0900_P2_VTH78 0xf339
+#define F0900_P2_VTH78 0xf33900ff
+
+/*P2_VITCURPUN*/
+#define R0900_P2_VITCURPUN 0xf33a
+#define F0900_P2_VIT_MAPPING 0xf33a00e0
+#define F0900_P2_VIT_CURPUN 0xf33a001f
+
+/*P2_VERROR*/
+#define R0900_P2_VERROR 0xf33b
+#define F0900_P2_REGERR_VIT 0xf33b00ff
+
+/*P2_PRVIT*/
+#define R0900_P2_PRVIT 0xf33c
+#define F0900_P2_DIS_VTHLOCK 0xf33c0040
+#define F0900_P2_E7_8VIT 0xf33c0020
+#define F0900_P2_E6_7VIT 0xf33c0010
+#define F0900_P2_E5_6VIT 0xf33c0008
+#define F0900_P2_E3_4VIT 0xf33c0004
+#define F0900_P2_E2_3VIT 0xf33c0002
+#define F0900_P2_E1_2VIT 0xf33c0001
+
+/*P2_VAVSRVIT*/
+#define R0900_P2_VAVSRVIT 0xf33d
+#define F0900_P2_AMVIT 0xf33d0080
+#define F0900_P2_FROZENVIT 0xf33d0040
+#define F0900_P2_SNVIT 0xf33d0030
+#define F0900_P2_TOVVIT 0xf33d000c
+#define F0900_P2_HYPVIT 0xf33d0003
+
+/*P2_VSTATUSVIT*/
+#define R0900_P2_VSTATUSVIT 0xf33e
+#define F0900_P2_VITERBI_ON 0xf33e0080
+#define F0900_P2_END_LOOPVIT 0xf33e0040
+#define F0900_P2_VITERBI_DEPRF 0xf33e0020
+#define F0900_P2_PRFVIT 0xf33e0010
+#define F0900_P2_LOCKEDVIT 0xf33e0008
+#define F0900_P2_VITERBI_DELOCK 0xf33e0004
+#define F0900_P2_VIT_DEMODSEL 0xf33e0002
+#define F0900_P2_VITERBI_COMPOUT 0xf33e0001
+
+/*P2_VTHINUSE*/
+#define R0900_P2_VTHINUSE 0xf33f
+#define F0900_P2_VIT_INUSE 0xf33f00ff
+
+/*P2_KDIV12*/
+#define R0900_P2_KDIV12 0xf340
+#define F0900_P2_KDIV12_MANUAL 0xf3400080
+#define F0900_P2_K_DIVIDER_12 0xf340007f
+
+/*P2_KDIV23*/
+#define R0900_P2_KDIV23 0xf341
+#define F0900_P2_KDIV23_MANUAL 0xf3410080
+#define F0900_P2_K_DIVIDER_23 0xf341007f
+
+/*P2_KDIV34*/
+#define R0900_P2_KDIV34 0xf342
+#define F0900_P2_KDIV34_MANUAL 0xf3420080
+#define F0900_P2_K_DIVIDER_34 0xf342007f
+
+/*P2_KDIV56*/
+#define R0900_P2_KDIV56 0xf343
+#define F0900_P2_KDIV56_MANUAL 0xf3430080
+#define F0900_P2_K_DIVIDER_56 0xf343007f
+
+/*P2_KDIV67*/
+#define R0900_P2_KDIV67 0xf344
+#define F0900_P2_KDIV67_MANUAL 0xf3440080
+#define F0900_P2_K_DIVIDER_67 0xf344007f
+
+/*P2_KDIV78*/
+#define R0900_P2_KDIV78 0xf345
+#define F0900_P2_KDIV78_MANUAL 0xf3450080
+#define F0900_P2_K_DIVIDER_78 0xf345007f
+
+/*P2_PDELCTRL1*/
+#define R0900_P2_PDELCTRL1 0xf350
+#define F0900_P2_INV_MISMASK 0xf3500080
+#define F0900_P2_FORCE_ACCEPTED 0xf3500040
+#define F0900_P2_FILTER_EN 0xf3500020
+#define F0900_P2_FORCE_PKTDELINUSE 0xf3500010
+#define F0900_P2_HYSTEN 0xf3500008
+#define F0900_P2_HYSTSWRST 0xf3500004
+#define F0900_P2_EN_MIS00 0xf3500002
+#define F0900_P2_ALGOSWRST 0xf3500001
+
+/*P2_PDELCTRL2*/
+#define R0900_P2_PDELCTRL2 0xf351
+#define F0900_P2_FORCE_CONTINUOUS 0xf3510080
+#define F0900_P2_RESET_UPKO_COUNT 0xf3510040
+#define F0900_P2_USER_PKTDELIN_NB 0xf3510020
+#define F0900_P2_FORCE_LOCKED 0xf3510010
+#define F0900_P2_DATA_UNBBSCRAM 0xf3510008
+#define F0900_P2_FORCE_LONGPKT 0xf3510004
+#define F0900_P2_FRAME_MODE 0xf3510002
+
+/*P2_HYSTTHRESH*/
+#define R0900_P2_HYSTTHRESH 0xf354
+#define F0900_P2_UNLCK_THRESH 0xf35400f0
+#define F0900_P2_DELIN_LCK_THRESH 0xf354000f
+
+/*P2_ISIENTRY*/
+#define R0900_P2_ISIENTRY 0xf35e
+#define F0900_P2_ISI_ENTRY 0xf35e00ff
+
+/*P2_ISIBITENA*/
+#define R0900_P2_ISIBITENA 0xf35f
+#define F0900_P2_ISI_BIT_EN 0xf35f00ff
+
+/*P2_MATSTR1*/
+#define R0900_P2_MATSTR1 0xf360
+#define F0900_P2_MATYPE_CURRENT1 0xf36000ff
+
+/*P2_MATSTR0*/
+#define R0900_P2_MATSTR0 0xf361
+#define F0900_P2_MATYPE_CURRENT0 0xf36100ff
+
+/*P2_UPLSTR1*/
+#define R0900_P2_UPLSTR1 0xf362
+#define F0900_P2_UPL_CURRENT1 0xf36200ff
+
+/*P2_UPLSTR0*/
+#define R0900_P2_UPLSTR0 0xf363
+#define F0900_P2_UPL_CURRENT0 0xf36300ff
+
+/*P2_DFLSTR1*/
+#define R0900_P2_DFLSTR1 0xf364
+#define F0900_P2_DFL_CURRENT1 0xf36400ff
+
+/*P2_DFLSTR0*/
+#define R0900_P2_DFLSTR0 0xf365
+#define F0900_P2_DFL_CURRENT0 0xf36500ff
+
+/*P2_SYNCSTR*/
+#define R0900_P2_SYNCSTR 0xf366
+#define F0900_P2_SYNC_CURRENT 0xf36600ff
+
+/*P2_SYNCDSTR1*/
+#define R0900_P2_SYNCDSTR1 0xf367
+#define F0900_P2_SYNCD_CURRENT1 0xf36700ff
+
+/*P2_SYNCDSTR0*/
+#define R0900_P2_SYNCDSTR0 0xf368
+#define F0900_P2_SYNCD_CURRENT0 0xf36800ff
+
+/*P2_PDELSTATUS1*/
+#define R0900_P2_PDELSTATUS1 0xf369
+#define F0900_P2_PKTDELIN_DELOCK 0xf3690080
+#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040
+#define F0900_P2_CONTINUOUS_STREAM 0xf3690020
+#define F0900_P2_UNACCEPTED_STREAM 0xf3690010
+#define F0900_P2_BCH_ERROR_FLAG 0xf3690008
+#define F0900_P2_BBHCRCKO 0xf3690004
+#define F0900_P2_PKTDELIN_LOCK 0xf3690002
+#define F0900_P2_FIRST_LOCK 0xf3690001
+
+/*P2_PDELSTATUS2*/
+#define R0900_P2_PDELSTATUS2 0xf36a
+#define F0900_P2_PKTDEL_DEMODSEL 0xf36a0080
+#define F0900_P2_FRAME_MODCOD 0xf36a007c
+#define F0900_P2_FRAME_TYPE 0xf36a0003
+
+/*P2_BBFCRCKO1*/
+#define R0900_P2_BBFCRCKO1 0xf36b
+#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff
+
+/*P2_BBFCRCKO0*/
+#define R0900_P2_BBFCRCKO0 0xf36c
+#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff
+
+/*P2_UPCRCKO1*/
+#define R0900_P2_UPCRCKO1 0xf36d
+#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff
+
+/*P2_UPCRCKO0*/
+#define R0900_P2_UPCRCKO0 0xf36e
+#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff
+
+/*P2_TSSTATEM*/
+#define R0900_P2_TSSTATEM 0xf370
+#define F0900_P2_TSDIL_ON 0xf3700080
+#define F0900_P2_TSSKIPRS_ON 0xf3700040
+#define F0900_P2_TSRS_ON 0xf3700020
+#define F0900_P2_TSDESCRAMB_ON 0xf3700010
+#define F0900_P2_TSFRAME_MODE 0xf3700008
+#define F0900_P2_TS_DISABLE 0xf3700004
+#define F0900_P2_TSACM_MODE 0xf3700002
+#define F0900_P2_TSOUT_NOSYNC 0xf3700001
+
+/*P2_TSCFGH*/
+#define R0900_P2_TSCFGH 0xf372
+#define F0900_P2_TSFIFO_DVBCI 0xf3720080
+#define F0900_P2_TSFIFO_SERIAL 0xf3720040
+#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020
+#define F0900_P2_TSFIFO_DUTY50 0xf3720010
+#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008
+#define F0900_P2_TSFIFO_ERRMODE 0xf3720006
+#define F0900_P2_RST_HWARE 0xf3720001
+
+/*P2_TSCFGM*/
+#define R0900_P2_TSCFGM 0xf373
+#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0
+#define F0900_P2_TSFIFO_PERMDATA 0xf3730020
+#define F0900_P2_TSFIFO_NONEWSGNL 0xf3730010
+#define F0900_P2_TSFIFO_BITSPEED 0xf3730008
+#define F0900_P2_NPD_SPECDVBS2 0xf3730004
+#define F0900_P2_TSFIFO_STOPCKDIS 0xf3730002
+#define F0900_P2_TSFIFO_INVDATA 0xf3730001
+
+/*P2_TSCFGL*/
+#define R0900_P2_TSCFGL 0xf374
+#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0
+#define F0900_P2_BCHERROR_MODE 0xf3740030
+#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008
+#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004
+#define F0900_P2_TSFIFO_DPUNACT 0xf3740002
+#define F0900_P2_TSFIFO_NPDOFF 0xf3740001
+
+/*P2_TSINSDELH*/
+#define R0900_P2_TSINSDELH 0xf376
+#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080
+#define F0900_P2_TSDEL_XXHEADER 0xf3760040
+#define F0900_P2_TSDEL_BBHEADER 0xf3760020
+#define F0900_P2_TSDEL_DATAFIELD 0xf3760010
+#define F0900_P2_TSINSDEL_ISCR 0xf3760008
+#define F0900_P2_TSINSDEL_NPD 0xf3760004
+#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002
+#define F0900_P2_TSINSDEL_CRC8 0xf3760001
+
+/*P2_TSSPEED*/
+#define R0900_P2_TSSPEED 0xf380
+#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff
+
+/*P2_TSSTATUS*/
+#define R0900_P2_TSSTATUS 0xf381
+#define F0900_P2_TSFIFO_LINEOK 0xf3810080
+#define F0900_P2_TSFIFO_ERROR 0xf3810040
+#define F0900_P2_TSFIFO_DATA7 0xf3810020
+#define F0900_P2_TSFIFO_NOSYNC 0xf3810010
+#define F0900_P2_ISCR_INITIALIZED 0xf3810008
+#define F0900_P2_ISCR_UPDATED 0xf3810004
+#define F0900_P2_SOFFIFO_UNREGUL 0xf3810002
+#define F0900_P2_DIL_READY 0xf3810001
+
+/*P2_TSSTATUS2*/
+#define R0900_P2_TSSTATUS2 0xf382
+#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080
+#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040
+#define F0900_P2_DILXX_RESET 0xf3820020
+#define F0900_P2_TSSERIAL_IMPOS 0xf3820010
+#define F0900_P2_TSFIFO_LINENOK 0xf3820008
+#define F0900_P2_BITSPEED_EVENT 0xf3820004
+#define F0900_P2_SCRAMBDETECT 0xf3820002
+#define F0900_P2_ULDTV67_FALSELOCK 0xf3820001
+
+/*P2_TSBITRATE1*/
+#define R0900_P2_TSBITRATE1 0xf383
+#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff
+
+/*P2_TSBITRATE0*/
+#define R0900_P2_TSBITRATE0 0xf384
+#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff
+
+/*P2_ERRCTRL1*/
+#define R0900_P2_ERRCTRL1 0xf398
+#define F0900_P2_ERR_SOURCE1 0xf39800f0
+#define F0900_P2_NUM_EVENT1 0xf3980007
+
+/*P2_ERRCNT12*/
+#define R0900_P2_ERRCNT12 0xf399
+#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080
+#define F0900_P2_ERR_CNT12 0xf399007f
+
+/*P2_ERRCNT11*/
+#define R0900_P2_ERRCNT11 0xf39a
+#define F0900_P2_ERR_CNT11 0xf39a00ff
+
+/*P2_ERRCNT10*/
+#define R0900_P2_ERRCNT10 0xf39b
+#define F0900_P2_ERR_CNT10 0xf39b00ff
+
+/*P2_ERRCTRL2*/
+#define R0900_P2_ERRCTRL2 0xf39c
+#define F0900_P2_ERR_SOURCE2 0xf39c00f0
+#define F0900_P2_NUM_EVENT2 0xf39c0007
+
+/*P2_ERRCNT22*/
+#define R0900_P2_ERRCNT22 0xf39d
+#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080
+#define F0900_P2_ERR_CNT22 0xf39d007f
+
+/*P2_ERRCNT21*/
+#define R0900_P2_ERRCNT21 0xf39e
+#define F0900_P2_ERR_CNT21 0xf39e00ff
+
+/*P2_ERRCNT20*/
+#define R0900_P2_ERRCNT20 0xf39f
+#define F0900_P2_ERR_CNT20 0xf39f00ff
+
+/*P2_FECSPY*/
+#define R0900_P2_FECSPY 0xf3a0
+#define F0900_P2_SPY_ENABLE 0xf3a00080
+#define F0900_P2_NO_SYNCBYTE 0xf3a00040
+#define F0900_P2_SERIAL_MODE 0xf3a00020
+#define F0900_P2_UNUSUAL_PACKET 0xf3a00010
+#define F0900_P2_BER_PACKMODE 0xf3a00008
+#define F0900_P2_BERMETER_LMODE 0xf3a00002
+#define F0900_P2_BERMETER_RESET 0xf3a00001
+
+/*P2_FSPYCFG*/
+#define R0900_P2_FSPYCFG 0xf3a1
+#define F0900_P2_FECSPY_INPUT 0xf3a100c0
+#define F0900_P2_RST_ON_ERROR 0xf3a10020
+#define F0900_P2_ONE_SHOT 0xf3a10010
+#define F0900_P2_I2C_MODE 0xf3a1000c
+#define F0900_P2_SPY_HYSTERESIS 0xf3a10003
+
+/*P2_FSPYDATA*/
+#define R0900_P2_FSPYDATA 0xf3a2
+#define F0900_P2_SPY_STUFFING 0xf3a20080
+#define F0900_P2_NOERROR_PKTJITTER 0xf3a20040
+#define F0900_P2_SPY_CNULLPKT 0xf3a20020
+#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f
+
+/*P2_FSPYOUT*/
+#define R0900_P2_FSPYOUT 0xf3a3
+#define F0900_P2_FSPY_DIRECT 0xf3a30080
+#define F0900_P2_SPY_OUTDATA_BUS 0xf3a30038
+#define F0900_P2_STUFF_MODE 0xf3a30007
+
+/*P2_FSTATUS*/
+#define R0900_P2_FSTATUS 0xf3a4
+#define F0900_P2_SPY_ENDSIM 0xf3a40080
+#define F0900_P2_VALID_SIM 0xf3a40040
+#define F0900_P2_FOUND_SIGNAL 0xf3a40020
+#define F0900_P2_DSS_SYNCBYTE 0xf3a40010
+#define F0900_P2_RESULT_STATE 0xf3a4000f
+
+/*P2_FBERCPT4*/
+#define R0900_P2_FBERCPT4 0xf3a8
+#define F0900_P2_FBERMETER_CPT4 0xf3a800ff
+
+/*P2_FBERCPT3*/
+#define R0900_P2_FBERCPT3 0xf3a9
+#define F0900_P2_FBERMETER_CPT3 0xf3a900ff
+
+/*P2_FBERCPT2*/
+#define R0900_P2_FBERCPT2 0xf3aa
+#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff
+
+/*P2_FBERCPT1*/
+#define R0900_P2_FBERCPT1 0xf3ab
+#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff
+
+/*P2_FBERCPT0*/
+#define R0900_P2_FBERCPT0 0xf3ac
+#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff
+
+/*P2_FBERERR2*/
+#define R0900_P2_FBERERR2 0xf3ad
+#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff
+
+/*P2_FBERERR1*/
+#define R0900_P2_FBERERR1 0xf3ae
+#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff
+
+/*P2_FBERERR0*/
+#define R0900_P2_FBERERR0 0xf3af
+#define F0900_P2_FBERMETER_ERR0 0xf3af00ff
+
+/*P2_FSPYBER*/
+#define R0900_P2_FSPYBER 0xf3b2
+#define F0900_P2_FSPYOBS_XORREAD 0xf3b20040
+#define F0900_P2_FSPYBER_OBSMODE 0xf3b20020
+#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010
+#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008
+#define F0900_P2_FSPYBER_CTIME 0xf3b20007
+
+/*P1_IQCONST*/
+#define R0900_P1_IQCONST 0xf400
+#define F0900_P1_CONSTEL_SELECT 0xf4000060
+#define F0900_P1_IQSYMB_SEL 0xf400001f
+
+/*P1_NOSCFG*/
+#define R0900_P1_NOSCFG 0xf401
+#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020
+#define F0900_P1_NOSPLH_BETA 0xf4010018
+#define F0900_P1_NOSDATA_BETA 0xf4010007
+
+/*P1_ISYMB*/
+#define R0900_P1_ISYMB 0xf402
+#define F0900_P1_I_SYMBOL 0xf40201ff
+
+/*P1_QSYMB*/
+#define R0900_P1_QSYMB 0xf403
+#define F0900_P1_Q_SYMBOL 0xf40301ff
+
+/*P1_AGC1CFG*/
+#define R0900_P1_AGC1CFG 0xf404
+#define F0900_P1_DC_FROZEN 0xf4040080
+#define F0900_P1_DC_CORRECT 0xf4040040
+#define F0900_P1_AMM_FROZEN 0xf4040020
+#define F0900_P1_AMM_CORRECT 0xf4040010
+#define F0900_P1_QUAD_FROZEN 0xf4040008
+#define F0900_P1_QUAD_CORRECT 0xf4040004
+#define F0900_P1_DCCOMP_SLOW 0xf4040002
+#define F0900_P1_IQMISM_SLOW 0xf4040001
+
+/*P1_AGC1CN*/
+#define R0900_P1_AGC1CN 0xf406
+#define F0900_P1_AGC1_LOCKED 0xf4060080
+#define F0900_P1_AGC1_OVERFLOW 0xf4060040
+#define F0900_P1_AGC1_NOSLOWLK 0xf4060020
+#define F0900_P1_AGC1_MINPOWER 0xf4060010
+#define F0900_P1_AGCOUT_FAST 0xf4060008
+#define F0900_P1_AGCIQ_BETA 0xf4060007
+
+/*P1_AGC1REF*/
+#define R0900_P1_AGC1REF 0xf407
+#define F0900_P1_AGCIQ_REF 0xf40700ff
+
+/*P1_IDCCOMP*/
+#define R0900_P1_IDCCOMP 0xf408
+#define F0900_P1_IAVERAGE_ADJ 0xf40801ff
+
+/*P1_QDCCOMP*/
+#define R0900_P1_QDCCOMP 0xf409
+#define F0900_P1_QAVERAGE_ADJ 0xf40901ff
+
+/*P1_POWERI*/
+#define R0900_P1_POWERI 0xf40a
+#define F0900_P1_POWER_I 0xf40a00ff
+
+/*P1_POWERQ*/
+#define R0900_P1_POWERQ 0xf40b
+#define F0900_P1_POWER_Q 0xf40b00ff
+
+/*P1_AGC1AMM*/
+#define R0900_P1_AGC1AMM 0xf40c
+#define F0900_P1_AMM_VALUE 0xf40c00ff
+
+/*P1_AGC1QUAD*/
+#define R0900_P1_AGC1QUAD 0xf40d
+#define F0900_P1_QUAD_VALUE 0xf40d01ff
+
+/*P1_AGCIQIN1*/
+#define R0900_P1_AGCIQIN1 0xf40e
+#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff
+
+/*P1_AGCIQIN0*/
+#define R0900_P1_AGCIQIN0 0xf40f
+#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff
+
+/*P1_DEMOD*/
+#define R0900_P1_DEMOD 0xf410
+#define F0900_P1_DEMOD_STOP 0xf4100040
+#define F0900_P1_SPECINV_CONTROL 0xf4100030
+#define F0900_P1_FORCE_ENASAMP 0xf4100008
+#define F0900_P1_MANUAL_ROLLOFF 0xf4100004
+#define F0900_P1_ROLLOFF_CONTROL 0xf4100003
+
+/*P1_DMDMODCOD*/
+#define R0900_P1_DMDMODCOD 0xf411
+#define F0900_P1_MANUAL_MODCOD 0xf4110080
+#define F0900_P1_DEMOD_MODCOD 0xf411007c
+#define F0900_P1_DEMOD_TYPE 0xf4110003
+
+/*P1_DSTATUS*/
+#define R0900_P1_DSTATUS 0xf412
+#define F0900_P1_CAR_LOCK 0xf4120080
+#define F0900_P1_TMGLOCK_QUALITY 0xf4120060
+#define F0900_P1_SDVBS1_ENABLE 0xf4120010
+#define F0900_P1_LOCK_DEFINITIF 0xf4120008
+#define F0900_P1_TIMING_IS_LOCKED 0xf4120004
+#define F0900_P1_COARSE_TMGLOCK 0xf4120002
+#define F0900_P1_COARSE_CARLOCK 0xf4120001
+
+/*P1_DSTATUS2*/
+#define R0900_P1_DSTATUS2 0xf413
+#define F0900_P1_DEMOD_DELOCK 0xf4130080
+#define F0900_P1_DEMOD_TIMEOUT 0xf4130040
+#define F0900_P1_MODCODRQ_SYNCTAG 0xf4130020
+#define F0900_P1_POLYPH_SATEVENT 0xf4130010
+#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008
+#define F0900_P1_AGC2_OVERFLOW 0xf4130004
+#define F0900_P1_CFR_OVERFLOW 0xf4130002
+#define F0900_P1_GAMMA_OVERUNDER 0xf4130001
+
+/*P1_DMDCFGMD*/
+#define R0900_P1_DMDCFGMD 0xf414
+#define F0900_P1_DVBS2_ENABLE 0xf4140080
+#define F0900_P1_DVBS1_ENABLE 0xf4140040
+#define F0900_P1_CFR_AUTOSCAN 0xf4140020
+#define F0900_P1_SCAN_ENABLE 0xf4140010
+#define F0900_P1_TUN_AUTOSCAN 0xf4140008
+#define F0900_P1_NOFORCE_RELOCK 0xf4140004
+#define F0900_P1_TUN_RNG 0xf4140003
+
+/*P1_DMDCFG2*/
+#define R0900_P1_DMDCFG2 0xf415
+#define F0900_P1_AGC1_WAITLOCK 0xf4150080
+#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040
+#define F0900_P1_OVERFLOW_TIMEOUT 0xf4150020
+#define F0900_P1_SCANFAIL_TIMEOUT 0xf4150010
+#define F0900_P1_DMDTOUT_BACK 0xf4150008
+#define F0900_P1_CARLOCK_S1ENABLE 0xf4150004
+#define F0900_P1_COARSE_LK3MODE 0xf4150002
+#define F0900_P1_COARSE_LK2MODE 0xf4150001
+
+/*P1_DMDISTATE*/
+#define R0900_P1_DMDISTATE 0xf416
+#define F0900_P1_I2C_NORESETDMODE 0xf4160080
+#define F0900_P1_FORCE_ETAPED 0xf4160040
+#define F0900_P1_SDMDRST_DIRCLK 0xf4160020
+#define F0900_P1_I2C_DEMOD_MODE 0xf416001f
+
+/*P1_DMDT0M*/
+#define R0900_P1_DMDT0M 0xf417
+#define F0900_P1_DMDT0_MIN 0xf41700ff
+
+/*P1_DMDSTATE*/
+#define R0900_P1_DMDSTATE 0xf41b
+#define F0900_P1_DEMOD_LOCKED 0xf41b0080
+#define F0900_P1_HEADER_MODE 0xf41b0060
+#define F0900_P1_DEMOD_MODE 0xf41b001f
+
+/*P1_DMDFLYW*/
+#define R0900_P1_DMDFLYW 0xf41c
+#define F0900_P1_I2C_IRQVAL 0xf41c00f0
+#define F0900_P1_FLYWHEEL_CPT 0xf41c000f
+
+/*P1_DSTATUS3*/
+#define R0900_P1_DSTATUS3 0xf41d
+#define F0900_P1_CFR_ZIGZAG 0xf41d0080
+#define F0900_P1_DEMOD_CFGMODE 0xf41d0060
+#define F0900_P1_GAMMA_LOWBAUDRATE 0xf41d0010
+#define F0900_P1_RELOCK_MODE 0xf41d0008
+#define F0900_P1_DEMOD_FAIL 0xf41d0004
+#define F0900_P1_ETAPE1A_DVBXMEM 0xf41d0003
+
+/*P1_DMDCFG3*/
+#define R0900_P1_DMDCFG3 0xf41e
+#define F0900_P1_DVBS1_TMGWAIT 0xf41e0080
+#define F0900_P1_NO_BWCENTERING 0xf41e0040
+#define F0900_P1_INV_SEQSRCH 0xf41e0020
+#define F0900_P1_DIS_SFRUPLOW_TRK 0xf41e0010
+#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008
+#define F0900_P1_LOCKTIME_MODE 0xf41e0007
+
+/*P1_DMDCFG4*/
+#define R0900_P1_DMDCFG4 0xf41f
+#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008
+#define F0900_P1_DIS_CLKENABLE 0xf41f0004
+#define F0900_P1_DIS_HDRDIVLOCK 0xf41f0002
+#define F0900_P1_NO_TNRWBINIT 0xf41f0001
+
+/*P1_CORRELMANT*/
+#define R0900_P1_CORRELMANT 0xf420
+#define F0900_P1_CORREL_MANT 0xf42000ff
+
+/*P1_CORRELABS*/
+#define R0900_P1_CORRELABS 0xf421
+#define F0900_P1_CORREL_ABS 0xf42100ff
+
+/*P1_CORRELEXP*/
+#define R0900_P1_CORRELEXP 0xf422
+#define F0900_P1_CORREL_ABSEXP 0xf42200f0
+#define F0900_P1_CORREL_EXP 0xf422000f
+
+/*P1_PLHMODCOD*/
+#define R0900_P1_PLHMODCOD 0xf424
+#define F0900_P1_SPECINV_DEMOD 0xf4240080
+#define F0900_P1_PLH_MODCOD 0xf424007c
+#define F0900_P1_PLH_TYPE 0xf4240003
+
+/*P1_AGCK32*/
+#define R0900_P1_AGCK32 0xf42b
+#define F0900_P1_R3ADJOFF_32APSK 0xf42b0080
+#define F0900_P1_R2ADJOFF_32APSK 0xf42b0040
+#define F0900_P1_R1ADJOFF_32APSK 0xf42b0020
+#define F0900_P1_RADJ_32APSK 0xf42b001f
+
+/*P1_AGC2O*/
+#define R0900_P1_AGC2O 0xf42c
+#define F0900_P1_AGC2REF_ADJUSTING 0xf42c0080
+#define F0900_P1_AGC2_COARSEFAST 0xf42c0040
+#define F0900_P1_AGC2_LKSQRT 0xf42c0020
+#define F0900_P1_AGC2_LKMODE 0xf42c0010
+#define F0900_P1_AGC2_LKEQUA 0xf42c0008
+#define F0900_P1_AGC2_COEF 0xf42c0007
+
+/*P1_AGC2REF*/
+#define R0900_P1_AGC2REF 0xf42d
+#define F0900_P1_AGC2_REF 0xf42d00ff
+
+/*P1_AGC1ADJ*/
+#define R0900_P1_AGC1ADJ 0xf42e
+#define F0900_P1_AGC1ADJ_MANUAL 0xf42e0080
+#define F0900_P1_AGC1_ADJUSTED 0xf42e017f
+
+/*P1_AGC2I1*/
+#define R0900_P1_AGC2I1 0xf436
+#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff
+
+/*P1_AGC2I0*/
+#define R0900_P1_AGC2I0 0xf437
+#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff
+
+/*P1_CARCFG*/
+#define R0900_P1_CARCFG 0xf438
+#define F0900_P1_CFRUPLOW_AUTO 0xf4380080
+#define F0900_P1_CFRUPLOW_TEST 0xf4380040
+#define F0900_P1_EN_CAR2CENTER 0xf4380020
+#define F0900_P1_CARHDR_NODIV8 0xf4380010
+#define F0900_P1_I2C_ROTA 0xf4380008
+#define F0900_P1_ROTAON 0xf4380004
+#define F0900_P1_PH_DET_ALGO 0xf4380003
+
+/*P1_ACLC*/
+#define R0900_P1_ACLC 0xf439
+#define F0900_P1_STOP_S2ALPHA 0xf43900c0
+#define F0900_P1_CAR_ALPHA_MANT 0xf4390030
+#define F0900_P1_CAR_ALPHA_EXP 0xf439000f
+
+/*P1_BCLC*/
+#define R0900_P1_BCLC 0xf43a
+#define F0900_P1_STOP_S2BETA 0xf43a00c0
+#define F0900_P1_CAR_BETA_MANT 0xf43a0030
+#define F0900_P1_CAR_BETA_EXP 0xf43a000f
+
+/*P1_CARFREQ*/
+#define R0900_P1_CARFREQ 0xf43d
+#define F0900_P1_KC_COARSE_EXP 0xf43d00f0
+#define F0900_P1_BETA_FREQ 0xf43d000f
+
+/*P1_CARHDR*/
+#define R0900_P1_CARHDR 0xf43e
+#define F0900_P1_K_FREQ_HDR 0xf43e00ff
+
+/*P1_LDT*/
+#define R0900_P1_LDT 0xf43f
+#define F0900_P1_CARLOCK_THRES 0xf43f01ff
+
+/*P1_LDT2*/
+#define R0900_P1_LDT2 0xf440
+#define F0900_P1_CARLOCK_THRES2 0xf44001ff
+
+/*P1_CFRICFG*/
+#define R0900_P1_CFRICFG 0xf441
+#define F0900_P1_CFRINIT_UNVALRNG 0xf4410080
+#define F0900_P1_CFRINIT_LUNVALCPT 0xf4410040
+#define F0900_P1_CFRINIT_ABORTDBL 0xf4410020
+#define F0900_P1_CFRINIT_ABORTPRED 0xf4410010
+#define F0900_P1_CFRINIT_UNVALSKIP 0xf4410008
+#define F0900_P1_CFRINIT_CSTINC 0xf4410004
+#define F0900_P1_NEG_CFRSTEP 0xf4410001
+
+/*P1_CFRUP1*/
+#define R0900_P1_CFRUP1 0xf442
+#define F0900_P1_CFR_UP1 0xf44201ff
+
+/*P1_CFRUP0*/
+#define R0900_P1_CFRUP0 0xf443
+#define F0900_P1_CFR_UP0 0xf44300ff
+
+/*P1_CFRLOW1*/
+#define R0900_P1_CFRLOW1 0xf446
+#define F0900_P1_CFR_LOW1 0xf44601ff
+
+/*P1_CFRLOW0*/
+#define R0900_P1_CFRLOW0 0xf447
+#define F0900_P1_CFR_LOW0 0xf44700ff
+
+/*P1_CFRINIT1*/
+#define R0900_P1_CFRINIT1 0xf448
+#define F0900_P1_CFR_INIT1 0xf44801ff
+
+/*P1_CFRINIT0*/
+#define R0900_P1_CFRINIT0 0xf449
+#define F0900_P1_CFR_INIT0 0xf44900ff
+
+/*P1_CFRINC1*/
+#define R0900_P1_CFRINC1 0xf44a
+#define F0900_P1_MANUAL_CFRINC 0xf44a0080
+#define F0900_P1_CFR_INC1 0xf44a017f
+
+/*P1_CFRINC0*/
+#define R0900_P1_CFRINC0 0xf44b
+#define F0900_P1_CFR_INC0 0xf44b00f0
+
+/*P1_CFR2*/
+#define R0900_P1_CFR2 0xf44c
+#define F0900_P1_CAR_FREQ2 0xf44c01ff
+
+/*P1_CFR1*/
+#define R0900_P1_CFR1 0xf44d
+#define F0900_P1_CAR_FREQ1 0xf44d00ff
+
+/*P1_CFR0*/
+#define R0900_P1_CFR0 0xf44e
+#define F0900_P1_CAR_FREQ0 0xf44e00ff
+
+/*P1_LDI*/
+#define R0900_P1_LDI 0xf44f
+#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff
+
+/*P1_TMGCFG*/
+#define R0900_P1_TMGCFG 0xf450
+#define F0900_P1_TMGLOCK_BETA 0xf45000c0
+#define F0900_P1_NOTMG_GROUPDELAY 0xf4500020
+#define F0900_P1_DO_TIMING_CORR 0xf4500010
+#define F0900_P1_MANUAL_SCAN 0xf450000c
+#define F0900_P1_TMG_MINFREQ 0xf4500003
+
+/*P1_RTC*/
+#define R0900_P1_RTC 0xf451
+#define F0900_P1_TMGALPHA_EXP 0xf45100f0
+#define F0900_P1_TMGBETA_EXP 0xf451000f
+
+/*P1_RTCS2*/
+#define R0900_P1_RTCS2 0xf452
+#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0
+#define F0900_P1_TMGBETAS2_EXP 0xf452000f
+
+/*P1_TMGTHRISE*/
+#define R0900_P1_TMGTHRISE 0xf453
+#define F0900_P1_TMGLOCK_THRISE 0xf45300ff
+
+/*P1_TMGTHFALL*/
+#define R0900_P1_TMGTHFALL 0xf454
+#define F0900_P1_TMGLOCK_THFALL 0xf45400ff
+
+/*P1_SFRUPRATIO*/
+#define R0900_P1_SFRUPRATIO 0xf455
+#define F0900_P1_SFR_UPRATIO 0xf45500ff
+
+/*P1_SFRLOWRATIO*/
+#define R0900_P1_SFRLOWRATIO 0xf456
+#define F0900_P1_SFR_LOWRATIO 0xf45600ff
+
+/*P1_KREFTMG*/
+#define R0900_P1_KREFTMG 0xf458
+#define F0900_P1_KREF_TMG 0xf45800ff
+
+/*P1_SFRSTEP*/
+#define R0900_P1_SFRSTEP 0xf459
+#define F0900_P1_SFR_SCANSTEP 0xf45900f0
+#define F0900_P1_SFR_CENTERSTEP 0xf459000f
+
+/*P1_TMGCFG2*/
+#define R0900_P1_TMGCFG2 0xf45a
+#define F0900_P1_DIS_AUTOSAMP 0xf45a0008
+#define F0900_P1_SCANINIT_QUART 0xf45a0004
+#define F0900_P1_NOTMG_DVBS1DERAT 0xf45a0002
+#define F0900_P1_SFRRATIO_FINE 0xf45a0001
+
+/*P1_SFRINIT1*/
+#define R0900_P1_SFRINIT1 0xf45e
+#define F0900_P1_SFR_INIT1 0xf45e00ff
+
+/*P1_SFRINIT0*/
+#define R0900_P1_SFRINIT0 0xf45f
+#define F0900_P1_SFR_INIT0 0xf45f00ff
+
+/*P1_SFRUP1*/
+#define R0900_P1_SFRUP1 0xf460
+#define F0900_P1_AUTO_GUP 0xf4600080
+#define F0900_P1_SYMB_FREQ_UP1 0xf460007f
+
+/*P1_SFRUP0*/
+#define R0900_P1_SFRUP0 0xf461
+#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff
+
+/*P1_SFRLOW1*/
+#define R0900_P1_SFRLOW1 0xf462
+#define F0900_P1_AUTO_GLOW 0xf4620080
+#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f
+
+/*P1_SFRLOW0*/
+#define R0900_P1_SFRLOW0 0xf463
+#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff
+
+/*P1_SFR3*/
+#define R0900_P1_SFR3 0xf464
+#define F0900_P1_SYMB_FREQ3 0xf46400ff
+
+/*P1_SFR2*/
+#define R0900_P1_SFR2 0xf465
+#define F0900_P1_SYMB_FREQ2 0xf46500ff
+
+/*P1_SFR1*/
+#define R0900_P1_SFR1 0xf466
+#define F0900_P1_SYMB_FREQ1 0xf46600ff
+
+/*P1_SFR0*/
+#define R0900_P1_SFR0 0xf467
+#define F0900_P1_SYMB_FREQ0 0xf46700ff
+
+/*P1_TMGREG2*/
+#define R0900_P1_TMGREG2 0xf468
+#define F0900_P1_TMGREG2 0xf46800ff
+
+/*P1_TMGREG1*/
+#define R0900_P1_TMGREG1 0xf469
+#define F0900_P1_TMGREG1 0xf46900ff
+
+/*P1_TMGREG0*/
+#define R0900_P1_TMGREG0 0xf46a
+#define F0900_P1_TMGREG0 0xf46a00ff
+
+/*P1_TMGLOCK1*/
+#define R0900_P1_TMGLOCK1 0xf46b
+#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff
+
+/*P1_TMGLOCK0*/
+#define R0900_P1_TMGLOCK0 0xf46c
+#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff
+
+/*P1_TMGOBS*/
+#define R0900_P1_TMGOBS 0xf46d
+#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0
+#define F0900_P1_SCAN_SIGN 0xf46d0030
+#define F0900_P1_TMG_SCANNING 0xf46d0008
+#define F0900_P1_CHCENTERING_MODE 0xf46d0004
+#define F0900_P1_TMG_SCANFAIL 0xf46d0002
+
+/*P1_EQUALCFG*/
+#define R0900_P1_EQUALCFG 0xf46f
+#define F0900_P1_NOTMG_NEGALWAIT 0xf46f0080
+#define F0900_P1_EQUAL_ON 0xf46f0040
+#define F0900_P1_SEL_EQUALCOR 0xf46f0038
+#define F0900_P1_MU_EQUALDFE 0xf46f0007
+
+/*P1_EQUAI1*/
+#define R0900_P1_EQUAI1 0xf470
+#define F0900_P1_EQUA_ACCI1 0xf47001ff
+
+/*P1_EQUAQ1*/
+#define R0900_P1_EQUAQ1 0xf471
+#define F0900_P1_EQUA_ACCQ1 0xf47101ff
+
+/*P1_EQUAI2*/
+#define R0900_P1_EQUAI2 0xf472
+#define F0900_P1_EQUA_ACCI2 0xf47201ff
+
+/*P1_EQUAQ2*/
+#define R0900_P1_EQUAQ2 0xf473
+#define F0900_P1_EQUA_ACCQ2 0xf47301ff
+
+/*P1_EQUAI3*/
+#define R0900_P1_EQUAI3 0xf474
+#define F0900_P1_EQUA_ACCI3 0xf47401ff
+
+/*P1_EQUAQ3*/
+#define R0900_P1_EQUAQ3 0xf475
+#define F0900_P1_EQUA_ACCQ3 0xf47501ff
+
+/*P1_EQUAI4*/
+#define R0900_P1_EQUAI4 0xf476
+#define F0900_P1_EQUA_ACCI4 0xf47601ff
+
+/*P1_EQUAQ4*/
+#define R0900_P1_EQUAQ4 0xf477
+#define F0900_P1_EQUA_ACCQ4 0xf47701ff
+
+/*P1_EQUAI5*/
+#define R0900_P1_EQUAI5 0xf478
+#define F0900_P1_EQUA_ACCI5 0xf47801ff
+
+/*P1_EQUAQ5*/
+#define R0900_P1_EQUAQ5 0xf479
+#define F0900_P1_EQUA_ACCQ5 0xf47901ff
+
+/*P1_EQUAI6*/
+#define R0900_P1_EQUAI6 0xf47a
+#define F0900_P1_EQUA_ACCI6 0xf47a01ff
+
+/*P1_EQUAQ6*/
+#define R0900_P1_EQUAQ6 0xf47b
+#define F0900_P1_EQUA_ACCQ6 0xf47b01ff
+
+/*P1_EQUAI7*/
+#define R0900_P1_EQUAI7 0xf47c
+#define F0900_P1_EQUA_ACCI7 0xf47c01ff
+
+/*P1_EQUAQ7*/
+#define R0900_P1_EQUAQ7 0xf47d
+#define F0900_P1_EQUA_ACCQ7 0xf47d01ff
+
+/*P1_EQUAI8*/
+#define R0900_P1_EQUAI8 0xf47e
+#define F0900_P1_EQUA_ACCI8 0xf47e01ff
+
+/*P1_EQUAQ8*/
+#define R0900_P1_EQUAQ8 0xf47f
+#define F0900_P1_EQUA_ACCQ8 0xf47f01ff
+
+/*P1_NNOSDATAT1*/
+#define R0900_P1_NNOSDATAT1 0xf480
+#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff
+
+/*P1_NNOSDATAT0*/
+#define R0900_P1_NNOSDATAT0 0xf481
+#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff
+
+/*P1_NNOSDATA1*/
+#define R0900_P1_NNOSDATA1 0xf482
+#define F0900_P1_NOSDATA_NORMED1 0xf48200ff
+
+/*P1_NNOSDATA0*/
+#define R0900_P1_NNOSDATA0 0xf483
+#define F0900_P1_NOSDATA_NORMED0 0xf48300ff
+
+/*P1_NNOSPLHT1*/
+#define R0900_P1_NNOSPLHT1 0xf484
+#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff
+
+/*P1_NNOSPLHT0*/
+#define R0900_P1_NNOSPLHT0 0xf485
+#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff
+
+/*P1_NNOSPLH1*/
+#define R0900_P1_NNOSPLH1 0xf486
+#define F0900_P1_NOSPLH_NORMED1 0xf48600ff
+
+/*P1_NNOSPLH0*/
+#define R0900_P1_NNOSPLH0 0xf487
+#define F0900_P1_NOSPLH_NORMED0 0xf48700ff
+
+/*P1_NOSDATAT1*/
+#define R0900_P1_NOSDATAT1 0xf488
+#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff
+
+/*P1_NOSDATAT0*/
+#define R0900_P1_NOSDATAT0 0xf489
+#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff
+
+/*P1_NOSDATA1*/
+#define R0900_P1_NOSDATA1 0xf48a
+#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff
+
+/*P1_NOSDATA0*/
+#define R0900_P1_NOSDATA0 0xf48b
+#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff
+
+/*P1_NOSPLHT1*/
+#define R0900_P1_NOSPLHT1 0xf48c
+#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff
+
+/*P1_NOSPLHT0*/
+#define R0900_P1_NOSPLHT0 0xf48d
+#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff
+
+/*P1_NOSPLH1*/
+#define R0900_P1_NOSPLH1 0xf48e
+#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff
+
+/*P1_NOSPLH0*/
+#define R0900_P1_NOSPLH0 0xf48f
+#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff
+
+/*P1_CAR2CFG*/
+#define R0900_P1_CAR2CFG 0xf490
+#define F0900_P1_DESCRAMB_OFF 0xf4900080
+#define F0900_P1_PN4_SELECT 0xf4900040
+#define F0900_P1_CFR2_STOPDVBS1 0xf4900020
+#define F0900_P1_STOP_CFR2UPDATE 0xf4900010
+#define F0900_P1_STOP_NCO2UPDATE 0xf4900008
+#define F0900_P1_ROTA2ON 0xf4900004
+#define F0900_P1_PH_DET_ALGO2 0xf4900003
+
+/*P1_ACLC2*/
+#define R0900_P1_ACLC2 0xf491
+#define F0900_P1_CAR2_PUNCT_ADERAT 0xf4910040
+#define F0900_P1_CAR2_ALPHA_MANT 0xf4910030
+#define F0900_P1_CAR2_ALPHA_EXP 0xf491000f
+
+/*P1_BCLC2*/
+#define R0900_P1_BCLC2 0xf492
+#define F0900_P1_DVBS2_NIP 0xf4920080
+#define F0900_P1_CAR2_PUNCT_BDERAT 0xf4920040
+#define F0900_P1_CAR2_BETA_MANT 0xf4920030
+#define F0900_P1_CAR2_BETA_EXP 0xf492000f
+
+/*P1_CFR22*/
+#define R0900_P1_CFR22 0xf493
+#define F0900_P1_CAR2_FREQ2 0xf49301ff
+
+/*P1_CFR21*/
+#define R0900_P1_CFR21 0xf494
+#define F0900_P1_CAR2_FREQ1 0xf49400ff
+
+/*P1_CFR20*/
+#define R0900_P1_CFR20 0xf495
+#define F0900_P1_CAR2_FREQ0 0xf49500ff
+
+/*P1_ACLC2S2Q*/
+#define R0900_P1_ACLC2S2Q 0xf497
+#define F0900_P1_ENAB_SPSKSYMB 0xf4970080
+#define F0900_P1_CAR2S2_QADERAT 0xf4970040
+#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030
+#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f
+
+/*P1_ACLC2S28*/
+#define R0900_P1_ACLC2S28 0xf498
+#define F0900_P1_OLDI3Q_MODE 0xf4980080
+#define F0900_P1_CAR2S2_8ADERAT 0xf4980040
+#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030
+#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f
+
+/*P1_ACLC2S216A*/
+#define R0900_P1_ACLC2S216A 0xf499
+#define F0900_P1_CAR2S2_16ADERAT 0xf4990040
+#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030
+#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f
+
+/*P1_ACLC2S232A*/
+#define R0900_P1_ACLC2S232A 0xf49a
+#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040
+#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030
+#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f
+
+/*P1_BCLC2S2Q*/
+#define R0900_P1_BCLC2S2Q 0xf49c
+#define F0900_P1_DVBS2S2Q_NIP 0xf49c0080
+#define F0900_P1_CAR2S2_QBDERAT 0xf49c0040
+#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030
+#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f
+
+/*P1_BCLC2S28*/
+#define R0900_P1_BCLC2S28 0xf49d
+#define F0900_P1_DVBS2S28_NIP 0xf49d0080
+#define F0900_P1_CAR2S2_8BDERAT 0xf49d0040
+#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030
+#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f
+
+/*P1_BCLC2S216A*/
+#define R0900_P1_BCLC2S216A 0xf49e
+#define F0900_P1_DVBS2S216A_NIP 0xf49e0080
+#define F0900_P1_CAR2S2_16BDERAT 0xf49e0040
+#define F0900_P1_CAR2S2_16A_BETA_M 0xf49e0030
+#define F0900_P1_CAR2S2_16A_BETA_E 0xf49e000f
+
+/*P1_BCLC2S232A*/
+#define R0900_P1_BCLC2S232A 0xf49f
+#define F0900_P1_DVBS2S232A_NIP 0xf49f0080
+#define F0900_P1_CAR2S2_32BDERAT 0xf49f0040
+#define F0900_P1_CAR2S2_32A_BETA_M 0xf49f0030
+#define F0900_P1_CAR2S2_32A_BETA_E 0xf49f000f
+
+/*P1_PLROOT2*/
+#define R0900_P1_PLROOT2 0xf4ac
+#define F0900_P1_SHORTFR_DISABLE 0xf4ac0080
+#define F0900_P1_LONGFR_DISABLE 0xf4ac0040
+#define F0900_P1_DUMMYPL_DISABLE 0xf4ac0020
+#define F0900_P1_SHORTFR_AVOID 0xf4ac0010
+#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c
+#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003
+
+/*P1_PLROOT1*/
+#define R0900_P1_PLROOT1 0xf4ad
+#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff
+
+/*P1_PLROOT0*/
+#define R0900_P1_PLROOT0 0xf4ae
+#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff
+
+/*P1_MODCODLST0*/
+#define R0900_P1_MODCODLST0 0xf4b0
+#define F0900_P1_EN_TOKEN31 0xf4b00080
+#define F0900_P1_SYNCTAG_SELECT 0xf4b00040
+#define F0900_P1_MODCODRQ_MODE 0xf4b00030
+
+/*P1_MODCODLST1*/
+#define R0900_P1_MODCODLST1 0xf4b1
+#define F0900_P1_DIS_MODCOD29 0xf4b100f0
+#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f
+
+/*P1_MODCODLST2*/
+#define R0900_P1_MODCODLST2 0xf4b2
+#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0
+#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f
+
+/*P1_MODCODLST3*/
+#define R0900_P1_MODCODLST3 0xf4b3
+#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0
+#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f
+
+/*P1_MODCODLST4*/
+#define R0900_P1_MODCODLST4 0xf4b4
+#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0
+#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f
+
+/*P1_MODCODLST5*/
+#define R0900_P1_MODCODLST5 0xf4b5
+#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0
+#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f
+
+/*P1_MODCODLST6*/
+#define R0900_P1_MODCODLST6 0xf4b6
+#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0
+#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f
+
+/*P1_MODCODLST7*/
+#define R0900_P1_MODCODLST7 0xf4b7
+#define F0900_P1_DIS_8P_9_10 0xf4b700f0
+#define F0900_P1_DIS_8P_8_9 0xf4b7000f
+
+/*P1_MODCODLST8*/
+#define R0900_P1_MODCODLST8 0xf4b8
+#define F0900_P1_DIS_8P_5_6 0xf4b800f0
+#define F0900_P1_DIS_8P_3_4 0xf4b8000f
+
+/*P1_MODCODLST9*/
+#define R0900_P1_MODCODLST9 0xf4b9
+#define F0900_P1_DIS_8P_2_3 0xf4b900f0
+#define F0900_P1_DIS_8P_3_5 0xf4b9000f
+
+/*P1_MODCODLSTA*/
+#define R0900_P1_MODCODLSTA 0xf4ba
+#define F0900_P1_DIS_QP_9_10 0xf4ba00f0
+#define F0900_P1_DIS_QP_8_9 0xf4ba000f
+
+/*P1_MODCODLSTB*/
+#define R0900_P1_MODCODLSTB 0xf4bb
+#define F0900_P1_DIS_QP_5_6 0xf4bb00f0
+#define F0900_P1_DIS_QP_4_5 0xf4bb000f
+
+/*P1_MODCODLSTC*/
+#define R0900_P1_MODCODLSTC 0xf4bc
+#define F0900_P1_DIS_QP_3_4 0xf4bc00f0
+#define F0900_P1_DIS_QP_2_3 0xf4bc000f
+
+/*P1_MODCODLSTD*/
+#define R0900_P1_MODCODLSTD 0xf4bd
+#define F0900_P1_DIS_QP_3_5 0xf4bd00f0
+#define F0900_P1_DIS_QP_1_2 0xf4bd000f
+
+/*P1_MODCODLSTE*/
+#define R0900_P1_MODCODLSTE 0xf4be
+#define F0900_P1_DIS_QP_2_5 0xf4be00f0
+#define F0900_P1_DIS_QP_1_3 0xf4be000f
+
+/*P1_MODCODLSTF*/
+#define R0900_P1_MODCODLSTF 0xf4bf
+#define F0900_P1_DIS_QP_1_4 0xf4bf00f0
+#define F0900_P1_DDEMOD_SET 0xf4bf0002
+#define F0900_P1_DDEMOD_MASK 0xf4bf0001
+
+/*P1_DMDRESCFG*/
+#define R0900_P1_DMDRESCFG 0xf4c6
+#define F0900_P1_DMDRES_RESET 0xf4c60080
+#define F0900_P1_DMDRES_NOISESQR 0xf4c60010
+#define F0900_P1_DMDRES_STRALL 0xf4c60008
+#define F0900_P1_DMDRES_NEWONLY 0xf4c60004
+#define F0900_P1_DMDRES_NOSTORE 0xf4c60002
+#define F0900_P1_DMDRES_AGC2MEM 0xf4c60001
+
+/*P1_DMDRESADR*/
+#define R0900_P1_DMDRESADR 0xf4c7
+#define F0900_P1_SUSP_PREDCANAL 0xf4c70080
+#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040
+#define F0900_P1_DMDRES_MEMFULL 0xf4c70030
+#define F0900_P1_DMDRES_RESNBR 0xf4c7000f
+
+/*P1_DMDRESDATA7*/
+#define R0900_P1_DMDRESDATA7 0xf4c8
+#define F0900_P1_DMDRES_DATA7 0xf4c800ff
+
+/*P1_DMDRESDATA6*/
+#define R0900_P1_DMDRESDATA6 0xf4c9
+#define F0900_P1_DMDRES_DATA6 0xf4c900ff
+
+/*P1_DMDRESDATA5*/
+#define R0900_P1_DMDRESDATA5 0xf4ca
+#define F0900_P1_DMDRES_DATA5 0xf4ca00ff
+
+/*P1_DMDRESDATA4*/
+#define R0900_P1_DMDRESDATA4 0xf4cb
+#define F0900_P1_DMDRES_DATA4 0xf4cb00ff
+
+/*P1_DMDRESDATA3*/
+#define R0900_P1_DMDRESDATA3 0xf4cc
+#define F0900_P1_DMDRES_DATA3 0xf4cc00ff
+
+/*P1_DMDRESDATA2*/
+#define R0900_P1_DMDRESDATA2 0xf4cd
+#define F0900_P1_DMDRES_DATA2 0xf4cd00ff
+
+/*P1_DMDRESDATA1*/
+#define R0900_P1_DMDRESDATA1 0xf4ce
+#define F0900_P1_DMDRES_DATA1 0xf4ce00ff
+
+/*P1_DMDRESDATA0*/
+#define R0900_P1_DMDRESDATA0 0xf4cf
+#define F0900_P1_DMDRES_DATA0 0xf4cf00ff
+
+/*P1_FFEI1*/
+#define R0900_P1_FFEI1 0xf4d0
+#define F0900_P1_FFE_ACCI1 0xf4d001ff
+
+/*P1_FFEQ1*/
+#define R0900_P1_FFEQ1 0xf4d1
+#define F0900_P1_FFE_ACCQ1 0xf4d101ff
+
+/*P1_FFEI2*/
+#define R0900_P1_FFEI2 0xf4d2
+#define F0900_P1_FFE_ACCI2 0xf4d201ff
+
+/*P1_FFEQ2*/
+#define R0900_P1_FFEQ2 0xf4d3
+#define F0900_P1_FFE_ACCQ2 0xf4d301ff
+
+/*P1_FFEI3*/
+#define R0900_P1_FFEI3 0xf4d4
+#define F0900_P1_FFE_ACCI3 0xf4d401ff
+
+/*P1_FFEQ3*/
+#define R0900_P1_FFEQ3 0xf4d5
+#define F0900_P1_FFE_ACCQ3 0xf4d501ff
+
+/*P1_FFEI4*/
+#define R0900_P1_FFEI4 0xf4d6
+#define F0900_P1_FFE_ACCI4 0xf4d601ff
+
+/*P1_FFEQ4*/
+#define R0900_P1_FFEQ4 0xf4d7
+#define F0900_P1_FFE_ACCQ4 0xf4d701ff
+
+/*P1_FFECFG*/
+#define R0900_P1_FFECFG 0xf4d8
+#define F0900_P1_EQUALFFE_ON 0xf4d80040
+#define F0900_P1_EQUAL_USEDSYMB 0xf4d80030
+#define F0900_P1_MU_EQUALFFE 0xf4d80007
+
+/*P1_TNRCFG*/
+#define R0900_P1_TNRCFG 0xf4e0
+#define F0900_P1_TUN_ACKFAIL 0xf4e00080
+#define F0900_P1_TUN_TYPE 0xf4e00070
+#define F0900_P1_TUN_SECSTOP 0xf4e00008
+#define F0900_P1_TUN_VCOSRCH 0xf4e00004
+#define F0900_P1_TUN_MADDRESS 0xf4e00003
+
+/*P1_TNRCFG2*/
+#define R0900_P1_TNRCFG2 0xf4e1
+#define F0900_P1_TUN_IQSWAP 0xf4e10080
+#define F0900_P1_STB6110_STEP2MHZ 0xf4e10040
+#define F0900_P1_STB6120_DBLI2C 0xf4e10020
+#define F0900_P1_DIS_FCCK 0xf4e10010
+#define F0900_P1_DIS_LPEN 0xf4e10008
+#define F0900_P1_DIS_BWCALC 0xf4e10004
+#define F0900_P1_SHORT_WAITSTATES 0xf4e10002
+#define F0900_P1_DIS_2BWAGC1 0xf4e10001
+
+/*P1_TNRXTAL*/
+#define R0900_P1_TNRXTAL 0xf4e4
+#define F0900_P1_TUN_MCLKDECIMAL 0xf4e400e0
+#define F0900_P1_TUN_XTALFREQ 0xf4e4001f
+
+/*P1_TNRSTEPS*/
+#define R0900_P1_TNRSTEPS 0xf4e7
+#define F0900_P1_TUNER_BW1P6 0xf4e70080
+#define F0900_P1_BWINC_OFFSET 0xf4e70070
+#define F0900_P1_SOFTSTEP_RNG 0xf4e70008
+#define F0900_P1_TUN_BWOFFSET 0xf4e70107
+
+/*P1_TNRGAIN*/
+#define R0900_P1_TNRGAIN 0xf4e8
+#define F0900_P1_TUN_KDIVEN 0xf4e800c0
+#define F0900_P1_STB6X00_OCK 0xf4e80030
+#define F0900_P1_TUN_GAIN 0xf4e8000f
+
+/*P1_TNRRF1*/
+#define R0900_P1_TNRRF1 0xf4e9
+#define F0900_P1_TUN_RFFREQ2 0xf4e900ff
+
+/*P1_TNRRF0*/
+#define R0900_P1_TNRRF0 0xf4ea
+#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff
+
+/*P1_TNRBW*/
+#define R0900_P1_TNRBW 0xf4eb
+#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0
+#define F0900_P1_TUN_BW 0xf4eb003f
+
+/*P1_TNRADJ*/
+#define R0900_P1_TNRADJ 0xf4ec
+#define F0900_P1_STB61X0_RCLK 0xf4ec0080
+#define F0900_P1_STB61X0_CALTIME 0xf4ec0040
+#define F0900_P1_STB6X00_DLB 0xf4ec0038
+#define F0900_P1_STB6000_FCL 0xf4ec0007
+
+/*P1_TNRCTL2*/
+#define R0900_P1_TNRCTL2 0xf4ed
+#define F0900_P1_STB61X0_LCP1_RCCKOFF 0xf4ed0080
+#define F0900_P1_STB61X0_LCP0 0xf4ed0040
+#define F0900_P1_STB61X0_XTOUT_RFOUTS 0xf4ed0020
+#define F0900_P1_STB61X0_XTON_MCKDV 0xf4ed0010
+#define F0900_P1_STB61X0_CALOFF_DCOFF 0xf4ed0008
+#define F0900_P1_STB6110_LPT 0xf4ed0004
+#define F0900_P1_STB6110_RX 0xf4ed0002
+#define F0900_P1_STB6110_SYN 0xf4ed0001
+
+/*P1_TNRCFG3*/
+#define R0900_P1_TNRCFG3 0xf4ee
+#define F0900_P1_STB6120_DISCTRL1 0xf4ee0080
+#define F0900_P1_STB6120_INVORDER 0xf4ee0040
+#define F0900_P1_STB6120_ENCTRL6 0xf4ee0020
+#define F0900_P1_TUN_PLLFREQ 0xf4ee001c
+#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003
+
+/*P1_TNRLAUNCH*/
+#define R0900_P1_TNRLAUNCH 0xf4f0
+
+/*P1_TNRLD*/
+#define R0900_P1_TNRLD 0xf4f0
+#define F0900_P1_TUNLD_VCOING 0xf4f00080
+#define F0900_P1_TUN_REG1FAIL 0xf4f00040
+#define F0900_P1_TUN_REG2FAIL 0xf4f00020
+#define F0900_P1_TUN_REG3FAIL 0xf4f00010
+#define F0900_P1_TUN_REG4FAIL 0xf4f00008
+#define F0900_P1_TUN_REG5FAIL 0xf4f00004
+#define F0900_P1_TUN_BWING 0xf4f00002
+#define F0900_P1_TUN_LOCKED 0xf4f00001
+
+/*P1_TNROBSL*/
+#define R0900_P1_TNROBSL 0xf4f6
+#define F0900_P1_TUN_I2CABORTED 0xf4f60080
+#define F0900_P1_TUN_LPEN 0xf4f60040
+#define F0900_P1_TUN_FCCK 0xf4f60020
+#define F0900_P1_TUN_I2CLOCKED 0xf4f60010
+#define F0900_P1_TUN_PROGDONE 0xf4f6000c
+#define F0900_P1_TUN_RFRESTE1 0xf4f60003
+
+/*P1_TNRRESTE*/
+#define R0900_P1_TNRRESTE 0xf4f7
+#define F0900_P1_TUN_RFRESTE0 0xf4f700ff
+
+/*P1_SMAPCOEF7*/
+#define R0900_P1_SMAPCOEF7 0xf500
+#define F0900_P1_DIS_QSCALE 0xf5000080
+#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f
+
+/*P1_SMAPCOEF6*/
+#define R0900_P1_SMAPCOEF6 0xf501
+#define F0900_P1_DIS_NEWSCALE 0xf5010008
+#define F0900_P1_ADJ_8PSKLLR1 0xf5010004
+#define F0900_P1_OLD_8PSKLLR1 0xf5010002
+#define F0900_P1_DIS_AB8PSK 0xf5010001
+
+/*P1_SMAPCOEF5*/
+#define R0900_P1_SMAPCOEF5 0xf502
+#define F0900_P1_DIS_8SCALE 0xf5020080
+#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f
+
+/*P1_DMDPLHSTAT*/
+#define R0900_P1_DMDPLHSTAT 0xf520
+#define F0900_P1_PLH_STATISTIC 0xf52000ff
+
+/*P1_LOCKTIME3*/
+#define R0900_P1_LOCKTIME3 0xf522
+#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff
+
+/*P1_LOCKTIME2*/
+#define R0900_P1_LOCKTIME2 0xf523
+#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff
+
+/*P1_LOCKTIME1*/
+#define R0900_P1_LOCKTIME1 0xf524
+#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff
+
+/*P1_LOCKTIME0*/
+#define R0900_P1_LOCKTIME0 0xf525
+#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff
+
+/*P1_VITSCALE*/
+#define R0900_P1_VITSCALE 0xf532
+#define F0900_P1_NVTH_NOSRANGE 0xf5320080
+#define F0900_P1_VERROR_MAXMODE 0xf5320040
+#define F0900_P1_KDIV_MODE 0xf5320030
+#define F0900_P1_NSLOWSN_LOCKED 0xf5320008
+#define F0900_P1_DELOCK_PRFLOSS 0xf5320004
+#define F0900_P1_DIS_RSFLOCK 0xf5320002
+
+/*P1_FECM*/
+#define R0900_P1_FECM 0xf533
+#define F0900_P1_DSS_DVB 0xf5330080
+#define F0900_P1_DEMOD_BYPASS 0xf5330040
+#define F0900_P1_CMP_SLOWMODE 0xf5330020
+#define F0900_P1_DSS_SRCH 0xf5330010
+#define F0900_P1_DIFF_MODEVIT 0xf5330004
+#define F0900_P1_SYNCVIT 0xf5330002
+#define F0900_P1_IQINV 0xf5330001
+
+/*P1_VTH12*/
+#define R0900_P1_VTH12 0xf534
+#define F0900_P1_VTH12 0xf53400ff
+
+/*P1_VTH23*/
+#define R0900_P1_VTH23 0xf535
+#define F0900_P1_VTH23 0xf53500ff
+
+/*P1_VTH34*/
+#define R0900_P1_VTH34 0xf536
+#define F0900_P1_VTH34 0xf53600ff
+
+/*P1_VTH56*/
+#define R0900_P1_VTH56 0xf537
+#define F0900_P1_VTH56 0xf53700ff
+
+/*P1_VTH67*/
+#define R0900_P1_VTH67 0xf538
+#define F0900_P1_VTH67 0xf53800ff
+
+/*P1_VTH78*/
+#define R0900_P1_VTH78 0xf539
+#define F0900_P1_VTH78 0xf53900ff
+
+/*P1_VITCURPUN*/
+#define R0900_P1_VITCURPUN 0xf53a
+#define F0900_P1_VIT_MAPPING 0xf53a00e0
+#define F0900_P1_VIT_CURPUN 0xf53a001f
+
+/*P1_VERROR*/
+#define R0900_P1_VERROR 0xf53b
+#define F0900_P1_REGERR_VIT 0xf53b00ff
+
+/*P1_PRVIT*/
+#define R0900_P1_PRVIT 0xf53c
+#define F0900_P1_DIS_VTHLOCK 0xf53c0040
+#define F0900_P1_E7_8VIT 0xf53c0020
+#define F0900_P1_E6_7VIT 0xf53c0010
+#define F0900_P1_E5_6VIT 0xf53c0008
+#define F0900_P1_E3_4VIT 0xf53c0004
+#define F0900_P1_E2_3VIT 0xf53c0002
+#define F0900_P1_E1_2VIT 0xf53c0001
+
+/*P1_VAVSRVIT*/
+#define R0900_P1_VAVSRVIT 0xf53d
+#define F0900_P1_AMVIT 0xf53d0080
+#define F0900_P1_FROZENVIT 0xf53d0040
+#define F0900_P1_SNVIT 0xf53d0030
+#define F0900_P1_TOVVIT 0xf53d000c
+#define F0900_P1_HYPVIT 0xf53d0003
+
+/*P1_VSTATUSVIT*/
+#define R0900_P1_VSTATUSVIT 0xf53e
+#define F0900_P1_VITERBI_ON 0xf53e0080
+#define F0900_P1_END_LOOPVIT 0xf53e0040
+#define F0900_P1_VITERBI_DEPRF 0xf53e0020
+#define F0900_P1_PRFVIT 0xf53e0010
+#define F0900_P1_LOCKEDVIT 0xf53e0008
+#define F0900_P1_VITERBI_DELOCK 0xf53e0004
+#define F0900_P1_VIT_DEMODSEL 0xf53e0002
+#define F0900_P1_VITERBI_COMPOUT 0xf53e0001
+
+/*P1_VTHINUSE*/
+#define R0900_P1_VTHINUSE 0xf53f
+#define F0900_P1_VIT_INUSE 0xf53f00ff
+
+/*P1_KDIV12*/
+#define R0900_P1_KDIV12 0xf540
+#define F0900_P1_KDIV12_MANUAL 0xf5400080
+#define F0900_P1_K_DIVIDER_12 0xf540007f
+
+/*P1_KDIV23*/
+#define R0900_P1_KDIV23 0xf541
+#define F0900_P1_KDIV23_MANUAL 0xf5410080
+#define F0900_P1_K_DIVIDER_23 0xf541007f
+
+/*P1_KDIV34*/
+#define R0900_P1_KDIV34 0xf542
+#define F0900_P1_KDIV34_MANUAL 0xf5420080
+#define F0900_P1_K_DIVIDER_34 0xf542007f
+
+/*P1_KDIV56*/
+#define R0900_P1_KDIV56 0xf543
+#define F0900_P1_KDIV56_MANUAL 0xf5430080
+#define F0900_P1_K_DIVIDER_56 0xf543007f
+
+/*P1_KDIV67*/
+#define R0900_P1_KDIV67 0xf544
+#define F0900_P1_KDIV67_MANUAL 0xf5440080
+#define F0900_P1_K_DIVIDER_67 0xf544007f
+
+/*P1_KDIV78*/
+#define R0900_P1_KDIV78 0xf545
+#define F0900_P1_KDIV78_MANUAL 0xf5450080
+#define F0900_P1_K_DIVIDER_78 0xf545007f
+
+/*P1_PDELCTRL1*/
+#define R0900_P1_PDELCTRL1 0xf550
+#define F0900_P1_INV_MISMASK 0xf5500080
+#define F0900_P1_FORCE_ACCEPTED 0xf5500040
+#define F0900_P1_FILTER_EN 0xf5500020
+#define F0900_P1_FORCE_PKTDELINUSE 0xf5500010
+#define F0900_P1_HYSTEN 0xf5500008
+#define F0900_P1_HYSTSWRST 0xf5500004
+#define F0900_P1_EN_MIS00 0xf5500002
+#define F0900_P1_ALGOSWRST 0xf5500001
+
+/*P1_PDELCTRL2*/
+#define R0900_P1_PDELCTRL2 0xf551
+#define F0900_P1_FORCE_CONTINUOUS 0xf5510080
+#define F0900_P1_RESET_UPKO_COUNT 0xf5510040
+#define F0900_P1_USER_PKTDELIN_NB 0xf5510020
+#define F0900_P1_FORCE_LOCKED 0xf5510010
+#define F0900_P1_DATA_UNBBSCRAM 0xf5510008
+#define F0900_P1_FORCE_LONGPKT 0xf5510004
+#define F0900_P1_FRAME_MODE 0xf5510002
+
+/*P1_HYSTTHRESH*/
+#define R0900_P1_HYSTTHRESH 0xf554
+#define F0900_P1_UNLCK_THRESH 0xf55400f0
+#define F0900_P1_DELIN_LCK_THRESH 0xf554000f
+
+/*P1_ISIENTRY*/
+#define R0900_P1_ISIENTRY 0xf55e
+#define F0900_P1_ISI_ENTRY 0xf55e00ff
+
+/*P1_ISIBITENA*/
+#define R0900_P1_ISIBITENA 0xf55f
+#define F0900_P1_ISI_BIT_EN 0xf55f00ff
+
+/*P1_MATSTR1*/
+#define R0900_P1_MATSTR1 0xf560
+#define F0900_P1_MATYPE_CURRENT1 0xf56000ff
+
+/*P1_MATSTR0*/
+#define R0900_P1_MATSTR0 0xf561
+#define F0900_P1_MATYPE_CURRENT0 0xf56100ff
+
+/*P1_UPLSTR1*/
+#define R0900_P1_UPLSTR1 0xf562
+#define F0900_P1_UPL_CURRENT1 0xf56200ff
+
+/*P1_UPLSTR0*/
+#define R0900_P1_UPLSTR0 0xf563
+#define F0900_P1_UPL_CURRENT0 0xf56300ff
+
+/*P1_DFLSTR1*/
+#define R0900_P1_DFLSTR1 0xf564
+#define F0900_P1_DFL_CURRENT1 0xf56400ff
+
+/*P1_DFLSTR0*/
+#define R0900_P1_DFLSTR0 0xf565
+#define F0900_P1_DFL_CURRENT0 0xf56500ff
+
+/*P1_SYNCSTR*/
+#define R0900_P1_SYNCSTR 0xf566
+#define F0900_P1_SYNC_CURRENT 0xf56600ff
+
+/*P1_SYNCDSTR1*/
+#define R0900_P1_SYNCDSTR1 0xf567
+#define F0900_P1_SYNCD_CURRENT1 0xf56700ff
+
+/*P1_SYNCDSTR0*/
+#define R0900_P1_SYNCDSTR0 0xf568
+#define F0900_P1_SYNCD_CURRENT0 0xf56800ff
+
+/*P1_PDELSTATUS1*/
+#define R0900_P1_PDELSTATUS1 0xf569
+#define F0900_P1_PKTDELIN_DELOCK 0xf5690080
+#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040
+#define F0900_P1_CONTINUOUS_STREAM 0xf5690020
+#define F0900_P1_UNACCEPTED_STREAM 0xf5690010
+#define F0900_P1_BCH_ERROR_FLAG 0xf5690008
+#define F0900_P1_BBHCRCKO 0xf5690004
+#define F0900_P1_PKTDELIN_LOCK 0xf5690002
+#define F0900_P1_FIRST_LOCK 0xf5690001
+
+/*P1_PDELSTATUS2*/
+#define R0900_P1_PDELSTATUS2 0xf56a
+#define F0900_P1_PKTDEL_DEMODSEL 0xf56a0080
+#define F0900_P1_FRAME_MODCOD 0xf56a007c
+#define F0900_P1_FRAME_TYPE 0xf56a0003
+
+/*P1_BBFCRCKO1*/
+#define R0900_P1_BBFCRCKO1 0xf56b
+#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff
+
+/*P1_BBFCRCKO0*/
+#define R0900_P1_BBFCRCKO0 0xf56c
+#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff
+
+/*P1_UPCRCKO1*/
+#define R0900_P1_UPCRCKO1 0xf56d
+#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff
+
+/*P1_UPCRCKO0*/
+#define R0900_P1_UPCRCKO0 0xf56e
+#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff
+
+/*P1_TSSTATEM*/
+#define R0900_P1_TSSTATEM 0xf570
+#define F0900_P1_TSDIL_ON 0xf5700080
+#define F0900_P1_TSSKIPRS_ON 0xf5700040
+#define F0900_P1_TSRS_ON 0xf5700020
+#define F0900_P1_TSDESCRAMB_ON 0xf5700010
+#define F0900_P1_TSFRAME_MODE 0xf5700008
+#define F0900_P1_TS_DISABLE 0xf5700004
+#define F0900_P1_TSACM_MODE 0xf5700002
+#define F0900_P1_TSOUT_NOSYNC 0xf5700001
+
+/*P1_TSCFGH*/
+#define R0900_P1_TSCFGH 0xf572
+#define F0900_P1_TSFIFO_DVBCI 0xf5720080
+#define F0900_P1_TSFIFO_SERIAL 0xf5720040
+#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020
+#define F0900_P1_TSFIFO_DUTY50 0xf5720010
+#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008
+#define F0900_P1_TSFIFO_ERRMODE 0xf5720006
+#define F0900_P1_RST_HWARE 0xf5720001
+
+/*P1_TSCFGM*/
+#define R0900_P1_TSCFGM 0xf573
+#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0
+#define F0900_P1_TSFIFO_PERMDATA 0xf5730020
+#define F0900_P1_TSFIFO_NONEWSGNL 0xf5730010
+#define F0900_P1_TSFIFO_BITSPEED 0xf5730008
+#define F0900_P1_NPD_SPECDVBS2 0xf5730004
+#define F0900_P1_TSFIFO_STOPCKDIS 0xf5730002
+#define F0900_P1_TSFIFO_INVDATA 0xf5730001
+
+/*P1_TSCFGL*/
+#define R0900_P1_TSCFGL 0xf574
+#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0
+#define F0900_P1_BCHERROR_MODE 0xf5740030
+#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008
+#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004
+#define F0900_P1_TSFIFO_DPUNACT 0xf5740002
+#define F0900_P1_TSFIFO_NPDOFF 0xf5740001
+
+/*P1_TSINSDELH*/
+#define R0900_P1_TSINSDELH 0xf576
+#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080
+#define F0900_P1_TSDEL_XXHEADER 0xf5760040
+#define F0900_P1_TSDEL_BBHEADER 0xf5760020
+#define F0900_P1_TSDEL_DATAFIELD 0xf5760010
+#define F0900_P1_TSINSDEL_ISCR 0xf5760008
+#define F0900_P1_TSINSDEL_NPD 0xf5760004
+#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002
+#define F0900_P1_TSINSDEL_CRC8 0xf5760001
+
+/*P1_TSSPEED*/
+#define R0900_P1_TSSPEED 0xf580
+#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff
+
+/*P1_TSSTATUS*/
+#define R0900_P1_TSSTATUS 0xf581
+#define F0900_P1_TSFIFO_LINEOK 0xf5810080
+#define F0900_P1_TSFIFO_ERROR 0xf5810040
+#define F0900_P1_TSFIFO_DATA7 0xf5810020
+#define F0900_P1_TSFIFO_NOSYNC 0xf5810010
+#define F0900_P1_ISCR_INITIALIZED 0xf5810008
+#define F0900_P1_ISCR_UPDATED 0xf5810004
+#define F0900_P1_SOFFIFO_UNREGUL 0xf5810002
+#define F0900_P1_DIL_READY 0xf5810001
+
+/*P1_TSSTATUS2*/
+#define R0900_P1_TSSTATUS2 0xf582
+#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080
+#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040
+#define F0900_P1_DILXX_RESET 0xf5820020
+#define F0900_P1_TSSERIAL_IMPOS 0xf5820010
+#define F0900_P1_TSFIFO_LINENOK 0xf5820008
+#define F0900_P1_BITSPEED_EVENT 0xf5820004
+#define F0900_P1_SCRAMBDETECT 0xf5820002
+#define F0900_P1_ULDTV67_FALSELOCK 0xf5820001
+
+/*P1_TSBITRATE1*/
+#define R0900_P1_TSBITRATE1 0xf583
+#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff
+
+/*P1_TSBITRATE0*/
+#define R0900_P1_TSBITRATE0 0xf584
+#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff
+
+/*P1_ERRCTRL1*/
+#define R0900_P1_ERRCTRL1 0xf598
+#define F0900_P1_ERR_SOURCE1 0xf59800f0
+#define F0900_P1_NUM_EVENT1 0xf5980007
+
+/*P1_ERRCNT12*/
+#define R0900_P1_ERRCNT12 0xf599
+#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080
+#define F0900_P1_ERR_CNT12 0xf599007f
+
+/*P1_ERRCNT11*/
+#define R0900_P1_ERRCNT11 0xf59a
+#define F0900_P1_ERR_CNT11 0xf59a00ff
+
+/*P1_ERRCNT10*/
+#define R0900_P1_ERRCNT10 0xf59b
+#define F0900_P1_ERR_CNT10 0xf59b00ff
+
+/*P1_ERRCTRL2*/
+#define R0900_P1_ERRCTRL2 0xf59c
+#define F0900_P1_ERR_SOURCE2 0xf59c00f0
+#define F0900_P1_NUM_EVENT2 0xf59c0007
+
+/*P1_ERRCNT22*/
+#define R0900_P1_ERRCNT22 0xf59d
+#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080
+#define F0900_P1_ERR_CNT22 0xf59d007f
+
+/*P1_ERRCNT21*/
+#define R0900_P1_ERRCNT21 0xf59e
+#define F0900_P1_ERR_CNT21 0xf59e00ff
+
+/*P1_ERRCNT20*/
+#define R0900_P1_ERRCNT20 0xf59f
+#define F0900_P1_ERR_CNT20 0xf59f00ff
+
+/*P1_FECSPY*/
+#define R0900_P1_FECSPY 0xf5a0
+#define F0900_P1_SPY_ENABLE 0xf5a00080
+#define F0900_P1_NO_SYNCBYTE 0xf5a00040
+#define F0900_P1_SERIAL_MODE 0xf5a00020
+#define F0900_P1_UNUSUAL_PACKET 0xf5a00010
+#define F0900_P1_BER_PACKMODE 0xf5a00008
+#define F0900_P1_BERMETER_LMODE 0xf5a00002
+#define F0900_P1_BERMETER_RESET 0xf5a00001
+
+/*P1_FSPYCFG*/
+#define R0900_P1_FSPYCFG 0xf5a1
+#define F0900_P1_FECSPY_INPUT 0xf5a100c0
+#define F0900_P1_RST_ON_ERROR 0xf5a10020
+#define F0900_P1_ONE_SHOT 0xf5a10010
+#define F0900_P1_I2C_MODE 0xf5a1000c
+#define F0900_P1_SPY_HYSTERESIS 0xf5a10003
+
+/*P1_FSPYDATA*/
+#define R0900_P1_FSPYDATA 0xf5a2
+#define F0900_P1_SPY_STUFFING 0xf5a20080
+#define F0900_P1_NOERROR_PKTJITTER 0xf5a20040
+#define F0900_P1_SPY_CNULLPKT 0xf5a20020
+#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f
+
+/*P1_FSPYOUT*/
+#define R0900_P1_FSPYOUT 0xf5a3
+#define F0900_P1_FSPY_DIRECT 0xf5a30080
+#define F0900_P1_SPY_OUTDATA_BUS 0xf5a30038
+#define F0900_P1_STUFF_MODE 0xf5a30007
+
+/*P1_FSTATUS*/
+#define R0900_P1_FSTATUS 0xf5a4
+#define F0900_P1_SPY_ENDSIM 0xf5a40080
+#define F0900_P1_VALID_SIM 0xf5a40040
+#define F0900_P1_FOUND_SIGNAL 0xf5a40020
+#define F0900_P1_DSS_SYNCBYTE 0xf5a40010
+#define F0900_P1_RESULT_STATE 0xf5a4000f
+
+/*P1_FBERCPT4*/
+#define R0900_P1_FBERCPT4 0xf5a8
+#define F0900_P1_FBERMETER_CPT4 0xf5a800ff
+
+/*P1_FBERCPT3*/
+#define R0900_P1_FBERCPT3 0xf5a9
+#define F0900_P1_FBERMETER_CPT3 0xf5a900ff
+
+/*P1_FBERCPT2*/
+#define R0900_P1_FBERCPT2 0xf5aa
+#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff
+
+/*P1_FBERCPT1*/
+#define R0900_P1_FBERCPT1 0xf5ab
+#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff
+
+/*P1_FBERCPT0*/
+#define R0900_P1_FBERCPT0 0xf5ac
+#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff
+
+/*P1_FBERERR2*/
+#define R0900_P1_FBERERR2 0xf5ad
+#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff
+
+/*P1_FBERERR1*/
+#define R0900_P1_FBERERR1 0xf5ae
+#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff
+
+/*P1_FBERERR0*/
+#define R0900_P1_FBERERR0 0xf5af
+#define F0900_P1_FBERMETER_ERR0 0xf5af00ff
+
+/*P1_FSPYBER*/
+#define R0900_P1_FSPYBER 0xf5b2
+#define F0900_P1_FSPYOBS_XORREAD 0xf5b20040
+#define F0900_P1_FSPYBER_OBSMODE 0xf5b20020
+#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010
+#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008
+#define F0900_P1_FSPYBER_CTIME 0xf5b20007
+
+/*RCCFGH*/
+#define R0900_RCCFGH 0xf600
+#define F0900_TSRCFIFO_DVBCI 0xf6000080
+#define F0900_TSRCFIFO_SERIAL 0xf6000040
+#define F0900_TSRCFIFO_DISABLE 0xf6000020
+#define F0900_TSFIFO_2TORC 0xf6000010
+#define F0900_TSRCFIFO_HSGNLOUT 0xf6000008
+#define F0900_TSRCFIFO_ERRMODE 0xf6000006
+
+/*TSGENERAL*/
+#define R0900_TSGENERAL 0xf630
+#define F0900_TSFIFO_BCLK1ALL 0xf6300020
+#define F0900_MUXSTREAM_OUTMODE 0xf6300008
+#define F0900_TSFIFO_PERMPARAL 0xf6300006
+#define F0900_RST_REEDSOLO 0xf6300001
+
+/*TSGENERAL1X*/
+#define R0900_TSGENERAL1X 0xf670
+#define F0900_TSFIFO1X_BCLK1ALL 0xf6700020
+#define F0900_MUXSTREAM1X_OUTMODE 0xf6700008
+#define F0900_TSFIFO1X_PERMPARAL 0xf6700006
+#define F0900_RST1X_REEDSOLO 0xf6700001
+
+/*NBITER_NF4*/
+#define R0900_NBITER_NF4 0xfa03
+#define F0900_NBITER_NF_QP_1_2 0xfa0300ff
+
+/*NBITER_NF5*/
+#define R0900_NBITER_NF5 0xfa04
+#define F0900_NBITER_NF_QP_3_5 0xfa0400ff
+
+/*NBITER_NF6*/
+#define R0900_NBITER_NF6 0xfa05
+#define F0900_NBITER_NF_QP_2_3 0xfa0500ff
+
+/*NBITER_NF7*/
+#define R0900_NBITER_NF7 0xfa06
+#define F0900_NBITER_NF_QP_3_4 0xfa0600ff
+
+/*NBITER_NF8*/
+#define R0900_NBITER_NF8 0xfa07
+#define F0900_NBITER_NF_QP_4_5 0xfa0700ff
+
+/*NBITER_NF9*/
+#define R0900_NBITER_NF9 0xfa08
+#define F0900_NBITER_NF_QP_5_6 0xfa0800ff
+
+/*NBITER_NF10*/
+#define R0900_NBITER_NF10 0xfa09
+#define F0900_NBITER_NF_QP_8_9 0xfa0900ff
+
+/*NBITER_NF11*/
+#define R0900_NBITER_NF11 0xfa0a
+#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff
+
+/*NBITER_NF12*/
+#define R0900_NBITER_NF12 0xfa0b
+#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff
+
+/*NBITER_NF13*/
+#define R0900_NBITER_NF13 0xfa0c
+#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff
+
+/*NBITER_NF14*/
+#define R0900_NBITER_NF14 0xfa0d
+#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff
+
+/*NBITER_NF15*/
+#define R0900_NBITER_NF15 0xfa0e
+#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff
+
+/*NBITER_NF16*/
+#define R0900_NBITER_NF16 0xfa0f
+#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff
+
+/*NBITER_NF17*/
+#define R0900_NBITER_NF17 0xfa10
+#define F0900_NBITER_NF_8P_9_10 0xfa1000ff
+
+/*NBITERNOERR*/
+#define R0900_NBITERNOERR 0xfa3f
+#define F0900_NBITER_STOP_CRIT 0xfa3f000f
+
+/*GAINLLR_NF4*/
+#define R0900_GAINLLR_NF4 0xfa43
+#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f
+
+/*GAINLLR_NF5*/
+#define R0900_GAINLLR_NF5 0xfa44
+#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f
+
+/*GAINLLR_NF6*/
+#define R0900_GAINLLR_NF6 0xfa45
+#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f
+
+/*GAINLLR_NF7*/
+#define R0900_GAINLLR_NF7 0xfa46
+#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f
+
+/*GAINLLR_NF8*/
+#define R0900_GAINLLR_NF8 0xfa47
+#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f
+
+/*GAINLLR_NF9*/
+#define R0900_GAINLLR_NF9 0xfa48
+#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f
+
+/*GAINLLR_NF10*/
+#define R0900_GAINLLR_NF10 0xfa49
+#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f
+
+/*GAINLLR_NF11*/
+#define R0900_GAINLLR_NF11 0xfa4a
+#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f
+
+/*GAINLLR_NF12*/
+#define R0900_GAINLLR_NF12 0xfa4b
+#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f
+
+/*GAINLLR_NF13*/
+#define R0900_GAINLLR_NF13 0xfa4c
+#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f
+
+/*GAINLLR_NF14*/
+#define R0900_GAINLLR_NF14 0xfa4d
+#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f
+
+/*GAINLLR_NF15*/
+#define R0900_GAINLLR_NF15 0xfa4e
+#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f
+
+/*GAINLLR_NF16*/
+#define R0900_GAINLLR_NF16 0xfa4f
+#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f
+
+/*GAINLLR_NF17*/
+#define R0900_GAINLLR_NF17 0xfa50
+#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f
+
+/*CFGEXT*/
+#define R0900_CFGEXT 0xfa80
+#define F0900_STAGMODE 0xfa800080
+#define F0900_BYPBCH 0xfa800040
+#define F0900_BYPLDPC 0xfa800020
+#define F0900_LDPCMODE 0xfa800010
+#define F0900_INVLLRSIGN 0xfa800008
+#define F0900_SHORTMULT 0xfa800004
+#define F0900_EXTERNTX 0xfa800001
+
+/*GENCFG*/
+#define R0900_GENCFG 0xfa86
+#define F0900_BROADCAST 0xfa860010
+#define F0900_NOSHFRD2 0xfa860008
+#define F0900_BCHERRFLAG 0xfa860004
+#define F0900_PRIORITY 0xfa860002
+#define F0900_DDEMOD 0xfa860001
+
+/*LDPCERR1*/
+#define R0900_LDPCERR1 0xfa96
+#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff
+
+/*LDPCERR0*/
+#define R0900_LDPCERR0 0xfa97
+#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff
+
+/*BCHERR*/
+#define R0900_BCHERR 0xfa98
+#define F0900_ERRORFLAG 0xfa980010
+#define F0900_BCH_ERRORS_COUNTER 0xfa98000f
+
+/*TSTRES0*/
+#define R0900_TSTRES0 0xff11
+#define F0900_FRESFEC 0xff110080
+#define F0900_FRESTS 0xff110040
+#define F0900_FRESVIT1 0xff110020
+#define F0900_FRESVIT2 0xff110010
+#define F0900_FRESSYM1 0xff110008
+#define F0900_FRESSYM2 0xff110004
+#define F0900_FRESMAS 0xff110002
+#define F0900_FRESINT 0xff110001
+
+/*P2_TSTDISRX*/
+#define R0900_P2_TSTDISRX 0xff65
+#define F0900_P2_EN_DISRX 0xff650080
+#define F0900_P2_TST_CURRSRC 0xff650040
+#define F0900_P2_IN_DIGSIGNAL 0xff650020
+#define F0900_P2_HIZ_CURRENTSRC 0xff650010
+#define F0900_TST_P2_PIN_SELECT 0xff650008
+#define F0900_P2_TST_DISRX 0xff650007
+
+/*P1_TSTDISRX*/
+#define R0900_P1_TSTDISRX 0xff67
+#define F0900_P1_EN_DISRX 0xff670080
+#define F0900_P1_TST_CURRSRC 0xff670040
+#define F0900_P1_IN_DIGSIGNAL 0xff670020
+#define F0900_P1_HIZ_CURRENTSRC 0xff670010
+#define F0900_TST_P1_PIN_SELECT 0xff670008
+#define F0900_P1_TST_DISRX 0xff670007
+
+#define STV0900_NBREGS 684
+#define STV0900_NBFIELDS 1702
+
+#endif
+
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c
new file mode 100644
index 000000000000..a5a31536cbcb
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_sw.c
@@ -0,0 +1,2847 @@
+/*
+ * stv0900_sw.c
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "stv0900.h"
+#include "stv0900_reg.h"
+#include "stv0900_priv.h"
+
+int stv0900_check_signal_presence(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 carr_offset,
+ agc2_integr,
+ max_carrier;
+
+ int no_signal;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ carr_offset = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8)
+ | stv0900_read_reg(i_params,
+ R0900_P1_CFR1);
+ carr_offset = ge2comp(carr_offset, 16);
+ agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
+ | stv0900_read_reg(i_params,
+ R0900_P1_AGC2I0);
+ max_carrier = i_params->dmd1_srch_range / 1000;
+ break;
+ case STV0900_DEMOD_2:
+ carr_offset = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8)
+ | stv0900_read_reg(i_params,
+ R0900_P2_CFR1);
+ carr_offset = ge2comp(carr_offset, 16);
+ agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
+ | stv0900_read_reg(i_params,
+ R0900_P2_AGC2I0);
+ max_carrier = i_params->dmd2_srch_range / 1000;
+ break;
+ }
+
+ max_carrier += (max_carrier / 10);
+ max_carrier = 65536 * (max_carrier / 2);
+ max_carrier /= i_params->mclk / 1000;
+ if (max_carrier > 0x4000)
+ max_carrier = 0x4000;
+
+ if ((agc2_integr > 0x2000)
+ || (carr_offset > + 2*max_carrier)
+ || (carr_offset < -2*max_carrier))
+ no_signal = TRUE;
+ else
+ no_signal = FALSE;
+
+ return no_signal;
+}
+
+static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params,
+ s32 *frequency_inc, s32 *sw_timeout,
+ s32 *steps,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 timeout, freq_inc, max_steps, srate, max_carrier;
+
+ enum fe_stv0900_search_standard standard;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ srate = i_params->dmd1_symbol_rate;
+ max_carrier = i_params->dmd1_srch_range / 1000;
+ max_carrier += max_carrier / 10;
+ standard = i_params->dmd1_srch_standard;
+ break;
+ case STV0900_DEMOD_2:
+ srate = i_params->dmd2_symbol_rate;
+ max_carrier = i_params->dmd2_srch_range / 1000;
+ max_carrier += max_carrier / 10;
+ standard = i_params->dmd2_srch_stndrd;
+ break;
+ }
+
+ max_carrier = 65536 * (max_carrier / 2);
+ max_carrier /= i_params->mclk / 1000;
+
+ if (max_carrier > 0x4000)
+ max_carrier = 0x4000;
+
+ freq_inc = srate;
+ freq_inc /= i_params->mclk >> 10;
+ freq_inc = freq_inc << 6;
+
+ switch (standard) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ freq_inc *= 3;
+ timeout = 20;
+ break;
+ case STV0900_SEARCH_DVBS2:
+ freq_inc *= 4;
+ timeout = 25;
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ freq_inc *= 3;
+ timeout = 25;
+ break;
+ }
+
+ freq_inc /= 100;
+
+ if ((freq_inc > max_carrier) || (freq_inc < 0))
+ freq_inc = max_carrier / 2;
+
+ timeout *= 27500;
+
+ if (srate > 0)
+ timeout /= srate / 1000;
+
+ if ((timeout > 100) || (timeout < 0))
+ timeout = 100;
+
+ max_steps = (max_carrier / freq_inc) + 1;
+
+ if ((max_steps > 100) || (max_steps < 0)) {
+ max_steps = 100;
+ freq_inc = max_carrier / max_steps;
+ }
+
+ *frequency_inc = freq_inc;
+ *sw_timeout = timeout;
+ *steps = max_steps;
+
+}
+
+static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params,
+ s32 FreqIncr, s32 Timeout, int zigzag,
+ s32 MaxStep, enum fe_stv0900_demod_num demod)
+{
+ int no_signal,
+ lock = FALSE;
+ s32 stepCpt,
+ freqOffset,
+ max_carrier;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ max_carrier = i_params->dmd1_srch_range / 1000;
+ max_carrier += (max_carrier / 10);
+ break;
+ case STV0900_DEMOD_2:
+ max_carrier = i_params->dmd2_srch_range / 1000;
+ max_carrier += (max_carrier / 10);
+ break;
+ }
+
+ max_carrier = 65536 * (max_carrier / 2);
+ max_carrier /= i_params->mclk / 1000;
+
+ if (max_carrier > 0x4000)
+ max_carrier = 0x4000;
+
+ if (zigzag == TRUE)
+ freqOffset = 0;
+ else
+ freqOffset = -max_carrier + FreqIncr;
+
+ stepCpt = 0;
+
+ do {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1,
+ (freqOffset / 256) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0,
+ freqOffset & 0xFF);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1);
+
+ if (i_params->chip_id == 0x12) {
+ stv0900_write_bits(i_params,
+ F0900_P1_RST_HWARE, 1);
+ stv0900_write_bits(i_params,
+ F0900_P1_RST_HWARE, 0);
+ }
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1,
+ (freqOffset / 256) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0,
+ freqOffset & 0xFF);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1);
+
+ if (i_params->chip_id == 0x12) {
+ stv0900_write_bits(i_params,
+ F0900_P2_RST_HWARE, 1);
+ stv0900_write_bits(i_params,
+ F0900_P2_RST_HWARE, 0);
+ }
+ break;
+ }
+
+ if (zigzag == TRUE) {
+ if (freqOffset >= 0)
+ freqOffset = -freqOffset - 2 * FreqIncr;
+ else
+ freqOffset = -freqOffset;
+ } else
+ freqOffset += + 2 * FreqIncr;
+
+ stepCpt++;
+ lock = stv0900_get_demod_lock(i_params, demod, Timeout);
+ no_signal = stv0900_check_signal_presence(i_params, demod);
+
+ } while ((lock == FALSE)
+ && (no_signal == FALSE)
+ && ((freqOffset - FreqIncr) < max_carrier)
+ && ((freqOffset + FreqIncr) > -max_carrier)
+ && (stepCpt < MaxStep));
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0);
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0);
+ break;
+ }
+
+ return lock;
+}
+
+int stv0900_sw_algo(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ int lock = FALSE;
+
+ int no_signal,
+ zigzag;
+ s32 dvbs2_fly_wheel;
+
+ s32 freqIncrement, softStepTimeout, trialCounter, max_steps;
+
+ stv0900_get_sw_loop_params(i_params, &freqIncrement, &softStepTimeout,
+ &max_steps, demod);
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ switch (i_params->dmd1_srch_standard) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ,
+ 0x3B);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ,
+ 0xef);
+
+ stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x49);
+ zigzag = FALSE;
+ break;
+ case STV0900_SEARCH_DVBS2:
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS,
+ 0x79);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS,
+ 0x68);
+
+ stv0900_write_reg(i_params, R0900_P1_DMDCFGMD,
+ 0x89);
+
+ zigzag = TRUE;
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ,
+ 0x3B);
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS,
+ 0x79);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ,
+ 0xef);
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS,
+ 0x68);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_DMDCFGMD,
+ 0xc9);
+ zigzag = FALSE;
+ break;
+ }
+
+ trialCounter = 0;
+ do {
+ lock = stv0900_search_carr_sw_loop(i_params,
+ freqIncrement,
+ softStepTimeout,
+ zigzag,
+ max_steps,
+ demod);
+ no_signal = stv0900_check_signal_presence(i_params,
+ demod);
+ trialCounter++;
+ if ((lock == TRUE)
+ || (no_signal == TRUE)
+ || (trialCounter == 2)) {
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params,
+ R0900_P1_CARFREQ,
+ 0x49);
+ stv0900_write_reg(i_params,
+ R0900_P1_CORRELABS,
+ 0x9e);
+ } else {
+ stv0900_write_reg(i_params,
+ R0900_P1_CARFREQ,
+ 0xed);
+ stv0900_write_reg(i_params,
+ R0900_P1_CORRELABS,
+ 0x88);
+ }
+
+ if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS2_FOUND)) {
+ msleep(softStepTimeout);
+ dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT);
+
+ if (dvbs2_fly_wheel < 0xd) {
+ msleep(softStepTimeout);
+ dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT);
+ }
+
+ if (dvbs2_fly_wheel < 0xd) {
+ lock = FALSE;
+
+ if (trialCounter < 2) {
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x79);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x68);
+
+ stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x89);
+ }
+ }
+ }
+ }
+
+ } while ((lock == FALSE)
+ && (trialCounter < 2)
+ && (no_signal == FALSE));
+
+ break;
+ case STV0900_DEMOD_2:
+ switch (i_params->dmd2_srch_stndrd) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ,
+ 0x3b);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ,
+ 0xef);
+
+ stv0900_write_reg(i_params, R0900_P2_DMDCFGMD,
+ 0x49);
+ zigzag = FALSE;
+ break;
+ case STV0900_SEARCH_DVBS2:
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS,
+ 0x79);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS,
+ 0x68);
+
+ stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89);
+ zigzag = TRUE;
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ,
+ 0x3b);
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS,
+ 0x79);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ,
+ 0xef);
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS,
+ 0x68);
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0xc9);
+
+ zigzag = FALSE;
+ break;
+ }
+
+ trialCounter = 0;
+
+ do {
+ lock = stv0900_search_carr_sw_loop(i_params,
+ freqIncrement,
+ softStepTimeout,
+ zigzag,
+ max_steps,
+ demod);
+ no_signal = stv0900_check_signal_presence(i_params,
+ demod);
+ trialCounter++;
+ if ((lock == TRUE)
+ || (no_signal == TRUE)
+ || (trialCounter == 2)) {
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params,
+ R0900_P2_CARFREQ,
+ 0x49);
+ stv0900_write_reg(i_params,
+ R0900_P2_CORRELABS,
+ 0x9e);
+ } else {
+ stv0900_write_reg(i_params,
+ R0900_P2_CARFREQ,
+ 0xed);
+ stv0900_write_reg(i_params,
+ R0900_P2_CORRELABS,
+ 0x88);
+ }
+
+ if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS2_FOUND)) {
+ msleep(softStepTimeout);
+ dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT);
+ if (dvbs2_fly_wheel < 0xd) {
+ msleep(softStepTimeout);
+ dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT);
+ }
+
+ if (dvbs2_fly_wheel < 0xd) {
+ lock = FALSE;
+ if (trialCounter < 2) {
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x79);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x68);
+
+ stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89);
+ }
+ }
+ }
+ }
+
+ } while ((lock == FALSE) && (trialCounter < 2) && (no_signal == FALSE));
+
+ break;
+ }
+
+ return lock;
+}
+
+static u32 stv0900_get_symbol_rate(struct stv0900_internal *i_params,
+ u32 mclk,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 sfr_field3, sfr_field2, sfr_field1, sfr_field0,
+ rem1, rem2, intval1, intval2, srate;
+
+ dmd_reg(sfr_field3, F0900_P1_SYMB_FREQ3, F0900_P2_SYMB_FREQ3);
+ dmd_reg(sfr_field2, F0900_P1_SYMB_FREQ2, F0900_P2_SYMB_FREQ2);
+ dmd_reg(sfr_field1, F0900_P1_SYMB_FREQ1, F0900_P2_SYMB_FREQ1);
+ dmd_reg(sfr_field0, F0900_P1_SYMB_FREQ0, F0900_P2_SYMB_FREQ0);
+
+ srate = (stv0900_get_bits(i_params, sfr_field3) << 24) +
+ (stv0900_get_bits(i_params, sfr_field2) << 16) +
+ (stv0900_get_bits(i_params, sfr_field1) << 8) +
+ (stv0900_get_bits(i_params, sfr_field0));
+ dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n",
+ srate, stv0900_get_bits(i_params, sfr_field0),
+ stv0900_get_bits(i_params, sfr_field1),
+ stv0900_get_bits(i_params, sfr_field2),
+ stv0900_get_bits(i_params, sfr_field3));
+
+ intval1 = (mclk) >> 16;
+ intval2 = (srate) >> 16;
+
+ rem1 = (mclk) % 0x10000;
+ rem2 = (srate) % 0x10000;
+ srate = (intval1 * intval2) +
+ ((intval1 * rem2) >> 16) +
+ ((intval2 * rem1) >> 16);
+
+ return srate;
+}
+
+static void stv0900_set_symbol_rate(struct stv0900_internal *i_params,
+ u32 mclk, u32 srate,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 sfr_init_reg;
+ u32 symb;
+
+ dprintk(KERN_INFO "%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk,
+ srate, demod);
+
+ dmd_reg(sfr_init_reg, R0900_P1_SFRINIT1, R0900_P2_SFRINIT1);
+
+ if (srate > 60000000) {
+ symb = srate << 4;
+ symb /= (mclk >> 12);
+ } else if (srate > 6000000) {
+ symb = srate << 6;
+ symb /= (mclk >> 10);
+ } else {
+ symb = srate << 9;
+ symb /= (mclk >> 7);
+ }
+
+ stv0900_write_reg(i_params, sfr_init_reg, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, sfr_init_reg + 1, (symb & 0xFF));
+}
+
+static void stv0900_set_max_symbol_rate(struct stv0900_internal *i_params,
+ u32 mclk, u32 srate,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 sfr_max_reg;
+ u32 symb;
+
+ dmd_reg(sfr_max_reg, R0900_P1_SFRUP1, R0900_P2_SFRUP1);
+
+ srate = 105 * (srate / 100);
+
+ if (srate > 60000000) {
+ symb = srate << 4;
+ symb /= (mclk >> 12);
+ } else if (srate > 6000000) {
+ symb = srate << 6;
+ symb /= (mclk >> 10);
+ } else {
+ symb = srate << 9;
+ symb /= (mclk >> 7);
+ }
+
+ if (symb < 0x7fff) {
+ stv0900_write_reg(i_params, sfr_max_reg, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, sfr_max_reg + 1, (symb & 0xFF));
+ } else {
+ stv0900_write_reg(i_params, sfr_max_reg, 0x7F);
+ stv0900_write_reg(i_params, sfr_max_reg + 1, 0xFF);
+ }
+}
+
+static void stv0900_set_min_symbol_rate(struct stv0900_internal *i_params,
+ u32 mclk, u32 srate,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 sfr_min_reg;
+ u32 symb;
+
+ dmd_reg(sfr_min_reg, R0900_P1_SFRLOW1, R0900_P2_SFRLOW1);
+
+ srate = 95 * (srate / 100);
+ if (srate > 60000000) {
+ symb = srate << 4;
+ symb /= (mclk >> 12);
+
+ } else if (srate > 6000000) {
+ symb = srate << 6;
+ symb /= (mclk >> 10);
+
+ } else {
+ symb = srate << 9;
+ symb /= (mclk >> 7);
+ }
+
+ stv0900_write_reg(i_params, sfr_min_reg, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, sfr_min_reg + 1, (symb & 0xFF));
+}
+
+static s32 stv0900_get_timing_offst(struct stv0900_internal *i_params,
+ u32 srate,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 tmgreg,
+ timingoffset;
+
+ dmd_reg(tmgreg, R0900_P1_TMGREG2, R0900_P2_TMGREG2);
+
+ timingoffset = (stv0900_read_reg(i_params, tmgreg) << 16) +
+ (stv0900_read_reg(i_params, tmgreg + 1) << 8) +
+ (stv0900_read_reg(i_params, tmgreg + 2));
+
+ timingoffset = ge2comp(timingoffset, 24);
+
+
+ if (timingoffset == 0)
+ timingoffset = 1;
+
+ timingoffset = ((s32)srate * 10) / ((s32)0x1000000 / timingoffset);
+ timingoffset /= 320;
+
+ return timingoffset;
+}
+
+static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 rolloff, man_fld, matstr_reg, rolloff_ctl_fld;
+
+ dmd_reg(man_fld, F0900_P1_MANUAL_ROLLOFF, F0900_P2_MANUAL_ROLLOFF);
+ dmd_reg(matstr_reg, R0900_P1_MATSTR1, R0900_P2_MATSTR1);
+ dmd_reg(rolloff_ctl_fld, F0900_P1_ROLLOFF_CONTROL,
+ F0900_P2_ROLLOFF_CONTROL);
+
+ if (i_params->chip_id == 0x10) {
+ stv0900_write_bits(i_params, man_fld, 1);
+ rolloff = stv0900_read_reg(i_params, matstr_reg) & 0x03;
+ stv0900_write_bits(i_params, rolloff_ctl_fld, rolloff);
+ } else
+ stv0900_write_bits(i_params, man_fld, 0);
+}
+
+static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro)
+{
+ u32 rolloff;
+
+ switch (ro) {
+ case STV0900_20:
+ rolloff = 20;
+ break;
+ case STV0900_25:
+ rolloff = 25;
+ break;
+ case STV0900_35:
+ default:
+ rolloff = 35;
+ break;
+ }
+
+ return srate + (srate * rolloff) / 100;
+}
+
+static int stv0900_check_timing_lock(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ int timingLock = FALSE;
+ s32 i,
+ timingcpt = 0;
+ u8 carFreq,
+ tmgTHhigh,
+ tmgTHLow;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ carFreq = stv0900_read_reg(i_params, R0900_P1_CARFREQ);
+ tmgTHhigh = stv0900_read_reg(i_params, R0900_P1_TMGTHRISE);
+ tmgTHLow = stv0900_read_reg(i_params, R0900_P1_TMGTHFALL);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x0);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+ stv0900_write_reg(i_params, R0900_P1_RTC, 0x80);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x40);
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x0);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0x0);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0x0);
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x65);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ msleep(7);
+
+ for (i = 0; i < 10; i++) {
+ if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2)
+ timingcpt++;
+
+ msleep(1);
+ }
+
+ if (timingcpt >= 3)
+ timingLock = TRUE;
+
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
+ stv0900_write_reg(i_params, R0900_P1_RTC, 0x88);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68);
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, carFreq);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, tmgTHhigh);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, tmgTHLow);
+ break;
+ case STV0900_DEMOD_2:
+ carFreq = stv0900_read_reg(i_params, R0900_P2_CARFREQ);
+ tmgTHhigh = stv0900_read_reg(i_params, R0900_P2_TMGTHRISE);
+ tmgTHLow = stv0900_read_reg(i_params, R0900_P2_TMGTHFALL);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+ stv0900_write_reg(i_params, R0900_P2_RTC, 0x80);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x40);
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x0);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0x0);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0x0);
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x65);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ msleep(5);
+ for (i = 0; i < 10; i++) {
+ if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2)
+ timingcpt++;
+
+ msleep(1);
+ }
+
+ if (timingcpt >= 3)
+ timingLock = TRUE;
+
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
+ stv0900_write_reg(i_params, R0900_P2_RTC, 0x88);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68);
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, carFreq);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, tmgTHhigh);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, tmgTHLow);
+ break;
+ }
+
+ return timingLock;
+}
+
+static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe,
+ s32 demod_timeout)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ int lock = FALSE;
+ s32 srate, search_range, locktimeout,
+ currier_step, nb_steps, current_step,
+ direction, tuner_freq, timeout;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ srate = i_params->dmd1_symbol_rate;
+ search_range = i_params->dmd1_srch_range;
+ break;
+
+ case STV0900_DEMOD_2:
+ srate = i_params->dmd2_symbol_rate;
+ search_range = i_params->dmd2_srch_range;
+ break;
+ }
+
+ if (srate >= 10000000)
+ locktimeout = demod_timeout / 3;
+ else
+ locktimeout = demod_timeout / 2;
+
+ lock = stv0900_get_demod_lock(i_params, demod, locktimeout);
+
+ if (lock == FALSE) {
+ if (srate >= 10000000) {
+ if (stv0900_check_timing_lock(i_params, demod) == TRUE) {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
+ break;
+ }
+
+ lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
+ } else
+ lock = FALSE;
+ } else {
+ if (srate <= 4000000)
+ currier_step = 1000;
+ else if (srate <= 7000000)
+ currier_step = 2000;
+ else if (srate <= 10000000)
+ currier_step = 3000;
+ else
+ currier_step = 5000;
+
+ nb_steps = ((search_range / 1000) / currier_step);
+ nb_steps /= 2;
+ nb_steps = (2 * (nb_steps + 1));
+ if (nb_steps < 0)
+ nb_steps = 2;
+ else if (nb_steps > 12)
+ nb_steps = 12;
+
+ current_step = 1;
+ direction = 1;
+ timeout = (demod_timeout / 3);
+ if (timeout > 1000)
+ timeout = 1000;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ if (lock == FALSE) {
+ tuner_freq = i_params->tuner1_freq;
+ i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + i_params->dmd1_symbol_rate;
+
+ while ((current_step <= nb_steps) && (lock == FALSE)) {
+
+ if (direction > 0)
+ tuner_freq += (current_step * currier_step);
+ else
+ tuner_freq -= (current_step * currier_step);
+
+ stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
+ if (i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS2) {
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
+ lock = stv0900_get_demod_lock(i_params, demod, timeout);
+ direction *= -1;
+ current_step++;
+ }
+ }
+ break;
+ case STV0900_DEMOD_2:
+ if (lock == FALSE) {
+ tuner_freq = i_params->tuner2_freq;
+ i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + srate;
+
+ while ((current_step <= nb_steps) && (lock == FALSE)) {
+
+ if (direction > 0)
+ tuner_freq += (current_step * currier_step);
+ else
+ tuner_freq -= (current_step * currier_step);
+
+ stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
+ if (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS2) {
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
+ lock = stv0900_get_demod_lock(i_params, demod, timeout);
+ direction *= -1;
+ current_step++;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ return lock;
+}
+
+static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout,
+ s32 srate,
+ enum fe_stv0900_search_algo algo)
+{
+ switch (algo) {
+ case STV0900_BLIND_SEARCH:
+ if (srate <= 1500000) {
+ (*demod_timeout) = 1500;
+ (*fec_timeout) = 400;
+ } else if (srate <= 5000000) {
+ (*demod_timeout) = 1000;
+ (*fec_timeout) = 300;
+ } else {
+ (*demod_timeout) = 700;
+ (*fec_timeout) = 100;
+ }
+
+ break;
+ case STV0900_COLD_START:
+ case STV0900_WARM_START:
+ default:
+ if (srate <= 1000000) {
+ (*demod_timeout) = 3000;
+ (*fec_timeout) = 1700;
+ } else if (srate <= 2000000) {
+ (*demod_timeout) = 2500;
+ (*fec_timeout) = 1100;
+ } else if (srate <= 5000000) {
+ (*demod_timeout) = 1000;
+ (*fec_timeout) = 550;
+ } else if (srate <= 10000000) {
+ (*demod_timeout) = 700;
+ (*fec_timeout) = 250;
+ } else if (srate <= 20000000) {
+ (*demod_timeout) = 400;
+ (*fec_timeout) = 130;
+ }
+
+ else {
+ (*demod_timeout) = 300;
+ (*fec_timeout) = 100;
+ }
+
+ break;
+
+ }
+
+ if (algo == STV0900_WARM_START)
+ (*demod_timeout) /= 2;
+}
+
+static void stv0900_set_viterbi_tracq(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+
+ s32 vth_reg;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12);
+
+ stv0900_write_reg(i_params, vth_reg++, 0xd0);
+ stv0900_write_reg(i_params, vth_reg++, 0x7d);
+ stv0900_write_reg(i_params, vth_reg++, 0x53);
+ stv0900_write_reg(i_params, vth_reg++, 0x2F);
+ stv0900_write_reg(i_params, vth_reg++, 0x24);
+ stv0900_write_reg(i_params, vth_reg++, 0x1F);
+}
+
+static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params,
+ enum fe_stv0900_search_standard Standard,
+ enum fe_stv0900_fec PunctureRate,
+ enum fe_stv0900_demod_num demod)
+{
+
+ s32 fecmReg,
+ prvitReg;
+
+ dprintk(KERN_INFO "%s: ViterbiStandard = ", __func__);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ fecmReg = R0900_P1_FECM;
+ prvitReg = R0900_P1_PRVIT;
+ break;
+ case STV0900_DEMOD_2:
+ fecmReg = R0900_P2_FECM;
+ prvitReg = R0900_P2_PRVIT;
+ break;
+ }
+
+ switch (Standard) {
+ case STV0900_AUTO_SEARCH:
+ dprintk("Auto\n");
+ stv0900_write_reg(i_params, fecmReg, 0x10);
+ stv0900_write_reg(i_params, prvitReg, 0x3F);
+ break;
+ case STV0900_SEARCH_DVBS1:
+ dprintk("DVBS1\n");
+ stv0900_write_reg(i_params, fecmReg, 0x00);
+ switch (PunctureRate) {
+ case STV0900_FEC_UNKNOWN:
+ default:
+ stv0900_write_reg(i_params, prvitReg, 0x2F);
+ break;
+ case STV0900_FEC_1_2:
+ stv0900_write_reg(i_params, prvitReg, 0x01);
+ break;
+ case STV0900_FEC_2_3:
+ stv0900_write_reg(i_params, prvitReg, 0x02);
+ break;
+ case STV0900_FEC_3_4:
+ stv0900_write_reg(i_params, prvitReg, 0x04);
+ break;
+ case STV0900_FEC_5_6:
+ stv0900_write_reg(i_params, prvitReg, 0x08);
+ break;
+ case STV0900_FEC_7_8:
+ stv0900_write_reg(i_params, prvitReg, 0x20);
+ break;
+ }
+
+ break;
+ case STV0900_SEARCH_DSS:
+ dprintk("DSS\n");
+ stv0900_write_reg(i_params, fecmReg, 0x80);
+ switch (PunctureRate) {
+ case STV0900_FEC_UNKNOWN:
+ default:
+ stv0900_write_reg(i_params, prvitReg, 0x13);
+ break;
+ case STV0900_FEC_1_2:
+ stv0900_write_reg(i_params, prvitReg, 0x01);
+ break;
+ case STV0900_FEC_2_3:
+ stv0900_write_reg(i_params, prvitReg, 0x02);
+ break;
+ case STV0900_FEC_6_7:
+ stv0900_write_reg(i_params, prvitReg, 0x10);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void stv0900_track_optimization(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ s32 srate, pilots, aclc, freq1, freq0,
+ i = 0, timed, timef, blindTunSw = 0;
+
+ enum fe_stv0900_rolloff rolloff;
+ enum fe_stv0900_modcode foundModcod;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate += stv0900_get_timing_offst(i_params, srate, demod);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ switch (i_params->dmd1_rslts.standard) {
+ case STV0900_DVBS1_STANDARD:
+ if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) {
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ }
+
+ stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff);
+ stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
+ break;
+ case STV0900_DSS_STANDARD:
+ if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) {
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ }
+
+ stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff);
+ stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
+ break;
+ case STV0900_DVBS2_STANDARD:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ stv0900_write_reg(i_params, R0900_P1_ACLC, 0);
+ stv0900_write_reg(i_params, R0900_P1_BCLC, 0);
+ if (i_params->dmd1_rslts.frame_length == STV0900_LONG_FRAME) {
+ foundModcod = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD);
+ pilots = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01;
+ aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id);
+ if (foundModcod <= STV0900_QPSK_910)
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc);
+ else if (foundModcod <= STV0900_8PSK_910) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc);
+ }
+
+ if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) {
+ if (foundModcod <= STV0900_16APSK_910) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc);
+ } else if (foundModcod <= STV0900_32APSK_910) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc);
+ }
+ }
+
+ } else {
+ aclc = stv0900_get_optim_short_carr_loop(srate, i_params->dmd1_rslts.modulation, i_params->chip_id);
+ if (i_params->dmd1_rslts.modulation == STV0900_QPSK)
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc);
+
+ else if (i_params->dmd1_rslts.modulation == STV0900_8PSK) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc);
+ } else if (i_params->dmd1_rslts.modulation == STV0900_16APSK) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc);
+ } else if (i_params->dmd1_rslts.modulation == STV0900_32APSK) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc);
+ }
+
+ }
+
+ if (i_params->chip_id <= 0x11) {
+ if (i_params->demod_mode != STV0900_SINGLE)
+ stv0900_activate_s2_modcode(i_params, demod);
+
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67);
+ break;
+ case STV0900_UNKNOWN_STANDARD:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ break;
+ }
+
+ freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2);
+ freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1);
+ rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS);
+ if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00);
+ stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
+ stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+ stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod);
+ stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod);
+ blindTunSw = 1;
+ }
+
+ if (i_params->chip_id >= 0x20) {
+ if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) {
+ stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0a);
+ stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x0);
+ }
+ }
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x08);
+
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0x0A);
+
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
+
+ if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd1_symbol_rate < 10000000)) {
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ i_params->tuner1_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000;
+
+ if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) {
+ if (i_params->dmd1_srch_algo != STV0900_WARM_START)
+ stv0900_set_bandwidth(fe, i_params->tuner1_bw);
+ }
+
+ if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000))
+ msleep(50);
+ else
+ msleep(5);
+
+ stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START);
+
+ if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) {
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ i = 0;
+ while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) {
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ i++;
+ }
+ }
+
+ }
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49);
+
+ if ((i_params->dmd1_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd1_rslts.standard == STV0900_DSS_STANDARD))
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ break;
+
+ case STV0900_DEMOD_2:
+ switch (i_params->dmd2_rslts.standard) {
+ case STV0900_DVBS1_STANDARD:
+
+ if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) {
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ }
+
+ stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff);
+ stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
+ break;
+ case STV0900_DSS_STANDARD:
+ if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) {
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ }
+
+ stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff);
+ stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
+ break;
+ case STV0900_DVBS2_STANDARD:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ stv0900_write_reg(i_params, R0900_P2_ACLC, 0);
+ stv0900_write_reg(i_params, R0900_P2_BCLC, 0);
+ if (i_params->dmd2_rslts.frame_length == STV0900_LONG_FRAME) {
+ foundModcod = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD);
+ pilots = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01;
+ aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id);
+ if (foundModcod <= STV0900_QPSK_910)
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc);
+ else if (foundModcod <= STV0900_8PSK_910) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc);
+ }
+
+ if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) {
+ if (foundModcod <= STV0900_16APSK_910) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc);
+ } else if (foundModcod <= STV0900_32APSK_910) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc);
+ }
+
+ }
+
+ } else {
+ aclc = stv0900_get_optim_short_carr_loop(srate,
+ i_params->dmd2_rslts.modulation,
+ i_params->chip_id);
+
+ if (i_params->dmd2_rslts.modulation == STV0900_QPSK)
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc);
+
+ else if (i_params->dmd2_rslts.modulation == STV0900_8PSK) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc);
+ } else if (i_params->dmd2_rslts.modulation == STV0900_16APSK) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc);
+ } else if (i_params->dmd2_rslts.modulation == STV0900_32APSK) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc);
+ }
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67);
+
+ break;
+ case STV0900_UNKNOWN_STANDARD:
+ default:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ break;
+ }
+
+ freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2);
+ freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1);
+ rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS);
+ if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00);
+ stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
+ stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+ stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod);
+ stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod);
+ blindTunSw = 1;
+ }
+
+ if (i_params->chip_id >= 0x20) {
+ if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) {
+ stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0a);
+ stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x0);
+ }
+ }
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x08);
+
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0x0a);
+
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
+ if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd2_symbol_rate < 10000000)) {
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000;
+
+ if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) {
+ if (i_params->dmd2_srch_algo != STV0900_WARM_START)
+ stv0900_set_bandwidth(fe, i_params->tuner2_bw);
+ }
+
+ if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000))
+ msleep(50);
+ else
+ msleep(5);
+
+ stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START);
+ if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) {
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ i = 0;
+ while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) {
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ i++;
+ }
+ }
+ }
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49);
+
+ if ((i_params->dmd2_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd2_rslts.standard == STV0900_DSS_STANDARD))
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ break;
+ }
+}
+
+static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv0900_demod_num demod, s32 time_out)
+{
+ s32 timer = 0, lock = 0, header_field, pktdelin_field, lock_vit_field;
+
+ enum fe_stv0900_search_state dmd_state;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(pktdelin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK);
+ dmd_reg(lock_vit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT);
+
+ dmd_state = stv0900_get_bits(i_params, header_field);
+
+ while ((timer < time_out) && (lock == 0)) {
+ switch (dmd_state) {
+ case STV0900_SEARCH:
+ case STV0900_PLH_DETECTED:
+ default:
+ lock = 0;
+ break;
+ case STV0900_DVBS2_FOUND:
+ lock = stv0900_get_bits(i_params, pktdelin_field);
+ break;
+ case STV0900_DVBS_FOUND:
+ lock = stv0900_get_bits(i_params, lock_vit_field);
+ break;
+ }
+
+ if (lock == 0) {
+ msleep(10);
+ timer += 10;
+ }
+ }
+
+ if (lock)
+ dprintk("DEMOD FEC LOCK OK\n");
+ else
+ dprintk("DEMOD FEC LOCK FAIL\n");
+
+ return lock;
+}
+
+static int stv0900_wait_for_lock(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod,
+ s32 dmd_timeout, s32 fec_timeout)
+{
+
+ s32 timer = 0, lock = 0, str_merg_rst_fld, str_merg_lock_fld;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(str_merg_rst_fld, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE);
+ dmd_reg(str_merg_lock_fld, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK);
+
+ lock = stv0900_get_demod_lock(i_params, demod, dmd_timeout);
+
+ if (lock)
+ lock = lock && stv0900_get_fec_lock(i_params, demod, fec_timeout);
+
+ if (lock) {
+ lock = 0;
+
+ dprintk(KERN_INFO "%s: Timer = %d, time_out = %d\n", __func__, timer, fec_timeout);
+
+ while ((timer < fec_timeout) && (lock == 0)) {
+ lock = stv0900_get_bits(i_params, str_merg_lock_fld);
+ msleep(1);
+ timer++;
+ }
+ }
+
+ if (lock)
+ dprintk(KERN_INFO "%s: DEMOD LOCK OK\n", __func__);
+ else
+ dprintk(KERN_INFO "%s: DEMOD LOCK FAIL\n", __func__);
+
+ if (lock)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
+ enum fe_stv0900_demod_num demod)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_tracking_standard fnd_standard;
+ s32 state_field,
+ dss_dvb_field;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(state_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(dss_dvb_field, F0900_P1_DSS_DVB, F0900_P2_DSS_DVB);
+
+ if (stv0900_get_bits(i_params, state_field) == 2)
+ fnd_standard = STV0900_DVBS2_STANDARD;
+
+ else if (stv0900_get_bits(i_params, state_field) == 3) {
+ if (stv0900_get_bits(i_params, dss_dvb_field) == 1)
+ fnd_standard = STV0900_DSS_STANDARD;
+ else
+ fnd_standard = STV0900_DVBS1_STANDARD;
+ } else
+ fnd_standard = STV0900_UNKNOWN_STANDARD;
+
+ return fnd_standard;
+}
+
+static s32 stv0900_get_carr_freq(struct stv0900_internal *i_params, u32 mclk,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 cfr_field2, cfr_field1, cfr_field0,
+ derot, rem1, rem2, intval1, intval2;
+
+ dmd_reg(cfr_field2, F0900_P1_CAR_FREQ2, F0900_P2_CAR_FREQ2);
+ dmd_reg(cfr_field1, F0900_P1_CAR_FREQ1, F0900_P2_CAR_FREQ1);
+ dmd_reg(cfr_field0, F0900_P1_CAR_FREQ0, F0900_P2_CAR_FREQ0);
+
+ derot = (stv0900_get_bits(i_params, cfr_field2) << 16) +
+ (stv0900_get_bits(i_params, cfr_field1) << 8) +
+ (stv0900_get_bits(i_params, cfr_field0));
+
+ derot = ge2comp(derot, 24);
+ intval1 = mclk >> 12;
+ intval2 = derot >> 12;
+ rem1 = mclk % 0x1000;
+ rem2 = derot % 0x1000;
+ derot = (intval1 * intval2) +
+ ((intval1 * rem2) >> 12) +
+ ((intval2 * rem1) >> 12);
+
+ return derot;
+}
+
+static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+ u32 frequency = 0;
+
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+
+ if (tuner_ops->get_frequency) {
+ if ((tuner_ops->get_frequency(fe, &frequency)) < 0)
+ dprintk("%s: Invalid parameter\n", __func__);
+ else
+ dprintk("%s: Frequency=%d\n", __func__, frequency);
+
+ }
+
+ return frequency;
+}
+
+static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 rate_fld, vit_curpun_fld;
+ enum fe_stv0900_fec prate;
+
+ dmd_reg(vit_curpun_fld, F0900_P1_VIT_CURPUN, F0900_P2_VIT_CURPUN);
+ rate_fld = stv0900_get_bits(i_params, vit_curpun_fld);
+
+ switch (rate_fld) {
+ case 13:
+ prate = STV0900_FEC_1_2;
+ break;
+ case 18:
+ prate = STV0900_FEC_2_3;
+ break;
+ case 21:
+ prate = STV0900_FEC_3_4;
+ break;
+ case 24:
+ prate = STV0900_FEC_5_6;
+ break;
+ case 25:
+ prate = STV0900_FEC_6_7;
+ break;
+ case 26:
+ prate = STV0900_FEC_7_8;
+ break;
+ default:
+ prate = STV0900_FEC_UNKNOWN;
+ break;
+ }
+
+ return prate;
+}
+
+static enum fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE;
+ s32 offsetFreq,
+ srate_offset,
+ i = 0;
+
+ u8 timing;
+
+ msleep(5);
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
+ timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2);
+ i = 0;
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x5c);
+
+ while ((i <= 50) && (timing != 0) && (timing != 0xFF)) {
+ timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2);
+ msleep(5);
+ i += 5;
+ }
+ }
+
+ i_params->dmd1_rslts.standard = stv0900_get_standard(fe, demod);
+ i_params->dmd1_rslts.frequency = stv0900_get_tuner_freq(fe);
+ offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000;
+ i_params->dmd1_rslts.frequency += offsetFreq;
+ i_params->dmd1_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd1_rslts.symbol_rate, demod);
+ i_params->dmd1_rslts.symbol_rate += srate_offset;
+ i_params->dmd1_rslts.fec = stv0900_get_vit_fec(i_params, demod);
+ i_params->dmd1_rslts.modcode = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD);
+ i_params->dmd1_rslts.pilot = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01;
+ i_params->dmd1_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE)) >> 1;
+ i_params->dmd1_rslts.rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS);
+ switch (i_params->dmd1_rslts.standard) {
+ case STV0900_DVBS2_STANDARD:
+ i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_SPECINV_DEMOD);
+ if (i_params->dmd1_rslts.modcode <= STV0900_QPSK_910)
+ i_params->dmd1_rslts.modulation = STV0900_QPSK;
+ else if (i_params->dmd1_rslts.modcode <= STV0900_8PSK_910)
+ i_params->dmd1_rslts.modulation = STV0900_8PSK;
+ else if (i_params->dmd1_rslts.modcode <= STV0900_16APSK_910)
+ i_params->dmd1_rslts.modulation = STV0900_16APSK;
+ else if (i_params->dmd1_rslts.modcode <= STV0900_32APSK_910)
+ i_params->dmd1_rslts.modulation = STV0900_32APSK;
+ else
+ i_params->dmd1_rslts.modulation = STV0900_UNKNOWN;
+ break;
+ case STV0900_DVBS1_STANDARD:
+ case STV0900_DSS_STANDARD:
+ i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_IQINV);
+ i_params->dmd1_rslts.modulation = STV0900_QPSK;
+ break;
+ default:
+ break;
+ }
+
+ if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) {
+ offsetFreq = i_params->dmd1_rslts.frequency - i_params->tuner1_freq;
+ i_params->tuner1_freq = stv0900_get_tuner_freq(fe);
+ if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500))
+ range = STV0900_RANGEOK;
+ else
+ if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd1_rslts.symbol_rate, i_params->dmd1_rslts.rolloff) / 2000))
+ range = STV0900_RANGEOK;
+ else
+ range = STV0900_OUTOFRANGE;
+
+ } else {
+ if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500))
+ range = STV0900_RANGEOK;
+ else
+ range = STV0900_OUTOFRANGE;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
+ timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2);
+ i = 0;
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x5c);
+
+ while ((i <= 50) && (timing != 0) && (timing != 0xff)) {
+ timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2);
+ msleep(5);
+ i += 5;
+ }
+ }
+
+ i_params->dmd2_rslts.standard = stv0900_get_standard(fe, demod);
+ i_params->dmd2_rslts.frequency = stv0900_get_tuner_freq(fe);
+ offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000;
+ i_params->dmd2_rslts.frequency += offsetFreq;
+ i_params->dmd2_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd2_rslts.symbol_rate, demod);
+ i_params->dmd2_rslts.symbol_rate += srate_offset;
+ i_params->dmd2_rslts.fec = stv0900_get_vit_fec(i_params, demod);
+ i_params->dmd2_rslts.modcode = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD);
+ i_params->dmd2_rslts.pilot = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01;
+ i_params->dmd2_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE)) >> 1;
+ i_params->dmd2_rslts.rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS);
+ switch (i_params->dmd2_rslts.standard) {
+ case STV0900_DVBS2_STANDARD:
+ i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_SPECINV_DEMOD);
+ if (i_params->dmd2_rslts.modcode <= STV0900_QPSK_910)
+ i_params->dmd2_rslts.modulation = STV0900_QPSK;
+ else if (i_params->dmd2_rslts.modcode <= STV0900_8PSK_910)
+ i_params->dmd2_rslts.modulation = STV0900_8PSK;
+ else if (i_params->dmd2_rslts.modcode <= STV0900_16APSK_910)
+ i_params->dmd2_rslts.modulation = STV0900_16APSK;
+ else if (i_params->dmd2_rslts.modcode <= STV0900_32APSK_910)
+ i_params->dmd2_rslts.modulation = STV0900_32APSK;
+ else
+ i_params->dmd2_rslts.modulation = STV0900_UNKNOWN;
+ break;
+ case STV0900_DVBS1_STANDARD:
+ case STV0900_DSS_STANDARD:
+ i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_IQINV);
+ i_params->dmd2_rslts.modulation = STV0900_QPSK;
+ break;
+ default:
+ break;
+ }
+
+ if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) {
+ offsetFreq = i_params->dmd2_rslts.frequency - i_params->tuner2_freq;
+ i_params->tuner2_freq = stv0900_get_tuner_freq(fe);
+
+ if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500))
+ range = STV0900_RANGEOK;
+ else
+ if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd2_rslts.symbol_rate, i_params->dmd2_rslts.rolloff) / 2000))
+ range = STV0900_RANGEOK;
+ else
+ range = STV0900_OUTOFRANGE;
+ } else {
+ if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500))
+ range = STV0900_RANGEOK;
+ else
+ range = STV0900_OUTOFRANGE;
+ }
+
+ break;
+ }
+
+ return range;
+}
+
+static enum fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ s32 srate, demod_timeout,
+ fec_timeout, freq1, freq0;
+ enum fe_stv0900_signal_type signal_type = STV0900_NODATA;;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ i_params->dmd1_rslts.locked = FALSE;
+ if (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) {
+ srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate += stv0900_get_timing_offst(i_params, srate, demod);
+ if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH)
+ stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START);
+ freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2);
+ freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+ stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
+ i_params->dmd1_rslts.locked = TRUE;
+ signal_type = stv0900_get_signal_params(fe);
+ stv0900_track_optimization(fe);
+ } else {
+ stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1c);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
+ i_params->dmd1_rslts.locked = TRUE;
+ signal_type = stv0900_get_signal_params(fe);
+ stv0900_track_optimization(fe);
+ }
+
+ }
+
+ } else
+ i_params->dmd1_rslts.locked = FALSE;
+
+ break;
+ case STV0900_DEMOD_2:
+ i_params->dmd2_rslts.locked = FALSE;
+ if (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) {
+ srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate += stv0900_get_timing_offst(i_params, srate, demod);
+
+ if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH)
+ stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START);
+ freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2);
+ freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+ stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+
+ if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
+ i_params->dmd2_rslts.locked = TRUE;
+ signal_type = stv0900_get_signal_params(fe);
+ stv0900_track_optimization(fe);
+ } else {
+ stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1c);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+
+ if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
+ i_params->dmd2_rslts.locked = TRUE;
+ signal_type = stv0900_get_signal_params(fe);
+ stv0900_track_optimization(fe);
+ }
+
+ }
+
+ } else
+ i_params->dmd1_rslts.locked = FALSE;
+
+ break;
+ }
+
+ return signal_type;
+}
+
+static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 minagc2level = 0xffff,
+ agc2level,
+ init_freq, freq_step;
+
+ s32 i, j, nb_steps, direction;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
+ stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1);
+
+ stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0);
+
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0);
+ stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
+ nb_steps = -1 + (i_params->dmd1_srch_range / 1000000);
+ nb_steps /= 2;
+ nb_steps = (2 * nb_steps) + 1;
+
+ if (nb_steps < 0)
+ nb_steps = 1;
+
+ direction = 1;
+
+ freq_step = (1000000 << 8) / (i_params->mclk >> 8);
+
+ init_freq = 0;
+
+ for (i = 0; i < nb_steps; i++) {
+ if (direction > 0)
+ init_freq = init_freq + (freq_step * i);
+ else
+ init_freq = init_freq - (freq_step * i);
+
+ direction *= -1;
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (init_freq >> 8) & 0xff);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, init_freq & 0xff);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x58);
+ msleep(10);
+ agc2level = 0;
+
+ for (j = 0; j < 10; j++)
+ agc2level += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P1_AGC2I0);
+
+ agc2level /= 10;
+
+ if (agc2level < minagc2level)
+ minagc2level = agc2level;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
+ stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0);
+ stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0);
+ stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
+ nb_steps = -1 + (i_params->dmd2_srch_range / 1000000);
+ nb_steps /= 2;
+ nb_steps = (2 * nb_steps) + 1;
+
+ if (nb_steps < 0)
+ nb_steps = 1;
+
+ direction = 1;
+ freq_step = (1000000 << 8) / (i_params->mclk >> 8);
+ init_freq = 0;
+ for (i = 0; i < nb_steps; i++) {
+ if (direction > 0)
+ init_freq = init_freq + (freq_step * i);
+ else
+ init_freq = init_freq - (freq_step * i);
+
+ direction *= -1;
+
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (init_freq >> 8) & 0xff);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, init_freq & 0xff);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x58);
+
+ msleep(10);
+ agc2level = 0;
+ for (j = 0; j < 10; j++)
+ agc2level += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P2_AGC2I0);
+
+ agc2level /= 10;
+
+ if (agc2level < minagc2level)
+ minagc2level = agc2level;
+ }
+ break;
+ }
+
+ return (u16)minagc2level;
+}
+
+static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ int timingLock = FALSE;
+ s32 i, timingcpt = 0,
+ direction = 1,
+ nb_steps,
+ current_step = 0,
+ tuner_freq;
+
+ u32 coarse_srate = 0, agc2_integr = 0, currier_step = 1200;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0x12);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xf0);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xe0);
+ stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0);
+ stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0);
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x50);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x6a);
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x95);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x73);
+ }
+
+ if (i_params->dmd1_symbol_rate <= 2000000)
+ currier_step = 1000;
+ else if (i_params->dmd1_symbol_rate <= 5000000)
+ currier_step = 2000;
+ else if (i_params->dmd1_symbol_rate <= 12000000)
+ currier_step = 3000;
+ else
+ currier_step = 5000;
+
+ nb_steps = -1 + ((i_params->dmd1_srch_range / 1000) / currier_step);
+ nb_steps /= 2;
+ nb_steps = (2 * nb_steps) + 1;
+
+ if (nb_steps < 0)
+ nb_steps = 1;
+
+ else if (nb_steps > 10) {
+ nb_steps = 11;
+ currier_step = (i_params->dmd1_srch_range / 1000) / 10;
+ }
+
+ current_step = 0;
+
+ direction = 1;
+ tuner_freq = i_params->tuner1_freq;
+
+ while ((timingLock == FALSE) && (current_step < nb_steps)) {
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5F);
+ stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x0);
+
+ msleep(50);
+
+ for (i = 0; i < 10; i++) {
+ if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2)
+ timingcpt++;
+
+ agc2_integr += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) | stv0900_read_reg(i_params, R0900_P1_AGC2I0);
+
+ }
+
+ agc2_integr /= 10;
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ current_step++;
+ direction *= -1;
+
+ dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started. tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n", tuner_freq, agc2_integr, coarse_srate, timingcpt);
+
+ if ((timingcpt >= 5) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) {
+ timingLock = TRUE;
+ }
+
+ else if (current_step < nb_steps) {
+ if (direction > 0)
+ tuner_freq += (current_step * currier_step);
+ else
+ tuner_freq -= (current_step * currier_step);
+
+ stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw);
+ }
+ }
+
+ if (timingLock == FALSE)
+ coarse_srate = 0;
+ else
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0x12);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xf0);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xe0);
+ stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0);
+ stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0);
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x50);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x6a);
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x95);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x73);
+ }
+
+ if (i_params->dmd2_symbol_rate <= 2000000)
+ currier_step = 1000;
+ else if (i_params->dmd2_symbol_rate <= 5000000)
+ currier_step = 2000;
+ else if (i_params->dmd2_symbol_rate <= 12000000)
+ currier_step = 3000;
+ else
+ currier_step = 5000;
+
+
+ nb_steps = -1 + ((i_params->dmd2_srch_range / 1000) / currier_step);
+ nb_steps /= 2;
+ nb_steps = (2 * nb_steps) + 1;
+
+ if (nb_steps < 0)
+ nb_steps = 1;
+ else if (nb_steps > 10) {
+ nb_steps = 11;
+ currier_step = (i_params->dmd2_srch_range / 1000) / 10;
+ }
+
+ current_step = 0;
+ direction = 1;
+ tuner_freq = i_params->tuner2_freq;
+
+ while ((timingLock == FALSE) && (current_step < nb_steps)) {
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5F);
+ stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x0);
+
+ msleep(50);
+ timingcpt = 0;
+
+ for (i = 0; i < 20; i++) {
+ if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2)
+ timingcpt++;
+ agc2_integr += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P2_AGC2I0);
+ }
+
+ agc2_integr /= 20;
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ if ((timingcpt >= 10) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000))
+ timingLock = TRUE;
+ else {
+ current_step++;
+ direction *= -1;
+
+ if (direction > 0)
+ tuner_freq += (current_step * currier_step);
+ else
+ tuner_freq -= (current_step * currier_step);
+
+ stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw);
+ }
+ }
+
+ if (timingLock == FALSE)
+ coarse_srate = 0;
+ else
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ break;
+ }
+
+ return coarse_srate;
+}
+
+static u32 stv0900_search_srate_fine(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ u32 coarse_srate,
+ coarse_freq,
+ symb;
+
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ coarse_freq = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8)
+ | stv0900_read_reg(i_params, R0900_P1_CFR1);
+ symb = 13 * (coarse_srate / 10);
+
+ if (symb < i_params->dmd1_symbol_rate)
+ coarse_srate = 0;
+ else {
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x00);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
+
+ if (coarse_srate > 3000000) {
+ symb = 13 * (coarse_srate / 10);
+ symb = (symb / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF));
+
+ symb = 10 * (coarse_srate / 13);
+ symb = (symb / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF));
+
+ symb = (coarse_srate / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+ stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF));
+ } else {
+ symb = 13 * (coarse_srate / 10);
+ symb = (symb / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF));
+
+ symb = 10 * (coarse_srate / 14);
+ symb = (symb / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF));
+
+ symb = (coarse_srate / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF));
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (coarse_freq >> 8) & 0xff);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, coarse_freq & 0xff);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
+ }
+ break;
+ case STV0900_DEMOD_2:
+ coarse_freq = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8)
+ | stv0900_read_reg(i_params, R0900_P2_CFR1);
+
+ symb = 13 * (coarse_srate / 10);
+
+ if (symb < i_params->dmd2_symbol_rate)
+ coarse_srate = 0;
+ else {
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0x00);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
+
+ if (coarse_srate > 3000000) {
+ symb = 13 * (coarse_srate / 10);
+ symb = (symb / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF));
+
+ symb = 10 * (coarse_srate / 13);
+ symb = (symb / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF));
+
+ symb = (coarse_srate / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+ stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF));
+ } else {
+ symb = 13 * (coarse_srate / 10);
+ symb = (symb / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF));
+
+ symb = 10 * (coarse_srate / 14);
+ symb = (symb / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF));
+
+ symb = (coarse_srate / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF));
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (coarse_freq >> 8) & 0xff);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, coarse_freq & 0xff);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
+ }
+
+ break;
+ }
+
+ return coarse_srate;
+}
+
+static int stv0900_blind_search_algo(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ u8 k_ref_tmg, k_ref_tmg_max, k_ref_tmg_min;
+ u32 coarse_srate;
+ int lock = FALSE, coarse_fail = FALSE;
+ s32 demod_timeout = 500, fec_timeout = 50, kref_tmg_reg, fail_cpt, i, agc2_overflow;
+ u16 agc2_integr;
+ u8 dstatus2;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (i_params->chip_id < 0x20) {
+ k_ref_tmg_max = 233;
+ k_ref_tmg_min = 143;
+ } else {
+ k_ref_tmg_max = 120;
+ k_ref_tmg_min = 30;
+ }
+
+ agc2_integr = stv0900_blind_check_agc2_min_level(i_params, demod);
+
+ if (agc2_integr > STV0900_BLIND_SEARCH_AGC2_TH) {
+ lock = FALSE;
+
+ } else {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xAA);
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55);
+
+ stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xC4);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82);
+ stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0);
+ }
+
+ kref_tmg_reg = R0900_P1_KREFTMG;
+ break;
+ case STV0900_DEMOD_2:
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xAA);
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55);
+
+ stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xC4);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82);
+ stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0);
+ }
+
+ kref_tmg_reg = R0900_P2_KREFTMG;
+ break;
+ }
+
+ k_ref_tmg = k_ref_tmg_max;
+
+ do {
+ stv0900_write_reg(i_params, kref_tmg_reg, k_ref_tmg);
+ if (stv0900_search_srate_coarse(fe) != 0) {
+ coarse_srate = stv0900_search_srate_fine(fe);
+
+ if (coarse_srate != 0) {
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, coarse_srate, STV0900_BLIND_SEARCH);
+ lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
+ } else
+ lock = FALSE;
+ } else {
+ fail_cpt = 0;
+ agc2_overflow = 0;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ for (i = 0; i < 10; i++) {
+ agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P1_AGC2I0);
+
+ if (agc2_integr >= 0xff00)
+ agc2_overflow++;
+
+ dstatus2 = stv0900_read_reg(i_params, R0900_P1_DSTATUS2);
+
+ if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1))
+ fail_cpt++;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ for (i = 0; i < 10; i++) {
+ agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P2_AGC2I0);
+
+ if (agc2_integr >= 0xff00)
+ agc2_overflow++;
+
+ dstatus2 = stv0900_read_reg(i_params, R0900_P2_DSTATUS2);
+
+ if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1))
+ fail_cpt++;
+ }
+ break;
+ }
+
+ if ((fail_cpt > 7) || (agc2_overflow > 7))
+ coarse_fail = TRUE;
+
+ lock = FALSE;
+ }
+ k_ref_tmg -= 30;
+ } while ((k_ref_tmg >= k_ref_tmg_min) && (lock == FALSE) && (coarse_fail == FALSE));
+ }
+
+ return lock;
+}
+
+static void stv0900_set_viterbi_acq(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 vth_reg;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12);
+
+ stv0900_write_reg(i_params, vth_reg++, 0x96);
+ stv0900_write_reg(i_params, vth_reg++, 0x64);
+ stv0900_write_reg(i_params, vth_reg++, 0x36);
+ stv0900_write_reg(i_params, vth_reg++, 0x23);
+ stv0900_write_reg(i_params, vth_reg++, 0x1E);
+ stv0900_write_reg(i_params, vth_reg++, 0x19);
+}
+
+static void stv0900_set_search_standard(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+
+ int sstndrd;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ sstndrd = i_params->dmd1_srch_standard;
+ if (demod == 1)
+ sstndrd = i_params->dmd2_srch_stndrd;
+
+ switch (sstndrd) {
+ case STV0900_SEARCH_DVBS1:
+ dprintk("Search Standard = DVBS1\n");
+ break;
+ case STV0900_SEARCH_DSS:
+ dprintk("Search Standard = DSS\n");
+ case STV0900_SEARCH_DVBS2:
+ break;
+ dprintk("Search Standard = DVBS2\n");
+ case STV0900_AUTO_SEARCH:
+ default:
+ dprintk("Search Standard = AUTO\n");
+ break;
+ }
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ switch (i_params->dmd1_srch_standard) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0);
+ stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x22);
+
+ stv0900_set_viterbi_acq(i_params, demod);
+ stv0900_set_viterbi_standard(i_params,
+ i_params->dmd1_srch_standard,
+ i_params->dmd1_fec, demod);
+
+ break;
+ case STV0900_SEARCH_DVBS2:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 1);
+ stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26);
+ if (i_params->demod_mode != STV0900_SINGLE) {
+ if (i_params->chip_id <= 0x11)
+ stv0900_stop_all_s2_modcod(i_params, demod);
+ else
+ stv0900_activate_s2_modcode(i_params, demod);
+
+ } else
+ stv0900_activate_s2_modcode_single(i_params, demod);
+
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0);
+ stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26);
+ if (i_params->demod_mode != STV0900_SINGLE) {
+ if (i_params->chip_id <= 0x11)
+ stv0900_stop_all_s2_modcod(i_params, demod);
+ else
+ stv0900_activate_s2_modcode(i_params, demod);
+
+ } else
+ stv0900_activate_s2_modcode_single(i_params, demod);
+
+ if (i_params->dmd1_symbol_rate >= 2000000)
+ stv0900_set_viterbi_acq(i_params, demod);
+ else
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ stv0900_set_viterbi_standard(i_params, i_params->dmd1_srch_standard, i_params->dmd1_fec, demod);
+
+ break;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ switch (i_params->dmd2_srch_stndrd) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0);
+ stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x22);
+ stv0900_set_viterbi_acq(i_params, demod);
+ stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod);
+ break;
+ case STV0900_SEARCH_DVBS2:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 1);
+ stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26);
+ if (i_params->demod_mode != STV0900_SINGLE)
+ stv0900_activate_s2_modcode(i_params, demod);
+ else
+ stv0900_activate_s2_modcode_single(i_params, demod);
+
+ stv0900_set_viterbi_tracq(i_params, demod);
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0);
+ stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26);
+ if (i_params->demod_mode != STV0900_SINGLE)
+ stv0900_activate_s2_modcode(i_params, demod);
+ else
+ stv0900_activate_s2_modcode_single(i_params, demod);
+
+ if (i_params->dmd2_symbol_rate >= 2000000)
+ stv0900_set_viterbi_acq(i_params, demod);
+ else
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod);
+
+ break;
+ }
+
+ break;
+ }
+}
+
+enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ s32 demod_timeout = 500, fec_timeout = 50, stream_merger_field;
+
+ int lock = FALSE, low_sr = FALSE;
+
+ enum fe_stv0900_signal_type signal_type = STV0900_NOCARRIER;
+ enum fe_stv0900_search_algo algo;
+ int no_signal = FALSE;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ algo = i_params->dmd1_srch_algo;
+
+ stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1);
+ stream_merger_field = F0900_P1_RST_HWARE;
+
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C);
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x9e);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x88);
+
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd1_symbol_rate, i_params->dmd1_srch_algo);
+
+ if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
+ i_params->tuner1_bw = 2 * 36000000;
+
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x00);
+ stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2);
+
+ if (i_params->dmd1_symbol_rate < 2000000)
+ stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x63);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70);
+
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0x5a);
+
+ if (i_params->dmd1_srch_algo == STV0900_COLD_START)
+ i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10;
+ else if (i_params->dmd1_srch_algo == STV0900_WARM_START)
+ i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000;
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0xc1);
+ i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10;
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
+ stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
+ stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
+ if (i_params->dmd1_symbol_rate >= 10000000)
+ low_sr = FALSE;
+ else
+ low_sr = TRUE;
+
+ }
+
+ stv0900_set_tuner(fe, i_params->tuner1_freq, i_params->tuner1_bw);
+
+ stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, i_params->dmd1_srch_iq_inv);
+ stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
+
+ stv0900_set_search_standard(i_params, demod);
+
+ if (i_params->dmd1_srch_algo != STV0900_BLIND_SEARCH)
+ stv0900_start_search(i_params, demod);
+ break;
+ case STV0900_DEMOD_2:
+ algo = i_params->dmd2_srch_algo;
+
+ stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1);
+
+ stream_merger_field = F0900_P2_RST_HWARE;
+
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C);
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x9e);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x88);
+
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd2_symbol_rate, i_params->dmd2_srch_algo);
+
+ if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
+ i_params->tuner2_bw = 2 * 36000000;
+
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x00);
+ stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2);
+
+ if (i_params->dmd2_symbol_rate < 2000000)
+ stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x63);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70);
+
+ if (i_params->dmd2_symbol_rate >= 10000000)
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
+ else
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x60);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0x5a);
+
+ if (i_params->dmd2_srch_algo == STV0900_COLD_START)
+ i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate,
+ i_params->rolloff) + 10000000)) / 10;
+ else if (i_params->dmd2_srch_algo == STV0900_WARM_START)
+ i_params->tuner2_bw = stv0900_carrier_width(i_params->dmd2_symbol_rate,
+ i_params->rolloff) + 10000000;
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0xc1);
+ i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate,
+ i_params->rolloff) + 10000000)) / 10;
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
+ stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
+ stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
+ if (i_params->dmd2_symbol_rate >= 10000000)
+ low_sr = FALSE;
+ else
+ low_sr = TRUE;
+
+ }
+
+ stv0900_set_tuner(fe, i_params->tuner2_freq, i_params->tuner2_bw);
+
+ stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, i_params->dmd2_srch_iq_inv);
+ stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
+
+ stv0900_set_search_standard(i_params, demod);
+
+ if (i_params->dmd2_srch_algo != STV0900_BLIND_SEARCH)
+ stv0900_start_search(i_params, demod);
+ break;
+ }
+
+ if (i_params->chip_id == 0x12) {
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ msleep(3);
+ stv0900_write_bits(i_params, stream_merger_field, 1);
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ }
+
+ if (algo == STV0900_BLIND_SEARCH)
+ lock = stv0900_blind_search_algo(fe);
+ else if (algo == STV0900_COLD_START)
+ lock = stv0900_get_demod_cold_lock(fe, demod_timeout);
+ else if (algo == STV0900_WARM_START)
+ lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
+
+ if ((lock == FALSE) && (algo == STV0900_COLD_START)) {
+ if (low_sr == FALSE) {
+ if (stv0900_check_timing_lock(i_params, demod) == TRUE)
+ lock = stv0900_sw_algo(i_params, demod);
+ }
+ }
+
+ if (lock == TRUE)
+ signal_type = stv0900_get_signal_params(fe);
+
+ if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) {
+ stv0900_track_optimization(fe);
+ if (i_params->chip_id <= 0x11) {
+ if ((stv0900_get_standard(fe, STV0900_DEMOD_1) == STV0900_DVBS1_STANDARD) && (stv0900_get_standard(fe, STV0900_DEMOD_2) == STV0900_DVBS1_STANDARD)) {
+ msleep(20);
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ } else {
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ msleep(3);
+ stv0900_write_bits(i_params, stream_merger_field, 1);
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ }
+ } else if (i_params->chip_id == 0x20) {
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ msleep(3);
+ stv0900_write_bits(i_params, stream_merger_field, 1);
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ }
+
+ if (stv0900_wait_for_lock(i_params, demod, fec_timeout, fec_timeout) == TRUE) {
+ lock = TRUE;
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ i_params->dmd1_rslts.locked = TRUE;
+ if (i_params->dmd1_rslts.standard == STV0900_DVBS2_STANDARD) {
+ stv0900_set_dvbs2_rolloff(i_params, demod);
+ stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0x40);
+ stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0);
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_FBERCPT4, 0);
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL2, 0xc1);
+ break;
+ case STV0900_DEMOD_2:
+ i_params->dmd2_rslts.locked = TRUE;
+
+ if (i_params->dmd2_rslts.standard == STV0900_DVBS2_STANDARD) {
+ stv0900_set_dvbs2_rolloff(i_params, demod);
+ stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x60);
+ stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_FBERCPT4, 0);
+
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL2, 0xc1);
+ break;
+ }
+ } else {
+ lock = FALSE;
+ signal_type = STV0900_NODATA;
+ no_signal = stv0900_check_signal_presence(i_params, demod);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ i_params->dmd1_rslts.locked = FALSE;
+ break;
+ case STV0900_DEMOD_2:
+ i_params->dmd2_rslts.locked = FALSE;
+ break;
+ }
+ }
+ }
+
+ if ((signal_type == STV0900_NODATA) && (no_signal == FALSE)) {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ if (i_params->chip_id <= 0x11) {
+ if ((stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) &&
+ (i_params->dmd1_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST))
+ signal_type = stv0900_dvbs1_acq_workaround(fe);
+ } else
+ i_params->dmd1_rslts.locked = FALSE;
+
+ break;
+ case STV0900_DEMOD_2:
+ if (i_params->chip_id <= 0x11) {
+ if ((stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) &&
+ (i_params->dmd2_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST))
+ signal_type = stv0900_dvbs1_acq_workaround(fe);
+ } else
+ i_params->dmd2_rslts.locked = FALSE;
+ break;
+ }
+ }
+
+ return signal_type;
+}
+
diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c
new file mode 100644
index 000000000000..70efac869d28
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110.c
@@ -0,0 +1,456 @@
+/*
+ * stv6110.c
+ *
+ * Driver for ST STV6110 satellite tuner IC.
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+
+#include <linux/types.h>
+
+#include "stv6110.h"
+
+static int debug;
+
+struct stv6110_priv {
+ int i2c_address;
+ struct i2c_adapter *i2c;
+
+ u32 mclk;
+ u8 regs[8];
+};
+
+#define dprintk(args...) \
+ do { \
+ if (debug) \
+ printk(KERN_DEBUG args); \
+ } while (0)
+
+static s32 abssub(s32 a, s32 b)
+{
+ if (a > b)
+ return a - b;
+ else
+ return b - a;
+};
+
+static int stv6110_release(struct dvb_frontend *fe)
+{
+ kfree(fe->tuner_priv);
+ fe->tuner_priv = NULL;
+ return 0;
+}
+
+static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[],
+ int start, int len)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ int rc;
+ u8 cmdbuf[len + 1];
+ struct i2c_msg msg = {
+ .addr = priv->i2c_address,
+ .flags = 0,
+ .buf = cmdbuf,
+ .len = len + 1
+ };
+
+ dprintk("%s\n", __func__);
+
+ if (start + len > 8)
+ return -EINVAL;
+
+ memcpy(&cmdbuf[1], buf, len);
+ cmdbuf[0] = start;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ rc = i2c_transfer(priv->i2c, &msg, 1);
+ if (rc != 1)
+ dprintk("%s: i2c error\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return 0;
+}
+
+static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[],
+ int start, int len)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ int rc;
+ u8 reg[] = { start };
+ struct i2c_msg msg_wr = {
+ .addr = priv->i2c_address,
+ .flags = 0,
+ .buf = reg,
+ .len = 1,
+ };
+
+ struct i2c_msg msg_rd = {
+ .addr = priv->i2c_address,
+ .flags = I2C_M_RD,
+ .buf = regs,
+ .len = len,
+ };
+ /* write subaddr */
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ rc = i2c_transfer(priv->i2c, &msg_wr, 1);
+ if (rc != 1)
+ dprintk("%s: i2c error\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ /* read registers */
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ rc = i2c_transfer(priv->i2c, &msg_rd, 1);
+ if (rc != 1)
+ dprintk("%s: i2c error\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ memcpy(&priv->regs[start], regs, len);
+
+ return 0;
+}
+
+static int stv6110_read_reg(struct dvb_frontend *fe, int start)
+{
+ u8 buf[] = { 0 };
+ stv6110_read_regs(fe, buf, start, 1);
+
+ return buf[0];
+}
+
+static int stv6110_sleep(struct dvb_frontend *fe)
+{
+ u8 reg[] = { 0 };
+ stv6110_write_regs(fe, reg, 0, 1);
+
+ return 0;
+}
+
+static u32 carrier_width(u32 symbol_rate, fe_rolloff_t rolloff)
+{
+ u32 rlf;
+
+ switch (rolloff) {
+ case ROLLOFF_20:
+ rlf = 20;
+ break;
+ case ROLLOFF_25:
+ rlf = 25;
+ break;
+ default:
+ rlf = 35;
+ break;
+ }
+
+ return symbol_rate + ((symbol_rate * rlf) / 100);
+}
+
+static int stv6110_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ u8 r8, ret = 0x04;
+ int i;
+
+ if ((bandwidth / 2) > 36000000) /*BW/2 max=31+5=36 mhz for r8=31*/
+ r8 = 31;
+ else if ((bandwidth / 2) < 5000000) /* BW/2 min=5Mhz for F=0 */
+ r8 = 0;
+ else /*if 5 < BW/2 < 36*/
+ r8 = (bandwidth / 2) / 1000000 - 5;
+
+ /* ctrl3, RCCLKOFF = 0 Activate the calibration Clock */
+ /* ctrl3, CF = r8 Set the LPF value */
+ priv->regs[RSTV6110_CTRL3] &= ~((1 << 6) | 0x1f);
+ priv->regs[RSTV6110_CTRL3] |= (r8 & 0x1f);
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
+ /* stat1, CALRCSTRT = 1 Start LPF auto calibration*/
+ priv->regs[RSTV6110_STAT1] |= 0x02;
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_STAT1], RSTV6110_STAT1, 1);
+
+ i = 0;
+ /* Wait for CALRCSTRT == 0 */
+ while ((i < 10) && (ret != 0)) {
+ ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x02);
+ mdelay(1); /* wait for LPF auto calibration */
+ i++;
+ }
+
+ /* RCCLKOFF = 1 calibration done, desactivate the calibration Clock */
+ priv->regs[RSTV6110_CTRL3] |= (1 << 6);
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
+ return 0;
+}
+
+static int stv6110_init(struct dvb_frontend *fe)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ u8 buf0[] = { 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
+
+ memcpy(priv->regs, buf0, 8);
+ /* K = (Reference / 1000000) - 16 */
+ priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
+ priv->regs[RSTV6110_CTRL1] |=
+ ((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
+
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8);
+ msleep(1);
+ stv6110_set_bandwidth(fe, 72000000);
+
+ return 0;
+}
+
+static int stv6110_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ u32 nbsteps, divider, psd2, freq;
+ u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ stv6110_read_regs(fe, regs, 0, 8);
+ /*N*/
+ divider = (priv->regs[RSTV6110_TUNING2] & 0x0f) << 8;
+ divider += priv->regs[RSTV6110_TUNING1];
+
+ /*R*/
+ nbsteps = (priv->regs[RSTV6110_TUNING2] >> 6) & 3;
+ /*p*/
+ psd2 = (priv->regs[RSTV6110_TUNING2] >> 4) & 1;
+
+ freq = divider * (priv->mclk / 1000);
+ freq /= (1 << (nbsteps + psd2));
+ freq /= 4;
+
+ *frequency = freq;
+
+ return 0;
+}
+
+static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ u8 ret = 0x04;
+ u32 divider, ref, p, presc, i, result_freq, vco_freq;
+ s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val;
+ s32 srate; u8 gain;
+
+ dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
+ frequency, priv->mclk);
+
+ /* K = (Reference / 1000000) - 16 */
+ priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
+ priv->regs[RSTV6110_CTRL1] |=
+ ((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
+
+ /* BB_GAIN = db/2 */
+ if (fe->ops.set_property && fe->ops.get_property) {
+ srate = c->symbol_rate;
+ dprintk("%s: Get Frontend parameters: srate=%d\n",
+ __func__, srate);
+ } else
+ srate = 15000000;
+
+ if (srate >= 15000000)
+ gain = 3; /* +6 dB */
+ else if (srate >= 5000000)
+ gain = 3; /* +6 dB */
+ else
+ gain = 3; /* +6 dB */
+
+ priv->regs[RSTV6110_CTRL2] &= ~0x0f;
+ priv->regs[RSTV6110_CTRL2] |= (gain & 0x0f);
+
+ if (frequency <= 1023000) {
+ p = 1;
+ presc = 0;
+ } else if (frequency <= 1300000) {
+ p = 1;
+ presc = 1;
+ } else if (frequency <= 2046000) {
+ p = 0;
+ presc = 0;
+ } else {
+ p = 0;
+ presc = 1;
+ }
+ /* DIV4SEL = p*/
+ priv->regs[RSTV6110_TUNING2] &= ~(1 << 4);
+ priv->regs[RSTV6110_TUNING2] |= (p << 4);
+
+ /* PRESC32ON = presc */
+ priv->regs[RSTV6110_TUNING2] &= ~(1 << 5);
+ priv->regs[RSTV6110_TUNING2] |= (presc << 5);
+
+ p_val = (int)(1 << (p + 1)) * 10;/* P = 2 or P = 4 */
+ for (r_div = 0; r_div <= 3; r_div++) {
+ p_calc = (priv->mclk / 100000);
+ p_calc /= (1 << (r_div + 1));
+ if ((abssub(p_calc, p_val)) < (abssub(p_calc_opt, p_val)))
+ r_div_opt = r_div;
+
+ p_calc_opt = (priv->mclk / 100000);
+ p_calc_opt /= (1 << (r_div_opt + 1));
+ }
+
+ ref = priv->mclk / ((1 << (r_div_opt + 1)) * (1 << (p + 1)));
+ divider = (((frequency * 1000) + (ref >> 1)) / ref);
+
+ /* RDIV = r_div_opt */
+ priv->regs[RSTV6110_TUNING2] &= ~(3 << 6);
+ priv->regs[RSTV6110_TUNING2] |= (((r_div_opt) & 3) << 6);
+
+ /* NDIV_MSB = MSB(divider) */
+ priv->regs[RSTV6110_TUNING2] &= ~0x0f;
+ priv->regs[RSTV6110_TUNING2] |= (((divider) >> 8) & 0x0f);
+
+ /* NDIV_LSB, LSB(divider) */
+ priv->regs[RSTV6110_TUNING1] = (divider & 0xff);
+
+ /* CALVCOSTRT = 1 VCO Auto Calibration */
+ priv->regs[RSTV6110_STAT1] |= 0x04;
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1],
+ RSTV6110_CTRL1, 8);
+
+ i = 0;
+ /* Wait for CALVCOSTRT == 0 */
+ while ((i < 10) && (ret != 0)) {
+ ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x04);
+ msleep(1); /* wait for VCO auto calibration */
+ i++;
+ }
+
+ ret = stv6110_read_reg(fe, RSTV6110_STAT1);
+ stv6110_get_frequency(fe, &result_freq);
+
+ vco_freq = divider * ((priv->mclk / 1000) / ((1 << (r_div_opt + 1))));
+ dprintk("%s, stat1=%x, lo_freq=%d kHz, vco_frec=%d kHz\n", __func__,
+ ret, result_freq, vco_freq);
+
+ return 0;
+}
+
+static int stv6110_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ u32 bandwidth = carrier_width(c->symbol_rate, c->rolloff);
+
+ stv6110_set_frequency(fe, c->frequency);
+ stv6110_set_bandwidth(fe, bandwidth);
+
+ return 0;
+}
+
+static int stv6110_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ u8 r8 = 0;
+ u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ stv6110_read_regs(fe, regs, 0, 8);
+
+ /* CF */
+ r8 = priv->regs[RSTV6110_CTRL3] & 0x1f;
+ *bandwidth = (r8 + 5) * 2000000;/* x2 for ZIF tuner BW/2 = F+5 Mhz */
+
+ return 0;
+}
+
+static struct dvb_tuner_ops stv6110_tuner_ops = {
+ .info = {
+ .name = "ST STV6110",
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_step = 1000,
+ },
+ .init = stv6110_init,
+ .release = stv6110_release,
+ .sleep = stv6110_sleep,
+ .set_params = stv6110_set_params,
+ .get_frequency = stv6110_get_frequency,
+ .set_frequency = stv6110_set_frequency,
+ .get_bandwidth = stv6110_get_bandwidth,
+ .set_bandwidth = stv6110_set_bandwidth,
+
+};
+
+struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+ const struct stv6110_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct stv6110_priv *priv = NULL;
+ u8 reg0[] = { 0x00, 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = config->i2c_address,
+ .flags = 0,
+ .buf = reg0,
+ .len = 9
+ }
+ };
+ int ret;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ ret = i2c_transfer(i2c, msg, 1);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ if (ret != 1)
+ return NULL;
+
+ priv = kzalloc(sizeof(struct stv6110_priv), GFP_KERNEL);
+ if (priv == NULL)
+ return NULL;
+
+ priv->i2c_address = config->i2c_address;
+ priv->i2c = i2c;
+ priv->mclk = config->mclk;
+
+ memcpy(&priv->regs, &reg0[1], 8);
+
+ memcpy(&fe->ops.tuner_ops, &stv6110_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+ fe->tuner_priv = priv;
+ printk(KERN_INFO "STV6110 attached on addr=%x!\n", priv->i2c_address);
+
+ return fe;
+}
+EXPORT_SYMBOL(stv6110_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("ST STV6110 driver");
+MODULE_AUTHOR("Igor M. Liplianin");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv6110.h b/drivers/media/dvb/frontends/stv6110.h
new file mode 100644
index 000000000000..1c0314d6aa55
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110.h
@@ -0,0 +1,62 @@
+/*
+ * stv6110.h
+ *
+ * Driver for ST STV6110 satellite tuner IC.
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __DVB_STV6110_H__
+#define __DVB_STV6110_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/* registers */
+#define RSTV6110_CTRL1 0
+#define RSTV6110_CTRL2 1
+#define RSTV6110_TUNING1 2
+#define RSTV6110_TUNING2 3
+#define RSTV6110_CTRL3 4
+#define RSTV6110_STAT1 5
+#define RSTV6110_STAT2 6
+#define RSTV6110_STAT3 7
+
+struct stv6110_config {
+ u8 i2c_address;
+ u32 mclk;
+ int iq_wiring;
+};
+
+#if defined(CONFIG_DVB_STV6110) || (defined(CONFIG_DVB_STV6110_MODULE) \
+ && defined(MODULE))
+extern struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+ const struct stv6110_config *config,
+ struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+ const struct stv6110_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 1465ff77b0cb..4981cef8b444 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -162,7 +162,7 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
if (ret != 2) {
dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
ret);
- return -1;
+ return -EINVAL;
}
dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__,
@@ -481,16 +481,18 @@ static void tda10046_init_plls(struct dvb_frontend* fe)
static int tda10046_fwupload(struct dvb_frontend* fe)
{
struct tda1004x_state* state = fe->demodulator_priv;
- int ret;
+ int ret, confc4;
const struct firmware *fw;
/* reset + wake up chip */
if (state->config->xtal_freq == TDA10046_XTAL_4M) {
- tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
+ confc4 = 0;
} else {
dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__);
- tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
+ confc4 = 0x80;
}
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
+
tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
/* set GPIO 1 and 3 */
if (state->config->gpio_config != TDA10046_GPTRI) {
@@ -508,13 +510,29 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
if (tda1004x_check_upload_ok(state) == 0)
return 0;
+ /*
+ For i2c normal work, we need to slow down the bus speed.
+ However, the slow down breaks the eeprom firmware load.
+ So, use normal speed for eeprom booting and then restore the
+ i2c speed after that. Tested with MSI TV @nyware A/D board,
+ that comes with firmware version 29 inside their eeprom.
+
+ It should also be noticed that no other I2C transfer should
+ be in course while booting from eeprom, otherwise, tda10046
+ goes into an instable state. So, proper locking are needed
+ at the i2c bus master.
+ */
printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
- tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, 4);
msleep(300);
- /* don't re-upload unless necessary */
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
+
+ /* Checks if eeprom firmware went without troubles */
if (tda1004x_check_upload_ok(state) == 0)
return 0;
+ /* eeprom firmware didn't work. Load one manually. */
+
if (state->config->request_firmware != NULL) {
/* request the firmware, this will block until someone uploads it */
printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c
new file mode 100644
index 000000000000..e22a0b381dc4
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10036.c
@@ -0,0 +1,519 @@
+/**
+ * Driver for Zarlink zl10036 DVB-S silicon tuner
+ *
+ * Copyright (C) 2006 Tino Reichardt
+ * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ **
+ * The data sheet for this tuner can be found at:
+ * http://www.mcmilk.de/projects/dvb-card/datasheets/ZL10036.pdf
+ *
+ * This one is working: (at my Avermedia DVB-S Pro)
+ * - zl10036 (40pin, FTA)
+ *
+ * A driver for zl10038 should be very similar.
+ */
+
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+#include <asm/types.h>
+
+#include "zl10036.h"
+
+static int zl10036_debug;
+#define dprintk(level, args...) \
+ do { if (zl10036_debug & level) printk(KERN_DEBUG "zl10036: " args); \
+ } while (0)
+
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_i2c(args...) dprintk(0x02, args)
+
+struct zl10036_state {
+ struct i2c_adapter *i2c;
+ const struct zl10036_config *config;
+ u32 frequency;
+ u8 br, bf;
+};
+
+
+/* This driver assumes the tuner is driven by a 10.111MHz Cristal */
+#define _XTAL 10111
+
+/* Some of the possible dividers:
+ * 64, (write 0x05 to reg), freq step size 158kHz
+ * 10, (write 0x0a to reg), freq step size 1.011kHz (used here)
+ * 5, (write 0x09 to reg), freq step size 2.022kHz
+ */
+
+#define _RDIV 10
+#define _RDIV_REG 0x0a
+#define _FR (_XTAL/_RDIV)
+
+#define STATUS_POR 0x80 /* Power on Reset */
+#define STATUS_FL 0x40 /* Frequency & Phase Lock */
+
+/* read/write for zl10036 and zl10038 */
+
+static int zl10036_read_status_reg(struct zl10036_state *state)
+{
+ u8 status;
+ struct i2c_msg msg[1] = {
+ { .addr = state->config->tuner_address, .flags = I2C_M_RD,
+ .buf = &status, .len = sizeof(status) },
+ };
+
+ if (i2c_transfer(state->i2c, msg, 1) != 1) {
+ printk(KERN_ERR "%s: i2c read failed at addr=%02x\n",
+ __func__, state->config->tuner_address);
+ return -EIO;
+ }
+
+ deb_i2c("R(status): %02x [FL=%d]\n", status,
+ (status & STATUS_FL) ? 1 : 0);
+ if (status & STATUS_POR)
+ deb_info("%s: Power-On-Reset bit enabled - "
+ "need to initialize the tuner\n", __func__);
+
+ return status;
+}
+
+static int zl10036_write(struct zl10036_state *state, u8 buf[], u8 count)
+{
+ struct i2c_msg msg[1] = {
+ { .addr = state->config->tuner_address, .flags = 0,
+ .buf = buf, .len = count },
+ };
+ u8 reg = 0;
+ int ret;
+
+ if (zl10036_debug & 0x02) {
+ /* every 8bit-value satisifes this!
+ * so only check for debug log */
+ if ((buf[0] & 0x80) == 0x00)
+ reg = 2;
+ else if ((buf[0] & 0xc0) == 0x80)
+ reg = 4;
+ else if ((buf[0] & 0xf0) == 0xc0)
+ reg = 6;
+ else if ((buf[0] & 0xf0) == 0xd0)
+ reg = 8;
+ else if ((buf[0] & 0xf0) == 0xe0)
+ reg = 10;
+ else if ((buf[0] & 0xf0) == 0xf0)
+ reg = 12;
+
+ deb_i2c("W(%d):", reg);
+ {
+ int i;
+ for (i = 0; i < count; i++)
+ printk(KERN_CONT " %02x", buf[i]);
+ printk(KERN_CONT "\n");
+ }
+ }
+
+ ret = i2c_transfer(state->i2c, msg, 1);
+ if (ret != 1) {
+ printk(KERN_ERR "%s: i2c error, ret=%d\n", __func__, ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int zl10036_release(struct dvb_frontend *fe)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+
+ fe->tuner_priv = NULL;
+ kfree(state);
+
+ return 0;
+}
+
+static int zl10036_sleep(struct dvb_frontend *fe)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+ u8 buf[] = { 0xf0, 0x80 }; /* regs 12/13 */
+ int ret;
+
+ deb_info("%s\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = zl10036_write(state, buf, sizeof(buf));
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ return ret;
+}
+
+/**
+ * register map of the ZL10036/ZL10038
+ *
+ * reg[default] content
+ * 2[0x00]: 0 | N14 | N13 | N12 | N11 | N10 | N9 | N8
+ * 3[0x00]: N7 | N6 | N5 | N4 | N3 | N2 | N1 | N0
+ * 4[0x80]: 1 | 0 | RFG | BA1 | BA0 | BG1 | BG0 | LEN
+ * 5[0x00]: P0 | C1 | C0 | R4 | R3 | R2 | R1 | R0
+ * 6[0xc0]: 1 | 1 | 0 | 0 | RSD | 0 | 0 | 0
+ * 7[0x20]: P1 | BF6 | BF5 | BF4 | BF3 | BF2 | BF1 | 0
+ * 8[0xdb]: 1 | 1 | 0 | 1 | 0 | CC | 1 | 1
+ * 9[0x30]: VSD | V2 | V1 | V0 | S3 | S2 | S1 | S0
+ * 10[0xe1]: 1 | 1 | 1 | 0 | 0 | LS2 | LS1 | LS0
+ * 11[0xf5]: WS | WH2 | WH1 | WH0 | WL2 | WL1 | WL0 | WRE
+ * 12[0xf0]: 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0
+ * 13[0x28]: PD | BR4 | BR3 | BR2 | BR1 | BR0 | CLR | TL
+ */
+
+static int zl10036_set_frequency(struct zl10036_state *state, u32 frequency)
+{
+ u8 buf[2];
+ u32 div, foffset;
+
+ div = (frequency + _FR/2) / _FR;
+ state->frequency = div * _FR;
+
+ foffset = frequency - state->frequency;
+
+ buf[0] = (div >> 8) & 0x7f;
+ buf[1] = (div >> 0) & 0xff;
+
+ deb_info("%s: ftodo=%u fpriv=%u ferr=%d div=%u\n", __func__,
+ frequency, state->frequency, foffset, div);
+
+ return zl10036_write(state, buf, sizeof(buf));
+}
+
+static int zl10036_set_bandwidth(struct zl10036_state *state, u32 fbw)
+{
+ /* fbw is measured in kHz */
+ u8 br, bf;
+ int ret;
+ u8 buf_bf[] = {
+ 0xc0, 0x00, /* 6/7: rsd=0 bf=0 */
+ };
+ u8 buf_br[] = {
+ 0xf0, 0x00, /* 12/13: br=0xa clr=0 tl=0*/
+ };
+ u8 zl10036_rsd_off[] = { 0xc8 }; /* set RSD=1 */
+
+ /* ensure correct values */
+ if (fbw > 35000)
+ fbw = 35000;
+ if (fbw < 8000)
+ fbw = 8000;
+
+#define _BR_MAXIMUM (_XTAL/575) /* _XTAL / 575kHz = 17 */
+
+ /* <= 28,82 MHz */
+ if (fbw <= 28820) {
+ br = _BR_MAXIMUM;
+ } else {
+ /**
+ * f(bw)=34,6MHz f(xtal)=10.111MHz
+ * br = (10111/34600) * 63 * 1/K = 14;
+ */
+ br = ((_XTAL * 21 * 1000) / (fbw * 419));
+ }
+
+ /* ensure correct values */
+ if (br < 4)
+ br = 4;
+ if (br > _BR_MAXIMUM)
+ br = _BR_MAXIMUM;
+
+ /*
+ * k = 1.257
+ * bf = fbw/_XTAL * br * k - 1 */
+
+ bf = (fbw * br * 1257) / (_XTAL * 1000) - 1;
+
+ /* ensure correct values */
+ if (bf > 62)
+ bf = 62;
+
+ buf_bf[1] = (bf << 1) & 0x7e;
+ buf_br[1] = (br << 2) & 0x7c;
+ deb_info("%s: BW=%d br=%u bf=%u\n", __func__, fbw, br, bf);
+
+ if (br != state->br) {
+ ret = zl10036_write(state, buf_br, sizeof(buf_br));
+ if (ret < 0)
+ return ret;
+ }
+
+ if (bf != state->bf) {
+ ret = zl10036_write(state, buf_bf, sizeof(buf_bf));
+ if (ret < 0)
+ return ret;
+
+ /* time = br/(32* fxtal) */
+ /* minimal sleep time to be calculated
+ * maximum br is 63 -> max time = 2 /10 MHz = 2e-7 */
+ msleep(1);
+
+ ret = zl10036_write(state, zl10036_rsd_off,
+ sizeof(zl10036_rsd_off));
+ if (ret < 0)
+ return ret;
+ }
+
+ state->br = br;
+ state->bf = bf;
+
+ return 0;
+}
+
+static int zl10036_set_gain_params(struct zl10036_state *state,
+ int c)
+{
+ u8 buf[2];
+ u8 rfg, ba, bg;
+
+ /* default values */
+ rfg = 0; /* enable when using an lna */
+ ba = 1;
+ bg = 1;
+
+ /* reg 4 */
+ buf[0] = 0x80 | ((rfg << 5) & 0x20)
+ | ((ba << 3) & 0x18) | ((bg << 1) & 0x06);
+
+ if (!state->config->rf_loop_enable)
+ buf[0] |= 0x01;
+
+ /* P0=0 */
+ buf[1] = _RDIV_REG | ((c << 5) & 0x60);
+
+ deb_info("%s: c=%u rfg=%u ba=%u bg=%u\n", __func__, c, rfg, ba, bg);
+ return zl10036_write(state, buf, sizeof(buf));
+}
+
+static int zl10036_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+ int ret = 0;
+ u32 frequency = params->frequency;
+ u32 fbw;
+ int i;
+ u8 c;
+
+ /* ensure correct values
+ * maybe redundant as core already checks this */
+ if ((frequency < fe->ops.info.frequency_min)
+ || (frequency > fe->ops.info.frequency_max))
+ return -EINVAL;
+
+ /**
+ * alpha = 1.35 for dvb-s
+ * fBW = (alpha*symbolrate)/(2*0.8)
+ * 1.35 / (2*0.8) = 27 / 32
+ */
+ fbw = (27 * params->u.qpsk.symbol_rate) / 32;
+
+ /* scale to kHz */
+ fbw /= 1000;
+
+ /* Add safe margin of 3MHz */
+ fbw += 3000;
+
+ /* setting the charge pump - guessed values */
+ if (frequency < 950000)
+ return -EINVAL;
+ else if (frequency < 1250000)
+ c = 0;
+ else if (frequency < 1750000)
+ c = 1;
+ else if (frequency < 2175000)
+ c = 2;
+ else
+ return -EINVAL;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = zl10036_set_gain_params(state, c);
+ if (ret < 0)
+ goto error;
+
+ ret = zl10036_set_frequency(state, params->frequency);
+ if (ret < 0)
+ goto error;
+
+ ret = zl10036_set_bandwidth(state, fbw);
+ if (ret < 0)
+ goto error;
+
+ /* wait for tuner lock - no idea if this is really needed */
+ for (i = 0; i < 20; i++) {
+ ret = zl10036_read_status_reg(state);
+ if (ret < 0)
+ goto error;
+
+ /* check Frequency & Phase Lock Bit */
+ if (ret & STATUS_FL)
+ break;
+
+ msleep(10);
+ }
+
+error:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ return ret;
+}
+
+static int zl10036_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+
+ *frequency = state->frequency;
+
+ return 0;
+}
+
+static int zl10036_init_regs(struct zl10036_state *state)
+{
+ int ret;
+ int i;
+
+ /* could also be one block from reg 2 to 13 and additional 10/11 */
+ u8 zl10036_init_tab[][2] = {
+ { 0x04, 0x00 }, /* 2/3: div=0x400 - arbitrary value */
+ { 0x8b, _RDIV_REG }, /* 4/5: rfg=0 ba=1 bg=1 len=? */
+ /* p0=0 c=0 r=_RDIV_REG */
+ { 0xc0, 0x20 }, /* 6/7: rsd=0 bf=0x10 */
+ { 0xd3, 0x40 }, /* 8/9: from datasheet */
+ { 0xe3, 0x5b }, /* 10/11: lock window level */
+ { 0xf0, 0x28 }, /* 12/13: br=0xa clr=0 tl=0*/
+ { 0xe3, 0xf9 }, /* 10/11: unlock window level */
+ };
+
+ /* invalid values to trigger writing */
+ state->br = 0xff;
+ state->bf = 0xff;
+
+ if (!state->config->rf_loop_enable)
+ zl10036_init_tab[1][2] |= 0x01;
+
+ deb_info("%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(zl10036_init_tab); i++) {
+ ret = zl10036_write(state, zl10036_init_tab[i], 2);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int zl10036_init(struct dvb_frontend *fe)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+ int ret = 0;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = zl10036_read_status_reg(state);
+ if (ret < 0)
+ return ret;
+
+ /* Only init if Power-on-Reset bit is set? */
+ ret = zl10036_init_regs(state);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ return ret;
+}
+
+static struct dvb_tuner_ops zl10036_tuner_ops = {
+ .info = {
+ .name = "Zarlink ZL10036",
+ .frequency_min = 950000,
+ .frequency_max = 2175000
+ },
+ .init = zl10036_init,
+ .release = zl10036_release,
+ .sleep = zl10036_sleep,
+ .set_params = zl10036_set_params,
+ .get_frequency = zl10036_get_frequency,
+};
+
+struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+ const struct zl10036_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct zl10036_state *state = NULL;
+ int ret;
+
+ if (NULL == config) {
+ printk(KERN_ERR "%s: no config specified", __func__);
+ goto error;
+ }
+
+ state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL);
+ if (NULL == state)
+ return NULL;
+
+ state->config = config;
+ state->i2c = i2c;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = zl10036_read_status_reg(state);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: No zl10036 found\n", __func__);
+ goto error;
+ }
+
+ ret = zl10036_init_regs(state);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: tuner initialization failed\n",
+ __func__);
+ goto error;
+ }
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ fe->tuner_priv = state;
+
+ memcpy(&fe->ops.tuner_ops, &zl10036_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+ printk(KERN_INFO "%s: tuner initialization (%s addr=0x%02x) ok\n",
+ __func__, fe->ops.tuner_ops.info.name, config->tuner_address);
+
+ return fe;
+
+error:
+ zl10036_release(fe);
+ return NULL;
+}
+EXPORT_SYMBOL(zl10036_attach);
+
+module_param_named(debug, zl10036_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+MODULE_DESCRIPTION("DVB ZL10036 driver");
+MODULE_AUTHOR("Tino Reichardt");
+MODULE_AUTHOR("Matthias Schwarzott");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/zl10036.h b/drivers/media/dvb/frontends/zl10036.h
new file mode 100644
index 000000000000..d84b8f8215e9
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10036.h
@@ -0,0 +1,53 @@
+/**
+ * Driver for Zarlink ZL10036 DVB-S silicon tuner
+ *
+ * Copyright (C) 2006 Tino Reichardt
+ * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef DVB_ZL10036_H
+#define DVB_ZL10036_H
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/**
+ * Attach a zl10036 tuner to the supplied frontend structure.
+ *
+ * @param fe Frontend to attach to.
+ * @param config zl10036_config structure
+ * @return FE pointer on success, NULL on failure.
+ */
+
+struct zl10036_config {
+ u8 tuner_address;
+ int rf_loop_enable;
+};
+
+#if defined(CONFIG_DVB_ZL10036) || \
+ (defined(CONFIG_DVB_ZL10036_MODULE) && defined(MODULE))
+extern struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+ const struct zl10036_config *config, struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+ const struct zl10036_config *config, struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif /* DVB_ZL10036_H */
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
index b150ed306696..148b6f7f6cb2 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -572,6 +572,10 @@ static int zl10353_init(struct dvb_frontend *fe)
zl10353_dump_regs(fe);
if (state->config.parallel_ts)
zl10353_reset_attach[2] &= ~0x20;
+ if (state->config.clock_ctl_1)
+ zl10353_reset_attach[3] = state->config.clock_ctl_1;
+ if (state->config.pll_0)
+ zl10353_reset_attach[4] = state->config.pll_0;
/* Do a "hard" reset if not already done */
if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] ||
@@ -614,6 +618,7 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
struct i2c_adapter *i2c)
{
struct zl10353_state *state = NULL;
+ int id;
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL);
@@ -625,7 +630,8 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
memcpy(&state->config, config, sizeof(struct zl10353_config));
/* check if the demod is there */
- if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353)
+ id = zl10353_read_register(state, CHIP_ID);
+ if ((id != ID_ZL10353) && (id != ID_CE6230) && (id != ID_CE6231))
goto error;
/* create dvb_frontend */
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
index 2287bac46243..6e3ca9eed048 100644
--- a/drivers/media/dvb/frontends/zl10353.h
+++ b/drivers/media/dvb/frontends/zl10353.h
@@ -41,6 +41,10 @@ struct zl10353_config
/* set if i2c_gate_ctrl disable is required */
u8 disable_i2c_gate_ctrl:1;
+
+ /* clock control registers (0x51-0x54) */
+ u8 clock_ctl_1; /* default: 0x46 */
+ u8 pll_0; /* default: 0x15 */
};
#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE))
diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h
index 055ff1f7e349..e0dd1d3e09dd 100644
--- a/drivers/media/dvb/frontends/zl10353_priv.h
+++ b/drivers/media/dvb/frontends/zl10353_priv.h
@@ -22,7 +22,9 @@
#ifndef _ZL10353_PRIV_
#define _ZL10353_PRIV_
-#define ID_ZL10353 0x14
+#define ID_ZL10353 0x14 /* Zarlink ZL10353 */
+#define ID_CE6230 0x18 /* Intel CE6230 */
+#define ID_CE6231 0x19 /* Intel CE6231 */
#define msb(x) (((x) >> 8) & 0xff)
#define lsb(x) ((x) & 0xff)
@@ -50,6 +52,10 @@ enum zl10353_reg_addr {
TPS_RECEIVED_0 = 0x1E,
TPS_CURRENT_1 = 0x1F,
TPS_CURRENT_0 = 0x20,
+ CLOCK_CTL_0 = 0x51,
+ CLOCK_CTL_1 = 0x52,
+ PLL_0 = 0x53,
+ PLL_1 = 0x54,
RESET = 0x55,
AGC_TARGET = 0x56,
MCLK_RATIO = 0x5C,
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index d101b304e9b0..ee89623be85a 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -116,6 +116,7 @@ struct pluto {
/* irq */
unsigned int overflow;
+ unsigned int dead;
/* dma */
dma_addr_t dma_addr;
@@ -336,8 +337,10 @@ static irqreturn_t pluto_irq(int irq, void *dev_id)
return IRQ_NONE;
if (tscr == 0xffffffff) {
- // FIXME: maybe recover somehow
- dev_err(&pluto->pdev->dev, "card hung up :(\n");
+ if (pluto->dead == 0)
+ dev_err(&pluto->pdev->dev, "card has hung or been ejected.\n");
+ /* It's dead Jim */
+ pluto->dead = 1;
return IRQ_HANDLED;
}
diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile
index ee0737af98c0..bcf93f4828b2 100644
--- a/drivers/media/dvb/siano/Makefile
+++ b/drivers/media/dvb/siano/Makefile
@@ -1,6 +1,8 @@
-sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o sms-cards.o
+sms1xxx-objs := smscoreapi.o sms-cards.o
obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o
+obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o
+obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsdvb.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index 4307e4e8aa34..63e4d0ec6583 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -19,50 +19,9 @@
#include "sms-cards.h"
-struct usb_device_id smsusb_id_table[] = {
-#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS
- { USB_DEVICE(0x187f, 0x0010),
- .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
- { USB_DEVICE(0x187f, 0x0100),
- .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
- { USB_DEVICE(0x187f, 0x0200),
- .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A },
- { USB_DEVICE(0x187f, 0x0201),
- .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
- { USB_DEVICE(0x187f, 0x0300),
- .driver_info = SMS1XXX_BOARD_SIANO_VEGA },
-#endif
- { USB_DEVICE(0x2040, 0x1700),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT },
- { USB_DEVICE(0x2040, 0x1800),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A },
- { USB_DEVICE(0x2040, 0x1801),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
- { USB_DEVICE(0x2040, 0x2000),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
- { USB_DEVICE(0x2040, 0x2009),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 },
- { USB_DEVICE(0x2040, 0x200a),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
- { USB_DEVICE(0x2040, 0x2010),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
- { USB_DEVICE(0x2040, 0x2019),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
- { USB_DEVICE(0x2040, 0x5500),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0x5510),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0x5520),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0x5530),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0x5580),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0x5590),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, smsusb_id_table);
+static int sms_dbg;
+module_param_named(cards_dbg, sms_dbg, int, 0644);
+MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
static struct sms_board sms_boards[] = {
[SMS_BOARD_UNKNOWN] = {
@@ -115,6 +74,7 @@ static struct sms_board sms_boards[] = {
.type = SMS_NOVA_B0,
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
.lna_ctrl = 29,
+ .rf_switch = 17,
},
[SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
.name = "Hauppauge WinTV MiniCard",
@@ -130,6 +90,7 @@ struct sms_board *sms_get_board(int id)
return &sms_boards[id];
}
+EXPORT_SYMBOL_GPL(sms_get_board);
static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
{
@@ -182,6 +143,7 @@ int sms_board_setup(struct smscore_device_t *coredev)
}
return 0;
}
+EXPORT_SYMBOL_GPL(sms_board_setup);
int sms_board_power(struct smscore_device_t *coredev, int onoff)
{
@@ -197,12 +159,13 @@ int sms_board_power(struct smscore_device_t *coredev, int onoff)
case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
/* LNA */
- sms_set_gpio(coredev,
- board->lna_ctrl, onoff ? 1 : 0);
+ if (!onoff)
+ sms_set_gpio(coredev, board->lna_ctrl, 0);
break;
}
return 0;
}
+EXPORT_SYMBOL_GPL(sms_board_power);
int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
{
@@ -225,3 +188,40 @@ int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
}
return 0;
}
+EXPORT_SYMBOL_GPL(sms_board_led_feedback);
+
+int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)
+{
+ int board_id = smscore_get_board_id(coredev);
+ struct sms_board *board = sms_get_board(board_id);
+
+ sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled");
+
+ switch (board_id) {
+ case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
+ case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+ sms_set_gpio(coredev,
+ board->rf_switch, onoff ? 1 : 0);
+ return sms_set_gpio(coredev,
+ board->lna_ctrl, onoff ? 1 : 0);
+ }
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(sms_board_lna_control);
+
+int sms_board_load_modules(int id)
+{
+ switch (id) {
+ case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
+ case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
+ case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
+ case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+ request_module("smsdvb");
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_load_modules);
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h
index 8e0fe9fd2610..64d74c59c33f 100644
--- a/drivers/media/dvb/siano/sms-cards.h
+++ b/drivers/media/dvb/siano/sms-cards.h
@@ -40,7 +40,7 @@ struct sms_board {
char *name, *fw[DEVICE_MODE_MAX];
/* gpios */
- int led_power, led_hi, led_lo, lna_ctrl;
+ int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
};
struct sms_board *sms_get_board(int id);
@@ -52,7 +52,8 @@ int sms_board_setup(struct smscore_device_t *coredev);
#define SMS_LED_HI 2
int sms_board_led_feedback(struct smscore_device_t *coredev, int led);
int sms_board_power(struct smscore_device_t *coredev, int onoff);
+int sms_board_lna_control(struct smscore_device_t *coredev, int onoff);
-extern struct usb_device_id smsusb_id_table[];
+extern int sms_board_load_modules(int id);
#endif /* __SMS_CARDS_H__ */
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index cf613f22fb8d..7bd4d1dee2b3 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -3,7 +3,7 @@
*
* This file contains implementation for the interface to sms core component
*
- * author: Anatoly Greenblat
+ * author: Uri Shkolnik
*
* Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
*
@@ -34,8 +34,8 @@
#include "smscoreapi.h"
#include "sms-cards.h"
-int sms_debug;
-module_param_named(debug, sms_debug, int, 0644);
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
struct smscore_device_notifyee_t {
@@ -105,11 +105,13 @@ int smscore_led_state(struct smscore_device_t *core, int led)
core->led_state = led;
return core->led_state;
}
+EXPORT_SYMBOL_GPL(smscore_set_board_id);
int smscore_get_board_id(struct smscore_device_t *core)
{
return core->board_id;
}
+EXPORT_SYMBOL_GPL(smscore_get_board_id);
struct smscore_registry_entry_t {
struct list_head entry;
@@ -170,6 +172,7 @@ int smscore_registry_getmode(char *devpath)
return default_mode;
}
+EXPORT_SYMBOL_GPL(smscore_registry_getmode);
static enum sms_device_type_st smscore_registry_gettype(char *devpath)
{
@@ -261,6 +264,7 @@ int smscore_register_hotplug(hotplug_t hotplug)
return rc;
}
+EXPORT_SYMBOL_GPL(smscore_register_hotplug);
/**
* unregister a client callback that called when device plugged in/unplugged
@@ -289,6 +293,7 @@ void smscore_unregister_hotplug(hotplug_t hotplug)
kmutex_unlock(&g_smscore_deviceslock);
}
+EXPORT_SYMBOL_GPL(smscore_unregister_hotplug);
static void smscore_notify_clients(struct smscore_device_t *coredev)
{
@@ -432,6 +437,7 @@ int smscore_register_device(struct smsdevice_params_t *params,
return 0;
}
+EXPORT_SYMBOL_GPL(smscore_register_device);
/**
* sets initial device mode and notifies client hotplugs that device is ready
@@ -460,6 +466,7 @@ int smscore_start_device(struct smscore_device_t *coredev)
return rc;
}
+EXPORT_SYMBOL_GPL(smscore_start_device);
static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
void *buffer, size_t size,
@@ -688,6 +695,7 @@ void smscore_unregister_device(struct smscore_device_t *coredev)
sms_info("device %p destroyed", coredev);
}
+EXPORT_SYMBOL_GPL(smscore_unregister_device);
static int smscore_detect_mode(struct smscore_device_t *coredev)
{
@@ -732,7 +740,7 @@ static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
/*DVBH*/
{"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
/*TDMB*/
- {"none", "tdmb_nova_12mhz.inp", "none", "none"},
+ {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"},
/*DABIP*/
{"none", "none", "none", "none"},
/*BDA*/
@@ -879,6 +887,7 @@ int smscore_get_device_mode(struct smscore_device_t *coredev)
{
return coredev->mode;
}
+EXPORT_SYMBOL_GPL(smscore_get_device_mode);
/**
* find client by response id & type within the clients list.
@@ -1006,6 +1015,7 @@ void smscore_onresponse(struct smscore_device_t *coredev,
smscore_putbuffer(coredev, cb);
}
}
+EXPORT_SYMBOL_GPL(smscore_onresponse);
/**
* return pointer to next free buffer descriptor from core pool
@@ -1031,6 +1041,7 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
return cb;
}
+EXPORT_SYMBOL_GPL(smscore_getbuffer);
/**
* return buffer descriptor to a pool
@@ -1045,6 +1056,7 @@ void smscore_putbuffer(struct smscore_device_t *coredev,
{
list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
}
+EXPORT_SYMBOL_GPL(smscore_putbuffer);
static int smscore_validate_client(struct smscore_device_t *coredev,
struct smscore_client_t *client,
@@ -1124,6 +1136,7 @@ int smscore_register_client(struct smscore_device_t *coredev,
return 0;
}
+EXPORT_SYMBOL_GPL(smscore_register_client);
/**
* frees smsclient object and all subclients associated with it
@@ -1154,6 +1167,7 @@ void smscore_unregister_client(struct smscore_client_t *client)
spin_unlock_irqrestore(&coredev->clientslock, flags);
}
+EXPORT_SYMBOL_GPL(smscore_unregister_client);
/**
* verifies that source id is not taken by another client,
@@ -1193,6 +1207,7 @@ int smsclient_sendrequest(struct smscore_client_t *client,
return coredev->sendrequest_handler(coredev->context, buffer, size);
}
+EXPORT_SYMBOL_GPL(smsclient_sendrequest);
int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
@@ -1276,12 +1291,12 @@ static int __init smscore_module_init(void)
INIT_LIST_HEAD(&g_smscore_registry);
kmutex_init(&g_smscore_registrylock);
- /* USB Register */
- rc = smsusb_register();
- /* DVB Register */
- rc = smsdvb_register();
+
+
+
+ return rc;
sms_debug("rc %d", rc);
return rc;
@@ -1290,6 +1305,10 @@ static int __init smscore_module_init(void)
static void __exit smscore_module_exit(void)
{
+
+
+
+
kmutex_lock(&g_smscore_deviceslock);
while (!list_empty(&g_smscore_notifyees)) {
struct smscore_device_notifyee_t *notifyee =
@@ -1312,18 +1331,12 @@ static void __exit smscore_module_exit(void)
}
kmutex_unlock(&g_smscore_registrylock);
- /* DVB UnRegister */
- smsdvb_unregister();
-
- /* Unregister USB */
- smsusb_unregister();
-
sms_debug("");
}
module_init(smscore_module_init);
module_exit(smscore_module_exit);
-MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle");
-MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)");
+MODULE_DESCRIPTION("Siano MDTV Core module");
+MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h
index 760e233fcbc5..548de9056e8b 100644
--- a/drivers/media/dvb/siano/smscoreapi.h
+++ b/drivers/media/dvb/siano/smscoreapi.h
@@ -29,13 +29,13 @@
#include <linux/scatterlist.h>
#include <linux/types.h>
#include <asm/page.h>
+#include <linux/mutex.h>
#include "dmxdev.h"
#include "dvbdev.h"
#include "dvb_demux.h"
#include "dvb_frontend.h"
-#include <linux/mutex.h>
#define kmutex_init(_p_) mutex_init(_p_)
#define kmutex_lock(_p_) mutex_lock(_p_)
@@ -369,27 +369,6 @@ struct smscore_gpio_config {
u8 outputdriving;
};
-struct smsdvb_client_t {
- struct list_head entry;
-
- struct smscore_device_t *coredev;
- struct smscore_client_t *smsclient;
-
- struct dvb_adapter adapter;
- struct dvb_demux demux;
- struct dmxdev dmxdev;
- struct dvb_frontend frontend;
-
- fe_status_t fe_status;
- int fe_ber, fe_snr, fe_unc, fe_signal_strength;
-
- struct completion tune_done, stat_done;
-
- /* todo: save freq/band instead whole struct */
- struct dvb_frontend_parameters fe_params;
-
-};
-
extern void smscore_registry_setmode(char *devpath, int mode);
extern int smscore_registry_getmode(char *devpath);
@@ -418,6 +397,13 @@ extern int smsclient_sendrequest(struct smscore_client_t *client,
extern void smscore_onresponse(struct smscore_device_t *coredev,
struct smscore_buffer_t *cb);
+extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
+extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
+ struct vm_area_struct *vma);
+extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
+ int mode, char *filename);
+extern int smscore_send_fw_file(struct smscore_device_t *coredev,
+ u8 *ufwbuf, int size);
extern
struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
@@ -433,18 +419,9 @@ int smscore_get_board_id(struct smscore_device_t *core);
int smscore_led_state(struct smscore_device_t *core, int led);
-/* smsdvb.c */
-int smsdvb_register(void);
-void smsdvb_unregister(void);
-
-/* smsusb.c */
-int smsusb_register(void);
-void smsusb_unregister(void);
/* ------------------------------------------------------------------------ */
-extern int sms_debug;
-
#define DBG_INFO 1
#define DBG_ADV 2
@@ -452,7 +429,7 @@ extern int sms_debug;
printk(kern "%s: " fmt "\n", __func__, ##arg)
#define dprintk(kern, lvl, fmt, arg...) do {\
- if (sms_debug & lvl) \
+ if (sms_dbg & lvl) \
sms_printk(kern, fmt, ##arg); } while (0)
#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
index 2da953a4f4f5..ba080b95befb 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -1,7 +1,7 @@
/*
* Driver for the Siano SMS1xxx USB dongle
*
- * author: Anatoly Greenblat
+ * Author: Uri Shkolni
*
* Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
*
@@ -27,9 +27,33 @@
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+struct smsdvb_client_t {
+ struct list_head entry;
+
+ struct smscore_device_t *coredev;
+ struct smscore_client_t *smsclient;
+
+ struct dvb_adapter adapter;
+ struct dvb_demux demux;
+ struct dmxdev dmxdev;
+ struct dvb_frontend frontend;
+
+ fe_status_t fe_status;
+ int fe_ber, fe_snr, fe_unc, fe_signal_strength;
+
+ struct completion tune_done, stat_done;
+
+ /* todo: save freq/band instead whole struct */
+ struct dvb_frontend_parameters fe_params;
+};
+
static struct list_head g_smsdvb_clients;
static struct mutex g_smsdvb_clientslock;
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
{
struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
@@ -262,6 +286,7 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
struct SmsMsgHdr_ST Msg;
u32 Data[3];
} Msg;
+ int ret;
Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
Msg.Msg.msgDstId = HIF_TASK;
@@ -282,6 +307,24 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
default: return -EINVAL;
}
+ /* Disable LNA, if any. An error is returned if no LNA is present */
+ ret = sms_board_lna_control(client->coredev, 0);
+ if (ret == 0) {
+ fe_status_t status;
+
+ /* tune with LNA off at first */
+ ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+ &client->tune_done);
+
+ smsdvb_read_status(fe, &status);
+
+ if (status & FE_HAS_LOCK)
+ return ret;
+
+ /* previous tune didnt lock - enable LNA and tune again */
+ sms_board_lna_control(client->coredev, 1);
+ }
+
return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
&client->tune_done);
}
@@ -329,7 +372,7 @@ static void smsdvb_release(struct dvb_frontend *fe)
static struct dvb_frontend_ops smsdvb_fe_ops = {
.info = {
- .name = "Siano Mobile Digital SMS1xxx",
+ .name = "Siano Mobile Digital MDTV Receiver",
.type = FE_OFDM,
.frequency_min = 44250000,
.frequency_max = 867250000,
@@ -371,7 +414,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
if (!arrival)
return 0;
- if (smscore_get_device_mode(coredev) != 4) {
+ if (smscore_get_device_mode(coredev) != DEVICE_MODE_DVBT_BDA) {
sms_err("SMS Device mode is not set for "
"DVB operation.");
return 0;
@@ -473,7 +516,7 @@ adapter_error:
return rc;
}
-int smsdvb_register(void)
+int smsdvb_module_init(void)
{
int rc;
@@ -487,7 +530,7 @@ int smsdvb_register(void)
return rc;
}
-void smsdvb_unregister(void)
+void smsdvb_module_exit(void)
{
smscore_unregister_hotplug(smsdvb_hotplug);
@@ -499,3 +542,10 @@ void smsdvb_unregister(void)
kmutex_unlock(&g_smsdvb_clientslock);
}
+
+module_init(smsdvb_module_init);
+module_exit(smsdvb_module_exit);
+
+MODULE_DESCRIPTION("SMS DVB subsystem adaptation module");
+MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index 5d7ca3417719..71c65f544c07 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -27,6 +27,10 @@
#include "smscoreapi.h"
#include "sms-cards.h"
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
#define USB1_BUFFER_SIZE 0x1000
#define USB2_BUFFER_SIZE 0x4000
@@ -424,6 +428,7 @@ static int smsusb_probe(struct usb_interface *intf,
rc = smsusb_init_device(intf, id->driver_info);
sms_info("rc %d", rc);
+ sms_board_load_modules(id->driver_info);
return rc;
}
@@ -436,7 +441,7 @@ static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg)
{
struct smsusb_device_t *dev =
(struct smsusb_device_t *)usb_get_intfdata(intf);
- printk(KERN_INFO "%s Entering status %d.\n", __func__, msg.event);
+ printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event);
smsusb_stop_streaming(dev);
return 0;
}
@@ -448,7 +453,7 @@ static int smsusb_resume(struct usb_interface *intf)
(struct smsusb_device_t *)usb_get_intfdata(intf);
struct usb_device *udev = interface_to_usbdev(intf);
- printk(KERN_INFO "%s Entering.\n", __func__);
+ printk(KERN_INFO "%s: Entering.\n", __func__);
usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81));
usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02));
@@ -463,9 +468,8 @@ static int smsusb_resume(struct usb_interface *intf)
intf->cur_altsetting->desc.
bInterfaceNumber, 0);
if (rc < 0) {
- printk(KERN_INFO
- "%s usb_set_interface failed, rc %d\n",
- __func__, rc);
+ printk(KERN_INFO "%s usb_set_interface failed, "
+ "rc %d\n", __func__, rc);
return rc;
}
}
@@ -474,8 +478,55 @@ static int smsusb_resume(struct usb_interface *intf)
return 0;
}
+struct usb_device_id smsusb_id_table[] = {
+#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS
+ { USB_DEVICE(0x187f, 0x0010),
+ .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
+ { USB_DEVICE(0x187f, 0x0100),
+ .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
+ { USB_DEVICE(0x187f, 0x0200),
+ .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A },
+ { USB_DEVICE(0x187f, 0x0201),
+ .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
+ { USB_DEVICE(0x187f, 0x0300),
+ .driver_info = SMS1XXX_BOARD_SIANO_VEGA },
+#endif
+ { USB_DEVICE(0x2040, 0x1700),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT },
+ { USB_DEVICE(0x2040, 0x1800),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A },
+ { USB_DEVICE(0x2040, 0x1801),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
+ { USB_DEVICE(0x2040, 0x2000),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+ { USB_DEVICE(0x2040, 0x2009),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 },
+ { USB_DEVICE(0x2040, 0x200a),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+ { USB_DEVICE(0x2040, 0x2010),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+ { USB_DEVICE(0x2040, 0x2011),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+ { USB_DEVICE(0x2040, 0x2019),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+ { USB_DEVICE(0x2040, 0x5500),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5510),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5520),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5530),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5580),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5590),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, smsusb_id_table);
+
static struct usb_driver smsusb_driver = {
- .name = "sms1xxx",
+ .name = "smsusb",
.probe = smsusb_probe,
.disconnect = smsusb_disconnect,
.id_table = smsusb_id_table,
@@ -484,7 +535,7 @@ static struct usb_driver smsusb_driver = {
.resume = smsusb_resume,
};
-int smsusb_register(void)
+int smsusb_module_init(void)
{
int rc = usb_register(&smsusb_driver);
if (rc)
@@ -495,10 +546,16 @@ int smsusb_register(void)
return rc;
}
-void smsusb_unregister(void)
+void smsusb_module_exit(void)
{
sms_debug("");
/* Regular USB Cleanup */
usb_deregister(&smsusb_driver);
}
+module_init(smsusb_module_init);
+module_exit(smsusb_module_exit);
+
+MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle");
+MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index ab0bcd208c78..772990415f99 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -108,7 +108,7 @@ config DVB_BUDGET_CI
select DVB_STB6100 if !DVB_FE_CUSTOMISE
select DVB_LNBP21 if !DVB_FE_CUSTOMISE
select DVB_TDA10023 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
select VIDEO_IR
help
Support for simple SAA7146 based DVB cards
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index aa1ff524256e..4624cee93e74 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -725,7 +725,7 @@ static int dvb_osd_ioctl(struct inode *inode, struct file *file,
}
-static struct file_operations dvb_osd_fops = {
+static const struct file_operations dvb_osd_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_generic_ioctl,
.open = dvb_generic_open,
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index bdc62acf2099..e4d0900d5121 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -1456,7 +1456,7 @@ static int dvb_audio_release(struct inode *inode, struct file *file)
* driver registration
******************************************************************************/
-static struct file_operations dvb_video_fops = {
+static const struct file_operations dvb_video_fops = {
.owner = THIS_MODULE,
.write = dvb_video_write,
.ioctl = dvb_generic_ioctl,
@@ -1474,7 +1474,7 @@ static struct dvb_device dvbdev_video = {
.kernel_ioctl = dvb_video_ioctl,
};
-static struct file_operations dvb_audio_fops = {
+static const struct file_operations dvb_audio_fops = {
.owner = THIS_MODULE,
.write = dvb_audio_write,
.ioctl = dvb_generic_ioctl,
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index 261135ded481..c7a65b1544a3 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -345,7 +345,7 @@ static ssize_t dvb_ca_read(struct file *file, char __user *buf,
return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
}
-static struct file_operations dvb_ca_fops = {
+static const struct file_operations dvb_ca_fops = {
.owner = THIS_MODULE,
.read = dvb_ca_read,
.write = dvb_ca_write,
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index c5b9c70563dc..2210cff738e6 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -316,253 +316,261 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
return 0;
}
-static long av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
{
- struct saa7146_dev *dev = fh->dev;
- struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
- dprintk(4, "saa7146_dev: %p\n", dev);
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+ u16 stereo_det;
+ s8 stereo;
- switch (cmd) {
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *t = arg;
- u16 stereo_det;
- s8 stereo;
+ dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
- dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
+ if (!av7110->analog_tuner_flags || t->index != 0)
+ return -EINVAL;
- if (!av7110->analog_tuner_flags || t->index != 0)
- return -EINVAL;
+ memset(t, 0, sizeof(*t));
+ strcpy((char *)t->name, "Television");
+
+ t->type = V4L2_TUNER_ANALOG_TV;
+ t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+ t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
+ t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
+ /* FIXME: add the real signal strength here */
+ t->signal = 0xffff;
+ t->afc = 0;
+
+ /* FIXME: standard / stereo detection is still broken */
+ msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
+ dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
+ msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
+ dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
+ stereo = (s8)(stereo_det >> 8);
+ if (stereo > 0x10) {
+ /* stereo */
+ t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
+ t->audmode = V4L2_TUNER_MODE_STEREO;
+ } else if (stereo < -0x10) {
+ /* bilingual */
+ t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+ t->audmode = V4L2_TUNER_MODE_LANG1;
+ } else /* mono */
+ t->rxsubchans = V4L2_TUNER_SUB_MONO;
- memset(t, 0, sizeof(*t));
- strcpy((char *)t->name, "Television");
-
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
- t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
- t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
- /* FIXME: add the real signal strength here */
- t->signal = 0xffff;
- t->afc = 0;
-
- // FIXME: standard / stereo detection is still broken
- msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
- dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
- msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
- dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
- stereo = (s8)(stereo_det >> 8);
- if (stereo > 0x10) {
- /* stereo */
- t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
- t->audmode = V4L2_TUNER_MODE_STEREO;
- }
- else if (stereo < -0x10) {
- /* bilingual */
- t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- t->audmode = V4L2_TUNER_MODE_LANG1;
- }
- else /* mono */
- t->rxsubchans = V4L2_TUNER_SUB_MONO;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *t = arg;
- u16 fm_matrix, src;
- dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
+static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+ u16 fm_matrix, src;
+ dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
- if (!av7110->analog_tuner_flags || av7110->current_input != 1)
- return -EINVAL;
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+ return -EINVAL;
- switch (t->audmode) {
- case V4L2_TUNER_MODE_STEREO:
- dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
- fm_matrix = 0x3001; // stereo
- src = 0x0020;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n");
- fm_matrix = 0x3000; // bilingual
- src = 0x0020;
- break;
- case V4L2_TUNER_MODE_LANG1:
- dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
- fm_matrix = 0x3000; // mono
- src = 0x0000;
- break;
- case V4L2_TUNER_MODE_LANG2:
- dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
- fm_matrix = 0x3000; // mono
- src = 0x0010;
- break;
- default: /* case V4L2_TUNER_MODE_MONO: */
- dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
- fm_matrix = 0x3000; // mono
- src = 0x0030;
- break;
- }
- msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
- msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
- msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
- msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
- return 0;
+ switch (t->audmode) {
+ case V4L2_TUNER_MODE_STEREO:
+ dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
+ fm_matrix = 0x3001; /* stereo */
+ src = 0x0020;
+ break;
+ case V4L2_TUNER_MODE_LANG1_LANG2:
+ dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n");
+ fm_matrix = 0x3000; /* bilingual */
+ src = 0x0020;
+ break;
+ case V4L2_TUNER_MODE_LANG1:
+ dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n");
+ fm_matrix = 0x3000; /* mono */
+ src = 0x0000;
+ break;
+ case V4L2_TUNER_MODE_LANG2:
+ dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
+ fm_matrix = 0x3000; /* mono */
+ src = 0x0010;
+ break;
+ default: /* case V4L2_TUNER_MODE_MONO: */
+ dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
+ fm_matrix = 0x3000; /* mono */
+ src = 0x0030;
+ break;
}
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
+ msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
+ msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
+ msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
+ return 0;
+}
- dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
+static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
- if (!av7110->analog_tuner_flags || av7110->current_input != 1)
- return -EINVAL;
+ dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
- memset(f, 0, sizeof(*f));
- f->type = V4L2_TUNER_ANALOG_TV;
- f->frequency = av7110->current_freq;
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+ return -EINVAL;
- dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
+ memset(f, 0, sizeof(*f));
+ f->type = V4L2_TUNER_ANALOG_TV;
+ f->frequency = av7110->current_freq;
+ return 0;
+}
- if (!av7110->analog_tuner_flags || av7110->current_input != 1)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
- if (V4L2_TUNER_ANALOG_TV != f->type)
- return -EINVAL;
+ dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
- msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute
- msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+ return -EINVAL;
- /* tune in desired frequency */
- if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
- ves1820_set_tv_freq(dev, f->frequency);
- } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
- stv0297_set_tv_freq(dev, f->frequency);
- }
- av7110->current_freq = f->frequency;
+ if (V4L2_TUNER_ANALOG_TV != f->type)
+ return -EINVAL;
- msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection
- msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
- msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
- msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
- return 0;
- }
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
+ msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); /* fast mute */
+ msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
- dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
+ /* tune in desired frequency */
+ if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820)
+ ves1820_set_tv_freq(dev, f->frequency);
+ else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297)
+ stv0297_set_tv_freq(dev, f->frequency);
+ av7110->current_freq = f->frequency;
- if (av7110->analog_tuner_flags) {
- if (i->index < 0 || i->index >= 4)
- return -EINVAL;
- } else {
- if (i->index != 0)
- return -EINVAL;
- }
+ msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); /* start stereo detection */
+ msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
+ msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); /* loudspeaker + headphone */
+ msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); /* SCART 1 volume */
+ return 0;
+}
- memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
- return 0;
+ dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
+
+ if (av7110->analog_tuner_flags) {
+ if (i->index < 0 || i->index >= 4)
+ return -EINVAL;
+ } else {
+ if (i->index != 0)
+ return -EINVAL;
}
- case VIDIOC_G_INPUT:
- {
- int *input = (int *)arg;
- *input = av7110->current_input;
- dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
+
+ memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
+
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ *input = av7110->current_input;
+ dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
+
+ if (!av7110->analog_tuner_flags)
return 0;
- }
- case VIDIOC_S_INPUT:
- {
- int input = *(int *)arg;
- dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
+ if (input < 0 || input >= 4)
+ return -EINVAL;
- if (!av7110->analog_tuner_flags)
- return 0;
+ av7110->current_input = input;
+ return av7110_dvb_c_switch(fh);
+}
- if (input < 0 || input >= 4)
- return -EINVAL;
+static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
+ if (a->index != 0)
+ return -EINVAL;
+ memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
+ return 0;
+}
- av7110->current_input = input;
- return av7110_dvb_c_switch(fh);
- }
- case VIDIOC_G_AUDIO:
- {
- struct v4l2_audio *a = arg;
+static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
+ return 0;
+}
- dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
- if (a->index != 0)
- return -EINVAL;
- memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
- break;
- }
- case VIDIOC_S_AUDIO:
- {
- struct v4l2_audio *a = arg;
- dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
- break;
- }
- case VIDIOC_G_SLICED_VBI_CAP:
- {
- struct v4l2_sliced_vbi_cap *cap = arg;
- dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
- memset(cap, 0, sizeof *cap);
- if (FW_VERSION(av7110->arm_app) >= 0x2623) {
- cap->service_set = V4L2_SLICED_WSS_625;
- cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
- }
- break;
- }
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *f = arg;
- dprintk(2, "VIDIOC_G_FMT:\n");
- if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
- FW_VERSION(av7110->arm_app) < 0x2623)
- return -EAGAIN; /* handled by core driver */
- memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
- if (av7110->wssMode) {
- f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
- f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
- f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
- }
- break;
+static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
+ struct v4l2_sliced_vbi_cap *cap)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
+ if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
+ return -EINVAL;
+ if (FW_VERSION(av7110->arm_app) >= 0x2623) {
+ cap->service_set = V4L2_SLICED_WSS_625;
+ cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
}
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *f = arg;
- dprintk(2, "VIDIOC_S_FMT\n");
- if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
- FW_VERSION(av7110->arm_app) < 0x2623)
- return -EAGAIN; /* handled by core driver */
- if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
- f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
- memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
- /* WSS controlled by firmware */
- av7110->wssMode = 0;
- av7110->wssData = 0;
- return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
- SetWSSConfig, 1, 0);
- } else {
- memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
- f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
- f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
- f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
- /* WSS controlled by userspace */
- av7110->wssMode = 1;
- av7110->wssData = 0;
- }
- break;
+ return 0;
+}
+
+static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_G_FMT:\n");
+ if (FW_VERSION(av7110->arm_app) < 0x2623)
+ return -EINVAL;
+ memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
+ if (av7110->wssMode) {
+ f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
+ f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+ f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
}
- default:
- printk("no such ioctl\n");
- return -ENOIOCTLCMD;
+ return 0;
+}
+
+static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_S_FMT\n");
+ if (FW_VERSION(av7110->arm_app) < 0x2623)
+ return -EINVAL;
+ if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
+ f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
+ memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
+ /* WSS controlled by firmware */
+ av7110->wssMode = 0;
+ av7110->wssData = 0;
+ return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
+ SetWSSConfig, 1, 0);
+ } else {
+ memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
+ f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
+ f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+ f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
+ /* WSS controlled by userspace */
+ av7110->wssMode = 1;
+ av7110->wssData = 0;
}
return 0;
}
@@ -609,22 +617,6 @@ static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size
* INITIALIZATION
****************************************************************************/
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE },
- { VIDIOC_G_FMT, SAA7146_BEFORE },
- { VIDIOC_S_FMT, SAA7146_BEFORE },
- { 0, 0 }
-};
-
static u8 saa7113_init_regs[] = {
0x02, 0xd0,
0x03, 0x23,
@@ -788,20 +780,34 @@ int av7110_init_analog_module(struct av7110 *av7110)
int av7110_init_v4l(struct av7110 *av7110)
{
struct saa7146_dev* dev = av7110->dev;
+ struct saa7146_ext_vv *vv_data;
int ret;
/* special case DVB-C: these cards have an analog tuner
plus need some special handling, so we have separate
saa7146_ext_vv data for these... */
if (av7110->analog_tuner_flags)
- ret = saa7146_vv_init(dev, &av7110_vv_data_c);
+ vv_data = &av7110_vv_data_c;
else
- ret = saa7146_vv_init(dev, &av7110_vv_data_st);
+ vv_data = &av7110_vv_data_st;
+ ret = saa7146_vv_init(dev, vv_data);
if (ret) {
ERR(("cannot init capture device. skipping.\n"));
return -ENODEV;
}
+ vv_data->ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data->ops.vidioc_g_input = vidioc_g_input;
+ vv_data->ops.vidioc_s_input = vidioc_s_input;
+ vv_data->ops.vidioc_g_tuner = vidioc_g_tuner;
+ vv_data->ops.vidioc_s_tuner = vidioc_s_tuner;
+ vv_data->ops.vidioc_g_frequency = vidioc_g_frequency;
+ vv_data->ops.vidioc_s_frequency = vidioc_s_frequency;
+ vv_data->ops.vidioc_g_audio = vidioc_g_audio;
+ vv_data->ops.vidioc_s_audio = vidioc_s_audio;
+ vv_data->ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap;
+ vv_data->ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out;
+ vv_data->ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out;
if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
ERR(("cannot register capture device. skipping.\n"));
@@ -900,9 +906,6 @@ static struct saa7146_ext_vv av7110_vv_data_st = {
.num_stds = ARRAY_SIZE(standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = av7110_ioctl,
-
.vbi_fops.open = av7110_vbi_reset,
.vbi_fops.release = av7110_vbi_reset,
.vbi_fops.write = av7110_vbi_write,
@@ -918,9 +921,6 @@ static struct saa7146_ext_vv av7110_vv_data_c = {
.num_stds = ARRAY_SIZE(standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = av7110_ioctl,
-
.vbi_fops.open = av7110_vbi_reset,
.vbi_fops.release = av7110_vbi_reset,
.vbi_fops.write = av7110_vbi_write,
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 4182121d7e5d..855fe74b640b 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -1404,6 +1404,41 @@ static int budget_av_detach(struct saa7146_dev *dev)
return err;
}
+#define KNC1_INPUTS 2
+static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
+ {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
+ {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
+};
+
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
+ if (i->index < 0 || i->index >= KNC1_INPUTS)
+ return -EINVAL;
+ memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
+
+ *i = budget_av->cur_input;
+
+ dprintk(1, "VIDIOC_G_INPUT %d.\n", *i);
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
+
+ dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
+ return saa7113_setinput(budget_av, input);
+}
+
static struct saa7146_ext_vv vv_data;
static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
@@ -1442,6 +1477,9 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
ERR(("cannot init vv subsystem.\n"));
return err;
}
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
/* fixme: proper cleanup here */
@@ -1480,54 +1518,6 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
return 0;
}
-#define KNC1_INPUTS 2
-static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
- {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
- {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
-};
-
-static struct saa7146_extension_ioctls ioctls[] = {
- {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
- {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
- {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
- {0, 0}
-};
-
-static long av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-{
- struct saa7146_dev *dev = fh->dev;
- struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
-
- switch (cmd) {
- case VIDIOC_ENUMINPUT:{
- struct v4l2_input *i = arg;
-
- dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
- if (i->index < 0 || i->index >= KNC1_INPUTS) {
- return -EINVAL;
- }
- memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
- return 0;
- }
- case VIDIOC_G_INPUT:{
- int *input = (int *) arg;
-
- *input = budget_av->cur_input;
-
- dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
- return 0;
- }
- case VIDIOC_S_INPUT:{
- int input = *(int *) arg;
- dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
- return saa7113_setinput(budget_av, input);
- }
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
static struct saa7146_standard standard[] = {
{.name = "PAL",.id = V4L2_STD_PAL,
.v_offset = 0x17,.v_field = 288,
@@ -1546,8 +1536,6 @@ static struct saa7146_ext_vv vv_data = {
.flags = 0,
.stds = &standard[0],
.num_stds = ARRAY_SIZE(standard),
- .ioctls = &ioctls[0],
- .ioctl = av_ioctl,
};
static struct saa7146_extension budget_extension;
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index bcbc5d41a0fe..371a71616810 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -1076,6 +1076,10 @@ static struct tda10023_config tda10023_config = {
.deltaf = 0xa511,
};
+static struct tda827x_config tda827x_config = {
+ .config = 0,
+};
+
/* TT S2-3200 DVB-S (STB0899) Inittab */
static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
@@ -1414,7 +1418,7 @@ static void frontend_init(struct budget_ci *budget_ci)
case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
if (budget_ci->budget.dvb_frontend) {
- if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, NULL) == NULL) {
+ if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) {
printk(KERN_ERR "%s: No tda827x found!\n", __func__);
dvb_frontend_detach(budget_ci->budget.dvb_frontend);
budget_ci->budget.dvb_frontend = NULL;
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 2014ebc4e984..cc54ed4efc48 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -390,9 +390,11 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
+ struct dsbr100_device *radio = video_drvdata(file);
+
strlcpy(v->driver, "dsbr100", sizeof(v->driver));
strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card));
- sprintf(v->bus_info, "USB");
+ usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
v->version = RADIO_VERSION;
v->capabilities = V4L2_CAP_TUNER;
return 0;
@@ -450,7 +452,10 @@ static int vidioc_s_frequency(struct file *file, void *priv,
if (radio->removed)
return -EIO;
+ mutex_lock(&radio->lock);
radio->curfreq = f->frequency;
+ mutex_unlock(&radio->lock);
+
retval = dsbr100_setfreq(radio, radio->curfreq);
if (retval < 0)
dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
@@ -601,7 +606,10 @@ static int usb_dsbr100_close(struct file *file)
if (!radio)
return -ENODEV;
+ mutex_lock(&radio->lock);
radio->users = 0;
+ mutex_unlock(&radio->lock);
+
if (!radio->removed) {
retval = dsbr100_stop(radio);
if (retval < 0) {
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index bfa13b8b3043..ac82e33cb6fc 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -32,14 +32,15 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+MODULE_AUTHOR("M.Kirkwood");
+MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
+MODULE_LICENSE("GPL");
#ifndef CONFIG_RADIO_RTRACK_PORT
#define CONFIG_RADIO_RTRACK_PORT -1
@@ -47,86 +48,95 @@
static int io = CONFIG_RADIO_RTRACK_PORT;
static int radio_nr = -1;
-static struct mutex lock;
-struct rt_device
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct rtrack
{
- unsigned long in_use;
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
int port;
int curvol;
unsigned long curfreq;
int muted;
+ int io;
+ struct mutex lock;
};
+static struct rtrack rtrack_card;
/* local things */
static void sleep_delay(long n)
{
/* Sleep nicely for 'n' uS */
- int d=n/msecs_to_jiffies(1000);
- if(!d)
+ int d = n / msecs_to_jiffies(1000);
+ if (!d)
udelay(n);
else
msleep(jiffies_to_msecs(d));
}
-static void rt_decvol(void)
+static void rt_decvol(struct rtrack *rt)
{
- outb(0x58, io); /* volume down + sigstr + on */
+ outb(0x58, rt->io); /* volume down + sigstr + on */
sleep_delay(100000);
- outb(0xd8, io); /* volume steady + sigstr + on */
+ outb(0xd8, rt->io); /* volume steady + sigstr + on */
}
-static void rt_incvol(void)
+static void rt_incvol(struct rtrack *rt)
{
- outb(0x98, io); /* volume up + sigstr + on */
+ outb(0x98, rt->io); /* volume up + sigstr + on */
sleep_delay(100000);
- outb(0xd8, io); /* volume steady + sigstr + on */
+ outb(0xd8, rt->io); /* volume steady + sigstr + on */
}
-static void rt_mute(struct rt_device *dev)
+static void rt_mute(struct rtrack *rt)
{
- dev->muted = 1;
- mutex_lock(&lock);
- outb(0xd0, io); /* volume steady, off */
- mutex_unlock(&lock);
+ rt->muted = 1;
+ mutex_lock(&rt->lock);
+ outb(0xd0, rt->io); /* volume steady, off */
+ mutex_unlock(&rt->lock);
}
-static int rt_setvol(struct rt_device *dev, int vol)
+static int rt_setvol(struct rtrack *rt, int vol)
{
int i;
- mutex_lock(&lock);
+ mutex_lock(&rt->lock);
- if(vol == dev->curvol) { /* requested volume = current */
- if (dev->muted) { /* user is unmuting the card */
- dev->muted = 0;
- outb (0xd8, io); /* enable card */
+ if (vol == rt->curvol) { /* requested volume = current */
+ if (rt->muted) { /* user is unmuting the card */
+ rt->muted = 0;
+ outb(0xd8, rt->io); /* enable card */
}
- mutex_unlock(&lock);
+ mutex_unlock(&rt->lock);
return 0;
}
- if(vol == 0) { /* volume = 0 means mute the card */
- outb(0x48, io); /* volume down but still "on" */
+ if (vol == 0) { /* volume = 0 means mute the card */
+ outb(0x48, rt->io); /* volume down but still "on" */
sleep_delay(2000000); /* make sure it's totally down */
- outb(0xd0, io); /* volume steady, off */
- dev->curvol = 0; /* track the volume state! */
- mutex_unlock(&lock);
+ outb(0xd0, rt->io); /* volume steady, off */
+ rt->curvol = 0; /* track the volume state! */
+ mutex_unlock(&rt->lock);
return 0;
}
- dev->muted = 0;
- if(vol > dev->curvol)
- for(i = dev->curvol; i < vol; i++)
- rt_incvol();
+ rt->muted = 0;
+ if (vol > rt->curvol)
+ for (i = rt->curvol; i < vol; i++)
+ rt_incvol(rt);
else
- for(i = dev->curvol; i > vol; i--)
- rt_decvol();
+ for (i = rt->curvol; i > vol; i--)
+ rt_decvol(rt);
- dev->curvol = vol;
- mutex_unlock(&lock);
+ rt->curvol = vol;
+ mutex_unlock(&rt->lock);
return 0;
}
@@ -135,155 +145,137 @@ static int rt_setvol(struct rt_device *dev, int vol)
* and bit 4 (+16) is to keep the signal strength meter enabled
*/
-static void send_0_byte(int port, struct rt_device *dev)
+static void send_0_byte(struct rtrack *rt)
{
- if ((dev->curvol == 0) || (dev->muted)) {
- outb_p(128+64+16+ 1, port); /* wr-enable + data low */
- outb_p(128+64+16+2+1, port); /* clock */
+ if (rt->curvol == 0 || rt->muted) {
+ outb_p(128+64+16+ 1, rt->io); /* wr-enable + data low */
+ outb_p(128+64+16+2+1, rt->io); /* clock */
}
else {
- outb_p(128+64+16+8+ 1, port); /* on + wr-enable + data low */
- outb_p(128+64+16+8+2+1, port); /* clock */
+ outb_p(128+64+16+8+ 1, rt->io); /* on + wr-enable + data low */
+ outb_p(128+64+16+8+2+1, rt->io); /* clock */
}
sleep_delay(1000);
}
-static void send_1_byte(int port, struct rt_device *dev)
+static void send_1_byte(struct rtrack *rt)
{
- if ((dev->curvol == 0) || (dev->muted)) {
- outb_p(128+64+16+4 +1, port); /* wr-enable+data high */
- outb_p(128+64+16+4+2+1, port); /* clock */
+ if (rt->curvol == 0 || rt->muted) {
+ outb_p(128+64+16+4 +1, rt->io); /* wr-enable+data high */
+ outb_p(128+64+16+4+2+1, rt->io); /* clock */
}
else {
- outb_p(128+64+16+8+4 +1, port); /* on+wr-enable+data high */
- outb_p(128+64+16+8+4+2+1, port); /* clock */
+ outb_p(128+64+16+8+4 +1, rt->io); /* on+wr-enable+data high */
+ outb_p(128+64+16+8+4+2+1, rt->io); /* clock */
}
sleep_delay(1000);
}
-static int rt_setfreq(struct rt_device *dev, unsigned long freq)
+static int rt_setfreq(struct rtrack *rt, unsigned long freq)
{
int i;
- /* adapted from radio-aztech.c */
+ mutex_lock(&rt->lock); /* Stop other ops interfering */
+
+ rt->curfreq = freq;
/* now uses VIDEO_TUNER_LOW for fine tuning */
freq += 171200; /* Add 10.7 MHz IF */
freq /= 800; /* Convert to 50 kHz units */
- mutex_lock(&lock); /* Stop other ops interfering */
-
- send_0_byte (io, dev); /* 0: LSB of frequency */
+ send_0_byte(rt); /* 0: LSB of frequency */
for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
if (freq & (1 << i))
- send_1_byte (io, dev);
+ send_1_byte(rt);
else
- send_0_byte (io, dev);
+ send_0_byte(rt);
- send_0_byte (io, dev); /* 14: test bit - always 0 */
- send_0_byte (io, dev); /* 15: test bit - always 0 */
+ send_0_byte(rt); /* 14: test bit - always 0 */
+ send_0_byte(rt); /* 15: test bit - always 0 */
- send_0_byte (io, dev); /* 16: band data 0 - always 0 */
- send_0_byte (io, dev); /* 17: band data 1 - always 0 */
- send_0_byte (io, dev); /* 18: band data 2 - always 0 */
- send_0_byte (io, dev); /* 19: time base - always 0 */
+ send_0_byte(rt); /* 16: band data 0 - always 0 */
+ send_0_byte(rt); /* 17: band data 1 - always 0 */
+ send_0_byte(rt); /* 18: band data 2 - always 0 */
+ send_0_byte(rt); /* 19: time base - always 0 */
- send_0_byte (io, dev); /* 20: spacing (0 = 25 kHz) */
- send_1_byte (io, dev); /* 21: spacing (1 = 25 kHz) */
- send_0_byte (io, dev); /* 22: spacing (0 = 25 kHz) */
- send_1_byte (io, dev); /* 23: AM/FM (FM = 1, always) */
+ send_0_byte(rt); /* 20: spacing (0 = 25 kHz) */
+ send_1_byte(rt); /* 21: spacing (1 = 25 kHz) */
+ send_0_byte(rt); /* 22: spacing (0 = 25 kHz) */
+ send_1_byte(rt); /* 23: AM/FM (FM = 1, always) */
- if ((dev->curvol == 0) || (dev->muted))
- outb (0xd0, io); /* volume steady + sigstr */
+ if (rt->curvol == 0 || rt->muted)
+ outb(0xd0, rt->io); /* volume steady + sigstr */
else
- outb (0xd8, io); /* volume steady + sigstr + on */
+ outb(0xd8, rt->io); /* volume steady + sigstr + on */
- mutex_unlock(&lock);
+ mutex_unlock(&rt->lock);
return 0;
}
-static int rt_getsigstr(struct rt_device *dev)
+static int rt_getsigstr(struct rtrack *rt)
{
- if (inb(io) & 2) /* bit set = no signal present */
- return 0;
- return 1; /* signal present */
-}
+ int sig = 1;
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
+ mutex_lock(&rt->lock);
+ if (inb(rt->io) & 2) /* bit set = no signal present */
+ sig = 0;
+ mutex_unlock(&rt->lock);
+ return sig;
+}
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
strlcpy(v->driver, "radio-aimslab", sizeof(v->driver));
strlcpy(v->card, "RadioTrack", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack *rt = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow = (87*16000);
- v->rangehigh = (108*16000);
+ v->rangelow = 87 * 16000;
+ v->rangehigh = 108 * 16000;
v->rxsubchans = V4L2_TUNER_SUB_MONO;
v->capability = V4L2_TUNER_CAP_LOW;
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = 0xffff*rt_getsigstr(rt);
+ v->signal = 0xffff * rt_getsigstr(rt);
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack *rt = video_drvdata(file);
- rt->curfreq = f->frequency;
- rt_setfreq(rt, rt->curfreq);
+ rt_setfreq(rt, f->frequency);
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack *rt = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = rt->curfreq;
@@ -293,14 +285,11 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff);
}
return -EINVAL;
}
@@ -308,14 +297,14 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack *rt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
ctrl->value = rt->muted;
return 0;
case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = rt->curvol * 6554;
+ ctrl->value = rt->curvol;
return 0;
}
return -EINVAL;
@@ -324,33 +313,22 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack *rt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value)
rt_mute(rt);
else
- rt_setvol(rt,rt->curvol);
+ rt_setvol(rt, rt->curvol);
return 0;
case V4L2_CID_AUDIO_VOLUME:
- rt_setvol(rt,ctrl->value);
+ rt_setvol(rt, ctrl->value);
return 0;
}
return -EINVAL;
}
-static int vidioc_g_audio (struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -359,36 +337,38 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static struct rt_device rtrack_unit;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
-static int rtrack_exclusive_open(struct file *file)
+static int rtrack_open(struct file *file)
{
- return test_and_set_bit(0, &rtrack_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int rtrack_exclusive_release(struct file *file)
+static int rtrack_release(struct file *file)
{
- clear_bit(0, &rtrack_unit.in_use);
return 0;
}
static const struct v4l2_file_operations rtrack_fops = {
.owner = THIS_MODULE,
- .open = rtrack_exclusive_open,
- .release = rtrack_exclusive_release,
+ .open = rtrack_open,
+ .release = rtrack_release,
.ioctl = video_ioctl2,
};
@@ -407,64 +387,69 @@ static const struct v4l2_ioctl_ops rtrack_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device rtrack_radio = {
- .name = "RadioTrack radio",
- .fops = &rtrack_fops,
- .ioctl_ops = &rtrack_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __init rtrack_init(void)
{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+ struct rtrack *rt = &rtrack_card;
+ struct v4l2_device *v4l2_dev = &rt->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "rtrack", sizeof(v4l2_dev->name));
+ rt->io = io;
+
+ if (rt->io == -1) {
+ v4l2_err(v4l2_dev, "you must set an I/O address with io=0x20f or 0x30f\n");
return -EINVAL;
}
- if (!request_region(io, 2, "rtrack"))
- {
- printk(KERN_ERR "rtrack: port 0x%x already in use\n", io);
+ if (!request_region(rt->io, 2, "rtrack")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", rt->io);
return -EBUSY;
}
- video_set_drvdata(&rtrack_radio, &rtrack_unit);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(rt->io, 2);
+ v4l2_err(v4l2_dev, "could not register v4l2_device\n");
+ return res;
+ }
- if (video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 2);
+ strlcpy(rt->vdev.name, v4l2_dev->name, sizeof(rt->vdev.name));
+ rt->vdev.v4l2_dev = v4l2_dev;
+ rt->vdev.fops = &rtrack_fops;
+ rt->vdev.ioctl_ops = &rtrack_ioctl_ops;
+ rt->vdev.release = video_device_release_empty;
+ video_set_drvdata(&rt->vdev, rt);
+
+ if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(&rt->v4l2_dev);
+ release_region(rt->io, 2);
return -EINVAL;
}
- printk(KERN_INFO "AIMSlab RadioTrack/RadioReveal card driver.\n");
+ v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
/* Set up the I/O locking */
- mutex_init(&lock);
+ mutex_init(&rt->lock);
/* mute card - prevents noisy bootups */
/* this ensures that the volume is all the way down */
- outb(0x48, io); /* volume down but still "on" */
+ outb(0x48, rt->io); /* volume down but still "on" */
sleep_delay(2000000); /* make sure it's totally down */
- outb(0xc0, io); /* steady volume, mute card */
- rtrack_unit.curvol = 0;
+ outb(0xc0, rt->io); /* steady volume, mute card */
return 0;
}
-MODULE_AUTHOR("M.Kirkwood");
-MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)");
-module_param(radio_nr, int, 0);
-
-static void __exit cleanup_rtrack_module(void)
+static void __exit rtrack_exit(void)
{
- video_unregister_device(&rtrack_radio);
- release_region(io,2);
+ struct rtrack *rt = &rtrack_card;
+
+ video_unregister_device(&rt->vdev);
+ v4l2_device_unregister(&rt->v4l2_dev);
+ release_region(rt->io, 2);
}
module_init(rtrack_init);
-module_exit(cleanup_rtrack_module);
+module_exit(rtrack_exit);
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 5604e881e96c..49299f7fd834 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -29,33 +29,15 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
+MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
+MODULE_DESCRIPTION("A driver for the Aztech radio card.");
+MODULE_LICENSE("GPL");
/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
@@ -66,55 +48,64 @@ static struct v4l2_queryctrl radio_qctrl[] = {
static int io = CONFIG_RADIO_AZTECH_PORT;
static int radio_nr = -1;
static int radio_wait_time = 1000;
-static struct mutex lock;
-struct az_device
+module_param(io, int, 0);
+module_param(radio_nr, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct aztech
{
- unsigned long in_use;
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
int curvol;
unsigned long curfreq;
int stereo;
+ struct mutex lock;
};
+static struct aztech aztech_card;
+
static int volconvert(int level)
{
- level>>=14; /* Map 16bits down to 2 bit */
- level&=3;
+ level >>= 14; /* Map 16bits down to 2 bit */
+ level &= 3;
/* convert to card-friendly values */
- switch (level)
- {
- case 0:
- return 0;
- case 1:
- return 1;
- case 2:
- return 4;
- case 3:
- return 5;
+ switch (level) {
+ case 0:
+ return 0;
+ case 1:
+ return 1;
+ case 2:
+ return 4;
+ case 3:
+ return 5;
}
return 0; /* Quieten gcc */
}
-static void send_0_byte (struct az_device *dev)
+static void send_0_byte(struct aztech *az)
{
udelay(radio_wait_time);
- outb_p(2+volconvert(dev->curvol), io);
- outb_p(64+2+volconvert(dev->curvol), io);
+ outb_p(2 + volconvert(az->curvol), az->io);
+ outb_p(64 + 2 + volconvert(az->curvol), az->io);
}
-static void send_1_byte (struct az_device *dev)
+static void send_1_byte(struct aztech *az)
{
udelay (radio_wait_time);
- outb_p(128+2+volconvert(dev->curvol), io);
- outb_p(128+64+2+volconvert(dev->curvol), io);
+ outb_p(128 + 2 + volconvert(az->curvol), az->io);
+ outb_p(128 + 64 + 2 + volconvert(az->curvol), az->io);
}
-static int az_setvol(struct az_device *dev, int vol)
+static int az_setvol(struct aztech *az, int vol)
{
- mutex_lock(&lock);
- outb (volconvert(vol), io);
- mutex_unlock(&lock);
+ mutex_lock(&az->lock);
+ outb(volconvert(vol), az->io);
+ mutex_unlock(&az->lock);
return 0;
}
@@ -126,116 +117,110 @@ static int az_setvol(struct az_device *dev, int vol)
*
*/
-static int az_getsigstr(struct az_device *dev)
+static int az_getsigstr(struct aztech *az)
{
- if (inb(io) & 2) /* bit set = no signal present */
- return 0;
- return 1; /* signal present */
+ int sig = 1;
+
+ mutex_lock(&az->lock);
+ if (inb(az->io) & 2) /* bit set = no signal present */
+ sig = 0;
+ mutex_unlock(&az->lock);
+ return sig;
}
-static int az_getstereo(struct az_device *dev)
+static int az_getstereo(struct aztech *az)
{
- if (inb(io) & 1) /* bit set = mono */
- return 0;
- return 1; /* stereo */
+ int stereo = 1;
+
+ mutex_lock(&az->lock);
+ if (inb(az->io) & 1) /* bit set = mono */
+ stereo = 0;
+ mutex_unlock(&az->lock);
+ return stereo;
}
-static int az_setfreq(struct az_device *dev, unsigned long frequency)
+static int az_setfreq(struct aztech *az, unsigned long frequency)
{
int i;
+ mutex_lock(&az->lock);
+
+ az->curfreq = frequency;
frequency += 171200; /* Add 10.7 MHz IF */
frequency /= 800; /* Convert to 50 kHz units */
- mutex_lock(&lock);
-
- send_0_byte (dev); /* 0: LSB of frequency */
+ send_0_byte(az); /* 0: LSB of frequency */
for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
if (frequency & (1 << i))
- send_1_byte (dev);
+ send_1_byte(az);
else
- send_0_byte (dev);
+ send_0_byte(az);
- send_0_byte (dev); /* 14: test bit - always 0 */
- send_0_byte (dev); /* 15: test bit - always 0 */
- send_0_byte (dev); /* 16: band data 0 - always 0 */
- if (dev->stereo) /* 17: stereo (1 to enable) */
- send_1_byte (dev);
+ send_0_byte(az); /* 14: test bit - always 0 */
+ send_0_byte(az); /* 15: test bit - always 0 */
+ send_0_byte(az); /* 16: band data 0 - always 0 */
+ if (az->stereo) /* 17: stereo (1 to enable) */
+ send_1_byte(az);
else
- send_0_byte (dev);
+ send_0_byte(az);
- send_1_byte (dev); /* 18: band data 1 - unknown */
- send_0_byte (dev); /* 19: time base - always 0 */
- send_0_byte (dev); /* 20: spacing (0 = 25 kHz) */
- send_1_byte (dev); /* 21: spacing (1 = 25 kHz) */
- send_0_byte (dev); /* 22: spacing (0 = 25 kHz) */
- send_1_byte (dev); /* 23: AM/FM (FM = 1, always) */
+ send_1_byte(az); /* 18: band data 1 - unknown */
+ send_0_byte(az); /* 19: time base - always 0 */
+ send_0_byte(az); /* 20: spacing (0 = 25 kHz) */
+ send_1_byte(az); /* 21: spacing (1 = 25 kHz) */
+ send_0_byte(az); /* 22: spacing (0 = 25 kHz) */
+ send_1_byte(az); /* 23: AM/FM (FM = 1, always) */
/* latch frequency */
- udelay (radio_wait_time);
- outb_p(128+64+volconvert(dev->curvol), io);
+ udelay(radio_wait_time);
+ outb_p(128 + 64 + volconvert(az->curvol), az->io);
- mutex_unlock(&lock);
+ mutex_unlock(&az->lock);
return 0;
}
-static int vidioc_querycap (struct file *file, void *priv,
+static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
- strlcpy(v->driver, "radio-aztech", sizeof (v->driver));
- strlcpy(v->card, "Aztech Radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
+ strlcpy(v->driver, "radio-aztech", sizeof(v->driver));
+ strlcpy(v->card, "Aztech Radio", sizeof(v->card));
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
-static int vidioc_g_tuner (struct file *file, void *priv,
+static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow=(87*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
- v->capability=V4L2_TUNER_CAP_LOW;
- if(az_getstereo(az))
+ v->rangelow = 87 * 16000;
+ v->rangehigh = 108 * 16000;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ if (az_getstereo(az))
v->audmode = V4L2_TUNER_MODE_STEREO;
else
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*az_getsigstr(az);
+ v->signal = 0xFFFF * az_getsigstr(az);
return 0;
}
-
-static int vidioc_s_tuner (struct file *file, void *priv,
+static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
-
- return 0;
-}
-
-static int vidioc_g_audio (struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
@@ -246,113 +231,107 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-
-static int vidioc_s_audio (struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
-
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static int vidioc_s_frequency (struct file *file, void *priv,
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = video_drvdata(file);
- az->curfreq = f->frequency;
- az_setfreq(az, az->curfreq);
+ az_setfreq(az, f->frequency);
return 0;
}
-static int vidioc_g_frequency (struct file *file, void *priv,
+static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = az->curfreq;
-
return 0;
}
-static int vidioc_queryctrl (struct file *file, void *priv,
+static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff);
}
return -EINVAL;
}
-static int vidioc_g_ctrl (struct file *file, void *priv,
+static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = video_drvdata(file);
switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (az->curvol==0)
- ctrl->value=1;
- else
- ctrl->value=0;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value=az->curvol * 6554;
- return (0);
+ case V4L2_CID_AUDIO_MUTE:
+ if (az->curvol == 0)
+ ctrl->value = 1;
+ else
+ ctrl->value = 0;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = az->curvol * 6554;
+ return 0;
}
return -EINVAL;
}
-static int vidioc_s_ctrl (struct file *file, void *priv,
+static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = video_drvdata(file);
switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- az_setvol(az,0);
- } else {
- az_setvol(az,az->curvol);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- az_setvol(az,ctrl->value);
- return (0);
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ az_setvol(az, 0);
+ else
+ az_setvol(az, az->curvol);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ az_setvol(az, ctrl->value);
+ return 0;
}
return -EINVAL;
}
-static struct az_device aztech_unit;
-
-static int aztech_exclusive_open(struct file *file)
+static int aztech_open(struct file *file)
{
- return test_and_set_bit(0, &aztech_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int aztech_exclusive_release(struct file *file)
+static int aztech_release(struct file *file)
{
- clear_bit(0, &aztech_unit.in_use);
return 0;
}
static const struct v4l2_file_operations aztech_fops = {
.owner = THIS_MODULE,
- .open = aztech_exclusive_open,
- .release = aztech_exclusive_release,
+ .open = aztech_open,
+ .release = aztech_release,
.ioctl = video_ioctl2,
};
@@ -371,57 +350,60 @@ static const struct v4l2_ioctl_ops aztech_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device aztech_radio = {
- .name = "Aztech radio",
- .fops = &aztech_fops,
- .ioctl_ops = &aztech_ioctl_ops,
- .release = video_device_release_empty,
-};
-
-module_param_named(debug,aztech_radio.debug, int, 0644);
-MODULE_PARM_DESC(debug,"activates debug info");
-
static int __init aztech_init(void)
{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+ struct aztech *az = &aztech_card;
+ struct v4l2_device *v4l2_dev = &az->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "aztech", sizeof(v4l2_dev->name));
+ az->io = io;
+
+ if (az->io == -1) {
+ v4l2_err(v4l2_dev, "you must set an I/O address with io=0x350 or 0x358\n");
return -EINVAL;
}
- if (!request_region(io, 2, "aztech"))
- {
- printk(KERN_ERR "aztech: port 0x%x already in use\n", io);
+ if (!request_region(az->io, 2, "aztech")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", az->io);
return -EBUSY;
}
- mutex_init(&lock);
- video_set_drvdata(&aztech_radio, &aztech_unit);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(az->io, 2);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
- if (video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io,2);
+ mutex_init(&az->lock);
+ strlcpy(az->vdev.name, v4l2_dev->name, sizeof(az->vdev.name));
+ az->vdev.v4l2_dev = v4l2_dev;
+ az->vdev.fops = &aztech_fops;
+ az->vdev.ioctl_ops = &aztech_ioctl_ops;
+ az->vdev.release = video_device_release_empty;
+ video_set_drvdata(&az->vdev, az);
+
+ if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(az->io, 2);
return -EINVAL;
}
- printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
+ v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
/* mute card - prevents noisy bootups */
- outb (0, io);
+ outb(0, az->io);
return 0;
}
-MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
-MODULE_DESCRIPTION("A driver for the Aztech radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-module_param(radio_nr, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
-
-static void __exit aztech_cleanup(void)
+static void __exit aztech_exit(void)
{
- video_unregister_device(&aztech_radio);
- release_region(io,2);
+ struct aztech *az = &aztech_card;
+
+ video_unregister_device(&az->vdev);
+ v4l2_device_unregister(&az->v4l2_dev);
+ release_region(az->io, 2);
}
module_init(aztech_init);
-module_exit(aztech_cleanup);
+module_exit(aztech_exit);
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index cb3075ac104c..d30fc0ce82c0 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -35,333 +35,318 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* V4L2 API defs */
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
#include <linux/param.h>
#include <linux/pnp.h>
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+
+MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
+MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card.");
+MODULE_LICENSE("GPL");
+
+static int io = -1; /* default to isapnp activation */
+static int radio_nr = -1;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)");
+module_param(radio_nr, int, 0);
+
+#define CADET_VERSION KERNEL_VERSION(0, 3, 3)
#define RDS_BUFFER 256
#define RDS_RX_FLAG 1
#define MBS_RX_FLAG 2
-#define CADET_VERSION KERNEL_VERSION(0,3,3)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
+struct cadet {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
+ int users;
+ int curtuner;
+ int tunestat;
+ int sigstrength;
+ wait_queue_head_t read_queue;
+ struct timer_list readtimer;
+ __u8 rdsin, rdsout, rdsstat;
+ unsigned char rdsbuf[RDS_BUFFER];
+ struct mutex lock;
+ int reading;
};
-static int io=-1; /* default to isapnp activation */
-static int radio_nr = -1;
-static int users;
-static int curtuner;
-static int tunestat;
-static int sigstrength;
-static wait_queue_head_t read_queue;
-static struct timer_list readtimer;
-static __u8 rdsin, rdsout, rdsstat;
-static unsigned char rdsbuf[RDS_BUFFER];
-static spinlock_t cadet_io_lock;
-
-static int cadet_probe(void);
+static struct cadet cadet_card;
/*
* Signal Strength Threshold Values
* The V4L API spec does not define any particular unit for the signal
* strength value. These values are in microvolts of RF at the tuner's input.
*/
-static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}};
+static __u16 sigtable[2][4] = {
+ { 5, 10, 30, 150 },
+ { 28, 40, 63, 1000 }
+};
-static int
-cadet_getstereo(void)
+static int cadet_getstereo(struct cadet *dev)
{
int ret = V4L2_TUNER_SUB_MONO;
- if(curtuner != 0) /* Only FM has stereo capability! */
+
+ if (dev->curtuner != 0) /* Only FM has stereo capability! */
return V4L2_TUNER_SUB_MONO;
- spin_lock(&cadet_io_lock);
- outb(7,io); /* Select tuner control */
- if( (inb(io+1) & 0x40) == 0)
+ mutex_lock(&dev->lock);
+ outb(7, dev->io); /* Select tuner control */
+ if ((inb(dev->io + 1) & 0x40) == 0)
ret = V4L2_TUNER_SUB_STEREO;
- spin_unlock(&cadet_io_lock);
+ mutex_unlock(&dev->lock);
return ret;
}
-static unsigned
-cadet_gettune(void)
+static unsigned cadet_gettune(struct cadet *dev)
{
- int curvol,i;
- unsigned fifo=0;
+ int curvol, i;
+ unsigned fifo = 0;
/*
* Prepare for read
*/
- spin_lock(&cadet_io_lock);
+ mutex_lock(&dev->lock);
- outb(7,io); /* Select tuner control */
- curvol=inb(io+1); /* Save current volume/mute setting */
- outb(0x00,io+1); /* Ensure WRITE-ENABLE is LOW */
- tunestat=0xffff;
+ outb(7, dev->io); /* Select tuner control */
+ curvol = inb(dev->io + 1); /* Save current volume/mute setting */
+ outb(0x00, dev->io + 1); /* Ensure WRITE-ENABLE is LOW */
+ dev->tunestat = 0xffff;
/*
* Read the shift register
*/
- for(i=0;i<25;i++) {
- fifo=(fifo<<1)|((inb(io+1)>>7)&0x01);
- if(i<24) {
- outb(0x01,io+1);
- tunestat&=inb(io+1);
- outb(0x00,io+1);
+ for (i = 0; i < 25; i++) {
+ fifo = (fifo << 1) | ((inb(dev->io + 1) >> 7) & 0x01);
+ if (i < 24) {
+ outb(0x01, dev->io + 1);
+ dev->tunestat &= inb(dev->io + 1);
+ outb(0x00, dev->io + 1);
}
}
/*
* Restore volume/mute setting
*/
- outb(curvol,io+1);
- spin_unlock(&cadet_io_lock);
+ outb(curvol, dev->io + 1);
+ mutex_unlock(&dev->lock);
return fifo;
}
-static unsigned
-cadet_getfreq(void)
+static unsigned cadet_getfreq(struct cadet *dev)
{
int i;
- unsigned freq=0,test,fifo=0;
+ unsigned freq = 0, test, fifo = 0;
/*
* Read current tuning
*/
- fifo=cadet_gettune();
+ fifo = cadet_gettune(dev);
/*
* Convert to actual frequency
*/
- if(curtuner==0) { /* FM */
- test=12500;
- for(i=0;i<14;i++) {
- if((fifo&0x01)!=0) {
- freq+=test;
- }
- test=test<<1;
- fifo=fifo>>1;
+ if (dev->curtuner == 0) { /* FM */
+ test = 12500;
+ for (i = 0; i < 14; i++) {
+ if ((fifo & 0x01) != 0)
+ freq += test;
+ test = test << 1;
+ fifo = fifo >> 1;
}
- freq-=10700000; /* IF frequency is 10.7 MHz */
- freq=(freq*16)/1000000; /* Make it 1/16 MHz */
- }
- if(curtuner==1) { /* AM */
- freq=((fifo&0x7fff)-2010)*16;
+ freq -= 10700000; /* IF frequency is 10.7 MHz */
+ freq = (freq * 16) / 1000000; /* Make it 1/16 MHz */
}
+ if (dev->curtuner == 1) /* AM */
+ freq = ((fifo & 0x7fff) - 2010) * 16;
return freq;
}
-static void
-cadet_settune(unsigned fifo)
+static void cadet_settune(struct cadet *dev, unsigned fifo)
{
int i;
unsigned test;
- spin_lock(&cadet_io_lock);
+ mutex_lock(&dev->lock);
- outb(7,io); /* Select tuner control */
+ outb(7, dev->io); /* Select tuner control */
/*
* Write the shift register
*/
- test=0;
- test=(fifo>>23)&0x02; /* Align data for SDO */
- test|=0x1c; /* SDM=1, SWE=1, SEN=1, SCK=0 */
- outb(7,io); /* Select tuner control */
- outb(test,io+1); /* Initialize for write */
- for(i=0;i<25;i++) {
- test|=0x01; /* Toggle SCK High */
- outb(test,io+1);
- test&=0xfe; /* Toggle SCK Low */
- outb(test,io+1);
- fifo=fifo<<1; /* Prepare the next bit */
- test=0x1c|((fifo>>23)&0x02);
- outb(test,io+1);
+ test = 0;
+ test = (fifo >> 23) & 0x02; /* Align data for SDO */
+ test |= 0x1c; /* SDM=1, SWE=1, SEN=1, SCK=0 */
+ outb(7, dev->io); /* Select tuner control */
+ outb(test, dev->io + 1); /* Initialize for write */
+ for (i = 0; i < 25; i++) {
+ test |= 0x01; /* Toggle SCK High */
+ outb(test, dev->io + 1);
+ test &= 0xfe; /* Toggle SCK Low */
+ outb(test, dev->io + 1);
+ fifo = fifo << 1; /* Prepare the next bit */
+ test = 0x1c | ((fifo >> 23) & 0x02);
+ outb(test, dev->io + 1);
}
- spin_unlock(&cadet_io_lock);
+ mutex_unlock(&dev->lock);
}
-static void
-cadet_setfreq(unsigned freq)
+static void cadet_setfreq(struct cadet *dev, unsigned freq)
{
unsigned fifo;
- int i,j,test;
+ int i, j, test;
int curvol;
/*
* Formulate a fifo command
*/
- fifo=0;
- if(curtuner==0) { /* FM */
- test=102400;
- freq=(freq*1000)/16; /* Make it kHz */
- freq+=10700; /* IF is 10700 kHz */
- for(i=0;i<14;i++) {
- fifo=fifo<<1;
- if(freq>=test) {
- fifo|=0x01;
- freq-=test;
+ fifo = 0;
+ if (dev->curtuner == 0) { /* FM */
+ test = 102400;
+ freq = (freq * 1000) / 16; /* Make it kHz */
+ freq += 10700; /* IF is 10700 kHz */
+ for (i = 0; i < 14; i++) {
+ fifo = fifo << 1;
+ if (freq >= test) {
+ fifo |= 0x01;
+ freq -= test;
}
- test=test>>1;
+ test = test >> 1;
}
}
- if(curtuner==1) { /* AM */
- fifo=(freq/16)+2010; /* Make it kHz */
- fifo|=0x100000; /* Select AM Band */
+ if (dev->curtuner == 1) { /* AM */
+ fifo = (freq / 16) + 2010; /* Make it kHz */
+ fifo |= 0x100000; /* Select AM Band */
}
/*
* Save current volume/mute setting
*/
- spin_lock(&cadet_io_lock);
- outb(7,io); /* Select tuner control */
- curvol=inb(io+1);
- spin_unlock(&cadet_io_lock);
+ mutex_lock(&dev->lock);
+ outb(7, dev->io); /* Select tuner control */
+ curvol = inb(dev->io + 1);
+ mutex_unlock(&dev->lock);
/*
* Tune the card
*/
- for(j=3;j>-1;j--) {
- cadet_settune(fifo|(j<<16));
+ for (j = 3; j > -1; j--) {
+ cadet_settune(dev, fifo | (j << 16));
- spin_lock(&cadet_io_lock);
- outb(7,io); /* Select tuner control */
- outb(curvol,io+1);
- spin_unlock(&cadet_io_lock);
+ mutex_lock(&dev->lock);
+ outb(7, dev->io); /* Select tuner control */
+ outb(curvol, dev->io + 1);
+ mutex_unlock(&dev->lock);
msleep(100);
- cadet_gettune();
- if((tunestat & 0x40) == 0) { /* Tuned */
- sigstrength=sigtable[curtuner][j];
+ cadet_gettune(dev);
+ if ((dev->tunestat & 0x40) == 0) { /* Tuned */
+ dev->sigstrength = sigtable[dev->curtuner][j];
return;
}
}
- sigstrength=0;
+ dev->sigstrength = 0;
}
-static int
-cadet_getvol(void)
+static int cadet_getvol(struct cadet *dev)
{
int ret = 0;
- spin_lock(&cadet_io_lock);
+ mutex_lock(&dev->lock);
- outb(7,io); /* Select tuner control */
- if((inb(io + 1) & 0x20) != 0)
+ outb(7, dev->io); /* Select tuner control */
+ if ((inb(dev->io + 1) & 0x20) != 0)
ret = 0xffff;
- spin_unlock(&cadet_io_lock);
+ mutex_unlock(&dev->lock);
return ret;
}
-static void
-cadet_setvol(int vol)
+static void cadet_setvol(struct cadet *dev, int vol)
{
- spin_lock(&cadet_io_lock);
- outb(7,io); /* Select tuner control */
- if(vol>0)
- outb(0x20,io+1);
+ mutex_lock(&dev->lock);
+ outb(7, dev->io); /* Select tuner control */
+ if (vol > 0)
+ outb(0x20, dev->io + 1);
else
- outb(0x00,io+1);
- spin_unlock(&cadet_io_lock);
+ outb(0x00, dev->io + 1);
+ mutex_unlock(&dev->lock);
}
-static void
-cadet_handler(unsigned long data)
+static void cadet_handler(unsigned long data)
{
- /*
- * Service the RDS fifo
- */
+ struct cadet *dev = (void *)data;
- if(spin_trylock(&cadet_io_lock))
- {
- outb(0x3,io); /* Select RDS Decoder Control */
- if((inb(io+1)&0x20)!=0) {
+ /* Service the RDS fifo */
+ if (mutex_trylock(&dev->lock)) {
+ outb(0x3, dev->io); /* Select RDS Decoder Control */
+ if ((inb(dev->io + 1) & 0x20) != 0)
printk(KERN_CRIT "cadet: RDS fifo overflow\n");
- }
- outb(0x80,io); /* Select RDS fifo */
- while((inb(io)&0x80)!=0) {
- rdsbuf[rdsin]=inb(io+1);
- if(rdsin==rdsout)
+ outb(0x80, dev->io); /* Select RDS fifo */
+ while ((inb(dev->io) & 0x80) != 0) {
+ dev->rdsbuf[dev->rdsin] = inb(dev->io + 1);
+ if (dev->rdsin == dev->rdsout)
printk(KERN_WARNING "cadet: RDS buffer overflow\n");
else
- rdsin++;
+ dev->rdsin++;
}
- spin_unlock(&cadet_io_lock);
+ mutex_unlock(&dev->lock);
}
/*
* Service pending read
*/
- if( rdsin!=rdsout)
- wake_up_interruptible(&read_queue);
+ if (dev->rdsin != dev->rdsout)
+ wake_up_interruptible(&dev->read_queue);
/*
* Clean up and exit
*/
- init_timer(&readtimer);
- readtimer.function=cadet_handler;
- readtimer.data=(unsigned long)0;
- readtimer.expires=jiffies+msecs_to_jiffies(50);
- add_timer(&readtimer);
+ init_timer(&dev->readtimer);
+ dev->readtimer.function = cadet_handler;
+ dev->readtimer.data = (unsigned long)0;
+ dev->readtimer.expires = jiffies + msecs_to_jiffies(50);
+ add_timer(&dev->readtimer);
}
-
-static ssize_t
-cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
+static ssize_t cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
{
- int i=0;
+ struct cadet *dev = video_drvdata(file);
unsigned char readbuf[RDS_BUFFER];
-
- if(rdsstat==0) {
- spin_lock(&cadet_io_lock);
- rdsstat=1;
- outb(0x80,io); /* Select RDS fifo */
- spin_unlock(&cadet_io_lock);
- init_timer(&readtimer);
- readtimer.function=cadet_handler;
- readtimer.data=(unsigned long)0;
- readtimer.expires=jiffies+msecs_to_jiffies(50);
- add_timer(&readtimer);
+ int i = 0;
+
+ if (dev->rdsstat == 0) {
+ mutex_lock(&dev->lock);
+ dev->rdsstat = 1;
+ outb(0x80, dev->io); /* Select RDS fifo */
+ mutex_unlock(&dev->lock);
+ init_timer(&dev->readtimer);
+ dev->readtimer.function = cadet_handler;
+ dev->readtimer.data = (unsigned long)dev;
+ dev->readtimer.expires = jiffies + msecs_to_jiffies(50);
+ add_timer(&dev->readtimer);
}
- if(rdsin==rdsout) {
+ if (dev->rdsin == dev->rdsout) {
if (file->f_flags & O_NONBLOCK)
return -EWOULDBLOCK;
- interruptible_sleep_on(&read_queue);
+ interruptible_sleep_on(&dev->read_queue);
}
- while( i<count && rdsin!=rdsout)
- readbuf[i++]=rdsbuf[rdsout++];
+ while (i < count && dev->rdsin != dev->rdsout)
+ readbuf[i++] = dev->rdsbuf[dev->rdsout++];
- if (copy_to_user(data,readbuf,i))
+ if (copy_to_user(data, readbuf, i))
return -EFAULT;
return i;
}
@@ -370,38 +355,40 @@ cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
- v->capabilities =
- V4L2_CAP_TUNER |
- V4L2_CAP_READWRITE;
+ strlcpy(v->driver, "ADS Cadet", sizeof(v->driver));
+ strlcpy(v->card, "ADS Cadet", sizeof(v->card));
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = CADET_VERSION;
- strcpy(v->driver, "ADS Cadet");
- strcpy(v->card, "ADS Cadet");
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_READWRITE;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
+ struct cadet *dev = video_drvdata(file);
+
v->type = V4L2_TUNER_RADIO;
switch (v->index) {
case 0:
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->capability = V4L2_TUNER_CAP_STEREO;
v->rangelow = 1400; /* 87.5 MHz */
v->rangehigh = 1728; /* 108.0 MHz */
- v->rxsubchans=cadet_getstereo();
- switch (v->rxsubchans){
+ v->rxsubchans = cadet_getstereo(dev);
+ switch (v->rxsubchans) {
case V4L2_TUNER_SUB_MONO:
v->audmode = V4L2_TUNER_MODE_MONO;
break;
case V4L2_TUNER_SUB_STEREO:
v->audmode = V4L2_TUNER_MODE_STEREO;
break;
- default: ;
+ default:
+ break;
}
break;
case 1:
- strcpy(v->name, "AM");
+ strlcpy(v->name, "AM", sizeof(v->name));
v->capability = V4L2_TUNER_CAP_LOW;
v->rangelow = 8320; /* 520 kHz */
v->rangehigh = 26400; /* 1650 kHz */
@@ -411,25 +398,29 @@ static int vidioc_g_tuner(struct file *file, void *priv,
default:
return -EINVAL;
}
- v->signal = sigstrength; /* We might need to modify scaling of this */
+ v->signal = dev->sigstrength; /* We might need to modify scaling of this */
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if((v->index != 0)&&(v->index != 1))
+ struct cadet *dev = video_drvdata(file);
+
+ if (v->index != 0 && v->index != 1)
return -EINVAL;
- curtuner = v->index;
+ dev->curtuner = v->index;
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- f->tuner = curtuner;
+ struct cadet *dev = video_drvdata(file);
+
+ f->tuner = dev->curtuner;
f->type = V4L2_TUNER_RADIO;
- f->frequency = cadet_getfreq();
+ f->frequency = cadet_getfreq(dev);
return 0;
}
@@ -437,27 +428,26 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
+ struct cadet *dev = video_drvdata(file);
+
if (f->type != V4L2_TUNER_RADIO)
return -EINVAL;
- if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728)))
+ if (dev->curtuner == 0 && (f->frequency < 1400 || f->frequency > 1728))
return -EINVAL;
- if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400)))
+ if (dev->curtuner == 1 && (f->frequency < 8320 || f->frequency > 26400))
return -EINVAL;
- cadet_setfreq(f->frequency);
+ cadet_setfreq(dev, f->frequency);
return 0;
}
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff);
}
return -EINVAL;
}
@@ -465,12 +455,14 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- switch (ctrl->id){
+ struct cadet *dev = video_drvdata(file);
+
+ switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
- ctrl->value = (cadet_getvol() == 0);
+ ctrl->value = (cadet_getvol(dev) == 0);
break;
case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = cadet_getvol();
+ ctrl->value = cadet_getvol(dev);
break;
default:
return -EINVAL;
@@ -481,15 +473,17 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
+ struct cadet *dev = video_drvdata(file);
+
switch (ctrl->id){
case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
if (ctrl->value)
- cadet_setvol(0);
+ cadet_setvol(dev, 0);
else
- cadet_setvol(0xffff);
+ cadet_setvol(dev, 0xffff);
break;
case V4L2_CID_AUDIO_VOLUME:
- cadet_setvol(ctrl->value);
+ cadet_setvol(dev, ctrl->value);
break;
default:
return -EINVAL;
@@ -497,16 +491,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
return 0;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -515,43 +499,52 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
+ return i ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
static int vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
- return 0;
+ return a->index ? -EINVAL : 0;
}
-static int
-cadet_open(struct file *file)
+static int cadet_open(struct file *file)
{
- users++;
- if (1 == users) init_waitqueue_head(&read_queue);
+ struct cadet *dev = video_drvdata(file);
+
+ dev->users++;
+ if (1 == dev->users)
+ init_waitqueue_head(&dev->read_queue);
return 0;
}
-static int
-cadet_release(struct file *file)
+static int cadet_release(struct file *file)
{
- users--;
- if (0 == users){
- del_timer_sync(&readtimer);
- rdsstat=0;
+ struct cadet *dev = video_drvdata(file);
+
+ dev->users--;
+ if (0 == dev->users) {
+ del_timer_sync(&dev->readtimer);
+ dev->rdsstat = 0;
}
return 0;
}
-static unsigned int
-cadet_poll(struct file *file, struct poll_table_struct *wait)
+static unsigned int cadet_poll(struct file *file, struct poll_table_struct *wait)
{
- poll_wait(file,&read_queue,wait);
- if(rdsin != rdsout)
+ struct cadet *dev = video_drvdata(file);
+
+ poll_wait(file, &dev->read_queue, wait);
+ if (dev->rdsin != dev->rdsout)
return POLLIN | POLLRDNORM;
return 0;
}
@@ -581,13 +574,6 @@ static const struct v4l2_ioctl_ops cadet_ioctl_ops = {
.vidioc_s_input = vidioc_s_input,
};
-static struct video_device cadet_radio = {
- .name = "Cadet radio",
- .fops = &cadet_fops,
- .ioctl_ops = &cadet_ioctl_ops,
- .release = video_device_release_empty,
-};
-
#ifdef CONFIG_PNP
static struct pnp_device_id cadet_pnp_devices[] = {
@@ -598,7 +584,7 @@ static struct pnp_device_id cadet_pnp_devices[] = {
MODULE_DEVICE_TABLE(pnp, cadet_pnp_devices);
-static int cadet_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
+static int cadet_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
if (!dev)
return -ENODEV;
@@ -606,13 +592,12 @@ static int cadet_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev
if (io > 0)
return -EBUSY;
- if (!pnp_port_valid(dev, 0)) {
+ if (!pnp_port_valid(dev, 0))
return -ENODEV;
- }
io = pnp_port_start(dev, 0);
- printk ("radio-cadet: PnP reports device at %#x\n", io);
+ printk(KERN_INFO "radio-cadet: PnP reports device at %#x\n", io);
return io;
}
@@ -628,23 +613,23 @@ static struct pnp_driver cadet_pnp_driver = {
static struct pnp_driver cadet_pnp_driver;
#endif
-static int cadet_probe(void)
+static void cadet_probe(struct cadet *dev)
{
- static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e};
+ static int iovals[8] = { 0x330, 0x332, 0x334, 0x336, 0x338, 0x33a, 0x33c, 0x33e };
int i;
- for(i=0;i<8;i++) {
- io=iovals[i];
- if (request_region(io, 2, "cadet-probe")) {
- cadet_setfreq(1410);
- if(cadet_getfreq()==1410) {
- release_region(io, 2);
- return io;
+ for (i = 0; i < 8; i++) {
+ dev->io = iovals[i];
+ if (request_region(dev->io, 2, "cadet-probe")) {
+ cadet_setfreq(dev, 1410);
+ if (cadet_getfreq(dev) == 1410) {
+ release_region(dev->io, 2);
+ return;
}
- release_region(io, 2);
+ release_region(dev->io, 2);
}
}
- return -1;
+ dev->io = -1;
}
/*
@@ -654,59 +639,69 @@ static int cadet_probe(void)
static int __init cadet_init(void)
{
- spin_lock_init(&cadet_io_lock);
+ struct cadet *dev = &cadet_card;
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+ int res;
- /*
- * If a probe was requested then probe ISAPnP first (safest)
- */
+ strlcpy(v4l2_dev->name, "cadet", sizeof(v4l2_dev->name));
+ mutex_init(&dev->lock);
+
+ /* If a probe was requested then probe ISAPnP first (safest) */
if (io < 0)
pnp_register_driver(&cadet_pnp_driver);
- /*
- * If that fails then probe unsafely if probe is requested
- */
- if(io < 0)
- io = cadet_probe ();
+ dev->io = io;
- /*
- * Else we bail out
- */
+ /* If that fails then probe unsafely if probe is requested */
+ if (dev->io < 0)
+ cadet_probe(dev);
- if(io < 0) {
+ /* Else we bail out */
+ if (dev->io < 0) {
#ifdef MODULE
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+ v4l2_err(v4l2_dev, "you must set an I/O address with io=0x330, 0x332, 0x334,\n");
+ v4l2_err(v4l2_dev, "0x336, 0x338, 0x33a, 0x33c or 0x33e\n");
#endif
goto fail;
}
- if (!request_region(io,2,"cadet"))
+ if (!request_region(dev->io, 2, "cadet"))
+ goto fail;
+
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(dev->io, 2);
+ v4l2_err(v4l2_dev, "could not register v4l2_device\n");
goto fail;
- if (video_register_device(&cadet_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io,2);
+ }
+
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &cadet_fops;
+ dev->vdev.ioctl_ops = &cadet_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
+
+ if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(dev->io, 2);
goto fail;
}
- printk(KERN_INFO "ADS Cadet Radio Card at 0x%x\n",io);
+ v4l2_info(v4l2_dev, "ADS Cadet Radio Card at 0x%x\n", dev->io);
return 0;
fail:
pnp_unregister_driver(&cadet_pnp_driver);
- return -1;
+ return -ENODEV;
}
-
-
-MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
-MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)");
-module_param(radio_nr, int, 0);
-
-static void __exit cadet_cleanup_module(void)
+static void __exit cadet_exit(void)
{
- video_unregister_device(&cadet_radio);
- release_region(io,2);
+ struct cadet *dev = &cadet_card;
+
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ release_region(dev->io, 2);
pnp_unregister_driver(&cadet_pnp_driver);
}
module_init(cadet_init);
-module_exit(cadet_cleanup_module);
+module_exit(cadet_exit);
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 0c96bf8525b0..09265d25725e 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -45,34 +45,25 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
#include <linux/errno.h>
-
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 65535,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
+#include <linux/io.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+MODULE_AUTHOR("Vladimir Shebordaev <vshebordaev@mail.ru>");
+MODULE_DESCRIPTION("The video4linux driver for the Gemtek PCI Radio Card");
+MODULE_LICENSE("GPL");
+
+static int nr_radio = -1;
+static int mx = 1;
+
+module_param(mx, bool, 0);
+MODULE_PARM_DESC(mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not");
+module_param(nr_radio, int, 0);
+MODULE_PARM_DESC(nr_radio, "video4linux device number to use");
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
#ifndef PCI_VENDOR_ID_GEMTEK
#define PCI_VENDOR_ID_GEMTEK 0x5046
@@ -90,8 +81,11 @@ static struct v4l2_queryctrl radio_qctrl[] = {
#define GEMTEK_PCI_RANGE_HIGH (108*16000)
#endif
-struct gemtek_pci_card {
- struct video_device *videodev;
+struct gemtek_pci {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ struct mutex lock;
+ struct pci_dev *pdev;
u32 iobase;
u32 length;
@@ -100,116 +94,133 @@ struct gemtek_pci_card {
u8 mute;
};
-static int nr_radio = -1;
-static unsigned long in_use;
+static inline struct gemtek_pci *to_gemtek_pci(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct gemtek_pci, v4l2_dev);
+}
-static inline u8 gemtek_pci_out( u16 value, u32 port )
+static inline u8 gemtek_pci_out(u16 value, u32 port)
{
- outw( value, port );
+ outw(value, port);
return (u8)value;
}
-#define _b0( v ) *((u8 *)&v)
-static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep )
+#define _b0(v) (*((u8 *)&v))
+
+static void __gemtek_pci_cmd(u16 value, u32 port, u8 *last_byte, int keep)
{
- register u8 byte = *last_byte;
+ u8 byte = *last_byte;
- if ( !value ) {
- if ( !keep )
+ if (!value) {
+ if (!keep)
value = (u16)port;
byte &= 0xfd;
} else
byte |= 2;
- _b0( value ) = byte;
- outw( value, port );
+ _b0(value) = byte;
+ outw(value, port);
byte |= 1;
- _b0( value ) = byte;
- outw( value, port );
+ _b0(value) = byte;
+ outw(value, port);
byte &= 0xfe;
- _b0( value ) = byte;
- outw( value, port );
+ _b0(value) = byte;
+ outw(value, port);
*last_byte = byte;
}
-static inline void gemtek_pci_nil( u32 port, u8 *last_byte )
+static inline void gemtek_pci_nil(u32 port, u8 *last_byte)
{
- __gemtek_pci_cmd( 0x00, port, last_byte, false );
+ __gemtek_pci_cmd(0x00, port, last_byte, false);
}
-static inline void gemtek_pci_cmd( u16 cmd, u32 port, u8 *last_byte )
+static inline void gemtek_pci_cmd(u16 cmd, u32 port, u8 *last_byte)
{
- __gemtek_pci_cmd( cmd, port, last_byte, true );
+ __gemtek_pci_cmd(cmd, port, last_byte, true);
}
-static void gemtek_pci_setfrequency( struct gemtek_pci_card *card, unsigned long frequency )
+static void gemtek_pci_setfrequency(struct gemtek_pci *card, unsigned long frequency)
{
- register int i;
- register u32 value = frequency / 200 + 856;
- register u16 mask = 0x8000;
+ int i;
+ u32 value = frequency / 200 + 856;
+ u16 mask = 0x8000;
u8 last_byte;
u32 port = card->iobase;
- last_byte = gemtek_pci_out( 0x06, port );
+ mutex_lock(&card->lock);
+ card->current_frequency = frequency;
+ last_byte = gemtek_pci_out(0x06, port);
i = 0;
do {
- gemtek_pci_nil( port, &last_byte );
+ gemtek_pci_nil(port, &last_byte);
i++;
- } while ( i < 9 );
+ } while (i < 9);
i = 0;
do {
- gemtek_pci_cmd( value & mask, port, &last_byte );
+ gemtek_pci_cmd(value & mask, port, &last_byte);
mask >>= 1;
i++;
- } while ( i < 16 );
+ } while (i < 16);
- outw( 0x10, port );
+ outw(0x10, port);
+ mutex_unlock(&card->lock);
}
-static inline void gemtek_pci_mute( struct gemtek_pci_card *card )
+static void gemtek_pci_mute(struct gemtek_pci *card)
{
- outb( 0x1f, card->iobase );
+ mutex_lock(&card->lock);
+ outb(0x1f, card->iobase);
card->mute = true;
+ mutex_unlock(&card->lock);
}
-static inline void gemtek_pci_unmute( struct gemtek_pci_card *card )
+static void gemtek_pci_unmute(struct gemtek_pci *card)
{
- if ( card->mute ) {
- gemtek_pci_setfrequency( card, card->current_frequency );
+ mutex_lock(&card->lock);
+ if (card->mute) {
+ gemtek_pci_setfrequency(card, card->current_frequency);
card->mute = false;
}
+ mutex_unlock(&card->lock);
}
-static inline unsigned int gemtek_pci_getsignal( struct gemtek_pci_card *card )
+static int gemtek_pci_getsignal(struct gemtek_pci *card)
{
- return ( inb( card->iobase ) & 0x08 ) ? 0 : 1;
+ int sig;
+
+ mutex_lock(&card->lock);
+ sig = (inb(card->iobase) & 0x08) ? 0 : 1;
+ mutex_unlock(&card->lock);
+ return sig;
}
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
+ struct gemtek_pci *card = video_drvdata(file);
+
strlcpy(v->driver, "radio-gemtek-pci", sizeof(v->driver));
strlcpy(v->card, "GemTek PCI Radio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(card->pdev));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct gemtek_pci_card *card = video_drvdata(file);
+ struct gemtek_pci *card = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
v->rangelow = GEMTEK_PCI_RANGE_LOW;
v->rangehigh = GEMTEK_PCI_RANGE_HIGH;
@@ -223,21 +234,18 @@ static int vidioc_g_tuner(struct file *file, void *priv,
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct gemtek_pci_card *card = video_drvdata(file);
+ struct gemtek_pci *card = video_drvdata(file);
- if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) ||
- (f->frequency > GEMTEK_PCI_RANGE_HIGH) )
+ if (f->frequency < GEMTEK_PCI_RANGE_LOW ||
+ f->frequency > GEMTEK_PCI_RANGE_HIGH)
return -EINVAL;
gemtek_pci_setfrequency(card, f->frequency);
- card->current_frequency = f->frequency;
card->mute = false;
return 0;
}
@@ -245,7 +253,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct gemtek_pci_card *card = video_drvdata(file);
+ struct gemtek_pci *card = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = card->current_frequency;
@@ -255,13 +263,11 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535);
}
return -EINVAL;
}
@@ -269,7 +275,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct gemtek_pci_card *card = video_drvdata(file);
+ struct gemtek_pci *card = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -288,7 +294,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct gemtek_pci_card *card = video_drvdata(file);
+ struct gemtek_pci *card = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -307,17 +313,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -326,17 +321,22 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
+ return i ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
static int vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
- return 0;
+ return a->index ? -EINVAL : 0;
}
enum {
@@ -354,25 +354,22 @@ static struct pci_device_id gemtek_pci_id[] =
{ 0 }
};
-MODULE_DEVICE_TABLE( pci, gemtek_pci_id );
-
-static int mx = 1;
+MODULE_DEVICE_TABLE(pci, gemtek_pci_id);
-static int gemtek_pci_exclusive_open(struct file *file)
+static int gemtek_pci_open(struct file *file)
{
- return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
+ return 0;
}
-static int gemtek_pci_exclusive_release(struct file *file)
+static int gemtek_pci_release(struct file *file)
{
- clear_bit(0, &in_use);
return 0;
}
static const struct v4l2_file_operations gemtek_pci_fops = {
.owner = THIS_MODULE,
- .open = gemtek_pci_exclusive_open,
- .release = gemtek_pci_exclusive_release,
+ .open = gemtek_pci_open,
+ .release = gemtek_pci_release,
.ioctl = video_ioctl2,
};
@@ -391,108 +388,100 @@ static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device vdev_template = {
- .name = "Gemtek PCI Radio",
- .fops = &gemtek_pci_fops,
- .ioctl_ops = &gemtek_pci_ioctl_ops,
- .release = video_device_release_empty,
-};
-
-static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id )
+static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
{
- struct gemtek_pci_card *card;
- struct video_device *devradio;
+ struct gemtek_pci *card;
+ struct v4l2_device *v4l2_dev;
+ int res;
- if ( (card = kzalloc( sizeof( struct gemtek_pci_card ), GFP_KERNEL )) == NULL ) {
- printk( KERN_ERR "gemtek_pci: out of memory\n" );
+ card = kzalloc(sizeof(struct gemtek_pci), GFP_KERNEL);
+ if (card == NULL) {
+ dev_err(&pdev->dev, "out of memory\n");
return -ENOMEM;
}
- if ( pci_enable_device( pci_dev ) )
- goto err_pci;
+ v4l2_dev = &card->v4l2_dev;
+ mutex_init(&card->lock);
+ card->pdev = pdev;
- card->iobase = pci_resource_start( pci_dev, 0 );
- card->length = pci_resource_len( pci_dev, 0 );
+ strlcpy(v4l2_dev->name, "gemtek_pci", sizeof(v4l2_dev->name));
- if ( request_region( card->iobase, card->length, card_names[pci_id->driver_data] ) == NULL ) {
- printk( KERN_ERR "gemtek_pci: i/o port already in use\n" );
- goto err_pci;
+ res = v4l2_device_register(&pdev->dev, v4l2_dev);
+ if (res < 0) {
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ kfree(card);
+ return res;
}
- pci_set_drvdata( pci_dev, card );
+ if (pci_enable_device(pdev))
+ goto err_pci;
- if ( (devradio = kmalloc( sizeof( struct video_device ), GFP_KERNEL )) == NULL ) {
- printk( KERN_ERR "gemtek_pci: out of memory\n" );
- goto err_video;
+ card->iobase = pci_resource_start(pdev, 0);
+ card->length = pci_resource_len(pdev, 0);
+
+ if (request_region(card->iobase, card->length, card_names[pci_id->driver_data]) == NULL) {
+ v4l2_err(v4l2_dev, "i/o port already in use\n");
+ goto err_pci;
}
- *devradio = vdev_template;
- if (video_register_device(devradio, VFL_TYPE_RADIO, nr_radio) < 0) {
- kfree( devradio );
+ strlcpy(card->vdev.name, v4l2_dev->name, sizeof(card->vdev.name));
+ card->vdev.v4l2_dev = v4l2_dev;
+ card->vdev.fops = &gemtek_pci_fops;
+ card->vdev.ioctl_ops = &gemtek_pci_ioctl_ops;
+ card->vdev.release = video_device_release_empty;
+ video_set_drvdata(&card->vdev, card);
+
+ if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0)
goto err_video;
- }
- card->videodev = devradio;
- video_set_drvdata(devradio, card);
- gemtek_pci_mute( card );
+ gemtek_pci_mute(card);
- printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
- pci_dev->revision, card->iobase, card->iobase + card->length - 1 );
+ v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
+ pdev->revision, card->iobase, card->iobase + card->length - 1);
return 0;
err_video:
- release_region( card->iobase, card->length );
+ release_region(card->iobase, card->length);
err_pci:
- kfree( card );
+ v4l2_device_unregister(v4l2_dev);
+ kfree(card);
return -ENODEV;
}
-static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev )
+static void __devexit gemtek_pci_remove(struct pci_dev *pdev)
{
- struct gemtek_pci_card *card = pci_get_drvdata( pci_dev );
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct gemtek_pci *card = to_gemtek_pci(v4l2_dev);
- video_unregister_device( card->videodev );
- kfree( card->videodev );
+ video_unregister_device(&card->vdev);
+ v4l2_device_unregister(v4l2_dev);
- release_region( card->iobase, card->length );
+ release_region(card->iobase, card->length);
- if ( mx )
- gemtek_pci_mute( card );
+ if (mx)
+ gemtek_pci_mute(card);
- kfree( card );
-
- pci_set_drvdata( pci_dev, NULL );
+ kfree(card);
}
-static struct pci_driver gemtek_pci_driver =
-{
+static struct pci_driver gemtek_pci_driver = {
.name = "gemtek_pci",
.id_table = gemtek_pci_id,
.probe = gemtek_pci_probe,
.remove = __devexit_p(gemtek_pci_remove),
};
-static int __init gemtek_pci_init_module( void )
+static int __init gemtek_pci_init(void)
{
- return pci_register_driver( &gemtek_pci_driver );
+ return pci_register_driver(&gemtek_pci_driver);
}
-static void __exit gemtek_pci_cleanup_module( void )
+static void __exit gemtek_pci_exit(void)
{
pci_unregister_driver(&gemtek_pci_driver);
}
-MODULE_AUTHOR( "Vladimir Shebordaev <vshebordaev@mail.ru>" );
-MODULE_DESCRIPTION( "The video4linux driver for the Gemtek PCI Radio Card" );
-MODULE_LICENSE("GPL");
-
-module_param(mx, bool, 0);
-MODULE_PARM_DESC( mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not" );
-module_param(nr_radio, int, 0);
-MODULE_PARM_DESC( nr_radio, "video4linux device number to use");
-
-module_init( gemtek_pci_init_module );
-module_exit( gemtek_pci_cleanup_module );
-
+module_init(gemtek_pci_init);
+module_exit(gemtek_pci_exit);
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 2b68be773f13..150464426d1d 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -20,16 +20,14 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/mutex.h>
+#include <linux/io.h> /* outb, outb_p */
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-common.h>
-#include <linux/spinlock.h>
+#include <media/v4l2-device.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,3)
-#define RADIO_BANNER "GemTek Radio card driver: v0.0.3"
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 3)
/*
* Module info.
@@ -57,7 +55,6 @@ static int shutdown = 1;
static int keepmuted = 1;
static int initmute = 1;
static int radio_nr = -1;
-static unsigned long in_use;
module_param(io, int, 0444);
MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic "
@@ -112,12 +109,19 @@ module_param(radio_nr, int, 0444);
#define SHORT_DELAY 5 /* usec */
#define LONG_DELAY 75 /* usec */
-struct gemtek_device {
+struct gemtek {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ struct mutex lock;
unsigned long lastfreq;
int muted;
+ int verified;
+ int io;
u32 bu2614data;
};
+static struct gemtek gemtek_card;
+
#define BU2614_FREQ_BITS 16 /* D0..D15, Frequency data */
#define BU2614_PORT_BITS 3 /* P0..P2, Output port control data */
#define BU2614_VOID_BITS 4 /* unused */
@@ -153,10 +157,6 @@ struct gemtek_device {
#define BU2614_FMUN_MASK MKMASK(FMUN)
#define BU2614_TEST_MASK MKMASK(TEST)
-static struct gemtek_device gemtek_unit;
-
-static spinlock_t lock;
-
/*
* Set data which will be sent to BU2614FS.
*/
@@ -166,33 +166,33 @@ static spinlock_t lock;
/*
* Transmit settings to BU2614FS over GemTek IC.
*/
-static void gemtek_bu2614_transmit(struct gemtek_device *dev)
+static void gemtek_bu2614_transmit(struct gemtek *gt)
{
int i, bit, q, mute;
- spin_lock(&lock);
+ mutex_lock(&gt->lock);
- mute = dev->muted ? GEMTEK_MT : 0x00;
+ mute = gt->muted ? GEMTEK_MT : 0x00;
- outb_p(mute | GEMTEK_DA | GEMTEK_CK, io);
+ outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io);
udelay(SHORT_DELAY);
- outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, io);
+ outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io);
udelay(LONG_DELAY);
- for (i = 0, q = dev->bu2614data; i < 32; i++, q >>= 1) {
- bit = (q & 1) ? GEMTEK_DA : 0;
- outb_p(mute | GEMTEK_CE | bit, io);
- udelay(SHORT_DELAY);
- outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, io);
- udelay(SHORT_DELAY);
+ for (i = 0, q = gt->bu2614data; i < 32; i++, q >>= 1) {
+ bit = (q & 1) ? GEMTEK_DA : 0;
+ outb_p(mute | GEMTEK_CE | bit, gt->io);
+ udelay(SHORT_DELAY);
+ outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, gt->io);
+ udelay(SHORT_DELAY);
}
- outb_p(mute | GEMTEK_DA | GEMTEK_CK, io);
+ outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io);
udelay(SHORT_DELAY);
- outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, io);
+ outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io);
udelay(LONG_DELAY);
- spin_unlock(&lock);
+ mutex_unlock(&gt->lock);
}
/*
@@ -206,107 +206,109 @@ static unsigned long gemtek_convfreq(unsigned long freq)
/*
* Set FM-frequency.
*/
-static void gemtek_setfreq(struct gemtek_device *dev, unsigned long freq)
+static void gemtek_setfreq(struct gemtek *gt, unsigned long freq)
{
-
- if (keepmuted && hardmute && dev->muted)
+ if (keepmuted && hardmute && gt->muted)
return;
- if (freq < GEMTEK_LOWFREQ)
- freq = GEMTEK_LOWFREQ;
- else if (freq > GEMTEK_HIGHFREQ)
- freq = GEMTEK_HIGHFREQ;
+ freq = clamp_val(freq, GEMTEK_LOWFREQ, GEMTEK_HIGHFREQ);
- dev->lastfreq = freq;
- dev->muted = 0;
+ gt->lastfreq = freq;
+ gt->muted = 0;
- gemtek_bu2614_set(dev, BU2614_PORT, 0);
- gemtek_bu2614_set(dev, BU2614_FMES, 0);
- gemtek_bu2614_set(dev, BU2614_SWIN, 0); /* FM-mode */
- gemtek_bu2614_set(dev, BU2614_SWAL, 0);
- gemtek_bu2614_set(dev, BU2614_FMUN, 1); /* GT bit set */
- gemtek_bu2614_set(dev, BU2614_TEST, 0);
+ gemtek_bu2614_set(gt, BU2614_PORT, 0);
+ gemtek_bu2614_set(gt, BU2614_FMES, 0);
+ gemtek_bu2614_set(gt, BU2614_SWIN, 0); /* FM-mode */
+ gemtek_bu2614_set(gt, BU2614_SWAL, 0);
+ gemtek_bu2614_set(gt, BU2614_FMUN, 1); /* GT bit set */
+ gemtek_bu2614_set(gt, BU2614_TEST, 0);
- gemtek_bu2614_set(dev, BU2614_STDF, GEMTEK_STDF_3_125_KHZ);
- gemtek_bu2614_set(dev, BU2614_FREQ, gemtek_convfreq(freq));
+ gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_STDF_3_125_KHZ);
+ gemtek_bu2614_set(gt, BU2614_FREQ, gemtek_convfreq(freq));
- gemtek_bu2614_transmit(dev);
+ gemtek_bu2614_transmit(gt);
}
/*
* Set mute flag.
*/
-static void gemtek_mute(struct gemtek_device *dev)
+static void gemtek_mute(struct gemtek *gt)
{
int i;
- dev->muted = 1;
+
+ gt->muted = 1;
if (hardmute) {
/* Turn off PLL, disable data output */
- gemtek_bu2614_set(dev, BU2614_PORT, 0);
- gemtek_bu2614_set(dev, BU2614_FMES, 0); /* CT bit off */
- gemtek_bu2614_set(dev, BU2614_SWIN, 0); /* FM-mode */
- gemtek_bu2614_set(dev, BU2614_SWAL, 0);
- gemtek_bu2614_set(dev, BU2614_FMUN, 0); /* GT bit off */
- gemtek_bu2614_set(dev, BU2614_TEST, 0);
- gemtek_bu2614_set(dev, BU2614_STDF, GEMTEK_PLL_OFF);
- gemtek_bu2614_set(dev, BU2614_FREQ, 0);
- gemtek_bu2614_transmit(dev);
- } else {
- spin_lock(&lock);
+ gemtek_bu2614_set(gt, BU2614_PORT, 0);
+ gemtek_bu2614_set(gt, BU2614_FMES, 0); /* CT bit off */
+ gemtek_bu2614_set(gt, BU2614_SWIN, 0); /* FM-mode */
+ gemtek_bu2614_set(gt, BU2614_SWAL, 0);
+ gemtek_bu2614_set(gt, BU2614_FMUN, 0); /* GT bit off */
+ gemtek_bu2614_set(gt, BU2614_TEST, 0);
+ gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_PLL_OFF);
+ gemtek_bu2614_set(gt, BU2614_FREQ, 0);
+ gemtek_bu2614_transmit(gt);
+ return;
+ }
- /* Read bus contents (CE, CK and DA). */
- i = inb_p(io);
- /* Write it back with mute flag set. */
- outb_p((i >> 5) | GEMTEK_MT, io);
- udelay(SHORT_DELAY);
+ mutex_lock(&gt->lock);
- spin_unlock(&lock);
- }
+ /* Read bus contents (CE, CK and DA). */
+ i = inb_p(gt->io);
+ /* Write it back with mute flag set. */
+ outb_p((i >> 5) | GEMTEK_MT, gt->io);
+ udelay(SHORT_DELAY);
+
+ mutex_unlock(&gt->lock);
}
/*
* Unset mute flag.
*/
-static void gemtek_unmute(struct gemtek_device *dev)
+static void gemtek_unmute(struct gemtek *gt)
{
int i;
- dev->muted = 0;
+ gt->muted = 0;
if (hardmute) {
/* Turn PLL back on. */
- gemtek_setfreq(dev, dev->lastfreq);
- } else {
- spin_lock(&lock);
+ gemtek_setfreq(gt, gt->lastfreq);
+ return;
+ }
+ mutex_lock(&gt->lock);
- i = inb_p(io);
- outb_p(i >> 5, io);
- udelay(SHORT_DELAY);
+ i = inb_p(gt->io);
+ outb_p(i >> 5, gt->io);
+ udelay(SHORT_DELAY);
- spin_unlock(&lock);
- }
+ mutex_unlock(&gt->lock);
}
/*
* Get signal strength (= stereo status).
*/
-static inline int gemtek_getsigstr(void)
+static inline int gemtek_getsigstr(struct gemtek *gt)
{
- return inb_p(io) & GEMTEK_NS ? 0 : 1;
+ int sig;
+
+ mutex_lock(&gt->lock);
+ sig = inb_p(gt->io) & GEMTEK_NS ? 0 : 1;
+ mutex_unlock(&gt->lock);
+ return sig;
}
/*
* Check if requested card acts like GemTek Radio card.
*/
-static int gemtek_verify(int port)
+static int gemtek_verify(struct gemtek *gt, int port)
{
- static int verified = -1;
int i, q;
- if (verified == port)
+ if (gt->verified == port)
return 1;
- spin_lock(&lock);
+ mutex_lock(&gt->lock);
q = inb_p(port); /* Read bus contents before probing. */
/* Try to turn on CE, CK and DA respectively and check if card responds
@@ -316,15 +318,15 @@ static int gemtek_verify(int port)
udelay(SHORT_DELAY);
if ((inb_p(port) & (~GEMTEK_NS)) != (0x17 | (1 << (i + 5)))) {
- spin_unlock(&lock);
+ mutex_unlock(&gt->lock);
return 0;
}
}
outb_p(q >> 5, port); /* Write bus contents back. */
udelay(SHORT_DELAY);
- spin_unlock(&lock);
- verified = port;
+ mutex_unlock(&gt->lock);
+ gt->verified = port;
return 1;
}
@@ -332,83 +334,61 @@ static int gemtek_verify(int port)
/*
* Automatic probing for card.
*/
-static int gemtek_probe(void)
+static int gemtek_probe(struct gemtek *gt)
{
+ struct v4l2_device *v4l2_dev = &gt->v4l2_dev;
int ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c };
int i;
if (!probe) {
- printk(KERN_INFO "Automatic device probing disabled.\n");
+ v4l2_info(v4l2_dev, "Automatic device probing disabled.\n");
return -1;
}
- printk(KERN_INFO "Automatic device probing enabled.\n");
+ v4l2_info(v4l2_dev, "Automatic device probing enabled.\n");
for (i = 0; i < ARRAY_SIZE(ioports); ++i) {
- printk(KERN_INFO "Trying I/O port 0x%x...\n", ioports[i]);
+ v4l2_info(v4l2_dev, "Trying I/O port 0x%x...\n", ioports[i]);
if (!request_region(ioports[i], 1, "gemtek-probe")) {
- printk(KERN_WARNING "I/O port 0x%x busy!\n",
+ v4l2_warn(v4l2_dev, "I/O port 0x%x busy!\n",
ioports[i]);
continue;
}
- if (gemtek_verify(ioports[i])) {
- printk(KERN_INFO "Card found from I/O port "
+ if (gemtek_verify(gt, ioports[i])) {
+ v4l2_info(v4l2_dev, "Card found from I/O port "
"0x%x!\n", ioports[i]);
release_region(ioports[i], 1);
-
- io = ioports[i];
- return io;
+ gt->io = ioports[i];
+ return gt->io;
}
release_region(ioports[i], 1);
}
- printk(KERN_ERR "Automatic probing failed!\n");
-
+ v4l2_err(v4l2_dev, "Automatic probing failed!\n");
return -1;
}
/*
* Video 4 Linux stuff.
*/
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- }, {
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 65535,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
-
-static int gemtek_exclusive_open(struct file *file)
+static int gemtek_open(struct file *file)
{
- return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
+ return 0;
}
-static int gemtek_exclusive_release(struct file *file)
+static int gemtek_release(struct file *file)
{
- clear_bit(0, &in_use);
return 0;
}
static const struct v4l2_file_operations gemtek_fops = {
.owner = THIS_MODULE,
- .open = gemtek_exclusive_open,
- .release = gemtek_exclusive_release,
+ .open = gemtek_open,
+ .release = gemtek_release,
.ioctl = video_ioctl2,
};
@@ -417,23 +397,25 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-gemtek", sizeof(v->driver));
strlcpy(v->card, "GemTek", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
{
+ struct gemtek *gt = video_drvdata(file);
+
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
v->rangelow = GEMTEK_LOWFREQ;
v->rangehigh = GEMTEK_HIGHFREQ;
v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
- v->signal = 0xffff * gemtek_getsigstr();
+ v->signal = 0xffff * gemtek_getsigstr(gt);
if (v->signal) {
v->audmode = V4L2_TUNER_MODE_STEREO;
v->rxsubchans = V4L2_TUNER_SUB_STEREO;
@@ -441,65 +423,56 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
v->audmode = V4L2_TUNER_MODE_MONO;
v->rxsubchans = V4L2_TUNER_SUB_MONO;
}
-
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return (v->index != 0) ? -EINVAL : 0;
}
-static int vidioc_s_frequency(struct file *file, void *priv,
+static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct gemtek_device *rt = video_drvdata(file);
-
- gemtek_setfreq(rt, f->frequency);
+ struct gemtek *gt = video_drvdata(file);
+ if (f->tuner != 0)
+ return -EINVAL;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = gt->lastfreq;
return 0;
}
-static int vidioc_g_frequency(struct file *file, void *priv,
+static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct gemtek_device *rt = video_drvdata(file);
+ struct gemtek *gt = video_drvdata(file);
- f->type = V4L2_TUNER_RADIO;
- f->frequency = rt->lastfreq;
+ if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+ return -EINVAL;
+ gemtek_setfreq(gt, f->frequency);
return 0;
}
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); ++i) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+ default:
+ return -EINVAL;
}
- return -EINVAL;
}
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct gemtek_device *rt = video_drvdata(file);
+ struct gemtek *gt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- ctrl->value = rt->muted;
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- if (rt->muted)
- ctrl->value = 0;
- else
- ctrl->value = 65535;
+ ctrl->value = gt->muted;
return 0;
}
return -EINVAL;
@@ -508,35 +481,19 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct gemtek_device *rt = video_drvdata(file);
+ struct gemtek *gt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value)
- gemtek_mute(rt);
- else
- gemtek_unmute(rt);
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- if (ctrl->value)
- gemtek_unmute(rt);
+ gemtek_mute(gt);
else
- gemtek_mute(rt);
+ gemtek_unmute(gt);
return 0;
}
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -545,16 +502,20 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
+ return (i != 0) ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
- return 0;
+ return (a->index != 0) ? -EINVAL : 0;
}
static const struct v4l2_ioctl_ops gemtek_ioctl_ops = {
@@ -572,62 +533,73 @@ static const struct v4l2_ioctl_ops gemtek_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl
};
-static struct video_device gemtek_radio = {
- .name = "GemTek Radio card",
- .fops = &gemtek_fops,
- .ioctl_ops = &gemtek_ioctl_ops,
- .release = video_device_release_empty,
-};
-
/*
* Initialization / cleanup related stuff.
*/
-/*
- * Initilize card.
- */
static int __init gemtek_init(void)
{
- printk(KERN_INFO RADIO_BANNER "\n");
+ struct gemtek *gt = &gemtek_card;
+ struct v4l2_device *v4l2_dev = &gt->v4l2_dev;
+ int res;
- spin_lock_init(&lock);
+ strlcpy(v4l2_dev->name, "gemtek", sizeof(v4l2_dev->name));
- gemtek_probe();
- if (io) {
- if (!request_region(io, 1, "gemtek")) {
- printk(KERN_ERR "I/O port 0x%x already in use.\n", io);
+ v4l2_info(v4l2_dev, "GemTek Radio card driver: v0.0.3\n");
+
+ mutex_init(&gt->lock);
+
+ gt->verified = -1;
+ gt->io = io;
+ gemtek_probe(gt);
+ if (gt->io) {
+ if (!request_region(gt->io, 1, "gemtek")) {
+ v4l2_err(v4l2_dev, "I/O port 0x%x already in use.\n", gt->io);
return -EBUSY;
}
- if (!gemtek_verify(io))
- printk(KERN_WARNING "Card at I/O port 0x%x does not "
+ if (!gemtek_verify(gt, gt->io))
+ v4l2_warn(v4l2_dev, "Card at I/O port 0x%x does not "
"respond properly, check your "
- "configuration.\n", io);
+ "configuration.\n", gt->io);
else
- printk(KERN_INFO "Using I/O port 0x%x.\n", io);
+ v4l2_info(v4l2_dev, "Using I/O port 0x%x.\n", gt->io);
} else if (probe) {
- printk(KERN_ERR "Automatic probing failed and no "
+ v4l2_err(v4l2_dev, "Automatic probing failed and no "
"fixed I/O port defined.\n");
return -ENODEV;
} else {
- printk(KERN_ERR "Automatic probing disabled but no fixed "
+ v4l2_err(v4l2_dev, "Automatic probing disabled but no fixed "
"I/O port defined.");
return -EINVAL;
}
- video_set_drvdata(&gemtek_radio, &gemtek_unit);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ release_region(gt->io, 1);
+ return res;
+ }
- if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 1);
+ strlcpy(gt->vdev.name, v4l2_dev->name, sizeof(gt->vdev.name));
+ gt->vdev.v4l2_dev = v4l2_dev;
+ gt->vdev.fops = &gemtek_fops;
+ gt->vdev.ioctl_ops = &gemtek_ioctl_ops;
+ gt->vdev.release = video_device_release_empty;
+ video_set_drvdata(&gt->vdev, gt);
+
+ if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(gt->io, 1);
return -EBUSY;
}
/* Set defaults */
- gemtek_unit.lastfreq = GEMTEK_LOWFREQ;
- gemtek_unit.bu2614data = 0;
+ gt->lastfreq = GEMTEK_LOWFREQ;
+ gt->bu2614data = 0;
if (initmute)
- gemtek_mute(&gemtek_unit);
+ gemtek_mute(gt);
return 0;
}
@@ -637,15 +609,19 @@ static int __init gemtek_init(void)
*/
static void __exit gemtek_exit(void)
{
+ struct gemtek *gt = &gemtek_card;
+ struct v4l2_device *v4l2_dev = &gt->v4l2_dev;
+
if (shutdown) {
hardmute = 1; /* Turn off PLL */
- gemtek_mute(&gemtek_unit);
+ gemtek_mute(gt);
} else {
- printk(KERN_INFO "Module unloaded but card not muted!\n");
+ v4l2_info(v4l2_dev, "Module unloaded but card not muted!\n");
}
- video_unregister_device(&gemtek_radio);
- release_region(io, 1);
+ video_unregister_device(&gt->vdev);
+ v4l2_device_unregister(&gt->v4l2_dev);
+ release_region(gt->io, 1);
}
module_init(gemtek_init);
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index ba3a13a90013..01a6d22950ad 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -22,27 +22,22 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#include <linux/pci.h>
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <linux/io.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,6)
-#define DRIVER_VERSION "0.06"
+MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
+MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
+MODULE_LICENSE("GPL");
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- }
-};
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 6)
+#define DRIVER_VERSION "0.06"
#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */
@@ -72,62 +67,27 @@ static struct v4l2_queryctrl radio_qctrl[] = {
#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF)
-static int radio_nr = -1;
-module_param(radio_nr, int, 0);
+struct maestro {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ struct pci_dev *pdev;
+ struct mutex lock;
-static unsigned long in_use;
-
-static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+ u16 io; /* base of Maestro card radio io (GPIO_DATA)*/
+ u16 muted; /* VIDEO_AUDIO_MUTE */
+ u16 stereo; /* VIDEO_TUNER_STEREO_ON */
+ u16 tuned; /* signal strength (0 or 0xffff) */
+};
-static int maestro_exclusive_open(struct file *file)
+static inline struct maestro *to_maestro(struct v4l2_device *v4l2_dev)
{
- return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
+ return container_of(v4l2_dev, struct maestro, v4l2_dev);
}
-static int maestro_exclusive_release(struct file *file)
+static u32 radio_bits_get(struct maestro *dev)
{
- clear_bit(0, &in_use);
- return 0;
-}
-
-static void maestro_remove(struct pci_dev *pdev);
-
-static struct pci_device_id maestro_r_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
- .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
- .class_mask = 0xffff00 },
- { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
- .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
- .class_mask = 0xffff00 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
-
-static struct pci_driver maestro_r_driver = {
- .name = "maestro_radio",
- .id_table = maestro_r_pci_tbl,
- .probe = maestro_probe,
- .remove = __devexit_p(maestro_remove),
-};
-
-static const struct v4l2_file_operations maestro_fops = {
- .owner = THIS_MODULE,
- .open = maestro_exclusive_open,
- .release = maestro_exclusive_release,
- .ioctl = video_ioctl2,
-};
-
-struct radio_device {
- u16 io, /* base of Maestro card radio io (GPIO_DATA)*/
- muted, /* VIDEO_AUDIO_MUTE */
- stereo, /* VIDEO_TUNER_STEREO_ON */
- tuned; /* signal strength (0 or 0xffff) */
-};
-
-static u32 radio_bits_get(struct radio_device *dev)
-{
- register u16 io=dev->io, l, rdata;
- register u32 data=0;
+ u16 io = dev->io, l, rdata;
+ u32 data = 0;
u16 omask;
omask = inw(io + IO_MASK);
@@ -135,25 +95,23 @@ static u32 radio_bits_get(struct radio_device *dev)
outw(0, io);
udelay(16);
- for (l=24;l--;) {
+ for (l = 24; l--;) {
outw(STR_CLK, io); /* HI state */
udelay(2);
- if(!l)
+ if (!l)
dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff;
outw(0, io); /* LO state */
udelay(2);
data <<= 1; /* shift data */
rdata = inw(io);
- if(!l)
- dev->stereo = rdata & STR_MOST ?
- 0 : 1;
- else
- if(rdata & STR_DATA)
- data++;
+ if (!l)
+ dev->stereo = (rdata & STR_MOST) ? 0 : 1;
+ else if (rdata & STR_DATA)
+ data++;
udelay(2);
}
- if(dev->muted)
+ if (dev->muted)
outw(STR_WREN, io);
udelay(4);
@@ -162,18 +120,18 @@ static u32 radio_bits_get(struct radio_device *dev)
return data & 0x3ffe;
}
-static void radio_bits_set(struct radio_device *dev, u32 data)
+static void radio_bits_set(struct maestro *dev, u32 data)
{
- register u16 io=dev->io, l, bits;
+ u16 io = dev->io, l, bits;
u16 omask, odir;
omask = inw(io + IO_MASK);
- odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
+ odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
outw(odir | STR_DATA, io + IO_DIR);
outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
udelay(16);
- for (l=25;l;l--) {
- bits = ((data >> 18) & STR_DATA) | STR_WREN ;
+ for (l = 25; l; l--) {
+ bits = ((data >> 18) & STR_DATA) | STR_WREN;
data <<= 1; /* shift data */
outw(bits, io); /* start strobe */
udelay(2);
@@ -183,7 +141,7 @@ static void radio_bits_set(struct radio_device *dev, u32 data)
udelay(4);
}
- if(!dev->muted)
+ if (!dev->muted)
outw(0, io);
udelay(4);
@@ -195,78 +153,79 @@ static void radio_bits_set(struct radio_device *dev, u32 data)
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
+ struct maestro *dev = video_drvdata(file);
+
strlcpy(v->driver, "radio-maestro", sizeof(v->driver));
strlcpy(v->card, "Maestro Radio", sizeof(v->card));
- sprintf(v->bus_info, "PCI");
+ snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct radio_device *card = video_drvdata(file);
+ struct maestro *dev = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- (void)radio_bits_get(card);
+ mutex_lock(&dev->lock);
+ radio_bits_get(dev);
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
v->rangelow = FREQ_LO;
v->rangehigh = FREQ_HI;
- v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
v->capability = V4L2_TUNER_CAP_LOW;
- if(card->stereo)
+ if (dev->stereo)
v->audmode = V4L2_TUNER_MODE_STEREO;
else
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = card->tuned;
+ v->signal = dev->tuned;
+ mutex_unlock(&dev->lock);
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct radio_device *card = video_drvdata(file);
+ struct maestro *dev = video_drvdata(file);
if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
return -EINVAL;
- radio_bits_set(card, FREQ2BITS(f->frequency));
+ mutex_lock(&dev->lock);
+ radio_bits_set(dev, FREQ2BITS(f->frequency));
+ mutex_unlock(&dev->lock);
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct radio_device *card = video_drvdata(file);
+ struct maestro *dev = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
- f->frequency = BITS2FREQ(radio_bits_get(card));
+ mutex_lock(&dev->lock);
+ f->frequency = BITS2FREQ(radio_bits_get(dev));
+ mutex_unlock(&dev->lock);
return 0;
}
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
}
return -EINVAL;
}
@@ -274,11 +233,11 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct radio_device *card = video_drvdata(file);
+ struct maestro *dev = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- ctrl->value = card->muted;
+ ctrl->value = dev->muted;
return 0;
}
return -EINVAL;
@@ -287,56 +246,85 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct radio_device *card = video_drvdata(file);
- register u16 io = card->io;
- register u16 omask = inw(io + IO_MASK);
+ struct maestro *dev = video_drvdata(file);
+ u16 io = dev->io;
+ u16 omask;
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
+ mutex_lock(&dev->lock);
+ omask = inw(io + IO_MASK);
outw(~STR_WREN, io + IO_MASK);
- outw((card->muted = ctrl->value ) ?
- STR_WREN : 0, io);
+ dev->muted = ctrl->value;
+ outw(dev->muted ? STR_WREN : 0, io);
udelay(4);
outw(omask, io + IO_MASK);
msleep(125);
+ mutex_unlock(&dev->lock);
return 0;
}
return -EINVAL;
}
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ return i ? -EINVAL : 0;
+}
+
static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- *i = 0;
- return 0;
+ return a->index ? -EINVAL : 0;
}
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+static int maestro_open(struct file *file)
{
- if (i != 0)
- return -EINVAL;
return 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
+static int maestro_release(struct file *file)
{
- if (a->index != 0)
- return -EINVAL;
return 0;
}
-static u16 __devinit radio_power_on(struct radio_device *dev)
+static const struct v4l2_file_operations maestro_fops = {
+ .owner = THIS_MODULE,
+ .open = maestro_open,
+ .release = maestro_release,
+ .ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+};
+
+static u16 __devinit radio_power_on(struct maestro *dev)
{
register u16 io = dev->io;
register u32 ofreq;
@@ -360,33 +348,11 @@ static u16 __devinit radio_power_on(struct radio_device *dev)
return (ofreq == radio_bits_get(dev));
}
-static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
-};
-
-static struct video_device maestro_radio = {
- .name = "Maestro radio",
- .fops = &maestro_fops,
- .ioctl_ops = &maestro_ioctl_ops,
- .release = video_device_release,
-};
-
static int __devinit maestro_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- struct radio_device *radio_unit;
- struct video_device *maestro_radio_inst;
+ struct maestro *dev;
+ struct v4l2_device *v4l2_dev;
int retval;
retval = pci_enable_device(pdev);
@@ -397,46 +363,53 @@ static int __devinit maestro_probe(struct pci_dev *pdev,
retval = -ENOMEM;
- radio_unit = kzalloc(sizeof(*radio_unit), GFP_KERNEL);
- if (radio_unit == NULL) {
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (dev == NULL) {
dev_err(&pdev->dev, "not enough memory\n");
goto err;
}
- radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA;
+ v4l2_dev = &dev->v4l2_dev;
+ mutex_init(&dev->lock);
+ dev->pdev = pdev;
- maestro_radio_inst = video_device_alloc();
- if (maestro_radio_inst == NULL) {
- dev_err(&pdev->dev, "not enough memory\n");
+ strlcpy(v4l2_dev->name, "maestro", sizeof(v4l2_dev->name));
+
+ retval = v4l2_device_register(&pdev->dev, v4l2_dev);
+ if (retval < 0) {
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
goto errfr;
}
- memcpy(maestro_radio_inst, &maestro_radio, sizeof(maestro_radio));
- video_set_drvdata(maestro_radio_inst, radio_unit);
- pci_set_drvdata(pdev, maestro_radio_inst);
+ dev->io = pci_resource_start(pdev, 0) + GPIO_DATA;
- retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO, radio_nr);
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &maestro_fops;
+ dev->vdev.ioctl_ops = &maestro_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
+
+ retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
if (retval) {
- printk(KERN_ERR "can't register video device!\n");
+ v4l2_err(v4l2_dev, "can't register video device!\n");
goto errfr1;
}
- if (!radio_power_on(radio_unit)) {
+ if (!radio_power_on(dev)) {
retval = -EIO;
goto errunr;
}
- dev_info(&pdev->dev, "version " DRIVER_VERSION " time " __TIME__ " "
- __DATE__ "\n");
- dev_info(&pdev->dev, "radio chip initialized\n");
+ v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
return 0;
errunr:
- video_unregister_device(maestro_radio_inst);
+ video_unregister_device(&dev->vdev);
errfr1:
- video_device_release(maestro_radio_inst);
+ v4l2_device_unregister(v4l2_dev);
errfr:
- kfree(radio_unit);
+ kfree(dev);
err:
return retval;
@@ -444,11 +417,31 @@ err:
static void __devexit maestro_remove(struct pci_dev *pdev)
{
- struct video_device *vdev = pci_get_drvdata(pdev);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct maestro *dev = to_maestro(v4l2_dev);
- video_unregister_device(vdev);
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
}
+static struct pci_device_id maestro_r_pci_tbl[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
+ .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
+ .class_mask = 0xffff00 },
+ { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
+ .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
+ .class_mask = 0xffff00 },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
+
+static struct pci_driver maestro_r_driver = {
+ .name = "maestro_radio",
+ .id_table = maestro_r_pci_tbl,
+ .probe = maestro_probe,
+ .remove = __devexit_p(maestro_remove),
+};
+
static int __init maestro_radio_init(void)
{
int retval = pci_register_driver(&maestro_r_driver);
@@ -466,7 +459,3 @@ static void __exit maestro_radio_exit(void)
module_init(maestro_radio_init);
module_exit(maestro_radio_exit);
-
-MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
-MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index c5dc00aa9c9f..2606f0b30355 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -37,38 +37,32 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
#include <linux/mutex.h>
-
#include <linux/pci.h>
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
+MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net");
+MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio.");
+MODULE_LICENSE("GPL");
+
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+
+static int debug;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
+
#define DRIVER_VERSION "0.77"
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,7,7)
-
-static struct video_device maxiradio_radio;
-
-#define dprintk(num, fmt, arg...) \
- do { \
- if (maxiradio_radio.debug >= num) \
- printk(KERN_DEBUG "%s: " fmt, \
- maxiradio_radio.name, ## arg); } while (0)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- }
-};
+#define RADIO_VERSION KERNEL_VERSION(0, 7, 7)
+
+#define dprintk(dev, num, fmt, arg...) \
+ v4l2_dbg(num, debug, &dev->v4l2_dev, fmt, ## arg)
#ifndef PCI_VENDOR_ID_GUILLEMOT
#define PCI_VENDOR_ID_GUILLEMOT 0x5046
@@ -80,90 +74,70 @@ static struct v4l2_queryctrl radio_qctrl[] = {
/* TEA5757 pin mappings */
-static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16 ;
-
-static int radio_nr = -1;
-module_param(radio_nr, int, 0);
+static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16;
-static unsigned long in_use;
-
-#define FREQ_LO 50*16000
-#define FREQ_HI 150*16000
+#define FREQ_LO (50 * 16000)
+#define FREQ_HI (150 * 16000)
#define FREQ_IF 171200 /* 10.7*16000 */
#define FREQ_STEP 200 /* 12.5*16 */
/* (x==fmhz*16*1000) -> bits */
-#define FREQ2BITS(x) ((( (unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1)) \
- /(FREQ_STEP<<2))<<2)
+#define FREQ2BITS(x) \
+ ((((unsigned int)(x) + FREQ_IF + (FREQ_STEP << 1)) / (FREQ_STEP << 2)) << 2)
#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF)
-static int maxiradio_exclusive_open(struct file *file)
+struct maxiradio
{
- return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
-}
-
-static int maxiradio_exclusive_release(struct file *file)
-{
- clear_bit(0, &in_use);
- return 0;
-}
-
-static const struct v4l2_file_operations maxiradio_fops = {
- .owner = THIS_MODULE,
- .open = maxiradio_exclusive_open,
- .release = maxiradio_exclusive_release,
- .ioctl = video_ioctl2,
-};
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ struct pci_dev *pdev;
-static struct radio_device
-{
- __u16 io, /* base of radio io */
- muted, /* VIDEO_AUDIO_MUTE */
- stereo, /* VIDEO_TUNER_STEREO_ON */
- tuned; /* signal strength (0 or 0xffff) */
+ u16 io; /* base of radio io */
+ u16 muted; /* VIDEO_AUDIO_MUTE */
+ u16 stereo; /* VIDEO_TUNER_STEREO_ON */
+ u16 tuned; /* signal strength (0 or 0xffff) */
unsigned long freq;
struct mutex lock;
-} radio_unit = {
- .muted =1,
- .freq = FREQ_LO,
};
-static void outbit(unsigned long bit, __u16 io)
+static inline struct maxiradio *to_maxiradio(struct v4l2_device *v4l2_dev)
{
- if (bit != 0)
- {
- outb( power|wren|data ,io); udelay(4);
- outb( power|wren|data|clk ,io); udelay(4);
- outb( power|wren|data ,io); udelay(4);
- }
- else
- {
- outb( power|wren ,io); udelay(4);
- outb( power|wren|clk ,io); udelay(4);
- outb( power|wren ,io); udelay(4);
- }
+ return container_of(v4l2_dev, struct maxiradio, v4l2_dev);
}
-static void turn_power(__u16 io, int p)
+static void outbit(unsigned long bit, u16 io)
+{
+ int val = power | wren | (bit ? data : 0);
+
+ outb(val, io);
+ udelay(4);
+ outb(val | clk, io);
+ udelay(4);
+ outb(val, io);
+ udelay(4);
+}
+
+static void turn_power(struct maxiradio *dev, int p)
{
if (p != 0) {
- dprintk(1, "Radio powered on\n");
- outb(power, io);
+ dprintk(dev, 1, "Radio powered on\n");
+ outb(power, dev->io);
} else {
- dprintk(1, "Radio powered off\n");
- outb(0,io);
+ dprintk(dev, 1, "Radio powered off\n");
+ outb(0, dev->io);
}
}
-static void set_freq(__u16 io, __u32 freq)
+static void set_freq(struct maxiradio *dev, u32 freq)
{
unsigned long int si;
int bl;
+ int io = dev->io;
int val = FREQ2BITS(freq);
/* TEA5757 shift register bits (see pdf) */
@@ -188,14 +162,14 @@ static void set_freq(__u16 io, __u32 freq)
si >>= 1;
}
- dprintk(1, "Radio freq set to %d.%02d MHz\n",
+ dprintk(dev, 1, "Radio freq set to %d.%02d MHz\n",
freq / 16000,
freq % 16000 * 100 / 16000);
- turn_power(io, 1);
+ turn_power(dev, 1);
}
-static int get_stereo(__u16 io)
+static int get_stereo(u16 io)
{
outb(power,io);
udelay(4);
@@ -203,7 +177,7 @@ static int get_stereo(__u16 io)
return !(inb(io) & mo_st);
}
-static int get_tune(__u16 io)
+static int get_tune(u16 io)
{
outb(power+clk,io);
udelay(4);
@@ -212,95 +186,84 @@ static int get_tune(__u16 io)
}
-static int vidioc_querycap (struct file *file, void *priv,
+static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
- strlcpy(v->driver, "radio-maxiradio", sizeof (v->driver));
- strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ struct maxiradio *dev = video_drvdata(file);
+ strlcpy(v->driver, "radio-maxiradio", sizeof(v->driver));
+ strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof(v->card));
+ snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev));
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
-static int vidioc_g_tuner (struct file *file, void *priv,
+static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct radio_device *card = video_drvdata(file);
+ struct maxiradio *dev = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
+ mutex_lock(&dev->lock);
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
-
- v->rangelow=FREQ_LO;
- v->rangehigh=FREQ_HI;
- v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
- v->capability=V4L2_TUNER_CAP_LOW;
- if(get_stereo(card->io))
+ v->rangelow = FREQ_LO;
+ v->rangehigh = FREQ_HI;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ if (get_stereo(dev->io))
v->audmode = V4L2_TUNER_MODE_STEREO;
else
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xffff*get_tune(card->io);
+ v->signal = 0xffff * get_tune(dev->io);
+ mutex_unlock(&dev->lock);
return 0;
}
-static int vidioc_s_tuner (struct file *file, void *priv,
+static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
-
- return 0;
-}
-
-static int vidioc_g_audio (struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "FM");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
-
return 0;
}
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
+ return i ? -EINVAL : 0;
+}
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static int vidioc_s_audio (struct file *file, void *priv,
+static int vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
-
- return 0;
+ return a->index ? -EINVAL : 0;
}
-static int vidioc_s_frequency (struct file *file, void *priv,
+static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct radio_device *card = video_drvdata(file);
+ struct maxiradio *dev = video_drvdata(file);
if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) {
- dprintk(1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n",
+ dprintk(dev, 1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n",
f->frequency / 16000,
f->frequency % 16000 * 100 / 16000,
FREQ_LO / 16000, FREQ_HI / 16000);
@@ -308,75 +271,91 @@ static int vidioc_s_frequency (struct file *file, void *priv,
return -EINVAL;
}
- card->freq = f->frequency;
- set_freq(card->io, card->freq);
+ mutex_lock(&dev->lock);
+ dev->freq = f->frequency;
+ set_freq(dev, dev->freq);
msleep(125);
+ mutex_unlock(&dev->lock);
return 0;
}
-static int vidioc_g_frequency (struct file *file, void *priv,
+static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct radio_device *card = video_drvdata(file);
+ struct maxiradio *dev = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
- f->frequency = card->freq;
+ f->frequency = dev->freq;
- dprintk(4, "radio freq is %d.%02d MHz",
+ dprintk(dev, 4, "radio freq is %d.%02d MHz",
f->frequency / 16000,
f->frequency % 16000 * 100 / 16000);
return 0;
}
-static int vidioc_queryctrl (struct file *file, void *priv,
+static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
- return (0);
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
}
-
return -EINVAL;
}
-static int vidioc_g_ctrl (struct file *file, void *priv,
- struct v4l2_control *ctrl)
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
{
- struct radio_device *card = video_drvdata(file);
+ struct maxiradio *dev = video_drvdata(file);
switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=card->muted;
- return (0);
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = dev->muted;
+ return 0;
}
return -EINVAL;
}
-static int vidioc_s_ctrl (struct file *file, void *priv,
- struct v4l2_control *ctrl)
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
{
- struct radio_device *card = video_drvdata(file);
+ struct maxiradio *dev = video_drvdata(file);
switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- card->muted = ctrl->value;
- if(card->muted)
- turn_power(card->io, 0);
- else
- set_freq(card->io, card->freq);
- return 0;
+ case V4L2_CID_AUDIO_MUTE:
+ mutex_lock(&dev->lock);
+ dev->muted = ctrl->value;
+ if (dev->muted)
+ turn_power(dev, 0);
+ else
+ set_freq(dev, dev->freq);
+ mutex_unlock(&dev->lock);
+ return 0;
}
return -EINVAL;
}
+static int maxiradio_open(struct file *file)
+{
+ return 0;
+}
+
+static int maxiradio_release(struct file *file)
+{
+ return 0;
+}
+
+static const struct v4l2_file_operations maxiradio_fops = {
+ .owner = THIS_MODULE,
+ .open = maxiradio_open,
+ .release = maxiradio_release,
+ .ioctl = video_ioctl2,
+};
+
static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
@@ -392,60 +371,84 @@ static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device maxiradio_radio = {
- .name = "Maxi Radio FM2000 radio",
- .fops = &maxiradio_fops,
- .ioctl_ops = &maxiradio_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- if(!request_region(pci_resource_start(pdev, 0),
+ struct maxiradio *dev;
+ struct v4l2_device *v4l2_dev;
+ int retval = -ENOMEM;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (dev == NULL) {
+ dev_err(&pdev->dev, "not enough memory\n");
+ return -ENOMEM;
+ }
+
+ v4l2_dev = &dev->v4l2_dev;
+ mutex_init(&dev->lock);
+ dev->pdev = pdev;
+ dev->muted = 1;
+ dev->freq = FREQ_LO;
+
+ strlcpy(v4l2_dev->name, "maxiradio", sizeof(v4l2_dev->name));
+
+ retval = v4l2_device_register(&pdev->dev, v4l2_dev);
+ if (retval < 0) {
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ goto errfr;
+ }
+
+ if (!request_region(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) {
- printk(KERN_ERR "radio-maxiradio: can't reserve I/O ports\n");
+ v4l2_err(v4l2_dev, "can't reserve I/O ports\n");
goto err_out;
}
if (pci_enable_device(pdev))
goto err_out_free_region;
- radio_unit.io = pci_resource_start(pdev, 0);
- mutex_init(&radio_unit.lock);
- video_set_drvdata(&maxiradio_radio, &radio_unit);
+ dev->io = pci_resource_start(pdev, 0);
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &maxiradio_fops;
+ dev->vdev.ioctl_ops = &maxiradio_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
- if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- printk("radio-maxiradio: can't register device!");
+ if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_err(v4l2_dev, "can't register device!");
goto err_out_free_region;
}
- printk(KERN_INFO "radio-maxiradio: version "
- DRIVER_VERSION
- " time "
- __TIME__ " "
- __DATE__
- "\n");
+ v4l2_info(v4l2_dev, "version " DRIVER_VERSION
+ " time " __TIME__ " " __DATE__ "\n");
- printk(KERN_INFO "radio-maxiradio: found Guillemot MAXI Radio device (io = 0x%x)\n",
- radio_unit.io);
+ v4l2_info(v4l2_dev, "found Guillemot MAXI Radio device (io = 0x%x)\n",
+ dev->io);
return 0;
err_out_free_region:
release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
err_out:
+ v4l2_device_unregister(v4l2_dev);
+errfr:
+ kfree(dev);
return -ENODEV;
}
static void __devexit maxiradio_remove_one(struct pci_dev *pdev)
{
- video_unregister_device(&maxiradio_radio);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct maxiradio *dev = to_maxiradio(v4l2_dev);
+
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
}
static struct pci_device_id maxiradio_pci_tbl[] = {
{ PCI_VENDOR_ID_GUILLEMOT, PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO,
PCI_ANY_ID, PCI_ANY_ID, },
- { 0,}
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, maxiradio_pci_tbl);
@@ -469,10 +472,3 @@ static void __exit maxiradio_radio_exit(void)
module_init(maxiradio_radio_init);
module_exit(maxiradio_radio_exit);
-
-MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net");
-MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio.");
-MODULE_LICENSE("GPL");
-
-module_param_named(debug,maxiradio_radio.debug, int, 0644);
-MODULE_PARM_DESC(debug,"activates debug info");
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index fdfc7bf86b9e..ded25bfb366e 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -22,7 +22,7 @@
*/
/*
- * Big thanks to authors of dsbr100.c and radio-si470x.c
+ * Big thanks to authors and contributors of dsbr100.c and radio-si470x.c
*
* When work was looked pretty good, i discover this:
* http://av-usbradio.sourceforge.net/index.php
@@ -30,18 +30,23 @@
* Latest release of theirs project was in 2005.
* Probably, this driver could be improved trough using their
* achievements (specifications given).
- * So, we have smth to begin with.
+ * Also, Faidon Liambotis <paravoid@debian.org> wrote nice driver for this radio
+ * in 2007. He allowed to use his driver to improve current mr800 radio driver.
+ * http://kerneltrap.org/mailarchive/linux-usb-devel/2007/10/11/342492
*
- * History:
* Version 0.01: First working version.
* It's required to blacklist AverMedia USB Radio
* in usbhid/hid-quirks.c
+ * Version 0.10: A lot of cleanups and fixes: unpluging the device,
+ * few mutex locks were added, codinstyle issues, etc.
+ * Added stereo support. Thanks to
+ * Douglas Schilling Landgraf <dougsland@gmail.com> and
+ * David Ellingsworth <david@identd.dyndns.org>
+ * for discussion, help and support.
*
* Many things to do:
* - Correct power managment of device (suspend & resume)
- * - Make x86 independance (little-endian and big-endian stuff)
* - Add code for scanning and smooth tuning
- * - Checked and add stereo&mono stuff
* - Add code for sensitivity value
* - Correct mistakes
* - In Japan another FREQ_MIN and FREQ_MAX
@@ -62,8 +67,8 @@
/* driver and module definitions */
#define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>"
#define DRIVER_DESC "AverMedia MR 800 USB FM radio driver"
-#define DRIVER_VERSION "0.01"
-#define RADIO_VERSION KERNEL_VERSION(0, 0, 1)
+#define DRIVER_VERSION "0.10"
+#define RADIO_VERSION KERNEL_VERSION(0, 1, 0)
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
@@ -87,6 +92,22 @@ devices, that would be 76 and 91. */
#define FREQ_MAX 108.0
#define FREQ_MUL 16000
+/*
+ * Commands that device should understand
+ * List isnt full and will be updated with implementation of new functions
+ */
+#define AMRADIO_SET_FREQ 0xa4
+#define AMRADIO_SET_MUTE 0xab
+#define AMRADIO_SET_MONO 0xae
+
+/* Comfortable defines for amradio_set_mute */
+#define AMRADIO_START 0x00
+#define AMRADIO_STOP 0x01
+
+/* Comfortable defines for amradio_set_stereo */
+#define WANT_STEREO 0x00
+#define WANT_MONO 0x01
+
/* module parameter */
static int radio_nr = -1;
module_param(radio_nr, int, 0);
@@ -169,43 +190,48 @@ static struct usb_driver usb_amradio_driver = {
.supports_autosuspend = 0,
};
-/* switch on radio. Send 8 bytes to device. */
-static int amradio_start(struct amradio_device *radio)
+/* switch on/off the radio. Send 8 bytes to device */
+static int amradio_set_mute(struct amradio_device *radio, char argument)
{
int retval;
int size;
+ /* safety check */
+ if (radio->removed)
+ return -EIO;
+
mutex_lock(&radio->lock);
radio->buffer[0] = 0x00;
radio->buffer[1] = 0x55;
radio->buffer[2] = 0xaa;
radio->buffer[3] = 0x00;
- radio->buffer[4] = 0xab;
- radio->buffer[5] = 0x00;
+ radio->buffer[4] = AMRADIO_SET_MUTE;
+ radio->buffer[5] = argument;
radio->buffer[6] = 0x00;
radio->buffer[7] = 0x00;
retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
- if (retval) {
+ if (retval < 0 || size != BUFFER_LENGTH) {
mutex_unlock(&radio->lock);
return retval;
}
- radio->muted = 0;
+ radio->muted = argument;
mutex_unlock(&radio->lock);
return retval;
}
-/* switch off radio */
-static int amradio_stop(struct amradio_device *radio)
+/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
+static int amradio_setfreq(struct amradio_device *radio, int freq)
{
int retval;
int size;
+ unsigned short freq_send = 0x10 + (freq >> 3) / 25;
/* safety check */
if (radio->removed)
@@ -216,33 +242,46 @@ static int amradio_stop(struct amradio_device *radio)
radio->buffer[0] = 0x00;
radio->buffer[1] = 0x55;
radio->buffer[2] = 0xaa;
- radio->buffer[3] = 0x00;
- radio->buffer[4] = 0xab;
- radio->buffer[5] = 0x01;
+ radio->buffer[3] = 0x03;
+ radio->buffer[4] = AMRADIO_SET_FREQ;
+ radio->buffer[5] = 0x00;
radio->buffer[6] = 0x00;
- radio->buffer[7] = 0x00;
+ radio->buffer[7] = 0x08;
retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
- if (retval) {
+ if (retval < 0 || size != BUFFER_LENGTH) {
mutex_unlock(&radio->lock);
return retval;
}
- radio->muted = 1;
+ /* frequency is calculated from freq_send and placed in first 2 bytes */
+ radio->buffer[0] = (freq_send >> 8) & 0xff;
+ radio->buffer[1] = freq_send & 0xff;
+ radio->buffer[2] = 0x01;
+ radio->buffer[3] = 0x00;
+ radio->buffer[4] = 0x00;
+ /* 5 and 6 bytes of buffer already = 0x00 */
+ radio->buffer[7] = 0x00;
+
+ retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
+ (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
+
+ if (retval < 0 || size != BUFFER_LENGTH) {
+ mutex_unlock(&radio->lock);
+ return retval;
+ }
mutex_unlock(&radio->lock);
return retval;
}
-/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
-static int amradio_setfreq(struct amradio_device *radio, int freq)
+static int amradio_set_stereo(struct amradio_device *radio, char argument)
{
int retval;
int size;
- unsigned short freq_send = 0x13 + (freq >> 3) / 25;
/* safety check */
if (radio->removed)
@@ -253,50 +292,33 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
radio->buffer[0] = 0x00;
radio->buffer[1] = 0x55;
radio->buffer[2] = 0xaa;
- radio->buffer[3] = 0x03;
- radio->buffer[4] = 0xa4;
- radio->buffer[5] = 0x00;
- radio->buffer[6] = 0x00;
- radio->buffer[7] = 0x08;
-
- retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
- (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
-
- if (retval) {
- mutex_unlock(&radio->lock);
- return retval;
- }
-
- /* frequency is calculated from freq_send and placed in first 2 bytes */
- radio->buffer[0] = (freq_send >> 8) & 0xff;
- radio->buffer[1] = freq_send & 0xff;
- radio->buffer[2] = 0x01;
radio->buffer[3] = 0x00;
- radio->buffer[4] = 0x00;
- /* 5 and 6 bytes of buffer already = 0x00 */
+ radio->buffer[4] = AMRADIO_SET_MONO;
+ radio->buffer[5] = argument;
+ radio->buffer[6] = 0x00;
radio->buffer[7] = 0x00;
retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
- if (retval) {
+ if (retval < 0 || size != BUFFER_LENGTH) {
+ radio->stereo = -1;
mutex_unlock(&radio->lock);
return retval;
}
- radio->stereo = 0;
+ radio->stereo = 1;
mutex_unlock(&radio->lock);
return retval;
}
-/* USB subsystem interface begins here */
-
-/* handle unplugging of the device, release data structures
-if nothing keeps us from doing it. If something is still
-keeping us busy, the release callback of v4l will take care
-of releasing it. */
+/* Handle unplugging the device.
+ * We call video_unregister_device in any case.
+ * The last function called in this procedure is
+ * usb_amradio_device_release.
+ */
static void usb_amradio_disconnect(struct usb_interface *intf)
{
struct amradio_device *radio = usb_get_intfdata(intf);
@@ -313,9 +335,11 @@ static void usb_amradio_disconnect(struct usb_interface *intf)
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
+ struct amradio_device *radio = video_drvdata(file);
+
strlcpy(v->driver, "radio-mr800", sizeof(v->driver));
strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card));
- sprintf(v->bus_info, "USB");
+ usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
v->version = RADIO_VERSION;
v->capabilities = V4L2_CAP_TUNER;
return 0;
@@ -326,6 +350,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
/* safety check */
if (radio->removed)
@@ -337,7 +362,16 @@ static int vidioc_g_tuner(struct file *file, void *priv,
/* TODO: Add function which look is signal stereo or not
* amradio_getstat(radio);
*/
- radio->stereo = -1;
+
+/* we call amradio_set_stereo to set radio->stereo
+ * Honestly, amradio_getstat should cover this in future and
+ * amradio_set_stereo shouldn't be here
+ */
+ retval = amradio_set_stereo(radio, WANT_STEREO);
+ if (retval < 0)
+ amradio_dev_warn(&radio->videodev->dev,
+ "set stereo failed\n");
+
strcpy(v->name, "FM");
v->type = V4L2_TUNER_RADIO;
v->rangelow = FREQ_MIN * FREQ_MUL;
@@ -358,6 +392,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
/* safety check */
if (radio->removed)
@@ -365,6 +400,25 @@ static int vidioc_s_tuner(struct file *file, void *priv,
if (v->index > 0)
return -EINVAL;
+
+ /* mono/stereo selector */
+ switch (v->audmode) {
+ case V4L2_TUNER_MODE_MONO:
+ retval = amradio_set_stereo(radio, WANT_MONO);
+ if (retval < 0)
+ amradio_dev_warn(&radio->videodev->dev,
+ "set mono failed\n");
+ break;
+ case V4L2_TUNER_MODE_STEREO:
+ retval = amradio_set_stereo(radio, WANT_STEREO);
+ if (retval < 0)
+ amradio_dev_warn(&radio->videodev->dev,
+ "set stereo failed\n");
+ break;
+ default:
+ return -EINVAL;
+ }
+
return 0;
}
@@ -373,13 +427,18 @@ static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
/* safety check */
if (radio->removed)
return -EIO;
+ mutex_lock(&radio->lock);
radio->curfreq = f->frequency;
- if (amradio_setfreq(radio, radio->curfreq) < 0)
+ mutex_unlock(&radio->lock);
+
+ retval = amradio_setfreq(radio, radio->curfreq);
+ if (retval < 0)
amradio_dev_warn(&radio->videodev->dev,
"set frequency failed\n");
return 0;
@@ -438,6 +497,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
/* safety check */
if (radio->removed)
@@ -446,13 +506,15 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value) {
- if (amradio_stop(radio) < 0) {
+ retval = amradio_set_mute(radio, AMRADIO_STOP);
+ if (retval < 0) {
amradio_dev_warn(&radio->videodev->dev,
"amradio_stop failed\n");
return -1;
}
} else {
- if (amradio_start(radio) < 0) {
+ retval = amradio_set_mute(radio, AMRADIO_START);
+ if (retval < 0) {
amradio_dev_warn(&radio->videodev->dev,
"amradio_start failed\n");
return -1;
@@ -503,20 +565,29 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
static int usb_amradio_open(struct file *file)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
lock_kernel();
radio->users = 1;
radio->muted = 1;
- if (amradio_start(radio) < 0) {
+ retval = amradio_set_mute(radio, AMRADIO_START);
+ if (retval < 0) {
amradio_dev_warn(&radio->videodev->dev,
"radio did not start up properly\n");
radio->users = 0;
unlock_kernel();
return -EIO;
}
- if (amradio_setfreq(radio, radio->curfreq) < 0)
+
+ retval = amradio_set_stereo(radio, WANT_STEREO);
+ if (retval < 0)
+ amradio_dev_warn(&radio->videodev->dev,
+ "set stereo failed\n");
+
+ retval = amradio_setfreq(radio, radio->curfreq);
+ if (retval < 0)
amradio_dev_warn(&radio->videodev->dev,
"set frequency failed\n");
@@ -533,10 +604,12 @@ static int usb_amradio_close(struct file *file)
if (!radio)
return -ENODEV;
+ mutex_lock(&radio->lock);
radio->users = 0;
+ mutex_unlock(&radio->lock);
if (!radio->removed) {
- retval = amradio_stop(radio);
+ retval = amradio_set_mute(radio, AMRADIO_STOP);
if (retval < 0)
amradio_dev_warn(&radio->videodev->dev,
"amradio_stop failed\n");
@@ -549,8 +622,10 @@ static int usb_amradio_close(struct file *file)
static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
{
struct amradio_device *radio = usb_get_intfdata(intf);
+ int retval;
- if (amradio_stop(radio) < 0)
+ retval = amradio_set_mute(radio, AMRADIO_STOP);
+ if (retval < 0)
dev_warn(&intf->dev, "amradio_stop failed\n");
dev_info(&intf->dev, "going into suspend..\n");
@@ -562,8 +637,10 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
static int usb_amradio_resume(struct usb_interface *intf)
{
struct amradio_device *radio = usb_get_intfdata(intf);
+ int retval;
- if (amradio_start(radio) < 0)
+ retval = amradio_set_mute(radio, AMRADIO_START);
+ if (retval < 0)
dev_warn(&intf->dev, "amradio_start failed\n");
dev_info(&intf->dev, "coming out of suspend..\n");
@@ -614,28 +691,32 @@ static struct video_device amradio_videodev_template = {
.release = usb_amradio_device_release,
};
-/* check if the device is present and register with v4l and
-usb if it is */
+/* check if the device is present and register with v4l and usb if it is */
static int usb_amradio_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct amradio_device *radio;
+ int retval;
radio = kmalloc(sizeof(struct amradio_device), GFP_KERNEL);
- if (!(radio))
+ if (!radio) {
+ dev_err(&intf->dev, "kmalloc for amradio_device failed\n");
return -ENOMEM;
+ }
radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
- if (!(radio->buffer)) {
+ if (!radio->buffer) {
+ dev_err(&intf->dev, "kmalloc for radio->buffer failed\n");
kfree(radio);
return -ENOMEM;
}
radio->videodev = video_device_alloc();
- if (!(radio->videodev)) {
+ if (!radio->videodev) {
+ dev_err(&intf->dev, "video_device_alloc failed\n");
kfree(radio->buffer);
kfree(radio);
return -ENOMEM;
@@ -648,12 +729,14 @@ static int usb_amradio_probe(struct usb_interface *intf,
radio->users = 0;
radio->usbdev = interface_to_usbdev(intf);
radio->curfreq = 95.16 * FREQ_MUL;
+ radio->stereo = -1;
mutex_init(&radio->lock);
video_set_drvdata(radio->videodev, radio);
- if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
- dev_warn(&intf->dev, "could not register video device\n");
+ retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
+ if (retval < 0) {
+ dev_err(&intf->dev, "could not register video device\n");
video_device_release(radio->videodev);
kfree(radio->buffer);
kfree(radio);
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index 2587227214bf..d1e6b01d4eca 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -13,34 +13,16 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
+#include <linux/mutex.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/spinlock.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 65535,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
+MODULE_AUTHOR("Ben Pfaff");
+MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
+MODULE_LICENSE("GPL");
#ifndef CONFIG_RADIO_RTRACK2_PORT
#define CONFIG_RADIO_RTRACK2_PORT -1
@@ -48,79 +30,88 @@ static struct v4l2_queryctrl radio_qctrl[] = {
static int io = CONFIG_RADIO_RTRACK2_PORT;
static int radio_nr = -1;
-static spinlock_t lock;
-struct rt_device
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct rtrack2
{
- unsigned long in_use;
- int port;
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
unsigned long curfreq;
int muted;
+ struct mutex lock;
};
+static struct rtrack2 rtrack2_card;
+
/* local things */
-static void rt_mute(struct rt_device *dev)
+static void rt_mute(struct rtrack2 *dev)
{
- if(dev->muted)
+ if (dev->muted)
return;
- spin_lock(&lock);
- outb(1, io);
- spin_unlock(&lock);
+ mutex_lock(&dev->lock);
+ outb(1, dev->io);
+ mutex_unlock(&dev->lock);
dev->muted = 1;
}
-static void rt_unmute(struct rt_device *dev)
+static void rt_unmute(struct rtrack2 *dev)
{
if(dev->muted == 0)
return;
- spin_lock(&lock);
- outb(0, io);
- spin_unlock(&lock);
+ mutex_lock(&dev->lock);
+ outb(0, dev->io);
+ mutex_unlock(&dev->lock);
dev->muted = 0;
}
-static void zero(void)
+static void zero(struct rtrack2 *dev)
{
- outb_p(1, io);
- outb_p(3, io);
- outb_p(1, io);
+ outb_p(1, dev->io);
+ outb_p(3, dev->io);
+ outb_p(1, dev->io);
}
-static void one(void)
+static void one(struct rtrack2 *dev)
{
- outb_p(5, io);
- outb_p(7, io);
- outb_p(5, io);
+ outb_p(5, dev->io);
+ outb_p(7, dev->io);
+ outb_p(5, dev->io);
}
-static int rt_setfreq(struct rt_device *dev, unsigned long freq)
+static int rt_setfreq(struct rtrack2 *dev, unsigned long freq)
{
int i;
+ mutex_lock(&dev->lock);
+ dev->curfreq = freq;
freq = freq / 200 + 856;
- spin_lock(&lock);
-
- outb_p(0xc8, io);
- outb_p(0xc9, io);
- outb_p(0xc9, io);
+ outb_p(0xc8, dev->io);
+ outb_p(0xc9, dev->io);
+ outb_p(0xc9, dev->io);
for (i = 0; i < 10; i++)
- zero ();
+ zero(dev);
for (i = 14; i >= 0; i--)
if (freq & (1 << i))
- one ();
+ one(dev);
else
- zero ();
+ zero(dev);
- outb_p(0xc8, io);
+ outb_p(0xc8, dev->io);
if (!dev->muted)
- outb_p(0, io);
+ outb_p(0, dev->io);
- spin_unlock(&lock);
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -129,61 +120,61 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-rtrack2", sizeof(v->driver));
strlcpy(v->card, "RadioTrack II", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
-
- return 0;
+ return v->index ? -EINVAL : 0;
}
-static int rt_getsigstr(struct rt_device *dev)
+static int rt_getsigstr(struct rtrack2 *dev)
{
- if (inb(io) & 2) /* bit set = no signal present */
- return 0;
- return 1; /* signal present */
+ int sig = 1;
+
+ mutex_lock(&dev->lock);
+ if (inb(dev->io) & 2) /* bit set = no signal present */
+ sig = 0;
+ mutex_unlock(&dev->lock);
+ return sig;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack2 *rt = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow = (88*16000);
- v->rangehigh = (108*16000);
+ v->rangelow = 88 * 16000;
+ v->rangehigh = 108 * 16000;
v->rxsubchans = V4L2_TUNER_SUB_MONO;
v->capability = V4L2_TUNER_CAP_LOW;
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = 0xFFFF*rt_getsigstr(rt);
+ v->signal = 0xFFFF * rt_getsigstr(rt);
return 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack2 *rt = video_drvdata(file);
- rt->curfreq = f->frequency;
- rt_setfreq(rt, rt->curfreq);
+ rt_setfreq(rt, f->frequency);
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack2 *rt = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = rt->curfreq;
@@ -193,14 +184,11 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535);
}
return -EINVAL;
}
@@ -208,7 +196,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack2 *rt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -227,7 +215,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack2 *rt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -246,17 +234,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -265,36 +242,38 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static struct rt_device rtrack2_unit;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
-static int rtrack2_exclusive_open(struct file *file)
+static int rtrack2_open(struct file *file)
{
- return test_and_set_bit(0, &rtrack2_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int rtrack2_exclusive_release(struct file *file)
+static int rtrack2_release(struct file *file)
{
- clear_bit(0, &rtrack2_unit.in_use);
return 0;
}
static const struct v4l2_file_operations rtrack2_fops = {
.owner = THIS_MODULE,
- .open = rtrack2_exclusive_open,
- .release = rtrack2_exclusive_release,
+ .open = rtrack2_open,
+ .release = rtrack2_release,
.ioctl = video_ioctl2,
};
@@ -313,62 +292,61 @@ static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = {
.vidioc_s_input = vidioc_s_input,
};
-static struct video_device rtrack2_radio = {
- .name = "RadioTrack II radio",
- .fops = &rtrack2_fops,
- .ioctl_ops = &rtrack2_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __init rtrack2_init(void)
{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n");
+ struct rtrack2 *dev = &rtrack2_card;
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "rtrack2", sizeof(v4l2_dev->name));
+ dev->io = io;
+ if (dev->io == -1) {
+ v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or io=0x30c\n");
return -EINVAL;
}
- if (!request_region(io, 4, "rtrack2"))
- {
- printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io);
+ if (!request_region(dev->io, 4, "rtrack2")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", dev->io);
return -EBUSY;
}
- video_set_drvdata(&rtrack2_radio, &rtrack2_unit);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(dev->io, 4);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
- spin_lock_init(&lock);
- if (video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 4);
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &rtrack2_fops;
+ dev->vdev.ioctl_ops = &rtrack2_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
+
+ mutex_init(&dev->lock);
+ if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(dev->io, 4);
return -EINVAL;
}
- printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n");
+ v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n");
/* mute card - prevents noisy bootups */
- outb(1, io);
- rtrack2_unit.muted = 1;
+ outb(1, dev->io);
+ dev->muted = 1;
return 0;
}
-MODULE_AUTHOR("Ben Pfaff");
-MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
-module_param(radio_nr, int, 0);
-
-static void __exit rtrack2_cleanup_module(void)
+static void __exit rtrack2_exit(void)
{
- video_unregister_device(&rtrack2_radio);
- release_region(io,4);
+ struct rtrack2 *dev = &rtrack2_card;
+
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ release_region(dev->io, 4);
}
module_init(rtrack2_init);
-module_exit(rtrack2_cleanup_module);
-
-/*
- Local variables:
- compile-command: "mmake"
- End:
-*/
+module_exit(rtrack2_exit);
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index d358e48c2422..f4784f0d1a88 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -22,113 +22,109 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
#include <linux/isapnp.h>
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/mutex.h>
+#include <linux/videodev2.h> /* kernel radio structs */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
+MODULE_DESCRIPTION("A driver for the SF16MI radio.");
+MODULE_LICENSE("GPL");
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- }
-};
+static int io = -1;
+static int radio_nr = -1;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
-struct fmi_device
+struct fmi
{
- unsigned long in_use;
- int port;
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
int curvol; /* 1 or 0 */
unsigned long curfreq; /* freq in kHz */
__u32 flags;
+ struct mutex lock;
};
-static int io = -1;
-static int radio_nr = -1;
-static struct pnp_dev *dev = NULL;
-static struct mutex lock;
+static struct fmi fmi_card;
+static struct pnp_dev *dev;
/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
/* It is only useful to give freq in intervall of 800 (=0.05Mhz),
* other bits will be truncated, e.g 92.7400016 -> 92.7, but
* 92.7400017 -> 92.75
*/
-#define RSF16_ENCODE(x) ((x)/800+214)
-#define RSF16_MINFREQ 87*16000
-#define RSF16_MAXFREQ 108*16000
+#define RSF16_ENCODE(x) ((x) / 800 + 214)
+#define RSF16_MINFREQ (87 * 16000)
+#define RSF16_MAXFREQ (108 * 16000)
-static void outbits(int bits, unsigned int data, int port)
+static void outbits(int bits, unsigned int data, int io)
{
- while(bits--) {
- if(data & 1) {
- outb(5, port);
+ while (bits--) {
+ if (data & 1) {
+ outb(5, io);
udelay(6);
- outb(7, port);
+ outb(7, io);
udelay(6);
} else {
- outb(1, port);
+ outb(1, io);
udelay(6);
- outb(3, port);
+ outb(3, io);
udelay(6);
}
- data>>=1;
+ data >>= 1;
}
}
-static inline void fmi_mute(int port)
+static inline void fmi_mute(struct fmi *fmi)
{
- mutex_lock(&lock);
- outb(0x00, port);
- mutex_unlock(&lock);
+ mutex_lock(&fmi->lock);
+ outb(0x00, fmi->io);
+ mutex_unlock(&fmi->lock);
}
-static inline void fmi_unmute(int port)
+static inline void fmi_unmute(struct fmi *fmi)
{
- mutex_lock(&lock);
- outb(0x08, port);
- mutex_unlock(&lock);
+ mutex_lock(&fmi->lock);
+ outb(0x08, fmi->io);
+ mutex_unlock(&fmi->lock);
}
-static inline int fmi_setfreq(struct fmi_device *dev)
+static inline int fmi_setfreq(struct fmi *fmi, unsigned long freq)
{
- int myport = dev->port;
- unsigned long freq = dev->curfreq;
+ mutex_lock(&fmi->lock);
+ fmi->curfreq = freq;
- mutex_lock(&lock);
-
- outbits(16, RSF16_ENCODE(freq), myport);
- outbits(8, 0xC0, myport);
+ outbits(16, RSF16_ENCODE(freq), fmi->io);
+ outbits(8, 0xC0, fmi->io);
msleep(143); /* was schedule_timeout(HZ/7) */
- mutex_unlock(&lock);
- if (dev->curvol) fmi_unmute(myport);
+ mutex_unlock(&fmi->lock);
+ if (fmi->curvol)
+ fmi_unmute(fmi);
return 0;
}
-static inline int fmi_getsigstr(struct fmi_device *dev)
+static inline int fmi_getsigstr(struct fmi *fmi)
{
int val;
int res;
- int myport = dev->port;
-
- mutex_lock(&lock);
- val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */
- outb(val, myport);
- outb(val | 0x10, myport);
+ mutex_lock(&fmi->lock);
+ val = fmi->curvol ? 0x08 : 0x00; /* unmute/mute */
+ outb(val, fmi->io);
+ outb(val | 0x10, fmi->io);
msleep(143); /* was schedule_timeout(HZ/7) */
- res = (int)inb(myport+1);
- outb(val, myport);
+ res = (int)inb(fmi->io + 1);
+ outb(val, fmi->io);
- mutex_unlock(&lock);
+ mutex_unlock(&fmi->lock);
return (res & 2) ? 0 : 0xFFFF;
}
@@ -137,9 +133,9 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver));
strlcpy(v->card, "SF16-FMx radio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
@@ -147,18 +143,18 @@ static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
int mult;
- struct fmi_device *fmi = video_drvdata(file);
+ struct fmi *fmi = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
- v->rangelow = RSF16_MINFREQ/mult;
- v->rangehigh = RSF16_MAXFREQ/mult;
+ v->rangelow = RSF16_MINFREQ / mult;
+ v->rangehigh = RSF16_MAXFREQ / mult;
v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
- v->capability = fmi->flags&V4L2_TUNER_CAP_LOW;
+ v->capability = fmi->flags & V4L2_TUNER_CAP_LOW;
v->audmode = V4L2_TUNER_MODE_STEREO;
v->signal = fmi_getsigstr(fmi);
return 0;
@@ -167,32 +163,29 @@ static int vidioc_g_tuner(struct file *file, void *priv,
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct fmi_device *fmi = video_drvdata(file);
+ struct fmi *fmi = video_drvdata(file);
if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
f->frequency *= 1000;
if (f->frequency < RSF16_MINFREQ ||
- f->frequency > RSF16_MAXFREQ )
+ f->frequency > RSF16_MAXFREQ)
return -EINVAL;
- /*rounding in steps of 800 to match th freq
- that will be used */
- fmi->curfreq = (f->frequency/800)*800;
- fmi_setfreq(fmi);
+ /* rounding in steps of 800 to match the freq
+ that will be used */
+ fmi_setfreq(fmi, (f->frequency / 800) * 800);
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct fmi_device *fmi = video_drvdata(file);
+ struct fmi *fmi = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = fmi->curfreq;
@@ -204,14 +197,9 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
}
return -EINVAL;
}
@@ -219,7 +207,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct fmi_device *fmi = video_drvdata(file);
+ struct fmi *fmi = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -232,31 +220,20 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct fmi_device *fmi = video_drvdata(file);
+ struct fmi *fmi = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value)
- fmi_mute(fmi->port);
+ fmi_mute(fmi);
else
- fmi_unmute(fmi->port);
+ fmi_unmute(fmi);
fmi->curvol = ctrl->value;
return 0;
}
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -265,36 +242,38 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static struct fmi_device fmi_unit;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
-static int fmi_exclusive_open(struct file *file)
+static int fmi_open(struct file *file)
{
- return test_and_set_bit(0, &fmi_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int fmi_exclusive_release(struct file *file)
+static int fmi_release(struct file *file)
{
- clear_bit(0, &fmi_unit.in_use);
return 0;
}
static const struct v4l2_file_operations fmi_fops = {
.owner = THIS_MODULE,
- .open = fmi_exclusive_open,
- .release = fmi_exclusive_release,
+ .open = fmi_open,
+ .release = fmi_release,
.ioctl = video_ioctl2,
};
@@ -313,13 +292,6 @@ static const struct v4l2_ioctl_ops fmi_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device fmi_radio = {
- .name = "SF16FMx radio",
- .fops = &fmi_fops,
- .ioctl_ops = &fmi_ioctl_ops,
- .release = video_device_release_empty,
-};
-
/* ladis: this is my card. does any other types exist? */
static struct isapnp_device_id id_table[] __devinitdata = {
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
@@ -344,7 +316,7 @@ static int __init isapnp_fmi_probe(void)
if (pnp_device_attach(dev) < 0)
return -EAGAIN;
if (pnp_activate_dev(dev) < 0) {
- printk ("radio-sf16fmi: PnP configure failed (out of resources?)\n");
+ printk(KERN_ERR "radio-sf16fmi: PnP configure failed (out of resources?)\n");
pnp_device_detach(dev);
return -ENOMEM;
}
@@ -354,59 +326,72 @@ static int __init isapnp_fmi_probe(void)
}
i = pnp_port_start(dev, 0);
- printk ("radio-sf16fmi: PnP reports card at %#x\n", i);
+ printk(KERN_INFO "radio-sf16fmi: PnP reports card at %#x\n", i);
return i;
}
static int __init fmi_init(void)
{
+ struct fmi *fmi = &fmi_card;
+ struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
+ int res;
+
if (io < 0)
io = isapnp_fmi_probe();
- if (io < 0) {
- printk(KERN_ERR "radio-sf16fmi: No PnP card found.\n");
- return io;
+ strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
+ fmi->io = io;
+ if (fmi->io < 0) {
+ v4l2_err(v4l2_dev, "No PnP card found.\n");
+ return fmi->io;
}
if (!request_region(io, 2, "radio-sf16fmi")) {
- printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", io);
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", fmi->io);
pnp_device_detach(dev);
return -EBUSY;
}
- fmi_unit.port = io;
- fmi_unit.curvol = 0;
- fmi_unit.curfreq = 0;
- fmi_unit.flags = V4L2_TUNER_CAP_LOW;
- video_set_drvdata(&fmi_radio, &fmi_unit);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(fmi->io, 2);
+ pnp_device_detach(dev);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
+
+ fmi->flags = V4L2_TUNER_CAP_LOW;
+ strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name));
+ fmi->vdev.v4l2_dev = v4l2_dev;
+ fmi->vdev.fops = &fmi_fops;
+ fmi->vdev.ioctl_ops = &fmi_ioctl_ops;
+ fmi->vdev.release = video_device_release_empty;
+ video_set_drvdata(&fmi->vdev, fmi);
- mutex_init(&lock);
+ mutex_init(&fmi->lock);
- if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 2);
+ if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(fmi->io, 2);
+ pnp_device_detach(dev);
return -EINVAL;
}
- printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io);
+ v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io);
/* mute card - prevents noisy bootups */
- fmi_mute(io);
+ fmi_mute(fmi);
return 0;
}
-MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
-MODULE_DESCRIPTION("A driver for the SF16MI radio.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
-module_param(radio_nr, int, 0);
-
-static void __exit fmi_cleanup_module(void)
+static void __exit fmi_exit(void)
{
- video_unregister_device(&fmi_radio);
- release_region(io, 2);
+ struct fmi *fmi = &fmi_card;
+
+ video_unregister_device(&fmi->vdev);
+ v4l2_device_unregister(&fmi->v4l2_dev);
+ release_region(fmi->io, 2);
if (dev)
pnp_device_detach(dev);
}
module_init(fmi_init);
-module_exit(fmi_cleanup_module);
+module_exit(fmi_exit);
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 92f17a347fa7..0ba9d88a80fc 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -18,40 +18,28 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
#include <linux/mutex.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
-static struct mutex lock;
+MODULE_AUTHOR("Ziglio Frediano, freddy77@angelfire.com");
+MODULE_DESCRIPTION("A driver for the SF16FMR2 radio.");
+MODULE_LICENSE("GPL");
+
+static int io = 0x384;
+static int radio_nr = -1;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the SF16FMR2 card (should be 0x384, if do not work try 0x284)");
+module_param(radio_nr, int, 0);
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#define RADIO_VERSION KERNEL_VERSION(0,0,2)
#define AUD_VOL_INDEX 1
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },
- [AUD_VOL_INDEX] = {
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 15,
- .step = 1,
- .default_value = 0,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
-
#undef DEBUG
//#define DEBUG 1
@@ -62,156 +50,160 @@ static struct v4l2_queryctrl radio_qctrl[] = {
#endif
/* this should be static vars for module size */
-struct fmr2_device
+struct fmr2
{
- unsigned long in_use;
- int port;
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ struct mutex lock;
+ int io;
int curvol; /* 0-15 */
int mute;
int stereo; /* card is producing stereo audio */
unsigned long curfreq; /* freq in kHz */
int card_type;
- __u32 flags;
+ u32 flags;
};
-static int io = 0x384;
-static int radio_nr = -1;
+static struct fmr2 fmr2_card;
/* hw precision is 12.5 kHz
* It is only useful to give freq in intervall of 200 (=0.0125Mhz),
* other bits will be truncated
*/
-#define RSF16_ENCODE(x) ((x)/200+856)
-#define RSF16_MINFREQ 87*16000
-#define RSF16_MAXFREQ 108*16000
+#define RSF16_ENCODE(x) ((x) / 200 + 856)
+#define RSF16_MINFREQ (87 * 16000)
+#define RSF16_MAXFREQ (108 * 16000)
-static inline void wait(int n,int port)
+static inline void wait(int n, int io)
{
- for (;n;--n) inb(port);
+ for (; n; --n)
+ inb(io);
}
-static void outbits(int bits, unsigned int data, int nWait, int port)
+static void outbits(int bits, unsigned int data, int nWait, int io)
{
int bit;
- for(;--bits>=0;) {
- bit = (data>>bits) & 1;
- outb(bit,port);
- wait(nWait,port);
- outb(bit|2,port);
- wait(nWait,port);
- outb(bit,port);
- wait(nWait,port);
+
+ for (; --bits >= 0;) {
+ bit = (data >> bits) & 1;
+ outb(bit, io);
+ wait(nWait, io);
+ outb(bit | 2, io);
+ wait(nWait, io);
+ outb(bit, io);
+ wait(nWait, io);
}
}
-static inline void fmr2_mute(int port)
+static inline void fmr2_mute(int io)
{
- outb(0x00, port);
- wait(4,port);
+ outb(0x00, io);
+ wait(4, io);
}
-static inline void fmr2_unmute(int port)
+static inline void fmr2_unmute(int io)
{
- outb(0x04, port);
- wait(4,port);
+ outb(0x04, io);
+ wait(4, io);
}
-static inline int fmr2_stereo_mode(int port)
+static inline int fmr2_stereo_mode(int io)
{
- int n = inb(port);
- outb(6,port);
- inb(port);
- n = ((n>>3)&1)^1;
+ int n = inb(io);
+
+ outb(6, io);
+ inb(io);
+ n = ((n >> 3) & 1) ^ 1;
debug_print((KERN_DEBUG "stereo: %d\n", n));
return n;
}
-static int fmr2_product_info(struct fmr2_device *dev)
+static int fmr2_product_info(struct fmr2 *dev)
{
- int n = inb(dev->port);
+ int n = inb(dev->io);
+
n &= 0xC1;
- if (n == 0)
- {
+ if (n == 0) {
/* this should support volume set */
dev->card_type = 12;
return 0;
}
/* not volume (mine is 11) */
- dev->card_type = (n==128)?11:0;
+ dev->card_type = (n == 128) ? 11 : 0;
return n;
}
-static inline int fmr2_getsigstr(struct fmr2_device *dev)
+static inline int fmr2_getsigstr(struct fmr2 *dev)
{
- /* !!! work only if scanning freq */
- int port = dev->port, res = 0xffff;
- outb(5,port);
- wait(4,port);
- if (!(inb(port)&1)) res = 0;
+ /* !!! works only if scanning freq */
+ int res = 0xffff;
+
+ outb(5, dev->io);
+ wait(4, dev->io);
+ if (!(inb(dev->io) & 1))
+ res = 0;
debug_print((KERN_DEBUG "signal: %d\n", res));
return res;
}
/* set frequency and unmute card */
-static int fmr2_setfreq(struct fmr2_device *dev)
+static int fmr2_setfreq(struct fmr2 *dev)
{
- int port = dev->port;
unsigned long freq = dev->curfreq;
- fmr2_mute(port);
+ fmr2_mute(dev->io);
/* 0x42 for mono output
* 0x102 forward scanning
* 0x182 scansione avanti
*/
- outbits(9,0x2,3,port);
- outbits(16,RSF16_ENCODE(freq),2,port);
+ outbits(9, 0x2, 3, dev->io);
+ outbits(16, RSF16_ENCODE(freq), 2, dev->io);
- fmr2_unmute(port);
+ fmr2_unmute(dev->io);
/* wait 0.11 sec */
msleep(110);
/* NOTE if mute this stop radio
you must set freq on unmute */
- dev->stereo = fmr2_stereo_mode(port);
+ dev->stereo = fmr2_stereo_mode(dev->io);
return 0;
}
/* !!! not tested, in my card this does't work !!! */
-static int fmr2_setvolume(struct fmr2_device *dev)
+static int fmr2_setvolume(struct fmr2 *dev)
{
int vol[16] = { 0x021, 0x084, 0x090, 0x104,
0x110, 0x204, 0x210, 0x402,
0x404, 0x408, 0x410, 0x801,
0x802, 0x804, 0x808, 0x810 };
- int i, a, port = dev->port;
+ int i, a;
int n = vol[dev->curvol & 0x0f];
if (dev->card_type != 11)
return 1;
for (i = 12; --i >= 0; ) {
- a = ((n >> i) & 1) << 6; /* if (a=0) a= 0; else a= 0x40; */
- outb(a | 4, port);
- wait(4, port);
- outb(a | 0x24, port);
- wait(4, port);
- outb(a | 4, port);
- wait(4, port);
+ a = ((n >> i) & 1) << 6; /* if (a==0) a = 0; else a = 0x40; */
+ outb(a | 4, dev->io);
+ wait(4, dev->io);
+ outb(a | 0x24, dev->io);
+ wait(4, dev->io);
+ outb(a | 4, dev->io);
+ wait(4, dev->io);
}
for (i = 6; --i >= 0; ) {
a = ((0x18 >> i) & 1) << 6;
- outb(a | 4, port);
- wait(4,port);
- outb(a | 0x24, port);
- wait(4,port);
- outb(a|4, port);
- wait(4,port);
+ outb(a | 4, dev->io);
+ wait(4, dev->io);
+ outb(a | 0x24, dev->io);
+ wait(4, dev->io);
+ outb(a | 4, dev->io);
+ wait(4, dev->io);
}
- wait(4, port);
- outb(0x14, port);
-
+ wait(4, dev->io);
+ outb(0x14, dev->io);
return 0;
}
@@ -220,9 +212,9 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-sf16fmr2", sizeof(v->driver));
strlcpy(v->card, "SF16-FMR2 radio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
@@ -230,54 +222,52 @@ static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
int mult;
- struct fmr2_device *fmr2 = video_drvdata(file);
+ struct fmr2 *fmr2 = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
- v->rangelow = RSF16_MINFREQ/mult;
- v->rangehigh = RSF16_MAXFREQ/mult;
+ v->rangelow = RSF16_MINFREQ / mult;
+ v->rangehigh = RSF16_MAXFREQ / mult;
v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
v->capability = fmr2->flags&V4L2_TUNER_CAP_LOW;
v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
V4L2_TUNER_MODE_MONO;
- mutex_lock(&lock);
+ mutex_lock(&fmr2->lock);
v->signal = fmr2_getsigstr(fmr2);
- mutex_unlock(&lock);
+ mutex_unlock(&fmr2->lock);
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct fmr2_device *fmr2 = video_drvdata(file);
+ struct fmr2 *fmr2 = video_drvdata(file);
if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
f->frequency *= 1000;
if (f->frequency < RSF16_MINFREQ ||
- f->frequency > RSF16_MAXFREQ )
+ f->frequency > RSF16_MAXFREQ)
return -EINVAL;
- /*rounding in steps of 200 to match th freq
- that will be used */
- fmr2->curfreq = (f->frequency/200)*200;
+ /* rounding in steps of 200 to match the freq
+ that will be used */
+ fmr2->curfreq = (f->frequency / 200) * 200;
/* set card freq (if not muted) */
if (fmr2->curvol && !fmr2->mute) {
- mutex_lock(&lock);
+ mutex_lock(&fmr2->lock);
fmr2_setfreq(fmr2);
- mutex_unlock(&lock);
+ mutex_unlock(&fmr2->lock);
}
return 0;
}
@@ -285,7 +275,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct fmr2_device *fmr2 = video_drvdata(file);
+ struct fmr2 *fmr2 = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = fmr2->curfreq;
@@ -297,13 +287,16 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
+ struct fmr2 *fmr2 = video_drvdata(file);
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &radio_qctrl[i], sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ /* Only card_type == 11 implements volume */
+ if (fmr2->card_type == 11)
+ return v4l2_ctrl_query_fill(qc, 0, 15, 1, 0);
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
}
return -EINVAL;
}
@@ -311,7 +304,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct fmr2_device *fmr2 = video_drvdata(file);
+ struct fmr2 *fmr2 = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -327,18 +320,14 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct fmr2_device *fmr2 = video_drvdata(file);
+ struct fmr2 *fmr2 = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
fmr2->mute = ctrl->value;
break;
case V4L2_CID_AUDIO_VOLUME:
- if (ctrl->value > radio_qctrl[AUD_VOL_INDEX].maximum)
- fmr2->curvol = radio_qctrl[AUD_VOL_INDEX].maximum;
- else
- fmr2->curvol = ctrl->value;
-
+ fmr2->curvol = ctrl->value;
break;
default:
return -EINVAL;
@@ -351,25 +340,14 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
printk(KERN_DEBUG "mute\n");
#endif
- mutex_lock(&lock);
+ mutex_lock(&fmr2->lock);
if (fmr2->curvol && !fmr2->mute) {
fmr2_setvolume(fmr2);
/* Set frequency and unmute card */
fmr2_setfreq(fmr2);
} else
- fmr2_mute(fmr2->port);
- mutex_unlock(&lock);
- return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
+ fmr2_mute(fmr2->io);
+ mutex_unlock(&fmr2->lock);
return 0;
}
@@ -381,36 +359,38 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static struct fmr2_device fmr2_unit;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
-static int fmr2_exclusive_open(struct file *file)
+static int fmr2_open(struct file *file)
{
- return test_and_set_bit(0, &fmr2_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int fmr2_exclusive_release(struct file *file)
+static int fmr2_release(struct file *file)
{
- clear_bit(0, &fmr2_unit.in_use);
return 0;
}
static const struct v4l2_file_operations fmr2_fops = {
.owner = THIS_MODULE,
- .open = fmr2_exclusive_open,
- .release = fmr2_exclusive_release,
+ .open = fmr2_open,
+ .release = fmr2_release,
.ioctl = video_ioctl2,
};
@@ -429,67 +409,64 @@ static const struct v4l2_ioctl_ops fmr2_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device fmr2_radio = {
- .name = "SF16FMR2 radio",
- .fops = &fmr2_fops,
- .ioctl_ops = &fmr2_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __init fmr2_init(void)
{
- fmr2_unit.port = io;
- fmr2_unit.curvol = 0;
- fmr2_unit.mute = 0;
- fmr2_unit.curfreq = 0;
- fmr2_unit.stereo = 1;
- fmr2_unit.flags = V4L2_TUNER_CAP_LOW;
- fmr2_unit.card_type = 0;
- video_set_drvdata(&fmr2_radio, &fmr2_unit);
-
- mutex_init(&lock);
-
- if (!request_region(io, 2, "sf16fmr2")) {
- printk(KERN_ERR "radio-sf16fmr2: request_region failed!\n");
+ struct fmr2 *fmr2 = &fmr2_card;
+ struct v4l2_device *v4l2_dev = &fmr2->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "sf16fmr2", sizeof(v4l2_dev->name));
+ fmr2->io = io;
+ fmr2->stereo = 1;
+ fmr2->flags = V4L2_TUNER_CAP_LOW;
+ mutex_init(&fmr2->lock);
+
+ if (!request_region(fmr2->io, 2, "sf16fmr2")) {
+ v4l2_err(v4l2_dev, "request_region failed!\n");
return -EBUSY;
}
- if (video_register_device(&fmr2_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 2);
- return -EINVAL;
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(fmr2->io, 2);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
}
- printk(KERN_INFO "SF16FMR2 radio card driver at 0x%x.\n", io);
- /* mute card - prevents noisy bootups */
- mutex_lock(&lock);
- fmr2_mute(io);
- fmr2_product_info(&fmr2_unit);
- mutex_unlock(&lock);
- debug_print((KERN_DEBUG "card_type %d\n", fmr2_unit.card_type));
+ strlcpy(fmr2->vdev.name, v4l2_dev->name, sizeof(fmr2->vdev.name));
+ fmr2->vdev.v4l2_dev = v4l2_dev;
+ fmr2->vdev.fops = &fmr2_fops;
+ fmr2->vdev.ioctl_ops = &fmr2_ioctl_ops;
+ fmr2->vdev.release = video_device_release_empty;
+ video_set_drvdata(&fmr2->vdev, fmr2);
- /* Only card_type == 11 implements volume */
- if (fmr2_unit.card_type != 11)
- radio_qctrl[AUD_VOL_INDEX].maximum = 1;
+ if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(fmr2->io, 2);
+ return -EINVAL;
+ }
+ v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io);
+ /* mute card - prevents noisy bootups */
+ mutex_lock(&fmr2->lock);
+ fmr2_mute(fmr2->io);
+ fmr2_product_info(fmr2);
+ mutex_unlock(&fmr2->lock);
+ debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type));
return 0;
}
-MODULE_AUTHOR("Ziglio Frediano, freddy77@angelfire.com");
-MODULE_DESCRIPTION("A driver for the SF16FMR2 radio.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the SF16FMR2 card (should be 0x384, if do not work try 0x284)");
-module_param(radio_nr, int, 0);
-
-static void __exit fmr2_cleanup_module(void)
+static void __exit fmr2_exit(void)
{
- video_unregister_device(&fmr2_radio);
- release_region(io,2);
+ struct fmr2 *fmr2 = &fmr2_card;
+
+ video_unregister_device(&fmr2->vdev);
+ v4l2_device_unregister(&fmr2->v4l2_dev);
+ release_region(fmr2->io, 2);
}
module_init(fmr2_init);
-module_exit(fmr2_cleanup_module);
+module_exit(fmr2_exit);
#ifndef MODULE
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index 4dfed6aa2dbc..713e242ba8b2 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -5,8 +5,9 @@
* - Silicon Labs USB FM Radio Reference Design
* - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF)
* - KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
+ * - Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear)
*
- * Copyright (c) 2008 Tobias Lorenz <tobias.lorenz@gmx.net>
+ * Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,7 +30,7 @@
* 2008-01-12 Tobias Lorenz <tobias.lorenz@gmx.net>
* Version 1.0.0
* - First working version
- * 2008-01-13 Tobias Lorenz <tobias.lorenz@gmx.net>
+ * 2008-01-13 Tobias Lorenz <tobias.lorenz@gmx.net>
* Version 1.0.1
* - Improved error handling, every function now returns errno
* - Improved multi user access (start/mute/stop)
@@ -104,6 +105,7 @@
* 2009-01-31 Rick Bronson <rick@efn.org>
* Tobias Lorenz <tobias.lorenz@gmx.net>
* - add LED status output
+ * - get HW/SW version from scratchpad
*
* ToDo:
* - add firmware download/update support
@@ -114,10 +116,10 @@
/* driver definitions */
#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
#define DRIVER_NAME "radio-si470x"
-#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 8)
+#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 9)
#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
-#define DRIVER_VERSION "1.0.8"
+#define DRIVER_VERSION "1.0.9"
/* kernel includes */
@@ -145,7 +147,7 @@ static struct usb_device_id si470x_usb_driver_id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
/* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) },
- /* DealExtreme USB Radio */
+ /* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */
{ USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) },
/* Terminating entry */
{ }
@@ -345,7 +347,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
/* Report 19: stream */
#define STREAM_REPORT_SIZE 3
-#define STREAM_REPORT 19
+#define STREAM_REPORT 19
/* Report 20: scratch */
#define SCRATCH_PAGE_SIZE 63
@@ -353,9 +355,13 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
#define SCRATCH_REPORT 20
/* Reports 19-22: flash upgrade of the C8051F321 */
+#define WRITE_REPORT_SIZE 4
#define WRITE_REPORT 19
+#define FLASH_REPORT_SIZE 64
#define FLASH_REPORT 20
+#define CRC_REPORT_SIZE 3
#define CRC_REPORT 21
+#define RESPONSE_REPORT_SIZE 2
#define RESPONSE_REPORT 22
/* Report 23: currently unused, but can accept 60 byte reports on the HID */
@@ -414,7 +420,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
/* bootloader commands */
#define GET_SW_VERSION_COMMAND 0x00
-#define SET_PAGE_COMMAND 0x01
+#define SET_PAGE_COMMAND 0x01
#define ERASE_PAGE_COMMAND 0x02
#define WRITE_PAGE_COMMAND 0x03
#define CRC_ON_PAGE_COMMAND 0x04
@@ -428,12 +434,6 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
#define COMMAND_FAILED 0x02
#define COMMAND_PENDING 0x03
-/* buffer sizes */
-#define COMMAND_BUFFER_SIZE 4
-#define RESPONSE_BUFFER_SIZE 2
-#define FLASH_BUFFER_SIZE 64
-#define CRC_BUFFER_SIZE 3
-
/**************************************************************************
@@ -465,6 +465,10 @@ struct si470x_device {
unsigned int buf_size;
unsigned int rd_index;
unsigned int wr_index;
+
+ /* scratch page */
+ unsigned char software_version;
+ unsigned char hardware_version;
};
@@ -480,7 +484,7 @@ struct si470x_device {
/**************************************************************************
- * General Driver Functions
+ * General Driver Functions - REGISTER_REPORTs
**************************************************************************/
/*
@@ -566,60 +570,6 @@ static int si470x_set_register(struct si470x_device *radio, int regnr)
/*
- * si470x_get_all_registers - read entire registers
- */
-static int si470x_get_all_registers(struct si470x_device *radio)
-{
- unsigned char buf[ENTIRE_REPORT_SIZE];
- int retval;
- unsigned char regnr;
-
- buf[0] = ENTIRE_REPORT;
-
- retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
-
- if (retval >= 0)
- for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
- radio->registers[regnr] = get_unaligned_be16(
- &buf[regnr * RADIO_REGISTER_SIZE + 1]);
-
- return (retval < 0) ? -EINVAL : 0;
-}
-
-
-/*
- * si470x_get_rds_registers - read rds registers
- */
-static int si470x_get_rds_registers(struct si470x_device *radio)
-{
- unsigned char buf[RDS_REPORT_SIZE];
- int retval;
- int size;
- unsigned char regnr;
-
- buf[0] = RDS_REPORT;
-
- retval = usb_interrupt_msg(radio->usbdev,
- usb_rcvintpipe(radio->usbdev, 1),
- (void *) &buf, sizeof(buf), &size, usb_timeout);
- if (size != sizeof(buf))
- printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
- "return size differs: %d != %zu\n", size, sizeof(buf));
- if (retval < 0)
- printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
- "usb_interrupt_msg returned %d\n", retval);
-
- if (retval >= 0)
- for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
- radio->registers[STATUSRSSI + regnr] =
- get_unaligned_be16(
- &buf[regnr * RADIO_REGISTER_SIZE + 1]);
-
- return (retval < 0) ? -EINVAL : 0;
-}
-
-
-/*
* si470x_set_chan - set the channel
*/
static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
@@ -887,6 +837,70 @@ static int si470x_rds_on(struct si470x_device *radio)
/**************************************************************************
+ * General Driver Functions - ENTIRE_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_all_registers - read entire registers
+ */
+static int si470x_get_all_registers(struct si470x_device *radio)
+{
+ unsigned char buf[ENTIRE_REPORT_SIZE];
+ int retval;
+ unsigned char regnr;
+
+ buf[0] = ENTIRE_REPORT;
+
+ retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
+
+ if (retval >= 0)
+ for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
+ radio->registers[regnr] = get_unaligned_be16(
+ &buf[regnr * RADIO_REGISTER_SIZE + 1]);
+
+ return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
+ * General Driver Functions - RDS_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_rds_registers - read rds registers
+ */
+static int si470x_get_rds_registers(struct si470x_device *radio)
+{
+ unsigned char buf[RDS_REPORT_SIZE];
+ int retval;
+ int size;
+ unsigned char regnr;
+
+ buf[0] = RDS_REPORT;
+
+ retval = usb_interrupt_msg(radio->usbdev,
+ usb_rcvintpipe(radio->usbdev, 1),
+ (void *) &buf, sizeof(buf), &size, usb_timeout);
+ if (size != sizeof(buf))
+ printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
+ "return size differs: %d != %zu\n", size, sizeof(buf));
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
+ "usb_interrupt_msg returned %d\n", retval);
+
+ if (retval >= 0)
+ for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
+ radio->registers[STATUSRSSI + regnr] =
+ get_unaligned_be16(
+ &buf[regnr * RADIO_REGISTER_SIZE + 1]);
+
+ return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
* General Driver Functions - LED_REPORT
**************************************************************************/
@@ -911,6 +925,35 @@ static int si470x_set_led_state(struct si470x_device *radio,
/**************************************************************************
+ * General Driver Functions - SCRATCH_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_scratch_versions - gets the scratch page and version infos
+ */
+static int si470x_get_scratch_page_versions(struct si470x_device *radio)
+{
+ unsigned char buf[SCRATCH_REPORT_SIZE];
+ int retval;
+
+ buf[0] = SCRATCH_REPORT;
+
+ retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
+
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME ": si470x_get_scratch: "
+ "si470x_get_report returned %d\n", retval);
+ else {
+ radio->software_version = buf[1];
+ radio->hardware_version = buf[2];
+ }
+
+ return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
* RDS Driver Functions
**************************************************************************/
@@ -1124,6 +1167,7 @@ static int si470x_fops_open(struct file *file)
}
if (radio->users == 1) {
+ /* start radio */
retval = si470x_start(radio);
if (retval < 0)
usb_autopm_put_interface(radio->intf);
@@ -1165,6 +1209,7 @@ static int si470x_fops_release(struct file *file)
/* cancel read processes */
wake_up_interruptible(&radio->read_queue);
+ /* stop radio */
retval = si470x_stop(radio);
usb_autopm_put_interface(radio->intf);
}
@@ -1226,9 +1271,11 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
static int si470x_vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *capability)
{
+ struct si470x_device *radio = video_drvdata(file);
+
strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
- sprintf(capability->bus_info, "USB");
+ usb_make_path(radio->usbdev, capability->bus_info, sizeof(capability->bus_info));
capability->version = DRIVER_KERNEL_VERSION;
capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
V4L2_CAP_TUNER | V4L2_CAP_RADIO;
@@ -1636,7 +1683,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
sizeof(si470x_viddev_template));
video_set_drvdata(radio->videodev, radio);
- /* show some infos about the specific device */
+ /* show some infos about the specific si470x device */
if (si470x_get_all_registers(radio) < 0) {
retval = -EIO;
goto err_all;
@@ -1644,7 +1691,16 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
radio->registers[DEVICEID], radio->registers[CHIPID]);
- /* check if firmware is current */
+ /* get software and hardware versions */
+ if (si470x_get_scratch_page_versions(radio) < 0) {
+ retval = -EIO;
+ goto err_all;
+ }
+ printk(KERN_INFO DRIVER_NAME
+ ": software version %d, hardware version %d\n",
+ radio->software_version, radio->hardware_version);
+
+ /* check if device and firmware is current */
if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
< RADIO_SW_VERSION_CURRENT) {
printk(KERN_WARNING DRIVER_NAME
@@ -1657,7 +1713,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
": If you have some trouble using this driver,\n");
printk(KERN_WARNING DRIVER_NAME
": please report to V4L ML at "
- "video4linux-list@redhat.com\n");
+ "linux-media@vger.kernel.org\n");
}
/* set initial frequency */
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index 4d35308fc1ff..393623818ade 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -298,7 +298,8 @@ static int vidioc_querycap(struct file *file, void *priv,
strlcpy(v->driver, dev->dev.driver->name, sizeof(v->driver));
strlcpy(v->card, dev->name, sizeof(v->card));
- snprintf(v->bus_info, sizeof(v->bus_info), "I2C:%s", dev->dev.bus_id);
+ snprintf(v->bus_info, sizeof(v->bus_info),
+ "I2C:%s", dev_name(&dev->dev));
v->version = RADIO_VERSION;
v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index 0798d71abd00..5b007f5c74b2 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -27,16 +27,29 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
-#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
+#include <linux/mutex.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/spinlock.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+MODULE_AUTHOR("R.OFFERMANNS & others");
+MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
+MODULE_LICENSE("GPL");
+
+#ifndef CONFIG_RADIO_TERRATEC_PORT
+#define CONFIG_RADIO_TERRATEC_PORT 0x590
+#endif
+
+static int io = CONFIG_RADIO_TERRATEC_PORT;
+static int radio_nr = -1;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
static struct v4l2_queryctrl radio_qctrl[] = {
{
@@ -57,13 +70,6 @@ static struct v4l2_queryctrl radio_qctrl[] = {
}
};
-#ifndef CONFIG_RADIO_TERRATEC_PORT
-#define CONFIG_RADIO_TERRATEC_PORT 0x590
-#endif
-
-/**************** this ones are for the terratec *******************/
-#define BASEPORT 0x590
-#define VOLPORT 0x591
#define WRT_DIS 0x00
#define CLK_OFF 0x00
#define IIC_DATA 0x01
@@ -71,138 +77,124 @@ static struct v4l2_queryctrl radio_qctrl[] = {
#define DATA 0x04
#define CLK_ON 0x08
#define WRT_EN 0x10
-/*******************************************************************/
-static int io = CONFIG_RADIO_TERRATEC_PORT;
-static int radio_nr = -1;
-static spinlock_t lock;
-
-struct tt_device
+struct terratec
{
- unsigned long in_use;
- int port;
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
int curvol;
unsigned long curfreq;
int muted;
+ struct mutex lock;
};
+static struct terratec terratec_card;
/* local things */
-static void cardWriteVol(int volume)
+static void tt_write_vol(struct terratec *tt, int volume)
{
int i;
- volume = volume+(volume * 32); // change both channels
- spin_lock(&lock);
- for (i=0;i<8;i++)
- {
- if (volume & (0x80>>i))
- outb(0x80, VOLPORT);
- else outb(0x00, VOLPORT);
+
+ volume = volume + (volume * 32); /* change both channels */
+ mutex_lock(&tt->lock);
+ for (i = 0; i < 8; i++) {
+ if (volume & (0x80 >> i))
+ outb(0x80, tt->io + 1);
+ else
+ outb(0x00, tt->io + 1);
}
- spin_unlock(&lock);
+ mutex_unlock(&tt->lock);
}
-static void tt_mute(struct tt_device *dev)
+static void tt_mute(struct terratec *tt)
{
- dev->muted = 1;
- cardWriteVol(0);
+ tt->muted = 1;
+ tt_write_vol(tt, 0);
}
-static int tt_setvol(struct tt_device *dev, int vol)
+static int tt_setvol(struct terratec *tt, int vol)
{
-
-// printk(KERN_ERR "setvol called, vol = %d\n", vol);
-
- if(vol == dev->curvol) { /* requested volume = current */
- if (dev->muted) { /* user is unmuting the card */
- dev->muted = 0;
- cardWriteVol(vol); /* enable card */
+ if (vol == tt->curvol) { /* requested volume = current */
+ if (tt->muted) { /* user is unmuting the card */
+ tt->muted = 0;
+ tt_write_vol(tt, vol); /* enable card */
}
-
return 0;
}
- if(vol == 0) { /* volume = 0 means mute the card */
- cardWriteVol(0); /* "turn off card" by setting vol to 0 */
- dev->curvol = vol; /* track the volume state! */
+ if (vol == 0) { /* volume = 0 means mute the card */
+ tt_write_vol(tt, 0); /* "turn off card" by setting vol to 0 */
+ tt->curvol = vol; /* track the volume state! */
return 0;
}
- dev->muted = 0;
-
- cardWriteVol(vol);
-
- dev->curvol = vol;
-
+ tt->muted = 0;
+ tt_write_vol(tt, vol);
+ tt->curvol = vol;
return 0;
-
}
/* this is the worst part in this driver */
/* many more or less strange things are going on here, but hey, it works :) */
-static int tt_setfreq(struct tt_device *dev, unsigned long freq1)
+static int tt_setfreq(struct terratec *tt, unsigned long freq1)
{
int freq;
int i;
int p;
int temp;
long rest;
-
unsigned char buffer[25]; /* we have to bit shift 25 registers */
- freq = freq1/160; /* convert the freq. to a nice to handle value */
- for(i=24;i>-1;i--)
- buffer[i]=0;
- rest = freq*10+10700; /* i once had understood what is going on here */
+ mutex_lock(&tt->lock);
+
+ tt->curfreq = freq1;
+
+ freq = freq1 / 160; /* convert the freq. to a nice to handle value */
+ memset(buffer, 0, sizeof(buffer));
+
+ rest = freq * 10 + 10700; /* I once had understood what is going on here */
/* maybe some wise guy (friedhelm?) can comment this stuff */
- i=13;
- p=10;
- temp=102400;
- while (rest!=0)
- {
- if (rest%temp == rest)
+ i = 13;
+ p = 10;
+ temp = 102400;
+ while (rest != 0) {
+ if (rest % temp == rest)
buffer[i] = 0;
- else
- {
+ else {
buffer[i] = 1;
- rest = rest-temp;
+ rest = rest - temp;
}
i--;
p--;
- temp = temp/2;
+ temp = temp / 2;
}
- spin_lock(&lock);
-
- for (i=24;i>-1;i--) /* bit shift the values to the radiocard */
- {
- if (buffer[i]==1)
- {
- outb(WRT_EN|DATA, BASEPORT);
- outb(WRT_EN|DATA|CLK_ON , BASEPORT);
- outb(WRT_EN|DATA, BASEPORT);
- }
- else
- {
- outb(WRT_EN|0x00, BASEPORT);
- outb(WRT_EN|0x00|CLK_ON , BASEPORT);
+ for (i = 24; i > -1; i--) { /* bit shift the values to the radiocard */
+ if (buffer[i] == 1) {
+ outb(WRT_EN | DATA, tt->io);
+ outb(WRT_EN | DATA | CLK_ON, tt->io);
+ outb(WRT_EN | DATA, tt->io);
+ } else {
+ outb(WRT_EN | 0x00, tt->io);
+ outb(WRT_EN | 0x00 | CLK_ON, tt->io);
}
}
- outb(0x00, BASEPORT);
+ outb(0x00, tt->io);
- spin_unlock(&lock);
+ mutex_unlock(&tt->lock);
return 0;
}
-static int tt_getsigstr(struct tt_device *dev) /* TODO */
+static int tt_getsigstr(struct terratec *tt)
{
- if (inb(io) & 2) /* bit set = no signal present */
+ if (inb(tt->io) & 2) /* bit set = no signal present */
return 0;
return 1; /* signal present */
}
@@ -212,53 +204,50 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-terratec", sizeof(v->driver));
strlcpy(v->card, "ActiveRadio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct tt_device *tt = video_drvdata(file);
+ struct terratec *tt = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow = (87*16000);
- v->rangehigh = (108*16000);
+ v->rangelow = 87 * 16000;
+ v->rangehigh = 108 * 16000;
v->rxsubchans = V4L2_TUNER_SUB_MONO;
v->capability = V4L2_TUNER_CAP_LOW;
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = 0xFFFF*tt_getsigstr(tt);
+ v->signal = 0xFFFF * tt_getsigstr(tt);
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct tt_device *tt = video_drvdata(file);
+ struct terratec *tt = video_drvdata(file);
- tt->curfreq = f->frequency;
- tt_setfreq(tt, tt->curfreq);
+ tt_setfreq(tt, f->frequency);
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct tt_device *tt = video_drvdata(file);
+ struct terratec *tt = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = tt->curfreq;
@@ -272,8 +261,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
+ memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
return 0;
}
}
@@ -283,7 +271,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct tt_device *tt = video_drvdata(file);
+ struct terratec *tt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -302,7 +290,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct tt_device *tt = video_drvdata(file);
+ struct terratec *tt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -318,17 +306,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -337,36 +314,38 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static struct tt_device terratec_unit;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
-static int terratec_exclusive_open(struct file *file)
+static int terratec_open(struct file *file)
{
- return test_and_set_bit(0, &terratec_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int terratec_exclusive_release(struct file *file)
+static int terratec_release(struct file *file)
{
- clear_bit(0, &terratec_unit.in_use);
return 0;
}
static const struct v4l2_file_operations terratec_fops = {
.owner = THIS_MODULE,
- .open = terratec_exclusive_open,
- .release = terratec_exclusive_release,
+ .open = terratec_open,
+ .release = terratec_release,
.ioctl = video_ioctl2,
};
@@ -385,60 +364,63 @@ static const struct v4l2_ioctl_ops terratec_ioctl_ops = {
.vidioc_s_input = vidioc_s_input,
};
-static struct video_device terratec_radio = {
- .name = "TerraTec ActiveRadio",
- .fops = &terratec_fops,
- .ioctl_ops = &terratec_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __init terratec_init(void)
{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+ struct terratec *tt = &terratec_card;
+ struct v4l2_device *v4l2_dev = &tt->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "terratec", sizeof(v4l2_dev->name));
+ tt->io = io;
+ if (tt->io == -1) {
+ v4l2_err(v4l2_dev, "you must set an I/O address with io=0x590 or 0x591\n");
return -EINVAL;
}
- if (!request_region(io, 2, "terratec"))
- {
- printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io);
+ if (!request_region(tt->io, 2, "terratec")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", io);
return -EBUSY;
}
- video_set_drvdata(&terratec_radio, &terratec_unit);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(tt->io, 2);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
+
+ strlcpy(tt->vdev.name, v4l2_dev->name, sizeof(tt->vdev.name));
+ tt->vdev.v4l2_dev = v4l2_dev;
+ tt->vdev.fops = &terratec_fops;
+ tt->vdev.ioctl_ops = &terratec_ioctl_ops;
+ tt->vdev.release = video_device_release_empty;
+ video_set_drvdata(&tt->vdev, tt);
- spin_lock_init(&lock);
+ mutex_init(&tt->lock);
- if (video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io,2);
+ if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(&tt->v4l2_dev);
+ release_region(tt->io, 2);
return -EINVAL;
}
- printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver.\n");
+ v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n");
/* mute card - prevents noisy bootups */
-
- /* this ensures that the volume is all the way down */
- cardWriteVol(0);
- terratec_unit.curvol = 0;
-
+ tt_write_vol(tt, 0);
return 0;
}
-MODULE_AUTHOR("R.OFFERMANNS & others");
-MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
-MODULE_LICENSE("GPL");
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)");
-module_param(radio_nr, int, 0);
-
-static void __exit terratec_cleanup_module(void)
+static void __exit terratec_exit(void)
{
- video_unregister_device(&terratec_radio);
- release_region(io,2);
- printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n");
+ struct terratec *tt = &terratec_card;
+ struct v4l2_device *v4l2_dev = &tt->v4l2_dev;
+
+ video_unregister_device(&tt->vdev);
+ v4l2_device_unregister(&tt->v4l2_dev);
+ release_region(tt->io, 2);
+ v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver unloaded.\n");
}
module_init(terratec_init);
-module_exit(terratec_cleanup_module);
+module_exit(terratec_exit);
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index bdf9cb6a75f4..d1be6492a07b 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -19,49 +19,15 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/ioport.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <linux/io.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 2048,
- .default_value = 65535,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_AUDIO_BASS,
- .name = "Bass",
- .minimum = 0,
- .maximum = 65535,
- .step = 4370,
- .default_value = 32768,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_AUDIO_TREBLE,
- .name = "Treble",
- .minimum = 0,
- .maximum = 65535,
- .step = 4370,
- .default_value = 32768,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
-};
+MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
+MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
+MODULE_LICENSE("GPL");
/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
@@ -71,26 +37,41 @@ static struct v4l2_queryctrl radio_qctrl[] = {
static int io = CONFIG_RADIO_TRUST_PORT;
static int radio_nr = -1;
-static int ioval = 0xf;
-static __u16 curvol;
-static __u16 curbass;
-static __u16 curtreble;
-static unsigned long curfreq;
-static int curstereo;
-static int curmute;
-static unsigned long in_use;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct trust {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
+ int ioval;
+ __u16 curvol;
+ __u16 curbass;
+ __u16 curtreble;
+ int muted;
+ unsigned long curfreq;
+ int curstereo;
+ int curmute;
+ struct mutex lock;
+};
+
+static struct trust trust_card;
/* i2c addresses */
#define TDA7318_ADDR 0x88
#define TSA6060T_ADDR 0xc4
-#define TR_DELAY do { inb(io); inb(io); inb(io); } while(0)
-#define TR_SET_SCL outb(ioval |= 2, io)
-#define TR_CLR_SCL outb(ioval &= 0xfd, io)
-#define TR_SET_SDA outb(ioval |= 1, io)
-#define TR_CLR_SDA outb(ioval &= 0xfe, io)
+#define TR_DELAY do { inb(tr->io); inb(tr->io); inb(tr->io); } while (0)
+#define TR_SET_SCL outb(tr->ioval |= 2, tr->io)
+#define TR_CLR_SCL outb(tr->ioval &= 0xfd, tr->io)
+#define TR_SET_SDA outb(tr->ioval |= 1, tr->io)
+#define TR_CLR_SDA outb(tr->ioval &= 0xfe, tr->io)
-static void write_i2c(int n, ...)
+static void write_i2c(struct trust *tr, int n, ...)
{
unsigned char val, mask;
va_list args;
@@ -136,62 +117,77 @@ static void write_i2c(int n, ...)
va_end(args);
}
-static void tr_setvol(__u16 vol)
+static void tr_setvol(struct trust *tr, __u16 vol)
{
- curvol = vol / 2048;
- write_i2c(2, TDA7318_ADDR, curvol ^ 0x1f);
+ mutex_lock(&tr->lock);
+ tr->curvol = vol / 2048;
+ write_i2c(tr, 2, TDA7318_ADDR, tr->curvol ^ 0x1f);
+ mutex_unlock(&tr->lock);
}
static int basstreble2chip[15] = {
0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8
};
-static void tr_setbass(__u16 bass)
+static void tr_setbass(struct trust *tr, __u16 bass)
{
- curbass = bass / 4370;
- write_i2c(2, TDA7318_ADDR, 0x60 | basstreble2chip[curbass]);
+ mutex_lock(&tr->lock);
+ tr->curbass = bass / 4370;
+ write_i2c(tr, 2, TDA7318_ADDR, 0x60 | basstreble2chip[tr->curbass]);
+ mutex_unlock(&tr->lock);
}
-static void tr_settreble(__u16 treble)
+static void tr_settreble(struct trust *tr, __u16 treble)
{
- curtreble = treble / 4370;
- write_i2c(2, TDA7318_ADDR, 0x70 | basstreble2chip[curtreble]);
+ mutex_lock(&tr->lock);
+ tr->curtreble = treble / 4370;
+ write_i2c(tr, 2, TDA7318_ADDR, 0x70 | basstreble2chip[tr->curtreble]);
+ mutex_unlock(&tr->lock);
}
-static void tr_setstereo(int stereo)
+static void tr_setstereo(struct trust *tr, int stereo)
{
- curstereo = !!stereo;
- ioval = (ioval & 0xfb) | (!curstereo << 2);
- outb(ioval, io);
+ mutex_lock(&tr->lock);
+ tr->curstereo = !!stereo;
+ tr->ioval = (tr->ioval & 0xfb) | (!tr->curstereo << 2);
+ outb(tr->ioval, tr->io);
+ mutex_unlock(&tr->lock);
}
-static void tr_setmute(int mute)
+static void tr_setmute(struct trust *tr, int mute)
{
- curmute = !!mute;
- ioval = (ioval & 0xf7) | (curmute << 3);
- outb(ioval, io);
+ mutex_lock(&tr->lock);
+ tr->curmute = !!mute;
+ tr->ioval = (tr->ioval & 0xf7) | (tr->curmute << 3);
+ outb(tr->ioval, tr->io);
+ mutex_unlock(&tr->lock);
}
-static int tr_getsigstr(void)
+static int tr_getsigstr(struct trust *tr)
{
int i, v;
- for(i = 0, v = 0; i < 100; i++) v |= inb(io);
- return (v & 1)? 0 : 0xffff;
+ mutex_lock(&tr->lock);
+ for (i = 0, v = 0; i < 100; i++)
+ v |= inb(tr->io);
+ mutex_unlock(&tr->lock);
+ return (v & 1) ? 0 : 0xffff;
}
-static int tr_getstereo(void)
+static int tr_getstereo(struct trust *tr)
{
/* don't know how to determine it, just return the setting */
- return curstereo;
+ return tr->curstereo;
}
-static void tr_setfreq(unsigned long f)
+static void tr_setfreq(struct trust *tr, unsigned long f)
{
+ mutex_lock(&tr->lock);
+ tr->curfreq = f;
f /= 160; /* Convert to 10 kHz units */
- f += 1070; /* Add 10.7 MHz IF */
-
- write_i2c(5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
+ f += 1070; /* Add 10.7 MHz IF */
+ write_i2c(tr, 5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
+ mutex_unlock(&tr->lock);
}
static int vidioc_querycap(struct file *file, void *priv,
@@ -199,68 +195,75 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-trust", sizeof(v->driver));
strlcpy(v->card, "Trust FM Radio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
+ struct trust *tr = video_drvdata(file);
+
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow = (87.5*16000);
- v->rangehigh = (108*16000);
- v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->rangelow = 87.5 * 16000;
+ v->rangehigh = 108 * 16000;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
v->capability = V4L2_TUNER_CAP_LOW;
- if (tr_getstereo())
+ if (tr_getstereo(tr))
v->audmode = V4L2_TUNER_MODE_STEREO;
else
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = tr_getsigstr();
+ v->signal = tr_getsigstr(tr);
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
+ struct trust *tr = video_drvdata(file);
+ if (v->index)
+ return -EINVAL;
+ tr_setstereo(tr, v->audmode == V4L2_TUNER_MODE_STEREO);
return 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- curfreq = f->frequency;
- tr_setfreq(curfreq);
+ struct trust *tr = video_drvdata(file);
+
+ tr_setfreq(tr, f->frequency);
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
+ struct trust *tr = video_drvdata(file);
+
f->type = V4L2_TUNER_RADIO;
- f->frequency = curfreq;
+ f->frequency = tr->curfreq;
return 0;
}
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 2048, 65535);
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 4370, 32768);
}
return -EINVAL;
}
@@ -268,18 +271,20 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
+ struct trust *tr = video_drvdata(file);
+
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- ctrl->value = curmute;
+ ctrl->value = tr->curmute;
return 0;
case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = curvol * 2048;
+ ctrl->value = tr->curvol * 2048;
return 0;
case V4L2_CID_AUDIO_BASS:
- ctrl->value = curbass * 4370;
+ ctrl->value = tr->curbass * 4370;
return 0;
case V4L2_CID_AUDIO_TREBLE:
- ctrl->value = curtreble * 4370;
+ ctrl->value = tr->curtreble * 4370;
return 0;
}
return -EINVAL;
@@ -288,34 +293,25 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
+ struct trust *tr = video_drvdata(file);
+
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- tr_setmute(ctrl->value);
+ tr_setmute(tr, ctrl->value);
return 0;
case V4L2_CID_AUDIO_VOLUME:
- tr_setvol(ctrl->value);
+ tr_setvol(tr, ctrl->value);
return 0;
case V4L2_CID_AUDIO_BASS:
- tr_setbass(ctrl->value);
+ tr_setbass(tr, ctrl->value);
return 0;
case V4L2_CID_AUDIO_TREBLE:
- tr_settreble(ctrl->value);
+ tr_settreble(tr, ctrl->value);
return 0;
}
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -324,34 +320,38 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
+ return i ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
static int vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
- return 0;
+ return a->index ? -EINVAL : 0;
}
-static int trust_exclusive_open(struct file *file)
+static int trust_open(struct file *file)
{
- return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
+ return 0;
}
-static int trust_exclusive_release(struct file *file)
+static int trust_release(struct file *file)
{
- clear_bit(0, &in_use);
return 0;
}
static const struct v4l2_file_operations trust_fops = {
.owner = THIS_MODULE,
- .open = trust_exclusive_open,
- .release = trust_exclusive_release,
+ .open = trust_open,
+ .release = trust_release,
.ioctl = video_ioctl2,
};
@@ -370,59 +370,72 @@ static const struct v4l2_ioctl_ops trust_ioctl_ops = {
.vidioc_s_input = vidioc_s_input,
};
-static struct video_device trust_radio = {
- .name = "Trust FM Radio",
- .fops = &trust_fops,
- .ioctl_ops = &trust_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __init trust_init(void)
{
- if(io == -1) {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+ struct trust *tr = &trust_card;
+ struct v4l2_device *v4l2_dev = &tr->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "trust", sizeof(v4l2_dev->name));
+ tr->io = io;
+ tr->ioval = 0xf;
+ mutex_init(&tr->lock);
+
+ if (tr->io == -1) {
+ v4l2_err(v4l2_dev, "You must set an I/O address with io=0x0x350 or 0x358\n");
return -EINVAL;
}
- if(!request_region(io, 2, "Trust FM Radio")) {
- printk(KERN_ERR "trust: port 0x%x already in use\n", io);
+ if (!request_region(tr->io, 2, "Trust FM Radio")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", tr->io);
return -EBUSY;
}
- if (video_register_device(&trust_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 2);
+
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(tr->io, 2);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
+
+ strlcpy(tr->vdev.name, v4l2_dev->name, sizeof(tr->vdev.name));
+ tr->vdev.v4l2_dev = v4l2_dev;
+ tr->vdev.fops = &trust_fops;
+ tr->vdev.ioctl_ops = &trust_ioctl_ops;
+ tr->vdev.release = video_device_release_empty;
+ video_set_drvdata(&tr->vdev, tr);
+
+ if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(tr->io, 2);
return -EINVAL;
}
- printk(KERN_INFO "Trust FM Radio card driver v1.0.\n");
+ v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n");
- write_i2c(2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */
- write_i2c(2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */
- write_i2c(2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */
- write_i2c(2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */
- write_i2c(2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */
+ write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */
+ write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */
+ write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */
+ write_i2c(tr, 2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */
+ write_i2c(tr, 2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */
- tr_setvol(0x8000);
- tr_setbass(0x8000);
- tr_settreble(0x8000);
- tr_setstereo(1);
+ tr_setvol(tr, 0xffff);
+ tr_setbass(tr, 0x8000);
+ tr_settreble(tr, 0x8000);
+ tr_setstereo(tr, 1);
/* mute card - prevents noisy bootups */
- tr_setmute(1);
+ tr_setmute(tr, 1);
return 0;
}
-MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
-MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)");
-module_param(radio_nr, int, 0);
-
static void __exit cleanup_trust_module(void)
{
- video_unregister_device(&trust_radio);
- release_region(io, 2);
+ struct trust *tr = &trust_card;
+
+ video_unregister_device(&tr->vdev);
+ v4l2_device_unregister(&tr->v4l2_dev);
+ release_region(tr->io, 2);
}
module_init(trust_init);
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index 5c3b319dab37..92d923c7f360 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -34,37 +34,15 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
-#include <linux/proc_fs.h> /* radio card status report */
-#include <linux/seq_file.h>
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,1,1)
-#define BANNER "Typhoon Radio Card driver v0.1.1\n"
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 1<<14,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
-
+MODULE_AUTHOR("Dr. Henrik Seidel");
+MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio).");
+MODULE_LICENSE("GPL");
#ifndef CONFIG_RADIO_TYPHOON_PORT
#define CONFIG_RADIO_TYPHOON_PORT -1
@@ -74,13 +52,26 @@ static struct v4l2_queryctrl radio_qctrl[] = {
#define CONFIG_RADIO_TYPHOON_MUTEFREQ 0
#endif
-#ifndef CONFIG_PROC_FS
-#undef CONFIG_RADIO_TYPHOON_PROC_FS
-#endif
+static int io = CONFIG_RADIO_TYPHOON_PORT;
+static int radio_nr = -1;
-struct typhoon_device {
- unsigned long in_use;
- int iobase;
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
+
+module_param(radio_nr, int, 0);
+
+static unsigned long mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ;
+module_param(mutefreq, ulong, 0);
+MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
+
+#define RADIO_VERSION KERNEL_VERSION(0, 1, 1)
+
+#define BANNER "Typhoon Radio Card driver v0.1.1\n"
+
+struct typhoon {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
int curvol;
int muted;
unsigned long curfreq;
@@ -88,25 +79,19 @@ struct typhoon_device {
struct mutex lock;
};
-static void typhoon_setvol_generic(struct typhoon_device *dev, int vol);
-static int typhoon_setfreq_generic(struct typhoon_device *dev,
- unsigned long frequency);
-static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency);
-static void typhoon_mute(struct typhoon_device *dev);
-static void typhoon_unmute(struct typhoon_device *dev);
-static int typhoon_setvol(struct typhoon_device *dev, int vol);
+static struct typhoon typhoon_card;
-static void typhoon_setvol_generic(struct typhoon_device *dev, int vol)
+static void typhoon_setvol_generic(struct typhoon *dev, int vol)
{
mutex_lock(&dev->lock);
vol >>= 14; /* Map 16 bit to 2 bit */
vol &= 3;
- outb_p(vol / 2, dev->iobase); /* Set the volume, high bit. */
- outb_p(vol % 2, dev->iobase + 2); /* Set the volume, low bit. */
+ outb_p(vol / 2, dev->io); /* Set the volume, high bit. */
+ outb_p(vol % 2, dev->io + 2); /* Set the volume, low bit. */
mutex_unlock(&dev->lock);
}
-static int typhoon_setfreq_generic(struct typhoon_device *dev,
+static int typhoon_setfreq_generic(struct typhoon *dev,
unsigned long frequency)
{
unsigned long outval;
@@ -130,22 +115,22 @@ static int typhoon_setfreq_generic(struct typhoon_device *dev,
outval -= (10 * x * x + 10433) / 20866;
outval += 4 * x - 11505;
- outb_p((outval >> 8) & 0x01, dev->iobase + 4);
- outb_p(outval >> 9, dev->iobase + 6);
- outb_p(outval & 0xff, dev->iobase + 8);
+ outb_p((outval >> 8) & 0x01, dev->io + 4);
+ outb_p(outval >> 9, dev->io + 6);
+ outb_p(outval & 0xff, dev->io + 8);
mutex_unlock(&dev->lock);
return 0;
}
-static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency)
+static int typhoon_setfreq(struct typhoon *dev, unsigned long frequency)
{
typhoon_setfreq_generic(dev, frequency);
dev->curfreq = frequency;
return 0;
}
-static void typhoon_mute(struct typhoon_device *dev)
+static void typhoon_mute(struct typhoon *dev)
{
if (dev->muted == 1)
return;
@@ -154,7 +139,7 @@ static void typhoon_mute(struct typhoon_device *dev)
dev->muted = 1;
}
-static void typhoon_unmute(struct typhoon_device *dev)
+static void typhoon_unmute(struct typhoon *dev)
{
if (dev->muted == 0)
return;
@@ -163,7 +148,7 @@ static void typhoon_unmute(struct typhoon_device *dev)
dev->muted = 0;
}
-static int typhoon_setvol(struct typhoon_device *dev, int vol)
+static int typhoon_setvol(struct typhoon *dev, int vol)
{
if (dev->muted && vol != 0) { /* user is unmuting the card */
dev->curvol = vol;
@@ -188,9 +173,9 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-typhoon", sizeof(v->driver));
strlcpy(v->card, "Typhoon Radio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
@@ -200,10 +185,10 @@ static int vidioc_g_tuner(struct file *file, void *priv,
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow = (87.5*16000);
- v->rangehigh = (108*16000);
+ v->rangelow = 87.5 * 16000;
+ v->rangehigh = 108 * 16000;
v->rxsubchans = V4L2_TUNER_SUB_MONO;
v->capability = V4L2_TUNER_CAP_LOW;
v->audmode = V4L2_TUNER_MODE_MONO;
@@ -214,44 +199,37 @@ static int vidioc_g_tuner(struct file *file, void *priv,
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
-
- return 0;
+ return v->index ? -EINVAL : 0;
}
-static int vidioc_s_frequency(struct file *file, void *priv,
+static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct typhoon_device *typhoon = video_drvdata(file);
+ struct typhoon *dev = video_drvdata(file);
- typhoon->curfreq = f->frequency;
- typhoon_setfreq(typhoon, typhoon->curfreq);
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = dev->curfreq;
return 0;
}
-static int vidioc_g_frequency(struct file *file, void *priv,
+static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct typhoon_device *typhoon = video_drvdata(file);
-
- f->type = V4L2_TUNER_RADIO;
- f->frequency = typhoon->curfreq;
+ struct typhoon *dev = video_drvdata(file);
+ dev->curfreq = f->frequency;
+ typhoon_setfreq(dev, dev->curfreq);
return 0;
}
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 16384, 65535);
}
return -EINVAL;
}
@@ -259,14 +237,14 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct typhoon_device *typhoon = video_drvdata(file);
+ struct typhoon *dev = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- ctrl->value = typhoon->muted;
+ ctrl->value = dev->muted;
return 0;
case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = typhoon->curvol;
+ ctrl->value = dev->curvol;
return 0;
}
return -EINVAL;
@@ -275,33 +253,22 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl (struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct typhoon_device *typhoon = video_drvdata(file);
+ struct typhoon *dev = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value)
- typhoon_mute(typhoon);
+ typhoon_mute(dev);
else
- typhoon_unmute(typhoon);
+ typhoon_unmute(dev);
return 0;
case V4L2_CID_AUDIO_VOLUME:
- typhoon_setvol(typhoon, ctrl->value);
+ typhoon_setvol(dev, ctrl->value);
return 0;
}
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -310,45 +277,62 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
+ return i ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
static int vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
- return 0;
+ return a->index ? -EINVAL : 0;
}
-static struct typhoon_device typhoon_unit =
+static int vidioc_log_status(struct file *file, void *priv)
{
- .iobase = CONFIG_RADIO_TYPHOON_PORT,
- .curfreq = CONFIG_RADIO_TYPHOON_MUTEFREQ,
- .mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ,
-};
+ struct typhoon *dev = video_drvdata(file);
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+
+ v4l2_info(v4l2_dev, BANNER);
+#ifdef MODULE
+ v4l2_info(v4l2_dev, "Load type: Driver loaded as a module\n\n");
+#else
+ v4l2_info(v4l2_dev, "Load type: Driver compiled into kernel\n\n");
+#endif
+ v4l2_info(v4l2_dev, "frequency = %lu kHz\n", dev->curfreq >> 4);
+ v4l2_info(v4l2_dev, "volume = %d\n", dev->curvol);
+ v4l2_info(v4l2_dev, "mute = %s\n", dev->muted ? "on" : "off");
+ v4l2_info(v4l2_dev, "io = 0x%x\n", dev->io);
+ v4l2_info(v4l2_dev, "mute frequency = %lu kHz\n", dev->mutefreq >> 4);
+ return 0;
+}
-static int typhoon_exclusive_open(struct file *file)
+static int typhoon_open(struct file *file)
{
- return test_and_set_bit(0, &typhoon_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int typhoon_exclusive_release(struct file *file)
+static int typhoon_release(struct file *file)
{
- clear_bit(0, &typhoon_unit.in_use);
return 0;
}
static const struct v4l2_file_operations typhoon_fops = {
.owner = THIS_MODULE,
- .open = typhoon_exclusive_open,
- .release = typhoon_exclusive_release,
+ .open = typhoon_open,
+ .release = typhoon_release,
.ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops typhoon_ioctl_ops = {
+ .vidioc_log_status = vidioc_log_status,
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -363,125 +347,72 @@ static const struct v4l2_ioctl_ops typhoon_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device typhoon_radio = {
- .name = "Typhoon Radio",
- .fops = &typhoon_fops,
- .ioctl_ops = &typhoon_ioctl_ops,
- .release = video_device_release_empty,
-};
-
-#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
-
-static int typhoon_proc_show(struct seq_file *m, void *v)
-{
- #ifdef MODULE
- #define MODULEPROCSTRING "Driver loaded as a module"
- #else
- #define MODULEPROCSTRING "Driver compiled into kernel"
- #endif
-
- seq_puts(m, BANNER);
- seq_puts(m, "Load type: " MODULEPROCSTRING "\n\n");
- seq_printf(m, "frequency = %lu kHz\n",
- typhoon_unit.curfreq >> 4);
- seq_printf(m, "volume = %d\n", typhoon_unit.curvol);
- seq_printf(m, "mute = %s\n", typhoon_unit.muted ?
- "on" : "off");
- seq_printf(m, "iobase = 0x%x\n", typhoon_unit.iobase);
- seq_printf(m, "mute frequency = %lu kHz\n",
- typhoon_unit.mutefreq >> 4);
- return 0;
-}
-
-static int typhoon_proc_open(struct inode *inode, struct file *file)
+static int __init typhoon_init(void)
{
- return single_open(file, typhoon_proc_show, NULL);
-}
-
-static const struct file_operations typhoon_proc_fops = {
- .owner = THIS_MODULE,
- .open = typhoon_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-#endif /* CONFIG_RADIO_TYPHOON_PROC_FS */
-
-MODULE_AUTHOR("Dr. Henrik Seidel");
-MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio).");
-MODULE_LICENSE("GPL");
-
-static int io = -1;
-static int radio_nr = -1;
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
-module_param(radio_nr, int, 0);
+ struct typhoon *dev = &typhoon_card;
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+ int res;
-#ifdef MODULE
-static unsigned long mutefreq;
-module_param(mutefreq, ulong, 0);
-MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
-#endif
+ strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name));
+ dev->io = io;
+ dev->curfreq = dev->mutefreq = mutefreq;
-static int __init typhoon_init(void)
-{
-#ifdef MODULE
- if (io == -1) {
- printk(KERN_ERR "radio-typhoon: You must set an I/O address with io=0x316 or io=0x336\n");
+ if (dev->io == -1) {
+ v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n");
return -EINVAL;
}
- typhoon_unit.iobase = io;
- if (mutefreq < 87000 || mutefreq > 108500) {
- printk(KERN_ERR "radio-typhoon: You must set a frequency (in kHz) used when muting the card,\n");
- printk(KERN_ERR "radio-typhoon: e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
+ if (dev->mutefreq < 87000 || dev->mutefreq > 108500) {
+ v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n");
+ v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
return -EINVAL;
}
- typhoon_unit.mutefreq = mutefreq;
-#endif /* MODULE */
-
- printk(KERN_INFO BANNER);
- mutex_init(&typhoon_unit.lock);
- io = typhoon_unit.iobase;
- if (!request_region(io, 8, "typhoon")) {
- printk(KERN_ERR "radio-typhoon: port 0x%x already in use\n",
- typhoon_unit.iobase);
+
+ mutex_init(&dev->lock);
+ if (!request_region(dev->io, 8, "typhoon")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n",
+ dev->io);
return -EBUSY;
}
- video_set_drvdata(&typhoon_radio, &typhoon_unit);
- if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 8);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(dev->io, 8);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
+ v4l2_info(v4l2_dev, BANNER);
+
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &typhoon_fops;
+ dev->vdev.ioctl_ops = &typhoon_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
+ if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(&dev->v4l2_dev);
+ release_region(dev->io, 8);
return -EINVAL;
}
- printk(KERN_INFO "radio-typhoon: port 0x%x.\n", typhoon_unit.iobase);
- printk(KERN_INFO "radio-typhoon: mute frequency is %lu kHz.\n",
- typhoon_unit.mutefreq);
- typhoon_unit.mutefreq <<= 4;
+ v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io);
+ v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", dev->mutefreq);
+ dev->mutefreq <<= 4;
/* mute card - prevents noisy bootups */
- typhoon_mute(&typhoon_unit);
-
-#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
- if (!proc_create("driver/radio-typhoon", 0, NULL, &typhoon_proc_fops))
- printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n");
-#endif
+ typhoon_mute(dev);
return 0;
}
-static void __exit typhoon_cleanup_module(void)
+static void __exit typhoon_exit(void)
{
+ struct typhoon *dev = &typhoon_card;
-#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
- remove_proc_entry("driver/radio-typhoon", NULL);
-#endif
-
- video_unregister_device(&typhoon_radio);
- release_region(io, 8);
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ release_region(dev->io, 8);
}
module_init(typhoon_init);
-module_exit(typhoon_cleanup_module);
+module_exit(typhoon_exit);
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index d2ac17eeec5f..1f85f2024dc0 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -33,33 +33,16 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay, msleep */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
+#include <linux/mutex.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 4096,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
+MODULE_AUTHOR("C.van Schaik");
+MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
+MODULE_LICENSE("GPL");
#ifndef CONFIG_RADIO_ZOLTRIX_PORT
#define CONFIG_RADIO_ZOLTRIX_PORT -1
@@ -68,9 +51,16 @@ static struct v4l2_queryctrl radio_qctrl[] = {
static int io = CONFIG_RADIO_ZOLTRIX_PORT;
static int radio_nr = -1;
-struct zol_device {
- unsigned long in_use;
- int port;
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct zoltrix {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
int curvol;
unsigned long curfreq;
int muted;
@@ -78,161 +68,158 @@ struct zol_device {
struct mutex lock;
};
-static int zol_setvol(struct zol_device *dev, int vol)
+static struct zoltrix zoltrix_card;
+
+static int zol_setvol(struct zoltrix *zol, int vol)
{
- dev->curvol = vol;
- if (dev->muted)
+ zol->curvol = vol;
+ if (zol->muted)
return 0;
- mutex_lock(&dev->lock);
+ mutex_lock(&zol->lock);
if (vol == 0) {
- outb(0, io);
- outb(0, io);
- inb(io + 3); /* Zoltrix needs to be read to confirm */
- mutex_unlock(&dev->lock);
+ outb(0, zol->io);
+ outb(0, zol->io);
+ inb(zol->io + 3); /* Zoltrix needs to be read to confirm */
+ mutex_unlock(&zol->lock);
return 0;
}
- outb(dev->curvol-1, io);
+ outb(zol->curvol-1, zol->io);
msleep(10);
- inb(io + 2);
- mutex_unlock(&dev->lock);
+ inb(zol->io + 2);
+ mutex_unlock(&zol->lock);
return 0;
}
-static void zol_mute(struct zol_device *dev)
+static void zol_mute(struct zoltrix *zol)
{
- dev->muted = 1;
- mutex_lock(&dev->lock);
- outb(0, io);
- outb(0, io);
- inb(io + 3); /* Zoltrix needs to be read to confirm */
- mutex_unlock(&dev->lock);
+ zol->muted = 1;
+ mutex_lock(&zol->lock);
+ outb(0, zol->io);
+ outb(0, zol->io);
+ inb(zol->io + 3); /* Zoltrix needs to be read to confirm */
+ mutex_unlock(&zol->lock);
}
-static void zol_unmute(struct zol_device *dev)
+static void zol_unmute(struct zoltrix *zol)
{
- dev->muted = 0;
- zol_setvol(dev, dev->curvol);
+ zol->muted = 0;
+ zol_setvol(zol, zol->curvol);
}
-static int zol_setfreq(struct zol_device *dev, unsigned long freq)
+static int zol_setfreq(struct zoltrix *zol, unsigned long freq)
{
/* tunes the radio to the desired frequency */
+ struct v4l2_device *v4l2_dev = &zol->v4l2_dev;
unsigned long long bitmask, f, m;
- unsigned int stereo = dev->stereo;
+ unsigned int stereo = zol->stereo;
int i;
if (freq == 0) {
- printk(KERN_WARNING "zoltrix: received zero freq. Failed to set.\n");
+ v4l2_warn(v4l2_dev, "cannot set a frequency of 0.\n");
return -EINVAL;
}
m = (freq / 160 - 8800) * 2;
- f = (unsigned long long) m + 0x4d1c;
+ f = (unsigned long long)m + 0x4d1c;
bitmask = 0xc480402c10080000ull;
i = 45;
- mutex_lock(&dev->lock);
+ mutex_lock(&zol->lock);
- outb(0, io);
- outb(0, io);
- inb(io + 3); /* Zoltrix needs to be read to confirm */
+ zol->curfreq = freq;
- outb(0x40, io);
- outb(0xc0, io);
+ outb(0, zol->io);
+ outb(0, zol->io);
+ inb(zol->io + 3); /* Zoltrix needs to be read to confirm */
- bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ ( stereo << 31));
+ outb(0x40, zol->io);
+ outb(0xc0, zol->io);
+
+ bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ (stereo << 31));
while (i--) {
if ((bitmask & 0x8000000000000000ull) != 0) {
- outb(0x80, io);
+ outb(0x80, zol->io);
udelay(50);
- outb(0x00, io);
+ outb(0x00, zol->io);
udelay(50);
- outb(0x80, io);
+ outb(0x80, zol->io);
udelay(50);
} else {
- outb(0xc0, io);
+ outb(0xc0, zol->io);
udelay(50);
- outb(0x40, io);
+ outb(0x40, zol->io);
udelay(50);
- outb(0xc0, io);
+ outb(0xc0, zol->io);
udelay(50);
}
bitmask *= 2;
}
/* termination sequence */
- outb(0x80, io);
- outb(0xc0, io);
- outb(0x40, io);
+ outb(0x80, zol->io);
+ outb(0xc0, zol->io);
+ outb(0x40, zol->io);
udelay(1000);
- inb(io+2);
+ inb(zol->io + 2);
udelay(1000);
- if (dev->muted)
- {
- outb(0, io);
- outb(0, io);
- inb(io + 3);
+ if (zol->muted) {
+ outb(0, zol->io);
+ outb(0, zol->io);
+ inb(zol->io + 3);
udelay(1000);
}
- mutex_unlock(&dev->lock);
+ mutex_unlock(&zol->lock);
- if(!dev->muted)
- {
- zol_setvol(dev, dev->curvol);
- }
+ if (!zol->muted)
+ zol_setvol(zol, zol->curvol);
return 0;
}
/* Get signal strength */
-
-static int zol_getsigstr(struct zol_device *dev)
+static int zol_getsigstr(struct zoltrix *zol)
{
int a, b;
- mutex_lock(&dev->lock);
- outb(0x00, io); /* This stuff I found to do nothing */
- outb(dev->curvol, io);
+ mutex_lock(&zol->lock);
+ outb(0x00, zol->io); /* This stuff I found to do nothing */
+ outb(zol->curvol, zol->io);
msleep(20);
- a = inb(io);
+ a = inb(zol->io);
msleep(10);
- b = inb(io);
+ b = inb(zol->io);
- mutex_unlock(&dev->lock);
+ mutex_unlock(&zol->lock);
if (a != b)
- return (0);
+ return 0;
- if ((a == 0xcf) || (a == 0xdf) /* I found this out by playing */
- || (a == 0xef)) /* with a binary scanner on the card io */
- return (1);
- return (0);
+ /* I found this out by playing with a binary scanner on the card io */
+ return a == 0xcf || a == 0xdf || a == 0xef;
}
-static int zol_is_stereo (struct zol_device *dev)
+static int zol_is_stereo(struct zoltrix *zol)
{
int x1, x2;
- mutex_lock(&dev->lock);
+ mutex_lock(&zol->lock);
- outb(0x00, io);
- outb(dev->curvol, io);
+ outb(0x00, zol->io);
+ outb(zol->curvol, zol->io);
msleep(20);
- x1 = inb(io);
+ x1 = inb(zol->io);
msleep(10);
- x2 = inb(io);
+ x2 = inb(zol->io);
- mutex_unlock(&dev->lock);
+ mutex_unlock(&zol->lock);
- if ((x1 == x2) && (x1 == 0xcf))
- return 1;
- return 0;
+ return x1 == x2 && x1 == 0xcf;
}
static int vidioc_querycap(struct file *file, void *priv,
@@ -240,59 +227,54 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-zoltrix", sizeof(v->driver));
strlcpy(v->card, "Zoltrix Radio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct zol_device *zol = video_drvdata(file);
+ struct zoltrix *zol = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow = (88*16000);
- v->rangehigh = (108*16000);
- v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->rangelow = 88 * 16000;
+ v->rangehigh = 108 * 16000;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
v->capability = V4L2_TUNER_CAP_LOW;
if (zol_is_stereo(zol))
v->audmode = V4L2_TUNER_MODE_STEREO;
else
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = 0xFFFF*zol_getsigstr(zol);
+ v->signal = 0xFFFF * zol_getsigstr(zol);
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct zol_device *zol = video_drvdata(file);
+ struct zoltrix *zol = video_drvdata(file);
- zol->curfreq = f->frequency;
- if (zol_setfreq(zol, zol->curfreq) != 0) {
- printk(KERN_WARNING "zoltrix: Set frequency failed.\n");
+ if (zol_setfreq(zol, f->frequency) != 0)
return -EINVAL;
- }
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct zol_device *zol = video_drvdata(file);
+ struct zoltrix *zol = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = zol->curfreq;
@@ -302,14 +284,11 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 4096, 65535);
}
return -EINVAL;
}
@@ -317,7 +296,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct zol_device *zol = video_drvdata(file);
+ struct zoltrix *zol = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -333,7 +312,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct zol_device *zol = video_drvdata(file);
+ struct zoltrix *zol = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -341,43 +320,30 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
zol_mute(zol);
else {
zol_unmute(zol);
- zol_setvol(zol,zol->curvol);
+ zol_setvol(zol, zol->curvol);
}
return 0;
case V4L2_CID_AUDIO_VOLUME:
- zol_setvol(zol,ctrl->value/4096);
+ zol_setvol(zol, ctrl->value / 4096);
return 0;
}
zol->stereo = 1;
- if (zol_setfreq(zol, zol->curfreq) != 0) {
- printk(KERN_WARNING "zoltrix: Set frequency failed.\n");
+ if (zol_setfreq(zol, zol->curfreq) != 0)
return -EINVAL;
- }
#if 0
/* FIXME: Implement stereo/mono switch on V4L2 */
- if (v->mode & VIDEO_SOUND_STEREO) {
- zol->stereo = 1;
- zol_setfreq(zol, zol->curfreq);
- }
- if (v->mode & VIDEO_SOUND_MONO) {
- zol->stereo = 0;
- zol_setfreq(zol, zol->curfreq);
- }
+ if (v->mode & VIDEO_SOUND_STEREO) {
+ zol->stereo = 1;
+ zol_setfreq(zol, zol->curfreq);
+ }
+ if (v->mode & VIDEO_SOUND_MONO) {
+ zol->stereo = 0;
+ zol_setfreq(zol, zol->curfreq);
+ }
#endif
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -386,37 +352,39 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static struct zol_device zoltrix_unit;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
-static int zoltrix_exclusive_open(struct file *file)
+static int zoltrix_open(struct file *file)
{
- return test_and_set_bit(0, &zoltrix_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int zoltrix_exclusive_release(struct file *file)
+static int zoltrix_release(struct file *file)
{
- clear_bit(0, &zoltrix_unit.in_use);
return 0;
}
static const struct v4l2_file_operations zoltrix_fops =
{
.owner = THIS_MODULE,
- .open = zoltrix_exclusive_open,
- .release = zoltrix_exclusive_release,
+ .open = zoltrix_open,
+ .release = zoltrix_release,
.ioctl = video_ioctl2,
};
@@ -435,67 +403,75 @@ static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device zoltrix_radio = {
- .name = "Zoltrix Radio Plus",
- .fops = &zoltrix_fops,
- .ioctl_ops = &zoltrix_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __init zoltrix_init(void)
{
- if (io == -1) {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+ struct zoltrix *zol = &zoltrix_card;
+ struct v4l2_device *v4l2_dev = &zol->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "zoltrix", sizeof(v4l2_dev->name));
+ zol->io = io;
+ if (zol->io == -1) {
+ v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or 0x30c\n");
return -EINVAL;
}
- if ((io != 0x20c) && (io != 0x30c)) {
- printk(KERN_ERR "zoltrix: invalid port, try 0x20c or 0x30c\n");
+ if (zol->io != 0x20c && zol->io != 0x30c) {
+ v4l2_err(v4l2_dev, "invalid port, try 0x20c or 0x30c\n");
return -ENXIO;
}
- video_set_drvdata(&zoltrix_radio, &zoltrix_unit);
- if (!request_region(io, 2, "zoltrix")) {
- printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io);
+ if (!request_region(zol->io, 2, "zoltrix")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", zol->io);
return -EBUSY;
}
- if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 2);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(zol->io, 2);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
+
+ strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
+ zol->vdev.v4l2_dev = v4l2_dev;
+ zol->vdev.fops = &zoltrix_fops;
+ zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
+ zol->vdev.release = video_device_release_empty;
+ video_set_drvdata(&zol->vdev, zol);
+
+ if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(zol->io, 2);
return -EINVAL;
}
- printk(KERN_INFO "Zoltrix Radio Plus card driver.\n");
+ v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
- mutex_init(&zoltrix_unit.lock);
+ mutex_init(&zol->lock);
/* mute card - prevents noisy bootups */
/* this ensures that the volume is all the way down */
- outb(0, io);
- outb(0, io);
+ outb(0, zol->io);
+ outb(0, zol->io);
msleep(20);
- inb(io + 3);
+ inb(zol->io + 3);
- zoltrix_unit.curvol = 0;
- zoltrix_unit.stereo = 1;
+ zol->curvol = 0;
+ zol->stereo = 1;
return 0;
}
-MODULE_AUTHOR("C.van Schaik");
-MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
-module_param(radio_nr, int, 0);
-
-static void __exit zoltrix_cleanup_module(void)
+static void __exit zoltrix_exit(void)
{
- video_unregister_device(&zoltrix_radio);
- release_region(io, 2);
+ struct zoltrix *zol = &zoltrix_card;
+
+ video_unregister_device(&zol->vdev);
+ v4l2_device_unregister(&zol->v4l2_dev);
+ release_region(zol->io, 2);
}
module_init(zoltrix_init);
-module_exit(zoltrix_cleanup_module);
+module_exit(zoltrix_exit);
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 19cf3b8f67c4..76bad5819592 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -249,11 +249,25 @@ config VIDEO_VP27SMPX
To compile this driver as a module, choose M here: the
module will be called vp27smpx.
+comment "RDS decoders"
+
+config VIDEO_SAA6588
+ tristate "SAA6588 Radio Chip RDS decoder support"
+ depends on VIDEO_V4L2 && I2C
+
+ help
+ Support for this Radio Data System (RDS) decoder. This allows
+ seeing radio station identification transmitted using this
+ standard.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa6588.
+
comment "Video decoders"
config VIDEO_BT819
tristate "BT819A VideoStream decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for BT819A video decoder.
@@ -262,7 +276,7 @@ config VIDEO_BT819
config VIDEO_BT856
tristate "BT856 VideoStream decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for BT856 video decoder.
@@ -271,7 +285,7 @@ config VIDEO_BT856
config VIDEO_BT866
tristate "BT866 VideoStream decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for BT866 video decoder.
@@ -280,7 +294,7 @@ config VIDEO_BT866
config VIDEO_KS0127
tristate "KS0127 video decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for KS0127 video decoder.
@@ -307,38 +321,18 @@ config VIDEO_TCM825X
config VIDEO_SAA7110
tristate "Philips SAA7110 video decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Philips SAA7110 video decoders.
To compile this driver as a module, choose M here: the
module will be called saa7110.
-config VIDEO_SAA7111
- tristate "Philips SAA7111 video decoder"
- depends on VIDEO_V4L1 && I2C
- ---help---
- Support for the Philips SAA711 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7111.
-
-config VIDEO_SAA7114
- tristate "Philips SAA7114 video decoder"
- depends on VIDEO_V4L1 && I2C
- ---help---
- Support for the Philips SAA7114 video decoder. This driver
- is used only on Zoran driver and should be moved soon to
- SAA711x module.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7114.
-
config VIDEO_SAA711X
- tristate "Philips SAA7113/4/5 video decoders"
+ tristate "Philips SAA7111/3/4/5 video decoders"
depends on VIDEO_V4L2 && I2C
---help---
- Support for the Philips SAA7113/4/5 video decoders.
+ Support for the Philips SAA7111/3/4/5 video decoders.
To compile this driver as a module, choose M here: the
module will be called saa7115.
@@ -383,7 +377,7 @@ config VIDEO_TVP5150
config VIDEO_VPX3220
tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for VPX322x video decoders.
@@ -421,7 +415,7 @@ config VIDEO_SAA7127
config VIDEO_SAA7185
tristate "Philips SAA7185 video encoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Philips SAA7185 video encoder.
@@ -430,7 +424,7 @@ config VIDEO_SAA7185
config VIDEO_ADV7170
tristate "Analog Devices ADV7170 video encoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Analog Devices ADV7170 video encoder driver
@@ -439,7 +433,7 @@ config VIDEO_ADV7170
config VIDEO_ADV7175
tristate "Analog Devices ADV7175 video encoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Analog Devices ADV7175 video encoder driver
@@ -487,18 +481,6 @@ config VIDEO_VIVI
source "drivers/media/video/bt8xx/Kconfig"
-config VIDEO_SAA6588
- tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
- depends on I2C && VIDEO_BT848
-
- help
- Support for Radio Data System (RDS) decoder. This allows seeing
- radio station identification transmitted using this standard.
- Currently, it works only with bt8x8 chips.
-
- To compile this driver as a module, choose M here: the
- module will be called saa6588.
-
config VIDEO_PMS
tristate "Mediavision Pro Movie Studio Video For Linux"
depends on ISA && VIDEO_V4L1
@@ -602,7 +584,6 @@ config VIDEO_SAA5249
config VIDEO_VINO
tristate "SGI Vino Video For Linux (EXPERIMENTAL)"
depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2
- select I2C_ALGO_SGI
select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO
help
Say Y here to build in support for the Vino video input system found
@@ -639,7 +620,7 @@ config VIDEO_MXB
depends on PCI && VIDEO_V4L1 && I2C
select VIDEO_SAA7146_VV
select VIDEO_TUNER
- select VIDEO_SAA7115 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TEA6420 if VIDEO_HELPER_CHIPS_AUTO
@@ -728,13 +709,6 @@ config SOC_CAMERA_MT9M001
This driver supports MT9M001 cameras from Micron, monochrome
and colour models.
-config MT9M001_PCA9536_SWITCH
- bool "pca9536 datawidth switch for mt9m001"
- depends on SOC_CAMERA_MT9M001 && GENERIC_GPIO
- help
- Select this if your MT9M001 camera uses a PCA9536 I2C GPIO
- extender to switch between 8 and 10 bit datawidth modes
-
config SOC_CAMERA_MT9M111
tristate "mt9m111 and mt9m112 support"
depends on SOC_CAMERA && I2C
@@ -754,13 +728,6 @@ config SOC_CAMERA_MT9V022
help
This driver supports MT9V022 cameras from Micron
-config MT9V022_PCA9536_SWITCH
- bool "pca9536 datawidth switch for mt9v022"
- depends on SOC_CAMERA_MT9V022 && GENERIC_GPIO
- help
- Select this if your MT9V022 camera uses a PCA9536 I2C GPIO
- extender to switch between 8 and 10 bit datawidth modes
-
config SOC_CAMERA_TW9910
tristate "tw9910 support"
depends on SOC_CAMERA && I2C
@@ -779,6 +746,13 @@ config SOC_CAMERA_OV772X
help
This is a ov772x camera driver
+config VIDEO_MX3
+ tristate "i.MX3x Camera Sensor Interface driver"
+ depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
+ select VIDEOBUF_DMA_CONTIG
+ ---help---
+ This is a v4l2 driver for the i.MX3x Camera Sensor Interface
+
config VIDEO_PXA27x
tristate "PXA27x Quick Capture Interface driver"
depends on VIDEO_DEV && PXA27x && SOC_CAMERA
@@ -817,6 +791,8 @@ source "drivers/media/video/gspca/Kconfig"
source "drivers/media/video/pvrusb2/Kconfig"
+source "drivers/media/video/hdpvr/Kconfig"
+
source "drivers/media/video/em28xx/Kconfig"
source "drivers/media/video/usbvision/Kconfig"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 72f6d03d2d8f..b9046744463b 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -30,7 +30,6 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o
-obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
@@ -43,8 +42,6 @@ obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o
obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o
-obj-$(CONFIG_VIDEO_SAA7111) += saa7111.o
-obj-$(CONFIG_VIDEO_SAA7114) += saa7114.o
obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o
obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
@@ -122,6 +119,8 @@ obj-$(CONFIG_USB_PWC) += pwc/
obj-$(CONFIG_USB_ZC0301) += zc0301/
obj-$(CONFIG_USB_GSPCA) += gspca/
+obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/
+
obj-$(CONFIG_USB_IBMCAM) += usbvideo/
obj-$(CONFIG_USB_KONICAWC) += usbvideo/
obj-$(CONFIG_USB_VICAM) += usbvideo/
@@ -134,10 +133,11 @@ obj-$(CONFIG_VIDEO_CX18) += cx18/
obj-$(CONFIG_VIDEO_VIVI) += vivi.o
obj-$(CONFIG_VIDEO_CX23885) += cx23885/
-obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
+obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
+obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
-obj-$(CONFIG_SOC_CAMERA) += soc_camera.o
+obj-$(CONFIG_SOC_CAMERA) += soc_camera.o
obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
index e0eb4f321442..873c30a41bd7 100644
--- a/drivers/media/video/adv7170.c
+++ b/drivers/media/video/adv7170.c
@@ -34,15 +34,16 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
MODULE_AUTHOR("Maxim Yevtyushkin");
MODULE_LICENSE("GPL");
+
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
@@ -50,38 +51,43 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
/* ----------------------------------------------------------------------- */
struct adv7170 {
+ struct v4l2_subdev sd;
unsigned char reg[128];
- int norm;
+ v4l2_std_id norm;
int input;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
};
+static inline struct adv7170 *to_adv7170(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct adv7170, sd);
+}
+
static char *inputs[] = { "pass_through", "play_back" };
-static char *norms[] = { "PAL", "NTSC" };
/* ----------------------------------------------------------------------- */
-static inline int adv7170_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int adv7170_write(struct v4l2_subdev *sd, u8 reg, u8 value)
{
- struct adv7170 *encoder = i2c_get_clientdata(client);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct adv7170 *encoder = to_adv7170(sd);
encoder->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int adv7170_read(struct i2c_client *client, u8 reg)
+static inline int adv7170_read(struct v4l2_subdev *sd, u8 reg)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
return i2c_smbus_read_byte_data(client, reg);
}
-static int adv7170_write_block(struct i2c_client *client,
+static int adv7170_write_block(struct v4l2_subdev *sd,
const u8 *data, unsigned int len)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct adv7170 *encoder = to_adv7170(sd);
int ret = -1;
u8 reg;
@@ -89,7 +95,6 @@ static int adv7170_write_block(struct i2c_client *client,
* the adapter understands raw I2C */
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
/* do raw I2C, not smbus compatible */
- struct adv7170 *encoder = i2c_get_clientdata(client);
u8 block_data[32];
int block_len;
@@ -110,7 +115,7 @@ static int adv7170_write_block(struct i2c_client *client,
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- ret = adv7170_write(client, reg, *data++);
+ ret = adv7170_write(sd, reg, *data++);
if (ret < 0)
break;
len -= 2;
@@ -128,203 +133,161 @@ static int adv7170_write_block(struct i2c_client *client,
#define TR1PLAY 0x00
static const unsigned char init_NTSC[] = {
- 0x00, 0x10, // MR0
- 0x01, 0x20, // MR1
- 0x02, 0x0e, // MR2 RTC control: bits 2 and 1
- 0x03, 0x80, // MR3
- 0x04, 0x30, // MR4
- 0x05, 0x00, // Reserved
- 0x06, 0x00, // Reserved
- 0x07, TR0MODE, // TM0
- 0x08, TR1CAPT, // TM1
- 0x09, 0x16, // Fsc0
- 0x0a, 0x7c, // Fsc1
- 0x0b, 0xf0, // Fsc2
- 0x0c, 0x21, // Fsc3
- 0x0d, 0x00, // Subcarrier Phase
- 0x0e, 0x00, // Closed Capt. Ext 0
- 0x0f, 0x00, // Closed Capt. Ext 1
- 0x10, 0x00, // Closed Capt. 0
- 0x11, 0x00, // Closed Capt. 1
- 0x12, 0x00, // Pedestal Ctl 0
- 0x13, 0x00, // Pedestal Ctl 1
- 0x14, 0x00, // Pedestal Ctl 2
- 0x15, 0x00, // Pedestal Ctl 3
- 0x16, 0x00, // CGMS_WSS_0
- 0x17, 0x00, // CGMS_WSS_1
- 0x18, 0x00, // CGMS_WSS_2
- 0x19, 0x00, // Teletext Ctl
+ 0x00, 0x10, /* MR0 */
+ 0x01, 0x20, /* MR1 */
+ 0x02, 0x0e, /* MR2 RTC control: bits 2 and 1 */
+ 0x03, 0x80, /* MR3 */
+ 0x04, 0x30, /* MR4 */
+ 0x05, 0x00, /* Reserved */
+ 0x06, 0x00, /* Reserved */
+ 0x07, TR0MODE, /* TM0 */
+ 0x08, TR1CAPT, /* TM1 */
+ 0x09, 0x16, /* Fsc0 */
+ 0x0a, 0x7c, /* Fsc1 */
+ 0x0b, 0xf0, /* Fsc2 */
+ 0x0c, 0x21, /* Fsc3 */
+ 0x0d, 0x00, /* Subcarrier Phase */
+ 0x0e, 0x00, /* Closed Capt. Ext 0 */
+ 0x0f, 0x00, /* Closed Capt. Ext 1 */
+ 0x10, 0x00, /* Closed Capt. 0 */
+ 0x11, 0x00, /* Closed Capt. 1 */
+ 0x12, 0x00, /* Pedestal Ctl 0 */
+ 0x13, 0x00, /* Pedestal Ctl 1 */
+ 0x14, 0x00, /* Pedestal Ctl 2 */
+ 0x15, 0x00, /* Pedestal Ctl 3 */
+ 0x16, 0x00, /* CGMS_WSS_0 */
+ 0x17, 0x00, /* CGMS_WSS_1 */
+ 0x18, 0x00, /* CGMS_WSS_2 */
+ 0x19, 0x00, /* Teletext Ctl */
};
static const unsigned char init_PAL[] = {
- 0x00, 0x71, // MR0
- 0x01, 0x20, // MR1
- 0x02, 0x0e, // MR2 RTC control: bits 2 and 1
- 0x03, 0x80, // MR3
- 0x04, 0x30, // MR4
- 0x05, 0x00, // Reserved
- 0x06, 0x00, // Reserved
- 0x07, TR0MODE, // TM0
- 0x08, TR1CAPT, // TM1
- 0x09, 0xcb, // Fsc0
- 0x0a, 0x8a, // Fsc1
- 0x0b, 0x09, // Fsc2
- 0x0c, 0x2a, // Fsc3
- 0x0d, 0x00, // Subcarrier Phase
- 0x0e, 0x00, // Closed Capt. Ext 0
- 0x0f, 0x00, // Closed Capt. Ext 1
- 0x10, 0x00, // Closed Capt. 0
- 0x11, 0x00, // Closed Capt. 1
- 0x12, 0x00, // Pedestal Ctl 0
- 0x13, 0x00, // Pedestal Ctl 1
- 0x14, 0x00, // Pedestal Ctl 2
- 0x15, 0x00, // Pedestal Ctl 3
- 0x16, 0x00, // CGMS_WSS_0
- 0x17, 0x00, // CGMS_WSS_1
- 0x18, 0x00, // CGMS_WSS_2
- 0x19, 0x00, // Teletext Ctl
+ 0x00, 0x71, /* MR0 */
+ 0x01, 0x20, /* MR1 */
+ 0x02, 0x0e, /* MR2 RTC control: bits 2 and 1 */
+ 0x03, 0x80, /* MR3 */
+ 0x04, 0x30, /* MR4 */
+ 0x05, 0x00, /* Reserved */
+ 0x06, 0x00, /* Reserved */
+ 0x07, TR0MODE, /* TM0 */
+ 0x08, TR1CAPT, /* TM1 */
+ 0x09, 0xcb, /* Fsc0 */
+ 0x0a, 0x8a, /* Fsc1 */
+ 0x0b, 0x09, /* Fsc2 */
+ 0x0c, 0x2a, /* Fsc3 */
+ 0x0d, 0x00, /* Subcarrier Phase */
+ 0x0e, 0x00, /* Closed Capt. Ext 0 */
+ 0x0f, 0x00, /* Closed Capt. Ext 1 */
+ 0x10, 0x00, /* Closed Capt. 0 */
+ 0x11, 0x00, /* Closed Capt. 1 */
+ 0x12, 0x00, /* Pedestal Ctl 0 */
+ 0x13, 0x00, /* Pedestal Ctl 1 */
+ 0x14, 0x00, /* Pedestal Ctl 2 */
+ 0x15, 0x00, /* Pedestal Ctl 3 */
+ 0x16, 0x00, /* CGMS_WSS_0 */
+ 0x17, 0x00, /* CGMS_WSS_1 */
+ 0x18, 0x00, /* CGMS_WSS_2 */
+ 0x19, 0x00, /* Teletext Ctl */
};
-static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int adv7170_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
{
- struct adv7170 *encoder = i2c_get_clientdata(client);
-
- switch (cmd) {
- case 0:
-#if 0
- /* This is just for testing!!! */
- adv7170_write_block(client, init_common,
- sizeof(init_common));
- adv7170_write(client, 0x07, TR0MODE | TR0RST);
- adv7170_write(client, 0x07, TR0MODE);
-#endif
- break;
-
- case ENCODER_GET_CAPABILITIES:
- {
- struct video_encoder_capability *cap = arg;
-
- cap->flags = VIDEO_ENCODER_PAL |
- VIDEO_ENCODER_NTSC;
- cap->inputs = 2;
- cap->outputs = 1;
- break;
+ struct adv7170 *encoder = to_adv7170(sd);
+
+ v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
+
+ if (std & V4L2_STD_NTSC) {
+ adv7170_write_block(sd, init_NTSC, sizeof(init_NTSC));
+ if (encoder->input == 0)
+ adv7170_write(sd, 0x02, 0x0e); /* Enable genlock */
+ adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7170_write(sd, 0x07, TR0MODE);
+ } else if (std & V4L2_STD_PAL) {
+ adv7170_write_block(sd, init_PAL, sizeof(init_PAL));
+ if (encoder->input == 0)
+ adv7170_write(sd, 0x02, 0x0e); /* Enable genlock */
+ adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7170_write(sd, 0x07, TR0MODE);
+ } else {
+ v4l2_dbg(1, debug, sd, "illegal norm: %llx\n",
+ (unsigned long long)std);
+ return -EINVAL;
}
+ v4l2_dbg(1, debug, sd, "switched to %llx\n", (unsigned long long)std);
+ encoder->norm = std;
+ return 0;
+}
- case ENCODER_SET_NORM:
- {
- int iarg = *(int *) arg;
-
- v4l_dbg(1, debug, client, "set norm %d\n", iarg);
-
- switch (iarg) {
- case VIDEO_MODE_NTSC:
- adv7170_write_block(client, init_NTSC,
- sizeof(init_NTSC));
- if (encoder->input == 0)
- adv7170_write(client, 0x02, 0x0e); // Enable genlock
- adv7170_write(client, 0x07, TR0MODE | TR0RST);
- adv7170_write(client, 0x07, TR0MODE);
- break;
-
- case VIDEO_MODE_PAL:
- adv7170_write_block(client, init_PAL,
- sizeof(init_PAL));
- if (encoder->input == 0)
- adv7170_write(client, 0x02, 0x0e); // Enable genlock
- adv7170_write(client, 0x07, TR0MODE | TR0RST);
- adv7170_write(client, 0x07, TR0MODE);
- break;
-
- default:
- v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
- return -EINVAL;
- }
- v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
- encoder->norm = iarg;
- break;
- }
+static int adv7170_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ struct adv7170 *encoder = to_adv7170(sd);
- case ENCODER_SET_INPUT:
- {
- int iarg = *(int *) arg;
-
- /* RJ: *iarg = 0: input is from decoder
- *iarg = 1: input is from ZR36060
- *iarg = 2: color bar */
-
- v4l_dbg(1, debug, client, "set input from %s\n",
- iarg == 0 ? "decoder" : "ZR36060");
-
- switch (iarg) {
- case 0:
- adv7170_write(client, 0x01, 0x20);
- adv7170_write(client, 0x08, TR1CAPT); /* TR1 */
- adv7170_write(client, 0x02, 0x0e); // Enable genlock
- adv7170_write(client, 0x07, TR0MODE | TR0RST);
- adv7170_write(client, 0x07, TR0MODE);
- /* udelay(10); */
- break;
-
- case 1:
- adv7170_write(client, 0x01, 0x00);
- adv7170_write(client, 0x08, TR1PLAY); /* TR1 */
- adv7170_write(client, 0x02, 0x08);
- adv7170_write(client, 0x07, TR0MODE | TR0RST);
- adv7170_write(client, 0x07, TR0MODE);
- /* udelay(10); */
- break;
-
- default:
- v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
- return -EINVAL;
- }
- v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
- encoder->input = iarg;
- break;
- }
+ /* RJ: route->input = 0: input is from decoder
+ route->input = 1: input is from ZR36060
+ route->input = 2: color bar */
- case ENCODER_SET_OUTPUT:
- {
- int *iarg = arg;
+ v4l2_dbg(1, debug, sd, "set input from %s\n",
+ route->input == 0 ? "decoder" : "ZR36060");
- /* not much choice of outputs */
- if (*iarg != 0) {
- return -EINVAL;
- }
+ switch (route->input) {
+ case 0:
+ adv7170_write(sd, 0x01, 0x20);
+ adv7170_write(sd, 0x08, TR1CAPT); /* TR1 */
+ adv7170_write(sd, 0x02, 0x0e); /* Enable genlock */
+ adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7170_write(sd, 0x07, TR0MODE);
+ /* udelay(10); */
break;
- }
-
- case ENCODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
- encoder->enable = !!*iarg;
+ case 1:
+ adv7170_write(sd, 0x01, 0x00);
+ adv7170_write(sd, 0x08, TR1PLAY); /* TR1 */
+ adv7170_write(sd, 0x02, 0x08);
+ adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7170_write(sd, 0x07, TR0MODE);
+ /* udelay(10); */
break;
- }
default:
+ v4l2_dbg(1, debug, sd, "illegal input: %d\n", route->input);
return -EINVAL;
}
-
+ v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[route->input]);
+ encoder->input = route->input;
return 0;
}
+static int adv7170_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7170, 0);
+}
+
/* ----------------------------------------------------------------------- */
-static unsigned short normal_i2c[] = {
- 0xd4 >> 1, 0xd6 >> 1, /* adv7170 IDs */
- 0x54 >> 1, 0x56 >> 1, /* adv7171 IDs */
- I2C_CLIENT_END
+static const struct v4l2_subdev_core_ops adv7170_core_ops = {
+ .g_chip_ident = adv7170_g_chip_ident,
};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_video_ops adv7170_video_ops = {
+ .s_std_output = adv7170_s_std_output,
+ .s_routing = adv7170_s_routing,
+};
+
+static const struct v4l2_subdev_ops adv7170_ops = {
+ .core = &adv7170_core_ops,
+ .video = &adv7170_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
static int adv7170_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adv7170 *encoder;
+ struct v4l2_subdev *sd;
int i;
/* Check if the adapter supports the needed features */
@@ -337,26 +300,29 @@ static int adv7170_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
- encoder->norm = VIDEO_MODE_NTSC;
+ sd = &encoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &adv7170_ops);
+ encoder->norm = V4L2_STD_NTSC;
encoder->input = 0;
- encoder->enable = 1;
- i2c_set_clientdata(client, encoder);
- i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC));
+ i = adv7170_write_block(sd, init_NTSC, sizeof(init_NTSC));
if (i >= 0) {
- i = adv7170_write(client, 0x07, TR0MODE | TR0RST);
- i = adv7170_write(client, 0x07, TR0MODE);
- i = adv7170_read(client, 0x12);
- v4l_dbg(1, debug, client, "revision %d\n", i & 1);
+ i = adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+ i = adv7170_write(sd, 0x07, TR0MODE);
+ i = adv7170_read(sd, 0x12);
+ v4l2_dbg(1, debug, sd, "revision %d\n", i & 1);
}
if (i < 0)
- v4l_dbg(1, debug, client, "init error 0x%x\n", i);
+ v4l2_dbg(1, debug, sd, "init error 0x%x\n", i);
return 0;
}
static int adv7170_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_adv7170(sd));
return 0;
}
@@ -371,8 +337,6 @@ MODULE_DEVICE_TABLE(i2c, adv7170_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "adv7170",
- .driverid = I2C_DRIVERID_ADV7170,
- .command = adv7170_command,
.probe = adv7170_probe,
.remove = adv7170_remove,
.id_table = adv7170_id,
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
index 6008e84653f1..ff1210303295 100644
--- a/drivers/media/video/adv7175.c
+++ b/drivers/media/video/adv7175.c
@@ -30,15 +30,19 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
+#define I2C_ADV7175 0xd4
+#define I2C_ADV7176 0x54
+
+
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
@@ -46,36 +50,38 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
/* ----------------------------------------------------------------------- */
struct adv7175 {
- int norm;
+ struct v4l2_subdev sd;
+ v4l2_std_id norm;
int input;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
};
-#define I2C_ADV7175 0xd4
-#define I2C_ADV7176 0x54
+static inline struct adv7175 *to_adv7175(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct adv7175, sd);
+}
static char *inputs[] = { "pass_through", "play_back", "color_bar" };
-static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" };
/* ----------------------------------------------------------------------- */
-static inline int adv7175_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int adv7175_write(struct v4l2_subdev *sd, u8 reg, u8 value)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int adv7175_read(struct i2c_client *client, u8 reg)
+static inline int adv7175_read(struct v4l2_subdev *sd, u8 reg)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
return i2c_smbus_read_byte_data(client, reg);
}
-static int adv7175_write_block(struct i2c_client *client,
+static int adv7175_write_block(struct v4l2_subdev *sd,
const u8 *data, unsigned int len)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = -1;
u8 reg;
@@ -103,7 +109,7 @@ static int adv7175_write_block(struct i2c_client *client,
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- ret = adv7175_write(client, reg, *data++);
+ ret = adv7175_write(sd, reg, *data++);
if (ret < 0)
break;
len -= 2;
@@ -113,18 +119,18 @@ static int adv7175_write_block(struct i2c_client *client,
return ret;
}
-static void set_subcarrier_freq(struct i2c_client *client, int pass_through)
+static void set_subcarrier_freq(struct v4l2_subdev *sd, int pass_through)
{
/* for some reason pass_through NTSC needs
* a different sub-carrier freq to remain stable. */
if (pass_through)
- adv7175_write(client, 0x02, 0x00);
+ adv7175_write(sd, 0x02, 0x00);
else
- adv7175_write(client, 0x02, 0x55);
+ adv7175_write(sd, 0x02, 0x55);
- adv7175_write(client, 0x03, 0x55);
- adv7175_write(client, 0x04, 0x55);
- adv7175_write(client, 0x05, 0x25);
+ adv7175_write(sd, 0x03, 0x55);
+ adv7175_write(sd, 0x04, 0x55);
+ adv7175_write(sd, 0x05, 0x25);
}
/* ----------------------------------------------------------------------- */
@@ -184,180 +190,144 @@ static const unsigned char init_ntsc[] = {
0x06, 0x1a, /* subc. phase */
};
-static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int adv7175_init(struct v4l2_subdev *sd, u32 val)
{
- struct adv7175 *encoder = i2c_get_clientdata(client);
+ /* This is just for testing!!! */
+ adv7175_write_block(sd, init_common, sizeof(init_common));
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ return 0;
+}
- switch (cmd) {
- case 0:
- /* This is just for testing!!! */
- adv7175_write_block(client, init_common,
- sizeof(init_common));
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- break;
+static int adv7175_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct adv7175 *encoder = to_adv7175(sd);
+
+ if (std & V4L2_STD_NTSC) {
+ adv7175_write_block(sd, init_ntsc, sizeof(init_ntsc));
+ if (encoder->input == 0)
+ adv7175_write(sd, 0x0d, 0x4f); /* Enable genlock */
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ } else if (std & V4L2_STD_PAL) {
+ adv7175_write_block(sd, init_pal, sizeof(init_pal));
+ if (encoder->input == 0)
+ adv7175_write(sd, 0x0d, 0x4f); /* Enable genlock */
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ } else if (std & V4L2_STD_SECAM) {
+ /* This is an attempt to convert
+ * SECAM->PAL (typically it does not work
+ * due to genlock: when decoder is in SECAM
+ * and encoder in in PAL the subcarrier can
+ * not be syncronized with horizontal
+ * quency) */
+ adv7175_write_block(sd, init_pal, sizeof(init_pal));
+ if (encoder->input == 0)
+ adv7175_write(sd, 0x0d, 0x49); /* Disable genlock */
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ } else {
+ v4l2_dbg(1, debug, sd, "illegal norm: %llx\n",
+ (unsigned long long)std);
+ return -EINVAL;
+ }
+ v4l2_dbg(1, debug, sd, "switched to %llx\n", (unsigned long long)std);
+ encoder->norm = std;
+ return 0;
+}
- case ENCODER_GET_CAPABILITIES:
- {
- struct video_encoder_capability *cap = arg;
+static int adv7175_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ struct adv7175 *encoder = to_adv7175(sd);
- cap->flags = VIDEO_ENCODER_PAL |
- VIDEO_ENCODER_NTSC |
- VIDEO_ENCODER_SECAM; /* well, hacky */
- cap->inputs = 2;
- cap->outputs = 1;
- break;
- }
+ /* RJ: route->input = 0: input is from decoder
+ route->input = 1: input is from ZR36060
+ route->input = 2: color bar */
- case ENCODER_SET_NORM:
- {
- int iarg = *(int *) arg;
-
- switch (iarg) {
- case VIDEO_MODE_NTSC:
- adv7175_write_block(client, init_ntsc,
- sizeof(init_ntsc));
- if (encoder->input == 0)
- adv7175_write(client, 0x0d, 0x4f); // Enable genlock
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- break;
-
- case VIDEO_MODE_PAL:
- adv7175_write_block(client, init_pal,
- sizeof(init_pal));
- if (encoder->input == 0)
- adv7175_write(client, 0x0d, 0x4f); // Enable genlock
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- break;
-
- case VIDEO_MODE_SECAM: // WARNING! ADV7176 does not support SECAM.
- /* This is an attempt to convert
- * SECAM->PAL (typically it does not work
- * due to genlock: when decoder is in SECAM
- * and encoder in in PAL the subcarrier can
- * not be syncronized with horizontal
- * quency) */
- adv7175_write_block(client, init_pal,
- sizeof(init_pal));
- if (encoder->input == 0)
- adv7175_write(client, 0x0d, 0x49); // Disable genlock
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- break;
- default:
- v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
- return -EINVAL;
- }
- v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
- encoder->norm = iarg;
+ switch (route->input) {
+ case 0:
+ adv7175_write(sd, 0x01, 0x00);
+
+ if (encoder->norm & V4L2_STD_NTSC)
+ set_subcarrier_freq(sd, 1);
+
+ adv7175_write(sd, 0x0c, TR1CAPT); /* TR1 */
+ if (encoder->norm & V4L2_STD_SECAM)
+ adv7175_write(sd, 0x0d, 0x49); /* Disable genlock */
+ else
+ adv7175_write(sd, 0x0d, 0x4f); /* Enable genlock */
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ /*udelay(10);*/
break;
- }
- case ENCODER_SET_INPUT:
- {
- int iarg = *(int *) arg;
-
- /* RJ: *iarg = 0: input is from SAA7110
- *iarg = 1: input is from ZR36060
- *iarg = 2: color bar */
-
- switch (iarg) {
- case 0:
- adv7175_write(client, 0x01, 0x00);
-
- if (encoder->norm == VIDEO_MODE_NTSC)
- set_subcarrier_freq(client, 1);
-
- adv7175_write(client, 0x0c, TR1CAPT); /* TR1 */
- if (encoder->norm == VIDEO_MODE_SECAM)
- adv7175_write(client, 0x0d, 0x49); // Disable genlock
- else
- adv7175_write(client, 0x0d, 0x4f); // Enable genlock
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- //udelay(10);
- break;
-
- case 1:
- adv7175_write(client, 0x01, 0x00);
-
- if (encoder->norm == VIDEO_MODE_NTSC)
- set_subcarrier_freq(client, 0);
-
- adv7175_write(client, 0x0c, TR1PLAY); /* TR1 */
- adv7175_write(client, 0x0d, 0x49);
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- /* udelay(10); */
- break;
-
- case 2:
- adv7175_write(client, 0x01, 0x80);
-
- if (encoder->norm == VIDEO_MODE_NTSC)
- set_subcarrier_freq(client, 0);
-
- adv7175_write(client, 0x0d, 0x49);
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- /* udelay(10); */
- break;
-
- default:
- v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
- return -EINVAL;
- }
- v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
- encoder->input = iarg;
- break;
- }
+ case 1:
+ adv7175_write(sd, 0x01, 0x00);
- case ENCODER_SET_OUTPUT:
- {
- int *iarg = arg;
+ if (encoder->norm & V4L2_STD_NTSC)
+ set_subcarrier_freq(sd, 0);
- /* not much choice of outputs */
- if (*iarg != 0)
- return -EINVAL;
+ adv7175_write(sd, 0x0c, TR1PLAY); /* TR1 */
+ adv7175_write(sd, 0x0d, 0x49);
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ /* udelay(10); */
break;
- }
- case ENCODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
+ case 2:
+ adv7175_write(sd, 0x01, 0x80);
+
+ if (encoder->norm & V4L2_STD_NTSC)
+ set_subcarrier_freq(sd, 0);
- encoder->enable = !!*iarg;
+ adv7175_write(sd, 0x0d, 0x49);
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ /* udelay(10); */
break;
- }
default:
+ v4l2_dbg(1, debug, sd, "illegal input: %d\n", route->input);
return -EINVAL;
}
-
+ v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[route->input]);
+ encoder->input = route->input;
return 0;
}
+static int adv7175_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7175, 0);
+}
+
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = {
- I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
- I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1,
- I2C_CLIENT_END
+static const struct v4l2_subdev_core_ops adv7175_core_ops = {
+ .g_chip_ident = adv7175_g_chip_ident,
+ .init = adv7175_init,
};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_video_ops adv7175_video_ops = {
+ .s_std_output = adv7175_s_std_output,
+ .s_routing = adv7175_s_routing,
+};
+
+static const struct v4l2_subdev_ops adv7175_ops = {
+ .core = &adv7175_core_ops,
+ .video = &adv7175_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
static int adv7175_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int i;
struct adv7175 *encoder;
+ struct v4l2_subdev *sd;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -369,26 +339,29 @@ static int adv7175_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
- encoder->norm = VIDEO_MODE_PAL;
+ sd = &encoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &adv7175_ops);
+ encoder->norm = V4L2_STD_NTSC;
encoder->input = 0;
- encoder->enable = 1;
- i2c_set_clientdata(client, encoder);
- i = adv7175_write_block(client, init_common, sizeof(init_common));
+ i = adv7175_write_block(sd, init_common, sizeof(init_common));
if (i >= 0) {
- i = adv7175_write(client, 0x07, TR0MODE | TR0RST);
- i = adv7175_write(client, 0x07, TR0MODE);
- i = adv7175_read(client, 0x12);
- v4l_dbg(1, debug, client, "revision %d\n", i & 1);
+ i = adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ i = adv7175_write(sd, 0x07, TR0MODE);
+ i = adv7175_read(sd, 0x12);
+ v4l2_dbg(1, debug, sd, "revision %d\n", i & 1);
}
if (i < 0)
- v4l_dbg(1, debug, client, "init error 0x%x\n", i);
+ v4l2_dbg(1, debug, sd, "init error 0x%x\n", i);
return 0;
}
static int adv7175_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_adv7175(sd));
return 0;
}
@@ -403,8 +376,6 @@ MODULE_DEVICE_TABLE(i2c, adv7175_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "adv7175",
- .driverid = I2C_DRIVERID_ADV7175,
- .command = adv7175_command,
.probe = adv7175_probe,
.remove = adv7175_remove,
.id_table = adv7175_id,
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
index 018f72b8e3e2..05cdf494dfb0 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/video/au0828/Kconfig
@@ -1,13 +1,13 @@
config VIDEO_AU0828
tristate "Auvitek AU0828 support"
- depends on I2C && INPUT && DVB_CORE && USB
+ depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2
select I2C_ALGOBIT
select VIDEO_TVEEPROM
- select DVB_AU8522 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
+ select DVB_AU8522 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
---help---
This is a video4linux driver for Auvitek's USB device.
diff --git a/drivers/media/video/au0828/Makefile b/drivers/media/video/au0828/Makefile
index cd2c58281b4e..4d2623158188 100644
--- a/drivers/media/video/au0828/Makefile
+++ b/drivers/media/video/au0828/Makefile
@@ -1,4 +1,4 @@
-au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o
+au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o au0828-video.o
obj-$(CONFIG_VIDEO_AU0828) += au0828.o
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index d60123b413f5..1aabaa7e55bb 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -21,25 +21,89 @@
#include "au0828.h"
#include "au0828-cards.h"
+#include "au8522.h"
+#include "media/tuner.h"
+#include "media/v4l2-common.h"
+
+void hvr950q_cs5340_audio(void *priv, int enable)
+{
+ /* Because the HVR-950q shares an i2s bus between the cs5340 and the
+ au8522, we need to hold cs5340 in reset when using the au8522 */
+ struct au0828_dev *dev = priv;
+ if (enable == 1)
+ au0828_set(dev, REG_000, 0x10);
+ else
+ au0828_clear(dev, REG_000, 0x10);
+}
struct au0828_board au0828_boards[] = {
[AU0828_BOARD_UNKNOWN] = {
.name = "Unknown board",
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},
[AU0828_BOARD_HAUPPAUGE_HVR850] = {
.name = "Hauppauge HVR850",
+ .tuner_type = TUNER_XC5000,
+ .tuner_addr = 0x61,
+ .input = {
+ {
+ .type = AU0828_VMUX_TELEVISION,
+ .vmux = AU8522_COMPOSITE_CH4_SIF,
+ .amux = AU8522_AUDIO_SIF,
+ },
+ {
+ .type = AU0828_VMUX_COMPOSITE,
+ .vmux = AU8522_COMPOSITE_CH1,
+ .amux = AU8522_AUDIO_NONE,
+ .audio_setup = hvr950q_cs5340_audio,
+ },
+ {
+ .type = AU0828_VMUX_SVIDEO,
+ .vmux = AU8522_SVIDEO_CH13,
+ .amux = AU8522_AUDIO_NONE,
+ .audio_setup = hvr950q_cs5340_audio,
+ },
+ },
},
[AU0828_BOARD_HAUPPAUGE_HVR950Q] = {
.name = "Hauppauge HVR950Q",
+ .tuner_type = TUNER_XC5000,
+ .tuner_addr = 0x61,
+ .input = {
+ {
+ .type = AU0828_VMUX_TELEVISION,
+ .vmux = AU8522_COMPOSITE_CH4_SIF,
+ .amux = AU8522_AUDIO_SIF,
+ },
+ {
+ .type = AU0828_VMUX_COMPOSITE,
+ .vmux = AU8522_COMPOSITE_CH1,
+ .amux = AU8522_AUDIO_NONE,
+ .audio_setup = hvr950q_cs5340_audio,
+ },
+ {
+ .type = AU0828_VMUX_SVIDEO,
+ .vmux = AU8522_SVIDEO_CH13,
+ .amux = AU8522_AUDIO_NONE,
+ .audio_setup = hvr950q_cs5340_audio,
+ },
+ },
},
[AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = {
.name = "Hauppauge HVR950Q rev xxF8",
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},
[AU0828_BOARD_DVICO_FUSIONHDTV7] = {
.name = "DViCO FusionHDTV USB",
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},
[AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
.name = "Hauppauge Woodbury",
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},
};
@@ -52,7 +116,7 @@ int au0828_tuner_callback(void *priv, int component, int command, int arg)
dprintk(1, "%s()\n", __func__);
- switch (dev->board) {
+ switch (dev->boardnr) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
@@ -81,17 +145,18 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
struct tveeprom tv;
tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data);
+ dev->board.tuner_type = tv.tuner_type;
/* Make sure we support the board model */
switch (tv.model) {
case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */
- case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */
- case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
- case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
- case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
- case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */
- case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */
- case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */
+ case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */
+ case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
+ case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
+ case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
+ case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and analog video */
+ case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */
+ case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and analog video */
case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */
break;
default:
@@ -107,15 +172,21 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
void au0828_card_setup(struct au0828_dev *dev)
{
static u8 eeprom[256];
+ struct tuner_setup tun_setup;
+ struct v4l2_subdev *sd;
+ unsigned int mode_mask = T_ANALOG_TV |
+ T_DIGITAL_TV;
dprintk(1, "%s()\n", __func__);
+ memcpy(&dev->board, &au0828_boards[dev->boardnr], sizeof(dev->board));
+
if (dev->i2c_rc == 0) {
dev->i2c_client.addr = 0xa0 >> 1;
tveeprom_read(&dev->i2c_client, eeprom, sizeof(eeprom));
}
- switch (dev->board) {
+ switch (dev->boardnr) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
@@ -124,6 +195,32 @@ void au0828_card_setup(struct au0828_dev *dev)
hauppauge_eeprom(dev, eeprom+0xa0);
break;
}
+
+ if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED) {
+ /* Load the analog demodulator driver (note this would need to
+ be abstracted out if we ever need to support a different
+ demod) */
+ sd = v4l2_i2c_new_subdev(&dev->i2c_adap, "au8522", "au8522",
+ 0x8e >> 1);
+ if (sd == NULL)
+ printk(KERN_ERR "analog subdev registration failed\n");
+ }
+
+ /* Setup tuners */
+ if (dev->board.tuner_type != TUNER_ABSENT) {
+ /* Load the tuner module, which does the attach */
+ sd = v4l2_i2c_new_subdev(&dev->i2c_adap, "tuner", "tuner",
+ dev->board.tuner_addr);
+ if (sd == NULL)
+ printk(KERN_ERR "tuner subdev registration fail\n");
+
+ tun_setup.mode_mask = mode_mask;
+ tun_setup.type = dev->board.tuner_type;
+ tun_setup.addr = dev->board.tuner_addr;
+ tun_setup.tuner_callback = au0828_tuner_callback;
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr,
+ &tun_setup);
+ }
}
/*
@@ -135,7 +232,7 @@ void au0828_gpio_setup(struct au0828_dev *dev)
{
dprintk(1, "%s()\n", __func__);
- switch (dev->board) {
+ switch (dev->boardnr) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
@@ -144,21 +241,23 @@ void au0828_gpio_setup(struct au0828_dev *dev)
* 4 - CS5340
* 5 - AU8522 Demodulator
* 6 - eeprom W/P
+ * 7 - power supply
* 9 - XC5000 Tuner
*/
/* Into reset */
au0828_write(dev, REG_003, 0x02);
- au0828_write(dev, REG_002, 0x88 | 0x20);
+ au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
au0828_write(dev, REG_001, 0x0);
au0828_write(dev, REG_000, 0x0);
msleep(100);
- /* Out of reset */
+ /* Out of reset (leave the cs5340 in reset until needed) */
au0828_write(dev, REG_003, 0x02);
au0828_write(dev, REG_001, 0x02);
- au0828_write(dev, REG_002, 0x88 | 0x20);
- au0828_write(dev, REG_000, 0x88 | 0x20 | 0x40);
+ au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
+ au0828_write(dev, REG_000, 0x80 | 0x40 | 0x20);
+
msleep(250);
break;
case AU0828_BOARD_DVICO_FUSIONHDTV7:
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
index 5765e8656376..8c761d164442 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/video/au0828/au0828-core.c
@@ -36,6 +36,8 @@ int au0828_debug;
module_param_named(debug, au0828_debug, int, 0644);
MODULE_PARM_DESC(debug, "enable debug messages");
+static atomic_t au0828_instance = ATOMIC_INIT(0);
+
#define _AU0828_BULKPIPE 0x03
#define _BULKPIPESIZE 0xffff
@@ -51,13 +53,13 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
u32 au0828_readreg(struct au0828_dev *dev, u16 reg)
{
recv_control_msg(dev, CMD_REQUEST_IN, 0, reg, dev->ctrlmsg, 1);
- dprintk(8, "%s(0x%x) = 0x%x\n", __func__, reg, dev->ctrlmsg[0]);
+ dprintk(8, "%s(0x%04x) = 0x%02x\n", __func__, reg, dev->ctrlmsg[0]);
return dev->ctrlmsg[0];
}
u32 au0828_writereg(struct au0828_dev *dev, u16 reg, u32 val)
{
- dprintk(8, "%s(0x%x, 0x%x)\n", __func__, reg, val);
+ dprintk(8, "%s(0x%04x, 0x%02x)\n", __func__, reg, val);
return send_control_msg(dev, CMD_REQUEST_OUT, val, reg,
dev->ctrlmsg, 0);
}
@@ -146,9 +148,14 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
/* Digital TV */
au0828_dvb_unregister(dev);
+ if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED)
+ au0828_analog_unregister(dev);
+
/* I2C */
au0828_i2c_unregister(dev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+
usb_set_intfdata(interface, NULL);
mutex_lock(&dev->mutex);
@@ -162,7 +169,7 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
static int au0828_usb_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
- int ifnum;
+ int ifnum, retval, i;
struct au0828_dev *dev;
struct usb_device *usbdev = interface_to_usbdev(interface);
@@ -185,10 +192,22 @@ static int au0828_usb_probe(struct usb_interface *interface,
mutex_init(&dev->mutex);
mutex_init(&dev->dvb.lock);
dev->usbdev = usbdev;
- dev->board = id->driver_info;
+ dev->boardnr = id->driver_info;
usb_set_intfdata(interface, dev);
+ /* Create the v4l2_device */
+ i = atomic_inc_return(&au0828_instance) - 1;
+ snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s-%03d",
+ "au0828", i);
+ retval = v4l2_device_register(&dev->usbdev->dev, &dev->v4l2_dev);
+ if (retval) {
+ printk(KERN_ERR "%s() v4l2_device_register failed\n",
+ __func__);
+ kfree(dev);
+ return -EIO;
+ }
+
/* Power Up the bridge */
au0828_write(dev, REG_600, 1 << 4);
@@ -201,12 +220,15 @@ static int au0828_usb_probe(struct usb_interface *interface,
/* Setup */
au0828_card_setup(dev);
+ /* Analog TV */
+ if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED)
+ au0828_analog_register(dev, interface);
+
/* Digital TV */
au0828_dvb_register(dev);
printk(KERN_INFO "Registered device AU0828 [%s]\n",
- au0828_boards[dev->board].name == NULL ? "Unset" :
- au0828_boards[dev->board].name);
+ dev->board.name == NULL ? "Unset" : dev->board.name);
return 0;
}
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index a882cf546d0a..14baffc22192 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -378,7 +378,7 @@ int au0828_dvb_register(struct au0828_dev *dev)
dprintk(1, "%s()\n", __func__);
/* init frontend */
- switch (dev->board) {
+ switch (dev->boardnr) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
dvb->frontend = dvb_attach(au8522_attach,
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c
index d618fbaade1b..f9a958d0aef1 100644
--- a/drivers/media/video/au0828/au0828-i2c.c
+++ b/drivers/media/video/au0828/au0828-i2c.c
@@ -140,13 +140,39 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
dprintk(4, "%s()\n", __func__);
au0828_write(dev, REG_2FF, 0x01);
- au0828_write(dev, REG_202, 0x07);
+
+ /* FIXME: There is a problem with i2c communications with xc5000 that
+ requires us to slow down the i2c clock until we have a better
+ strategy (such as using the secondary i2c bus to do firmware
+ loading */
+ if ((msg->addr << 1) == 0xc2)
+ au0828_write(dev, REG_202, 0x40);
+ else
+ au0828_write(dev, REG_202, 0x07);
/* Hardware needs 8 bit addresses */
au0828_write(dev, REG_203, msg->addr << 1);
dprintk(4, "SEND: %02x\n", msg->addr);
+ /* Deal with i2c_scan */
+ if (msg->len == 0) {
+ /* The analog tuner detection code makes use of the SMBUS_QUICK
+ message (which involves a zero length i2c write). To avoid
+ checking the status register when we didn't strobe out any
+ actual bytes to the bus, just do a read check. This is
+ consistent with how I saw i2c device checking done in the
+ USB trace of the Windows driver */
+ au0828_write(dev, REG_200, 0x20);
+ if (!i2c_wait_done(i2c_adap))
+ return -EIO;
+
+ if (i2c_wait_read_ack(i2c_adap))
+ return -EIO;
+
+ return 0;
+ }
+
for (i = 0; i < msg->len;) {
dprintk(4, " %02x\n", msg->buf[i]);
@@ -191,7 +217,15 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
dprintk(4, "%s()\n", __func__);
au0828_write(dev, REG_2FF, 0x01);
- au0828_write(dev, REG_202, 0x07);
+
+ /* FIXME: There is a problem with i2c communications with xc5000 that
+ requires us to slow down the i2c clock until we have a better
+ strategy (such as using the secondary i2c bus to do firmware
+ loading */
+ if ((msg->addr << 1) == 0xc2)
+ au0828_write(dev, REG_202, 0x40);
+ else
+ au0828_write(dev, REG_202, 0x07);
/* Hardware needs 8 bit addresses */
au0828_write(dev, REG_203, msg->addr << 1);
@@ -265,33 +299,6 @@ err:
return retval;
}
-static int attach_inform(struct i2c_client *client)
-{
- dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr, client->name);
-
- if (!client->driver->command)
- return 0;
-
- return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
- dprintk(1, "i2c detach [client=%s]\n", client->name);
-
- return 0;
-}
-
-void au0828_call_i2c_clients(struct au0828_dev *dev,
- unsigned int cmd, void *arg)
-{
- if (dev->i2c_rc != 0)
- return;
-
- i2c_clients_command(&dev->i2c_adap, cmd, arg);
-}
-
static u32 au0828_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
@@ -309,9 +316,6 @@ static struct i2c_adapter au0828_i2c_adap_template = {
.owner = THIS_MODULE,
.id = I2C_HW_B_AU0828,
.algo = &au0828_i2c_algo_template,
- .class = I2C_CLASS_TV_ANALOG,
- .client_register = attach_inform,
- .client_unregister = detach_inform,
};
static struct i2c_client au0828_i2c_client_template = {
@@ -356,9 +360,9 @@ int au0828_i2c_register(struct au0828_dev *dev)
strlcpy(dev->i2c_adap.name, DRIVER_NAME,
sizeof(dev->i2c_adap.name));
- dev->i2c_algo.data = dev;
+ dev->i2c_adap.algo = &dev->i2c_algo;
dev->i2c_adap.algo_data = dev;
- i2c_set_adapdata(&dev->i2c_adap, dev);
+ i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
i2c_add_adapter(&dev->i2c_adap);
dev->i2c_client.adapter = &dev->i2c_adap;
diff --git a/drivers/media/video/au0828/au0828-reg.h b/drivers/media/video/au0828/au0828-reg.h
index 1e87fa0c6842..b15e4a3b6fc0 100644
--- a/drivers/media/video/au0828/au0828-reg.h
+++ b/drivers/media/video/au0828/au0828-reg.h
@@ -27,6 +27,9 @@
#define REG_002 0x002
#define REG_003 0x003
+#define AU0828_SENSORCTRL_100 0x100
+#define AU0828_SENSORCTRL_VBI_103 0x103
+
#define REG_200 0x200
#define REG_201 0x201
#define REG_202 0x202
@@ -35,4 +38,7 @@
#define REG_209 0x209
#define REG_2FF 0x2ff
+/* Audio registers */
+#define AU0828_AUDIOCTRL_50C 0x50C
+
#define REG_600 0x600
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
new file mode 100644
index 000000000000..f7ad4958b94e
--- /dev/null
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -0,0 +1,1712 @@
+/*
+ * Auvitek AU0828 USB Bridge (Analog video support)
+ *
+ * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
+ * Copyright (C) 2005-2008 Auvitek International, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * As published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/* Developer Notes:
+ *
+ * VBI support is not yet working
+ * The hardware scaler supported is unimplemented
+ * AC97 audio support is unimplemented (only i2s audio mode)
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/suspend.h>
+#include <linux/version.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/tuner.h>
+#include "au0828.h"
+#include "au0828-reg.h"
+
+static LIST_HEAD(au0828_devlist);
+static DEFINE_MUTEX(au0828_sysfs_lock);
+
+#define AU0828_VERSION_CODE KERNEL_VERSION(0, 0, 1)
+
+/* ------------------------------------------------------------------
+ Videobuf operations
+ ------------------------------------------------------------------*/
+
+static unsigned int isoc_debug;
+module_param(isoc_debug, int, 0644);
+MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
+
+#define au0828_isocdbg(fmt, arg...) \
+do {\
+ if (isoc_debug) { \
+ printk(KERN_INFO "au0828 %s :"fmt, \
+ __func__ , ##arg); \
+ } \
+ } while (0)
+
+static inline void print_err_status(struct au0828_dev *dev,
+ int packet, int status)
+{
+ char *errmsg = "Unknown";
+
+ switch (status) {
+ case -ENOENT:
+ errmsg = "unlinked synchronuously";
+ break;
+ case -ECONNRESET:
+ errmsg = "unlinked asynchronuously";
+ break;
+ case -ENOSR:
+ errmsg = "Buffer error (overrun)";
+ break;
+ case -EPIPE:
+ errmsg = "Stalled (device not responding)";
+ break;
+ case -EOVERFLOW:
+ errmsg = "Babble (bad cable?)";
+ break;
+ case -EPROTO:
+ errmsg = "Bit-stuff error (bad cable?)";
+ break;
+ case -EILSEQ:
+ errmsg = "CRC/Timeout (could be anything)";
+ break;
+ case -ETIME:
+ errmsg = "Device does not respond";
+ break;
+ }
+ if (packet < 0) {
+ au0828_isocdbg("URB status %d [%s].\n", status, errmsg);
+ } else {
+ au0828_isocdbg("URB packet %d, status %d [%s].\n",
+ packet, status, errmsg);
+ }
+}
+
+static int check_dev(struct au0828_dev *dev)
+{
+ if (dev->dev_state & DEV_DISCONNECTED) {
+ printk(KERN_INFO "v4l2 ioctl: device not present\n");
+ return -ENODEV;
+ }
+
+ if (dev->dev_state & DEV_MISCONFIGURED) {
+ printk(KERN_INFO "v4l2 ioctl: device is misconfigured; "
+ "close and open it again\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+/*
+ * IRQ callback, called by URB callback
+ */
+static void au0828_irq_callback(struct urb *urb)
+{
+ struct au0828_dmaqueue *dma_q = urb->context;
+ struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
+ int rc, i;
+
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ au0828_isocdbg("au0828_irq_callback called: status kill\n");
+ return;
+ default: /* unknown error */
+ au0828_isocdbg("urb completition error %d.\n", urb->status);
+ break;
+ }
+
+ /* Copy data from URB */
+ spin_lock(&dev->slock);
+ rc = dev->isoc_ctl.isoc_copy(dev, urb);
+ spin_unlock(&dev->slock);
+
+ /* Reset urb buffers */
+ for (i = 0; i < urb->number_of_packets; i++) {
+ urb->iso_frame_desc[i].status = 0;
+ urb->iso_frame_desc[i].actual_length = 0;
+ }
+ urb->status = 0;
+
+ urb->status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (urb->status) {
+ au0828_isocdbg("urb resubmit failed (error=%i)\n",
+ urb->status);
+ }
+}
+
+/*
+ * Stop and Deallocate URBs
+ */
+void au0828_uninit_isoc(struct au0828_dev *dev)
+{
+ struct urb *urb;
+ int i;
+
+ au0828_isocdbg("au0828: called au0828_uninit_isoc\n");
+
+ dev->isoc_ctl.nfields = -1;
+ for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
+ urb = dev->isoc_ctl.urb[i];
+ if (urb) {
+ if (!irqs_disabled())
+ usb_kill_urb(urb);
+ else
+ usb_unlink_urb(urb);
+
+ if (dev->isoc_ctl.transfer_buffer[i]) {
+ usb_buffer_free(dev->usbdev,
+ urb->transfer_buffer_length,
+ dev->isoc_ctl.transfer_buffer[i],
+ urb->transfer_dma);
+ }
+ usb_free_urb(urb);
+ dev->isoc_ctl.urb[i] = NULL;
+ }
+ dev->isoc_ctl.transfer_buffer[i] = NULL;
+ }
+
+ kfree(dev->isoc_ctl.urb);
+ kfree(dev->isoc_ctl.transfer_buffer);
+
+ dev->isoc_ctl.urb = NULL;
+ dev->isoc_ctl.transfer_buffer = NULL;
+ dev->isoc_ctl.num_bufs = 0;
+}
+
+/*
+ * Allocate URBs and start IRQ
+ */
+int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
+ int num_bufs, int max_pkt_size,
+ int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb))
+{
+ struct au0828_dmaqueue *dma_q = &dev->vidq;
+ int i;
+ int sb_size, pipe;
+ struct urb *urb;
+ int j, k;
+ int rc;
+
+ au0828_isocdbg("au0828: called au0828_prepare_isoc\n");
+
+ /* De-allocates all pending stuff */
+ au0828_uninit_isoc(dev);
+
+ dev->isoc_ctl.isoc_copy = isoc_copy;
+ dev->isoc_ctl.num_bufs = num_bufs;
+
+ dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
+ if (!dev->isoc_ctl.urb) {
+ au0828_isocdbg("cannot alloc memory for usb buffers\n");
+ return -ENOMEM;
+ }
+
+ dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
+ GFP_KERNEL);
+ if (!dev->isoc_ctl.transfer_buffer) {
+ au0828_isocdbg("cannot allocate memory for usb transfer\n");
+ kfree(dev->isoc_ctl.urb);
+ return -ENOMEM;
+ }
+
+ dev->isoc_ctl.max_pkt_size = max_pkt_size;
+ dev->isoc_ctl.buf = NULL;
+
+ sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
+
+ /* allocate urbs and transfer buffers */
+ for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
+ urb = usb_alloc_urb(max_packets, GFP_KERNEL);
+ if (!urb) {
+ au0828_isocdbg("cannot alloc isoc_ctl.urb %i\n", i);
+ au0828_uninit_isoc(dev);
+ return -ENOMEM;
+ }
+ dev->isoc_ctl.urb[i] = urb;
+
+ dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->usbdev,
+ sb_size, GFP_KERNEL, &urb->transfer_dma);
+ if (!dev->isoc_ctl.transfer_buffer[i]) {
+ printk("unable to allocate %i bytes for transfer"
+ " buffer %i%s\n",
+ sb_size, i,
+ in_interrupt() ? " while in int" : "");
+ au0828_uninit_isoc(dev);
+ return -ENOMEM;
+ }
+ memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
+
+ pipe = usb_rcvisocpipe(dev->usbdev,
+ dev->isoc_in_endpointaddr),
+
+ usb_fill_int_urb(urb, dev->usbdev, pipe,
+ dev->isoc_ctl.transfer_buffer[i], sb_size,
+ au0828_irq_callback, dma_q, 1);
+
+ urb->number_of_packets = max_packets;
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+
+ k = 0;
+ for (j = 0; j < max_packets; j++) {
+ urb->iso_frame_desc[j].offset = k;
+ urb->iso_frame_desc[j].length =
+ dev->isoc_ctl.max_pkt_size;
+ k += dev->isoc_ctl.max_pkt_size;
+ }
+ }
+
+ init_waitqueue_head(&dma_q->wq);
+
+ /* submit urbs and enables IRQ */
+ for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
+ rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
+ if (rc) {
+ au0828_isocdbg("submit of urb %i failed (error=%i)\n",
+ i, rc);
+ au0828_uninit_isoc(dev);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Announces that a buffer were filled and request the next
+ */
+static inline void buffer_filled(struct au0828_dev *dev,
+ struct au0828_dmaqueue *dma_q,
+ struct au0828_buffer *buf)
+{
+ /* Advice that buffer was filled */
+ au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
+
+ buf->vb.state = VIDEOBUF_DONE;
+ buf->vb.field_count++;
+ do_gettimeofday(&buf->vb.ts);
+
+ dev->isoc_ctl.buf = NULL;
+
+ list_del(&buf->vb.queue);
+ wake_up(&buf->vb.done);
+}
+
+/*
+ * Identify the buffer header type and properly handles
+ */
+static void au0828_copy_video(struct au0828_dev *dev,
+ struct au0828_dmaqueue *dma_q,
+ struct au0828_buffer *buf,
+ unsigned char *p,
+ unsigned char *outp, unsigned long len)
+{
+ void *fieldstart, *startwrite, *startread;
+ int linesdone, currlinedone, offset, lencopy, remain;
+ int bytesperline = dev->width << 1; /* Assumes 16-bit depth @@@@ */
+
+ if (dma_q->pos + len > buf->vb.size)
+ len = buf->vb.size - dma_q->pos;
+
+ startread = p;
+ remain = len;
+
+ /* Interlaces frame */
+ if (buf->top_field)
+ fieldstart = outp;
+ else
+ fieldstart = outp + bytesperline;
+
+ linesdone = dma_q->pos / bytesperline;
+ currlinedone = dma_q->pos % bytesperline;
+ offset = linesdone * bytesperline * 2 + currlinedone;
+ startwrite = fieldstart + offset;
+ lencopy = bytesperline - currlinedone;
+ lencopy = lencopy > remain ? remain : lencopy;
+
+ if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
+ au0828_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
+ ((char *)startwrite + lencopy) -
+ ((char *)outp + buf->vb.size));
+ remain = (char *)outp + buf->vb.size - (char *)startwrite;
+ lencopy = remain;
+ }
+ if (lencopy <= 0)
+ return;
+ memcpy(startwrite, startread, lencopy);
+
+ remain -= lencopy;
+
+ while (remain > 0) {
+ startwrite += lencopy + bytesperline;
+ startread += lencopy;
+ if (bytesperline > remain)
+ lencopy = remain;
+ else
+ lencopy = bytesperline;
+
+ if ((char *)startwrite + lencopy > (char *)outp +
+ buf->vb.size) {
+ au0828_isocdbg("Overflow %zi bytes past buf end (2)\n",
+ ((char *)startwrite + lencopy) -
+ ((char *)outp + buf->vb.size));
+ lencopy = remain = (char *)outp + buf->vb.size -
+ (char *)startwrite;
+ }
+ if (lencopy <= 0)
+ break;
+
+ memcpy(startwrite, startread, lencopy);
+
+ remain -= lencopy;
+ }
+
+ if (offset > 1440) {
+ /* We have enough data to check for greenscreen */
+ if (outp[0] < 0x60 && outp[1440] < 0x60)
+ dev->greenscreen_detected = 1;
+ }
+
+ dma_q->pos += len;
+}
+
+/*
+ * video-buf generic routine to get the next available buffer
+ */
+static inline void get_next_buf(struct au0828_dmaqueue *dma_q,
+ struct au0828_buffer **buf)
+{
+ struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
+
+ if (list_empty(&dma_q->active)) {
+ au0828_isocdbg("No active queue to serve\n");
+ dev->isoc_ctl.buf = NULL;
+ *buf = NULL;
+ return;
+ }
+
+ /* Get the next buffer */
+ *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue);
+ dev->isoc_ctl.buf = *buf;
+
+ return;
+}
+
+/*
+ * Controls the isoc copy of each urb packet
+ */
+static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
+{
+ struct au0828_buffer *buf;
+ struct au0828_dmaqueue *dma_q = urb->context;
+ unsigned char *outp = NULL;
+ int i, len = 0, rc = 1;
+ unsigned char *p;
+ unsigned char fbyte;
+
+ if (!dev)
+ return 0;
+
+ if ((dev->dev_state & DEV_DISCONNECTED) ||
+ (dev->dev_state & DEV_MISCONFIGURED))
+ return 0;
+
+ if (urb->status < 0) {
+ print_err_status(dev, -1, urb->status);
+ if (urb->status == -ENOENT)
+ return 0;
+ }
+
+ buf = dev->isoc_ctl.buf;
+ if (buf != NULL)
+ outp = videobuf_to_vmalloc(&buf->vb);
+
+ for (i = 0; i < urb->number_of_packets; i++) {
+ int status = urb->iso_frame_desc[i].status;
+
+ if (status < 0) {
+ print_err_status(dev, i, status);
+ if (urb->iso_frame_desc[i].status != -EPROTO)
+ continue;
+ }
+
+ if (urb->iso_frame_desc[i].actual_length <= 0)
+ continue;
+
+ if (urb->iso_frame_desc[i].actual_length >
+ dev->max_pkt_size) {
+ au0828_isocdbg("packet bigger than packet size");
+ continue;
+ }
+
+ p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+ fbyte = p[0];
+ len = urb->iso_frame_desc[i].actual_length - 4;
+ p += 4;
+
+ if (fbyte & 0x80) {
+ len -= 4;
+ p += 4;
+ au0828_isocdbg("Video frame %s\n",
+ (fbyte & 0x40) ? "odd" : "even");
+ if (!(fbyte & 0x40)) {
+ if (buf != NULL)
+ buffer_filled(dev, dma_q, buf);
+ get_next_buf(dma_q, &buf);
+ if (buf == NULL)
+ outp = NULL;
+ else
+ outp = videobuf_to_vmalloc(&buf->vb);
+ }
+
+ if (buf != NULL) {
+ if (fbyte & 0x40)
+ buf->top_field = 1;
+ else
+ buf->top_field = 0;
+ }
+
+ dma_q->pos = 0;
+ }
+ if (buf != NULL)
+ au0828_copy_video(dev, dma_q, buf, p, outp, len);
+ }
+ return rc;
+}
+
+static int
+buffer_setup(struct videobuf_queue *vq, unsigned int *count,
+ unsigned int *size)
+{
+ struct au0828_fh *fh = vq->priv_data;
+ *size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
+
+ if (0 == *count)
+ *count = AU0828_DEF_BUF;
+
+ if (*count < AU0828_MIN_BUF)
+ *count = AU0828_MIN_BUF;
+ return 0;
+}
+
+/* This is called *without* dev->slock held; please keep it that way */
+static void free_buffer(struct videobuf_queue *vq, struct au0828_buffer *buf)
+{
+ struct au0828_fh *fh = vq->priv_data;
+ struct au0828_dev *dev = fh->dev;
+ unsigned long flags = 0;
+ if (in_interrupt())
+ BUG();
+
+ /* We used to wait for the buffer to finish here, but this didn't work
+ because, as we were keeping the state as VIDEOBUF_QUEUED,
+ videobuf_queue_cancel marked it as finished for us.
+ (Also, it could wedge forever if the hardware was misconfigured.)
+
+ This should be safe; by the time we get here, the buffer isn't
+ queued anymore. If we ever start marking the buffers as
+ VIDEOBUF_ACTIVE, it won't be, though.
+ */
+ spin_lock_irqsave(&dev->slock, flags);
+ if (dev->isoc_ctl.buf == buf)
+ dev->isoc_ctl.buf = NULL;
+ spin_unlock_irqrestore(&dev->slock, flags);
+
+ videobuf_vmalloc_free(&buf->vb);
+ buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int
+buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
+ enum v4l2_field field)
+{
+ struct au0828_fh *fh = vq->priv_data;
+ struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
+ struct au0828_dev *dev = fh->dev;
+ int rc = 0, urb_init = 0;
+
+ buf->vb.size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
+
+ if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
+ return -EINVAL;
+
+ buf->vb.width = dev->width;
+ buf->vb.height = dev->height;
+ buf->vb.field = field;
+
+ if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+ rc = videobuf_iolock(vq, &buf->vb, NULL);
+ if (rc < 0) {
+ printk(KERN_INFO "videobuf_iolock failed\n");
+ goto fail;
+ }
+ }
+
+ if (!dev->isoc_ctl.num_bufs)
+ urb_init = 1;
+
+ if (urb_init) {
+ rc = au0828_init_isoc(dev, AU0828_ISO_PACKETS_PER_URB,
+ AU0828_MAX_ISO_BUFS, dev->max_pkt_size,
+ au0828_isoc_copy);
+ if (rc < 0) {
+ printk(KERN_INFO "au0828_init_isoc failed\n");
+ goto fail;
+ }
+ }
+
+ buf->vb.state = VIDEOBUF_PREPARED;
+ return 0;
+
+fail:
+ free_buffer(vq, buf);
+ return rc;
+}
+
+static void
+buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+ struct au0828_buffer *buf = container_of(vb,
+ struct au0828_buffer,
+ vb);
+ struct au0828_fh *fh = vq->priv_data;
+ struct au0828_dev *dev = fh->dev;
+ struct au0828_dmaqueue *vidq = &dev->vidq;
+
+ buf->vb.state = VIDEOBUF_QUEUED;
+ list_add_tail(&buf->vb.queue, &vidq->active);
+}
+
+static void buffer_release(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct au0828_buffer *buf = container_of(vb,
+ struct au0828_buffer,
+ vb);
+
+ free_buffer(vq, buf);
+}
+
+static struct videobuf_queue_ops au0828_video_qops = {
+ .buf_setup = buffer_setup,
+ .buf_prepare = buffer_prepare,
+ .buf_queue = buffer_queue,
+ .buf_release = buffer_release,
+};
+
+/* ------------------------------------------------------------------
+ V4L2 interface
+ ------------------------------------------------------------------*/
+
+static int au0828_i2s_init(struct au0828_dev *dev)
+{
+ /* Enable i2s mode */
+ au0828_writereg(dev, AU0828_AUDIOCTRL_50C, 0x01);
+ return 0;
+}
+
+/*
+ * Auvitek au0828 analog stream enable
+ * Please set interface0 to AS5 before enable the stream
+ */
+int au0828_analog_stream_enable(struct au0828_dev *d)
+{
+ dprintk(1, "au0828_analog_stream_enable called\n");
+ au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
+ au0828_writereg(d, 0x106, 0x00);
+ /* set x position */
+ au0828_writereg(d, 0x110, 0x00);
+ au0828_writereg(d, 0x111, 0x00);
+ au0828_writereg(d, 0x114, 0xa0);
+ au0828_writereg(d, 0x115, 0x05);
+ /* set y position */
+ au0828_writereg(d, 0x112, 0x02);
+ au0828_writereg(d, 0x113, 0x00);
+ au0828_writereg(d, 0x116, 0xf2);
+ au0828_writereg(d, 0x117, 0x00);
+ au0828_writereg(d, AU0828_SENSORCTRL_100, 0xb3);
+
+ return 0;
+}
+
+int au0828_analog_stream_disable(struct au0828_dev *d)
+{
+ dprintk(1, "au0828_analog_stream_disable called\n");
+ au0828_writereg(d, AU0828_SENSORCTRL_100, 0x0);
+ return 0;
+}
+
+void au0828_analog_stream_reset(struct au0828_dev *dev)
+{
+ dprintk(1, "au0828_analog_stream_reset called\n");
+ au0828_writereg(dev, AU0828_SENSORCTRL_100, 0x0);
+ mdelay(30);
+ au0828_writereg(dev, AU0828_SENSORCTRL_100, 0xb3);
+}
+
+/*
+ * Some operations needs to stop current streaming
+ */
+static int au0828_stream_interrupt(struct au0828_dev *dev)
+{
+ int ret = 0;
+
+ dev->stream_state = STREAM_INTERRUPT;
+ if (dev->dev_state == DEV_DISCONNECTED)
+ return -ENODEV;
+ else if (ret) {
+ dev->dev_state = DEV_MISCONFIGURED;
+ dprintk(1, "%s device is misconfigured!\n", __func__);
+ return ret;
+ }
+ return 0;
+}
+
+/*
+ * au0828_release_resources
+ * unregister v4l2 devices
+ */
+void au0828_analog_unregister(struct au0828_dev *dev)
+{
+ dprintk(1, "au0828_release_resources called\n");
+ mutex_lock(&au0828_sysfs_lock);
+
+ if (dev->vdev) {
+ list_del(&dev->au0828list);
+ video_unregister_device(dev->vdev);
+ }
+ if (dev->vbi_dev)
+ video_unregister_device(dev->vbi_dev);
+
+ mutex_unlock(&au0828_sysfs_lock);
+}
+
+
+/* Usage lock check functions */
+static int res_get(struct au0828_fh *fh)
+{
+ struct au0828_dev *dev = fh->dev;
+ int rc = 0;
+
+ /* This instance already has stream_on */
+ if (fh->stream_on)
+ return rc;
+
+ if (dev->stream_on)
+ return -EBUSY;
+
+ dev->stream_on = 1;
+ fh->stream_on = 1;
+ return rc;
+}
+
+static int res_check(struct au0828_fh *fh)
+{
+ return fh->stream_on;
+}
+
+static void res_free(struct au0828_fh *fh)
+{
+ struct au0828_dev *dev = fh->dev;
+
+ fh->stream_on = 0;
+ dev->stream_on = 0;
+}
+
+static int au0828_v4l2_open(struct file *filp)
+{
+ int minor = video_devdata(filp)->minor;
+ int ret = 0;
+ struct au0828_dev *h, *dev = NULL;
+ struct au0828_fh *fh;
+ int type = 0;
+ struct list_head *list;
+
+ list_for_each(list, &au0828_devlist) {
+ h = list_entry(list, struct au0828_dev, au0828list);
+ if (h->vdev->minor == minor) {
+ dev = h;
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ }
+#ifdef VBI_IS_WORKING
+ if (h->vbi_dev->minor == minor) {
+ dev = h;
+ type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ }
+#endif
+ }
+
+ if (NULL == dev)
+ return -ENODEV;
+
+ fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
+ if (NULL == fh) {
+ dprintk(1, "Failed allocate au0828_fh struct!\n");
+ return -ENOMEM;
+ }
+
+ fh->type = type;
+ fh->dev = dev;
+ filp->private_data = fh;
+
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
+ /* set au0828 interface0 to AS5 here again */
+ ret = usb_set_interface(dev->usbdev, 0, 5);
+ if (ret < 0) {
+ printk(KERN_INFO "Au0828 can't set alternate to 5!\n");
+ return -EBUSY;
+ }
+ dev->width = NTSC_STD_W;
+ dev->height = NTSC_STD_H;
+ dev->frame_size = dev->width * dev->height * 2;
+ dev->field_size = dev->width * dev->height;
+ dev->bytesperline = dev->width * 2;
+
+ au0828_analog_stream_enable(dev);
+ au0828_analog_stream_reset(dev);
+
+ /* If we were doing ac97 instead of i2s, it would go here...*/
+ au0828_i2s_init(dev);
+
+ dev->stream_state = STREAM_OFF;
+ dev->dev_state |= DEV_INITIALIZED;
+ }
+
+ dev->users++;
+
+ videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops,
+ NULL, &dev->slock, fh->type,
+ V4L2_FIELD_INTERLACED,
+ sizeof(struct au0828_buffer), fh);
+
+ return ret;
+}
+
+static int au0828_v4l2_close(struct file *filp)
+{
+ int ret;
+ struct au0828_fh *fh = filp->private_data;
+ struct au0828_dev *dev = fh->dev;
+
+ mutex_lock(&dev->lock);
+ if (res_check(fh))
+ res_free(fh);
+
+ if (dev->users == 1) {
+ videobuf_stop(&fh->vb_vidq);
+ videobuf_mmap_free(&fh->vb_vidq);
+
+ if (dev->dev_state & DEV_DISCONNECTED) {
+ au0828_analog_unregister(dev);
+ mutex_unlock(&dev->lock);
+ kfree(dev);
+ return 0;
+ }
+
+ au0828_analog_stream_disable(dev);
+
+ au0828_uninit_isoc(dev);
+
+ /* When close the device, set the usb intf0 into alt0 to free
+ USB bandwidth */
+ ret = usb_set_interface(dev->usbdev, 0, 0);
+ if (ret < 0)
+ printk(KERN_INFO "Au0828 can't set alternate to 0!\n");
+ }
+
+ kfree(fh);
+ dev->users--;
+ wake_up_interruptible_nr(&dev->open, 1);
+ mutex_unlock(&dev->lock);
+ return 0;
+}
+
+static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *pos)
+{
+ struct au0828_fh *fh = filp->private_data;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ mutex_lock(&dev->lock);
+ rc = res_get(fh);
+ mutex_unlock(&dev->lock);
+
+ if (unlikely(rc < 0))
+ return rc;
+
+ return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
+ filp->f_flags & O_NONBLOCK);
+ }
+ return 0;
+}
+
+static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait)
+{
+ struct au0828_fh *fh = filp->private_data;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ mutex_lock(&dev->lock);
+ rc = res_get(fh);
+ mutex_unlock(&dev->lock);
+
+ if (unlikely(rc < 0))
+ return POLLERR;
+
+ if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
+ return POLLERR;
+
+ return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
+}
+
+static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct au0828_fh *fh = filp->private_data;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ mutex_lock(&dev->lock);
+ rc = res_get(fh);
+ mutex_unlock(&dev->lock);
+
+ if (unlikely(rc < 0))
+ return rc;
+
+ rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+
+ dprintk(2, "vma start=0x%08lx, size=%ld, ret=%d\n",
+ (unsigned long)vma->vm_start,
+ (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
+ rc);
+
+ return rc;
+}
+
+static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
+ struct v4l2_format *format)
+{
+ int ret;
+ int width = format->fmt.pix.width;
+ int height = format->fmt.pix.height;
+ unsigned int maxwidth, maxheight;
+
+ maxwidth = 720;
+ maxheight = 480;
+
+#ifdef VBI_IS_WORKING
+ if (format->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
+ dprintk(1, "VBI format set: to be supported!\n");
+ return 0;
+ }
+ if (format->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return 0;
+#endif
+ if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ /* If they are demanding a format other than the one we support,
+ bail out (tvtime asks for UYVY and then retries with YUYV) */
+ if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY)
+ return -EINVAL;
+
+ /* format->fmt.pix.width only support 720 and height 480 */
+ if (width != 720)
+ width = 720;
+ if (height != 480)
+ height = 480;
+
+ format->fmt.pix.width = width;
+ format->fmt.pix.height = height;
+ format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+ format->fmt.pix.bytesperline = width * 2;
+ format->fmt.pix.sizeimage = width * height * 2;
+ format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ format->fmt.pix.field = V4L2_FIELD_INTERLACED;
+
+ if (cmd == VIDIOC_TRY_FMT)
+ return 0;
+
+ /* maybe set new image format, driver current only support 720*480 */
+ dev->width = width;
+ dev->height = height;
+ dev->frame_size = width * height * 2;
+ dev->field_size = width * height;
+ dev->bytesperline = width * 2;
+
+ if (dev->stream_state == STREAM_ON) {
+ dprintk(1, "VIDIOC_SET_FMT: interrupting stream!\n");
+ ret = au0828_stream_interrupt(dev);
+ if (ret != 0) {
+ dprintk(1, "error interrupting video stream!\n");
+ return ret;
+ }
+ }
+
+ /* set au0828 interface0 to AS5 here again */
+ ret = usb_set_interface(dev->usbdev, 0, 5);
+ if (ret < 0) {
+ printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
+ return -EBUSY;
+ }
+
+ au0828_analog_stream_enable(dev);
+
+ return 0;
+}
+
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
+ if (qc->type)
+ return 0;
+ else
+ return -EINVAL;
+}
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ strlcpy(cap->driver, "au0828", sizeof(cap->driver));
+ strlcpy(cap->card, dev->board.name, sizeof(cap->card));
+ strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
+
+ cap->version = AU0828_VERSION_CODE;
+
+ /*set the device capabilities */
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
+#ifdef VBI_IS_WORKING
+ V4L2_CAP_VBI_CAPTURE |
+#endif
+ V4L2_CAP_AUDIO |
+ V4L2_CAP_READWRITE |
+ V4L2_CAP_STREAMING |
+ V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ if (f->index)
+ return -EINVAL;
+
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ strcpy(f->description, "Packed YUV2");
+
+ f->flags = 0;
+ f->pixelformat = V4L2_PIX_FMT_UYVY;
+
+ return 0;
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ f->fmt.pix.width = dev->width;
+ f->fmt.pix.height = dev->height;
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+ f->fmt.pix.bytesperline = dev->bytesperline;
+ f->fmt.pix.sizeimage = dev->frame_size;
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */
+ f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+ return 0;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ return au0828_set_format(dev, VIDIOC_TRY_FMT, f);
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ if (videobuf_queue_is_busy(&fh->vb_vidq)) {
+ printk(KERN_INFO "%s queue busy\n", __func__);
+ rc = -EBUSY;
+ goto out;
+ }
+
+ if (dev->stream_on && !fh->stream_on) {
+ printk(KERN_INFO "%s device in use by another fh\n", __func__);
+ rc = -EBUSY;
+ goto out;
+ }
+
+ return au0828_set_format(dev, VIDIOC_S_FMT, f);
+out:
+ return rc;
+}
+
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ /* FIXME: when we support something other than NTSC, we are going to
+ have to make the au0828 bridge adjust the size of its capture
+ buffer, which is currently hardcoded at 720x480 */
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_std, *norm);
+ return 0;
+}
+
+static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *input)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ unsigned int tmp;
+
+ static const char *inames[] = {
+ [AU0828_VMUX_UNDEFINED] = "Undefined",
+ [AU0828_VMUX_COMPOSITE] = "Composite",
+ [AU0828_VMUX_SVIDEO] = "S-Video",
+ [AU0828_VMUX_CABLE] = "Cable TV",
+ [AU0828_VMUX_TELEVISION] = "Television",
+ [AU0828_VMUX_DVB] = "DVB",
+ [AU0828_VMUX_DEBUG] = "tv debug"
+ };
+
+ tmp = input->index;
+
+ if (tmp > AU0828_MAX_INPUT)
+ return -EINVAL;
+ if (AUVI_INPUT(tmp).type == 0)
+ return -EINVAL;
+
+ input->index = tmp;
+ strcpy(input->name, inames[AUVI_INPUT(tmp).type]);
+ if ((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) ||
+ (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE))
+ input->type |= V4L2_INPUT_TYPE_TUNER;
+ else
+ input->type |= V4L2_INPUT_TYPE_CAMERA;
+
+ input->std = dev->vdev->tvnorms;
+
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ *i = dev->ctrl_input;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int i;
+ struct v4l2_routing route;
+
+ dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __func__,
+ index);
+ if (index >= AU0828_MAX_INPUT)
+ return -EINVAL;
+ if (AUVI_INPUT(index).type == 0)
+ return -EINVAL;
+ dev->ctrl_input = index;
+
+ switch (AUVI_INPUT(index).type) {
+ case AU0828_VMUX_SVIDEO:
+ dev->input_type = AU0828_VMUX_SVIDEO;
+ break;
+ case AU0828_VMUX_COMPOSITE:
+ dev->input_type = AU0828_VMUX_COMPOSITE;
+ break;
+ case AU0828_VMUX_TELEVISION:
+ dev->input_type = AU0828_VMUX_TELEVISION;
+ break;
+ default:
+ dprintk(1, "VIDIOC_S_INPUT unknown input type set [%d]\n",
+ AUVI_INPUT(index).type);
+ break;
+ }
+
+ route.input = AUVI_INPUT(index).vmux;
+ route.output = 0;
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, &route);
+
+ for (i = 0; i < AU0828_MAX_INPUT; i++) {
+ int enable = 0;
+ if (AUVI_INPUT(i).audio_setup == NULL)
+ continue;
+
+ if (i == index)
+ enable = 1;
+ else
+ enable = 0;
+ if (enable) {
+ (AUVI_INPUT(i).audio_setup)(dev, enable);
+ } else {
+ /* Make sure we leave it turned on if some
+ other input is routed to this callback */
+ if ((AUVI_INPUT(i).audio_setup) !=
+ ((AUVI_INPUT(index).audio_setup))) {
+ (AUVI_INPUT(i).audio_setup)(dev, enable);
+ }
+ }
+ }
+
+ route.input = AUVI_INPUT(index).amux;
+ v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, &route);
+ return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ unsigned int index = a->index;
+
+ if (a->index > 1)
+ return -EINVAL;
+
+ index = dev->ctrl_ainput;
+ if (index == 0)
+ strcpy(a->name, "Television");
+ else
+ strcpy(a->name, "Line in");
+
+ a->capability = V4L2_AUDCAP_STEREO;
+ a->index = index;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ if (a->index != dev->ctrl_ainput)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
+ return 0;
+
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ if (t->index != 0)
+ return -EINVAL;
+
+ strcpy(t->name, "Auvitek tuner");
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *t)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ if (t->index != 0)
+ return -EINVAL;
+
+ t->type = V4L2_TUNER_ANALOG_TV;
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
+ dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal,
+ t->afc);
+ return 0;
+
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *freq)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ freq->type = V4L2_TUNER_ANALOG_TV;
+ freq->frequency = dev->ctrl_freq;
+ return 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *freq)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ if (freq->tuner != 0)
+ return -EINVAL;
+ if (freq->type != V4L2_TUNER_ANALOG_TV)
+ return -EINVAL;
+
+ dev->ctrl_freq = freq->frequency;
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, freq);
+
+ au0828_analog_stream_reset(dev);
+
+ return 0;
+}
+
+static int vidioc_g_chip_ident(struct file *file, void *priv,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ chip->ident = V4L2_IDENT_NONE;
+ chip->revision = 0;
+
+ if (v4l2_chip_match_host(&chip->match)) {
+ chip->ident = V4L2_IDENT_AU0828;
+ return 0;
+ }
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
+ if (chip->ident == V4L2_IDENT_NONE)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vidioc_cropcap(struct file *file, void *priv,
+ struct v4l2_cropcap *cc)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ cc->bounds.left = 0;
+ cc->bounds.top = 0;
+ cc->bounds.width = dev->width;
+ cc->bounds.height = dev->height;
+
+ cc->defrect = cc->bounds;
+
+ cc->pixelaspect.numerator = 54;
+ cc->pixelaspect.denominator = 59;
+
+ return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ au0828_analog_stream_enable(dev);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
+ }
+
+ mutex_lock(&dev->lock);
+ rc = res_get(fh);
+
+ if (likely(rc >= 0))
+ rc = videobuf_streamon(&fh->vb_vidq);
+ mutex_unlock(&dev->lock);
+
+ return rc;
+}
+
+static int vidioc_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int i;
+ int ret;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ if (type != fh->type)
+ return -EINVAL;
+
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
+ ret = au0828_stream_interrupt(dev);
+ if (ret != 0)
+ return ret;
+ }
+
+ for (i = 0; i < AU0828_MAX_INPUT; i++) {
+ if (AUVI_INPUT(i).audio_setup == NULL)
+ continue;
+ (AUVI_INPUT(i).audio_setup)(dev, 0);
+ }
+
+ mutex_lock(&dev->lock);
+ videobuf_streamoff(&fh->vb_vidq);
+ res_free(fh);
+ mutex_unlock(&dev->lock);
+
+ return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ switch (reg->match.type) {
+ case V4L2_CHIP_MATCH_I2C_DRIVER:
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int vidioc_s_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ switch (reg->match.type) {
+ case V4L2_CHIP_MATCH_I2C_DRIVER:
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+#endif
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *rb)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ return videobuf_reqbufs(&fh->vb_vidq, rb);
+}
+
+static int vidioc_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *b)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ return videobuf_querybuf(&fh->vb_vidq, b);
+}
+
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ return videobuf_qbuf(&fh->vb_vidq, b);
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ /* Workaround for a bug in the au0828 hardware design that sometimes
+ results in the colorspace being inverted */
+ if (dev->greenscreen_detected == 1) {
+ dprintk(1, "Detected green frame. Resetting stream...\n");
+ au0828_analog_stream_reset(dev);
+ dev->greenscreen_detected = 0;
+ }
+
+ return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
+}
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
+{
+ struct au0828_fh *fh = priv;
+
+ return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
+}
+#endif
+
+static struct v4l2_file_operations au0828_v4l_fops = {
+ .owner = THIS_MODULE,
+ .open = au0828_v4l2_open,
+ .release = au0828_v4l2_close,
+ .read = au0828_v4l2_read,
+ .poll = au0828_v4l2_poll,
+ .mmap = au0828_v4l2_mmap,
+ .ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+#ifdef VBI_IS_WORKING
+ .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
+ .vidioc_try_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
+ .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
+#endif
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_cropcap = vidioc_cropcap,
+#ifdef VBI_IS_WORKING
+ .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
+ .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
+ .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
+#endif
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+ .vidioc_s_std = vidioc_s_std,
+ .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = vidioc_g_register,
+ .vidioc_s_register = vidioc_s_register,
+#endif
+ .vidioc_g_chip_ident = vidioc_g_chip_ident,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ .vidiocgmbuf = vidiocgmbuf,
+#endif
+};
+
+static const struct video_device au0828_video_template = {
+ .fops = &au0828_v4l_fops,
+ .release = video_device_release,
+ .ioctl_ops = &video_ioctl_ops,
+ .minor = -1,
+ .tvnorms = V4L2_STD_NTSC_M,
+ .current_norm = V4L2_STD_NTSC_M,
+};
+
+/**************************************************************************/
+
+int au0828_analog_register(struct au0828_dev *dev,
+ struct usb_interface *interface)
+{
+ int retval = -ENOMEM;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ int i;
+
+ dprintk(1, "au0828_analog_register called!\n");
+
+ /* set au0828 usb interface0 to as5 */
+ retval = usb_set_interface(dev->usbdev,
+ interface->cur_altsetting->desc.bInterfaceNumber, 5);
+ if (retval != 0) {
+ printk(KERN_INFO "Failure setting usb interface0 to as5\n");
+ return retval;
+ }
+
+ /* Figure out which endpoint has the isoc interface */
+ iface_desc = interface->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
+ endpoint = &iface_desc->endpoint[i].desc;
+ if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+ == USB_DIR_IN) &&
+ ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_ISOC)) {
+
+ /* we find our isoc in endpoint */
+ u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize);
+ dev->max_pkt_size = (tmp & 0x07ff) *
+ (((tmp & 0x1800) >> 11) + 1);
+ dev->isoc_in_endpointaddr = endpoint->bEndpointAddress;
+ }
+ }
+ if (!(dev->isoc_in_endpointaddr)) {
+ printk(KERN_INFO "Could not locate isoc endpoint\n");
+ kfree(dev);
+ return -ENODEV;
+ }
+
+ init_waitqueue_head(&dev->open);
+ spin_lock_init(&dev->slock);
+ mutex_init(&dev->lock);
+
+ INIT_LIST_HEAD(&dev->vidq.active);
+ INIT_LIST_HEAD(&dev->vidq.queued);
+
+ dev->width = NTSC_STD_W;
+ dev->height = NTSC_STD_H;
+ dev->field_size = dev->width * dev->height;
+ dev->frame_size = dev->field_size << 1;
+ dev->bytesperline = dev->width << 1;
+ dev->ctrl_ainput = 0;
+
+ /* allocate and fill v4l2 video struct */
+ dev->vdev = video_device_alloc();
+ if (NULL == dev->vdev) {
+ dprintk(1, "Can't allocate video_device.\n");
+ return -ENOMEM;
+ }
+
+#ifdef VBI_IS_WORKING
+ dev->vbi_dev = video_device_alloc();
+ if (NULL == dev->vbi_dev) {
+ dprintk(1, "Can't allocate vbi_device.\n");
+ kfree(dev->vdev);
+ return -ENOMEM;
+ }
+#endif
+
+ /* Fill the video capture device struct */
+ *dev->vdev = au0828_video_template;
+ dev->vdev->parent = &dev->usbdev->dev;
+ strcpy(dev->vdev->name, "au0828a video");
+
+#ifdef VBI_IS_WORKING
+ /* Setup the VBI device */
+ *dev->vbi_dev = au0828_video_template;
+ dev->vbi_dev->parent = &dev->usbdev->dev;
+ strcpy(dev->vbi_dev->name, "au0828a vbi");
+#endif
+
+ list_add_tail(&dev->au0828list, &au0828_devlist);
+
+ /* Register the v4l2 device */
+ retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1);
+ if (retval != 0) {
+ dprintk(1, "unable to register video device (error = %d).\n",
+ retval);
+ list_del(&dev->au0828list);
+ video_device_release(dev->vdev);
+ return -ENODEV;
+ }
+
+#ifdef VBI_IS_WORKING
+ /* Register the vbi device */
+ retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1);
+ if (retval != 0) {
+ dprintk(1, "unable to register vbi device (error = %d).\n",
+ retval);
+ list_del(&dev->au0828list);
+ video_device_release(dev->vbi_dev);
+ video_device_release(dev->vdev);
+ return -ENODEV;
+ }
+#endif
+
+ dprintk(1, "%s completed!\n", __func__);
+
+ return 0;
+}
+
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index 9d6a1161dc98..6ed1a6129731 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -24,6 +24,11 @@
#include <linux/i2c-algo-bit.h>
#include <media/tveeprom.h>
+/* Analog */
+#include <linux/videodev2.h>
+#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
+
/* DVB */
#include "demux.h"
#include "dmxdev.h"
@@ -39,8 +44,45 @@
#define URB_COUNT 16
#define URB_BUFSIZE (0xe522)
+/* Analog constants */
+#define NTSC_STD_W 720
+#define NTSC_STD_H 480
+
+#define AU0828_INTERLACED_DEFAULT 1
+#define V4L2_CID_PRIVATE_SHARPNESS (V4L2_CID_PRIVATE_BASE + 0)
+
+/* Defination for AU0828 USB transfer */
+#define AU0828_MAX_ISO_BUFS 12 /* maybe resize this value in the future */
+#define AU0828_ISO_PACKETS_PER_URB 10
+
+#define AU0828_MIN_BUF 4
+#define AU0828_DEF_BUF 8
+
+#define AU0828_MAX_INPUT 4
+
+enum au0828_itype {
+ AU0828_VMUX_UNDEFINED = 0,
+ AU0828_VMUX_COMPOSITE,
+ AU0828_VMUX_SVIDEO,
+ AU0828_VMUX_CABLE,
+ AU0828_VMUX_TELEVISION,
+ AU0828_VMUX_DVB,
+ AU0828_VMUX_DEBUG
+};
+
+struct au0828_input {
+ enum au0828_itype type;
+ unsigned int vmux;
+ unsigned int amux;
+ void (*audio_setup) (void *priv, int enable);
+};
+
struct au0828_board {
char *name;
+ unsigned int tuner_type;
+ unsigned char tuner_addr;
+ struct au0828_input input[AU0828_MAX_INPUT];
+
};
struct au0828_dvb {
@@ -55,31 +97,143 @@ struct au0828_dvb {
int feeding;
};
+enum au0828_stream_state {
+ STREAM_OFF,
+ STREAM_INTERRUPT,
+ STREAM_ON
+};
+
+#define AUVI_INPUT(nr) (dev->board.input[nr])
+
+/* device state */
+enum au0828_dev_state {
+ DEV_INITIALIZED = 0x01,
+ DEV_DISCONNECTED = 0x02,
+ DEV_MISCONFIGURED = 0x04
+};
+
+struct au0828_fh {
+ struct au0828_dev *dev;
+ unsigned int stream_on:1; /* Locks streams */
+ struct videobuf_queue vb_vidq;
+ enum v4l2_buf_type type;
+};
+
+struct au0828_usb_isoc_ctl {
+ /* max packet size of isoc transaction */
+ int max_pkt_size;
+
+ /* number of allocated urbs */
+ int num_bufs;
+
+ /* urb for isoc transfers */
+ struct urb **urb;
+
+ /* transfer buffers for isoc transfer */
+ char **transfer_buffer;
+
+ /* Last buffer command and region */
+ u8 cmd;
+ int pos, size, pktsize;
+
+ /* Last field: ODD or EVEN? */
+ int field;
+
+ /* Stores incomplete commands */
+ u32 tmp_buf;
+ int tmp_buf_len;
+
+ /* Stores already requested buffers */
+ struct au0828_buffer *buf;
+
+ /* Stores the number of received fields */
+ int nfields;
+
+ /* isoc urb callback */
+ int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb);
+
+};
+
+/* buffer for one video frame */
+struct au0828_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct videobuf_buffer vb;
+
+ struct list_head frame;
+ int top_field;
+ int receiving;
+};
+
+struct au0828_dmaqueue {
+ struct list_head active;
+ struct list_head queued;
+
+ wait_queue_head_t wq;
+
+ /* Counters to control buffer fill */
+ int pos;
+};
+
struct au0828_dev {
struct mutex mutex;
struct usb_device *usbdev;
- int board;
+ int boardnr;
+ struct au0828_board board;
u8 ctrlmsg[64];
/* I2C */
struct i2c_adapter i2c_adap;
- struct i2c_algo_bit_data i2c_algo;
+ struct i2c_algorithm i2c_algo;
struct i2c_client i2c_client;
u32 i2c_rc;
/* Digital */
struct au0828_dvb dvb;
+ /* Analog */
+ struct list_head au0828list;
+ struct v4l2_device v4l2_dev;
+ int users;
+ unsigned int stream_on:1; /* Locks streams */
+ struct video_device *vdev;
+ struct video_device *vbi_dev;
+ int width;
+ int height;
+ u32 field_size;
+ u32 frame_size;
+ u32 bytesperline;
+ int type;
+ u8 ctrl_ainput;
+ __u8 isoc_in_endpointaddr;
+ u8 isoc_init_ok;
+ int greenscreen_detected;
+ unsigned int frame_count;
+ int ctrl_freq;
+ int input_type;
+ unsigned int ctrl_input;
+ enum au0828_dev_state dev_state;
+ enum au0828_stream_state stream_state;
+ wait_queue_head_t open;
+
+ struct mutex lock;
+
+ /* Isoc control struct */
+ struct au0828_dmaqueue vidq;
+ struct au0828_usb_isoc_ctl isoc_ctl;
+ spinlock_t slock;
+
+ /* usb transfer */
+ int alt; /* alternate */
+ int max_pkt_size; /* max packet size of isoc transaction */
+ int num_alt; /* Number of alternative settings */
+ unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
+ struct urb *urb[AU0828_MAX_ISO_BUFS]; /* urb for isoc transfers */
+ char *transfer_buffer[AU0828_MAX_ISO_BUFS];/* transfer buffers for isoc
+ transfer */
+
/* USB / URB Related */
int urb_streaming;
struct urb *urbs[URB_COUNT];
-
-};
-
-struct au0828_buff {
- struct au0828_dev *dev;
- struct urb *purb;
- struct list_head buff_list;
};
/* ----------------------------------------------------------- */
@@ -111,8 +265,13 @@ extern void au0828_card_setup(struct au0828_dev *dev);
/* au0828-i2c.c */
extern int au0828_i2c_register(struct au0828_dev *dev);
extern int au0828_i2c_unregister(struct au0828_dev *dev);
-extern void au0828_call_i2c_clients(struct au0828_dev *dev,
- unsigned int cmd, void *arg);
+
+/* ----------------------------------------------------------- */
+/* au0828-video.c */
+int au0828_analog_register(struct au0828_dev *dev,
+ struct usb_interface *interface);
+int au0828_analog_stream_disable(struct au0828_dev *d);
+void au0828_analog_unregister(struct au0828_dev *dev);
/* ----------------------------------------------------------- */
/* au0828-dvb.c */
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index a07b7b88e5b8..df4516d8dcab 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -29,16 +29,16 @@
*/
#include <linux/module.h>
-#include <linux/delay.h>
#include <linux/types.h>
#include <linux/ioctl.h>
-#include <asm/uaccess.h>
+#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
+#include <media/bt819.h>
MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -48,13 +48,15 @@ static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
/* ----------------------------------------------------------------------- */
struct bt819 {
+ struct v4l2_subdev sd;
unsigned char reg[32];
- int initialized;
- int norm;
+ v4l2_std_id norm;
+ int ident;
int input;
int enable;
int bright;
@@ -63,6 +65,11 @@ struct bt819 {
int sat;
};
+static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct bt819, sd);
+}
+
struct timing {
int hactive;
int hdelay;
@@ -80,24 +87,23 @@ static struct timing timing_data[] = {
/* ----------------------------------------------------------------------- */
-static inline int bt819_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int bt819_write(struct bt819 *decoder, u8 reg, u8 value)
{
- struct bt819 *decoder = i2c_get_clientdata(client);
+ struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
decoder->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int bt819_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
+static inline int bt819_setbit(struct bt819 *decoder, u8 reg, u8 bit, u8 value)
{
- struct bt819 *decoder = i2c_get_clientdata(client);
-
- return bt819_write(client, reg,
+ return bt819_write(decoder, reg,
(decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
}
-static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
+static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int len)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
int ret = -1;
u8 reg;
@@ -105,7 +111,6 @@ static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned
* the adapter understands raw I2C */
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
/* do raw I2C, not smbus compatible */
- struct bt819 *decoder = i2c_get_clientdata(client);
u8 block_data[32];
int block_len;
@@ -126,7 +131,8 @@ static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- if ((ret = bt819_write(client, reg, *data++)) < 0)
+ ret = bt819_write(decoder, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
@@ -135,15 +141,15 @@ static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned
return ret;
}
-static inline int bt819_read(struct i2c_client *client, u8 reg)
+static inline int bt819_read(struct bt819 *decoder, u8 reg)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
+
return i2c_smbus_read_byte_data(client, reg);
}
-static int bt819_init(struct i2c_client *client)
+static int bt819_init(struct v4l2_subdev *sd)
{
- struct bt819 *decoder = i2c_get_clientdata(client);
-
static unsigned char init[] = {
/*0x1f, 0x00,*/ /* Reset */
0x01, 0x59, /* 0x01 input format */
@@ -178,7 +184,8 @@ static int bt819_init(struct i2c_client *client)
0x1a, 0x80, /* 0x1a ADC Interface */
};
- struct timing *timing = &timing_data[decoder->norm];
+ struct bt819 *decoder = to_bt819(sd);
+ struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0];
init[0x03 * 2 - 1] =
(((timing->vdelay >> 8) & 0x03) << 6) |
@@ -192,266 +199,306 @@ static int bt819_init(struct i2c_client *client)
init[0x08 * 2 - 1] = timing->hscale >> 8;
init[0x09 * 2 - 1] = timing->hscale & 0xff;
/* 0x15 in array is address 0x19 */
- init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93; /* Chroma burst delay */
+ init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93; /* Chroma burst delay */
/* reset */
- bt819_write(client, 0x1f, 0x00);
+ bt819_write(decoder, 0x1f, 0x00);
mdelay(1);
/* init */
- return bt819_write_block(client, init, sizeof(init));
+ return bt819_write_block(decoder, init, sizeof(init));
}
/* ----------------------------------------------------------------------- */
-static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
{
- int temp;
+ struct bt819 *decoder = to_bt819(sd);
+ int status = bt819_read(decoder, 0x00);
+ int res = V4L2_IN_ST_NO_SIGNAL;
+ v4l2_std_id std;
- struct bt819 *decoder = i2c_get_clientdata(client);
+ if ((status & 0x80))
+ res = 0;
- if (!decoder->initialized) { /* First call to bt819_init could be */
- bt819_init(client); /* without #FRST = 0 */
- decoder->initialized = 1;
- }
+ if ((status & 0x10))
+ std = V4L2_STD_PAL;
+ else
+ std = V4L2_STD_NTSC;
+ if (pstd)
+ *pstd = std;
+ if (pstatus)
+ *pstatus = status;
- switch (cmd) {
- case 0:
- /* This is just for testing!!! */
- bt819_init(client);
- break;
+ v4l2_dbg(1, debug, sd, "get status %x\n", status);
+ return 0;
+}
- case DECODER_GET_CAPABILITIES:
- {
- struct video_decoder_capability *cap = arg;
+static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ return bt819_status(sd, NULL, std);
+}
- cap->flags = VIDEO_DECODER_PAL |
- VIDEO_DECODER_NTSC |
- VIDEO_DECODER_AUTO |
- VIDEO_DECODER_CCIR;
- cap->inputs = 8;
- cap->outputs = 1;
- break;
+static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+ return bt819_status(sd, status, NULL);
+}
+
+static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct bt819 *decoder = to_bt819(sd);
+ struct timing *timing = NULL;
+
+ v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
+
+ if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
+ v4l2_err(sd, "no notify found!\n");
+
+ if (std & V4L2_STD_NTSC) {
+ v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0);
+ bt819_setbit(decoder, 0x01, 0, 1);
+ bt819_setbit(decoder, 0x01, 1, 0);
+ bt819_setbit(decoder, 0x01, 5, 0);
+ bt819_write(decoder, 0x18, 0x68);
+ bt819_write(decoder, 0x19, 0x5d);
+ /* bt819_setbit(decoder, 0x1a, 5, 1); */
+ timing = &timing_data[1];
+ } else if (std & V4L2_STD_PAL) {
+ v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0);
+ bt819_setbit(decoder, 0x01, 0, 1);
+ bt819_setbit(decoder, 0x01, 1, 1);
+ bt819_setbit(decoder, 0x01, 5, 1);
+ bt819_write(decoder, 0x18, 0x7f);
+ bt819_write(decoder, 0x19, 0x72);
+ /* bt819_setbit(decoder, 0x1a, 5, 0); */
+ timing = &timing_data[0];
+ } else {
+ v4l2_dbg(1, debug, sd, "unsupported norm %llx\n",
+ (unsigned long long)std);
+ return -EINVAL;
}
+ bt819_write(decoder, 0x03,
+ (((timing->vdelay >> 8) & 0x03) << 6) |
+ (((timing->vactive >> 8) & 0x03) << 4) |
+ (((timing->hdelay >> 8) & 0x03) << 2) |
+ ((timing->hactive >> 8) & 0x03));
+ bt819_write(decoder, 0x04, timing->vdelay & 0xff);
+ bt819_write(decoder, 0x05, timing->vactive & 0xff);
+ bt819_write(decoder, 0x06, timing->hdelay & 0xff);
+ bt819_write(decoder, 0x07, timing->hactive & 0xff);
+ bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff);
+ bt819_write(decoder, 0x09, timing->hscale & 0xff);
+ decoder->norm = std;
+ v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, 0);
+ return 0;
+}
- case DECODER_GET_STATUS:
- {
- int *iarg = arg;
- int status;
- int res;
+static int bt819_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ struct bt819 *decoder = to_bt819(sd);
- status = bt819_read(client, 0x00);
- res = 0;
- if ((status & 0x80))
- res |= DECODER_STATUS_GOOD;
+ v4l2_dbg(1, debug, sd, "set input %x\n", route->input);
- switch (decoder->norm) {
- case VIDEO_MODE_NTSC:
- res |= DECODER_STATUS_NTSC;
- break;
- case VIDEO_MODE_PAL:
- res |= DECODER_STATUS_PAL;
- break;
- default:
- case VIDEO_MODE_AUTO:
- if ((status & 0x10))
- res |= DECODER_STATUS_PAL;
- else
- res |= DECODER_STATUS_NTSC;
- break;
- }
- res |= DECODER_STATUS_COLOR;
- *iarg = res;
+ if (route->input < 0 || route->input > 7)
+ return -EINVAL;
- v4l_dbg(1, debug, client, "get status %x\n", *iarg);
- break;
+ if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
+ v4l2_err(sd, "no notify found!\n");
+
+ if (decoder->input != route->input) {
+ v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0);
+ decoder->input = route->input;
+ /* select mode */
+ if (decoder->input == 0) {
+ bt819_setbit(decoder, 0x0b, 6, 0);
+ bt819_setbit(decoder, 0x1a, 1, 1);
+ } else {
+ bt819_setbit(decoder, 0x0b, 6, 1);
+ bt819_setbit(decoder, 0x1a, 1, 0);
+ }
+ v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, 0);
}
+ return 0;
+}
- case DECODER_SET_NORM:
- {
- int *iarg = arg;
- struct timing *timing = NULL;
-
- v4l_dbg(1, debug, client, "set norm %x\n", *iarg);
-
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- bt819_setbit(client, 0x01, 0, 1);
- bt819_setbit(client, 0x01, 1, 0);
- bt819_setbit(client, 0x01, 5, 0);
- bt819_write(client, 0x18, 0x68);
- bt819_write(client, 0x19, 0x5d);
- /* bt819_setbit(client, 0x1a, 5, 1); */
- timing = &timing_data[VIDEO_MODE_NTSC];
- break;
- case VIDEO_MODE_PAL:
- bt819_setbit(client, 0x01, 0, 1);
- bt819_setbit(client, 0x01, 1, 1);
- bt819_setbit(client, 0x01, 5, 1);
- bt819_write(client, 0x18, 0x7f);
- bt819_write(client, 0x19, 0x72);
- /* bt819_setbit(client, 0x1a, 5, 0); */
- timing = &timing_data[VIDEO_MODE_PAL];
- break;
- case VIDEO_MODE_AUTO:
- bt819_setbit(client, 0x01, 0, 0);
- bt819_setbit(client, 0x01, 1, 0);
- break;
- default:
- v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg);
- return -EINVAL;
- }
+static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct bt819 *decoder = to_bt819(sd);
- if (timing) {
- bt819_write(client, 0x03,
- (((timing->vdelay >> 8) & 0x03) << 6) |
- (((timing->vactive >> 8) & 0x03) << 4) |
- (((timing->hdelay >> 8) & 0x03) << 2) |
- ((timing->hactive >> 8) & 0x03) );
- bt819_write(client, 0x04, timing->vdelay & 0xff);
- bt819_write(client, 0x05, timing->vactive & 0xff);
- bt819_write(client, 0x06, timing->hdelay & 0xff);
- bt819_write(client, 0x07, timing->hactive & 0xff);
- bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
- bt819_write(client, 0x09, timing->hscale & 0xff);
- }
+ v4l2_dbg(1, debug, sd, "enable output %x\n", enable);
- decoder->norm = *iarg;
- break;
+ if (decoder->enable != enable) {
+ decoder->enable = enable;
+ bt819_setbit(decoder, 0x16, 7, !enable);
}
+ return 0;
+}
- case DECODER_SET_INPUT:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set input %x\n", *iarg);
-
- if (*iarg < 0 || *iarg > 7)
- return -EINVAL;
-
- if (decoder->input != *iarg) {
- decoder->input = *iarg;
- /* select mode */
- if (decoder->input == 0) {
- bt819_setbit(client, 0x0b, 6, 0);
- bt819_setbit(client, 0x1a, 1, 1);
- } else {
- bt819_setbit(client, 0x0b, 6, 1);
- bt819_setbit(client, 0x1a, 1, 0);
- }
- }
+static int bt819_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
break;
- }
- case DECODER_SET_OUTPUT:
- {
- int *iarg = arg;
+ case V4L2_CID_CONTRAST:
+ v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
+ break;
- v4l_dbg(1, debug, client, "set output %x\n", *iarg);
+ case V4L2_CID_SATURATION:
+ v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
+ break;
- /* not much choice of outputs */
- if (*iarg != 0)
- return -EINVAL;
+ case V4L2_CID_HUE:
+ v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
break;
- }
- case DECODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
- int enable = (*iarg != 0);
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
- v4l_dbg(1, debug, client, "enable output %x\n", *iarg);
+static int bt819_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct bt819 *decoder = to_bt819(sd);
+ int temp;
- if (decoder->enable != enable) {
- decoder->enable = enable;
- bt819_setbit(client, 0x16, 7, !enable);
- }
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ if (decoder->bright == ctrl->value)
+ break;
+ decoder->bright = ctrl->value;
+ bt819_write(decoder, 0x0a, decoder->bright);
break;
- }
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
-
- v4l_dbg(1, debug, client,
- "set picture brightness %d contrast %d colour %d\n",
- pic->brightness, pic->contrast, pic->colour);
+ case V4L2_CID_CONTRAST:
+ if (decoder->contrast == ctrl->value)
+ break;
+ decoder->contrast = ctrl->value;
+ bt819_write(decoder, 0x0c, decoder->contrast & 0xff);
+ bt819_setbit(decoder, 0x0b, 2, ((decoder->contrast >> 8) & 0x01));
+ break;
+ case V4L2_CID_SATURATION:
+ if (decoder->sat == ctrl->value)
+ break;
+ decoder->sat = ctrl->value;
+ bt819_write(decoder, 0x0d, (decoder->sat >> 7) & 0xff);
+ bt819_setbit(decoder, 0x0b, 1, ((decoder->sat >> 15) & 0x01));
+
+ /* Ratio between U gain and V gain must stay the same as
+ the ratio between the default U and V gain values. */
+ temp = (decoder->sat * 180) / 254;
+ bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
+ bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
+ break;
- if (decoder->bright != pic->brightness) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->bright = pic->brightness;
- bt819_write(client, 0x0a,
- (decoder->bright >> 8) - 128);
- }
+ case V4L2_CID_HUE:
+ if (decoder->hue == ctrl->value)
+ break;
+ decoder->hue = ctrl->value;
+ bt819_write(decoder, 0x0f, decoder->hue);
+ break;
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 511 we get 0-65535 */
- decoder->contrast = pic->contrast;
- bt819_write(client, 0x0c,
- (decoder->contrast >> 7) & 0xff);
- bt819_setbit(client, 0x0b, 2,
- ((decoder->contrast >> 15) & 0x01));
- }
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
- if (decoder->sat != pic->colour) {
- /* We want 0 to 511 we get 0-65535 */
- decoder->sat = pic->colour;
- bt819_write(client, 0x0d,
- (decoder->sat >> 7) & 0xff);
- bt819_setbit(client, 0x0b, 1,
- ((decoder->sat >> 15) & 0x01));
-
- temp = (decoder->sat * 201) / 237;
- bt819_write(client, 0x0e, (temp >> 7) & 0xff);
- bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
- }
+static int bt819_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct bt819 *decoder = to_bt819(sd);
- if (decoder->hue != pic->hue) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->hue = pic->hue;
- bt819_write(client, 0x0f,
- 128 - (decoder->hue >> 8));
- }
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = decoder->bright;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = decoder->contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->value = decoder->sat;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value = decoder->hue;
break;
- }
-
default:
return -EINVAL;
}
-
return 0;
}
+static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct bt819 *decoder = to_bt819(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
+}
+
/* ----------------------------------------------------------------------- */
-static unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END };
+static const struct v4l2_subdev_core_ops bt819_core_ops = {
+ .g_chip_ident = bt819_g_chip_ident,
+ .g_ctrl = bt819_g_ctrl,
+ .s_ctrl = bt819_s_ctrl,
+ .queryctrl = bt819_queryctrl,
+};
+
+static const struct v4l2_subdev_tuner_ops bt819_tuner_ops = {
+ .s_std = bt819_s_std,
+};
+
+static const struct v4l2_subdev_video_ops bt819_video_ops = {
+ .s_routing = bt819_s_routing,
+ .s_stream = bt819_s_stream,
+ .querystd = bt819_querystd,
+ .g_input_status = bt819_g_input_status,
+};
+
+static const struct v4l2_subdev_ops bt819_ops = {
+ .core = &bt819_core_ops,
+ .tuner = &bt819_tuner_ops,
+ .video = &bt819_video_ops,
+};
-I2C_CLIENT_INSMOD;
+/* ----------------------------------------------------------------------- */
static int bt819_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int i, ver;
struct bt819 *decoder;
+ struct v4l2_subdev *sd;
const char *name;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
- ver = bt819_read(client, 0x17);
+ decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
+ if (decoder == NULL)
+ return -ENOMEM;
+ sd = &decoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &bt819_ops);
+
+ ver = bt819_read(decoder, 0x17);
switch (ver & 0xf0) {
case 0x70:
name = "bt819a";
+ decoder->ident = V4L2_IDENT_BT819A;
break;
case 0x60:
name = "bt817a";
+ decoder->ident = V4L2_IDENT_BT817A;
break;
case 0x20:
name = "bt815a";
+ decoder->ident = V4L2_IDENT_BT815A;
break;
default:
- v4l_dbg(1, debug, client,
+ v4l2_dbg(1, debug, sd,
"unknown chip version 0x%02x\n", ver);
return -ENODEV;
}
@@ -459,28 +506,26 @@ static int bt819_probe(struct i2c_client *client,
v4l_info(client, "%s found @ 0x%x (%s)\n", name,
client->addr << 1, client->adapter->name);
- decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
- if (decoder == NULL)
- return -ENOMEM;
- decoder->norm = VIDEO_MODE_NTSC;
+ decoder->norm = V4L2_STD_NTSC;
decoder->input = 0;
decoder->enable = 1;
- decoder->bright = 32768;
- decoder->contrast = 32768;
- decoder->hue = 32768;
- decoder->sat = 32768;
- decoder->initialized = 0;
- i2c_set_clientdata(client, decoder);
-
- i = bt819_init(client);
+ decoder->bright = 0;
+ decoder->contrast = 0xd8; /* 100% of original signal */
+ decoder->hue = 0;
+ decoder->sat = 0xfe; /* 100% of original signal */
+
+ i = bt819_init(sd);
if (i < 0)
- v4l_dbg(1, debug, client, "init status %d\n", i);
+ v4l2_dbg(1, debug, sd, "init status %d\n", i);
return 0;
}
static int bt819_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_bt819(sd));
return 0;
}
@@ -496,8 +541,6 @@ MODULE_DEVICE_TABLE(i2c, bt819_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "bt819",
- .driverid = I2C_DRIVERID_BT819,
- .command = bt819_command,
.probe = bt819_probe,
.remove = bt819_remove,
.id_table = bt819_id,
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
index 4213867507f8..78db39503947 100644
--- a/drivers/media/video/bt856.c
+++ b/drivers/media/video/bt856.c
@@ -34,10 +34,10 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -47,43 +47,46 @@ static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
/* ----------------------------------------------------------------------- */
#define BT856_REG_OFFSET 0xDA
#define BT856_NR_REG 6
struct bt856 {
+ struct v4l2_subdev sd;
unsigned char reg[BT856_NR_REG];
- int norm;
- int enable;
+ v4l2_std_id norm;
};
+static inline struct bt856 *to_bt856(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct bt856, sd);
+}
+
/* ----------------------------------------------------------------------- */
-static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int bt856_write(struct bt856 *encoder, u8 reg, u8 value)
{
- struct bt856 *encoder = i2c_get_clientdata(client);
+ struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd);
encoder->reg[reg - BT856_REG_OFFSET] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
+static inline int bt856_setbit(struct bt856 *encoder, u8 reg, u8 bit, u8 value)
{
- struct bt856 *encoder = i2c_get_clientdata(client);
-
- return bt856_write(client, reg,
+ return bt856_write(encoder, reg,
(encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) |
(value ? (1 << bit) : 0));
}
-static void bt856_dump(struct i2c_client *client)
+static void bt856_dump(struct bt856 *encoder)
{
int i;
- struct bt856 *encoder = i2c_get_clientdata(client);
- v4l_info(client, "register dump:\n");
+ v4l2_info(&encoder->sd, "register dump:\n");
for (i = 0; i < BT856_NR_REG; i += 2)
printk(KERN_CONT " %02x", encoder->reg[i]);
printk(KERN_CONT "\n");
@@ -91,153 +94,120 @@ static void bt856_dump(struct i2c_client *client)
/* ----------------------------------------------------------------------- */
-static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int bt856_init(struct v4l2_subdev *sd, u32 arg)
{
- struct bt856 *encoder = i2c_get_clientdata(client);
-
- switch (cmd) {
- case 0:
- /* This is just for testing!!! */
- v4l_dbg(1, debug, client, "init\n");
- bt856_write(client, 0xdc, 0x18);
- bt856_write(client, 0xda, 0);
- bt856_write(client, 0xde, 0);
-
- bt856_setbit(client, 0xdc, 3, 1);
- //bt856_setbit(client, 0xdc, 6, 0);
- bt856_setbit(client, 0xdc, 4, 1);
-
- switch (encoder->norm) {
- case VIDEO_MODE_NTSC:
- bt856_setbit(client, 0xdc, 2, 0);
- break;
-
- case VIDEO_MODE_PAL:
- bt856_setbit(client, 0xdc, 2, 1);
- break;
- }
-
- bt856_setbit(client, 0xdc, 1, 1);
- bt856_setbit(client, 0xde, 4, 0);
- bt856_setbit(client, 0xde, 3, 1);
- if (debug != 0)
- bt856_dump(client);
- break;
-
- case ENCODER_GET_CAPABILITIES:
- {
- struct video_encoder_capability *cap = arg;
-
- v4l_dbg(1, debug, client, "get capabilities\n");
+ struct bt856 *encoder = to_bt856(sd);
+
+ /* This is just for testing!!! */
+ v4l2_dbg(1, debug, sd, "init\n");
+ bt856_write(encoder, 0xdc, 0x18);
+ bt856_write(encoder, 0xda, 0);
+ bt856_write(encoder, 0xde, 0);
+
+ bt856_setbit(encoder, 0xdc, 3, 1);
+ /*bt856_setbit(encoder, 0xdc, 6, 0);*/
+ bt856_setbit(encoder, 0xdc, 4, 1);
+
+ if (encoder->norm & V4L2_STD_NTSC)
+ bt856_setbit(encoder, 0xdc, 2, 0);
+ else
+ bt856_setbit(encoder, 0xdc, 2, 1);
+
+ bt856_setbit(encoder, 0xdc, 1, 1);
+ bt856_setbit(encoder, 0xde, 4, 0);
+ bt856_setbit(encoder, 0xde, 3, 1);
+ if (debug != 0)
+ bt856_dump(encoder);
+ return 0;
+}
- cap->flags = VIDEO_ENCODER_PAL |
- VIDEO_ENCODER_NTSC |
- VIDEO_ENCODER_CCIR;
- cap->inputs = 2;
- cap->outputs = 1;
- break;
- }
+static int bt856_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct bt856 *encoder = to_bt856(sd);
- case ENCODER_SET_NORM:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
-
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- bt856_setbit(client, 0xdc, 2, 0);
- break;
-
- case VIDEO_MODE_PAL:
- bt856_setbit(client, 0xdc, 2, 1);
- bt856_setbit(client, 0xda, 0, 0);
- //bt856_setbit(client, 0xda, 0, 1);
- break;
-
- default:
- return -EINVAL;
- }
- encoder->norm = *iarg;
- if (debug != 0)
- bt856_dump(client);
- break;
- }
+ v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
- case ENCODER_SET_INPUT:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set input %d\n", *iarg);
-
- /* We only have video bus.
- * iarg = 0: input is from bt819
- * iarg = 1: input is from ZR36060 */
- switch (*iarg) {
- case 0:
- bt856_setbit(client, 0xde, 4, 0);
- bt856_setbit(client, 0xde, 3, 1);
- bt856_setbit(client, 0xdc, 3, 1);
- bt856_setbit(client, 0xdc, 6, 0);
- break;
- case 1:
- bt856_setbit(client, 0xde, 4, 0);
- bt856_setbit(client, 0xde, 3, 1);
- bt856_setbit(client, 0xdc, 3, 1);
- bt856_setbit(client, 0xdc, 6, 1);
- break;
- case 2: // Color bar
- bt856_setbit(client, 0xdc, 3, 0);
- bt856_setbit(client, 0xde, 4, 1);
- break;
- default:
- return -EINVAL;
- }
-
- if (debug != 0)
- bt856_dump(client);
- break;
+ if (std & V4L2_STD_NTSC) {
+ bt856_setbit(encoder, 0xdc, 2, 0);
+ } else if (std & V4L2_STD_PAL) {
+ bt856_setbit(encoder, 0xdc, 2, 1);
+ bt856_setbit(encoder, 0xda, 0, 0);
+ /*bt856_setbit(encoder, 0xda, 0, 1);*/
+ } else {
+ return -EINVAL;
}
+ encoder->norm = std;
+ if (debug != 0)
+ bt856_dump(encoder);
+ return 0;
+}
- case ENCODER_SET_OUTPUT:
- {
- int *iarg = arg;
+static int bt856_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ struct bt856 *encoder = to_bt856(sd);
- v4l_dbg(1, debug, client, "set output %d\n", *iarg);
+ v4l2_dbg(1, debug, sd, "set input %d\n", route->input);
- /* not much choice of outputs */
- if (*iarg != 0)
- return -EINVAL;
+ /* We only have video bus.
+ * route->input= 0: input is from bt819
+ * route->input= 1: input is from ZR36060 */
+ switch (route->input) {
+ case 0:
+ bt856_setbit(encoder, 0xde, 4, 0);
+ bt856_setbit(encoder, 0xde, 3, 1);
+ bt856_setbit(encoder, 0xdc, 3, 1);
+ bt856_setbit(encoder, 0xdc, 6, 0);
break;
- }
-
- case ENCODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
-
- encoder->enable = !!*iarg;
-
- v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
+ case 1:
+ bt856_setbit(encoder, 0xde, 4, 0);
+ bt856_setbit(encoder, 0xde, 3, 1);
+ bt856_setbit(encoder, 0xdc, 3, 1);
+ bt856_setbit(encoder, 0xdc, 6, 1);
+ break;
+ case 2: /* Color bar */
+ bt856_setbit(encoder, 0xdc, 3, 0);
+ bt856_setbit(encoder, 0xde, 4, 1);
break;
- }
-
default:
return -EINVAL;
}
+ if (debug != 0)
+ bt856_dump(encoder);
return 0;
}
+static int bt856_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT856, 0);
+}
+
/* ----------------------------------------------------------------------- */
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+static const struct v4l2_subdev_core_ops bt856_core_ops = {
+ .g_chip_ident = bt856_g_chip_ident,
+ .init = bt856_init,
+};
+
+static const struct v4l2_subdev_video_ops bt856_video_ops = {
+ .s_std_output = bt856_s_std_output,
+ .s_routing = bt856_s_routing,
+};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_ops bt856_ops = {
+ .core = &bt856_core_ops,
+ .video = &bt856_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
static int bt856_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct bt856 *encoder;
+ struct v4l2_subdev *sd;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -249,41 +219,38 @@ static int bt856_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
- encoder->norm = VIDEO_MODE_NTSC;
- encoder->enable = 1;
- i2c_set_clientdata(client, encoder);
+ sd = &encoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &bt856_ops);
+ encoder->norm = V4L2_STD_NTSC;
- bt856_write(client, 0xdc, 0x18);
- bt856_write(client, 0xda, 0);
- bt856_write(client, 0xde, 0);
+ bt856_write(encoder, 0xdc, 0x18);
+ bt856_write(encoder, 0xda, 0);
+ bt856_write(encoder, 0xde, 0);
- bt856_setbit(client, 0xdc, 3, 1);
- //bt856_setbit(client, 0xdc, 6, 0);
- bt856_setbit(client, 0xdc, 4, 1);
+ bt856_setbit(encoder, 0xdc, 3, 1);
+ /*bt856_setbit(encoder, 0xdc, 6, 0);*/
+ bt856_setbit(encoder, 0xdc, 4, 1);
- switch (encoder->norm) {
+ if (encoder->norm & V4L2_STD_NTSC)
+ bt856_setbit(encoder, 0xdc, 2, 0);
+ else
+ bt856_setbit(encoder, 0xdc, 2, 1);
- case VIDEO_MODE_NTSC:
- bt856_setbit(client, 0xdc, 2, 0);
- break;
-
- case VIDEO_MODE_PAL:
- bt856_setbit(client, 0xdc, 2, 1);
- break;
- }
-
- bt856_setbit(client, 0xdc, 1, 1);
- bt856_setbit(client, 0xde, 4, 0);
- bt856_setbit(client, 0xde, 3, 1);
+ bt856_setbit(encoder, 0xdc, 1, 1);
+ bt856_setbit(encoder, 0xde, 4, 0);
+ bt856_setbit(encoder, 0xde, 3, 1);
if (debug != 0)
- bt856_dump(client);
+ bt856_dump(encoder);
return 0;
}
static int bt856_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_bt856(sd));
return 0;
}
@@ -295,8 +262,6 @@ MODULE_DEVICE_TABLE(i2c, bt856_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "bt856",
- .driverid = I2C_DRIVERID_BT856,
- .command = bt856_command,
.probe = bt856_probe,
.remove = bt856_remove,
.id_table = bt856_id,
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
index 596f9e2376be..350cae4b02c3 100644
--- a/drivers/media/video/bt866.c
+++ b/drivers/media/video/bt866.c
@@ -34,10 +34,10 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -47,22 +47,22 @@ static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
/* ----------------------------------------------------------------------- */
struct bt866 {
+ struct v4l2_subdev sd;
u8 reg[256];
-
- int norm;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
};
-static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data)
+static inline struct bt866 *to_bt866(struct v4l2_subdev *sd)
{
- struct bt866 *encoder = i2c_get_clientdata(client);
+ return container_of(sd, struct bt866, sd);
+}
+
+static int bt866_write(struct bt866 *encoder, u8 subaddr, u8 data)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd);
u8 buffer[2];
int err;
@@ -89,163 +89,120 @@ static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data)
return 0;
}
-static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int bt866_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
{
- struct bt866 *encoder = i2c_get_clientdata(client);
-
- switch (cmd) {
- case ENCODER_GET_CAPABILITIES:
- {
- struct video_encoder_capability *cap = arg;
-
- v4l_dbg(1, debug, client, "get capabilities\n");
-
- cap->flags
- = VIDEO_ENCODER_PAL
- | VIDEO_ENCODER_NTSC
- | VIDEO_ENCODER_CCIR;
- cap->inputs = 2;
- cap->outputs = 1;
- break;
- }
-
- case ENCODER_SET_NORM:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
-
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- break;
-
- case VIDEO_MODE_PAL:
- break;
-
- default:
- return -EINVAL;
- }
- encoder->norm = *iarg;
- break;
- }
-
- case ENCODER_SET_INPUT:
- {
- int *iarg = arg;
- static const __u8 init[] = {
- 0xc8, 0xcc, /* CRSCALE */
- 0xca, 0x91, /* CBSCALE */
- 0xcc, 0x24, /* YC16 | OSDNUM */
- 0xda, 0x00, /* */
- 0xdc, 0x24, /* SETMODE | PAL */
- 0xde, 0x02, /* EACTIVE */
-
- /* overlay colors */
- 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
- 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
- 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
- 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
- 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
- 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
- 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
- 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
-
- 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
- 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
- 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
- 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
- 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
- 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
- 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
- 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
- };
- int i;
- u8 val;
-
- for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
- bt866_write(client, init[i], init[i+1]);
-
- val = encoder->reg[0xdc];
-
- if (*iarg == 0)
- val |= 0x40; /* CBSWAP */
- else
- val &= ~0x40; /* !CBSWAP */
-
- bt866_write(client, 0xdc, val);
-
- val = encoder->reg[0xcc];
- if (*iarg == 2)
- val |= 0x01; /* OSDBAR */
- else
- val &= ~0x01; /* !OSDBAR */
- bt866_write(client, 0xcc, val);
-
- v4l_dbg(1, debug, client, "set input %d\n", *iarg);
-
- switch (*iarg) {
- case 0:
- break;
- case 1:
- break;
- default:
- return -EINVAL;
- }
- break;
- }
-
- case ENCODER_SET_OUTPUT:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set output %d\n", *iarg);
-
- /* not much choice of outputs */
- if (*iarg != 0)
- return -EINVAL;
- break;
- }
-
- case ENCODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
- encoder->enable = !!*iarg;
+ v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
- v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
- break;
- }
-
- case 4711:
- {
- int *iarg = arg;
- __u8 val;
-
- v4l_dbg(1, debug, client, "square %d\n", *iarg);
+ /* Only PAL supported by this driver at the moment! */
+ if (!(std & V4L2_STD_NTSC))
+ return -EINVAL;
+ return 0;
+}
- val = encoder->reg[0xdc];
- if (*iarg)
- val |= 1; /* SQUARE */
- else
- val &= ~1; /* !SQUARE */
- bt866_write(client, 0xdc, val);
+static int bt866_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ static const __u8 init[] = {
+ 0xc8, 0xcc, /* CRSCALE */
+ 0xca, 0x91, /* CBSCALE */
+ 0xcc, 0x24, /* YC16 | OSDNUM */
+ 0xda, 0x00, /* */
+ 0xdc, 0x24, /* SETMODE | PAL */
+ 0xde, 0x02, /* EACTIVE */
+
+ /* overlay colors */
+ 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
+ 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
+ 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
+ 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
+ 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
+ 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
+ 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
+ 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
+
+ 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
+ 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
+ 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
+ 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
+ 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
+ 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
+ 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
+ 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
+ };
+ struct bt866 *encoder = to_bt866(sd);
+ u8 val;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
+ bt866_write(encoder, init[i], init[i+1]);
+
+ val = encoder->reg[0xdc];
+
+ if (route->input == 0)
+ val |= 0x40; /* CBSWAP */
+ else
+ val &= ~0x40; /* !CBSWAP */
+
+ bt866_write(encoder, 0xdc, val);
+
+ val = encoder->reg[0xcc];
+ if (route->input == 2)
+ val |= 0x01; /* OSDBAR */
+ else
+ val &= ~0x01; /* !OSDBAR */
+ bt866_write(encoder, 0xcc, val);
+
+ v4l2_dbg(1, debug, sd, "set input %d\n", route->input);
+
+ switch (route->input) {
+ case 0:
+ case 1:
+ case 2:
break;
- }
-
default:
return -EINVAL;
}
-
return 0;
}
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+#if 0
+/* Code to setup square pixels, might be of some use in the future,
+ but is currently unused. */
+ val = encoder->reg[0xdc];
+ if (*iarg)
+ val |= 1; /* SQUARE */
+ else
+ val &= ~1; /* !SQUARE */
+ bt866_write(client, 0xdc, val);
+#endif
+
+static int bt866_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT866, 0);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops bt866_core_ops = {
+ .g_chip_ident = bt866_g_chip_ident,
+};
+
+static const struct v4l2_subdev_video_ops bt866_video_ops = {
+ .s_std_output = bt866_s_std_output,
+ .s_routing = bt866_s_routing,
+};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_ops bt866_ops = {
+ .core = &bt866_core_ops,
+ .video = &bt866_video_ops,
+};
static int bt866_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct bt866 *encoder;
+ struct v4l2_subdev *sd;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
@@ -253,20 +210,18 @@ static int bt866_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
-
- i2c_set_clientdata(client, encoder);
+ sd = &encoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &bt866_ops);
return 0;
}
static int bt866_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
- return 0;
-}
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
-static int bt866_legacy_probe(struct i2c_adapter *adapter)
-{
- return adapter->id == I2C_HW_B_ZR36067;
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_bt866(sd));
+ return 0;
}
static const struct i2c_device_id bt866_id[] = {
@@ -277,10 +232,7 @@ MODULE_DEVICE_TABLE(i2c, bt866_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "bt866",
- .driverid = I2C_DRIVERID_BT866,
- .command = bt866_command,
.probe = bt866_probe,
.remove = bt866_remove,
- .legacy_probe = bt866_legacy_probe,
.id_table = bt866_id,
};
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
index ce71e8e7b835..3077c45015f5 100644
--- a/drivers/media/video/bt8xx/Kconfig
+++ b/drivers/media/video/bt8xx/Kconfig
@@ -10,7 +10,7 @@ config VIDEO_BT848
select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TDA7432 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TDA9875 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO
---help---
Support for BT848 based frame grabber/overlay boards. This includes
the Miro, Hauppauge and STB boards. Please read the material in
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index d24dcc025e37..b9c3ba51fb86 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -73,6 +73,11 @@ static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input);
static void geovision_muxsel(struct bttv *btv, unsigned int input);
+static void phytec_muxsel(struct bttv *btv, unsigned int input);
+
+static void gv800s_muxsel(struct bttv *btv, unsigned int input);
+static void gv800s_init(struct bttv *btv);
+
static int terratec_active_radio_upgrade(struct bttv *btv);
static int tea5757_read(struct bttv *btv);
static int tea5757_write(struct bttv *btv, int value);
@@ -91,12 +96,10 @@ static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
static unsigned int svhs[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
static unsigned int remote[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
+static unsigned int audiodev[BTTV_MAX];
+static unsigned int saa6588[BTTV_MAX];
static struct bttv *master[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = NULL };
-#ifdef MODULE
-static unsigned int autoload = 1;
-#else
-static unsigned int autoload;
-#endif
+static unsigned int autoload = UNSET;
static unsigned int gpiomask = UNSET;
static unsigned int audioall = UNSET;
static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET };
@@ -115,6 +118,7 @@ module_param_array(pll, int, NULL, 0444);
module_param_array(tuner, int, NULL, 0444);
module_param_array(svhs, int, NULL, 0444);
module_param_array(remote, int, NULL, 0444);
+module_param_array(audiodev, int, NULL, 0444);
module_param_array(audiomux, int, NULL, 0444);
MODULE_PARM_DESC(triton1,"set ETBF pci config bit "
@@ -125,7 +129,14 @@ MODULE_PARM_DESC(latency,"pci latency timer");
MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)");
MODULE_PARM_DESC(tuner,"specify installed tuner type");
-MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)");
+MODULE_PARM_DESC(autoload, "obsolete option, please do not use anymore");
+MODULE_PARM_DESC(audiodev, "specify audio device:\n"
+ "\t\t-1 = no audio\n"
+ "\t\t 0 = autodetect (default)\n"
+ "\t\t 1 = msp3400\n"
+ "\t\t 2 = tda7432\n"
+ "\t\t 3 = tvaudio");
+MODULE_PARM_DESC(saa6588, "if 1, then load the saa6588 RDS module, default (0) is to use the card definition.");
MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)"
" [some VIA/SIS chipsets are known to have problem with overlay]");
@@ -246,6 +257,10 @@ static struct CARD {
{ 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" },
{ 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" },
{ 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xf0500000, BTTV_BOARD_IVCE8784, "IVCE-8784" },
+ { 0xf0500001, BTTV_BOARD_IVCE8784, "IVCE-8784" },
+ { 0xf0500002, BTTV_BOARD_IVCE8784, "IVCE-8784" },
+ { 0xf0500003, BTTV_BOARD_IVCE8784, "IVCE-8784" },
{ 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" },
{ 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" },
@@ -289,6 +304,8 @@ static struct CARD {
/* Duplicate PCI ID, reconfigure for this board during the eeprom read.
* { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB, "Hauppauge ImpactVCB" }, */
+ { 0x109e036e, BTTV_BOARD_CONCEPTRONIC_CTVFMI2, "Conceptronic CTVFMi v2"},
+
/* DVB cards (using pci function .1 for mpeg data xfer) */
{ 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" },
{ 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
@@ -305,6 +322,20 @@ static struct CARD {
{ 0xd200dbc0, BTTV_BOARD_DVICO_FUSIONHDTV_2, "DViCO FusionHDTV 2" },
{ 0x763c008a, BTTV_BOARD_GEOVISION_GV600, "GeoVision GV-600" },
{ 0x18011000, BTTV_BOARD_ENLTV_FM_2, "Encore ENL TV-FM-2" },
+ { 0x763d800a, BTTV_BOARD_GEOVISION_GV800S, "GeoVision GV-800(S) (master)" },
+ { 0x763d800b, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" },
+ { 0x763d800c, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" },
+ { 0x763d800d, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" },
+
+ { 0x15401830, BTTV_BOARD_PV183, "Provideo PV183-1" },
+ { 0x15401831, BTTV_BOARD_PV183, "Provideo PV183-2" },
+ { 0x15401832, BTTV_BOARD_PV183, "Provideo PV183-3" },
+ { 0x15401833, BTTV_BOARD_PV183, "Provideo PV183-4" },
+ { 0x15401834, BTTV_BOARD_PV183, "Provideo PV183-5" },
+ { 0x15401835, BTTV_BOARD_PV183, "Provideo PV183-6" },
+ { 0x15401836, BTTV_BOARD_PV183, "Provideo PV183-7" },
+ { 0x15401837, BTTV_BOARD_PV183, "Provideo PV183-8" },
+
{ 0, -1, NULL }
};
@@ -316,59 +347,50 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_UNKNOWN] = {
.name = " *** UNKNOWN/GENERIC *** ",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
.svhs = 2,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MIRO] = {
.name = "MIRO PCTV",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_HAUPPAUGE] = {
.name = "Hauppauge (bt848)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_STB] = {
.name = "STB, Gateway P/N 6000699 (bt848)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 4, 0, 2, 3 },
.gpiomute = 1,
.no_msp34xx = 1,
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
@@ -377,202 +399,177 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_INTEL] = {
.name = "Intel Create and Share PCI/ Smart Video Recorder III",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_DIAMOND] = {
.name = "Diamond DTV2000",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 3,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0, 1, 0, 1 },
.gpiomute = 3,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_AVERMEDIA] = {
.name = "AVerMedia TVPhone",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomask = 0x0f,
.gpiomux = { 0x0c, 0x04, 0x08, 0x04 },
/* 0x04 for some cards ?? */
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= avermedia_tvphone_audio,
.has_remote = 1,
},
[BTTV_BOARD_MATRIX_VISION] = {
.name = "MATRIX-Vision MV-Delta",
.video_inputs = 5,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0, 0),
.gpiomux = { 0 },
.needs_tvaudio = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x08 ---------------------------------- */
[BTTV_BOARD_FLYVIDEO] = {
.name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xc00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0xc00, 0x800, 0x400 },
.gpiomute = 0xc00,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TURBOTV] = {
.name = "IMS/IXmicro TurboTV",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 3,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 1, 2, 3 },
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_HAUPPAUGE878] = {
.name = "Hauppauge (bt878)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x0f, /* old: 7 */
- .muxsel = { 2, 0, 1, 1 },
+ .muxsel = MUXSEL(2, 0, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MIROPRO] = {
.name = "MIRO PCTV pro",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3014f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20001,0x10001, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x0c ---------------------------------- */
[BTTV_BOARD_ADSTECH_TV] = {
.name = "ADS Technologies Channel Surfer TV (bt848)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 13, 14, 11, 7 },
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_AVERMEDIA98] = {
.name = "AVerMedia TVCapture 98",
.video_inputs = 3,
- .audio_inputs = 4,
- .tuner = 0,
+ /* .audio_inputs= 4, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 13, 14, 11, 7 },
.needs_tvaudio = 1,
.msp34xx_alt = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= avermedia_tv_stereo_audio,
.no_gpioirq = 1,
},
[BTTV_BOARD_VHX] = {
.name = "Aimslab Video Highway Xtreme (VHX)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */
.gpiomute = 4,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ZOLTRIX] = {
.name = "Zoltrix TV-Max",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 1, 0 },
.gpiomute = 10,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x10 ---------------------------------- */
[BTTV_BOARD_PIXVIEWPLAYTV] = {
.name = "Prolink Pixelview PlayTV (bt878)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x01fe00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
/* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
.gpiomux = { 0x001e00, 0, 0x018000, 0x014000 },
.gpiomute = 0x002000,
@@ -580,194 +577,170 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_WINVIEW_601] = {
.name = "Leadtek WinView 601",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x8300f8,
- .muxsel = { 2, 3, 1, 1,0 },
+ .muxsel = MUXSEL(2, 3, 1, 1, 0),
.gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 },
.gpiomute = 0xcfa007,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.volume_gpio = winview_volume,
.has_radio = 1,
},
[BTTV_BOARD_AVEC_INTERCAP] = {
.name = "AVEC Intercapture",
.video_inputs = 3,
- .audio_inputs = 2,
- .tuner = 0,
+ /* .audio_inputs= 2, */
.svhs = 2,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 0, 0, 0 },
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_LIFE_FLYKIT] = {
.name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 0x8dff00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0 },
.no_msp34xx = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x14 ---------------------------------- */
[BTTV_BOARD_CEI_RAFFLES] = {
.name = "CEI Raffles Card",
.video_inputs = 3,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_CONFERENCETV] = {
.name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
.video_inputs = 4,
- .audio_inputs = 2, /* tuner, line in */
- .tuner = 0,
+ /* .audio_inputs= 2, tuner, line in */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_PHOEBE_TVMAS] = {
.name = "Askey CPH050/ Phoebe Tv Master + FM",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xc00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 0x800, 0x400 },
.gpiomute = 0xc00,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MODTEC_205] = {
.name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
+ .has_dig_in = 1,
.gpiomask = 7,
- .muxsel = { 2, 3, -1 },
- .digital_mode = DIGITAL_MODE_CAMERA,
+ .muxsel = MUXSEL(2, 3, 0), /* input 2 is digital */
+ /* .digital_mode= DIGITAL_MODE_CAMERA, */
.gpiomux = { 0, 0, 0, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_ALPS_TSBB5_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x18 ---------------------------------- */
[BTTV_BOARD_MAGICTVIEW061] = {
.name = "Askey CPH05X/06X (bt878) [many vendors]",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xe00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = {0x400, 0x400, 0x400, 0x400 },
.gpiomute = 0xc00,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
},
[BTTV_BOARD_VOBIS_BOOSTAR] = {
.name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x1f0fff,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20000, 0x30000, 0x10000, 0 },
.gpiomute = 0x40000,
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= terratv_audio,
},
[BTTV_BOARD_HAUPPAUG_WCAM] = {
.name = "Hauppauge WinCam newer (bt878)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 7,
- .muxsel = { 2, 0, 1, 1 },
+ .muxsel = MUXSEL(2, 0, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MAXI] = {
.name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
.video_inputs = 4,
- .audio_inputs = 2,
- .tuner = 0,
+ /* .audio_inputs= 2, */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_SECAM,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x1c ---------------------------------- */
[BTTV_BOARD_TERRATV] = {
.name = "Terratec TerraTV+ Version 1.1 (bt878)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x1f0fff,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 },
.gpiomute = 0x40000,
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= terratv_audio,
/* GPIO wiring:
External 20 pin connector (for Active Radio Upgrade board)
@@ -805,87 +778,77 @@ struct tvcard bttv_tvcards[] = {
/* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
.name = "Imagenation PXC200",
.video_inputs = 5,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1, /* was: 4 */
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0},
+ .muxsel = MUXSEL(2, 3, 1, 0, 0),
.gpiomux = { 0 },
.needs_tvaudio = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.muxsel_hook = PXC200_muxsel,
},
[BTTV_BOARD_FLYVIDEO_98] = {
.name = "Lifeview FlyVideo 98 LR50",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x1800, /* 0x8dfe00 */
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x0800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_IPROTV] = {
.name = "Formac iProTV, Formac ProTV I (bt848)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 1,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 0, 0, 0 },
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x20 ---------------------------------- */
[BTTV_BOARD_INTEL_C_S_PCI] = {
.name = "Intel Create and Share PCI/ Smart Video Recorder III",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TERRATVALUE] = {
.name = "Terratec TerraTValue Version Bt878",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xffff00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x500, 0, 0x300, 0x900 },
.gpiomute = 0x900,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_WINFAST2000] = {
.name = "Leadtek WinFast 2000/ WinFast 2000 XP",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 1, 0 }, /* TV, CVid, SVid, CVid over SVid connector */
+ /* TV, CVid, SVid, CVid over SVid connector */
+ .muxsel = MUXSEL(2, 3, 1, 1, 0),
/* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
.gpiomask = 0xb33000,
.gpiomux = { 0x122000,0x1000,0x0000,0x620000 },
@@ -906,217 +869,191 @@ struct tvcard bttv_tvcards[] = {
.has_radio = 1,
.tuner_type = TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= winfast2000_audio,
.has_remote = 1,
},
[BTTV_BOARD_CHRONOS_VS2] = {
.name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x24 ---------------------------------- */
[BTTV_BOARD_TYPHOON_TVIEW] = {
.name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
},
[BTTV_BOARD_PXELVWPLTVPRO] = {
.name = "Prolink PixelView PlayTV pro",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xff,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x21, 0x20, 0x24, 0x2c },
.gpiomute = 0x29,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MAGICTVIEW063] = {
.name = "Askey CPH06X TView99",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x551e00,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0x551400, 0x551200, 0, 0 },
.gpiomute = 0x551c00,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
},
[BTTV_BOARD_PINNACLE] = {
.name = "Pinnacle PCTV Studio/Rave",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x03000F,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0xd0001, 0, 0 },
.gpiomute = 1,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x28 ---------------------------------- */
[BTTV_BOARD_STB2] = {
.name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 4, 0, 2, 3 },
.gpiomute = 1,
.no_msp34xx = 1,
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
[BTTV_BOARD_AVPHONE98] = {
.name = "AVerMedia TVPhone 98",
.video_inputs = 3,
- .audio_inputs = 4,
- .tuner = 0,
+ /* .audio_inputs= 4, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 13, 4, 11, 7 },
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
.audio_mode_gpio= avermedia_tvphone_audio,
},
[BTTV_BOARD_PV951] = {
.name = "ProVideo PV951", /* pic16c54 */
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 1},
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 0, 0},
.needs_tvaudio = 1,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ONAIR_TV] = {
.name = "Little OnAir TV",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xe00b,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 },
.gpiomute = 0xff3ffc,
.no_msp34xx = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x2c ---------------------------------- */
[BTTV_BOARD_SIGMA_TVII_FM] = {
.name = "Sigma TVII-FM",
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 3,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 1, 0, 2 },
.gpiomute = 3,
.no_msp34xx = 1,
.pll = PLL_NONE,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MATRIX_VISION2] = {
.name = "MATRIX-Vision MV-Delta 2",
.video_inputs = 5,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0, 0),
.gpiomux = { 0 },
.no_msp34xx = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ZOLTRIX_GENIE] = {
.name = "Zoltrix Genie TV/FM",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xbcf03f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0 },
.gpiomute = 0xbcb03f,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4039FR5_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TERRATVRADIO] = {
.name = "Terratec TV/Radio+",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x70000,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20000, 0x30000, 0x10000, 0 },
.gpiomute = 0x40000,
.needs_tvaudio = 1,
@@ -1124,7 +1061,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_35,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
},
@@ -1132,51 +1068,46 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_DYNALINK] = {
.name = "Askey CPH03x/ Dynalink Magic TView",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = {2,0,0,0 },
.gpiomute = 1,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_GVBCTV3PCI] = {
.name = "IODATA GV-BCTV3/PCI",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x010f00,
- .muxsel = {2, 3, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 0, 0),
.gpiomux = {0x10000, 0, 0x10000, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_ALPS_TSHC6_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= gvbctv3pci_audio,
},
[BTTV_BOARD_PXELVWPLTVPAK] = {
.name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
.video_inputs = 5,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
+ .has_dig_in = 1,
.gpiomask = 0xAA0000,
- .muxsel = { 2,3,1,1,-1 },
- .digital_mode = DIGITAL_MODE_CAMERA,
+ .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */
+ /* .digital_mode= DIGITAL_MODE_CAMERA, */
.gpiomux = { 0x20000, 0, 0x80000, 0x80000 },
.gpiomute = 0xa8000,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
/* GPIO wiring: (different from Rev.4C !)
GPIO17: U4.A0 (first hef4052bt)
@@ -1191,17 +1122,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_EAGLE] = {
.name = "Eagle Wireless Capricorn2 (bt878A)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 0, 1, 1 },
+ .muxsel = MUXSEL(2, 0, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.pll = PLL_28,
.tuner_type = UNSET /* TUNER_ALPS_TMDH2_NTSC */,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x34 ---------------------------------- */
@@ -1209,11 +1138,10 @@ struct tvcard bttv_tvcards[] = {
/* David Härdeman <david@2gen.com> */
.name = "Pinnacle PCTV Studio Pro",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 0x03000F,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 0xd0001, 0, 0 },
.gpiomute = 10,
/* sound path (5 sources):
@@ -1229,25 +1157,22 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TVIEW_RDS_FM] = {
/* Claas Langbehn <claas@bigfoot.com>,
Sven Grothklags <sven@upb.de> */
.name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x1c,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 0x10, 8 },
.gpiomute = 4,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
},
[BTTV_BOARD_LIFETEC_9415] = {
@@ -1258,11 +1183,10 @@ struct tvcard bttv_tvcards[] = {
options tuner type=5 */
.name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x18e0,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x0000,0x0800,0x1000,0x1000 },
.gpiomute = 0x18e0,
/* For cards with tda9820/tda9821:
@@ -1272,25 +1196,22 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_BESTBUY_EASYTV] = {
/* Miguel Angel Alvarez <maacruz@navegalia.com>
old Easy TV BT848 version (model CPH031) */
.name = "Askey CPH031/ BESTBUY Easy TV",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xF,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x38 ---------------------------------- */
@@ -1298,17 +1219,15 @@ struct tvcard bttv_tvcards[] = {
/* Gordon Heydon <gjheydon@bigfoot.com ('98) */
.name = "Lifeview FlyVideo 98FM LR50",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* This is the ultimate cheapo capture card
* just a BT848A on a small PCB!
@@ -1316,51 +1235,45 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_GRANDTEC] = {
.name = "GrandTec 'Grand Video Capture' (Bt848)",
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
.gpiomask = 0,
- .muxsel = { 3, 1 },
+ .muxsel = MUXSEL(3, 1),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_35,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ASKEY_CPH060] = {
/* Daniel Herrington <daniel.herrington@home.com> */
.name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xe00,
- .muxsel = { 2, 3, 1, 1},
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x400, 0x400, 0x400, 0x400 },
.gpiomute = 0x800,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4036FY5_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ASKEY_CPH03X] = {
/* Matti Mottus <mottus@physic.ut.ee> */
.name = "Askey CPH03x TV Capturer",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x03000F,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x3c ---------------------------------- */
@@ -1368,34 +1281,30 @@ struct tvcard bttv_tvcards[] = {
/* Philip Blundell <philb@gnu.org> */
.name = "Modular Technology MM100PCTV",
.video_inputs = 2,
- .audio_inputs = 2,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 2, */
+ .svhs = NO_SVHS,
.gpiomask = 11,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 1 },
.gpiomute = 8,
.pll = PLL_35,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_GMV1] = {
/* Adrian Cox <adrian@humboldt.co.uk */
.name = "AG Electronics GMV1",
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
.gpiomask = 0xF,
- .muxsel = { 2, 2 },
+ .muxsel = MUXSEL(2, 2),
.gpiomux = { },
.no_msp34xx = 1,
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_BESTBUY_EASYTV2] = {
/* Miguel Angel Alvarez <maacruz@navegalia.com>
@@ -1403,34 +1312,30 @@ struct tvcard bttv_tvcards[] = {
special thanks to Informatica Mieres for providing the card */
.name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
.video_inputs = 3,
- .audio_inputs = 2,
- .tuner = 0,
+ /* .audio_inputs= 2, */
.svhs = 2,
.gpiomask = 0xFF,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 1, 0, 4, 4 },
.gpiomute = 9,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ATI_TVWONDER] = {
/* Lukas Gebauer <geby@volny.cz> */
.name = "ATI TV-Wonder",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xf03f,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0xbffe, 0, 0xbfff, 0 },
.gpiomute = 0xbffe,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x40 ---------------------------------- */
@@ -1438,27 +1343,24 @@ struct tvcard bttv_tvcards[] = {
/* Lukas Gebauer <geby@volny.cz> */
.name = "ATI TV-Wonder VE",
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 1,
- .muxsel = { 2, 3, 0, 1 },
+ .muxsel = MUXSEL(2, 3, 0, 1),
.gpiomux = { 0, 0, 1, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_FLYVIDEO2000] = {
/* DeeJay <deejay@westel900.net (2000S) */
.name = "Lifeview FlyVideo 2000S LR90",
.video_inputs = 3,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x18e0,
- .muxsel = { 2, 3, 0, 1 },
+ .muxsel = MUXSEL(2, 3, 0, 1),
/* Radio changed from 1e80 to 0x800 to make
FlyVideo2000S in .hu happy (gm)*/
/* -dk-???: set mute=0x1800 for tda9874h daughterboard */
@@ -1471,40 +1373,35 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TERRATVALUER] = {
.name = "Terratec TValueRadio",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xffff00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x500, 0x500, 0x300, 0x900 },
.gpiomute = 0x900,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
},
[BTTV_BOARD_GVBCTV4PCI] = {
/* TANAKA Kei <peg00625@nifty.com> */
.name = "IODATA GV-BCTV4/PCI",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x010f00,
- .muxsel = {2, 3, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 0, 0),
.gpiomux = {0x10000, 0, 0x10000, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= gvbctv3pci_audio,
},
@@ -1514,9 +1411,8 @@ struct tvcard bttv_tvcards[] = {
/* try "insmod msp3400 simple=0" if you have
* sound problems with this card. */
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 0x4f8a00,
/* 0x100000: 1=MSP enabled (0=disable again)
* 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
@@ -1524,10 +1420,9 @@ struct tvcard bttv_tvcards[] = {
.gpiomute = 0x947fff,
/* tvtuner, radio, external,internal, mute, stereo
* tuner, Composit, SVid, Composit-on-Svid-adapter */
- .muxsel = { 2, 3 ,0 ,1 },
+ .muxsel = MUXSEL(2, 3, 0, 1),
.tuner_type = TUNER_MT2032,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
@@ -1536,9 +1431,8 @@ struct tvcard bttv_tvcards[] = {
/* try "insmod msp3400 simple=0" if you have
* sound problems with this card. */
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 0x4f8a00,
/* 0x100000: 1=MSP enabled (0=disable again)
* 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
@@ -1546,10 +1440,9 @@ struct tvcard bttv_tvcards[] = {
.gpiomute = 0x947fff,
/* tvtuner, radio, external,internal, mute, stereo
* tuner, Composit, SVid, Composit-on-Svid-adapter */
- .muxsel = { 2, 3 ,0 ,1 },
+ .muxsel = MUXSEL(2, 3, 0, 1),
.tuner_type = TUNER_MT2032,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
@@ -1557,31 +1450,27 @@ struct tvcard bttv_tvcards[] = {
/* Philip Blundell <pb@nexus.co.uk> */
.name = "Active Imaging AIMMS",
.video_inputs = 1,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
- .muxsel = { 2 },
+ .muxsel = MUXSEL(2),
.gpiomask = 0
},
[BTTV_BOARD_PV_BT878P_PLUS] = {
/* Tomasz Pyra <hellfire@sedez.iq.pl> */
.name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
.video_inputs = 3,
- .audio_inputs = 4,
- .tuner = 0,
+ /* .audio_inputs= 4, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */
.gpiomute = 13,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_LG_PAL_I_FM,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
/* GPIO wiring:
GPIO0: U4.A0 (hef4052bt)
@@ -1594,15 +1483,14 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_FLYVIDEO98EZ] = {
.name = "Lifeview FlyVideo 98EZ (capture only) LR51",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 1 }, /* AV1, AV2, SVHS, CVid adapter on SVHS */
+ /* AV1, AV2, SVHS, CVid adapter on SVHS */
+ .muxsel = MUXSEL(2, 3, 1, 1),
.pll = PLL_28,
.no_msp34xx = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x48 ---------------------------------- */
@@ -1610,11 +1498,10 @@ struct tvcard bttv_tvcards[] = {
/* Dariusz Kowalewski <darekk@automex.pl> */
.name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x01, 0x00, 0x03, 0x03 },
.gpiomute = 0x09,
.needs_tvaudio = 1,
@@ -1623,7 +1510,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= pvbt878p9b_audio, /* Note: not all cards have stereo */
.has_radio = 1, /* Note: not all cards have radio */
.has_remote = 1,
@@ -1640,49 +1526,42 @@ struct tvcard bttv_tvcards[] = {
/* you must jumper JP5 for the card to work */
.name = "Sensoray 311",
.video_inputs = 5,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 4,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0, 0),
.gpiomux = { 0 },
.needs_tvaudio = 0,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_RV605] = {
/* Miguel Freitas <miguel@cetuc.puc-rio.br> */
.name = "RemoteVision MX (RV605)",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0x00,
.gpiomask2 = 0x07ff,
- .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
- 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
+ .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
.no_msp34xx = 1,
.no_tda9875 = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.muxsel_hook = rv605_muxsel,
},
[BTTV_BOARD_POWERCLR_MTV878] = {
.name = "Powercolor MTV878/ MTV878R/ MTV878F",
.video_inputs = 3,
- .audio_inputs = 2,
- .tuner = 0,
+ /* .audio_inputs= 2, */
.svhs = 2,
.gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
- .muxsel = { 2, 1, 1, },
+ .muxsel = MUXSEL(2, 1, 1),
.gpiomux = { 0, 1, 2, 2 },
.gpiomute = 4,
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
@@ -1692,42 +1571,38 @@ struct tvcard bttv_tvcards[] = {
/* Masaki Suzuki <masaki@btree.org> */
.name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x140007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= windvr_audio,
},
[BTTV_BOARD_GRANDTEC_MULTI] = {
.name = "GrandTec Multi Capture Card (Bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_KWORLD] = {
.name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */
+ /* Tuner, SVid, SVHS, SVid to SVHS connector */
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 4, 4 },/* Yes, this tuner uses the same audio output for TV and FM radio!
* This card lacks external Audio In, so we mute it on Ext. & Int.
* The PCB can take a sbx1637/sbx1673, wiring unknown.
@@ -1741,7 +1616,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
/* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
radio signal strength indicators work fine. */
.has_radio = 1,
@@ -1759,27 +1633,24 @@ struct tvcard bttv_tvcards[] = {
/* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
.name = "DSP Design TCVIDEO",
.video_inputs = 4,
- .svhs = UNSET,
- .muxsel = { 2, 3, 1, 0 },
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 3, 1, 0),
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x50 ---------------------------------- */
[BTTV_BOARD_HAUPPAUGEPVR] = {
.name = "Hauppauge WinTV PVR",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 0, 1, 1 },
+ .muxsel = MUXSEL(2, 0, 1, 1),
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.gpiomask = 7,
.gpiomux = {7},
@@ -1787,32 +1658,28 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_GVBCTV5PCI] = {
.name = "IODATA GV-BCTV5/PCI",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x0f0f80,
- .muxsel = {2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = {0x030000, 0x010000, 0, 0 },
.gpiomute = 0x020000,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC_M,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= gvbctv5pci_audio,
.has_radio = 1,
},
[BTTV_BOARD_OSPREY1x0] = {
.name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
.video_inputs = 4, /* id-inputs-clock */
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 3,
- .muxsel = { 3, 2, 0, 1 },
+ .muxsel = MUXSEL(3, 2, 0, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1820,14 +1687,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY1x0_848] = {
.name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
.video_inputs = 3,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1837,14 +1702,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY101_848] = {
.name = "Osprey 101 (848)", /* 0x05-40C0-C1 */
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .muxsel = { 3, 1 },
+ .muxsel = MUXSEL(3, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1852,14 +1715,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY1x1] = {
.name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
.video_inputs = 1,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 0 },
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(0),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1867,14 +1728,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY1x1_SVID] = {
.name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .muxsel = { 0, 1 },
+ .muxsel = MUXSEL(0, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1882,14 +1741,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY2xx] = {
.name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
.video_inputs = 1,
- .audio_inputs = 1,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 0 },
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(0),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1899,14 +1756,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY2x0_SVID] = {
.name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1,
- .muxsel = { 0, 1 },
+ .muxsel = MUXSEL(0, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1914,14 +1769,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY2x0] = {
.name = "Osprey 210/220/230", /* 0x1(A|B)-04C0-C1 */
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1,
- .muxsel = { 2, 3 },
+ .muxsel = MUXSEL(2, 3),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1929,14 +1782,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY500] = {
.name = "Osprey 500", /* 500 */
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1,
- .muxsel = { 2, 3 },
+ .muxsel = MUXSEL(2, 3),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1944,12 +1795,10 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY540] = {
.name = "Osprey 540", /* 540 */
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1959,14 +1808,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY2000] = {
.name = "Osprey 2000", /* 2000 */
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1,
- .muxsel = { 2, 3 },
+ .muxsel = MUXSEL(2, 3),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
@@ -1975,14 +1822,12 @@ struct tvcard bttv_tvcards[] = {
/* M G Berberich <berberic@forwiss.uni-passau.de> */
.name = "IDS Eagle",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
.gpiomask = 0,
- .muxsel = { 0, 1, 2, 3 },
+ .muxsel = MUXSEL(2, 2, 2, 2),
.muxsel_hook = eagle_muxsel,
.no_msp34xx = 1,
.no_tda9875 = 1,
@@ -1991,16 +1836,14 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_PINNACLESAT] = {
.name = "Pinnacle PCTV Sat",
.video_inputs = 2,
- .audio_inputs = 0,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .muxsel = { 3, 1 },
+ .muxsel = MUXSEL(3, 1),
.pll = PLL_28,
.no_gpioirq = 1,
.has_dvb = 1,
@@ -2008,18 +1851,16 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_FORMAC_PROTV] = {
.name = "Formac ProTV II (bt878)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 2,
/* TV, Comp1, Composite over SVID con, SVID */
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 2, 0, 0 },
.pll = PLL_28,
.has_radio = 1,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
/* sound routing:
GPIO=0x00,0x01,0x03: mute (?)
0x02: both TV and radio (tuner: FM1216/I)
@@ -2033,62 +1874,55 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_MACHTV] = {
.name = "MachTV",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1},
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3},
.gpiomute = 4,
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
},
[BTTV_BOARD_EURESYS_PICOLO] = {
.name = "Euresys Picolo",
.video_inputs = 3,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
.gpiomask = 0,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .muxsel = { 2, 0, 1},
+ .muxsel = MUXSEL(2, 0, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_PV150] = {
/* Luc Van Hoeylandt <luc@e-magic.be> */
.name = "ProVideo PV150", /* 0x4f */
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0,
- .muxsel = { 2, 3 },
+ .muxsel = MUXSEL(2, 3),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_AD_TVK503] = {
/* Hiroshi Takekawa <sian@big.or.jp> */
/* This card lacks subsystem ID */
.name = "AD-TVK503", /* 0x63 */
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x001e8007,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
/* Tuner, Radio, external, internal, off, on */
.gpiomux = { 0x08, 0x0f, 0x0a, 0x08 },
.gpiomute = 0x0f,
@@ -2097,7 +1931,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= adtvk503_audio,
},
@@ -2105,17 +1938,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_HERCULES_SM_TV] = {
.name = "Hercules Smart TV Stereo",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.needs_tvaudio = 1,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
/* Notes:
- card lacks subsystem ID
- stereo variant w/ daughter board with tda9874a @0xb0
@@ -2129,16 +1960,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_PACETV] = {
.name = "Pace TV & Radio Card",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 1 }, /* Tuner, CVid, SVid, CVid over SVid connector */
+ /* Tuner, CVid, SVid, CVid over SVid connector */
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomask = 0,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
.pll = PLL_28,
/* Bt878, Bt832, FI1246 tuner; no pci subsystem id
@@ -2152,27 +1982,34 @@ struct tvcard bttv_tvcards[] = {
/* Chris Willing <chris@vislab.usyd.edu.au> */
.name = "IVC-200",
.video_inputs = 1,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
+ .gpiomask = 0xdf,
+ .muxsel = MUXSEL(2),
+ .pll = PLL_28,
+ },
+ [BTTV_BOARD_IVCE8784] = {
+ .name = "IVCE-8784",
+ .video_inputs = 1,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ .svhs = NO_SVHS,
.gpiomask = 0xdf,
- .muxsel = { 2 },
+ .muxsel = MUXSEL(2),
.pll = PLL_28,
},
[BTTV_BOARD_XGUARD] = {
.name = "Grand X-Guard / Trust 814PCI",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.gpiomask2 = 0xff,
- .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
+ .muxsel = MUXSEL(2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0),
.muxsel_hook = xguard_muxsel,
.no_msp34xx = 1,
.no_tda9875 = 1,
@@ -2184,16 +2021,14 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_NEBULA_DIGITV] = {
.name = "Nebula Electronics DigiTV",
.video_inputs = 1,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 2, 3, 1, 0 },
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 3, 1, 0),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_dvb = 1,
.has_remote = 1,
.gpiomask = 0x1b,
@@ -2203,118 +2038,101 @@ struct tvcard bttv_tvcards[] = {
/* Jorge Boncompte - DTI2 <jorge@dti2.net> */
.name = "ProVideo PV143",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD009X1_VD011_MINIDIN] = {
/* M.Klahr@phytec.de */
.name = "PHYTEC VD-009-X1 VD-011 MiniDIN (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 3,
.gpiomask = 0x00,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD009X1_VD011_COMBI] = {
.name = "PHYTEC VD-009-X1 VD-011 Combi (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 3,
.gpiomask = 0x00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x6c ---------------------------------- */
[BTTV_BOARD_VD009_MINIDIN] = {
.name = "PHYTEC VD-009 MiniDIN (bt878)",
.video_inputs = 10,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 9,
.gpiomask = 0x00,
- .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
- via the upper nibble of muxsel. here: used for
- xternal video-mux */
- .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
+ .gpiomask2 = 0x03, /* used for external vodeo mux */
+ .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0),
+ .muxsel_hook = phytec_muxsel,
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD009_COMBI] = {
.name = "PHYTEC VD-009 Combi (bt878)",
.video_inputs = 10,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 9,
.gpiomask = 0x00,
- .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
- via the upper nibble of muxsel. here: used for
- xternal video-mux */
- .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
+ .gpiomask2 = 0x03, /* used for external vodeo mux */
+ .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1),
+ .muxsel_hook = phytec_muxsel,
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_IVC100] = {
.name = "IVC-100",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
.gpiomask = 0xdf,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.pll = PLL_28,
},
[BTTV_BOARD_IVC120] = {
/* IVC-120G - Alan Garfield <alan@fromorbit.com> */
.name = "IVC-120G",
.video_inputs = 16,
- .audio_inputs = 0, /* card has no audio */
- .tuner = UNSET, /* card has no tuner */
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET, /* card has no svhs */
+ .svhs = NO_SVHS, /* card has no svhs */
.needs_tvaudio = 0,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.gpiomask = 0x00,
- .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
+ .muxsel = MUXSEL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
.muxsel_hook = ivc120_muxsel,
.pll = PLL_28,
},
@@ -2323,13 +2141,11 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_PC_HDTV] = {
.name = "pcHDTV HD-2000 TV",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = TUNER_PHILIPS_FCV1236D,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_dvb = 1,
},
[BTTV_BOARD_TWINHAN_DST] = {
@@ -2339,38 +2155,34 @@ struct tvcard bttv_tvcards[] = {
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_video = 1,
.has_dvb = 1,
},
[BTTV_BOARD_WINFASTVC100] = {
.name = "Winfast VC100",
.video_inputs = 3,
- .audio_inputs = 0,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .tuner = UNSET,
- .muxsel = { 3, 1, 1, 3 }, /* Vid In, SVid In, Vid over SVid in connector */
+ /* Vid In, SVid In, Vid over SVid in connector */
+ .muxsel = MUXSEL(3, 1, 1, 3),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
},
[BTTV_BOARD_TEV560] = {
.name = "Teppro TEV-560/InterVision IV-560",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 3,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 1, 1, 1 },
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_35,
},
@@ -2378,14 +2190,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_SIMUS_GVC1100] = {
.name = "SIMUS GVC1100",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
- .muxsel = { 2, 2, 2, 2 },
+ .muxsel = MUXSEL(2, 2, 2, 2),
.gpiomask = 0x3F,
.muxsel_hook = gvc1100_muxsel,
},
@@ -2393,47 +2203,41 @@ struct tvcard bttv_tvcards[] = {
/* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
.name = "NGS NGSTV+",
.video_inputs = 3,
- .tuner = 0,
.svhs = 2,
.gpiomask = 0x008007,
- .muxsel = { 2, 3, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 0, 0),
.gpiomux = { 0, 0, 0, 0 },
.gpiomute = 0x000003,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
},
[BTTV_BOARD_LMLBT4] = {
/* http://linuxmedialabs.com */
.name = "LMLBT4",
.video_inputs = 4, /* IN1,IN2,IN3,IN4 */
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 2, 3, 1, 0 },
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 3, 1, 0),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.needs_tvaudio = 0,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TEKRAM_M205] = {
/* Helmroos Harri <harri.helmroos@pp.inet.fi> */
.name = "Tekram M205 PRO",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.svhs = 2,
.needs_tvaudio = 0,
.gpiomask = 0x68,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.gpiomux = { 0x68, 0x68, 0x61, 0x61 },
.pll = PLL_28,
},
@@ -2444,18 +2248,16 @@ struct tvcard bttv_tvcards[] = {
/* bt878 TV + FM without subsystem ID */
.name = "Conceptronic CONTVFMi",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x008007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 2 },
.gpiomute = 3,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
.has_radio = 1,
},
@@ -2466,37 +2268,34 @@ struct tvcard bttv_tvcards[] = {
/*0x79 in bttv.h*/
.name = "Euresys Picolo Tetra",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0,
.gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/
+ /*878A input is always MUX0, see above.*/
+ .muxsel = MUXSEL(2, 2, 2, 2),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.pll = PLL_28,
.needs_tvaudio = 0,
.muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_SPIRIT_TV] = {
/* Spirit TV Tuner from http://spiritmodems.com.au */
/* Stafford Goodsell <surge@goliath.homeunix.org> */
.name = "Spirit TV Tuner",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x0000000f,
- .muxsel = { 2, 1, 1 },
+ .muxsel = MUXSEL(2, 1, 1),
.gpiomux = { 0x02, 0x00, 0x00, 0x00 },
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
},
@@ -2505,11 +2304,9 @@ struct tvcard bttv_tvcards[] = {
.name = "AVerMedia AVerTV DVB-T 771",
.video_inputs = 2,
.svhs = 1,
- .tuner = UNSET,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .muxsel = { 3 , 3 },
+ .muxsel = MUXSEL(3, 3),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -2524,54 +2321,47 @@ struct tvcard bttv_tvcards[] = {
/* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */
.name = "AverMedia AverTV DVB-T 761",
.video_inputs = 2,
- .tuner = UNSET,
.svhs = 1,
- .muxsel = { 3, 1, 2, 0 }, /* Comp0, S-Video, ?, ? */
+ .muxsel = MUXSEL(3, 1, 2, 0), /* Comp0, S-Video, ?, ? */
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_dvb = 1,
.no_gpioirq = 1,
.has_remote = 1,
},
[BTTV_BOARD_MATRIX_VISIONSQ] = {
/* andre.schwarz@matrix-vision.de */
- .name = "MATRIX Vision Sigma-SQ",
- .video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .gpiomask = 0x0,
- .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3 },
- .muxsel_hook = sigmaSQ_muxsel,
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
+ .name = "MATRIX Vision Sigma-SQ",
+ .video_inputs = 16,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .gpiomask = 0x0,
+ .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3),
+ .muxsel_hook = sigmaSQ_muxsel,
+ .gpiomux = { 0 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
},
[BTTV_BOARD_MATRIX_VISIONSLC] = {
/* andre.schwarz@matrix-vision.de */
- .name = "MATRIX Vision Sigma-SLC",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .gpiomask = 0x0,
- .muxsel = { 2, 2, 2, 2 },
- .muxsel_hook = sigmaSLC_muxsel,
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
+ .name = "MATRIX Vision Sigma-SLC",
+ .video_inputs = 4,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .gpiomask = 0x0,
+ .muxsel = MUXSEL(2, 2, 2, 2),
+ .muxsel_hook = sigmaSLC_muxsel,
+ .gpiomux = { 0 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
},
/* BTTV_BOARD_APAC_VIEWCOMP */
[BTTV_BOARD_APAC_VIEWCOMP] = {
@@ -2579,18 +2369,16 @@ struct tvcard bttv_tvcards[] = {
/* bt878 TV + FM 0x00000000 subsystem ID */
.name = "APAC Viewcomp 878(AMAX)",
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 0xFF,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
.has_radio = 1, /* not every card has radio */
},
@@ -2599,46 +2387,40 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_DVICO_DVBT_LITE] = {
/* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
.name = "DViCO FusionHDTV DVB-T Lite",
- .tuner = UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
.no_video = 1,
.has_dvb = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VGEAR_MYVCD] = {
/* Steven <photon38@pchome.com.tw> */
.name = "V-Gear MyVCD",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3f,
- .muxsel = {2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = {0x31, 0x31, 0x31, 0x31 },
.gpiomute = 0x31,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC_M,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 0,
},
[BTTV_BOARD_SUPER_TV] = {
/* Rick C <cryptdragoon@gmail.com> */
.name = "Super TV Tuner",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.gpiomask = 0x008007,
.gpiomux = { 0, 0x000001,0,0 },
.needs_tvaudio = 1,
@@ -2648,17 +2430,15 @@ struct tvcard bttv_tvcards[] = {
/* Chris Fanning <video4linux@haydon.net> */
.name = "Tibet Systems 'Progress DVR' CS16",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.muxsel_hook = tibetCS16_muxsel,
},
[BTTV_BOARD_KODICOM_4400R] = {
@@ -2675,12 +2455,10 @@ struct tvcard bttv_tvcards[] = {
*/
.name = "Kodicom 4400R (master)",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
/* GPIO bits 0-9 used for analog switch:
* 00 - 03: camera selector
* 04 - 06: channel (controller) selector
@@ -2691,7 +2469,7 @@ struct tvcard bttv_tvcards[] = {
*/
.gpiomask = 0x0003ff,
.no_gpioirq = 1,
- .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
+ .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda7432 = 1,
@@ -2707,15 +2485,13 @@ struct tvcard bttv_tvcards[] = {
*/
.name = "Kodicom 4400R (slave)",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
.gpiomask = 0x010000,
.no_gpioirq = 1,
- .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
+ .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda7432 = 1,
@@ -2728,27 +2504,23 @@ struct tvcard bttv_tvcards[] = {
/* Adlink RTV24 with special unlock codes */
.name = "Adlink RTV24",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
},
/* ---- card 0x87---------------------------------- */
[BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = {
/* Michael Krufky <mkrufky@m1k.net> */
.name = "DViCO FusionHDTV 5 Lite",
- .tuner = 0,
.tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.video_inputs = 3,
- .audio_inputs = 1,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.gpiomask = 0x00e00007,
.gpiomux = { 0x00400005, 0, 0x00000001, 0 },
.gpiomute = 0x00c00007,
@@ -2762,75 +2534,68 @@ struct tvcard bttv_tvcards[] = {
/* Mauro Carvalho Chehab <mchehab@infradead.org> */
.name = "Acorp Y878F",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x01fe00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x001e00, 0, 0x018000, 0x014000 },
.gpiomute = 0x002000,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
.tuner_addr = 0xc1 >>1,
- .radio_addr = 0xc1 >>1,
.has_radio = 1,
},
/* ---- card 0x89 ---------------------------------- */
[BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = {
.name = "Conceptronic CTVFMi v2",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x001c0007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 2 },
.gpiomute = 3,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_TENA_9533_DI,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
.has_radio = 1,
},
/* ---- card 0x8a ---------------------------------- */
[BTTV_BOARD_PV_BT878P_2E] = {
- .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
- .video_inputs = 5,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 3,
- .gpiomask = 0x01fe00,
- .muxsel = { 2,3,1,1,-1 },
- .digital_mode = DIGITAL_MODE_CAMERA,
- .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 },
- .gpiomute = 0x12400,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_LG_PAL_FM,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .has_remote = 1,
+ .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
+ .video_inputs = 5,
+ /* .audio_inputs= 1, */
+ .svhs = 3,
+ .has_dig_in = 1,
+ .gpiomask = 0x01fe00,
+ .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */
+ /* .digital_mode= DIGITAL_MODE_CAMERA, */
+ .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 },
+ .gpiomute = 0x12400,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_LG_PAL_FM,
+ .tuner_addr = ADDR_UNSET,
+ .has_remote = 1,
},
/* ---- card 0x8b ---------------------------------- */
[BTTV_BOARD_PV_M4900] = {
/* Sérgio Fortier <sergiofortier@yahoo.com.br> */
.name = "Prolink PixelView PlayTV MPEG2 PV-M4900",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x21, 0x20, 0x24, 0x2c },
.gpiomute = 0x29,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_YMEC_TVF_5533MF,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
.has_remote = 1,
},
@@ -2850,17 +2615,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY440] = {
.name = "Osprey 440",
.video_inputs = 4,
- .audio_inputs = 2, /* this is meaningless */
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 2, 3, 0, 1 }, /* 3,0,1 are guesses */
+ /* .audio_inputs= 2, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 3, 0, 1), /* 3,0,1 are guesses */
.gpiomask = 0x303,
.gpiomute = 0x000, /* int + 32kHz */
.gpiomux = { 0, 0, 0x000, 0x100},
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -2869,28 +2632,25 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_ASOUND_SKYEYE] = {
.name = "Asound Skyeye PCTV",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 1,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x8e ---------------------------------- */
[BTTV_BOARD_SABRENT_TVFM] = {
.name = "Sabrent TV-FM (bttv version)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x108007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 100000, 100002, 100002, 100000 },
.no_msp34xx = 1,
.no_tda9875 = 1,
@@ -2904,17 +2664,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = {
.name = "Hauppauge ImpactVCB (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0x0f, /* old: 7 */
- .muxsel = { 0, 1, 3, 2 }, /* Composite 0-3 */
+ .muxsel = MUXSEL(0, 1, 3, 2), /* Composite 0-3 */
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MACHTV_MAGICTV] = {
/* Julian Calaby <julian.calaby@gmail.com>
@@ -2926,16 +2684,14 @@ struct tvcard bttv_tvcards[] = {
.name = "MagicTV", /* rebranded MachTV */
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.tuner_type = TUNER_TEMIC_4009FR5_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
.has_remote = 1,
@@ -2943,36 +2699,30 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_SSAI_SECURITY] = {
.name = "SSAI Security Video Interface",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 0, 1, 2, 3 },
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(0, 1, 2, 3),
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_SSAI_ULTRASOUND] = {
.name = "SSAI Ultrasound Video Interface",
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .muxsel = { 2, 0, 1, 3 },
- .tuner_type = UNSET,
+ .muxsel = MUXSEL(2, 0, 1, 3),
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x94---------------------------------- */
[BTTV_BOARD_DVICO_FUSIONHDTV_2] = {
.name = "DViCO FusionHDTV 2",
- .tuner = 0,
.tuner_type = TUNER_PHILIPS_FCV1236D,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.video_inputs = 3,
- .audio_inputs = 1,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.gpiomask = 0x00e00007,
.gpiomux = { 0x00400005, 0, 0x00000001, 0 },
.gpiomute = 0x00c00007,
@@ -2984,36 +2734,31 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_TYPHOON_TVTUNERPCI] = {
.name = "Typhoon TV-Tuner PCI (50684)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3014f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20001,0x10001, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_GEOVISION_GV600] = {
/* emhn@usb.ve */
- .name = "Geovision GV-600",
- .video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .gpiomask = 0x0,
- .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2 },
- .muxsel_hook = geovision_muxsel,
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
+ .name = "Geovision GV-600",
+ .video_inputs = 16,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .gpiomask = 0x0,
+ .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
+ .muxsel_hook = geovision_muxsel,
+ .gpiomux = { 0 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
},
[BTTV_BOARD_KOZUMI_KTV_01C] = {
/* Mauro Lacy <mauro@lacy.com.ar>
@@ -3021,17 +2766,15 @@ struct tvcard bttv_tvcards[] = {
.name = "Kozumi KTV-01C",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x008007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */
.gpiomute = 3, /* CONTVFMi */
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
.has_remote = 1,
@@ -3041,8 +2784,7 @@ struct tvcard bttv_tvcards[] = {
Mauro Carvalho Chehab <mchehab@infradead.org */
.name = "Encore ENL TV-FM-2",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
/* bit 6 -> IR disabled
bit 18/17 = 00 -> mute
@@ -3051,12 +2793,11 @@ struct tvcard bttv_tvcards[] = {
11 -> internal audio input
*/
.gpiomask = 0x060040,
- .muxsel = { 2, 3, 3 },
+ .muxsel = MUXSEL(2, 3, 3),
.gpiomux = { 0x60000, 0x60000, 0x20000, 0x20000 },
.gpiomute = 0,
.tuner_type = TUNER_TCL_MF02GIP_5N,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
.has_remote = 1,
@@ -3065,50 +2806,111 @@ struct tvcard bttv_tvcards[] = {
/* D.Heer@Phytec.de */
.name = "PHYTEC VD-012 (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
- .svhs = UNSET, /* card has no s-video */
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0x00,
- .muxsel = { 0, 2, 3, 1 },
+ .muxsel = MUXSEL(0, 2, 3, 1),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD012_X1] = {
/* D.Heer@Phytec.de */
.name = "PHYTEC VD-012-X1 (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 3,
.gpiomask = 0x00,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD012_X2] = {
/* D.Heer@Phytec.de */
.name = "PHYTEC VD-012-X2 (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 3,
.gpiomask = 0x00,
- .muxsel = { 3, 2, 1 },
+ .muxsel = MUXSEL(3, 2, 1),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- }
+ },
+ [BTTV_BOARD_GEOVISION_GV800S] = {
+ /* Bruno Christo <bchristo@inf.ufsm.br>
+ *
+ * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
+ * 1 audio input per BT878A = 4 audio inputs
+ * 4 video inputs per BT878A = 16 video inputs
+ * This is the first BT878A chip of the GV-800(S). It's the
+ * "master" chip and it controls the video inputs through an
+ * analog multiplexer (a CD22M3494) via some GPIO pins. The
+ * slaves should use card type 0x9e (following this one).
+ * There is a EEPROM on the card which is currently not handled.
+ * The audio input is not working yet.
+ */
+ .name = "Geovision GV-800(S) (master)",
+ .video_inputs = 4,
+ /* .audio_inputs= 1, */
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ .svhs = NO_SVHS,
+ .gpiomask = 0xf107f,
+ .no_gpioirq = 1,
+ .muxsel = MUXSEL(2, 2, 2, 2),
+ .pll = PLL_28,
+ .no_msp34xx = 1,
+ .no_tda7432 = 1,
+ .no_tda9875 = 1,
+ .muxsel_hook = gv800s_muxsel,
+ },
+ [BTTV_BOARD_GEOVISION_GV800S_SL] = {
+ /* Bruno Christo <bchristo@inf.ufsm.br>
+ *
+ * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
+ * 1 audio input per BT878A = 4 audio inputs
+ * 4 video inputs per BT878A = 16 video inputs
+ * The 3 other BT878A chips are "slave" chips of the GV-800(S)
+ * and should use this card type.
+ * The audio input is not working yet.
+ */
+ .name = "Geovision GV-800(S) (slave)",
+ .video_inputs = 4,
+ /* .audio_inputs= 1, */
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ .svhs = NO_SVHS,
+ .gpiomask = 0x00,
+ .no_gpioirq = 1,
+ .muxsel = MUXSEL(2, 2, 2, 2),
+ .pll = PLL_28,
+ .no_msp34xx = 1,
+ .no_tda7432 = 1,
+ .no_tda9875 = 1,
+ .muxsel_hook = gv800s_muxsel,
+ },
+ [BTTV_BOARD_PV183] = {
+ .name = "ProVideo PV183", /* 0x9f */
+ .video_inputs = 2,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .gpiomask = 0,
+ .muxsel = MUXSEL(2, 3),
+ .gpiomux = { 0 },
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ },
};
static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -3152,7 +2954,7 @@ void __devinit bttv_idcard(struct bttv *btv)
btv->c.nr, btv->cardid & 0xffff,
(btv->cardid >> 16) & 0xffff);
printk(KERN_DEBUG "please mail id, board name and "
- "the correct card= insmod option to video4linux-list@redhat.com\n");
+ "the correct card= insmod option to linux-media@vger.kernel.org\n");
}
}
@@ -3403,8 +3205,7 @@ static void init_ids_eagle(struct bttv *btv)
* has its own multiplexer */
static void eagle_muxsel(struct bttv *btv, unsigned int input)
{
- btaor((2)<<5, ~(3<<5), BT848_IFORM);
- gpio_bits(3,bttv_tvcards[btv->c.type].muxsel[input&7]);
+ gpio_bits(3, input & 3);
/* composite */
/* set chroma ADC to sleep */
@@ -3523,6 +3324,17 @@ void __devinit bttv_init_card1(struct bttv *btv)
/* initialization part two -- after registering i2c bus */
void __devinit bttv_init_card2(struct bttv *btv)
{
+ static const unsigned short tvaudio_addrs[] = {
+ I2C_ADDR_TDA8425 >> 1,
+ I2C_ADDR_TEA6300 >> 1,
+ I2C_ADDR_TEA6420 >> 1,
+ I2C_ADDR_TDA9840 >> 1,
+ I2C_ADDR_TDA985x_L >> 1,
+ I2C_ADDR_TDA985x_H >> 1,
+ I2C_ADDR_TDA9874 >> 1,
+ I2C_ADDR_PIC16C54 >> 1,
+ I2C_CLIENT_END
+ };
int addr=ADDR_UNSET;
btv->tuner_type = UNSET;
@@ -3629,6 +3441,9 @@ void __devinit bttv_init_card2(struct bttv *btv)
case BTTV_BOARD_KODICOM_4400R:
kodicom4400r_init(btv);
break;
+ case BTTV_BOARD_GEOVISION_GV800S:
+ gv800s_init(btv);
+ break;
}
/* pll configuration */
@@ -3670,13 +3485,12 @@ void __devinit bttv_init_card2(struct bttv *btv)
addr = bttv_tvcards[btv->c.type].tuner_addr;
if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
- if(UNSET == btv->tuner_type)
+ if (UNSET == btv->tuner_type)
btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
if (UNSET != tuner[btv->c.nr])
btv->tuner_type = tuner[btv->c.nr];
- if (btv->tuner_type == TUNER_ABSENT ||
- bttv_tvcards[btv->c.type].tuner == UNSET)
+ if (btv->tuner_type == TUNER_ABSENT)
printk(KERN_INFO "bttv%d: tuner absent\n", btv->c.nr);
else if(btv->tuner_type == UNSET)
printk(KERN_WARNING "bttv%d: tuner type unset\n", btv->c.nr);
@@ -3684,14 +3498,35 @@ void __devinit bttv_init_card2(struct bttv *btv)
printk(KERN_INFO "bttv%d: tuner type=%d\n", btv->c.nr,
btv->tuner_type);
- if (btv->tuner_type != UNSET) {
+ if (autoload != UNSET) {
+ printk(KERN_WARNING "bttv%d: the autoload option is obsolete.\n", btv->c.nr);
+ printk(KERN_WARNING "bttv%d: use option msp3400, tda7432 or tvaudio to\n", btv->c.nr);
+ printk(KERN_WARNING "bttv%d: override which audio module should be used.\n", btv->c.nr);
+ }
+
+ if (UNSET == btv->tuner_type)
+ btv->tuner_type = TUNER_ABSENT;
+
+ if (btv->tuner_type != TUNER_ABSENT) {
struct tuner_setup tun_setup;
+ /* Load tuner module before issuing tuner config call! */
+ if (bttv_tvcards[btv->c.type].has_radio)
+ v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+ v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
+
tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
tun_setup.type = btv->tuner_type;
tun_setup.addr = addr;
- bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
+ if (bttv_tvcards[btv->c.type].has_radio)
+ tun_setup.mode_mask |= T_RADIO;
+
+ bttv_call_all(btv, tuner, s_type_addr, &tun_setup);
}
if (btv->tda9887_conf) {
@@ -3700,10 +3535,13 @@ void __devinit bttv_init_card2(struct bttv *btv)
tda9887_cfg.tuner = TUNER_TDA9887;
tda9887_cfg.priv = &btv->tda9887_conf;
- bttv_call_i2c_clients(btv, TUNER_SET_CONFIG, &tda9887_cfg);
+ bttv_call_all(btv, tuner, s_config, &tda9887_cfg);
}
- btv->svhs = bttv_tvcards[btv->c.type].svhs;
+ btv->dig = bttv_tvcards[btv->c.type].has_dig_in ?
+ bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET;
+ btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ?
+ UNSET : bttv_tvcards[btv->c.type].svhs;
if (svhs[btv->c.nr] != UNSET)
btv->svhs = svhs[btv->c.nr];
if (remote[btv->c.nr] != UNSET)
@@ -3720,34 +3558,127 @@ void __devinit bttv_init_card2(struct bttv *btv)
if (bttv_tvcards[btv->c.type].audio_mode_gpio)
btv->audio_mode_gpio=bttv_tvcards[btv->c.type].audio_mode_gpio;
- if (!autoload)
- return;
-
- if (bttv_tvcards[btv->c.type].tuner == UNSET)
+ if (btv->tuner_type == TUNER_ABSENT)
return; /* no tuner or related drivers to load */
+ if (btv->has_saa6588 || saa6588[btv->c.nr]) {
+ /* Probe for RDS receiver chip */
+ static const unsigned short addrs[] = {
+ 0x20 >> 1,
+ 0x22 >> 1,
+ I2C_CLIENT_END
+ };
+ struct v4l2_subdev *sd;
+
+ sd = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "saa6588", "saa6588", addrs);
+ btv->has_saa6588 = (sd != NULL);
+ }
+
/* try to detect audio/fader chips */
- if (!bttv_tvcards[btv->c.type].no_msp34xx &&
- bttv_I2CRead(btv, I2C_ADDR_MSP3400, "MSP34xx") >=0)
- request_module("msp3400");
- if (bttv_tvcards[btv->c.type].msp34xx_alt &&
- bttv_I2CRead(btv, I2C_ADDR_MSP3400_ALT, "MSP34xx (alternate address)") >=0)
- request_module("msp3400");
+ /* First check if the user specified the audio chip via a module
+ option. */
+
+ switch (audiodev[btv->c.nr]) {
+ case -1:
+ return; /* do not load any audio module */
+
+ case 0: /* autodetect */
+ break;
+
+ case 1: {
+ /* The user specified that we should probe for msp3400 */
+ static const unsigned short addrs[] = {
+ I2C_ADDR_MSP3400 >> 1,
+ I2C_ADDR_MSP3400_ALT >> 1,
+ I2C_CLIENT_END
+ };
+
+ btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "msp3400", "msp3400", addrs);
+ if (btv->sd_msp34xx)
+ return;
+ goto no_audio;
+ }
+
+ case 2: {
+ /* The user specified that we should probe for tda7432 */
+ static const unsigned short addrs[] = {
+ I2C_ADDR_TDA7432 >> 1,
+ I2C_CLIENT_END
+ };
+
+ if (v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tda7432", "tda7432", addrs))
+ return;
+ goto no_audio;
+ }
+
+ case 3: {
+ /* The user specified that we should probe for tvaudio */
+ btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tvaudio", "tvaudio", tvaudio_addrs);
+ if (btv->sd_tvaudio)
+ return;
+ goto no_audio;
+ }
+
+ default:
+ printk(KERN_WARNING "bttv%d: unknown audiodev value!\n",
+ btv->c.nr);
+ return;
+ }
- if (!bttv_tvcards[btv->c.type].no_tda9875 &&
- bttv_I2CRead(btv, I2C_ADDR_TDA9875, "TDA9875") >=0)
- request_module("tda9875");
+ /* There were no overrides, so now we try to discover this through the
+ card definition */
+
+ /* probe for msp3400 first: this driver can detect whether or not
+ it really is a msp3400, so it will return NULL when the device
+ found is really something else (e.g. a tea6300). */
+ if (!bttv_tvcards[btv->c.type].no_msp34xx) {
+ static const unsigned short addrs[] = {
+ I2C_ADDR_MSP3400 >> 1,
+ I2C_CLIENT_END
+ };
+
+ btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "msp3400", "msp3400", addrs);
+ } else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
+ static const unsigned short addrs[] = {
+ I2C_ADDR_MSP3400_ALT >> 1,
+ I2C_CLIENT_END
+ };
+
+ btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "msp3400", "msp3400", addrs);
+ }
- if (!bttv_tvcards[btv->c.type].no_tda7432 &&
- bttv_I2CRead(btv, I2C_ADDR_TDA7432, "TDA7432") >=0)
- request_module("tda7432");
+ /* If we found a msp34xx, then we're done. */
+ if (btv->sd_msp34xx)
+ return;
- if (bttv_tvcards[btv->c.type].needs_tvaudio)
- request_module("tvaudio");
+ /* it might also be a tda7432. */
+ if (!bttv_tvcards[btv->c.type].no_tda7432) {
+ static const unsigned short addrs[] = {
+ I2C_ADDR_TDA7432 >> 1,
+ I2C_CLIENT_END
+ };
- if (btv->tuner_type != UNSET && btv->tuner_type != TUNER_ABSENT)
- request_module("tuner");
+ if (v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tda7432", "tda7432", addrs))
+ return;
+ }
+
+ /* Now see if we can find one of the tvaudio devices. */
+ btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tvaudio", "tvaudio", tvaudio_addrs);
+ if (btv->sd_tvaudio)
+ return;
+
+no_audio:
+ printk(KERN_WARNING "bttv%d: audio absent, no audio device found!\n",
+ btv->c.nr);
}
@@ -3819,6 +3750,7 @@ static int terratec_active_radio_upgrade(struct bttv *btv)
printk("bttv%d: Terratec Active Radio Upgrade found.\n",
btv->c.nr);
btv->has_radio = 1;
+ btv->has_saa6588 = 1;
btv->has_matchbox = 1;
} else {
btv->has_radio = 0;
@@ -4067,27 +3999,26 @@ static void __devinit avermedia_eeprom(struct bttv *btv)
btv->has_remote ? "yes" : "no");
}
-/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */
-void bttv_tda9880_setnorm(struct bttv *btv, int norm)
+/*
+ * For Voodoo TV/FM and Voodoo 200. These cards' tuners use a TDA9880
+ * analog demod, which is not I2C controlled like the newer and more common
+ * TDA9887 series. Instead is has two tri-state input pins, S0 and S1,
+ * that control the IF for the video and audio. Apparently, bttv GPIO
+ * 0x10000 is connected to S0. S0 low selects a 38.9 MHz VIF for B/G/D/K/I
+ * (i.e., PAL) while high selects 45.75 MHz for M/N (i.e., NTSC).
+ */
+u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits)
{
- /* fix up our card entry */
- if(norm==V4L2_STD_NTSC) {
- bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x957fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=0x957fff;
- dprintk("bttv_tda9880_setnorm to NTSC\n");
- }
- else {
- bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x947fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=0x947fff;
- dprintk("bttv_tda9880_setnorm to PAL\n");
+
+ if (btv->audio == TVAUDIO_INPUT_TUNER) {
+ if (bttv_tvnorms[btv->tvnorm].v4l2_id & V4L2_STD_MN)
+ gpiobits |= 0x10000;
+ else
+ gpiobits &= ~0x10000;
}
- /* set GPIO according */
- gpio_bits(bttv_tvcards[btv->c.type].gpiomask,
- bttv_tvcards[btv->c.type].gpiomux[btv->audio]);
+
+ gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpiobits);
+ return gpiobits;
}
@@ -4463,6 +4394,11 @@ void tea5757_set_freq(struct bttv *btv, unsigned short freq)
*/
static void rv605_muxsel(struct bttv *btv, unsigned int input)
{
+ static const u8 muxgpio[] = { 0x3, 0x1, 0x2, 0x4, 0xf, 0x7, 0xe, 0x0,
+ 0xd, 0xb, 0xc, 0x6, 0x9, 0x5, 0x8, 0xa };
+
+ gpio_bits(0x07f, muxgpio[input]);
+
/* reset all conections */
gpio_bits(0x200,0x200);
mdelay(1);
@@ -4470,7 +4406,6 @@ static void rv605_muxsel(struct bttv *btv, unsigned int input)
mdelay(1);
/* create a new connection */
- gpio_bits(0x480,0x080);
gpio_bits(0x480,0x480);
mdelay(1);
gpio_bits(0x480,0x080);
@@ -4729,8 +4664,7 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input)
bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02,
((matrix == 2) ? 0x03 : 0x00), 1); /* 9-12 */
- /* Selects MUX0 for input on the 878 */
- btaor((0)<<5, ~(3<<5), BT848_IFORM);
+ /* 878's MUX0 is already selected for input via muxsel values */
}
@@ -4814,6 +4748,132 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input)
printk(KERN_DEBUG "bttv%d: setting input channel to:%d\n", btv->c.nr,(int)mux);
}
+static void phytec_muxsel(struct bttv *btv, unsigned int input)
+{
+ unsigned int mux = input % 4;
+
+ if (input == btv->svhs)
+ mux = 0;
+
+ gpio_bits(0x3, mux);
+}
+
+/*
+ * GeoVision GV-800(S) functions
+ * Bruno Christo <bchristo@inf.ufsm.br>
+*/
+
+/* This is a function to control the analog switch, which determines which
+ * camera is routed to which controller. The switch comprises an X-address
+ * (gpio bits 0-3, representing the camera, ranging from 0-15), and a
+ * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3).
+ * A data value (gpio bit 18) of '1' enables the switch, and '0' disables
+ * the switch. A STROBE bit (gpio bit 17) latches the data value into the
+ * specified address. There is also a chip select (gpio bit 16).
+ * The idea is to set the address and chip select together, bring
+ * STROBE high, write the data, and finally bring STROBE back to low.
+ */
+static void gv800s_write(struct bttv *btv,
+ unsigned char xaddr,
+ unsigned char yaddr,
+ unsigned char data) {
+ /* On the "master" 878A:
+ * GPIO bits 0-9 are used for the analog switch:
+ * 00 - 03: camera selector
+ * 04 - 06: 878A (controller) selector
+ * 16: cselect
+ * 17: strobe
+ * 18: data (1->on, 0->off)
+ * 19: reset
+ */
+ const u32 ADDRESS = ((xaddr&0xf) | (yaddr&3)<<4);
+ const u32 CSELECT = 1<<16;
+ const u32 STROBE = 1<<17;
+ const u32 DATA = data<<18;
+
+ gpio_bits(0x1007f, ADDRESS | CSELECT); /* write ADDRESS and CSELECT */
+ gpio_bits(0x20000, STROBE); /* STROBE high */
+ gpio_bits(0x40000, DATA); /* write DATA */
+ gpio_bits(0x20000, ~STROBE); /* STROBE low */
+}
+
+/*
+ * GeoVision GV-800(S) muxsel
+ *
+ * Each of the 4 cards (controllers) use this function.
+ * The controller using this function selects the input through the GPIO pins
+ * of the "master" card. A pointer to this card is stored in master[btv->c.nr].
+ *
+ * The parameter 'input' is the requested camera number (0-4) on the controller.
+ * The map array has the address of each input. Note that the addresses in the
+ * array are in the sequence the original GeoVision driver uses, that is, set
+ * every controller to input 0, then to input 1, 2, 3, repeat. This means that
+ * the physical "camera 1" connector corresponds to controller 0 input 0,
+ * "camera 2" corresponds to controller 1 input 0, and so on.
+ *
+ * After getting the input address, the function then writes the appropriate
+ * data to the analog switch, and housekeeps the local copy of the switch
+ * information.
+ */
+static void gv800s_muxsel(struct bttv *btv, unsigned int input)
+{
+ struct bttv *mctlr;
+ char *sw_status;
+ int xaddr, yaddr;
+ static unsigned int map[4][4] = { { 0x0, 0x4, 0xa, 0x6 },
+ { 0x1, 0x5, 0xb, 0x7 },
+ { 0x2, 0x8, 0xc, 0xe },
+ { 0x3, 0x9, 0xd, 0xf } };
+ input = input%4;
+ mctlr = master[btv->c.nr];
+ if (mctlr == NULL) {
+ /* do nothing until the "master" is detected */
+ return;
+ }
+ yaddr = (btv->c.nr - mctlr->c.nr) & 3;
+ sw_status = (char *)(&mctlr->mbox_we);
+ xaddr = map[yaddr][input] & 0xf;
+
+ /* Check if the controller/camera pair has changed, ignore otherwise */
+ if (sw_status[yaddr] != xaddr) {
+ /* disable the old switch, enable the new one and save status */
+ gv800s_write(mctlr, sw_status[yaddr], yaddr, 0);
+ sw_status[yaddr] = xaddr;
+ gv800s_write(mctlr, xaddr, yaddr, 1);
+ }
+}
+
+/* GeoVision GV-800(S) "master" chip init */
+static void gv800s_init(struct bttv *btv)
+{
+ char *sw_status = (char *)(&btv->mbox_we);
+ int ix;
+
+ gpio_inout(0xf107f, 0xf107f);
+ gpio_write(1<<19); /* reset the analog MUX */
+ gpio_write(0);
+
+ /* Preset camera 0 to the 4 controllers */
+ for (ix = 0; ix < 4; ix++) {
+ sw_status[ix] = ix;
+ gv800s_write(btv, ix, ix, 1);
+ }
+
+ /* Inputs on the "master" controller need this brightness fix */
+ bttv_I2CWrite(btv, 0x18, 0x5, 0x90, 1);
+
+ if (btv->c.nr > BTTV_MAX-4)
+ return;
+ /*
+ * Store the "master" controller pointer in the master
+ * array for later use in the muxsel function.
+ */
+ master[btv->c.nr] = btv;
+ master[btv->c.nr+1] = btv;
+ master[btv->c.nr+2] = btv;
+ master[btv->c.nr+3] = btv;
+}
+
/* ----------------------------------------------------------------------- */
/* motherboard chipset specific stuff */
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index c71f394fc0ea..7a8ca0d8356f 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -58,7 +58,7 @@
unsigned int bttv_num; /* number of Bt848s in use */
-struct bttv bttvs[BTTV_MAX];
+struct bttv *bttvs[BTTV_MAX];
unsigned int bttv_debug;
unsigned int bttv_verbose = 1;
@@ -167,7 +167,7 @@ static ssize_t show_card(struct device *cd,
struct device_attribute *attr, char *buf)
{
struct video_device *vfd = container_of(cd, struct video_device, dev);
- struct bttv *btv = dev_get_drvdata(vfd->parent);
+ struct bttv *btv = video_get_drvdata(vfd);
return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
}
static DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
@@ -1040,7 +1040,7 @@ static void bt848A_set_timing(struct bttv *btv)
int table_idx = bttv_tvnorms[btv->tvnorm].sram;
int fsc = bttv_tvnorms[btv->tvnorm].Fsc;
- if (UNSET == bttv_tvcards[btv->c.type].muxsel[btv->input]) {
+ if (btv->input == btv->dig) {
dprintk("bttv%d: load digital timing table (table_idx=%d)\n",
btv->c.nr,table_idx);
@@ -1142,7 +1142,7 @@ video_mux(struct bttv *btv, unsigned int input)
btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
}
- mux = bttv_tvcards[btv->c.type].muxsel[input] & 3;
+ mux = bttv_muxsel(btv, input);
btaor(mux<<5, ~(3<<5), BT848_IFORM);
dprintk(KERN_DEBUG "bttv%d: video mux: input=%d mux=%d\n",
btv->c.nr,input,mux);
@@ -1163,7 +1163,6 @@ audio_mux(struct bttv *btv, int input, int mute)
{
int gpio_val, signal;
struct v4l2_control ctrl;
- struct i2c_client *c;
gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
bttv_tvcards[btv->c.type].gpiomask);
@@ -1180,7 +1179,16 @@ audio_mux(struct bttv *btv, int input, int mute)
else
gpio_val = bttv_tvcards[btv->c.type].gpiomux[input];
- gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
+ switch (btv->c.type) {
+ case BTTV_BOARD_VOODOOTV_FM:
+ case BTTV_BOARD_VOODOOTV_200:
+ gpio_val = bttv_tda9880_setnorm(btv, gpio_val);
+ break;
+
+ default:
+ gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
+ }
+
if (bttv_gpio)
bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]);
if (in_interrupt())
@@ -1188,9 +1196,8 @@ audio_mux(struct bttv *btv, int input, int mute)
ctrl.id = V4L2_CID_AUDIO_MUTE;
ctrl.value = btv->mute;
- bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl);
- c = btv->i2c_msp34xx_client;
- if (c) {
+ bttv_call_all(btv, core, s_ctrl, &ctrl);
+ if (btv->sd_msp34xx) {
struct v4l2_routing route;
/* Note: the inputs tuner/radio/extern/intern are translated
@@ -1229,15 +1236,14 @@ audio_mux(struct bttv *btv, int input, int mute)
break;
}
route.output = MSP_OUTPUT_DEFAULT;
- c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ v4l2_subdev_call(btv->sd_msp34xx, audio, s_routing, &route);
}
- c = btv->i2c_tvaudio_client;
- if (c) {
+ if (btv->sd_tvaudio) {
struct v4l2_routing route;
route.input = input;
route.output = 0;
- c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing, &route);
}
return 0;
}
@@ -1277,7 +1283,7 @@ bttv_crop_calc_limits(struct bttv_crop *c)
}
static void
-bttv_crop_reset(struct bttv_crop *c, int norm)
+bttv_crop_reset(struct bttv_crop *c, unsigned int norm)
{
c->rect = bttv_tvnorms[norm].cropcap.defrect;
bttv_crop_calc_limits(c);
@@ -1290,16 +1296,13 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
const struct bttv_tvnorm *tvnorm;
v4l2_std_id id;
- if (norm < 0 || norm >= BTTV_TVNORMS)
- return -EINVAL;
+ BUG_ON(norm >= BTTV_TVNORMS);
+ BUG_ON(btv->tvnorm >= BTTV_TVNORMS);
tvnorm = &bttv_tvnorms[norm];
- if (btv->tvnorm < 0 ||
- btv->tvnorm >= BTTV_TVNORMS ||
- 0 != memcmp(&bttv_tvnorms[btv->tvnorm].cropcap,
- &tvnorm->cropcap,
- sizeof (tvnorm->cropcap))) {
+ if (!memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap,
+ sizeof (tvnorm->cropcap))) {
bttv_crop_reset(&btv->crop[0], norm);
btv->crop[1] = btv->crop[0]; /* current = default */
@@ -1322,11 +1325,11 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
switch (btv->c.type) {
case BTTV_BOARD_VOODOOTV_FM:
case BTTV_BOARD_VOODOOTV_200:
- bttv_tda9880_setnorm(btv,norm);
+ bttv_tda9880_setnorm(btv, gpio_read());
break;
}
id = tvnorm->v4l2_id;
- bttv_call_i2c_clients(btv, VIDIOC_S_STD, &id);
+ bttv_call_all(btv, tuner, s_std, id);
return 0;
}
@@ -1350,8 +1353,8 @@ set_input(struct bttv *btv, unsigned int input, unsigned int norm)
} else {
video_mux(btv,input);
}
- audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ?
- TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN));
+ audio_input(btv, (btv->tuner_type != TUNER_ABSENT && input == 0) ?
+ TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN);
set_tvnorm(btv, norm);
}
@@ -1470,7 +1473,7 @@ static int bttv_g_ctrl(struct file *file, void *priv,
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- bttv_call_i2c_clients(btv, VIDIOC_G_CTRL, c);
+ bttv_call_all(btv, core, g_ctrl, c);
break;
case V4L2_CID_PRIVATE_CHROMA_AGC:
@@ -1544,12 +1547,12 @@ static int bttv_s_ctrl(struct file *file, void *f,
if (btv->volume_gpio)
btv->volume_gpio(btv, c->value);
- bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c);
+ bttv_call_all(btv, core, s_ctrl, c);
break;
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c);
+ bttv_call_all(btv, core, s_ctrl, c);
break;
case V4L2_CID_PRIVATE_CHROMA_AGC:
@@ -1888,20 +1891,15 @@ static int bttv_enum_input(struct file *file, void *priv,
{
struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv;
- unsigned int n;
-
- n = i->index;
+ int n;
- if (n >= bttv_tvcards[btv->c.type].video_inputs)
+ if (i->index >= bttv_tvcards[btv->c.type].video_inputs)
return -EINVAL;
- memset(i, 0, sizeof(*i));
-
- i->index = n;
i->type = V4L2_INPUT_TYPE_CAMERA;
i->audioset = 1;
- if (i->index == bttv_tvcards[btv->c.type].tuner) {
+ if (btv->tuner_type != TUNER_ABSENT && i->index == 0) {
sprintf(i->name, "Television");
i->type = V4L2_INPUT_TYPE_TUNER;
i->tuner = 0;
@@ -1965,14 +1963,14 @@ static int bttv_s_tuner(struct file *file, void *priv,
if (0 != err)
return err;
- if (UNSET == bttv_tvcards[btv->c.type].tuner)
+ if (btv->tuner_type == TUNER_ABSENT)
return -EINVAL;
if (0 != t->index)
return -EINVAL;
mutex_lock(&btv->lock);
- bttv_call_i2c_clients(btv, VIDIOC_S_TUNER, t);
+ bttv_call_all(btv, tuner, s_tuner, t);
if (btv->audio_mode_gpio)
btv->audio_mode_gpio(btv, t, 1);
@@ -2017,7 +2015,7 @@ static int bttv_s_frequency(struct file *file, void *priv,
return -EINVAL;
mutex_lock(&btv->lock);
btv->freq = f->frequency;
- bttv_call_i2c_clients(btv, VIDIOC_S_FREQUENCY, f);
+ bttv_call_all(btv, tuner, s_frequency, f);
if (btv->has_matchbox && btv->radio_user)
tea5757_set_freq(btv, btv->freq);
mutex_unlock(&btv->lock);
@@ -2031,7 +2029,7 @@ static int bttv_log_status(struct file *file, void *f)
printk(KERN_INFO "bttv%d: ======== START STATUS CARD #%d ========\n",
btv->c.nr, btv->c.nr);
- bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL);
+ bttv_call_all(btv, core, log_status);
printk(KERN_INFO "bttv%d: ======== END STATUS CARD #%d ========\n",
btv->c.nr, btv->c.nr);
return 0;
@@ -2659,8 +2657,7 @@ static int bttv_querycap(struct file *file, void *priv,
if (no_overlay <= 0)
cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
- if (bttv_tvcards[btv->c.type].tuner != UNSET &&
- bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
+ if (btv->tuner_type != TUNER_ABSENT)
cap->capabilities |= V4L2_CAP_TUNER;
return 0;
}
@@ -2927,13 +2924,9 @@ static int bttv_g_parm(struct file *file, void *f,
{
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
- struct v4l2_standard s;
- if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id,
- bttv_tvnorms[btv->tvnorm].name);
- parm->parm.capture.timeperframe = s.frameperiod;
+ v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id,
+ &parm->parm.capture.timeperframe);
return 0;
}
@@ -2943,15 +2936,14 @@ static int bttv_g_tuner(struct file *file, void *priv,
struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv;
- if (UNSET == bttv_tvcards[btv->c.type].tuner)
+ if (btv->tuner_type == TUNER_ABSENT)
return -EINVAL;
if (0 != t->index)
return -EINVAL;
mutex_lock(&btv->lock);
- memset(t, 0, sizeof(*t));
t->rxsubchans = V4L2_TUNER_SUB_MONO;
- bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+ bttv_call_all(btv, tuner, g_tuner, t);
strcpy(t->name, "Television");
t->capability = V4L2_TUNER_CAP_NORM;
t->type = V4L2_TUNER_ANALOG_TV;
@@ -3212,29 +3204,19 @@ err:
static int bttv_open(struct file *file)
{
int minor = video_devdata(file)->minor;
- struct bttv *btv = NULL;
+ struct bttv *btv = video_drvdata(file);
struct bttv_fh *fh;
enum v4l2_buf_type type = 0;
- unsigned int i;
dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
lock_kernel();
- for (i = 0; i < bttv_num; i++) {
- if (bttvs[i].video_dev &&
- bttvs[i].video_dev->minor == minor) {
- btv = &bttvs[i];
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- }
- if (bttvs[i].vbi_dev &&
- bttvs[i].vbi_dev->minor == minor) {
- btv = &bttvs[i];
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- }
- }
- if (NULL == btv) {
+ if (btv->video_dev->minor == minor) {
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ } else if (btv->vbi_dev->minor == minor) {
+ type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ } else {
+ WARN_ON(1);
unlock_kernel();
return -ENODEV;
}
@@ -3424,20 +3406,14 @@ static struct video_device bttv_video_template = {
static int radio_open(struct file *file)
{
int minor = video_devdata(file)->minor;
- struct bttv *btv = NULL;
+ struct bttv *btv = video_drvdata(file);
struct bttv_fh *fh;
- unsigned int i;
dprintk("bttv: open minor=%d\n",minor);
lock_kernel();
- for (i = 0; i < bttv_num; i++) {
- if (bttvs[i].radio_dev && bttvs[i].radio_dev->minor == minor) {
- btv = &bttvs[i];
- break;
- }
- }
- if (NULL == btv) {
+ WARN_ON(btv->radio_dev && btv->radio_dev->minor != minor);
+ if (!btv->radio_dev || btv->radio_dev->minor != minor) {
unlock_kernel();
return -ENODEV;
}
@@ -3458,7 +3434,7 @@ static int radio_open(struct file *file)
btv->radio_user++;
- bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL);
+ bttv_call_all(btv, tuner, s_radio);
audio_input(btv,TVAUDIO_INPUT_RADIO);
mutex_unlock(&btv->lock);
@@ -3478,7 +3454,7 @@ static int radio_release(struct file *file)
btv->radio_user--;
- bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd);
+ bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd);
return 0;
}
@@ -3503,16 +3479,15 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv;
- if (UNSET == bttv_tvcards[btv->c.type].tuner)
+ if (btv->tuner_type == TUNER_ABSENT)
return -EINVAL;
if (0 != t->index)
return -EINVAL;
mutex_lock(&btv->lock);
- memset(t, 0, sizeof(*t));
strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
- bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+ bttv_call_all(btv, tuner, g_tuner, t);
if (btv->audio_mode_gpio)
btv->audio_mode_gpio(btv, t, 0);
@@ -3554,7 +3529,7 @@ static int radio_s_tuner(struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+ bttv_call_all(btv, tuner, g_tuner, t);
return 0;
}
@@ -3615,7 +3590,7 @@ static ssize_t radio_read(struct file *file, char __user *data,
cmd.instance = file;
cmd.result = -ENODEV;
- bttv_call_i2c_clients(btv, RDS_CMD_READ, &cmd);
+ bttv_call_all(btv, core, ioctl, RDS_CMD_READ, &cmd);
return cmd.result;
}
@@ -3628,7 +3603,7 @@ static unsigned int radio_poll(struct file *file, poll_table *wait)
cmd.instance = file;
cmd.event_list = wait;
cmd.result = -ENODEV;
- bttv_call_i2c_clients(btv, RDS_CMD_POLL, &cmd);
+ bttv_call_all(btv, core, ioctl, RDS_CMD_POLL, &cmd);
return cmd.result;
}
@@ -3712,14 +3687,14 @@ static void bttv_risc_disasm(struct bttv *btv,
unsigned int i,j,n;
printk("%s: risc disasm: %p [dma=0x%08lx]\n",
- btv->c.name, risc->cpu, (unsigned long)risc->dma);
+ btv->c.v4l2_dev.name, risc->cpu, (unsigned long)risc->dma);
for (i = 0; i < (risc->size >> 2); i += n) {
- printk("%s: 0x%lx: ", btv->c.name,
+ printk("%s: 0x%lx: ", btv->c.v4l2_dev.name,
(unsigned long)(risc->dma + (i<<2)));
n = bttv_risc_decode(le32_to_cpu(risc->cpu[i]));
for (j = 1; j < n; j++)
printk("%s: 0x%lx: 0x%08x [ arg #%d ]\n",
- btv->c.name, (unsigned long)(risc->dma + ((i+j)<<2)),
+ btv->c.v4l2_dev.name, (unsigned long)(risc->dma + ((i+j)<<2)),
risc->cpu[i+j], j);
if (0 == risc->cpu[i])
break;
@@ -4195,9 +4170,10 @@ static struct video_device *vdev_init(struct bttv *btv,
return NULL;
*vfd = *template;
vfd->minor = -1;
- vfd->parent = &btv->c.pci->dev;
+ vfd->v4l2_dev = &btv->c.v4l2_dev;
vfd->release = video_device_release;
vfd->debug = bttv_debug;
+ video_set_drvdata(vfd, btv);
snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
type_name, bttv_tvcards[btv->c.type].name);
@@ -4307,10 +4283,14 @@ static int __devinit bttv_probe(struct pci_dev *dev,
if (bttv_num == BTTV_MAX)
return -ENOMEM;
printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
- btv=&bttvs[bttv_num];
- memset(btv,0,sizeof(*btv));
+ bttvs[bttv_num] = btv = kzalloc(sizeof(*btv), GFP_KERNEL);
+ if (btv == NULL) {
+ printk(KERN_ERR "bttv: out of memory.\n");
+ return -ENOMEM;
+ }
btv->c.nr = bttv_num;
- sprintf(btv->c.name,"bttv%d",btv->c.nr);
+ snprintf(btv->c.v4l2_dev.name, sizeof(btv->c.v4l2_dev.name),
+ "bttv%d", btv->c.nr);
/* initialize structs / fill in defaults */
mutex_init(&btv->lock);
@@ -4347,7 +4327,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
}
if (!request_mem_region(pci_resource_start(dev,0),
pci_resource_len(dev,0),
- btv->c.name)) {
+ btv->c.v4l2_dev.name)) {
printk(KERN_WARNING "bttv%d: can't request iomem (0x%llx).\n",
btv->c.nr,
(unsigned long long)pci_resource_start(dev,0));
@@ -4355,7 +4335,12 @@ static int __devinit bttv_probe(struct pci_dev *dev,
}
pci_set_master(dev);
pci_set_command(dev);
- pci_set_drvdata(dev,btv);
+
+ result = v4l2_device_register(&dev->dev, &btv->c.v4l2_dev);
+ if (result < 0) {
+ printk(KERN_WARNING "bttv%d: v4l2_device_register() failed\n", btv->c.nr);
+ goto fail0;
+ }
pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
@@ -4379,7 +4364,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
/* disable irqs, register irq handler */
btwrite(0, BT848_INT_MASK);
result = request_irq(btv->c.pci->irq, bttv_irq,
- IRQF_SHARED | IRQF_DISABLED,btv->c.name,(void *)btv);
+ IRQF_SHARED | IRQF_DISABLED, btv->c.v4l2_dev.name, (void *)btv);
if (result < 0) {
printk(KERN_ERR "bttv%d: can't get IRQ %d\n",
bttv_num,btv->c.pci->irq);
@@ -4463,21 +4448,24 @@ static int __devinit bttv_probe(struct pci_dev *dev,
bttv_num++;
return 0;
- fail2:
+fail2:
free_irq(btv->c.pci->irq,btv);
- fail1:
+fail1:
+ v4l2_device_unregister(&btv->c.v4l2_dev);
+
+fail0:
if (btv->bt848_mmio)
iounmap(btv->bt848_mmio);
release_mem_region(pci_resource_start(btv->c.pci,0),
pci_resource_len(btv->c.pci,0));
- pci_set_drvdata(dev,NULL);
return result;
}
static void __devexit bttv_remove(struct pci_dev *pci_dev)
{
- struct bttv *btv = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct bttv *btv = to_bttv(v4l2_dev);
if (bttv_verbose)
printk("bttv%d: unloading\n",btv->c.nr);
@@ -4511,14 +4499,18 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
release_mem_region(pci_resource_start(btv->c.pci,0),
pci_resource_len(btv->c.pci,0));
- pci_set_drvdata(pci_dev, NULL);
+ v4l2_device_unregister(&btv->c.v4l2_dev);
+ bttvs[btv->c.nr] = NULL;
+ kfree(btv);
+
return;
}
#ifdef CONFIG_PM
static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
{
- struct bttv *btv = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct bttv *btv = to_bttv(v4l2_dev);
struct bttv_buffer_set idle;
unsigned long flags;
@@ -4553,7 +4545,8 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
static int bttv_resume(struct pci_dev *pci_dev)
{
- struct bttv *btv = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct bttv *btv = to_bttv(v4l2_dev);
unsigned long flags;
int err;
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index bcd2cd240a16..a99d92fac3dc 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -36,8 +36,6 @@
#include <linux/jiffies.h>
#include <asm/io.h>
-static int attach_inform(struct i2c_client *client);
-
static int i2c_debug;
static int i2c_hw;
static int i2c_scan;
@@ -231,7 +229,8 @@ bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
{
- struct bttv *btv = i2c_get_adapdata(i2c_adap);
+ struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap);
+ struct bttv *btv = to_bttv(v4l2_dev);
int retval = 0;
int i;
@@ -265,52 +264,6 @@ static const struct i2c_algorithm bttv_algo = {
/* ----------------------------------------------------------------------- */
/* I2C functions - common stuff */
-static int attach_inform(struct i2c_client *client)
-{
- struct bttv *btv = i2c_get_adapdata(client->adapter);
- int addr=ADDR_UNSET;
-
-
- if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
- addr = bttv_tvcards[btv->c.type].tuner_addr;
-
-
- if (bttv_debug)
- printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
- btv->c.nr, client->driver->driver.name, client->addr,
- client->name);
- if (!client->driver->command)
- return 0;
-
- if (client->driver->id == I2C_DRIVERID_MSP3400)
- btv->i2c_msp34xx_client = client;
- if (client->driver->id == I2C_DRIVERID_TVAUDIO)
- btv->i2c_tvaudio_client = client;
- if (btv->tuner_type != UNSET) {
- struct tuner_setup tun_setup;
-
- if ((addr==ADDR_UNSET) ||
- (addr==client->addr)) {
-
- tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO;
- tun_setup.type = btv->tuner_type;
- tun_setup.addr = addr;
- bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
- }
-
- }
-
- return 0;
-}
-
-void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
-{
- if (0 != btv->i2c_rc)
- return;
- i2c_clients_command(&btv->c.i2c_adap, cmd, arg);
-}
-
-
/* read I2C */
int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
{
@@ -417,21 +370,15 @@ int __devinit init_bttv_i2c(struct bttv *btv)
btv->c.i2c_adap.algo_data = &btv->i2c_algo;
}
btv->c.i2c_adap.owner = THIS_MODULE;
- btv->c.i2c_adap.class = I2C_CLASS_TV_ANALOG;
- btv->c.i2c_adap.client_register = attach_inform;
btv->c.i2c_adap.dev.parent = &btv->c.pci->dev;
snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name),
"bt%d #%d [%s]", btv->id, btv->c.nr,
btv->use_i2c_hw ? "hw" : "sw");
- i2c_set_adapdata(&btv->c.i2c_adap, btv);
+ i2c_set_adapdata(&btv->c.i2c_adap, &btv->c.v4l2_dev);
btv->i2c_client.adapter = &btv->c.i2c_adap;
- if (bttv_tvcards[btv->c.type].no_video)
- btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG;
- if (bttv_tvcards[btv->c.type].has_dvb)
- btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
if (btv->use_i2c_hw) {
btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);
@@ -441,7 +388,7 @@ int __devinit init_bttv_i2c(struct bttv *btv)
btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap);
}
if (0 == btv->i2c_rc && i2c_scan)
- do_i2c_scan(btv->c.name,&btv->i2c_client);
+ do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);
return btv->i2c_rc;
}
diff --git a/drivers/media/video/bt8xx/bttv-if.c b/drivers/media/video/bt8xx/bttv-if.c
index ecf07988cd33..a6a540dc9e4b 100644
--- a/drivers/media/video/bt8xx/bttv-if.c
+++ b/drivers/media/video/bt8xx/bttv-if.c
@@ -47,7 +47,10 @@ struct pci_dev* bttv_get_pcidev(unsigned int card)
{
if (card >= bttv_num)
return NULL;
- return bttvs[card].c.pci;
+ if (!bttvs[card])
+ return NULL;
+
+ return bttvs[card]->c.pci;
}
@@ -59,7 +62,10 @@ int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data)
return -EINVAL;
}
- btv = &bttvs[card];
+ btv = bttvs[card];
+ if (!btv)
+ return -ENODEV;
+
gpio_inout(mask,data);
if (bttv_gpio)
bttv_gpio_tracking(btv,"extern enable");
@@ -74,7 +80,9 @@ int bttv_read_gpio(unsigned int card, unsigned long *data)
return -EINVAL;
}
- btv = &bttvs[card];
+ btv = bttvs[card];
+ if (!btv)
+ return -ENODEV;
if(btv->shutdown) {
return -ENODEV;
@@ -94,7 +102,9 @@ int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data)
return -EINVAL;
}
- btv = &bttvs[card];
+ btv = bttvs[card];
+ if (!btv)
+ return -ENODEV;
/* prior setting BT848_GPIO_REG_INP is (probably) not needed
because direct input is set on init */
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c
index 5b1b8e4c78ba..d16af2836379 100644
--- a/drivers/media/video/bt8xx/bttv-risc.c
+++ b/drivers/media/video/bt8xx/bttv-risc.c
@@ -341,7 +341,7 @@ bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
int totalwidth = tvnorm->totalwidth;
int scaledtwidth = tvnorm->scaledtwidth;
- if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
+ if (btv->input == btv->dig) {
swidth = 720;
totalwidth = 858;
scaledtwidth = 858;
@@ -391,7 +391,7 @@ bttv_calc_geo (struct bttv * btv,
&& crop->width == tvnorm->cropcap.defrect.width
&& crop->height == tvnorm->cropcap.defrect.height
&& width <= tvnorm->swidth /* see PAL-Nc et al */)
- || bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
+ || btv->input == btv->dig) {
bttv_calc_geo_old(btv, geo, width, height,
both_fields, tvnorm);
return;
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c
index 6819e21a3773..e79a402fa6cd 100644
--- a/drivers/media/video/bt8xx/bttv-vbi.c
+++ b/drivers/media/video/bt8xx/bttv-vbi.c
@@ -411,7 +411,7 @@ int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
return 0;
}
-void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm)
+void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm)
{
const struct bttv_tvnorm *tvnorm;
unsigned int real_samples_per_line;
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h
index 529bf6cf634d..3d36daf206f3 100644
--- a/drivers/media/video/bt8xx/bttv.h
+++ b/drivers/media/video/bt8xx/bttv.h
@@ -14,8 +14,9 @@
#ifndef _BTTV_H_
#define _BTTV_H_
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/i2c.h>
+#include <media/v4l2-device.h>
#include <media/ir-common.h>
#include <media/ir-kbd-i2c.h>
#include <media/i2c-addr.h>
@@ -180,6 +181,10 @@
#define BTTV_BOARD_VD012 0x99
#define BTTV_BOARD_VD012_X1 0x9a
#define BTTV_BOARD_VD012_X2 0x9b
+#define BTTV_BOARD_IVCE8784 0x9c
+#define BTTV_BOARD_GEOVISION_GV800S 0x9d
+#define BTTV_BOARD_GEOVISION_GV800S_SL 0x9e
+#define BTTV_BOARD_PV183 0x9f
/* more card-specific defines */
@@ -191,12 +196,9 @@
#define WINVIEW_PT2254_DATA 0x20
#define WINVIEW_PT2254_STROBE 0x80
-/* digital_mode */
-#define DIGITAL_MODE_VIDEO 1
-#define DIGITAL_MODE_CAMERA 2
-
struct bttv_core {
/* device structs */
+ struct v4l2_device v4l2_dev;
struct pci_dev *pci;
struct i2c_adapter i2c_adap;
struct list_head subs; /* struct bttv_sub_device */
@@ -204,59 +206,79 @@ struct bttv_core {
/* device config */
unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */
unsigned int type; /* card type (pointer into tvcards[]) */
- char name[8]; /* dev name */
};
struct bttv;
-
-struct tvcard
-{
+struct tvcard {
char *name;
- unsigned int video_inputs;
- unsigned int audio_inputs;
- unsigned int tuner;
- unsigned int svhs;
- unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
+ void (*volume_gpio)(struct bttv *btv, __u16 volume);
+ void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set);
+ void (*muxsel_hook)(struct bttv *btv, unsigned int input);
+
+ /* MUX bits for each input, two bits per input starting with the LSB */
+ u32 muxsel; /* Use MUXSEL() to set */
+
u32 gpiomask;
- u32 muxsel[16];
u32 gpiomux[4]; /* Tuner, Radio, external, internal */
u32 gpiomute; /* GPIO mute setting */
u32 gpiomask2; /* GPIO MUX mask */
+ unsigned int tuner_type;
+ u8 tuner_addr;
+ u8 video_inputs; /* Number of inputs */
+ unsigned int svhs:4; /* Which input is s-video */
+#define NO_SVHS 15
+ unsigned int pll:2;
+#define PLL_NONE 0
+#define PLL_28 1
+#define PLL_35 2
+
/* i2c audio flags */
unsigned int no_msp34xx:1;
unsigned int no_tda9875:1;
unsigned int no_tda7432:1;
unsigned int needs_tvaudio:1;
unsigned int msp34xx_alt:1;
+ /* Note: currently no card definition needs to mark the presence
+ of a RDS saa6588 chip. If this is ever needed, then add a new
+ 'has_saa6588' bit here. */
- /* flag: video pci function is unused */
- unsigned int no_video:1;
+ unsigned int no_video:1; /* video pci function is unused */
unsigned int has_dvb:1;
unsigned int has_remote:1;
+ unsigned int has_radio:1;
+ unsigned int has_dig_in:1; /* Has digital input (always last input) */
unsigned int no_gpioirq:1;
-
- /* other settings */
- unsigned int pll;
-#define PLL_NONE 0
-#define PLL_28 1
-#define PLL_35 2
-
- unsigned int tuner_type;
- unsigned int tuner_addr;
- unsigned int radio_addr;
-
- unsigned int has_radio;
-
- void (*volume_gpio)(struct bttv *btv, __u16 volume);
- void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-
- void (*muxsel_hook)(struct bttv *btv, unsigned int input);
};
extern struct tvcard bttv_tvcards[];
+/*
+ * This bit of cpp voodoo is used to create a macro with a variable number of
+ * arguments (1 to 16). It will pack each argument into a word two bits at a
+ * time. It can't be a function because it needs to be compile time constant to
+ * initialize structures. Since each argument must fit in two bits, it's ok
+ * that they are changed to octal. One should not use hex number, macros, or
+ * anything else with this macro. Just use plain integers from 0 to 3.
+ */
+#define _MUXSELf(a) 0##a << 30
+#define _MUXSELe(a, b...) 0##a << 28 | _MUXSELf(b)
+#define _MUXSELd(a, b...) 0##a << 26 | _MUXSELe(b)
+#define _MUXSELc(a, b...) 0##a << 24 | _MUXSELd(b)
+#define _MUXSELb(a, b...) 0##a << 22 | _MUXSELc(b)
+#define _MUXSELa(a, b...) 0##a << 20 | _MUXSELb(b)
+#define _MUXSEL9(a, b...) 0##a << 18 | _MUXSELa(b)
+#define _MUXSEL8(a, b...) 0##a << 16 | _MUXSEL9(b)
+#define _MUXSEL7(a, b...) 0##a << 14 | _MUXSEL8(b)
+#define _MUXSEL6(a, b...) 0##a << 12 | _MUXSEL7(b)
+#define _MUXSEL5(a, b...) 0##a << 10 | _MUXSEL6(b)
+#define _MUXSEL4(a, b...) 0##a << 8 | _MUXSEL5(b)
+#define _MUXSEL3(a, b...) 0##a << 6 | _MUXSEL4(b)
+#define _MUXSEL2(a, b...) 0##a << 4 | _MUXSEL3(b)
+#define _MUXSEL1(a, b...) 0##a << 2 | _MUXSEL2(b)
+#define MUXSEL(a, b...) (a | _MUXSEL1(b))
+
/* identification / initialization of the card */
extern void bttv_idcard(struct bttv *btv);
extern void bttv_init_card1(struct bttv *btv);
@@ -264,7 +286,7 @@ extern void bttv_init_card2(struct bttv *btv);
/* card-specific funtions */
extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
-extern void bttv_tda9880_setnorm(struct bttv *btv, int norm);
+extern u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits);
/* extra tweaks for some chipsets */
extern void bttv_check_chipset(void);
@@ -336,7 +358,9 @@ void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits);
/* ---------------------------------------------------------- */
/* i2c */
-extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg);
+#define bttv_call_all(btv, o, f, args...) \
+ v4l2_device_call_all(&btv->c.v4l2_dev, 0, o, f, ##args)
+
extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for);
extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
unsigned char b2, int both);
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index 199a4d225caf..96498489199d 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -32,7 +32,6 @@
#include <linux/wait.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
#include <linux/pci.h>
#include <linux/input.h>
#include <linux/mutex.h>
@@ -135,7 +134,7 @@ struct bttv_buffer {
/* bttv specific */
const struct bttv_format *fmt;
- int tvnorm;
+ unsigned int tvnorm;
int btformat;
int btswap;
struct bttv_geometry geo;
@@ -154,7 +153,7 @@ struct bttv_buffer_set {
};
struct bttv_overlay {
- int tvnorm;
+ unsigned int tvnorm;
struct v4l2_rect w;
enum v4l2_field field;
struct v4l2_clip *clips;
@@ -174,7 +173,7 @@ struct bttv_vbi_fmt {
};
/* bttv-vbi.c */
-void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm);
+void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm);
struct bttv_crop {
/* A cropping rectangle in struct bttv_tvnorm.cropcap units. */
@@ -329,7 +328,8 @@ struct bttv {
unsigned int cardid; /* pci subsystem id (bt878 based ones) */
unsigned int tuner_type; /* tuner chip type */
unsigned int tda9887_conf;
- unsigned int svhs;
+ unsigned int svhs, dig;
+ unsigned int has_saa6588:1;
struct bttv_pll_info pll;
int triton1;
int gpioirq;
@@ -353,8 +353,8 @@ struct bttv {
int i2c_state, i2c_rc;
int i2c_done;
wait_queue_head_t i2c_queue;
- struct i2c_client *i2c_msp34xx_client;
- struct i2c_client *i2c_tvaudio_client;
+ struct v4l2_subdev *sd_msp34xx;
+ struct v4l2_subdev *sd_tvaudio;
/* video4linux (1) */
struct video_device *video_dev;
@@ -378,7 +378,8 @@ struct bttv {
unsigned int audio;
unsigned int mute;
unsigned long freq;
- int tvnorm,hue,contrast,bright,saturation;
+ unsigned int tvnorm;
+ int hue, contrast, bright, saturation;
struct v4l2_framebuffer fbuf;
unsigned int field_count;
@@ -458,10 +459,21 @@ struct bttv {
__s32 crop_start;
};
+static inline struct bttv *to_bttv(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct bttv, c.v4l2_dev);
+}
+
/* our devices */
#define BTTV_MAX 32
extern unsigned int bttv_num;
-extern struct bttv bttvs[BTTV_MAX];
+extern struct bttv *bttvs[BTTV_MAX];
+
+static inline unsigned int bttv_muxsel(const struct bttv *btv,
+ unsigned int input)
+{
+ return (bttv_tvcards[btv->c.type].muxsel >> (input * 2)) & 3;
+}
#endif
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 46fd573a4f15..7abe94d9fb4c 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -11,6 +11,12 @@
*
* Written by Jonathan Corbet, corbet@lwn.net.
*
+ * v4l2_device/v4l2_subdev conversion by:
+ * Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * Note: this conversion is untested! Please contact the linux-media
+ * mailinglist if you can test this, together with the test results.
+ *
* This file may be distributed under the terms of the GNU General
* Public License, version 2.
*/
@@ -25,7 +31,7 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-chip-ident.h>
#include <linux/device.h>
@@ -33,7 +39,6 @@
#include <linux/list.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
-#include <linux/debugfs.h>
#include <linux/jiffies.h>
#include <linux/vmalloc.h>
@@ -136,6 +141,7 @@ struct cafe_sio_buffer {
*/
struct cafe_camera
{
+ struct v4l2_device v4l2_dev;
enum cafe_state state;
unsigned long flags; /* Buffer status, mainly (dev_lock) */
int users; /* How many open FDs */
@@ -145,9 +151,10 @@ struct cafe_camera
* Subsystem structures.
*/
struct pci_dev *pdev;
- struct video_device v4ldev;
+ struct video_device vdev;
struct i2c_adapter i2c_adapter;
- struct i2c_client *sensor;
+ struct v4l2_subdev *sensor;
+ unsigned short sensor_addr;
unsigned char __iomem *regs;
struct list_head dev_list; /* link to other devices */
@@ -180,10 +187,6 @@ struct cafe_camera
/* Misc */
wait_queue_head_t smbus_wait; /* Waiting on i2c events */
wait_queue_head_t iowait; /* Waiting on frame data */
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- struct dentry *dfs_regs;
- struct dentry *dfs_cam_regs;
-#endif
};
/*
@@ -195,6 +198,13 @@ struct cafe_camera
#define CF_DMA_ACTIVE 3 /* A frame is incoming */
#define CF_CONFIG_NEEDED 4 /* Must configure hardware */
+#define sensor_call(cam, o, f, args...) \
+ v4l2_subdev_call(cam->sensor, o, f, ##args)
+
+static inline struct cafe_camera *to_cam(struct v4l2_device *dev)
+{
+ return container_of(dev, struct cafe_camera, v4l2_dev);
+}
/*
@@ -238,59 +248,7 @@ static void cafe_set_config_needed(struct cafe_camera *cam, int needed)
/* ---------------------------------------------------------------------*/
-/*
- * We keep a simple list of known devices to search at open time.
- */
-static LIST_HEAD(cafe_dev_list);
-static DEFINE_MUTEX(cafe_dev_list_lock);
-
-static void cafe_add_dev(struct cafe_camera *cam)
-{
- mutex_lock(&cafe_dev_list_lock);
- list_add_tail(&cam->dev_list, &cafe_dev_list);
- mutex_unlock(&cafe_dev_list_lock);
-}
-
-static void cafe_remove_dev(struct cafe_camera *cam)
-{
- mutex_lock(&cafe_dev_list_lock);
- list_del(&cam->dev_list);
- mutex_unlock(&cafe_dev_list_lock);
-}
-
-static struct cafe_camera *cafe_find_dev(int minor)
-{
- struct cafe_camera *cam;
-
- mutex_lock(&cafe_dev_list_lock);
- list_for_each_entry(cam, &cafe_dev_list, dev_list) {
- if (cam->v4ldev.minor == minor)
- goto done;
- }
- cam = NULL;
- done:
- mutex_unlock(&cafe_dev_list_lock);
- return cam;
-}
-
-
-static struct cafe_camera *cafe_find_by_pdev(struct pci_dev *pdev)
-{
- struct cafe_camera *cam;
- mutex_lock(&cafe_dev_list_lock);
- list_for_each_entry(cam, &cafe_dev_list, dev_list) {
- if (cam->pdev == pdev)
- goto done;
- }
- cam = NULL;
- done:
- mutex_unlock(&cafe_dev_list_lock);
- return cam;
-}
-
-
-/* ------------------------------------------------------------------------ */
/*
* Device register I/O
*/
@@ -481,18 +439,11 @@ static int cafe_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
unsigned short flags, char rw, u8 command,
int size, union i2c_smbus_data *data)
{
- struct cafe_camera *cam = i2c_get_adapdata(adapter);
+ struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter);
+ struct cafe_camera *cam = to_cam(v4l2_dev);
int ret = -EINVAL;
/*
- * Refuse to talk to anything but OV cam chips. We should
- * never even see an attempt to do so, but one never knows.
- */
- if (cam->sensor && addr != cam->sensor->addr) {
- cam_err(cam, "funky smbus addr %d\n", addr);
- return -EINVAL;
- }
- /*
* This interface would appear to only do byte data ops. OK
* it can do word too, but the cam chip has no use for that.
*/
@@ -530,38 +481,9 @@ static struct i2c_algorithm cafe_smbus_algo = {
};
/* Somebody is on the bus */
-static int cafe_cam_init(struct cafe_camera *cam);
static void cafe_ctlr_stop_dma(struct cafe_camera *cam);
static void cafe_ctlr_power_down(struct cafe_camera *cam);
-static int cafe_smbus_attach(struct i2c_client *client)
-{
- struct cafe_camera *cam = i2c_get_adapdata(client->adapter);
-
- /*
- * Don't talk to chips we don't recognize.
- */
- if (client->driver->id == I2C_DRIVERID_OV7670) {
- cam->sensor = client;
- return cafe_cam_init(cam);
- }
- return -EINVAL;
-}
-
-static int cafe_smbus_detach(struct i2c_client *client)
-{
- struct cafe_camera *cam = i2c_get_adapdata(client->adapter);
-
- if (cam->sensor == client) {
- cafe_ctlr_stop_dma(cam);
- cafe_ctlr_power_down(cam);
- cam_err(cam, "lost the sensor!\n");
- cam->sensor = NULL; /* Bummer, no camera */
- cam->state = S_NOTREADY;
- }
- return 0;
-}
-
static int cafe_smbus_setup(struct cafe_camera *cam)
{
struct i2c_adapter *adap = &cam->i2c_adapter;
@@ -570,12 +492,10 @@ static int cafe_smbus_setup(struct cafe_camera *cam)
cafe_smbus_enable_irq(cam);
adap->id = I2C_HW_SMBUS_CAFE;
adap->owner = THIS_MODULE;
- adap->client_register = cafe_smbus_attach;
- adap->client_unregister = cafe_smbus_detach;
adap->algo = &cafe_smbus_algo;
strcpy(adap->name, "cafe_ccic");
adap->dev.parent = &cam->pdev->dev;
- i2c_set_adapdata(adap, cam);
+ i2c_set_adapdata(adap, &cam->v4l2_dev);
ret = i2c_add_adapter(adap);
if (ret)
printk(KERN_ERR "Unable to register cafe i2c adapter\n");
@@ -809,9 +729,9 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam)
* Control 1 is power down, set to 0 to operate.
*/
cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */
-// mdelay(1); /* Marvell says 1ms will do it */
+/* mdelay(1); */ /* Marvell says 1ms will do it */
cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0);
-// mdelay(1); /* Enough? */
+/* mdelay(1); */ /* Enough? */
spin_unlock_irqrestore(&cam->dev_lock, flags);
msleep(5); /* Just to be sure */
}
@@ -833,23 +753,9 @@ static void cafe_ctlr_power_down(struct cafe_camera *cam)
* Communications with the sensor.
*/
-static int __cafe_cam_cmd(struct cafe_camera *cam, int cmd, void *arg)
-{
- struct i2c_client *sc = cam->sensor;
- int ret;
-
- if (sc == NULL || sc->driver == NULL || sc->driver->command == NULL)
- return -EINVAL;
- ret = sc->driver->command(sc, cmd, arg);
- if (ret == -EPERM) /* Unsupported command */
- return 0;
- return ret;
-}
-
static int __cafe_cam_reset(struct cafe_camera *cam)
{
- int zero = 0;
- return __cafe_cam_cmd(cam, VIDIOC_INT_RESET, &zero);
+ return sensor_call(cam, core, reset, 0);
}
/*
@@ -869,14 +775,13 @@ static int cafe_cam_init(struct cafe_camera *cam)
if (ret)
goto out;
chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR;
- chip.match.addr = cam->sensor->addr;
- ret = __cafe_cam_cmd(cam, VIDIOC_DBG_G_CHIP_IDENT, &chip);
+ chip.match.addr = cam->sensor_addr;
+ ret = sensor_call(cam, core, g_chip_ident, &chip);
if (ret)
goto out;
cam->sensor_type = chip.ident;
-// if (cam->sensor->addr != OV7xx0_SID) {
if (cam->sensor_type != V4L2_IDENT_OV7670) {
- cam_err(cam, "Unsupported sensor type %d", cam->sensor->addr);
+ cam_err(cam, "Unsupported sensor type 0x%x", cam->sensor_type);
ret = -EINVAL;
goto out;
}
@@ -900,21 +805,21 @@ static int cafe_cam_set_flip(struct cafe_camera *cam)
memset(&ctrl, 0, sizeof(ctrl));
ctrl.id = V4L2_CID_VFLIP;
ctrl.value = flip;
- return __cafe_cam_cmd(cam, VIDIOC_S_CTRL, &ctrl);
+ return sensor_call(cam, core, s_ctrl, &ctrl);
}
static int cafe_cam_configure(struct cafe_camera *cam)
{
struct v4l2_format fmt;
- int ret, zero = 0;
+ int ret;
if (cam->state != S_IDLE)
return -EINVAL;
fmt.fmt.pix = cam->pix_format;
- ret = __cafe_cam_cmd(cam, VIDIOC_INT_INIT, &zero);
+ ret = sensor_call(cam, core, init, 0);
if (ret == 0)
- ret = __cafe_cam_cmd(cam, VIDIOC_S_FMT, &fmt);
+ ret = sensor_call(cam, video, s_fmt, &fmt);
/*
* OV7670 does weird things if flip is set *before* format...
*/
@@ -1246,8 +1151,6 @@ static int cafe_vidioc_reqbufs(struct file *filp, void *priv,
* Make sure it's something we can do. User pointers could be
* implemented without great pain, but that's not been done yet.
*/
- if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (req->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
/*
@@ -1311,9 +1214,7 @@ static int cafe_vidioc_querybuf(struct file *filp, void *priv,
int ret = -EINVAL;
mutex_lock(&cam->s_mutex);
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- goto out;
- if (buf->index < 0 || buf->index >= cam->n_sbufs)
+ if (buf->index >= cam->n_sbufs)
goto out;
*buf = cam->sb_bufs[buf->index].v4lbuf;
ret = 0;
@@ -1331,9 +1232,7 @@ static int cafe_vidioc_qbuf(struct file *filp, void *priv,
unsigned long flags;
mutex_lock(&cam->s_mutex);
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- goto out;
- if (buf->index < 0 || buf->index >= cam->n_sbufs)
+ if (buf->index >= cam->n_sbufs)
goto out;
sbuf = cam->sb_bufs + buf->index;
if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED) {
@@ -1364,8 +1263,6 @@ static int cafe_vidioc_dqbuf(struct file *filp, void *priv,
unsigned long flags;
mutex_lock(&cam->s_mutex);
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- goto out_unlock;
if (cam->state != S_STREAMING)
goto out_unlock;
if (list_empty(&cam->sb_full) && filp->f_flags & O_NONBLOCK) {
@@ -1474,11 +1371,8 @@ static int cafe_v4l_mmap(struct file *filp, struct vm_area_struct *vma)
static int cafe_v4l_open(struct file *filp)
{
- struct cafe_camera *cam;
+ struct cafe_camera *cam = video_drvdata(filp);
- cam = cafe_find_dev(video_devdata(filp)->minor);
- if (cam == NULL)
- return -ENODEV;
filp->private_data = cam;
mutex_lock(&cam->s_mutex);
@@ -1532,11 +1426,11 @@ static unsigned int cafe_v4l_poll(struct file *filp,
static int cafe_vidioc_queryctrl(struct file *filp, void *priv,
struct v4l2_queryctrl *qc)
{
- struct cafe_camera *cam = filp->private_data;
+ struct cafe_camera *cam = priv;
int ret;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_QUERYCTRL, qc);
+ ret = sensor_call(cam, core, queryctrl, qc);
mutex_unlock(&cam->s_mutex);
return ret;
}
@@ -1545,11 +1439,11 @@ static int cafe_vidioc_queryctrl(struct file *filp, void *priv,
static int cafe_vidioc_g_ctrl(struct file *filp, void *priv,
struct v4l2_control *ctrl)
{
- struct cafe_camera *cam = filp->private_data;
+ struct cafe_camera *cam = priv;
int ret;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_G_CTRL, ctrl);
+ ret = sensor_call(cam, core, g_ctrl, ctrl);
mutex_unlock(&cam->s_mutex);
return ret;
}
@@ -1558,11 +1452,11 @@ static int cafe_vidioc_g_ctrl(struct file *filp, void *priv,
static int cafe_vidioc_s_ctrl(struct file *filp, void *priv,
struct v4l2_control *ctrl)
{
- struct cafe_camera *cam = filp->private_data;
+ struct cafe_camera *cam = priv;
int ret;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_S_CTRL, ctrl);
+ ret = sensor_call(cam, core, s_ctrl, ctrl);
mutex_unlock(&cam->s_mutex);
return ret;
}
@@ -1601,10 +1495,8 @@ static int cafe_vidioc_enum_fmt_vid_cap(struct file *filp,
struct cafe_camera *cam = priv;
int ret;
- if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_ENUM_FMT, fmt);
+ ret = sensor_call(cam, video, enum_fmt, fmt);
mutex_unlock(&cam->s_mutex);
return ret;
}
@@ -1617,7 +1509,7 @@ static int cafe_vidioc_try_fmt_vid_cap(struct file *filp, void *priv,
int ret;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_TRY_FMT, fmt);
+ ret = sensor_call(cam, video, try_fmt, fmt);
mutex_unlock(&cam->s_mutex);
return ret;
}
@@ -1726,7 +1618,7 @@ static int cafe_vidioc_g_parm(struct file *filp, void *priv,
int ret;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_G_PARM, parms);
+ ret = sensor_call(cam, video, g_parm, parms);
mutex_unlock(&cam->s_mutex);
parms->parm.capture.readbuffers = n_dma_bufs;
return ret;
@@ -1739,20 +1631,52 @@ static int cafe_vidioc_s_parm(struct file *filp, void *priv,
int ret;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_S_PARM, parms);
+ ret = sensor_call(cam, video, s_parm, parms);
mutex_unlock(&cam->s_mutex);
parms->parm.capture.readbuffers = n_dma_bufs;
return ret;
}
+static int cafe_vidioc_g_chip_ident(struct file *file, void *priv,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct cafe_camera *cam = priv;
-static void cafe_v4l_dev_release(struct video_device *vd)
+ chip->ident = V4L2_IDENT_NONE;
+ chip->revision = 0;
+ if (v4l2_chip_match_host(&chip->match)) {
+ chip->ident = V4L2_IDENT_CAFE;
+ return 0;
+ }
+ return sensor_call(cam, core, g_chip_ident, chip);
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int cafe_vidioc_g_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
{
- struct cafe_camera *cam = container_of(vd, struct cafe_camera, v4ldev);
+ struct cafe_camera *cam = priv;
- kfree(cam);
+ if (v4l2_chip_match_host(&reg->match)) {
+ reg->val = cafe_reg_read(cam, reg->reg);
+ reg->size = 4;
+ return 0;
+ }
+ return sensor_call(cam, core, g_register, reg);
}
+static int cafe_vidioc_s_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
+{
+ struct cafe_camera *cam = priv;
+
+ if (v4l2_chip_match_host(&reg->match)) {
+ cafe_reg_write(cam, reg->reg, reg->val);
+ return 0;
+ }
+ return sensor_call(cam, core, s_register, reg);
+}
+#endif
/*
* This template device holds all of those v4l2 methods; we
@@ -1790,6 +1714,11 @@ static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = {
.vidioc_s_ctrl = cafe_vidioc_s_ctrl,
.vidioc_g_parm = cafe_vidioc_g_parm,
.vidioc_s_parm = cafe_vidioc_s_parm,
+ .vidioc_g_chip_ident = cafe_vidioc_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = cafe_vidioc_g_register,
+ .vidioc_s_register = cafe_vidioc_s_register,
+#endif
};
static struct video_device cafe_v4l_template = {
@@ -1800,15 +1729,10 @@ static struct video_device cafe_v4l_template = {
.fops = &cafe_v4l_fops,
.ioctl_ops = &cafe_v4l_ioctl_ops,
- .release = cafe_v4l_dev_release,
+ .release = video_device_release_empty,
};
-
-
-
-
-
/* ---------------------------------------------------------------------- */
/*
* Interrupt handler stuff
@@ -1962,127 +1886,6 @@ static irqreturn_t cafe_irq(int irq, void *data)
/* -------------------------------------------------------------------------- */
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-/*
- * Debugfs stuff.
- */
-
-static char cafe_debug_buf[1024];
-static struct dentry *cafe_dfs_root;
-
-static void cafe_dfs_setup(void)
-{
- cafe_dfs_root = debugfs_create_dir("cafe_ccic", NULL);
- if (IS_ERR(cafe_dfs_root)) {
- cafe_dfs_root = NULL; /* Never mind */
- printk(KERN_NOTICE "cafe_ccic unable to set up debugfs\n");
- }
-}
-
-static void cafe_dfs_shutdown(void)
-{
- if (cafe_dfs_root)
- debugfs_remove(cafe_dfs_root);
-}
-
-static int cafe_dfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-static ssize_t cafe_dfs_read_regs(struct file *file,
- char __user *buf, size_t count, loff_t *ppos)
-{
- struct cafe_camera *cam = file->private_data;
- char *s = cafe_debug_buf;
- int offset;
-
- for (offset = 0; offset < 0x44; offset += 4)
- s += sprintf(s, "%02x: %08x\n", offset,
- cafe_reg_read(cam, offset));
- for (offset = 0x88; offset <= 0x90; offset += 4)
- s += sprintf(s, "%02x: %08x\n", offset,
- cafe_reg_read(cam, offset));
- for (offset = 0xb4; offset <= 0xbc; offset += 4)
- s += sprintf(s, "%02x: %08x\n", offset,
- cafe_reg_read(cam, offset));
- for (offset = 0x3000; offset <= 0x300c; offset += 4)
- s += sprintf(s, "%04x: %08x\n", offset,
- cafe_reg_read(cam, offset));
- return simple_read_from_buffer(buf, count, ppos, cafe_debug_buf,
- s - cafe_debug_buf);
-}
-
-static const struct file_operations cafe_dfs_reg_ops = {
- .owner = THIS_MODULE,
- .read = cafe_dfs_read_regs,
- .open = cafe_dfs_open
-};
-
-static ssize_t cafe_dfs_read_cam(struct file *file,
- char __user *buf, size_t count, loff_t *ppos)
-{
- struct cafe_camera *cam = file->private_data;
- char *s = cafe_debug_buf;
- int offset;
-
- if (! cam->sensor)
- return -EINVAL;
- for (offset = 0x0; offset < 0x8a; offset++)
- {
- u8 v;
-
- cafe_smbus_read_data(cam, cam->sensor->addr, offset, &v);
- s += sprintf(s, "%02x: %02x\n", offset, v);
- }
- return simple_read_from_buffer(buf, count, ppos, cafe_debug_buf,
- s - cafe_debug_buf);
-}
-
-static const struct file_operations cafe_dfs_cam_ops = {
- .owner = THIS_MODULE,
- .read = cafe_dfs_read_cam,
- .open = cafe_dfs_open
-};
-
-
-
-static void cafe_dfs_cam_setup(struct cafe_camera *cam)
-{
- char fname[40];
-
- if (!cafe_dfs_root)
- return;
- sprintf(fname, "regs-%d", cam->v4ldev.num);
- cam->dfs_regs = debugfs_create_file(fname, 0444, cafe_dfs_root,
- cam, &cafe_dfs_reg_ops);
- sprintf(fname, "cam-%d", cam->v4ldev.num);
- cam->dfs_cam_regs = debugfs_create_file(fname, 0444, cafe_dfs_root,
- cam, &cafe_dfs_cam_ops);
-}
-
-
-static void cafe_dfs_cam_shutdown(struct cafe_camera *cam)
-{
- if (! IS_ERR(cam->dfs_regs))
- debugfs_remove(cam->dfs_regs);
- if (! IS_ERR(cam->dfs_cam_regs))
- debugfs_remove(cam->dfs_cam_regs);
-}
-
-#else
-
-#define cafe_dfs_setup()
-#define cafe_dfs_shutdown()
-#define cafe_dfs_cam_setup(cam)
-#define cafe_dfs_cam_shutdown(cam)
-#endif /* CONFIG_VIDEO_ADV_DEBUG */
-
-
-
-
-/* ------------------------------------------------------------------------*/
/*
* PCI interface stuff.
*/
@@ -2100,6 +1903,10 @@ static int cafe_pci_probe(struct pci_dev *pdev,
cam = kzalloc(sizeof(struct cafe_camera), GFP_KERNEL);
if (cam == NULL)
goto out;
+ ret = v4l2_device_register(&pdev->dev, &cam->v4l2_dev);
+ if (ret)
+ goto out_free;
+
mutex_init(&cam->s_mutex);
mutex_lock(&cam->s_mutex);
spin_lock_init(&cam->dev_lock);
@@ -2118,14 +1925,14 @@ static int cafe_pci_probe(struct pci_dev *pdev,
*/
ret = pci_enable_device(pdev);
if (ret)
- goto out_free;
+ goto out_unreg;
pci_set_master(pdev);
ret = -EIO;
cam->regs = pci_iomap(pdev, 0, 0);
if (! cam->regs) {
printk(KERN_ERR "Unable to ioremap cafe-ccic regs\n");
- goto out_free;
+ goto out_unreg;
}
ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam);
if (ret)
@@ -2145,17 +1952,31 @@ static int cafe_pci_probe(struct pci_dev *pdev,
ret = cafe_smbus_setup(cam);
if (ret)
goto out_freeirq;
+
+ cam->sensor_addr = 0x42;
+ cam->sensor = v4l2_i2c_new_subdev(&cam->i2c_adapter,
+ "ov7670", "ov7670", cam->sensor_addr);
+ if (cam->sensor == NULL) {
+ ret = -ENODEV;
+ goto out_smbus;
+ }
+ ret = cafe_cam_init(cam);
+ if (ret)
+ goto out_smbus;
+
/*
* Get the v4l2 setup done.
*/
mutex_lock(&cam->s_mutex);
- cam->v4ldev = cafe_v4l_template;
- cam->v4ldev.debug = 0;
-// cam->v4ldev.debug = V4L2_DEBUG_IOCTL_ARG;
- cam->v4ldev.parent = &pdev->dev;
- ret = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, -1);
+ cam->vdev = cafe_v4l_template;
+ cam->vdev.debug = 0;
+/* cam->vdev.debug = V4L2_DEBUG_IOCTL_ARG;*/
+ cam->vdev.v4l2_dev = &cam->v4l2_dev;
+ ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
if (ret)
goto out_smbus;
+ video_set_drvdata(&cam->vdev, cam);
+
/*
* If so requested, try to get our DMA buffers now.
*/
@@ -2165,21 +1986,21 @@ static int cafe_pci_probe(struct pci_dev *pdev,
" will try again later.");
}
- cafe_dfs_cam_setup(cam);
mutex_unlock(&cam->s_mutex);
- cafe_add_dev(cam);
return 0;
- out_smbus:
+out_smbus:
cafe_smbus_shutdown(cam);
- out_freeirq:
+out_freeirq:
cafe_ctlr_power_down(cam);
free_irq(pdev->irq, cam);
- out_iounmap:
+out_iounmap:
pci_iounmap(pdev, cam->regs);
- out_free:
+out_free:
+ v4l2_device_unregister(&cam->v4l2_dev);
+out_unreg:
kfree(cam);
- out:
+out:
return ret;
}
@@ -2190,25 +2011,23 @@ static int cafe_pci_probe(struct pci_dev *pdev,
static void cafe_shutdown(struct cafe_camera *cam)
{
/* FIXME: Make sure we take care of everything here */
- cafe_dfs_cam_shutdown(cam);
if (cam->n_sbufs > 0)
/* What if they are still mapped? Shouldn't be, but... */
cafe_free_sio_buffers(cam);
- cafe_remove_dev(cam);
cafe_ctlr_stop_dma(cam);
cafe_ctlr_power_down(cam);
cafe_smbus_shutdown(cam);
cafe_free_dma_bufs(cam);
free_irq(cam->pdev->irq, cam);
pci_iounmap(cam->pdev, cam->regs);
- video_unregister_device(&cam->v4ldev);
- /* kfree(cam); done in v4l_release () */
+ video_unregister_device(&cam->vdev);
}
static void cafe_pci_remove(struct pci_dev *pdev)
{
- struct cafe_camera *cam = cafe_find_by_pdev(pdev);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct cafe_camera *cam = to_cam(v4l2_dev);
if (cam == NULL) {
printk(KERN_WARNING "pci_remove on unknown pdev %p\n", pdev);
@@ -2218,6 +2037,8 @@ static void cafe_pci_remove(struct pci_dev *pdev)
if (cam->users > 0)
cam_warn(cam, "Removing a device with users!\n");
cafe_shutdown(cam);
+ v4l2_device_unregister(&cam->v4l2_dev);
+ kfree(cam);
/* No unlock - it no longer exists */
}
@@ -2228,7 +2049,8 @@ static void cafe_pci_remove(struct pci_dev *pdev)
*/
static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
- struct cafe_camera *cam = cafe_find_by_pdev(pdev);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct cafe_camera *cam = to_cam(v4l2_dev);
int ret;
enum cafe_state cstate;
@@ -2246,7 +2068,8 @@ static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state)
static int cafe_pci_resume(struct pci_dev *pdev)
{
- struct cafe_camera *cam = cafe_find_by_pdev(pdev);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct cafe_camera *cam = to_cam(v4l2_dev);
int ret = 0;
ret = pci_restore_state(pdev);
@@ -2307,13 +2130,11 @@ static int __init cafe_init(void)
printk(KERN_NOTICE "Marvell M88ALP01 'CAFE' Camera Controller version %d\n",
CAFE_VERSION);
- cafe_dfs_setup();
ret = pci_register_driver(&cafe_pci_driver);
if (ret) {
printk(KERN_ERR "Unable to register cafe_ccic driver\n");
goto out;
}
- request_module("ov7670"); /* FIXME want something more general */
ret = 0;
out:
@@ -2324,7 +2145,6 @@ static int __init cafe_init(void)
static void __exit cafe_exit(void)
{
pci_unregister_driver(&cafe_pci_driver);
- cafe_dfs_shutdown();
}
module_init(cafe_init);
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index c3b0c8c63c76..43ab0adf3b61 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -1381,9 +1381,7 @@ static void proc_cpia_create(void)
{
cpia_proc_root = proc_mkdir("cpia", NULL);
- if (cpia_proc_root)
- cpia_proc_root->owner = THIS_MODULE;
- else
+ if (!cpia_proc_root)
LOG("Unable to initialise /proc/cpia\n");
}
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 9c25894fdd8e..d4099f5312ac 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -37,6 +37,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/init.h>
+#include <linux/videodev.h>
#include <media/v4l2-ioctl.h>
#include "cpia2.h"
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 87e91072627a..9714059ee949 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -141,11 +141,6 @@ static int cs5345_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops cs5345_core_ops = {
@@ -214,8 +209,6 @@ MODULE_DEVICE_TABLE(i2c, cs5345_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "cs5345",
- .driverid = I2C_DRIVERID_CS5345,
- .command = cs5345_command,
.probe = cs5345_probe,
.remove = cs5345_remove,
.id_table = cs5345_id,
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index 7292a6316e63..5aeb066857a7 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -29,7 +29,7 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
MODULE_AUTHOR("Martin Vaughan");
@@ -41,9 +41,6 @@ module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On");
-static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
/* ----------------------------------------------------------------------- */
@@ -122,11 +119,6 @@ static int cs53l32a_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int cs53l32a_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops cs53l32a_core_ops = {
@@ -218,8 +210,6 @@ MODULE_DEVICE_TABLE(i2c, cs53l32a_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "cs53l32a",
- .driverid = I2C_DRIVERID_CS53L32A,
- .command = cs53l32a_command,
.remove = cs53l32a_remove,
.probe = cs53l32a_probe,
.id_table = cs53l32a_id,
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index 8940b5387dec..e8a50a611ebc 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -9,7 +9,7 @@ config VIDEO_CX18
select VIDEO_CX2341X
select VIDEO_CS5345
select DVB_S5H1409 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
---help---
This is a video4linux driver for Conexant cx23418 based
PCI combo video recorder devices.
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
index 57beddf0af4d..bb5c5165dd5f 100644
--- a/drivers/media/video/cx18/cx18-audio.c
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -23,7 +23,6 @@
#include "cx18-driver.h"
#include "cx18-io.h"
-#include "cx18-i2c.h"
#include "cx18-cards.h"
#include "cx18-audio.h"
@@ -33,55 +32,32 @@
settings. */
int cx18_audio_set_io(struct cx18 *cx)
{
+ const struct cx18_card_audio_input *in;
struct v4l2_routing route;
- u32 audio_input;
u32 val;
- int mux_input;
int err;
/* Determine which input to use */
- if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
- audio_input = cx->card->radio_input.audio_input;
- mux_input = cx->card->radio_input.muxer_input;
- } else {
- audio_input =
- cx->card->audio_inputs[cx->audio_input].audio_input;
- mux_input =
- cx->card->audio_inputs[cx->audio_input].muxer_input;
- }
+ if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
+ in = &cx->card->radio_input;
+ else
+ in = &cx->card->audio_inputs[cx->audio_input];
/* handle muxer chips */
- route.input = mux_input;
+ route.input = in->muxer_input;
route.output = 0;
- cx18_i2c_hw(cx, cx->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ v4l2_subdev_call(cx->sd_extmux, audio, s_routing, &route);
- route.input = audio_input;
- err = cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
- VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ route.input = in->audio_input;
+ err = cx18_call_hw_err(cx, cx->card->hw_audio_ctrl,
+ audio, s_routing, &route);
if (err)
return err;
+ /* FIXME - this internal mux should be abstracted to a subdev */
val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30;
- val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
- (audio_input << 4);
- cx18_write_reg(cx, val | 0xb00, CX18_AUDIO_ENABLE);
- cx18_vapi(cx, CX18_APU_RESETAI, 1, 0);
+ val |= (in->audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
+ (in->audio_input << 4);
+ cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30);
return 0;
}
-
-void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route)
-{
- cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
- VIDIOC_INT_S_AUDIO_ROUTING, route);
-}
-
-void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq)
-{
- static u32 freqs[3] = { 44100, 48000, 32000 };
-
- /* The audio clock of the digitizer must match the codec sample
- rate otherwise you get some very strange effects. */
- if (freq > 2)
- return;
- cx18_call_i2c_clients(cx, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[freq]);
-}
diff --git a/drivers/media/video/cx18/cx18-audio.h b/drivers/media/video/cx18/cx18-audio.h
index cb569a69379c..2731d29b0ab9 100644
--- a/drivers/media/video/cx18/cx18-audio.h
+++ b/drivers/media/video/cx18/cx18-audio.h
@@ -22,5 +22,3 @@
*/
int cx18_audio_set_io(struct cx18 *cx);
-void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route);
-void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq);
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
index a2f0ad570434..9e30983f2ff6 100644
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -464,82 +464,76 @@ static void set_mute(struct cx18 *cx, int mute)
}
}
-int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg)
+int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
struct cx18_av_state *state = &cx->av_state;
- struct v4l2_control *ctrl = arg;
int retval;
+ u8 v;
- switch (cmd) {
- case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- {
- u8 v;
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- v = cx18_av_read(cx, 0x803) & ~0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- cx18_av_write(cx, 0x8d3, 0x1f);
- }
- v = cx18_av_read(cx, 0x810) | 0x1;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
+ if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
+ v = cx18_av_read(cx, 0x803) & ~0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
+ cx18_av_write(cx, 0x8d3, 0x1f);
+ }
+ v = cx18_av_read(cx, 0x810) | 0x1;
+ cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
- retval = set_audclk_freq(cx, *(u32 *)arg);
+ retval = set_audclk_freq(cx, freq);
- v = cx18_av_read(cx, 0x810) & ~0x1;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- v = cx18_av_read(cx, 0x803) | 0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- }
- return retval;
+ v = cx18_av_read(cx, 0x810) & ~0x1;
+ cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
+ if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
+ v = cx18_av_read(cx, 0x803) | 0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
}
+ return retval;
+}
- case VIDIOC_G_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = get_volume(cx);
- break;
- case V4L2_CID_AUDIO_BASS:
- ctrl->value = get_bass(cx);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- ctrl->value = get_treble(cx);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- ctrl->value = get_balance(cx);
- break;
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value = get_mute(cx);
- break;
- default:
- return -EINVAL;
- }
+int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = get_volume(cx);
break;
-
- case VIDIOC_S_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- set_volume(cx, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BASS:
- set_bass(cx, ctrl->value);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- set_treble(cx, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- set_balance(cx, ctrl->value);
- break;
- case V4L2_CID_AUDIO_MUTE:
- set_mute(cx, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
+ case V4L2_CID_AUDIO_BASS:
+ ctrl->value = get_bass(cx);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ ctrl->value = get_treble(cx);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ ctrl->value = get_balance(cx);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = get_mute(cx);
break;
-
default:
return -EINVAL;
}
+ return 0;
+}
+int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ set_volume(cx, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ set_bass(cx, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ set_treble(cx, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ set_balance(cx, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ set_mute(cx, ctrl->value);
+ break;
+ default:
+ return -EINVAL;
+ }
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 0b1c84b4ddd6..f4dd9d78eb3d 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -22,8 +22,10 @@
* 02110-1301, USA.
*/
+#include <media/v4l2-chip-ident.h>
#include "cx18-driver.h"
#include "cx18-io.h"
+#include "cx18-cards.h"
int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
{
@@ -97,15 +99,6 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
or_value);
}
-/* ----------------------------------------------------------------------- */
-
-static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
- enum cx18_av_audio_input aud_input);
-static void log_audio_status(struct cx18 *cx);
-static void log_video_status(struct cx18 *cx);
-
-/* ----------------------------------------------------------------------- */
-
static void cx18_av_initialize(struct cx18 *cx)
{
struct cx18_av_state *state = &cx->av_state;
@@ -169,9 +162,14 @@ static void cx18_av_initialize(struct cx18 *cx)
/* Set VGA_TRACK_RANGE to 0x20 */
cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000);
- /* Enable VBI capture */
- cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253F);
- /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */
+ /*
+ * Initial VBI setup
+ * VIP-1.1, 10 bit mode, enable Raw, disable sliced,
+ * don't clamp raw samples when codes are in use, 1 byte user D-words,
+ * IDID0 has line #, RP code V bit transition on VBLANK, data during
+ * blanking intervals
+ */
+ cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4013252e);
/* Set the video input.
The setting in MODE_CTRL gets lost when we do the above setup */
@@ -195,11 +193,61 @@ static void cx18_av_initialize(struct cx18 *cx)
state->default_volume = ((state->default_volume / 2) + 23) << 9;
}
-/* ----------------------------------------------------------------------- */
+static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ cx18_av_initialize(cx);
+ return 0;
+}
+
+static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ switch (val) {
+ case CX18_AV_INIT_PLLS:
+ /*
+ * The crystal freq used in calculations in this driver will be
+ * 28.636360 MHz.
+ * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
+ */
+
+ /*
+ * VDCLK Integer = 0x0f, Post Divider = 0x04
+ * AIMCLK Integer = 0x0e, Post Divider = 0x16
+ */
+ cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
+
+ /* VDCLK Fraction = 0x2be2fe */
+ /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
+ cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
+
+ /* AIMCLK Fraction = 0x05227ad */
+ /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
+ cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
+
+ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
+ cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
+ break;
+
+ case CX18_AV_INIT_NORMAL:
+ default:
+ if (!state->is_initialized) {
+ /* initialize on first use */
+ state->is_initialized = 1;
+ cx18_av_initialize(cx);
+ }
+ break;
+ }
+ return 0;
+}
void cx18_av_std_setup(struct cx18 *cx)
{
struct cx18_av_state *state = &cx->av_state;
+ struct v4l2_subdev *sd = &state->sd;
v4l2_std_id std = state->std;
int hblank, hactive, burst, vblank, vactive, sc;
int vblank656, src_decimation;
@@ -213,6 +261,7 @@ void cx18_av_std_setup(struct cx18 *cx)
cx18_av_write(cx, 0x49f, 0x14);
if (std & V4L2_STD_625_50) {
+ /* FIXME - revisit these for Sliced VBI */
hblank = 132;
hactive = 720;
burst = 93;
@@ -236,13 +285,40 @@ void cx18_av_std_setup(struct cx18 *cx)
sc = 672351;
}
} else {
+ /*
+ * The following relationships of half line counts should hold:
+ * 525 = vsync + vactive + vblank656
+ * 12 = vblank656 - vblank
+ *
+ * vsync: always 6 half-lines of vsync pulses
+ * vactive: half lines of active video
+ * vblank656: half lines, after line 3/mid-266, of blanked video
+ * vblank: half lines, after line 9/272, of blanked video
+ *
+ * As far as I can tell:
+ * vblank656 starts counting from the falling edge of the first
+ * vsync pulse (start of line 4 or mid-266)
+ * vblank starts counting from the after the 6 vsync pulses and
+ * 6 or 5 equalization pulses (start of line 10 or 272)
+ *
+ * For 525 line systems the driver will extract VBI information
+ * from lines 10-21 and lines 273-284.
+ */
+ vblank656 = 38; /* lines 4 - 22 & 266 - 284 */
+ vblank = 26; /* lines 10 - 22 & 272 - 284 */
+ vactive = 481; /* lines 23 - 263 & 285 - 525 */
+
+ /*
+ * For a 13.5 Mpps clock and 15,734.26 Hz line rate, a line is
+ * is 858 pixels = 720 active + 138 blanking. The Hsync leading
+ * edge should happen 1.2 us * 13.5 Mpps ~= 16 pixels after the
+ * end of active video, leaving 122 pixels of hblank to ignore
+ * before active video starts.
+ */
hactive = 720;
hblank = 122;
- vactive = 487;
luma_lpf = 1;
uv_lpf = 1;
- vblank = 26;
- vblank656 = 26;
src_decimation = 0x21f;
if (std == V4L2_STD_PAL_60) {
@@ -265,33 +341,35 @@ void cx18_av_std_setup(struct cx18 *cx)
pll_int = cx18_av_read(cx, 0x108);
pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff;
pll_post = cx18_av_read(cx, 0x109);
- CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n",
- pll_int, pll_frac, pll_post);
+ CX18_DEBUG_INFO_DEV(sd, "PLL regs = int: %u, frac: %u, post: %u\n",
+ pll_int, pll_frac, pll_post);
if (pll_post) {
int fin, fsc, pll;
pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25;
pll /= pll_post;
- CX18_DEBUG_INFO("PLL = %d.%06d MHz\n",
- pll / 1000000, pll % 1000000);
- CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n",
- pll / 8000000, (pll / 8) % 1000000);
+ CX18_DEBUG_INFO_DEV(sd, "PLL = %d.%06d MHz\n",
+ pll / 1000000, pll % 1000000);
+ CX18_DEBUG_INFO_DEV(sd, "PLL/8 = %d.%06d MHz\n",
+ pll / 8000000, (pll / 8) % 1000000);
fin = ((u64)src_decimation * pll) >> 12;
- CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n",
- fin / 1000000, fin % 1000000);
+ CX18_DEBUG_INFO_DEV(sd, "ADC Sampling freq = %d.%06d MHz\n",
+ fin / 1000000, fin % 1000000);
fsc = (((u64)sc) * pll) >> 24L;
- CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n",
- fsc / 1000000, fsc % 1000000);
-
- CX18_DEBUG_INFO("hblank %i, hactive %i, "
- "vblank %i , vactive %i, vblank656 %i, src_dec %i,"
- "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x,"
- " sc 0x%06x\n",
- hblank, hactive, vblank, vactive, vblank656,
- src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
+ CX18_DEBUG_INFO_DEV(sd,
+ "Chroma sub-carrier freq = %d.%06d MHz\n",
+ fsc / 1000000, fsc % 1000000);
+
+ CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, "
+ "vactive %i, vblank656 %i, src_dec %i, "
+ "burst 0x%02x, luma_lpf %i, uv_lpf %i, "
+ "comb 0x%02x, sc 0x%06x\n",
+ hblank, hactive, vblank, vactive, vblank656,
+ src_decimation, burst, luma_lpf, uv_lpf,
+ comb, sc);
}
/* Sets horizontal blanking delay and active lines */
@@ -325,18 +403,16 @@ void cx18_av_std_setup(struct cx18 *cx)
cx18_av_write(cx, 0x47d, 0xff & sc >> 8);
cx18_av_write(cx, 0x47e, 0xff & sc >> 16);
- /* Sets VBI parameters */
if (std & V4L2_STD_625_50) {
- cx18_av_write(cx, 0x47f, 0x01);
- state->vbi_line_offset = 5;
+ state->slicer_line_delay = 1;
+ state->slicer_line_offset = (6 + state->slicer_line_delay - 2);
} else {
- cx18_av_write(cx, 0x47f, 0x00);
- state->vbi_line_offset = 8;
+ state->slicer_line_delay = 0;
+ state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
}
+ cx18_av_write(cx, 0x47f, state->slicer_line_delay);
}
-/* ----------------------------------------------------------------------- */
-
static void input_change(struct cx18 *cx)
{
struct cx18_av_state *state = &cx->av_state;
@@ -382,17 +458,26 @@ static void input_change(struct cx18 *cx)
}
}
+static int cx18_av_s_frequency(struct v4l2_subdev *sd,
+ struct v4l2_frequency *freq)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ input_change(cx);
+ return 0;
+}
+
static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
enum cx18_av_audio_input aud_input)
{
struct cx18_av_state *state = &cx->av_state;
+ struct v4l2_subdev *sd = &state->sd;
u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 &&
vid_input <= CX18_AV_COMPOSITE8);
u8 reg;
u8 v;
- CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n",
- vid_input, aud_input);
+ CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n",
+ vid_input, aud_input);
if (is_composite) {
reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
@@ -405,8 +490,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
luma > CX18_AV_SVIDEO_LUMA8 ||
chroma < CX18_AV_SVIDEO_CHROMA4 ||
chroma > CX18_AV_SVIDEO_CHROMA8) {
- CX18_ERR("0x%04x is not a valid video input!\n",
- vid_input);
+ CX18_ERR_DEV(sd, "0x%04x is not a valid video input!\n",
+ vid_input);
return -EINVAL;
}
reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
@@ -431,7 +516,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
default:
- CX18_ERR("0x%04x is not a valid audio input!\n", aud_input);
+ CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n",
+ aud_input);
return -EINVAL;
}
@@ -461,14 +547,118 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
return 0;
}
-/* ----------------------------------------------------------------------- */
+static int cx18_av_s_video_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ return set_input(cx, route->input, state->aud_input);
+}
+
+static int cx18_av_s_audio_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ return set_input(cx, state->vid_input, route->input);
+}
-static int set_v4lstd(struct cx18 *cx)
+static int cx18_av_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
{
- struct cx18_av_state *state = &cx->av_state;
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ u8 vpres;
+ u8 mode;
+ int val = 0;
+
+ if (state->radio)
+ return 0;
+
+ vpres = cx18_av_read(cx, 0x40e) & 0x20;
+ vt->signal = vpres ? 0xffff : 0x0;
+
+ vt->capability |=
+ V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
+ V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+
+ mode = cx18_av_read(cx, 0x804);
+
+ /* get rxsubchans and audmode */
+ if ((mode & 0xf) == 1)
+ val |= V4L2_TUNER_SUB_STEREO;
+ else
+ val |= V4L2_TUNER_SUB_MONO;
+
+ if (mode == 2 || mode == 4)
+ val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+
+ if (mode & 0x10)
+ val |= V4L2_TUNER_SUB_SAP;
+
+ vt->rxsubchans = val;
+ vt->audmode = state->audmode;
+ return 0;
+}
+
+static int cx18_av_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ u8 v;
+
+ if (state->radio)
+ return 0;
+
+ v = cx18_av_read(cx, 0x809);
+ v &= ~0xf;
+
+ switch (vt->audmode) {
+ case V4L2_TUNER_MODE_MONO:
+ /* mono -> mono
+ stereo -> mono
+ bilingual -> lang1 */
+ break;
+ case V4L2_TUNER_MODE_STEREO:
+ case V4L2_TUNER_MODE_LANG1:
+ /* mono -> mono
+ stereo -> stereo
+ bilingual -> lang1 */
+ v |= 0x4;
+ break;
+ case V4L2_TUNER_MODE_LANG1_LANG2:
+ /* mono -> mono
+ stereo -> stereo
+ bilingual -> lang1/lang2 */
+ v |= 0x7;
+ break;
+ case V4L2_TUNER_MODE_LANG2:
+ /* mono -> mono
+ stereo -> stereo
+ bilingual -> lang2 */
+ v |= 0x1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ cx18_av_write_expect(cx, 0x809, v, v, 0xff);
+ state->audmode = vt->audmode;
+ return 0;
+}
+
+static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
u8 fmt = 0; /* zero is autodetect */
u8 pal_m = 0;
+ if (state->radio == 0 && state->std == norm)
+ return 0;
+
+ state->radio = 0;
+ state->std = norm;
+
/* First tests should be against specific std */
if (state->std == V4L2_STD_NTSC_M_JP) {
fmt = 0x2;
@@ -493,7 +683,7 @@ static int set_v4lstd(struct cx18 *cx)
fmt = 0xc;
}
- CX18_DEBUG_INFO("changing video std to fmt %i\n", fmt);
+ CX18_DEBUG_INFO_DEV(sd, "changing video std to fmt %i\n", fmt);
/* Follow step 9 of section 3.16 in the cx18_av datasheet.
Without this PAL may display a vertical ghosting effect.
@@ -511,15 +701,22 @@ static int set_v4lstd(struct cx18 *cx)
return 0;
}
-/* ----------------------------------------------------------------------- */
+static int cx18_av_s_radio(struct v4l2_subdev *sd)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ state->radio = 1;
+ return 0;
+}
-static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+static int cx18_av_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
if (ctrl->value < 0 || ctrl->value > 255) {
- CX18_ERR("invalid brightness setting %d\n",
- ctrl->value);
+ CX18_ERR_DEV(sd, "invalid brightness setting %d\n",
+ ctrl->value);
return -ERANGE;
}
@@ -528,8 +725,8 @@ static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
case V4L2_CID_CONTRAST:
if (ctrl->value < 0 || ctrl->value > 127) {
- CX18_ERR("invalid contrast setting %d\n",
- ctrl->value);
+ CX18_ERR_DEV(sd, "invalid contrast setting %d\n",
+ ctrl->value);
return -ERANGE;
}
@@ -538,8 +735,8 @@ static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
case V4L2_CID_SATURATION:
if (ctrl->value < 0 || ctrl->value > 127) {
- CX18_ERR("invalid saturation setting %d\n",
- ctrl->value);
+ CX18_ERR_DEV(sd, "invalid saturation setting %d\n",
+ ctrl->value);
return -ERANGE;
}
@@ -548,8 +745,9 @@ static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
break;
case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
- CX18_ERR("invalid hue setting %d\n", ctrl->value);
+ if (ctrl->value < -128 || ctrl->value > 127) {
+ CX18_ERR_DEV(sd, "invalid hue setting %d\n",
+ ctrl->value);
return -ERANGE;
}
@@ -561,17 +759,18 @@ static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_MUTE:
- return cx18_av_audio(cx, VIDIOC_S_CTRL, ctrl);
+ return cx18_av_audio_s_ctrl(cx, ctrl);
default:
return -EINVAL;
}
-
return 0;
}
-static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+static int cx18_av_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
ctrl->value = (s8)cx18_av_read(cx, 0x414) + 128;
@@ -590,31 +789,57 @@ static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_MUTE:
- return cx18_av_audio(cx, VIDIOC_G_CTRL, ctrl);
+ return cx18_av_audio_g_ctrl(cx, ctrl);
default:
return -EINVAL;
}
-
return 0;
}
-/* ----------------------------------------------------------------------- */
-
-static int get_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
+static int cx18_av_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
- switch (fmt->type) {
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx18_av_vbi(cx, VIDIOC_G_FMT, fmt);
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+ case V4L2_CID_CONTRAST:
+ case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
+ case V4L2_CID_HUE:
+ return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
+ default:
+ break;
+ }
+
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535,
+ 65535 / 100, state->default_volume);
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+ case V4L2_CID_AUDIO_BALANCE:
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
default:
return -EINVAL;
}
+ return -EINVAL;
+}
- return 0;
+static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ return cx18_av_vbi_g_fmt(cx, fmt);
}
-static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
+static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
- struct cx18_av_state *state = &cx->av_state;
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
struct v4l2_pix_format *pix;
int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
int is_50Hz = !(state->std & V4L2_STD_525_60);
@@ -629,12 +854,26 @@ static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
- Vlines = pix->height + (is_50Hz ? 4 : 7);
-
+ /*
+ * This adjustment reflects the excess of vactive, set in
+ * cx18_av_std_setup(), above standard values:
+ *
+ * 480 + 1 for 60 Hz systems
+ * 576 + 4 for 50 Hz systems
+ */
+ Vlines = pix->height + (is_50Hz ? 4 : 1);
+
+ /*
+ * Invalid height and width scaling requests are:
+ * 1. width less than 1/16 of the source width
+ * 2. width greater than the source width
+ * 3. height less than 1/8 of the source height
+ * 4. height greater than the source height
+ */
if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
(Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
- CX18_ERR("%dx%d is not a valid size!\n",
- pix->width, pix->height);
+ CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n",
+ pix->width, pix->height);
return -ERANGE;
}
@@ -651,8 +890,9 @@ static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
else
filter = 3;
- CX18_DEBUG_INFO("decoder set size %dx%d -> scale %ux%u\n",
- pix->width, pix->height, HSC, VSC);
+ CX18_DEBUG_INFO_DEV(sd,
+ "decoder set size %dx%d -> scale %ux%u\n",
+ pix->width, pix->height, HSC, VSC);
/* HSCALE=HSC */
cx18_av_write(cx, 0x418, HSC & 0xff);
@@ -666,231 +906,32 @@ static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
break;
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
+ return cx18_av_vbi_s_fmt(cx, fmt);
case V4L2_BUF_TYPE_VBI_CAPTURE:
- return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
+ return cx18_av_vbi_s_fmt(cx, fmt);
default:
return -EINVAL;
}
-
return 0;
}
-/* ----------------------------------------------------------------------- */
-
-int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg)
+static int cx18_av_s_stream(struct v4l2_subdev *sd, int enable)
{
- struct cx18_av_state *state = &cx->av_state;
- struct v4l2_tuner *vt = arg;
- struct v4l2_routing *route = arg;
-
- /* ignore these commands */
- switch (cmd) {
- case TUNER_SET_TYPE_ADDR:
- return 0;
- }
-
- if (!state->is_initialized) {
- CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd);
- /* initialize on first use */
- state->is_initialized = 1;
- cx18_av_initialize(cx);
- }
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
- switch (cmd) {
- case VIDIOC_INT_DECODE_VBI_LINE:
- return cx18_av_vbi(cx, cmd, arg);
-
- case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- return cx18_av_audio(cx, cmd, arg);
-
- case VIDIOC_STREAMON:
- CX18_DEBUG_INFO("enable output\n");
+ CX18_DEBUG_INFO_DEV(sd, "%s output\n", enable ? "enable" : "disable");
+ if (enable) {
cx18_av_write(cx, 0x115, 0x8c);
cx18_av_write(cx, 0x116, 0x07);
- break;
-
- case VIDIOC_STREAMOFF:
- CX18_DEBUG_INFO("disable output\n");
+ } else {
cx18_av_write(cx, 0x115, 0x00);
cx18_av_write(cx, 0x116, 0x00);
- break;
-
- case VIDIOC_LOG_STATUS:
- log_video_status(cx);
- log_audio_status(cx);
- break;
-
- case VIDIOC_G_CTRL:
- return get_v4lctrl(cx, (struct v4l2_control *)arg);
-
- case VIDIOC_S_CTRL:
- return set_v4lctrl(cx, (struct v4l2_control *)arg);
-
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
-
- switch (qc->id) {
- case V4L2_CID_BRIGHTNESS:
- case V4L2_CID_CONTRAST:
- case V4L2_CID_SATURATION:
- case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill_std(qc);
- default:
- break;
- }
-
- switch (qc->id) {
- case V4L2_CID_AUDIO_VOLUME:
- return v4l2_ctrl_query_fill(qc, 0, 65535,
- 65535 / 100, state->default_volume);
- case V4L2_CID_AUDIO_MUTE:
- case V4L2_CID_AUDIO_BALANCE:
- case V4L2_CID_AUDIO_BASS:
- case V4L2_CID_AUDIO_TREBLE:
- return v4l2_ctrl_query_fill_std(qc);
- default:
- return -EINVAL;
- }
- return -EINVAL;
- }
-
- case VIDIOC_G_STD:
- *(v4l2_std_id *)arg = state->std;
- break;
-
- case VIDIOC_S_STD:
- if (state->radio == 0 && state->std == *(v4l2_std_id *)arg)
- return 0;
- state->radio = 0;
- state->std = *(v4l2_std_id *)arg;
- return set_v4lstd(cx);
-
- case AUDC_SET_RADIO:
- state->radio = 1;
- break;
-
- case VIDIOC_INT_G_VIDEO_ROUTING:
- route->input = state->vid_input;
- route->output = 0;
- break;
-
- case VIDIOC_INT_S_VIDEO_ROUTING:
- return set_input(cx, route->input, state->aud_input);
-
- case VIDIOC_INT_G_AUDIO_ROUTING:
- route->input = state->aud_input;
- route->output = 0;
- break;
-
- case VIDIOC_INT_S_AUDIO_ROUTING:
- return set_input(cx, state->vid_input, route->input);
-
- case VIDIOC_S_FREQUENCY:
- input_change(cx);
- break;
-
- case VIDIOC_G_TUNER:
- {
- u8 vpres = cx18_av_read(cx, 0x40e) & 0x20;
- u8 mode;
- int val = 0;
-
- if (state->radio)
- break;
-
- vt->signal = vpres ? 0xffff : 0x0;
-
- vt->capability |=
- V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
- V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
-
- mode = cx18_av_read(cx, 0x804);
-
- /* get rxsubchans and audmode */
- if ((mode & 0xf) == 1)
- val |= V4L2_TUNER_SUB_STEREO;
- else
- val |= V4L2_TUNER_SUB_MONO;
-
- if (mode == 2 || mode == 4)
- val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-
- if (mode & 0x10)
- val |= V4L2_TUNER_SUB_SAP;
-
- vt->rxsubchans = val;
- vt->audmode = state->audmode;
- break;
- }
-
- case VIDIOC_S_TUNER:
- {
- u8 v;
-
- if (state->radio)
- break;
-
- v = cx18_av_read(cx, 0x809);
- v &= ~0xf;
-
- switch (vt->audmode) {
- case V4L2_TUNER_MODE_MONO:
- /* mono -> mono
- stereo -> mono
- bilingual -> lang1 */
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang1 */
- v |= 0x4;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang1/lang2 */
- v |= 0x7;
- break;
- case V4L2_TUNER_MODE_LANG2:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang2 */
- v |= 0x1;
- break;
- default:
- return -EINVAL;
- }
- cx18_av_write_expect(cx, 0x809, v, v, 0xff);
- state->audmode = vt->audmode;
- break;
}
-
- case VIDIOC_G_FMT:
- return get_v4lfmt(cx, (struct v4l2_format *)arg);
-
- case VIDIOC_S_FMT:
- return set_v4lfmt(cx, (struct v4l2_format *)arg);
-
- case VIDIOC_INT_RESET:
- cx18_av_initialize(cx);
- break;
-
- default:
- return -EINVAL;
- }
-
return 0;
}
-/* ----------------------------------------------------------------------- */
-
-/* ----------------------------------------------------------------------- */
-
static void log_video_status(struct cx18 *cx)
{
static const char *const fmt_strs[] = {
@@ -903,36 +944,40 @@ static void log_video_status(struct cx18 *cx)
};
struct cx18_av_state *state = &cx->av_state;
+ struct v4l2_subdev *sd = &state->sd;
u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf;
u8 gen_stat1 = cx18_av_read(cx, 0x40d);
u8 gen_stat2 = cx18_av_read(cx, 0x40e);
int vid_input = state->vid_input;
- CX18_INFO("Video signal: %spresent\n",
- (gen_stat2 & 0x20) ? "" : "not ");
- CX18_INFO("Detected format: %s\n",
- fmt_strs[gen_stat1 & 0xf]);
+ CX18_INFO_DEV(sd, "Video signal: %spresent\n",
+ (gen_stat2 & 0x20) ? "" : "not ");
+ CX18_INFO_DEV(sd, "Detected format: %s\n",
+ fmt_strs[gen_stat1 & 0xf]);
- CX18_INFO("Specified standard: %s\n",
- vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
+ CX18_INFO_DEV(sd, "Specified standard: %s\n",
+ vidfmt_sel ? fmt_strs[vidfmt_sel]
+ : "automatic detection");
if (vid_input >= CX18_AV_COMPOSITE1 &&
vid_input <= CX18_AV_COMPOSITE8) {
- CX18_INFO("Specified video input: Composite %d\n",
- vid_input - CX18_AV_COMPOSITE1 + 1);
+ CX18_INFO_DEV(sd, "Specified video input: Composite %d\n",
+ vid_input - CX18_AV_COMPOSITE1 + 1);
} else {
- CX18_INFO("Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
- (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
+ CX18_INFO_DEV(sd, "Specified video input: "
+ "S-Video (Luma In%d, Chroma In%d)\n",
+ (vid_input & 0xf0) >> 4,
+ (vid_input & 0xf00) >> 8);
}
- CX18_INFO("Specified audioclock freq: %d Hz\n", state->audclk_freq);
+ CX18_INFO_DEV(sd, "Specified audioclock freq: %d Hz\n",
+ state->audclk_freq);
}
-/* ----------------------------------------------------------------------- */
-
static void log_audio_status(struct cx18 *cx)
{
struct cx18_av_state *state = &cx->av_state;
+ struct v4l2_subdev *sd = &state->sd;
u8 download_ctl = cx18_av_read(cx, 0x803);
u8 mod_det_stat0 = cx18_av_read(cx, 0x804);
u8 mod_det_stat1 = cx18_av_read(cx, 0x805);
@@ -955,7 +1000,7 @@ static void log_audio_status(struct cx18 *cx)
case 0xfe: p = "forced mode"; break;
default: p = "not defined"; break;
}
- CX18_INFO("Detected audio mode: %s\n", p);
+ CX18_INFO_DEV(sd, "Detected audio mode: %s\n", p);
switch (mod_det_stat1) {
case 0x00: p = "not defined"; break;
@@ -980,11 +1025,11 @@ static void log_audio_status(struct cx18 *cx)
case 0xff: p = "no detected audio standard"; break;
default: p = "not defined"; break;
}
- CX18_INFO("Detected audio standard: %s\n", p);
- CX18_INFO("Audio muted: %s\n",
- (mute_ctl & 0x2) ? "yes" : "no");
- CX18_INFO("Audio microcontroller: %s\n",
- (download_ctl & 0x10) ? "running" : "stopped");
+ CX18_INFO_DEV(sd, "Detected audio standard: %s\n", p);
+ CX18_INFO_DEV(sd, "Audio muted: %s\n",
+ (mute_ctl & 0x2) ? "yes" : "no");
+ CX18_INFO_DEV(sd, "Audio microcontroller: %s\n",
+ (download_ctl & 0x10) ? "running" : "stopped");
switch (audio_config >> 4) {
case 0x00: p = "undefined"; break;
@@ -1005,7 +1050,7 @@ static void log_audio_status(struct cx18 *cx)
case 0x0f: p = "automatic detection"; break;
default: p = "undefined"; break;
}
- CX18_INFO("Configured audio standard: %s\n", p);
+ CX18_INFO_DEV(sd, "Configured audio standard: %s\n", p);
if ((audio_config >> 4) < 0xF) {
switch (audio_config & 0xF) {
@@ -1019,7 +1064,7 @@ static void log_audio_status(struct cx18 *cx)
case 0x07: p = "DUAL3 (AB)"; break;
default: p = "undefined";
}
- CX18_INFO("Configured audio mode: %s\n", p);
+ CX18_INFO_DEV(sd, "Configured audio mode: %s\n", p);
} else {
switch (audio_config & 0xF) {
case 0x00: p = "BG"; break;
@@ -1037,14 +1082,14 @@ static void log_audio_status(struct cx18 *cx)
case 0x0f: p = "automatic standard and mode detection"; break;
default: p = "undefined"; break;
}
- CX18_INFO("Configured audio system: %s\n", p);
+ CX18_INFO_DEV(sd, "Configured audio system: %s\n", p);
}
if (aud_input)
- CX18_INFO("Specified audio input: Tuner (In%d)\n",
- aud_input);
+ CX18_INFO_DEV(sd, "Specified audio input: Tuner (In%d)\n",
+ aud_input);
else
- CX18_INFO("Specified audio input: External\n");
+ CX18_INFO_DEV(sd, "Specified audio input: External\n");
switch (pref_mode & 0xf) {
case 0: p = "mono/language A"; break;
@@ -1057,14 +1102,14 @@ static void log_audio_status(struct cx18 *cx)
case 7: p = "language AB"; break;
default: p = "undefined"; break;
}
- CX18_INFO("Preferred audio mode: %s\n", p);
+ CX18_INFO_DEV(sd, "Preferred audio mode: %s\n", p);
if ((audio_config & 0xf) == 0xf) {
switch ((afc0 >> 3) & 0x1) {
case 0: p = "system DK"; break;
case 1: p = "system L"; break;
}
- CX18_INFO("Selected 65 MHz format: %s\n", p);
+ CX18_INFO_DEV(sd, "Selected 65 MHz format: %s\n", p);
switch (afc0 & 0x7) {
case 0: p = "Chroma"; break;
@@ -1074,6 +1119,131 @@ static void log_audio_status(struct cx18 *cx)
case 4: p = "autodetect"; break;
default: p = "undefined"; break;
}
- CX18_INFO("Selected 45 MHz format: %s\n", p);
+ CX18_INFO_DEV(sd, "Selected 45 MHz format: %s\n", p);
}
}
+
+static int cx18_av_log_status(struct v4l2_subdev *sd)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ log_video_status(cx);
+ log_audio_status(cx);
+ return 0;
+}
+
+static inline int cx18_av_dbg_match(const struct v4l2_dbg_match *match)
+{
+ return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 1;
+}
+
+static int cx18_av_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+
+ if (cx18_av_dbg_match(&chip->match)) {
+ chip->ident = state->id;
+ chip->revision = state->rev;
+ }
+ return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int cx18_av_g_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ if (!cx18_av_dbg_match(&reg->match))
+ return -EINVAL;
+ if ((reg->reg & 0x3) != 0)
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ reg->size = 4;
+ reg->val = cx18_av_read4(cx, reg->reg & 0x00000ffc);
+ return 0;
+}
+
+static int cx18_av_s_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ if (!cx18_av_dbg_match(&reg->match))
+ return -EINVAL;
+ if ((reg->reg & 0x3) != 0)
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ cx18_av_write4(cx, reg->reg & 0x00000ffc, reg->val);
+ return 0;
+}
+#endif
+
+static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
+ .g_chip_ident = cx18_av_g_chip_ident,
+ .log_status = cx18_av_log_status,
+ .init = cx18_av_init,
+ .reset = cx18_av_reset,
+ .queryctrl = cx18_av_queryctrl,
+ .g_ctrl = cx18_av_g_ctrl,
+ .s_ctrl = cx18_av_s_ctrl,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = cx18_av_g_register,
+ .s_register = cx18_av_s_register,
+#endif
+};
+
+static const struct v4l2_subdev_tuner_ops cx18_av_tuner_ops = {
+ .s_radio = cx18_av_s_radio,
+ .s_frequency = cx18_av_s_frequency,
+ .g_tuner = cx18_av_g_tuner,
+ .s_tuner = cx18_av_s_tuner,
+ .s_std = cx18_av_s_std,
+};
+
+static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {
+ .s_clock_freq = cx18_av_s_clock_freq,
+ .s_routing = cx18_av_s_audio_routing,
+};
+
+static const struct v4l2_subdev_video_ops cx18_av_video_ops = {
+ .s_routing = cx18_av_s_video_routing,
+ .decode_vbi_line = cx18_av_decode_vbi_line,
+ .s_stream = cx18_av_s_stream,
+ .g_fmt = cx18_av_g_fmt,
+ .s_fmt = cx18_av_s_fmt,
+};
+
+static const struct v4l2_subdev_ops cx18_av_ops = {
+ .core = &cx18_av_general_ops,
+ .tuner = &cx18_av_tuner_ops,
+ .audio = &cx18_av_audio_ops,
+ .video = &cx18_av_video_ops,
+};
+
+int cx18_av_probe(struct cx18 *cx)
+{
+ struct cx18_av_state *state = &cx->av_state;
+ struct v4l2_subdev *sd;
+
+ state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
+ state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
+ ? V4L2_IDENT_CX23418_843 : V4L2_IDENT_UNKNOWN;
+
+ state->vid_input = CX18_AV_COMPOSITE7;
+ state->aud_input = CX18_AV_AUDIO8;
+ state->audclk_freq = 48000;
+ state->audmode = V4L2_TUNER_MODE_LANG1;
+ state->slicer_line_delay = 0;
+ state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
+
+ sd = &state->sd;
+ v4l2_subdev_init(sd, &cx18_av_ops);
+ v4l2_set_subdevdata(sd, cx);
+ snprintf(sd->name, sizeof(sd->name),
+ "%s %03x", cx->v4l2_dev.name, (state->rev >> 4));
+ sd->grp_id = CX18_HW_418_AV;
+ return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
+}
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index cf68a6039091..c458120e8c90 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -25,6 +25,8 @@
#ifndef _CX18_AV_CORE_H_
#define _CX18_AV_CORE_H_
+#include <media/v4l2-device.h>
+
struct cx18;
enum cx18_av_video_input {
@@ -73,17 +75,40 @@ enum cx18_av_audio_input {
};
struct cx18_av_state {
+ struct v4l2_subdev sd;
int radio;
v4l2_std_id std;
enum cx18_av_video_input vid_input;
enum cx18_av_audio_input aud_input;
u32 audclk_freq;
int audmode;
- int vbi_line_offset;
int default_volume;
u32 id;
u32 rev;
int is_initialized;
+
+ /*
+ * The VBI slicer starts operating and counting lines, begining at
+ * slicer line count of 1, at D lines after the deassertion of VRESET.
+ * This staring field line, S, is 6 (& 319) or 10 (& 273) for 625 or 525
+ * line systems respectively. Sliced ancillary data captured on VBI
+ * slicer line M is inserted after the VBI slicer is done with line M,
+ * when VBI slicer line count is N = M+1. Thus when the VBI slicer
+ * reports a VBI slicer line number with ancillary data, the IDID0 byte
+ * indicates VBI slicer line N. The actual field line that the captured
+ * data comes from is
+ *
+ * L = M+(S+D-1) = N-1+(S+D-1) = N + (S+D-2).
+ *
+ * L is the line in the field, not frame, from which the VBI data came.
+ * N is the line reported by the slicer in the ancillary data.
+ * D is the slicer_line_delay value programmed into register 0x47f.
+ * S is 6 for 625 line systems or 10 for 525 line systems
+ * (S+D-2) is the slicer_line_offset used to convert slicer reported
+ * line counts to actual field lines.
+ */
+ int slicer_line_delay;
+ int slicer_line_offset;
};
@@ -298,6 +323,16 @@ struct cx18_av_state {
#define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */
#define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */
+static inline struct cx18_av_state *to_cx18_av_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct cx18_av_state, sd);
+}
+
+enum cx18_av_subdev_init_arg {
+ CX18_AV_INIT_NORMAL = 0,
+ CX18_AV_INIT_PLLS = 1,
+};
+
/* ----------------------------------------------------------------------- */
/* cx18_av-core.c */
int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
@@ -310,20 +345,26 @@ u8 cx18_av_read(struct cx18 *cx, u16 addr);
u32 cx18_av_read4(struct cx18 *cx, u16 addr);
int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
-int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg);
void cx18_av_std_setup(struct cx18 *cx);
+int cx18_av_probe(struct cx18 *cx);
+
/* ----------------------------------------------------------------------- */
/* cx18_av-firmware.c */
int cx18_av_loadfw(struct cx18 *cx);
/* ----------------------------------------------------------------------- */
/* cx18_av-audio.c */
-int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg);
+int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl);
+int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl);
+int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
void cx18_av_audio_set_path(struct cx18 *cx);
/* ----------------------------------------------------------------------- */
/* cx18_av-vbi.c */
-int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg);
+int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
+ struct v4l2_decode_vbi_line *vbi);
+int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt);
+int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt);
#endif
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index c64fd0a05a97..49a55cc8d839 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -29,6 +29,7 @@
int cx18_av_loadfw(struct cx18 *cx)
{
+ struct v4l2_subdev *sd = &cx->av_state.sd;
const struct firmware *fw = NULL;
u32 size;
u32 v;
@@ -36,8 +37,8 @@ int cx18_av_loadfw(struct cx18 *cx)
int i;
int retries1 = 0;
- if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) {
- CX18_ERR("unable to open firmware %s\n", FWFILE);
+ if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) {
+ CX18_ERR_DEV(sd, "unable to open firmware %s\n", FWFILE);
return -EINVAL;
}
@@ -88,7 +89,7 @@ int cx18_av_loadfw(struct cx18 *cx)
retries1++;
}
if (retries1 >= 5) {
- CX18_ERR("unable to load firmware %s\n", FWFILE);
+ CX18_ERR_DEV(sd, "unable to load firmware %s\n", FWFILE);
release_firmware(fw);
return -EIO;
}
@@ -115,9 +116,9 @@ int cx18_av_loadfw(struct cx18 *cx)
are generated) */
cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0);
- /* set alt I2s master clock to /16 and enable alt divider i2s
+ /* set alt I2s master clock to /0x16 and enable alt divider i2s
passthrough */
- cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687);
+ cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5600B687);
cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, 0x000000F6, 0x000000F6,
0x3F00FFFF);
@@ -131,7 +132,8 @@ int cx18_av_loadfw(struct cx18 *cx)
v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
/* If bit 11 is 1, clear bit 10 */
if (v & 0x800)
- cx18_write_reg(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE);
+ cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE,
+ 0, 0x400);
/* Enable WW auto audio standard detection */
v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
@@ -142,6 +144,6 @@ int cx18_av_loadfw(struct cx18 *cx)
release_firmware(fw);
- CX18_INFO("loaded %s firmware (%d bytes)\n", FWFILE, size);
+ CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
index 1527ea4f6b06..23b31670bf1d 100644
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -24,6 +24,52 @@
#include "cx18-driver.h"
+/*
+ * For sliced VBI output, we set up to use VIP-1.1, 8-bit mode,
+ * NN counts 1 byte Dwords, an IDID with the VBI line # in it.
+ * Thus, according to the VIP-2 Spec, our VBI ancillary data lines
+ * (should!) look like:
+ * 4 byte EAV code: 0xff 0x00 0x00 0xRP
+ * unknown number of possible idle bytes
+ * 3 byte Anc data preamble: 0x00 0xff 0xff
+ * 1 byte data identifier: ne010iii (parity bits, 010, DID bits)
+ * 1 byte secondary data id: nessssss (parity bits, SDID bits)
+ * 1 byte data word count: necccccc (parity bits, NN Dword count)
+ * 2 byte Internal DID: VBI-line-# 0x80
+ * NN data bytes
+ * 1 byte checksum
+ * Fill bytes needed to fil out to 4*NN bytes of payload
+ *
+ * The RP codes for EAVs when in VIP-1.1 mode, not in raw mode, &
+ * in the vertical blanking interval are:
+ * 0xb0 (Task 0 VerticalBlank HorizontalBlank 0 0 0 0)
+ * 0xf0 (Task EvenField VerticalBlank HorizontalBlank 0 0 0 0)
+ *
+ * Since the V bit is only allowed to toggle in the EAV RP code, just
+ * before the first active region line and for active lines, they are:
+ * 0x90 (Task 0 0 HorizontalBlank 0 0 0 0)
+ * 0xd0 (Task EvenField 0 HorizontalBlank 0 0 0 0)
+ *
+ * The user application DID bytes we care about are:
+ * 0x91 (1 0 010 0 !ActiveLine AncDataPresent)
+ * 0x55 (0 1 010 2ndField !ActiveLine AncDataPresent)
+ *
+ */
+static const u8 sliced_vbi_did[2] = { 0x91, 0x55 };
+
+struct vbi_anc_data {
+ /* u8 eav[4]; */
+ /* u8 idle[]; Variable number of idle bytes */
+ u8 preamble[3];
+ u8 did;
+ u8 sdid;
+ u8 data_count;
+ u8 idid[2];
+ u8 payload[1]; /* data_count of payload */
+ /* u8 checksum; */
+ /* u8 fill[]; Variable number of fill bytes */
+};
+
static int odd_parity(u8 c)
{
c ^= (c >> 4);
@@ -83,188 +129,189 @@ static int decode_vps(u8 *dst, u8 *p)
return err & 0xf0;
}
-int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
+int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt)
{
struct cx18_av_state *state = &cx->av_state;
- struct v4l2_format *fmt;
struct v4l2_sliced_vbi_format *svbi;
+ static const u16 lcr2vbi[] = {
+ 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
+ 0, V4L2_SLICED_WSS_625, 0, /* 4 */
+ V4L2_SLICED_CAPTION_525, /* 6 */
+ 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
+ 0, 0, 0, 0
+ };
+ int is_pal = !(state->std & V4L2_STD_525_60);
+ int i;
- switch (cmd) {
- case VIDIOC_G_FMT:
- {
- static u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
- 0, V4L2_SLICED_WSS_625, 0, /* 4 */
- V4L2_SLICED_CAPTION_525, /* 6 */
- 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
- 0, 0, 0, 0
- };
- int is_pal = !(state->std & V4L2_STD_525_60);
- int i;
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- memset(svbi, 0, sizeof(*svbi));
- /* we're done if raw VBI is active */
- if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
- break;
-
- if (is_pal) {
- for (i = 7; i <= 23; i++) {
- u8 v = cx18_av_read(cx, 0x424 + i - 7);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |= svbi->service_lines[0][i] |
- svbi->service_lines[1][i];
- }
- } else {
- for (i = 10; i <= 21; i++) {
- u8 v = cx18_av_read(cx, 0x424 + i - 10);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |= svbi->service_lines[0][i] |
- svbi->service_lines[1][i];
- }
- }
- break;
- }
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ memset(svbi, 0, sizeof(*svbi));
+ /* we're done if raw VBI is active */
+ if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
+ return 0;
- case VIDIOC_S_FMT:
- {
- int is_pal = !(state->std & V4L2_STD_525_60);
- int vbi_offset = is_pal ? 1 : 0;
- int i, x;
- u8 lcr[24];
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
- fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- /* raw VBI */
- memset(svbi, 0, sizeof(*svbi));
-
- /* Setup standard */
- cx18_av_std_setup(cx);
-
- /* VBI Offset */
- cx18_av_write(cx, 0x47f, vbi_offset);
- cx18_av_write(cx, 0x404, 0x2e);
- break;
+ if (is_pal) {
+ for (i = 7; i <= 23; i++) {
+ u8 v = cx18_av_read(cx, 0x424 + i - 7);
+
+ svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+ svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+ svbi->service_set |= svbi->service_lines[0][i] |
+ svbi->service_lines[1][i];
+ }
+ } else {
+ for (i = 10; i <= 21; i++) {
+ u8 v = cx18_av_read(cx, 0x424 + i - 10);
+
+ svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+ svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+ svbi->service_set |= svbi->service_lines[0][i] |
+ svbi->service_lines[1][i];
}
+ }
+ return 0;
+}
- for (x = 0; x <= 23; x++)
- lcr[x] = 0x00;
+int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt)
+{
+ struct cx18_av_state *state = &cx->av_state;
+ struct v4l2_sliced_vbi_format *svbi;
+ int is_pal = !(state->std & V4L2_STD_525_60);
+ int i, x;
+ u8 lcr[24];
+
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
+ fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ /* raw VBI */
+ memset(svbi, 0, sizeof(*svbi));
/* Setup standard */
cx18_av_std_setup(cx);
- /* Sliced VBI */
- cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
- cx18_av_write(cx, 0x406, 0x13);
- cx18_av_write(cx, 0x47f, vbi_offset);
-
- if (is_pal) {
- for (i = 0; i <= 6; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- } else {
- for (i = 0; i <= 9; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
-
- for (i = 22; i <= 23; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- }
+ /* VBI Offset */
+ cx18_av_write(cx, 0x47f, state->slicer_line_delay);
+ cx18_av_write(cx, 0x404, 0x2e);
+ return 0;
+ }
- for (i = 7; i <= 23; i++) {
- for (x = 0; x <= 1; x++) {
- switch (svbi->service_lines[1-x][i]) {
- case V4L2_SLICED_TELETEXT_B:
- lcr[i] |= 1 << (4 * x);
- break;
- case V4L2_SLICED_WSS_625:
- lcr[i] |= 4 << (4 * x);
- break;
- case V4L2_SLICED_CAPTION_525:
- lcr[i] |= 6 << (4 * x);
- break;
- case V4L2_SLICED_VPS:
- lcr[i] |= 9 << (4 * x);
- break;
- }
- }
- }
+ for (x = 0; x <= 23; x++)
+ lcr[x] = 0x00;
+
+ /* Setup standard */
+ cx18_av_std_setup(cx);
+
+ /* Sliced VBI */
+ cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
+ cx18_av_write(cx, 0x406, 0x13);
+ cx18_av_write(cx, 0x47f, state->slicer_line_delay);
+
+ /* Force impossible lines to 0 */
+ if (is_pal) {
+ for (i = 0; i <= 6; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ } else {
+ for (i = 0; i <= 9; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+
+ for (i = 22; i <= 23; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ }
- if (is_pal) {
- for (x = 1, i = 0x424; i <= 0x434; i++, x++)
- cx18_av_write(cx, i, lcr[6 + x]);
- } else {
- for (x = 1, i = 0x424; i <= 0x430; i++, x++)
- cx18_av_write(cx, i, lcr[9 + x]);
- for (i = 0x431; i <= 0x434; i++)
- cx18_av_write(cx, i, 0);
+ /* Build register values for requested service lines */
+ for (i = 7; i <= 23; i++) {
+ for (x = 0; x <= 1; x++) {
+ switch (svbi->service_lines[1-x][i]) {
+ case V4L2_SLICED_TELETEXT_B:
+ lcr[i] |= 1 << (4 * x);
+ break;
+ case V4L2_SLICED_WSS_625:
+ lcr[i] |= 4 << (4 * x);
+ break;
+ case V4L2_SLICED_CAPTION_525:
+ lcr[i] |= 6 << (4 * x);
+ break;
+ case V4L2_SLICED_VPS:
+ lcr[i] |= 9 << (4 * x);
+ break;
+ }
}
+ }
- cx18_av_write(cx, 0x43c, 0x16);
- cx18_av_write(cx, 0x474, is_pal ? 0x2a : 0x22);
- break;
+ if (is_pal) {
+ for (x = 1, i = 0x424; i <= 0x434; i++, x++)
+ cx18_av_write(cx, i, lcr[6 + x]);
+ } else {
+ for (x = 1, i = 0x424; i <= 0x430; i++, x++)
+ cx18_av_write(cx, i, lcr[9 + x]);
+ for (i = 0x431; i <= 0x434; i++)
+ cx18_av_write(cx, i, 0);
}
- case VIDIOC_INT_DECODE_VBI_LINE:
- {
- struct v4l2_decode_vbi_line *vbi = arg;
- u8 *p = vbi->p;
- int id1, id2, l, err = 0;
+ cx18_av_write(cx, 0x43c, 0x16);
+ /* FIXME - should match vblank set in cx18_av_std_setup() */
+ cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26);
+ return 0;
+}
+
+int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
+ struct v4l2_decode_vbi_line *vbi)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ struct cx18_av_state *state = &cx->av_state;
+ struct vbi_anc_data *anc = (struct vbi_anc_data *)vbi->p;
+ u8 *p;
+ int did, sdid, l, err = 0;
+
+ /*
+ * Check for the ancillary data header for sliced VBI
+ */
+ if (anc->preamble[0] ||
+ anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
+ (anc->did != sliced_vbi_did[0] &&
+ anc->did != sliced_vbi_did[1])) {
+ vbi->line = vbi->type = 0;
+ return 0;
+ }
- if (p[0] || p[1] != 0xff || p[2] != 0xff ||
- (p[3] != 0x55 && p[3] != 0x91)) {
- vbi->line = vbi->type = 0;
- break;
- }
+ did = anc->did;
+ sdid = anc->sdid & 0xf;
+ l = anc->idid[0] & 0x3f;
+ l += state->slicer_line_offset;
+ p = anc->payload;
- p += 4;
- id1 = p[-1];
- id2 = p[0] & 0xf;
- l = p[2] & 0x3f;
- l += state->vbi_line_offset;
- p += 4;
-
- switch (id2) {
- case 1:
- id2 = V4L2_SLICED_TELETEXT_B;
- break;
- case 4:
- id2 = V4L2_SLICED_WSS_625;
- break;
- case 6:
- id2 = V4L2_SLICED_CAPTION_525;
- err = !odd_parity(p[0]) || !odd_parity(p[1]);
- break;
- case 9:
- id2 = V4L2_SLICED_VPS;
- if (decode_vps(p, p) != 0)
- err = 1;
- break;
- default:
- id2 = 0;
+ /* Decode the SDID set by the slicer */
+ switch (sdid) {
+ case 1:
+ sdid = V4L2_SLICED_TELETEXT_B;
+ break;
+ case 4:
+ sdid = V4L2_SLICED_WSS_625;
+ break;
+ case 6:
+ sdid = V4L2_SLICED_CAPTION_525;
+ err = !odd_parity(p[0]) || !odd_parity(p[1]);
+ break;
+ case 9:
+ sdid = V4L2_SLICED_VPS;
+ if (decode_vps(p, p) != 0)
err = 1;
- break;
- }
-
- vbi->type = err ? 0 : id2;
- vbi->line = err ? 0 : l;
- vbi->is_second_field = err ? 0 : (id1 == 0x55);
- vbi->p = p;
break;
- }
+ default:
+ sdid = 0;
+ err = 1;
+ break;
}
+ vbi->type = err ? 0 : sdid;
+ vbi->line = err ? 0 : l;
+ vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
+ vbi->p = p;
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index e274043657dd..9bc221837847 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -51,12 +51,12 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = {
static const struct cx18_card cx18_card_hvr1600_esmt = {
.type = CX18_CARD_HVR_1600_ESMT,
.name = "Hauppauge HVR-1600",
- .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+ .comment = "Simultaneous Digital and Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
+ .hw_audio_ctrl = CX18_HW_418_AV,
.hw_muxer = CX18_HW_CS5345,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
- CX18_HW_CS5345 | CX18_HW_DVB,
+ .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
+ CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
{ CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
@@ -97,12 +97,12 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
static const struct cx18_card cx18_card_hvr1600_samsung = {
.type = CX18_CARD_HVR_1600_SAMSUNG,
.name = "Hauppauge HVR-1600 (Preproduction)",
- .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+ .comment = "Simultaneous Digital and Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
+ .hw_audio_ctrl = CX18_HW_418_AV,
.hw_muxer = CX18_HW_CS5345,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
- CX18_HW_CS5345 | CX18_HW_DVB,
+ .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
+ CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
{ CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
@@ -152,10 +152,10 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = {
static const struct cx18_card cx18_card_h900 = {
.type = CX18_CARD_COMPRO_H900,
.name = "Compro VideoMate H900",
- .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+ .comment = "Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
- .hw_all = CX18_HW_TUNER,
+ .hw_audio_ctrl = CX18_HW_418_AV,
+ .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
@@ -201,8 +201,8 @@ static const struct cx18_card cx18_card_mpc718 = {
.name = "Yuan MPC718",
.comment = "Analog video capture works; some audio line in may not.\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
- .hw_all = CX18_HW_TUNER,
+ .hw_audio_ctrl = CX18_HW_418_AV,
+ .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
@@ -249,11 +249,11 @@ static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = {
static const struct cx18_card cx18_card_cnxt_raptor_pal = {
.type = CX18_CARD_CNXT_RAPTOR_PAL,
.name = "Conexant Raptor PAL/SECAM",
- .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+ .comment = "Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
- .hw_muxer = CX18_HW_GPIO,
- .hw_all = CX18_HW_TUNER | CX18_HW_GPIO,
+ .hw_audio_ctrl = CX18_HW_418_AV,
+ .hw_muxer = CX18_HW_GPIO_MUX,
+ .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
@@ -306,8 +306,8 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
.comment = "Experimenters and photos needed for device to work well.\n"
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
- .hw_all = CX18_HW_TUNER,
+ .hw_audio_ctrl = CX18_HW_418_AV,
+ .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE6 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
@@ -339,19 +339,21 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
/* Leadtek WinFast PVR2100 */
static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 },
+ { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */
+ { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */
{ 0, 0, 0 }
};
static const struct cx18_card cx18_card_leadtek_pvr2100 = {
.type = CX18_CARD_LEADTEK_PVR2100,
- .name = "Leadtek WinFast PVR2100",
+ .name = "Leadtek WinFast PVR2100/DVR3100 H",
.comment = "Experimenters and photos needed for device to work well.\n"
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
- .hw_muxer = CX18_HW_GPIO,
- .hw_all = CX18_HW_TUNER | CX18_HW_GPIO,
+ .hw_audio_ctrl = CX18_HW_418_AV,
+ .hw_muxer = CX18_HW_GPIO_MUX,
+ .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
+ CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index 6fa7bcb42dde..3c552b6b7c4d 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -22,12 +22,13 @@
*/
/* hardware flags */
-#define CX18_HW_TUNER (1 << 0)
-#define CX18_HW_TVEEPROM (1 << 1)
-#define CX18_HW_CS5345 (1 << 2)
-#define CX18_HW_GPIO (1 << 3)
-#define CX18_HW_CX23418 (1 << 4)
-#define CX18_HW_DVB (1 << 5)
+#define CX18_HW_TUNER (1 << 0)
+#define CX18_HW_TVEEPROM (1 << 1)
+#define CX18_HW_CS5345 (1 << 2)
+#define CX18_HW_DVB (1 << 3)
+#define CX18_HW_418_AV (1 << 4)
+#define CX18_HW_GPIO_MUX (1 << 5)
+#define CX18_HW_GPIO_RESET_CTRL (1 << 6)
/* video inputs */
#define CX18_CARD_INPUT_VID_TUNER 1
@@ -49,8 +50,7 @@
/* V4L2 capability aliases */
#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \
- V4L2_CAP_VBI_CAPTURE)
-/* | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */
+ V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)
struct cx18_card_video_input {
u8 video_type; /* video input type */
@@ -122,7 +122,7 @@ struct cx18_card {
char *comment;
u32 v4l2_capabilities;
u32 hw_audio_ctrl; /* hardware used for the V4L2 controls (only
- 1 dev allowed) */
+ 1 dev allowed currently) */
u32 hw_muxer; /* hardware used to multiplex audio input */
u32 hw_all; /* all hardware used by the board */
struct cx18_card_video_input video_inputs[CX18_CARD_MAX_VIDEO_INPUTS];
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 17edf305d649..82fc2f9d4021 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -22,14 +22,13 @@
*/
#include "cx18-driver.h"
-#include "cx18-av-core.h"
#include "cx18-cards.h"
#include "cx18-ioctl.h"
#include "cx18-audio.h"
-#include "cx18-i2c.h"
#include "cx18-mailbox.h"
#include "cx18-controls.h"
+/* Must be sorted from low to high control ID! */
static const u32 user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
@@ -66,7 +65,7 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
case V4L2_CID_HUE:
case V4L2_CID_SATURATION:
case V4L2_CID_CONTRAST:
- if (cx18_av_cmd(cx, VIDIOC_QUERYCTRL, qctrl))
+ if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl))
qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
return 0;
@@ -76,7 +75,7 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_LOUDNESS:
- if (cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_QUERYCTRL, qctrl))
+ if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl))
qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
return 0;
@@ -125,7 +124,7 @@ static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
case V4L2_CID_HUE:
case V4L2_CID_SATURATION:
case V4L2_CID_CONTRAST:
- return cx18_av_cmd(cx, VIDIOC_S_CTRL, vctrl);
+ return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl);
case V4L2_CID_AUDIO_VOLUME:
case V4L2_CID_AUDIO_MUTE:
@@ -133,7 +132,7 @@ static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_LOUDNESS:
- return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl);
+ return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl);
default:
CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
@@ -150,7 +149,7 @@ static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
case V4L2_CID_HUE:
case V4L2_CID_SATURATION:
case V4L2_CID_CONTRAST:
- return cx18_av_cmd(cx, VIDIOC_G_CTRL, vctrl);
+ return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl);
case V4L2_CID_AUDIO_VOLUME:
case V4L2_CID_AUDIO_MUTE:
@@ -158,7 +157,8 @@ static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_LOUDNESS:
- return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl);
+ return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl);
+
default:
CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
return -EINVAL;
@@ -166,38 +166,57 @@ static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
return 0;
}
-static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt)
+static int cx18_setup_vbi_fmt(struct cx18 *cx,
+ enum v4l2_mpeg_stream_vbi_fmt fmt,
+ enum v4l2_mpeg_stream_type type)
{
if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE))
return -EINVAL;
if (atomic_read(&cx->ana_capturing) > 0)
return -EBUSY;
- /* First try to allocate sliced VBI buffers if needed. */
- if (fmt && cx->vbi.sliced_mpeg_data[0] == NULL) {
+ if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV ||
+ type != V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
+ /* We don't do VBI insertion aside from IVTV format in a PS */
+ cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE;
+ CX18_DEBUG_INFO("disabled insertion of sliced VBI data into "
+ "the MPEG stream\n");
+ return 0;
+ }
+
+ /* Allocate sliced VBI buffers if needed. */
+ if (cx->vbi.sliced_mpeg_data[0] == NULL) {
int i;
for (i = 0; i < CX18_VBI_FRAMES; i++) {
- /* Yuck, hardcoded. Needs to be a define */
- cx->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL);
+ cx->vbi.sliced_mpeg_data[i] =
+ kmalloc(CX18_SLICED_MPEG_DATA_BUFSZ, GFP_KERNEL);
if (cx->vbi.sliced_mpeg_data[i] == NULL) {
while (--i >= 0) {
kfree(cx->vbi.sliced_mpeg_data[i]);
cx->vbi.sliced_mpeg_data[i] = NULL;
}
+ cx->vbi.insert_mpeg =
+ V4L2_MPEG_STREAM_VBI_FMT_NONE;
+ CX18_WARN("Unable to allocate buffers for "
+ "sliced VBI data insertion\n");
return -ENOMEM;
}
}
}
cx->vbi.insert_mpeg = fmt;
+ CX18_DEBUG_INFO("enabled insertion of sliced VBI data into the MPEG PS,"
+ "when sliced VBI is enabled\n");
- if (cx->vbi.insert_mpeg == 0)
- return 0;
- /* Need sliced data for mpeg insertion */
+ /*
+ * If our current settings have no lines set for capture, store a valid,
+ * default set of service lines to capture, in our current settings.
+ */
if (cx18_get_service_set(cx->vbi.sliced_in) == 0) {
if (cx->is_60hz)
- cx->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525;
+ cx->vbi.sliced_in->service_set =
+ V4L2_SLICED_CAPTION_525;
else
cx->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
cx18_expand_service_set(cx->vbi.sliced_in, cx->is_50hz);
@@ -259,10 +278,12 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
return err;
}
if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+ static u32 freqs[3] = { 44100, 48000, 32000 };
struct cx18_api_func_private priv;
struct cx2341x_mpeg_params p = cx->params;
int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing),
c, VIDIOC_S_EXT_CTRLS);
+ unsigned int idx;
if (err)
return err;
@@ -277,16 +298,23 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
fmt.fmt.pix.width = cx->params.width
/ (is_mpeg1 ? 2 : 1);
fmt.fmt.pix.height = cx->params.height;
- cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt);
+ v4l2_subdev_call(cx->sd_av, video, s_fmt, &fmt);
}
priv.cx = cx;
priv.s = &cx->streams[id->type];
err = cx2341x_update(&priv, cx18_api_func, &cx->params, &p);
- if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt)
- err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt);
+ if (!err &&
+ (cx->params.stream_vbi_fmt != p.stream_vbi_fmt ||
+ cx->params.stream_type != p.stream_type))
+ err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt,
+ p.stream_type);
cx->params = p;
cx->dualwatch_stereo_mode = p.audio_properties & 0x0300;
- cx18_audio_set_audio_clock_freq(cx, p.audio_properties & 0x03);
+ idx = p.audio_properties & 0x03;
+ /* The audio clock of the digitizer must match the codec sample
+ rate otherwise you get some very strange effects. */
+ if (idx < sizeof(freqs))
+ cx18_call_all(cx, audio, s_clock_freq, freqs[idx]);
return err;
}
return -EINVAL;
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index f50cf2167adc..210c68aaae00 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -39,10 +39,6 @@
#include <media/tveeprom.h>
-
-/* var to keep track of the number of array elements in use */
-int cx18_cards_active;
-
/* If you have already X v4l cards, then set this to X. This way
the device numbers stay matched. Example: you have a WinTV card
without radio and a Compro H900 with. Normally this would give a
@@ -50,12 +46,6 @@ int cx18_cards_active;
setting this to 1 you ensure that radio0 is now also radio1. */
int cx18_first_minor;
-/* Master variable for all cx18 info */
-struct cx18 *cx18_cards[CX18_MAX_CARDS];
-
-/* Protects cx18_cards_active */
-DEFINE_SPINLOCK(cx18_cards_lock);
-
/* add your revision and whatnot here */
static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
{PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
@@ -65,6 +55,8 @@ static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, cx18_pci_tbl);
+static atomic_t cx18_instance = ATOMIC_INIT(0);
+
/* Parameter declarations */
static int cardtype[CX18_MAX_CARDS];
static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
@@ -159,7 +151,7 @@ MODULE_PARM_DESC(cardtype,
"\t\t\t 4 = Yuan MPC718\n"
"\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
"\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
- "\t\t\t 7 = Leadtek WinFast PVR2100\n"
+ "\t\t\t 7 = Leadtek WinFast PVR2100/DVR3100 H\n"
"\t\t\t 0 = Autodetect (default)\n"
"\t\t\t-1 = Ignore this card\n\t\t");
MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
@@ -277,11 +269,16 @@ static void cx18_iounmap(struct cx18 *cx)
/* Hauppauge card? get values from tveeprom */
void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
{
+ struct i2c_client c;
u8 eedata[256];
- cx->i2c_client[0].addr = 0xA0 >> 1;
- tveeprom_read(&cx->i2c_client[0], eedata, sizeof(eedata));
- tveeprom_hauppauge_analog(&cx->i2c_client[0], tv, eedata);
+ memset(&c, 0, sizeof(c));
+ strlcpy(c.name, "cx18 tveeprom tmp", sizeof(c.name));
+ c.adapter = &cx->i2c_adap[0];
+ c.addr = 0xA0 >> 1;
+
+ tveeprom_read(&c, eedata, sizeof(eedata));
+ tveeprom_hauppauge_analog(&c, tv, eedata);
}
static void cx18_process_eeprom(struct cx18 *cx)
@@ -448,34 +445,38 @@ static void cx18_process_options(struct cx18 *cx)
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = 0; /* computed later */
+ cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_active_samples * 36;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */
- /* Except for VBI ensure stream_buffers & stream_buf_size are valid */
+ /* Ensure stream_buffers & stream_buf_size are valid */
for (i = 0; i < CX18_MAX_STREAMS; i++) {
- /* User said to use 0 buffers */
- if (cx->stream_buffers[i] == 0) {
- cx->options.megabytes[i] = 0;
- cx->stream_buf_size[i] = 0;
- continue;
- }
- /* User said to use 0 MB total */
- if (cx->options.megabytes[i] <= 0) {
+ if (cx->stream_buffers[i] == 0 || /* User said 0 buffers */
+ cx->options.megabytes[i] <= 0 || /* User said 0 MB total */
+ cx->stream_buf_size[i] <= 0) { /* User said buf size 0 */
cx->options.megabytes[i] = 0;
cx->stream_buffers[i] = 0;
cx->stream_buf_size[i] = 0;
continue;
}
- /* VBI is computed later or user said buffer has size 0 */
- if (cx->stream_buf_size[i] <= 0) {
- if (i != CX18_ENC_STREAM_TYPE_VBI) {
- cx->options.megabytes[i] = 0;
- cx->stream_buffers[i] = 0;
- cx->stream_buf_size[i] = 0;
+ /*
+ * VBI is a special case where the stream_buf_size is fixed
+ * and already in bytes
+ */
+ if (i == CX18_ENC_STREAM_TYPE_VBI) {
+ if (cx->stream_buffers[i] < 0) {
+ cx->stream_buffers[i] =
+ cx->options.megabytes[i] * 1024 * 1024
+ / cx->stream_buf_size[i];
+ } else {
+ /* N.B. This might round down to 0 */
+ cx->options.megabytes[i] =
+ cx->stream_buffers[i]
+ * cx->stream_buf_size[i]/(1024 * 1024);
}
continue;
}
+ /* All other streams have stream_buf_size in kB at this point */
if (cx->stream_buffers[i] < 0) {
cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
/ cx->stream_buf_size[i];
@@ -487,9 +488,9 @@ static void cx18_process_options(struct cx18 *cx)
cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */
}
- cx->options.cardtype = cardtype[cx->num];
- cx->options.tuner = tuner[cx->num];
- cx->options.radio = radio[cx->num];
+ cx->options.cardtype = cardtype[cx->instance];
+ cx->options.tuner = tuner[cx->instance];
+ cx->options.radio = radio[cx->instance];
cx->std = cx18_parse_std(cx);
if (cx->options.cardtype == -1) {
@@ -502,7 +503,7 @@ static void cx18_process_options(struct cx18 *cx)
else if (cx->options.cardtype != 0)
CX18_ERR("Unknown user specified type, trying to autodetect card\n");
if (cx->card == NULL) {
- if (cx->dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
+ if (cx->pci_dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
CX18_INFO("Autodetected Hauppauge card\n");
}
@@ -512,13 +513,13 @@ static void cx18_process_options(struct cx18 *cx)
if (cx->card->pci_list == NULL)
continue;
for (j = 0; cx->card->pci_list[j].device; j++) {
- if (cx->dev->device !=
+ if (cx->pci_dev->device !=
cx->card->pci_list[j].device)
continue;
- if (cx->dev->subsystem_vendor !=
+ if (cx->pci_dev->subsystem_vendor !=
cx->card->pci_list[j].subsystem_vendor)
continue;
- if (cx->dev->subsystem_device !=
+ if (cx->pci_dev->subsystem_device !=
cx->card->pci_list[j].subsystem_device)
continue;
CX18_INFO("Autodetected %s card\n", cx->card->name);
@@ -531,9 +532,10 @@ done:
if (cx->card == NULL) {
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
- cx->dev->vendor, cx->dev->device);
+ cx->pci_dev->vendor, cx->pci_dev->device);
CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n",
- cx->dev->subsystem_vendor, cx->dev->subsystem_device);
+ cx->pci_dev->subsystem_vendor,
+ cx->pci_dev->subsystem_device);
CX18_ERR("Defaulting to %s card\n", cx->card->name);
CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
@@ -545,7 +547,7 @@ done:
}
/* Precondition: the cx18 structure has been memset to 0. Only
- the dev and num fields have been filled in.
+ the dev and instance fields have been filled in.
No assumptions on the card type may be made here (see cx18_init_struct2
for that).
*/
@@ -553,18 +555,14 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
{
int i;
- cx->base_addr = pci_resource_start(cx->dev, 0);
+ cx->base_addr = pci_resource_start(cx->pci_dev, 0);
mutex_init(&cx->serialize_lock);
- mutex_init(&cx->i2c_bus_lock[0]);
- mutex_init(&cx->i2c_bus_lock[1]);
mutex_init(&cx->gpio_lock);
mutex_init(&cx->epu2apu_mb_lock);
mutex_init(&cx->epu2cpu_mb_lock);
- spin_lock_init(&cx->lock);
-
- cx->work_queue = create_singlethread_workqueue(cx->name);
+ cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name);
if (cx->work_queue == NULL) {
CX18_ERR("Unable to create work hander thread\n");
return -ENOMEM;
@@ -587,7 +585,8 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
(cx->params.video_temporal_filter_mode << 1) |
(cx->params.video_median_filter_type << 2);
cx->params.port = CX2341X_PORT_MEMORY;
- cx->params.capabilities = CX2341X_CAP_HAS_TS;
+ cx->params.capabilities =
+ CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_SLICED_VBI;
init_waitqueue_head(&cx->cap_w);
init_waitqueue_head(&cx->mb_apu_waitq);
init_waitqueue_head(&cx->mb_cpu_waitq);
@@ -597,49 +596,6 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
- /*
- * The VBI line sizes depend on the pixel clock and the horiz rate
- *
- * (1/Fh)*(2*Fp) = Samples/line
- * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
- *
- * Sliced VBI is sent as ancillary data during horizontal blanking
- * Raw VBI is sent as active video samples during vertcal blanking
- *
- * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
- * length of 720 pixels @ 4:2:2 sampling. Thus...
- *
- * For systems that use a 15.734 kHz horizontal rate, such as
- * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
- *
- * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
- * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
- *
- * For systems that use a 15.625 kHz horizontal rate, such as
- * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
- *
- * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
- * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
- *
- */
-
- /* FIXME: init these based on tuner std & modify when std changes */
- /* CX18-AV-Core number of VBI samples output per horizontal line */
- cx->vbi.raw_decoder_line_size = 1444; /* 4 byte SAV + 2 * 720 */
- cx->vbi.sliced_decoder_line_size = 272; /* 60 Hz: 268+4, 50 Hz: 280+4 */
-
- /* CX18-AV-Core VBI samples/line possibly rounded up */
- cx->vbi.raw_size = 1444; /* Real max size is 1444 */
- cx->vbi.sliced_size = 284; /* Real max size is 284 */
-
- /*
- * CX18-AV-Core SAV/EAV RP codes in VIP 1.x mode
- * Task Field VerticalBlank HorizontalBlank 0 0 0 0
- */
- cx->vbi.raw_decoder_sav_odd_field = 0x20; /* V */
- cx->vbi.raw_decoder_sav_even_field = 0x60; /* FV */
- cx->vbi.sliced_decoder_sav_odd_field = 0xB0; /* T VH - actually EAV */
- cx->vbi.sliced_decoder_sav_even_field = 0xF0; /* TFVH - actually EAV */
return 0;
}
@@ -668,15 +624,9 @@ static void __devinit cx18_init_struct2(struct cx18 *cx)
i = 0;
cx->active_input = i;
cx->audio_input = cx->card->video_inputs[i].audio_index;
- cx->av_state.vid_input = CX18_AV_COMPOSITE7;
- cx->av_state.aud_input = CX18_AV_AUDIO8;
- cx->av_state.audclk_freq = 48000;
- cx->av_state.audmode = V4L2_TUNER_MODE_LANG1;
- /* FIXME - 8 is NTSC value, investigate */
- cx->av_state.vbi_line_offset = 8;
}
-static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
+static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
u16 cmd;
@@ -684,124 +634,125 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
CX18_DEBUG_INFO("Enabling pci device\n");
- if (pci_enable_device(dev)) {
- CX18_ERR("Can't enable device %d!\n", cx->num);
+ if (pci_enable_device(pci_dev)) {
+ CX18_ERR("Can't enable device %d!\n", cx->instance);
return -EIO;
}
- if (pci_set_dma_mask(dev, 0xffffffff)) {
- CX18_ERR("No suitable DMA available on card %d.\n", cx->num);
+ if (pci_set_dma_mask(pci_dev, 0xffffffff)) {
+ CX18_ERR("No suitable DMA available, card %d\n", cx->instance);
return -EIO;
}
if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) {
- CX18_ERR("Cannot request encoder memory region on card %d.\n", cx->num);
+ CX18_ERR("Cannot request encoder memory region, card %d\n",
+ cx->instance);
return -EIO;
}
/* Enable bus mastering and memory mapped IO for the CX23418 */
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_read_config_word(pci_dev, PCI_COMMAND, &cmd);
cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
+ pci_write_config_word(pci_dev, PCI_COMMAND, cmd);
- pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev);
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+ pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &cx->card_rev);
+ pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
if (pci_latency < 64 && cx18_pci_latency) {
CX18_INFO("Unreasonably low latency timer, "
"setting to 64 (was %d)\n", pci_latency);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+ pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, 64);
+ pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
}
CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, "
"irq: %d, latency: %d, memory: 0x%lx\n",
- cx->dev->device, cx->card_rev, dev->bus->number,
- PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
- cx->dev->irq, pci_latency, (unsigned long)cx->base_addr);
+ cx->pci_dev->device, cx->card_rev, pci_dev->bus->number,
+ PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn),
+ cx->pci_dev->irq, pci_latency, (unsigned long)cx->base_addr);
return 0;
}
-#ifdef MODULE
-static u32 cx18_request_module(struct cx18 *cx, u32 hw,
- const char *name, u32 id)
-{
- if ((hw & id) == 0)
- return hw;
- if (request_module(name) != 0) {
- CX18_ERR("Failed to load module %s\n", name);
- return hw & ~id;
- }
- CX18_DEBUG_INFO("Loaded module %s\n", name);
- return hw;
-}
-#endif
-
-static void cx18_load_and_init_modules(struct cx18 *cx)
+static void cx18_init_subdevs(struct cx18 *cx)
{
u32 hw = cx->card->hw_all;
+ u32 device;
int i;
-#ifdef MODULE
- /* load modules */
-#ifdef CONFIG_MEDIA_TUNER_MODULE
- hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
-#endif
-#ifdef CONFIG_VIDEO_CS5345_MODULE
- hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
-#endif
-#endif
-
- /* check which i2c devices are actually found */
- for (i = 0; i < 32; i++) {
- u32 device = 1 << i;
+ for (i = 0, device = 1; i < 32; i++, device <<= 1) {
if (!(device & hw))
continue;
- if (device == CX18_HW_GPIO || device == CX18_HW_TVEEPROM ||
- device == CX18_HW_CX23418 || device == CX18_HW_DVB) {
- /* These 'devices' do not use i2c probing */
+
+ switch (device) {
+ case CX18_HW_DVB:
+ case CX18_HW_TVEEPROM:
+ /* These subordinate devices do not use probing */
cx->hw_flags |= device;
- continue;
- }
- cx18_i2c_register(cx, i);
- if (cx18_i2c_hw_addr(cx, device) > 0)
+ break;
+ case CX18_HW_418_AV:
+ /* The A/V decoder gets probed earlier to set PLLs */
+ /* Just note that the card uses it (i.e. has analog) */
cx->hw_flags |= device;
+ break;
+ case CX18_HW_GPIO_RESET_CTRL:
+ /*
+ * The Reset Controller gets probed and added to
+ * hw_flags earlier for i2c adapter/bus initialization
+ */
+ break;
+ case CX18_HW_GPIO_MUX:
+ if (cx18_gpio_register(cx, device) == 0)
+ cx->hw_flags |= device;
+ break;
+ default:
+ if (cx18_i2c_register(cx, i) == 0)
+ cx->hw_flags |= device;
+ break;
+ }
}
- hw = cx->hw_flags;
+ if (cx->hw_flags & CX18_HW_418_AV)
+ cx->sd_av = cx18_find_hw(cx, CX18_HW_418_AV);
+
+ if (cx->card->hw_muxer != 0)
+ cx->sd_extmux = cx18_find_hw(cx, cx->card->hw_muxer);
}
-static int __devinit cx18_probe(struct pci_dev *dev,
+static int __devinit cx18_probe(struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
int retval = 0;
int i;
- int vbi_buf_size;
u32 devtype;
struct cx18 *cx;
- spin_lock(&cx18_cards_lock);
-
- /* Make sure we've got a place for this card */
- if (cx18_cards_active == CX18_MAX_CARDS) {
- printk(KERN_ERR "cx18: Maximum number of cards detected (%d).\n",
- cx18_cards_active);
- spin_unlock(&cx18_cards_lock);
+ /* FIXME - module parameter arrays constrain max instances */
+ i = atomic_inc_return(&cx18_instance) - 1;
+ if (i >= CX18_MAX_CARDS) {
+ printk(KERN_ERR "cx18: cannot manage card %d, driver has a "
+ "limit of 0 - %d\n", i, CX18_MAX_CARDS - 1);
return -ENOMEM;
}
cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
- if (!cx) {
- spin_unlock(&cx18_cards_lock);
+ if (cx == NULL) {
+ printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n",
+ i);
return -ENOMEM;
}
- cx18_cards[cx18_cards_active] = cx;
- cx->dev = dev;
- cx->num = cx18_cards_active++;
- snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num);
- CX18_INFO("Initializing card #%d\n", cx->num);
+ cx->pci_dev = pci_dev;
+ cx->instance = i;
- spin_unlock(&cx18_cards_lock);
+ retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev);
+ if (retval) {
+ printk(KERN_ERR "cx18: v4l2_device_register of card %d failed"
+ "\n", cx->instance);
+ kfree(cx);
+ return retval;
+ }
+ snprintf(cx->v4l2_dev.name, sizeof(cx->v4l2_dev.name), "cx18-%d",
+ cx->instance);
+ CX18_INFO("Initializing card %d\n", cx->instance);
cx18_process_options(cx);
if (cx->options.cardtype == -1) {
@@ -816,13 +767,10 @@ static int __devinit cx18_probe(struct pci_dev *dev,
CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
/* PCI Device Setup */
- retval = cx18_setup_pci(cx, dev, pci_id);
+ retval = cx18_setup_pci(cx, pci_dev, pci_id);
if (retval != 0)
goto free_workqueue;
- /* save cx in the pci struct for later use */
- pci_set_drvdata(dev, cx);
-
/* map io memory */
CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE);
@@ -856,6 +804,23 @@ static int __devinit cx18_probe(struct pci_dev *dev,
cx18_gpio_init(cx);
+ /* Initialize integrated A/V decoder early to set PLLs, just in case */
+ retval = cx18_av_probe(cx);
+ if (retval) {
+ CX18_ERR("Could not register A/V decoder subdevice\n");
+ goto free_map;
+ }
+ cx18_call_hw(cx, CX18_HW_418_AV, core, init, (u32) CX18_AV_INIT_PLLS);
+
+ /* Initialize GPIO Reset Controller to do chip resets during i2c init */
+ if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) {
+ if (cx18_gpio_register(cx, CX18_HW_GPIO_RESET_CTRL) != 0)
+ CX18_WARN("Could not register GPIO reset controller"
+ "subdevice; proceeding anyway.\n");
+ else
+ cx->hw_flags |= CX18_HW_GPIO_RESET_CTRL;
+ }
+
/* active i2c */
CX18_DEBUG_INFO("activating i2c...\n");
retval = init_cx18_i2c(cx);
@@ -864,8 +829,6 @@ static int __devinit cx18_probe(struct pci_dev *dev,
goto free_map;
}
- CX18_DEBUG_INFO("Active card count: %d.\n", cx18_cards_active);
-
if (cx->card->hw_all & CX18_HW_TVEEPROM) {
/* Based on the model number the cardtype may be changed.
The PCI IDs are not always reliable. */
@@ -881,8 +844,9 @@ static int __devinit cx18_probe(struct pci_dev *dev,
cx18_init_scb(cx);
/* Register IRQ */
- retval = request_irq(cx->dev->irq, cx18_irq_handler,
- IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx);
+ retval = request_irq(cx->pci_dev->irq, cx18_irq_handler,
+ IRQF_SHARED | IRQF_DISABLED,
+ cx->v4l2_dev.name, (void *)cx);
if (retval) {
CX18_ERR("Failed to register irq %d\n", retval);
goto free_i2c;
@@ -917,33 +881,14 @@ static int __devinit cx18_probe(struct pci_dev *dev,
initialization. */
cx18_init_struct2(cx);
- cx18_load_and_init_modules(cx);
+ cx18_init_subdevs(cx);
- if (cx->std & V4L2_STD_525_60) {
+ if (cx->std & V4L2_STD_525_60)
cx->is_60hz = 1;
- cx->is_out_60hz = 1;
- } else {
+ else
cx->is_50hz = 1;
- cx->is_out_50hz = 1;
- }
- cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
-
- /*
- * FIXME: setting the buffer size based on the tuner standard is
- * suboptimal, as the CVBS and SVideo inputs could use a different std
- * and the buffer could end up being too small in that case.
- */
- vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
- if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0)
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] =
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] * 1024 * 1024
- / vbi_buf_size;
- else
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] =
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] * vbi_buf_size
- / (1024 * 1024);
+ cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
if (cx->options.radio > 0)
cx->v4l2_cap |= V4L2_CAP_RADIO;
@@ -956,7 +901,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
setup.tuner_callback = (setup.type == TUNER_XC2028) ?
cx18_reset_tuner_gpio : NULL;
- cx18_call_i2c_clients(cx, TUNER_SET_TYPE_ADDR, &setup);
+ cx18_call_all(cx, tuner, s_type_addr, &setup);
if (setup.type == TUNER_XC2028) {
static struct xc2028_ctrl ctrl = {
.fname = XC2028_DEFAULT_FIRMWARE,
@@ -966,7 +911,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
.tuner = cx->options.tuner,
.priv = &ctrl,
};
- cx18_call_i2c_clients(cx, TUNER_SET_CONFIG, &cfg);
+ cx18_call_all(cx, tuner, s_config, &cfg);
}
}
@@ -985,14 +930,13 @@ static int __devinit cx18_probe(struct pci_dev *dev,
goto free_streams;
}
- CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name);
-
+ CX18_INFO("Initialized card: %s\n", cx->card_name);
return 0;
free_streams:
cx18_streams_cleanup(cx, 1);
free_irq:
- free_irq(cx->dev->irq, (void *)cx);
+ free_irq(cx->pci_dev->irq, (void *)cx);
free_i2c:
exit_cx18_i2c(cx);
free_map:
@@ -1006,11 +950,8 @@ err:
retval = -ENODEV;
CX18_ERR("Error %d on initialization\n", retval);
- i = cx->num;
- spin_lock(&cx18_cards_lock);
- kfree(cx18_cards[i]);
- cx18_cards[i] = NULL;
- spin_unlock(&cx18_cards_lock);
+ v4l2_device_unregister(&cx->v4l2_dev);
+ kfree(cx);
return retval;
}
@@ -1043,8 +984,21 @@ int cx18_init_on_first_open(struct cx18 *cx)
}
set_bit(CX18_F_I_LOADED_FW, &cx->i_flags);
- /* Init the firmware twice to work around a silicon bug
- * transport related. */
+ /*
+ * Init the firmware twice to work around a silicon bug
+ * with the digital TS.
+ *
+ * The second firmware load requires us to normalize the APU state,
+ * or the audio for the first analog capture will be badly incorrect.
+ *
+ * I can't seem to call APU_RESETAI and have it succeed without the
+ * APU capturing audio, so we start and stop it here to do the reset
+ */
+
+ /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
+ cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
+ cx18_vapi(cx, CX18_APU_RESETAI, 0);
+ cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
fw_retry_count = 3;
while (--fw_retry_count > 0) {
@@ -1060,6 +1014,22 @@ int cx18_init_on_first_open(struct cx18 *cx)
return -ENXIO;
}
+ /*
+ * The second firmware load requires us to normalize the APU state,
+ * or the audio for the first analog capture will be badly incorrect.
+ *
+ * I can't seem to call APU_RESETAI and have it succeed without the
+ * APU capturing audio, so we start and stop it here to do the reset
+ */
+
+ /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
+ cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
+ cx18_vapi(cx, CX18_APU_RESETAI, 0);
+ cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
+
+ /* Init the A/V decoder, if it hasn't been already */
+ v4l2_subdev_call(cx->sd_av, core, init, (u32) CX18_AV_INIT_NORMAL);
+
vf.tuner = 0;
vf.type = V4L2_TUNER_ANALOG_TV;
vf.frequency = 6400; /* the tuner 'baseline' frequency */
@@ -1092,9 +1062,11 @@ static void cx18_cancel_epu_work_orders(struct cx18 *cx)
static void cx18_remove(struct pci_dev *pci_dev)
{
- struct cx18 *cx = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct cx18 *cx = to_cx18(v4l2_dev);
+ int i;
- CX18_DEBUG_INFO("Removing Card #%d\n", cx->num);
+ CX18_DEBUG_INFO("Removing Card\n");
/* Stop all captures */
CX18_DEBUG_INFO("Stopping all streams\n");
@@ -1115,15 +1087,22 @@ static void cx18_remove(struct pci_dev *pci_dev)
exit_cx18_i2c(cx);
- free_irq(cx->dev->irq, (void *)cx);
+ free_irq(cx->pci_dev->irq, (void *)cx);
cx18_iounmap(cx);
release_mem_region(cx->base_addr, CX18_MEM_SIZE);
- pci_disable_device(cx->dev);
+ pci_disable_device(cx->pci_dev);
+
+ if (cx->vbi.sliced_mpeg_data[0] != NULL)
+ for (i = 0; i < CX18_VBI_FRAMES; i++)
+ kfree(cx->vbi.sliced_mpeg_data[i]);
+
+ CX18_INFO("Removed %s\n", cx->card_name);
- CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num);
+ v4l2_device_unregister(v4l2_dev);
+ kfree(cx);
}
/* define a pci_driver for card detection */
@@ -1138,8 +1117,6 @@ static int module_start(void)
{
printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION);
- memset(cx18_cards, 0, sizeof(cx18_cards));
-
/* Validate parameters */
if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n",
@@ -1162,16 +1139,7 @@ static int module_start(void)
static void module_cleanup(void)
{
- int i;
-
pci_unregister_driver(&cx18_pci_driver);
-
- for (i = 0; i < cx18_cards_active; i++) {
- if (cx18_cards[i] == NULL)
- continue;
- kfree(cx18_cards[i]);
- }
-
}
module_init(module_start);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 0d2edebc39b4..ece4f281ef42 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -48,6 +48,7 @@
#include <linux/dvb/audio.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
#include <media/tuner.h>
#include "cx18-mailbox.h"
#include "cx18-av-core.h"
@@ -79,7 +80,7 @@
#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */
#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
-#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */
+#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100/DVR3100 H */
#define CX18_CARD_LAST 6
#define CX18_ENC_STREAM_TYPE_MPG 0
@@ -143,12 +144,12 @@
/* Flag to turn on high volume debugging */
#define CX18_DBGFLG_HIGHVOL (1 << 8)
-/* NOTE: extra space before comma in 'cx->num , ## args' is required for
+/* NOTE: extra space before comma in 'fmt , ## args' is required for
gcc-2.95, otherwise it won't compile. */
#define CX18_DEBUG(x, type, fmt, args...) \
do { \
if ((x) & cx18_debug) \
- printk(KERN_INFO "cx18-%d " type ": " fmt, cx->num , ## args); \
+ v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
} while (0)
#define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args)
#define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args)
@@ -162,7 +163,7 @@
#define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \
do { \
if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
- printk(KERN_INFO "cx18%d " type ": " fmt, cx->num , ## args); \
+ v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
} while (0)
#define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args)
#define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args)
@@ -174,9 +175,58 @@
#define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
/* Standard kernel messages */
-#define CX18_ERR(fmt, args...) printk(KERN_ERR "cx18-%d: " fmt, cx->num , ## args)
-#define CX18_WARN(fmt, args...) printk(KERN_WARNING "cx18-%d: " fmt, cx->num , ## args)
-#define CX18_INFO(fmt, args...) printk(KERN_INFO "cx18-%d: " fmt, cx->num , ## args)
+#define CX18_ERR(fmt, args...) v4l2_err(&cx->v4l2_dev, fmt , ## args)
+#define CX18_WARN(fmt, args...) v4l2_warn(&cx->v4l2_dev, fmt , ## args)
+#define CX18_INFO(fmt, args...) v4l2_info(&cx->v4l2_dev, fmt , ## args)
+
+/* Messages for internal subdevs to use */
+#define CX18_DEBUG_DEV(x, dev, type, fmt, args...) \
+ do { \
+ if ((x) & cx18_debug) \
+ v4l2_info(dev, " " type ": " fmt , ## args); \
+ } while (0)
+#define CX18_DEBUG_WARN_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
+#define CX18_DEBUG_INFO_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
+#define CX18_DEBUG_API_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
+#define CX18_DEBUG_DMA_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
+#define CX18_DEBUG_IOCTL_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
+#define CX18_DEBUG_FILE_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
+#define CX18_DEBUG_I2C_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
+#define CX18_DEBUG_IRQ_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
+
+#define CX18_DEBUG_HIGH_VOL_DEV(x, dev, type, fmt, args...) \
+ do { \
+ if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
+ v4l2_info(dev, " " type ": " fmt , ## args); \
+ } while (0)
+#define CX18_DEBUG_HI_WARN_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
+#define CX18_DEBUG_HI_INFO_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
+#define CX18_DEBUG_HI_API_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
+#define CX18_DEBUG_HI_DMA_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
+#define CX18_DEBUG_HI_IOCTL_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
+#define CX18_DEBUG_HI_FILE_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
+#define CX18_DEBUG_HI_I2C_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
+#define CX18_DEBUG_HI_IRQ_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
+
+#define CX18_ERR_DEV(dev, fmt, args...) v4l2_err(dev, fmt , ## args)
+#define CX18_WARN_DEV(dev, fmt, args...) v4l2_warn(dev, fmt , ## args)
+#define CX18_INFO_DEV(dev, fmt, args...) v4l2_info(dev, fmt , ## args)
/* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
#define MPEG_FRAME_TYPE_IFRAME 1
@@ -279,7 +329,7 @@ struct cx18_epu_work_order {
struct cx18_stream {
/* These first four fields are always set, even if the stream
is not actually created. */
- struct video_device *v4l2dev; /* NULL when stream not created */
+ struct video_device *video_dev; /* NULL when stream not created */
struct cx18 *cx; /* for ease of use */
const char *name; /* name of the stream */
int type; /* stream type */
@@ -292,7 +342,6 @@ struct cx18_stream {
int dma; /* can be PCI_DMA_TODEVICE,
PCI_DMA_FROMDEVICE or
PCI_DMA_NONE */
- u64 dma_pts;
wait_queue_head_t waitq;
/* Buffer Stats */
@@ -318,59 +367,121 @@ struct cx18_open_id {
/* forward declaration of struct defined in cx18-cards.h */
struct cx18_card;
+/*
+ * A note about "sliced" VBI data as implemented in this driver:
+ *
+ * Currently we collect the sliced VBI in the form of Ancillary Data
+ * packets, inserted by the AV core decoder/digitizer/slicer in the
+ * horizontal blanking region of the VBI lines, in "raw" mode as far as
+ * the Encoder is concerned. We don't ever tell the Encoder itself
+ * to provide sliced VBI. (AV Core: sliced mode - Encoder: raw mode)
+ *
+ * We then process the ancillary data ourselves to send the sliced data
+ * to the user application directly or build up MPEG-2 private stream 1
+ * packets to splice into (only!) MPEG-2 PS streams for the user app.
+ *
+ * (That's how ivtv essentially does it.)
+ *
+ * The Encoder should be able to extract certain sliced VBI data for
+ * us and provide it in a separate stream or splice it into any type of
+ * MPEG PS or TS stream, but this isn't implemented yet.
+ */
+
+/*
+ * Number of "raw" VBI samples per horizontal line we tell the Encoder to
+ * grab from the decoder/digitizer/slicer output for raw or sliced VBI.
+ * It depends on the pixel clock and the horiz rate:
+ *
+ * (1/Fh)*(2*Fp) = Samples/line
+ * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
+ *
+ * Sliced VBI data is sent as ancillary data during horizontal blanking
+ * Raw VBI is sent as active video samples during vertcal blanking
+ *
+ * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
+ * length of 720 pixels @ 4:2:2 sampling. Thus...
+ *
+ * For systems that use a 15.734 kHz horizontal rate, such as
+ * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
+ *
+ * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
+ * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
+ *
+ * For systems that use a 15.625 kHz horizontal rate, such as
+ * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
+ *
+ * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
+ * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
+ */
+static const u32 vbi_active_samples = 1444; /* 4 byte SAV + 720 Y + 720 U/V */
+static const u32 vbi_hblank_samples_60Hz = 272; /* 4 byte EAV + 268 anc/fill */
+static const u32 vbi_hblank_samples_50Hz = 284; /* 4 byte EAV + 280 anc/fill */
#define CX18_VBI_FRAMES 32
-/* VBI data */
struct vbi_info {
- u32 enc_size;
- u32 frame;
- u8 cc_data_odd[256];
- u8 cc_data_even[256];
- int cc_pos;
- u8 cc_no_update;
- u8 vps[5];
- u8 vps_found;
- int wss;
- u8 wss_found;
- u8 wss_no_update;
- u32 raw_decoder_line_size;
- u8 raw_decoder_sav_odd_field;
- u8 raw_decoder_sav_even_field;
- u32 sliced_decoder_line_size;
- u8 sliced_decoder_sav_odd_field;
- u8 sliced_decoder_sav_even_field;
+ /* Current state of v4l2 VBI settings for this device */
struct v4l2_format in;
- /* convenience pointer to sliced struct in vbi_in union */
- struct v4l2_sliced_vbi_format *sliced_in;
- u32 service_set_in;
- int insert_mpeg;
+ struct v4l2_sliced_vbi_format *sliced_in; /* pointer to in.fmt.sliced */
+ u32 count; /* Count of VBI data lines: 60 Hz: 12 or 50 Hz: 18 */
+ u32 start[2]; /* First VBI data line per field: 10 & 273 or 6 & 318 */
- /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
- One for /dev/vbi0 and one for /dev/vbi8 */
- struct v4l2_sliced_vbi_data sliced_data[36];
+ u32 frame; /* Count of VBI buffers/frames received from Encoder */
- /* Buffer for VBI data inserted into MPEG stream.
- The first byte is a dummy byte that's never used.
- The next 16 bytes contain the MPEG header for the VBI data,
- the remainder is the actual VBI data.
- The max size accepted by the MPEG VBI reinsertion turns out
- to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes,
- where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is
- a single line header byte and 2 * 18 is the number of VBI lines per frame.
+ /*
+ * Vars for creation and insertion of MPEG Private Stream 1 packets
+ * of sliced VBI data into an MPEG PS
+ */
- However, it seems that the data must be 1K aligned, so we have to
- pad the data until the 1 or 2 K boundary.
+ /* Boolean: create and insert Private Stream 1 packets into the PS */
+ int insert_mpeg;
+
+ /*
+ * Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
+ * Used in cx18-vbi.c only for collecting sliced data, and as a source
+ * during conversion of sliced VBI data into MPEG Priv Stream 1 packets.
+ * We don't need to save state here, but the array may have been a bit
+ * too big (2304 bytes) to alloc from the stack.
+ */
+ struct v4l2_sliced_vbi_data sliced_data[36];
- This pointer array will allocate 2049 bytes to store each VBI frame. */
+ /*
+ * A ring buffer of driver-generated MPEG-2 PS
+ * Program Pack/Private Stream 1 packets for sliced VBI data insertion
+ * into the MPEG PS stream.
+ *
+ * In each sliced_mpeg_data[] buffer is:
+ * 16 byte MPEG-2 PS Program Pack Header
+ * 16 byte MPEG-2 Private Stream 1 PES Header
+ * 4 byte magic number: "itv0" or "ITV0"
+ * 4 byte first field line mask, if "itv0"
+ * 4 byte second field line mask, if "itv0"
+ * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data
+ *
+ * Each line in the payload is
+ * 1 byte line header derived from the SDID (WSS, CC, VPS, etc.)
+ * 42 bytes of line data
+ *
+ * That's a maximum 1552 bytes of payload in the Private Stream 1 packet
+ * which is the payload size a PVR-350 (CX23415) MPEG decoder will
+ * accept for VBI data. So, including the headers, it's a maximum 1584
+ * bytes total.
+ */
+#define CX18_SLICED_MPEG_DATA_MAXSZ 1584
+ /* copy_vbi_buf() needs 8 temp bytes on the end for the worst case */
+#define CX18_SLICED_MPEG_DATA_BUFSZ (CX18_SLICED_MPEG_DATA_MAXSZ+8)
u8 *sliced_mpeg_data[CX18_VBI_FRAMES];
u32 sliced_mpeg_size[CX18_VBI_FRAMES];
- struct cx18_buffer sliced_mpeg_buf;
+
+ /* Count of Program Pack/Program Stream 1 packets inserted into PS */
u32 inserted_frame;
- u32 start[2], count;
- u32 raw_size;
- u32 sliced_size;
+ /*
+ * A dummy driver stream transfer buffer with a copy of the next
+ * sliced_mpeg_data[] buffer for output to userland apps.
+ * Only used in cx18-fileops.c, but its state needs to persist at times.
+ */
+ struct cx18_buffer sliced_mpeg_buf;
};
/* Per cx23418, per I2C bus private algo callback data */
@@ -383,16 +494,17 @@ struct cx18_i2c_algo_callback_data {
/* Struct to hold info about cx18 cards */
struct cx18 {
- int num; /* board number, -1 during init! */
- char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */
- struct pci_dev *dev; /* PCI device */
+ int instance;
+ struct pci_dev *pci_dev;
+ struct v4l2_device v4l2_dev;
+ struct v4l2_subdev *sd_av; /* A/V decoder/digitizer sub-device */
+ struct v4l2_subdev *sd_extmux; /* External multiplexer sub-dev */
+
const struct cx18_card *card; /* card information */
const char *card_name; /* full name of the card */
const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
u8 is_50hz;
u8 is_60hz;
- u8 is_out_50hz;
- u8 is_out_60hz;
u8 nof_inputs; /* number of video inputs */
u8 nof_audio_inputs; /* number of audio inputs */
u16 buffer_id; /* buffer ID counter */
@@ -413,10 +525,7 @@ struct cx18 {
/* dualwatch */
unsigned long dualwatch_jiffies;
- u16 dualwatch_stereo_mode;
-
- /* Digitizer type */
- int digitizer; /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */
+ u32 dualwatch_stereo_mode;
struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
struct cx18_options options; /* User options */
@@ -426,7 +535,6 @@ struct cx18 {
unsigned long i_flags; /* global cx18 flags */
atomic_t ana_capturing; /* count number of active analog capture streams */
atomic_t tot_capturing; /* total count number of active capture streams */
- spinlock_t lock; /* lock access to this struct */
int search_pack_header;
int open_id; /* incremented each time an open occurs, used as
@@ -468,30 +576,30 @@ struct cx18 {
struct i2c_adapter i2c_adap[2];
struct i2c_algo_bit_data i2c_algo[2];
struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
- struct i2c_client i2c_client[2];
- struct mutex i2c_bus_lock[2];
- struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];
/* gpio */
u32 gpio_dir;
u32 gpio_val;
struct mutex gpio_lock;
+ struct v4l2_subdev sd_gpiomux;
+ struct v4l2_subdev sd_resetctrl;
/* v4l2 and User settings */
/* codec settings */
u32 audio_input;
u32 active_input;
- u32 active_output;
v4l2_std_id std;
v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
};
+static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct cx18, v4l2_dev);
+}
+
/* Globals */
-extern struct cx18 *cx18_cards[];
-extern int cx18_cards_active;
extern int cx18_first_minor;
-extern spinlock_t cx18_cards_lock;
/*==============Prototypes==================*/
@@ -511,4 +619,22 @@ static inline int cx18_raw_vbi(const struct cx18 *cx)
return cx->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
}
+/* Call the specified callback for all subdevs with a grp_id bit matching the
+ * mask in hw (if 0, then match them all). Ignore any errors. */
+#define cx18_call_hw(cx, hw, o, f, args...) \
+ __v4l2_device_call_subdevs(&(cx)->v4l2_dev, \
+ !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+
+#define cx18_call_all(cx, o, f, args...) cx18_call_hw(cx, 0, o, f , ##args)
+
+/* Call the specified callback for all subdevs with a grp_id bit matching the
+ * mask in hw (if 0, then match them all). If the callback returns an error
+ * other than 0 or -ENOIOCTLCMD, then return with that error code. */
+#define cx18_call_hw_err(cx, hw, o, f, args...) \
+ __v4l2_device_call_subdevs_until_err( \
+ &(cx)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+
+#define cx18_call_all_err(cx, o, f, args...) \
+ cx18_call_hw_err(cx, 0, o, f , ##args)
+
#endif /* CX18_DRIVER_H */
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index bd5e6f3fd4d0..3b86f57cd15a 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -167,7 +167,7 @@ int cx18_dvb_register(struct cx18_stream *stream)
ret = dvb_register_adapter(&dvb->dvb_adapter,
CX18_DRIVER_NAME,
- THIS_MODULE, &cx->dev->dev, adapter_nr);
+ THIS_MODULE, &cx->pci_dev->dev, adapter_nr);
if (ret < 0)
goto err_out;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 055f6e004b2d..4d7d6d5a7f86 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -128,15 +128,15 @@ static void cx18_release_stream(struct cx18_stream *s)
static void cx18_dualwatch(struct cx18 *cx)
{
struct v4l2_tuner vt;
- u16 new_bitmap;
- u16 new_stereo_mode;
- const u16 stereo_mask = 0x0300;
- const u16 dual = 0x0200;
+ u32 new_bitmap;
+ u32 new_stereo_mode;
+ const u32 stereo_mask = 0x0300;
+ const u32 dual = 0x0200;
u32 h;
new_stereo_mode = cx->params.audio_properties & stereo_mask;
memset(&vt, 0, sizeof(vt));
- cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, &vt);
+ cx18_call_all(cx, tuner, g_tuner, &vt);
if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
(vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
new_stereo_mode = dual;
@@ -176,6 +176,8 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
*err = 0;
while (1) {
if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
+ /* Process pending program info updates and pending
+ VBI data */
if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
cx->dualwatch_jiffies = jiffies;
@@ -186,7 +188,6 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) {
/* byteswap and process VBI data */
cx18_process_vbi_data(cx, buf,
- s_vbi->dma_pts,
s_vbi->type);
cx18_stream_put_buf_fw(s_vbi, buf);
}
@@ -207,8 +208,7 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
cx18_buf_swap(buf);
else {
/* byteswap and process VBI data */
- cx18_process_vbi_data(cx, buf,
- s->dma_pts, s->type);
+ cx18_process_vbi_data(cx, buf, s->type);
}
return buf;
}
@@ -260,6 +260,20 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
len = ucount;
if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
!cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
+ /*
+ * Try to find a good splice point in the PS, just before
+ * an MPEG-2 Program Pack start code, and provide only
+ * up to that point to the user, so it's easy to insert VBI data
+ * the next time around.
+ */
+ /* FIXME - This only works for an MPEG-2 PS, not a TS */
+ /*
+ * An MPEG-2 Program Stream (PS) is a series of
+ * MPEG-2 Program Packs terminated by an
+ * MPEG Program End Code after the last Program Pack.
+ * A Program Pack may hold a PS System Header packet and any
+ * number of Program Elementary Stream (PES) Packets
+ */
const char *start = buf->buf + buf->readpos;
const char *p = start + 1;
const u8 *q;
@@ -267,38 +281,54 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
int stuffing, i;
while (start + len > p) {
+ /* Scan for a 0 to find a potential MPEG-2 start code */
q = memchr(p, 0, start + len - p);
if (q == NULL)
break;
p = q + 1;
+ /*
+ * Keep looking if not a
+ * MPEG-2 Pack header start code: 0x00 0x00 0x01 0xba
+ * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0
+ */
if ((char *)q + 15 >= buf->buf + buf->bytesused ||
q[1] != 0 || q[2] != 1 || q[3] != ch)
continue;
+
+ /* If expecting the primary video PES */
if (!cx->search_pack_header) {
+ /* Continue if it couldn't be a PES packet */
if ((q[6] & 0xc0) != 0x80)
continue;
- if (((q[7] & 0xc0) == 0x80 &&
- (q[9] & 0xf0) == 0x20) ||
- ((q[7] & 0xc0) == 0xc0 &&
- (q[9] & 0xf0) == 0x30)) {
- ch = 0xba;
+ /* Check if a PTS or PTS & DTS follow */
+ if (((q[7] & 0xc0) == 0x80 && /* PTS only */
+ (q[9] & 0xf0) == 0x20) || /* PTS only */
+ ((q[7] & 0xc0) == 0xc0 && /* PTS & DTS */
+ (q[9] & 0xf0) == 0x30)) { /* DTS follows */
+ /* Assume we found the video PES hdr */
+ ch = 0xba; /* next want a Program Pack*/
cx->search_pack_header = 1;
- p = q + 9;
+ p = q + 9; /* Skip this video PES hdr */
}
continue;
}
+
+ /* We may have found a Program Pack start code */
+
+ /* Get the count of stuffing bytes & verify them */
stuffing = q[13] & 7;
/* all stuffing bytes must be 0xff */
for (i = 0; i < stuffing; i++)
if (q[14 + i] != 0xff)
break;
- if (i == stuffing &&
- (q[4] & 0xc4) == 0x44 &&
- (q[12] & 3) == 3 &&
- q[14 + stuffing] == 0 &&
+ if (i == stuffing && /* right number of stuffing bytes*/
+ (q[4] & 0xc4) == 0x44 && /* marker check */
+ (q[12] & 3) == 3 && /* marker check */
+ q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */
q[15 + stuffing] == 0 &&
q[16 + stuffing] == 1) {
- cx->search_pack_header = 0;
+ /* We declare we actually found a Program Pack*/
+ cx->search_pack_header = 0; /* expect vid PES */
len = (char *)q - start;
cx18_setup_sliced_vbi_buf(cx);
break;
@@ -578,7 +608,7 @@ int cx18_v4l2_close(struct file *filp)
/* Mark that the radio is no longer in use */
clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
/* Switch tuner to TV */
- cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
+ cx18_call_all(cx, tuner, s_std, cx->std);
/* Select correct audio input (i.e. TV tuner or Line in) */
cx18_audio_set_io(cx);
if (atomic_read(&cx->ana_capturing) > 0) {
@@ -641,7 +671,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
/* We have the radio */
cx18_mute(cx);
/* Switch tuner to radio */
- cx18_call_i2c_clients(cx, AUDC_SET_RADIO, NULL);
+ cx18_call_all(cx, tuner, s_radio);
/* Select the correct audio input (i.e. radio tuner) */
cx18_audio_set_io(cx);
/* Done! Unmute and continue. */
@@ -652,38 +682,15 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
int cx18_v4l2_open(struct file *filp)
{
- int res, x, y = 0;
- struct cx18 *cx = NULL;
- struct cx18_stream *s = NULL;
- int minor = video_devdata(filp)->minor;
-
- /* Find which card this open was on */
- spin_lock(&cx18_cards_lock);
- for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
- /* find out which stream this open was on */
- for (y = 0; y < CX18_MAX_STREAMS; y++) {
- if (cx18_cards[x] == NULL)
- continue;
- s = &cx18_cards[x]->streams[y];
- if (s->v4l2dev && s->v4l2dev->minor == minor) {
- cx = cx18_cards[x];
- break;
- }
- }
- }
- spin_unlock(&cx18_cards_lock);
-
- if (cx == NULL) {
- /* Couldn't find a device registered
- on that minor, shouldn't happen! */
- printk(KERN_WARNING "No cx18 device found on minor %d\n",
- minor);
- return -ENXIO;
- }
+ int res;
+ struct video_device *video_dev = video_devdata(filp);
+ struct cx18_stream *s = video_get_drvdata(video_dev);
+ struct cx18 *cx = s->cx;;
mutex_lock(&cx->serialize_lock);
if (cx18_init_on_first_open(cx)) {
- CX18_ERR("Failed to initialize on minor %d\n", minor);
+ CX18_ERR("Failed to initialize on minor %d\n",
+ video_dev->minor);
mutex_unlock(&cx->serialize_lock);
return -ENXIO;
}
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
index 1fa95da1575e..83cd559cc609 100644
--- a/drivers/media/video/cx18/cx18-firmware.c
+++ b/drivers/media/video/cx18/cx18-firmware.c
@@ -26,7 +26,6 @@
#include "cx18-irq.h"
#include "cx18-firmware.h"
#include "cx18-cards.h"
-#include "cx18-av-core.h"
#include <linux/firmware.h>
#define CX18_PROC_SOFT_RESET 0xc70010
@@ -107,7 +106,7 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
u32 __iomem *dst = (u32 __iomem *)mem;
const u32 *src;
- if (request_firmware(&fw, fn, &cx->dev->dev)) {
+ if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
CX18_ERR("Unable to open firmware %s\n", fn);
CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
return -ENOMEM;
@@ -151,7 +150,7 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
u32 apu_version = 0;
int sz;
- if (request_firmware(&fw, fn, &cx->dev->dev)) {
+ if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
CX18_ERR("unable to open firmware %s\n", fn);
CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
cx18_setup_page(cx, 0);
@@ -286,23 +285,6 @@ void cx18_init_power(struct cx18 *cx, int lowpwr)
cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC);
cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);
- /*
- * VDCLK Integer = 0x0f, Post Divider = 0x04
- * AIMCLK Integer = 0x0e, Post Divider = 0x16
- */
- cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
-
- /* VDCLK Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
- cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
-
- /* AIMCLK Fraction = 0x05227ad */
- /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz before post-divide */
- cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
- cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
-
/* Defaults */
/* APU = SC or SC/2 = 125/62.5 */
/* EPU = SC = 125 */
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index 1a99329f33cb..5518d1424f8f 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -46,6 +46,9 @@
* gpio13: cs5345 reset pin
*/
+/*
+ * File scope utility functions
+ */
static void gpio_write(struct cx18 *cx)
{
u32 dir_lo = cx->gpio_dir & 0xffff;
@@ -63,73 +66,201 @@ static void gpio_write(struct cx18 *cx)
CX18_REG_GPIO_OUT2, val_hi, dir_hi);
}
-void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
+static void gpio_update(struct cx18 *cx, u32 mask, u32 data)
{
- const struct cx18_gpio_i2c_slave_reset *p;
+ if (mask == 0)
+ return;
- p = &cx->card->gpio_i2c_slave_reset;
+ mutex_lock(&cx->gpio_lock);
+ cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
+ gpio_write(cx);
+ mutex_unlock(&cx->gpio_lock);
+}
+
+static void gpio_reset_seq(struct cx18 *cx, u32 active_lo, u32 active_hi,
+ unsigned int assert_msecs,
+ unsigned int recovery_msecs)
+{
+ u32 mask;
- if ((p->active_lo_mask | p->active_hi_mask) == 0)
+ mask = active_lo | active_hi;
+ if (mask == 0)
return;
- /* Assuming that the masks are a subset of the bits in gpio_dir */
+ /*
+ * Assuming that active_hi and active_lo are a subsets of the bits in
+ * gpio_dir. Also assumes that active_lo and active_hi don't overlap
+ * in any bit position
+ */
/* Assert */
- mutex_lock(&cx->gpio_lock);
- cx->gpio_val =
- (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask);
- gpio_write(cx);
- schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
+ gpio_update(cx, mask, ~active_lo);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(assert_msecs));
/* Deassert */
- cx->gpio_val =
- (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask);
- gpio_write(cx);
- schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
+ gpio_update(cx, mask, ~active_hi);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(recovery_msecs));
+}
+
+/*
+ * GPIO Multiplexer - logical device
+ */
+static int gpiomux_log_status(struct v4l2_subdev *sd)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ mutex_lock(&cx->gpio_lock);
+ CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n",
+ cx->gpio_dir, cx->gpio_val);
mutex_unlock(&cx->gpio_lock);
+ return 0;
}
-void cx18_reset_ir_gpio(void *data)
+static int gpiomux_s_radio(struct v4l2_subdev *sd)
{
- struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
- const struct cx18_gpio_i2c_slave_reset *p;
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
- p = &cx->card->gpio_i2c_slave_reset;
+ /*
+ * FIXME - work out the cx->active/audio_input mess - this is
+ * intended to handle the switch to radio mode and set the
+ * audio routing, but we need to update the state in cx
+ */
+ gpio_update(cx, cx->card->gpio_audio_input.mask,
+ cx->card->gpio_audio_input.radio);
+ return 0;
+}
- if (p->ir_reset_mask == 0)
- return;
+static int gpiomux_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ u32 data;
- CX18_DEBUG_INFO("Resetting IR microcontroller\n");
+ switch (cx->card->audio_inputs[cx->audio_input].muxer_input) {
+ case 1:
+ data = cx->card->gpio_audio_input.linein;
+ break;
+ case 0:
+ data = cx->card->gpio_audio_input.tuner;
+ break;
+ default:
+ /*
+ * FIXME - work out the cx->active/audio_input mess - this is
+ * intended to handle the switch from radio mode and set the
+ * audio routing, but we need to update the state in cx
+ */
+ data = cx->card->gpio_audio_input.tuner;
+ break;
+ }
+ gpio_update(cx, cx->card->gpio_audio_input.mask, data);
+ return 0;
+}
- /*
- Assert timing for the Z8F0811 on HVR-1600 boards:
- 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate
- 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles
- (6,601,085 nanoseconds ~= 7 milliseconds)
- 3. DBG pin must be high before chip exits reset for normal operation.
- DBG is open drain and hopefully pulled high since we don't
- normally drive it (GPIO 1?) for the HVR-1600
- 4. Z8F0811 won't exit reset until RESET is deasserted
- */
- mutex_lock(&cx->gpio_lock);
- cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask;
- gpio_write(cx);
- mutex_unlock(&cx->gpio_lock);
- schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
+static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ u32 data;
+
+ switch (route->input) {
+ case 0:
+ data = cx->card->gpio_audio_input.tuner;
+ break;
+ case 1:
+ data = cx->card->gpio_audio_input.linein;
+ break;
+ case 2:
+ data = cx->card->gpio_audio_input.radio;
+ break;
+ default:
+ return -EINVAL;
+ }
+ gpio_update(cx, cx->card->gpio_audio_input.mask, data);
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops gpiomux_core_ops = {
+ .log_status = gpiomux_log_status,
+};
+
+static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = {
+ .s_std = gpiomux_s_std,
+ .s_radio = gpiomux_s_radio,
+};
+
+static const struct v4l2_subdev_audio_ops gpiomux_audio_ops = {
+ .s_routing = gpiomux_s_audio_routing,
+};
+
+static const struct v4l2_subdev_ops gpiomux_ops = {
+ .core = &gpiomux_core_ops,
+ .tuner = &gpiomux_tuner_ops,
+ .audio = &gpiomux_audio_ops,
+};
+
+/*
+ * GPIO Reset Controller - logical device
+ */
+static int resetctrl_log_status(struct v4l2_subdev *sd)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
- /*
- Zilog comes out of reset, loads reset vector address and executes
- from there. Required recovery delay unknown.
- */
mutex_lock(&cx->gpio_lock);
- cx->gpio_val = cx->gpio_val | p->ir_reset_mask;
- gpio_write(cx);
+ CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n",
+ cx->gpio_dir, cx->gpio_val);
mutex_unlock(&cx->gpio_lock);
- schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
+ return 0;
}
-EXPORT_SYMBOL(cx18_reset_ir_gpio);
-/* This symbol is exported for use by an infrared module for the IR-blaster */
+static int resetctrl_reset(struct v4l2_subdev *sd, u32 val)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ const struct cx18_gpio_i2c_slave_reset *p;
+
+ p = &cx->card->gpio_i2c_slave_reset;
+ switch (val) {
+ case CX18_GPIO_RESET_I2C:
+ gpio_reset_seq(cx, p->active_lo_mask, p->active_hi_mask,
+ p->msecs_asserted, p->msecs_recovery);
+ break;
+ case CX18_GPIO_RESET_Z8F0811:
+ /*
+ * Assert timing for the Z8F0811 on HVR-1600 boards:
+ * 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to
+ * initiate
+ * 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock
+ * cycles (6,601,085 nanoseconds ~= 7 milliseconds)
+ * 3. DBG pin must be high before chip exits reset for normal
+ * operation. DBG is open drain and hopefully pulled high
+ * since we don't normally drive it (GPIO 1?) for the
+ * HVR-1600
+ * 4. Z8F0811 won't exit reset until RESET is deasserted
+ * 5. Zilog comes out of reset, loads reset vector address and
+ * executes from there. Required recovery delay unknown.
+ */
+ gpio_reset_seq(cx, p->ir_reset_mask, 0,
+ p->msecs_asserted, p->msecs_recovery);
+ break;
+ case CX18_GPIO_RESET_XC2028:
+ if (cx->card->tuners[0].tuner == TUNER_XC2028)
+ gpio_reset_seq(cx, (1 << cx->card->xceive_pin), 0,
+ 1, 1);
+ break;
+ }
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops resetctrl_core_ops = {
+ .log_status = resetctrl_log_status,
+ .reset = resetctrl_reset,
+};
+
+static const struct v4l2_subdev_ops resetctrl_ops = {
+ .core = &resetctrl_core_ops,
+};
+
+/*
+ * External entry points
+ */
void cx18_gpio_init(struct cx18 *cx)
{
mutex_lock(&cx->gpio_lock);
@@ -156,6 +287,49 @@ void cx18_gpio_init(struct cx18 *cx)
mutex_unlock(&cx->gpio_lock);
}
+int cx18_gpio_register(struct cx18 *cx, u32 hw)
+{
+ struct v4l2_subdev *sd;
+ const struct v4l2_subdev_ops *ops;
+ char *str;
+
+ switch (hw) {
+ case CX18_HW_GPIO_MUX:
+ sd = &cx->sd_gpiomux;
+ ops = &gpiomux_ops;
+ str = "gpio-mux";
+ break;
+ case CX18_HW_GPIO_RESET_CTRL:
+ sd = &cx->sd_resetctrl;
+ ops = &resetctrl_ops;
+ str = "gpio-reset-ctrl";
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ v4l2_subdev_init(sd, ops);
+ v4l2_set_subdevdata(sd, cx);
+ snprintf(sd->name, sizeof(sd->name), "%s %s", cx->v4l2_dev.name, str);
+ sd->grp_id = hw;
+ return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
+}
+
+void cx18_reset_ir_gpio(void *data)
+{
+ struct cx18 *cx = to_cx18((struct v4l2_device *)data);
+
+ if (cx->card->gpio_i2c_slave_reset.ir_reset_mask == 0)
+ return;
+
+ CX18_DEBUG_INFO("Resetting IR microcontroller\n");
+
+ v4l2_subdev_call(&cx->sd_resetctrl,
+ core, reset, CX18_GPIO_RESET_Z8F0811);
+}
+EXPORT_SYMBOL(cx18_reset_ir_gpio);
+/* This symbol is exported for use by lirc_pvr150 for the IR-blaster */
+
/* Xceive tuner reset function */
int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
{
@@ -163,56 +337,11 @@ int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
struct cx18_i2c_algo_callback_data *cb_data = algo->data;
struct cx18 *cx = cb_data->cx;
- if (cmd != XC2028_TUNER_RESET)
+ if (cmd != XC2028_TUNER_RESET ||
+ cx->card->tuners[0].tuner != TUNER_XC2028)
return 0;
- CX18_DEBUG_INFO("Resetting tuner\n");
- mutex_lock(&cx->gpio_lock);
- cx->gpio_val &= ~(1 << cx->card->xceive_pin);
- gpio_write(cx);
- mutex_unlock(&cx->gpio_lock);
- schedule_timeout_interruptible(msecs_to_jiffies(1));
-
- mutex_lock(&cx->gpio_lock);
- cx->gpio_val |= 1 << cx->card->xceive_pin;
- gpio_write(cx);
- mutex_unlock(&cx->gpio_lock);
- schedule_timeout_interruptible(msecs_to_jiffies(1));
- return 0;
-}
-
-int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg)
-{
- struct v4l2_routing *route = arg;
- u32 mask, data;
-
- switch (command) {
- case VIDIOC_INT_S_AUDIO_ROUTING:
- if (route->input > 2)
- return -EINVAL;
- mask = cx->card->gpio_audio_input.mask;
- switch (route->input) {
- case 0:
- data = cx->card->gpio_audio_input.tuner;
- break;
- case 1:
- data = cx->card->gpio_audio_input.linein;
- break;
- case 2:
- default:
- data = cx->card->gpio_audio_input.radio;
- break;
- }
- break;
-
- default:
- return -EINVAL;
- }
- if (mask) {
- mutex_lock(&cx->gpio_lock);
- cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
- gpio_write(cx);
- mutex_unlock(&cx->gpio_lock);
- }
- return 0;
+ CX18_DEBUG_INFO("Resetting XCeive tuner\n");
+ return v4l2_subdev_call(&cx->sd_resetctrl,
+ core, reset, CX18_GPIO_RESET_XC2028);
}
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h
index 39ffccc19d8a..f9a5ca3566af 100644
--- a/drivers/media/video/cx18/cx18-gpio.h
+++ b/drivers/media/video/cx18/cx18-gpio.h
@@ -22,7 +22,13 @@
*/
void cx18_gpio_init(struct cx18 *cx);
-void cx18_reset_i2c_slaves_gpio(struct cx18 *cx);
+int cx18_gpio_register(struct cx18 *cx, u32 hw);
+
+enum cx18_gpio_reset_type {
+ CX18_GPIO_RESET_I2C = 0,
+ CX18_GPIO_RESET_Z8F0811 = 1,
+ CX18_GPIO_RESET_XC2028 = 2,
+};
+
void cx18_reset_ir_gpio(void *data);
int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value);
-int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg);
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 83e1c6333126..d092643faf46 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -26,7 +26,6 @@
#include "cx18-io.h"
#include "cx18-cards.h"
#include "cx18-gpio.h"
-#include "cx18-av-core.h"
#include "cx18-i2c.h"
#include "cx18-irq.h"
@@ -43,31 +42,37 @@
#define CX18_CS5345_I2C_ADDR 0x4c
/* This array should match the CX18_HW_ defines */
-static const u8 hw_driverids[] = {
- I2C_DRIVERID_TUNER,
- I2C_DRIVERID_TVEEPROM,
- I2C_DRIVERID_CS5345,
- 0, /* CX18_HW_GPIO dummy driver ID */
- 0 /* CX18_HW_CX23418 dummy driver ID */
-};
-
-/* This array should match the CX18_HW_ defines */
static const u8 hw_addrs[] = {
- 0,
- 0,
- CX18_CS5345_I2C_ADDR,
- 0, /* CX18_HW_GPIO dummy driver ID */
- 0, /* CX18_HW_CX23418 dummy driver ID */
+ 0, /* CX18_HW_TUNER */
+ 0, /* CX18_HW_TVEEPROM */
+ CX18_CS5345_I2C_ADDR, /* CX18_HW_CS5345 */
+ 0, /* CX18_HW_DVB */
+ 0, /* CX18_HW_418_AV */
+ 0, /* CX18_HW_GPIO_MUX */
+ 0, /* CX18_HW_GPIO_RESET_CTRL */
};
/* This array should match the CX18_HW_ defines */
/* This might well become a card-specific array */
static const u8 hw_bus[] = {
- 0,
- 0,
- 0,
- 0, /* CX18_HW_GPIO dummy driver ID */
- 0, /* CX18_HW_CX23418 dummy driver ID */
+ 1, /* CX18_HW_TUNER */
+ 0, /* CX18_HW_TVEEPROM */
+ 0, /* CX18_HW_CS5345 */
+ 0, /* CX18_HW_DVB */
+ 0, /* CX18_HW_418_AV */
+ 0, /* CX18_HW_GPIO_MUX */
+ 0, /* CX18_HW_GPIO_RESET_CTRL */
+};
+
+/* This array should match the CX18_HW_ defines */
+static const char * const hw_modules[] = {
+ "tuner", /* CX18_HW_TUNER */
+ NULL, /* CX18_HW_TVEEPROM */
+ "cs5345", /* CX18_HW_CS5345 */
+ NULL, /* CX18_HW_DVB */
+ NULL, /* CX18_HW_418_AV */
+ NULL, /* CX18_HW_GPIO_MUX */
+ NULL, /* CX18_HW_GPIO_RESET_CTRL */
};
/* This array should match the CX18_HW_ defines */
@@ -75,83 +80,67 @@ static const char * const hw_devicenames[] = {
"tuner",
"tveeprom",
"cs5345",
- "gpio",
- "cx23418",
+ "cx23418_DTV",
+ "cx23418_AV",
+ "gpio_mux",
+ "gpio_reset_ctrl",
};
int cx18_i2c_register(struct cx18 *cx, unsigned idx)
{
- struct i2c_board_info info;
- struct i2c_client *c;
- u8 id, bus;
- int i;
-
- CX18_DEBUG_I2C("i2c client register\n");
- if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0)
+ struct v4l2_subdev *sd;
+ int bus = hw_bus[idx];
+ struct i2c_adapter *adap = &cx->i2c_adap[bus];
+ const char *mod = hw_modules[idx];
+ const char *type = hw_devicenames[idx];
+ u32 hw = 1 << idx;
+
+ if (idx >= ARRAY_SIZE(hw_addrs))
return -1;
- id = hw_driverids[idx];
- bus = hw_bus[idx];
- memset(&info, 0, sizeof(info));
- strlcpy(info.type, hw_devicenames[idx], sizeof(info.type));
- info.addr = hw_addrs[idx];
- for (i = 0; i < I2C_CLIENTS_MAX; i++)
- if (cx->i2c_clients[i] == NULL)
- break;
-
- if (i == I2C_CLIENTS_MAX) {
- CX18_ERR("insufficient room for new I2C client!\n");
- return -ENOMEM;
- }
- if (id != I2C_DRIVERID_TUNER) {
- c = i2c_new_device(&cx->i2c_adap[bus], &info);
- if (c->driver == NULL)
- i2c_unregister_device(c);
- else
- cx->i2c_clients[i] = c;
- return cx->i2c_clients[i] ? 0 : -ENODEV;
+ if (hw == CX18_HW_TUNER) {
+ /* special tuner group handling */
+ sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
+ cx->card_i2c->radio);
+ if (sd != NULL)
+ sd->grp_id = hw;
+ sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
+ cx->card_i2c->demod);
+ if (sd != NULL)
+ sd->grp_id = hw;
+ sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
+ cx->card_i2c->tv);
+ if (sd != NULL)
+ sd->grp_id = hw;
+ return sd != NULL ? 0 : -1;
}
- /* special tuner handling */
- c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->radio);
- if (c && c->driver == NULL)
- i2c_unregister_device(c);
- else if (c)
- cx->i2c_clients[i++] = c;
- c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->demod);
- if (c && c->driver == NULL)
- i2c_unregister_device(c);
- else if (c)
- cx->i2c_clients[i++] = c;
- c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->tv);
- if (c && c->driver == NULL)
- i2c_unregister_device(c);
- else if (c)
- cx->i2c_clients[i++] = c;
- return 0;
-}
+ /* Is it not an I2C device or one we do not wish to register? */
+ if (!hw_addrs[idx])
+ return -1;
-static int attach_inform(struct i2c_client *client)
-{
- return 0;
+ /* It's an I2C device other than an analog tuner */
+ sd = v4l2_i2c_new_subdev(adap, mod, type, hw_addrs[idx]);
+ if (sd != NULL)
+ sd->grp_id = hw;
+ return sd != NULL ? 0 : -1;
}
-static int detach_inform(struct i2c_client *client)
+/* Find the first member of the subdev group id in hw */
+struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw)
{
- int i;
- struct cx18 *cx = (struct cx18 *)i2c_get_adapdata(client->adapter);
+ struct v4l2_subdev *result = NULL;
+ struct v4l2_subdev *sd;
- CX18_DEBUG_I2C("i2c client detach\n");
- for (i = 0; i < I2C_CLIENTS_MAX; i++) {
- if (cx->i2c_clients[i] == client) {
- cx->i2c_clients[i] = NULL;
+ spin_lock(&cx->v4l2_dev.lock);
+ v4l2_device_for_each_subdev(sd, &cx->v4l2_dev) {
+ if (sd->grp_id == hw) {
+ result = sd;
break;
}
}
- CX18_DEBUG_I2C("i2c detach [client=%s,%s]\n",
- client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed");
-
- return 0;
+ spin_unlock(&cx->v4l2_dev.lock);
+ return result;
}
static void cx18_setscl(void *data, int state)
@@ -204,8 +193,6 @@ static struct i2c_adapter cx18_i2c_adap_template = {
.id = I2C_HW_B_CX2341X,
.algo = NULL, /* set by i2c-algo-bit */
.algo_data = NULL, /* filled from template */
- .client_register = attach_inform,
- .client_unregister = detach_inform,
.owner = THIS_MODULE,
};
@@ -221,152 +208,28 @@ static struct i2c_algo_bit_data cx18_i2c_algo_template = {
.timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */
};
-static struct i2c_client cx18_i2c_client_template = {
- .name = "cx18 internal",
-};
-
-int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg)
-{
- struct i2c_client *client;
- int retval;
- int i;
-
- CX18_DEBUG_I2C("call_i2c_client addr=%02x\n", addr);
- for (i = 0; i < I2C_CLIENTS_MAX; i++) {
- client = cx->i2c_clients[i];
- if (client == NULL || client->driver == NULL ||
- client->driver->command == NULL)
- continue;
- if (addr == client->addr) {
- retval = client->driver->command(client, cmd, arg);
- return retval;
- }
- }
- if (cmd != VIDIOC_DBG_G_CHIP_IDENT)
- CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n",
- addr, cmd);
- return -ENODEV;
-}
-
-/* Find the i2c device based on the driver ID and return
- its i2c address or -ENODEV if no matching device was found. */
-static int cx18_i2c_id_addr(struct cx18 *cx, u32 id)
-{
- struct i2c_client *client;
- int retval = -ENODEV;
- int i;
-
- for (i = 0; i < I2C_CLIENTS_MAX; i++) {
- client = cx->i2c_clients[i];
- if (client == NULL || client->driver == NULL)
- continue;
- if (id == client->driver->id) {
- retval = client->addr;
- break;
- }
- }
- return retval;
-}
-
-/* Find the i2c device name matching the CX18_HW_ flag */
-static const char *cx18_i2c_hw_name(u32 hw)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
- if (1 << i == hw)
- return hw_devicenames[i];
- return "unknown device";
-}
-
-/* Find the i2c device matching the CX18_HW_ flag and return
- its i2c address or -ENODEV if no matching device was found. */
-int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
- if (1 << i == hw)
- return cx18_i2c_id_addr(cx, hw_driverids[i]);
- return -ENODEV;
-}
-
-/* Calls i2c device based on CX18_HW_ flag. If hw == 0, then do nothing.
- If hw == CX18_HW_GPIO then call the gpio handler. */
-int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg)
-{
- int addr;
-
- if (hw == 0)
- return 0;
-
- if (hw == CX18_HW_GPIO)
- return cx18_gpio(cx, cmd, arg);
-
- if (hw == CX18_HW_CX23418)
- return cx18_av_cmd(cx, cmd, arg);
-
- addr = cx18_i2c_hw_addr(cx, hw);
- if (addr < 0) {
- CX18_ERR("i2c hardware 0x%08x (%s) not found for cmd 0x%x!\n",
- hw, cx18_i2c_hw_name(hw), cmd);
- return addr;
- }
- return cx18_call_i2c_client(cx, addr, cmd, arg);
-}
-
-/* broadcast cmd for all I2C clients and for the gpio subsystem */
-void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg)
-{
- if (cx->i2c_adap[0].algo == NULL || cx->i2c_adap[1].algo == NULL) {
- CX18_ERR("adapter is not set\n");
- return;
- }
- cx18_av_cmd(cx, cmd, arg);
- i2c_clients_command(&cx->i2c_adap[0], cmd, arg);
- i2c_clients_command(&cx->i2c_adap[1], cmd, arg);
- if (cx->hw_flags & CX18_HW_GPIO)
- cx18_gpio(cx, cmd, arg);
-}
-
/* init + register i2c algo-bit adapter */
int init_cx18_i2c(struct cx18 *cx)
{
int i;
CX18_DEBUG_I2C("i2c init\n");
- /* Sanity checks for the I2C hardware arrays. They must be the
- * same size and GPIO/CX23418 must be the last entries.
- */
- if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) ||
- ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) ||
- CX18_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 2)) ||
- CX18_HW_CX23418 != (1 << (ARRAY_SIZE(hw_addrs) - 1)) ||
- hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) {
- CX18_ERR("Mismatched I2C hardware arrays\n");
- return -ENODEV;
- }
-
for (i = 0; i < 2; i++) {
- memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
- sizeof(struct i2c_adapter));
+ /* Setup algorithm for adapter */
memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template,
sizeof(struct i2c_algo_bit_data));
cx->i2c_algo_cb_data[i].cx = cx;
cx->i2c_algo_cb_data[i].bus_index = i;
cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i];
- cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
+ /* Setup adapter */
+ memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
+ sizeof(struct i2c_adapter));
+ cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
- " #%d-%d", cx->num, i);
- i2c_set_adapdata(&cx->i2c_adap[i], cx);
-
- memcpy(&cx->i2c_client[i], &cx18_i2c_client_template,
- sizeof(struct i2c_client));
- sprintf(cx->i2c_client[i].name +
- strlen(cx->i2c_client[i].name), "%d", i);
- cx->i2c_client[i].adapter = &cx->i2c_adap[i];
- cx->i2c_adap[i].dev.parent = &cx->dev->dev;
+ " #%d-%d", cx->instance, i);
+ i2c_set_adapdata(&cx->i2c_adap[i], &cx->v4l2_dev);
+ cx->i2c_adap[i].dev.parent = &cx->pci_dev->dev;
}
if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) {
@@ -402,7 +265,8 @@ int init_cx18_i2c(struct cx18 *cx)
cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
- cx18_reset_i2c_slaves_gpio(cx);
+ cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
+ core, reset, (u32) CX18_GPIO_RESET_I2C);
return i2c_bit_add_bus(&cx->i2c_adap[0]) ||
i2c_bit_add_bus(&cx->i2c_adap[1]);
diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/video/cx18/cx18-i2c.h
index 4869739013bd..bdfd1921e300 100644
--- a/drivers/media/video/cx18/cx18-i2c.h
+++ b/drivers/media/video/cx18/cx18-i2c.h
@@ -21,11 +21,8 @@
* 02111-1307 USA
*/
-int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw);
-int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg);
-int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg);
-void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg);
int cx18_i2c_register(struct cx18 *cx, unsigned idx);
+struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw);
/* init + register i2c algo-bit adapter */
int init_cx18_i2c(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 7086aaba77d6..e4c9e3d8bacd 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -58,12 +58,21 @@ u16 cx18_service2vbi(int type)
}
}
+/* Check if VBI services are allowed on the (field, line) for the video std */
static int valid_service_line(int field, int line, int is_pal)
{
- return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
+ return (is_pal && line >= 6 &&
+ ((field == 0 && line <= 23) || (field == 1 && line <= 22))) ||
(!is_pal && line >= 10 && line < 22);
}
+/*
+ * For a (field, line, std) and inbound potential set of services for that line,
+ * return the first valid service of those passed in the incoming set for that
+ * line in priority order:
+ * CC, VPS, or WSS over TELETEXT for well known lines
+ * TELETEXT, before VPS, before CC, before WSS, for other lines
+ */
static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
{
u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
@@ -90,6 +99,10 @@ static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
return 0;
}
+/*
+ * Expand the service_set of *fmt into valid service_lines for the std,
+ * and clear the passed in fmt->service_set
+ */
void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
{
u16 set = fmt->service_set;
@@ -102,7 +115,25 @@ void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
}
}
+/*
+ * Sanitize the service_lines in *fmt per the video std, and return 1
+ * if any service_line is left as valid after santization
+ */
+static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
+{
+ int f, l;
+ u16 set = 0;
+
+ for (f = 0; f < 2; f++) {
+ for (l = 0; l < 24; l++) {
+ fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
+ set |= fmt->service_lines[f][l];
+ }
+ }
+ return set != 0;
+}
+/* Compute the service_set from the assumed valid service_lines of *fmt */
u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
{
int f, l;
@@ -129,10 +160,8 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
pixfmt->priv = 0;
if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
- /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
- pixfmt->sizeimage =
- pixfmt->height * pixfmt->width +
- pixfmt->height * (pixfmt->width / 2);
+ /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
+ pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
pixfmt->bytesperline = 720;
} else {
pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
@@ -149,8 +178,8 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
vbifmt->sampling_rate = 27000000;
- vbifmt->offset = 248;
- vbifmt->samples_per_line = cx->vbi.raw_decoder_line_size - 4;
+ vbifmt->offset = 248; /* FIXME - slightly wrong for both 50 & 60 Hz */
+ vbifmt->samples_per_line = vbi_active_samples - 4;
vbifmt->sample_format = V4L2_PIX_FMT_GREY;
vbifmt->start[0] = cx->vbi.start[0];
vbifmt->start[1] = cx->vbi.start[1];
@@ -164,7 +193,30 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- return -EINVAL;
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+ struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+
+ /* sane, V4L2 spec compliant, defaults */
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
+ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+ memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
+ vbifmt->service_set = 0;
+
+ /*
+ * Fetch the configured service_lines and total service_set from the
+ * digitizer/slicer. Note, cx18_av_vbi() wipes the passed in
+ * fmt->fmt.sliced under valid calling conditions
+ */
+ if (v4l2_subdev_call(cx->sd_av, video, g_fmt, fmt))
+ return -EINVAL;
+
+ /* Ensure V4L2 spec compliant output */
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
+ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+ vbifmt->service_set = cx18_get_service_set(vbifmt);
+ return 0;
}
static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
@@ -174,11 +226,18 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
struct cx18 *cx = id->cx;
int w = fmt->fmt.pix.width;
int h = fmt->fmt.pix.height;
+ int min_h = 2;
w = min(w, 720);
- w = max(w, 1);
+ w = max(w, 2);
+ if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
+ /* YUV height must be a multiple of 32 */
+ h &= ~0x1f;
+ min_h = 32;
+ }
h = min(h, cx->is_50hz ? 576 : 480);
- h = max(h, 2);
+ h = max(h, min_h);
+
cx18_g_fmt_vid_cap(file, fh, fmt);
fmt->fmt.pix.width = w;
fmt->fmt.pix.height = h;
@@ -194,7 +253,20 @@ static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- return -EINVAL;
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+ struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+
+ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
+
+ /* If given a service set, expand it validly & clear passed in set */
+ if (vbifmt->service_set)
+ cx18_expand_service_set(vbifmt, cx->is_50hz);
+ /* Sanitize the service_lines, and compute the new set if any valid */
+ if (check_service_set(vbifmt, cx->is_50hz))
+ vbifmt->service_set = cx18_get_service_set(vbifmt);
+ return 0;
}
static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
@@ -223,7 +295,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
cx->params.width = w;
cx->params.height = h;
- cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
+ v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
return cx18_g_fmt_vid_cap(file, fh, fmt);
}
@@ -238,54 +310,131 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
if (ret)
return ret;
+ /*
+ * Changing the Encoder's Raw VBI parameters won't have any effect
+ * if any analog capture is ongoing
+ */
if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
return -EBUSY;
+ /*
+ * Set the digitizer registers for raw active VBI.
+ * Note cx18_av_vbi_wipes out alot of the passed in fmt under valid
+ * calling conditions
+ */
+ ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
+ if (ret)
+ return ret;
+
+ /* Store our new v4l2 (non-)sliced VBI state */
cx->vbi.sliced_in->service_set = 0;
cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
- cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
+
return cx18_g_fmt_vbi_cap(file, fh, fmt);
}
static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- return -EINVAL;
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
+ int ret;
+ struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+
+ ret = v4l2_prio_check(&cx->prio, &id->prio);
+ if (ret)
+ return ret;
+
+ cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
+
+ /*
+ * Changing the Encoder's Raw VBI parameters won't have any effect
+ * if any analog capture is ongoing
+ */
+ if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
+ return -EBUSY;
+
+ /*
+ * Set the service_lines requested in the digitizer/slicer registers.
+ * Note, cx18_av_vbi() wipes some "impossible" service lines in the
+ * passed in fmt->fmt.sliced under valid calling conditions
+ */
+ ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
+ if (ret)
+ return ret;
+ /* Store our current v4l2 sliced VBI settings */
+ cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+ memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
+ return 0;
}
static int cx18_g_chip_ident(struct file *file, void *fh,
struct v4l2_dbg_chip_ident *chip)
{
struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+ int err = 0;
chip->ident = V4L2_IDENT_NONE;
chip->revision = 0;
- if (v4l2_chip_match_host(&chip->match)) {
- chip->ident = V4L2_IDENT_CX23418;
- return 0;
+ switch (chip->match.type) {
+ case V4L2_CHIP_MATCH_HOST:
+ switch (chip->match.addr) {
+ case 0:
+ chip->ident = V4L2_IDENT_CX23418;
+ chip->revision = cx18_read_reg(cx, 0xC72028);
+ break;
+ case 1:
+ /*
+ * The A/V decoder is always present, but in the rare
+ * case that the card doesn't have analog, we don't
+ * use it. We find it w/o using the cx->sd_av pointer
+ */
+ cx18_call_hw(cx, CX18_HW_418_AV,
+ core, g_chip_ident, chip);
+ break;
+ default:
+ /*
+ * Could return ident = V4L2_IDENT_UNKNOWN if we had
+ * other host chips at higher addresses, but we don't
+ */
+ err = -EINVAL; /* per V4L2 spec */
+ break;
+ }
+ break;
+ case V4L2_CHIP_MATCH_I2C_DRIVER:
+ /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
+ cx18_call_all(cx, core, g_chip_ident, chip);
+ break;
+ case V4L2_CHIP_MATCH_I2C_ADDR:
+ /*
+ * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
+ * to look if a chip is at the address with no driver. That's a
+ * dangerous thing to do with EEPROMs anyway.
+ */
+ cx18_call_all(cx, core, g_chip_ident, chip);
+ break;
+ default:
+ err = -EINVAL;
+ break;
}
- cx18_call_i2c_clients(cx, VIDIOC_DBG_G_CHIP_IDENT, chip);
- return 0;
+ return err;
}
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
{
struct v4l2_dbg_register *regs = arg;
- unsigned long flags;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
return -EINVAL;
- spin_lock_irqsave(&cx18_cards_lock, flags);
regs->size = 4;
- if (cmd == VIDIOC_DBG_G_REGISTER)
- regs->val = cx18_read_enc(cx, regs->reg);
- else
+ if (cmd == VIDIOC_DBG_S_REGISTER)
cx18_write_enc(cx, regs->val, regs->reg);
- spin_unlock_irqrestore(&cx18_cards_lock, flags);
+ else
+ regs->val = cx18_read_enc(cx, regs->reg);
return 0;
}
@@ -296,7 +445,8 @@ static int cx18_g_register(struct file *file, void *fh,
if (v4l2_chip_match_host(&reg->match))
return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
- cx18_call_i2c_clients(cx, VIDIOC_DBG_G_REGISTER, reg);
+ /* FIXME - errors shouldn't be ignored */
+ cx18_call_all(cx, core, g_register, reg);
return 0;
}
@@ -307,7 +457,8 @@ static int cx18_s_register(struct file *file, void *fh,
if (v4l2_chip_match_host(&reg->match))
return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
- cx18_call_i2c_clients(cx, VIDIOC_DBG_S_REGISTER, reg);
+ /* FIXME - errors shouldn't be ignored */
+ cx18_call_all(cx, core, s_register, reg);
return 0;
}
#endif
@@ -335,7 +486,8 @@ static int cx18_querycap(struct file *file, void *fh,
strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
- snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(cx->dev));
+ snprintf(vcap->bus_info, sizeof(vcap->bus_info),
+ "PCI:%s", pci_name(cx->pci_dev));
vcap->version = CX18_DRIVER_VERSION; /* version */
vcap->capabilities = cx->v4l2_cap; /* capabilities */
return 0;
@@ -403,7 +555,8 @@ static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- return cx18_av_cmd(cx, VIDIOC_S_CROP, crop);
+ CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n");
+ return -EINVAL;
}
static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
@@ -412,7 +565,8 @@ static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- return cx18_av_cmd(cx, VIDIOC_G_CROP, crop);
+ CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n");
+ return -EINVAL;
}
static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
@@ -483,7 +637,7 @@ static int cx18_g_frequency(struct file *file, void *fh,
if (vf->tuner != 0)
return -EINVAL;
- cx18_call_i2c_clients(cx, VIDIOC_G_FREQUENCY, vf);
+ cx18_call_all(cx, tuner, g_frequency, vf);
return 0;
}
@@ -502,7 +656,7 @@ int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
cx18_mute(cx);
CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
- cx18_call_i2c_clients(cx, VIDIOC_S_FREQUENCY, vf);
+ cx18_call_all(cx, tuner, s_frequency, vf);
cx18_unmute(cx);
return 0;
}
@@ -547,12 +701,11 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
cx->vbi.count = cx->is_50hz ? 18 : 12;
cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
- cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284;
CX18_DEBUG_INFO("Switching standard to %llx.\n",
(unsigned long long) cx->std);
/* Tuner */
- cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
+ cx18_call_all(cx, tuner, s_std, cx->std);
return 0;
}
@@ -569,9 +722,7 @@ static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
if (vt->index != 0)
return -EINVAL;
- /* Setting tuner can only set audio mode */
- cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt);
-
+ cx18_call_all(cx, tuner, s_tuner, vt);
return 0;
}
@@ -582,7 +733,7 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
if (vt->index != 0)
return -EINVAL;
- cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt);
+ cx18_call_all(cx, tuner, g_tuner, vt);
if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
@@ -598,7 +749,30 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_sliced_vbi_cap *cap)
{
- return -EINVAL;
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+ int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
+ int f, l;
+
+ if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ return -EINVAL;
+
+ cap->service_set = 0;
+ for (f = 0; f < 2; f++) {
+ for (l = 0; l < 24; l++) {
+ if (valid_service_line(f, l, cx->is_50hz)) {
+ /*
+ * We can find all v4l2 supported vbi services
+ * for the standard, on a valid line for the std
+ */
+ cap->service_lines[f][l] = set;
+ cap->service_set |= set;
+ } else
+ cap->service_lines[f][l] = 0;
+ }
+ }
+ for (f = 0; f < 3; f++)
+ cap->reserved[f] = 0;
+ return 0;
}
static int cx18_g_enc_index(struct file *file, void *fh,
@@ -708,13 +882,15 @@ static int cx18_log_status(struct file *file, void *fh)
struct v4l2_audio audin;
int i;
- CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num);
+ CX18_INFO("================= START STATUS CARD #%d "
+ "=================\n", cx->instance);
+ CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name);
if (cx->hw_flags & CX18_HW_TVEEPROM) {
struct tveeprom tv;
cx18_read_eeprom(cx, &tv);
}
- cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL);
+ cx18_call_all(cx, core, log_status);
cx18_get_input(cx, cx->active_input, &vidin);
cx18_get_audio_input(cx, cx->audio_input, &audin);
CX18_INFO("Video Input: %s\n", vidin.name);
@@ -725,12 +901,12 @@ static int cx18_log_status(struct file *file, void *fh)
mutex_unlock(&cx->gpio_lock);
CX18_INFO("Tuner: %s\n",
test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
- cx2341x_log_status(&cx->params, cx->name);
+ cx2341x_log_status(&cx->params, cx->v4l2_dev.name);
CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
for (i = 0; i < CX18_MAX_STREAMS; i++) {
struct cx18_stream *s = &cx->streams[i];
- if (s->v4l2dev == NULL || s->buffers == 0)
+ if (s->video_dev == NULL || s->buffers == 0)
continue;
CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
s->name, s->s_flags,
@@ -740,7 +916,8 @@ static int cx18_log_status(struct file *file, void *fh)
CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
(long long)cx->mpg_data_received,
(long long)cx->vbi_data_inserted);
- CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num);
+ CX18_INFO("================== END STATUS CARD #%d "
+ "==================\n", cx->instance);
return 0;
}
@@ -754,7 +931,8 @@ static long cx18_default(struct file *file, void *fh, int cmd, void *arg)
CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n",
route->input, route->output);
- cx18_audio_set_route(cx, route);
+ cx18_call_hw(cx, cx->card->hw_audio_ctrl, audio, s_routing,
+ route);
break;
}
@@ -762,7 +940,8 @@ static long cx18_default(struct file *file, void *fh, int cmd, void *arg)
u32 val = *(u32 *)arg;
if ((val == 0) || (val & 0x01))
- cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]);
+ cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset,
+ (u32) CX18_GPIO_RESET_Z8F0811);
break;
}
@@ -782,6 +961,8 @@ long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd,
mutex_lock(&cx->serialize_lock);
+ /* FIXME - consolidate v4l2_prio_check()'s here */
+
if (cx18_debug & CX18_DBGFLG_IOCTL)
vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
res = video_ioctl2(filp, cmd, arg);
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index de5e723fdf44..2226e5791e99 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -83,6 +83,8 @@ static const struct cx18_api_info api_info[] = {
API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW),
+ API_ENTRY(APU, CX18_APU_START, 0),
+ API_ENTRY(APU, CX18_APU_STOP, 0),
API_ENTRY(APU, CX18_APU_RESETAI, 0),
API_ENTRY(CPU, CX18_CPU_DEBUG_PEEK32, 0),
API_ENTRY(0, 0, 0),
@@ -98,21 +100,30 @@ static const struct cx18_api_info *find_api_info(u32 cmd)
return NULL;
}
-static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
+/* Call with buf of n*11+1 bytes */
+static char *u32arr2hex(u32 data[], int n, char *buf)
{
- char argstr[MAX_MB_ARGUMENTS*11+1];
char *p;
int i;
+ for (i = 0, p = buf; i < n; i++, p += 11) {
+ /* kernel snprintf() appends '\0' always */
+ snprintf(p, 12, " %#010x", data[i]);
+ }
+ *p = '\0';
+ return buf;
+}
+
+static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
+{
+ char argstr[MAX_MB_ARGUMENTS*11+1];
+
if (!(cx18_debug & CX18_DBGFLG_API))
return;
- for (i = 0, p = argstr; i < MAX_MB_ARGUMENTS; i++, p += 11) {
- /* kernel snprintf() appends '\0' always */
- snprintf(p, 12, " %#010x", mb->args[i]);
- }
CX18_DEBUG_API("%s: req %#010x ack %#010x cmd %#010x err %#010x args%s"
- "\n", name, mb->request, mb->ack, mb->cmd, mb->error, argstr);
+ "\n", name, mb->request, mb->ack, mb->cmd, mb->error,
+ u32arr2hex(mb->args, MAX_MB_ARGUMENTS, argstr));
}
@@ -439,7 +450,8 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
"incoming %s to EPU mailbox (sequence no. %u)"
"\n",
rpu_str[rpu], rpu_str[rpu], order_mb->request);
- dump_mb(cx, order_mb, "incoming");
+ if (cx18_debug & CX18_DBGFLG_WARN)
+ dump_mb(cx, order_mb, "incoming");
order->flags = CX18_F_EWO_MB_STALE_UPON_RECEIPT;
}
@@ -468,16 +480,24 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
struct mutex *mb_lock;
long int timeout, ret;
int i;
+ char argstr[MAX_MB_ARGUMENTS*11+1];
if (info == NULL) {
CX18_WARN("unknown cmd %x\n", cmd);
return -EINVAL;
}
- if (cmd == CX18_CPU_DE_SET_MDL)
- CX18_DEBUG_HI_API("%s\n", info->name);
- else
- CX18_DEBUG_API("%s\n", info->name);
+ if (cx18_debug & CX18_DBGFLG_API) { /* only call u32arr2hex if needed */
+ if (cmd == CX18_CPU_DE_SET_MDL) {
+ if (cx18_debug & CX18_DBGFLG_HIGHVOL)
+ CX18_DEBUG_HI_API("%s\tcmd %#010x args%s\n",
+ info->name, cmd,
+ u32arr2hex(data, args, argstr));
+ } else
+ CX18_DEBUG_API("%s\tcmd %#010x args%s\n",
+ info->name, cmd,
+ u32arr2hex(data, args, argstr));
+ }
switch (info->rpu) {
case APU:
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 8d9441e88c4e..3046b8e74345 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -204,7 +204,7 @@ int cx18_stream_alloc(struct cx18_stream *s)
}
buf->id = cx->buffer_id++;
INIT_LIST_HEAD(&buf->list);
- buf->dma_handle = pci_map_single(s->cx->dev,
+ buf->dma_handle = pci_map_single(s->cx->pci_dev,
buf->buf, s->buf_size, s->dma);
cx18_buf_sync_for_cpu(s, buf);
cx18_enqueue(s, buf, &s->q_free);
@@ -227,7 +227,7 @@ void cx18_stream_free(struct cx18_stream *s)
/* empty q_free */
while ((buf = cx18_dequeue(s, &s->q_free))) {
- pci_unmap_single(s->cx->dev, buf->dma_handle,
+ pci_unmap_single(s->cx->pci_dev, buf->dma_handle,
s->buf_size, s->dma);
kfree(buf->buf);
kfree(buf);
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index 456cec3bc28f..4de06269d88f 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -29,14 +29,14 @@
static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
struct cx18_buffer *buf)
{
- pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle,
+ pci_dma_sync_single_for_cpu(s->cx->pci_dev, buf->dma_handle,
s->buf_size, s->dma);
}
static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
struct cx18_buffer *buf)
{
- pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle,
+ pci_dma_sync_single_for_device(s->cx->pci_dev, buf->dma_handle,
s->buf_size, s->dma);
}
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 89c1ec94f335..0932b76b2373 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -32,7 +32,6 @@
#include "cx18-streams.h"
#include "cx18-cards.h"
#include "cx18-scb.h"
-#include "cx18-av-core.h"
#include "cx18-dvb.h"
#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
@@ -101,11 +100,11 @@ static struct {
static void cx18_stream_init(struct cx18 *cx, int type)
{
struct cx18_stream *s = &cx->streams[type];
- struct video_device *dev = s->v4l2dev;
+ struct video_device *video_dev = s->video_dev;
- /* we need to keep v4l2dev, so restore it afterwards */
+ /* we need to keep video_dev, so restore it afterwards */
memset(s, 0, sizeof(*s));
- s->v4l2dev = dev;
+ s->video_dev = video_dev;
/* initialize cx18_stream fields */
s->cx = cx;
@@ -130,12 +129,12 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
struct cx18_stream *s = &cx->streams[type];
u32 cap = cx->v4l2_cap;
int num_offset = cx18_stream_info[type].num_offset;
- int num = cx->num + cx18_first_minor + num_offset;
+ int num = cx->instance + cx18_first_minor + num_offset;
- /* These four fields are always initialized. If v4l2dev == NULL, then
+ /* These four fields are always initialized. If video_dev == NULL, then
this stream is not in use. In that case no other fields but these
four can be used. */
- s->v4l2dev = NULL;
+ s->video_dev = NULL;
s->cx = cx;
s->type = type;
s->name = cx18_stream_info[type].name;
@@ -163,22 +162,22 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
return 0;
/* allocate and initialize the v4l2 video device structure */
- s->v4l2dev = video_device_alloc();
- if (s->v4l2dev == NULL) {
+ s->video_dev = video_device_alloc();
+ if (s->video_dev == NULL) {
CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
s->name);
return -ENOMEM;
}
- snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d",
- cx->num);
+ snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s",
+ cx->v4l2_dev.name, s->name);
- s->v4l2dev->num = num;
- s->v4l2dev->parent = &cx->dev->dev;
- s->v4l2dev->fops = &cx18_v4l2_enc_fops;
- s->v4l2dev->release = video_device_release;
- s->v4l2dev->tvnorms = V4L2_STD_ALL;
- cx18_set_funcs(s->v4l2dev);
+ s->video_dev->num = num;
+ s->video_dev->v4l2_dev = &cx->v4l2_dev;
+ s->video_dev->fops = &cx18_v4l2_enc_fops;
+ s->video_dev->release = video_device_release;
+ s->video_dev->tvnorms = V4L2_STD_ALL;
+ cx18_set_funcs(s->video_dev);
return 0;
}
@@ -227,28 +226,30 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
}
}
- if (s->v4l2dev == NULL)
+ if (s->video_dev == NULL)
return 0;
- num = s->v4l2dev->num;
+ num = s->video_dev->num;
/* card number + user defined offset + device offset */
if (type != CX18_ENC_STREAM_TYPE_MPG) {
struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
- if (s_mpg->v4l2dev)
- num = s_mpg->v4l2dev->num + cx18_stream_info[type].num_offset;
+ if (s_mpg->video_dev)
+ num = s_mpg->video_dev->num
+ + cx18_stream_info[type].num_offset;
}
+ video_set_drvdata(s->video_dev, s);
/* Register device. First try the desired minor, then any free one. */
- ret = video_register_device(s->v4l2dev, vfl_type, num);
+ ret = video_register_device(s->video_dev, vfl_type, num);
if (ret < 0) {
CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n",
s->name, num);
- video_device_release(s->v4l2dev);
- s->v4l2dev = NULL;
+ video_device_release(s->video_dev);
+ s->video_dev = NULL;
return ret;
}
- num = s->v4l2dev->num;
+ num = s->video_dev->num;
switch (vfl_type) {
case VFL_TYPE_GRABBER:
@@ -312,9 +313,9 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
cx->streams[type].dvb.enabled = false;
}
- vdev = cx->streams[type].v4l2dev;
+ vdev = cx->streams[type].video_dev;
- cx->streams[type].v4l2dev = NULL;
+ cx->streams[type].video_dev = NULL;
if (vdev == NULL)
continue;
@@ -346,46 +347,88 @@ static void cx18_vbi_setup(struct cx18_stream *s)
}
/* setup VBI registers */
- cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
-
- /* determine number of lines and total number of VBI bytes.
- A raw line takes 1444 bytes: 4 byte SAV code + 2 * 720
- A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal
- header, 42 data bytes + checksum (to be confirmed) */
+ v4l2_subdev_call(cx->sd_av, video, s_fmt, &cx->vbi.in);
+
+ /*
+ * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw
+ * VBI when the first analog capture channel starts, as once it starts
+ * (e.g. MPEG), we can't effect any change in the Encoder Raw VBI setup
+ * (i.e. for the VBI capture channels). We also send it for each
+ * analog capture channel anyway just to make sure we get the proper
+ * behavior
+ */
if (raw) {
lines = cx->vbi.count * 2;
} else {
- lines = cx->is_60hz ? 24 : 38;
- if (cx->is_60hz)
- lines += 2;
+ /*
+ * For 525/60 systems, according to the VIP 2 & BT.656 std:
+ * The EAV RP code's Field bit toggles on line 4, a few lines
+ * after the Vertcal Blank bit has already toggled.
+ * Tell the encoder to capture 21-4+1=18 lines per field,
+ * since we want lines 10 through 21.
+ *
+ * FIXME - revisit for 625/50 systems
+ */
+ lines = cx->is_60hz ? (21 - 4 + 1) * 2 : 38;
}
- cx->vbi.enc_size = lines *
- (raw ? cx->vbi.raw_size : cx->vbi.sliced_size);
-
data[0] = s->handle;
/* Lines per field */
data[1] = (lines / 2) | ((lines / 2) << 16);
/* bytes per line */
- data[2] = (raw ? cx->vbi.raw_decoder_line_size
- : cx->vbi.sliced_decoder_line_size);
+ data[2] = (raw ? vbi_active_samples
+ : (cx->is_60hz ? vbi_hblank_samples_60Hz
+ : vbi_hblank_samples_50Hz));
/* Every X number of frames a VBI interrupt arrives
(frames as in 25 or 30 fps) */
data[3] = 1;
- /* Setup VBI for the cx25840 digitizer */
+ /*
+ * Set the SAV/EAV RP codes to look for as start/stop points
+ * when in VIP-1.1 mode
+ */
if (raw) {
+ /*
+ * Start codes for beginning of "active" line in vertical blank
+ * 0x20 ( VerticalBlank )
+ * 0x60 ( EvenField VerticalBlank )
+ */
data[4] = 0x20602060;
+ /*
+ * End codes for end of "active" raw lines and regular lines
+ * 0x30 ( VerticalBlank HorizontalBlank)
+ * 0x70 ( EvenField VerticalBlank HorizontalBlank)
+ * 0x90 (Task HorizontalBlank)
+ * 0xd0 (Task EvenField HorizontalBlank)
+ */
data[5] = 0x307090d0;
} else {
+ /*
+ * End codes for active video, we want data in the hblank region
+ * 0xb0 (Task 0 VerticalBlank HorizontalBlank)
+ * 0xf0 (Task EvenField VerticalBlank HorizontalBlank)
+ *
+ * Since the V bit is only allowed to toggle in the EAV RP code,
+ * just before the first active region line, these two
+ * are problematic:
+ * 0x90 (Task HorizontalBlank)
+ * 0xd0 (Task EvenField HorizontalBlank)
+ *
+ * We have set the digitzer such that we don't have to worry
+ * about these problem codes.
+ */
data[4] = 0xB0F0B0F0;
+ /*
+ * Start codes for beginning of active line in vertical blank
+ * 0xa0 (Task VerticalBlank )
+ * 0xe0 (Task EvenField VerticalBlank )
+ */
data[5] = 0xA0E0A0E0;
}
CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n",
data[0], data[1], data[2], data[3], data[4], data[5]);
- if (s->type == CX18_ENC_STREAM_TYPE_VBI)
- cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
+ cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
}
struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
@@ -434,10 +477,10 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
u32 data[MAX_MB_ARGUMENTS];
struct cx18 *cx = s->cx;
struct cx18_buffer *buf;
- int ts = 0;
int captype = 0;
+ struct cx18_api_func_private priv;
- if (s->v4l2dev == NULL && s->dvb.enabled == 0)
+ if (s->video_dev == NULL && s->dvb.enabled == 0)
return -EINVAL;
CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
@@ -453,7 +496,6 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
case CX18_ENC_STREAM_TYPE_TS:
captype = CAPTURE_CHANNEL_TYPE_TS;
- ts = 1;
break;
case CX18_ENC_STREAM_TYPE_YUV:
captype = CAPTURE_CHANNEL_TYPE_YUV;
@@ -462,8 +504,16 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
captype = CAPTURE_CHANNEL_TYPE_PCM;
break;
case CX18_ENC_STREAM_TYPE_VBI:
+#ifdef CX18_ENCODER_PARSES_SLICED
captype = cx18_raw_vbi(cx) ?
CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI;
+#else
+ /*
+ * Currently we set things up so that Sliced VBI from the
+ * digitizer is handled as Raw VBI by the encoder
+ */
+ captype = CAPTURE_CHANNEL_TYPE_VBI;
+#endif
cx->vbi.frame = 0;
cx->vbi.inserted_frame = 0;
memset(cx->vbi.sliced_mpeg_size,
@@ -473,10 +523,6 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
return -EINVAL;
}
- /* mute/unmute video */
- cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
- s->handle, !!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags));
-
/* Clear Streamoff flags in case left from last capture */
clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
@@ -484,31 +530,63 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
s->handle = data[0];
cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
- if (atomic_read(&cx->ana_capturing) == 0 && !ts) {
- struct cx18_api_func_private priv;
-
- /* Stuff from Windows, we don't know what it is */
+ /*
+ * For everything but CAPTURE_CHANNEL_TYPE_TS, play it safe and
+ * set up all the parameters, as it is not obvious which parameters the
+ * firmware shares across capture channel types and which it does not.
+ *
+ * Some of the cx18_vapi() calls below apply to only certain capture
+ * channel types. We're hoping there's no harm in calling most of them
+ * anyway, as long as the values are all consistent. Setting some
+ * shared parameters will have no effect once an analog capture channel
+ * has started streaming.
+ */
+ if (captype != CAPTURE_CHANNEL_TYPE_TS) {
cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0);
cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1);
- cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, s->handle, 12);
+ /*
+ * Audio related reset according to
+ * Documentation/video4linux/cx2341x/fw-encoder-api.txt
+ */
+ if (atomic_read(&cx->ana_capturing) == 0)
+ cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
+ s->handle, 12);
+
+ /*
+ * Number of lines for Field 1 & Field 2 according to
+ * Documentation/video4linux/cx2341x/fw-encoder-api.txt
+ * Field 1 is 312 for 625 line systems in BT.656
+ * Field 2 is 313 for 625 line systems in BT.656
+ */
cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3,
- s->handle, cx->digitizer, cx->digitizer);
+ s->handle, 312, 313);
- /* Setup VBI */
if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE)
cx18_vbi_setup(s);
- /* assign program index info.
- Mask 7: select I/P/B, Num_req: 400 max */
+ /*
+ * assign program index info.
+ * Mask 7: select I/P/B, Num_req: 400 max
+ * FIXME - currently we have this hardcoded as disabled
+ */
cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0);
- /* Setup API for Stream */
+ /* Call out to the common CX2341x API setup for user controls */
priv.cx = cx;
priv.s = s;
cx2341x_update(&priv, cx18_api_func, NULL, &cx->params);
+
+ /*
+ * When starting a capture and we're set for radio,
+ * ensure the video is muted, despite the user control.
+ */
+ if (!cx->params.video_mute &&
+ test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
+ cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
+ (cx->params.video_mute_yuv << 8) | 1);
}
if (atomic_read(&cx->tot_capturing) == 0) {
@@ -552,7 +630,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
}
/* you're live! sit back and await interrupts :) */
- if (!ts)
+ if (captype != CAPTURE_CHANNEL_TYPE_TS)
atomic_inc(&cx->ana_capturing);
atomic_inc(&cx->tot_capturing);
return 0;
@@ -565,7 +643,7 @@ void cx18_stop_all_captures(struct cx18 *cx)
for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
struct cx18_stream *s = &cx->streams[i];
- if (s->v4l2dev == NULL && s->dvb.enabled == 0)
+ if (s->video_dev == NULL && s->dvb.enabled == 0)
continue;
if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
cx18_stop_v4l2_encode_stream(s, 0);
@@ -577,7 +655,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
struct cx18 *cx = s->cx;
unsigned long then;
- if (s->v4l2dev == NULL && s->dvb.enabled == 0)
+ if (s->video_dev == NULL && s->dvb.enabled == 0)
return -EINVAL;
/* This function assumes that you are allowed to stop the capture
@@ -629,7 +707,7 @@ u32 cx18_find_handle(struct cx18 *cx)
for (i = 0; i < CX18_MAX_STREAMS; i++) {
struct cx18_stream *s = &cx->streams[i];
- if (s->v4l2dev && (s->handle != CX18_INVALID_TASK_HANDLE))
+ if (s->video_dev && (s->handle != CX18_INVALID_TASK_HANDLE))
return s->handle;
}
return CX18_INVALID_TASK_HANDLE;
@@ -647,7 +725,7 @@ struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle)
s = &cx->streams[i];
if (s->handle != handle)
continue;
- if (s->v4l2dev || s->dvb.enabled)
+ if (s->video_dev || s->dvb.enabled)
return s;
}
return NULL;
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
index fb595bd548e8..c2aef4add31d 100644
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -25,7 +25,16 @@
#include "cx18-vbi.h"
#include "cx18-ioctl.h"
#include "cx18-queue.h"
-#include "cx18-av-core.h"
+
+/*
+ * Raster Reference/Protection (RP) bytes, used in Start/End Active
+ * Video codes emitted from the digitzer in VIP 1.x mode, that flag the start
+ * of VBI sample or VBI ancilliary data regions in the digitial ratser line.
+ *
+ * Task FieldEven VerticalBlank HorizontalBlank 0 0 0 0
+ */
+static const u8 raw_vbi_sav_rp[2] = { 0x20, 0x60 }; /* __V_, _FV_ */
+static const u8 sliced_vbi_eav_rp[2] = { 0xb0, 0xf0 }; /* T_VH, TFVH */
static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
{
@@ -34,10 +43,17 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
u32 linemask[2] = { 0, 0 };
unsigned short size;
static const u8 mpeg_hdr_data[] = {
- 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
- 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
- 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
- 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
+ /* MPEG-2 Program Pack */
+ 0x00, 0x00, 0x01, 0xba, /* Prog Pack start code */
+ 0x44, 0x00, 0x0c, 0x66, 0x24, 0x01, /* SCR, SCR Ext, markers */
+ 0x01, 0xd1, 0xd3, /* Mux Rate, markers */
+ 0xfa, 0xff, 0xff, /* Res, Suff cnt, Stuff */
+ /* MPEG-2 Private Stream 1 PES Packet */
+ 0x00, 0x00, 0x01, 0xbd, /* Priv Stream 1 start */
+ 0x00, 0x1a, /* length */
+ 0x84, 0x80, 0x07, /* flags, hdr data len */
+ 0x21, 0x00, 0x5d, 0x63, 0xa7, /* PTS, markers */
+ 0xff, 0xff /* stuffing */
};
const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
int idx = cx->vbi.frame % CX18_VBI_FRAMES;
@@ -71,7 +87,9 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
memcpy(dst + sd + 4, dst + sd + 12, line * 43);
size = 4 + ((43 * line + 3) & ~3);
} else {
- memcpy(dst + sd, "cx0", 4);
+ memcpy(dst + sd, "itv0", 4);
+ cpu_to_le32s(&linemask[0]);
+ cpu_to_le32s(&linemask[1]);
memcpy(dst + sd + 4, &linemask[0], 8);
size = 12 + ((43 * line + 3) & ~3);
}
@@ -86,58 +104,76 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
}
/* Compress raw VBI format, removes leading SAV codes and surplus space
- after the field.
- Returns new compressed size. */
-static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
+ after the frame. Returns new compressed size. */
+static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size)
{
- u32 line_size = cx->vbi.raw_decoder_line_size;
- u32 lines = cx->vbi.count;
- u8 sav1 = cx->vbi.raw_decoder_sav_odd_field;
- u8 sav2 = cx->vbi.raw_decoder_sav_even_field;
+ u32 line_size = vbi_active_samples;
+ u32 lines = cx->vbi.count * 2;
u8 *q = buf;
u8 *p;
int i;
+ /* Skip the header */
+ buf += hdr_size;
+
for (i = 0; i < lines; i++) {
p = buf + i * line_size;
/* Look for SAV code */
if (p[0] != 0xff || p[1] || p[2] ||
- (p[3] != sav1 && p[3] != sav2))
+ (p[3] != raw_vbi_sav_rp[0] &&
+ p[3] != raw_vbi_sav_rp[1]))
break;
- memcpy(q, p + 4, line_size - 4);
- q += line_size - 4;
+ if (i == lines - 1) {
+ /* last line is hdr_size bytes short - extrapolate it */
+ memcpy(q, p + 4, line_size - 4 - hdr_size);
+ q += line_size - 4 - hdr_size;
+ p += line_size - hdr_size - 1;
+ memset(q, (int) *p, hdr_size);
+ } else {
+ memcpy(q, p + 4, line_size - 4);
+ q += line_size - 4;
+ }
}
return lines * (line_size - 4);
}
-
-/* Compressed VBI format, all found sliced blocks put next to one another
- Returns new compressed size */
-static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
- u32 size, u8 sav)
+static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size,
+ const u32 hdr_size)
{
- u32 line_size = cx->vbi.sliced_decoder_line_size;
struct v4l2_decode_vbi_line vbi;
int i;
+ u32 line = 0;
+ u32 line_size = cx->is_60hz ? vbi_hblank_samples_60Hz
+ : vbi_hblank_samples_50Hz;
/* find the first valid line */
- for (i = 0; i < size; i++, buf++) {
- if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
+ for (i = hdr_size, buf += hdr_size; i < size; i++, buf++) {
+ if (buf[0] == 0xff && !buf[1] && !buf[2] &&
+ (buf[3] == sliced_vbi_eav_rp[0] ||
+ buf[3] == sliced_vbi_eav_rp[1]))
break;
}
- size -= i;
+ /*
+ * The last line is short by hdr_size bytes, but for the remaining
+ * checks against size, we pretend that it is not, by counting the
+ * header bytes we knowingly skipped
+ */
+ size -= (i - hdr_size);
if (size < line_size)
return line;
+
for (i = 0; i < size / line_size; i++) {
u8 *p = buf + i * line_size;
- /* Look for SAV code */
- if (p[0] != 0xff || p[1] || p[2] || p[3] != sav)
+ /* Look for EAV code */
+ if (p[0] != 0xff || p[1] || p[2] ||
+ (p[3] != sliced_vbi_eav_rp[0] &&
+ p[3] != sliced_vbi_eav_rp[1]))
continue;
vbi.p = p + 4;
- cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
+ v4l2_subdev_call(cx->sd_av, video, decode_vbi_line, &vbi);
if (vbi.type) {
cx->vbi.sliced_data[line].id = vbi.type;
cx->vbi.sliced_data[line].field = vbi.is_second_field;
@@ -150,51 +186,56 @@ static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
}
void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
- u64 pts_stamp, int streamtype)
+ int streamtype)
{
+ /*
+ * The CX23418 provides a 12 byte header in its raw VBI buffers to us:
+ * 0x3fffffff [4 bytes of something] [4 byte presentation time stamp]
+ */
+ struct vbi_data_hdr {
+ __be32 magic;
+ __be32 unknown;
+ __be32 pts;
+ } *hdr = (struct vbi_data_hdr *) buf->buf;
+
u8 *p = (u8 *) buf->buf;
u32 size = buf->bytesused;
+ u32 pts;
int lines;
if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
return;
+ /*
+ * The CX23418 sends us data that is 32 bit little-endian swapped,
+ * but we want the raw VBI bytes in the order they were in the raster
+ * line. This has a side effect of making the header big endian
+ */
+ cx18_buf_swap(buf);
+
/* Raw VBI data */
if (cx18_raw_vbi(cx)) {
- u8 type;
-
- cx18_buf_swap(buf);
-
- /* Skip 12 bytes of header that gets stuffed in */
- size -= 12;
- memcpy(p, &buf->buf[12], size);
- type = p[3];
- size = buf->bytesused = compress_raw_buf(cx, p, size);
+ size = buf->bytesused =
+ compress_raw_buf(cx, p, size, sizeof(struct vbi_data_hdr));
- /* second field of the frame? */
- if (type == cx->vbi.raw_decoder_sav_even_field) {
- /* Dirty hack needed for backwards
- compatibility of old VBI software. */
- p += size - 4;
- memcpy(p, &cx->vbi.frame, 4);
- cx->vbi.frame++;
- }
+ /*
+ * Hack needed for compatibility with old VBI software.
+ * Write the frame # at the last 4 bytes of the frame
+ */
+ p += size - 4;
+ memcpy(p, &cx->vbi.frame, 4);
+ cx->vbi.frame++;
return;
}
/* Sliced VBI data with data insertion */
- cx18_buf_swap(buf);
- /* first field */
- lines = compress_sliced_buf(cx, 0, p, size / 2,
- cx->vbi.sliced_decoder_sav_odd_field);
- /* second field */
- /* experimentation shows that the second half does not always
- begin at the exact address. So start a bit earlier
- (hence 32). */
- lines = compress_sliced_buf(cx, lines, p + size / 2 - 32,
- size / 2 + 32, cx->vbi.sliced_decoder_sav_even_field);
+ pts = (be32_to_cpu(hdr->magic) == 0x3fffffff) ? be32_to_cpu(hdr->pts)
+ : 0;
+
+ lines = compress_sliced_buf(cx, p, size, sizeof(struct vbi_data_hdr));
+
/* always return at least one empty line */
if (lines == 0) {
cx->vbi.sliced_data[0].id = 0;
@@ -206,6 +247,6 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
memcpy(p, &cx->vbi.sliced_data[0], size);
if (cx->vbi.insert_mpeg)
- copy_vbi_data(cx, lines, pts_stamp);
+ copy_vbi_data(cx, lines, pts);
cx->vbi.frame++;
}
diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/video/cx18/cx18-vbi.h
index c56ff7d28f20..e7e1ae427f34 100644
--- a/drivers/media/video/cx18/cx18-vbi.h
+++ b/drivers/media/video/cx18/cx18-vbi.h
@@ -22,5 +22,5 @@
*/
void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
- u64 pts_stamp, int streamtype);
+ int streamtype);
int cx18_used_line(struct cx18 *cx, int line, int field);
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index 84c0ff13b607..bd9bd44da791 100644
--- a/drivers/media/video/cx18/cx18-version.h
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -24,8 +24,8 @@
#define CX18_DRIVER_NAME "cx18"
#define CX18_DRIVER_VERSION_MAJOR 1
-#define CX18_DRIVER_VERSION_MINOR 0
-#define CX18_DRIVER_VERSION_PATCHLEVEL 4
+#define CX18_DRIVER_VERSION_MINOR 1
+#define CX18_DRIVER_VERSION_PATCHLEVEL 0
#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
#define CX18_DRIVER_VERSION KERNEL_VERSION(CX18_DRIVER_VERSION_MAJOR, \
diff --git a/drivers/media/video/cx18/cx18-video.c b/drivers/media/video/cx18/cx18-video.c
index 2e5c41939330..6fdadedf17a8 100644
--- a/drivers/media/video/cx18/cx18-video.c
+++ b/drivers/media/video/cx18/cx18-video.c
@@ -21,7 +21,6 @@
#include "cx18-driver.h"
#include "cx18-video.h"
-#include "cx18-av-core.h"
#include "cx18-cards.h"
void cx18_video_set_io(struct cx18 *cx)
@@ -32,7 +31,7 @@ void cx18_video_set_io(struct cx18 *cx)
route.input = cx->card->video_inputs[inp].video_input;
route.output = 0;
- cx18_av_cmd(cx, VIDIOC_INT_S_VIDEO_ROUTING, &route);
+ v4l2_subdev_call(cx->sd_av, video, s_routing, &route);
type = cx->card->video_inputs[inp].video_type;
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
index 601f3a2ab742..9956abf576c5 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -56,6 +56,22 @@
#define APU_CMD_MASK 0x10000000
#define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000)
+#define CX18_APU_ENCODING_METHOD_MPEG (0 << 28)
+#define CX18_APU_ENCODING_METHOD_AC3 (1 << 28)
+
+/* Description: Command APU to start audio
+ IN[0] - audio parameters (same as CX18_CPU_SET_AUDIO_PARAMETERS?)
+ IN[1] - caller buffer address, or 0
+ ReturnCode - ??? */
+#define CX18_APU_START (APU_CMD_MASK | 0x01)
+
+/* Description: Command APU to stop audio
+ IN[0] - encoding method to stop
+ ReturnCode - ??? */
+#define CX18_APU_STOP (APU_CMD_MASK | 0x02)
+
+/* Description: Command APU to reset the AI
+ ReturnCode - ??? */
#define CX18_APU_RESETAI (APU_CMD_MASK | 0x05)
/* Description: This command indicates that a Memory Descriptor List has been
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index cbbe47fb87b7..8ded52946334 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -1,5 +1,5 @@
/*
- * cx2341x - generic code for cx23415/6 based devices
+ * cx2341x - generic code for cx23415/6/8 based devices
*
* Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
*
@@ -30,7 +30,7 @@
#include <media/cx2341x.h>
#include <media/v4l2-common.h>
-MODULE_DESCRIPTION("cx23415/6 driver");
+MODULE_DESCRIPTION("cx23415/6/8 driver");
MODULE_AUTHOR("Hans Verkuil");
MODULE_LICENSE("GPL");
@@ -38,6 +38,7 @@ static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+/* Must be sorted from low to high control ID! */
const u32 cx2341x_mpeg_ctrls[] = {
V4L2_CID_MPEG_CLASS,
V4L2_CID_MPEG_STREAM_TYPE,
@@ -50,6 +51,7 @@ const u32 cx2341x_mpeg_ctrls[] = {
V4L2_CID_MPEG_AUDIO_EMPHASIS,
V4L2_CID_MPEG_AUDIO_CRC,
V4L2_CID_MPEG_AUDIO_MUTE,
+ V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
V4L2_CID_MPEG_VIDEO_ENCODING,
V4L2_CID_MPEG_VIDEO_ASPECT,
V4L2_CID_MPEG_VIDEO_B_FRAMES,
@@ -94,6 +96,7 @@ static const struct cx2341x_mpeg_params default_params = {
.audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
.audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
.audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
+ .audio_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_224K,
.audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
.audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
.audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
@@ -148,6 +151,9 @@ static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params *params,
case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
ctrl->value = params->audio_l2_bitrate;
break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ ctrl->value = params->audio_ac3_bitrate;
+ break;
case V4L2_CID_MPEG_AUDIO_MODE:
ctrl->value = params->audio_mode;
break;
@@ -256,6 +262,12 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
params->audio_sampling_freq = ctrl->value;
break;
case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (busy)
+ return -EBUSY;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3)
+ if (ctrl->value != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
+ ctrl->value != V4L2_MPEG_AUDIO_ENCODING_AC3)
+ return -ERANGE;
params->audio_encoding = ctrl->value;
break;
case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
@@ -263,6 +275,13 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
return -EBUSY;
params->audio_l2_bitrate = ctrl->value;
break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ if (busy)
+ return -EBUSY;
+ if (!(params->capabilities & CX2341X_CAP_HAS_AC3))
+ return -EINVAL;
+ params->audio_ac3_bitrate = ctrl->value;
+ break;
case V4L2_CID_MPEG_AUDIO_MODE:
params->audio_mode = ctrl->value;
break;
@@ -481,29 +500,106 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
int err;
switch (qctrl->id) {
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
+
+ case V4L2_CID_MPEG_STREAM_VBI_FMT:
+ if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_STREAM_VBI_FMT_NONE,
+ V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1,
+ V4L2_MPEG_STREAM_VBI_FMT_NONE);
+ return cx2341x_ctrl_query_fill(qctrl,
+ V4L2_MPEG_STREAM_VBI_FMT_NONE,
+ V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
+ default_params.stream_vbi_fmt);
+
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
+
case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (params->capabilities & CX2341X_CAP_HAS_AC3) {
+ /*
+ * The state of L2 & AC3 bitrate controls can change
+ * when this control changes, but v4l2_ctrl_query_fill()
+ * already sets V4L2_CTRL_FLAG_UPDATE for
+ * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
+ */
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+ V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
+ default_params.audio_encoding);
+ }
+
return v4l2_ctrl_query_fill(qctrl,
V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
default_params.audio_encoding);
case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
+ err = v4l2_ctrl_query_fill(qctrl,
V4L2_MPEG_AUDIO_L2_BITRATE_192K,
V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
default_params.audio_l2_bitrate);
+ if (err)
+ return err;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3 &&
+ params->audio_encoding != V4L2_MPEG_AUDIO_ENCODING_LAYER_2)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return 0;
- case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
- case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
- return -EINVAL;
+ case V4L2_CID_MPEG_AUDIO_MODE:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_MODE_STEREO,
+ V4L2_MPEG_AUDIO_MODE_MONO, 1,
+ V4L2_MPEG_AUDIO_MODE_STEREO);
case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
- err = v4l2_ctrl_query_fill_std(qctrl);
+ err = v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
if (err == 0 &&
params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
return err;
+ case V4L2_CID_MPEG_AUDIO_EMPHASIS:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_EMPHASIS_NONE,
+ V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1,
+ V4L2_MPEG_AUDIO_EMPHASIS_NONE);
+
+ case V4L2_CID_MPEG_AUDIO_CRC:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_CRC_NONE,
+ V4L2_MPEG_AUDIO_CRC_CRC16, 1,
+ V4L2_MPEG_AUDIO_CRC_NONE);
+
+ case V4L2_CID_MPEG_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
+
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ err = v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_48K,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1,
+ default_params.audio_ac3_bitrate);
+ if (err)
+ return err;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3) {
+ if (params->audio_encoding !=
+ V4L2_MPEG_AUDIO_ENCODING_AC3)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ } else
+ qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
+ return 0;
+
case V4L2_CID_MPEG_VIDEO_ENCODING:
/* this setting is read-only for the cx2341x since the
V4L2_CID_MPEG_STREAM_TYPE really determines the
@@ -516,32 +612,51 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
return err;
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_VIDEO_ASPECT_1x1,
+ V4L2_MPEG_VIDEO_ASPECT_221x100, 1,
+ V4L2_MPEG_VIDEO_ASPECT_4x3);
+
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+ return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2);
+
+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+ return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
+ params->is_50hz ? 12 : 15);
+
+ case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
+
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- err = v4l2_ctrl_query_fill_std(qctrl);
+ err = v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
if (err == 0 &&
params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
return err;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
+
case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- err = v4l2_ctrl_query_fill_std(qctrl);
+ err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
if (err == 0 &&
params->video_bitrate_mode ==
V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
return err;
- case V4L2_CID_MPEG_STREAM_VBI_FMT:
- if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
- return v4l2_ctrl_query_fill_std(qctrl);
- return cx2341x_ctrl_query_fill(qctrl,
- V4L2_MPEG_STREAM_VBI_FMT_NONE,
- V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
- default_params.stream_vbi_fmt);
+ case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
+ return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
- params->is_50hz ? 12 : 15);
+ case V4L2_CID_MPEG_VIDEO_MUTE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
+
+ case V4L2_CID_MPEG_VIDEO_MUTE_YUV: /* Init YUV (really YCbCr) to black */
+ return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080);
/* CX23415/6 specific */
case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
@@ -643,7 +758,7 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
default_params.stream_insert_nav_packets);
default:
- return v4l2_ctrl_query_fill_std(qctrl);
+ return -EINVAL;
}
}
@@ -671,6 +786,15 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
NULL
};
+ static const char *mpeg_audio_encoding_l2_ac3[] = {
+ "",
+ "MPEG-1/2 Layer II",
+ "",
+ "",
+ "AC-3",
+ NULL
+ };
+
static const char *cx2341x_video_spatial_filter_mode_menu[] = {
"Manual",
"Auto",
@@ -711,6 +835,9 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
case V4L2_CID_MPEG_STREAM_TYPE:
return (p->capabilities & CX2341X_CAP_HAS_TS) ?
mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ return (p->capabilities & CX2341X_CAP_HAS_AC3) ?
+ mpeg_audio_encoding_l2_ac3 : v4l2_ctrl_get_menu(id);
case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
return NULL;
@@ -730,16 +857,34 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
}
EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
+/* definitions for audio properties bits 29-28 */
+#define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0
+#define CX2341X_AUDIO_ENCODING_METHOD_AC3 1
+#define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2
+
static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
{
- params->audio_properties = (params->audio_sampling_freq << 0) |
- ((3 - params->audio_encoding) << 2) |
- ((1 + params->audio_l2_bitrate) << 4) |
+ params->audio_properties =
+ (params->audio_sampling_freq << 0) |
(params->audio_mode << 8) |
(params->audio_mode_extension << 10) |
(((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
? 3 : params->audio_emphasis) << 12) |
(params->audio_crc << 14);
+
+ if ((params->capabilities & CX2341X_CAP_HAS_AC3) &&
+ params->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) {
+ params->audio_properties |=
+ /* Not sure if this MPEG Layer II setting is required */
+ ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
+ (params->audio_ac3_bitrate << 4) |
+ (CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
+ } else {
+ /* Assuming MPEG Layer II */
+ params->audio_properties |=
+ ((3 - params->audio_encoding) << 2) |
+ ((1 + params->audio_l2_bitrate) << 4);
+ }
}
int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
@@ -1022,7 +1167,10 @@ void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
prefix,
cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
- cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
+ cx2341x_menu_item(p,
+ p->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3
+ ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
+ : V4L2_CID_MPEG_AUDIO_L2_BITRATE),
cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
p->audio_mute ? " (muted)" : "");
if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index 00f1e2e8889e..fd3fc3e3198a 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -15,12 +15,15 @@ config VIDEO_CX23885
select DVB_S5H1411 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_TDA10048 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
+ select DVB_TDA10048 if !DVB_FE_CUSTOMISE
+ select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+ select DVB_STV6110 if !DVB_FE_CUSTOMISE
+ select DVB_STV0900 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
---help---
This is a video4linux driver for Conexant 23885 based
TV cards.
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
index 29c23b44c13c..ab8ea35c9bfb 100644
--- a/drivers/media/video/cx23885/Makefile
+++ b/drivers/media/video/cx23885/Makefile
@@ -1,4 +1,6 @@
-cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o
+cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \
+ cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \
+ netup-init.o cimax2.o netup-eeprom.o
obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c
new file mode 100644
index 000000000000..9a6536998d90
--- /dev/null
+++ b/drivers/media/video/cx23885/cimax2.c
@@ -0,0 +1,472 @@
+/*
+ * cimax2.c
+ *
+ * CIMax2(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "cx23885.h"
+#include "dvb_ca_en50221.h"
+/**** Bit definitions for MC417_RWD and MC417_OEN registers ***
+ bits 31-16
++-----------+
+| Reserved |
++-----------+
+ bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8
++-------+-------+-------+-------+-------+-------+-------+-------+
+| WR# | RD# | | ACK# | ADHI | ADLO | CS1# | CS0# |
++-------+-------+-------+-------+-------+-------+-------+-------+
+ bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
++-------+-------+-------+-------+-------+-------+-------+-------+
+| DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0|
++-------+-------+-------+-------+-------+-------+-------+-------+
+***/
+/* MC417 */
+#define NETUP_DATA 0x000000ff
+#define NETUP_WR 0x00008000
+#define NETUP_RD 0x00004000
+#define NETUP_ACK 0x00001000
+#define NETUP_ADHI 0x00000800
+#define NETUP_ADLO 0x00000400
+#define NETUP_CS1 0x00000200
+#define NETUP_CS0 0x00000100
+#define NETUP_EN_ALL 0x00001000
+#define NETUP_CTRL_OFF (NETUP_CS1 | NETUP_CS0 | NETUP_WR | NETUP_RD)
+#define NETUP_CI_CTL 0x04
+#define NETUP_CI_RD 1
+
+
+static unsigned int ci_dbg;
+module_param(ci_dbg, int, 0644);
+MODULE_PARM_DESC(ci_dbg, "Enable CI debugging");
+
+#define ci_dbg_print(args...) \
+ do { \
+ if (ci_dbg) \
+ printk(KERN_DEBUG args); \
+ } while (0)
+
+/* stores all private variables for communication with CI */
+struct netup_ci_state {
+ struct dvb_ca_en50221 ca;
+ struct mutex ca_mutex;
+ struct i2c_adapter *i2c_adap;
+ u8 ci_i2c_addr;
+ int status;
+ struct work_struct work;
+ void *priv;
+};
+
+struct mutex gpio_mutex;/* Two CiMax's uses same GPIO lines */
+
+int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
+ u8 *buf, int len)
+{
+ int ret;
+ struct i2c_msg msg[] = {
+ {
+ .addr = addr,
+ .flags = 0,
+ .buf = &reg,
+ .len = 1
+ }, {
+ .addr = addr,
+ .flags = I2C_M_RD,
+ .buf = buf,
+ .len = len
+ }
+ };
+
+ ret = i2c_transfer(i2c_adap, msg, 2);
+
+ if (ret != 2) {
+ ci_dbg_print("%s: i2c read error, Reg = 0x%02x, Status = %d\n",
+ __func__, reg, ret);
+
+ return -1;
+ }
+
+ ci_dbg_print("%s: i2c read Addr=0x%04x, Reg = 0x%02x, data = %02x\n",
+ __func__, addr, reg, buf[0]);
+
+ return 0;
+}
+
+int netup_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
+ u8 *buf, int len)
+{
+ int ret;
+ u8 buffer[len + 1];
+
+ struct i2c_msg msg = {
+ .addr = addr,
+ .flags = 0,
+ .buf = &buffer[0],
+ .len = len + 1
+ };
+
+ buffer[0] = reg;
+ memcpy(&buffer[1], buf, len);
+
+ ret = i2c_transfer(i2c_adap, &msg, 1);
+
+ if (ret != 1) {
+ ci_dbg_print("%s: i2c write error, Reg=[0x%02x], Status=%d\n",
+ __func__, reg, ret);
+ return -1;
+ }
+
+ return 0;
+}
+
+int netup_ci_get_mem(struct cx23885_dev *dev)
+{
+ int mem;
+ unsigned long timeout = jiffies + msecs_to_jiffies(1);
+
+ for (;;) {
+ mem = cx_read(MC417_RWD);
+ if ((mem & NETUP_ACK) == 0)
+ break;
+ if (time_after(jiffies, timeout))
+ break;
+ udelay(1);
+ }
+
+ cx_set(MC417_RWD, NETUP_CTRL_OFF);
+
+ return mem & 0xff;
+}
+
+int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
+ u8 flag, u8 read, int addr, u8 data)
+{
+ struct netup_ci_state *state = en50221->data;
+ struct cx23885_tsport *port = state->priv;
+ struct cx23885_dev *dev = port->dev;
+
+ u8 store;
+ int mem;
+ int ret;
+
+ if (0 != slot)
+ return -EINVAL;
+
+ ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &store, 1);
+ if (ret != 0)
+ return ret;
+
+ store &= ~0x0c;
+ store |= flag;
+
+ ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &store, 1);
+ if (ret != 0)
+ return ret;
+
+ mutex_lock(&gpio_mutex);
+
+ /* write addr */
+ cx_write(MC417_OEN, NETUP_EN_ALL);
+ cx_write(MC417_RWD, NETUP_CTRL_OFF |
+ NETUP_ADLO | (0xff & addr));
+ cx_clear(MC417_RWD, NETUP_ADLO);
+ cx_write(MC417_RWD, NETUP_CTRL_OFF |
+ NETUP_ADHI | (0xff & (addr >> 8)));
+ cx_clear(MC417_RWD, NETUP_ADHI);
+
+ if (read) /* data in */
+ cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA);
+ else /* data out */
+ cx_write(MC417_RWD, NETUP_CTRL_OFF | data);
+
+ /* choose chip */
+ cx_clear(MC417_RWD,
+ (state->ci_i2c_addr == 0x40) ? NETUP_CS0 : NETUP_CS1);
+ /* read/write */
+ cx_clear(MC417_RWD, (read) ? NETUP_RD : NETUP_WR);
+ mem = netup_ci_get_mem(dev);
+
+ mutex_unlock(&gpio_mutex);
+
+ if (!read)
+ if (mem < 0)
+ return -EREMOTEIO;
+
+ ci_dbg_print("%s: %s: addr=[0x%02x], %s=%x\n", __func__,
+ (read) ? "read" : "write", addr,
+ (flag == NETUP_CI_CTL) ? "ctl" : "mem",
+ (read) ? mem : data);
+
+ if (read)
+ return mem;
+
+ return 0;
+}
+
+int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
+ int slot, int addr)
+{
+ return netup_ci_op_cam(en50221, slot, 0, NETUP_CI_RD, addr, 0);
+}
+
+int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
+ int slot, int addr, u8 data)
+{
+ return netup_ci_op_cam(en50221, slot, 0, 0, addr, data);
+}
+
+int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
+{
+ return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL,
+ NETUP_CI_RD, addr, 0);
+}
+
+int netup_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot,
+ u8 addr, u8 data)
+{
+ return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL, 0, addr, data);
+}
+
+int netup_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
+{
+ struct netup_ci_state *state = en50221->data;
+ u8 buf = 0x80;
+ int ret;
+
+ if (0 != slot)
+ return -EINVAL;
+
+ udelay(500);
+ ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &buf, 1);
+
+ if (ret != 0)
+ return ret;
+
+ udelay(500);
+
+ buf = 0x00;
+ ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &buf, 1);
+
+ msleep(1000);
+ dvb_ca_en50221_camready_irq(&state->ca, 0);
+
+ return 0;
+
+}
+
+int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
+{
+ /* not implemented */
+ return 0;
+}
+
+int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot)
+{
+ struct netup_ci_state *state = en50221->data;
+ u8 buf = 0x60;
+
+ if (0 != slot)
+ return -EINVAL;
+
+ return netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &buf, 1);
+}
+
+/* work handler */
+static void netup_read_ci_status(struct work_struct *work)
+{
+ struct netup_ci_state *state =
+ container_of(work, struct netup_ci_state, work);
+ u8 buf[33];
+ int ret;
+
+ ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &buf[0], 33);
+
+ if (ret != 0)
+ return;
+
+ ci_dbg_print("%s: Slot Status Addr=[0x%04x], Reg=[0x%02x], data=%02x, "
+ "TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0],
+ buf[32]);
+
+ if (buf[0] && 1)
+ state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
+ DVB_CA_EN50221_POLL_CAM_READY;
+ else
+ state->status = 0;
+}
+
+/* CI irq handler */
+int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status)
+{
+ struct cx23885_tsport *port = NULL;
+ struct netup_ci_state *state = NULL;
+
+ if (pci_status & PCI_MSK_GPIO0)
+ port = &dev->ts1;
+ else if (pci_status & PCI_MSK_GPIO1)
+ port = &dev->ts2;
+ else /* who calls ? */
+ return 0;
+
+ state = port->port_priv;
+
+ schedule_work(&state->work);
+
+ return 1;
+}
+
+int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open)
+{
+ struct netup_ci_state *state = en50221->data;
+
+ if (0 != slot)
+ return -EINVAL;
+
+ return state->status;
+}
+
+int netup_ci_init(struct cx23885_tsport *port)
+{
+ struct netup_ci_state *state;
+ u8 cimax_init[34] = {
+ 0x00, /* module A control*/
+ 0x00, /* auto select mask high A */
+ 0x00, /* auto select mask low A */
+ 0x00, /* auto select pattern high A */
+ 0x00, /* auto select pattern low A */
+ 0x44, /* memory access time A */
+ 0x00, /* invert input A */
+ 0x00, /* RFU */
+ 0x00, /* RFU */
+ 0x00, /* module B control*/
+ 0x00, /* auto select mask high B */
+ 0x00, /* auto select mask low B */
+ 0x00, /* auto select pattern high B */
+ 0x00, /* auto select pattern low B */
+ 0x44, /* memory access time B */
+ 0x00, /* invert input B */
+ 0x00, /* RFU */
+ 0x00, /* RFU */
+ 0x00, /* auto select mask high Ext */
+ 0x00, /* auto select mask low Ext */
+ 0x00, /* auto select pattern high Ext */
+ 0x00, /* auto select pattern low Ext */
+ 0x00, /* RFU */
+ 0x02, /* destination - module A */
+ 0x01, /* power on (use it like store place) */
+ 0x00, /* RFU */
+ 0x00, /* int status read only */
+ 0x01, /* all int unmasked */
+ 0x04, /* int config */
+ 0x00, /* USCG1 */
+ 0x04, /* ack active low */
+ 0x00, /* LOCK = 0 */
+ 0x33, /* serial mode, rising in, rising out, MSB first*/
+ 0x31, /* syncronization */
+ };
+ int ret;
+
+ ci_dbg_print("%s\n", __func__);
+ state = kzalloc(sizeof(struct netup_ci_state), GFP_KERNEL);
+ if (!state) {
+ ci_dbg_print("%s: Unable create CI structure!\n", __func__);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ port->port_priv = state;
+
+ switch (port->nr) {
+ case 1:
+ state->ci_i2c_addr = 0x40;
+ mutex_init(&gpio_mutex);
+ break;
+ case 2:
+ state->ci_i2c_addr = 0x41;
+ break;
+ }
+
+ state->i2c_adap = &port->dev->i2c_bus[0].i2c_adap;
+ state->ca.owner = THIS_MODULE;
+ state->ca.read_attribute_mem = netup_ci_read_attribute_mem;
+ state->ca.write_attribute_mem = netup_ci_write_attribute_mem;
+ state->ca.read_cam_control = netup_ci_read_cam_ctl;
+ state->ca.write_cam_control = netup_ci_write_cam_ctl;
+ state->ca.slot_reset = netup_ci_slot_reset;
+ state->ca.slot_shutdown = netup_ci_slot_shutdown;
+ state->ca.slot_ts_enable = netup_ci_slot_ts_ctl;
+ state->ca.poll_slot_status = netup_poll_ci_slot_status;
+ state->ca.data = state;
+ state->priv = port;
+
+ ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &cimax_init[0], 34);
+ /* lock registers */
+ ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0x1f, &cimax_init[0x18], 1);
+ /* power on slots */
+ ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0x18, &cimax_init[0x18], 1);
+
+ if (0 != ret)
+ goto err;
+
+ ret = dvb_ca_en50221_init(&port->frontends.adapter,
+ &state->ca,
+ /* flags */ 0,
+ /* n_slots */ 1);
+ if (0 != ret)
+ goto err;
+
+ INIT_WORK(&state->work, netup_read_ci_status);
+
+ ci_dbg_print("%s: CI initialized!\n", __func__);
+
+ return 0;
+err:
+ ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret);
+ kfree(state);
+ return ret;
+}
+
+void netup_ci_exit(struct cx23885_tsport *port)
+{
+ struct netup_ci_state *state;
+
+ if (NULL == port)
+ return;
+
+ state = (struct netup_ci_state *)port->port_priv;
+ if (NULL == state)
+ return;
+
+ if (NULL == state->ca.data)
+ return;
+
+ dvb_ca_en50221_release(&state->ca);
+ kfree(state);
+}
diff --git a/drivers/media/video/cx23885/cimax2.h b/drivers/media/video/cx23885/cimax2.h
new file mode 100644
index 000000000000..518744a4c8a5
--- /dev/null
+++ b/drivers/media/video/cx23885/cimax2.h
@@ -0,0 +1,47 @@
+/*
+ * cimax2.h
+ *
+ * CIMax(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef CIMAX2_H
+#define CIMAX2_H
+#include "dvb_ca_en50221.h"
+
+extern int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
+ int slot, int addr);
+extern int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
+ int slot, int addr, u8 data);
+extern int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221,
+ int slot, u8 addr);
+extern int netup_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221,
+ int slot, u8 addr, u8 data);
+extern int netup_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot);
+extern int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot);
+extern int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot);
+extern int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status);
+extern int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221,
+ int slot, int open);
+extern int netup_ci_init(struct cx23885_tsport *port);
+extern void netup_ci_exit(struct cx23885_tsport *port);
+
+#endif
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index bfe25841dbf4..6f5df90af93e 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -896,7 +896,7 @@ static int cx23885_load_firmware(struct cx23885_dev *dev)
if (retval != 0) {
printk(KERN_ERR
"ERROR: Hotplug firmware request failed (%s).\n",
- CX2341X_FIRM_ENC_FILENAME);
+ CX23885_FIRM_IMAGE_NAME);
printk(KERN_ERR "Please fix your hotplug setup, the board will "
"not work without firmware loaded!\n");
return -1;
@@ -1198,21 +1198,16 @@ static int vidioc_enum_input(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_input *input;
- unsigned int n;
+ int n;
- n = i->index;
-
- if (n >= 4)
+ if (i->index >= 4)
return -EINVAL;
- input = &cx23885_boards[dev->board].input[n];
+ input = &cx23885_boards[dev->board].input[i->index];
if (input->type == 0)
return -EINVAL;
- memset(i, 0, sizeof(*i));
- i->index = n;
-
/* FIXME
* strcpy(i->name, input->name); */
strcpy(i->name, "unset");
@@ -1255,10 +1250,8 @@ static int vidioc_g_tuner(struct file *file, void *priv,
return -EINVAL;
if (0 != t->index)
return -EINVAL;
- memset(t, 0, sizeof(*t));
strcpy(t->name, "Television");
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t);
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);
+ call_all(dev, tuner, g_tuner, t);
dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
@@ -1275,7 +1268,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
return -EINVAL;
/* Update the A/V core */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t);
+ call_all(dev, tuner, s_tuner, t);
return 0;
}
@@ -1286,14 +1279,12 @@ static int vidioc_g_frequency(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- memset(f, 0, sizeof(*f));
if (UNSET == dev->tuner_type)
return -EINVAL;
f->type = V4L2_TUNER_ANALOG_TV;
f->frequency = dev->freq;
- /* Assumption that tuner is always on bus 1 */
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+ call_all(dev, tuner, g_frequency, f);
return 0;
}
@@ -1320,8 +1311,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
return -EINVAL;
dev->freq = f->frequency;
- /* Assumption that tuner is always on bus 1 */
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+ call_all(dev, tuner, s_frequency, f);
cx23885_initialize_codec(dev);
@@ -1335,7 +1325,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
struct cx23885_dev *dev = fh->dev;
/* Update the A/V core */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl);
+ call_all(dev, core, s_ctrl, ctl);
return 0;
}
@@ -1346,7 +1336,6 @@ static int vidioc_querycap(struct file *file, void *priv,
struct cx23885_dev *dev = fh->dev;
struct cx23885_tsport *tsport = &dev->ts1;
- memset(cap, 0, sizeof(*cap));
strcpy(cap->driver, dev->name);
strlcpy(cap->card, cx23885_boards[tsport->dev->board].name,
sizeof(cap->card));
@@ -1366,16 +1355,10 @@ static int vidioc_querycap(struct file *file, void *priv,
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- int index;
-
- index = f->index;
- if (index != 0)
+ if (f->index != 0)
return -EINVAL;
- memset(f, 0, sizeof(*f));
- f->index = index;
strlcpy(f->description, "MPEG", sizeof(f->description));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->pixelformat = V4L2_PIX_FMT_MPEG;
return 0;
@@ -1387,8 +1370,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- memset(f, 0, sizeof(*f));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage =
@@ -1408,12 +1389,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage =
dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.sizeimage =
f->fmt.pix.colorspace = 0;
dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
dev->ts1.width, dev->ts1.height, fh->mpegq.field);
@@ -1426,7 +1405,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage =
@@ -1543,12 +1521,7 @@ static int vidioc_log_status(struct file *file, void *priv)
printk(KERN_INFO
"%s/2: ============ START LOG STATUS ============\n",
dev->name);
- cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS,
- NULL);
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS,
- NULL);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS,
- NULL);
+ call_all(dev, core, log_status);
cx2341x_log_status(&dev->mpeg_params, name);
printk(KERN_INFO
"%s/2: ============= END LOG STATUS =============\n",
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index caa098beeecf..5e4b7e790d94 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -27,6 +27,7 @@
#include "cx23885.h"
#include "tuner-xc2028.h"
+#include "netup-init.h"
/* ------------------------------------------------------------------ */
/* board config info */
@@ -162,6 +163,24 @@ struct cx23885_board cx23885_boards[] = {
.name = "Compro VideoMate E650F",
.portc = CX23885_MPEG_DVB,
},
+ [CX23885_BOARD_TBS_6920] = {
+ .name = "TurboSight TBS 6920",
+ .portb = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_TEVII_S470] = {
+ .name = "TeVii S470",
+ .portb = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_DVBWORLD_2005] = {
+ .name = "DVBWorld DVB-S2 2005",
+ .portb = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_NETUP_DUAL_DVBS2_CI] = {
+ .cimax = 1,
+ .name = "NetUP Dual DVB-S2 CI",
+ .portb = CX23885_MPEG_DVB,
+ .portc = CX23885_MPEG_DVB,
+ },
};
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
@@ -245,6 +264,22 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x185b,
.subdevice = 0xe800,
.card = CX23885_BOARD_COMPRO_VIDEOMATE_E650F,
+ }, {
+ .subvendor = 0x6920,
+ .subdevice = 0x8888,
+ .card = CX23885_BOARD_TBS_6920,
+ }, {
+ .subvendor = 0xd470,
+ .subdevice = 0x9022,
+ .card = CX23885_BOARD_TEVII_S470,
+ }, {
+ .subvendor = 0x0001,
+ .subdevice = 0x2005,
+ .card = CX23885_BOARD_DVBWORLD_2005,
+ }, {
+ .subvendor = 0x1b55,
+ .subdevice = 0x2a2c,
+ .card = CX23885_BOARD_NETUP_DUAL_DVBS2_CI,
},
};
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -552,6 +587,38 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
mdelay(20);
cx_set(GP0_IO, 0x00040004);
break;
+ case CX23885_BOARD_TBS_6920:
+ case CX23885_BOARD_TEVII_S470:
+ cx_write(MC417_CTL, 0x00000036);
+ cx_write(MC417_OEN, 0x00001000);
+ cx_write(MC417_RWD, 0x00001800);
+ break;
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ /* GPIO-0 INTA from CiMax1
+ GPIO-1 INTB from CiMax2
+ GPIO-2 reset chips
+ GPIO-3 to GPIO-10 data/addr for CA
+ GPIO-11 ~CS0 to CiMax1
+ GPIO-12 ~CS1 to CiMax2
+ GPIO-13 ADL0 load LSB addr
+ GPIO-14 ADL1 load MSB addr
+ GPIO-15 ~RDY from CiMax
+ GPIO-17 ~RD to CiMax
+ GPIO-18 ~WR to CiMax
+ */
+ cx_set(GP0_IO, 0x00040000); /* GPIO as out */
+ /* GPIO1 and GPIO2 as INTA and INTB from CiMaxes, reset low */
+ cx_clear(GP0_IO, 0x00030004);
+ mdelay(100);/* reset delay */
+ cx_set(GP0_IO, 0x00040004); /* GPIO as out, reset high */
+ cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */
+ /* GPIO-15 IN as ~ACK, rest as OUT */
+ cx_write(MC417_OEN, 0x00001000);
+ /* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */
+ cx_write(MC417_RWD, 0x0000c300);
+ /* enable irq */
+ cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
+ break;
}
}
@@ -632,6 +699,21 @@ void cx23885_card_setup(struct cx23885_dev *dev)
ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
break;
+ case CX23885_BOARD_TEVII_S470:
+ case CX23885_BOARD_TBS_6920:
+ case CX23885_BOARD_DVBWORLD_2005:
+ ts1->gen_ctrl_val = 0x5; /* Parallel */
+ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+ break;
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
+ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+ ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
+ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+ break;
case CX23885_BOARD_HAUPPAUGE_HVR1250:
case CX23885_BOARD_HAUPPAUGE_HVR1500:
case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
@@ -656,7 +738,17 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_HAUPPAUGE_HVR1700:
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
- request_module("cx25840");
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->i2c_bus[2].i2c_adap,
+ "cx25840", "cx25840", 0x88 >> 1);
+ v4l2_subdev_call(dev->sd_cx25840, core, init, 0);
+ break;
+ }
+
+ /* AUX-PLL 27MHz CLK */
+ switch (dev->board) {
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ netup_initialize(dev);
break;
}
}
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 8f6fb2add7de..dc7fff22cfdd 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -31,6 +31,7 @@
#include <asm/div64.h>
#include "cx23885.h"
+#include "cimax2.h"
MODULE_DESCRIPTION("Driver for cx23885 based TV cards");
MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -791,6 +792,8 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
dev->pci_bus = dev->pci->bus->number;
dev->pci_slot = PCI_SLOT(dev->pci->devfn);
dev->pci_irqmask = 0x001f00;
+ if (cx23885_boards[dev->board].cimax > 0)
+ dev->pci_irqmask |= 0x01800000; /* for CiMaxes */
/* External Master 1 Bus */
dev->i2c_bus[0].nr = 0;
@@ -872,7 +875,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
cx23885_i2c_register(&dev->i2c_bus[1]);
cx23885_i2c_register(&dev->i2c_bus[2]);
cx23885_card_setup(dev);
- cx23885_call_i2c_clients(&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL);
+ call_all(dev, core, s_standby, 0);
cx23885_ir_init(dev);
if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
@@ -1643,7 +1646,9 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
(pci_status & PCI_MSK_VID_B) ||
(pci_status & PCI_MSK_VID_A) ||
(pci_status & PCI_MSK_AUD_INT) ||
- (pci_status & PCI_MSK_AUD_EXT)) {
+ (pci_status & PCI_MSK_AUD_EXT) ||
+ (pci_status & PCI_MSK_GPIO0) ||
+ (pci_status & PCI_MSK_GPIO1)) {
if (pci_status & PCI_MSK_RISC_RD)
dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n",
@@ -1685,8 +1690,20 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n",
PCI_MSK_AUD_EXT);
+ if (pci_status & PCI_MSK_GPIO0)
+ dprintk(7, " (PCI_MSK_GPIO0 0x%08x)\n",
+ PCI_MSK_GPIO0);
+
+ if (pci_status & PCI_MSK_GPIO1)
+ dprintk(7, " (PCI_MSK_GPIO1 0x%08x)\n",
+ PCI_MSK_GPIO1);
}
+ if (cx23885_boards[dev->board].cimax > 0 &&
+ ((pci_status & PCI_MSK_GPIO0) || (pci_status & PCI_MSK_GPIO1)))
+ /* handled += cx23885_irq_gpio(dev, pci_status); */
+ handled += netup_ci_slot_status(dev, pci_status);
+
if (ts1_status) {
if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
handled += cx23885_irq_ts(ts1, ts1_status);
@@ -1722,16 +1739,20 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
if (NULL == dev)
return -ENOMEM;
+ err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
+ if (err < 0)
+ goto fail_free;
+
/* pci init */
dev->pci = pci_dev;
if (pci_enable_device(pci_dev)) {
err = -EIO;
- goto fail_free;
+ goto fail_unreg;
}
if (cx23885_dev_setup(dev) < 0) {
err = -EINVAL;
- goto fail_free;
+ goto fail_unreg;
}
/* print pci info */
@@ -1758,11 +1779,18 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
goto fail_irq;
}
- pci_set_drvdata(pci_dev, dev);
+ switch (dev->board) {
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ cx_set(PCI_INT_MSK, 0x01800000); /* for NetUP */
+ break;
+ }
+
return 0;
fail_irq:
cx23885_dev_unregister(dev);
+fail_unreg:
+ v4l2_device_unregister(&dev->v4l2_dev);
fail_free:
kfree(dev);
return err;
@@ -1770,7 +1798,8 @@ fail_free:
static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
{
- struct cx23885_dev *dev = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct cx23885_dev *dev = to_cx23885(v4l2_dev);
cx23885_shutdown(dev);
@@ -1778,13 +1807,13 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
/* unregister stuff */
free_irq(pci_dev->irq, dev);
- pci_set_drvdata(pci_dev, NULL);
mutex_lock(&devlist);
list_del(&dev->devlist);
mutex_unlock(&devlist);
cx23885_dev_unregister(dev);
+ v4l2_device_unregister(v4l2_dev);
kfree(dev);
}
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 1c454128a9df..d43c74396767 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -30,6 +30,7 @@
#include "cx23885.h"
#include <media/v4l2-common.h>
+#include "dvb_ca_en50221.h"
#include "s5h1409.h"
#include "s5h1411.h"
#include "mt2131.h"
@@ -43,6 +44,13 @@
#include "dib7000p.h"
#include "dibx000_common.h"
#include "zl10353.h"
+#include "stv0900.h"
+#include "stv6110.h"
+#include "lnbh24.h"
+#include "cx24116.h"
+#include "cimax2.h"
+#include "netup-eeprom.h"
+#include "netup-init.h"
static unsigned int debug;
@@ -308,11 +316,63 @@ static struct zl10353_config dvico_fusionhdtv_xc3028 = {
.no_tuner = 1,
};
+static struct stv0900_config netup_stv0900_config = {
+ .demod_address = 0x68,
+ .xtal = 27000000,
+ .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
+ .diseqc_mode = 2,/* 2/3 PWM */
+ .path1_mode = 2,/*Serial continues clock */
+ .path2_mode = 2,/*Serial continues clock */
+ .tun1_maddress = 0,/* 0x60 */
+ .tun2_maddress = 3,/* 0x63 */
+ .tun1_adc = 1,/* 1 Vpp */
+ .tun2_adc = 1,/* 1 Vpp */
+};
+
+static struct stv6110_config netup_stv6110_tunerconfig_a = {
+ .i2c_address = 0x60,
+ .mclk = 27000000,
+ .iq_wiring = 0,
+};
+
+static struct stv6110_config netup_stv6110_tunerconfig_b = {
+ .i2c_address = 0x63,
+ .mclk = 27000000,
+ .iq_wiring = 1,
+};
+
+static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+ struct cx23885_tsport *port = fe->dvb->priv;
+ struct cx23885_dev *dev = port->dev;
+
+ if (voltage == SEC_VOLTAGE_18)
+ cx_write(MC417_RWD, 0x00001e00);/* GPIO-13 high */
+ else if (voltage == SEC_VOLTAGE_13)
+ cx_write(MC417_RWD, 0x00001a00);/* GPIO-13 low */
+ else
+ cx_write(MC417_RWD, 0x00001800);/* GPIO-12 low */
+ return 0;
+}
+
+static struct cx24116_config tbs_cx24116_config = {
+ .demod_address = 0x05,
+};
+
+static struct cx24116_config tevii_cx24116_config = {
+ .demod_address = 0x55,
+};
+
+static struct cx24116_config dvbworld_cx24116_config = {
+ .demod_address = 0x05,
+};
+
static int dvb_register(struct cx23885_tsport *port)
{
struct cx23885_dev *dev = port->dev;
struct cx23885_i2c *i2c_bus = NULL;
struct videobuf_dvb_frontend *fe0;
+ int ret;
/* Get the first frontend */
fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
@@ -526,6 +586,78 @@ static int dvb_register(struct cx23885_tsport *port)
fe->ops.tuner_ops.set_config(fe, &ctl);
}
break;
+ case CX23885_BOARD_TBS_6920:
+ i2c_bus = &dev->i2c_bus[0];
+
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &tbs_cx24116_config,
+ &i2c_bus->i2c_adap);
+ if (fe0->dvb.frontend != NULL)
+ fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+
+ break;
+ case CX23885_BOARD_TEVII_S470:
+ i2c_bus = &dev->i2c_bus[1];
+
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &tevii_cx24116_config,
+ &i2c_bus->i2c_adap);
+ if (fe0->dvb.frontend != NULL)
+ fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+
+ break;
+ case CX23885_BOARD_DVBWORLD_2005:
+ i2c_bus = &dev->i2c_bus[1];
+
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &dvbworld_cx24116_config,
+ &i2c_bus->i2c_adap);
+ break;
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ i2c_bus = &dev->i2c_bus[0];
+ switch (port->nr) {
+ /* port B */
+ case 1:
+ fe0->dvb.frontend = dvb_attach(stv0900_attach,
+ &netup_stv0900_config,
+ &i2c_bus->i2c_adap, 0);
+ if (fe0->dvb.frontend != NULL) {
+ if (dvb_attach(stv6110_attach,
+ fe0->dvb.frontend,
+ &netup_stv6110_tunerconfig_a,
+ &i2c_bus->i2c_adap)) {
+ if (!dvb_attach(lnbh24_attach,
+ fe0->dvb.frontend,
+ &i2c_bus->i2c_adap,
+ LNBH24_PCL, 0, 0x09))
+ printk(KERN_ERR
+ "No LNBH24 found!\n");
+
+ }
+ }
+ break;
+ /* port C */
+ case 2:
+ fe0->dvb.frontend = dvb_attach(stv0900_attach,
+ &netup_stv0900_config,
+ &i2c_bus->i2c_adap, 1);
+ if (fe0->dvb.frontend != NULL) {
+ if (dvb_attach(stv6110_attach,
+ fe0->dvb.frontend,
+ &netup_stv6110_tunerconfig_b,
+ &i2c_bus->i2c_adap)) {
+ if (!dvb_attach(lnbh24_attach,
+ fe0->dvb.frontend,
+ &i2c_bus->i2c_adap,
+ LNBH24_PCL, 0, 0x0a))
+ printk(KERN_ERR
+ "No LNBH24 found!\n");
+
+ }
+ }
+ break;
+ }
+ break;
default:
printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
" isn't supported yet\n",
@@ -541,15 +673,39 @@ static int dvb_register(struct cx23885_tsport *port)
fe0->dvb.frontend->callback = cx23885_tuner_callback;
/* Put the analog decoder in standby to keep it quiet */
- cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
+ call_all(dev, core, s_standby, 0);
if (fe0->dvb.frontend->ops.analog_ops.standby)
fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
/* register everything */
- return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
+ ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
&dev->pci->dev, adapter_nr, 0);
+ /* init CI & MAC */
+ switch (dev->board) {
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: {
+ static struct netup_card_info cinfo;
+
+ netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo);
+ memcpy(port->frontends.adapter.proposed_mac,
+ cinfo.port[port->nr - 1].mac, 6);
+ printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC="
+ "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ port->nr,
+ port->frontends.adapter.proposed_mac[0],
+ port->frontends.adapter.proposed_mac[1],
+ port->frontends.adapter.proposed_mac[2],
+ port->frontends.adapter.proposed_mac[3],
+ port->frontends.adapter.proposed_mac[4],
+ port->frontends.adapter.proposed_mac[5]);
+
+ netup_ci_init(port);
+ break;
+ }
+ }
+
+ return ret;
}
int cx23885_dvb_register(struct cx23885_tsport *port)
@@ -622,6 +778,12 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port)
if (fe0->dvb.frontend)
videobuf_dvb_unregister_bus(&port->frontends);
+ switch (port->dev->board) {
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ netup_ci_exit(port);
+ break;
+ }
+
return 0;
}
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index bb7f71a1fcbe..3421bd12056a 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -268,64 +268,6 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap,
return retval;
}
-static int attach_inform(struct i2c_client *client)
-{
- struct cx23885_i2c *bus = i2c_get_adapdata(client->adapter);
- struct cx23885_dev *dev = bus->dev;
- struct tuner_setup tun_setup;
-
- dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr, client->name);
-
- if (!client->driver->command)
- return 0;
-
- if (dev->tuner_type != UNSET) {
-
- dprintk(1, "%s (tuner) i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr,
- client->name);
-
- if ((dev->tuner_addr == ADDR_UNSET) ||
- (dev->tuner_addr == client->addr)) {
-
- dprintk(1, "%s (tuner || addr UNSET)\n",
- client->driver->driver.name);
-
- dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name,
- client->addr, client->name);
-
- tun_setup.mode_mask = T_ANALOG_TV;
- tun_setup.type = dev->tuner_type;
- tun_setup.addr = dev->tuner_addr;
-
- client->driver->command(client, TUNER_SET_TYPE_ADDR,
- &tun_setup);
- }
- }
-
- return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
- struct cx23885_dev *dev = i2c_get_adapdata(client->adapter);
-
- dprintk(1, "i2c detach [client=%s]\n", client->name);
-
- return 0;
-}
-
-void cx23885_call_i2c_clients(struct cx23885_i2c *bus,
- unsigned int cmd, void *arg)
-{
- if (bus->i2c_rc != 0)
- return;
-
- i2c_clients_command(&bus->i2c_adap, cmd, arg);
-}
-
static u32 cx23885_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
@@ -343,9 +285,6 @@ static struct i2c_adapter cx23885_i2c_adap_template = {
.owner = THIS_MODULE,
.id = I2C_HW_B_CX23885,
.algo = &cx23885_i2c_algo_template,
- .class = I2C_CLASS_TV_ANALOG,
- .client_register = attach_inform,
- .client_unregister = detach_inform,
};
static struct i2c_client cx23885_i2c_client_template = {
@@ -402,15 +341,18 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
bus->i2c_algo.data = bus;
bus->i2c_adap.algo_data = bus;
- i2c_set_adapdata(&bus->i2c_adap, bus);
+ i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
i2c_add_adapter(&bus->i2c_adap);
bus->i2c_client.adapter = &bus->i2c_adap;
if (0 == bus->i2c_rc) {
dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr);
- if (i2c_scan)
+ if (i2c_scan) {
+ printk(KERN_INFO "%s: scan bus %d:\n",
+ dev->name, bus->nr);
do_i2c_scan(dev->name, &bus->i2c_client);
+ }
} else
printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
dev->name, bus->nr);
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
index 20b68a236260..eafbe5226bae 100644
--- a/drivers/media/video/cx23885/cx23885-reg.h
+++ b/drivers/media/video/cx23885/cx23885-reg.h
@@ -212,6 +212,8 @@ Channel manager Data Structure entry = 20 DWORD
#define DEV_CNTRL2 0x00040000
+#define PCI_MSK_GPIO1 (1 << 24)
+#define PCI_MSK_GPIO0 (1 << 23)
#define PCI_MSK_APB_DMA (1 << 12)
#define PCI_MSK_AL_WR (1 << 11)
#define PCI_MSK_AL_RD (1 << 10)
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index eaa11893bfe9..f0ac62c5dc83 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -35,11 +35,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* Include V4L1 specific functions. Should be removed soon */
-#include <linux/videodev.h>
-#endif
-
MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
MODULE_LICENSE("GPL");
@@ -244,6 +239,7 @@ static struct cx23885_ctrl cx23885_ctls[] = {
};
static const int CX23885_CTLS = ARRAY_SIZE(cx23885_ctls);
+/* Must be sorted from low to high control ID! */
static const u32 cx23885_user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
@@ -303,11 +299,7 @@ static int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
dev->tvnorm = norm;
- /* Tell the analog tuner/demods */
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_STD, &norm);
-
- /* Tell the internal A/V decoder */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_STD, &norm);
+ call_all(dev, tuner, s_std, norm);
return 0;
}
@@ -324,8 +316,8 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev,
if (NULL == vfd)
return NULL;
*vfd = *template;
- vfd->minor = -1;
- vfd->parent = &pci->dev;
+ vfd->minor = -1;
+ vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
dev->name, type, cx23885_boards[dev->board].name);
@@ -414,8 +406,7 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
route.input = INPUT(input)->vmux;
/* Tell the internal A/V decoder */
- cx23885_call_i2c_clients(&dev->i2c_bus[2],
- VIDIOC_INT_S_VIDEO_ROUTING, &route);
+ v4l2_subdev_call(dev->sd_cx25840, video, s_routing, &route);
return 0;
}
@@ -891,7 +882,7 @@ static int cx23885_get_control(struct cx23885_dev *dev,
struct v4l2_control *ctl)
{
dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl);
+ call_all(dev, core, g_ctrl, ctl);
return 0;
}
@@ -1005,7 +996,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
fh->vidq.field = f->fmt.pix.field;
dprintk(2, "%s() width=%d height=%d field=%d\n", __func__,
fh->width, fh->height, fh->vidq.field);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_FMT, f);
+ call_all(dev, video, s_fmt, f);
return 0;
}
@@ -1285,7 +1276,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
f->frequency = dev->freq;
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+ call_all(dev, tuner, g_frequency, f);
return 0;
}
@@ -1300,7 +1291,7 @@ static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f)
mutex_lock(&dev->lock);
dev->freq = f->frequency;
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+ call_all(dev, tuner, s_frequency, f);
/* When changing channels it is required to reset TVAUDIO */
msleep(10);
@@ -1334,7 +1325,7 @@ static int vidioc_g_register(struct file *file, void *fh,
if (!v4l2_chip_match_host(&reg->match))
return -EINVAL;
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg);
+ call_all(dev, core, g_register, reg);
return 0;
}
@@ -1347,7 +1338,7 @@ static int vidioc_s_register(struct file *file, void *fh,
if (!v4l2_chip_match_host(&reg->match))
return -EINVAL;
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg);
+ call_all(dev, core, s_register, reg);
return 0;
}
@@ -1528,6 +1519,26 @@ int cx23885_video_register(struct cx23885_dev *dev)
/* Don't enable VBI yet */
cx_set(PCI_INT_MSK, 1);
+ if (TUNER_ABSENT != dev->tuner_type) {
+ struct v4l2_subdev *sd = NULL;
+
+ if (dev->tuner_addr)
+ sd = v4l2_i2c_new_subdev(&dev->i2c_bus[1].i2c_adap,
+ "tuner", "tuner", dev->tuner_addr);
+ else
+ sd = v4l2_i2c_new_probed_subdev(&dev->i2c_bus[1].i2c_adap,
+ "tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV));
+ if (sd) {
+ struct tuner_setup tun_setup;
+
+ tun_setup.mode_mask = T_ANALOG_TV;
+ tun_setup.type = dev->tuner_type;
+ tun_setup.addr = v4l2_i2c_subdev_addr(sd);
+
+ v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
+ }
+ }
+
/* register v4l devices */
dev->video_dev = cx23885_vdev_init(dev, dev->pci,
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 67828029fc69..02d980a29962 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -24,7 +24,7 @@
#include <linux/i2c-algo-bit.h>
#include <linux/kdev_t.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/tuner.h>
#include <media/tveeprom.h>
#include <media/videobuf-dma-sg.h>
@@ -67,6 +67,10 @@
#define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP 11
#define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H 12
#define CX23885_BOARD_COMPRO_VIDEOMATE_E650F 13
+#define CX23885_BOARD_TBS_6920 14
+#define CX23885_BOARD_TEVII_S470 15
+#define CX23885_BOARD_DVBWORLD_2005 16
+#define CX23885_BOARD_NETUP_DUAL_DVBS2_CI 17
/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
#define CX23885_NORMS (\
@@ -184,6 +188,7 @@ struct cx23885_board {
*/
u32 clk_freq;
struct cx23885_input input[MAX_CX23885_INPUT];
+ int cimax; /* for NetUP */
};
struct cx23885_subid {
@@ -266,11 +271,13 @@ struct cx23885_tsport {
/* Allow a single tsport to have multiple frontends */
u32 num_frontends;
+ void *port_priv;
};
struct cx23885_dev {
struct list_head devlist;
atomic_t refcount;
+ struct v4l2_device v4l2_dev;
/* pci stuff */
struct pci_dev *pci;
@@ -316,6 +323,7 @@ struct cx23885_dev {
unsigned int radio_type;
unsigned char radio_addr;
unsigned int has_radio;
+ struct v4l2_subdev *sd_cx25840;
/* V4l */
u32 freq;
@@ -336,6 +344,14 @@ struct cx23885_dev {
};
+static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct cx23885_dev, v4l2_dev);
+}
+
+#define call_all(dev, o, f, args...) \
+ v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
+
extern struct list_head cx23885_devlist;
#define SRAM_CH01 0 /* Video A */
@@ -452,8 +468,6 @@ extern struct videobuf_queue_ops cx23885_vbi_qops;
/* cx23885-i2c.c */
extern int cx23885_i2c_register(struct cx23885_i2c *bus);
extern int cx23885_i2c_unregister(struct cx23885_i2c *bus);
-extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd,
- void *arg);
extern void cx23885_av_clk(struct cx23885_dev *dev, int enable);
/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/cx23885/netup-eeprom.c b/drivers/media/video/cx23885/netup-eeprom.c
new file mode 100644
index 000000000000..042bbbbd48f8
--- /dev/null
+++ b/drivers/media/video/cx23885/netup-eeprom.c
@@ -0,0 +1,107 @@
+
+/*
+ * netup-eeprom.c
+ *
+ * 24LC02 EEPROM driver in conjunction with NetUP Dual DVB-S2 CI card
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#
+#include "cx23885.h"
+#include "netup-eeprom.h"
+
+#define EEPROM_I2C_ADDR 0x50
+
+int netup_eeprom_read(struct i2c_adapter *i2c_adap, u8 addr)
+{
+ int ret;
+ unsigned char buf[2];
+
+ /* Read from EEPROM */
+ struct i2c_msg msg[] = {
+ {
+ .addr = EEPROM_I2C_ADDR,
+ .flags = 0,
+ .buf = &buf[0],
+ .len = 1
+ }, {
+ .addr = EEPROM_I2C_ADDR,
+ .flags = I2C_M_RD,
+ .buf = &buf[1],
+ .len = 1
+ }
+
+ };
+
+ buf[0] = addr;
+ buf[1] = 0x0;
+
+ ret = i2c_transfer(i2c_adap, msg, 2);
+
+ if (ret != 2) {
+ printk(KERN_ERR "eeprom i2c read error, status=%d\n", ret);
+ return -1;
+ }
+
+ return buf[1];
+};
+
+int netup_eeprom_write(struct i2c_adapter *i2c_adap, u8 addr, u8 data)
+{
+ int ret;
+ unsigned char bufw[2];
+
+ /* Write into EEPROM */
+ struct i2c_msg msg[] = {
+ {
+ .addr = EEPROM_I2C_ADDR,
+ .flags = 0,
+ .buf = &bufw[0],
+ .len = 2
+ }
+ };
+
+ bufw[0] = addr;
+ bufw[1] = data;
+
+ ret = i2c_transfer(i2c_adap, msg, 1);
+
+ if (ret != 1) {
+ printk(KERN_ERR "eeprom i2c write error, status=%d\n", ret);
+ return -1;
+ }
+
+ mdelay(10); /* prophylactic delay, datasheet write cycle time = 5 ms */
+ return 0;
+};
+
+void netup_get_card_info(struct i2c_adapter *i2c_adap,
+ struct netup_card_info *cinfo)
+{
+ int i, j;
+
+ cinfo->rev = netup_eeprom_read(i2c_adap, 13);
+
+ for (i = 0, j = 0; i < 6; i++, j++)
+ cinfo->port[0].mac[j] = netup_eeprom_read(i2c_adap, i);
+
+ for (i = 6, j = 0; i < 12; i++, j++)
+ cinfo->port[1].mac[j] = netup_eeprom_read(i2c_adap, i);
+};
diff --git a/drivers/media/video/cx23885/netup-eeprom.h b/drivers/media/video/cx23885/netup-eeprom.h
new file mode 100644
index 000000000000..13926e18feba
--- /dev/null
+++ b/drivers/media/video/cx23885/netup-eeprom.h
@@ -0,0 +1,42 @@
+/*
+ * netup-eeprom.h
+ *
+ * 24LC02 EEPROM driver in conjunction with NetUP Dual DVB-S2 CI card
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef NETUP_EEPROM_H
+#define NETUP_EEPROM_H
+
+struct netup_port_info {
+ u8 mac[6];/* card MAC address */
+};
+
+struct netup_card_info {
+ struct netup_port_info port[2];/* ports - 1,2 */
+ u8 rev;/* card revision */
+};
+
+extern int netup_eeprom_read(struct i2c_adapter *i2c_adap, u8 addr);
+extern int netup_eeprom_write(struct i2c_adapter *i2c_adap, u8 addr, u8 data);
+extern void netup_get_card_info(struct i2c_adapter *i2c_adap,
+ struct netup_card_info *cinfo);
+
+#endif
diff --git a/drivers/media/video/cx23885/netup-init.c b/drivers/media/video/cx23885/netup-init.c
new file mode 100644
index 000000000000..f4893e69cd89
--- /dev/null
+++ b/drivers/media/video/cx23885/netup-init.c
@@ -0,0 +1,125 @@
+/*
+ * netup-init.c
+ *
+ * NetUP Dual DVB-S2 CI driver
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "cx23885.h"
+
+static void i2c_av_write(struct i2c_adapter *i2c, u16 reg, u8 val)
+{
+ int ret;
+ u8 buf[3];
+ struct i2c_msg msg = {
+ .addr = 0x88 >> 1,
+ .flags = 0,
+ .buf = buf,
+ .len = 3
+ };
+
+ buf[0] = reg >> 8;
+ buf[1] = reg & 0xff;
+ buf[2] = val;
+
+ ret = i2c_transfer(i2c, &msg, 1);
+
+ if (ret != 1)
+ printk(KERN_ERR "%s: i2c write error!\n", __func__);
+}
+
+static void i2c_av_write4(struct i2c_adapter *i2c, u16 reg, u32 val)
+{
+ int ret;
+ u8 buf[6];
+ struct i2c_msg msg = {
+ .addr = 0x88 >> 1,
+ .flags = 0,
+ .buf = buf,
+ .len = 6
+ };
+
+ buf[0] = reg >> 8;
+ buf[1] = reg & 0xff;
+ buf[2] = val & 0xff;
+ buf[3] = (val >> 8) & 0xff;
+ buf[4] = (val >> 16) & 0xff;
+ buf[5] = val >> 24;
+
+ ret = i2c_transfer(i2c, &msg, 1);
+
+ if (ret != 1)
+ printk(KERN_ERR "%s: i2c write error!\n", __func__);
+}
+
+static u8 i2c_av_read(struct i2c_adapter *i2c, u16 reg)
+{
+ int ret;
+ u8 buf[2];
+ struct i2c_msg msg = {
+ .addr = 0x88 >> 1,
+ .flags = 0,
+ .buf = buf,
+ .len = 2
+ };
+
+ buf[0] = reg >> 8;
+ buf[1] = reg & 0xff;
+
+ ret = i2c_transfer(i2c, &msg, 1);
+
+ if (ret != 1)
+ printk(KERN_ERR "%s: i2c write error!\n", __func__);
+
+ msg.flags = I2C_M_RD;
+ msg.len = 1;
+
+ ret = i2c_transfer(i2c, &msg, 1);
+
+ if (ret != 1)
+ printk(KERN_ERR "%s: i2c read error!\n", __func__);
+
+ return buf[0];
+}
+
+static void i2c_av_and_or(struct i2c_adapter *i2c, u16 reg, unsigned and_mask,
+ u8 or_value)
+{
+ i2c_av_write(i2c, reg, (i2c_av_read(i2c, reg) & and_mask) | or_value);
+}
+/* set 27MHz on AUX_CLK */
+void netup_initialize(struct cx23885_dev *dev)
+{
+ struct cx23885_i2c *i2c_bus = &dev->i2c_bus[2];
+ struct i2c_adapter *i2c = &i2c_bus->i2c_adap;
+
+ /* Stop microcontroller */
+ i2c_av_and_or(i2c, 0x803, ~0x10, 0x00);
+
+ /* Aux PLL frac for 27 MHz */
+ i2c_av_write4(i2c, 0x114, 0xea0eb3);
+
+ /* Aux PLL int for 27 MHz */
+ i2c_av_write4(i2c, 0x110, 0x090319);
+
+ /* start microcontroller */
+ i2c_av_and_or(i2c, 0x803, ~0x10, 0x10);
+}
diff --git a/drivers/media/video/cx23885/netup-init.h b/drivers/media/video/cx23885/netup-init.h
new file mode 100644
index 000000000000..d26ae4b1590e
--- /dev/null
+++ b/drivers/media/video/cx23885/netup-init.h
@@ -0,0 +1,25 @@
+/*
+ * netup-init.h
+ *
+ * NetUP Dual DVB-S2 CI driver
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+extern void netup_initialize(struct cx23885_dev *dev);
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index d199d80ea0a3..93d74bee292a 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -363,75 +363,74 @@ static void set_mute(struct i2c_client *client, int mute)
}
}
-int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
+int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- struct v4l2_control *ctrl = arg;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct cx25840_state *state = to_state(sd);
int retval;
- switch (cmd) {
- case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- if (!state->is_cx25836)
- cx25840_and_or(client, 0x810, ~0x1, 1);
- if (state->aud_input != CX25840_AUDIO_SERIAL) {
- cx25840_and_or(client, 0x803, ~0x10, 0);
- cx25840_write(client, 0x8d3, 0x1f);
- }
- retval = set_audclk_freq(client, *(u32 *)arg);
- if (state->aud_input != CX25840_AUDIO_SERIAL) {
- cx25840_and_or(client, 0x803, ~0x10, 0x10);
- }
- if (!state->is_cx25836)
- cx25840_and_or(client, 0x810, ~0x1, 0);
- return retval;
-
- case VIDIOC_G_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = get_volume(client);
- break;
- case V4L2_CID_AUDIO_BASS:
- ctrl->value = get_bass(client);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- ctrl->value = get_treble(client);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- ctrl->value = get_balance(client);
- break;
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value = get_mute(client);
- break;
- default:
- return -EINVAL;
- }
- break;
+ if (!state->is_cx25836)
+ cx25840_and_or(client, 0x810, ~0x1, 1);
+ if (state->aud_input != CX25840_AUDIO_SERIAL) {
+ cx25840_and_or(client, 0x803, ~0x10, 0);
+ cx25840_write(client, 0x8d3, 0x1f);
+ }
+ retval = set_audclk_freq(client, freq);
+ if (state->aud_input != CX25840_AUDIO_SERIAL)
+ cx25840_and_or(client, 0x803, ~0x10, 0x10);
+ if (!state->is_cx25836)
+ cx25840_and_or(client, 0x810, ~0x1, 0);
+ return retval;
+}
- case VIDIOC_S_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- set_volume(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BASS:
- set_bass(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- set_treble(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- set_balance(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_MUTE:
- set_mute(client, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
- break;
+int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = get_volume(client);
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ ctrl->value = get_bass(client);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ ctrl->value = get_treble(client);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ ctrl->value = get_balance(client);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = get_mute(client);
+ break;
default:
return -EINVAL;
}
+ return 0;
+}
+int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ set_volume(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ set_bass(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ set_treble(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ set_balance(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ set_mute(client, ctrl->value);
+ break;
+ default:
+ return -EINVAL;
+ }
return 0;
}
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 25eb3bec9e5d..737ee4ea8830 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -39,7 +39,7 @@
#include <linux/delay.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include <media/cx25840.h>
#include "cx25840-core.h"
@@ -48,15 +48,12 @@ MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver");
MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford");
MODULE_LICENSE("GPL");
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
-
static int cx25840_debug;
module_param_named(debug,cx25840_debug, int, 0644);
MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]");
-I2C_CLIENT_INSMOD;
/* ----------------------------------------------------------------------- */
@@ -763,7 +760,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
break;
case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
+ if (ctrl->value < -128 || ctrl->value > 127) {
v4l_err(client, "invalid hue setting %d\n", ctrl->value);
return -ERANGE;
}
@@ -778,7 +775,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_MUTE:
if (state->is_cx25836)
return -EINVAL;
- return cx25840_audio(client, VIDIOC_S_CTRL, ctrl);
+ return cx25840_audio_s_ctrl(sd, ctrl);
default:
return -EINVAL;
@@ -815,7 +812,7 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_MUTE:
if (state->is_cx25836)
return -EINVAL;
- return cx25840_audio(client, VIDIOC_G_CTRL, ctrl);
+ return cx25840_audio_g_ctrl(sd, ctrl);
default:
return -EINVAL;
}
@@ -827,11 +824,9 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
switch (fmt->type) {
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx25840_vbi(client, VIDIOC_G_FMT, fmt);
+ return cx25840_vbi_g_fmt(sd, fmt);
default:
return -EINVAL;
}
@@ -893,10 +888,10 @@ static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
break;
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
+ return cx25840_vbi_s_fmt(sd, fmt);
case V4L2_BUF_TYPE_VBI_CAPTURE:
- return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
+ return cx25840_vbi_s_fmt(sd, fmt);
default:
return -EINVAL;
@@ -1101,6 +1096,16 @@ static void log_audio_status(struct i2c_client *client)
/* ----------------------------------------------------------------------- */
+/* This init operation must be called to load the driver's firmware.
+ Without this the audio standard detection will fail and you will
+ only get mono.
+
+ Since loading the firmware is often problematic when the driver is
+ compiled into the kernel I recommend postponing calling this function
+ until the first open of the video device. Another reason for
+ postponing it is that loading this firmware takes a long time (seconds)
+ due to the slow i2c bus speed. So it will speed up the boot process if
+ you can avoid loading the fw as long as the video device isn't used. */
static int cx25840_init(struct v4l2_subdev *sd, u32 val)
{
struct cx25840_state *state = to_state(sd);
@@ -1146,20 +1151,6 @@ static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *
}
#endif
-static int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return cx25840_vbi(client, VIDIOC_INT_DECODE_VBI_LINE, vbi);
-}
-
-static int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return cx25840_audio(client, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freq);
-}
-
static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
{
struct cx25840_state *state = to_state(sd);
@@ -1195,10 +1186,12 @@ static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
switch (qc->id) {
case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
case V4L2_CID_CONTRAST:
case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill_std(qc);
+ return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
default:
break;
}
@@ -1210,10 +1203,11 @@ static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
return v4l2_ctrl_query_fill(qc, 0, 65535,
65535 / 100, state->default_volume);
case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- return v4l2_ctrl_query_fill_std(qc);
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
default:
return -EINVAL;
}
@@ -1380,19 +1374,6 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- /* ignore this command */
- if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG)
- return 0;
-
- /* Old-style drivers rely on initialization on first use, so
- call the init whenever a command is issued to this driver.
- New-style drivers using v4l2_subdev should call init explicitly. */
- cx25840_init(i2c_get_clientdata(client), 0);
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops cx25840_core_ops = {
@@ -1528,8 +1509,6 @@ MODULE_DEVICE_TABLE(i2c, cx25840_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "cx25840",
- .driverid = I2C_DRIVERID_CX25840,
- .command = cx25840_command,
.probe = cx25840_probe,
.remove = cx25840_remove,
.id_table = cx25840_id,
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index be0558277ca3..9ad0eb86ecfd 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -75,11 +75,15 @@ int cx25840_loadfw(struct i2c_client *client);
/* ----------------------------------------------------------------------- */
/* cx25850-audio.c */
-int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg);
void cx25840_audio_set_path(struct i2c_client *client);
+int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
+int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
/* ----------------------------------------------------------------------- */
/* cx25850-vbi.c */
-int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg);
+int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt);
+int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt);
+int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi);
#endif
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
index 03f09b288eb8..35f6592f6c47 100644
--- a/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/drivers/media/video/cx25840/cx25840-vbi.c
@@ -82,199 +82,181 @@ static int decode_vps(u8 * dst, u8 * p)
return err & 0xf0;
}
-int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
+int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- struct v4l2_format *fmt;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct cx25840_state *state = to_state(sd);
struct v4l2_sliced_vbi_format *svbi;
+ static const u16 lcr2vbi[] = {
+ 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
+ 0, V4L2_SLICED_WSS_625, 0, /* 4 */
+ V4L2_SLICED_CAPTION_525, /* 6 */
+ 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
+ 0, 0, 0, 0
+ };
+ int is_pal = !(state->std & V4L2_STD_525_60);
+ int i;
- switch (cmd) {
- case VIDIOC_G_FMT:
- {
- static u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
- 0, V4L2_SLICED_WSS_625, 0, /* 4 */
- V4L2_SLICED_CAPTION_525, /* 6 */
- 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
- 0, 0, 0, 0
- };
- int is_pal = !(state->std & V4L2_STD_525_60);
- int i;
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- memset(svbi, 0, sizeof(*svbi));
- /* we're done if raw VBI is active */
- if ((cx25840_read(client, 0x404) & 0x10) == 0)
- break;
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ memset(svbi, 0, sizeof(*svbi));
+ /* we're done if raw VBI is active */
+ if ((cx25840_read(client, 0x404) & 0x10) == 0)
+ return 0;
- if (is_pal) {
- for (i = 7; i <= 23; i++) {
- u8 v = cx25840_read(client, 0x424 + i - 7);
+ if (is_pal) {
+ for (i = 7; i <= 23; i++) {
+ u8 v = cx25840_read(client, 0x424 + i - 7);
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |=
- svbi->service_lines[0][i] | svbi->service_lines[1][i];
- }
+ svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+ svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+ svbi->service_set |= svbi->service_lines[0][i] |
+ svbi->service_lines[1][i];
}
- else {
- for (i = 10; i <= 21; i++) {
- u8 v = cx25840_read(client, 0x424 + i - 10);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |=
- svbi->service_lines[0][i] | svbi->service_lines[1][i];
- }
+ } else {
+ for (i = 10; i <= 21; i++) {
+ u8 v = cx25840_read(client, 0x424 + i - 10);
+
+ svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+ svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+ svbi->service_set |= svbi->service_lines[0][i] |
+ svbi->service_lines[1][i];
}
- break;
}
+ return 0;
+}
- case VIDIOC_S_FMT:
- {
- int is_pal = !(state->std & V4L2_STD_525_60);
- int vbi_offset = is_pal ? 1 : 0;
- int i, x;
- u8 lcr[24];
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
- fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- /* raw VBI */
- memset(svbi, 0, sizeof(*svbi));
-
- /* Setup standard */
- cx25840_std_setup(client);
-
- /* VBI Offset */
- cx25840_write(client, 0x47f, vbi_offset);
- cx25840_write(client, 0x404, 0x2e);
- break;
- }
-
- for (x = 0; x <= 23; x++)
- lcr[x] = 0x00;
+int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct cx25840_state *state = to_state(sd);
+ struct v4l2_sliced_vbi_format *svbi;
+ int is_pal = !(state->std & V4L2_STD_525_60);
+ int vbi_offset = is_pal ? 1 : 0;
+ int i, x;
+ u8 lcr[24];
+
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
+ fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ /* raw VBI */
+ memset(svbi, 0, sizeof(*svbi));
/* Setup standard */
cx25840_std_setup(client);
- /* Sliced VBI */
- cx25840_write(client, 0x404, 0x32); /* Ancillary data */
- cx25840_write(client, 0x406, 0x13);
+ /* VBI Offset */
cx25840_write(client, 0x47f, vbi_offset);
+ cx25840_write(client, 0x404, 0x2e);
+ return 0;
+ }
- if (is_pal) {
- for (i = 0; i <= 6; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- } else {
- for (i = 0; i <= 9; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
-
- for (i = 22; i <= 23; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- }
-
- for (i = 7; i <= 23; i++) {
- for (x = 0; x <= 1; x++) {
- switch (svbi->service_lines[1-x][i]) {
- case V4L2_SLICED_TELETEXT_B:
- lcr[i] |= 1 << (4 * x);
- break;
- case V4L2_SLICED_WSS_625:
- lcr[i] |= 4 << (4 * x);
- break;
- case V4L2_SLICED_CAPTION_525:
- lcr[i] |= 6 << (4 * x);
- break;
- case V4L2_SLICED_VPS:
- lcr[i] |= 9 << (4 * x);
- break;
- }
- }
- }
+ for (x = 0; x <= 23; x++)
+ lcr[x] = 0x00;
+
+ /* Setup standard */
+ cx25840_std_setup(client);
+
+ /* Sliced VBI */
+ cx25840_write(client, 0x404, 0x32); /* Ancillary data */
+ cx25840_write(client, 0x406, 0x13);
+ cx25840_write(client, 0x47f, vbi_offset);
+
+ if (is_pal) {
+ for (i = 0; i <= 6; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ } else {
+ for (i = 0; i <= 9; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+
+ for (i = 22; i <= 23; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ }
- if (is_pal) {
- for (x = 1, i = 0x424; i <= 0x434; i++, x++) {
- cx25840_write(client, i, lcr[6 + x]);
- }
- }
- else {
- for (x = 1, i = 0x424; i <= 0x430; i++, x++) {
- cx25840_write(client, i, lcr[9 + x]);
- }
- for (i = 0x431; i <= 0x434; i++) {
- cx25840_write(client, i, 0);
+ for (i = 7; i <= 23; i++) {
+ for (x = 0; x <= 1; x++) {
+ switch (svbi->service_lines[1-x][i]) {
+ case V4L2_SLICED_TELETEXT_B:
+ lcr[i] |= 1 << (4 * x);
+ break;
+ case V4L2_SLICED_WSS_625:
+ lcr[i] |= 4 << (4 * x);
+ break;
+ case V4L2_SLICED_CAPTION_525:
+ lcr[i] |= 6 << (4 * x);
+ break;
+ case V4L2_SLICED_VPS:
+ lcr[i] |= 9 << (4 * x);
+ break;
}
}
+ }
- cx25840_write(client, 0x43c, 0x16);
-
- if (is_pal) {
- cx25840_write(client, 0x474, 0x2a);
- } else {
- cx25840_write(client, 0x474, 0x22);
- }
- break;
+ if (is_pal) {
+ for (x = 1, i = 0x424; i <= 0x434; i++, x++)
+ cx25840_write(client, i, lcr[6 + x]);
+ } else {
+ for (x = 1, i = 0x424; i <= 0x430; i++, x++)
+ cx25840_write(client, i, lcr[9 + x]);
+ for (i = 0x431; i <= 0x434; i++)
+ cx25840_write(client, i, 0);
}
- case VIDIOC_INT_DECODE_VBI_LINE:
- {
- struct v4l2_decode_vbi_line *vbi = arg;
- u8 *p = vbi->p;
- int id1, id2, l, err = 0;
+ cx25840_write(client, 0x43c, 0x16);
+ cx25840_write(client, 0x474, is_pal ? 0x2a : 0x22);
+ return 0;
+}
- if (p[0] || p[1] != 0xff || p[2] != 0xff ||
- (p[3] != 0x55 && p[3] != 0x91)) {
- vbi->line = vbi->type = 0;
- break;
- }
+int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
+{
+ struct cx25840_state *state = to_state(sd);
+ u8 *p = vbi->p;
+ int id1, id2, l, err = 0;
+
+ if (p[0] || p[1] != 0xff || p[2] != 0xff ||
+ (p[3] != 0x55 && p[3] != 0x91)) {
+ vbi->line = vbi->type = 0;
+ return 0;
+ }
- p += 4;
- id1 = p[-1];
- id2 = p[0] & 0xf;
- l = p[2] & 0x3f;
- l += state->vbi_line_offset;
- p += 4;
+ p += 4;
+ id1 = p[-1];
+ id2 = p[0] & 0xf;
+ l = p[2] & 0x3f;
+ l += state->vbi_line_offset;
+ p += 4;
- switch (id2) {
- case 1:
- id2 = V4L2_SLICED_TELETEXT_B;
- break;
- case 4:
- id2 = V4L2_SLICED_WSS_625;
- break;
- case 6:
- id2 = V4L2_SLICED_CAPTION_525;
- err = !odd_parity(p[0]) || !odd_parity(p[1]);
- break;
- case 9:
- id2 = V4L2_SLICED_VPS;
- if (decode_vps(p, p) != 0) {
- err = 1;
- }
- break;
- default:
- id2 = 0;
+ switch (id2) {
+ case 1:
+ id2 = V4L2_SLICED_TELETEXT_B;
+ break;
+ case 4:
+ id2 = V4L2_SLICED_WSS_625;
+ break;
+ case 6:
+ id2 = V4L2_SLICED_CAPTION_525;
+ err = !odd_parity(p[0]) || !odd_parity(p[1]);
+ break;
+ case 9:
+ id2 = V4L2_SLICED_VPS;
+ if (decode_vps(p, p) != 0)
err = 1;
- break;
- }
-
- vbi->type = err ? 0 : id2;
- vbi->line = err ? 0 : l;
- vbi->is_second_field = err ? 0 : (id1 == 0x55);
- vbi->p = p;
break;
- }
+ default:
+ id2 = 0;
+ err = 1;
+ break;
}
+ vbi->type = err ? 0 : id2;
+ vbi->line = err ? 0 : l;
+ vbi->is_second_field = err ? 0 : (id1 == 0x55);
+ vbi->p = p;
return 0;
}
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 2d250a2a7bc3..49952980dab3 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -61,7 +61,7 @@ config VIDEO_CX88_DVB
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_STV0288 if !DVB_FE_CUSTOMISE
select DVB_STB6000 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
---help---
This adds support for DVB/ATSC cards based on the
Conexant 2388x chip.
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 66c755c116dc..ce98d955231a 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -803,9 +803,10 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
return (-ENOENT);
}
- card = snd_card_new(index[devno], id[devno], THIS_MODULE, sizeof(snd_cx88_card_t));
- if (!card)
- return (-ENOMEM);
+ err = snd_card_create(index[devno], id[devno], THIS_MODULE,
+ sizeof(snd_cx88_card_t), &card);
+ if (err < 0)
+ return err;
card->private_free = snd_cx88_dev_free;
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 7f5b8bfd08ac..44eacfb0d0d6 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -746,7 +746,6 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
return -EINVAL;
strlcpy(f->description, "MPEG", sizeof(f->description));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->pixelformat = V4L2_PIX_FMT_MPEG;
return 0;
}
@@ -757,7 +756,6 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
struct cx8802_fh *fh = priv;
struct cx8802_dev *dev = fh->dev;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */
@@ -776,7 +774,6 @@ static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,
struct cx8802_fh *fh = priv;
struct cx8802_dev *dev = fh->dev;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
@@ -793,7 +790,6 @@ static int vidioc_s_fmt_vid_cap (struct file *file, void *priv,
struct cx8802_dev *dev = fh->dev;
struct cx88_core *core = dev->core;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
@@ -919,7 +915,7 @@ static int vidioc_log_status (struct file *file, void *priv)
snprintf(name, sizeof(name), "%s/2", core->name);
printk("%s/2: ============ START LOG STATUS ============\n",
core->name);
- cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, NULL);
+ call_all(core, core, log_status);
cx2341x_log_status(&dev->params, name);
printk("%s/2: ============= END LOG STATUS =============\n",
core->name);
@@ -974,7 +970,7 @@ static int vidioc_g_frequency (struct file *file, void *priv,
f->type = V4L2_TUNER_ANALOG_TV;
f->frequency = core->freq;
- cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f);
+ call_all(core, tuner, g_frequency, f);
return 0;
}
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 733ede34f93a..0363971a23a8 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -732,6 +732,8 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ /* Some variants use a tda9874 and so need the tvaudio module. */
+ .audio_chip = V4L2_IDENT_TVAUDIO,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -1934,6 +1936,39 @@ static const struct cx88_board cx88_boards[] = {
} },
.mpeg = CX88_MPEG_DVB,
},
+ [CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII] = {
+ .name = "Terratec Cinergy HT PCI MKII",
+ .tuner_type = TUNER_XC2028,
+ .tuner_addr = 0x61,
+ .radio_type = TUNER_XC2028,
+ .radio_addr = 0x61,
+ .input = { {
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x004ff,
+ .gpio1 = 0x010ff,
+ .gpio2 = 0x00001,
+ }, {
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x004fb,
+ .gpio1 = 0x010ef,
+ .audioroute = 1,
+ }, {
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x004fb,
+ .gpio1 = 0x010ef,
+ .audioroute = 1,
+ } },
+ .radio = {
+ .type = CX88_RADIO,
+ .gpio0 = 0x004ff,
+ .gpio1 = 0x010ff,
+ .gpio2 = 0x0ff,
+ },
+ .mpeg = CX88_MPEG_DVB,
+ },
};
/* ------------------------------------------------------------------ */
@@ -2343,6 +2378,10 @@ static const struct cx88_subid cx88_subids[] = {
.subvendor = 0xb200,
.subdevice = 0x4200,
.card = CX88_BOARD_SATTRADE_ST4200,
+ }, {
+ .subvendor = 0x153b,
+ .subdevice = 0x1177,
+ .card = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII,
},
};
@@ -2819,6 +2858,7 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
*/
break;
case CX88_BOARD_PINNACLE_HYBRID_PCTV:
+ case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
ctl->demod = XC3028_FE_ZARLINK456;
ctl->mts = 1;
break;
@@ -2947,7 +2987,7 @@ static void cx88_card_setup(struct cx88_core *core)
tea5767_cfg.tuner = TUNER_TEA5767;
tea5767_cfg.priv = &ctl;
- cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg);
+ call_all(core, tuner, s_config, &tea5767_cfg);
break;
}
case CX88_BOARD_TEVII_S420:
@@ -2972,7 +3012,7 @@ static void cx88_card_setup(struct cx88_core *core)
tun_setup.type = core->board.radio_type;
tun_setup.addr = core->board.radio_addr;
tun_setup.tuner_callback = cx88_tuner_callback;
- cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
+ call_all(core, tuner, s_type_addr, &tun_setup);
mode_mask &= ~T_RADIO;
}
@@ -2982,7 +3022,7 @@ static void cx88_card_setup(struct cx88_core *core)
tun_setup.addr = core->board.tuner_addr;
tun_setup.tuner_callback = cx88_tuner_callback;
- cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
+ call_all(core, tuner, s_type_addr, &tun_setup);
}
if (core->board.tda9887_conf) {
@@ -2991,7 +3031,7 @@ static void cx88_card_setup(struct cx88_core *core)
tda9887_cfg.tuner = TUNER_TDA9887;
tda9887_cfg.priv = &core->board.tda9887_conf;
- cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tda9887_cfg);
+ call_all(core, tuner, s_config, &tda9887_cfg);
}
if (core->board.tuner_type == TUNER_XC2028) {
@@ -3007,9 +3047,9 @@ static void cx88_card_setup(struct cx88_core *core)
xc2028_cfg.priv = &ctl;
info_printk(core, "Asking xc2028/3028 to load firmware %s\n",
ctl.fname);
- cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg);
+ call_all(core, tuner, s_config, &xc2028_cfg);
}
- cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
+ call_all(core, core, s_standby, 0);
}
/* ------------------------------------------------------------------ */
@@ -3089,6 +3129,8 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
int i;
core = kzalloc(sizeof(*core), GFP_KERNEL);
+ if (core == NULL)
+ return NULL;
atomic_inc(&core->refcount);
core->pci_bus = pci->bus->number;
@@ -3100,7 +3142,15 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
core->nr = nr;
sprintf(core->name, "cx88[%d]", core->nr);
+
+ strcpy(core->v4l2_dev.name, core->name);
+ if (v4l2_device_register(NULL, &core->v4l2_dev)) {
+ kfree(core);
+ return NULL;
+ }
+
if (0 != cx88_get_resources(core, pci)) {
+ v4l2_device_unregister(&core->v4l2_dev);
kfree(core);
return NULL;
}
@@ -3111,6 +3161,11 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
pci_resource_len(pci, 0));
core->bmmio = (u8 __iomem *)core->lmmio;
+ if (core->lmmio == NULL) {
+ kfree(core);
+ return NULL;
+ }
+
/* board config */
core->boardnr = UNSET;
if (card[core->nr] < ARRAY_SIZE(cx88_boards))
@@ -3149,8 +3204,36 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
cx88_i2c_init(core, pci);
/* load tuner module, if needed */
- if (TUNER_ABSENT != core->board.tuner_type)
- request_module("tuner");
+ if (TUNER_ABSENT != core->board.tuner_type) {
+ /* Ignore 0x6b and 0x6f on cx88 boards.
+ * FusionHDTV5 RT Gold has an ir receiver at 0x6b
+ * and an RTC at 0x6f which can get corrupted if probed. */
+ static const unsigned short tv_addrs[] = {
+ 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e,
+ I2C_CLIENT_END
+ };
+ int has_demod = (core->board.tda9887_conf & TDA9887_PRESENT);
+
+ /* I don't trust the radio_type as is stored in the card
+ definitions, so we just probe for it.
+ The radio_type is sometimes missing, or set to UNSET but
+ later code configures a tea5767.
+ */
+ v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner", "tuner",
+ v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+ if (has_demod)
+ v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ if (core->board.tuner_addr == ADDR_UNSET) {
+ v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner",
+ "tuner", has_demod ? tv_addrs + 4 : tv_addrs);
+ } else {
+ v4l2_i2c_new_subdev(&core->i2c_adap,
+ "tuner", "tuner", core->board.tuner_addr);
+ }
+ }
cx88_card_setup(core);
cx88_ir_init(core, pci);
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index b045874ad04f..f2fb9f30bfc1 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -991,7 +991,7 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
set_tvaudio(core);
// tell i2c chips
- cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm);
+ call_all(core, tuner, s_std, norm);
// done
return 0;
@@ -1011,7 +1011,8 @@ struct video_device *cx88_vdev_init(struct cx88_core *core,
return NULL;
*vfd = *template;
vfd->minor = -1;
- vfd->parent = &pci->dev;
+ vfd->v4l2_dev = &core->v4l2_dev;
+ vfd->parent = &pci->dev;
vfd->release = video_device_release;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
core->name, type, core->board.name);
@@ -1058,12 +1059,16 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
mutex_lock(&devlist);
cx88_ir_fini(core);
- if (0 == core->i2c_rc)
+ if (0 == core->i2c_rc) {
+ if (core->i2c_rtc)
+ i2c_unregister_device(core->i2c_rtc);
i2c_del_adapter(&core->i2c_adap);
+ }
list_del(&core->devlist);
iounmap(core->lmmio);
cx88_devcount--;
mutex_unlock(&devlist);
+ v4l2_device_unregister(&core->v4l2_dev);
kfree(core);
}
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index aef5297534af..4ff4d9fe0355 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -241,6 +241,12 @@ static struct mt352_config dvico_fusionhdtv_dual = {
.demod_init = dvico_dual_demod_init,
};
+static struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
+ .demod_address = (0x1e >> 1),
+ .no_tuner = 1,
+ .if2 = 45600,
+};
+
#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
{
@@ -1131,6 +1137,16 @@ static int dvb_register(struct cx8802_dev *dev)
if (fe0->dvb.frontend != NULL)
fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
break;
+ case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
+ &cx88_terratec_cinergy_ht_pci_mkii_config,
+ &core->i2c_adap);
+ if (fe0->dvb.frontend) {
+ fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
+ if (attach_xc3028(0x61, dev) < 0)
+ goto frontend_detach;
+ }
+ break;
default:
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
core->name);
@@ -1152,7 +1168,7 @@ static int dvb_register(struct cx8802_dev *dev)
fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
/* Put the analog decoder in standby to keep it quiet */
- cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
+ call_all(core, core, s_standby, 0);
/* register everything */
return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index c0ff2305d804..996b4ed5a4fc 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -97,37 +97,6 @@ static int cx8800_bit_getsda(void *data)
/* ----------------------------------------------------------------------- */
-static int attach_inform(struct i2c_client *client)
-{
- struct cx88_core *core = i2c_get_adapdata(client->adapter);
-
- dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr, client->name);
- return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
- struct cx88_core *core = i2c_get_adapdata(client->adapter);
-
- dprintk(1, "i2c detach [client=%s]\n", client->name);
- return 0;
-}
-
-void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
-{
- if (0 != core->i2c_rc)
- return;
-
- if (core->gate_ctrl)
- core->gate_ctrl(core, 1);
-
- i2c_clients_command(&core->i2c_adap, cmd, arg);
-
- if (core->gate_ctrl)
- core->gate_ctrl(core, 0);
-}
-
static const struct i2c_algo_bit_data cx8800_i2c_algo_template = {
.setsda = cx8800_bit_setsda,
.setscl = cx8800_bit_setscl,
@@ -173,20 +142,14 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
memcpy(&core->i2c_algo, &cx8800_i2c_algo_template,
sizeof(core->i2c_algo));
- if (core->board.tuner_type != TUNER_ABSENT)
- core->i2c_adap.class |= I2C_CLASS_TV_ANALOG;
- if (core->board.mpeg & CX88_MPEG_DVB)
- core->i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
core->i2c_adap.dev.parent = &pci->dev;
strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name));
core->i2c_adap.owner = THIS_MODULE;
core->i2c_adap.id = I2C_HW_B_CX2388x;
- core->i2c_adap.client_register = attach_inform;
- core->i2c_adap.client_unregister = detach_inform;
core->i2c_algo.udelay = i2c_udelay;
core->i2c_algo.data = core;
- i2c_set_adapdata(&core->i2c_adap,core);
+ i2c_set_adapdata(&core->i2c_adap, &core->v4l2_dev);
core->i2c_adap.algo_data = &core->i2c_algo;
core->i2c_client.adapter = &core->i2c_adap;
strlcpy(core->i2c_client.name, "cx88xx internal", I2C_NAME_SIZE);
@@ -222,8 +185,6 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
/* ----------------------------------------------------------------------- */
-EXPORT_SYMBOL(cx88_call_i2c_clients);
-
/*
* Local variables:
* c-basic-offset: 8
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 8683d104de72..ec05312a9b62 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -48,8 +48,7 @@ struct cx88_IR {
/* poll external decoder */
int polling;
- struct work_struct work;
- struct timer_list timer;
+ struct delayed_work work;
u32 gpio_addr;
u32 last_gpio;
u32 mask_keycode;
@@ -143,27 +142,19 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
}
}
-static void ir_timer(unsigned long data)
-{
- struct cx88_IR *ir = (struct cx88_IR *)data;
-
- schedule_work(&ir->work);
-}
-
static void cx88_ir_work(struct work_struct *work)
{
- struct cx88_IR *ir = container_of(work, struct cx88_IR, work);
+ struct cx88_IR *ir = container_of(work, struct cx88_IR, work.work);
cx88_ir_handle_key(ir);
- mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
+ schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
}
void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir)
{
if (ir->polling) {
- setup_timer(&ir->timer, ir_timer, (unsigned long)ir);
- INIT_WORK(&ir->work, cx88_ir_work);
- schedule_work(&ir->work);
+ INIT_DELAYED_WORK(&ir->work, cx88_ir_work);
+ schedule_delayed_work(&ir->work, 0);
}
if (ir->sampling) {
core->pci_irqmask |= PCI_INT_IR_SMPINT;
@@ -179,10 +170,8 @@ void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir)
core->pci_irqmask &= ~PCI_INT_IR_SMPINT;
}
- if (ir->polling) {
- del_timer_sync(&ir->timer);
- flush_scheduled_work();
- }
+ if (ir->polling)
+ cancel_delayed_work_sync(&ir->work);
}
/* ---------------------------------------------------------------------- */
@@ -226,6 +215,8 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
case CX88_BOARD_HAUPPAUGE_HVR3000:
case CX88_BOARD_HAUPPAUGE_HVR4000:
case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
+ case CX88_BOARD_PCHDTV_HD3000:
+ case CX88_BOARD_PCHDTV_HD5500:
ir_codes = ir_codes_hauppauge_new;
ir_type = IR_TYPE_RC5;
ir->sampling = 1;
@@ -466,6 +457,8 @@ void cx88_ir_irq(struct cx88_core *core)
case CX88_BOARD_HAUPPAUGE_HVR3000:
case CX88_BOARD_HAUPPAUGE_HVR4000:
case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
+ case CX88_BOARD_PCHDTV_HD3000:
+ case CX88_BOARD_PCHDTV_HD5500:
ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
ir_dprintk("biphase decoded: %x\n", ircode);
/*
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 791e69d804f9..434237af5184 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -41,11 +41,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* Include V4L1 specific functions. Should be removed soon */
-#include <linux/videodev.h>
-#endif
-
MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL");
@@ -298,6 +293,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
};
static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
+/* Must be sorted from low to high control ID! */
const u32 cx88_user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
@@ -435,8 +431,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
struct v4l2_routing route;
route.input = INPUT(input).audioroute;
- cx88_call_i2c_clients(core,
- VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ call_all(core, audio, s_routing, &route);
}
/* cx2388's C-ADC is connected to the tuner only.
When used with S-Video, that ADC is busy dealing with
@@ -831,8 +826,7 @@ static int video_open(struct file *file)
struct v4l2_routing route;
route.input = core->board.radio.audioroute;
- cx88_call_i2c_clients(core,
- VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ call_all(core, audio, s_routing, &route);
}
/* "I2S ADC mode" */
core->tvaudio = WW_I2SADC;
@@ -843,7 +837,7 @@ static int video_open(struct file *file)
cx88_set_tvaudio(core);
cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
}
- cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
+ call_all(core, tuner, s_radio);
}
unlock_kernel();
@@ -937,7 +931,7 @@ static int video_release(struct file *file)
kfree(fh);
if(atomic_dec_and_test(&dev->core->users))
- cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+ call_all(dev->core, core, s_standby, 0);
return 0;
}
@@ -1276,15 +1270,12 @@ int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i)
[ CX88_VMUX_DVB ] = "DVB",
[ CX88_VMUX_DEBUG ] = "for debug only",
};
- unsigned int n;
+ unsigned int n = i->index;
- n = i->index;
if (n >= 4)
return -EINVAL;
if (0 == INPUT(n).type)
return -EINVAL;
- memset(i,0,sizeof(*i));
- i->index = n;
i->type = V4L2_INPUT_TYPE_CAMERA;
strcpy(i->name,iname[INPUT(n).type]);
if ((CX88_VMUX_TELEVISION == INPUT(n).type) ||
@@ -1402,7 +1393,7 @@ static int vidioc_g_frequency (struct file *file, void *priv,
f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
f->frequency = core->freq;
- cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f);
+ call_all(core, tuner, g_frequency, f);
return 0;
}
@@ -1418,7 +1409,7 @@ int cx88_set_freq (struct cx88_core *core,
mutex_lock(&core->lock);
core->freq = f->frequency;
cx88_newstation(core);
- cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f);
+ call_all(core, tuner, s_frequency, f);
/* When changing channels it is required to reset TVAUDIO */
msleep (10);
@@ -1500,7 +1491,7 @@ static int radio_g_tuner (struct file *file, void *priv,
strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
- cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t);
+ call_all(core, tuner, g_tuner, t);
return 0;
}
@@ -1520,7 +1511,6 @@ static int radio_g_audio (struct file *file, void *priv, struct v4l2_audio *a)
if (unlikely(a->index))
return -EINVAL;
- memset(a,0,sizeof(*a));
strcpy(a->name,"Radio");
return 0;
}
@@ -1535,7 +1525,7 @@ static int radio_s_tuner (struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- cx88_call_i2c_clients(core,VIDIOC_S_TUNER,t);
+ call_all(core, tuner, s_tuner, t);
return 0;
}
@@ -1892,12 +1882,30 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
/* load and configure helper modules */
if (core->board.audio_chip == V4L2_IDENT_WM8775)
- request_module("wm8775");
+ v4l2_i2c_new_subdev(&core->i2c_adap,
+ "wm8775", "wm8775", 0x36 >> 1);
+
+ if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
+ /* This probes for a tda9874 as is used on some
+ Pixelview Ultra boards. */
+ static const unsigned short i2c_addr[] = {
+ 0xb0 >> 1, I2C_CLIENT_END
+ };
+
+ v4l2_i2c_new_probed_subdev(&core->i2c_adap,
+ "tvaudio", "tvaudio", i2c_addr);
+ }
switch (core->boardnr) {
case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
- case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
+ case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: {
+ static struct i2c_board_info rtc_info = {
+ I2C_BOARD_INFO("isl1208", 0x6f)
+ };
+
request_module("rtc-isl1208");
+ core->i2c_rtc = i2c_new_device(&core->i2c_adap, &rtc_info);
+ }
/* break intentionally omitted */
case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
request_module("ir-kbd-i2c");
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 6025fdd23344..9a43fdf20fae 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -25,7 +25,7 @@
#include <linux/videodev2.h>
#include <linux/kdev_t.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/tuner.h>
#include <media/tveeprom.h>
#include <media/videobuf-dma-sg.h>
@@ -231,6 +231,7 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_SATTRADE_ST4200 76
#define CX88_BOARD_TBS_8910 77
#define CX88_BOARD_PROF_6200 78
+#define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79
enum cx88_itype {
CX88_VMUX_COMPOSITE1 = 1,
@@ -302,7 +303,6 @@ struct cx88_dmaqueue {
struct btcx_riscmem stopper;
u32 count;
};
-struct cx88_core;
struct cx88_core {
struct list_head devlist;
@@ -327,6 +327,8 @@ struct cx88_core {
u32 i2c_state, i2c_rc;
/* config info -- analog */
+ struct v4l2_device v4l2_dev;
+ struct i2c_client *i2c_rtc;
unsigned int boardnr;
struct cx88_board board;
@@ -365,6 +367,22 @@ struct cx88_core {
int active_fe_id;
};
+static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct cx88_core, v4l2_dev);
+}
+
+#define call_all(core, o, f, args...) \
+ do { \
+ if (!core->i2c_rc) { \
+ if (core->gate_ctrl) \
+ core->gate_ctrl(core, 1); \
+ v4l2_device_call_all(&core->v4l2_dev, 0, o, f, ##args); \
+ if (core->gate_ctrl) \
+ core->gate_ctrl(core, 0); \
+ } \
+ } while (0)
+
struct cx8800_dev;
struct cx8802_dev;
@@ -610,8 +628,6 @@ extern struct videobuf_queue_ops cx8800_vbi_qops;
/* cx88-i2c.c */
extern int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci);
-extern void cx88_call_i2c_clients(struct cx88_core *core,
- unsigned int cmd, void *arg);
/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index 298810d5262b..ba3709bec3f0 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -189,17 +189,20 @@ static void dabusb_iso_complete (struct urb *purb)
dst += len;
}
else
- err("dabusb_iso_complete: invalid len %d", len);
+ dev_err(&purb->dev->dev,
+ "dabusb_iso_complete: invalid len %d\n", len);
}
else
dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status);
if (dst != purb->actual_length)
- err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length);
+ dev_err(&purb->dev->dev,
+ "dst!=purb->actual_length:%d!=%d\n",
+ dst, purb->actual_length);
}
if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) {
s->overruns++;
- err("overrun (%d)", s->overruns);
+ dev_err(&purb->dev->dev, "overrun (%d)\n", s->overruns);
}
wake_up (&s->wait);
}
@@ -220,13 +223,14 @@ static int dabusb_alloc_buffers (pdabusb_t s)
while (transfer_len < (s->total_buffer_size << 10)) {
b = kzalloc(sizeof (buff_t), GFP_KERNEL);
if (!b) {
- err("kzalloc(sizeof(buff_t))==NULL");
+ dev_err(&s->usbdev->dev,
+ "kzalloc(sizeof(buff_t))==NULL\n");
goto err;
}
b->s = s;
b->purb = usb_alloc_urb(packets, GFP_KERNEL);
if (!b->purb) {
- err("usb_alloc_urb == NULL");
+ dev_err(&s->usbdev->dev, "usb_alloc_urb == NULL\n");
kfree (b);
goto err;
}
@@ -235,7 +239,8 @@ static int dabusb_alloc_buffers (pdabusb_t s)
if (!b->purb->transfer_buffer) {
kfree (b->purb);
kfree (b);
- err("kmalloc(%d)==NULL", transfer_buffer_length);
+ dev_err(&s->usbdev->dev,
+ "kmalloc(%d)==NULL\n", transfer_buffer_length);
goto err;
}
@@ -279,10 +284,11 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
ret=usb_bulk_msg(s->usbdev, pipe, pb->data, pb->size, &actual_length, 100);
if(ret<0) {
- err("dabusb: usb_bulk_msg failed(%d)",ret);
+ dev_err(&s->usbdev->dev,
+ "usb_bulk_msg failed(%d)\n", ret);
if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
- err("set_interface failed");
+ dev_err(&s->usbdev->dev, "set_interface failed\n");
return -EINVAL;
}
@@ -291,7 +297,7 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
if( ret == -EPIPE ) {
dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n");
if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
- err("request failed");
+ dev_err(&s->usbdev->dev, "request failed\n");
}
pb->size = actual_length;
@@ -305,7 +311,8 @@ static int dabusb_writemem (pdabusb_t s, int pos, const unsigned char *data,
unsigned char *transfer_buffer = kmalloc (len, GFP_KERNEL);
if (!transfer_buffer) {
- err("dabusb_writemem: kmalloc(%d) failed.", len);
+ dev_err(&s->usbdev->dev,
+ "dabusb_writemem: kmalloc(%d) failed.\n", len);
return -ENOMEM;
}
@@ -327,13 +334,14 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname)
{
int ret;
const struct ihex_binrec *rec;
- const struct firmware *fw;
+ const struct firmware *uninitialized_var(fw);
dbg("Enter dabusb_loadmem (internal)");
ret = request_ihex_firmware(&fw, "dabusb/firmware.fw", &s->usbdev->dev);
if (ret) {
- err("Failed to load \"dabusb/firmware.fw\": %d\n", ret);
+ dev_err(&s->usbdev->dev,
+ "Failed to load \"dabusb/firmware.fw\": %d\n", ret);
goto out;
}
ret = dabusb_8051_reset (s, 1);
@@ -346,9 +354,10 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname)
ret = dabusb_writemem(s, be32_to_cpu(rec->addr), rec->data,
be16_to_cpu(rec->len));
if (ret < 0) {
- err("dabusb_writemem failed (%d %04X %p %d)", ret,
- be32_to_cpu(rec->addr), rec->data,
- be16_to_cpu(rec->len));
+ dev_err(&s->usbdev->dev,
+ "dabusb_writemem failed (%d %04X %p %d)\n",
+ ret, be32_to_cpu(rec->addr),
+ rec->data, be16_to_cpu(rec->len));
break;
}
}
@@ -396,13 +405,15 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
dbg("Enter dabusb_fpga_download (internal)");
if (!b) {
- err("kmalloc(sizeof(bulk_transfer_t))==NULL");
+ dev_err(&s->usbdev->dev,
+ "kmalloc(sizeof(bulk_transfer_t))==NULL\n");
return -ENOMEM;
}
ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev);
if (ret) {
- err("Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
+ dev_err(&s->usbdev->dev,
+ "Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
kfree(b);
return ret;
}
@@ -425,7 +436,7 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
memcpy (b->data + 4, fw->data + 74 + n, 60);
ret = dabusb_bulk (s, b);
if (ret < 0) {
- err("dabusb_bulk failed.");
+ dev_err(&s->usbdev->dev, "dabusb_bulk failed.\n");
break;
}
mdelay (1);
@@ -478,9 +489,11 @@ static int dabusb_startrek (pdabusb_t s)
ret = usb_submit_urb (end->purb, GFP_KERNEL);
if (ret) {
- err("usb_submit_urb returned:%d", ret);
+ dev_err(&s->usbdev->dev,
+ "usb_submit_urb returned:%d\n", ret);
if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
- err("startrek: dabusb_add_buf_tail failed");
+ dev_err(&s->usbdev->dev,
+ "startrek: dabusb_add_buf_tail failed\n");
break;
}
else
@@ -523,7 +536,8 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
spin_unlock_irqrestore(&s->lock, flags);
- err("error: rec_buf_list is empty");
+ dev_err(&s->usbdev->dev,
+ "error: rec_buf_list is empty\n");
goto err;
}
@@ -552,7 +566,8 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
if (list_empty (&s->rec_buff_list)) {
spin_unlock_irqrestore(&s->lock, flags);
- err("error: still no buffer available.");
+ dev_err(&s->usbdev->dev,
+ "error: still no buffer available.\n");
goto err;
}
spin_unlock_irqrestore(&s->lock, flags);
@@ -573,7 +588,7 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt);
if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) {
- err("read: copy_to_user failed");
+ dev_err(&s->usbdev->dev, "read: copy_to_user failed\n");
if (!ret)
ret = -EFAULT;
goto err;
@@ -587,7 +602,8 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
if (s->readptr == purb->actual_length) {
// finished, take next buffer
if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
- err("read: dabusb_add_buf_tail failed");
+ dev_err(&s->usbdev->dev,
+ "read: dabusb_add_buf_tail failed\n");
s->readptr = 0;
}
}
@@ -623,7 +639,7 @@ static int dabusb_open (struct inode *inode, struct file *file)
}
if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
mutex_unlock(&s->mutex);
- err("set_interface failed");
+ dev_err(&s->usbdev->dev, "set_interface failed\n");
return -EINVAL;
}
s->opened = 1;
@@ -648,7 +664,7 @@ static int dabusb_release (struct inode *inode, struct file *file)
if (!s->remove_pending) {
if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)
- err("set_interface failed");
+ dev_err(&s->usbdev->dev, "set_interface failed\n");
}
else
wake_up (&s->remove_ok);
@@ -657,7 +673,7 @@ static int dabusb_release (struct inode *inode, struct file *file)
return 0;
}
-static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg)
{
pdabusb_t s = (pdabusb_t) file->private_data;
pbulk_transfer_t pbulk;
@@ -666,13 +682,17 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
dbg("dabusb_ioctl");
- if (s->remove_pending)
+ lock_kernel();
+ if (s->remove_pending) {
+ unlock_kernel();
return -EIO;
+ }
mutex_lock(&s->mutex);
if (!s->usbdev) {
mutex_unlock(&s->mutex);
+ unlock_kernel();
return -EIO;
}
@@ -713,6 +733,7 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
break;
}
mutex_unlock(&s->mutex);
+ unlock_kernel();
return ret;
}
@@ -721,7 +742,7 @@ static const struct file_operations dabusb_fops =
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = dabusb_read,
- .ioctl = dabusb_ioctl,
+ .unlocked_ioctl = dabusb_ioctl,
.open = dabusb_open,
.release = dabusb_release,
};
@@ -764,7 +785,7 @@ static int dabusb_probe (struct usb_interface *intf,
s->devnum = intf->minor;
if (usb_reset_configuration (usbdev) < 0) {
- err("reset_configuration failed");
+ dev_err(&intf->dev, "reset_configuration failed\n");
goto reject;
}
if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) {
@@ -775,7 +796,7 @@ static int dabusb_probe (struct usb_interface *intf,
dabusb_fpga_download (s, NULL);
if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) {
- err("set_interface failed");
+ dev_err(&intf->dev, "set_interface failed\n");
goto reject;
}
}
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index 2ac738fa6a07..0131322475bf 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(debug, "activates debug info");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static int em28xx_isoc_audio_deinit(struct em28xx *dev)
+static int em28xx_deinit_isoc_audio(struct em28xx *dev)
{
int i;
@@ -66,6 +66,7 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev)
usb_kill_urb(dev->adev.urb[i]);
else
usb_unlink_urb(dev->adev.urb[i]);
+
usb_free_urb(dev->adev.urb[i]);
dev->adev.urb[i] = NULL;
@@ -87,6 +88,20 @@ static void em28xx_audio_isocirq(struct urb *urb)
unsigned int stride;
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
+
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ dprintk("urb completition error %d.\n", urb->status);
+ break;
+ }
+
if (dev->adev.capture_pcm_substream) {
substream = dev->adev.capture_pcm_substream;
runtime = substream->runtime;
@@ -137,9 +152,6 @@ static void em28xx_audio_isocirq(struct urb *urb)
}
urb->status = 0;
- if (dev->adev.shutdown)
- return;
-
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status < 0) {
em28xx_errdev("resubmit of audio urb failed (error=%i)\n",
@@ -197,8 +209,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
if (errCode) {
- em28xx_isoc_audio_deinit(dev);
-
+ em28xx_deinit_isoc_audio(dev);
return errCode;
}
}
@@ -213,14 +224,16 @@ static int em28xx_cmd(struct em28xx *dev, int cmd, int arg)
switch (cmd) {
case EM28XX_CAPTURE_STREAM_EN:
- if (dev->adev.capture_stream == STREAM_OFF && arg == 1) {
+ if (dev->adev.capture_stream == STREAM_OFF &&
+ arg == EM28XX_START_AUDIO) {
dev->adev.capture_stream = STREAM_ON;
em28xx_init_audio_isoc(dev);
- } else if (dev->adev.capture_stream == STREAM_ON && arg == 0) {
+ } else if (dev->adev.capture_stream == STREAM_ON &&
+ arg == EM28XX_STOP_AUDIO) {
dev->adev.capture_stream = STREAM_OFF;
- em28xx_isoc_audio_deinit(dev);
+ em28xx_deinit_isoc_audio(dev);
} else {
- printk(KERN_ERR "An underrun very likely occurred. "
+ em28xx_errdev("An underrun very likely occurred. "
"Ignoring it.\n");
}
return 0;
@@ -234,7 +247,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
{
struct snd_pcm_runtime *runtime = subs->runtime;
- dprintk("Alocating vbuffer\n");
+ dprintk("Allocating vbuffer\n");
if (runtime->dma_area) {
if (runtime->dma_bytes > size)
return 0;
@@ -302,7 +315,9 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
dprintk("changing alternate number to 7\n");
}
+ mutex_lock(&dev->lock);
dev->adev.users++;
+ mutex_unlock(&dev->lock);
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
dev->adev.capture_pcm_substream = substream;
@@ -317,22 +332,15 @@ err:
static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
{
struct em28xx *dev = snd_pcm_substream_chip(substream);
- dev->adev.users--;
dprintk("closing device\n");
dev->mute = 1;
mutex_lock(&dev->lock);
+ dev->adev.users--;
em28xx_audio_analog_set(dev);
mutex_unlock(&dev->lock);
- if (dev->adev.users == 0 && dev->adev.shutdown == 1) {
- dprintk("audio users: %d\n", dev->adev.users);
- dprintk("disabling audio stream!\n");
- dev->adev.shutdown = 0;
- dprintk("released lock\n");
- em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
- }
return 0;
}
@@ -363,7 +371,7 @@ static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream)
dprintk("Stop capture, if needed\n");
if (dev->adev.capture_stream == STREAM_ON)
- em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
+ em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO);
return 0;
}
@@ -377,33 +385,40 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct em28xx *dev = snd_pcm_substream_chip(substream);
+ int retval;
+
+ dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START) ?
+ "start" : "stop");
- dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START)?
- "start": "stop");
+ spin_lock(&dev->adev.slock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1);
- return 0;
+ em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_START_AUDIO);
+ retval = 0;
+ break;
case SNDRV_PCM_TRIGGER_STOP:
- dev->adev.shutdown = 1;
- return 0;
+ em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO);
+ retval = 0;
+ break;
default:
- return -EINVAL;
+ retval = -EINVAL;
}
+
+ spin_unlock(&dev->adev.slock);
+ return retval;
}
static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
*substream)
{
- unsigned long flags;
-
+ unsigned long flags;
struct em28xx *dev;
snd_pcm_uframes_t hwptr_done;
dev = snd_pcm_substream_chip(substream);
- spin_lock_irqsave(&dev->adev.slock, flags);
+ spin_lock_irqsave(&dev->adev.slock, flags);
hwptr_done = dev->adev.hwptr_done_capture;
- spin_unlock_irqrestore(&dev->adev.slock, flags);
+ spin_unlock_irqrestore(&dev->adev.slock, flags);
return hwptr_done;
}
@@ -448,9 +463,10 @@ static int em28xx_audio_init(struct em28xx *dev)
printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
"Rechberger\n");
- card = snd_card_new(index[devnr], "Em28xx Audio", THIS_MODULE, 0);
- if (card == NULL)
- return -ENOMEM;
+ err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0,
+ &card);
+ if (err < 0)
+ return err;
spin_lock_init(&adev->slock);
err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 3b3ca3f46d52..0f48c0ff5ac3 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -122,6 +122,22 @@ static struct em28xx_reg_seq default_tuner_gpio[] = {
{ -1, -1, -1, -1},
};
+/* Mute/unmute */
+static struct em28xx_reg_seq compro_unmute_tv_gpio[] = {
+ {EM28XX_R08_GPIO, 5, 7, 10},
+ { -1, -1, -1, -1},
+};
+
+static struct em28xx_reg_seq compro_unmute_svid_gpio[] = {
+ {EM28XX_R08_GPIO, 4, 7, 10},
+ { -1, -1, -1, -1},
+};
+
+static struct em28xx_reg_seq compro_mute_gpio[] = {
+ {EM28XX_R08_GPIO, 6, 7, 10},
+ { -1, -1, -1, -1},
+};
+
/*
* Board definitions
*/
@@ -183,6 +199,25 @@ struct em28xx_board em28xx_boards[] = {
.amux = EM28XX_AMUX_LINE_IN,
} },
},
+ [EM2820_BOARD_GADMEI_TVR200] = {
+ .name = "Gadmei TVR200",
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA711X,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = EM28XX_AMUX_LINE_IN,
+ } },
+ },
[EM2820_BOARD_TERRATEC_CINERGY_250] = {
.name = "Terratec Cinergy 250 USB",
.tuner_type = TUNER_LG_PAL_NEW_TAPC,
@@ -225,7 +260,7 @@ struct em28xx_board em28xx_boards[] = {
.name = "Hauppauge WinTV USB 2",
.tuner_type = TUNER_PHILIPS_FM1236_MK3,
.tda9887_conf = TDA9887_PRESENT |
- TDA9887_PORT1_ACTIVE|
+ TDA9887_PORT1_ACTIVE |
TDA9887_PORT2_ACTIVE,
.decoder = EM28XX_TVP5150,
.has_msp34xx = 1,
@@ -350,26 +385,6 @@ struct em28xx_board em28xx_boards[] = {
.amux = EM28XX_AMUX_VIDEO,
} },
},
- [EM2821_BOARD_PROLINK_PLAYTV_USB2] = {
- .name = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_LG_PAL_NEW_TAPC, /* unknown? */
- .tda9887_conf = TDA9887_PRESENT, /* unknown? */
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
[EM2821_BOARD_SUPERCOMP_USB_2] = {
.name = "Supercomp USB 2.0 TV",
.valid = EM28XX_BOARD_NOT_VALIDATED,
@@ -498,7 +513,7 @@ struct em28xx_board em28xx_boards[] = {
},
[EM2861_BOARD_YAKUMO_MOVIE_MIXER] = {
.name = "Yakumo MovieMixer",
- .tuner_type = TUNER_ABSENT, /* Capture only device */
+ .tuner_type = TUNER_ABSENT, /* Capture only device */
.decoder = EM28XX_TVP5150,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
@@ -604,6 +619,7 @@ struct em28xx_board em28xx_boards[] = {
.mts_firmware = 1,
.has_dvb = 1,
.dvb_gpio = hauppauge_wintv_hvr_900_digital,
+ .ir_codes = ir_codes_hauppauge_new,
.decoder = EM28XX_TVP5150,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
@@ -628,6 +644,7 @@ struct em28xx_board em28xx_boards[] = {
.tuner_type = TUNER_XC2028,
.tuner_gpio = default_tuner_gpio,
.mts_firmware = 1,
+ .ir_codes = ir_codes_hauppauge_new,
.decoder = EM28XX_TVP5150,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
@@ -842,11 +859,11 @@ struct em28xx_board em28xx_boards[] = {
} },
},
[EM2800_BOARD_GRABBEEX_USB2800] = {
- .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
- .is_em2800 = 1,
- .decoder = EM28XX_SAA711X,
- .tuner_type = TUNER_ABSENT, /* capture only board */
- .input = { {
+ .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
+ .is_em2800 = 1,
+ .decoder = EM28XX_SAA711X,
+ .tuner_type = TUNER_ABSENT, /* capture only board */
+ .input = { {
.type = EM28XX_VMUX_COMPOSITE1,
.vmux = SAA7115_COMPOSITE0,
.amux = EM28XX_AMUX_LINE_IN,
@@ -897,7 +914,7 @@ struct em28xx_board em28xx_boards[] = {
} },
},
[EM2820_BOARD_PINNACLE_DVC_90] = {
- .name = "Pinnacle Dazzle DVC 90/DVC 100",
+ .name = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker",
.tuner_type = TUNER_ABSENT, /* capture only board */
.decoder = EM28XX_SAA711X,
.input = { {
@@ -952,7 +969,7 @@ struct em28xx_board em28xx_boards[] = {
} },
},
[EM2820_BOARD_PROLINK_PLAYTV_USB2] = {
- .name = "Pixelview Prolink PlayTV USB 2.0",
+ .name = "SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0",
.has_snapshot_button = 1,
.tda9887_conf = TDA9887_PRESENT,
.tuner_type = TUNER_YMEC_TVF_5533MF,
@@ -1198,7 +1215,9 @@ struct em28xx_board em28xx_boards[] = {
.has_dvb = 1,
.dvb_gpio = kworld_330u_digital,
.xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
- .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_EEPROM_ON_BOARD | EM28XX_I2C_EEPROM_KEY_VALID,
+ .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
+ EM28XX_I2C_EEPROM_ON_BOARD |
+ EM28XX_I2C_EEPROM_KEY_VALID,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
.vmux = TVP5150_COMPOSITE0,
@@ -1223,21 +1242,88 @@ struct em28xx_board em28xx_boards[] = {
.tuner_type = TUNER_LG_PAL_NEW_TAPC,
.tda9887_conf = TDA9887_PRESENT,
.decoder = EM28XX_TVP5150,
+ .adecoder = EM28XX_TVAUDIO,
+ .mute_gpio = compro_mute_gpio,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
.vmux = TVP5150_COMPOSITE0,
+ .amux = EM28XX_AMUX_VIDEO,
+ .gpio = compro_unmute_tv_gpio,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = EM28XX_AMUX_LINE_IN,
+ .gpio = compro_unmute_svid_gpio,
+ } },
+ },
+ [EM2860_BOARD_KAIOMY_TVNPC_U2] = {
+ .name = "Kaiomy TVnPC U2",
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .tuner_addr = 0x61,
+ .mts_firmware = 1,
+ .decoder = EM28XX_TVP5150,
+ .tuner_gpio = default_tuner_gpio,
+ .ir_codes = ir_codes_kaiomy,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = EM28XX_AMUX_VIDEO,
+
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
.amux = EM28XX_AMUX_LINE_IN,
}, {
.type = EM28XX_VMUX_SVIDEO,
.vmux = TVP5150_SVIDEO,
.amux = EM28XX_AMUX_LINE_IN,
} },
+ .radio = {
+ .type = EM28XX_RADIO,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }
+ },
+ [EM2860_BOARD_EASYCAP] = {
+ .name = "Easy Cap Capture DC-60",
+ .vchannels = 2,
+ .tuner_type = TUNER_ABSENT,
+ .decoder = EM28XX_SAA711X,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = EM28XX_AMUX_LINE_IN,
+ } },
+ },
+ [EM2820_BOARD_IODATA_GVMVP_SZ] = {
+ .name = "IO-DATA GV-MVP/SZ",
+ .tuner_type = TUNER_PHILIPS_FM1236_MK3,
+ .tuner_gpio = default_tuner_gpio,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = EM28XX_AMUX_VIDEO,
+ }, { /* Composite has not been tested yet */
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = EM28XX_AMUX_VIDEO,
+ }, { /* S-video has not been tested yet */
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = EM28XX_AMUX_VIDEO,
+ } },
},
};
const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
/* table of devices that work with this driver */
-struct usb_device_id em28xx_id_table [] = {
+struct usb_device_id em28xx_id_table[] = {
{ USB_DEVICE(0xeb1a, 0x2750),
.driver_info = EM2750_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0x2751),
@@ -1260,6 +1346,8 @@ struct usb_device_id em28xx_id_table [] = {
.driver_info = EM2820_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0xe300),
.driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
+ { USB_DEVICE(0xeb1a, 0xe303),
+ .driver_info = EM2860_BOARD_KAIOMY_TVNPC_U2 },
{ USB_DEVICE(0xeb1a, 0xe305),
.driver_info = EM2880_BOARD_KWORLD_DVB_305U },
{ USB_DEVICE(0xeb1a, 0xe310),
@@ -1278,6 +1366,8 @@ struct usb_device_id em28xx_id_table [] = {
.driver_info = EM2800_BOARD_GRABBEEX_USB2800 },
{ USB_DEVICE(0xeb1a, 0xe357),
.driver_info = EM2870_BOARD_KWORLD_355U },
+ { USB_DEVICE(0x1b80, 0xe302),
+ .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kaiser Baas Video to DVD maker */
{ USB_DEVICE(0x0ccd, 0x0036),
.driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
{ USB_DEVICE(0x0ccd, 0x004c),
@@ -1330,6 +1420,8 @@ struct usb_device_id em28xx_id_table [] = {
.driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII },
{ USB_DEVICE(0x093b, 0xa005),
.driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U },
+ { USB_DEVICE(0x04bb, 0x0515),
+ .driver_info = EM2820_BOARD_IODATA_GVMVP_SZ },
{ },
};
MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -1337,7 +1429,7 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table);
/*
* EEPROM hash table for devices with generic USB IDs
*/
-static struct em28xx_hash_table em28xx_eeprom_hash [] = {
+static struct em28xx_hash_table em28xx_eeprom_hash[] = {
/* P/N: SA 60002070465 Tuner: TVF7533-MF */
{0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
{0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
@@ -1349,6 +1441,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
{0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
{0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
{0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT},
+ {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
};
int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
@@ -1368,7 +1461,7 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
}
EXPORT_SYMBOL_GPL(em28xx_tuner_callback);
-static void inline em28xx_set_model(struct em28xx *dev)
+static inline void em28xx_set_model(struct em28xx *dev)
{
memcpy(&dev->board, &em28xx_boards[dev->model], sizeof(dev->board));
@@ -1504,6 +1597,34 @@ void em28xx_pre_card_setup(struct em28xx *dev)
/* enables audio for that devices */
em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
break;
+
+ case EM2860_BOARD_KAIOMY_TVNPC_U2:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ em28xx_write_regs(dev, 0x0d, "\x42", 1);
+ em28xx_write_regs(dev, 0x08, "\xfd", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\xff", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\x7f", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\x6b", 1);
+
+ break;
+ case EM2860_BOARD_EASYCAP:
+ em28xx_write_regs(dev, 0x08, "\xf8", 1);
+ break;
+
+ case EM2820_BOARD_IODATA_GVMVP_SZ:
+ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+ msleep(70);
+ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
+ msleep(10);
+ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+ msleep(70);
+ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+ msleep(70);
+ break;
}
em28xx_gpio_set(dev, dev->board.tuner_gpio);
@@ -1610,7 +1731,7 @@ static int em28xx_hint_board(struct em28xx *dev)
em28xx_errdev("If the board were missdetected, "
"please email this log to:\n");
em28xx_errdev("\tV4L Mailing List "
- " <video4linux-list@redhat.com>\n");
+ " <linux-media@vger.kernel.org>\n");
em28xx_errdev("Board detected as %s\n",
em28xx_boards[dev->model].name);
@@ -1642,7 +1763,7 @@ static int em28xx_hint_board(struct em28xx *dev)
em28xx_errdev("If the board were missdetected, "
"please email this log to:\n");
em28xx_errdev("\tV4L Mailing List "
- " <video4linux-list@redhat.com>\n");
+ " <linux-media@vger.kernel.org>\n");
em28xx_errdev("Board detected as %s\n",
em28xx_boards[dev->model].name);
@@ -1655,7 +1776,7 @@ static int em28xx_hint_board(struct em28xx *dev)
em28xx_errdev("You may try to use card=<n> insmod option to "
"workaround that.\n");
em28xx_errdev("Please send an email with this log to:\n");
- em28xx_errdev("\tV4L Mailing List <video4linux-list@redhat.com>\n");
+ em28xx_errdev("\tV4L Mailing List <linux-media@vger.kernel.org>\n");
em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash);
em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash);
@@ -1800,6 +1921,8 @@ void em28xx_card_setup(struct em28xx *dev)
request_module("tvp5150");
if (dev->board.tuner_type != TUNER_ABSENT)
request_module("tuner");
+ if (dev->board.adecoder == EM28XX_TVAUDIO)
+ request_module("tvaudio");
#endif
em28xx_config_tuner(dev);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 94fb1b639a2e..8f1999ca4803 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -33,8 +33,8 @@
/* #define ENABLE_DEBUG_ISOC_FRAMES */
static unsigned int core_debug;
-module_param(core_debug,int,0644);
-MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
+module_param(core_debug, int, 0644);
+MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
#define em28xx_coredbg(fmt, arg...) do {\
if (core_debug) \
@@ -42,8 +42,8 @@ MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
dev->name, __func__ , ##arg); } while (0)
static unsigned int reg_debug;
-module_param(reg_debug,int,0644);
-MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");
+module_param(reg_debug, int, 0644);
+MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]");
#define em28xx_regdbg(fmt, arg...) do {\
if (reg_debug) \
@@ -77,7 +77,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
return -EINVAL;
if (reg_debug) {
- printk( KERN_DEBUG "(pipe 0x%08x): "
+ printk(KERN_DEBUG "(pipe 0x%08x): "
"IN: %02x %02x %02x %02x %02x %02x %02x %02x ",
pipe,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -154,7 +154,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
if (reg_debug) {
int byte;
- printk( KERN_DEBUG "(pipe 0x%08x): "
+ printk(KERN_DEBUG "(pipe 0x%08x): "
"OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>",
pipe,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -378,6 +378,11 @@ static int em28xx_set_audio_source(struct em28xx *dev)
}
}
+ if (dev->board.mute_gpio && dev->mute)
+ em28xx_gpio_set(dev, dev->board.mute_gpio);
+ else
+ em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio);
+
ret = em28xx_write_reg_bits(dev, EM28XX_R0E_AUDIOSRC, input, 0xc0);
if (ret < 0)
return ret;
@@ -424,7 +429,7 @@ int em28xx_audio_analog_set(struct em28xx *dev)
xclk = dev->board.xclk & 0x7f;
if (!dev->mute)
- xclk |= 0x80;
+ xclk |= EM28XX_XCLK_AUDIO_UNMUTE;
ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk);
if (ret < 0)
@@ -462,7 +467,8 @@ int em28xx_audio_analog_set(struct em28xx *dev)
if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) {
int sel = ac97_return_record_select(dev->ctl_aoutput);
- /* Use the same input for both left and right channels */
+ /* Use the same input for both left and right
+ channels */
sel |= (sel << 8);
em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel);
@@ -698,7 +704,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2);
/* it seems that both H and V scalers must be active
to work correctly */
- mode = (h || v)? 0x30: 0x00;
+ mode = (h || v) ? 0x30 : 0x00;
}
return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30);
}
@@ -827,6 +833,19 @@ static void em28xx_irq_callback(struct urb *urb)
struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
int rc, i;
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ em28xx_isocdbg("urb completition error %d.\n", urb->status);
+ break;
+ }
+
/* Copy data from URB */
spin_lock(&dev->slock);
rc = dev->isoc_ctl.isoc_copy(dev, urb);
@@ -945,7 +964,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
em28xx_err("unable to allocate %i bytes for transfer"
" buffer %i%s\n",
sb_size, i,
- in_interrupt()?" while in int":"");
+ in_interrupt() ? " while in int" : "");
em28xx_uninit_isoc(dev);
return -ENOMEM;
}
@@ -963,7 +982,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
em28xx_irq_callback, dma_q, 1);
urb->number_of_packets = max_packets;
- urb->transfer_flags = URB_ISO_ASAP;
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
k = 0;
for (j = 0; j < max_packets; j++) {
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index 9ad8527b3fda..fcd25511209b 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -29,9 +29,6 @@
#include "lgdt330x.h"
#include "zl10353.h"
#include "s5h1409.h"
-#ifdef EM28XX_DRX397XD_SUPPORT
-#include "drx397xD.h"
-#endif
MODULE_DESCRIPTION("driver for em28xx based DVB cards");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index d69f0efcc9aa..02c12fe6361b 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -402,10 +402,12 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
dev->name);
break;
case 2:
- printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n", dev->name);
+ printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n",
+ dev->name);
break;
case 3:
- printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n", dev->name);
+ printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n",
+ dev->name);
break;
}
@@ -508,12 +510,17 @@ static int attach_inform(struct i2c_client *client)
dprintk1(1, "attach_inform: tvp5150 detected.\n");
break;
+ case 0xb0:
+ dprintk1(1, "attach_inform: tda9874 detected\n");
+ break;
+
default:
if (!dev->tuner_addr)
dev->tuner_addr = client->addr;
dprintk1(1, "attach inform: detected I2C address %x\n",
client->addr << 1);
+ dprintk1(1, "driver id %d\n", client->driver->id);
}
@@ -552,6 +559,7 @@ static char *i2c_devs[128] = {
[0x80 >> 1] = "msp34xx",
[0x88 >> 1] = "msp34xx",
[0xa0 >> 1] = "eeprom",
+ [0xb0 >> 1] = "tda9874",
[0xb8 >> 1] = "tvp5150a",
[0xba >> 1] = "tvp5150a",
[0xc0 >> 1] = "tuner (analog)",
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 0443afe09ff8..a5abfd7a19f5 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -68,8 +68,7 @@ struct em28xx_IR {
/* poll external decoder */
int polling;
- struct work_struct work;
- struct timer_list timer;
+ struct delayed_work work;
unsigned int last_toggle:1;
unsigned int last_readcount;
unsigned int repeat_interval;
@@ -292,32 +291,23 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
return;
}
-static void ir_timer(unsigned long data)
-{
- struct em28xx_IR *ir = (struct em28xx_IR *)data;
-
- schedule_work(&ir->work);
-}
-
static void em28xx_ir_work(struct work_struct *work)
{
- struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work);
+ struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work.work);
em28xx_ir_handle_key(ir);
- mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
+ schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
}
static void em28xx_ir_start(struct em28xx_IR *ir)
{
- setup_timer(&ir->timer, ir_timer, (unsigned long)ir);
- INIT_WORK(&ir->work, em28xx_ir_work);
- schedule_work(&ir->work);
+ INIT_DELAYED_WORK(&ir->work, em28xx_ir_work);
+ schedule_delayed_work(&ir->work, 0);
}
static void em28xx_ir_stop(struct em28xx_IR *ir)
{
- del_timer_sync(&ir->timer);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&ir->work);
}
int em28xx_ir_init(struct em28xx *dev)
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 8e61b2ca9167..575472f1e702 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -186,7 +186,8 @@ static void em28xx_copy_video(struct em28xx *dev,
em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
((char *)startwrite + lencopy) -
((char *)outp + buf->vb.size));
- lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite;
+ remain = (char *)outp + buf->vb.size - (char *)startwrite;
+ lencopy = remain;
}
if (lencopy <= 0)
return;
@@ -202,7 +203,8 @@ static void em28xx_copy_video(struct em28xx *dev,
else
lencopy = bytesperline;
- if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
+ if ((char *)startwrite + lencopy > (char *)outp +
+ buf->vb.size) {
em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n",
((char *)startwrite + lencopy) -
((char *)outp + buf->vb.size));
@@ -347,7 +349,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
}
if (p[0] == 0x22 && p[1] == 0x5a) {
em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
- len, (p[2] & 1)? "odd" : "even");
+ len, (p[2] & 1) ? "odd" : "even");
if (!(p[2] & 1)) {
if (buf != NULL)
@@ -476,7 +478,9 @@ fail:
static void
buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
{
- struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
+ struct em28xx_buffer *buf = container_of(vb,
+ struct em28xx_buffer,
+ vb);
struct em28xx_fh *fh = vq->priv_data;
struct em28xx *dev = fh->dev;
struct em28xx_dmaqueue *vidq = &dev->vidq;
@@ -489,7 +493,9 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
static void buffer_release(struct videobuf_queue *vq,
struct videobuf_buffer *vb)
{
- struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
+ struct em28xx_buffer *buf = container_of(vb,
+ struct em28xx_buffer,
+ vb);
struct em28xx_fh *fh = vq->priv_data;
struct em28xx *dev = (struct em28xx *)fh->dev;
@@ -534,6 +540,13 @@ static void video_mux(struct em28xx *dev, int index)
&route);
}
+ if (dev->board.adecoder != EM28XX_NOADECODER) {
+ route.input = dev->ctl_ainput;
+ route.output = dev->ctl_aoutput;
+ em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
+ &route);
+ }
+
em28xx_audio_analog_set(dev);
}
@@ -557,7 +570,7 @@ static int res_get(struct em28xx_fh *fh)
static int res_check(struct em28xx_fh *fh)
{
- return (fh->stream_on);
+ return fh->stream_on;
}
static void res_free(struct em28xx_fh *fh)
@@ -791,7 +804,7 @@ out:
return rc;
}
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
{
struct em28xx_fh *fh = priv;
struct em28xx *dev = fh->dev;
@@ -1008,8 +1021,13 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
if (dev->board.has_msp34xx)
em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
- else
+ else {
rc = em28xx_get_ctrl(dev, ctrl);
+ if (rc < 0) {
+ em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
+ rc = 0;
+ }
+ }
mutex_unlock(&dev->lock);
return rc;
@@ -1345,7 +1363,7 @@ static int vidioc_querycap(struct file *file, void *priv,
strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
- strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->version = EM28XX_VERSION_CODE;
@@ -1431,7 +1449,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
if (rc < 0)
return rc;
- return (videobuf_reqbufs(&fh->vb_vidq, rb));
+ return videobuf_reqbufs(&fh->vb_vidq, rb);
}
static int vidioc_querybuf(struct file *file, void *priv,
@@ -1445,7 +1463,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
if (rc < 0)
return rc;
- return (videobuf_querybuf(&fh->vb_vidq, b));
+ return videobuf_querybuf(&fh->vb_vidq, b);
}
static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1458,7 +1476,7 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
if (rc < 0)
return rc;
- return (videobuf_qbuf(&fh->vb_vidq, b));
+ return videobuf_qbuf(&fh->vb_vidq, b);
}
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1471,8 +1489,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
if (rc < 0)
return rc;
- return (videobuf_dqbuf(&fh->vb_vidq, b,
- file->f_flags & O_NONBLOCK));
+ return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
}
#ifdef CONFIG_VIDEO_V4L1_COMPAT
@@ -1496,7 +1513,7 @@ static int radio_querycap(struct file *file, void *priv,
strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
- strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->version = EM28XX_VERSION_CODE;
cap->capabilities = V4L2_CAP_TUNER;
@@ -1781,7 +1798,7 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
* em28xx_v4l2_poll()
* will allocate buffers when called for the first time
*/
-static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
+static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
{
struct em28xx_fh *fh = filp->private_data;
struct em28xx *dev = fh->dev;
@@ -1934,8 +1951,8 @@ static struct video_device em28xx_radio_template = {
static struct video_device *em28xx_vdev_init(struct em28xx *dev,
- const struct video_device *template,
- const char *type_name)
+ const struct video_device *template,
+ const char *type_name)
{
struct video_device *vfd;
@@ -1984,8 +2001,9 @@ int em28xx_register_analog_devices(struct em28xx *dev)
/* enable vbi capturing */
/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
- val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
- em28xx_write_reg(dev, EM28XX_R0F_XCLK, (EM28XX_XCLK_AUDIO_UNMUTE | val));
+ val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
+ em28xx_write_reg(dev, EM28XX_R0F_XCLK,
+ (EM28XX_XCLK_AUDIO_UNMUTE | val));
em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
em28xx_set_outfmt(dev);
@@ -2020,7 +2038,8 @@ int em28xx_register_analog_devices(struct em28xx *dev)
}
if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
- dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
+ dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
+ "radio");
if (!dev->radio_dev) {
em28xx_errdev("cannot allocate video_device.\n");
return -ENODEV;
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index dd2cd36fb1bb..a33a58da016e 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -70,7 +70,6 @@
#define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30
#define EM2821_BOARD_USBGEAR_VD204 31
#define EM2821_BOARD_SUPERCOMP_USB_2 32
-#define EM2821_BOARD_PROLINK_PLAYTV_USB2 33
#define EM2860_BOARD_TERRATEC_HYBRID_XS 34
#define EM2860_BOARD_TYPHOON_DVD_MAKER 35
#define EM2860_BOARD_NETGMBH_CAM 36
@@ -98,6 +97,10 @@
#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58
#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60
#define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61
+#define EM2820_BOARD_GADMEI_TVR200 62
+#define EM2860_BOARD_KAIOMY_TVNPC_U2 63
+#define EM2860_BOARD_EASYCAP 64
+#define EM2820_BOARD_IODATA_GVMVP_SZ 65
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
@@ -110,6 +113,10 @@
#define EM28XX_BOARD_NOT_VALIDATED 1
#define EM28XX_BOARD_VALIDATED 0
+/* Params for em28xx_cmd() audio */
+#define EM28XX_START_AUDIO 1
+#define EM28XX_STOP_AUDIO 0
+
/* maximum number of em28xx boards */
#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
@@ -154,7 +161,8 @@
*/
/* time to wait when stopping the isoc transfer */
-#define EM28XX_URB_TIMEOUT msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
+#define EM28XX_URB_TIMEOUT \
+ msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
/* time in msecs to wait for i2c writes to finish */
#define EM2800_I2C_WRITE_TIMEOUT 20
@@ -348,6 +356,11 @@ enum em28xx_decoder {
EM28XX_SAA711X,
};
+enum em28xx_adecoder {
+ EM28XX_NOADECODER = 0,
+ EM28XX_TVAUDIO,
+};
+
struct em28xx_board {
char *name;
int vchannels;
@@ -361,6 +374,7 @@ struct em28xx_board {
struct em28xx_reg_seq *dvb_gpio;
struct em28xx_reg_seq *suspend_gpio;
struct em28xx_reg_seq *tuner_gpio;
+ struct em28xx_reg_seq *mute_gpio;
unsigned int is_em2800:1;
unsigned int has_msp34xx:1;
@@ -373,6 +387,7 @@ struct em28xx_board {
unsigned char xclk, i2c_speed;
enum em28xx_decoder decoder;
+ enum em28xx_adecoder adecoder;
struct em28xx_input input[MAX_EM28XX_INPUT];
struct em28xx_input radio;
@@ -420,7 +435,7 @@ struct em28xx_audio {
unsigned int hwptr_done_capture;
struct snd_card *sndcard;
- int users, shutdown;
+ int users;
enum em28xx_stream_state capture_stream;
spinlock_t slock;
};
@@ -523,7 +538,8 @@ struct em28xx {
int num_alt; /* Number of alternative settings */
unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */
- char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */
+ char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc
+ transfer */
char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */
/* helper funcs that call usb_control_msg */
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index ee6a691dff22..578dc4ffc965 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -56,6 +56,15 @@ config USB_GSPCA_MARS
To compile this driver as a module, choose M here: the
module will be called gspca_mars.
+config USB_GSPCA_MR97310A
+ tristate "Mars-Semi MR97310A USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on the MR97310A chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_mr97310a.
+
config USB_GSPCA_OV519
tristate "OV519 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
@@ -167,6 +176,24 @@ config USB_GSPCA_SPCA561
To compile this driver as a module, choose M here: the
module will be called gspca_spca561.
+config USB_GSPCA_SQ905
+ tristate "SQ Technologies SQ905 based USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on the SQ905 chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_sq905.
+
+config USB_GSPCA_SQ905C
+ tristate "SQ Technologies SQ905C based USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on the SQ905C chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_sq905c.
+
config USB_GSPCA_STK014
tristate "Syntek DV4000 (STK014) USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index bd8d9ee40504..8a6643e8eb96 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -1,50 +1,56 @@
-obj-$(CONFIG_USB_GSPCA) += gspca_main.o
-obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
-obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
-obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
-obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
-obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
-obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
-obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
-obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
-obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
-obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
-obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o
-obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o
-obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o
-obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o
-obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o
-obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o
-obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
-obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
-obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
-obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
-obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
-obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
+obj-$(CONFIG_USB_GSPCA) += gspca_main.o
+obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
+obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
+obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
+obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
+obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
+obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
+obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
+obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
+obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
+obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
+obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
+obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o
+obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o
+obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o
+obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o
+obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o
+obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o
+obj-$(CONFIG_USB_GSPCA_SQ905) += gspca_sq905.o
+obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o
+obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
+obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
+obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
+obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
+obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
+obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
-gspca_main-objs := gspca.o
-gspca_conex-objs := conex.o
-gspca_etoms-objs := etoms.o
-gspca_finepix-objs := finepix.o
-gspca_mars-objs := mars.o
-gspca_ov519-objs := ov519.o
-gspca_ov534-objs := ov534.o
-gspca_pac207-objs := pac207.o
-gspca_pac7311-objs := pac7311.o
-gspca_sonixb-objs := sonixb.o
-gspca_sonixj-objs := sonixj.o
-gspca_spca500-objs := spca500.o
-gspca_spca501-objs := spca501.o
-gspca_spca505-objs := spca505.o
-gspca_spca506-objs := spca506.o
-gspca_spca508-objs := spca508.o
-gspca_spca561-objs := spca561.o
-gspca_stk014-objs := stk014.o
-gspca_sunplus-objs := sunplus.o
-gspca_t613-objs := t613.o
-gspca_tv8532-objs := tv8532.o
-gspca_vc032x-objs := vc032x.o
-gspca_zc3xx-objs := zc3xx.o
+gspca_main-objs := gspca.o
+gspca_conex-objs := conex.o
+gspca_etoms-objs := etoms.o
+gspca_finepix-objs := finepix.o
+gspca_mars-objs := mars.o
+gspca_mr97310a-objs := mr97310a.o
+gspca_ov519-objs := ov519.o
+gspca_ov534-objs := ov534.o
+gspca_pac207-objs := pac207.o
+gspca_pac7311-objs := pac7311.o
+gspca_sonixb-objs := sonixb.o
+gspca_sonixj-objs := sonixj.o
+gspca_spca500-objs := spca500.o
+gspca_spca501-objs := spca501.o
+gspca_spca505-objs := spca505.o
+gspca_spca506-objs := spca506.o
+gspca_spca508-objs := spca508.o
+gspca_spca561-objs := spca561.o
+gspca_sq905-objs := sq905.o
+gspca_sq905c-objs := sq905c.o
+gspca_stk014-objs := stk014.o
+gspca_sunplus-objs := sunplus.o
+gspca_t613-objs := t613.o
+gspca_tv8532-objs := tv8532.o
+gspca_vc032x-objs := vc032x.o
+gspca_zc3xx-objs := zc3xx.o
-obj-$(CONFIG_USB_M5602) += m5602/
-obj-$(CONFIG_USB_STV06XX) += stv06xx/
+obj-$(CONFIG_USB_M5602) += m5602/
+obj-$(CONFIG_USB_STV06XX) += stv06xx/
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 1753f5bb3544..219cfa6fb877 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -36,8 +36,12 @@ struct sd {
unsigned char brightness;
unsigned char contrast;
unsigned char colors;
+ u8 quality;
+#define QUALITY_MIN 30
+#define QUALITY_MAX 60
+#define QUALITY_DEF 40
- unsigned char qindex;
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -815,14 +819,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
- sd->qindex = 0; /* set the quantization */
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
+ sd->quality = QUALITY_DEF;
return 0;
}
@@ -839,6 +842,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
static int sd_start(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x22); /* JPEG 411 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
cx11646_initsize(gspca_dev);
cx11646_fw(gspca_dev);
cx_sensor(gspca_dev);
@@ -849,8 +860,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
int retry = 50;
+ kfree(sd->jpeg_hdr);
+
if (!gspca_dev->present)
return;
reg_w_val(gspca_dev, 0x0000, 0x00);
@@ -876,6 +890,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
__u8 *data, /* isoc packet */
int len) /* iso packet length */
{
+ struct sd *sd = (struct sd *) gspca_dev;
+
if (data[0] == 0xff && data[1] == 0xd8) {
/* start of frame */
@@ -883,9 +899,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
data, 0);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame,
- ((struct sd *) gspca_dev)->qindex,
- 0x22);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
data += 2;
len -= 2;
}
@@ -988,6 +1003,34 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -998,6 +1041,8 @@ static struct sd_desc sd_desc = {
.start = sd_start,
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -1029,8 +1074,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index f3cd8ff5cc92..2c20d06a03e8 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -472,19 +472,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
reg_w_val(gspca_dev, ET_O_RED + i, brightness);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- int brightness = 0;
-
- for (i = 0; i < 4; i++) {
- reg_r(gspca_dev, ET_O_RED + i, 1);
- brightness += gspca_dev->usb_buf[0];
- }
- sd->brightness = brightness >> 3;
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -495,19 +482,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, ET_G_RED, RGBG, 6);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- int contrast = 0;
-
- for (i = 0; i < 4; i++) {
- reg_r(gspca_dev, ET_G_RED + i, 1);
- contrast += gspca_dev->usb_buf[0];
- }
- sd->contrast = contrast >> 2;
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -658,7 +632,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 1;
sd->sensor = id->driver_info;
if (sd->sensor == SENSOR_PAS106) {
cam->cam_mode = sif_mode;
@@ -821,7 +794,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -840,7 +812,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -859,7 +830,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -928,8 +898,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index afc8b2dd307b..00e6863ed666 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -27,7 +27,7 @@ MODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver");
MODULE_LICENSE("GPL");
/* Default timeout, in ms */
-#define FPIX_TIMEOUT (HZ / 10)
+#define FPIX_TIMEOUT 250
/* Maximum transfer size to use. The windows driver reads by chunks of
* 0x2000 bytes, so do the same. Note: reading more seems to work
@@ -38,38 +38,15 @@ MODULE_LICENSE("GPL");
struct usb_fpix {
struct gspca_dev gspca_dev; /* !! must be the first item */
- /*
- * USB stuff
- */
- struct usb_ctrlrequest ctrlreq;
- struct urb *control_urb;
- struct timer_list bulk_timer;
-
- enum {
- FPIX_NOP, /* inactive, else streaming */
- FPIX_RESET, /* must reset */
- FPIX_REQ_FRAME, /* requesting a frame */
- FPIX_READ_FRAME, /* reading frame */
- } state;
-
- /*
- * Driver stuff
- */
- struct delayed_work wqe;
- struct completion can_close;
- int streaming;
+ struct work_struct work_struct;
+ struct workqueue_struct *work_thread;
};
/* Delay after which claim the next frame. If the delay is too small,
* the camera will return old frames. On the 4800Z, 20ms is bad, 25ms
- * will fail every 4 or 5 frames, but 30ms is perfect. */
-#define NEXT_FRAME_DELAY (((HZ * 30) + 999) / 1000)
-
-#define dev_new_state(new_state) { \
- PDEBUG(D_STREAM, "new state from %d to %d at %s:%d", \
- dev->state, new_state, __func__, __LINE__); \
- dev->state = new_state; \
-}
+ * will fail every 4 or 5 frames, but 30ms is perfect. On the A210,
+ * 30ms is bad while 35ms is perfect. */
+#define NEXT_FRAME_DELAY 35
/* These cameras only support 320x200. */
static const struct v4l2_pix_format fpix_mode[1] = {
@@ -80,316 +57,183 @@ static const struct v4l2_pix_format fpix_mode[1] = {
.priv = 0}
};
-/* Reads part of a frame */
-static void read_frame_part(struct usb_fpix *dev)
+/* send a command to the webcam */
+static int command(struct gspca_dev *gspca_dev,
+ int order) /* 0: reset, 1: frame request */
{
- int ret;
+ static u8 order_values[2][12] = {
+ {0xc6, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0}, /* reset */
+ {0xd3, 0, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0}, /* fr req */
+ };
- PDEBUG(D_STREAM, "read_frame_part");
-
- /* Reads part of a frame */
- ret = usb_submit_urb(dev->gspca_dev.urb[0], GFP_ATOMIC);
- if (ret) {
- dev_new_state(FPIX_RESET);
- schedule_delayed_work(&dev->wqe, 1);
- PDEBUG(D_STREAM, "usb_submit_urb failed with %d",
- ret);
- } else {
- /* Sometimes we never get a callback, so use a timer.
- * Is this masking a bug somewhere else? */
- dev->bulk_timer.expires = jiffies + msecs_to_jiffies(150);
- add_timer(&dev->bulk_timer);
- }
+ memcpy(gspca_dev->usb_buf, order_values[order], 12);
+ return usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_GET_STATUS,
+ USB_DIR_OUT | USB_TYPE_CLASS |
+ USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
+ 12, FPIX_TIMEOUT);
}
-/* Callback for URBs. */
-static void urb_callback(struct urb *urb)
+/* workqueue */
+static void dostream(struct work_struct *work)
{
- struct gspca_dev *gspca_dev = urb->context;
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
- PDEBUG(D_PACK,
- "enter urb_callback - status=%d, length=%d",
- urb->status, urb->actual_length);
-
- if (dev->state == FPIX_READ_FRAME)
- del_timer(&dev->bulk_timer);
-
- if (urb->status != 0) {
- /* We kill a stuck urb every 50 frames on average, so don't
- * display a log message for that. */
- if (urb->status != -ECONNRESET)
- PDEBUG(D_STREAM, "bad URB status %d", urb->status);
- dev_new_state(FPIX_RESET);
- schedule_delayed_work(&dev->wqe, 1);
- }
-
- switch (dev->state) {
- case FPIX_REQ_FRAME:
- dev_new_state(FPIX_READ_FRAME);
- read_frame_part(dev);
- break;
-
- case FPIX_READ_FRAME: {
- unsigned char *data = urb->transfer_buffer;
- struct gspca_frame *frame;
-
- frame = gspca_get_i_frame(&dev->gspca_dev);
- if (frame == NULL)
- gspca_dev->last_packet_type = DISCARD_PACKET;
- if (urb->actual_length < FPIX_MAX_TRANSFER ||
- (data[urb->actual_length-2] == 0xff &&
- data[urb->actual_length-1] == 0xd9)) {
-
- /* If the result is less than what was asked
- * for, then it's the end of the
- * frame. Sometime the jpeg is not complete,
- * but there's nothing we can do. We also end
- * here if the the jpeg ends right at the end
- * of the frame. */
- if (frame)
- gspca_frame_add(gspca_dev, LAST_PACKET,
- frame,
- data, urb->actual_length);
- dev_new_state(FPIX_REQ_FRAME);
- schedule_delayed_work(&dev->wqe, NEXT_FRAME_DELAY);
- } else {
+ struct usb_fpix *dev = container_of(work, struct usb_fpix, work_struct);
+ struct gspca_dev *gspca_dev = &dev->gspca_dev;
+ struct urb *urb = gspca_dev->urb[0];
+ u8 *data = urb->transfer_buffer;
+ struct gspca_frame *frame;
+ int ret = 0;
+ int len;
+
+ /* synchronize with the main driver */
+ mutex_lock(&gspca_dev->usb_lock);
+ mutex_unlock(&gspca_dev->usb_lock);
+ PDEBUG(D_STREAM, "dostream started");
+
+ /* loop reading a frame */
+again:
+ while (gspca_dev->present && gspca_dev->streaming) {
+
+ /* request a frame */
+ mutex_lock(&gspca_dev->usb_lock);
+ ret = command(gspca_dev, 1);
+ mutex_unlock(&gspca_dev->usb_lock);
+ if (ret < 0)
+ break;
+ if (!gspca_dev->present || !gspca_dev->streaming)
+ break;
+
+ /* the frame comes in parts */
+ for (;;) {
+ ret = usb_bulk_msg(gspca_dev->dev,
+ urb->pipe,
+ data,
+ FPIX_MAX_TRANSFER,
+ &len, FPIX_TIMEOUT);
+ if (ret < 0) {
+ /* Most of the time we get a timeout
+ * error. Just restart. */
+ goto again;
+ }
+ if (!gspca_dev->present || !gspca_dev->streaming)
+ goto out;
+ frame = gspca_get_i_frame(&dev->gspca_dev);
+ if (frame == NULL)
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+
+ if (len < FPIX_MAX_TRANSFER ||
+ (data[len - 2] == 0xff &&
+ data[len - 1] == 0xd9)) {
+
+ /* If the result is less than what was asked
+ * for, then it's the end of the
+ * frame. Sometimes the jpeg is not complete,
+ * but there's nothing we can do. We also end
+ * here if the the jpeg ends right at the end
+ * of the frame. */
+ if (frame)
+ frame = gspca_frame_add(gspca_dev,
+ LAST_PACKET,
+ frame,
+ data, len);
+ break;
+ }
/* got a partial image */
if (frame)
gspca_frame_add(gspca_dev,
gspca_dev->last_packet_type
- == LAST_PACKET
+ == LAST_PACKET
? FIRST_PACKET : INTER_PACKET,
- frame,
- data, urb->actual_length);
- read_frame_part(dev);
+ frame, data, len);
}
- break;
- }
-
- case FPIX_NOP:
- case FPIX_RESET:
- PDEBUG(D_STREAM, "invalid state %d", dev->state);
- break;
- }
-}
-/* Request a new frame */
-static void request_frame(struct usb_fpix *dev)
-{
- int ret;
- struct gspca_dev *gspca_dev = &dev->gspca_dev;
-
- /* Setup command packet */
- memset(gspca_dev->usb_buf, 0, 12);
- gspca_dev->usb_buf[0] = 0xd3;
- gspca_dev->usb_buf[7] = 0x01;
-
- /* Request a frame */
- dev->ctrlreq.bRequestType =
- USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
- dev->ctrlreq.bRequest = USB_REQ_GET_STATUS;
- dev->ctrlreq.wValue = 0;
- dev->ctrlreq.wIndex = 0;
- dev->ctrlreq.wLength = cpu_to_le16(12);
-
- usb_fill_control_urb(dev->control_urb,
- gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- (unsigned char *) &dev->ctrlreq,
- gspca_dev->usb_buf,
- 12, urb_callback, gspca_dev);
-
- ret = usb_submit_urb(dev->control_urb, GFP_ATOMIC);
- if (ret) {
- dev_new_state(FPIX_RESET);
- schedule_delayed_work(&dev->wqe, 1);
- PDEBUG(D_STREAM, "usb_submit_urb failed with %d", ret);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-/* State machine. */
-static void fpix_sm(struct work_struct *work)
-{
- struct usb_fpix *dev = container_of(work, struct usb_fpix, wqe.work);
-
- PDEBUG(D_STREAM, "fpix_sm state %d", dev->state);
-
- /* verify that the device wasn't unplugged */
- if (!dev->gspca_dev.present) {
- PDEBUG(D_STREAM, "device is gone");
- dev_new_state(FPIX_NOP);
- complete(&dev->can_close);
- return;
- }
-
- if (!dev->streaming) {
- PDEBUG(D_STREAM, "stopping state machine");
- dev_new_state(FPIX_NOP);
- complete(&dev->can_close);
- return;
+ /* We must wait before trying reading the next
+ * frame. If we don't, or if the delay is too short,
+ * the camera will disconnect. */
+ msleep(NEXT_FRAME_DELAY);
}
- switch (dev->state) {
- case FPIX_RESET:
- dev_new_state(FPIX_REQ_FRAME);
- schedule_delayed_work(&dev->wqe, HZ / 10);
- break;
-
- case FPIX_REQ_FRAME:
- /* get an image */
- request_frame(dev);
- break;
-
- case FPIX_NOP:
- case FPIX_READ_FRAME:
- PDEBUG(D_STREAM, "invalid state %d", dev->state);
- break;
- }
+out:
+ PDEBUG(D_STREAM, "dostream stopped");
}
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
+ struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
struct cam *cam = &gspca_dev->cam;
cam->cam_mode = fpix_mode;
cam->nmodes = 1;
- cam->epaddr = 0x01; /* todo: correct for all cams? */
cam->bulk_size = FPIX_MAX_TRANSFER;
-/* gspca_dev->nbalt = 1; * use bulk transfer */
- return 0;
-}
-
-/* Stop streaming and free the ressources allocated by sd_start. */
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
- dev->streaming = 0;
-
- /* Stop the state machine */
- if (dev->state != FPIX_NOP)
- wait_for_completion(&dev->can_close);
-}
-
-/* called on streamoff with alt 0 and disconnect */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
- usb_free_urb(dev->control_urb);
- dev->control_urb = NULL;
-}
-
-/* Kill an URB that hasn't completed. */
-static void timeout_kill(unsigned long data)
-{
- struct urb *urb = (struct urb *) data;
+ INIT_WORK(&dev->work_struct, dostream);
- usb_unlink_urb(urb);
+ return 0;
}
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
- INIT_DELAYED_WORK(&dev->wqe, fpix_sm);
-
- init_timer(&dev->bulk_timer);
- dev->bulk_timer.function = timeout_kill;
-
return 0;
}
+/* start the camera */
static int sd_start(struct gspca_dev *gspca_dev)
{
struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
- int ret;
- int size_ret;
+ int ret, len;
/* Init the device */
- memset(gspca_dev->usb_buf, 0, 12);
- gspca_dev->usb_buf[0] = 0xc6;
- gspca_dev->usb_buf[8] = 0x20;
-
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- USB_REQ_GET_STATUS,
- USB_DIR_OUT | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
- 12, FPIX_TIMEOUT);
-
- if (ret != 12) {
- PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret);
- ret = -EIO;
- goto error;
+ ret = command(gspca_dev, 0);
+ if (ret < 0) {
+ PDEBUG(D_STREAM, "init failed %d", ret);
+ return ret;
}
/* Read the result of the command. Ignore the result, for it
* varies with the device. */
ret = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev,
- gspca_dev->cam.epaddr),
- gspca_dev->usb_buf, FPIX_MAX_TRANSFER, &size_ret,
+ gspca_dev->urb[0]->pipe,
+ gspca_dev->urb[0]->transfer_buffer,
+ FPIX_MAX_TRANSFER, &len,
FPIX_TIMEOUT);
- if (ret != 0) {
- PDEBUG(D_STREAM, "usb_bulk_msg failed (%d)", ret);
- ret = -EIO;
- goto error;
+ if (ret < 0) {
+ PDEBUG(D_STREAM, "usb_bulk_msg failed %d", ret);
+ return ret;
}
/* Request a frame, but don't read it */
- memset(gspca_dev->usb_buf, 0, 12);
- gspca_dev->usb_buf[0] = 0xd3;
- gspca_dev->usb_buf[7] = 0x01;
-
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- USB_REQ_GET_STATUS,
- USB_DIR_OUT | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
- 12, FPIX_TIMEOUT);
- if (ret != 12) {
- PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret);
- ret = -EIO;
- goto error;
+ ret = command(gspca_dev, 1);
+ if (ret < 0) {
+ PDEBUG(D_STREAM, "frame request failed %d", ret);
+ return ret;
}
/* Again, reset bulk in endpoint */
- usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr);
-
- /* Allocate a control URB */
- dev->control_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->control_urb) {
- PDEBUG(D_STREAM, "No free urbs available");
- ret = -EIO;
- goto error;
- }
-
- /* Various initializations. */
- init_completion(&dev->can_close);
- dev->bulk_timer.data = (unsigned long)dev->gspca_dev.urb[0];
- dev->gspca_dev.urb[0]->complete = urb_callback;
- dev->streaming = 1;
+ usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
- /* Schedule a frame request. */
- dev_new_state(FPIX_REQ_FRAME);
- schedule_delayed_work(&dev->wqe, 1);
+ /* Start the workqueue function to do the streaming */
+ dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
+ queue_work(dev->work_thread, &dev->work_struct);
return 0;
+}
+
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-error:
- /* Free the ressources */
- sd_stopN(gspca_dev);
- sd_stop0(gspca_dev);
- return ret;
+ /* wait for the work queue to terminate */
+ mutex_unlock(&gspca_dev->usb_lock);
+ destroy_workqueue(dev->work_thread);
+ mutex_lock(&gspca_dev->usb_lock);
+ dev->work_thread = NULL;
}
/* Table of supported USB devices */
@@ -424,12 +268,11 @@ MODULE_DEVICE_TABLE(usb, device_table);
/* sub-driver description */
static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
+ .name = MODULE_NAME,
.config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .stop0 = sd_stop0,
+ .init = sd_init,
+ .start = sd_start,
+ .stop0 = sd_stop0,
};
/* -- device connect -- */
@@ -443,24 +286,28 @@ static int sd_probe(struct usb_interface *intf,
}
static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
.disconnect = gspca_disconnect,
#ifdef CONFIG_PM
.suspend = gspca_suspend,
- .resume = gspca_resume,
+ .resume = gspca_resume,
#endif
};
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
+
static void __exit sd_mod_exit(void)
{
usb_deregister(&sd_driver);
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 65e4901f4db7..a75c1ca2db41 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -38,15 +38,16 @@
#include "gspca.h"
/* global values */
-#define DEF_NURBS 2 /* default number of URBs */
+#define DEF_NURBS 3 /* default number of URBs */
+#if DEF_NURBS > MAX_NURBS
+#error "DEF_NURBS too big"
+#endif
MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("GSPCA USB Camera Driver");
MODULE_LICENSE("GPL");
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 4, 0)
-
-static int video_nr = -1;
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 5, 0)
#ifdef GSPCA_DEBUG
int gspca_debug = D_ERR | D_PROBE;
@@ -126,16 +127,18 @@ static void fill_frame(struct gspca_dev *gspca_dev,
struct urb *urb)
{
struct gspca_frame *frame;
- __u8 *data; /* address of data in the iso message */
+ u8 *data; /* address of data in the iso message */
int i, len, st;
cam_pkt_op pkt_scan;
if (urb->status != 0) {
+ if (urb->status == -ESHUTDOWN)
+ return; /* disconnection */
#ifdef CONFIG_PM
if (!gspca_dev->frozen)
#endif
PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
- return; /* disconnection ? */
+ return;
}
pkt_scan = gspca_dev->sd_desc->pkt_scan;
for (i = 0; i < urb->number_of_packets; i++) {
@@ -166,7 +169,7 @@ static void fill_frame(struct gspca_dev *gspca_dev,
/* let the packet be analyzed by the subdriver */
PDEBUG(D_PACK, "packet [%d] o:%d l:%d",
i, urb->iso_frame_desc[i].offset, len);
- data = (__u8 *) urb->transfer_buffer
+ data = (u8 *) urb->transfer_buffer
+ urb->iso_frame_desc[i].offset;
pkt_scan(gspca_dev, frame, data, len);
}
@@ -182,8 +185,7 @@ static void fill_frame(struct gspca_dev *gspca_dev,
*
* Analyse each packet and call the subdriver for copy to the frame buffer.
*/
-static void isoc_irq(struct urb *urb
-)
+static void isoc_irq(struct urb *urb)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
@@ -196,8 +198,7 @@ static void isoc_irq(struct urb *urb
/*
* bulk message interrupt from the USB device
*/
-static void bulk_irq(struct urb *urb
-)
+static void bulk_irq(struct urb *urb)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
struct gspca_frame *frame;
@@ -209,6 +210,8 @@ static void bulk_irq(struct urb *urb
switch (urb->status) {
case 0:
break;
+ case -ESHUTDOWN:
+ return; /* disconnection */
case -ECONNRESET:
urb->status = 0;
break;
@@ -217,7 +220,7 @@ static void bulk_irq(struct urb *urb
if (!gspca_dev->frozen)
#endif
PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
- return; /* disconnection ? */
+ return;
}
/* check the availability of the frame buffer */
@@ -322,6 +325,7 @@ static int gspca_is_compressed(__u32 format)
case V4L2_PIX_FMT_JPEG:
case V4L2_PIX_FMT_SPCA561:
case V4L2_PIX_FMT_PAC207:
+ case V4L2_PIX_FMT_MR97310A:
return 1;
}
return 0;
@@ -422,10 +426,8 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
if (urb == NULL)
break;
- BUG_ON(!gspca_dev->dev);
gspca_dev->urb[i] = NULL;
- if (!gspca_dev->present)
- usb_kill_urb(urb);
+ usb_kill_urb(urb);
if (urb->transfer_buffer != NULL)
usb_buffer_free(gspca_dev->dev,
urb->transfer_buffer_length,
@@ -439,22 +441,16 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
* look for an input transfer endpoint in an alternate setting
*/
static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
- __u8 epaddr,
__u8 xfer)
{
struct usb_host_endpoint *ep;
int i, attr;
- epaddr |= USB_DIR_IN;
for (i = 0; i < alt->desc.bNumEndpoints; i++) {
ep = &alt->endpoint[i];
- if (ep->desc.bEndpointAddress == epaddr) {
- attr = ep->desc.bmAttributes
- & USB_ENDPOINT_XFERTYPE_MASK;
- if (attr == xfer)
- return ep;
- break;
- }
+ attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+ if (attr == xfer)
+ return ep;
}
return NULL;
}
@@ -478,23 +474,23 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
i = gspca_dev->alt; /* previous alt setting */
/* try isoc */
- while (--i > 0) { /* alt 0 is unusable */
+ while (--i >= 0) {
ep = alt_xfer(&intf->altsetting[i],
- gspca_dev->cam.epaddr,
USB_ENDPOINT_XFER_ISOC);
if (ep)
break;
}
- /* if no isoc, try bulk */
+ /* if no isoc, try bulk (alt 0 only) */
if (ep == NULL) {
ep = alt_xfer(&intf->altsetting[0],
- gspca_dev->cam.epaddr,
USB_ENDPOINT_XFER_BULK);
if (ep == NULL) {
err("no transfer endpoint found");
return NULL;
}
+ i = 0;
+ gspca_dev->bulk = 1;
}
PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
i, ep->desc.bEndpointAddress);
@@ -521,7 +517,7 @@ static int create_urbs(struct gspca_dev *gspca_dev,
/* calculate the packet size and the number of packets */
psize = le16_to_cpu(ep->desc.wMaxPacketSize);
- if (gspca_dev->alt != 0) { /* isoc */
+ if (!gspca_dev->bulk) { /* isoc */
/* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
@@ -601,6 +597,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
+ if (!gspca_dev->present) {
+ ret = -ENODEV;
+ goto out;
+ }
+
/* set the higher alternate setting and
* loop until urb submit succeeds */
gspca_dev->alt = gspca_dev->nbalt;
@@ -616,10 +617,9 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
goto out;
/* clear the bulk endpoint */
- if (gspca_dev->alt == 0) /* if bulk transfer */
+ if (gspca_dev->bulk)
usb_clear_halt(gspca_dev->dev,
- usb_rcvintpipe(gspca_dev->dev,
- gspca_dev->cam.epaddr));
+ gspca_dev->urb[0]->pipe);
/* start the cam */
ret = gspca_dev->sd_desc->start(gspca_dev);
@@ -630,7 +630,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
gspca_dev->streaming = 1;
/* some bulk transfers are started by the subdriver */
- if (gspca_dev->alt == 0 && gspca_dev->cam.bulk_nurbs == 0)
+ if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0)
break;
/* submit the URBs */
@@ -671,11 +671,14 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
static void gspca_stream_off(struct gspca_dev *gspca_dev)
{
gspca_dev->streaming = 0;
- if (gspca_dev->present
- && gspca_dev->sd_desc->stopN)
- gspca_dev->sd_desc->stopN(gspca_dev);
- destroy_urbs(gspca_dev);
- gspca_set_alt0(gspca_dev);
+ if (gspca_dev->present) {
+ if (gspca_dev->sd_desc->stopN)
+ gspca_dev->sd_desc->stopN(gspca_dev);
+ destroy_urbs(gspca_dev);
+ gspca_set_alt0(gspca_dev);
+ }
+
+ /* always call stop0 to free the subdriver's resources */
if (gspca_dev->sd_desc->stop0)
gspca_dev->sd_desc->stop0(gspca_dev);
PDEBUG(D_STREAM, "stream off OK");
@@ -762,7 +765,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
fmtdesc->pixelformat = fmt_tb[index];
if (gspca_is_compressed(fmt_tb[index]))
fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
- fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmtdesc->description[0] = fmtdesc->pixelformat & 0xff;
fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff;
fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff;
@@ -957,8 +959,15 @@ static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
struct gspca_dev *gspca_dev = priv;
+ int ret;
- memset(cap, 0, sizeof *cap);
+ /* protect the access to the usb device */
+ if (mutex_lock_interruptible(&gspca_dev->usb_lock))
+ return -ERESTARTSYS;
+ if (!gspca_dev->present) {
+ ret = -ENODEV;
+ goto out;
+ }
strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
if (gspca_dev->dev->product != NULL) {
strncpy(cap->card, gspca_dev->dev->product,
@@ -969,13 +978,15 @@ static int vidioc_querycap(struct file *file, void *priv,
le16_to_cpu(gspca_dev->dev->descriptor.idVendor),
le16_to_cpu(gspca_dev->dev->descriptor.idProduct));
}
- strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name,
- sizeof cap->bus_info);
+ usb_make_path(gspca_dev->dev, cap->bus_info, sizeof(cap->bus_info));
cap->version = DRIVER_VERSION_NUMBER;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_STREAMING
| V4L2_CAP_READWRITE;
- return 0;
+ ret = 0;
+out:
+ mutex_unlock(&gspca_dev->usb_lock);
+ return ret;
}
static int vidioc_queryctrl(struct file *file, void *priv,
@@ -1038,7 +1049,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = ctrls->set(gspca_dev, ctrl->value);
+ if (gspca_dev->present)
+ ret = ctrls->set(gspca_dev, ctrl->value);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1062,7 +1076,10 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = ctrls->get(gspca_dev, &ctrl->value);
+ if (gspca_dev->present)
+ ret = ctrls->get(gspca_dev, &ctrl->value);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1081,7 +1098,6 @@ static int vidioc_s_audio(struct file *file, void *priv,
static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *audio)
{
- memset(audio, 0, sizeof *audio);
strcpy(audio->name, "Microphone");
return 0;
}
@@ -1115,7 +1131,6 @@ static int vidioc_enum_input(struct file *file, void *priv,
if (input->index != 0)
return -EINVAL;
- memset(input, 0, sizeof *input);
input->type = V4L2_INPUT_TYPE_CAMERA;
strncpy(input->name, gspca_dev->sd_desc->name,
sizeof input->name);
@@ -1224,10 +1239,7 @@ static int vidioc_streamon(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
- if (!gspca_dev->present) {
- ret = -ENODEV;
- goto out;
- }
+
if (gspca_dev->nframes == 0
|| !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) {
ret = -EINVAL;
@@ -1295,7 +1307,10 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1310,7 +1325,10 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1320,8 +1338,6 @@ static int vidioc_g_parm(struct file *filp, void *priv,
{
struct gspca_dev *gspca_dev = priv;
- memset(parm, 0, sizeof *parm);
- parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
parm->parm.capture.readbuffers = gspca_dev->nbufread;
if (gspca_dev->sd_desc->get_streamparm) {
@@ -1329,7 +1345,11 @@ static int vidioc_g_parm(struct file *filp, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, parm);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->get_streamparm(gspca_dev,
+ parm);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1354,7 +1374,11 @@ static int vidioc_s_parm(struct file *filp, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, parm);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->set_streamparm(gspca_dev,
+ parm);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1382,7 +1406,6 @@ static int vidiocgmbuf(struct file *file, void *priv,
{
struct v4l2_format fmt;
- memset(&fmt, 0, sizeof fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
i = gspca_dev->cam.nmodes - 1; /* highest mode */
fmt.fmt.pix.width = gspca_dev->cam.cam_mode[i].width;
@@ -1528,7 +1551,8 @@ static int frame_wait(struct gspca_dev *gspca_dev,
if (gspca_dev->sd_desc->dq_callback) {
mutex_lock(&gspca_dev->usb_lock);
- gspca_dev->sd_desc->dq_callback(gspca_dev);
+ if (gspca_dev->present)
+ gspca_dev->sd_desc->dq_callback(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
}
return j;
@@ -1550,6 +1574,9 @@ static int vidioc_dqbuf(struct file *file, void *priv,
if (v4l2_buf->memory != gspca_dev->memory)
return -EINVAL;
+ if (!gspca_dev->present)
+ return -ENODEV;
+
/* if not streaming, be sure the application will not loop forever */
if (!(file->f_flags & O_NONBLOCK)
&& !gspca_dev->streaming && gspca_dev->users == 1)
@@ -1700,8 +1727,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
PDEBUG(D_FRAM, "poll");
poll_wait(file, &gspca_dev->wq, wait);
- if (!gspca_dev->present)
- return POLLERR;
/* if reqbufs is not done, the user would use read() */
if (gspca_dev->nframes == 0) {
@@ -1714,10 +1739,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0)
return POLLERR;
- if (!gspca_dev->present) {
- ret = POLLERR;
- goto out;
- }
/* check the next incoming buffer */
i = gspca_dev->fr_o;
@@ -1726,8 +1747,9 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
ret = POLLIN | POLLRDNORM; /* something to read */
else
ret = 0;
-out:
mutex_unlock(&gspca_dev->queue_lock);
+ if (!gspca_dev->present)
+ return POLLHUP;
return ret;
}
@@ -1925,7 +1947,7 @@ int gspca_dev_probe(struct usb_interface *intf,
gspca_dev->present = 1;
ret = video_register_device(&gspca_dev->vdev,
VFL_TYPE_GRABBER,
- video_nr);
+ -1);
if (ret < 0) {
err("video_register_device err %d", ret);
goto out;
@@ -1953,10 +1975,16 @@ void gspca_disconnect(struct usb_interface *intf)
mutex_lock(&gspca_dev->usb_lock);
gspca_dev->present = 0;
- mutex_unlock(&gspca_dev->usb_lock);
- destroy_urbs(gspca_dev);
+ if (gspca_dev->streaming) {
+ destroy_urbs(gspca_dev);
+ wake_up_interruptible(&gspca_dev->wq);
+ }
+
+ /* the device is freed at exit of this function */
gspca_dev->dev = NULL;
+ mutex_unlock(&gspca_dev->usb_lock);
+
usb_set_intfdata(intf, NULL);
/* release the device */
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index c90af9cb1e07..e4d4cf6ce05a 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -33,19 +33,13 @@ extern int gspca_debug;
#endif
#undef err
#define err(fmt, args...) \
- do {\
- printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args); \
- } while (0)
+ printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args)
#undef info
#define info(fmt, args...) \
- do {\
- printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \
- } while (0)
+ printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args)
#undef warn
#define warn(fmt, args...) \
- do {\
- printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args); \
- } while (0)
+ printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args)
#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */
/* image transfers */
@@ -62,7 +56,6 @@ struct cam {
* - cannot be > MAX_NURBS
* - when 0 and bulk_size != 0 means
* 1 URB and submit done by subdriver */
- __u8 epaddr;
};
struct gspca_dev;
@@ -174,6 +167,7 @@ struct gspca_dev {
__u8 iface; /* USB interface number */
__u8 alt; /* USB alternate setting */
__u8 nbalt; /* number of USB alternate settings */
+ u8 bulk; /* image transfer by 0:isoc / 1:bulk */
};
int gspca_dev_probe(struct usb_interface *intf,
diff --git a/drivers/media/video/gspca/jpeg.h b/drivers/media/video/gspca/jpeg.h
index d823b47bd4e6..de63c36806c0 100644
--- a/drivers/media/video/gspca/jpeg.h
+++ b/drivers/media/video/gspca/jpeg.h
@@ -24,171 +24,39 @@
*
*/
-/* start of jpeg frame + quantization table */
-static const unsigned char quant[][0x88] = {
-/* index 0 - Q40*/
- {
+/*
+ * generation options
+ * CONEX_CAM Conexant if present
+ */
+
+/* JPEG header */
+static const u8 jpeg_head[] = {
0xff, 0xd8, /* jpeg */
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0, /* quantization table part 1 */
- 20, 14, 15, 18, 15, 13, 20, 18, 16, 18, 23, 21, 20, 24, 30, 50,
- 33, 30, 28, 28, 30, 61, 44, 46, 36, 50, 73, 64, 76, 75, 71, 64,
- 70, 69, 80, 90, 115, 98, 80, 85, 109, 86, 69, 70, 100, 136, 101,
- 109,
- 119, 123, 129, 130, 129, 78, 96, 141, 151, 140, 125, 150, 115,
- 126, 129, 124,
-1, /* quantization table part 2 */
- 21, 23, 23, 30, 26, 30, 59, 33, 33, 59, 124, 83, 70, 83, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124},
-/* index 1 - Q50 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40,
- 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51,
- 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80, 109, 81, 87,
- 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101,
- 103, 99,
-1,
- 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99},
-/* index 2 Q60 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 13, 9, 10, 11, 10, 8, 13, 11, 10, 11, 14, 14, 13, 15, 19, 32,
- 21, 19, 18, 18, 19, 39, 28, 30, 23, 32, 46, 41, 49, 48, 46, 41,
- 45, 44, 51, 58, 74, 62, 51, 54, 70, 55, 44, 45, 64, 87, 65, 70,
- 76, 78, 82, 83, 82, 50, 62, 90, 97, 90, 80, 96, 74, 81, 82, 79,
-1,
- 14, 14, 14, 19, 17, 19, 38, 21, 21, 38, 79, 53, 45, 53, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79},
-/* index 3 - Q70 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 10, 7, 7, 8, 7, 6, 10, 8, 8, 8, 11, 10, 10, 11, 14, 24,
- 16, 14, 13, 13, 14, 29, 21, 22, 17, 24, 35, 31, 37, 36, 34, 31,
- 34, 33, 38, 43, 55, 47, 38, 41, 52, 41, 33, 34, 48, 65, 49, 52,
- 57, 59, 62, 62, 62, 37, 46, 68, 73, 67, 60, 72, 55, 61, 62, 59,
-1,
- 10, 11, 11, 14, 13, 14, 28, 16, 16, 28, 59, 40, 34, 40, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59},
-/* index 4 - Q80 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 6, 4, 5, 6, 5, 4, 6, 6, 5, 6, 7, 7, 6, 8, 10, 16,
- 10, 10, 9, 9, 10, 20, 14, 15, 12, 16, 23, 20, 24, 24, 23, 20,
- 22, 22, 26, 29, 37, 31, 26, 27, 35, 28, 22, 22, 32, 44, 32, 35,
- 38, 39, 41, 42, 41, 25, 31, 45, 48, 45, 40, 48, 37, 40, 41, 40,
-1,
- 7, 7, 7, 10, 8, 10, 19, 10, 10, 19, 40, 26, 22, 26, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40},
-/* index 5 - Q85 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, 7, 12,
- 8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, 18, 17, 15,
- 17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, 24, 33, 24, 26,
- 29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, 36, 28, 30, 31, 30,
-1,
- 5, 5, 5, 7, 6, 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
-/* index 6 - 86 */
-{
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x04,
- 0x04, 0x04, 0x05, 0x05, 0x04, 0x05, 0x07, 0x0B,
- 0x07, 0x07, 0x06, 0x06, 0x07, 0x0E, 0x0A, 0x0A,
- 0x08, 0x0B, 0x10, 0x0E, 0x11, 0x11, 0x10, 0x0E,
- 0x10, 0x0F, 0x12, 0x14, 0x1A, 0x16, 0x12, 0x13,
- 0x18, 0x13, 0x0F, 0x10, 0x16, 0x1F, 0x17, 0x18,
- 0x1B, 0x1B, 0x1D, 0x1D, 0x1D, 0x11, 0x16, 0x20,
- 0x22, 0x1F, 0x1C, 0x22, 0x1A, 0x1C, 0x1D, 0x1C,
-1,
- 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0D, 0x07,
- 0x07, 0x0D, 0x1C, 0x12, 0x10, 0x12, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- },
-/* index 7 - 88 */
-{
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x04, 0x03,
- 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x06, 0x0A,
- 0x06, 0x06, 0x05, 0x05, 0x06, 0x0C, 0x08, 0x09,
- 0x07, 0x0A, 0x0E, 0x0C, 0x0F, 0x0E, 0x0E, 0x0C,
- 0x0D, 0x0D, 0x0F, 0x11, 0x16, 0x13, 0x0F, 0x10,
- 0x15, 0x11, 0x0D, 0x0D, 0x13, 0x1A, 0x13, 0x15,
- 0x17, 0x18, 0x19, 0x19, 0x19, 0x0F, 0x12, 0x1B,
- 0x1D, 0x1B, 0x18, 0x1D, 0x16, 0x18, 0x19, 0x18,
-1,
- 0x04, 0x04, 0x04, 0x06, 0x05, 0x06, 0x0B, 0x06,
- 0x06, 0x0B, 0x18, 0x10, 0x0D, 0x10, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-},
-/* index 8 - ?? */
-{
- 0xff, 0xd8,
+
+/* quantization table quality 50% */
0xff, 0xdb, 0x00, 0x84, /* DQT */
0,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x05,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x05,
- 0x04, 0x05, 0x07, 0x06, 0x08, 0x08, 0x07, 0x06,
- 0x07, 0x07, 0x08, 0x09, 0x0C, 0x0A, 0x08, 0x09,
- 0x0B, 0x09, 0x07, 0x07, 0x0A, 0x0E, 0x0A, 0x0B,
- 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x08, 0x0A, 0x0E,
- 0x0F, 0x0E, 0x0D, 0x0F, 0x0C, 0x0D, 0x0D, 0x0C,
+#define JPEG_QT0_OFFSET 7
+ 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
+ 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
+ 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
+ 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
+ 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
+ 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
+ 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
+ 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
1,
- 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x06, 0x03,
- 0x03, 0x06, 0x0C, 0x08, 0x07, 0x08, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C
-}
-};
+#define JPEG_QT1_OFFSET 72
+ 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
+ 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-/* huffman table + start of SOF0 */
-static unsigned char huffman[] = {
+/* huffman table */
0xff, 0xc4, 0x01, 0xa2,
0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -244,58 +112,57 @@ static unsigned char huffman[] = {
0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
#ifdef CONEX_CAM
/* the Conexant frames start with SOF0 */
+#define JPEG_HDR_SZ 556
#else
0xff, 0xc0, 0x00, 0x11, /* SOF0 (start of frame 0 */
0x08, /* data precision */
-#endif
-};
-
-#ifndef CONEX_CAM
-/* variable part:
- * 0x01, 0xe0, height
- * 0x02, 0x80, width
- * 0x03, component number
- * 0x01,
- * 0x21, samples Y
- */
-
-/* end of header */
-static unsigned char eoh[] = {
+#define JPEG_HEIGHT_OFFSET 561
+ 0x01, 0xe0, /* height */
+ 0x02, 0x80, /* width */
+ 0x03, /* component number */
+ 0x01,
+ 0x21, /* samples Y */
0x00, /* quant Y */
0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */
0x03, 0x11, 0x01,
0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan) */
0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
-};
+#define JPEG_HDR_SZ 589
#endif
+};
-/* -- output the JPEG header -- */
-static void jpeg_put_header(struct gspca_dev *gspca_dev,
- struct gspca_frame *frame,
- int qindex,
- int samplesY)
+/* define the JPEG header */
+static void jpeg_define(u8 *jpeg_hdr,
+ int height,
+ int width,
+ int samplesY)
{
+ memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head);
#ifndef CONEX_CAM
- unsigned char tmpbuf[8];
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8;
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height & 0xff;
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8;
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width & 0xff;
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 6] = samplesY;
#endif
+}
- gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
- (unsigned char *) quant[qindex], sizeof quant[0]);
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- (unsigned char *) huffman, sizeof huffman);
-#ifndef CONEX_CAM
- tmpbuf[0] = gspca_dev->height >> 8;
- tmpbuf[1] = gspca_dev->height & 0xff;
- tmpbuf[2] = gspca_dev->width >> 8;
- tmpbuf[3] = gspca_dev->width & 0xff;
- tmpbuf[4] = 0x03; /* component number */
- tmpbuf[5] = 0x01; /* first component */
- tmpbuf[6] = samplesY;
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- tmpbuf, 7);
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- eoh, sizeof eoh);
-#endif
+/* set the JPEG quality */
+static void jpeg_set_qual(u8 *jpeg_hdr,
+ int quality)
+{
+ int i, sc;
+
+ if (quality < 50)
+ sc = 5000 / quality;
+ else
+ sc = 200 - quality * 2;
+ for (i = 0; i < 64; i++) {
+ jpeg_hdr[JPEG_QT0_OFFSET + i] =
+ (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
+ jpeg_hdr[JPEG_QT1_OFFSET + i] =
+ (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
+ }
}
#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index ed906fe31287..b35e4838a6e5 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -332,7 +332,6 @@ static int m5602_configure(struct gspca_dev *gspca_dev,
int err;
cam = &gspca_dev->cam;
- cam->epaddr = M5602_ISOC_ENDPOINT_ADDR;
sd->desc = &sd_desc;
if (dump_bridge)
@@ -374,8 +373,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init mod_m5602_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 3d2090e67a63..75e8d14e4ac7 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -32,17 +32,91 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- char qindex;
+ u8 brightness;
+ u8 colors;
+ u8 gamma;
+ u8 sharpness;
+ u8 quality;
+#define QUALITY_MIN 40
+#define QUALITY_MAX 70
+#define QUALITY_DEF 50
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
+
static struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 30,
+ .step = 1,
+#define BRIGHTNESS_DEF 15
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color",
+ .minimum = 1,
+ .maximum = 255,
+ .step = 1,
+#define COLOR_DEF 200
+ .default_value = COLOR_DEF,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+ {
+ {
+ .id = V4L2_CID_GAMMA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gamma",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+#define GAMMA_DEF 1
+ .default_value = GAMMA_DEF,
+ },
+ .set = sd_setgamma,
+ .get = sd_getgamma,
+ },
+ {
+ {
+ .id = V4L2_CID_SHARPNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Sharpness",
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+#define SHARPNESS_DEF 1
+ .default_value = SHARPNESS_DEF,
+ },
+ .set = sd_setsharpness,
+ .get = sd_getsharpness,
+ },
};
static const struct v4l2_pix_format vga_mode[] = {
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 589,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
.priv = 2},
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -52,65 +126,45 @@ static const struct v4l2_pix_format vga_mode[] = {
.priv = 1},
};
-/* MI Register table //elvis */
-enum {
- REG_HW_MI_0,
- REG_HW_MI_1,
- REG_HW_MI_2,
- REG_HW_MI_3,
- REG_HW_MI_4,
- REG_HW_MI_5,
- REG_HW_MI_6,
- REG_HW_MI_7,
- REG_HW_MI_9 = 0x09,
- REG_HW_MI_B = 0x0B,
- REG_HW_MI_C,
- REG_HW_MI_D,
- REG_HW_MI_1E = 0x1E,
- REG_HW_MI_20 = 0x20,
- REG_HW_MI_2B = 0x2B,
- REG_HW_MI_2C,
- REG_HW_MI_2D,
- REG_HW_MI_2E,
- REG_HW_MI_35 = 0x35,
- REG_HW_MI_5F = 0x5f,
- REG_HW_MI_60,
- REG_HW_MI_61,
- REG_HW_MI_62,
- REG_HW_MI_63,
- REG_HW_MI_64,
- REG_HW_MI_F1 = 0xf1,
- ATTR_TOTAL_MI_REG = 0xf2
+static const __u8 mi_data[0x20] = {
+/* 01 02 03 04 05 06 07 08 */
+ 0x48, 0x22, 0x01, 0x47, 0x10, 0x00, 0x00, 0x00,
+/* 09 0a 0b 0c 0d 0e 0f 10 */
+ 0x00, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01,
+/* 11 12 13 14 15 16 17 18 */
+ 0x30, 0x00, 0x04, 0x00, 0x06, 0x01, 0xe2, 0x02,
+/* 19 1a 1b 1c 1d 1e 1f 20 */
+ 0x82, 0x00, 0x20, 0x17, 0x80, 0x08, 0x0c, 0x00
};
-/* the bytes to write are in gspca_dev->usb_buf */
+/* write <len> bytes from gspca_dev->usb_buf */
static int reg_w(struct gspca_dev *gspca_dev,
- __u16 index, int len)
+ int len)
{
- int rc;
-
- rc = usb_control_msg(gspca_dev->dev,
- usb_sndbulkpipe(gspca_dev->dev, 4),
- 0x12,
- 0xc8, /* ?? */
- 0, /* value */
- index, gspca_dev->usb_buf, len, 500);
- if (rc < 0)
- PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
- return rc;
+ int alen, ret;
+
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_sndbulkpipe(gspca_dev->dev, 4),
+ gspca_dev->usb_buf,
+ len,
+ &alen,
+ 500); /* timeout in milliseconds */
+ if (ret < 0)
+ PDEBUG(D_ERR, "reg write [%02x] error %d",
+ gspca_dev->usb_buf[0], ret);
+ return ret;
}
-static void bulk_w(struct gspca_dev *gspca_dev,
- __u16 *pch,
- __u16 Address)
+static void mi_w(struct gspca_dev *gspca_dev,
+ u8 addr,
+ u8 value)
{
gspca_dev->usb_buf[0] = 0x1f;
gspca_dev->usb_buf[1] = 0; /* control byte */
- gspca_dev->usb_buf[2] = Address;
- gspca_dev->usb_buf[3] = *pch >> 8; /* high byte */
- gspca_dev->usb_buf[4] = *pch; /* low byte */
+ gspca_dev->usb_buf[2] = addr;
+ gspca_dev->usb_buf[3] = value;
- reg_w(gspca_dev, Address, 5);
+ reg_w(gspca_dev, 4);
}
/* this function is called at probe time */
@@ -121,10 +175,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
- sd->qindex = 1; /* set the quantization table */
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->colors = COLOR_DEF;
+ sd->gamma = GAMMA_DEF;
+ sd->sharpness = SHARPNESS_DEF;
+ sd->quality = QUALITY_DEF;
+ gspca_dev->nbalt = 9; /* use the altsetting 08 */
return 0;
}
@@ -136,24 +194,22 @@ static int sd_init(struct gspca_dev *gspca_dev)
static int sd_start(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
int err_code;
- __u8 *data;
- __u16 *MI_buf;
- int h_size, v_size;
- int intpipe;
-
- PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface);
- err_code = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8);
- if (err_code < 0) {
- PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error");
- return err_code;
- }
+ u8 *data;
+ int i;
+
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x21); /* JPEG 422 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
data = gspca_dev->usb_buf;
+
data[0] = 0x01; /* address */
data[1] = 0x01;
-
- err_code = reg_w(gspca_dev, data[0], 2);
+ err_code = reg_w(gspca_dev, 2);
if (err_code < 0)
return err_code;
@@ -163,30 +219,28 @@ static int sd_start(struct gspca_dev *gspca_dev)
data[0] = 0x00; /* address */
data[1] = 0x0c | 0x01; /* reg 0 */
data[2] = 0x01; /* reg 1 */
- h_size = gspca_dev->width;
- v_size = gspca_dev->height;
- data[3] = h_size / 8; /* h_size , reg 2 */
- data[4] = v_size / 8; /* v_size , reg 3 */
+ data[3] = gspca_dev->width / 8; /* h_size , reg 2 */
+ data[4] = gspca_dev->height / 8; /* v_size , reg 3 */
data[5] = 0x30; /* reg 4, MI, PAS5101 :
* 0x30 for 24mhz , 0x28 for 12mhz */
- data[6] = 4; /* reg 5, H start */
- data[7] = 0xc0; /* reg 6, gamma 1.5 */
- data[8] = 3; /* reg 7, V start */
+ data[6] = 0x02; /* reg 5, H start - was 0x04 */
+ data[7] = sd->gamma * 0x40; /* reg 0x06: gamma */
+ data[8] = 0x01; /* reg 7, V start - was 0x03 */
/* if (h_size == 320 ) */
/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */
/* else */
data[9] = 0x52; /* reg 8, 24MHz, no scale down */
- data[10] = 0x5d; /* reg 9, I2C device address
- * [for PAS5101 (0x40)] [for MI (0x5d)] */
+/*jfm: from win trace*/
+ data[10] = 0x18;
- err_code = reg_w(gspca_dev, data[0], 11);
+ err_code = reg_w(gspca_dev, 11);
if (err_code < 0)
return err_code;
data[0] = 0x23; /* address */
data[1] = 0x09; /* reg 35, append frame header */
- err_code = reg_w(gspca_dev, data[0], 2);
+ err_code = reg_w(gspca_dev, 2);
if (err_code < 0)
return err_code;
@@ -197,137 +251,57 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* else */
data[1] = 50; /* 50 reg 60, pc-cam frame size
* (unit: 4KB) 200KB */
- err_code = reg_w(gspca_dev, data[0], 2);
+ err_code = reg_w(gspca_dev, 2);
if (err_code < 0)
return err_code;
- if (0) { /* fixed dark-gain */
- data[1] = 0; /* reg 94, Y Gain (1.75) */
- data[2] = 0; /* reg 95, UV Gain (1.75) */
- data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable
- * auto dark-gain */
- data[4] = 0; /* reg 97, set fixed dark level */
- data[5] = 0; /* reg 98, don't care */
- } else { /* auto dark-gain */
- data[1] = 0; /* reg 94, Y Gain (auto) */
- data[2] = 0; /* reg 95, UV Gain (1.75) */
- data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable
- * auto dark-gain */
- switch (gspca_dev->width) {
-/* case 1280: */
-/* data[4] = 154;
- * reg 97, %3 shadow point (unit: 256 pixel) */
-/* data[5] = 51;
- * reg 98, %1 highlight point
- * (uint: 256 pixel) */
-/* break; */
- default:
-/* case 640: */
- data[4] = 36; /* reg 97, %3 shadow point
- * (unit: 256 pixel) */
- data[5] = 12; /* reg 98, %1 highlight point
- * (uint: 256 pixel) */
- break;
- case 320:
- data[4] = 9; /* reg 97, %3 shadow point
- * (unit: 256 pixel) */
- data[5] = 3; /* reg 98, %1 highlight point
- * (uint: 256 pixel) */
- break;
- }
- }
/* auto dark-gain */
data[0] = 0x5e; /* address */
-
- err_code = reg_w(gspca_dev, data[0], 6);
+ data[1] = 0; /* reg 94, Y Gain (auto) */
+/*jfm: from win trace*/
+ /* reg 0x5f/0x60 (LE) = saturation */
+ /* h (60): xxxx x100
+ * l (5f): xxxx x000 */
+ data[2] = sd->colors << 3;
+ data[3] = ((sd->colors >> 2) & 0xf8) | 0x04;
+ data[4] = sd->brightness; /* reg 0x61 = brightness */
+ data[5] = 0x00;
+
+ err_code = reg_w(gspca_dev, 6);
if (err_code < 0)
return err_code;
data[0] = 0x67;
- data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */
- err_code = reg_w(gspca_dev, data[0], 2);
+/*jfm: from win trace*/
+ data[1] = sd->sharpness * 4 + 3;
+ data[2] = 0x14;
+ err_code = reg_w(gspca_dev, 3);
if (err_code < 0)
return err_code;
- /*
- * initialize the value of MI sensor...
- */
- MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL);
- MI_buf[REG_HW_MI_1] = 0x000a;
- MI_buf[REG_HW_MI_2] = 0x000c;
- MI_buf[REG_HW_MI_3] = 0x0405;
- MI_buf[REG_HW_MI_4] = 0x0507;
- /* mi_Attr_Reg_[REG_HW_MI_5] = 0x01ff;//13 */
- MI_buf[REG_HW_MI_5] = 0x0013; /* 13 */
- MI_buf[REG_HW_MI_6] = 0x001f; /* vertical blanking */
- /* mi_Attr_Reg_[REG_HW_MI_6] = 0x0400; // vertical blanking */
- MI_buf[REG_HW_MI_7] = 0x0002;
- /* mi_Attr_Reg_[REG_HW_MI_9] = 0x015f; */
- /* mi_Attr_Reg_[REG_HW_MI_9] = 0x030f; */
- MI_buf[REG_HW_MI_9] = 0x0374;
- MI_buf[REG_HW_MI_B] = 0x0000;
- MI_buf[REG_HW_MI_C] = 0x0000;
- MI_buf[REG_HW_MI_D] = 0x0000;
- MI_buf[REG_HW_MI_1E] = 0x8000;
-/* mi_Attr_Reg_[REG_HW_MI_20] = 0x1104; */
- MI_buf[REG_HW_MI_20] = 0x1104; /* 0x111c; */
- MI_buf[REG_HW_MI_2B] = 0x0008;
-/* mi_Attr_Reg_[REG_HW_MI_2C] = 0x000f; */
- MI_buf[REG_HW_MI_2C] = 0x001f; /* lita suggest */
- MI_buf[REG_HW_MI_2D] = 0x0008;
- MI_buf[REG_HW_MI_2E] = 0x0008;
- MI_buf[REG_HW_MI_35] = 0x0051;
- MI_buf[REG_HW_MI_5F] = 0x0904; /* fail to write */
- MI_buf[REG_HW_MI_60] = 0x0000;
- MI_buf[REG_HW_MI_61] = 0x0000;
- MI_buf[REG_HW_MI_62] = 0x0498;
- MI_buf[REG_HW_MI_63] = 0x0000;
- MI_buf[REG_HW_MI_64] = 0x0000;
- MI_buf[REG_HW_MI_F1] = 0x0001;
- /* changing while setting up the different value of dx/dy */
-
- if (gspca_dev->width != 1280) {
- MI_buf[0x01] = 0x010a;
- MI_buf[0x02] = 0x014c;
- MI_buf[0x03] = 0x01e5;
- MI_buf[0x04] = 0x0287;
- }
- MI_buf[0x20] = 0x1104;
-
- bulk_w(gspca_dev, MI_buf + 1, 1);
- bulk_w(gspca_dev, MI_buf + 2, 2);
- bulk_w(gspca_dev, MI_buf + 3, 3);
- bulk_w(gspca_dev, MI_buf + 4, 4);
- bulk_w(gspca_dev, MI_buf + 5, 5);
- bulk_w(gspca_dev, MI_buf + 6, 6);
- bulk_w(gspca_dev, MI_buf + 7, 7);
- bulk_w(gspca_dev, MI_buf + 9, 9);
- bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b);
- bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c);
- bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d);
- bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e);
- bulk_w(gspca_dev, MI_buf + 0x20, 0x20);
- bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b);
- bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c);
- bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d);
- bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e);
- bulk_w(gspca_dev, MI_buf + 0x35, 0x35);
- bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f);
- bulk_w(gspca_dev, MI_buf + 0x60, 0x60);
- bulk_w(gspca_dev, MI_buf + 0x61, 0x61);
- bulk_w(gspca_dev, MI_buf + 0x62, 0x62);
- bulk_w(gspca_dev, MI_buf + 0x63, 0x63);
- bulk_w(gspca_dev, MI_buf + 0x64, 0x64);
- bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1);
- kfree(MI_buf);
-
- intpipe = usb_sndintpipe(gspca_dev->dev, 0);
- err_code = usb_clear_halt(gspca_dev->dev, intpipe);
+ data[0] = 0x69;
+ data[1] = 0x2f;
+ data[2] = 0x28;
+ data[3] = 0x42;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x63;
+ data[1] = 0x07;
+ err_code = reg_w(gspca_dev, 2);
+/*jfm: win trace - many writes here to reg 0x64*/
+ if (err_code < 0)
+ return err_code;
+
+ /* initialize the MI sensor */
+ for (i = 0; i < sizeof mi_data; i++)
+ mi_w(gspca_dev, i + 1, mi_data[i]);
data[0] = 0x00;
data[1] = 0x4d; /* ISOC transfering enable... */
- reg_w(gspca_dev, data[0], 2);
- return err_code;
+ reg_w(gspca_dev, 2);
+ return 0;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -336,11 +310,18 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
gspca_dev->usb_buf[0] = 1;
gspca_dev->usb_buf[1] = 0;
- result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2);
+ result = reg_w(gspca_dev, 2);
if (result < 0)
PDEBUG(D_ERR, "Camera Stop failed");
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
@@ -363,16 +344,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|| data[5 + p] == 0x65
|| data[5 + p] == 0x66
|| data[5 + p] == 0x67) {
- PDEBUG(D_PACK, "sof offset: %d leng: %d",
+ PDEBUG(D_PACK, "sof offset: %d len: %d",
p, len);
frame = gspca_frame_add(gspca_dev, LAST_PACKET,
- frame, data, 0);
+ frame, data, p);
/* put the JPEG header */
- jpeg_put_header(gspca_dev, frame,
- sd->qindex, 0x21);
- data += 16;
- len -= 16;
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
+ data += p + 16;
+ len -= p + 16;
break;
}
}
@@ -380,6 +361,121 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming) {
+ gspca_dev->usb_buf[0] = 0x61;
+ gspca_dev->usb_buf[1] = val;
+ reg_w(gspca_dev, 2);
+ }
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming) {
+
+ /* see sd_start */
+ gspca_dev->usb_buf[0] = 0x5f;
+ gspca_dev->usb_buf[1] = sd->colors << 3;
+ gspca_dev->usb_buf[2] = ((sd->colors >> 2) & 0xf8) | 0x04;
+ reg_w(gspca_dev, 3);
+ }
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->colors;
+ return 0;
+}
+
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gamma = val;
+ if (gspca_dev->streaming) {
+ gspca_dev->usb_buf[0] = 0x06;
+ gspca_dev->usb_buf[1] = val * 0x40;
+ reg_w(gspca_dev, 2);
+ }
+ return 0;
+}
+
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gamma;
+ return 0;
+}
+
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->sharpness = val;
+ if (gspca_dev->streaming) {
+ gspca_dev->usb_buf[0] = 0x67;
+ gspca_dev->usb_buf[1] = val * 4 + 3;
+ reg_w(gspca_dev, 2);
+ }
+ return 0;
+}
+
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->sharpness;
+ return 0;
+}
+
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -389,7 +485,10 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -421,8 +520,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
new file mode 100644
index 000000000000..2a901a4a6f00
--- /dev/null
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -0,0 +1,362 @@
+/*
+ * Mars MR97310A library
+ *
+ * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "mr97310a"
+
+#include "gspca.h"
+
+MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>");
+MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+ u8 sof_read;
+};
+
+/* V4L2 controls supported by the driver */
+static struct ctrl sd_ctrls[] = {
+};
+
+static const struct v4l2_pix_format vga_mode[] = {
+ {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 4},
+ {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 3},
+ {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 2},
+ {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+
+/* the bytes to write are in gspca_dev->usb_buf */
+static int reg_w(struct gspca_dev *gspca_dev, int len)
+{
+ int rc;
+
+ rc = usb_bulk_msg(gspca_dev->dev,
+ usb_sndbulkpipe(gspca_dev->dev, 4),
+ gspca_dev->usb_buf, len, NULL, 500);
+ if (rc < 0)
+ PDEBUG(D_ERR, "reg write [%02x] error %d",
+ gspca_dev->usb_buf[0], rc);
+ return rc;
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct cam *cam;
+
+ cam = &gspca_dev->cam;
+ cam->cam_mode = vga_mode;
+ cam->nmodes = ARRAY_SIZE(vga_mode);
+ return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ return 0;
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 *data = gspca_dev->usb_buf;
+ int err_code;
+
+ sd->sof_read = 0;
+
+ /* Note: register descriptions guessed from MR97113A driver */
+
+ data[0] = 0x01;
+ data[1] = 0x01;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x00;
+ data[1] = 0x0d;
+ data[2] = 0x01;
+ data[5] = 0x2b;
+ data[7] = 0x00;
+ data[9] = 0x50; /* reg 8, no scale down */
+ data[10] = 0xc0;
+
+ switch (gspca_dev->width) {
+ case 160:
+ data[9] |= 0x0c; /* reg 8, 4:1 scale down */
+ /* fall thru */
+ case 320:
+ data[9] |= 0x04; /* reg 8, 2:1 scale down */
+ /* fall thru */
+ case 640:
+ default:
+ data[3] = 0x50; /* reg 2, H size */
+ data[4] = 0x78; /* reg 3, V size */
+ data[6] = 0x04; /* reg 5, H start */
+ data[8] = 0x03; /* reg 7, V start */
+ break;
+
+ case 176:
+ data[9] |= 0x04; /* reg 8, 2:1 scale down */
+ /* fall thru */
+ case 352:
+ data[3] = 0x2c; /* reg 2, H size */
+ data[4] = 0x48; /* reg 3, V size */
+ data[6] = 0x94; /* reg 5, H start */
+ data[8] = 0x63; /* reg 7, V start */
+ break;
+ }
+
+ err_code = reg_w(gspca_dev, 11);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x0a;
+ data[1] = 0x80;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x14;
+ data[1] = 0x0a;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1b;
+ data[1] = 0x00;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x15;
+ data[1] = 0x16;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x16;
+ data[1] = 0x10;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x17;
+ data[1] = 0x3a;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x18;
+ data[1] = 0x68;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x00;
+ data[2] = 0x02;
+ data[3] = 0x06;
+ data[4] = 0x59;
+ data[5] = 0x0c;
+ data[6] = 0x16;
+ data[7] = 0x00;
+ data[8] = 0x07;
+ data[9] = 0x00;
+ data[10] = 0x01;
+ err_code = reg_w(gspca_dev, 11);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x04;
+ data[2] = 0x11;
+ data[3] = 0x01;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x00;
+ data[2] = 0x0a;
+ data[3] = 0x00;
+ data[4] = 0x01;
+ data[5] = 0x00;
+ data[6] = 0x00;
+ data[7] = 0x01;
+ data[8] = 0x00;
+ data[9] = 0x0a;
+ err_code = reg_w(gspca_dev, 10);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x04;
+ data[2] = 0x11;
+ data[3] = 0x01;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x00;
+ data[2] = 0x12;
+ data[3] = 0x00;
+ data[4] = 0x63;
+ data[5] = 0x00;
+ data[6] = 0x70;
+ data[7] = 0x00;
+ data[8] = 0x00;
+ err_code = reg_w(gspca_dev, 9);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x04;
+ data[2] = 0x11;
+ data[3] = 0x01;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x00;
+ data[1] = 0x4d; /* ISOC transfering enable... */
+ err_code = reg_w(gspca_dev, 2);
+ return err_code;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ int result;
+
+ gspca_dev->usb_buf[0] = 1;
+ gspca_dev->usb_buf[1] = 0;
+ result = reg_w(gspca_dev, 2);
+ if (result < 0)
+ PDEBUG(D_ERR, "Camera Stop failed");
+}
+
+/* Include pac common sof detection functions */
+#include "pac_common.h"
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ unsigned char *sof;
+
+ sof = pac_find_sof(gspca_dev, data, len);
+ if (sof) {
+ int n;
+
+ /* finish decoding current frame */
+ n = sof - data;
+ if (n > sizeof pac_sof_marker)
+ n -= sizeof pac_sof_marker;
+ else
+ n = 0;
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, n);
+ /* Start next frame. */
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ pac_sof_marker, sizeof pac_sof_marker);
+ len -= sof - data;
+ data = sof;
+ }
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .init = sd_init,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x08ca, 0x0111)},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "registered");
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index ee232956c812..1fff37b79891 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -1360,7 +1360,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
cam = &gspca_dev->cam;
- cam->epaddr = OV511_ENDPOINT_ADDRESS;
if (!sd->sif) {
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -2177,8 +2176,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 3bf15e401693..19e0bc60de14 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1,7 +1,8 @@
/*
- * ov534/ov772x gspca driver
+ * ov534 gspca driver
* Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
* Copyright (C) 2008 Jim Paris <jim@jtan.com>
+ * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
*
* Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
* USB protocol reverse engineered by Jim Paris <jim@jtan.com>
@@ -26,7 +27,7 @@
#include "gspca.h"
-#define OV534_REG_ADDRESS 0xf1 /* ? */
+#define OV534_REG_ADDRESS 0xf1 /* sensor address */
#define OV534_REG_SUBADDR 0xf2
#define OV534_REG_WRITE 0xf3
#define OV534_REG_READ 0xf4
@@ -46,9 +47,13 @@ MODULE_LICENSE("GPL");
/* specific webcam descriptor */
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- __u32 last_fid;
__u32 last_pts;
- int frame_rate;
+ u16 last_fid;
+ u8 frame_rate;
+
+ u8 sensor;
+#define SENSOR_OV772X 0
+#define SENSOR_OV965X 1
};
/* V4L2 controls supported by the driver */
@@ -63,114 +68,7 @@ static const struct v4l2_pix_format vga_mode[] = {
.priv = 0},
};
-static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
-{
- struct usb_device *udev = gspca_dev->dev;
- int ret;
-
- PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
- gspca_dev->usb_buf[0] = val;
- ret = usb_control_msg(udev,
- usb_sndctrlpipe(udev, 0),
- 0x1,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
- if (ret < 0)
- PDEBUG(D_ERR, "write failed");
-}
-
-static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
-{
- struct usb_device *udev = gspca_dev->dev;
- int ret;
-
- ret = usb_control_msg(udev,
- usb_rcvctrlpipe(udev, 0),
- 0x1,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
- PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
- if (ret < 0)
- PDEBUG(D_ERR, "read failed");
- return gspca_dev->usb_buf[0];
-}
-
-/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
- * (direction and output)? */
-static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
-{
- u8 data;
-
- PDEBUG(D_CONF, "led status: %d", status);
-
- data = ov534_reg_read(gspca_dev, 0x21);
- data |= 0x80;
- ov534_reg_write(gspca_dev, 0x21, data);
-
- data = ov534_reg_read(gspca_dev, 0x23);
- if (status)
- data |= 0x80;
- else
- data &= ~(0x80);
-
- ov534_reg_write(gspca_dev, 0x23, data);
-}
-
-static int sccb_check_status(struct gspca_dev *gspca_dev)
-{
- u8 data;
- int i;
-
- for (i = 0; i < 5; i++) {
- data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
-
- switch (data) {
- case 0x00:
- return 1;
- case 0x04:
- return 0;
- case 0x03:
- break;
- default:
- PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
- data, i + 1);
- }
- }
- return 0;
-}
-
-static void sccb_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
-{
- PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%02x", reg, val);
- ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
- ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
- ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
-
- if (!sccb_check_status(gspca_dev))
- PDEBUG(D_ERR, "sccb_reg_write failed");
-}
-
-#ifdef GSPCA_DEBUG
-static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
-{
- ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
- ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
- if (!sccb_check_status(gspca_dev))
- PDEBUG(D_ERR, "sccb_reg_read failed 1");
-
- ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
- if (!sccb_check_status(gspca_dev))
- PDEBUG(D_ERR, "sccb_reg_read failed 2");
-
- return ov534_reg_read(gspca_dev, OV534_REG_READ);
-}
-#endif
-
-static const __u8 ov534_reg_initdata[][2] = {
- { 0xe7, 0x3a },
-
- { OV534_REG_ADDRESS, 0x42 }, /* select OV772x sensor */
-
+static const u8 bridge_init_ov722x[][2] = {
{ 0xc2, 0x0c },
{ 0x88, 0xf8 },
{ 0xc3, 0x69 },
@@ -228,7 +126,7 @@ static const __u8 ov534_reg_initdata[][2] = {
{ 0xc2, 0x0c },
};
-static const __u8 ov772x_reg_initdata[][2] = {
+static const u8 sensor_init_ov722x[][2] = {
{ 0x12, 0x80 },
{ 0x11, 0x01 },
@@ -311,6 +209,456 @@ static const __u8 ov772x_reg_initdata[][2] = {
{ 0x0c, 0xd0 }
};
+static const u8 bridge_init_ov965x[][2] = {
+ {0x88, 0xf8},
+ {0x89, 0xff},
+ {0x76, 0x03},
+ {0x92, 0x03},
+ {0x95, 0x10},
+ {0xe2, 0x00},
+ {0xe7, 0x3e},
+ {0x8d, 0x1c},
+ {0x8e, 0x00},
+ {0x8f, 0x00},
+ {0x1f, 0x00},
+ {0xc3, 0xf9},
+ {0x89, 0xff},
+ {0x88, 0xf8},
+ {0x76, 0x03},
+ {0x92, 0x01},
+ {0x93, 0x18},
+ {0x1c, 0x0a},
+ {0x1d, 0x48},
+ {0xc0, 0x50},
+ {0xc1, 0x3c},
+ {0x34, 0x05},
+ {0xc2, 0x0c},
+ {0xc3, 0xf9},
+ {0x34, 0x05},
+ {0xe7, 0x2e},
+ {0x31, 0xf9},
+ {0x35, 0x02},
+ {0xd9, 0x10},
+ {0x25, 0x42},
+ {0x94, 0x11},
+};
+
+static const u8 sensor_init_ov965x[][2] = {
+ {0x12, 0x80}, /* com7 - reset */
+ {0x00, 0x00}, /* gain */
+ {0x01, 0x80}, /* blue */
+ {0x02, 0x80}, /* red */
+ {0x03, 0x1b}, /* vref */
+ {0x04, 0x03}, /* com1 - exposure low bits */
+ {0x0b, 0x57}, /* ver */
+ {0x0e, 0x61}, /* com5 */
+ {0x0f, 0x42}, /* com6 */
+ {0x11, 0x00}, /* clkrc */
+ {0x12, 0x02}, /* com7 */
+ {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
+ {0x14, 0x28}, /* com9 */
+ {0x16, 0x24}, /* rsvd16 */
+ {0x17, 0x1d}, /* hstart*/
+ {0x18, 0xbd}, /* hstop */
+ {0x19, 0x01}, /* vstrt */
+ {0x1a, 0x81}, /* vstop*/
+ {0x1e, 0x04}, /* mvfp */
+ {0x24, 0x3c}, /* aew */
+ {0x25, 0x36}, /* aeb */
+ {0x26, 0x71}, /* vpt */
+ {0x27, 0x08}, /* bbias */
+ {0x28, 0x08}, /* gbbias */
+ {0x29, 0x15}, /* gr com */
+ {0x2a, 0x00},
+ {0x2b, 0x00},
+ {0x2c, 0x08}, /* rbias */
+ {0x32, 0xff}, /* href */
+ {0x33, 0x00}, /* chlf */
+ {0x34, 0x3f}, /* arblm */
+ {0x35, 0x00}, /* rsvd35 */
+ {0x36, 0xf8}, /* rsvd36 */
+ {0x38, 0x72}, /* acom38 */
+ {0x39, 0x57}, /* ofon */
+ {0x3a, 0x80}, /* tslb */
+ {0x3b, 0xc4},
+ {0x3d, 0x99}, /* com13 */
+ {0x3f, 0xc1},
+ {0x40, 0xc0}, /* com15 */
+ {0x41, 0x40}, /* com16 */
+ {0x42, 0xc0},
+ {0x43, 0x0a},
+ {0x44, 0xf0},
+ {0x45, 0x46},
+ {0x46, 0x62},
+ {0x47, 0x2a},
+ {0x48, 0x3c},
+ {0x4a, 0xfc},
+ {0x4b, 0xfc},
+ {0x4c, 0x7f},
+ {0x4d, 0x7f},
+ {0x4e, 0x7f},
+ {0x4f, 0x98},
+ {0x50, 0x98},
+ {0x51, 0x00},
+ {0x52, 0x28},
+ {0x53, 0x70},
+ {0x54, 0x98},
+ {0x58, 0x1a},
+ {0x59, 0x85},
+ {0x5a, 0xa9},
+ {0x5b, 0x64},
+ {0x5c, 0x84},
+ {0x5d, 0x53},
+ {0x5e, 0x0e},
+ {0x5f, 0xf0},
+ {0x60, 0xf0},
+ {0x61, 0xf0},
+ {0x62, 0x00}, /* lcc1 */
+ {0x63, 0x00}, /* lcc2 */
+ {0x64, 0x02}, /* lcc3 */
+ {0x65, 0x16}, /* lcc4 */
+ {0x66, 0x01}, /* lcc5 */
+ {0x69, 0x02}, /* hv */
+ {0x6b, 0x5a}, /* dbvl */
+ {0x6c, 0x04},
+ {0x6d, 0x55},
+ {0x6e, 0x00},
+ {0x6f, 0x9d},
+ {0x70, 0x21},
+ {0x71, 0x78},
+ {0x72, 0x00},
+ {0x73, 0x01},
+ {0x74, 0x3a},
+ {0x75, 0x35},
+ {0x76, 0x01},
+ {0x77, 0x02},
+ {0x7a, 0x12},
+ {0x7b, 0x08},
+ {0x7c, 0x16},
+ {0x7d, 0x30},
+ {0x7e, 0x5e},
+ {0x7f, 0x72},
+ {0x80, 0x82},
+ {0x81, 0x8e},
+ {0x82, 0x9a},
+ {0x83, 0xa4},
+ {0x84, 0xac},
+ {0x85, 0xb8},
+ {0x86, 0xc3},
+ {0x87, 0xd6},
+ {0x88, 0xe6},
+ {0x89, 0xf2},
+ {0x8a, 0x03},
+ {0x8c, 0x89},
+ {0x14, 0x28}, /* com9 */
+ {0x90, 0x7d},
+ {0x91, 0x7b},
+ {0x9d, 0x03},
+ {0x9e, 0x04},
+ {0x9f, 0x7a},
+ {0xa0, 0x79},
+ {0xa1, 0x40}, /* aechm */
+ {0xa4, 0x50},
+ {0xa5, 0x68}, /* com26 */
+ {0xa6, 0x4a},
+ {0xa8, 0xc1}, /* acoma8 */
+ {0xa9, 0xef}, /* acoma9 */
+ {0xaa, 0x92},
+ {0xab, 0x04},
+ {0xac, 0x80},
+ {0xad, 0x80},
+ {0xae, 0x80},
+ {0xaf, 0x80},
+ {0xb2, 0xf2},
+ {0xb3, 0x20},
+ {0xb4, 0x20},
+ {0xb5, 0x00},
+ {0xb6, 0xaf},
+ {0xbb, 0xae},
+ {0xbc, 0x7f},
+ {0xdb, 0x7f},
+ {0xbe, 0x7f},
+ {0xbf, 0x7f},
+ {0xc0, 0xe2},
+ {0xc1, 0xc0},
+ {0xc2, 0x01},
+ {0xc3, 0x4e},
+ {0xc6, 0x85},
+ {0xc7, 0x80},
+ {0xc9, 0xe0},
+ {0xca, 0xe8},
+ {0xcb, 0xf0},
+ {0xcc, 0xd8},
+ {0xcd, 0xf1},
+ {0x4f, 0x98},
+ {0x50, 0x98},
+ {0x51, 0x00},
+ {0x52, 0x28},
+ {0x53, 0x70},
+ {0x54, 0x98},
+ {0x58, 0x1a},
+ {0xff, 0x41}, /* read 41, write ff 00 */
+ {0x41, 0x40}, /* com16 */
+ {0xc5, 0x03},
+ {0x6a, 0x02},
+
+ {0x12, 0x62}, /* com7 - VGA + CIF */
+ {0x36, 0xfa}, /* rsvd36 */
+ {0x69, 0x0a}, /* hv */
+ {0x8c, 0x89}, /* com22 */
+ {0x14, 0x28}, /* com9 */
+ {0x3e, 0x0c},
+ {0x41, 0x40}, /* com16 */
+ {0x72, 0x00},
+ {0x73, 0x00},
+ {0x74, 0x3a},
+ {0x75, 0x35},
+ {0x76, 0x01},
+ {0xc7, 0x80},
+ {0x03, 0x12}, /* vref */
+ {0x17, 0x16}, /* hstart */
+ {0x18, 0x02}, /* hstop */
+ {0x19, 0x01}, /* vstrt */
+ {0x1a, 0x3d}, /* vstop */
+ {0x32, 0xff}, /* href */
+ {0xc0, 0xaa},
+};
+
+static const u8 bridge_init_ov965x_2[][2] = {
+ {0x94, 0xaa},
+ {0xf1, 0x60},
+ {0xe5, 0x04},
+ {0xc0, 0x50},
+ {0xc1, 0x3c},
+ {0x8c, 0x00},
+ {0x8d, 0x1c},
+ {0x34, 0x05},
+
+ {0xc2, 0x0c},
+ {0xc3, 0xf9},
+ {0xda, 0x01},
+ {0x50, 0x00},
+ {0x51, 0xa0},
+ {0x52, 0x3c},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x00},
+ {0x57, 0x00},
+ {0x5c, 0x00},
+ {0x5a, 0xa0},
+ {0x5b, 0x78},
+ {0x35, 0x02},
+ {0xd9, 0x10},
+ {0x94, 0x11},
+};
+
+static const u8 sensor_init_ov965x_2[][2] = {
+ {0x3b, 0xc4},
+ {0x1e, 0x04}, /* mvfp */
+ {0x13, 0xe0}, /* com8 */
+ {0x00, 0x00}, /* gain */
+ {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
+ {0x11, 0x03}, /* clkrc */
+ {0x6b, 0x5a}, /* dblv */
+ {0x6a, 0x05},
+ {0xc5, 0x07},
+ {0xa2, 0x4b},
+ {0xa3, 0x3e},
+ {0x2d, 0x00},
+ {0xff, 0x42}, /* read 42, write ff 00 */
+ {0x42, 0xc0},
+ {0x2d, 0x00},
+ {0xff, 0x42}, /* read 42, write ff 00 */
+ {0x42, 0xc1},
+ {0x3f, 0x01},
+ {0xff, 0x42}, /* read 42, write ff 00 */
+ {0x42, 0xc1},
+ {0x4f, 0x98},
+ {0x50, 0x98},
+ {0x51, 0x00},
+ {0x52, 0x28},
+ {0x53, 0x70},
+ {0x54, 0x98},
+ {0x58, 0x1a},
+ {0xff, 0x41}, /* read 41, write ff 00 */
+ {0x41, 0x40}, /* com16 */
+ {0x56, 0x40},
+ {0x55, 0x8f},
+ {0x10, 0x25}, /* aech - exposure high bits */
+ {0xff, 0x13}, /* read 13, write ff 00 */
+ {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
+};
+
+static const u8 bridge_start_ov965x[][2] = {
+ {0xc2, 0x4c},
+ {0xc3, 0xf9},
+ {0x50, 0x00},
+ {0x51, 0xa0},
+ {0x52, 0x78},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x00},
+ {0x57, 0x00},
+ {0x5c, 0x00},
+ {0x5a, 0x28},
+ {0x5b, 0x1e},
+ {0x35, 0x00},
+ {0xd9, 0x21},
+ {0x94, 0x11},
+};
+
+static const u8 sensor_start_ov965x[][2] = {
+ {0x3b, 0xe4},
+ {0x1e, 0x04}, /* mvfp */
+ {0x13, 0xe0}, /* com8 */
+ {0x00, 0x00},
+ {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
+ {0x11, 0x01}, /* clkrc */
+ {0x6b, 0x5a}, /* dblv */
+ {0x6a, 0x02},
+ {0xc5, 0x03},
+ {0xa2, 0x96},
+ {0xa3, 0x7d},
+ {0xff, 0x13}, /* read 13, write ff 00 */
+ {0x13, 0xe7},
+ {0x3a, 0x80},
+ {0xff, 0x42}, /* read 42, write ff 00 */
+ {0x42, 0xc1},
+};
+
+
+static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
+{
+ struct usb_device *udev = gspca_dev->dev;
+ int ret;
+
+ PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
+ gspca_dev->usb_buf[0] = val;
+ ret = usb_control_msg(udev,
+ usb_sndctrlpipe(udev, 0),
+ 0x01,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
+ if (ret < 0)
+ PDEBUG(D_ERR, "write failed");
+}
+
+static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
+{
+ struct usb_device *udev = gspca_dev->dev;
+ int ret;
+
+ ret = usb_control_msg(udev,
+ usb_rcvctrlpipe(udev, 0),
+ 0x01,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
+ PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
+ if (ret < 0)
+ PDEBUG(D_ERR, "read failed");
+ return gspca_dev->usb_buf[0];
+}
+
+/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
+ * (direction and output)? */
+static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
+{
+ u8 data;
+
+ PDEBUG(D_CONF, "led status: %d", status);
+
+ data = ov534_reg_read(gspca_dev, 0x21);
+ data |= 0x80;
+ ov534_reg_write(gspca_dev, 0x21, data);
+
+ data = ov534_reg_read(gspca_dev, 0x23);
+ if (status)
+ data |= 0x80;
+ else
+ data &= ~0x80;
+
+ ov534_reg_write(gspca_dev, 0x23, data);
+
+ if (!status) {
+ data = ov534_reg_read(gspca_dev, 0x21);
+ data &= ~0x80;
+ ov534_reg_write(gspca_dev, 0x21, data);
+ }
+}
+
+static int sccb_check_status(struct gspca_dev *gspca_dev)
+{
+ u8 data;
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
+
+ switch (data) {
+ case 0x00:
+ return 1;
+ case 0x04:
+ return 0;
+ case 0x03:
+ break;
+ default:
+ PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
+ data, i + 1);
+ }
+ }
+ return 0;
+}
+
+static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
+{
+ PDEBUG(D_USBO, "reg: 0x%02x, val: 0x%02x", reg, val);
+ ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
+ ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
+ ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
+
+ if (!sccb_check_status(gspca_dev))
+ PDEBUG(D_ERR, "sccb_reg_write failed");
+}
+
+static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
+{
+ ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
+ ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
+ if (!sccb_check_status(gspca_dev))
+ PDEBUG(D_ERR, "sccb_reg_read failed 1");
+
+ ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
+ if (!sccb_check_status(gspca_dev))
+ PDEBUG(D_ERR, "sccb_reg_read failed 2");
+
+ return ov534_reg_read(gspca_dev, OV534_REG_READ);
+}
+
+/* output a bridge sequence (reg - val) */
+static void reg_w_array(struct gspca_dev *gspca_dev,
+ const u8 (*data)[2], int len)
+{
+ while (--len >= 0) {
+ ov534_reg_write(gspca_dev, (*data)[0], (*data)[1]);
+ data++;
+ }
+}
+
+/* output a sensor sequence (reg - val) */
+static void sccb_w_array(struct gspca_dev *gspca_dev,
+ const u8 (*data)[2], int len)
+{
+ while (--len >= 0) {
+ if ((*data)[0] != 0xff) {
+ sccb_reg_write(gspca_dev, (*data)[0], (*data)[1]);
+ } else {
+ sccb_reg_read(gspca_dev, (*data)[1]);
+ sccb_reg_write(gspca_dev, 0xff, 0x00);
+ }
+ data++;
+ }
+}
+
/* set framerate */
static void ov534_set_frame_rate(struct gspca_dev *gspca_dev)
{
@@ -346,40 +694,17 @@ static void ov534_set_frame_rate(struct gspca_dev *gspca_dev)
PDEBUG(D_PROBE, "frame_rate: %d", fr);
}
-/* setup method */
-static void ov534_setup(struct gspca_dev *gspca_dev)
-{
- int i;
-
- /* Initialize bridge chip */
- for (i = 0; i < ARRAY_SIZE(ov534_reg_initdata); i++)
- ov534_reg_write(gspca_dev, ov534_reg_initdata[i][0],
- ov534_reg_initdata[i][1]);
-
- PDEBUG(D_PROBE, "sensor is ov%02x%02x",
- sccb_reg_read(gspca_dev, 0x0a),
- sccb_reg_read(gspca_dev, 0x0b));
-
- ov534_set_led(gspca_dev, 1);
-
- /* Initialize sensor */
- for (i = 0; i < ARRAY_SIZE(ov772x_reg_initdata); i++)
- sccb_reg_write(gspca_dev, ov772x_reg_initdata[i][0],
- ov772x_reg_initdata[i][1]);
-
- ov534_reg_write(gspca_dev, 0xe0, 0x09);
- ov534_set_led(gspca_dev, 0);
-}
-
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
+ struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
+ sd->sensor = id->driver_info;
+
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -392,26 +717,102 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
- ov534_setup(gspca_dev);
- ov534_set_frame_rate(gspca_dev);
+ struct sd *sd = (struct sd *) gspca_dev;
+ u16 sensor_id;
+ static const u8 sensor_addr[2] = {
+ 0x42, /* 0 SENSOR_OV772X */
+ 0x60, /* 1 SENSOR_OV965X */
+ };
+
+ /* reset bridge */
+ ov534_reg_write(gspca_dev, 0xe7, 0x3a);
+ ov534_reg_write(gspca_dev, 0xe0, 0x08);
+ msleep(100);
+
+ /* initialize the sensor address */
+ ov534_reg_write(gspca_dev, OV534_REG_ADDRESS,
+ sensor_addr[sd->sensor]);
+
+ /* reset sensor */
+ sccb_reg_write(gspca_dev, 0x12, 0x80);
+ msleep(10);
+
+ /* probe the sensor */
+ sccb_reg_read(gspca_dev, 0x0a);
+ sensor_id = sccb_reg_read(gspca_dev, 0x0a) << 8;
+ sccb_reg_read(gspca_dev, 0x0b);
+ sensor_id |= sccb_reg_read(gspca_dev, 0x0b);
+ PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
+
+ /* initialize */
+ switch (sd->sensor) {
+ case SENSOR_OV772X:
+ reg_w_array(gspca_dev, bridge_init_ov722x,
+ ARRAY_SIZE(bridge_init_ov722x));
+ ov534_set_led(gspca_dev, 1);
+ sccb_w_array(gspca_dev, sensor_init_ov722x,
+ ARRAY_SIZE(sensor_init_ov722x));
+ ov534_reg_write(gspca_dev, 0xe0, 0x09);
+ ov534_set_led(gspca_dev, 0);
+ ov534_set_frame_rate(gspca_dev);
+ break;
+ default:
+/* case SENSOR_OV965X: */
+ reg_w_array(gspca_dev, bridge_init_ov965x,
+ ARRAY_SIZE(bridge_init_ov965x));
+ sccb_w_array(gspca_dev, sensor_init_ov965x,
+ ARRAY_SIZE(sensor_init_ov965x));
+ reg_w_array(gspca_dev, bridge_init_ov965x_2,
+ ARRAY_SIZE(bridge_init_ov965x_2));
+ sccb_w_array(gspca_dev, sensor_init_ov965x_2,
+ ARRAY_SIZE(sensor_init_ov965x_2));
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ ov534_reg_write(gspca_dev, 0xe0, 0x01);
+ ov534_set_led(gspca_dev, 0);
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ }
return 0;
}
static int sd_start(struct gspca_dev *gspca_dev)
{
- /* start streaming data */
- ov534_set_led(gspca_dev, 1);
- ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ struct sd *sd = (struct sd *) gspca_dev;
+ switch (sd->sensor) {
+ case SENSOR_OV772X:
+ ov534_set_led(gspca_dev, 1);
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ break;
+ default:
+/* case SENSOR_OV965X: */
+ reg_w_array(gspca_dev, bridge_start_ov965x,
+ ARRAY_SIZE(bridge_start_ov965x));
+ sccb_w_array(gspca_dev, sensor_start_ov965x,
+ ARRAY_SIZE(sensor_start_ov965x));
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ ov534_set_led(gspca_dev, 1);
+/*fixme: other sensor start omitted*/
+ }
return 0;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
{
- /* stop streaming data */
- ov534_reg_write(gspca_dev, 0xe0, 0x09);
- ov534_set_led(gspca_dev, 0);
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->sensor) {
+ case SENSOR_OV772X:
+ ov534_reg_write(gspca_dev, 0xe0, 0x09);
+ ov534_set_led(gspca_dev, 0);
+ break;
+ default:
+/* case SENSOR_OV965X: */
+ ov534_reg_write(gspca_dev, 0xe0, 0x01);
+ ov534_set_led(gspca_dev, 0);
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ break;
+ }
}
/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
@@ -429,75 +830,75 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
{
struct sd *sd = (struct sd *) gspca_dev;
__u32 this_pts;
- int this_fid;
+ u16 this_fid;
int remaining_len = len;
- __u8 *next_data = data;
-scan_next:
- if (remaining_len <= 0)
- return;
-
- data = next_data;
- len = min(remaining_len, 2048);
- remaining_len -= len;
- next_data += len;
-
- /* Payloads are prefixed with a UVC-style header. We
- consider a frame to start when the FID toggles, or the PTS
- changes. A frame ends when EOF is set, and we've received
- the correct number of bytes. */
-
- /* Verify UVC header. Header length is always 12 */
- if (data[0] != 12 || len < 12) {
- PDEBUG(D_PACK, "bad header");
- goto discard;
- }
-
- /* Check errors */
- if (data[1] & UVC_STREAM_ERR) {
- PDEBUG(D_PACK, "payload error");
- goto discard;
- }
+ do {
+ len = min(remaining_len, 2040); /*fixme: was 2048*/
- /* Extract PTS and FID */
- if (!(data[1] & UVC_STREAM_PTS)) {
- PDEBUG(D_PACK, "PTS not present");
- goto discard;
- }
- this_pts = (data[5] << 24) | (data[4] << 16) | (data[3] << 8) | data[2];
- this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
-
- /* If PTS or FID has changed, start a new frame. */
- if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
- gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
- sd->last_pts = this_pts;
- sd->last_fid = this_fid;
- }
+ /* Payloads are prefixed with a UVC-style header. We
+ consider a frame to start when the FID toggles, or the PTS
+ changes. A frame ends when EOF is set, and we've received
+ the correct number of bytes. */
- /* Add the data from this payload */
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- data + 12, len - 12);
+ /* Verify UVC header. Header length is always 12 */
+ if (data[0] != 12 || len < 12) {
+ PDEBUG(D_PACK, "bad header");
+ goto discard;
+ }
- /* If this packet is marked as EOF, end the frame */
- if (data[1] & UVC_STREAM_EOF) {
- sd->last_pts = 0;
+ /* Check errors */
+ if (data[1] & UVC_STREAM_ERR) {
+ PDEBUG(D_PACK, "payload error");
+ goto discard;
+ }
- if ((frame->data_end - frame->data) !=
- (gspca_dev->width * gspca_dev->height * 2)) {
- PDEBUG(D_PACK, "short frame");
+ /* Extract PTS and FID */
+ if (!(data[1] & UVC_STREAM_PTS)) {
+ PDEBUG(D_PACK, "PTS not present");
goto discard;
}
+ this_pts = (data[5] << 24) | (data[4] << 16)
+ | (data[3] << 8) | data[2];
+ this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
+
+ /* If PTS or FID has changed, start a new frame. */
+ if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ NULL, 0);
+ sd->last_pts = this_pts;
+ sd->last_fid = this_fid;
+ }
- gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0);
- }
+ /* Add the data from this payload */
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ data + 12, len - 12);
- /* Done this payload */
- goto scan_next;
+ /* If this packet is marked as EOF, end the frame */
+ if (data[1] & UVC_STREAM_EOF) {
+ sd->last_pts = 0;
+
+ if (frame->data_end - frame->data !=
+ gspca_dev->width * gspca_dev->height * 2) {
+ PDEBUG(D_PACK, "short frame");
+ goto discard;
+ }
+
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ NULL, 0);
+ }
+
+ /* Done this payload */
+ goto scan_next;
discard:
- /* Discard data until a new frame starts. */
- gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
- goto scan_next;
+ /* Discard data until a new frame starts. */
+ gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
+
+scan_next:
+ remaining_len -= len;
+ data += len;
+ } while (remaining_len > 0);
}
/* get stream parameters (framerate) */
@@ -556,9 +957,8 @@ static const struct sd_desc sd_desc = {
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x06f8, 0x3002)}, /* Hercules Blog Webcam */
- {USB_DEVICE(0x06f8, 0x3003)}, /* Hercules Dualpix HD Weblog */
- {USB_DEVICE(0x1415, 0x2000)}, /* Sony HD Eye for PS3 (SLEH 00201) */
+ {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X},
+ {USB_DEVICE(0x1415, 0x2000), .driver_info = SENSOR_OV772X},
{}
};
@@ -585,8 +985,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index c90ac852bac0..95a97ab684cd 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -256,7 +256,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
cam = &gspca_dev->cam;
- cam->epaddr = 0x05;
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
@@ -536,6 +535,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x093a, 0x2470)},
{USB_DEVICE(0x093a, 0x2471)},
{USB_DEVICE(0x093a, 0x2472)},
+ {USB_DEVICE(0x093a, 0x2474)},
{USB_DEVICE(0x093a, 0x2476)},
{USB_DEVICE(0x145f, 0x013a)},
{USB_DEVICE(0x2001, 0xf115)},
@@ -565,8 +565,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index a9c95cba710e..e1e3a3a50484 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -498,7 +498,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x05;
sd->sensor = id->driver_info;
if (sd->sensor == SENSOR_PAC7302) {
@@ -1097,8 +1096,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index b3e4e0677b68..153d0a91d4b5 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -870,7 +870,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
if (!(sensor_data[sd->sensor].flags & F_SIF)) {
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -1272,8 +1271,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 3373b8d9d2a8..c72e19d3ac37 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -35,36 +35,47 @@ struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
atomic_t avg_lum;
- unsigned int exposure;
-
- __u16 brightness;
- __u8 contrast;
- __u8 colors;
- __u8 autogain;
- __u8 blue;
- __u8 red;
- __u8 vflip; /* ov7630 only */
- __u8 infrared; /* mi0360 only */
-
- __s8 ag_cnt;
+ u32 exposure;
+
+ u16 brightness;
+ u8 contrast;
+ u8 colors;
+ u8 autogain;
+ u8 blue;
+ u8 red;
+ u8 gamma;
+ u8 vflip; /* ov7630/ov7648 only */
+ u8 infrared; /* mt9v111 only */
+ u8 quality; /* image quality */
+#define QUALITY_MIN 60
+#define QUALITY_MAX 95
+#define QUALITY_DEF 80
+ u8 jpegqual; /* webcam quality */
+
+ u8 reg18;
+
+ s8 ag_cnt;
#define AG_CNT_START 13
- __u8 qindex;
- __u8 bridge;
+ u8 bridge;
#define BRIDGE_SN9C102P 0
#define BRIDGE_SN9C105 1
#define BRIDGE_SN9C110 2
#define BRIDGE_SN9C120 3
#define BRIDGE_SN9C325 4
- __u8 sensor; /* Type of image sensor chip */
+ u8 sensor; /* Type of image sensor chip */
#define SENSOR_HV7131R 0
#define SENSOR_MI0360 1
#define SENSOR_MO4000 2
-#define SENSOR_OM6802 3
-#define SENSOR_OV7630 4
-#define SENSOR_OV7648 5
-#define SENSOR_OV7660 6
- __u8 i2c_base;
+#define SENSOR_MT9V111 3
+#define SENSOR_OM6802 4
+#define SENSOR_OV7630 5
+#define SENSOR_OV7648 6
+#define SENSOR_OV7660 7
+#define SENSOR_SP80708 8
+ u8 i2c_base;
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -78,6 +89,8 @@ static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -158,6 +171,20 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setred_balance,
.get = sd_getred_balance,
},
+ {
+ {
+ .id = V4L2_CID_GAMMA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gamma",
+ .minimum = 0,
+ .maximum = 40,
+ .step = 1,
+#define GAMMA_DEF 20
+ .default_value = GAMMA_DEF,
+ },
+ .set = sd_setgamma,
+ .get = sd_getgamma,
+ },
#define AUTOGAIN_IDX 5
{
{
@@ -173,7 +200,7 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setautogain,
.get = sd_getautogain,
},
-/* ov7630 only */
+/* ov7630/ov7648 only */
#define VFLIP_IDX 6
{
{
@@ -183,13 +210,13 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
-#define VFLIP_DEF 1
+#define VFLIP_DEF 0 /* vflip def = 1 for ov7630 */
.default_value = VFLIP_DEF,
},
.set = sd_setvflip,
.get = sd_getvflip,
},
-/* mi0360 only */
+/* mt9v111 only */
#define INFRARED_IDX 7
{
{
@@ -211,18 +238,22 @@ static struct ctrl sd_ctrls[] = {
static __u32 ctrl_dis[] = {
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
/* SENSOR_HV7131R 0 */
- (1 << VFLIP_IDX),
+ (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
/* SENSOR_MI0360 1 */
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
/* SENSOR_MO4000 2 */
+ (1 << VFLIP_IDX),
+ /* SENSOR_MT9V111 3 */
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
- /* SENSOR_OM6802 3 */
+ /* SENSOR_OM6802 4 */
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
- /* SENSOR_OV7630 4 */
+ /* SENSOR_OV7630 5 */
+ (1 << INFRARED_IDX),
+ /* SENSOR_OV7648 6 */
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
- /* SENSOR_OV7648 5 */
+ /* SENSOR_OV7660 7 */
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
- /* SENSOR_OV7660 6 */
+ /* SENSOR_SP80708 8 */
};
static const struct v4l2_pix_format vga_mode[] = {
@@ -243,196 +274,228 @@ static const struct v4l2_pix_format vga_mode[] = {
.priv = 0},
};
-/*Data from sn9c102p+hv71331r */
-static const __u8 sn_hv7131[] = {
+/*Data from sn9c102p+hv7131r */
+static const u8 sn_hv7131[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x0a, 0x00, 0x00, 0x00
};
-static const __u8 sn_mi0360[] = {
+static const u8 sn_mi0360[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x06, 0x00, 0x00, 0x00
};
-static const __u8 sn_mo4000[] = {
+static const u8 sn_mo4000[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
+ 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
/* reg8 reg9 rega regb regc regd rege regf */
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x08, 0x00, 0x00, 0x00
};
-static const __u8 sn_om6802[] = {
+static const u8 sn_mt9v111[0x1c] = {
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
+ 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
+/* reg8 reg9 rega regb regc regd rege regf */
+ 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
+ 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
+/* reg18 reg19 reg1a reg1b */
+ 0x06, 0x00, 0x00, 0x00
+};
+
+static const u8 sn_om6802[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
- 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
- 0xf7
+/* reg18 reg19 reg1a reg1b */
+ 0x05, 0x00, 0x00, 0x00
};
-static const __u8 sn_ov7630[] = {
+static const u8 sn_ov7630[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x0b, 0x00, 0x00, 0x00
};
-static const __u8 sn_ov7648[] = {
+static const u8 sn_ov7648[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x0b, 0x00, 0x00, 0x00
};
-static const __u8 sn_ov7660[] = {
+static const u8 sn_ov7660[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* reg18 reg19 reg1a reg1b */
+ 0x07, 0x00, 0x00, 0x00
+};
+
+static const u8 sn_sp80708[0x1c] = {
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
+ 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
+/* reg8 reg9 rega regb regc regd rege regf */
+ 0x81, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
+ 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
+/* reg18 reg19 reg1a reg1b */
+ 0x07, 0x00, 0x00, 0x00
};
/* sequence specific to the sensors - !! index = SENSOR_xxx */
-static const __u8 *sn_tb[] = {
+static const u8 *sn_tb[] = {
sn_hv7131,
sn_mi0360,
sn_mo4000,
+ sn_mt9v111,
sn_om6802,
sn_ov7630,
sn_ov7648,
- sn_ov7660
+ sn_ov7660,
+ sn_sp80708
};
-static const __u8 gamma_def[] = {
+/* default gamma table */
+static const u8 gamma_def[17] = {
0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
};
+/* gamma for sensors HV7131R and MT9V111 */
+static const u8 gamma_spec_1[17] = {
+ 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
+ 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
+};
+/* gamma for sensor SP80708 */
+static const u8 gamma_spec_2[17] = {
+ 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
+ 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
+};
/* color matrix and offsets */
-static const __u8 reg84[] = {
+static const u8 reg84[] = {
0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
0x00, 0x00, 0x00 /* YUV offsets */
};
-static const __u8 hv7131r_sensor_init[][8] = {
- {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
- {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
- {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
- {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
-
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
- {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
- {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
- {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
- {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
- {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
-
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
-
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
+static const u8 hv7131r_sensor_init[][8] = {
+ {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
+ {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
+/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
+ {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
+/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
+
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
+ {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
+ {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
+ {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
+ {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
+ {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
+
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
+
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
{}
};
-static const __u8 mi0360_sensor_init[][8] = {
- {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
- {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
- {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
- {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
- {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
- {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
- {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
- {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
- {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
- {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
-
- {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
- {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
-
- {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
- {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
-
- {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
- {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
-/* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
-/* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
- {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
- {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
+static const u8 mi0360_sensor_init[][8] = {
+ {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
+ {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
+ {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
+ {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
+ {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
+ {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
+ {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
+ {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
+ {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
+ {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
+
+ {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
+ {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
+
+ {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
+ {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
+
+ {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
+ {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
+/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
+/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
+ {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
+ {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
{}
};
-static const __u8 mo4000_sensor_init[][8] = {
+static const u8 mo4000_sensor_init[][8] = {
{0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -455,7 +518,49 @@ static const __u8 mo4000_sensor_init[][8] = {
{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
{}
};
-static __u8 om6802_sensor_init[][8] = {
+static const u8 mt9v111_sensor_init[][8] = {
+ {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
+ /* delay 20 ms */
+ {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
+ {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
+ {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
+ {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
+ {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
+ {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
+ {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
+ {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
+ {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
+ {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
+ {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
+ {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
+ {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ /*******/
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
+ {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
+ {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
+ /*******/
+ {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
+ {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
+ {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
+ {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
+ {}
+};
+static const u8 om6802_sensor_init[][8] = {
{0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
{0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
{0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
@@ -489,7 +594,7 @@ static __u8 om6802_sensor_init[][8] = {
/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
{}
};
-static const __u8 ov7630_sensor_init[][8] = {
+static const u8 ov7630_sensor_init[][8] = {
{0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
/* win: delay 20ms */
@@ -543,7 +648,7 @@ static const __u8 ov7630_sensor_init[][8] = {
{}
};
-static const __u8 ov7648_sensor_init[][8] = {
+static const u8 ov7648_sensor_init[][8] = {
{0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -572,7 +677,8 @@ static const __u8 ov7648_sensor_init[][8] = {
{0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
/*...*/
/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
-/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
+/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
+ * set by setvflip */
{0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
@@ -589,7 +695,7 @@ static const __u8 ov7648_sensor_init[][8] = {
{}
};
-static const __u8 ov7660_sensor_init[][8] = {
+static const u8 ov7660_sensor_init[][8] = {
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
/* (delay 20ms) */
{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
@@ -678,28 +784,92 @@ static const __u8 ov7660_sensor_init[][8] = {
{}
};
-static const __u8 qtable4[] = {
- 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
- 0x06, 0x08, 0x0A, 0x11,
- 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
- 0x19, 0x19, 0x17, 0x15,
- 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
- 0x21, 0x2E, 0x21, 0x23,
- 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
- 0x25, 0x29, 0x2C, 0x29,
- 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
- 0x17, 0x1B, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29
+static const u8 sp80708_sensor_init[][8] = {
+ {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
+ /********/
+ {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
+ {}
};
/* read <len> bytes to gspca_dev->usb_buf */
static void reg_r(struct gspca_dev *gspca_dev,
- __u16 value, int len)
+ u16 value, int len)
{
#ifdef GSPCA_DEBUG
if (len > USB_BUF_SZ) {
@@ -718,10 +888,10 @@ static void reg_r(struct gspca_dev *gspca_dev,
}
static void reg_w1(struct gspca_dev *gspca_dev,
- __u16 value,
- __u8 data)
+ u16 value,
+ u8 data)
{
- PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
+ PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
gspca_dev->usb_buf[0] = data;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -733,11 +903,11 @@ static void reg_w1(struct gspca_dev *gspca_dev,
500);
}
static void reg_w(struct gspca_dev *gspca_dev,
- __u16 value,
- const __u8 *buffer,
+ u16 value,
+ const u8 *buffer,
int len)
{
- PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
+ PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
value, buffer[0], buffer[1]);
#ifdef GSPCA_DEBUG
if (len > USB_BUF_SZ) {
@@ -756,7 +926,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
}
/* I2C write 1 byte */
-static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
+static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -781,7 +951,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
/* I2C write 8 bytes */
static void i2c_w8(struct gspca_dev *gspca_dev,
- const __u8 *buffer)
+ const u8 *buffer)
{
memcpy(gspca_dev->usb_buf, buffer, 8);
usb_control_msg(gspca_dev->dev,
@@ -795,10 +965,10 @@ static void i2c_w8(struct gspca_dev *gspca_dev,
}
/* read 5 bytes in gspca_dev->usb_buf */
-static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
+static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 mode[8];
+ u8 mode[8];
mode[0] = 0x81 | 0x10;
mode[1] = sd->i2c_base;
@@ -817,7 +987,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
reg_r(gspca_dev, 0x0a, 5);
}
-static int probesensor(struct gspca_dev *gspca_dev)
+static int hv7131r_probe(struct gspca_dev *gspca_dev)
{
i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
msleep(10);
@@ -839,16 +1009,66 @@ static int probesensor(struct gspca_dev *gspca_dev)
return -ENODEV;
}
+static void mi0360_probe(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i, j;
+ u16 val = 0;
+ static const u8 probe_tb[][4][8] = {
+ { /* mi0360 */
+ {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
+ },
+ { /* mt9v111 */
+ {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
+ {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {}
+ },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
+ reg_w1(gspca_dev, 0x17, 0x62);
+ reg_w1(gspca_dev, 0x01, 0x08);
+ for (j = 0; j < 3; j++)
+ i2c_w8(gspca_dev, probe_tb[i][j]);
+ msleep(2);
+ reg_r(gspca_dev, 0x0a, 5);
+ val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
+ if (probe_tb[i][3][0] != 0)
+ i2c_w8(gspca_dev, probe_tb[i][3]);
+ reg_w1(gspca_dev, 0x01, 0x29);
+ reg_w1(gspca_dev, 0x17, 0x42);
+ if (val != 0xffff)
+ break;
+ }
+ switch (val) {
+ case 0x823a:
+ PDEBUG(D_PROBE, "Sensor mt9v111");
+ sd->sensor = SENSOR_MT9V111;
+ sd->i2c_base = 0x5c;
+ break;
+ case 0x8243:
+ PDEBUG(D_PROBE, "Sensor mi0360");
+ break;
+ default:
+ PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
+ break;
+ }
+}
+
static int configure_gpio(struct gspca_dev *gspca_dev,
- const __u8 *sn9c1xx)
+ const u8 *sn9c1xx)
{
struct sd *sd = (struct sd *) gspca_dev;
- const __u8 *reg9a;
- static const __u8 reg9a_def[] =
+ const u8 *reg9a;
+ static const u8 reg9a_def[] =
{0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
- static const __u8 reg9a_sn9c325[] =
+ static const u8 reg9a_sn9c325[] =
{0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
- static const __u8 regd4[] = {0x60, 0x00, 0x00};
+ static const u8 regd4[] = {0x60, 0x00, 0x00};
reg_w1(gspca_dev, 0xf1, 0x00);
reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
@@ -872,6 +1092,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
switch (sd->sensor) {
+ case SENSOR_MT9V111:
+ reg_w1(gspca_dev, 0x01, 0x61);
+ reg_w1(gspca_dev, 0x17, 0x61);
+ reg_w1(gspca_dev, 0x01, 0x60);
+ reg_w1(gspca_dev, 0x01, 0x40);
+ break;
case SENSOR_OM6802:
reg_w1(gspca_dev, 0x02, 0x71);
reg_w1(gspca_dev, 0x01, 0x42);
@@ -900,12 +1126,20 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
break;
}
/* fall thru */
+ case SENSOR_SP80708:
+ reg_w1(gspca_dev, 0x01, 0x63);
+ reg_w1(gspca_dev, 0x17, 0x20);
+ reg_w1(gspca_dev, 0x01, 0x62);
+ reg_w1(gspca_dev, 0x01, 0x42);
+ mdelay(100);
+ reg_w1(gspca_dev, 0x02, 0x62);
+ break;
default:
reg_w1(gspca_dev, 0x01, 0x43);
reg_w1(gspca_dev, 0x17, 0x61);
reg_w1(gspca_dev, 0x01, 0x42);
if (sd->sensor == SENSOR_HV7131R) {
- if (probesensor(gspca_dev) < 0)
+ if (hv7131r_probe(gspca_dev) < 0)
return -ENODEV;
}
break;
@@ -916,7 +1150,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
{
int i = 0;
- static const __u8 SetSensorClk[] = /* 0x08 Mclk */
+ static const u8 SetSensorClk[] = /* 0x08 Mclk */
{ 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
while (hv7131r_sensor_init[i][0]) {
@@ -946,6 +1180,19 @@ static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
}
}
+static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+
+ i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
+ i++;
+ msleep(20);
+ while (mt9v111_sensor_init[i][0]) {
+ i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
+ i++;
+ }
+}
+
static void om6802_InitSensor(struct gspca_dev *gspca_dev)
{
int i = 0;
@@ -1010,6 +1257,19 @@ static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
}
}
+static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+
+ i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
+ i++;
+ msleep(20);
+ while (sp80708_sensor_init[i][0]) {
+ i2c_w8(gspca_dev, sp80708_sensor_init[i]);
+ i++;
+ }
+}
+
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
@@ -1018,7 +1278,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -1026,16 +1285,21 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = id->driver_info >> 8;
sd->i2c_base = id->driver_info;
- sd->qindex = 4; /* set the quantization table */
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
sd->blue = BLUE_BALANCE_DEF;
sd->red = RED_BALANCE_DEF;
+ sd->gamma = GAMMA_DEF;
sd->autogain = AUTOGAIN_DEF;
sd->ag_cnt = -1;
- sd->vflip = VFLIP_DEF;
+ if (sd->sensor != SENSOR_OV7630)
+ sd->vflip = 0;
+ else
+ sd->vflip = 1;
sd->infrared = INFRARED_DEF;
+ sd->quality = QUALITY_DEF;
+ sd->jpegqual = 80;
gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
return 0;
@@ -1045,8 +1309,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
static int sd_init(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 regGpio[] = { 0x29, 0x74 };
- __u8 regF1;
+ u8 regGpio[] = { 0x29, 0x74 };
+ u8 regF1;
/* setup a selector by bridge */
reg_w1(gspca_dev, 0xf1, 0x01);
@@ -1064,11 +1328,15 @@ static int sd_init(struct gspca_dev *gspca_dev)
case BRIDGE_SN9C105:
if (regF1 != 0x11)
return -ENODEV;
+ if (sd->sensor == SENSOR_MI0360)
+ mi0360_probe(gspca_dev);
reg_w(gspca_dev, 0x01, regGpio, 2);
break;
case BRIDGE_SN9C120:
if (regF1 != 0x12)
return -ENODEV;
+ if (sd->sensor == SENSOR_MI0360)
+ mi0360_probe(gspca_dev);
regGpio[1] = 0x70;
reg_w(gspca_dev, 0x01, regGpio, 2);
break;
@@ -1086,20 +1354,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
return 0;
}
-static unsigned int setexposure(struct gspca_dev *gspca_dev,
- unsigned int expo)
+static u32 setexposure(struct gspca_dev *gspca_dev,
+ u32 expo)
{
struct sd *sd = (struct sd *) gspca_dev;
- static const __u8 doit[] = /* update sensor */
- { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
- static const __u8 sensorgo[] = /* sensor on */
- { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
- static const __u8 gainMo[] =
- { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
switch (sd->sensor) {
case SENSOR_HV7131R: {
- __u8 Expodoit[] =
+ u8 Expodoit[] =
{ 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
Expodoit[3] = expo >> 16;
@@ -1109,8 +1371,12 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
break;
}
case SENSOR_MI0360: {
- __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
+ u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
{ 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
+ static const u8 doit[] = /* update sensor */
+ { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
+ static const u8 sensorgo[] = /* sensor on */
+ { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
if (expo > 0x0635)
expo = 0x0635;
@@ -1124,10 +1390,12 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
break;
}
case SENSOR_MO4000: {
- __u8 expoMof[] =
+ u8 expoMof[] =
{ 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
- __u8 expoMo10[] =
+ u8 expoMo10[] =
{ 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
+ static const u8 gainMo[] =
+ { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
if (expo > 0x1fff)
expo = 0x1fff;
@@ -1139,14 +1407,27 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
| ((expo & 0x0003) << 4);
i2c_w8(gspca_dev, expoMo10);
i2c_w8(gspca_dev, gainMo);
- PDEBUG(D_CONF, "set exposure %d",
+ PDEBUG(D_FRAM, "set exposure %d",
((expoMo10[3] & 0x07) << 10)
| (expoMof[3] << 2)
| ((expoMo10[3] & 0x30) >> 4));
break;
}
+ case SENSOR_MT9V111: {
+ u8 expo_c1[] =
+ { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
+
+ if (expo > 0x0280)
+ expo = 0x0280;
+ else if (expo < 0x0040)
+ expo = 0x0040;
+ expo_c1[3] = expo >> 8;
+ expo_c1[4] = expo;
+ i2c_w8(gspca_dev, expo_c1);
+ break;
+ }
case SENSOR_OM6802: {
- __u8 gainOm[] =
+ u8 gainOm[] =
{ 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
if (expo > 0x03ff)
@@ -1156,7 +1437,7 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
gainOm[3] = expo >> 2;
i2c_w8(gspca_dev, gainOm);
reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
- PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
+ PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
break;
}
}
@@ -1167,7 +1448,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
unsigned int expo;
- __u8 k2;
+ u8 k2;
k2 = ((int) sd->brightness - 0x8000) >> 10;
switch (sd->sensor) {
@@ -1184,6 +1465,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
expo = sd->brightness >> 4;
sd->exposure = setexposure(gspca_dev, expo);
break;
+ case SENSOR_MT9V111:
+ expo = sd->brightness >> 8;
+ sd->exposure = setexposure(gspca_dev, expo);
+ break;
case SENSOR_OM6802:
expo = sd->brightness >> 6;
sd->exposure = setexposure(gspca_dev, expo);
@@ -1191,14 +1476,15 @@ static void setbrightness(struct gspca_dev *gspca_dev)
break;
}
- reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
+ if (sd->sensor != SENSOR_MT9V111)
+ reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
}
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 k2;
- __u8 contrast[6];
+ u8 k2;
+ u8 contrast[6];
k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
contrast[0] = (k2 + 1) / 2; /* red */
@@ -1214,8 +1500,8 @@ static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i, v;
- __u8 reg8a[12]; /* U & V gains */
- static __s16 uv[6] = { /* same as reg84 in signed decimal */
+ u8 reg8a[12]; /* U & V gains */
+ static s16 uv[6] = { /* same as reg84 in signed decimal */
-24, -38, 64, /* UR UG UB */
62, -51, -9 /* VR VG VB */
};
@@ -1236,22 +1522,75 @@ static void setredblue(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x06, sd->blue);
}
+static void setgamma(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i;
+ u8 gamma[17];
+ const u8 *gamma_base;
+ static const u8 delta[17] = {
+ 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
+ 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
+ };
+
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ case SENSOR_MT9V111:
+ gamma_base = gamma_spec_1;
+ break;
+ case SENSOR_SP80708:
+ gamma_base = gamma_spec_2;
+ break;
+ default:
+ gamma_base = gamma_def;
+ break;
+ }
+
+ for (i = 0; i < sizeof gamma; i++)
+ gamma[i] = gamma_base[i]
+ + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
+ reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
+}
+
static void setautogain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
return;
+ switch (sd->sensor) {
+ case SENSOR_OV7630:
+ case SENSOR_OV7648: {
+ u8 comb;
+
+ if (sd->sensor == SENSOR_OV7630)
+ comb = 0xc0;
+ else
+ comb = 0xa0;
+ if (sd->autogain)
+ comb |= 0x02;
+ i2c_w1(&sd->gspca_dev, 0x13, comb);
+ return;
+ }
+ }
if (sd->autogain)
sd->ag_cnt = AG_CNT_START;
else
sd->ag_cnt = -1;
}
+/* ov7630/ov7648 only */
static void setvflip(struct sd *sd)
{
- i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
- sd->vflip ? 0x82 : 0x02);
+ u8 comn;
+
+ if (sd->sensor == SENSOR_OV7630)
+ comn = 0x02;
+ else
+ comn = 0x06;
+ if (sd->vflip)
+ comn |= 0x80;
+ i2c_w1(&sd->gspca_dev, 0x75, comn);
}
static void setinfrared(struct sd *sd)
@@ -1262,20 +1601,63 @@ static void setinfrared(struct sd *sd)
sd->infrared ? 0x66 : 0x64);
}
+static void setjpegqual(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i, sc;
+
+ if (sd->jpegqual < 50)
+ sc = 5000 / sd->jpegqual;
+ else
+ sc = 200 - sd->jpegqual * 2;
+#if USB_BUF_SZ < 64
+#error "No room enough in usb_buf for quantization table"
+#endif
+ for (i = 0; i < 64; i++)
+ gspca_dev->usb_buf[i] =
+ (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x08,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0x0100, 0,
+ gspca_dev->usb_buf, 64,
+ 500);
+ for (i = 0; i < 64; i++)
+ gspca_dev->usb_buf[i] =
+ (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x08,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0x0140, 0,
+ gspca_dev->usb_buf, 64,
+ 500);
+
+ sd->reg18 ^= 0x40;
+ reg_w1(gspca_dev, 0x18, sd->reg18);
+}
+
/* -- start the camera -- */
static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i;
- __u8 reg1, reg17, reg18;
- const __u8 *sn9c1xx;
+ u8 reg1, reg17;
+ const u8 *sn9c1xx;
int mode;
- static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
- static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
- static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
- static const __u8 CE_ov76xx[] =
+ static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
+ static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
+ static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
+ static const u8 CE_ov76xx[] =
{ 0x32, 0xdd, 0x32, 0xdd };
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x21); /* JPEG 422 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
sn9c1xx = sn_tb[(int) sd->sensor];
configure_gpio(gspca_dev, sn9c1xx);
@@ -1292,6 +1674,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0xc9, 0x3c);
reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
switch (sd->sensor) {
+ case SENSOR_MT9V111:
+ reg17 = 0xe0;
+ break;
case SENSOR_OV7630:
reg17 = 0xe2;
break;
@@ -1315,14 +1700,24 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
- reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
+
+ setgamma(gspca_dev);
+
for (i = 0; i < 8; i++)
reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
switch (sd->sensor) {
+ case SENSOR_MT9V111:
+ reg_w1(gspca_dev, 0x9a, 0x07);
+ reg_w1(gspca_dev, 0x99, 0x59);
+ break;
case SENSOR_OV7648:
reg_w1(gspca_dev, 0x9a, 0x0a);
reg_w1(gspca_dev, 0x99, 0x60);
break;
+ case SENSOR_SP80708:
+ reg_w1(gspca_dev, 0x9a, 0x05);
+ reg_w1(gspca_dev, 0x99, 0x59);
+ break;
case SENSOR_OV7660:
if (sd->bridge == BRIDGE_SN9C120) {
reg_w1(gspca_dev, 0x9a, 0x05);
@@ -1358,6 +1753,15 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* reg1 = 0x06; * 640 clk 24Mz (done) */
}
break;
+ case SENSOR_MT9V111:
+ mt9v111_InitSensor(gspca_dev);
+ if (mode) {
+ reg1 = 0x04; /* 320 clk 48Mhz */
+ } else {
+/* reg1 = 0x06; * 640 clk 24Mz (done) */
+ reg17 = 0xc2;
+ }
+ break;
case SENSOR_OM6802:
om6802_InitSensor(gspca_dev);
reg17 = 0x64; /* 640 MCKSIZE */
@@ -1373,8 +1777,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg17 = 0x21;
/* reg1 = 0x42; * 42 - 46? */
break;
- default:
-/* case SENSOR_OV7660: */
+ case SENSOR_OV7660:
ov7660_InitSensor(gspca_dev);
if (sd->bridge == BRIDGE_SN9C120) {
if (mode) { /* 320x240 - 160x120 */
@@ -1387,6 +1790,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
* inverse power down */
}
break;
+ default:
+/* case SENSOR_SP80708: */
+ sp80708_InitSensor(gspca_dev);
+ if (mode) {
+/*?? reg1 = 0x04; * 320 clk 48Mhz */
+ } else {
+ reg1 = 0x46; /* 640 clk 48Mz */
+ reg17 = 0xa2;
+ }
+ break;
}
reg_w(gspca_dev, 0xc0, C0, 6);
reg_w(gspca_dev, 0xca, CA, 4);
@@ -1403,20 +1816,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
}
/* here change size mode 0 -> VGA; 1 -> CIF */
- reg18 = sn9c1xx[0x18] | (mode << 4);
- reg_w1(gspca_dev, 0x18, reg18 | 0x40);
-
- reg_w(gspca_dev, 0x100, qtable4, 0x40);
- reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
-
- reg_w1(gspca_dev, 0x18, reg18);
+ sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
+ reg_w1(gspca_dev, 0x18, sd->reg18);
+ setjpegqual(gspca_dev);
reg_w1(gspca_dev, 0x17, reg17);
reg_w1(gspca_dev, 0x01, reg1);
switch (sd->sensor) {
- case SENSOR_MI0360:
- setinfrared(sd);
- break;
case SENSOR_OV7630:
setvflip(sd);
break;
@@ -1430,14 +1836,14 @@ static int sd_start(struct gspca_dev *gspca_dev)
static void sd_stopN(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- static const __u8 stophv7131[] =
+ static const u8 stophv7131[] =
{ 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
- static const __u8 stopmi0360[] =
+ static const u8 stopmi0360[] =
{ 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
- static const __u8 stopov7648[] =
+ static const u8 stopov7648[] =
{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
- __u8 data;
- const __u8 *sn9c1xx;
+ u8 data;
+ const u8 *sn9c1xx;
data = 0x0b;
switch (sd->sensor) {
@@ -1452,6 +1858,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
case SENSOR_OV7648:
i2c_w8(gspca_dev, stopov7648);
/* fall thru */
+ case SENSOR_MT9V111:
case SENSOR_OV7630:
data = 0x29;
break;
@@ -1468,13 +1875,20 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0xf1, 0x00);
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void do_autogain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int delta;
int expotimes;
- __u8 luma_mean = 130;
- __u8 luma_delta = 20;
+ u8 luma_mean = 130;
+ u8 luma_delta = 20;
/* Thanks S., without your advice, autobright should not work :) */
if (sd->ag_cnt < 0)
@@ -1499,6 +1913,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
default:
/* case SENSOR_MO4000: */
/* case SENSOR_MI0360: */
+/* case SENSOR_MT9V111: */
/* case SENSOR_OM6802: */
expotimes = sd->exposure;
expotimes += (luma_mean - delta) >> 6;
@@ -1516,7 +1931,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
/* This function is run at interrupt level. */
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
- __u8 *data, /* isoc packet */
+ u8 *data, /* isoc packet */
int len) /* iso packet length */
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1550,7 +1965,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
if (gspca_dev->last_packet_type == LAST_PACKET) {
/* put the JPEG 422 header */
- jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
}
gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
@@ -1645,6 +2061,24 @@ static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gamma = val;
+ if (gspca_dev->streaming)
+ setgamma(gspca_dev);
+ return 0;
+}
+
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gamma;
+ return 0;
+}
+
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1699,6 +2133,34 @@ static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -1708,8 +2170,11 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.dq_callback = do_autogain,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -1724,9 +2189,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
#endif
{USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
{USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
-#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
-#endif
{USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
{USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
{USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
@@ -1764,10 +2227,10 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
+#endif
{USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
-#endif
- {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
+ {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -1794,8 +2257,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
info("registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 942f04cd44dd..6f38fa6d86b6 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -38,8 +38,11 @@ struct sd {
unsigned char brightness;
unsigned char contrast;
unsigned char colors;
+ u8 quality;
+#define QUALITY_MIN 70
+#define QUALITY_MAX 95
+#define QUALITY_DEF 85
- char qindex;
char subtype;
#define AgfaCl20 0
#define AiptekPocketDV 1
@@ -56,6 +59,8 @@ struct sd {
#define Optimedia 12
#define PalmPixDC85 13
#define ToptroIndus 14
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -629,7 +634,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
sd->subtype = id->driver_info;
if (sd->subtype != LogitechClickSmart310) {
cam->cam_mode = vga_mode;
@@ -638,10 +642,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
}
- sd->qindex = 5;
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
+ sd->quality = QUALITY_DEF;
return 0;
}
@@ -667,6 +671,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
__u8 Data;
__u8 xmult, ymult;
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x22); /* JPEG 411 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
if (sd->subtype == LogitechClickSmart310) {
xmult = 0x16;
ymult = 0x12;
@@ -713,7 +723,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
write_vector(gspca_dev, spca500_visual_defaults);
spca500_setmode(gspca_dev, xmult, ymult);
/* enable drop packet */
- reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+ err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+ if (err < 0)
PDEBUG(D_ERR, "failed to enable drop packet");
reg_w(gspca_dev, 0x00, 0x8880, 3);
err = spca50x_setup_qtable(gspca_dev,
@@ -881,6 +892,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
gspca_dev->usb_buf[0]);
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
@@ -901,7 +919,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
ffd9, 2);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
data += SPCA500_OFFSET_DATA;
len -= SPCA500_OFFSET_DATA;
@@ -937,16 +956,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
(__u8) (sd->brightness - 128));
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1);
- if (ret >= 0)
- sd->brightness = ret + 128;
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -954,16 +963,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1);
- if (ret >= 0)
- sd->contrast = ret;
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -971,16 +970,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1);
- if (ret >= 0)
- sd->colors = ret;
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -995,7 +984,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -1014,7 +1002,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -1033,11 +1020,38 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -1047,7 +1061,10 @@ static struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -1093,8 +1110,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index 82e3e3e2ada1..d48b27c648ca 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -1883,10 +1883,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1897,10 +1893,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
sd->contrast & 0xff);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1908,10 +1900,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, sd->colors);
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
-}
-
static void setblue_balance(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1934,7 +1922,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
sd->subtype = id->driver_info;
@@ -2084,7 +2071,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -2103,7 +2089,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -2122,7 +2107,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -2211,8 +2195,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index 2a33a29010ee..2acec58b1b97 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -31,9 +31,9 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- unsigned char brightness;
+ u8 brightness;
- char subtype;
+ u8 subtype;
#define IntelPCCameraPro 0
#define Nxultra 1
};
@@ -43,7 +43,6 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
{
{
.id = V4L2_CID_BRIGHTNESS,
@@ -52,7 +51,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 255,
.step = 1,
- .default_value = 127,
+#define BRIGHTNESS_DEF 127
+ .default_value = BRIGHTNESS_DEF,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
@@ -64,12 +64,12 @@ static const struct v4l2_pix_format vga_mode[] = {
.bytesperline = 160,
.sizeimage = 160 * 120 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 5},
+ .priv = 4},
{176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
.bytesperline = 176,
.sizeimage = 176 * 144 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 4},
+ .priv = 3},
{320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 * 3 / 2,
@@ -93,6 +93,7 @@ static const struct v4l2_pix_format vga_mode[] = {
#define SPCA50X_USB_CTRL 0x00 /* spca505 */
#define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */
+
#define SPCA50X_REG_GLOBAL 0x03 /* spca505 */
#define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */
#define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */
@@ -101,230 +102,230 @@ static const struct v4l2_pix_format vga_mode[] = {
#define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */
#define SPCA50X_GMISC3_SAA7113RST 0x20 /* Not sure about this one spca505 */
+/* Image format and compression control */
+#define SPCA50X_REG_COMPRESS 0x04
+
/*
* Data to initialize a SPCA505. Common to the CCD and external modes
*/
-static const __u16 spca505_init_data[][3] = {
- /* line bmRequest,value,index */
- /* 1819 */
+static const u8 spca505_init_data[][3] = {
+ /* bmRequest,value,index */
{SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3},
/* Sensor reset */
- /* 1822 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
- /* 1825 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
+ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
+ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
/* Block USB reset */
- /* 1828 */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL,
- SPCA50X_GLOBAL_MISC0},
+ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, SPCA50X_GLOBAL_MISC0},
- /* 1831 */ {0x5, 0x01, 0x10},
+ {0x05, 0x01, 0x10},
/* Maybe power down some stuff */
- /* 1834 */ {0x5, 0x0f, 0x11},
+ {0x05, 0x0f, 0x11},
/* Setup internal CCD ? */
- /* 1837 */ {0x6, 0x10, 0x08},
- /* 1840 */ {0x6, 0x00, 0x09},
- /* 1843 */ {0x6, 0x00, 0x0a},
- /* 1846 */ {0x6, 0x00, 0x0b},
- /* 1849 */ {0x6, 0x10, 0x0c},
- /* 1852 */ {0x6, 0x00, 0x0d},
- /* 1855 */ {0x6, 0x00, 0x0e},
- /* 1858 */ {0x6, 0x00, 0x0f},
- /* 1861 */ {0x6, 0x10, 0x10},
- /* 1864 */ {0x6, 0x02, 0x11},
- /* 1867 */ {0x6, 0x00, 0x12},
- /* 1870 */ {0x6, 0x04, 0x13},
- /* 1873 */ {0x6, 0x02, 0x14},
- /* 1876 */ {0x6, 0x8a, 0x51},
- /* 1879 */ {0x6, 0x40, 0x52},
- /* 1882 */ {0x6, 0xb6, 0x53},
- /* 1885 */ {0x6, 0x3d, 0x54},
+ {0x06, 0x10, 0x08},
+ {0x06, 0x00, 0x09},
+ {0x06, 0x00, 0x0a},
+ {0x06, 0x00, 0x0b},
+ {0x06, 0x10, 0x0c},
+ {0x06, 0x00, 0x0d},
+ {0x06, 0x00, 0x0e},
+ {0x06, 0x00, 0x0f},
+ {0x06, 0x10, 0x10},
+ {0x06, 0x02, 0x11},
+ {0x06, 0x00, 0x12},
+ {0x06, 0x04, 0x13},
+ {0x06, 0x02, 0x14},
+ {0x06, 0x8a, 0x51},
+ {0x06, 0x40, 0x52},
+ {0x06, 0xb6, 0x53},
+ {0x06, 0x3d, 0x54},
{}
};
/*
* Data to initialize the camera using the internal CCD
*/
-static const __u16 spca505_open_data_ccd[][3] = {
- /* line bmRequest,value,index */
+static const u8 spca505_open_data_ccd[][3] = {
+ /* bmRequest,value,index */
/* Internal CCD data set */
- /* 1891 */ {0x3, 0x04, 0x01},
+ {0x03, 0x04, 0x01},
/* This could be a reset */
- /* 1894 */ {0x3, 0x00, 0x01},
+ {0x03, 0x00, 0x01},
/* Setup compression and image registers. 0x6 and 0x7 seem to be
related to H&V hold, and are resolution mode specific */
- /* 1897 */ {0x4, 0x10, 0x01},
+ {0x04, 0x10, 0x01},
/* DIFF(0x50), was (0x10) */
- /* 1900 */ {0x4, 0x00, 0x04},
- /* 1903 */ {0x4, 0x00, 0x05},
- /* 1906 */ {0x4, 0x20, 0x06},
- /* 1909 */ {0x4, 0x20, 0x07},
+ {0x04, 0x00, 0x04},
+ {0x04, 0x00, 0x05},
+ {0x04, 0x20, 0x06},
+ {0x04, 0x20, 0x07},
- /* 1912 */ {0x8, 0x0a, 0x00},
+ {0x08, 0x0a, 0x00},
/* DIFF (0x4a), was (0xa) */
- /* 1915 */ {0x5, 0x00, 0x10},
- /* 1918 */ {0x5, 0x00, 0x11},
- /* 1921 */ {0x5, 0x00, 0x00},
+ {0x05, 0x00, 0x10},
+ {0x05, 0x00, 0x11},
+ {0x05, 0x00, 0x00},
/* DIFF not written */
- /* 1924 */ {0x5, 0x00, 0x01},
+ {0x05, 0x00, 0x01},
/* DIFF not written */
- /* 1927 */ {0x5, 0x00, 0x02},
+ {0x05, 0x00, 0x02},
/* DIFF not written */
- /* 1930 */ {0x5, 0x00, 0x03},
+ {0x05, 0x00, 0x03},
/* DIFF not written */
- /* 1933 */ {0x5, 0x00, 0x04},
+ {0x05, 0x00, 0x04},
/* DIFF not written */
- /* 1936 */ {0x5, 0x80, 0x05},
+ {0x05, 0x80, 0x05},
/* DIFF not written */
- /* 1939 */ {0x5, 0xe0, 0x06},
+ {0x05, 0xe0, 0x06},
/* DIFF not written */
- /* 1942 */ {0x5, 0x20, 0x07},
+ {0x05, 0x20, 0x07},
/* DIFF not written */
- /* 1945 */ {0x5, 0xa0, 0x08},
+ {0x05, 0xa0, 0x08},
/* DIFF not written */
- /* 1948 */ {0x5, 0x0, 0x12},
+ {0x05, 0x0, 0x12},
/* DIFF not written */
- /* 1951 */ {0x5, 0x02, 0x0f},
+ {0x05, 0x02, 0x0f},
/* DIFF not written */
- /* 1954 */ {0x5, 0x10, 0x46},
+ {0x05, 0x10, 0x46},
/* DIFF not written */
- /* 1957 */ {0x5, 0x8, 0x4a},
+ {0x05, 0x8, 0x4a},
/* DIFF not written */
- /* 1960 */ {0x3, 0x08, 0x03},
+ {0x03, 0x08, 0x03},
/* DIFF (0x3,0x28,0x3) */
- /* 1963 */ {0x3, 0x08, 0x01},
- /* 1966 */ {0x3, 0x0c, 0x03},
+ {0x03, 0x08, 0x01},
+ {0x03, 0x0c, 0x03},
/* DIFF not written */
- /* 1969 */ {0x3, 0x21, 0x00},
+ {0x03, 0x21, 0x00},
/* DIFF (0x39) */
/* Extra block copied from init to hopefully ensure CCD is in a sane state */
- /* 1837 */ {0x6, 0x10, 0x08},
- /* 1840 */ {0x6, 0x00, 0x09},
- /* 1843 */ {0x6, 0x00, 0x0a},
- /* 1846 */ {0x6, 0x00, 0x0b},
- /* 1849 */ {0x6, 0x10, 0x0c},
- /* 1852 */ {0x6, 0x00, 0x0d},
- /* 1855 */ {0x6, 0x00, 0x0e},
- /* 1858 */ {0x6, 0x00, 0x0f},
- /* 1861 */ {0x6, 0x10, 0x10},
- /* 1864 */ {0x6, 0x02, 0x11},
- /* 1867 */ {0x6, 0x00, 0x12},
- /* 1870 */ {0x6, 0x04, 0x13},
- /* 1873 */ {0x6, 0x02, 0x14},
- /* 1876 */ {0x6, 0x8a, 0x51},
- /* 1879 */ {0x6, 0x40, 0x52},
- /* 1882 */ {0x6, 0xb6, 0x53},
- /* 1885 */ {0x6, 0x3d, 0x54},
+ {0x06, 0x10, 0x08},
+ {0x06, 0x00, 0x09},
+ {0x06, 0x00, 0x0a},
+ {0x06, 0x00, 0x0b},
+ {0x06, 0x10, 0x0c},
+ {0x06, 0x00, 0x0d},
+ {0x06, 0x00, 0x0e},
+ {0x06, 0x00, 0x0f},
+ {0x06, 0x10, 0x10},
+ {0x06, 0x02, 0x11},
+ {0x06, 0x00, 0x12},
+ {0x06, 0x04, 0x13},
+ {0x06, 0x02, 0x14},
+ {0x06, 0x8a, 0x51},
+ {0x06, 0x40, 0x52},
+ {0x06, 0xb6, 0x53},
+ {0x06, 0x3d, 0x54},
/* End of extra block */
- /* 1972 */ {0x6, 0x3f, 0x1},
+ {0x06, 0x3f, 0x1},
/* Block skipped */
- /* 1975 */ {0x6, 0x10, 0x02},
- /* 1978 */ {0x6, 0x64, 0x07},
- /* 1981 */ {0x6, 0x10, 0x08},
- /* 1984 */ {0x6, 0x00, 0x09},
- /* 1987 */ {0x6, 0x00, 0x0a},
- /* 1990 */ {0x6, 0x00, 0x0b},
- /* 1993 */ {0x6, 0x10, 0x0c},
- /* 1996 */ {0x6, 0x00, 0x0d},
- /* 1999 */ {0x6, 0x00, 0x0e},
- /* 2002 */ {0x6, 0x00, 0x0f},
- /* 2005 */ {0x6, 0x10, 0x10},
- /* 2008 */ {0x6, 0x02, 0x11},
- /* 2011 */ {0x6, 0x00, 0x12},
- /* 2014 */ {0x6, 0x04, 0x13},
- /* 2017 */ {0x6, 0x02, 0x14},
- /* 2020 */ {0x6, 0x8a, 0x51},
- /* 2023 */ {0x6, 0x40, 0x52},
- /* 2026 */ {0x6, 0xb6, 0x53},
- /* 2029 */ {0x6, 0x3d, 0x54},
- /* 2032 */ {0x6, 0x60, 0x57},
- /* 2035 */ {0x6, 0x20, 0x58},
- /* 2038 */ {0x6, 0x15, 0x59},
- /* 2041 */ {0x6, 0x05, 0x5a},
-
- /* 2044 */ {0x5, 0x01, 0xc0},
- /* 2047 */ {0x5, 0x10, 0xcb},
- /* 2050 */ {0x5, 0x80, 0xc1},
+ {0x06, 0x10, 0x02},
+ {0x06, 0x64, 0x07},
+ {0x06, 0x10, 0x08},
+ {0x06, 0x00, 0x09},
+ {0x06, 0x00, 0x0a},
+ {0x06, 0x00, 0x0b},
+ {0x06, 0x10, 0x0c},
+ {0x06, 0x00, 0x0d},
+ {0x06, 0x00, 0x0e},
+ {0x06, 0x00, 0x0f},
+ {0x06, 0x10, 0x10},
+ {0x06, 0x02, 0x11},
+ {0x06, 0x00, 0x12},
+ {0x06, 0x04, 0x13},
+ {0x06, 0x02, 0x14},
+ {0x06, 0x8a, 0x51},
+ {0x06, 0x40, 0x52},
+ {0x06, 0xb6, 0x53},
+ {0x06, 0x3d, 0x54},
+ {0x06, 0x60, 0x57},
+ {0x06, 0x20, 0x58},
+ {0x06, 0x15, 0x59},
+ {0x06, 0x05, 0x5a},
+
+ {0x05, 0x01, 0xc0},
+ {0x05, 0x10, 0xcb},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2053 */ {0x5, 0x0, 0xc2},
+ {0x05, 0x0, 0xc2},
/* 4 was 0 */
- /* 2056 */ {0x5, 0x00, 0xca},
- /* 2059 */ {0x5, 0x80, 0xc1},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2062 */ {0x5, 0x04, 0xc2},
- /* 2065 */ {0x5, 0x00, 0xca},
- /* 2068 */ {0x5, 0x0, 0xc1},
+ {0x05, 0x04, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x0, 0xc1},
/* */
- /* 2071 */ {0x5, 0x00, 0xc2},
- /* 2074 */ {0x5, 0x00, 0xca},
- /* 2077 */ {0x5, 0x40, 0xc1},
+ {0x05, 0x00, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x40, 0xc1},
/* */
- /* 2080 */ {0x5, 0x17, 0xc2},
- /* 2083 */ {0x5, 0x00, 0xca},
- /* 2086 */ {0x5, 0x80, 0xc1},
+ {0x05, 0x17, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2089 */ {0x5, 0x06, 0xc2},
- /* 2092 */ {0x5, 0x00, 0xca},
- /* 2095 */ {0x5, 0x80, 0xc1},
+ {0x05, 0x06, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2098 */ {0x5, 0x04, 0xc2},
- /* 2101 */ {0x5, 0x00, 0xca},
+ {0x05, 0x04, 0xc2},
+ {0x05, 0x00, 0xca},
- /* 2104 */ {0x3, 0x4c, 0x3},
- /* 2107 */ {0x3, 0x18, 0x1},
+ {0x03, 0x4c, 0x3},
+ {0x03, 0x18, 0x1},
- /* 2110 */ {0x6, 0x70, 0x51},
- /* 2113 */ {0x6, 0xbe, 0x53},
- /* 2116 */ {0x6, 0x71, 0x57},
- /* 2119 */ {0x6, 0x20, 0x58},
- /* 2122 */ {0x6, 0x05, 0x59},
- /* 2125 */ {0x6, 0x15, 0x5a},
+ {0x06, 0x70, 0x51},
+ {0x06, 0xbe, 0x53},
+ {0x06, 0x71, 0x57},
+ {0x06, 0x20, 0x58},
+ {0x06, 0x05, 0x59},
+ {0x06, 0x15, 0x5a},
- /* 2128 */ {0x4, 0x00, 0x08},
+ {0x04, 0x00, 0x08},
/* Compress = OFF (0x1 to turn on) */
- /* 2131 */ {0x4, 0x12, 0x09},
- /* 2134 */ {0x4, 0x21, 0x0a},
- /* 2137 */ {0x4, 0x10, 0x0b},
- /* 2140 */ {0x4, 0x21, 0x0c},
- /* 2143 */ {0x4, 0x05, 0x00},
+ {0x04, 0x12, 0x09},
+ {0x04, 0x21, 0x0a},
+ {0x04, 0x10, 0x0b},
+ {0x04, 0x21, 0x0c},
+ {0x04, 0x05, 0x00},
/* was 5 (Image Type ? ) */
- /* 2146 */ {0x4, 0x00, 0x01},
-
- /* 2149 */ {0x6, 0x3f, 0x01},
-
- /* 2152 */ {0x4, 0x00, 0x04},
- /* 2155 */ {0x4, 0x00, 0x05},
- /* 2158 */ {0x4, 0x40, 0x06},
- /* 2161 */ {0x4, 0x40, 0x07},
-
- /* 2164 */ {0x6, 0x1c, 0x17},
- /* 2167 */ {0x6, 0xe2, 0x19},
- /* 2170 */ {0x6, 0x1c, 0x1b},
- /* 2173 */ {0x6, 0xe2, 0x1d},
- /* 2176 */ {0x6, 0xaa, 0x1f},
- /* 2179 */ {0x6, 0x70, 0x20},
-
- /* 2182 */ {0x5, 0x01, 0x10},
- /* 2185 */ {0x5, 0x00, 0x11},
- /* 2188 */ {0x5, 0x01, 0x00},
- /* 2191 */ {0x5, 0x05, 0x01},
- /* 2194 */ {0x5, 0x00, 0xc1},
+ {0x04, 0x00, 0x01},
+
+ {0x06, 0x3f, 0x01},
+
+ {0x04, 0x00, 0x04},
+ {0x04, 0x00, 0x05},
+ {0x04, 0x40, 0x06},
+ {0x04, 0x40, 0x07},
+
+ {0x06, 0x1c, 0x17},
+ {0x06, 0xe2, 0x19},
+ {0x06, 0x1c, 0x1b},
+ {0x06, 0xe2, 0x1d},
+ {0x06, 0xaa, 0x1f},
+ {0x06, 0x70, 0x20},
+
+ {0x05, 0x01, 0x10},
+ {0x05, 0x00, 0x11},
+ {0x05, 0x01, 0x00},
+ {0x05, 0x05, 0x01},
+ {0x05, 0x00, 0xc1},
/* */
- /* 2197 */ {0x5, 0x00, 0xc2},
- /* 2200 */ {0x5, 0x00, 0xca},
+ {0x05, 0x00, 0xc2},
+ {0x05, 0x00, 0xca},
- /* 2203 */ {0x6, 0x70, 0x51},
- /* 2206 */ {0x6, 0xbe, 0x53},
+ {0x06, 0x70, 0x51},
+ {0x06, 0xbe, 0x53},
{}
};
/*
- Made by Tomasz Zablocki (skalamandra@poczta.onet.pl)
+ * Made by Tomasz Zablocki (skalamandra@poczta.onet.pl)
* SPCA505b chip based cameras initialization data
- *
*/
/* jfm */
#define initial_brightness 0x7f /* 0x0(white)-0xff(black) */
@@ -332,7 +333,7 @@ static const __u16 spca505_open_data_ccd[][3] = {
/*
* Data to initialize a SPCA505. Common to the CCD and external modes
*/
-static const __u16 spca505b_init_data[][3] = {
+static const u8 spca505b_init_data[][3] = {
/* start */
{0x02, 0x00, 0x00}, /* init */
{0x02, 0x00, 0x01},
@@ -396,7 +397,7 @@ static const __u16 spca505b_init_data[][3] = {
/*
* Data to initialize the camera using the internal CCD
*/
-static const __u16 spca505b_open_data_ccd[][3] = {
+static const u8 spca505b_open_data_ccd[][3] = {
/* {0x02,0x00,0x00}, */
{0x03, 0x04, 0x01}, /* rst */
@@ -426,7 +427,7 @@ static const __u16 spca505b_open_data_ccd[][3] = {
{0x05, 0x00, 0x12},
{0x05, 0x6f, 0x00},
{0x05, initial_brightness >> 6, 0x00},
- {0x05, initial_brightness << 2, 0x01},
+ {0x05, (initial_brightness << 2) & 0xff, 0x01},
{0x05, 0x00, 0x02},
{0x05, 0x01, 0x03},
{0x05, 0x00, 0x04},
@@ -436,7 +437,7 @@ static const __u16 spca505b_open_data_ccd[][3] = {
{0x05, 0xa0, 0x08},
{0x05, 0x00, 0x12},
{0x05, 0x02, 0x0f},
- {0x05, 128, 0x14}, /* max exposure off (0=on) */
+ {0x05, 0x80, 0x14}, /* max exposure off (0=on) */
{0x05, 0x01, 0xb0},
{0x05, 0x01, 0xbf},
{0x03, 0x02, 0x06},
@@ -560,26 +561,26 @@ static const __u16 spca505b_open_data_ccd[][3] = {
{0x06, 0x32, 0x20},
{0x05, initial_brightness >> 6, 0x00},
- {0x05, initial_brightness << 2, 0x01},
+ {0x05, (initial_brightness << 2) & 0xff, 0x01},
{0x05, 0x06, 0xc1},
{0x05, 0x58, 0xc2},
- {0x05, 0x0, 0xca},
- {0x05, 0x0, 0x11},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x00, 0x11},
{}
};
static int reg_write(struct usb_device *dev,
- __u16 reg, __u16 index, __u16 value)
+ u16 req, u16 index, u16 value)
{
int ret;
ret = usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
- reg,
+ req,
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, NULL, 0, 500);
- PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x",
- reg, index, value, ret);
+ PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
+ req, index, value, ret);
if (ret < 0)
PDEBUG(D_ERR, "reg write: error %d", ret);
return ret;
@@ -587,42 +588,34 @@ static int reg_write(struct usb_device *dev,
/* returns: negative is error, pos or zero is data */
static int reg_read(struct gspca_dev *gspca_dev,
- __u16 reg, /* bRequest */
- __u16 index, /* wIndex */
- __u16 length) /* wLength (1 or 2 only) */
+ u16 req, /* bRequest */
+ u16 index) /* wIndex */
{
int ret;
- gspca_dev->usb_buf[1] = 0;
ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
- reg,
+ req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- (__u16) 0, /* value */
- (__u16) index,
- gspca_dev->usb_buf, length,
+ 0, /* value */
+ index,
+ gspca_dev->usb_buf, 2,
500); /* timeout */
- if (ret < 0) {
- PDEBUG(D_ERR, "reg_read err %d", ret);
- return -1;
- }
+ if (ret < 0)
+ return ret;
return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
}
static int write_vector(struct gspca_dev *gspca_dev,
- const __u16 data[][3])
+ const u8 data[][3])
{
struct usb_device *dev = gspca_dev->dev;
int ret, i = 0;
- while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
+ while (data[i][0] != 0) {
ret = reg_write(dev, data[i][0], data[i][2], data[i][1]);
- if (ret < 0) {
- PDEBUG(D_ERR,
- "Register write failed for 0x%x,0x%x,0x%x",
- data[i][0], data[i][1], data[i][2]);
+ if (ret < 0)
return ret;
- }
i++;
}
return 0;
@@ -636,14 +629,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
sd->subtype = id->driver_info;
if (sd->subtype != IntelPCCameraPro)
- cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ cam->nmodes = ARRAY_SIZE(vga_mode);
else /* no 640x480 for IntelPCCameraPro */
- cam->nmodes = sizeof vga_mode / sizeof vga_mode[0] - 1;
- sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
+ cam->nmodes = ARRAY_SIZE(vga_mode) - 1;
+ sd->brightness = BRIGHTNESS_DEF;
if (sd->subtype == Nxultra) {
if (write_vector(gspca_dev, spca505b_init_data))
@@ -658,81 +650,71 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
+ return 0;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
struct sd *sd = (struct sd *) gspca_dev;
- int ret;
+ u8 brightness = sd->brightness;
+
+ reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6);
+ reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2);
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ int ret, mode;
+ static u8 mode_tb[][3] = {
+ /* r00 r06 r07 */
+ {0x00, 0x10, 0x10}, /* 640x480 */
+ {0x01, 0x1a, 0x1a}, /* 352x288 */
+ {0x02, 0x1c, 0x1d}, /* 320x240 */
+ {0x04, 0x34, 0x34}, /* 176x144 */
+ {0x05, 0x40, 0x40} /* 160x120 */
+ };
- PDEBUG(D_STREAM, "Initializing SPCA505");
if (sd->subtype == Nxultra)
write_vector(gspca_dev, spca505b_open_data_ccd);
else
write_vector(gspca_dev, spca505_open_data_ccd);
- ret = reg_read(gspca_dev, 6, 0x16, 2);
+ ret = reg_read(gspca_dev, 0x06, 0x16);
if (ret < 0) {
- PDEBUG(D_ERR|D_STREAM,
- "register read failed for after vector read err = %d",
+ PDEBUG(D_ERR|D_CONF,
+ "register read failed err: %d",
ret);
- return -EIO;
+ return ret;
}
- PDEBUG(D_STREAM,
- "After vector read returns : 0x%x should be 0x0101",
- ret & 0xffff);
-
- ret = reg_write(gspca_dev->dev, 6, 0x16, 0x0a);
- if (ret < 0) {
- PDEBUG(D_ERR, "register write failed for (6,0xa,0x16) err=%d",
- ret);
- return -EIO;
+ if (ret != 0x0101) {
+ PDEBUG(D_ERR|D_CONF,
+ "After vector read returns 0x%04x should be 0x0101",
+ ret);
}
- reg_write(gspca_dev->dev, 5, 0xc2, 18);
- return 0;
-}
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
+ ret = reg_write(gspca_dev->dev, 0x06, 0x16, 0x0a);
+ if (ret < 0)
+ return ret;
+ reg_write(gspca_dev->dev, 0x05, 0xc2, 0x12);
/* necessary because without it we can see stream
* only once after loading module */
/* stopping usb registers Tomasz change */
- reg_write(dev, 0x02, 0x0, 0x0);
- switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
- case 0:
- reg_write(dev, 0x04, 0x00, 0x00);
- reg_write(dev, 0x04, 0x06, 0x10);
- reg_write(dev, 0x04, 0x07, 0x10);
- break;
- case 1:
- reg_write(dev, 0x04, 0x00, 0x01);
- reg_write(dev, 0x04, 0x06, 0x1a);
- reg_write(dev, 0x04, 0x07, 0x1a);
- break;
- case 2:
- reg_write(dev, 0x04, 0x00, 0x02);
- reg_write(dev, 0x04, 0x06, 0x1c);
- reg_write(dev, 0x04, 0x07, 0x1d);
- break;
- case 4:
- reg_write(dev, 0x04, 0x00, 0x04);
- reg_write(dev, 0x04, 0x06, 0x34);
- reg_write(dev, 0x04, 0x07, 0x34);
- break;
- default:
-/* case 5: */
- reg_write(dev, 0x04, 0x00, 0x05);
- reg_write(dev, 0x04, 0x06, 0x40);
- reg_write(dev, 0x04, 0x07, 0x40);
- break;
- }
-/* Enable ISO packet machine - should we do this here or in ISOC init ? */
+ reg_write(dev, 0x02, 0x00, 0x00);
+
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ reg_write(dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]);
+ reg_write(dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]);
+ reg_write(dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]);
+
ret = reg_write(dev, SPCA50X_REG_USB,
SPCA50X_USB_CTRL,
SPCA50X_CUSB_ENABLE);
-/* reg_write(dev, 0x5, 0x0, 0x0); */
-/* reg_write(dev, 0x5, 0x0, 0x1); */
-/* reg_write(dev, 0x5, 0x11, 0x2); */
+ setbrightness(gspca_dev);
+
return ret;
}
@@ -750,15 +732,15 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
/* This maybe reset or power control */
reg_write(gspca_dev->dev, 0x03, 0x03, 0x20);
- reg_write(gspca_dev->dev, 0x03, 0x01, 0x0);
- reg_write(gspca_dev->dev, 0x03, 0x00, 0x1);
- reg_write(gspca_dev->dev, 0x05, 0x10, 0x1);
- reg_write(gspca_dev->dev, 0x05, 0x11, 0xf);
+ reg_write(gspca_dev->dev, 0x03, 0x01, 0x00);
+ reg_write(gspca_dev->dev, 0x03, 0x00, 0x01);
+ reg_write(gspca_dev->dev, 0x05, 0x10, 0x01);
+ reg_write(gspca_dev->dev, 0x05, 0x11, 0x0f);
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
- __u8 *data, /* isoc packet */
+ u8 *data, /* isoc packet */
int len) /* iso packet length */
{
switch (data[0]) {
@@ -771,7 +753,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
data, len);
break;
case 0xff: /* drop */
-/* gspca_dev->last_packet_type = DISCARD_PACKET; */
break;
default:
data += 1;
@@ -782,24 +763,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
}
}
-static void setbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- __u8 brightness = sd->brightness;
- reg_write(gspca_dev->dev, 5, 0x00, (255 - brightness) >> 6);
- reg_write(gspca_dev->dev, 5, 0x01, (255 - brightness) << 2);
-
-}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = 255
- - ((reg_read(gspca_dev, 5, 0x01, 1) >> 2)
- + (reg_read(gspca_dev, 5, 0x0, 1) << 6));
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -814,7 +777,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -863,8 +825,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 96e2512e0621..3a0c893f942d 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -193,24 +193,6 @@ static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur,
}
}
-static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg)
-{
- int retry = 60;
-
- reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004);
- reg_w(gspca_dev->dev, 0x07, reg, 0x0001);
- reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002);
- while (--retry) {
- reg_r(gspca_dev, 0x07, 0x0003, 2);
- if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00)
- break;
- }
- if (retry == 0)
- return -1;
- reg_r(gspca_dev, 0x07, 0x0000, 1);
- return gspca_dev->usb_buf[0];
-}
-
static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
__u16 norme,
__u16 channel)
@@ -303,7 +285,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
@@ -596,13 +577,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = spca506_ReadI2c(gspca_dev, SAA7113_bright);
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -612,13 +586,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->contrast = spca506_ReadI2c(gspca_dev, SAA7113_contrast);
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -628,13 +595,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->colors = spca506_ReadI2c(gspca_dev, SAA7113_saturation);
-}
-
static void sethue(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -644,13 +604,6 @@ static void sethue(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void gethue(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->hue = spca506_ReadI2c(gspca_dev, SAA7113_hue);
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -665,7 +618,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -684,7 +636,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -703,7 +654,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -722,7 +672,6 @@ static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- gethue(gspca_dev);
*val = sd->hue;
return 0;
}
@@ -772,8 +721,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index be5d740a315d..adacf8437661 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -101,8 +101,7 @@ static const struct v4l2_pix_format sif_mode[] = {
* Initialization data: this is the first set-up data written to the
* device (before the open data).
*/
-static const __u16 spca508_init_data[][3] =
-#define IGN(x) /* nothing */
+static const u16 spca508_init_data[][2] =
{
/* line URB value, index */
/* 44274 1804 */ {0x0000, 0x870b},
@@ -589,11 +588,10 @@ static const __u16 spca508_init_data[][3] =
{}
};
-
/*
* Initialization data for Intel EasyPC Camera CS110
*/
-static const __u16 spca508cs110_init_data[][3] = {
+static const u16 spca508cs110_init_data[][2] = {
{0x0000, 0x870b}, /* Reset CTL3 */
{0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
{0x0000, 0x8111}, /* Normal operation on reset */
@@ -677,7 +675,7 @@ static const __u16 spca508cs110_init_data[][3] = {
{}
};
-static const __u16 spca508_sightcam_init_data[][3] = {
+static const u16 spca508_sightcam_init_data[][2] = {
/* This line seems to setup the frame/canvas */
/*368 */ {0x000f, 0x8402},
@@ -760,7 +758,7 @@ static const __u16 spca508_sightcam_init_data[][3] = {
{}
};
-static const __u16 spca508_sightcam2_init_data[][3] = {
+static const u16 spca508_sightcam2_init_data[][2] = {
/* 35 */ {0x0020, 0x8112},
/* 36 */ {0x000f, 0x8402},
@@ -1107,7 +1105,7 @@ static const __u16 spca508_sightcam2_init_data[][3] = {
/*
* Initialization data for Creative Webcam Vista
*/
-static const __u16 spca508_vista_init_data[][3] = {
+static const u16 spca508_vista_init_data[][2] = {
{0x0008, 0x8200}, /* Clear register */
{0x0000, 0x870b}, /* Reset CTL3 */
{0x0020, 0x8112}, /* Video Drop packet enable */
@@ -1309,18 +1307,18 @@ static const __u16 spca508_vista_init_data[][3] = {
{0x0050, 0x8703},
{0x0002, 0x8704}, /* External input CKIx1 */
- {0x0001, 0x870C}, /* Select CKOx2 output */
- {0x009A, 0x8600}, /* Line memory Read Counter (L) */
+ {0x0001, 0x870c}, /* Select CKOx2 output */
+ {0x009a, 0x8600}, /* Line memory Read Counter (L) */
{0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */
{0x0023, 0x8601},
{0x0010, 0x8602},
- {0x000A, 0x8603},
+ {0x000a, 0x8603},
{0x009A, 0x8600},
- {0x0001, 0x865B}, /* 1 Horizontal Offset for Valid Pixel(L) */
- {0x0003, 0x865C}, /* Vertical offset for valid lines (L) */
- {0x0058, 0x865D}, /* Horizontal valid pixels window (L) */
- {0x0048, 0x865E}, /* Vertical valid lines window (L) */
- {0x0000, 0x865F},
+ {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */
+ {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */
+ {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */
+ {0x0048, 0x865e}, /* Vertical valid lines window (L) */
+ {0x0000, 0x865f},
{0x0006, 0x8660},
/* Enable nibble data input, select nibble input order */
@@ -1328,63 +1326,63 @@ static const __u16 spca508_vista_init_data[][3] = {
{0x0013, 0x8608}, /* A11 Coeficients for color correction */
{0x0028, 0x8609},
/* Note: these values are confirmed at the end of array */
- {0x0005, 0x860A}, /* ... */
- {0x0025, 0x860B},
- {0x00E1, 0x860C},
- {0x00FA, 0x860D},
- {0x00F4, 0x860E},
- {0x00E8, 0x860F},
+ {0x0005, 0x860a}, /* ... */
+ {0x0025, 0x860b},
+ {0x00e1, 0x860c},
+ {0x00fa, 0x860D},
+ {0x00f4, 0x860e},
+ {0x00e8, 0x860f},
{0x0025, 0x8610}, /* A33 Coef. */
- {0x00FC, 0x8611}, /* White balance offset: R */
+ {0x00fc, 0x8611}, /* White balance offset: R */
{0x0001, 0x8612}, /* White balance offset: Gr */
- {0x00FE, 0x8613}, /* White balance offset: B */
+ {0x00fe, 0x8613}, /* White balance offset: B */
{0x0000, 0x8614}, /* White balance offset: Gb */
{0x0064, 0x8651}, /* R gain for white balance (L) */
{0x0040, 0x8652}, /* Gr gain for white balance (L) */
{0x0066, 0x8653}, /* B gain for white balance (L) */
{0x0040, 0x8654}, /* Gb gain for white balance (L) */
- {0x0001, 0x863F}, /* Enable fixed gamma correction */
+ {0x0001, 0x863f}, /* Enable fixed gamma correction */
- {0x00A1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */
+ {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */
/* UV division: UV no change, Enable New edge enhancement */
{0x0018, 0x8657}, /* Edge gain high threshold */
{0x0020, 0x8658}, /* Edge gain low threshold */
{0x000A, 0x8659}, /* Edge bandwidth high threshold */
- {0x0005, 0x865A}, /* Edge bandwidth low threshold */
+ {0x0005, 0x865a}, /* Edge bandwidth low threshold */
{0x0064, 0x8607}, /* UV filter enable */
{0x0016, 0x8660},
- {0x0000, 0x86B0}, /* Bad pixels compensation address */
- {0x00DC, 0x86B1}, /* X coord for bad pixels compensation (L) */
- {0x0000, 0x86B2},
- {0x0009, 0x86B3}, /* Y coord for bad pixels compensation (L) */
- {0x0000, 0x86B4},
-
- {0x0001, 0x86B0},
- {0x00F5, 0x86B1},
- {0x0000, 0x86B2},
- {0x00C6, 0x86B3},
- {0x0000, 0x86B4},
-
- {0x0002, 0x86B0},
- {0x001C, 0x86B1},
- {0x0001, 0x86B2},
- {0x00D7, 0x86B3},
- {0x0000, 0x86B4},
-
- {0x0003, 0x86B0},
- {0x001C, 0x86B1},
- {0x0001, 0x86B2},
- {0x00D8, 0x86B3},
- {0x0000, 0x86B4},
-
- {0x0004, 0x86B0},
- {0x001D, 0x86B1},
- {0x0001, 0x86B2},
- {0x00D8, 0x86B3},
- {0x0000, 0x86B4},
- {0x001E, 0x8660},
+ {0x0000, 0x86b0}, /* Bad pixels compensation address */
+ {0x00dc, 0x86b1}, /* X coord for bad pixels compensation (L) */
+ {0x0000, 0x86b2},
+ {0x0009, 0x86b3}, /* Y coord for bad pixels compensation (L) */
+ {0x0000, 0x86b4},
+
+ {0x0001, 0x86b0},
+ {0x00f5, 0x86b1},
+ {0x0000, 0x86b2},
+ {0x00c6, 0x86b3},
+ {0x0000, 0x86b4},
+
+ {0x0002, 0x86b0},
+ {0x001c, 0x86b1},
+ {0x0001, 0x86b2},
+ {0x00d7, 0x86b3},
+ {0x0000, 0x86b4},
+
+ {0x0003, 0x86b0},
+ {0x001c, 0x86b1},
+ {0x0001, 0x86b2},
+ {0x00d8, 0x86b3},
+ {0x0000, 0x86b4},
+
+ {0x0004, 0x86b0},
+ {0x001d, 0x86b1},
+ {0x0001, 0x86b2},
+ {0x00d8, 0x86b3},
+ {0x0000, 0x86b4},
+ {0x001e, 0x8660},
/* READ { 0, 0x0000, 0x8608 } ->
0000: 13 */
@@ -1449,7 +1447,7 @@ static int reg_read(struct gspca_dev *gspca_dev,
}
static int write_vector(struct gspca_dev *gspca_dev,
- const __u16 data[][3])
+ const u16 data[][2])
{
struct usb_device *dev = gspca_dev->dev;
int ret, i = 0;
@@ -1487,7 +1485,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
@@ -1593,13 +1590,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, 0x8654, brightness);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = reg_read(gspca_dev, 0x8651);
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1614,7 +1604,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -1666,8 +1655,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 3c9288019e96..c99c5e34e211 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -141,38 +141,38 @@ static const struct v4l2_pix_format sif_072a_mode[] = {
#define SPCA561_OFFSET_WIN1GBAVE 14
#define SPCA561_OFFSET_FREQ 15
#define SPCA561_OFFSET_VSYNC 16
-#define SPCA561_OFFSET_DATA 1
#define SPCA561_INDEX_I2C_BASE 0x8800
#define SPCA561_SNAPBIT 0x20
#define SPCA561_SNAPCTRL 0x40
-static const __u16 rev72a_init_data1[][2] = {
+static const u16 rev72a_reset[][2] = {
{0x0000, 0x8114}, /* Software GPIO output data */
{0x0001, 0x8114}, /* Software GPIO output data */
{0x0000, 0x8112}, /* Some kind of reset */
+ {}
+};
+static const __u16 rev72a_init_data1[][2] = {
{0x0003, 0x8701}, /* PCLK clock delay adjustment */
{0x0001, 0x8703}, /* HSYNC from cmos inverted */
{0x0011, 0x8118}, /* Enable and conf sensor */
{0x0001, 0x8118}, /* Conf sensor */
{0x0092, 0x8804}, /* I know nothing about these */
{0x0010, 0x8802}, /* 0x88xx registers, so I won't */
- {0x000d, 0x8805}, /* sensor default setting */
{}
};
-static const __u16 rev72a_init_sensor1[][2] = {
- /* ms-win values */
- {0x0001, 0x0018}, /* 0x01 <- 0x0d */
- {0x0002, 0x0065}, /* 0x02 <- 0x18 */
- {0x0004, 0x0121}, /* 0x04 <- 0x0165 */
- {0x0005, 0x00aa}, /* 0x05 <- 0x21 */
- {0x0007, 0x0004}, /* 0x07 <- 0xaa */
- {0x0020, 0x1502}, /* 0x20 <- 0x1504 */
- {0x0039, 0x0010}, /* 0x39 <- 0x02 */
- {0x0035, 0x0049}, /* 0x35 <- 0x10 */
- {0x0009, 0x100b}, /* 0x09 <- 0x1049 */
- {0x0028, 0x000f}, /* 0x28 <- 0x0b */
- {0x003b, 0x003c}, /* 0x3b <- 0x0f */
- {0x003c, 0x0000}, /* 0x3c <- 0x00 */
+static const u16 rev72a_init_sensor1[][2] = {
+ {0x0001, 0x000d},
+ {0x0002, 0x0018},
+ {0x0004, 0x0165},
+ {0x0005, 0x0021},
+ {0x0007, 0x00aa},
+ {0x0020, 0x1504},
+ {0x0039, 0x0002},
+ {0x0035, 0x0010},
+ {0x0009, 0x1049},
+ {0x0028, 0x000b},
+ {0x003b, 0x000f},
+ {0x003c, 0x0000},
{}
};
static const __u16 rev72a_init_data2[][2] = {
@@ -190,15 +190,10 @@ static const __u16 rev72a_init_data2[][2] = {
{0x0002, 0x8201}, /* Output address for r/w serial EEPROM */
{0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
{0x0001, 0x8200}, /* OprMode to be executed by hardware */
- {0x0007, 0x8201}, /* Output address for r/w serial EEPROM */
- {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
- {0x0001, 0x8200}, /* OprMode to be executed by hardware */
- {0x0010, 0x8660}, /* Compensation memory stuff */
- {0x0018, 0x8660}, /* Compensation memory stuff */
-
- {0x0004, 0x8611}, /* R offset for white balance */
- {0x0004, 0x8612}, /* Gr offset for white balance */
- {0x0007, 0x8613}, /* B offset for white balance */
+/* from ms-win */
+ {0x0000, 0x8611}, /* R offset for white balance */
+ {0x00fd, 0x8612}, /* Gr offset for white balance */
+ {0x0003, 0x8613}, /* B offset for white balance */
{0x0000, 0x8614}, /* Gb offset for white balance */
/* from ms-win */
{0x0035, 0x8651}, /* R gain for white balance */
@@ -206,8 +201,8 @@ static const __u16 rev72a_init_data2[][2] = {
{0x005f, 0x8653}, /* B gain for white balance */
{0x0040, 0x8654}, /* Gb gain for white balance */
{0x0002, 0x8502}, /* Maximum average bit rate stuff */
-
{0x0011, 0x8802},
+
{0x0087, 0x8700}, /* Set master clock (96Mhz????) */
{0x0081, 0x8702}, /* Master clock output enable */
@@ -218,104 +213,15 @@ static const __u16 rev72a_init_data2[][2] = {
{0x0003, 0x865c}, /* Vertical offset for valid lines */
{}
};
-static const __u16 rev72a_init_sensor2[][2] = {
- /* ms-win values */
- {0x0003, 0x0121}, /* 0x03 <- 0x01 0x21 //289 */
- {0x0004, 0x0165}, /* 0x04 <- 0x01 0x65 //357 */
- {0x0005, 0x002f}, /* 0x05 <- 0x2f */
- {0x0006, 0x0000}, /* 0x06 <- 0 */
- {0x000a, 0x0002}, /* 0x0a <- 2 */
- {0x0009, 0x1061}, /* 0x09 <- 0x1061 */
- {0x0035, 0x0014}, /* 0x35 <- 0x14 */
- {}
-};
-static const __u16 rev72a_init_data3[][2] = {
- {0x0030, 0x8112}, /* ISO and drop packet enable */
-/*fixme: should stop here*/
- {0x0000, 0x8112}, /* Some kind of reset ???? */
- {0x0009, 0x8118}, /* Enable sensor and set standby */
- {0x0000, 0x8114}, /* Software GPIO output data */
- {0x0000, 0x8114}, /* Software GPIO output data */
- {0x0001, 0x8114}, /* Software GPIO output data */
- {0x0000, 0x8112}, /* Some kind of reset ??? */
- {0x0003, 0x8701},
- {0x0001, 0x8703},
- {0x0011, 0x8118},
- {0x0001, 0x8118},
- /***************/
- {0x0092, 0x8804},
- {0x0010, 0x8802},
- {0x000d, 0x8805},
- {0x0001, 0x8801},
- {0x0000, 0x8800},
- {0x0018, 0x8805},
- {0x0002, 0x8801},
- {0x0000, 0x8800},
- {0x0065, 0x8805},
- {0x0004, 0x8801},
- {0x0001, 0x8800},
- {0x0021, 0x8805},
- {0x0005, 0x8801},
- {0x0000, 0x8800},
- {0x00aa, 0x8805},
- {0x0007, 0x8801}, /* mode 0xaa */
- {0x0000, 0x8800},
- {0x0004, 0x8805},
- {0x0020, 0x8801},
- {0x0015, 0x8800}, /* mode 0x0415 */
- {0x0002, 0x8805},
- {0x0039, 0x8801},
- {0x0000, 0x8800},
- {0x0010, 0x8805},
- {0x0035, 0x8801},
- {0x0000, 0x8800},
- {0x0049, 0x8805},
- {0x0009, 0x8801},
- {0x0010, 0x8800},
- {0x000b, 0x8805},
- {0x0028, 0x8801},
- {0x0000, 0x8800},
- {0x000f, 0x8805},
- {0x003b, 0x8801},
- {0x0000, 0x8800},
- {0x0000, 0x8805},
- {0x003c, 0x8801},
- {0x0000, 0x8800},
- {0x0002, 0x8502},
- {0x0039, 0x8801},
- {0x0000, 0x8805},
- {0x0000, 0x8800},
-
- {0x0087, 0x8700}, /* overwrite by start */
- {0x0081, 0x8702},
- {0x0000, 0x8500},
-/* {0x0010, 0x8500}, -- Previous line was this */
- {0x0002, 0x865b},
- {0x0003, 0x865c},
- /***************/
- {0x0003, 0x8801}, /* 0x121-> 289 */
- {0x0021, 0x8805},
- {0x0001, 0x8800},
- {0x0004, 0x8801}, /* 0x165 -> 357 */
- {0x0065, 0x8805},
- {0x0001, 0x8800},
- {0x0005, 0x8801}, /* 0x2f //blanking control colonne */
- {0x002f, 0x8805},
- {0x0000, 0x8800},
- {0x0006, 0x8801}, /* 0x00 //blanking mode row */
- {0x0000, 0x8805},
- {0x0000, 0x8800},
- {0x000a, 0x8801}, /* 0x01 //0x02 */
- {0x0001, 0x8805},
- {0x0000, 0x8800},
- {0x0009, 0x8801}, /* 0x1061 - setexposure times && pixel clock
+static const u16 rev72a_init_sensor2[][2] = {
+ {0x0003, 0x0121},
+ {0x0004, 0x0165},
+ {0x0005, 0x002f}, /* blanking control column */
+ {0x0006, 0x0000}, /* blanking mode row*/
+ {0x000a, 0x0002},
+ {0x0009, 0x1061}, /* setexposure times && pixel clock
* 0001 0 | 000 0110 0001 */
- {0x0061, 0x8805}, /* 61 31 */
- {0x0008, 0x8800}, /* 08 */
- {0x0035, 0x8801}, /* 0x14 - set gain general */
- {0x001f, 0x8805}, /* 0x14 */
- {0x0000, 0x8800},
- {0x000e, 0x8112}, /* white balance - was 30 */
+ {0x0035, 0x0014},
{}
};
@@ -460,6 +366,7 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
reg_r(gspca_dev, 0x8803, 1);
if (!gspca_dev->usb_buf[0])
return;
+ msleep(10);
} while (--retry);
}
@@ -479,6 +386,7 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
reg_r(gspca_dev, 0x8805, 1);
return ((int) value << 8) | gspca_dev->usb_buf[0];
}
+ msleep(10);
} while (--retry);
return -1;
}
@@ -541,7 +449,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */
sd->chip_revision = id->driver_info;
@@ -572,11 +479,13 @@ static int sd_init_12a(struct gspca_dev *gspca_dev)
static int sd_init_72a(struct gspca_dev *gspca_dev)
{
PDEBUG(D_STREAM, "Chip revision: 072a");
+ write_vector(gspca_dev, rev72a_reset);
+ msleep(200);
write_vector(gspca_dev, rev72a_init_data1);
write_sensor_72a(gspca_dev, rev72a_init_sensor1);
write_vector(gspca_dev, rev72a_init_data2);
write_sensor_72a(gspca_dev, rev72a_init_sensor2);
- write_vector(gspca_dev, rev72a_init_data3);
+ reg_w_val(gspca_dev->dev, 0x8112, 0x30);
return 0;
}
@@ -731,11 +640,18 @@ static int sd_start_72a(struct gspca_dev *gspca_dev)
int Clck;
int mode;
+ write_vector(gspca_dev, rev72a_reset);
+ msleep(200);
+ write_vector(gspca_dev, rev72a_init_data1);
+ write_sensor_72a(gspca_dev, rev72a_init_sensor1);
+
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
switch (mode) {
default:
-/* case 0:
- case 1: */
+ case 0:
+ Clck = 0x27; /* ms-win 0x87 */
+ break;
+ case 1:
Clck = 0x25;
break;
case 2:
@@ -745,13 +661,14 @@ static int sd_start_72a(struct gspca_dev *gspca_dev)
Clck = 0x21;
break;
}
- reg_w_val(dev, 0x8500, mode); /* mode */
reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
- reg_w_val(dev, 0x8112, 0x10 | 0x20);
+ reg_w_val(dev, 0x8702, 0x81);
+ reg_w_val(dev, 0x8500, mode); /* mode */
+ write_sensor_72a(gspca_dev, rev72a_init_sensor2);
setcontrast(gspca_dev);
/* setbrightness(gspca_dev); * fixme: bad values */
- setwhite(gspca_dev);
setautogain(gspca_dev);
+ reg_w_val(dev, 0x8112, 0x10 | 0x20);
return 0;
}
@@ -867,12 +784,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
- switch (data[0]) { /* sequence number */
+ len--;
+ switch (*data++) { /* sequence number */
case 0: /* start of frame */
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
data, 0);
- data += SPCA561_OFFSET_DATA;
- len -= SPCA561_OFFSET_DATA;
if (data[1] & 0x10) {
/* compressed bayer */
gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -893,8 +809,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
case 0xff: /* drop (empty mpackets) */
return;
}
- data++;
- len--;
gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
@@ -1197,8 +1111,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
new file mode 100644
index 000000000000..04e3ae57a2e3
--- /dev/null
+++ b/drivers/media/video/gspca/sq905.c
@@ -0,0 +1,456 @@
+/*
+ * SQ905 subdriver
+ *
+ * Copyright (C) 2008, 2009 Adam Baker and Theodore Kilgore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * History and Acknowledgments
+ *
+ * The original Linux driver for SQ905 based cameras was written by
+ * Marcell Lengyel and furter developed by many other contributers
+ * and is available from http://sourceforge.net/projects/sqcam/
+ *
+ * This driver takes advantage of the reverse engineering work done for
+ * that driver and for libgphoto2 but shares no code with them.
+ *
+ * This driver has used as a base the finepix driver and other gspca
+ * based drivers and may still contain code fragments taken from those
+ * drivers.
+ */
+
+#define MODULE_NAME "sq905"
+
+#include <linux/workqueue.h>
+#include "gspca.h"
+
+MODULE_AUTHOR("Adam Baker <linux@baker-net.org.uk>, "
+ "Theodore Kilgore <kilgota@auburn.edu>");
+MODULE_DESCRIPTION("GSPCA/SQ905 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* Default timeouts, in ms */
+#define SQ905_CMD_TIMEOUT 500
+#define SQ905_DATA_TIMEOUT 1000
+
+/* Maximum transfer size to use. */
+#define SQ905_MAX_TRANSFER 0x8000
+#define FRAME_HEADER_LEN 64
+
+/* The known modes, or registers. These go in the "value" slot. */
+
+/* 00 is "none" obviously */
+
+#define SQ905_BULK_READ 0x03 /* precedes any bulk read */
+#define SQ905_COMMAND 0x06 /* precedes the command codes below */
+#define SQ905_PING 0x07 /* when reading an "idling" command */
+#define SQ905_READ_DONE 0xc0 /* ack bulk read completed */
+
+/* Any non-zero value in the bottom 2 bits of the 2nd byte of
+ * the ID appears to indicate the camera can do 640*480. If the
+ * LSB of that byte is set the image is just upside down, otherwise
+ * it is rotated 180 degrees. */
+#define SQ905_HIRES_MASK 0x00000300
+#define SQ905_ORIENTATION_MASK 0x00000100
+
+/* Some command codes. These go in the "index" slot. */
+
+#define SQ905_ID 0xf0 /* asks for model string */
+#define SQ905_CONFIG 0x20 /* gets photo alloc. table, not used here */
+#define SQ905_DATA 0x30 /* accesses photo data, not used here */
+#define SQ905_CLEAR 0xa0 /* clear everything */
+#define SQ905_CAPTURE_LOW 0x60 /* Starts capture at 160x120 */
+#define SQ905_CAPTURE_MED 0x61 /* Starts capture at 320x240 */
+#define SQ905_CAPTURE_HIGH 0x62 /* Starts capture at 640x480 (some cams only) */
+/* note that the capture command also controls the output dimensions */
+
+/* Structure to hold all of our device specific stuff */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ /*
+ * Driver stuff
+ */
+ struct work_struct work_struct;
+ struct workqueue_struct *work_thread;
+};
+
+static struct v4l2_pix_format sq905_mode[] = {
+ { 160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+ { 320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+ { 640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0}
+};
+
+/*
+ * Send a command to the camera.
+ */
+static int sq905_command(struct gspca_dev *gspca_dev, u16 index)
+{
+ int ret;
+
+ gspca_dev->usb_buf[0] = '\0';
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ SQ905_COMMAND, index, gspca_dev->usb_buf, 1,
+ SQ905_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ SQ905_PING, 0, gspca_dev->usb_buf, 1,
+ SQ905_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed 2 (%d)",
+ __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Acknowledge the end of a frame - see warning on sq905_command.
+ */
+static int sq905_ack_frame(struct gspca_dev *gspca_dev)
+{
+ int ret;
+
+ gspca_dev->usb_buf[0] = '\0';
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ SQ905_READ_DONE, 0, gspca_dev->usb_buf, 1,
+ SQ905_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * request and read a block of data - see warning on sq905_command.
+ */
+static int
+sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size)
+{
+ int ret;
+ int act_len;
+
+ gspca_dev->usb_buf[0] = '\0';
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ SQ905_BULK_READ, size, gspca_dev->usb_buf,
+ 1, SQ905_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
+ return ret;
+ }
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_rcvbulkpipe(gspca_dev->dev, 0x81),
+ data, size, &act_len, SQ905_DATA_TIMEOUT);
+
+ /* successful, it returns 0, otherwise negative */
+ if (ret < 0 || act_len != size) {
+ PDEBUG(D_ERR, "bulk read fail (%d) len %d/%d",
+ ret, act_len, size);
+ return -EIO;
+ }
+ return 0;
+}
+
+/* This function is called as a workqueue function and runs whenever the camera
+ * is streaming data. Because it is a workqueue function it is allowed to sleep
+ * so we can use synchronous USB calls. To avoid possible collisions with other
+ * threads attempting to use the camera's USB interface we take the gspca
+ * usb_lock when performing USB operations. In practice the only thing we need
+ * to protect against is the usb_set_interface call that gspca makes during
+ * stream_off as the camera doesn't provide any controls that the user could try
+ * to change.
+ */
+static void sq905_dostream(struct work_struct *work)
+{
+ struct sd *dev = container_of(work, struct sd, work_struct);
+ struct gspca_dev *gspca_dev = &dev->gspca_dev;
+ struct gspca_frame *frame;
+ int bytes_left; /* bytes remaining in current frame. */
+ int data_len; /* size to use for the next read. */
+ int header_read; /* true if we have already read the frame header. */
+ int discarding; /* true if we failed to get space for frame. */
+ int packet_type;
+ int frame_sz;
+ int ret;
+ u8 *data;
+ u8 *buffer;
+
+ buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
+ mutex_lock(&gspca_dev->usb_lock);
+ if (!buffer) {
+ PDEBUG(D_ERR, "Couldn't allocate USB buffer");
+ goto quit_stream;
+ }
+
+ frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage
+ + FRAME_HEADER_LEN;
+
+ while (gspca_dev->present && gspca_dev->streaming) {
+ /* Need a short delay to ensure streaming flag was set by
+ * gspca and to make sure gspca can grab the mutex. */
+ mutex_unlock(&gspca_dev->usb_lock);
+ msleep(1);
+
+ /* request some data and then read it until we have
+ * a complete frame. */
+ bytes_left = frame_sz;
+ header_read = 0;
+ discarding = 0;
+
+ while (bytes_left > 0) {
+ data_len = bytes_left > SQ905_MAX_TRANSFER ?
+ SQ905_MAX_TRANSFER : bytes_left;
+ mutex_lock(&gspca_dev->usb_lock);
+ if (!gspca_dev->present)
+ goto quit_stream;
+ ret = sq905_read_data(gspca_dev, buffer, data_len);
+ if (ret < 0)
+ goto quit_stream;
+ mutex_unlock(&gspca_dev->usb_lock);
+ PDEBUG(D_STREAM,
+ "Got %d bytes out of %d for frame",
+ data_len, bytes_left);
+ bytes_left -= data_len;
+ data = buffer;
+ if (!header_read) {
+ packet_type = FIRST_PACKET;
+ /* The first 64 bytes of each frame are
+ * a header full of FF 00 bytes */
+ data += FRAME_HEADER_LEN;
+ data_len -= FRAME_HEADER_LEN;
+ header_read = 1;
+ } else if (bytes_left == 0) {
+ packet_type = LAST_PACKET;
+ } else {
+ packet_type = INTER_PACKET;
+ }
+ frame = gspca_get_i_frame(gspca_dev);
+ if (frame && !discarding) {
+ frame = gspca_frame_add(gspca_dev, packet_type,
+ frame, data, data_len);
+ /* If entire frame fits in one packet we still
+ need to add a LAST_PACKET */
+ if (packet_type == FIRST_PACKET &&
+ bytes_left == 0)
+ frame = gspca_frame_add(gspca_dev,
+ LAST_PACKET,
+ frame, data, 0);
+ } else {
+ discarding = 1;
+ }
+ }
+ /* acknowledge the frame */
+ mutex_lock(&gspca_dev->usb_lock);
+ if (!gspca_dev->present)
+ goto quit_stream;
+ ret = sq905_ack_frame(gspca_dev);
+ if (ret < 0)
+ goto quit_stream;
+ }
+quit_stream:
+ /* the usb_lock is already acquired */
+ if (gspca_dev->present)
+ sq905_command(gspca_dev, SQ905_CLEAR);
+ mutex_unlock(&gspca_dev->usb_lock);
+ kfree(buffer);
+}
+
+/* This function is called at probe time just before sd_init */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct cam *cam = &gspca_dev->cam;
+ struct sd *dev = (struct sd *) gspca_dev;
+
+ /* We don't use the buffer gspca allocates so make it small. */
+ cam->bulk_size = 64;
+
+ INIT_WORK(&dev->work_struct, sq905_dostream);
+
+ return 0;
+}
+
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *dev = (struct sd *) gspca_dev;
+
+ /* wait for the work queue to terminate */
+ mutex_unlock(&gspca_dev->usb_lock);
+ /* This waits for sq905_dostream to finish */
+ destroy_workqueue(dev->work_thread);
+ dev->work_thread = NULL;
+ mutex_lock(&gspca_dev->usb_lock);
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ u32 ident;
+ int ret;
+
+ /* connect to the camera and read
+ * the model ID and process that and put it away.
+ */
+ ret = sq905_command(gspca_dev, SQ905_CLEAR);
+ if (ret < 0)
+ return ret;
+ ret = sq905_command(gspca_dev, SQ905_ID);
+ if (ret < 0)
+ return ret;
+ ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4);
+ if (ret < 0)
+ return ret;
+ /* usb_buf is allocated with kmalloc so is aligned.
+ * Camera model number is the right way round if we assume this
+ * reverse engineered ID is supposed to be big endian. */
+ ident = be32_to_cpup((__be32 *)gspca_dev->usb_buf);
+ ret = sq905_command(gspca_dev, SQ905_CLEAR);
+ if (ret < 0)
+ return ret;
+ PDEBUG(D_CONF, "SQ905 camera ID %08x detected", ident);
+ gspca_dev->cam.cam_mode = sq905_mode;
+ gspca_dev->cam.nmodes = ARRAY_SIZE(sq905_mode);
+ if (!(ident & SQ905_HIRES_MASK))
+ gspca_dev->cam.nmodes--;
+ return 0;
+}
+
+/* Set up for getting frames. */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *dev = (struct sd *) gspca_dev;
+ int ret;
+
+ /* "Open the shutter" and set size, to start capture */
+ switch (gspca_dev->curr_mode) {
+ default:
+/* case 2: */
+ PDEBUG(D_STREAM, "Start streaming at high resolution");
+ ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_HIGH);
+ break;
+ case 1:
+ PDEBUG(D_STREAM, "Start streaming at medium resolution");
+ ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_MED);
+ break;
+ case 0:
+ PDEBUG(D_STREAM, "Start streaming at low resolution");
+ ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_LOW);
+ }
+
+ if (ret < 0) {
+ PDEBUG(D_ERR, "Start streaming command failed");
+ return ret;
+ }
+ /* Start the workqueue function to do the streaming */
+ dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
+ queue_work(dev->work_thread, &dev->work_struct);
+
+ return 0;
+}
+
+/* Table of supported USB devices */
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x2770, 0x9120)},
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .config = sd_config,
+ .init = sd_init,
+ .start = sd_start,
+ .stop0 = sd_stop0,
+};
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id,
+ &sd_desc,
+ sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
+ PDEBUG(D_PROBE, "registered");
+ return 0;
+}
+
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
new file mode 100644
index 000000000000..0bcb74a1b143
--- /dev/null
+++ b/drivers/media/video/gspca/sq905c.c
@@ -0,0 +1,328 @@
+/*
+ * SQ905C subdriver
+ *
+ * Copyright (C) 2009 Theodore Kilgore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ *
+ * This driver uses work done in
+ * libgphoto2/camlibs/digigr8, Copyright (C) Theodore Kilgore.
+ *
+ * This driver has also used as a base the sq905c driver
+ * and may contain code fragments from it.
+ */
+
+#define MODULE_NAME "sq905c"
+
+#include <linux/workqueue.h>
+#include "gspca.h"
+
+MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
+MODULE_DESCRIPTION("GSPCA/SQ905C USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* Default timeouts, in ms */
+#define SQ905C_CMD_TIMEOUT 500
+#define SQ905C_DATA_TIMEOUT 1000
+
+/* Maximum transfer size to use. */
+#define SQ905C_MAX_TRANSFER 0x8000
+
+#define FRAME_HEADER_LEN 0x50
+
+/* Commands. These go in the "value" slot. */
+#define SQ905C_CLEAR 0xa0 /* clear everything */
+#define SQ905C_CAPTURE_LOW 0xa040 /* Starts capture at 160x120 */
+#define SQ905C_CAPTURE_MED 0x1440 /* Starts capture at 320x240 */
+#define SQ905C_CAPTURE_HI 0x2840 /* Starts capture at 320x240 */
+
+/* For capture, this must go in the "index" slot. */
+#define SQ905C_CAPTURE_INDEX 0x110f
+
+/* Structure to hold all of our device specific stuff */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+ const struct v4l2_pix_format *cap_mode;
+ /* Driver stuff */
+ struct work_struct work_struct;
+ struct workqueue_struct *work_thread;
+};
+
+/*
+ * Most of these cameras will do 640x480 and 320x240. 160x120 works
+ * in theory but gives very poor output. Therefore, not supported.
+ * The 0x2770:0x9050 cameras have max resolution of 320x240.
+ */
+static struct v4l2_pix_format sq905c_mode[] = {
+ { 320, 240, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+ { 640, 480, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0}
+};
+
+/* Send a command to the camera. */
+static int sq905c_command(struct gspca_dev *gspca_dev, u16 command, u16 index)
+{
+ int ret;
+
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ command, index, NULL, 0,
+ SQ905C_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)",
+ __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/* This function is called as a workqueue function and runs whenever the camera
+ * is streaming data. Because it is a workqueue function it is allowed to sleep
+ * so we can use synchronous USB calls. To avoid possible collisions with other
+ * threads attempting to use the camera's USB interface the gspca usb_lock is
+ * used when performing the one USB control operation inside the workqueue,
+ * which tells the camera to close the stream. In practice the only thing
+ * which needs to be protected against is the usb_set_interface call that
+ * gspca makes during stream_off. Otherwise the camera doesn't provide any
+ * controls that the user could try to change.
+ */
+static void sq905c_dostream(struct work_struct *work)
+{
+ struct sd *dev = container_of(work, struct sd, work_struct);
+ struct gspca_dev *gspca_dev = &dev->gspca_dev;
+ struct gspca_frame *frame;
+ int bytes_left; /* bytes remaining in current frame. */
+ int data_len; /* size to use for the next read. */
+ int act_len;
+ int discarding = 0; /* true if we failed to get space for frame. */
+ int packet_type;
+ int ret;
+ u8 *buffer;
+
+ buffer = kmalloc(SQ905C_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
+ if (!buffer) {
+ PDEBUG(D_ERR, "Couldn't allocate USB buffer");
+ goto quit_stream;
+ }
+
+ while (gspca_dev->present && gspca_dev->streaming) {
+ if (!gspca_dev->present)
+ goto quit_stream;
+ /* Request the header, which tells the size to download */
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_rcvbulkpipe(gspca_dev->dev, 0x81),
+ buffer, FRAME_HEADER_LEN, &act_len,
+ SQ905C_DATA_TIMEOUT);
+ PDEBUG(D_STREAM,
+ "Got %d bytes out of %d for header",
+ act_len, FRAME_HEADER_LEN);
+ if (ret < 0 || act_len < FRAME_HEADER_LEN)
+ goto quit_stream;
+ /* size is read from 4 bytes starting 0x40, little endian */
+ bytes_left = buffer[0x40]|(buffer[0x41]<<8)|(buffer[0x42]<<16)
+ |(buffer[0x43]<<24);
+ PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left);
+ /* We keep the header. It has other information, too. */
+ packet_type = FIRST_PACKET;
+ frame = gspca_get_i_frame(gspca_dev);
+ if (frame && !discarding) {
+ gspca_frame_add(gspca_dev, packet_type,
+ frame, buffer, FRAME_HEADER_LEN);
+ } else
+ discarding = 1;
+ while (bytes_left > 0) {
+ data_len = bytes_left > SQ905C_MAX_TRANSFER ?
+ SQ905C_MAX_TRANSFER : bytes_left;
+ if (!gspca_dev->present)
+ goto quit_stream;
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_rcvbulkpipe(gspca_dev->dev, 0x81),
+ buffer, data_len, &act_len,
+ SQ905C_DATA_TIMEOUT);
+ if (ret < 0 || act_len < data_len)
+ goto quit_stream;
+ PDEBUG(D_STREAM,
+ "Got %d bytes out of %d for frame",
+ data_len, bytes_left);
+ bytes_left -= data_len;
+ if (bytes_left == 0)
+ packet_type = LAST_PACKET;
+ else
+ packet_type = INTER_PACKET;
+ frame = gspca_get_i_frame(gspca_dev);
+ if (frame && !discarding)
+ gspca_frame_add(gspca_dev, packet_type,
+ frame, buffer, data_len);
+ else
+ discarding = 1;
+ }
+ }
+quit_stream:
+ mutex_lock(&gspca_dev->usb_lock);
+ if (gspca_dev->present)
+ sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
+ mutex_unlock(&gspca_dev->usb_lock);
+ kfree(buffer);
+}
+
+/* This function is called at probe time just before sd_init */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct cam *cam = &gspca_dev->cam;
+ struct sd *dev = (struct sd *) gspca_dev;
+
+ PDEBUG(D_PROBE,
+ "SQ9050 camera detected"
+ " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ cam->cam_mode = sq905c_mode;
+ cam->nmodes = 2;
+ if (id->idProduct == 0x9050)
+ cam->nmodes = 1;
+ /* We don't use the buffer gspca allocates so make it small. */
+ cam->bulk_size = 32;
+ INIT_WORK(&dev->work_struct, sq905c_dostream);
+ return 0;
+}
+
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *dev = (struct sd *) gspca_dev;
+
+ /* wait for the work queue to terminate */
+ mutex_unlock(&gspca_dev->usb_lock);
+ /* This waits for sq905c_dostream to finish */
+ destroy_workqueue(dev->work_thread);
+ dev->work_thread = NULL;
+ mutex_lock(&gspca_dev->usb_lock);
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ int ret;
+
+ /* connect to the camera and reset it. */
+ ret = sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
+ return ret;
+}
+
+/* Set up for getting frames. */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *dev = (struct sd *) gspca_dev;
+ int ret;
+
+ dev->cap_mode = gspca_dev->cam.cam_mode;
+ /* "Open the shutter" and set size, to start capture */
+ switch (gspca_dev->width) {
+ case 640:
+ PDEBUG(D_STREAM, "Start streaming at high resolution");
+ dev->cap_mode++;
+ ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_HI,
+ SQ905C_CAPTURE_INDEX);
+ break;
+ default: /* 320 */
+ PDEBUG(D_STREAM, "Start streaming at medium resolution");
+ ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_MED,
+ SQ905C_CAPTURE_INDEX);
+ }
+
+ if (ret < 0) {
+ PDEBUG(D_ERR, "Start streaming command failed");
+ return ret;
+ }
+ /* Start the workqueue function to do the streaming */
+ dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
+ queue_work(dev->work_thread, &dev->work_struct);
+
+ return 0;
+}
+
+/* Table of supported USB devices */
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x2770, 0x905c)},
+ {USB_DEVICE(0x2770, 0x9050)},
+ {USB_DEVICE(0x2770, 0x913d)},
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .config = sd_config,
+ .init = sd_init,
+ .start = sd_start,
+ .stop0 = sd_stop0,
+};
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id,
+ &sd_desc,
+ sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
+ PDEBUG(D_PROBE, "registered");
+ return 0;
+}
+
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 60de9af87fbb..f25be20cf1a6 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -35,10 +35,13 @@ struct sd {
unsigned char contrast;
unsigned char colors;
unsigned char lightfreq;
-};
+ u8 quality;
+#define QUALITY_MIN 60
+#define QUALITY_MAX 95
+#define QUALITY_DEF 80
-/* global parameters */
-static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */
+ u8 *jpeg_hdr;
+};
/* V4L2 controls supported by the driver */
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -180,7 +183,7 @@ static int rcv_val(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x63b, 0);
reg_w(gspca_dev, 0x630, 5);
ret = usb_bulk_msg(dev,
- usb_rcvbulkpipe(dev, 5),
+ usb_rcvbulkpipe(dev, 0x05),
gspca_dev->usb_buf,
4, /* length */
&alen,
@@ -294,15 +297,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam = &gspca_dev->cam;
- cam->epaddr = 0x02;
gspca_dev->cam.cam_mode = vga_mode;
gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
sd->lightfreq = FREQ_DEF;
+ sd->quality = QUALITY_DEF;
return 0;
}
@@ -326,8 +328,15 @@ static int sd_init(struct gspca_dev *gspca_dev)
/* -- start the camera -- */
static int sd_start(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
int ret, value;
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x22); /* JPEG 411 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
/* work on alternate 1 */
usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
@@ -399,11 +408,19 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
PDEBUG(D_STREAM, "camera stopped");
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
int len) /* iso packet length */
{
+ struct sd *sd = (struct sd *) gspca_dev;
static unsigned char ffd9[] = {0xff, 0xd9};
/* a frame starts with:
@@ -420,7 +437,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
ffd9, 2);
/* put the JPEG 411 header */
- jpeg_put_header(gspca_dev, frame, sd_quant, 0x22);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
/* beginning of the frame */
#define STKHDRSZ 12
@@ -520,6 +538,34 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
return -EINVAL;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -529,8 +575,11 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.querymenu = sd_querymenu,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -562,8 +611,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
info("registered");
return 0;
}
@@ -575,6 +626,3 @@ static void __exit sd_mod_exit(void)
module_init(sd_mod_init);
module_exit(sd_mod_exit);
-
-module_param_named(quant, sd_quant, int, 0644);
-MODULE_PARM_DESC(quant, "Quantization index (0..8)");
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 13a021e3cbb7..9dff2e65b116 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -429,7 +429,6 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Configuring camera");
cam = &gspca_dev->cam;
- cam->epaddr = STV_ISOC_ENDPOINT_ADDR;
sd->desc = sd_desc;
gspca_dev->sd_desc = &sd->desc;
@@ -501,8 +500,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
index 14335a9e4bb5..b16903814203 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
@@ -30,6 +30,66 @@
#include "stv06xx_hdcs.h"
+static const struct ctrl hdcs1x00_ctrl[] = {
+ {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "exposure",
+ .minimum = 0x00,
+ .maximum = 0xffff,
+ .step = 0x1,
+ .default_value = HDCS_DEFAULT_EXPOSURE,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = hdcs_set_exposure,
+ .get = hdcs_get_exposure
+ }, {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "gain",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x1,
+ .default_value = HDCS_DEFAULT_GAIN,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = hdcs_set_gain,
+ .get = hdcs_get_gain
+ }
+};
+
+static struct v4l2_pix_format hdcs1x00_mode[] = {
+ {
+ HDCS_1X00_DEF_WIDTH,
+ HDCS_1X00_DEF_HEIGHT,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
+ .bytesperline = HDCS_1X00_DEF_WIDTH,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1
+ }
+};
+
+static const struct ctrl hdcs1020_ctrl[] = {};
+
+static struct v4l2_pix_format hdcs1020_mode[] = {
+ {
+ HDCS_1020_DEF_WIDTH,
+ HDCS_1020_DEF_HEIGHT,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
+ .bytesperline = HDCS_1020_DEF_WIDTH,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1
+ }
+};
+
enum hdcs_power_state {
HDCS_STATE_SLEEP,
HDCS_STATE_IDLE,
@@ -353,10 +413,10 @@ static int hdcs_probe_1x00(struct sd *sd)
info("HDCS-1000/1100 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1x00.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1x00.nmodes;
- sd->desc.ctrls = stv06xx_sensor_hdcs1x00.ctrls;
- sd->desc.nctrls = stv06xx_sensor_hdcs1x00.nctrls;
+ sd->gspca_dev.cam.cam_mode = hdcs1x00_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode);
+ sd->desc.ctrls = hdcs1x00_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(hdcs1x00_ctrl);
hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
if (!hdcs)
@@ -412,10 +472,10 @@ static int hdcs_probe_1020(struct sd *sd)
info("HDCS-1020 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1020.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1020.nmodes;
- sd->desc.ctrls = stv06xx_sensor_hdcs1020.ctrls;
- sd->desc.nctrls = stv06xx_sensor_hdcs1020.nctrls;
+ sd->gspca_dev.cam.cam_mode = hdcs1020_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode);
+ sd->desc.ctrls = hdcs1020_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(hdcs1020_ctrl);
hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
if (!hdcs)
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
index 9c7279a4cd88..412f06cf3d5c 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
@@ -152,53 +152,6 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = {
.stop = hdcs_stop,
.disconnect = hdcs_disconnect,
.dump = hdcs_dump,
-
- .nctrls = 2,
- .ctrls = {
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0xffff,
- .step = 0x1,
- .default_value = HDCS_DEFAULT_EXPOSURE,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = hdcs_set_exposure,
- .get = hdcs_get_exposure
- },
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = HDCS_DEFAULT_GAIN,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = hdcs_set_gain,
- .get = hdcs_get_gain
- }
- },
-
- .nmodes = 1,
- .modes = {
- {
- HDCS_1X00_DEF_WIDTH,
- HDCS_1X00_DEF_HEIGHT,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
- .bytesperline = HDCS_1X00_DEF_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
- }
};
const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
@@ -207,29 +160,11 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
.i2c_addr = (0x55 << 1),
.i2c_len = 1,
- .nctrls = 0,
- .ctrls = {},
-
.init = hdcs_init,
.probe = hdcs_probe_1020,
.start = hdcs_start,
.stop = hdcs_stop,
.dump = hdcs_dump,
-
- .nmodes = 1,
- .modes = {
- {
- HDCS_1020_DEF_WIDTH,
- HDCS_1020_DEF_HEIGHT,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
- .bytesperline = HDCS_1020_DEF_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
- }
};
static const u16 stv_bridge_init[][2] = {
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
index d0a0f8596454..285221e6b390 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
@@ -46,6 +46,132 @@
#include "stv06xx_pb0100.h"
+static const struct ctrl pb0100_ctrl[] = {
+#define GAIN_IDX 0
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gain",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 128
+ },
+ .set = pb0100_set_gain,
+ .get = pb0100_get_gain
+ },
+#define RED_BALANCE_IDX 1
+ {
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Red Balance",
+ .minimum = -255,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = pb0100_set_red_balance,
+ .get = pb0100_get_red_balance
+ },
+#define BLUE_BALANCE_IDX 2
+ {
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Blue Balance",
+ .minimum = -255,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = pb0100_set_blue_balance,
+ .get = pb0100_get_blue_balance
+ },
+#define EXPOSURE_IDX 3
+ {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Exposure",
+ .minimum = 0,
+ .maximum = 511,
+ .step = 1,
+ .default_value = 12
+ },
+ .set = pb0100_set_exposure,
+ .get = pb0100_get_exposure
+ },
+#define AUTOGAIN_IDX 4
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Automatic Gain and Exposure",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1
+ },
+ .set = pb0100_set_autogain,
+ .get = pb0100_get_autogain
+ },
+#define AUTOGAIN_TARGET_IDX 5
+ {
+ {
+ .id = V4L2_CTRL_CLASS_USER + 0x1000,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Automatic Gain Target",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 128
+ },
+ .set = pb0100_set_autogain_target,
+ .get = pb0100_get_autogain_target
+ },
+#define NATURAL_IDX 6
+ {
+ {
+ .id = V4L2_CTRL_CLASS_USER + 0x1001,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Natural Light Source",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1
+ },
+ .set = pb0100_set_natural,
+ .get = pb0100_get_natural
+ }
+};
+
+static struct v4l2_pix_format pb0100_mode[] = {
+/* low res / subsample modes disabled as they are only half res horizontal,
+ halving the vertical resolution does not seem to work */
+ {
+ 320,
+ 240,
+ V4L2_PIX_FMT_SGRBG8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 320 * 240,
+ .bytesperline = 320,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = PB0100_CROP_TO_VGA
+ },
+ {
+ 352,
+ 288,
+ V4L2_PIX_FMT_SGRBG8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 352 * 288,
+ .bytesperline = 352,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
+ }
+};
+
static int pb0100_probe(struct sd *sd)
{
u16 sensor;
@@ -59,20 +185,19 @@ static int pb0100_probe(struct sd *sd)
if ((sensor >> 8) == 0x64) {
sensor_settings = kmalloc(
- stv06xx_sensor_pb0100.nctrls * sizeof(s32),
+ ARRAY_SIZE(pb0100_ctrl) * sizeof(s32),
GFP_KERNEL);
if (!sensor_settings)
return -ENOMEM;
info("Photobit pb0100 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_pb0100.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_pb0100.nmodes;
- sd->desc.ctrls = stv06xx_sensor_pb0100.ctrls;
- sd->desc.nctrls = stv06xx_sensor_pb0100.nctrls;
- for (i = 0; i < stv06xx_sensor_pb0100.nctrls; i++)
- sensor_settings[i] = stv06xx_sensor_pb0100.
- ctrls[i].qctrl.default_value;
+ sd->gspca_dev.cam.cam_mode = pb0100_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode);
+ sd->desc.ctrls = pb0100_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(pb0100_ctrl);
+ for (i = 0; i < sd->desc.nctrls; i++)
+ sensor_settings[i] = pb0100_ctrl[i].qctrl.default_value;
sd->sensor_priv = sensor_settings;
return 0;
@@ -143,6 +268,12 @@ out:
return (err < 0) ? err : 0;
}
+static void pb0100_disconnect(struct sd *sd)
+{
+ sd->sensor = NULL;
+ kfree(sd->sensor_priv);
+}
+
/* FIXME: Sort the init commands out and put them into tables,
this is only for getting the camera to work */
/* FIXME: No error handling for now,
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
index 5ea21a1154c4..4de4fa5ebc57 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
@@ -114,6 +114,7 @@ static int pb0100_start(struct sd *sd);
static int pb0100_init(struct sd *sd);
static int pb0100_stop(struct sd *sd);
static int pb0100_dump(struct sd *sd);
+static void pb0100_disconnect(struct sd *sd);
/* V4L2 controls supported by the driver */
static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
@@ -137,139 +138,12 @@ const struct stv06xx_sensor stv06xx_sensor_pb0100 = {
.i2c_addr = 0xba,
.i2c_len = 2,
- .nctrls = 7,
- .ctrls = {
-#define GAIN_IDX 0
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 128
- },
- .set = pb0100_set_gain,
- .get = pb0100_get_gain
- },
-#define RED_BALANCE_IDX 1
- {
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Red Balance",
- .minimum = -255,
- .maximum = 255,
- .step = 1,
- .default_value = 0
- },
- .set = pb0100_set_red_balance,
- .get = pb0100_get_red_balance
- },
-#define BLUE_BALANCE_IDX 2
- {
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Blue Balance",
- .minimum = -255,
- .maximum = 255,
- .step = 1,
- .default_value = 0
- },
- .set = pb0100_set_blue_balance,
- .get = pb0100_get_blue_balance
- },
-#define EXPOSURE_IDX 3
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Exposure",
- .minimum = 0,
- .maximum = 511,
- .step = 1,
- .default_value = 12
- },
- .set = pb0100_set_exposure,
- .get = pb0100_get_exposure
- },
-#define AUTOGAIN_IDX 4
- {
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Automatic Gain and Exposure",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = pb0100_set_autogain,
- .get = pb0100_get_autogain
- },
-#define AUTOGAIN_TARGET_IDX 5
- {
- {
- .id = V4L2_CTRL_CLASS_USER + 0x1000,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Automatic Gain Target",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 128
- },
- .set = pb0100_set_autogain_target,
- .get = pb0100_get_autogain_target
- },
-#define NATURAL_IDX 6
- {
- {
- .id = V4L2_CTRL_CLASS_USER + 0x1001,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Natural Light Source",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = pb0100_set_natural,
- .get = pb0100_get_natural
- },
- },
-
.init = pb0100_init,
.probe = pb0100_probe,
.start = pb0100_start,
.stop = pb0100_stop,
.dump = pb0100_dump,
-
- .nmodes = 2,
- .modes = {
-/* low res / subsample modes disabled as they are only half res horizontal,
- halving the vertical resolution does not seem to work */
- {
- 320,
- 240,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage = 320 * 240,
- .bytesperline = 320,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = PB0100_CROP_TO_VGA
- },
- {
- 352,
- 288,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage = 352 * 288,
- .bytesperline = 352,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- },
- }
+ .disconnect = pb0100_disconnect,
};
#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
index c726dacefa1f..e88c42f7d2f8 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
@@ -41,8 +41,6 @@ extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00;
extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020;
extern const struct stv06xx_sensor stv06xx_sensor_pb0100;
-#define STV06XX_MAX_CTRLS (V4L2_CID_LASTP1 - V4L2_CID_BASE + 10)
-
struct stv06xx_sensor {
/* Defines the name of a sensor */
char name[32];
@@ -81,12 +79,6 @@ struct stv06xx_sensor {
/* Instructs the sensor to dump all its contents */
int (*dump)(struct sd *sd);
-
- int nctrls;
- struct ctrl ctrls[STV06XX_MAX_CTRLS];
-
- char nmodes;
- struct v4l2_pix_format modes[];
};
#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
index 1ca91f2a6dee..69c77c932fc0 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
@@ -29,26 +29,92 @@
#include "stv06xx_vv6410.h"
+static struct v4l2_pix_format vv6410_mode[] = {
+ {
+ 356,
+ 292,
+ V4L2_PIX_FMT_SGRBG8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 356 * 292,
+ .bytesperline = 356,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
+ }
+};
+
+static const struct ctrl vv6410_ctrl[] = {
+#define HFLIP_IDX 0
+ {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = vv6410_set_hflip,
+ .get = vv6410_get_hflip
+ },
+#define VFLIP_IDX 1
+ {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = vv6410_set_vflip,
+ .get = vv6410_get_vflip
+ },
+#define GAIN_IDX 2
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "analog gain",
+ .minimum = 0,
+ .maximum = 15,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = vv6410_set_analog_gain,
+ .get = vv6410_get_analog_gain
+ }
+};
+
static int vv6410_probe(struct sd *sd)
{
u16 data;
- int err;
+ int err, i;
+ s32 *sensor_settings;
err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data);
-
if (err < 0)
return -ENODEV;
if (data == 0x19) {
info("vv6410 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_vv6410.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_vv6410.nmodes;
- sd->desc.ctrls = stv06xx_sensor_vv6410.ctrls;
- sd->desc.nctrls = stv06xx_sensor_vv6410.nctrls;
+ sensor_settings = kmalloc(ARRAY_SIZE(vv6410_ctrl) * sizeof(s32),
+ GFP_KERNEL);
+ if (!sensor_settings)
+ return -ENOMEM;
+
+ sd->gspca_dev.cam.cam_mode = vv6410_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode);
+ sd->desc.ctrls = vv6410_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(vv6410_ctrl);
+
+ for (i = 0; i < sd->desc.nctrls; i++)
+ sensor_settings[i] = vv6410_ctrl[i].qctrl.default_value;
+ sd->sensor_priv = sensor_settings;
return 0;
}
-
return -ENODEV;
}
@@ -80,6 +146,12 @@ static int vv6410_init(struct sd *sd)
return (err < 0) ? err : 0;
}
+static void vv6410_disconnect(struct sd *sd)
+{
+ sd->sensor = NULL;
+ kfree(sd->sensor_priv);
+}
+
static int vv6410_start(struct sd *sd)
{
int err;
@@ -156,17 +228,13 @@ static int vv6410_dump(struct sd *sd)
static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
-
- *val = (i2c_data & VV6410_HFLIP) ? 1 : 0;
-
+ *val = sensor_settings[HFLIP_IDX];
PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
- return (err < 0) ? err : 0;
+ return 0;
}
static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -174,6 +242,9 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
int err;
u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ sensor_settings[HFLIP_IDX] = val;
err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
if (err < 0)
return err;
@@ -191,17 +262,13 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
-
- *val = (i2c_data & VV6410_VFLIP) ? 1 : 0;
-
+ *val = sensor_settings[VFLIP_IDX];
PDEBUG(D_V4L2, "Read vertical flip %d", *val);
- return (err < 0) ? err : 0;
+ return 0;
}
static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -209,6 +276,9 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
int err;
u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ sensor_settings[VFLIP_IDX] = val;
err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
if (err < 0)
return err;
@@ -226,24 +296,23 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = stv06xx_read_sensor(sd, VV6410_ANALOGGAIN, &i2c_data);
-
- *val = i2c_data & 0xf;
+ *val = sensor_settings[GAIN_IDX];
PDEBUG(D_V4L2, "Read analog gain %d", *val);
- return (err < 0) ? err : 0;
+ return 0;
}
static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+ sensor_settings[GAIN_IDX] = val;
PDEBUG(D_V4L2, "Set analog gain to %d", val);
err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf));
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
index 3ff8c4ea3362..95ac55891bd4 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -178,6 +178,7 @@ static int vv6410_start(struct sd *sd);
static int vv6410_init(struct sd *sd);
static int vv6410_stop(struct sd *sd);
static int vv6410_dump(struct sd *sd);
+static void vv6410_disconnect(struct sd *sd);
/* V4L2 controls supported by the driver */
static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -197,62 +198,7 @@ const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
.start = vv6410_start,
.stop = vv6410_stop,
.dump = vv6410_dump,
-
- .nctrls = 3,
- .ctrls = {
- {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = vv6410_set_hflip,
- .get = vv6410_get_hflip
- }, {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = vv6410_set_vflip,
- .get = vv6410_get_vflip
- }, {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "analog gain",
- .minimum = 0,
- .maximum = 15,
- .step = 1,
- .default_value = 0
- },
- .set = vv6410_set_analog_gain,
- .get = vv6410_get_analog_gain
- }
- },
-
- .nmodes = 1,
- .modes = {
- {
- 356,
- 292,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 356 * 292,
- .bytesperline = 356,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- }
- }
+ .disconnect = vv6410_disconnect,
};
/* If NULL, only single value to write, stored in len */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 6d904d5e4c74..c2b8c10c075a 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -39,8 +39,11 @@ struct sd {
unsigned char contrast;
unsigned char colors;
unsigned char autogain;
+ u8 quality;
+#define QUALITY_MIN 70
+#define QUALITY_MAX 95
+#define QUALITY_DEF 85
- char qindex;
char bridge;
#define BRIDGE_SPCA504 0
#define BRIDGE_SPCA504B 1
@@ -52,6 +55,8 @@ struct sd {
#define LogitechClickSmart420 2
#define LogitechClickSmart820 3
#define MegapixV4 4
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -812,7 +817,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
sd->bridge = id->driver_info >> 8;
sd->subtype = id->driver_info;
@@ -850,10 +854,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];
break;
}
- sd->qindex = 5; /* set the quantization table */
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+ sd->quality = QUALITY_DEF;
return 0;
}
@@ -970,6 +974,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
__u8 i;
__u8 info[6];
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x22); /* JPEG 411 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
if (sd->bridge == BRIDGE_SPCA504B)
spca504B_setQtable(gspca_dev);
spca504B_SetSizeType(gspca_dev);
@@ -1079,6 +1089,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
}
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
@@ -1155,9 +1172,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
ffd9, 2);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame,
- ((struct sd *) gspca_dev)->qindex,
- 0x22);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
}
/* add 0x00 after 0xff */
@@ -1198,26 +1214,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
}
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u16 brightness = 0;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2);
- break;
- case BRIDGE_SPCA536:
- brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2);
- break;
- }
- sd->brightness = ((brightness & 0xff) - 128) % 255;
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1237,24 +1233,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
}
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2);
- break;
- case BRIDGE_SPCA536:
- sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2);
- break;
- }
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1274,24 +1252,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
}
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1;
- break;
- case BRIDGE_SPCA536:
- sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1;
- break;
- }
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1306,7 +1266,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -1325,7 +1284,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -1344,7 +1302,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -1365,6 +1322,34 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -1374,7 +1359,10 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -1465,8 +1453,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 6ee111a3cbd1..f63e37e2e4fd 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -37,20 +37,21 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- unsigned char brightness;
- unsigned char contrast;
- unsigned char colors;
- unsigned char autogain;
- unsigned char gamma;
- unsigned char sharpness;
- unsigned char freq;
- unsigned char whitebalance;
- unsigned char mirror;
- unsigned char effect;
-
- __u8 sensor;
-#define SENSOR_TAS5130A 0
-#define SENSOR_OM6802 1
+ u8 brightness;
+ u8 contrast;
+ u8 colors;
+ u8 autogain;
+ u8 gamma;
+ u8 sharpness;
+ u8 freq;
+ u8 whitebalance;
+ u8 mirror;
+ u8 effect;
+
+ u8 sensor;
+#define SENSOR_OM6802 0
+#define SENSOR_OTHER 1
+#define SENSOR_TAS5130A 2
};
/* V4L2 controls supported by the driver */
@@ -78,7 +79,6 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
struct v4l2_querymenu *menu);
static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
{
{
.id = V4L2_CID_BRIGHTNESS,
@@ -87,12 +87,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 14,
.step = 1,
- .default_value = 8,
+#define BRIGHTNESS_DEF 8
+ .default_value = BRIGHTNESS_DEF,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
},
-#define SD_CONTRAST 1
{
{
.id = V4L2_CID_CONTRAST,
@@ -101,12 +101,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 0x0d,
.step = 1,
- .default_value = 0x07,
+#define CONTRAST_DEF 0x07
+ .default_value = CONTRAST_DEF,
},
.set = sd_setcontrast,
.get = sd_getcontrast,
},
-#define SD_COLOR 2
{
{
.id = V4L2_CID_SATURATION,
@@ -115,7 +115,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 0x0f,
.step = 1,
- .default_value = 0x05,
+#define COLORS_DEF 0x05
+ .default_value = COLORS_DEF,
},
.set = sd_setcolors,
.get = sd_getcolors,
@@ -135,7 +136,6 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setgamma,
.get = sd_getgamma,
},
-#define SD_AUTOGAIN 4
{
{
.id = V4L2_CID_GAIN, /* here, i activate only the lowlight,
@@ -146,12 +146,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 0x01,
+#define AUTOGAIN_DEF 0x01
+ .default_value = AUTOGAIN_DEF,
},
.set = sd_setlowlight,
.get = sd_getlowlight,
},
-#define SD_MIRROR 5
{
{
.id = V4L2_CID_HFLIP,
@@ -160,12 +160,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 0,
+#define MIRROR_DEF 0
+ .default_value = MIRROR_DEF,
},
.set = sd_setflip,
.get = sd_getflip
},
-#define SD_LIGHTFREQ 6
{
{
.id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -174,12 +174,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 1, /* 1 -> 0x50, 2->0x60 */
.maximum = 2,
.step = 1,
- .default_value = 1,
+#define FREQ_DEF 1
+ .default_value = FREQ_DEF,
},
.set = sd_setfreq,
.get = sd_getfreq},
-#define SD_WHITE_BALANCE 7
{
{
.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
@@ -188,12 +188,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 0,
+#define WHITE_BALANCE_DEF 0
+ .default_value = WHITE_BALANCE_DEF,
},
.set = sd_setwhitebalance,
.get = sd_getwhitebalance
},
-#define SD_SHARPNESS 8 /* (aka definition on win) */
{
{
.id = V4L2_CID_SHARPNESS,
@@ -202,12 +202,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 15,
.step = 1,
- .default_value = 0x06,
+#define SHARPNESS_DEF 0x06
+ .default_value = SHARPNESS_DEF,
},
.set = sd_setsharpness,
.get = sd_getsharpness,
},
-#define SD_EFFECTS 9
{
{
.id = V4L2_CID_EFFECTS,
@@ -216,7 +216,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 4,
.step = 1,
- .default_value = 0,
+#define EFFECTS_DEF 0
+ .default_value = EFFECTS_DEF,
},
.set = sd_seteffect,
.get = sd_geteffect
@@ -263,28 +264,50 @@ static const struct v4l2_pix_format vga_mode_t16[] = {
/* sensor specific data */
struct additional_sensor_data {
- const __u8 data1[20];
- const __u8 data2[18];
- const __u8 data3[18];
- const __u8 data4[4];
- const __u8 data5[6];
- const __u8 stream[4];
+ const u8 data1[10];
+ const u8 data2[9];
+ const u8 data3[9];
+ const u8 data4[4];
+ const u8 data5[6];
+ const u8 stream[4];
};
-const static struct additional_sensor_data sensor_data[] = {
+static const struct additional_sensor_data sensor_data[] = {
+ { /* OM6802 */
+ .data1 =
+ {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
+ 0xb3, 0xfc},
+ .data2 =
+ {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
+ 0xff},
+ .data4 = /*Freq (50/60Hz). Splitted for test purpose */
+ {0x66, 0xca, 0xa8, 0xf0},
+ .data5 = /* this could be removed later */
+ {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
+ .stream =
+ {0x0b, 0x04, 0x0a, 0x78},
+ },
+ { /* OTHER */
+ .data1 =
+ {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
+ 0xe8, 0xfc},
+ .data2 =
+ {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
+ 0xd9},
+ .data4 =
+ {0x66, 0x00, 0xa8, 0xa8},
+ .data5 =
+ {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
+ .stream =
+ {0x0b, 0x04, 0x0a, 0x00},
+ },
{ /* TAS5130A */
.data1 =
- {0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10,
- 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
- 0xd8, 0xc8, 0xd9, 0xfc},
+ {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
+ 0xc8, 0xfc},
.data2 =
- {0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60,
- 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
- 0xe8, 0xe0},
- .data3 =
- {0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60,
- 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
- 0xcf, 0xe0},
+ {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
+ 0xe0},
.data4 = /* Freq (50/60Hz). Splitted for test purpose */
{0x66, 0x00, 0xa8, 0xe8},
.data5 =
@@ -292,32 +315,12 @@ const static struct additional_sensor_data sensor_data[] = {
.stream =
{0x0b, 0x04, 0x0a, 0x40},
},
- { /* OM6802 */
- .data1 =
- {0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22,
- 0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06,
- 0xd8, 0xb3, 0xd9, 0xfc},
- .data2 =
- {0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80,
- 0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff,
- 0xe8, 0xff},
- .data3 =
- {0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80,
- 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff,
- 0xcf, 0xff},
- .data4 = /*Freq (50/60Hz). Splitted for test purpose */
- {0x66, 0xca, 0xa8, 0xf0 },
- .data5 = /* this could be removed later */
- {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
- .stream =
- {0x0b, 0x04, 0x0a, 0x78},
- }
};
#define MAX_EFFECTS 7
/* easily done by soft, this table could be removed,
* i keep it here just in case */
-static const __u8 effects_table[MAX_EFFECTS][6] = {
+static const u8 effects_table[MAX_EFFECTS][6] = {
{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
@@ -327,90 +330,58 @@ static const __u8 effects_table[MAX_EFFECTS][6] = {
{0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
};
-static const __u8 gamma_table[GAMMA_MAX][34] = {
- {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, /* 0 */
- 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
- 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
- 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75, /* 1 */
- 0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad,
- 0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4,
- 0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b, /* 2 */
- 0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6,
- 0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0,
- 0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, /* 3 */
- 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e,
- 0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb,
- 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55, /* 4 */
- 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
- 0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6,
- 0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48, /* 5 */
- 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
- 0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe,
- 0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, /* 6 */
- 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
- 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
- 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, /* 7 */
- 0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70,
- 0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0,
- 0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, /* 8 */
- 0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79,
- 0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6,
- 0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, /* 9 */
- 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
- 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
- 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44, /* 10 */
- 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e,
- 0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4,
- 0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52, /* 11 */
- 0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B,
- 0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb,
- 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e, /* 12 */
- 0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8,
- 0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3,
- 0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83, /* 13 */
- 0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7,
- 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc,
- 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a, /* 14 */
- 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6,
- 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3,
- 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7, /* 15 */
- 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8,
- 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed,
- 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc,
- 0xa0, 0xff}
+static const u8 gamma_table[GAMMA_MAX][17] = {
+ {0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9, /* 0 */
+ 0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8,
+ 0xff},
+ {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad, /* 1 */
+ 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7,
+ 0xff},
+ {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6, /* 2 */
+ 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6,
+ 0xff},
+ {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e, /* 3 */
+ 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
+ 0xff},
+ {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95, /* 4 */
+ 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4,
+ 0xff},
+ {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87, /* 5 */
+ 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3,
+ 0xff},
+ {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67, /* 6 */
+ 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
+ 0xff},
+ {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70, /* 7 */
+ 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
+ 0xff},
+ {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79, /* 8 */
+ 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0,
+ 0xff},
+ {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84, /* 9 */
+ 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0,
+ 0xff},
+ {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */
+ 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
+ 0xff},
+ {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8D, 0x9B, /* 11 */
+ 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
+ 0xff},
+ {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
+ 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
+ 0xff},
+ {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */
+ 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
+ 0xff},
+ {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */
+ 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
+ 0xff},
+ {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */
+ 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
+ 0xff}
};
-static const __u8 tas5130a_sensor_init[][8] = {
+static const u8 tas5130a_sensor_init[][8] = {
{0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
{0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
@@ -418,11 +389,11 @@ static const __u8 tas5130a_sensor_init[][8] = {
{},
};
-static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
+static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
/* read 1 byte */
-static int reg_r(struct gspca_dev *gspca_dev,
- __u16 index)
+static u8 reg_r(struct gspca_dev *gspca_dev,
+ u16 index)
{
usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -435,7 +406,7 @@ static int reg_r(struct gspca_dev *gspca_dev,
}
static void reg_w(struct gspca_dev *gspca_dev,
- __u16 index)
+ u16 index)
{
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -446,7 +417,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
}
static void reg_w_buf(struct gspca_dev *gspca_dev,
- const __u8 *buffer, __u16 len)
+ const u8 *buffer, u16 len)
{
if (len <= USB_BUF_SZ) {
memcpy(gspca_dev->usb_buf, buffer, len);
@@ -457,7 +428,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
0x01, 0,
gspca_dev->usb_buf, len, 500);
} else {
- __u8 *tmpbuf;
+ u8 *tmpbuf;
tmpbuf = kmalloc(len, GFP_KERNEL);
memcpy(tmpbuf, buffer, len);
@@ -471,14 +442,41 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
}
}
+/* write values to consecutive registers */
+static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
+ u8 reg,
+ const u8 *buffer, u16 len)
+{
+ int i;
+ u8 *p, *tmpbuf;
+
+ if (len * 2 <= USB_BUF_SZ)
+ p = tmpbuf = gspca_dev->usb_buf;
+ else
+ p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
+ i = len;
+ while (--i >= 0) {
+ *p++ = reg++;
+ *p++ = *buffer++;
+ }
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x01, 0,
+ tmpbuf, len * 2, 500);
+ if (len * 2 > USB_BUF_SZ)
+ kfree(tmpbuf);
+}
+
/* Reported as OM6802*/
static void om6802_sensor_init(struct gspca_dev *gspca_dev)
{
int i;
- const __u8 *p;
- __u8 byte;
- __u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
- static const __u8 sensor_init[] = {
+ const u8 *p;
+ u8 byte;
+ u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
+ static const u8 sensor_init[] = {
0xdf, 0x6d,
0xdd, 0x18,
0x5a, 0xe0,
@@ -497,7 +495,7 @@ static void om6802_sensor_init(struct gspca_dev *gspca_dev)
};
reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
- msleep(5);
+ msleep(100);
i = 4;
while (--i > 0) {
byte = reg_r(gspca_dev, 0x0060);
@@ -538,20 +536,20 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode_t16;
cam->nmodes = ARRAY_SIZE(vga_mode_t16);
- sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
- sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
- sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->contrast = CONTRAST_DEF;
+ sd->colors = COLORS_DEF;
sd->gamma = GAMMA_DEF;
- sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
- sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
- sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
- sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
- sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
+ sd->autogain = AUTOGAIN_DEF;
+ sd->mirror = MIRROR_DEF;
+ sd->freq = FREQ_DEF;
+ sd->whitebalance = WHITE_BALANCE_DEF;
+ sd->sharpness = SHARPNESS_DEF;
+ sd->effect = EFFECTS_DEF;
return 0;
}
@@ -559,7 +557,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
unsigned int brightness;
- __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
+ u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
brightness = sd->brightness;
if (brightness < 7) {
@@ -576,7 +574,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
unsigned int contrast = sd->contrast;
- __u16 reg_to_write;
+ u16 reg_to_write;
if (contrast < 7)
reg_to_write = 0x8ea9 - contrast * 0x200;
@@ -589,7 +587,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u16 reg_to_write;
+ u16 reg_to_write;
reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */
reg_w(gspca_dev, reg_to_write);
@@ -600,14 +598,15 @@ static void setgamma(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
- reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
+ reg_w_ixbuf(gspca_dev, 0x90,
+ gamma_table[sd->gamma], sizeof gamma_table[0]);
}
static void setwhitebalance(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 white_balance[8] =
+ u8 white_balance[8] =
{0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
if (sd->whitebalance)
@@ -619,7 +618,7 @@ static void setwhitebalance(struct gspca_dev *gspca_dev)
static void setsharpness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u16 reg_to_write;
+ u16 reg_to_write;
reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
@@ -635,18 +634,22 @@ static int sd_init(struct gspca_dev *gspca_dev)
* to see the initial parameters.*/
struct sd *sd = (struct sd *) gspca_dev;
int i;
- __u8 byte, test_byte;
-
- static const __u8 read_indexs[] =
- { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
- 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
- static const __u8 n1[] =
+ u16 sensor_id;
+ u8 test_byte = 0;
+ u16 reg80, reg8e;
+
+ static const u8 read_indexs[] =
+ { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
+ 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
+ static const u8 n1[] =
{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
- static const __u8 n2[] =
+ static const u8 n2[] =
{0x08, 0x00};
- static const __u8 n3[] =
+ static const u8 n3[6] =
{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
- static const __u8 n4[] =
+ static const u8 n3_other[6] =
+ {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00};
+ static const u8 n4[] =
{0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
@@ -656,40 +659,61 @@ static int sd_init(struct gspca_dev *gspca_dev)
0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
- static const __u8 nset9[4] =
- { 0x0b, 0x04, 0x0a, 0x78 };
- static const __u8 nset8[6] =
+ static const u8 n4_other[] =
+ {0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
+ 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
+ 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
+ 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
+ 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
+ 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
+ 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
+ 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00};
+ static const u8 nset8[6] =
{ 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
-
- byte = reg_r(gspca_dev, 0x06);
- test_byte = reg_r(gspca_dev, 0x07);
- if (byte == 0x08 && test_byte == 0x07) {
- PDEBUG(D_CONF, "sensor om6802");
- sd->sensor = SENSOR_OM6802;
- } else if (byte == 0x08 && test_byte == 0x01) {
- PDEBUG(D_CONF, "sensor tas5130a");
- sd->sensor = SENSOR_TAS5130A;
- } else {
- PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
+ static const u8 nset8_other[6] =
+ { 0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00 };
+ static const u8 nset9[4] =
+ { 0x0b, 0x04, 0x0a, 0x78 };
+ static const u8 nset9_other[4] =
+ { 0x0b, 0x04, 0x0a, 0x00 };
+
+ sensor_id = (reg_r(gspca_dev, 0x06) << 8)
+ | reg_r(gspca_dev, 0x07);
+ switch (sensor_id & 0xff0f) {
+ case 0x0801:
+ PDEBUG(D_PROBE, "sensor tas5130a");
sd->sensor = SENSOR_TAS5130A;
+ break;
+ case 0x0803:
+ PDEBUG(D_PROBE, "sensor 'other'");
+ sd->sensor = SENSOR_OTHER;
+ break;
+ case 0x0807:
+ PDEBUG(D_PROBE, "sensor om6802");
+ sd->sensor = SENSOR_OM6802;
+ break;
+ default:
+ PDEBUG(D_ERR|D_PROBE, "unknown sensor %04x", sensor_id);
+ return -EINVAL;
}
- reg_w_buf(gspca_dev, n1, sizeof n1);
- test_byte = 0;
- i = 5;
- while (--i >= 0) {
- reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
- test_byte = reg_r(gspca_dev, 0x0063);
- msleep(100);
- if (test_byte == 0x17)
- break; /* OK */
- }
- if (i < 0) {
- err("Bad sensor reset %02x", test_byte);
-/* return -EIO; */
+ if (sd->sensor != SENSOR_OTHER) {
+ reg_w_buf(gspca_dev, n1, sizeof n1);
+ i = 5;
+ while (--i >= 0) {
+ reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
+ test_byte = reg_r(gspca_dev, 0x0063);
+ msleep(100);
+ if (test_byte == 0x17)
+ break; /* OK */
+ }
+ if (i < 0) {
+ err("Bad sensor reset %02x", test_byte);
+/* return -EIO; */
/*fixme: test - continue */
+ }
+ reg_w_buf(gspca_dev, n2, sizeof n2);
}
- reg_w_buf(gspca_dev, n2, sizeof n2);
i = 0;
while (read_indexs[i] != 0x00) {
@@ -699,21 +723,31 @@ static int sd_init(struct gspca_dev *gspca_dev)
i++;
}
- reg_w_buf(gspca_dev, n3, sizeof n3);
- reg_w_buf(gspca_dev, n4, sizeof n4);
- reg_r(gspca_dev, 0x0080);
- reg_w(gspca_dev, 0x2c80);
+ if (sd->sensor != SENSOR_OTHER) {
+ reg_w_buf(gspca_dev, n3, sizeof n3);
+ reg_w_buf(gspca_dev, n4, sizeof n4);
+ reg_r(gspca_dev, 0x0080);
+ reg_w(gspca_dev, 0x2c80);
+ reg80 = 0x3880;
+ reg8e = 0x338e;
+ } else {
+ reg_w_buf(gspca_dev, n3_other, sizeof n3_other);
+ reg_w_buf(gspca_dev, n4_other, sizeof n4_other);
+ sd->gamma = 5;
+ reg80 = 0xac80;
+ reg8e = 0xb88e;
+ }
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+ reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
sizeof sensor_data[sd->sensor].data1);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
- sizeof sensor_data[sd->sensor].data3);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+ reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
+ sizeof sensor_data[sd->sensor].data2);
+ reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
sizeof sensor_data[sd->sensor].data2);
- reg_w(gspca_dev, 0x3880);
- reg_w(gspca_dev, 0x3880);
- reg_w(gspca_dev, 0x338e);
+ reg_w(gspca_dev, reg80);
+ reg_w(gspca_dev, reg80);
+ reg_w(gspca_dev, reg8e);
setbrightness(gspca_dev);
setcontrast(gspca_dev);
@@ -730,16 +764,20 @@ static int sd_init(struct gspca_dev *gspca_dev)
sizeof sensor_data[sd->sensor].data4);
reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
sizeof sensor_data[sd->sensor].data5);
- reg_w_buf(gspca_dev, nset8, sizeof nset8);
- reg_w_buf(gspca_dev, nset9, sizeof nset9);
-
- reg_w(gspca_dev, 0x2880);
+ if (sd->sensor != SENSOR_OTHER) {
+ reg_w_buf(gspca_dev, nset8, sizeof nset8);
+ reg_w_buf(gspca_dev, nset9, sizeof nset9);
+ reg_w(gspca_dev, 0x2880);
+ } else {
+ reg_w_buf(gspca_dev, nset8_other, sizeof nset8_other);
+ reg_w_buf(gspca_dev, nset9_other, sizeof nset9_other);
+ }
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+ reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
sizeof sensor_data[sd->sensor].data1);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
- sizeof sensor_data[sd->sensor].data3);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+ reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
+ sizeof sensor_data[sd->sensor].data2);
+ reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
sizeof sensor_data[sd->sensor].data2);
return 0;
@@ -748,7 +786,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
static void setflip(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 flipcmd[8] =
+ u8 flipcmd[8] =
{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
if (sd->mirror)
@@ -778,7 +816,7 @@ static void seteffect(struct gspca_dev *gspca_dev)
static void setlightfreq(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
+ u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
if (sd->freq == 2) /* 60hz */
freq[1] = 0x00;
@@ -791,22 +829,22 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
static void poll_sensor(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- static const __u8 poll1[] =
+ static const u8 poll1[] =
{0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
0x60, 0x14};
- static const __u8 poll2[] =
+ static const u8 poll2[] =
{0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
- static const __u8 poll3[] =
+ static const u8 poll3[] =
{0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
- static const __u8 poll4[] =
+ static const u8 poll4[] =
{0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
0xc2, 0x80, 0xc3, 0x10};
- if (sd->sensor != SENSOR_TAS5130A) {
+ if (sd->sensor == SENSOR_OM6802) {
PDEBUG(D_STREAM, "[Sensor requires polling]");
reg_w_buf(gspca_dev, poll1, sizeof poll1);
reg_w_buf(gspca_dev, poll2, sizeof poll2);
@@ -819,13 +857,14 @@ static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i, mode;
- __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
- static const __u8 t3[] =
- { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
- 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
+ u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
+ static const u8 t3[] =
+ { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
switch (mode) {
+ case 0: /* 640x480 (0x00) */
+ break;
case 1: /* 352x288 */
t2[1] = 0x40;
break;
@@ -835,14 +874,20 @@ static int sd_start(struct gspca_dev *gspca_dev)
case 3: /* 176x144 */
t2[1] = 0x50;
break;
- case 4: /* 160x120 */
+ default:
+/* case 4: * 160x120 */
t2[1] = 0x20;
break;
- default: /* 640x480 (0x00) */
- break;
}
- if (sd->sensor == SENSOR_TAS5130A) {
+ switch (sd->sensor) {
+ case SENSOR_OM6802:
+ om6802_sensor_init(gspca_dev);
+ break;
+ case SENSOR_OTHER:
+ break;
+ default:
+/* case SENSOR_TAS5130A: */
i = 0;
while (tas5130a_sensor_init[i][0] != 0) {
reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
@@ -854,14 +899,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
sizeof tas5130a_sensor_init[0]);
reg_w(gspca_dev, 0x3c80);
- } else {
- om6802_sensor_init(gspca_dev);
+ break;
}
reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
sizeof sensor_data[sd->sensor].data4);
reg_r(gspca_dev, 0x0012);
reg_w_buf(gspca_dev, t2, sizeof t2);
- reg_w_buf(gspca_dev, t3, sizeof t3);
+ reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
reg_w(gspca_dev, 0x0013);
msleep(15);
reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
@@ -885,16 +929,18 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
msleep(20);
reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
sizeof sensor_data[sd->sensor].stream);
- msleep(20);
- reg_w(gspca_dev, 0x0309);
+ if (sd->sensor != SENSOR_OTHER) {
+ msleep(20);
+ reg_w(gspca_dev, 0x0309);
+ }
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
- __u8 *data, /* isoc packet */
+ u8 *data, /* isoc packet */
int len) /* iso packet length */
{
- static __u8 ffd9[] = { 0xff, 0xd9 };
+ static u8 ffd9[] = { 0xff, 0xd9 };
if (data[0] == 0x5a) {
/* Control Packet, after this came the header again,
@@ -1172,8 +1218,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 94163cceb28a..9f243d7e3110 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -31,7 +31,6 @@ struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
__u16 brightness;
- __u16 contrast;
__u8 packet;
};
@@ -39,38 +38,22 @@ struct sd {
/* V4L2 controls supported by the driver */
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
{
{
.id = V4L2_CID_BRIGHTNESS,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Brightness",
.minimum = 1,
- .maximum = 0x2ff,
+ .maximum = 0x15f, /* = 352 - 1 */
.step = 1,
- .default_value = 0x18f,
+#define BRIGHTNESS_DEF 0x14c
+ .default_value = BRIGHTNESS_DEF,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
},
-#define SD_CONTRAST 1
- {
- {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 0xffff,
- .step = 1,
- .default_value = 0x7fff,
- },
- .set = sd_setcontrast,
- .get = sd_getcontrast,
- },
};
static const struct v4l2_pix_format sif_mode[] = {
@@ -86,78 +69,64 @@ static const struct v4l2_pix_format sif_mode[] = {
.priv = 0},
};
-/*
- * Initialization data: this is the first set-up data written to the
- * device (before the open data).
- */
-#define TESTCLK 0x10 /* reg 0x2c -> 0x12 //10 */
-#define TESTCOMP 0x90 /* reg 0x28 -> 0x80 */
-#define TESTLINE 0x81 /* reg 0x29 -> 0x81 */
-#define QCIFLINE 0x41 /* reg 0x29 -> 0x81 */
-#define TESTPTL 0x14 /* reg 0x2D -> 0x14 */
-#define TESTPTH 0x01 /* reg 0x2E -> 0x01 */
-#define TESTPTBL 0x12 /* reg 0x2F -> 0x0a */
-#define TESTPTBH 0x01 /* reg 0x30 -> 0x01 */
-#define ADWIDTHL 0xe8 /* reg 0x0c -> 0xe8 */
-#define ADWIDTHH 0x03 /* reg 0x0d -> 0x03 */
-#define ADHEIGHL 0x90 /* reg 0x0e -> 0x91 //93 */
-#define ADHEIGHH 0x01 /* reg 0x0f -> 0x01 */
-#define EXPOL 0x8f /* reg 0x1c -> 0x8f */
-#define EXPOH 0x01 /* reg 0x1d -> 0x01 */
-#define ADCBEGINL 0x44 /* reg 0x10 -> 0x46 //47 */
-#define ADCBEGINH 0x00 /* reg 0x11 -> 0x00 */
-#define ADRBEGINL 0x0a /* reg 0x14 -> 0x0b //0x0c */
-#define ADRBEGINH 0x00 /* reg 0x15 -> 0x00 */
-#define TV8532_CMD_UPDATE 0x84
-
-#define TV8532_EEprom_Add 0x03
-#define TV8532_EEprom_DataL 0x04
-#define TV8532_EEprom_DataM 0x05
-#define TV8532_EEprom_DataH 0x06
-#define TV8532_EEprom_TableLength 0x07
-#define TV8532_EEprom_Write 0x08
-#define TV8532_PART_CTRL 0x00
-#define TV8532_CTRL 0x01
-#define TV8532_CMD_EEprom_Open 0x30
-#define TV8532_CMD_EEprom_Close 0x29
-#define TV8532_UDP_UPDATE 0x31
-#define TV8532_GPIO 0x39
-#define TV8532_GPIO_OE 0x3B
-#define TV8532_REQ_RegWrite 0x02
-#define TV8532_REQ_RegRead 0x03
-
-#define TV8532_ADWIDTH_L 0x0C
-#define TV8532_ADWIDTH_H 0x0D
-#define TV8532_ADHEIGHT_L 0x0E
-#define TV8532_ADHEIGHT_H 0x0F
-#define TV8532_EXPOSURE 0x1C
-#define TV8532_QUANT_COMP 0x28
-#define TV8532_MODE_PACKET 0x29
-#define TV8532_SETCLK 0x2C
-#define TV8532_POINT_L 0x2D
-#define TV8532_POINT_H 0x2E
-#define TV8532_POINTB_L 0x2F
-#define TV8532_POINTB_H 0x30
-#define TV8532_BUDGET_L 0x2A
-#define TV8532_BUDGET_H 0x2B
-#define TV8532_VID_L 0x34
-#define TV8532_VID_H 0x35
-#define TV8532_PID_L 0x36
-#define TV8532_PID_H 0x37
-#define TV8532_DeviceID 0x83
-#define TV8532_AD_SLOPE 0x91
-#define TV8532_AD_BITCTRL 0x94
-#define TV8532_AD_COLBEGIN_L 0x10
-#define TV8532_AD_COLBEGIN_H 0x11
-#define TV8532_AD_ROWBEGIN_L 0x14
-#define TV8532_AD_ROWBEGIN_H 0x15
-
-static const __u32 tv_8532_eeprom_data[] = {
-/* add dataL dataM dataH */
- 0x00010001, 0x01018011, 0x02050014, 0x0305001c,
- 0x040d001e, 0x0505001f, 0x06050519, 0x0705011b,
- 0x0805091e, 0x090d892e, 0x0a05892f, 0x0b050dd9,
- 0x0c0509f1, 0
+/* TV-8532A (ICM532A) registers (LE) */
+#define R00_PART_CONTROL 0x00
+#define LATENT_CHANGE 0x80
+#define EXPO_CHANGE 0x04
+#define R01_TIMING_CONTROL_LOW 0x01
+#define CMD_EEprom_Open 0x30
+#define CMD_EEprom_Close 0x29
+#define R03_TABLE_ADDR 0x03
+#define R04_WTRAM_DATA_L 0x04
+#define R05_WTRAM_DATA_M 0x05
+#define R06_WTRAM_DATA_H 0x06
+#define R07_TABLE_LEN 0x07
+#define R08_RAM_WRITE_ACTION 0x08
+#define R0C_AD_WIDTHL 0x0c
+#define R0D_AD_WIDTHH 0x0d
+#define R0E_AD_HEIGHTL 0x0e
+#define R0F_AD_HEIGHTH 0x0f
+#define R10_AD_COL_BEGINL 0x10
+#define R11_AD_COL_BEGINH 0x11
+#define MIRROR 0x04 /* [10] */
+#define R14_AD_ROW_BEGINL 0x14
+#define R15_AD_ROWBEGINH 0x15
+#define R1C_AD_EXPOSE_TIMEL 0x1c
+#define R28_QUANT 0x28
+#define R29_LINE 0x29
+#define R2C_POLARITY 0x2c
+#define R2D_POINT 0x2d
+#define R2E_POINTH 0x2e
+#define R2F_POINTB 0x2f
+#define R30_POINTBH 0x30
+#define R31_UPD 0x31
+#define R2A_HIGH_BUDGET 0x2a
+#define R2B_LOW_BUDGET 0x2b
+#define R34_VID 0x34
+#define R35_VIDH 0x35
+#define R36_PID 0x36
+#define R37_PIDH 0x37
+#define R39_Test1 0x39 /* GPIO */
+#define R3B_Test3 0x3B /* GPIO */
+#define R83_AD_IDH 0x83
+#define R91_AD_SLOPEREG 0x91
+#define R94_AD_BITCONTROL 0x94
+
+static const u8 eeprom_data[][3] = {
+/* dataH dataM dataL */
+ {0x01, 0x00, 0x01},
+ {0x01, 0x80, 0x11},
+ {0x05, 0x00, 0x14},
+ {0x05, 0x00, 0x1c},
+ {0x0d, 0x00, 0x1e},
+ {0x05, 0x00, 0x1f},
+ {0x05, 0x05, 0x19},
+ {0x05, 0x01, 0x1b},
+ {0x05, 0x09, 0x1e},
+ {0x0d, 0x89, 0x2e},
+ {0x05, 0x89, 0x2f},
+ {0x05, 0x0d, 0xd9},
+ {0x05, 0x09, 0xf1},
};
static int reg_r(struct gspca_dev *gspca_dev,
@@ -165,7 +134,7 @@ static int reg_r(struct gspca_dev *gspca_dev,
{
usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
- TV8532_REQ_RegRead,
+ 0x03,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, 1,
@@ -174,27 +143,27 @@ static int reg_r(struct gspca_dev *gspca_dev,
}
/* write 1 byte */
-static void reg_w_1(struct gspca_dev *gspca_dev,
+static void reg_w1(struct gspca_dev *gspca_dev,
__u16 index, __u8 value)
{
gspca_dev->usb_buf[0] = value;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
- TV8532_REQ_RegWrite,
+ 0x02,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, 1, 500);
}
/* write 2 bytes */
-static void reg_w_2(struct gspca_dev *gspca_dev,
- __u16 index, __u8 val1, __u8 val2)
+static void reg_w2(struct gspca_dev *gspca_dev,
+ u16 index, u16 value)
{
- gspca_dev->usb_buf[0] = val1;
- gspca_dev->usb_buf[1] = val2;
+ gspca_dev->usb_buf[0] = value;
+ gspca_dev->usb_buf[1] = value >> 8;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
- TV8532_REQ_RegWrite,
+ 0x02,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, 2, 500);
@@ -202,32 +171,18 @@ static void reg_w_2(struct gspca_dev *gspca_dev,
static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev)
{
- int i = 0;
- __u8 reg, data0, data1, data2;
-
- reg_w_1(gspca_dev, TV8532_GPIO, 0xb0);
- reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Open);
-/* msleep(1); */
- while (tv_8532_eeprom_data[i]) {
- reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24;
- reg_w_1(gspca_dev, TV8532_EEprom_Add, reg);
- /* msleep(1); */
- data0 = (tv_8532_eeprom_data[i] & 0x000000ff);
- reg_w_1(gspca_dev, TV8532_EEprom_DataL, data0);
- /* msleep(1); */
- data1 = (tv_8532_eeprom_data[i] & 0x0000ff00) >> 8;
- reg_w_1(gspca_dev, TV8532_EEprom_DataM, data1);
- /* msleep(1); */
- data2 = (tv_8532_eeprom_data[i] & 0x00ff0000) >> 16;
- reg_w_1(gspca_dev, TV8532_EEprom_DataH, data2);
- /* msleep(1); */
- reg_w_1(gspca_dev, TV8532_EEprom_Write, 0);
- /* msleep(10); */
- i++;
+ int i;
+
+ reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Open);
+ for (i = 0; i < ARRAY_SIZE(eeprom_data); i++) {
+ reg_w1(gspca_dev, R03_TABLE_ADDR, i);
+ reg_w1(gspca_dev, R04_WTRAM_DATA_L, eeprom_data[i][2]);
+ reg_w1(gspca_dev, R05_WTRAM_DATA_M, eeprom_data[i][1]);
+ reg_w1(gspca_dev, R06_WTRAM_DATA_H, eeprom_data[i][0]);
+ reg_w1(gspca_dev, R08_RAM_WRITE_ACTION, 0);
}
- reg_w_1(gspca_dev, TV8532_EEprom_TableLength, i);
-/* msleep(1); */
- reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Close);
+ reg_w1(gspca_dev, R07_TABLE_LEN, i);
+ reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close);
msleep(10);
}
@@ -238,79 +193,76 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
- tv_8532WriteEEprom(gspca_dev);
-
cam = &gspca_dev->cam;
- cam->epaddr = 1;
cam->cam_mode = sif_mode;
- cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+ cam->nmodes = ARRAY_SIZE(sif_mode);
- sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
- sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
+ sd->brightness = BRIGHTNESS_DEF;
return 0;
}
static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev)
{
- __u8 data;
-
- data = reg_r(gspca_dev, 0x0001);
- PDEBUG(D_USBI, "register 0x01-> %x", data);
- data = reg_r(gspca_dev, 0x0002);
- PDEBUG(D_USBI, "register 0x02-> %x", data);
- reg_r(gspca_dev, TV8532_ADWIDTH_L);
- reg_r(gspca_dev, TV8532_ADWIDTH_H);
- reg_r(gspca_dev, TV8532_QUANT_COMP);
- reg_r(gspca_dev, TV8532_MODE_PACKET);
- reg_r(gspca_dev, TV8532_SETCLK);
- reg_r(gspca_dev, TV8532_POINT_L);
- reg_r(gspca_dev, TV8532_POINT_H);
- reg_r(gspca_dev, TV8532_POINTB_L);
- reg_r(gspca_dev, TV8532_POINTB_H);
- reg_r(gspca_dev, TV8532_BUDGET_L);
- reg_r(gspca_dev, TV8532_BUDGET_H);
- reg_r(gspca_dev, TV8532_VID_L);
- reg_r(gspca_dev, TV8532_VID_H);
- reg_r(gspca_dev, TV8532_PID_L);
- reg_r(gspca_dev, TV8532_PID_H);
- reg_r(gspca_dev, TV8532_DeviceID);
- reg_r(gspca_dev, TV8532_AD_COLBEGIN_L);
- reg_r(gspca_dev, TV8532_AD_COLBEGIN_H);
- reg_r(gspca_dev, TV8532_AD_ROWBEGIN_L);
- reg_r(gspca_dev, TV8532_AD_ROWBEGIN_H);
+ int i;
+ static u8 reg_tb[] = {
+ R0C_AD_WIDTHL,
+ R0D_AD_WIDTHH,
+ R28_QUANT,
+ R29_LINE,
+ R2C_POLARITY,
+ R2D_POINT,
+ R2E_POINTH,
+ R2F_POINTB,
+ R30_POINTBH,
+ R2A_HIGH_BUDGET,
+ R2B_LOW_BUDGET,
+ R34_VID,
+ R35_VIDH,
+ R36_PID,
+ R37_PIDH,
+ R83_AD_IDH,
+ R10_AD_COL_BEGINL,
+ R11_AD_COL_BEGINH,
+ R14_AD_ROW_BEGINL,
+ R15_AD_ROWBEGINH,
+ 0
+ };
+
+ i = 0;
+ do {
+ reg_r(gspca_dev, reg_tb[i]);
+ i++;
+ } while (reg_tb[i] != 0);
}
static void tv_8532_setReg(struct gspca_dev *gspca_dev)
{
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
- ADCBEGINL); /* 0x10 */
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
- ADCBEGINH); /* also digital gain */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
-
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0a);
+ reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44);
+ /* begin active line */
+ reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00);
+ /* mirror and digital gain */
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* = 0x84 */
+
+ reg_w1(gspca_dev, R3B_Test3, 0x0a); /* Test0Sel = 10 */
/******************************************************/
- reg_w_1(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL); /* 0e */
- reg_w_1(gspca_dev, TV8532_ADHEIGHT_H, ADHEIGHH); /* 0f */
- reg_w_2(gspca_dev, TV8532_EXPOSURE,
- EXPOL, EXPOH); /* 350d 0x014c; 1c */
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
- ADCBEGINL); /* 0x10 */
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
- ADCBEGINH); /* also digital gain */
- reg_w_1(gspca_dev, TV8532_AD_ROWBEGIN_L,
- ADRBEGINL); /* 0x14 */
-
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */
- reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x02); /* 0x94 */
-
- reg_w_1(gspca_dev, TV8532_CTRL,
- TV8532_CMD_EEprom_Close); /* 0x01 */
-
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ reg_w1(gspca_dev, R0E_AD_HEIGHTL, 0x90);
+ reg_w1(gspca_dev, R0F_AD_HEIGHTH, 0x01);
+ reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f);
+ reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44);
+ /* begin active line */
+ reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00);
+ /* mirror and digital gain */
+ reg_w1(gspca_dev, R14_AD_ROW_BEGINL, 0x0a);
+
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00);
+ reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x02);
+
+ reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close);
+
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00);
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* = 0x84 */
}
static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
@@ -319,54 +271,55 @@ static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
/* strange polling from tgc */
for (i = 0; i < 10; i++) {
- reg_w_1(gspca_dev, TV8532_SETCLK,
- TESTCLK); /* 0x48; //0x08; 0x2c */
- reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ reg_w1(gspca_dev, R2C_POLARITY, 0x10);
+ reg_w1(gspca_dev, R00_PART_CONTROL,
+ LATENT_CHANGE | EXPO_CHANGE);
+ reg_w1(gspca_dev, R31_UPD, 0x01);
}
}
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
- reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
+ tv_8532WriteEEprom(gspca_dev);
+
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V,
+ * slope rate 2 */
+ reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00);
tv_8532ReadRegisters(gspca_dev);
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
- reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL,
- ADHEIGHH); /* 401d 0x0169; 0e */
- reg_w_2(gspca_dev, TV8532_EXPOSURE, EXPOL,
- EXPOH); /* 350d 0x014c; 1c */
- reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */
- reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */
+ reg_w1(gspca_dev, R3B_Test3, 0x0b);
+ reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190);
+ reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f);
+ reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8);
+ reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03);
/*******************************************************************/
- reg_w_1(gspca_dev, TV8532_QUANT_COMP,
- TESTCOMP); /* 0x72 compressed mode 0x28 */
- reg_w_1(gspca_dev, TV8532_MODE_PACKET,
- TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ reg_w1(gspca_dev, R28_QUANT, 0x90);
+ /* no compress - fixed Q - quant 0 */
+ reg_w1(gspca_dev, R29_LINE, 0x81);
+ /* 0x84; // CIF | 4 packet 0x29 */
/************************************************/
- reg_w_1(gspca_dev, TV8532_SETCLK,
- TESTCLK); /* 0x48; //0x08; 0x2c */
- reg_w_1(gspca_dev, TV8532_POINT_L,
- TESTPTL); /* 0x38; 0x2d */
- reg_w_1(gspca_dev, TV8532_POINT_H,
- TESTPTH); /* 0x04; 0x2e */
- reg_w_1(gspca_dev, TV8532_POINTB_L,
- TESTPTBL); /* 0x04; 0x2f */
- reg_w_1(gspca_dev, TV8532_POINTB_H,
- TESTPTBH); /* 0x04; 0x30 */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ reg_w1(gspca_dev, R2C_POLARITY, 0x10);
+ /* 0x48; //0x08; 0x2c */
+ reg_w1(gspca_dev, R2D_POINT, 0x14);
+ /* 0x38; 0x2d */
+ reg_w1(gspca_dev, R2E_POINTH, 0x01);
+ /* 0x04; 0x2e */
+ reg_w1(gspca_dev, R2F_POINTB, 0x12);
+ /* 0x04; 0x2f */
+ reg_w1(gspca_dev, R30_POINTBH, 0x01);
+ /* 0x04; 0x30 */
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* 0x00<-0x84 */
/*************************************************/
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */
msleep(200);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
/*************************************************/
tv_8532_setReg(gspca_dev);
/*************************************************/
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
/*************************************************/
tv_8532_setReg(gspca_dev);
/*************************************************/
@@ -377,11 +330,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int brightness = sd->brightness;
- reg_w_2(gspca_dev, TV8532_EXPOSURE,
- brightness >> 8, brightness); /* 1c */
- reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
+ reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, sd->brightness);
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* 0x84 */
}
/* -- start the camera -- */
@@ -389,57 +341,50 @@ static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
- reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V,
+ * slope rate 2 */
+ reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00);
tv_8532ReadRegisters(gspca_dev);
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
- reg_w_2(gspca_dev, TV8532_ADHEIGHT_L,
- ADHEIGHL, ADHEIGHH); /* 401d 0x0169; 0e */
-/* reg_w_2(gspca_dev, TV8532_EXPOSURE,
- EXPOL, EXPOH); * 350d 0x014c; 1c */
+ reg_w1(gspca_dev, R3B_Test3, 0x0b);
+
+ reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190);
setbrightness(gspca_dev);
- reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */
- reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */
+ reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8); /* 0x20; 0x0c */
+ reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03);
/************************************************/
- reg_w_1(gspca_dev, TV8532_QUANT_COMP,
- TESTCOMP); /* 0x72 compressed mode 0x28 */
+ reg_w1(gspca_dev, R28_QUANT, 0x90);
+ /* 0x72 compressed mode 0x28 */
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
/* 176x144 */
- reg_w_1(gspca_dev, TV8532_MODE_PACKET,
- QCIFLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ reg_w1(gspca_dev, R29_LINE, 0x41);
+ /* CIF - 2 lines/packet */
} else {
/* 352x288 */
- reg_w_1(gspca_dev, TV8532_MODE_PACKET,
- TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ reg_w1(gspca_dev, R29_LINE, 0x81);
+ /* CIF - 2 lines/packet */
}
/************************************************/
- reg_w_1(gspca_dev, TV8532_SETCLK,
- TESTCLK); /* 0x48; //0x08; 0x2c */
- reg_w_1(gspca_dev, TV8532_POINT_L,
- TESTPTL); /* 0x38; 0x2d */
- reg_w_1(gspca_dev, TV8532_POINT_H,
- TESTPTH); /* 0x04; 0x2e */
- reg_w_1(gspca_dev, TV8532_POINTB_L,
- TESTPTBL); /* 0x04; 0x2f */
- reg_w_1(gspca_dev, TV8532_POINTB_H,
- TESTPTBH); /* 0x04; 0x30 */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ reg_w1(gspca_dev, R2C_POLARITY, 0x10); /* slow clock */
+ reg_w1(gspca_dev, R2D_POINT, 0x14);
+ reg_w1(gspca_dev, R2E_POINTH, 0x01);
+ reg_w1(gspca_dev, R2F_POINTB, 0x12);
+ reg_w1(gspca_dev, R30_POINTBH, 0x01);
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
/************************************************/
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */
msleep(200);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
/************************************************/
tv_8532_setReg(gspca_dev);
/************************************************/
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
/************************************************/
tv_8532_setReg(gspca_dev);
/************************************************/
tv_8532_PollReg(gspca_dev);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
gspca_dev->empty_packet = 0; /* check the empty packets */
sd->packet = 0; /* ignore the first packets */
@@ -449,7 +394,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
static void sd_stopN(struct gspca_dev *gspca_dev)
{
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -473,9 +418,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
/* each packet contains:
* - header 2 bytes
- * - RG line
+ * - RGRG line
* - 4 bytes
- * - GB line
+ * - GBGB line
* - 4 bytes
*/
gspca_frame_add(gspca_dev, packet_type0,
@@ -484,10 +429,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
frame, data + gspca_dev->width + 6, gspca_dev->width);
}
-static void setcontrast(struct gspca_dev *gspca_dev)
-{
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -506,24 +447,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->contrast = val;
- if (gspca_dev->streaming)
- setcontrast(gspca_dev);
- return 0;
-}
-
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->contrast;
- return 0;
-}
-
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -570,8 +493,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 0525ea51a6de..4c802fb12cd6 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -37,18 +37,21 @@ struct sd {
__u8 lightfreq;
__u8 sharpness;
+ u8 image_offset;
+
char bridge;
#define BRIDGE_VC0321 0
#define BRIDGE_VC0323 1
char sensor;
#define SENSOR_HV7131R 0
#define SENSOR_MI0360 1
-#define SENSOR_MI1320 2
-#define SENSOR_MI1310_SOC 3
-#define SENSOR_OV7660 4
-#define SENSOR_OV7670 5
-#define SENSOR_PO1200 6
-#define SENSOR_PO3130NC 7
+#define SENSOR_MI1310_SOC 2
+#define SENSOR_MI1320 3
+#define SENSOR_MI1320_SOC 4
+#define SENSOR_OV7660 5
+#define SENSOR_OV7670 6
+#define SENSOR_PO1200 7
+#define SENSOR_PO3130NC 8
};
/* V4L2 controls supported by the driver */
@@ -149,8 +152,50 @@ static const struct v4l2_pix_format vc0323_mode[] = {
.sizeimage = 640 * 480 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
.priv = 0},
+ {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi13x0_soc only */
+ .bytesperline = 1280,
+ .sizeimage = 1280 * 1024 * 1 / 4 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
+};
+static const struct v4l2_pix_format bi_mode[] = {
+/*fixme: jeg does not work
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 5},
+*/
+ {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 4},
+/*
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 3},
+*/
+ {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 2},
+/*
+ {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 1280,
+ .sizeimage = 1280 * 1024 * 1 / 4 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+*/
+ {1280, 1024, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+ .bytesperline = 1280,
+ .sizeimage = 1280 * 1024 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
};
-
static const struct v4l2_pix_format svga_mode[] = {
{800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 800,
@@ -400,92 +445,208 @@ static const __u8 mi0360_initQVGA_JPG[][4] = {
static const __u8 mi1310_socinitVGA_JPG[][4] = {
{0xb0, 0x03, 0x19, 0xcc},
{0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x64, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x00, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x03, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
{0xb3, 0x08, 0x01, 0xcc},
{0xb3, 0x09, 0x0c, 0xcc},
{0xb3, 0x34, 0x02, 0xcc},
{0xb3, 0x35, 0xdd, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc},
{0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x04, 0x0d, 0xcc},
{0xb3, 0x20, 0x00, 0xcc},
{0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x03, 0xcc},
- {0xb3, 0x23, 0xc0, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
{0xb3, 0x14, 0x00, 0xcc},
{0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x04, 0xcc},
- {0xb3, 0x17, 0xff, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc},
- {0xbc, 0x00, 0xd0, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xf0, 0x00, 0x02, 0xbb},
- {0xc8, 0x9f, 0x0b, 0xbb},
- {0x5b, 0x00, 0x01, 0xbb},
- {0x2f, 0xde, 0x20, 0xbb},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x26, 0x80, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb8, 0x00, 0x13, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xb8, 0x81, 0x01, 0xcc},
+ {0xb8, 0x2c, 0x5a, 0xcc},
+ {0xb8, 0x2d, 0xff, 0xcc},
+ {0xb8, 0x2e, 0xee, 0xcc},
+ {0xb8, 0x2f, 0xfb, 0xcc},
+ {0xb8, 0x30, 0x52, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf1, 0xcc},
+ {0xb8, 0x33, 0xff, 0xcc},
+ {0xb8, 0x34, 0x54, 0xcc},
+ {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc},
+ {0xb8, 0x37, 0x00, 0xcc},
{0xf0, 0x00, 0x00, 0xbb},
- {0x20, 0x03, 0x02, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x0d, 0x00, 0x09, 0xbb},
+ {0x0d, 0x00, 0x08, 0xbb},
{0xf0, 0x00, 0x01, 0xbb},
- {0x05, 0x00, 0x07, 0xbb},
- {0x34, 0x00, 0x00, 0xbb},
- {0x35, 0xff, 0x00, 0xbb},
- {0xdc, 0x07, 0x02, 0xbb},
- {0xdd, 0x3c, 0x18, 0xbb},
- {0xde, 0x92, 0x6d, 0xbb},
- {0xdf, 0xcd, 0xb1, 0xbb},
- {0xe0, 0xff, 0xe7, 0xbb},
- {0x06, 0xf0, 0x0d, 0xbb},
- {0x06, 0x70, 0x0e, 0xbb},
- {0x4c, 0x00, 0x01, 0xbb},
- {0x4d, 0x00, 0x01, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x2e, 0x0c, 0x55, 0xbb},
- {0x21, 0xb6, 0x6e, 0xbb},
- {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc1, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x06, 0x00, 0x14, 0xbb},
+ {0x3a, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x9b, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
{0xf0, 0x00, 0x00, 0xbb},
- {0x07, 0x00, 0x84, 0xbb},
- {0x08, 0x02, 0x4a, 0xbb},
- {0x05, 0x01, 0x10, 0xbb},
- {0x06, 0x00, 0x39, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x58, 0x02, 0x67, 0xbb},
- {0x57, 0x02, 0x00, 0xbb},
- {0x5a, 0x02, 0x67, 0xbb},
- {0x59, 0x02, 0x00, 0xbb},
- {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb},
- {0x39, 0x06, 0x18, 0xbb},
- {0x3a, 0x06, 0x18, 0xbb},
- {0x3b, 0x06, 0x18, 0xbb},
- {0x3c, 0x06, 0x18, 0xbb},
- {0x64, 0x7b, 0x5b, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc0, 0xbb},
- {0xbc, 0x0e, 0x00, 0xcc},
- {0xbc, 0x0f, 0x05, 0xcc},
- {0xbc, 0x10, 0xc0, 0xcc},
- {0xbc, 0x11, 0x03, 0xcc},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x2b, 0x00, 0x28, 0xbb},
+ {0x2c, 0x00, 0x30, 0xbb},
+ {0x2d, 0x00, 0x30, 0xbb},
+ {0x2e, 0x00, 0x28, 0xbb},
+ {0x41, 0x00, 0xd7, 0xbb},
+ {0x09, 0x02, 0x3a, 0xbb},
+ {0x0c, 0x00, 0x00, 0xbb},
+ {0x20, 0x00, 0x00, 0xbb},
+ {0x05, 0x00, 0x8c, 0xbb},
+ {0x06, 0x00, 0x32, 0xbb},
+ {0x07, 0x00, 0xc6, 0xbb},
+ {0x08, 0x00, 0x19, 0xbb},
+ {0x24, 0x80, 0x6f, 0xbb},
+ {0xc8, 0x00, 0x0f, 0xbb},
+ {0x20, 0x00, 0x0f, 0xbb},
{0xb6, 0x00, 0x00, 0xcc},
{0xb6, 0x03, 0x02, 0xcc},
{0xb6, 0x02, 0x80, 0xcc},
{0xb6, 0x05, 0x01, 0xcc},
{0xb6, 0x04, 0xe0, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x25, 0xcc},
+ {0xb6, 0x12, 0x78, 0xcc},
{0xb6, 0x18, 0x02, 0xcc},
{0xb6, 0x17, 0x58, 0xcc},
{0xb6, 0x16, 0x00, 0xcc},
{0xb6, 0x22, 0x12, 0xcc},
{0xb6, 0x23, 0x0b, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc},
{0xbf, 0xc0, 0x39, 0xcc},
{0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x00, 0xcc},
+ {0xbf, 0xcc, 0x10, 0xcc},
+ {0xb9, 0x12, 0x00, 0xcc},
+ {0xb9, 0x13, 0x0a, 0xcc},
+ {0xb9, 0x14, 0x0a, 0xcc},
+ {0xb9, 0x15, 0x0a, 0xcc},
+ {0xb9, 0x16, 0x0a, 0xcc},
+ {0xb9, 0x18, 0x00, 0xcc},
+ {0xb9, 0x19, 0x0f, 0xcc},
+ {0xb9, 0x1a, 0x0f, 0xcc},
+ {0xb9, 0x1b, 0x0f, 0xcc},
+ {0xb9, 0x1c, 0x0f, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0x03, 0x03, 0xc0, 0xbb},
+ {0x06, 0x00, 0x10, 0xbb},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0x2f, 0x00, 0xC0, 0xbb},
+ {0xb8, 0xa0, 0x12, 0xcc},
+ {},
+};
+static const __u8 mi1310_socinitQVGA_JPG[][4] = {
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x03, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xdd, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x0d, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x26, 0x80, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb8, 0x00, 0x13, 0xcc},
+ {0xbc, 0x00, 0xd1, 0xcc},
+ {0xb8, 0x81, 0x01, 0xcc},
+ {0xb8, 0x2c, 0x5a, 0xcc},
+ {0xb8, 0x2d, 0xff, 0xcc},
+ {0xb8, 0x2e, 0xee, 0xcc},
+ {0xb8, 0x2f, 0xfb, 0xcc},
+ {0xb8, 0x30, 0x52, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf1, 0xcc},
+ {0xb8, 0x33, 0xff, 0xcc},
+ {0xb8, 0x34, 0x54, 0xcc},
+ {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc},
+ {0xb8, 0x37, 0x00, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x0d, 0x00, 0x09, 0xbb},
+ {0x0d, 0x00, 0x08, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x06, 0x00, 0x14, 0xbb},
+ {0x3a, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x9b, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x2b, 0x00, 0x28, 0xbb},
+ {0x2c, 0x00, 0x30, 0xbb},
+ {0x2d, 0x00, 0x30, 0xbb},
+ {0x2e, 0x00, 0x28, 0xbb},
+ {0x41, 0x00, 0xd7, 0xbb},
+ {0x09, 0x02, 0x3a, 0xbb},
+ {0x0c, 0x00, 0x00, 0xbb},
+ {0x20, 0x00, 0x00, 0xbb},
+ {0x05, 0x00, 0x8c, 0xbb},
+ {0x06, 0x00, 0x32, 0xbb},
+ {0x07, 0x00, 0xc6, 0xbb},
+ {0x08, 0x00, 0x19, 0xbb},
+ {0x24, 0x80, 0x6f, 0xbb},
+ {0xc8, 0x00, 0x0f, 0xbb},
+ {0x20, 0x00, 0x0f, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x01, 0xcc},
+ {0xb6, 0x02, 0x40, 0xcc},
+ {0xb6, 0x05, 0x00, 0xcc},
+ {0xb6, 0x04, 0xf0, 0xcc},
+ {0xb6, 0x12, 0x78, 0xcc},
+ {0xb6, 0x18, 0x00, 0xcc},
+ {0xb6, 0x17, 0x96, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x10, 0xcc},
+ {0xb9, 0x12, 0x00, 0xcc},
+ {0xb9, 0x13, 0x0a, 0xcc},
+ {0xb9, 0x14, 0x0a, 0xcc},
+ {0xb9, 0x15, 0x0a, 0xcc},
+ {0xb9, 0x16, 0x0a, 0xcc},
+ {0xb9, 0x18, 0x00, 0xcc},
+ {0xb9, 0x19, 0x0f, 0xcc},
+ {0xb9, 0x1a, 0x0f, 0xcc},
+ {0xb9, 0x1b, 0x0f, 0xcc},
+ {0xb9, 0x1c, 0x0f, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc},
{0xbc, 0x02, 0x18, 0xcc},
{0xbc, 0x03, 0x50, 0xcc},
{0xbc, 0x04, 0x18, 0xcc},
@@ -496,131 +657,123 @@ static const __u8 mi1310_socinitVGA_JPG[][4] = {
{0xbc, 0x0a, 0x10, 0xcc},
{0xbc, 0x0b, 0x00, 0xcc},
{0xbc, 0x0c, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x80, 0x00, 0x03, 0xbb},
- {0x81, 0xc7, 0x14, 0xbb},
- {0x82, 0xeb, 0xe8, 0xbb},
- {0x83, 0xfe, 0xf4, 0xbb},
- {0x84, 0xcd, 0x10, 0xbb},
- {0x85, 0xf3, 0xee, 0xbb},
- {0x86, 0xff, 0xf1, 0xbb},
- {0x87, 0xcd, 0x10, 0xbb},
- {0x88, 0xf3, 0xee, 0xbb},
- {0x89, 0x01, 0xf1, 0xbb},
- {0x8a, 0xe5, 0x17, 0xbb},
- {0x8b, 0xe8, 0xe2, 0xbb},
- {0x8c, 0xf7, 0xed, 0xbb},
- {0x8d, 0x00, 0xff, 0xbb},
- {0x8e, 0xec, 0x10, 0xbb},
- {0x8f, 0xf0, 0xed, 0xbb},
- {0x90, 0xf9, 0xf2, 0xbb},
- {0x91, 0x00, 0x00, 0xbb},
- {0x92, 0xe9, 0x0d, 0xbb},
- {0x93, 0xf4, 0xf2, 0xbb},
- {0x94, 0xfb, 0xf5, 0xbb},
- {0x95, 0x00, 0xff, 0xbb},
- {0xb6, 0x0f, 0x08, 0xbb},
- {0xb7, 0x3d, 0x16, 0xbb},
- {0xb8, 0x0c, 0x04, 0xbb},
- {0xb9, 0x1c, 0x07, 0xbb},
- {0xba, 0x0a, 0x03, 0xbb},
- {0xbb, 0x1b, 0x09, 0xbb},
- {0xbc, 0x17, 0x0d, 0xbb},
- {0xbd, 0x23, 0x1d, 0xbb},
- {0xbe, 0x00, 0x28, 0xbb},
- {0xbf, 0x11, 0x09, 0xbb},
- {0xc0, 0x16, 0x15, 0xbb},
- {0xc1, 0x00, 0x1b, 0xbb},
- {0xc2, 0x0e, 0x07, 0xbb},
- {0xc3, 0x14, 0x10, 0xbb},
- {0xc4, 0x00, 0x17, 0xbb},
- {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x06, 0xf4, 0x8e, 0xbb},
- {0x00, 0x00, 0x50, 0xdd},
- {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x24, 0x50, 0x20, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x34, 0x0c, 0x50, 0xbb},
{0xb3, 0x01, 0x41, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb},
{0x03, 0x03, 0xc0, 0xbb},
+ {0x06, 0x00, 0x10, 0xbb},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0x2f, 0x00, 0xC0, 0xbb},
+ {0xb8, 0xa0, 0x12, 0xcc},
{},
};
-static const __u8 mi1310_socinitQVGA_JPG[][4] = {
- {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x03, 0xcc},
- {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x04, 0xcc},
- {0xb3, 0x17, 0xff, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc}, {0xbc, 0x00, 0xf0, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb},
- {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb},
- {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
- {0x20, 0x03, 0x02, 0xbb}, {0xf0, 0x00, 0x01, 0xbb},
- {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb},
- {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb},
- {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb},
- {0xdf, 0xcd, 0xb1, 0xbb}, {0xe0, 0xff, 0xe7, 0xbb},
- {0x06, 0xf0, 0x0d, 0xbb}, {0x06, 0x70, 0x0e, 0xbb},
- {0x4c, 0x00, 0x01, 0xbb}, {0x4d, 0x00, 0x01, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x2e, 0x0c, 0x55, 0xbb},
- {0x21, 0xb6, 0x6e, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
- {0x07, 0x00, 0x84, 0xbb}, {0x08, 0x02, 0x4a, 0xbb},
- {0x05, 0x01, 0x10, 0xbb}, {0x06, 0x00, 0x39, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x58, 0x02, 0x67, 0xbb},
- {0x57, 0x02, 0x00, 0xbb}, {0x5a, 0x02, 0x67, 0xbb},
- {0x59, 0x02, 0x00, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb}, {0x39, 0x06, 0x18, 0xbb},
- {0x3a, 0x06, 0x18, 0xbb}, {0x3b, 0x06, 0x18, 0xbb},
- {0x3c, 0x06, 0x18, 0xbb}, {0x64, 0x7b, 0x5b, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc0, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc},
- {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc},
- {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc},
- {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x25, 0xcc},
- {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc}, {0xf0, 0x00, 0x01, 0xbb},
- {0x80, 0x00, 0x03, 0xbb}, {0x81, 0xc7, 0x14, 0xbb},
- {0x82, 0xeb, 0xe8, 0xbb}, {0x83, 0xfe, 0xf4, 0xbb},
- {0x84, 0xcd, 0x10, 0xbb}, {0x85, 0xf3, 0xee, 0xbb},
- {0x86, 0xff, 0xf1, 0xbb}, {0x87, 0xcd, 0x10, 0xbb},
- {0x88, 0xf3, 0xee, 0xbb}, {0x89, 0x01, 0xf1, 0xbb},
- {0x8a, 0xe5, 0x17, 0xbb}, {0x8b, 0xe8, 0xe2, 0xbb},
- {0x8c, 0xf7, 0xed, 0xbb}, {0x8d, 0x00, 0xff, 0xbb},
- {0x8e, 0xec, 0x10, 0xbb}, {0x8f, 0xf0, 0xed, 0xbb},
- {0x90, 0xf9, 0xf2, 0xbb}, {0x91, 0x00, 0x00, 0xbb},
- {0x92, 0xe9, 0x0d, 0xbb}, {0x93, 0xf4, 0xf2, 0xbb},
- {0x94, 0xfb, 0xf5, 0xbb}, {0x95, 0x00, 0xff, 0xbb},
- {0xb6, 0x0f, 0x08, 0xbb}, {0xb7, 0x3d, 0x16, 0xbb},
- {0xb8, 0x0c, 0x04, 0xbb}, {0xb9, 0x1c, 0x07, 0xbb},
- {0xba, 0x0a, 0x03, 0xbb}, {0xbb, 0x1b, 0x09, 0xbb},
- {0xbc, 0x17, 0x0d, 0xbb}, {0xbd, 0x23, 0x1d, 0xbb},
- {0xbe, 0x00, 0x28, 0xbb}, {0xbf, 0x11, 0x09, 0xbb},
- {0xc0, 0x16, 0x15, 0xbb}, {0xc1, 0x00, 0x1b, 0xbb},
- {0xc2, 0x0e, 0x07, 0xbb}, {0xc3, 0x14, 0x10, 0xbb},
- {0xc4, 0x00, 0x17, 0xbb}, {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0xf4, 0x8e, 0xbb},
- {0x00, 0x00, 0x50, 0xdd}, {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x24, 0x50, 0x20, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x34, 0x0c, 0x50, 0xbb},
- {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb},
- {0x03, 0x03, 0xc0, 0xbb},
- {},
+static const u8 mi1310_soc_InitSXGA_JPG[][4] = {
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xdd, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x0d, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x04, 0xcc},
+ {0xb3, 0x23, 0x00, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x04, 0xcc},
+ {0xb3, 0x17, 0xff, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x26, 0x80, 0xcc},
+ {0xb8, 0x06, 0x00, 0xcc},
+ {0xb8, 0x07, 0x05, 0xcc},
+ {0xb8, 0x08, 0x00, 0xcc},
+ {0xb8, 0x09, 0x04, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb8, 0x00, 0x11, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xb8, 0x81, 0x01, 0xcc},
+ {0xb8, 0x2c, 0x5a, 0xcc},
+ {0xb8, 0x2d, 0xff, 0xcc},
+ {0xb8, 0x2e, 0xee, 0xcc},
+ {0xb8, 0x2f, 0xfb, 0xcc},
+ {0xb8, 0x30, 0x52, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf1, 0xcc},
+ {0xb8, 0x33, 0xff, 0xcc},
+ {0xb8, 0x34, 0x54, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x0d, 0x00, 0x09, 0xbb},
+ {0x0d, 0x00, 0x08, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x06, 0x00, 0x14, 0xbb},
+ {0x3a, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x9b, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x2b, 0x00, 0x28, 0xbb},
+ {0x2c, 0x00, 0x30, 0xbb},
+ {0x2d, 0x00, 0x30, 0xbb},
+ {0x2e, 0x00, 0x28, 0xbb},
+ {0x41, 0x00, 0xd7, 0xbb},
+ {0x09, 0x02, 0x3a, 0xbb},
+ {0x0c, 0x00, 0x00, 0xbb},
+ {0x20, 0x00, 0x00, 0xbb},
+ {0x05, 0x00, 0x8c, 0xbb},
+ {0x06, 0x00, 0x32, 0xbb},
+ {0x07, 0x00, 0xc6, 0xbb},
+ {0x08, 0x00, 0x19, 0xbb},
+ {0x24, 0x80, 0x6f, 0xbb},
+ {0xc8, 0x00, 0x0f, 0xbb},
+ {0x20, 0x00, 0x03, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x05, 0xcc},
+ {0xb6, 0x02, 0x00, 0xcc},
+ {0xb6, 0x05, 0x04, 0xcc},
+ {0xb6, 0x04, 0x00, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x18, 0x0a, 0xcc},
+ {0xb6, 0x17, 0x00, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x10, 0xcc},
+ {0xb9, 0x12, 0x00, 0xcc},
+ {0xb9, 0x13, 0x14, 0xcc},
+ {0xb9, 0x14, 0x14, 0xcc},
+ {0xb9, 0x15, 0x14, 0xcc},
+ {0xb9, 0x16, 0x14, 0xcc},
+ {0xb9, 0x18, 0x00, 0xcc},
+ {0xb9, 0x19, 0x1e, 0xcc},
+ {0xb9, 0x1a, 0x1e, 0xcc},
+ {0xb9, 0x1b, 0x1e, 0xcc},
+ {0xb9, 0x1c, 0x1e, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0x2f, 0x00, 0xC0, 0xbb},
+ {0xb8, 0xa0, 0x12, 0xcc},
+ {}
};
static const __u8 mi1320_gamma[17] = {
@@ -778,6 +931,722 @@ static const __u8 mi1320_initQVGA_data[][4] = {
{}
};
+static const u8 mi1320_soc_InitVGA[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xc8, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x07, 0x00, 0xe0, 0xbb},
+ {0x08, 0x00, 0x0b, 0xbb},
+ {0x21, 0x00, 0x0c, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0xbf, 0xc0, 0x26, 0xcc},
+ {0xbf, 0xc1, 0x02, 0xcc},
+ {0xbf, 0xcc, 0x04, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {}
+};
+static const u8 mi1320_soc_InitVGA_JPG[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xc8, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x07, 0x00, 0xe0, 0xbb},
+ {0x08, 0x00, 0x0b, 0xbb},
+ {0x21, 0x00, 0x0c, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x02, 0xcc},
+ {0xb6, 0x02, 0x80, 0xcc},
+ {0xb6, 0x05, 0x01, 0xcc},
+ {0xb6, 0x04, 0xe0, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x13, 0x05, 0xcc},
+ {0xb6, 0x18, 0x02, 0xcc},
+ {0xb6, 0x17, 0x58, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x00, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {}
+};
+static const u8 mi1320_soc_InitQVGA[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0xd1, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xc8, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x07, 0x00, 0xe0, 0xbb},
+ {0x08, 0x00, 0x0b, 0xbb},
+ {0x21, 0x00, 0x0c, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0xbf, 0xc0, 0x26, 0xcc},
+ {0xbf, 0xc1, 0x02, 0xcc},
+ {0xbf, 0xcc, 0x04, 0xcc},
+ {0xbc, 0x02, 0x18, 0xcc},
+ {0xbc, 0x03, 0x50, 0xcc},
+ {0xbc, 0x04, 0x18, 0xcc},
+ {0xbc, 0x05, 0x00, 0xcc},
+ {0xbc, 0x06, 0x00, 0xcc},
+ {0xbc, 0x08, 0x30, 0xcc},
+ {0xbc, 0x09, 0x40, 0xcc},
+ {0xbc, 0x0a, 0x10, 0xcc},
+ {0xbc, 0x0b, 0x00, 0xcc},
+ {0xbc, 0x0c, 0x00, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {}
+};
+static const u8 mi1320_soc_InitQVGA_JPG[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0xd1, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xc8, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x07, 0x00, 0xe0, 0xbb},
+ {0x08, 0x00, 0x0b, 0xbb},
+ {0x21, 0x00, 0x0c, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x01, 0xcc},
+ {0xb6, 0x02, 0x40, 0xcc},
+ {0xb6, 0x05, 0x00, 0xcc},
+ {0xb6, 0x04, 0xf0, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x13, 0x05, 0xcc},
+ {0xb6, 0x18, 0x00, 0xcc},
+ {0xb6, 0x17, 0x96, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x00, 0xcc},
+ {0xbc, 0x02, 0x18, 0xcc},
+ {0xbc, 0x03, 0x50, 0xcc},
+ {0xbc, 0x04, 0x18, 0xcc},
+ {0xbc, 0x05, 0x00, 0xcc},
+ {0xbc, 0x06, 0x00, 0xcc},
+ {0xbc, 0x08, 0x30, 0xcc},
+ {0xbc, 0x09, 0x40, 0xcc},
+ {0xbc, 0x0a, 0x10, 0xcc},
+ {0xbc, 0x0b, 0x00, 0xcc},
+ {0xbc, 0x0c, 0x00, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {}
+};
+static const u8 mi1320_soc_InitSXGA_JPG[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x33, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x00, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x04, 0xcc},
+ {0xb3, 0x23, 0x00, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x04, 0xcc},
+ {0xb3, 0x17, 0xff, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xc8, 0x9f, 0x0b, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0x5b, 0x00, 0x01, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x05, 0xcc},
+ {0xb6, 0x02, 0x00, 0xcc},
+ {0xb6, 0x05, 0x04, 0xcc},
+ {0xb6, 0x04, 0x00, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x13, 0x29, 0xcc},
+ {0xb6, 0x18, 0x0a, 0xcc},
+ {0xb6, 0x17, 0x00, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x00, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x13, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x00, 0x85, 0xbb},
+ {0x08, 0x00, 0x27, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0x0d, 0xbb},
+ {0x3a, 0x06, 0x1b, 0xbb},
+ {0x3b, 0x00, 0x95, 0xbb},
+ {0x3c, 0x04, 0xdb, 0xbb},
+ {0x57, 0x02, 0x00, 0xbb},
+ {0x58, 0x02, 0x66, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0x5a, 0x01, 0x33, 0xbb},
+ {0x5c, 0x12, 0x0d, 0xbb},
+ {0x5d, 0x16, 0x11, 0xbb},
+ {0x64, 0x5e, 0x1c, 0xbb},
+ {0x2f, 0x90, 0x00, 0xbb},
+ {}
+};
+static const u8 mi1320_soc_InitSXGA[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x04, 0xcc},
+ {0xb3, 0x23, 0x00, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x04, 0xcc},
+ {0xb3, 0x17, 0xff, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xc8, 0x9f, 0x0b, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0x5b, 0x00, 0x01, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0xbf, 0xc0, 0x26, 0xcc},
+ {0xbf, 0xc1, 0x02, 0xcc},
+ {0xbf, 0xcc, 0x04, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x13, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x00, 0x85, 0xbb},
+ {0x08, 0x00, 0x27, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0x0d, 0xbb},
+ {0x3a, 0x06, 0x1b, 0xbb},
+ {0x3b, 0x00, 0x95, 0xbb},
+ {0x3c, 0x04, 0xdb, 0xbb},
+ {0x57, 0x02, 0x00, 0xbb},
+ {0x58, 0x02, 0x66, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0x5a, 0x01, 0x33, 0xbb},
+ {0x5c, 0x12, 0x0d, 0xbb},
+ {0x5d, 0x16, 0x11, 0xbb},
+ {0x64, 0x5e, 0x1c, 0xbb},
+ {}
+};
static const __u8 po3130_gamma[17] = {
0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
@@ -1764,26 +2633,43 @@ static const __u8 po1200_initVGA_data[][4] = {
};
struct sensor_info {
- int sensorId;
- __u8 I2cAdd;
- __u8 IdAdd;
- __u16 VpId;
- __u8 m1;
- __u8 m2;
- __u8 op;
- };
+ s8 sensorId;
+ u8 I2cAdd;
+ u8 IdAdd;
+ u16 VpId;
+ u8 m1;
+ u8 m2;
+ u8 op;
+};
static const struct sensor_info sensor_info_data[] = {
/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */
- {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
- {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
+ {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
+ {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01},
+/* (tested in vc032x_probe_sensor) */
+/* {-1, 0x80 | 0x20, 0x83, 0x0000, 0x24, 0x25, 0x01}, */
{SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01},
- {SENSOR_MI1320, 0x80 | 0xc8, 0x00, 0x148c, 0x64, 0x65, 0x01},
- {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
{SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
/* (tested in vc032x_probe_sensor) */
/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
+ {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
+ {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05},
+ {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05},
+ {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
+/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01}, */
+ {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
+/* {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01}, */
+/* {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, */
+ {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01},
{SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
+ {-1, 0x80 | 0x2d, 0x00, 0x0000, 0x65, 0x67, 0x01},
+ {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
+ {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01},
+ {SENSOR_MI1320_SOC, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x67, 0x01},
+/*fixme: previously detected?*/
+ {SENSOR_MI1320, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x65, 0x01},
+/*fixme: not in the ms-win probe - may be found before?*/
+ {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
};
/* read 'len' bytes in gspca_dev->usb_buf */
@@ -1814,51 +2700,49 @@ static void reg_w(struct usb_device *dev,
500);
}
-static void read_sensor_register(struct gspca_dev *gspca_dev,
- __u16 address, __u16 *value)
+static u16 read_sensor_register(struct gspca_dev *gspca_dev,
+ u16 address)
{
struct usb_device *dev = gspca_dev->dev;
- __u8 ldata, mdata, hdata;
+ u8 ldata, mdata, hdata;
int retry = 50;
- *value = 0;
-
reg_r(gspca_dev, 0xa1, 0xb33f, 1);
- /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */
if (!(gspca_dev->usb_buf[0] & 0x02)) {
- PDEBUG(D_ERR, "I2c Bus Busy Wait %d",
- gspca_dev->usb_buf[0] & 0x02);
- return;
+ PDEBUG(D_ERR, "I2c Bus Busy Wait %02x",
+ gspca_dev->usb_buf[0]);
+ return 0;
}
reg_w(dev, 0xa0, address, 0xb33a);
reg_w(dev, 0xa0, 0x02, 0xb339);
- reg_r(gspca_dev, 0xa1, 0xb33b, 1);
- while (retry-- && gspca_dev->usb_buf[0]) {
+ do {
reg_r(gspca_dev, 0xa1, 0xb33b, 1);
-/* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */
- msleep(1);
- }
+ if (gspca_dev->usb_buf[0] == 0x00)
+ break;
+ msleep(40);
+ } while (--retry >= 0);
+
reg_r(gspca_dev, 0xa1, 0xb33e, 1);
ldata = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0xa1, 0xb33d, 1);
mdata = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0xa1, 0xb33c, 1);
hdata = gspca_dev->usb_buf[0];
- PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
- hdata, mdata, ldata);
+ if (hdata != 0 && mdata != 0 && ldata != 0)
+ PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
+ hdata, mdata, ldata);
reg_r(gspca_dev, 0xa1, 0xb334, 1);
if (gspca_dev->usb_buf[0] == 0x02)
- *value = (hdata << 8) + mdata;
- else
- *value = hdata;
+ return (hdata << 8) + mdata;
+ return hdata;
}
static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
{
struct usb_device *dev = gspca_dev->dev;
int i;
- __u16 value;
+ u16 value;
const struct sensor_info *ptsensor_info;
reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
@@ -1872,48 +2756,51 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
reg_w(dev, 0xa0, 0x0c, 0xb309);
reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335);
reg_w(dev, 0xa0, ptsensor_info->op, 0xb301);
- read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value);
- if (value == ptsensor_info->VpId)
- return ptsensor_info->sensorId;
-
- /* special case for MI0360 */
- if (ptsensor_info->sensorId == SENSOR_MI1310_SOC
- && value == 0x8243)
- return SENSOR_MI0360;
+ value = read_sensor_register(gspca_dev, ptsensor_info->IdAdd);
+ if (value == 0 && ptsensor_info->IdAdd == 0x82)
+ value = read_sensor_register(gspca_dev, 0x83);
+ if (value != 0) {
+ PDEBUG(D_ERR|D_PROBE, "Sensor ID %04x (%d)",
+ value, i);
+ if (value == ptsensor_info->VpId)
+ return ptsensor_info->sensorId;
+
+ switch (value) {
+ case 0x7673:
+ return SENSOR_OV7670;
+ case 0x8243:
+ return SENSOR_MI0360;
+ }
+/*fixme: should return here*/
+ }
}
return -1;
}
-static __u8 i2c_write(struct gspca_dev *gspca_dev,
- __u8 reg, const __u8 *val, __u8 size)
+static void i2c_write(struct gspca_dev *gspca_dev,
+ u8 reg, const u8 *val,
+ u8 size) /* 1 or 2 */
{
struct usb_device *dev = gspca_dev->dev;
+ int retry;
- if (size > 3 || size < 1)
- return -EINVAL;
reg_r(gspca_dev, 0xa1, 0xb33f, 1);
+/*fixme:should check if (!(gspca_dev->usb_buf[0] & 0x02)) error*/
reg_w(dev, 0xa0, size, 0xb334);
reg_w(dev, 0xa0, reg, 0xb33a);
- switch (size) {
- case 1:
- reg_w(dev, 0xa0, val[0], 0xb336);
- break;
- case 2:
- reg_w(dev, 0xa0, val[0], 0xb336);
+ reg_w(dev, 0xa0, val[0], 0xb336);
+ if (size > 1)
reg_w(dev, 0xa0, val[1], 0xb337);
- break;
- case 3:
- reg_w(dev, 0xa0, val[0], 0xb336);
- reg_w(dev, 0xa0, val[1], 0xb337);
- reg_w(dev, 0xa0, val[2], 0xb338);
- break;
- default:
- reg_w(dev, 0xa0, 0x01, 0xb334);
- return -EINVAL;
- }
reg_w(dev, 0xa0, 0x01, 0xb339);
- reg_r(gspca_dev, 0xa1, 0xb33b, 1);
- return gspca_dev->usb_buf[0] == 0;
+ retry = 4;
+ do {
+ reg_r(gspca_dev, 0xa1, 0xb33b, 1);
+ if (gspca_dev->usb_buf[0] == 0)
+ break;
+ msleep(20);
+ } while (--retry > 0);
+ if (retry <= 0)
+ PDEBUG(D_ERR, "i2c_write failed");
}
static void put_tab_to_reg(struct gspca_dev *gspca_dev,
@@ -1938,7 +2825,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
return;
case 0xcc: /* normal write */
reg_w(dev, 0xa0, data[i][2],
- ((data[i][0])<<8) | data[i][1]);
+ (data[i][0]) << 8 | data[i][1]);
break;
case 0xaa: /* i2c op */
i2c_write(gspca_dev, data[i][1], &data[i][2], 1);
@@ -1955,19 +2842,6 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
/*not reached*/
}
-/*
- "GammaT"=hex:04,17,31,4f,6a,83,99,ad,bf,ce,da,e5,ee,f5,fb,ff,ff
- "MatrixT"=hex:60,f9,e5,e7,50,05,f3,e6,66
- */
-
-static void vc0321_reset(struct gspca_dev *gspca_dev)
-{
- reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb04d);
- reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb301);
- msleep(100);
- reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb003);
- msleep(100);
-}
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
@@ -1979,10 +2853,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
int sensor;
cam = &gspca_dev->cam;
- cam->epaddr = 0x02;
sd->bridge = id->driver_info;
-
- vc0321_reset(gspca_dev);
sensor = vc032x_probe_sensor(gspca_dev);
switch (sensor) {
case -1:
@@ -2001,6 +2872,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
case SENSOR_MI1320:
PDEBUG(D_PROBE, "Find Sensor MI1320");
break;
+ case SENSOR_MI1320_SOC:
+ PDEBUG(D_PROBE, "Find Sensor MI1320_SOC");
+ break;
case SENSOR_OV7660:
PDEBUG(D_PROBE, "Find Sensor OV7660");
break;
@@ -2020,12 +2894,23 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = vc0321_mode;
cam->nmodes = ARRAY_SIZE(vc0321_mode);
} else {
- if (sensor != SENSOR_PO1200) {
- cam->cam_mode = vc0323_mode;
- cam->nmodes = ARRAY_SIZE(vc0323_mode);
- } else {
+ switch (sensor) {
+ case SENSOR_PO1200:
cam->cam_mode = svga_mode;
cam->nmodes = ARRAY_SIZE(svga_mode);
+ break;
+ case SENSOR_MI1310_SOC:
+ cam->cam_mode = vc0323_mode;
+ cam->nmodes = ARRAY_SIZE(vc0323_mode);
+ break;
+ case SENSOR_MI1320_SOC:
+ cam->cam_mode = bi_mode;
+ cam->nmodes = ARRAY_SIZE(bi_mode);
+ break;
+ default:
+ cam->cam_mode = vc0323_mode;
+ cam->nmodes = ARRAY_SIZE(vc0323_mode) - 1;
+ break;
}
}
@@ -2061,7 +2946,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
return 0;
}
-/* this function is called at probe and time */
+/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
return 0;
@@ -2124,9 +3009,18 @@ static void setsharpness(struct gspca_dev *gspca_dev)
static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ const __u8 (*init)[4];
const __u8 *GammaT = NULL;
const __u8 *MatrixT = NULL;
int mode;
+ static const u8 (*mi1320_soc_init[])[4] = {
+ mi1320_soc_InitSXGA,
+ mi1320_soc_InitSXGA_JPG,
+ mi1320_soc_InitVGA,
+ mi1320_soc_InitVGA_JPG,
+ mi1320_soc_InitQVGA,
+ mi1320_soc_InitQVGA_JPG
+ };
/* Assume start use the good resolution from gspca_dev->mode */
if (sd->bridge == BRIDGE_VC0321) {
@@ -2134,6 +3028,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfed);
reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfee);
reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfef);
+ sd->image_offset = 46;
+ } else {
+ if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].pixelformat
+ == V4L2_PIX_FMT_JPEG)
+ sd->image_offset = 0;
+ else
+ sd->image_offset = 32;
}
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@@ -2141,115 +3042,87 @@ static int sd_start(struct gspca_dev *gspca_dev)
case SENSOR_HV7131R:
GammaT = hv7131r_gamma;
MatrixT = hv7131r_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, hv7131r_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, hv7131r_initVGA_data);
- }
+ if (mode)
+ init = hv7131r_initQVGA_data; /* 320x240 */
+ else
+ init = hv7131r_initVGA_data; /* 640x480 */
break;
case SENSOR_OV7660:
GammaT = ov7660_gamma;
MatrixT = ov7660_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, ov7660_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, ov7660_initVGA_data);
- }
+ if (mode)
+ init = ov7660_initQVGA_data; /* 320x240 */
+ else
+ init = ov7660_initVGA_data; /* 640x480 */
break;
case SENSOR_OV7670:
/*GammaT = ov7660_gamma; */
/*MatrixT = ov7660_matrix; */
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, ov7670_initQVGA_JPG);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, ov7670_initVGA_JPG);
- }
+ if (mode)
+ init = ov7670_initQVGA_JPG; /* 320x240 */
+ else
+ init = ov7670_initVGA_JPG; /* 640x480 */
break;
case SENSOR_MI0360:
GammaT = mi1320_gamma;
MatrixT = mi0360_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, mi0360_initQVGA_JPG);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, mi0360_initVGA_JPG);
- }
+ if (mode)
+ init = mi0360_initQVGA_JPG; /* 320x240 */
+ else
+ init = mi0360_initVGA_JPG; /* 640x480 */
break;
case SENSOR_MI1310_SOC:
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, mi1310_socinitQVGA_JPG);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, mi1310_socinitVGA_JPG);
+ GammaT = mi1320_gamma;
+ MatrixT = mi1320_matrix;
+ switch (mode) {
+ case 1:
+ init = mi1310_socinitQVGA_JPG; /* 320x240 */
+ break;
+ case 0:
+ init = mi1310_socinitVGA_JPG; /* 640x480 */
+ break;
+ default:
+ init = mi1310_soc_InitSXGA_JPG; /* 1280x1024 */
+ break;
}
break;
case SENSOR_MI1320:
GammaT = mi1320_gamma;
MatrixT = mi1320_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, mi1320_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, mi1320_initVGA_data);
- }
+ if (mode)
+ init = mi1320_initQVGA_data; /* 320x240 */
+ else
+ init = mi1320_initVGA_data; /* 640x480 */
+ break;
+ case SENSOR_MI1320_SOC:
+ GammaT = mi1320_gamma;
+ MatrixT = mi1320_matrix;
+ init = mi1320_soc_init[mode];
break;
case SENSOR_PO3130NC:
GammaT = po3130_gamma;
MatrixT = po3130_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, po3130_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, po3130_initVGA_data);
- }
- usb_exchange(gspca_dev, po3130_rundata);
+ if (mode)
+ init = po3130_initQVGA_data; /* 320x240 */
+ else
+ init = po3130_initVGA_data; /* 640x480 */
+ usb_exchange(gspca_dev, init);
+ init = po3130_rundata;
break;
- case SENSOR_PO1200:
+ default:
+/* case SENSOR_PO1200: */
GammaT = po1200_gamma;
MatrixT = po1200_matrix;
- usb_exchange(gspca_dev, po1200_initVGA_data);
+ init = po1200_initVGA_data;
break;
- default:
- PDEBUG(D_PROBE, "Damned !! no sensor found Bye");
- return -EMEDIUMTYPE;
}
+ usb_exchange(gspca_dev, init);
if (GammaT && MatrixT) {
put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a);
put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b);
put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c);
put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
- /* Seem SHARPNESS */
- /*
- reg_w(gspca_dev->dev, 0xa0, 0x80, 0xb80a);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80b);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80e);
- */
- /* all 0x40 ??? do nothing
- reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb822);
- reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb823);
- reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824);
- */
- /* Only works for HV7131R ??
- reg_r (gspca_dev, 0xa1, 0xb881, 1);
- reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881);
- reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801);
- */
- /* only hv7131r et ov7660
- reg_w(gspca_dev->dev, 0xa0, 0x20, 0xb827);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb826); * ISP_GAIN 80
- reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS
- */
/* set the led on 0x0892 0x0896 */
if (sd->sensor != SENSOR_PO1200) {
reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
@@ -2296,12 +3169,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
"vc032x header packet found len %d", len);
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
data, 0);
- if (sd->bridge == BRIDGE_VC0321) {
-#define VCHDRSZ 46
- data += VCHDRSZ;
- len -= VCHDRSZ;
-#undef VCHDRSZ
- }
+ data += sd->image_offset;
+ len -= sd->image_offset;
gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
data, len);
return;
@@ -2399,7 +3268,8 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
strcpy((char *) menu->name, "50 Hz");
return 0;
- case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+ default:
+/* case 2: * V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
strcpy((char *) menu->name, "60 Hz");
return 0;
}
@@ -2424,6 +3294,7 @@ static const struct sd_desc sd_desc = {
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x041e, 0x405b), .driver_info = BRIDGE_VC0323},
{USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x046d, 0x0897), .driver_info = BRIDGE_VC0321},
@@ -2432,6 +3303,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321},
+ {USB_DEVICE(0x15b8, 0x6001), .driver_info = BRIDGE_VC0323},
{USB_DEVICE(0x15b8, 0x6002), .driver_info = BRIDGE_VC0323},
{USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323},
{}
@@ -2460,8 +3332,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index ec2a53d53fe2..4fe01d8b6c87 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -23,6 +23,7 @@
#define MODULE_NAME "zc3xx"
#include "gspca.h"
+#include "jpeg.h"
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, "
"Serge A. Suchkov <Serge.A.S@tochka.ru>");
@@ -31,7 +32,7 @@ MODULE_LICENSE("GPL");
static int force_sensor = -1;
-#include "jpeg.h"
+#define QUANT_VAL 1 /* quantization table */
#include "zc3xx-reg.h"
/* specific webcam descriptor */
@@ -44,30 +45,36 @@ struct sd {
__u8 autogain;
__u8 lightfreq;
__u8 sharpness;
+ u8 quality; /* image quality */
+#define QUALITY_MIN 40
+#define QUALITY_MAX 60
+#define QUALITY_DEF 50
- char qindex;
signed char sensor; /* Type of image sensor chip */
/* !! values used in different tables */
-#define SENSOR_CS2102 0
-#define SENSOR_CS2102K 1
-#define SENSOR_GC0305 2
-#define SENSOR_HDCS2020b 3
-#define SENSOR_HV7131B 4
-#define SENSOR_HV7131C 5
-#define SENSOR_ICM105A 6
-#define SENSOR_MC501CB 7
-#define SENSOR_OV7620 8
-/*#define SENSOR_OV7648 8 - same values */
-#define SENSOR_OV7630C 9
-#define SENSOR_PAS106 10
-#define SENSOR_PAS202B 11
-#define SENSOR_PB0330 12
-#define SENSOR_PO2030 13
-#define SENSOR_TAS5130CK 14
-#define SENSOR_TAS5130CXX 15
-#define SENSOR_TAS5130C_VF0250 16
-#define SENSOR_MAX 17
+#define SENSOR_ADCM2700 0
+#define SENSOR_CS2102 1
+#define SENSOR_CS2102K 2
+#define SENSOR_GC0305 3
+#define SENSOR_HDCS2020b 4
+#define SENSOR_HV7131B 5
+#define SENSOR_HV7131C 6
+#define SENSOR_ICM105A 7
+#define SENSOR_MC501CB 8
+#define SENSOR_OV7620 9
+/*#define SENSOR_OV7648 9 - same values */
+#define SENSOR_OV7630C 10
+#define SENSOR_PAS106 11
+#define SENSOR_PAS202B 12
+#define SENSOR_PB0330 13
+#define SENSOR_PO2030 14
+#define SENSOR_TAS5130CK 15
+#define SENSOR_TAS5130CXX 16
+#define SENSOR_TAS5130C_VF0250 17
+#define SENSOR_MAX 18
unsigned short chip_revision;
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -206,6 +213,213 @@ struct usb_action {
__u16 idx;
};
+static const struct usb_action adcm2700_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */
+ {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */
+ {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */
+ {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */
+ {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */
+ {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */
+ {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */
+ {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */
+ {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */
+ {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */
+ {0xbb, 0x86, 0x0002}, /* 00,86,02,bb */
+ {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */
+ {0xbb, 0x86, 0x0802}, /* 08,86,02,bb */
+ {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */
+/*mswin+*/
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xaa, 0xfe, 0x0002},
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xaa, 0xb4, 0xcd37},
+ {0xaa, 0xa4, 0x0004},
+ {0xaa, 0xa8, 0x0007},
+ {0xaa, 0xac, 0x0004},
+/*mswin-*/
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */
+ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
+ {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */
+ {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {}
+};
+static const struct usb_action adcm2700_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
+ {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */
+ {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */
+ {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0050}, /* 00,00,50,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */
+ {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */
+ {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */
+ {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */
+ {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */
+ {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */
+ {0xbb, 0x86, 0x0002}, /* 00,88,02,bb */
+ {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */
+ {0xbb, 0x86, 0x0802}, /* 08,88,02,bb */
+ {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */
+ /*******/
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */
+ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
+ {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */
+ {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {}
+};
+static const struct usb_action adcm2700_50HZ[] = {
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x05, 0x8400}, /* 84,05,00,bb */
+ {0xbb, 0xd0, 0xb007}, /* b0,d0,07,bb */
+ {0xbb, 0xa0, 0xb80f}, /* b8,a0,0f,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {0xaa, 0x26, 0x00d0}, /* 00,26,d0,aa */
+ {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */
+ {}
+};
+static const struct usb_action adcm2700_60HZ[] = {
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */
+ {0xbb, 0x82, 0xb006}, /* b0,82,06,bb */
+ {0xbb, 0x04, 0xb80d}, /* b8,04,0d,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {0xaa, 0x26, 0x0057}, /* 00,26,57,aa */
+ {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */
+ {}
+};
+static const struct usb_action adcm2700_NoFliker[] = {
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */
+ {0xbb, 0x05, 0xb000}, /* b0,05,00,bb */
+ {0xbb, 0xa0, 0xb801}, /* b8,a0,01,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {}
+};
static const struct usb_action cs2102_Initial[] = {
{0xa1, 0x01, 0x0008},
{0xa1, 0x01, 0x0008},
@@ -877,7 +1091,7 @@ static const struct usb_action cs2102K_Initial[] = {
};
static const struct usb_action cs2102K_InitialScale[] = {
- {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
{0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
@@ -894,6 +1108,7 @@ static const struct usb_action cs2102K_InitialScale[] = {
{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
{0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
{0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+/*fixme: next sequence = i2c exchanges*/
{0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
{0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
{0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
@@ -1077,207 +1292,6 @@ static const struct usb_action cs2102K_InitialScale[] = {
{0xa0, 0x60, ZC3XX_R116_RGAIN},
{0xa0, 0x40, ZC3XX_R117_GGAIN},
{0xa0, 0x4c, ZC3XX_R118_BGAIN},
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
- {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0A, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0B, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0C, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0D, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xA3, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0E, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0C, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x78, ZC3XX_R18D_YTARGET},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0x01, 0x01b1},
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x4c, ZC3XX_R118_BGAIN},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
- {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
- {0xa0, 0x38, ZC3XX_R121_GAMMA01},
- {0xa0, 0x59, ZC3XX_R122_GAMMA02},
- {0xa0, 0x79, ZC3XX_R123_GAMMA03},
- {0xa0, 0x92, ZC3XX_R124_GAMMA04},
- {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
- {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
- {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
- {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
- {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
- {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
- {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
- {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
- {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
- {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
- {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
- {0xa0, 0x26, ZC3XX_R130_GAMMA10},
- {0xa0, 0x22, ZC3XX_R131_GAMMA11},
- {0xa0, 0x20, ZC3XX_R132_GAMMA12},
- {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
- {0xa0, 0x16, ZC3XX_R134_GAMMA14},
- {0xa0, 0x13, ZC3XX_R135_GAMMA15},
- {0xa0, 0x10, ZC3XX_R136_GAMMA16},
- {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
- {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
- {0xa0, 0x09, ZC3XX_R139_GAMMA19},
- {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
- {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
- {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
- {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
- {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
- {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
- {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf4, ZC3XX_R10B_RGB01},
- {0xa0, 0xf4, ZC3XX_R10C_RGB02},
- {0xa0, 0xf4, ZC3XX_R10D_RGB10},
- {0xa0, 0x58, ZC3XX_R10E_RGB11},
- {0xa0, 0xf4, ZC3XX_R10F_RGB12},
- {0xa0, 0xf4, ZC3XX_R110_RGB20},
- {0xa0, 0xf4, ZC3XX_R111_RGB21},
- {0xa0, 0x58, ZC3XX_R112_RGB22},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
- {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x19, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x1f, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x4c, ZC3XX_R118_BGAIN},
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
{0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
@@ -1334,6 +1348,7 @@ static const struct usb_action cs2102K_InitialScale[] = {
{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+/*fixme:what does the next sequence?*/
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
@@ -6237,7 +6252,7 @@ static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
{}
};
-static int reg_r_i(struct gspca_dev *gspca_dev,
+static u8 reg_r_i(struct gspca_dev *gspca_dev,
__u16 index)
{
usb_control_msg(gspca_dev->dev,
@@ -6250,10 +6265,10 @@ static int reg_r_i(struct gspca_dev *gspca_dev,
return gspca_dev->usb_buf[0];
}
-static int reg_r(struct gspca_dev *gspca_dev,
+static u8 reg_r(struct gspca_dev *gspca_dev,
__u16 index)
{
- int ret;
+ u8 ret;
ret = reg_r_i(gspca_dev, index);
PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret);
@@ -6286,8 +6301,8 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev,
__u8 retbyte;
__u16 retval;
- reg_w_i(gspca_dev->dev, reg, 0x92);
- reg_w_i(gspca_dev->dev, 0x02, 0x90); /* <- read command */
+ reg_w_i(gspca_dev->dev, reg, 0x0092);
+ reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */
msleep(25);
retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */
@@ -6332,6 +6347,12 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
action->idx & 0xff, /* valL */
action->idx >> 8); /* valH */
break;
+ case 0xbb:
+ i2c_write(gspca_dev,
+ action->idx >> 8, /* reg */
+ action->idx & 0xff, /* valL */
+ action->val); /* valH */
+ break;
default:
/* case 0xdd: * delay */
msleep(action->val / 64 + 10);
@@ -6347,6 +6368,10 @@ static void setmatrix(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
int i;
const __u8 *matrix;
+ static const u8 adcm2700_matrix[9] =
+/* {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; */
+/*ms-win*/
+ {0x74, 0xed, 0xed, 0xed, 0x74, 0xed, 0xed, 0xed, 0x74};
static const __u8 gc0305_matrix[9] =
{0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50};
static const __u8 ov7620_matrix[9] =
@@ -6358,23 +6383,24 @@ static void setmatrix(struct gspca_dev *gspca_dev)
static const __u8 vf0250_matrix[9] =
{0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
static const __u8 *matrix_tb[SENSOR_MAX] = {
- NULL, /* SENSOR_CS2102 0 */
- NULL, /* SENSOR_CS2102K 1 */
- gc0305_matrix, /* SENSOR_GC0305 2 */
- NULL, /* SENSOR_HDCS2020b 3 */
- NULL, /* SENSOR_HV7131B 4 */
- NULL, /* SENSOR_HV7131C 5 */
- NULL, /* SENSOR_ICM105A 6 */
- NULL, /* SENSOR_MC501CB 7 */
- ov7620_matrix, /* SENSOR_OV7620 8 */
- NULL, /* SENSOR_OV7630C 9 */
- NULL, /* SENSOR_PAS106 10 */
- pas202b_matrix, /* SENSOR_PAS202B 11 */
- NULL, /* SENSOR_PB0330 12 */
- po2030_matrix, /* SENSOR_PO2030 13 */
- NULL, /* SENSOR_TAS5130CK 14 */
- NULL, /* SENSOR_TAS5130CXX 15 */
- vf0250_matrix, /* SENSOR_TAS5130C_VF0250 16 */
+ adcm2700_matrix, /* SENSOR_ADCM2700 0 */
+ NULL, /* SENSOR_CS2102 1 */
+ NULL, /* SENSOR_CS2102K 2 */
+ gc0305_matrix, /* SENSOR_GC0305 3 */
+ NULL, /* SENSOR_HDCS2020b 4 */
+ NULL, /* SENSOR_HV7131B 5 */
+ NULL, /* SENSOR_HV7131C 6 */
+ NULL, /* SENSOR_ICM105A 7 */
+ NULL, /* SENSOR_MC501CB 8 */
+ ov7620_matrix, /* SENSOR_OV7620 9 */
+ NULL, /* SENSOR_OV7630C 10 */
+ NULL, /* SENSOR_PAS106 11 */
+ pas202b_matrix, /* SENSOR_PAS202B 12 */
+ NULL, /* SENSOR_PB0330 13 */
+ po2030_matrix, /* SENSOR_PO2030 14 */
+ NULL, /* SENSOR_TAS5130CK 15 */
+ NULL, /* SENSOR_TAS5130CXX 16 */
+ vf0250_matrix, /* SENSOR_TAS5130C_VF0250 17 */
};
matrix = matrix_tb[sd->sensor];
@@ -6398,8 +6424,11 @@ static void setbrightness(struct gspca_dev *gspca_dev)
/*fixme: is it really write to 011d and 018d for all other sensors? */
brightness = sd->brightness;
reg_w(gspca_dev->dev, brightness, 0x011d);
- if (sd->sensor == SENSOR_HV7131B)
+ switch (sd->sensor) {
+ case SENSOR_ADCM2700:
+ case SENSOR_HV7131B:
return;
+ }
if (brightness < 0x70)
brightness += 0x10;
else
@@ -6536,10 +6565,10 @@ static void setquality(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
- __u8 quality;
__u8 frxt;
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_HV7131B:
case SENSOR_OV7620:
@@ -6547,26 +6576,18 @@ static void setquality(struct gspca_dev *gspca_dev)
return;
}
/*fixme: is it really 0008 0007 0018 for all other sensors? */
- quality = sd->qindex;
- reg_w(dev, quality, 0x0008);
+ reg_w(dev, QUANT_VAL, 0x0008);
frxt = 0x30;
reg_w(dev, frxt, 0x0007);
- switch (quality) {
- case 0:
- case 1:
- case 2:
- frxt = 0xff;
- break;
- case 3:
- frxt = 0xf0;
- break;
- case 4:
- frxt = 0xe0;
- break;
- case 5:
- frxt = 0x20;
- break;
- }
+#if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2
+ frxt = 0xff;
+#elif QUANT_VAL == 3
+ frxt = 0xf0;
+#elif QUANT_VAL == 4
+ frxt = 0xe0;
+#else
+ frxt = 0x20;
+#endif
reg_w(dev, frxt, 0x0018);
}
@@ -6583,71 +6604,75 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
int i, mode;
const struct usb_action *zc3_freq;
static const struct usb_action *freq_tb[SENSOR_MAX][6] = {
-/* SENSOR_CS2102 0 */
+/* SENSOR_ADCM2700 0 */
+ {adcm2700_NoFliker, adcm2700_NoFliker,
+ adcm2700_50HZ, adcm2700_50HZ,
+ adcm2700_60HZ, adcm2700_60HZ},
+/* SENSOR_CS2102 1 */
{cs2102_NoFliker, cs2102_NoFlikerScale,
cs2102_50HZ, cs2102_50HZScale,
cs2102_60HZ, cs2102_60HZScale},
-/* SENSOR_CS2102K 1 */
+/* SENSOR_CS2102K 2 */
{cs2102_NoFliker, cs2102_NoFlikerScale,
NULL, NULL, /* currently disabled */
NULL, NULL},
-/* SENSOR_GC0305 2 */
+/* SENSOR_GC0305 3 */
{gc0305_NoFliker, gc0305_NoFliker,
gc0305_50HZ, gc0305_50HZ,
gc0305_60HZ, gc0305_60HZ},
-/* SENSOR_HDCS2020b 3 */
+/* SENSOR_HDCS2020b 4 */
{hdcs2020b_NoFliker, hdcs2020b_NoFliker,
hdcs2020b_50HZ, hdcs2020b_50HZ,
hdcs2020b_60HZ, hdcs2020b_60HZ},
-/* SENSOR_HV7131B 4 */
+/* SENSOR_HV7131B 5 */
{hv7131b_NoFlikerScale, hv7131b_NoFliker,
hv7131b_50HZScale, hv7131b_50HZ,
hv7131b_60HZScale, hv7131b_60HZ},
-/* SENSOR_HV7131C 5 */
+/* SENSOR_HV7131C 6 */
{NULL, NULL,
NULL, NULL,
NULL, NULL},
-/* SENSOR_ICM105A 6 */
+/* SENSOR_ICM105A 7 */
{icm105a_NoFliker, icm105a_NoFlikerScale,
icm105a_50HZ, icm105a_50HZScale,
icm105a_60HZ, icm105a_60HZScale},
-/* SENSOR_MC501CB 7 */
+/* SENSOR_MC501CB 8 */
{MC501CB_NoFliker, MC501CB_NoFlikerScale,
MC501CB_50HZ, MC501CB_50HZScale,
MC501CB_60HZ, MC501CB_60HZScale},
-/* SENSOR_OV7620 8 */
+/* SENSOR_OV7620 9 */
{OV7620_NoFliker, OV7620_NoFliker,
OV7620_50HZ, OV7620_50HZ,
OV7620_60HZ, OV7620_60HZ},
-/* SENSOR_OV7630C 9 */
+/* SENSOR_OV7630C 10 */
{NULL, NULL,
NULL, NULL,
NULL, NULL},
-/* SENSOR_PAS106 10 */
+/* SENSOR_PAS106 11 */
{pas106b_NoFliker, pas106b_NoFliker,
pas106b_50HZ, pas106b_50HZ,
pas106b_60HZ, pas106b_60HZ},
-/* SENSOR_PAS202B 11 */
+/* SENSOR_PAS202B 12 */
{pas202b_NoFlikerScale, pas202b_NoFliker,
pas202b_50HZScale, pas202b_50HZ,
pas202b_60HZScale, pas202b_60HZ},
-/* SENSOR_PB0330 12 */
+/* SENSOR_PB0330 13 */
{pb0330_NoFliker, pb0330_NoFlikerScale,
pb0330_50HZ, pb0330_50HZScale,
pb0330_60HZ, pb0330_60HZScale},
-/* SENSOR_PO2030 13 */
+/* SENSOR_PO2030 14 */
{PO2030_NoFliker, PO2030_NoFliker,
PO2030_50HZ, PO2030_50HZ,
PO2030_60HZ, PO2030_60HZ},
-/* SENSOR_TAS5130CK 14 */
+/* SENSOR_TAS5130CK 15 */
{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
tas5130cxx_50HZ, tas5130cxx_50HZScale,
tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130CXX 15 */
+/* SENSOR_TAS5130CXX 16 */
{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
tas5130cxx_50HZ, tas5130cxx_50HZScale,
tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130C_VF0250 16 */
+/* SENSOR_TAS5130C_VF0250 17 */
{tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale},
@@ -6701,6 +6726,7 @@ static void send_unknown(struct usb_device *dev, int sensor)
reg_w(dev, 0x0c, 0x003b);
reg_w(dev, 0x08, 0x0038);
break;
+ case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_OV7620:
case SENSOR_PB0330:
@@ -6743,26 +6769,25 @@ static int sif_probe(struct gspca_dev *gspca_dev)
static int vga_2wr_probe(struct gspca_dev *gspca_dev)
{
struct usb_device *dev = gspca_dev->dev;
- __u8 retbyte;
- __u16 checkword;
+ u16 retword;
start_2wr_probe(dev, 0x00); /* HV7131B */
i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x00; /* HV7131B */
start_2wr_probe(dev, 0x04); /* CS2102 */
i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x04; /* CS2102 */
start_2wr_probe(dev, 0x06); /* OmniVision */
reg_w(dev, 0x08, 0x008d);
i2c_write(gspca_dev, 0x11, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x11);
- if (retbyte != 0) {
+ retword = i2c_read(gspca_dev, 0x11);
+ if (retword != 0) {
/* (should have returned 0xaa) --> Omnivision? */
/* reg_r 0x10 -> 0x06 --> */
goto ov_check;
@@ -6770,40 +6795,40 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
start_2wr_probe(dev, 0x08); /* HDCS2020 */
i2c_write(gspca_dev, 0x15, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x15);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x15);
+ if (retword != 0)
return 0x08; /* HDCS2020 */
start_2wr_probe(dev, 0x0a); /* PB0330 */
i2c_write(gspca_dev, 0x07, 0xaa, 0xaa);
- retbyte = i2c_read(gspca_dev, 0x07);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x07);
+ if (retword != 0)
return 0x0a; /* PB0330 */
- retbyte = i2c_read(gspca_dev, 0x03);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x03);
+ if (retword != 0)
return 0x0a; /* PB0330 ?? */
- retbyte = i2c_read(gspca_dev, 0x04);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x04);
+ if (retword != 0)
return 0x0a; /* PB0330 ?? */
start_2wr_probe(dev, 0x0c); /* ICM105A */
i2c_write(gspca_dev, 0x01, 0x11, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x0c; /* ICM105A */
start_2wr_probe(dev, 0x0e); /* PAS202BCB */
reg_w(dev, 0x08, 0x008d);
i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
msleep(500);
- retbyte = i2c_read(gspca_dev, 0x03);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x03);
+ if (retword != 0)
return 0x0e; /* PAS202BCB */
start_2wr_probe(dev, 0x02); /* ?? */
i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x02; /* ?? */
ov_check:
reg_r(gspca_dev, 0x0010); /* ?? */
@@ -6817,12 +6842,10 @@ ov_check:
msleep(500);
reg_w(dev, 0x01, 0x0012);
i2c_write(gspca_dev, 0x12, 0x80, 0x00); /* sensor reset */
- retbyte = i2c_read(gspca_dev, 0x0a);
- checkword = retbyte << 8;
- retbyte = i2c_read(gspca_dev, 0x0b);
- checkword |= retbyte;
- PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", checkword);
- switch (checkword) {
+ retword = i2c_read(gspca_dev, 0x0a) << 8;
+ retword |= i2c_read(gspca_dev, 0x0b);
+ PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", retword);
+ switch (retword) {
case 0x7631: /* OV7630C */
reg_w(dev, 0x06, 0x0010);
break;
@@ -6832,7 +6855,7 @@ ov_check:
default:
return -1; /* not OmniVision */
}
- return checkword;
+ return retword;
}
struct sensor_by_chipset_revision {
@@ -6845,6 +6868,7 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
{0x8001, 0x13},
{0x8000, 0x14}, /* CS2102K */
{0x8400, 0x15}, /* TAS5130K */
+ {0x4001, 0x16}, /* ADCM2700 */
};
static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6853,7 +6877,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
struct usb_device *dev = gspca_dev->dev;
int i;
__u8 retbyte;
- __u16 checkword;
+ u16 retword;
/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
reg_w(dev, 0x02, 0x0010);
@@ -6865,27 +6889,25 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x03, 0x0012);
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x14);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x14);
+ if (retword != 0)
return 0x11; /* HV7131R */
- retbyte = i2c_read(gspca_dev, 0x15);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x15);
+ if (retword != 0)
return 0x11; /* HV7131R */
- retbyte = i2c_read(gspca_dev, 0x16);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x16);
+ if (retword != 0)
return 0x11; /* HV7131R */
reg_w(dev, 0x02, 0x0010);
- retbyte = reg_r(gspca_dev, 0x000b);
- checkword = retbyte << 8;
- retbyte = reg_r(gspca_dev, 0x000a);
- checkword |= retbyte;
- PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword);
+ retword = reg_r(gspca_dev, 0x000b) << 8;
+ retword |= reg_r(gspca_dev, 0x000a);
+ PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword);
reg_r(gspca_dev, 0x0010);
/* this is tested only once anyway */
for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
- if (chipset_revision_sensor[i].revision == checkword) {
- sd->chip_revision = checkword;
+ if (chipset_revision_sensor[i].revision == retword) {
+ sd->chip_revision = retword;
send_unknown(dev, SENSOR_PB0330);
return chipset_revision_sensor[i].internal_sensor_id;
}
@@ -6897,8 +6919,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x0a, 0x0010);
reg_w(dev, 0x03, 0x0012);
reg_w(dev, 0x01, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x00);
- if (retbyte != 0) {
+ retword = i2c_read(gspca_dev, 0x00);
+ if (retword != 0) {
PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
return 0x0a; /* ?? */
}
@@ -6910,14 +6932,14 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x03, 0x0012);
msleep(2);
reg_w(dev, 0x01, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x00);
- if (retbyte != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte);
- if (retbyte == 0x11) /* VF0250 */
+ retword = i2c_read(gspca_dev, 0x00);
+ if (retword != 0) {
+ PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword);
+ if (retword == 0x0011) /* VF0250 */
return 0x0250;
- if (retbyte == 0x29) /* gc0305 */
+ if (retword == 0x0029) /* gc0305 */
send_unknown(dev, SENSOR_GC0305);
- return retbyte;
+ return retword;
}
reg_w(dev, 0x01, 0x0000); /* check OmniVision */
@@ -6927,8 +6949,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x06, 0x0010);
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012);
- if (i2c_read(gspca_dev, 0x1c) == 0x7f /* OV7610 - manufacturer ID */
- && i2c_read(gspca_dev, 0x1d) == 0xa2) {
+ if (i2c_read(gspca_dev, 0x1c) == 0x007f /* OV7610 - manufacturer ID */
+ && i2c_read(gspca_dev, 0x1d) == 0x00a2) {
send_unknown(dev, SENSOR_OV7620);
return 0x06; /* OmniVision confirm ? */
}
@@ -6942,16 +6964,14 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
/* msleep(150); */
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x0000); /* ID 0 */
- checkword = retbyte << 8;
- retbyte = i2c_read(gspca_dev, 0x0001); /* ID 1 */
- checkword |= retbyte;
- PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword);
- if (checkword == 0x2030) {
+ retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */
+ retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */
+ PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword);
+ if (retword == 0x2030) {
retbyte = i2c_read(gspca_dev, 0x02); /* revision number */
PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte);
send_unknown(dev, SENSOR_PO2030);
- return checkword;
+ return retword;
}
reg_w(dev, 0x01, 0x0000);
@@ -6962,10 +6982,10 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0001);
reg_w(dev, 0xd3, 0x008b);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
- return 0x0a; /* ?? */
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0) {
+ PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword);
+ return retword;
}
return -1;
}
@@ -6973,7 +6993,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int sensor, sensor2;
+ int sensor;
switch (sd->sensor) {
case SENSOR_MC501CB:
@@ -6988,16 +7008,9 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
break;
}
sensor = vga_2wr_probe(gspca_dev);
- if (sensor >= 0) {
- if (sensor < 0x7600)
- return sensor;
- /* next probe is needed for OmniVision ? */
- }
- sensor2 = vga_3wr_probe(gspca_dev);
- if (sensor2 >= 0
- && sensor >= 0)
+ if (sensor >= 0)
return sensor;
- return sensor2;
+ return vga_3wr_probe(gspca_dev);
}
/* this function is called at probe time */
@@ -7009,23 +7022,24 @@ static int sd_config(struct gspca_dev *gspca_dev,
int sensor;
int vga = 1; /* 1: vga, 0: sif */
static const __u8 gamma[SENSOR_MAX] = {
- 5, /* SENSOR_CS2102 0 */
- 5, /* SENSOR_CS2102K 1 */
- 4, /* SENSOR_GC0305 2 */
- 4, /* SENSOR_HDCS2020b 3 */
- 4, /* SENSOR_HV7131B 4 */
- 4, /* SENSOR_HV7131C 5 */
- 4, /* SENSOR_ICM105A 6 */
- 4, /* SENSOR_MC501CB 7 */
- 3, /* SENSOR_OV7620 8 */
- 4, /* SENSOR_OV7630C 9 */
- 4, /* SENSOR_PAS106 10 */
- 4, /* SENSOR_PAS202B 11 */
- 4, /* SENSOR_PB0330 12 */
- 4, /* SENSOR_PO2030 13 */
- 4, /* SENSOR_TAS5130CK 14 */
- 4, /* SENSOR_TAS5130CXX 15 */
- 3, /* SENSOR_TAS5130C_VF0250 16 */
+ 4, /* SENSOR_ADCM2700 0 */
+ 5, /* SENSOR_CS2102 1 */
+ 5, /* SENSOR_CS2102K 2 */
+ 4, /* SENSOR_GC0305 3 */
+ 4, /* SENSOR_HDCS2020b 4 */
+ 4, /* SENSOR_HV7131B 5 */
+ 4, /* SENSOR_HV7131C 6 */
+ 4, /* SENSOR_ICM105A 7 */
+ 4, /* SENSOR_MC501CB 8 */
+ 3, /* SENSOR_OV7620 9 */
+ 4, /* SENSOR_OV7630C 10 */
+ 4, /* SENSOR_PAS106 11 */
+ 4, /* SENSOR_PAS202B 12 */
+ 4, /* SENSOR_PB0330 13 */
+ 4, /* SENSOR_PO2030 14 */
+ 4, /* SENSOR_TAS5130CK 15 */
+ 4, /* SENSOR_TAS5130CXX 16 */
+ 3, /* SENSOR_TAS5130C_VF0250 17 */
};
/* define some sensors from the vendor/product */
@@ -7033,7 +7047,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = id->driver_info;
sensor = zcxx_probeSensor(gspca_dev);
if (sensor >= 0)
- PDEBUG(D_PROBE, "probe sensor -> %02x", sensor);
+ PDEBUG(D_PROBE, "probe sensor -> %04x", sensor);
if ((unsigned) force_sensor < SENSOR_MAX) {
sd->sensor = force_sensor;
PDEBUG(D_PROBE, "sensor forced to %d", force_sensor);
@@ -7112,6 +7126,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->chip_revision);
sd->sensor = SENSOR_TAS5130CK;
break;
+ case 0x16:
+ PDEBUG(D_PROBE, "Find Sensor ADCM2700");
+ sd->sensor = SENSOR_ADCM2700;
+ break;
case 0x29:
PDEBUG(D_PROBE, "Find Sensor GC0305");
sd->sensor = SENSOR_GC0305;
@@ -7129,12 +7147,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Find Sensor OV7620");
sd->sensor = SENSOR_OV7620;
break;
+ case 0x7631:
+ PDEBUG(D_PROBE, "Find Sensor OV7630C");
+ sd->sensor = SENSOR_OV7630C;
+ break;
case 0x7648:
PDEBUG(D_PROBE, "Find Sensor OV7648");
sd->sensor = SENSOR_OV7620; /* same sensor (?) */
break;
default:
- PDEBUG(D_ERR|D_PROBE, "Unknown sensor %02x", sensor);
+ PDEBUG(D_ERR|D_PROBE, "Unknown sensor %04x", sensor);
return -EINVAL;
}
}
@@ -7147,7 +7169,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
/*fixme:test*/
gspca_dev->nbalt--;
if (vga) {
@@ -7157,12 +7178,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
}
- sd->qindex = 1;
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
sd->gamma = gamma[(int) sd->sensor];
sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value;
+ sd->quality = QUALITY_DEF;
switch (sd->sensor) {
case SENSOR_GC0305:
@@ -7196,27 +7217,34 @@ static int sd_start(struct gspca_dev *gspca_dev)
const struct usb_action *zc3_init;
int mode;
static const struct usb_action *init_tb[SENSOR_MAX][2] = {
- {cs2102_InitialScale, cs2102_Initial}, /* 0 */
- {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */
- {gc0305_Initial, gc0305_InitialScale}, /* 2 */
- {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 3 */
- {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 4 */
- {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 5 */
- {icm105axx_InitialScale, icm105axx_Initial}, /* 6 */
- {MC501CB_InitialScale, MC501CB_Initial}, /* 7 */
- {OV7620_mode0, OV7620_mode1}, /* 8 */
- {ov7630c_InitialScale, ov7630c_Initial}, /* 9 */
- {pas106b_InitialScale, pas106b_Initial}, /* 10 */
- {pas202b_Initial, pas202b_InitialScale}, /* 11 */
- {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */
+ {adcm2700_Initial, adcm2700_InitialScale}, /* 0 */
+ {cs2102_InitialScale, cs2102_Initial}, /* 1 */
+ {cs2102K_InitialScale, cs2102K_Initial}, /* 2 */
+ {gc0305_Initial, gc0305_InitialScale}, /* 3 */
+ {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 4 */
+ {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 5 */
+ {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */
+ {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */
+ {MC501CB_InitialScale, MC501CB_Initial}, /* 8 */
+ {OV7620_mode0, OV7620_mode1}, /* 9 */
+ {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */
+ {pas106b_InitialScale, pas106b_Initial}, /* 11 */
+ {pas202b_Initial, pas202b_InitialScale}, /* 12 */
+ {pb0330xx_InitialScale, pb0330xx_Initial}, /* 13 */
/* or {pb03303x_InitialScale, pb03303x_Initial}, */
- {PO2030_mode0, PO2030_mode1}, /* 13 */
- {tas5130CK_InitialScale, tas5130CK_Initial}, /* 14 */
- {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 15 */
+ {PO2030_mode0, PO2030_mode1}, /* 14 */
+ {tas5130CK_InitialScale, tas5130CK_Initial}, /* 15 */
+ {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 16 */
{tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial},
- /* 16 */
+ /* 17 */
};
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x21); /* JPEG 422 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
zc3_init = init_tb[(int) sd->sensor][mode];
switch (sd->sensor) {
@@ -7243,11 +7271,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
usb_exchange(gspca_dev, zc3_init);
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_OV7620:
case SENSOR_PO2030:
case SENSOR_TAS5130C_VF0250:
- msleep(100); /* ?? */
+/* msleep(100); * ?? */
reg_r(gspca_dev, 0x0002); /* --> 0x40 */
reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
reg_w(dev, 0x15, 0x01ae);
@@ -7260,6 +7289,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
setmatrix(gspca_dev);
setbrightness(gspca_dev);
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
case SENSOR_OV7620:
reg_r(gspca_dev, 0x0008);
reg_w(dev, 0x00, 0x0008);
@@ -7301,6 +7331,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
setlightfreq(gspca_dev);
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
+ reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
+ reg_w(dev, 0x15, 0x01ae);
+ reg_w(dev, 0x02, 0x0180);
+ /* ms-win + */
+ reg_w(dev, 0x40, 0x0117);
+ break;
case SENSOR_GC0305:
reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
reg_w(dev, 0x15, 0x01ae);
@@ -7323,19 +7360,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
setautogain(gspca_dev);
switch (sd->sensor) {
- case SENSOR_PAS202B:
- reg_w(dev, 0x00, 0x0007); /* (from win traces) */
- break;
case SENSOR_PO2030:
msleep(500);
reg_r(gspca_dev, 0x0008);
reg_r(gspca_dev, 0x0007);
+ /*fall thru*/
+ case SENSOR_PAS202B:
reg_w(dev, 0x00, 0x0007); /* (from win traces) */
- reg_w(dev, 0x02, 0x0008);
+ reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
break;
}
- if (sd->sensor == SENSOR_PAS202B)
- reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
return 0;
}
@@ -7344,6 +7378,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ kfree(sd->jpeg_hdr);
if (!gspca_dev->present)
return;
send_unknown(gspca_dev->dev, sd->sensor);
@@ -7354,14 +7389,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
__u8 *data,
int len)
{
+ struct sd *sd = (struct sd *) gspca_dev;
if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
data, 0);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame,
- ((struct sd *) gspca_dev)->qindex,
- 0x21);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
+
/* remove the webcam's header:
* ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp
* - 'ss ss' is the frame sequence number (BE)
@@ -7503,6 +7539,34 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
return -EINVAL;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
.ctrls = sd_ctrls,
@@ -7513,6 +7577,8 @@ static const struct sd_desc sd_desc = {
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.querymenu = sd_querymenu,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
static const __devinitdata struct usb_device_id device_table[] = {
@@ -7563,11 +7629,9 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x055f, 0xd004)},
{USB_DEVICE(0x0698, 0x2003)},
{USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106},
- {USB_DEVICE(0x0ac8, 0x0302)},
+ {USB_DEVICE(0x0ac8, 0x0302), .driver_info = SENSOR_PAS106},
{USB_DEVICE(0x0ac8, 0x301b)},
-#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE
{USB_DEVICE(0x0ac8, 0x303b)},
-#endif
{USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250},
{USB_DEVICE(0x0ac8, 0x307b)},
{USB_DEVICE(0x10fd, 0x0128)},
@@ -7600,8 +7664,10 @@ static struct usb_driver sd_driver = {
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/hdpvr/Kconfig b/drivers/media/video/hdpvr/Kconfig
new file mode 100644
index 000000000000..de247f3c7d05
--- /dev/null
+++ b/drivers/media/video/hdpvr/Kconfig
@@ -0,0 +1,10 @@
+
+config VIDEO_HDPVR
+ tristate "Hauppauge HD PVR support"
+ depends on VIDEO_DEV
+ ---help---
+ This is a video4linux driver for Hauppauge's HD PVR USB device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called hdpvr
+
diff --git a/drivers/media/video/hdpvr/Makefile b/drivers/media/video/hdpvr/Makefile
new file mode 100644
index 000000000000..e0230fcb2e36
--- /dev/null
+++ b/drivers/media/video/hdpvr/Makefile
@@ -0,0 +1,9 @@
+hdpvr-objs := hdpvr-control.o hdpvr-core.o hdpvr-video.o
+
+hdpvr-$(CONFIG_I2C) += hdpvr-i2c.o
+
+obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o
+
+EXTRA_CFLAGS += -Idrivers/media/video
+
+EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/hdpvr/hdpvr-control.c b/drivers/media/video/hdpvr/hdpvr-control.c
new file mode 100644
index 000000000000..06791749d1a0
--- /dev/null
+++ b/drivers/media/video/hdpvr/hdpvr-control.c
@@ -0,0 +1,201 @@
+/*
+ * Hauppauge HD PVR USB driver - video 4 linux 2 interface
+ *
+ * Copyright (C) 2008 Janne Grunau (j@jannau.net)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+
+#include <linux/videodev2.h>
+
+#include <media/v4l2-common.h>
+
+#include "hdpvr.h"
+
+
+int hdpvr_config_call(struct hdpvr_device *dev, uint value, u8 valbuf)
+{
+ int ret;
+ char request_type = 0x38, snd_request = 0x01;
+
+ msleep(10);
+
+ mutex_lock(&dev->usbc_mutex);
+ dev->usbc_buf[0] = valbuf;
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ snd_request, 0x00 | request_type,
+ value, CTRL_DEFAULT_INDEX,
+ dev->usbc_buf, 1, 10000);
+
+ mutex_unlock(&dev->usbc_mutex);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "config call request for value 0x%x returned %d\n", value,
+ ret);
+
+ return ret < 0 ? ret : 0;
+}
+
+struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev)
+{
+ struct hdpvr_video_info *vidinf = NULL;
+#ifdef HDPVR_DEBUG
+ char print_buf[15];
+#endif
+ int ret;
+
+ vidinf = kzalloc(sizeof(struct hdpvr_video_info), GFP_KERNEL);
+ if (!vidinf) {
+ v4l2_err(&dev->v4l2_dev, "out of memory\n");
+ goto err;
+ }
+
+ mutex_lock(&dev->usbc_mutex);
+ ret = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ 0x81, 0x80 | 0x38,
+ 0x1400, 0x0003,
+ dev->usbc_buf, 5,
+ 1000);
+ if (ret == 5) {
+ vidinf->width = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
+ vidinf->height = dev->usbc_buf[3] << 8 | dev->usbc_buf[2];
+ vidinf->fps = dev->usbc_buf[4];
+ }
+
+#ifdef HDPVR_DEBUG
+ if (hdpvr_debug & MSG_INFO) {
+ hex_dump_to_buffer(dev->usbc_buf, 5, 16, 1, print_buf,
+ sizeof(print_buf), 0);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "get video info returned: %d, %s\n", ret, print_buf);
+ }
+#endif
+ mutex_unlock(&dev->usbc_mutex);
+
+ if (!vidinf->width || !vidinf->height || !vidinf->fps) {
+ kfree(vidinf);
+ vidinf = NULL;
+ }
+err:
+ return vidinf;
+}
+
+int get_input_lines_info(struct hdpvr_device *dev)
+{
+#ifdef HDPVR_DEBUG
+ char print_buf[9];
+#endif
+ int ret, lines;
+
+ mutex_lock(&dev->usbc_mutex);
+ ret = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ 0x81, 0x80 | 0x38,
+ 0x1800, 0x0003,
+ dev->usbc_buf, 3,
+ 1000);
+
+#ifdef HDPVR_DEBUG
+ if (hdpvr_debug & MSG_INFO) {
+ hex_dump_to_buffer(dev->usbc_buf, 3, 16, 1, print_buf,
+ sizeof(print_buf), 0);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "get input lines info returned: %d, %s\n", ret,
+ print_buf);
+ }
+#endif
+ lines = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
+ mutex_unlock(&dev->usbc_mutex);
+ return lines;
+}
+
+
+int hdpvr_set_bitrate(struct hdpvr_device *dev)
+{
+ int ret;
+
+ mutex_lock(&dev->usbc_mutex);
+ memset(dev->usbc_buf, 0, 4);
+ dev->usbc_buf[0] = dev->options.bitrate;
+ dev->usbc_buf[2] = dev->options.peak_bitrate;
+
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0x01, 0x38, CTRL_BITRATE_VALUE,
+ CTRL_DEFAULT_INDEX, dev->usbc_buf, 4, 1000);
+ mutex_unlock(&dev->usbc_mutex);
+
+ return ret;
+}
+
+int hdpvr_set_audio(struct hdpvr_device *dev, u8 input,
+ enum v4l2_mpeg_audio_encoding codec)
+{
+ int ret = 0;
+
+ if (dev->flags & HDPVR_FLAG_AC3_CAP) {
+ mutex_lock(&dev->usbc_mutex);
+ memset(dev->usbc_buf, 0, 2);
+ dev->usbc_buf[0] = input;
+ if (codec == V4L2_MPEG_AUDIO_ENCODING_AAC)
+ dev->usbc_buf[1] = 0;
+ else if (codec == V4L2_MPEG_AUDIO_ENCODING_AC3)
+ dev->usbc_buf[1] = 1;
+ else {
+ mutex_unlock(&dev->usbc_mutex);
+ v4l2_err(&dev->v4l2_dev, "invalid audio codec %d\n",
+ codec);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0x01, 0x38, CTRL_AUDIO_INPUT_VALUE,
+ CTRL_DEFAULT_INDEX, dev->usbc_buf, 2,
+ 1000);
+ mutex_unlock(&dev->usbc_mutex);
+ if (ret == 2)
+ ret = 0;
+ } else
+ ret = hdpvr_config_call(dev, CTRL_AUDIO_INPUT_VALUE,
+ dev->options.audio_input+1);
+error:
+ return ret;
+}
+
+int hdpvr_set_options(struct hdpvr_device *dev)
+{
+ hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, dev->options.video_std);
+
+ hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE,
+ dev->options.video_input+1);
+
+ hdpvr_set_audio(dev, dev->options.audio_input+1,
+ dev->options.audio_codec);
+
+ hdpvr_set_bitrate(dev);
+ hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
+ dev->options.bitrate_mode);
+ hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, dev->options.gop_mode);
+
+ hdpvr_config_call(dev, CTRL_BRIGHTNESS, dev->options.brightness);
+ hdpvr_config_call(dev, CTRL_CONTRAST, dev->options.contrast);
+ hdpvr_config_call(dev, CTRL_HUE, dev->options.hue);
+ hdpvr_config_call(dev, CTRL_SATURATION, dev->options.saturation);
+ hdpvr_config_call(dev, CTRL_SHARPNESS, dev->options.sharpness);
+
+ return 0;
+}
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
new file mode 100644
index 000000000000..188bd5aea258
--- /dev/null
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -0,0 +1,466 @@
+/*
+ * Hauppauge HD PVR USB driver
+ *
+ * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2008 Janne Grunau (j@jannau.net)
+ * Copyright (C) 2008 John Poet
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+#include <linux/i2c.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-common.h>
+
+#include "hdpvr.h"
+
+static int video_nr[HDPVR_MAX] = {[0 ... (HDPVR_MAX - 1)] = UNSET};
+module_param_array(video_nr, int, NULL, 0);
+MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)");
+
+/* holds the number of currently registered devices */
+static atomic_t dev_nr = ATOMIC_INIT(-1);
+
+int hdpvr_debug;
+module_param(hdpvr_debug, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(hdpvr_debug, "enable debugging output");
+
+uint default_video_input = HDPVR_VIDEO_INPUTS;
+module_param(default_video_input, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / "
+ "1=S-Video / 2=Composite");
+
+uint default_audio_input = HDPVR_AUDIO_INPUTS;
+module_param(default_audio_input, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / "
+ "1=RCA front / 2=S/PDIF");
+
+static int boost_audio;
+module_param(boost_audio, bool, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(boost_audio, "boost the audio signal");
+
+
+/* table of devices that work with this driver */
+static struct usb_device_id hdpvr_table[] = {
+ { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID) },
+ { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) },
+ { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, hdpvr_table);
+
+
+void hdpvr_delete(struct hdpvr_device *dev)
+{
+ hdpvr_free_buffers(dev);
+
+ if (dev->video_dev)
+ video_device_release(dev->video_dev);
+
+ usb_put_dev(dev->udev);
+}
+
+static void challenge(u8 *bytes)
+{
+ u64 *i64P, tmp64;
+ uint i, idx;
+
+ for (idx = 0; idx < 32; ++idx) {
+
+ if (idx & 0x3)
+ bytes[(idx >> 3) + 3] = bytes[(idx >> 2) & 0x3];
+
+ switch (idx & 0x3) {
+ case 0x3:
+ bytes[2] += bytes[3] * 4 + bytes[4] + bytes[5];
+ bytes[4] += bytes[(idx & 0x1) * 2] * 9 + 9;
+ break;
+ case 0x1:
+ bytes[0] *= 8;
+ bytes[0] += 7*idx + 4;
+ bytes[6] += bytes[3] * 3;
+ break;
+ case 0x0:
+ bytes[3 - (idx >> 3)] = bytes[idx >> 2];
+ bytes[5] += bytes[6] * 3;
+ for (i = 0; i < 3; i++)
+ bytes[3] *= bytes[3] + 1;
+ break;
+ case 0x2:
+ for (i = 0; i < 3; i++)
+ bytes[1] *= bytes[6] + 1;
+ for (i = 0; i < 3; i++) {
+ i64P = (u64 *)bytes;
+ tmp64 = le64_to_cpup(i64P);
+ tmp64 <<= bytes[7] & 0x0f;
+ *i64P += cpu_to_le64(tmp64);
+ }
+ break;
+ }
+ }
+}
+
+/* try to init the device like the windows driver */
+static int device_authorization(struct hdpvr_device *dev)
+{
+
+ int ret, retval = -ENOMEM;
+ char request_type = 0x38, rcv_request = 0x81;
+ char *response;
+#ifdef HDPVR_DEBUG
+ size_t buf_size = 46;
+ char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL);
+ if (!print_buf) {
+ v4l2_err(&dev->v4l2_dev, "Out of memory\n");
+ goto error;
+ }
+#endif
+
+ mutex_lock(&dev->usbc_mutex);
+ ret = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ rcv_request, 0x80 | request_type,
+ 0x0400, 0x0003,
+ dev->usbc_buf, 46,
+ 10000);
+ if (ret != 46) {
+ v4l2_err(&dev->v4l2_dev,
+ "unexpected answer of status request, len %d\n", ret);
+ goto error;
+ }
+#ifdef HDPVR_DEBUG
+ else {
+ hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf,
+ sizeof(print_buf), 0);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "Status request returned, len %d: %s\n",
+ ret, print_buf);
+ }
+#endif
+ if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION) {
+ dev->flags &= ~HDPVR_FLAG_AC3_CAP;
+ } else if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION_AC3) {
+ dev->flags |= HDPVR_FLAG_AC3_CAP;
+ } else if (dev->usbc_buf[1] > HDPVR_FIRMWARE_VERSION_AC3) {
+ v4l2_info(&dev->v4l2_dev, "untested firmware version 0x%x, "
+ "the driver might not work\n", dev->usbc_buf[1]);
+ dev->flags |= HDPVR_FLAG_AC3_CAP;
+ } else {
+ v4l2_err(&dev->v4l2_dev, "unknown firmware version 0x%x\n",
+ dev->usbc_buf[1]);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ response = dev->usbc_buf+38;
+#ifdef HDPVR_DEBUG
+ hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, "challenge: %s\n",
+ print_buf);
+#endif
+ challenge(response);
+#ifdef HDPVR_DEBUG
+ hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n",
+ print_buf);
+#endif
+
+ msleep(100);
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0xd1, 0x00 | request_type,
+ 0x0000, 0x0000,
+ response, 8,
+ 10000);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "magic request returned %d\n", ret);
+ mutex_unlock(&dev->usbc_mutex);
+
+ retval = ret != 8;
+error:
+ return retval;
+}
+
+static int hdpvr_device_init(struct hdpvr_device *dev)
+{
+ int ret;
+ u8 *buf;
+ struct hdpvr_video_info *vidinf;
+
+ if (device_authorization(dev))
+ return -EACCES;
+
+ /* default options for init */
+ hdpvr_set_options(dev);
+
+ /* set filter options */
+ mutex_lock(&dev->usbc_mutex);
+ buf = dev->usbc_buf;
+ buf[0] = 0x03; buf[1] = 0x03; buf[2] = 0x00; buf[3] = 0x00;
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0x01, 0x38,
+ CTRL_LOW_PASS_FILTER_VALUE, CTRL_DEFAULT_INDEX,
+ buf, 4,
+ 1000);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "control request returned %d\n", ret);
+ mutex_unlock(&dev->usbc_mutex);
+
+ vidinf = get_video_info(dev);
+ if (!vidinf)
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "no valid video signal or device init failed\n");
+ else
+ kfree(vidinf);
+
+ /* enable fan and bling leds */
+ mutex_lock(&dev->usbc_mutex);
+ buf[0] = 0x1;
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0xd4, 0x38, 0, 0, buf, 1,
+ 1000);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "control request returned %d\n", ret);
+
+ /* boost analog audio */
+ buf[0] = boost_audio;
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0xd5, 0x38, 0, 0, buf, 1,
+ 1000);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "control request returned %d\n", ret);
+ mutex_unlock(&dev->usbc_mutex);
+
+ dev->status = STATUS_IDLE;
+ return 0;
+}
+
+static const struct hdpvr_options hdpvr_default_options = {
+ .video_std = HDPVR_60HZ,
+ .video_input = HDPVR_COMPONENT,
+ .audio_input = HDPVR_RCA_BACK,
+ .bitrate = 65, /* 6 mbps */
+ .peak_bitrate = 90, /* 9 mbps */
+ .bitrate_mode = HDPVR_CONSTANT,
+ .gop_mode = HDPVR_SIMPLE_IDR_GOP,
+ .audio_codec = V4L2_MPEG_AUDIO_ENCODING_AAC,
+ .brightness = 0x86,
+ .contrast = 0x80,
+ .hue = 0x80,
+ .saturation = 0x80,
+ .sharpness = 0x80,
+};
+
+static int hdpvr_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct hdpvr_device *dev;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ size_t buffer_size;
+ int i;
+ int retval = -ENOMEM;
+
+ /* allocate memory for our device state and initialize it */
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ err("Out of memory");
+ goto error;
+ }
+
+ /* register v4l2_device early so it can be used for printks */
+ if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
+ err("v4l2_device_register failed");
+ goto error;
+ }
+
+ mutex_init(&dev->io_mutex);
+ mutex_init(&dev->i2c_mutex);
+ mutex_init(&dev->usbc_mutex);
+ dev->usbc_buf = kmalloc(64, GFP_KERNEL);
+ if (!dev->usbc_buf) {
+ v4l2_err(&dev->v4l2_dev, "Out of memory\n");
+ goto error;
+ }
+
+ init_waitqueue_head(&dev->wait_buffer);
+ init_waitqueue_head(&dev->wait_data);
+
+ dev->workqueue = create_singlethread_workqueue("hdpvr_buffer");
+ if (!dev->workqueue)
+ goto error;
+
+ /* init video transfer queues */
+ INIT_LIST_HEAD(&dev->free_buff_list);
+ INIT_LIST_HEAD(&dev->rec_buff_list);
+
+ dev->options = hdpvr_default_options;
+
+ if (default_video_input < HDPVR_VIDEO_INPUTS)
+ dev->options.video_input = default_video_input;
+
+ if (default_audio_input < HDPVR_AUDIO_INPUTS)
+ dev->options.audio_input = default_audio_input;
+
+ dev->udev = usb_get_dev(interface_to_usbdev(interface));
+
+ /* set up the endpoint information */
+ /* use only the first bulk-in and bulk-out endpoints */
+ iface_desc = interface->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ if (!dev->bulk_in_endpointAddr &&
+ usb_endpoint_is_bulk_in(endpoint)) {
+ /* USB interface description is buggy, reported max
+ * packet size is 512 bytes, windows driver uses 8192 */
+ buffer_size = 8192;
+ dev->bulk_in_size = buffer_size;
+ dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
+ }
+
+ }
+ if (!dev->bulk_in_endpointAddr) {
+ v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n");
+ goto error;
+ }
+
+ /* init the device */
+ if (hdpvr_device_init(dev)) {
+ v4l2_err(&dev->v4l2_dev, "device init failed\n");
+ goto error;
+ }
+
+ mutex_lock(&dev->io_mutex);
+ if (hdpvr_alloc_buffers(dev, NUM_BUFFERS)) {
+ v4l2_err(&dev->v4l2_dev,
+ "allocating transfer buffers failed\n");
+ goto error;
+ }
+ mutex_unlock(&dev->io_mutex);
+
+ if (hdpvr_register_videodev(dev, &interface->dev,
+ video_nr[atomic_inc_return(&dev_nr)])) {
+ v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
+ goto error;
+ }
+
+#ifdef CONFIG_I2C
+ /* until i2c is working properly */
+ retval = 0; /* hdpvr_register_i2c_adapter(dev); */
+ if (retval < 0) {
+ v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n");
+ goto error;
+ }
+#endif /* CONFIG_I2C */
+
+ /* save our data pointer in this interface device */
+ usb_set_intfdata(interface, dev);
+
+ /* let the user know what node this device is now attached to */
+ v4l2_info(&dev->v4l2_dev, "device now attached to /dev/video%d\n",
+ dev->video_dev->minor);
+ return 0;
+
+error:
+ if (dev) {
+ mutex_unlock(&dev->io_mutex);
+ /* this frees allocated memory */
+ hdpvr_delete(dev);
+ }
+ return retval;
+}
+
+static void hdpvr_disconnect(struct usb_interface *interface)
+{
+ struct hdpvr_device *dev;
+ int minor;
+
+ dev = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
+
+ minor = dev->video_dev->minor;
+
+ /* prevent more I/O from starting and stop any ongoing */
+ mutex_lock(&dev->io_mutex);
+ dev->status = STATUS_DISCONNECTED;
+ v4l2_device_disconnect(&dev->v4l2_dev);
+ video_unregister_device(dev->video_dev);
+ wake_up_interruptible(&dev->wait_data);
+ wake_up_interruptible(&dev->wait_buffer);
+ mutex_unlock(&dev->io_mutex);
+ msleep(100);
+ flush_workqueue(dev->workqueue);
+ mutex_lock(&dev->io_mutex);
+ hdpvr_cancel_queue(dev);
+ destroy_workqueue(dev->workqueue);
+ mutex_unlock(&dev->io_mutex);
+
+ /* deregister I2C adapter */
+#ifdef CONFIG_I2C
+ mutex_lock(&dev->i2c_mutex);
+ if (dev->i2c_adapter)
+ i2c_del_adapter(dev->i2c_adapter);
+ kfree(dev->i2c_adapter);
+ dev->i2c_adapter = NULL;
+ mutex_unlock(&dev->i2c_mutex);
+#endif /* CONFIG_I2C */
+
+ atomic_dec(&dev_nr);
+
+ v4l2_info(&dev->v4l2_dev, "device /dev/video%d disconnected\n", minor);
+
+ v4l2_device_unregister(&dev->v4l2_dev);
+ kfree(dev->usbc_buf);
+ kfree(dev);
+}
+
+
+static struct usb_driver hdpvr_usb_driver = {
+ .name = "hdpvr",
+ .probe = hdpvr_probe,
+ .disconnect = hdpvr_disconnect,
+ .id_table = hdpvr_table,
+};
+
+static int __init hdpvr_init(void)
+{
+ int result;
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&hdpvr_usb_driver);
+ if (result)
+ err("usb_register failed. Error number %d", result);
+
+ return result;
+}
+
+static void __exit hdpvr_exit(void)
+{
+ /* deregister this driver with the USB subsystem */
+ usb_deregister(&hdpvr_usb_driver);
+}
+
+module_init(hdpvr_init);
+module_exit(hdpvr_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Janne Grunau");
+MODULE_DESCRIPTION("Hauppauge HD PVR driver");
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
new file mode 100644
index 000000000000..c4b5d1515c10
--- /dev/null
+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
@@ -0,0 +1,145 @@
+
+/*
+ * Hauppauge HD PVR USB driver
+ *
+ * Copyright (C) 2008 Janne Grunau (j@jannau.net)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <linux/i2c.h>
+
+#include "hdpvr.h"
+
+#define CTRL_READ_REQUEST 0xb8
+#define CTRL_WRITE_REQUEST 0x38
+
+#define REQTYPE_I2C_READ 0xb1
+#define REQTYPE_I2C_WRITE 0xb0
+#define REQTYPE_I2C_WRITE_STATT 0xd0
+
+static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr,
+ char *data, int len)
+{
+ int ret;
+ char *buf = kmalloc(len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ ret = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ REQTYPE_I2C_READ, CTRL_READ_REQUEST,
+ 0x100|addr, 0, buf, len, 1000);
+
+ if (ret == len) {
+ memcpy(data, buf, len);
+ ret = 0;
+ } else if (ret >= 0)
+ ret = -EIO;
+
+ kfree(buf);
+
+ return ret;
+}
+
+static int hdpvr_i2c_write(struct hdpvr_device *dev, unsigned char addr,
+ char *data, int len)
+{
+ int ret;
+ char *buf = kmalloc(len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ memcpy(buf, data, len);
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
+ 0x100|addr, 0, buf, len, 1000);
+
+ if (ret < 0)
+ goto error;
+
+ ret = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
+ 0, 0, buf, 2, 1000);
+
+ if (ret == 2)
+ ret = 0;
+ else if (ret >= 0)
+ ret = -EIO;
+
+error:
+ kfree(buf);
+ return ret;
+}
+
+static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs,
+ int num)
+{
+ struct hdpvr_device *dev = i2c_get_adapdata(i2c_adapter);
+ int retval = 0, i, addr;
+
+ if (num <= 0)
+ return 0;
+
+ mutex_lock(&dev->i2c_mutex);
+
+ for (i = 0; i < num && !retval; i++) {
+ addr = msgs[i].addr << 1;
+
+ if (msgs[i].flags & I2C_M_RD)
+ retval = hdpvr_i2c_read(dev, addr, msgs[i].buf,
+ msgs[i].len);
+ else
+ retval = hdpvr_i2c_write(dev, addr, msgs[i].buf,
+ msgs[i].len);
+ }
+
+ mutex_unlock(&dev->i2c_mutex);
+
+ return retval ? retval : num;
+}
+
+static u32 hdpvr_functionality(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm hdpvr_algo = {
+ .master_xfer = hdpvr_transfer,
+ .functionality = hdpvr_functionality,
+};
+
+int hdpvr_register_i2c_adapter(struct hdpvr_device *dev)
+{
+ struct i2c_adapter *i2c_adap;
+ int retval = -ENOMEM;
+
+ i2c_adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
+ if (i2c_adap == NULL)
+ goto error;
+
+ strlcpy(i2c_adap->name, "Hauppauge HD PVR I2C",
+ sizeof(i2c_adap->name));
+ i2c_adap->algo = &hdpvr_algo;
+ i2c_adap->class = I2C_CLASS_TV_ANALOG;
+ i2c_adap->id = I2C_HW_B_HDPVR;
+ i2c_adap->owner = THIS_MODULE;
+ i2c_adap->dev.parent = &dev->udev->dev;
+
+ i2c_set_adapdata(i2c_adap, dev);
+
+ retval = i2c_add_adapter(i2c_adap);
+
+ if (!retval)
+ dev->i2c_adapter = i2c_adap;
+ else
+ kfree(i2c_adap);
+
+error:
+ return retval;
+}
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
new file mode 100644
index 000000000000..3e6ffee8dfed
--- /dev/null
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -0,0 +1,1248 @@
+/*
+ * Hauppauge HD PVR USB driver - video 4 linux 2 interface
+ *
+ * Copyright (C) 2008 Janne Grunau (j@jannau.net)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+#include <linux/version.h>
+#include <linux/workqueue.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include "hdpvr.h"
+
+#define BULK_URB_TIMEOUT 1250 /* 1.25 seconds */
+
+#define print_buffer_status() { \
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, \
+ "%s:%d buffer stat: %d free, %d proc\n", \
+ __func__, __LINE__, \
+ list_size(&dev->free_buff_list), \
+ list_size(&dev->rec_buff_list)); }
+
+struct hdpvr_fh {
+ struct hdpvr_device *dev;
+};
+
+static uint list_size(struct list_head *list)
+{
+ struct list_head *tmp;
+ uint count = 0;
+
+ list_for_each(tmp, list) {
+ count++;
+ }
+
+ return count;
+}
+
+/*=========================================================================*/
+/* urb callback */
+static void hdpvr_read_bulk_callback(struct urb *urb)
+{
+ struct hdpvr_buffer *buf = (struct hdpvr_buffer *)urb->context;
+ struct hdpvr_device *dev = buf->dev;
+
+ /* marking buffer as received and wake waiting */
+ buf->status = BUFSTAT_READY;
+ wake_up_interruptible(&dev->wait_data);
+}
+
+/*=========================================================================*/
+/* bufffer bits */
+
+/* function expects dev->io_mutex to be hold by caller */
+int hdpvr_cancel_queue(struct hdpvr_device *dev)
+{
+ struct hdpvr_buffer *buf;
+
+ list_for_each_entry(buf, &dev->rec_buff_list, buff_list) {
+ usb_kill_urb(buf->urb);
+ buf->status = BUFSTAT_AVAILABLE;
+ }
+
+ list_splice_init(&dev->rec_buff_list, dev->free_buff_list.prev);
+
+ return 0;
+}
+
+static int hdpvr_free_queue(struct list_head *q)
+{
+ struct list_head *tmp;
+ struct list_head *p;
+ struct hdpvr_buffer *buf;
+ struct urb *urb;
+
+ for (p = q->next; p != q;) {
+ buf = list_entry(p, struct hdpvr_buffer, buff_list);
+
+ urb = buf->urb;
+ usb_buffer_free(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
+ usb_free_urb(urb);
+ tmp = p->next;
+ list_del(p);
+ kfree(buf);
+ p = tmp;
+ }
+
+ return 0;
+}
+
+/* function expects dev->io_mutex to be hold by caller */
+int hdpvr_free_buffers(struct hdpvr_device *dev)
+{
+ hdpvr_cancel_queue(dev);
+
+ hdpvr_free_queue(&dev->free_buff_list);
+ hdpvr_free_queue(&dev->rec_buff_list);
+
+ return 0;
+}
+
+/* function expects dev->io_mutex to be hold by caller */
+int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
+{
+ uint i;
+ int retval = -ENOMEM;
+ u8 *mem;
+ struct hdpvr_buffer *buf;
+ struct urb *urb;
+
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "allocating %u buffers\n", count);
+
+ for (i = 0; i < count; i++) {
+
+ buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL);
+ if (!buf) {
+ v4l2_err(&dev->v4l2_dev, "cannot allocate buffer\n");
+ goto exit;
+ }
+ buf->dev = dev;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n");
+ goto exit;
+ }
+ buf->urb = urb;
+
+ mem = usb_buffer_alloc(dev->udev, dev->bulk_in_size, GFP_KERNEL,
+ &urb->transfer_dma);
+ if (!mem) {
+ v4l2_err(&dev->v4l2_dev,
+ "cannot allocate usb transfer buffer\n");
+ goto exit;
+ }
+
+ usb_fill_bulk_urb(buf->urb, dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+ dev->bulk_in_endpointAddr),
+ mem, dev->bulk_in_size,
+ hdpvr_read_bulk_callback, buf);
+
+ buf->status = BUFSTAT_AVAILABLE;
+ list_add_tail(&buf->buff_list, &dev->free_buff_list);
+ }
+ return 0;
+exit:
+ hdpvr_free_buffers(dev);
+ return retval;
+}
+
+static int hdpvr_submit_buffers(struct hdpvr_device *dev)
+{
+ struct hdpvr_buffer *buf;
+ struct urb *urb;
+ int ret = 0, err_count = 0;
+
+ mutex_lock(&dev->io_mutex);
+
+ while (dev->status == STATUS_STREAMING &&
+ !list_empty(&dev->free_buff_list)) {
+
+ buf = list_entry(dev->free_buff_list.next, struct hdpvr_buffer,
+ buff_list);
+ if (buf->status != BUFSTAT_AVAILABLE) {
+ v4l2_err(&dev->v4l2_dev,
+ "buffer not marked as availbale\n");
+ ret = -EFAULT;
+ goto err;
+ }
+
+ urb = buf->urb;
+ urb->status = 0;
+ urb->actual_length = 0;
+ ret = usb_submit_urb(urb, GFP_KERNEL);
+ if (ret) {
+ v4l2_err(&dev->v4l2_dev,
+ "usb_submit_urb in %s returned %d\n",
+ __func__, ret);
+ if (++err_count > 2)
+ break;
+ continue;
+ }
+ buf->status = BUFSTAT_INPROGRESS;
+ list_move_tail(&buf->buff_list, &dev->rec_buff_list);
+ }
+err:
+ print_buffer_status();
+ mutex_unlock(&dev->io_mutex);
+ return ret;
+}
+
+static struct hdpvr_buffer *hdpvr_get_next_buffer(struct hdpvr_device *dev)
+{
+ struct hdpvr_buffer *buf;
+
+ mutex_lock(&dev->io_mutex);
+
+ if (list_empty(&dev->rec_buff_list)) {
+ mutex_unlock(&dev->io_mutex);
+ return NULL;
+ }
+
+ buf = list_entry(dev->rec_buff_list.next, struct hdpvr_buffer,
+ buff_list);
+ mutex_unlock(&dev->io_mutex);
+
+ return buf;
+}
+
+static void hdpvr_transmit_buffers(struct work_struct *work)
+{
+ struct hdpvr_device *dev = container_of(work, struct hdpvr_device,
+ worker);
+
+ while (dev->status == STATUS_STREAMING) {
+
+ if (hdpvr_submit_buffers(dev)) {
+ v4l2_err(&dev->v4l2_dev, "couldn't submit buffers\n");
+ goto error;
+ }
+ if (wait_event_interruptible(dev->wait_buffer,
+ !list_empty(&dev->free_buff_list) ||
+ dev->status != STATUS_STREAMING))
+ goto error;
+ }
+
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "transmit worker exited\n");
+ return;
+error:
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "transmit buffers errored\n");
+ dev->status = STATUS_ERROR;
+}
+
+/* function expects dev->io_mutex to be hold by caller */
+static int hdpvr_start_streaming(struct hdpvr_device *dev)
+{
+ int ret;
+ struct hdpvr_video_info *vidinf;
+
+ if (dev->status == STATUS_STREAMING)
+ return 0;
+ else if (dev->status != STATUS_IDLE)
+ return -EAGAIN;
+
+ vidinf = get_video_info(dev);
+
+ if (vidinf) {
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "video signal: %dx%d@%dhz\n", vidinf->width,
+ vidinf->height, vidinf->fps);
+ kfree(vidinf);
+
+ /* start streaming 2 request */
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "encoder start control request returned %d\n", ret);
+
+ hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
+
+ INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
+ queue_work(dev->workqueue, &dev->worker);
+
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "streaming started\n");
+ dev->status = STATUS_STREAMING;
+
+ return 0;
+ }
+ msleep(250);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "no video signal at input %d\n", dev->options.video_input);
+ return -EAGAIN;
+}
+
+
+/* function expects dev->io_mutex to be hold by caller */
+static int hdpvr_stop_streaming(struct hdpvr_device *dev)
+{
+ uint actual_length, c = 0;
+ u8 *buf;
+
+ if (dev->status == STATUS_IDLE)
+ return 0;
+ else if (dev->status != STATUS_STREAMING)
+ return -EAGAIN;
+
+ buf = kmalloc(dev->bulk_in_size, GFP_KERNEL);
+ if (!buf)
+ v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer "
+ "for emptying the internal device buffer. "
+ "Next capture start will be slow\n");
+
+ dev->status = STATUS_SHUTTING_DOWN;
+ hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00);
+ mutex_unlock(&dev->io_mutex);
+
+ wake_up_interruptible(&dev->wait_buffer);
+ msleep(50);
+
+ flush_workqueue(dev->workqueue);
+
+ mutex_lock(&dev->io_mutex);
+ /* kill the still outstanding urbs */
+ hdpvr_cancel_queue(dev);
+
+ /* emptying the device buffer beforeshutting it down */
+ while (buf && ++c < 500 &&
+ !usb_bulk_msg(dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+ dev->bulk_in_endpointAddr),
+ buf, dev->bulk_in_size, &actual_length,
+ BULK_URB_TIMEOUT)) {
+ /* wait */
+ msleep(5);
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "%2d: got %d bytes\n", c, actual_length);
+ }
+ kfree(buf);
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "used %d urbs to empty device buffers\n", c-1);
+ msleep(10);
+
+ dev->status = STATUS_IDLE;
+
+ return 0;
+}
+
+
+/*=======================================================================*/
+/*
+ * video 4 linux 2 file operations
+ */
+
+static int hdpvr_open(struct file *file)
+{
+ struct hdpvr_device *dev;
+ struct hdpvr_fh *fh;
+ int retval = -ENOMEM;
+
+ dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file));
+ if (!dev) {
+ v4l2_err(&dev->v4l2_dev, "open failing with with ENODEV\n");
+ retval = -ENODEV;
+ goto err;
+ }
+
+ fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL);
+ if (!fh) {
+ v4l2_err(&dev->v4l2_dev, "Out of memory\n");
+ goto err;
+ }
+ /* lock the device to allow correctly handling errors
+ * in resumption */
+ mutex_lock(&dev->io_mutex);
+ dev->open_count++;
+
+ fh->dev = dev;
+
+ /* save our object in the file's private structure */
+ file->private_data = fh;
+
+ retval = 0;
+err:
+ mutex_unlock(&dev->io_mutex);
+ return retval;
+}
+
+static int hdpvr_release(struct file *file)
+{
+ struct hdpvr_fh *fh = (struct hdpvr_fh *)file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->io_mutex);
+ if (!(--dev->open_count) && dev->status == STATUS_STREAMING)
+ hdpvr_stop_streaming(dev);
+
+ mutex_unlock(&dev->io_mutex);
+
+ return 0;
+}
+
+/*
+ * hdpvr_v4l2_read()
+ * will allocate buffers when called for the first time
+ */
+static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
+ loff_t *pos)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ struct hdpvr_buffer *buf = NULL;
+ struct urb *urb;
+ unsigned int ret = 0;
+ int rem, cnt;
+
+ if (*pos)
+ return -ESPIPE;
+
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->io_mutex);
+ if (dev->status == STATUS_IDLE) {
+ if (hdpvr_start_streaming(dev)) {
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "start_streaming failed\n");
+ ret = -EIO;
+ msleep(200);
+ dev->status = STATUS_IDLE;
+ mutex_unlock(&dev->io_mutex);
+ goto err;
+ }
+ print_buffer_status();
+ }
+ mutex_unlock(&dev->io_mutex);
+
+ /* wait for the first buffer */
+ if (!(file->f_flags & O_NONBLOCK)) {
+ if (wait_event_interruptible(dev->wait_data,
+ hdpvr_get_next_buffer(dev)))
+ return -ERESTARTSYS;
+ }
+
+ buf = hdpvr_get_next_buffer(dev);
+
+ while (count > 0 && buf) {
+
+ if (buf->status != BUFSTAT_READY &&
+ dev->status != STATUS_DISCONNECTED) {
+ /* return nonblocking */
+ if (file->f_flags & O_NONBLOCK) {
+ if (!ret)
+ ret = -EAGAIN;
+ goto err;
+ }
+
+ if (wait_event_interruptible(dev->wait_data,
+ buf->status == BUFSTAT_READY)) {
+ ret = -ERESTARTSYS;
+ goto err;
+ }
+ }
+
+ if (buf->status != BUFSTAT_READY)
+ break;
+
+ /* set remaining bytes to copy */
+ urb = buf->urb;
+ rem = urb->actual_length - buf->pos;
+ cnt = rem > count ? count : rem;
+
+ if (copy_to_user(buffer, urb->transfer_buffer + buf->pos,
+ cnt)) {
+ v4l2_err(&dev->v4l2_dev, "read: copy_to_user failed\n");
+ if (!ret)
+ ret = -EFAULT;
+ goto err;
+ }
+
+ buf->pos += cnt;
+ count -= cnt;
+ buffer += cnt;
+ ret += cnt;
+
+ /* finished, take next buffer */
+ if (buf->pos == urb->actual_length) {
+ mutex_lock(&dev->io_mutex);
+ buf->pos = 0;
+ buf->status = BUFSTAT_AVAILABLE;
+
+ list_move_tail(&buf->buff_list, &dev->free_buff_list);
+
+ print_buffer_status();
+
+ mutex_unlock(&dev->io_mutex);
+
+ wake_up_interruptible(&dev->wait_buffer);
+
+ buf = hdpvr_get_next_buffer(dev);
+ }
+ }
+err:
+ if (!ret && !buf)
+ ret = -EAGAIN;
+ return ret;
+}
+
+static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
+{
+ struct hdpvr_buffer *buf = NULL;
+ struct hdpvr_fh *fh = (struct hdpvr_fh *)filp->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ unsigned int mask = 0;
+
+ mutex_lock(&dev->io_mutex);
+
+ if (video_is_unregistered(dev->video_dev))
+ return -EIO;
+
+ if (dev->status == STATUS_IDLE) {
+ if (hdpvr_start_streaming(dev)) {
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "start_streaming failed\n");
+ dev->status = STATUS_IDLE;
+ }
+
+ print_buffer_status();
+ }
+ mutex_unlock(&dev->io_mutex);
+
+ buf = hdpvr_get_next_buffer(dev);
+ /* only wait if no data is available */
+ if (!buf || buf->status != BUFSTAT_READY) {
+ poll_wait(filp, &dev->wait_data, wait);
+ buf = hdpvr_get_next_buffer(dev);
+ }
+ if (buf && buf->status == BUFSTAT_READY)
+ mask |= POLLIN | POLLRDNORM;
+
+ return mask;
+}
+
+
+static const struct v4l2_file_operations hdpvr_fops = {
+ .owner = THIS_MODULE,
+ .open = hdpvr_open,
+ .release = hdpvr_release,
+ .read = hdpvr_read,
+ .poll = hdpvr_poll,
+ .unlocked_ioctl = video_ioctl2,
+};
+
+/*=======================================================================*/
+/*
+ * V4L2 ioctl handling
+ */
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct hdpvr_device *dev = video_drvdata(file);
+
+ strcpy(cap->driver, "hdpvr");
+ strcpy(cap->card, "Haupauge HD PVR");
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
+ cap->version = HDPVR_VERSION;
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_AUDIO |
+ V4L2_CAP_READWRITE;
+ return 0;
+}
+
+static int vidioc_s_std(struct file *file, void *private_data,
+ v4l2_std_id *std)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ u8 std_type = 1;
+
+ if (*std & (V4L2_STD_NTSC | V4L2_STD_PAL_60))
+ std_type = 0;
+
+ return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type);
+}
+
+static const char *iname[] = {
+ [HDPVR_COMPONENT] = "Component",
+ [HDPVR_SVIDEO] = "S-Video",
+ [HDPVR_COMPOSITE] = "Composite",
+};
+
+static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *i)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ unsigned int n;
+
+ n = i->index;
+ if (n >= HDPVR_VIDEO_INPUTS)
+ return -EINVAL;
+
+ i->type = V4L2_INPUT_TYPE_CAMERA;
+
+ strncpy(i->name, iname[n], sizeof(i->name) - 1);
+ i->name[sizeof(i->name) - 1] = '\0';
+
+ i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF;
+
+ i->std = dev->video_dev->tvnorms;
+
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *private_data,
+ unsigned int index)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int retval;
+
+ if (index >= HDPVR_VIDEO_INPUTS)
+ return -EINVAL;
+
+ if (dev->status != STATUS_IDLE)
+ return -EAGAIN;
+
+ retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1);
+ if (!retval)
+ dev->options.video_input = index;
+
+ return retval;
+}
+
+static int vidioc_g_input(struct file *file, void *private_data,
+ unsigned int *index)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+
+ *index = dev->options.video_input;
+ return 0;
+}
+
+
+static const char *audio_iname[] = {
+ [HDPVR_RCA_FRONT] = "RCA front",
+ [HDPVR_RCA_BACK] = "RCA back",
+ [HDPVR_SPDIF] = "SPDIF",
+};
+
+static int vidioc_enumaudio(struct file *file, void *priv,
+ struct v4l2_audio *audio)
+{
+ unsigned int n;
+
+ n = audio->index;
+ if (n >= HDPVR_AUDIO_INPUTS)
+ return -EINVAL;
+
+ audio->capability = V4L2_AUDCAP_STEREO;
+
+ strncpy(audio->name, audio_iname[n], sizeof(audio->name) - 1);
+ audio->name[sizeof(audio->name) - 1] = '\0';
+
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *private_data,
+ struct v4l2_audio *audio)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int retval;
+
+ if (audio->index >= HDPVR_AUDIO_INPUTS)
+ return -EINVAL;
+
+ if (dev->status != STATUS_IDLE)
+ return -EAGAIN;
+
+ retval = hdpvr_set_audio(dev, audio->index+1, dev->options.audio_codec);
+ if (!retval)
+ dev->options.audio_input = audio->index;
+
+ return retval;
+}
+
+static int vidioc_g_audio(struct file *file, void *private_data,
+ struct v4l2_audio *audio)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+
+ audio->index = dev->options.audio_input;
+ audio->capability = V4L2_AUDCAP_STEREO;
+ strncpy(audio->name, audio_iname[audio->index], sizeof(audio->name));
+ audio->name[sizeof(audio->name) - 1] = '\0';
+ return 0;
+}
+
+static const s32 supported_v4l2_ctrls[] = {
+ V4L2_CID_BRIGHTNESS,
+ V4L2_CID_CONTRAST,
+ V4L2_CID_SATURATION,
+ V4L2_CID_HUE,
+ V4L2_CID_SHARPNESS,
+ V4L2_CID_MPEG_AUDIO_ENCODING,
+ V4L2_CID_MPEG_VIDEO_ENCODING,
+ V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+ V4L2_CID_MPEG_VIDEO_BITRATE,
+ V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+};
+
+static int fill_queryctrl(struct hdpvr_options *opt, struct v4l2_queryctrl *qc,
+ int ac3)
+{
+ int err;
+
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86);
+ case V4L2_CID_CONTRAST:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ case V4L2_CID_HUE:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ case V4L2_CID_SHARPNESS:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ return v4l2_ctrl_query_fill(
+ qc, V4L2_MPEG_AUDIO_ENCODING_AAC,
+ ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3
+ : V4L2_MPEG_AUDIO_ENCODING_AAC,
+ 1, V4L2_MPEG_AUDIO_ENCODING_AAC);
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ return v4l2_ctrl_query_fill(
+ qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC);
+
+/* case V4L2_CID_MPEG_VIDEO_? maybe keyframe interval: */
+/* return v4l2_ctrl_query_fill(qc, 0, 128, 128, 0); */
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ return v4l2_ctrl_query_fill(
+ qc, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
+
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ return v4l2_ctrl_query_fill(qc, 1000000, 13500000, 100000,
+ 6500000);
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ err = v4l2_ctrl_query_fill(qc, 1100000, 20200000, 100000,
+ 9000000);
+ if (!err && opt->bitrate_mode == HDPVR_CONSTANT)
+ qc->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return err;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int vidioc_queryctrl(struct file *file, void *private_data,
+ struct v4l2_queryctrl *qc)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int i, next;
+ u32 id = qc->id;
+
+ memset(qc, 0, sizeof(*qc));
+
+ next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
+ qc->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
+
+ for (i = 0; i < ARRAY_SIZE(supported_v4l2_ctrls); i++) {
+ if (next) {
+ if (qc->id < supported_v4l2_ctrls[i])
+ qc->id = supported_v4l2_ctrls[i];
+ else
+ continue;
+ }
+
+ if (qc->id == supported_v4l2_ctrls[i])
+ return fill_queryctrl(&dev->options, qc,
+ dev->flags & HDPVR_FLAG_AC3_CAP);
+
+ if (qc->id < supported_v4l2_ctrls[i])
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *private_data,
+ struct v4l2_control *ctrl)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = dev->options.brightness;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = dev->options.contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->value = dev->options.saturation;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value = dev->options.hue;
+ break;
+ case V4L2_CID_SHARPNESS:
+ ctrl->value = dev->options.sharpness;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *private_data,
+ struct v4l2_control *ctrl)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int retval;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ retval = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->value);
+ if (!retval)
+ dev->options.brightness = ctrl->value;
+ break;
+ case V4L2_CID_CONTRAST:
+ retval = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->value);
+ if (!retval)
+ dev->options.contrast = ctrl->value;
+ break;
+ case V4L2_CID_SATURATION:
+ retval = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->value);
+ if (!retval)
+ dev->options.saturation = ctrl->value;
+ break;
+ case V4L2_CID_HUE:
+ retval = hdpvr_config_call(dev, CTRL_HUE, ctrl->value);
+ if (!retval)
+ dev->options.hue = ctrl->value;
+ break;
+ case V4L2_CID_SHARPNESS:
+ retval = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->value);
+ if (!retval)
+ dev->options.sharpness = ctrl->value;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return retval;
+}
+
+
+static int hdpvr_get_ctrl(struct hdpvr_options *opt,
+ struct v4l2_ext_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ ctrl->value = opt->audio_codec;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC;
+ break;
+/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
+/* ctrl->value = (opt->gop_mode & 0x2) ? 0 : 128; */
+/* break; */
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ ctrl->value = opt->bitrate_mode == HDPVR_CONSTANT
+ ? V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
+ : V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ ctrl->value = opt->bitrate * 100000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ ctrl->value = opt->peak_bitrate * 100000;
+ break;
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_g_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *ctrls)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int i, err = 0;
+
+ if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ctrl = ctrls->controls + i;
+
+ err = hdpvr_get_ctrl(&dev->options, ctrl);
+ if (err) {
+ ctrls->error_idx = i;
+ break;
+ }
+ }
+ return err;
+
+ }
+
+ return -EINVAL;
+}
+
+
+static int hdpvr_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
+{
+ int ret = -EINVAL;
+
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AAC ||
+ (ac3 && ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AC3))
+ ret = 0;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ if (ctrl->value == V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC)
+ ret = 0;
+ break;
+/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
+/* if (ctrl->value == 0 || ctrl->value == 128) */
+/* ret = 0; */
+/* break; */
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR ||
+ ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
+ ret = 0;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ {
+ uint bitrate = ctrl->value / 100000;
+ if (bitrate >= 10 && bitrate <= 135)
+ ret = 0;
+ break;
+ }
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ {
+ uint peak_bitrate = ctrl->value / 100000;
+ if (peak_bitrate >= 10 && peak_bitrate <= 202)
+ ret = 0;
+ break;
+ }
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ if (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)
+ ret = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_try_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *ctrls)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int i, err = 0;
+
+ if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ctrl = ctrls->controls + i;
+
+ err = hdpvr_try_ctrl(ctrl,
+ dev->flags & HDPVR_FLAG_AC3_CAP);
+ if (err) {
+ ctrls->error_idx = i;
+ break;
+ }
+ }
+ return err;
+ }
+
+ return -EINVAL;
+}
+
+
+static int hdpvr_set_ctrl(struct hdpvr_device *dev,
+ struct v4l2_ext_control *ctrl)
+{
+ struct hdpvr_options *opt = &dev->options;
+ int ret = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (dev->flags & HDPVR_FLAG_AC3_CAP) {
+ opt->audio_codec = ctrl->value;
+ ret = hdpvr_set_audio(dev, opt->audio_input,
+ opt->audio_codec);
+ }
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ break;
+/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
+/* if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */
+/* opt->gop_mode |= 0x2; */
+/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
+/* opt->gop_mode); */
+/* } */
+/* if (ctrl->value == 128 && opt->gop_mode & 0x2) { */
+/* opt->gop_mode &= ~0x2; */
+/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
+/* opt->gop_mode); */
+/* } */
+/* break; */
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR &&
+ opt->bitrate_mode != HDPVR_CONSTANT) {
+ opt->bitrate_mode = HDPVR_CONSTANT;
+ hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
+ opt->bitrate_mode);
+ }
+ if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
+ opt->bitrate_mode == HDPVR_CONSTANT) {
+ opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE;
+ hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
+ opt->bitrate_mode);
+ }
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE: {
+ uint bitrate = ctrl->value / 100000;
+
+ opt->bitrate = bitrate;
+ if (bitrate >= opt->peak_bitrate)
+ opt->peak_bitrate = bitrate+1;
+
+ hdpvr_set_bitrate(dev);
+ break;
+ }
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: {
+ uint peak_bitrate = ctrl->value / 100000;
+
+ if (opt->bitrate_mode == HDPVR_CONSTANT)
+ break;
+
+ if (opt->bitrate < peak_bitrate) {
+ opt->peak_bitrate = peak_bitrate;
+ hdpvr_set_bitrate(dev);
+ } else
+ ret = -EINVAL;
+ break;
+ }
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ret;
+}
+
+static int vidioc_s_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *ctrls)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int i, err = 0;
+
+ if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ctrl = ctrls->controls + i;
+
+ err = hdpvr_try_ctrl(ctrl,
+ dev->flags & HDPVR_FLAG_AC3_CAP);
+ if (err) {
+ ctrls->error_idx = i;
+ break;
+ }
+ err = hdpvr_set_ctrl(dev, ctrl);
+ if (err) {
+ ctrls->error_idx = i;
+ break;
+ }
+ }
+ return err;
+
+ }
+
+ return -EINVAL;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
+ struct v4l2_fmtdesc *f)
+{
+
+ if (f->index != 0 || f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ f->flags = V4L2_FMT_FLAG_COMPRESSED;
+ strncpy(f->description, "MPEG2-TS with AVC/AAC streams", 32);
+ f->pixelformat = V4L2_PIX_FMT_MPEG;
+
+ return 0;
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *private_data,
+ struct v4l2_format *f)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ struct hdpvr_video_info *vid_info;
+
+ if (!dev)
+ return -ENODEV;
+
+ vid_info = get_video_info(dev);
+ if (!vid_info)
+ return -EFAULT;
+
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
+ f->fmt.pix.width = vid_info->width;
+ f->fmt.pix.height = vid_info->height;
+ f->fmt.pix.sizeimage = dev->bulk_in_size;
+ f->fmt.pix.colorspace = 0;
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.field = V4L2_FIELD_ANY;
+
+ kfree(vid_info);
+ return 0;
+}
+
+static int vidioc_encoder_cmd(struct file *filp, void *priv,
+ struct v4l2_encoder_cmd *a)
+{
+ struct hdpvr_fh *fh = filp->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int res;
+
+ mutex_lock(&dev->io_mutex);
+
+ memset(&a->raw, 0, sizeof(a->raw));
+ switch (a->cmd) {
+ case V4L2_ENC_CMD_START:
+ a->flags = 0;
+ res = hdpvr_start_streaming(dev);
+ break;
+ case V4L2_ENC_CMD_STOP:
+ res = hdpvr_stop_streaming(dev);
+ break;
+ default:
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "Unsupported encoder cmd %d\n", a->cmd);
+ res = -EINVAL;
+ }
+ mutex_unlock(&dev->io_mutex);
+ return res;
+}
+
+static int vidioc_try_encoder_cmd(struct file *filp, void *priv,
+ struct v4l2_encoder_cmd *a)
+{
+ switch (a->cmd) {
+ case V4L2_ENC_CMD_START:
+ case V4L2_ENC_CMD_STOP:
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct v4l2_ioctl_ops hdpvr_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_s_std = vidioc_s_std,
+ .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_enumaudio = vidioc_enumaudio,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
+ .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
+ .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_encoder_cmd = vidioc_encoder_cmd,
+ .vidioc_try_encoder_cmd = vidioc_try_encoder_cmd,
+};
+
+static void hdpvr_device_release(struct video_device *vdev)
+{
+ struct hdpvr_device *dev = video_get_drvdata(vdev);
+
+ hdpvr_delete(dev);
+}
+
+static const struct video_device hdpvr_video_template = {
+/* .type = VFL_TYPE_GRABBER, */
+/* .type2 = VID_TYPE_CAPTURE | VID_TYPE_MPEG_ENCODER, */
+ .fops = &hdpvr_fops,
+ .release = hdpvr_device_release,
+ .ioctl_ops = &hdpvr_ioctl_ops,
+ .tvnorms =
+ V4L2_STD_NTSC | V4L2_STD_SECAM | V4L2_STD_PAL_B |
+ V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_PAL_I |
+ V4L2_STD_PAL_D | V4L2_STD_PAL_M | V4L2_STD_PAL_N |
+ V4L2_STD_PAL_60,
+};
+
+int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
+ int devnum)
+{
+ /* setup and register video device */
+ dev->video_dev = video_device_alloc();
+ if (!dev->video_dev) {
+ v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n");
+ goto error;
+ }
+
+ *(dev->video_dev) = hdpvr_video_template;
+ strcpy(dev->video_dev->name, "Hauppauge HD PVR");
+ dev->video_dev->parent = parent;
+ video_set_drvdata(dev->video_dev, dev);
+
+ if (video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum)) {
+ v4l2_err(&dev->v4l2_dev, "video_device registration failed\n");
+ goto error;
+ }
+
+ return 0;
+error:
+ return -ENOMEM;
+}
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
new file mode 100644
index 000000000000..1edd8759121e
--- /dev/null
+++ b/drivers/media/video/hdpvr/hdpvr.h
@@ -0,0 +1,303 @@
+/*
+ * Hauppauge HD PVR USB driver
+ *
+ * Copyright (C) 2008 Janne Grunau (j@jannau.net)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-device.h>
+
+#define HDPVR_MAJOR_VERSION 0
+#define HDPVR_MINOR_VERSION 2
+#define HDPVR_RELEASE 0
+#define HDPVR_VERSION \
+ KERNEL_VERSION(HDPVR_MAJOR_VERSION, HDPVR_MINOR_VERSION, HDPVR_RELEASE)
+
+#define HDPVR_MAX 8
+
+/* Define these values to match your devices */
+#define HD_PVR_VENDOR_ID 0x2040
+#define HD_PVR_PRODUCT_ID 0x4900
+#define HD_PVR_PRODUCT_ID1 0x4901
+#define HD_PVR_PRODUCT_ID2 0x4902
+
+#define UNSET (-1U)
+
+#define NUM_BUFFERS 64
+
+#define HDPVR_FIRMWARE_VERSION 0x8
+#define HDPVR_FIRMWARE_VERSION_AC3 0xd
+
+/* #define HDPVR_DEBUG */
+
+extern int hdpvr_debug;
+
+#define MSG_INFO 1
+#define MSG_BUFFER 2
+
+struct hdpvr_options {
+ u8 video_std;
+ u8 video_input;
+ u8 audio_input;
+ u8 bitrate; /* in 100kbps */
+ u8 peak_bitrate; /* in 100kbps */
+ u8 bitrate_mode;
+ u8 gop_mode;
+ enum v4l2_mpeg_audio_encoding audio_codec;
+ u8 brightness;
+ u8 contrast;
+ u8 hue;
+ u8 saturation;
+ u8 sharpness;
+};
+
+/* Structure to hold all of our device specific stuff */
+struct hdpvr_device {
+ /* the v4l device for this device */
+ struct video_device *video_dev;
+ /* the usb device for this device */
+ struct usb_device *udev;
+ /* v4l2-device unused */
+ struct v4l2_device v4l2_dev;
+
+ /* the max packet size of the bulk endpoint */
+ size_t bulk_in_size;
+ /* the address of the bulk in endpoint */
+ __u8 bulk_in_endpointAddr;
+
+ /* holds the current device status */
+ __u8 status;
+ /* count the number of openers */
+ uint open_count;
+
+ /* holds the cureent set options */
+ struct hdpvr_options options;
+
+ uint flags;
+
+ /* synchronize I/O */
+ struct mutex io_mutex;
+ /* available buffers */
+ struct list_head free_buff_list;
+ /* in progress buffers */
+ struct list_head rec_buff_list;
+ /* waitqueue for buffers */
+ wait_queue_head_t wait_buffer;
+ /* waitqueue for data */
+ wait_queue_head_t wait_data;
+ /**/
+ struct workqueue_struct *workqueue;
+ /**/
+ struct work_struct worker;
+
+ /* I2C adapter */
+ struct i2c_adapter *i2c_adapter;
+ /* I2C lock */
+ struct mutex i2c_mutex;
+
+ /* usb control transfer buffer and lock */
+ struct mutex usbc_mutex;
+ u8 *usbc_buf;
+};
+
+
+/* buffer one bulk urb of data */
+struct hdpvr_buffer {
+ struct list_head buff_list;
+
+ struct urb *urb;
+
+ struct hdpvr_device *dev;
+
+ uint pos;
+
+ __u8 status;
+};
+
+/* */
+
+struct hdpvr_video_info {
+ u16 width;
+ u16 height;
+ u8 fps;
+};
+
+enum {
+ STATUS_UNINITIALIZED = 0,
+ STATUS_IDLE,
+ STATUS_STARTING,
+ STATUS_SHUTTING_DOWN,
+ STATUS_STREAMING,
+ STATUS_ERROR,
+ STATUS_DISCONNECTED,
+};
+
+enum {
+ HDPVR_FLAG_AC3_CAP = 1,
+};
+
+enum {
+ BUFSTAT_UNINITIALIZED = 0,
+ BUFSTAT_AVAILABLE,
+ BUFSTAT_INPROGRESS,
+ BUFSTAT_READY,
+};
+
+#define CTRL_START_STREAMING_VALUE 0x0700
+#define CTRL_STOP_STREAMING_VALUE 0x0800
+#define CTRL_BITRATE_VALUE 0x1000
+#define CTRL_BITRATE_MODE_VALUE 0x1200
+#define CTRL_GOP_MODE_VALUE 0x1300
+#define CTRL_VIDEO_INPUT_VALUE 0x1500
+#define CTRL_VIDEO_STD_TYPE 0x1700
+#define CTRL_AUDIO_INPUT_VALUE 0x2500
+#define CTRL_BRIGHTNESS 0x2900
+#define CTRL_CONTRAST 0x2a00
+#define CTRL_HUE 0x2b00
+#define CTRL_SATURATION 0x2c00
+#define CTRL_SHARPNESS 0x2d00
+#define CTRL_LOW_PASS_FILTER_VALUE 0x3100
+
+#define CTRL_DEFAULT_INDEX 0x0003
+
+
+ /* :0 s 38 01 1000 0003 0004 4 = 0a00ca00
+ * BITRATE SETTING
+ * 1st and 2nd byte (little endian): average bitrate in 100 000 bit/s
+ * min: 1 mbit/s, max: 13.5 mbit/s
+ * 3rd and 4th byte (little endian): peak bitrate in 100 000 bit/s
+ * min: average + 100kbit/s,
+ * max: 20.2 mbit/s
+ */
+
+ /* :0 s 38 01 1200 0003 0001 1 = 02
+ * BIT RATE MODE
+ * constant = 1, variable (peak) = 2, variable (average) = 3
+ */
+
+ /* :0 s 38 01 1300 0003 0001 1 = 03
+ * GOP MODE (2 bit)
+ * low bit 0/1: advanced/simple GOP
+ * high bit 0/1: IDR(4/32/128) / no IDR (4/32/0)
+ */
+
+ /* :0 s 38 01 1700 0003 0001 1 = 00
+ * VIDEO STANDARD or FREQUNCY 0 = 60hz, 1 = 50hz
+ */
+
+ /* :0 s 38 01 3100 0003 0004 4 = 03030000
+ * FILTER CONTROL
+ * 1st byte luma low pass filter strength,
+ * 2nd byte chroma low pass filter strength,
+ * 3rd byte MF enable chroma, min=0, max=1
+ * 4th byte n
+ */
+
+
+ /* :0 s 38 b9 0001 0000 0000 0 */
+
+
+
+/* :0 s 38 d3 0000 0000 0001 1 = 00 */
+/* ret = usb_control_msg(dev->udev, */
+/* usb_sndctrlpipe(dev->udev, 0), */
+/* 0xd3, 0x38, */
+/* 0, 0, */
+/* "\0", 1, */
+/* 1000); */
+
+/* info("control request returned %d", ret); */
+/* msleep(5000); */
+
+
+ /* :0 s b8 81 1400 0003 0005 5 <
+ * :0 0 5 = d0024002 19
+ * QUERY FRAME SIZE AND RATE
+ * 1st and 2nd byte (little endian): horizontal resolution
+ * 3rd and 4th byte (little endian): vertical resolution
+ * 5th byte: frame rate
+ */
+
+ /* :0 s b8 81 1800 0003 0003 3 <
+ * :0 0 3 = 030104
+ * QUERY SIGNAL AND DETECTED LINES, maybe INPUT
+ */
+
+enum hdpvr_video_std {
+ HDPVR_60HZ = 0,
+ HDPVR_50HZ,
+};
+
+enum hdpvr_video_input {
+ HDPVR_COMPONENT = 0,
+ HDPVR_SVIDEO,
+ HDPVR_COMPOSITE,
+ HDPVR_VIDEO_INPUTS
+};
+
+enum hdpvr_audio_inputs {
+ HDPVR_RCA_BACK = 0,
+ HDPVR_RCA_FRONT,
+ HDPVR_SPDIF,
+ HDPVR_AUDIO_INPUTS
+};
+
+enum hdpvr_bitrate_mode {
+ HDPVR_CONSTANT = 1,
+ HDPVR_VARIABLE_PEAK,
+ HDPVR_VARIABLE_AVERAGE,
+};
+
+enum hdpvr_gop_mode {
+ HDPVR_ADVANCED_IDR_GOP = 0,
+ HDPVR_SIMPLE_IDR_GOP,
+ HDPVR_ADVANCED_NOIDR_GOP,
+ HDPVR_SIMPLE_NOIDR_GOP,
+};
+
+void hdpvr_delete(struct hdpvr_device *dev);
+
+/*========================================================================*/
+/* hardware control functions */
+int hdpvr_set_options(struct hdpvr_device *dev);
+
+int hdpvr_set_bitrate(struct hdpvr_device *dev);
+
+int hdpvr_set_audio(struct hdpvr_device *dev, u8 input,
+ enum v4l2_mpeg_audio_encoding codec);
+
+int hdpvr_config_call(struct hdpvr_device *dev, uint value,
+ unsigned char valbuf);
+
+struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev);
+
+/* :0 s b8 81 1800 0003 0003 3 < */
+/* :0 0 3 = 0301ff */
+int get_input_lines_info(struct hdpvr_device *dev);
+
+
+/*========================================================================*/
+/* v4l2 registration */
+int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
+ int devnumber);
+
+int hdpvr_cancel_queue(struct hdpvr_device *dev);
+
+/*========================================================================*/
+/* i2c adapter registration */
+int hdpvr_register_i2c_adapter(struct hdpvr_device *dev);
+
+/*========================================================================*/
+/* buffer management */
+int hdpvr_free_buffers(struct hdpvr_device *dev);
+int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count);
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index 79393d1772e4..8e1463ee1b64 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -56,17 +56,6 @@ struct hexium_data
u8 byte;
};
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_STD, SAA7146_AFTER },
- { VIDIOC_G_CTRL, SAA7146_BEFORE },
- { VIDIOC_S_CTRL, SAA7146_BEFORE },
- { 0, 0 }
-};
-
#define HEXIUM_CONTROLS 1
static struct v4l2_queryctrl hexium_controls[] = {
{ V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 },
@@ -231,6 +220,132 @@ static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec)
return 0;
}
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+
+ if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
+
+ DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ *input = hexium->cur_input;
+
+ DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
+
+ if (input < 0 || input >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ hexium->cur_input = input;
+ hexium_set_input(hexium, input);
+ return 0;
+}
+
+/* the saa7146 provides some controls (brightness, contrast, saturation)
+ which gets registered *after* this function. because of this we have
+ to return with a value != 0 even if the function succeded.. */
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ int i;
+
+ for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+ if (hexium_controls[i].id == qc->id) {
+ *qc = hexium_controls[i];
+ DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
+ return 0;
+ }
+ }
+ return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
+}
+
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+ int i;
+
+ for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+ if (hexium_controls[i].id == vc->id)
+ break;
+ }
+
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
+
+ if (vc->id == V4L2_CID_PRIVATE_BASE) {
+ vc->value = hexium->cur_bw;
+ DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+ int i = 0;
+
+ for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+ if (hexium_controls[i].id == vc->id)
+ break;
+ }
+
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
+
+ if (vc->id == V4L2_CID_PRIVATE_BASE)
+ hexium->cur_bw = vc->value;
+
+ DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
+
+ if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_pal);
+ return 0;
+ }
+ if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_ntsc);
+ return 0;
+ }
+ if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_secam);
+ return 0;
+ }
+ if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_pal_bw);
+ return 0;
+ }
+ if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_ntsc_bw);
+ return 0;
+ }
+ if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std)
+ /* fixme: is there no bw secam mode? */
+ return -EINVAL;
+
+ return -EINVAL;
+}
+
+
static struct saa7146_ext_vv vv_data;
/* this function only gets called when the probing was successful */
@@ -279,6 +394,12 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
hexium->cur_input = 0;
saa7146_vv_init(dev, &vv_data);
+ vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
+ vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
+ vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) {
printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
return -1;
@@ -306,153 +427,6 @@ static int hexium_detach(struct saa7146_dev *dev)
return 0;
}
-static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-{
- struct saa7146_dev *dev = fh->dev;
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-/*
- struct saa7146_vv *vv = dev->vv_data;
-*/
- switch (cmd) {
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
- DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-
- if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-
- DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
- return 0;
- }
- case VIDIOC_G_INPUT:
- {
- int *input = (int *) arg;
- *input = hexium->cur_input;
-
- DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
- return 0;
- }
- case VIDIOC_S_INPUT:
- {
- int input = *(int *) arg;
-
- DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
-
- if (input < 0 || input >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- hexium->cur_input = input;
- hexium_set_input(hexium, input);
-
- return 0;
- }
- /* the saa7146 provides some controls (brightness, contrast, saturation)
- which gets registered *after* this function. because of this we have
- to return with a value != 0 even if the function succeded.. */
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
- if (hexium_controls[i].id == qc->id) {
- *qc = hexium_controls[i];
- DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
- return 0;
- }
- }
- return -EAGAIN;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i;
-
- for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
- if (hexium_controls[i].id == vc->id) {
- break;
- }
- }
-
- if (i < 0) {
- return -EAGAIN;
- }
-
- switch (vc->id) {
- case V4L2_CID_PRIVATE_BASE:{
- vc->value = hexium->cur_bw;
- DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
- return 0;
- }
- }
- return -EINVAL;
- }
-
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i = 0;
-
- for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
- if (hexium_controls[i].id == vc->id) {
- break;
- }
- }
-
- if (i < 0) {
- return -EAGAIN;
- }
-
- switch (vc->id) {
- case V4L2_CID_PRIVATE_BASE:{
- hexium->cur_bw = vc->value;
- break;
- }
- }
-
- DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
-
- if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_pal);
- return 0;
- }
- if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_ntsc);
- return 0;
- }
- if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_secam);
- return 0;
- }
- if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_pal_bw);
- return 0;
- }
- if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_ntsc_bw);
- return 0;
- }
- if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
- /* fixme: is there no bw secam mode? */
- return -EINVAL;
- }
-
- return -EINVAL;
- }
- default:
-/*
- DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
-*/
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
{
struct hexium *hexium = (struct hexium *) dev->ext_priv;
@@ -514,8 +488,6 @@ static struct saa7146_ext_vv vv_data = {
.stds = &hexium_standards[0],
.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = hexium_ioctl,
};
static struct saa7146_extension hexium_extension = {
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 074bec711fe0..2bc39f628455 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -57,14 +57,6 @@ struct hexium_data
u8 byte;
};
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_STD, SAA7146_AFTER },
- { 0, 0 }
-};
-
struct hexium
{
int type;
@@ -329,6 +321,44 @@ static int hexium_set_input(struct hexium *hexium, int input)
return 0;
}
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+
+ if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
+
+ DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ *input = hexium->cur_input;
+
+ DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ if (input < 0 || input >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ hexium->cur_input = input;
+ hexium_set_input(hexium, input);
+
+ return 0;
+}
+
static struct saa7146_ext_vv vv_data;
/* this function only gets called when the probing was successful */
@@ -339,6 +369,9 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
DEB_EE((".\n"));
saa7146_vv_init(dev, &vv_data);
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) {
printk("hexium_orion: cannot register capture v4l2 device. skipping.\n");
return -1;
@@ -370,58 +403,6 @@ static int hexium_detach(struct saa7146_dev *dev)
return 0;
}
-static long hexium_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-{
- struct saa7146_dev *dev = fh->dev;
- struct hexium *hexium = (struct hexium *) dev->ext_priv;
-/*
- struct saa7146_vv *vv = dev->vv_data;
-*/
- switch (cmd) {
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
- DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-
- if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-
- DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
- return 0;
- }
- case VIDIOC_G_INPUT:
- {
- int *input = (int *) arg;
- *input = hexium->cur_input;
-
- DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
- return 0;
- }
- case VIDIOC_S_INPUT:
- {
- int input = *(int *) arg;
-
- if (input < 0 || input >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- hexium->cur_input = input;
- hexium_set_input(hexium, input);
-
- return 0;
- }
- default:
-/*
- DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
-*/
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
{
return 0;
@@ -479,8 +460,6 @@ static struct saa7146_ext_vv vv_data = {
.stds = &hexium_standards[0],
.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = hexium_ioctl,
};
static struct saa7146_extension extension = {
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c
index 84b9e4f2b3b3..3d6940163b12 100644
--- a/drivers/media/video/indycam.c
+++ b/drivers/media/video/indycam.c
@@ -19,10 +19,12 @@
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/videodev.h>
/* IndyCam decodes stream of photons into digital image representation ;-) */
-#include <linux/video_decoder.h>
+#include <linux/videodev2.h>
#include <linux/i2c.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
#include "indycam.h"
@@ -33,6 +35,7 @@ MODULE_VERSION(INDYCAM_MODULE_VERSION);
MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
MODULE_LICENSE("GPL");
+
// #define INDYCAM_DEBUG
#ifdef INDYCAM_DEBUG
@@ -44,11 +47,14 @@ MODULE_LICENSE("GPL");
#endif
struct indycam {
- struct i2c_client *client;
+ struct v4l2_subdev sd;
u8 version;
};
-static struct i2c_driver i2c_driver_indycam;
+static inline struct indycam *to_indycam(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct indycam, sd);
+}
static const u8 initseq[] = {
INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */
@@ -63,8 +69,9 @@ static const u8 initseq[] = {
/* IndyCam register handling */
-static int indycam_read_reg(struct i2c_client *client, u8 reg, u8 *value)
+static int indycam_read_reg(struct v4l2_subdev *sd, u8 reg, u8 *value)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
if (reg == INDYCAM_REG_RESET) {
@@ -87,12 +94,12 @@ static int indycam_read_reg(struct i2c_client *client, u8 reg, u8 *value)
return 0;
}
-static int indycam_write_reg(struct i2c_client *client, u8 reg, u8 value)
+static int indycam_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int err;
- if ((reg == INDYCAM_REG_BRIGHTNESS)
- || (reg == INDYCAM_REG_VERSION)) {
+ if (reg == INDYCAM_REG_BRIGHTNESS || reg == INDYCAM_REG_VERSION) {
dprintk("indycam_write_reg(): "
"skipping read-only register %d\n", reg);
return 0;
@@ -108,13 +115,13 @@ static int indycam_write_reg(struct i2c_client *client, u8 reg, u8 value)
return err;
}
-static int indycam_write_block(struct i2c_client *client, u8 reg,
+static int indycam_write_block(struct v4l2_subdev *sd, u8 reg,
u8 length, u8 *data)
{
int i, err;
for (i = 0; i < length; i++) {
- err = indycam_write_reg(client, reg + i, data[i]);
+ err = indycam_write_reg(sd, reg + i, data[i]);
if (err)
return err;
}
@@ -125,79 +132,78 @@ static int indycam_write_block(struct i2c_client *client, u8 reg,
/* Helper functions */
#ifdef INDYCAM_DEBUG
-static void indycam_regdump_debug(struct i2c_client *client)
+static void indycam_regdump_debug(struct v4l2_subdev *sd)
{
int i;
u8 val;
for (i = 0; i < 9; i++) {
- indycam_read_reg(client, i, &val);
+ indycam_read_reg(sd, i, &val);
dprintk("Reg %d = 0x%02x\n", i, val);
}
}
#endif
-static int indycam_get_control(struct i2c_client *client,
- struct indycam_control *ctrl)
+static int indycam_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct indycam *camera = i2c_get_clientdata(client);
+ struct indycam *camera = to_indycam(sd);
u8 reg;
int ret = 0;
- switch (ctrl->type) {
- case INDYCAM_CONTROL_AGC:
- case INDYCAM_CONTROL_AWB:
- ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg);
+ switch (ctrl->id) {
+ case V4L2_CID_AUTOGAIN:
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, &reg);
if (ret)
return -EIO;
- if (ctrl->type == INDYCAM_CONTROL_AGC)
+ if (ctrl->id == V4L2_CID_AUTOGAIN)
ctrl->value = (reg & INDYCAM_CONTROL_AGCENA)
? 1 : 0;
else
ctrl->value = (reg & INDYCAM_CONTROL_AWBCTL)
? 1 : 0;
break;
- case INDYCAM_CONTROL_SHUTTER:
- ret = indycam_read_reg(client, INDYCAM_REG_SHUTTER, &reg);
+ case V4L2_CID_EXPOSURE:
+ ret = indycam_read_reg(sd, INDYCAM_REG_SHUTTER, &reg);
if (ret)
return -EIO;
ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1);
break;
- case INDYCAM_CONTROL_GAIN:
- ret = indycam_read_reg(client, INDYCAM_REG_GAIN, &reg);
+ case V4L2_CID_GAIN:
+ ret = indycam_read_reg(sd, INDYCAM_REG_GAIN, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
- case INDYCAM_CONTROL_RED_BALANCE:
- ret = indycam_read_reg(client, INDYCAM_REG_RED_BALANCE, &reg);
+ case V4L2_CID_RED_BALANCE:
+ ret = indycam_read_reg(sd, INDYCAM_REG_RED_BALANCE, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
- case INDYCAM_CONTROL_BLUE_BALANCE:
- ret = indycam_read_reg(client, INDYCAM_REG_BLUE_BALANCE, &reg);
+ case V4L2_CID_BLUE_BALANCE:
+ ret = indycam_read_reg(sd, INDYCAM_REG_BLUE_BALANCE, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
case INDYCAM_CONTROL_RED_SATURATION:
- ret = indycam_read_reg(client,
+ ret = indycam_read_reg(sd,
INDYCAM_REG_RED_SATURATION, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
case INDYCAM_CONTROL_BLUE_SATURATION:
- ret = indycam_read_reg(client,
+ ret = indycam_read_reg(sd,
INDYCAM_REG_BLUE_SATURATION, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
- case INDYCAM_CONTROL_GAMMA:
+ case V4L2_CID_GAMMA:
if (camera->version == CAMERA_VERSION_MOOSE) {
- ret = indycam_read_reg(client,
+ ret = indycam_read_reg(sd,
INDYCAM_REG_GAMMA, &reg);
if (ret)
return -EIO;
@@ -213,21 +219,20 @@ static int indycam_get_control(struct i2c_client *client,
return ret;
}
-static int indycam_set_control(struct i2c_client *client,
- struct indycam_control *ctrl)
+static int indycam_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct indycam *camera = i2c_get_clientdata(client);
+ struct indycam *camera = to_indycam(sd);
u8 reg;
int ret = 0;
- switch (ctrl->type) {
- case INDYCAM_CONTROL_AGC:
- case INDYCAM_CONTROL_AWB:
- ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg);
+ switch (ctrl->id) {
+ case V4L2_CID_AUTOGAIN:
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, &reg);
if (ret)
break;
- if (ctrl->type == INDYCAM_CONTROL_AGC) {
+ if (ctrl->id == V4L2_CID_AUTOGAIN) {
if (ctrl->value)
reg |= INDYCAM_CONTROL_AGCENA;
else
@@ -239,34 +244,34 @@ static int indycam_set_control(struct i2c_client *client,
reg &= ~INDYCAM_CONTROL_AWBCTL;
}
- ret = indycam_write_reg(client, INDYCAM_REG_CONTROL, reg);
+ ret = indycam_write_reg(sd, INDYCAM_REG_CONTROL, reg);
break;
- case INDYCAM_CONTROL_SHUTTER:
+ case V4L2_CID_EXPOSURE:
reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1);
- ret = indycam_write_reg(client, INDYCAM_REG_SHUTTER, reg);
+ ret = indycam_write_reg(sd, INDYCAM_REG_SHUTTER, reg);
break;
- case INDYCAM_CONTROL_GAIN:
- ret = indycam_write_reg(client, INDYCAM_REG_GAIN, ctrl->value);
+ case V4L2_CID_GAIN:
+ ret = indycam_write_reg(sd, INDYCAM_REG_GAIN, ctrl->value);
break;
- case INDYCAM_CONTROL_RED_BALANCE:
- ret = indycam_write_reg(client, INDYCAM_REG_RED_BALANCE,
+ case V4L2_CID_RED_BALANCE:
+ ret = indycam_write_reg(sd, INDYCAM_REG_RED_BALANCE,
ctrl->value);
break;
- case INDYCAM_CONTROL_BLUE_BALANCE:
- ret = indycam_write_reg(client, INDYCAM_REG_BLUE_BALANCE,
+ case V4L2_CID_BLUE_BALANCE:
+ ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_BALANCE,
ctrl->value);
break;
case INDYCAM_CONTROL_RED_SATURATION:
- ret = indycam_write_reg(client, INDYCAM_REG_RED_SATURATION,
+ ret = indycam_write_reg(sd, INDYCAM_REG_RED_SATURATION,
ctrl->value);
break;
case INDYCAM_CONTROL_BLUE_SATURATION:
- ret = indycam_write_reg(client, INDYCAM_REG_BLUE_SATURATION,
+ ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_SATURATION,
ctrl->value);
break;
- case INDYCAM_CONTROL_GAMMA:
+ case V4L2_CID_GAMMA:
if (camera->version == CAMERA_VERSION_MOOSE) {
- ret = indycam_write_reg(client, INDYCAM_REG_GAMMA,
+ ret = indycam_write_reg(sd, INDYCAM_REG_GAMMA,
ctrl->value);
}
break;
@@ -279,192 +284,103 @@ static int indycam_set_control(struct i2c_client *client,
/* I2C-interface */
-static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
+static int indycam_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct indycam *camera = to_indycam(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_INDYCAM,
+ camera->version);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops indycam_core_ops = {
+ .g_chip_ident = indycam_g_chip_ident,
+ .g_ctrl = indycam_g_ctrl,
+ .s_ctrl = indycam_s_ctrl,
+};
+
+static const struct v4l2_subdev_ops indycam_ops = {
+ .core = &indycam_core_ops,
+};
+
+static int indycam_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int err = 0;
struct indycam *camera;
- struct i2c_client *client;
+ struct v4l2_subdev *sd;
- printk(KERN_INFO "SGI IndyCam driver version %s\n",
- INDYCAM_MODULE_VERSION);
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
camera = kzalloc(sizeof(struct indycam), GFP_KERNEL);
- if (!camera) {
- err = -ENOMEM;
- goto out_free_client;
- }
-
- client->addr = addr;
- client->adapter = adap;
- client->driver = &i2c_driver_indycam;
- client->flags = 0;
- strcpy(client->name, "IndyCam client");
- i2c_set_clientdata(client, camera);
-
- camera->client = client;
+ if (!camera)
+ return -ENOMEM;
- err = i2c_attach_client(client);
- if (err)
- goto out_free_camera;
+ sd = &camera->sd;
+ v4l2_i2c_subdev_init(sd, client, &indycam_ops);
camera->version = i2c_smbus_read_byte_data(client,
INDYCAM_REG_VERSION);
if (camera->version != CAMERA_VERSION_INDY &&
camera->version != CAMERA_VERSION_MOOSE) {
- err = -ENODEV;
- goto out_detach_client;
+ kfree(camera);
+ return -ENODEV;
}
+
printk(KERN_INFO "IndyCam v%d.%d detected\n",
INDYCAM_VERSION_MAJOR(camera->version),
INDYCAM_VERSION_MINOR(camera->version));
- indycam_regdump(client);
+ indycam_regdump(sd);
// initialize
- err = indycam_write_block(client, 0, sizeof(initseq), (u8 *)&initseq);
+ err = indycam_write_block(sd, 0, sizeof(initseq), (u8 *)&initseq);
if (err) {
printk(KERN_ERR "IndyCam initialization failed\n");
- err = -EIO;
- goto out_detach_client;
+ kfree(camera);
+ return -EIO;
}
- indycam_regdump(client);
+ indycam_regdump(sd);
// white balance
- err = indycam_write_reg(client, INDYCAM_REG_CONTROL,
+ err = indycam_write_reg(sd, INDYCAM_REG_CONTROL,
INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL);
if (err) {
printk(KERN_ERR "IndyCam: White balancing camera failed\n");
- err = -EIO;
- goto out_detach_client;
+ kfree(camera);
+ return -EIO;
}
- indycam_regdump(client);
+ indycam_regdump(sd);
printk(KERN_INFO "IndyCam initialized\n");
return 0;
-
-out_detach_client:
- i2c_detach_client(client);
-out_free_camera:
- kfree(camera);
-out_free_client:
- kfree(client);
- return err;
}
-static int indycam_probe(struct i2c_adapter *adap)
+static int indycam_remove(struct i2c_client *client)
{
- /* Indy specific crap */
- if (adap->id == I2C_HW_SGI_VINO)
- return indycam_attach(adap, INDYCAM_ADDR, 0);
- /* Feel free to add probe here :-) */
- return -ENODEV;
-}
-
-static int indycam_detach(struct i2c_client *client)
-{
- struct indycam *camera = i2c_get_clientdata(client);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
- i2c_detach_client(client);
- kfree(camera);
- kfree(client);
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_indycam(sd));
return 0;
}
-static int indycam_command(struct i2c_client *client, unsigned int cmd,
- void *arg)
-{
- // struct indycam *camera = i2c_get_clientdata(client);
-
- /* The old video_decoder interface just isn't enough,
- * so we'll use some custom commands. */
- switch (cmd) {
- case DECODER_GET_CAPABILITIES: {
- struct video_decoder_capability *cap = arg;
-
- cap->flags = VIDEO_DECODER_NTSC;
- cap->inputs = 1;
- cap->outputs = 1;
- break;
- }
- case DECODER_GET_STATUS: {
- int *iarg = arg;
-
- *iarg = DECODER_STATUS_GOOD | DECODER_STATUS_NTSC |
- DECODER_STATUS_COLOR;
- break;
- }
- case DECODER_SET_NORM: {
- int *iarg = arg;
-
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- break;
- default:
- return -EINVAL;
- }
- break;
- }
- case DECODER_SET_INPUT: {
- int *iarg = arg;
-
- if (*iarg != 0)
- return -EINVAL;
- break;
- }
- case DECODER_SET_OUTPUT: {
- int *iarg = arg;
-
- if (*iarg != 0)
- return -EINVAL;
- break;
- }
- case DECODER_ENABLE_OUTPUT: {
- /* Always enabled */
- break;
- }
- case DECODER_SET_PICTURE: {
- // struct video_picture *pic = arg;
- /* TODO: convert values for indycam_set_controls() */
- break;
- }
- case DECODER_INDYCAM_GET_CONTROL: {
- return indycam_get_control(client, arg);
- }
- case DECODER_INDYCAM_SET_CONTROL: {
- return indycam_set_control(client, arg);
- }
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static struct i2c_driver i2c_driver_indycam = {
- .driver = {
- .name = "indycam",
- },
- .id = I2C_DRIVERID_INDYCAM,
- .attach_adapter = indycam_probe,
- .detach_client = indycam_detach,
- .command = indycam_command,
+static const struct i2c_device_id indycam_id[] = {
+ { "indycam", 0 },
+ { }
};
+MODULE_DEVICE_TABLE(i2c, indycam_id);
-static int __init indycam_init(void)
-{
- return i2c_add_driver(&i2c_driver_indycam);
-}
-
-static void __exit indycam_exit(void)
-{
- i2c_del_driver(&i2c_driver_indycam);
-}
-
-module_init(indycam_init);
-module_exit(indycam_exit);
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "indycam",
+ .probe = indycam_probe,
+ .remove = indycam_remove,
+ .id_table = indycam_id,
+};
diff --git a/drivers/media/video/indycam.h b/drivers/media/video/indycam.h
index e6ee82063ed8..881f21c474c4 100644
--- a/drivers/media/video/indycam.h
+++ b/drivers/media/video/indycam.h
@@ -87,22 +87,7 @@
/* Driver interface definitions */
-#define INDYCAM_CONTROL_AGC 0 /* boolean */
-#define INDYCAM_CONTROL_AWB 1 /* boolean */
-#define INDYCAM_CONTROL_SHUTTER 2
-#define INDYCAM_CONTROL_GAIN 3
-#define INDYCAM_CONTROL_RED_BALANCE 4
-#define INDYCAM_CONTROL_BLUE_BALANCE 5
-#define INDYCAM_CONTROL_RED_SATURATION 6
-#define INDYCAM_CONTROL_BLUE_SATURATION 7
-#define INDYCAM_CONTROL_GAMMA 8
-
-struct indycam_control {
- u8 type;
- s32 value;
-};
-
-#define DECODER_INDYCAM_GET_CONTROL _IOR('d', 193, struct indycam_control)
-#define DECODER_INDYCAM_SET_CONTROL _IOW('d', 194, struct indycam_control)
+#define INDYCAM_CONTROL_RED_SATURATION (V4L2_CID_PRIVATE_BASE + 0)
+#define INDYCAM_CONTROL_BLUE_SATURATION (V4L2_CID_PRIVATE_BASE + 1)
#endif
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index d4658c56eddc..092c7da0f37a 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -16,6 +16,8 @@
* Henry Wong <henry@stuffedcow.net>
* Mark Schultz <n9xmj@yahoo.com>
* Brian Rogers <brian_rogers@comcast.net>
+ * modified for AVerMedia Cardbus by
+ * Oldrich Jedlicka <oldium.pro@seznam.cz>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -216,6 +218,46 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
return 1;
}
+static int get_key_avermedia_cardbus(struct IR_i2c *ir,
+ u32 *ir_key, u32 *ir_raw)
+{
+ unsigned char subaddr, key, keygroup;
+ struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0,
+ .buf = &subaddr, .len = 1},
+ { .addr = ir->c.addr, .flags = I2C_M_RD,
+ .buf = &key, .len = 1} };
+ subaddr = 0x0d;
+ if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+ dprintk(1, "read error\n");
+ return -EIO;
+ }
+
+ if (key == 0xff)
+ return 0;
+
+ subaddr = 0x0b;
+ msg[1].buf = &keygroup;
+ if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+ dprintk(1, "read error\n");
+ return -EIO;
+ }
+
+ if (keygroup == 0xff)
+ return 0;
+
+ dprintk(1, "read key 0x%02x/0x%02x\n", key, keygroup);
+ if (keygroup < 2 || keygroup > 3) {
+ /* Only a warning */
+ dprintk(1, "warning: invalid key group 0x%02x for key 0x%02x\n",
+ keygroup, key);
+ }
+ key |= (keygroup & 1) << 6;
+
+ *ir_key = key;
+ *ir_raw = key;
+ return 1;
+}
+
/* ----------------------------------------------------------------------- */
static void ir_key_poll(struct IR_i2c *ir)
@@ -237,15 +279,9 @@ static void ir_key_poll(struct IR_i2c *ir)
}
}
-static void ir_timer(unsigned long data)
-{
- struct IR_i2c *ir = (struct IR_i2c*)data;
- schedule_work(&ir->work);
-}
-
static void ir_work(struct work_struct *work)
{
- struct IR_i2c *ir = container_of(work, struct IR_i2c, work);
+ struct IR_i2c *ir = container_of(work, struct IR_i2c, work.work);
int polling_interval = 100;
/* MSI TV@nywhere Plus requires more frequent polling
@@ -254,7 +290,7 @@ static void ir_work(struct work_struct *work)
polling_interval = 50;
ir_key_poll(ir);
- mod_timer(&ir->timer, jiffies + msecs_to_jiffies(polling_interval));
+ schedule_delayed_work(&ir->work, msecs_to_jiffies(polling_interval));
}
/* ----------------------------------------------------------------------- */
@@ -360,6 +396,12 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
ir_type = IR_TYPE_OTHER;
}
break;
+ case 0x40:
+ name = "AVerMedia Cardbus remote";
+ ir->get_key = get_key_avermedia_cardbus;
+ ir_type = IR_TYPE_OTHER;
+ ir_codes = ir_codes_avermedia_cardbus;
+ break;
default:
/* shouldn't happen */
printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr);
@@ -404,11 +446,8 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
ir->input->name, ir->input->phys, adap->name);
/* start polling via eventd */
- INIT_WORK(&ir->work, ir_work);
- init_timer(&ir->timer);
- ir->timer.function = ir_timer;
- ir->timer.data = (unsigned long)ir;
- schedule_work(&ir->work);
+ INIT_DELAYED_WORK(&ir->work, ir_work);
+ schedule_delayed_work(&ir->work, 0);
return 0;
@@ -425,8 +464,7 @@ static int ir_detach(struct i2c_client *client)
struct IR_i2c *ir = i2c_get_clientdata(client);
/* kill outstanding polls */
- del_timer_sync(&ir->timer);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&ir->work);
/* unregister devices */
input_unregister_device(ir->input);
@@ -524,6 +562,22 @@ static int ir_probe(struct i2c_adapter *adap)
ir_attach(adap, msg.addr, 0, 0);
}
+ /* Special case for AVerMedia Cardbus remote */
+ if (adap->id == I2C_HW_SAA7134) {
+ unsigned char subaddr, data;
+ struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0,
+ .buf = &subaddr, .len = 1},
+ { .addr = 0x40, .flags = I2C_M_RD,
+ .buf = &data, .len = 1} };
+ subaddr = 0x0d;
+ rc = i2c_transfer(adap, msg, 2);
+ dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n",
+ msg[0].addr, subaddr, adap->name,
+ (2 == rc) ? "yes" : "no");
+ if (2 == rc)
+ ir_attach(adap, msg[0].addr, 0, 0);
+ }
+
return 0;
}
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index 62aa06f5d168..84995bcf4a75 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -26,6 +26,7 @@
#include "ivtv-mailbox.h"
#include "ivtv-controls.h"
+/* Must be sorted from low to high control ID! */
static const u32 user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index c46c990987f9..eca8bf92a225 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -357,7 +357,7 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv)
static void ivtv_process_eeprom(struct ivtv *itv)
{
struct tveeprom tv;
- int pci_slot = PCI_SLOT(itv->dev->devfn);
+ int pci_slot = PCI_SLOT(itv->pdev->devfn);
ivtv_read_eeprom(itv, &tv);
@@ -604,7 +604,7 @@ static void ivtv_process_options(struct ivtv *itv)
itv->std = ivtv_parse_std(itv);
if (itv->std == 0 && tunertype >= 0)
itv->std = tunertype ? V4L2_STD_MN : (V4L2_STD_ALL & ~V4L2_STD_MN);
- itv->has_cx23415 = (itv->dev->device == PCI_DEVICE_ID_IVTV15);
+ itv->has_cx23415 = (itv->pdev->device == PCI_DEVICE_ID_IVTV15);
chipname = itv->has_cx23415 ? "cx23415" : "cx23416";
if (itv->options.cardtype == -1) {
IVTV_INFO("Ignore card (detected %s based chip)\n", chipname);
@@ -617,9 +617,9 @@ static void ivtv_process_options(struct ivtv *itv)
IVTV_ERR("Unknown user specified type, trying to autodetect card\n");
}
if (itv->card == NULL) {
- if (itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE ||
- itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 ||
- itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) {
+ if (itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE ||
+ itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 ||
+ itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) {
itv->card = ivtv_get_card(itv->has_cx23415 ? IVTV_CARD_PVR_350 : IVTV_CARD_PVR_150);
IVTV_INFO("Autodetected Hauppauge card (%s based)\n",
chipname);
@@ -630,13 +630,13 @@ static void ivtv_process_options(struct ivtv *itv)
if (itv->card->pci_list == NULL)
continue;
for (j = 0; itv->card->pci_list[j].device; j++) {
- if (itv->dev->device !=
+ if (itv->pdev->device !=
itv->card->pci_list[j].device)
continue;
- if (itv->dev->subsystem_vendor !=
+ if (itv->pdev->subsystem_vendor !=
itv->card->pci_list[j].subsystem_vendor)
continue;
- if (itv->dev->subsystem_device !=
+ if (itv->pdev->subsystem_device !=
itv->card->pci_list[j].subsystem_device)
continue;
IVTV_INFO("Autodetected %s card (%s based)\n",
@@ -650,9 +650,9 @@ done:
if (itv->card == NULL) {
itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
IVTV_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
- itv->dev->vendor, itv->dev->device);
+ itv->pdev->vendor, itv->pdev->device);
IVTV_ERR(" subsystem vendor/device: [%04x:%04x]\n",
- itv->dev->subsystem_vendor, itv->dev->subsystem_device);
+ itv->pdev->subsystem_vendor, itv->pdev->subsystem_device);
IVTV_ERR(" %s based\n", chipname);
IVTV_ERR("Defaulting to %s card\n", itv->card->name);
IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
@@ -671,7 +671,7 @@ done:
*/
static int __devinit ivtv_init_struct1(struct ivtv *itv)
{
- itv->base_addr = pci_resource_start(itv->dev, 0);
+ itv->base_addr = pci_resource_start(itv->pdev, 0);
itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */
itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */
@@ -682,7 +682,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
spin_lock_init(&itv->lock);
spin_lock_init(&itv->dma_reg_lock);
- itv->irq_work_queues = create_singlethread_workqueue(itv->device.name);
+ itv->irq_work_queues = create_singlethread_workqueue(itv->v4l2_dev.name);
if (itv->irq_work_queues == NULL) {
IVTV_ERR("Could not create ivtv workqueue\n");
return -1;
@@ -766,7 +766,7 @@ static void __devinit ivtv_init_struct2(struct ivtv *itv)
itv->audio_input = itv->card->video_inputs[i].audio_index;
}
-static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
+static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
u16 cmd;
@@ -775,11 +775,11 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
IVTV_DEBUG_INFO("Enabling pci device\n");
- if (pci_enable_device(dev)) {
+ if (pci_enable_device(pdev)) {
IVTV_ERR("Can't enable device!\n");
return -EIO;
}
- if (pci_set_dma_mask(dev, 0xffffffff)) {
+ if (pci_set_dma_mask(pdev, 0xffffffff)) {
IVTV_ERR("No suitable DMA available.\n");
return -EIO;
}
@@ -805,11 +805,11 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
}
/* Check for bus mastering */
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
if (!(cmd & PCI_COMMAND_MASTER)) {
IVTV_DEBUG_INFO("Attempting to enable Bus Mastering\n");
- pci_set_master(dev);
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_set_master(pdev);
+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
if (!(cmd & PCI_COMMAND_MASTER)) {
IVTV_ERR("Bus Mastering is not enabled\n");
return -ENXIO;
@@ -817,26 +817,26 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
}
IVTV_DEBUG_INFO("Bus Mastering Enabled.\n");
- pci_read_config_byte(dev, PCI_CLASS_REVISION, &card_rev);
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+ pci_read_config_byte(pdev, PCI_CLASS_REVISION, &card_rev);
+ pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
if (pci_latency < 64 && ivtv_pci_latency) {
IVTV_INFO("Unreasonably low latency timer, "
"setting to 64 (was %d)\n", pci_latency);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
+ pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
}
/* This config space value relates to DMA latencies. The
default value 0x8080 is too low however and will lead
to DMA errors. 0xffff is the max value which solves
these problems. */
- pci_write_config_dword(dev, 0x40, 0xffff);
+ pci_write_config_dword(pdev, 0x40, 0xffff);
IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, "
"irq: %d, latency: %d, memory: 0x%lx\n",
- itv->dev->device, card_rev, dev->bus->number,
- PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
- itv->dev->irq, pci_latency, (unsigned long)itv->base_addr);
+ pdev->device, card_rev, pdev->bus->number,
+ PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
+ pdev->irq, pci_latency, (unsigned long)itv->base_addr);
return 0;
}
@@ -935,7 +935,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
}
}
-static int __devinit ivtv_probe(struct pci_dev *dev,
+static int __devinit ivtv_probe(struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
int retval = 0;
@@ -945,17 +945,17 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
itv = kzalloc(sizeof(struct ivtv), GFP_ATOMIC);
if (itv == NULL)
return -ENOMEM;
- itv->dev = dev;
+ itv->pdev = pdev;
itv->instance = atomic_inc_return(&ivtv_instance) - 1;
- retval = v4l2_device_register(&dev->dev, &itv->device);
+ retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev);
if (retval) {
kfree(itv);
return retval;
}
/* "ivtv + PCI ID" is a bit of a mouthful, so use
"ivtv + instance" instead. */
- snprintf(itv->device.name, sizeof(itv->device.name),
+ snprintf(itv->v4l2_dev.name, sizeof(itv->v4l2_dev.name),
"ivtv%d", itv->instance);
IVTV_INFO("Initializing card %d\n", itv->instance);
@@ -972,12 +972,11 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr);
/* PCI Device Setup */
- if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) {
- if (retval == -EIO)
- goto free_workqueue;
- else if (retval == -ENXIO)
- goto free_mem;
- }
+ retval = ivtv_setup_pci(itv, pdev, pci_id);
+ if (retval == -EIO)
+ goto free_workqueue;
+ if (retval == -ENXIO)
+ goto free_mem;
/* map io memory */
IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
@@ -1154,8 +1153,8 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
ivtv_set_irq_mask(itv, 0xffffffff);
/* Register IRQ */
- retval = request_irq(itv->dev->irq, ivtv_irq_handler,
- IRQF_SHARED | IRQF_DISABLED, itv->device.name, (void *)itv);
+ retval = request_irq(itv->pdev->irq, ivtv_irq_handler,
+ IRQF_SHARED | IRQF_DISABLED, itv->v4l2_dev.name, (void *)itv);
if (retval) {
IVTV_ERR("Failed to register irq %d\n", retval);
goto free_i2c;
@@ -1177,7 +1176,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
free_streams:
ivtv_streams_cleanup(itv, 1);
free_irq:
- free_irq(itv->dev->irq, (void *)itv);
+ free_irq(itv->pdev->irq, (void *)itv);
free_i2c:
exit_ivtv_i2c(itv);
free_io:
@@ -1194,7 +1193,7 @@ err:
retval = -ENODEV;
IVTV_ERR("Error %d on initialization\n", retval);
- v4l2_device_unregister(&itv->device);
+ v4l2_device_unregister(&itv->v4l2_dev);
kfree(itv);
return retval;
}
@@ -1292,10 +1291,10 @@ int ivtv_init_on_first_open(struct ivtv *itv)
return 0;
}
-static void ivtv_remove(struct pci_dev *pci_dev)
+static void ivtv_remove(struct pci_dev *pdev)
{
- struct v4l2_device *dev = dev_get_drvdata(&pci_dev->dev);
- struct ivtv *itv = to_ivtv(dev);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct ivtv *itv = to_ivtv(v4l2_dev);
int i;
IVTV_DEBUG_INFO("Removing card\n");
@@ -1336,11 +1335,9 @@ static void ivtv_remove(struct pci_dev *pci_dev)
ivtv_streams_cleanup(itv, 1);
ivtv_udma_free(itv);
- v4l2_device_unregister(&itv->device);
-
exit_ivtv_i2c(itv);
- free_irq(itv->dev->irq, (void *)itv);
+ free_irq(itv->pdev->irq, (void *)itv);
ivtv_iounmap(itv);
release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
@@ -1348,11 +1345,13 @@ static void ivtv_remove(struct pci_dev *pci_dev)
if (itv->has_cx23415)
release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
- pci_disable_device(itv->dev);
+ pci_disable_device(itv->pdev);
for (i = 0; i < IVTV_VBI_FRAMES; i++)
kfree(itv->vbi.sliced_mpeg_data[i]);
printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name);
+
+ v4l2_device_unregister(&itv->v4l2_dev);
kfree(itv);
}
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index ce8d9b74357e..440f7328a7ed 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -133,7 +133,7 @@ extern int ivtv_debug;
#define IVTV_DEBUG(x, type, fmt, args...) \
do { \
if ((x) & ivtv_debug) \
- v4l2_info(&itv->device, " " type ": " fmt , ##args); \
+ v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \
} while (0)
#define IVTV_DEBUG_WARN(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_WARN, "warn", fmt , ## args)
#define IVTV_DEBUG_INFO(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args)
@@ -149,7 +149,7 @@ extern int ivtv_debug;
#define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \
do { \
if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \
- v4l2_info(&itv->device, " " type ": " fmt , ##args); \
+ v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \
} while (0)
#define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warn", fmt , ## args)
#define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info", fmt , ## args)
@@ -163,9 +163,9 @@ extern int ivtv_debug;
#define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
/* Standard kernel messages */
-#define IVTV_ERR(fmt, args...) v4l2_err(&itv->device, fmt , ## args)
-#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->device, fmt , ## args)
-#define IVTV_INFO(fmt, args...) v4l2_info(&itv->device, fmt , ## args)
+#define IVTV_ERR(fmt, args...) v4l2_err(&itv->v4l2_dev, fmt , ## args)
+#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->v4l2_dev, fmt , ## args)
+#define IVTV_INFO(fmt, args...) v4l2_info(&itv->v4l2_dev, fmt , ## args)
/* output modes (cx23415 only) */
#define OUT_NONE 0
@@ -315,7 +315,7 @@ struct ivtv; /* forward reference */
struct ivtv_stream {
/* These first four fields are always set, even if the stream
is not actually created. */
- struct video_device *v4l2dev; /* NULL when stream not created */
+ struct video_device *vdev; /* NULL when stream not created */
struct ivtv *itv; /* for ease of use */
const char *name; /* name of the stream */
int type; /* stream type */
@@ -592,7 +592,7 @@ struct ivtv_card;
/* Struct to hold info about ivtv cards */
struct ivtv {
/* General fixed card data */
- struct pci_dev *dev; /* PCI device */
+ struct pci_dev *pdev; /* PCI device */
const struct ivtv_card *card; /* card information */
const char *card_name; /* full name of the card */
const struct ivtv_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
@@ -612,7 +612,7 @@ struct ivtv {
volatile void __iomem *reg_mem; /* pointer to mapped registers */
struct ivtv_options options; /* user options */
- struct v4l2_device device;
+ struct v4l2_device v4l2_dev;
struct v4l2_subdev sd_gpio; /* GPIO sub-device */
u16 instance;
@@ -696,7 +696,7 @@ struct ivtv {
u64 vbi_data_inserted; /* number of VBI bytes inserted into the MPEG stream */
u32 last_dec_timing[3]; /* cache last retrieved pts/scr/frame values */
unsigned long dualwatch_jiffies;/* jiffies value of the previous dualwatch check */
- u16 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */
+ u32 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */
/* VBI state info */
@@ -719,9 +719,9 @@ struct ivtv {
struct osd_info *osd_info; /* ivtvfb private OSD info */
};
-static inline struct ivtv *to_ivtv(struct v4l2_device *dev)
+static inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev)
{
- return container_of(dev, struct ivtv, device);
+ return container_of(v4l2_dev, struct ivtv, v4l2_dev);
}
/* Globals */
@@ -788,7 +788,7 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv)
/* Call the specified callback for all subdevs matching hw (if 0, then
match them all). Ignore any errors. */
#define ivtv_call_hw(itv, hw, o, f, args...) \
- __v4l2_device_call_subdevs(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+ __v4l2_device_call_subdevs(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
#define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args)
@@ -796,7 +796,7 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv)
match them all). If the callback returns an error other than 0 or
-ENOIOCTLCMD, then return with that error code. */
#define ivtv_call_hw_err(itv, hw, o, f, args...) \
- __v4l2_device_call_subdevs_until_err(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+ __v4l2_device_call_subdevs_until_err(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
#define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args)
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index d594bc29f07f..cfaacf6096d0 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -148,10 +148,10 @@ void ivtv_release_stream(struct ivtv_stream *s)
static void ivtv_dualwatch(struct ivtv *itv)
{
struct v4l2_tuner vt;
- u16 new_bitmap;
- u16 new_stereo_mode;
- const u16 stereo_mask = 0x0300;
- const u16 dual = 0x0200;
+ u32 new_bitmap;
+ u32 new_stereo_mode;
+ const u32 stereo_mask = 0x0300;
+ const u32 dual = 0x0200;
new_stereo_mode = itv->params.audio_properties & stereo_mask;
memset(&vt, 0, sizeof(vt));
@@ -991,7 +991,7 @@ int ivtv_v4l2_open(struct file *filp)
mutex_lock(&itv->serialize_lock);
if (ivtv_init_on_first_open(itv)) {
IVTV_ERR("Failed to initialize on minor %d\n",
- s->v4l2dev->minor);
+ vdev->minor);
mutex_unlock(&itv->serialize_lock);
return -ENXIO;
}
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c
index 6dba55b7e25a..c1b7ec475c27 100644
--- a/drivers/media/video/ivtv/ivtv-firmware.c
+++ b/drivers/media/video/ivtv/ivtv-firmware.c
@@ -52,7 +52,7 @@ static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv
int retries = 3;
retry:
- if (retries && request_firmware(&fw, fn, &itv->dev->dev) == 0) {
+ if (retries && request_firmware(&fw, fn, &itv->pdev->dev) == 0) {
int i;
volatile u32 __iomem *dst = (volatile u32 __iomem *)mem;
const u32 *src = (const u32 *)fw->data;
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
index dc2850e87a7e..3321983d89e5 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -384,7 +384,7 @@ int ivtv_gpio_init(struct ivtv *itv)
write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT);
write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR);
v4l2_subdev_init(&itv->sd_gpio, &subdev_ops);
- snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->device.name);
+ snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name);
itv->sd_gpio.grp_id = IVTV_HW_GPIO;
- return v4l2_device_register_subdev(&itv->device, &itv->sd_gpio);
+ return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio);
}
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index ca1d9557945e..e73a196ecc7a 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -194,14 +194,14 @@ struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw)
struct v4l2_subdev *result = NULL;
struct v4l2_subdev *sd;
- spin_lock(&itv->device.lock);
- v4l2_device_for_each_subdev(sd, &itv->device) {
+ spin_lock(&itv->v4l2_dev.lock);
+ v4l2_device_for_each_subdev(sd, &itv->v4l2_dev) {
if (sd->grp_id == hw) {
result = sd;
break;
}
}
- spin_unlock(&itv->device.lock);
+ spin_unlock(&itv->v4l2_dev.lock);
return result;
}
@@ -472,8 +472,8 @@ static int ivtv_read(struct ivtv *itv, unsigned char addr, unsigned char *data,
intervening stop condition */
static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
{
- struct v4l2_device *drv = i2c_get_adapdata(i2c_adap);
- struct ivtv *itv = to_ivtv(drv);
+ struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap);
+ struct ivtv *itv = to_ivtv(v4l2_dev);
int retval;
int i;
@@ -604,12 +604,12 @@ int init_ivtv_i2c(struct ivtv *itv)
sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d",
itv->instance);
- i2c_set_adapdata(&itv->i2c_adap, &itv->device);
+ i2c_set_adapdata(&itv->i2c_adap, &itv->v4l2_dev);
memcpy(&itv->i2c_client, &ivtv_i2c_client_template,
sizeof(struct i2c_client));
itv->i2c_client.adapter = &itv->i2c_adap;
- itv->i2c_adap.dev.parent = &itv->dev->dev;
+ itv->i2c_adap.dev.parent = &itv->pdev->dev;
IVTV_DEBUG_I2C("setting scl and sda to 1\n");
ivtv_setscl(itv, 1);
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index c13bd2aa0bea..9a0424298af1 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -345,10 +345,8 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
pixfmt->priv = 0;
if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
- /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
- pixfmt->sizeimage =
- pixfmt->height * pixfmt->width +
- pixfmt->height * (pixfmt->width / 2);
+ /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
+ pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
pixfmt->bytesperline = 720;
} else {
pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
@@ -469,11 +467,17 @@ static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format
struct ivtv *itv = id->itv;
int w = fmt->fmt.pix.width;
int h = fmt->fmt.pix.height;
+ int min_h = 2;
w = min(w, 720);
w = max(w, 2);
+ if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
+ /* YUV height must be a multiple of 32 */
+ h &= ~0x1f;
+ min_h = 32;
+ }
h = min(h, itv->is_50hz ? 576 : 480);
- h = max(h, 2);
+ h = max(h, min_h);
ivtv_g_fmt_vid_cap(file, fh, fmt);
fmt->fmt.pix.width = w;
fmt->fmt.pix.height = h;
@@ -766,7 +770,7 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc
strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
- snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->dev));
+ snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
vcap->version = IVTV_DRIVER_VERSION; /* version */
vcap->capabilities = itv->v4l2_cap; /* capabilities */
return 0;
@@ -1513,12 +1517,12 @@ static int ivtv_log_status(struct file *file, void *fh)
}
IVTV_INFO("Tuner: %s\n",
test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
- cx2341x_log_status(&itv->params, itv->device.name);
+ cx2341x_log_status(&itv->params, itv->v4l2_dev.name);
IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
for (i = 0; i < IVTV_MAX_STREAMS; i++) {
struct ivtv_stream *s = &itv->streams[i];
- if (s->v4l2dev == NULL || s->buffers == 0)
+ if (s->vdev == NULL || s->buffers == 0)
continue;
IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
(s->buffers - s->q_free.buffers) * 100 / s->buffers,
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index f5d00ec5da73..01c14d2b381a 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -46,7 +46,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv)
IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n");
if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS ||
- s->v4l2dev == NULL || !ivtv_use_pio(s)) {
+ s->vdev == NULL || !ivtv_use_pio(s)) {
itv->cur_pio_stream = -1;
/* trigger PIO complete user interrupt */
write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
@@ -109,7 +109,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
int rc;
/* sanity checks */
- if (s->v4l2dev == NULL) {
+ if (s->vdev == NULL) {
IVTV_DEBUG_WARN("Stream %s not started\n", s->name);
return -1;
}
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c
index 71bd13e22e2e..ff7b7deded4f 100644
--- a/drivers/media/video/ivtv/ivtv-queue.c
+++ b/drivers/media/video/ivtv/ivtv-queue.c
@@ -230,7 +230,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
return -ENOMEM;
}
if (ivtv_might_use_dma(s)) {
- s->sg_handle = pci_map_single(itv->dev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma);
+ s->sg_handle = pci_map_single(itv->pdev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma);
ivtv_stream_sync_for_cpu(s);
}
@@ -248,7 +248,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
}
INIT_LIST_HEAD(&buf->list);
if (ivtv_might_use_dma(s)) {
- buf->dma_handle = pci_map_single(s->itv->dev,
+ buf->dma_handle = pci_map_single(s->itv->pdev,
buf->buf, s->buf_size + 256, s->dma);
ivtv_buf_sync_for_cpu(s, buf);
}
@@ -271,7 +271,7 @@ void ivtv_stream_free(struct ivtv_stream *s)
/* empty q_free */
while ((buf = ivtv_dequeue(s, &s->q_free))) {
if (ivtv_might_use_dma(s))
- pci_unmap_single(s->itv->dev, buf->dma_handle,
+ pci_unmap_single(s->itv->pdev, buf->dma_handle,
s->buf_size + 256, s->dma);
kfree(buf->buf);
kfree(buf);
@@ -280,7 +280,7 @@ void ivtv_stream_free(struct ivtv_stream *s)
/* Free SG Array/Lists */
if (s->sg_dma != NULL) {
if (s->sg_handle != IVTV_DMA_UNMAPPED) {
- pci_unmap_single(s->itv->dev, s->sg_handle,
+ pci_unmap_single(s->itv->pdev, s->sg_handle,
sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
s->sg_handle = IVTV_DMA_UNMAPPED;
}
diff --git a/drivers/media/video/ivtv/ivtv-queue.h b/drivers/media/video/ivtv/ivtv-queue.h
index 476556afd39a..91233839a26c 100644
--- a/drivers/media/video/ivtv/ivtv-queue.h
+++ b/drivers/media/video/ivtv/ivtv-queue.h
@@ -53,14 +53,14 @@ static inline int ivtv_use_dma(struct ivtv_stream *s)
static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf)
{
if (ivtv_use_dma(s))
- pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle,
+ pci_dma_sync_single_for_cpu(s->itv->pdev, buf->dma_handle,
s->buf_size + 256, s->dma);
}
static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf)
{
if (ivtv_use_dma(s))
- pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle,
+ pci_dma_sync_single_for_device(s->itv->pdev, buf->dma_handle,
s->buf_size + 256, s->dma);
}
@@ -82,14 +82,14 @@ void ivtv_stream_free(struct ivtv_stream *s);
static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
{
if (ivtv_use_dma(s))
- pci_dma_sync_single_for_cpu(s->itv->dev, s->sg_handle,
+ pci_dma_sync_single_for_cpu(s->itv->pdev, s->sg_handle,
sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
}
static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
{
if (ivtv_use_dma(s))
- pci_dma_sync_single_for_device(s->itv->dev, s->sg_handle,
+ pci_dma_sync_single_for_device(s->itv->pdev, s->sg_handle,
sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
}
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 854a950af78c..15da01710efc 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -137,11 +137,11 @@ static struct {
static void ivtv_stream_init(struct ivtv *itv, int type)
{
struct ivtv_stream *s = &itv->streams[type];
- struct video_device *dev = s->v4l2dev;
+ struct video_device *vdev = s->vdev;
- /* we need to keep v4l2dev, so restore it afterwards */
+ /* we need to keep vdev, so restore it afterwards */
memset(s, 0, sizeof(*s));
- s->v4l2dev = dev;
+ s->vdev = vdev;
/* initialize ivtv_stream fields */
s->itv = itv;
@@ -172,10 +172,10 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
int num_offset = ivtv_stream_info[type].num_offset;
int num = itv->instance + ivtv_first_minor + num_offset;
- /* These four fields are always initialized. If v4l2dev == NULL, then
+ /* These four fields are always initialized. If vdev == NULL, then
this stream is not in use. In that case no other fields but these
four can be used. */
- s->v4l2dev = NULL;
+ s->vdev = NULL;
s->itv = itv;
s->type = type;
s->name = ivtv_stream_info[type].name;
@@ -197,21 +197,21 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
ivtv_stream_init(itv, type);
/* allocate and initialize the v4l2 video device structure */
- s->v4l2dev = video_device_alloc();
- if (s->v4l2dev == NULL) {
+ s->vdev = video_device_alloc();
+ if (s->vdev == NULL) {
IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name);
return -ENOMEM;
}
- snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "%s %s",
- itv->device.name, s->name);
+ snprintf(s->vdev->name, sizeof(s->vdev->name), "%s %s",
+ itv->v4l2_dev.name, s->name);
- s->v4l2dev->num = num;
- s->v4l2dev->v4l2_dev = &itv->device;
- s->v4l2dev->fops = ivtv_stream_info[type].fops;
- s->v4l2dev->release = video_device_release;
- s->v4l2dev->tvnorms = V4L2_STD_ALL;
- ivtv_set_funcs(s->v4l2dev);
+ s->vdev->num = num;
+ s->vdev->v4l2_dev = &itv->v4l2_dev;
+ s->vdev->fops = ivtv_stream_info[type].fops;
+ s->vdev->release = video_device_release;
+ s->vdev->tvnorms = V4L2_STD_ALL;
+ ivtv_set_funcs(s->vdev);
return 0;
}
@@ -226,7 +226,7 @@ int ivtv_streams_setup(struct ivtv *itv)
if (ivtv_prep_dev(itv, type))
break;
- if (itv->streams[type].v4l2dev == NULL)
+ if (itv->streams[type].vdev == NULL)
continue;
/* Allocate Stream */
@@ -247,28 +247,28 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
int vfl_type = ivtv_stream_info[type].vfl_type;
int num;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return 0;
- num = s->v4l2dev->num;
+ num = s->vdev->num;
/* card number + user defined offset + device offset */
if (type != IVTV_ENC_STREAM_TYPE_MPG) {
struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG];
- if (s_mpg->v4l2dev)
- num = s_mpg->v4l2dev->num + ivtv_stream_info[type].num_offset;
+ if (s_mpg->vdev)
+ num = s_mpg->vdev->num + ivtv_stream_info[type].num_offset;
}
- video_set_drvdata(s->v4l2dev, s);
+ video_set_drvdata(s->vdev, s);
/* Register device. First try the desired minor, then any free one. */
- if (video_register_device(s->v4l2dev, vfl_type, num)) {
+ if (video_register_device(s->vdev, vfl_type, num)) {
IVTV_ERR("Couldn't register v4l2 device for %s kernel number %d\n",
s->name, num);
- video_device_release(s->v4l2dev);
- s->v4l2dev = NULL;
+ video_device_release(s->vdev);
+ s->vdev = NULL;
return -ENOMEM;
}
- num = s->v4l2dev->num;
+ num = s->vdev->num;
switch (vfl_type) {
case VFL_TYPE_GRABBER:
@@ -316,9 +316,9 @@ void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
/* Teardown all streams */
for (type = 0; type < IVTV_MAX_STREAMS; type++) {
- struct video_device *vdev = itv->streams[type].v4l2dev;
+ struct video_device *vdev = itv->streams[type].vdev;
- itv->streams[type].v4l2dev = NULL;
+ itv->streams[type].vdev = NULL;
if (vdev == NULL)
continue;
@@ -449,7 +449,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
int captype = 0, subtype = 0;
int enable_passthrough = 0;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name);
@@ -611,7 +611,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
struct cx2341x_mpeg_params *p = &itv->params;
int datatype;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
IVTV_DEBUG_INFO("Setting some initial decoder settings\n");
@@ -657,7 +657,7 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset)
{
struct ivtv *itv = s->itv;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags))
@@ -705,7 +705,7 @@ void ivtv_stop_all_captures(struct ivtv *itv)
for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) {
struct ivtv_stream *s = &itv->streams[i];
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
continue;
if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
ivtv_stop_v4l2_encode_stream(s, 0);
@@ -720,7 +720,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
int cap_type;
int stopmode;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
/* This function assumes that you are allowed to stop the capture
@@ -834,7 +834,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
{
struct ivtv *itv = s->itv;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG)
@@ -895,7 +895,7 @@ int ivtv_passthrough_mode(struct ivtv *itv, int enable)
struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV];
struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
- if (yuv_stream->v4l2dev == NULL || dec_stream->v4l2dev == NULL)
+ if (yuv_stream->vdev == NULL || dec_stream->vdev == NULL)
return -EINVAL;
IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n");
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index 460db03b0ba0..d07ad6c39024 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -93,7 +93,7 @@ void ivtv_udma_alloc(struct ivtv *itv)
{
if (itv->udma.SG_handle == 0) {
/* Map DMA Page Array Buffer */
- itv->udma.SG_handle = pci_map_single(itv->dev, itv->udma.SGarray,
+ itv->udma.SG_handle = pci_map_single(itv->pdev, itv->udma.SGarray,
sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
ivtv_udma_sync_for_cpu(itv);
}
@@ -147,7 +147,7 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
}
/* Map SG List */
- dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
+ dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
/* Fill SG Array with new values */
ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1);
@@ -172,7 +172,7 @@ void ivtv_udma_unmap(struct ivtv *itv)
/* Unmap Scatterlist */
if (dma->SG_length) {
- pci_unmap_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
+ pci_unmap_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
dma->SG_length = 0;
}
/* sync DMA */
@@ -191,13 +191,13 @@ void ivtv_udma_free(struct ivtv *itv)
/* Unmap SG Array */
if (itv->udma.SG_handle) {
- pci_unmap_single(itv->dev, itv->udma.SG_handle,
+ pci_unmap_single(itv->pdev, itv->udma.SG_handle,
sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
}
/* Unmap Scatterlist */
if (itv->udma.SG_length) {
- pci_unmap_sg(itv->dev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE);
+ pci_unmap_sg(itv->pdev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE);
}
for (i = 0; i < IVTV_DMA_SG_OSD_ENT; i++) {
diff --git a/drivers/media/video/ivtv/ivtv-udma.h b/drivers/media/video/ivtv/ivtv-udma.h
index df727e23be0a..ee3c9efb5b72 100644
--- a/drivers/media/video/ivtv/ivtv-udma.h
+++ b/drivers/media/video/ivtv/ivtv-udma.h
@@ -35,13 +35,13 @@ void ivtv_udma_start(struct ivtv *itv);
static inline void ivtv_udma_sync_for_device(struct ivtv *itv)
{
- pci_dma_sync_single_for_device((struct pci_dev *)itv->dev, itv->udma.SG_handle,
+ pci_dma_sync_single_for_device(itv->pdev, itv->udma.SG_handle,
sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
}
static inline void ivtv_udma_sync_for_cpu(struct ivtv *itv)
{
- pci_dma_sync_single_for_cpu((struct pci_dev *)itv->dev, itv->udma.SG_handle,
+ pci_dma_sync_single_for_cpu(itv->pdev, itv->udma.SG_handle,
sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
}
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index 5c5d1c462fef..f420d31b937d 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -185,6 +185,8 @@ static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
size = 4 + ((43 * line + 3) & ~3);
} else {
memcpy(dst + sd, "itv0", 4);
+ cpu_to_le32s(&linemask[0]);
+ cpu_to_le32s(&linemask[1]);
memcpy(dst + sd + 4, &linemask[0], 8);
size = 12 + ((43 * line + 3) & ~3);
}
diff --git a/drivers/media/video/ivtv/ivtv-version.h b/drivers/media/video/ivtv/ivtv-version.h
index 8cd753d30bf7..b530dec399d3 100644
--- a/drivers/media/video/ivtv/ivtv-version.h
+++ b/drivers/media/video/ivtv/ivtv-version.h
@@ -23,7 +23,7 @@
#define IVTV_DRIVER_NAME "ivtv"
#define IVTV_DRIVER_VERSION_MAJOR 1
#define IVTV_DRIVER_VERSION_MINOR 4
-#define IVTV_DRIVER_VERSION_PATCHLEVEL 0
+#define IVTV_DRIVER_VERSION_PATCHLEVEL 1
#define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL)
#define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index ee91107376c7..7912ed6b72ee 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -103,7 +103,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
dma->page_count = 0;
return -ENOMEM;
}
- dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
+ dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
/* Fill SG Array with new values */
ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
@@ -910,7 +910,7 @@ static void ivtv_yuv_init(struct ivtv *itv)
/* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
if (yi->blanking_ptr) {
- yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
+ yi->blanking_dmaptr = pci_map_single(itv->pdev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
} else {
yi->blanking_dmaptr = 0;
IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
@@ -1237,7 +1237,7 @@ void ivtv_yuv_close(struct ivtv *itv)
if (yi->blanking_ptr) {
kfree(yi->blanking_ptr);
yi->blanking_ptr = NULL;
- pci_unmap_single(itv->dev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
+ pci_unmap_single(itv->pdev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
}
/* Invalidate the old dimension information */
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 36abd2aef6f1..66e6eb513076 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -1192,12 +1192,12 @@ static int ivtvfb_init_card(struct ivtv *itv)
static int __init ivtvfb_callback_init(struct device *dev, void *p)
{
struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device);
+ struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
if (ivtvfb_init_card(itv) == 0) {
IVTVFB_INFO("Framebuffer registered on %s\n",
- itv->device.name);
+ itv->v4l2_dev.name);
(*(int *)p)++;
}
}
@@ -1207,7 +1207,7 @@ static int __init ivtvfb_callback_init(struct device *dev, void *p)
static int ivtvfb_callback_cleanup(struct device *dev, void *p)
{
struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device);
+ struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
index bae2d2beb709..841024b6bcdf 100644
--- a/drivers/media/video/ks0127.c
+++ b/drivers/media/video/ks0127.c
@@ -39,19 +39,20 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
#include "ks0127.h"
MODULE_DESCRIPTION("KS0127 video decoder driver");
MODULE_AUTHOR("Ryan Drake");
MODULE_LICENSE("GPL");
-#define KS_TYPE_UNKNOWN 0
-#define KS_TYPE_0122S 1
-#define KS_TYPE_0127 2
-#define KS_TYPE_0127B 3
+/* Addresses */
+#define I2C_KS0127_ADDON 0xD8
+#define I2C_KS0127_ONBOARD 0xDA
+
/* ks0127 control registers */
#define KS_STAT 0x00
@@ -197,15 +198,17 @@ struct adjust {
};
struct ks0127 {
- int format_width;
- int format_height;
- int cap_width;
- int cap_height;
- int norm;
- int ks_type;
+ struct v4l2_subdev sd;
+ v4l2_std_id norm;
+ int ident;
u8 regs[256];
};
+static inline struct ks0127 *to_ks0127(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct ks0127, sd);
+}
+
static int debug; /* insmod parameter */
@@ -311,43 +314,45 @@ static void init_reg_defaults(void)
*/
-static u8 ks0127_read(struct i2c_client *c, u8 reg)
+static u8 ks0127_read(struct v4l2_subdev *sd, u8 reg)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
char val = 0;
struct i2c_msg msgs[] = {
- { c->addr, 0, sizeof(reg), &reg },
- { c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val }
+ { client->addr, 0, sizeof(reg), &reg },
+ { client->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val }
};
int ret;
- ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs));
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (ret != ARRAY_SIZE(msgs))
- v4l_dbg(1, debug, c, "read error\n");
+ v4l2_dbg(1, debug, sd, "read error\n");
return val;
}
-static void ks0127_write(struct i2c_client *c, u8 reg, u8 val)
+static void ks0127_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
- struct ks0127 *ks = i2c_get_clientdata(c);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ks0127 *ks = to_ks0127(sd);
char msg[] = { reg, val };
- if (i2c_master_send(c, msg, sizeof(msg)) != sizeof(msg))
- v4l_dbg(1, debug, c, "write error\n");
+ if (i2c_master_send(client, msg, sizeof(msg)) != sizeof(msg))
+ v4l2_dbg(1, debug, sd, "write error\n");
ks->regs[reg] = val;
}
/* generic bit-twiddling */
-static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v)
+static void ks0127_and_or(struct v4l2_subdev *sd, u8 reg, u8 and_v, u8 or_v)
{
- struct ks0127 *ks = i2c_get_clientdata(client);
+ struct ks0127 *ks = to_ks0127(sd);
u8 val = ks->regs[reg];
val = (val & and_v) | or_v;
- ks0127_write(client, reg, val);
+ ks0127_write(sd, reg, val);
}
@@ -355,439 +360,363 @@ static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v)
/****************************************************************************
* ks0127 private api
****************************************************************************/
-static void ks0127_reset(struct i2c_client *c)
+static void ks0127_init(struct v4l2_subdev *sd)
{
- struct ks0127 *ks = i2c_get_clientdata(c);
+ struct ks0127 *ks = to_ks0127(sd);
u8 *table = reg_defaults;
int i;
- ks->ks_type = KS_TYPE_UNKNOWN;
+ ks->ident = V4L2_IDENT_KS0127;
- v4l_dbg(1, debug, c, "reset\n");
+ v4l2_dbg(1, debug, sd, "reset\n");
msleep(1);
/* initialize all registers to known values */
/* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */
for (i = 1; i < 33; i++)
- ks0127_write(c, i, table[i]);
+ ks0127_write(sd, i, table[i]);
for (i = 35; i < 40; i++)
- ks0127_write(c, i, table[i]);
+ ks0127_write(sd, i, table[i]);
for (i = 41; i < 56; i++)
- ks0127_write(c, i, table[i]);
+ ks0127_write(sd, i, table[i]);
for (i = 58; i < 64; i++)
- ks0127_write(c, i, table[i]);
+ ks0127_write(sd, i, table[i]);
- if ((ks0127_read(c, KS_STAT) & 0x80) == 0) {
- ks->ks_type = KS_TYPE_0122S;
- v4l_dbg(1, debug, c, "ks0122s found\n");
+ if ((ks0127_read(sd, KS_STAT) & 0x80) == 0) {
+ ks->ident = V4L2_IDENT_KS0122S;
+ v4l2_dbg(1, debug, sd, "ks0122s found\n");
return;
}
- switch (ks0127_read(c, KS_CMDE) & 0x0f) {
+ switch (ks0127_read(sd, KS_CMDE) & 0x0f) {
case 0:
- ks->ks_type = KS_TYPE_0127;
- v4l_dbg(1, debug, c, "ks0127 found\n");
+ v4l2_dbg(1, debug, sd, "ks0127 found\n");
break;
case 9:
- ks->ks_type = KS_TYPE_0127B;
- v4l_dbg(1, debug, c, "ks0127B Revision A found\n");
+ ks->ident = V4L2_IDENT_KS0127B;
+ v4l2_dbg(1, debug, sd, "ks0127B Revision A found\n");
break;
default:
- v4l_dbg(1, debug, c, "unknown revision\n");
+ v4l2_dbg(1, debug, sd, "unknown revision\n");
break;
}
}
-static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
+static int ks0127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
{
- struct ks0127 *ks = i2c_get_clientdata(c);
- int *iarg = (int *)arg;
- int status;
-
- if (!ks)
- return -ENODEV;
+ struct ks0127 *ks = to_ks0127(sd);
+
+ switch (route->input) {
+ case KS_INPUT_COMPOSITE_1:
+ case KS_INPUT_COMPOSITE_2:
+ case KS_INPUT_COMPOSITE_3:
+ case KS_INPUT_COMPOSITE_4:
+ case KS_INPUT_COMPOSITE_5:
+ case KS_INPUT_COMPOSITE_6:
+ v4l2_dbg(1, debug, sd,
+ "s_routing %d: Composite\n", route->input);
+ /* autodetect 50/60 Hz */
+ ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00);
+ /* VSE=0 */
+ ks0127_and_or(sd, KS_CMDA, ~0x40, 0x00);
+ /* set input line */
+ ks0127_and_or(sd, KS_CMDB, 0xb0, route->input);
+ /* non-freerunning mode */
+ ks0127_and_or(sd, KS_CMDC, 0x70, 0x0a);
+ /* analog input */
+ ks0127_and_or(sd, KS_CMDD, 0x03, 0x00);
+ /* enable chroma demodulation */
+ ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00);
+ /* chroma trap, HYBWR=1 */
+ ks0127_and_or(sd, KS_LUMA, 0x00,
+ (reg_defaults[KS_LUMA])|0x0c);
+ /* scaler fullbw, luma comb off */
+ ks0127_and_or(sd, KS_VERTIA, 0x08, 0x81);
+ /* manual chroma comb .25 .5 .25 */
+ ks0127_and_or(sd, KS_VERTIC, 0x0f, 0x90);
+
+ /* chroma path delay */
+ ks0127_and_or(sd, KS_CHROMB, 0x0f, 0x90);
+
+ ks0127_write(sd, KS_UGAIN, reg_defaults[KS_UGAIN]);
+ ks0127_write(sd, KS_VGAIN, reg_defaults[KS_VGAIN]);
+ ks0127_write(sd, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+ ks0127_write(sd, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
+ break;
- switch (cmd) {
- case DECODER_INIT:
- v4l_dbg(1, debug, c, "DECODER_INIT\n");
- ks0127_reset(c);
+ case KS_INPUT_SVIDEO_1:
+ case KS_INPUT_SVIDEO_2:
+ case KS_INPUT_SVIDEO_3:
+ v4l2_dbg(1, debug, sd,
+ "s_routing %d: S-Video\n", route->input);
+ /* autodetect 50/60 Hz */
+ ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00);
+ /* VSE=0 */
+ ks0127_and_or(sd, KS_CMDA, ~0x40, 0x00);
+ /* set input line */
+ ks0127_and_or(sd, KS_CMDB, 0xb0, route->input);
+ /* non-freerunning mode */
+ ks0127_and_or(sd, KS_CMDC, 0x70, 0x0a);
+ /* analog input */
+ ks0127_and_or(sd, KS_CMDD, 0x03, 0x00);
+ /* enable chroma demodulation */
+ ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00);
+ ks0127_and_or(sd, KS_LUMA, 0x00,
+ reg_defaults[KS_LUMA]);
+ /* disable luma comb */
+ ks0127_and_or(sd, KS_VERTIA, 0x08,
+ (reg_defaults[KS_VERTIA]&0xf0)|0x01);
+ ks0127_and_or(sd, KS_VERTIC, 0x0f,
+ reg_defaults[KS_VERTIC]&0xf0);
+
+ ks0127_and_or(sd, KS_CHROMB, 0x0f,
+ reg_defaults[KS_CHROMB]&0xf0);
+
+ ks0127_write(sd, KS_UGAIN, reg_defaults[KS_UGAIN]);
+ ks0127_write(sd, KS_VGAIN, reg_defaults[KS_VGAIN]);
+ ks0127_write(sd, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+ ks0127_write(sd, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
break;
- case DECODER_SET_INPUT:
- switch(*iarg) {
- case KS_INPUT_COMPOSITE_1:
- case KS_INPUT_COMPOSITE_2:
- case KS_INPUT_COMPOSITE_3:
- case KS_INPUT_COMPOSITE_4:
- case KS_INPUT_COMPOSITE_5:
- case KS_INPUT_COMPOSITE_6:
- v4l_dbg(1, debug, c,
- "DECODER_SET_INPUT %d: Composite\n", *iarg);
- /* autodetect 50/60 Hz */
- ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
- /* VSE=0 */
- ks0127_and_or(c, KS_CMDA, ~0x40, 0x00);
- /* set input line */
- ks0127_and_or(c, KS_CMDB, 0xb0, *iarg);
- /* non-freerunning mode */
- ks0127_and_or(c, KS_CMDC, 0x70, 0x0a);
- /* analog input */
- ks0127_and_or(c, KS_CMDD, 0x03, 0x00);
- /* enable chroma demodulation */
- ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00);
- /* chroma trap, HYBWR=1 */
- ks0127_and_or(c, KS_LUMA, 0x00,
- (reg_defaults[KS_LUMA])|0x0c);
- /* scaler fullbw, luma comb off */
- ks0127_and_or(c, KS_VERTIA, 0x08, 0x81);
- /* manual chroma comb .25 .5 .25 */
- ks0127_and_or(c, KS_VERTIC, 0x0f, 0x90);
-
- /* chroma path delay */
- ks0127_and_or(c, KS_CHROMB, 0x0f, 0x90);
-
- ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]);
- ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]);
- ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
- ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
- break;
-
- case KS_INPUT_SVIDEO_1:
- case KS_INPUT_SVIDEO_2:
- case KS_INPUT_SVIDEO_3:
- v4l_dbg(1, debug, c,
- "DECODER_SET_INPUT %d: S-Video\n", *iarg);
- /* autodetect 50/60 Hz */
- ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
- /* VSE=0 */
- ks0127_and_or(c, KS_CMDA, ~0x40, 0x00);
- /* set input line */
- ks0127_and_or(c, KS_CMDB, 0xb0, *iarg);
- /* non-freerunning mode */
- ks0127_and_or(c, KS_CMDC, 0x70, 0x0a);
- /* analog input */
- ks0127_and_or(c, KS_CMDD, 0x03, 0x00);
- /* enable chroma demodulation */
- ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00);
- ks0127_and_or(c, KS_LUMA, 0x00,
- reg_defaults[KS_LUMA]);
- /* disable luma comb */
- ks0127_and_or(c, KS_VERTIA, 0x08,
- (reg_defaults[KS_VERTIA]&0xf0)|0x01);
- ks0127_and_or(c, KS_VERTIC, 0x0f,
- reg_defaults[KS_VERTIC]&0xf0);
-
- ks0127_and_or(c, KS_CHROMB, 0x0f,
- reg_defaults[KS_CHROMB]&0xf0);
-
- ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]);
- ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]);
- ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
- ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
- break;
-
- case KS_INPUT_YUV656:
- v4l_dbg(1, debug, c,
- "DECODER_SET_INPUT 15: YUV656\n");
- if (ks->norm == VIDEO_MODE_NTSC ||
- ks->norm == KS_STD_PAL_M)
- /* force 60 Hz */
- ks0127_and_or(c, KS_CMDA, 0xfc, 0x03);
- else
- /* force 50 Hz */
- ks0127_and_or(c, KS_CMDA, 0xfc, 0x02);
-
- ks0127_and_or(c, KS_CMDA, 0xff, 0x40); /* VSE=1 */
- /* set input line and VALIGN */
- ks0127_and_or(c, KS_CMDB, 0xb0, (*iarg | 0x40));
- /* freerunning mode, */
- /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/
- ks0127_and_or(c, KS_CMDC, 0x70, 0x87);
- /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
- ks0127_and_or(c, KS_CMDD, 0x03, 0x08);
- /* disable chroma demodulation */
- ks0127_and_or(c, KS_CTRACK, 0xcf, 0x30);
- /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
- ks0127_and_or(c, KS_LUMA, 0x00, 0x71);
- ks0127_and_or(c, KS_VERTIC, 0x0f,
- reg_defaults[KS_VERTIC]&0xf0);
-
- /* scaler fullbw, luma comb off */
- ks0127_and_or(c, KS_VERTIA, 0x08, 0x81);
-
- ks0127_and_or(c, KS_CHROMB, 0x0f,
- reg_defaults[KS_CHROMB]&0xf0);
-
- ks0127_and_or(c, KS_CON, 0x00, 0x00);
- ks0127_and_or(c, KS_BRT, 0x00, 32); /* spec: 34 */
- /* spec: 229 (e5) */
- ks0127_and_or(c, KS_SAT, 0x00, 0xe8);
- ks0127_and_or(c, KS_HUE, 0x00, 0);
-
- ks0127_and_or(c, KS_UGAIN, 0x00, 238);
- ks0127_and_or(c, KS_VGAIN, 0x00, 0x00);
-
- /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
- ks0127_and_or(c, KS_UVOFFH, 0x00, 0x4f);
- ks0127_and_or(c, KS_UVOFFL, 0x00, 0x00);
- break;
-
- default:
- v4l_dbg(1, debug, c,
- "DECODER_SET_INPUT: Unknown input %d\n", *iarg);
- break;
- }
-
- /* hack: CDMLPF sometimes spontaneously switches on; */
- /* force back off */
- ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]);
+ case KS_INPUT_YUV656:
+ v4l2_dbg(1, debug, sd, "s_routing 15: YUV656\n");
+ if (ks->norm & V4L2_STD_525_60)
+ /* force 60 Hz */
+ ks0127_and_or(sd, KS_CMDA, 0xfc, 0x03);
+ else
+ /* force 50 Hz */
+ ks0127_and_or(sd, KS_CMDA, 0xfc, 0x02);
+
+ ks0127_and_or(sd, KS_CMDA, 0xff, 0x40); /* VSE=1 */
+ /* set input line and VALIGN */
+ ks0127_and_or(sd, KS_CMDB, 0xb0, (route->input | 0x40));
+ /* freerunning mode, */
+ /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/
+ ks0127_and_or(sd, KS_CMDC, 0x70, 0x87);
+ /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
+ ks0127_and_or(sd, KS_CMDD, 0x03, 0x08);
+ /* disable chroma demodulation */
+ ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x30);
+ /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
+ ks0127_and_or(sd, KS_LUMA, 0x00, 0x71);
+ ks0127_and_or(sd, KS_VERTIC, 0x0f,
+ reg_defaults[KS_VERTIC]&0xf0);
+
+ /* scaler fullbw, luma comb off */
+ ks0127_and_or(sd, KS_VERTIA, 0x08, 0x81);
+
+ ks0127_and_or(sd, KS_CHROMB, 0x0f,
+ reg_defaults[KS_CHROMB]&0xf0);
+
+ ks0127_and_or(sd, KS_CON, 0x00, 0x00);
+ ks0127_and_or(sd, KS_BRT, 0x00, 32); /* spec: 34 */
+ /* spec: 229 (e5) */
+ ks0127_and_or(sd, KS_SAT, 0x00, 0xe8);
+ ks0127_and_or(sd, KS_HUE, 0x00, 0);
+
+ ks0127_and_or(sd, KS_UGAIN, 0x00, 238);
+ ks0127_and_or(sd, KS_VGAIN, 0x00, 0x00);
+
+ /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
+ ks0127_and_or(sd, KS_UVOFFH, 0x00, 0x4f);
+ ks0127_and_or(sd, KS_UVOFFL, 0x00, 0x00);
break;
- case DECODER_SET_OUTPUT:
- switch(*iarg) {
- case KS_OUTPUT_YUV656E:
- v4l_dbg(1, debug, c,
- "DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n");
- return -EINVAL;
-
- case KS_OUTPUT_EXV:
- v4l_dbg(1, debug, c,
- "DECODER_SET_OUTPUT: OUTPUT_EXV\n");
- ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09);
- break;
- }
+ default:
+ v4l2_dbg(1, debug, sd,
+ "s_routing: Unknown input %d\n", route->input);
break;
+ }
- case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */
- /* Set to automatic SECAM/Fsc mode */
- ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00);
-
- ks->norm = *iarg;
- switch (*iarg) {
- /* this is untested !! */
- /* It just detects PAL_N/NTSC_M (no special frequencies) */
- /* And you have to set the standard a second time afterwards */
- case VIDEO_MODE_AUTO:
- v4l_dbg(1, debug, c,
- "DECODER_SET_NORM: AUTO\n");
-
- /* The chip determines the format */
- /* based on the current field rate */
- ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
- ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
- /* This is wrong for PAL ! As I said, */
- /* you need to set the standard once again !! */
- ks->format_height = 240;
- ks->format_width = 704;
- break;
-
- case VIDEO_MODE_NTSC:
- v4l_dbg(1, debug, c,
- "DECODER_SET_NORM: NTSC_M\n");
- ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
- ks->format_height = 240;
- ks->format_width = 704;
- break;
-
- case KS_STD_NTSC_N:
- v4l_dbg(1, debug, c,
- "KS0127_SET_NORM: NTSC_N (fixme)\n");
- ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
- ks->format_height = 240;
- ks->format_width = 704;
- break;
-
- case VIDEO_MODE_PAL:
- v4l_dbg(1, debug, c,
- "DECODER_SET_NORM: PAL_N\n");
- ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
- ks->format_height = 290;
- ks->format_width = 704;
- break;
-
- case KS_STD_PAL_M:
- v4l_dbg(1, debug, c,
- "KS0127_SET_NORM: PAL_M (fixme)\n");
- ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
- ks->format_height = 290;
- ks->format_width = 704;
- break;
-
- case VIDEO_MODE_SECAM:
- v4l_dbg(1, debug, c,
- "KS0127_SET_NORM: SECAM\n");
- ks->format_height = 290;
- ks->format_width = 704;
-
- /* set to secam autodetection */
- ks0127_and_or(c, KS_CHROMA, 0xdf, 0x20);
- ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00);
- schedule_timeout_interruptible(HZ/10+1);
-
- /* did it autodetect? */
- if (ks0127_read(c, KS_DEMOD) & 0x40)
- break;
+ /* hack: CDMLPF sometimes spontaneously switches on; */
+ /* force back off */
+ ks0127_write(sd, KS_DEMOD, reg_defaults[KS_DEMOD]);
+ return 0;
+}
+static int ks0127_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct ks0127 *ks = to_ks0127(sd);
+
+ /* Set to automatic SECAM/Fsc mode */
+ ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x00);
+
+ ks->norm = std;
+ if (std & V4L2_STD_NTSC) {
+ v4l2_dbg(1, debug, sd,
+ "s_std: NTSC_M\n");
+ ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20);
+ } else if (std & V4L2_STD_PAL_N) {
+ v4l2_dbg(1, debug, sd,
+ "s_std: NTSC_N (fixme)\n");
+ ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40);
+ } else if (std & V4L2_STD_PAL) {
+ v4l2_dbg(1, debug, sd,
+ "s_std: PAL_N\n");
+ ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20);
+ } else if (std & V4L2_STD_PAL_M) {
+ v4l2_dbg(1, debug, sd,
+ "s_std: PAL_M (fixme)\n");
+ ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40);
+ } else if (std & V4L2_STD_SECAM) {
+ v4l2_dbg(1, debug, sd,
+ "s_std: SECAM\n");
+
+ /* set to secam autodetection */
+ ks0127_and_or(sd, KS_CHROMA, 0xdf, 0x20);
+ ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x00);
+ schedule_timeout_interruptible(HZ/10+1);
+
+ /* did it autodetect? */
+ if (!(ks0127_read(sd, KS_DEMOD) & 0x40))
/* force to secam mode */
- ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f);
- break;
-
- default:
- v4l_dbg(1, debug, c,
- "DECODER_SET_NORM: Unknown norm %d\n", *iarg);
- break;
- }
- break;
-
- case DECODER_SET_PICTURE:
- v4l_dbg(1, debug, c,
- "DECODER_SET_PICTURE: not yet supported\n");
- return -EINVAL;
-
- /* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */
- /* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */
- /* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */
- /* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */
- /* sam todo: KS0127_SET_AGC_MODE: */
- /* sam todo: KS0127_SET_AGC: */
- /* sam todo: KS0127_SET_CHROMA_MODE: */
- /* sam todo: KS0127_SET_PIXCLK_MODE: */
- /* sam todo: KS0127_SET_GAMMA_MODE: */
- /* sam todo: KS0127_SET_UGAIN: */
- /* sam todo: KS0127_SET_VGAIN: */
- /* sam todo: KS0127_SET_INVALY: */
- /* sam todo: KS0127_SET_INVALU: */
- /* sam todo: KS0127_SET_INVALV: */
- /* sam todo: KS0127_SET_UNUSEY: */
- /* sam todo: KS0127_SET_UNUSEU: */
- /* sam todo: KS0127_SET_UNUSEV: */
- /* sam todo: KS0127_SET_VSALIGN_MODE: */
-
- case DECODER_ENABLE_OUTPUT:
- {
- int enable;
-
- iarg = arg;
- enable = (*iarg != 0);
- if (enable) {
- v4l_dbg(1, debug, c,
- "DECODER_ENABLE_OUTPUT on\n");
- /* All output pins on */
- ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30);
- /* Obey the OEN pin */
- ks0127_and_or(c, KS_CDEM, 0x7f, 0x00);
- } else {
- v4l_dbg(1, debug, c,
- "DECODER_ENABLE_OUTPUT off\n");
- /* Video output pins off */
- ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00);
- /* Ignore the OEN pin */
- ks0127_and_or(c, KS_CDEM, 0x7f, 0x80);
- }
- break;
+ ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x0f);
+ } else {
+ v4l2_dbg(1, debug, sd, "s_std: Unknown norm %llx\n",
+ (unsigned long long)std);
}
+ return 0;
+}
- /* sam todo: KS0127_SET_OUTPUT_MODE: */
- /* sam todo: KS0127_SET_WIDTH: */
- /* sam todo: KS0127_SET_HEIGHT: */
- /* sam todo: KS0127_SET_HSCALE: */
-
- case DECODER_GET_STATUS:
- v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n");
- *iarg = 0;
- status = ks0127_read(c, KS_STAT);
- if (!(status & 0x20)) /* NOVID not set */
- *iarg = (*iarg | DECODER_STATUS_GOOD);
- if ((status & 0x01)) /* CLOCK set */
- *iarg = (*iarg | DECODER_STATUS_COLOR);
- if ((status & 0x08)) /* PALDET set */
- *iarg = (*iarg | DECODER_STATUS_PAL);
- else
- *iarg = (*iarg | DECODER_STATUS_NTSC);
- break;
-
- /* Catch any unknown command */
- default:
- v4l_dbg(1, debug, c, "unknown: 0x%08x\n", cmd);
- return -EINVAL;
+static int ks0127_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ v4l2_dbg(1, debug, sd, "s_stream(%d)\n", enable);
+ if (enable) {
+ /* All output pins on */
+ ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x30);
+ /* Obey the OEN pin */
+ ks0127_and_or(sd, KS_CDEM, 0x7f, 0x00);
+ } else {
+ /* Video output pins off */
+ ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x00);
+ /* Ignore the OEN pin */
+ ks0127_and_or(sd, KS_CDEM, 0x7f, 0x80);
}
return 0;
}
+static int ks0127_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
+{
+ int stat = V4L2_IN_ST_NO_SIGNAL;
+ u8 status;
+ v4l2_std_id std = V4L2_STD_ALL;
+
+ status = ks0127_read(sd, KS_STAT);
+ if (!(status & 0x20)) /* NOVID not set */
+ stat = 0;
+ if (!(status & 0x01)) /* CLOCK set */
+ stat |= V4L2_IN_ST_NO_COLOR;
+ if ((status & 0x08)) /* PALDET set */
+ std = V4L2_STD_PAL;
+ else
+ std = V4L2_STD_NTSC;
+ if (pstd)
+ *pstd = std;
+ if (pstatus)
+ *pstatus = stat;
+ return 0;
+}
+
+static int ks0127_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ v4l2_dbg(1, debug, sd, "querystd\n");
+ return ks0127_status(sd, NULL, std);
+}
-/* Addresses to scan */
-#define I2C_KS0127_ADDON 0xD8
-#define I2C_KS0127_ONBOARD 0xDA
+static int ks0127_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+ v4l2_dbg(1, debug, sd, "g_input_status\n");
+ return ks0127_status(sd, status, NULL);
+}
+
+static int ks0127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ks0127 *ks = to_ks0127(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, ks->ident, 0);
+}
+
+/* ----------------------------------------------------------------------- */
-static unsigned short normal_i2c[] = {
- I2C_KS0127_ADDON >> 1,
- I2C_KS0127_ONBOARD >> 1,
- I2C_CLIENT_END
+static const struct v4l2_subdev_core_ops ks0127_core_ops = {
+ .g_chip_ident = ks0127_g_chip_ident,
};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_tuner_ops ks0127_tuner_ops = {
+ .s_std = ks0127_s_std,
+};
+
+static const struct v4l2_subdev_video_ops ks0127_video_ops = {
+ .s_routing = ks0127_s_routing,
+ .s_stream = ks0127_s_stream,
+ .querystd = ks0127_querystd,
+ .g_input_status = ks0127_g_input_status,
+};
+
+static const struct v4l2_subdev_ops ks0127_ops = {
+ .core = &ks0127_core_ops,
+ .tuner = &ks0127_tuner_ops,
+ .video = &ks0127_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
+
-static int ks0127_probe(struct i2c_client *c, const struct i2c_device_id *id)
+static int ks0127_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct ks0127 *ks;
+ struct v4l2_subdev *sd;
- v4l_info(c, "%s chip found @ 0x%x (%s)\n",
- c->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
- c->addr << 1, c->adapter->name);
+ v4l_info(client, "%s chip found @ 0x%x (%s)\n",
+ client->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
+ client->addr << 1, client->adapter->name);
ks = kzalloc(sizeof(*ks), GFP_KERNEL);
if (ks == NULL)
return -ENOMEM;
-
- i2c_set_clientdata(c, ks);
-
- ks->ks_type = KS_TYPE_UNKNOWN;
+ sd = &ks->sd;
+ v4l2_i2c_subdev_init(sd, client, &ks0127_ops);
/* power up */
init_reg_defaults();
- ks0127_write(c, KS_CMDA, 0x2c);
+ ks0127_write(sd, KS_CMDA, 0x2c);
mdelay(10);
/* reset the device */
- ks0127_reset(c);
+ ks0127_init(sd);
return 0;
}
-static int ks0127_remove(struct i2c_client *c)
+static int ks0127_remove(struct i2c_client *client)
{
- struct ks0127 *ks = i2c_get_clientdata(c);
-
- ks0127_write(c, KS_OFMTA, 0x20); /* tristate */
- ks0127_write(c, KS_CMDA, 0x2c | 0x80); /* power down */
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
- kfree(ks);
+ v4l2_device_unregister_subdev(sd);
+ ks0127_write(sd, KS_OFMTA, 0x20); /* tristate */
+ ks0127_write(sd, KS_CMDA, 0x2c | 0x80); /* power down */
+ kfree(to_ks0127(sd));
return 0;
}
-static int ks0127_legacy_probe(struct i2c_adapter *adapter)
-{
- return adapter->id == I2C_HW_B_ZR36067;
-}
-
static const struct i2c_device_id ks0127_id[] = {
{ "ks0127", 0 },
+ { "ks0127b", 0 },
+ { "ks0122s", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ks0127_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "ks0127",
- .driverid = I2C_DRIVERID_KS0127,
- .command = ks0127_command,
.probe = ks0127_probe,
.remove = ks0127_remove,
- .legacy_probe = ks0127_legacy_probe,
.id_table = ks0127_id,
};
diff --git a/drivers/media/video/ks0127.h b/drivers/media/video/ks0127.h
index 1ec578833aea..cb8abd5403b3 100644
--- a/drivers/media/video/ks0127.h
+++ b/drivers/media/video/ks0127.h
@@ -24,8 +24,6 @@
#ifndef KS0127_H
#define KS0127_H
-#include <linux/videodev.h>
-
/* input channels */
#define KS_INPUT_COMPOSITE_1 0
#define KS_INPUT_COMPOSITE_2 1
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index de397ef57b44..1f340fefc49d 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -132,11 +132,6 @@ static int m52790_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int m52790_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops m52790_core_ops = {
@@ -210,8 +205,6 @@ MODULE_DEVICE_TABLE(i2c, m52790_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "m52790",
- .driverid = I2C_DRIVERID_M52790,
- .command = m52790_command,
.probe = m52790_probe,
.remove = m52790_remove,
.id_table = m52790_id,
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index b76e33d5c867..2ad11f0999c6 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1017,7 +1017,6 @@ static int meyeioc_stilljcapt(int *len)
static int vidioc_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
- memset(cap, 0, sizeof(*cap));
strcpy(cap->driver, "meye");
strcpy(cap->card, "meye");
sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev));
@@ -1036,8 +1035,6 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
if (i->index != 0)
return -EINVAL;
- memset(i, 0, sizeof(*i));
- i->index = 0;
strcpy(i->name, "Camera");
i->type = V4L2_INPUT_TYPE_CAMERA;
@@ -1259,22 +1256,13 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,
if (f->index > 1)
return -EINVAL;
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (f->index == 0) {
/* standard YUV 422 capture */
- memset(f, 0, sizeof(*f));
- f->index = 0;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->flags = 0;
strcpy(f->description, "YUV422");
f->pixelformat = V4L2_PIX_FMT_YUYV;
} else {
/* compressed MJPEG capture */
- memset(f, 0, sizeof(*f));
- f->index = 1;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->flags = V4L2_FMT_FLAG_COMPRESSED;
strcpy(f->description, "MJPEG");
f->pixelformat = V4L2_PIX_FMT_MJPEG;
@@ -1286,9 +1274,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,
static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
return -EINVAL;
@@ -1319,12 +1304,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
switch (meye.mchip_mode) {
case MCHIP_HIC_MODE_CONT_OUT:
default:
@@ -1341,8 +1320,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
f->fmt.pix.sizeimage = f->fmt.pix.height *
f->fmt.pix.bytesperline;
- f->fmt.pix.colorspace = 0;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -1350,9 +1327,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
return -EINVAL;
@@ -1398,9 +1372,6 @@ static int vidioc_reqbufs(struct file *file, void *fh,
{
int i;
- if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (req->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
@@ -1441,15 +1412,11 @@ static int vidioc_reqbufs(struct file *file, void *fh,
static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
{
- int index = buf->index;
+ unsigned int index = buf->index;
- if (index < 0 || index >= gbuffers)
+ if (index >= gbuffers)
return -EINVAL;
- memset(buf, 0, sizeof(*buf));
-
- buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- buf->index = index;
buf->bytesused = meye.grab_buffer[index].size;
buf->flags = V4L2_BUF_FLAG_MAPPED;
@@ -1471,13 +1438,10 @@ static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
{
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (buf->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
- if (buf->index < 0 || buf->index >= gbuffers)
+ if (buf->index >= gbuffers)
return -EINVAL;
if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED)
@@ -1497,9 +1461,6 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
{
int reqnr;
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (buf->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 4d7a91852117..9e8e06cfe5c6 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -366,29 +366,6 @@ int msp_sleep(struct msp_state *state, int timeout)
}
/* ------------------------------------------------------------------------ */
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
-static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode)
-{
- if (rxsubchans == V4L2_TUNER_SUB_MONO)
- return VIDEO_SOUND_MONO;
- if (rxsubchans == V4L2_TUNER_SUB_STEREO)
- return VIDEO_SOUND_STEREO;
- if (audmode == V4L2_TUNER_MODE_LANG2)
- return VIDEO_SOUND_LANG2;
- return VIDEO_SOUND_LANG1;
-}
-
-static int msp_mode_v4l1_to_v4l2(int mode)
-{
- if (mode & VIDEO_SOUND_STEREO)
- return V4L2_TUNER_MODE_STEREO;
- if (mode & VIDEO_SOUND_LANG2)
- return V4L2_TUNER_MODE_LANG2;
- if (mode & VIDEO_SOUND_LANG1)
- return V4L2_TUNER_MODE_LANG1;
- return V4L2_TUNER_MODE_MONO;
-}
-#endif
static int msp_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
@@ -482,96 +459,6 @@ static int msp_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
return 0;
}
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
-static long msp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
- struct msp_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- switch (cmd) {
- /* --- v4l ioctls --- */
- /* take care: bttv does userspace copying, we'll get a
- kernel pointer here... */
- case VIDIOCGAUDIO:
- {
- struct video_audio *va = arg;
-
- va->flags |= VIDEO_AUDIO_VOLUME | VIDEO_AUDIO_MUTABLE;
- if (state->has_sound_processing)
- va->flags |= VIDEO_AUDIO_BALANCE |
- VIDEO_AUDIO_BASS |
- VIDEO_AUDIO_TREBLE;
- if (state->muted)
- va->flags |= VIDEO_AUDIO_MUTE;
- va->volume = state->volume;
- va->balance = state->volume ? state->balance : 32768;
- va->bass = state->bass;
- va->treble = state->treble;
-
- if (state->radio)
- break;
- if (state->opmode == OPMODE_AUTOSELECT)
- msp_detect_stereo(client);
- va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans, state->audmode);
- break;
- }
-
- case VIDIOCSAUDIO:
- {
- struct video_audio *va = arg;
-
- state->muted = (va->flags & VIDEO_AUDIO_MUTE);
- state->volume = va->volume;
- state->balance = va->balance;
- state->bass = va->bass;
- state->treble = va->treble;
- msp_set_audio(client);
-
- if (va->mode != 0 && state->radio == 0 &&
- state->audmode != msp_mode_v4l1_to_v4l2(va->mode)) {
- state->audmode = msp_mode_v4l1_to_v4l2(va->mode);
- msp_set_audmode(client);
- }
- break;
- }
-
- case VIDIOCSCHAN:
- {
- struct video_channel *vc = arg;
- int update = 0;
- v4l2_std_id std;
-
- if (state->radio)
- update = 1;
- state->radio = 0;
- if (vc->norm == VIDEO_MODE_PAL)
- std = V4L2_STD_PAL;
- else if (vc->norm == VIDEO_MODE_SECAM)
- std = V4L2_STD_SECAM;
- else
- std = V4L2_STD_NTSC;
- if (std != state->v4l2_std) {
- state->v4l2_std = std;
- update = 1;
- }
- if (update)
- msp_wake_thread(client);
- break;
- }
-
- case VIDIOCSFREQ:
- {
- /* new channel -- kick audio carrier scan */
- msp_wake_thread(client);
- break;
- }
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-#endif
-
/* --- v4l2 ioctls --- */
static int msp_s_radio(struct v4l2_subdev *sd)
{
@@ -713,22 +600,24 @@ static int msp_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
struct msp_state *state = to_state(sd);
switch (qc->id) {
- case V4L2_CID_AUDIO_VOLUME:
- case V4L2_CID_AUDIO_MUTE:
- return v4l2_ctrl_query_fill_std(qc);
- default:
- break;
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+ default:
+ break;
}
if (!state->has_sound_processing)
return -EINVAL;
switch (qc->id) {
- case V4L2_CID_AUDIO_LOUDNESS:
- case V4L2_CID_AUDIO_BALANCE:
- case V4L2_CID_AUDIO_BASS:
- case V4L2_CID_AUDIO_TREBLE:
- return v4l2_ctrl_query_fill_std(qc);
- default:
- return -EINVAL;
+ case V4L2_CID_AUDIO_LOUDNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+ case V4L2_CID_AUDIO_BALANCE:
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
+ default:
+ return -EINVAL;
}
return 0;
}
@@ -820,9 +709,6 @@ static const struct v4l2_subdev_core_ops msp_core_ops = {
.g_ctrl = msp_g_ctrl,
.s_ctrl = msp_s_ctrl,
.queryctrl = msp_queryctrl,
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
- .ioctl = msp_ioctl,
-#endif
};
static const struct v4l2_subdev_tuner_ops msp_tuner_ops = {
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index c1bf75ef2741..fa7e5093edeb 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -12,7 +12,6 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/log2.h>
-#include <linux/gpio.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
@@ -73,9 +72,7 @@ struct mt9m001 {
struct i2c_client *client;
struct soc_camera_device icd;
int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
- int switch_gpio;
unsigned char autoexposure;
- unsigned char datawidth;
};
static int reg_read(struct soc_camera_device *icd, const u8 reg)
@@ -181,92 +178,28 @@ static int mt9m001_stop_capture(struct soc_camera_device *icd)
return 0;
}
-static int bus_switch_request(struct mt9m001 *mt9m001,
- struct soc_camera_link *icl)
-{
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
- int ret;
- unsigned int gpio = icl->gpio;
-
- if (gpio_is_valid(gpio)) {
- /* We have a data bus switch. */
- ret = gpio_request(gpio, "mt9m001");
- if (ret < 0) {
- dev_err(&mt9m001->client->dev, "Cannot get GPIO %u\n",
- gpio);
- return ret;
- }
-
- ret = gpio_direction_output(gpio, 0);
- if (ret < 0) {
- dev_err(&mt9m001->client->dev,
- "Cannot set GPIO %u to output\n", gpio);
- gpio_free(gpio);
- return ret;
- }
- }
-
- mt9m001->switch_gpio = gpio;
-#else
- mt9m001->switch_gpio = -EINVAL;
-#endif
- return 0;
-}
-
-static void bus_switch_release(struct mt9m001 *mt9m001)
-{
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
- if (gpio_is_valid(mt9m001->switch_gpio))
- gpio_free(mt9m001->switch_gpio);
-#endif
-}
-
-static int bus_switch_act(struct mt9m001 *mt9m001, int go8bit)
-{
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
- if (!gpio_is_valid(mt9m001->switch_gpio))
- return -ENODEV;
-
- gpio_set_value_cansleep(mt9m001->switch_gpio, go8bit);
- return 0;
-#else
- return -ENODEV;
-#endif
-}
-
-static int bus_switch_possible(struct mt9m001 *mt9m001)
-{
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
- return gpio_is_valid(mt9m001->switch_gpio);
-#else
- return 0;
-#endif
-}
-
static int mt9m001_set_bus_param(struct soc_camera_device *icd,
unsigned long flags)
{
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
- unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
- int ret;
+ struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
+ unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
- /* Flags validity verified in test_bus_param */
+ /* Only one width bit may be set */
+ if (!is_power_of_2(width_flag))
+ return -EINVAL;
- if ((mt9m001->datawidth != 10 && (width_flag == SOCAM_DATAWIDTH_10)) ||
- (mt9m001->datawidth != 9 && (width_flag == SOCAM_DATAWIDTH_9)) ||
- (mt9m001->datawidth != 8 && (width_flag == SOCAM_DATAWIDTH_8))) {
- /* Well, we actually only can do 10 or 8 bits... */
- if (width_flag == SOCAM_DATAWIDTH_9)
- return -EINVAL;
- ret = bus_switch_act(mt9m001,
- width_flag == SOCAM_DATAWIDTH_8);
- if (ret < 0)
- return ret;
+ if (icl->set_bus_param)
+ return icl->set_bus_param(icl, width_flag);
- mt9m001->datawidth = width_flag == SOCAM_DATAWIDTH_8 ? 8 : 10;
- }
+ /*
+ * Without board specific bus width settings we only support the
+ * sensors native bus width
+ */
+ if (width_flag == SOCAM_DATAWIDTH_10)
+ return 0;
- return 0;
+ return -EINVAL;
}
static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
@@ -274,18 +207,20 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
/* MT9M001 has all capture_format parameters fixed */
- unsigned long flags = SOCAM_DATAWIDTH_10 | SOCAM_PCLK_SAMPLE_RISING |
+ unsigned long flags = SOCAM_PCLK_SAMPLE_RISING |
SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
- SOCAM_MASTER;
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER;
- if (bus_switch_possible(mt9m001))
- flags |= SOCAM_DATAWIDTH_8;
+ if (icl->query_bus_param)
+ flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
+ else
+ flags |= SOCAM_DATAWIDTH_10;
return soc_camera_apply_sensor_flags(icl, flags);
}
-static int mt9m001_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+static int mt9m001_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
{
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
int ret;
@@ -324,6 +259,20 @@ static int mt9m001_set_fmt(struct soc_camera_device *icd,
return ret;
}
+static int mt9m001_set_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct v4l2_rect rect = {
+ .left = icd->x_current,
+ .top = icd->y_current,
+ .width = f->fmt.pix.width,
+ .height = f->fmt.pix.height,
+ };
+
+ /* No support for scaling so far, just crop. TODO: use skipping */
+ return mt9m001_set_crop(icd, &rect);
+}
+
static int mt9m001_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
@@ -449,6 +398,7 @@ static struct soc_camera_ops mt9m001_ops = {
.release = mt9m001_release,
.start_capture = mt9m001_start_capture,
.stop_capture = mt9m001_stop_capture,
+ .set_crop = mt9m001_set_crop,
.set_fmt = mt9m001_set_fmt,
.try_fmt = mt9m001_try_fmt,
.set_bus_param = mt9m001_set_bus_param,
@@ -583,6 +533,7 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
s32 data;
int ret;
+ unsigned long flags;
/* We must have a parent by now. And it cannot be a wrong one.
* So this entire test is completely redundant. */
@@ -603,18 +554,10 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
case 0x8421:
mt9m001->model = V4L2_IDENT_MT9M001C12ST;
icd->formats = mt9m001_colour_formats;
- if (gpio_is_valid(icl->gpio))
- icd->num_formats = ARRAY_SIZE(mt9m001_colour_formats);
- else
- icd->num_formats = 1;
break;
case 0x8431:
mt9m001->model = V4L2_IDENT_MT9M001C12STM;
icd->formats = mt9m001_monochrome_formats;
- if (gpio_is_valid(icl->gpio))
- icd->num_formats = ARRAY_SIZE(mt9m001_monochrome_formats);
- else
- icd->num_formats = 1;
break;
default:
ret = -ENODEV;
@@ -623,6 +566,26 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
goto ei2c;
}
+ icd->num_formats = 0;
+
+ /*
+ * This is a 10bit sensor, so by default we only allow 10bit.
+ * The platform may support different bus widths due to
+ * different routing of the data lines.
+ */
+ if (icl->query_bus_param)
+ flags = icl->query_bus_param(icl);
+ else
+ flags = SOCAM_DATAWIDTH_10;
+
+ if (flags & SOCAM_DATAWIDTH_10)
+ icd->num_formats++;
+ else
+ icd->formats++;
+
+ if (flags & SOCAM_DATAWIDTH_8)
+ icd->num_formats++;
+
dev_info(&icd->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
data == 0x8431 ? "C12STM" : "C12ST");
@@ -688,18 +651,10 @@ static int mt9m001_probe(struct i2c_client *client,
icd->height_max = 1024;
icd->y_skip_top = 1;
icd->iface = icl->bus_id;
- /* Default datawidth - this is the only width this camera (normally)
- * supports. It is only with extra logic that it can support
- * other widths. Therefore it seems to be a sensible default. */
- mt9m001->datawidth = 10;
/* Simulated autoexposure. If enabled, we calculate shutter width
* ourselves in the driver based on vertical blanking and frame width */
mt9m001->autoexposure = 1;
- ret = bus_switch_request(mt9m001, icl);
- if (ret)
- goto eswinit;
-
ret = soc_camera_device_register(icd);
if (ret)
goto eisdr;
@@ -707,8 +662,6 @@ static int mt9m001_probe(struct i2c_client *client,
return 0;
eisdr:
- bus_switch_release(mt9m001);
-eswinit:
kfree(mt9m001);
return ret;
}
@@ -718,7 +671,6 @@ static int mt9m001_remove(struct i2c_client *client)
struct mt9m001 *mt9m001 = i2c_get_clientdata(client);
soc_camera_device_unregister(&mt9m001->icd);
- bus_switch_release(mt9m001);
kfree(mt9m001);
return 0;
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 5b8e20979cce..cdd1ddb51388 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -152,7 +152,7 @@ struct mt9m111 {
struct soc_camera_device icd;
int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
enum mt9m111_context context;
- unsigned int left, top, width, height;
+ struct v4l2_rect rect;
u32 pixfmt;
unsigned char autoexposure;
unsigned char datawidth;
@@ -249,12 +249,13 @@ static int mt9m111_set_context(struct soc_camera_device *icd,
return reg_write(CONTEXT_CONTROL, valA);
}
-static int mt9m111_setup_rect(struct soc_camera_device *icd)
+static int mt9m111_setup_rect(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
{
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
int ret, is_raw_format;
- int width = mt9m111->width;
- int height = mt9m111->height;
+ int width = rect->width;
+ int height = rect->height;
if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8)
|| (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16))
@@ -262,9 +263,9 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd)
else
is_raw_format = 0;
- ret = reg_write(COLUMN_START, mt9m111->left);
+ ret = reg_write(COLUMN_START, rect->left);
if (!ret)
- ret = reg_write(ROW_START, mt9m111->top);
+ ret = reg_write(ROW_START, rect->top);
if (is_raw_format) {
if (!ret)
@@ -393,6 +394,8 @@ static int mt9m111_disable(struct soc_camera_device *icd)
static int mt9m111_reset(struct soc_camera_device *icd)
{
+ struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+ struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
int ret;
ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
@@ -401,6 +404,10 @@ static int mt9m111_reset(struct soc_camera_device *icd)
if (!ret)
ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE
| MT9M111_RESET_RESET_SOC);
+
+ if (icl->reset)
+ icl->reset(&mt9m111->client->dev);
+
return ret;
}
@@ -420,7 +427,7 @@ static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd)
struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |
SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
- SOCAM_DATAWIDTH_8;
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
return soc_camera_apply_sensor_flags(icl, flags);
}
@@ -430,6 +437,22 @@ static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f)
return 0;
}
+static int mt9m111_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+ int ret;
+
+ dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
+ __func__, rect->left, rect->top, rect->width,
+ rect->height);
+
+ ret = mt9m111_setup_rect(icd, rect);
+ if (!ret)
+ mt9m111->rect = *rect;
+ return ret;
+}
+
static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
{
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
@@ -480,23 +503,27 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
}
static int mt9m111_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+ struct v4l2_format *f)
{
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct v4l2_rect rect = {
+ .left = mt9m111->rect.left,
+ .top = mt9m111->rect.top,
+ .width = pix->width,
+ .height = pix->height,
+ };
int ret;
- mt9m111->left = rect->left;
- mt9m111->top = rect->top;
- mt9m111->width = rect->width;
- mt9m111->height = rect->height;
-
dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n",
- __func__, pixfmt, mt9m111->left, mt9m111->top, mt9m111->width,
- mt9m111->height);
+ __func__, pix->pixelformat, rect.left, rect.top, rect.width,
+ rect.height);
- ret = mt9m111_setup_rect(icd);
+ ret = mt9m111_setup_rect(icd, &rect);
+ if (!ret)
+ ret = mt9m111_set_pixfmt(icd, pix->pixelformat);
if (!ret)
- ret = mt9m111_set_pixfmt(icd, pixfmt);
+ mt9m111->rect = rect;
return ret;
}
@@ -627,6 +654,7 @@ static struct soc_camera_ops mt9m111_ops = {
.release = mt9m111_release,
.start_capture = mt9m111_start_capture,
.stop_capture = mt9m111_stop_capture,
+ .set_crop = mt9m111_set_crop,
.set_fmt = mt9m111_set_fmt,
.try_fmt = mt9m111_try_fmt,
.query_bus_param = mt9m111_query_bus_param,
@@ -811,7 +839,7 @@ static int mt9m111_restore_state(struct soc_camera_device *icd)
mt9m111_set_context(icd, mt9m111->context);
mt9m111_set_pixfmt(icd, mt9m111->pixfmt);
- mt9m111_setup_rect(icd);
+ mt9m111_setup_rect(icd, &mt9m111->rect);
mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
mt9m111_set_global_gain(icd, icd->gain);
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 349d8e365530..23f9ce9d67ef 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -144,13 +144,11 @@ static int mt9t031_init(struct soc_camera_device *icd)
int ret;
/* Disable chip output, synchronous option update */
- dev_dbg(icd->vdev->parent, "%s\n", __func__);
-
ret = reg_write(icd, MT9T031_RESET, 1);
if (ret >= 0)
ret = reg_write(icd, MT9T031_RESET, 0);
if (ret >= 0)
- ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3);
+ ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2);
return ret >= 0 ? 0 : -EIO;
}
@@ -158,14 +156,14 @@ static int mt9t031_init(struct soc_camera_device *icd)
static int mt9t031_release(struct soc_camera_device *icd)
{
/* Disable the chip */
- reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3);
+ reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2);
return 0;
}
static int mt9t031_start_capture(struct soc_camera_device *icd)
{
/* Switch to master "normal" mode */
- if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 3) < 0)
+ if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 2) < 0)
return -EIO;
return 0;
}
@@ -173,7 +171,7 @@ static int mt9t031_start_capture(struct soc_camera_device *icd)
static int mt9t031_stop_capture(struct soc_camera_device *icd)
{
/* Stop sensor readout */
- if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3) < 0)
+ if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2) < 0)
return -EIO;
return 0;
}
@@ -186,9 +184,9 @@ static int mt9t031_set_bus_param(struct soc_camera_device *icd,
return -EINVAL;
if (flags & SOCAM_PCLK_SAMPLE_FALLING)
- reg_set(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
- else
reg_clear(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
+ else
+ reg_set(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
return 0;
}
@@ -201,67 +199,73 @@ static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd)
return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM);
}
-static int mt9t031_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+/* Round up minima and round down maxima */
+static void recalculate_limits(struct soc_camera_device *icd,
+ u16 xskip, u16 yskip)
+{
+ icd->x_min = (MT9T031_COLUMN_SKIP + xskip - 1) / xskip;
+ icd->y_min = (MT9T031_ROW_SKIP + yskip - 1) / yskip;
+ icd->width_min = (MT9T031_MIN_WIDTH + xskip - 1) / xskip;
+ icd->height_min = (MT9T031_MIN_HEIGHT + yskip - 1) / yskip;
+ icd->width_max = MT9T031_MAX_WIDTH / xskip;
+ icd->height_max = MT9T031_MAX_HEIGHT / yskip;
+}
+
+static int mt9t031_set_params(struct soc_camera_device *icd,
+ struct v4l2_rect *rect, u16 xskip, u16 yskip)
{
struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
int ret;
+ u16 xbin, ybin, width, height, left, top;
const u16 hblank = MT9T031_HORIZONTAL_BLANK,
vblank = MT9T031_VERTICAL_BLANK;
- u16 xbin, xskip = mt9t031->xskip, ybin, yskip = mt9t031->yskip,
- width = rect->width * xskip, height = rect->height * yskip;
- if (pixfmt) {
- /* S_FMT - use binning and skipping for scaling, recalculate */
- /* Is this more optimal than just a division? */
- for (xskip = 8; xskip > 1; xskip--)
- if (rect->width * xskip <= icd->width_max)
- break;
+ /* Make sure we don't exceed sensor limits */
+ if (rect->left + rect->width > icd->width_max)
+ rect->left = (icd->width_max - rect->width) / 2 + icd->x_min;
- for (yskip = 8; yskip > 1; yskip--)
- if (rect->height * yskip <= icd->height_max)
- break;
+ if (rect->top + rect->height > icd->height_max)
+ rect->top = (icd->height_max - rect->height) / 2 + icd->y_min;
- width = rect->width * xskip;
- height = rect->height * yskip;
-
- dev_dbg(&icd->dev, "xskip %u, width %u, yskip %u, height %u\n",
- xskip, width, yskip, height);
- }
+ width = rect->width * xskip;
+ height = rect->height * yskip;
+ left = rect->left * xskip;
+ top = rect->top * yskip;
xbin = min(xskip, (u16)3);
ybin = min(yskip, (u16)3);
- /* Make sure we don't exceed frame limits */
- if (rect->left + width > icd->width_max)
- rect->left = (icd->width_max - width) / 2;
-
- if (rect->top + height > icd->height_max)
- rect->top = (icd->height_max - height) / 2;
+ dev_dbg(&icd->dev, "xskip %u, width %u/%u, yskip %u, height %u/%u\n",
+ xskip, width, rect->width, yskip, height, rect->height);
- /* Could just do roundup(rect->left, [xy]bin); but this is cheaper */
+ /* Could just do roundup(rect->left, [xy]bin * 2); but this is cheaper */
switch (xbin) {
case 2:
- rect->left = (rect->left + 1) & ~1;
+ left = (left + 3) & ~3;
break;
case 3:
- rect->left = roundup(rect->left, 3);
+ left = roundup(left, 6);
}
switch (ybin) {
case 2:
- rect->top = (rect->top + 1) & ~1;
+ top = (top + 3) & ~3;
break;
case 3:
- rect->top = roundup(rect->top, 3);
+ top = roundup(top, 6);
}
+ /* Disable register update, reconfigure atomically */
+ ret = reg_set(icd, MT9T031_OUTPUT_CONTROL, 1);
+ if (ret < 0)
+ return ret;
+
/* Blanking and start values - default... */
ret = reg_write(icd, MT9T031_HORIZONTAL_BLANKING, hblank);
if (ret >= 0)
ret = reg_write(icd, MT9T031_VERTICAL_BLANKING, vblank);
- if (pixfmt) {
+ if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) {
/* Binning, skipping */
if (ret >= 0)
ret = reg_write(icd, MT9T031_COLUMN_ADDRESS_MODE,
@@ -270,14 +274,14 @@ static int mt9t031_set_fmt(struct soc_camera_device *icd,
ret = reg_write(icd, MT9T031_ROW_ADDRESS_MODE,
((ybin - 1) << 4) | (yskip - 1));
}
- dev_dbg(&icd->dev, "new left %u, top %u\n", rect->left, rect->top);
+ dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top);
/* The caller provides a supported format, as guaranteed by
* icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */
if (ret >= 0)
- ret = reg_write(icd, MT9T031_COLUMN_START, rect->left);
+ ret = reg_write(icd, MT9T031_COLUMN_START, left);
if (ret >= 0)
- ret = reg_write(icd, MT9T031_ROW_START, rect->top);
+ ret = reg_write(icd, MT9T031_ROW_START, top);
if (ret >= 0)
ret = reg_write(icd, MT9T031_WINDOW_WIDTH, width - 1);
if (ret >= 0)
@@ -297,12 +301,58 @@ static int mt9t031_set_fmt(struct soc_camera_device *icd,
}
}
- if (!ret && pixfmt) {
+ /* Re-enable register update, commit all changes */
+ if (ret >= 0)
+ ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 1);
+
+ return ret < 0 ? ret : 0;
+}
+
+static int mt9t031_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+
+ /* CROP - no change in scaling, or in limits */
+ return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip);
+}
+
+static int mt9t031_set_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+ int ret;
+ u16 xskip, yskip;
+ struct v4l2_rect rect = {
+ .left = icd->x_current,
+ .top = icd->y_current,
+ .width = f->fmt.pix.width,
+ .height = f->fmt.pix.height,
+ };
+
+ /*
+ * try_fmt has put rectangle within limits.
+ * S_FMT - use binning and skipping for scaling, recalculate
+ * limits, used for cropping
+ */
+ /* Is this more optimal than just a division? */
+ for (xskip = 8; xskip > 1; xskip--)
+ if (rect.width * xskip <= MT9T031_MAX_WIDTH)
+ break;
+
+ for (yskip = 8; yskip > 1; yskip--)
+ if (rect.height * yskip <= MT9T031_MAX_HEIGHT)
+ break;
+
+ recalculate_limits(icd, xskip, yskip);
+
+ ret = mt9t031_set_params(icd, &rect, xskip, yskip);
+ if (!ret) {
mt9t031->xskip = xskip;
mt9t031->yskip = yskip;
}
- return ret < 0 ? ret : 0;
+ return ret;
}
static int mt9t031_try_fmt(struct soc_camera_device *icd,
@@ -310,14 +360,14 @@ static int mt9t031_try_fmt(struct soc_camera_device *icd,
{
struct v4l2_pix_format *pix = &f->fmt.pix;
- if (pix->height < icd->height_min)
- pix->height = icd->height_min;
- if (pix->height > icd->height_max)
- pix->height = icd->height_max;
- if (pix->width < icd->width_min)
- pix->width = icd->width_min;
- if (pix->width > icd->width_max)
- pix->width = icd->width_max;
+ if (pix->height < MT9T031_MIN_HEIGHT)
+ pix->height = MT9T031_MIN_HEIGHT;
+ if (pix->height > MT9T031_MAX_HEIGHT)
+ pix->height = MT9T031_MAX_HEIGHT;
+ if (pix->width < MT9T031_MIN_WIDTH)
+ pix->width = MT9T031_MIN_WIDTH;
+ if (pix->width > MT9T031_MAX_WIDTH)
+ pix->width = MT9T031_MAX_WIDTH;
pix->width &= ~0x01; /* has to be even */
pix->height &= ~0x01; /* has to be even */
@@ -390,6 +440,14 @@ static const struct v4l2_queryctrl mt9t031_controls[] = {
.step = 1,
.default_value = 0,
}, {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Flip Horizontally",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ }, {
.id = V4L2_CID_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Gain",
@@ -431,6 +489,7 @@ static struct soc_camera_ops mt9t031_ops = {
.release = mt9t031_release,
.start_capture = mt9t031_start_capture,
.stop_capture = mt9t031_stop_capture,
+ .set_crop = mt9t031_set_crop,
.set_fmt = mt9t031_set_fmt,
.try_fmt = mt9t031_try_fmt,
.set_bus_param = mt9t031_set_bus_param,
@@ -513,21 +572,23 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
if (data < 0)
return -EIO;
} else {
- /* Pack it into 1.125..15 variable step, register values 9..67 */
+ /* Pack it into 1.125..128 variable step, register values 9..0x7860 */
/* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
unsigned long range = qctrl->maximum - qctrl->default_value - 1;
+ /* calculated gain: map 65..127 to 9..1024 step 0.125 */
unsigned long gain = ((ctrl->value - qctrl->default_value - 1) *
- 111 + range / 2) / range + 9;
+ 1015 + range / 2) / range + 9;
- if (gain <= 32)
+ if (gain <= 32) /* calculated gain 9..32 -> 9..32 */
data = gain;
- else if (gain <= 64)
+ else if (gain <= 64) /* calculated gain 33..64 -> 0x51..0x60 */
data = ((gain - 32) * 16 + 16) / 32 + 80;
else
- data = ((gain - 64) * 7 + 28) / 56 + 96;
+ /* calculated gain 65..1024 -> (1..120) << 8 + 0x60 */
+ data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60;
- dev_dbg(&icd->dev, "Setting gain from %d to %d\n",
- reg_read(icd, MT9T031_GLOBAL_GAIN), data);
+ dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n",
+ reg_read(icd, MT9T031_GLOBAL_GAIN), data);
data = reg_write(icd, MT9T031_GLOBAL_GAIN, data);
if (data < 0)
return -EIO;
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index b04c8cb1644d..4d3b4813c322 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -13,7 +13,6 @@
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/log2.h>
-#include <linux/gpio.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
@@ -89,9 +88,7 @@ struct mt9v022 {
struct i2c_client *client;
struct soc_camera_device icd;
int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
- int switch_gpio;
u16 chip_control;
- unsigned char datawidth;
};
static int reg_read(struct soc_camera_device *icd, const u8 reg)
@@ -209,66 +206,6 @@ static int mt9v022_stop_capture(struct soc_camera_device *icd)
return 0;
}
-static int bus_switch_request(struct mt9v022 *mt9v022, struct soc_camera_link *icl)
-{
-#ifdef CONFIG_MT9V022_PCA9536_SWITCH
- int ret;
- unsigned int gpio = icl->gpio;
-
- if (gpio_is_valid(gpio)) {
- /* We have a data bus switch. */
- ret = gpio_request(gpio, "mt9v022");
- if (ret < 0) {
- dev_err(&mt9v022->client->dev, "Cannot get GPIO %u\n", gpio);
- return ret;
- }
-
- ret = gpio_direction_output(gpio, 0);
- if (ret < 0) {
- dev_err(&mt9v022->client->dev,
- "Cannot set GPIO %u to output\n", gpio);
- gpio_free(gpio);
- return ret;
- }
- }
-
- mt9v022->switch_gpio = gpio;
-#else
- mt9v022->switch_gpio = -EINVAL;
-#endif
- return 0;
-}
-
-static void bus_switch_release(struct mt9v022 *mt9v022)
-{
-#ifdef CONFIG_MT9V022_PCA9536_SWITCH
- if (gpio_is_valid(mt9v022->switch_gpio))
- gpio_free(mt9v022->switch_gpio);
-#endif
-}
-
-static int bus_switch_act(struct mt9v022 *mt9v022, int go8bit)
-{
-#ifdef CONFIG_MT9V022_PCA9536_SWITCH
- if (!gpio_is_valid(mt9v022->switch_gpio))
- return -ENODEV;
-
- gpio_set_value_cansleep(mt9v022->switch_gpio, go8bit);
- return 0;
-#else
- return -ENODEV;
-#endif
-}
-
-static int bus_switch_possible(struct mt9v022 *mt9v022)
-{
-#ifdef CONFIG_MT9V022_PCA9536_SWITCH
- return gpio_is_valid(mt9v022->switch_gpio);
-#else
- return 0;
-#endif
-}
-
static int mt9v022_set_bus_param(struct soc_camera_device *icd,
unsigned long flags)
{
@@ -282,19 +219,17 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
if (!is_power_of_2(width_flag))
return -EINVAL;
- if ((mt9v022->datawidth != 10 && (width_flag == SOCAM_DATAWIDTH_10)) ||
- (mt9v022->datawidth != 9 && (width_flag == SOCAM_DATAWIDTH_9)) ||
- (mt9v022->datawidth != 8 && (width_flag == SOCAM_DATAWIDTH_8))) {
- /* Well, we actually only can do 10 or 8 bits... */
- if (width_flag == SOCAM_DATAWIDTH_9)
- return -EINVAL;
-
- ret = bus_switch_act(mt9v022,
- width_flag == SOCAM_DATAWIDTH_8);
- if (ret < 0)
+ if (icl->set_bus_param) {
+ ret = icl->set_bus_param(icl, width_flag);
+ if (ret)
return ret;
-
- mt9v022->datawidth = width_flag == SOCAM_DATAWIDTH_8 ? 8 : 10;
+ } else {
+ /*
+ * Without board specific bus width settings we only support the
+ * sensors native bus width
+ */
+ if (width_flag != SOCAM_DATAWIDTH_10)
+ return -EINVAL;
}
flags = soc_camera_apply_sensor_flags(icl, flags);
@@ -328,44 +263,27 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
{
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
- unsigned int width_flag = SOCAM_DATAWIDTH_10;
+ struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
+ unsigned int width_flag;
- if (bus_switch_possible(mt9v022))
- width_flag |= SOCAM_DATAWIDTH_8;
+ if (icl->query_bus_param)
+ width_flag = icl->query_bus_param(icl) &
+ SOCAM_DATAWIDTH_MASK;
+ else
+ width_flag = SOCAM_DATAWIDTH_10;
return SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
- SOCAM_MASTER | SOCAM_SLAVE |
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_SLAVE |
width_flag;
}
-static int mt9v022_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+static int mt9v022_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
{
- struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
int ret;
- /* The caller provides a supported format, as verified per call to
- * icd->try_fmt(), datawidth is from our supported format list */
- switch (pixfmt) {
- case V4L2_PIX_FMT_GREY:
- case V4L2_PIX_FMT_Y16:
- if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
- return -EINVAL;
- break;
- case V4L2_PIX_FMT_SBGGR8:
- case V4L2_PIX_FMT_SBGGR16:
- if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
- return -EINVAL;
- break;
- case 0:
- /* No format change, only geometry */
- break;
- default:
- return -EINVAL;
- }
-
/* Like in example app. Contradicts the datasheet though */
ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE);
if (ret >= 0) {
@@ -403,6 +321,42 @@ static int mt9v022_set_fmt(struct soc_camera_device *icd,
return 0;
}
+static int mt9v022_set_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct v4l2_rect rect = {
+ .left = icd->x_current,
+ .top = icd->y_current,
+ .width = pix->width,
+ .height = pix->height,
+ };
+
+ /* The caller provides a supported format, as verified per call to
+ * icd->try_fmt(), datawidth is from our supported format list */
+ switch (pix->pixelformat) {
+ case V4L2_PIX_FMT_GREY:
+ case V4L2_PIX_FMT_Y16:
+ if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
+ return -EINVAL;
+ break;
+ case V4L2_PIX_FMT_SBGGR8:
+ case V4L2_PIX_FMT_SBGGR16:
+ if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
+ return -EINVAL;
+ break;
+ case 0:
+ /* No format change, only geometry */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* No support for scaling on this camera, just crop. */
+ return mt9v022_set_crop(icd, &rect);
+}
+
static int mt9v022_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
@@ -544,6 +498,7 @@ static struct soc_camera_ops mt9v022_ops = {
.release = mt9v022_release,
.start_capture = mt9v022_start_capture,
.stop_capture = mt9v022_stop_capture,
+ .set_crop = mt9v022_set_crop,
.set_fmt = mt9v022_set_fmt,
.try_fmt = mt9v022_try_fmt,
.set_bus_param = mt9v022_set_bus_param,
@@ -699,6 +654,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
s32 data;
int ret;
+ unsigned long flags;
if (!icd->dev.parent ||
to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
@@ -732,22 +688,36 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
icd->formats = mt9v022_colour_formats;
- if (gpio_is_valid(icl->gpio))
- icd->num_formats = ARRAY_SIZE(mt9v022_colour_formats);
- else
- icd->num_formats = 1;
} else {
ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11);
mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
icd->formats = mt9v022_monochrome_formats;
- if (gpio_is_valid(icl->gpio))
- icd->num_formats = ARRAY_SIZE(mt9v022_monochrome_formats);
- else
- icd->num_formats = 1;
}
- if (!ret)
- ret = soc_camera_video_start(icd);
+ if (ret < 0)
+ goto eisis;
+
+ icd->num_formats = 0;
+
+ /*
+ * This is a 10bit sensor, so by default we only allow 10bit.
+ * The platform may support different bus widths due to
+ * different routing of the data lines.
+ */
+ if (icl->query_bus_param)
+ flags = icl->query_bus_param(icl);
+ else
+ flags = SOCAM_DATAWIDTH_10;
+
+ if (flags & SOCAM_DATAWIDTH_10)
+ icd->num_formats++;
+ else
+ icd->formats++;
+
+ if (flags & SOCAM_DATAWIDTH_8)
+ icd->num_formats++;
+
+ ret = soc_camera_video_start(icd);
if (ret < 0)
goto eisis;
@@ -812,14 +782,6 @@ static int mt9v022_probe(struct i2c_client *client,
icd->height_max = 480;
icd->y_skip_top = 1;
icd->iface = icl->bus_id;
- /* Default datawidth - this is the only width this camera (normally)
- * supports. It is only with extra logic that it can support
- * other widths. Therefore it seems to be a sensible default. */
- mt9v022->datawidth = 10;
-
- ret = bus_switch_request(mt9v022, icl);
- if (ret)
- goto eswinit;
ret = soc_camera_device_register(icd);
if (ret)
@@ -828,8 +790,6 @@ static int mt9v022_probe(struct i2c_client *client,
return 0;
eisdr:
- bus_switch_release(mt9v022);
-eswinit:
kfree(mt9v022);
return ret;
}
@@ -839,7 +799,6 @@ static int mt9v022_remove(struct i2c_client *client)
struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
soc_camera_device_unregister(&mt9v022->icd);
- bus_switch_release(mt9v022);
kfree(mt9v022);
return 0;
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
new file mode 100644
index 000000000000..70629e172e65
--- /dev/null
+++ b/drivers/media/video/mx3_camera.c
@@ -0,0 +1,1220 @@
+/*
+ * V4L2 Driver for i.MX3x camera host
+ *
+ * Copyright (C) 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/videodev2.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-dev.h>
+#include <media/videobuf-dma-contig.h>
+#include <media/soc_camera.h>
+
+#include <mach/ipu.h>
+#include <mach/mx3_camera.h>
+
+#define MX3_CAM_DRV_NAME "mx3-camera"
+
+/* CMOS Sensor Interface Registers */
+#define CSI_REG_START 0x60
+
+#define CSI_SENS_CONF (0x60 - CSI_REG_START)
+#define CSI_SENS_FRM_SIZE (0x64 - CSI_REG_START)
+#define CSI_ACT_FRM_SIZE (0x68 - CSI_REG_START)
+#define CSI_OUT_FRM_CTRL (0x6C - CSI_REG_START)
+#define CSI_TST_CTRL (0x70 - CSI_REG_START)
+#define CSI_CCIR_CODE_1 (0x74 - CSI_REG_START)
+#define CSI_CCIR_CODE_2 (0x78 - CSI_REG_START)
+#define CSI_CCIR_CODE_3 (0x7C - CSI_REG_START)
+#define CSI_FLASH_STROBE_1 (0x80 - CSI_REG_START)
+#define CSI_FLASH_STROBE_2 (0x84 - CSI_REG_START)
+
+#define CSI_SENS_CONF_VSYNC_POL_SHIFT 0
+#define CSI_SENS_CONF_HSYNC_POL_SHIFT 1
+#define CSI_SENS_CONF_DATA_POL_SHIFT 2
+#define CSI_SENS_CONF_PIX_CLK_POL_SHIFT 3
+#define CSI_SENS_CONF_SENS_PRTCL_SHIFT 4
+#define CSI_SENS_CONF_SENS_CLKSRC_SHIFT 7
+#define CSI_SENS_CONF_DATA_FMT_SHIFT 8
+#define CSI_SENS_CONF_DATA_WIDTH_SHIFT 10
+#define CSI_SENS_CONF_EXT_VSYNC_SHIFT 15
+#define CSI_SENS_CONF_DIVRATIO_SHIFT 16
+
+#define CSI_SENS_CONF_DATA_FMT_RGB_YUV444 (0UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
+#define CSI_SENS_CONF_DATA_FMT_YUV422 (2UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
+#define CSI_SENS_CONF_DATA_FMT_BAYER (3UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
+
+#define MAX_VIDEO_MEM 16
+
+struct mx3_camera_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct videobuf_buffer vb;
+ const struct soc_camera_data_format *fmt;
+
+ /* One descriptot per scatterlist (per frame) */
+ struct dma_async_tx_descriptor *txd;
+
+ /* We have to "build" a scatterlist ourselves - one element per frame */
+ struct scatterlist sg;
+};
+
+/**
+ * struct mx3_camera_dev - i.MX3x camera (CSI) object
+ * @dev: camera device, to which the coherent buffer is attached
+ * @icd: currently attached camera sensor
+ * @clk: pointer to clock
+ * @base: remapped register base address
+ * @pdata: platform data
+ * @platform_flags: platform flags
+ * @mclk: master clock frequency in Hz
+ * @capture: list of capture videobuffers
+ * @lock: protects video buffer lists
+ * @active: active video buffer
+ * @idmac_channel: array of pointers to IPU DMAC DMA channels
+ * @soc_host: embedded soc_host object
+ */
+struct mx3_camera_dev {
+ struct device *dev;
+ /*
+ * i.MX3x is only supposed to handle one camera on its Camera Sensor
+ * Interface. If anyone ever builds hardware to enable more than one
+ * camera _simultaneously_, they will have to modify this driver too
+ */
+ struct soc_camera_device *icd;
+ struct clk *clk;
+
+ void __iomem *base;
+
+ struct mx3_camera_pdata *pdata;
+
+ unsigned long platform_flags;
+ unsigned long mclk;
+
+ struct list_head capture;
+ spinlock_t lock; /* Protects video buffer lists */
+ struct mx3_camera_buffer *active;
+
+ /* IDMAC / dmaengine interface */
+ struct idmac_channel *idmac_channel[1]; /* We need one channel */
+
+ struct soc_camera_host soc_host;
+};
+
+struct dma_chan_request {
+ struct mx3_camera_dev *mx3_cam;
+ enum ipu_channel id;
+};
+
+static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt);
+
+static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg)
+{
+ return __raw_readl(mx3->base + reg);
+}
+
+static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg)
+{
+ __raw_writel(value, mx3->base + reg);
+}
+
+/* Called from the IPU IDMAC ISR */
+static void mx3_cam_dma_done(void *arg)
+{
+ struct idmac_tx_desc *desc = to_tx_desc(arg);
+ struct dma_chan *chan = desc->txd.chan;
+ struct idmac_channel *ichannel = to_idmac_chan(chan);
+ struct mx3_camera_dev *mx3_cam = ichannel->client;
+ struct videobuf_buffer *vb;
+
+ dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n",
+ desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0);
+
+ spin_lock(&mx3_cam->lock);
+ if (mx3_cam->active) {
+ vb = &mx3_cam->active->vb;
+
+ list_del_init(&vb->queue);
+ vb->state = VIDEOBUF_DONE;
+ do_gettimeofday(&vb->ts);
+ vb->field_count++;
+ wake_up(&vb->done);
+ }
+
+ if (list_empty(&mx3_cam->capture)) {
+ mx3_cam->active = NULL;
+ spin_unlock(&mx3_cam->lock);
+
+ /*
+ * stop capture - without further buffers IPU_CHA_BUF0_RDY will
+ * not get updated
+ */
+ return;
+ }
+
+ mx3_cam->active = list_entry(mx3_cam->capture.next,
+ struct mx3_camera_buffer, vb.queue);
+ mx3_cam->active->vb.state = VIDEOBUF_ACTIVE;
+ spin_unlock(&mx3_cam->lock);
+}
+
+static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct videobuf_buffer *vb = &buf->vb;
+ struct dma_async_tx_descriptor *txd = buf->txd;
+ struct idmac_channel *ichan;
+
+ BUG_ON(in_interrupt());
+
+ dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+ vb, vb->baddr, vb->bsize);
+
+ /*
+ * This waits until this buffer is out of danger, i.e., until it is no
+ * longer in STATE_QUEUED or STATE_ACTIVE
+ */
+ videobuf_waiton(vb, 0, 0);
+ if (txd) {
+ ichan = to_idmac_chan(txd->chan);
+ async_tx_ack(txd);
+ }
+ videobuf_dma_contig_free(vq, vb);
+ buf->txd = NULL;
+
+ vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+/*
+ * Videobuf operations
+ */
+
+/*
+ * Calculate the __buffer__ (not data) size and number of buffers.
+ * Called with .vb_lock held
+ */
+static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
+ unsigned int *size)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ /*
+ * bits-per-pixel (depth) as specified in camera's pixel format does
+ * not necessarily match what the camera interface writes to RAM, but
+ * it should be good enough for now.
+ */
+ unsigned int bpp = DIV_ROUND_UP(icd->current_fmt->depth, 8);
+
+ if (!mx3_cam->idmac_channel[0])
+ return -EINVAL;
+
+ *size = icd->width * icd->height * bpp;
+
+ if (!*count)
+ *count = 32;
+
+ if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
+ *count = MAX_VIDEO_MEM * 1024 * 1024 / *size;
+
+ return 0;
+}
+
+/* Called with .vb_lock held */
+static int mx3_videobuf_prepare(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb, enum v4l2_field field)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ struct mx3_camera_buffer *buf =
+ container_of(vb, struct mx3_camera_buffer, vb);
+ /* current_fmt _must_ always be set */
+ size_t new_size = icd->width * icd->height *
+ ((icd->current_fmt->depth + 7) >> 3);
+ int ret;
+
+ /*
+ * I think, in buf_prepare you only have to protect global data,
+ * the actual buffer is yours
+ */
+
+ if (buf->fmt != icd->current_fmt ||
+ vb->width != icd->width ||
+ vb->height != icd->height ||
+ vb->field != field) {
+ buf->fmt = icd->current_fmt;
+ vb->width = icd->width;
+ vb->height = icd->height;
+ vb->field = field;
+ if (vb->state != VIDEOBUF_NEEDS_INIT)
+ free_buffer(vq, buf);
+ }
+
+ if (vb->baddr && vb->bsize < new_size) {
+ /* User provided buffer, but it is too small */
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ if (vb->state == VIDEOBUF_NEEDS_INIT) {
+ struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
+ struct scatterlist *sg = &buf->sg;
+
+ /*
+ * The total size of video-buffers that will be allocated / mapped.
+ * *size that we calculated in videobuf_setup gets assigned to
+ * vb->bsize, and now we use the same calculation to get vb->size.
+ */
+ vb->size = new_size;
+
+ /* This actually (allocates and) maps buffers */
+ ret = videobuf_iolock(vq, vb, NULL);
+ if (ret)
+ goto fail;
+
+ /*
+ * We will have to configure the IDMAC channel. It has two slots
+ * for DMA buffers, we shall enter the first two buffers there,
+ * and then submit new buffers in DMA-ready interrupts
+ */
+ sg_init_table(sg, 1);
+ sg_dma_address(sg) = videobuf_to_dma_contig(vb);
+ sg_dma_len(sg) = vb->size;
+
+ buf->txd = ichan->dma_chan.device->device_prep_slave_sg(
+ &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE,
+ DMA_PREP_INTERRUPT);
+ if (!buf->txd) {
+ ret = -EIO;
+ goto fail;
+ }
+
+ buf->txd->callback_param = buf->txd;
+ buf->txd->callback = mx3_cam_dma_done;
+
+ vb->state = VIDEOBUF_PREPARED;
+ }
+
+ return 0;
+
+fail:
+ free_buffer(vq, buf);
+out:
+ return ret;
+}
+
+static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc)
+{
+ /* Add more formats as need arises and test possibilities appear... */
+ switch (fourcc) {
+ case V4L2_PIX_FMT_RGB565:
+ return IPU_PIX_FMT_RGB565;
+ case V4L2_PIX_FMT_RGB24:
+ return IPU_PIX_FMT_RGB24;
+ case V4L2_PIX_FMT_RGB332:
+ return IPU_PIX_FMT_RGB332;
+ case V4L2_PIX_FMT_YUV422P:
+ return IPU_PIX_FMT_YVU422P;
+ default:
+ return IPU_PIX_FMT_GENERIC;
+ }
+}
+
+/* Called with .vb_lock held */
+static void mx3_videobuf_queue(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ struct mx3_camera_buffer *buf =
+ container_of(vb, struct mx3_camera_buffer, vb);
+ struct dma_async_tx_descriptor *txd = buf->txd;
+ struct idmac_channel *ichan = to_idmac_chan(txd->chan);
+ struct idmac_video_param *video = &ichan->params.video;
+ const struct soc_camera_data_format *data_fmt = icd->current_fmt;
+ dma_cookie_t cookie;
+ unsigned long flags;
+
+ /* This is the configuration of one sg-element */
+ video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc);
+ video->out_width = icd->width;
+ video->out_height = icd->height;
+ video->out_stride = icd->width;
+
+#ifdef DEBUG
+ /* helps to see what DMA actually has written */
+ memset((void *)vb->baddr, 0xaa, vb->bsize);
+#endif
+
+ spin_lock_irqsave(&mx3_cam->lock, flags);
+
+ list_add_tail(&vb->queue, &mx3_cam->capture);
+
+ if (!mx3_cam->active) {
+ mx3_cam->active = buf;
+ vb->state = VIDEOBUF_ACTIVE;
+ } else {
+ vb->state = VIDEOBUF_QUEUED;
+ }
+
+ spin_unlock_irqrestore(&mx3_cam->lock, flags);
+
+ cookie = txd->tx_submit(txd);
+ dev_dbg(&icd->dev, "Submitted cookie %d DMA 0x%08x\n", cookie, sg_dma_address(&buf->sg));
+ if (cookie >= 0)
+ return;
+
+ /* Submit error */
+ vb->state = VIDEOBUF_PREPARED;
+
+ spin_lock_irqsave(&mx3_cam->lock, flags);
+
+ list_del_init(&vb->queue);
+
+ if (mx3_cam->active == buf)
+ mx3_cam->active = NULL;
+
+ spin_unlock_irqrestore(&mx3_cam->lock, flags);
+}
+
+/* Called with .vb_lock held */
+static void mx3_videobuf_release(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ struct mx3_camera_buffer *buf =
+ container_of(vb, struct mx3_camera_buffer, vb);
+ unsigned long flags;
+
+ dev_dbg(&icd->dev, "Release%s DMA 0x%08x (state %d), queue %sempty\n",
+ mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg),
+ vb->state, list_empty(&vb->queue) ? "" : "not ");
+ spin_lock_irqsave(&mx3_cam->lock, flags);
+ if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) &&
+ !list_empty(&vb->queue)) {
+ vb->state = VIDEOBUF_ERROR;
+
+ list_del_init(&vb->queue);
+ if (mx3_cam->active == buf)
+ mx3_cam->active = NULL;
+ }
+ spin_unlock_irqrestore(&mx3_cam->lock, flags);
+ free_buffer(vq, buf);
+}
+
+static struct videobuf_queue_ops mx3_videobuf_ops = {
+ .buf_setup = mx3_videobuf_setup,
+ .buf_prepare = mx3_videobuf_prepare,
+ .buf_queue = mx3_videobuf_queue,
+ .buf_release = mx3_videobuf_release,
+};
+
+static void mx3_camera_init_videobuf(struct videobuf_queue *q,
+ struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+
+ videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, mx3_cam->dev,
+ &mx3_cam->lock,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ V4L2_FIELD_NONE,
+ sizeof(struct mx3_camera_buffer), icd);
+}
+
+/* First part of ipu_csi_init_interface() */
+static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
+ struct soc_camera_device *icd)
+{
+ u32 conf;
+ long rate;
+
+ /* Set default size: ipu_csi_set_window_size() */
+ csi_reg_write(mx3_cam, (640 - 1) | ((480 - 1) << 16), CSI_ACT_FRM_SIZE);
+ /* ...and position to 0:0: ipu_csi_set_window_pos() */
+ conf = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
+ csi_reg_write(mx3_cam, conf, CSI_OUT_FRM_CTRL);
+
+ /* We use only gated clock synchronisation mode so far */
+ conf = 0 << CSI_SENS_CONF_SENS_PRTCL_SHIFT;
+
+ /* Set generic data, platform-biggest bus-width */
+ conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
+
+ if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
+ conf |= 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
+ conf |= 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
+ conf |= 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ else/* if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)*/
+ conf |= 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+
+ if (mx3_cam->platform_flags & MX3_CAMERA_CLK_SRC)
+ conf |= 1 << CSI_SENS_CONF_SENS_CLKSRC_SHIFT;
+ if (mx3_cam->platform_flags & MX3_CAMERA_EXT_VSYNC)
+ conf |= 1 << CSI_SENS_CONF_EXT_VSYNC_SHIFT;
+ if (mx3_cam->platform_flags & MX3_CAMERA_DP)
+ conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
+ if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
+ conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
+ if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
+ conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
+ if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
+ conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
+
+ /* ipu_csi_init_interface() */
+ csi_reg_write(mx3_cam, conf, CSI_SENS_CONF);
+
+ clk_enable(mx3_cam->clk);
+ rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
+ dev_dbg(&icd->dev, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
+ if (rate)
+ clk_set_rate(mx3_cam->clk, rate);
+}
+
+/* Called with .video_lock held */
+static int mx3_camera_add_device(struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ int ret;
+
+ if (mx3_cam->icd) {
+ ret = -EBUSY;
+ goto ebusy;
+ }
+
+ mx3_camera_activate(mx3_cam, icd);
+ ret = icd->ops->init(icd);
+ if (ret < 0) {
+ clk_disable(mx3_cam->clk);
+ goto einit;
+ }
+
+ mx3_cam->icd = icd;
+
+einit:
+ebusy:
+ if (!ret)
+ dev_info(&icd->dev, "MX3 Camera driver attached to camera %d\n",
+ icd->devnum);
+
+ return ret;
+}
+
+/* Called with .video_lock held */
+static void mx3_camera_remove_device(struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
+
+ BUG_ON(icd != mx3_cam->icd);
+
+ if (*ichan) {
+ dma_release_channel(&(*ichan)->dma_chan);
+ *ichan = NULL;
+ }
+
+ icd->ops->release(icd);
+
+ clk_disable(mx3_cam->clk);
+
+ mx3_cam->icd = NULL;
+
+ dev_info(&icd->dev, "MX3 Camera driver detached from camera %d\n",
+ icd->devnum);
+}
+
+static bool channel_change_requested(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
+
+ /* Do buffers have to be re-allocated or channel re-configured? */
+ return ichan && rect->width * rect->height > icd->width * icd->height;
+}
+
+static int test_platform_param(struct mx3_camera_dev *mx3_cam,
+ unsigned char buswidth, unsigned long *flags)
+{
+ /*
+ * Platform specified synchronization and pixel clock polarities are
+ * only a recommendation and are only used during probing. MX3x
+ * camera interface only works in master mode, i.e., uses HSYNC and
+ * VSYNC signals from the sensor
+ */
+ *flags = SOCAM_MASTER |
+ SOCAM_HSYNC_ACTIVE_HIGH |
+ SOCAM_HSYNC_ACTIVE_LOW |
+ SOCAM_VSYNC_ACTIVE_HIGH |
+ SOCAM_VSYNC_ACTIVE_LOW |
+ SOCAM_PCLK_SAMPLE_RISING |
+ SOCAM_PCLK_SAMPLE_FALLING |
+ SOCAM_DATA_ACTIVE_HIGH |
+ SOCAM_DATA_ACTIVE_LOW;
+
+ /* If requested data width is supported by the platform, use it or any
+ * possible lower value - i.MX31 is smart enough to schift bits */
+ switch (buswidth) {
+ case 15:
+ if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15))
+ return -EINVAL;
+ *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 |
+ SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
+ break;
+ case 10:
+ if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10))
+ return -EINVAL;
+ *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 |
+ SOCAM_DATAWIDTH_4;
+ break;
+ case 8:
+ if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8))
+ return -EINVAL;
+ *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
+ break;
+ case 4:
+ if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4))
+ return -EINVAL;
+ *flags |= SOCAM_DATAWIDTH_4;
+ break;
+ default:
+ dev_info(mx3_cam->dev, "Unsupported bus width %d\n", buswidth);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
+ const unsigned int depth)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ unsigned long bus_flags, camera_flags;
+ int ret = test_platform_param(mx3_cam, depth, &bus_flags);
+
+ dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", depth, ret);
+
+ if (ret < 0)
+ return ret;
+
+ camera_flags = icd->ops->query_bus_param(icd);
+
+ ret = soc_camera_bus_param_compatible(camera_flags, bus_flags);
+ if (ret < 0)
+ dev_warn(&icd->dev, "Flags incompatible: camera %lx, host %lx\n",
+ camera_flags, bus_flags);
+
+ return ret;
+}
+
+static bool chan_filter(struct dma_chan *chan, void *arg)
+{
+ struct dma_chan_request *rq = arg;
+ struct mx3_camera_pdata *pdata;
+
+ if (!rq)
+ return false;
+
+ pdata = rq->mx3_cam->dev->platform_data;
+
+ return rq->id == chan->chan_id &&
+ pdata->dma_dev == chan->device->dev;
+}
+
+static const struct soc_camera_data_format mx3_camera_formats[] = {
+ {
+ .name = "Bayer (sRGB) 8 bit",
+ .depth = 8,
+ .fourcc = V4L2_PIX_FMT_SBGGR8,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ }, {
+ .name = "Monochrome 8 bit",
+ .depth = 8,
+ .fourcc = V4L2_PIX_FMT_GREY,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+};
+
+static bool buswidth_supported(struct soc_camera_host *ici, int depth)
+{
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+
+ switch (depth) {
+ case 4:
+ return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4);
+ case 8:
+ return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8);
+ case 10:
+ return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10);
+ case 15:
+ return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15);
+ }
+ return false;
+}
+
+static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
+ struct soc_camera_format_xlate *xlate)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ int formats = 0, buswidth, ret;
+
+ buswidth = icd->formats[idx].depth;
+
+ if (!buswidth_supported(ici, buswidth))
+ return 0;
+
+ ret = mx3_camera_try_bus_param(icd, buswidth);
+ if (ret < 0)
+ return 0;
+
+ switch (icd->formats[idx].fourcc) {
+ case V4L2_PIX_FMT_SGRBG10:
+ formats++;
+ if (xlate) {
+ xlate->host_fmt = &mx3_camera_formats[0];
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = buswidth;
+ xlate++;
+ dev_dbg(&ici->dev, "Providing format %s using %s\n",
+ mx3_camera_formats[0].name,
+ icd->formats[idx].name);
+ }
+ goto passthrough;
+ case V4L2_PIX_FMT_Y16:
+ formats++;
+ if (xlate) {
+ xlate->host_fmt = &mx3_camera_formats[1];
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = buswidth;
+ xlate++;
+ dev_dbg(&ici->dev, "Providing format %s using %s\n",
+ mx3_camera_formats[0].name,
+ icd->formats[idx].name);
+ }
+ default:
+passthrough:
+ /* Generic pass-through */
+ formats++;
+ if (xlate) {
+ xlate->host_fmt = icd->formats + idx;
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = buswidth;
+ xlate++;
+ dev_dbg(&ici->dev,
+ "Providing format %s in pass-through mode\n",
+ icd->formats[idx].name);
+ }
+ }
+
+ return formats;
+}
+
+static void configure_geometry(struct mx3_camera_dev *mx3_cam,
+ struct v4l2_rect *rect)
+{
+ u32 ctrl, width_field, height_field;
+
+ /* Setup frame size - this cannot be changed on-the-fly... */
+ width_field = rect->width - 1;
+ height_field = rect->height - 1;
+ csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE);
+
+ csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1);
+ csi_reg_write(mx3_cam, (height_field << 16) | 0x22, CSI_FLASH_STROBE_2);
+
+ csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_ACT_FRM_SIZE);
+
+ /* ...and position */
+ ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
+ /* Sensor does the cropping */
+ csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL);
+
+ /*
+ * No need to free resources here if we fail, we'll see if we need to
+ * do this next time we are called
+ */
+}
+
+static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
+{
+ dma_cap_mask_t mask;
+ struct dma_chan *chan;
+ struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
+ /* We have to use IDMAC_IC_7 for Bayer / generic data */
+ struct dma_chan_request rq = {.mx3_cam = mx3_cam,
+ .id = IDMAC_IC_7};
+
+ if (*ichan) {
+ struct videobuf_buffer *vb, *_vb;
+ dma_release_channel(&(*ichan)->dma_chan);
+ *ichan = NULL;
+ mx3_cam->active = NULL;
+ list_for_each_entry_safe(vb, _vb, &mx3_cam->capture, queue) {
+ list_del_init(&vb->queue);
+ vb->state = VIDEOBUF_ERROR;
+ wake_up(&vb->done);
+ }
+ }
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ dma_cap_set(DMA_PRIVATE, mask);
+ chan = dma_request_channel(mask, chan_filter, &rq);
+ if (!chan)
+ return -EBUSY;
+
+ *ichan = to_idmac_chan(chan);
+ (*ichan)->client = mx3_cam;
+
+ return 0;
+}
+
+static int mx3_camera_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+
+ /*
+ * We now know pixel formats and can decide upon DMA-channel(s)
+ * So far only direct camera-to-memory is supported
+ */
+ if (channel_change_requested(icd, rect)) {
+ int ret = acquire_dma_channel(mx3_cam);
+ if (ret < 0)
+ return ret;
+ }
+
+ configure_geometry(mx3_cam, rect);
+
+ return icd->ops->set_crop(icd, rect);
+}
+
+static int mx3_camera_set_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ const struct soc_camera_format_xlate *xlate;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct v4l2_rect rect = {
+ .left = icd->x_current,
+ .top = icd->y_current,
+ .width = pix->width,
+ .height = pix->height,
+ };
+ int ret;
+
+ xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
+ if (!xlate) {
+ dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+ return -EINVAL;
+ }
+
+ ret = acquire_dma_channel(mx3_cam);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Might have to perform a complete interface initialisation like in
+ * ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider
+ * mxc_v4l2_s_fmt()
+ */
+
+ configure_geometry(mx3_cam, &rect);
+
+ ret = icd->ops->set_fmt(icd, f);
+ if (!ret) {
+ icd->buswidth = xlate->buswidth;
+ icd->current_fmt = xlate->host_fmt;
+ }
+
+ return ret;
+}
+
+static int mx3_camera_try_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ const struct soc_camera_format_xlate *xlate;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ __u32 pixfmt = pix->pixelformat;
+ enum v4l2_field field;
+ int ret;
+
+ xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
+ if (pixfmt && !xlate) {
+ dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+ return -EINVAL;
+ }
+
+ /* limit to MX3 hardware capabilities */
+ if (pix->height > 4096)
+ pix->height = 4096;
+ if (pix->width > 4096)
+ pix->width = 4096;
+
+ pix->bytesperline = pix->width *
+ DIV_ROUND_UP(xlate->host_fmt->depth, 8);
+ pix->sizeimage = pix->height * pix->bytesperline;
+
+ /* camera has to see its format, but the user the original one */
+ pix->pixelformat = xlate->cam_fmt->fourcc;
+ /* limit to sensor capabilities */
+ ret = icd->ops->try_fmt(icd, f);
+ pix->pixelformat = xlate->host_fmt->fourcc;
+
+ field = pix->field;
+
+ if (field == V4L2_FIELD_ANY) {
+ pix->field = V4L2_FIELD_NONE;
+ } else if (field != V4L2_FIELD_NONE) {
+ dev_err(&icd->dev, "Field type %d unsupported.\n", field);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int mx3_camera_reqbufs(struct soc_camera_file *icf,
+ struct v4l2_requestbuffers *p)
+{
+ return 0;
+}
+
+static unsigned int mx3_camera_poll(struct file *file, poll_table *pt)
+{
+ struct soc_camera_file *icf = file->private_data;
+
+ return videobuf_poll_stream(file, &icf->vb_vidq, pt);
+}
+
+static int mx3_camera_querycap(struct soc_camera_host *ici,
+ struct v4l2_capability *cap)
+{
+ /* cap->name is set by the firendly caller:-> */
+ strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card));
+ cap->version = KERNEL_VERSION(0, 2, 2);
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+
+ return 0;
+}
+
+static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ unsigned long bus_flags, camera_flags, common_flags;
+ u32 dw, sens_conf;
+ int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags);
+ const struct soc_camera_format_xlate *xlate;
+
+ xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
+ if (!xlate) {
+ dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+ return -EINVAL;
+ }
+
+ dev_dbg(&ici->dev, "requested bus width %d bit: %d\n",
+ icd->buswidth, ret);
+
+ if (ret < 0)
+ return ret;
+
+ camera_flags = icd->ops->query_bus_param(icd);
+
+ common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
+ if (!common_flags) {
+ dev_dbg(&ici->dev, "no common flags: camera %lx, host %lx\n",
+ camera_flags, bus_flags);
+ return -EINVAL;
+ }
+
+ /* Make choices, based on platform preferences */
+ if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
+ (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
+ if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
+ common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
+ else
+ common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
+ }
+
+ if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
+ (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
+ if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
+ common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
+ else
+ common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
+ }
+
+ if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) &&
+ (common_flags & SOCAM_DATA_ACTIVE_LOW)) {
+ if (mx3_cam->platform_flags & MX3_CAMERA_DP)
+ common_flags &= ~SOCAM_DATA_ACTIVE_HIGH;
+ else
+ common_flags &= ~SOCAM_DATA_ACTIVE_LOW;
+ }
+
+ if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
+ (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
+ if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
+ common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
+ else
+ common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
+ }
+
+ /* Make the camera work in widest common mode, we'll take care of
+ * the rest */
+ if (common_flags & SOCAM_DATAWIDTH_15)
+ common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
+ SOCAM_DATAWIDTH_15;
+ else if (common_flags & SOCAM_DATAWIDTH_10)
+ common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
+ SOCAM_DATAWIDTH_10;
+ else if (common_flags & SOCAM_DATAWIDTH_8)
+ common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
+ SOCAM_DATAWIDTH_8;
+ else
+ common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
+ SOCAM_DATAWIDTH_4;
+
+ ret = icd->ops->set_bus_param(icd, common_flags);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * So far only gated clock mode is supported. Add a line
+ * (3 << CSI_SENS_CONF_SENS_PRTCL_SHIFT) |
+ * below and select the required mode when supporting other
+ * synchronisation protocols.
+ */
+ sens_conf = csi_reg_read(mx3_cam, CSI_SENS_CONF) &
+ ~((1 << CSI_SENS_CONF_VSYNC_POL_SHIFT) |
+ (1 << CSI_SENS_CONF_HSYNC_POL_SHIFT) |
+ (1 << CSI_SENS_CONF_DATA_POL_SHIFT) |
+ (1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT) |
+ (3 << CSI_SENS_CONF_DATA_FMT_SHIFT) |
+ (3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT));
+
+ /* TODO: Support RGB and YUV formats */
+
+ /* This has been set in mx3_camera_activate(), but we clear it above */
+ sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
+
+ if (common_flags & SOCAM_PCLK_SAMPLE_FALLING)
+ sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
+ if (common_flags & SOCAM_HSYNC_ACTIVE_LOW)
+ sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
+ if (common_flags & SOCAM_VSYNC_ACTIVE_LOW)
+ sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
+ if (common_flags & SOCAM_DATA_ACTIVE_LOW)
+ sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
+
+ /* Just do what we're asked to do */
+ switch (xlate->host_fmt->depth) {
+ case 4:
+ dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ break;
+ case 8:
+ dw = 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ break;
+ case 10:
+ dw = 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ break;
+ default:
+ /*
+ * Actually it can only be 15 now, default is just to silence
+ * compiler warnings
+ */
+ case 15:
+ dw = 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ }
+
+ csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF);
+
+ dev_dbg(&ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw);
+
+ return 0;
+}
+
+static struct soc_camera_host_ops mx3_soc_camera_host_ops = {
+ .owner = THIS_MODULE,
+ .add = mx3_camera_add_device,
+ .remove = mx3_camera_remove_device,
+#ifdef CONFIG_PM
+ .suspend = mx3_camera_suspend,
+ .resume = mx3_camera_resume,
+#endif
+ .set_crop = mx3_camera_set_crop,
+ .set_fmt = mx3_camera_set_fmt,
+ .try_fmt = mx3_camera_try_fmt,
+ .get_formats = mx3_camera_get_formats,
+ .init_videobuf = mx3_camera_init_videobuf,
+ .reqbufs = mx3_camera_reqbufs,
+ .poll = mx3_camera_poll,
+ .querycap = mx3_camera_querycap,
+ .set_bus_param = mx3_camera_set_bus_param,
+};
+
+static int mx3_camera_probe(struct platform_device *pdev)
+{
+ struct mx3_camera_dev *mx3_cam;
+ struct resource *res;
+ void __iomem *base;
+ int err = 0;
+ struct soc_camera_host *soc_host;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ err = -ENODEV;
+ goto egetres;
+ }
+
+ mx3_cam = vmalloc(sizeof(*mx3_cam));
+ if (!mx3_cam) {
+ dev_err(&pdev->dev, "Could not allocate mx3 camera object\n");
+ err = -ENOMEM;
+ goto ealloc;
+ }
+ memset(mx3_cam, 0, sizeof(*mx3_cam));
+
+ mx3_cam->clk = clk_get(&pdev->dev, "csi_clk");
+ if (IS_ERR(mx3_cam->clk)) {
+ err = PTR_ERR(mx3_cam->clk);
+ goto eclkget;
+ }
+
+ dev_set_drvdata(&pdev->dev, mx3_cam);
+
+ mx3_cam->pdata = pdev->dev.platform_data;
+ mx3_cam->platform_flags = mx3_cam->pdata->flags;
+ if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 |
+ MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10 |
+ MX3_CAMERA_DATAWIDTH_15))) {
+ /* Platform hasn't set available data widths. This is bad.
+ * Warn and use a default. */
+ dev_warn(&pdev->dev, "WARNING! Platform hasn't set available "
+ "data widths, using default 8 bit\n");
+ mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8;
+ }
+
+ mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000;
+ if (!mx3_cam->mclk) {
+ dev_warn(&pdev->dev,
+ "mclk_10khz == 0! Please, fix your platform data. "
+ "Using default 20MHz\n");
+ mx3_cam->mclk = 20000000;
+ }
+
+ /* list of video-buffers */
+ INIT_LIST_HEAD(&mx3_cam->capture);
+ spin_lock_init(&mx3_cam->lock);
+
+ base = ioremap(res->start, res->end - res->start + 1);
+ if (!base) {
+ err = -ENOMEM;
+ goto eioremap;
+ }
+
+ mx3_cam->base = base;
+ mx3_cam->dev = &pdev->dev;
+
+ soc_host = &mx3_cam->soc_host;
+ soc_host->drv_name = MX3_CAM_DRV_NAME;
+ soc_host->ops = &mx3_soc_camera_host_ops;
+ soc_host->priv = mx3_cam;
+ soc_host->dev.parent = &pdev->dev;
+ soc_host->nr = pdev->id;
+ err = soc_camera_host_register(soc_host);
+ if (err)
+ goto ecamhostreg;
+
+ /* IDMAC interface */
+ dmaengine_get();
+
+ return 0;
+
+ecamhostreg:
+ iounmap(base);
+eioremap:
+ clk_put(mx3_cam->clk);
+eclkget:
+ vfree(mx3_cam);
+ealloc:
+egetres:
+ return err;
+}
+
+static int __devexit mx3_camera_remove(struct platform_device *pdev)
+{
+ struct mx3_camera_dev *mx3_cam = platform_get_drvdata(pdev);
+
+ clk_put(mx3_cam->clk);
+
+ soc_camera_host_unregister(&mx3_cam->soc_host);
+
+ iounmap(mx3_cam->base);
+
+ /*
+ * The channel has either not been allocated,
+ * or should have been released
+ */
+ if (WARN_ON(mx3_cam->idmac_channel[0]))
+ dma_release_channel(&mx3_cam->idmac_channel[0]->dma_chan);
+
+ vfree(mx3_cam);
+
+ dmaengine_put();
+
+ dev_info(&pdev->dev, "i.MX3x Camera driver unloaded\n");
+
+ return 0;
+}
+
+static struct platform_driver mx3_camera_driver = {
+ .driver = {
+ .name = MX3_CAM_DRV_NAME,
+ },
+ .probe = mx3_camera_probe,
+ .remove = __exit_p(mx3_camera_remove),
+};
+
+
+static int __devinit mx3_camera_init(void)
+{
+ return platform_driver_register(&mx3_camera_driver);
+}
+
+static void __exit mx3_camera_exit(void)
+{
+ platform_driver_unregister(&mx3_camera_driver);
+}
+
+module_init(mx3_camera_init);
+module_exit(mx3_camera_exit);
+
+MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver");
+MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index e3cbe14c349a..84aec62e8452 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -25,16 +25,20 @@
#include <media/saa7146_vv.h>
#include <media/tuner.h>
-#include <linux/video_decoder.h>
#include <media/v4l2-common.h>
#include <media/saa7115.h>
#include "mxb.h"
#include "tea6415c.h"
#include "tea6420.h"
-#include "tda9840.h"
-#define I2C_SAA7111 0x24
+#define I2C_SAA5246A 0x11
+#define I2C_SAA7111A 0x24
+#define I2C_TDA9840 0x42
+#define I2C_TEA6415C 0x43
+#define I2C_TEA6420_1 0x4c
+#define I2C_TEA6420_2 0x4d
+#define I2C_TUNER 0x60
#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
@@ -79,57 +83,35 @@ static struct {
static int video_audio_connect[MXB_INPUTS] =
{ 0, 1, 3, 3 };
-/* these are the necessary input-output-pins for bringing one audio source
-(see above) to the CD-output */
-static struct tea6420_multiplex TEA6420_cd[MXB_AUDIOS+1][2] =
- {
- {{1,1,0},{1,1,0}}, /* Tuner */
- {{5,1,0},{6,1,0}}, /* AUX 1 */
- {{4,1,0},{6,1,0}}, /* AUX 2 */
- {{3,1,0},{6,1,0}}, /* AUX 3 */
- {{1,1,0},{3,1,0}}, /* Radio */
- {{1,1,0},{2,1,0}}, /* CD-Rom */
- {{6,1,0},{6,1,0}} /* Mute */
- };
-
-/* these are the necessary input-output-pins for bringing one audio source
-(see above) to the line-output */
-static struct tea6420_multiplex TEA6420_line[MXB_AUDIOS+1][2] =
- {
- {{2,3,0},{1,2,0}},
- {{5,3,0},{6,2,0}},
- {{4,3,0},{6,2,0}},
- {{3,3,0},{6,2,0}},
- {{2,3,0},{3,2,0}},
- {{2,3,0},{2,2,0}},
- {{6,3,0},{6,2,0}} /* Mute */
- };
+/* These are the necessary input-output-pins for bringing one audio source
+ (see above) to the CD-output. Note that gain is set to 0 in this table. */
+static struct v4l2_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
+ { { 1, 1 }, { 1, 1 } }, /* Tuner */
+ { { 5, 1 }, { 6, 1 } }, /* AUX 1 */
+ { { 4, 1 }, { 6, 1 } }, /* AUX 2 */
+ { { 3, 1 }, { 6, 1 } }, /* AUX 3 */
+ { { 1, 1 }, { 3, 1 } }, /* Radio */
+ { { 1, 1 }, { 2, 1 } }, /* CD-Rom */
+ { { 6, 1 }, { 6, 1 } } /* Mute */
+};
+
+/* These are the necessary input-output-pins for bringing one audio source
+ (see above) to the line-output. Note that gain is set to 0 in this table. */
+static struct v4l2_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
+ { { 2, 3 }, { 1, 2 } },
+ { { 5, 3 }, { 6, 2 } },
+ { { 4, 3 }, { 6, 2 } },
+ { { 3, 3 }, { 6, 2 } },
+ { { 2, 3 }, { 3, 2 } },
+ { { 2, 3 }, { 2, 2 } },
+ { { 6, 3 }, { 6, 2 } } /* Mute */
+};
#define MAXCONTROLS 1
static struct v4l2_queryctrl mxb_controls[] = {
{ V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
};
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
- { VIDIOC_G_CTRL, SAA7146_BEFORE },
- { VIDIOC_S_CTRL, SAA7146_BEFORE },
- { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_DBG_G_REGISTER, SAA7146_EXCLUSIVE },
- { VIDIOC_DBG_S_REGISTER, SAA7146_EXCLUSIVE },
- { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */
- { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */
- { 0, 0 }
-};
-
struct mxb
{
struct video_device *video_dev;
@@ -137,12 +119,12 @@ struct mxb
struct i2c_adapter i2c_adapter;
- struct i2c_client *saa7111a;
- struct i2c_client *tda9840;
- struct i2c_client *tea6415c;
- struct i2c_client *tuner;
- struct i2c_client *tea6420_1;
- struct i2c_client *tea6420_2;
+ struct v4l2_subdev *saa7111a;
+ struct v4l2_subdev *tda9840;
+ struct v4l2_subdev *tea6415c;
+ struct v4l2_subdev *tuner;
+ struct v4l2_subdev *tea6420_1;
+ struct v4l2_subdev *tea6420_2;
int cur_mode; /* current audio mode (mono, stereo, ...) */
int cur_input; /* current input */
@@ -150,84 +132,51 @@ struct mxb
struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */
};
-static struct saa7146_extension extension;
-
-static int mxb_check_clients(struct device *dev, void *data)
-{
- struct mxb *mxb = data;
- struct i2c_client *client = i2c_verify_client(dev);
-
- if (!client)
- return 0;
-
- if (I2C_ADDR_TEA6420_1 == client->addr)
- mxb->tea6420_1 = client;
- if (I2C_ADDR_TEA6420_2 == client->addr)
- mxb->tea6420_2 = client;
- if (I2C_TEA6415C_2 == client->addr)
- mxb->tea6415c = client;
- if (I2C_ADDR_TDA9840 == client->addr)
- mxb->tda9840 = client;
- if (I2C_SAA7111 == client->addr)
- mxb->saa7111a = client;
- if (0x60 == client->addr)
- mxb->tuner = client;
+#define saa7111a_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
+#define tea6420_1_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tea6420_1, o, f, ##args)
+#define tea6420_2_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tea6420_2, o, f, ##args)
+#define tda9840_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tda9840, o, f, ##args)
+#define tea6415c_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tea6415c, o, f, ##args)
+#define tuner_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tuner, o, f, ##args)
+#define call_all(dev, o, f, args...) \
+ v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
- return 0;
-}
+static struct saa7146_extension extension;
-static int mxb_probe(struct saa7146_dev* dev)
+static int mxb_probe(struct saa7146_dev *dev)
{
- struct mxb* mxb = NULL;
- int result;
-
- result = request_module("saa7115");
- if (result < 0) {
- printk("mxb: saa7111 i2c module not available.\n");
- return -ENODEV;
- }
- result = request_module("tea6420");
- if (result < 0) {
- printk("mxb: tea6420 i2c module not available.\n");
- return -ENODEV;
- }
- result = request_module("tea6415c");
- if (result < 0) {
- printk("mxb: tea6415c i2c module not available.\n");
- return -ENODEV;
- }
- result = request_module("tda9840");
- if (result < 0) {
- printk("mxb: tda9840 i2c module not available.\n");
- return -ENODEV;
- }
- result = request_module("tuner");
- if (result < 0) {
- printk("mxb: tuner i2c module not available.\n");
- return -ENODEV;
- }
+ struct mxb *mxb = NULL;
mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
- if( NULL == mxb ) {
+ if (mxb == NULL) {
DEB_D(("not enough kernel memory.\n"));
return -ENOMEM;
}
- mxb->i2c_adapter = (struct i2c_adapter) {
- .class = I2C_CLASS_TV_ANALOG,
- };
-
snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);
saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
- if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
+ if (i2c_add_adapter(&mxb->i2c_adapter) < 0) {
DEB_S(("cannot register i2c-device. skipping.\n"));
kfree(mxb);
return -EFAULT;
}
- /* loop through all i2c-devices on the bus and look who is there */
- device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients);
+ mxb->saa7111a = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "saa7115", "saa7111", I2C_SAA7111A);
+ mxb->tea6420_1 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6420", "tea6420", I2C_TEA6420_1);
+ mxb->tea6420_2 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6420", "tea6420", I2C_TEA6420_2);
+ mxb->tea6415c = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6415c", "tea6415c", I2C_TEA6415C);
+ mxb->tda9840 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tda9840", "tda9840", I2C_TDA9840);
+ mxb->tuner = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tuner", "tuner", I2C_TUNER);
+ if (v4l2_i2c_new_subdev(&mxb->i2c_adapter, "saa5246a", "saa5246a", I2C_SAA5246A)) {
+ printk(KERN_INFO "mxb: found teletext decoder\n");
+ }
/* check if all devices are present */
if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
@@ -315,47 +264,45 @@ static int mxb_init_done(struct saa7146_dev* dev)
struct v4l2_routing route;
int i = 0, err = 0;
- struct tea6415c_multiplex vm;
/* select video mode in saa7111a */
- mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_S_STD, &std);
+ saa7111a_call(mxb, tuner, s_std, std);
/* select tuner-output on saa7111a */
i = 0;
route.input = SAA7115_COMPOSITE0;
route.output = SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS;
- mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route);
+ saa7111a_call(mxb, video, s_routing, &route);
/* select a tuner type */
tun_setup.mode_mask = T_ANALOG_TV;
tun_setup.addr = ADDR_UNSET;
tun_setup.type = TUNER_PHILIPS_PAL;
- mxb->tuner->driver->command(mxb->tuner, TUNER_SET_TYPE_ADDR, &tun_setup);
+ tuner_call(mxb, tuner, s_type_addr, &tun_setup);
/* tune in some frequency on tuner */
mxb->cur_freq.tuner = 0;
mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
mxb->cur_freq.frequency = freq;
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY,
- &mxb->cur_freq);
+ tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
/* set a default video standard */
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
+ tuner_call(mxb, tuner, s_std, std);
/* mute audio on tea6420s */
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[6][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[6][1]);
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[6][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[6][1]);
+ tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]);
+ tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]);
+ tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]);
+ tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]);
- /* switch to tuner-channel on tea6415c*/
- vm.out = 17;
- vm.in = 3;
- mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);
+ /* switch to tuner-channel on tea6415c */
+ route.input = 3;
+ route.output = 17;
+ tea6415c_call(mxb, video, s_routing, &route);
- /* select tuner-output on multicable on tea6415c*/
- vm.in = 3;
- vm.out = 13;
- mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);
+ /* select tuner-output on multicable on tea6415c */
+ route.input = 3;
+ route.output = 13;
+ tea6415c_call(mxb, video, s_routing, &route);
/* the rest for mxb */
mxb->cur_input = 0;
@@ -424,395 +371,414 @@ void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
}
*/
-static struct saa7146_ext_vv vv_data;
-
-/* this function only gets called when the probing was successful */
-static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
{
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
-
- DEB_EE(("dev:%p\n", dev));
-
- /* checking for i2c-devices can be omitted here, because we
- already did this in "mxb_vl42_probe" */
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ int i;
- saa7146_vv_init(dev, &vv_data);
- if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
- ERR(("cannot register capture v4l2 device. skipping.\n"));
- return -1;
+ for (i = MAXCONTROLS - 1; i >= 0; i--) {
+ if (mxb_controls[i].id == qc->id) {
+ *qc = mxb_controls[i];
+ DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
+ return 0;
+ }
}
+ return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
+}
- /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
- if (MXB_BOARD_CAN_DO_VBI(dev)) {
- if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
- ERR(("cannot register vbi v4l2 device. skipping.\n"));
- }
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ int i;
+
+ for (i = MAXCONTROLS - 1; i >= 0; i--) {
+ if (mxb_controls[i].id == vc->id)
+ break;
}
- i2c_use_client(mxb->tea6420_1);
- i2c_use_client(mxb->tea6420_2);
- i2c_use_client(mxb->tea6415c);
- i2c_use_client(mxb->tda9840);
- i2c_use_client(mxb->saa7111a);
- i2c_use_client(mxb->tuner);
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
- printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
+ if (vc->id == V4L2_CID_AUDIO_MUTE) {
+ vc->value = mxb->cur_mute;
+ DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
+ return 0;
+ }
- mxb_num++;
- mxb_init_done(dev);
+ DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
return 0;
}
-static int mxb_detach(struct saa7146_dev *dev)
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ int i = 0;
- DEB_EE(("dev:%p\n", dev));
-
- i2c_release_client(mxb->tea6420_1);
- i2c_release_client(mxb->tea6420_2);
- i2c_release_client(mxb->tea6415c);
- i2c_release_client(mxb->tda9840);
- i2c_release_client(mxb->saa7111a);
- i2c_release_client(mxb->tuner);
-
- saa7146_unregister_device(&mxb->video_dev,dev);
- if (MXB_BOARD_CAN_DO_VBI(dev))
- saa7146_unregister_device(&mxb->vbi_dev, dev);
- saa7146_vv_release(dev);
-
- mxb_num--;
+ for (i = MAXCONTROLS - 1; i >= 0; i--) {
+ if (mxb_controls[i].id == vc->id)
+ break;
+ }
- i2c_del_adapter(&mxb->i2c_adapter);
- kfree(mxb);
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
+
+ if (vc->id == V4L2_CID_AUDIO_MUTE) {
+ mxb->cur_mute = vc->value;
+ if (!vc->value) {
+ /* switch the audio-source */
+ tea6420_1_call(mxb, audio, s_routing,
+ &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
+ tea6420_2_call(mxb, audio, s_routing,
+ &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
+ } else {
+ tea6420_1_call(mxb, audio, s_routing,
+ &TEA6420_line[6][0]);
+ tea6420_2_call(mxb, audio, s_routing,
+ &TEA6420_line[6][1]);
+ }
+ DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
+ }
+ return 0;
+}
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+ if (i->index < 0 || i->index >= MXB_INPUTS)
+ return -EINVAL;
+ memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
return 0;
}
-static long mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
{
- struct saa7146_dev *dev = fh->dev;
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct mxb *mxb = (struct mxb *)dev->ext_priv;
- struct saa7146_vv *vv = dev->vv_data;
+ *i = mxb->cur_input;
- switch(cmd) {
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
+ DEB_EE(("VIDIOC_G_INPUT %d.\n", *i));
+ return 0;
+}
- DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
- if (i->index < 0 || i->index >= MXB_INPUTS)
- return -EINVAL;
- memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
- return 0;
- }
- /* the saa7146 provides some controls (brightness, contrast, saturation)
- which gets registered *after* this function. because of this we have
- to return with a value != 0 even if the function succeded.. */
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = MAXCONTROLS - 1; i >= 0; i--) {
- if (mxb_controls[i].id == qc->id) {
- *qc = mxb_controls[i];
- DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
- return 0;
- }
- }
- return -EAGAIN;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i;
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ struct v4l2_routing route;
+ int i = 0;
- for (i = MAXCONTROLS - 1; i >= 0; i--) {
- if (mxb_controls[i].id == vc->id)
- break;
- }
+ DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
- if (i < 0)
- return -EAGAIN;
+ if (input < 0 || input >= MXB_INPUTS)
+ return -EINVAL;
- if (vc->id == V4L2_CID_AUDIO_MUTE) {
- vc->value = mxb->cur_mute;
- DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
- return 0;
- }
+ mxb->cur_input = input;
- DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
- return 0;
- }
+ saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
+ input_port_selection[input].hps_sync);
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i = 0;
+ /* prepare switching of tea6415c and saa7111a;
+ have a look at the 'background'-file for further informations */
+ switch (input) {
+ case TUNER:
+ i = SAA7115_COMPOSITE0;
+ route.input = 3;
+ route.output = 17;
- for (i = MAXCONTROLS - 1; i >= 0; i--) {
- if (mxb_controls[i].id == vc->id)
- break;
+ if (tea6415c_call(mxb, video, s_routing, &route)) {
+ printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
+ return -EFAULT;
}
+ /* connect tuner-output always to multicable */
+ route.input = 3;
+ route.output = 13;
+ break;
+ case AUX3_YC:
+ /* nothing to be done here. aux3_yc is
+ directly connected to the saa711a */
+ i = SAA7115_SVIDEO1;
+ break;
+ case AUX3:
+ /* nothing to be done here. aux3 is
+ directly connected to the saa711a */
+ i = SAA7115_COMPOSITE1;
+ break;
+ case AUX1:
+ i = SAA7115_COMPOSITE0;
+ route.input = 1;
+ route.output = 17;
+ break;
+ }
- if (i < 0)
- return -EAGAIN;
-
- if (vc->id == V4L2_CID_AUDIO_MUTE) {
- mxb->cur_mute = vc->value;
- if (!vc->value) {
- /* switch the audio-source */
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
- } else {
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
- &TEA6420_line[6][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
- &TEA6420_line[6][1]);
- }
- DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
+ /* switch video in tea6415c only if necessary */
+ switch (input) {
+ case TUNER:
+ case AUX1:
+ if (tea6415c_call(mxb, video, s_routing, &route)) {
+ printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
+ return -EFAULT;
}
- return 0;
+ break;
+ default:
+ break;
}
- case VIDIOC_G_INPUT:
- {
- int *input = (int *)arg;
- *input = mxb->cur_input;
- DEB_EE(("VIDIOC_G_INPUT %d.\n", *input));
- return 0;
+ /* switch video in saa7111a */
+ route.input = i;
+ route.output = 0;
+ if (saa7111a_call(mxb, video, s_routing, &route))
+ printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n");
+
+ /* switch the audio-source only if necessary */
+ if (0 == mxb->cur_mute) {
+ tea6420_1_call(mxb, audio, s_routing,
+ &TEA6420_line[video_audio_connect[input]][0]);
+ tea6420_2_call(mxb, audio, s_routing,
+ &TEA6420_line[video_audio_connect[input]][1]);
}
- case VIDIOC_S_INPUT:
- {
- int input = *(int *)arg;
- struct tea6415c_multiplex vm;
- struct v4l2_routing route;
- int i = 0;
- DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
+ return 0;
+}
- if (input < 0 || input >= MXB_INPUTS)
- return -EINVAL;
+static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- mxb->cur_input = input;
+ if (t->index) {
+ DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
+ return -EINVAL;
+ }
- saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
- input_port_selection[input].hps_sync);
+ DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
- /* prepare switching of tea6415c and saa7111a;
- have a look at the 'background'-file for further informations */
- switch (input) {
- case TUNER:
- i = SAA7115_COMPOSITE0;
- vm.in = 3;
- vm.out = 17;
+ memset(t, 0, sizeof(*t));
+ strlcpy(t->name, "TV Tuner", sizeof(t->name));
+ t->type = V4L2_TUNER_ANALOG_TV;
+ t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+ t->audmode = mxb->cur_mode;
+ return call_all(dev, tuner, g_tuner, t);
+}
- if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
- printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
- return -EFAULT;
- }
- /* connect tuner-output always to multicable */
- vm.in = 3;
- vm.out = 13;
- break;
- case AUX3_YC:
- /* nothing to be done here. aux3_yc is
- directly connected to the saa711a */
- i = SAA7115_SVIDEO1;
- break;
- case AUX3:
- /* nothing to be done here. aux3 is
- directly connected to the saa711a */
- i = SAA7115_COMPOSITE1;
- break;
- case AUX1:
- i = SAA7115_COMPOSITE0;
- vm.in = 1;
- vm.out = 17;
- break;
- }
+static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- /* switch video in tea6415c only if necessary */
- switch (input) {
- case TUNER:
- case AUX1:
- if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
- printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
- return -EFAULT;
- }
- break;
- default:
- break;
- }
+ if (t->index) {
+ DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n", t->index));
+ return -EINVAL;
+ }
- /* switch video in saa7111a */
- route.input = i;
- route.output = 0;
- if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route))
- printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
-
- /* switch the audio-source only if necessary */
- if( 0 == mxb->cur_mute ) {
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[input]][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[input]][1]);
- }
+ mxb->cur_mode = t->audmode;
+ return call_all(dev, tuner, s_tuner, t);
+}
- return 0;
+static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ if (mxb->cur_input) {
+ DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
+ mxb->cur_input));
+ return -EINVAL;
}
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *t = arg;
- if (t->index) {
- DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
- return -EINVAL;
- }
+ *f = mxb->cur_freq;
- DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
+ DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
+ return 0;
+}
- memset(t, 0, sizeof(*t));
- i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
+static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ struct saa7146_vv *vv = dev->vv_data;
- strlcpy(t->name, "TV Tuner", sizeof(t->name));
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | \
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
- t->audmode = mxb->cur_mode;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *t = arg;
+ if (f->tuner)
+ return -EINVAL;
- if (t->index) {
- DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
- return -EINVAL;
- }
+ if (V4L2_TUNER_ANALOG_TV != f->type)
+ return -EINVAL;
- mxb->cur_mode = t->audmode;
- i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
- return 0;
+ if (mxb->cur_input) {
+ DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
+ return -EINVAL;
}
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
- if (mxb->cur_input) {
- DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
- mxb->cur_input));
- return -EINVAL;
- }
+ mxb->cur_freq = *f;
+ DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
- *f = mxb->cur_freq;
+ /* tune in desired frequency */
+ tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
- DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
- return 0;
+ /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
+ spin_lock(&dev->slock);
+ vv->vbi_fieldcount = 0;
+ spin_unlock(&dev->slock);
+
+ return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ if (a->index < 0 || a->index > MXB_INPUTS) {
+ DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
+ return -EINVAL;
}
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
- if (f->tuner)
- return -EINVAL;
+ DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
+ memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
+ return 0;
+}
- if (V4L2_TUNER_ANALOG_TV != f->type)
- return -EINVAL;
+static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
+ return 0;
+}
- if (mxb->cur_input) {
- DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
- return -EINVAL;
- }
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- mxb->cur_freq = *f;
- DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
+ return call_all(dev, core, g_register, reg);
+}
- /* tune in desired frequency */
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
+static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
- spin_lock(&dev->slock);
- vv->vbi_fieldcount = 0;
- spin_unlock(&dev->slock);
+ return call_all(dev, core, s_register, reg);
+}
+#endif
- return 0;
- }
+static long vidioc_default(struct file *file, void *fh, int cmd, void *arg)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ switch (cmd) {
case MXB_S_AUDIO_CD:
{
- int i = *(int*)arg;
+ int i = *(int *)arg;
if (i < 0 || i >= MXB_AUDIOS) {
- DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
+ DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n", i));
return -EINVAL;
}
- DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));
+ DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i));
- mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
+ tea6420_1_call(mxb, audio, s_routing, &TEA6420_cd[i][0]);
+ tea6420_2_call(mxb, audio, s_routing, &TEA6420_cd[i][1]);
return 0;
}
case MXB_S_AUDIO_LINE:
{
- int i = *(int*)arg;
+ int i = *(int *)arg;
if (i < 0 || i >= MXB_AUDIOS) {
- DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
+ DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n", i));
return -EINVAL;
}
- DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
- mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);
+ DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i));
+ tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[i][0]);
+ tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[i][1]);
return 0;
}
- case VIDIOC_G_AUDIO:
- {
- struct v4l2_audio *a = arg;
+ default:
+/*
+ DEB2(printk("does not handle this ioctl.\n"));
+*/
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+}
- if (a->index < 0 || a->index > MXB_INPUTS) {
- DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
- return -EINVAL;
- }
+static struct saa7146_ext_vv vv_data;
- DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
- memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
+/* this function only gets called when the probing was successful */
+static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
+{
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- return 0;
- }
- case VIDIOC_S_AUDIO:
- {
- struct v4l2_audio *a = arg;
+ DEB_EE(("dev:%p\n", dev));
- DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
- return 0;
- }
+ /* checking for i2c-devices can be omitted here, because we
+ already did this in "mxb_vl42_probe" */
+
+ saa7146_vv_init(dev, &vv_data);
+ vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
+ vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
+ vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
+ vv_data.ops.vidioc_g_tuner = vidioc_g_tuner;
+ vv_data.ops.vidioc_s_tuner = vidioc_s_tuner;
+ vv_data.ops.vidioc_g_frequency = vidioc_g_frequency;
+ vv_data.ops.vidioc_s_frequency = vidioc_s_frequency;
+ vv_data.ops.vidioc_g_audio = vidioc_g_audio;
+ vv_data.ops.vidioc_s_audio = vidioc_s_audio;
#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_DBG_S_REGISTER:
- case VIDIOC_DBG_G_REGISTER:
- i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
- return 0;
+ vv_data.ops.vidioc_g_register = vidioc_g_register;
+ vv_data.ops.vidioc_s_register = vidioc_s_register;
#endif
- default:
-/*
- DEB2(printk("does not handle this ioctl.\n"));
-*/
- return -ENOIOCTLCMD;
+ vv_data.ops.vidioc_default = vidioc_default;
+ if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
+ ERR(("cannot register capture v4l2 device. skipping.\n"));
+ return -1;
}
+
+ /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
+ if (MXB_BOARD_CAN_DO_VBI(dev)) {
+ if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
+ ERR(("cannot register vbi v4l2 device. skipping.\n"));
+ }
+ }
+
+ printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
+
+ mxb_num++;
+ mxb_init_done(dev);
+ return 0;
+}
+
+static int mxb_detach(struct saa7146_dev *dev)
+{
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ DEB_EE(("dev:%p\n", dev));
+
+ saa7146_unregister_device(&mxb->video_dev,dev);
+ if (MXB_BOARD_CAN_DO_VBI(dev))
+ saa7146_unregister_device(&mxb->vbi_dev, dev);
+ saa7146_vv_release(dev);
+
+ mxb_num--;
+
+ i2c_del_adapter(&mxb->i2c_adapter);
+ kfree(mxb);
+
return 0;
}
static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
{
struct mxb *mxb = (struct mxb *)dev->ext_priv;
- int zero = 0;
- int one = 1;
if (V4L2_STD_PAL_I == standard->id) {
v4l2_std_id std = V4L2_STD_PAL_I;
@@ -821,8 +787,8 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
/* set the 7146 gpio register -- I don't know what this does exactly */
saa7146_write(dev, GPIO_CTRL, 0x00404050);
/* unset the 7111 gpio register -- I don't know what this does exactly */
- mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &zero);
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
+ saa7111a_call(mxb, core, s_gpio, 0);
+ tuner_call(mxb, tuner, s_std, std);
} else {
v4l2_std_id std = V4L2_STD_PAL_BG;
@@ -830,8 +796,8 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
/* set the 7146 gpio register -- I don't know what this does exactly */
saa7146_write(dev, GPIO_CTRL, 0x00404050);
/* set the 7111 gpio register -- I don't know what this does exactly */
- mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &one);
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
+ saa7111a_call(mxb, core, s_gpio, 1);
+ tuner_call(mxb, tuner, s_std, std);
}
return 0;
}
@@ -885,8 +851,6 @@ static struct saa7146_ext_vv vv_data = {
.stds = &standard[0],
.num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = mxb_ioctl,
};
static struct saa7146_extension extension = {
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c
index 73eb656acfe3..5fc4ac0d88f0 100644
--- a/drivers/media/video/omap24xxcam.c
+++ b/drivers/media/video/omap24xxcam.c
@@ -80,17 +80,17 @@ static int omap24xxcam_clock_get(struct omap24xxcam_device *cam)
{
int rval = 0;
- cam->fck = clk_get(cam->dev, "cam_fck");
+ cam->fck = clk_get(cam->dev, "fck");
if (IS_ERR(cam->fck)) {
- dev_err(cam->dev, "can't get cam_fck");
+ dev_err(cam->dev, "can't get camera fck");
rval = PTR_ERR(cam->fck);
omap24xxcam_clock_put(cam);
return rval;
}
- cam->ick = clk_get(cam->dev, "cam_ick");
+ cam->ick = clk_get(cam->dev, "ick");
if (IS_ERR(cam->ick)) {
- dev_err(cam->dev, "can't get cam_ick");
+ dev_err(cam->dev, "can't get camera ick");
rval = PTR_ERR(cam->ick);
omap24xxcam_clock_put(cam);
}
@@ -1285,9 +1285,6 @@ static int vidioc_g_parm(struct file *file, void *fh,
struct omap24xxcam_device *cam = ofh->cam;
int rval;
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
mutex_lock(&cam->mutex);
rval = vidioc_int_g_parm(cam->sdev, a);
mutex_unlock(&cam->mutex);
@@ -1303,9 +1300,6 @@ static int vidioc_s_parm(struct file *file, void *fh,
struct v4l2_streamparm old_streamparm;
int rval;
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
mutex_lock(&cam->mutex);
if (cam->streaming) {
rval = -EBUSY;
@@ -1665,7 +1659,6 @@ static int omap24xxcam_device_register(struct v4l2_int_device *s)
vfd->parent = cam->dev;
strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));
- vfd->vfl_type = VID_TYPE_CAPTURE | VID_TYPE_CHROMAKEY;
vfd->fops = &omap24xxcam_fops;
vfd->minor = -1;
vfd->ioctl_ops = &omap24xxcam_ioctl_fops;
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 05c14a29375a..0e2184ec994e 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -12,18 +12,22 @@
*/
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/i2c.h>
#include <linux/delay.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
-#include <linux/i2c.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
MODULE_DESCRIPTION("A low-level driver for OmniVision ov7670 sensors");
MODULE_LICENSE("GPL");
+static int debug;
+module_param(debug, bool, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
/*
* Basic window sizes. These probably belong somewhere more globally
* useful.
@@ -189,11 +193,16 @@ MODULE_LICENSE("GPL");
*/
struct ov7670_format_struct; /* coming later */
struct ov7670_info {
+ struct v4l2_subdev sd;
struct ov7670_format_struct *fmt; /* Current format */
unsigned char sat; /* Saturation value */
int hue; /* Hue value */
};
+static inline struct ov7670_info *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct ov7670_info, sd);
+}
@@ -400,24 +409,27 @@ static struct regval_list ov7670_fmt_raw[] = {
* Low-level register I/O.
*/
-static int ov7670_read(struct i2c_client *c, unsigned char reg,
+static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg,
unsigned char *value)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
- ret = i2c_smbus_read_byte_data(c, reg);
+ ret = i2c_smbus_read_byte_data(client, reg);
if (ret >= 0) {
- *value = (unsigned char) ret;
+ *value = (unsigned char)ret;
ret = 0;
}
return ret;
}
-static int ov7670_write(struct i2c_client *c, unsigned char reg,
+static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg,
unsigned char value)
{
- int ret = i2c_smbus_write_byte_data(c, reg, value);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret = i2c_smbus_write_byte_data(client, reg, value);
+
if (reg == REG_COM7 && (value & COM7_RESET))
msleep(2); /* Wait for reset to run */
return ret;
@@ -427,10 +439,10 @@ static int ov7670_write(struct i2c_client *c, unsigned char reg,
/*
* Write a list of register settings; ff/ff stops the process.
*/
-static int ov7670_write_array(struct i2c_client *c, struct regval_list *vals)
+static int ov7670_write_array(struct v4l2_subdev *sd, struct regval_list *vals)
{
while (vals->reg_num != 0xff || vals->value != 0xff) {
- int ret = ov7670_write(c, vals->reg_num, vals->value);
+ int ret = ov7670_write(sd, vals->reg_num, vals->value);
if (ret < 0)
return ret;
vals++;
@@ -442,34 +454,35 @@ static int ov7670_write_array(struct i2c_client *c, struct regval_list *vals)
/*
* Stuff that knows about the sensor.
*/
-static void ov7670_reset(struct i2c_client *client)
+static int ov7670_reset(struct v4l2_subdev *sd, u32 val)
{
- ov7670_write(client, REG_COM7, COM7_RESET);
+ ov7670_write(sd, REG_COM7, COM7_RESET);
msleep(1);
+ return 0;
}
-static int ov7670_init(struct i2c_client *client)
+static int ov7670_init(struct v4l2_subdev *sd, u32 val)
{
- return ov7670_write_array(client, ov7670_default_regs);
+ return ov7670_write_array(sd, ov7670_default_regs);
}
-static int ov7670_detect(struct i2c_client *client)
+static int ov7670_detect(struct v4l2_subdev *sd)
{
unsigned char v;
int ret;
- ret = ov7670_init(client);
+ ret = ov7670_init(sd, 0);
if (ret < 0)
return ret;
- ret = ov7670_read(client, REG_MIDH, &v);
+ ret = ov7670_read(sd, REG_MIDH, &v);
if (ret < 0)
return ret;
if (v != 0x7f) /* OV manuf. id. */
return -ENODEV;
- ret = ov7670_read(client, REG_MIDL, &v);
+ ret = ov7670_read(sd, REG_MIDL, &v);
if (ret < 0)
return ret;
if (v != 0xa2)
@@ -477,12 +490,12 @@ static int ov7670_detect(struct i2c_client *client)
/*
* OK, we know we have an OmniVision chip...but which one?
*/
- ret = ov7670_read(client, REG_PID, &v);
+ ret = ov7670_read(sd, REG_PID, &v);
if (ret < 0)
return ret;
if (v != 0x76) /* PID + VER = 0x76 / 0x73 */
return -ENODEV;
- ret = ov7670_read(client, REG_VER, &v);
+ ret = ov7670_read(sd, REG_VER, &v);
if (ret < 0)
return ret;
if (v != 0x73) /* PID + VER = 0x76 / 0x73 */
@@ -627,7 +640,7 @@ static struct ov7670_win_size {
/*
* Store a set of start/stop values into the camera.
*/
-static int ov7670_set_hw(struct i2c_client *client, int hstart, int hstop,
+static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop,
int vstart, int vstop)
{
int ret;
@@ -637,26 +650,26 @@ static int ov7670_set_hw(struct i2c_client *client, int hstart, int hstop,
* hstart are in href[2:0], bottom 3 of hstop in href[5:3]. There is
* a mystery "edge offset" value in the top two bits of href.
*/
- ret = ov7670_write(client, REG_HSTART, (hstart >> 3) & 0xff);
- ret += ov7670_write(client, REG_HSTOP, (hstop >> 3) & 0xff);
- ret += ov7670_read(client, REG_HREF, &v);
+ ret = ov7670_write(sd, REG_HSTART, (hstart >> 3) & 0xff);
+ ret += ov7670_write(sd, REG_HSTOP, (hstop >> 3) & 0xff);
+ ret += ov7670_read(sd, REG_HREF, &v);
v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x7);
msleep(10);
- ret += ov7670_write(client, REG_HREF, v);
+ ret += ov7670_write(sd, REG_HREF, v);
/*
* Vertical: similar arrangement, but only 10 bits.
*/
- ret += ov7670_write(client, REG_VSTART, (vstart >> 2) & 0xff);
- ret += ov7670_write(client, REG_VSTOP, (vstop >> 2) & 0xff);
- ret += ov7670_read(client, REG_VREF, &v);
+ ret += ov7670_write(sd, REG_VSTART, (vstart >> 2) & 0xff);
+ ret += ov7670_write(sd, REG_VSTOP, (vstop >> 2) & 0xff);
+ ret += ov7670_read(sd, REG_VREF, &v);
v = (v & 0xf0) | ((vstop & 0x3) << 2) | (vstart & 0x3);
msleep(10);
- ret += ov7670_write(client, REG_VREF, v);
+ ret += ov7670_write(sd, REG_VREF, v);
return ret;
}
-static int ov7670_enum_fmt(struct i2c_client *c, struct v4l2_fmtdesc *fmt)
+static int ov7670_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt)
{
struct ov7670_format_struct *ofmt;
@@ -671,7 +684,8 @@ static int ov7670_enum_fmt(struct i2c_client *c, struct v4l2_fmtdesc *fmt)
}
-static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt,
+static int ov7670_try_fmt_internal(struct v4l2_subdev *sd,
+ struct v4l2_format *fmt,
struct ov7670_format_struct **ret_fmt,
struct ov7670_win_size **ret_wsize)
{
@@ -715,18 +729,23 @@ static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt,
return 0;
}
+static int ov7670_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ return ov7670_try_fmt_internal(sd, fmt, NULL, NULL);
+}
+
/*
* Set a format.
*/
-static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt)
+static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
int ret;
struct ov7670_format_struct *ovfmt;
struct ov7670_win_size *wsize;
- struct ov7670_info *info = i2c_get_clientdata(c);
- unsigned char com7, clkrc;
+ struct ov7670_info *info = to_state(sd);
+ unsigned char com7, clkrc = 0;
- ret = ov7670_try_fmt(c, fmt, &ovfmt, &wsize);
+ ret = ov7670_try_fmt_internal(sd, fmt, &ovfmt, &wsize);
if (ret)
return ret;
/*
@@ -735,7 +754,7 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt)
* the colors.
*/
if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
- ret = ov7670_read(c, REG_CLKRC, &clkrc);
+ ret = ov7670_read(sd, REG_CLKRC, &clkrc);
if (ret)
return ret;
}
@@ -747,20 +766,20 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt)
*/
com7 = ovfmt->regs[0].value;
com7 |= wsize->com7_bit;
- ov7670_write(c, REG_COM7, com7);
+ ov7670_write(sd, REG_COM7, com7);
/*
* Now write the rest of the array. Also store start/stops
*/
- ov7670_write_array(c, ovfmt->regs + 1);
- ov7670_set_hw(c, wsize->hstart, wsize->hstop, wsize->vstart,
+ ov7670_write_array(sd, ovfmt->regs + 1);
+ ov7670_set_hw(sd, wsize->hstart, wsize->hstop, wsize->vstart,
wsize->vstop);
ret = 0;
if (wsize->regs)
- ret = ov7670_write_array(c, wsize->regs);
+ ret = ov7670_write_array(sd, wsize->regs);
info->fmt = ovfmt;
if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565 && ret == 0)
- ret = ov7670_write(c, REG_CLKRC, clkrc);
+ ret = ov7670_write(sd, REG_CLKRC, clkrc);
return ret;
}
@@ -768,7 +787,7 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt)
* Implement G/S_PARM. There is a "high quality" mode we could try
* to do someday; for now, we just do the frame rate tweak.
*/
-static int ov7670_g_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
+static int ov7670_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
{
struct v4l2_captureparm *cp = &parms->parm.capture;
unsigned char clkrc;
@@ -776,7 +795,7 @@ static int ov7670_g_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- ret = ov7670_read(c, REG_CLKRC, &clkrc);
+ ret = ov7670_read(sd, REG_CLKRC, &clkrc);
if (ret < 0)
return ret;
memset(cp, 0, sizeof(struct v4l2_captureparm));
@@ -788,7 +807,7 @@ static int ov7670_g_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
return 0;
}
-static int ov7670_s_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
+static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
{
struct v4l2_captureparm *cp = &parms->parm.capture;
struct v4l2_fract *tpf = &cp->timeperframe;
@@ -802,7 +821,7 @@ static int ov7670_s_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
/*
* CLKRC has a reserved bit, so let's preserve it.
*/
- ret = ov7670_read(c, REG_CLKRC, &clkrc);
+ ret = ov7670_read(sd, REG_CLKRC, &clkrc);
if (ret < 0)
return ret;
if (tpf->numerator == 0 || tpf->denominator == 0)
@@ -816,7 +835,7 @@ static int ov7670_s_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
clkrc = (clkrc & 0x80) | div;
tpf->numerator = 1;
tpf->denominator = OV7670_FRAME_RATE/div;
- return ov7670_write(c, REG_CLKRC, clkrc);
+ return ov7670_write(sd, REG_CLKRC, clkrc);
}
@@ -829,7 +848,7 @@ static int ov7670_s_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
-static int ov7670_store_cmatrix(struct i2c_client *client,
+static int ov7670_store_cmatrix(struct v4l2_subdev *sd,
int matrix[CMATRIX_LEN])
{
int i, ret;
@@ -839,7 +858,7 @@ static int ov7670_store_cmatrix(struct i2c_client *client,
* Weird crap seems to exist in the upper part of
* the sign bits register, so let's preserve it.
*/
- ret = ov7670_read(client, REG_CMATRIX_SIGN, &signbits);
+ ret = ov7670_read(sd, REG_CMATRIX_SIGN, &signbits);
signbits &= 0xc0;
for (i = 0; i < CMATRIX_LEN; i++) {
@@ -858,9 +877,9 @@ static int ov7670_store_cmatrix(struct i2c_client *client,
else
raw = matrix[i] & 0xff;
}
- ret += ov7670_write(client, REG_CMATRIX_BASE + i, raw);
+ ret += ov7670_write(sd, REG_CMATRIX_BASE + i, raw);
}
- ret += ov7670_write(client, REG_CMATRIX_SIGN, signbits);
+ ret += ov7670_write(sd, REG_CMATRIX_SIGN, signbits);
return ret;
}
@@ -943,29 +962,29 @@ static void ov7670_calc_cmatrix(struct ov7670_info *info,
-static int ov7670_t_sat(struct i2c_client *client, int value)
+static int ov7670_s_sat(struct v4l2_subdev *sd, int value)
{
- struct ov7670_info *info = i2c_get_clientdata(client);
+ struct ov7670_info *info = to_state(sd);
int matrix[CMATRIX_LEN];
int ret;
info->sat = value;
ov7670_calc_cmatrix(info, matrix);
- ret = ov7670_store_cmatrix(client, matrix);
+ ret = ov7670_store_cmatrix(sd, matrix);
return ret;
}
-static int ov7670_q_sat(struct i2c_client *client, __s32 *value)
+static int ov7670_g_sat(struct v4l2_subdev *sd, __s32 *value)
{
- struct ov7670_info *info = i2c_get_clientdata(client);
+ struct ov7670_info *info = to_state(sd);
*value = info->sat;
return 0;
}
-static int ov7670_t_hue(struct i2c_client *client, int value)
+static int ov7670_s_hue(struct v4l2_subdev *sd, int value)
{
- struct ov7670_info *info = i2c_get_clientdata(client);
+ struct ov7670_info *info = to_state(sd);
int matrix[CMATRIX_LEN];
int ret;
@@ -973,14 +992,14 @@ static int ov7670_t_hue(struct i2c_client *client, int value)
return -EINVAL;
info->hue = value;
ov7670_calc_cmatrix(info, matrix);
- ret = ov7670_store_cmatrix(client, matrix);
+ ret = ov7670_store_cmatrix(sd, matrix);
return ret;
}
-static int ov7670_q_hue(struct i2c_client *client, __s32 *value)
+static int ov7670_g_hue(struct v4l2_subdev *sd, __s32 *value)
{
- struct ov7670_info *info = i2c_get_clientdata(client);
+ struct ov7670_info *info = to_state(sd);
*value = info->hue;
return 0;
@@ -994,8 +1013,7 @@ static unsigned char ov7670_sm_to_abs(unsigned char v)
{
if ((v & 0x80) == 0)
return v + 128;
- else
- return 128 - (v & 0x7f);
+ return 128 - (v & 0x7f);
}
@@ -1003,369 +1021,275 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
{
if (v > 127)
return v & 0x7f;
- else
- return (128 - v) | 0x80;
+ return (128 - v) | 0x80;
}
-static int ov7670_t_brightness(struct i2c_client *client, int value)
+static int ov7670_s_brightness(struct v4l2_subdev *sd, int value)
{
unsigned char com8 = 0, v;
int ret;
- ov7670_read(client, REG_COM8, &com8);
+ ov7670_read(sd, REG_COM8, &com8);
com8 &= ~COM8_AEC;
- ov7670_write(client, REG_COM8, com8);
+ ov7670_write(sd, REG_COM8, com8);
v = ov7670_abs_to_sm(value);
- ret = ov7670_write(client, REG_BRIGHT, v);
+ ret = ov7670_write(sd, REG_BRIGHT, v);
return ret;
}
-static int ov7670_q_brightness(struct i2c_client *client, __s32 *value)
+static int ov7670_g_brightness(struct v4l2_subdev *sd, __s32 *value)
{
unsigned char v = 0;
- int ret = ov7670_read(client, REG_BRIGHT, &v);
+ int ret = ov7670_read(sd, REG_BRIGHT, &v);
*value = ov7670_sm_to_abs(v);
return ret;
}
-static int ov7670_t_contrast(struct i2c_client *client, int value)
+static int ov7670_s_contrast(struct v4l2_subdev *sd, int value)
{
- return ov7670_write(client, REG_CONTRAS, (unsigned char) value);
+ return ov7670_write(sd, REG_CONTRAS, (unsigned char) value);
}
-static int ov7670_q_contrast(struct i2c_client *client, __s32 *value)
+static int ov7670_g_contrast(struct v4l2_subdev *sd, __s32 *value)
{
unsigned char v = 0;
- int ret = ov7670_read(client, REG_CONTRAS, &v);
+ int ret = ov7670_read(sd, REG_CONTRAS, &v);
*value = v;
return ret;
}
-static int ov7670_q_hflip(struct i2c_client *client, __s32 *value)
+static int ov7670_g_hflip(struct v4l2_subdev *sd, __s32 *value)
{
int ret;
unsigned char v = 0;
- ret = ov7670_read(client, REG_MVFP, &v);
+ ret = ov7670_read(sd, REG_MVFP, &v);
*value = (v & MVFP_MIRROR) == MVFP_MIRROR;
return ret;
}
-static int ov7670_t_hflip(struct i2c_client *client, int value)
+static int ov7670_s_hflip(struct v4l2_subdev *sd, int value)
{
unsigned char v = 0;
int ret;
- ret = ov7670_read(client, REG_MVFP, &v);
+ ret = ov7670_read(sd, REG_MVFP, &v);
if (value)
v |= MVFP_MIRROR;
else
v &= ~MVFP_MIRROR;
msleep(10); /* FIXME */
- ret += ov7670_write(client, REG_MVFP, v);
+ ret += ov7670_write(sd, REG_MVFP, v);
return ret;
}
-static int ov7670_q_vflip(struct i2c_client *client, __s32 *value)
+static int ov7670_g_vflip(struct v4l2_subdev *sd, __s32 *value)
{
int ret;
unsigned char v = 0;
- ret = ov7670_read(client, REG_MVFP, &v);
+ ret = ov7670_read(sd, REG_MVFP, &v);
*value = (v & MVFP_FLIP) == MVFP_FLIP;
return ret;
}
-static int ov7670_t_vflip(struct i2c_client *client, int value)
+static int ov7670_s_vflip(struct v4l2_subdev *sd, int value)
{
unsigned char v = 0;
int ret;
- ret = ov7670_read(client, REG_MVFP, &v);
+ ret = ov7670_read(sd, REG_MVFP, &v);
if (value)
v |= MVFP_FLIP;
else
v &= ~MVFP_FLIP;
msleep(10); /* FIXME */
- ret += ov7670_write(client, REG_MVFP, v);
+ ret += ov7670_write(sd, REG_MVFP, v);
return ret;
}
-
-static struct ov7670_control {
- struct v4l2_queryctrl qc;
- int (*query)(struct i2c_client *c, __s32 *value);
- int (*tweak)(struct i2c_client *c, int value);
-} ov7670_controls[] =
+static int ov7670_queryctrl(struct v4l2_subdev *sd,
+ struct v4l2_queryctrl *qc)
{
- {
- .qc = {
- .id = V4L2_CID_BRIGHTNESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Brightness",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 0x80,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .tweak = ov7670_t_brightness,
- .query = ov7670_q_brightness,
- },
- {
- .qc = {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 127,
- .step = 1,
- .default_value = 0x40, /* XXX ov7670 spec */
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .tweak = ov7670_t_contrast,
- .query = ov7670_q_contrast,
- },
- {
- .qc = {
- .id = V4L2_CID_SATURATION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 256,
- .step = 1,
- .default_value = 0x80,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .tweak = ov7670_t_sat,
- .query = ov7670_q_sat,
- },
- {
- .qc = {
- .id = V4L2_CID_HUE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "HUE",
- .minimum = -180,
- .maximum = 180,
- .step = 5,
- .default_value = 0,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .tweak = ov7670_t_hue,
- .query = ov7670_q_hue,
- },
- {
- .qc = {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- .tweak = ov7670_t_vflip,
- .query = ov7670_q_vflip,
- },
- {
- .qc = {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Horizontal mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- .tweak = ov7670_t_hflip,
- .query = ov7670_q_hflip,
- },
-};
-#define N_CONTROLS (ARRAY_SIZE(ov7670_controls))
+ /* Fill in min, max, step and default value for these controls. */
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+ case V4L2_CID_CONTRAST:
+ return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
+ case V4L2_CID_VFLIP:
+ case V4L2_CID_HFLIP:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+ case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0, 256, 1, 128);
+ case V4L2_CID_HUE:
+ return v4l2_ctrl_query_fill(qc, -180, 180, 5, 0);
+ }
+ return -EINVAL;
+}
-static struct ov7670_control *ov7670_find_control(__u32 id)
+static int ov7670_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- int i;
-
- for (i = 0; i < N_CONTROLS; i++)
- if (ov7670_controls[i].qc.id == id)
- return ov7670_controls + i;
- return NULL;
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return ov7670_g_brightness(sd, &ctrl->value);
+ case V4L2_CID_CONTRAST:
+ return ov7670_g_contrast(sd, &ctrl->value);
+ case V4L2_CID_SATURATION:
+ return ov7670_g_sat(sd, &ctrl->value);
+ case V4L2_CID_HUE:
+ return ov7670_g_hue(sd, &ctrl->value);
+ case V4L2_CID_VFLIP:
+ return ov7670_g_vflip(sd, &ctrl->value);
+ case V4L2_CID_HFLIP:
+ return ov7670_g_hflip(sd, &ctrl->value);
+ }
+ return -EINVAL;
}
+static int ov7670_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return ov7670_s_brightness(sd, ctrl->value);
+ case V4L2_CID_CONTRAST:
+ return ov7670_s_contrast(sd, ctrl->value);
+ case V4L2_CID_SATURATION:
+ return ov7670_s_sat(sd, ctrl->value);
+ case V4L2_CID_HUE:
+ return ov7670_s_hue(sd, ctrl->value);
+ case V4L2_CID_VFLIP:
+ return ov7670_s_vflip(sd, ctrl->value);
+ case V4L2_CID_HFLIP:
+ return ov7670_s_hflip(sd, ctrl->value);
+ }
+ return -EINVAL;
+}
-static int ov7670_queryctrl(struct i2c_client *client,
- struct v4l2_queryctrl *qc)
+static int ov7670_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
{
- struct ov7670_control *ctrl = ov7670_find_control(qc->id);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (ctrl == NULL)
- return -EINVAL;
- *qc = ctrl->qc;
- return 0;
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV7670, 0);
}
-static int ov7670_g_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov7670_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct ov7670_control *octrl = ov7670_find_control(ctrl->id);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ unsigned char val = 0;
int ret;
- if (octrl == NULL)
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
return -EINVAL;
- ret = octrl->query(client, &ctrl->value);
- if (ret >= 0)
- return 0;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ ret = ov7670_read(sd, reg->reg & 0xff, &val);
+ reg->val = val;
+ reg->size = 1;
return ret;
}
-static int ov7670_s_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+static int ov7670_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct ov7670_control *octrl = ov7670_find_control(ctrl->id);
- int ret;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (octrl == NULL)
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
return -EINVAL;
- ret = octrl->tweak(client, ctrl->value);
- if (ret >= 0)
- return 0;
- return ret;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ ov7670_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ return 0;
}
+#endif
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops ov7670_core_ops = {
+ .g_chip_ident = ov7670_g_chip_ident,
+ .g_ctrl = ov7670_g_ctrl,
+ .s_ctrl = ov7670_s_ctrl,
+ .queryctrl = ov7670_queryctrl,
+ .reset = ov7670_reset,
+ .init = ov7670_init,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ov7670_g_register,
+ .s_register = ov7670_s_register,
+#endif
+};
+static const struct v4l2_subdev_video_ops ov7670_video_ops = {
+ .enum_fmt = ov7670_enum_fmt,
+ .try_fmt = ov7670_try_fmt,
+ .s_fmt = ov7670_s_fmt,
+ .s_parm = ov7670_s_parm,
+ .g_parm = ov7670_g_parm,
+};
+static const struct v4l2_subdev_ops ov7670_ops = {
+ .core = &ov7670_core_ops,
+ .video = &ov7670_video_ops,
+};
+/* ----------------------------------------------------------------------- */
-
-
-/*
- * Basic i2c stuff.
- */
-static struct i2c_driver ov7670_driver;
-
-static int ov7670_attach(struct i2c_adapter *adapter)
+static int ov7670_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- int ret;
- struct i2c_client *client;
+ struct v4l2_subdev *sd;
struct ov7670_info *info;
+ int ret;
- /*
- * For now: only deal with adapters we recognize.
- */
- if (adapter->id != I2C_HW_SMBUS_CAFE)
- return -ENODEV;
-
- client = kzalloc(sizeof (struct i2c_client), GFP_KERNEL);
- if (! client)
+ info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL);
+ if (info == NULL)
return -ENOMEM;
- client->adapter = adapter;
- client->addr = OV7670_I2C_ADDR;
- client->driver = &ov7670_driver,
- strcpy(client->name, "OV7670");
- /*
- * Set up our info structure.
- */
- info = kzalloc(sizeof (struct ov7670_info), GFP_KERNEL);
- if (! info) {
- ret = -ENOMEM;
- goto out_free;
+ sd = &info->sd;
+ v4l2_i2c_subdev_init(sd, client, &ov7670_ops);
+
+ /* Make sure it's an ov7670 */
+ ret = ov7670_detect(sd);
+ if (ret) {
+ v4l_dbg(1, debug, client,
+ "chip found @ 0x%x (%s) is not an ov7670 chip.\n",
+ client->addr << 1, client->adapter->name);
+ kfree(info);
+ return ret;
}
+ v4l_info(client, "chip found @ 0x%02x (%s)\n",
+ client->addr << 1, client->adapter->name);
+
info->fmt = &ov7670_formats[0];
info->sat = 128; /* Review this */
- i2c_set_clientdata(client, info);
- /*
- * Make sure it's an ov7670
- */
- ret = ov7670_detect(client);
- if (ret)
- goto out_free_info;
- ret = i2c_attach_client(client);
- if (ret)
- goto out_free_info;
return 0;
-
- out_free_info:
- kfree(info);
- out_free:
- kfree(client);
- return ret;
}
-static int ov7670_detach(struct i2c_client *client)
+static int ov7670_remove(struct i2c_client *client)
{
- i2c_detach_client(client);
- kfree(i2c_get_clientdata(client));
- kfree(client);
- return 0;
-}
-
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
-static int ov7670_command(struct i2c_client *client, unsigned int cmd,
- void *arg)
-{
- switch (cmd) {
- case VIDIOC_DBG_G_CHIP_IDENT:
- return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_OV7670, 0);
-
- case VIDIOC_INT_RESET:
- ov7670_reset(client);
- return 0;
-
- case VIDIOC_INT_INIT:
- return ov7670_init(client);
-
- case VIDIOC_ENUM_FMT:
- return ov7670_enum_fmt(client, (struct v4l2_fmtdesc *) arg);
- case VIDIOC_TRY_FMT:
- return ov7670_try_fmt(client, (struct v4l2_format *) arg, NULL, NULL);
- case VIDIOC_S_FMT:
- return ov7670_s_fmt(client, (struct v4l2_format *) arg);
- case VIDIOC_QUERYCTRL:
- return ov7670_queryctrl(client, (struct v4l2_queryctrl *) arg);
- case VIDIOC_S_CTRL:
- return ov7670_s_ctrl(client, (struct v4l2_control *) arg);
- case VIDIOC_G_CTRL:
- return ov7670_g_ctrl(client, (struct v4l2_control *) arg);
- case VIDIOC_S_PARM:
- return ov7670_s_parm(client, (struct v4l2_streamparm *) arg);
- case VIDIOC_G_PARM:
- return ov7670_g_parm(client, (struct v4l2_streamparm *) arg);
- }
- return -EINVAL;
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_state(sd));
+ return 0;
}
-
-
-static struct i2c_driver ov7670_driver = {
- .driver = {
- .name = "ov7670",
- },
- .id = I2C_DRIVERID_OV7670,
- .attach_adapter = ov7670_attach,
- .detach_client = ov7670_detach,
- .command = ov7670_command,
+static const struct i2c_device_id ov7670_id[] = {
+ { "ov7670", 0 },
+ { }
};
+MODULE_DEVICE_TABLE(i2c, ov7670_id);
-
-/*
- * Module initialization
- */
-static int __init ov7670_mod_init(void)
-{
- printk(KERN_NOTICE "OmniVision ov7670 sensor driver, at your service\n");
- return i2c_add_driver(&ov7670_driver);
-}
-
-static void __exit ov7670_mod_exit(void)
-{
- i2c_del_driver(&ov7670_driver);
-}
-
-module_init(ov7670_mod_init);
-module_exit(ov7670_mod_exit);
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "ov7670",
+ .probe = ov7670_probe,
+ .remove = ov7670_remove,
+ .id_table = ov7670_id,
+};
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 3c9e0ba974e9..84b0fc1bb237 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -217,10 +217,11 @@
#define OCAP_4x 0x03 /* 4x */
/* COM3 */
-#define SWAP_MASK 0x38
+#define SWAP_MASK (SWAP_RGB | SWAP_YUV | SWAP_ML)
+#define IMG_MASK (VFLIP_IMG | HFLIP_IMG)
-#define VFIMG_ON_OFF 0x80 /* Vertical flip image ON/OFF selection */
-#define HMIMG_ON_OFF 0x40 /* Horizontal mirror image ON/OFF selection */
+#define VFLIP_IMG 0x80 /* Vertical flip image ON/OFF selection */
+#define HFLIP_IMG 0x40 /* Horizontal mirror image ON/OFF selection */
#define SWAP_RGB 0x20 /* Swap B/R output sequence in RGB mode */
#define SWAP_YUV 0x10 /* Swap Y/UV output sequence in YUV mode */
#define SWAP_ML 0x08 /* Swap output MSB/LSB */
@@ -271,11 +272,13 @@
#define SLCT_QVGA 0x40 /* 1 : QVGA */
#define ITU656_ON_OFF 0x20 /* ITU656 protocol ON/OFF selection */
/* RGB output format control */
+#define FMT_MASK 0x0c /* Mask of color format */
#define FMT_GBR422 0x00 /* 00 : GBR 4:2:2 */
#define FMT_RGB565 0x04 /* 01 : RGB 565 */
#define FMT_RGB555 0x08 /* 10 : RGB 555 */
#define FMT_RGB444 0x0c /* 11 : RGB 444 */
/* Output format control */
+#define OFMT_MASK 0x03 /* Mask of output format */
#define OFMT_YUV 0x00 /* 00 : YUV */
#define OFMT_P_BRAW 0x01 /* 01 : Processed Bayer RAW */
#define OFMT_RGB 0x02 /* 10 : RGB */
@@ -299,7 +302,7 @@
#define GAIN_2x 0x00 /* 000 : 2x */
#define GAIN_4x 0x10 /* 001 : 4x */
#define GAIN_8x 0x20 /* 010 : 8x */
-#define GAIN_16x 0x30 /* 011 : 16x */
+#define GAIN_16x 0x30 /* 011 : 16x */
#define GAIN_32x 0x40 /* 100 : 32x */
#define GAIN_64x 0x50 /* 101 : 64x */
#define GAIN_128x 0x60 /* 110 : 128x */
@@ -356,13 +359,6 @@
#define VOSZ_QVGA 0x78
/*
- * bit configure (32 bit)
- * this is used in struct ov772x_color_format :: option
- */
-#define OP_UV 0x00000001
-#define OP_SWAP_RGB 0x00000002
-
-/*
* ID
*/
#define OV7720 0x7720
@@ -380,8 +376,9 @@ struct regval_list {
struct ov772x_color_format {
char *name;
__u32 fourcc;
- const struct regval_list *regs;
- unsigned int option;
+ u8 dsp3;
+ u8 com3;
+ u8 com7;
};
struct ov772x_win_size {
@@ -399,39 +396,13 @@ struct ov772x_priv {
const struct ov772x_color_format *fmt;
const struct ov772x_win_size *win;
int model;
+ unsigned int flag_vflip:1;
+ unsigned int flag_hflip:1;
};
#define ENDMARKER { 0xff, 0xff }
/*
- * register setting for color format
- */
-static const struct regval_list ov772x_RGB555_regs[] = {
- { COM3, 0x00 },
- { COM7, FMT_RGB555 | OFMT_RGB },
- ENDMARKER,
-};
-
-static const struct regval_list ov772x_RGB565_regs[] = {
- { COM3, 0x00 },
- { COM7, FMT_RGB565 | OFMT_RGB },
- ENDMARKER,
-};
-
-static const struct regval_list ov772x_YYUV_regs[] = {
- { COM3, SWAP_YUV },
- { COM7, OFMT_YUV },
- ENDMARKER,
-};
-
-static const struct regval_list ov772x_UVYY_regs[] = {
- { COM3, 0x00 },
- { COM7, OFMT_YUV },
- ENDMARKER,
-};
-
-
-/*
* register setting for window size
*/
static const struct regval_list ov772x_qvga_regs[] = {
@@ -500,38 +471,48 @@ static const struct soc_camera_data_format ov772x_fmt_lists[] = {
/*
* color format list
*/
-#define T_YUYV 0
static const struct ov772x_color_format ov772x_cfmts[] = {
- [T_YUYV] = {
+ {
SETFOURCC(YUYV),
- .regs = ov772x_YYUV_regs,
+ .dsp3 = 0x0,
+ .com3 = SWAP_YUV,
+ .com7 = OFMT_YUV,
},
{
SETFOURCC(YVYU),
- .regs = ov772x_YYUV_regs,
- .option = OP_UV,
+ .dsp3 = UV_ON,
+ .com3 = SWAP_YUV,
+ .com7 = OFMT_YUV,
},
{
SETFOURCC(UYVY),
- .regs = ov772x_UVYY_regs,
+ .dsp3 = 0x0,
+ .com3 = 0x0,
+ .com7 = OFMT_YUV,
},
{
SETFOURCC(RGB555),
- .regs = ov772x_RGB555_regs,
- .option = OP_SWAP_RGB,
+ .dsp3 = 0x0,
+ .com3 = SWAP_RGB,
+ .com7 = FMT_RGB555 | OFMT_RGB,
},
{
SETFOURCC(RGB555X),
- .regs = ov772x_RGB555_regs,
+ .dsp3 = 0x0,
+ .com3 = 0x0,
+ .com7 = FMT_RGB555 | OFMT_RGB,
},
{
SETFOURCC(RGB565),
- .regs = ov772x_RGB565_regs,
- .option = OP_SWAP_RGB,
+ .dsp3 = 0x0,
+ .com3 = SWAP_RGB,
+ .com7 = FMT_RGB565 | OFMT_RGB,
},
{
SETFOURCC(RGB565X),
- .regs = ov772x_RGB565_regs,
+ .dsp3 = 0x0,
+ .com3 = 0x0,
+ .com7 = FMT_RGB565 | OFMT_RGB,
},
};
@@ -562,6 +543,27 @@ static const struct ov772x_win_size ov772x_win_qvga = {
.regs = ov772x_qvga_regs,
};
+static const struct v4l2_queryctrl ov772x_controls[] = {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Flip Vertically",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Flip Horizontally",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+};
+
/*
* general function
@@ -587,8 +589,11 @@ static int ov772x_mask_set(struct i2c_client *client,
u8 set)
{
s32 val = i2c_smbus_read_byte_data(client, command);
+ if (val < 0)
+ return val;
+
val &= ~mask;
- val |= set;
+ val |= set & mask;
return i2c_smbus_write_byte_data(client, command, val);
}
@@ -635,74 +640,24 @@ static int ov772x_release(struct soc_camera_device *icd)
static int ov772x_start_capture(struct soc_camera_device *icd)
{
struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
- int ret;
-
- if (!priv->win)
- priv->win = &ov772x_win_vga;
- if (!priv->fmt)
- priv->fmt = &ov772x_cfmts[T_YUYV];
-
- /*
- * reset hardware
- */
- ov772x_reset(priv->client);
- /*
- * set color format
- */
- ret = ov772x_write_array(priv->client, priv->fmt->regs);
- if (ret < 0)
- goto start_end;
-
- /*
- * set size format
- */
- ret = ov772x_write_array(priv->client, priv->win->regs);
- if (ret < 0)
- goto start_end;
-
- /*
- * set COM7 bit ( QVGA or VGA )
- */
- ret = ov772x_mask_set(priv->client,
- COM7, SLCT_MASK, priv->win->com7_bit);
- if (ret < 0)
- goto start_end;
-
- /*
- * set UV setting
- */
- if (priv->fmt->option & OP_UV) {
- ret = ov772x_mask_set(priv->client,
- DSP_CTRL3, UV_MASK, UV_ON);
- if (ret < 0)
- goto start_end;
+ if (!priv->win || !priv->fmt) {
+ dev_err(&icd->dev, "norm or win select error\n");
+ return -EPERM;
}
- /*
- * set SWAP setting
- */
- if (priv->fmt->option & OP_SWAP_RGB) {
- ret = ov772x_mask_set(priv->client,
- COM3, SWAP_MASK, SWAP_RGB);
- if (ret < 0)
- goto start_end;
- }
+ ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, 0);
dev_dbg(&icd->dev,
"format %s, win %s\n", priv->fmt->name, priv->win->name);
-start_end:
- priv->fmt = NULL;
- priv->win = NULL;
-
- return ret;
+ return 0;
}
static int ov772x_stop_capture(struct soc_camera_device *icd)
{
struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
- ov772x_reset(priv->client);
+ ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
return 0;
}
@@ -718,11 +673,54 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
struct soc_camera_link *icl = priv->client->dev.platform_data;
unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
- priv->info->buswidth;
+ SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
return soc_camera_apply_sensor_flags(icl, flags);
}
+static int ov772x_get_control(struct soc_camera_device *icd,
+ struct v4l2_control *ctrl)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+
+ switch (ctrl->id) {
+ case V4L2_CID_VFLIP:
+ ctrl->value = priv->flag_vflip;
+ break;
+ case V4L2_CID_HFLIP:
+ ctrl->value = priv->flag_hflip;
+ break;
+ }
+ return 0;
+}
+
+static int ov772x_set_control(struct soc_camera_device *icd,
+ struct v4l2_control *ctrl)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+ int ret = 0;
+ u8 val;
+
+ switch (ctrl->id) {
+ case V4L2_CID_VFLIP:
+ val = ctrl->value ? VFLIP_IMG : 0x00;
+ priv->flag_vflip = ctrl->value;
+ if (priv->info->flags & OV772X_FLAG_VFLIP)
+ val ^= VFLIP_IMG;
+ ret = ov772x_mask_set(priv->client, COM3, VFLIP_IMG, val);
+ break;
+ case V4L2_CID_HFLIP:
+ val = ctrl->value ? HFLIP_IMG : 0x00;
+ priv->flag_hflip = ctrl->value;
+ if (priv->info->flags & OV772X_FLAG_HFLIP)
+ val ^= HFLIP_IMG;
+ ret = ov772x_mask_set(priv->client, COM3, HFLIP_IMG, val);
+ break;
+ }
+
+ return ret;
+}
+
static int ov772x_get_chip_id(struct soc_camera_device *icd,
struct v4l2_dbg_chip_ident *id)
{
@@ -787,13 +785,11 @@ ov772x_select_win(u32 width, u32 height)
return win;
}
-
-static int ov772x_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt,
- struct v4l2_rect *rect)
+static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
+ u32 pixfmt)
{
- struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
int ret = -EINVAL;
+ u8 val;
int i;
/*
@@ -803,19 +799,101 @@ static int ov772x_set_fmt(struct soc_camera_device *icd,
for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
if (pixfmt == ov772x_cfmts[i].fourcc) {
priv->fmt = ov772x_cfmts + i;
- ret = 0;
break;
}
}
+ if (!priv->fmt)
+ goto ov772x_set_fmt_error;
/*
* select win
*/
- priv->win = ov772x_select_win(rect->width, rect->height);
+ priv->win = ov772x_select_win(width, height);
+
+ /*
+ * reset hardware
+ */
+ ov772x_reset(priv->client);
+
+ /*
+ * set size format
+ */
+ ret = ov772x_write_array(priv->client, priv->win->regs);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ /*
+ * set DSP_CTRL3
+ */
+ val = priv->fmt->dsp3;
+ if (val) {
+ ret = ov772x_mask_set(priv->client,
+ DSP_CTRL3, UV_MASK, val);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+ }
+
+ /*
+ * set COM3
+ */
+ val = priv->fmt->com3;
+ if (priv->info->flags & OV772X_FLAG_VFLIP)
+ val |= VFLIP_IMG;
+ if (priv->info->flags & OV772X_FLAG_HFLIP)
+ val |= HFLIP_IMG;
+ if (priv->flag_vflip)
+ val ^= VFLIP_IMG;
+ if (priv->flag_hflip)
+ val ^= HFLIP_IMG;
+
+ ret = ov772x_mask_set(priv->client,
+ COM3, SWAP_MASK | IMG_MASK, val);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ /*
+ * set COM7
+ */
+ val = priv->win->com7_bit | priv->fmt->com7;
+ ret = ov772x_mask_set(priv->client,
+ COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK),
+ val);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ return ret;
+
+ov772x_set_fmt_error:
+
+ ov772x_reset(priv->client);
+ priv->win = NULL;
+ priv->fmt = NULL;
return ret;
}
+static int ov772x_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+
+ if (!priv->fmt)
+ return -EINVAL;
+
+ return ov772x_set_params(priv, rect->width, rect->height,
+ priv->fmt->fourcc);
+}
+
+static int ov772x_set_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+
+ return ov772x_set_params(priv, pix->width, pix->height,
+ pix->pixelformat);
+}
+
static int ov772x_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
@@ -889,7 +967,6 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
i2c_smbus_read_byte_data(priv->client, MIDH),
i2c_smbus_read_byte_data(priv->client, MIDL));
-
return soc_camera_video_start(icd);
}
@@ -906,10 +983,15 @@ static struct soc_camera_ops ov772x_ops = {
.release = ov772x_release,
.start_capture = ov772x_start_capture,
.stop_capture = ov772x_stop_capture,
+ .set_crop = ov772x_set_crop,
.set_fmt = ov772x_set_fmt,
.try_fmt = ov772x_try_fmt,
.set_bus_param = ov772x_set_bus_param,
.query_bus_param = ov772x_query_bus_param,
+ .controls = ov772x_controls,
+ .num_controls = ARRAY_SIZE(ov772x_controls),
+ .get_control = ov772x_get_control,
+ .set_control = ov772x_set_control,
.get_chip_id = ov772x_get_chip_id,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.get_register = ov772x_get_register,
diff --git a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c
index c841f4e4fbe4..d573d8428998 100644
--- a/drivers/media/video/ovcamchip/ovcamchip_core.c
+++ b/drivers/media/video/ovcamchip/ovcamchip_core.c
@@ -15,6 +15,9 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-i2c-drv.h>
#include "ovcamchip_priv.h"
#define DRIVER_VERSION "v2.27 for Linux 2.6"
@@ -44,6 +47,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
+
/* Registers common to all chips, that are needed for detection */
#define GENERIC_REG_ID_HIGH 0x1C /* manufacturer ID MSB */
#define GENERIC_REG_ID_LOW 0x1D /* manufacturer ID LSB */
@@ -61,10 +65,6 @@ static char *chip_names[NUM_CC_TYPES] = {
[CC_OV6630AF] = "OV6630AF",
};
-/* Forward declarations */
-static struct i2c_driver driver;
-static struct i2c_client client_template;
-
/* ----------------------------------------------------------------------- */
int ov_write_regvals(struct i2c_client *c, struct ovcamchip_regvals *rvals)
@@ -253,112 +253,36 @@ static int ovcamchip_detect(struct i2c_client *c)
/* Test for 7xx0 */
PDEBUG(3, "Testing for 0V7xx0");
- c->addr = OV7xx0_SID;
- if (init_camchip(c) < 0) {
- /* Test for 6xx0 */
- PDEBUG(3, "Testing for 0V6xx0");
- c->addr = OV6xx0_SID;
- if (init_camchip(c) < 0) {
- return -ENODEV;
- } else {
- if (ov6xx0_detect(c) < 0) {
- PERROR("Failed to init OV6xx0");
- return -EIO;
- }
- }
- } else {
+ if (init_camchip(c) < 0)
+ return -ENODEV;
+ /* 7-bit addresses with bit 0 set are for the OV7xx0 */
+ if (c->addr & 1) {
if (ov7xx0_detect(c) < 0) {
PERROR("Failed to init OV7xx0");
return -EIO;
}
+ return 0;
+ }
+ /* Test for 6xx0 */
+ PDEBUG(3, "Testing for 0V6xx0");
+ if (ov6xx0_detect(c) < 0) {
+ PERROR("Failed to init OV6xx0");
+ return -EIO;
}
-
return 0;
}
/* ----------------------------------------------------------------------- */
-static int ovcamchip_attach(struct i2c_adapter *adap)
+static long ovcamchip_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
- int rc = 0;
- struct ovcamchip *ov;
- struct i2c_client *c;
-
- /* I2C is not a PnP bus, so we can never be certain that we're talking
- * to the right chip. To prevent damage to EEPROMS and such, only
- * attach to adapters that are known to contain OV camera chips. */
-
- switch (adap->id) {
- case I2C_HW_SMBUS_OV511:
- case I2C_HW_SMBUS_OV518:
- case I2C_HW_SMBUS_W9968CF:
- PDEBUG(1, "Adapter ID 0x%06x accepted", adap->id);
- break;
- default:
- PDEBUG(1, "Adapter ID 0x%06x rejected", adap->id);
- return -ENODEV;
- }
-
- c = kmalloc(sizeof *c, GFP_KERNEL);
- if (!c) {
- rc = -ENOMEM;
- goto no_client;
- }
- memcpy(c, &client_template, sizeof *c);
- c->adapter = adap;
- strcpy(c->name, "OV????");
-
- ov = kzalloc(sizeof *ov, GFP_KERNEL);
- if (!ov) {
- rc = -ENOMEM;
- goto no_ov;
- }
- i2c_set_clientdata(c, ov);
-
- rc = ovcamchip_detect(c);
- if (rc < 0)
- goto error;
-
- strcpy(c->name, chip_names[ov->subtype]);
-
- PDEBUG(1, "Camera chip detection complete");
-
- i2c_attach_client(c);
-
- return rc;
-error:
- kfree(ov);
-no_ov:
- kfree(c);
-no_client:
- PDEBUG(1, "returning %d", rc);
- return rc;
-}
-
-static int ovcamchip_detach(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- int rc;
-
- rc = ov->sops->free(c);
- if (rc < 0)
- return rc;
-
- i2c_detach_client(c);
-
- kfree(ov);
- kfree(c);
- return 0;
-}
-
-static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
+ struct ovcamchip *ov = to_ovcamchip(sd);
+ struct i2c_client *c = v4l2_get_subdevdata(sd);
if (!ov->initialized &&
cmd != OVCAMCHIP_CMD_Q_SUBTYPE &&
cmd != OVCAMCHIP_CMD_INITIALIZE) {
- dev_err(&c->dev, "ERROR: Camera chip not initialized yet!\n");
+ v4l2_err(sd, "Camera chip not initialized yet!\n");
return -EPERM;
}
@@ -379,10 +303,10 @@ static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg)
if (ov->mono) {
if (ov->subtype != CC_OV7620)
- dev_warn(&c->dev, "Warning: Monochrome not "
+ v4l2_warn(sd, "Monochrome not "
"implemented for this chip\n");
else
- dev_info(&c->dev, "Initializing chip as "
+ v4l2_info(sd, "Initializing chip as "
"monochrome\n");
}
@@ -400,35 +324,72 @@ static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg)
/* ----------------------------------------------------------------------- */
-static struct i2c_driver driver = {
- .driver = {
- .name = "ovcamchip",
- },
- .id = I2C_DRIVERID_OVCAMCHIP,
- .attach_adapter = ovcamchip_attach,
- .detach_client = ovcamchip_detach,
- .command = ovcamchip_command,
+static const struct v4l2_subdev_core_ops ovcamchip_core_ops = {
+ .ioctl = ovcamchip_ioctl,
};
-static struct i2c_client client_template = {
- .name = "(unset)",
- .driver = &driver,
+static const struct v4l2_subdev_ops ovcamchip_ops = {
+ .core = &ovcamchip_core_ops,
};
-static int __init ovcamchip_init(void)
+static int ovcamchip_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
-#ifdef DEBUG
- ovcamchip_debug = debug;
-#endif
+ struct ovcamchip *ov;
+ struct v4l2_subdev *sd;
+ int rc = 0;
+
+ ov = kzalloc(sizeof *ov, GFP_KERNEL);
+ if (!ov) {
+ rc = -ENOMEM;
+ goto no_ov;
+ }
+ sd = &ov->sd;
+ v4l2_i2c_subdev_init(sd, client, &ovcamchip_ops);
+
+ rc = ovcamchip_detect(client);
+ if (rc < 0)
+ goto error;
+
+ v4l_info(client, "%s found @ 0x%02x (%s)\n",
+ chip_names[ov->subtype], client->addr << 1, client->adapter->name);
+
+ PDEBUG(1, "Camera chip detection complete");
- PINFO(DRIVER_VERSION " : " DRIVER_DESC);
- return i2c_add_driver(&driver);
+ return rc;
+error:
+ kfree(ov);
+no_ov:
+ PDEBUG(1, "returning %d", rc);
+ return rc;
}
-static void __exit ovcamchip_exit(void)
+static int ovcamchip_remove(struct i2c_client *client)
{
- i2c_del_driver(&driver);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ovcamchip *ov = to_ovcamchip(sd);
+ int rc;
+
+ v4l2_device_unregister_subdev(sd);
+ rc = ov->sops->free(client);
+ if (rc < 0)
+ return rc;
+
+ kfree(ov);
+ return 0;
}
-module_init(ovcamchip_init);
-module_exit(ovcamchip_exit);
+/* ----------------------------------------------------------------------- */
+
+static const struct i2c_device_id ovcamchip_id[] = {
+ { "ovcamchip", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ovcamchip_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "ovcamchip",
+ .probe = ovcamchip_probe,
+ .remove = ovcamchip_remove,
+ .id_table = ovcamchip_id,
+};
diff --git a/drivers/media/video/ovcamchip/ovcamchip_priv.h b/drivers/media/video/ovcamchip/ovcamchip_priv.h
index a05650faedda..4f07b78c88bc 100644
--- a/drivers/media/video/ovcamchip/ovcamchip_priv.h
+++ b/drivers/media/video/ovcamchip/ovcamchip_priv.h
@@ -16,6 +16,7 @@
#define __LINUX_OVCAMCHIP_PRIV_H
#include <linux/i2c.h>
+#include <media/v4l2-subdev.h>
#include <media/ovcamchip.h>
#ifdef DEBUG
@@ -46,6 +47,7 @@ struct ovcamchip_ops {
};
struct ovcamchip {
+ struct v4l2_subdev sd;
struct ovcamchip_ops *sops;
void *spriv; /* Private data for OV7x10.c etc... */
int subtype; /* = SEN_OV7610 etc... */
@@ -53,6 +55,11 @@ struct ovcamchip {
int initialized; /* OVCAMCHIP_CMD_INITIALIZE was successful */
};
+static inline struct ovcamchip *to_ovcamchip(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct ovcamchip, sd);
+}
+
extern struct ovcamchip_ops ov6x20_ops;
extern struct ovcamchip_ops ov6x30_ops;
extern struct ovcamchip_ops ov7x10_ops;
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
index 854c2a885358..f9b6001e1dd7 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -40,10 +40,10 @@ config VIDEO_PVRUSB2_DVB
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_S5H1409 if !DVB_FE_CUSTOMISE
select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select DVB_TDA10048 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
+ select DVB_TDA10048 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
---help---
This option enables a DVB interface for the pvrusb2 driver.
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile
index 4fda2de69ab7..de2fc14f043b 100644
--- a/drivers/media/video/pvrusb2/Makefile
+++ b/drivers/media/video/pvrusb2/Makefile
@@ -2,14 +2,15 @@ obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o
obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o
obj-pvrusb2-dvb-$(CONFIG_VIDEO_PVRUSB2_DVB) := pvrusb2-dvb.o
-pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
- pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \
+pvrusb2-objs := pvrusb2-i2c-core.o \
+ pvrusb2-audio.o \
pvrusb2-encoder.o pvrusb2-video-v4l.o \
- pvrusb2-eeprom.o pvrusb2-tuner.o \
+ pvrusb2-eeprom.o \
pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \
pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \
pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \
pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \
+ pvrusb2-cs53l32a.o \
$(obj-pvrusb2-dvb-y) \
$(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y)
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index cdedaa55f152..ccf2a3c7ad06 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -26,14 +26,6 @@
#include <media/msp3400.h>
#include <media/v4l2-common.h>
-struct pvr2_msp3400_handler {
- struct pvr2_hdw *hdw;
- struct pvr2_i2c_client *client;
- struct pvr2_i2c_handler i2c_handler;
- unsigned long stale_mask;
-};
-
-
struct routing_scheme {
const int *def;
@@ -63,123 +55,33 @@ static const struct routing_scheme routing_schemes[] = {
},
};
-/* This function selects the correct audio input source */
-static void set_stereo(struct pvr2_msp3400_handler *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- struct v4l2_routing route;
- const struct routing_scheme *sp;
- unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c msp3400 v4l2 set_stereo");
-
- if ((sid < ARRAY_SIZE(routing_schemes)) &&
- ((sp = routing_schemes + sid) != NULL) &&
- (hdw->input_val >= 0) &&
- (hdw->input_val < sp->cnt)) {
- route.input = sp->def[hdw->input_val];
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "*** WARNING *** i2c msp3400 v4l2 set_stereo:"
- " Invalid routing scheme (%u) and/or input (%d)",
- sid,hdw->input_val);
- return;
- }
- route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
-}
-
-
-static int check_stereo(struct pvr2_msp3400_handler *ctxt)
+void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->input_dirty;
-}
-
-
-struct pvr2_msp3400_ops {
- void (*update)(struct pvr2_msp3400_handler *);
- int (*check)(struct pvr2_msp3400_handler *);
-};
-
-
-static const struct pvr2_msp3400_ops msp3400_ops[] = {
- { .update = set_stereo, .check = check_stereo},
-};
-
-
-static int msp3400_check(struct pvr2_msp3400_handler *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(msp3400_ops); idx++) {
- msk = 1 << idx;
- if (ctxt->stale_mask & msk) continue;
- if (msp3400_ops[idx].check(ctxt)) {
- ctxt->stale_mask |= msk;
+ if (hdw->input_dirty || hdw->force_dirty) {
+ struct v4l2_routing route;
+ const struct routing_scheme *sp;
+ unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo");
+
+ if ((sid < ARRAY_SIZE(routing_schemes)) &&
+ ((sp = routing_schemes + sid) != NULL) &&
+ (hdw->input_val >= 0) &&
+ (hdw->input_val < sp->cnt)) {
+ route.input = sp->def[hdw->input_val];
+ } else {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "*** WARNING *** subdev msp3400 set_input:"
+ " Invalid routing scheme (%u)"
+ " and/or input (%d)",
+ sid, hdw->input_val);
+ return;
}
+ route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
+ sd->ops->audio->s_routing(sd, &route);
}
- return ctxt->stale_mask != 0;
}
-
-static void msp3400_update(struct pvr2_msp3400_handler *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(msp3400_ops); idx++) {
- msk = 1 << idx;
- if (!(ctxt->stale_mask & msk)) continue;
- ctxt->stale_mask &= ~msk;
- msp3400_ops[idx].update(ctxt);
- }
-}
-
-
-static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt)
-{
- ctxt->client->handler = NULL;
- kfree(ctxt);
-}
-
-
-static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler *ctxt,
- char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-audio v4l2");
-}
-
-
-static const struct pvr2_i2c_handler_functions msp3400_funcs = {
- .detach = (void (*)(void *))pvr2_msp3400_detach,
- .check = (int (*)(void *))msp3400_check,
- .update = (void (*)(void *))msp3400_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_msp3400_describe,
-};
-
-
-int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
- struct pvr2_msp3400_handler *ctxt;
- if (cp->handler) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->i2c_handler.func_data = ctxt;
- ctxt->i2c_handler.func_table = &msp3400_funcs;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- ctxt->stale_mask = (1 << ARRAY_SIZE(msp3400_ops)) - 1;
- cp->handler = &ctxt->i2c_handler;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up",
- cp->client->addr);
- return !0;
-}
-
-
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
*** Local Variables: ***
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.h b/drivers/media/video/pvrusb2/pvrusb2-audio.h
index ac54eed3721b..e3e63d750891 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.h
@@ -22,10 +22,8 @@
#ifndef __PVRUSB2_AUDIO_H
#define __PVRUSB2_AUDIO_H
-#include "pvrusb2-i2c-core.h"
-
-int pvr2_i2c_msp3400_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
-
+#include "pvrusb2-hdw-internal.h"
+void pvr2_msp3400_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
#endif /* __PVRUSB2_AUDIO_H */
/*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
new file mode 100644
index 000000000000..b5c3428ebb9f
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
@@ -0,0 +1,95 @@
+/*
+ *
+ *
+ * Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/*
+
+ This source file is specifically designed to interface with the
+ v4l-dvb cs53l32a module.
+
+*/
+
+#include "pvrusb2-cs53l32a.h"
+
+
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-debug.h"
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+struct routing_scheme {
+ const int *def;
+ unsigned int cnt;
+};
+
+
+static const int routing_scheme1[] = {
+ [PVR2_CVAL_INPUT_TV] = 2, /* 1 or 2 seems to work here */
+ [PVR2_CVAL_INPUT_RADIO] = 2,
+ [PVR2_CVAL_INPUT_COMPOSITE] = 0,
+ [PVR2_CVAL_INPUT_SVIDEO] = 0,
+};
+
+static const struct routing_scheme routing_schemes[] = {
+ [PVR2_ROUTING_SCHEME_ONAIR] = {
+ .def = routing_scheme1,
+ .cnt = ARRAY_SIZE(routing_scheme1),
+ },
+};
+
+
+void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
+{
+ if (hdw->input_dirty || hdw->force_dirty) {
+ struct v4l2_routing route;
+ const struct routing_scheme *sp;
+ unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
+ hdw->input_val);
+ if ((sid < ARRAY_SIZE(routing_schemes)) &&
+ ((sp = routing_schemes + sid) != NULL) &&
+ (hdw->input_val >= 0) &&
+ (hdw->input_val < sp->cnt)) {
+ route.input = sp->def[hdw->input_val];
+ } else {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "*** WARNING *** subdev v4l2 set_input:"
+ " Invalid routing scheme (%u)"
+ " and/or input (%d)",
+ sid, hdw->input_val);
+ return;
+ }
+ route.output = 0;
+ sd->ops->audio->s_routing(sd, &route);
+ }
+}
+
+
+/*
+ Stuff for Emacs to see, in order to encourage consistent editing style:
+ *** Local Variables: ***
+ *** mode: c ***
+ *** fill-column: 70 ***
+ *** tab-width: 8 ***
+ *** c-basic-offset: 8 ***
+ *** End: ***
+ */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.h b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h
index ef4afaf37b0a..53ba548b72a7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-tuner.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h
@@ -2,6 +2,7 @@
*
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,14 +18,24 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#ifndef __PVRUSB2_TUNER_H
-#define __PVRUSB2_TUNER_H
-#include "pvrusb2-i2c-core.h"
+#ifndef __PVRUSB2_CS53L32A_H
+#define __PVRUSB2_CS53L32A_H
-int pvr2_i2c_tuner_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
+/*
+
+ This module connects the pvrusb2 driver to the I2C chip level
+ driver which handles device video processing. This interface is
+ used internally by the driver; higher level code should only
+ interact through the interface provided by pvrusb2-hdw.h.
+
+*/
+
+
+#include "pvrusb2-hdw-internal.h"
+void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
-#endif /* __PVRUSB2_TUNER_H */
+#endif /* __PVRUSB2_AUDIO_CS53L32A_H */
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 895859ec495a..4e017ff26c36 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -28,7 +28,6 @@
#include "pvrusb2-cx2584x-v4l.h"
#include "pvrusb2-video-v4l.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
#include "pvrusb2-hdw-internal.h"
@@ -39,14 +38,6 @@
#include <linux/errno.h>
#include <linux/slab.h>
-struct pvr2_v4l_cx2584x {
- struct pvr2_i2c_handler handler;
- struct pvr2_decoder_ctrl ctrl;
- struct pvr2_i2c_client *client;
- struct pvr2_hdw *hdw;
- unsigned long stale_mask;
-};
-
struct routing_scheme_item {
int vid;
@@ -110,218 +101,44 @@ static const struct routing_scheme routing_schemes[] = {
},
};
-static void set_input(struct pvr2_v4l_cx2584x *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- struct v4l2_routing route;
- enum cx25840_video_input vid_input;
- enum cx25840_audio_input aud_input;
- const struct routing_scheme *sp;
- unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
-
- memset(&route,0,sizeof(route));
-
- if ((sid < ARRAY_SIZE(routing_schemes)) &&
- ((sp = routing_schemes + sid) != NULL) &&
- (hdw->input_val >= 0) &&
- (hdw->input_val < sp->cnt)) {
- vid_input = sp->def[hdw->input_val].vid;
- aud_input = sp->def[hdw->input_val].aud;
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "*** WARNING *** i2c cx2584x set_input:"
- " Invalid routing scheme (%u) and/or input (%d)",
- sid,hdw->input_val);
- return;
- }
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x",
- vid_input,aud_input);
- route.input = (u32)vid_input;
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
- route.input = (u32)aud_input;
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
-}
-
-
-static int check_input(struct pvr2_v4l_cx2584x *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->input_dirty != 0;
-}
-
-
-static void set_audio(struct pvr2_v4l_cx2584x *ctxt)
-{
- u32 val;
- struct pvr2_hdw *hdw = ctxt->hdw;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_audio %d",
- hdw->srate_val);
- switch (hdw->srate_val) {
- default:
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
- val = 48000;
- break;
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
- val = 44100;
- break;
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
- val = 32000;
- break;
- }
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
-}
-
-
-static int check_audio(struct pvr2_v4l_cx2584x *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->srate_dirty != 0;
-}
-
-
-struct pvr2_v4l_cx2584x_ops {
- void (*update)(struct pvr2_v4l_cx2584x *);
- int (*check)(struct pvr2_v4l_cx2584x *);
-};
-
-
-static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = {
- { .update = set_input, .check = check_input},
- { .update = set_audio, .check = check_audio},
-};
-
-
-static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt)
+void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
- ctxt->client->handler = NULL;
- pvr2_hdw_set_decoder(ctxt->hdw,NULL);
- kfree(ctxt);
-}
-
-
-static int decoder_check(struct pvr2_v4l_cx2584x *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
- msk = 1 << idx;
- if (ctxt->stale_mask & msk) continue;
- if (decoder_ops[idx].check(ctxt)) {
- ctxt->stale_mask |= msk;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update...");
+ if (hdw->input_dirty || hdw->force_dirty) {
+ struct v4l2_routing route;
+ enum cx25840_video_input vid_input;
+ enum cx25840_audio_input aud_input;
+ const struct routing_scheme *sp;
+ unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+
+ memset(&route, 0, sizeof(route));
+
+ if ((sid < ARRAY_SIZE(routing_schemes)) &&
+ ((sp = routing_schemes + sid) != NULL) &&
+ (hdw->input_val >= 0) &&
+ (hdw->input_val < sp->cnt)) {
+ vid_input = sp->def[hdw->input_val].vid;
+ aud_input = sp->def[hdw->input_val].aud;
+ } else {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "*** WARNING *** subdev cx2584x set_input:"
+ " Invalid routing scheme (%u)"
+ " and/or input (%d)",
+ sid, hdw->input_val);
+ return;
}
- }
- return ctxt->stale_mask != 0;
-}
-
-static void decoder_update(struct pvr2_v4l_cx2584x *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
- msk = 1 << idx;
- if (!(ctxt->stale_mask & msk)) continue;
- ctxt->stale_mask &= ~msk;
- decoder_ops[idx].update(ctxt);
+ pvr2_trace(PVR2_TRACE_CHIPS,
+ "subdev cx2584x set_input vid=0x%x aud=0x%x",
+ vid_input, aud_input);
+ route.input = (u32)vid_input;
+ sd->ops->video->s_routing(sd, &route);
+ route.input = (u32)aud_input;
+ sd->ops->audio->s_routing(sd, &route);
}
}
-static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl)
-{
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl);
- pvr2_v4l2_cmd_stream(ctxt->client,fl);
-}
-
-
-static int decoder_detect(struct pvr2_i2c_client *cp)
-{
- int ret;
- /* Attempt to query the decoder - let's see if it will answer */
- struct v4l2_queryctrl qc;
-
- memset(&qc,0,sizeof(qc));
-
- qc.id = V4L2_CID_BRIGHTNESS;
-
- ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc);
- return ret == 0; /* Return true if it answered */
-}
-
-
-static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt,
- char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l");
-}
-
-
-static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt)
-{
- int ret;
- ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL);
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret);
-}
-
-
-static const struct pvr2_i2c_handler_functions hfuncs = {
- .detach = (void (*)(void *))decoder_detach,
- .check = (int (*)(void *))decoder_check,
- .update = (void (*)(void *))decoder_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
-};
-
-
-int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw,
- struct pvr2_i2c_client *cp)
-{
- struct pvr2_v4l_cx2584x *ctxt;
-
- if (hdw->decoder_ctrl) return 0;
- if (cp->handler) return 0;
- if (!decoder_detect(cp)) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->handler.func_data = ctxt;
- ctxt->handler.func_table = &hfuncs;
- ctxt->ctrl.ctxt = ctxt;
- ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
- ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
- ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1;
- pvr2_hdw_set_decoder(hdw,&ctxt->ctrl);
- cp->handler = &ctxt->handler;
- {
- /*
- Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit
- of nuttiness for cx25840 causes that module to
- correctly set up its video scaling. This is really
- a problem in the cx25840 module itself, but we work
- around it here. The problem has not been seen in
- ivtv because there VBI is supported and set up. We
- don't do VBI here (at least not yet) and thus we
- never attempted to even set it up.
- */
- struct v4l2_format fmt;
- memset(&fmt,0,sizeof(fmt));
- fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_FMT,&fmt);
- }
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up",
- cp->client->addr);
- return !0;
-}
-
-
-
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
index 66abf77f51fd..e35c2322a08c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
@@ -34,9 +34,9 @@
-#include "pvrusb2-i2c-core.h"
+#include "pvrusb2-hdw-internal.h"
-int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
+void pvr2_cx25840_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);
#endif /* __PVRUSB2_CX2584X_V4L_H */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
index ca892fb78a5b..fbe3856bdca6 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
@@ -23,7 +23,6 @@
#include "pvrusb2-debugifc.h"
#include "pvrusb2-hdw.h"
#include "pvrusb2-debug.h"
-#include "pvrusb2-i2c-core.h"
struct debugifc_mask_item {
const char *name;
@@ -147,10 +146,6 @@ int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt)
bcnt += ccnt; acnt -= ccnt; buf += ccnt;
ccnt = pvr2_hdw_state_report(hdw,buf,acnt);
bcnt += ccnt; acnt -= ccnt; buf += ccnt;
- ccnt = scnprintf(buf,acnt,"Attached I2C modules:\n");
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
- ccnt = pvr2_i2c_report(hdw,buf,acnt);
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
return bcnt;
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
index e24ff59f8605..2f8d46761cd0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
@@ -22,16 +22,16 @@
struct pvr2_hdw;
-/* Non-intrusively print some useful debugging info from inside the
- driver. This should work even if the driver appears to be
- wedged. */
-int pvr2_debugifc_print_info(struct pvr2_hdw *,
- char *buf_ptr,unsigned int buf_size);
-
/* Print general status of driver. This will also trigger a probe of
the USB link. Unlike print_info(), this one synchronizes with the
driver so the information should be self-consistent (but it will
hang if the driver is wedged). */
+int pvr2_debugifc_print_info(struct pvr2_hdw *,
+ char *buf_ptr, unsigned int buf_size);
+
+/* Non-intrusively print some useful debugging info from inside the
+ driver. This should work even if the driver appears to be
+ wedged. */
int pvr2_debugifc_print_status(struct pvr2_hdw *,
char *buf_ptr,unsigned int buf_size);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index cbe2a3417851..1cb6a260e8b0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -46,10 +46,11 @@ pvr2_device_desc structures.
/*------------------------------------------------------------------------*/
/* Hauppauge PVR-USB2 Model 29xxx */
-static const char *pvr2_client_29xxx[] = {
- "msp3400",
- "saa7115",
- "tuner",
+static const struct pvr2_device_client_desc pvr2_cli_29xxx[] = {
+ { .module_id = PVR2_CLIENT_ID_SAA7115 },
+ { .module_id = PVR2_CLIENT_ID_MSP3400 },
+ { .module_id = PVR2_CLIENT_ID_TUNER },
+ { .module_id = PVR2_CLIENT_ID_DEMOD },
};
static const char *pvr2_fw1_names_29xxx[] = {
@@ -59,8 +60,8 @@ static const char *pvr2_fw1_names_29xxx[] = {
static const struct pvr2_device_desc pvr2_device_29xxx = {
.description = "WinTV PVR USB2 Model Category 29xxx",
.shortname = "29xxx",
- .client_modules.lst = pvr2_client_29xxx,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_29xxx),
+ .client_table.lst = pvr2_cli_29xxx,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx),
.fx2_firmware.lst = pvr2_fw1_names_29xxx,
.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_29xxx),
.flag_has_hauppauge_rom = !0,
@@ -77,10 +78,11 @@ static const struct pvr2_device_desc pvr2_device_29xxx = {
/*------------------------------------------------------------------------*/
/* Hauppauge PVR-USB2 Model 24xxx */
-static const char *pvr2_client_24xxx[] = {
- "cx25840",
- "tuner",
- "wm8775",
+static const struct pvr2_device_client_desc pvr2_cli_24xxx[] = {
+ { .module_id = PVR2_CLIENT_ID_CX25840 },
+ { .module_id = PVR2_CLIENT_ID_TUNER },
+ { .module_id = PVR2_CLIENT_ID_WM8775 },
+ { .module_id = PVR2_CLIENT_ID_DEMOD },
};
static const char *pvr2_fw1_names_24xxx[] = {
@@ -90,8 +92,8 @@ static const char *pvr2_fw1_names_24xxx[] = {
static const struct pvr2_device_desc pvr2_device_24xxx = {
.description = "WinTV PVR USB2 Model Category 24xxx",
.shortname = "24xxx",
- .client_modules.lst = pvr2_client_24xxx,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_24xxx),
+ .client_table.lst = pvr2_cli_24xxx,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx),
.fx2_firmware.lst = pvr2_fw1_names_24xxx,
.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_24xxx),
.flag_has_cx25840 = !0,
@@ -111,16 +113,16 @@ static const struct pvr2_device_desc pvr2_device_24xxx = {
/*------------------------------------------------------------------------*/
/* GOTVIEW USB2.0 DVD2 */
-static const char *pvr2_client_gotview_2[] = {
- "cx25840",
- "tuner",
+static const struct pvr2_device_client_desc pvr2_cli_gotview_2[] = {
+ { .module_id = PVR2_CLIENT_ID_CX25840 },
+ { .module_id = PVR2_CLIENT_ID_TUNER },
};
static const struct pvr2_device_desc pvr2_device_gotview_2 = {
.description = "Gotview USB 2.0 DVD 2",
.shortname = "gv2",
- .client_modules.lst = pvr2_client_gotview_2,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_gotview_2),
+ .client_table.lst = pvr2_cli_gotview_2,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2),
.flag_has_cx25840 = !0,
.default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
.flag_has_analogtuner = !0,
@@ -140,8 +142,8 @@ static const struct pvr2_device_desc pvr2_device_gotview_2 = {
static const struct pvr2_device_desc pvr2_device_gotview_2d = {
.description = "Gotview USB 2.0 DVD Deluxe",
.shortname = "gv2d",
- .client_modules.lst = pvr2_client_gotview_2,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_gotview_2),
+ .client_table.lst = pvr2_cli_gotview_2,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2),
.flag_has_cx25840 = !0,
.default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
.flag_has_analogtuner = !0,
@@ -181,29 +183,29 @@ static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap)
return 0;
}
-static struct pvr2_dvb_props pvr2_onair_creator_fe_props = {
+static const struct pvr2_dvb_props pvr2_onair_creator_fe_props = {
.frontend_attach = pvr2_lgdt3303_attach,
.tuner_attach = pvr2_lgh06xf_attach,
};
#endif
-static const char *pvr2_client_onair_creator[] = {
- "saa7115",
- "tuner",
- "cs53l32a",
+static const struct pvr2_device_client_desc pvr2_cli_onair_creator[] = {
+ { .module_id = PVR2_CLIENT_ID_SAA7115 },
+ { .module_id = PVR2_CLIENT_ID_CS53L32A },
+ { .module_id = PVR2_CLIENT_ID_TUNER },
};
static const struct pvr2_device_desc pvr2_device_onair_creator = {
.description = "OnAir Creator Hybrid USB tuner",
.shortname = "oac",
- .client_modules.lst = pvr2_client_onair_creator,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_creator),
+ .client_table.lst = pvr2_cli_onair_creator,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_creator),
.default_tuner_type = TUNER_LG_TDVS_H06XF,
.flag_has_analogtuner = !0,
.flag_has_composite = !0,
.flag_has_svideo = !0,
.flag_digital_requires_cx23416 = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+ .signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR,
.digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR,
.default_std_mask = V4L2_STD_NTSC_M,
#ifdef CONFIG_VIDEO_PVRUSB2_DVB
@@ -241,29 +243,29 @@ static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap)
return 0;
}
-static struct pvr2_dvb_props pvr2_onair_usb2_fe_props = {
+static const struct pvr2_dvb_props pvr2_onair_usb2_fe_props = {
.frontend_attach = pvr2_lgdt3302_attach,
.tuner_attach = pvr2_fcv1236d_attach,
};
#endif
-static const char *pvr2_client_onair_usb2[] = {
- "saa7115",
- "tuner",
- "cs53l32a",
+static const struct pvr2_device_client_desc pvr2_cli_onair_usb2[] = {
+ { .module_id = PVR2_CLIENT_ID_SAA7115 },
+ { .module_id = PVR2_CLIENT_ID_CS53L32A },
+ { .module_id = PVR2_CLIENT_ID_TUNER },
};
static const struct pvr2_device_desc pvr2_device_onair_usb2 = {
.description = "OnAir USB2 Hybrid USB tuner",
.shortname = "oa2",
- .client_modules.lst = pvr2_client_onair_usb2,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_usb2),
+ .client_table.lst = pvr2_cli_onair_usb2,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_usb2),
.default_tuner_type = TUNER_PHILIPS_FCV1236D,
.flag_has_analogtuner = !0,
.flag_has_composite = !0,
.flag_has_svideo = !0,
.flag_digital_requires_cx23416 = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+ .signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR,
.digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR,
.default_std_mask = V4L2_STD_NTSC_M,
#ifdef CONFIG_VIDEO_PVRUSB2_DVB
@@ -314,15 +316,16 @@ static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
return 0;
}
-static struct pvr2_dvb_props pvr2_73xxx_dvb_props = {
+static const struct pvr2_dvb_props pvr2_73xxx_dvb_props = {
.frontend_attach = pvr2_tda10048_attach,
.tuner_attach = pvr2_73xxx_tda18271_8295_attach,
};
#endif
-static const char *pvr2_client_73xxx[] = {
- "cx25840",
- "tuner",
+static const struct pvr2_device_client_desc pvr2_cli_73xxx[] = {
+ { .module_id = PVR2_CLIENT_ID_CX25840 },
+ { .module_id = PVR2_CLIENT_ID_TUNER,
+ .i2c_address_list = "\x42"},
};
static const char *pvr2_fw1_names_73xxx[] = {
@@ -332,8 +335,8 @@ static const char *pvr2_fw1_names_73xxx[] = {
static const struct pvr2_device_desc pvr2_device_73xxx = {
.description = "WinTV HVR-1900 Model Category 73xxx",
.shortname = "73xxx",
- .client_modules.lst = pvr2_client_73xxx,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_73xxx),
+ .client_table.lst = pvr2_cli_73xxx,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
.fx2_firmware.lst = pvr2_fw1_names_73xxx,
.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_73xxx),
.flag_has_cx25840 = !0,
@@ -418,22 +421,17 @@ static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
return 0;
}
-static struct pvr2_dvb_props pvr2_750xx_dvb_props = {
+static const struct pvr2_dvb_props pvr2_750xx_dvb_props = {
.frontend_attach = pvr2_s5h1409_attach,
.tuner_attach = pvr2_tda18271_8295_attach,
};
-static struct pvr2_dvb_props pvr2_751xx_dvb_props = {
+static const struct pvr2_dvb_props pvr2_751xx_dvb_props = {
.frontend_attach = pvr2_s5h1411_attach,
.tuner_attach = pvr2_tda18271_8295_attach,
};
#endif
-static const char *pvr2_client_75xxx[] = {
- "cx25840",
- "tuner",
-};
-
static const char *pvr2_fw1_names_75xxx[] = {
"v4l-pvrusb2-73xxx-01.fw",
};
@@ -441,8 +439,8 @@ static const char *pvr2_fw1_names_75xxx[] = {
static const struct pvr2_device_desc pvr2_device_750xx = {
.description = "WinTV HVR-1950 Model Category 750xx",
.shortname = "750xx",
- .client_modules.lst = pvr2_client_75xxx,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx),
+ .client_table.lst = pvr2_cli_73xxx,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
.fx2_firmware.lst = pvr2_fw1_names_75xxx,
.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx),
.flag_has_cx25840 = !0,
@@ -463,8 +461,8 @@ static const struct pvr2_device_desc pvr2_device_750xx = {
static const struct pvr2_device_desc pvr2_device_751xx = {
.description = "WinTV HVR-1950 Model Category 751xx",
.shortname = "751xx",
- .client_modules.lst = pvr2_client_75xxx,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx),
+ .client_table.lst = pvr2_cli_73xxx,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
.fx2_firmware.lst = pvr2_fw1_names_75xxx,
.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx),
.flag_has_cx25840 = !0,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index cb3a33eb0276..3e553389cbc3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -33,6 +33,34 @@
*/
+#define PVR2_CLIENT_ID_NULL 0
+#define PVR2_CLIENT_ID_MSP3400 1
+#define PVR2_CLIENT_ID_CX25840 2
+#define PVR2_CLIENT_ID_SAA7115 3
+#define PVR2_CLIENT_ID_TUNER 4
+#define PVR2_CLIENT_ID_CS53L32A 5
+#define PVR2_CLIENT_ID_WM8775 6
+#define PVR2_CLIENT_ID_DEMOD 7
+
+struct pvr2_device_client_desc {
+ /* One ovr PVR2_CLIENT_ID_xxxx */
+ unsigned char module_id;
+
+ /* Null-terminated array of I2C addresses to try in order
+ initialize the module. It's safe to make this null terminated
+ since we're never going to encounter an i2c device with an
+ address of zero. If this is a null pointer or zero-length,
+ then no I2C addresses have been specified, in which case we'll
+ try some compiled in defaults for now. */
+ unsigned char *i2c_address_list;
+};
+
+struct pvr2_device_client_table {
+ const struct pvr2_device_client_desc *lst;
+ unsigned char cnt;
+};
+
+
struct pvr2_string_table {
const char **lst;
unsigned int cnt;
@@ -40,6 +68,7 @@ struct pvr2_string_table {
#define PVR2_ROUTING_SCHEME_HAUPPAUGE 0
#define PVR2_ROUTING_SCHEME_GOTVIEW 1
+#define PVR2_ROUTING_SCHEME_ONAIR 2
#define PVR2_DIGITAL_SCHEME_NONE 0
#define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
@@ -66,6 +95,9 @@ struct pvr2_device_desc {
/* List of additional client modules we need to load */
struct pvr2_string_table client_modules;
+ /* List of defined client modules we need to load */
+ struct pvr2_device_client_table client_table;
+
/* List of FX2 firmware file names we should search; if empty then
FX2 firmware check / load is skipped and we assume the device
was initialized from internal ROM. */
@@ -73,7 +105,7 @@ struct pvr2_device_desc {
#ifdef CONFIG_VIDEO_PVRUSB2_DVB
/* callback functions to handle attachment of digital tuner & demod */
- struct pvr2_dvb_props *dvb_props;
+ const struct pvr2_dvb_props *dvb_props;
#endif
/* Initial standard bits to use for this device, if not zero.
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
index 77b3c3385066..b7f5c49b1dbc 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
@@ -321,7 +321,7 @@ static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter *adap)
static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
{
struct pvr2_hdw *hdw = adap->channel.hdw;
- struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props;
+ const struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props;
int ret = 0;
if (dvb_props == NULL) {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 273d2a1aa220..54ac5349dee2 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -347,7 +347,7 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
int encMisc3Arg = 0;
#if 0
- /* This inexplicable bit happens in the Hauppage windows
+ /* This inexplicable bit happens in the Hauppauge windows
driver (for both 24xxx and 29xxx devices). However I
currently see no difference in behavior with or without
this stuff. Leave this here as a note of its existence,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index de7ee7264be6..5d75eb5211b1 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -38,6 +38,7 @@
#include <linux/mutex.h>
#include "pvrusb2-hdw.h"
#include "pvrusb2-io.h"
+#include <media/v4l2-device.h>
#include <media/cx2341x.h>
#include "pvrusb2-devattr.h"
@@ -57,8 +58,6 @@
#define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0)
#define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0)
-struct pvr2_decoder;
-
typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *);
typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *);
typedef int (*pvr2_ctlf_check_value)(struct pvr2_ctrl *,int);
@@ -139,22 +138,6 @@ struct pvr2_ctrl {
};
-struct pvr2_decoder_ctrl {
- void *ctxt;
- void (*detach)(void *);
- void (*enable)(void *,int);
- void (*force_reset)(void *);
-};
-
-#define PVR2_I2C_PEND_DETECT 0x01 /* Need to detect a client type */
-#define PVR2_I2C_PEND_CLIENT 0x02 /* Client needs a specific update */
-#define PVR2_I2C_PEND_REFRESH 0x04 /* Client has specific pending bits */
-#define PVR2_I2C_PEND_STALE 0x08 /* Broadcast pending bits */
-
-#define PVR2_I2C_PEND_ALL (PVR2_I2C_PEND_DETECT |\
- PVR2_I2C_PEND_CLIENT |\
- PVR2_I2C_PEND_REFRESH |\
- PVR2_I2C_PEND_STALE)
/* Disposition of firmware1 loading situation */
#define FW1_STATE_UNKNOWN 0
@@ -179,6 +162,8 @@ struct pvr2_hdw {
struct usb_device *usb_dev;
struct usb_interface *usb_intf;
+ /* Our handle into the v4l2 sub-device architecture */
+ struct v4l2_device v4l2_dev;
/* Device description, anything that must adjust behavior based on
device specific info will use information held here. */
const struct pvr2_device_desc *hdw_desc;
@@ -186,7 +171,6 @@ struct pvr2_hdw {
/* Kernel worker thread handling */
struct workqueue_struct *workqueue;
struct work_struct workpoll; /* Update driver state */
- struct work_struct worki2csync; /* Update i2c clients */
/* Video spigot */
struct pvr2_stream *vid_stream;
@@ -195,20 +179,26 @@ struct pvr2_hdw {
struct mutex big_lock_mutex;
int big_lock_held; /* For debugging */
+ /* This is a simple string which identifies the instance of this
+ driver. It is unique within the set of existing devices, but
+ there is no attempt to keep the name consistent with the same
+ physical device each time. */
char name[32];
+ /* This is a simple string which identifies the physical device
+ instance itself - if possible. (If not possible, then it is
+ based on the specific driver instance, similar to name above.)
+ The idea here is that userspace might hopefully be able to use
+ this recognize specific tuners. It will encode a serial number,
+ if available. */
+ char identifier[32];
+
/* I2C stuff */
struct i2c_adapter i2c_adap;
struct i2c_algorithm i2c_algo;
pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT];
int i2c_cx25840_hack_state;
int i2c_linked;
- unsigned int i2c_pend_types; /* Which types of update are needed */
- unsigned long i2c_pend_mask; /* Change bits we need to scan */
- unsigned long i2c_stale_mask; /* Pending broadcast change bits */
- unsigned long i2c_active_mask; /* All change bits currently in use */
- struct list_head i2c_clients;
- struct mutex i2c_list_lock;
/* Frequency table */
unsigned int freqTable[FREQTABLE_SIZE];
@@ -275,6 +265,7 @@ struct pvr2_hdw {
wait_queue_head_t state_wait_data;
+ int force_dirty; /* consider all controls dirty if true */
int flag_ok; /* device in known good state */
int flag_disconnected; /* flag_ok == 0 due to disconnect */
int flag_init_ok; /* true if structure is fully initialized */
@@ -283,17 +274,13 @@ struct pvr2_hdw {
int flag_decoder_missed;/* We've noticed missing decoder */
int flag_tripped; /* Indicates overall failure to start */
- struct pvr2_decoder_ctrl *decoder_ctrl;
+ unsigned int decoder_client_id;
// CPU firmware info (used to help find / save firmware data)
char *fw_buffer;
unsigned int fw_size;
int fw_cpu_flag; /* True if we are dealing with the CPU */
- // True if there is a request to trigger logging of state in each
- // module.
- int log_requested;
-
/* Tuner / frequency control stuff */
unsigned int tuner_type;
int tuner_updated;
@@ -391,7 +378,8 @@ struct pvr2_hdw {
/* This function gets the current frequency */
unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *);
-void pvr2_hdw_set_decoder(struct pvr2_hdw *,struct pvr2_decoder_ctrl *);
+
+void pvr2_hdw_status_poll(struct pvr2_hdw *);
#endif /* __PVRUSB2_HDW_INTERNAL_H */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index fa304e5f252a..7a65b42a4f53 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -24,17 +24,22 @@
#include <linux/firmware.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+#include <media/tuner.h>
#include "pvrusb2.h"
#include "pvrusb2-std.h"
#include "pvrusb2-util.h"
#include "pvrusb2-hdw.h"
#include "pvrusb2-i2c-core.h"
-#include "pvrusb2-tuner.h"
#include "pvrusb2-eeprom.h"
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-encoder.h"
#include "pvrusb2-debug.h"
#include "pvrusb2-fx2-cmd.h"
+#include "pvrusb2-wm8775.h"
+#include "pvrusb2-video-v4l.h"
+#include "pvrusb2-cx2584x-v4l.h"
+#include "pvrusb2-cs53l32a.h"
+#include "pvrusb2-audio.h"
#define TV_MIN_FREQ 55250000L
#define TV_MAX_FREQ 850000000L
@@ -104,6 +109,39 @@ MODULE_PARM_DESC(radio_freq, "specify initial radio frequency");
/* size of a firmware chunk */
#define FIRMWARE_CHUNK_SIZE 0x2000
+typedef void (*pvr2_subdev_update_func)(struct pvr2_hdw *,
+ struct v4l2_subdev *);
+
+static const pvr2_subdev_update_func pvr2_module_update_functions[] = {
+ [PVR2_CLIENT_ID_WM8775] = pvr2_wm8775_subdev_update,
+ [PVR2_CLIENT_ID_SAA7115] = pvr2_saa7115_subdev_update,
+ [PVR2_CLIENT_ID_MSP3400] = pvr2_msp3400_subdev_update,
+ [PVR2_CLIENT_ID_CX25840] = pvr2_cx25840_subdev_update,
+ [PVR2_CLIENT_ID_CS53L32A] = pvr2_cs53l32a_subdev_update,
+};
+
+static const char *module_names[] = {
+ [PVR2_CLIENT_ID_MSP3400] = "msp3400",
+ [PVR2_CLIENT_ID_CX25840] = "cx25840",
+ [PVR2_CLIENT_ID_SAA7115] = "saa7115",
+ [PVR2_CLIENT_ID_TUNER] = "tuner",
+ [PVR2_CLIENT_ID_DEMOD] = "tuner",
+ [PVR2_CLIENT_ID_CS53L32A] = "cs53l32a",
+ [PVR2_CLIENT_ID_WM8775] = "wm8775",
+};
+
+
+static const unsigned char *module_i2c_addresses[] = {
+ [PVR2_CLIENT_ID_TUNER] = "\x60\x61\x62\x63",
+ [PVR2_CLIENT_ID_DEMOD] = "\x43",
+ [PVR2_CLIENT_ID_MSP3400] = "\x40",
+ [PVR2_CLIENT_ID_SAA7115] = "\x21",
+ [PVR2_CLIENT_ID_WM8775] = "\x1b",
+ [PVR2_CLIENT_ID_CX25840] = "\x44",
+ [PVR2_CLIENT_ID_CS53L32A] = "\x11",
+};
+
+
/* Define the list of additional controls we'll dynamically construct based
on query of the cx2341x module. */
struct pvr2_mpeg_ids {
@@ -277,7 +315,6 @@ static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v);
static void pvr2_hdw_state_sched(struct pvr2_hdw *);
static int pvr2_hdw_state_eval(struct pvr2_hdw *);
static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long);
-static void pvr2_hdw_worker_i2c(struct work_struct *work);
static void pvr2_hdw_worker_poll(struct work_struct *work);
static int pvr2_hdw_wait(struct pvr2_hdw *,int state);
static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *);
@@ -642,7 +679,7 @@ static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp)
unsigned long fv;
struct pvr2_hdw *hdw = cptr->hdw;
if (hdw->tuner_signal_stale) {
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
}
fv = hdw->tuner_signal_info.rangehigh;
if (!fv) {
@@ -664,7 +701,7 @@ static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp)
unsigned long fv;
struct pvr2_hdw *hdw = cptr->hdw;
if (hdw->tuner_signal_stale) {
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
}
fv = hdw->tuner_signal_info.rangelow;
if (!fv) {
@@ -858,7 +895,7 @@ static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
{
struct pvr2_hdw *hdw = cptr->hdw;
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
*vp = hdw->tuner_signal_info.signal;
return 0;
}
@@ -868,7 +905,7 @@ static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp)
int val = 0;
unsigned int subchan;
struct pvr2_hdw *hdw = cptr->hdw;
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
subchan = hdw->tuner_signal_info.rxsubchans;
if (subchan & V4L2_TUNER_SUB_MONO) {
val |= (1 << V4L2_TUNER_MODE_MONO);
@@ -1283,6 +1320,12 @@ const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw)
}
+const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *hdw)
+{
+ return hdw->identifier;
+}
+
+
unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
{
return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
@@ -1634,33 +1677,27 @@ static const char *pvr2_get_state_name(unsigned int st)
static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl)
{
- if (!hdw->decoder_ctrl) {
- if (!hdw->flag_decoder_missed) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "WARNING: No decoder present");
- hdw->flag_decoder_missed = !0;
- trace_stbit("flag_decoder_missed",
- hdw->flag_decoder_missed);
- }
- return -EIO;
+ /* Even though we really only care about the video decoder chip at
+ this point, we'll broadcast stream on/off to all sub-devices
+ anyway, just in case somebody else wants to hear the
+ command... */
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 stream=%s",
+ (enablefl ? "on" : "off"));
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_stream, enablefl);
+ if (hdw->decoder_client_id) {
+ /* We get here if the encoder has been noticed. Otherwise
+ we'll issue a warning to the user (which should
+ normally never happen). */
+ return 0;
}
- hdw->decoder_ctrl->enable(hdw->decoder_ctrl->ctxt,enablefl);
- return 0;
-}
-
-
-void pvr2_hdw_set_decoder(struct pvr2_hdw *hdw,struct pvr2_decoder_ctrl *ptr)
-{
- if (hdw->decoder_ctrl == ptr) return;
- hdw->decoder_ctrl = ptr;
- if (hdw->decoder_ctrl && hdw->flag_decoder_missed) {
- hdw->flag_decoder_missed = 0;
+ if (!hdw->flag_decoder_missed) {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "WARNING: No decoder present");
+ hdw->flag_decoder_missed = !0;
trace_stbit("flag_decoder_missed",
hdw->flag_decoder_missed);
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Decoder has appeared");
- pvr2_hdw_state_sched(hdw);
}
+ return -EIO;
}
@@ -1927,6 +1964,166 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
}
+static unsigned int pvr2_copy_i2c_addr_list(
+ unsigned short *dst, const unsigned char *src,
+ unsigned int dst_max)
+{
+ unsigned int cnt = 0;
+ if (!src) return 0;
+ while (src[cnt] && (cnt + 1) < dst_max) {
+ dst[cnt] = src[cnt];
+ cnt++;
+ }
+ dst[cnt] = I2C_CLIENT_END;
+ return cnt;
+}
+
+
+static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
+ const struct pvr2_device_client_desc *cd)
+{
+ const char *fname;
+ unsigned char mid;
+ struct v4l2_subdev *sd;
+ unsigned int i2ccnt;
+ const unsigned char *p;
+ /* Arbitrary count - max # i2c addresses we will probe */
+ unsigned short i2caddr[25];
+
+ mid = cd->module_id;
+ fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL;
+ if (!fname) {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "Module ID %u for device %s has no name",
+ mid,
+ hdw->hdw_desc->description);
+ return -EINVAL;
+ }
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Module ID %u (%s) for device %s being loaded...",
+ mid, fname,
+ hdw->hdw_desc->description);
+
+ i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, cd->i2c_address_list,
+ ARRAY_SIZE(i2caddr));
+ if (!i2ccnt && ((p = (mid < ARRAY_SIZE(module_i2c_addresses)) ?
+ module_i2c_addresses[mid] : NULL) != NULL)) {
+ /* Second chance: Try default i2c address list */
+ i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, p,
+ ARRAY_SIZE(i2caddr));
+ if (i2ccnt) {
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Module ID %u:"
+ " Using default i2c address list",
+ mid);
+ }
+ }
+
+ if (!i2ccnt) {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "Module ID %u (%s) for device %s:"
+ " No i2c addresses",
+ mid, fname, hdw->hdw_desc->description);
+ return -EINVAL;
+ }
+
+ /* Note how the 2nd and 3rd arguments are the same for both
+ * v4l2_i2c_new_subdev() and v4l2_i2c_new_probed_subdev(). Why?
+ * Well the 2nd argument is the module name to load, while the 3rd
+ * argument is documented in the framework as being the "chipid" -
+ * and every other place where I can find examples of this, the
+ * "chipid" appears to just be the module name again. So here we
+ * just do the same thing. */
+ if (i2ccnt == 1) {
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Module ID %u:"
+ " Setting up with specified i2c address 0x%x",
+ mid, i2caddr[0]);
+ sd = v4l2_i2c_new_subdev(&hdw->i2c_adap,
+ fname, fname,
+ i2caddr[0]);
+ } else {
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Module ID %u:"
+ " Setting up with address probe list",
+ mid);
+ sd = v4l2_i2c_new_probed_subdev(&hdw->i2c_adap,
+ fname, fname,
+ i2caddr);
+ }
+
+ if (!sd) {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "Module ID %u (%s) for device %s failed to load",
+ mid, fname, hdw->hdw_desc->description);
+ return -EIO;
+ }
+
+ /* Tag this sub-device instance with the module ID we know about.
+ In other places we'll use that tag to determine if the instance
+ requires special handling. */
+ sd->grp_id = mid;
+
+ pvr2_trace(PVR2_TRACE_INFO, "Attached sub-driver %s", fname);
+
+
+ /* client-specific setup... */
+ switch (mid) {
+ case PVR2_CLIENT_ID_CX25840:
+ hdw->decoder_client_id = mid;
+ {
+ /*
+ Mike Isely <isely@pobox.com> 19-Nov-2006 - This
+ bit of nuttiness for cx25840 causes that module
+ to correctly set up its video scaling. This is
+ really a problem in the cx25840 module itself,
+ but we work around it here. The problem has not
+ been seen in ivtv because there VBI is supported
+ and set up. We don't do VBI here (at least not
+ yet) and thus we never attempted to even set it
+ up.
+ */
+ struct v4l2_format fmt;
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Module ID %u:"
+ " Executing cx25840 VBI hack",
+ mid);
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+ v4l2_device_call_all(&hdw->v4l2_dev, mid,
+ video, s_fmt, &fmt);
+ }
+ break;
+ case PVR2_CLIENT_ID_SAA7115:
+ hdw->decoder_client_id = mid;
+ break;
+ default: break;
+ }
+
+ return 0;
+}
+
+
+static void pvr2_hdw_load_modules(struct pvr2_hdw *hdw)
+{
+ unsigned int idx;
+ const struct pvr2_string_table *cm;
+ const struct pvr2_device_client_table *ct;
+ int okFl = !0;
+
+ cm = &hdw->hdw_desc->client_modules;
+ for (idx = 0; idx < cm->cnt; idx++) {
+ request_module(cm->lst[idx]);
+ }
+
+ ct = &hdw->hdw_desc->client_table;
+ for (idx = 0; idx < ct->cnt; idx++) {
+ if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0;
+ }
+ if (!okFl) pvr2_hdw_render_useless(hdw);
+}
+
+
static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
{
int ret;
@@ -1966,9 +2163,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
if (!pvr2_hdw_dev_ok(hdw)) return;
- for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) {
- request_module(hdw->hdw_desc->client_modules.lst[idx]);
- }
+ hdw->force_dirty = !0;
if (!hdw->hdw_desc->flag_no_powerup) {
pvr2_hdw_cmd_powerup(hdw);
@@ -1987,6 +2182,11 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
pvr2_i2c_core_init(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return;
+ pvr2_hdw_load_modules(hdw);
+ if (!pvr2_hdw_dev_ok(hdw)) return;
+
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, core, init, 0);
+
for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
cptr = hdw->controls + idx;
if (cptr->info->skip_init) continue;
@@ -2024,6 +2224,19 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
hdw->std_mask_eeprom = V4L2_STD_ALL;
}
+ if (hdw->serial_number) {
+ idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
+ "sn-%lu", hdw->serial_number);
+ } else if (hdw->unit_number >= 0) {
+ idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
+ "unit-%c",
+ hdw->unit_number + 'a');
+ } else {
+ idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
+ "unit-??");
+ }
+ hdw->identifier[idx] = 0;
+
pvr2_hdw_setup_std(hdw);
if (!get_default_tuner_type(hdw)) {
@@ -2032,8 +2245,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
hdw->tuner_type);
}
- pvr2_i2c_core_check_stale(hdw);
- hdw->tuner_updated = 0;
if (!pvr2_hdw_dev_ok(hdw)) return;
@@ -2171,11 +2382,14 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
struct pvr2_hdw *hdw = NULL;
int valid_std_mask;
struct pvr2_ctrl *cptr;
+ struct usb_device *usb_dev;
const struct pvr2_device_desc *hdw_desc;
__u8 ifnum;
struct v4l2_queryctrl qctrl;
struct pvr2_ctl_info *ciptr;
+ usb_dev = interface_to_usbdev(intf);
+
hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info);
if (hdw_desc == NULL) {
@@ -2360,6 +2574,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
if (!hdw->ctl_read_urb) goto fail;
+ if (v4l2_device_register(&usb_dev->dev, &hdw->v4l2_dev) != 0) {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "Error registering with v4l core, giving up");
+ goto fail;
+ }
mutex_lock(&pvr2_unit_mtx); do {
for (idx = 0; idx < PVR_NUM; idx++) {
if (unit_pointers[idx]) continue;
@@ -2382,7 +2601,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->workqueue = create_singlethread_workqueue(hdw->name);
INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll);
- INIT_WORK(&hdw->worki2csync,pvr2_hdw_worker_i2c);
pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
hdw->unit_number,hdw->name);
@@ -2391,12 +2609,9 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->flag_ok = !0;
hdw->usb_intf = intf;
- hdw->usb_dev = interface_to_usbdev(intf);
+ hdw->usb_dev = usb_dev;
- scnprintf(hdw->bus_info,sizeof(hdw->bus_info),
- "usb %s address %d",
- dev_name(&hdw->usb_dev->dev),
- hdw->usb_dev->devnum);
+ usb_make_path(hdw->usb_dev, hdw->bus_info, sizeof(hdw->bus_info));
ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
usb_set_interface(hdw->usb_dev,ifnum,0);
@@ -2454,6 +2669,10 @@ static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
hdw->ctl_write_buffer = NULL;
}
hdw->flag_disconnected = !0;
+ /* If we don't do this, then there will be a dangling struct device
+ reference to our disappearing device persisting inside the V4L
+ core... */
+ v4l2_device_disconnect(&hdw->v4l2_dev);
hdw->usb_dev = NULL;
hdw->usb_intf = NULL;
pvr2_hdw_render_useless(hdw);
@@ -2481,10 +2700,8 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
pvr2_stream_destroy(hdw->vid_stream);
hdw->vid_stream = NULL;
}
- if (hdw->decoder_ctrl) {
- hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
- }
pvr2_i2c_core_done(hdw);
+ v4l2_device_unregister(&hdw->v4l2_dev);
pvr2_hdw_remove_usb_stuff(hdw);
mutex_lock(&pvr2_unit_mtx); do {
if ((hdw->unit_number >= 0) &&
@@ -2678,6 +2895,150 @@ static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
}
+static void pvr2_subdev_set_control(struct pvr2_hdw *hdw, int id,
+ const char *name, int val)
+{
+ struct v4l2_control ctrl;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 %s=%d", name, val);
+ memset(&ctrl, 0, sizeof(ctrl));
+ ctrl.id = id;
+ ctrl.value = val;
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, core, s_ctrl, &ctrl);
+}
+
+#define PVR2_SUBDEV_SET_CONTROL(hdw, id, lab) \
+ if ((hdw)->lab##_dirty || (hdw)->force_dirty) { \
+ pvr2_subdev_set_control(hdw, id, #lab, (hdw)->lab##_val); \
+ }
+
+/* Execute whatever commands are required to update the state of all the
+ sub-devices so that they match our current control values. */
+static void pvr2_subdev_update(struct pvr2_hdw *hdw)
+{
+ struct v4l2_subdev *sd;
+ unsigned int id;
+ pvr2_subdev_update_func fp;
+
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev update...");
+
+ if (hdw->tuner_updated || hdw->force_dirty) {
+ struct tuner_setup setup;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev tuner set_type(%d)",
+ hdw->tuner_type);
+ if (((int)(hdw->tuner_type)) >= 0) {
+ setup.addr = ADDR_UNSET;
+ setup.type = hdw->tuner_type;
+ setup.mode_mask = T_RADIO | T_ANALOG_TV;
+ v4l2_device_call_all(&hdw->v4l2_dev, 0,
+ tuner, s_type_addr, &setup);
+ }
+ }
+
+ if (hdw->input_dirty || hdw->std_dirty || hdw->force_dirty) {
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_standard");
+ if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
+ v4l2_device_call_all(&hdw->v4l2_dev, 0,
+ tuner, s_radio);
+ } else {
+ v4l2_std_id vs;
+ vs = hdw->std_mask_cur;
+ v4l2_device_call_all(&hdw->v4l2_dev, 0,
+ tuner, s_std, vs);
+ }
+ hdw->tuner_signal_stale = !0;
+ hdw->cropcap_stale = !0;
+ }
+
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_BRIGHTNESS, brightness);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_CONTRAST, contrast);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_SATURATION, saturation);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_HUE, hue);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_MUTE, mute);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_VOLUME, volume);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BALANCE, balance);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BASS, bass);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_TREBLE, treble);
+
+ if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) {
+ struct v4l2_tuner vt;
+ memset(&vt, 0, sizeof(vt));
+ vt.audmode = hdw->audiomode_val;
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt);
+ }
+
+ if (hdw->freqDirty || hdw->force_dirty) {
+ unsigned long fv;
+ struct v4l2_frequency freq;
+ fv = pvr2_hdw_get_cur_freq(hdw);
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_freq(%lu)", fv);
+ if (hdw->tuner_signal_stale) pvr2_hdw_status_poll(hdw);
+ memset(&freq, 0, sizeof(freq));
+ if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
+ /* ((fv * 1000) / 62500) */
+ freq.frequency = (fv * 2) / 125;
+ } else {
+ freq.frequency = fv / 62500;
+ }
+ /* tuner-core currently doesn't seem to care about this, but
+ let's set it anyway for completeness. */
+ if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
+ freq.type = V4L2_TUNER_RADIO;
+ } else {
+ freq.type = V4L2_TUNER_ANALOG_TV;
+ }
+ freq.tuner = 0;
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner,
+ s_frequency, &freq);
+ }
+
+ if (hdw->res_hor_dirty || hdw->res_ver_dirty || hdw->force_dirty) {
+ struct v4l2_format fmt;
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmt.fmt.pix.width = hdw->res_hor_val;
+ fmt.fmt.pix.height = hdw->res_ver_val;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)",
+ fmt.fmt.pix.width, fmt.fmt.pix.height);
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_fmt, &fmt);
+ }
+
+ if (hdw->srate_dirty || hdw->force_dirty) {
+ u32 val;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_audio %d",
+ hdw->srate_val);
+ switch (hdw->srate_val) {
+ default:
+ case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
+ val = 48000;
+ break;
+ case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
+ val = 44100;
+ break;
+ case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
+ val = 32000;
+ break;
+ }
+ v4l2_device_call_all(&hdw->v4l2_dev, 0,
+ audio, s_clock_freq, val);
+ }
+
+ /* Unable to set crop parameters; there is apparently no equivalent
+ for VIDIOC_S_CROP */
+
+ v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
+ id = sd->grp_id;
+ if (id >= ARRAY_SIZE(pvr2_module_update_functions)) continue;
+ fp = pvr2_module_update_functions[id];
+ if (!fp) continue;
+ (*fp)(hdw, sd);
+ }
+
+ if (hdw->tuner_signal_stale || hdw->cropcap_stale) {
+ pvr2_hdw_status_poll(hdw);
+ }
+}
+
+
/* Figure out if we need to commit control changes. If so, mark internal
state flags to indicate this fact and return true. Otherwise do nothing
else and return false. */
@@ -2686,7 +3047,7 @@ static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw)
unsigned int idx;
struct pvr2_ctrl *cptr;
int value;
- int commit_flag = 0;
+ int commit_flag = hdw->force_dirty;
char buf[100];
unsigned int bcnt,ccnt;
@@ -2842,18 +3203,6 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS);
}
- /* Scan i2c core at this point - before we clear all the dirty
- bits. Various parts of the i2c core will notice dirty bits as
- appropriate and arrange to broadcast or directly send updates to
- the client drivers in order to keep everything in sync */
- pvr2_i2c_core_check_stale(hdw);
-
- for (idx = 0; idx < hdw->control_cnt; idx++) {
- cptr = hdw->controls + idx;
- if (!cptr->info->clear_dirty) continue;
- cptr->info->clear_dirty(cptr);
- }
-
if (hdw->active_stream_type != hdw->desired_stream_type) {
/* Handle any side effects of stream config here */
hdw->active_stream_type = hdw->desired_stream_type;
@@ -2873,8 +3222,16 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
}
}
- /* Now execute i2c core update */
- pvr2_i2c_core_sync(hdw);
+ /* Check and update state for all sub-devices. */
+ pvr2_subdev_update(hdw);
+
+ hdw->tuner_updated = 0;
+ hdw->force_dirty = 0;
+ for (idx = 0; idx < hdw->control_cnt; idx++) {
+ cptr = hdw->controls + idx;
+ if (!cptr->info->clear_dirty) continue;
+ cptr->info->clear_dirty(cptr);
+ }
if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) &&
hdw->state_encoder_run) {
@@ -2904,15 +3261,6 @@ int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
}
-static void pvr2_hdw_worker_i2c(struct work_struct *work)
-{
- struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,worki2csync);
- LOCK_TAKE(hdw->big_lock); do {
- pvr2_i2c_core_sync(hdw);
- } while (0); LOCK_GIVE(hdw->big_lock);
-}
-
-
static void pvr2_hdw_worker_poll(struct work_struct *work)
{
int fl = 0;
@@ -2973,7 +3321,7 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw)
{
LOCK_TAKE(hdw->big_lock); do {
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
} while (0); LOCK_GIVE(hdw->big_lock);
}
@@ -2983,7 +3331,7 @@ static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw)
if (!hdw->cropcap_stale) {
return 0;
}
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
if (hdw->cropcap_stale) {
return -EIO;
}
@@ -3010,7 +3358,7 @@ int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp)
{
LOCK_TAKE(hdw->big_lock); do {
if (hdw->tuner_signal_stale) {
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
}
memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
} while (0); LOCK_GIVE(hdw->big_lock);
@@ -3029,11 +3377,8 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
{
int nr = pvr2_hdw_get_unit_number(hdw);
LOCK_TAKE(hdw->big_lock); do {
- hdw->log_requested = !0;
printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
- pvr2_i2c_core_check_stale(hdw);
- hdw->log_requested = 0;
- pvr2_i2c_core_sync(hdw);
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, core, log_status);
pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
pvr2_hdw_state_log_state(hdw);
@@ -3716,22 +4061,16 @@ int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *hdw)
int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
{
- if (!hdw->decoder_ctrl) {
- pvr2_trace(PVR2_TRACE_INIT,
- "Unable to reset decoder: nothing attached");
- return -ENOTTY;
- }
-
- if (!hdw->decoder_ctrl->force_reset) {
- pvr2_trace(PVR2_TRACE_INIT,
- "Unable to reset decoder: not implemented");
- return -ENOTTY;
- }
-
pvr2_trace(PVR2_TRACE_INIT,
"Requesting decoder reset");
- hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
- return 0;
+ if (hdw->decoder_client_id) {
+ v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
+ core, reset, 0);
+ return 0;
+ }
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Unable to reset decoder: nothing attached");
+ return -ENOTTY;
}
@@ -4476,6 +4815,79 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
}
+/* Generate report containing info about attached sub-devices and attached
+ i2c clients, including an indication of which attached i2c clients are
+ actually sub-devices. */
+static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw,
+ char *buf, unsigned int acnt)
+{
+ struct v4l2_subdev *sd;
+ unsigned int tcnt = 0;
+ unsigned int ccnt;
+ struct i2c_client *client;
+ struct list_head *item;
+ void *cd;
+ const char *p;
+ unsigned int id;
+
+ ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers:");
+ tcnt += ccnt;
+ v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
+ id = sd->grp_id;
+ p = NULL;
+ if (id < ARRAY_SIZE(module_names)) p = module_names[id];
+ if (p) {
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s", p);
+ tcnt += ccnt;
+ } else {
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt,
+ " (unknown id=%u)", id);
+ tcnt += ccnt;
+ }
+ }
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
+ tcnt += ccnt;
+
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt, "I2C clients:\n");
+ tcnt += ccnt;
+
+ mutex_lock(&hdw->i2c_adap.clist_lock);
+ list_for_each(item, &hdw->i2c_adap.clients) {
+ client = list_entry(item, struct i2c_client, list);
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt,
+ " %s: i2c=%02x", client->name, client->addr);
+ tcnt += ccnt;
+ cd = i2c_get_clientdata(client);
+ v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
+ if (cd == sd) {
+ id = sd->grp_id;
+ p = NULL;
+ if (id < ARRAY_SIZE(module_names)) {
+ p = module_names[id];
+ }
+ if (p) {
+ ccnt = scnprintf(buf + tcnt,
+ acnt - tcnt,
+ " subdev=%s", p);
+ tcnt += ccnt;
+ } else {
+ ccnt = scnprintf(buf + tcnt,
+ acnt - tcnt,
+ " subdev= id %u)",
+ id);
+ tcnt += ccnt;
+ }
+ break;
+ }
+ }
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
+ tcnt += ccnt;
+ }
+ mutex_unlock(&hdw->i2c_adap.clist_lock);
+ return tcnt;
+}
+
+
unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
char *buf,unsigned int acnt)
{
@@ -4490,6 +4902,8 @@ unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
buf[0] = '\n'; ccnt = 1;
bcnt += ccnt; acnt -= ccnt; buf += ccnt;
}
+ ccnt = pvr2_hdw_report_clients(hdw, buf, acnt);
+ bcnt += ccnt; acnt -= ccnt; buf += ccnt;
LOCK_GIVE(hdw->big_lock);
return bcnt;
}
@@ -4497,14 +4911,25 @@ unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw)
{
- char buf[128];
- unsigned int idx,ccnt;
+ char buf[256];
+ unsigned int idx, ccnt;
+ unsigned int lcnt, ucnt;
for (idx = 0; ; idx++) {
ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf));
if (!ccnt) break;
printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf);
}
+ ccnt = pvr2_hdw_report_clients(hdw, buf, sizeof(buf));
+ ucnt = 0;
+ while (ucnt < ccnt) {
+ lcnt = 0;
+ while ((lcnt + ucnt < ccnt) && (buf[lcnt + ucnt] != '\n')) {
+ lcnt++;
+ }
+ printk(KERN_INFO "%s %.*s\n", hdw->name, lcnt, buf + ucnt);
+ ucnt += lcnt + 1;
+ }
}
@@ -4641,6 +5066,30 @@ int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
}
+void pvr2_hdw_status_poll(struct pvr2_hdw *hdw)
+{
+ struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
+ memset(vtp, 0, sizeof(*vtp));
+ hdw->tuner_signal_stale = 0;
+ /* Note: There apparently is no replacement for VIDIOC_CROPCAP
+ using v4l2-subdev - therefore we can't support that AT ALL right
+ now. (Of course, no sub-drivers seem to implement it either.
+ But now it's a a chicken and egg problem...) */
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, g_tuner,
+ &hdw->tuner_signal_info);
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll"
+ " type=%u strength=%u audio=0x%x cap=0x%x"
+ " low=%u hi=%u",
+ vtp->type,
+ vtp->signal, vtp->rxsubchans, vtp->capability,
+ vtp->rangelow, vtp->rangehigh);
+
+ /* We have to do this to avoid getting into constant polling if
+ there's nobody to answer a poll of cropcap info. */
+ hdw->cropcap_stale = 0;
+}
+
+
unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw)
{
return hdw->input_avail_mask;
@@ -4736,7 +5185,6 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
int setFl, u64 *val_ptr)
{
#ifdef CONFIG_VIDEO_ADV_DEBUG
- struct pvr2_i2c_client *cp;
struct v4l2_dbg_register req;
int stat = 0;
int okFl = 0;
@@ -4746,21 +5194,9 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
req.match = *match;
req.reg = reg_id;
if (setFl) req.val = *val_ptr;
- mutex_lock(&hdw->i2c_list_lock); do {
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- if (!v4l2_chip_match_i2c_client(
- cp->client,
- &req.match)) {
- continue;
- }
- stat = pvr2_i2c_client_cmd(
- cp,(setFl ? VIDIOC_DBG_S_REGISTER :
- VIDIOC_DBG_G_REGISTER),&req);
- if (!setFl) *val_ptr = req.val;
- okFl = !0;
- break;
- }
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
+ /* It would be nice to know if a sub-device answered the request */
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, core, g_register, &req);
+ if (!setFl) *val_ptr = req.val;
if (okFl) {
return stat;
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 1b4fec337c6b..7b6940554e9a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -132,6 +132,9 @@ unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *);
/* Retrieve bus location info of device */
const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *);
+/* Retrieve per-instance string identifier for this specific device */
+const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *);
+
/* Called when hardware has been unplugged */
void pvr2_hdw_disconnect(struct pvr2_hdw *);
@@ -236,8 +239,7 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,
enum pvr2_v4l_type index,int);
/* Direct read/write access to chip's registers:
- match_type - how to interpret match_chip (e.g. driver ID, i2c address)
- match_chip - chip match value (e.g. I2C_DRIVERD_xxxx)
+ match - specify criteria to identify target chip (this is a v4l dbg struct)
reg_id - register number to access
setFl - true to set the register, false to read it
val_ptr - storage location for source / result. */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
deleted file mode 100644
index 94a47718e88e..000000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/kernel.h>
-#include "pvrusb2-i2c-core.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
-#include "pvrusb2-audio.h"
-#include "pvrusb2-tuner.h"
-#include "pvrusb2-video-v4l.h"
-#include "pvrusb2-cx2584x-v4l.h"
-#include "pvrusb2-wm8775.h"
-
-#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
-
-#define OP_STANDARD 0
-#define OP_AUDIOMODE 1
-#define OP_BCSH 2
-#define OP_VOLUME 3
-#define OP_FREQ 4
-#define OP_AUDIORATE 5
-#define OP_CROP 6
-#define OP_SIZE 7
-#define OP_LOG 8
-
-static const struct pvr2_i2c_op * const ops[] = {
- [OP_STANDARD] = &pvr2_i2c_op_v4l2_standard,
- [OP_AUDIOMODE] = &pvr2_i2c_op_v4l2_audiomode,
- [OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh,
- [OP_VOLUME] = &pvr2_i2c_op_v4l2_volume,
- [OP_FREQ] = &pvr2_i2c_op_v4l2_frequency,
- [OP_CROP] = &pvr2_i2c_op_v4l2_crop,
- [OP_SIZE] = &pvr2_i2c_op_v4l2_size,
- [OP_LOG] = &pvr2_i2c_op_v4l2_log,
-};
-
-void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
- int id;
- id = cp->client->driver->id;
- cp->ctl_mask = ((1 << OP_STANDARD) |
- (1 << OP_AUDIOMODE) |
- (1 << OP_BCSH) |
- (1 << OP_VOLUME) |
- (1 << OP_FREQ) |
- (1 << OP_CROP) |
- (1 << OP_SIZE) |
- (1 << OP_LOG));
- cp->status_poll = pvr2_v4l2_cmd_status_poll;
-
- if (id == I2C_DRIVERID_MSP3400) {
- if (pvr2_i2c_msp3400_setup(hdw,cp)) {
- return;
- }
- }
- if (id == I2C_DRIVERID_TUNER) {
- if (pvr2_i2c_tuner_setup(hdw,cp)) {
- return;
- }
- }
- if (id == I2C_DRIVERID_CX25840) {
- if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) {
- return;
- }
- }
- if (id == I2C_DRIVERID_WM8775) {
- if (pvr2_i2c_wm8775_setup(hdw,cp)) {
- return;
- }
- }
- if (id == I2C_DRIVERID_SAA711X) {
- if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) {
- return;
- }
- }
-}
-
-
-const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx)
-{
- if (idx >= ARRAY_SIZE(ops))
- return NULL;
- return ops[idx];
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
deleted file mode 100644
index 16bb11902a52..000000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "pvrusb2-i2c-cmd-v4l2.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-
-static void set_standard(struct pvr2_hdw *hdw)
-{
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_standard");
-
- if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
- pvr2_i2c_core_cmd(hdw,AUDC_SET_RADIO,NULL);
- } else {
- v4l2_std_id vs;
- vs = hdw->std_mask_cur;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs);
- }
- hdw->tuner_signal_stale = !0;
- hdw->cropcap_stale = !0;
-}
-
-
-static int check_standard(struct pvr2_hdw *hdw)
-{
- return (hdw->input_dirty != 0) || (hdw->std_dirty != 0);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard = {
- .check = check_standard,
- .update = set_standard,
- .name = "v4l2_standard",
-};
-
-
-static void set_bcsh(struct pvr2_hdw *hdw)
-{
- struct v4l2_control ctrl;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_bcsh"
- " b=%d c=%d s=%d h=%d",
- hdw->brightness_val,hdw->contrast_val,
- hdw->saturation_val,hdw->hue_val);
- memset(&ctrl,0,sizeof(ctrl));
- ctrl.id = V4L2_CID_BRIGHTNESS;
- ctrl.value = hdw->brightness_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_CONTRAST;
- ctrl.value = hdw->contrast_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_SATURATION;
- ctrl.value = hdw->saturation_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_HUE;
- ctrl.value = hdw->hue_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-}
-
-
-static int check_bcsh(struct pvr2_hdw *hdw)
-{
- return (hdw->brightness_dirty ||
- hdw->contrast_dirty ||
- hdw->saturation_dirty ||
- hdw->hue_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh = {
- .check = check_bcsh,
- .update = set_bcsh,
- .name = "v4l2_bcsh",
-};
-
-
-static void set_volume(struct pvr2_hdw *hdw)
-{
- struct v4l2_control ctrl;
- pvr2_trace(PVR2_TRACE_CHIPS,
- "i2c v4l2 set_volume"
- "(vol=%d bal=%d bas=%d treb=%d mute=%d)",
- hdw->volume_val,
- hdw->balance_val,
- hdw->bass_val,
- hdw->treble_val,
- hdw->mute_val);
- memset(&ctrl,0,sizeof(ctrl));
- ctrl.id = V4L2_CID_AUDIO_MUTE;
- ctrl.value = hdw->mute_val ? 1 : 0;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_AUDIO_VOLUME;
- ctrl.value = hdw->volume_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_AUDIO_BALANCE;
- ctrl.value = hdw->balance_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_AUDIO_BASS;
- ctrl.value = hdw->bass_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_AUDIO_TREBLE;
- ctrl.value = hdw->treble_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-}
-
-
-static int check_volume(struct pvr2_hdw *hdw)
-{
- return (hdw->volume_dirty ||
- hdw->balance_dirty ||
- hdw->bass_dirty ||
- hdw->treble_dirty ||
- hdw->mute_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume = {
- .check = check_volume,
- .update = set_volume,
- .name = "v4l2_volume",
-};
-
-
-static void set_audiomode(struct pvr2_hdw *hdw)
-{
- struct v4l2_tuner vt;
- memset(&vt,0,sizeof(vt));
- vt.audmode = hdw->audiomode_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_TUNER,&vt);
-}
-
-
-static int check_audiomode(struct pvr2_hdw *hdw)
-{
- return (hdw->input_dirty ||
- hdw->audiomode_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode = {
- .check = check_audiomode,
- .update = set_audiomode,
- .name = "v4l2_audiomode",
-};
-
-
-static void set_frequency(struct pvr2_hdw *hdw)
-{
- unsigned long fv;
- struct v4l2_frequency freq;
- fv = pvr2_hdw_get_cur_freq(hdw);
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_freq(%lu)",fv);
- if (hdw->tuner_signal_stale) {
- pvr2_i2c_core_status_poll(hdw);
- }
- memset(&freq,0,sizeof(freq));
- if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
- // ((fv * 1000) / 62500)
- freq.frequency = (fv * 2) / 125;
- } else {
- freq.frequency = fv / 62500;
- }
- /* tuner-core currently doesn't seem to care about this, but
- let's set it anyway for completeness. */
- if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
- freq.type = V4L2_TUNER_RADIO;
- } else {
- freq.type = V4L2_TUNER_ANALOG_TV;
- }
- freq.tuner = 0;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_FREQUENCY,&freq);
-}
-
-
-static int check_frequency(struct pvr2_hdw *hdw)
-{
- return hdw->freqDirty != 0;
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency = {
- .check = check_frequency,
- .update = set_frequency,
- .name = "v4l2_freq",
-};
-
-
-static void set_size(struct pvr2_hdw *hdw)
-{
- struct v4l2_format fmt;
-
- memset(&fmt,0,sizeof(fmt));
-
- fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt.fmt.pix.width = hdw->res_hor_val;
- fmt.fmt.pix.height = hdw->res_ver_val;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_size(%dx%d)",
- fmt.fmt.pix.width,fmt.fmt.pix.height);
-
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_FMT,&fmt);
-}
-
-
-static int check_size(struct pvr2_hdw *hdw)
-{
- return (hdw->res_hor_dirty || hdw->res_ver_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = {
- .check = check_size,
- .update = set_size,
- .name = "v4l2_size",
-};
-
-
-static void set_crop(struct pvr2_hdw *hdw)
-{
- struct v4l2_crop crop;
-
- memset(&crop, 0, sizeof crop);
- crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- crop.c.left = hdw->cropl_val;
- crop.c.top = hdw->cropt_val;
- crop.c.height = hdw->croph_val;
- crop.c.width = hdw->cropw_val;
-
- pvr2_trace(PVR2_TRACE_CHIPS,
- "i2c v4l2 set_crop crop=%d:%d:%d:%d",
- crop.c.width, crop.c.height, crop.c.left, crop.c.top);
-
- pvr2_i2c_core_cmd(hdw, VIDIOC_S_CROP, &crop);
-}
-
-static int check_crop(struct pvr2_hdw *hdw)
-{
- return (hdw->cropl_dirty || hdw->cropt_dirty ||
- hdw->cropw_dirty || hdw->croph_dirty);
-}
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop = {
- .check = check_crop,
- .update = set_crop,
- .name = "v4l2_crop",
-};
-
-
-static void do_log(struct pvr2_hdw *hdw)
-{
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()");
- pvr2_i2c_core_cmd(hdw,VIDIOC_LOG_STATUS,NULL);
-
-}
-
-
-static int check_log(struct pvr2_hdw *hdw)
-{
- return hdw->log_requested != 0;
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log = {
- .check = check_log,
- .update = do_log,
- .name = "v4l2_log",
-};
-
-
-void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl)
-{
- pvr2_i2c_client_cmd(cp,
- (fl ? VIDIOC_STREAMON : VIDIOC_STREAMOFF),NULL);
-}
-
-
-void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *cp)
-{
- int stat;
- struct pvr2_hdw *hdw = cp->hdw;
- if (hdw->cropcap_stale) {
- hdw->cropcap_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- stat = pvr2_i2c_client_cmd(cp, VIDIOC_CROPCAP,
- &hdw->cropcap_info);
- if (stat == 0) {
- /* Check was successful, so the data is no
- longer considered stale. */
- hdw->cropcap_stale = 0;
- }
- }
- pvr2_i2c_client_cmd(cp, VIDIOC_G_TUNER, &hdw->tuner_signal_info);
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
deleted file mode 100644
index eb744a20610d..000000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#ifndef __PVRUSB2_CMD_V4L2_H
-#define __PVRUSB2_CMD_V4L2_H
-
-#include "pvrusb2-i2c-core.h"
-
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_radio;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log;
-
-void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int);
-void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *);
-
-#endif /* __PVRUSB2_CMD_V4L2_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index d6a35401fefb..9464862745fa 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -18,6 +18,7 @@
*
*/
+#include <linux/i2c.h>
#include "pvrusb2-i2c-core.h"
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h"
@@ -29,8 +30,7 @@
/*
This module attempts to implement a compliant I2C adapter for the pvrusb2
- device. By doing this we can then make use of existing functionality in
- V4L (e.g. tuner.c) rather than rolling our own.
+ device.
*/
@@ -42,10 +42,6 @@ static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
module_param_array(ir_mode, int, NULL, 0444);
MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
-static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
- unsigned int detail,
- char *buf,unsigned int maxlen);
-
static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */
u8 i2c_addr, /* I2C address we're talking to */
u8 *data, /* Data to write */
@@ -524,414 +520,13 @@ static u32 pvr2_i2c_functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
}
-static int pvr2_i2c_core_singleton(struct i2c_client *cp,
- unsigned int cmd,void *arg)
-{
- int stat;
- if (!cp) return -EINVAL;
- if (!(cp->driver)) return -EINVAL;
- if (!(cp->driver->command)) return -EINVAL;
- if (!try_module_get(cp->driver->driver.owner)) return -EAGAIN;
- stat = cp->driver->command(cp,cmd,arg);
- module_put(cp->driver->driver.owner);
- return stat;
-}
-
-int pvr2_i2c_client_cmd(struct pvr2_i2c_client *cp,unsigned int cmd,void *arg)
-{
- int stat;
- if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
- char buf[100];
- unsigned int cnt;
- cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
- buf,sizeof(buf));
- pvr2_trace(PVR2_TRACE_I2C_CMD,
- "i2c COMMAND (code=%u 0x%x) to %.*s",
- cmd,cmd,cnt,buf);
- }
- stat = pvr2_i2c_core_singleton(cp->client,cmd,arg);
- if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
- char buf[100];
- unsigned int cnt;
- cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
- buf,sizeof(buf));
- pvr2_trace(PVR2_TRACE_I2C_CMD,
- "i2c COMMAND to %.*s (ret=%d)",cnt,buf,stat);
- }
- return stat;
-}
-
-int pvr2_i2c_core_cmd(struct pvr2_hdw *hdw,unsigned int cmd,void *arg)
-{
- struct pvr2_i2c_client *cp, *ncp;
- int stat = -EINVAL;
-
- if (!hdw) return stat;
-
- mutex_lock(&hdw->i2c_list_lock);
- list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
- if (!cp->recv_enable) continue;
- mutex_unlock(&hdw->i2c_list_lock);
- stat = pvr2_i2c_client_cmd(cp,cmd,arg);
- mutex_lock(&hdw->i2c_list_lock);
- }
- mutex_unlock(&hdw->i2c_list_lock);
- return stat;
-}
-
-
-static int handler_check(struct pvr2_i2c_client *cp)
-{
- struct pvr2_i2c_handler *hp = cp->handler;
- if (!hp) return 0;
- if (!hp->func_table->check) return 0;
- return hp->func_table->check(hp->func_data) != 0;
-}
-
-#define BUFSIZE 500
-
-
-void pvr2_i2c_core_status_poll(struct pvr2_hdw *hdw)
-{
- struct pvr2_i2c_client *cp;
- mutex_lock(&hdw->i2c_list_lock); do {
- struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
- memset(vtp,0,sizeof(*vtp));
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- if (!cp->detected_flag) continue;
- if (!cp->status_poll) continue;
- cp->status_poll(cp);
- }
- hdw->tuner_signal_stale = 0;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c status poll"
- " type=%u strength=%u audio=0x%x cap=0x%x"
- " low=%u hi=%u",
- vtp->type,
- vtp->signal,vtp->rxsubchans,vtp->capability,
- vtp->rangelow,vtp->rangehigh);
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
-}
-
-
-/* Issue various I2C operations to bring chip-level drivers into sync with
- state stored in this driver. */
-void pvr2_i2c_core_sync(struct pvr2_hdw *hdw)
-{
- unsigned long msk;
- unsigned int idx;
- struct pvr2_i2c_client *cp, *ncp;
-
- if (!hdw->i2c_linked) return;
- if (!(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL)) {
- return;
- }
- mutex_lock(&hdw->i2c_list_lock); do {
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync BEGIN");
- if (hdw->i2c_pend_types & PVR2_I2C_PEND_DETECT) {
- /* One or more I2C clients have attached since we
- last synced. So scan the list and identify the
- new clients. */
- char *buf;
- unsigned int cnt;
- unsigned long amask = 0;
- buf = kmalloc(BUFSIZE,GFP_KERNEL);
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_DETECT");
- hdw->i2c_pend_types &= ~PVR2_I2C_PEND_DETECT;
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- if (!cp->detected_flag) {
- cp->ctl_mask = 0;
- pvr2_i2c_probe(hdw,cp);
- cp->detected_flag = !0;
- msk = cp->ctl_mask;
- cnt = 0;
- if (buf) {
- cnt = pvr2_i2c_client_describe(
- cp,
- PVR2_I2C_DETAIL_ALL,
- buf,BUFSIZE);
- }
- trace_i2c("Probed: %.*s",cnt,buf);
- if (handler_check(cp)) {
- hdw->i2c_pend_types |=
- PVR2_I2C_PEND_CLIENT;
- }
- cp->pend_mask = msk;
- hdw->i2c_pend_mask |= msk;
- hdw->i2c_pend_types |=
- PVR2_I2C_PEND_REFRESH;
- }
- amask |= cp->ctl_mask;
- }
- hdw->i2c_active_mask = amask;
- if (buf) kfree(buf);
- }
- if (hdw->i2c_pend_types & PVR2_I2C_PEND_STALE) {
- /* Need to do one or more global updates. Arrange
- for this to happen. */
- unsigned long m2;
- pvr2_trace(PVR2_TRACE_I2C_CORE,
- "i2c: PEND_STALE (0x%lx)",
- hdw->i2c_stale_mask);
- hdw->i2c_pend_types &= ~PVR2_I2C_PEND_STALE;
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- m2 = hdw->i2c_stale_mask;
- m2 &= cp->ctl_mask;
- m2 &= ~cp->pend_mask;
- if (m2) {
- pvr2_trace(PVR2_TRACE_I2C_CORE,
- "i2c: cp=%p setting 0x%lx",
- cp,m2);
- cp->pend_mask |= m2;
- }
- }
- hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
- hdw->i2c_stale_mask = 0;
- hdw->i2c_pend_types |= PVR2_I2C_PEND_REFRESH;
- }
- if (hdw->i2c_pend_types & PVR2_I2C_PEND_CLIENT) {
- /* One or more client handlers are asking for an
- update. Run through the list of known clients
- and update each one. */
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_CLIENT");
- hdw->i2c_pend_types &= ~PVR2_I2C_PEND_CLIENT;
- list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients,
- list) {
- if (!cp->handler) continue;
- if (!cp->handler->func_table->update) continue;
- pvr2_trace(PVR2_TRACE_I2C_CORE,
- "i2c: cp=%p update",cp);
- mutex_unlock(&hdw->i2c_list_lock);
- cp->handler->func_table->update(
- cp->handler->func_data);
- mutex_lock(&hdw->i2c_list_lock);
- /* If client's update function set some
- additional pending bits, account for that
- here. */
- if (cp->pend_mask & ~hdw->i2c_pend_mask) {
- hdw->i2c_pend_mask |= cp->pend_mask;
- hdw->i2c_pend_types |=
- PVR2_I2C_PEND_REFRESH;
- }
- }
- }
- if (hdw->i2c_pend_types & PVR2_I2C_PEND_REFRESH) {
- const struct pvr2_i2c_op *opf;
- unsigned long pm;
- /* Some actual updates are pending. Walk through
- each update type and perform it. */
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_REFRESH"
- " (0x%lx)",hdw->i2c_pend_mask);
- hdw->i2c_pend_types &= ~PVR2_I2C_PEND_REFRESH;
- pm = hdw->i2c_pend_mask;
- hdw->i2c_pend_mask = 0;
- for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
- if (!(pm & msk)) continue;
- pm &= ~msk;
- list_for_each_entry(cp, &hdw->i2c_clients,
- list) {
- if (cp->pend_mask & msk) {
- cp->pend_mask &= ~msk;
- cp->recv_enable = !0;
- } else {
- cp->recv_enable = 0;
- }
- }
- opf = pvr2_i2c_get_op(idx);
- if (!opf) continue;
- mutex_unlock(&hdw->i2c_list_lock);
- opf->update(hdw);
- mutex_lock(&hdw->i2c_list_lock);
- }
- }
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync END");
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
-}
-
-int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw)
-{
- unsigned long msk,sm,pm;
- unsigned int idx;
- const struct pvr2_i2c_op *opf;
- struct pvr2_i2c_client *cp;
- unsigned int pt = 0;
-
- pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale BEGIN");
-
- pm = hdw->i2c_active_mask;
- sm = 0;
- for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
- if (!(msk & pm)) continue;
- pm &= ~msk;
- opf = pvr2_i2c_get_op(idx);
- if (!opf) continue;
- if (opf->check(hdw)) {
- sm |= msk;
- }
- }
- if (sm) pt |= PVR2_I2C_PEND_STALE;
-
- list_for_each_entry(cp, &hdw->i2c_clients, list)
- if (handler_check(cp))
- pt |= PVR2_I2C_PEND_CLIENT;
-
- if (pt) {
- mutex_lock(&hdw->i2c_list_lock); do {
- hdw->i2c_pend_types |= pt;
- hdw->i2c_stale_mask |= sm;
- hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
- }
-
- pvr2_trace(PVR2_TRACE_I2C_CORE,
- "i2c: types=0x%x stale=0x%lx pend=0x%lx",
- hdw->i2c_pend_types,
- hdw->i2c_stale_mask,
- hdw->i2c_pend_mask);
- pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale END");
-
- return (hdw->i2c_pend_types & PVR2_I2C_PEND_ALL) != 0;
-}
-
-static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
- unsigned int detail,
- char *buf,unsigned int maxlen)
-{
- unsigned int ccnt,bcnt;
- int spcfl = 0;
- const struct pvr2_i2c_op *opf;
-
- ccnt = 0;
- if (detail & PVR2_I2C_DETAIL_DEBUG) {
- bcnt = scnprintf(buf,maxlen,
- "ctxt=%p ctl_mask=0x%lx",
- cp,cp->ctl_mask);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- spcfl = !0;
- }
- bcnt = scnprintf(buf,maxlen,
- "%s%s @ 0x%x",
- (spcfl ? " " : ""),
- cp->client->name,
- cp->client->addr);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- if ((detail & PVR2_I2C_DETAIL_HANDLER) &&
- cp->handler && cp->handler->func_table->describe) {
- bcnt = scnprintf(buf,maxlen," (");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- bcnt = cp->handler->func_table->describe(
- cp->handler->func_data,buf,maxlen);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- bcnt = scnprintf(buf,maxlen,")");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- }
- if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) {
- unsigned int idx;
- unsigned long msk,sm;
-
- bcnt = scnprintf(buf,maxlen," [");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- sm = 0;
- spcfl = 0;
- for (idx = 0, msk = 1; msk; idx++, msk <<= 1) {
- if (!(cp->ctl_mask & msk)) continue;
- opf = pvr2_i2c_get_op(idx);
- if (opf) {
- bcnt = scnprintf(buf,maxlen,"%s%s",
- spcfl ? " " : "",
- opf->name);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- spcfl = !0;
- } else {
- sm |= msk;
- }
- }
- if (sm) {
- bcnt = scnprintf(buf,maxlen,"%s%lx",
- idx != 0 ? " " : "",sm);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- }
- bcnt = scnprintf(buf,maxlen,"]");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- }
- return ccnt;
-}
-
-unsigned int pvr2_i2c_report(struct pvr2_hdw *hdw,
- char *buf,unsigned int maxlen)
-{
- unsigned int ccnt,bcnt;
- struct pvr2_i2c_client *cp;
- ccnt = 0;
- mutex_lock(&hdw->i2c_list_lock); do {
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- bcnt = pvr2_i2c_client_describe(
- cp,
- (PVR2_I2C_DETAIL_HANDLER|
- PVR2_I2C_DETAIL_CTLMASK),
- buf,maxlen);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- bcnt = scnprintf(buf,maxlen,"\n");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- }
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
- return ccnt;
-}
-
static int pvr2_i2c_attach_inform(struct i2c_client *client)
{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
- struct pvr2_i2c_client *cp;
- int fl = !(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL);
- cp = kzalloc(sizeof(*cp),GFP_KERNEL);
- trace_i2c("i2c_attach [client=%s @ 0x%x ctxt=%p]",
- client->name,
- client->addr,cp);
- if (!cp) return -ENOMEM;
- cp->hdw = hdw;
- INIT_LIST_HEAD(&cp->list);
- cp->client = client;
- mutex_lock(&hdw->i2c_list_lock); do {
- hdw->cropcap_stale = !0;
- list_add_tail(&cp->list,&hdw->i2c_clients);
- hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT;
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
- if (fl) queue_work(hdw->workqueue,&hdw->worki2csync);
return 0;
}
static int pvr2_i2c_detach_inform(struct i2c_client *client)
{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
- struct pvr2_i2c_client *cp, *ncp;
- unsigned long amask = 0;
- int foundfl = 0;
- mutex_lock(&hdw->i2c_list_lock); do {
- hdw->cropcap_stale = !0;
- list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
- if (cp->client == client) {
- trace_i2c("pvr2_i2c_detach"
- " [client=%s @ 0x%x ctxt=%p]",
- client->name,
- client->addr,cp);
- if (cp->handler &&
- cp->handler->func_table->detach) {
- cp->handler->func_table->detach(
- cp->handler->func_data);
- }
- list_del(&cp->list);
- kfree(cp);
- foundfl = !0;
- continue;
- }
- amask |= cp->ctl_mask;
- }
- hdw->i2c_active_mask = amask;
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
- if (!foundfl) {
- trace_i2c("pvr2_i2c_detach [client=%s @ 0x%x ctxt=<unknown>]",
- client->name,
- client->addr);
- }
return 0;
}
@@ -942,7 +537,7 @@ static struct i2c_algorithm pvr2_i2c_algo_template = {
static struct i2c_adapter pvr2_i2c_adap_template = {
.owner = THIS_MODULE,
- .class = I2C_CLASS_TV_ANALOG,
+ .class = 0,
.id = I2C_HW_B_BT848,
.client_register = pvr2_i2c_attach_inform,
.client_unregister = pvr2_i2c_detach_inform,
@@ -1009,12 +604,8 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
hdw->i2c_adap.algo = &hdw->i2c_algo;
hdw->i2c_adap.algo_data = hdw;
- hdw->i2c_pend_mask = 0;
- hdw->i2c_stale_mask = 0;
- hdw->i2c_active_mask = 0;
- INIT_LIST_HEAD(&hdw->i2c_clients);
- mutex_init(&hdw->i2c_list_lock);
hdw->i2c_linked = !0;
+ i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev);
i2c_add_adapter(&hdw->i2c_adap);
if (hdw->i2c_func[0x18] == i2c_24xxx_ir) {
/* Probe for a different type of IR receiver on this
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
index 6ef7a1c0e935..6a75769200bd 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
@@ -20,68 +20,13 @@
#ifndef __PVRUSB2_I2C_CORE_H
#define __PVRUSB2_I2C_CORE_H
-#include <linux/list.h>
-#include <linux/i2c.h>
-
struct pvr2_hdw;
-struct pvr2_i2c_client;
-struct pvr2_i2c_handler;
-struct pvr2_i2c_handler_functions;
-struct pvr2_i2c_op;
-struct pvr2_i2c_op_functions;
-
-struct pvr2_i2c_client {
- struct i2c_client *client;
- struct pvr2_i2c_handler *handler;
- struct list_head list;
- struct pvr2_hdw *hdw;
- int detected_flag;
- int recv_enable;
- unsigned long pend_mask;
- unsigned long ctl_mask;
- void (*status_poll)(struct pvr2_i2c_client *);
-};
-
-struct pvr2_i2c_handler {
- void *func_data;
- const struct pvr2_i2c_handler_functions *func_table;
-};
-
-struct pvr2_i2c_handler_functions {
- void (*detach)(void *);
- int (*check)(void *);
- void (*update)(void *);
- unsigned int (*describe)(void *,char *,unsigned int);
-};
-
-struct pvr2_i2c_op {
- int (*check)(struct pvr2_hdw *);
- void (*update)(struct pvr2_hdw *);
- const char *name;
-};
void pvr2_i2c_core_init(struct pvr2_hdw *);
void pvr2_i2c_core_done(struct pvr2_hdw *);
-int pvr2_i2c_client_cmd(struct pvr2_i2c_client *,unsigned int cmd,void *arg);
-int pvr2_i2c_core_cmd(struct pvr2_hdw *,unsigned int cmd,void *arg);
-
-int pvr2_i2c_core_check_stale(struct pvr2_hdw *);
-void pvr2_i2c_core_sync(struct pvr2_hdw *);
-void pvr2_i2c_core_status_poll(struct pvr2_hdw *);
-unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen);
-#define PVR2_I2C_DETAIL_DEBUG 0x0001
-#define PVR2_I2C_DETAIL_HANDLER 0x0002
-#define PVR2_I2C_DETAIL_CTLMASK 0x0004
-#define PVR2_I2C_DETAIL_ALL (\
- PVR2_I2C_DETAIL_DEBUG |\
- PVR2_I2C_DETAIL_HANDLER |\
- PVR2_I2C_DETAIL_CTLMASK)
-
-void pvr2_i2c_probe(struct pvr2_hdw *,struct pvr2_i2c_client *);
-const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx);
-#endif /* __PVRUSB2_I2C_CORE_H */
+#endif /* __PVRUSB2_I2C_ADAPTER_H */
/*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
index 9b3c874d96d6..8689ddb54420 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -137,10 +137,10 @@ static int __init pvr_init(void)
ret = usb_register(&pvr_driver);
if (ret == 0)
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ printk(KERN_INFO "pvrusb2: " DRIVER_VERSION ":"
DRIVER_DESC "\n");
if (pvrusb2_debug)
- printk(KERN_INFO KBUILD_MODNAME ": Debug mask is %d (0x%x)\n",
+ printk(KERN_INFO "pvrusb2: Debug mask is %d (0x%x)\n",
pvrusb2_debug,pvrusb2_debug);
pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete");
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index e641cd971453..e20ba1e6e0ea 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -627,16 +627,8 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
class_dev->class = &class_ptr->class;
- if (pvr2_hdw_get_sn(sfp->channel.hdw)) {
- dev_set_name(class_dev, "sn-%lu",
- pvr2_hdw_get_sn(sfp->channel.hdw));
- } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) {
- dev_set_name(class_dev, "unit-%c",
- pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a');
- } else {
- kfree(class_dev);
- return;
- }
+ dev_set_name(class_dev, "%s",
+ pvr2_hdw_get_device_identifier(sfp->channel.hdw));
class_dev->parent = &usb_dev->dev;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.c b/drivers/media/video/pvrusb2/pvrusb2-tuner.c
deleted file mode 100644
index 07775d1aad4e..000000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-tuner.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include "pvrusb2.h"
-#include "pvrusb2-util.h"
-#include "pvrusb2-tuner.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include <linux/videodev2.h>
-#include <media/tuner.h>
-#include <media/v4l2-common.h>
-
-struct pvr2_tuner_handler {
- struct pvr2_hdw *hdw;
- struct pvr2_i2c_client *client;
- struct pvr2_i2c_handler i2c_handler;
- int type_update_fl;
-};
-
-
-static void set_type(struct pvr2_tuner_handler *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- struct tuner_setup setup;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c tuner set_type(%d)",hdw->tuner_type);
- if (((int)(hdw->tuner_type)) < 0) return;
-
- setup.addr = ADDR_UNSET;
- setup.type = hdw->tuner_type;
- setup.mode_mask = T_RADIO | T_ANALOG_TV;
- /* We may really want mode_mask to be T_ANALOG_TV for now */
- pvr2_i2c_client_cmd(ctxt->client,TUNER_SET_TYPE_ADDR,&setup);
- ctxt->type_update_fl = 0;
-}
-
-
-static int tuner_check(struct pvr2_tuner_handler *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- if (hdw->tuner_updated) ctxt->type_update_fl = !0;
- return ctxt->type_update_fl != 0;
-}
-
-
-static void tuner_update(struct pvr2_tuner_handler *ctxt)
-{
- if (ctxt->type_update_fl) set_type(ctxt);
-}
-
-
-static void pvr2_tuner_detach(struct pvr2_tuner_handler *ctxt)
-{
- ctxt->client->handler = NULL;
- kfree(ctxt);
-}
-
-
-static unsigned int pvr2_tuner_describe(struct pvr2_tuner_handler *ctxt,char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-tuner");
-}
-
-
-static const struct pvr2_i2c_handler_functions tuner_funcs = {
- .detach = (void (*)(void *))pvr2_tuner_detach,
- .check = (int (*)(void *))tuner_check,
- .update = (void (*)(void *))tuner_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_tuner_describe,
-};
-
-
-int pvr2_i2c_tuner_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
- struct pvr2_tuner_handler *ctxt;
- if (cp->handler) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->i2c_handler.func_data = ctxt;
- ctxt->i2c_handler.func_table = &tuner_funcs;
- ctxt->type_update_fl = !0;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- cp->handler = &ctxt->i2c_handler;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tuner handler set up",
- cp->client->addr);
- return !0;
-}
-
-
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 878fd52a73b3..9e0f2b07b93b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -91,7 +91,7 @@ static struct v4l2_capability pvr_capability ={
.card = "Hauppauge WinTV pvr-usb2",
.bus_info = "usb",
.version = KERNEL_VERSION(0,8,0),
- .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
+ .capabilities = (V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
V4L2_CAP_READWRITE),
.reserved = {0,0,0,0}
@@ -952,10 +952,6 @@ static long pvr2_v4l2_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
-/* Temporary hack : use ivtv api until a v4l2 one is available. */
-#define IVTV_IOC_G_CODEC 0xFFEE7703
-#define IVTV_IOC_S_CODEC 0xFFEE7704
- if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0;
return video_usercopy(file, cmd, arg, pvr2_v4l2_do_ioctl);
}
@@ -1268,8 +1264,9 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
dip->minor_type = pvr2_v4l_type_video;
nr_ptr = video_nr;
if (!dip->stream) {
- err("Failed to set up pvrusb2 v4l video dev"
- " due to missing stream instance");
+ pr_err(KBUILD_MODNAME
+ ": Failed to set up pvrusb2 v4l video dev"
+ " due to missing stream instance\n");
return;
}
break;
@@ -1286,8 +1283,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
break;
default:
/* Bail out (this should be impossible) */
- err("Failed to set up pvrusb2 v4l dev"
- " due to unrecognized config");
+ pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev"
+ " due to unrecognized config\n");
return;
}
@@ -1303,7 +1300,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
dip->v4l_type, mindevnum) < 0) &&
(video_register_device(&dip->devbase,
dip->v4l_type, -1) < 0)) {
- err("Failed to register pvrusb2 v4l device");
+ pr_err(KBUILD_MODNAME
+ ": Failed to register pvrusb2 v4l device\n");
}
printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n",
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index 4059648c7056..b3862f5554bd 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -28,7 +28,7 @@
*/
#include "pvrusb2-video-v4l.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
+
#include "pvrusb2-hdw-internal.h"
@@ -39,15 +39,6 @@
#include <linux/errno.h>
#include <linux/slab.h>
-struct pvr2_v4l_decoder {
- struct pvr2_i2c_handler handler;
- struct pvr2_decoder_ctrl ctrl;
- struct pvr2_i2c_client *client;
- struct pvr2_hdw *hdw;
- unsigned long stale_mask;
-};
-
-
struct routing_scheme {
const int *def;
unsigned int cnt;
@@ -63,190 +54,51 @@ static const int routing_scheme0[] = {
[PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2,
};
+static const int routing_scheme1[] = {
+ [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4,
+ [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5,
+ [PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE3,
+ [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, /* or SVIDEO0, it seems */
+};
+
static const struct routing_scheme routing_schemes[] = {
[PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
.def = routing_scheme0,
.cnt = ARRAY_SIZE(routing_scheme0),
},
+ [PVR2_ROUTING_SCHEME_ONAIR] = {
+ .def = routing_scheme1,
+ .cnt = ARRAY_SIZE(routing_scheme1),
+ },
};
-static void set_input(struct pvr2_v4l_decoder *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- struct v4l2_routing route;
- const struct routing_scheme *sp;
- unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val);
-
- if ((sid < ARRAY_SIZE(routing_schemes)) &&
- ((sp = routing_schemes + sid) != NULL) &&
- (hdw->input_val >= 0) &&
- (hdw->input_val < sp->cnt)) {
- route.input = sp->def[hdw->input_val];
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "*** WARNING *** i2c v4l2 set_input:"
- " Invalid routing scheme (%u) and/or input (%d)",
- sid,hdw->input_val);
- return;
- }
-
- route.output = 0;
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
-}
-
-
-static int check_input(struct pvr2_v4l_decoder *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->input_dirty != 0;
-}
-
-
-static void set_audio(struct pvr2_v4l_decoder *ctxt)
-{
- u32 val;
- struct pvr2_hdw *hdw = ctxt->hdw;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_audio %d",
- hdw->srate_val);
- switch (hdw->srate_val) {
- default:
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
- val = 48000;
- break;
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
- val = 44100;
- break;
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
- val = 32000;
- break;
- }
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
-}
-
-
-static int check_audio(struct pvr2_v4l_decoder *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->srate_dirty != 0;
-}
-
-
-struct pvr2_v4l_decoder_ops {
- void (*update)(struct pvr2_v4l_decoder *);
- int (*check)(struct pvr2_v4l_decoder *);
-};
-
-
-static const struct pvr2_v4l_decoder_ops decoder_ops[] = {
- { .update = set_input, .check = check_input},
- { .update = set_audio, .check = check_audio},
-};
-
-
-static void decoder_detach(struct pvr2_v4l_decoder *ctxt)
+void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
- ctxt->client->handler = NULL;
- pvr2_hdw_set_decoder(ctxt->hdw,NULL);
- kfree(ctxt);
-}
-
-
-static int decoder_check(struct pvr2_v4l_decoder *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
- msk = 1 << idx;
- if (ctxt->stale_mask & msk) continue;
- if (decoder_ops[idx].check(ctxt)) {
- ctxt->stale_mask |= msk;
+ if (hdw->input_dirty || hdw->force_dirty) {
+ struct v4l2_routing route;
+ const struct routing_scheme *sp;
+ unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
+ hdw->input_val);
+ if ((sid < ARRAY_SIZE(routing_schemes)) &&
+ ((sp = routing_schemes + sid) != NULL) &&
+ (hdw->input_val >= 0) &&
+ (hdw->input_val < sp->cnt)) {
+ route.input = sp->def[hdw->input_val];
+ } else {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "*** WARNING *** subdev v4l2 set_input:"
+ " Invalid routing scheme (%u)"
+ " and/or input (%d)",
+ sid, hdw->input_val);
+ return;
}
+ route.output = 0;
+ sd->ops->video->s_routing(sd, &route);
}
- return ctxt->stale_mask != 0;
-}
-
-
-static void decoder_update(struct pvr2_v4l_decoder *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
- msk = 1 << idx;
- if (!(ctxt->stale_mask & msk)) continue;
- ctxt->stale_mask &= ~msk;
- decoder_ops[idx].update(ctxt);
- }
-}
-
-
-static int decoder_detect(struct pvr2_i2c_client *cp)
-{
- /* Attempt to query the decoder - let's see if it will answer */
- struct v4l2_tuner vt;
- int ret;
-
- memset(&vt,0,sizeof(vt));
- ret = pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&vt);
- return ret == 0; /* Return true if it answered */
-}
-
-
-static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl)
-{
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl);
- pvr2_v4l2_cmd_stream(ctxt->client,fl);
-}
-
-
-static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l");
-}
-
-
-static const struct pvr2_i2c_handler_functions hfuncs = {
- .detach = (void (*)(void *))decoder_detach,
- .check = (int (*)(void *))decoder_check,
- .update = (void (*)(void *))decoder_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
-};
-
-
-int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw,
- struct pvr2_i2c_client *cp)
-{
- struct pvr2_v4l_decoder *ctxt;
-
- if (hdw->decoder_ctrl) return 0;
- if (cp->handler) return 0;
- if (!decoder_detect(cp)) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->handler.func_data = ctxt;
- ctxt->handler.func_table = &hfuncs;
- ctxt->ctrl.ctxt = ctxt;
- ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
- ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1;
- pvr2_hdw_set_decoder(hdw,&ctxt->ctrl);
- cp->handler = &ctxt->handler;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up",
- cp->client->addr);
- return !0;
}
-
-
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
*** Local Variables: ***
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
index 4ff5b892b303..3b0bd5db602b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
@@ -32,11 +32,8 @@
*/
-
-#include "pvrusb2-i2c-core.h"
-
-int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
-
+#include "pvrusb2-hdw-internal.h"
+void pvr2_saa7115_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
#endif /* __PVRUSB2_VIDEO_V4L_H */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
index f6fcf0ac6118..1670aa4051ce 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
@@ -27,7 +27,6 @@
*/
#include "pvrusb2-wm8775.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
#include "pvrusb2-hdw-internal.h"
@@ -37,128 +36,31 @@
#include <linux/errno.h>
#include <linux/slab.h>
-struct pvr2_v4l_wm8775 {
- struct pvr2_i2c_handler handler;
- struct pvr2_i2c_client *client;
- struct pvr2_hdw *hdw;
- unsigned long stale_mask;
-};
-
-
-static void set_input(struct pvr2_v4l_wm8775 *ctxt)
-{
- struct v4l2_routing route;
- struct pvr2_hdw *hdw = ctxt->hdw;
-
- memset(&route,0,sizeof(route));
-
- switch(hdw->input_val) {
- case PVR2_CVAL_INPUT_RADIO:
- route.input = 1;
- break;
- default:
- /* All other cases just use the second input */
- route.input = 2;
- break;
- }
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c wm8775 set_input(val=%d route=0x%x)",
- hdw->input_val,route.input);
-
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
-}
-
-static int check_input(struct pvr2_v4l_wm8775 *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->input_dirty != 0;
-}
-
-
-struct pvr2_v4l_wm8775_ops {
- void (*update)(struct pvr2_v4l_wm8775 *);
- int (*check)(struct pvr2_v4l_wm8775 *);
-};
-
-
-static const struct pvr2_v4l_wm8775_ops wm8775_ops[] = {
- { .update = set_input, .check = check_input},
-};
-
-
-static unsigned int wm8775_describe(struct pvr2_v4l_wm8775 *ctxt,
- char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-wm8775");
-}
-
-
-static void wm8775_detach(struct pvr2_v4l_wm8775 *ctxt)
+void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
- ctxt->client->handler = NULL;
- kfree(ctxt);
-}
-
-
-static int wm8775_check(struct pvr2_v4l_wm8775 *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) {
- msk = 1 << idx;
- if (ctxt->stale_mask & msk) continue;
- if (wm8775_ops[idx].check(ctxt)) {
- ctxt->stale_mask |= msk;
+ if (hdw->input_dirty || hdw->force_dirty) {
+ struct v4l2_routing route;
+
+ memset(&route, 0, sizeof(route));
+
+ switch (hdw->input_val) {
+ case PVR2_CVAL_INPUT_RADIO:
+ route.input = 1;
+ break;
+ default:
+ /* All other cases just use the second input */
+ route.input = 2;
+ break;
}
- }
- return ctxt->stale_mask != 0;
-}
-
-
-static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev wm8775"
+ " set_input(val=%d route=0x%x)",
+ hdw->input_val, route.input);
- for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) {
- msk = 1 << idx;
- if (!(ctxt->stale_mask & msk)) continue;
- ctxt->stale_mask &= ~msk;
- wm8775_ops[idx].update(ctxt);
+ sd->ops->audio->s_routing(sd, &route);
}
}
-static const struct pvr2_i2c_handler_functions hfuncs = {
- .detach = (void (*)(void *))wm8775_detach,
- .check = (int (*)(void *))wm8775_check,
- .update = (void (*)(void *))wm8775_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))wm8775_describe,
-};
-
-
-int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
- struct pvr2_v4l_wm8775 *ctxt;
-
- if (cp->handler) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->handler.func_data = ctxt;
- ctxt->handler.func_table = &hfuncs;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- ctxt->stale_mask = (1 << ARRAY_SIZE(wm8775_ops)) - 1;
- cp->handler = &ctxt->handler;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x wm8775 V4L2 handler set up",
- cp->client->addr);
- return !0;
-}
-
-
-
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
index 807090961255..0577bc7246fb 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
@@ -34,9 +34,9 @@
-#include "pvrusb2-i2c-core.h"
+#include "pvrusb2-hdw-internal.h"
-int pvr2_i2c_wm8775_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
+void pvr2_wm8775_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);
#endif /* __PVRUSB2_WM8775_H */
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig
index 7298cf2e1650..8b9f0aa844a1 100644
--- a/drivers/media/video/pwc/Kconfig
+++ b/drivers/media/video/pwc/Kconfig
@@ -35,3 +35,13 @@ config USB_PWC_DEBUG
Say Y here in order to have the pwc driver generate verbose debugging
messages.
A special module options 'trace' is used to control the verbosity.
+
+config USB_PWC_INPUT_EVDEV
+ bool "USB Philips Cameras input events device support"
+ default y
+ depends on USB_PWC && INPUT
+ ---help---
+ This option makes USB Philips cameras register the snapshot button as
+ an input device to report button events.
+
+ If you are in doubt, say Y.
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 0d810189dd87..7c542caf248e 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -53,6 +53,7 @@
- Xavier Roche: QuickCam Pro 4000 ID
- Jens Knudsen: QuickCam Zoom ID
- J. Debert: QuickCam for Notebooks ID
+ - Pham Thanh Nam: webcam snapshot button as an event input device
*/
#include <linux/errno.h>
@@ -61,6 +62,9 @@
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+#include <linux/usb/input.h>
+#endif
#include <linux/vmalloc.h>
#include <asm/io.h>
@@ -586,6 +590,23 @@ static void pwc_frame_dumped(struct pwc_device *pdev)
pdev->vframe_count);
}
+static void pwc_snapshot_button(struct pwc_device *pdev, int down)
+{
+ if (down) {
+ PWC_TRACE("Snapshot button pressed.\n");
+ pdev->snapshot_button_status = 1;
+ } else {
+ PWC_TRACE("Snapshot button released.\n");
+ }
+
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ if (pdev->button_dev) {
+ input_report_key(pdev->button_dev, BTN_0, down);
+ input_sync(pdev->button_dev);
+ }
+#endif
+}
+
static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_buf *fbuf)
{
int awake = 0;
@@ -603,13 +624,7 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_
pdev->vframes_error++;
}
if ((ptr[0] ^ pdev->vmirror) & 0x01) {
- if (ptr[0] & 0x01) {
- pdev->snapshot_button_status = 1;
- PWC_TRACE("Snapshot button pressed.\n");
- }
- else {
- PWC_TRACE("Snapshot button released.\n");
- }
+ pwc_snapshot_button(pdev, ptr[0] & 0x01);
}
if ((ptr[0] ^ pdev->vmirror) & 0x02) {
if (ptr[0] & 0x02)
@@ -633,12 +648,7 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_
else if (pdev->type == 740 || pdev->type == 720) {
unsigned char *ptr = (unsigned char *)fbuf->data;
if ((ptr[0] ^ pdev->vmirror) & 0x01) {
- if (ptr[0] & 0x01) {
- pdev->snapshot_button_status = 1;
- PWC_TRACE("Snapshot button pressed.\n");
- }
- else
- PWC_TRACE("Snapshot button released.\n");
+ pwc_snapshot_button(pdev, ptr[0] & 0x01);
}
pdev->vmirror = ptr[0] & 0x03;
}
@@ -1115,6 +1125,7 @@ static int pwc_video_open(struct file *file)
}
mutex_lock(&pdev->modlock);
+ pwc_construct(pdev); /* set min/max sizes correct */
if (!pdev->usb_init) {
PWC_DEBUG_OPEN("Doing first time initialization.\n");
pdev->usb_init = 1;
@@ -1139,7 +1150,6 @@ static int pwc_video_open(struct file *file)
if (pwc_set_leds(pdev, led_on, led_off) < 0)
PWC_DEBUG_OPEN("Failed to set LED on/off time.\n");
- pwc_construct(pdev); /* set min/max sizes correct */
/* So far, so good. Allocate memory. */
i = pwc_allocate_buffers(pdev);
@@ -1216,6 +1226,15 @@ static void pwc_cleanup(struct pwc_device *pdev)
{
pwc_remove_sysfs_files(pdev->vdev);
video_unregister_device(pdev->vdev);
+
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ if (pdev->button_dev) {
+ input_unregister_device(pdev->button_dev);
+ input_free_device(pdev->button_dev);
+ kfree(pdev->button_dev->phys);
+ pdev->button_dev = NULL;
+ }
+#endif
}
/* Note that all cleanup is done in the reverse order as in _open */
@@ -1483,6 +1502,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
int features = 0;
int video_nr = -1; /* default: use next available device */
char serial_number[30], *name;
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ char *phys = NULL;
+#endif
vendor_id = le16_to_cpu(udev->descriptor.idVendor);
product_id = le16_to_cpu(udev->descriptor.idProduct);
@@ -1807,6 +1829,35 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
pwc_set_leds(pdev, 0, 0);
pwc_camera_power(pdev, 0);
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ /* register webcam snapshot button input device */
+ pdev->button_dev = input_allocate_device();
+ if (!pdev->button_dev) {
+ PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
+ return -ENOMEM;
+ }
+
+ pdev->button_dev->name = "PWC snapshot button";
+ phys = kasprintf(GFP_KERNEL,"usb-%s-%s", pdev->udev->bus->bus_name, pdev->udev->devpath);
+ if (!phys) {
+ input_free_device(pdev->button_dev);
+ return -ENOMEM;
+ }
+ pdev->button_dev->phys = phys;
+ usb_to_input_id(pdev->udev, &pdev->button_dev->id);
+ pdev->button_dev->dev.parent = &pdev->udev->dev;
+ pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
+ pdev->button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
+
+ rc = input_register_device(pdev->button_dev);
+ if (rc) {
+ input_free_device(pdev->button_dev);
+ kfree(pdev->button_dev->phys);
+ pdev->button_dev = NULL;
+ return rc;
+ }
+#endif
+
return 0;
err_unreg:
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 01411fb2337a..0be6f814f539 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -37,6 +37,9 @@
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+#include <linux/input.h>
+#endif
#include "pwc-uncompress.h"
#include <media/pwc-ioctl.h>
@@ -255,6 +258,9 @@ struct pwc_device
int pan_angle; /* in degrees * 100 */
int tilt_angle; /* absolute angle; 0,0 is home position */
int snapshot_button_status; /* set to 1 when the user push the button, reset to 0 when this value is read */
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ struct input_dev *button_dev; /* webcam snapshot button input */
+#endif
/*** Misc. data ***/
wait_queue_head_t frameq; /* When waiting for a frame to finish... */
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 07c334f25aae..c522616ef38f 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -35,7 +35,6 @@
#include <linux/videodev2.h>
#include <mach/dma.h>
-#include <mach/pxa-regs.h>
#include <mach/camera.h>
#define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5)
@@ -879,6 +878,7 @@ static int test_platform_param(struct pxa_camera_dev *pcdev,
SOCAM_HSYNC_ACTIVE_LOW |
SOCAM_VSYNC_ACTIVE_HIGH |
SOCAM_VSYNC_ACTIVE_LOW |
+ SOCAM_DATA_ACTIVE_HIGH |
SOCAM_PCLK_SAMPLE_RISING |
SOCAM_PCLK_SAMPLE_FALLING;
@@ -1150,8 +1150,43 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
return formats;
}
+static int pxa_camera_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct pxa_camera_dev *pcdev = ici->priv;
+ struct soc_camera_sense sense = {
+ .master_clock = pcdev->mclk,
+ .pixel_clock_max = pcdev->ciclk / 4,
+ };
+ int ret;
+
+ /* If PCLK is used to latch data from the sensor, check sense */
+ if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
+ icd->sense = &sense;
+
+ ret = icd->ops->set_crop(icd, rect);
+
+ icd->sense = NULL;
+
+ if (ret < 0) {
+ dev_warn(&ici->dev, "Failed to crop to %ux%u@%u:%u\n",
+ rect->width, rect->height, rect->left, rect->top);
+ } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
+ if (sense.pixel_clock > sense.pixel_clock_max) {
+ dev_err(&ici->dev,
+ "pixel clock %lu set by the camera too high!",
+ sense.pixel_clock);
+ return -EIO;
+ }
+ recalculate_fifo_timeout(pcdev, sense.pixel_clock);
+ }
+
+ return ret;
+}
+
static int pxa_camera_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+ struct v4l2_format *f)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct pxa_camera_dev *pcdev = ici->priv;
@@ -1161,35 +1196,30 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
.master_clock = pcdev->mclk,
.pixel_clock_max = pcdev->ciclk / 4,
};
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct v4l2_format cam_f = *f;
int ret;
- if (pixfmt) {
- xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
- if (!xlate) {
- dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
- return -EINVAL;
- }
-
- cam_fmt = xlate->cam_fmt;
+ xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
+ if (!xlate) {
+ dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+ return -EINVAL;
}
+ cam_fmt = xlate->cam_fmt;
+
/* If PCLK is used to latch data from the sensor, check sense */
if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
icd->sense = &sense;
- switch (pixfmt) {
- case 0: /* Only geometry change */
- ret = icd->ops->set_fmt(icd, pixfmt, rect);
- break;
- default:
- ret = icd->ops->set_fmt(icd, cam_fmt->fourcc, rect);
- }
+ cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
+ ret = icd->ops->set_fmt(icd, &cam_f);
icd->sense = NULL;
if (ret < 0) {
dev_warn(&ici->dev, "Failed to configure for format %x\n",
- pixfmt);
+ pix->pixelformat);
} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
if (sense.pixel_clock > sense.pixel_clock_max) {
dev_err(&ici->dev,
@@ -1200,7 +1230,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
recalculate_fifo_timeout(pcdev, sense.pixel_clock);
}
- if (pixfmt && !ret) {
+ if (!ret) {
icd->buswidth = xlate->buswidth;
icd->current_fmt = xlate->host_fmt;
}
@@ -1364,6 +1394,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
.remove = pxa_camera_remove_device,
.suspend = pxa_camera_suspend,
.resume = pxa_camera_resume,
+ .set_crop = pxa_camera_set_crop,
.get_formats = pxa_camera_get_formats,
.set_fmt = pxa_camera_set_fmt,
.try_fmt = pxa_camera_try_fmt,
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 13f85ad363cd..b5be633e3bb0 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -336,14 +336,19 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
u16 index, u16 value, void *buf,
s32 buf_len, int bOut);
+/* dev_err macro with driver name */
+#define S2255_DRIVER_NAME "s2255"
+#define s2255_dev_err(dev, fmt, arg...) \
+ dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
+
#define dprintk(level, fmt, arg...) \
do { \
if (*s2255_debug >= (level)) { \
- printk(KERN_DEBUG "s2255: " fmt, ##arg); \
+ printk(KERN_DEBUG S2255_DRIVER_NAME \
+ ": " fmt, ##arg); \
} \
} while (0)
-
static struct usb_driver s2255_driver;
@@ -528,14 +533,14 @@ static void s2255_fwchunk_complete(struct urb *urb)
int len;
dprintk(100, "udev %p urb %p", udev, urb);
if (urb->status) {
- dev_err(&udev->dev, "URB failed with status %d", urb->status);
+ dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
atomic_set(&data->fw_state, S2255_FW_FAILED);
/* wake up anything waiting for the firmware */
wake_up(&data->wait_fw);
return;
}
if (data->fw_urb == NULL) {
- dev_err(&udev->dev, "s2255 disconnected\n");
+ s2255_dev_err(&udev->dev, "disconnected\n");
atomic_set(&data->fw_state, S2255_FW_FAILED);
/* wake up anything waiting for the firmware */
wake_up(&data->wait_fw);
@@ -841,8 +846,7 @@ static int vidioc_querycap(struct file *file, void *priv,
struct s2255_dev *dev = fh->dev;
strlcpy(cap->driver, "s2255", sizeof(cap->driver));
strlcpy(cap->card, "s2255", sizeof(cap->card));
- strlcpy(cap->bus_info, dev_name(&dev->udev->dev),
- sizeof(cap->bus_info));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->version = S2255_VERSION;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
return 0;
@@ -1278,7 +1282,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
}
if (!res_get(dev, fh)) {
- dev_err(&dev->udev->dev, "s2255: stream busy\n");
+ s2255_dev_err(&dev->udev->dev, "stream busy\n");
return -EBUSY;
}
@@ -1545,7 +1549,8 @@ static int s2255_open(struct file *file)
switch (atomic_read(&dev->fw_data->fw_state)) {
case S2255_FW_FAILED:
- err("2255 firmware load failed. retrying.\n");
+ s2255_dev_err(&dev->udev->dev,
+ "firmware load failed. retrying.\n");
s2255_fwload_start(dev, 1);
wait_event_timeout(dev->fw_data->wait_fw,
((atomic_read(&dev->fw_data->fw_state)
@@ -2173,7 +2178,8 @@ static int s2255_board_init(struct s2255_dev *dev)
printk(KERN_INFO "2255 usb firmware version %d \n", fw_ver);
if (fw_ver < CUR_USB_FWVER)
- err("usb firmware not up to date %d\n", fw_ver);
+ dev_err(&dev->udev->dev,
+ "usb firmware not up to date %d\n", fw_ver);
for (j = 0; j < MAX_CHANNELS; j++) {
dev->b_acquire[j] = 0;
@@ -2228,13 +2234,13 @@ static void read_pipe_completion(struct urb *purb)
dprintk(100, "read pipe completion %p, status %d\n", purb,
purb->status);
if (pipe_info == NULL) {
- err("no context !");
+ dev_err(&purb->dev->dev, "no context!\n");
return;
}
dev = pipe_info->dev;
if (dev == NULL) {
- err("no context !");
+ dev_err(&purb->dev->dev, "no context!\n");
return;
}
status = purb->status;
@@ -2286,7 +2292,7 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!pipe_info->stream_urb) {
dev_err(&dev->udev->dev,
- "ReadStream: Unable to alloc URB");
+ "ReadStream: Unable to alloc URB\n");
return -ENOMEM;
}
/* transfer buffer allocated in board_init */
@@ -2391,7 +2397,7 @@ static void s2255_stop_readpipe(struct s2255_dev *dev)
int j;
if (dev == NULL) {
- err("s2255: invalid device");
+ s2255_dev_err(&dev->udev->dev, "invalid device\n");
return;
}
dprintk(4, "stop read pipe\n");
@@ -2453,7 +2459,7 @@ static int s2255_probe(struct usb_interface *interface,
/* allocate memory for our device state and initialize it to zero */
dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
if (dev == NULL) {
- err("s2255: out of memory");
+ s2255_dev_err(&interface->dev, "out of memory\n");
goto error;
}
@@ -2487,7 +2493,7 @@ static int s2255_probe(struct usb_interface *interface,
}
if (!dev->read_endpoint) {
- dev_err(&interface->dev, "Could not find bulk-in endpoint");
+ dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
goto error;
}
@@ -2583,7 +2589,7 @@ static void s2255_disconnect(struct usb_interface *interface)
}
static struct usb_driver s2255_driver = {
- .name = "s2255",
+ .name = S2255_DRIVER_NAME,
.probe = s2255_probe,
.disconnect = s2255_disconnect,
.id_table = s2255_table,
@@ -2597,7 +2603,8 @@ static int __init usb_s2255_init(void)
result = usb_register(&s2255_driver);
if (result)
- err("usb_register failed. Error number %d", result);
+ pr_err(KBUILD_MODNAME
+ ": usb_register failed. Error number %d\n", result);
dprintk(2, "s2255_init: done\n");
return result;
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index e637e440b6d5..da47b2f05288 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -46,10 +46,11 @@
#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/videotext.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>");
MODULE_DESCRIPTION("Philips SAA5246A, SAA5281 Teletext decoder driver");
@@ -388,13 +389,19 @@ MODULE_LICENSE("GPL");
struct saa5246a_device
{
+ struct v4l2_subdev sd;
+ struct video_device *vdev;
u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE];
int is_searching[NUM_DAUS];
- struct i2c_client *client;
unsigned long in_use;
struct mutex lock;
};
+static inline struct saa5246a_device *to_dev(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa5246a_device, sd);
+}
+
static struct video_device saa_template; /* Declared near bottom */
/*
@@ -403,12 +410,13 @@ static struct video_device saa_template; /* Declared near bottom */
static int i2c_sendbuf(struct saa5246a_device *t, int reg, int count, u8 *data)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
char buf[64];
buf[0] = reg;
memcpy(buf+1, data, count);
- if(i2c_master_send(t->client, buf, count+1)==count+1)
+ if (i2c_master_send(client, buf, count + 1) == count + 1)
return 0;
return -1;
}
@@ -436,7 +444,9 @@ static int i2c_senddata(struct saa5246a_device *t, ...)
*/
static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf)
{
- if(i2c_master_recv(t->client, buf, count)!=count)
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+
+ if (i2c_master_recv(client, buf, count) != count)
return -1;
return 0;
}
@@ -961,9 +971,6 @@ static int saa5246a_open(struct file *file)
{
struct saa5246a_device *t = video_drvdata(file);
- if (t->client == NULL)
- return -ENODEV;
-
if (test_and_set_bit(0, &t->in_use))
return -EBUSY;
@@ -1033,18 +1040,29 @@ static struct video_device saa_template =
.minor = -1,
};
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
+static int saa5246a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5246A, 0);
+}
+
+static const struct v4l2_subdev_core_ops saa5246a_core_ops = {
+ .g_chip_ident = saa5246a_g_chip_ident,
+};
+
+static const struct v4l2_subdev_ops saa5246a_ops = {
+ .core = &saa5246a_core_ops,
+};
-I2C_CLIENT_INSMOD;
static int saa5246a_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int pgbuf;
int err;
- struct video_device *vd;
struct saa5246a_device *t;
+ struct v4l2_subdev *sd;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
@@ -1053,40 +1071,43 @@ static int saa5246a_probe(struct i2c_client *client,
t = kzalloc(sizeof(*t), GFP_KERNEL);
if (t == NULL)
return -ENOMEM;
+ sd = &t->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa5246a_ops);
mutex_init(&t->lock);
/* Now create a video4linux device */
- vd = video_device_alloc();
- if (vd == NULL) {
+ t->vdev = video_device_alloc();
+ if (t->vdev == NULL) {
kfree(t);
return -ENOMEM;
}
- i2c_set_clientdata(client, vd);
- memcpy(vd, &saa_template, sizeof(*vd));
+ memcpy(t->vdev, &saa_template, sizeof(*t->vdev));
for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) {
memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0]));
t->is_searching[pgbuf] = false;
}
- video_set_drvdata(vd, t);
+ video_set_drvdata(t->vdev, t);
/* Register it */
- err = video_register_device(vd, VFL_TYPE_VTX, -1);
+ err = video_register_device(t->vdev, VFL_TYPE_VTX, -1);
if (err < 0) {
kfree(t);
- video_device_release(vd);
+ video_device_release(t->vdev);
+ t->vdev = NULL;
return err;
}
- t->client = client;
return 0;
}
static int saa5246a_remove(struct i2c_client *client)
{
- struct video_device *vd = i2c_get_clientdata(client);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct saa5246a_device *t = to_dev(sd);
- video_unregister_device(vd);
- kfree(video_get_drvdata(vd));
+ video_unregister_device(t->vdev);
+ v4l2_device_unregister_subdev(sd);
+ kfree(t);
return 0;
}
@@ -1098,7 +1119,6 @@ MODULE_DEVICE_TABLE(i2c, saa5246a_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa5246a",
- .driverid = I2C_DRIVERID_SAA5249,
.probe = saa5246a_probe,
.remove = saa5246a_remove,
.id_table = saa5246a_id,
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index e29765192469..48b27fe48087 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -50,15 +50,17 @@
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/videotext.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>");
MODULE_DESCRIPTION("Philips SAA5249 Teletext decoder driver");
MODULE_LICENSE("GPL");
+
#define VTX_VER_MAJ 1
#define VTX_VER_MIN 8
@@ -95,17 +97,23 @@ typedef struct {
struct saa5249_device
{
+ struct v4l2_subdev sd;
+ struct video_device *vdev;
vdau_t vdau[NUM_DAUS]; /* Data for virtual DAUs (the 5249 only has one */
/* real DAU, so we have to simulate some more) */
int vtx_use_count;
int is_searching[NUM_DAUS];
int disp_mode;
int virtual_mode;
- struct i2c_client *client;
unsigned long in_use;
struct mutex lock;
};
+static inline struct saa5249_device *to_dev(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa5249_device, sd);
+}
+
#define CCTWR 34 /* IC write/read-address of vtx-chip */
#define CCTRD 35
@@ -147,12 +155,13 @@ static void jdelay(unsigned long delay)
static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
char buf[64];
buf[0] = reg;
memcpy(buf+1, data, count);
- if (i2c_master_send(t->client, buf, count + 1) == count + 1)
+ if (i2c_master_send(client, buf, count + 1) == count + 1)
return 0;
return -1;
}
@@ -180,7 +189,9 @@ static int i2c_senddata(struct saa5249_device *t, ...)
static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
{
- if(i2c_master_recv(t->client, buf, count)!=count)
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+
+ if (i2c_master_recv(client, buf, count) != count)
return -1;
return 0;
}
@@ -497,9 +508,6 @@ static int saa5249_open(struct file *file)
struct saa5249_device *t = video_drvdata(file);
int pgbuf;
- if (t->client == NULL)
- return -ENODEV;
-
if (test_and_set_bit(0, &t->in_use))
return -EBUSY;
@@ -553,18 +561,28 @@ static struct video_device saa_template =
.release = video_device_release,
};
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
+static int saa5249_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5249, 0);
+}
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_core_ops saa5249_core_ops = {
+ .g_chip_ident = saa5249_g_chip_ident,
+};
+
+static const struct v4l2_subdev_ops saa5249_ops = {
+ .core = &saa5249_core_ops,
+};
static int saa5249_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int pgbuf;
int err;
- struct video_device *vd;
struct saa5249_device *t;
+ struct v4l2_subdev *sd;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
@@ -573,16 +591,17 @@ static int saa5249_probe(struct i2c_client *client,
t = kzalloc(sizeof(*t), GFP_KERNEL);
if (t == NULL)
return -ENOMEM;
+ sd = &t->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa5249_ops);
mutex_init(&t->lock);
/* Now create a video4linux device */
- vd = kmalloc(sizeof(struct video_device), GFP_KERNEL);
- if (vd == NULL) {
+ t->vdev = video_device_alloc();
+ if (t->vdev == NULL) {
kfree(client);
return -ENOMEM;
}
- i2c_set_clientdata(client, vd);
- memcpy(vd, &saa_template, sizeof(*vd));
+ memcpy(t->vdev, &saa_template, sizeof(*t->vdev));
for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) {
memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
@@ -593,26 +612,27 @@ static int saa5249_probe(struct i2c_client *client,
t->vdau[pgbuf].stopped = true;
t->is_searching[pgbuf] = false;
}
- video_set_drvdata(vd, t);
+ video_set_drvdata(t->vdev, t);
/* Register it */
- err = video_register_device(vd, VFL_TYPE_VTX, -1);
+ err = video_register_device(t->vdev, VFL_TYPE_VTX, -1);
if (err < 0) {
kfree(t);
- kfree(vd);
+ video_device_release(t->vdev);
+ t->vdev = NULL;
return err;
}
- t->client = client;
return 0;
}
static int saa5249_remove(struct i2c_client *client)
{
- struct video_device *vd = i2c_get_clientdata(client);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct saa5249_device *t = to_dev(sd);
- video_unregister_device(vd);
- kfree(video_get_drvdata(vd));
- kfree(vd);
+ video_unregister_device(t->vdev);
+ v4l2_device_unregister_subdev(sd);
+ kfree(t);
return 0;
}
@@ -624,7 +644,6 @@ MODULE_DEVICE_TABLE(i2c, saa5249_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa5249",
- .driverid = I2C_DRIVERID_SAA5249,
.probe = saa5249_probe,
.remove = saa5249_remove,
.id_table = saa5249_id,
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index f05024259f01..c25e81af5ce0 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -23,7 +23,7 @@
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/types.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>
@@ -32,15 +32,10 @@
#include <asm/uaccess.h>
#include <media/rds.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {
- 0x20 >> 1,
- 0x22 >> 1,
- I2C_CLIENT_END,
-};
-
-I2C_CLIENT_INSMOD;
/* insmod options */
static unsigned int debug;
@@ -72,9 +67,8 @@ MODULE_LICENSE("GPL");
#define dprintk if (debug) printk
struct saa6588 {
- struct i2c_client client;
- struct work_struct work;
- struct timer_list timer;
+ struct v4l2_subdev sd;
+ struct delayed_work work;
spinlock_t lock;
unsigned char *buffer;
unsigned int buf_size;
@@ -86,8 +80,10 @@ struct saa6588 {
int data_available_for_read;
};
-static struct i2c_driver driver;
-static struct i2c_client client_template;
+static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa6588, sd);
+}
/* ---------------------------------------------------------------------- */
@@ -258,6 +254,7 @@ static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf)
static void saa6588_i2c_poll(struct saa6588 *s)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&s->sd);
unsigned long flags;
unsigned char tmpbuf[6];
unsigned char blocknum;
@@ -265,7 +262,7 @@ static void saa6588_i2c_poll(struct saa6588 *s)
/* Although we only need 3 bytes, we have to read at least 6.
SAA6588 returns garbage otherwise */
- if (6 != i2c_master_recv(&s->client, &tmpbuf[0], 6)) {
+ if (6 != i2c_master_recv(client, &tmpbuf[0], 6)) {
if (debug > 1)
dprintk(PREFIX "read error!\n");
return;
@@ -316,23 +313,17 @@ static void saa6588_i2c_poll(struct saa6588 *s)
wake_up_interruptible(&s->read_queue);
}
-static void saa6588_timer(unsigned long data)
-{
- struct saa6588 *s = (struct saa6588 *)data;
-
- schedule_work(&s->work);
-}
-
static void saa6588_work(struct work_struct *work)
{
- struct saa6588 *s = container_of(work, struct saa6588, work);
+ struct saa6588 *s = container_of(work, struct saa6588, work.work);
saa6588_i2c_poll(s);
- mod_timer(&s->timer, jiffies + msecs_to_jiffies(20));
+ schedule_delayed_work(&s->work, msecs_to_jiffies(20));
}
static int saa6588_configure(struct saa6588 *s)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&s->sd);
unsigned char buf[3];
int rc;
@@ -380,7 +371,8 @@ static int saa6588_configure(struct saa6588 *s)
dprintk(PREFIX "writing: 0w=0x%02x 1w=0x%02x 2w=0x%02x\n",
buf[0], buf[1], buf[2]);
- if (3 != (rc = i2c_master_send(&s->client, buf, 3)))
+ rc = i2c_master_send(client, buf, 3);
+ if (rc != 3)
printk(PREFIX "i2c i/o error: rc == %d (should be 3)\n", rc);
return 0;
@@ -388,70 +380,10 @@ static int saa6588_configure(struct saa6588 *s)
/* ---------------------------------------------------------------------- */
-static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind)
-{
- struct saa6588 *s;
- client_template.adapter = adap;
- client_template.addr = addr;
-
- printk(PREFIX "chip found @ 0x%x\n", addr << 1);
-
- if (NULL == (s = kmalloc(sizeof(*s), GFP_KERNEL)))
- return -ENOMEM;
-
- s->buf_size = bufblocks * 3;
-
- if (NULL == (s->buffer = kmalloc(s->buf_size, GFP_KERNEL))) {
- kfree(s);
- return -ENOMEM;
- }
- spin_lock_init(&s->lock);
- s->client = client_template;
- s->block_count = 0;
- s->wr_index = 0;
- s->rd_index = 0;
- s->last_blocknum = 0xff;
- init_waitqueue_head(&s->read_queue);
- s->data_available_for_read = 0;
- i2c_set_clientdata(&s->client, s);
- i2c_attach_client(&s->client);
-
- saa6588_configure(s);
-
- /* start polling via eventd */
- INIT_WORK(&s->work, saa6588_work);
- init_timer(&s->timer);
- s->timer.function = saa6588_timer;
- s->timer.data = (unsigned long)s;
- schedule_work(&s->work);
- return 0;
-}
-
-static int saa6588_probe(struct i2c_adapter *adap)
-{
- if (adap->class & I2C_CLASS_TV_ANALOG)
- return i2c_probe(adap, &addr_data, saa6588_attach);
- return 0;
-}
-
-static int saa6588_detach(struct i2c_client *client)
-{
- struct saa6588 *s = i2c_get_clientdata(client);
-
- del_timer_sync(&s->timer);
- flush_scheduled_work();
-
- i2c_detach_client(client);
- kfree(s->buffer);
- kfree(s);
- return 0;
-}
-
-static int saa6588_command(struct i2c_client *client, unsigned int cmd,
- void *arg)
+static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
- struct saa6588 *s = i2c_get_clientdata(client);
- struct rds_command *a = (struct rds_command *)arg;
+ struct saa6588 *s = to_saa6588(sd);
+ struct rds_command *a = arg;
switch (cmd) {
/* --- open() for /dev/radio --- */
@@ -479,45 +411,94 @@ static int saa6588_command(struct i2c_client *client, unsigned int cmd,
default:
/* nothing */
- break;
+ return -ENOIOCTLCMD;
}
return 0;
}
+static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA6588, 0);
+}
+
/* ----------------------------------------------------------------------- */
-static struct i2c_driver driver = {
- .driver = {
- .name = "saa6588",
- },
- .id = -1, /* FIXME */
- .attach_adapter = saa6588_probe,
- .detach_client = saa6588_detach,
- .command = saa6588_command,
+static const struct v4l2_subdev_core_ops saa6588_core_ops = {
+ .g_chip_ident = saa6588_g_chip_ident,
+ .ioctl = saa6588_ioctl,
};
-static struct i2c_client client_template = {
- .name = "saa6588",
- .driver = &driver,
+static const struct v4l2_subdev_ops saa6588_ops = {
+ .core = &saa6588_core_ops,
};
-static int __init saa6588_init_module(void)
+/* ---------------------------------------------------------------------- */
+
+static int saa6588_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- return i2c_add_driver(&driver);
+ struct saa6588 *s;
+ struct v4l2_subdev *sd;
+
+ v4l_info(client, "saa6588 found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
+
+ s = kzalloc(sizeof(*s), GFP_KERNEL);
+ if (s == NULL)
+ return -ENOMEM;
+
+ s->buf_size = bufblocks * 3;
+
+ s->buffer = kmalloc(s->buf_size, GFP_KERNEL);
+ if (s->buffer == NULL) {
+ kfree(s);
+ return -ENOMEM;
+ }
+ sd = &s->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa6588_ops);
+ spin_lock_init(&s->lock);
+ s->block_count = 0;
+ s->wr_index = 0;
+ s->rd_index = 0;
+ s->last_blocknum = 0xff;
+ init_waitqueue_head(&s->read_queue);
+ s->data_available_for_read = 0;
+
+ saa6588_configure(s);
+
+ /* start polling via eventd */
+ INIT_DELAYED_WORK(&s->work, saa6588_work);
+ schedule_delayed_work(&s->work, 0);
+ return 0;
}
-static void __exit saa6588_cleanup_module(void)
+static int saa6588_remove(struct i2c_client *client)
{
- i2c_del_driver(&driver);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct saa6588 *s = to_saa6588(sd);
+
+ v4l2_device_unregister_subdev(sd);
+
+ cancel_delayed_work_sync(&s->work);
+
+ kfree(s->buffer);
+ kfree(s);
+ return 0;
}
-module_init(saa6588_init_module);
-module_exit(saa6588_cleanup_module);
+/* ----------------------------------------------------------------------- */
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
+static const struct i2c_device_id saa6588_id[] = {
+ { "saa6588", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, saa6588_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "saa6588",
+ .probe = saa6588_probe,
+ .remove = saa6588_remove,
+ .id_table = saa6588_id,
+};
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index 37860698f782..df4e08d2dceb 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -33,15 +33,16 @@
#include <linux/wait.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
MODULE_AUTHOR("Pauline Middelink");
MODULE_LICENSE("GPL");
+
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
@@ -52,9 +53,10 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
#define SAA7110_NR_REG 0x35
struct saa7110 {
+ struct v4l2_subdev sd;
u8 reg[SAA7110_NR_REG];
- int norm;
+ v4l2_std_id norm;
int input;
int enable;
int bright;
@@ -65,20 +67,28 @@ struct saa7110 {
wait_queue_head_t wq;
};
+static inline struct saa7110 *to_saa7110(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa7110, sd);
+}
+
/* ----------------------------------------------------------------------- */
/* I2C support functions */
/* ----------------------------------------------------------------------- */
-static int saa7110_write(struct i2c_client *client, u8 reg, u8 value)
+static int saa7110_write(struct v4l2_subdev *sd, u8 reg, u8 value)
{
- struct saa7110 *decoder = i2c_get_clientdata(client);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct saa7110 *decoder = to_saa7110(sd);
decoder->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
+static int saa7110_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct saa7110 *decoder = to_saa7110(sd);
int ret = -1;
u8 reg = *data; /* first register to write to */
@@ -89,15 +99,13 @@ static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsign
/* the saa7110 has an autoincrement function, use it if
* the adapter understands raw I2C */
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- struct saa7110 *decoder = i2c_get_clientdata(client);
-
ret = i2c_master_send(client, data, len);
/* Cache the written data */
memcpy(decoder->reg + reg, data + 1, len - 1);
} else {
for (++data, --len; len; len--) {
- ret = saa7110_write(client, reg++, *data++);
+ ret = saa7110_write(sd, reg++, *data++);
if (ret < 0)
break;
}
@@ -106,8 +114,10 @@ static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsign
return ret;
}
-static inline int saa7110_read(struct i2c_client *client)
+static inline int saa7110_read(struct v4l2_subdev *sd)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
return i2c_smbus_read_byte(client);
}
@@ -115,11 +125,11 @@ static inline int saa7110_read(struct i2c_client *client)
/* SAA7110 functions */
/* ----------------------------------------------------------------------- */
-#define FRESP_06H_COMPST 0x03 //0x13
-#define FRESP_06H_SVIDEO 0x83 //0xC0
+#define FRESP_06H_COMPST 0x03 /*0x13*/
+#define FRESP_06H_SVIDEO 0x83 /*0xC0*/
-static int saa7110_selmux(struct i2c_client *client, int chan)
+static int saa7110_selmux(struct v4l2_subdev *sd, int chan)
{
static const unsigned char modes[9][8] = {
/* mode 0 */
@@ -150,17 +160,17 @@ static int saa7110_selmux(struct i2c_client *client, int chan)
{FRESP_06H_SVIDEO, 0x3C, 0x27, 0xC1, 0x23,
0x44, 0x75, 0x21}
};
- struct saa7110 *decoder = i2c_get_clientdata(client);
+ struct saa7110 *decoder = to_saa7110(sd);
const unsigned char *ptr = modes[chan];
- saa7110_write(client, 0x06, ptr[0]); /* Luminance control */
- saa7110_write(client, 0x20, ptr[1]); /* Analog Control #1 */
- saa7110_write(client, 0x21, ptr[2]); /* Analog Control #2 */
- saa7110_write(client, 0x22, ptr[3]); /* Mixer Control #1 */
- saa7110_write(client, 0x2C, ptr[4]); /* Mixer Control #2 */
- saa7110_write(client, 0x30, ptr[5]); /* ADCs gain control */
- saa7110_write(client, 0x31, ptr[6]); /* Mixer Control #3 */
- saa7110_write(client, 0x21, ptr[7]); /* Analog Control #2 */
+ saa7110_write(sd, 0x06, ptr[0]); /* Luminance control */
+ saa7110_write(sd, 0x20, ptr[1]); /* Analog Control #1 */
+ saa7110_write(sd, 0x21, ptr[2]); /* Analog Control #2 */
+ saa7110_write(sd, 0x22, ptr[3]); /* Mixer Control #1 */
+ saa7110_write(sd, 0x2C, ptr[4]); /* Mixer Control #2 */
+ saa7110_write(sd, 0x30, ptr[5]); /* ADCs gain control */
+ saa7110_write(sd, 0x31, ptr[6]); /* Mixer Control #3 */
+ saa7110_write(sd, 0x21, ptr[7]); /* Analog Control #2 */
decoder->input = chan;
return 0;
@@ -176,246 +186,260 @@ static const unsigned char initseq[1 + SAA7110_NR_REG] = {
/* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02
};
-static int determine_norm(struct i2c_client *client)
+static v4l2_std_id determine_norm(struct v4l2_subdev *sd)
{
DEFINE_WAIT(wait);
- struct saa7110 *decoder = i2c_get_clientdata(client);
+ struct saa7110 *decoder = to_saa7110(sd);
int status;
/* mode changed, start automatic detection */
- saa7110_write_block(client, initseq, sizeof(initseq));
- saa7110_selmux(client, decoder->input);
+ saa7110_write_block(sd, initseq, sizeof(initseq));
+ saa7110_selmux(sd, decoder->input);
prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
schedule_timeout(msecs_to_jiffies(250));
finish_wait(&decoder->wq, &wait);
- status = saa7110_read(client);
+ status = saa7110_read(sd);
if (status & 0x40) {
- v4l_dbg(1, debug, client, "status=0x%02x (no signal)\n", status);
- return decoder->norm; // no change
+ v4l2_dbg(1, debug, sd, "status=0x%02x (no signal)\n", status);
+ return decoder->norm; /* no change*/
}
if ((status & 3) == 0) {
- saa7110_write(client, 0x06, 0x83);
+ saa7110_write(sd, 0x06, 0x83);
if (status & 0x20) {
- v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status);
- //saa7110_write(client,0x2E,0x81);
- return VIDEO_MODE_NTSC;
+ v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC/no color)\n", status);
+ /*saa7110_write(sd,0x2E,0x81);*/
+ return V4L2_STD_NTSC;
}
- v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status);
- //saa7110_write(client,0x2E,0x9A);
- return VIDEO_MODE_PAL;
+ v4l2_dbg(1, debug, sd, "status=0x%02x (PAL/no color)\n", status);
+ /*saa7110_write(sd,0x2E,0x9A);*/
+ return V4L2_STD_PAL;
}
- //saa7110_write(client,0x06,0x03);
+ /*saa7110_write(sd,0x06,0x03);*/
if (status & 0x20) { /* 60Hz */
- v4l_dbg(1, debug, client, "status=0x%02x (NTSC)\n", status);
- saa7110_write(client, 0x0D, 0x86);
- saa7110_write(client, 0x0F, 0x50);
- saa7110_write(client, 0x11, 0x2C);
- //saa7110_write(client,0x2E,0x81);
- return VIDEO_MODE_NTSC;
+ v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC)\n", status);
+ saa7110_write(sd, 0x0D, 0x86);
+ saa7110_write(sd, 0x0F, 0x50);
+ saa7110_write(sd, 0x11, 0x2C);
+ /*saa7110_write(sd,0x2E,0x81);*/
+ return V4L2_STD_NTSC;
}
/* 50Hz -> PAL/SECAM */
- saa7110_write(client, 0x0D, 0x86);
- saa7110_write(client, 0x0F, 0x10);
- saa7110_write(client, 0x11, 0x59);
- //saa7110_write(client,0x2E,0x9A);
+ saa7110_write(sd, 0x0D, 0x86);
+ saa7110_write(sd, 0x0F, 0x10);
+ saa7110_write(sd, 0x11, 0x59);
+ /*saa7110_write(sd,0x2E,0x9A);*/
prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
schedule_timeout(msecs_to_jiffies(250));
finish_wait(&decoder->wq, &wait);
- status = saa7110_read(client);
+ status = saa7110_read(sd);
if ((status & 0x03) == 0x01) {
- v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status);
- saa7110_write(client, 0x0D, 0x87);
- return VIDEO_MODE_SECAM;
+ v4l2_dbg(1, debug, sd, "status=0x%02x (SECAM)\n", status);
+ saa7110_write(sd, 0x0D, 0x87);
+ return V4L2_STD_SECAM;
}
- v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status);
- return VIDEO_MODE_PAL;
+ v4l2_dbg(1, debug, sd, "status=0x%02x (PAL)\n", status);
+ return V4L2_STD_PAL;
}
-static int
-saa7110_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int saa7110_g_input_status(struct v4l2_subdev *sd, u32 *pstatus)
{
- struct saa7110 *decoder = i2c_get_clientdata(client);
- int v;
+ struct saa7110 *decoder = to_saa7110(sd);
+ int res = V4L2_IN_ST_NO_SIGNAL;
+ int status = saa7110_read(sd);
+
+ v4l2_dbg(1, debug, sd, "status=0x%02x norm=%llx\n",
+ status, (unsigned long long)decoder->norm);
+ if (!(status & 0x40))
+ res = 0;
+ if (!(status & 0x03))
+ res |= V4L2_IN_ST_NO_COLOR;
+
+ *pstatus = res;
+ return 0;
+}
- switch (cmd) {
- case 0:
- //saa7110_write_block(client, initseq, sizeof(initseq));
- break;
+static int saa7110_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ *(v4l2_std_id *)std = determine_norm(sd);
+ return 0;
+}
- case DECODER_GET_CAPABILITIES:
- {
- struct video_decoder_capability *dc = arg;
+static int saa7110_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct saa7110 *decoder = to_saa7110(sd);
+
+ if (decoder->norm != std) {
+ decoder->norm = std;
+ /*saa7110_write(sd, 0x06, 0x03);*/
+ if (std & V4L2_STD_NTSC) {
+ saa7110_write(sd, 0x0D, 0x86);
+ saa7110_write(sd, 0x0F, 0x50);
+ saa7110_write(sd, 0x11, 0x2C);
+ /*saa7110_write(sd, 0x2E, 0x81);*/
+ v4l2_dbg(1, debug, sd, "switched to NTSC\n");
+ } else if (std & V4L2_STD_PAL) {
+ saa7110_write(sd, 0x0D, 0x86);
+ saa7110_write(sd, 0x0F, 0x10);
+ saa7110_write(sd, 0x11, 0x59);
+ /*saa7110_write(sd, 0x2E, 0x9A);*/
+ v4l2_dbg(1, debug, sd, "switched to PAL\n");
+ } else if (std & V4L2_STD_SECAM) {
+ saa7110_write(sd, 0x0D, 0x87);
+ saa7110_write(sd, 0x0F, 0x10);
+ saa7110_write(sd, 0x11, 0x59);
+ /*saa7110_write(sd, 0x2E, 0x9A);*/
+ v4l2_dbg(1, debug, sd, "switched to SECAM\n");
+ } else {
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
- dc->flags =
- VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
- VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
- dc->inputs = SAA7110_MAX_INPUT;
- dc->outputs = SAA7110_MAX_OUTPUT;
- break;
+static int saa7110_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ struct saa7110 *decoder = to_saa7110(sd);
+
+ if (route->input < 0 || route->input >= SAA7110_MAX_INPUT) {
+ v4l2_dbg(1, debug, sd, "input=%d not available\n", route->input);
+ return -EINVAL;
+ }
+ if (decoder->input != route->input) {
+ saa7110_selmux(sd, route->input);
+ v4l2_dbg(1, debug, sd, "switched to input=%d\n", route->input);
}
+ return 0;
+}
- case DECODER_GET_STATUS:
- {
- int status;
- int res = 0;
-
- status = saa7110_read(client);
- v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n",
- status, decoder->norm);
- if (!(status & 0x40))
- res |= DECODER_STATUS_GOOD;
- if (status & 0x03)
- res |= DECODER_STATUS_COLOR;
-
- switch (decoder->norm) {
- case VIDEO_MODE_NTSC:
- res |= DECODER_STATUS_NTSC;
- break;
- case VIDEO_MODE_PAL:
- res |= DECODER_STATUS_PAL;
- break;
- case VIDEO_MODE_SECAM:
- res |= DECODER_STATUS_SECAM;
- break;
- }
- *(int *) arg = res;
- break;
+static int saa7110_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct saa7110 *decoder = to_saa7110(sd);
+
+ if (decoder->enable != enable) {
+ decoder->enable = enable;
+ saa7110_write(sd, 0x0E, enable ? 0x18 : 0x80);
+ v4l2_dbg(1, debug, sd, "YUV %s\n", enable ? "on" : "off");
}
+ return 0;
+}
- case DECODER_SET_NORM:
- v = *(int *) arg;
- if (decoder->norm != v) {
- decoder->norm = v;
- //saa7110_write(client, 0x06, 0x03);
- switch (v) {
- case VIDEO_MODE_NTSC:
- saa7110_write(client, 0x0D, 0x86);
- saa7110_write(client, 0x0F, 0x50);
- saa7110_write(client, 0x11, 0x2C);
- //saa7110_write(client, 0x2E, 0x81);
- v4l_dbg(1, debug, client, "switched to NTSC\n");
- break;
- case VIDEO_MODE_PAL:
- saa7110_write(client, 0x0D, 0x86);
- saa7110_write(client, 0x0F, 0x10);
- saa7110_write(client, 0x11, 0x59);
- //saa7110_write(client, 0x2E, 0x9A);
- v4l_dbg(1, debug, client, "switched to PAL\n");
- break;
- case VIDEO_MODE_SECAM:
- saa7110_write(client, 0x0D, 0x87);
- saa7110_write(client, 0x0F, 0x10);
- saa7110_write(client, 0x11, 0x59);
- //saa7110_write(client, 0x2E, 0x9A);
- v4l_dbg(1, debug, client, "switched to SECAM\n");
- break;
- case VIDEO_MODE_AUTO:
- v4l_dbg(1, debug, client, "switched to AUTO\n");
- decoder->norm = determine_norm(client);
- *(int *) arg = decoder->norm;
- break;
- default:
- return -EPERM;
- }
- }
- break;
+static int saa7110_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+ case V4L2_CID_CONTRAST:
+ case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
+ case V4L2_CID_HUE:
+ return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
- case DECODER_SET_INPUT:
- v = *(int *) arg;
- if (v < 0 || v >= SAA7110_MAX_INPUT) {
- v4l_dbg(1, debug, client, "input=%d not available\n", v);
- return -EINVAL;
- }
- if (decoder->input != v) {
- saa7110_selmux(client, v);
- v4l_dbg(1, debug, client, "switched to input=%d\n", v);
- }
- break;
+static int saa7110_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct saa7110 *decoder = to_saa7110(sd);
- case DECODER_SET_OUTPUT:
- v = *(int *) arg;
- /* not much choice of outputs */
- if (v != 0)
- return -EINVAL;
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = decoder->bright;
break;
-
- case DECODER_ENABLE_OUTPUT:
- v = *(int *) arg;
- if (decoder->enable != v) {
- decoder->enable = v;
- saa7110_write(client, 0x0E, v ? 0x18 : 0x80);
- v4l_dbg(1, debug, client, "YUV %s\n", v ? "on" : "off");
- }
+ case V4L2_CID_CONTRAST:
+ ctrl->value = decoder->contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->value = decoder->sat;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value = decoder->hue;
break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
+static int saa7110_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct saa7110 *decoder = to_saa7110(sd);
- if (decoder->bright != pic->brightness) {
- /* We want 0 to 255 we get 0-65535 */
- decoder->bright = pic->brightness;
- saa7110_write(client, 0x19, decoder->bright >> 8);
- }
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->contrast = pic->contrast;
- saa7110_write(client, 0x13,
- decoder->contrast >> 9);
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ if (decoder->bright != ctrl->value) {
+ decoder->bright = ctrl->value;
+ saa7110_write(sd, 0x19, decoder->bright);
}
- if (decoder->sat != pic->colour) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->sat = pic->colour;
- saa7110_write(client, 0x12, decoder->sat >> 9);
+ break;
+ case V4L2_CID_CONTRAST:
+ if (decoder->contrast != ctrl->value) {
+ decoder->contrast = ctrl->value;
+ saa7110_write(sd, 0x13, decoder->contrast);
}
- if (decoder->hue != pic->hue) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->hue = pic->hue;
- saa7110_write(client, 0x07,
- (decoder->hue >> 8) - 128);
+ break;
+ case V4L2_CID_SATURATION:
+ if (decoder->sat != ctrl->value) {
+ decoder->sat = ctrl->value;
+ saa7110_write(sd, 0x12, decoder->sat);
}
break;
- }
-
- case DECODER_DUMP:
- if (!debug)
- break;
- for (v = 0; v < SAA7110_NR_REG; v += 16) {
- int j;
- v4l_dbg(1, debug, client, "%02x:", v);
- for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++)
- printk(KERN_CONT " %02x", decoder->reg[v + j]);
- printk(KERN_CONT "\n");
+ case V4L2_CID_HUE:
+ if (decoder->hue != ctrl->value) {
+ decoder->hue = ctrl->value;
+ saa7110_write(sd, 0x07, decoder->hue);
}
break;
-
default:
- v4l_dbg(1, debug, client, "unknown command %08x\n", cmd);
return -EINVAL;
}
return 0;
}
+static int saa7110_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7110, 0);
+}
+
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
+static const struct v4l2_subdev_core_ops saa7110_core_ops = {
+ .g_chip_ident = saa7110_g_chip_ident,
+ .g_ctrl = saa7110_g_ctrl,
+ .s_ctrl = saa7110_s_ctrl,
+ .queryctrl = saa7110_queryctrl,
+};
-static unsigned short normal_i2c[] = { 0x9c >> 1, 0x9e >> 1, I2C_CLIENT_END };
+static const struct v4l2_subdev_tuner_ops saa7110_tuner_ops = {
+ .s_std = saa7110_s_std,
+};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_video_ops saa7110_video_ops = {
+ .s_routing = saa7110_s_routing,
+ .s_stream = saa7110_s_stream,
+ .querystd = saa7110_querystd,
+ .g_input_status = saa7110_g_input_status,
+};
+
+static const struct v4l2_subdev_ops saa7110_ops = {
+ .core = &saa7110_core_ops,
+ .tuner = &saa7110_tuner_ops,
+ .video = &saa7110_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
static int saa7110_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct saa7110 *decoder;
+ struct v4l2_subdev *sd;
int rv;
/* Check if the adapter supports the needed features */
@@ -429,7 +453,9 @@ static int saa7110_probe(struct i2c_client *client,
decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
if (!decoder)
return -ENOMEM;
- decoder->norm = VIDEO_MODE_PAL;
+ sd = &decoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa7110_ops);
+ decoder->norm = V4L2_STD_PAL;
decoder->input = 0;
decoder->enable = 1;
decoder->bright = 32768;
@@ -437,30 +463,29 @@ static int saa7110_probe(struct i2c_client *client,
decoder->hue = 32768;
decoder->sat = 32768;
init_waitqueue_head(&decoder->wq);
- i2c_set_clientdata(client, decoder);
- rv = saa7110_write_block(client, initseq, sizeof(initseq));
+ rv = saa7110_write_block(sd, initseq, sizeof(initseq));
if (rv < 0) {
- v4l_dbg(1, debug, client, "init status %d\n", rv);
+ v4l2_dbg(1, debug, sd, "init status %d\n", rv);
} else {
int ver, status;
- saa7110_write(client, 0x21, 0x10);
- saa7110_write(client, 0x0e, 0x18);
- saa7110_write(client, 0x0D, 0x04);
- ver = saa7110_read(client);
- saa7110_write(client, 0x0D, 0x06);
- //mdelay(150);
- status = saa7110_read(client);
- v4l_dbg(1, debug, client, "version %x, status=0x%02x\n",
+ saa7110_write(sd, 0x21, 0x10);
+ saa7110_write(sd, 0x0e, 0x18);
+ saa7110_write(sd, 0x0D, 0x04);
+ ver = saa7110_read(sd);
+ saa7110_write(sd, 0x0D, 0x06);
+ /*mdelay(150);*/
+ status = saa7110_read(sd);
+ v4l2_dbg(1, debug, sd, "version %x, status=0x%02x\n",
ver, status);
- saa7110_write(client, 0x0D, 0x86);
- saa7110_write(client, 0x0F, 0x10);
- saa7110_write(client, 0x11, 0x59);
- //saa7110_write(client, 0x2E, 0x9A);
+ saa7110_write(sd, 0x0D, 0x86);
+ saa7110_write(sd, 0x0F, 0x10);
+ saa7110_write(sd, 0x11, 0x59);
+ /*saa7110_write(sd, 0x2E, 0x9A);*/
}
- //saa7110_selmux(client,0);
- //determine_norm(client);
+ /*saa7110_selmux(sd,0);*/
+ /*determine_norm(sd);*/
/* setup and implicit mode 0 select has been performed */
return 0;
@@ -468,7 +493,10 @@ static int saa7110_probe(struct i2c_client *client,
static int saa7110_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_saa7110(sd));
return 0;
}
@@ -482,8 +510,6 @@ MODULE_DEVICE_TABLE(i2c, saa7110_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa7110",
- .driverid = I2C_DRIVERID_SAA7110,
- .command = saa7110_command,
.probe = saa7110_probe,
.remove = saa7110_remove,
.id_table = saa7110_id,
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c
deleted file mode 100644
index a4738a2fb4d3..000000000000
--- a/drivers/media/video/saa7111.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * saa7111 - Philips SAA7111A video decoder driver version 0.0.3
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * Slight changes for video timing and attachment output by
- * Wolfgang Scherr <scherr@net4you.net>
- *
- * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
- * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
- *
- * Changes by Michael Hunold <michael@mihu.de>
- * - implemented DECODER_SET_GPIO, DECODER_INIT, DECODER_SET_VBI_BYPASS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
-
-MODULE_DESCRIPTION("Philips SAA7111 video decoder driver");
-MODULE_AUTHOR("Dave Perks");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/* ----------------------------------------------------------------------- */
-
-#define SAA7111_NR_REG 0x18
-
-struct saa7111 {
- unsigned char reg[SAA7111_NR_REG];
-
- int norm;
- int input;
- int enable;
-};
-
-/* ----------------------------------------------------------------------- */
-
-static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value)
-{
- struct saa7111 *decoder = i2c_get_clientdata(client);
-
- decoder->reg[reg] = value;
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
-{
- struct saa7111 *decoder = i2c_get_clientdata(client);
-
- if (decoder->reg[reg] != value) {
- decoder->reg[reg] = value;
- i2c_smbus_write_byte_data(client, reg, value);
- }
-}
-
-static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
-{
- int ret = -1;
- u8 reg;
-
- /* the saa7111 has an autoincrement function, use it if
- * the adapter understands raw I2C */
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- /* do raw I2C, not smbus compatible */
- struct saa7111 *decoder = i2c_get_clientdata(client);
- u8 block_data[32];
- int block_len;
-
- while (len >= 2) {
- block_len = 0;
- block_data[block_len++] = reg = data[0];
- do {
- block_data[block_len++] =
- decoder->reg[reg++] = data[1];
- len -= 2;
- data += 2;
- } while (len >= 2 && data[0] == reg && block_len < 32);
- ret = i2c_master_send(client, block_data, block_len);
- if (ret < 0)
- break;
- }
- } else {
- /* do some slow I2C emulation kind of thing */
- while (len >= 2) {
- reg = *data++;
- ret = saa7111_write(client, reg, *data++);
- if (ret < 0)
- break;
- len -= 2;
- }
- }
-
- return ret;
-}
-
-static int saa7111_init_decoder(struct i2c_client *client,
- struct video_decoder_init *init)
-{
- return saa7111_write_block(client, init->data, init->len);
-}
-
-static inline int saa7111_read(struct i2c_client *client, u8 reg)
-{
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const unsigned char saa7111_i2c_init[] = {
- 0x00, 0x00, /* 00 - ID byte */
- 0x01, 0x00, /* 01 - reserved */
-
- /*front end */
- 0x02, 0xd0, /* 02 - FUSE=3, GUDL=2, MODE=0 */
- 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0,
- * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
- 0x04, 0x00, /* 04 - GAI1=256 */
- 0x05, 0x00, /* 05 - GAI2=256 */
-
- /* decoder */
- 0x06, 0xf3, /* 06 - HSB at 13(50Hz) / 17(60Hz)
- * pixels after end of last line */
- /*0x07, 0x13, * 07 - HSS at 113(50Hz) / 117(60Hz) pixels
- * after end of last line */
- 0x07, 0xe8, /* 07 - HSS seems to be needed to
- * work with NTSC, too */
- 0x08, 0xc8, /* 08 - AUFD=1, FSEL=1, EXFIL=0,
- * VTRC=1, HPLL=0, VNOI=0 */
- 0x09, 0x01, /* 09 - BYPS=0, PREF=0, BPSS=0,
- * VBLB=0, UPTCV=0, APER=1 */
- 0x0a, 0x80, /* 0a - BRIG=128 */
- 0x0b, 0x47, /* 0b - CONT=1.109 */
- 0x0c, 0x40, /* 0c - SATN=1.0 */
- 0x0d, 0x00, /* 0d - HUE=0 */
- 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
- * FCTC=0, CHBW=1 */
- 0x0f, 0x00, /* 0f - reserved */
- 0x10, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
- 0x11, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
- * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
- 0x12, 0x00, /* 12 - output control 2 */
- 0x13, 0x00, /* 13 - output control 3 */
- 0x14, 0x00, /* 14 - reserved */
- 0x15, 0x00, /* 15 - VBI */
- 0x16, 0x00, /* 16 - VBI */
- 0x17, 0x00, /* 17 - VBI */
-};
-
-static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- struct saa7111 *decoder = i2c_get_clientdata(client);
-
- switch (cmd) {
- case 0:
- break;
- case DECODER_INIT:
- {
- struct video_decoder_init *init = arg;
- struct video_decoder_init vdi;
-
- if (NULL != init)
- return saa7111_init_decoder(client, init);
- vdi.data = saa7111_i2c_init;
- vdi.len = sizeof(saa7111_i2c_init);
- return saa7111_init_decoder(client, &vdi);
- }
-
- case DECODER_DUMP:
- {
- int i;
-
- for (i = 0; i < SAA7111_NR_REG; i += 16) {
- int j;
-
- v4l_info(client, "%03x", i);
- for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) {
- printk(KERN_CONT " %02x",
- saa7111_read(client, i + j));
- }
- printk(KERN_CONT "\n");
- }
- break;
- }
-
- case DECODER_GET_CAPABILITIES:
- {
- struct video_decoder_capability *cap = arg;
-
- cap->flags = VIDEO_DECODER_PAL |
- VIDEO_DECODER_NTSC |
- VIDEO_DECODER_SECAM |
- VIDEO_DECODER_AUTO |
- VIDEO_DECODER_CCIR;
- cap->inputs = 8;
- cap->outputs = 1;
- break;
- }
-
- case DECODER_GET_STATUS:
- {
- int *iarg = arg;
- int status;
- int res;
-
- status = saa7111_read(client, 0x1f);
- v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
- res = 0;
- if ((status & (1 << 6)) == 0) {
- res |= DECODER_STATUS_GOOD;
- }
- switch (decoder->norm) {
- case VIDEO_MODE_NTSC:
- res |= DECODER_STATUS_NTSC;
- break;
- case VIDEO_MODE_PAL:
- res |= DECODER_STATUS_PAL;
- break;
- case VIDEO_MODE_SECAM:
- res |= DECODER_STATUS_SECAM;
- break;
- default:
- case VIDEO_MODE_AUTO:
- if ((status & (1 << 5)) != 0) {
- res |= DECODER_STATUS_NTSC;
- } else {
- res |= DECODER_STATUS_PAL;
- }
- break;
- }
- if ((status & (1 << 0)) != 0) {
- res |= DECODER_STATUS_COLOR;
- }
- *iarg = res;
- break;
- }
-
- case DECODER_SET_GPIO:
- {
- int *iarg = arg;
- if (0 != *iarg) {
- saa7111_write(client, 0x11,
- (decoder->reg[0x11] | 0x80));
- } else {
- saa7111_write(client, 0x11,
- (decoder->reg[0x11] & 0x7f));
- }
- break;
- }
-
- case DECODER_SET_VBI_BYPASS:
- {
- int *iarg = arg;
- if (0 != *iarg) {
- saa7111_write(client, 0x13,
- (decoder->reg[0x13] & 0xf0) | 0x0a);
- } else {
- saa7111_write(client, 0x13,
- (decoder->reg[0x13] & 0xf0));
- }
- break;
- }
-
- case DECODER_SET_NORM:
- {
- int *iarg = arg;
-
- switch (*iarg) {
-
- case VIDEO_MODE_NTSC:
- saa7111_write(client, 0x08,
- (decoder->reg[0x08] & 0x3f) | 0x40);
- saa7111_write(client, 0x0e,
- (decoder->reg[0x0e] & 0x8f));
- break;
-
- case VIDEO_MODE_PAL:
- saa7111_write(client, 0x08,
- (decoder->reg[0x08] & 0x3f) | 0x00);
- saa7111_write(client, 0x0e,
- (decoder->reg[0x0e] & 0x8f));
- break;
-
- case VIDEO_MODE_SECAM:
- saa7111_write(client, 0x08,
- (decoder->reg[0x08] & 0x3f) | 0x00);
- saa7111_write(client, 0x0e,
- (decoder->reg[0x0e] & 0x8f) | 0x50);
- break;
-
- case VIDEO_MODE_AUTO:
- saa7111_write(client, 0x08,
- (decoder->reg[0x08] & 0x3f) | 0x80);
- saa7111_write(client, 0x0e,
- (decoder->reg[0x0e] & 0x8f));
- break;
-
- default:
- return -EINVAL;
-
- }
- decoder->norm = *iarg;
- break;
- }
-
- case DECODER_SET_INPUT:
- {
- int *iarg = arg;
-
- if (*iarg < 0 || *iarg > 7) {
- return -EINVAL;
- }
-
- if (decoder->input != *iarg) {
- decoder->input = *iarg;
- /* select mode */
- saa7111_write(client, 0x02,
- (decoder->
- reg[0x02] & 0xf8) | decoder->input);
- /* bypass chrominance trap for modes 4..7 */
- saa7111_write(client, 0x09,
- (decoder->
- reg[0x09] & 0x7f) | ((decoder->
- input >
- 3) ? 0x80 :
- 0));
- }
- break;
- }
-
- case DECODER_SET_OUTPUT:
- {
- int *iarg = arg;
-
- /* not much choice of outputs */
- if (*iarg != 0) {
- return -EINVAL;
- }
- break;
- }
-
- case DECODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
- int enable = (*iarg != 0);
-
- if (decoder->enable != enable) {
- decoder->enable = enable;
-
- /* RJ: If output should be disabled (for
- * playing videos), we also need a open PLL.
- * The input is set to 0 (where no input
- * source is connected), although this
- * is not necessary.
- *
- * If output should be enabled, we have to
- * reverse the above.
- */
-
- if (decoder->enable) {
- saa7111_write(client, 0x02,
- (decoder->
- reg[0x02] & 0xf8) |
- decoder->input);
- saa7111_write(client, 0x08,
- (decoder->reg[0x08] & 0xfb));
- saa7111_write(client, 0x11,
- (decoder->
- reg[0x11] & 0xf3) | 0x0c);
- } else {
- saa7111_write(client, 0x02,
- (decoder->reg[0x02] & 0xf8));
- saa7111_write(client, 0x08,
- (decoder->
- reg[0x08] & 0xfb) | 0x04);
- saa7111_write(client, 0x11,
- (decoder->reg[0x11] & 0xf3));
- }
- }
- break;
- }
-
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
-
- /* We want 0 to 255 we get 0-65535 */
- saa7111_write_if_changed(client, 0x0a, pic->brightness >> 8);
- /* We want 0 to 127 we get 0-65535 */
- saa7111_write(client, 0x0b, pic->contrast >> 9);
- /* We want 0 to 127 we get 0-65535 */
- saa7111_write(client, 0x0c, pic->colour >> 9);
- /* We want -128 to 127 we get 0-65535 */
- saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8);
- break;
- }
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static unsigned short normal_i2c[] = { 0x48 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
-static int saa7111_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int i;
- struct saa7111 *decoder;
- struct video_decoder_init vdi;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL);
- if (decoder == NULL) {
- kfree(client);
- return -ENOMEM;
- }
- decoder->norm = VIDEO_MODE_NTSC;
- decoder->input = 0;
- decoder->enable = 1;
- i2c_set_clientdata(client, decoder);
-
- vdi.data = saa7111_i2c_init;
- vdi.len = sizeof(saa7111_i2c_init);
- i = saa7111_init_decoder(client, &vdi);
- if (i < 0) {
- v4l_dbg(1, debug, client, "init status %d\n", i);
- } else {
- v4l_dbg(1, debug, client, "revision %x\n",
- saa7111_read(client, 0x00) >> 4);
- }
- return 0;
-}
-
-static int saa7111_remove(struct i2c_client *client)
-{
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id saa7111_id[] = {
- { "saa7111_old", 0 }, /* "saa7111" maps to the saa7115 driver */
- { }
-};
-MODULE_DEVICE_TABLE(i2c, saa7111_id);
-
-static struct v4l2_i2c_driver_data v4l2_i2c_data = {
- .name = "saa7111",
- .driverid = I2C_DRIVERID_SAA7111A,
- .command = saa7111_command,
- .probe = saa7111_probe,
- .remove = saa7111_remove,
- .id_table = saa7111_id,
-};
diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c
deleted file mode 100644
index 7ca709fda5f4..000000000000
--- a/drivers/media/video/saa7114.c
+++ /dev/null
@@ -1,1068 +0,0 @@
-/*
- * saa7114 - Philips SAA7114H video decoder driver version 0.0.1
- *
- * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
- *
- * Based on saa7111 driver by Dave Perks
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * Slight changes for video timing and attachment output by
- * Wolfgang Scherr <scherr@net4you.net>
- *
- * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
- * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
-
-MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
-MODULE_AUTHOR("Maxim Yevtyushkin");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/* ----------------------------------------------------------------------- */
-
-struct saa7114 {
- unsigned char reg[0xf0 * 2];
-
- int norm;
- int input;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
- int playback;
-};
-
-#define I2C_DELAY 10
-
-
-//#define SAA_7114_NTSC_HSYNC_START (-3)
-//#define SAA_7114_NTSC_HSYNC_STOP (-18)
-
-#define SAA_7114_NTSC_HSYNC_START (-17)
-#define SAA_7114_NTSC_HSYNC_STOP (-32)
-
-//#define SAA_7114_NTSC_HOFFSET (5)
-#define SAA_7114_NTSC_HOFFSET (6)
-#define SAA_7114_NTSC_VOFFSET (10)
-#define SAA_7114_NTSC_WIDTH (720)
-#define SAA_7114_NTSC_HEIGHT (250)
-
-#define SAA_7114_SECAM_HSYNC_START (-17)
-#define SAA_7114_SECAM_HSYNC_STOP (-32)
-
-#define SAA_7114_SECAM_HOFFSET (2)
-#define SAA_7114_SECAM_VOFFSET (10)
-#define SAA_7114_SECAM_WIDTH (720)
-#define SAA_7114_SECAM_HEIGHT (300)
-
-#define SAA_7114_PAL_HSYNC_START (-17)
-#define SAA_7114_PAL_HSYNC_STOP (-32)
-
-#define SAA_7114_PAL_HOFFSET (2)
-#define SAA_7114_PAL_VOFFSET (10)
-#define SAA_7114_PAL_WIDTH (720)
-#define SAA_7114_PAL_HEIGHT (300)
-
-
-
-#define SAA_7114_VERTICAL_CHROMA_OFFSET 0 //0x50504040
-#define SAA_7114_VERTICAL_LUMA_OFFSET 0
-
-#define REG_ADDR(x) (((x) << 1) + 1)
-#define LOBYTE(x) ((unsigned char)((x) & 0xff))
-#define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff))
-#define LOWORD(x) ((unsigned short int)((x) & 0xffff))
-#define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff))
-
-
-/* ----------------------------------------------------------------------- */
-
-static inline int saa7114_write(struct i2c_client *client, u8 reg, u8 value)
-{
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
-{
- int ret = -1;
- u8 reg;
-
- /* the saa7114 has an autoincrement function, use it if
- * the adapter understands raw I2C */
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- /* do raw I2C, not smbus compatible */
- u8 block_data[32];
- int block_len;
-
- while (len >= 2) {
- block_len = 0;
- block_data[block_len++] = reg = data[0];
- do {
- block_data[block_len++] = data[1];
- reg++;
- len -= 2;
- data += 2;
- } while (len >= 2 && data[0] == reg && block_len < 32);
- ret = i2c_master_send(client, block_data, block_len);
- if (ret < 0)
- break;
- }
- } else {
- /* do some slow I2C emulation kind of thing */
- while (len >= 2) {
- reg = *data++;
- ret = saa7114_write(client, reg, *data++);
- if (ret < 0)
- break;
- len -= 2;
- }
- }
-
- return ret;
-}
-
-static inline int saa7114_read(struct i2c_client *client, u8 reg)
-{
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* ----------------------------------------------------------------------- */
-
-// initially set NTSC, composite
-
-
-static const unsigned char init[] = {
- 0x00, 0x00, /* 00 - ID byte , chip version,
- * read only */
- 0x01, 0x08, /* 01 - X,X,X,X, IDEL3 to IDEL0 -
- * horizontal increment delay,
- * recommended position */
- 0x02, 0x00, /* 02 - FUSE=3, GUDL=2, MODE=0 ;
- * input control */
- 0x03, 0x10, /* 03 - HLNRS=0, VBSL=1, WPOFF=0,
- * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
- 0x04, 0x90, /* 04 - GAI1=256 */
- 0x05, 0x90, /* 05 - GAI2=256 */
- 0x06, SAA_7114_NTSC_HSYNC_START, /* 06 - HSB: hsync start,
- * depends on the video standard */
- 0x07, SAA_7114_NTSC_HSYNC_STOP, /* 07 - HSS: hsync stop, depends
- *on the video standard */
- 0x08, 0xb8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1,
- * HPLL: free running in playback, locked
- * in capture, VNOI=0 */
- 0x09, 0x80, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0,
- * UPTCV=0, APER=1; depends from input */
- 0x0a, 0x80, /* 0a - BRIG=128 */
- 0x0b, 0x44, /* 0b - CONT=1.109 */
- 0x0c, 0x40, /* 0c - SATN=1.0 */
- 0x0d, 0x00, /* 0d - HUE=0 */
- 0x0e, 0x84, /* 0e - CDTO, CSTD2 to 0, DCVF, FCTC,
- * CCOMB; depends from video standard */
- 0x0f, 0x24, /* 0f - ACGC,CGAIN6 to CGAIN0; depends
- * from video standard */
- 0x10, 0x03, /* 10 - OFFU1 to 0, OFFV1 to 0, CHBW,
- * LCBW2 to 0 */
- 0x11, 0x59, /* 11 - COLO, RTP1, HEDL1 to 0, RTP0,
- * YDEL2 to 0 */
- 0x12, 0xc9, /* 12 - RT signal control RTSE13 to 10
- * and 03 to 00 */
- 0x13, 0x80, /* 13 - RT/X port output control */
- 0x14, 0x00, /* 14 - analog, ADC, compatibility control */
- 0x15, 0x00, /* 15 - VGATE start FID change */
- 0x16, 0xfe, /* 16 - VGATE stop */
- 0x17, 0x00, /* 17 - Misc., VGATE MSBs */
- 0x18, 0x40, /* RAWG */
- 0x19, 0x80, /* RAWO */
- 0x1a, 0x00,
- 0x1b, 0x00,
- 0x1c, 0x00,
- 0x1d, 0x00,
- 0x1e, 0x00,
- 0x1f, 0x00, /* status byte, read only */
- 0x20, 0x00, /* video decoder reserved part */
- 0x21, 0x00,
- 0x22, 0x00,
- 0x23, 0x00,
- 0x24, 0x00,
- 0x25, 0x00,
- 0x26, 0x00,
- 0x27, 0x00,
- 0x28, 0x00,
- 0x29, 0x00,
- 0x2a, 0x00,
- 0x2b, 0x00,
- 0x2c, 0x00,
- 0x2d, 0x00,
- 0x2e, 0x00,
- 0x2f, 0x00,
- 0x30, 0xbc, /* audio clock generator */
- 0x31, 0xdf,
- 0x32, 0x02,
- 0x33, 0x00,
- 0x34, 0xcd,
- 0x35, 0xcc,
- 0x36, 0x3a,
- 0x37, 0x00,
- 0x38, 0x03,
- 0x39, 0x10,
- 0x3a, 0x00,
- 0x3b, 0x00,
- 0x3c, 0x00,
- 0x3d, 0x00,
- 0x3e, 0x00,
- 0x3f, 0x00,
- 0x40, 0x00, /* VBI data slicer */
- 0x41, 0xff,
- 0x42, 0xff,
- 0x43, 0xff,
- 0x44, 0xff,
- 0x45, 0xff,
- 0x46, 0xff,
- 0x47, 0xff,
- 0x48, 0xff,
- 0x49, 0xff,
- 0x4a, 0xff,
- 0x4b, 0xff,
- 0x4c, 0xff,
- 0x4d, 0xff,
- 0x4e, 0xff,
- 0x4f, 0xff,
- 0x50, 0xff,
- 0x51, 0xff,
- 0x52, 0xff,
- 0x53, 0xff,
- 0x54, 0xff,
- 0x55, 0xff,
- 0x56, 0xff,
- 0x57, 0xff,
- 0x58, 0x40, // framing code
- 0x59, 0x47, // horizontal offset
- 0x5a, 0x06, // vertical offset
- 0x5b, 0x83, // field offset
- 0x5c, 0x00, // reserved
- 0x5d, 0x3e, // header and data
- 0x5e, 0x00, // sliced data
- 0x5f, 0x00, // reserved
- 0x60, 0x00, /* video decoder reserved part */
- 0x61, 0x00,
- 0x62, 0x00,
- 0x63, 0x00,
- 0x64, 0x00,
- 0x65, 0x00,
- 0x66, 0x00,
- 0x67, 0x00,
- 0x68, 0x00,
- 0x69, 0x00,
- 0x6a, 0x00,
- 0x6b, 0x00,
- 0x6c, 0x00,
- 0x6d, 0x00,
- 0x6e, 0x00,
- 0x6f, 0x00,
- 0x70, 0x00, /* video decoder reserved part */
- 0x71, 0x00,
- 0x72, 0x00,
- 0x73, 0x00,
- 0x74, 0x00,
- 0x75, 0x00,
- 0x76, 0x00,
- 0x77, 0x00,
- 0x78, 0x00,
- 0x79, 0x00,
- 0x7a, 0x00,
- 0x7b, 0x00,
- 0x7c, 0x00,
- 0x7d, 0x00,
- 0x7e, 0x00,
- 0x7f, 0x00,
- 0x80, 0x00, /* X-port, I-port and scaler */
- 0x81, 0x00,
- 0x82, 0x00,
- 0x83, 0x00,
- 0x84, 0xc5,
- 0x85, 0x0d, // hsync and vsync ?
- 0x86, 0x40,
- 0x87, 0x01,
- 0x88, 0x00,
- 0x89, 0x00,
- 0x8a, 0x00,
- 0x8b, 0x00,
- 0x8c, 0x00,
- 0x8d, 0x00,
- 0x8e, 0x00,
- 0x8f, 0x00,
- 0x90, 0x03, /* Task A definition */
- 0x91, 0x08,
- 0x92, 0x00,
- 0x93, 0x40,
- 0x94, 0x00, // window settings
- 0x95, 0x00,
- 0x96, 0x00,
- 0x97, 0x00,
- 0x98, 0x00,
- 0x99, 0x00,
- 0x9a, 0x00,
- 0x9b, 0x00,
- 0x9c, 0x00,
- 0x9d, 0x00,
- 0x9e, 0x00,
- 0x9f, 0x00,
- 0xa0, 0x01, /* horizontal integer prescaling ratio */
- 0xa1, 0x00, /* horizontal prescaler accumulation
- * sequence length */
- 0xa2, 0x00, /* UV FIR filter, Y FIR filter, prescaler
- * DC gain */
- 0xa3, 0x00,
- 0xa4, 0x80, // luminance brightness
- 0xa5, 0x40, // luminance gain
- 0xa6, 0x40, // chrominance saturation
- 0xa7, 0x00,
- 0xa8, 0x00, // horizontal luminance scaling increment
- 0xa9, 0x04,
- 0xaa, 0x00, // horizontal luminance phase offset
- 0xab, 0x00,
- 0xac, 0x00, // horizontal chrominance scaling increment
- 0xad, 0x02,
- 0xae, 0x00, // horizontal chrominance phase offset
- 0xaf, 0x00,
- 0xb0, 0x00, // vertical luminance scaling increment
- 0xb1, 0x04,
- 0xb2, 0x00, // vertical chrominance scaling increment
- 0xb3, 0x04,
- 0xb4, 0x00,
- 0xb5, 0x00,
- 0xb6, 0x00,
- 0xb7, 0x00,
- 0xb8, 0x00,
- 0xb9, 0x00,
- 0xba, 0x00,
- 0xbb, 0x00,
- 0xbc, 0x00,
- 0xbd, 0x00,
- 0xbe, 0x00,
- 0xbf, 0x00,
- 0xc0, 0x02, // Task B definition
- 0xc1, 0x08,
- 0xc2, 0x00,
- 0xc3, 0x40,
- 0xc4, 0x00, // window settings
- 0xc5, 0x00,
- 0xc6, 0x00,
- 0xc7, 0x00,
- 0xc8, 0x00,
- 0xc9, 0x00,
- 0xca, 0x00,
- 0xcb, 0x00,
- 0xcc, 0x00,
- 0xcd, 0x00,
- 0xce, 0x00,
- 0xcf, 0x00,
- 0xd0, 0x01, // horizontal integer prescaling ratio
- 0xd1, 0x00, // horizontal prescaler accumulation sequence length
- 0xd2, 0x00, // UV FIR filter, Y FIR filter, prescaler DC gain
- 0xd3, 0x00,
- 0xd4, 0x80, // luminance brightness
- 0xd5, 0x40, // luminance gain
- 0xd6, 0x40, // chrominance saturation
- 0xd7, 0x00,
- 0xd8, 0x00, // horizontal luminance scaling increment
- 0xd9, 0x04,
- 0xda, 0x00, // horizontal luminance phase offset
- 0xdb, 0x00,
- 0xdc, 0x00, // horizontal chrominance scaling increment
- 0xdd, 0x02,
- 0xde, 0x00, // horizontal chrominance phase offset
- 0xdf, 0x00,
- 0xe0, 0x00, // vertical luminance scaling increment
- 0xe1, 0x04,
- 0xe2, 0x00, // vertical chrominance scaling increment
- 0xe3, 0x04,
- 0xe4, 0x00,
- 0xe5, 0x00,
- 0xe6, 0x00,
- 0xe7, 0x00,
- 0xe8, 0x00,
- 0xe9, 0x00,
- 0xea, 0x00,
- 0xeb, 0x00,
- 0xec, 0x00,
- 0xed, 0x00,
- 0xee, 0x00,
- 0xef, 0x00
-};
-
-static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- struct saa7114 *decoder = i2c_get_clientdata(client);
-
- switch (cmd) {
- case 0:
- //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client));
- //saa7114_write_block(client, init, sizeof(init));
- break;
-
- case DECODER_DUMP:
- {
- int i;
-
- if (!debug)
- break;
- v4l_info(client, "decoder dump\n");
-
- for (i = 0; i < 32; i += 16) {
- int j;
-
- v4l_info(client, "%03x", i);
- for (j = 0; j < 16; ++j) {
- printk(KERN_CONT " %02x",
- saa7114_read(client, i + j));
- }
- printk(KERN_CONT "\n");
- }
- break;
- }
-
- case DECODER_GET_CAPABILITIES:
- {
- struct video_decoder_capability *cap = arg;
-
- v4l_dbg(1, debug, client, "get capabilities\n");
-
- cap->flags = VIDEO_DECODER_PAL |
- VIDEO_DECODER_NTSC |
- VIDEO_DECODER_AUTO |
- VIDEO_DECODER_CCIR;
- cap->inputs = 8;
- cap->outputs = 1;
- break;
- }
-
- case DECODER_GET_STATUS:
- {
- int *iarg = arg;
- int status;
- int res;
-
- status = saa7114_read(client, 0x1f);
-
- v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
- res = 0;
- if ((status & (1 << 6)) == 0) {
- res |= DECODER_STATUS_GOOD;
- }
- switch (decoder->norm) {
- case VIDEO_MODE_NTSC:
- res |= DECODER_STATUS_NTSC;
- break;
- case VIDEO_MODE_PAL:
- res |= DECODER_STATUS_PAL;
- break;
- case VIDEO_MODE_SECAM:
- res |= DECODER_STATUS_SECAM;
- break;
- default:
- case VIDEO_MODE_AUTO:
- if ((status & (1 << 5)) != 0) {
- res |= DECODER_STATUS_NTSC;
- } else {
- res |= DECODER_STATUS_PAL;
- }
- break;
- }
- if ((status & (1 << 0)) != 0) {
- res |= DECODER_STATUS_COLOR;
- }
- *iarg = res;
- break;
- }
-
- case DECODER_SET_NORM:
- {
- int *iarg = arg;
-
- short int hoff = 0, voff = 0, w = 0, h = 0;
-
- v4l_dbg(1, debug, client, "set norm\n");
-
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- v4l_dbg(1, debug, client, "NTSC\n");
- decoder->reg[REG_ADDR(0x06)] =
- SAA_7114_NTSC_HSYNC_START;
- decoder->reg[REG_ADDR(0x07)] =
- SAA_7114_NTSC_HSYNC_STOP;
-
- decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
-
- decoder->reg[REG_ADDR(0x0e)] = 0x85;
- decoder->reg[REG_ADDR(0x0f)] = 0x24;
-
- hoff = SAA_7114_NTSC_HOFFSET;
- voff = SAA_7114_NTSC_VOFFSET;
- w = SAA_7114_NTSC_WIDTH;
- h = SAA_7114_NTSC_HEIGHT;
-
- break;
-
- case VIDEO_MODE_PAL:
- v4l_dbg(1, debug, client, "PAL\n");
- decoder->reg[REG_ADDR(0x06)] =
- SAA_7114_PAL_HSYNC_START;
- decoder->reg[REG_ADDR(0x07)] =
- SAA_7114_PAL_HSYNC_STOP;
-
- decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
-
- decoder->reg[REG_ADDR(0x0e)] = 0x81;
- decoder->reg[REG_ADDR(0x0f)] = 0x24;
-
- hoff = SAA_7114_PAL_HOFFSET;
- voff = SAA_7114_PAL_VOFFSET;
- w = SAA_7114_PAL_WIDTH;
- h = SAA_7114_PAL_HEIGHT;
-
- break;
-
- default:
- v4l_dbg(1, debug, client, "Unknown video mode\n");
- return -EINVAL;
- }
-
-
- decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
- decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
- decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
- decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
- decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
- decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
- decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
- decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
- decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
- decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
- decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
- decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
-
- decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
- decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
- decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
- decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
- decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
- decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
- decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
- decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
- decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
- decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
- decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
- decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
-
-
- saa7114_write(client, 0x80, 0x06); // i-port and scaler back end clock selection, task A&B off
- saa7114_write(client, 0x88, 0xd8); // sw reset scaler
- saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
-
- saa7114_write_block(client, decoder->reg + (0x06 << 1),
- 3 << 1);
- saa7114_write_block(client, decoder->reg + (0x0e << 1),
- 2 << 1);
- saa7114_write_block(client, decoder->reg + (0x5a << 1),
- 2 << 1);
-
- saa7114_write_block(client, decoder->reg + (0x94 << 1),
- (0x9f + 1 - 0x94) << 1);
- saa7114_write_block(client, decoder->reg + (0xc4 << 1),
- (0xcf + 1 - 0xc4) << 1);
-
- saa7114_write(client, 0x88, 0xd8); // sw reset scaler
- saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
- saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection
-
- decoder->norm = *iarg;
- break;
- }
-
- case DECODER_SET_INPUT:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set input (%d)\n", *iarg);
- if (*iarg < 0 || *iarg > 7) {
- return -EINVAL;
- }
-
- if (decoder->input != *iarg) {
- v4l_dbg(1, debug, client, "now setting %s input\n",
- *iarg >= 6 ? "S-Video" : "Composite");
- decoder->input = *iarg;
-
- /* select mode */
- decoder->reg[REG_ADDR(0x02)] =
- (decoder->
- reg[REG_ADDR(0x02)] & 0xf0) | (decoder->
- input <
- 6 ? 0x0 : 0x9);
- saa7114_write(client, 0x02,
- decoder->reg[REG_ADDR(0x02)]);
-
- /* bypass chrominance trap for modes 6..9 */
- decoder->reg[REG_ADDR(0x09)] =
- (decoder->
- reg[REG_ADDR(0x09)] & 0x7f) | (decoder->
- input <
- 6 ? 0x0 :
- 0x80);
- saa7114_write(client, 0x09,
- decoder->reg[REG_ADDR(0x09)]);
-
- decoder->reg[REG_ADDR(0x0e)] =
- decoder->input <
- 6 ? decoder->
- reg[REG_ADDR(0x0e)] | 1 : decoder->
- reg[REG_ADDR(0x0e)] & ~1;
- saa7114_write(client, 0x0e,
- decoder->reg[REG_ADDR(0x0e)]);
- }
- break;
- }
-
- case DECODER_SET_OUTPUT:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set output\n");
-
- /* not much choice of outputs */
- if (*iarg != 0) {
- return -EINVAL;
- }
- break;
- }
-
- case DECODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
- int enable = (*iarg != 0);
-
- v4l_dbg(1, debug, client, "%s output\n",
- enable ? "enable" : "disable");
-
- decoder->playback = !enable;
-
- if (decoder->enable != enable) {
- decoder->enable = enable;
-
- /* RJ: If output should be disabled (for
- * playing videos), we also need a open PLL.
- * The input is set to 0 (where no input
- * source is connected), although this
- * is not necessary.
- *
- * If output should be enabled, we have to
- * reverse the above.
- */
-
- if (decoder->enable) {
- decoder->reg[REG_ADDR(0x08)] = 0xb8;
- decoder->reg[REG_ADDR(0x12)] = 0xc9;
- decoder->reg[REG_ADDR(0x13)] = 0x80;
- decoder->reg[REG_ADDR(0x87)] = 0x01;
- } else {
- decoder->reg[REG_ADDR(0x08)] = 0x7c;
- decoder->reg[REG_ADDR(0x12)] = 0x00;
- decoder->reg[REG_ADDR(0x13)] = 0x00;
- decoder->reg[REG_ADDR(0x87)] = 0x00;
- }
-
- saa7114_write_block(client,
- decoder->reg + (0x12 << 1),
- 2 << 1);
- saa7114_write(client, 0x08,
- decoder->reg[REG_ADDR(0x08)]);
- saa7114_write(client, 0x87,
- decoder->reg[REG_ADDR(0x87)]);
- saa7114_write(client, 0x88, 0xd8); // sw reset scaler
- saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
- saa7114_write(client, 0x80, 0x36);
-
- }
- break;
- }
-
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
-
- v4l_dbg(1, debug, client,
- "decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
- pic->brightness, pic->contrast, pic->colour, pic->hue);
-
- if (decoder->bright != pic->brightness) {
- /* We want 0 to 255 we get 0-65535 */
- decoder->bright = pic->brightness;
- saa7114_write(client, 0x0a, decoder->bright >> 8);
- }
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->contrast = pic->contrast;
- saa7114_write(client, 0x0b,
- decoder->contrast >> 9);
- }
- if (decoder->sat != pic->colour) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->sat = pic->colour;
- saa7114_write(client, 0x0c, decoder->sat >> 9);
- }
- if (decoder->hue != pic->hue) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->hue = pic->hue;
- saa7114_write(client, 0x0d,
- (decoder->hue - 32768) >> 8);
- }
- break;
- }
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
-static int saa7114_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int i, err[30];
- short int hoff = SAA_7114_NTSC_HOFFSET;
- short int voff = SAA_7114_NTSC_VOFFSET;
- short int w = SAA_7114_NTSC_WIDTH;
- short int h = SAA_7114_NTSC_HEIGHT;
- struct saa7114 *decoder;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL);
- if (decoder == NULL)
- return -ENOMEM;
- decoder->norm = VIDEO_MODE_NTSC;
- decoder->input = -1;
- decoder->enable = 1;
- decoder->bright = 32768;
- decoder->contrast = 32768;
- decoder->hue = 32768;
- decoder->sat = 32768;
- decoder->playback = 0; // initially capture mode useda
- i2c_set_clientdata(client, decoder);
-
- memcpy(decoder->reg, init, sizeof(init));
-
- decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
- decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
- decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
- decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
- decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
- decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
- decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
- decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
- decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
- decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
- decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
- decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
-
- decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
- decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
- decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
- decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
- decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
- decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
- decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
- decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
- decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
- decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
- decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
- decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
-
- decoder->reg[REG_ADDR(0xb8)] =
- LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
- decoder->reg[REG_ADDR(0xb9)] =
- HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
- decoder->reg[REG_ADDR(0xba)] =
- LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
- decoder->reg[REG_ADDR(0xbb)] =
- HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
-
- decoder->reg[REG_ADDR(0xbc)] =
- LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
- decoder->reg[REG_ADDR(0xbd)] =
- HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
- decoder->reg[REG_ADDR(0xbe)] =
- LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
- decoder->reg[REG_ADDR(0xbf)] =
- HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
-
- decoder->reg[REG_ADDR(0xe8)] =
- LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
- decoder->reg[REG_ADDR(0xe9)] =
- HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
- decoder->reg[REG_ADDR(0xea)] =
- LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
- decoder->reg[REG_ADDR(0xeb)] =
- HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
-
- decoder->reg[REG_ADDR(0xec)] =
- LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
- decoder->reg[REG_ADDR(0xed)] =
- HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
- decoder->reg[REG_ADDR(0xee)] =
- LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
- decoder->reg[REG_ADDR(0xef)] =
- HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
-
-
- decoder->reg[REG_ADDR(0x13)] = 0x80; // RTC0 on
- decoder->reg[REG_ADDR(0x87)] = 0x01; // I-Port
- decoder->reg[REG_ADDR(0x12)] = 0xc9; // RTS0
-
- decoder->reg[REG_ADDR(0x02)] = 0xc0; // set composite1 input, aveasy
- decoder->reg[REG_ADDR(0x09)] = 0x00; // chrominance trap
- decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on
-
-
- v4l_dbg(1, debug, client, "starting init\n");
-
- err[0] =
- saa7114_write_block(client, decoder->reg + (0x20 << 1),
- 0x10 << 1);
- err[1] =
- saa7114_write_block(client, decoder->reg + (0x30 << 1),
- 0x10 << 1);
- err[2] =
- saa7114_write_block(client, decoder->reg + (0x63 << 1),
- (0x7f + 1 - 0x63) << 1);
- err[3] =
- saa7114_write_block(client, decoder->reg + (0x89 << 1),
- 6 << 1);
- err[4] =
- saa7114_write_block(client, decoder->reg + (0xb8 << 1),
- 8 << 1);
- err[5] =
- saa7114_write_block(client, decoder->reg + (0xe8 << 1),
- 8 << 1);
-
-
- for (i = 0; i <= 5; i++) {
- if (err[i] < 0) {
- v4l_dbg(1, debug, client,
- "init error %d at stage %d, leaving attach.\n",
- i, err[i]);
- kfree(decoder);
- return -EIO;
- }
- }
-
- for (i = 6; i < 8; i++) {
- v4l_dbg(1, debug, client,
- "reg[0x%02x] = 0x%02x (0x%02x)\n",
- i, saa7114_read(client, i),
- decoder->reg[REG_ADDR(i)]);
- }
-
- v4l_dbg(1, debug, client,
- "performing decoder reset sequence\n");
-
- err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off
- err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
- err[8] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
-
- for (i = 6; i <= 8; i++) {
- if (err[i] < 0) {
- v4l_dbg(1, debug, client,
- "init error %d at stage %d, leaving attach.\n",
- i, err[i]);
- kfree(decoder);
- return -EIO;
- }
- }
-
- v4l_dbg(1, debug, client, "performing the rest of init\n");
-
- err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
- err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq
- err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1); // slicer
- err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1); // ?
- err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1); // ?
- err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1); // Task A
- err[15] =
- saa7114_write_block(client, decoder->reg + (0x94 << 1),
- 12 << 1);
- err[16] =
- saa7114_write_block(client, decoder->reg + (0xa0 << 1),
- 8 << 1);
- err[17] =
- saa7114_write_block(client, decoder->reg + (0xa8 << 1),
- 8 << 1);
- err[18] =
- saa7114_write_block(client, decoder->reg + (0xb0 << 1),
- 8 << 1);
- err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1); // Task B
- err[15] =
- saa7114_write_block(client, decoder->reg + (0xc4 << 1),
- 12 << 1);
- err[16] =
- saa7114_write_block(client, decoder->reg + (0xd0 << 1),
- 8 << 1);
- err[17] =
- saa7114_write_block(client, decoder->reg + (0xd8 << 1),
- 8 << 1);
- err[18] =
- saa7114_write_block(client, decoder->reg + (0xe0 << 1),
- 8 << 1);
-
- for (i = 9; i <= 18; i++) {
- if (err[i] < 0) {
- v4l_dbg(1, debug, client,
- "init error %d at stage %d, leaving attach.\n",
- i, err[i]);
- kfree(decoder);
- return -EIO;
- }
- }
-
-
- for (i = 6; i < 8; i++) {
- v4l_dbg(1, debug, client,
- "reg[0x%02x] = 0x%02x (0x%02x)\n",
- i, saa7114_read(client, i),
- decoder->reg[REG_ADDR(i)]);
- }
-
-
- for (i = 0x11; i <= 0x13; i++) {
- v4l_dbg(1, debug, client,
- "reg[0x%02x] = 0x%02x (0x%02x)\n",
- i, saa7114_read(client, i),
- decoder->reg[REG_ADDR(i)]);
- }
-
-
- v4l_dbg(1, debug, client, "setting video input\n");
-
- err[19] =
- saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
- err[20] =
- saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]);
- err[21] =
- saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]);
-
- for (i = 19; i <= 21; i++) {
- if (err[i] < 0) {
- v4l_dbg(1, debug, client,
- "init error %d at stage %d, leaving attach.\n",
- i, err[i]);
- kfree(decoder);
- return -EIO;
- }
- }
-
- v4l_dbg(1, debug, client, "performing decoder reset sequence\n");
-
- err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
- err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
- err[24] = saa7114_write(client, 0x80, 0x36); // i-port and scaler backend clock selection, task A&B off
-
-
- for (i = 22; i <= 24; i++) {
- if (err[i] < 0) {
- v4l_dbg(1, debug, client,
- "init error %d at stage %d, leaving attach.\n",
- i, err[i]);
- kfree(decoder);
- return -EIO;
- }
- }
-
- err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]);
- err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
- err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
-
- v4l_dbg(1, debug, client, "chip version %x, decoder status 0x%02x\n",
- saa7114_read(client, 0x00) >> 4,
- saa7114_read(client, 0x1f));
- v4l_dbg(1, debug, client,
- "power save control: 0x%02x, scaler status: 0x%02x\n",
- saa7114_read(client, 0x88),
- saa7114_read(client, 0x8f));
-
-
- for (i = 0x94; i < 0x96; i++) {
- v4l_dbg(1, debug, client,
- "reg[0x%02x] = 0x%02x (0x%02x)\n",
- i, saa7114_read(client, i),
- decoder->reg[REG_ADDR(i)]);
- }
-
- //i = saa7114_write_block(client, init, sizeof(init));
- return 0;
-}
-
-static int saa7114_remove(struct i2c_client *client)
-{
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id saa7114_id[] = {
- { "saa7114_old", 0 }, /* "saa7114" maps to the saa7115 driver */
- { }
-};
-MODULE_DEVICE_TABLE(i2c, saa7114_id);
-
-static struct v4l2_i2c_driver_data v4l2_i2c_data = {
- .name = "saa7114",
- .driverid = I2C_DRIVERID_SAA7114,
- .command = saa7114_command,
- .probe = saa7114_probe,
- .remove = saa7114_remove,
- .id_table = saa7114_id,
-};
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 46c796c3fec8..cebf159f52cf 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -778,7 +778,7 @@ static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
break;
case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
+ if (ctrl->value < -128 || ctrl->value > 127) {
v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
return -ERANGE;
}
@@ -931,8 +931,8 @@ static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
/* Prevent unnecessary standard changes. During a standard
change the I-Port is temporarily disabled. Any devices
reading from that port can get confused.
- Note that VIDIOC_S_STD is also used to switch from
- radio to TV mode, so if a VIDIOC_S_STD is broadcast to
+ Note that s_std is also used to switch from
+ radio to TV mode, so if a s_std is broadcast to
all I2C devices then you do not want to have an unwanted
side-effect here. */
if (std == state->std)
@@ -1206,10 +1206,12 @@ static int saa711x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
switch (qc->id) {
case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
case V4L2_CID_CONTRAST:
case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill_std(qc);
+ return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
default:
return -EINVAL;
}
@@ -1308,11 +1310,12 @@ static int saa711x_s_stream(struct v4l2_subdev *sd, int enable)
v4l2_dbg(1, debug, sd, "%s output\n",
enable ? "enable" : "disable");
- if (state->enable != enable) {
- state->enable = enable;
- saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
- state->enable);
- }
+ if (state->enable == enable)
+ return 0;
+ state->enable = enable;
+ if (!saa711x_has_reg(state->ident, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED))
+ return 0;
+ saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, state->enable);
return 0;
}
@@ -1370,6 +1373,47 @@ static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_dat
}
}
+static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ struct saa711x_state *state = to_state(sd);
+ int reg1e;
+
+ *std = V4L2_STD_ALL;
+ if (state->ident != V4L2_IDENT_SAA7115)
+ return 0;
+ reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
+
+ switch (reg1e & 0x03) {
+ case 1:
+ *std = V4L2_STD_NTSC;
+ break;
+ case 2:
+ *std = V4L2_STD_PAL;
+ break;
+ case 3:
+ *std = V4L2_STD_SECAM;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int saa711x_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+ struct saa711x_state *state = to_state(sd);
+ int reg1e = 0x80;
+ int reg1f;
+
+ *status = V4L2_IN_ST_NO_SIGNAL;
+ if (state->ident == V4L2_IDENT_SAA7115)
+ reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
+ reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
+ if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80)
+ *status = 0;
+ return 0;
+}
+
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
@@ -1493,6 +1537,8 @@ static const struct v4l2_subdev_video_ops saa711x_video_ops = {
.g_vbi_data = saa711x_g_vbi_data,
.decode_vbi_line = saa711x_decode_vbi_line,
.s_stream = saa711x_s_stream,
+ .querystd = saa711x_querystd,
+ .g_input_status = saa711x_g_input_status,
};
static const struct v4l2_subdev_ops saa711x_ops = {
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 05221d47dd4c..128bb8b8dbbf 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -810,7 +810,6 @@ MODULE_DEVICE_TABLE(i2c, saa7127_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa7127",
- .driverid = I2C_DRIVERID_SAA7127,
.probe = saa7127_probe,
.remove = saa7127_remove,
.id_table = saa7127_id,
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index fc2164e28e76..0ba68987bfce 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -6,6 +6,7 @@ config VIDEO_SAA7134
select VIDEO_TUNER
select VIDEO_TVEEPROM
select CRC32
+ select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO
---help---
This is a video4linux driver for Philips SAA713x based
TV cards.
@@ -35,8 +36,16 @@ config VIDEO_SAA7134_DVB
select DVB_TDA10086 if !DVB_FE_CUSTOMISE
select DVB_TDA826X if !DVB_FE_CUSTOMISE
select DVB_ISL6421 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
+ select DVB_ISL6405 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+ select DVB_ZL10036 if !DVB_FE_CUSTOMISE
+ select DVB_MT312 if !DVB_FE_CUSTOMISE
+ select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+ select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+ select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
---help---
This adds support for DVB cards based on the
Philips saa7134 chip.
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 1fee6e84a512..dc2213e2f86e 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -33,9 +33,10 @@
#include <linux/i2c.h>
#include <linux/types.h>
#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include <linux/init.h>
#include <linux/crc32.h>
@@ -44,10 +45,6 @@
#define MPEG_TOTAL_TARGET_BITRATE_MAX 27000
#define MPEG_PID_MAX ((1 << 14) - 1)
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END};
-
-I2C_CLIENT_INSMOD;
MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder");
MODULE_AUTHOR("Andrew de Quincey");
@@ -95,6 +92,7 @@ static const struct v4l2_format v4l2_format_table[] =
};
struct saa6752hs_state {
+ struct v4l2_subdev sd;
int chip;
u32 revision;
int has_ac3;
@@ -115,6 +113,11 @@ enum saa6752hs_command {
SAA6752HS_COMMAND_MAX
};
+static inline struct saa6752hs_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa6752hs_state, sd);
+}
+
/* ---------------------------------------------------------------------- */
static u8 PAT[] = {
@@ -360,185 +363,191 @@ static int saa6752hs_set_bitrate(struct i2c_client *client,
return 0;
}
-static void saa6752hs_set_subsampling(struct i2c_client *client,
- struct v4l2_format *f)
-{
- struct saa6752hs_state *h = i2c_get_clientdata(client);
- int dist_352, dist_480, dist_720;
-
- /*
- FIXME: translate and round width/height into EMPRESS
- subsample type:
- type | PAL | NTSC
- ---------------------------
- SIF | 352x288 | 352x240
- 1/2 D1 | 352x576 | 352x480
- 2/3 D1 | 480x576 | 480x480
- D1 | 720x576 | 720x480
- */
-
- dist_352 = abs(f->fmt.pix.width - 352);
- dist_480 = abs(f->fmt.pix.width - 480);
- dist_720 = abs(f->fmt.pix.width - 720);
- if (dist_720 < dist_480) {
- f->fmt.pix.width = 720;
- f->fmt.pix.height = 576;
- h->video_format = SAA6752HS_VF_D1;
- }
- else if (dist_480 < dist_352) {
- f->fmt.pix.width = 480;
- f->fmt.pix.height = 576;
- h->video_format = SAA6752HS_VF_2_3_D1;
- }
- else {
- f->fmt.pix.width = 352;
- if (abs(f->fmt.pix.height - 576) <
- abs(f->fmt.pix.height - 288)) {
- f->fmt.pix.height = 576;
- h->video_format = SAA6752HS_VF_1_2_D1;
- }
- else {
- f->fmt.pix.height = 288;
- h->video_format = SAA6752HS_VF_SIF;
- }
+static int get_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
+ struct v4l2_ext_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_PMT:
+ ctrl->value = params->ts_pid_pmt;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+ ctrl->value = params->ts_pid_audio;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+ ctrl->value = params->ts_pid_video;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_PCR:
+ ctrl->value = params->ts_pid_pcr;
+ break;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ ctrl->value = params->au_encoding;
+ break;
+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+ ctrl->value = params->au_l2_bitrate;
+ break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ if (!has_ac3)
+ return -EINVAL;
+ ctrl->value = params->au_ac3_bitrate;
+ break;
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ ctrl->value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ ctrl->value = params->vi_aspect;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ ctrl->value = params->vi_bitrate * 1000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ ctrl->value = params->vi_bitrate_peak * 1000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ ctrl->value = params->vi_bitrate_mode;
+ break;
+ default:
+ return -EINVAL;
}
+ return 0;
}
-
static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
- struct v4l2_ext_control *ctrl, unsigned int cmd)
+ struct v4l2_ext_control *ctrl, int set)
{
int old = 0, new;
- int set = (cmd == VIDIOC_S_EXT_CTRLS);
new = ctrl->value;
switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PMT:
- old = params->ts_pid_pmt;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_pmt = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_AUDIO:
- old = params->ts_pid_audio;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_audio = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_VIDEO:
- old = params->ts_pid_video;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_video = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PCR:
- old = params->ts_pid_pcr;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_pcr = new;
- break;
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- old = params->au_encoding;
- if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
- (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- old = params->au_l2_bitrate;
- if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
- new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
- return -ERANGE;
- if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
- new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
- else
- new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
- params->au_l2_bitrate = new;
- break;
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- if (!has_ac3)
- return -EINVAL;
- old = params->au_ac3_bitrate;
- if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
- new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
- return -ERANGE;
- if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
- new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
- else
- new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
- params->au_ac3_bitrate = new;
- break;
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- old = params->vi_aspect;
- if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
- new != V4L2_MPEG_VIDEO_ASPECT_4x3)
- return -ERANGE;
- if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
- new = V4L2_MPEG_VIDEO_ASPECT_4x3;
- params->vi_aspect = new;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- old = params->vi_bitrate * 1000;
- new = 1000 * (new / 1000);
- if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- return -ERANGE;
- if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
- params->vi_bitrate = new / 1000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- old = params->vi_bitrate_peak * 1000;
- new = 1000 * (new / 1000);
- if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- return -ERANGE;
- if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
- params->vi_bitrate_peak = new / 1000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- old = params->vi_bitrate_mode;
- params->vi_bitrate_mode = new;
- break;
- default:
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
+ if (set && new != old)
+ return -ERANGE;
+ new = old;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_PMT:
+ old = params->ts_pid_pmt;
+ if (set && new > MPEG_PID_MAX)
+ return -ERANGE;
+ if (new > MPEG_PID_MAX)
+ new = MPEG_PID_MAX;
+ params->ts_pid_pmt = new;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+ old = params->ts_pid_audio;
+ if (set && new > MPEG_PID_MAX)
+ return -ERANGE;
+ if (new > MPEG_PID_MAX)
+ new = MPEG_PID_MAX;
+ params->ts_pid_audio = new;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+ old = params->ts_pid_video;
+ if (set && new > MPEG_PID_MAX)
+ return -ERANGE;
+ if (new > MPEG_PID_MAX)
+ new = MPEG_PID_MAX;
+ params->ts_pid_video = new;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_PCR:
+ old = params->ts_pid_pcr;
+ if (set && new > MPEG_PID_MAX)
+ return -ERANGE;
+ if (new > MPEG_PID_MAX)
+ new = MPEG_PID_MAX;
+ params->ts_pid_pcr = new;
+ break;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ old = params->au_encoding;
+ if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
+ (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
+ return -ERANGE;
+ new = old;
+ break;
+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+ old = params->au_l2_bitrate;
+ if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
+ new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
+ return -ERANGE;
+ if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
+ new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
+ else
+ new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
+ params->au_l2_bitrate = new;
+ break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ if (!has_ac3)
return -EINVAL;
+ old = params->au_ac3_bitrate;
+ if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
+ new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
+ return -ERANGE;
+ if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
+ new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
+ else
+ new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
+ params->au_ac3_bitrate = new;
+ break;
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
+ if (set && new != old)
+ return -ERANGE;
+ new = old;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
+ if (set && new != old)
+ return -ERANGE;
+ new = old;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ old = params->vi_aspect;
+ if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
+ new != V4L2_MPEG_VIDEO_ASPECT_4x3)
+ return -ERANGE;
+ if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
+ new = V4L2_MPEG_VIDEO_ASPECT_4x3;
+ params->vi_aspect = new;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ old = params->vi_bitrate * 1000;
+ new = 1000 * (new / 1000);
+ if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+ return -ERANGE;
+ if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+ new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
+ params->vi_bitrate = new / 1000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ old = params->vi_bitrate_peak * 1000;
+ new = 1000 * (new / 1000);
+ if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+ return -ERANGE;
+ if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+ new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
+ params->vi_bitrate_peak = new / 1000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ old = params->vi_bitrate_mode;
+ params->vi_bitrate_mode = new;
+ break;
+ default:
+ return -EINVAL;
}
- if (cmd == VIDIOC_G_EXT_CTRLS)
- ctrl->value = old;
- else
- ctrl->value = new;
+ ctrl->value = new;
return 0;
}
-static int saa6752hs_qctrl(struct saa6752hs_state *h,
- struct v4l2_queryctrl *qctrl)
+
+static int saa6752hs_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
{
+ struct saa6752hs_state *h = to_state(sd);
struct saa6752hs_mpeg_params *params = &h->params;
int err;
@@ -583,7 +592,7 @@ static int saa6752hs_qctrl(struct saa6752hs_state *h,
V4L2_MPEG_VIDEO_ASPECT_4x3);
case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- err = v4l2_ctrl_query_fill_std(qctrl);
+ err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
if (err == 0 &&
params->vi_bitrate_mode ==
V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
@@ -597,12 +606,20 @@ static int saa6752hs_qctrl(struct saa6752hs_state *h,
V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
case V4L2_CID_MPEG_VIDEO_BITRATE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
case V4L2_CID_MPEG_STREAM_PID_PMT:
+ return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16);
case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+ return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260);
case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+ return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256);
case V4L2_CID_MPEG_STREAM_PID_PCR:
- return v4l2_ctrl_query_fill_std(qctrl);
+ return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259);
default:
break;
@@ -610,8 +627,7 @@ static int saa6752hs_qctrl(struct saa6752hs_state *h,
return -EINVAL;
}
-static int saa6752hs_qmenu(struct saa6752hs_state *h,
- struct v4l2_querymenu *qmenu)
+static int saa6752hs_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qmenu)
{
static const u32 mpeg_audio_encoding[] = {
V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
@@ -632,11 +648,12 @@ static int saa6752hs_qmenu(struct saa6752hs_state *h,
V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
V4L2_CTRL_MENU_IDS_END
};
+ struct saa6752hs_state *h = to_state(sd);
struct v4l2_queryctrl qctrl;
int err;
qctrl.id = qmenu->id;
- err = saa6752hs_qctrl(h, &qctrl);
+ err = saa6752hs_queryctrl(sd, &qctrl);
if (err)
return err;
switch (qmenu->id) {
@@ -656,17 +673,16 @@ static int saa6752hs_qmenu(struct saa6752hs_state *h,
return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL);
}
-static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
+static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes)
{
unsigned char buf[9], buf2[4];
- struct saa6752hs_state *h;
+ struct saa6752hs_state *h = to_state(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
unsigned size;
u32 crc;
unsigned char localPAT[256];
unsigned char localPMT[256];
- h = i2c_get_clientdata(client);
-
/* Set video format - must be done first as it resets other settings */
set_reg8(client, 0x41, h->video_format);
@@ -762,7 +778,7 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
buf[3] = 0x82;
buf[4] = 0xB0;
buf[5] = buf2[0];
- switch(h->params.vi_aspect) {
+ switch (h->params.vi_aspect) {
case V4L2_MPEG_VIDEO_ASPECT_16x9:
buf[6] = buf2[1] | 0x40;
break;
@@ -770,7 +786,6 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
default:
buf[6] = buf2[1] & 0xBF;
break;
- break;
}
buf[7] = buf2[2];
buf[8] = buf2[3];
@@ -779,81 +794,162 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
return 0;
}
-static int
-saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
+static int saa6752hs_do_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls, int set)
{
- struct saa6752hs_state *h = i2c_get_clientdata(client);
- struct v4l2_ext_controls *ctrls = arg;
+ struct saa6752hs_state *h = to_state(sd);
struct saa6752hs_mpeg_params params;
- int err = 0;
int i;
- switch (cmd) {
- case VIDIOC_INT_INIT:
- /* apply settings and start encoder */
- saa6752hs_init(client, *(u32 *)arg);
- break;
- case VIDIOC_S_EXT_CTRLS:
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- /* fall through */
- case VIDIOC_TRY_EXT_CTRLS:
- case VIDIOC_G_EXT_CTRLS:
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- params = h->params;
- for (i = 0; i < ctrls->count; i++) {
- err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, cmd);
- if (err) {
- ctrls->error_idx = i;
- return err;
- }
+ if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+ return -EINVAL;
+
+ params = h->params;
+ for (i = 0; i < ctrls->count; i++) {
+ int err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, set);
+
+ if (err) {
+ ctrls->error_idx = i;
+ return err;
}
- h->params = params;
- break;
- case VIDIOC_QUERYCTRL:
- return saa6752hs_qctrl(h, arg);
- case VIDIOC_QUERYMENU:
- return saa6752hs_qmenu(h, arg);
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *f = arg;
-
- if (h->video_format == SAA6752HS_VF_UNKNOWN)
- h->video_format = SAA6752HS_VF_D1;
- f->fmt.pix.width =
- v4l2_format_table[h->video_format].fmt.pix.width;
- f->fmt.pix.height =
- v4l2_format_table[h->video_format].fmt.pix.height;
- break ;
}
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *f = arg;
+ if (set)
+ h->params = params;
+ return 0;
+}
- saa6752hs_set_subsampling(client, f);
- break;
+static int saa6752hs_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ return saa6752hs_do_ext_ctrls(sd, ctrls, 1);
+}
+
+static int saa6752hs_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ return saa6752hs_do_ext_ctrls(sd, ctrls, 0);
+}
+
+static int saa6752hs_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ struct saa6752hs_state *h = to_state(sd);
+ int i;
+
+ if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+ return -EINVAL;
+
+ for (i = 0; i < ctrls->count; i++) {
+ int err = get_ctrl(h->has_ac3, &h->params, ctrls->controls + i);
+
+ if (err) {
+ ctrls->error_idx = i;
+ return err;
+ }
}
- case VIDIOC_S_STD:
- h->standard = *((v4l2_std_id *) arg);
- break;
+ return 0;
+}
- case VIDIOC_DBG_G_CHIP_IDENT:
- return v4l2_chip_ident_i2c_client(client,
- arg, h->chip, h->revision);
+static int saa6752hs_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+ struct saa6752hs_state *h = to_state(sd);
- default:
- /* nothing */
- break;
+ if (h->video_format == SAA6752HS_VF_UNKNOWN)
+ h->video_format = SAA6752HS_VF_D1;
+ f->fmt.pix.width =
+ v4l2_format_table[h->video_format].fmt.pix.width;
+ f->fmt.pix.height =
+ v4l2_format_table[h->video_format].fmt.pix.height;
+ return 0;
+}
+
+static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+ struct saa6752hs_state *h = to_state(sd);
+ int dist_352, dist_480, dist_720;
+
+ /*
+ FIXME: translate and round width/height into EMPRESS
+ subsample type:
+
+ type | PAL | NTSC
+ ---------------------------
+ SIF | 352x288 | 352x240
+ 1/2 D1 | 352x576 | 352x480
+ 2/3 D1 | 480x576 | 480x480
+ D1 | 720x576 | 720x480
+ */
+
+ dist_352 = abs(f->fmt.pix.width - 352);
+ dist_480 = abs(f->fmt.pix.width - 480);
+ dist_720 = abs(f->fmt.pix.width - 720);
+ if (dist_720 < dist_480) {
+ f->fmt.pix.width = 720;
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_D1;
+ } else if (dist_480 < dist_352) {
+ f->fmt.pix.width = 480;
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_2_3_D1;
+ } else {
+ f->fmt.pix.width = 352;
+ if (abs(f->fmt.pix.height - 576) <
+ abs(f->fmt.pix.height - 288)) {
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_1_2_D1;
+ } else {
+ f->fmt.pix.height = 288;
+ h->video_format = SAA6752HS_VF_SIF;
+ }
}
+ return 0;
+}
+
+static int saa6752hs_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct saa6752hs_state *h = to_state(sd);
+
+ h->standard = std;
+ return 0;
+}
- return err;
+static int saa6752hs_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct saa6752hs_state *h = to_state(sd);
+
+ return v4l2_chip_ident_i2c_client(client,
+ chip, h->chip, h->revision);
}
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
+ .g_chip_ident = saa6752hs_g_chip_ident,
+ .init = saa6752hs_init,
+ .queryctrl = saa6752hs_queryctrl,
+ .querymenu = saa6752hs_querymenu,
+ .g_ext_ctrls = saa6752hs_g_ext_ctrls,
+ .s_ext_ctrls = saa6752hs_s_ext_ctrls,
+ .try_ext_ctrls = saa6752hs_try_ext_ctrls,
+};
+
+static const struct v4l2_subdev_tuner_ops saa6752hs_tuner_ops = {
+ .s_std = saa6752hs_s_std,
+};
+
+static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
+ .s_fmt = saa6752hs_s_fmt,
+ .g_fmt = saa6752hs_g_fmt,
+};
+
+static const struct v4l2_subdev_ops saa6752hs_ops = {
+ .core = &saa6752hs_core_ops,
+ .tuner = &saa6752hs_tuner_ops,
+ .video = &saa6752hs_video_ops,
+};
+
static int saa6752hs_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL);
+ struct v4l2_subdev *sd;
u8 addr = 0x13;
u8 data[12];
@@ -861,6 +957,8 @@ static int saa6752hs_probe(struct i2c_client *client,
client->addr << 1, client->adapter->name);
if (h == NULL)
return -ENOMEM;
+ sd = &h->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa6752hs_ops);
i2c_master_send(client, &addr, 1);
i2c_master_recv(client, data, sizeof(data));
@@ -874,14 +972,15 @@ static int saa6752hs_probe(struct i2c_client *client,
}
h->params = param_defaults;
h->standard = 0; /* Assume 625 input lines */
-
- i2c_set_clientdata(client, h);
return 0;
}
static int saa6752hs_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_state(sd));
return 0;
}
@@ -893,8 +992,6 @@ MODULE_DEVICE_TABLE(i2c, saa6752hs_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa6752hs",
- .driverid = I2C_DRIVERID_SAA6752HS,
- .command = saa6752hs_command,
.probe = saa6752hs_probe,
.remove = saa6752hs_remove,
.id_table = saa6752hs_id,
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index c750d3dd57d2..8b0b64a89874 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -990,10 +990,10 @@ static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
if (!enable[devnum])
return -ENODEV;
- card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, sizeof(snd_card_saa7134_t));
-
- if (card == NULL)
- return -ENOMEM;
+ err = snd_card_create(index[devnum], id[devnum], THIS_MODULE,
+ sizeof(snd_card_saa7134_t), &card);
+ if (err < 0)
+ return err;
strcpy(card->driver, "SAA7134");
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index e2febcd6e529..a790a7246a63 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -31,6 +31,7 @@
#include <media/v4l2-common.h>
#include <media/tveeprom.h>
#include "tea5767.h"
+#include "tda18271.h"
/* commly used strings */
static char name_mute[] = "mute";
@@ -272,6 +273,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.inputs = {{
.name = name_comp1,
@@ -408,6 +410,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x820000,
.inputs = {{
@@ -818,6 +821,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.inputs = {{
.name = name_comp1,
.vmux = 4,
@@ -977,6 +981,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.inputs = {{
.name = name_comp1,
.vmux = 1,
@@ -1699,6 +1704,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .rds_addr = 0x10,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.name = name_tv,
@@ -2364,6 +2370,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x21,
.inputs = {{
.name = "Composite 0",
.vmux = 0,
@@ -3291,6 +3298,68 @@ struct saa7134_board saa7134_boards[] = {
.gpio = 0x0200100,
},
},
+ [SAA7134_BOARD_HAUPPAUGE_HVR1120] = {
+ .name = "Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tuner_config = 3,
+ .mpeg = SAA7134_MPEG_DVB,
+ .ts_type = SAA7134_MPEG_TS_SERIAL,
+ .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x0000100,
+ }, {
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
+ .gpio = 0x0800100, /* GPIO 23 HI for FM */
+ },
+ },
+ [SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = {
+ .name = "Hauppauge WinTV-HVR1110r3",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tuner_config = 3,
+ .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x0000100,
+ }, {
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
+ .gpio = 0x0800100, /* GPIO 23 HI for FM */
+ },
+ },
[SAA7134_BOARD_CINERGY_HT_PCMCIA] = {
.name = "Terratec Cinergy HT PCMCIA",
.audio_clock = 0x00187de7,
@@ -4070,6 +4139,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.inputs = { {
.name = name_tv,
@@ -4106,6 +4176,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.inputs = { {
.name = name_tv,
@@ -4143,6 +4214,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.inputs = { {
.name = name_tv,
@@ -4323,13 +4395,13 @@ struct saa7134_board saa7134_boards[] = {
.amux = TV,
.tv = 1,
}, {
- .name = name_comp,
- .vmux = 0,
+ .name = name_comp1,
+ .vmux = 3,
.amux = LINE1,
}, {
.name = name_svideo,
.vmux = 8,
- .amux = LINE1,
+ .amux = LINE2,
} },
.radio = {
.name = name_radio,
@@ -4421,8 +4493,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- /* no DVB support for now */
- /* .mpeg = SAA7134_MPEG_DVB, */
+ .mpeg = SAA7134_MPEG_DVB,
.inputs = { {
.name = name_comp,
.vmux = 1,
@@ -4441,8 +4512,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- /* no DVB support for now */
- /* .mpeg = SAA7134_MPEG_DVB, */
+ .mpeg = SAA7134_MPEG_DVB,
.inputs = { {
.name = name_comp,
.vmux = 1,
@@ -4611,7 +4681,7 @@ struct saa7134_board saa7134_boards[] = {
.tuner_type = TUNER_YMEC_TVF_5533MF,
.radio_type = TUNER_TEA5767,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
+ .radio_addr = 0x60,
.gpiomask = 0x80000700,
.inputs = { {
.name = name_tv,
@@ -5405,6 +5475,36 @@ struct pci_device_id saa7134_pci_tbl[] = {
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x0070,
+ .subdevice = 0x6706,
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x0070,
+ .subdevice = 0x6707,
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x0070,
+ .subdevice = 0x6708,
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x0070,
+ .subdevice = 0x6709,
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x0070,
+ .subdevice = 0x670a,
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x153b,
.subdevice = 0x1172,
.driver_data = SAA7134_BOARD_CINERGY_HT_PCMCIA,
@@ -5821,8 +5921,8 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev,
}
-static int saa7134_tda8290_callback(struct saa7134_dev *dev,
- int command, int arg)
+static int saa7134_tda8290_827x_callback(struct saa7134_dev *dev,
+ int command, int arg)
{
u8 sync_control;
@@ -5848,6 +5948,65 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev,
return 0;
}
+static inline int saa7134_tda18271_hvr11x0_toggle_agc(struct saa7134_dev *dev,
+ enum tda18271_mode mode)
+{
+ /* toggle AGC switch through GPIO 26 */
+ switch (mode) {
+ case TDA18271_ANALOG:
+ saa7134_set_gpio(dev, 26, 0);
+ break;
+ case TDA18271_DIGITAL:
+ saa7134_set_gpio(dev, 26, 1);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
+ int command, int arg)
+{
+ int ret = 0;
+
+ switch (command) {
+ case TDA18271_CALLBACK_CMD_AGC_ENABLE: /* 0 */
+ switch (dev->board) {
+ case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+ case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+ ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static int saa7134_tda8290_callback(struct saa7134_dev *dev,
+ int command, int arg)
+{
+ int ret;
+
+ switch (dev->board) {
+ case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+ case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+ /* tda8290 + tda18271 */
+ ret = saa7134_tda8290_18271_callback(dev, command, arg);
+ break;
+ default:
+ /* tda8290 + tda827x */
+ ret = saa7134_tda8290_827x_callback(dev, command, arg);
+ break;
+ }
+ return ret;
+}
+
int saa7134_tuner_callback(void *priv, int component, int command, int arg)
{
struct saa7134_dev *dev = priv;
@@ -5878,11 +6037,16 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data)
switch (tv.model) {
case 67019: /* WinTV-HVR1110 (Retail, IR Blaster, hybrid, FM, SVid/Comp, 3.5mm audio in) */
case 67109: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */
+ case 67201: /* WinTV-HVR1120 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
+ case 67301: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */
+ case 67209: /* WinTV-HVR1110 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
case 67559: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
case 67569: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM) */
case 67579: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM) */
case 67589: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */
case 67599: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */
+ case 67651: /* WinTV-HVR1120 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
+ case 67659: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
break;
default:
printk(KERN_WARNING "%s: warning: "
@@ -6019,6 +6183,11 @@ int saa7134_board_init1(struct saa7134_dev *dev)
msleep(10);
break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+ saa7134_set_gpio(dev, 23, 0);
+ msleep(10);
+ saa7134_set_gpio(dev, 23, 1);
+ dev->has_remote = SAA7134_REMOTE_I2C;
+ break;
case SAA7134_BOARD_AVERMEDIA_M103:
saa7134_set_gpio(dev, 23, 0);
msleep(10);
@@ -6054,6 +6223,16 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00);
break;
+ case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+ case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+ /* GPIO 26 high for digital, low for analog */
+ saa7134_set_gpio(dev, 26, 0);
+ msleep(1);
+
+ saa7134_set_gpio(dev, 22, 0);
+ msleep(10);
+ saa7134_set_gpio(dev, 22, 1);
+ break;
/* i2c remotes */
case SAA7134_BOARD_PINNACLE_PCTV_110i:
case SAA7134_BOARD_PINNACLE_PCTV_310i:
@@ -6079,15 +6258,15 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x8c040007, 0x8c040007);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0c0007cd, 0x0c0007cd);
break;
- case SAA7134_BOARD_AVERMEDIA_A700_PRO:
case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
- /* write windows gpio values */
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100);
printk("%s: %s: hybrid analog/dvb card\n"
- "%s: Sorry, only analog s-video and composite input "
+ "%s: Sorry, of the analog inputs, only analog s-video and composite "
"are supported for now.\n",
dev->name, card(dev).name, dev->name);
+ case SAA7134_BOARD_AVERMEDIA_A700_PRO:
+ /* write windows gpio values */
+ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100);
+ saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100);
break;
}
return 0;
@@ -6109,7 +6288,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
tun_setup.mode_mask = T_RADIO;
- saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+ saa_call_all(dev, tuner, s_type_addr, &tun_setup);
mode_mask &= ~T_RADIO;
}
@@ -6121,7 +6300,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
tun_setup.mode_mask = mode_mask;
- saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+ saa_call_all(dev, tuner, s_type_addr, &tun_setup);
}
if (dev->tda9887_conf) {
@@ -6130,8 +6309,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
tda9887_cfg.tuner = TUNER_TDA9887;
tda9887_cfg.priv = &dev->tda9887_conf;
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
- &tda9887_cfg);
+ saa_call_all(dev, tuner, s_config, &tda9887_cfg);
}
if (dev->tuner_type == TUNER_XC2028) {
@@ -6158,7 +6336,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
xc2028_cfg.tuner = TUNER_XC2028;
xc2028_cfg.priv = &ctl;
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
+ saa_call_all(dev, tuner, s_config, &xc2028_cfg);
}
}
@@ -6168,9 +6346,20 @@ int saa7134_board_init2(struct saa7134_dev *dev)
unsigned char buf;
int board;
+ /* Put here the code that enables the chips that are needed
+ for analog mode and doesn't depend on the tuner attachment.
+ It is also a good idea to get tuner type from eeprom, etc before
+ initializing tuner, since we can avoid loading tuner driver
+ on devices that has TUNER_ABSENT
+ */
switch (dev->board) {
case SAA7134_BOARD_BMK_MPEX_NOTUNER:
case SAA7134_BOARD_BMK_MPEX_TUNER:
+ /* Checks if the device has a tuner at 0x60 addr
+ If the device doesn't have a tuner, TUNER_ABSENT
+ will be used at tuner_type, avoiding loading tuner
+ without needing it
+ */
dev->i2c_client.addr = 0x60;
board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0)
? SAA7134_BOARD_BMK_MPEX_NOTUNER
@@ -6188,11 +6377,15 @@ int saa7134_board_init2(struct saa7134_dev *dev)
u8 subaddr;
u8 data[3];
int ret, tuner_t;
-
struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1},
{.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}};
+
subaddr= 0x14;
tuner_t = 0;
+
+ /* Retrieve device data from eeprom, checking for the
+ proper tuner_type.
+ */
ret = i2c_transfer(&dev->i2c_adap, msg, 2);
if (ret != 2) {
printk(KERN_ERR "EEPROM read failure\n");
@@ -6248,12 +6441,14 @@ int saa7134_board_init2(struct saa7134_dev *dev)
dev->name, saa7134_boards[dev->board].name);
break;
}
+ /* break intentionally omitted */
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
{
- /* The Philips EUROPA based hybrid boards have the tuner connected through
- * the channel decoder. We have to make it transparent to find it
+ /* The Philips EUROPA based hybrid boards have the tuner
+ connected through the channel decoder. We have to make it
+ transparent to find it
*/
u8 data[] = { 0x07, 0x02};
struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
@@ -6274,21 +6469,15 @@ int saa7134_board_init2(struct saa7134_dev *dev)
if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
dev->tuner_type = TUNER_PHILIPS_TDA8290;
- saa7134_tuner_setup(dev);
-
data[2] = 0x68;
i2c_transfer(&dev->i2c_adap, &msg, 1);
-
- /* Tuner setup is handled before I2C transfer.
- Due to that, there's no need to do it later
- */
- return 0;
+ break;
}
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
- case SAA7134_BOARD_ASUSTeK_TVFM7135:
- /* The card below is detected as card=53, but is different */
+ case SAA7134_BOARD_ASUSTeK_TVFM7135:
+ /* The card below is detected as card=53, but is different */
if (dev->autodetected && (dev->eedata[0x27] == 0x03)) {
dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG;
printk(KERN_INFO "%s: P7131 analog only, using "
@@ -6296,6 +6485,10 @@ int saa7134_board_init2(struct saa7134_dev *dev)
dev->name, saa7134_boards[dev->board].name);
}
break;
+ case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+ case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+ hauppauge_eeprom(dev, dev->eedata+0x80);
+ break;
case SAA7134_BOARD_HAUPPAUGE_HVR1110:
hauppauge_eeprom(dev, dev->eedata+0x80);
/* break intentionally omitted */
@@ -6351,22 +6544,6 @@ int saa7134_board_init2(struct saa7134_dev *dev)
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
- case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
- case SAA7134_BOARD_KWORLD_ATSC110:
- {
- /* enable tuner */
- int i;
- static const u8 buffer [] = { 0x10, 0x12, 0x13, 0x04, 0x16,
- 0x00, 0x14, 0x04, 0x17, 0x00 };
- dev->i2c_client.addr = 0x0a;
- for (i = 0; i < 5; i++)
- if (2 != i2c_master_send(&dev->i2c_client,
- &buffer[i*2], 2))
- printk(KERN_WARNING
- "%s: Unable to enable tuner(%i).\n",
- dev->name, i);
- break;
- }
case SAA7134_BOARD_VIDEOMATE_DVBT_200:
case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
/* The T200 and the T200A share the same pci id. Consequently,
@@ -6375,9 +6552,9 @@ int saa7134_board_init2(struct saa7134_dev *dev)
/* Don't do this if the board was specifically selected with an
* insmod option or if we have the default configuration T200*/
- if(!dev->autodetected || (dev->eedata[0x41] == 0xd0))
+ if (!dev->autodetected || (dev->eedata[0x41] == 0xd0))
break;
- if(dev->eedata[0x41] == 0x02) {
+ if (dev->eedata[0x41] == 0x02) {
/* Reconfigure board as T200A */
dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A;
dev->tuner_type = saa7134_boards[dev->board].tuner_type;
@@ -6390,6 +6567,58 @@ int saa7134_board_init2(struct saa7134_dev *dev)
break;
}
break;
+ case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
+ case SAA7134_BOARD_KWORLD_ATSC110:
+ {
+ struct i2c_msg msg = { .addr = 0x0a, .flags = 0 };
+ int i;
+ static u8 buffer[][2] = {
+ { 0x10, 0x12 },
+ { 0x13, 0x04 },
+ { 0x16, 0x00 },
+ { 0x14, 0x04 },
+ { 0x17, 0x00 },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(buffer); i++) {
+ msg.buf = &buffer[i][0];
+ msg.len = ARRAY_SIZE(buffer[0]);
+ if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
+ printk(KERN_WARNING
+ "%s: Unable to enable tuner(%i).\n",
+ dev->name, i);
+ }
+ break;
+ }
+ } /* switch() */
+
+ /* initialize tuner */
+ if (TUNER_ABSENT != dev->tuner_type) {
+ int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
+
+ /* Note: radio tuner address is always filled in,
+ so we do not need to probe for a radio tuner device. */
+ if (dev->radio_type != UNSET)
+ v4l2_i2c_new_subdev(&dev->i2c_adap,
+ "tuner", "tuner", dev->radio_addr);
+ if (has_demod)
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ if (dev->tuner_addr == ADDR_UNSET) {
+ enum v4l2_i2c_tuner_type type =
+ has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(type));
+ } else {
+ v4l2_i2c_new_subdev(&dev->i2c_adap,
+ "tuner", "tuner", dev->tuner_addr);
+ }
+ }
+
+ saa7134_tuner_setup(dev);
+
+ switch (dev->board) {
case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
{
struct v4l2_priv_tun_config tea5767_cfg;
@@ -6401,12 +6630,10 @@ int saa7134_board_init2(struct saa7134_dev *dev)
ctl.xtal_freq = TEA5767_HIGH_LO_13MHz;
tea5767_cfg.tuner = TUNER_TEA5767;
tea5767_cfg.priv = &ctl;
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tea5767_cfg);
+ saa_call_all(dev, tuner, s_config, &tea5767_cfg);
break;
}
} /* switch() */
- saa7134_tuner_setup(dev);
-
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 99221d726edb..dafa0d88bed0 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -54,13 +54,9 @@ static unsigned int gpio_tracking;
module_param(gpio_tracking, int, 0644);
MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
-static unsigned int alsa;
+static unsigned int alsa = 1;
module_param(alsa, int, 0644);
-MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]");
-
-static unsigned int oss;
-module_param(oss, int, 0644);
-MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]");
+MODULE_PARM_DESC(alsa,"enable/disable ALSA DMA sound [dmasound]");
static unsigned int latency = UNSET;
module_param(latency, int, 0444);
@@ -90,8 +86,10 @@ MODULE_PARM_DESC(radio_nr, "radio device number");
MODULE_PARM_DESC(tuner, "tuner type");
MODULE_PARM_DESC(card, "card type");
-static DEFINE_MUTEX(devlist_lock);
+DEFINE_MUTEX(saa7134_devlist_lock);
+EXPORT_SYMBOL(saa7134_devlist_lock);
LIST_HEAD(saa7134_devlist);
+EXPORT_SYMBOL(saa7134_devlist);
static LIST_HEAD(mops_list);
static unsigned int saa7134_devcount;
@@ -156,10 +154,10 @@ static void request_module_async(struct work_struct *work){
request_module("saa7134-empress");
if (card_is_dvb(dev))
request_module("saa7134-dvb");
- if (alsa)
- request_module("saa7134-alsa");
- if (oss)
- request_module("saa7134-oss");
+ if (alsa) {
+ if (dev->pci->device != PCI_DEVICE_ID_PHILIPS_SAA7130)
+ request_module("saa7134-alsa");
+ }
}
static void request_submodules(struct saa7134_dev *dev)
@@ -778,7 +776,7 @@ static struct video_device *vdev_init(struct saa7134_dev *dev,
return NULL;
*vfd = *template;
vfd->minor = -1;
- vfd->parent = &dev->pci->dev;
+ vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
vfd->debug = video_debug;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
@@ -851,6 +849,10 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
if (NULL == dev)
return -ENOMEM;
+ err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
+ if (err)
+ goto fail0;
+
/* pci init */
dev->pci = pci_dev;
if (pci_enable_device(pci_dev)) {
@@ -927,6 +929,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
dev->autodetected = card[dev->nr] != dev->board;
dev->tuner_type = saa7134_boards[dev->board].tuner_type;
dev->tuner_addr = saa7134_boards[dev->board].tuner_addr;
+ dev->radio_type = saa7134_boards[dev->board].radio_type;
+ dev->radio_addr = saa7134_boards[dev->board].radio_addr;
dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
if (UNSET != tuner[dev->nr])
dev->tuner_type = tuner[dev->nr];
@@ -971,23 +975,48 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
/* wait a bit, register i2c bus */
msleep(100);
saa7134_i2c_register(dev);
-
- /* initialize hardware #2 */
- if (TUNER_ABSENT != dev->tuner_type)
- request_module("tuner");
saa7134_board_init2(dev);
saa7134_hwinit2(dev);
/* load i2c helpers */
if (card_is_empress(dev)) {
- request_module("saa6752hs");
+ struct v4l2_subdev *sd =
+ v4l2_i2c_new_subdev(&dev->i2c_adap,
+ "saa6752hs", "saa6752hs",
+ saa7134_boards[dev->board].empress_addr);
+
+ if (sd)
+ sd->grp_id = GRP_EMPRESS;
+ }
+
+ if (saa7134_boards[dev->board].rds_addr) {
+ unsigned short addrs[2] = { 0, I2C_CLIENT_END };
+ struct v4l2_subdev *sd;
+
+ addrs[0] = saa7134_boards[dev->board].rds_addr;
+ sd = v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "saa6588",
+ "saa6588", addrs);
+ if (sd)
+ printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
}
request_submodules(dev);
v4l2_prio_init(&dev->prio);
+ mutex_lock(&saa7134_devlist_lock);
+ list_for_each_entry(mops, &mops_list, next)
+ mpeg_ops_attach(mops, dev);
+ list_add_tail(&dev->devlist, &saa7134_devlist);
+ mutex_unlock(&saa7134_devlist_lock);
+
+ /* check for signal */
+ saa7134_irq_video_signalchange(dev);
+
+ if (TUNER_ABSENT != dev->tuner_type)
+ saa_call_all(dev, core, s_standby, 0);
+
/* register v4l devices */
if (saa7134_no_overlay > 0)
printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name);
@@ -1023,24 +1052,10 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
}
/* everything worked */
- pci_set_drvdata(pci_dev,dev);
saa7134_devcount++;
- mutex_lock(&devlist_lock);
- list_for_each_entry(mops, &mops_list, next)
- mpeg_ops_attach(mops, dev);
- list_add_tail(&dev->devlist,&saa7134_devlist);
- mutex_unlock(&devlist_lock);
-
- /* check for signal */
- saa7134_irq_video_signalchange(dev);
-
- if (saa7134_dmasound_init && !dev->dmasound.priv_data) {
+ if (saa7134_dmasound_init && !dev->dmasound.priv_data)
saa7134_dmasound_init(dev);
- }
-
- if (TUNER_ABSENT != dev->tuner_type)
- saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
return 0;
@@ -1055,13 +1070,16 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
release_mem_region(pci_resource_start(pci_dev,0),
pci_resource_len(pci_dev,0));
fail1:
+ v4l2_device_unregister(&dev->v4l2_dev);
+ fail0:
kfree(dev);
return err;
}
static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
{
- struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
struct saa7134_mpeg_ops *mops;
/* Release DMA sound modules if present */
@@ -1088,11 +1106,11 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
saa7134_hwfini(dev);
/* unregister */
- mutex_lock(&devlist_lock);
+ mutex_lock(&saa7134_devlist_lock);
list_del(&dev->devlist);
list_for_each_entry(mops, &mops_list, next)
mpeg_ops_detach(mops, dev);
- mutex_unlock(&devlist_lock);
+ mutex_unlock(&saa7134_devlist_lock);
saa7134_devcount--;
saa7134_i2c_unregister(dev);
@@ -1113,7 +1131,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
release_mem_region(pci_resource_start(pci_dev,0),
pci_resource_len(pci_dev,0));
- pci_set_drvdata(pci_dev, NULL);
+
+ v4l2_device_unregister(&dev->v4l2_dev);
/* free memory */
kfree(dev);
@@ -1148,8 +1167,8 @@ static int saa7134_buffer_requeue(struct saa7134_dev *dev,
static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
{
-
- struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
/* disable overlay - apps should enable it explicitly on resume*/
dev->ovenable = 0;
@@ -1185,7 +1204,8 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
static int saa7134_resume(struct pci_dev *pci_dev)
{
- struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
unsigned long flags;
pci_set_power_state(pci_dev, PCI_D0);
@@ -1247,11 +1267,11 @@ int saa7134_ts_register(struct saa7134_mpeg_ops *ops)
{
struct saa7134_dev *dev;
- mutex_lock(&devlist_lock);
+ mutex_lock(&saa7134_devlist_lock);
list_for_each_entry(dev, &saa7134_devlist, devlist)
mpeg_ops_attach(ops, dev);
list_add_tail(&ops->next,&mops_list);
- mutex_unlock(&devlist_lock);
+ mutex_unlock(&saa7134_devlist_lock);
return 0;
}
@@ -1259,11 +1279,11 @@ void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops)
{
struct saa7134_dev *dev;
- mutex_lock(&devlist_lock);
+ mutex_lock(&saa7134_devlist_lock);
list_del(&ops->next);
list_for_each_entry(dev, &saa7134_devlist, devlist)
mpeg_ops_detach(ops, dev);
- mutex_unlock(&devlist_lock);
+ mutex_unlock(&saa7134_devlist_lock);
}
EXPORT_SYMBOL(saa7134_ts_register);
@@ -1307,8 +1327,6 @@ module_exit(saa7134_fini);
/* ----------------------------------------------------------- */
EXPORT_SYMBOL(saa7134_set_gpio);
-EXPORT_SYMBOL(saa7134_i2c_call_clients);
-EXPORT_SYMBOL(saa7134_devlist);
EXPORT_SYMBOL(saa7134_boards);
/* ----------------- for the DMA sound modules --------------- */
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index b5370b3e1a3d..4eff1ca8593c 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -48,9 +48,15 @@
#include "isl6405.h"
#include "lnbp21.h"
#include "tuner-simple.h"
+#include "tda18271.h"
+#include "lgdt3305.h"
+#include "tda8290.h"
#include "zl10353.h"
+#include "zl10036.h"
+#include "mt312.h"
+
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL");
@@ -189,7 +195,7 @@ static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe,
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
i2c_transfer(&dev->i2c_adap, &msg, 1);
- saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
+ saa_call_all(dev, tuner, s_frequency, &f);
msg.buf = on;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@@ -950,6 +956,45 @@ static struct nxt200x_config kworldatsc110 = {
.demod_address = 0x0a,
};
+/* ------------------------------------------------------------------ */
+
+static struct mt312_config avertv_a700_mt312 = {
+ .demod_address = 0x0e,
+ .voltage_inverted = 1,
+};
+
+static struct zl10036_config avertv_a700_tuner = {
+ .tuner_address = 0x60,
+};
+
+static struct lgdt3305_config hcw_lgdt3305_config = {
+ .i2c_addr = 0x0e,
+ .mpeg_mode = LGDT3305_MPEG_SERIAL,
+ .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE,
+ .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
+ .deny_i2c_rptr = 1,
+ .spectral_inversion = 1,
+ .qam_if_khz = 4000,
+ .vsb_if_khz = 3250,
+};
+
+static struct tda18271_std_map hauppauge_tda18271_std_map = {
+ .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4,
+ .if_lvl = 1, .rfagc_top = 0x58, },
+ .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5,
+ .if_lvl = 1, .rfagc_top = 0x58, },
+};
+
+static struct tda18271_config hcw_tda18271_config = {
+ .std_map = &hauppauge_tda18271_std_map,
+ .gate = TDA18271_GATE_ANALOG,
+ .config = 3,
+};
+
+static struct tda829x_config tda829x_no_probe = {
+ .probe_tuner = TDA829X_DONT_PROBE,
+};
+
/* ==================================================================
* Core code
*/
@@ -1076,6 +1121,19 @@ static int dvb_init(struct saa7134_dev *dev)
&tda827x_cfg_1) < 0)
goto dettach_frontend;
break;
+ case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+ fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
+ &hcw_lgdt3305_config,
+ &dev->i2c_adap);
+ if (fe0->dvb.frontend) {
+ dvb_attach(tda829x_attach, fe0->dvb.frontend,
+ &dev->i2c_adap, 0x4b,
+ &tda829x_no_probe);
+ dvb_attach(tda18271_attach, fe0->dvb.frontend,
+ 0x60, &dev->i2c_adap,
+ &hcw_tda18271_config);
+ }
+ break;
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
if (configure_tda827x_fe(dev, &asus_p7131_dual_config,
&tda827x_cfg_0) < 0)
@@ -1376,6 +1434,19 @@ static int dvb_init(struct saa7134_dev *dev)
TUNER_PHILIPS_FMD1216ME_MK3);
}
break;
+ case SAA7134_BOARD_AVERMEDIA_A700_PRO:
+ case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
+ /* Zarlink ZL10313 */
+ fe0->dvb.frontend = dvb_attach(mt312_attach,
+ &avertv_a700_mt312, &dev->i2c_adap);
+ if (fe0->dvb.frontend) {
+ if (dvb_attach(zl10036_attach, fe0->dvb.frontend,
+ &avertv_a700_tuner, &dev->i2c_adap) == NULL) {
+ wprintk("%s: No zl10036 found!\n",
+ __func__);
+ }
+ }
+ break;
default:
wprintk("Huh? unknown DVB card?\n");
break;
@@ -1449,7 +1520,7 @@ static int dvb_fini(struct saa7134_dev *dev)
tda9887_cfg.priv = &on;
/* otherwise we don't detect the tuner on next insmod */
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tda9887_cfg);
+ saa_call_all(dev, tuner, s_config, &tda9887_cfg);
} else if (dev->board == SAA7134_BOARD_MEDION_MD8800_QUADRO) {
if ((dev->eedata[2] == 0x07) && use_frontend) {
/* turn off the 2nd lnb supply */
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index c9d8beb87a60..9db3472667e5 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -76,7 +76,7 @@ static int ts_init_encoder(struct saa7134_dev* dev)
break;
}
ts_reset_encoder(dev);
- saa7134_i2c_call_clients(dev, VIDIOC_INT_INIT, &leading_null_bytes);
+ saa_call_all(dev, core, init, leading_null_bytes);
dev->empress_started = 1;
return 0;
}
@@ -234,7 +234,7 @@ static int empress_g_fmt_vid_cap(struct file *file, void *priv,
{
struct saa7134_dev *dev = file->private_data;
- saa7134_i2c_call_clients(dev, VIDIOC_G_FMT, f);
+ saa_call_all(dev, video, g_fmt, f);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
@@ -247,7 +247,7 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv,
{
struct saa7134_dev *dev = file->private_data;
- saa7134_i2c_call_clients(dev, VIDIOC_S_FMT, f);
+ saa_call_all(dev, video, s_fmt, f);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
@@ -317,7 +317,7 @@ static int empress_s_ext_ctrls(struct file *file, void *priv,
if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
- err = saa7134_i2c_call_saa6752(dev, VIDIOC_S_EXT_CTRLS, ctrls);
+ err = saa_call_empress(dev, core, s_ext_ctrls, ctrls);
ts_init_encoder(dev);
return err;
@@ -330,7 +330,7 @@ static int empress_g_ext_ctrls(struct file *file, void *priv,
if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
- return saa7134_i2c_call_saa6752(dev, VIDIOC_G_EXT_CTRLS, ctrls);
+ return saa_call_empress(dev, core, g_ext_ctrls, ctrls);
}
static int empress_g_ctrl(struct file *file, void *priv,
@@ -352,6 +352,7 @@ static int empress_s_ctrl(struct file *file, void *priv,
static int empress_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *c)
{
+ /* Must be sorted from low to high control ID! */
static const u32 user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
@@ -364,6 +365,7 @@ static int empress_queryctrl(struct file *file, void *priv,
0
};
+ /* Must be sorted from low to high control ID! */
static const u32 mpeg_ctrls[] = {
V4L2_CID_MPEG_CLASS,
V4L2_CID_MPEG_STREAM_TYPE,
@@ -388,10 +390,10 @@ static int empress_queryctrl(struct file *file, void *priv,
if (c->id == 0)
return -EINVAL;
if (c->id == V4L2_CID_USER_CLASS || c->id == V4L2_CID_MPEG_CLASS)
- return v4l2_ctrl_query_fill_std(c);
+ return v4l2_ctrl_query_fill(c, 0, 0, 0, 0);
if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
return saa7134_queryctrl(file, priv, c);
- return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYCTRL, c);
+ return saa_call_empress(dev, core, queryctrl, c);
}
static int empress_querymenu(struct file *file, void *priv,
@@ -401,7 +403,7 @@ static int empress_querymenu(struct file *file, void *priv,
if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
- return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c);
+ return saa_call_empress(dev, core, querymenu, c);
}
static int empress_g_chip_ident(struct file *file, void *fh,
@@ -411,14 +413,11 @@ static int empress_g_chip_ident(struct file *file, void *fh,
chip->ident = V4L2_IDENT_NONE;
chip->revision = 0;
- if (dev->mpeg_i2c_client == NULL)
- return -EINVAL;
if (chip->match.type == V4L2_CHIP_MATCH_I2C_DRIVER &&
!strcmp(chip->match.name, "saa6752hs"))
- return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
- if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR &&
- chip->match.addr == dev->mpeg_i2c_client->addr)
- return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
+ return saa_call_empress(dev, core, g_chip_ident, chip);
+ if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR)
+ return saa_call_empress(dev, core, g_chip_ident, chip);
return -EINVAL;
}
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 20c1b33caf7b..f3e285aa2fb4 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -255,7 +255,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
addr = msgs[i].addr << 1;
if (msgs[i].flags & I2C_M_RD)
addr |= 1;
- if (i > 0 && msgs[i].flags & I2C_M_RD) {
+ if (i > 0 && msgs[i].flags & I2C_M_RD && msgs[i].addr != 0x40) {
/* workaround for a saa7134 i2c bug
* needed to talk to the mt352 demux
* thanks to pinnacle for the hint */
@@ -327,8 +327,6 @@ static int attach_inform(struct i2c_client *client)
d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
client->driver->driver.name, client->addr, client->name);
- if (client->addr == 0x20 && client->driver && client->driver->command)
- dev->mpeg_i2c_client = client;
/* Am I an i2c remote control? */
@@ -357,7 +355,6 @@ static struct i2c_algorithm saa7134_algo = {
static struct i2c_adapter saa7134_adap_template = {
.owner = THIS_MODULE,
- .class = I2C_CLASS_TV_ANALOG,
.name = "saa7134",
.id = I2C_HW_SAA7134,
.algo = &saa7134_algo,
@@ -421,29 +418,13 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
}
}
-void saa7134_i2c_call_clients(struct saa7134_dev *dev,
- unsigned int cmd, void *arg)
-{
- BUG_ON(NULL == dev->i2c_adap.algo_data);
- i2c_clients_command(&dev->i2c_adap, cmd, arg);
-}
-
-int saa7134_i2c_call_saa6752(struct saa7134_dev *dev,
- unsigned int cmd, void *arg)
-{
- if (dev->mpeg_i2c_client == NULL)
- return -EINVAL;
- return dev->mpeg_i2c_client->driver->command(dev->mpeg_i2c_client,
- cmd, arg);
-}
-EXPORT_SYMBOL_GPL(saa7134_i2c_call_saa6752);
-
int saa7134_i2c_register(struct saa7134_dev *dev)
{
dev->i2c_adap = saa7134_adap_template;
dev->i2c_adap.dev.parent = &dev->pci->dev;
strcpy(dev->i2c_adap.name,dev->name);
dev->i2c_adap.algo_data = dev;
+ i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
i2c_add_adapter(&dev->i2c_adap);
dev->i2c_client = saa7134_client_template;
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index ef55a59f0cda..cc8b923afbc0 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -79,8 +79,19 @@ static int buffer_activate(struct saa7134_dev *dev,
saa_writeb(SAA7134_TS_SERIAL1, 0x00);
/* Start TS stream */
- saa_writeb(SAA7134_TS_SERIAL0, 0x40);
- saa_writeb(SAA7134_TS_PARALLEL, 0xEC);
+ switch (saa7134_boards[dev->board].ts_type) {
+ case SAA7134_MPEG_TS_PARALLEL:
+ saa_writeb(SAA7134_TS_SERIAL0, 0x40);
+ saa_writeb(SAA7134_TS_PARALLEL, 0xec);
+ break;
+ case SAA7134_MPEG_TS_SERIAL:
+ saa_writeb(SAA7134_TS_SERIAL0, 0xd8);
+ saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
+ saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc);
+ saa_writeb(SAA7134_TS_SERIAL1, 0x02);
+ break;
+ }
+
dev->ts_state = SAA7134_TS_STARTED;
}
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index a1f7e351f572..404f70eeb355 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -30,11 +30,7 @@
#include "saa7134-reg.h"
#include "saa7134.h"
#include <media/v4l2-common.h>
-
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* Include V4L1 specific functions. Should be removed soon */
-#include <linux/videodev.h>
-#endif
+#include <media/rds.h>
/* ------------------------------------------------------------------ */
@@ -452,6 +448,7 @@ static const struct v4l2_queryctrl video_ctrls[] = {
.name = "y offset odd field",
.minimum = 0,
.maximum = 128,
+ .step = 1,
.default_value = 0,
.type = V4L2_CTRL_TYPE_INTEGER,
},{
@@ -459,6 +456,7 @@ static const struct v4l2_queryctrl video_ctrls[] = {
.name = "y offset even field",
.minimum = 0,
.maximum = 128,
+ .step = 1,
.default_value = 0,
.type = V4L2_CTRL_TYPE_INTEGER,
},{
@@ -627,10 +625,10 @@ void saa7134_set_tvnorm_hw(struct saa7134_dev *dev)
saa7134_set_decoder(dev);
if (card_in(dev, dev->ctl_input).tv)
- saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+ saa_call_all(dev, tuner, s_std, dev->tvnorm->id);
/* Set the correct norm for the saa6752hs. This function
does nothing if there is no saa6752hs. */
- saa7134_i2c_call_saa6752(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+ saa_call_empress(dev, tuner, s_std, dev->tvnorm->id);
}
static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
@@ -1266,8 +1264,7 @@ int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, str
else
dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
- &tda9887_cfg);
+ saa_call_all(dev, tuner, s_config, &tda9887_cfg);
}
break;
}
@@ -1334,7 +1331,7 @@ static int video_open(struct file *file)
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
int radio = 0;
- lock_kernel();
+ mutex_lock(&saa7134_devlist_lock);
list_for_each_entry(dev, &saa7134_devlist, devlist) {
if (dev->video_dev && (dev->video_dev->minor == minor))
goto found;
@@ -1347,19 +1344,20 @@ static int video_open(struct file *file)
goto found;
}
}
- unlock_kernel();
+ mutex_unlock(&saa7134_devlist_lock);
return -ENODEV;
- found:
+
+found:
+ mutex_unlock(&saa7134_devlist_lock);
dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
v4l2_type_names[type]);
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh),GFP_KERNEL);
- if (NULL == fh) {
- unlock_kernel();
+ if (NULL == fh)
return -ENOMEM;
- }
+
file->private_data = fh;
fh->dev = dev;
fh->radio = radio;
@@ -1387,12 +1385,11 @@ static int video_open(struct file *file)
if (fh->radio) {
/* switch to radio mode */
saa7134_tvaudio_setinput(dev,&card(dev).radio);
- saa7134_i2c_call_clients(dev,AUDC_SET_RADIO, NULL);
+ saa_call_all(dev, tuner, s_radio);
} else {
/* switch to video/vbi mode */
video_mux(dev,dev->ctl_input);
}
- unlock_kernel();
return 0;
}
@@ -1466,6 +1463,7 @@ static int video_release(struct file *file)
{
struct saa7134_fh *fh = file->private_data;
struct saa7134_dev *dev = fh->dev;
+ struct rds_command cmd;
unsigned long flags;
/* turn off overlay */
@@ -1498,7 +1496,9 @@ static int video_release(struct file *file)
saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
- saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+ saa_call_all(dev, core, s_standby, 0);
+ if (fh->radio)
+ saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd);
/* free stuff */
videobuf_mmap_free(&fh->cap);
@@ -1519,6 +1519,37 @@ static int video_mmap(struct file *file, struct vm_area_struct * vma)
return videobuf_mmap_mapper(saa7134_queue(fh), vma);
}
+static ssize_t radio_read(struct file *file, char __user *data,
+ size_t count, loff_t *ppos)
+{
+ struct saa7134_fh *fh = file->private_data;
+ struct saa7134_dev *dev = fh->dev;
+ struct rds_command cmd;
+
+ cmd.block_count = count/3;
+ cmd.buffer = data;
+ cmd.instance = file;
+ cmd.result = -ENODEV;
+
+ saa_call_all(dev, core, ioctl, RDS_CMD_READ, &cmd);
+
+ return cmd.result;
+}
+
+static unsigned int radio_poll(struct file *file, poll_table *wait)
+{
+ struct saa7134_fh *fh = file->private_data;
+ struct saa7134_dev *dev = fh->dev;
+ struct rds_command cmd;
+
+ cmd.instance = file;
+ cmd.event_list = wait;
+ cmd.result = -ENODEV;
+ saa_call_all(dev, core, ioctl, RDS_CMD_POLL, &cmd);
+
+ return cmd.result;
+}
+
/* ------------------------------------------------------------------ */
static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,
@@ -2041,7 +2072,7 @@ static int saa7134_s_frequency(struct file *file, void *priv,
mutex_lock(&dev->lock);
dev->ctl_freq = f->frequency;
- saa7134_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
+ saa_call_all(dev, tuner, s_frequency, f);
saa7134_tvaudio_do_scan(dev);
mutex_unlock(&dev->lock);
@@ -2299,7 +2330,7 @@ static int radio_g_tuner(struct file *file, void *priv,
strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
- saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
+ saa_call_all(dev, tuner, g_tuner, t);
if (dev->input->amux == TV) {
t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11);
t->rxsubchans = (saa_readb(0x529) & 0x08) ?
@@ -2316,7 +2347,7 @@ static int radio_s_tuner(struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- saa7134_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
+ saa_call_all(dev, tuner, s_tuner, t);
return 0;
}
@@ -2443,8 +2474,10 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
static const struct v4l2_file_operations radio_fops = {
.owner = THIS_MODULE,
.open = video_open,
+ .read = radio_read,
.release = video_release,
.ioctl = video_ioctl2,
+ .poll = radio_poll,
};
static const struct v4l2_ioctl_ops radio_ioctl_ops = {
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 14ee265f3374..a2dd326de5b9 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -35,6 +35,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
#include <media/tuner.h>
#include <media/ir-common.h>
#include <media/ir-kbd-i2c.h>
@@ -277,6 +278,8 @@ struct saa7134_format {
#define SAA7134_BOARD_ASUSTeK_TIGER 152
#define SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG 153
#define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154
+#define SAA7134_BOARD_HAUPPAUGE_HVR1120 155
+#define SAA7134_BOARD_HAUPPAUGE_HVR1110R3 156
#define SAA7134_MAXBOARDS 32
#define SAA7134_INPUT_MAX 8
@@ -309,6 +312,11 @@ enum saa7134_mpeg_type {
SAA7134_MPEG_DVB,
};
+enum saa7134_mpeg_ts_type {
+ SAA7134_MPEG_TS_PARALLEL = 0,
+ SAA7134_MPEG_TS_SERIAL,
+};
+
struct saa7134_board {
char *name;
unsigned int audio_clock;
@@ -324,6 +332,8 @@ struct saa7134_board {
unsigned int radio_type;
unsigned char tuner_addr;
unsigned char radio_addr;
+ unsigned char empress_addr;
+ unsigned char rds_addr;
unsigned int tda9887_conf;
unsigned int tuner_config;
@@ -331,6 +341,7 @@ struct saa7134_board {
/* peripheral I/O */
enum saa7134_video_out video_out;
enum saa7134_mpeg_type mpeg;
+ enum saa7134_mpeg_ts_type ts_type;
unsigned int vid_port_opts;
};
@@ -445,7 +456,6 @@ struct saa7134_dmasound {
unsigned int bufsize;
struct saa7134_pgtable pt;
struct videobuf_dmabuf dma;
- wait_queue_head_t wq;
unsigned int dma_blk;
unsigned int read_offset;
unsigned int read_count;
@@ -482,6 +492,7 @@ struct saa7134_dev {
struct mutex lock;
spinlock_t slock;
struct v4l2_prio_state prio;
+ struct v4l2_device v4l2_dev;
/* workstruct for loading modules */
struct work_struct request_module_wk;
@@ -572,7 +583,6 @@ struct saa7134_dev {
enum saa7134_ts_status ts_state;
unsigned int buff_cnt;
struct saa7134_mpeg_ops *mops;
- struct i2c_client *mpeg_i2c_client;
/* SAA7134_MPEG_EMPRESS only */
struct video_device *empress_dev;
@@ -588,6 +598,7 @@ struct saa7134_dev {
int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);
#endif
+ void (*gate_ctrl)(struct saa7134_dev *dev, int open);
};
/* ----------------------------------------------------------- */
@@ -616,10 +627,31 @@ struct saa7134_dev {
V4L2_STD_NTSC | V4L2_STD_PAL_M | \
V4L2_STD_PAL_60)
+#define GRP_EMPRESS (1)
+#define saa_call_all(dev, o, f, args...) do { \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 1); \
+ v4l2_device_call_all(&(dev)->v4l2_dev, 0, o, f , ##args); \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 0); \
+} while (0)
+
+#define saa_call_empress(dev, o, f, args...) ({ \
+ long _rc; \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 1); \
+ _rc = v4l2_device_call_until_err(&(dev)->v4l2_dev, \
+ GRP_EMPRESS, o, f , ##args); \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 0); \
+ _rc; \
+})
+
/* ----------------------------------------------------------- */
/* saa7134-core.c */
extern struct list_head saa7134_devlist;
+extern struct mutex saa7134_devlist_lock;
extern int saa7134_no_overlay;
void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
@@ -668,10 +700,6 @@ int saa7134_tuner_callback(void *priv, int component, int command, int arg);
int saa7134_i2c_register(struct saa7134_dev *dev);
int saa7134_i2c_unregister(struct saa7134_dev *dev);
-void saa7134_i2c_call_clients(struct saa7134_dev *dev,
- unsigned int cmd, void *arg);
-int saa7134_i2c_call_saa6752(struct saa7134_dev *dev,
- unsigned int cmd, void *arg);
/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/saa7146.h b/drivers/media/video/saa7146.h
index 2830b5e33aec..9fadb331a40b 100644
--- a/drivers/media/video/saa7146.h
+++ b/drivers/media/video/saa7146.h
@@ -25,8 +25,6 @@
#include <linux/types.h>
#include <linux/wait.h>
-#include <linux/videodev.h>
-
#ifndef O_NONCAP
#define O_NONCAP O_TRUNC
#endif
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index 88c5e942f751..25bf2303a6b5 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -931,7 +931,7 @@ static int saa717x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
break;
case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
+ if (ctrl->value < -128 || ctrl->value > 127) {
v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
return -ERANGE;
}
@@ -1380,11 +1380,6 @@ static int saa717x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
return 0;
}
-static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops saa717x_core_ops = {
@@ -1528,10 +1523,7 @@ MODULE_DEVICE_TABLE(i2c, saa717x_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa717x",
- .driverid = I2C_DRIVERID_SAA717X,
- .command = saa717x_command,
.probe = saa717x_probe,
.remove = saa717x_remove,
- .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
.id_table = saa717x_id,
};
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
index 6debb65152ee..75747b104d07 100644
--- a/drivers/media/video/saa7185.c
+++ b/drivers/media/video/saa7185.c
@@ -30,52 +30,58 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
/* ----------------------------------------------------------------------- */
struct saa7185 {
+ struct v4l2_subdev sd;
unsigned char reg[128];
- int norm;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
+ v4l2_std_id norm;
};
+static inline struct saa7185 *to_saa7185(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa7185, sd);
+}
+
/* ----------------------------------------------------------------------- */
-static inline int saa7185_read(struct i2c_client *client)
+static inline int saa7185_read(struct v4l2_subdev *sd)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
return i2c_smbus_read_byte(client);
}
-static int saa7185_write(struct i2c_client *client, u8 reg, u8 value)
+static int saa7185_write(struct v4l2_subdev *sd, u8 reg, u8 value)
{
- struct saa7185 *encoder = i2c_get_clientdata(client);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct saa7185 *encoder = to_saa7185(sd);
- v4l_dbg(1, debug, client, "%02x set to %02x\n", reg, value);
+ v4l2_dbg(1, debug, sd, "%02x set to %02x\n", reg, value);
encoder->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static int saa7185_write_block(struct i2c_client *client,
+static int saa7185_write_block(struct v4l2_subdev *sd,
const u8 *data, unsigned int len)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct saa7185 *encoder = to_saa7185(sd);
int ret = -1;
u8 reg;
@@ -83,7 +89,6 @@ static int saa7185_write_block(struct i2c_client *client,
* the adapter understands raw I2C */
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
/* do raw I2C, not smbus compatible */
- struct saa7185 *encoder = i2c_get_clientdata(client);
u8 block_data[32];
int block_len;
@@ -104,7 +109,7 @@ static int saa7185_write_block(struct i2c_client *client,
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- ret = saa7185_write(client, reg, *data++);
+ ret = saa7185_write(sd, reg, *data++);
if (ret < 0)
break;
len -= 2;
@@ -213,133 +218,106 @@ static const unsigned char init_ntsc[] = {
0x66, 0x21, /* FSC3 */
};
-static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- struct saa7185 *encoder = i2c_get_clientdata(client);
-
- switch (cmd) {
- case 0:
- saa7185_write_block(client, init_common,
- sizeof(init_common));
- switch (encoder->norm) {
-
- case VIDEO_MODE_NTSC:
- saa7185_write_block(client, init_ntsc,
- sizeof(init_ntsc));
- break;
-
- case VIDEO_MODE_PAL:
- saa7185_write_block(client, init_pal,
- sizeof(init_pal));
- break;
- }
- break;
- case ENCODER_GET_CAPABILITIES:
- {
- struct video_encoder_capability *cap = arg;
+static int saa7185_init(struct v4l2_subdev *sd, u32 val)
+{
+ struct saa7185 *encoder = to_saa7185(sd);
- cap->flags =
- VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC |
- VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR;
- cap->inputs = 1;
- cap->outputs = 1;
- break;
- }
+ saa7185_write_block(sd, init_common, sizeof(init_common));
+ if (encoder->norm & V4L2_STD_NTSC)
+ saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
+ else
+ saa7185_write_block(sd, init_pal, sizeof(init_pal));
+ return 0;
+}
- case ENCODER_SET_NORM:
- {
- int *iarg = arg;
+static int saa7185_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct saa7185 *encoder = to_saa7185(sd);
- //saa7185_write_block(client, init_common, sizeof(init_common));
+ if (std & V4L2_STD_NTSC)
+ saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
+ else if (std & V4L2_STD_PAL)
+ saa7185_write_block(sd, init_pal, sizeof(init_pal));
+ else
+ return -EINVAL;
+ encoder->norm = std;
+ return 0;
+}
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- saa7185_write_block(client, init_ntsc,
- sizeof(init_ntsc));
- break;
+static int saa7185_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ struct saa7185 *encoder = to_saa7185(sd);
- case VIDEO_MODE_PAL:
- saa7185_write_block(client, init_pal,
- sizeof(init_pal));
- break;
+ /* RJ: route->input = 0: input is from SA7111
+ route->input = 1: input is from ZR36060 */
- case VIDEO_MODE_SECAM:
- default:
- return -EINVAL;
- }
- encoder->norm = *iarg;
- break;
- }
-
- case ENCODER_SET_INPUT:
- {
- int *iarg = arg;
-
- /* RJ: *iarg = 0: input is from SA7111
- *iarg = 1: input is from ZR36060 */
-
- switch (*iarg) {
- case 0:
- /* Switch RTCE to 1 */
- saa7185_write(client, 0x61,
- (encoder->reg[0x61] & 0xf7) | 0x08);
- saa7185_write(client, 0x6e, 0x01);
- break;
-
- case 1:
- /* Switch RTCE to 0 */
- saa7185_write(client, 0x61,
- (encoder->reg[0x61] & 0xf7) | 0x00);
- /* SW: a slight sync problem... */
- saa7185_write(client, 0x6e, 0x00);
- break;
-
- default:
- return -EINVAL;
- }
+ switch (route->input) {
+ case 0:
+ /* turn off colorbar */
+ saa7185_write(sd, 0x3a, 0x0f);
+ /* Switch RTCE to 1 */
+ saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08);
+ saa7185_write(sd, 0x6e, 0x01);
break;
- }
- case ENCODER_SET_OUTPUT:
- {
- int *iarg = arg;
-
- /* not much choice of outputs */
- if (*iarg != 0)
- return -EINVAL;
+ case 1:
+ /* turn off colorbar */
+ saa7185_write(sd, 0x3a, 0x0f);
+ /* Switch RTCE to 0 */
+ saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x00);
+ /* SW: a slight sync problem... */
+ saa7185_write(sd, 0x6e, 0x00);
break;
- }
-
- case ENCODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
- encoder->enable = !!*iarg;
- saa7185_write(client, 0x61,
- (encoder->reg[0x61] & 0xbf) |
- (encoder->enable ? 0x00 : 0x40));
+ case 2:
+ /* turn on colorbar */
+ saa7185_write(sd, 0x3a, 0x8f);
+ /* Switch RTCE to 0 */
+ saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08);
+ /* SW: a slight sync problem... */
+ saa7185_write(sd, 0x6e, 0x01);
break;
- }
default:
return -EINVAL;
}
-
return 0;
}
+static int saa7185_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7185, 0);
+}
+
/* ----------------------------------------------------------------------- */
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+static const struct v4l2_subdev_core_ops saa7185_core_ops = {
+ .g_chip_ident = saa7185_g_chip_ident,
+ .init = saa7185_init,
+};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_video_ops saa7185_video_ops = {
+ .s_std_output = saa7185_s_std_output,
+ .s_routing = saa7185_s_routing,
+};
+
+static const struct v4l2_subdev_ops saa7185_ops = {
+ .core = &saa7185_core_ops,
+ .video = &saa7185_video_ops,
+};
+
+
+/* ----------------------------------------------------------------------- */
static int saa7185_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int i;
struct saa7185 *encoder;
+ struct v4l2_subdev *sd;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -351,28 +329,29 @@ static int saa7185_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
- encoder->norm = VIDEO_MODE_NTSC;
- encoder->enable = 1;
- i2c_set_clientdata(client, encoder);
+ encoder->norm = V4L2_STD_NTSC;
+ sd = &encoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa7185_ops);
- i = saa7185_write_block(client, init_common, sizeof(init_common));
+ i = saa7185_write_block(sd, init_common, sizeof(init_common));
if (i >= 0)
- i = saa7185_write_block(client, init_ntsc, sizeof(init_ntsc));
+ i = saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
if (i < 0)
- v4l_dbg(1, debug, client, "init error %d\n", i);
+ v4l2_dbg(1, debug, sd, "init error %d\n", i);
else
- v4l_dbg(1, debug, client, "revision 0x%x\n",
- saa7185_read(client) >> 5);
+ v4l2_dbg(1, debug, sd, "revision 0x%x\n",
+ saa7185_read(sd) >> 5);
return 0;
}
static int saa7185_remove(struct i2c_client *client)
{
- struct saa7185 *encoder = i2c_get_clientdata(client);
-
- saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */
- //saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct saa7185 *encoder = to_saa7185(sd);
+ v4l2_device_unregister_subdev(sd);
+ /* SW: output off is active */
+ saa7185_write(sd, 0x61, (encoder->reg[0x61]) | 0x40);
kfree(encoder);
return 0;
}
@@ -387,8 +366,6 @@ MODULE_DEVICE_TABLE(i2c, saa7185_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa7185",
- .driverid = I2C_DRIVERID_SAA7185B,
- .command = saa7185_command,
.probe = saa7185_probe,
.remove = saa7185_remove,
.id_table = saa7185_id,
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
index b4018cce3285..3f523aeec56e 100644
--- a/drivers/media/video/saa7191.c
+++ b/drivers/media/video/saa7191.c
@@ -19,9 +19,11 @@
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
+#include <linux/videodev2.h>
#include <linux/i2c.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
#include "saa7191.h"
@@ -32,6 +34,7 @@ MODULE_VERSION(SAA7191_MODULE_VERSION);
MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
MODULE_LICENSE("GPL");
+
// #define SAA7191_DEBUG
#ifdef SAA7191_DEBUG
@@ -44,17 +47,20 @@ MODULE_LICENSE("GPL");
#define SAA7191_SYNC_DELAY 100 /* milliseconds */
struct saa7191 {
- struct i2c_client *client;
+ struct v4l2_subdev sd;
/* the register values are stored here as the actual
* I2C-registers are write-only */
u8 reg[25];
int input;
- int norm;
+ v4l2_std_id norm;
};
-static struct i2c_driver i2c_driver_saa7191;
+static inline struct saa7191 *to_saa7191(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa7191, sd);
+}
static const u8 initseq[] = {
0, /* Subaddress */
@@ -100,15 +106,14 @@ static const u8 initseq[] = {
/* SAA7191 register handling */
-static u8 saa7191_read_reg(struct i2c_client *client,
- u8 reg)
+static u8 saa7191_read_reg(struct v4l2_subdev *sd, u8 reg)
{
- return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
+ return to_saa7191(sd)->reg[reg];
}
-static int saa7191_read_status(struct i2c_client *client,
- u8 *value)
+static int saa7191_read_status(struct v4l2_subdev *sd, u8 *value)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
ret = i2c_master_recv(client, value, 1);
@@ -121,21 +126,23 @@ static int saa7191_read_status(struct i2c_client *client,
}
-static int saa7191_write_reg(struct i2c_client *client, u8 reg,
- u8 value)
+static int saa7191_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value)
{
- ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ to_saa7191(sd)->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
/* the first byte of data must be the first subaddress number (register) */
-static int saa7191_write_block(struct i2c_client *client,
+static int saa7191_write_block(struct v4l2_subdev *sd,
u8 length, const u8 *data)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct saa7191 *decoder = to_saa7191(sd);
int i;
int ret;
- struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client);
for (i = 0; i < (length - 1); i++) {
decoder->reg[data[0] + i] = data[i + 1];
}
@@ -152,14 +159,15 @@ static int saa7191_write_block(struct i2c_client *client,
/* Helper functions */
-static int saa7191_set_input(struct i2c_client *client, int input)
+static int saa7191_s_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
{
- struct saa7191 *decoder = i2c_get_clientdata(client);
- u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
- u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
+ struct saa7191 *decoder = to_saa7191(sd);
+ u8 luma = saa7191_read_reg(sd, SAA7191_REG_LUMA);
+ u8 iock = saa7191_read_reg(sd, SAA7191_REG_IOCK);
int err;
- switch (input) {
+ switch (route->input) {
case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
| SAA7191_IOCK_GPSW2);
@@ -175,54 +183,50 @@ static int saa7191_set_input(struct i2c_client *client, int input)
return -EINVAL;
}
- err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma);
+ err = saa7191_write_reg(sd, SAA7191_REG_LUMA, luma);
if (err)
return -EIO;
- err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock);
+ err = saa7191_write_reg(sd, SAA7191_REG_IOCK, iock);
if (err)
return -EIO;
- decoder->input = input;
+ decoder->input = route->input;
return 0;
}
-static int saa7191_set_norm(struct i2c_client *client, int norm)
+static int saa7191_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
{
- struct saa7191 *decoder = i2c_get_clientdata(client);
- u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
- u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
- u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
+ struct saa7191 *decoder = to_saa7191(sd);
+ u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC);
+ u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3);
+ u8 chcv = saa7191_read_reg(sd, SAA7191_REG_CHCV);
int err;
- switch(norm) {
- case SAA7191_NORM_PAL:
+ if (norm & V4L2_STD_PAL) {
stdc &= ~SAA7191_STDC_SECS;
ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
chcv = SAA7191_CHCV_PAL;
- break;
- case SAA7191_NORM_NTSC:
+ } else if (norm & V4L2_STD_NTSC) {
stdc &= ~SAA7191_STDC_SECS;
ctl3 &= ~SAA7191_CTL3_AUFD;
ctl3 |= SAA7191_CTL3_FSEL;
chcv = SAA7191_CHCV_NTSC;
- break;
- case SAA7191_NORM_SECAM:
+ } else if (norm & V4L2_STD_SECAM) {
stdc |= SAA7191_STDC_SECS;
ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
chcv = SAA7191_CHCV_PAL;
- break;
- default:
+ } else {
return -EINVAL;
}
- err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
+ err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
if (err)
return -EIO;
- err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
+ err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc);
if (err)
return -EIO;
- err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv);
+ err = saa7191_write_reg(sd, SAA7191_REG_CHCV, chcv);
if (err)
return -EIO;
@@ -230,19 +234,19 @@ static int saa7191_set_norm(struct i2c_client *client, int norm)
dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
stdc, chcv);
- dprintk("norm: %d\n", norm);
+ dprintk("norm: %llx\n", norm);
return 0;
}
-static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
+static int saa7191_wait_for_signal(struct v4l2_subdev *sd, u8 *status)
{
int i = 0;
dprintk("Checking for signal...\n");
for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
- if (saa7191_read_status(client, status))
+ if (saa7191_read_status(sd, status))
return -EIO;
if (((*status) & SAA7191_STATUS_HLCK) == 0) {
@@ -258,31 +262,34 @@ static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
return -EBUSY;
}
-static int saa7191_autodetect_norm_extended(struct i2c_client *client)
+static int saa7191_querystd(struct v4l2_subdev *sd, v4l2_std_id *norm)
{
- u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
- u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
+ struct saa7191 *decoder = to_saa7191(sd);
+ u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC);
+ u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3);
u8 status;
+ v4l2_std_id old_norm = decoder->norm;
int err = 0;
dprintk("SAA7191 extended signal auto-detection...\n");
+ *norm = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
stdc &= ~SAA7191_STDC_SECS;
ctl3 &= ~(SAA7191_CTL3_FSEL);
- err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
+ err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc);
if (err) {
err = -EIO;
goto out;
}
- err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
+ err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
if (err) {
err = -EIO;
goto out;
}
ctl3 |= SAA7191_CTL3_AUFD;
- err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
+ err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
if (err) {
err = -EIO;
goto out;
@@ -290,53 +297,54 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client)
msleep(SAA7191_SYNC_DELAY);
- err = saa7191_wait_for_signal(client, &status);
+ err = saa7191_wait_for_signal(sd, &status);
if (err)
goto out;
if (status & SAA7191_STATUS_FIDT) {
/* 60Hz signal -> NTSC */
dprintk("60Hz signal: NTSC\n");
- return saa7191_set_norm(client, SAA7191_NORM_NTSC);
+ *norm = V4L2_STD_NTSC;
+ return 0;
}
/* 50Hz signal */
dprintk("50Hz signal: Trying PAL...\n");
/* try PAL first */
- err = saa7191_set_norm(client, SAA7191_NORM_PAL);
+ err = saa7191_s_std(sd, V4L2_STD_PAL);
if (err)
goto out;
msleep(SAA7191_SYNC_DELAY);
- err = saa7191_wait_for_signal(client, &status);
+ err = saa7191_wait_for_signal(sd, &status);
if (err)
goto out;
/* not 50Hz ? */
if (status & SAA7191_STATUS_FIDT) {
dprintk("No 50Hz signal\n");
- err = -EAGAIN;
- goto out;
+ saa7191_s_std(sd, old_norm);
+ return -EAGAIN;
}
if (status & SAA7191_STATUS_CODE) {
dprintk("PAL\n");
- return 0;
+ *norm = V4L2_STD_PAL;
+ return saa7191_s_std(sd, old_norm);
}
dprintk("No color detected with PAL - Trying SECAM...\n");
/* no color detected ? -> try SECAM */
- err = saa7191_set_norm(client,
- SAA7191_NORM_SECAM);
+ err = saa7191_s_std(sd, V4L2_STD_SECAM);
if (err)
goto out;
msleep(SAA7191_SYNC_DELAY);
- err = saa7191_wait_for_signal(client, &status);
+ err = saa7191_wait_for_signal(sd, &status);
if (err)
goto out;
@@ -350,32 +358,17 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client)
if (status & SAA7191_STATUS_CODE) {
/* Color detected -> SECAM */
dprintk("SECAM\n");
- return 0;
+ *norm = V4L2_STD_SECAM;
+ return saa7191_s_std(sd, old_norm);
}
dprintk("No color detected with SECAM - Going back to PAL.\n");
- /* still no color detected ?
- * -> set norm back to PAL */
- err = saa7191_set_norm(client,
- SAA7191_NORM_PAL);
- if (err)
- goto out;
-
out:
- ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
- if (ctl3 & SAA7191_CTL3_AUFD) {
- ctl3 &= ~(SAA7191_CTL3_AUFD);
- err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
- if (err) {
- err = -EIO;
- }
- }
-
- return err;
+ return saa7191_s_std(sd, old_norm);
}
-static int saa7191_autodetect_norm(struct i2c_client *client)
+static int saa7191_autodetect_norm(struct v4l2_subdev *sd)
{
u8 status;
@@ -383,7 +376,7 @@ static int saa7191_autodetect_norm(struct i2c_client *client)
dprintk("Reading status...\n");
- if (saa7191_read_status(client, &status))
+ if (saa7191_read_status(sd, &status))
return -EIO;
dprintk("Checking for signal...\n");
@@ -399,26 +392,25 @@ static int saa7191_autodetect_norm(struct i2c_client *client)
if (status & SAA7191_STATUS_FIDT) {
/* 60hz signal -> NTSC */
dprintk("NTSC\n");
- return saa7191_set_norm(client, SAA7191_NORM_NTSC);
+ return saa7191_s_std(sd, V4L2_STD_NTSC);
} else {
/* 50hz signal -> PAL */
dprintk("PAL\n");
- return saa7191_set_norm(client, SAA7191_NORM_PAL);
+ return saa7191_s_std(sd, V4L2_STD_PAL);
}
}
-static int saa7191_get_control(struct i2c_client *client,
- struct saa7191_control *ctrl)
+static int saa7191_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
u8 reg;
int ret = 0;
- switch (ctrl->type) {
+ switch (ctrl->id) {
case SAA7191_CONTROL_BANDPASS:
case SAA7191_CONTROL_BANDPASS_WEIGHT:
case SAA7191_CONTROL_CORING:
- reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
- switch (ctrl->type) {
+ reg = saa7191_read_reg(sd, SAA7191_REG_LUMA);
+ switch (ctrl->id) {
case SAA7191_CONTROL_BANDPASS:
ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
>> SAA7191_LUMA_BPSS_SHIFT;
@@ -435,15 +427,15 @@ static int saa7191_get_control(struct i2c_client *client,
break;
case SAA7191_CONTROL_FORCE_COLOUR:
case SAA7191_CONTROL_CHROMA_GAIN:
- reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
- if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR)
+ reg = saa7191_read_reg(sd, SAA7191_REG_GAIN);
+ if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR)
ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
else
ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
>> SAA7191_GAIN_LFIS_SHIFT;
break;
- case SAA7191_CONTROL_HUE:
- reg = saa7191_read_reg(client, SAA7191_REG_HUEC);
+ case V4L2_CID_HUE:
+ reg = saa7191_read_reg(sd, SAA7191_REG_HUEC);
if (reg < 0x80)
reg += 0x80;
else
@@ -451,18 +443,18 @@ static int saa7191_get_control(struct i2c_client *client,
ctrl->value = (s32)reg;
break;
case SAA7191_CONTROL_VTRC:
- reg = saa7191_read_reg(client, SAA7191_REG_STDC);
+ reg = saa7191_read_reg(sd, SAA7191_REG_STDC);
ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
break;
case SAA7191_CONTROL_LUMA_DELAY:
- reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
+ reg = saa7191_read_reg(sd, SAA7191_REG_CTL3);
ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
>> SAA7191_CTL3_YDEL_SHIFT;
if (ctrl->value >= 4)
ctrl->value -= 8;
break;
case SAA7191_CONTROL_VNR:
- reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
+ reg = saa7191_read_reg(sd, SAA7191_REG_CTL4);
ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
>> SAA7191_CTL4_VNOI_SHIFT;
break;
@@ -473,18 +465,17 @@ static int saa7191_get_control(struct i2c_client *client,
return ret;
}
-static int saa7191_set_control(struct i2c_client *client,
- struct saa7191_control *ctrl)
+static int saa7191_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
u8 reg;
int ret = 0;
- switch (ctrl->type) {
+ switch (ctrl->id) {
case SAA7191_CONTROL_BANDPASS:
case SAA7191_CONTROL_BANDPASS_WEIGHT:
case SAA7191_CONTROL_CORING:
- reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
- switch (ctrl->type) {
+ reg = saa7191_read_reg(sd, SAA7191_REG_LUMA);
+ switch (ctrl->id) {
case SAA7191_CONTROL_BANDPASS:
reg &= ~SAA7191_LUMA_BPSS_MASK;
reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
@@ -501,12 +492,12 @@ static int saa7191_set_control(struct i2c_client *client,
& SAA7191_LUMA_CORI_MASK;
break;
}
- ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg);
+ ret = saa7191_write_reg(sd, SAA7191_REG_LUMA, reg);
break;
case SAA7191_CONTROL_FORCE_COLOUR:
case SAA7191_CONTROL_CHROMA_GAIN:
- reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
- if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) {
+ reg = saa7191_read_reg(sd, SAA7191_REG_GAIN);
+ if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) {
if (ctrl->value)
reg |= SAA7191_GAIN_COLO;
else
@@ -516,41 +507,41 @@ static int saa7191_set_control(struct i2c_client *client,
reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT)
& SAA7191_GAIN_LFIS_MASK;
}
- ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg);
+ ret = saa7191_write_reg(sd, SAA7191_REG_GAIN, reg);
break;
- case SAA7191_CONTROL_HUE:
+ case V4L2_CID_HUE:
reg = ctrl->value & 0xff;
if (reg < 0x80)
reg += 0x80;
else
reg -= 0x80;
- ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg);
+ ret = saa7191_write_reg(sd, SAA7191_REG_HUEC, reg);
break;
case SAA7191_CONTROL_VTRC:
- reg = saa7191_read_reg(client, SAA7191_REG_STDC);
+ reg = saa7191_read_reg(sd, SAA7191_REG_STDC);
if (ctrl->value)
reg |= SAA7191_STDC_VTRC;
else
reg &= ~SAA7191_STDC_VTRC;
- ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg);
+ ret = saa7191_write_reg(sd, SAA7191_REG_STDC, reg);
break;
case SAA7191_CONTROL_LUMA_DELAY: {
s32 value = ctrl->value;
if (value < 0)
value += 8;
- reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
+ reg = saa7191_read_reg(sd, SAA7191_REG_CTL3);
reg &= ~SAA7191_CTL3_YDEL_MASK;
reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
& SAA7191_CTL3_YDEL_MASK;
- ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg);
+ ret = saa7191_write_reg(sd, SAA7191_REG_CTL3, reg);
break;
}
case SAA7191_CONTROL_VNR:
- reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
+ reg = saa7191_read_reg(sd, SAA7191_REG_CTL4);
reg &= ~SAA7191_CTL4_VNOI_MASK;
reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
& SAA7191_CTL4_VNOI_MASK;
- ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg);
+ ret = saa7191_write_reg(sd, SAA7191_REG_CTL4, reg);
break;
default:
ret = -EINVAL;
@@ -561,247 +552,108 @@ static int saa7191_set_control(struct i2c_client *client,
/* I2C-interface */
-static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
+static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status)
{
- int err = 0;
- struct saa7191 *decoder;
- struct i2c_client *client;
-
- printk(KERN_INFO "Philips SAA7191 driver version %s\n",
- SAA7191_MODULE_VERSION);
-
- client = kzalloc(sizeof(*client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
- if (!decoder) {
- err = -ENOMEM;
- goto out_free_client;
- }
-
- client->addr = addr;
- client->adapter = adap;
- client->driver = &i2c_driver_saa7191;
- client->flags = 0;
- strcpy(client->name, "saa7191 client");
- i2c_set_clientdata(client, decoder);
-
- decoder->client = client;
-
- err = i2c_attach_client(client);
- if (err)
- goto out_free_decoder;
-
- err = saa7191_write_block(client, sizeof(initseq), initseq);
- if (err) {
- printk(KERN_ERR "SAA7191 initialization failed\n");
- goto out_detach_client;
- }
-
- printk(KERN_INFO "SAA7191 initialized\n");
-
- decoder->input = SAA7191_INPUT_COMPOSITE;
- decoder->norm = SAA7191_NORM_PAL;
-
- err = saa7191_autodetect_norm(client);
- if (err && (err != -EBUSY)) {
- printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
- }
+ u8 status_reg;
+ int res = V4L2_IN_ST_NO_SIGNAL;
+ if (saa7191_read_status(sd, &status_reg))
+ return -EIO;
+ if ((status_reg & SAA7191_STATUS_HLCK) == 0)
+ res = 0;
+ if (!(status_reg & SAA7191_STATUS_CODE))
+ res |= V4L2_IN_ST_NO_COLOR;
+ *status = res;
return 0;
-
-out_detach_client:
- i2c_detach_client(client);
-out_free_decoder:
- kfree(decoder);
-out_free_client:
- kfree(client);
- return err;
}
-static int saa7191_probe(struct i2c_adapter *adap)
-{
- /* Always connected to VINO */
- if (adap->id == I2C_HW_SGI_VINO)
- return saa7191_attach(adap, SAA7191_ADDR, 0);
- /* Feel free to add probe here :-) */
- return -ENODEV;
-}
-static int saa7191_detach(struct i2c_client *client)
+static int saa7191_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
{
- struct saa7191 *decoder = i2c_get_clientdata(client);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- i2c_detach_client(client);
- kfree(decoder);
- kfree(client);
- return 0;
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7191, 0);
}
-static int saa7191_command(struct i2c_client *client, unsigned int cmd,
- void *arg)
-{
- struct saa7191 *decoder = i2c_get_clientdata(client);
+/* ----------------------------------------------------------------------- */
- switch (cmd) {
- case DECODER_GET_CAPABILITIES: {
- struct video_decoder_capability *cap = arg;
+static const struct v4l2_subdev_core_ops saa7191_core_ops = {
+ .g_chip_ident = saa7191_g_chip_ident,
+ .g_ctrl = saa7191_g_ctrl,
+ .s_ctrl = saa7191_s_ctrl,
+};
- cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
- VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
- cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
- cap->outputs = 1;
- break;
- }
- case DECODER_GET_STATUS: {
- int *iarg = arg;
- u8 status;
- int res = 0;
+static const struct v4l2_subdev_tuner_ops saa7191_tuner_ops = {
+ .s_std = saa7191_s_std,
+};
- if (saa7191_read_status(client, &status)) {
- return -EIO;
- }
- if ((status & SAA7191_STATUS_HLCK) == 0)
- res |= DECODER_STATUS_GOOD;
- if (status & SAA7191_STATUS_CODE)
- res |= DECODER_STATUS_COLOR;
- switch (decoder->norm) {
- case SAA7191_NORM_NTSC:
- res |= DECODER_STATUS_NTSC;
- break;
- case SAA7191_NORM_PAL:
- res |= DECODER_STATUS_PAL;
- break;
- case SAA7191_NORM_SECAM:
- res |= DECODER_STATUS_SECAM;
- break;
- case SAA7191_NORM_AUTO:
- default:
- if (status & SAA7191_STATUS_FIDT)
- res |= DECODER_STATUS_NTSC;
- else
- res |= DECODER_STATUS_PAL;
- break;
- }
- *iarg = res;
- break;
- }
- case DECODER_SET_NORM: {
- int *iarg = arg;
-
- switch (*iarg) {
- case VIDEO_MODE_AUTO:
- return saa7191_autodetect_norm(client);
- case VIDEO_MODE_PAL:
- return saa7191_set_norm(client, SAA7191_NORM_PAL);
- case VIDEO_MODE_NTSC:
- return saa7191_set_norm(client, SAA7191_NORM_NTSC);
- case VIDEO_MODE_SECAM:
- return saa7191_set_norm(client, SAA7191_NORM_SECAM);
- default:
- return -EINVAL;
- }
- break;
- }
- case DECODER_SET_INPUT: {
- int *iarg = arg;
-
- switch (client->adapter->id) {
- case I2C_HW_SGI_VINO:
- return saa7191_set_input(client, *iarg);
- default:
- if (*iarg != 0)
- return -EINVAL;
- }
- break;
- }
- case DECODER_SET_OUTPUT: {
- int *iarg = arg;
+static const struct v4l2_subdev_video_ops saa7191_video_ops = {
+ .s_routing = saa7191_s_routing,
+ .querystd = saa7191_querystd,
+ .g_input_status = saa7191_g_input_status,
+};
- /* not much choice of outputs */
- if (*iarg != 0)
- return -EINVAL;
- break;
- }
- case DECODER_ENABLE_OUTPUT: {
- /* Always enabled */
- break;
- }
- case DECODER_SET_PICTURE: {
- struct video_picture *pic = arg;
- unsigned val;
- int err;
+static const struct v4l2_subdev_ops saa7191_ops = {
+ .core = &saa7191_core_ops,
+ .video = &saa7191_video_ops,
+ .tuner = &saa7191_tuner_ops,
+};
- val = (pic->hue >> 8) - 0x80;
+static int saa7191_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int err = 0;
+ struct saa7191 *decoder;
+ struct v4l2_subdev *sd;
- err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
- if (err)
- return -EIO;
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
- break;
- }
- case DECODER_SAA7191_GET_STATUS: {
- struct saa7191_status *status = arg;
- u8 status_reg;
+ decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
+ if (!decoder)
+ return -ENOMEM;
- if (saa7191_read_status(client, &status_reg))
- return -EIO;
+ sd = &decoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa7191_ops);
- status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
- ? 1 : 0;
- status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT)
- ? 1 : 0;
- status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0;
+ err = saa7191_write_block(sd, sizeof(initseq), initseq);
+ if (err) {
+ printk(KERN_ERR "SAA7191 initialization failed\n");
+ kfree(decoder);
+ return err;
+ }
- status->input = decoder->input;
- status->norm = decoder->norm;
+ printk(KERN_INFO "SAA7191 initialized\n");
- break;
- }
- case DECODER_SAA7191_SET_NORM: {
- int *norm = arg;
-
- switch (*norm) {
- case SAA7191_NORM_AUTO:
- return saa7191_autodetect_norm(client);
- case SAA7191_NORM_AUTO_EXT:
- return saa7191_autodetect_norm_extended(client);
- default:
- return saa7191_set_norm(client, *norm);
- }
- }
- case DECODER_SAA7191_GET_CONTROL: {
- return saa7191_get_control(client, arg);
- }
- case DECODER_SAA7191_SET_CONTROL: {
- return saa7191_set_control(client, arg);
- }
- default:
- return -EINVAL;
- }
+ decoder->input = SAA7191_INPUT_COMPOSITE;
+ decoder->norm = V4L2_STD_PAL;
+
+ err = saa7191_autodetect_norm(sd);
+ if (err && (err != -EBUSY))
+ printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
return 0;
}
-static struct i2c_driver i2c_driver_saa7191 = {
- .driver = {
- .name = "saa7191",
- },
- .id = I2C_DRIVERID_SAA7191,
- .attach_adapter = saa7191_probe,
- .detach_client = saa7191_detach,
- .command = saa7191_command
-};
-
-static int saa7191_init(void)
+static int saa7191_remove(struct i2c_client *client)
{
- return i2c_add_driver(&i2c_driver_saa7191);
-}
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
-static void saa7191_exit(void)
-{
- i2c_del_driver(&i2c_driver_saa7191);
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_saa7191(sd));
+ return 0;
}
-module_init(saa7191_init);
-module_exit(saa7191_exit);
+static const struct i2c_device_id saa7191_id[] = {
+ { "saa7191", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7191_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "saa7191",
+ .probe = saa7191_probe,
+ .remove = saa7191_remove,
+ .id_table = saa7191_id,
+};
diff --git a/drivers/media/video/saa7191.h b/drivers/media/video/saa7191.h
index a2310da1940d..803c74d6066f 100644
--- a/drivers/media/video/saa7191.h
+++ b/drivers/media/video/saa7191.h
@@ -176,11 +176,9 @@
#define SAA7191_INPUT_COMPOSITE 0
#define SAA7191_INPUT_SVIDEO 1
-#define SAA7191_NORM_AUTO 0
#define SAA7191_NORM_PAL 1
#define SAA7191_NORM_NTSC 2
#define SAA7191_NORM_SECAM 3
-#define SAA7191_NORM_AUTO_EXT 4 /* extended auto-detection */
struct saa7191_status {
/* 0=no signal, 1=signal detected */
@@ -232,24 +230,16 @@ struct saa7191_status {
#define SAA7191_VNR_MAX 0x03
#define SAA7191_VNR_DEFAULT 0x00
-#define SAA7191_CONTROL_BANDPASS 0
-#define SAA7191_CONTROL_BANDPASS_WEIGHT 1
-#define SAA7191_CONTROL_CORING 2
-#define SAA7191_CONTROL_FORCE_COLOUR 3 /* boolean */
-#define SAA7191_CONTROL_CHROMA_GAIN 4
-#define SAA7191_CONTROL_HUE 5
-#define SAA7191_CONTROL_VTRC 6 /* boolean */
-#define SAA7191_CONTROL_LUMA_DELAY 7
-#define SAA7191_CONTROL_VNR 8
-
-struct saa7191_control {
- u8 type;
- s32 value;
-};
+#define SAA7191_CONTROL_BANDPASS (V4L2_CID_PRIVATE_BASE + 0)
+#define SAA7191_CONTROL_BANDPASS_WEIGHT (V4L2_CID_PRIVATE_BASE + 1)
+#define SAA7191_CONTROL_CORING (V4L2_CID_PRIVATE_BASE + 2)
+#define SAA7191_CONTROL_FORCE_COLOUR (V4L2_CID_PRIVATE_BASE + 3)
+#define SAA7191_CONTROL_CHROMA_GAIN (V4L2_CID_PRIVATE_BASE + 4)
+#define SAA7191_CONTROL_VTRC (V4L2_CID_PRIVATE_BASE + 5)
+#define SAA7191_CONTROL_LUMA_DELAY (V4L2_CID_PRIVATE_BASE + 6)
+#define SAA7191_CONTROL_VNR (V4L2_CID_PRIVATE_BASE + 7)
#define DECODER_SAA7191_GET_STATUS _IOR('d', 195, struct saa7191_status)
#define DECODER_SAA7191_SET_NORM _IOW('d', 196, int)
-#define DECODER_SAA7191_GET_CONTROL _IOR('d', 197, struct saa7191_control)
-#define DECODER_SAA7191_SET_CONTROL _IOW('d', 198, struct saa7191_control)
#endif
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index ddcb81d0b81a..b5e37a530c62 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -94,13 +94,37 @@ struct sh_mobile_ceu_dev {
spinlock_t lock;
struct list_head capture;
struct videobuf_buffer *active;
- int is_interlace;
+ int is_interlaced;
struct sh_mobile_ceu_info *pdata;
const struct soc_camera_data_format *camera_fmt;
};
+static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev)
+{
+ unsigned long flags;
+
+ flags = SOCAM_MASTER |
+ SOCAM_PCLK_SAMPLE_RISING |
+ SOCAM_HSYNC_ACTIVE_HIGH |
+ SOCAM_HSYNC_ACTIVE_LOW |
+ SOCAM_VSYNC_ACTIVE_HIGH |
+ SOCAM_VSYNC_ACTIVE_LOW |
+ SOCAM_DATA_ACTIVE_HIGH;
+
+ if (pcdev->pdata->flags & SH_CEU_FLAG_USE_8BIT_BUS)
+ flags |= SOCAM_DATAWIDTH_8;
+
+ if (pcdev->pdata->flags & SH_CEU_FLAG_USE_16BIT_BUS)
+ flags |= SOCAM_DATAWIDTH_16;
+
+ if (flags & SOCAM_DATAWIDTH_MASK)
+ return flags;
+
+ return 0;
+}
+
static void ceu_write(struct sh_mobile_ceu_dev *priv,
unsigned long reg_offs, u32 data)
{
@@ -150,6 +174,7 @@ static void free_buffer(struct videobuf_queue *vq,
if (in_interrupt())
BUG();
+ videobuf_waiton(&buf->vb, 0, 0);
videobuf_dma_contig_free(vq, &buf->vb);
dev_dbg(&icd->dev, "%s freed\n", __func__);
buf->vb.state = VIDEOBUF_NEEDS_INIT;
@@ -181,7 +206,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
phys_addr_top = videobuf_to_dma_contig(pcdev->active);
ceu_write(pcdev, CDAYR, phys_addr_top);
- if (pcdev->is_interlace) {
+ if (pcdev->is_interlaced) {
phys_addr_bottom = phys_addr_top + icd->width;
ceu_write(pcdev, CDBYR, phys_addr_bottom);
}
@@ -193,7 +218,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
case V4L2_PIX_FMT_NV61:
phys_addr_top += icd->width * icd->height;
ceu_write(pcdev, CDACR, phys_addr_top);
- if (pcdev->is_interlace) {
+ if (pcdev->is_interlaced) {
phys_addr_bottom = phys_addr_top + icd->width;
ceu_write(pcdev, CDBCR, phys_addr_bottom);
}
@@ -396,7 +421,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
camera_flags = icd->ops->query_bus_param(icd);
common_flags = soc_camera_bus_param_compatible(camera_flags,
- pcdev->pdata->flags);
+ make_bus_param(pcdev));
if (!common_flags)
return -EINVAL;
@@ -457,7 +482,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
ceu_write(pcdev, CAMCR, value);
ceu_write(pcdev, CAPCR, 0x00300000);
- ceu_write(pcdev, CAIFR, (pcdev->is_interlace) ? 0x101 : 0);
+ ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0);
mdelay(1);
@@ -473,7 +498,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
}
height = icd->height;
- if (pcdev->is_interlace) {
+ if (pcdev->is_interlaced) {
height /= 2;
cdwdr_width *= 2;
}
@@ -517,7 +542,7 @@ static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd)
camera_flags = icd->ops->query_bus_param(icd);
common_flags = soc_camera_bus_param_compatible(camera_flags,
- pcdev->pdata->flags);
+ make_bus_param(pcdev));
if (!common_flags)
return -EINVAL;
@@ -562,11 +587,29 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
if (ret < 0)
return 0;
+ /* Beginning of a pass */
+ if (!idx)
+ icd->host_priv = NULL;
+
switch (icd->formats[idx].fourcc) {
case V4L2_PIX_FMT_UYVY:
case V4L2_PIX_FMT_VYUY:
case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_YVYU:
+ if (icd->host_priv)
+ goto add_single_format;
+
+ /*
+ * Our case is simple so far: for any of the above four camera
+ * formats we add all our four synthesized NV* formats, so,
+ * just marking the device with a single flag suffices. If
+ * the format generation rules are more complex, you would have
+ * to actually hang your already added / counted formats onto
+ * the host_priv pointer and check whether the format you're
+ * going to add now is already there.
+ */
+ icd->host_priv = (void *)sh_mobile_ceu_formats;
+
n = ARRAY_SIZE(sh_mobile_ceu_formats);
formats += n;
for (k = 0; xlate && k < n; k++) {
@@ -579,6 +622,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
icd->formats[idx].name);
}
default:
+add_single_format:
/* Generic pass-through */
formats++;
if (xlate) {
@@ -595,24 +639,30 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
return formats;
}
+static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ return icd->ops->set_crop(icd, rect);
+}
+
static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+ struct v4l2_format *f)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
+ __u32 pixfmt = f->fmt.pix.pixelformat;
const struct soc_camera_format_xlate *xlate;
+ struct v4l2_format cam_f = *f;
int ret;
- if (!pixfmt)
- return icd->ops->set_fmt(icd, pixfmt, rect);
-
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
if (!xlate) {
dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
return -EINVAL;
}
- ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect);
+ cam_f.fmt.pix.pixelformat = xlate->cam_fmt->fourcc;
+ ret = icd->ops->set_fmt(icd, &cam_f);
if (!ret) {
icd->buswidth = xlate->buswidth;
@@ -662,13 +712,13 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
switch (f->fmt.pix.field) {
case V4L2_FIELD_INTERLACED:
- pcdev->is_interlace = 1;
+ pcdev->is_interlaced = 1;
break;
case V4L2_FIELD_ANY:
f->fmt.pix.field = V4L2_FIELD_NONE;
/* fall-through */
case V4L2_FIELD_NONE:
- pcdev->is_interlace = 0;
+ pcdev->is_interlaced = 0;
break;
default:
ret = -EINVAL;
@@ -734,7 +784,8 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
&sh_mobile_ceu_videobuf_ops,
&ici->dev, &pcdev->lock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_ANY,
+ pcdev->is_interlaced ?
+ V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE,
sizeof(struct sh_mobile_ceu_buffer),
icd);
}
@@ -744,6 +795,7 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
.add = sh_mobile_ceu_add_device,
.remove = sh_mobile_ceu_remove_device,
.get_formats = sh_mobile_ceu_get_formats,
+ .set_crop = sh_mobile_ceu_set_crop,
.set_fmt = sh_mobile_ceu_set_fmt,
.try_fmt = sh_mobile_ceu_try_fmt,
.reqbufs = sh_mobile_ceu_reqbufs,
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index 8cb3457e778d..38a716020d7f 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -96,9 +96,7 @@ static const struct usb_device_id sn9c102_id_table[] = {
#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
{ SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
-#endif
{ SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
-#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
{ SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
#endif
{ SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
@@ -123,7 +121,9 @@ static const struct usb_device_id sn9c102_id_table[] = {
{ SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), },
#endif
{ SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
{ SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
+#endif
{ SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), },
{ }
};
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index fcb05f06de8f..6d8bfd4d97e2 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -30,6 +30,10 @@
#include <media/videobuf-core.h>
#include <media/soc_camera.h>
+/* Default to VGA resolution */
+#define DEFAULT_WIDTH 640
+#define DEFAULT_HEIGHT 480
+
static LIST_HEAD(hosts);
static LIST_HEAD(devices);
static DEFINE_MUTEX(list_lock);
@@ -256,6 +260,46 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd)
vfree(icd->user_formats);
}
+/* Called with .vb_lock held */
+static int soc_camera_set_fmt(struct soc_camera_file *icf,
+ struct v4l2_format *f)
+{
+ struct soc_camera_device *icd = icf->icd;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ int ret;
+
+ /* We always call try_fmt() before set_fmt() or set_crop() */
+ ret = ici->ops->try_fmt(icd, f);
+ if (ret < 0)
+ return ret;
+
+ ret = ici->ops->set_fmt(icd, f);
+ if (ret < 0) {
+ return ret;
+ } else if (!icd->current_fmt ||
+ icd->current_fmt->fourcc != pix->pixelformat) {
+ dev_err(&ici->dev,
+ "Host driver hasn't set up current format correctly!\n");
+ return -EINVAL;
+ }
+
+ icd->width = pix->width;
+ icd->height = pix->height;
+ icf->vb_vidq.field =
+ icd->field = pix->field;
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
+ f->type);
+
+ dev_dbg(&icd->dev, "set width: %d height: %d\n",
+ icd->width, icd->height);
+
+ /* set physical bus parameters */
+ return ici->ops->set_bus_param(icd, pix->pixelformat);
+}
+
static int soc_camera_open(struct file *file)
{
struct video_device *vdev;
@@ -297,14 +341,28 @@ static int soc_camera_open(struct file *file)
/* Now we really have to activate the camera */
if (icd->use_count == 1) {
- ret = soc_camera_init_user_formats(icd);
- if (ret < 0)
- goto eiufmt;
+ /* Restore parameters before the last close() per V4L2 API */
+ struct v4l2_format f = {
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .fmt.pix = {
+ .width = icd->width,
+ .height = icd->height,
+ .field = icd->field,
+ .pixelformat = icd->current_fmt->fourcc,
+ .colorspace = icd->current_fmt->colorspace,
+ },
+ };
+
ret = ici->ops->add(icd);
if (ret < 0) {
dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
goto eiciadd;
}
+
+ /* Try to configure with default parameters */
+ ret = soc_camera_set_fmt(icf, &f);
+ if (ret < 0)
+ goto esfmt;
}
mutex_unlock(&icd->video_lock);
@@ -316,10 +374,13 @@ static int soc_camera_open(struct file *file)
return 0;
- /* First two errors are entered with the .video_lock held */
+ /*
+ * First three errors are entered with the .video_lock held
+ * and use_count == 1
+ */
+esfmt:
+ ici->ops->remove(icd);
eiciadd:
- soc_camera_free_user_formats(icd);
-eiufmt:
icd->use_count--;
mutex_unlock(&icd->video_lock);
module_put(ici->ops->owner);
@@ -339,10 +400,9 @@ static int soc_camera_close(struct file *file)
mutex_lock(&icd->video_lock);
icd->use_count--;
- if (!icd->use_count) {
+ if (!icd->use_count)
ici->ops->remove(icd);
- soc_camera_free_user_formats(icd);
- }
+
mutex_unlock(&icd->video_lock);
module_put(icd->ops->owner);
@@ -415,18 +475,10 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
{
struct soc_camera_file *icf = file->private_data;
struct soc_camera_device *icd = icf->icd;
- struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
- struct v4l2_pix_format *pix = &f->fmt.pix;
- __u32 pixfmt = pix->pixelformat;
int ret;
- struct v4l2_rect rect;
WARN_ON(priv != file->private_data);
- ret = soc_camera_try_fmt_vid_cap(file, priv, f);
- if (ret < 0)
- return ret;
-
mutex_lock(&icf->vb_vidq.vb_lock);
if (videobuf_queue_is_busy(&icf->vb_vidq)) {
@@ -435,33 +487,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
goto unlock;
}
- rect.left = icd->x_current;
- rect.top = icd->y_current;
- rect.width = pix->width;
- rect.height = pix->height;
- ret = ici->ops->set_fmt(icd, pix->pixelformat, &rect);
- if (ret < 0) {
- goto unlock;
- } else if (!icd->current_fmt ||
- icd->current_fmt->fourcc != pixfmt) {
- dev_err(&ici->dev,
- "Host driver hasn't set up current format correctly!\n");
- ret = -EINVAL;
- goto unlock;
- }
-
- icd->width = rect.width;
- icd->height = rect.height;
- icf->vb_vidq.field = pix->field;
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
- f->type);
-
- dev_dbg(&icd->dev, "set width: %d height: %d\n",
- icd->width, icd->height);
-
- /* set physical bus parameters */
- ret = ici->ops->set_bus_param(icd, pixfmt);
+ ret = soc_camera_set_fmt(icf, f);
unlock:
mutex_unlock(&icf->vb_vidq.vb_lock);
@@ -648,8 +674,8 @@ static int soc_camera_cropcap(struct file *file, void *fh,
a->bounds.height = icd->height_max;
a->defrect.left = icd->x_min;
a->defrect.top = icd->y_min;
- a->defrect.width = 640;
- a->defrect.height = 480;
+ a->defrect.width = DEFAULT_WIDTH;
+ a->defrect.height = DEFAULT_HEIGHT;
a->pixelaspect.numerator = 1;
a->pixelaspect.denominator = 1;
@@ -685,7 +711,7 @@ static int soc_camera_s_crop(struct file *file, void *fh,
/* Cropping is allowed during a running capture, guard consistency */
mutex_lock(&icf->vb_vidq.vb_lock);
- ret = ici->ops->set_fmt(icd, 0, &a->c);
+ ret = ici->ops->set_crop(icd, &a->c);
if (!ret) {
icd->width = a->c.width;
icd->height = a->c.height;
@@ -844,9 +870,18 @@ static int soc_camera_probe(struct device *dev)
qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
icd->exposure = qctrl ? qctrl->default_value :
(unsigned short)~0;
+
+ ret = soc_camera_init_user_formats(icd);
+ if (ret < 0)
+ goto eiufmt;
+
+ icd->height = DEFAULT_HEIGHT;
+ icd->width = DEFAULT_WIDTH;
+ icd->field = V4L2_FIELD_ANY;
}
- ici->ops->remove(icd);
+eiufmt:
+ ici->ops->remove(icd);
eiadd:
mutex_unlock(&icd->video_lock);
module_put(ici->ops->owner);
@@ -865,6 +900,8 @@ static int soc_camera_remove(struct device *dev)
if (icd->ops->remove)
icd->ops->remove(icd);
+ soc_camera_free_user_formats(icd);
+
return 0;
}
@@ -918,6 +955,7 @@ int soc_camera_host_register(struct soc_camera_host *ici)
if (!ici || !ici->ops ||
!ici->ops->try_fmt ||
!ici->ops->set_fmt ||
+ !ici->ops->set_crop ||
!ici->ops->set_bus_param ||
!ici->ops->querycap ||
!ici->ops->init_videobuf ||
@@ -998,6 +1036,7 @@ int soc_camera_device_register(struct soc_camera_device *icd)
!icd->ops->release ||
!icd->ops->start_capture ||
!icd->ops->stop_capture ||
+ !icd->ops->set_crop ||
!icd->ops->set_fmt ||
!icd->ops->try_fmt ||
!icd->ops->query_bus_param ||
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index 013ab06e3180..c48676356ab7 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -79,8 +79,14 @@ soc_camera_platform_query_bus_param(struct soc_camera_device *icd)
return p->bus_param;
}
+static int soc_camera_platform_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ return 0;
+}
+
static int soc_camera_platform_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+ struct v4l2_format *f)
{
return 0;
}
@@ -125,6 +131,7 @@ static struct soc_camera_ops soc_camera_platform_ops = {
.release = soc_camera_platform_release,
.start_capture = soc_camera_platform_start_capture,
.stop_capture = soc_camera_platform_stop_capture,
+ .set_crop = soc_camera_platform_set_crop,
.set_fmt = soc_camera_platform_set_fmt,
.try_fmt = soc_camera_platform_try_fmt,
.set_bus_param = soc_camera_platform_set_bus_param,
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index 26378cf390fc..1a6d39cbd6f3 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -933,8 +933,6 @@ static int stk_vidioc_s_ctrl(struct file *filp,
static int stk_vidioc_enum_fmt_vid_cap(struct file *filp,
void *priv, struct v4l2_fmtdesc *fmtd)
{
- fmtd->flags = 0;
-
switch (fmtd->index) {
case 0:
fmtd->pixelformat = V4L2_PIX_FMT_RGB565;
@@ -992,7 +990,6 @@ static int stk_vidioc_g_fmt_vid_cap(struct file *filp,
pix_format->height = stk_sizes[i].h;
pix_format->field = V4L2_FIELD_NONE;
pix_format->colorspace = V4L2_COLORSPACE_SRGB;
- pix_format->priv = 0;
pix_format->pixelformat = dev->vsettings.palette;
if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8)
pix_format->bytesperline = pix_format->width;
@@ -1115,8 +1112,6 @@ static int stk_vidioc_reqbufs(struct file *filp,
if (dev == NULL)
return -ENODEV;
- if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (rb->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
if (is_streaming(dev)
@@ -1139,16 +1134,10 @@ static int stk_vidioc_reqbufs(struct file *filp,
static int stk_vidioc_querybuf(struct file *filp,
void *priv, struct v4l2_buffer *buf)
{
- int index;
struct stk_camera *dev = priv;
struct stk_sio_buffer *sbuf;
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- index = buf->index;
-
- if (index < 0 || index >= dev->n_sbufs)
+ if (buf->index < 0 || buf->index >= dev->n_sbufs)
return -EINVAL;
sbuf = dev->sio_bufs + buf->index;
*buf = sbuf->v4lbuf;
@@ -1161,8 +1150,6 @@ static int stk_vidioc_qbuf(struct file *filp,
struct stk_camera *dev = priv;
struct stk_sio_buffer *sbuf;
unsigned long flags;
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (buf->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
@@ -1189,8 +1176,7 @@ static int stk_vidioc_dqbuf(struct file *filp,
unsigned long flags;
int ret;
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
- || !is_streaming(dev))
+ if (!is_streaming(dev))
return -EINVAL;
if (filp->f_flags & O_NONBLOCK && list_empty(&dev->sio_full))
@@ -1249,16 +1235,10 @@ static int stk_vidioc_streamoff(struct file *filp,
static int stk_vidioc_g_parm(struct file *filp,
void *priv, struct v4l2_streamparm *sp)
{
- if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- sp->parm.capture.capability = 0;
- sp->parm.capture.capturemode = 0;
/*FIXME This is not correct */
sp->parm.capture.timeperframe.numerator = 1;
sp->parm.capture.timeperframe.denominator = 30;
sp->parm.capture.readbuffers = 2;
- sp->parm.capture.extendedmode = 0;
return 0;
}
diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c
index 29991d1cf13e..b30c49248217 100644
--- a/drivers/media/video/tcm825x.c
+++ b/drivers/media/video/tcm825x.c
@@ -50,7 +50,7 @@ struct tcm825x_sensor {
};
/* list of image formats supported by TCM825X sensor */
-const static struct v4l2_fmtdesc tcm825x_formats[] = {
+static const struct v4l2_fmtdesc tcm825x_formats[] = {
{
.description = "YUYV (YUV 4:2:2), packed",
.pixelformat = V4L2_PIX_FMT_UYVY,
@@ -76,15 +76,15 @@ const static struct v4l2_fmtdesc tcm825x_formats[] = {
* TCM825X register configuration for all combinations of pixel format and
* image size
*/
-const static struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ };
-const static struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ };
-const static struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ };
-const static struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ };
-const static struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ };
-const static struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ };
+static const struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ };
+static const struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ };
+static const struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ };
+static const struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ };
+static const struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ };
+static const struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ };
-const static struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT };
-const static struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT };
+static const struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT };
+static const struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT };
/* Our own specific controls */
#define V4L2_CID_ALC V4L2_CID_PRIVATE_BASE
@@ -248,10 +248,10 @@ static struct vcontrol {
};
-const static struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] =
+static const struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] =
{ &subqcif, &qqvga, &qcif, &qvga, &cif, &vga };
-const static struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] =
+static const struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] =
{ &yuv422, &rgb565 };
/*
diff --git a/drivers/media/video/tcm825x.h b/drivers/media/video/tcm825x.h
index 770ebacfa344..5b7e69682368 100644
--- a/drivers/media/video/tcm825x.h
+++ b/drivers/media/video/tcm825x.h
@@ -188,7 +188,7 @@ struct tcm825x_platform_data {
/* Array of image sizes supported by TCM825X. These must be ordered from
* smallest image size to largest.
*/
-const static struct capture_size tcm825x_sizes[] = {
+static const struct capture_size tcm825x_sizes[] = {
{ 128, 96 }, /* subQCIF */
{ 160, 120 }, /* QQVGA */
{ 176, 144 }, /* QCIF */
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 0c020585fffb..005f8a468031 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -50,7 +50,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/i2c-addr.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#ifndef VIDEO_AUDIO_BALANCE
# define VIDEO_AUDIO_BALANCE 32
@@ -69,13 +69,6 @@ MODULE_PARM_DESC(maxvol,"Set maximium volume to +20db (0), default is 0db(1)");
module_param(maxvol, int, S_IRUGO | S_IWUSR);
-/* Address to scan (I2C address of this chip) */
-static unsigned short normal_i2c[] = {
- I2C_ADDR_TDA7432 >> 1,
- I2C_CLIENT_END,
-};
-
-I2C_CLIENT_INSMOD;
/* Structure of address and subaddresses for the tda7432 */
@@ -421,21 +414,18 @@ static int tda7432_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int tda7432_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
switch (qc->id) {
- case V4L2_CID_AUDIO_MUTE:
case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- return v4l2_ctrl_query_fill_std(qc);
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
}
return -EINVAL;
}
-static int tda7432_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tda7432_core_ops = {
@@ -498,8 +488,6 @@ MODULE_DEVICE_TABLE(i2c, tda7432_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tda7432",
- .driverid = I2C_DRIVERID_TDA7432,
- .command = tda7432_command,
.probe = tda7432_probe,
.remove = tda7432_remove,
.id_table = tda7432_id,
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
index 6afb7059502d..fe1158094c24 100644
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/video/tda9840.c
@@ -30,8 +30,8 @@
#include <linux/ioctl.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
-#include "tda9840.h"
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
MODULE_DESCRIPTION("tda9840 driver");
@@ -56,11 +56,6 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
#define TDA9840_SET_BOTH_R 0x16
#define TDA9840_SET_EXTERNAL 0x7a
-/* addresses to scan, found only at 0x42 (7-Bit) */
-static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END };
-
-/* magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
static void tda9840_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
@@ -137,60 +132,17 @@ static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
return 0;
}
-static long tda9840_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
+static int tda9840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
{
- int byte;
-
- switch (cmd) {
- case TDA9840_LEVEL_ADJUST:
- byte = *(int *)arg;
- v4l2_dbg(1, debug, sd, "TDA9840_LEVEL_ADJUST: %d\n", byte);
-
- /* check for correct range */
- if (byte > 25 || byte < -20)
- return -EINVAL;
-
- /* calculate actual value to set, see specs, page 18 */
- byte /= 5;
- if (0 < byte)
- byte += 0x8;
- else
- byte = -byte;
- tda9840_write(sd, LEVEL_ADJUST, byte);
- break;
-
- case TDA9840_STEREO_ADJUST:
- byte = *(int *)arg;
- v4l2_dbg(1, debug, sd, "TDA9840_STEREO_ADJUST: %d\n", byte);
-
- /* check for correct range */
- if (byte > 25 || byte < -24)
- return -EINVAL;
-
- /* calculate actual value to set */
- byte /= 5;
- if (0 < byte)
- byte += 0x20;
- else
- byte = -byte;
-
- tda9840_write(sd, STEREO_ADJUST, byte);
- break;
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
-static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TDA9840, 0);
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tda9840_core_ops = {
- .ioctl = tda9840_ioctl,
+ .g_chip_ident = tda9840_g_chip_ident,
};
static const struct v4l2_subdev_tuner_ops tda9840_tuner_ops = {
@@ -209,8 +161,6 @@ static int tda9840_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct v4l2_subdev *sd;
- int result;
- int byte;
/* let's see whether this adapter can support what we need */
if (!i2c_check_functionality(client->adapter,
@@ -227,15 +177,9 @@ static int tda9840_probe(struct i2c_client *client,
v4l2_i2c_subdev_init(sd, client, &tda9840_ops);
/* set initial values for level & stereo - adjustment, mode */
- byte = 0;
- result = tda9840_ioctl(sd, TDA9840_LEVEL_ADJUST, &byte);
- result |= tda9840_ioctl(sd, TDA9840_STEREO_ADJUST, &byte);
+ tda9840_write(sd, LEVEL_ADJUST, 0);
+ tda9840_write(sd, STEREO_ADJUST, 0);
tda9840_write(sd, SWITCH, TDA9840_SET_STEREO);
- if (result) {
- v4l2_dbg(1, debug, sd, "could not initialize tda9840\n");
- kfree(sd);
- return -ENODEV;
- }
return 0;
}
@@ -248,12 +192,7 @@ static int tda9840_remove(struct i2c_client *client)
return 0;
}
-static int tda9840_legacy_probe(struct i2c_adapter *adapter)
-{
- /* Let's see whether this is a known adapter we can attach to.
- Prevents conflicts with tvaudio.c. */
- return adapter->id == I2C_HW_SAA7146;
-}
+
static const struct i2c_device_id tda9840_id[] = {
{ "tda9840", 0 },
{ }
@@ -262,10 +201,7 @@ MODULE_DEVICE_TABLE(i2c, tda9840_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tda9840",
- .driverid = I2C_DRIVERID_TDA9840,
- .command = tda9840_command,
.probe = tda9840_probe,
.remove = tda9840_remove,
- .legacy_probe = tda9840_legacy_probe,
.id_table = tda9840_id,
};
diff --git a/drivers/media/video/tda9840.h b/drivers/media/video/tda9840.h
deleted file mode 100644
index dc12ae7caf6f..000000000000
--- a/drivers/media/video/tda9840.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __INCLUDED_TDA9840__
-#define __INCLUDED_TDA9840__
-
-#define I2C_ADDR_TDA9840 0x42
-
-/* values may range between +2.5 and -2.0;
- the value has to be multiplied with 10 */
-#define TDA9840_LEVEL_ADJUST _IOW('v',3,int)
-
-/* values may range between +2.5 and -2.4;
- the value has to be multiplied with 10 */
-#define TDA9840_STEREO_ADJUST _IOW('v',4,int)
-
-#endif
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 00c6cbe06ab0..24e2b7d2ae58 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -28,20 +28,13 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include <media/i2c-addr.h>
static int debug; /* insmod parameter */
module_param(debug, int, S_IRUGO | S_IWUSR);
MODULE_LICENSE("GPL");
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {
- I2C_ADDR_TDA9875 >> 1,
- I2C_CLIENT_END
-};
-
-I2C_CLIENT_INSMOD;
/* This is a superset of the TDA9875 */
struct tda9875 {
@@ -313,18 +306,14 @@ static int tda9875_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
switch (qc->id) {
case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- return v4l2_ctrl_query_fill_std(qc);
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
}
return -EINVAL;
}
-static int tda9875_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tda9875_core_ops = {
@@ -401,8 +390,6 @@ MODULE_DEVICE_TABLE(i2c, tda9875_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tda9875",
- .driverid = I2C_DRIVERID_TDA9875,
- .command = tda9875_command,
.probe = tda9875_probe,
.remove = tda9875_remove,
.id_table = tda9875_id,
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index 7519fd1f57ef..d61c56f42bcd 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -32,7 +32,8 @@
#include <linux/ioctl.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
#include "tea6415c.h"
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -44,25 +45,22 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-/* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */
-static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END };
-/* magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
-
-/* makes a connection between the input-pin 'i' and the output-pin 'o'
- for the tea6415c-client 'client' */
-static int switch_matrix(struct i2c_client *client, int i, int o)
+/* makes a connection between the input-pin 'i' and the output-pin 'o' */
+static int tea6415c_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
u8 byte = 0;
+ u32 i = route->input;
+ u32 o = route->output;
int ret;
- v4l_dbg(1, debug, client, "i=%d, o=%d\n", i, o);
+ v4l2_dbg(1, debug, sd, "i=%d, o=%d\n", i, o);
/* check if the pins are valid */
if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i)
&& (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o)))
- return -1;
+ return -EINVAL;
/* to understand this, have a look at the tea6415c-specs (p.5) */
switch (o) {
@@ -115,37 +113,33 @@ static int switch_matrix(struct i2c_client *client, int i, int o)
ret = i2c_smbus_write_byte(client, byte);
if (ret) {
- v4l_dbg(1, debug, client,
+ v4l2_dbg(1, debug, sd,
"i2c_smbus_write_byte() failed, ret:%d\n", ret);
return -EIO;
}
return ret;
}
-static long tea6415c_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
+static int tea6415c_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
{
- if (cmd == TEA6415C_SWITCH) {
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- return switch_matrix(client, v->in, v->out);
- }
- return -ENOIOCTLCMD;
-}
-
-static int tea6415c_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6415C, 0);
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tea6415c_core_ops = {
- .ioctl = tea6415c_ioctl,
+ .g_chip_ident = tea6415c_g_chip_ident,
+};
+
+static const struct v4l2_subdev_video_ops tea6415c_video_ops = {
+ .s_routing = tea6415c_s_routing,
};
static const struct v4l2_subdev_ops tea6415c_ops = {
.core = &tea6415c_core_ops,
+ .video = &tea6415c_video_ops,
};
/* this function is called by i2c_probe */
@@ -176,12 +170,6 @@ static int tea6415c_remove(struct i2c_client *client)
return 0;
}
-static int tea6415c_legacy_probe(struct i2c_adapter *adapter)
-{
- /* Let's see whether this is a known adapter we can attach to.
- Prevents conflicts with tvaudio.c. */
- return adapter->id == I2C_HW_SAA7146;
-}
static const struct i2c_device_id tea6415c_id[] = {
{ "tea6415c", 0 },
@@ -191,10 +179,7 @@ MODULE_DEVICE_TABLE(i2c, tea6415c_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tea6415c",
- .driverid = I2C_DRIVERID_TEA6415C,
- .command = tea6415c_command,
.probe = tea6415c_probe,
.remove = tea6415c_remove,
- .legacy_probe = tea6415c_legacy_probe,
.id_table = tea6415c_id,
};
diff --git a/drivers/media/video/tea6415c.h b/drivers/media/video/tea6415c.h
index f84ed80050b3..3a47d697536e 100644
--- a/drivers/media/video/tea6415c.h
+++ b/drivers/media/video/tea6415c.h
@@ -1,10 +1,6 @@
#ifndef __INCLUDED_TEA6415C__
#define __INCLUDED_TEA6415C__
-/* possible i2c-addresses */
-#define I2C_TEA6415C_1 0x03
-#define I2C_TEA6415C_2 0x43
-
/* the tea6415c's design is quite brain-dead. although there are
8 inputs and 6 outputs, these aren't enumerated in any way. because
I don't want to say "connect input pin 20 to output pin 17", I define
@@ -28,12 +24,4 @@
#define TEA6415C_INPUT7 1
#define TEA6415C_INPUT8 11
-struct tea6415c_multiplex
-{
- int in; /* input-pin */
- int out; /* output-pin */
-};
-
-#define TEA6415C_SWITCH _IOW('v',1,struct tea6415c_multiplex)
-
#endif
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
index 081e74fa3b2e..34922232402a 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -32,7 +32,8 @@
#include <linux/ioctl.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
#include "tea6420.h"
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -44,24 +45,23 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-/* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */
-static unsigned short normal_i2c[] = { I2C_ADDR_TEA6420_1, I2C_ADDR_TEA6420_2, I2C_CLIENT_END };
-
-/* magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
/* make a connection between the input 'i' and the output 'o'
- with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */
-static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
+ with gain 'g' (note: i = 6 means 'mute') */
+static int tea6420_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int i = route->input;
+ int o = route->output & 0xf;
+ int g = (route->output >> 4) & 0xf;
u8 byte;
int ret;
- v4l_dbg(1, debug, client, "i=%d, o=%d, g=%d\n", i, o, g);
+ v4l2_dbg(1, debug, sd, "i=%d, o=%d, g=%d\n", i, o, g);
/* check if the parameters are valid */
if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0)
- return -1;
+ return -EINVAL;
byte = ((o - 1) << 5);
byte |= (i - 1);
@@ -83,37 +83,33 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
ret = i2c_smbus_write_byte(client, byte);
if (ret) {
- v4l_dbg(1, debug, client,
+ v4l2_dbg(1, debug, sd,
"i2c_smbus_write_byte() failed, ret:%d\n", ret);
return -EIO;
}
return 0;
}
-static long tea6420_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
+static int tea6420_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
{
- if (cmd == TEA6420_SWITCH) {
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- return tea6420_switch(client, a->in, a->out, a->gain);
- }
- return -ENOIOCTLCMD;
-}
-
-static int tea6420_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6420, 0);
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tea6420_core_ops = {
- .ioctl = tea6420_ioctl,
+ .g_chip_ident = tea6420_g_chip_ident,
+};
+
+static const struct v4l2_subdev_audio_ops tea6420_audio_ops = {
+ .s_routing = tea6420_s_routing,
};
static const struct v4l2_subdev_ops tea6420_ops = {
.core = &tea6420_core_ops,
+ .audio = &tea6420_audio_ops,
};
/* this function is called by i2c_probe */
@@ -130,20 +126,24 @@ static int tea6420_probe(struct i2c_client *client,
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
+ sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+ if (sd == NULL)
+ return -ENOMEM;
+ v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
+
/* set initial values: set "mute"-input to all outputs at gain 0 */
err = 0;
for (i = 1; i < 5; i++) {
- err += tea6420_switch(client, 6, i, 0);
+ struct v4l2_routing route;
+
+ route.input = 6;
+ route.output = i;
+ err += tea6420_s_routing(sd, &route);
}
if (err) {
v4l_dbg(1, debug, client, "could not initialize tea6420\n");
return -ENODEV;
}
-
- sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
- if (sd == NULL)
- return -ENOMEM;
- v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
return 0;
}
@@ -156,12 +156,6 @@ static int tea6420_remove(struct i2c_client *client)
return 0;
}
-static int tea6420_legacy_probe(struct i2c_adapter *adapter)
-{
- /* Let's see whether this is a known adapter we can attach to.
- Prevents conflicts with tvaudio.c. */
- return adapter->id == I2C_HW_SAA7146;
-}
static const struct i2c_device_id tea6420_id[] = {
{ "tea6420", 0 },
@@ -171,10 +165,7 @@ MODULE_DEVICE_TABLE(i2c, tea6420_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tea6420",
- .driverid = I2C_DRIVERID_TEA6420,
- .command = tea6420_command,
.probe = tea6420_probe,
.remove = tea6420_remove,
- .legacy_probe = tea6420_legacy_probe,
.id_table = tea6420_id,
};
diff --git a/drivers/media/video/tea6420.h b/drivers/media/video/tea6420.h
index 5ef7c18e0c54..4aa3edb3e193 100644
--- a/drivers/media/video/tea6420.h
+++ b/drivers/media/video/tea6420.h
@@ -1,17 +1,24 @@
#ifndef __INCLUDED_TEA6420__
#define __INCLUDED_TEA6420__
-/* possible addresses */
-#define I2C_ADDR_TEA6420_1 0x4c
-#define I2C_ADDR_TEA6420_2 0x4d
+/* input pins */
+#define TEA6420_OUTPUT1 1
+#define TEA6420_OUTPUT2 2
+#define TEA6420_OUTPUT3 3
+#define TEA6420_OUTPUT4 4
-struct tea6420_multiplex
-{
- int in; /* input of audio switch */
- int out; /* output of audio switch */
- int gain; /* gain of connection */
-};
+/* output pins */
+#define TEA6420_INPUT1 1
+#define TEA6420_INPUT2 2
+#define TEA6420_INPUT3 3
+#define TEA6420_INPUT4 4
+#define TEA6420_INPUT5 5
+#define TEA6420_INPUT6 6
-#define TEA6420_SWITCH _IOW('v',1,struct tea6420_multiplex)
+/* gain on the output pins, ORed with the output pin */
+#define TEA6420_GAIN0 0x00
+#define TEA6420_GAIN2 0x20
+#define TEA6420_GAIN4 0x40
+#define TEA6420_GAIN6 0x60
#endif
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index 5c95ecd09dc2..07789c64814c 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -31,15 +31,12 @@
#include <linux/i2c-id.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("tlv320aic23b driver");
MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil");
MODULE_LICENSE("GPL");
-static unsigned short normal_i2c[] = { 0x34 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
/* ----------------------------------------------------------------------- */
@@ -121,11 +118,6 @@ static int tlv320aic23b_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int tlv320aic23b_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = {
@@ -208,8 +200,6 @@ MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tlv320aic23b",
- .driverid = I2C_DRIVERID_TLV320AIC23B,
- .command = tlv320aic23b_command,
.probe = tlv320aic23b_probe,
.remove = tlv320aic23b_remove,
.id_table = tlv320aic23b_id,
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 30640fbfd0f9..72d41032742d 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -364,7 +364,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
}
t->type = type;
- t->config = new_config;
+ /* prevent invalid config values */
+ t->config = ((new_config >= 0) && (new_config < 256)) ? new_config : 0;
if (tuner_callback != NULL) {
tuner_dbg("defining GPIO callback\n");
t->fe.callback = tuner_callback;
@@ -452,7 +453,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
struct dvb_tuner_ops *xc_tuner_ops;
xc5000_cfg.i2c_address = t->i2c->addr;
- xc5000_cfg.if_khz = 5380;
+ /* if_khz will be set when the digital dvb_attach() occurs */
+ xc5000_cfg.if_khz = 0;
if (!dvb_attach(xc5000_attach,
&t->fe, t->i2c->adapter, &xc5000_cfg))
goto attach_failed;
@@ -776,8 +778,7 @@ static int tuner_s_radio(struct v4l2_subdev *sd)
struct tuner *t = to_tuner(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO")
- == -EINVAL)
+ if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL)
return 0;
if (t->radio_freq)
set_freq(client, t->radio_freq);
@@ -791,7 +792,7 @@ static int tuner_s_standby(struct v4l2_subdev *sd, u32 standby)
tuner_dbg("Putting tuner to sleep\n");
- if (check_mode(t, "TUNER_SET_STANDBY") == -EINVAL)
+ if (check_mode(t, "s_standby") == -EINVAL)
return 0;
t->mode = T_STANDBY;
if (analog_ops->standby)
@@ -799,132 +800,6 @@ static int tuner_s_standby(struct v4l2_subdev *sd, u32 standby)
return 0;
}
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
-static long tuner_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
- struct tuner *t = to_tuner(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
- struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
-
- switch (cmd) {
- case VIDIOCSAUDIO:
- if (check_mode(t, "VIDIOCSAUDIO") == -EINVAL)
- return 0;
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- /* Should be implemented, since bttv calls it */
- tuner_dbg("VIDIOCSAUDIO not implemented.\n");
- break;
- case VIDIOCSCHAN:
- {
- static const v4l2_std_id map[] = {
- [VIDEO_MODE_PAL] = V4L2_STD_PAL,
- [VIDEO_MODE_NTSC] = V4L2_STD_NTSC_M,
- [VIDEO_MODE_SECAM] = V4L2_STD_SECAM,
- [4 /* bttv */ ] = V4L2_STD_PAL_M,
- [5 /* bttv */ ] = V4L2_STD_PAL_N,
- [6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
- };
- struct video_channel *vc = arg;
-
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==-EINVAL)
- return 0;
-
- if (vc->norm < ARRAY_SIZE(map))
- t->std = map[vc->norm];
- tuner_fixup_std(t);
- if (t->tv_freq)
- set_tv_freq(client, t->tv_freq);
- return 0;
- }
- case VIDIOCSFREQ:
- {
- unsigned long *v = arg;
-
- if (check_mode(t, "VIDIOCSFREQ") == -EINVAL)
- return 0;
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- set_freq(client, *v);
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner *vt = arg;
-
- if (check_mode(t, "VIDIOCGTUNER") == -EINVAL)
- return 0;
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- if (V4L2_TUNER_RADIO == t->mode) {
- if (fe_tuner_ops->get_status) {
- u32 tuner_status;
-
- fe_tuner_ops->get_status(&t->fe, &tuner_status);
- if (tuner_status & TUNER_STATUS_STEREO)
- vt->flags |= VIDEO_TUNER_STEREO_ON;
- else
- vt->flags &= ~VIDEO_TUNER_STEREO_ON;
- } else {
- if (analog_ops->is_stereo) {
- if (analog_ops->is_stereo(&t->fe))
- vt->flags |=
- VIDEO_TUNER_STEREO_ON;
- else
- vt->flags &=
- ~VIDEO_TUNER_STEREO_ON;
- }
- }
- if (analog_ops->has_signal)
- vt->signal =
- analog_ops->has_signal(&t->fe);
-
- vt->flags |= VIDEO_TUNER_LOW; /* Allow freqs at 62.5 Hz */
-
- vt->rangelow = radio_range[0] * 16000;
- vt->rangehigh = radio_range[1] * 16000;
-
- } else {
- vt->rangelow = tv_range[0] * 16;
- vt->rangehigh = tv_range[1] * 16;
- }
-
- return 0;
- }
- case VIDIOCGAUDIO:
- {
- struct video_audio *va = arg;
-
- if (check_mode(t, "VIDIOCGAUDIO") == -EINVAL)
- return 0;
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- if (V4L2_TUNER_RADIO == t->mode) {
- if (fe_tuner_ops->get_status) {
- u32 tuner_status;
-
- fe_tuner_ops->get_status(&t->fe, &tuner_status);
- va->mode = (tuner_status & TUNER_STATUS_STEREO)
- ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
- } else if (analog_ops->is_stereo)
- va->mode = analog_ops->is_stereo(&t->fe)
- ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
- }
- return 0;
- }
- }
- return -ENOIOCTLCMD;
-}
-#endif
-
static int tuner_s_config(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *cfg)
{
struct tuner *t = to_tuner(sd);
@@ -950,8 +825,7 @@ static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
struct tuner *t = to_tuner(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD")
- == -EINVAL)
+ if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "s_std") == -EINVAL)
return 0;
switch_v4l2();
@@ -968,8 +842,7 @@ static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
struct tuner *t = to_tuner(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode(client, t, f->type, "VIDIOC_S_FREQUENCY")
- == -EINVAL)
+ if (set_mode(client, t, f->type, "s_frequency") == -EINVAL)
return 0;
switch_v4l2();
set_freq(client, f->frequency);
@@ -982,7 +855,7 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
struct tuner *t = to_tuner(sd);
struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
- if (check_mode(t, "VIDIOC_G_FREQUENCY") == -EINVAL)
+ if (check_mode(t, "g_frequency") == -EINVAL)
return 0;
switch_v4l2();
f->type = t->mode;
@@ -1006,7 +879,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
- if (check_mode(t, "VIDIOC_G_TUNER") == -EINVAL)
+ if (check_mode(t, "g_tuner") == -EINVAL)
return 0;
switch_v4l2();
@@ -1055,7 +928,7 @@ static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
struct tuner *t = to_tuner(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (check_mode(t, "VIDIOC_S_TUNER") == -EINVAL)
+ if (check_mode(t, "s_tuner") == -EINVAL)
return 0;
switch_v4l2();
@@ -1112,9 +985,6 @@ static int tuner_resume(struct i2c_client *c)
static const struct v4l2_subdev_core_ops tuner_core_ops = {
.log_status = tuner_log_status,
.s_standby = tuner_s_standby,
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
- .ioctl = tuner_ioctl,
-#endif
};
static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 076ed5bf48b1..226bf3565ac9 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -26,7 +26,7 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/slab.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kthread.h>
@@ -1047,6 +1047,116 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
return 0;
}
+/* ---------------------------------------------------------------------- */
+/* audio chip description - defines+functions for tda9875 */
+/* The TDA9875 is made by Philips Semiconductor
+ * http://www.semiconductors.philips.com
+ * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator
+ *
+ */
+
+/* subaddresses for TDA9875 */
+#define TDA9875_MUT 0x12 /*General mute (value --> 0b11001100*/
+#define TDA9875_CFG 0x01 /* Config register (value --> 0b00000000 */
+#define TDA9875_DACOS 0x13 /*DAC i/o select (ADC) 0b0000100*/
+#define TDA9875_LOSR 0x16 /*Line output select regirter 0b0100 0001*/
+
+#define TDA9875_CH1V 0x0c /*Channel 1 volume (mute)*/
+#define TDA9875_CH2V 0x0d /*Channel 2 volume (mute)*/
+#define TDA9875_SC1 0x14 /*SCART 1 in (mono)*/
+#define TDA9875_SC2 0x15 /*SCART 2 in (mono)*/
+
+#define TDA9875_ADCIS 0x17 /*ADC input select (mono) 0b0110 000*/
+#define TDA9875_AER 0x19 /*Audio effect (AVL+Pseudo) 0b0000 0110*/
+#define TDA9875_MCS 0x18 /*Main channel select (DAC) 0b0000100*/
+#define TDA9875_MVL 0x1a /* Main volume gauche */
+#define TDA9875_MVR 0x1b /* Main volume droite */
+#define TDA9875_MBA 0x1d /* Main Basse */
+#define TDA9875_MTR 0x1e /* Main treble */
+#define TDA9875_ACS 0x1f /* Auxilary channel select (FM) 0b0000000*/
+#define TDA9875_AVL 0x20 /* Auxilary volume gauche */
+#define TDA9875_AVR 0x21 /* Auxilary volume droite */
+#define TDA9875_ABA 0x22 /* Auxilary Basse */
+#define TDA9875_ATR 0x23 /* Auxilary treble */
+
+#define TDA9875_MSR 0x02 /* Monitor select register */
+#define TDA9875_C1MSB 0x03 /* Carrier 1 (FM) frequency register MSB */
+#define TDA9875_C1MIB 0x04 /* Carrier 1 (FM) frequency register (16-8]b */
+#define TDA9875_C1LSB 0x05 /* Carrier 1 (FM) frequency register LSB */
+#define TDA9875_C2MSB 0x06 /* Carrier 2 (nicam) frequency register MSB */
+#define TDA9875_C2MIB 0x07 /* Carrier 2 (nicam) frequency register (16-8]b */
+#define TDA9875_C2LSB 0x08 /* Carrier 2 (nicam) frequency register LSB */
+#define TDA9875_DCR 0x09 /* Demodulateur configuration regirter*/
+#define TDA9875_DEEM 0x0a /* FM de-emphasis regirter*/
+#define TDA9875_FMAT 0x0b /* FM Matrix regirter*/
+
+/* values */
+#define TDA9875_MUTE_ON 0xff /* general mute */
+#define TDA9875_MUTE_OFF 0xcc /* general no mute */
+
+static int tda9875_initialize(struct CHIPSTATE *chip)
+{
+ chip_write(chip, TDA9875_CFG, 0xd0); /*reg de config 0 (reset)*/
+ chip_write(chip, TDA9875_MSR, 0x03); /* Monitor 0b00000XXX*/
+ chip_write(chip, TDA9875_C1MSB, 0x00); /*Car1(FM) MSB XMHz*/
+ chip_write(chip, TDA9875_C1MIB, 0x00); /*Car1(FM) MIB XMHz*/
+ chip_write(chip, TDA9875_C1LSB, 0x00); /*Car1(FM) LSB XMHz*/
+ chip_write(chip, TDA9875_C2MSB, 0x00); /*Car2(NICAM) MSB XMHz*/
+ chip_write(chip, TDA9875_C2MIB, 0x00); /*Car2(NICAM) MIB XMHz*/
+ chip_write(chip, TDA9875_C2LSB, 0x00); /*Car2(NICAM) LSB XMHz*/
+ chip_write(chip, TDA9875_DCR, 0x00); /*Demod config 0x00*/
+ chip_write(chip, TDA9875_DEEM, 0x44); /*DE-Emph 0b0100 0100*/
+ chip_write(chip, TDA9875_FMAT, 0x00); /*FM Matrix reg 0x00*/
+ chip_write(chip, TDA9875_SC1, 0x00); /* SCART 1 (SC1)*/
+ chip_write(chip, TDA9875_SC2, 0x01); /* SCART 2 (sc2)*/
+
+ chip_write(chip, TDA9875_CH1V, 0x10); /* Channel volume 1 mute*/
+ chip_write(chip, TDA9875_CH2V, 0x10); /* Channel volume 2 mute */
+ chip_write(chip, TDA9875_DACOS, 0x02); /* sig DAC i/o(in:nicam)*/
+ chip_write(chip, TDA9875_ADCIS, 0x6f); /* sig ADC input(in:mono)*/
+ chip_write(chip, TDA9875_LOSR, 0x00); /* line out (in:mono)*/
+ chip_write(chip, TDA9875_AER, 0x00); /*06 Effect (AVL+PSEUDO) */
+ chip_write(chip, TDA9875_MCS, 0x44); /* Main ch select (DAC) */
+ chip_write(chip, TDA9875_MVL, 0x03); /* Vol Main left 10dB */
+ chip_write(chip, TDA9875_MVR, 0x03); /* Vol Main right 10dB*/
+ chip_write(chip, TDA9875_MBA, 0x00); /* Main Bass Main 0dB*/
+ chip_write(chip, TDA9875_MTR, 0x00); /* Main Treble Main 0dB*/
+ chip_write(chip, TDA9875_ACS, 0x44); /* Aux chan select (dac)*/
+ chip_write(chip, TDA9875_AVL, 0x00); /* Vol Aux left 0dB*/
+ chip_write(chip, TDA9875_AVR, 0x00); /* Vol Aux right 0dB*/
+ chip_write(chip, TDA9875_ABA, 0x00); /* Aux Bass Main 0dB*/
+ chip_write(chip, TDA9875_ATR, 0x00); /* Aux Aigus Main 0dB*/
+
+ chip_write(chip, TDA9875_MUT, 0xcc); /* General mute */
+ return 0;
+}
+
+static int tda9875_volume(int val) { return (unsigned char)(val / 602 - 84); }
+static int tda9875_bass(int val) { return (unsigned char)(max(-12, val / 2115 - 15)); }
+static int tda9875_treble(int val) { return (unsigned char)(val / 2622 - 12); }
+
+/* ----------------------------------------------------------------------- */
+
+
+/* *********************** *
+ * i2c interface functions *
+ * *********************** */
+
+static int tda9875_checkit(struct CHIPSTATE *chip)
+{
+ struct v4l2_subdev *sd = &chip->sd;
+ int dic, rev;
+
+ dic = chip_read2(chip, 254);
+ rev = chip_read2(chip, 255);
+
+ if (dic == 0 || dic == 2) { /* tda9875 and tda9875A */
+ v4l2_info(sd, "found tda9875%s rev. %d.\n",
+ dic == 0 ? "" : "A", rev);
+ return 1;
+ }
+ return 0;
+}
/* ---------------------------------------------------------------------- */
/* audio chip descriptions - defines+functions for tea6420 */
@@ -1280,6 +1390,7 @@ static int tda9850 = 1;
static int tda9855 = 1;
static int tda9873 = 1;
static int tda9874a = 1;
+static int tda9875 = 1;
static int tea6300; /* default 0 - address clash with msp34xx */
static int tea6320; /* default 0 - address clash with msp34xx */
static int tea6420 = 1;
@@ -1292,6 +1403,7 @@ module_param(tda9850, int, 0444);
module_param(tda9855, int, 0444);
module_param(tda9873, int, 0444);
module_param(tda9874a, int, 0444);
+module_param(tda9875, int, 0444);
module_param(tea6300, int, 0444);
module_param(tea6320, int, 0444);
module_param(tea6420, int, 0444);
@@ -1349,6 +1461,26 @@ static struct CHIPDESC chiplist[] = {
.setmode = tda9874a_setmode,
},
{
+ .name = "tda9875",
+ .insmodopt = &tda9875,
+ .addr_lo = I2C_ADDR_TDA9875 >> 1,
+ .addr_hi = I2C_ADDR_TDA9875 >> 1,
+ .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE,
+
+ /* callbacks */
+ .initialize = tda9875_initialize,
+ .checkit = tda9875_checkit,
+ .volfunc = tda9875_volume,
+ .bassfunc = tda9875_bass,
+ .treblefunc = tda9875_treble,
+ .leftreg = TDA9875_MVL,
+ .rightreg = TDA9875_MVR,
+ .bassreg = TDA9875_MBA,
+ .treblereg = TDA9875_MTR,
+ .leftinit = 58880,
+ .rightinit = 58880,
+ },
+ {
.name = "tda9850",
.insmodopt = &tda9850,
.addr_lo = I2C_ADDR_TDA985x_L >> 1,
@@ -1511,6 +1643,8 @@ static int tvaudio_g_ctrl(struct v4l2_subdev *sd,
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
+ if (!(desc->flags & CHIP_HAS_INPUTSEL))
+ break;
ctrl->value=chip->muted;
return 0;
case V4L2_CID_AUDIO_VOLUME:
@@ -1552,6 +1686,9 @@ static int tvaudio_s_ctrl(struct v4l2_subdev *sd,
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
+ if (!(desc->flags & CHIP_HAS_INPUTSEL))
+ break;
+
if (ctrl->value < 0 || ctrl->value >= 2)
return -ERANGE;
chip->muted = ctrl->value;
@@ -1636,21 +1773,26 @@ static int tvaudio_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
switch (qc->id) {
case V4L2_CID_AUDIO_MUTE:
+ if (desc->flags & CHIP_HAS_INPUTSEL)
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
break;
case V4L2_CID_AUDIO_VOLUME:
+ if (desc->flags & CHIP_HAS_VOLUME)
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
+ break;
case V4L2_CID_AUDIO_BALANCE:
- if (!(desc->flags & CHIP_HAS_VOLUME))
- return -EINVAL;
+ if (desc->flags & CHIP_HAS_VOLUME)
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
break;
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- if (!(desc->flags & CHIP_HAS_BASSTREBLE))
- return -EINVAL;
+ if (desc->flags & CHIP_HAS_BASSTREBLE)
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
break;
default:
- return -EINVAL;
+ break;
}
- return v4l2_ctrl_query_fill_std(qc);
+ return -EINVAL;
}
static int tvaudio_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *rt)
@@ -1658,7 +1800,9 @@ static int tvaudio_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *
struct CHIPSTATE *chip = to_state(sd);
struct CHIPDESC *desc = chip->desc;
- if (!(desc->flags & CHIP_HAS_INPUTSEL) || rt->input >= 4)
+ if (!(desc->flags & CHIP_HAS_INPUTSEL))
+ return 0;
+ if (rt->input >= 4)
return -EINVAL;
/* There are four inputs: tuner, radio, extern and intern. */
chip->input = rt->input;
@@ -1675,8 +1819,11 @@ static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
struct CHIPDESC *desc = chip->desc;
int mode = 0;
+ if (!desc->setmode)
+ return 0;
if (chip->radio)
return 0;
+
switch (vt->audmode) {
case V4L2_TUNER_MODE_MONO:
case V4L2_TUNER_MODE_STEREO:
@@ -1692,7 +1839,7 @@ static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
}
chip->audmode = vt->audmode;
- if (desc->setmode && mode) {
+ if (mode) {
chip->watch_stereo = 0;
/* del_timer(&chip->wt); */
chip->mode = mode;
@@ -1707,15 +1854,17 @@ static int tvaudio_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
struct CHIPDESC *desc = chip->desc;
int mode = V4L2_TUNER_MODE_MONO;
+ if (!desc->getmode)
+ return 0;
if (chip->radio)
return 0;
+
vt->audmode = chip->audmode;
vt->rxsubchans = 0;
vt->capability = V4L2_TUNER_CAP_STEREO |
V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
- if (desc->getmode)
- mode = desc->getmode(chip);
+ mode = desc->getmode(chip);
if (mode & V4L2_TUNER_MODE_MONO)
vt->rxsubchans |= V4L2_TUNER_SUB_MONO;
@@ -1901,6 +2050,7 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
}
chip->thread = NULL;
+ init_timer(&chip->wt);
if (desc->flags & CHIP_NEED_CHECKMODE) {
if (!desc->getmode || !desc->setmode) {
/* This shouldn't be happen. Warn user, but keep working
@@ -1910,7 +2060,6 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
return 0;
}
/* start async thread */
- init_timer(&chip->wt);
chip->wt.function = chip_thread_wake;
chip->wt.data = (unsigned long)chip;
chip->thread = kthread_run(chip_thread, chip, client->name);
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 78277abb733b..e24a38c7fa46 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -261,7 +261,12 @@ hauppauge_tuner[] =
{ TUNER_ABSENT, "MaxLinear MXL5005_v2"},
{ TUNER_PHILIPS_TDA8290, "Philips 18271_8295"},
/* 150-159 */
- { TUNER_ABSENT, "Xceive XC5000"},
+ { TUNER_XC5000, "Xceive XC5000"},
+ { TUNER_ABSENT, "Xceive XC3028L"},
+ { TUNER_ABSENT, "NXP 18271C2_716x"},
+ { TUNER_ABSENT, "Xceive XC4000"},
+ { TUNER_ABSENT, "Dibcom 7070"},
+ { TUNER_PHILIPS_TDA8290, "NXP 18271C2"},
};
/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 8e23aa53c29a..4262e60b8116 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -86,9 +86,12 @@ struct tvp514x_std_info {
struct v4l2_standard standard;
};
+static struct tvp514x_reg tvp514x_reg_list_default[0x40];
/**
- * struct tvp514x_decoded - TVP5146/47 decoder object
+ * struct tvp514x_decoder - TVP5146/47 decoder object
* @v4l2_int_device: Slave handle
+ * @tvp514x_slave: Slave pointer which is used by @v4l2_int_device
+ * @tvp514x_regs: copy of hw's regs with preset values.
* @pdata: Board specific
* @client: I2C client data
* @id: Entry from I2C table
@@ -103,7 +106,9 @@ struct tvp514x_std_info {
* @route: input and output routing at chip level
*/
struct tvp514x_decoder {
- struct v4l2_int_device *v4l2_int_device;
+ struct v4l2_int_device v4l2_int_device;
+ struct v4l2_int_slave tvp514x_slave;
+ struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)];
const struct tvp514x_platform_data *pdata;
struct i2c_client *client;
@@ -124,7 +129,7 @@ struct tvp514x_decoder {
};
/* TVP514x default register values */
-static struct tvp514x_reg tvp514x_reg_list[] = {
+static struct tvp514x_reg tvp514x_reg_list_default[] = {
{TOK_WRITE, REG_INPUT_SEL, 0x05}, /* Composite selected */
{TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F},
{TOK_WRITE, REG_VIDEO_STD, 0x00}, /* Auto mode */
@@ -422,7 +427,7 @@ static int tvp514x_configure(struct tvp514x_decoder *decoder)
/* common register initialization */
err =
- tvp514x_write_regs(decoder->client, tvp514x_reg_list);
+ tvp514x_write_regs(decoder->client, decoder->tvp514x_regs);
if (err)
return err;
@@ -580,7 +585,8 @@ static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id)
return err;
decoder->current_std = i;
- tvp514x_reg_list[REG_VIDEO_STD].val = decoder->std_list[i].video_std;
+ decoder->tvp514x_regs[REG_VIDEO_STD].val =
+ decoder->std_list[i].video_std;
v4l_dbg(1, debug, decoder->client, "Standard set to: %s",
decoder->std_list[i].standard.name);
@@ -625,8 +631,8 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
if (err)
return err;
- tvp514x_reg_list[REG_INPUT_SEL].val = input_sel;
- tvp514x_reg_list[REG_OUTPUT_FORMATTER1].val = output_sel;
+ decoder->tvp514x_regs[REG_INPUT_SEL].val = input_sel;
+ decoder->tvp514x_regs[REG_OUTPUT_FORMATTER1].val = output_sel;
/* Clear status */
msleep(LOCK_RETRY_DELAY);
@@ -686,7 +692,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
break; /* Input detected */
}
- if ((current_std == STD_INVALID) || (try_count < 0))
+ if ((current_std == STD_INVALID) || (try_count <= 0))
return -EINVAL;
decoder->current_std = current_std;
@@ -719,10 +725,9 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
switch (qctrl->id) {
case V4L2_CID_BRIGHTNESS:
- /* Brightness supported is same as standard one (0-255),
- * so make use of standard API provided.
+ /* Brightness supported is (0-255),
*/
- err = v4l2_ctrl_query_fill_std(qctrl);
+ err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
break;
case V4L2_CID_CONTRAST:
case V4L2_CID_SATURATION:
@@ -779,16 +784,16 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
- ctrl->value = tvp514x_reg_list[REG_BRIGHTNESS].val;
+ ctrl->value = decoder->tvp514x_regs[REG_BRIGHTNESS].val;
break;
case V4L2_CID_CONTRAST:
- ctrl->value = tvp514x_reg_list[REG_CONTRAST].val;
+ ctrl->value = decoder->tvp514x_regs[REG_CONTRAST].val;
break;
case V4L2_CID_SATURATION:
- ctrl->value = tvp514x_reg_list[REG_SATURATION].val;
+ ctrl->value = decoder->tvp514x_regs[REG_SATURATION].val;
break;
case V4L2_CID_HUE:
- ctrl->value = tvp514x_reg_list[REG_HUE].val;
+ ctrl->value = decoder->tvp514x_regs[REG_HUE].val;
if (ctrl->value == 0x7F)
ctrl->value = 180;
else if (ctrl->value == 0x80)
@@ -798,7 +803,7 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
break;
case V4L2_CID_AUTOGAIN:
- ctrl->value = tvp514x_reg_list[REG_AFE_GAIN_CTRL].val;
+ ctrl->value = decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val;
if ((ctrl->value & 0x3) == 3)
ctrl->value = 1;
else
@@ -848,7 +853,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
value);
if (err)
return err;
- tvp514x_reg_list[REG_BRIGHTNESS].val = value;
+ decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
break;
case V4L2_CID_CONTRAST:
if (ctrl->value < 0 || ctrl->value > 255) {
@@ -861,7 +866,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
value);
if (err)
return err;
- tvp514x_reg_list[REG_CONTRAST].val = value;
+ decoder->tvp514x_regs[REG_CONTRAST].val = value;
break;
case V4L2_CID_SATURATION:
if (ctrl->value < 0 || ctrl->value > 255) {
@@ -874,7 +879,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
value);
if (err)
return err;
- tvp514x_reg_list[REG_SATURATION].val = value;
+ decoder->tvp514x_regs[REG_SATURATION].val = value;
break;
case V4L2_CID_HUE:
if (value == 180)
@@ -893,7 +898,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
value);
if (err)
return err;
- tvp514x_reg_list[REG_HUE].val = value;
+ decoder->tvp514x_regs[REG_HUE].val = value;
break;
case V4L2_CID_AUTOGAIN:
if (value == 1)
@@ -910,7 +915,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
value);
if (err)
return err;
- tvp514x_reg_list[REG_AFE_GAIN_CTRL].val = value;
+ decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
break;
default:
v4l_err(decoder->client,
@@ -1275,7 +1280,7 @@ static int ioctl_init(struct v4l2_int_device *s)
struct tvp514x_decoder *decoder = s->priv;
/* Set default standard to auto */
- tvp514x_reg_list[REG_VIDEO_STD].val =
+ decoder->tvp514x_regs[REG_VIDEO_STD].val =
VIDEO_STD_AUTO_SWITCH_BIT;
return tvp514x_configure(decoder);
@@ -1344,11 +1349,6 @@ static struct v4l2_int_ioctl_desc tvp514x_ioctl_desc[] = {
(v4l2_int_ioctl_func *) ioctl_s_routing},
};
-static struct v4l2_int_slave tvp514x_slave = {
- .ioctls = tvp514x_ioctl_desc,
- .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc),
-};
-
static struct tvp514x_decoder tvp514x_dev = {
.state = STATE_NOT_DETECTED,
@@ -1369,17 +1369,15 @@ static struct tvp514x_decoder tvp514x_dev = {
.current_std = STD_NTSC_MJ,
.std_list = tvp514x_std_list,
.num_stds = ARRAY_SIZE(tvp514x_std_list),
-
-};
-
-static struct v4l2_int_device tvp514x_int_device = {
- .module = THIS_MODULE,
- .name = TVP514X_MODULE_NAME,
- .priv = &tvp514x_dev,
- .type = v4l2_int_type_slave,
- .u = {
- .slave = &tvp514x_slave,
- },
+ .v4l2_int_device = {
+ .module = THIS_MODULE,
+ .name = TVP514X_MODULE_NAME,
+ .type = v4l2_int_type_slave,
+ },
+ .tvp514x_slave = {
+ .ioctls = tvp514x_ioctl_desc,
+ .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc),
+ },
};
/**
@@ -1392,26 +1390,37 @@ static struct v4l2_int_device tvp514x_int_device = {
static int
tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
- struct tvp514x_decoder *decoder = &tvp514x_dev;
+ struct tvp514x_decoder *decoder;
int err;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EIO;
- decoder->pdata = client->dev.platform_data;
- if (!decoder->pdata) {
+ decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
+ if (!decoder)
+ return -ENOMEM;
+
+ if (!client->dev.platform_data) {
v4l_err(client, "No platform data!!\n");
- return -ENODEV;
+ err = -ENODEV;
+ goto out_free;
}
+
+ *decoder = tvp514x_dev;
+ decoder->v4l2_int_device.priv = decoder;
+ decoder->pdata = client->dev.platform_data;
+ decoder->v4l2_int_device.u.slave = &decoder->tvp514x_slave;
+ memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default,
+ sizeof(tvp514x_reg_list_default));
/*
* Fetch platform specific data, and configure the
* tvp514x_reg_list[] accordingly. Since this is one
* time configuration, no need to preserve.
*/
- tvp514x_reg_list[REG_OUTPUT_FORMATTER2].val |=
+ decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |=
(decoder->pdata->clk_polarity << 1);
- tvp514x_reg_list[REG_SYNC_CONTROL].val |=
+ decoder->tvp514x_regs[REG_SYNC_CONTROL].val |=
((decoder->pdata->hs_polarity << 2) |
(decoder->pdata->vs_polarity << 3));
/*
@@ -1419,23 +1428,27 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
*/
decoder->id = (struct i2c_device_id *)id;
/* Attach to Master */
- strcpy(tvp514x_int_device.u.slave->attach_to, decoder->pdata->master);
- decoder->v4l2_int_device = &tvp514x_int_device;
+ strcpy(decoder->v4l2_int_device.u.slave->attach_to,
+ decoder->pdata->master);
decoder->client = client;
i2c_set_clientdata(client, decoder);
/* Register with V4L2 layer as slave device */
- err = v4l2_int_device_register(decoder->v4l2_int_device);
+ err = v4l2_int_device_register(&decoder->v4l2_int_device);
if (err) {
i2c_set_clientdata(client, NULL);
v4l_err(client,
"Unable to register to v4l2. Err[%d]\n", err);
+ goto out_free;
} else
v4l_info(client, "Registered to v4l2 master %s!!\n",
decoder->pdata->master);
-
return 0;
+
+out_free:
+ kfree(decoder);
+ return err;
}
/**
@@ -1452,9 +1465,9 @@ static int __exit tvp514x_remove(struct i2c_client *client)
if (!client->adapter)
return -ENODEV; /* our client isn't attached */
- v4l2_int_device_unregister(decoder->v4l2_int_device);
+ v4l2_int_device_unregister(&decoder->v4l2_int_device);
i2c_set_clientdata(client, NULL);
-
+ kfree(decoder);
return 0;
}
/*
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 2cd64ef27b95..3a5a95f134b4 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -8,7 +8,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <linux/delay.h>
-#include <linux/video_decoder.h>
#include <media/v4l2-device.h>
#include <media/tvp5150.h>
#include <media/v4l2-i2c-drv-legacy.h>
@@ -632,7 +631,7 @@ static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
const struct i2c_vbi_ram_value *regs = vbi_ram_default;
int line;
- v4l2_dbg(1, debug, sd, "VIDIOC_G_SLICED_VBI_CAP\n");
+ v4l2_dbg(1, debug, sd, "g_sliced_vbi_cap\n");
memset(cap, 0, sizeof *cap);
while (regs->reg != (u16)-1 ) {
@@ -831,7 +830,7 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
static int tvp5150_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- v4l2_dbg(1, debug, sd, "VIDIOC_G_CTRL called\n");
+ v4l2_dbg(1, debug, sd, "g_ctrl called\n");
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
@@ -861,7 +860,7 @@ static int tvp5150_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
if (ctrl->value < tvp5150_qctrl[i].minimum ||
ctrl->value > tvp5150_qctrl[i].maximum)
return -ERANGE;
- v4l2_dbg(1, debug, sd, "VIDIOC_S_CTRL: id=%d, value=%d\n",
+ v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
ctrl->id, ctrl->value);
break;
}
@@ -1015,7 +1014,7 @@ static int tvp5150_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
int i;
- v4l2_dbg(1, debug, sd, "VIDIOC_QUERYCTRL called\n");
+ v4l2_dbg(1, debug, sd, "queryctrl called\n");
for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++)
if (qc->id && qc->id == tvp5150_qctrl[i].id) {
@@ -1126,7 +1125,6 @@ MODULE_DEVICE_TABLE(i2c, tvp5150_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tvp5150",
- .driverid = I2C_DRIVERID_TVP5150,
.command = tvp5150_command,
.probe = tvp5150_probe,
.remove = tvp5150_remove,
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index 52c0357faa5d..a39947643992 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -460,9 +460,11 @@ static int tw9910_mask_set(struct i2c_client *client, u8 command,
u8 mask, u8 set)
{
s32 val = i2c_smbus_read_byte_data(client, command);
+ if (val < 0)
+ return val;
val &= ~mask;
- val |= set;
+ val |= set & mask;
return i2c_smbus_write_byte_data(client, command, val);
}
@@ -639,8 +641,8 @@ static int tw9910_set_register(struct soc_camera_device *icd,
}
#endif
-static int tw9910_set_fmt(struct soc_camera_device *icd, __u32 pixfmt,
- struct v4l2_rect *rect)
+static int tw9910_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
{
struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
int ret = -EINVAL;
@@ -731,8 +733,33 @@ tw9910_set_fmt_error:
return ret;
}
+static int tw9910_set_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct v4l2_rect rect = {
+ .left = icd->x_current,
+ .top = icd->y_current,
+ .width = pix->width,
+ .height = pix->height,
+ };
+ int i;
+
+ /*
+ * check color format
+ */
+ for (i = 0; i < ARRAY_SIZE(tw9910_color_fmt); i++)
+ if (pix->pixelformat == tw9910_color_fmt[i].fourcc)
+ break;
+
+ if (i == ARRAY_SIZE(tw9910_color_fmt))
+ return -EINVAL;
+
+ return tw9910_set_crop(icd, &rect);
+}
+
static int tw9910_try_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
+ struct v4l2_format *f)
{
struct v4l2_pix_format *pix = &f->fmt.pix;
const struct tw9910_scale_ctrl *scale;
@@ -820,6 +847,7 @@ static struct soc_camera_ops tw9910_ops = {
.release = tw9910_release,
.start_capture = tw9910_start_capture,
.stop_capture = tw9910_stop_capture,
+ .set_crop = tw9910_set_crop,
.set_fmt = tw9910_set_fmt,
.try_fmt = tw9910_try_fmt,
.set_bus_param = tw9910_set_bus_param,
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index f4522bb08916..c0ac651bb358 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -187,11 +187,6 @@ static int upd64031a_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register
}
#endif
-static int upd64031a_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops upd64031a_core_ops = {
@@ -267,8 +262,6 @@ MODULE_DEVICE_TABLE(i2c, upd64031a_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "upd64031a",
- .driverid = I2C_DRIVERID_UPD64031A,
- .command = upd64031a_command,
.probe = upd64031a_probe,
.remove = upd64031a_remove,
.id_table = upd64031a_id,
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index a5fb74bf2407..410c915d51fa 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -164,11 +164,6 @@ static int upd64083_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int upd64083_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops upd64083_core_ops = {
@@ -239,8 +234,6 @@ MODULE_DEVICE_TABLE(i2c, upd64083_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "upd64083",
- .driverid = I2C_DRIVERID_UPD64083,
- .command = upd64083_command,
.probe = upd64083_probe,
.remove = upd64083_remove,
.id_table = upd64083_id,
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index 2f1106338c08..8d73979596f9 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -191,7 +191,7 @@ initialize_camera(struct vicam_camera *cam)
{
int err;
const struct ihex_binrec *rec;
- const struct firmware *fw;
+ const struct firmware *uninitialized_var(fw);
err = request_ihex_firmware(&fw, "vicam/firmware.fw", &cam->udev->dev);
if (err) {
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index 9e4f50639975..a0feb1c97736 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -36,7 +36,6 @@
#include <linux/spinlock.h>
#include <asm/io.h>
#include <linux/videodev2.h>
-#include <linux/video_decoder.h>
#include <linux/i2c.h>
#include <media/saa7115.h>
@@ -381,8 +380,9 @@ int usbvision_scratch_alloc(struct usb_usbvision *usbvision)
usbvision->scratch = vmalloc_32(scratch_buf_size);
scratch_reset(usbvision);
if(usbvision->scratch == NULL) {
- err("%s: unable to allocate %d bytes for scratch",
- __func__, scratch_buf_size);
+ dev_err(&usbvision->dev->dev,
+ "%s: unable to allocate %d bytes for scratch\n",
+ __func__, scratch_buf_size);
return -ENOMEM;
}
return 0;
@@ -491,8 +491,9 @@ int usbvision_decompress_alloc(struct usb_usbvision *usbvision)
int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2;
usbvision->IntraFrameBuffer = vmalloc_32(IFB_size);
if (usbvision->IntraFrameBuffer == NULL) {
- err("%s: unable to allocate %d for compr. frame buffer",
- __func__, IFB_size);
+ dev_err(&usbvision->dev->dev,
+ "%s: unable to allocate %d for compr. frame buffer\n",
+ __func__, IFB_size);
return -ENOMEM;
}
return 0;
@@ -1514,8 +1515,9 @@ static void usbvision_isocIrq(struct urb *urb)
errCode = usb_submit_urb (urb, GFP_ATOMIC);
if(errCode) {
- err("%s: usb_submit_urb failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_submit_urb failed: error %d\n",
+ __func__, errCode);
}
return;
@@ -1546,7 +1548,8 @@ int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg)
0, (__u16) reg, buffer, 1, HZ);
if (errCode < 0) {
- err("%s: failed: error %d", __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: failed: error %d\n", __func__, errCode);
return errCode;
}
return buffer[0];
@@ -1574,7 +1577,8 @@ int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg,
USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ);
if (errCode < 0) {
- err("%s: failed: error %d", __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: failed: error %d\n", __func__, errCode);
}
return errCode;
}
@@ -1850,7 +1854,8 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width,
0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ);
if (errCode < 0) {
- err("%s failed: error %d", __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s failed: error %d\n", __func__, errCode);
return errCode;
}
usbvision->curwidth = usbvision->stretch_width * UsbWidth;
@@ -2236,7 +2241,7 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
(__u16) USBVISION_DRM_PRM1, value, 8, HZ);
if (rc < 0) {
- err("%sERROR=%d", __func__, rc);
+ dev_err(&usbvision->dev->dev, "%sERROR=%d\n", __func__, rc);
return rc;
}
@@ -2432,8 +2437,9 @@ int usbvision_set_alternate(struct usb_usbvision *dev)
PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize);
errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt);
if (errCode < 0) {
- err ("cannot change alternate number to %d (error=%i)",
- dev->ifaceAlt, errCode);
+ dev_err(&dev->dev->dev,
+ "cannot change alternate number to %d (error=%i)\n",
+ dev->ifaceAlt, errCode);
return errCode;
}
}
@@ -2484,7 +2490,8 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
if (urb == NULL) {
- err("%s: usb_alloc_urb() failed", __func__);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_alloc_urb() failed\n", __func__);
return -ENOMEM;
}
usbvision->sbuf[bufIdx].urb = urb;
@@ -2496,7 +2503,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
urb->dev = dev;
urb->context = usbvision;
urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
- urb->transfer_flags = URB_ISO_ASAP;
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
urb->interval = 1;
urb->transfer_buffer = usbvision->sbuf[bufIdx].data;
urb->complete = usbvision_isocIrq;
@@ -2516,8 +2523,9 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb,
GFP_KERNEL);
if (errCode) {
- err("%s: usb_submit_urb(%d) failed: error %d",
- __func__, bufIdx, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_submit_urb(%d) failed: error %d\n",
+ __func__, bufIdx, errCode);
}
}
@@ -2566,8 +2574,9 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
errCode = usb_set_interface(usbvision->dev, usbvision->iface,
usbvision->ifaceAlt);
if (errCode < 0) {
- err("%s: usb_set_interface() failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_set_interface() failed: error %d\n",
+ __func__, errCode);
usbvision->last_error = errCode;
}
regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
@@ -2623,7 +2632,7 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel)
}
route.input = mode[channel];
route.output = 0;
- call_i2c_clients(usbvision, VIDIOC_INT_S_VIDEO_ROUTING,&route);
+ call_all(usbvision, video, s_routing, &route);
usbvision_set_audio(usbvision, audio[channel]);
return 0;
}
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 6b66ae4f430f..dd2f8f27c73b 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -119,7 +119,8 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap,
/* try extended address code... */
ret = try_write_address(i2c_adap, addr, retries);
if (ret != 1) {
- err("died at extended address code, while writing");
+ dev_err(&i2c_adap->dev,
+ "died at extended address code, while writing\n");
return -EREMOTEIO;
}
add[0] = addr;
@@ -128,7 +129,8 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap,
addr |= 0x01;
ret = try_read_address(i2c_adap, addr, retries);
if (ret != 1) {
- err("died at extended address code, while reading");
+ dev_err(&i2c_adap->dev,
+ "died at extended address code, while reading\n");
return -EREMOTEIO;
}
}
@@ -200,72 +202,78 @@ static struct i2c_algorithm usbvision_algo = {
};
-/*
- * registering functions to load algorithms at runtime
- */
-static int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap)
-{
- PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]");
- PDEBUG(DBG_I2C, "ALGO debugging is enabled [i2c]");
-
- /* register new adapter to i2c module... */
-
- adap->algo = &usbvision_algo;
-
- adap->timeout = 100; /* default values, should */
- adap->retries = 3; /* be replaced by defines */
-
- i2c_add_adapter(adap);
-
- PDEBUG(DBG_I2C,"i2c bus for %s registered", adap->name);
-
- return 0;
-}
-
/* ----------------------------------------------------------------------- */
/* usbvision specific I2C functions */
/* ----------------------------------------------------------------------- */
static struct i2c_adapter i2c_adap_template;
-static struct i2c_client i2c_client_template;
int usbvision_i2c_register(struct usb_usbvision *usbvision)
{
+ static unsigned short saa711x_addrs[] = {
+ 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
+ 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
+ I2C_CLIENT_END };
+
memcpy(&usbvision->i2c_adap, &i2c_adap_template,
sizeof(struct i2c_adapter));
- memcpy(&usbvision->i2c_client, &i2c_client_template,
- sizeof(struct i2c_client));
sprintf(usbvision->i2c_adap.name + strlen(usbvision->i2c_adap.name),
" #%d", usbvision->vdev->num);
PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name);
usbvision->i2c_adap.dev.parent = &usbvision->dev->dev;
- i2c_set_adapdata(&usbvision->i2c_adap, usbvision);
- i2c_set_clientdata(&usbvision->i2c_client, usbvision);
-
- usbvision->i2c_client.adapter = &usbvision->i2c_adap;
+ i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev);
if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
printk(KERN_ERR "usbvision_register: can't write reg\n");
return -EBUSY;
}
-#ifdef CONFIG_MODULES
+ PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]");
+ PDEBUG(DBG_I2C, "ALGO debugging is enabled [i2c]");
+
+ /* register new adapter to i2c module... */
+
+ usbvision->i2c_adap.algo = &usbvision_algo;
+
+ usbvision->i2c_adap.timeout = 100; /* default values, should */
+ usbvision->i2c_adap.retries = 3; /* be replaced by defines */
+
+ i2c_add_adapter(&usbvision->i2c_adap);
+
+ PDEBUG(DBG_I2C, "i2c bus for %s registered", usbvision->i2c_adap.name);
+
/* Request the load of the i2c modules we need */
switch (usbvision_device_data[usbvision->DevModel].Codec) {
case CODEC_SAA7113:
- request_module("saa7115");
- break;
case CODEC_SAA7111:
- request_module("saa7115");
+ v4l2_i2c_new_probed_subdev(&usbvision->i2c_adap, "saa7115",
+ "saa7115_auto", saa711x_addrs);
break;
}
if (usbvision_device_data[usbvision->DevModel].Tuner == 1) {
- request_module("tuner");
+ struct v4l2_subdev *sd;
+ enum v4l2_i2c_tuner_type type;
+ struct tuner_setup tun_setup;
+
+ sd = v4l2_i2c_new_probed_subdev(&usbvision->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ /* depending on whether we found a demod or not, select
+ the tuner type. */
+ type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+
+ sd = v4l2_i2c_new_probed_subdev(&usbvision->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(type));
+
+ if (usbvision->tuner_type != -1) {
+ tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
+ tun_setup.type = usbvision->tuner_type;
+ tun_setup.addr = v4l2_i2c_subdev_addr(sd);
+ call_all(usbvision, tuner, s_type_addr, &tun_setup);
+ }
}
-#endif
- return usbvision_i2c_usb_add_bus(&usbvision->i2c_adap);
+ return 0;
}
int usbvision_i2c_unregister(struct usb_usbvision *usbvision)
@@ -278,67 +286,6 @@ int usbvision_i2c_unregister(struct usb_usbvision *usbvision)
return 0;
}
-void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,
- void *arg)
-{
- i2c_clients_command(&usbvision->i2c_adap, cmd, arg);
-}
-
-static int attach_inform(struct i2c_client *client)
-{
- struct usb_usbvision *usbvision;
-
- usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter);
-
- switch (client->addr << 1) {
- case 0x42 << 1:
- case 0x43 << 1:
- case 0x4a << 1:
- case 0x4b << 1:
- PDEBUG(DBG_I2C,"attach_inform: tda9887 detected.");
- break;
- case 0x42:
- PDEBUG(DBG_I2C,"attach_inform: saa7114 detected.");
- break;
- case 0x4a:
- PDEBUG(DBG_I2C,"attach_inform: saa7113 detected.");
- break;
- case 0x48:
- PDEBUG(DBG_I2C,"attach_inform: saa7111 detected.");
- break;
- case 0xa0:
- PDEBUG(DBG_I2C,"attach_inform: eeprom detected.");
- break;
-
- default:
- {
- struct tuner_setup tun_setup;
-
- PDEBUG(DBG_I2C,"attach inform: detected I2C address %x", client->addr << 1);
- usbvision->tuner_addr = client->addr;
-
- if ((usbvision->have_tuner) && (usbvision->tuner_type != -1)) {
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = usbvision->tuner_type;
- tun_setup.addr = usbvision->tuner_addr;
- call_i2c_clients(usbvision, TUNER_SET_TYPE_ADDR, &tun_setup);
- }
- }
- break;
- }
- return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
- struct usb_usbvision *usbvision;
-
- usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter);
-
- PDEBUG(DBG_I2C,"usbvision[%d] detaches %s", usbvision->nr, client->name);
- return 0;
-}
-
static int
usbvision_i2c_read_max4(struct usb_usbvision *usbvision, unsigned char addr,
char *buf, short len)
@@ -511,14 +458,6 @@ static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char add
static struct i2c_adapter i2c_adap_template = {
.owner = THIS_MODULE,
.name = "usbvision",
- .id = I2C_HW_B_BT848, /* FIXME */
- .client_register = attach_inform,
- .client_unregister = detach_inform,
- .class = I2C_CLASS_TV_ANALOG,
-};
-
-static struct i2c_client i2c_client_template = {
- .name = "usbvision internal",
};
/*
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 2622de003a45..fa62a2fd7b22 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -59,7 +59,6 @@
#include <linux/spinlock.h>
#include <asm/io.h>
#include <linux/videodev2.h>
-#include <linux/video_decoder.h>
#include <linux/i2c.h>
#include <media/saa7115.h>
@@ -212,7 +211,7 @@ static ssize_t show_hue(struct device *cd,
ctrl.id = V4L2_CID_HUE;
ctrl.value = 0;
if(usbvision->user)
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+ call_all(usbvision, core, g_ctrl, &ctrl);
return sprintf(buf, "%d\n", ctrl.value);
}
static DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
@@ -227,7 +226,7 @@ static ssize_t show_contrast(struct device *cd,
ctrl.id = V4L2_CID_CONTRAST;
ctrl.value = 0;
if(usbvision->user)
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+ call_all(usbvision, core, g_ctrl, &ctrl);
return sprintf(buf, "%d\n", ctrl.value);
}
static DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
@@ -242,7 +241,7 @@ static ssize_t show_brightness(struct device *cd,
ctrl.id = V4L2_CID_BRIGHTNESS;
ctrl.value = 0;
if(usbvision->user)
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+ call_all(usbvision, core, g_ctrl, &ctrl);
return sprintf(buf, "%d\n", ctrl.value);
}
static DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
@@ -257,7 +256,7 @@ static ssize_t show_saturation(struct device *cd,
ctrl.id = V4L2_CID_SATURATION;
ctrl.value = 0;
if(usbvision->user)
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+ call_all(usbvision, core, g_ctrl, &ctrl);
return sprintf(buf, "%d\n", ctrl.value);
}
static DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
@@ -329,7 +328,7 @@ static void usbvision_create_sysfs(struct video_device *vdev)
return;
} while (0);
- err("%s error: %d\n", __func__, res);
+ dev_err(&vdev->dev, "%s error: %d\n", __func__, res);
}
static void usbvision_remove_sysfs(struct video_device *vdev)
@@ -487,8 +486,9 @@ static int vidioc_g_register (struct file *file, void *priv,
/* NT100x has a 8-bit register space */
errCode = usbvision_read_reg(usbvision, reg->reg&0xff);
if (errCode < 0) {
- err("%s: VIDIOC_DBG_G_REGISTER failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->vdev->dev,
+ "%s: VIDIOC_DBG_G_REGISTER failed: error %d\n",
+ __func__, errCode);
return errCode;
}
reg->val = errCode;
@@ -507,8 +507,9 @@ static int vidioc_s_register (struct file *file, void *priv,
/* NT100x has a 8-bit register space */
errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
if (errCode < 0) {
- err("%s: VIDIOC_DBG_S_REGISTER failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->vdev->dev,
+ "%s: VIDIOC_DBG_S_REGISTER failed: error %d\n",
+ __func__, errCode);
return errCode;
}
return 0;
@@ -524,8 +525,7 @@ static int vidioc_querycap (struct file *file, void *priv,
strlcpy(vc->card,
usbvision_device_data[usbvision->DevModel].ModelString,
sizeof(vc->card));
- strlcpy(vc->bus_info, dev_name(&usbvision->dev->dev),
- sizeof(vc->bus_info));
+ usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info));
vc->version = USBVISION_DRIVER_VERSION;
vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_AUDIO |
@@ -621,8 +621,7 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id)
usbvision->tvnormId=*id;
mutex_lock(&usbvision->lock);
- call_i2c_clients(usbvision, VIDIOC_S_STD,
- &usbvision->tvnormId);
+ call_all(usbvision, tuner, s_std, usbvision->tvnormId);
mutex_unlock(&usbvision->lock);
/* propagate the change to the decoder */
usbvision_muxsel(usbvision, usbvision->ctl_input);
@@ -644,7 +643,7 @@ static int vidioc_g_tuner (struct file *file, void *priv,
strcpy(vt->name, "Television");
}
/* Let clients fill in the remainder of this struct */
- call_i2c_clients(usbvision,VIDIOC_G_TUNER,vt);
+ call_all(usbvision, tuner, g_tuner, vt);
return 0;
}
@@ -658,7 +657,7 @@ static int vidioc_s_tuner (struct file *file, void *priv,
if (!usbvision->have_tuner || vt->index)
return -EINVAL;
/* let clients handle this */
- call_i2c_clients(usbvision,VIDIOC_S_TUNER,vt);
+ call_all(usbvision, tuner, s_tuner, vt);
return 0;
}
@@ -689,7 +688,7 @@ static int vidioc_s_frequency (struct file *file, void *priv,
return -EINVAL;
usbvision->freq = freq->frequency;
- call_i2c_clients(usbvision, VIDIOC_S_FREQUENCY, freq);
+ call_all(usbvision, tuner, s_frequency, freq);
return 0;
}
@@ -698,7 +697,6 @@ static int vidioc_g_audio (struct file *file, void *priv, struct v4l2_audio *a)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- memset(a,0,sizeof(*a));
if(usbvision->radio) {
strcpy(a->name,"Radio");
} else {
@@ -722,12 +720,8 @@ static int vidioc_queryctrl (struct file *file, void *priv,
struct v4l2_queryctrl *ctrl)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int id=ctrl->id;
- memset(ctrl,0,sizeof(*ctrl));
- ctrl->id=id;
-
- call_i2c_clients(usbvision, VIDIOC_QUERYCTRL, ctrl);
+ call_all(usbvision, core, queryctrl, ctrl);
if (!ctrl->type)
return -EINVAL;
@@ -739,7 +733,7 @@ static int vidioc_g_ctrl (struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl);
+ call_all(usbvision, core, g_ctrl, ctrl);
return 0;
}
@@ -748,7 +742,7 @@ static int vidioc_s_ctrl (struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- call_i2c_clients(usbvision, VIDIOC_S_CTRL, ctrl);
+ call_all(usbvision, core, s_ctrl, ctrl);
return 0;
}
@@ -763,8 +757,7 @@ static int vidioc_reqbufs (struct file *file,
/* Check input validity:
the user must do a VIDEO CAPTURE and MMAP method. */
- if((vr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
- (vr->memory != V4L2_MEMORY_MMAP))
+ if (vr->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
if(usbvision->streaming == Stream_On) {
@@ -789,9 +782,6 @@ static int vidioc_querybuf (struct file *file,
/* FIXME : must control
that buffers are mapped (VIDIOC_REQBUFS has been called) */
- if(vb->type != V4L2_CAP_VIDEO_CAPTURE) {
- return -EINVAL;
- }
if(vb->index>=usbvision->num_frames) {
return -EINVAL;
}
@@ -825,9 +815,6 @@ static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *vb)
unsigned long lock_flags;
/* FIXME : works only on VIDEO_CAPTURE MODE, MMAP. */
- if(vb->type != V4L2_CAP_VIDEO_CAPTURE) {
- return -EINVAL;
- }
if(vb->index>=usbvision->num_frames) {
return -EINVAL;
}
@@ -862,9 +849,6 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb)
struct usbvision_frame *f;
unsigned long lock_flags;
- if (vb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (list_empty(&(usbvision->outqueue))) {
if (usbvision->streaming == Stream_Idle)
return -EINVAL;
@@ -899,10 +883,9 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb)
static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int b=V4L2_BUF_TYPE_VIDEO_CAPTURE;
usbvision->streaming = Stream_On;
- call_i2c_clients(usbvision,VIDIOC_STREAMON , &b);
+ call_all(usbvision, video, s_stream, 1);
return 0;
}
@@ -911,7 +894,6 @@ static int vidioc_streamoff(struct file *file,
void *priv, enum v4l2_buf_type type)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int b=V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -919,7 +901,7 @@ static int vidioc_streamoff(struct file *file,
if(usbvision->streaming == Stream_On) {
usbvision_stream_interrupt(usbvision);
/* Stop all video streamings */
- call_i2c_clients(usbvision,VIDIOC_STREAMOFF , &b);
+ call_all(usbvision, video, s_stream, 0);
}
usbvision_empty_framequeues(usbvision);
@@ -932,11 +914,8 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
if(vfd->index>=USBVISION_SUPPORTED_PALETTES-1) {
return -EINVAL;
}
- vfd->flags = 0;
- vfd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
strcpy(vfd->description,usbvision_v4l2_format[vfd->index].desc);
vfd->pixelformat = usbvision_v4l2_format[vfd->index].format;
- memset(vfd->reserved, 0, sizeof(vfd->reserved));
return 0;
}
@@ -1042,7 +1021,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf,
if(usbvision->streaming != Stream_On) {
/* no stream is running, make it running ! */
usbvision->streaming = Stream_On;
- call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL);
+ call_all(usbvision, video, s_stream, 1);
}
/* Then, enqueue as many frames as possible
@@ -1189,7 +1168,9 @@ static int usbvision_radio_open(struct file *file)
mutex_lock(&usbvision->lock);
if (usbvision->user) {
- err("%s: Someone tried to open an already opened USBVision Radio!", __func__);
+ dev_err(&usbvision->rdev->dev,
+ "%s: Someone tried to open an already opened USBVision Radio!\n",
+ __func__);
errCode = -EBUSY;
}
else {
@@ -1211,7 +1192,7 @@ static int usbvision_radio_open(struct file *file)
// If so far no errors then we shall start the radio
usbvision->radio = 1;
- call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type);
+ call_all(usbvision, tuner, s_radio);
usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO);
usbvision->user++;
}
@@ -1413,7 +1394,8 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
struct video_device *vdev;
if (usb_dev == NULL) {
- err("%s: usbvision->dev is not set", __func__);
+ dev_err(&usbvision->dev->dev,
+ "%s: usbvision->dev is not set\n", __func__);
return NULL;
}
@@ -1423,7 +1405,7 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
}
*vdev = *vdev_template;
// vdev->minor = -1;
- vdev->parent = &usb_dev->dev;
+ vdev->v4l2_dev = &usbvision->v4l2_dev;
snprintf(vdev->name, sizeof(vdev->name), "%s", name);
video_set_drvdata(vdev, usbvision);
return vdev;
@@ -1524,7 +1506,9 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
return 0;
err_exit:
- err("USBVision[%d]: video_register_device() failed", usbvision->nr);
+ dev_err(&usbvision->dev->dev,
+ "USBVision[%d]: video_register_device() failed\n",
+ usbvision->nr);
usbvision_unregister_video(usbvision);
return -1;
}
@@ -1542,33 +1526,30 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev)
{
struct usb_usbvision *usbvision;
- if ((usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL)) ==
- NULL) {
- goto err_exit;
- }
+ usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL);
+ if (usbvision == NULL)
+ return NULL;
usbvision->dev = dev;
+ if (v4l2_device_register(&dev->dev, &usbvision->v4l2_dev))
+ goto err_free;
mutex_init(&usbvision->lock); /* available */
// prepare control urb for control messages during interrupts
usbvision->ctrlUrb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
- if (usbvision->ctrlUrb == NULL) {
- goto err_exit;
- }
+ if (usbvision->ctrlUrb == NULL)
+ goto err_unreg;
init_waitqueue_head(&usbvision->ctrlUrb_wq);
usbvision_init_powerOffTimer(usbvision);
return usbvision;
-err_exit:
- if (usbvision && usbvision->ctrlUrb) {
- usb_free_urb(usbvision->ctrlUrb);
- }
- if (usbvision) {
- kfree(usbvision);
- }
+err_unreg:
+ v4l2_device_unregister(&usbvision->v4l2_dev);
+err_free:
+ kfree(usbvision);
return NULL;
}
@@ -1598,6 +1579,7 @@ static void usbvision_release(struct usb_usbvision *usbvision)
usb_free_urb(usbvision->ctrlUrb);
}
+ v4l2_device_unregister(&usbvision->v4l2_dev);
kfree(usbvision);
PDEBUG(DBG_PROBE, "success");
@@ -1675,20 +1657,20 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
}
endpoint = &interface->endpoint[1].desc;
if (!usb_endpoint_xfer_isoc(endpoint)) {
- err("%s: interface %d. has non-ISO endpoint!",
+ dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n",
__func__, ifnum);
- err("%s: Endpoint attributes %d",
+ dev_err(&intf->dev, "%s: Endpoint attributes %d",
__func__, endpoint->bmAttributes);
return -ENODEV;
}
if (usb_endpoint_dir_out(endpoint)) {
- err("%s: interface %d. has ISO OUT endpoint!",
+ dev_err(&intf->dev, "%s: interface %d. has ISO OUT endpoint!\n",
__func__, ifnum);
return -ENODEV;
}
if ((usbvision = usbvision_alloc(dev)) == NULL) {
- err("%s: couldn't allocate USBVision struct", __func__);
+ dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", __func__);
return -ENOMEM;
}
@@ -1711,7 +1693,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
usbvision->alt_max_pkt_size = kmalloc(32*
usbvision->num_alt,GFP_KERNEL);
if (usbvision->alt_max_pkt_size == NULL) {
- err("usbvision: out of memory!\n");
+ dev_err(&intf->dev, "usbvision: out of memory!\n");
mutex_unlock(&usbvision->lock);
return -ENOMEM;
}
@@ -1733,8 +1715,6 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
usbvision->tuner_type = usbvision_device_data[model].TunerType;
}
- usbvision->tuner_addr = ADDR_UNSET;
-
usbvision->DevModel = model;
usbvision->remove_pending = 0;
usbvision->iface = ifnum;
@@ -1772,7 +1752,8 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
PDEBUG(DBG_PROBE, "");
if (usbvision == NULL) {
- err("%s: usb_get_intfdata() failed", __func__);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_get_intfdata() failed\n", __func__);
return;
}
usb_set_intfdata (intf, NULL);
@@ -1782,6 +1763,8 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
// At this time we ask to cancel outstanding URBs
usbvision_stop_isoc(usbvision);
+ v4l2_device_disconnect(&usbvision->v4l2_dev);
+
if (usbvision->power) {
usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h
index 20d7ec624999..f8d7458daf3e 100644
--- a/drivers/media/video/usbvision/usbvision.h
+++ b/drivers/media/video/usbvision/usbvision.h
@@ -6,7 +6,7 @@
* Dwaine Garden <dwainegarden@rogers.com>
*
*
- * Report problems to v4l MailingList : http://www.redhat.com/mailman/listinfo/video4linux-list
+ * Report problems to v4l MailingList: linux-media@vger.kernel.org
*
* This module is part of usbvision driver project.
* Updates to driver completed by Dwaine P. Garden
@@ -35,7 +35,7 @@
#include <linux/usb.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/tuner.h>
#include <linux/videodev2.h>
@@ -357,13 +357,13 @@ extern struct usbvision_device_data_st usbvision_device_data[];
extern struct usb_device_id usbvision_table[];
struct usb_usbvision {
+ struct v4l2_device v4l2_dev;
struct video_device *vdev; /* Video Device */
struct video_device *rdev; /* Radio Device */
struct video_device *vbi; /* VBI Device */
/* i2c Declaration Section*/
struct i2c_adapter i2c_adap;
- struct i2c_client i2c_client;
struct urb *ctrlUrb;
unsigned char ctrlUrbBuffer[8];
@@ -374,7 +374,6 @@ struct usb_usbvision {
/* configuration part */
int have_tuner;
int tuner_type;
- int tuner_addr;
int bridgeType; // NT1003, NT1004, NT1005
int radio;
int video_inputs; // # of inputs
@@ -464,6 +463,8 @@ struct usb_usbvision {
int ComprBlockTypes[4];
};
+#define call_all(usbvision, o, f, args...) \
+ v4l2_device_call_all(&usbvision->v4l2_dev, 0, o, f, ##args)
/* --------------------------------------------------------------- */
/* defined in usbvision-i2c.c */
@@ -475,7 +476,6 @@ struct usb_usbvision {
/* ----------------------------------------------------------------------- */
int usbvision_i2c_register(struct usb_usbvision *usbvision);
int usbvision_i2c_unregister(struct usb_usbvision *usbvision);
-void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,void *arg);
/* defined in usbvision-core.c */
int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg);
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index d2576f6391c0..0d7e38d6ff6a 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -786,7 +786,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
v4l2_ctrl->id = mapping->id;
v4l2_ctrl->type = mapping->v4l2_type;
- strncpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
+ strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
v4l2_ctrl->flags = 0;
if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR))
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index b12873265cc5..399412d7f020 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -314,7 +314,7 @@ static int uvc_parse_format(struct uvc_device *dev,
fmtdesc = uvc_format_by_guid(&buffer[5]);
if (fmtdesc != NULL) {
- strncpy(format->name, fmtdesc->name,
+ strlcpy(format->name, fmtdesc->name,
sizeof format->name);
format->fcc = fmtdesc->fcc;
} else {
@@ -345,7 +345,7 @@ static int uvc_parse_format(struct uvc_device *dev,
return -EINVAL;
}
- strncpy(format->name, "MJPEG", sizeof format->name);
+ strlcpy(format->name, "MJPEG", sizeof format->name);
format->fcc = V4L2_PIX_FMT_MJPEG;
format->flags = UVC_FMT_FLAG_COMPRESSED;
format->bpp = 0;
@@ -363,13 +363,13 @@ static int uvc_parse_format(struct uvc_device *dev,
switch (buffer[8] & 0x7f) {
case 0:
- strncpy(format->name, "SD-DV", sizeof format->name);
+ strlcpy(format->name, "SD-DV", sizeof format->name);
break;
case 1:
- strncpy(format->name, "SDL-DV", sizeof format->name);
+ strlcpy(format->name, "SDL-DV", sizeof format->name);
break;
case 2:
- strncpy(format->name, "HD-DV", sizeof format->name);
+ strlcpy(format->name, "HD-DV", sizeof format->name);
break;
default:
uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
@@ -379,7 +379,7 @@ static int uvc_parse_format(struct uvc_device *dev,
return -EINVAL;
}
- strncat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
+ strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
sizeof format->name);
format->fcc = V4L2_PIX_FMT_DV;
@@ -1526,7 +1526,7 @@ static int uvc_register_video(struct uvc_device *dev)
vdev->minor = -1;
vdev->fops = &uvc_fops;
vdev->release = video_device_release;
- strncpy(vdev->name, dev->name, sizeof vdev->name);
+ strlcpy(vdev->name, dev->name, sizeof vdev->name);
/* Set the driver data before calling video_register_device, otherwise
* uvc_v4l2_open might race us.
@@ -1621,7 +1621,7 @@ static int uvc_probe(struct usb_interface *intf,
dev->quirks = id->driver_info | uvc_quirks_param;
if (udev->product != NULL)
- strncpy(dev->name, udev->product, sizeof dev->name);
+ strlcpy(dev->name, udev->product, sizeof dev->name);
else
snprintf(dev->name, sizeof dev->name,
"UVC Camera (%04x:%04x)",
@@ -1833,6 +1833,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0 },
+ /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x058f,
+ .idProduct = 0x3820,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
/* Apple Built-In iSight */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1852,6 +1861,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
+ /* ViMicro */
+ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x0ac8,
+ .idProduct = 0x0000,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
/* MT6227 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1879,7 +1897,7 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Asus F9SG */
+ /* Syntek (Asus F9SG) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x174f,
@@ -1897,6 +1915,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
+ /* Syntek (JAOtech Smart Terminal) */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x174f,
+ .idProduct = 0x8a34,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_STREAM_NO_FID },
/* Lenovo Thinkpad SL500 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c
index c705f248da88..21d87124986b 100644
--- a/drivers/media/video/uvc/uvc_status.c
+++ b/drivers/media/video/uvc/uvc_status.c
@@ -24,26 +24,19 @@
#ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV
static int uvc_input_init(struct uvc_device *dev)
{
- struct usb_device *udev = dev->udev;
struct input_dev *input;
- char *phys = NULL;
int ret;
input = input_allocate_device();
if (input == NULL)
return -ENOMEM;
- phys = kmalloc(6 + strlen(udev->bus->bus_name) + strlen(udev->devpath),
- GFP_KERNEL);
- if (phys == NULL) {
- ret = -ENOMEM;
- goto error;
- }
- sprintf(phys, "usb-%s-%s", udev->bus->bus_name, udev->devpath);
+ usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys));
+ strlcat(dev->input_phys, "/button", sizeof(dev->input_phys));
input->name = dev->name;
- input->phys = phys;
- usb_to_input_id(udev, &input->id);
+ input->phys = dev->input_phys;
+ usb_to_input_id(dev->udev, &input->id);
input->dev.parent = &dev->intf->dev;
__set_bit(EV_KEY, input->evbit);
@@ -57,7 +50,6 @@ static int uvc_input_init(struct uvc_device *dev)
error:
input_free_device(input);
- kfree(phys);
return ret;
}
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index d681519d0c8a..2a80caa54fb4 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -55,7 +55,7 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video,
return -EINVAL;
menu_info = &mapping->menu_info[query_menu->index];
- strncpy(query_menu->name, menu_info->name, 32);
+ strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
return 0;
}
@@ -486,10 +486,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
struct v4l2_capability *cap = arg;
memset(cap, 0, sizeof *cap);
- strncpy(cap->driver, "uvcvideo", sizeof cap->driver);
- strncpy(cap->card, vdev->name, 32);
- strncpy(cap->bus_info, video->dev->udev->bus->bus_name,
- sizeof cap->bus_info);
+ strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
+ strlcpy(cap->card, vdev->name, sizeof cap->card);
+ usb_make_path(video->dev->udev,
+ cap->bus_info, sizeof(cap->bus_info));
cap->version = DRIVER_VERSION_NUMBER;
if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
@@ -620,7 +620,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
memset(input, 0, sizeof *input);
input->index = index;
- strncpy(input->name, iterm->name, sizeof input->name);
+ strlcpy(input->name, iterm->name, sizeof input->name);
if (UVC_ENTITY_TYPE(iterm) == ITT_CAMERA)
input->type = V4L2_INPUT_TYPE_CAMERA;
break;
@@ -673,16 +673,22 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct v4l2_fmtdesc *fmt = arg;
struct uvc_format *format;
+ enum v4l2_buf_type type = fmt->type;
+ __u32 index = fmt->index;
if (fmt->type != video->streaming->type ||
fmt->index >= video->streaming->nformats)
return -EINVAL;
+ memset(fmt, 0, sizeof(*fmt));
+ fmt->index = index;
+ fmt->type = type;
+
format = &video->streaming->format[fmt->index];
fmt->flags = 0;
if (format->flags & UVC_FMT_FLAG_COMPRESSED)
fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
- strncpy(fmt->description, format->name,
+ strlcpy(fmt->description, format->name,
sizeof fmt->description);
fmt->description[sizeof fmt->description - 1] = 0;
fmt->pixelformat = format->fcc;
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 9bc4705be78d..a95e17329c5b 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -61,7 +61,7 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
return 0;
}
-static void uvc_fixup_buffer_size(struct uvc_video_device *video,
+static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
struct uvc_streaming_control *ctrl)
{
struct uvc_format *format;
@@ -84,6 +84,31 @@ static void uvc_fixup_buffer_size(struct uvc_video_device *video,
video->dev->uvc_version < 0x0110))
ctrl->dwMaxVideoFrameSize =
frame->dwMaxVideoFrameBufferSize;
+
+ if (video->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
+ video->streaming->intf->num_altsetting > 1) {
+ u32 interval;
+ u32 bandwidth;
+
+ interval = (ctrl->dwFrameInterval > 100000)
+ ? ctrl->dwFrameInterval
+ : frame->dwFrameInterval[0];
+
+ /* Compute a bandwidth estimation by multiplying the frame
+ * size by the number of video frames per second, divide the
+ * result by the number of USB frames (or micro-frames for
+ * high-speed devices) per second and add the UVC header size
+ * (assumed to be 12 bytes long).
+ */
+ bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp;
+ bandwidth *= 10000000 / interval + 1;
+ bandwidth /= 1000;
+ if (video->dev->udev->speed == USB_SPEED_HIGH)
+ bandwidth /= 8;
+ bandwidth += 12;
+
+ ctrl->dwMaxPayloadTransferSize = bandwidth;
+ }
}
static int uvc_get_video_ctrl(struct uvc_video_device *video,
@@ -158,10 +183,11 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
ctrl->bMaxVersion = 0;
}
- /* Some broken devices return a null or wrong dwMaxVideoFrameSize.
- * Try to get the value from the format and frame descriptors.
+ /* Some broken devices return null or wrong dwMaxVideoFrameSize and
+ * dwMaxPayloadTransferSize fields. Try to get the value from the
+ * format and frame descriptors.
*/
- uvc_fixup_buffer_size(video, ctrl);
+ uvc_fixup_video_ctrl(video, ctrl);
ret = 0;
out:
@@ -540,6 +566,9 @@ static void uvc_video_decode_bulk(struct urb *urb,
u8 *mem;
int len, ret;
+ if (urb->actual_length == 0)
+ return;
+
mem = urb->transfer_buffer;
len = urb->actual_length;
video->bulk.payload_size += len;
@@ -699,27 +728,47 @@ static void uvc_free_urb_buffers(struct uvc_video_device *video)
* already allocated when resuming from suspend, in which case it will
* return without touching the buffers.
*
- * Return 0 on success or -ENOMEM when out of memory.
+ * Limit the buffer size to UVC_MAX_PACKETS bulk/isochronous packets. If the
+ * system is too low on memory try successively smaller numbers of packets
+ * until allocation succeeds.
+ *
+ * Return the number of allocated packets on success or 0 when out of memory.
*/
static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
- unsigned int size)
+ unsigned int size, unsigned int psize, gfp_t gfp_flags)
{
+ unsigned int npackets;
unsigned int i;
/* Buffers are already allocated, bail out. */
if (video->urb_size)
return 0;
- for (i = 0; i < UVC_URBS; ++i) {
- video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
- size, GFP_KERNEL, &video->urb_dma[i]);
- if (video->urb_buffer[i] == NULL) {
- uvc_free_urb_buffers(video);
- return -ENOMEM;
+ /* Compute the number of packets. Bulk endpoints might transfer UVC
+ * payloads accross multiple URBs.
+ */
+ npackets = DIV_ROUND_UP(size, psize);
+ if (npackets > UVC_MAX_PACKETS)
+ npackets = UVC_MAX_PACKETS;
+
+ /* Retry allocations until one succeed. */
+ for (; npackets > 1; npackets /= 2) {
+ for (i = 0; i < UVC_URBS; ++i) {
+ video->urb_buffer[i] = usb_buffer_alloc(
+ video->dev->udev, psize * npackets,
+ gfp_flags | __GFP_NOWARN, &video->urb_dma[i]);
+ if (!video->urb_buffer[i]) {
+ uvc_free_urb_buffers(video);
+ break;
+ }
+ }
+
+ if (i == UVC_URBS) {
+ video->urb_size = psize * npackets;
+ return npackets;
}
}
- video->urb_size = size;
return 0;
}
@@ -753,29 +802,19 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
{
struct urb *urb;
unsigned int npackets, i, j;
- __u16 psize;
- __u32 size;
+ u16 psize;
+ u32 size;
- /* Compute the number of isochronous packets to allocate by dividing
- * the maximum video frame size by the packet size. Limit the result
- * to UVC_MAX_ISO_PACKETS.
- */
psize = le16_to_cpu(ep->desc.wMaxPacketSize);
psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
-
size = video->streaming->ctrl.dwMaxVideoFrameSize;
- if (size > UVC_MAX_FRAME_SIZE)
- return -EINVAL;
- npackets = DIV_ROUND_UP(size, psize);
- if (npackets > UVC_MAX_ISO_PACKETS)
- npackets = UVC_MAX_ISO_PACKETS;
+ npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
+ if (npackets == 0)
+ return -ENOMEM;
size = npackets * psize;
- if (uvc_alloc_urb_buffers(video, size) < 0)
- return -ENOMEM;
-
for (i = 0; i < UVC_URBS; ++i) {
urb = usb_alloc_urb(npackets, gfp_flags);
if (urb == NULL) {
@@ -814,25 +853,20 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
struct usb_host_endpoint *ep, gfp_t gfp_flags)
{
struct urb *urb;
- unsigned int pipe, i;
- __u16 psize;
- __u32 size;
-
- /* Compute the bulk URB size. Some devices set the maximum payload
- * size to a value too high for memory-constrained devices. We must
- * then transfer the payload accross multiple URBs. To be consistant
- * with isochronous mode, allocate maximum UVC_MAX_ISO_PACKETS per bulk
- * URB.
- */
+ unsigned int npackets, pipe, i;
+ u16 psize;
+ u32 size;
+
psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff;
size = video->streaming->ctrl.dwMaxPayloadTransferSize;
video->bulk.max_payload_size = size;
- if (size > psize * UVC_MAX_ISO_PACKETS)
- size = psize * UVC_MAX_ISO_PACKETS;
- if (uvc_alloc_urb_buffers(video, size) < 0)
+ npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
+ if (npackets == 0)
return -ENOMEM;
+ size = npackets * psize;
+
if (usb_endpoint_dir_in(&ep->desc))
pipe = usb_rcvbulkpipe(video->dev->udev,
ep->desc.bEndpointAddress);
@@ -1021,11 +1055,20 @@ int uvc_video_init(struct uvc_video_device *video)
*/
usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
- /* Some webcams don't suport GET_DEF requests on the probe control. We
- * fall back to GET_CUR if GET_DEF fails.
+ /* Set the streaming probe control with default streaming parameters
+ * retrieved from the device. Webcams that don't suport GET_DEF
+ * requests on the probe control will just keep their current streaming
+ * parameters.
+ */
+ if (uvc_get_video_ctrl(video, probe, 1, GET_DEF) == 0)
+ uvc_set_video_ctrl(video, probe, 1);
+
+ /* Initialize the streaming parameters with the probe control current
+ * value. This makes sure SET_CUR requests on the streaming commit
+ * control will always use values retrieved from a successful GET_CUR
+ * request on the probe control, as required by the UVC specification.
*/
- if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 &&
- (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0)
+ if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0)
return ret;
/* Check if the default format descriptor exists. Use the first
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 027947ea9b6e..e5014e668f99 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -296,10 +296,8 @@ struct uvc_xu_control {
/* Number of isochronous URBs. */
#define UVC_URBS 5
-/* Maximum number of packets per isochronous URB. */
-#define UVC_MAX_ISO_PACKETS 40
-/* Maximum frame size in bytes, for sanity checking. */
-#define UVC_MAX_FRAME_SIZE (16*1024*1024)
+/* Maximum number of packets per URB. */
+#define UVC_MAX_PACKETS 32
/* Maximum number of video buffers. */
#define UVC_MAX_VIDEO_BUFFERS 32
/* Maximum status buffer size in bytes of interrupt URB. */
@@ -316,6 +314,7 @@ struct uvc_xu_control {
#define UVC_QUIRK_STREAM_NO_FID 0x00000010
#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
#define UVC_QUIRK_PRUNE_CONTROLS 0x00000040
+#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080
/* Format flags */
#define UVC_FMT_FLAG_COMPRESSED 0x00000001
@@ -649,6 +648,7 @@ struct uvc_device {
struct urb *int_urb;
__u8 *status;
struct input_dev *input;
+ char input_phys[64];
/* Video Streaming interfaces */
struct list_head streaming;
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index b8f2be8d5c0e..1da8cb836cb6 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -334,6 +334,12 @@ const char **v4l2_ctrl_get_menu(u32 id)
"Aperture Priority Mode",
NULL
};
+ static const char *colorfx[] = {
+ "None",
+ "Black & White",
+ "Sepia",
+ NULL
+ };
switch (id) {
case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
@@ -370,6 +376,8 @@ const char **v4l2_ctrl_get_menu(u32 id)
return camera_power_line_frequency;
case V4L2_CID_EXPOSURE_AUTO:
return camera_exposure_auto;
+ case V4L2_CID_COLORFX:
+ return colorfx;
default:
return NULL;
}
@@ -382,16 +390,16 @@ const char *v4l2_ctrl_get_name(u32 id)
switch (id) {
/* USER controls */
case V4L2_CID_USER_CLASS: return "User Controls";
+ case V4L2_CID_BRIGHTNESS: return "Brightness";
+ case V4L2_CID_CONTRAST: return "Contrast";
+ case V4L2_CID_SATURATION: return "Saturation";
+ case V4L2_CID_HUE: return "Hue";
case V4L2_CID_AUDIO_VOLUME: return "Volume";
- case V4L2_CID_AUDIO_MUTE: return "Mute";
case V4L2_CID_AUDIO_BALANCE: return "Balance";
case V4L2_CID_AUDIO_BASS: return "Bass";
case V4L2_CID_AUDIO_TREBLE: return "Treble";
+ case V4L2_CID_AUDIO_MUTE: return "Mute";
case V4L2_CID_AUDIO_LOUDNESS: return "Loudness";
- case V4L2_CID_BRIGHTNESS: return "Brightness";
- case V4L2_CID_CONTRAST: return "Contrast";
- case V4L2_CID_SATURATION: return "Saturation";
- case V4L2_CID_HUE: return "Hue";
case V4L2_CID_BLACK_LEVEL: return "Black Level";
case V4L2_CID_AUTO_WHITE_BALANCE: return "White Balance, Automatic";
case V4L2_CID_DO_WHITE_BALANCE: return "Do White Balance";
@@ -412,6 +420,7 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation";
case V4L2_CID_CHROMA_AGC: return "Chroma AGC";
case V4L2_CID_COLOR_KILLER: return "Color Killer";
+ case V4L2_CID_COLORFX: return "Color Effects";
/* MPEG controls */
case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls";
@@ -490,16 +499,25 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
case V4L2_CID_HFLIP:
case V4L2_CID_VFLIP:
case V4L2_CID_HUE_AUTO:
+ case V4L2_CID_CHROMA_AGC:
+ case V4L2_CID_COLOR_KILLER:
case V4L2_CID_MPEG_AUDIO_MUTE:
case V4L2_CID_MPEG_VIDEO_MUTE:
case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
case V4L2_CID_MPEG_VIDEO_PULLDOWN:
case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
+ case V4L2_CID_FOCUS_AUTO:
case V4L2_CID_PRIVACY:
qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
min = 0;
max = step = 1;
break;
+ case V4L2_CID_PAN_RESET:
+ case V4L2_CID_TILT_RESET:
+ qctrl->type = V4L2_CTRL_TYPE_BUTTON;
+ qctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
+ min = max = step = def = 0;
+ break;
case V4L2_CID_POWER_LINE_FREQUENCY:
case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
case V4L2_CID_MPEG_AUDIO_ENCODING:
@@ -517,6 +535,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
case V4L2_CID_MPEG_STREAM_TYPE:
case V4L2_CID_MPEG_STREAM_VBI_FMT:
case V4L2_CID_EXPOSURE_AUTO:
+ case V4L2_CID_COLORFX:
qctrl->type = V4L2_CTRL_TYPE_MENU;
step = 1;
break;
@@ -547,161 +566,29 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
case V4L2_CID_CONTRAST:
case V4L2_CID_SATURATION:
case V4L2_CID_HUE:
+ case V4L2_CID_RED_BALANCE:
+ case V4L2_CID_BLUE_BALANCE:
+ case V4L2_CID_GAMMA:
+ case V4L2_CID_SHARPNESS:
qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
break;
+ case V4L2_CID_PAN_RELATIVE:
+ case V4L2_CID_TILT_RELATIVE:
+ case V4L2_CID_FOCUS_RELATIVE:
+ case V4L2_CID_ZOOM_RELATIVE:
+ qctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
+ break;
}
qctrl->minimum = min;
qctrl->maximum = max;
qctrl->step = step;
qctrl->default_value = def;
qctrl->reserved[0] = qctrl->reserved[1] = 0;
- snprintf(qctrl->name, sizeof(qctrl->name), name);
+ strlcpy(qctrl->name, name, sizeof(qctrl->name));
return 0;
}
EXPORT_SYMBOL(v4l2_ctrl_query_fill);
-/* Fill in a struct v4l2_queryctrl with standard values based on
- the control ID. */
-int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
-{
- switch (qctrl->id) {
- /* USER controls */
- case V4L2_CID_USER_CLASS:
- case V4L2_CID_MPEG_CLASS:
- return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
- case V4L2_CID_AUDIO_VOLUME:
- return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 58880);
- case V4L2_CID_AUDIO_MUTE:
- case V4L2_CID_AUDIO_LOUDNESS:
- return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
- case V4L2_CID_AUDIO_BALANCE:
- case V4L2_CID_AUDIO_BASS:
- case V4L2_CID_AUDIO_TREBLE:
- return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 32768);
- case V4L2_CID_BRIGHTNESS:
- return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
- case V4L2_CID_CONTRAST:
- case V4L2_CID_SATURATION:
- return v4l2_ctrl_query_fill(qctrl, 0, 127, 1, 64);
- case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill(qctrl, -128, 127, 1, 0);
-
- /* MPEG controls */
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_ENCODING_LAYER_1,
- V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
- case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_L1_BITRATE_32K,
- V4L2_MPEG_AUDIO_L1_BITRATE_448K, 1,
- V4L2_MPEG_AUDIO_L1_BITRATE_256K);
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_L2_BITRATE_32K,
- V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
- V4L2_MPEG_AUDIO_L2_BITRATE_224K);
- case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_L3_BITRATE_32K,
- V4L2_MPEG_AUDIO_L3_BITRATE_320K, 1,
- V4L2_MPEG_AUDIO_L3_BITRATE_192K);
- case V4L2_CID_MPEG_AUDIO_AAC_BITRATE:
- return v4l2_ctrl_query_fill(qctrl, 0, 6400, 1, 3200000);
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_AC3_BITRATE_32K,
- V4L2_MPEG_AUDIO_AC3_BITRATE_640K, 1,
- V4L2_MPEG_AUDIO_AC3_BITRATE_384K);
- case V4L2_CID_MPEG_AUDIO_MODE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_MODE_STEREO,
- V4L2_MPEG_AUDIO_MODE_MONO, 1,
- V4L2_MPEG_AUDIO_MODE_STEREO);
- case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
- case V4L2_CID_MPEG_AUDIO_EMPHASIS:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_EMPHASIS_NONE,
- V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1,
- V4L2_MPEG_AUDIO_EMPHASIS_NONE);
- case V4L2_CID_MPEG_AUDIO_CRC:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_CRC_NONE,
- V4L2_MPEG_AUDIO_CRC_CRC16, 1,
- V4L2_MPEG_AUDIO_CRC_NONE);
- case V4L2_CID_MPEG_AUDIO_MUTE:
- return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_ASPECT_1x1,
- V4L2_MPEG_VIDEO_ASPECT_221x100, 1,
- V4L2_MPEG_VIDEO_ASPECT_4x3);
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2);
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- return v4l2_ctrl_query_fill(qctrl, 1, 34, 1, 12);
- case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
- return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
- case V4L2_CID_MPEG_VIDEO_PULLDOWN:
- return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
- case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
- return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
- case V4L2_CID_MPEG_VIDEO_MUTE:
- return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
- case V4L2_CID_MPEG_VIDEO_MUTE_YUV: /* Init YUV (really YCbCr) to black */
- return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080);
- case V4L2_CID_MPEG_STREAM_TYPE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
- V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1,
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
- case V4L2_CID_MPEG_STREAM_PID_PMT:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16);
- case V4L2_CID_MPEG_STREAM_PID_AUDIO:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260);
- case V4L2_CID_MPEG_STREAM_PID_VIDEO:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256);
- case V4L2_CID_MPEG_STREAM_PID_PCR:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259);
- case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO:
- return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
- case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO:
- return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
- case V4L2_CID_MPEG_STREAM_VBI_FMT:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_STREAM_VBI_FMT_NONE,
- V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1,
- V4L2_MPEG_STREAM_VBI_FMT_NONE);
- default:
- return -EINVAL;
- }
-}
-EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
-
/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
the menu. The qctrl pointer may be NULL, in which case it is ignored.
If menu_items is NULL, then the menu items are retrieved using
@@ -720,7 +607,7 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc
for (i = 0; i < qmenu->index && menu_items[i]; i++) ;
if (menu_items[i] == NULL || menu_items[i][0] == '\0')
return -EINVAL;
- snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]);
+ strlcpy(qmenu->name, menu_items[qmenu->index], sizeof(qmenu->name));
return 0;
}
EXPORT_SYMBOL(v4l2_ctrl_query_menu);
@@ -737,8 +624,8 @@ int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *id
return -EINVAL;
while (*ids != V4L2_CTRL_MENU_IDS_END) {
if (*ids++ == qmenu->index) {
- snprintf(qmenu->name, sizeof(qmenu->name),
- menu_items[qmenu->index]);
+ strlcpy(qmenu->name, menu_items[qmenu->index],
+ sizeof(qmenu->name));
return 0;
}
}
@@ -749,7 +636,7 @@ EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid_items);
/* ctrl_classes points to an array of u32 pointers, the last element is
a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
Each array must be sorted low to high and belong to the same control
- class. The array of u32 pointer must also be sorted, from low class IDs
+ class. The array of u32 pointers must also be sorted, from low class IDs
to high class IDs.
This function returns the first ID that follows after the given ID.
@@ -910,10 +797,10 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter,
struct i2c_board_info info;
BUG_ON(!dev);
-#ifdef MODULE
+
if (module_name)
request_module(module_name);
-#endif
+
/* Setup the i2c board info with the device type and
the device address. */
memset(&info, 0, sizeof(info));
@@ -927,11 +814,11 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter,
We need better support from the kernel so that we
can easily wait for the load to finish. */
if (client == NULL || client->driver == NULL)
- return NULL;
+ goto error;
/* Lock the module so we can safely get the v4l2_subdev pointer */
if (!try_module_get(client->driver->driver.owner))
- return NULL;
+ goto error;
sd = i2c_get_clientdata(client);
/* Register with the v4l2_device which increases the module's
@@ -940,8 +827,13 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter,
sd = NULL;
/* Decrease the module use count to match the first try_module_get. */
module_put(client->driver->driver.owner);
- return sd;
+error:
+ /* If we have a client but no subdev, then something went wrong and
+ we must unregister the client. */
+ if (client && sd == NULL)
+ i2c_unregister_device(client);
+ return sd;
}
EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
@@ -958,10 +850,10 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
struct i2c_board_info info;
BUG_ON(!dev);
-#ifdef MODULE
+
if (module_name)
request_module(module_name);
-#endif
+
/* Setup the i2c board info with the device type and
the device address. */
memset(&info, 0, sizeof(info));
@@ -974,11 +866,11 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
We need better support from the kernel so that we
can easily wait for the load to finish. */
if (client == NULL || client->driver == NULL)
- return NULL;
+ goto error;
/* Lock the module so we can safely get the v4l2_subdev pointer */
if (!try_module_get(client->driver->driver.owner))
- return NULL;
+ goto error;
sd = i2c_get_clientdata(client);
/* Register with the v4l2_device which increases the module's
@@ -987,8 +879,59 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
sd = NULL;
/* Decrease the module use count to match the first try_module_get. */
module_put(client->driver->driver.owner);
+
+error:
+ /* If we have a client but no subdev, then something went wrong and
+ we must unregister the client. */
+ if (client && sd == NULL)
+ i2c_unregister_device(client);
return sd;
}
EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev);
+/* Return i2c client address of v4l2_subdev. */
+unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return client ? client->addr : I2C_CLIENT_END;
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_addr);
+
+/* Return a list of I2C tuner addresses to probe. Use only if the tuner
+ addresses are unknown. */
+const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
+{
+ static const unsigned short radio_addrs[] = {
+#if defined(CONFIG_MEDIA_TUNER_TEA5761) || defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE)
+ 0x10,
+#endif
+ 0x60,
+ I2C_CLIENT_END
+ };
+ static const unsigned short demod_addrs[] = {
+ 0x42, 0x43, 0x4a, 0x4b,
+ I2C_CLIENT_END
+ };
+ static const unsigned short tv_addrs[] = {
+ 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ I2C_CLIENT_END
+ };
+
+ switch (type) {
+ case ADDRS_RADIO:
+ return radio_addrs;
+ case ADDRS_DEMOD:
+ return demod_addrs;
+ case ADDRS_TV:
+ return tv_addrs;
+ case ADDRS_TV_WITH_DEMOD:
+ return tv_addrs + 4;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
+
#endif
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 110376be5d2b..0056b115b42e 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -1047,7 +1047,6 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
case VIDIOC_DBG_S_REGISTER:
case VIDIOC_DBG_G_REGISTER:
case VIDIOC_DBG_G_CHIP_IDENT:
- case VIDIOC_G_CHIP_IDENT_OLD:
case VIDIOC_S_HW_FREQ_SEEK:
ret = do_video_ioctl(file, cmd, arg);
break;
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 13f87c22e78d..91228b3df07d 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -198,6 +198,23 @@ static long v4l2_unlocked_ioctl(struct file *filp,
return vdev->fops->unlocked_ioctl(filp, cmd, arg);
}
+#ifdef CONFIG_MMU
+#define v4l2_get_unmapped_area NULL
+#else
+static unsigned long v4l2_get_unmapped_area(struct file *filp,
+ unsigned long addr, unsigned long len, unsigned long pgoff,
+ unsigned long flags)
+{
+ struct video_device *vdev = video_devdata(filp);
+
+ if (!vdev->fops->get_unmapped_area)
+ return -ENOSYS;
+ if (video_is_unregistered(vdev))
+ return -ENODEV;
+ return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags);
+}
+#endif
+
static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
{
struct video_device *vdev = video_devdata(filp);
@@ -250,6 +267,7 @@ static const struct file_operations v4l2_unlocked_fops = {
.read = v4l2_read,
.write = v4l2_write,
.open = v4l2_open,
+ .get_unmapped_area = v4l2_get_unmapped_area,
.mmap = v4l2_mmap,
.unlocked_ioctl = v4l2_unlocked_ioctl,
#ifdef CONFIG_COMPAT
@@ -265,6 +283,7 @@ static const struct file_operations v4l2_fops = {
.read = v4l2_read,
.write = v4l2_write,
.open = v4l2_open,
+ .get_unmapped_area = v4l2_get_unmapped_area,
.mmap = v4l2_mmap,
.ioctl = v4l2_ioctl,
#ifdef CONFIG_COMPAT
@@ -288,37 +307,38 @@ static const struct file_operations v4l2_fops = {
*/
static int get_index(struct video_device *vdev, int num)
{
- u32 used = 0;
- const int max_index = sizeof(used) * 8 - 1;
+ /* This can be static since this function is called with the global
+ videodev_lock held. */
+ static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES);
int i;
- /* Currently a single v4l driver instance cannot create more than
- 32 devices.
- Increase to u64 or an array of u32 if more are needed. */
- if (num > max_index) {
+ if (num >= VIDEO_NUM_DEVICES) {
printk(KERN_ERR "videodev: %s num is too large\n", __func__);
return -EINVAL;
}
- /* Some drivers do not set the parent. In that case always return 0. */
+ /* Some drivers do not set the parent. In that case always return
+ num or 0. */
if (vdev->parent == NULL)
- return 0;
+ return num >= 0 ? num : 0;
+
+ bitmap_zero(used, VIDEO_NUM_DEVICES);
for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
if (video_device[i] != NULL &&
video_device[i]->parent == vdev->parent) {
- used |= 1 << video_device[i]->index;
+ set_bit(video_device[i]->index, used);
}
}
if (num >= 0) {
- if (used & (1 << num))
+ if (test_bit(num, used))
return -ENFILE;
return num;
}
- i = ffz(used);
- return i > max_index ? -ENFILE : i;
+ i = find_first_zero_bit(used, VIDEO_NUM_DEVICES);
+ return i == VIDEO_NUM_DEVICES ? -ENFILE : i;
}
int video_register_device(struct video_device *vdev, int type, int nr)
@@ -365,12 +385,11 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
/* A minor value of -1 marks this video device as never
having been registered */
- if (vdev)
- vdev->minor = -1;
+ vdev->minor = -1;
/* the release callback MUST be present */
- WARN_ON(!vdev || !vdev->release);
- if (!vdev || !vdev->release)
+ WARN_ON(!vdev->release);
+ if (!vdev->release)
return -EINVAL;
/* Part 1: check device type */
@@ -395,7 +414,7 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
vdev->vfl_type = type;
vdev->cdev = NULL;
- if (vdev->v4l2_dev)
+ if (vdev->v4l2_dev && vdev->v4l2_dev->dev)
vdev->parent = vdev->v4l2_dev->dev;
/* Part 2: find a free minor, kernel number and device index. */
@@ -582,6 +601,7 @@ module_exit(videodev_exit)
MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR);
/*
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index cf9d4c7f571a..94aa485ade52 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -26,48 +26,66 @@
int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
{
- if (dev == NULL || v4l2_dev == NULL)
+ if (v4l2_dev == NULL)
return -EINVAL;
- /* Warn if we apparently re-register a device */
- WARN_ON(dev_get_drvdata(dev) != NULL);
+
INIT_LIST_HEAD(&v4l2_dev->subdevs);
spin_lock_init(&v4l2_dev->lock);
v4l2_dev->dev = dev;
- snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
- dev->driver->name, dev->bus_id);
+ if (dev == NULL) {
+ /* If dev == NULL, then name must be filled in by the caller */
+ WARN_ON(!v4l2_dev->name[0]);
+ return 0;
+ }
+
+ /* Set name to driver name + device name if it is empty. */
+ if (!v4l2_dev->name[0])
+ snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
+ dev->driver->name, dev_name(dev));
+ if (dev_get_drvdata(dev))
+ v4l2_warn(v4l2_dev, "Non-NULL drvdata on register\n");
dev_set_drvdata(dev, v4l2_dev);
return 0;
}
EXPORT_SYMBOL_GPL(v4l2_device_register);
+void v4l2_device_disconnect(struct v4l2_device *v4l2_dev)
+{
+ if (v4l2_dev->dev) {
+ dev_set_drvdata(v4l2_dev->dev, NULL);
+ v4l2_dev->dev = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(v4l2_device_disconnect);
+
void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
{
struct v4l2_subdev *sd, *next;
- if (v4l2_dev == NULL || v4l2_dev->dev == NULL)
+ if (v4l2_dev == NULL)
return;
- dev_set_drvdata(v4l2_dev->dev, NULL);
- /* unregister subdevs */
+ v4l2_device_disconnect(v4l2_dev);
+
+ /* Unregister subdevs */
list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list)
v4l2_device_unregister_subdev(sd);
-
- v4l2_dev->dev = NULL;
}
EXPORT_SYMBOL_GPL(v4l2_device_unregister);
-int v4l2_device_register_subdev(struct v4l2_device *dev, struct v4l2_subdev *sd)
+int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
+ struct v4l2_subdev *sd)
{
/* Check for valid input */
- if (dev == NULL || sd == NULL || !sd->name[0])
+ if (v4l2_dev == NULL || sd == NULL || !sd->name[0])
return -EINVAL;
/* Warn if we apparently re-register a subdev */
- WARN_ON(sd->dev != NULL);
+ WARN_ON(sd->v4l2_dev != NULL);
if (!try_module_get(sd->owner))
return -ENODEV;
- sd->dev = dev;
- spin_lock(&dev->lock);
- list_add_tail(&sd->list, &dev->subdevs);
- spin_unlock(&dev->lock);
+ sd->v4l2_dev = v4l2_dev;
+ spin_lock(&v4l2_dev->lock);
+ list_add_tail(&sd->list, &v4l2_dev->subdevs);
+ spin_unlock(&v4l2_dev->lock);
return 0;
}
EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
@@ -75,12 +93,12 @@ EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
{
/* return if it isn't registered */
- if (sd == NULL || sd->dev == NULL)
+ if (sd == NULL || sd->v4l2_dev == NULL)
return;
- spin_lock(&sd->dev->lock);
+ spin_lock(&sd->v4l2_dev->lock);
list_del(&sd->list);
- spin_unlock(&sd->dev->lock);
- sd->dev = NULL;
+ spin_unlock(&sd->v4l2_dev->lock);
+ sd->v4l2_dev = NULL;
module_put(sd->owner);
}
EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 52d687b165e0..f41c6f506f42 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#define __OLD_VIDIOC_ /* To allow fixing old calls */
+#include <linux/videodev.h>
#include <linux/videodev2.h>
#ifdef CONFIG_VIDEO_V4L1
@@ -24,7 +25,7 @@
#endif
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-#include <linux/video_decoder.h>
+#include <media/v4l2-chip-ident.h>
#define dbgarg(cmd, fmt, arg...) \
do { \
@@ -100,25 +101,27 @@ const char *v4l2_norm_to_name(v4l2_std_id id)
}
EXPORT_SYMBOL(v4l2_norm_to_name);
+/* Returns frame period for the given standard */
+void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
+{
+ if (id & V4L2_STD_525_60) {
+ frameperiod->numerator = 1001;
+ frameperiod->denominator = 30000;
+ } else {
+ frameperiod->numerator = 1;
+ frameperiod->denominator = 25;
+ }
+}
+EXPORT_SYMBOL(v4l2_video_std_frame_period);
+
/* Fill in the fields of a v4l2_standard structure according to the
'id' and 'transmission' parameters. Returns negative on error. */
int v4l2_video_std_construct(struct v4l2_standard *vs,
int id, const char *name)
{
- u32 index = vs->index;
-
- memset(vs, 0, sizeof(struct v4l2_standard));
- vs->index = index;
- vs->id = id;
- if (id & V4L2_STD_525_60) {
- vs->frameperiod.numerator = 1001;
- vs->frameperiod.denominator = 30000;
- vs->framelines = 525;
- } else {
- vs->frameperiod.numerator = 1;
- vs->frameperiod.denominator = 25;
- vs->framelines = 625;
- }
+ vs->id = id;
+ v4l2_video_std_frame_period(id, &vs->frameperiod);
+ vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
strlcpy(vs->name, name, sizeof(vs->name));
return 0;
}
@@ -273,19 +276,6 @@ static const char *v4l2_ioctls[] = {
#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
static const char *v4l2_int_ioctls[] = {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
- [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
- [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
- [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT",
- [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT",
- [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT",
- [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE",
- [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO",
- [_IOC_NR(DECODER_INIT)] = "DECODER_INIT",
- [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS",
- [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP",
-#endif
[_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
[_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
@@ -654,8 +644,6 @@ static long __video_do_ioctl(struct file *file,
if (cmd == VIDIOCGMBUF) {
struct video_mbuf *p = arg;
- memset(p, 0, sizeof(*p));
-
if (!ops->vidiocgmbuf)
return ret;
ret = ops->vidiocgmbuf(file, fh, p);
@@ -682,7 +670,6 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_QUERYCAP:
{
struct v4l2_capability *cap = (struct v4l2_capability *)arg;
- memset(cap, 0, sizeof(*cap));
if (!ops->vidioc_querycap)
break;
@@ -725,16 +712,8 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_ENUM_FMT:
{
struct v4l2_fmtdesc *f = arg;
- enum v4l2_buf_type type;
- unsigned int index;
-
- index = f->index;
- type = f->type;
- memset(f, 0, sizeof(*f));
- f->index = index;
- f->type = type;
- switch (type) {
+ switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
if (ops->vidioc_enum_fmt_vid_cap)
ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
@@ -771,8 +750,6 @@ static long __video_do_ioctl(struct file *file,
{
struct v4l2_format *f = (struct v4l2_format *)arg;
- memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data));
-
/* FIXME: Should be one dump per type */
dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
@@ -1088,7 +1065,6 @@ static long __video_do_ioctl(struct file *file,
return -EINVAL;
v4l2_video_std_construct(p, curr_id, descr);
- p->index = index;
dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
"framelines=%d\n", p->index,
@@ -1153,12 +1129,9 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_ENUMINPUT:
{
struct v4l2_input *p = arg;
- int i = p->index;
if (!ops->vidioc_enum_input)
break;
- memset(p, 0, sizeof(*p));
- p->index = i;
ret = ops->vidioc_enum_input(file, fh, p);
if (!ret)
@@ -1197,12 +1170,9 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_ENUMOUTPUT:
{
struct v4l2_output *p = arg;
- int i = p->index;
if (!ops->vidioc_enum_output)
break;
- memset(p, 0, sizeof(*p));
- p->index = i;
ret = ops->vidioc_enum_output(file, fh, p);
if (!ret)
@@ -1378,13 +1348,10 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_G_AUDIO:
{
struct v4l2_audio *p = arg;
- __u32 index = p->index;
if (!ops->vidioc_g_audio)
break;
- memset(p, 0, sizeof(*p));
- p->index = index;
ret = ops->vidioc_g_audio(file, fh, p);
if (!ret)
dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
@@ -1426,7 +1393,7 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_g_audout)
break;
- dbgarg(cmd, "Enum for index=%d\n", p->index);
+
ret = ops->vidioc_g_audout(file, fh, p);
if (!ret)
dbgarg2("index=%d, name=%s, capability=%d, "
@@ -1479,15 +1446,10 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_G_CROP:
{
struct v4l2_crop *p = arg;
- __u32 type;
if (!ops->vidioc_g_crop)
break;
- type = p->type;
- memset(p, 0, sizeof(*p));
- p->type = type;
-
dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
ret = ops->vidioc_g_crop(file, fh, p);
if (!ret)
@@ -1508,16 +1470,11 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_CROPCAP:
{
struct v4l2_cropcap *p = arg;
- __u32 type;
/*FIXME: Should also show v4l2_fract pixelaspect */
if (!ops->vidioc_cropcap)
break;
- type = p->type;
- memset(p, 0, sizeof(*p));
- p->type = type;
-
dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
ret = ops->vidioc_cropcap(file, fh, p);
if (!ret) {
@@ -1533,8 +1490,6 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_g_jpegcomp)
break;
- memset(p, 0, sizeof(*p));
-
ret = ops->vidioc_g_jpegcomp(file, fh, p);
if (!ret)
dbgarg(cmd, "quality=%d, APPn=%d, "
@@ -1575,7 +1530,6 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_encoder_cmd)
break;
- memset(&p->raw, 0, sizeof(p->raw));
ret = ops->vidioc_encoder_cmd(file, fh, p);
if (!ret)
dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
@@ -1587,7 +1541,6 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_try_encoder_cmd)
break;
- memset(&p->raw, 0, sizeof(p->raw));
ret = ops->vidioc_try_encoder_cmd(file, fh, p);
if (!ret)
dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
@@ -1596,23 +1549,18 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_G_PARM:
{
struct v4l2_streamparm *p = arg;
- __u32 type = p->type;
-
- memset(p, 0, sizeof(*p));
- p->type = type;
if (ops->vidioc_g_parm) {
+ ret = check_fmt(ops, p->type);
+ if (ret)
+ break;
ret = ops->vidioc_g_parm(file, fh, p);
} else {
- struct v4l2_standard s;
-
if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- v4l2_video_std_construct(&s, vfd->current_norm,
- v4l2_norm_to_name(vfd->current_norm));
-
- p->parm.capture.timeperframe = s.frameperiod;
+ v4l2_video_std_frame_period(vfd->current_norm,
+ &p->parm.capture.timeperframe);
ret = 0;
}
@@ -1625,6 +1573,10 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_s_parm)
break;
+ ret = check_fmt(ops, p->type);
+ if (ret)
+ break;
+
dbgarg(cmd, "type=%d\n", p->type);
ret = ops->vidioc_s_parm(file, fh, p);
break;
@@ -1632,14 +1584,10 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_G_TUNER:
{
struct v4l2_tuner *p = arg;
- __u32 index = p->index;
if (!ops->vidioc_g_tuner)
break;
- memset(p, 0, sizeof(*p));
- p->index = index;
-
ret = ops->vidioc_g_tuner(file, fh, p);
if (!ret)
dbgarg(cmd, "index=%d, name=%s, type=%d, "
@@ -1676,8 +1624,6 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_g_frequency)
break;
- memset(p->reserved, 0, sizeof(p->reserved));
-
ret = ops->vidioc_g_frequency(file, fh, p);
if (!ret)
dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
@@ -1698,12 +1644,13 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_G_SLICED_VBI_CAP:
{
struct v4l2_sliced_vbi_cap *p = arg;
- __u32 type = p->type;
if (!ops->vidioc_g_sliced_vbi_cap)
break;
- memset(p, 0, sizeof(*p));
- p->type = type;
+
+ /* Clear up to type, everything after type is zerod already */
+ memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
+
dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p);
if (!ret)
@@ -1745,16 +1692,13 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_g_chip_ident)
break;
+ p->ident = V4L2_IDENT_NONE;
+ p->revision = 0;
ret = ops->vidioc_g_chip_ident(file, fh, p);
if (!ret)
dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
break;
}
- case VIDIOC_G_CHIP_IDENT_OLD:
- printk(KERN_ERR "VIDIOC_G_CHIP_IDENT has been deprecated and will disappear in 2.6.30.\n");
- printk(KERN_ERR "It is a debugging ioctl and must not be used in applications!\n");
- return -EINVAL;
-
case VIDIOC_S_HW_FREQ_SEEK:
{
struct v4l2_hw_freq_seek *p = arg;
@@ -1774,8 +1718,6 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_enum_framesizes)
break;
- memset(p, 0, sizeof(*p));
-
ret = ops->vidioc_enum_framesizes(file, fh, p);
dbgarg(cmd,
"index=%d, pixelformat=%d, type=%d ",
@@ -1807,8 +1749,6 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_enum_frameintervals)
break;
- memset(p, 0, sizeof(*p));
-
ret = ops->vidioc_enum_frameintervals(file, fh, p);
dbgarg(cmd,
"index=%d, pixelformat=%d, width=%d, height=%d, type=%d ",
@@ -1857,6 +1797,45 @@ static long __video_do_ioctl(struct file *file,
return ret;
}
+/* In some cases, only a few fields are used as input, i.e. when the app sets
+ * "index" and then the driver fills in the rest of the structure for the thing
+ * with that index. We only need to copy up the first non-input field. */
+static unsigned long cmd_input_size(unsigned int cmd)
+{
+ /* Size of structure up to and including 'field' */
+#define CMDINSIZE(cmd, type, field) \
+ case VIDIOC_##cmd: \
+ return offsetof(struct v4l2_##type, field) + \
+ sizeof(((struct v4l2_##type *)0)->field);
+
+ switch (cmd) {
+ CMDINSIZE(ENUM_FMT, fmtdesc, type);
+ CMDINSIZE(G_FMT, format, type);
+ CMDINSIZE(QUERYBUF, buffer, type);
+ CMDINSIZE(G_PARM, streamparm, type);
+ CMDINSIZE(ENUMSTD, standard, index);
+ CMDINSIZE(ENUMINPUT, input, index);
+ CMDINSIZE(G_CTRL, control, id);
+ CMDINSIZE(G_TUNER, tuner, index);
+ CMDINSIZE(QUERYCTRL, queryctrl, id);
+ CMDINSIZE(QUERYMENU, querymenu, index);
+ CMDINSIZE(ENUMOUTPUT, output, index);
+ CMDINSIZE(G_MODULATOR, modulator, index);
+ CMDINSIZE(G_FREQUENCY, frequency, tuner);
+ CMDINSIZE(CROPCAP, cropcap, type);
+ CMDINSIZE(G_CROP, crop, type);
+ CMDINSIZE(ENUMAUDIO, audio, index);
+ CMDINSIZE(ENUMAUDOUT, audioout, index);
+ CMDINSIZE(ENCODER_CMD, encoder_cmd, flags);
+ CMDINSIZE(TRY_ENCODER_CMD, encoder_cmd, flags);
+ CMDINSIZE(G_SLICED_VBI_CAP, sliced_vbi_cap, type);
+ CMDINSIZE(ENUM_FRAMESIZES, frmsizeenum, pixel_format);
+ CMDINSIZE(ENUM_FRAMEINTERVALS, frmivalenum, height);
+ default:
+ return _IOC_SIZE(cmd);
+ }
+}
+
long video_ioctl2(struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -1875,13 +1854,7 @@ long video_ioctl2(struct file *file,
cmd == VIDIOC_TRY_EXT_CTRLS);
/* Copy arguments into temp kernel buffer */
- switch (_IOC_DIR(cmd)) {
- case _IOC_NONE:
- parg = NULL;
- break;
- case _IOC_READ:
- case _IOC_WRITE:
- case (_IOC_WRITE | _IOC_READ):
+ if (_IOC_DIR(cmd) != _IOC_NONE) {
if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
parg = sbuf;
} else {
@@ -1893,10 +1866,19 @@ long video_ioctl2(struct file *file,
}
err = -EFAULT;
- if (_IOC_DIR(cmd) & _IOC_WRITE)
- if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
+ if (_IOC_DIR(cmd) & _IOC_WRITE) {
+ unsigned long n = cmd_input_size(cmd);
+
+ if (copy_from_user(parg, (void __user *)arg, n))
goto out;
- break;
+
+ /* zero out anything we don't copy from userspace */
+ if (n < _IOC_SIZE(cmd))
+ memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
+ } else {
+ /* read-only ioctl */
+ memset(parg, 0, _IOC_SIZE(cmd));
+ }
}
if (is_ext_ctrl) {
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index 21208805ea9b..dc881671d536 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/video/v4l2-subdev.c
@@ -33,6 +33,12 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg)
return v4l2_subdev_call(sd, core, g_ctrl, arg);
case VIDIOC_S_CTRL:
return v4l2_subdev_call(sd, core, s_ctrl, arg);
+ case VIDIOC_G_EXT_CTRLS:
+ return v4l2_subdev_call(sd, core, g_ext_ctrls, arg);
+ case VIDIOC_S_EXT_CTRLS:
+ return v4l2_subdev_call(sd, core, s_ext_ctrls, arg);
+ case VIDIOC_TRY_EXT_CTRLS:
+ return v4l2_subdev_call(sd, core, try_ext_ctrls, arg);
case VIDIOC_QUERYMENU:
return v4l2_subdev_call(sd, core, querymenu, arg);
case VIDIOC_LOG_STATUS:
@@ -92,16 +98,28 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg)
return v4l2_subdev_call(sd, video, g_vbi_data, arg);
case VIDIOC_G_SLICED_VBI_CAP:
return v4l2_subdev_call(sd, video, g_sliced_vbi_cap, arg);
+ case VIDIOC_ENUM_FMT:
+ return v4l2_subdev_call(sd, video, enum_fmt, arg);
+ case VIDIOC_TRY_FMT:
+ return v4l2_subdev_call(sd, video, try_fmt, arg);
case VIDIOC_S_FMT:
return v4l2_subdev_call(sd, video, s_fmt, arg);
case VIDIOC_G_FMT:
return v4l2_subdev_call(sd, video, g_fmt, arg);
case VIDIOC_INT_S_STD_OUTPUT:
return v4l2_subdev_call(sd, video, s_std_output, *(v4l2_std_id *)arg);
+ case VIDIOC_QUERYSTD:
+ return v4l2_subdev_call(sd, video, querystd, arg);
+ case VIDIOC_INT_G_INPUT_STATUS:
+ return v4l2_subdev_call(sd, video, g_input_status, arg);
case VIDIOC_STREAMON:
return v4l2_subdev_call(sd, video, s_stream, 1);
case VIDIOC_STREAMOFF:
return v4l2_subdev_call(sd, video, s_stream, 0);
+ case VIDIOC_S_PARM:
+ return v4l2_subdev_call(sd, video, s_parm, arg);
+ case VIDIOC_G_PARM:
+ return v4l2_subdev_call(sd, video, g_parm, arg);
default:
return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index 31944b11e6ea..6109fb5f34e2 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -400,7 +400,7 @@ void videobuf_dma_contig_free(struct videobuf_queue *q,
So, it should free memory only if the memory were allocated for
read() operation.
*/
- if ((buf->memory != V4L2_MEMORY_USERPTR) || !buf->baddr)
+ if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
return;
if (!mem)
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index be65a2fb3976..30ae30f99ccc 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -425,7 +425,7 @@ void videobuf_vmalloc_free (struct videobuf_buffer *buf)
So, it should free memory only if the memory were allocated for
read() operation.
*/
- if ((buf->memory != V4L2_MEMORY_USERPTR) || (buf->baddr == 0))
+ if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
return;
if (!mem)
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 88bf845a3d56..8da4dd1e0e94 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -8,6 +8,12 @@
*
* Based on the previous version of the driver for 2.4 kernels by:
* Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
+ *
+ * v4l2_device/v4l2_subdev conversion by:
+ * Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * Note: this conversion is untested! Please contact the linux-media
+ * mailinglist if you can test this, together with the test results.
*/
/*
@@ -33,12 +39,10 @@
#include <linux/kmod.h>
#include <linux/i2c.h>
-#include <linux/i2c-algo-sgi.h>
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/video_decoder.h>
#include <linux/mutex.h>
#include <asm/paccess.h>
@@ -139,13 +143,23 @@ MODULE_LICENSE("GPL");
#define VINO_DATA_NORM_PAL 1
#define VINO_DATA_NORM_SECAM 2
#define VINO_DATA_NORM_D1 3
-/* The following are special entries that can be used to
- * autodetect the norm. */
-#define VINO_DATA_NORM_AUTO 0xfe
-#define VINO_DATA_NORM_AUTO_EXT 0xff
#define VINO_DATA_NORM_COUNT 4
+/* I2C controller flags */
+#define SGI_I2C_FORCE_IDLE (0 << 0)
+#define SGI_I2C_NOT_IDLE (1 << 0)
+#define SGI_I2C_WRITE (0 << 1)
+#define SGI_I2C_READ (1 << 1)
+#define SGI_I2C_RELEASE_BUS (0 << 2)
+#define SGI_I2C_HOLD_BUS (1 << 2)
+#define SGI_I2C_XFER_DONE (0 << 4)
+#define SGI_I2C_XFER_BUSY (1 << 4)
+#define SGI_I2C_ACK (0 << 5)
+#define SGI_I2C_NACK (1 << 5)
+#define SGI_I2C_BUS_OK (0 << 7)
+#define SGI_I2C_BUS_ERR (1 << 7)
+
/* Internal data structure definitions */
struct vino_input {
@@ -289,22 +303,20 @@ struct vino_channel_settings {
struct vino_interrupt_data int_data;
/* V4L support */
- struct video_device *v4l_device;
-};
-
-struct vino_client {
- /* the channel which owns this client:
- * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
- unsigned int owner;
- struct i2c_client *driver;
+ struct video_device *vdev;
};
struct vino_settings {
+ struct v4l2_device v4l2_dev;
struct vino_channel_settings a;
struct vino_channel_settings b;
- struct vino_client decoder;
- struct vino_client camera;
+ /* the channel which owns this client:
+ * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
+ unsigned int decoder_owner;
+ struct v4l2_subdev *decoder;
+ unsigned int camera_owner;
+ struct v4l2_subdev *camera;
/* a lock for vino register access */
spinlock_t vino_lock;
@@ -344,11 +356,16 @@ static struct sgi_vino *vino;
static struct vino_settings *vino_drvdata;
+#define camera_call(o, f, args...) \
+ v4l2_subdev_call(vino_drvdata->camera, o, f, ##args)
+#define decoder_call(o, f, args...) \
+ v4l2_subdev_call(vino_drvdata->decoder, o, f, ##args)
+
static const char *vino_driver_name = "vino";
static const char *vino_driver_description = "SGI VINO";
static const char *vino_bus_name = "GIO64 bus";
-static const char *vino_v4l_device_name_a = "SGI VINO Channel A";
-static const char *vino_v4l_device_name_b = "SGI VINO Channel B";
+static const char *vino_vdev_name_a = "SGI VINO Channel A";
+static const char *vino_vdev_name_b = "SGI VINO Channel B";
static void vino_capture_tasklet(unsigned long channel);
@@ -360,11 +377,11 @@ static const struct vino_input vino_inputs[] = {
.name = "Composite",
.std = V4L2_STD_NTSC | V4L2_STD_PAL
| V4L2_STD_SECAM,
- },{
+ }, {
.name = "S-Video",
.std = V4L2_STD_NTSC | V4L2_STD_PAL
| V4L2_STD_SECAM,
- },{
+ }, {
.name = "D1/IndyCam",
.std = V4L2_STD_NTSC,
}
@@ -376,17 +393,17 @@ static const struct vino_data_format vino_data_formats[] = {
.bpp = 1,
.pixelformat = V4L2_PIX_FMT_GREY,
.colorspace = V4L2_COLORSPACE_SMPTE170M,
- },{
+ }, {
.description = "8-bit dithered RGB 3-3-2",
.bpp = 1,
.pixelformat = V4L2_PIX_FMT_RGB332,
.colorspace = V4L2_COLORSPACE_SRGB,
- },{
+ }, {
.description = "32-bit RGB",
.bpp = 4,
.pixelformat = V4L2_PIX_FMT_RGB32,
.colorspace = V4L2_COLORSPACE_SRGB,
- },{
+ }, {
.description = "YUV 4:2:2",
.bpp = 2,
.pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped?
@@ -417,7 +434,7 @@ static const struct vino_data_norm vino_data_norms[] = {
+ VINO_NTSC_HEIGHT / 2 - 1,
.right = VINO_NTSC_WIDTH,
},
- },{
+ }, {
.description = "PAL",
.std = V4L2_STD_PAL,
.fps_min = 5,
@@ -439,7 +456,7 @@ static const struct vino_data_norm vino_data_norms[] = {
+ VINO_PAL_HEIGHT / 2 - 1,
.right = VINO_PAL_WIDTH,
},
- },{
+ }, {
.description = "SECAM",
.std = V4L2_STD_SECAM,
.fps_min = 5,
@@ -461,7 +478,7 @@ static const struct vino_data_norm vino_data_norms[] = {
+ VINO_PAL_HEIGHT / 2 - 1,
.right = VINO_PAL_WIDTH,
},
- },{
+ }, {
.description = "NTSC/D1",
.std = V4L2_STD_NTSC,
.fps_min = 6,
@@ -497,9 +514,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = 1,
.step = 1,
.default_value = INDYCAM_AGC_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_AGC, 0 },
- },{
+ }, {
.id = V4L2_CID_AUTO_WHITE_BALANCE,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Automatic White Balance",
@@ -507,9 +522,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = 1,
.step = 1,
.default_value = INDYCAM_AWB_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_AWB, 0 },
- },{
+ }, {
.id = V4L2_CID_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Gain",
@@ -517,29 +530,23 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = INDYCAM_GAIN_MAX,
.step = 1,
.default_value = INDYCAM_GAIN_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_GAIN, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE,
+ }, {
+ .id = INDYCAM_CONTROL_RED_SATURATION,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Red Saturation",
.minimum = INDYCAM_RED_SATURATION_MIN,
.maximum = INDYCAM_RED_SATURATION_MAX,
.step = 1,
.default_value = INDYCAM_RED_SATURATION_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_RED_SATURATION, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 1,
+ }, {
+ .id = INDYCAM_CONTROL_BLUE_SATURATION,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Blue Saturation",
.minimum = INDYCAM_BLUE_SATURATION_MIN,
.maximum = INDYCAM_BLUE_SATURATION_MAX,
.step = 1,
.default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_BLUE_SATURATION, 0 },
- },{
+ }, {
.id = V4L2_CID_RED_BALANCE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Red Balance",
@@ -547,9 +554,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = INDYCAM_RED_BALANCE_MAX,
.step = 1,
.default_value = INDYCAM_RED_BALANCE_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_RED_BALANCE, 0 },
- },{
+ }, {
.id = V4L2_CID_BLUE_BALANCE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Blue Balance",
@@ -557,9 +562,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = INDYCAM_BLUE_BALANCE_MAX,
.step = 1,
.default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_BLUE_BALANCE, 0 },
- },{
+ }, {
.id = V4L2_CID_EXPOSURE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Shutter Control",
@@ -567,9 +570,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = INDYCAM_SHUTTER_MAX,
.step = 1,
.default_value = INDYCAM_SHUTTER_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_SHUTTER, 0 },
- },{
+ }, {
.id = V4L2_CID_GAMMA,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Gamma",
@@ -577,8 +578,6 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = INDYCAM_GAMMA_MAX,
.step = 1,
.default_value = INDYCAM_GAMMA_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_GAMMA, 0 },
}
};
@@ -593,209 +592,73 @@ struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
.maximum = SAA7191_HUE_MAX,
.step = 1,
.default_value = SAA7191_HUE_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_HUE, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE,
+ }, {
+ .id = SAA7191_CONTROL_BANDPASS,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Luminance Bandpass",
.minimum = SAA7191_BANDPASS_MIN,
.maximum = SAA7191_BANDPASS_MAX,
.step = 1,
.default_value = SAA7191_BANDPASS_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_BANDPASS, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 1,
+ }, {
+ .id = SAA7191_CONTROL_BANDPASS_WEIGHT,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Luminance Bandpass Weight",
.minimum = SAA7191_BANDPASS_WEIGHT_MIN,
.maximum = SAA7191_BANDPASS_WEIGHT_MAX,
.step = 1,
.default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_BANDPASS_WEIGHT, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 2,
+ }, {
+ .id = SAA7191_CONTROL_CORING,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "HF Luminance Coring",
.minimum = SAA7191_CORING_MIN,
.maximum = SAA7191_CORING_MAX,
.step = 1,
.default_value = SAA7191_CORING_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_CORING, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 3,
+ }, {
+ .id = SAA7191_CONTROL_FORCE_COLOUR,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Force Colour",
.minimum = SAA7191_FORCE_COLOUR_MIN,
.maximum = SAA7191_FORCE_COLOUR_MAX,
.step = 1,
.default_value = SAA7191_FORCE_COLOUR_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_FORCE_COLOUR, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 4,
+ }, {
+ .id = SAA7191_CONTROL_CHROMA_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Chrominance Gain Control",
.minimum = SAA7191_CHROMA_GAIN_MIN,
.maximum = SAA7191_CHROMA_GAIN_MAX,
.step = 1,
.default_value = SAA7191_CHROMA_GAIN_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_CHROMA_GAIN, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 5,
+ }, {
+ .id = SAA7191_CONTROL_VTRC,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "VTR Time Constant",
.minimum = SAA7191_VTRC_MIN,
.maximum = SAA7191_VTRC_MAX,
.step = 1,
.default_value = SAA7191_VTRC_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_VTRC, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 6,
+ }, {
+ .id = SAA7191_CONTROL_LUMA_DELAY,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Luminance Delay Compensation",
.minimum = SAA7191_LUMA_DELAY_MIN,
.maximum = SAA7191_LUMA_DELAY_MAX,
.step = 1,
.default_value = SAA7191_LUMA_DELAY_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_LUMA_DELAY, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 7,
+ }, {
+ .id = SAA7191_CONTROL_VNR,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Vertical Noise Reduction",
.minimum = SAA7191_VNR_MIN,
.maximum = SAA7191_VNR_MAX,
.step = 1,
.default_value = SAA7191_VNR_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_VNR, 0 },
}
};
-/* VINO I2C bus functions */
-
-unsigned i2c_vino_getctrl(void *data)
-{
- return vino->i2c_control;
-}
-
-void i2c_vino_setctrl(void *data, unsigned val)
-{
- vino->i2c_control = val;
-}
-
-unsigned i2c_vino_rdata(void *data)
-{
- return vino->i2c_data;
-}
-
-void i2c_vino_wdata(void *data, unsigned val)
-{
- vino->i2c_data = val;
-}
-
-static struct i2c_algo_sgi_data i2c_sgi_vino_data =
-{
- .getctrl = &i2c_vino_getctrl,
- .setctrl = &i2c_vino_setctrl,
- .rdata = &i2c_vino_rdata,
- .wdata = &i2c_vino_wdata,
- .xfer_timeout = 200,
- .ack_timeout = 1000,
-};
-
-/*
- * There are two possible clients on VINO I2C bus, so we limit usage only
- * to them.
- */
-static int i2c_vino_client_reg(struct i2c_client *client)
-{
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- switch (client->driver->id) {
- case I2C_DRIVERID_SAA7191:
- if (vino_drvdata->decoder.driver)
- ret = -EBUSY;
- else
- vino_drvdata->decoder.driver = client;
- break;
- case I2C_DRIVERID_INDYCAM:
- if (vino_drvdata->camera.driver)
- ret = -EBUSY;
- else
- vino_drvdata->camera.driver = client;
- break;
- default:
- ret = -ENODEV;
- }
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return ret;
-}
-
-static int i2c_vino_client_unreg(struct i2c_client *client)
-{
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- if (client == vino_drvdata->decoder.driver) {
- if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL)
- ret = -EBUSY;
- else
- vino_drvdata->decoder.driver = NULL;
- } else if (client == vino_drvdata->camera.driver) {
- if (vino_drvdata->camera.owner != VINO_NO_CHANNEL)
- ret = -EBUSY;
- else
- vino_drvdata->camera.driver = NULL;
- }
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return ret;
-}
-
-static struct i2c_adapter vino_i2c_adapter =
-{
- .name = "VINO I2C bus",
- .id = I2C_HW_SGI_VINO,
- .algo_data = &i2c_sgi_vino_data,
- .client_register = &i2c_vino_client_reg,
- .client_unregister = &i2c_vino_client_unreg,
-};
-
-static int vino_i2c_add_bus(void)
-{
- return i2c_sgi_add_bus(&vino_i2c_adapter);
-}
-
-static int vino_i2c_del_bus(void)
-{
- return i2c_del_adapter(&vino_i2c_adapter);
-}
-
-static int i2c_camera_command(unsigned int cmd, void *arg)
-{
- return vino_drvdata->camera.driver->
- driver->command(vino_drvdata->camera.driver,
- cmd, arg);
-}
-
-static int i2c_decoder_command(unsigned int cmd, void *arg)
-{
- return vino_drvdata->decoder.driver->
- driver->command(vino_drvdata->decoder.driver,
- cmd, arg);
-}
-
/* VINO framebuffer/DMA descriptor management */
static void vino_free_buffer_with_count(struct vino_framebuffer *fb,
@@ -1741,6 +1604,184 @@ static inline void vino_set_default_framerate(struct
vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max);
}
+/* VINO I2C bus functions */
+
+struct i2c_algo_sgi_data {
+ void *data; /* private data for lowlevel routines */
+ unsigned (*getctrl)(void *data);
+ void (*setctrl)(void *data, unsigned val);
+ unsigned (*rdata)(void *data);
+ void (*wdata)(void *data, unsigned val);
+
+ int xfer_timeout;
+ int ack_timeout;
+};
+
+static int wait_xfer_done(struct i2c_algo_sgi_data *adap)
+{
+ int i;
+
+ for (i = 0; i < adap->xfer_timeout; i++) {
+ if ((adap->getctrl(adap->data) & SGI_I2C_XFER_BUSY) == 0)
+ return 0;
+ udelay(1);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int wait_ack(struct i2c_algo_sgi_data *adap)
+{
+ int i;
+
+ if (wait_xfer_done(adap))
+ return -ETIMEDOUT;
+ for (i = 0; i < adap->ack_timeout; i++) {
+ if ((adap->getctrl(adap->data) & SGI_I2C_NACK) == 0)
+ return 0;
+ udelay(1);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int force_idle(struct i2c_algo_sgi_data *adap)
+{
+ int i;
+
+ adap->setctrl(adap->data, SGI_I2C_FORCE_IDLE);
+ for (i = 0; i < adap->xfer_timeout; i++) {
+ if ((adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE) == 0)
+ goto out;
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+out:
+ if (adap->getctrl(adap->data) & SGI_I2C_BUS_ERR)
+ return -EIO;
+ return 0;
+}
+
+static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr,
+ int rd)
+{
+ if (rd)
+ adap->setctrl(adap->data, SGI_I2C_NOT_IDLE);
+ /* Check if bus is idle, eventually force it to do so */
+ if (adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE)
+ if (force_idle(adap))
+ return -EIO;
+ /* Write out the i2c chip address and specify operation */
+ adap->setctrl(adap->data,
+ SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE);
+ if (rd)
+ addr |= 1;
+ adap->wdata(adap->data, addr);
+ if (wait_ack(adap))
+ return -EIO;
+ return 0;
+}
+
+static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf,
+ unsigned int len)
+{
+ int i;
+
+ adap->setctrl(adap->data,
+ SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE);
+ for (i = 0; i < len; i++) {
+ if (wait_xfer_done(adap))
+ return -EIO;
+ buf[i] = adap->rdata(adap->data);
+ }
+ adap->setctrl(adap->data, SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE);
+
+ return 0;
+
+}
+
+static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf,
+ unsigned int len)
+{
+ int i;
+
+ /* We are already in write state */
+ for (i = 0; i < len; i++) {
+ adap->wdata(adap->data, buf[i]);
+ if (wait_ack(adap))
+ return -EIO;
+ }
+ return 0;
+}
+
+static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
+ int num)
+{
+ struct i2c_algo_sgi_data *adap = i2c_adap->algo_data;
+ struct i2c_msg *p;
+ int i, err = 0;
+
+ for (i = 0; !err && i < num; i++) {
+ p = &msgs[i];
+ err = do_address(adap, p->addr, p->flags & I2C_M_RD);
+ if (err || !p->len)
+ continue;
+ if (p->flags & I2C_M_RD)
+ err = i2c_read(adap, p->buf, p->len);
+ else
+ err = i2c_write(adap, p->buf, p->len);
+ }
+
+ return (err < 0) ? err : i;
+}
+
+static u32 sgi_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm sgi_algo = {
+ .master_xfer = sgi_xfer,
+ .functionality = sgi_func,
+};
+
+static unsigned i2c_vino_getctrl(void *data)
+{
+ return vino->i2c_control;
+}
+
+static void i2c_vino_setctrl(void *data, unsigned val)
+{
+ vino->i2c_control = val;
+}
+
+static unsigned i2c_vino_rdata(void *data)
+{
+ return vino->i2c_data;
+}
+
+static void i2c_vino_wdata(void *data, unsigned val)
+{
+ vino->i2c_data = val;
+}
+
+static struct i2c_algo_sgi_data i2c_sgi_vino_data = {
+ .getctrl = &i2c_vino_getctrl,
+ .setctrl = &i2c_vino_setctrl,
+ .rdata = &i2c_vino_rdata,
+ .wdata = &i2c_vino_wdata,
+ .xfer_timeout = 200,
+ .ack_timeout = 1000,
+};
+
+static struct i2c_adapter vino_i2c_adapter = {
+ .name = "VINO I2C bus",
+ .id = I2C_HW_SGI_VINO,
+ .algo = &sgi_algo,
+ .algo_data = &i2c_sgi_vino_data,
+ .owner = THIS_MODULE,
+};
+
/*
* Prepare VINO for DMA transfer...
* (execute only with vino_lock and input_lock locked)
@@ -2490,86 +2531,15 @@ static int vino_get_saa7191_input(int input)
}
}
-static int vino_get_saa7191_norm(unsigned int data_norm)
-{
- switch (data_norm) {
- case VINO_DATA_NORM_AUTO:
- return SAA7191_NORM_AUTO;
- case VINO_DATA_NORM_AUTO_EXT:
- return SAA7191_NORM_AUTO_EXT;
- case VINO_DATA_NORM_PAL:
- return SAA7191_NORM_PAL;
- case VINO_DATA_NORM_NTSC:
- return SAA7191_NORM_NTSC;
- case VINO_DATA_NORM_SECAM:
- return SAA7191_NORM_SECAM;
- default:
- printk(KERN_ERR "VINO: vino_get_saa7191_norm(): "
- "invalid norm!\n");
- return -1;
- }
-}
-
-static int vino_get_from_saa7191_norm(int saa7191_norm)
-{
- switch (saa7191_norm) {
- case SAA7191_NORM_PAL:
- return VINO_DATA_NORM_PAL;
- case SAA7191_NORM_NTSC:
- return VINO_DATA_NORM_NTSC;
- case SAA7191_NORM_SECAM:
- return VINO_DATA_NORM_SECAM;
- default:
- printk(KERN_ERR "VINO: vino_get_from_saa7191_norm(): "
- "invalid norm!\n");
- return VINO_DATA_NORM_NONE;
- }
-}
-
-static int vino_saa7191_set_norm(unsigned int *data_norm)
-{
- int saa7191_norm, new_data_norm;
- int err = 0;
-
- saa7191_norm = vino_get_saa7191_norm(*data_norm);
-
- err = i2c_decoder_command(DECODER_SAA7191_SET_NORM,
- &saa7191_norm);
- if (err)
- goto out;
-
- if ((*data_norm == VINO_DATA_NORM_AUTO)
- || (*data_norm == VINO_DATA_NORM_AUTO_EXT)) {
- struct saa7191_status status;
-
- err = i2c_decoder_command(DECODER_SAA7191_GET_STATUS,
- &status);
- if (err)
- goto out;
-
- new_data_norm =
- vino_get_from_saa7191_norm(status.norm);
- if (new_data_norm == VINO_DATA_NORM_NONE) {
- err = -EINVAL;
- goto out;
- }
-
- *data_norm = (unsigned int)new_data_norm;
- }
-
-out:
- return err;
-}
-
/* execute with input_lock locked */
static int vino_is_input_owner(struct vino_channel_settings *vcs)
{
switch(vcs->input) {
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO:
- return (vino_drvdata->decoder.owner == vcs->channel);
+ return vino_drvdata->decoder_owner == vcs->channel;
case VINO_INPUT_D1:
- return (vino_drvdata->camera.owner == vcs->channel);
+ return vino_drvdata->camera_owner == vcs->channel;
default:
return 0;
}
@@ -2585,23 +2555,22 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
/* First try D1 and then SAA7191 */
- if (vino_drvdata->camera.driver
- && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) {
- i2c_use_client(vino_drvdata->camera.driver);
- vino_drvdata->camera.owner = vcs->channel;
+ if (vino_drvdata->camera
+ && (vino_drvdata->camera_owner == VINO_NO_CHANNEL)) {
+ vino_drvdata->camera_owner = vcs->channel;
vcs->input = VINO_INPUT_D1;
vcs->data_norm = VINO_DATA_NORM_D1;
- } else if (vino_drvdata->decoder.driver
- && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) {
- int input, data_norm;
- int saa7191_input;
+ } else if (vino_drvdata->decoder
+ && (vino_drvdata->decoder_owner == VINO_NO_CHANNEL)) {
+ int input;
+ int data_norm;
+ v4l2_std_id norm;
+ struct v4l2_routing route = { 0, 0 };
- i2c_use_client(vino_drvdata->decoder.driver);
input = VINO_INPUT_COMPOSITE;
- saa7191_input = vino_get_saa7191_input(input);
- ret = i2c_decoder_command(DECODER_SET_INPUT,
- &saa7191_input);
+ route.input = vino_get_saa7191_input(input);
+ ret = decoder_call(video, s_routing, &route);
if (ret) {
ret = -EINVAL;
goto out;
@@ -2612,12 +2581,15 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
/* Don't hold spinlocks while auto-detecting norm
* as it may take a while... */
- data_norm = VINO_DATA_NORM_AUTO_EXT;
-
- ret = vino_saa7191_set_norm(&data_norm);
- if ((ret == -EBUSY) || (ret == -EAGAIN)) {
- data_norm = VINO_DATA_NORM_PAL;
- ret = vino_saa7191_set_norm(&data_norm);
+ ret = decoder_call(video, querystd, &norm);
+ if (!ret) {
+ for (data_norm = 0; data_norm < 3; data_norm++) {
+ if (vino_data_norms[data_norm].std & norm)
+ break;
+ }
+ if (data_norm == 3)
+ data_norm = VINO_DATA_NORM_PAL;
+ ret = decoder_call(tuner, s_std, norm);
}
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
@@ -2627,7 +2599,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
goto out;
}
- vino_drvdata->decoder.owner = vcs->channel;
+ vino_drvdata->decoder_owner = vcs->channel;
vcs->input = input;
vcs->data_norm = data_norm;
@@ -2672,25 +2644,24 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
switch (input) {
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO:
- if (!vino_drvdata->decoder.driver) {
+ if (!vino_drvdata->decoder) {
ret = -EINVAL;
goto out;
}
- if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) {
- i2c_use_client(vino_drvdata->decoder.driver);
- vino_drvdata->decoder.owner = vcs->channel;
+ if (vino_drvdata->decoder_owner == VINO_NO_CHANNEL) {
+ vino_drvdata->decoder_owner = vcs->channel;
}
- if (vino_drvdata->decoder.owner == vcs->channel) {
+ if (vino_drvdata->decoder_owner == vcs->channel) {
int data_norm;
- int saa7191_input;
+ v4l2_std_id norm;
+ struct v4l2_routing route = { 0, 0 };
- saa7191_input = vino_get_saa7191_input(input);
- ret = i2c_decoder_command(DECODER_SET_INPUT,
- &saa7191_input);
+ route.input = vino_get_saa7191_input(input);
+ ret = decoder_call(video, s_routing, &route);
if (ret) {
- vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+ vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
ret = -EINVAL;
goto out;
}
@@ -2700,18 +2671,21 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
/* Don't hold spinlocks while auto-detecting norm
* as it may take a while... */
- data_norm = VINO_DATA_NORM_AUTO_EXT;
-
- ret = vino_saa7191_set_norm(&data_norm);
- if ((ret == -EBUSY) || (ret == -EAGAIN)) {
- data_norm = VINO_DATA_NORM_PAL;
- ret = vino_saa7191_set_norm(&data_norm);
+ ret = decoder_call(video, querystd, &norm);
+ if (!ret) {
+ for (data_norm = 0; data_norm < 3; data_norm++) {
+ if (vino_data_norms[data_norm].std & norm)
+ break;
+ }
+ if (data_norm == 3)
+ data_norm = VINO_DATA_NORM_PAL;
+ ret = decoder_call(tuner, s_std, norm);
}
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
if (ret) {
- vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+ vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
ret = -EINVAL;
goto out;
}
@@ -2728,37 +2702,31 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
vcs->data_norm = vcs2->data_norm;
}
- if (vino_drvdata->camera.owner == vcs->channel) {
+ if (vino_drvdata->camera_owner == vcs->channel) {
/* Transfer the ownership or release the input */
if (vcs2->input == VINO_INPUT_D1) {
- vino_drvdata->camera.owner = vcs2->channel;
+ vino_drvdata->camera_owner = vcs2->channel;
} else {
- i2c_release_client(vino_drvdata->
- camera.driver);
- vino_drvdata->camera.owner = VINO_NO_CHANNEL;
+ vino_drvdata->camera_owner = VINO_NO_CHANNEL;
}
}
break;
case VINO_INPUT_D1:
- if (!vino_drvdata->camera.driver) {
+ if (!vino_drvdata->camera) {
ret = -EINVAL;
goto out;
}
- if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) {
- i2c_use_client(vino_drvdata->camera.driver);
- vino_drvdata->camera.owner = vcs->channel;
- }
+ if (vino_drvdata->camera_owner == VINO_NO_CHANNEL)
+ vino_drvdata->camera_owner = vcs->channel;
- if (vino_drvdata->decoder.owner == vcs->channel) {
+ if (vino_drvdata->decoder_owner == vcs->channel) {
/* Transfer the ownership or release the input */
if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
(vcs2->input == VINO_INPUT_SVIDEO)) {
- vino_drvdata->decoder.owner = vcs2->channel;
+ vino_drvdata->decoder_owner = vcs2->channel;
} else {
- i2c_release_client(vino_drvdata->
- decoder.driver);
- vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+ vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
}
}
@@ -2795,20 +2763,18 @@ static void vino_release_input(struct vino_channel_settings *vcs)
/* Release ownership of the channel
* and if the other channel takes input from
* the same source, transfer the ownership */
- if (vino_drvdata->camera.owner == vcs->channel) {
+ if (vino_drvdata->camera_owner == vcs->channel) {
if (vcs2->input == VINO_INPUT_D1) {
- vino_drvdata->camera.owner = vcs2->channel;
+ vino_drvdata->camera_owner = vcs2->channel;
} else {
- i2c_release_client(vino_drvdata->camera.driver);
- vino_drvdata->camera.owner = VINO_NO_CHANNEL;
+ vino_drvdata->camera_owner = VINO_NO_CHANNEL;
}
- } else if (vino_drvdata->decoder.owner == vcs->channel) {
+ } else if (vino_drvdata->decoder_owner == vcs->channel) {
if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
(vcs2->input == VINO_INPUT_SVIDEO)) {
- vino_drvdata->decoder.owner = vcs2->channel;
+ vino_drvdata->decoder_owner = vcs2->channel;
} else {
- i2c_release_client(vino_drvdata->decoder.driver);
- vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+ vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
}
}
vcs->input = VINO_INPUT_NONE;
@@ -2829,18 +2795,16 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs,
switch (vcs->input) {
case VINO_INPUT_D1:
/* only one "norm" supported */
- if ((data_norm != VINO_DATA_NORM_D1)
- && (data_norm != VINO_DATA_NORM_AUTO)
- && (data_norm != VINO_DATA_NORM_AUTO_EXT))
+ if (data_norm != VINO_DATA_NORM_D1)
return -EINVAL;
break;
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO: {
+ v4l2_std_id norm;
+
if ((data_norm != VINO_DATA_NORM_PAL)
&& (data_norm != VINO_DATA_NORM_NTSC)
- && (data_norm != VINO_DATA_NORM_SECAM)
- && (data_norm != VINO_DATA_NORM_AUTO)
- && (data_norm != VINO_DATA_NORM_AUTO_EXT))
+ && (data_norm != VINO_DATA_NORM_SECAM))
return -EINVAL;
spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags);
@@ -2848,7 +2812,8 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs,
/* Don't hold spinlocks while setting norm
* as it may take a while... */
- err = vino_saa7191_set_norm(&data_norm);
+ norm = vino_data_norms[data_norm].std;
+ err = decoder_call(tuner, s_std, norm);
spin_lock_irqsave(&vino_drvdata->input_lock, *flags);
@@ -2884,41 +2849,13 @@ static int vino_find_data_format(__u32 pixelformat)
return VINO_DATA_FMT_NONE;
}
-static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index)
-{
- int data_norm = VINO_DATA_NORM_NONE;
- unsigned long flags;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- switch(vcs->input) {
- case VINO_INPUT_COMPOSITE:
- case VINO_INPUT_SVIDEO:
- if (index == 0) {
- data_norm = VINO_DATA_NORM_PAL;
- } else if (index == 1) {
- data_norm = VINO_DATA_NORM_NTSC;
- } else if (index == 2) {
- data_norm = VINO_DATA_NORM_SECAM;
- }
- break;
- case VINO_INPUT_D1:
- if (index == 0) {
- data_norm = VINO_DATA_NORM_D1;
- }
- break;
- }
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return data_norm;
-}
-
-static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
+static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index)
{
int input = VINO_INPUT_NONE;
unsigned long flags;
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
+ if (vino_drvdata->decoder && vino_drvdata->camera) {
switch (index) {
case 0:
input = VINO_INPUT_COMPOSITE;
@@ -2930,7 +2867,7 @@ static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
input = VINO_INPUT_D1;
break;
}
- } else if (vino_drvdata->decoder.driver) {
+ } else if (vino_drvdata->decoder) {
switch (index) {
case 0:
input = VINO_INPUT_COMPOSITE;
@@ -2939,7 +2876,7 @@ static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
input = VINO_INPUT_SVIDEO;
break;
}
- } else if (vino_drvdata->camera.driver) {
+ } else if (vino_drvdata->camera) {
switch (index) {
case 0:
input = VINO_INPUT_D1;
@@ -2957,7 +2894,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
__u32 index = 0;
// FIXME: detect when no inputs available
- if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
+ if (vino_drvdata->decoder && vino_drvdata->camera) {
switch (vcs->input) {
case VINO_INPUT_COMPOSITE:
index = 0;
@@ -2969,7 +2906,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
index = 2;
break;
}
- } else if (vino_drvdata->decoder.driver) {
+ } else if (vino_drvdata->decoder) {
switch (vcs->input) {
case VINO_INPUT_COMPOSITE:
index = 0;
@@ -2978,7 +2915,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
index = 1;
break;
}
- } else if (vino_drvdata->camera.driver) {
+ } else if (vino_drvdata->camera) {
switch (vcs->input) {
case VINO_INPUT_D1:
index = 0;
@@ -2991,7 +2928,8 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
/* V4L2 ioctls */
-static void vino_v4l2_querycap(struct v4l2_capability *cap)
+static int vino_querycap(struct file *file, void *__fh,
+ struct v4l2_capability *cap)
{
memset(cap, 0, sizeof(struct v4l2_capability));
@@ -3003,16 +2941,18 @@ static void vino_v4l2_querycap(struct v4l2_capability *cap)
V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_STREAMING;
// V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE
+ return 0;
}
-static int vino_v4l2_enuminput(struct vino_channel_settings *vcs,
+static int vino_enum_input(struct file *file, void *__fh,
struct v4l2_input *i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
__u32 index = i->index;
int input;
dprintk("requested index = %d\n", index);
- input = vino_enum_input(vcs, index);
+ input = vino_int_enum_input(vcs, index);
if (input == VINO_INPUT_NONE)
return -EINVAL;
@@ -3023,20 +2963,15 @@ static int vino_v4l2_enuminput(struct vino_channel_settings *vcs,
i->std = vino_inputs[input].std;
strcpy(i->name, vino_inputs[input].name);
- if ((input == VINO_INPUT_COMPOSITE)
- || (input == VINO_INPUT_SVIDEO)) {
- struct saa7191_status status;
- i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
- i->status |= status.signal ? 0 : V4L2_IN_ST_NO_SIGNAL;
- i->status |= status.color ? 0 : V4L2_IN_ST_NO_COLOR;
- }
-
+ if (input == VINO_INPUT_COMPOSITE || input == VINO_INPUT_SVIDEO)
+ decoder_call(video, g_input_status, &i->status);
return 0;
}
-static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
+static int vino_g_input(struct file *file, void *__fh,
unsigned int *i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
__u32 index;
int input;
unsigned long flags;
@@ -3057,52 +2992,24 @@ static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
return 0;
}
-static int vino_v4l2_s_input(struct vino_channel_settings *vcs,
- unsigned int *i)
+static int vino_s_input(struct file *file, void *__fh,
+ unsigned int i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
int input;
- dprintk("requested input = %d\n", *i);
+ dprintk("requested input = %d\n", i);
- input = vino_enum_input(vcs, *i);
+ input = vino_int_enum_input(vcs, i);
if (input == VINO_INPUT_NONE)
return -EINVAL;
return vino_set_input(vcs, input);
}
-static int vino_v4l2_enumstd(struct vino_channel_settings *vcs,
- struct v4l2_standard *s)
-{
- int index = s->index;
- int data_norm;
-
- data_norm = vino_enum_data_norm(vcs, index);
- dprintk("standard index = %d\n", index);
-
- if (data_norm == VINO_DATA_NORM_NONE)
- return -EINVAL;
-
- dprintk("standard name = %s\n",
- vino_data_norms[data_norm].description);
-
- memset(s, 0, sizeof(struct v4l2_standard));
- s->index = index;
-
- s->id = vino_data_norms[data_norm].std;
- s->frameperiod.numerator = 1;
- s->frameperiod.denominator =
- vino_data_norms[data_norm].fps_max;
- s->framelines =
- vino_data_norms[data_norm].framelines;
- strcpy(s->name,
- vino_data_norms[data_norm].description);
-
- return 0;
-}
-
-static int vino_v4l2_querystd(struct vino_channel_settings *vcs,
+static int vino_querystd(struct file *file, void *__fh,
v4l2_std_id *std)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int err = 0;
@@ -3114,19 +3021,7 @@ static int vino_v4l2_querystd(struct vino_channel_settings *vcs,
break;
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO: {
- struct saa7191_status status;
-
- i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
-
- if (status.signal) {
- if (status.signal_60hz) {
- *std = V4L2_STD_NTSC;
- } else {
- *std = V4L2_STD_PAL | V4L2_STD_SECAM;
- }
- } else {
- *std = vino_inputs[vcs->input].std;
- }
+ decoder_call(video, querystd, std);
break;
}
default:
@@ -3138,9 +3033,10 @@ static int vino_v4l2_querystd(struct vino_channel_settings *vcs,
return err;
}
-static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
+static int vino_g_std(struct file *file, void *__fh,
v4l2_std_id *std)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
@@ -3153,9 +3049,10 @@ static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
return 0;
}
-static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
+static int vino_s_std(struct file *file, void *__fh,
v4l2_std_id *std)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int ret = 0;
@@ -3176,12 +3073,7 @@ static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
if (vcs->input == VINO_INPUT_D1)
goto out;
- if (((*std) & V4L2_STD_PAL)
- && ((*std) & V4L2_STD_NTSC)
- && ((*std) & V4L2_STD_SECAM)) {
- ret = vino_set_data_norm(vcs, VINO_DATA_NORM_AUTO_EXT,
- &flags);
- } else if ((*std) & V4L2_STD_PAL) {
+ if ((*std) & V4L2_STD_PAL) {
ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL,
&flags);
} else if ((*std) & V4L2_STD_NTSC) {
@@ -3207,185 +3099,144 @@ out:
return ret;
}
-static int vino_v4l2_enum_fmt(struct vino_channel_settings *vcs,
+static int vino_enum_fmt_vid_cap(struct file *file, void *__fh,
struct v4l2_fmtdesc *fd)
{
- enum v4l2_buf_type type = fd->type;
- int index = fd->index;
- dprintk("format index = %d\n", index);
+ dprintk("format index = %d\n", fd->index);
- switch (fd->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if ((fd->index < 0) ||
- (fd->index >= VINO_DATA_FMT_COUNT))
- return -EINVAL;
- dprintk("format name = %s\n",
- vino_data_formats[index].description);
-
- memset(fd, 0, sizeof(struct v4l2_fmtdesc));
- fd->index = index;
- fd->type = type;
- fd->pixelformat = vino_data_formats[index].pixelformat;
- strcpy(fd->description, vino_data_formats[index].description);
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
+ if (fd->index >= VINO_DATA_FMT_COUNT)
return -EINVAL;
- }
+ dprintk("format name = %s\n", vino_data_formats[fd->index].description);
+ fd->pixelformat = vino_data_formats[fd->index].pixelformat;
+ strcpy(fd->description, vino_data_formats[fd->index].description);
return 0;
}
-static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
+static int vino_try_fmt_vid_cap(struct file *file, void *__fh,
struct v4l2_format *f)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
struct vino_channel_settings tempvcs;
unsigned long flags;
+ struct v4l2_pix_format *pf = &f->fmt.pix;
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_pix_format *pf = &f->fmt.pix;
-
- dprintk("requested: w = %d, h = %d\n",
- pf->width, pf->height);
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+ dprintk("requested: w = %d, h = %d\n",
+ pf->width, pf->height);
- tempvcs.data_format = vino_find_data_format(pf->pixelformat);
- if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
- tempvcs.data_format = VINO_DATA_FMT_GREY;
- pf->pixelformat =
- vino_data_formats[tempvcs.data_format].
- pixelformat;
- }
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+ memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- /* data format must be set before clipping/scaling */
- vino_set_scaling(&tempvcs, pf->width, pf->height);
+ tempvcs.data_format = vino_find_data_format(pf->pixelformat);
+ if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
+ tempvcs.data_format = VINO_DATA_FMT_GREY;
+ pf->pixelformat =
+ vino_data_formats[tempvcs.data_format].
+ pixelformat;
+ }
- dprintk("data format = %s\n",
- vino_data_formats[tempvcs.data_format].description);
+ /* data format must be set before clipping/scaling */
+ vino_set_scaling(&tempvcs, pf->width, pf->height);
- pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
- tempvcs.decimation;
- pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
- tempvcs.decimation;
+ dprintk("data format = %s\n",
+ vino_data_formats[tempvcs.data_format].description);
- pf->field = V4L2_FIELD_INTERLACED;
- pf->bytesperline = tempvcs.line_size;
- pf->sizeimage = tempvcs.line_size *
- (tempvcs.clipping.bottom - tempvcs.clipping.top) /
- tempvcs.decimation;
- pf->colorspace =
- vino_data_formats[tempvcs.data_format].colorspace;
+ pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
+ tempvcs.decimation;
+ pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
+ tempvcs.decimation;
- pf->priv = 0;
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ pf->field = V4L2_FIELD_INTERLACED;
+ pf->bytesperline = tempvcs.line_size;
+ pf->sizeimage = tempvcs.line_size *
+ (tempvcs.clipping.bottom - tempvcs.clipping.top) /
+ tempvcs.decimation;
+ pf->colorspace =
+ vino_data_formats[tempvcs.data_format].colorspace;
+ pf->priv = 0;
return 0;
}
-static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs,
+static int vino_g_fmt_vid_cap(struct file *file, void *__fh,
struct v4l2_format *f)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
+ struct v4l2_pix_format *pf = &f->fmt.pix;
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_pix_format *pf = &f->fmt.pix;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- pf->width = (vcs->clipping.right - vcs->clipping.left) /
- vcs->decimation;
- pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
- vcs->decimation;
- pf->pixelformat =
- vino_data_formats[vcs->data_format].pixelformat;
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- pf->field = V4L2_FIELD_INTERLACED;
- pf->bytesperline = vcs->line_size;
- pf->sizeimage = vcs->line_size *
- (vcs->clipping.bottom - vcs->clipping.top) /
- vcs->decimation;
- pf->colorspace =
- vino_data_formats[vcs->data_format].colorspace;
+ pf->width = (vcs->clipping.right - vcs->clipping.left) /
+ vcs->decimation;
+ pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
+ vcs->decimation;
+ pf->pixelformat =
+ vino_data_formats[vcs->data_format].pixelformat;
- pf->priv = 0;
+ pf->field = V4L2_FIELD_INTERLACED;
+ pf->bytesperline = vcs->line_size;
+ pf->sizeimage = vcs->line_size *
+ (vcs->clipping.bottom - vcs->clipping.top) /
+ vcs->decimation;
+ pf->colorspace =
+ vino_data_formats[vcs->data_format].colorspace;
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ pf->priv = 0;
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return 0;
}
-static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs,
+static int vino_s_fmt_vid_cap(struct file *file, void *__fh,
struct v4l2_format *f)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
int data_format;
unsigned long flags;
+ struct v4l2_pix_format *pf = &f->fmt.pix;
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_pix_format *pf = &f->fmt.pix;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- data_format = vino_find_data_format(pf->pixelformat);
+ data_format = vino_find_data_format(pf->pixelformat);
- if (data_format == VINO_DATA_FMT_NONE) {
- vcs->data_format = VINO_DATA_FMT_GREY;
- pf->pixelformat =
- vino_data_formats[vcs->data_format].
- pixelformat;
- } else {
- vcs->data_format = data_format;
- }
+ if (data_format == VINO_DATA_FMT_NONE) {
+ vcs->data_format = VINO_DATA_FMT_GREY;
+ pf->pixelformat =
+ vino_data_formats[vcs->data_format].
+ pixelformat;
+ } else {
+ vcs->data_format = data_format;
+ }
- /* data format must be set before clipping/scaling */
- vino_set_scaling(vcs, pf->width, pf->height);
+ /* data format must be set before clipping/scaling */
+ vino_set_scaling(vcs, pf->width, pf->height);
- dprintk("data format = %s\n",
- vino_data_formats[vcs->data_format].description);
+ dprintk("data format = %s\n",
+ vino_data_formats[vcs->data_format].description);
- pf->width = vcs->clipping.right - vcs->clipping.left;
- pf->height = vcs->clipping.bottom - vcs->clipping.top;
+ pf->width = vcs->clipping.right - vcs->clipping.left;
+ pf->height = vcs->clipping.bottom - vcs->clipping.top;
- pf->field = V4L2_FIELD_INTERLACED;
- pf->bytesperline = vcs->line_size;
- pf->sizeimage = vcs->line_size *
- (vcs->clipping.bottom - vcs->clipping.top) /
- vcs->decimation;
- pf->colorspace =
- vino_data_formats[vcs->data_format].colorspace;
+ pf->field = V4L2_FIELD_INTERLACED;
+ pf->bytesperline = vcs->line_size;
+ pf->sizeimage = vcs->line_size *
+ (vcs->clipping.bottom - vcs->clipping.top) /
+ vcs->decimation;
+ pf->colorspace =
+ vino_data_formats[vcs->data_format].colorspace;
- pf->priv = 0;
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ pf->priv = 0;
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return 0;
}
-static int vino_v4l2_cropcap(struct vino_channel_settings *vcs,
+static int vino_cropcap(struct file *file, void *__fh,
struct v4l2_cropcap *ccap)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
const struct vino_data_norm *norm;
unsigned long flags;
@@ -3415,9 +3266,10 @@ static int vino_v4l2_cropcap(struct vino_channel_settings *vcs,
return 0;
}
-static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
+static int vino_g_crop(struct file *file, void *__fh,
struct v4l2_crop *c)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
switch (c->type) {
@@ -3439,9 +3291,10 @@ static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
return 0;
}
-static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
+static int vino_s_crop(struct file *file, void *__fh,
struct v4l2_crop *c)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
switch (c->type) {
@@ -3461,108 +3314,83 @@ static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
return 0;
}
-static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
+static int vino_g_parm(struct file *file, void *__fh,
struct v4l2_streamparm *sp)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
+ struct v4l2_captureparm *cp = &sp->parm.capture;
- switch (sp->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_captureparm *cp = &sp->parm.capture;
- memset(cp, 0, sizeof(struct v4l2_captureparm));
+ cp->capability = V4L2_CAP_TIMEPERFRAME;
+ cp->timeperframe.numerator = 1;
- cp->capability = V4L2_CAP_TIMEPERFRAME;
- cp->timeperframe.numerator = 1;
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+ cp->timeperframe.denominator = vcs->fps;
- cp->timeperframe.denominator = vcs->fps;
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- // TODO: cp->readbuffers = xxx;
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ /* TODO: cp->readbuffers = xxx; */
return 0;
}
-static int vino_v4l2_s_parm(struct vino_channel_settings *vcs,
+static int vino_s_parm(struct file *file, void *__fh,
struct v4l2_streamparm *sp)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
+ struct v4l2_captureparm *cp = &sp->parm.capture;
- switch (sp->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_captureparm *cp = &sp->parm.capture;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- if ((cp->timeperframe.numerator == 0) ||
- (cp->timeperframe.denominator == 0)) {
- /* reset framerate */
- vino_set_default_framerate(vcs);
- } else {
- vino_set_framerate(vcs, cp->timeperframe.denominator /
- cp->timeperframe.numerator);
- }
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- // TODO: set buffers according to cp->readbuffers
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
+ if ((cp->timeperframe.numerator == 0) ||
+ (cp->timeperframe.denominator == 0)) {
+ /* reset framerate */
+ vino_set_default_framerate(vcs);
+ } else {
+ vino_set_framerate(vcs, cp->timeperframe.denominator /
+ cp->timeperframe.numerator);
}
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+
return 0;
}
-static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs,
+static int vino_reqbufs(struct file *file, void *__fh,
struct v4l2_requestbuffers *rb)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
+
if (vcs->reading)
return -EBUSY;
- switch (rb->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- // TODO: check queue type
- if (rb->memory != V4L2_MEMORY_MMAP) {
- dprintk("type not mmap\n");
- return -EINVAL;
- }
+ /* TODO: check queue type */
+ if (rb->memory != V4L2_MEMORY_MMAP) {
+ dprintk("type not mmap\n");
+ return -EINVAL;
+ }
- dprintk("count = %d\n", rb->count);
- if (rb->count > 0) {
- if (vino_is_capturing(vcs)) {
- dprintk("busy, capturing\n");
- return -EBUSY;
- }
+ dprintk("count = %d\n", rb->count);
+ if (rb->count > 0) {
+ if (vino_is_capturing(vcs)) {
+ dprintk("busy, capturing\n");
+ return -EBUSY;
+ }
- if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
- dprintk("busy, buffers still mapped\n");
- return -EBUSY;
- } else {
- vcs->streaming = 0;
- vino_queue_free(&vcs->fb_queue);
- vino_queue_init(&vcs->fb_queue, &rb->count);
- }
+ if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
+ dprintk("busy, buffers still mapped\n");
+ return -EBUSY;
} else {
vcs->streaming = 0;
- vino_capture_stop(vcs);
vino_queue_free(&vcs->fb_queue);
+ vino_queue_init(&vcs->fb_queue, &rb->count);
}
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
+ } else {
+ vcs->streaming = 0;
+ vino_capture_stop(vcs);
+ vino_queue_free(&vcs->fb_queue);
}
return 0;
@@ -3606,156 +3434,135 @@ static void vino_v4l2_get_buffer_status(struct vino_channel_settings *vcs,
fb->id, fb->size, fb->data_size, fb->offset);
}
-static int vino_v4l2_querybuf(struct vino_channel_settings *vcs,
+static int vino_querybuf(struct file *file, void *__fh,
struct v4l2_buffer *b)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
+ struct vino_framebuffer *fb;
+
if (vcs->reading)
return -EBUSY;
- switch (b->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct vino_framebuffer *fb;
-
- // TODO: check queue type
- if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
- dprintk("invalid index = %d\n",
- b->index);
- return -EINVAL;
- }
-
- fb = vino_queue_get_buffer(&vcs->fb_queue,
- b->index);
- if (fb == NULL) {
- dprintk("vino_queue_get_buffer() failed");
- return -EINVAL;
- }
-
- vino_v4l2_get_buffer_status(vcs, fb, b);
- break;
+ /* TODO: check queue type */
+ if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
+ dprintk("invalid index = %d\n",
+ b->index);
+ return -EINVAL;
}
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
+
+ fb = vino_queue_get_buffer(&vcs->fb_queue,
+ b->index);
+ if (fb == NULL) {
+ dprintk("vino_queue_get_buffer() failed");
return -EINVAL;
}
+ vino_v4l2_get_buffer_status(vcs, fb, b);
+
return 0;
}
-static int vino_v4l2_qbuf(struct vino_channel_settings *vcs,
+static int vino_qbuf(struct file *file, void *__fh,
struct v4l2_buffer *b)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
+ struct vino_framebuffer *fb;
+ int ret;
+
if (vcs->reading)
return -EBUSY;
- switch (b->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct vino_framebuffer *fb;
- int ret;
-
- // TODO: check queue type
- if (b->memory != V4L2_MEMORY_MMAP) {
- dprintk("type not mmap\n");
- return -EINVAL;
- }
+ /* TODO: check queue type */
+ if (b->memory != V4L2_MEMORY_MMAP) {
+ dprintk("type not mmap\n");
+ return -EINVAL;
+ }
- fb = vino_capture_enqueue(vcs, b->index);
- if (fb == NULL)
- return -EINVAL;
+ fb = vino_capture_enqueue(vcs, b->index);
+ if (fb == NULL)
+ return -EINVAL;
- vino_v4l2_get_buffer_status(vcs, fb, b);
+ vino_v4l2_get_buffer_status(vcs, fb, b);
- if (vcs->streaming) {
- ret = vino_capture_next(vcs, 1);
- if (ret)
- return ret;
- }
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
+ if (vcs->streaming) {
+ ret = vino_capture_next(vcs, 1);
+ if (ret)
+ return ret;
}
return 0;
}
-static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
- struct v4l2_buffer *b,
- unsigned int nonblocking)
+static int vino_dqbuf(struct file *file, void *__fh,
+ struct v4l2_buffer *b)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
+ unsigned int nonblocking = file->f_flags & O_NONBLOCK;
+ struct vino_framebuffer *fb;
+ unsigned int incoming, outgoing;
+ int err;
+
if (vcs->reading)
return -EBUSY;
- switch (b->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct vino_framebuffer *fb;
- unsigned int incoming, outgoing;
- int err;
+ /* TODO: check queue type */
- // TODO: check queue type
+ err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
+ if (err) {
+ dprintk("vino_queue_get_incoming() failed\n");
+ return -EINVAL;
+ }
+ err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
+ if (err) {
+ dprintk("vino_queue_get_outgoing() failed\n");
+ return -EINVAL;
+ }
- err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
- if (err) {
- dprintk("vino_queue_get_incoming() failed\n");
+ dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
+
+ if (outgoing == 0) {
+ if (incoming == 0) {
+ dprintk("no incoming or outgoing buffers\n");
return -EINVAL;
}
- err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
- if (err) {
- dprintk("vino_queue_get_outgoing() failed\n");
- return -EINVAL;
+ if (nonblocking) {
+ dprintk("non-blocking I/O was selected and "
+ "there are no buffers to dequeue\n");
+ return -EAGAIN;
}
- dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
-
- if (outgoing == 0) {
- if (incoming == 0) {
- dprintk("no incoming or outgoing buffers\n");
- return -EINVAL;
- }
- if (nonblocking) {
- dprintk("non-blocking I/O was selected and "
- "there are no buffers to dequeue\n");
- return -EAGAIN;
- }
-
+ err = vino_wait_for_frame(vcs);
+ if (err) {
err = vino_wait_for_frame(vcs);
if (err) {
- err = vino_wait_for_frame(vcs);
- if (err) {
- /* interrupted or
- * no frames captured because
- * of frame skipping */
- // vino_capture_failed(vcs);
- return -EIO;
- }
+ /* interrupted or no frames captured because of
+ * frame skipping */
+ /* vino_capture_failed(vcs); */
+ return -EIO;
}
}
+ }
- fb = vino_queue_remove(&vcs->fb_queue, &b->index);
- if (fb == NULL) {
- dprintk("vino_queue_remove() failed\n");
- return -EINVAL;
- }
-
- err = vino_check_buffer(vcs, fb);
+ fb = vino_queue_remove(&vcs->fb_queue, &b->index);
+ if (fb == NULL) {
+ dprintk("vino_queue_remove() failed\n");
+ return -EINVAL;
+ }
- vino_v4l2_get_buffer_status(vcs, fb, b);
+ err = vino_check_buffer(vcs, fb);
- if (err)
- return -EIO;
+ vino_v4l2_get_buffer_status(vcs, fb, b);
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ if (err)
+ return -EIO;
return 0;
}
-static int vino_v4l2_streamon(struct vino_channel_settings *vcs)
+static int vino_streamon(struct file *file, void *__fh,
+ enum v4l2_buf_type i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned int incoming;
int ret;
if (vcs->reading)
@@ -3792,8 +3599,10 @@ static int vino_v4l2_streamon(struct vino_channel_settings *vcs)
return 0;
}
-static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
+static int vino_streamoff(struct file *file, void *__fh,
+ enum v4l2_buf_type i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
if (vcs->reading)
return -EBUSY;
@@ -3806,9 +3615,10 @@ static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
return 0;
}
-static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
+static int vino_queryctrl(struct file *file, void *__fh,
struct v4l2_queryctrl *queryctrl)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int i;
int err = 0;
@@ -3855,9 +3665,10 @@ static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
return err;
}
-static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs,
+static int vino_g_ctrl(struct file *file, void *__fh,
struct v4l2_control *control)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int i;
int err = 0;
@@ -3866,56 +3677,38 @@ static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs,
switch (vcs->input) {
case VINO_INPUT_D1: {
- struct indycam_control indycam_ctrl;
-
+ err = -EINVAL;
for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
- if (vino_indycam_v4l2_controls[i].id ==
- control->id) {
- goto found1;
+ if (vino_indycam_v4l2_controls[i].id == control->id) {
+ err = 0;
+ break;
}
}
- err = -EINVAL;
- goto out;
-
-found1:
- indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
-
- err = i2c_camera_command(DECODER_INDYCAM_GET_CONTROL,
- &indycam_ctrl);
- if (err) {
- err = -EINVAL;
+ if (err)
goto out;
- }
- control->value = indycam_ctrl.value;
+ err = camera_call(core, g_ctrl, control);
+ if (err)
+ err = -EINVAL;
break;
}
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO: {
- struct saa7191_control saa7191_ctrl;
-
+ err = -EINVAL;
for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
- if (vino_saa7191_v4l2_controls[i].id ==
- control->id) {
- goto found2;
+ if (vino_saa7191_v4l2_controls[i].id == control->id) {
+ err = 0;
+ break;
}
}
- err = -EINVAL;
- goto out;
-
-found2:
- saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
-
- err = i2c_decoder_command(DECODER_SAA7191_GET_CONTROL,
- &saa7191_ctrl);
- if (err) {
- err = -EINVAL;
+ if (err)
goto out;
- }
- control->value = saa7191_ctrl.value;
+ err = decoder_call(core, g_ctrl, control);
+ if (err)
+ err = -EINVAL;
break;
}
default:
@@ -3928,9 +3721,10 @@ out:
return err;
}
-static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs,
+static int vino_s_ctrl(struct file *file, void *__fh,
struct v4l2_control *control)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int i;
int err = 0;
@@ -3944,65 +3738,43 @@ static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs,
switch (vcs->input) {
case VINO_INPUT_D1: {
- struct indycam_control indycam_ctrl;
-
+ err = -EINVAL;
for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
- if (vino_indycam_v4l2_controls[i].id ==
- control->id) {
- if ((control->value >=
- vino_indycam_v4l2_controls[i].minimum)
- && (control->value <=
- vino_indycam_v4l2_controls[i].
- maximum)) {
- goto found1;
- } else {
- err = -ERANGE;
- goto out;
- }
+ if (vino_indycam_v4l2_controls[i].id == control->id) {
+ err = 0;
+ break;
}
}
-
- err = -EINVAL;
- goto out;
-
-found1:
- indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
- indycam_ctrl.value = control->value;
-
- err = i2c_camera_command(DECODER_INDYCAM_SET_CONTROL,
- &indycam_ctrl);
+ if (err)
+ goto out;
+ if (control->value < vino_indycam_v4l2_controls[i].minimum ||
+ control->value > vino_indycam_v4l2_controls[i].maximum) {
+ err = -ERANGE;
+ goto out;
+ }
+ err = camera_call(core, s_ctrl, control);
if (err)
err = -EINVAL;
break;
}
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO: {
- struct saa7191_control saa7191_ctrl;
-
+ err = -EINVAL;
for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
- if (vino_saa7191_v4l2_controls[i].id ==
- control->id) {
- if ((control->value >=
- vino_saa7191_v4l2_controls[i].minimum)
- && (control->value <=
- vino_saa7191_v4l2_controls[i].
- maximum)) {
- goto found2;
- } else {
- err = -ERANGE;
- goto out;
- }
+ if (vino_saa7191_v4l2_controls[i].id == control->id) {
+ err = 0;
+ break;
}
}
- err = -EINVAL;
- goto out;
-
-found2:
- saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
- saa7191_ctrl.value = control->value;
+ if (err)
+ goto out;
+ if (control->value < vino_saa7191_v4l2_controls[i].minimum ||
+ control->value > vino_saa7191_v4l2_controls[i].maximum) {
+ err = -ERANGE;
+ goto out;
+ }
- err = i2c_decoder_command(DECODER_SAA7191_SET_CONTROL,
- &saa7191_ctrl);
+ err = decoder_call(core, s_ctrl, control);
if (err)
err = -EINVAL;
break;
@@ -4233,116 +4005,9 @@ over:
ret = POLLIN | POLLRDNORM;
error:
-
return ret;
}
-static long vino_do_ioctl(struct file *file, unsigned int cmd, void *arg)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
-
-#ifdef VINO_DEBUG
- switch (_IOC_TYPE(cmd)) {
- case 'v':
- dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd);
- break;
- case 'V':
- dprintk("ioctl(): V4L2 %s (0x%08x)\n",
- v4l2_ioctl_names[_IOC_NR(cmd)], cmd);
- break;
- default:
- dprintk("ioctl(): unsupported command 0x%08x\n", cmd);
- }
-#endif
-
- switch (cmd) {
- /* V4L2 interface */
- case VIDIOC_QUERYCAP: {
- vino_v4l2_querycap(arg);
- break;
- }
- case VIDIOC_ENUMINPUT: {
- return vino_v4l2_enuminput(vcs, arg);
- }
- case VIDIOC_G_INPUT: {
- return vino_v4l2_g_input(vcs, arg);
- }
- case VIDIOC_S_INPUT: {
- return vino_v4l2_s_input(vcs, arg);
- }
- case VIDIOC_ENUMSTD: {
- return vino_v4l2_enumstd(vcs, arg);
- }
- case VIDIOC_QUERYSTD: {
- return vino_v4l2_querystd(vcs, arg);
- }
- case VIDIOC_G_STD: {
- return vino_v4l2_g_std(vcs, arg);
- }
- case VIDIOC_S_STD: {
- return vino_v4l2_s_std(vcs, arg);
- }
- case VIDIOC_ENUM_FMT: {
- return vino_v4l2_enum_fmt(vcs, arg);
- }
- case VIDIOC_TRY_FMT: {
- return vino_v4l2_try_fmt(vcs, arg);
- }
- case VIDIOC_G_FMT: {
- return vino_v4l2_g_fmt(vcs, arg);
- }
- case VIDIOC_S_FMT: {
- return vino_v4l2_s_fmt(vcs, arg);
- }
- case VIDIOC_CROPCAP: {
- return vino_v4l2_cropcap(vcs, arg);
- }
- case VIDIOC_G_CROP: {
- return vino_v4l2_g_crop(vcs, arg);
- }
- case VIDIOC_S_CROP: {
- return vino_v4l2_s_crop(vcs, arg);
- }
- case VIDIOC_G_PARM: {
- return vino_v4l2_g_parm(vcs, arg);
- }
- case VIDIOC_S_PARM: {
- return vino_v4l2_s_parm(vcs, arg);
- }
- case VIDIOC_REQBUFS: {
- return vino_v4l2_reqbufs(vcs, arg);
- }
- case VIDIOC_QUERYBUF: {
- return vino_v4l2_querybuf(vcs, arg);
- }
- case VIDIOC_QBUF: {
- return vino_v4l2_qbuf(vcs, arg);
- }
- case VIDIOC_DQBUF: {
- return vino_v4l2_dqbuf(vcs, arg, file->f_flags & O_NONBLOCK);
- }
- case VIDIOC_STREAMON: {
- return vino_v4l2_streamon(vcs);
- }
- case VIDIOC_STREAMOFF: {
- return vino_v4l2_streamoff(vcs);
- }
- case VIDIOC_QUERYCTRL: {
- return vino_v4l2_queryctrl(vcs, arg);
- }
- case VIDIOC_G_CTRL: {
- return vino_v4l2_g_ctrl(vcs, arg);
- }
- case VIDIOC_S_CTRL: {
- return vino_v4l2_s_ctrl(vcs, arg);
- }
- default:
- return -ENOIOCTLCMD;
- }
-
- return 0;
-}
-
static long vino_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -4352,7 +4017,7 @@ static long vino_ioctl(struct file *file,
if (mutex_lock_interruptible(&vcs->mutex))
return -EINTR;
- ret = video_usercopy(file, cmd, arg, vino_do_ioctl);
+ ret = video_ioctl2(file, cmd, arg);
mutex_unlock(&vcs->mutex);
@@ -4364,45 +4029,75 @@ static long vino_ioctl(struct file *file,
/* __initdata */
static int vino_init_stage;
+const struct v4l2_ioctl_ops vino_ioctl_ops = {
+ .vidioc_enum_fmt_vid_cap = vino_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vino_g_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vino_s_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vino_try_fmt_vid_cap,
+ .vidioc_querycap = vino_querycap,
+ .vidioc_enum_input = vino_enum_input,
+ .vidioc_g_input = vino_g_input,
+ .vidioc_s_input = vino_s_input,
+ .vidioc_g_std = vino_g_std,
+ .vidioc_s_std = vino_s_std,
+ .vidioc_querystd = vino_querystd,
+ .vidioc_cropcap = vino_cropcap,
+ .vidioc_s_crop = vino_s_crop,
+ .vidioc_g_crop = vino_g_crop,
+ .vidioc_s_parm = vino_s_parm,
+ .vidioc_g_parm = vino_g_parm,
+ .vidioc_reqbufs = vino_reqbufs,
+ .vidioc_querybuf = vino_querybuf,
+ .vidioc_qbuf = vino_qbuf,
+ .vidioc_dqbuf = vino_dqbuf,
+ .vidioc_streamon = vino_streamon,
+ .vidioc_streamoff = vino_streamoff,
+ .vidioc_queryctrl = vino_queryctrl,
+ .vidioc_g_ctrl = vino_g_ctrl,
+ .vidioc_s_ctrl = vino_s_ctrl,
+};
+
static const struct v4l2_file_operations vino_fops = {
.owner = THIS_MODULE,
.open = vino_open,
.release = vino_close,
- .ioctl = vino_ioctl,
+ .unlocked_ioctl = vino_ioctl,
.mmap = vino_mmap,
.poll = vino_poll,
};
-static struct video_device v4l_device_template = {
+static struct video_device vdev_template = {
.name = "NOT SET",
.fops = &vino_fops,
+ .ioctl_ops = &vino_ioctl_ops,
+ .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
.minor = -1,
};
static void vino_module_cleanup(int stage)
{
switch(stage) {
+ case 11:
+ video_unregister_device(vino_drvdata->b.vdev);
+ vino_drvdata->b.vdev = NULL;
case 10:
- video_unregister_device(vino_drvdata->b.v4l_device);
- vino_drvdata->b.v4l_device = NULL;
+ video_unregister_device(vino_drvdata->a.vdev);
+ vino_drvdata->a.vdev = NULL;
case 9:
- video_unregister_device(vino_drvdata->a.v4l_device);
- vino_drvdata->a.v4l_device = NULL;
+ i2c_del_adapter(&vino_i2c_adapter);
case 8:
- vino_i2c_del_bus();
- case 7:
free_irq(SGI_VINO_IRQ, NULL);
+ case 7:
+ if (vino_drvdata->b.vdev) {
+ video_device_release(vino_drvdata->b.vdev);
+ vino_drvdata->b.vdev = NULL;
+ }
case 6:
- if (vino_drvdata->b.v4l_device) {
- video_device_release(vino_drvdata->b.v4l_device);
- vino_drvdata->b.v4l_device = NULL;
+ if (vino_drvdata->a.vdev) {
+ video_device_release(vino_drvdata->a.vdev);
+ vino_drvdata->a.vdev = NULL;
}
case 5:
- if (vino_drvdata->a.v4l_device) {
- video_device_release(vino_drvdata->a.v4l_device);
- vino_drvdata->a.v4l_device = NULL;
- }
- case 4:
/* all entries in dma_cpu dummy table have the same address */
dma_unmap_single(NULL,
vino_drvdata->dummy_desc_table.dma_cpu[0],
@@ -4412,8 +4107,10 @@ static void vino_module_cleanup(int stage)
(void *)vino_drvdata->
dummy_desc_table.dma_cpu,
vino_drvdata->dummy_desc_table.dma);
- case 3:
+ case 4:
free_page(vino_drvdata->dummy_page);
+ case 3:
+ v4l2_device_unregister(&vino_drvdata->v4l2_dev);
case 2:
kfree(vino_drvdata);
case 1:
@@ -4468,6 +4165,7 @@ static int vino_probe(void)
static int vino_init(void)
{
dma_addr_t dma_dummy_address;
+ int err;
int i;
vino_drvdata = kzalloc(sizeof(struct vino_settings), GFP_KERNEL);
@@ -4476,6 +4174,12 @@ static int vino_init(void)
return -ENOMEM;
}
vino_init_stage++;
+ strlcpy(vino_drvdata->v4l2_dev.name, "vino",
+ sizeof(vino_drvdata->v4l2_dev.name));
+ err = v4l2_device_register(NULL, &vino_drvdata->v4l2_dev);
+ if (err)
+ return err;
+ vino_init_stage++;
/* create a dummy dma descriptor */
vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
@@ -4542,25 +4246,27 @@ static int vino_init_channel_settings(struct vino_channel_settings *vcs,
spin_lock_init(&vcs->fb_queue.queue_lock);
init_waitqueue_head(&vcs->fb_queue.frame_wait_queue);
- vcs->v4l_device = video_device_alloc();
- if (!vcs->v4l_device) {
+ vcs->vdev = video_device_alloc();
+ if (!vcs->vdev) {
vino_module_cleanup(vino_init_stage);
return -ENOMEM;
}
vino_init_stage++;
- memcpy(vcs->v4l_device, &v4l_device_template,
+ memcpy(vcs->vdev, &vdev_template,
sizeof(struct video_device));
- strcpy(vcs->v4l_device->name, name);
- vcs->v4l_device->release = video_device_release;
+ strcpy(vcs->vdev->name, name);
+ vcs->vdev->release = video_device_release;
+ vcs->vdev->v4l2_dev = &vino_drvdata->v4l2_dev;
- video_set_drvdata(vcs->v4l_device, vcs);
+ video_set_drvdata(vcs->vdev, vcs);
return 0;
}
static int __init vino_module_init(void)
{
+ unsigned short addr[] = { 0, I2C_CLIENT_END };
int ret;
printk(KERN_INFO "SGI VINO driver version %s\n",
@@ -4580,12 +4286,12 @@ static int __init vino_module_init(void)
spin_lock_init(&vino_drvdata->input_lock);
ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A,
- vino_v4l_device_name_a);
+ vino_vdev_name_a);
if (ret)
return ret;
ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B,
- vino_v4l_device_name_b);
+ vino_vdev_name_b);
if (ret)
return ret;
@@ -4601,15 +4307,16 @@ static int __init vino_module_init(void)
}
vino_init_stage++;
- ret = vino_i2c_add_bus();
+ ret = i2c_add_adapter(&vino_i2c_adapter);
if (ret) {
printk(KERN_ERR "VINO I2C bus registration failed\n");
vino_module_cleanup(vino_init_stage);
return ret;
}
+ i2c_set_adapdata(&vino_i2c_adapter, &vino_drvdata->v4l2_dev);
vino_init_stage++;
- ret = video_register_device(vino_drvdata->a.v4l_device,
+ ret = video_register_device(vino_drvdata->a.vdev,
VFL_TYPE_GRABBER, -1);
if (ret < 0) {
printk(KERN_ERR "VINO channel A Video4Linux-device "
@@ -4619,7 +4326,7 @@ static int __init vino_module_init(void)
}
vino_init_stage++;
- ret = video_register_device(vino_drvdata->b.v4l_device,
+ ret = video_register_device(vino_drvdata->b.vdev,
VFL_TYPE_GRABBER, -1);
if (ret < 0) {
printk(KERN_ERR "VINO channel B Video4Linux-device "
@@ -4629,10 +4336,12 @@ static int __init vino_module_init(void)
}
vino_init_stage++;
-#ifdef MODULE
- request_module("saa7191");
- request_module("indycam");
-#endif
+ addr[0] = 0x45;
+ vino_drvdata->decoder = v4l2_i2c_new_probed_subdev(&vino_i2c_adapter,
+ "saa7191", "saa7191", addr);
+ addr[0] = 0x2b;
+ vino_drvdata->camera = v4l2_i2c_new_probed_subdev(&vino_i2c_adapter,
+ "indycam", "indycam", addr);
dprintk("init complete!\n");
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 81d5aa5cf331..fbfefae7886f 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -28,17 +28,14 @@
#include <linux/mutex.h>
#include <linux/videodev2.h>
#include <linux/dma-mapping.h>
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* Include V4L1 specific functions. Should be removed soon */
-#include <linux/videodev.h>
-#endif
#include <linux/interrupt.h>
-#include <media/videobuf-vmalloc.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
#include <linux/kthread.h>
#include <linux/highmem.h>
#include <linux/freezer.h>
+#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include "font.h"
#define VIVI_MODULE_NAME "vivi"
@@ -47,18 +44,32 @@
#define WAKE_DENOMINATOR 1001
#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
-#include "font.h"
-
#define VIVI_MAJOR_VERSION 0
-#define VIVI_MINOR_VERSION 5
+#define VIVI_MINOR_VERSION 6
#define VIVI_RELEASE 0
#define VIVI_VERSION \
KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE)
-/* Declare static vars that will be used as parameters */
-static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
-static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
-static int n_devs = 1; /* Number of virtual devices */
+MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
+MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static unsigned video_nr = -1;
+module_param(video_nr, uint, 0644);
+MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
+
+static unsigned n_devs = 1;
+module_param(n_devs, uint, 0644);
+MODULE_PARM_DESC(n_devs, "number of video devices to create");
+
+static unsigned debug;
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
+
+static unsigned int vid_limit = 16;
+module_param(vid_limit, uint, 0644);
+MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
+
/* supported controls */
static struct v4l2_queryctrl vivi_qctrl[] = {
@@ -69,7 +80,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
.maximum = 65535,
.step = 65535/100,
.default_value = 65535,
- .flags = 0,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
.type = V4L2_CTRL_TYPE_INTEGER,
}, {
.id = V4L2_CID_BRIGHTNESS,
@@ -79,7 +90,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
.maximum = 255,
.step = 1,
.default_value = 127,
- .flags = 0,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
}, {
.id = V4L2_CID_CONTRAST,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -88,7 +99,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
.maximum = 255,
.step = 0x1,
.default_value = 0x10,
- .flags = 0,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
}, {
.id = V4L2_CID_SATURATION,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -97,7 +108,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
.maximum = 255,
.step = 0x1,
.default_value = 127,
- .flags = 0,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
}, {
.id = V4L2_CID_HUE,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -106,17 +117,12 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
.maximum = 127,
.step = 0x1,
.default_value = 0,
- .flags = 0,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
}
};
-static int qctl_regs[ARRAY_SIZE(vivi_qctrl)];
-
-#define dprintk(dev, level, fmt, arg...) \
- do { \
- if (dev->vfd->debug >= (level)) \
- printk(KERN_DEBUG "vivi: " fmt , ## arg); \
- } while (0)
+#define dprintk(dev, level, fmt, arg...) \
+ v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
/* ------------------------------------------------------------------
Basic structures
@@ -206,6 +212,7 @@ static LIST_HEAD(vivi_devlist);
struct vivi_dev {
struct list_head vivi_devlist;
+ struct v4l2_device v4l2_dev;
spinlock_t slock;
struct mutex mutex;
@@ -223,6 +230,12 @@ struct vivi_dev {
char timestr[13];
int mv_count; /* Controls bars movement */
+
+ /* Input Number */
+ int input;
+
+ /* Control 'registers' */
+ int qctl_regs[ARRAY_SIZE(vivi_qctrl)];
};
struct vivi_fh {
@@ -235,6 +248,7 @@ struct vivi_fh {
enum v4l2_buf_type type;
unsigned char bars[8][3];
+ int input; /* Input Number on bars */
};
/* ------------------------------------------------------------------
@@ -254,18 +268,72 @@ enum colors {
BLACK,
};
-static u8 bars[8][3] = {
/* R G B */
- {204, 204, 204}, /* white */
- {208, 208, 0}, /* ambar */
- { 0, 206, 206}, /* cyan */
- { 0, 239, 0}, /* green */
- {239, 0, 239}, /* magenta */
- {205, 0, 0}, /* red */
- { 0, 0, 255}, /* blue */
- { 0, 0, 0}, /* black */
+#define COLOR_WHITE {204, 204, 204}
+#define COLOR_AMBAR {208, 208, 0}
+#define COLOR_CIAN { 0, 206, 206}
+#define COLOR_GREEN { 0, 239, 0}
+#define COLOR_MAGENTA {239, 0, 239}
+#define COLOR_RED {205, 0, 0}
+#define COLOR_BLUE { 0, 0, 255}
+#define COLOR_BLACK { 0, 0, 0}
+
+struct bar_std {
+ u8 bar[8][3];
};
+/* Maximum number of bars are 10 - otherwise, the input print code
+ should be modified */
+static struct bar_std bars[] = {
+ { /* Standard ITU-R color bar sequence */
+ {
+ COLOR_WHITE,
+ COLOR_AMBAR,
+ COLOR_CIAN,
+ COLOR_GREEN,
+ COLOR_MAGENTA,
+ COLOR_RED,
+ COLOR_BLUE,
+ COLOR_BLACK,
+ }
+ }, {
+ {
+ COLOR_WHITE,
+ COLOR_AMBAR,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_AMBAR,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_AMBAR,
+ }
+ }, {
+ {
+ COLOR_WHITE,
+ COLOR_CIAN,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_CIAN,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_CIAN,
+ }
+ }, {
+ {
+ COLOR_WHITE,
+ COLOR_GREEN,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_GREEN,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_GREEN,
+ }
+ },
+};
+
+#define NUM_INPUTS ARRAY_SIZE(bars)
+
#define TO_Y(r, g, b) \
(((16829 * r + 33039 * g + 6416 * b + 32768) >> 16) + 16)
/* RGB to V(Cr) Color transform */
@@ -275,9 +343,10 @@ static u8 bars[8][3] = {
#define TO_U(r, g, b) \
(((-9714 * r - 19070 * g + 28784 * b + 32768) >> 16) + 128)
-#define TSTAMP_MIN_Y 24
-#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15
-#define TSTAMP_MIN_X 64
+#define TSTAMP_MIN_Y 24
+#define TSTAMP_MAX_Y (TSTAMP_MIN_Y + 15)
+#define TSTAMP_INPUT_X 10
+#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X)
static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos)
{
@@ -392,9 +461,29 @@ static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax,
pos += 4; /* only 16 bpp supported for now */
}
- /* Checks if it is possible to show timestamp */
+ /* Prints input entry number */
+
+ /* Checks if it is possible to input number */
if (TSTAMP_MAX_Y >= hmax)
goto end;
+
+ if (TSTAMP_INPUT_X + strlen(timestr) >= wmax)
+ goto end;
+
+ if (line >= TSTAMP_MIN_Y && line <= TSTAMP_MAX_Y) {
+ chr = rom8x16_bits[fh->input * 16 + line - TSTAMP_MIN_Y];
+ pos = TSTAMP_INPUT_X;
+ for (i = 0; i < 7; i++) {
+ /* Draw white font on black background */
+ if (chr & 1 << (7 - i))
+ gen_twopix(fh, basep + pos, WHITE);
+ else
+ gen_twopix(fh, basep + pos, BLACK);
+ pos += 2;
+ }
+ }
+
+ /* Checks if it is possible to show timestamp */
if (TSTAMP_MIN_X + strlen(timestr) >= wmax)
goto end;
@@ -577,7 +666,7 @@ static int vivi_start_thread(struct vivi_fh *fh)
dma_q->kthread = kthread_run(vivi_thread, fh, "vivi");
if (IS_ERR(dma_q->kthread)) {
- printk(KERN_ERR "vivi: kernel_thread() failed\n");
+ v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
return PTR_ERR(dma_q->kthread);
}
/* Wakes thread */
@@ -720,8 +809,12 @@ static struct videobuf_queue_ops vivi_video_qops = {
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
+ struct vivi_fh *fh = priv;
+ struct vivi_dev *dev = fh->dev;
+
strcpy(cap->driver, "vivi");
strcpy(cap->card, "vivi");
+ strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
cap->version = VIVI_VERSION;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_STREAMING |
@@ -807,38 +900,19 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-/*FIXME: This seems to be generic enough to be at videodev2 */
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
+/* precalculate color bar values to speed up rendering */
+static void precalculate_bars(struct vivi_fh *fh)
{
- struct vivi_fh *fh = priv;
- struct videobuf_queue *q = &fh->vb_vidq;
+ struct vivi_dev *dev = fh->dev;
unsigned char r, g, b;
int k, is_yuv;
- int ret = vidioc_try_fmt_vid_cap(file, fh, f);
- if (ret < 0)
- return (ret);
-
- mutex_lock(&q->vb_lock);
-
- if (videobuf_queue_is_busy(&fh->vb_vidq)) {
- dprintk(fh->dev, 1, "%s queue busy\n", __func__);
- ret = -EBUSY;
- goto out;
- }
-
- fh->fmt = get_format(f);
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
- fh->vb_vidq.field = f->fmt.pix.field;
- fh->type = f->type;
+ fh->input = dev->input;
- /* precalculate color bar values to speed up rendering */
for (k = 0; k < 8; k++) {
- r = bars[k][0];
- g = bars[k][1];
- b = bars[k][2];
+ r = bars[fh->input].bar[k][0];
+ g = bars[fh->input].bar[k][1];
+ b = bars[fh->input].bar[k][2];
is_yuv = 0;
switch (fh->fmt->fourcc) {
@@ -871,11 +945,40 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
}
}
+}
+
+/*FIXME: This seems to be generic enough to be at videodev2 */
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct vivi_fh *fh = priv;
+ struct videobuf_queue *q = &fh->vb_vidq;
+
+ int ret = vidioc_try_fmt_vid_cap(file, fh, f);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&q->vb_lock);
+
+ if (videobuf_queue_is_busy(&fh->vb_vidq)) {
+ dprintk(fh->dev, 1, "%s queue busy\n", __func__);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ fh->fmt = get_format(f);
+ fh->width = f->fmt.pix.width;
+ fh->height = f->fmt.pix.height;
+ fh->vb_vidq.field = f->fmt.pix.field;
+ fh->type = f->type;
+
+ precalculate_bars(fh);
+
ret = 0;
out:
mutex_unlock(&q->vb_lock);
- return (ret);
+ return ret;
}
static int vidioc_reqbufs(struct file *file, void *priv,
@@ -950,27 +1053,36 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *inp)
{
- if (inp->index != 0)
+ if (inp->index >= NUM_INPUTS)
return -EINVAL;
inp->type = V4L2_INPUT_TYPE_CAMERA;
inp->std = V4L2_STD_525_60;
- strcpy(inp->name, "Camera");
+ sprintf(inp->name, "Camera %u", inp->index);
return (0);
}
static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
{
- *i = 0;
+ struct vivi_fh *fh = priv;
+ struct vivi_dev *dev = fh->dev;
+
+ *i = dev->input;
return (0);
}
static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
{
- if (i > 0)
+ struct vivi_fh *fh = priv;
+ struct vivi_dev *dev = fh->dev;
+
+ if (i >= NUM_INPUTS)
return -EINVAL;
+ dev->input = i;
+ precalculate_bars(fh);
+
return (0);
}
@@ -993,12 +1105,14 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
+ struct vivi_fh *fh = priv;
+ struct vivi_dev *dev = fh->dev;
int i;
for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
if (ctrl->id == vivi_qctrl[i].id) {
- ctrl->value = qctl_regs[i];
- return (0);
+ ctrl->value = dev->qctl_regs[i];
+ return 0;
}
return -EINVAL;
@@ -1006,16 +1120,18 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
+ struct vivi_fh *fh = priv;
+ struct vivi_dev *dev = fh->dev;
int i;
for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
if (ctrl->id == vivi_qctrl[i].id) {
- if (ctrl->value < vivi_qctrl[i].minimum
- || ctrl->value > vivi_qctrl[i].maximum) {
- return (-ERANGE);
- }
- qctl_regs[i] = ctrl->value;
- return (0);
+ if (ctrl->value < vivi_qctrl[i].minimum ||
+ ctrl->value > vivi_qctrl[i].maximum) {
+ return -ERANGE;
+ }
+ dev->qctl_regs[i] = ctrl->value;
+ return 0;
}
return -EINVAL;
}
@@ -1026,32 +1142,20 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
static int vivi_open(struct file *file)
{
- int minor = video_devdata(file)->minor;
- struct vivi_dev *dev;
+ struct vivi_dev *dev = video_drvdata(file);
struct vivi_fh *fh = NULL;
- int i;
int retval = 0;
- printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor);
-
- lock_kernel();
- list_for_each_entry(dev, &vivi_devlist, vivi_devlist)
- if (dev->vfd->minor == minor)
- goto found;
- unlock_kernel();
- return -ENODEV;
-
-found:
mutex_lock(&dev->mutex);
dev->users++;
if (dev->users > 1) {
dev->users--;
- retval = -EBUSY;
- goto unlock;
+ mutex_unlock(&dev->mutex);
+ return -EBUSY;
}
- dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor,
+ dprintk(dev, 1, "open /dev/video%d type=%s users=%d\n", dev->vfd->num,
v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
/* allocate + initialize per filehandle data */
@@ -1059,14 +1163,11 @@ found:
if (NULL == fh) {
dev->users--;
retval = -ENOMEM;
- goto unlock;
}
-unlock:
mutex_unlock(&dev->mutex);
- if (retval) {
- unlock_kernel();
+
+ if (retval)
return retval;
- }
file->private_data = fh;
fh->dev = dev;
@@ -1076,10 +1177,6 @@ unlock:
fh->width = 640;
fh->height = 480;
- /* Put all controls at a sane state */
- for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
- qctl_regs[i] = vivi_qctrl[i].default_value;
-
/* Resets frame counters */
dev->h = 0;
dev->m = 0;
@@ -1095,7 +1192,6 @@ unlock:
sizeof(struct vivi_buffer), fh);
vivi_start_thread(fh);
- unlock_kernel();
return 0;
}
@@ -1151,32 +1247,6 @@ static int vivi_close(struct file *file)
return 0;
}
-static int vivi_release(void)
-{
- struct vivi_dev *dev;
- struct list_head *list;
-
- while (!list_empty(&vivi_devlist)) {
- list = vivi_devlist.next;
- list_del(list);
- dev = list_entry(list, struct vivi_dev, vivi_devlist);
-
- if (-1 != dev->vfd->minor) {
- printk(KERN_INFO "%s: unregistering /dev/video%d\n",
- VIVI_MODULE_NAME, dev->vfd->num);
- video_unregister_device(dev->vfd);
- } else {
- printk(KERN_INFO "%s: releasing /dev/video%d\n",
- VIVI_MODULE_NAME, dev->vfd->num);
- video_device_release(dev->vfd);
- }
-
- kfree(dev);
- }
-
- return 0;
-}
-
static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
{
struct vivi_fh *fh = file->private_data;
@@ -1239,87 +1309,130 @@ static struct video_device vivi_template = {
.tvnorms = V4L2_STD_525_60,
.current_norm = V4L2_STD_NTSC_M,
};
+
/* -----------------------------------------------------------------
Initialization and module stuff
------------------------------------------------------------------*/
-/* This routine allocates from 1 to n_devs virtual drivers.
+static int vivi_release(void)
+{
+ struct vivi_dev *dev;
+ struct list_head *list;
- The real maximum number of virtual drivers will depend on how many drivers
- will succeed. This is limited to the maximum number of devices that
- videodev supports. Since there are 64 minors for video grabbers, this is
- currently the theoretical maximum limit. However, a further limit does
- exist at videodev that forbids any driver to register more than 32 video
- grabbers.
- */
-static int __init vivi_init(void)
+ while (!list_empty(&vivi_devlist)) {
+ list = vivi_devlist.next;
+ list_del(list);
+ dev = list_entry(list, struct vivi_dev, vivi_devlist);
+
+ v4l2_info(&dev->v4l2_dev, "unregistering /dev/video%d\n",
+ dev->vfd->num);
+ video_unregister_device(dev->vfd);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ kfree(dev);
+ }
+
+ return 0;
+}
+
+static int __init vivi_create_instance(int inst)
{
- int ret = -ENOMEM, i;
struct vivi_dev *dev;
struct video_device *vfd;
+ int ret, i;
- if (n_devs <= 0)
- n_devs = 1;
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
- for (i = 0; i < n_devs; i++) {
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- break;
+ snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
+ "%s-%03d", VIVI_MODULE_NAME, inst);
+ ret = v4l2_device_register(NULL, &dev->v4l2_dev);
+ if (ret)
+ goto free_dev;
- /* init video dma queues */
- INIT_LIST_HEAD(&dev->vidq.active);
- init_waitqueue_head(&dev->vidq.wq);
+ /* init video dma queues */
+ INIT_LIST_HEAD(&dev->vidq.active);
+ init_waitqueue_head(&dev->vidq.wq);
- /* initialize locks */
- spin_lock_init(&dev->slock);
- mutex_init(&dev->mutex);
+ /* initialize locks */
+ spin_lock_init(&dev->slock);
+ mutex_init(&dev->mutex);
- vfd = video_device_alloc();
- if (!vfd) {
- kfree(dev);
- break;
- }
+ ret = -ENOMEM;
+ vfd = video_device_alloc();
+ if (!vfd)
+ goto unreg_dev;
- *vfd = vivi_template;
+ *vfd = vivi_template;
- ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
- if (ret < 0) {
- video_device_release(vfd);
- kfree(dev);
+ ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
+ if (ret < 0)
+ goto rel_vdev;
- /* If some registers succeeded, keep driver */
- if (i)
- ret = 0;
+ video_set_drvdata(vfd, dev);
- break;
- }
+ /* Set all controls to their default value. */
+ for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
+ dev->qctl_regs[i] = vivi_qctrl[i].default_value;
+
+ /* Now that everything is fine, let's add it to device list */
+ list_add_tail(&dev->vivi_devlist, &vivi_devlist);
+
+ snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
+ vivi_template.name, vfd->num);
+
+ if (video_nr >= 0)
+ video_nr++;
- /* Now that everything is fine, let's add it to device list */
- list_add_tail(&dev->vivi_devlist, &vivi_devlist);
+ dev->vfd = vfd;
+ v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n",
+ vfd->num);
+ return 0;
+
+rel_vdev:
+ video_device_release(vfd);
+unreg_dev:
+ v4l2_device_unregister(&dev->v4l2_dev);
+free_dev:
+ kfree(dev);
+ return ret;
+}
+
+/* This routine allocates from 1 to n_devs virtual drivers.
- snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
- vivi_template.name, vfd->minor);
+ The real maximum number of virtual drivers will depend on how many drivers
+ will succeed. This is limited to the maximum number of devices that
+ videodev supports, which is equal to VIDEO_NUM_DEVICES.
+ */
+static int __init vivi_init(void)
+{
+ int ret = 0, i;
- if (video_nr >= 0)
- video_nr++;
+ if (n_devs <= 0)
+ n_devs = 1;
- dev->vfd = vfd;
- printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n",
- VIVI_MODULE_NAME, vfd->num);
+ for (i = 0; i < n_devs; i++) {
+ ret = vivi_create_instance(i);
+ if (ret) {
+ /* If some instantiations succeeded, keep driver */
+ if (i)
+ ret = 0;
+ break;
+ }
}
if (ret < 0) {
- vivi_release();
printk(KERN_INFO "Error %d while loading vivi driver\n", ret);
- } else {
- printk(KERN_INFO "Video Technology Magazine Virtual Video "
+ return ret;
+ }
+
+ printk(KERN_INFO "Video Technology Magazine Virtual Video "
"Capture Board ver %u.%u.%u successfully loaded.\n",
(VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF,
VIVI_VERSION & 0xFF);
- /* n_devs will reflect the actual number of allocated devices */
- n_devs = i;
- }
+ /* n_devs will reflect the actual number of allocated devices */
+ n_devs = i;
return ret;
}
@@ -1331,19 +1444,3 @@ static void __exit vivi_exit(void)
module_init(vivi_init);
module_exit(vivi_exit);
-
-MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
-MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
-MODULE_LICENSE("Dual BSD/GPL");
-
-module_param(video_nr, uint, 0444);
-MODULE_PARM_DESC(video_nr, "video iminor start number");
-
-module_param(n_devs, uint, 0444);
-MODULE_PARM_DESC(n_devs, "number of video devices to create");
-
-module_param_named(debug, vivi_template.debug, int, 0444);
-MODULE_PARM_DESC(debug, "activates debug info");
-
-module_param(vid_limit, int, 0644);
-MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
index 5d73f66d9f55..42e23a4fa607 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/video/vp27smpx.c
@@ -129,11 +129,6 @@ static int vp27smpx_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int vp27smpx_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops vp27smpx_core_ops = {
@@ -206,8 +201,6 @@ MODULE_DEVICE_TABLE(i2c, vp27smpx_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "vp27smpx",
- .driverid = I2C_DRIVERID_VP27SMPX,
- .command = vp27smpx_command,
.probe = vp27smpx_probe,
.remove = vp27smpx_remove,
.id_table = vp27smpx_id,
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 67aa0db4b81a..2fa7e8bb5746 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -24,10 +24,10 @@
#include <linux/types.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
MODULE_AUTHOR("Laurent Pinchart");
@@ -37,14 +37,17 @@ static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
#define VPX_TIMEOUT_COUNT 10
/* ----------------------------------------------------------------------- */
struct vpx3220 {
+ struct v4l2_subdev sd;
unsigned char reg[255];
- int norm;
+ v4l2_std_id norm;
+ int ident;
int input;
int enable;
int bright;
@@ -53,30 +56,38 @@ struct vpx3220 {
int sat;
};
+static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct vpx3220, sd);
+}
+
static char *inputs[] = { "internal", "composite", "svideo" };
/* ----------------------------------------------------------------------- */
-static inline int vpx3220_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int vpx3220_write(struct v4l2_subdev *sd, u8 reg, u8 value)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct vpx3220 *decoder = i2c_get_clientdata(client);
decoder->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int vpx3220_read(struct i2c_client *client, u8 reg)
+static inline int vpx3220_read(struct v4l2_subdev *sd, u8 reg)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
return i2c_smbus_read_byte_data(client, reg);
}
-static int vpx3220_fp_status(struct i2c_client *client)
+static int vpx3220_fp_status(struct v4l2_subdev *sd)
{
unsigned char status;
unsigned int i;
for (i = 0; i < VPX_TIMEOUT_COUNT; i++) {
- status = vpx3220_read(client, 0x29);
+ status = vpx3220_read(sd, 0x29);
if (!(status & 4))
return 0;
@@ -90,57 +101,60 @@ static int vpx3220_fp_status(struct i2c_client *client)
return -1;
}
-static int vpx3220_fp_write(struct i2c_client *client, u8 fpaddr, u16 data)
+static int vpx3220_fp_write(struct v4l2_subdev *sd, u8 fpaddr, u16 data)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
/* Write the 16-bit address to the FPWR register */
if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) {
- v4l_dbg(1, debug, client, "%s: failed\n", __func__);
+ v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
return -1;
}
- if (vpx3220_fp_status(client) < 0)
+ if (vpx3220_fp_status(sd) < 0)
return -1;
/* Write the 16-bit data to the FPDAT register */
if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) {
- v4l_dbg(1, debug, client, "%s: failed\n", __func__);
+ v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
return -1;
}
return 0;
}
-static u16 vpx3220_fp_read(struct i2c_client *client, u16 fpaddr)
+static u16 vpx3220_fp_read(struct v4l2_subdev *sd, u16 fpaddr)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
s16 data;
/* Write the 16-bit address to the FPRD register */
if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) {
- v4l_dbg(1, debug, client, "%s: failed\n", __func__);
+ v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
return -1;
}
- if (vpx3220_fp_status(client) < 0)
+ if (vpx3220_fp_status(sd) < 0)
return -1;
/* Read the 16-bit data from the FPDAT register */
data = i2c_smbus_read_word_data(client, 0x28);
if (data == -1) {
- v4l_dbg(1, debug, client, "%s: failed\n", __func__);
+ v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
return -1;
}
return swab16(data);
}
-static int vpx3220_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
+static int vpx3220_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
{
u8 reg;
int ret = -1;
while (len >= 2) {
reg = *data++;
- ret = vpx3220_write(client, reg, *data++);
+ ret = vpx3220_write(sd, reg, *data++);
if (ret < 0)
break;
len -= 2;
@@ -149,7 +163,7 @@ static int vpx3220_write_block(struct i2c_client *client, const u8 *data, unsign
return ret;
}
-static int vpx3220_write_fp_block(struct i2c_client *client,
+static int vpx3220_write_fp_block(struct v4l2_subdev *sd,
const u16 *data, unsigned int len)
{
u8 reg;
@@ -157,7 +171,7 @@ static int vpx3220_write_fp_block(struct i2c_client *client,
while (len > 1) {
reg = *data++;
- ret |= vpx3220_fp_write(client, reg, *data++);
+ ret |= vpx3220_fp_write(sd, reg, *data++);
len -= 2;
}
@@ -259,276 +273,277 @@ static const unsigned short init_fp[] = {
0x4b, 0x298, /* PLL gain */
};
-static void vpx3220_dump_i2c(struct i2c_client *client)
-{
- int len = sizeof(init_common);
- const unsigned char *data = init_common;
- while (len > 1) {
- v4l_dbg(1, debug, client, "i2c reg 0x%02x data 0x%02x\n",
- *data, vpx3220_read(client, *data));
- data += 2;
- len -= 2;
- }
+static int vpx3220_init(struct v4l2_subdev *sd, u32 val)
+{
+ struct vpx3220 *decoder = to_vpx3220(sd);
+
+ vpx3220_write_block(sd, init_common, sizeof(init_common));
+ vpx3220_write_fp_block(sd, init_fp, sizeof(init_fp) >> 1);
+ if (decoder->norm & V4L2_STD_NTSC)
+ vpx3220_write_fp_block(sd, init_ntsc, sizeof(init_ntsc) >> 1);
+ else if (decoder->norm & V4L2_STD_PAL)
+ vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
+ else if (decoder->norm & V4L2_STD_SECAM)
+ vpx3220_write_fp_block(sd, init_secam, sizeof(init_secam) >> 1);
+ else
+ vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
+ return 0;
}
-static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int vpx3220_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
{
- struct vpx3220 *decoder = i2c_get_clientdata(client);
+ int res = V4L2_IN_ST_NO_SIGNAL, status;
+ v4l2_std_id std = 0;
- switch (cmd) {
- case 0:
- {
- vpx3220_write_block(client, init_common,
- sizeof(init_common));
- vpx3220_write_fp_block(client, init_fp,
- sizeof(init_fp) >> 1);
- switch (decoder->norm) {
- case VIDEO_MODE_NTSC:
- vpx3220_write_fp_block(client, init_ntsc,
- sizeof(init_ntsc) >> 1);
- break;
+ status = vpx3220_fp_read(sd, 0x0f3);
+
+ v4l2_dbg(1, debug, sd, "status: 0x%04x\n", status);
+
+ if (status < 0)
+ return status;
- case VIDEO_MODE_PAL:
- vpx3220_write_fp_block(client, init_pal,
- sizeof(init_pal) >> 1);
+ if ((status & 0x20) == 0) {
+ res = 0;
+
+ switch (status & 0x18) {
+ case 0x00:
+ case 0x10:
+ case 0x14:
+ case 0x18:
+ std = V4L2_STD_PAL;
break;
- case VIDEO_MODE_SECAM:
- vpx3220_write_fp_block(client, init_secam,
- sizeof(init_secam) >> 1);
+
+ case 0x08:
+ std = V4L2_STD_SECAM;
break;
- default:
- vpx3220_write_fp_block(client, init_pal,
- sizeof(init_pal) >> 1);
+
+ case 0x04:
+ case 0x0c:
+ case 0x1c:
+ std = V4L2_STD_NTSC;
break;
}
- break;
- }
-
- case DECODER_DUMP:
- {
- vpx3220_dump_i2c(client);
- break;
}
+ if (pstd)
+ *pstd = std;
+ if (pstatus)
+ *pstatus = status;
+ return 0;
+}
- case DECODER_GET_CAPABILITIES:
- {
- struct video_decoder_capability *cap = arg;
+static int vpx3220_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ v4l2_dbg(1, debug, sd, "querystd\n");
+ return vpx3220_status(sd, NULL, std);
+}
- v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n");
+static int vpx3220_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+ v4l2_dbg(1, debug, sd, "g_input_status\n");
+ return vpx3220_status(sd, status, NULL);
+}
- cap->flags = VIDEO_DECODER_PAL |
- VIDEO_DECODER_NTSC |
- VIDEO_DECODER_SECAM |
- VIDEO_DECODER_AUTO |
- VIDEO_DECODER_CCIR;
- cap->inputs = 3;
- cap->outputs = 1;
- break;
+static int vpx3220_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct vpx3220 *decoder = to_vpx3220(sd);
+ int temp_input;
+
+ /* Here we back up the input selection because it gets
+ overwritten when we fill the registers with the
+ choosen video norm */
+ temp_input = vpx3220_fp_read(sd, 0xf2);
+
+ v4l2_dbg(1, debug, sd, "s_std %llx\n", (unsigned long long)std);
+ if (std & V4L2_STD_NTSC) {
+ vpx3220_write_fp_block(sd, init_ntsc, sizeof(init_ntsc) >> 1);
+ v4l2_dbg(1, debug, sd, "norm switched to NTSC\n");
+ } else if (std & V4L2_STD_PAL) {
+ vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
+ v4l2_dbg(1, debug, sd, "norm switched to PAL\n");
+ } else if (std & V4L2_STD_SECAM) {
+ vpx3220_write_fp_block(sd, init_secam, sizeof(init_secam) >> 1);
+ v4l2_dbg(1, debug, sd, "norm switched to SECAM\n");
+ } else {
+ return -EINVAL;
}
- case DECODER_GET_STATUS:
- {
- int res = 0, status;
+ decoder->norm = std;
- v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n");
-
- status = vpx3220_fp_read(client, 0x0f3);
-
- v4l_dbg(1, debug, client, "status: 0x%04x\n", status);
-
- if (status < 0)
- return status;
+ /* And here we set the backed up video input again */
+ vpx3220_fp_write(sd, 0xf2, temp_input | 0x0010);
+ udelay(10);
+ return 0;
+}
- if ((status & 0x20) == 0) {
- res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR;
+static int vpx3220_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ int data;
- switch (status & 0x18) {
- case 0x00:
- case 0x10:
- case 0x14:
- case 0x18:
- res |= DECODER_STATUS_PAL;
- break;
+ /* RJ: route->input = 0: ST8 (PCTV) input
+ route->input = 1: COMPOSITE input
+ route->input = 2: SVHS input */
- case 0x08:
- res |= DECODER_STATUS_SECAM;
- break;
+ const int input[3][2] = {
+ {0x0c, 0},
+ {0x0d, 0},
+ {0x0e, 1}
+ };
- case 0x04:
- case 0x0c:
- case 0x1c:
- res |= DECODER_STATUS_NTSC;
- break;
- }
- }
+ if (route->input < 0 || route->input > 2)
+ return -EINVAL;
- *(int *) arg = res;
- break;
- }
+ v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[route->input]);
- case DECODER_SET_NORM:
- {
- int *iarg = arg, data;
- int temp_input;
-
- /* Here we back up the input selection because it gets
- overwritten when we fill the registers with the
- choosen video norm */
- temp_input = vpx3220_fp_read(client, 0xf2);
-
- v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg);
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- vpx3220_write_fp_block(client, init_ntsc,
- sizeof(init_ntsc) >> 1);
- v4l_dbg(1, debug, client, "norm switched to NTSC\n");
- break;
+ vpx3220_write(sd, 0x33, input[route->input][0]);
- case VIDEO_MODE_PAL:
- vpx3220_write_fp_block(client, init_pal,
- sizeof(init_pal) >> 1);
- v4l_dbg(1, debug, client, "norm switched to PAL\n");
- break;
+ data = vpx3220_fp_read(sd, 0xf2) & ~(0x0020);
+ if (data < 0)
+ return data;
+ /* 0x0010 is required to latch the setting */
+ vpx3220_fp_write(sd, 0xf2,
+ data | (input[route->input][1] << 5) | 0x0010);
- case VIDEO_MODE_SECAM:
- vpx3220_write_fp_block(client, init_secam,
- sizeof(init_secam) >> 1);
- v4l_dbg(1, debug, client, "norm switched to SECAM\n");
- break;
+ udelay(10);
+ return 0;
+}
- case VIDEO_MODE_AUTO:
- /* FIXME This is only preliminary support */
- data = vpx3220_fp_read(client, 0xf2) & 0x20;
- vpx3220_fp_write(client, 0xf2, 0x00c0 | data);
- v4l_dbg(1, debug, client, "norm switched to AUTO\n");
- break;
+static int vpx3220_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ v4l2_dbg(1, debug, sd, "s_stream %s\n", enable ? "on" : "off");
- default:
- return -EINVAL;
- }
- decoder->norm = *iarg;
+ vpx3220_write(sd, 0xf2, (enable ? 0x1b : 0x00));
+ return 0;
+}
- /* And here we set the backed up video input again */
- vpx3220_fp_write(client, 0xf2, temp_input | 0x0010);
- udelay(10);
+static int vpx3220_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
break;
- }
-
- case DECODER_SET_INPUT:
- {
- int *iarg = arg, data;
-
- /* RJ: *iarg = 0: ST8 (PCTV) input
- *iarg = 1: COMPOSITE input
- *iarg = 2: SVHS input */
-
- const int input[3][2] = {
- {0x0c, 0},
- {0x0d, 0},
- {0x0e, 1}
- };
- if (*iarg < 0 || *iarg > 2)
- return -EINVAL;
-
- v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]);
-
- vpx3220_write(client, 0x33, input[*iarg][0]);
-
- data = vpx3220_fp_read(client, 0xf2) & ~(0x0020);
- if (data < 0)
- return data;
- /* 0x0010 is required to latch the setting */
- vpx3220_fp_write(client, 0xf2,
- data | (input[*iarg][1] << 5) | 0x0010);
-
- udelay(10);
+ case V4L2_CID_CONTRAST:
+ v4l2_ctrl_query_fill(qc, 0, 63, 1, 32);
break;
- }
- case DECODER_SET_OUTPUT:
- {
- int *iarg = arg;
+ case V4L2_CID_SATURATION:
+ v4l2_ctrl_query_fill(qc, 0, 4095, 1, 2048);
+ break;
- /* not much choice of outputs */
- if (*iarg != 0) {
- return -EINVAL;
- }
+ case V4L2_CID_HUE:
+ v4l2_ctrl_query_fill(qc, -512, 511, 1, 0);
break;
- }
- case DECODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
- v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg);
+static int vpx3220_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct vpx3220 *decoder = to_vpx3220(sd);
- vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00));
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = decoder->bright;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = decoder->contrast;
break;
+ case V4L2_CID_SATURATION:
+ ctrl->value = decoder->sat;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value = decoder->hue;
+ break;
+ default:
+ return -EINVAL;
}
+ return 0;
+}
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
+static int vpx3220_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct vpx3220 *decoder = to_vpx3220(sd);
- if (decoder->bright != pic->brightness) {
- /* We want -128 to 128 we get 0-65535 */
- decoder->bright = pic->brightness;
- vpx3220_write(client, 0xe6,
- (decoder->bright - 32768) >> 8);
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ if (decoder->bright != ctrl->value) {
+ decoder->bright = ctrl->value;
+ vpx3220_write(sd, 0xe6, decoder->bright);
}
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 64 we get 0-65535 */
+ break;
+ case V4L2_CID_CONTRAST:
+ if (decoder->contrast != ctrl->value) {
/* Bit 7 and 8 is for noise shaping */
- decoder->contrast = pic->contrast;
- vpx3220_write(client, 0xe7,
- (decoder->contrast >> 10) + 192);
+ decoder->contrast = ctrl->value;
+ vpx3220_write(sd, 0xe7, decoder->contrast + 192);
}
- if (decoder->sat != pic->colour) {
- /* We want 0 to 4096 we get 0-65535 */
- decoder->sat = pic->colour;
- vpx3220_fp_write(client, 0xa0,
- decoder->sat >> 4);
+ break;
+ case V4L2_CID_SATURATION:
+ if (decoder->sat != ctrl->value) {
+ decoder->sat = ctrl->value;
+ vpx3220_fp_write(sd, 0xa0, decoder->sat);
}
- if (decoder->hue != pic->hue) {
- /* We want -512 to 512 we get 0-65535 */
- decoder->hue = pic->hue;
- vpx3220_fp_write(client, 0x1c,
- ((decoder->hue - 32768) >> 6) & 0xFFF);
+ break;
+ case V4L2_CID_HUE:
+ if (decoder->hue != ctrl->value) {
+ decoder->hue = ctrl->value;
+ vpx3220_fp_write(sd, 0x1c, decoder->hue);
}
break;
- }
-
default:
return -EINVAL;
}
-
return 0;
}
-static int vpx3220_init_client(struct i2c_client *client)
+static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
{
- vpx3220_write_block(client, init_common, sizeof(init_common));
- vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1);
- /* Default to PAL */
- vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1);
+ struct vpx3220 *decoder = to_vpx3220(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- return 0;
+ return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
}
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
+ .g_chip_ident = vpx3220_g_chip_ident,
+ .init = vpx3220_init,
+ .g_ctrl = vpx3220_g_ctrl,
+ .s_ctrl = vpx3220_s_ctrl,
+ .queryctrl = vpx3220_queryctrl,
+};
+
+static const struct v4l2_subdev_tuner_ops vpx3220_tuner_ops = {
+ .s_std = vpx3220_s_std,
+};
+
+static const struct v4l2_subdev_video_ops vpx3220_video_ops = {
+ .s_routing = vpx3220_s_routing,
+ .s_stream = vpx3220_s_stream,
+ .querystd = vpx3220_querystd,
+ .g_input_status = vpx3220_g_input_status,
+};
+
+static const struct v4l2_subdev_ops vpx3220_ops = {
+ .core = &vpx3220_core_ops,
+ .tuner = &vpx3220_tuner_ops,
+ .video = &vpx3220_video_ops,
+};
+
/* -----------------------------------------------------------------------
* Client management code
*/
-static unsigned short normal_i2c[] = { 0x86 >> 1, 0x8e >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
static int vpx3220_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct vpx3220 *decoder;
+ struct v4l2_subdev *sd;
const char *name = NULL;
u8 ver;
u16 pn;
@@ -541,18 +556,20 @@ static int vpx3220_probe(struct i2c_client *client,
decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
if (decoder == NULL)
return -ENOMEM;
- decoder->norm = VIDEO_MODE_PAL;
+ sd = &decoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &vpx3220_ops);
+ decoder->norm = V4L2_STD_PAL;
decoder->input = 0;
decoder->enable = 1;
decoder->bright = 32768;
decoder->contrast = 32768;
decoder->hue = 32768;
decoder->sat = 32768;
- i2c_set_clientdata(client, decoder);
ver = i2c_smbus_read_byte_data(client, 0x00);
pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
i2c_smbus_read_byte_data(client, 0x01);
+ decoder->ident = V4L2_IDENT_VPX3220A;
if (ver == 0xec) {
switch (pn) {
case 0x4680:
@@ -560,26 +577,34 @@ static int vpx3220_probe(struct i2c_client *client,
break;
case 0x4260:
name = "vpx3216b";
+ decoder->ident = V4L2_IDENT_VPX3216B;
break;
case 0x4280:
name = "vpx3214c";
+ decoder->ident = V4L2_IDENT_VPX3214C;
break;
}
}
if (name)
- v4l_info(client, "%s found @ 0x%x (%s)\n", name,
+ v4l2_info(sd, "%s found @ 0x%x (%s)\n", name,
client->addr << 1, client->adapter->name);
else
- v4l_info(client, "chip (%02x:%04x) found @ 0x%x (%s)\n",
+ v4l2_info(sd, "chip (%02x:%04x) found @ 0x%x (%s)\n",
ver, pn, client->addr << 1, client->adapter->name);
- vpx3220_init_client(client);
+ vpx3220_write_block(sd, init_common, sizeof(init_common));
+ vpx3220_write_fp_block(sd, init_fp, sizeof(init_fp) >> 1);
+ /* Default to PAL */
+ vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
return 0;
}
static int vpx3220_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_vpx3220(sd));
return 0;
}
@@ -593,8 +618,6 @@ MODULE_DEVICE_TABLE(i2c, vpx3220_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "vpx3220",
- .driverid = I2C_DRIVERID_VPX3220,
- .command = vpx3220_command,
.probe = vpx3220_probe,
.remove = vpx3220_remove,
.id_table = vpx3220_id,
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 038ff32b01b8..dcade619cbd8 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -57,7 +57,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/videodev2.h>
+#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <linux/parport.h>
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 105a832531f2..3b08bc4af909 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -42,6 +42,7 @@
#include <asm/page.h>
#include <asm/uaccess.h>
#include <linux/page-flags.h>
+#include <linux/videodev.h>
#include <media/v4l2-ioctl.h>
#include "w9968cf.h"
@@ -68,7 +69,6 @@ MODULE_VERSION(W9968CF_MODULE_VERSION);
MODULE_LICENSE(W9968CF_MODULE_LICENSE);
MODULE_SUPPORTED_DEVICE("Video");
-static int ovmod_load = W9968CF_OVMOD_LOAD;
static unsigned short simcams = W9968CF_SIMCAMS;
static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/
static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] =
@@ -111,9 +111,6 @@ static int specific_debug = W9968CF_SPECIFIC_DEBUG;
static unsigned int param_nv[24]; /* number of values per parameter */
-#ifdef CONFIG_MODULES
-module_param(ovmod_load, bool, 0644);
-#endif
module_param(simcams, ushort, 0644);
module_param_array(video_nr, short, &param_nv[0], 0444);
module_param_array(packet_size, uint, &param_nv[1], 0444);
@@ -144,18 +141,6 @@ module_param(debug, ushort, 0644);
module_param(specific_debug, bool, 0644);
#endif
-#ifdef CONFIG_MODULES
-MODULE_PARM_DESC(ovmod_load,
- "\n<0|1> Automatic 'ovcamchip' module loading."
- "\n0 disabled, 1 enabled."
- "\nIf enabled,'insmod' searches for the required 'ovcamchip'"
- "\nmodule in the system, according to its configuration, and"
- "\nattempts to load that module automatically. This action is"
- "\nperformed once as soon as the 'w9968cf' module is loaded"
- "\ninto memory."
- "\nDefault value is "__MODULE_STRING(W9968CF_OVMOD_LOAD)"."
- "\n");
-#endif
MODULE_PARM_DESC(simcams,
"\n<n> Number of cameras allowed to stream simultaneously."
"\nn may vary from 0 to "
@@ -443,8 +428,6 @@ static int w9968cf_i2c_smbus_xfer(struct i2c_adapter*, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data*);
static u32 w9968cf_i2c_func(struct i2c_adapter*);
-static int w9968cf_i2c_attach_inform(struct i2c_client*);
-static int w9968cf_i2c_detach_inform(struct i2c_client*);
/* Memory management */
static void* rvmalloc(unsigned long size);
@@ -1443,19 +1426,11 @@ w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
unsigned short flags, char read_write, u8 command,
int size, union i2c_smbus_data *data)
{
- struct w9968cf_device* cam = i2c_get_adapdata(adapter);
+ struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter);
+ struct w9968cf_device *cam = to_cam(v4l2_dev);
u8 i;
int err = 0;
- switch (addr) {
- case OV6xx0_SID:
- case OV7xx0_SID:
- break;
- default:
- DBG(4, "Rejected slave ID 0x%04X", addr)
- return -EINVAL;
- }
-
if (size == I2C_SMBUS_BYTE) {
/* Why addr <<= 1? See OVXXX0_SID defines in ovcamchip.h */
addr <<= 1;
@@ -1463,8 +1438,17 @@ w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
if (read_write == I2C_SMBUS_WRITE)
err = w9968cf_i2c_adap_write_byte(cam, addr, command);
else if (read_write == I2C_SMBUS_READ)
- err = w9968cf_i2c_adap_read_byte(cam,addr,&data->byte);
-
+ for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) {
+ err = w9968cf_i2c_adap_read_byte(cam, addr,
+ &data->byte);
+ if (err) {
+ if (w9968cf_smbus_refresh_bus(cam)) {
+ err = -EIO;
+ break;
+ }
+ } else
+ break;
+ }
} else if (size == I2C_SMBUS_BYTE_DATA) {
addr <<= 1;
@@ -1491,7 +1475,6 @@ w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
DBG(4, "Unsupported I2C transfer mode (%d)", size)
return -EINVAL;
}
-
return err;
}
@@ -1504,44 +1487,6 @@ static u32 w9968cf_i2c_func(struct i2c_adapter* adap)
}
-static int w9968cf_i2c_attach_inform(struct i2c_client* client)
-{
- struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
- int id = client->driver->id, err = 0;
-
- if (id == I2C_DRIVERID_OVCAMCHIP) {
- cam->sensor_client = client;
- err = w9968cf_sensor_init(cam);
- if (err) {
- cam->sensor_client = NULL;
- return err;
- }
- } else {
- DBG(4, "Rejected client [%s] with driver [%s]",
- client->name, client->driver->driver.name)
- return -EINVAL;
- }
-
- DBG(5, "I2C attach client [%s] with driver [%s]",
- client->name, client->driver->driver.name)
-
- return 0;
-}
-
-
-static int w9968cf_i2c_detach_inform(struct i2c_client* client)
-{
- struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
-
- if (cam->sensor_client == client)
- cam->sensor_client = NULL;
-
- DBG(5, "I2C detach client [%s]", client->name)
-
- return 0;
-}
-
-
static int w9968cf_i2c_init(struct w9968cf_device* cam)
{
int err = 0;
@@ -1554,15 +1499,13 @@ static int w9968cf_i2c_init(struct w9968cf_device* cam)
static struct i2c_adapter adap = {
.id = I2C_HW_SMBUS_W9968CF,
.owner = THIS_MODULE,
- .client_register = w9968cf_i2c_attach_inform,
- .client_unregister = w9968cf_i2c_detach_inform,
.algo = &algo,
};
memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
strcpy(cam->i2c_adapter.name, "w9968cf");
cam->i2c_adapter.dev.parent = &cam->usbdev->dev;
- i2c_set_adapdata(&cam->i2c_adapter, cam);
+ i2c_set_adapdata(&cam->i2c_adapter, &cam->v4l2_dev);
DBG(6, "Registering I2C adapter with kernel...")
@@ -2165,13 +2108,9 @@ w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val)
static int
w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
{
- struct i2c_client* c = cam->sensor_client;
- int rc = 0;
-
- if (!c || !c->driver || !c->driver->command)
- return -EINVAL;
+ int rc;
- rc = c->driver->command(c, cmd, arg);
+ rc = v4l2_subdev_call(cam->sensor_sd, core, ioctl, cmd, arg);
/* The I2C driver returns -EPERM on non-supported controls */
return (rc < 0 && rc != -EPERM) ? rc : 0;
}
@@ -2346,7 +2285,7 @@ static int w9968cf_sensor_init(struct w9968cf_device* cam)
goto error;
/* NOTE: Make sure width and height are a multiple of 16 */
- switch (cam->sensor_client->addr) {
+ switch (v4l2_i2c_subdev_addr(cam->sensor_sd)) {
case OV6xx0_SID:
cam->maxwidth = 352;
cam->maxheight = 288;
@@ -2651,6 +2590,7 @@ static void w9968cf_release_resources(struct w9968cf_device* cam)
w9968cf_deallocate_memory(cam);
kfree(cam->control_buffer);
kfree(cam->data_buffer);
+ v4l2_device_unregister(&cam->v4l2_dev);
mutex_unlock(&w9968cf_devlist_mutex);
}
@@ -3480,6 +3420,11 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
struct list_head* ptr;
u8 sc = 0; /* number of simultaneous cameras */
static unsigned short dev_nr; /* 0 - we are handling device number n */
+ static unsigned short addrs[] = {
+ OV7xx0_SID,
+ OV6xx0_SID,
+ I2C_CLIENT_END
+ };
if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[0].idVendor &&
le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
@@ -3495,12 +3440,14 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
if (!cam)
return -ENOMEM;
+ err = v4l2_device_register(&udev->dev, &cam->v4l2_dev);
+ if (err)
+ goto fail0;
+
mutex_init(&cam->dev_mutex);
mutex_lock(&cam->dev_mutex);
cam->usbdev = udev;
- /* NOTE: a local copy is used to avoid possible race conditions */
- memcpy(&cam->dev, &udev->dev, sizeof(struct device));
DBG(2, "%s detected", symbolic(camlist, mod_id))
@@ -3549,7 +3496,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
video_set_drvdata(cam->v4ldev, cam);
- cam->v4ldev->parent = &cam->dev;
+ cam->v4ldev->v4l2_dev = &cam->v4l2_dev;
err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
video_nr[dev_nr]);
@@ -3576,9 +3523,13 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
w9968cf_turn_on_led(cam);
w9968cf_i2c_init(cam);
+ cam->sensor_sd = v4l2_i2c_new_probed_subdev(&cam->i2c_adapter,
+ "ovcamchip", "ovcamchip", addrs);
usb_set_intfdata(intf, cam);
mutex_unlock(&cam->dev_mutex);
+
+ err = w9968cf_sensor_init(cam);
return 0;
fail: /* Free unused memory */
@@ -3587,6 +3538,8 @@ fail: /* Free unused memory */
if (cam->v4ldev)
video_device_release(cam->v4ldev);
mutex_unlock(&cam->dev_mutex);
+ v4l2_device_unregister(&cam->v4l2_dev);
+fail0:
kfree(cam);
return err;
}
@@ -3597,15 +3550,16 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf)
struct w9968cf_device* cam =
(struct w9968cf_device*)usb_get_intfdata(intf);
- down_write(&w9968cf_disconnect);
-
if (cam) {
+ down_write(&w9968cf_disconnect);
/* Prevent concurrent accesses to data */
mutex_lock(&cam->dev_mutex);
cam->disconnected = 1;
- DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id))
+ DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id));
+
+ v4l2_device_disconnect(&cam->v4l2_dev);
wake_up_interruptible_all(&cam->open);
@@ -3621,12 +3575,12 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf)
w9968cf_release_resources(cam);
mutex_unlock(&cam->dev_mutex);
+ up_write(&w9968cf_disconnect);
- if (!cam->users)
+ if (!cam->users) {
kfree(cam);
+ }
}
-
- up_write(&w9968cf_disconnect);
}
@@ -3650,9 +3604,6 @@ static int __init w9968cf_module_init(void)
KDBG(2, W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION)
KDBG(3, W9968CF_MODULE_AUTHOR)
- if (ovmod_load)
- request_module("ovcamchip");
-
if ((err = usb_register(&w9968cf_usb_driver)))
return err;
diff --git a/drivers/media/video/w9968cf.h b/drivers/media/video/w9968cf.h
index 30032e15e23c..fdfc6a4e1c8f 100644
--- a/drivers/media/video/w9968cf.h
+++ b/drivers/media/video/w9968cf.h
@@ -33,6 +33,7 @@
#include <linux/rwsem.h>
#include <linux/mutex.h>
+#include <media/v4l2-device.h>
#include <media/ovcamchip.h>
#include "w9968cf_vpp.h"
@@ -42,7 +43,6 @@
* Default values *
****************************************************************************/
-#define W9968CF_OVMOD_LOAD 1 /* automatic 'ovcamchip' module loading */
#define W9968CF_VPPMOD_LOAD 1 /* automatic 'w9968cf-vpp' module loading */
/* Comment/uncomment the following line to enable/disable debugging messages */
@@ -195,10 +195,9 @@ enum w9968cf_vpp_flag {
/* Main device driver structure */
struct w9968cf_device {
- struct device dev; /* device structure */
-
enum w9968cf_model_id id; /* private device identifier */
+ struct v4l2_device v4l2_dev;
struct video_device* v4ldev; /* -> V4L structure */
struct list_head v4llist; /* entry of the list of V4L cameras */
@@ -265,7 +264,7 @@ struct w9968cf_device {
/* I2C interface to kernel */
struct i2c_adapter i2c_adapter;
- struct i2c_client* sensor_client;
+ struct v4l2_subdev *sensor_sd;
/* Locks */
struct mutex dev_mutex, /* for probe, disconnect,open and close */
@@ -277,6 +276,11 @@ struct w9968cf_device {
char command[16]; /* name of the program holding the device */
};
+static inline struct w9968cf_device *to_cam(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct w9968cf_device, v4l2_dev);
+}
+
/****************************************************************************
* Macros for debugging *
@@ -291,14 +295,14 @@ struct w9968cf_device {
if ( ((specific_debug) && (debug == (level))) || \
((!specific_debug) && (debug >= (level))) ) { \
if ((level) == 1) \
- dev_err(&cam->dev, fmt "\n", ## args); \
+ v4l2_err(&cam->v4l2_dev, fmt "\n", ## args); \
else if ((level) == 2 || (level) == 3) \
- dev_info(&cam->dev, fmt "\n", ## args); \
+ v4l2_info(&cam->v4l2_dev, fmt "\n", ## args); \
else if ((level) == 4) \
- dev_warn(&cam->dev, fmt "\n", ## args); \
+ v4l2_warn(&cam->v4l2_dev, fmt "\n", ## args); \
else if ((level) >= 5) \
- dev_info(&cam->dev, "[%s:%d] " fmt "\n", \
- __func__, __LINE__ , ## args); \
+ v4l2_info(&cam->v4l2_dev, "[%s:%d] " fmt "\n", \
+ __func__, __LINE__ , ## args); \
} \
}
/* For generic kernel (not device specific) messages */
@@ -321,7 +325,7 @@ struct w9968cf_device {
#undef PDBG
#define PDBG(fmt, args...) \
-dev_info(&cam->dev, "[%s:%d] " fmt "\n", __func__, __LINE__ , ## args);
+v4l2_info(&cam->v4l2_dev, "[%s:%d] " fmt "\n", __func__, __LINE__ , ## args);
#undef PDBGG
#define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index f2864d5cd180..b572ce288e14 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -252,11 +252,6 @@ static int wm8739_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int wm8739_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops wm8739_core_ops = {
@@ -343,8 +338,6 @@ MODULE_DEVICE_TABLE(i2c, wm8739_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "wm8739",
- .driverid = I2C_DRIVERID_WM8739,
- .command = wm8739_command,
.probe = wm8739_probe,
.remove = wm8739_remove,
.id_table = wm8739_id,
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index 53fcd42843e0..eddf11abe1d9 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -34,15 +34,12 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("wm8775 driver");
MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
MODULE_LICENSE("GPL");
-static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
/* ----------------------------------------------------------------------- */
@@ -161,11 +158,6 @@ static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fre
return 0;
}
-static int wm8775_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops wm8775_core_ops = {
@@ -268,8 +260,6 @@ MODULE_DEVICE_TABLE(i2c, wm8775_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "wm8775",
- .driverid = I2C_DRIVERID_WM8775,
- .command = wm8775_command,
.probe = wm8775_probe,
.remove = wm8775_remove,
.id_table = wm8775_id,
diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h
index b0cd49c438a3..3a408de91b9c 100644
--- a/drivers/media/video/zc0301/zc0301_sensor.h
+++ b/drivers/media/video/zc0301/zc0301_sensor.h
@@ -58,12 +58,20 @@ zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor);
.idProduct = (prod), \
.bInterfaceClass = (intclass)
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
#define ZC0301_ID_TABLE \
static const struct usb_device_id zc0301_id_table[] = { \
{ ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \
{ ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \
{ } \
};
+#else
+#define ZC0301_ID_TABLE \
+static const struct usb_device_id zc0301_id_table[] = { \
+ { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \
+ { } \
+};
+#endif
/*****************************************************************************/
diff --git a/drivers/media/video/zoran/Kconfig b/drivers/media/video/zoran/Kconfig
index 8666e19f31a7..fd4120e4c104 100644
--- a/drivers/media/video/zoran/Kconfig
+++ b/drivers/media/video/zoran/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_ZORAN
tristate "Zoran ZR36057/36067 Video For Linux"
- depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && VIRT_TO_BUS
+ depends on PCI && I2C_ALGOBIT && VIDEO_V4L2 && VIRT_TO_BUS
help
Say Y for support for MJPEG capture cards based on the Zoran
36057/36067 PCI controller chipset. This includes the Iomega
@@ -32,7 +32,7 @@ config VIDEO_ZORAN_ZR36060
config VIDEO_ZORAN_BUZ
tristate "Iomega Buz support"
depends on VIDEO_ZORAN_ZR36060
- select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO
help
Support for the Iomega Buz MJPEG capture/playback card.
@@ -58,7 +58,7 @@ config VIDEO_ZORAN_LML33
config VIDEO_ZORAN_LML33R10
tristate "Linux Media Labs LML33R10 support"
depends on VIDEO_ZORAN_ZR36060
- select VIDEO_SAA7114 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO
help
support for the Linux Media Labs LML33R10 MJPEG capture/playback
@@ -66,7 +66,7 @@ config VIDEO_ZORAN_LML33R10
config VIDEO_ZORAN_AVS6EYES
tristate "AverMedia 6 Eyes support (EXPERIMENTAL)"
- depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1
+ depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL
select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_BT866 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO
diff --git a/drivers/media/video/zoran/videocodec.h b/drivers/media/video/zoran/videocodec.h
index 97a3bbeda505..5c27b251354e 100644
--- a/drivers/media/video/zoran/videocodec.h
+++ b/drivers/media/video/zoran/videocodec.h
@@ -97,7 +97,7 @@
available) - it returns 0 if the mode is possible
set_size -> this fn-ref. sets the norm and image size for
compression/decompression (returns 0 on success)
- the norm param is defined in videodev.h (VIDEO_MODE_*)
+ the norm param is defined in videodev2.h (V4L2_STD_*)
additional setup may be available, too - but the codec should work with
some default values even without this
@@ -144,9 +144,8 @@ M zr36055[1] 0001 0000c001 00000000 (zr36050[1])
#ifndef __LINUX_VIDEOCODEC_H
#define __LINUX_VIDEOCODEC_H
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
-//should be in videodev.h ??? (VID_DO_....)
#define CODEC_DO_COMPRESSION 0
#define CODEC_DO_EXPANSION 1
@@ -237,10 +236,6 @@ struct vfe_settings {
__u32 width, height; /* Area to capture */
__u16 decimation; /* Decimation divider */
__u16 flags; /* Flags for capture */
-/* flags are the same as in struct video_capture - see videodev.h:
-#define VIDEO_CAPTURE_ODD 0
-#define VIDEO_CAPTURE_EVEN 1
-*/
__u16 quality; /* quality of the video */
};
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h
index e873a916250f..afecf32f1a87 100644
--- a/drivers/media/video/zoran/zoran.h
+++ b/drivers/media/video/zoran/zoran.h
@@ -31,6 +31,8 @@
#ifndef _BUZ_H_
#define _BUZ_H_
+#include <media/v4l2-device.h>
+
struct zoran_requestbuffers {
unsigned long count; /* Number of buffers for MJPEG grabbing */
unsigned long size; /* Size PER BUFFER in bytes */
@@ -170,7 +172,7 @@ Private IOCTL to set up for displaying MJPEG
#endif
#define V4L_MASK_FRAME (V4L_MAX_FRAME - 1)
-#define MAX_KMALLOC_MEM (128*1024)
+#define MAX_FRAME (BUZ_MAX_FRAME > VIDEO_MAX_FRAME ? BUZ_MAX_FRAME : VIDEO_MAX_FRAME)
#include "zr36057.h"
@@ -240,9 +242,6 @@ enum gpcs_type {
struct zoran_format {
char *name;
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- int palette;
-#endif
__u32 fourcc;
int colorspace;
int depth;
@@ -283,21 +282,21 @@ struct zoran_mapping {
int count;
};
-struct zoran_jpg_buffer {
- struct zoran_mapping *map;
- __le32 *frag_tab; /* addresses of frag table */
- u32 frag_tab_bus; /* same value cached to save time in ISR */
- enum zoran_buffer_state state; /* non-zero if corresponding buffer is in use in grab queue */
- struct zoran_sync bs; /* DONE: info to return to application */
-};
-
-struct zoran_v4l_buffer {
+struct zoran_buffer {
struct zoran_mapping *map;
- char *fbuffer; /* virtual address of frame buffer */
- unsigned long fbuffer_phys; /* physical address of frame buffer */
- unsigned long fbuffer_bus; /* bus address of frame buffer */
- enum zoran_buffer_state state; /* state: unused/pending/done */
- struct zoran_sync bs; /* DONE: info to return to application */
+ enum zoran_buffer_state state; /* state: unused/pending/dma/done */
+ struct zoran_sync bs; /* DONE: info to return to application */
+ union {
+ struct {
+ __le32 *frag_tab; /* addresses of frag table */
+ u32 frag_tab_bus; /* same value cached to save time in ISR */
+ } jpg;
+ struct {
+ char *fbuffer; /* virtual address of frame buffer */
+ unsigned long fbuffer_phys;/* physical address of frame buffer */
+ unsigned long fbuffer_bus;/* bus address of frame buffer */
+ } v4l;
+ };
};
enum zoran_lock_activity {
@@ -307,21 +306,13 @@ enum zoran_lock_activity {
};
/* buffer collections */
-struct zoran_jpg_struct {
+struct zoran_buffer_col {
enum zoran_lock_activity active; /* feature currently in use? */
- struct zoran_jpg_buffer buffer[BUZ_MAX_FRAME]; /* buffers */
- int num_buffers, buffer_size;
+ unsigned int num_buffers, buffer_size;
+ struct zoran_buffer buffer[MAX_FRAME]; /* buffers */
u8 allocated; /* Flag if buffers are allocated */
- u8 ready_to_be_freed; /* hack - see zoran_driver.c */
u8 need_contiguous; /* Flag if contiguous buffers are needed */
-};
-
-struct zoran_v4l_struct {
- enum zoran_lock_activity active; /* feature currently in use? */
- struct zoran_v4l_buffer buffer[VIDEO_MAX_FRAME]; /* buffers */
- int num_buffers, buffer_size;
- u8 allocated; /* Flag if buffers are allocated */
- u8 ready_to_be_freed; /* hack - see zoran_driver.c */
+ /* only applies to jpg buffers, raw buffers are always contiguous */
};
struct zoran;
@@ -330,23 +321,27 @@ struct zoran;
struct zoran_fh {
struct zoran *zr;
- enum zoran_map_mode map_mode; /* Flag which bufferset will map by next mmap() */
+ enum zoran_map_mode map_mode; /* Flag which bufferset will map by next mmap() */
struct zoran_overlay_settings overlay_settings;
- u32 *overlay_mask; /* overlay mask */
- enum zoran_lock_activity overlay_active; /* feature currently in use? */
+ u32 *overlay_mask; /* overlay mask */
+ enum zoran_lock_activity overlay_active;/* feature currently in use? */
- struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */
- struct zoran_v4l_struct v4l_buffers; /* V4L buffers' info */
+ struct zoran_buffer_col buffers; /* buffers' info */
+ struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */
struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */
- struct zoran_jpg_struct jpg_buffers; /* MJPEG buffers' info */
};
struct card_info {
enum card_type type;
char name[32];
- u16 i2c_decoder, i2c_encoder; /* I2C types */
+ const char *i2c_decoder; /* i2c decoder device */
+ const char *mod_decoder; /* i2c decoder module */
+ const unsigned short *addrs_decoder;
+ const char *i2c_encoder; /* i2c encoder device */
+ const char *mod_encoder; /* i2c encoder module */
+ const unsigned short *addrs_encoder;
u16 video_vfe, video_codec; /* videocodec types */
u16 audio_chip; /* audio type */
@@ -356,7 +351,7 @@ struct card_info {
char name[32];
} input[BUZ_MAX_INPUT];
- int norms;
+ v4l2_std_id norms;
struct tvnorm *tvn[3]; /* supported TV norms */
u32 jpeg_int; /* JPEG interrupt */
@@ -377,14 +372,15 @@ struct card_info {
};
struct zoran {
+ struct v4l2_device v4l2_dev;
struct video_device *video_dev;
struct i2c_adapter i2c_adapter; /* */
struct i2c_algo_bit_data i2c_algo; /* */
u32 i2cbr;
- struct i2c_client *decoder; /* video decoder i2c client */
- struct i2c_client *encoder; /* video encoder i2c client */
+ struct v4l2_subdev *decoder; /* video decoder sub-device */
+ struct v4l2_subdev *encoder; /* video encoder sub-device */
struct videocodec *codec; /* video codec */
struct videocodec *vfe; /* video front end */
@@ -405,9 +401,15 @@ struct zoran {
spinlock_t spinlock; /* Spinlock */
/* Video for Linux parameters */
- int input, norm; /* card's norm and input - norm=VIDEO_MODE_* */
- int hue, saturation, contrast, brightness; /* Current picture params */
- struct video_buffer buffer; /* Current buffer params */
+ int input; /* card's norm and input - norm=VIDEO_MODE_* */
+ v4l2_std_id norm;
+
+ /* Current buffer params */
+ void *vbuf_base;
+ int vbuf_height, vbuf_width;
+ int vbuf_depth;
+ int vbuf_bytesperline;
+
struct zoran_overlay_settings overlay_settings;
u32 *overlay_mask; /* overlay mask */
enum zoran_lock_activity overlay_active; /* feature currently in use? */
@@ -427,7 +429,7 @@ struct zoran {
unsigned long v4l_pend_tail;
unsigned long v4l_sync_tail;
int v4l_pend[V4L_MAX_FRAME];
- struct zoran_v4l_struct v4l_buffers; /* V4L buffers' info */
+ struct zoran_buffer_col v4l_buffers; /* V4L buffers' info */
/* Buz MJPEG parameters */
enum zoran_codec_mode codec_mode; /* status of codec */
@@ -454,7 +456,7 @@ struct zoran {
int jpg_pend[BUZ_MAX_FRAME];
/* array indexed by frame number */
- struct zoran_jpg_struct jpg_buffers; /* MJPEG buffers' info */
+ struct zoran_buffer_col jpg_buffers; /* MJPEG buffers' info */
/* Additional stuff for testing */
#ifdef CONFIG_PROC_FS
@@ -488,6 +490,11 @@ struct zoran {
wait_queue_head_t test_q;
};
+static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct zoran, v4l2_dev);
+}
+
/* There was something called _ALPHA_BUZ that used the PCI address instead of
* the kernel iomapped address for btread/btwrite. */
#define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr))
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 5d2f090aa0f8..f91bba435ed5 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -38,8 +38,7 @@
#include <linux/proc_fs.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
#include <linux/spinlock.h>
#include <linux/sem.h>
#include <linux/kmod.h>
@@ -47,11 +46,10 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
-#include <linux/video_decoder.h>
-#include <linux/video_encoder.h>
#include <linux/mutex.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
+#include <media/v4l2-common.h>
+#include <media/bt819.h>
#include "videocodec.h"
#include "zoran.h"
@@ -108,25 +106,8 @@ static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(video_nr, int, NULL, 0444);
MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
-/*
- Number and size of grab buffers for Video 4 Linux
- The vast majority of applications should not need more than 2,
- the very popular BTTV driver actually does ONLY have 2.
- Time sensitive applications might need more, the maximum
- is VIDEO_MAX_FRAME (defined in <linux/videodev.h>).
-
- The size is set so that the maximum possible request
- can be satisfied. Decrease it, if bigphys_area alloc'd
- memory is low. If you don't have the bigphys_area patch,
- set it to 128 KB. Will you allow only to grab small
- images with V4L, but that's better than nothing.
-
- v4l_bufsize has to be given in KB !
-
-*/
-
-int v4l_nbufs = 2;
-int v4l_bufsize = 128; /* Everybody should be able to work with this setting */
+int v4l_nbufs = 4;
+int v4l_bufsize = 864; /* Everybody should be able to work with this setting */
module_param(v4l_nbufs, int, 0644);
MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use");
module_param(v4l_bufsize, int, 0644);
@@ -273,7 +254,7 @@ zr36016_write (struct videocodec *codec,
static void
dc10_init (struct zoran *zr)
{
- dprintk(3, KERN_DEBUG "%s: dc10_init()\n", ZR_DEVNAME(zr));
+ dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
/* Pixel clock selection */
GPIO(zr, 4, 0);
@@ -285,13 +266,13 @@ dc10_init (struct zoran *zr)
static void
dc10plus_init (struct zoran *zr)
{
- dprintk(3, KERN_DEBUG "%s: dc10plus_init()\n", ZR_DEVNAME(zr));
+ dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
}
static void
buz_init (struct zoran *zr)
{
- dprintk(3, KERN_DEBUG "%s: buz_init()\n", ZR_DEVNAME(zr));
+ dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
/* some stuff from Iomega */
pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15);
@@ -302,7 +283,7 @@ buz_init (struct zoran *zr)
static void
lml33_init (struct zoran *zr)
{
- dprintk(3, KERN_DEBUG "%s: lml33_init()\n", ZR_DEVNAME(zr));
+ dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
GPIO(zr, 2, 1); // Set Composite input/output
}
@@ -332,50 +313,6 @@ avs6eyes_init (struct zoran *zr)
}
static char *
-i2cid_to_modulename (u16 i2c_id)
-{
- char *name = NULL;
-
- switch (i2c_id) {
- case I2C_DRIVERID_SAA7110:
- name = "saa7110";
- break;
- case I2C_DRIVERID_SAA7111A:
- name = "saa7111";
- break;
- case I2C_DRIVERID_SAA7114:
- name = "saa7114";
- break;
- case I2C_DRIVERID_SAA7185B:
- name = "saa7185";
- break;
- case I2C_DRIVERID_ADV7170:
- name = "adv7170";
- break;
- case I2C_DRIVERID_ADV7175:
- name = "adv7175";
- break;
- case I2C_DRIVERID_BT819:
- name = "bt819";
- break;
- case I2C_DRIVERID_BT856:
- name = "bt856";
- break;
- case I2C_DRIVERID_BT866:
- name = "bt866";
- break;
- case I2C_DRIVERID_VPX3220:
- name = "vpx3220";
- break;
- case I2C_DRIVERID_KS0127:
- name = "ks0127";
- break;
- }
-
- return name;
-}
-
-static char *
codecid_to_modulename (u16 codecid)
{
char *name = NULL;
@@ -425,11 +362,24 @@ static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 }
static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 };
static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 };
+static const unsigned short vpx3220_addrs[] = { 0x43, 0x47, I2C_CLIENT_END };
+static const unsigned short saa7110_addrs[] = { 0x4e, 0x4f, I2C_CLIENT_END };
+static const unsigned short saa7111_addrs[] = { 0x25, 0x24, I2C_CLIENT_END };
+static const unsigned short saa7114_addrs[] = { 0x21, 0x20, I2C_CLIENT_END };
+static const unsigned short adv717x_addrs[] = { 0x6a, 0x6b, 0x2a, 0x2b, I2C_CLIENT_END };
+static const unsigned short ks0127_addrs[] = { 0x6c, 0x6d, I2C_CLIENT_END };
+static const unsigned short saa7185_addrs[] = { 0x44, I2C_CLIENT_END };
+static const unsigned short bt819_addrs[] = { 0x45, I2C_CLIENT_END };
+static const unsigned short bt856_addrs[] = { 0x44, I2C_CLIENT_END };
+static const unsigned short bt866_addrs[] = { 0x44, I2C_CLIENT_END };
+
static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{
.type = DC10_old,
.name = "DC10(old)",
- .i2c_decoder = I2C_DRIVERID_VPX3220,
+ .i2c_decoder = "vpx3220a",
+ .mod_decoder = "vpx3220",
+ .addrs_decoder = vpx3220_addrs,
.video_codec = CODEC_TYPE_ZR36050,
.video_vfe = CODEC_TYPE_ZR36016,
@@ -439,7 +389,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 2, "S-Video" },
{ 0, "Internal/comp" }
},
- .norms = 3,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel_dc10,
&f60sqpixel_dc10,
@@ -457,8 +407,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC10_new,
.name = "DC10(new)",
- .i2c_decoder = I2C_DRIVERID_SAA7110,
- .i2c_encoder = I2C_DRIVERID_ADV7175,
+ .i2c_decoder = "saa7110",
+ .mod_decoder = "saa7110",
+ .addrs_decoder = saa7110_addrs,
+ .i2c_encoder = "adv7175",
+ .mod_encoder = "adv7175",
+ .addrs_encoder = adv717x_addrs,
.video_codec = CODEC_TYPE_ZR36060,
.inputs = 3,
@@ -467,7 +421,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 7, "S-Video" },
{ 5, "Internal/comp" }
},
- .norms = 3,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel,
&f60sqpixel,
@@ -484,8 +438,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC10plus,
.name = "DC10plus",
- .i2c_decoder = I2C_DRIVERID_SAA7110,
- .i2c_encoder = I2C_DRIVERID_ADV7175,
+ .i2c_decoder = "saa7110",
+ .mod_decoder = "saa7110",
+ .addrs_decoder = saa7110_addrs,
+ .i2c_encoder = "adv7175",
+ .mod_encoder = "adv7175",
+ .addrs_encoder = adv717x_addrs,
.video_codec = CODEC_TYPE_ZR36060,
.inputs = 3,
@@ -494,7 +452,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 7, "S-Video" },
{ 5, "Internal/comp" }
},
- .norms = 3,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel,
&f60sqpixel,
@@ -512,8 +470,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC30,
.name = "DC30",
- .i2c_decoder = I2C_DRIVERID_VPX3220,
- .i2c_encoder = I2C_DRIVERID_ADV7175,
+ .i2c_decoder = "vpx3220a",
+ .mod_decoder = "vpx3220",
+ .addrs_decoder = vpx3220_addrs,
+ .i2c_encoder = "adv7175",
+ .mod_encoder = "adv7175",
+ .addrs_encoder = adv717x_addrs,
.video_codec = CODEC_TYPE_ZR36050,
.video_vfe = CODEC_TYPE_ZR36016,
@@ -523,7 +485,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 2, "S-Video" },
{ 0, "Internal/comp" }
},
- .norms = 3,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel_dc10,
&f60sqpixel_dc10,
@@ -541,8 +503,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC30plus,
.name = "DC30plus",
- .i2c_decoder = I2C_DRIVERID_VPX3220,
- .i2c_encoder = I2C_DRIVERID_ADV7175,
+ .i2c_decoder = "vpx3220a",
+ .mod_decoder = "vpx3220",
+ .addrs_decoder = vpx3220_addrs,
+ .i2c_encoder = "adv7175",
+ .mod_encoder = "adv7175",
+ .addrs_encoder = adv717x_addrs,
.video_codec = CODEC_TYPE_ZR36050,
.video_vfe = CODEC_TYPE_ZR36016,
@@ -552,7 +518,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 2, "S-Video" },
{ 0, "Internal/comp" }
},
- .norms = 3,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel_dc10,
&f60sqpixel_dc10,
@@ -570,8 +536,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = LML33,
.name = "LML33",
- .i2c_decoder = I2C_DRIVERID_BT819,
- .i2c_encoder = I2C_DRIVERID_BT856,
+ .i2c_decoder = "bt819a",
+ .mod_decoder = "bt819",
+ .addrs_decoder = bt819_addrs,
+ .i2c_encoder = "bt856",
+ .mod_encoder = "bt856",
+ .addrs_encoder = bt856_addrs,
.video_codec = CODEC_TYPE_ZR36060,
.inputs = 2,
@@ -579,7 +549,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 0, "Composite" },
{ 7, "S-Video" }
},
- .norms = 2,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
.tvn = {
&f50ccir601_lml33,
&f60ccir601_lml33,
@@ -597,8 +567,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = LML33R10,
.name = "LML33R10",
- .i2c_decoder = I2C_DRIVERID_SAA7114,
- .i2c_encoder = I2C_DRIVERID_ADV7170,
+ .i2c_decoder = "saa7114",
+ .mod_decoder = "saa7115",
+ .addrs_decoder = saa7114_addrs,
+ .i2c_encoder = "adv7170",
+ .mod_encoder = "adv7170",
+ .addrs_encoder = adv717x_addrs,
.video_codec = CODEC_TYPE_ZR36060,
.inputs = 2,
@@ -606,7 +580,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 0, "Composite" },
{ 7, "S-Video" }
},
- .norms = 2,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
.tvn = {
&f50ccir601_lm33r10,
&f60ccir601_lm33r10,
@@ -624,8 +598,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = BUZ,
.name = "Buz",
- .i2c_decoder = I2C_DRIVERID_SAA7111A,
- .i2c_encoder = I2C_DRIVERID_SAA7185B,
+ .i2c_decoder = "saa7111",
+ .mod_decoder = "saa7115",
+ .addrs_decoder = saa7111_addrs,
+ .i2c_encoder = "saa7185",
+ .mod_encoder = "saa7185",
+ .addrs_encoder = saa7185_addrs,
.video_codec = CODEC_TYPE_ZR36060,
.inputs = 2,
@@ -633,7 +611,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 3, "Composite" },
{ 7, "S-Video" }
},
- .norms = 3,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50ccir601,
&f60ccir601,
@@ -653,8 +631,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
.name = "6-Eyes",
/* AverMedia chose not to brand the 6-Eyes. Thus it
can't be autodetected, and requires card=x. */
- .i2c_decoder = I2C_DRIVERID_KS0127,
- .i2c_encoder = I2C_DRIVERID_BT866,
+ .i2c_decoder = "ks0127",
+ .mod_decoder = "ks0127",
+ .addrs_decoder = ks0127_addrs,
+ .i2c_encoder = "bt866",
+ .mod_encoder = "bt866",
+ .addrs_encoder = bt866_addrs,
.video_codec = CODEC_TYPE_ZR36060,
.inputs = 10,
@@ -670,7 +652,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{10, "S-Video 3" },
{15, "YCbCr" }
},
- .norms = 2,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
.tvn = {
&f50ccir601_avs6eyes,
&f60ccir601_avs6eyes,
@@ -735,69 +717,6 @@ zoran_i2c_setscl (void *data,
btwrite(zr->i2cbr, ZR36057_I2CBR);
}
-static int
-zoran_i2c_client_register (struct i2c_client *client)
-{
- struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter);
- int res = 0;
-
- dprintk(2,
- KERN_DEBUG "%s: i2c_client_register() - driver id = %d\n",
- ZR_DEVNAME(zr), client->driver->id);
-
- mutex_lock(&zr->resource_lock);
-
- if (zr->user > 0) {
- /* we're already busy, so we keep a reference to
- * them... Could do a lot of stuff here, but this
- * is easiest. (Did I ever mention I'm a lazy ass?)
- */
- res = -EBUSY;
- goto clientreg_unlock_and_return;
- }
-
- if (client->driver->id == zr->card.i2c_decoder)
- zr->decoder = client;
- else if (client->driver->id == zr->card.i2c_encoder)
- zr->encoder = client;
- else {
- res = -ENODEV;
- goto clientreg_unlock_and_return;
- }
-
-clientreg_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-static int
-zoran_i2c_client_unregister (struct i2c_client *client)
-{
- struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter);
- int res = 0;
-
- dprintk(2, KERN_DEBUG "%s: i2c_client_unregister()\n", ZR_DEVNAME(zr));
-
- mutex_lock(&zr->resource_lock);
-
- if (zr->user > 0) {
- res = -EBUSY;
- goto clientunreg_unlock_and_return;
- }
-
- /* try to locate it */
- if (client == zr->encoder) {
- zr->encoder = NULL;
- } else if (client == zr->decoder) {
- zr->decoder = NULL;
- snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%d]", zr->id);
- }
-clientunreg_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
-}
-
static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
.setsda = zoran_i2c_setsda,
.setscl = zoran_i2c_setscl,
@@ -813,13 +732,10 @@ zoran_register_i2c (struct zoran *zr)
memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
sizeof(struct i2c_algo_bit_data));
zr->i2c_algo.data = zr;
- zr->i2c_adapter.class = I2C_CLASS_TV_ANALOG;
zr->i2c_adapter.id = I2C_HW_B_ZR36067;
- zr->i2c_adapter.client_register = zoran_i2c_client_register;
- zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister;
strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
sizeof(zr->i2c_adapter.name));
- i2c_set_adapdata(&zr->i2c_adapter, zr);
+ i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev);
zr->i2c_adapter.algo_data = &zr->i2c_algo;
zr->i2c_adapter.dev.parent = &zr->pci_dev->dev;
return i2c_bit_add_bus(&zr->i2c_adapter);
@@ -835,19 +751,20 @@ zoran_unregister_i2c (struct zoran *zr)
int
zoran_check_jpg_settings (struct zoran *zr,
- struct zoran_jpg_settings *settings)
+ struct zoran_jpg_settings *settings,
+ int try)
{
int err = 0, err0 = 0;
dprintk(4,
KERN_DEBUG
- "%s: check_jpg_settings() - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n",
- ZR_DEVNAME(zr), settings->decimation, settings->HorDcm,
+ "%s: %s - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n",
+ ZR_DEVNAME(zr), __func__, settings->decimation, settings->HorDcm,
settings->VerDcm, settings->TmpDcm);
dprintk(4,
KERN_DEBUG
- "%s: check_jpg_settings() - x: %d, y: %d, w: %d, y: %d\n",
- ZR_DEVNAME(zr), settings->img_x, settings->img_y,
+ "%s: %s - x: %d, y: %d, w: %d, y: %d\n",
+ ZR_DEVNAME(zr), __func__, settings->img_x, settings->img_y,
settings->img_width, settings->img_height);
/* Check decimation, set default values for decimation = 1, 2, 4 */
switch (settings->decimation) {
@@ -879,8 +796,8 @@ zoran_check_jpg_settings (struct zoran *zr,
if (zr->card.type == DC10_new) {
dprintk(1,
KERN_DEBUG
- "%s: check_jpg_settings() - HDec by 4 is not supported on the DC10\n",
- ZR_DEVNAME(zr));
+ "%s: %s - HDec by 4 is not supported on the DC10\n",
+ ZR_DEVNAME(zr), __func__);
err0++;
break;
}
@@ -900,50 +817,73 @@ zoran_check_jpg_settings (struct zoran *zr,
/* We have to check the data the user has set */
if (settings->HorDcm != 1 && settings->HorDcm != 2 &&
- (zr->card.type == DC10_new || settings->HorDcm != 4))
+ (zr->card.type == DC10_new || settings->HorDcm != 4)) {
+ settings->HorDcm = clamp(settings->HorDcm, 1, 2);
err0++;
- if (settings->VerDcm != 1 && settings->VerDcm != 2)
+ }
+ if (settings->VerDcm != 1 && settings->VerDcm != 2) {
+ settings->VerDcm = clamp(settings->VerDcm, 1, 2);
err0++;
- if (settings->TmpDcm != 1 && settings->TmpDcm != 2)
+ }
+ if (settings->TmpDcm != 1 && settings->TmpDcm != 2) {
+ settings->TmpDcm = clamp(settings->TmpDcm, 1, 2);
err0++;
+ }
if (settings->field_per_buff != 1 &&
- settings->field_per_buff != 2)
+ settings->field_per_buff != 2) {
+ settings->field_per_buff = clamp(settings->field_per_buff, 1, 2);
err0++;
- if (settings->img_x < 0)
+ }
+ if (settings->img_x < 0) {
+ settings->img_x = 0;
err0++;
- if (settings->img_y < 0)
+ }
+ if (settings->img_y < 0) {
+ settings->img_y = 0;
err0++;
- if (settings->img_width < 0)
+ }
+ if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) {
+ settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH);
err0++;
- if (settings->img_height < 0)
+ }
+ if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) {
+ settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2);
err0++;
- if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH)
+ }
+ if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) {
+ settings->img_x = BUZ_MAX_WIDTH - settings->img_width;
err0++;
- if (settings->img_y + settings->img_height >
- BUZ_MAX_HEIGHT / 2)
+ }
+ if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) {
+ settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height;
+ err0++;
+ }
+ if (settings->img_width % (16 * settings->HorDcm) != 0) {
+ settings->img_width -= settings->img_width % (16 * settings->HorDcm);
+ if (settings->img_width == 0)
+ settings->img_width = 16 * settings->HorDcm;
+ err0++;
+ }
+ if (settings->img_height % (8 * settings->VerDcm) != 0) {
+ settings->img_height -= settings->img_height % (8 * settings->VerDcm);
+ if (settings->img_height == 0)
+ settings->img_height = 8 * settings->VerDcm;
err0++;
- if (settings->HorDcm && settings->VerDcm) {
- if (settings->img_width %
- (16 * settings->HorDcm) != 0)
- err0++;
- if (settings->img_height %
- (8 * settings->VerDcm) != 0)
- err0++;
}
- if (err0) {
+ if (!try && err0) {
dprintk(1,
KERN_ERR
- "%s: check_jpg_settings() - error in params for decimation = 0\n",
- ZR_DEVNAME(zr));
+ "%s: %s - error in params for decimation = 0\n",
+ ZR_DEVNAME(zr), __func__);
err++;
}
break;
default:
dprintk(1,
KERN_ERR
- "%s: check_jpg_settings() - decimation = %d, must be 0, 1, 2 or 4\n",
- ZR_DEVNAME(zr), settings->decimation);
+ "%s: %s - decimation = %d, must be 0, 1, 2 or 4\n",
+ ZR_DEVNAME(zr), __func__, settings->decimation);
err++;
break;
}
@@ -1021,12 +961,10 @@ zoran_open_init_params (struct zoran *zr)
sizeof(zr->jpg_settings.jpg_comp.COM_data));
zr->jpg_settings.jpg_comp.jpeg_markers =
JPEG_MARKER_DHT | JPEG_MARKER_DQT;
- i = zoran_check_jpg_settings(zr, &zr->jpg_settings);
+ i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
if (i)
- dprintk(1,
- KERN_ERR
- "%s: zoran_open_init_params() internal error\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s internal error\n",
+ ZR_DEVNAME(zr), __func__);
clear_interrupt_counters(zr);
zr->testing = 0;
@@ -1062,13 +1000,11 @@ static int __devinit
zr36057_init (struct zoran *zr)
{
int j, err;
- int two = 2;
- int zero = 0;
dprintk(1,
KERN_INFO
- "%s: zr36057_init() - initializing card[%d], zr=%p\n",
- ZR_DEVNAME(zr), zr->id, zr);
+ "%s: %s - initializing card[%d], zr=%p\n",
+ ZR_DEVNAME(zr), __func__, zr->id, zr);
/* default setup of all parameters which will persist between opens */
zr->user = 0;
@@ -1079,24 +1015,32 @@ zr36057_init (struct zoran *zr)
zr->jpg_buffers.allocated = 0;
zr->v4l_buffers.allocated = 0;
- zr->buffer.base = (void *) vidmem;
- zr->buffer.width = 0;
- zr->buffer.height = 0;
- zr->buffer.depth = 0;
- zr->buffer.bytesperline = 0;
+ zr->vbuf_base = (void *) vidmem;
+ zr->vbuf_width = 0;
+ zr->vbuf_height = 0;
+ zr->vbuf_depth = 0;
+ zr->vbuf_bytesperline = 0;
/* Avoid nonsense settings from user for default input/norm */
- if (default_norm < VIDEO_MODE_PAL &&
- default_norm > VIDEO_MODE_SECAM)
- default_norm = VIDEO_MODE_PAL;
- zr->norm = default_norm;
- if (!(zr->timing = zr->card.tvn[zr->norm])) {
+ if (default_norm < 0 && default_norm > 2)
+ default_norm = 0;
+ if (default_norm == 0) {
+ zr->norm = V4L2_STD_PAL;
+ zr->timing = zr->card.tvn[0];
+ } else if (default_norm == 1) {
+ zr->norm = V4L2_STD_NTSC;
+ zr->timing = zr->card.tvn[1];
+ } else {
+ zr->norm = V4L2_STD_SECAM;
+ zr->timing = zr->card.tvn[2];
+ }
+ if (zr->timing == NULL) {
dprintk(1,
KERN_WARNING
- "%s: zr36057_init() - default TV standard not supported by hardware. PAL will be used.\n",
- ZR_DEVNAME(zr));
- zr->norm = VIDEO_MODE_PAL;
- zr->timing = zr->card.tvn[zr->norm];
+ "%s: %s - default TV standard not supported by hardware. PAL will be used.\n",
+ ZR_DEVNAME(zr), __func__);
+ zr->norm = V4L2_STD_PAL;
+ zr->timing = zr->card.tvn[0];
}
if (default_input > zr->card.inputs-1) {
@@ -1108,12 +1052,6 @@ zr36057_init (struct zoran *zr)
}
zr->input = default_input;
- /* Should the following be reset at every open ? */
- zr->hue = 32768;
- zr->contrast = 32768;
- zr->saturation = 32768;
- zr->brightness = 32768;
-
/* default setup (will be repeated at every open) */
zoran_open_init_params(zr);
@@ -1124,8 +1062,8 @@ zr36057_init (struct zoran *zr)
if (!zr->stat_com || !zr->video_dev) {
dprintk(1,
KERN_ERR
- "%s: zr36057_init() - kmalloc (STAT_COM) failed\n",
- ZR_DEVNAME(zr));
+ "%s: %s - kmalloc (STAT_COM) failed\n",
+ ZR_DEVNAME(zr), __func__);
err = -ENOMEM;
goto exit_free;
}
@@ -1137,6 +1075,7 @@ zr36057_init (struct zoran *zr)
* Now add the template and register the device unit.
*/
memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
+ zr->video_dev->parent = &zr->pci_dev->dev;
strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
if (err < 0)
@@ -1148,8 +1087,10 @@ zr36057_init (struct zoran *zr)
detect_guest_activity(zr);
test_interrupts(zr);
if (!pass_through) {
- decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
- encoder_command(zr, ENCODER_SET_INPUT, &two);
+ struct v4l2_routing route = { 2, 0 };
+
+ decoder_call(zr, video, s_stream, 0);
+ encoder_call(zr, video, s_routing, &route);
}
zr->zoran_proc = NULL;
@@ -1164,7 +1105,8 @@ exit_free:
static void __devexit zoran_remove(struct pci_dev *pdev)
{
- struct zoran *zr = pci_get_drvdata(pdev);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct zoran *zr = to_zoran(v4l2_dev);
if (!zr->initialized)
goto exit_free;
@@ -1197,7 +1139,7 @@ static void __devexit zoran_remove(struct pci_dev *pdev)
pci_disable_device(zr->pci_dev);
video_unregister_device(zr->video_dev);
exit_free:
- pci_set_drvdata(pdev, NULL);
+ v4l2_device_unregister(&zr->v4l2_dev);
kfree(zr);
}
@@ -1215,10 +1157,8 @@ zoran_setup_videocodec (struct zoran *zr,
m = kmalloc(sizeof(struct videocodec_master), GFP_KERNEL);
if (!m) {
- dprintk(1,
- KERN_ERR
- "%s: zoran_setup_videocodec() - no memory\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s - no memory\n",
+ ZR_DEVNAME(zr), __func__);
return m;
}
@@ -1256,6 +1196,18 @@ zoran_setup_videocodec (struct zoran *zr,
return m;
}
+static void zoran_subdev_notify(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+ struct zoran *zr = to_zoran(sd->v4l2_dev);
+
+ /* Bt819 needs to reset its FIFO buffer using #FRST pin and
+ LML33 card uses GPIO(7) for that. */
+ if (cmd == BT819_FIFO_RESET_LOW)
+ GPIO(zr, 7, 0);
+ else if (cmd == BT819_FIFO_RESET_HIGH)
+ GPIO(zr, 7, 1);
+}
+
/*
* Scan for a Buz card (actually for the PCI controller ZR36057),
* request the irq and map the io memory
@@ -1269,34 +1221,33 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
struct videocodec_master *master_vfe = NULL;
struct videocodec_master *master_codec = NULL;
int card_num;
- char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name;
+ char *codec_name, *vfe_name;
unsigned int nr;
nr = zoran_num++;
if (nr >= BUZ_MAX) {
- dprintk(1,
- KERN_ERR
- "%s: driver limited to %d card(s) maximum\n",
+ dprintk(1, KERN_ERR "%s: driver limited to %d card(s) maximum\n",
ZORAN_NAME, BUZ_MAX);
return -ENOENT;
}
zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
if (!zr) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - kzalloc failed\n",
- ZORAN_NAME);
+ dprintk(1, KERN_ERR "%s: %s - kzalloc failed\n",
+ ZORAN_NAME, __func__);
return -ENOMEM;
}
+ zr->v4l2_dev.notify = zoran_subdev_notify;
+ if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev))
+ goto zr_free_mem;
zr->pci_dev = pdev;
zr->id = nr;
snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
spin_lock_init(&zr->spinlock);
mutex_init(&zr->resource_lock);
if (pci_enable_device(pdev))
- goto zr_free_mem;
+ goto zr_unreg;
pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
dprintk(1,
@@ -1323,7 +1274,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
KERN_ERR
"%s: It is not possible to auto-detect ZR36057 based cards\n",
ZR_DEVNAME(zr));
- goto zr_free_mem;
+ goto zr_unreg;
}
card_num = ent->driver_data;
@@ -1332,7 +1283,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
KERN_ERR
"%s: Unknown card, try specifying card=X module parameter\n",
ZR_DEVNAME(zr));
- goto zr_free_mem;
+ goto zr_unreg;
}
dprintk(3,
KERN_DEBUG
@@ -1345,7 +1296,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
KERN_ERR
"%s: User specified card type %d out of range (0 .. %d)\n",
ZR_DEVNAME(zr), card_num, NUM_CARDS - 1);
- goto zr_free_mem;
+ goto zr_unreg;
}
}
@@ -1360,11 +1311,9 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0);
if (!zr->zr36057_mem) {
- dprintk(1,
- KERN_ERR
- "%s: %s() - ioremap failed\n",
+ dprintk(1, KERN_ERR "%s: %s() - ioremap failed\n",
ZR_DEVNAME(zr), __func__);
- goto zr_free_mem;
+ goto zr_unreg;
}
result = request_irq(zr->pci_dev->irq, zoran_irq,
@@ -1373,18 +1322,18 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
if (result == -EINVAL) {
dprintk(1,
KERN_ERR
- "%s: find_zr36057() - bad irq number or handler\n",
- ZR_DEVNAME(zr));
+ "%s: %s - bad irq number or handler\n",
+ ZR_DEVNAME(zr), __func__);
} else if (result == -EBUSY) {
dprintk(1,
KERN_ERR
- "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
- ZR_DEVNAME(zr), zr->pci_dev->irq);
+ "%s: %s - IRQ %d busy, change your PnP config in BIOS\n",
+ ZR_DEVNAME(zr), __func__, zr->pci_dev->irq);
} else {
dprintk(1,
KERN_ERR
- "%s: find_zr36057() - can't assign irq, error code %d\n",
- ZR_DEVNAME(zr), result);
+ "%s: %s - can't assign irq, error code %d\n",
+ ZR_DEVNAME(zr), __func__, result);
}
goto zr_unmap;
}
@@ -1394,9 +1343,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
&latency);
need_latency = zr->revision > 1 ? 32 : 48;
if (latency != need_latency) {
- dprintk(2,
- KERN_INFO
- "%s: Changing PCI latency from %d to %d\n",
+ dprintk(2, KERN_INFO "%s: Changing PCI latency from %d to %d\n",
ZR_DEVNAME(zr), latency, need_latency);
pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
need_latency);
@@ -1407,54 +1354,20 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
ZR_DEVNAME(zr));
- /* i2c decoder */
- if (decoder[zr->id] != -1) {
- i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
- zr->card.i2c_decoder = decoder[zr->id];
- } else if (zr->card.i2c_decoder != 0) {
- i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder);
- } else {
- i2c_dec_name = NULL;
- }
-
- if (i2c_dec_name) {
- result = request_module(i2c_dec_name);
- if (result < 0) {
- dprintk(1,
- KERN_ERR
- "%s: failed to load module %s: %d\n",
- ZR_DEVNAME(zr), i2c_dec_name, result);
- }
- }
-
- /* i2c encoder */
- if (encoder[zr->id] != -1) {
- i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
- zr->card.i2c_encoder = encoder[zr->id];
- } else if (zr->card.i2c_encoder != 0) {
- i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder);
- } else {
- i2c_enc_name = NULL;
- }
-
- if (i2c_enc_name) {
- result = request_module(i2c_enc_name);
- if (result < 0) {
- dprintk(1,
- KERN_ERR
- "%s: failed to load module %s: %d\n",
- ZR_DEVNAME(zr), i2c_enc_name, result);
- }
- }
-
if (zoran_register_i2c(zr) < 0) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - can't initialize i2c bus\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s - can't initialize i2c bus\n",
+ ZR_DEVNAME(zr), __func__);
goto zr_free_irq;
}
+ zr->decoder = v4l2_i2c_new_probed_subdev(&zr->i2c_adapter,
+ zr->card.mod_decoder, zr->card.i2c_decoder, zr->card.addrs_decoder);
+
+ if (zr->card.mod_encoder)
+ zr->encoder = v4l2_i2c_new_probed_subdev(&zr->i2c_adapter,
+ zr->card.mod_encoder, zr->card.i2c_encoder,
+ zr->card.addrs_encoder);
+
dprintk(2,
KERN_INFO "%s: Initializing videocodec bus...\n",
ZR_DEVNAME(zr));
@@ -1495,17 +1408,13 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
goto zr_unreg_i2c;
zr->codec = videocodec_attach(master_codec);
if (!zr->codec) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - no codec found\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s - no codec found\n",
+ ZR_DEVNAME(zr), __func__);
goto zr_free_codec;
}
if (zr->codec->type != zr->card.video_codec) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - wrong codec\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s - wrong codec\n",
+ ZR_DEVNAME(zr), __func__);
goto zr_detach_codec;
}
}
@@ -1515,17 +1424,13 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
goto zr_detach_codec;
zr->vfe = videocodec_attach(master_vfe);
if (!zr->vfe) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - no VFE found\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s - no VFE found\n",
+ ZR_DEVNAME(zr), __func__);
goto zr_free_vfe;
}
if (zr->vfe->type != zr->card.video_vfe) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() = wrong VFE\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s = wrong VFE\n",
+ ZR_DEVNAME(zr), __func__);
goto zr_detach_vfe;
}
}
@@ -1533,8 +1438,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
/* take care of Natoma chipset and a revision 1 zr36057 */
if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
zr->jpg_buffers.need_contiguous = 1;
- dprintk(1,
- KERN_INFO
+ dprintk(1, KERN_INFO
"%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
ZR_DEVNAME(zr));
}
@@ -1544,8 +1448,6 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
zoran_proc_init(zr);
- pci_set_drvdata(pdev, zr);
-
return 0;
zr_detach_vfe:
@@ -1563,6 +1465,8 @@ zr_free_irq:
free_irq(zr->pci_dev->irq, zr);
zr_unmap:
iounmap(zr->zr36057_mem);
+zr_unreg:
+ v4l2_device_unregister(&zr->v4l2_dev);
zr_free_mem:
kfree(zr);
@@ -1613,9 +1517,6 @@ static int __init zoran_init(void)
ZORAN_NAME, vidmem);
}
- /* random nonsense */
- dprintk(6, KERN_DEBUG "Jotti is een held!\n");
-
/* some mainboards might not do PCI-PCI data transfer well */
if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL|PCIPCI_ALIMAGIK)) {
dprintk(1,
diff --git a/drivers/media/video/zoran/zoran_card.h b/drivers/media/video/zoran/zoran_card.h
index 4507bdc5e338..4936fead73e8 100644
--- a/drivers/media/video/zoran/zoran_card.h
+++ b/drivers/media/video/zoran/zoran_card.h
@@ -44,7 +44,8 @@ extern int zr36067_debug;
extern struct video_device zoran_template;
extern int zoran_check_jpg_settings(struct zoran *zr,
- struct zoran_jpg_settings *settings);
+ struct zoran_jpg_settings *settings,
+ int try);
extern void zoran_open_init_params(struct zoran *zr);
extern void zoran_vdev_release(struct video_device *vdev);
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c
index 5d948ff7faf0..e0223deed35e 100644
--- a/drivers/media/video/zoran/zoran_device.c
+++ b/drivers/media/video/zoran/zoran_device.c
@@ -36,13 +36,12 @@
#include <linux/proc_fs.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
#include <linux/spinlock.h>
#include <linux/sem.h>
#include <linux/pci.h>
-#include <linux/video_decoder.h>
-#include <linux/video_encoder.h>
#include <linux/delay.h>
#include <linux/wait.h>
@@ -312,9 +311,9 @@ zr36057_adjust_vfe (struct zoran *zr,
case BUZ_MODE_MOTION_COMPRESS:
case BUZ_MODE_IDLE:
default:
- if (zr->norm == VIDEO_MODE_NTSC ||
+ if ((zr->norm & V4L2_STD_NTSC) ||
(zr->card.type == LML33R10 &&
- zr->norm == VIDEO_MODE_PAL))
+ (zr->norm & V4L2_STD_PAL)))
btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
else
btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
@@ -355,14 +354,6 @@ zr36057_set_vfe (struct zoran *zr,
dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n",
ZR_DEVNAME(zr), video_width, video_height);
- if (zr->norm != VIDEO_MODE_PAL &&
- zr->norm != VIDEO_MODE_NTSC &&
- zr->norm != VIDEO_MODE_SECAM) {
- dprintk(1,
- KERN_ERR "%s: set_vfe() - norm = %d not valid\n",
- ZR_DEVNAME(zr), zr->norm);
- return;
- }
if (video_width < BUZ_MIN_WIDTH ||
video_height < BUZ_MIN_HEIGHT ||
video_width > Wa || video_height > Ha) {
@@ -426,7 +417,7 @@ zr36057_set_vfe (struct zoran *zr,
* we get the correct colors when uncompressing to the screen */
//reg |= ZR36057_VFESPFR_VCLKPol; /**/
/* RJ: Don't know if that is needed for NTSC also */
- if (zr->norm != VIDEO_MODE_NTSC)
+ if (!(zr->norm & V4L2_STD_NTSC))
reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang
reg |= ZR36057_VFESPFR_TopField;
if (HorDcm >= 48) {
@@ -497,11 +488,11 @@ zr36057_overlay (struct zoran *zr,
* All error messages are internal driver checking only! */
/* video display top and bottom registers */
- reg = (long) zr->buffer.base +
+ reg = (long) zr->vbuf_base +
zr->overlay_settings.x *
((zr->overlay_settings.format->depth + 7) / 8) +
zr->overlay_settings.y *
- zr->buffer.bytesperline;
+ zr->vbuf_bytesperline;
btwrite(reg, ZR36057_VDTR);
if (reg & 3)
dprintk(1,
@@ -509,15 +500,15 @@ zr36057_overlay (struct zoran *zr,
"%s: zr36057_overlay() - video_address not aligned\n",
ZR_DEVNAME(zr));
if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2)
- reg += zr->buffer.bytesperline;
+ reg += zr->vbuf_bytesperline;
btwrite(reg, ZR36057_VDBR);
/* video stride, status, and frame grab register */
- reg = zr->buffer.bytesperline -
+ reg = zr->vbuf_bytesperline -
zr->overlay_settings.width *
((zr->overlay_settings.format->depth + 7) / 8);
if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2)
- reg += zr->buffer.bytesperline;
+ reg += zr->vbuf_bytesperline;
if (reg & 3)
dprintk(1,
KERN_ERR
@@ -544,12 +535,8 @@ zr36057_overlay (struct zoran *zr,
* and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels.
*/
-void
-write_overlay_mask (struct file *file,
- struct video_clip *vp,
- int count)
+void write_overlay_mask(struct zoran_fh *fh, struct v4l2_clip *vp, int count)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
u32 *mask;
@@ -563,10 +550,10 @@ write_overlay_mask (struct file *file,
for (i = 0; i < count; ++i) {
/* pick up local copy of clip */
- x = vp[i].x;
- y = vp[i].y;
- width = vp[i].width;
- height = vp[i].height;
+ x = vp[i].c.left;
+ y = vp[i].c.top;
+ width = vp[i].c.width;
+ height = vp[i].c.height;
/* trim clips that extend beyond the window */
if (x < 0) {
@@ -981,11 +968,10 @@ void
zr36057_enable_jpg (struct zoran *zr,
enum zoran_codec_mode mode)
{
- static int zero;
- static int one = 1;
struct vfe_settings cap;
int field_size =
zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff;
+ struct v4l2_routing route = { 0, 0 };
zr->codec_mode = mode;
@@ -1007,8 +993,9 @@ zr36057_enable_jpg (struct zoran *zr,
* the video bus direction set to input.
*/
set_videobus_dir(zr, 0);
- decoder_command(zr, DECODER_ENABLE_OUTPUT, &one);
- encoder_command(zr, ENCODER_SET_INPUT, &zero);
+ decoder_call(zr, video, s_stream, 1);
+ route.input = 0;
+ encoder_call(zr, video, s_routing, &route);
/* Take the JPEG codec and the VFE out of sleep */
jpeg_codec_sleep(zr, 0);
@@ -1054,9 +1041,10 @@ zr36057_enable_jpg (struct zoran *zr,
/* In motion decompression mode, the decoder output must be disabled, and
* the video bus direction set to output.
*/
- decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
+ decoder_call(zr, video, s_stream, 0);
set_videobus_dir(zr, 1);
- encoder_command(zr, ENCODER_SET_INPUT, &one);
+ route.input = 1;
+ encoder_call(zr, video, s_routing, &route);
/* Take the JPEG codec and the VFE out of sleep */
jpeg_codec_sleep(zr, 0);
@@ -1100,8 +1088,9 @@ zr36057_enable_jpg (struct zoran *zr,
jpeg_codec_sleep(zr, 1);
zr36057_adjust_vfe(zr, mode);
- decoder_command(zr, DECODER_ENABLE_OUTPUT, &one);
- encoder_command(zr, ENCODER_SET_INPUT, &zero);
+ decoder_call(zr, video, s_stream, 1);
+ route.input = 0;
+ encoder_call(zr, video, s_routing, &route);
dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr));
break;
@@ -1132,7 +1121,7 @@ zoran_feed_stat_com (struct zoran *zr)
if (!(zr->stat_com[i] & cpu_to_le32(1)))
break;
zr->stat_com[i] =
- cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
+ cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
} else {
/* fill 2 stat_com entries */
i = ((zr->jpg_dma_head -
@@ -1140,9 +1129,9 @@ zoran_feed_stat_com (struct zoran *zr)
if (!(zr->stat_com[i] & cpu_to_le32(1)))
break;
zr->stat_com[i] =
- cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
+ cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
zr->stat_com[i + 1] =
- cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
+ cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
}
zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA;
zr->jpg_dma_head++;
@@ -1162,7 +1151,7 @@ zoran_reap_stat_com (struct zoran *zr)
u32 stat_com;
unsigned int seq;
unsigned int dif;
- struct zoran_jpg_buffer *buffer;
+ struct zoran_buffer *buffer;
int frame;
/* In motion decompress we don't have a hardware frame counter,
@@ -1208,22 +1197,52 @@ zoran_reap_stat_com (struct zoran *zr)
}
}
+static void zoran_restart(struct zoran *zr)
+{
+ /* Now the stat_comm buffer is ready for restart */
+ int status = 0, mode;
+
+ if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
+ decoder_call(zr, video, g_input_status, &status);
+ mode = CODEC_DO_COMPRESSION;
+ } else {
+ status = V4L2_IN_ST_NO_SIGNAL;
+ mode = CODEC_DO_EXPANSION;
+ }
+ if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
+ !(status & V4L2_IN_ST_NO_SIGNAL)) {
+ /********** RESTART code *************/
+ jpeg_codec_reset(zr);
+ zr->codec->set_mode(zr->codec, mode);
+ zr36057_set_jpg(zr, zr->codec_mode);
+ jpeg_start(zr);
+
+ if (zr->num_errors <= 8)
+ dprintk(2, KERN_INFO "%s: Restart\n",
+ ZR_DEVNAME(zr));
+
+ zr->JPEG_missed = 0;
+ zr->JPEG_error = 2;
+ /********** End RESTART code ***********/
+ }
+}
+
static void
error_handler (struct zoran *zr,
u32 astat,
u32 stat)
{
+ int i, j;
+
/* This is JPEG error handling part */
- if ((zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) &&
- (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS)) {
- //dprintk(1, KERN_ERR "%s: Internal error: error handling request in mode %d\n", ZR_DEVNAME(zr), zr->codec_mode);
+ if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS &&
+ zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS) {
return;
}
if ((stat & 1) == 0 &&
zr->codec_mode == BUZ_MODE_MOTION_COMPRESS &&
- zr->jpg_dma_tail - zr->jpg_que_tail >=
- zr->jpg_buffers.num_buffers) {
+ zr->jpg_dma_tail - zr->jpg_que_tail >= zr->jpg_buffers.num_buffers) {
/* No free buffers... */
zoran_reap_stat_com(zr);
zoran_feed_stat_com(zr);
@@ -1232,142 +1251,95 @@ error_handler (struct zoran *zr,
return;
}
- if (zr->JPEG_error != 1) {
- /*
- * First entry: error just happened during normal operation
- *
- * In BUZ_MODE_MOTION_COMPRESS:
- *
- * Possible glitch in TV signal. In this case we should
- * stop the codec and wait for good quality signal before
- * restarting it to avoid further problems
- *
- * In BUZ_MODE_MOTION_DECOMPRESS:
- *
- * Bad JPEG frame: we have to mark it as processed (codec crashed
- * and was not able to do it itself), and to remove it from queue.
- */
- btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
- udelay(1);
- stat = stat | (post_office_read(zr, 7, 0) & 3) << 8;
- btwrite(0, ZR36057_JPC);
- btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
- jpeg_codec_reset(zr);
- jpeg_codec_sleep(zr, 1);
- zr->JPEG_error = 1;
- zr->num_errors++;
-
- /* Report error */
- if (zr36067_debug > 1 && zr->num_errors <= 8) {
- long frame;
- frame =
- zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
- printk(KERN_ERR
- "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ",
- ZR_DEVNAME(zr), stat, zr->last_isr,
- zr->jpg_que_tail, zr->jpg_dma_tail,
- zr->jpg_dma_head, zr->jpg_que_head,
- zr->jpg_seq_num, frame);
- printk("stat_com frames:");
- {
- int i, j;
- for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
- for (i = 0;
- i < zr->jpg_buffers.num_buffers;
- i++) {
- if (le32_to_cpu(zr->stat_com[j]) ==
- zr->jpg_buffers.
- buffer[i].
- frag_tab_bus) {
- printk("% d->%d",
- j, i);
- }
- }
- }
- printk("\n");
- }
- }
- /* Find an entry in stat_com and rotate contents */
- {
- int i;
-
- if (zr->jpg_settings.TmpDcm == 1)
- i = (zr->jpg_dma_tail -
- zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
- else
- i = ((zr->jpg_dma_tail -
- zr->jpg_err_shift) & 1) * 2;
- if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
- /* Mimic zr36067 operation */
- zr->stat_com[i] |= cpu_to_le32(1);
- if (zr->jpg_settings.TmpDcm != 1)
- zr->stat_com[i + 1] |= cpu_to_le32(1);
- /* Refill */
- zoran_reap_stat_com(zr);
- zoran_feed_stat_com(zr);
- wake_up_interruptible(&zr->jpg_capq);
- /* Find an entry in stat_com again after refill */
- if (zr->jpg_settings.TmpDcm == 1)
- i = (zr->jpg_dma_tail -
- zr->jpg_err_shift) &
- BUZ_MASK_STAT_COM;
- else
- i = ((zr->jpg_dma_tail -
- zr->jpg_err_shift) & 1) * 2;
- }
- if (i) {
- /* Rotate stat_comm entries to make current entry first */
- int j;
- __le32 bus_addr[BUZ_NUM_STAT_COM];
-
- /* Here we are copying the stat_com array, which
- * is already in little endian format, so
- * no endian conversions here
- */
- memcpy(bus_addr, zr->stat_com,
- sizeof(bus_addr));
- for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
- zr->stat_com[j] =
- bus_addr[(i + j) &
- BUZ_MASK_STAT_COM];
+ if (zr->JPEG_error == 1) {
+ zoran_restart(zr);
+ return;
+ }
- }
- zr->jpg_err_shift += i;
- zr->jpg_err_shift &= BUZ_MASK_STAT_COM;
+ /*
+ * First entry: error just happened during normal operation
+ *
+ * In BUZ_MODE_MOTION_COMPRESS:
+ *
+ * Possible glitch in TV signal. In this case we should
+ * stop the codec and wait for good quality signal before
+ * restarting it to avoid further problems
+ *
+ * In BUZ_MODE_MOTION_DECOMPRESS:
+ *
+ * Bad JPEG frame: we have to mark it as processed (codec crashed
+ * and was not able to do it itself), and to remove it from queue.
+ */
+ btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
+ udelay(1);
+ stat = stat | (post_office_read(zr, 7, 0) & 3) << 8;
+ btwrite(0, ZR36057_JPC);
+ btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
+ jpeg_codec_reset(zr);
+ jpeg_codec_sleep(zr, 1);
+ zr->JPEG_error = 1;
+ zr->num_errors++;
+
+ /* Report error */
+ if (zr36067_debug > 1 && zr->num_errors <= 8) {
+ long frame;
+
+ frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
+ printk(KERN_ERR
+ "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ",
+ ZR_DEVNAME(zr), stat, zr->last_isr,
+ zr->jpg_que_tail, zr->jpg_dma_tail,
+ zr->jpg_dma_head, zr->jpg_que_head,
+ zr->jpg_seq_num, frame);
+ printk(KERN_INFO "stat_com frames:");
+ for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
+ for (i = 0; i < zr->jpg_buffers.num_buffers; i++) {
+ if (le32_to_cpu(zr->stat_com[j]) == zr->jpg_buffers.buffer[i].jpg.frag_tab_bus)
+ printk(KERN_CONT "% d->%d", j, i);
}
- if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)
- zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */
}
+ printk(KERN_CONT "\n");
}
+ /* Find an entry in stat_com and rotate contents */
+ if (zr->jpg_settings.TmpDcm == 1)
+ i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
+ else
+ i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2;
+ if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
+ /* Mimic zr36067 operation */
+ zr->stat_com[i] |= cpu_to_le32(1);
+ if (zr->jpg_settings.TmpDcm != 1)
+ zr->stat_com[i + 1] |= cpu_to_le32(1);
+ /* Refill */
+ zoran_reap_stat_com(zr);
+ zoran_feed_stat_com(zr);
+ wake_up_interruptible(&zr->jpg_capq);
+ /* Find an entry in stat_com again after refill */
+ if (zr->jpg_settings.TmpDcm == 1)
+ i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
+ else
+ i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2;
+ }
+ if (i) {
+ /* Rotate stat_comm entries to make current entry first */
+ int j;
+ __le32 bus_addr[BUZ_NUM_STAT_COM];
+
+ /* Here we are copying the stat_com array, which
+ * is already in little endian format, so
+ * no endian conversions here
+ */
+ memcpy(bus_addr, zr->stat_com, sizeof(bus_addr));
- /* Now the stat_comm buffer is ready for restart */
- do {
- int status, mode;
-
- if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
- decoder_command(zr, DECODER_GET_STATUS, &status);
- mode = CODEC_DO_COMPRESSION;
- } else {
- status = 0;
- mode = CODEC_DO_EXPANSION;
- }
- if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
- (status & DECODER_STATUS_GOOD)) {
- /********** RESTART code *************/
- jpeg_codec_reset(zr);
- zr->codec->set_mode(zr->codec, mode);
- zr36057_set_jpg(zr, zr->codec_mode);
- jpeg_start(zr);
-
- if (zr->num_errors <= 8)
- dprintk(2, KERN_INFO "%s: Restart\n",
- ZR_DEVNAME(zr));
+ for (j = 0; j < BUZ_NUM_STAT_COM; j++)
+ zr->stat_com[j] = bus_addr[(i + j) & BUZ_MASK_STAT_COM];
- zr->JPEG_missed = 0;
- zr->JPEG_error = 2;
- /********** End RESTART code ***********/
- }
- } while (0);
+ zr->jpg_err_shift += i;
+ zr->jpg_err_shift &= BUZ_MASK_STAT_COM;
+ }
+ if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)
+ zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */
+ zoran_restart(zr);
}
irqreturn_t
@@ -1425,10 +1397,8 @@ zoran_irq (int irq,
* We simply ignore them */
if (zr->v4l_memgrab_active) {
-
/* A lot more checks should be here ... */
- if ((btread(ZR36057_VSSFGR) &
- ZR36057_VSSFGR_SnapShot) == 0)
+ if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) == 0)
dprintk(1,
KERN_WARNING
"%s: BuzIRQ with SnapShot off ???\n",
@@ -1436,10 +1406,7 @@ zoran_irq (int irq,
if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) {
/* There is a grab on a frame going on, check if it has finished */
-
- if ((btread(ZR36057_VSSFGR) &
- ZR36057_VSSFGR_FrameGrab) ==
- 0) {
+ if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FrameGrab) == 0) {
/* it is finished, notify the user */
zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE;
@@ -1457,9 +1424,7 @@ zoran_irq (int irq,
if (zr->v4l_grab_frame == NO_GRAB_ACTIVE &&
zr->v4l_pend_tail != zr->v4l_pend_head) {
-
- int frame = zr->v4l_pend[zr->v4l_pend_tail &
- V4L_MASK_FRAME];
+ int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME];
u32 reg;
zr->v4l_grab_frame = frame;
@@ -1468,27 +1433,17 @@ zoran_irq (int irq,
/* Buffer address */
- reg =
- zr->v4l_buffers.buffer[frame].
- fbuffer_bus;
+ reg = zr->v4l_buffers.buffer[frame].v4l.fbuffer_bus;
btwrite(reg, ZR36057_VDTR);
- if (zr->v4l_settings.height >
- BUZ_MAX_HEIGHT / 2)
- reg +=
- zr->v4l_settings.
- bytesperline;
+ if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
+ reg += zr->v4l_settings.bytesperline;
btwrite(reg, ZR36057_VDBR);
/* video stride, status, and frame grab register */
reg = 0;
- if (zr->v4l_settings.height >
- BUZ_MAX_HEIGHT / 2)
- reg +=
- zr->v4l_settings.
- bytesperline;
- reg =
- (reg <<
- ZR36057_VSSFGR_DispStride);
+ if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
+ reg += zr->v4l_settings.bytesperline;
+ reg = (reg << ZR36057_VSSFGR_DispStride);
reg |= ZR36057_VSSFGR_VidOvf;
reg |= ZR36057_VSSFGR_SnapShot;
reg |= ZR36057_VSSFGR_FrameGrab;
@@ -1506,77 +1461,66 @@ zoran_irq (int irq,
#if (IRQ_MASK & ZR36057_ISR_CodRepIRQ)
if (astat & ZR36057_ISR_CodRepIRQ) {
zr->intr_counter_CodRepIRQ++;
- IDEBUG(printk
- (KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n",
+ IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n",
ZR_DEVNAME(zr)));
btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR);
}
#endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */
#if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ)
- if (astat & ZR36057_ISR_JPEGRepIRQ) {
-
- if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
- zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
- if (zr36067_debug > 1 &&
- (!zr->frame_num || zr->JPEG_error)) {
- printk(KERN_INFO
- "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n",
- ZR_DEVNAME(zr), stat,
- zr->jpg_settings.odd_even,
- zr->jpg_settings.
- field_per_buff,
- zr->JPEG_missed);
- {
- char sc[] = "0000";
- char sv[5];
- int i;
- strcpy(sv, sc);
- for (i = 0; i < 4; i++) {
- if (le32_to_cpu(zr->stat_com[i]) & 1)
- sv[i] = '1';
- }
- sv[4] = 0;
- printk(KERN_INFO
- "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n",
- ZR_DEVNAME(zr), sv,
- zr->jpg_que_tail,
- zr->jpg_dma_tail,
- zr->jpg_dma_head,
- zr->jpg_que_head);
- }
- } else {
- if (zr->JPEG_missed > zr->JPEG_max_missed) // Get statistics
- zr->JPEG_max_missed =
- zr->JPEG_missed;
- if (zr->JPEG_missed <
- zr->JPEG_min_missed)
- zr->JPEG_min_missed =
- zr->JPEG_missed;
+ if ((astat & ZR36057_ISR_JPEGRepIRQ) &&
+ (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
+ zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) {
+ if (zr36067_debug > 1 && (!zr->frame_num || zr->JPEG_error)) {
+ char sc[] = "0000";
+ char sv[5];
+ int i;
+
+ printk(KERN_INFO
+ "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n",
+ ZR_DEVNAME(zr), stat,
+ zr->jpg_settings.odd_even,
+ zr->jpg_settings.field_per_buff,
+ zr->JPEG_missed);
+
+ strcpy(sv, sc);
+ for (i = 0; i < 4; i++) {
+ if (le32_to_cpu(zr->stat_com[i]) & 1)
+ sv[i] = '1';
}
+ sv[4] = 0;
+ printk(KERN_INFO
+ "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n",
+ ZR_DEVNAME(zr), sv,
+ zr->jpg_que_tail,
+ zr->jpg_dma_tail,
+ zr->jpg_dma_head,
+ zr->jpg_que_head);
+ } else {
+ /* Get statistics */
+ if (zr->JPEG_missed > zr->JPEG_max_missed)
+ zr->JPEG_max_missed = zr->JPEG_missed;
+ if (zr->JPEG_missed < zr->JPEG_min_missed)
+ zr->JPEG_min_missed = zr->JPEG_missed;
+ }
- if (zr36067_debug > 2 && zr->frame_num < 6) {
- int i;
- printk("%s: seq=%ld stat_com:",
- ZR_DEVNAME(zr), zr->jpg_seq_num);
- for (i = 0; i < 4; i++) {
- printk(" %08x",
- le32_to_cpu(zr->stat_com[i]));
- }
- printk("\n");
+ if (zr36067_debug > 2 && zr->frame_num < 6) {
+ int i;
+
+ printk(KERN_INFO "%s: seq=%ld stat_com:",
+ ZR_DEVNAME(zr), zr->jpg_seq_num);
+ for (i = 0; i < 4; i++) {
+ printk(KERN_CONT " %08x",
+ le32_to_cpu(zr->stat_com[i]));
}
- zr->frame_num++;
- zr->JPEG_missed = 0;
- zr->JPEG_error = 0;
- zoran_reap_stat_com(zr);
- zoran_feed_stat_com(zr);
- wake_up_interruptible(&zr->jpg_capq);
- } /*else {
- dprintk(1,
- KERN_ERR
- "%s: JPEG interrupt while not in motion (de)compress mode!\n",
- ZR_DEVNAME(zr));
- }*/
+ printk(KERN_CONT "\n");
+ }
+ zr->frame_num++;
+ zr->JPEG_missed = 0;
+ zr->JPEG_error = 0;
+ zoran_reap_stat_com(zr);
+ zoran_feed_stat_com(zr);
+ wake_up_interruptible(&zr->jpg_capq);
}
#endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */
@@ -1585,8 +1529,7 @@ zoran_irq (int irq,
zr->JPEG_missed > 25 ||
zr->JPEG_error == 1 ||
((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) &&
- (zr->frame_num & (zr->JPEG_missed >
- zr->jpg_settings.field_per_buff)))) {
+ (zr->frame_num & (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) {
error_handler(zr, astat, stat);
}
@@ -1628,7 +1571,7 @@ zoran_set_pci_master (struct zoran *zr,
void
zoran_init_hardware (struct zoran *zr)
{
- int j, zero = 0;
+ struct v4l2_routing route = { 0, 0 };
/* Enable bus-mastering */
zoran_set_pci_master(zr, 1);
@@ -1638,15 +1581,16 @@ zoran_init_hardware (struct zoran *zr)
zr->card.init(zr);
}
- j = zr->card.input[zr->input].muxsel;
+ route.input = zr->card.input[zr->input].muxsel;
- decoder_command(zr, 0, NULL);
- decoder_command(zr, DECODER_SET_NORM, &zr->norm);
- decoder_command(zr, DECODER_SET_INPUT, &j);
+ decoder_call(zr, core, init, 0);
+ decoder_call(zr, tuner, s_std, zr->norm);
+ decoder_call(zr, video, s_routing, &route);
- encoder_command(zr, 0, NULL);
- encoder_command(zr, ENCODER_SET_NORM, &zr->norm);
- encoder_command(zr, ENCODER_SET_INPUT, &zero);
+ encoder_call(zr, core, init, 0);
+ encoder_call(zr, video, s_std_output, zr->norm);
+ route.input = 0;
+ encoder_call(zr, video, s_routing, &route);
/* toggle JPEG codec sleep to sync PLL */
jpeg_codec_sleep(zr, 1);
@@ -1706,42 +1650,3 @@ zr36057_init_vfe (struct zoran *zr)
reg |= ZR36057_VDCR_Triton;
btwrite(reg, ZR36057_VDCR);
}
-
-/*
- * Interface to decoder and encoder chips using i2c bus
- */
-
-int
-decoder_command (struct zoran *zr,
- int cmd,
- void *data)
-{
- if (zr->decoder == NULL)
- return -EIO;
-
- if (zr->card.type == LML33 &&
- (cmd == DECODER_SET_NORM || cmd == DECODER_SET_INPUT)) {
- int res;
-
- // Bt819 needs to reset its FIFO buffer using #FRST pin and
- // LML33 card uses GPIO(7) for that.
- GPIO(zr, 7, 0);
- res = zr->decoder->driver->command(zr->decoder, cmd, data);
- // Pull #FRST high.
- GPIO(zr, 7, 1);
- return res;
- } else
- return zr->decoder->driver->command(zr->decoder, cmd,
- data);
-}
-
-int
-encoder_command (struct zoran *zr,
- int cmd,
- void *data)
-{
- if (zr->encoder == NULL)
- return -1;
-
- return zr->encoder->driver->command(zr->encoder, cmd, data);
-}
diff --git a/drivers/media/video/zoran/zoran_device.h b/drivers/media/video/zoran/zoran_device.h
index 74c6c8edb7d0..07f2c23ff740 100644
--- a/drivers/media/video/zoran/zoran_device.h
+++ b/drivers/media/video/zoran/zoran_device.h
@@ -54,8 +54,8 @@ extern int jpeg_codec_reset(struct zoran *zr);
/* zr360x7 access to raw capture */
extern void zr36057_overlay(struct zoran *zr,
int on);
-extern void write_overlay_mask(struct file *file,
- struct video_clip *vp,
+extern void write_overlay_mask(struct zoran_fh *fh,
+ struct v4l2_clip *vp,
int count);
extern void zr36057_set_memgrab(struct zoran *zr,
int mode);
@@ -87,11 +87,9 @@ extern int jpg_bufsize;
extern int pass_through;
/* i2c */
-extern int decoder_command(struct zoran *zr,
- int cmd,
- void *data);
-extern int encoder_command(struct zoran *zr,
- int cmd,
- void *data);
+#define decoder_call(zr, o, f, args...) \
+ v4l2_subdev_call(zr->decoder, o, f, ##args)
+#define encoder_call(zr, o, f, args...) \
+ v4l2_subdev_call(zr->encoder, o, f, ##args)
#endif /* __ZORAN_DEVICE_H__ */
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 120ef235e63d..f16e57cf11e4 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -58,16 +58,6 @@
#include <linux/i2c-algo-bit.h>
#include <linux/spinlock.h>
-#define MAP_NR(x) virt_to_page(x)
-#define ZORAN_VID_TYPE ( \
- VID_TYPE_CAPTURE | \
- VID_TYPE_OVERLAY | \
- VID_TYPE_CLIPPING | \
- VID_TYPE_FRAMERAM | \
- VID_TYPE_SCALES | \
- VID_TYPE_MJPEG_DECODER | \
- VID_TYPE_MJPEG_ENCODER \
- )
#include <linux/videodev.h>
#include <media/v4l2-common.h>
@@ -79,36 +69,17 @@
#include <asm/uaccess.h>
#include <linux/proc_fs.h>
-#include <linux/video_decoder.h>
-#include <linux/video_encoder.h>
#include <linux/mutex.h>
#include "zoran.h"
#include "zoran_device.h"
#include "zoran_card.h"
- /* we declare some card type definitions here, they mean
- * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */
-#define ZORAN_V4L2_VID_FLAGS ( \
- V4L2_CAP_STREAMING |\
- V4L2_CAP_VIDEO_CAPTURE |\
- V4L2_CAP_VIDEO_OUTPUT |\
- V4L2_CAP_VIDEO_OVERLAY \
- )
-
-
-#if defined(CONFIG_VIDEO_V4L1_COMPAT)
-#define ZFMT(pal, fcc, cs) \
- .palette = (pal), .fourcc = (fcc), .colorspace = (cs)
-#else
-#define ZFMT(pal, fcc, cs) \
- .fourcc = (fcc), .colorspace = (cs)
-#endif
const struct zoran_format zoran_formats[] = {
{
.name = "15-bit RGB LE",
- ZFMT(VIDEO_PALETTE_RGB555,
- V4L2_PIX_FMT_RGB555, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_RGB555,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 15,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
@@ -116,16 +87,16 @@ const struct zoran_format zoran_formats[] = {
ZR36057_VFESPFR_LittleEndian,
}, {
.name = "15-bit RGB BE",
- ZFMT(-1,
- V4L2_PIX_FMT_RGB555X, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_RGB555X,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 15,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif,
}, {
.name = "16-bit RGB LE",
- ZFMT(VIDEO_PALETTE_RGB565,
- V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 16,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
@@ -133,56 +104,56 @@ const struct zoran_format zoran_formats[] = {
ZR36057_VFESPFR_LittleEndian,
}, {
.name = "16-bit RGB BE",
- ZFMT(-1,
- V4L2_PIX_FMT_RGB565X, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_RGB565X,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 16,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif,
}, {
.name = "24-bit RGB",
- ZFMT(VIDEO_PALETTE_RGB24,
- V4L2_PIX_FMT_BGR24, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_BGR24,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 24,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24,
}, {
.name = "32-bit RGB LE",
- ZFMT(VIDEO_PALETTE_RGB32,
- V4L2_PIX_FMT_BGR32, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_BGR32,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 32,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian,
}, {
.name = "32-bit RGB BE",
- ZFMT(-1,
- V4L2_PIX_FMT_RGB32, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_RGB32,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 32,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_RGB888,
}, {
.name = "4:2:2, packed, YUYV",
- ZFMT(VIDEO_PALETTE_YUV422,
- V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_SMPTE170M),
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .colorspace = V4L2_COLORSPACE_SMPTE170M,
.depth = 16,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_YUV422,
}, {
.name = "4:2:2, packed, UYVY",
- ZFMT(VIDEO_PALETTE_UYVY,
- V4L2_PIX_FMT_UYVY, V4L2_COLORSPACE_SMPTE170M),
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .colorspace = V4L2_COLORSPACE_SMPTE170M,
.depth = 16,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian,
}, {
.name = "Hardware-encoded Motion-JPEG",
- ZFMT(-1,
- V4L2_PIX_FMT_MJPEG, V4L2_COLORSPACE_SMPTE170M),
+ .fourcc = V4L2_PIX_FMT_MJPEG,
+ .colorspace = V4L2_COLORSPACE_SMPTE170M,
.depth = 0,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_PLAYBACK |
@@ -191,13 +162,6 @@ const struct zoran_format zoran_formats[] = {
};
#define NUM_FORMATS ARRAY_SIZE(zoran_formats)
-// RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined
-
-
-static int lock_norm; /* 0 = default 1 = Don't change TV standard (norm) */
-module_param(lock_norm, int, 0644);
-MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)");
-
/* small helper function for calculating buffersizes for v4l2
* we calculate the nearest higher power-of-two, which
* will be the recommended buffersize */
@@ -222,221 +186,106 @@ zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings)
}
/* forward references */
-static void v4l_fbuffer_free(struct file *file);
-static void jpg_fbuffer_free(struct file *file);
+static void v4l_fbuffer_free(struct zoran_fh *fh);
+static void jpg_fbuffer_free(struct zoran_fh *fh);
+
+/* Set mapping mode */
+static void map_mode_raw(struct zoran_fh *fh)
+{
+ fh->map_mode = ZORAN_MAP_MODE_RAW;
+ fh->buffers.buffer_size = v4l_bufsize;
+ fh->buffers.num_buffers = v4l_nbufs;
+}
+static void map_mode_jpg(struct zoran_fh *fh, int play)
+{
+ fh->map_mode = play ? ZORAN_MAP_MODE_JPG_PLAY : ZORAN_MAP_MODE_JPG_REC;
+ fh->buffers.buffer_size = jpg_bufsize;
+ fh->buffers.num_buffers = jpg_nbufs;
+}
+static inline const char *mode_name(enum zoran_map_mode mode)
+{
+ return mode == ZORAN_MAP_MODE_RAW ? "V4L" : "JPG";
+}
/*
* Allocate the V4L grab buffers
*
* These have to be pysically contiguous.
- * If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc
- * else we try to allocate them with bigphysarea_alloc_pages
- * if the bigphysarea patch is present in the kernel,
- * else we try to use high memory (if the user has bootet
- * Linux with the necessary memory left over).
*/
-static unsigned long
-get_high_mem (unsigned long size)
+static int v4l_fbuffer_alloc(struct zoran_fh *fh)
{
-/*
- * Check if there is usable memory at the end of Linux memory
- * of at least size. Return the physical address of this memory,
- * return 0 on failure.
- *
- * The idea is from Alexandro Rubini's book "Linux device drivers".
- * The driver from him which is downloadable from O'Reilly's
- * web site misses the "virt_to_phys(high_memory)" part
- * (and therefore doesn't work at all - at least with 2.2.x kernels).
- *
- * It should be unnecessary to mention that THIS IS DANGEROUS,
- * if more than one driver at a time has the idea to use this memory!!!!
- */
-
- volatile unsigned char __iomem *mem;
- unsigned char c;
- unsigned long hi_mem_ph;
- unsigned long i;
-
- /* Map the high memory to user space */
-
- hi_mem_ph = virt_to_phys(high_memory);
-
- mem = ioremap(hi_mem_ph, size);
- if (!mem) {
- dprintk(1,
- KERN_ERR "%s: get_high_mem() - ioremap failed\n",
- ZORAN_NAME);
- return 0;
- }
-
- for (i = 0; i < size; i++) {
- /* Check if it is memory */
- c = i & 0xff;
- writeb(c, mem + i);
- if (readb(mem + i) != c)
- break;
- c = 255 - c;
- writeb(c, mem + i);
- if (readb(mem + i) != c)
- break;
- writeb(0, mem + i); /* zero out memory */
-
- /* give the kernel air to breath */
- if ((i & 0x3ffff) == 0x3ffff)
- schedule();
- }
-
- iounmap(mem);
-
- if (i != size) {
- dprintk(1,
- KERN_ERR
- "%s: get_high_mem() - requested %lu, avail %lu\n",
- ZORAN_NAME, size, i);
- return 0;
- }
-
- return hi_mem_ph;
-}
-
-static int
-v4l_fbuffer_alloc (struct file *file)
-{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
int i, off;
unsigned char *mem;
- unsigned long pmem = 0;
- /* we might have old buffers lying around... */
- if (fh->v4l_buffers.ready_to_be_freed) {
- v4l_fbuffer_free(file);
- }
-
- for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
- if (fh->v4l_buffers.buffer[i].fbuffer)
+ for (i = 0; i < fh->buffers.num_buffers; i++) {
+ if (fh->buffers.buffer[i].v4l.fbuffer)
dprintk(2,
KERN_WARNING
- "%s: v4l_fbuffer_alloc() - buffer %d allready allocated!?\n",
- ZR_DEVNAME(zr), i);
+ "%s: %s - buffer %d already allocated!?\n",
+ ZR_DEVNAME(zr), __func__, i);
//udelay(20);
- if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
- /* Use kmalloc */
-
- mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL);
- if (!mem) {
- dprintk(1,
- KERN_ERR
- "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n",
- ZR_DEVNAME(zr), i);
- v4l_fbuffer_free(file);
- return -ENOBUFS;
- }
- fh->v4l_buffers.buffer[i].fbuffer = mem;
- fh->v4l_buffers.buffer[i].fbuffer_phys =
- virt_to_phys(mem);
- fh->v4l_buffers.buffer[i].fbuffer_bus =
- virt_to_bus(mem);
- for (off = 0; off < fh->v4l_buffers.buffer_size;
- off += PAGE_SIZE)
- SetPageReserved(MAP_NR(mem + off));
- dprintk(4,
- KERN_INFO
- "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n",
- ZR_DEVNAME(zr), i, (unsigned long) mem,
- virt_to_bus(mem));
- } else {
-
- /* Use high memory which has been left at boot time */
-
- /* Ok., Ok. this is an evil hack - we make
- * the assumption that physical addresses are
- * the same as bus addresses (true at least
- * for Intel processors). The whole method of
- * obtaining and using this memory is not very
- * nice - but I hope it saves some poor users
- * from kernel hacking, which might have even
- * more evil results */
-
- if (i == 0) {
- int size =
- fh->v4l_buffers.num_buffers *
- fh->v4l_buffers.buffer_size;
-
- pmem = get_high_mem(size);
- if (pmem == 0) {
- dprintk(1,
- KERN_ERR
- "%s: v4l_fbuffer_alloc() - get_high_mem (size = %d KB) for V4L bufs failed\n",
- ZR_DEVNAME(zr), size >> 10);
- return -ENOBUFS;
- }
- fh->v4l_buffers.buffer[0].fbuffer = NULL;
- fh->v4l_buffers.buffer[0].fbuffer_phys = pmem;
- fh->v4l_buffers.buffer[0].fbuffer_bus = pmem;
- dprintk(4,
- KERN_INFO
- "%s: v4l_fbuffer_alloc() - using %d KB high memory\n",
- ZR_DEVNAME(zr), size >> 10);
- } else {
- fh->v4l_buffers.buffer[i].fbuffer = NULL;
- fh->v4l_buffers.buffer[i].fbuffer_phys =
- pmem + i * fh->v4l_buffers.buffer_size;
- fh->v4l_buffers.buffer[i].fbuffer_bus =
- pmem + i * fh->v4l_buffers.buffer_size;
- }
+ mem = kmalloc(fh->buffers.buffer_size,
+ GFP_KERNEL | __GFP_NOWARN);
+ if (!mem) {
+ dprintk(1,
+ KERN_ERR
+ "%s: %s - kmalloc for V4L buf %d failed\n",
+ ZR_DEVNAME(zr), __func__, i);
+ v4l_fbuffer_free(fh);
+ return -ENOBUFS;
}
+ fh->buffers.buffer[i].v4l.fbuffer = mem;
+ fh->buffers.buffer[i].v4l.fbuffer_phys = virt_to_phys(mem);
+ fh->buffers.buffer[i].v4l.fbuffer_bus = virt_to_bus(mem);
+ for (off = 0; off < fh->buffers.buffer_size;
+ off += PAGE_SIZE)
+ SetPageReserved(virt_to_page(mem + off));
+ dprintk(4,
+ KERN_INFO
+ "%s: %s - V4L frame %d mem 0x%lx (bus: 0x%llx)\n",
+ ZR_DEVNAME(zr), __func__, i, (unsigned long) mem,
+ (unsigned long long)virt_to_bus(mem));
}
- fh->v4l_buffers.allocated = 1;
+ fh->buffers.allocated = 1;
return 0;
}
/* free the V4L grab buffers */
-static void
-v4l_fbuffer_free (struct file *file)
+static void v4l_fbuffer_free(struct zoran_fh *fh)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
int i, off;
unsigned char *mem;
- dprintk(4, KERN_INFO "%s: v4l_fbuffer_free()\n", ZR_DEVNAME(zr));
+ dprintk(4, KERN_INFO "%s: %s\n", ZR_DEVNAME(zr), __func__);
- for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
- if (!fh->v4l_buffers.buffer[i].fbuffer)
+ for (i = 0; i < fh->buffers.num_buffers; i++) {
+ if (!fh->buffers.buffer[i].v4l.fbuffer)
continue;
- if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
- mem = fh->v4l_buffers.buffer[i].fbuffer;
- for (off = 0; off < fh->v4l_buffers.buffer_size;
- off += PAGE_SIZE)
- ClearPageReserved(MAP_NR(mem + off));
- kfree((void *) fh->v4l_buffers.buffer[i].fbuffer);
- }
- fh->v4l_buffers.buffer[i].fbuffer = NULL;
+ mem = fh->buffers.buffer[i].v4l.fbuffer;
+ for (off = 0; off < fh->buffers.buffer_size;
+ off += PAGE_SIZE)
+ ClearPageReserved(virt_to_page(mem + off));
+ kfree(fh->buffers.buffer[i].v4l.fbuffer);
+ fh->buffers.buffer[i].v4l.fbuffer = NULL;
}
- fh->v4l_buffers.allocated = 0;
- fh->v4l_buffers.ready_to_be_freed = 0;
+ fh->buffers.allocated = 0;
}
/*
* Allocate the MJPEG grab buffers.
*
- * If the requested buffer size is smaller than MAX_KMALLOC_MEM,
- * kmalloc is used to request a physically contiguous area,
- * else we allocate the memory in framgents with get_zeroed_page.
- *
* If a Natoma chipset is present and this is a revision 1 zr36057,
* each MJPEG buffer needs to be physically contiguous.
* (RJ: This statement is from Dave Perks' original driver,
* I could never check it because I have a zr36067)
- * The driver cares about this because it reduces the buffer
- * size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation).
*
* RJ: The contents grab buffers needs never be accessed in the driver.
* Therefore there is no need to allocate them with vmalloc in order
@@ -458,162 +307,128 @@ v4l_fbuffer_free (struct file *file)
* and fragment buffers are not little-endian.
*/
-static int
-jpg_fbuffer_alloc (struct file *file)
+static int jpg_fbuffer_alloc(struct zoran_fh *fh)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
int i, j, off;
- unsigned long mem;
-
- /* we might have old buffers lying around */
- if (fh->jpg_buffers.ready_to_be_freed) {
- jpg_fbuffer_free(file);
- }
+ u8 *mem;
- for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
- if (fh->jpg_buffers.buffer[i].frag_tab)
+ for (i = 0; i < fh->buffers.num_buffers; i++) {
+ if (fh->buffers.buffer[i].jpg.frag_tab)
dprintk(2,
KERN_WARNING
- "%s: jpg_fbuffer_alloc() - buffer %d allready allocated!?\n",
- ZR_DEVNAME(zr), i);
+ "%s: %s - buffer %d already allocated!?\n",
+ ZR_DEVNAME(zr), __func__, i);
/* Allocate fragment table for this buffer */
- mem = get_zeroed_page(GFP_KERNEL);
+ mem = (void *)get_zeroed_page(GFP_KERNEL);
if (mem == 0) {
dprintk(1,
KERN_ERR
- "%s: jpg_fbuffer_alloc() - get_zeroed_page (frag_tab) failed for buffer %d\n",
- ZR_DEVNAME(zr), i);
- jpg_fbuffer_free(file);
+ "%s: %s - get_zeroed_page (frag_tab) failed for buffer %d\n",
+ ZR_DEVNAME(zr), __func__, i);
+ jpg_fbuffer_free(fh);
return -ENOBUFS;
}
- fh->jpg_buffers.buffer[i].frag_tab = (__le32 *) mem;
- fh->jpg_buffers.buffer[i].frag_tab_bus =
- virt_to_bus((void *) mem);
-
- //if (alloc_contig) {
- if (fh->jpg_buffers.need_contiguous) {
- mem =
- (unsigned long) kmalloc(fh->jpg_buffers.
- buffer_size,
- GFP_KERNEL);
- if (mem == 0) {
+ fh->buffers.buffer[i].jpg.frag_tab = (__le32 *)mem;
+ fh->buffers.buffer[i].jpg.frag_tab_bus = virt_to_bus(mem);
+
+ if (fh->buffers.need_contiguous) {
+ mem = kmalloc(fh->buffers.buffer_size, GFP_KERNEL);
+ if (mem == NULL) {
dprintk(1,
KERN_ERR
- "%s: jpg_fbuffer_alloc() - kmalloc failed for buffer %d\n",
- ZR_DEVNAME(zr), i);
- jpg_fbuffer_free(file);
+ "%s: %s - kmalloc failed for buffer %d\n",
+ ZR_DEVNAME(zr), __func__, i);
+ jpg_fbuffer_free(fh);
return -ENOBUFS;
}
- fh->jpg_buffers.buffer[i].frag_tab[0] =
- cpu_to_le32(virt_to_bus((void *) mem));
- fh->jpg_buffers.buffer[i].frag_tab[1] =
- cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1);
- for (off = 0; off < fh->jpg_buffers.buffer_size;
- off += PAGE_SIZE)
- SetPageReserved(MAP_NR(mem + off));
+ fh->buffers.buffer[i].jpg.frag_tab[0] =
+ cpu_to_le32(virt_to_bus(mem));
+ fh->buffers.buffer[i].jpg.frag_tab[1] =
+ cpu_to_le32((fh->buffers.buffer_size >> 1) | 1);
+ for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE)
+ SetPageReserved(virt_to_page(mem + off));
} else {
- /* jpg_bufsize is allreay page aligned */
- for (j = 0;
- j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
- j++) {
- mem = get_zeroed_page(GFP_KERNEL);
- if (mem == 0) {
+ /* jpg_bufsize is already page aligned */
+ for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) {
+ mem = (void *)get_zeroed_page(GFP_KERNEL);
+ if (mem == NULL) {
dprintk(1,
KERN_ERR
- "%s: jpg_fbuffer_alloc() - get_zeroed_page failed for buffer %d\n",
- ZR_DEVNAME(zr), i);
- jpg_fbuffer_free(file);
+ "%s: %s - get_zeroed_page failed for buffer %d\n",
+ ZR_DEVNAME(zr), __func__, i);
+ jpg_fbuffer_free(fh);
return -ENOBUFS;
}
- fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
- cpu_to_le32(virt_to_bus((void *) mem));
- fh->jpg_buffers.buffer[i].frag_tab[2 * j +
- 1] =
- cpu_to_le32((PAGE_SIZE / 4) << 1);
- SetPageReserved(MAP_NR(mem));
+ fh->buffers.buffer[i].jpg.frag_tab[2 * j] =
+ cpu_to_le32(virt_to_bus(mem));
+ fh->buffers.buffer[i].jpg.frag_tab[2 * j + 1] =
+ cpu_to_le32((PAGE_SIZE >> 2) << 1);
+ SetPageReserved(virt_to_page(mem));
}
- fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1);
+ fh->buffers.buffer[i].jpg.frag_tab[2 * j - 1] |= cpu_to_le32(1);
}
}
dprintk(4,
- KERN_DEBUG "%s: jpg_fbuffer_alloc() - %d KB allocated\n",
- ZR_DEVNAME(zr),
- (fh->jpg_buffers.num_buffers *
- fh->jpg_buffers.buffer_size) >> 10);
+ KERN_DEBUG "%s: %s - %d KB allocated\n",
+ ZR_DEVNAME(zr), __func__,
+ (fh->buffers.num_buffers * fh->buffers.buffer_size) >> 10);
- fh->jpg_buffers.allocated = 1;
+ fh->buffers.allocated = 1;
return 0;
}
/* free the MJPEG grab buffers */
-static void
-jpg_fbuffer_free (struct file *file)
+static void jpg_fbuffer_free(struct zoran_fh *fh)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
int i, j, off;
unsigned char *mem;
+ __le32 frag_tab;
+ struct zoran_buffer *buffer;
- dprintk(4, KERN_DEBUG "%s: jpg_fbuffer_free()\n", ZR_DEVNAME(zr));
+ dprintk(4, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
- for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
- if (!fh->jpg_buffers.buffer[i].frag_tab)
+ for (i = 0, buffer = &fh->buffers.buffer[0];
+ i < fh->buffers.num_buffers; i++, buffer++) {
+ if (!buffer->jpg.frag_tab)
continue;
- //if (alloc_contig) {
- if (fh->jpg_buffers.need_contiguous) {
- if (fh->jpg_buffers.buffer[i].frag_tab[0]) {
- mem = (unsigned char *) bus_to_virt(le32_to_cpu(
- fh->jpg_buffers.buffer[i].frag_tab[0]));
- for (off = 0;
- off < fh->jpg_buffers.buffer_size;
- off += PAGE_SIZE)
- ClearPageReserved(MAP_NR
- (mem + off));
+ if (fh->buffers.need_contiguous) {
+ frag_tab = buffer->jpg.frag_tab[0];
+
+ if (frag_tab) {
+ mem = bus_to_virt(le32_to_cpu(frag_tab));
+ for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE)
+ ClearPageReserved(virt_to_page(mem + off));
kfree(mem);
- fh->jpg_buffers.buffer[i].frag_tab[0] = 0;
- fh->jpg_buffers.buffer[i].frag_tab[1] = 0;
+ buffer->jpg.frag_tab[0] = 0;
+ buffer->jpg.frag_tab[1] = 0;
}
} else {
- for (j = 0;
- j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
- j++) {
- if (!fh->jpg_buffers.buffer[i].
- frag_tab[2 * j])
+ for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) {
+ frag_tab = buffer->jpg.frag_tab[2 * j];
+
+ if (!frag_tab)
break;
- ClearPageReserved(MAP_NR
- (bus_to_virt
- (le32_to_cpu
- (fh->jpg_buffers.
- buffer[i].frag_tab[2 *
- j]))));
- free_page((unsigned long)
- bus_to_virt
- (le32_to_cpu
- (fh->jpg_buffers.
- buffer[i].
- frag_tab[2 * j])));
- fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
- 0;
- fh->jpg_buffers.buffer[i].frag_tab[2 * j +
- 1] = 0;
+ ClearPageReserved(virt_to_page(bus_to_virt(le32_to_cpu(frag_tab))));
+ free_page((unsigned long)bus_to_virt(le32_to_cpu(frag_tab)));
+ buffer->jpg.frag_tab[2 * j] = 0;
+ buffer->jpg.frag_tab[2 * j + 1] = 0;
}
}
- free_page((unsigned long) fh->jpg_buffers.buffer[i].
- frag_tab);
- fh->jpg_buffers.buffer[i].frag_tab = NULL;
+ free_page((unsigned long)buffer->jpg.frag_tab);
+ buffer->jpg.frag_tab = NULL;
}
- fh->jpg_buffers.allocated = 0;
- fh->jpg_buffers.ready_to_be_freed = 0;
+ fh->buffers.allocated = 0;
}
/*
@@ -621,12 +436,11 @@ jpg_fbuffer_free (struct file *file)
*/
static int
-zoran_v4l_set_format (struct file *file,
+zoran_v4l_set_format (struct zoran_fh *fh,
int width,
int height,
const struct zoran_format *format)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
int bpp;
@@ -636,19 +450,19 @@ zoran_v4l_set_format (struct file *file,
height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) {
dprintk(1,
KERN_ERR
- "%s: v4l_set_format() - wrong frame size (%dx%d)\n",
- ZR_DEVNAME(zr), width, height);
+ "%s: %s - wrong frame size (%dx%d)\n",
+ ZR_DEVNAME(zr), __func__, width, height);
return -EINVAL;
}
bpp = (format->depth + 7) / 8;
/* Check against available buffer size */
- if (height * width * bpp > fh->v4l_buffers.buffer_size) {
+ if (height * width * bpp > fh->buffers.buffer_size) {
dprintk(1,
KERN_ERR
- "%s: v4l_set_format() - video buffer size (%d kB) is too small\n",
- ZR_DEVNAME(zr), fh->v4l_buffers.buffer_size >> 10);
+ "%s: %s - video buffer size (%d kB) is too small\n",
+ ZR_DEVNAME(zr), __func__, fh->buffers.buffer_size >> 10);
return -EINVAL;
}
@@ -657,8 +471,8 @@ zoran_v4l_set_format (struct file *file,
if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) {
dprintk(1,
KERN_ERR
- "%s: v4l_set_format() - wrong frame alingment\n",
- ZR_DEVNAME(zr));
+ "%s: %s - wrong frame alignment\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
@@ -670,43 +484,40 @@ zoran_v4l_set_format (struct file *file,
return 0;
}
-static int
-zoran_v4l_queue_frame (struct file *file,
- int num)
+static int zoran_v4l_queue_frame(struct zoran_fh *fh, int num)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
unsigned long flags;
int res = 0;
- if (!fh->v4l_buffers.allocated) {
+ if (!fh->buffers.allocated) {
dprintk(1,
KERN_ERR
- "%s: v4l_queue_frame() - buffers not yet allocated\n",
- ZR_DEVNAME(zr));
+ "%s: %s - buffers not yet allocated\n",
+ ZR_DEVNAME(zr), __func__);
res = -ENOMEM;
}
/* No grabbing outside the buffer range! */
- if (num >= fh->v4l_buffers.num_buffers || num < 0) {
+ if (num >= fh->buffers.num_buffers || num < 0) {
dprintk(1,
KERN_ERR
- "%s: v4l_queue_frame() - buffer %d is out of range\n",
- ZR_DEVNAME(zr), num);
+ "%s: %s - buffer %d is out of range\n",
+ ZR_DEVNAME(zr), __func__, num);
res = -EINVAL;
}
spin_lock_irqsave(&zr->spinlock, flags);
- if (fh->v4l_buffers.active == ZORAN_FREE) {
+ if (fh->buffers.active == ZORAN_FREE) {
if (zr->v4l_buffers.active == ZORAN_FREE) {
- zr->v4l_buffers = fh->v4l_buffers;
- fh->v4l_buffers.active = ZORAN_ACTIVE;
+ zr->v4l_buffers = fh->buffers;
+ fh->buffers.active = ZORAN_ACTIVE;
} else {
dprintk(1,
KERN_ERR
- "%s: v4l_queue_frame() - another session is already capturing\n",
- ZR_DEVNAME(zr));
+ "%s: %s - another session is already capturing\n",
+ ZR_DEVNAME(zr), __func__);
res = -EBUSY;
}
}
@@ -717,7 +528,7 @@ zoran_v4l_queue_frame (struct file *file,
default:
case BUZ_STATE_PEND:
if (zr->v4l_buffers.active == ZORAN_FREE) {
- fh->v4l_buffers.active = ZORAN_FREE;
+ fh->buffers.active = ZORAN_FREE;
zr->v4l_buffers.allocated = 0;
}
res = -EBUSY; /* what are you doing? */
@@ -725,19 +536,17 @@ zoran_v4l_queue_frame (struct file *file,
case BUZ_STATE_DONE:
dprintk(2,
KERN_WARNING
- "%s: v4l_queue_frame() - queueing buffer %d in state DONE!?\n",
- ZR_DEVNAME(zr), num);
+ "%s: %s - queueing buffer %d in state DONE!?\n",
+ ZR_DEVNAME(zr), __func__, num);
case BUZ_STATE_USER:
/* since there is at least one unused buffer there's room for at least
* one more pend[] entry */
- zr->v4l_pend[zr->v4l_pend_head++ &
- V4L_MASK_FRAME] = num;
+ zr->v4l_pend[zr->v4l_pend_head++ & V4L_MASK_FRAME] = num;
zr->v4l_buffers.buffer[num].state = BUZ_STATE_PEND;
zr->v4l_buffers.buffer[num].bs.length =
fh->v4l_settings.bytesperline *
zr->v4l_settings.height;
- fh->v4l_buffers.buffer[num] =
- zr->v4l_buffers.buffer[num];
+ fh->buffers.buffer[num] = zr->v4l_buffers.buffer[num];
break;
}
}
@@ -745,65 +554,7 @@ zoran_v4l_queue_frame (struct file *file,
spin_unlock_irqrestore(&zr->spinlock, flags);
if (!res && zr->v4l_buffers.active == ZORAN_FREE)
- zr->v4l_buffers.active = fh->v4l_buffers.active;
-
- return res;
-}
-
-static int
-v4l_grab (struct file *file,
- struct video_mmap *mp)
-{
- struct zoran_fh *fh = file->private_data;
- struct zoran *zr = fh->zr;
- int res = 0, i;
-
- for (i = 0; i < NUM_FORMATS; i++) {
- if (zoran_formats[i].palette == mp->format &&
- zoran_formats[i].flags & ZORAN_FORMAT_CAPTURE &&
- !(zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED))
- break;
- }
- if (i == NUM_FORMATS || zoran_formats[i].depth == 0) {
- dprintk(1,
- KERN_ERR
- "%s: v4l_grab() - wrong bytes-per-pixel format\n",
- ZR_DEVNAME(zr));
- return -EINVAL;
- }
-
- /*
- * To minimize the time spent in the IRQ routine, we avoid setting up
- * the video front end there.
- * If this grab has different parameters from a running streaming capture
- * we stop the streaming capture and start it over again.
- */
- if (zr->v4l_memgrab_active &&
- (zr->v4l_settings.width != mp->width ||
- zr->v4l_settings.height != mp->height ||
- zr->v4l_settings.format->palette != mp->format)) {
- res = wait_grab_pending(zr);
- if (res)
- return res;
- }
- if ((res = zoran_v4l_set_format(file,
- mp->width,
- mp->height,
- &zoran_formats[i])))
- return res;
- zr->v4l_settings = fh->v4l_settings;
-
- /* queue the frame in the pending queue */
- if ((res = zoran_v4l_queue_frame(file, mp->frame))) {
- fh->v4l_buffers.active = ZORAN_FREE;
- return res;
- }
-
- /* put the 36057 into frame grabbing mode */
- if (!res && !zr->v4l_memgrab_active)
- zr36057_set_memgrab(zr, 1);
-
- //dprintk(4, KERN_INFO "%s: Frame grab 3...\n", ZR_DEVNAME(zr));
+ zr->v4l_buffers.active = fh->buffers.active;
return res;
}
@@ -812,27 +563,24 @@ v4l_grab (struct file *file,
* Sync on a V4L buffer
*/
-static int
-v4l_sync (struct file *file,
- int frame)
+static int v4l_sync(struct zoran_fh *fh, int frame)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
unsigned long flags;
- if (fh->v4l_buffers.active == ZORAN_FREE) {
+ if (fh->buffers.active == ZORAN_FREE) {
dprintk(1,
KERN_ERR
- "%s: v4l_sync() - no grab active for this session\n",
- ZR_DEVNAME(zr));
+ "%s: %s - no grab active for this session\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
/* check passed-in frame number */
- if (frame >= fh->v4l_buffers.num_buffers || frame < 0) {
+ if (frame >= fh->buffers.num_buffers || frame < 0) {
dprintk(1,
- KERN_ERR "%s: v4l_sync() - frame %d is invalid\n",
- ZR_DEVNAME(zr), frame);
+ KERN_ERR "%s: %s - frame %d is invalid\n",
+ ZR_DEVNAME(zr), __func__, frame);
return -EINVAL;
}
@@ -840,15 +588,14 @@ v4l_sync (struct file *file,
if (zr->v4l_buffers.buffer[frame].state == BUZ_STATE_USER) {
dprintk(1,
KERN_ERR
- "%s: v4l_sync() - attempt to sync on a buffer which was not queued?\n",
- ZR_DEVNAME(zr));
+ "%s: %s - attempt to sync on a buffer which was not queued?\n",
+ ZR_DEVNAME(zr), __func__);
return -EPROTO;
}
/* wait on this buffer to get ready */
if (!wait_event_interruptible_timeout(zr->v4l_capq,
- (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND),
- 10*HZ))
+ (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND), 10*HZ))
return -ETIME;
if (signal_pending(current))
return -ERESTARTSYS;
@@ -856,11 +603,11 @@ v4l_sync (struct file *file,
/* buffer should now be in BUZ_STATE_DONE */
if (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_DONE)
dprintk(2,
- KERN_ERR "%s: v4l_sync() - internal state error\n",
- ZR_DEVNAME(zr));
+ KERN_ERR "%s: %s - internal state error\n",
+ ZR_DEVNAME(zr), __func__);
zr->v4l_buffers.buffer[frame].state = BUZ_STATE_USER;
- fh->v4l_buffers.buffer[frame] = zr->v4l_buffers.buffer[frame];
+ fh->buffers.buffer[frame] = zr->v4l_buffers.buffer[frame];
spin_lock_irqsave(&zr->spinlock, flags);
@@ -868,8 +615,7 @@ v4l_sync (struct file *file,
if (zr->v4l_pend_tail == zr->v4l_pend_head) {
zr36057_set_memgrab(zr, 0);
if (zr->v4l_buffers.active == ZORAN_ACTIVE) {
- fh->v4l_buffers.active = zr->v4l_buffers.active =
- ZORAN_FREE;
+ fh->buffers.active = zr->v4l_buffers.active = ZORAN_FREE;
zr->v4l_buffers.allocated = 0;
}
}
@@ -883,31 +629,28 @@ v4l_sync (struct file *file,
* Queue a MJPEG buffer for capture/playback
*/
-static int
-zoran_jpg_queue_frame (struct file *file,
- int num,
- enum zoran_codec_mode mode)
+static int zoran_jpg_queue_frame(struct zoran_fh *fh, int num,
+ enum zoran_codec_mode mode)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
unsigned long flags;
int res = 0;
/* Check if buffers are allocated */
- if (!fh->jpg_buffers.allocated) {
+ if (!fh->buffers.allocated) {
dprintk(1,
KERN_ERR
- "%s: jpg_queue_frame() - buffers not yet allocated\n",
- ZR_DEVNAME(zr));
+ "%s: %s - buffers not yet allocated\n",
+ ZR_DEVNAME(zr), __func__);
return -ENOMEM;
}
/* No grabbing outside the buffer range! */
- if (num >= fh->jpg_buffers.num_buffers || num < 0) {
+ if (num >= fh->buffers.num_buffers || num < 0) {
dprintk(1,
KERN_ERR
- "%s: jpg_queue_frame() - buffer %d out of range\n",
- ZR_DEVNAME(zr), num);
+ "%s: %s - buffer %d out of range\n",
+ ZR_DEVNAME(zr), __func__, num);
return -EINVAL;
}
@@ -918,20 +661,20 @@ zoran_jpg_queue_frame (struct file *file,
/* wrong codec mode active - invalid */
dprintk(1,
KERN_ERR
- "%s: jpg_queue_frame() - codec in wrong mode\n",
- ZR_DEVNAME(zr));
+ "%s: %s - codec in wrong mode\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
- if (fh->jpg_buffers.active == ZORAN_FREE) {
+ if (fh->buffers.active == ZORAN_FREE) {
if (zr->jpg_buffers.active == ZORAN_FREE) {
- zr->jpg_buffers = fh->jpg_buffers;
- fh->jpg_buffers.active = ZORAN_ACTIVE;
+ zr->jpg_buffers = fh->buffers;
+ fh->buffers.active = ZORAN_ACTIVE;
} else {
dprintk(1,
KERN_ERR
- "%s: jpg_queue_frame() - another session is already capturing\n",
- ZR_DEVNAME(zr));
+ "%s: %s - another session is already capturing\n",
+ ZR_DEVNAME(zr), __func__);
res = -EBUSY;
}
}
@@ -948,23 +691,21 @@ zoran_jpg_queue_frame (struct file *file,
case BUZ_STATE_DONE:
dprintk(2,
KERN_WARNING
- "%s: jpg_queue_frame() - queing frame in BUZ_STATE_DONE state!?\n",
- ZR_DEVNAME(zr));
+ "%s: %s - queing frame in BUZ_STATE_DONE state!?\n",
+ ZR_DEVNAME(zr), __func__);
case BUZ_STATE_USER:
/* since there is at least one unused buffer there's room for at
*least one more pend[] entry */
- zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] =
- num;
+ zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = num;
zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND;
- fh->jpg_buffers.buffer[num] =
- zr->jpg_buffers.buffer[num];
+ fh->buffers.buffer[num] = zr->jpg_buffers.buffer[num];
zoran_feed_stat_com(zr);
break;
default:
case BUZ_STATE_DMA:
case BUZ_STATE_PEND:
if (zr->jpg_buffers.active == ZORAN_FREE) {
- fh->jpg_buffers.active = ZORAN_FREE;
+ fh->buffers.active = ZORAN_FREE;
zr->jpg_buffers.allocated = 0;
}
res = -EBUSY; /* what are you doing? */
@@ -974,47 +715,41 @@ zoran_jpg_queue_frame (struct file *file,
spin_unlock_irqrestore(&zr->spinlock, flags);
- if (!res && zr->jpg_buffers.active == ZORAN_FREE) {
- zr->jpg_buffers.active = fh->jpg_buffers.active;
- }
+ if (!res && zr->jpg_buffers.active == ZORAN_FREE)
+ zr->jpg_buffers.active = fh->buffers.active;
return res;
}
-static int
-jpg_qbuf (struct file *file,
- int frame,
- enum zoran_codec_mode mode)
+static int jpg_qbuf(struct zoran_fh *fh, int frame, enum zoran_codec_mode mode)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
int res = 0;
/* Does the user want to stop streaming? */
if (frame < 0) {
if (zr->codec_mode == mode) {
- if (fh->jpg_buffers.active == ZORAN_FREE) {
+ if (fh->buffers.active == ZORAN_FREE) {
dprintk(1,
KERN_ERR
- "%s: jpg_qbuf(-1) - session not active\n",
- ZR_DEVNAME(zr));
+ "%s: %s(-1) - session not active\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
- fh->jpg_buffers.active = zr->jpg_buffers.active =
- ZORAN_FREE;
+ fh->buffers.active = zr->jpg_buffers.active = ZORAN_FREE;
zr->jpg_buffers.allocated = 0;
zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
return 0;
} else {
dprintk(1,
KERN_ERR
- "%s: jpg_qbuf() - stop streaming but not in streaming mode\n",
- ZR_DEVNAME(zr));
+ "%s: %s - stop streaming but not in streaming mode\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
}
- if ((res = zoran_jpg_queue_frame(file, frame, mode)))
+ if ((res = zoran_jpg_queue_frame(fh, frame, mode)))
return res;
/* Start the jpeg codec when the first frame is queued */
@@ -1028,28 +763,25 @@ jpg_qbuf (struct file *file,
* Sync on a MJPEG buffer
*/
-static int
-jpg_sync (struct file *file,
- struct zoran_sync *bs)
+static int jpg_sync(struct zoran_fh *fh, struct zoran_sync *bs)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
unsigned long flags;
int frame;
- if (fh->jpg_buffers.active == ZORAN_FREE) {
+ if (fh->buffers.active == ZORAN_FREE) {
dprintk(1,
KERN_ERR
- "%s: jpg_sync() - capture is not currently active\n",
- ZR_DEVNAME(zr));
+ "%s: %s - capture is not currently active\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS &&
zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) {
dprintk(1,
KERN_ERR
- "%s: jpg_sync() - codec not in streaming mode\n",
- ZR_DEVNAME(zr));
+ "%s: %s - codec not in streaming mode\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
if (!wait_event_interruptible_timeout(zr->jpg_capq,
@@ -1064,8 +796,8 @@ jpg_sync (struct file *file,
sizeof(isr), &isr);
dprintk(1,
KERN_ERR
- "%s: jpg_sync() - timeout: codec isr=0x%02x\n",
- ZR_DEVNAME(zr), isr);
+ "%s: %s - timeout: codec isr=0x%02x\n",
+ ZR_DEVNAME(zr), __func__, isr);
return -ETIME;
@@ -1083,28 +815,26 @@ jpg_sync (struct file *file,
/* buffer should now be in BUZ_STATE_DONE */
if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE)
dprintk(2,
- KERN_ERR "%s: jpg_sync() - internal state error\n",
- ZR_DEVNAME(zr));
+ KERN_ERR "%s: %s - internal state error\n",
+ ZR_DEVNAME(zr), __func__);
*bs = zr->jpg_buffers.buffer[frame].bs;
bs->frame = frame;
zr->jpg_buffers.buffer[frame].state = BUZ_STATE_USER;
- fh->jpg_buffers.buffer[frame] = zr->jpg_buffers.buffer[frame];
+ fh->buffers.buffer[frame] = zr->jpg_buffers.buffer[frame];
spin_unlock_irqrestore(&zr->spinlock, flags);
return 0;
}
-static void
-zoran_open_init_session (struct file *file)
+static void zoran_open_init_session(struct zoran_fh *fh)
{
int i;
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
/* Per default, map the V4L Buffers */
- fh->map_mode = ZORAN_MAP_MODE_RAW;
+ map_mode_raw(fh);
/* take over the card's current settings */
fh->overlay_settings = zr->overlay_settings;
@@ -1114,40 +844,21 @@ zoran_open_init_session (struct file *file)
/* v4l settings */
fh->v4l_settings = zr->v4l_settings;
-
- /* v4l_buffers */
- memset(&fh->v4l_buffers, 0, sizeof(struct zoran_v4l_struct));
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- fh->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
- fh->v4l_buffers.buffer[i].bs.frame = i;
- }
- fh->v4l_buffers.allocated = 0;
- fh->v4l_buffers.ready_to_be_freed = 0;
- fh->v4l_buffers.active = ZORAN_FREE;
- fh->v4l_buffers.buffer_size = v4l_bufsize;
- fh->v4l_buffers.num_buffers = v4l_nbufs;
-
/* jpg settings */
fh->jpg_settings = zr->jpg_settings;
- /* jpg_buffers */
- memset(&fh->jpg_buffers, 0, sizeof(struct zoran_jpg_struct));
- for (i = 0; i < BUZ_MAX_FRAME; i++) {
- fh->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
- fh->jpg_buffers.buffer[i].bs.frame = i;
+ /* buffers */
+ memset(&fh->buffers, 0, sizeof(fh->buffers));
+ for (i = 0; i < MAX_FRAME; i++) {
+ fh->buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
+ fh->buffers.buffer[i].bs.frame = i;
}
- fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous;
- fh->jpg_buffers.allocated = 0;
- fh->jpg_buffers.ready_to_be_freed = 0;
- fh->jpg_buffers.active = ZORAN_FREE;
- fh->jpg_buffers.buffer_size = jpg_bufsize;
- fh->jpg_buffers.num_buffers = jpg_nbufs;
+ fh->buffers.allocated = 0;
+ fh->buffers.active = ZORAN_FREE;
}
-static void
-zoran_close_end_session (struct file *file)
+static void zoran_close_end_session(struct zoran_fh *fh)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
/* overlay */
@@ -1159,36 +870,32 @@ zoran_close_end_session (struct file *file)
zr->overlay_mask = NULL;
}
- /* v4l capture */
- if (fh->v4l_buffers.active != ZORAN_FREE) {
- unsigned long flags;
+ if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
+ /* v4l capture */
+ if (fh->buffers.active != ZORAN_FREE) {
+ unsigned long flags;
- spin_lock_irqsave(&zr->spinlock, flags);
- zr36057_set_memgrab(zr, 0);
- zr->v4l_buffers.allocated = 0;
- zr->v4l_buffers.active = fh->v4l_buffers.active =
- ZORAN_FREE;
- spin_unlock_irqrestore(&zr->spinlock, flags);
- }
-
- /* v4l buffers */
- if (fh->v4l_buffers.allocated ||
- fh->v4l_buffers.ready_to_be_freed) {
- v4l_fbuffer_free(file);
- }
+ spin_lock_irqsave(&zr->spinlock, flags);
+ zr36057_set_memgrab(zr, 0);
+ zr->v4l_buffers.allocated = 0;
+ zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
+ spin_unlock_irqrestore(&zr->spinlock, flags);
+ }
- /* jpg capture */
- if (fh->jpg_buffers.active != ZORAN_FREE) {
- zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
- zr->jpg_buffers.allocated = 0;
- zr->jpg_buffers.active = fh->jpg_buffers.active =
- ZORAN_FREE;
- }
+ /* v4l buffers */
+ if (fh->buffers.allocated)
+ v4l_fbuffer_free(fh);
+ } else {
+ /* jpg capture */
+ if (fh->buffers.active != ZORAN_FREE) {
+ zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
+ zr->jpg_buffers.allocated = 0;
+ zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE;
+ }
- /* jpg buffers */
- if (fh->jpg_buffers.allocated ||
- fh->jpg_buffers.ready_to_be_freed) {
- jpg_fbuffer_free(file);
+ /* jpg buffers */
+ if (fh->buffers.allocated)
+ jpg_fbuffer_free(fh);
}
}
@@ -1202,15 +909,11 @@ static int zoran_open(struct file *file)
struct zoran_fh *fh;
int res, first_open = 0;
- dprintk(2, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
- ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user + 1);
+ dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(-)=%d\n",
+ ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user + 1);
lock_kernel();
- /* see fs/device.c - the kernel already locks during open(),
- * so locking ourselves only causes deadlocks */
- /*mutex_lock(&zr->resource_lock);*/
-
if (zr->user >= 2048) {
dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
ZR_DEVNAME(zr), zr->user);
@@ -1218,41 +921,15 @@ static int zoran_open(struct file *file)
goto fail_unlock;
}
- if (!zr->decoder) {
- dprintk(1,
- KERN_ERR "%s: no TV decoder loaded for device!\n",
- ZR_DEVNAME(zr));
- res = -EIO;
- goto fail_unlock;
- }
-
- if (!try_module_get(zr->decoder->driver->driver.owner)) {
- dprintk(1,
- KERN_ERR
- "%s: failed to grab ownership of video decoder\n",
- ZR_DEVNAME(zr));
- res = -EIO;
- goto fail_unlock;
- }
- if (zr->encoder &&
- !try_module_get(zr->encoder->driver->driver.owner)) {
- dprintk(1,
- KERN_ERR
- "%s: failed to grab ownership of video encoder\n",
- ZR_DEVNAME(zr));
- res = -EIO;
- goto fail_decoder;
- }
-
/* now, create the open()-specific file_ops struct */
fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
if (!fh) {
dprintk(1,
KERN_ERR
- "%s: zoran_open() - allocation of zoran_fh failed\n",
- ZR_DEVNAME(zr));
+ "%s: %s - allocation of zoran_fh failed\n",
+ ZR_DEVNAME(zr), __func__);
res = -ENOMEM;
- goto fail_encoder;
+ goto fail_unlock;
}
/* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows
* on norm-change! */
@@ -1261,8 +938,8 @@ static int zoran_open(struct file *file)
if (!fh->overlay_mask) {
dprintk(1,
KERN_ERR
- "%s: zoran_open() - allocation of overlay_mask failed\n",
- ZR_DEVNAME(zr));
+ "%s: %s - allocation of overlay_mask failed\n",
+ ZR_DEVNAME(zr), __func__);
res = -ENOMEM;
goto fail_fh;
}
@@ -1284,18 +961,13 @@ static int zoran_open(struct file *file)
/* set file_ops stuff */
file->private_data = fh;
fh->zr = zr;
- zoran_open_init_session(file);
+ zoran_open_init_session(fh);
unlock_kernel();
return 0;
fail_fh:
kfree(fh);
-fail_encoder:
- if (zr->encoder)
- module_put(zr->encoder->driver->driver.owner);
-fail_decoder:
- module_put(zr->decoder->driver->driver.owner);
fail_unlock:
unlock_kernel();
@@ -1311,14 +983,14 @@ zoran_close(struct file *file)
struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
- dprintk(2, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
- ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user - 1);
+ dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(+)=%d\n",
+ ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user - 1);
/* kernel locks (fs/device.c), so don't do that ourselves
* (prevents deadlocks) */
/*mutex_lock(&zr->resource_lock);*/
- zoran_close_end_session(file);
+ zoran_close_end_session(fh);
if (zr->user-- == 1) { /* Last process */
/* Clean up JPEG process */
@@ -1346,9 +1018,10 @@ zoran_close(struct file *file)
zoran_set_pci_master(zr, 0);
if (!pass_through) { /* Switch to color bar */
- int zero = 0, two = 2;
- decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
- encoder_command(zr, ENCODER_SET_INPUT, &two);
+ struct v4l2_routing route = { 2, 0 };
+
+ decoder_call(zr, video, s_stream, 0);
+ encoder_call(zr, video, s_routing, &route);
}
}
@@ -1356,14 +1029,7 @@ zoran_close(struct file *file)
kfree(fh->overlay_mask);
kfree(fh);
- /* release locks on the i2c modules */
- module_put(zr->decoder->driver->driver.owner);
- if (zr->encoder)
- module_put(zr->encoder->driver->driver.owner);
-
- /*mutex_unlock(&zr->resource_lock);*/
-
- dprintk(4, KERN_INFO "%s: zoran_close() done\n", ZR_DEVNAME(zr));
+ dprintk(4, KERN_INFO "%s: %s done\n", ZR_DEVNAME(zr), __func__);
return 0;
}
@@ -1391,15 +1057,13 @@ zoran_write (struct file *file,
return -EINVAL;
}
-static int
-setup_fbuffer (struct file *file,
+static int setup_fbuffer(struct zoran_fh *fh,
void *base,
const struct zoran_format *fmt,
int width,
int height,
int bytesperline)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
/* (Ronald) v4l/v4l2 guidelines */
@@ -1427,8 +1091,8 @@ setup_fbuffer (struct file *file,
* friendly and silently do as if nothing went wrong */
dprintk(3,
KERN_ERR
- "%s: setup_fbuffer() - forced overlay turnoff because framebuffer changed\n",
- ZR_DEVNAME(zr));
+ "%s: %s - forced overlay turnoff because framebuffer changed\n",
+ ZR_DEVNAME(zr), __func__);
zr36057_overlay(zr, 0);
}
#endif
@@ -1436,31 +1100,31 @@ setup_fbuffer (struct file *file,
if (!(fmt->flags & ZORAN_FORMAT_OVERLAY)) {
dprintk(1,
KERN_ERR
- "%s: setup_fbuffer() - no valid overlay format given\n",
- ZR_DEVNAME(zr));
+ "%s: %s - no valid overlay format given\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
if (height <= 0 || width <= 0 || bytesperline <= 0) {
dprintk(1,
KERN_ERR
- "%s: setup_fbuffer() - invalid height/width/bpl value (%d|%d|%d)\n",
- ZR_DEVNAME(zr), width, height, bytesperline);
+ "%s: %s - invalid height/width/bpl value (%d|%d|%d)\n",
+ ZR_DEVNAME(zr), __func__, width, height, bytesperline);
return -EINVAL;
}
if (bytesperline & 3) {
dprintk(1,
KERN_ERR
- "%s: setup_fbuffer() - bytesperline (%d) must be 4-byte aligned\n",
- ZR_DEVNAME(zr), bytesperline);
+ "%s: %s - bytesperline (%d) must be 4-byte aligned\n",
+ ZR_DEVNAME(zr), __func__, bytesperline);
return -EINVAL;
}
- zr->buffer.base = (void *) ((unsigned long) base & ~3);
- zr->buffer.height = height;
- zr->buffer.width = width;
- zr->buffer.depth = fmt->depth;
+ zr->vbuf_base = (void *) ((unsigned long) base & ~3);
+ zr->vbuf_height = height;
+ zr->vbuf_width = width;
+ zr->vbuf_depth = fmt->depth;
zr->overlay_settings.format = fmt;
- zr->buffer.bytesperline = bytesperline;
+ zr->vbuf_bytesperline = bytesperline;
/* The user should set new window parameters */
zr->overlay_settings.is_set = 0;
@@ -1469,35 +1133,27 @@ setup_fbuffer (struct file *file,
}
-static int
-setup_window (struct file *file,
- int x,
- int y,
- int width,
- int height,
- struct video_clip __user *clips,
- int clipcount,
- void __user *bitmap)
+static int setup_window(struct zoran_fh *fh, int x, int y, int width, int height,
+ struct v4l2_clip __user *clips, int clipcount, void __user *bitmap)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
- struct video_clip *vcp = NULL;
+ struct v4l2_clip *vcp = NULL;
int on, end;
- if (!zr->buffer.base) {
+ if (!zr->vbuf_base) {
dprintk(1,
KERN_ERR
- "%s: setup_window() - frame buffer has to be set first\n",
- ZR_DEVNAME(zr));
+ "%s: %s - frame buffer has to be set first\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
if (!fh->overlay_settings.format) {
dprintk(1,
KERN_ERR
- "%s: setup_window() - no overlay format set\n",
- ZR_DEVNAME(zr));
+ "%s: %s - no overlay format set\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
@@ -1505,13 +1161,13 @@ setup_window (struct file *file,
* The video front end needs 4-byte alinged line sizes, we correct that
* silently here if necessary
*/
- if (zr->buffer.depth == 15 || zr->buffer.depth == 16) {
+ if (zr->vbuf_depth == 15 || zr->vbuf_depth == 16) {
end = (x + width) & ~1; /* round down */
x = (x + 1) & ~1; /* round up */
width = end - x;
}
- if (zr->buffer.depth == 24) {
+ if (zr->vbuf_depth == 24) {
end = (x + width) & ~3; /* round down */
x = (x + 3) & ~3; /* round up */
width = end - x;
@@ -1527,8 +1183,8 @@ setup_window (struct file *file,
width > BUZ_MAX_WIDTH || height > BUZ_MAX_HEIGHT) {
dprintk(1,
KERN_ERR
- "%s: setup_window() - width = %d or height = %d invalid\n",
- ZR_DEVNAME(zr), width, height);
+ "%s: %s - width = %d or height = %d invalid\n",
+ ZR_DEVNAME(zr), __func__, width, height);
return -EINVAL;
}
@@ -1566,20 +1222,20 @@ setup_window (struct file *file,
}
} else if (clipcount > 0) {
/* write our own bitmap from the clips */
- vcp = vmalloc(sizeof(struct video_clip) * (clipcount + 4));
+ vcp = vmalloc(sizeof(struct v4l2_clip) * (clipcount + 4));
if (vcp == NULL) {
dprintk(1,
KERN_ERR
- "%s: setup_window() - Alloc of clip mask failed\n",
- ZR_DEVNAME(zr));
+ "%s: %s - Alloc of clip mask failed\n",
+ ZR_DEVNAME(zr), __func__);
return -ENOMEM;
}
if (copy_from_user
- (vcp, clips, sizeof(struct video_clip) * clipcount)) {
+ (vcp, clips, sizeof(struct v4l2_clip) * clipcount)) {
vfree(vcp);
return -EFAULT;
}
- write_overlay_mask(file, vcp, clipcount);
+ write_overlay_mask(fh, vcp, clipcount);
vfree(vcp);
}
@@ -1595,11 +1251,8 @@ setup_window (struct file *file,
return wait_grab_pending(zr);
}
-static int
-setup_overlay (struct file *file,
- int on)
+static int setup_overlay(struct zoran_fh *fh, int on)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
/* If there is nothing to do, return immediatly */
@@ -1612,16 +1265,16 @@ setup_overlay (struct file *file,
fh->overlay_active == ZORAN_FREE) {
dprintk(1,
KERN_ERR
- "%s: setup_overlay() - overlay is already active for another session\n",
- ZR_DEVNAME(zr));
+ "%s: %s - overlay is already active for another session\n",
+ ZR_DEVNAME(zr), __func__);
return -EBUSY;
}
if (!on && zr->overlay_active != ZORAN_FREE &&
fh->overlay_active == ZORAN_FREE) {
dprintk(1,
KERN_ERR
- "%s: setup_overlay() - you cannot cancel someone else's session\n",
- ZR_DEVNAME(zr));
+ "%s: %s - you cannot cancel someone else's session\n",
+ ZR_DEVNAME(zr), __func__);
return -EPERM;
}
@@ -1634,18 +1287,18 @@ setup_overlay (struct file *file,
zr36057_overlay(zr, 0);
zr->overlay_mask = NULL;
} else {
- if (!zr->buffer.base || !fh->overlay_settings.is_set) {
+ if (!zr->vbuf_base || !fh->overlay_settings.is_set) {
dprintk(1,
KERN_ERR
- "%s: setup_overlay() - buffer or window not set\n",
- ZR_DEVNAME(zr));
+ "%s: %s - buffer or window not set\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
if (!fh->overlay_settings.format) {
dprintk(1,
KERN_ERR
- "%s: setup_overlay() - no overlay format set\n",
- ZR_DEVNAME(zr));
+ "%s: %s - no overlay format set\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
zr->overlay_active = fh->overlay_active = ZORAN_LOCKED;
@@ -1662,41 +1315,47 @@ setup_overlay (struct file *file,
return wait_grab_pending(zr);
}
- /* get the status of a buffer in the clients buffer queue */
-static int
-zoran_v4l2_buffer_status (struct file *file,
- struct v4l2_buffer *buf,
- int num)
+/* get the status of a buffer in the clients buffer queue */
+static int zoran_v4l2_buffer_status(struct zoran_fh *fh,
+ struct v4l2_buffer *buf, int num)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
+ unsigned long flags;
buf->flags = V4L2_BUF_FLAG_MAPPED;
switch (fh->map_mode) {
case ZORAN_MAP_MODE_RAW:
-
/* check range */
- if (num < 0 || num >= fh->v4l_buffers.num_buffers ||
- !fh->v4l_buffers.allocated) {
+ if (num < 0 || num >= fh->buffers.num_buffers ||
+ !fh->buffers.allocated) {
dprintk(1,
KERN_ERR
- "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
- ZR_DEVNAME(zr));
+ "%s: %s - wrong number or buffers not allocated\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
+ spin_lock_irqsave(&zr->spinlock, flags);
+ dprintk(3,
+ KERN_DEBUG
+ "%s: %s() - raw active=%c, buffer %d: state=%c, map=%c\n",
+ ZR_DEVNAME(zr), __func__,
+ "FAL"[fh->buffers.active], num,
+ "UPMD"[zr->v4l_buffers.buffer[num].state],
+ fh->buffers.buffer[num].map ? 'Y' : 'N');
+ spin_unlock_irqrestore(&zr->spinlock, flags);
+
buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- buf->length = fh->v4l_buffers.buffer_size;
+ buf->length = fh->buffers.buffer_size;
/* get buffer */
- buf->bytesused = fh->v4l_buffers.buffer[num].bs.length;
- if (fh->v4l_buffers.buffer[num].state == BUZ_STATE_DONE ||
- fh->v4l_buffers.buffer[num].state == BUZ_STATE_USER) {
- buf->sequence = fh->v4l_buffers.buffer[num].bs.seq;
+ buf->bytesused = fh->buffers.buffer[num].bs.length;
+ if (fh->buffers.buffer[num].state == BUZ_STATE_DONE ||
+ fh->buffers.buffer[num].state == BUZ_STATE_USER) {
+ buf->sequence = fh->buffers.buffer[num].bs.seq;
buf->flags |= V4L2_BUF_FLAG_DONE;
- buf->timestamp =
- fh->v4l_buffers.buffer[num].bs.timestamp;
+ buf->timestamp = fh->buffers.buffer[num].bs.timestamp;
} else {
buf->flags |= V4L2_BUF_FLAG_QUEUED;
}
@@ -1712,28 +1371,26 @@ zoran_v4l2_buffer_status (struct file *file,
case ZORAN_MAP_MODE_JPG_PLAY:
/* check range */
- if (num < 0 || num >= fh->jpg_buffers.num_buffers ||
- !fh->jpg_buffers.allocated) {
+ if (num < 0 || num >= fh->buffers.num_buffers ||
+ !fh->buffers.allocated) {
dprintk(1,
KERN_ERR
- "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
- ZR_DEVNAME(zr));
+ "%s: %s - wrong number or buffers not allocated\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
buf->type = (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
V4L2_BUF_TYPE_VIDEO_CAPTURE :
V4L2_BUF_TYPE_VIDEO_OUTPUT;
- buf->length = fh->jpg_buffers.buffer_size;
+ buf->length = fh->buffers.buffer_size;
/* these variables are only written after frame has been captured */
- if (fh->jpg_buffers.buffer[num].state == BUZ_STATE_DONE ||
- fh->jpg_buffers.buffer[num].state == BUZ_STATE_USER) {
- buf->sequence = fh->jpg_buffers.buffer[num].bs.seq;
- buf->timestamp =
- fh->jpg_buffers.buffer[num].bs.timestamp;
- buf->bytesused =
- fh->jpg_buffers.buffer[num].bs.length;
+ if (fh->buffers.buffer[num].state == BUZ_STATE_DONE ||
+ fh->buffers.buffer[num].state == BUZ_STATE_USER) {
+ buf->sequence = fh->buffers.buffer[num].bs.seq;
+ buf->timestamp = fh->buffers.buffer[num].bs.timestamp;
+ buf->bytesused = fh->buffers.buffer[num].bs.length;
buf->flags |= V4L2_BUF_FLAG_DONE;
} else {
buf->flags |= V4L2_BUF_FLAG_QUEUED;
@@ -1741,14 +1398,11 @@ zoran_v4l2_buffer_status (struct file *file,
/* which fields are these? */
if (fh->jpg_settings.TmpDcm != 1)
- buf->field =
- fh->jpg_settings.
- odd_even ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
+ buf->field = fh->jpg_settings.odd_even ?
+ V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
else
- buf->field =
- fh->jpg_settings.
- odd_even ? V4L2_FIELD_SEQ_TB :
- V4L2_FIELD_SEQ_BT;
+ buf->field = fh->jpg_settings.odd_even ?
+ V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT;
break;
@@ -1756,8 +1410,8 @@ zoran_v4l2_buffer_status (struct file *file,
dprintk(5,
KERN_ERR
- "%s: v4l2_buffer_status() - invalid buffer type|map_mode (%d|%d)\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
+ "%s: %s - invalid buffer type|map_mode (%d|%d)\n",
+ ZR_DEVNAME(zr), __func__, buf->type, fh->map_mode);
return -EINVAL;
}
@@ -1770,81 +1424,55 @@ zoran_v4l2_buffer_status (struct file *file,
static int
zoran_set_norm (struct zoran *zr,
- int norm) /* VIDEO_MODE_* */
+ v4l2_std_id norm)
{
- int norm_encoder, on;
+ int on;
if (zr->v4l_buffers.active != ZORAN_FREE ||
zr->jpg_buffers.active != ZORAN_FREE) {
dprintk(1,
KERN_WARNING
- "%s: set_norm() called while in playback/capture mode\n",
- ZR_DEVNAME(zr));
+ "%s: %s called while in playback/capture mode\n",
+ ZR_DEVNAME(zr), __func__);
return -EBUSY;
}
- if (lock_norm && norm != zr->norm) {
- if (lock_norm > 1) {
- dprintk(1,
- KERN_WARNING
- "%s: set_norm() - TV standard is locked, can not switch norm\n",
- ZR_DEVNAME(zr));
- return -EPERM;
- } else {
- dprintk(1,
- KERN_WARNING
- "%s: set_norm() - TV standard is locked, norm was not changed\n",
- ZR_DEVNAME(zr));
- norm = zr->norm;
- }
- }
-
- if (norm != VIDEO_MODE_AUTO &&
- (norm < 0 || norm >= zr->card.norms ||
- !zr->card.tvn[norm])) {
+ if (!(norm & zr->card.norms)) {
dprintk(1,
- KERN_ERR "%s: set_norm() - unsupported norm %d\n",
- ZR_DEVNAME(zr), norm);
+ KERN_ERR "%s: %s - unsupported norm %llx\n",
+ ZR_DEVNAME(zr), __func__, norm);
return -EINVAL;
}
- if (norm == VIDEO_MODE_AUTO) {
- int status;
+ if (norm == V4L2_STD_ALL) {
+ int status = 0;
+ v4l2_std_id std = 0;
- /* if we have autodetect, ... */
- struct video_decoder_capability caps;
- decoder_command(zr, DECODER_GET_CAPABILITIES, &caps);
- if (!(caps.flags & VIDEO_DECODER_AUTO)) {
- dprintk(1, KERN_ERR "%s: norm=auto unsupported\n",
- ZR_DEVNAME(zr));
- return -EINVAL;
- }
-
- decoder_command(zr, DECODER_SET_NORM, &norm);
+ decoder_call(zr, video, querystd, &std);
+ decoder_call(zr, tuner, s_std, std);
/* let changes come into effect */
ssleep(2);
- decoder_command(zr, DECODER_GET_STATUS, &status);
- if (!(status & DECODER_STATUS_GOOD)) {
+ decoder_call(zr, video, g_input_status, &status);
+ if (status & V4L2_IN_ST_NO_SIGNAL) {
dprintk(1,
KERN_ERR
- "%s: set_norm() - no norm detected\n",
- ZR_DEVNAME(zr));
+ "%s: %s - no norm detected\n",
+ ZR_DEVNAME(zr), __func__);
/* reset norm */
- decoder_command(zr, DECODER_SET_NORM, &zr->norm);
+ decoder_call(zr, tuner, s_std, zr->norm);
return -EIO;
}
- if (status & DECODER_STATUS_NTSC)
- norm = VIDEO_MODE_NTSC;
- else if (status & DECODER_STATUS_SECAM)
- norm = VIDEO_MODE_SECAM;
- else
- norm = VIDEO_MODE_PAL;
+ norm = std;
}
- zr->timing = zr->card.tvn[norm];
- norm_encoder = norm;
+ if (norm & V4L2_STD_SECAM)
+ zr->timing = zr->card.tvn[2];
+ else if (norm & V4L2_STD_NTSC)
+ zr->timing = zr->card.tvn[1];
+ else
+ zr->timing = zr->card.tvn[0];
/* We switch overlay off and on since a change in the
* norm needs different VFE settings */
@@ -1852,8 +1480,8 @@ zoran_set_norm (struct zoran *zr,
if (on)
zr36057_overlay(zr, 0);
- decoder_command(zr, DECODER_SET_NORM, &norm);
- encoder_command(zr, ENCODER_SET_NORM, &norm_encoder);
+ decoder_call(zr, tuner, s_std, norm);
+ encoder_call(zr, video, s_std_output, norm);
if (on)
zr36057_overlay(zr, 1);
@@ -1868,7 +1496,7 @@ static int
zoran_set_input (struct zoran *zr,
int input)
{
- int realinput;
+ struct v4l2_routing route = { 0, 0 };
if (input == zr->input) {
return 0;
@@ -1878,23 +1506,23 @@ zoran_set_input (struct zoran *zr,
zr->jpg_buffers.active != ZORAN_FREE) {
dprintk(1,
KERN_WARNING
- "%s: set_input() called while in playback/capture mode\n",
- ZR_DEVNAME(zr));
+ "%s: %s called while in playback/capture mode\n",
+ ZR_DEVNAME(zr), __func__);
return -EBUSY;
}
if (input < 0 || input >= zr->card.inputs) {
dprintk(1,
KERN_ERR
- "%s: set_input() - unnsupported input %d\n",
- ZR_DEVNAME(zr), input);
+ "%s: %s - unnsupported input %d\n",
+ ZR_DEVNAME(zr), __func__, input);
return -EINVAL;
}
- realinput = zr->card.input[input].muxsel;
+ route.input = zr->card.input[input].muxsel;
zr->input = input;
- decoder_command(zr, DECODER_SET_INPUT, &realinput);
+ decoder_call(zr, video, s_routing, &route);
return 0;
}
@@ -1903,410 +1531,14 @@ zoran_set_input (struct zoran *zr,
* ioctl routine
*/
-static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
{
- struct zoran_fh *fh = file->private_data;
+ struct zoran_fh *fh = __fh;
struct zoran *zr = fh->zr;
- /* CAREFUL: used in multiple places here */
struct zoran_jpg_settings settings;
- /* we might have older buffers lying around... We don't want
- * to wait, but we do want to try cleaning them up ASAP. So
- * we try to obtain the lock and free them. If that fails, we
- * don't do anything and wait for the next turn. In the end,
- * zoran_close() or a new allocation will still free them...
- * This is just a 'the sooner the better' extra 'feature'
- *
- * We don't free the buffers right on munmap() because that
- * causes oopses (kfree() inside munmap() oopses for no
- * apparent reason - it's also not reproduceable in any way,
- * but moving the free code outside the munmap() handler fixes
- * all this... If someone knows why, please explain me (Ronald)
- */
- if (mutex_trylock(&zr->resource_lock)) {
- /* we obtained it! Let's try to free some things */
- if (fh->jpg_buffers.ready_to_be_freed)
- jpg_fbuffer_free(file);
- if (fh->v4l_buffers.ready_to_be_freed)
- v4l_fbuffer_free(file);
-
- mutex_unlock(&zr->resource_lock);
- }
-
switch (cmd) {
-
- case VIDIOCGCAP:
- {
- struct video_capability *vcap = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr));
-
- memset(vcap, 0, sizeof(struct video_capability));
- strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name)-1);
- vcap->type = ZORAN_VID_TYPE;
-
- vcap->channels = zr->card.inputs;
- vcap->audios = 0;
- mutex_lock(&zr->resource_lock);
- vcap->maxwidth = BUZ_MAX_WIDTH;
- vcap->maxheight = BUZ_MAX_HEIGHT;
- vcap->minwidth = BUZ_MIN_WIDTH;
- vcap->minheight = BUZ_MIN_HEIGHT;
- mutex_unlock(&zr->resource_lock);
-
- return 0;
- }
- break;
-
- case VIDIOCGCHAN:
- {
- struct video_channel *vchan = arg;
- int channel = vchan->channel;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGCHAN - channel=%d\n",
- ZR_DEVNAME(zr), vchan->channel);
-
- memset(vchan, 0, sizeof(struct video_channel));
- if (channel > zr->card.inputs || channel < 0) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOCGCHAN on not existing channel %d\n",
- ZR_DEVNAME(zr), channel);
- return -EINVAL;
- }
-
- strcpy(vchan->name, zr->card.input[channel].name);
-
- vchan->tuners = 0;
- vchan->flags = 0;
- vchan->type = VIDEO_TYPE_CAMERA;
- mutex_lock(&zr->resource_lock);
- vchan->norm = zr->norm;
- mutex_unlock(&zr->resource_lock);
- vchan->channel = channel;
-
- return 0;
- }
- break;
-
- /* RJ: the documentation at http://roadrunner.swansea.linux.org.uk/v4lapi.shtml says:
- *
- * * "The VIDIOCSCHAN ioctl takes an integer argument and switches the capture to this input."
- * * ^^^^^^^
- * * The famos BTTV driver has it implemented with a struct video_channel argument
- * * and we follow it for compatibility reasons
- * *
- * * BTW: this is the only way the user can set the norm!
- */
-
- case VIDIOCSCHAN:
- {
- struct video_channel *vchan = arg;
- int res;
-
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOCSCHAN - channel=%d, norm=%d\n",
- ZR_DEVNAME(zr), vchan->channel, vchan->norm);
-
- mutex_lock(&zr->resource_lock);
- if ((res = zoran_set_input(zr, vchan->channel)))
- goto schan_unlock_and_return;
- if ((res = zoran_set_norm(zr, vchan->norm)))
- goto schan_unlock_and_return;
-
- /* Make sure the changes come into effect */
- res = wait_grab_pending(zr);
- schan_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
- }
- break;
-
- case VIDIOCGPICT:
- {
- struct video_picture *vpict = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGPICT\n", ZR_DEVNAME(zr));
-
- memset(vpict, 0, sizeof(struct video_picture));
- mutex_lock(&zr->resource_lock);
- vpict->hue = zr->hue;
- vpict->brightness = zr->brightness;
- vpict->contrast = zr->contrast;
- vpict->colour = zr->saturation;
- if (fh->overlay_settings.format) {
- vpict->depth = fh->overlay_settings.format->depth;
- vpict->palette = fh->overlay_settings.format->palette;
- } else {
- vpict->depth = 0;
- }
- mutex_unlock(&zr->resource_lock);
-
- return 0;
- }
- break;
-
- case VIDIOCSPICT:
- {
- struct video_picture *vpict = arg;
- int i;
-
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOCSPICT - bri=%d, hue=%d, col=%d, con=%d, dep=%d, pal=%d\n",
- ZR_DEVNAME(zr), vpict->brightness, vpict->hue,
- vpict->colour, vpict->contrast, vpict->depth,
- vpict->palette);
-
- for (i = 0; i < NUM_FORMATS; i++) {
- const struct zoran_format *fmt = &zoran_formats[i];
-
- if (fmt->palette != -1 &&
- fmt->flags & ZORAN_FORMAT_OVERLAY &&
- fmt->palette == vpict->palette &&
- fmt->depth == vpict->depth)
- break;
- }
- if (i == NUM_FORMATS) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOCSPICT - Invalid palette %d\n",
- ZR_DEVNAME(zr), vpict->palette);
- return -EINVAL;
- }
-
- mutex_lock(&zr->resource_lock);
-
- decoder_command(zr, DECODER_SET_PICTURE, vpict);
-
- zr->hue = vpict->hue;
- zr->contrast = vpict->contrast;
- zr->saturation = vpict->colour;
- zr->brightness = vpict->brightness;
-
- fh->overlay_settings.format = &zoran_formats[i];
-
- mutex_unlock(&zr->resource_lock);
-
- return 0;
- }
- break;
-
- case VIDIOCCAPTURE:
- {
- int *on = arg, res;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCCAPTURE - on=%d\n",
- ZR_DEVNAME(zr), *on);
-
- mutex_lock(&zr->resource_lock);
- res = setup_overlay(file, *on);
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
- break;
-
- case VIDIOCGWIN:
- {
- struct video_window *vwin = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGWIN\n", ZR_DEVNAME(zr));
-
- memset(vwin, 0, sizeof(struct video_window));
- mutex_lock(&zr->resource_lock);
- vwin->x = fh->overlay_settings.x;
- vwin->y = fh->overlay_settings.y;
- vwin->width = fh->overlay_settings.width;
- vwin->height = fh->overlay_settings.height;
- mutex_unlock(&zr->resource_lock);
- vwin->clipcount = 0;
- return 0;
- }
- break;
-
- case VIDIOCSWIN:
- {
- struct video_window *vwin = arg;
- int res;
-
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOCSWIN - x=%d, y=%d, w=%d, h=%d, clipcount=%d\n",
- ZR_DEVNAME(zr), vwin->x, vwin->y, vwin->width,
- vwin->height, vwin->clipcount);
-
- mutex_lock(&zr->resource_lock);
- res =
- setup_window(file, vwin->x, vwin->y, vwin->width,
- vwin->height, vwin->clips,
- vwin->clipcount, NULL);
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
- break;
-
- case VIDIOCGFBUF:
- {
- struct video_buffer *vbuf = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGFBUF\n", ZR_DEVNAME(zr));
-
- mutex_lock(&zr->resource_lock);
- *vbuf = zr->buffer;
- mutex_unlock(&zr->resource_lock);
- return 0;
- }
- break;
-
- case VIDIOCSFBUF:
- {
- struct video_buffer *vbuf = arg;
- int i, res = 0;
-
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOCSFBUF - base=%p, w=%d, h=%d, depth=%d, bpl=%d\n",
- ZR_DEVNAME(zr), vbuf->base, vbuf->width,
- vbuf->height, vbuf->depth, vbuf->bytesperline);
-
- for (i = 0; i < NUM_FORMATS; i++)
- if (zoran_formats[i].depth == vbuf->depth)
- break;
- if (i == NUM_FORMATS) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOCSFBUF - invalid fbuf depth %d\n",
- ZR_DEVNAME(zr), vbuf->depth);
- return -EINVAL;
- }
-
- mutex_lock(&zr->resource_lock);
- res =
- setup_fbuffer(file, vbuf->base, &zoran_formats[i],
- vbuf->width, vbuf->height,
- vbuf->bytesperline);
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
- break;
-
- case VIDIOCSYNC:
- {
- int *frame = arg, res;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCSYNC - frame=%d\n",
- ZR_DEVNAME(zr), *frame);
-
- mutex_lock(&zr->resource_lock);
- res = v4l_sync(file, *frame);
- mutex_unlock(&zr->resource_lock);
- if (!res)
- zr->v4l_sync_tail++;
- return res;
- }
- break;
-
- case VIDIOCMCAPTURE:
- {
- struct video_mmap *vmap = arg;
- int res;
-
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOCMCAPTURE - frame=%d, geom=%dx%d, fmt=%d\n",
- ZR_DEVNAME(zr), vmap->frame, vmap->width, vmap->height,
- vmap->format);
-
- mutex_lock(&zr->resource_lock);
- res = v4l_grab(file, vmap);
- mutex_unlock(&zr->resource_lock);
- return res;
- }
- break;
-
- case VIDIOCGMBUF:
- {
- struct video_mbuf *vmbuf = arg;
- int i, res = 0;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGMBUF\n", ZR_DEVNAME(zr));
-
- vmbuf->size =
- fh->v4l_buffers.num_buffers *
- fh->v4l_buffers.buffer_size;
- vmbuf->frames = fh->v4l_buffers.num_buffers;
- for (i = 0; i < vmbuf->frames; i++) {
- vmbuf->offsets[i] =
- i * fh->v4l_buffers.buffer_size;
- }
-
- mutex_lock(&zr->resource_lock);
-
- if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOCGMBUF - buffers already allocated\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto v4l1reqbuf_unlock_and_return;
- }
-
- if (v4l_fbuffer_alloc(file)) {
- res = -ENOMEM;
- goto v4l1reqbuf_unlock_and_return;
- }
-
- /* The next mmap will map the V4L buffers */
- fh->map_mode = ZORAN_MAP_MODE_RAW;
- v4l1reqbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
- break;
-
- case VIDIOCGUNIT:
- {
- struct video_unit *vunit = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGUNIT\n", ZR_DEVNAME(zr));
-
- vunit->video = zr->video_dev->minor;
- vunit->vbi = VIDEO_NO_UNIT;
- vunit->radio = VIDEO_NO_UNIT;
- vunit->audio = VIDEO_NO_UNIT;
- vunit->teletext = VIDEO_NO_UNIT;
-
- return 0;
- }
- break;
-
- /*
- * RJ: In principal we could support subcaptures for V4L grabbing.
- * Not even the famous BTTV driver has them, however.
- * If there should be a strong demand, one could consider
- * to implement them.
- */
- case VIDIOCGCAPTURE:
- {
- dprintk(3, KERN_ERR "%s: VIDIOCGCAPTURE not supported\n",
- ZR_DEVNAME(zr));
- return -EINVAL;
- }
- break;
-
- case VIDIOCSCAPTURE:
- {
- dprintk(3, KERN_ERR "%s: VIDIOCSCAPTURE not supported\n",
- ZR_DEVNAME(zr));
- return -EINVAL;
- }
- break;
-
case BUZIOC_G_PARAMS:
{
struct zoran_params *bparams = arg;
@@ -2319,7 +1551,13 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
mutex_lock(&zr->resource_lock);
- bparams->norm = zr->norm;
+ if (zr->norm & V4L2_STD_NTSC)
+ bparams->norm = VIDEO_MODE_NTSC;
+ else if (zr->norm & V4L2_STD_PAL)
+ bparams->norm = VIDEO_MODE_PAL;
+ else
+ bparams->norm = VIDEO_MODE_SECAM;
+
bparams->input = zr->input;
bparams->decimation = fh->jpg_settings.decimation;
@@ -2352,7 +1590,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
return 0;
}
- break;
case BUZIOC_S_PARAMS:
{
@@ -2395,18 +1632,17 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
/* Check the params first before overwriting our
* nternal values */
- if (zoran_check_jpg_settings(zr, &settings)) {
+ if (zoran_check_jpg_settings(zr, &settings, 0)) {
res = -EINVAL;
goto sparams_unlock_and_return;
}
fh->jpg_settings = settings;
- sparams_unlock_and_return:
+sparams_unlock_and_return:
mutex_unlock(&zr->resource_lock);
return res;
}
- break;
case BUZIOC_REQBUFS:
{
@@ -2430,38 +1666,34 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
* tables to a Maximum of 2 MB */
if (breq->size > jpg_bufsize)
breq->size = jpg_bufsize;
- if (fh->jpg_buffers.need_contiguous &&
- breq->size > MAX_KMALLOC_MEM)
- breq->size = MAX_KMALLOC_MEM;
mutex_lock(&zr->resource_lock);
- if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
+ if (fh->buffers.allocated) {
dprintk(1,
KERN_ERR
- "%s: BUZIOC_REQBUFS - buffers allready allocated\n",
+ "%s: BUZIOC_REQBUFS - buffers already allocated\n",
ZR_DEVNAME(zr));
res = -EBUSY;
goto jpgreqbuf_unlock_and_return;
}
- fh->jpg_buffers.num_buffers = breq->count;
- fh->jpg_buffers.buffer_size = breq->size;
+ /* The next mmap will map the MJPEG buffers - could
+ * also be *_PLAY, but it doesn't matter here */
+ map_mode_jpg(fh, 0);
+ fh->buffers.num_buffers = breq->count;
+ fh->buffers.buffer_size = breq->size;
- if (jpg_fbuffer_alloc(file)) {
+ if (jpg_fbuffer_alloc(fh)) {
res = -ENOMEM;
goto jpgreqbuf_unlock_and_return;
}
- /* The next mmap will map the MJPEG buffers - could
- * also be *_PLAY, but it doesn't matter here */
- fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
- jpgreqbuf_unlock_and_return:
+jpgreqbuf_unlock_and_return:
mutex_unlock(&zr->resource_lock);
return res;
}
- break;
case BUZIOC_QBUF_CAPT:
{
@@ -2471,12 +1703,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
ZR_DEVNAME(zr), *frame);
mutex_lock(&zr->resource_lock);
- res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_COMPRESS);
+ res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_COMPRESS);
mutex_unlock(&zr->resource_lock);
return res;
}
- break;
case BUZIOC_QBUF_PLAY:
{
@@ -2486,12 +1717,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
ZR_DEVNAME(zr), *frame);
mutex_lock(&zr->resource_lock);
- res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_DECOMPRESS);
+ res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_DECOMPRESS);
mutex_unlock(&zr->resource_lock);
return res;
}
- break;
case BUZIOC_SYNC:
{
@@ -2501,17 +1731,26 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr));
mutex_lock(&zr->resource_lock);
- res = jpg_sync(file, bsync);
+
+ if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
+ dprintk(2, KERN_WARNING
+ "%s: %s - not in jpg capture mode\n",
+ ZR_DEVNAME(zr), __func__);
+ res = -EINVAL;
+ } else {
+ res = jpg_sync(fh, bsync);
+ }
mutex_unlock(&zr->resource_lock);
return res;
}
- break;
case BUZIOC_G_STATUS:
{
struct zoran_status *bstat = arg;
- int norm, input, status, res = 0;
+ struct v4l2_routing route = { 0, 0 };
+ int status = 0, res = 0;
+ v4l2_std_id norm;
dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr));
@@ -2523,8 +1762,7 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
return -EINVAL;
}
- input = zr->card.input[bstat->input].muxsel;
- norm = VIDEO_MODE_AUTO;
+ route.input = zr->card.input[bstat->input].muxsel;
mutex_lock(&zr->resource_lock);
@@ -2537,1629 +1775,1262 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
goto gstat_unlock_and_return;
}
- decoder_command(zr, DECODER_SET_INPUT, &input);
- decoder_command(zr, DECODER_SET_NORM, &norm);
+ decoder_call(zr, video, s_routing, &route);
/* sleep 1 second */
ssleep(1);
/* Get status of video decoder */
- decoder_command(zr, DECODER_GET_STATUS, &status);
+ decoder_call(zr, video, querystd, &norm);
+ decoder_call(zr, video, g_input_status, &status);
/* restore previous input and norm */
- input = zr->card.input[zr->input].muxsel;
- decoder_command(zr, DECODER_SET_INPUT, &input);
- decoder_command(zr, DECODER_SET_NORM, &zr->norm);
- gstat_unlock_and_return:
+ route.input = zr->card.input[zr->input].muxsel;
+ decoder_call(zr, video, s_routing, &route);
+gstat_unlock_and_return:
mutex_unlock(&zr->resource_lock);
if (!res) {
bstat->signal =
- (status & DECODER_STATUS_GOOD) ? 1 : 0;
- if (status & DECODER_STATUS_NTSC)
+ (status & V4L2_IN_ST_NO_SIGNAL) ? 0 : 1;
+ if (norm & V4L2_STD_NTSC)
bstat->norm = VIDEO_MODE_NTSC;
- else if (status & DECODER_STATUS_SECAM)
+ else if (norm & V4L2_STD_SECAM)
bstat->norm = VIDEO_MODE_SECAM;
else
bstat->norm = VIDEO_MODE_PAL;
bstat->color =
- (status & DECODER_STATUS_COLOR) ? 1 : 0;
+ (status & V4L2_IN_ST_NO_COLOR) ? 0 : 1;
}
return res;
}
- break;
-
- /* The new video4linux2 capture interface - much nicer than video4linux1, since
- * it allows for integrating the JPEG capturing calls inside standard v4l2
- */
-
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *cap = arg;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr));
-
- memset(cap, 0, sizeof(*cap));
- strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1);
- strncpy(cap->driver, "zoran", sizeof(cap->driver)-1);
- snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
- pci_name(zr->pci_dev));
- cap->version =
- KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION,
- RELEASE_VERSION);
- cap->capabilities = ZORAN_V4L2_VID_FLAGS;
-
- return 0;
+ default:
+ return -EINVAL;
}
- break;
+}
- case VIDIOC_ENUM_FMT:
- {
- struct v4l2_fmtdesc *fmt = arg;
- int index = fmt->index, num = -1, i, flag = 0, type =
- fmt->type;
+static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *vmbuf)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int i, res = 0;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUM_FMT - index=%d\n",
- ZR_DEVNAME(zr), fmt->index);
- switch (fmt->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- flag = ZORAN_FORMAT_CAPTURE;
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- flag = ZORAN_FORMAT_PLAYBACK;
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- flag = ZORAN_FORMAT_OVERLAY;
- break;
- default:
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_ENUM_FMT - unknown type %d\n",
- ZR_DEVNAME(zr), fmt->type);
- return -EINVAL;
- }
+ mutex_lock(&zr->resource_lock);
- for (i = 0; i < NUM_FORMATS; i++) {
- if (zoran_formats[i].flags & flag)
- num++;
- if (num == fmt->index)
- break;
- }
- if (fmt->index < 0 /* late, but not too late */ ||
- i == NUM_FORMATS)
- return -EINVAL;
+ if (fh->buffers.allocated) {
+ dprintk(1,
+ KERN_ERR
+ "%s: VIDIOCGMBUF - buffers already allocated\n",
+ ZR_DEVNAME(zr));
+ res = -EINVAL;
+ goto v4l1reqbuf_unlock_and_return;
+ }
- memset(fmt, 0, sizeof(*fmt));
- fmt->index = index;
- fmt->type = type;
- strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1);
- fmt->pixelformat = zoran_formats[i].fourcc;
- if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
- fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
+ /* The next mmap will map the V4L buffers */
+ map_mode_raw(fh);
- return 0;
+ if (v4l_fbuffer_alloc(fh)) {
+ res = -ENOMEM;
+ goto v4l1reqbuf_unlock_and_return;
}
- break;
-
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *fmt = arg;
- int type = fmt->type;
- dprintk(5, KERN_DEBUG "%s: VIDIOC_G_FMT\n", ZR_DEVNAME(zr));
+ vmbuf->size = fh->buffers.num_buffers * fh->buffers.buffer_size;
+ vmbuf->frames = fh->buffers.num_buffers;
+ for (i = 0; i < vmbuf->frames; i++)
+ vmbuf->offsets[i] = i * fh->buffers.buffer_size;
- memset(fmt, 0, sizeof(*fmt));
- fmt->type = type;
+v4l1reqbuf_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- switch (fmt->type) {
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ return res;
+}
+#endif
- mutex_lock(&zr->resource_lock);
+static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- fmt->fmt.win.w.left = fh->overlay_settings.x;
- fmt->fmt.win.w.top = fh->overlay_settings.y;
- fmt->fmt.win.w.width = fh->overlay_settings.width;
- fmt->fmt.win.w.height =
- fh->overlay_settings.height;
- if (fh->overlay_settings.width * 2 >
- BUZ_MAX_HEIGHT)
- fmt->fmt.win.field = V4L2_FIELD_INTERLACED;
- else
- fmt->fmt.win.field = V4L2_FIELD_TOP;
+ memset(cap, 0, sizeof(*cap));
+ strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1);
+ strncpy(cap->driver, "zoran", sizeof(cap->driver)-1);
+ snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
+ pci_name(zr->pci_dev));
+ cap->version = KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION,
+ RELEASE_VERSION);
+ cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OVERLAY;
+ return 0;
+}
- mutex_unlock(&zr->resource_lock);
+static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag)
+{
+ int num = -1, i;
+ for (i = 0; i < NUM_FORMATS; i++) {
+ if (zoran_formats[i].flags & flag)
+ num++;
+ if (num == fmt->index)
break;
+ }
+ if (fmt->index < 0 /* late, but not too late */ || i == NUM_FORMATS)
+ return -EINVAL;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-
- mutex_lock(&zr->resource_lock);
-
- if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- fh->map_mode == ZORAN_MAP_MODE_RAW) {
-
- fmt->fmt.pix.width =
- fh->v4l_settings.width;
- fmt->fmt.pix.height =
- fh->v4l_settings.height;
- fmt->fmt.pix.sizeimage =
- fh->v4l_settings.bytesperline *
- fh->v4l_settings.height;
- fmt->fmt.pix.pixelformat =
- fh->v4l_settings.format->fourcc;
- fmt->fmt.pix.colorspace =
- fh->v4l_settings.format->colorspace;
- fmt->fmt.pix.bytesperline =
- fh->v4l_settings.bytesperline;
- if (BUZ_MAX_HEIGHT <
- (fh->v4l_settings.height * 2))
- fmt->fmt.pix.field =
- V4L2_FIELD_INTERLACED;
- else
- fmt->fmt.pix.field =
- V4L2_FIELD_TOP;
-
- } else {
-
- fmt->fmt.pix.width =
- fh->jpg_settings.img_width /
- fh->jpg_settings.HorDcm;
- fmt->fmt.pix.height =
- fh->jpg_settings.img_height /
- (fh->jpg_settings.VerDcm *
- fh->jpg_settings.TmpDcm);
- fmt->fmt.pix.sizeimage =
- zoran_v4l2_calc_bufsize(&fh->
- jpg_settings);
- fmt->fmt.pix.pixelformat =
- V4L2_PIX_FMT_MJPEG;
- if (fh->jpg_settings.TmpDcm == 1)
- fmt->fmt.pix.field =
- (fh->jpg_settings.
- odd_even ? V4L2_FIELD_SEQ_BT :
- V4L2_FIELD_SEQ_BT);
- else
- fmt->fmt.pix.field =
- (fh->jpg_settings.
- odd_even ? V4L2_FIELD_TOP :
- V4L2_FIELD_BOTTOM);
-
- fmt->fmt.pix.bytesperline = 0;
- fmt->fmt.pix.colorspace =
- V4L2_COLORSPACE_SMPTE170M;
- }
-
- mutex_unlock(&zr->resource_lock);
+ strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1);
+ fmt->pixelformat = zoran_formats[i].fourcc;
+ if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
+ fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
+ return 0;
+}
- break;
+static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
+ struct v4l2_fmtdesc *f)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- default:
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_G_FMT - unsupported type %d\n",
- ZR_DEVNAME(zr), fmt->type);
- return -EINVAL;
- }
- return 0;
- }
- break;
+ return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE);
+}
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *fmt = arg;
- int i, res = 0;
- __le32 printformat;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOC_S_FMT - type=%d, ",
- ZR_DEVNAME(zr), fmt->type);
-
- switch (fmt->type) {
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-
- dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n",
- fmt->fmt.win.w.left, fmt->fmt.win.w.top,
- fmt->fmt.win.w.width,
- fmt->fmt.win.w.height,
- fmt->fmt.win.clipcount,
- fmt->fmt.win.bitmap);
- mutex_lock(&zr->resource_lock);
- res =
- setup_window(file, fmt->fmt.win.w.left,
- fmt->fmt.win.w.top,
- fmt->fmt.win.w.width,
- fmt->fmt.win.w.height,
- (struct video_clip __user *)
- fmt->fmt.win.clips,
- fmt->fmt.win.clipcount,
- fmt->fmt.win.bitmap);
- mutex_unlock(&zr->resource_lock);
- return res;
- break;
+static int zoran_enum_fmt_vid_out(struct file *file, void *__fh,
+ struct v4l2_fmtdesc *f)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-
- printformat =
- __cpu_to_le32(fmt->fmt.pix.pixelformat);
- dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n",
- fmt->fmt.pix.width, fmt->fmt.pix.height,
- fmt->fmt.pix.pixelformat,
- (char *) &printformat);
-
- /* we can be requested to do JPEG/raw playback/capture */
- if (!
- (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- fmt->fmt.pix.pixelformat ==
- V4L2_PIX_FMT_MJPEG))) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_FMT - unknown type %d/0x%x(%4.4s) combination\n",
- ZR_DEVNAME(zr), fmt->type,
- fmt->fmt.pix.pixelformat,
- (char *) &printformat);
- return -EINVAL;
- }
+ return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK);
+}
- if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
- mutex_lock(&zr->resource_lock);
+static int zoran_enum_fmt_vid_overlay(struct file *file, void *__fh,
+ struct v4l2_fmtdesc *f)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- settings = fh->jpg_settings;
+ return zoran_enum_fmt(zr, f, ZORAN_FORMAT_OVERLAY);
+}
- if (fh->v4l_buffers.allocated ||
- fh->jpg_buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_FMT - cannot change capture mode\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto sfmtjpg_unlock_and_return;
- }
+static int zoran_g_fmt_vid_out(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- /* we actually need to set 'real' parameters now */
- if ((fmt->fmt.pix.height * 2) >
- BUZ_MAX_HEIGHT)
- settings.TmpDcm = 1;
- else
- settings.TmpDcm = 2;
- settings.decimation = 0;
- if (fmt->fmt.pix.height <=
- fh->jpg_settings.img_height / 2)
- settings.VerDcm = 2;
- else
- settings.VerDcm = 1;
- if (fmt->fmt.pix.width <=
- fh->jpg_settings.img_width / 4)
- settings.HorDcm = 4;
- else if (fmt->fmt.pix.width <=
- fh->jpg_settings.img_width / 2)
- settings.HorDcm = 2;
- else
- settings.HorDcm = 1;
- if (settings.TmpDcm == 1)
- settings.field_per_buff = 2;
- else
- settings.field_per_buff = 1;
-
- /* check */
- if ((res =
- zoran_check_jpg_settings(zr,
- &settings)))
- goto sfmtjpg_unlock_and_return;
-
- /* it's ok, so set them */
- fh->jpg_settings = settings;
-
- /* tell the user what we actually did */
- fmt->fmt.pix.width =
- settings.img_width / settings.HorDcm;
- fmt->fmt.pix.height =
- settings.img_height * 2 /
- (settings.TmpDcm * settings.VerDcm);
- if (settings.TmpDcm == 1)
- fmt->fmt.pix.field =
- (fh->jpg_settings.
- odd_even ? V4L2_FIELD_SEQ_TB :
- V4L2_FIELD_SEQ_BT);
- else
- fmt->fmt.pix.field =
- (fh->jpg_settings.
- odd_even ? V4L2_FIELD_TOP :
- V4L2_FIELD_BOTTOM);
- fh->jpg_buffers.buffer_size =
- zoran_v4l2_calc_bufsize(&fh->
- jpg_settings);
- fmt->fmt.pix.bytesperline = 0;
- fmt->fmt.pix.sizeimage =
- fh->jpg_buffers.buffer_size;
- fmt->fmt.pix.colorspace =
- V4L2_COLORSPACE_SMPTE170M;
-
- /* we hereby abuse this variable to show that
- * we're gonna do mjpeg capture */
- fh->map_mode =
- (fmt->type ==
- V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
- ZORAN_MAP_MODE_JPG_REC :
- ZORAN_MAP_MODE_JPG_PLAY;
- sfmtjpg_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- } else {
- for (i = 0; i < NUM_FORMATS; i++)
- if (fmt->fmt.pix.pixelformat ==
- zoran_formats[i].fourcc)
- break;
- if (i == NUM_FORMATS) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n",
- ZR_DEVNAME(zr),
- fmt->fmt.pix.pixelformat,
- (char *) &printformat);
- return -EINVAL;
- }
- mutex_lock(&zr->resource_lock);
- if (fh->jpg_buffers.allocated ||
- (fh->v4l_buffers.allocated &&
- fh->v4l_buffers.active !=
- ZORAN_FREE)) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_FMT - cannot change capture mode\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto sfmtv4l_unlock_and_return;
- }
- if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
- fmt->fmt.pix.height =
- BUZ_MAX_HEIGHT;
- if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
- fmt->fmt.pix.width = BUZ_MAX_WIDTH;
-
- if ((res =
- zoran_v4l_set_format(file,
- fmt->fmt.pix.
- width,
- fmt->fmt.pix.
- height,
- &zoran_formats
- [i])))
- goto sfmtv4l_unlock_and_return;
-
- /* tell the user the
- * results/missing stuff */
- fmt->fmt.pix.bytesperline =
- fh->v4l_settings.bytesperline;
- fmt->fmt.pix.sizeimage =
- fh->v4l_settings.height *
- fh->v4l_settings.bytesperline;
- fmt->fmt.pix.colorspace =
- fh->v4l_settings.format->colorspace;
- if (BUZ_MAX_HEIGHT <
- (fh->v4l_settings.height * 2))
- fmt->fmt.pix.field =
- V4L2_FIELD_INTERLACED;
- else
- fmt->fmt.pix.field =
- V4L2_FIELD_TOP;
-
- fh->map_mode = ZORAN_MAP_MODE_RAW;
- sfmtv4l_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- }
+ mutex_lock(&zr->resource_lock);
- break;
+ fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm;
+ fmt->fmt.pix.height = fh->jpg_settings.img_height * 2 /
+ (fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm);
+ fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
+ fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
+ if (fh->jpg_settings.TmpDcm == 1)
+ fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+ V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
+ else
+ fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+ V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
+ fmt->fmt.pix.bytesperline = 0;
+ fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- default:
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_FMT - unsupported type %d\n",
- ZR_DEVNAME(zr), fmt->type);
- return -EINVAL;
- }
+ mutex_unlock(&zr->resource_lock);
+ return 0;
+}
- return res;
- }
- break;
+static int zoran_g_fmt_vid_cap(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- case VIDIOC_G_FBUF:
- {
- struct v4l2_framebuffer *fb = arg;
+ if (fh->map_mode != ZORAN_MAP_MODE_RAW)
+ return zoran_g_fmt_vid_out(file, fh, fmt);
- dprintk(3, KERN_DEBUG "%s: VIDIOC_G_FBUF\n", ZR_DEVNAME(zr));
+ mutex_lock(&zr->resource_lock);
+ fmt->fmt.pix.width = fh->v4l_settings.width;
+ fmt->fmt.pix.height = fh->v4l_settings.height;
+ fmt->fmt.pix.sizeimage = fh->v4l_settings.bytesperline *
+ fh->v4l_settings.height;
+ fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc;
+ fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace;
+ fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline;
+ if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2))
+ fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
+ else
+ fmt->fmt.pix.field = V4L2_FIELD_TOP;
+ mutex_unlock(&zr->resource_lock);
+ return 0;
+}
- memset(fb, 0, sizeof(*fb));
- mutex_lock(&zr->resource_lock);
- fb->base = zr->buffer.base;
- fb->fmt.width = zr->buffer.width;
- fb->fmt.height = zr->buffer.height;
- if (zr->overlay_settings.format) {
- fb->fmt.pixelformat =
- fh->overlay_settings.format->fourcc;
- }
- fb->fmt.bytesperline = zr->buffer.bytesperline;
- mutex_unlock(&zr->resource_lock);
- fb->fmt.colorspace = V4L2_COLORSPACE_SRGB;
- fb->fmt.field = V4L2_FIELD_INTERLACED;
- fb->flags = V4L2_FBUF_FLAG_OVERLAY;
- fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
+static int zoran_g_fmt_vid_overlay(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- return 0;
- }
- break;
+ mutex_lock(&zr->resource_lock);
- case VIDIOC_S_FBUF:
- {
- int i, res = 0;
- struct v4l2_framebuffer *fb = arg;
- __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat);
+ fmt->fmt.win.w.left = fh->overlay_settings.x;
+ fmt->fmt.win.w.top = fh->overlay_settings.y;
+ fmt->fmt.win.w.width = fh->overlay_settings.width;
+ fmt->fmt.win.w.height = fh->overlay_settings.height;
+ if (fh->overlay_settings.width * 2 > BUZ_MAX_HEIGHT)
+ fmt->fmt.win.field = V4L2_FIELD_INTERLACED;
+ else
+ fmt->fmt.win.field = V4L2_FIELD_TOP;
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOC_S_FBUF - base=0x%p, size=%dx%d, bpl=%d, fmt=0x%x (%4.4s)\n",
- ZR_DEVNAME(zr), fb->base, fb->fmt.width, fb->fmt.height,
- fb->fmt.bytesperline, fb->fmt.pixelformat,
- (char *) &printformat);
+ mutex_unlock(&zr->resource_lock);
+ return 0;
+}
- for (i = 0; i < NUM_FORMATS; i++)
- if (zoran_formats[i].fourcc == fb->fmt.pixelformat)
- break;
- if (i == NUM_FORMATS) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
- ZR_DEVNAME(zr), fb->fmt.pixelformat,
- (char *) &printformat);
- return -EINVAL;
- }
+static int zoran_try_fmt_vid_overlay(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- mutex_lock(&zr->resource_lock);
- res =
- setup_fbuffer(file, fb->base, &zoran_formats[i],
- fb->fmt.width, fb->fmt.height,
- fb->fmt.bytesperline);
- mutex_unlock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
- return res;
- }
- break;
+ if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH)
+ fmt->fmt.win.w.width = BUZ_MAX_WIDTH;
+ if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH)
+ fmt->fmt.win.w.width = BUZ_MIN_WIDTH;
+ if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT)
+ fmt->fmt.win.w.height = BUZ_MAX_HEIGHT;
+ if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT)
+ fmt->fmt.win.w.height = BUZ_MIN_HEIGHT;
- case VIDIOC_OVERLAY:
- {
- int *on = arg, res;
+ mutex_unlock(&zr->resource_lock);
+ return 0;
+}
- dprintk(3, KERN_DEBUG "%s: VIDIOC_PREVIEW - on=%d\n",
- ZR_DEVNAME(zr), *on);
+static int zoran_try_fmt_vid_out(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ struct zoran_jpg_settings settings;
+ int res = 0;
- mutex_lock(&zr->resource_lock);
- res = setup_overlay(file, *on);
- mutex_unlock(&zr->resource_lock);
+ if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
+ return -EINVAL;
- return res;
- }
- break;
+ mutex_lock(&zr->resource_lock);
+ settings = fh->jpg_settings;
- case VIDIOC_REQBUFS:
- {
- struct v4l2_requestbuffers *req = arg;
- int res = 0;
+ /* we actually need to set 'real' parameters now */
+ if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT)
+ settings.TmpDcm = 1;
+ else
+ settings.TmpDcm = 2;
+ settings.decimation = 0;
+ if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2)
+ settings.VerDcm = 2;
+ else
+ settings.VerDcm = 1;
+ if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4)
+ settings.HorDcm = 4;
+ else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2)
+ settings.HorDcm = 2;
+ else
+ settings.HorDcm = 1;
+ if (settings.TmpDcm == 1)
+ settings.field_per_buff = 2;
+ else
+ settings.field_per_buff = 1;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_REQBUFS - type=%d\n",
- ZR_DEVNAME(zr), req->type);
+ if (settings.HorDcm > 1) {
+ settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
+ settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
+ } else {
+ settings.img_x = 0;
+ settings.img_width = BUZ_MAX_WIDTH;
+ }
+
+ /* check */
+ res = zoran_check_jpg_settings(zr, &settings, 1);
+ if (res)
+ goto tryfmt_unlock_and_return;
+
+ /* tell the user what we actually did */
+ fmt->fmt.pix.width = settings.img_width / settings.HorDcm;
+ fmt->fmt.pix.height = settings.img_height * 2 /
+ (settings.TmpDcm * settings.VerDcm);
+ if (settings.TmpDcm == 1)
+ fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+ V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
+ else
+ fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+ V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
- if (req->memory != V4L2_MEMORY_MMAP) {
- dprintk(1,
- KERN_ERR
- "%s: only MEMORY_MMAP capture is supported, not %d\n",
- ZR_DEVNAME(zr), req->memory);
- return -EINVAL;
- }
+ fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings);
+ fmt->fmt.pix.bytesperline = 0;
+ fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+tryfmt_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- mutex_lock(&zr->resource_lock);
+static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int bpp;
+ int i;
- if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_REQBUFS - buffers allready allocated\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto v4l2reqbuf_unlock_and_return;
- }
+ if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
+ return zoran_try_fmt_vid_out(file, fh, fmt);
- if (fh->map_mode == ZORAN_MAP_MODE_RAW &&
- req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ mutex_lock(&zr->resource_lock);
- /* control user input */
- if (req->count < 2)
- req->count = 2;
- if (req->count > v4l_nbufs)
- req->count = v4l_nbufs;
- fh->v4l_buffers.num_buffers = req->count;
+ for (i = 0; i < NUM_FORMATS; i++)
+ if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat)
+ break;
- if (v4l_fbuffer_alloc(file)) {
- res = -ENOMEM;
- goto v4l2reqbuf_unlock_and_return;
- }
+ if (i == NUM_FORMATS) {
+ mutex_unlock(&zr->resource_lock);
+ return -EINVAL;
+ }
- /* The next mmap will map the V4L buffers */
- fh->map_mode = ZORAN_MAP_MODE_RAW;
+ bpp = (zoran_formats[i].depth + 7) / 8;
+ fmt->fmt.pix.width &= ~((bpp == 2) ? 1 : 3);
+ if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
+ fmt->fmt.pix.width = BUZ_MAX_WIDTH;
+ if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
+ fmt->fmt.pix.width = BUZ_MIN_WIDTH;
+ if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
+ fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
+ if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
+ fmt->fmt.pix.height = BUZ_MIN_HEIGHT;
+ mutex_unlock(&zr->resource_lock);
- } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC ||
- fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
+ return 0;
+}
- /* we need to calculate size ourselves now */
- if (req->count < 4)
- req->count = 4;
- if (req->count > jpg_nbufs)
- req->count = jpg_nbufs;
- fh->jpg_buffers.num_buffers = req->count;
- fh->jpg_buffers.buffer_size =
- zoran_v4l2_calc_bufsize(&fh->jpg_settings);
+static int zoran_s_fmt_vid_overlay(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res;
+
+ dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n",
+ fmt->fmt.win.w.left, fmt->fmt.win.w.top,
+ fmt->fmt.win.w.width,
+ fmt->fmt.win.w.height,
+ fmt->fmt.win.clipcount,
+ fmt->fmt.win.bitmap);
+ mutex_lock(&zr->resource_lock);
+ res = setup_window(fh, fmt->fmt.win.w.left, fmt->fmt.win.w.top,
+ fmt->fmt.win.w.width, fmt->fmt.win.w.height,
+ (struct v4l2_clip __user *)fmt->fmt.win.clips,
+ fmt->fmt.win.clipcount, fmt->fmt.win.bitmap);
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- if (jpg_fbuffer_alloc(file)) {
- res = -ENOMEM;
- goto v4l2reqbuf_unlock_and_return;
- }
+static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat);
+ struct zoran_jpg_settings settings;
+ int res = 0;
- /* The next mmap will map the MJPEG buffers */
- if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
- else
- fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY;
+ dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n",
+ fmt->fmt.pix.width, fmt->fmt.pix.height,
+ fmt->fmt.pix.pixelformat,
+ (char *) &printformat);
+ if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
+ return -EINVAL;
- } else {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_REQBUFS - unknown type %d\n",
- ZR_DEVNAME(zr), req->type);
- res = -EINVAL;
- goto v4l2reqbuf_unlock_and_return;
- }
- v4l2reqbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
- return 0;
+ if (fh->buffers.allocated) {
+ dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
+ ZR_DEVNAME(zr));
+ res = -EBUSY;
+ goto sfmtjpg_unlock_and_return;
}
- break;
- case VIDIOC_QUERYBUF:
- {
- struct v4l2_buffer *buf = arg;
- __u32 type = buf->type;
- int index = buf->index, res;
+ settings = fh->jpg_settings;
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOC_QUERYBUF - index=%d, type=%d\n",
- ZR_DEVNAME(zr), buf->index, buf->type);
-
- memset(buf, 0, sizeof(*buf));
- buf->type = type;
- buf->index = index;
-
- mutex_lock(&zr->resource_lock);
- res = zoran_v4l2_buffer_status(file, buf, buf->index);
- mutex_unlock(&zr->resource_lock);
+ /* we actually need to set 'real' parameters now */
+ if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT)
+ settings.TmpDcm = 1;
+ else
+ settings.TmpDcm = 2;
+ settings.decimation = 0;
+ if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2)
+ settings.VerDcm = 2;
+ else
+ settings.VerDcm = 1;
+ if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4)
+ settings.HorDcm = 4;
+ else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2)
+ settings.HorDcm = 2;
+ else
+ settings.HorDcm = 1;
+ if (settings.TmpDcm == 1)
+ settings.field_per_buff = 2;
+ else
+ settings.field_per_buff = 1;
- return res;
+ if (settings.HorDcm > 1) {
+ settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
+ settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
+ } else {
+ settings.img_x = 0;
+ settings.img_width = BUZ_MAX_WIDTH;
}
- break;
- case VIDIOC_QBUF:
- {
- struct v4l2_buffer *buf = arg;
- int res = 0, codec_mode, buf_type;
+ /* check */
+ res = zoran_check_jpg_settings(zr, &settings, 0);
+ if (res)
+ goto sfmtjpg_unlock_and_return;
- dprintk(3,
- KERN_DEBUG "%s: VIDIOC_QBUF - type=%d, index=%d\n",
- ZR_DEVNAME(zr), buf->type, buf->index);
+ /* it's ok, so set them */
+ fh->jpg_settings = settings;
- mutex_lock(&zr->resource_lock);
+ map_mode_jpg(fh, fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW:
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
- res = -EINVAL;
- goto qbuf_unlock_and_return;
- }
+ /* tell the user what we actually did */
+ fmt->fmt.pix.width = settings.img_width / settings.HorDcm;
+ fmt->fmt.pix.height = settings.img_height * 2 /
+ (settings.TmpDcm * settings.VerDcm);
+ if (settings.TmpDcm == 1)
+ fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+ V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
+ else
+ fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+ V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
+ fmt->fmt.pix.bytesperline = 0;
+ fmt->fmt.pix.sizeimage = fh->buffers.buffer_size;
+ fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- res = zoran_v4l_queue_frame(file, buf->index);
- if (res)
- goto qbuf_unlock_and_return;
- if (!zr->v4l_memgrab_active &&
- fh->v4l_buffers.active == ZORAN_LOCKED)
- zr36057_set_memgrab(zr, 1);
- break;
+sfmtjpg_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
- if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
- buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- codec_mode = BUZ_MODE_MOTION_DECOMPRESS;
- } else {
- buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- codec_mode = BUZ_MODE_MOTION_COMPRESS;
- }
+static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int i;
+ int res = 0;
- if (buf->type != buf_type) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
- res = -EINVAL;
- goto qbuf_unlock_and_return;
- }
+ if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
+ return zoran_s_fmt_vid_out(file, fh, fmt);
- res =
- zoran_jpg_queue_frame(file, buf->index,
- codec_mode);
- if (res != 0)
- goto qbuf_unlock_and_return;
- if (zr->codec_mode == BUZ_MODE_IDLE &&
- fh->jpg_buffers.active == ZORAN_LOCKED) {
- zr36057_enable_jpg(zr, codec_mode);
- }
+ for (i = 0; i < NUM_FORMATS; i++)
+ if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc)
break;
-
- default:
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_QBUF - unsupported type %d\n",
- ZR_DEVNAME(zr), buf->type);
- res = -EINVAL;
- goto qbuf_unlock_and_return;
- }
- qbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
+ if (i == NUM_FORMATS) {
+ dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x\n",
+ ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat);
+ return -EINVAL;
}
- break;
- case VIDIOC_DQBUF:
- {
- struct v4l2_buffer *buf = arg;
- int res = 0, buf_type, num = -1; /* compiler borks here (?) */
-
- dprintk(3, KERN_DEBUG "%s: VIDIOC_DQBUF - type=%d\n",
- ZR_DEVNAME(zr), buf->type);
-
- mutex_lock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW:
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
- res = -EINVAL;
- goto dqbuf_unlock_and_return;
- }
+ if ((fh->map_mode != ZORAN_MAP_MODE_RAW && fh->buffers.allocated) ||
+ fh->buffers.active != ZORAN_FREE) {
+ dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
+ ZR_DEVNAME(zr));
+ res = -EBUSY;
+ goto sfmtv4l_unlock_and_return;
+ }
+ if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
+ fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
+ if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
+ fmt->fmt.pix.width = BUZ_MAX_WIDTH;
+
+ map_mode_raw(fh);
+
+ res = zoran_v4l_set_format(fh, fmt->fmt.pix.width, fmt->fmt.pix.height,
+ &zoran_formats[i]);
+ if (res)
+ goto sfmtv4l_unlock_and_return;
+
+ /* tell the user the results/missing stuff */
+ fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline;
+ fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline;
+ fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace;
+ if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2))
+ fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
+ else
+ fmt->fmt.pix.field = V4L2_FIELD_TOP;
- num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
- if (file->f_flags & O_NONBLOCK &&
- zr->v4l_buffers.buffer[num].state !=
- BUZ_STATE_DONE) {
- res = -EAGAIN;
- goto dqbuf_unlock_and_return;
- }
- res = v4l_sync(file, num);
- if (res)
- goto dqbuf_unlock_and_return;
- else
- zr->v4l_sync_tail++;
- res = zoran_v4l2_buffer_status(file, buf, num);
- break;
+sfmtv4l_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
- {
- struct zoran_sync bs;
+static int zoran_g_fbuf(struct file *file, void *__fh,
+ struct v4l2_framebuffer *fb)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY)
- buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- else
- buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ memset(fb, 0, sizeof(*fb));
+ mutex_lock(&zr->resource_lock);
+ fb->base = zr->vbuf_base;
+ fb->fmt.width = zr->vbuf_width;
+ fb->fmt.height = zr->vbuf_height;
+ if (zr->overlay_settings.format)
+ fb->fmt.pixelformat = fh->overlay_settings.format->fourcc;
+ fb->fmt.bytesperline = zr->vbuf_bytesperline;
+ mutex_unlock(&zr->resource_lock);
+ fb->fmt.colorspace = V4L2_COLORSPACE_SRGB;
+ fb->fmt.field = V4L2_FIELD_INTERLACED;
+ fb->flags = V4L2_FBUF_FLAG_OVERLAY;
+ fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
- if (buf->type != buf_type) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
- res = -EINVAL;
- goto dqbuf_unlock_and_return;
- }
+ return 0;
+}
- num =
- zr->jpg_pend[zr->
- jpg_que_tail & BUZ_MASK_FRAME];
+static int zoran_s_fbuf(struct file *file, void *__fh,
+ struct v4l2_framebuffer *fb)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int i, res = 0;
+ __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat);
- if (file->f_flags & O_NONBLOCK &&
- zr->jpg_buffers.buffer[num].state !=
- BUZ_STATE_DONE) {
- res = -EAGAIN;
- goto dqbuf_unlock_and_return;
- }
- res = jpg_sync(file, &bs);
- if (res)
- goto dqbuf_unlock_and_return;
- res =
- zoran_v4l2_buffer_status(file, buf, bs.frame);
+ for (i = 0; i < NUM_FORMATS; i++)
+ if (zoran_formats[i].fourcc == fb->fmt.pixelformat)
break;
- }
-
- default:
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_DQBUF - unsupported type %d\n",
- ZR_DEVNAME(zr), buf->type);
- res = -EINVAL;
- goto dqbuf_unlock_and_return;
- }
- dqbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
+ if (i == NUM_FORMATS) {
+ dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
+ ZR_DEVNAME(zr), fb->fmt.pixelformat,
+ (char *)&printformat);
+ return -EINVAL;
}
- break;
- case VIDIOC_STREAMON:
- {
- int res = 0;
+ mutex_lock(&zr->resource_lock);
+ res = setup_fbuffer(fh, fb->base, &zoran_formats[i], fb->fmt.width,
+ fb->fmt.height, fb->fmt.bytesperline);
+ mutex_unlock(&zr->resource_lock);
- dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMON\n", ZR_DEVNAME(zr));
+ return res;
+}
- mutex_lock(&zr->resource_lock);
+static int zoran_overlay(struct file *file, void *__fh, unsigned int on)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res;
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW: /* raw capture */
- if (zr->v4l_buffers.active != ZORAN_ACTIVE ||
- fh->v4l_buffers.active != ZORAN_ACTIVE) {
- res = -EBUSY;
- goto strmon_unlock_and_return;
- }
+ mutex_lock(&zr->resource_lock);
+ res = setup_overlay(fh, on);
+ mutex_unlock(&zr->resource_lock);
- zr->v4l_buffers.active = fh->v4l_buffers.active =
- ZORAN_LOCKED;
- zr->v4l_settings = fh->v4l_settings;
+ return res;
+}
- zr->v4l_sync_tail = zr->v4l_pend_tail;
- if (!zr->v4l_memgrab_active &&
- zr->v4l_pend_head != zr->v4l_pend_tail) {
- zr36057_set_memgrab(zr, 1);
- }
- break;
+static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type);
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
- /* what is the codec mode right now? */
- if (zr->jpg_buffers.active != ZORAN_ACTIVE ||
- fh->jpg_buffers.active != ZORAN_ACTIVE) {
- res = -EBUSY;
- goto strmon_unlock_and_return;
- }
+static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0;
- zr->jpg_buffers.active = fh->jpg_buffers.active =
- ZORAN_LOCKED;
+ if (req->memory != V4L2_MEMORY_MMAP) {
+ dprintk(2,
+ KERN_ERR
+ "%s: only MEMORY_MMAP capture is supported, not %d\n",
+ ZR_DEVNAME(zr), req->memory);
+ return -EINVAL;
+ }
- if (zr->jpg_que_head != zr->jpg_que_tail) {
- /* Start the jpeg codec when the first frame is queued */
- jpeg_start(zr);
- }
+ if (req->count == 0)
+ return zoran_streamoff(file, fh, req->type);
- break;
- default:
- dprintk(1,
+ mutex_lock(&zr->resource_lock);
+ if (fh->buffers.allocated) {
+ dprintk(2,
KERN_ERR
- "%s: VIDIOC_STREAMON - invalid map mode %d\n",
- ZR_DEVNAME(zr), fh->map_mode);
- res = -EINVAL;
- goto strmon_unlock_and_return;
- }
- strmon_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
+ "%s: VIDIOC_REQBUFS - buffers already allocated\n",
+ ZR_DEVNAME(zr));
+ res = -EBUSY;
+ goto v4l2reqbuf_unlock_and_return;
}
- break;
- case VIDIOC_STREAMOFF:
- {
- int i, res = 0;
+ if (fh->map_mode == ZORAN_MAP_MODE_RAW &&
+ req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ /* control user input */
+ if (req->count < 2)
+ req->count = 2;
+ if (req->count > v4l_nbufs)
+ req->count = v4l_nbufs;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMOFF\n", ZR_DEVNAME(zr));
+ /* The next mmap will map the V4L buffers */
+ map_mode_raw(fh);
+ fh->buffers.num_buffers = req->count;
- mutex_lock(&zr->resource_lock);
+ if (v4l_fbuffer_alloc(fh)) {
+ res = -ENOMEM;
+ goto v4l2reqbuf_unlock_and_return;
+ }
+ } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC ||
+ fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
+ /* we need to calculate size ourselves now */
+ if (req->count < 4)
+ req->count = 4;
+ if (req->count > jpg_nbufs)
+ req->count = jpg_nbufs;
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW: /* raw capture */
- if (fh->v4l_buffers.active == ZORAN_FREE &&
- zr->v4l_buffers.active != ZORAN_FREE) {
- res = -EPERM; /* stay off other's settings! */
- goto strmoff_unlock_and_return;
- }
- if (zr->v4l_buffers.active == ZORAN_FREE)
- goto strmoff_unlock_and_return;
+ /* The next mmap will map the MJPEG buffers */
+ map_mode_jpg(fh, req->type == V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ fh->buffers.num_buffers = req->count;
+ fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
- /* unload capture */
- if (zr->v4l_memgrab_active) {
- unsigned long flags;
+ if (jpg_fbuffer_alloc(fh)) {
+ res = -ENOMEM;
+ goto v4l2reqbuf_unlock_and_return;
+ }
+ } else {
+ dprintk(1,
+ KERN_ERR
+ "%s: VIDIOC_REQBUFS - unknown type %d\n",
+ ZR_DEVNAME(zr), req->type);
+ res = -EINVAL;
+ goto v4l2reqbuf_unlock_and_return;
+ }
+v4l2reqbuf_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- spin_lock_irqsave(&zr->spinlock, flags);
- zr36057_set_memgrab(zr, 0);
- spin_unlock_irqrestore(&zr->spinlock, flags);
- }
+ return res;
+}
- for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
- zr->v4l_buffers.buffer[i].state =
- BUZ_STATE_USER;
- fh->v4l_buffers = zr->v4l_buffers;
+static int zoran_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res;
- zr->v4l_buffers.active = fh->v4l_buffers.active =
- ZORAN_FREE;
+ mutex_lock(&zr->resource_lock);
+ res = zoran_v4l2_buffer_status(fh, buf, buf->index);
+ mutex_unlock(&zr->resource_lock);
- zr->v4l_grab_seq = 0;
- zr->v4l_pend_head = zr->v4l_pend_tail = 0;
- zr->v4l_sync_tail = 0;
+ return res;
+}
- break;
+static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0, codec_mode, buf_type;
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
- if (fh->jpg_buffers.active == ZORAN_FREE &&
- zr->jpg_buffers.active != ZORAN_FREE) {
- res = -EPERM; /* stay off other's settings! */
- goto strmoff_unlock_and_return;
- }
- if (zr->jpg_buffers.active == ZORAN_FREE)
- goto strmoff_unlock_and_return;
-
- res =
- jpg_qbuf(file, -1,
- (fh->map_mode ==
- ZORAN_MAP_MODE_JPG_REC) ?
- BUZ_MODE_MOTION_COMPRESS :
- BUZ_MODE_MOTION_DECOMPRESS);
- if (res)
- goto strmoff_unlock_and_return;
- break;
- default:
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_STREAMOFF - invalid map mode %d\n",
- ZR_DEVNAME(zr), fh->map_mode);
+ mutex_lock(&zr->resource_lock);
+
+ switch (fh->map_mode) {
+ case ZORAN_MAP_MODE_RAW:
+ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
+ ZR_DEVNAME(zr), buf->type, fh->map_mode);
res = -EINVAL;
- goto strmoff_unlock_and_return;
+ goto qbuf_unlock_and_return;
}
- strmoff_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
- }
+ res = zoran_v4l_queue_frame(fh, buf->index);
+ if (res)
+ goto qbuf_unlock_and_return;
+ if (!zr->v4l_memgrab_active && fh->buffers.active == ZORAN_LOCKED)
+ zr36057_set_memgrab(zr, 1);
break;
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *ctrl = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCTRL - id=%d\n",
- ZR_DEVNAME(zr), ctrl->id);
-
- /* we only support hue/saturation/contrast/brightness */
- if (ctrl->id < V4L2_CID_BRIGHTNESS ||
- ctrl->id > V4L2_CID_HUE)
- return -EINVAL;
- else {
- int id = ctrl->id;
- memset(ctrl, 0, sizeof(*ctrl));
- ctrl->id = id;
+ case ZORAN_MAP_MODE_JPG_REC:
+ case ZORAN_MAP_MODE_JPG_PLAY:
+ if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
+ buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ codec_mode = BUZ_MODE_MOTION_DECOMPRESS;
+ } else {
+ buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ codec_mode = BUZ_MODE_MOTION_COMPRESS;
}
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1);
- break;
- case V4L2_CID_CONTRAST:
- strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1);
- break;
- case V4L2_CID_SATURATION:
- strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1);
- break;
- case V4L2_CID_HUE:
- strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1);
- break;
+ if (buf->type != buf_type) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
+ ZR_DEVNAME(zr), buf->type, fh->map_mode);
+ res = -EINVAL;
+ goto qbuf_unlock_and_return;
}
- ctrl->minimum = 0;
- ctrl->maximum = 65535;
- ctrl->step = 1;
- ctrl->default_value = 32768;
- ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ res = zoran_jpg_queue_frame(fh, buf->index, codec_mode);
+ if (res != 0)
+ goto qbuf_unlock_and_return;
+ if (zr->codec_mode == BUZ_MODE_IDLE &&
+ fh->buffers.active == ZORAN_LOCKED)
+ zr36057_enable_jpg(zr, codec_mode);
- return 0;
- }
break;
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOC_G_CTRL - id=%d\n",
- ZR_DEVNAME(zr), ctrl->id);
-
- /* we only support hue/saturation/contrast/brightness */
- if (ctrl->id < V4L2_CID_BRIGHTNESS ||
- ctrl->id > V4L2_CID_HUE)
- return -EINVAL;
-
- mutex_lock(&zr->resource_lock);
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- ctrl->value = zr->brightness;
- break;
- case V4L2_CID_CONTRAST:
- ctrl->value = zr->contrast;
- break;
- case V4L2_CID_SATURATION:
- ctrl->value = zr->saturation;
- break;
- case V4L2_CID_HUE:
- ctrl->value = zr->hue;
- break;
- }
- mutex_unlock(&zr->resource_lock);
-
- return 0;
- }
+ default:
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_QBUF - unsupported type %d\n",
+ ZR_DEVNAME(zr), buf->type);
+ res = -EINVAL;
break;
+ }
+qbuf_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl = arg;
- struct video_picture pict;
+ return res;
+}
- dprintk(3, KERN_DEBUG "%s: VIDIOC_S_CTRL - id=%d\n",
- ZR_DEVNAME(zr), ctrl->id);
+static int zoran_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0, buf_type, num = -1; /* compiler borks here (?) */
- /* we only support hue/saturation/contrast/brightness */
- if (ctrl->id < V4L2_CID_BRIGHTNESS ||
- ctrl->id > V4L2_CID_HUE)
- return -EINVAL;
+ mutex_lock(&zr->resource_lock);
- if (ctrl->value < 0 || ctrl->value > 65535) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n",
- ZR_DEVNAME(zr), ctrl->value, ctrl->id);
- return -EINVAL;
+ switch (fh->map_mode) {
+ case ZORAN_MAP_MODE_RAW:
+ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
+ ZR_DEVNAME(zr), buf->type, fh->map_mode);
+ res = -EINVAL;
+ goto dqbuf_unlock_and_return;
}
- mutex_lock(&zr->resource_lock);
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- zr->brightness = ctrl->value;
- break;
- case V4L2_CID_CONTRAST:
- zr->contrast = ctrl->value;
- break;
- case V4L2_CID_SATURATION:
- zr->saturation = ctrl->value;
- break;
- case V4L2_CID_HUE:
- zr->hue = ctrl->value;
- break;
+ num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
+ if (file->f_flags & O_NONBLOCK &&
+ zr->v4l_buffers.buffer[num].state != BUZ_STATE_DONE) {
+ res = -EAGAIN;
+ goto dqbuf_unlock_and_return;
}
- pict.brightness = zr->brightness;
- pict.contrast = zr->contrast;
- pict.colour = zr->saturation;
- pict.hue = zr->hue;
-
- decoder_command(zr, DECODER_SET_PICTURE, &pict);
-
- mutex_unlock(&zr->resource_lock);
-
- return 0;
- }
+ res = v4l_sync(fh, num);
+ if (res)
+ goto dqbuf_unlock_and_return;
+ zr->v4l_sync_tail++;
+ res = zoran_v4l2_buffer_status(fh, buf, num);
break;
- case VIDIOC_ENUMSTD:
+ case ZORAN_MAP_MODE_JPG_REC:
+ case ZORAN_MAP_MODE_JPG_PLAY:
{
- struct v4l2_standard *std = arg;
+ struct zoran_sync bs;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMSTD - index=%d\n",
- ZR_DEVNAME(zr), std->index);
+ if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY)
+ buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ else
+ buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (std->index < 0 || std->index >= (zr->card.norms + 1))
- return -EINVAL;
- else {
- int id = std->index;
- memset(std, 0, sizeof(*std));
- std->index = id;
+ if (buf->type != buf_type) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
+ ZR_DEVNAME(zr), buf->type, fh->map_mode);
+ res = -EINVAL;
+ goto dqbuf_unlock_and_return;
}
- if (std->index == zr->card.norms) {
- /* if we have autodetect, ... */
- struct video_decoder_capability caps;
- decoder_command(zr, DECODER_GET_CAPABILITIES,
- &caps);
- if (caps.flags & VIDEO_DECODER_AUTO) {
- std->id = V4L2_STD_ALL;
- strncpy(std->name, "Autodetect", sizeof(std->name)-1);
- return 0;
- } else
- return -EINVAL;
- }
- switch (std->index) {
- case 0:
- std->id = V4L2_STD_PAL;
- strncpy(std->name, "PAL", sizeof(std->name)-1);
- std->frameperiod.numerator = 1;
- std->frameperiod.denominator = 25;
- std->framelines = zr->card.tvn[0]->Ht;
- break;
- case 1:
- std->id = V4L2_STD_NTSC;
- strncpy(std->name, "NTSC", sizeof(std->name)-1);
- std->frameperiod.numerator = 1001;
- std->frameperiod.denominator = 30000;
- std->framelines = zr->card.tvn[1]->Ht;
- break;
- case 2:
- std->id = V4L2_STD_SECAM;
- strncpy(std->name, "SECAM", sizeof(std->name)-1);
- std->frameperiod.numerator = 1;
- std->frameperiod.denominator = 25;
- std->framelines = zr->card.tvn[2]->Ht;
- break;
- }
+ num = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
- return 0;
+ if (file->f_flags & O_NONBLOCK &&
+ zr->jpg_buffers.buffer[num].state != BUZ_STATE_DONE) {
+ res = -EAGAIN;
+ goto dqbuf_unlock_and_return;
+ }
+ res = jpg_sync(fh, &bs);
+ if (res)
+ goto dqbuf_unlock_and_return;
+ res = zoran_v4l2_buffer_status(fh, buf, bs.frame);
+ break;
}
+
+ default:
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_DQBUF - unsupported type %d\n",
+ ZR_DEVNAME(zr), buf->type);
+ res = -EINVAL;
break;
+ }
+dqbuf_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- case VIDIOC_G_STD:
- {
- v4l2_std_id *std = arg;
- int norm;
+ return res;
+}
- dprintk(3, KERN_DEBUG "%s: VIDIOC_G_STD\n", ZR_DEVNAME(zr));
+static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0;
- mutex_lock(&zr->resource_lock);
- norm = zr->norm;
- mutex_unlock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
- switch (norm) {
- case VIDEO_MODE_PAL:
- *std = V4L2_STD_PAL;
- break;
- case VIDEO_MODE_NTSC:
- *std = V4L2_STD_NTSC;
- break;
- case VIDEO_MODE_SECAM:
- *std = V4L2_STD_SECAM;
- break;
+ switch (fh->map_mode) {
+ case ZORAN_MAP_MODE_RAW: /* raw capture */
+ if (zr->v4l_buffers.active != ZORAN_ACTIVE ||
+ fh->buffers.active != ZORAN_ACTIVE) {
+ res = -EBUSY;
+ goto strmon_unlock_and_return;
}
- return 0;
- }
+ zr->v4l_buffers.active = fh->buffers.active = ZORAN_LOCKED;
+ zr->v4l_settings = fh->v4l_settings;
+
+ zr->v4l_sync_tail = zr->v4l_pend_tail;
+ if (!zr->v4l_memgrab_active &&
+ zr->v4l_pend_head != zr->v4l_pend_tail) {
+ zr36057_set_memgrab(zr, 1);
+ }
break;
- case VIDIOC_S_STD:
- {
- int norm = -1, res = 0;
- v4l2_std_id *std = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOC_S_STD - norm=0x%llx\n",
- ZR_DEVNAME(zr), (unsigned long long)*std);
-
- if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL))
- norm = VIDEO_MODE_PAL;
- else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC))
- norm = VIDEO_MODE_NTSC;
- else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM))
- norm = VIDEO_MODE_SECAM;
- else if (*std == V4L2_STD_ALL)
- norm = VIDEO_MODE_AUTO;
- else {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_STD - invalid norm 0x%llx\n",
- ZR_DEVNAME(zr), (unsigned long long)*std);
- return -EINVAL;
+ case ZORAN_MAP_MODE_JPG_REC:
+ case ZORAN_MAP_MODE_JPG_PLAY:
+ /* what is the codec mode right now? */
+ if (zr->jpg_buffers.active != ZORAN_ACTIVE ||
+ fh->buffers.active != ZORAN_ACTIVE) {
+ res = -EBUSY;
+ goto strmon_unlock_and_return;
}
- mutex_lock(&zr->resource_lock);
- if ((res = zoran_set_norm(zr, norm)))
- goto sstd_unlock_and_return;
+ zr->jpg_buffers.active = fh->buffers.active = ZORAN_LOCKED;
- res = wait_grab_pending(zr);
- sstd_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
- }
+ if (zr->jpg_que_head != zr->jpg_que_tail) {
+ /* Start the jpeg codec when the first frame is queued */
+ jpeg_start(zr);
+ }
break;
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *inp = arg;
- int status;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMINPUT - index=%d\n",
- ZR_DEVNAME(zr), inp->index);
+ default:
+ dprintk(1,
+ KERN_ERR
+ "%s: VIDIOC_STREAMON - invalid map mode %d\n",
+ ZR_DEVNAME(zr), fh->map_mode);
+ res = -EINVAL;
+ break;
+ }
+strmon_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- if (inp->index < 0 || inp->index >= zr->card.inputs)
- return -EINVAL;
- else {
- int id = inp->index;
- memset(inp, 0, sizeof(*inp));
- inp->index = id;
- }
+ return res;
+}
- strncpy(inp->name, zr->card.input[inp->index].name,
- sizeof(inp->name) - 1);
- inp->type = V4L2_INPUT_TYPE_CAMERA;
- inp->std = V4L2_STD_ALL;
+static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int i, res = 0;
+ unsigned long flags;
- /* Get status of video decoder */
- mutex_lock(&zr->resource_lock);
- decoder_command(zr, DECODER_GET_STATUS, &status);
- mutex_unlock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
- if (!(status & DECODER_STATUS_GOOD)) {
- inp->status |= V4L2_IN_ST_NO_POWER;
- inp->status |= V4L2_IN_ST_NO_SIGNAL;
+ switch (fh->map_mode) {
+ case ZORAN_MAP_MODE_RAW: /* raw capture */
+ if (fh->buffers.active == ZORAN_FREE &&
+ zr->v4l_buffers.active != ZORAN_FREE) {
+ res = -EPERM; /* stay off other's settings! */
+ goto strmoff_unlock_and_return;
}
- if (!(status & DECODER_STATUS_COLOR))
- inp->status |= V4L2_IN_ST_NO_COLOR;
+ if (zr->v4l_buffers.active == ZORAN_FREE)
+ goto strmoff_unlock_and_return;
- return 0;
- }
- break;
+ spin_lock_irqsave(&zr->spinlock, flags);
+ /* unload capture */
+ if (zr->v4l_memgrab_active) {
- case VIDIOC_G_INPUT:
- {
- int *input = arg;
+ zr36057_set_memgrab(zr, 0);
+ }
- dprintk(3, KERN_DEBUG "%s: VIDIOC_G_INPUT\n", ZR_DEVNAME(zr));
+ for (i = 0; i < fh->buffers.num_buffers; i++)
+ zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER;
+ fh->buffers = zr->v4l_buffers;
- mutex_lock(&zr->resource_lock);
- *input = zr->input;
- mutex_unlock(&zr->resource_lock);
+ zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
- return 0;
- }
- break;
+ zr->v4l_grab_seq = 0;
+ zr->v4l_pend_head = zr->v4l_pend_tail = 0;
+ zr->v4l_sync_tail = 0;
- case VIDIOC_S_INPUT:
- {
- int *input = arg, res = 0;
+ spin_unlock_irqrestore(&zr->spinlock, flags);
- dprintk(3, KERN_DEBUG "%s: VIDIOC_S_INPUT - input=%d\n",
- ZR_DEVNAME(zr), *input);
+ break;
- mutex_lock(&zr->resource_lock);
- if ((res = zoran_set_input(zr, *input)))
- goto sinput_unlock_and_return;
+ case ZORAN_MAP_MODE_JPG_REC:
+ case ZORAN_MAP_MODE_JPG_PLAY:
+ if (fh->buffers.active == ZORAN_FREE &&
+ zr->jpg_buffers.active != ZORAN_FREE) {
+ res = -EPERM; /* stay off other's settings! */
+ goto strmoff_unlock_and_return;
+ }
+ if (zr->jpg_buffers.active == ZORAN_FREE)
+ goto strmoff_unlock_and_return;
- /* Make sure the changes come into effect */
- res = wait_grab_pending(zr);
- sinput_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
- }
+ res = jpg_qbuf(fh, -1,
+ (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
+ BUZ_MODE_MOTION_COMPRESS :
+ BUZ_MODE_MOTION_DECOMPRESS);
+ if (res)
+ goto strmoff_unlock_and_return;
+ break;
+ default:
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_STREAMOFF - invalid map mode %d\n",
+ ZR_DEVNAME(zr), fh->map_mode);
+ res = -EINVAL;
break;
+ }
+strmoff_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- case VIDIOC_ENUMOUTPUT:
- {
- struct v4l2_output *outp = arg;
+ return res;
+}
- dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMOUTPUT - index=%d\n",
- ZR_DEVNAME(zr), outp->index);
+static int zoran_queryctrl(struct file *file, void *__fh,
+ struct v4l2_queryctrl *ctrl)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- if (outp->index != 0)
- return -EINVAL;
+ /* we only support hue/saturation/contrast/brightness */
+ if (ctrl->id < V4L2_CID_BRIGHTNESS ||
+ ctrl->id > V4L2_CID_HUE)
+ return -EINVAL;
- memset(outp, 0, sizeof(*outp));
- outp->index = 0;
- outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
- strncpy(outp->name, "Autodetect", sizeof(outp->name)-1);
+ decoder_call(zr, core, queryctrl, ctrl);
- return 0;
- }
- break;
+ return 0;
+}
- case VIDIOC_G_OUTPUT:
- {
- int *output = arg;
+static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_G_OUTPUT\n", ZR_DEVNAME(zr));
+ /* we only support hue/saturation/contrast/brightness */
+ if (ctrl->id < V4L2_CID_BRIGHTNESS ||
+ ctrl->id > V4L2_CID_HUE)
+ return -EINVAL;
- *output = 0;
+ mutex_lock(&zr->resource_lock);
+ decoder_call(zr, core, g_ctrl, ctrl);
+ mutex_unlock(&zr->resource_lock);
- return 0;
- }
- break;
+ return 0;
+}
- case VIDIOC_S_OUTPUT:
- {
- int *output = arg;
+static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_S_OUTPUT - output=%d\n",
- ZR_DEVNAME(zr), *output);
+ /* we only support hue/saturation/contrast/brightness */
+ if (ctrl->id < V4L2_CID_BRIGHTNESS ||
+ ctrl->id > V4L2_CID_HUE)
+ return -EINVAL;
- if (*output != 0)
- return -EINVAL;
+ mutex_lock(&zr->resource_lock);
+ decoder_call(zr, core, s_ctrl, ctrl);
+ mutex_unlock(&zr->resource_lock);
- return 0;
- }
- break;
+ return 0;
+}
- /* cropping (sub-frame capture) */
- case VIDIOC_CROPCAP:
- {
- struct v4l2_cropcap *cropcap = arg;
- int type = cropcap->type, res = 0;
+static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- dprintk(3, KERN_ERR "%s: VIDIOC_CROPCAP - type=%d\n",
- ZR_DEVNAME(zr), cropcap->type);
+ mutex_lock(&zr->resource_lock);
+ *std = zr->norm;
+ mutex_unlock(&zr->resource_lock);
+ return 0;
+}
- memset(cropcap, 0, sizeof(*cropcap));
- cropcap->type = type;
+static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0;
- mutex_lock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
+ res = zoran_set_norm(zr, *std);
+ if (res)
+ goto sstd_unlock_and_return;
- if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- fh->map_mode == ZORAN_MAP_MODE_RAW)) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto cropcap_unlock_and_return;
- }
+ res = wait_grab_pending(zr);
+sstd_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- cropcap->bounds.top = cropcap->bounds.left = 0;
- cropcap->bounds.width = BUZ_MAX_WIDTH;
- cropcap->bounds.height = BUZ_MAX_HEIGHT;
- cropcap->defrect.top = cropcap->defrect.left = 0;
- cropcap->defrect.width = BUZ_MIN_WIDTH;
- cropcap->defrect.height = BUZ_MIN_HEIGHT;
- cropcap_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
- }
- break;
+static int zoran_enum_input(struct file *file, void *__fh,
+ struct v4l2_input *inp)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- case VIDIOC_G_CROP:
- {
- struct v4l2_crop *crop = arg;
- int type = crop->type, res = 0;
+ if (inp->index < 0 || inp->index >= zr->card.inputs)
+ return -EINVAL;
+ else {
+ int id = inp->index;
+ memset(inp, 0, sizeof(*inp));
+ inp->index = id;
+ }
- dprintk(3, KERN_ERR "%s: VIDIOC_G_CROP - type=%d\n",
- ZR_DEVNAME(zr), crop->type);
+ strncpy(inp->name, zr->card.input[inp->index].name,
+ sizeof(inp->name) - 1);
+ inp->type = V4L2_INPUT_TYPE_CAMERA;
+ inp->std = V4L2_STD_ALL;
- memset(crop, 0, sizeof(*crop));
- crop->type = type;
+ /* Get status of video decoder */
+ mutex_lock(&zr->resource_lock);
+ decoder_call(zr, video, g_input_status, &inp->status);
+ mutex_unlock(&zr->resource_lock);
+ return 0;
+}
- mutex_lock(&zr->resource_lock);
+static int zoran_g_input(struct file *file, void *__fh, unsigned int *input)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- fh->map_mode == ZORAN_MAP_MODE_RAW)) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto gcrop_unlock_and_return;
- }
+ mutex_lock(&zr->resource_lock);
+ *input = zr->input;
+ mutex_unlock(&zr->resource_lock);
- crop->c.top = fh->jpg_settings.img_y;
- crop->c.left = fh->jpg_settings.img_x;
- crop->c.width = fh->jpg_settings.img_width;
- crop->c.height = fh->jpg_settings.img_height;
+ return 0;
+}
- gcrop_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
+static int zoran_s_input(struct file *file, void *__fh, unsigned int input)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res;
- return res;
- }
- break;
+ mutex_lock(&zr->resource_lock);
+ res = zoran_set_input(zr, input);
+ if (res)
+ goto sinput_unlock_and_return;
- case VIDIOC_S_CROP:
- {
- struct v4l2_crop *crop = arg;
- int res = 0;
+ /* Make sure the changes come into effect */
+ res = wait_grab_pending(zr);
+sinput_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- settings = fh->jpg_settings;
+static int zoran_enum_output(struct file *file, void *__fh,
+ struct v4l2_output *outp)
+{
+ if (outp->index != 0)
+ return -EINVAL;
- dprintk(3,
- KERN_ERR
- "%s: VIDIOC_S_CROP - type=%d, x=%d,y=%d,w=%d,h=%d\n",
- ZR_DEVNAME(zr), crop->type, crop->c.left, crop->c.top,
- crop->c.width, crop->c.height);
+ memset(outp, 0, sizeof(*outp));
+ outp->index = 0;
+ outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
+ strncpy(outp->name, "Autodetect", sizeof(outp->name)-1);
- mutex_lock(&zr->resource_lock);
+ return 0;
+}
- if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_CROP - cannot change settings while active\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto scrop_unlock_and_return;
- }
+static int zoran_g_output(struct file *file, void *__fh, unsigned int *output)
+{
+ *output = 0;
- if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- fh->map_mode == ZORAN_MAP_MODE_RAW)) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto scrop_unlock_and_return;
- }
+ return 0;
+}
- /* move into a form that we understand */
- settings.img_x = crop->c.left;
- settings.img_y = crop->c.top;
- settings.img_width = crop->c.width;
- settings.img_height = crop->c.height;
+static int zoran_s_output(struct file *file, void *__fh, unsigned int output)
+{
+ if (output != 0)
+ return -EINVAL;
- /* check validity */
- if ((res = zoran_check_jpg_settings(zr, &settings)))
- goto scrop_unlock_and_return;
+ return 0;
+}
- /* accept */
- fh->jpg_settings = settings;
+/* cropping (sub-frame capture) */
+static int zoran_cropcap(struct file *file, void *__fh,
+ struct v4l2_cropcap *cropcap)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int type = cropcap->type, res = 0;
- scrop_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
- }
- break;
+ memset(cropcap, 0, sizeof(*cropcap));
+ cropcap->type = type;
- case VIDIOC_G_JPEGCOMP:
- {
- struct v4l2_jpegcompression *params = arg;
+ mutex_lock(&zr->resource_lock);
- dprintk(3, KERN_DEBUG "%s: VIDIOC_G_JPEGCOMP\n",
+ if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ fh->map_mode == ZORAN_MAP_MODE_RAW)) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n",
ZR_DEVNAME(zr));
+ res = -EINVAL;
+ goto cropcap_unlock_and_return;
+ }
- memset(params, 0, sizeof(*params));
+ cropcap->bounds.top = cropcap->bounds.left = 0;
+ cropcap->bounds.width = BUZ_MAX_WIDTH;
+ cropcap->bounds.height = BUZ_MAX_HEIGHT;
+ cropcap->defrect.top = cropcap->defrect.left = 0;
+ cropcap->defrect.width = BUZ_MIN_WIDTH;
+ cropcap->defrect.height = BUZ_MIN_HEIGHT;
+cropcap_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- mutex_lock(&zr->resource_lock);
+static int zoran_g_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int type = crop->type, res = 0;
- params->quality = fh->jpg_settings.jpg_comp.quality;
- params->APPn = fh->jpg_settings.jpg_comp.APPn;
- memcpy(params->APP_data,
- fh->jpg_settings.jpg_comp.APP_data,
- fh->jpg_settings.jpg_comp.APP_len);
- params->APP_len = fh->jpg_settings.jpg_comp.APP_len;
- memcpy(params->COM_data,
- fh->jpg_settings.jpg_comp.COM_data,
- fh->jpg_settings.jpg_comp.COM_len);
- params->COM_len = fh->jpg_settings.jpg_comp.COM_len;
- params->jpeg_markers =
- fh->jpg_settings.jpg_comp.jpeg_markers;
+ memset(crop, 0, sizeof(*crop));
+ crop->type = type;
- mutex_unlock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
- return 0;
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ fh->map_mode == ZORAN_MAP_MODE_RAW)) {
+ dprintk(1,
+ KERN_ERR
+ "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
+ ZR_DEVNAME(zr));
+ res = -EINVAL;
+ goto gcrop_unlock_and_return;
}
- break;
-
- case VIDIOC_S_JPEGCOMP:
- {
- struct v4l2_jpegcompression *params = arg;
- int res = 0;
- settings = fh->jpg_settings;
+ crop->c.top = fh->jpg_settings.img_y;
+ crop->c.left = fh->jpg_settings.img_x;
+ crop->c.width = fh->jpg_settings.img_width;
+ crop->c.height = fh->jpg_settings.img_height;
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOC_S_JPEGCOMP - quality=%d, APPN=%d, APP_len=%d, COM_len=%d\n",
- ZR_DEVNAME(zr), params->quality, params->APPn,
- params->APP_len, params->COM_len);
+gcrop_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- settings.jpg_comp = *params;
+ return res;
+}
- mutex_lock(&zr->resource_lock);
+static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0;
+ struct zoran_jpg_settings settings;
- if (fh->v4l_buffers.active != ZORAN_FREE ||
- fh->jpg_buffers.active != ZORAN_FREE) {
- dprintk(1,
- KERN_WARNING
- "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto sjpegc_unlock_and_return;
- }
+ settings = fh->jpg_settings;
- if ((res = zoran_check_jpg_settings(zr, &settings)))
- goto sjpegc_unlock_and_return;
- if (!fh->jpg_buffers.allocated)
- fh->jpg_buffers.buffer_size =
- zoran_v4l2_calc_bufsize(&fh->jpg_settings);
- fh->jpg_settings.jpg_comp = *params = settings.jpg_comp;
- sjpegc_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
- return 0;
+ if (fh->buffers.allocated) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_S_CROP - cannot change settings while active\n",
+ ZR_DEVNAME(zr));
+ res = -EBUSY;
+ goto scrop_unlock_and_return;
}
- break;
- case VIDIOC_QUERYSTD: /* why is this useful? */
- {
- v4l2_std_id *std = arg;
-
- dprintk(3,
- KERN_DEBUG "%s: VIDIOC_QUERY_STD - std=0x%llx\n",
- ZR_DEVNAME(zr), (unsigned long long)*std);
-
- if (*std == V4L2_STD_ALL || *std == V4L2_STD_NTSC ||
- *std == V4L2_STD_PAL || (*std == V4L2_STD_SECAM &&
- zr->card.norms == 3)) {
- return 0;
- }
-
- return -EINVAL;
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ fh->map_mode == ZORAN_MAP_MODE_RAW)) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
+ ZR_DEVNAME(zr));
+ res = -EINVAL;
+ goto scrop_unlock_and_return;
}
- break;
- case VIDIOC_TRY_FMT:
- {
- struct v4l2_format *fmt = arg;
- int res = 0;
+ /* move into a form that we understand */
+ settings.img_x = crop->c.left;
+ settings.img_y = crop->c.top;
+ settings.img_width = crop->c.width;
+ settings.img_height = crop->c.height;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_TRY_FMT - type=%d\n",
- ZR_DEVNAME(zr), fmt->type);
+ /* check validity */
+ res = zoran_check_jpg_settings(zr, &settings, 0);
+ if (res)
+ goto scrop_unlock_and_return;
- switch (fmt->type) {
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- mutex_lock(&zr->resource_lock);
+ /* accept */
+ fh->jpg_settings = settings;
- if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH)
- fmt->fmt.win.w.width = BUZ_MAX_WIDTH;
- if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH)
- fmt->fmt.win.w.width = BUZ_MIN_WIDTH;
- if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT)
- fmt->fmt.win.w.height = BUZ_MAX_HEIGHT;
- if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT)
- fmt->fmt.win.w.height = BUZ_MIN_HEIGHT;
+scrop_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- mutex_unlock(&zr->resource_lock);
- break;
+static int zoran_g_jpegcomp(struct file *file, void *__fh,
+ struct v4l2_jpegcompression *params)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ memset(params, 0, sizeof(*params));
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (fmt->fmt.pix.bytesperline > 0)
- return -EINVAL;
+ mutex_lock(&zr->resource_lock);
- mutex_lock(&zr->resource_lock);
-
- if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
- settings = fh->jpg_settings;
-
- /* we actually need to set 'real' parameters now */
- if ((fmt->fmt.pix.height * 2) >
- BUZ_MAX_HEIGHT)
- settings.TmpDcm = 1;
- else
- settings.TmpDcm = 2;
- settings.decimation = 0;
- if (fmt->fmt.pix.height <=
- fh->jpg_settings.img_height / 2)
- settings.VerDcm = 2;
- else
- settings.VerDcm = 1;
- if (fmt->fmt.pix.width <=
- fh->jpg_settings.img_width / 4)
- settings.HorDcm = 4;
- else if (fmt->fmt.pix.width <=
- fh->jpg_settings.img_width / 2)
- settings.HorDcm = 2;
- else
- settings.HorDcm = 1;
- if (settings.TmpDcm == 1)
- settings.field_per_buff = 2;
- else
- settings.field_per_buff = 1;
-
- /* check */
- if ((res =
- zoran_check_jpg_settings(zr,
- &settings)))
- goto tryfmt_unlock_and_return;
-
- /* tell the user what we actually did */
- fmt->fmt.pix.width =
- settings.img_width / settings.HorDcm;
- fmt->fmt.pix.height =
- settings.img_height * 2 /
- (settings.TmpDcm * settings.VerDcm);
- if (settings.TmpDcm == 1)
- fmt->fmt.pix.field =
- (fh->jpg_settings.
- odd_even ? V4L2_FIELD_SEQ_TB :
- V4L2_FIELD_SEQ_BT);
- else
- fmt->fmt.pix.field =
- (fh->jpg_settings.
- odd_even ? V4L2_FIELD_TOP :
- V4L2_FIELD_BOTTOM);
-
- fmt->fmt.pix.sizeimage =
- zoran_v4l2_calc_bufsize(&settings);
- } else if (fmt->type ==
- V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- int i;
-
- for (i = 0; i < NUM_FORMATS; i++)
- if (zoran_formats[i].fourcc ==
- fmt->fmt.pix.pixelformat)
- break;
- if (i == NUM_FORMATS) {
- res = -EINVAL;
- goto tryfmt_unlock_and_return;
- }
+ params->quality = fh->jpg_settings.jpg_comp.quality;
+ params->APPn = fh->jpg_settings.jpg_comp.APPn;
+ memcpy(params->APP_data,
+ fh->jpg_settings.jpg_comp.APP_data,
+ fh->jpg_settings.jpg_comp.APP_len);
+ params->APP_len = fh->jpg_settings.jpg_comp.APP_len;
+ memcpy(params->COM_data,
+ fh->jpg_settings.jpg_comp.COM_data,
+ fh->jpg_settings.jpg_comp.COM_len);
+ params->COM_len = fh->jpg_settings.jpg_comp.COM_len;
+ params->jpeg_markers =
+ fh->jpg_settings.jpg_comp.jpeg_markers;
- if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
- fmt->fmt.pix.width = BUZ_MAX_WIDTH;
- if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
- fmt->fmt.pix.width = BUZ_MIN_WIDTH;
- if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
- fmt->fmt.pix.height =
- BUZ_MAX_HEIGHT;
- if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
- fmt->fmt.pix.height =
- BUZ_MIN_HEIGHT;
- } else {
- res = -EINVAL;
- goto tryfmt_unlock_and_return;
- }
- tryfmt_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
+ mutex_unlock(&zr->resource_lock);
- return res;
- break;
+ return 0;
+}
- default:
- return -EINVAL;
- }
+static int zoran_s_jpegcomp(struct file *file, void *__fh,
+ struct v4l2_jpegcompression *params)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0;
+ struct zoran_jpg_settings settings;
- return 0;
- }
- break;
+ settings = fh->jpg_settings;
- default:
- dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n",
- ZR_DEVNAME(zr), cmd);
- return -ENOIOCTLCMD;
- break;
+ settings.jpg_comp = *params;
+
+ mutex_lock(&zr->resource_lock);
+ if (fh->buffers.active != ZORAN_FREE) {
+ dprintk(1, KERN_WARNING
+ "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n",
+ ZR_DEVNAME(zr));
+ res = -EBUSY;
+ goto sjpegc_unlock_and_return;
}
- return 0;
-}
+ res = zoran_check_jpg_settings(zr, &settings, 0);
+ if (res)
+ goto sjpegc_unlock_and_return;
+ if (!fh->buffers.allocated)
+ fh->buffers.buffer_size =
+ zoran_v4l2_calc_bufsize(&fh->jpg_settings);
+ fh->jpg_settings.jpg_comp = *params = settings.jpg_comp;
+sjpegc_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
-static long
-zoran_ioctl(struct file *file,
- unsigned int cmd,
- unsigned long arg)
-{
- return video_usercopy(file, cmd, arg, zoran_do_ioctl);
+ return res;
}
static unsigned int
@@ -4191,11 +3062,11 @@ zoran_poll (struct file *file,
KERN_DEBUG
"%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n",
ZR_DEVNAME(zr), __func__,
- "FAL"[fh->v4l_buffers.active], zr->v4l_sync_tail,
+ "FAL"[fh->buffers.active], zr->v4l_sync_tail,
"UPMD"[zr->v4l_buffers.buffer[frame].state],
zr->v4l_pend_tail, zr->v4l_pend_head);
/* Process is the one capturing? */
- if (fh->v4l_buffers.active != ZORAN_FREE &&
+ if (fh->buffers.active != ZORAN_FREE &&
/* Buffer ready to DQBUF? */
zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE)
res = POLLIN | POLLRDNORM;
@@ -4213,10 +3084,10 @@ zoran_poll (struct file *file,
KERN_DEBUG
"%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n",
ZR_DEVNAME(zr), __func__,
- "FAL"[fh->jpg_buffers.active], zr->jpg_que_tail,
+ "FAL"[fh->buffers.active], zr->jpg_que_tail,
"UPMD"[zr->jpg_buffers.buffer[frame].state],
zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head);
- if (fh->jpg_buffers.active != ZORAN_FREE &&
+ if (fh->buffers.active != ZORAN_FREE &&
zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) {
if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC)
res = POLLIN | POLLRDNORM;
@@ -4230,8 +3101,8 @@ zoran_poll (struct file *file,
default:
dprintk(1,
KERN_ERR
- "%s: zoran_poll() - internal error, unknown map_mode=%d\n",
- ZR_DEVNAME(zr), fh->map_mode);
+ "%s: %s - internal error, unknown map_mode=%d\n",
+ ZR_DEVNAME(zr), __func__, fh->map_mode);
res = POLLNVAL;
}
@@ -4265,98 +3136,53 @@ static void
zoran_vm_close (struct vm_area_struct *vma)
{
struct zoran_mapping *map = vma->vm_private_data;
- struct file *file = map->file;
- struct zoran_fh *fh = file->private_data;
+ struct zoran_fh *fh = map->file->private_data;
struct zoran *zr = fh->zr;
int i;
- map->count--;
- if (map->count == 0) {
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
-
- dprintk(3, KERN_INFO "%s: munmap(MJPEG)\n",
- ZR_DEVNAME(zr));
+ if (--map->count > 0)
+ return;
- for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
- if (fh->jpg_buffers.buffer[i].map == map) {
- fh->jpg_buffers.buffer[i].map =
- NULL;
- }
- }
- kfree(map);
-
- for (i = 0; i < fh->jpg_buffers.num_buffers; i++)
- if (fh->jpg_buffers.buffer[i].map)
- break;
- if (i == fh->jpg_buffers.num_buffers) {
- mutex_lock(&zr->resource_lock);
-
- if (fh->jpg_buffers.active != ZORAN_FREE) {
- jpg_qbuf(file, -1, zr->codec_mode);
- zr->jpg_buffers.allocated = 0;
- zr->jpg_buffers.active =
- fh->jpg_buffers.active =
- ZORAN_FREE;
- }
- //jpg_fbuffer_free(file);
- fh->jpg_buffers.allocated = 0;
- fh->jpg_buffers.ready_to_be_freed = 1;
-
- mutex_unlock(&zr->resource_lock);
- }
+ dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr),
+ __func__, mode_name(fh->map_mode));
- break;
-
- case ZORAN_MAP_MODE_RAW:
-
- dprintk(3, KERN_INFO "%s: munmap(V4L)\n",
- ZR_DEVNAME(zr));
-
- for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
- if (fh->v4l_buffers.buffer[i].map == map) {
- /* unqueue/unmap */
- fh->v4l_buffers.buffer[i].map =
- NULL;
- }
- }
- kfree(map);
+ for (i = 0; i < fh->buffers.num_buffers; i++) {
+ if (fh->buffers.buffer[i].map == map)
+ fh->buffers.buffer[i].map = NULL;
+ }
+ kfree(map);
- for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
- if (fh->v4l_buffers.buffer[i].map)
- break;
- if (i == fh->v4l_buffers.num_buffers) {
- mutex_lock(&zr->resource_lock);
-
- if (fh->v4l_buffers.active != ZORAN_FREE) {
- unsigned long flags;
-
- spin_lock_irqsave(&zr->spinlock, flags);
- zr36057_set_memgrab(zr, 0);
- zr->v4l_buffers.allocated = 0;
- zr->v4l_buffers.active =
- fh->v4l_buffers.active =
- ZORAN_FREE;
- spin_unlock_irqrestore(&zr->spinlock, flags);
- }
- //v4l_fbuffer_free(file);
- fh->v4l_buffers.allocated = 0;
- fh->v4l_buffers.ready_to_be_freed = 1;
+ /* Any buffers still mapped? */
+ for (i = 0; i < fh->buffers.num_buffers; i++)
+ if (fh->buffers.buffer[i].map)
+ return;
- mutex_unlock(&zr->resource_lock);
- }
+ dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr),
+ __func__, mode_name(fh->map_mode));
- break;
+ mutex_lock(&zr->resource_lock);
- default:
- printk(KERN_ERR
- "%s: munmap() - internal error - unknown map mode %d\n",
- ZR_DEVNAME(zr), fh->map_mode);
- break;
+ if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
+ if (fh->buffers.active != ZORAN_FREE) {
+ unsigned long flags;
+ spin_lock_irqsave(&zr->spinlock, flags);
+ zr36057_set_memgrab(zr, 0);
+ zr->v4l_buffers.allocated = 0;
+ zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
+ spin_unlock_irqrestore(&zr->spinlock, flags);
}
+ v4l_fbuffer_free(fh);
+ } else {
+ if (fh->buffers.active != ZORAN_FREE) {
+ jpg_qbuf(fh, -1, zr->codec_mode);
+ zr->jpg_buffers.allocated = 0;
+ zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE;
+ }
+ jpg_fbuffer_free(fh);
}
+
+ mutex_unlock(&zr->resource_lock);
}
static struct vm_operations_struct zoran_vm_ops = {
@@ -4379,90 +3205,106 @@ zoran_mmap (struct file *file,
int res = 0;
dprintk(3,
- KERN_INFO "%s: mmap(%s) of 0x%08lx-0x%08lx (size=%lu)\n",
- ZR_DEVNAME(zr),
- fh->map_mode == ZORAN_MAP_MODE_RAW ? "V4L" : "MJPEG",
- vma->vm_start, vma->vm_end, size);
+ KERN_INFO "%s: %s(%s) of 0x%08lx-0x%08lx (size=%lu)\n",
+ ZR_DEVNAME(zr), __func__,
+ mode_name(fh->map_mode), vma->vm_start, vma->vm_end, size);
if (!(vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_READ) ||
!(vma->vm_flags & VM_WRITE)) {
dprintk(1,
KERN_ERR
- "%s: mmap() - no MAP_SHARED/PROT_{READ,WRITE} given\n",
- ZR_DEVNAME(zr));
+ "%s: %s - no MAP_SHARED/PROT_{READ,WRITE} given\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
- switch (fh->map_mode) {
+ mutex_lock(&zr->resource_lock);
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
+ if (!fh->buffers.allocated) {
+ dprintk(1,
+ KERN_ERR
+ "%s: %s(%s) - buffers not yet allocated\n",
+ ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode));
+ res = -ENOMEM;
+ goto mmap_unlock_and_return;
+ }
- /* lock */
- mutex_lock(&zr->resource_lock);
+ first = offset / fh->buffers.buffer_size;
+ last = first - 1 + size / fh->buffers.buffer_size;
+ if (offset % fh->buffers.buffer_size != 0 ||
+ size % fh->buffers.buffer_size != 0 || first < 0 ||
+ last < 0 || first >= fh->buffers.num_buffers ||
+ last >= fh->buffers.buffer_size) {
+ dprintk(1,
+ KERN_ERR
+ "%s: %s(%s) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
+ ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), offset, size,
+ fh->buffers.buffer_size,
+ fh->buffers.num_buffers);
+ res = -EINVAL;
+ goto mmap_unlock_and_return;
+ }
- /* Map the MJPEG buffers */
- if (!fh->jpg_buffers.allocated) {
+ /* Check if any buffers are already mapped */
+ for (i = first; i <= last; i++) {
+ if (fh->buffers.buffer[i].map) {
dprintk(1,
KERN_ERR
- "%s: zoran_mmap(MJPEG) - buffers not yet allocated\n",
- ZR_DEVNAME(zr));
- res = -ENOMEM;
- goto jpg_mmap_unlock_and_return;
+ "%s: %s(%s) - buffer %d already mapped\n",
+ ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), i);
+ res = -EBUSY;
+ goto mmap_unlock_and_return;
}
+ }
- first = offset / fh->jpg_buffers.buffer_size;
- last = first - 1 + size / fh->jpg_buffers.buffer_size;
- if (offset % fh->jpg_buffers.buffer_size != 0 ||
- size % fh->jpg_buffers.buffer_size != 0 || first < 0 ||
- last < 0 || first >= fh->jpg_buffers.num_buffers ||
- last >= fh->jpg_buffers.num_buffers) {
- dprintk(1,
- KERN_ERR
- "%s: mmap(MJPEG) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
- ZR_DEVNAME(zr), offset, size,
- fh->jpg_buffers.buffer_size,
- fh->jpg_buffers.num_buffers);
- res = -EINVAL;
- goto jpg_mmap_unlock_and_return;
- }
+ /* map these buffers */
+ map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
+ if (!map) {
+ res = -ENOMEM;
+ goto mmap_unlock_and_return;
+ }
+ map->file = file;
+ map->count = 1;
+
+ vma->vm_ops = &zoran_vm_ops;
+ vma->vm_flags |= VM_DONTEXPAND;
+ vma->vm_private_data = map;
+
+ if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
for (i = first; i <= last; i++) {
- if (fh->jpg_buffers.buffer[i].map) {
+ todo = size;
+ if (todo > fh->buffers.buffer_size)
+ todo = fh->buffers.buffer_size;
+ page = fh->buffers.buffer[i].v4l.fbuffer_phys;
+ if (remap_pfn_range(vma, start, page >> PAGE_SHIFT,
+ todo, PAGE_SHARED)) {
dprintk(1,
KERN_ERR
- "%s: mmap(MJPEG) - buffer %d already mapped\n",
- ZR_DEVNAME(zr), i);
- res = -EBUSY;
- goto jpg_mmap_unlock_and_return;
+ "%s: %s(V4L) - remap_pfn_range failed\n",
+ ZR_DEVNAME(zr), __func__);
+ res = -EAGAIN;
+ goto mmap_unlock_and_return;
}
+ size -= todo;
+ start += todo;
+ fh->buffers.buffer[i].map = map;
+ if (size == 0)
+ break;
}
-
- /* map these buffers (v4l_buffers[i]) */
- map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
- if (!map) {
- res = -ENOMEM;
- goto jpg_mmap_unlock_and_return;
- }
- map->file = file;
- map->count = 1;
-
- vma->vm_ops = &zoran_vm_ops;
- vma->vm_flags |= VM_DONTEXPAND;
- vma->vm_private_data = map;
-
+ } else {
for (i = first; i <= last; i++) {
for (j = 0;
- j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
+ j < fh->buffers.buffer_size / PAGE_SIZE;
j++) {
fraglen =
- (le32_to_cpu(fh->jpg_buffers.buffer[i].
+ (le32_to_cpu(fh->buffers.buffer[i].jpg.
frag_tab[2 * j + 1]) & ~1) << 1;
todo = size;
if (todo > fraglen)
todo = fraglen;
pos =
- le32_to_cpu(fh->jpg_buffers.
- buffer[i].frag_tab[2 * j]);
+ le32_to_cpu(fh->buffers.
+ buffer[i].jpg.frag_tab[2 * j]);
/* should just be pos on i386 */
page = virt_to_phys(bus_to_virt(pos))
>> PAGE_SHIFT;
@@ -4470,123 +3312,82 @@ zoran_mmap (struct file *file,
todo, PAGE_SHARED)) {
dprintk(1,
KERN_ERR
- "%s: zoran_mmap(V4L) - remap_pfn_range failed\n",
- ZR_DEVNAME(zr));
+ "%s: %s(V4L) - remap_pfn_range failed\n",
+ ZR_DEVNAME(zr), __func__);
res = -EAGAIN;
- goto jpg_mmap_unlock_and_return;
+ goto mmap_unlock_and_return;
}
size -= todo;
start += todo;
if (size == 0)
break;
- if (le32_to_cpu(fh->jpg_buffers.buffer[i].
+ if (le32_to_cpu(fh->buffers.buffer[i].jpg.
frag_tab[2 * j + 1]) & 1)
break; /* was last fragment */
}
- fh->jpg_buffers.buffer[i].map = map;
+ fh->buffers.buffer[i].map = map;
if (size == 0)
break;
}
- jpg_mmap_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- break;
-
- case ZORAN_MAP_MODE_RAW:
-
- mutex_lock(&zr->resource_lock);
-
- /* Map the V4L buffers */
- if (!fh->v4l_buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: zoran_mmap(V4L) - buffers not yet allocated\n",
- ZR_DEVNAME(zr));
- res = -ENOMEM;
- goto v4l_mmap_unlock_and_return;
- }
-
- first = offset / fh->v4l_buffers.buffer_size;
- last = first - 1 + size / fh->v4l_buffers.buffer_size;
- if (offset % fh->v4l_buffers.buffer_size != 0 ||
- size % fh->v4l_buffers.buffer_size != 0 || first < 0 ||
- last < 0 || first >= fh->v4l_buffers.num_buffers ||
- last >= fh->v4l_buffers.buffer_size) {
- dprintk(1,
- KERN_ERR
- "%s: mmap(V4L) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
- ZR_DEVNAME(zr), offset, size,
- fh->v4l_buffers.buffer_size,
- fh->v4l_buffers.num_buffers);
- res = -EINVAL;
- goto v4l_mmap_unlock_and_return;
- }
- for (i = first; i <= last; i++) {
- if (fh->v4l_buffers.buffer[i].map) {
- dprintk(1,
- KERN_ERR
- "%s: mmap(V4L) - buffer %d already mapped\n",
- ZR_DEVNAME(zr), i);
- res = -EBUSY;
- goto v4l_mmap_unlock_and_return;
- }
- }
-
- /* map these buffers (v4l_buffers[i]) */
- map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
- if (!map) {
- res = -ENOMEM;
- goto v4l_mmap_unlock_and_return;
- }
- map->file = file;
- map->count = 1;
-
- vma->vm_ops = &zoran_vm_ops;
- vma->vm_flags |= VM_DONTEXPAND;
- vma->vm_private_data = map;
-
- for (i = first; i <= last; i++) {
- todo = size;
- if (todo > fh->v4l_buffers.buffer_size)
- todo = fh->v4l_buffers.buffer_size;
- page = fh->v4l_buffers.buffer[i].fbuffer_phys;
- if (remap_pfn_range(vma, start, page >> PAGE_SHIFT,
- todo, PAGE_SHARED)) {
- dprintk(1,
- KERN_ERR
- "%s: zoran_mmap(V4L)i - remap_pfn_range failed\n",
- ZR_DEVNAME(zr));
- res = -EAGAIN;
- goto v4l_mmap_unlock_and_return;
- }
- size -= todo;
- start += todo;
- fh->v4l_buffers.buffer[i].map = map;
- if (size == 0)
- break;
- }
- v4l_mmap_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- break;
-
- default:
- dprintk(1,
- KERN_ERR
- "%s: zoran_mmap() - internal error - unknown map mode %d\n",
- ZR_DEVNAME(zr), fh->map_mode);
- break;
}
+mmap_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+
return 0;
}
+static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
+ .vidioc_querycap = zoran_querycap,
+ .vidioc_cropcap = zoran_cropcap,
+ .vidioc_s_crop = zoran_s_crop,
+ .vidioc_g_crop = zoran_g_crop,
+ .vidioc_enum_input = zoran_enum_input,
+ .vidioc_g_input = zoran_g_input,
+ .vidioc_s_input = zoran_s_input,
+ .vidioc_enum_output = zoran_enum_output,
+ .vidioc_g_output = zoran_g_output,
+ .vidioc_s_output = zoran_s_output,
+ .vidioc_g_fbuf = zoran_g_fbuf,
+ .vidioc_s_fbuf = zoran_s_fbuf,
+ .vidioc_g_std = zoran_g_std,
+ .vidioc_s_std = zoran_s_std,
+ .vidioc_g_jpegcomp = zoran_g_jpegcomp,
+ .vidioc_s_jpegcomp = zoran_s_jpegcomp,
+ .vidioc_overlay = zoran_overlay,
+ .vidioc_reqbufs = zoran_reqbufs,
+ .vidioc_querybuf = zoran_querybuf,
+ .vidioc_qbuf = zoran_qbuf,
+ .vidioc_dqbuf = zoran_dqbuf,
+ .vidioc_streamon = zoran_streamon,
+ .vidioc_streamoff = zoran_streamoff,
+ .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out,
+ .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay,
+ .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap,
+ .vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out,
+ .vidioc_g_fmt_vid_overlay = zoran_g_fmt_vid_overlay,
+ .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap,
+ .vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out,
+ .vidioc_s_fmt_vid_overlay = zoran_s_fmt_vid_overlay,
+ .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap,
+ .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out,
+ .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay,
+ .vidioc_queryctrl = zoran_queryctrl,
+ .vidioc_s_ctrl = zoran_s_ctrl,
+ .vidioc_g_ctrl = zoran_g_ctrl,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ .vidioc_default = zoran_default,
+ .vidiocgmbuf = zoran_vidiocgmbuf,
+#endif
+};
+
static const struct v4l2_file_operations zoran_fops = {
.owner = THIS_MODULE,
.open = zoran_open,
.release = zoran_close,
- .ioctl = zoran_ioctl,
+ .ioctl = video_ioctl2,
.read = zoran_read,
.write = zoran_write,
.mmap = zoran_mmap,
@@ -4596,7 +3397,9 @@ static const struct v4l2_file_operations zoran_fops = {
struct video_device zoran_template __devinitdata = {
.name = ZORAN_NAME,
.fops = &zoran_fops,
+ .ioctl_ops = &zoran_ioctl_ops,
.release = &zoran_vdev_release,
+ .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
.minor = -1
};
diff --git a/drivers/media/video/zoran/zoran_procfs.c b/drivers/media/video/zoran/zoran_procfs.c
index 870bc5a70e3f..f1423b777db1 100644
--- a/drivers/media/video/zoran/zoran_procfs.c
+++ b/drivers/media/video/zoran/zoran_procfs.c
@@ -36,7 +36,7 @@
#include <linux/pci.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/spinlock.h>
#include <linux/sem.h>
#include <linux/seq_file.h>
diff --git a/drivers/media/video/zoran/zr36016.c b/drivers/media/video/zoran/zr36016.c
index 00d132bcd1e4..21c088ea9046 100644
--- a/drivers/media/video/zoran/zr36016.c
+++ b/drivers/media/video/zoran/zr36016.c
@@ -34,15 +34,10 @@
#include <linux/types.h>
#include <linux/wait.h>
-/* includes for structures and defines regarding video
- #include<linux/videodev.h> */
-
/* I/O commands, error codes */
#include <asm/io.h>
-//#include<errno.h>
/* v4l API */
-#include <linux/videodev.h>
/* headerfile of this module */
#include"zr36016.h"
diff --git a/drivers/media/video/zoran/zr36050.c b/drivers/media/video/zoran/zr36050.c
index cf8b271a1c8f..639dd87c663f 100644
--- a/drivers/media/video/zoran/zr36050.c
+++ b/drivers/media/video/zoran/zr36050.c
@@ -34,12 +34,8 @@
#include <linux/types.h>
#include <linux/wait.h>
-/* includes for structures and defines regarding video
- #include<linux/videodev.h> */
-
/* I/O commands, error codes */
#include <asm/io.h>
-//#include<errno.h>
/* headerfile of this module */
#include "zr36050.h"
diff --git a/drivers/media/video/zoran/zr36060.c b/drivers/media/video/zoran/zr36060.c
index 8e74054d5ef1..008746ff7746 100644
--- a/drivers/media/video/zoran/zr36060.c
+++ b/drivers/media/video/zoran/zr36060.c
@@ -34,12 +34,8 @@
#include <linux/types.h>
#include <linux/wait.h>
-/* includes for structures and defines regarding video
- #include<linux/videodev.h> */
-
/* I/O commands, error codes */
#include <asm/io.h>
-//#include<errno.h>
/* headerfile of this module */
#include "zr36060.h"
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 93023560f324..221409fe1682 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -96,6 +96,7 @@ static struct usb_device_id device_table[] = {
{USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
{USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
{USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
+ {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 },
{} /* Terminating entry */
};
@@ -425,7 +426,6 @@ static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t cnt,
static int zr364xx_vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- memset(cap, 0, sizeof(*cap));
strcpy(cap->driver, DRIVER_DESC);
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
return 0;
@@ -436,8 +436,6 @@ static int zr364xx_vidioc_enum_input(struct file *file, void *priv,
{
if (i->index != 0)
return -EINVAL;
- memset(i, 0, sizeof(*i));
- i->index = 0;
strcpy(i->name, DRIVER_DESC " Camera");
i->type = V4L2_INPUT_TYPE_CAMERA;
return 0;
@@ -529,11 +527,6 @@ static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file,
{
if (f->index > 0)
return -EINVAL;
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- memset(f, 0, sizeof(*f));
- f->index = 0;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->flags = V4L2_FMT_FLAG_COMPRESSED;
strcpy(f->description, "JPEG");
f->pixelformat = V4L2_PIX_FMT_JPEG;
@@ -550,8 +543,6 @@ static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
return -ENODEV;
cam = video_get_drvdata(vdev);
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
return -EINVAL;
if (f->fmt.pix.field != V4L2_FIELD_ANY &&
@@ -577,10 +568,6 @@ static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
return -ENODEV;
cam = video_get_drvdata(vdev);
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
f->fmt.pix.field = V4L2_FIELD_NONE;
f->fmt.pix.width = cam->width;
@@ -602,8 +589,6 @@ static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
return -ENODEV;
cam = video_get_drvdata(vdev);
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
return -EINVAL;
if (f->fmt.pix.field != V4L2_FIELD_ANY &&
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 12b732512e57..a9019f081b97 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -2279,9 +2279,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
mutex_lock(&ioc->sas_topology_mutex);
list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
- if (port_info->phy_info &&
- (!(port_info->phy_info[0].identify.device_info &
- MPI_SAS_DEVICE_INFO_SMP_TARGET)))
+ if (!(port_info->phy_info[0].identify.device_info &
+ MPI_SAS_DEVICE_INFO_SMP_TARGET))
continue;
if (mptsas_sas_expander_pg0(ioc, &buffer,
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
index 9a36b5a7de57..7045c45da9b1 100644
--- a/drivers/message/i2o/i2o_proc.c
+++ b/drivers/message/i2o/i2o_proc.c
@@ -2037,8 +2037,6 @@ static int __init i2o_proc_fs_create(void)
if (!i2o_proc_dir_root)
return -1;
- i2o_proc_dir_root->owner = THIS_MODULE;
-
list_for_each_entry(c, &i2o_controllers, list)
i2o_proc_iop_add(i2o_proc_dir_root, c);
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 06a2b0f7737c..ee3927ab11e0 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -52,6 +52,7 @@ config HTC_EGPIO
config HTC_PASIC3
tristate "HTC PASIC3 LED/DS1WM chip support"
+ select MFD_CORE
help
This core driver provides register access for the LED/DS1WM
chips labeled "AIC2" and "AIC3", found on HTC Blueangel and
@@ -88,7 +89,7 @@ config MENELAUS
help
If you say yes here you get support for the Texas Instruments
TWL92330/Menelaus Power Management chip. This include voltage
- regulators, Dual slot memory card tranceivers, real-time clock
+ regulators, Dual slot memory card transceivers, real-time clock
and other features that are often used in portable devices like
cell phones and PDAs.
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c
index 99f8dcfe3d98..7283d88656af 100644
--- a/drivers/mfd/da903x.c
+++ b/drivers/mfd/da903x.c
@@ -413,7 +413,7 @@ static void da903x_irq_work(struct work_struct *work)
enable_irq(chip->client->irq);
}
-static int da903x_irq_handler(int irq, void *data)
+static irqreturn_t da903x_irq_handler(int irq, void *data)
{
struct da903x_chip *chip = data;
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
index 91b294dcc133..386da1566fcc 100644
--- a/drivers/mfd/htc-pasic3.c
+++ b/drivers/mfd/htc-pasic3.c
@@ -12,18 +12,17 @@
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/ds1wm.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/ds1wm.h>
#include <linux/mfd/htc-pasic3.h>
struct pasic3_data {
void __iomem *mapping;
unsigned int bus_shift;
- struct platform_device *ds1wm_pdev;
- struct platform_device *led_pdev;
};
#define REG_ADDR 5
@@ -65,46 +64,15 @@ EXPORT_SYMBOL(pasic3_read_register); /* for leds-pasic3 */
* LEDs
*/
-static int led_device_add(struct device *pasic3_dev,
- const struct pasic3_leds_machinfo *pdata)
-{
- struct pasic3_data *asic = pasic3_dev->driver_data;
- struct platform_device *pdev;
- int ret;
-
- pdev = platform_device_alloc("pasic3-led", -1);
- if (!pdev) {
- dev_dbg(pasic3_dev, "failed to allocate LED platform device\n");
- return -ENOMEM;
- }
-
- ret = platform_device_add_data(pdev, pdata,
- sizeof(struct pasic3_leds_machinfo));
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add LED platform data\n");
- goto exit_pdev_put;
- }
-
- pdev->dev.parent = pasic3_dev;
- ret = platform_device_add(pdev);
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add LED platform device\n");
- goto exit_pdev_put;
- }
-
- asic->led_pdev = pdev;
- return 0;
-
-exit_pdev_put:
- platform_device_put(pdev);
- return ret;
-}
+static struct mfd_cell led_cell __initdata = {
+ .name = "leds-pasic3",
+};
/*
* DS1WM
*/
-static void ds1wm_enable(struct platform_device *pdev)
+static int ds1wm_enable(struct platform_device *pdev)
{
struct device *dev = pdev->dev.parent;
int c;
@@ -113,9 +81,10 @@ static void ds1wm_enable(struct platform_device *pdev)
pasic3_write_register(dev, 0x28, c & 0x7f);
dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & 0x7f);
+ return 0;
}
-static void ds1wm_disable(struct platform_device *pdev)
+static int ds1wm_disable(struct platform_device *pdev)
{
struct device *dev = pdev->dev.parent;
int c;
@@ -124,56 +93,33 @@ static void ds1wm_disable(struct platform_device *pdev)
pasic3_write_register(dev, 0x28, c | 0x80);
dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | 0x80);
+ return 0;
}
-static struct ds1wm_platform_data ds1wm_pdata = {
- .bus_shift = 2,
- .enable = ds1wm_enable,
- .disable = ds1wm_disable,
+static struct ds1wm_driver_data ds1wm_pdata = {
+ .active_high = 0,
};
-static int ds1wm_device_add(struct platform_device *pasic3_pdev, int bus_shift)
-{
- struct device *pasic3_dev = &pasic3_pdev->dev;
- struct pasic3_data *asic = pasic3_dev->driver_data;
- struct platform_device *pdev;
- int ret;
-
- pdev = platform_device_alloc("ds1wm", -1);
- if (!pdev) {
- dev_dbg(pasic3_dev, "failed to allocate DS1WM platform device\n");
- return -ENOMEM;
- }
-
- ret = platform_device_add_resources(pdev, pasic3_pdev->resource,
- pasic3_pdev->num_resources);
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add DS1WM resources\n");
- goto exit_pdev_put;
- }
-
- ds1wm_pdata.bus_shift = asic->bus_shift;
- ret = platform_device_add_data(pdev, &ds1wm_pdata,
- sizeof(struct ds1wm_platform_data));
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add DS1WM platform data\n");
- goto exit_pdev_put;
- }
-
- pdev->dev.parent = pasic3_dev;
- ret = platform_device_add(pdev);
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add DS1WM platform device\n");
- goto exit_pdev_put;
- }
-
- asic->ds1wm_pdev = pdev;
- return 0;
+static struct resource ds1wm_resources[] __initdata = {
+ [0] = {
+ .start = 0,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
-exit_pdev_put:
- platform_device_put(pdev);
- return ret;
-}
+static struct mfd_cell ds1wm_cell __initdata = {
+ .name = "ds1wm",
+ .enable = ds1wm_enable,
+ .disable = ds1wm_disable,
+ .driver_data = &ds1wm_pdata,
+ .num_resources = 2,
+ .resources = ds1wm_resources,
+};
static int __init pasic3_probe(struct platform_device *pdev)
{
@@ -182,12 +128,27 @@ static int __init pasic3_probe(struct platform_device *pdev)
struct pasic3_data *asic;
struct resource *r;
int ret;
+ int irq = 0;
+
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (r) {
+ ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags &
+ (IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE));
+ irq = r->start;
+ }
+
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (r) {
+ ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags &
+ (IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE));
+ irq = r->start;
+ }
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r)
return -ENXIO;
- if (!request_mem_region(r->start, r->end - r->start + 1, "pasic3"))
+ if (!request_mem_region(r->start, resource_size(r), "pasic3"))
return -EBUSY;
asic = kzalloc(sizeof(struct pasic3_data), GFP_KERNEL);
@@ -196,24 +157,33 @@ static int __init pasic3_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, asic);
- if (pdata && pdata->bus_shift)
- asic->bus_shift = pdata->bus_shift;
- else
- asic->bus_shift = 2;
-
- asic->mapping = ioremap(r->start, r->end - r->start + 1);
+ asic->mapping = ioremap(r->start, resource_size(r));
if (!asic->mapping) {
dev_err(dev, "couldn't ioremap PASIC3\n");
kfree(asic);
return -ENOMEM;
}
- ret = ds1wm_device_add(pdev, asic->bus_shift);
- if (ret < 0)
- dev_warn(dev, "failed to register DS1WM\n");
+ /* calculate bus shift from mem resource */
+ asic->bus_shift = (resource_size(r) - 5) >> 3;
+
+ if (pdata && pdata->clock_rate) {
+ ds1wm_pdata.clock_rate = pdata->clock_rate;
+ /* the first 5 PASIC3 registers control the DS1WM */
+ ds1wm_resources[0].end = (5 << asic->bus_shift) - 1;
+ ds1wm_cell.platform_data = &ds1wm_cell;
+ ds1wm_cell.data_size = sizeof(ds1wm_cell);
+ ret = mfd_add_devices(&pdev->dev, pdev->id,
+ &ds1wm_cell, 1, r, irq);
+ if (ret < 0)
+ dev_warn(dev, "failed to register DS1WM\n");
+ }
- if (pdata->led_pdata) {
- ret = led_device_add(dev, pdata->led_pdata);
+ if (pdata && pdata->led_pdata) {
+ led_cell.driver_data = pdata->led_pdata;
+ led_cell.platform_data = &led_cell;
+ led_cell.data_size = sizeof(ds1wm_cell);
+ ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0);
if (ret < 0)
dev_warn(dev, "failed to register LED device\n");
}
@@ -226,14 +196,11 @@ static int pasic3_remove(struct platform_device *pdev)
struct pasic3_data *asic = platform_get_drvdata(pdev);
struct resource *r;
- if (asic->led_pdev)
- platform_device_unregister(asic->led_pdev);
- if (asic->ds1wm_pdev)
- platform_device_unregister(asic->ds1wm_pdev);
+ mfd_remove_devices(&pdev->dev);
iounmap(asic->mapping);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(r->start, r->end - r->start + 1);
+ release_mem_region(r->start, resource_size(r));
kfree(asic);
return 0;
}
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index 6063dc2b52e8..57271cb3b316 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -214,7 +214,7 @@ EXPORT_SYMBOL(mcp_host_alloc);
int mcp_host_register(struct mcp *mcp)
{
- strcpy(mcp->attached_device.bus_id, "mcp0");
+ dev_set_name(&mcp->attached_device, "mcp0");
return device_register(&mcp->attached_device);
}
EXPORT_SYMBOL(mcp_host_register);
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 2e36057659e1..7793932a513b 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -15,7 +15,6 @@
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/sysfs.h>
-#include <linux/device.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/interrupt.h>
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 9f7024c0f8ec..e9f4323dd2cb 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -108,7 +108,7 @@ static int t7l66xb_mmc_disable(struct platform_device *mmc)
/*--------------------------------------------------------------------------*/
-const static struct resource t7l66xb_mmc_resources[] = {
+static const struct resource t7l66xb_mmc_resources[] = {
{
.start = 0x800,
.end = 0x9ff,
@@ -126,7 +126,7 @@ const static struct resource t7l66xb_mmc_resources[] = {
},
};
-const static struct resource t7l66xb_nand_resources[] = {
+static const struct resource t7l66xb_nand_resources[] = {
{
.start = 0xc00,
.end = 0xc07,
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index f856e9463a9f..77a12fc8045e 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -172,7 +172,7 @@ static struct resource __devinitdata tc6393xb_mmc_resources[] = {
},
};
-const static struct resource tc6393xb_ohci_resources[] = {
+static const struct resource tc6393xb_ohci_resources[] = {
{
.start = 0x3000,
.end = 0x31ff,
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index 68826f1e36bc..ec90e953adce 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -592,11 +592,9 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
/* maybe add LDOs that are omitted on cost-reduced parts */
if (twl_has_regulator() && !(features & TPS_SUBSET)) {
- /*
child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
if (IS_ERR(child))
return PTR_ERR(child);
- */
child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2);
if (IS_ERR(child))
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index b10876036983..aca2670afd78 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -182,7 +182,7 @@ static int twl4030_irq_thread(void *data)
long irq = (long)data;
struct irq_desc *desc = irq_to_desc(irq);
static unsigned i2c_errors;
- const static unsigned max_i2c_errors = 100;
+ static const unsigned max_i2c_errors = 100;
if (!desc) {
pr_err("twl4030: Invalid IRQ: %ld\n", irq);
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index 6860c924f364..fea9085fe52c 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -492,7 +492,7 @@ static int ucb1x00_probe(struct mcp *mcp)
ucb->dev.class = &ucb1x00_class;
ucb->dev.parent = &mcp->attached_device;
- strlcpy(ucb->dev.bus_id, "ucb1x00", sizeof(ucb->dev.bus_id));
+ dev_set_name(&ucb->dev, "ucb1x00");
spin_lock_init(&ucb->lock);
spin_lock_init(&ucb->io_lock);
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index b457a05b28d9..c2be3088e2e1 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -1111,7 +1111,7 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
do {
schedule_timeout_interruptible(1);
reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
- } while (--tries && (reg & WM8350_AUXADC_POLL));
+ } while ((reg & WM8350_AUXADC_POLL) && --tries);
if (!tries)
dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
@@ -1238,7 +1238,7 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode)
}
wm8350->reg_cache =
- kzalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL);
+ kmalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL);
if (wm8350->reg_cache == NULL)
return -ENOMEM;
@@ -1246,17 +1246,20 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode)
* a PMIC so the device many not be in a virgin state and we
* can't rely on the silicon values.
*/
+ ret = wm8350->read_dev(wm8350, 0,
+ sizeof(u16) * (WM8350_MAX_REGISTER + 1),
+ wm8350->reg_cache);
+ if (ret < 0) {
+ dev_err(wm8350->dev,
+ "failed to read initial cache values\n");
+ goto out;
+ }
+
+ /* Mask out uncacheable/unreadable bits and the audio. */
for (i = 0; i < WM8350_MAX_REGISTER; i++) {
- /* audio register range */
if (wm8350_reg_io_map[i].readable &&
(i < WM8350_CLOCK_CONTROL_1 || i > WM8350_AIF_TEST)) {
- ret = wm8350->read_dev(wm8350, i, 2, (char *)&value);
- if (ret < 0) {
- dev_err(wm8350->dev,
- "failed to read initial cache value\n");
- goto out;
- }
- value = be16_to_cpu(value);
+ value = be16_to_cpu(wm8350->reg_cache[i]);
value &= wm8350_reg_io_map[i].readable;
value &= ~wm8350_reg_io_map[i].vol;
wm8350->reg_cache[i] = value;
@@ -1435,7 +1438,21 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
mutex_init(&wm8350->irq_mutex);
INIT_WORK(&wm8350->irq_work, wm8350_irq_worker);
if (irq) {
- ret = request_irq(irq, wm8350_irq, 0,
+ int flags = 0;
+
+ if (pdata && pdata->irq_high) {
+ flags |= IRQF_TRIGGER_HIGH;
+
+ wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
+ WM8350_IRQ_POL);
+ } else {
+ flags |= IRQF_TRIGGER_LOW;
+
+ wm8350_clear_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
+ WM8350_IRQ_POL);
+ }
+
+ ret = request_irq(irq, wm8350_irq, flags,
"wm8350", wm8350);
if (ret != 0) {
dev_err(wm8350->dev, "Failed to request IRQ: %d\n",
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1c484084ed4f..6d1ac180f6ee 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -18,8 +18,8 @@ config ATMEL_PWM
depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9
help
This option enables device driver support for the PWM channels
- on certain Atmel prcoessors. Pulse Width Modulation is used for
- purposes including software controlled power-efficent backlights
+ on certain Atmel processors. Pulse Width Modulation is used for
+ purposes including software controlled power-efficient backlights
on LCD displays, motor control, and waveform generation.
config ATMEL_TCLIB
@@ -142,7 +142,7 @@ config ATMEL_SSC
tristate "Device driver for Atmel SSC peripheral"
depends on AVR32 || ARCH_AT91
---help---
- This option enables device driver support for Atmel Syncronized
+ This option enables device driver support for Atmel Synchronized
Serial Communication peripheral (SSC).
The SSC peripheral supports a wide variety of serial frame based
@@ -165,7 +165,7 @@ config SGI_XP
depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_UV) && SMP
select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
- select SGI_GRU if (IA64_GENERIC || IA64_SGI_UV || X86_64) && SMP
+ select SGI_GRU if X86_64 && SMP
---help---
An SGI machine can be divided into multiple Single System
Images which act independently of each other and have
@@ -189,7 +189,7 @@ config HP_ILO
config SGI_GRU
tristate "SGI GRU driver"
- depends on (X86_UV || IA64_SGI_UV || IA64_GENERIC) && SMP
+ depends on X86_UV && SMP
default n
select MMU_NOTIFIER
---help---
@@ -223,6 +223,16 @@ config DELL_LAPTOP
This driver adds support for rfkill and backlight control to Dell
laptops.
+config ISL29003
+ tristate "Intersil ISL29003 ambient light sensor"
+ depends on I2C && SYSFS
+ help
+ If you say yes here you get support for the Intersil ISL29003
+ ambient light sensor.
+
+ This driver can also be built as a module. If so, the module
+ will be called isl29003.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index bc1199830554..7871f05dcb9b 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -18,5 +18,6 @@ obj-$(CONFIG_KGDB_TESTS) += kgdbts.o
obj-$(CONFIG_SGI_XP) += sgi-xp/
obj-$(CONFIG_SGI_GRU) += sgi-gru/
obj-$(CONFIG_HP_ILO) += hpilo.o
+obj-$(CONFIG_ISL29003) += isl29003.o
obj-$(CONFIG_C2PORT) += c2port/
obj-y += eeprom/
diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig
index c76df8cda5ef..89fec052f3b4 100644
--- a/drivers/misc/eeprom/Kconfig
+++ b/drivers/misc/eeprom/Kconfig
@@ -2,7 +2,7 @@ menu "EEPROM support"
config EEPROM_AT24
tristate "I2C EEPROMs from most vendors"
- depends on I2C && SYSFS && EXPERIMENTAL
+ depends on I2C && SYSFS
help
Enable this driver to get read/write support to most I2C EEPROMs,
after you configure the driver to know about each EEPROM on
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index d4775528abc6..d184dfab9631 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -53,6 +53,7 @@
struct at24_data {
struct at24_platform_data chip;
+ struct memory_accessor macc;
bool use_smbus;
/*
@@ -225,14 +226,11 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
return status;
}
-static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr,
+static ssize_t at24_read(struct at24_data *at24,
char *buf, loff_t off, size_t count)
{
- struct at24_data *at24;
ssize_t retval = 0;
- at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
-
if (unlikely(!count))
return count;
@@ -262,12 +260,14 @@ static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr,
return retval;
}
+static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct at24_data *at24;
-/*
- * REVISIT: export at24_bin{read,write}() to let other kernel code use
- * eeprom data. For example, it might hold a board's Ethernet address, or
- * board-specific calibration data generated on the manufacturing floor.
- */
+ at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
+ return at24_read(at24, buf, off, count);
+}
/*
@@ -347,14 +347,11 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf,
return -ETIMEDOUT;
}
-static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr,
+static ssize_t at24_write(struct at24_data *at24,
char *buf, loff_t off, size_t count)
{
- struct at24_data *at24;
ssize_t retval = 0;
- at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
-
if (unlikely(!count))
return count;
@@ -384,6 +381,39 @@ static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr,
return retval;
}
+static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct at24_data *at24;
+
+ at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
+ return at24_write(at24, buf, off, count);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * This lets other kernel code access the eeprom data. For example, it
+ * might hold a board's Ethernet address, or board-specific calibration
+ * data generated on the manufacturing floor.
+ */
+
+static ssize_t at24_macc_read(struct memory_accessor *macc, char *buf,
+ off_t offset, size_t count)
+{
+ struct at24_data *at24 = container_of(macc, struct at24_data, macc);
+
+ return at24_read(at24, buf, offset, count);
+}
+
+static ssize_t at24_macc_write(struct memory_accessor *macc, char *buf,
+ off_t offset, size_t count)
+{
+ struct at24_data *at24 = container_of(macc, struct at24_data, macc);
+
+ return at24_write(at24, buf, offset, count);
+}
+
/*-------------------------------------------------------------------------*/
static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
@@ -413,6 +443,9 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
* is recommended anyhow.
*/
chip.page_size = 1;
+
+ chip.setup = NULL;
+ chip.context = NULL;
}
if (!is_power_of_2(chip.byte_len))
@@ -463,6 +496,8 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
at24->bin.read = at24_bin_read;
at24->bin.size = chip.byte_len;
+ at24->macc.read = at24_macc_read;
+
writable = !(chip.flags & AT24_FLAG_READONLY);
if (writable) {
if (!use_smbus || i2c_check_functionality(client->adapter,
@@ -470,6 +505,8 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
unsigned write_max = chip.page_size;
+ at24->macc.write = at24_macc_write;
+
at24->bin.write = at24_bin_write;
at24->bin.attr.mode |= S_IWUSR;
@@ -520,6 +557,10 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
at24->write_max,
use_smbus ? ", use_smbus" : "");
+ /* export data to kernel code */
+ if (chip.setup)
+ chip.setup(&at24->macc, chip.context);
+
return 0;
err_clients:
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index 290dbe99647a..6bc0dac5c1e8 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -30,6 +30,7 @@
struct at25_data {
struct spi_device *spi;
+ struct memory_accessor mem;
struct mutex lock;
struct spi_eeprom chip;
struct bin_attribute bin;
@@ -75,6 +76,13 @@ at25_ee_read(
struct spi_transfer t[2];
struct spi_message m;
+ if (unlikely(offset >= at25->bin.size))
+ return 0;
+ if ((offset + count) > at25->bin.size)
+ count = at25->bin.size - offset;
+ if (unlikely(!count))
+ return count;
+
cp = command;
*cp++ = AT25_READ;
@@ -127,13 +135,6 @@ at25_bin_read(struct kobject *kobj, struct bin_attribute *bin_attr,
dev = container_of(kobj, struct device, kobj);
at25 = dev_get_drvdata(dev);
- if (unlikely(off >= at25->bin.size))
- return 0;
- if ((off + count) > at25->bin.size)
- count = at25->bin.size - off;
- if (unlikely(!count))
- return count;
-
return at25_ee_read(at25, buf, off, count);
}
@@ -146,6 +147,13 @@ at25_ee_write(struct at25_data *at25, char *buf, loff_t off, size_t count)
unsigned buf_size;
u8 *bounce;
+ if (unlikely(off >= at25->bin.size))
+ return -EFBIG;
+ if ((off + count) > at25->bin.size)
+ count = at25->bin.size - off;
+ if (unlikely(!count))
+ return count;
+
/* Temp buffer starts with command and address */
buf_size = at25->chip.page_size;
if (buf_size > io_limit)
@@ -253,18 +261,31 @@ at25_bin_write(struct kobject *kobj, struct bin_attribute *bin_attr,
dev = container_of(kobj, struct device, kobj);
at25 = dev_get_drvdata(dev);
- if (unlikely(off >= at25->bin.size))
- return -EFBIG;
- if ((off + count) > at25->bin.size)
- count = at25->bin.size - off;
- if (unlikely(!count))
- return count;
-
return at25_ee_write(at25, buf, off, count);
}
/*-------------------------------------------------------------------------*/
+/* Let in-kernel code access the eeprom data. */
+
+static ssize_t at25_mem_read(struct memory_accessor *mem, char *buf,
+ off_t offset, size_t count)
+{
+ struct at25_data *at25 = container_of(mem, struct at25_data, mem);
+
+ return at25_ee_read(at25, buf, offset, count);
+}
+
+static ssize_t at25_mem_write(struct memory_accessor *mem, char *buf,
+ off_t offset, size_t count)
+{
+ struct at25_data *at25 = container_of(mem, struct at25_data, mem);
+
+ return at25_ee_write(at25, buf, offset, count);
+}
+
+/*-------------------------------------------------------------------------*/
+
static int at25_probe(struct spi_device *spi)
{
struct at25_data *at25 = NULL;
@@ -317,6 +338,10 @@ static int at25_probe(struct spi_device *spi)
at25->addrlen = addrlen;
/* Export the EEPROM bytes through sysfs, since that's convenient.
+ * And maybe to other kernel code; it might hold a board's Ethernet
+ * address, or board-specific calibration data generated on the
+ * manufacturing floor.
+ *
* Default to root-only access to the data; EEPROMs often hold data
* that's sensitive for read and/or write, like ethernet addresses,
* security codes, board-specific manufacturing calibrations, etc.
@@ -324,17 +349,22 @@ static int at25_probe(struct spi_device *spi)
at25->bin.attr.name = "eeprom";
at25->bin.attr.mode = S_IRUSR;
at25->bin.read = at25_bin_read;
+ at25->mem.read = at25_mem_read;
at25->bin.size = at25->chip.byte_len;
if (!(chip->flags & EE_READONLY)) {
at25->bin.write = at25_bin_write;
at25->bin.attr.mode |= S_IWUSR;
+ at25->mem.write = at25_mem_write;
}
err = sysfs_create_bin_file(&spi->dev.kobj, &at25->bin);
if (err)
goto fail;
+ if (chip->setup)
+ chip->setup(&at25->mem, chip->context);
+
dev_info(&spi->dev, "%Zd %s %s eeprom%s, pagesize %u\n",
(at25->bin.size < 1024)
? at25->bin.size
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
index cf991850f01b..880ccf39e23b 100644
--- a/drivers/misc/hpilo.c
+++ b/drivers/misc/hpilo.c
@@ -209,7 +209,7 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data)
/* give iLO some time to process stop request */
for (retries = MAX_WAIT; retries > 0; retries--) {
doorbell_set(driver_ccb);
- udelay(1);
+ udelay(WAIT_TIME);
if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A))
&&
!(ioread32(&device_ccb->recv_ctrl) & (1 << CTRL_BITPOS_A)))
@@ -312,7 +312,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
for (i = MAX_WAIT; i > 0; i--) {
if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL))
break;
- udelay(1);
+ udelay(WAIT_TIME);
}
if (i) {
@@ -759,7 +759,7 @@ static void __exit ilo_exit(void)
class_destroy(ilo_class);
}
-MODULE_VERSION("1.0");
+MODULE_VERSION("1.1");
MODULE_ALIAS(ILO_NAME);
MODULE_DESCRIPTION(ILO_NAME);
MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>");
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h
index b64a20ef07e3..03a14c82aad9 100644
--- a/drivers/misc/hpilo.h
+++ b/drivers/misc/hpilo.h
@@ -19,8 +19,12 @@
#define MAX_ILO_DEV 1
/* max number of files */
#define MAX_OPEN (MAX_CCB * MAX_ILO_DEV)
+/* total wait time in usec */
+#define MAX_WAIT_TIME 10000
+/* per spin wait time in usec */
+#define WAIT_TIME 10
/* spin counter for open/close delay */
-#define MAX_WAIT 10000
+#define MAX_WAIT (MAX_WAIT_TIME / WAIT_TIME)
/*
* Per device, used to track global memory allocations.
diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c
new file mode 100644
index 000000000000..2e2a5923d4c2
--- /dev/null
+++ b/drivers/misc/isl29003.c
@@ -0,0 +1,470 @@
+/*
+ * isl29003.c - Linux kernel module for
+ * Intersil ISL29003 ambient light sensor
+ *
+ * See file:Documentation/misc-devices/isl29003
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * Based on code written by
+ * Rodolfo Giometti <giometti@linux.it>
+ * Eurotech S.p.A. <info@eurotech.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#define ISL29003_DRV_NAME "isl29003"
+#define DRIVER_VERSION "1.0"
+
+#define ISL29003_REG_COMMAND 0x00
+#define ISL29003_ADC_ENABLED (1 << 7)
+#define ISL29003_ADC_PD (1 << 6)
+#define ISL29003_TIMING_INT (1 << 5)
+#define ISL29003_MODE_SHIFT (2)
+#define ISL29003_MODE_MASK (0x3 << ISL29003_MODE_SHIFT)
+#define ISL29003_RES_SHIFT (0)
+#define ISL29003_RES_MASK (0x3 << ISL29003_RES_SHIFT)
+
+#define ISL29003_REG_CONTROL 0x01
+#define ISL29003_INT_FLG (1 << 5)
+#define ISL29003_RANGE_SHIFT (2)
+#define ISL29003_RANGE_MASK (0x3 << ISL29003_RANGE_SHIFT)
+#define ISL29003_INT_PERSISTS_SHIFT (0)
+#define ISL29003_INT_PERSISTS_MASK (0xf << ISL29003_INT_PERSISTS_SHIFT)
+
+#define ISL29003_REG_IRQ_THRESH_HI 0x02
+#define ISL29003_REG_IRQ_THRESH_LO 0x03
+#define ISL29003_REG_LSB_SENSOR 0x04
+#define ISL29003_REG_MSB_SENSOR 0x05
+#define ISL29003_REG_LSB_TIMER 0x06
+#define ISL29003_REG_MSB_TIMER 0x07
+
+#define ISL29003_NUM_CACHABLE_REGS 4
+
+struct isl29003_data {
+ struct i2c_client *client;
+ struct mutex lock;
+ u8 reg_cache[ISL29003_NUM_CACHABLE_REGS];
+};
+
+static int gain_range[] = {
+ 1000, 4000, 16000, 64000
+};
+
+/*
+ * register access helpers
+ */
+
+static int __isl29003_read_reg(struct i2c_client *client,
+ u32 reg, u8 mask, u8 shift)
+{
+ struct isl29003_data *data = i2c_get_clientdata(client);
+ return (data->reg_cache[reg] & mask) >> shift;
+}
+
+static int __isl29003_write_reg(struct i2c_client *client,
+ u32 reg, u8 mask, u8 shift, u8 val)
+{
+ struct isl29003_data *data = i2c_get_clientdata(client);
+ int ret = 0;
+ u8 tmp;
+
+ if (reg >= ISL29003_NUM_CACHABLE_REGS)
+ return -EINVAL;
+
+ mutex_lock(&data->lock);
+
+ tmp = data->reg_cache[reg];
+ tmp &= ~mask;
+ tmp |= val << shift;
+
+ ret = i2c_smbus_write_byte_data(client, reg, tmp);
+ if (!ret)
+ data->reg_cache[reg] = tmp;
+
+ mutex_unlock(&data->lock);
+ return ret;
+}
+
+/*
+ * internally used functions
+ */
+
+/* range */
+static int isl29003_get_range(struct i2c_client *client)
+{
+ return __isl29003_read_reg(client, ISL29003_REG_CONTROL,
+ ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT);
+}
+
+static int isl29003_set_range(struct i2c_client *client, int range)
+{
+ return __isl29003_write_reg(client, ISL29003_REG_CONTROL,
+ ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT, range);
+}
+
+/* resolution */
+static int isl29003_get_resolution(struct i2c_client *client)
+{
+ return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
+ ISL29003_RES_MASK, ISL29003_RES_SHIFT);
+}
+
+static int isl29003_set_resolution(struct i2c_client *client, int res)
+{
+ return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
+ ISL29003_RES_MASK, ISL29003_RES_SHIFT, res);
+}
+
+/* mode */
+static int isl29003_get_mode(struct i2c_client *client)
+{
+ return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
+ ISL29003_RES_MASK, ISL29003_RES_SHIFT);
+}
+
+static int isl29003_set_mode(struct i2c_client *client, int mode)
+{
+ return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
+ ISL29003_RES_MASK, ISL29003_RES_SHIFT, mode);
+}
+
+/* power_state */
+static int isl29003_set_power_state(struct i2c_client *client, int state)
+{
+ return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
+ ISL29003_ADC_ENABLED | ISL29003_ADC_PD, 0,
+ state ? ISL29003_ADC_ENABLED : ISL29003_ADC_PD);
+}
+
+static int isl29003_get_power_state(struct i2c_client *client)
+{
+ struct isl29003_data *data = i2c_get_clientdata(client);
+ u8 cmdreg = data->reg_cache[ISL29003_REG_COMMAND];
+ return ~cmdreg & ISL29003_ADC_PD;
+}
+
+static int isl29003_get_adc_value(struct i2c_client *client)
+{
+ struct isl29003_data *data = i2c_get_clientdata(client);
+ int lsb, msb, range, bitdepth;
+
+ mutex_lock(&data->lock);
+ lsb = i2c_smbus_read_byte_data(client, ISL29003_REG_LSB_SENSOR);
+
+ if (lsb < 0) {
+ mutex_unlock(&data->lock);
+ return lsb;
+ }
+
+ msb = i2c_smbus_read_byte_data(client, ISL29003_REG_MSB_SENSOR);
+ mutex_unlock(&data->lock);
+
+ if (msb < 0)
+ return msb;
+
+ range = isl29003_get_range(client);
+ bitdepth = (4 - isl29003_get_resolution(client)) * 4;
+ return (((msb << 8) | lsb) * gain_range[range]) >> bitdepth;
+}
+
+/*
+ * sysfs layer
+ */
+
+/* range */
+static ssize_t isl29003_show_range(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%i\n", isl29003_get_range(client));
+}
+
+static ssize_t isl29003_store_range(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3))
+ return -EINVAL;
+
+ ret = isl29003_set_range(client, val);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(range, S_IWUSR | S_IRUGO,
+ isl29003_show_range, isl29003_store_range);
+
+
+/* resolution */
+static ssize_t isl29003_show_resolution(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%d\n", isl29003_get_resolution(client));
+}
+
+static ssize_t isl29003_store_resolution(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3))
+ return -EINVAL;
+
+ ret = isl29003_set_resolution(client, val);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(resolution, S_IWUSR | S_IRUGO,
+ isl29003_show_resolution, isl29003_store_resolution);
+
+/* mode */
+static ssize_t isl29003_show_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%d\n", isl29003_get_mode(client));
+}
+
+static ssize_t isl29003_store_mode(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((strict_strtoul(buf, 10, &val) < 0) || (val > 2))
+ return -EINVAL;
+
+ ret = isl29003_set_mode(client, val);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO,
+ isl29003_show_mode, isl29003_store_mode);
+
+
+/* power state */
+static ssize_t isl29003_show_power_state(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%d\n", isl29003_get_power_state(client));
+}
+
+static ssize_t isl29003_store_power_state(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((strict_strtoul(buf, 10, &val) < 0) || (val > 1))
+ return -EINVAL;
+
+ ret = isl29003_set_power_state(client, val);
+ return ret ? ret : count;
+}
+
+static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
+ isl29003_show_power_state, isl29003_store_power_state);
+
+
+/* lux */
+static ssize_t isl29003_show_lux(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ /* No LUX data if not operational */
+ if (!isl29003_get_power_state(client))
+ return -EBUSY;
+
+ return sprintf(buf, "%d\n", isl29003_get_adc_value(client));
+}
+
+static DEVICE_ATTR(lux, S_IRUGO, isl29003_show_lux, NULL);
+
+static struct attribute *isl29003_attributes[] = {
+ &dev_attr_range.attr,
+ &dev_attr_resolution.attr,
+ &dev_attr_mode.attr,
+ &dev_attr_power_state.attr,
+ &dev_attr_lux.attr,
+ NULL
+};
+
+static const struct attribute_group isl29003_attr_group = {
+ .attrs = isl29003_attributes,
+};
+
+static int isl29003_init_client(struct i2c_client *client)
+{
+ struct isl29003_data *data = i2c_get_clientdata(client);
+ int i;
+
+ /* read all the registers once to fill the cache.
+ * if one of the reads fails, we consider the init failed */
+ for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) {
+ int v = i2c_smbus_read_byte_data(client, i);
+ if (v < 0)
+ return -ENODEV;
+
+ data->reg_cache[i] = v;
+ }
+
+ /* set defaults */
+ isl29003_set_range(client, 0);
+ isl29003_set_resolution(client, 0);
+ isl29003_set_mode(client, 0);
+ isl29003_set_power_state(client, 0);
+
+ return 0;
+}
+
+/*
+ * I2C layer
+ */
+
+static int __devinit isl29003_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ struct isl29003_data *data;
+ int err = 0;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
+ return -EIO;
+
+ data = kzalloc(sizeof(struct isl29003_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->client = client;
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->lock);
+
+ /* initialize the ISL29003 chip */
+ err = isl29003_init_client(client);
+ if (err)
+ goto exit_kfree;
+
+ /* register sysfs hooks */
+ err = sysfs_create_group(&client->dev.kobj, &isl29003_attr_group);
+ if (err)
+ goto exit_kfree;
+
+ dev_info(&client->dev, "driver version %s enabled\n", DRIVER_VERSION);
+ return 0;
+
+exit_kfree:
+ kfree(data);
+ return err;
+}
+
+static int __devexit isl29003_remove(struct i2c_client *client)
+{
+ sysfs_remove_group(&client->dev.kobj, &isl29003_attr_group);
+ isl29003_set_power_state(client, 0);
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int isl29003_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ return isl29003_set_power_state(client, 0);
+}
+
+static int isl29003_resume(struct i2c_client *client)
+{
+ int i;
+ struct isl29003_data *data = i2c_get_clientdata(client);
+
+ /* restore registers from cache */
+ for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++)
+ if (!i2c_smbus_write_byte_data(client, i, data->reg_cache[i]))
+ return -EIO;
+
+ return 0;
+}
+
+#else
+#define isl29003_suspend NULL
+#define isl29003_resume NULL
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id isl29003_id[] = {
+ { "isl29003", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, isl29003_id);
+
+static struct i2c_driver isl29003_driver = {
+ .driver = {
+ .name = ISL29003_DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .suspend = isl29003_suspend,
+ .resume = isl29003_resume,
+ .probe = isl29003_probe,
+ .remove = __devexit_p(isl29003_remove),
+ .id_table = isl29003_id,
+};
+
+static int __init isl29003_init(void)
+{
+ return i2c_add_driver(&isl29003_driver);
+}
+
+static void __exit isl29003_exit(void)
+{
+ i2c_del_driver(&isl29003_driver);
+}
+
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_DESCRIPTION("ISL29003 ambient light sensor driver");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(isl29003_init);
+module_exit(isl29003_exit);
+
diff --git a/drivers/misc/sgi-gru/Makefile b/drivers/misc/sgi-gru/Makefile
index 9e9170b3599a..bcd8136d2f98 100644
--- a/drivers/misc/sgi-gru/Makefile
+++ b/drivers/misc/sgi-gru/Makefile
@@ -3,5 +3,5 @@ ifdef CONFIG_SGI_GRU_DEBUG
endif
obj-$(CONFIG_SGI_GRU) := gru.o
-gru-y := grufile.o grumain.o grufault.o grutlbpurge.o gruprocfs.o grukservices.o
+gru-y := grufile.o grumain.o grufault.o grutlbpurge.o gruprocfs.o grukservices.o gruhandles.o
diff --git a/drivers/misc/sgi-gru/gru_instructions.h b/drivers/misc/sgi-gru/gru_instructions.h
index 48762e7b98be..3fde33c1e8f3 100644
--- a/drivers/misc/sgi-gru/gru_instructions.h
+++ b/drivers/misc/sgi-gru/gru_instructions.h
@@ -19,8 +19,11 @@
#ifndef __GRU_INSTRUCTIONS_H__
#define __GRU_INSTRUCTIONS_H__
-#define gru_flush_cache_hook(p)
-#define gru_emulator_wait_hook(p, w)
+extern int gru_check_status_proc(void *cb);
+extern int gru_wait_proc(void *cb);
+extern void gru_wait_abort_proc(void *cb);
+
+
/*
* Architecture dependent functions
@@ -29,16 +32,16 @@
#if defined(CONFIG_IA64)
#include <linux/compiler.h>
#include <asm/intrinsics.h>
-#define __flush_cache(p) ia64_fc(p)
+#define __flush_cache(p) ia64_fc((unsigned long)p)
/* Use volatile on IA64 to ensure ordering via st4.rel */
-#define gru_ordered_store_int(p,v) \
+#define gru_ordered_store_int(p, v) \
do { \
barrier(); \
*((volatile int *)(p)) = v; /* force st.rel */ \
} while (0)
#elif defined(CONFIG_X86_64)
#define __flush_cache(p) clflush(p)
-#define gru_ordered_store_int(p,v) \
+#define gru_ordered_store_int(p, v) \
do { \
barrier(); \
*(int *)p = v; \
@@ -558,20 +561,19 @@ extern int gru_get_cb_exception_detail(void *cb,
#define GRU_EXC_STR_SIZE 256
-extern int gru_check_status_proc(void *cb);
-extern int gru_wait_proc(void *cb);
-extern void gru_wait_abort_proc(void *cb);
/*
* Control block definition for checking status
*/
struct gru_control_block_status {
unsigned int icmd :1;
- unsigned int unused1 :31;
+ unsigned int ima :3;
+ unsigned int reserved0 :4;
+ unsigned int unused1 :24;
unsigned int unused2 :24;
unsigned int istatus :2;
unsigned int isubstatus :4;
- unsigned int inused3 :2;
+ unsigned int unused3 :2;
};
/* Get CB status */
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
index 3ee698ad8599..ab118558552e 100644
--- a/drivers/misc/sgi-gru/grufault.c
+++ b/drivers/misc/sgi-gru/grufault.c
@@ -32,6 +32,7 @@
#include <linux/device.h>
#include <linux/io.h>
#include <linux/uaccess.h>
+#include <linux/security.h>
#include <asm/pgtable.h>
#include "gru.h"
#include "grutables.h"
@@ -266,6 +267,44 @@ err:
return 1;
}
+static int gru_vtop(struct gru_thread_state *gts, unsigned long vaddr,
+ int write, int atomic, unsigned long *gpa, int *pageshift)
+{
+ struct mm_struct *mm = gts->ts_mm;
+ struct vm_area_struct *vma;
+ unsigned long paddr;
+ int ret, ps;
+
+ vma = find_vma(mm, vaddr);
+ if (!vma)
+ goto inval;
+
+ /*
+ * Atomic lookup is faster & usually works even if called in non-atomic
+ * context.
+ */
+ rmb(); /* Must/check ms_range_active before loading PTEs */
+ ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &ps);
+ if (ret) {
+ if (atomic)
+ goto upm;
+ if (non_atomic_pte_lookup(vma, vaddr, write, &paddr, &ps))
+ goto inval;
+ }
+ if (is_gru_paddr(paddr))
+ goto inval;
+ paddr = paddr & ~((1UL << ps) - 1);
+ *gpa = uv_soc_phys_ram_to_gpa(paddr);
+ *pageshift = ps;
+ return 0;
+
+inval:
+ return -1;
+upm:
+ return -2;
+}
+
+
/*
* Drop a TLB entry into the GRU. The fault is described by info in an TFH.
* Input:
@@ -280,10 +319,8 @@ static int gru_try_dropin(struct gru_thread_state *gts,
struct gru_tlb_fault_handle *tfh,
unsigned long __user *cb)
{
- struct mm_struct *mm = gts->ts_mm;
- struct vm_area_struct *vma;
- int pageshift, asid, write, ret;
- unsigned long paddr, gpa, vaddr;
+ int pageshift = 0, asid, write, ret, atomic = !cb;
+ unsigned long gpa = 0, vaddr = 0;
/*
* NOTE: The GRU contains magic hardware that eliminates races between
@@ -317,28 +354,19 @@ static int gru_try_dropin(struct gru_thread_state *gts,
if (atomic_read(&gts->ts_gms->ms_range_active))
goto failactive;
- vma = find_vma(mm, vaddr);
- if (!vma)
+ ret = gru_vtop(gts, vaddr, write, atomic, &gpa, &pageshift);
+ if (ret == -1)
goto failinval;
+ if (ret == -2)
+ goto failupm;
- /*
- * Atomic lookup is faster & usually works even if called in non-atomic
- * context.
- */
- rmb(); /* Must/check ms_range_active before loading PTEs */
- ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &pageshift);
- if (ret) {
- if (!cb)
+ if (!(gts->ts_sizeavail & GRU_SIZEAVAIL(pageshift))) {
+ gts->ts_sizeavail |= GRU_SIZEAVAIL(pageshift);
+ if (atomic || !gru_update_cch(gts, 0)) {
+ gts->ts_force_cch_reload = 1;
goto failupm;
- if (non_atomic_pte_lookup(vma, vaddr, write, &paddr,
- &pageshift))
- goto failinval;
+ }
}
- if (is_gru_paddr(paddr))
- goto failinval;
-
- paddr = paddr & ~((1UL << pageshift) - 1);
- gpa = uv_soc_phys_ram_to_gpa(paddr);
gru_cb_set_istatus_active(cb);
tfh_write_restart(tfh, gpa, GAA_RAM, vaddr, asid, write,
GRU_PAGESIZE(pageshift));
@@ -368,6 +396,7 @@ failupm:
failfmm:
/* FMM state on UPM call */
+ gru_flush_cache(tfh);
STAT(tlb_dropin_fail_fmm);
gru_dbg(grudev, "FAILED fmm tfh: 0x%p, state %d\n", tfh, tfh->state);
return 0;
@@ -448,6 +477,7 @@ irqreturn_t gru_intr(int irq, void *dev_id)
up_read(&gts->ts_mm->mmap_sem);
} else {
tfh_user_polling_mode(tfh);
+ STAT(intr_mm_lock_failed);
}
}
return IRQ_HANDLED;
@@ -497,10 +527,8 @@ int gru_handle_user_call_os(unsigned long cb)
if (!gts)
return -EINVAL;
- if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) {
- ret = -EINVAL;
+ if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE)
goto exit;
- }
/*
* If force_unload is set, the UPM TLB fault is phony. The task
@@ -508,6 +536,20 @@ int gru_handle_user_call_os(unsigned long cb)
* unload the context. The task will page fault and assign a new
* context.
*/
+ if (gts->ts_tgid_owner == current->tgid && gts->ts_blade >= 0 &&
+ gts->ts_blade != uv_numa_blade_id()) {
+ STAT(call_os_offnode_reference);
+ gts->ts_force_unload = 1;
+ }
+
+ /*
+ * CCH may contain stale data if ts_force_cch_reload is set.
+ */
+ if (gts->ts_gru && gts->ts_force_cch_reload) {
+ gru_update_cch(gts, 0);
+ gts->ts_force_cch_reload = 0;
+ }
+
ret = -EAGAIN;
cbrnum = thread_cbr_number(gts, ucbnum);
if (gts->ts_force_unload) {
@@ -541,11 +583,13 @@ int gru_get_exception_detail(unsigned long arg)
if (!gts)
return -EINVAL;
- if (gts->ts_gru) {
- ucbnum = get_cb_number((void *)excdet.cb);
+ ucbnum = get_cb_number((void *)excdet.cb);
+ if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) {
+ ret = -EINVAL;
+ } else if (gts->ts_gru) {
cbrnum = thread_cbr_number(gts, ucbnum);
cbe = get_cbe_by_index(gts->ts_gru, cbrnum);
- prefetchw(cbe); /* Harmless on hardware, required for emulator */
+ prefetchw(cbe);/* Harmless on hardware, required for emulator */
excdet.opc = cbe->opccpy;
excdet.exopc = cbe->exopccpy;
excdet.ecause = cbe->ecause;
@@ -567,6 +611,31 @@ int gru_get_exception_detail(unsigned long arg)
/*
* User request to unload a context. Content is saved for possible reload.
*/
+static int gru_unload_all_contexts(void)
+{
+ struct gru_thread_state *gts;
+ struct gru_state *gru;
+ int gid, ctxnum;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ foreach_gid(gid) {
+ gru = GID_TO_GRU(gid);
+ spin_lock(&gru->gs_lock);
+ for (ctxnum = 0; ctxnum < GRU_NUM_CCH; ctxnum++) {
+ gts = gru->gs_gts[ctxnum];
+ if (gts && mutex_trylock(&gts->ts_ctxlock)) {
+ spin_unlock(&gru->gs_lock);
+ gru_unload_context(gts, 1);
+ gru_unlock_gts(gts);
+ spin_lock(&gru->gs_lock);
+ }
+ }
+ spin_unlock(&gru->gs_lock);
+ }
+ return 0;
+}
+
int gru_user_unload_context(unsigned long arg)
{
struct gru_thread_state *gts;
@@ -578,6 +647,9 @@ int gru_user_unload_context(unsigned long arg)
gru_dbg(grudev, "gseg 0x%lx\n", req.gseg);
+ if (!req.gseg)
+ return gru_unload_all_contexts();
+
gts = gru_find_lock_gts(req.gseg);
if (!gts)
return -EINVAL;
@@ -609,7 +681,7 @@ int gru_user_flush_tlb(unsigned long arg)
if (!gts)
return -EINVAL;
- gru_flush_tlb_range(gts->ts_gms, req.vaddr, req.vaddr + req.len);
+ gru_flush_tlb_range(gts->ts_gms, req.vaddr, req.len);
gru_unlock_gts(gts);
return 0;
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index c67e4e8bd62c..3e6e42d2f01b 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -45,7 +45,9 @@
#include <asm/uv/uv_mmrs.h>
struct gru_blade_state *gru_base[GRU_MAX_BLADES] __read_mostly;
-unsigned long gru_start_paddr, gru_end_paddr __read_mostly;
+unsigned long gru_start_paddr __read_mostly;
+unsigned long gru_end_paddr __read_mostly;
+unsigned int gru_max_gids __read_mostly;
struct gru_stats_s gru_stats;
/* Guaranteed user available resources on each node */
@@ -101,7 +103,7 @@ static int gru_file_mmap(struct file *file, struct vm_area_struct *vma)
return -EPERM;
if (vma->vm_start & (GRU_GSEG_PAGESIZE - 1) ||
- vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
+ vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
return -EINVAL;
vma->vm_flags |=
@@ -273,8 +275,11 @@ static void gru_init_chiplet(struct gru_state *gru, unsigned long paddr,
gru->gs_blade_id = bid;
gru->gs_cbr_map = (GRU_CBR_AU == 64) ? ~0 : (1UL << GRU_CBR_AU) - 1;
gru->gs_dsr_map = (1UL << GRU_DSR_AU) - 1;
+ gru->gs_asid_limit = MAX_ASID;
gru_tgh_flush_init(gru);
- gru_dbg(grudev, "bid %d, nid %d, gru %x, vaddr %p (0x%lx)\n",
+ if (gru->gs_gid >= gru_max_gids)
+ gru_max_gids = gru->gs_gid + 1;
+ gru_dbg(grudev, "bid %d, nid %d, gid %d, vaddr %p (0x%lx)\n",
bid, nid, gru->gs_gid, gru->gs_gru_base_vaddr,
gru->gs_gru_base_paddr);
gru_kservices_init(gru);
@@ -295,7 +300,7 @@ static int gru_init_tables(unsigned long gru_base_paddr, void *gru_base_vaddr)
for_each_online_node(nid) {
bid = uv_node_to_blade_id(nid);
pnode = uv_node_to_pnode(nid);
- if (gru_base[bid])
+ if (bid < 0 || gru_base[bid])
continue;
page = alloc_pages_node(nid, GFP_KERNEL, order);
if (!page)
@@ -308,11 +313,11 @@ static int gru_init_tables(unsigned long gru_base_paddr, void *gru_base_vaddr)
dsrbytes = 0;
cbrs = 0;
for (gru = gru_base[bid]->bs_grus, chip = 0;
- chip < GRU_CHIPLETS_PER_BLADE;
+ chip < GRU_CHIPLETS_PER_BLADE;
chip++, gru++) {
paddr = gru_chiplet_paddr(gru_base_paddr, pnode, chip);
vaddr = gru_chiplet_vaddr(gru_base_vaddr, pnode, chip);
- gru_init_chiplet(gru, paddr, vaddr, bid, nid, chip);
+ gru_init_chiplet(gru, paddr, vaddr, nid, bid, chip);
n = hweight64(gru->gs_cbr_map) * GRU_CBR_AU_SIZE;
cbrs = max(cbrs, n);
n = hweight64(gru->gs_dsr_map) * GRU_DSR_AU_BYTES;
@@ -370,26 +375,26 @@ static int __init gru_init(void)
void *gru_start_vaddr;
if (!is_uv_system())
- return 0;
+ return -ENODEV;
#if defined CONFIG_IA64
gru_start_paddr = 0xd000000000UL; /* ZZZZZZZZZZZZZZZZZZZ fixme */
#else
gru_start_paddr = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR) &
0x7fffffffffffUL;
-
#endif
gru_start_vaddr = __va(gru_start_paddr);
- gru_end_paddr = gru_start_paddr + MAX_NUMNODES * GRU_SIZE;
+ gru_end_paddr = gru_start_paddr + GRU_MAX_BLADES * GRU_SIZE;
printk(KERN_INFO "GRU space: 0x%lx - 0x%lx\n",
gru_start_paddr, gru_end_paddr);
irq = get_base_irq();
for (chip = 0; chip < GRU_CHIPLETS_PER_BLADE; chip++) {
ret = request_irq(irq + chip, gru_intr, 0, id, NULL);
- /* TODO: fix irq handling on x86. For now ignore failures because
+ /* TODO: fix irq handling on x86. For now ignore failure because
* interrupts are not required & not yet fully supported */
if (ret) {
- printk("!!!WARNING: GRU ignoring request failure!!!\n");
+ printk(KERN_WARNING
+ "!!!WARNING: GRU ignoring request failure!!!\n");
ret = 0;
}
if (ret) {
@@ -435,7 +440,7 @@ exit1:
static void __exit gru_exit(void)
{
- int i, bid;
+ int i, bid, gid;
int order = get_order(sizeof(struct gru_state) *
GRU_CHIPLETS_PER_BLADE);
@@ -445,6 +450,9 @@ static void __exit gru_exit(void)
for (i = 0; i < GRU_CHIPLETS_PER_BLADE; i++)
free_irq(IRQ_GRU + i, NULL);
+ foreach_gid(gid)
+ gru_kservices_exit(GID_TO_GRU(gid));
+
for (bid = 0; bid < GRU_MAX_BLADES; bid++)
free_pages((unsigned long)gru_base[bid], order);
@@ -469,7 +477,11 @@ struct vm_operations_struct gru_vm_ops = {
.fault = gru_fault,
};
+#ifndef MODULE
fs_initcall(gru_init);
+#else
+module_init(gru_init);
+#endif
module_exit(gru_exit);
module_param(gru_options, ulong, 0644);
diff --git a/drivers/misc/sgi-gru/gruhandles.c b/drivers/misc/sgi-gru/gruhandles.c
new file mode 100644
index 000000000000..9b7ccb328697
--- /dev/null
+++ b/drivers/misc/sgi-gru/gruhandles.c
@@ -0,0 +1,183 @@
+/*
+ * GRU KERNEL MCS INSTRUCTIONS
+ *
+ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include "gru.h"
+#include "grulib.h"
+#include "grutables.h"
+
+/* 10 sec */
+#ifdef CONFIG_IA64
+#include <asm/processor.h>
+#define GRU_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10)
+#else
+#include <asm/tsc.h>
+#define GRU_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
+#endif
+
+/* Extract the status field from a kernel handle */
+#define GET_MSEG_HANDLE_STATUS(h) (((*(unsigned long *)(h)) >> 16) & 3)
+
+struct mcs_op_statistic mcs_op_statistics[mcsop_last];
+
+static void update_mcs_stats(enum mcs_op op, unsigned long clks)
+{
+ atomic_long_inc(&mcs_op_statistics[op].count);
+ atomic_long_add(clks, &mcs_op_statistics[op].total);
+ if (mcs_op_statistics[op].max < clks)
+ mcs_op_statistics[op].max = clks;
+}
+
+static void start_instruction(void *h)
+{
+ unsigned long *w0 = h;
+
+ wmb(); /* setting CMD bit must be last */
+ *w0 = *w0 | 1;
+ gru_flush_cache(h);
+}
+
+static int wait_instruction_complete(void *h, enum mcs_op opc)
+{
+ int status;
+ cycles_t start_time = get_cycles();
+
+ while (1) {
+ cpu_relax();
+ status = GET_MSEG_HANDLE_STATUS(h);
+ if (status != CCHSTATUS_ACTIVE)
+ break;
+ if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time))
+ panic("GRU %p is malfunctioning\n", h);
+ }
+ if (gru_options & OPT_STATS)
+ update_mcs_stats(opc, get_cycles() - start_time);
+ return status;
+}
+
+int cch_allocate(struct gru_context_configuration_handle *cch,
+ int asidval, int sizeavail, unsigned long cbrmap,
+ unsigned long dsrmap)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ cch->asid[i] = (asidval++);
+ cch->sizeavail[i] = sizeavail;
+ }
+ cch->dsr_allocation_map = dsrmap;
+ cch->cbr_allocation_map = cbrmap;
+ cch->opc = CCHOP_ALLOCATE;
+ start_instruction(cch);
+ return wait_instruction_complete(cch, cchop_allocate);
+}
+
+int cch_start(struct gru_context_configuration_handle *cch)
+{
+ cch->opc = CCHOP_START;
+ start_instruction(cch);
+ return wait_instruction_complete(cch, cchop_start);
+}
+
+int cch_interrupt(struct gru_context_configuration_handle *cch)
+{
+ cch->opc = CCHOP_INTERRUPT;
+ start_instruction(cch);
+ return wait_instruction_complete(cch, cchop_interrupt);
+}
+
+int cch_deallocate(struct gru_context_configuration_handle *cch)
+{
+ cch->opc = CCHOP_DEALLOCATE;
+ start_instruction(cch);
+ return wait_instruction_complete(cch, cchop_deallocate);
+}
+
+int cch_interrupt_sync(struct gru_context_configuration_handle
+ *cch)
+{
+ cch->opc = CCHOP_INTERRUPT_SYNC;
+ start_instruction(cch);
+ return wait_instruction_complete(cch, cchop_interrupt_sync);
+}
+
+int tgh_invalidate(struct gru_tlb_global_handle *tgh,
+ unsigned long vaddr, unsigned long vaddrmask,
+ int asid, int pagesize, int global, int n,
+ unsigned short ctxbitmap)
+{
+ tgh->vaddr = vaddr;
+ tgh->asid = asid;
+ tgh->pagesize = pagesize;
+ tgh->n = n;
+ tgh->global = global;
+ tgh->vaddrmask = vaddrmask;
+ tgh->ctxbitmap = ctxbitmap;
+ tgh->opc = TGHOP_TLBINV;
+ start_instruction(tgh);
+ return wait_instruction_complete(tgh, tghop_invalidate);
+}
+
+void tfh_write_only(struct gru_tlb_fault_handle *tfh,
+ unsigned long pfn, unsigned long vaddr,
+ int asid, int dirty, int pagesize)
+{
+ tfh->fillasid = asid;
+ tfh->fillvaddr = vaddr;
+ tfh->pfn = pfn;
+ tfh->dirty = dirty;
+ tfh->pagesize = pagesize;
+ tfh->opc = TFHOP_WRITE_ONLY;
+ start_instruction(tfh);
+}
+
+void tfh_write_restart(struct gru_tlb_fault_handle *tfh,
+ unsigned long paddr, int gaa,
+ unsigned long vaddr, int asid, int dirty,
+ int pagesize)
+{
+ tfh->fillasid = asid;
+ tfh->fillvaddr = vaddr;
+ tfh->pfn = paddr >> GRU_PADDR_SHIFT;
+ tfh->gaa = gaa;
+ tfh->dirty = dirty;
+ tfh->pagesize = pagesize;
+ tfh->opc = TFHOP_WRITE_RESTART;
+ start_instruction(tfh);
+}
+
+void tfh_restart(struct gru_tlb_fault_handle *tfh)
+{
+ tfh->opc = TFHOP_RESTART;
+ start_instruction(tfh);
+}
+
+void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh)
+{
+ tfh->opc = TFHOP_USER_POLLING_MODE;
+ start_instruction(tfh);
+}
+
+void tfh_exception(struct gru_tlb_fault_handle *tfh)
+{
+ tfh->opc = TFHOP_EXCEPTION;
+ start_instruction(tfh);
+}
+
diff --git a/drivers/misc/sgi-gru/gruhandles.h b/drivers/misc/sgi-gru/gruhandles.h
index b63018d60fe1..1ed74d7508c8 100644
--- a/drivers/misc/sgi-gru/gruhandles.h
+++ b/drivers/misc/sgi-gru/gruhandles.h
@@ -489,170 +489,28 @@ enum gru_cbr_state {
* 64m 26 8
* ...
*/
-#define GRU_PAGESIZE(sh) ((((sh) > 20 ? (sh) + 2: (sh)) >> 1) - 6)
+#define GRU_PAGESIZE(sh) ((((sh) > 20 ? (sh) + 2 : (sh)) >> 1) - 6)
#define GRU_SIZEAVAIL(sh) (1UL << GRU_PAGESIZE(sh))
/* minimum TLB purge count to ensure a full purge */
#define GRUMAXINVAL 1024UL
-
-/* Extract the status field from a kernel handle */
-#define GET_MSEG_HANDLE_STATUS(h) (((*(unsigned long *)(h)) >> 16) & 3)
-
-static inline void start_instruction(void *h)
-{
- unsigned long *w0 = h;
-
- wmb(); /* setting CMD bit must be last */
- *w0 = *w0 | 1;
- gru_flush_cache(h);
-}
-
-static inline int wait_instruction_complete(void *h)
-{
- int status;
-
- do {
- cpu_relax();
- barrier();
- status = GET_MSEG_HANDLE_STATUS(h);
- } while (status == CCHSTATUS_ACTIVE);
- return status;
-}
-
-#if defined CONFIG_IA64
-static inline void cch_allocate_set_asids(
- struct gru_context_configuration_handle *cch, int asidval)
-{
- int i;
-
- for (i = 0; i <= RGN_HPAGE; i++) { /* assume HPAGE is last region */
- cch->asid[i] = (asidval++);
-#if 0
- /* ZZZ hugepages not supported yet */
- if (i == RGN_HPAGE)
- cch->sizeavail[i] = GRU_SIZEAVAIL(hpage_shift);
- else
-#endif
- cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT);
- }
-}
-#elif defined CONFIG_X86_64
-static inline void cch_allocate_set_asids(
- struct gru_context_configuration_handle *cch, int asidval)
-{
- int i;
-
- for (i = 0; i < 8; i++) {
- cch->asid[i] = asidval++;
- cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT) |
- GRU_SIZEAVAIL(21);
- }
-}
-#endif
-
-static inline int cch_allocate(struct gru_context_configuration_handle *cch,
- int asidval, unsigned long cbrmap,
- unsigned long dsrmap)
-{
- cch_allocate_set_asids(cch, asidval);
- cch->dsr_allocation_map = dsrmap;
- cch->cbr_allocation_map = cbrmap;
- cch->opc = CCHOP_ALLOCATE;
- start_instruction(cch);
- return wait_instruction_complete(cch);
-}
-
-static inline int cch_start(struct gru_context_configuration_handle *cch)
-{
- cch->opc = CCHOP_START;
- start_instruction(cch);
- return wait_instruction_complete(cch);
-}
-
-static inline int cch_interrupt(struct gru_context_configuration_handle *cch)
-{
- cch->opc = CCHOP_INTERRUPT;
- start_instruction(cch);
- return wait_instruction_complete(cch);
-}
-
-static inline int cch_deallocate(struct gru_context_configuration_handle *cch)
-{
- cch->opc = CCHOP_DEALLOCATE;
- start_instruction(cch);
- return wait_instruction_complete(cch);
-}
-
-static inline int cch_interrupt_sync(struct gru_context_configuration_handle
- *cch)
-{
- cch->opc = CCHOP_INTERRUPT_SYNC;
- start_instruction(cch);
- return wait_instruction_complete(cch);
-}
-
-static inline int tgh_invalidate(struct gru_tlb_global_handle *tgh,
- unsigned long vaddr, unsigned long vaddrmask,
- int asid, int pagesize, int global, int n,
- unsigned short ctxbitmap)
-{
- tgh->vaddr = vaddr;
- tgh->asid = asid;
- tgh->pagesize = pagesize;
- tgh->n = n;
- tgh->global = global;
- tgh->vaddrmask = vaddrmask;
- tgh->ctxbitmap = ctxbitmap;
- tgh->opc = TGHOP_TLBINV;
- start_instruction(tgh);
- return wait_instruction_complete(tgh);
-}
-
-static inline void tfh_write_only(struct gru_tlb_fault_handle *tfh,
- unsigned long pfn, unsigned long vaddr,
- int asid, int dirty, int pagesize)
-{
- tfh->fillasid = asid;
- tfh->fillvaddr = vaddr;
- tfh->pfn = pfn;
- tfh->dirty = dirty;
- tfh->pagesize = pagesize;
- tfh->opc = TFHOP_WRITE_ONLY;
- start_instruction(tfh);
-}
-
-static inline void tfh_write_restart(struct gru_tlb_fault_handle *tfh,
- unsigned long paddr, int gaa,
- unsigned long vaddr, int asid, int dirty,
- int pagesize)
-{
- tfh->fillasid = asid;
- tfh->fillvaddr = vaddr;
- tfh->pfn = paddr >> GRU_PADDR_SHIFT;
- tfh->gaa = gaa;
- tfh->dirty = dirty;
- tfh->pagesize = pagesize;
- tfh->opc = TFHOP_WRITE_RESTART;
- start_instruction(tfh);
-}
-
-static inline void tfh_restart(struct gru_tlb_fault_handle *tfh)
-{
- tfh->opc = TFHOP_RESTART;
- start_instruction(tfh);
-}
-
-static inline void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh)
-{
- tfh->opc = TFHOP_USER_POLLING_MODE;
- start_instruction(tfh);
-}
-
-static inline void tfh_exception(struct gru_tlb_fault_handle *tfh)
-{
- tfh->opc = TFHOP_EXCEPTION;
- start_instruction(tfh);
-}
+int cch_allocate(struct gru_context_configuration_handle *cch,
+ int asidval, int sizeavail, unsigned long cbrmap, unsigned long dsrmap);
+
+int cch_start(struct gru_context_configuration_handle *cch);
+int cch_interrupt(struct gru_context_configuration_handle *cch);
+int cch_deallocate(struct gru_context_configuration_handle *cch);
+int cch_interrupt_sync(struct gru_context_configuration_handle *cch);
+int tgh_invalidate(struct gru_tlb_global_handle *tgh, unsigned long vaddr,
+ unsigned long vaddrmask, int asid, int pagesize, int global, int n,
+ unsigned short ctxbitmap);
+void tfh_write_only(struct gru_tlb_fault_handle *tfh, unsigned long pfn,
+ unsigned long vaddr, int asid, int dirty, int pagesize);
+void tfh_write_restart(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
+ int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
+void tfh_restart(struct gru_tlb_fault_handle *tfh);
+void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh);
+void tfh_exception(struct gru_tlb_fault_handle *tfh);
#endif /* __GRUHANDLES_H__ */
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c
index 880c55dfb662..d8bd7d84a7cf 100644
--- a/drivers/misc/sgi-gru/grukservices.c
+++ b/drivers/misc/sgi-gru/grukservices.c
@@ -52,8 +52,10 @@
*/
/* Blade percpu resources PERMANENTLY reserved for kernel use */
-#define GRU_NUM_KERNEL_CBR 1
+#define GRU_NUM_KERNEL_CBR 1
#define GRU_NUM_KERNEL_DSR_BYTES 256
+#define GRU_NUM_KERNEL_DSR_CL (GRU_NUM_KERNEL_DSR_BYTES / \
+ GRU_CACHE_LINE_BYTES)
#define KERNEL_CTXNUM 15
/* GRU instruction attributes for all instructions */
@@ -94,7 +96,6 @@ struct message_header {
char fill;
};
-#define QLINES(mq) ((mq) + offsetof(struct message_queue, qlines))
#define HSTATUS(mq, h) ((mq) + offsetof(struct message_queue, hstatus[h]))
static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr)
@@ -122,7 +123,7 @@ int gru_get_cb_exception_detail(void *cb,
struct gru_control_block_extended *cbe;
cbe = get_cbe(GRUBASE(cb), get_cb_number(cb));
- prefetchw(cbe); /* Harmless on hardware, required for emulator */
+ prefetchw(cbe); /* Harmless on hardware, required for emulator */
excdet->opc = cbe->opccpy;
excdet->exopc = cbe->exopccpy;
excdet->ecause = cbe->ecause;
@@ -250,7 +251,8 @@ static inline void restore_present2(void *p, int val)
* Create a message queue.
* qlines - message queue size in cache lines. Includes 2-line header.
*/
-int gru_create_message_queue(void *p, unsigned int bytes)
+int gru_create_message_queue(struct gru_message_queue_desc *mqd,
+ void *p, unsigned int bytes, int nasid, int vector, int apicid)
{
struct message_queue *mq = p;
unsigned int qlines;
@@ -265,6 +267,12 @@ int gru_create_message_queue(void *p, unsigned int bytes)
mq->hstatus[0] = 0;
mq->hstatus[1] = 1;
mq->head = gru_mesq_head(2, qlines / 2 + 1);
+ mqd->mq = mq;
+ mqd->mq_gpa = uv_gpa(mq);
+ mqd->qlines = qlines;
+ mqd->interrupt_pnode = UV_NASID_TO_PNODE(nasid);
+ mqd->interrupt_vector = vector;
+ mqd->interrupt_apicid = apicid;
return 0;
}
EXPORT_SYMBOL_GPL(gru_create_message_queue);
@@ -277,8 +285,8 @@ EXPORT_SYMBOL_GPL(gru_create_message_queue);
* -1 - if mesq sent successfully but queue not full
* >0 - unexpected error. MQE_xxx returned
*/
-static int send_noop_message(void *cb,
- unsigned long mq, void *mesg)
+static int send_noop_message(void *cb, struct gru_message_queue_desc *mqd,
+ void *mesg)
{
const struct message_header noop_header = {
.present = MQS_NOOP, .lines = 1};
@@ -289,7 +297,7 @@ static int send_noop_message(void *cb,
STAT(mesq_noop);
save_mhdr = *mhdr;
*mhdr = noop_header;
- gru_mesq(cb, mq, gru_get_tri(mhdr), 1, IMA);
+ gru_mesq(cb, mqd->mq_gpa, gru_get_tri(mhdr), 1, IMA);
ret = gru_wait(cb);
if (ret) {
@@ -313,7 +321,7 @@ static int send_noop_message(void *cb,
break;
case CBSS_PUT_NACKED:
STAT(mesq_noop_put_nacked);
- m = mq + (gru_get_amo_value_head(cb) << 6);
+ m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, 1, 1,
IMA);
if (gru_wait(cb) == CBS_IDLE)
@@ -333,30 +341,20 @@ static int send_noop_message(void *cb,
/*
* Handle a gru_mesq full.
*/
-static int send_message_queue_full(void *cb,
- unsigned long mq, void *mesg, int lines)
+static int send_message_queue_full(void *cb, struct gru_message_queue_desc *mqd,
+ void *mesg, int lines)
{
union gru_mesqhead mqh;
unsigned int limit, head;
unsigned long avalue;
- int half, qlines, save;
+ int half, qlines;
/* Determine if switching to first/second half of q */
avalue = gru_get_amo_value(cb);
head = gru_get_amo_value_head(cb);
limit = gru_get_amo_value_limit(cb);
- /*
- * Fetch "qlines" from the queue header. Since the queue may be
- * in memory that can't be accessed using socket addresses, use
- * the GRU to access the data. Use DSR space from the message.
- */
- save = *(int *)mesg;
- gru_vload(cb, QLINES(mq), gru_get_tri(mesg), XTYPE_W, 1, 1, IMA);
- if (gru_wait(cb) != CBS_IDLE)
- goto cberr;
- qlines = *(int *)mesg;
- *(int *)mesg = save;
+ qlines = mqd->qlines;
half = (limit != qlines);
if (half)
@@ -365,7 +363,7 @@ static int send_message_queue_full(void *cb,
mqh = gru_mesq_head(2, qlines / 2 + 1);
/* Try to get lock for switching head pointer */
- gru_gamir(cb, EOP_IR_CLR, HSTATUS(mq, half), XTYPE_DW, IMA);
+ gru_gamir(cb, EOP_IR_CLR, HSTATUS(mqd->mq_gpa, half), XTYPE_DW, IMA);
if (gru_wait(cb) != CBS_IDLE)
goto cberr;
if (!gru_get_amo_value(cb)) {
@@ -375,8 +373,8 @@ static int send_message_queue_full(void *cb,
/* Got the lock. Send optional NOP if queue not full, */
if (head != limit) {
- if (send_noop_message(cb, mq, mesg)) {
- gru_gamir(cb, EOP_IR_INC, HSTATUS(mq, half),
+ if (send_noop_message(cb, mqd, mesg)) {
+ gru_gamir(cb, EOP_IR_INC, HSTATUS(mqd->mq_gpa, half),
XTYPE_DW, IMA);
if (gru_wait(cb) != CBS_IDLE)
goto cberr;
@@ -387,14 +385,16 @@ static int send_message_queue_full(void *cb,
}
/* Then flip queuehead to other half of queue. */
- gru_gamer(cb, EOP_ERR_CSWAP, mq, XTYPE_DW, mqh.val, avalue, IMA);
+ gru_gamer(cb, EOP_ERR_CSWAP, mqd->mq_gpa, XTYPE_DW, mqh.val, avalue,
+ IMA);
if (gru_wait(cb) != CBS_IDLE)
goto cberr;
/* If not successfully in swapping queue head, clear the hstatus lock */
if (gru_get_amo_value(cb) != avalue) {
STAT(mesq_qf_switch_head_failed);
- gru_gamir(cb, EOP_IR_INC, HSTATUS(mq, half), XTYPE_DW, IMA);
+ gru_gamir(cb, EOP_IR_INC, HSTATUS(mqd->mq_gpa, half), XTYPE_DW,
+ IMA);
if (gru_wait(cb) != CBS_IDLE)
goto cberr;
}
@@ -404,15 +404,25 @@ cberr:
return MQE_UNEXPECTED_CB_ERR;
}
+/*
+ * Send a cross-partition interrupt to the SSI that contains the target
+ * message queue. Normally, the interrupt is automatically delivered by hardware
+ * but some error conditions require explicit delivery.
+ */
+static void send_message_queue_interrupt(struct gru_message_queue_desc *mqd)
+{
+ if (mqd->interrupt_vector)
+ uv_hub_send_ipi(mqd->interrupt_pnode, mqd->interrupt_apicid,
+ mqd->interrupt_vector);
+}
+
/*
* Handle a gru_mesq failure. Some of these failures are software recoverable
* or retryable.
*/
-static int send_message_failure(void *cb,
- unsigned long mq,
- void *mesg,
- int lines)
+static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd,
+ void *mesg, int lines)
{
int substatus, ret = 0;
unsigned long m;
@@ -429,7 +439,7 @@ static int send_message_failure(void *cb,
break;
case CBSS_QLIMIT_REACHED:
STAT(mesq_send_qlimit_reached);
- ret = send_message_queue_full(cb, mq, mesg, lines);
+ ret = send_message_queue_full(cb, mqd, mesg, lines);
break;
case CBSS_AMO_NACKED:
STAT(mesq_send_amo_nacked);
@@ -437,12 +447,14 @@ static int send_message_failure(void *cb,
break;
case CBSS_PUT_NACKED:
STAT(mesq_send_put_nacked);
- m =mq + (gru_get_amo_value_head(cb) << 6);
+ m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, lines, 1, IMA);
- if (gru_wait(cb) == CBS_IDLE)
+ if (gru_wait(cb) == CBS_IDLE) {
ret = MQE_OK;
- else
+ send_message_queue_interrupt(mqd);
+ } else {
ret = MQE_UNEXPECTED_CB_ERR;
+ }
break;
default:
BUG();
@@ -452,12 +464,12 @@ static int send_message_failure(void *cb,
/*
* Send a message to a message queue
- * cb GRU control block to use to send message
- * mq message queue
+ * mqd message queue descriptor
* mesg message. ust be vaddr within a GSEG
* bytes message size (<= 2 CL)
*/
-int gru_send_message_gpa(unsigned long mq, void *mesg, unsigned int bytes)
+int gru_send_message_gpa(struct gru_message_queue_desc *mqd, void *mesg,
+ unsigned int bytes)
{
struct message_header *mhdr;
void *cb;
@@ -481,10 +493,10 @@ int gru_send_message_gpa(unsigned long mq, void *mesg, unsigned int bytes)
do {
ret = MQE_OK;
- gru_mesq(cb, mq, gru_get_tri(mhdr), clines, IMA);
+ gru_mesq(cb, mqd->mq_gpa, gru_get_tri(mhdr), clines, IMA);
istatus = gru_wait(cb);
if (istatus != CBS_IDLE)
- ret = send_message_failure(cb, mq, dsr, clines);
+ ret = send_message_failure(cb, mqd, dsr, clines);
} while (ret == MQIE_AGAIN);
gru_free_cpu_resources(cb, dsr);
@@ -497,9 +509,9 @@ EXPORT_SYMBOL_GPL(gru_send_message_gpa);
/*
* Advance the receive pointer for the queue to the next message.
*/
-void gru_free_message(void *rmq, void *mesg)
+void gru_free_message(struct gru_message_queue_desc *mqd, void *mesg)
{
- struct message_queue *mq = rmq;
+ struct message_queue *mq = mqd->mq;
struct message_header *mhdr = mq->next;
void *next, *pnext;
int half = -1;
@@ -529,16 +541,16 @@ EXPORT_SYMBOL_GPL(gru_free_message);
* present. User must call next_message() to move to next message.
* rmq message queue
*/
-void *gru_get_next_message(void *rmq)
+void *gru_get_next_message(struct gru_message_queue_desc *mqd)
{
- struct message_queue *mq = rmq;
+ struct message_queue *mq = mqd->mq;
struct message_header *mhdr = mq->next;
int present = mhdr->present;
/* skip NOOP messages */
STAT(mesq_receive);
while (present == MQS_NOOP) {
- gru_free_message(rmq, mhdr);
+ gru_free_message(mqd, mhdr);
mhdr = mq->next;
present = mhdr->present;
}
@@ -576,7 +588,7 @@ int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa,
if (gru_get_cpu_resources(GRU_NUM_KERNEL_DSR_BYTES, &cb, &dsr))
return MQE_BUG_NO_RESOURCES;
gru_bcopy(cb, src_gpa, dest_gpa, gru_get_tri(dsr),
- XTYPE_B, bytes, GRU_NUM_KERNEL_DSR_BYTES, IMA);
+ XTYPE_B, bytes, GRU_NUM_KERNEL_DSR_CL, IMA);
ret = gru_wait(cb);
gru_free_cpu_resources(cb, dsr);
return ret;
@@ -611,7 +623,7 @@ static int quicktest(struct gru_state *gru)
if (word0 != word1 || word0 != MAGIC) {
printk
- ("GRU quicktest err: gru %d, found 0x%lx, expected 0x%lx\n",
+ ("GRU quicktest err: gid %d, found 0x%lx, expected 0x%lx\n",
gru->gs_gid, word1, MAGIC);
BUG(); /* ZZZ should not be fatal */
}
@@ -660,15 +672,15 @@ int gru_kservices_init(struct gru_state *gru)
cch->tlb_int_enable = 0;
cch->tfm_done_bit_enable = 0;
cch->unmap_enable = 1;
- err = cch_allocate(cch, 0, cbr_map, dsr_map);
+ err = cch_allocate(cch, 0, 0, cbr_map, dsr_map);
if (err) {
gru_dbg(grudev,
- "Unable to allocate kernel CCH: gru %d, err %d\n",
+ "Unable to allocate kernel CCH: gid %d, err %d\n",
gru->gs_gid, err);
BUG();
}
if (cch_start(cch)) {
- gru_dbg(grudev, "Unable to start kernel CCH: gru %d, err %d\n",
+ gru_dbg(grudev, "Unable to start kernel CCH: gid %d, err %d\n",
gru->gs_gid, err);
BUG();
}
@@ -678,3 +690,22 @@ int gru_kservices_init(struct gru_state *gru)
quicktest(gru);
return 0;
}
+
+void gru_kservices_exit(struct gru_state *gru)
+{
+ struct gru_context_configuration_handle *cch;
+ struct gru_blade_state *bs;
+
+ bs = gru->gs_blade;
+ if (gru != &bs->bs_grus[1])
+ return;
+
+ cch = get_cch(gru->gs_gru_base_vaddr, KERNEL_CTXNUM);
+ lock_cch_handle(cch);
+ if (cch_interrupt_sync(cch))
+ BUG();
+ if (cch_deallocate(cch))
+ BUG();
+ unlock_cch_handle(cch);
+}
+
diff --git a/drivers/misc/sgi-gru/grukservices.h b/drivers/misc/sgi-gru/grukservices.h
index eb17e0a3ac61..747ed315d56f 100644
--- a/drivers/misc/sgi-gru/grukservices.h
+++ b/drivers/misc/sgi-gru/grukservices.h
@@ -41,6 +41,15 @@
* - gru_create_message_queue() needs interrupt vector info
*/
+struct gru_message_queue_desc {
+ void *mq; /* message queue vaddress */
+ unsigned long mq_gpa; /* global address of mq */
+ int qlines; /* queue size in CL */
+ int interrupt_vector; /* interrupt vector */
+ int interrupt_pnode; /* pnode for interrupt */
+ int interrupt_apicid; /* lapicid for interrupt */
+};
+
/*
* Initialize a user allocated chunk of memory to be used as
* a message queue. The caller must ensure that the queue is
@@ -51,14 +60,19 @@
* to manage the queue.
*
* Input:
- * p pointer to user allocated memory.
+ * mqd pointer to message queue descriptor
+ * p pointer to user allocated mesq memory.
* bytes size of message queue in bytes
+ * vector interrupt vector (zero if no interrupts)
+ * nasid nasid of blade where interrupt is delivered
+ * apicid apicid of cpu for interrupt
*
* Errors:
* 0 OK
* >0 error
*/
-extern int gru_create_message_queue(void *p, unsigned int bytes);
+extern int gru_create_message_queue(struct gru_message_queue_desc *mqd,
+ void *p, unsigned int bytes, int nasid, int vector, int apicid);
/*
* Send a message to a message queue.
@@ -68,7 +82,7 @@ extern int gru_create_message_queue(void *p, unsigned int bytes);
*
*
* Input:
- * xmq message queue - must be a UV global physical address
+ * mqd pointer to message queue descriptor
* mesg pointer to message. Must be 64-bit aligned
* bytes size of message in bytes
*
@@ -77,8 +91,8 @@ extern int gru_create_message_queue(void *p, unsigned int bytes);
* >0 Send failure - see error codes below
*
*/
-extern int gru_send_message_gpa(unsigned long mq_gpa, void *mesg,
- unsigned int bytes);
+extern int gru_send_message_gpa(struct gru_message_queue_desc *mqd,
+ void *mesg, unsigned int bytes);
/* Status values for gru_send_message() */
#define MQE_OK 0 /* message sent successfully */
@@ -94,10 +108,11 @@ extern int gru_send_message_gpa(unsigned long mq_gpa, void *mesg,
* API extensions may allow for out-of-order freeing.
*
* Input
- * mq message queue
+ * mqd pointer to message queue descriptor
* mesq message being freed
*/
-extern void gru_free_message(void *mq, void *mesq);
+extern void gru_free_message(struct gru_message_queue_desc *mqd,
+ void *mesq);
/*
* Get next message from message queue. Returns pointer to
@@ -106,13 +121,13 @@ extern void gru_free_message(void *mq, void *mesq);
* in order to move the queue pointers to next message.
*
* Input
- * mq message queue
+ * mqd pointer to message queue descriptor
*
* Output:
* p pointer to message
* NULL no message available
*/
-extern void *gru_get_next_message(void *mq);
+extern void *gru_get_next_message(struct gru_message_queue_desc *mqd);
/*
diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
index 3d2fc216bae5..ec3f7a17d221 100644
--- a/drivers/misc/sgi-gru/grumain.c
+++ b/drivers/misc/sgi-gru/grumain.c
@@ -76,10 +76,9 @@ int gru_cpu_fault_map_id(void)
/* Hit the asid limit. Start over */
static int gru_wrap_asid(struct gru_state *gru)
{
- gru_dbg(grudev, "gru %p\n", gru);
+ gru_dbg(grudev, "gid %d\n", gru->gs_gid);
STAT(asid_wrap);
gru->gs_asid_gen++;
- gru_flush_all_tlb(gru);
return MIN_ASID;
}
@@ -88,19 +87,21 @@ static int gru_reset_asid_limit(struct gru_state *gru, int asid)
{
int i, gid, inuse_asid, limit;
- gru_dbg(grudev, "gru %p, asid 0x%x\n", gru, asid);
+ gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid);
STAT(asid_next);
limit = MAX_ASID;
if (asid >= limit)
asid = gru_wrap_asid(gru);
+ gru_flush_all_tlb(gru);
gid = gru->gs_gid;
again:
for (i = 0; i < GRU_NUM_CCH; i++) {
if (!gru->gs_gts[i])
continue;
inuse_asid = gru->gs_gts[i]->ts_gms->ms_asids[gid].mt_asid;
- gru_dbg(grudev, "gru %p, inuse_asid 0x%x, cxtnum %d, gts %p\n",
- gru, inuse_asid, i, gru->gs_gts[i]);
+ gru_dbg(grudev, "gid %d, gts %p, gms %p, inuse 0x%x, cxt %d\n",
+ gru->gs_gid, gru->gs_gts[i], gru->gs_gts[i]->ts_gms,
+ inuse_asid, i);
if (inuse_asid == asid) {
asid += ASID_INC;
if (asid >= limit) {
@@ -120,8 +121,8 @@ again:
}
gru->gs_asid_limit = limit;
gru->gs_asid = asid;
- gru_dbg(grudev, "gru %p, new asid 0x%x, new_limit 0x%x\n", gru, asid,
- limit);
+ gru_dbg(grudev, "gid %d, new asid 0x%x, new_limit 0x%x\n", gru->gs_gid,
+ asid, limit);
return asid;
}
@@ -130,14 +131,12 @@ static int gru_assign_asid(struct gru_state *gru)
{
int asid;
- spin_lock(&gru->gs_asid_lock);
gru->gs_asid += ASID_INC;
asid = gru->gs_asid;
if (asid >= gru->gs_asid_limit)
asid = gru_reset_asid_limit(gru, asid);
- spin_unlock(&gru->gs_asid_lock);
- gru_dbg(grudev, "gru %p, asid 0x%x\n", gru, asid);
+ gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid);
return asid;
}
@@ -215,17 +214,20 @@ static int check_gru_resources(struct gru_state *gru, int cbr_au_count,
* TLB manangment requires tracking all GRU chiplets that have loaded a GSEG
* context.
*/
-static int gru_load_mm_tracker(struct gru_state *gru, struct gru_mm_struct *gms,
- int ctxnum)
+static int gru_load_mm_tracker(struct gru_state *gru,
+ struct gru_thread_state *gts)
{
+ struct gru_mm_struct *gms = gts->ts_gms;
struct gru_mm_tracker *asids = &gms->ms_asids[gru->gs_gid];
- unsigned short ctxbitmap = (1 << ctxnum);
+ unsigned short ctxbitmap = (1 << gts->ts_ctxnum);
int asid;
spin_lock(&gms->ms_asid_lock);
asid = asids->mt_asid;
- if (asid == 0 || asids->mt_asid_gen != gru->gs_asid_gen) {
+ spin_lock(&gru->gs_asid_lock);
+ if (asid == 0 || (asids->mt_ctxbitmap == 0 && asids->mt_asid_gen !=
+ gru->gs_asid_gen)) {
asid = gru_assign_asid(gru);
asids->mt_asid = asid;
asids->mt_asid_gen = gru->gs_asid_gen;
@@ -233,6 +235,7 @@ static int gru_load_mm_tracker(struct gru_state *gru, struct gru_mm_struct *gms,
} else {
STAT(asid_reuse);
}
+ spin_unlock(&gru->gs_asid_lock);
BUG_ON(asids->mt_ctxbitmap & ctxbitmap);
asids->mt_ctxbitmap |= ctxbitmap;
@@ -241,24 +244,28 @@ static int gru_load_mm_tracker(struct gru_state *gru, struct gru_mm_struct *gms,
spin_unlock(&gms->ms_asid_lock);
gru_dbg(grudev,
- "gru %x, gms %p, ctxnum 0x%d, asid 0x%x, asidmap 0x%lx\n",
- gru->gs_gid, gms, ctxnum, asid, gms->ms_asidmap[0]);
+ "gid %d, gts %p, gms %p, ctxnum %d, asid 0x%x, asidmap 0x%lx\n",
+ gru->gs_gid, gts, gms, gts->ts_ctxnum, asid,
+ gms->ms_asidmap[0]);
return asid;
}
static void gru_unload_mm_tracker(struct gru_state *gru,
- struct gru_mm_struct *gms, int ctxnum)
+ struct gru_thread_state *gts)
{
+ struct gru_mm_struct *gms = gts->ts_gms;
struct gru_mm_tracker *asids;
unsigned short ctxbitmap;
asids = &gms->ms_asids[gru->gs_gid];
- ctxbitmap = (1 << ctxnum);
+ ctxbitmap = (1 << gts->ts_ctxnum);
spin_lock(&gms->ms_asid_lock);
+ spin_lock(&gru->gs_asid_lock);
BUG_ON((asids->mt_ctxbitmap & ctxbitmap) != ctxbitmap);
asids->mt_ctxbitmap ^= ctxbitmap;
- gru_dbg(grudev, "gru %x, gms %p, ctxnum 0x%d, asidmap 0x%lx\n",
- gru->gs_gid, gms, ctxnum, gms->ms_asidmap[0]);
+ gru_dbg(grudev, "gid %d, gts %p, gms %p, ctxnum 0x%d, asidmap 0x%lx\n",
+ gru->gs_gid, gts, gms, gts->ts_ctxnum, gms->ms_asidmap[0]);
+ spin_unlock(&gru->gs_asid_lock);
spin_unlock(&gms->ms_asid_lock);
}
@@ -319,6 +326,7 @@ static struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
gts->ts_vma = vma;
gts->ts_tlb_int_select = -1;
gts->ts_gms = gru_register_mmu_notifier();
+ gts->ts_sizeavail = GRU_SIZEAVAIL(PAGE_SHIFT);
if (!gts->ts_gms)
goto err;
@@ -399,7 +407,7 @@ static void gru_free_gru_context(struct gru_thread_state *gts)
struct gru_state *gru;
gru = gts->ts_gru;
- gru_dbg(grudev, "gts %p, gru %p\n", gts, gru);
+ gru_dbg(grudev, "gts %p, gid %d\n", gts, gru->gs_gid);
spin_lock(&gru->gs_lock);
gru->gs_gts[gts->ts_ctxnum] = NULL;
@@ -408,6 +416,7 @@ static void gru_free_gru_context(struct gru_thread_state *gts)
__clear_bit(gts->ts_ctxnum, &gru->gs_context_map);
gts->ts_ctxnum = NULLCTX;
gts->ts_gru = NULL;
+ gts->ts_blade = -1;
spin_unlock(&gru->gs_lock);
gts_drop(gts);
@@ -432,8 +441,8 @@ static inline long gru_copy_handle(void *d, void *s)
return GRU_HANDLE_BYTES;
}
-static void gru_prefetch_context(void *gseg, void *cb, void *cbe, unsigned long cbrmap,
- unsigned long length)
+static void gru_prefetch_context(void *gseg, void *cb, void *cbe,
+ unsigned long cbrmap, unsigned long length)
{
int i, scr;
@@ -500,12 +509,12 @@ void gru_unload_context(struct gru_thread_state *gts, int savestate)
zap_vma_ptes(gts->ts_vma, UGRUADDR(gts), GRU_GSEG_PAGESIZE);
cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
+ gru_dbg(grudev, "gts %p\n", gts);
lock_cch_handle(cch);
if (cch_interrupt_sync(cch))
BUG();
- gru_dbg(grudev, "gts %p\n", gts);
- gru_unload_mm_tracker(gru, gts->ts_gms, gts->ts_ctxnum);
+ gru_unload_mm_tracker(gru, gts);
if (savestate)
gru_unload_context_data(gts->ts_gdata, gru->gs_gru_base_vaddr,
ctxnum, gts->ts_cbr_map,
@@ -534,7 +543,7 @@ static void gru_load_context(struct gru_thread_state *gts)
cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
lock_cch_handle(cch);
- asid = gru_load_mm_tracker(gru, gts->ts_gms, gts->ts_ctxnum);
+ asid = gru_load_mm_tracker(gru, gts);
cch->tfm_fault_bit_enable =
(gts->ts_user_options == GRU_OPT_MISS_FMM_POLL
|| gts->ts_user_options == GRU_OPT_MISS_FMM_INTR);
@@ -544,7 +553,8 @@ static void gru_load_context(struct gru_thread_state *gts)
cch->tlb_int_select = gts->ts_tlb_int_select;
}
cch->tfm_done_bit_enable = 0;
- err = cch_allocate(cch, asid, gts->ts_cbr_map, gts->ts_dsr_map);
+ err = cch_allocate(cch, asid, gts->ts_sizeavail, gts->ts_cbr_map,
+ gts->ts_dsr_map);
if (err) {
gru_dbg(grudev,
"err %d: cch %p, gts %p, cbr 0x%lx, dsr 0x%lx\n",
@@ -565,11 +575,12 @@ static void gru_load_context(struct gru_thread_state *gts)
/*
* Update fields in an active CCH:
* - retarget interrupts on local blade
+ * - update sizeavail mask
* - force a delayed context unload by clearing the CCH asids. This
* forces TLB misses for new GRU instructions. The context is unloaded
* when the next TLB miss occurs.
*/
-static int gru_update_cch(struct gru_thread_state *gts, int int_select)
+int gru_update_cch(struct gru_thread_state *gts, int force_unload)
{
struct gru_context_configuration_handle *cch;
struct gru_state *gru = gts->ts_gru;
@@ -583,9 +594,11 @@ static int gru_update_cch(struct gru_thread_state *gts, int int_select)
goto exit;
if (cch_interrupt(cch))
BUG();
- if (int_select >= 0) {
- gts->ts_tlb_int_select = int_select;
- cch->tlb_int_select = int_select;
+ if (!force_unload) {
+ for (i = 0; i < 8; i++)
+ cch->sizeavail[i] = gts->ts_sizeavail;
+ gts->ts_tlb_int_select = gru_cpu_fault_map_id();
+ cch->tlb_int_select = gru_cpu_fault_map_id();
} else {
for (i = 0; i < 8; i++)
cch->asid[i] = 0;
@@ -617,7 +630,7 @@ static int gru_retarget_intr(struct gru_thread_state *gts)
gru_dbg(grudev, "retarget from %d to %d\n", gts->ts_tlb_int_select,
gru_cpu_fault_map_id());
- return gru_update_cch(gts, gru_cpu_fault_map_id());
+ return gru_update_cch(gts, 0);
}
@@ -688,7 +701,7 @@ static void gru_steal_context(struct gru_thread_state *gts)
STAT(steal_context_failed);
}
gru_dbg(grudev,
- "stole gru %x, ctxnum %d from gts %p. Need cb %d, ds %d;"
+ "stole gid %d, ctxnum %d from gts %p. Need cb %d, ds %d;"
" avail cb %ld, ds %ld\n",
gru->gs_gid, ctxnum, ngts, cbr, dsr, hweight64(gru->gs_cbr_map),
hweight64(gru->gs_dsr_map));
@@ -727,6 +740,7 @@ again:
}
reserve_gru_resources(gru, gts);
gts->ts_gru = gru;
+ gts->ts_blade = gru->gs_blade_id;
gts->ts_ctxnum =
find_first_zero_bit(&gru->gs_context_map, GRU_NUM_CCH);
BUG_ON(gts->ts_ctxnum == GRU_NUM_CCH);
@@ -737,7 +751,7 @@ again:
STAT(assign_context);
gru_dbg(grudev,
- "gseg %p, gts %p, gru %x, ctx %d, cbr %d, dsr %d\n",
+ "gseg %p, gts %p, gid %d, ctx %d, cbr %d, dsr %d\n",
gseg_virtual_address(gts->ts_gru, gts->ts_ctxnum), gts,
gts->ts_gru->gs_gid, gts->ts_ctxnum,
gts->ts_cbr_au_count, gts->ts_dsr_au_count);
@@ -773,8 +787,8 @@ int gru_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
return VM_FAULT_SIGBUS;
again:
- preempt_disable();
mutex_lock(&gts->ts_ctxlock);
+ preempt_disable();
if (gts->ts_gru) {
if (gts->ts_gru->gs_blade_id != uv_numa_blade_id()) {
STAT(migrated_nopfn_unload);
diff --git a/drivers/misc/sgi-gru/gruprocfs.c b/drivers/misc/sgi-gru/gruprocfs.c
index 73b0ca061bb5..ee74821b171c 100644
--- a/drivers/misc/sgi-gru/gruprocfs.c
+++ b/drivers/misc/sgi-gru/gruprocfs.c
@@ -62,7 +62,9 @@ static int statistics_show(struct seq_file *s, void *p)
printstat(s, asid_wrap);
printstat(s, asid_reuse);
printstat(s, intr);
+ printstat(s, intr_mm_lock_failed);
printstat(s, call_os);
+ printstat(s, call_os_offnode_reference);
printstat(s, call_os_check_for_bug);
printstat(s, call_os_wait_queue);
printstat(s, user_flush_tlb);
@@ -120,6 +122,30 @@ static ssize_t statistics_write(struct file *file, const char __user *userbuf,
return count;
}
+static int mcs_statistics_show(struct seq_file *s, void *p)
+{
+ int op;
+ unsigned long total, count, max;
+ static char *id[] = {"cch_allocate", "cch_start", "cch_interrupt",
+ "cch_interrupt_sync", "cch_deallocate", "tgh_invalidate"};
+
+ for (op = 0; op < mcsop_last; op++) {
+ count = atomic_long_read(&mcs_op_statistics[op].count);
+ total = atomic_long_read(&mcs_op_statistics[op].total);
+ max = mcs_op_statistics[op].max;
+ seq_printf(s, "%-20s%12ld%12ld%12ld\n", id[op], count,
+ count ? total / count : 0, max);
+ }
+ return 0;
+}
+
+static ssize_t mcs_statistics_write(struct file *file,
+ const char __user *userbuf, size_t count, loff_t *data)
+{
+ memset(mcs_op_statistics, 0, sizeof(mcs_op_statistics));
+ return count;
+}
+
static int options_show(struct seq_file *s, void *p)
{
seq_printf(s, "0x%lx\n", gru_options);
@@ -135,6 +161,7 @@ static ssize_t options_write(struct file *file, const char __user *userbuf,
if (copy_from_user
(buf, userbuf, count < sizeof(buf) ? count : sizeof(buf)))
return -EFAULT;
+ buf[count - 1] = '\0';
if (!strict_strtoul(buf, 10, &val))
gru_options = val;
@@ -199,7 +226,7 @@ static void seq_stop(struct seq_file *file, void *data)
static void *seq_start(struct seq_file *file, loff_t *gid)
{
- if (*gid < GRU_MAX_GRUS)
+ if (*gid < gru_max_gids)
return gid;
return NULL;
}
@@ -207,7 +234,7 @@ static void *seq_start(struct seq_file *file, loff_t *gid)
static void *seq_next(struct seq_file *file, void *data, loff_t *gid)
{
(*gid)++;
- if (*gid < GRU_MAX_GRUS)
+ if (*gid < gru_max_gids)
return gid;
return NULL;
}
@@ -231,6 +258,11 @@ static int statistics_open(struct inode *inode, struct file *file)
return single_open(file, statistics_show, NULL);
}
+static int mcs_statistics_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mcs_statistics_show, NULL);
+}
+
static int options_open(struct inode *inode, struct file *file)
{
return single_open(file, options_show, NULL);
@@ -255,6 +287,14 @@ static const struct file_operations statistics_fops = {
.release = single_release,
};
+static const struct file_operations mcs_statistics_fops = {
+ .open = mcs_statistics_open,
+ .read = seq_read,
+ .write = mcs_statistics_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static const struct file_operations options_fops = {
.open = options_open,
.read = seq_read,
@@ -283,6 +323,7 @@ static struct proc_entry {
struct proc_dir_entry *entry;
} proc_files[] = {
{"statistics", 0644, &statistics_fops},
+ {"mcs_statistics", 0644, &mcs_statistics_fops},
{"debug_options", 0644, &options_fops},
{"cch_status", 0444, &cch_fops},
{"gru_status", 0444, &gru_fops},
diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h
index a78f70deeb59..bf1eeb7553ed 100644
--- a/drivers/misc/sgi-gru/grutables.h
+++ b/drivers/misc/sgi-gru/grutables.h
@@ -153,6 +153,7 @@
extern struct gru_stats_s gru_stats;
extern struct gru_blade_state *gru_base[];
extern unsigned long gru_start_paddr, gru_end_paddr;
+extern unsigned int gru_max_gids;
#define GRU_MAX_BLADES MAX_NUMNODES
#define GRU_MAX_GRUS (GRU_MAX_BLADES * GRU_CHIPLETS_PER_BLADE)
@@ -184,7 +185,9 @@ struct gru_stats_s {
atomic_long_t asid_wrap;
atomic_long_t asid_reuse;
atomic_long_t intr;
+ atomic_long_t intr_mm_lock_failed;
atomic_long_t call_os;
+ atomic_long_t call_os_offnode_reference;
atomic_long_t call_os_check_for_bug;
atomic_long_t call_os_wait_queue;
atomic_long_t user_flush_tlb;
@@ -237,6 +240,17 @@ struct gru_stats_s {
};
+enum mcs_op {cchop_allocate, cchop_start, cchop_interrupt, cchop_interrupt_sync,
+ cchop_deallocate, tghop_invalidate, mcsop_last};
+
+struct mcs_op_statistic {
+ atomic_long_t count;
+ atomic_long_t total;
+ unsigned long max;
+};
+
+extern struct mcs_op_statistic mcs_op_statistics[mcsop_last];
+
#define OPT_DPRINT 1
#define OPT_STATS 2
#define GRU_QUICKLOOK 4
@@ -278,13 +292,12 @@ struct gru_stats_s {
/* Generate a GRU asid value from a GRU base asid & a virtual address. */
#if defined CONFIG_IA64
#define VADDR_HI_BIT 64
-#define GRUREGION(addr) ((addr) >> (VADDR_HI_BIT - 3) & 3)
#elif defined CONFIG_X86_64
#define VADDR_HI_BIT 48
-#define GRUREGION(addr) (0) /* ZZZ could do better */
#else
#error "Unsupported architecture"
#endif
+#define GRUREGION(addr) ((addr) >> (VADDR_HI_BIT - 3) & 3)
#define GRUASID(asid, addr) ((asid) + GRUREGION(addr))
/*------------------------------------------------------------------------------
@@ -297,12 +310,12 @@ struct gru_state;
* This structure is pointed to from the mmstruct via the notifier pointer.
* There is one of these per address space.
*/
-struct gru_mm_tracker {
- unsigned int mt_asid_gen; /* ASID wrap count */
- int mt_asid; /* current base ASID for gru */
- unsigned short mt_ctxbitmap; /* bitmap of contexts using
+struct gru_mm_tracker { /* pack to reduce size */
+ unsigned int mt_asid_gen:24; /* ASID wrap count */
+ unsigned int mt_asid:24; /* current base ASID for gru */
+ unsigned short mt_ctxbitmap:16;/* bitmap of contexts using
asid */
-};
+} __attribute__ ((packed));
struct gru_mm_struct {
struct mmu_notifier ms_notifier;
@@ -348,6 +361,7 @@ struct gru_thread_state {
long ts_user_options;/* misc user option flags */
pid_t ts_tgid_owner; /* task that is using the
context - for migration */
+ unsigned short ts_sizeavail; /* Pagesizes in use */
int ts_tsid; /* thread that owns the
structure */
int ts_tlb_int_select;/* target cpu if interrupts
@@ -359,6 +373,9 @@ struct gru_thread_state {
required for contest */
unsigned char ts_cbr_au_count;/* Number of CBR resources
required for contest */
+ char ts_blade; /* If >= 0, migrate context if
+ ref from diferent blade */
+ char ts_force_cch_reload;
char ts_force_unload;/* force context to be unloaded
after migration */
char ts_cbr_idx[GRU_CBR_AU];/* CBR numbers of each
@@ -392,12 +409,12 @@ struct gru_state {
gru segments (64) */
void *gs_gru_base_vaddr; /* Virtual address of
gru segments (64) */
- unsigned char gs_gid; /* unique GRU number */
+ unsigned short gs_gid; /* unique GRU number */
+ unsigned short gs_blade_id; /* blade of GRU */
unsigned char gs_tgh_local_shift; /* used to pick TGH for
local flush */
unsigned char gs_tgh_first_remote; /* starting TGH# for
remote flush */
- unsigned short gs_blade_id; /* blade of GRU */
spinlock_t gs_asid_lock; /* lock used for
assigning asids */
spinlock_t gs_lock; /* lock used for
@@ -492,6 +509,10 @@ struct gru_blade_state {
(i) < GRU_CHIPLETS_PER_BLADE; \
(i)++, (gru)++)
+/* Scan all GRUs */
+#define foreach_gid(gid) \
+ for ((gid) = 0; (gid) < gru_max_gids; (gid)++)
+
/* Scan all active GTSs on a gru. Note: must hold ss_lock to use this macro. */
#define for_each_gts_on_gru(gts, gru, ctxnum) \
for ((ctxnum) = 0; (ctxnum) < GRU_NUM_CCH; (ctxnum)++) \
@@ -578,9 +599,11 @@ extern struct gru_thread_state *gru_find_thread_state(struct vm_area_struct
extern struct gru_thread_state *gru_alloc_thread_state(struct vm_area_struct
*vma, int tsid);
extern void gru_unload_context(struct gru_thread_state *gts, int savestate);
+extern int gru_update_cch(struct gru_thread_state *gts, int force_unload);
extern void gts_drop(struct gru_thread_state *gts);
extern void gru_tgh_flush_init(struct gru_state *gru);
extern int gru_kservices_init(struct gru_state *gru);
+extern void gru_kservices_exit(struct gru_state *gru);
extern irqreturn_t gru_intr(int irq, void *dev_id);
extern int gru_handle_user_call_os(unsigned long address);
extern int gru_user_flush_tlb(unsigned long arg);
diff --git a/drivers/misc/sgi-gru/grutlbpurge.c b/drivers/misc/sgi-gru/grutlbpurge.c
index c84496a77691..1d125091f5e7 100644
--- a/drivers/misc/sgi-gru/grutlbpurge.c
+++ b/drivers/misc/sgi-gru/grutlbpurge.c
@@ -187,7 +187,7 @@ void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start,
" FLUSH gruid %d, asid 0x%x, num %ld, cbmap 0x%x\n",
gid, asid, num, asids->mt_ctxbitmap);
tgh = get_lock_tgh_handle(gru);
- tgh_invalidate(tgh, start, 0, asid, grupagesize, 0,
+ tgh_invalidate(tgh, start, ~0, asid, grupagesize, 0,
num - 1, asids->mt_ctxbitmap);
get_unlock_tgh_handle(tgh);
} else {
@@ -210,11 +210,10 @@ void gru_flush_all_tlb(struct gru_state *gru)
{
struct gru_tlb_global_handle *tgh;
- gru_dbg(grudev, "gru %p, gid %d\n", gru, gru->gs_gid);
+ gru_dbg(grudev, "gid %d\n", gru->gs_gid);
tgh = get_lock_tgh_handle(gru);
- tgh_invalidate(tgh, 0, ~0, 0, 1, 1, GRUMAXINVAL - 1, 0);
+ tgh_invalidate(tgh, 0, ~0, 0, 1, 1, GRUMAXINVAL - 1, 0xffff);
get_unlock_tgh_handle(tgh);
- preempt_enable();
}
/*
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
index 275b78896a73..114444cfd496 100644
--- a/drivers/misc/sgi-xp/xpc.h
+++ b/drivers/misc/sgi-xp/xpc.h
@@ -92,7 +92,9 @@ struct xpc_rsvd_page {
u8 pad1[3]; /* align to next u64 in 1st 64-byte cacheline */
union {
unsigned long vars_pa; /* phys address of struct xpc_vars */
- unsigned long activate_mq_gpa; /* gru phy addr of activate_mq */
+ unsigned long activate_gru_mq_desc_gpa; /* phys addr of */
+ /* activate mq's */
+ /* gru mq descriptor */
} sn;
unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
u64 pad2[10]; /* align to last u64 in 2nd 64-byte cacheline */
@@ -189,7 +191,9 @@ struct xpc_gru_mq_uv {
int irq; /* irq raised when message is received in mq */
int mmr_blade; /* blade where watchlist was allocated from */
unsigned long mmr_offset; /* offset of irq mmr located on mmr_blade */
+ unsigned long mmr_value; /* value of irq mmr located on mmr_blade */
int watchlist_num; /* number of watchlist allocatd by BIOS */
+ void *gru_mq_desc; /* opaque structure used by the GRU driver */
};
/*
@@ -197,6 +201,7 @@ struct xpc_gru_mq_uv {
* heartbeat, partition active state, and channel state. This is UV only.
*/
struct xpc_activate_mq_msghdr_uv {
+ unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */
short partid; /* sender's partid */
u8 act_state; /* sender's act_state at time msg sent */
u8 type; /* message's type */
@@ -232,7 +237,7 @@ struct xpc_activate_mq_msg_heartbeat_req_uv {
struct xpc_activate_mq_msg_activate_req_uv {
struct xpc_activate_mq_msghdr_uv hdr;
unsigned long rp_gpa;
- unsigned long activate_mq_gpa;
+ unsigned long activate_gru_mq_desc_gpa;
};
struct xpc_activate_mq_msg_deactivate_req_uv {
@@ -263,7 +268,7 @@ struct xpc_activate_mq_msg_chctl_openreply_uv {
short ch_number;
short remote_nentries; /* ??? Is this needed? What is? */
short local_nentries; /* ??? Is this needed? What is? */
- unsigned long local_notify_mq_gpa;
+ unsigned long notify_gru_mq_desc_gpa;
};
/*
@@ -510,8 +515,8 @@ struct xpc_channel_sn2 {
};
struct xpc_channel_uv {
- unsigned long remote_notify_mq_gpa; /* gru phys address of remote */
- /* partition's notify mq */
+ void *cached_notify_gru_mq_desc; /* remote partition's notify mq's */
+ /* gru mq descriptor */
struct xpc_send_msg_slot_uv *send_msg_slots;
void *recv_msg_slots; /* each slot will hold a xpc_notify_mq_msg_uv */
@@ -682,8 +687,12 @@ struct xpc_partition_sn2 {
};
struct xpc_partition_uv {
- unsigned long remote_activate_mq_gpa; /* gru phys address of remote */
- /* partition's activate mq */
+ unsigned long activate_gru_mq_desc_gpa; /* phys addr of parititon's */
+ /* activate mq's gru mq */
+ /* descriptor */
+ void *cached_activate_gru_mq_desc; /* cached copy of partition's */
+ /* activate mq's gru mq descriptor */
+ struct mutex cached_activate_gru_mq_desc_mutex;
spinlock_t flags_lock; /* protect updating of flags */
unsigned int flags; /* general flags */
u8 remote_act_state; /* remote partition's act_state */
@@ -694,8 +703,9 @@ struct xpc_partition_uv {
/* struct xpc_partition_uv flags */
-#define XPC_P_HEARTBEAT_OFFLINE_UV 0x00000001
-#define XPC_P_ENGAGED_UV 0x00000002
+#define XPC_P_HEARTBEAT_OFFLINE_UV 0x00000001
+#define XPC_P_ENGAGED_UV 0x00000002
+#define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV 0x00000004
/* struct xpc_partition_uv act_state change requests */
@@ -804,6 +814,7 @@ extern void xpc_activate_kthreads(struct xpc_channel *, int);
extern void xpc_create_kthreads(struct xpc_channel *, int, int);
extern void xpc_disconnect_wait(int);
extern int (*xpc_setup_partitions_sn) (void);
+extern void (*xpc_teardown_partitions_sn) (void);
extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *, u64 *,
unsigned long *,
size_t *);
@@ -846,8 +857,8 @@ extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *,
unsigned long *);
extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *);
-extern void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *,
- unsigned long);
+extern enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *,
+ unsigned long);
extern enum xp_retval (*xpc_send_payload) (struct xpc_channel *, u32, void *,
u16, u8, xpc_notify_func, void *);
diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c
index 45fd653dbe31..99a2534c38a1 100644
--- a/drivers/misc/sgi-xp/xpc_channel.c
+++ b/drivers/misc/sgi-xp/xpc_channel.c
@@ -183,6 +183,7 @@ xpc_process_openclose_chctl_flags(struct xpc_partition *part, int ch_number,
&part->remote_openclose_args[ch_number];
struct xpc_channel *ch = &part->channels[ch_number];
enum xp_retval reason;
+ enum xp_retval ret;
spin_lock_irqsave(&ch->lock, irq_flags);
@@ -399,8 +400,13 @@ again:
DBUG_ON(args->local_nentries == 0);
DBUG_ON(args->remote_nentries == 0);
+ ret = xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa);
+ if (ret != xpSuccess) {
+ XPC_DISCONNECT_CHANNEL(ch, ret, &irq_flags);
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return;
+ }
ch->flags |= XPC_C_ROPENREPLY;
- xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa);
if (args->local_nentries < ch->remote_nentries) {
dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY: new "
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index 6576170de962..1ab9fda87fab 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -171,6 +171,7 @@ static struct notifier_block xpc_die_notifier = {
};
int (*xpc_setup_partitions_sn) (void);
+void (*xpc_teardown_partitions_sn) (void);
enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *buf, u64 *cookie,
unsigned long *rp_pa,
size_t *len);
@@ -217,8 +218,8 @@ void (*xpc_send_chctl_openrequest) (struct xpc_channel *ch,
void (*xpc_send_chctl_openreply) (struct xpc_channel *ch,
unsigned long *irq_flags);
-void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch,
- unsigned long msgqueue_pa);
+enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch,
+ unsigned long msgqueue_pa);
enum xp_retval (*xpc_send_payload) (struct xpc_channel *ch, u32 flags,
void *payload, u16 payload_size,
@@ -998,6 +999,7 @@ xpc_setup_partitions(void)
static void
xpc_teardown_partitions(void)
{
+ xpc_teardown_partitions_sn();
kfree(xpc_partitions);
}
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c
index 2e975762c32b..eaaa964942de 100644
--- a/drivers/misc/sgi-xp/xpc_sn2.c
+++ b/drivers/misc/sgi-xp/xpc_sn2.c
@@ -66,6 +66,12 @@ xpc_setup_partitions_sn_sn2(void)
return 0;
}
+static void
+xpc_teardown_partitions_sn_sn2(void)
+{
+ /* nothing needs to be done */
+}
+
/* SH_IPI_ACCESS shub register value on startup */
static u64 xpc_sh1_IPI_access_sn2;
static u64 xpc_sh2_IPI_access0_sn2;
@@ -436,11 +442,12 @@ xpc_send_chctl_local_msgrequest_sn2(struct xpc_channel *ch)
XPC_SEND_LOCAL_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST);
}
-static void
+static enum xp_retval
xpc_save_remote_msgqueue_pa_sn2(struct xpc_channel *ch,
unsigned long msgqueue_pa)
{
ch->sn.sn2.remote_msgqueue_pa = msgqueue_pa;
+ return xpSuccess;
}
/*
@@ -1737,20 +1744,20 @@ xpc_clear_remote_msgqueue_flags_sn2(struct xpc_channel *ch)
{
struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
struct xpc_msg_sn2 *msg;
- s64 put;
+ s64 put, remote_nentries = ch->remote_nentries;
/* flags are zeroed when the buffer is allocated */
- if (ch_sn2->remote_GP.put < ch->remote_nentries)
+ if (ch_sn2->remote_GP.put < remote_nentries)
return;
- put = max(ch_sn2->w_remote_GP.put, ch->remote_nentries);
+ put = max(ch_sn2->w_remote_GP.put, remote_nentries);
do {
msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue +
- (put % ch->remote_nentries) *
+ (put % remote_nentries) *
ch->entry_size);
DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
DBUG_ON(!(msg->flags & XPC_M_SN2_DONE));
- DBUG_ON(msg->number != put - ch->remote_nentries);
+ DBUG_ON(msg->number != put - remote_nentries);
msg->flags = 0;
} while (++put < ch_sn2->remote_GP.put);
}
@@ -2315,6 +2322,7 @@ xpc_init_sn2(void)
size_t buf_size;
xpc_setup_partitions_sn = xpc_setup_partitions_sn_sn2;
+ xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_sn2;
xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2;
xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_sn2;
xpc_increment_heartbeat = xpc_increment_heartbeat_sn2;
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
index 29c0502a96b2..f7fff4727edb 100644
--- a/drivers/misc/sgi-xp/xpc_uv.c
+++ b/drivers/misc/sgi-xp/xpc_uv.c
@@ -31,6 +31,21 @@
#include "../sgi-gru/grukservices.h"
#include "xpc.h"
+#if defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+struct uv_IO_APIC_route_entry {
+ __u64 vector : 8,
+ delivery_mode : 3,
+ dest_mode : 1,
+ delivery_status : 1,
+ polarity : 1,
+ __reserved_1 : 1,
+ trigger : 1,
+ mask : 1,
+ __reserved_2 : 15,
+ dest : 32;
+};
+#endif
+
static atomic64_t xpc_heartbeat_uv;
static DECLARE_BITMAP(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV);
@@ -56,26 +71,52 @@ xpc_setup_partitions_sn_uv(void)
for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
part_uv = &xpc_partitions[partid].sn.uv;
+ mutex_init(&part_uv->cached_activate_gru_mq_desc_mutex);
spin_lock_init(&part_uv->flags_lock);
part_uv->remote_act_state = XPC_P_AS_INACTIVE;
}
return 0;
}
+static void
+xpc_teardown_partitions_sn_uv(void)
+{
+ short partid;
+ struct xpc_partition_uv *part_uv;
+ unsigned long irq_flags;
+
+ for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
+ part_uv = &xpc_partitions[partid].sn.uv;
+
+ if (part_uv->cached_activate_gru_mq_desc != NULL) {
+ mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex);
+ spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
+ part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
+ spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
+ kfree(part_uv->cached_activate_gru_mq_desc);
+ part_uv->cached_activate_gru_mq_desc = NULL;
+ mutex_unlock(&part_uv->
+ cached_activate_gru_mq_desc_mutex);
+ }
+ }
+}
+
static int
xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
{
+ int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
+
#if defined CONFIG_X86_64
mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset);
if (mq->irq < 0) {
dev_err(xpc_part, "uv_setup_irq() returned error=%d\n",
- mq->irq);
+ -mq->irq);
+ return mq->irq;
}
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
- int mmr_pnode;
- unsigned long mmr_value;
+ mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset);
+#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
if (strcmp(irq_name, XPC_ACTIVATE_IRQ_NAME) == 0)
mq->irq = SGI_XPC_ACTIVATE;
else if (strcmp(irq_name, XPC_NOTIFY_IRQ_NAME) == 0)
@@ -83,10 +124,8 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
else
return -EINVAL;
- mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
- mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq;
-
- uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value);
+ mq->mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq;
+ uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mq->mmr_value);
#else
#error not a supported configuration
#endif
@@ -127,7 +166,7 @@ xpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq)
return ret;
}
#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
- ret = sn_mq_watchlist_alloc(mq->mmr_blade, uv_gpa(mq->address),
+ ret = sn_mq_watchlist_alloc(mq->mmr_blade, (void *)uv_gpa(mq->address),
mq->order, &mq->mmr_offset);
if (ret < 0) {
dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n",
@@ -168,12 +207,22 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
int pg_order;
struct page *page;
struct xpc_gru_mq_uv *mq;
+ struct uv_IO_APIC_route_entry *mmr_value;
mq = kmalloc(sizeof(struct xpc_gru_mq_uv), GFP_KERNEL);
if (mq == NULL) {
dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() "
"a xpc_gru_mq_uv structure\n");
ret = -ENOMEM;
+ goto out_0;
+ }
+
+ mq->gru_mq_desc = kzalloc(sizeof(struct gru_message_queue_desc),
+ GFP_KERNEL);
+ if (mq->gru_mq_desc == NULL) {
+ dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() "
+ "a gru_message_queue_desc structure\n");
+ ret = -ENOMEM;
goto out_1;
}
@@ -194,14 +243,6 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
}
mq->address = page_address(page);
- ret = gru_create_message_queue(mq->address, mq_size);
- if (ret != 0) {
- dev_err(xpc_part, "gru_create_message_queue() returned "
- "error=%d\n", ret);
- ret = -EINVAL;
- goto out_3;
- }
-
/* enable generation of irq when GRU mq operation occurs to this mq */
ret = xpc_gru_mq_watchlist_alloc_uv(mq);
if (ret != 0)
@@ -214,10 +255,20 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
ret = request_irq(mq->irq, irq_handler, 0, irq_name, NULL);
if (ret != 0) {
dev_err(xpc_part, "request_irq(irq=%d) returned error=%d\n",
- mq->irq, ret);
+ mq->irq, -ret);
goto out_5;
}
+ mmr_value = (struct uv_IO_APIC_route_entry *)&mq->mmr_value;
+ ret = gru_create_message_queue(mq->gru_mq_desc, mq->address, mq_size,
+ nid, mmr_value->vector, mmr_value->dest);
+ if (ret != 0) {
+ dev_err(xpc_part, "gru_create_message_queue() returned "
+ "error=%d\n", ret);
+ ret = -EINVAL;
+ goto out_6;
+ }
+
/* allow other partitions to access this GRU mq */
xp_ret = xp_expand_memprotect(xp_pa(mq->address), mq_size);
if (xp_ret != xpSuccess) {
@@ -237,8 +288,10 @@ out_4:
out_3:
free_pages((unsigned long)mq->address, pg_order);
out_2:
- kfree(mq);
+ kfree(mq->gru_mq_desc);
out_1:
+ kfree(mq);
+out_0:
return ERR_PTR(ret);
}
@@ -268,13 +321,14 @@ xpc_destroy_gru_mq_uv(struct xpc_gru_mq_uv *mq)
}
static enum xp_retval
-xpc_send_gru_msg(unsigned long mq_gpa, void *msg, size_t msg_size)
+xpc_send_gru_msg(struct gru_message_queue_desc *gru_mq_desc, void *msg,
+ size_t msg_size)
{
enum xp_retval xp_ret;
int ret;
while (1) {
- ret = gru_send_message_gpa(mq_gpa, msg, msg_size);
+ ret = gru_send_message_gpa(gru_mq_desc, msg, msg_size);
if (ret == MQE_OK) {
xp_ret = xpSuccess;
break;
@@ -421,7 +475,15 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV;
part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */
part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies;
- part_uv->remote_activate_mq_gpa = msg->activate_mq_gpa;
+
+ if (msg->activate_gru_mq_desc_gpa !=
+ part_uv->activate_gru_mq_desc_gpa) {
+ spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
+ part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
+ spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
+ part_uv->activate_gru_mq_desc_gpa =
+ msg->activate_gru_mq_desc_gpa;
+ }
spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
(*wakeup_hb_checker)++;
@@ -498,7 +560,7 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
args = &part->remote_openclose_args[msg->ch_number];
args->remote_nentries = msg->remote_nentries;
args->local_nentries = msg->local_nentries;
- args->local_msgqueue_pa = msg->local_notify_mq_gpa;
+ args->local_msgqueue_pa = msg->notify_gru_mq_desc_gpa;
spin_lock_irqsave(&part->chctl_lock, irq_flags);
part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREPLY;
@@ -558,9 +620,10 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id)
short partid;
struct xpc_partition *part;
int wakeup_hb_checker = 0;
+ int part_referenced;
while (1) {
- msg_hdr = gru_get_next_message(xpc_activate_mq_uv->address);
+ msg_hdr = gru_get_next_message(xpc_activate_mq_uv->gru_mq_desc);
if (msg_hdr == NULL)
break;
@@ -571,14 +634,15 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id)
partid);
} else {
part = &xpc_partitions[partid];
- if (xpc_part_ref(part)) {
- xpc_handle_activate_mq_msg_uv(part, msg_hdr,
- &wakeup_hb_checker);
+
+ part_referenced = xpc_part_ref(part);
+ xpc_handle_activate_mq_msg_uv(part, msg_hdr,
+ &wakeup_hb_checker);
+ if (part_referenced)
xpc_part_deref(part);
- }
}
- gru_free_message(xpc_activate_mq_uv->address, msg_hdr);
+ gru_free_message(xpc_activate_mq_uv->gru_mq_desc, msg_hdr);
}
if (wakeup_hb_checker)
@@ -588,21 +652,73 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id)
}
static enum xp_retval
+xpc_cache_remote_gru_mq_desc_uv(struct gru_message_queue_desc *gru_mq_desc,
+ unsigned long gru_mq_desc_gpa)
+{
+ enum xp_retval ret;
+
+ ret = xp_remote_memcpy(uv_gpa(gru_mq_desc), gru_mq_desc_gpa,
+ sizeof(struct gru_message_queue_desc));
+ if (ret == xpSuccess)
+ gru_mq_desc->mq = NULL;
+
+ return ret;
+}
+
+static enum xp_retval
xpc_send_activate_IRQ_uv(struct xpc_partition *part, void *msg, size_t msg_size,
int msg_type)
{
struct xpc_activate_mq_msghdr_uv *msg_hdr = msg;
+ struct xpc_partition_uv *part_uv = &part->sn.uv;
+ struct gru_message_queue_desc *gru_mq_desc;
+ unsigned long irq_flags;
+ enum xp_retval ret;
DBUG_ON(msg_size > XPC_ACTIVATE_MSG_SIZE_UV);
msg_hdr->type = msg_type;
- msg_hdr->partid = XPC_PARTID(part);
+ msg_hdr->partid = xp_partition_id;
msg_hdr->act_state = part->act_state;
msg_hdr->rp_ts_jiffies = xpc_rsvd_page->ts_jiffies;
+ mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex);
+again:
+ if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV)) {
+ gru_mq_desc = part_uv->cached_activate_gru_mq_desc;
+ if (gru_mq_desc == NULL) {
+ gru_mq_desc = kmalloc(sizeof(struct
+ gru_message_queue_desc),
+ GFP_KERNEL);
+ if (gru_mq_desc == NULL) {
+ ret = xpNoMemory;
+ goto done;
+ }
+ part_uv->cached_activate_gru_mq_desc = gru_mq_desc;
+ }
+
+ ret = xpc_cache_remote_gru_mq_desc_uv(gru_mq_desc,
+ part_uv->
+ activate_gru_mq_desc_gpa);
+ if (ret != xpSuccess)
+ goto done;
+
+ spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
+ part_uv->flags |= XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
+ spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
+ }
+
/* ??? Is holding a spin_lock (ch->lock) during this call a bad idea? */
- return xpc_send_gru_msg(part->sn.uv.remote_activate_mq_gpa, msg,
- msg_size);
+ ret = xpc_send_gru_msg(part_uv->cached_activate_gru_mq_desc, msg,
+ msg_size);
+ if (ret != xpSuccess) {
+ smp_rmb(); /* ensure a fresh copy of part_uv->flags */
+ if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV))
+ goto again;
+ }
+done:
+ mutex_unlock(&part_uv->cached_activate_gru_mq_desc_mutex);
+ return ret;
}
static void
@@ -620,7 +736,7 @@ static void
xpc_send_activate_IRQ_ch_uv(struct xpc_channel *ch, unsigned long *irq_flags,
void *msg, size_t msg_size, int msg_type)
{
- struct xpc_partition *part = &xpc_partitions[ch->number];
+ struct xpc_partition *part = &xpc_partitions[ch->partid];
enum xp_retval ret;
ret = xpc_send_activate_IRQ_uv(part, msg, msg_size, msg_type);
@@ -692,7 +808,8 @@ xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa,
static int
xpc_setup_rsvd_page_sn_uv(struct xpc_rsvd_page *rp)
{
- rp->sn.activate_mq_gpa = uv_gpa(xpc_activate_mq_uv->address);
+ rp->sn.activate_gru_mq_desc_gpa =
+ uv_gpa(xpc_activate_mq_uv->gru_mq_desc);
return 0;
}
@@ -787,7 +904,8 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
part->remote_rp_pa = remote_rp_gpa; /* !!! _pa here is really _gpa */
part->remote_rp_ts_jiffies = remote_rp->ts_jiffies;
- part->sn.uv.remote_activate_mq_gpa = remote_rp->sn.activate_mq_gpa;
+ part->sn.uv.activate_gru_mq_desc_gpa =
+ remote_rp->sn.activate_gru_mq_desc_gpa;
/*
* ??? Is it a good idea to make this conditional on what is
@@ -795,7 +913,8 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
*/
if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) {
msg.rp_gpa = uv_gpa(xpc_rsvd_page);
- msg.activate_mq_gpa = xpc_rsvd_page->sn.activate_mq_gpa;
+ msg.activate_gru_mq_desc_gpa =
+ xpc_rsvd_page->sn.activate_gru_mq_desc_gpa;
xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV);
}
@@ -857,7 +976,8 @@ xpc_get_fifo_entry_uv(struct xpc_fifo_head_uv *head)
if (head->first == NULL)
head->last = NULL;
}
- head->n_entries++;
+ head->n_entries--;
+ BUG_ON(head->n_entries < 0);
spin_unlock_irqrestore(&head->lock, irq_flags);
first->next = NULL;
return first;
@@ -876,8 +996,7 @@ xpc_put_fifo_entry_uv(struct xpc_fifo_head_uv *head,
else
head->first = last;
head->last = last;
- head->n_entries--;
- BUG_ON(head->n_entries < 0);
+ head->n_entries++;
spin_unlock_irqrestore(&head->lock, irq_flags);
}
@@ -1037,6 +1156,12 @@ xpc_setup_msg_structures_uv(struct xpc_channel *ch)
DBUG_ON(ch->flags & XPC_C_SETUP);
+ ch_uv->cached_notify_gru_mq_desc = kmalloc(sizeof(struct
+ gru_message_queue_desc),
+ GFP_KERNEL);
+ if (ch_uv->cached_notify_gru_mq_desc == NULL)
+ return xpNoMemory;
+
ret = xpc_allocate_send_msg_slot_uv(ch);
if (ret == xpSuccess) {
@@ -1060,7 +1185,8 @@ xpc_teardown_msg_structures_uv(struct xpc_channel *ch)
DBUG_ON(!spin_is_locked(&ch->lock));
- ch_uv->remote_notify_mq_gpa = 0;
+ kfree(ch_uv->cached_notify_gru_mq_desc);
+ ch_uv->cached_notify_gru_mq_desc = NULL;
if (ch->flags & XPC_C_SETUP) {
xpc_init_fifo_uv(&ch_uv->msg_slot_free_list);
@@ -1111,7 +1237,7 @@ xpc_send_chctl_openreply_uv(struct xpc_channel *ch, unsigned long *irq_flags)
msg.ch_number = ch->number;
msg.local_nentries = ch->local_nentries;
msg.remote_nentries = ch->remote_nentries;
- msg.local_notify_mq_gpa = uv_gpa(xpc_notify_mq_uv);
+ msg.notify_gru_mq_desc_gpa = uv_gpa(xpc_notify_mq_uv->gru_mq_desc);
xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV);
}
@@ -1128,11 +1254,15 @@ xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number)
xpc_wakeup_channel_mgr(part);
}
-static void
+static enum xp_retval
xpc_save_remote_msgqueue_pa_uv(struct xpc_channel *ch,
- unsigned long msgqueue_pa)
+ unsigned long gru_mq_desc_gpa)
{
- ch->sn.uv.remote_notify_mq_gpa = msgqueue_pa;
+ struct xpc_channel_uv *ch_uv = &ch->sn.uv;
+
+ DBUG_ON(ch_uv->cached_notify_gru_mq_desc == NULL);
+ return xpc_cache_remote_gru_mq_desc_uv(ch_uv->cached_notify_gru_mq_desc,
+ gru_mq_desc_gpa);
}
static void
@@ -1339,7 +1469,8 @@ xpc_handle_notify_IRQ_uv(int irq, void *dev_id)
short partid;
struct xpc_partition *part;
- while ((msg = gru_get_next_message(xpc_notify_mq_uv)) != NULL) {
+ while ((msg = gru_get_next_message(xpc_notify_mq_uv->gru_mq_desc)) !=
+ NULL) {
partid = msg->hdr.partid;
if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) {
@@ -1354,7 +1485,7 @@ xpc_handle_notify_IRQ_uv(int irq, void *dev_id)
}
}
- gru_free_message(xpc_notify_mq_uv, msg);
+ gru_free_message(xpc_notify_mq_uv->gru_mq_desc, msg);
}
return IRQ_HANDLED;
@@ -1438,7 +1569,8 @@ xpc_send_payload_uv(struct xpc_channel *ch, u32 flags, void *payload,
msg->hdr.msg_slot_number = msg_slot->msg_slot_number;
memcpy(&msg->payload, payload, payload_size);
- ret = xpc_send_gru_msg(ch->sn.uv.remote_notify_mq_gpa, msg, msg_size);
+ ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg,
+ msg_size);
if (ret == xpSuccess)
goto out_1;
@@ -1529,7 +1661,7 @@ xpc_received_payload_uv(struct xpc_channel *ch, void *payload)
msg->hdr.partid = xp_partition_id;
msg->hdr.size = 0; /* size of zero indicates this is an ACK */
- ret = xpc_send_gru_msg(ch->sn.uv.remote_notify_mq_gpa, msg,
+ ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg,
sizeof(struct xpc_notify_mq_msghdr_uv));
if (ret != xpSuccess)
XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret);
@@ -1541,6 +1673,7 @@ int
xpc_init_uv(void)
{
xpc_setup_partitions_sn = xpc_setup_partitions_sn_uv;
+ xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_uv;
xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv;
xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv;
xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_uv;
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 513eb09a638f..fe8041e619ea 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -41,6 +41,8 @@
#include "queue.h"
+MODULE_ALIAS("mmc:block");
+
/*
* max 8 partitions per card
*/
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index 78ad48718ab0..36a8d53ad2a2 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
+#include <linux/seq_file.h>
#include <linux/serial_reg.h>
#include <linux/circ_buf.h>
#include <linux/gfp.h>
@@ -933,67 +934,64 @@ static int sdio_uart_tiocmset(struct tty_struct *tty, struct file *file,
return result;
}
-static int sdio_uart_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static int sdio_uart_proc_show(struct seq_file *m, void *v)
{
- int i, len = 0;
- off_t begin = 0;
+ int i;
- len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n",
+ seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n",
"", "", "");
- for (i = 0; i < UART_NR && len < PAGE_SIZE - 96; i++) {
+ for (i = 0; i < UART_NR; i++) {
struct sdio_uart_port *port = sdio_uart_port_get(i);
if (port) {
- len += sprintf(page+len, "%d: uart:SDIO", i);
+ seq_printf(m, "%d: uart:SDIO", i);
if(capable(CAP_SYS_ADMIN)) {
- len += sprintf(page + len, " tx:%d rx:%d",
+ seq_printf(m, " tx:%d rx:%d",
port->icount.tx, port->icount.rx);
if (port->icount.frame)
- len += sprintf(page + len, " fe:%d",
+ seq_printf(m, " fe:%d",
port->icount.frame);
if (port->icount.parity)
- len += sprintf(page + len, " pe:%d",
+ seq_printf(m, " pe:%d",
port->icount.parity);
if (port->icount.brk)
- len += sprintf(page + len, " brk:%d",
+ seq_printf(m, " brk:%d",
port->icount.brk);
if (port->icount.overrun)
- len += sprintf(page + len, " oe:%d",
+ seq_printf(m, " oe:%d",
port->icount.overrun);
if (port->icount.cts)
- len += sprintf(page + len, " cts:%d",
+ seq_printf(m, " cts:%d",
port->icount.cts);
if (port->icount.dsr)
- len += sprintf(page + len, " dsr:%d",
+ seq_printf(m, " dsr:%d",
port->icount.dsr);
if (port->icount.rng)
- len += sprintf(page + len, " rng:%d",
+ seq_printf(m, " rng:%d",
port->icount.rng);
if (port->icount.dcd)
- len += sprintf(page + len, " dcd:%d",
+ seq_printf(m, " dcd:%d",
port->icount.dcd);
}
- strcat(page, "\n");
- len++;
sdio_uart_port_put(port);
- }
-
- if (len + begin > off + count)
- goto done;
- if (len + begin < off) {
- begin += len;
- len = 0;
+ seq_putc(m, '\n');
}
}
- *eof = 1;
+ return 0;
+}
-done:
- if (off >= len + begin)
- return 0;
- *start = page + (off - begin);
- return (count < begin + len - off) ? count : (begin + len - off);
+static int sdio_uart_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, sdio_uart_proc_show, NULL);
}
+static const struct file_operations sdio_uart_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = sdio_uart_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static const struct tty_operations sdio_uart_ops = {
.open = sdio_uart_open,
.close = sdio_uart_close,
@@ -1007,7 +1005,7 @@ static const struct tty_operations sdio_uart_ops = {
.break_ctl = sdio_uart_break_ctl,
.tiocmget = sdio_uart_tiocmget,
.tiocmset = sdio_uart_tiocmset,
- .read_proc = sdio_uart_read_proc,
+ .proc_fops = &sdio_uart_proc_fops,
};
static struct tty_driver *sdio_uart_tty_driver;
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index f210a8ee6861..bdb165f93046 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -84,6 +84,14 @@ mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
}
retval = add_uevent_var(env, "MMC_NAME=%s", mmc_card_name(card));
+ if (retval)
+ return retval;
+
+ /*
+ * Request the mmc_block device. Note: that this is a direct request
+ * for the module it carries no information as to what is inserted.
+ */
+ retval = add_uevent_var(env, "MODALIAS=mmc:block");
return retval;
}
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index df6ce4a06cf3..fa073ab3fa34 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -21,6 +21,7 @@
#include <linux/leds.h>
#include <linux/scatterlist.h>
#include <linux/log2.h>
+#include <linux/regulator/consumer.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -297,6 +298,21 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
data->timeout_clks = 0;
}
}
+ /*
+ * Some cards need very high timeouts if driven in SPI mode.
+ * The worst observed timeout was 900ms after writing a
+ * continuous stream of data until the internal logic
+ * overflowed.
+ */
+ if (mmc_host_is_spi(card->host)) {
+ if (data->flags & MMC_DATA_WRITE) {
+ if (data->timeout_ns < 1000000000)
+ data->timeout_ns = 1000000000; /* 1s */
+ } else {
+ if (data->timeout_ns < 100000000)
+ data->timeout_ns = 100000000; /* 100ms */
+ }
+ }
}
EXPORT_SYMBOL(mmc_set_data_timeout);
@@ -523,6 +539,105 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max)
}
EXPORT_SYMBOL(mmc_vddrange_to_ocrmask);
+#ifdef CONFIG_REGULATOR
+
+/**
+ * mmc_regulator_get_ocrmask - return mask of supported voltages
+ * @supply: regulator to use
+ *
+ * This returns either a negative errno, or a mask of voltages that
+ * can be provided to MMC/SD/SDIO devices using the specified voltage
+ * regulator. This would normally be called before registering the
+ * MMC host adapter.
+ */
+int mmc_regulator_get_ocrmask(struct regulator *supply)
+{
+ int result = 0;
+ int count;
+ int i;
+
+ count = regulator_count_voltages(supply);
+ if (count < 0)
+ return count;
+
+ for (i = 0; i < count; i++) {
+ int vdd_uV;
+ int vdd_mV;
+
+ vdd_uV = regulator_list_voltage(supply, i);
+ if (vdd_uV <= 0)
+ continue;
+
+ vdd_mV = vdd_uV / 1000;
+ result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV);
+ }
+
+ return result;
+}
+EXPORT_SYMBOL(mmc_regulator_get_ocrmask);
+
+/**
+ * mmc_regulator_set_ocr - set regulator to match host->ios voltage
+ * @vdd_bit: zero for power off, else a bit number (host->ios.vdd)
+ * @supply: regulator to use
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * MMC host drivers may use this to enable or disable a regulator using
+ * a particular supply voltage. This would normally be called from the
+ * set_ios() method.
+ */
+int mmc_regulator_set_ocr(struct regulator *supply, unsigned short vdd_bit)
+{
+ int result = 0;
+ int min_uV, max_uV;
+ int enabled;
+
+ enabled = regulator_is_enabled(supply);
+ if (enabled < 0)
+ return enabled;
+
+ if (vdd_bit) {
+ int tmp;
+ int voltage;
+
+ /* REVISIT mmc_vddrange_to_ocrmask() may have set some
+ * bits this regulator doesn't quite support ... don't
+ * be too picky, most cards and regulators are OK with
+ * a 0.1V range goof (it's a small error percentage).
+ */
+ tmp = vdd_bit - ilog2(MMC_VDD_165_195);
+ if (tmp == 0) {
+ min_uV = 1650 * 1000;
+ max_uV = 1950 * 1000;
+ } else {
+ min_uV = 1900 * 1000 + tmp * 100 * 1000;
+ max_uV = min_uV + 100 * 1000;
+ }
+
+ /* avoid needless changes to this voltage; the regulator
+ * might not allow this operation
+ */
+ voltage = regulator_get_voltage(supply);
+ if (voltage < 0)
+ result = voltage;
+ else if (voltage < min_uV || voltage > max_uV)
+ result = regulator_set_voltage(supply, min_uV, max_uV);
+ else
+ result = 0;
+
+ if (result == 0 && !enabled)
+ result = regulator_enable(supply);
+ } else if (enabled) {
+ result = regulator_disable(supply);
+ }
+
+ return result;
+}
+EXPORT_SYMBOL(mmc_regulator_set_ocr);
+
+#endif
+
/*
* Mask off any voltages we don't support and select
* the lowest voltage
@@ -815,6 +930,7 @@ void mmc_stop_host(struct mmc_host *host)
spin_unlock_irqrestore(&host->lock, flags);
#endif
+ cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
mmc_bus_get(host);
@@ -842,6 +958,7 @@ void mmc_stop_host(struct mmc_host *host)
*/
int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
{
+ cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
mmc_bus_get(host);
@@ -875,6 +992,7 @@ int mmc_resume_host(struct mmc_host *host)
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
mmc_power_up(host);
+ mmc_select_voltage(host, host->ocr);
BUG_ON(!host->bus_ops->resume);
host->bus_ops->resume(host);
}
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 1237bb4c722b..610dbd1fcc82 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -184,6 +184,68 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(mmc_dbg_card_status_fops, mmc_dbg_card_status_get,
NULL, "%08llx\n");
+#define EXT_CSD_STR_LEN 1025
+
+static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
+{
+ struct mmc_card *card = inode->i_private;
+ char *buf;
+ ssize_t n = 0;
+ u8 *ext_csd;
+ int err, i;
+
+ buf = kmalloc(EXT_CSD_STR_LEN + 1, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ ext_csd = kmalloc(512, GFP_KERNEL);
+ if (!ext_csd) {
+ err = -ENOMEM;
+ goto out_free;
+ }
+
+ mmc_claim_host(card->host);
+ err = mmc_send_ext_csd(card, ext_csd);
+ mmc_release_host(card->host);
+ if (err)
+ goto out_free;
+
+ for (i = 511; i >= 0; i--)
+ n += sprintf(buf + n, "%02x", ext_csd[i]);
+ n += sprintf(buf + n, "\n");
+ BUG_ON(n != EXT_CSD_STR_LEN);
+
+ filp->private_data = buf;
+ kfree(ext_csd);
+ return 0;
+
+out_free:
+ kfree(buf);
+ kfree(ext_csd);
+ return err;
+}
+
+static ssize_t mmc_ext_csd_read(struct file *filp, char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ char *buf = filp->private_data;
+
+ return simple_read_from_buffer(ubuf, cnt, ppos,
+ buf, EXT_CSD_STR_LEN);
+}
+
+static int mmc_ext_csd_release(struct inode *inode, struct file *file)
+{
+ kfree(file->private_data);
+ return 0;
+}
+
+static struct file_operations mmc_dbg_ext_csd_fops = {
+ .open = mmc_ext_csd_open,
+ .read = mmc_ext_csd_read,
+ .release = mmc_ext_csd_release,
+};
+
void mmc_add_card_debugfs(struct mmc_card *card)
{
struct mmc_host *host = card->host;
@@ -211,6 +273,11 @@ void mmc_add_card_debugfs(struct mmc_card *card)
&mmc_dbg_card_status_fops))
goto err;
+ if (mmc_card_mmc(card))
+ if (!debugfs_create_file("ext_csd", S_IRUSR, root, card,
+ &mmc_dbg_ext_csd_fops))
+ goto err;
+
return;
err:
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c
index 956bd7677502..963f2937c5e3 100644
--- a/drivers/mmc/core/sdio_cis.c
+++ b/drivers/mmc/core/sdio_cis.c
@@ -223,10 +223,18 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
if (tpl_code == 0xff)
break;
+ /* null entries have no link field or data */
+ if (tpl_code == 0x00)
+ continue;
+
ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_link);
if (ret)
break;
+ /* a size of 0xff also means we're done */
+ if (tpl_link == 0xff)
+ break;
+
this = kmalloc(sizeof(*this) + tpl_link, GFP_KERNEL);
if (!this)
return -ENOMEM;
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
index c8fa095a4488..4eb7825fd1a7 100644
--- a/drivers/mmc/core/sdio_ops.c
+++ b/drivers/mmc/core/sdio_ops.c
@@ -76,6 +76,10 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
BUG_ON(!card);
BUG_ON(fn > 7);
+ /* sanity check */
+ if (addr & ~0x1FFFF)
+ return -EINVAL;
+
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = SD_IO_RW_DIRECT;
@@ -125,6 +129,10 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
WARN_ON(blocks == 0);
WARN_ON(blksz == 0);
+ /* sanity check */
+ if (addr & ~0x1FFFF)
+ return -EINVAL;
+
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 99d4b28d52ed..b4cf691f3f64 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -37,6 +37,13 @@ config MMC_SDHCI
If unsure, say N.
+config MMC_SDHCI_IO_ACCESSORS
+ bool
+ depends on MMC_SDHCI
+ help
+ This is silent Kconfig symbol that is selected by the drivers that
+ need to overwrite SDHCI IO memory accessors.
+
config MMC_SDHCI_PCI
tristate "SDHCI support on PCI bus"
depends on MMC_SDHCI && PCI
@@ -65,6 +72,17 @@ config MMC_RICOH_MMC
If unsure, say Y.
+config MMC_SDHCI_OF
+ tristate "SDHCI support on OpenFirmware platforms"
+ depends on MMC_SDHCI && PPC_OF
+ select MMC_SDHCI_IO_ACCESSORS
+ help
+ This selects the OF support for Secure Digital Host Controller
+ Interfaces. So far, only the Freescale eSDHC controller is known
+ to exist on OF platforms.
+
+ If unsure, say N.
+
config MMC_OMAP
tristate "TI OMAP Multimedia Card Interface support"
depends on ARCH_OMAP
@@ -171,13 +189,24 @@ config MMC_TIFM_SD
To compile this driver as a module, choose M here: the
module will be called tifm_sd.
+config MMC_MVSDIO
+ tristate "Marvell MMC/SD/SDIO host driver"
+ depends on PLAT_ORION
+ ---help---
+ This selects the Marvell SDIO host driver.
+ SDIO may currently be found on the Kirkwood 88F6281 and 88F6192
+ SoC controllers.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mvsdio.
+
config MMC_SPI
tristate "MMC/SD/SDIO over SPI"
depends on SPI_MASTER && !HIGHMEM && HAS_DMA
select CRC7
select CRC_ITU_T
help
- Some systems accss MMC/SD/SDIO cards using a SPI controller
+ Some systems access MMC/SD/SDIO cards using a SPI controller
instead of using a "native" MMC/SD/SDIO controller. This has a
disadvantage of being relatively high overhead, but a compensating
advantage of working on many systems without dedicated MMC/SD/SDIO
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index dedec55861d9..970a997620e1 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o
+obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o
obj-$(CONFIG_MMC_WBSD) += wbsd.o
obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
obj-$(CONFIG_MMC_OMAP) += omap.o
@@ -20,6 +21,7 @@ obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o
obj-$(CONFIG_MMC_AT91) += at91_mci.o
obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o
obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
+obj-$(CONFIG_MMC_MVSDIO) += mvsdio.o
obj-$(CONFIG_MMC_SPI) += mmc_spi.o
ifeq ($(CONFIG_OF),y)
obj-$(CONFIG_MMC_SPI) += of_mmc_spi.o
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 2b1196e6142c..cf6a100bb38f 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -812,7 +812,7 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
slot->sdc_reg |= MCI_SDCBUS_1BIT;
break;
case MMC_BUS_WIDTH_4:
- slot->sdc_reg = MCI_SDCBUS_4BIT;
+ slot->sdc_reg |= MCI_SDCBUS_4BIT;
break;
}
@@ -1603,7 +1603,7 @@ static int __init atmci_probe(struct platform_device *pdev)
tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)host);
- ret = request_irq(irq, atmci_interrupt, 0, pdev->dev.bus_id, host);
+ ret = request_irq(irq, atmci_interrupt, 0, dev_name(&pdev->dev), host);
if (ret)
goto err_request_irq;
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 87e211df68ac..72f8bde4877a 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -279,8 +279,11 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
* so it can always DMA directly into the target buffer.
* It'd probably be better to memcpy() the first chunk and
* avoid extra i/o calls...
+ *
+ * Note we check for more than 8 bytes, because in practice,
+ * some SD cards are slow...
*/
- for (i = 2; i < 9; i++) {
+ for (i = 2; i < 16; i++) {
value = mmc_spi_readbytes(host, 1);
if (value < 0)
goto done;
@@ -609,6 +612,7 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
struct spi_device *spi = host->spi;
int status, i;
struct scratch *scratch = host->data;
+ u32 pattern;
if (host->mmc->use_spi_crc)
scratch->crc_val = cpu_to_be16(
@@ -636,8 +640,27 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
* doesn't necessarily tell whether the write operation succeeded;
* it just says if the transmission was ok and whether *earlier*
* writes succeeded; see the standard.
+ *
+ * In practice, there are (even modern SDHC-)cards which are late
+ * in sending the response, and miss the time frame by a few bits,
+ * so we have to cope with this situation and check the response
+ * bit-by-bit. Arggh!!!
*/
- switch (SPI_MMC_RESPONSE_CODE(scratch->status[0])) {
+ pattern = scratch->status[0] << 24;
+ pattern |= scratch->status[1] << 16;
+ pattern |= scratch->status[2] << 8;
+ pattern |= scratch->status[3];
+
+ /* First 3 bit of pattern are undefined */
+ pattern |= 0xE0000000;
+
+ /* left-adjust to leading 0 bit */
+ while (pattern & 0x80000000)
+ pattern <<= 1;
+ /* right-adjust for pattern matching. Code is in bit 4..0 now. */
+ pattern >>= 27;
+
+ switch (pattern) {
case SPI_RESPONSE_ACCEPTED:
status = 0;
break;
@@ -668,8 +691,9 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
/* Return when not busy. If we didn't collect that status yet,
* we'll need some more I/O.
*/
- for (i = 1; i < sizeof(scratch->status); i++) {
- if (scratch->status[i] != 0)
+ for (i = 4; i < sizeof(scratch->status); i++) {
+ /* card is non-busy if the most recent bit is 1 */
+ if (scratch->status[i] & 0x01)
return 0;
}
return mmc_spi_wait_unbusy(host, timeout);
@@ -1204,10 +1228,12 @@ static int mmc_spi_probe(struct spi_device *spi)
/* MMC and SD specs only seem to care that sampling is on the
* rising edge ... meaning SPI modes 0 or 3. So either SPI mode
- * should be legit. We'll use mode 0 since it seems to be a
- * bit less troublesome on some hardware ... unclear why.
+ * should be legit. We'll use mode 0 since the steady state is 0,
+ * which is appropriate for hotplugging, unless the platform data
+ * specify mode 3 (if hardware is not compatible to mode 0).
*/
- spi->mode = SPI_MODE_0;
+ if (spi->mode != SPI_MODE_3)
+ spi->mode = SPI_MODE_0;
spi->bits_per_word = 8;
status = spi_setup(spi);
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 2909bbc8ad00..a663429b3d55 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -490,7 +490,7 @@ static void mmci_check_status(unsigned long data)
mod_timer(&host->timer, jiffies + HZ);
}
-static int mmci_probe(struct amba_device *dev, void *id)
+static int __devinit mmci_probe(struct amba_device *dev, void *id)
{
struct mmc_platform_data *plat = dev->dev.platform_data;
struct mmci_host *host;
@@ -633,7 +633,7 @@ static int mmci_probe(struct amba_device *dev, void *id)
return ret;
}
-static int mmci_remove(struct amba_device *dev)
+static int __devexit mmci_remove(struct amba_device *dev)
{
struct mmc_host *mmc = amba_get_drvdata(dev);
@@ -730,7 +730,7 @@ static struct amba_driver mmci_driver = {
.name = DRIVER_NAME,
},
.probe = mmci_probe,
- .remove = mmci_remove,
+ .remove = __devexit_p(mmci_remove),
.suspend = mmci_suspend,
.resume = mmci_resume,
.id_table = mmci_ids,
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
new file mode 100644
index 000000000000..b5c375d94ab3
--- /dev/null
+++ b/drivers/mmc/host/mvsdio.c
@@ -0,0 +1,885 @@
+/*
+ * Marvell MMC/SD/SDIO driver
+ *
+ * Authors: Maen Suleiman, Nicolas Pitre
+ * Copyright (C) 2008-2009 Marvell Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/mbus.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+
+#include <asm/sizes.h>
+#include <asm/unaligned.h>
+#include <plat/mvsdio.h>
+
+#include "mvsdio.h"
+
+#define DRIVER_NAME "mvsdio"
+
+static int maxfreq = MVSD_CLOCKRATE_MAX;
+static int nodma;
+
+struct mvsd_host {
+ void __iomem *base;
+ struct mmc_request *mrq;
+ spinlock_t lock;
+ unsigned int xfer_mode;
+ unsigned int intr_en;
+ unsigned int ctrl;
+ unsigned int pio_size;
+ void *pio_ptr;
+ unsigned int sg_frags;
+ unsigned int ns_per_clk;
+ unsigned int clock;
+ unsigned int base_clock;
+ struct timer_list timer;
+ struct mmc_host *mmc;
+ struct device *dev;
+ struct resource *res;
+ int irq;
+ int gpio_card_detect;
+ int gpio_write_protect;
+};
+
+#define mvsd_write(offs, val) writel(val, iobase + (offs))
+#define mvsd_read(offs) readl(iobase + (offs))
+
+static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
+{
+ void __iomem *iobase = host->base;
+ unsigned int tmout;
+ int tmout_index;
+
+ /* If timeout=0 then maximum timeout index is used. */
+ tmout = DIV_ROUND_UP(data->timeout_ns, host->ns_per_clk);
+ tmout += data->timeout_clks;
+ tmout_index = fls(tmout - 1) - 12;
+ if (tmout_index < 0)
+ tmout_index = 0;
+ if (tmout_index > MVSD_HOST_CTRL_TMOUT_MAX)
+ tmout_index = MVSD_HOST_CTRL_TMOUT_MAX;
+
+ dev_dbg(host->dev, "data %s at 0x%08x: blocks=%d blksz=%d tmout=%u (%d)\n",
+ (data->flags & MMC_DATA_READ) ? "read" : "write",
+ (u32)sg_virt(data->sg), data->blocks, data->blksz,
+ tmout, tmout_index);
+
+ host->ctrl &= ~MVSD_HOST_CTRL_TMOUT_MASK;
+ host->ctrl |= MVSD_HOST_CTRL_TMOUT(tmout_index);
+ mvsd_write(MVSD_HOST_CTRL, host->ctrl);
+ mvsd_write(MVSD_BLK_COUNT, data->blocks);
+ mvsd_write(MVSD_BLK_SIZE, data->blksz);
+
+ if (nodma || (data->blksz | data->sg->offset) & 3) {
+ /*
+ * We cannot do DMA on a buffer which offset or size
+ * is not aligned on a 4-byte boundary.
+ */
+ host->pio_size = data->blocks * data->blksz;
+ host->pio_ptr = sg_virt(data->sg);
+ if (!nodma)
+ printk(KERN_DEBUG "%s: fallback to PIO for data "
+ "at 0x%p size %d\n",
+ mmc_hostname(host->mmc),
+ host->pio_ptr, host->pio_size);
+ return 1;
+ } else {
+ dma_addr_t phys_addr;
+ int dma_dir = (data->flags & MMC_DATA_READ) ?
+ DMA_FROM_DEVICE : DMA_TO_DEVICE;
+ host->sg_frags = dma_map_sg(mmc_dev(host->mmc), data->sg,
+ data->sg_len, dma_dir);
+ phys_addr = sg_dma_address(data->sg);
+ mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff);
+ mvsd_write(MVSD_SYS_ADDR_HI, (u32)phys_addr >> 16);
+ return 0;
+ }
+}
+
+static void mvsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ struct mvsd_host *host = mmc_priv(mmc);
+ void __iomem *iobase = host->base;
+ struct mmc_command *cmd = mrq->cmd;
+ u32 cmdreg = 0, xfer = 0, intr = 0;
+ unsigned long flags;
+
+ BUG_ON(host->mrq != NULL);
+ host->mrq = mrq;
+
+ dev_dbg(host->dev, "cmd %d (hw state 0x%04x)\n",
+ cmd->opcode, mvsd_read(MVSD_HW_STATE));
+
+ cmdreg = MVSD_CMD_INDEX(cmd->opcode);
+
+ if (cmd->flags & MMC_RSP_BUSY)
+ cmdreg |= MVSD_CMD_RSP_48BUSY;
+ else if (cmd->flags & MMC_RSP_136)
+ cmdreg |= MVSD_CMD_RSP_136;
+ else if (cmd->flags & MMC_RSP_PRESENT)
+ cmdreg |= MVSD_CMD_RSP_48;
+ else
+ cmdreg |= MVSD_CMD_RSP_NONE;
+
+ if (cmd->flags & MMC_RSP_CRC)
+ cmdreg |= MVSD_CMD_CHECK_CMDCRC;
+
+ if (cmd->flags & MMC_RSP_OPCODE)
+ cmdreg |= MVSD_CMD_INDX_CHECK;
+
+ if (cmd->flags & MMC_RSP_PRESENT) {
+ cmdreg |= MVSD_UNEXPECTED_RESP;
+ intr |= MVSD_NOR_UNEXP_RSP;
+ }
+
+ if (mrq->data) {
+ struct mmc_data *data = mrq->data;
+ int pio;
+
+ cmdreg |= MVSD_CMD_DATA_PRESENT | MVSD_CMD_CHECK_DATACRC16;
+ xfer |= MVSD_XFER_MODE_HW_WR_DATA_EN;
+ if (data->flags & MMC_DATA_READ)
+ xfer |= MVSD_XFER_MODE_TO_HOST;
+
+ pio = mvsd_setup_data(host, data);
+ if (pio) {
+ xfer |= MVSD_XFER_MODE_PIO;
+ /* PIO section of mvsd_irq has comments on those bits */
+ if (data->flags & MMC_DATA_WRITE)
+ intr |= MVSD_NOR_TX_AVAIL;
+ else if (host->pio_size > 32)
+ intr |= MVSD_NOR_RX_FIFO_8W;
+ else
+ intr |= MVSD_NOR_RX_READY;
+ }
+
+ if (data->stop) {
+ struct mmc_command *stop = data->stop;
+ u32 cmd12reg = 0;
+
+ mvsd_write(MVSD_AUTOCMD12_ARG_LOW, stop->arg & 0xffff);
+ mvsd_write(MVSD_AUTOCMD12_ARG_HI, stop->arg >> 16);
+
+ if (stop->flags & MMC_RSP_BUSY)
+ cmd12reg |= MVSD_AUTOCMD12_BUSY;
+ if (stop->flags & MMC_RSP_OPCODE)
+ cmd12reg |= MVSD_AUTOCMD12_INDX_CHECK;
+ cmd12reg |= MVSD_AUTOCMD12_INDEX(stop->opcode);
+ mvsd_write(MVSD_AUTOCMD12_CMD, cmd12reg);
+
+ xfer |= MVSD_XFER_MODE_AUTO_CMD12;
+ intr |= MVSD_NOR_AUTOCMD12_DONE;
+ } else {
+ intr |= MVSD_NOR_XFER_DONE;
+ }
+ } else {
+ intr |= MVSD_NOR_CMD_DONE;
+ }
+
+ mvsd_write(MVSD_ARG_LOW, cmd->arg & 0xffff);
+ mvsd_write(MVSD_ARG_HI, cmd->arg >> 16);
+
+ spin_lock_irqsave(&host->lock, flags);
+
+ host->xfer_mode &= MVSD_XFER_MODE_INT_CHK_EN;
+ host->xfer_mode |= xfer;
+ mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+
+ mvsd_write(MVSD_NOR_INTR_STATUS, ~MVSD_NOR_CARD_INT);
+ mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+ mvsd_write(MVSD_CMD, cmdreg);
+
+ host->intr_en &= MVSD_NOR_CARD_INT;
+ host->intr_en |= intr | MVSD_NOR_ERROR;
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ mvsd_write(MVSD_ERR_INTR_EN, 0xffff);
+
+ mod_timer(&host->timer, jiffies + 5 * HZ);
+
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static u32 mvsd_finish_cmd(struct mvsd_host *host, struct mmc_command *cmd,
+ u32 err_status)
+{
+ void __iomem *iobase = host->base;
+
+ if (cmd->flags & MMC_RSP_136) {
+ unsigned int response[8], i;
+ for (i = 0; i < 8; i++)
+ response[i] = mvsd_read(MVSD_RSP(i));
+ cmd->resp[0] = ((response[0] & 0x03ff) << 22) |
+ ((response[1] & 0xffff) << 6) |
+ ((response[2] & 0xfc00) >> 10);
+ cmd->resp[1] = ((response[2] & 0x03ff) << 22) |
+ ((response[3] & 0xffff) << 6) |
+ ((response[4] & 0xfc00) >> 10);
+ cmd->resp[2] = ((response[4] & 0x03ff) << 22) |
+ ((response[5] & 0xffff) << 6) |
+ ((response[6] & 0xfc00) >> 10);
+ cmd->resp[3] = ((response[6] & 0x03ff) << 22) |
+ ((response[7] & 0x3fff) << 8);
+ } else if (cmd->flags & MMC_RSP_PRESENT) {
+ unsigned int response[3], i;
+ for (i = 0; i < 3; i++)
+ response[i] = mvsd_read(MVSD_RSP(i));
+ cmd->resp[0] = ((response[2] & 0x003f) << (8 - 8)) |
+ ((response[1] & 0xffff) << (14 - 8)) |
+ ((response[0] & 0x03ff) << (30 - 8));
+ cmd->resp[1] = ((response[0] & 0xfc00) >> 10);
+ cmd->resp[2] = 0;
+ cmd->resp[3] = 0;
+ }
+
+ if (err_status & MVSD_ERR_CMD_TIMEOUT) {
+ cmd->error = -ETIMEDOUT;
+ } else if (err_status & (MVSD_ERR_CMD_CRC | MVSD_ERR_CMD_ENDBIT |
+ MVSD_ERR_CMD_INDEX | MVSD_ERR_CMD_STARTBIT)) {
+ cmd->error = -EILSEQ;
+ }
+ err_status &= ~(MVSD_ERR_CMD_TIMEOUT | MVSD_ERR_CMD_CRC |
+ MVSD_ERR_CMD_ENDBIT | MVSD_ERR_CMD_INDEX |
+ MVSD_ERR_CMD_STARTBIT);
+
+ return err_status;
+}
+
+static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
+ u32 err_status)
+{
+ void __iomem *iobase = host->base;
+
+ if (host->pio_ptr) {
+ host->pio_ptr = NULL;
+ host->pio_size = 0;
+ } else {
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags,
+ (data->flags & MMC_DATA_READ) ?
+ DMA_FROM_DEVICE : DMA_TO_DEVICE);
+ }
+
+ if (err_status & MVSD_ERR_DATA_TIMEOUT)
+ data->error = -ETIMEDOUT;
+ else if (err_status & (MVSD_ERR_DATA_CRC | MVSD_ERR_DATA_ENDBIT))
+ data->error = -EILSEQ;
+ else if (err_status & MVSD_ERR_XFER_SIZE)
+ data->error = -EBADE;
+ err_status &= ~(MVSD_ERR_DATA_TIMEOUT | MVSD_ERR_DATA_CRC |
+ MVSD_ERR_DATA_ENDBIT | MVSD_ERR_XFER_SIZE);
+
+ dev_dbg(host->dev, "data done: blocks_left=%d, bytes_left=%d\n",
+ mvsd_read(MVSD_CURR_BLK_LEFT), mvsd_read(MVSD_CURR_BYTE_LEFT));
+ data->bytes_xfered =
+ (data->blocks - mvsd_read(MVSD_CURR_BLK_LEFT)) * data->blksz;
+ /* We can't be sure about the last block when errors are detected */
+ if (data->bytes_xfered && data->error)
+ data->bytes_xfered -= data->blksz;
+
+ /* Handle Auto cmd 12 response */
+ if (data->stop) {
+ unsigned int response[3], i;
+ for (i = 0; i < 3; i++)
+ response[i] = mvsd_read(MVSD_AUTO_RSP(i));
+ data->stop->resp[0] = ((response[2] & 0x003f) << (8 - 8)) |
+ ((response[1] & 0xffff) << (14 - 8)) |
+ ((response[0] & 0x03ff) << (30 - 8));
+ data->stop->resp[1] = ((response[0] & 0xfc00) >> 10);
+ data->stop->resp[2] = 0;
+ data->stop->resp[3] = 0;
+
+ if (err_status & MVSD_ERR_AUTOCMD12) {
+ u32 err_cmd12 = mvsd_read(MVSD_AUTOCMD12_ERR_STATUS);
+ dev_dbg(host->dev, "c12err 0x%04x\n", err_cmd12);
+ if (err_cmd12 & MVSD_AUTOCMD12_ERR_NOTEXE)
+ data->stop->error = -ENOEXEC;
+ else if (err_cmd12 & MVSD_AUTOCMD12_ERR_TIMEOUT)
+ data->stop->error = -ETIMEDOUT;
+ else if (err_cmd12)
+ data->stop->error = -EILSEQ;
+ err_status &= ~MVSD_ERR_AUTOCMD12;
+ }
+ }
+
+ return err_status;
+}
+
+static irqreturn_t mvsd_irq(int irq, void *dev)
+{
+ struct mvsd_host *host = dev;
+ void __iomem *iobase = host->base;
+ u32 intr_status, intr_done_mask;
+ int irq_handled = 0;
+
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ dev_dbg(host->dev, "intr 0x%04x intr_en 0x%04x hw_state 0x%04x\n",
+ intr_status, mvsd_read(MVSD_NOR_INTR_EN),
+ mvsd_read(MVSD_HW_STATE));
+
+ spin_lock(&host->lock);
+
+ /* PIO handling, if needed. Messy business... */
+ if (host->pio_size &&
+ (intr_status & host->intr_en &
+ (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) {
+ u16 *p = host->pio_ptr;
+ int s = host->pio_size;
+ while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) {
+ readsw(iobase + MVSD_FIFO, p, 16);
+ p += 16;
+ s -= 32;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ /*
+ * Normally we'd use < 32 here, but the RX_FIFO_8W bit
+ * doesn't appear to assert when there is exactly 32 bytes
+ * (8 words) left to fetch in a transfer.
+ */
+ if (s <= 32) {
+ while (s >= 4 && (intr_status & MVSD_NOR_RX_READY)) {
+ put_unaligned(mvsd_read(MVSD_FIFO), p++);
+ put_unaligned(mvsd_read(MVSD_FIFO), p++);
+ s -= 4;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ if (s && s < 4 && (intr_status & MVSD_NOR_RX_READY)) {
+ u16 val[2] = {0, 0};
+ val[0] = mvsd_read(MVSD_FIFO);
+ val[1] = mvsd_read(MVSD_FIFO);
+ memcpy(p, &val, s);
+ s = 0;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ if (s == 0) {
+ host->intr_en &=
+ ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W);
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ } else if (host->intr_en & MVSD_NOR_RX_FIFO_8W) {
+ host->intr_en &= ~MVSD_NOR_RX_FIFO_8W;
+ host->intr_en |= MVSD_NOR_RX_READY;
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ }
+ }
+ dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
+ s, intr_status, mvsd_read(MVSD_HW_STATE));
+ host->pio_ptr = p;
+ host->pio_size = s;
+ irq_handled = 1;
+ } else if (host->pio_size &&
+ (intr_status & host->intr_en &
+ (MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) {
+ u16 *p = host->pio_ptr;
+ int s = host->pio_size;
+ /*
+ * The TX_FIFO_8W bit is unreliable. When set, bursting
+ * 16 halfwords all at once in the FIFO drops data. Actually
+ * TX_AVAIL does go off after only one word is pushed even if
+ * TX_FIFO_8W remains set.
+ */
+ while (s >= 4 && (intr_status & MVSD_NOR_TX_AVAIL)) {
+ mvsd_write(MVSD_FIFO, get_unaligned(p++));
+ mvsd_write(MVSD_FIFO, get_unaligned(p++));
+ s -= 4;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ if (s < 4) {
+ if (s && (intr_status & MVSD_NOR_TX_AVAIL)) {
+ u16 val[2] = {0, 0};
+ memcpy(&val, p, s);
+ mvsd_write(MVSD_FIFO, val[0]);
+ mvsd_write(MVSD_FIFO, val[1]);
+ s = 0;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ if (s == 0) {
+ host->intr_en &=
+ ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ }
+ }
+ dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
+ s, intr_status, mvsd_read(MVSD_HW_STATE));
+ host->pio_ptr = p;
+ host->pio_size = s;
+ irq_handled = 1;
+ }
+
+ mvsd_write(MVSD_NOR_INTR_STATUS, intr_status);
+
+ intr_done_mask = MVSD_NOR_CARD_INT | MVSD_NOR_RX_READY |
+ MVSD_NOR_RX_FIFO_8W | MVSD_NOR_TX_FIFO_8W;
+ if (intr_status & host->intr_en & ~intr_done_mask) {
+ struct mmc_request *mrq = host->mrq;
+ struct mmc_command *cmd = mrq->cmd;
+ u32 err_status = 0;
+
+ del_timer(&host->timer);
+ host->mrq = NULL;
+
+ host->intr_en &= MVSD_NOR_CARD_INT;
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ mvsd_write(MVSD_ERR_INTR_EN, 0);
+
+ spin_unlock(&host->lock);
+
+ if (intr_status & MVSD_NOR_UNEXP_RSP) {
+ cmd->error = -EPROTO;
+ } else if (intr_status & MVSD_NOR_ERROR) {
+ err_status = mvsd_read(MVSD_ERR_INTR_STATUS);
+ dev_dbg(host->dev, "err 0x%04x\n", err_status);
+ }
+
+ err_status = mvsd_finish_cmd(host, cmd, err_status);
+ if (mrq->data)
+ err_status = mvsd_finish_data(host, mrq->data, err_status);
+ if (err_status) {
+ printk(KERN_ERR "%s: unhandled error status %#04x\n",
+ mmc_hostname(host->mmc), err_status);
+ cmd->error = -ENOMSG;
+ }
+
+ mmc_request_done(host->mmc, mrq);
+ irq_handled = 1;
+ } else
+ spin_unlock(&host->lock);
+
+ if (intr_status & MVSD_NOR_CARD_INT) {
+ mmc_signal_sdio_irq(host->mmc);
+ irq_handled = 1;
+ }
+
+ if (irq_handled)
+ return IRQ_HANDLED;
+
+ printk(KERN_ERR "%s: unhandled interrupt status=0x%04x en=0x%04x "
+ "pio=%d\n", mmc_hostname(host->mmc), intr_status,
+ host->intr_en, host->pio_size);
+ return IRQ_NONE;
+}
+
+static void mvsd_timeout_timer(unsigned long data)
+{
+ struct mvsd_host *host = (struct mvsd_host *)data;
+ void __iomem *iobase = host->base;
+ struct mmc_request *mrq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ mrq = host->mrq;
+ if (mrq) {
+ printk(KERN_ERR "%s: Timeout waiting for hardware interrupt.\n",
+ mmc_hostname(host->mmc));
+ printk(KERN_ERR "%s: hw_state=0x%04x, intr_status=0x%04x "
+ "intr_en=0x%04x\n", mmc_hostname(host->mmc),
+ mvsd_read(MVSD_HW_STATE),
+ mvsd_read(MVSD_NOR_INTR_STATUS),
+ mvsd_read(MVSD_NOR_INTR_EN));
+
+ host->mrq = NULL;
+
+ mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+
+ host->xfer_mode &= MVSD_XFER_MODE_INT_CHK_EN;
+ mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+
+ host->intr_en &= MVSD_NOR_CARD_INT;
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ mvsd_write(MVSD_ERR_INTR_EN, 0);
+ mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+
+ mrq->cmd->error = -ETIMEDOUT;
+ mvsd_finish_cmd(host, mrq->cmd, 0);
+ if (mrq->data) {
+ mrq->data->error = -ETIMEDOUT;
+ mvsd_finish_data(host, mrq->data, 0);
+ }
+ }
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ if (mrq)
+ mmc_request_done(host->mmc, mrq);
+}
+
+static irqreturn_t mvsd_card_detect_irq(int irq, void *dev)
+{
+ struct mvsd_host *host = dev;
+ mmc_detect_change(host->mmc, msecs_to_jiffies(100));
+ return IRQ_HANDLED;
+}
+
+static void mvsd_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+ struct mvsd_host *host = mmc_priv(mmc);
+ void __iomem *iobase = host->base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ if (enable) {
+ host->xfer_mode |= MVSD_XFER_MODE_INT_CHK_EN;
+ host->intr_en |= MVSD_NOR_CARD_INT;
+ } else {
+ host->xfer_mode &= ~MVSD_XFER_MODE_INT_CHK_EN;
+ host->intr_en &= ~MVSD_NOR_CARD_INT;
+ }
+ mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static int mvsd_get_ro(struct mmc_host *mmc)
+{
+ struct mvsd_host *host = mmc_priv(mmc);
+
+ if (host->gpio_write_protect)
+ return gpio_get_value(host->gpio_write_protect);
+
+ /*
+ * Board doesn't support read only detection; let the mmc core
+ * decide what to do.
+ */
+ return -ENOSYS;
+}
+
+static void mvsd_power_up(struct mvsd_host *host)
+{
+ void __iomem *iobase = host->base;
+ dev_dbg(host->dev, "power up\n");
+ mvsd_write(MVSD_NOR_INTR_EN, 0);
+ mvsd_write(MVSD_ERR_INTR_EN, 0);
+ mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+ mvsd_write(MVSD_XFER_MODE, 0);
+ mvsd_write(MVSD_NOR_STATUS_EN, 0xffff);
+ mvsd_write(MVSD_ERR_STATUS_EN, 0xffff);
+ mvsd_write(MVSD_NOR_INTR_STATUS, 0xffff);
+ mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+}
+
+static void mvsd_power_down(struct mvsd_host *host)
+{
+ void __iomem *iobase = host->base;
+ dev_dbg(host->dev, "power down\n");
+ mvsd_write(MVSD_NOR_INTR_EN, 0);
+ mvsd_write(MVSD_ERR_INTR_EN, 0);
+ mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+ mvsd_write(MVSD_XFER_MODE, MVSD_XFER_MODE_STOP_CLK);
+ mvsd_write(MVSD_NOR_STATUS_EN, 0);
+ mvsd_write(MVSD_ERR_STATUS_EN, 0);
+ mvsd_write(MVSD_NOR_INTR_STATUS, 0xffff);
+ mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+}
+
+static void mvsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct mvsd_host *host = mmc_priv(mmc);
+ void __iomem *iobase = host->base;
+ u32 ctrl_reg = 0;
+
+ if (ios->power_mode == MMC_POWER_UP)
+ mvsd_power_up(host);
+
+ if (ios->clock == 0) {
+ mvsd_write(MVSD_XFER_MODE, MVSD_XFER_MODE_STOP_CLK);
+ mvsd_write(MVSD_CLK_DIV, MVSD_BASE_DIV_MAX);
+ host->clock = 0;
+ dev_dbg(host->dev, "clock off\n");
+ } else if (ios->clock != host->clock) {
+ u32 m = DIV_ROUND_UP(host->base_clock, ios->clock) - 1;
+ if (m > MVSD_BASE_DIV_MAX)
+ m = MVSD_BASE_DIV_MAX;
+ mvsd_write(MVSD_CLK_DIV, m);
+ host->clock = ios->clock;
+ host->ns_per_clk = 1000000000 / (host->base_clock / (m+1));
+ dev_dbg(host->dev, "clock=%d (%d), div=0x%04x\n",
+ ios->clock, host->base_clock / (m+1), m);
+ }
+
+ /* default transfer mode */
+ ctrl_reg |= MVSD_HOST_CTRL_BIG_ENDIAN;
+ ctrl_reg &= ~MVSD_HOST_CTRL_LSB_FIRST;
+
+ /* default to maximum timeout */
+ ctrl_reg |= MVSD_HOST_CTRL_TMOUT_MASK;
+ ctrl_reg |= MVSD_HOST_CTRL_TMOUT_EN;
+
+ if (ios->bus_mode == MMC_BUSMODE_PUSHPULL)
+ ctrl_reg |= MVSD_HOST_CTRL_PUSH_PULL_EN;
+
+ if (ios->bus_width == MMC_BUS_WIDTH_4)
+ ctrl_reg |= MVSD_HOST_CTRL_DATA_WIDTH_4_BITS;
+
+ if (ios->timing == MMC_TIMING_MMC_HS ||
+ ios->timing == MMC_TIMING_SD_HS)
+ ctrl_reg |= MVSD_HOST_CTRL_HI_SPEED_EN;
+
+ host->ctrl = ctrl_reg;
+ mvsd_write(MVSD_HOST_CTRL, ctrl_reg);
+ dev_dbg(host->dev, "ctrl 0x%04x: %s %s %s\n", ctrl_reg,
+ (ctrl_reg & MVSD_HOST_CTRL_PUSH_PULL_EN) ?
+ "push-pull" : "open-drain",
+ (ctrl_reg & MVSD_HOST_CTRL_DATA_WIDTH_4_BITS) ?
+ "4bit-width" : "1bit-width",
+ (ctrl_reg & MVSD_HOST_CTRL_HI_SPEED_EN) ?
+ "high-speed" : "");
+
+ if (ios->power_mode == MMC_POWER_OFF)
+ mvsd_power_down(host);
+}
+
+static const struct mmc_host_ops mvsd_ops = {
+ .request = mvsd_request,
+ .get_ro = mvsd_get_ro,
+ .set_ios = mvsd_set_ios,
+ .enable_sdio_irq = mvsd_enable_sdio_irq,
+};
+
+static void __init mv_conf_mbus_windows(struct mvsd_host *host,
+ struct mbus_dram_target_info *dram)
+{
+ void __iomem *iobase = host->base;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ writel(0, iobase + MVSD_WINDOW_CTRL(i));
+ writel(0, iobase + MVSD_WINDOW_BASE(i));
+ }
+
+ for (i = 0; i < dram->num_cs; i++) {
+ struct mbus_dram_window *cs = dram->cs + i;
+ writel(((cs->size - 1) & 0xffff0000) |
+ (cs->mbus_attr << 8) |
+ (dram->mbus_dram_target_id << 4) | 1,
+ iobase + MVSD_WINDOW_CTRL(i));
+ writel(cs->base, iobase + MVSD_WINDOW_BASE(i));
+ }
+}
+
+static int __init mvsd_probe(struct platform_device *pdev)
+{
+ struct mmc_host *mmc = NULL;
+ struct mvsd_host *host = NULL;
+ const struct mvsdio_platform_data *mvsd_data;
+ struct resource *r;
+ int ret, irq;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ mvsd_data = pdev->dev.platform_data;
+ if (!r || irq < 0 || !mvsd_data)
+ return -ENXIO;
+
+ r = request_mem_region(r->start, SZ_1K, DRIVER_NAME);
+ if (!r)
+ return -EBUSY;
+
+ mmc = mmc_alloc_host(sizeof(struct mvsd_host), &pdev->dev);
+ if (!mmc) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ host = mmc_priv(mmc);
+ host->mmc = mmc;
+ host->dev = &pdev->dev;
+ host->res = r;
+ host->base_clock = mvsd_data->clock / 2;
+
+ mmc->ops = &mvsd_ops;
+
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ |
+ MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
+
+ mmc->f_min = DIV_ROUND_UP(host->base_clock, MVSD_BASE_DIV_MAX);
+ mmc->f_max = maxfreq;
+
+ mmc->max_blk_size = 2048;
+ mmc->max_blk_count = 65535;
+
+ mmc->max_hw_segs = 1;
+ mmc->max_phys_segs = 1;
+ mmc->max_seg_size = mmc->max_blk_size * mmc->max_blk_count;
+ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+
+ spin_lock_init(&host->lock);
+
+ host->base = ioremap(r->start, SZ_4K);
+ if (!host->base) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* (Re-)program MBUS remapping windows if we are asked to. */
+ if (mvsd_data->dram != NULL)
+ mv_conf_mbus_windows(host, mvsd_data->dram);
+
+ mvsd_power_down(host);
+
+ ret = request_irq(irq, mvsd_irq, 0, DRIVER_NAME, host);
+ if (ret) {
+ printk(KERN_ERR "%s: cannot assign irq %d\n", DRIVER_NAME, irq);
+ goto out;
+ } else
+ host->irq = irq;
+
+ if (mvsd_data->gpio_card_detect) {
+ ret = gpio_request(mvsd_data->gpio_card_detect,
+ DRIVER_NAME " cd");
+ if (ret == 0) {
+ gpio_direction_input(mvsd_data->gpio_card_detect);
+ irq = gpio_to_irq(mvsd_data->gpio_card_detect);
+ ret = request_irq(irq, mvsd_card_detect_irq,
+ IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING,
+ DRIVER_NAME " cd", host);
+ if (ret == 0)
+ host->gpio_card_detect =
+ mvsd_data->gpio_card_detect;
+ else
+ gpio_free(mvsd_data->gpio_card_detect);
+ }
+ }
+ if (!host->gpio_card_detect)
+ mmc->caps |= MMC_CAP_NEEDS_POLL;
+
+ if (mvsd_data->gpio_write_protect) {
+ ret = gpio_request(mvsd_data->gpio_write_protect,
+ DRIVER_NAME " wp");
+ if (ret == 0) {
+ gpio_direction_input(mvsd_data->gpio_write_protect);
+ host->gpio_write_protect =
+ mvsd_data->gpio_write_protect;
+ }
+ }
+
+ setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host);
+ platform_set_drvdata(pdev, mmc);
+ ret = mmc_add_host(mmc);
+ if (ret)
+ goto out;
+
+ printk(KERN_NOTICE "%s: %s driver initialized, ",
+ mmc_hostname(mmc), DRIVER_NAME);
+ if (host->gpio_card_detect)
+ printk("using GPIO %d for card detection\n",
+ host->gpio_card_detect);
+ else
+ printk("lacking card detect (fall back to polling)\n");
+ return 0;
+
+out:
+ if (host) {
+ if (host->irq)
+ free_irq(host->irq, host);
+ if (host->gpio_card_detect) {
+ free_irq(gpio_to_irq(host->gpio_card_detect), host);
+ gpio_free(host->gpio_card_detect);
+ }
+ if (host->gpio_write_protect)
+ gpio_free(host->gpio_write_protect);
+ if (host->base)
+ iounmap(host->base);
+ }
+ if (r)
+ release_resource(r);
+ if (mmc)
+ mmc_free_host(mmc);
+
+ return ret;
+}
+
+static int __exit mvsd_remove(struct platform_device *pdev)
+{
+ struct mmc_host *mmc = platform_get_drvdata(pdev);
+
+ if (mmc) {
+ struct mvsd_host *host = mmc_priv(mmc);
+
+ if (host->gpio_card_detect) {
+ free_irq(gpio_to_irq(host->gpio_card_detect), host);
+ gpio_free(host->gpio_card_detect);
+ }
+ mmc_remove_host(mmc);
+ free_irq(host->irq, host);
+ if (host->gpio_write_protect)
+ gpio_free(host->gpio_write_protect);
+ del_timer_sync(&host->timer);
+ mvsd_power_down(host);
+ iounmap(host->base);
+ release_resource(host->res);
+ mmc_free_host(mmc);
+ }
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int mvsd_suspend(struct platform_device *dev, pm_message_t state,
+ u32 level)
+{
+ struct mmc_host *mmc = platform_get_drvdata(dev);
+ int ret = 0;
+
+ if (mmc && level == SUSPEND_DISABLE)
+ ret = mmc_suspend_host(mmc, state);
+
+ return ret;
+}
+
+static int mvsd_resume(struct platform_device *dev, u32 level)
+{
+ struct mmc_host *mmc = platform_dev_get_drvdata(dev);
+ int ret = 0;
+
+ if (mmc && level == RESUME_ENABLE)
+ ret = mmc_resume_host(mmc);
+
+ return ret;
+}
+#else
+#define mvsd_suspend NULL
+#define mvsd_resume NULL
+#endif
+
+static struct platform_driver mvsd_driver = {
+ .remove = __exit_p(mvsd_remove),
+ .suspend = mvsd_suspend,
+ .resume = mvsd_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ },
+};
+
+static int __init mvsd_init(void)
+{
+ return platform_driver_probe(&mvsd_driver, mvsd_probe);
+}
+
+static void __exit mvsd_exit(void)
+{
+ platform_driver_unregister(&mvsd_driver);
+}
+
+module_init(mvsd_init);
+module_exit(mvsd_exit);
+
+/* maximum card clock frequency (default 50MHz) */
+module_param(maxfreq, int, 0);
+
+/* force PIO transfers all the time */
+module_param(nodma, int, 0);
+
+MODULE_AUTHOR("Maen Suleiman, Nicolas Pitre");
+MODULE_DESCRIPTION("Marvell MMC,SD,SDIO Host Controller driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/mvsdio.h b/drivers/mmc/host/mvsdio.h
new file mode 100644
index 000000000000..7d9727b9f5aa
--- /dev/null
+++ b/drivers/mmc/host/mvsdio.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2008 Marvell Semiconductors, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MVSDIO_H
+#define __MVSDIO_H
+
+/*
+ * Clock rates
+ */
+
+#define MVSD_CLOCKRATE_MAX 50000000
+#define MVSD_BASE_DIV_MAX 0x7ff
+
+
+/*
+ * Register offsets
+ */
+
+#define MVSD_SYS_ADDR_LOW 0x000
+#define MVSD_SYS_ADDR_HI 0x004
+#define MVSD_BLK_SIZE 0x008
+#define MVSD_BLK_COUNT 0x00c
+#define MVSD_ARG_LOW 0x010
+#define MVSD_ARG_HI 0x014
+#define MVSD_XFER_MODE 0x018
+#define MVSD_CMD 0x01c
+#define MVSD_RSP(i) (0x020 + ((i)<<2))
+#define MVSD_RSP0 0x020
+#define MVSD_RSP1 0x024
+#define MVSD_RSP2 0x028
+#define MVSD_RSP3 0x02c
+#define MVSD_RSP4 0x030
+#define MVSD_RSP5 0x034
+#define MVSD_RSP6 0x038
+#define MVSD_RSP7 0x03c
+#define MVSD_FIFO 0x040
+#define MVSD_RSP_CRC7 0x044
+#define MVSD_HW_STATE 0x048
+#define MVSD_HOST_CTRL 0x050
+#define MVSD_BLK_GAP_CTRL 0x054
+#define MVSD_CLK_CTRL 0x058
+#define MVSD_SW_RESET 0x05c
+#define MVSD_NOR_INTR_STATUS 0x060
+#define MVSD_ERR_INTR_STATUS 0x064
+#define MVSD_NOR_STATUS_EN 0x068
+#define MVSD_ERR_STATUS_EN 0x06c
+#define MVSD_NOR_INTR_EN 0x070
+#define MVSD_ERR_INTR_EN 0x074
+#define MVSD_AUTOCMD12_ERR_STATUS 0x078
+#define MVSD_CURR_BYTE_LEFT 0x07c
+#define MVSD_CURR_BLK_LEFT 0x080
+#define MVSD_AUTOCMD12_ARG_LOW 0x084
+#define MVSD_AUTOCMD12_ARG_HI 0x088
+#define MVSD_AUTOCMD12_CMD 0x08c
+#define MVSD_AUTO_RSP(i) (0x090 + ((i)<<2))
+#define MVSD_AUTO_RSP0 0x090
+#define MVSD_AUTO_RSP1 0x094
+#define MVSD_AUTO_RSP2 0x098
+#define MVSD_CLK_DIV 0x128
+
+#define MVSD_WINDOW_CTRL(i) (0x108 + ((i) << 3))
+#define MVSD_WINDOW_BASE(i) (0x10c + ((i) << 3))
+
+
+/*
+ * MVSD_CMD
+ */
+
+#define MVSD_CMD_RSP_NONE (0 << 0)
+#define MVSD_CMD_RSP_136 (1 << 0)
+#define MVSD_CMD_RSP_48 (2 << 0)
+#define MVSD_CMD_RSP_48BUSY (3 << 0)
+
+#define MVSD_CMD_CHECK_DATACRC16 (1 << 2)
+#define MVSD_CMD_CHECK_CMDCRC (1 << 3)
+#define MVSD_CMD_INDX_CHECK (1 << 4)
+#define MVSD_CMD_DATA_PRESENT (1 << 5)
+#define MVSD_UNEXPECTED_RESP (1 << 7)
+#define MVSD_CMD_INDEX(x) ((x) << 8)
+
+
+/*
+ * MVSD_AUTOCMD12_CMD
+ */
+
+#define MVSD_AUTOCMD12_BUSY (1 << 0)
+#define MVSD_AUTOCMD12_INDX_CHECK (1 << 1)
+#define MVSD_AUTOCMD12_INDEX(x) ((x) << 8)
+
+/*
+ * MVSD_XFER_MODE
+ */
+
+#define MVSD_XFER_MODE_WR_DATA_START (1 << 0)
+#define MVSD_XFER_MODE_HW_WR_DATA_EN (1 << 1)
+#define MVSD_XFER_MODE_AUTO_CMD12 (1 << 2)
+#define MVSD_XFER_MODE_INT_CHK_EN (1 << 3)
+#define MVSD_XFER_MODE_TO_HOST (1 << 4)
+#define MVSD_XFER_MODE_STOP_CLK (1 << 5)
+#define MVSD_XFER_MODE_PIO (1 << 6)
+
+
+/*
+ * MVSD_HOST_CTRL
+ */
+
+#define MVSD_HOST_CTRL_PUSH_PULL_EN (1 << 0)
+
+#define MVSD_HOST_CTRL_CARD_TYPE_MEM_ONLY (0 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_ONLY (1 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_MEM_COMBO (2 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_MMC (3 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_MASK (3 << 1)
+
+#define MVSD_HOST_CTRL_BIG_ENDIAN (1 << 3)
+#define MVSD_HOST_CTRL_LSB_FIRST (1 << 4)
+#define MVSD_HOST_CTRL_DATA_WIDTH_4_BITS (1 << 9)
+#define MVSD_HOST_CTRL_HI_SPEED_EN (1 << 10)
+
+#define MVSD_HOST_CTRL_TMOUT_MAX 0xf
+#define MVSD_HOST_CTRL_TMOUT_MASK (0xf << 11)
+#define MVSD_HOST_CTRL_TMOUT(x) ((x) << 11)
+#define MVSD_HOST_CTRL_TMOUT_EN (1 << 15)
+
+
+/*
+ * MVSD_SW_RESET
+ */
+
+#define MVSD_SW_RESET_NOW (1 << 8)
+
+
+/*
+ * Normal interrupt status bits
+ */
+
+#define MVSD_NOR_CMD_DONE (1 << 0)
+#define MVSD_NOR_XFER_DONE (1 << 1)
+#define MVSD_NOR_BLK_GAP_EVT (1 << 2)
+#define MVSD_NOR_DMA_DONE (1 << 3)
+#define MVSD_NOR_TX_AVAIL (1 << 4)
+#define MVSD_NOR_RX_READY (1 << 5)
+#define MVSD_NOR_CARD_INT (1 << 8)
+#define MVSD_NOR_READ_WAIT_ON (1 << 9)
+#define MVSD_NOR_RX_FIFO_8W (1 << 10)
+#define MVSD_NOR_TX_FIFO_8W (1 << 11)
+#define MVSD_NOR_SUSPEND_ON (1 << 12)
+#define MVSD_NOR_AUTOCMD12_DONE (1 << 13)
+#define MVSD_NOR_UNEXP_RSP (1 << 14)
+#define MVSD_NOR_ERROR (1 << 15)
+
+
+/*
+ * Error status bits
+ */
+
+#define MVSD_ERR_CMD_TIMEOUT (1 << 0)
+#define MVSD_ERR_CMD_CRC (1 << 1)
+#define MVSD_ERR_CMD_ENDBIT (1 << 2)
+#define MVSD_ERR_CMD_INDEX (1 << 3)
+#define MVSD_ERR_DATA_TIMEOUT (1 << 4)
+#define MVSD_ERR_DATA_CRC (1 << 5)
+#define MVSD_ERR_DATA_ENDBIT (1 << 6)
+#define MVSD_ERR_AUTOCMD12 (1 << 8)
+#define MVSD_ERR_CMD_STARTBIT (1 << 9)
+#define MVSD_ERR_XFER_SIZE (1 << 10)
+#define MVSD_ERR_RESP_T_BIT (1 << 11)
+#define MVSD_ERR_CRC_ENDBIT (1 << 12)
+#define MVSD_ERR_CRC_STARTBIT (1 << 13)
+#define MVSD_ERR_CRC_STATUS (1 << 14)
+
+
+/*
+ * CMD12 error status bits
+ */
+
+#define MVSD_AUTOCMD12_ERR_NOTEXE (1 << 0)
+#define MVSD_AUTOCMD12_ERR_TIMEOUT (1 << 1)
+#define MVSD_AUTOCMD12_ERR_CRC (1 << 2)
+#define MVSD_AUTOCMD12_ERR_ENDBIT (1 << 3)
+#define MVSD_AUTOCMD12_ERR_INDEX (1 << 4)
+#define MVSD_AUTOCMD12_ERR_RESP_T_BIT (1 << 5)
+#define MVSD_AUTOCMD12_ERR_RESP_STARTBIT (1 << 6)
+
+#endif
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index dda0be4e25dc..b4a615c55f28 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -42,7 +42,7 @@
#define HAS_DMA
#endif
-#define DRIVER_NAME "imx-mmc"
+#define DRIVER_NAME "mxc-mmc"
#define MMC_REG_STR_STP_CLK 0x00
#define MMC_REG_STATUS 0x04
@@ -707,7 +707,7 @@ static int mxcmci_probe(struct platform_device *pdev)
host->res = r;
host->irq = irq;
- host->clk = clk_get(&pdev->dev, "sdhc_clk");
+ host->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(host->clk)) {
ret = PTR_ERR(host->clk);
goto out_iounmap;
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c
index fb2921f8099d..0c44d560bf1a 100644
--- a/drivers/mmc/host/of_mmc_spi.c
+++ b/drivers/mmc/host/of_mmc_spi.c
@@ -103,7 +103,7 @@ struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi)
if (!gpio_is_valid(oms->gpios[i]))
continue;
- ret = gpio_request(oms->gpios[i], dev->bus_id);
+ ret = gpio_request(oms->gpios[i], dev_name(dev));
if (ret < 0) {
oms->gpios[i] = -EINVAL;
continue;
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 67d7b7fef084..5570849188cc 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1460,18 +1460,12 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
if (!host->virt_base)
goto err_ioremap;
- if (cpu_is_omap24xx()) {
- host->iclk = clk_get(&pdev->dev, "mmc_ick");
- if (IS_ERR(host->iclk))
- goto err_free_mmc_host;
- clk_enable(host->iclk);
- }
-
- if (!cpu_is_omap24xx())
- host->fclk = clk_get(&pdev->dev, "mmc_ck");
- else
- host->fclk = clk_get(&pdev->dev, "mmc_fck");
+ host->iclk = clk_get(&pdev->dev, "ick");
+ if (IS_ERR(host->iclk))
+ goto err_free_mmc_host;
+ clk_enable(host->iclk);
+ host->fclk = clk_get(&pdev->dev, "fck");
if (IS_ERR(host->fclk)) {
ret = PTR_ERR(host->fclk);
goto err_free_iclk;
@@ -1536,10 +1530,10 @@ static int mmc_omap_remove(struct platform_device *pdev)
if (host->pdata->cleanup)
host->pdata->cleanup(&pdev->dev);
- if (host->iclk && !IS_ERR(host->iclk))
- clk_put(host->iclk);
- if (host->fclk && !IS_ERR(host->fclk))
- clk_put(host->fclk);
+ mmc_omap_fclk_enable(host, 0);
+ clk_put(host->fclk);
+ clk_disable(host->iclk);
+ clk_put(host->iclk);
iounmap(host->virt_base);
release_mem_region(pdev->resource[0].start,
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index a631c81dce12..d183be6f2a5f 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -56,6 +56,7 @@
#define SDVS18 (0x5 << 9)
#define SDVS30 (0x6 << 9)
#define SDVS33 (0x7 << 9)
+#define SDVS_MASK 0x00000E00
#define SDVSCLR 0xFFFFF1FF
#define SDVSDET 0x00000400
#define AUTOIDLE 0x1
@@ -76,6 +77,7 @@
#define MSBS (1 << 5)
#define BCE (1 << 1)
#define FOUR_BIT (1 << 1)
+#define DW8 (1 << 5)
#define CC 0x1
#define TC 0x02
#define OD 0x1
@@ -98,10 +100,8 @@
*/
#define OMAP_MMC1_DEVID 0
#define OMAP_MMC2_DEVID 1
+#define OMAP_MMC3_DEVID 2
-#define OMAP_MMC_DATADIR_NONE 0
-#define OMAP_MMC_DATADIR_READ 1
-#define OMAP_MMC_DATADIR_WRITE 2
#define MMC_TIMEOUT_MS 20
#define OMAP_MMC_MASTER_CLOCK 96000000
#define DRIVER_NAME "mmci-omap-hs"
@@ -137,18 +137,18 @@ struct mmc_omap_host {
resource_size_t mapbase;
unsigned int id;
unsigned int dma_len;
- unsigned int dma_dir;
+ unsigned int dma_sg_idx;
unsigned char bus_mode;
- unsigned char datadir;
u32 *buffer;
u32 bytesleft;
int suspended;
int irq;
int carddetect;
int use_dma, dma_ch;
- int initstr;
+ int dma_line_tx, dma_line_rx;
int slot_id;
int dbclk_enabled;
+ int response_busy;
struct omap_mmc_platform_data *pdata;
};
@@ -218,7 +218,7 @@ mmc_omap_show_slot_name(struct device *dev, struct device_attribute *attr,
struct mmc_omap_host *host = mmc_priv(mmc);
struct omap_mmc_slot_data slot = host->pdata->slots[host->slot_id];
- return sprintf(buf, "slot:%s\n", slot.name);
+ return sprintf(buf, "%s\n", slot.name);
}
static DEVICE_ATTR(slot_name, S_IRUGO, mmc_omap_show_slot_name, NULL);
@@ -243,10 +243,14 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd,
OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
+ host->response_busy = 0;
if (cmd->flags & MMC_RSP_PRESENT) {
if (cmd->flags & MMC_RSP_136)
resptype = 1;
- else
+ else if (cmd->flags & MMC_RSP_BUSY) {
+ resptype = 3;
+ host->response_busy = 1;
+ } else
resptype = 2;
}
@@ -275,19 +279,35 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd,
OMAP_HSMMC_WRITE(host->base, CMD, cmdreg);
}
+static int
+mmc_omap_get_dma_dir(struct mmc_omap_host *host, struct mmc_data *data)
+{
+ if (data->flags & MMC_DATA_WRITE)
+ return DMA_TO_DEVICE;
+ else
+ return DMA_FROM_DEVICE;
+}
+
/*
* Notify the transfer complete to MMC core
*/
static void
mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
{
+ if (!data) {
+ struct mmc_request *mrq = host->mrq;
+
+ host->mrq = NULL;
+ mmc_omap_fclk_lazy_disable(host);
+ mmc_request_done(host->mmc, mrq);
+ return;
+ }
+
host->data = NULL;
if (host->use_dma && host->dma_ch != -1)
dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len,
- host->dma_dir);
-
- host->datadir = OMAP_MMC_DATADIR_NONE;
+ mmc_omap_get_dma_dir(host, data));
if (!data->error)
data->bytes_xfered += data->blocks * (data->blksz);
@@ -322,7 +342,7 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10);
}
}
- if (host->data == NULL || cmd->error) {
+ if ((host->data == NULL && !host->response_busy) || cmd->error) {
host->mrq = NULL;
mmc_request_done(host->mmc, cmd->mrq);
}
@@ -331,19 +351,18 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
/*
* DMA clean up for command errors
*/
-static void mmc_dma_cleanup(struct mmc_omap_host *host)
+static void mmc_dma_cleanup(struct mmc_omap_host *host, int errno)
{
- host->data->error = -ETIMEDOUT;
+ host->data->error = errno;
if (host->use_dma && host->dma_ch != -1) {
dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,
- host->dma_dir);
+ mmc_omap_get_dma_dir(host, host->data));
omap_free_dma(host->dma_ch);
host->dma_ch = -1;
up(&host->sem);
}
host->data = NULL;
- host->datadir = OMAP_MMC_DATADIR_NONE;
}
/*
@@ -412,7 +431,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
struct mmc_data *data;
int end_cmd = 0, end_trans = 0, status;
- if (host->cmd == NULL && host->data == NULL) {
+ if (host->mrq == NULL) {
OMAP_HSMMC_WRITE(host->base, STAT,
OMAP_HSMMC_READ(host->base, STAT));
return IRQ_HANDLED;
@@ -437,18 +456,24 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
}
end_cmd = 1;
}
- if (host->data) {
- mmc_dma_cleanup(host);
+ if (host->data || host->response_busy) {
+ if (host->data)
+ mmc_dma_cleanup(host, -ETIMEDOUT);
+ host->response_busy = 0;
mmc_omap_reset_controller_fsm(host, SRD);
}
}
if ((status & DATA_TIMEOUT) ||
(status & DATA_CRC)) {
- if (host->data) {
- if (status & DATA_TIMEOUT)
- mmc_dma_cleanup(host);
+ if (host->data || host->response_busy) {
+ int err = (status & DATA_TIMEOUT) ?
+ -ETIMEDOUT : -EILSEQ;
+
+ if (host->data)
+ mmc_dma_cleanup(host, err);
else
- host->data->error = -EILSEQ;
+ host->mrq->cmd->error = err;
+ host->response_busy = 0;
mmc_omap_reset_controller_fsm(host, SRD);
end_trans = 1;
}
@@ -473,6 +498,19 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static void set_sd_bus_power(struct mmc_omap_host *host)
+{
+ unsigned long i;
+
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+ for (i = 0; i < loops_per_jiffy; i++) {
+ if (OMAP_HSMMC_READ(host->base, HCTL) & SDBP)
+ break;
+ cpu_relax();
+ }
+}
+
/*
* Switch MMC interface voltage ... only relevant for MMC1.
*
@@ -485,9 +523,6 @@ static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd)
u32 reg_val = 0;
int ret;
- if (host->id != OMAP_MMC1_DEVID)
- return 0;
-
/* Disable the clocks */
clk_disable(host->fclk);
clk_disable(host->iclk);
@@ -532,9 +567,7 @@ static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd)
reg_val |= SDVS30;
OMAP_HSMMC_WRITE(host->base, HCTL, reg_val);
-
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+ set_sd_bus_power(host);
return 0;
err:
@@ -551,7 +584,10 @@ static void mmc_omap_detect(struct work_struct *work)
mmc_carddetect_work);
struct omap_mmc_slot_data *slot = &mmc_slot(host);
- host->carddetect = slot->card_detect(slot->card_detect_irq);
+ if (mmc_slot(host).card_detect)
+ host->carddetect = slot->card_detect(slot->card_detect_irq);
+ else
+ host->carddetect = -ENOSYS;
sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
if (host->carddetect) {
@@ -574,6 +610,48 @@ static irqreturn_t omap_mmc_cd_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static int mmc_omap_get_dma_sync_dev(struct mmc_omap_host *host,
+ struct mmc_data *data)
+{
+ int sync_dev;
+
+ if (data->flags & MMC_DATA_WRITE)
+ sync_dev = host->dma_line_tx;
+ else
+ sync_dev = host->dma_line_rx;
+ return sync_dev;
+}
+
+static void mmc_omap_config_dma_params(struct mmc_omap_host *host,
+ struct mmc_data *data,
+ struct scatterlist *sgl)
+{
+ int blksz, nblk, dma_ch;
+
+ dma_ch = host->dma_ch;
+ if (data->flags & MMC_DATA_WRITE) {
+ omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
+ (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+ omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
+ sg_dma_address(sgl), 0, 0);
+ } else {
+ omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
+ (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+ omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
+ sg_dma_address(sgl), 0, 0);
+ }
+
+ blksz = host->data->blksz;
+ nblk = sg_dma_len(sgl) / blksz;
+
+ omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
+ blksz / 4, nblk, OMAP_DMA_SYNC_FRAME,
+ mmc_omap_get_dma_sync_dev(host, data),
+ !(data->flags & MMC_DATA_WRITE));
+
+ omap_start_dma(dma_ch);
+}
+
/*
* DMA call back function
*/
@@ -587,6 +665,14 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
if (host->dma_ch < 0)
return;
+ host->dma_sg_idx++;
+ if (host->dma_sg_idx < host->dma_len) {
+ /* Fire up the next transfer. */
+ mmc_omap_config_dma_params(host, host->data,
+ host->data->sg + host->dma_sg_idx);
+ return;
+ }
+
omap_free_dma(host->dma_ch);
host->dma_ch = -1;
/*
@@ -597,38 +683,28 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
}
/*
- * Configure dma src and destination parameters
- */
-static int mmc_omap_config_dma_param(int sync_dir, struct mmc_omap_host *host,
- struct mmc_data *data)
-{
- if (sync_dir == 0) {
- omap_set_dma_dest_params(host->dma_ch, 0,
- OMAP_DMA_AMODE_CONSTANT,
- (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
- omap_set_dma_src_params(host->dma_ch, 0,
- OMAP_DMA_AMODE_POST_INC,
- sg_dma_address(&data->sg[0]), 0, 0);
- } else {
- omap_set_dma_src_params(host->dma_ch, 0,
- OMAP_DMA_AMODE_CONSTANT,
- (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
- omap_set_dma_dest_params(host->dma_ch, 0,
- OMAP_DMA_AMODE_POST_INC,
- sg_dma_address(&data->sg[0]), 0, 0);
- }
- return 0;
-}
-/*
* Routine to configure and start DMA for the MMC card
*/
static int
mmc_omap_start_dma_transfer(struct mmc_omap_host *host, struct mmc_request *req)
{
- int sync_dev, sync_dir = 0;
- int dma_ch = 0, ret = 0, err = 1;
+ int dma_ch = 0, ret = 0, err = 1, i;
struct mmc_data *data = req->data;
+ /* Sanity check: all the SG entries must be aligned by block size. */
+ for (i = 0; i < host->dma_len; i++) {
+ struct scatterlist *sgl;
+
+ sgl = data->sg + i;
+ if (sgl->length % data->blksz)
+ return -EINVAL;
+ }
+ if ((data->blksz % 4) != 0)
+ /* REVISIT: The MMC buffer increments only when MSB is written.
+ * Return error for blksz which is non multiple of four.
+ */
+ return -EINVAL;
+
/*
* If for some reason the DMA transfer is still active,
* we wait for timeout period and free the dma
@@ -647,49 +723,22 @@ mmc_omap_start_dma_transfer(struct mmc_omap_host *host, struct mmc_request *req)
return err;
}
- if (!(data->flags & MMC_DATA_WRITE)) {
- host->dma_dir = DMA_FROM_DEVICE;
- if (host->id == OMAP_MMC1_DEVID)
- sync_dev = OMAP24XX_DMA_MMC1_RX;
- else
- sync_dev = OMAP24XX_DMA_MMC2_RX;
- } else {
- host->dma_dir = DMA_TO_DEVICE;
- if (host->id == OMAP_MMC1_DEVID)
- sync_dev = OMAP24XX_DMA_MMC1_TX;
- else
- sync_dev = OMAP24XX_DMA_MMC2_TX;
- }
-
- ret = omap_request_dma(sync_dev, "MMC/SD", mmc_omap_dma_cb,
- host, &dma_ch);
+ ret = omap_request_dma(mmc_omap_get_dma_sync_dev(host, data), "MMC/SD",
+ mmc_omap_dma_cb,host, &dma_ch);
if (ret != 0) {
- dev_dbg(mmc_dev(host->mmc),
+ dev_err(mmc_dev(host->mmc),
"%s: omap_request_dma() failed with %d\n",
mmc_hostname(host->mmc), ret);
return ret;
}
host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
- data->sg_len, host->dma_dir);
+ data->sg_len, mmc_omap_get_dma_dir(host, data));
host->dma_ch = dma_ch;
+ host->dma_sg_idx = 0;
- if (!(data->flags & MMC_DATA_WRITE))
- mmc_omap_config_dma_param(1, host, data);
- else
- mmc_omap_config_dma_param(0, host, data);
-
- if ((data->blksz % 4) == 0)
- omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
- (data->blksz / 4), data->blocks, OMAP_DMA_SYNC_FRAME,
- sync_dev, sync_dir);
- else
- /* REVISIT: The MMC buffer increments only when MSB is written.
- * Return error for blksz which is non multiple of four.
- */
- return -EINVAL;
+ mmc_omap_config_dma_params(host, data, data->sg);
- omap_start_dma(dma_ch);
return 0;
}
@@ -739,7 +788,6 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
host->data = req->data;
if (req->data == NULL) {
- host->datadir = OMAP_MMC_DATADIR_NONE;
OMAP_HSMMC_WRITE(host->base, BLK, 0);
return 0;
}
@@ -748,9 +796,6 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
| (req->data->blocks << 16));
set_data_timeout(host, req);
- host->datadir = (req->data->flags & MMC_DATA_WRITE) ?
- OMAP_MMC_DATADIR_WRITE : OMAP_MMC_DATADIR_READ;
-
if (host->use_dma) {
ret = mmc_omap_start_dma_transfer(host, req);
if (ret != 0) {
@@ -782,36 +827,29 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
u16 dsor = 0;
unsigned long regval;
unsigned long timeout;
+ u32 con;
switch (ios->power_mode) {
case MMC_POWER_OFF:
mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
- /*
- * Reset interface voltage to 3V if it's 1.8V now;
- * only relevant on MMC-1, the others always use 1.8V.
- *
- * REVISIT: If we are able to detect cards after unplugging
- * a 1.8V card, this code should not be needed.
- */
- if (host->id != OMAP_MMC1_DEVID)
- break;
- if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) {
- int vdd = fls(host->mmc->ocr_avail) - 1;
- if (omap_mmc_switch_opcond(host, vdd) != 0)
- host->mmc->ios.vdd = vdd;
- }
break;
case MMC_POWER_UP:
mmc_slot(host).set_power(host->dev, host->slot_id, 1, ios->vdd);
break;
}
+ con = OMAP_HSMMC_READ(host->base, CON);
switch (mmc->ios.bus_width) {
+ case MMC_BUS_WIDTH_8:
+ OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
+ break;
case MMC_BUS_WIDTH_4:
+ OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
OMAP_HSMMC_WRITE(host->base, HCTL,
OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
break;
case MMC_BUS_WIDTH_1:
+ OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
OMAP_HSMMC_WRITE(host->base, HCTL,
OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
break;
@@ -891,6 +929,33 @@ static int omap_hsmmc_get_ro(struct mmc_host *mmc)
return pdata->slots[0].get_ro(host->dev, 0);
}
+static void omap_hsmmc_init(struct mmc_omap_host *host)
+{
+ u32 hctl, capa, value;
+
+ /* Only MMC1 supports 3.0V */
+ if (host->id == OMAP_MMC1_DEVID) {
+ hctl = SDVS30;
+ capa = VS30 | VS18;
+ } else {
+ hctl = SDVS18;
+ capa = VS18;
+ }
+
+ value = OMAP_HSMMC_READ(host->base, HCTL) & ~SDVS_MASK;
+ OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl);
+
+ value = OMAP_HSMMC_READ(host->base, CAPA);
+ OMAP_HSMMC_WRITE(host->base, CAPA, value | capa);
+
+ /* Set the controller to AUTO IDLE mode */
+ value = OMAP_HSMMC_READ(host->base, SYSCONFIG);
+ OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE);
+
+ /* Set SD bus power bit */
+ set_sd_bus_power(host);
+}
+
static struct mmc_host_ops mmc_omap_ops = {
.request = omap_mmc_request,
.set_ios = omap_mmc_set_ios,
@@ -906,7 +971,6 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
struct mmc_omap_host *host = NULL;
struct resource *res;
int ret = 0, irq;
- u32 hctl, capa;
if (pdata == NULL) {
dev_err(&pdev->dev, "Platform Data is missing\n");
@@ -956,13 +1020,13 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
sema_init(&host->sem, 1);
- host->iclk = clk_get(&pdev->dev, "mmchs_ick");
+ host->iclk = clk_get(&pdev->dev, "ick");
if (IS_ERR(host->iclk)) {
ret = PTR_ERR(host->iclk);
host->iclk = NULL;
goto err1;
}
- host->fclk = clk_get(&pdev->dev, "mmchs_fck");
+ host->fclk = clk_get(&pdev->dev, "fck");
if (IS_ERR(host->fclk)) {
ret = PTR_ERR(host->fclk);
host->fclk = NULL;
@@ -996,10 +1060,11 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
else
host->dbclk_enabled = 1;
-#ifdef CONFIG_MMC_BLOCK_BOUNCE
- mmc->max_phys_segs = 1;
- mmc->max_hw_segs = 1;
-#endif
+ /* Since we do only SG emulation, we can have as many segs
+ * as we want. */
+ mmc->max_phys_segs = 1024;
+ mmc->max_hw_segs = 1024;
+
mmc->max_blk_size = 512; /* Block Length at max can be 1024 */
mmc->max_blk_count = 0xFFFF; /* No. of Blocks is 16 bits */
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
@@ -1008,31 +1073,31 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
mmc->ocr_avail = mmc_slot(host).ocr_mask;
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
- if (pdata->slots[host->slot_id].wires >= 4)
+ if (pdata->slots[host->slot_id].wires >= 8)
+ mmc->caps |= MMC_CAP_8_BIT_DATA;
+ else if (pdata->slots[host->slot_id].wires >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
- /* Only MMC1 supports 3.0V */
- if (host->id == OMAP_MMC1_DEVID) {
- hctl = SDVS30;
- capa = VS30 | VS18;
- } else {
- hctl = SDVS18;
- capa = VS18;
- }
-
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) | hctl);
-
- OMAP_HSMMC_WRITE(host->base, CAPA,
- OMAP_HSMMC_READ(host->base, CAPA) | capa);
-
- /* Set the controller to AUTO IDLE mode */
- OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
- OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
+ omap_hsmmc_init(host);
- /* Set SD bus power bit */
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+ /* Select DMA lines */
+ switch (host->id) {
+ case OMAP_MMC1_DEVID:
+ host->dma_line_tx = OMAP24XX_DMA_MMC1_TX;
+ host->dma_line_rx = OMAP24XX_DMA_MMC1_RX;
+ break;
+ case OMAP_MMC2_DEVID:
+ host->dma_line_tx = OMAP24XX_DMA_MMC2_TX;
+ host->dma_line_rx = OMAP24XX_DMA_MMC2_RX;
+ break;
+ case OMAP_MMC3_DEVID:
+ host->dma_line_tx = OMAP34XX_DMA_MMC3_TX;
+ host->dma_line_rx = OMAP34XX_DMA_MMC3_RX;
+ break;
+ default:
+ dev_err(mmc_dev(host->mmc), "Invalid MMC id\n");
+ goto err_irq;
+ }
/* Request IRQ for MMC operations */
ret = request_irq(host->irq, mmc_omap_irq, IRQF_DISABLED,
@@ -1051,7 +1116,7 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
}
/* Request IRQ for card detect */
- if ((mmc_slot(host).card_detect_irq) && (mmc_slot(host).card_detect)) {
+ if ((mmc_slot(host).card_detect_irq)) {
ret = request_irq(mmc_slot(host).card_detect_irq,
omap_mmc_cd_handler,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
@@ -1074,8 +1139,8 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
if (ret < 0)
goto err_slot_name;
}
- if (mmc_slot(host).card_detect_irq && mmc_slot(host).card_detect &&
- host->pdata->slots[host->slot_id].get_cover_state) {
+ if (mmc_slot(host).card_detect_irq &&
+ host->pdata->slots[host->slot_id].get_cover_state) {
ret = device_create_file(&mmc->class_dev,
&dev_attr_cover_switch);
if (ret < 0)
@@ -1173,20 +1238,8 @@ static int omap_mmc_suspend(struct platform_device *pdev, pm_message_t state)
" level suspend\n");
}
- if (host->id == OMAP_MMC1_DEVID
- && !(OMAP_HSMMC_READ(host->base, HCTL)
- & SDVSDET)) {
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL)
- & SDVSCLR);
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL)
- | SDVS30);
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL)
- | SDBP);
- }
-
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
clk_disable(host->fclk);
clk_disable(host->iclk);
clk_disable(host->dbclk);
@@ -1222,6 +1275,8 @@ static int omap_mmc_resume(struct platform_device *pdev)
dev_dbg(mmc_dev(host->mmc),
"Enabling debounce clk failed\n");
+ omap_hsmmc_init(host);
+
if (host->pdata->resume) {
ret = host->pdata->resume(&pdev->dev, host->slot_id);
if (ret)
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 9702ad3774cf..430095725f9f 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -30,9 +30,8 @@
#include <asm/sizes.h>
-#include <mach/dma.h>
#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/dma.h>
#include <mach/mmc.h>
#include "pxamci.h"
diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of.c
new file mode 100644
index 000000000000..3ff4ac3abe8b
--- /dev/null
+++ b/drivers/mmc/host/sdhci-of.c
@@ -0,0 +1,309 @@
+/*
+ * OpenFirmware bindings for Secure Digital Host Controller Interface.
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ * Copyright (c) 2009 MontaVista Software, Inc.
+ *
+ * Authors: Xiaobo Xie <X.Xie@freescale.com>
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/mmc/host.h>
+#include "sdhci.h"
+
+struct sdhci_of_data {
+ unsigned int quirks;
+ struct sdhci_ops ops;
+};
+
+struct sdhci_of_host {
+ unsigned int clock;
+ u16 xfer_mode_shadow;
+};
+
+/*
+ * Ops and quirks for the Freescale eSDHC controller.
+ */
+
+#define ESDHC_DMA_SYSCTL 0x40c
+#define ESDHC_DMA_SNOOP 0x00000040
+
+#define ESDHC_SYSTEM_CONTROL 0x2c
+#define ESDHC_CLOCK_MASK 0x0000fff0
+#define ESDHC_PREDIV_SHIFT 8
+#define ESDHC_DIVIDER_SHIFT 4
+#define ESDHC_CLOCK_PEREN 0x00000004
+#define ESDHC_CLOCK_HCKEN 0x00000002
+#define ESDHC_CLOCK_IPGEN 0x00000001
+
+static u32 esdhc_readl(struct sdhci_host *host, int reg)
+{
+ return in_be32(host->ioaddr + reg);
+}
+
+static u16 esdhc_readw(struct sdhci_host *host, int reg)
+{
+ return in_be16(host->ioaddr + (reg ^ 0x2));
+}
+
+static u8 esdhc_readb(struct sdhci_host *host, int reg)
+{
+ return in_8(host->ioaddr + (reg ^ 0x3));
+}
+
+static void esdhc_writel(struct sdhci_host *host, u32 val, int reg)
+{
+ out_be32(host->ioaddr + reg, val);
+}
+
+static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
+{
+ struct sdhci_of_host *of_host = sdhci_priv(host);
+ int base = reg & ~0x3;
+ int shift = (reg & 0x2) * 8;
+
+ switch (reg) {
+ case SDHCI_TRANSFER_MODE:
+ /*
+ * Postpone this write, we must do it together with a
+ * command write that is down below.
+ */
+ of_host->xfer_mode_shadow = val;
+ return;
+ case SDHCI_COMMAND:
+ esdhc_writel(host, val << 16 | of_host->xfer_mode_shadow,
+ SDHCI_TRANSFER_MODE);
+ return;
+ case SDHCI_BLOCK_SIZE:
+ /*
+ * Two last DMA bits are reserved, and first one is used for
+ * non-standard blksz of 4096 bytes that we don't support
+ * yet. So clear the DMA boundary bits.
+ */
+ val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
+ /* fall through */
+ }
+ clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
+}
+
+static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+ int base = reg & ~0x3;
+ int shift = (reg & 0x3) * 8;
+
+ clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
+}
+
+static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+ int div;
+ int pre_div = 2;
+
+ clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
+ ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
+
+ if (clock == 0)
+ goto out;
+
+ if (host->max_clk / 16 > clock) {
+ for (; pre_div < 256; pre_div *= 2) {
+ if (host->max_clk / pre_div < clock * 16)
+ break;
+ }
+ }
+
+ for (div = 1; div <= 16; div++) {
+ if (host->max_clk / (div * pre_div) <= clock)
+ break;
+ }
+
+ pre_div >>= 1;
+
+ setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
+ ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
+ div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT);
+ mdelay(100);
+out:
+ host->clock = clock;
+}
+
+static int esdhc_enable_dma(struct sdhci_host *host)
+{
+ setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
+ return 0;
+}
+
+static unsigned int esdhc_get_max_clock(struct sdhci_host *host)
+{
+ struct sdhci_of_host *of_host = sdhci_priv(host);
+
+ return of_host->clock;
+}
+
+static unsigned int esdhc_get_timeout_clock(struct sdhci_host *host)
+{
+ struct sdhci_of_host *of_host = sdhci_priv(host);
+
+ return of_host->clock / 1000;
+}
+
+static struct sdhci_of_data sdhci_esdhc = {
+ .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
+ SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+ SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
+ SDHCI_QUIRK_NO_BUSY_IRQ |
+ SDHCI_QUIRK_NONSTANDARD_CLOCK |
+ SDHCI_QUIRK_PIO_NEEDS_DELAY |
+ SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET |
+ SDHCI_QUIRK_NO_CARD_NO_RESET,
+ .ops = {
+ .readl = esdhc_readl,
+ .readw = esdhc_readw,
+ .readb = esdhc_readb,
+ .writel = esdhc_writel,
+ .writew = esdhc_writew,
+ .writeb = esdhc_writeb,
+ .set_clock = esdhc_set_clock,
+ .enable_dma = esdhc_enable_dma,
+ .get_max_clock = esdhc_get_max_clock,
+ .get_timeout_clock = esdhc_get_timeout_clock,
+ },
+};
+
+#ifdef CONFIG_PM
+
+static int sdhci_of_suspend(struct of_device *ofdev, pm_message_t state)
+{
+ struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+ return mmc_suspend_host(host->mmc, state);
+}
+
+static int sdhci_of_resume(struct of_device *ofdev)
+{
+ struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+ return mmc_resume_host(host->mmc);
+}
+
+#else
+
+#define sdhci_of_suspend NULL
+#define sdhci_of_resume NULL
+
+#endif
+
+static int __devinit sdhci_of_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct device_node *np = ofdev->node;
+ struct sdhci_of_data *sdhci_of_data = match->data;
+ struct sdhci_host *host;
+ struct sdhci_of_host *of_host;
+ const u32 *clk;
+ int size;
+ int ret;
+
+ if (!of_device_is_available(np))
+ return -ENODEV;
+
+ host = sdhci_alloc_host(&ofdev->dev, sizeof(*of_host));
+ if (!host)
+ return -ENOMEM;
+
+ of_host = sdhci_priv(host);
+ dev_set_drvdata(&ofdev->dev, host);
+
+ host->ioaddr = of_iomap(np, 0);
+ if (!host->ioaddr) {
+ ret = -ENOMEM;
+ goto err_addr_map;
+ }
+
+ host->irq = irq_of_parse_and_map(np, 0);
+ if (!host->irq) {
+ ret = -EINVAL;
+ goto err_no_irq;
+ }
+
+ host->hw_name = dev_name(&ofdev->dev);
+ if (sdhci_of_data) {
+ host->quirks = sdhci_of_data->quirks;
+ host->ops = &sdhci_of_data->ops;
+ }
+
+ clk = of_get_property(np, "clock-frequency", &size);
+ if (clk && size == sizeof(*clk) && *clk)
+ of_host->clock = *clk;
+
+ ret = sdhci_add_host(host);
+ if (ret)
+ goto err_add_host;
+
+ return 0;
+
+err_add_host:
+ irq_dispose_mapping(host->irq);
+err_no_irq:
+ iounmap(host->ioaddr);
+err_addr_map:
+ sdhci_free_host(host);
+ return ret;
+}
+
+static int __devexit sdhci_of_remove(struct of_device *ofdev)
+{
+ struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+ sdhci_remove_host(host, 0);
+ sdhci_free_host(host);
+ irq_dispose_mapping(host->irq);
+ iounmap(host->ioaddr);
+ return 0;
+}
+
+static const struct of_device_id sdhci_of_match[] = {
+ { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, },
+ { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, },
+ { .compatible = "generic-sdhci", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sdhci_of_match);
+
+static struct of_platform_driver sdhci_of_driver = {
+ .driver.name = "sdhci-of",
+ .match_table = sdhci_of_match,
+ .probe = sdhci_of_probe,
+ .remove = __devexit_p(sdhci_of_remove),
+ .suspend = sdhci_of_suspend,
+ .resume = sdhci_of_resume,
+};
+
+static int __init sdhci_of_init(void)
+{
+ return of_register_platform_driver(&sdhci_of_driver);
+}
+module_init(sdhci_of_init);
+
+static void __exit sdhci_of_exit(void)
+{
+ of_unregister_platform_driver(&sdhci_of_driver);
+}
+module_exit(sdhci_of_exit);
+
+MODULE_DESCRIPTION("Secure Digital Host Controller Interface OF driver");
+MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
+ "Anton Vorontsov <avorontsov@ru.mvista.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index accb592764ed..30d8e3d4e6fd 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -48,35 +48,35 @@ static void sdhci_dumpregs(struct sdhci_host *host)
printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n");
printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n",
- readl(host->ioaddr + SDHCI_DMA_ADDRESS),
- readw(host->ioaddr + SDHCI_HOST_VERSION));
+ sdhci_readl(host, SDHCI_DMA_ADDRESS),
+ sdhci_readw(host, SDHCI_HOST_VERSION));
printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n",
- readw(host->ioaddr + SDHCI_BLOCK_SIZE),
- readw(host->ioaddr + SDHCI_BLOCK_COUNT));
+ sdhci_readw(host, SDHCI_BLOCK_SIZE),
+ sdhci_readw(host, SDHCI_BLOCK_COUNT));
printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
- readl(host->ioaddr + SDHCI_ARGUMENT),
- readw(host->ioaddr + SDHCI_TRANSFER_MODE));
+ sdhci_readl(host, SDHCI_ARGUMENT),
+ sdhci_readw(host, SDHCI_TRANSFER_MODE));
printk(KERN_DEBUG DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n",
- readl(host->ioaddr + SDHCI_PRESENT_STATE),
- readb(host->ioaddr + SDHCI_HOST_CONTROL));
+ sdhci_readl(host, SDHCI_PRESENT_STATE),
+ sdhci_readb(host, SDHCI_HOST_CONTROL));
printk(KERN_DEBUG DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n",
- readb(host->ioaddr + SDHCI_POWER_CONTROL),
- readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL));
+ sdhci_readb(host, SDHCI_POWER_CONTROL),
+ sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
printk(KERN_DEBUG DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n",
- readb(host->ioaddr + SDHCI_WAKE_UP_CONTROL),
- readw(host->ioaddr + SDHCI_CLOCK_CONTROL));
+ sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
+ sdhci_readw(host, SDHCI_CLOCK_CONTROL));
printk(KERN_DEBUG DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n",
- readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL),
- readl(host->ioaddr + SDHCI_INT_STATUS));
+ sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
+ sdhci_readl(host, SDHCI_INT_STATUS));
printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
- readl(host->ioaddr + SDHCI_INT_ENABLE),
- readl(host->ioaddr + SDHCI_SIGNAL_ENABLE));
+ sdhci_readl(host, SDHCI_INT_ENABLE),
+ sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
- readw(host->ioaddr + SDHCI_ACMD12_ERR),
- readw(host->ioaddr + SDHCI_SLOT_INT_STATUS));
+ sdhci_readw(host, SDHCI_ACMD12_ERR),
+ sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
printk(KERN_DEBUG DRIVER_NAME ": Caps: 0x%08x | Max curr: 0x%08x\n",
- readl(host->ioaddr + SDHCI_CAPABILITIES),
- readl(host->ioaddr + SDHCI_MAX_CURRENT));
+ sdhci_readl(host, SDHCI_CAPABILITIES),
+ sdhci_readl(host, SDHCI_MAX_CURRENT));
printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
}
@@ -87,17 +87,65 @@ static void sdhci_dumpregs(struct sdhci_host *host)
* *
\*****************************************************************************/
+static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
+{
+ u32 ier;
+
+ ier = sdhci_readl(host, SDHCI_INT_ENABLE);
+ ier &= ~clear;
+ ier |= set;
+ sdhci_writel(host, ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
+}
+
+static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
+{
+ sdhci_clear_set_irqs(host, 0, irqs);
+}
+
+static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
+{
+ sdhci_clear_set_irqs(host, irqs, 0);
+}
+
+static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
+{
+ u32 irqs = SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT;
+
+ if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+ return;
+
+ if (enable)
+ sdhci_unmask_irqs(host, irqs);
+ else
+ sdhci_mask_irqs(host, irqs);
+}
+
+static void sdhci_enable_card_detection(struct sdhci_host *host)
+{
+ sdhci_set_card_detection(host, true);
+}
+
+static void sdhci_disable_card_detection(struct sdhci_host *host)
+{
+ sdhci_set_card_detection(host, false);
+}
+
static void sdhci_reset(struct sdhci_host *host, u8 mask)
{
unsigned long timeout;
+ u32 uninitialized_var(ier);
if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
- if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
+ if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
SDHCI_CARD_PRESENT))
return;
}
- writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET);
+ if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
+ ier = sdhci_readl(host, SDHCI_INT_ENABLE);
+
+ sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
if (mask & SDHCI_RESET_ALL)
host->clock = 0;
@@ -106,7 +154,7 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
timeout = 100;
/* hw clears the bit when it's done */
- while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) {
+ while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
if (timeout == 0) {
printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
mmc_hostname(host->mmc), (int)mask);
@@ -116,42 +164,44 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
timeout--;
mdelay(1);
}
+
+ if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
+ sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
}
static void sdhci_init(struct sdhci_host *host)
{
- u32 intmask;
-
sdhci_reset(host, SDHCI_RESET_ALL);
- intmask = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
+ sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
+ SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
- SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT |
- SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL |
- SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE |
- SDHCI_INT_ADMA_ERROR;
+ SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
+}
- writel(intmask, host->ioaddr + SDHCI_INT_ENABLE);
- writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE);
+static void sdhci_reinit(struct sdhci_host *host)
+{
+ sdhci_init(host);
+ sdhci_enable_card_detection(host);
}
static void sdhci_activate_led(struct sdhci_host *host)
{
u8 ctrl;
- ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
ctrl |= SDHCI_CTRL_LED;
- writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
}
static void sdhci_deactivate_led(struct sdhci_host *host)
{
u8 ctrl;
- ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
ctrl &= ~SDHCI_CTRL_LED;
- writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
}
#ifdef SDHCI_USE_LEDS_CLASS
@@ -205,7 +255,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host)
while (len) {
if (chunk == 0) {
- scratch = readl(host->ioaddr + SDHCI_BUFFER);
+ scratch = sdhci_readl(host, SDHCI_BUFFER);
chunk = 4;
}
@@ -257,7 +307,7 @@ static void sdhci_write_block_pio(struct sdhci_host *host)
len--;
if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
- writel(scratch, host->ioaddr + SDHCI_BUFFER);
+ sdhci_writel(host, scratch, SDHCI_BUFFER);
chunk = 0;
scratch = 0;
}
@@ -292,7 +342,10 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
(host->data->blocks == 1))
mask = ~0;
- while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
+ while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
+ if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY)
+ udelay(100);
+
if (host->data->flags & MMC_DATA_READ)
sdhci_read_block_pio(host);
else
@@ -561,6 +614,17 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
return count;
}
+static void sdhci_set_transfer_irqs(struct sdhci_host *host)
+{
+ u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL;
+ u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
+
+ if (host->flags & SDHCI_REQ_USE_DMA)
+ sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
+ else
+ sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
+}
+
static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
{
u8 count;
@@ -581,7 +645,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
host->data_early = 0;
count = sdhci_calc_timeout(host, data);
- writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL);
+ sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
if (host->flags & SDHCI_USE_DMA)
host->flags |= SDHCI_REQ_USE_DMA;
@@ -661,8 +725,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
WARN_ON(1);
host->flags &= ~SDHCI_REQ_USE_DMA;
} else {
- writel(host->adma_addr,
- host->ioaddr + SDHCI_ADMA_ADDRESS);
+ sdhci_writel(host, host->adma_addr,
+ SDHCI_ADMA_ADDRESS);
}
} else {
int sg_cnt;
@@ -681,8 +745,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
host->flags &= ~SDHCI_REQ_USE_DMA;
} else {
WARN_ON(sg_cnt != 1);
- writel(sg_dma_address(data->sg),
- host->ioaddr + SDHCI_DMA_ADDRESS);
+ sdhci_writel(host, sg_dma_address(data->sg),
+ SDHCI_DMA_ADDRESS);
}
}
}
@@ -693,14 +757,14 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
* is ADMA.
*/
if (host->version >= SDHCI_SPEC_200) {
- ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
ctrl &= ~SDHCI_CTRL_DMA_MASK;
if ((host->flags & SDHCI_REQ_USE_DMA) &&
(host->flags & SDHCI_USE_ADMA))
ctrl |= SDHCI_CTRL_ADMA32;
else
ctrl |= SDHCI_CTRL_SDMA;
- writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
}
if (!(host->flags & SDHCI_REQ_USE_DMA)) {
@@ -709,10 +773,11 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
host->blocks = data->blocks;
}
+ sdhci_set_transfer_irqs(host);
+
/* We do not handle DMA boundaries, so set it to max (512 KiB) */
- writew(SDHCI_MAKE_BLKSZ(7, data->blksz),
- host->ioaddr + SDHCI_BLOCK_SIZE);
- writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT);
+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE);
+ sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
}
static void sdhci_set_transfer_mode(struct sdhci_host *host,
@@ -733,7 +798,7 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host,
if (host->flags & SDHCI_REQ_USE_DMA)
mode |= SDHCI_TRNS_DMA;
- writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE);
+ sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
}
static void sdhci_finish_data(struct sdhci_host *host)
@@ -802,7 +867,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
if (host->mrq->data && (cmd == host->mrq->data->stop))
mask &= ~SDHCI_DATA_INHIBIT;
- while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
+ while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
if (timeout == 0) {
printk(KERN_ERR "%s: Controller never released "
"inhibit bit(s).\n", mmc_hostname(host->mmc));
@@ -821,7 +886,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
sdhci_prepare_data(host, cmd->data);
- writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT);
+ sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
sdhci_set_transfer_mode(host, cmd->data);
@@ -849,8 +914,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
if (cmd->data)
flags |= SDHCI_CMD_DATA;
- writew(SDHCI_MAKE_CMD(cmd->opcode, flags),
- host->ioaddr + SDHCI_COMMAND);
+ sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
}
static void sdhci_finish_command(struct sdhci_host *host)
@@ -863,15 +927,15 @@ static void sdhci_finish_command(struct sdhci_host *host)
if (host->cmd->flags & MMC_RSP_136) {
/* CRC is stripped so we need to do some shifting. */
for (i = 0;i < 4;i++) {
- host->cmd->resp[i] = readl(host->ioaddr +
+ host->cmd->resp[i] = sdhci_readl(host,
SDHCI_RESPONSE + (3-i)*4) << 8;
if (i != 3)
host->cmd->resp[i] |=
- readb(host->ioaddr +
+ sdhci_readb(host,
SDHCI_RESPONSE + (3-i)*4-1);
}
} else {
- host->cmd->resp[0] = readl(host->ioaddr + SDHCI_RESPONSE);
+ host->cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
}
}
@@ -895,7 +959,13 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
if (clock == host->clock)
return;
- writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
+ if (host->ops->set_clock) {
+ host->ops->set_clock(host, clock);
+ if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
+ return;
+ }
+
+ sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
if (clock == 0)
goto out;
@@ -908,11 +978,11 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
clk = div << SDHCI_DIVIDER_SHIFT;
clk |= SDHCI_CLOCK_INT_EN;
- writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
/* Wait max 10 ms */
timeout = 10;
- while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL))
+ while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
& SDHCI_CLOCK_INT_STABLE)) {
if (timeout == 0) {
printk(KERN_ERR "%s: Internal clock never "
@@ -925,7 +995,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
}
clk |= SDHCI_CLOCK_CARD_EN;
- writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
out:
host->clock = clock;
@@ -939,7 +1009,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
return;
if (power == (unsigned short)-1) {
- writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
+ sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
goto out;
}
@@ -948,7 +1018,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
* a new value. Some controllers don't seem to like this though.
*/
if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
- writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
+ sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
pwr = SDHCI_POWER_ON;
@@ -973,10 +1043,9 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
* and set turn on power at the same time, so set the voltage first.
*/
if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
- writeb(pwr & ~SDHCI_POWER_ON,
- host->ioaddr + SDHCI_POWER_CONTROL);
+ sdhci_writeb(host, pwr & ~SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
- writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL);
+ sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
out:
host->power = power;
@@ -991,6 +1060,7 @@ out:
static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct sdhci_host *host;
+ bool present;
unsigned long flags;
host = mmc_priv(mmc);
@@ -1005,8 +1075,14 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
host->mrq = mrq;
- if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)
- || (host->flags & SDHCI_DEVICE_DEAD)) {
+ /* If polling, assume that the card is always present. */
+ if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+ present = true;
+ else
+ present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
+ SDHCI_CARD_PRESENT;
+
+ if (!present || host->flags & SDHCI_DEVICE_DEAD) {
host->mrq->cmd->error = -ENOMEDIUM;
tasklet_schedule(&host->finish_tasklet);
} else
@@ -1034,8 +1110,8 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
* Should clear out any weird states.
*/
if (ios->power_mode == MMC_POWER_OFF) {
- writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE);
- sdhci_init(host);
+ sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
+ sdhci_reinit(host);
}
sdhci_set_clock(host, ios->clock);
@@ -1045,7 +1121,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
else
sdhci_set_power(host, ios->vdd);
- ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
if (ios->bus_width == MMC_BUS_WIDTH_4)
ctrl |= SDHCI_CTRL_4BITBUS;
@@ -1057,7 +1133,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
else
ctrl &= ~SDHCI_CTRL_HISPD;
- writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
/*
* Some (ENE) controllers go apeshit on some ios operation,
@@ -1085,10 +1161,12 @@ static int sdhci_get_ro(struct mmc_host *mmc)
if (host->flags & SDHCI_DEVICE_DEAD)
present = 0;
else
- present = readl(host->ioaddr + SDHCI_PRESENT_STATE);
+ present = sdhci_readl(host, SDHCI_PRESENT_STATE);
spin_unlock_irqrestore(&host->lock, flags);
+ if (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)
+ return !!(present & SDHCI_WRITE_PROTECT);
return !(present & SDHCI_WRITE_PROTECT);
}
@@ -1096,7 +1174,6 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct sdhci_host *host;
unsigned long flags;
- u32 ier;
host = mmc_priv(mmc);
@@ -1105,15 +1182,10 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
if (host->flags & SDHCI_DEVICE_DEAD)
goto out;
- ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
-
- ier &= ~SDHCI_INT_CARD_INT;
if (enable)
- ier |= SDHCI_INT_CARD_INT;
-
- writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
- writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
-
+ sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
+ else
+ sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
out:
mmiowb();
@@ -1142,7 +1214,7 @@ static void sdhci_tasklet_card(unsigned long param)
spin_lock_irqsave(&host->lock, flags);
- if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
+ if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
if (host->mrq) {
printk(KERN_ERR "%s: Card removed during transfer!\n",
mmc_hostname(host->mmc));
@@ -1346,8 +1418,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
* we need to at least restart the transfer.
*/
if (intmask & SDHCI_INT_DMA_END)
- writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS),
- host->ioaddr + SDHCI_DMA_ADDRESS);
+ sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS),
+ SDHCI_DMA_ADDRESS);
if (intmask & SDHCI_INT_DATA_END) {
if (host->cmd) {
@@ -1373,7 +1445,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
spin_lock(&host->lock);
- intmask = readl(host->ioaddr + SDHCI_INT_STATUS);
+ intmask = sdhci_readl(host, SDHCI_INT_STATUS);
if (!intmask || intmask == 0xffffffff) {
result = IRQ_NONE;
@@ -1384,22 +1456,22 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
mmc_hostname(host->mmc), intmask);
if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
- writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE),
- host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
+ SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
tasklet_schedule(&host->card_tasklet);
}
intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
if (intmask & SDHCI_INT_CMD_MASK) {
- writel(intmask & SDHCI_INT_CMD_MASK,
- host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
+ SDHCI_INT_STATUS);
sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
}
if (intmask & SDHCI_INT_DATA_MASK) {
- writel(intmask & SDHCI_INT_DATA_MASK,
- host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
+ SDHCI_INT_STATUS);
sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
}
@@ -1410,7 +1482,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
if (intmask & SDHCI_INT_BUS_POWER) {
printk(KERN_ERR "%s: Card is consuming too much power!\n",
mmc_hostname(host->mmc));
- writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
}
intmask &= ~SDHCI_INT_BUS_POWER;
@@ -1425,7 +1497,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
mmc_hostname(host->mmc), intmask);
sdhci_dumpregs(host);
- writel(intmask, host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, intmask, SDHCI_INT_STATUS);
}
result = IRQ_HANDLED;
@@ -1455,6 +1527,8 @@ int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
{
int ret;
+ sdhci_disable_card_detection(host);
+
ret = mmc_suspend_host(host->mmc, state);
if (ret)
return ret;
@@ -1487,6 +1561,8 @@ int sdhci_resume_host(struct sdhci_host *host)
if (ret)
return ret;
+ sdhci_enable_card_detection(host);
+
return 0;
}
@@ -1537,7 +1613,7 @@ int sdhci_add_host(struct sdhci_host *host)
sdhci_reset(host, SDHCI_RESET_ALL);
- host->version = readw(host->ioaddr + SDHCI_HOST_VERSION);
+ host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
host->version = (host->version & SDHCI_SPEC_VER_MASK)
>> SDHCI_SPEC_VER_SHIFT;
if (host->version > SDHCI_SPEC_200) {
@@ -1546,7 +1622,7 @@ int sdhci_add_host(struct sdhci_host *host)
host->version);
}
- caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
+ caps = sdhci_readl(host, SDHCI_CAPABILITIES);
if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
host->flags |= SDHCI_USE_DMA;
@@ -1614,19 +1690,27 @@ int sdhci_add_host(struct sdhci_host *host)
host->max_clk =
(caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
+ host->max_clk *= 1000000;
if (host->max_clk == 0) {
- printk(KERN_ERR "%s: Hardware doesn't specify base clock "
- "frequency.\n", mmc_hostname(mmc));
- return -ENODEV;
+ if (!host->ops->get_max_clock) {
+ printk(KERN_ERR
+ "%s: Hardware doesn't specify base clock "
+ "frequency.\n", mmc_hostname(mmc));
+ return -ENODEV;
+ }
+ host->max_clk = host->ops->get_max_clock(host);
}
- host->max_clk *= 1000000;
host->timeout_clk =
(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
if (host->timeout_clk == 0) {
- printk(KERN_ERR "%s: Hardware doesn't specify timeout clock "
- "frequency.\n", mmc_hostname(mmc));
- return -ENODEV;
+ if (!host->ops->get_timeout_clock) {
+ printk(KERN_ERR
+ "%s: Hardware doesn't specify timeout clock "
+ "frequency.\n", mmc_hostname(mmc));
+ return -ENODEV;
+ }
+ host->timeout_clk = host->ops->get_timeout_clock(host);
}
if (caps & SDHCI_TIMEOUT_CLK_UNIT)
host->timeout_clk *= 1000;
@@ -1642,6 +1726,9 @@ int sdhci_add_host(struct sdhci_host *host)
if (caps & SDHCI_CAN_DO_HISPD)
mmc->caps |= MMC_CAP_SD_HIGHSPEED;
+ if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+ mmc->caps |= MMC_CAP_NEEDS_POLL;
+
mmc->ocr_avail = 0;
if (caps & SDHCI_CAN_VDD_330)
mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
@@ -1690,13 +1777,19 @@ int sdhci_add_host(struct sdhci_host *host)
* Maximum block size. This varies from controller to controller and
* is specified in the capabilities register.
*/
- mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
- if (mmc->max_blk_size >= 3) {
- printk(KERN_WARNING "%s: Invalid maximum block size, "
- "assuming 512 bytes\n", mmc_hostname(mmc));
- mmc->max_blk_size = 512;
- } else
- mmc->max_blk_size = 512 << mmc->max_blk_size;
+ if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) {
+ mmc->max_blk_size = 2;
+ } else {
+ mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >>
+ SDHCI_MAX_BLOCK_SHIFT;
+ if (mmc->max_blk_size >= 3) {
+ printk(KERN_WARNING "%s: Invalid maximum block size, "
+ "assuming 512 bytes\n", mmc_hostname(mmc));
+ mmc->max_blk_size = 0;
+ }
+ }
+
+ mmc->max_blk_size = 512 << mmc->max_blk_size;
/*
* Maximum block count.
@@ -1746,6 +1839,8 @@ int sdhci_add_host(struct sdhci_host *host)
(host->flags & SDHCI_USE_ADMA)?"A":"",
(host->flags & SDHCI_USE_DMA)?"DMA":"PIO");
+ sdhci_enable_card_detection(host);
+
return 0;
#ifdef SDHCI_USE_LEDS_CLASS
@@ -1782,6 +1877,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
spin_unlock_irqrestore(&host->lock, flags);
}
+ sdhci_disable_card_detection(host);
+
mmc_remove_host(host->mmc);
#ifdef SDHCI_USE_LEDS_CLASS
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 43c37c68d07a..f20a834f4309 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -10,6 +10,9 @@
*/
#include <linux/scatterlist.h>
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/io.h>
/*
* Controller registers
@@ -123,6 +126,7 @@
SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
SDHCI_INT_DATA_END_BIT)
+#define SDHCI_INT_ALL_MASK ((unsigned int)-1)
#define SDHCI_ACMD12_ERR 0x3C
@@ -210,6 +214,18 @@ struct sdhci_host {
#define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13)
/* Controller does not provide transfer-complete interrupt when not busy */
#define SDHCI_QUIRK_NO_BUSY_IRQ (1<<14)
+/* Controller has unreliable card detection */
+#define SDHCI_QUIRK_BROKEN_CARD_DETECTION (1<<15)
+/* Controller reports inverted write-protect state */
+#define SDHCI_QUIRK_INVERTED_WRITE_PROTECT (1<<16)
+/* Controller has nonstandard clock management */
+#define SDHCI_QUIRK_NONSTANDARD_CLOCK (1<<17)
+/* Controller does not like fast PIO transfers */
+#define SDHCI_QUIRK_PIO_NEEDS_DELAY (1<<18)
+/* Controller losing signal/interrupt enable states after reset */
+#define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET (1<<19)
+/* Controller has to be forced to use block size of 2048 bytes */
+#define SDHCI_QUIRK_FORCE_BLK_SZ_2048 (1<<20)
int irq; /* Device IRQ */
void __iomem * ioaddr; /* Mapped address */
@@ -267,9 +283,105 @@ struct sdhci_host {
struct sdhci_ops {
+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+ u32 (*readl)(struct sdhci_host *host, int reg);
+ u16 (*readw)(struct sdhci_host *host, int reg);
+ u8 (*readb)(struct sdhci_host *host, int reg);
+ void (*writel)(struct sdhci_host *host, u32 val, int reg);
+ void (*writew)(struct sdhci_host *host, u16 val, int reg);
+ void (*writeb)(struct sdhci_host *host, u8 val, int reg);
+#endif
+
+ void (*set_clock)(struct sdhci_host *host, unsigned int clock);
+
int (*enable_dma)(struct sdhci_host *host);
+ unsigned int (*get_max_clock)(struct sdhci_host *host);
+ unsigned int (*get_timeout_clock)(struct sdhci_host *host);
};
+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+
+static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+ if (unlikely(host->ops->writel))
+ host->ops->writel(host, val, reg);
+ else
+ writel(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+ if (unlikely(host->ops->writew))
+ host->ops->writew(host, val, reg);
+ else
+ writew(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+ if (unlikely(host->ops->writeb))
+ host->ops->writeb(host, val, reg);
+ else
+ writeb(val, host->ioaddr + reg);
+}
+
+static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
+{
+ if (unlikely(host->ops->readl))
+ return host->ops->readl(host, reg);
+ else
+ return readl(host->ioaddr + reg);
+}
+
+static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
+{
+ if (unlikely(host->ops->readw))
+ return host->ops->readw(host, reg);
+ else
+ return readw(host->ioaddr + reg);
+}
+
+static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
+{
+ if (unlikely(host->ops->readb))
+ return host->ops->readb(host, reg);
+ else
+ return readb(host->ioaddr + reg);
+}
+
+#else
+
+static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+ writel(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+ writew(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+ writeb(val, host->ioaddr + reg);
+}
+
+static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
+{
+ return readl(host->ioaddr + reg);
+}
+
+static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
+{
+ return readw(host->ioaddr + reg);
+}
+
+static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
+{
+ return readb(host->ioaddr + reg);
+}
+
+#endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */
extern struct sdhci_host *sdhci_alloc_host(struct device *dev,
size_t priv_size);
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index 6a7a61904833..63fbd5b7d312 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -568,11 +568,11 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
host->mmc = mmc;
platform_set_drvdata(dev, mmc);
- host->ctl = ioremap(res_ctl->start, res_ctl->end - res_ctl->start);
+ host->ctl = ioremap(res_ctl->start, resource_size(res_ctl));
if (!host->ctl)
goto host_free;
- host->cnf = ioremap(res_cnf->start, res_cnf->end - res_cnf->start);
+ host->cnf = ioremap(res_cnf->start, resource_size(res_cnf));
if (!host->cnf)
goto unmap_ctl;
@@ -650,10 +650,10 @@ static int __devexit tmio_mmc_remove(struct platform_device *dev)
if (mmc) {
struct tmio_mmc_host *host = mmc_priv(mmc);
mmc_remove_host(mmc);
- mmc_free_host(mmc);
free_irq(host->irq, host);
iounmap(host->ctl);
iounmap(host->cnf);
+ mmc_free_host(mmc);
}
return 0;
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index ba2b4240a86a..9c831ab2ece6 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -8,6 +8,9 @@
* published by the Free Software Foundation.
*
*/
+
+#include <linux/highmem.h>
+
#define CNF_CMD 0x04
#define CNF_CTL_BASE 0x10
#define CNF_INT_PIN 0x3d
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 4521b1ecce45..82d1e4de475b 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -4,7 +4,7 @@
# Core functionality.
obj-$(CONFIG_MTD) += mtd.o
-mtd-y := mtdcore.o mtdsuper.o
+mtd-y := mtdcore.o mtdsuper.o mtdbdi.o
mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o
diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c
index ecf170b55c32..6697a1ec72d0 100644
--- a/drivers/mtd/ar7part.c
+++ b/drivers/mtd/ar7part.c
@@ -44,8 +44,6 @@ struct ar7_bin_rec {
unsigned int address;
};
-static struct mtd_partition ar7_parts[AR7_PARTS];
-
static int create_mtd_partitions(struct mtd_info *master,
struct mtd_partition **pparts,
unsigned long origin)
@@ -57,7 +55,11 @@ static int create_mtd_partitions(struct mtd_info *master,
unsigned int root_offset = ROOT_OFFSET;
int retries = 10;
+ struct mtd_partition *ar7_parts;
+ ar7_parts = kzalloc(sizeof(*ar7_parts) * AR7_PARTS, GFP_KERNEL);
+ if (!ar7_parts)
+ return -ENOMEM;
ar7_parts[0].name = "loader";
ar7_parts[0].offset = 0;
ar7_parts[0].size = master->erasesize;
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index f5ab6fa1057b..c240454fd113 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -1236,10 +1236,14 @@ static int inval_cache_and_wait_for_operation(
remove_wait_queue(&chip->wq, &wait);
spin_lock(chip->mutex);
}
- if (chip->erase_suspended || chip->write_suspended) {
- /* Suspend has occured while sleep: reset timeout */
+ if (chip->erase_suspended && chip_state == FL_ERASING) {
+ /* Erase suspend occured while sleep: reset timeout */
timeo = reset_timeo;
chip->erase_suspended = 0;
+ }
+ if (chip->write_suspended && chip_state == FL_WRITING) {
+ /* Write suspend occured while sleep: reset timeout */
+ timeo = reset_timeo;
chip->write_suspended = 0;
}
}
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 94bb61e19047..61ea833e0908 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -282,6 +282,16 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param)
}
}
+static void fixup_M29W128G_write_buffer(struct mtd_info *mtd, void *param)
+{
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ if (cfi->cfiq->BufWriteTimeoutTyp) {
+ pr_warning("Don't use write buffer on ST flash M29W128G\n");
+ cfi->cfiq->BufWriteTimeoutTyp = 0;
+ }
+}
+
static struct cfi_fixup cfi_fixup_table[] = {
{ CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
#ifdef AMD_BOOTLOC_BUG
@@ -298,6 +308,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
{ CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, },
{ CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, },
{ CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, },
+ { CFI_MFR_ST, 0x227E, fixup_M29W128G_write_buffer, NULL, },
#if !FORCE_WORD_WRITE
{ CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
#endif
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index 2f3f2f719ba4..e824b9b9b056 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -159,6 +159,7 @@
#define SST39LF800 0x2781
#define SST39LF160 0x2782
#define SST39VF1601 0x234b
+#define SST39VF3201 0x235b
#define SST39LF512 0x00D4
#define SST39LF010 0x00D5
#define SST39LF020 0x00D6
@@ -1490,6 +1491,21 @@ static const struct amd_flash_info jedec_table[] = {
ERASEINFO(0x1000,256)
}
}, {
+ .mfr_id = MANUFACTURER_SST, /* should be CFI */
+ .dev_id = SST39VF3201,
+ .name = "SST 39VF3201",
+ .devtypes = CFI_DEVICETYPE_X16,
+ .uaddr = MTD_UADDR_0xAAAA_0x5555,
+ .dev_size = SIZE_4MiB,
+ .cmd_set = P_ID_AMD_STD,
+ .nr_regions = 4,
+ .regions = {
+ ERASEINFO(0x1000,256),
+ ERASEINFO(0x1000,256),
+ ERASEINFO(0x1000,256),
+ ERASEINFO(0x1000,256)
+ }
+ }, {
.mfr_id = MANUFACTURER_SST,
.dev_id = SST36VF3203,
.name = "SST 36VF3203",
diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c
index 072dd8abf33a..6bdc50c727e7 100644
--- a/drivers/mtd/chips/map_ram.c
+++ b/drivers/mtd/chips/map_ram.c
@@ -21,6 +21,8 @@ static int mapram_write (struct mtd_info *, loff_t, size_t, size_t *, const u_ch
static int mapram_erase (struct mtd_info *, struct erase_info *);
static void mapram_nop (struct mtd_info *);
static struct mtd_info *map_ram_probe(struct map_info *map);
+static unsigned long mapram_unmapped_area(struct mtd_info *, unsigned long,
+ unsigned long, unsigned long);
static struct mtd_chip_driver mapram_chipdrv = {
@@ -64,6 +66,7 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
mtd->type = MTD_RAM;
mtd->size = map->size;
mtd->erase = mapram_erase;
+ mtd->get_unmapped_area = mapram_unmapped_area;
mtd->read = mapram_read;
mtd->write = mapram_write;
mtd->sync = mapram_nop;
@@ -79,6 +82,20 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
}
+/*
+ * Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+static unsigned long mapram_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ struct map_info *map = mtd->priv;
+ return (unsigned long) map->virt + offset;
+}
+
static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
{
struct map_info *map = mtd->priv;
diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c
index c76d6e5f47ee..076090a67b90 100644
--- a/drivers/mtd/chips/map_rom.c
+++ b/drivers/mtd/chips/map_rom.c
@@ -20,6 +20,8 @@ static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_ch
static void maprom_nop (struct mtd_info *);
static struct mtd_info *map_rom_probe(struct map_info *map);
static int maprom_erase (struct mtd_info *mtd, struct erase_info *info);
+static unsigned long maprom_unmapped_area(struct mtd_info *, unsigned long,
+ unsigned long, unsigned long);
static struct mtd_chip_driver maprom_chipdrv = {
.probe = map_rom_probe,
@@ -40,6 +42,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
mtd->name = map->name;
mtd->type = MTD_ROM;
mtd->size = map->size;
+ mtd->get_unmapped_area = maprom_unmapped_area;
mtd->read = maprom_read;
mtd->write = maprom_write;
mtd->sync = maprom_nop;
@@ -53,6 +56,20 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
}
+/*
+ * Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+static unsigned long maprom_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ struct map_info *map = mtd->priv;
+ return (unsigned long) map->virt + offset;
+}
+
static int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
{
struct map_info *map = mtd->priv;
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index 50a340388e74..5011fa73f918 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -335,7 +335,11 @@ static int parse_cmdline_partitions(struct mtd_info *master,
}
offset += part->parts[i].size;
}
- *pparts = part->parts;
+ *pparts = kmemdup(part->parts,
+ sizeof(*part->parts) * part->num_parts,
+ GFP_KERNEL);
+ if (!*pparts)
+ return -ENOMEM;
return part->num_parts;
}
}
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 50de839c77a9..5bf5f460e132 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -10,7 +10,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/sched.h>
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index e32c568c1145..0990f7803628 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -10,7 +10,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index d853f891b586..719b2915dc3a 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -14,7 +14,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c
index 874e51b110a2..a19cda52da5c 100644
--- a/drivers/mtd/devices/docecc.c
+++ b/drivers/mtd/devices/docecc.c
@@ -26,7 +26,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 7c3fc766dcf1..8185b1f3e5e6 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -65,12 +65,6 @@
#define FAST_READ_DUMMY_BYTE 0
#endif
-#ifdef CONFIG_MTD_PARTITIONS
-#define mtd_has_partitions() (1)
-#else
-#define mtd_has_partitions() (0)
-#endif
-
/****************************************************************************/
struct m25p {
@@ -678,6 +672,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
flash->mtd.erasesize = info->sector_size;
}
+ flash->mtd.dev.parent = &spi->dev;
+
dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name,
(long long)flash->mtd.size >> 10);
@@ -708,12 +704,13 @@ static int __devinit m25p_probe(struct spi_device *spi)
struct mtd_partition *parts = NULL;
int nr_parts = 0;
-#ifdef CONFIG_MTD_CMDLINE_PARTS
- static const char *part_probes[] = { "cmdlinepart", NULL, };
+ if (mtd_has_cmdlinepart()) {
+ static const char *part_probes[]
+ = { "cmdlinepart", NULL, };
- nr_parts = parse_mtd_partitions(&flash->mtd,
- part_probes, &parts, 0);
-#endif
+ nr_parts = parse_mtd_partitions(&flash->mtd,
+ part_probes, &parts, 0);
+ }
if (nr_parts <= 0 && data && data->parts) {
parts = data->parts;
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 6d9f810565c8..62dee54af0a5 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -98,12 +98,6 @@ struct dataflash {
struct mtd_info mtd;
};
-#ifdef CONFIG_MTD_PARTITIONS
-#define mtd_has_partitions() (1)
-#else
-#define mtd_has_partitions() (0)
-#endif
-
/* ......................................................................... */
/*
@@ -670,6 +664,8 @@ add_dataflash_otp(struct spi_device *spi, char *name,
device->write = dataflash_write;
device->priv = priv;
+ device->dev.parent = &spi->dev;
+
if (revision >= 'c')
otp_tag = otp_setup(device, revision);
@@ -682,11 +678,13 @@ add_dataflash_otp(struct spi_device *spi, char *name,
struct mtd_partition *parts;
int nr_parts = 0;
-#ifdef CONFIG_MTD_CMDLINE_PARTS
- static const char *part_probes[] = { "cmdlinepart", NULL, };
+ if (mtd_has_cmdlinepart()) {
+ static const char *part_probes[]
+ = { "cmdlinepart", NULL, };
- nr_parts = parse_mtd_partitions(device, part_probes, &parts, 0);
-#endif
+ nr_parts = parse_mtd_partitions(device,
+ part_probes, &parts, 0);
+ }
if (nr_parts <= 0 && pdata && pdata->parts) {
parts = pdata->parts;
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
index 3aaca88847d3..fce5ff7589aa 100644
--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -65,6 +65,19 @@ static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
{
}
+/*
+ * Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+static unsigned long ram_get_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ return (unsigned long) mtd->priv + offset;
+}
+
static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
@@ -116,6 +129,7 @@ int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
mtd->erase = ram_erase;
mtd->point = ram_point;
mtd->unpoint = ram_unpoint;
+ mtd->get_unmapped_area = ram_get_unmapped_area;
mtd->read = ram_read;
mtd->write = ram_write;
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index f751dd97c549..32e82aef3e53 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -28,7 +28,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
diff --git a/include/asm-frv/ide.h b/drivers/mtd/internal.h
index 361076611855..c658fe7216b5 100644
--- a/include/asm-frv/ide.h
+++ b/drivers/mtd/internal.h
@@ -1,6 +1,6 @@
-/* ide.h: FRV IDE declarations
+/* Internal MTD definitions
*
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright © 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -9,16 +9,9 @@
* 2 of the License, or (at your option) any later version.
*/
-#ifndef _ASM_IDE_H
-#define _ASM_IDE_H
-
-#ifdef __KERNEL__
-
-#include <asm/setup.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <asm-generic/ide_iops.h>
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_IDE_H */
+/*
+ * mtdbdi.c
+ */
+extern struct backing_dev_info mtd_bdi_unmappable;
+extern struct backing_dev_info mtd_bdi_ro_mappable;
+extern struct backing_dev_info mtd_bdi_rw_mappable;
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 043d50fb6ef6..82923bd2d9c5 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -529,12 +529,6 @@ config MTD_DMV182
help
Map driver for Dy-4 SVME/DMV-182 board.
-config MTD_SHARP_SL
- tristate "ROM mapped on Sharp SL Series"
- depends on ARCH_PXA
- help
- This enables access to the flash chip on the Sharp SL Series of PDAs.
-
config MTD_INTEL_VR_NOR
tristate "NOR flash on Intel Vermilion Range Expansion Bus CS0"
depends on PCI
@@ -542,6 +536,12 @@ config MTD_INTEL_VR_NOR
Map driver for a NOR flash bank located on the Expansion Bus of the
Intel Vermilion Range chipset.
+config MTD_RBTX4939
+ tristate "Map driver for RBTX4939 board"
+ depends on TOSHIBA_RBTX4939 && MTD_CFI && MTD_COMPLEX_MAPPINGS
+ help
+ Map driver for NOR flash chips on RBTX4939 board.
+
config MTD_PLATRAM
tristate "Map driver for platform device RAM (mtd-ram)"
select MTD_RAM
@@ -551,5 +551,15 @@ config MTD_PLATRAM
This selection automatically selects the map_ram driver.
-endmenu
+config MTD_VMU
+ tristate "Map driver for Dreamcast VMU"
+ depends on MAPLE
+ help
+ This driver enables access to the Dreamcast Visual Memory Unit (VMU).
+
+ Most Dreamcast users will want to say Y here.
+ To build this as a module select M here, the module will be called
+ vmu-flash.
+
+endmenu
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 6d9ba35caf11..2dbc1bec8488 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -56,8 +56,9 @@ obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o
obj-$(CONFIG_MTD_IXP2000) += ixp2000.o
obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
obj-$(CONFIG_MTD_DMV182) += dmv182.o
-obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o
obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o
+obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o
+obj-$(CONFIG_MTD_VMU) += vmu-flash.o
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
index d2ec262666c7..c9681a339a59 100644
--- a/drivers/mtd/maps/integrator-flash.c
+++ b/drivers/mtd/maps/integrator-flash.c
@@ -31,6 +31,7 @@
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/init.h>
+#include <linux/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
@@ -38,7 +39,6 @@
#include <asm/mach/flash.h>
#include <mach/hardware.h>
-#include <asm/io.h>
#include <asm/system.h>
#ifdef CONFIG_ARCH_P720T
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index 7e50e9b1b781..a24478102b11 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -115,6 +115,8 @@ static int __init omapflash_probe(struct platform_device *pdev)
}
info->mtd->owner = THIS_MODULE;
+ info->mtd->dev.parent = &pdev->dev;
+
#ifdef CONFIG_MTD_PARTITIONS
err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0);
if (err > 0)
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index 229718222db7..29a901157352 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -147,6 +147,7 @@ static int physmap_flash_probe(struct platform_device *dev)
devices_found++;
}
info->mtd[i]->owner = THIS_MODULE;
+ info->mtd[i]->dev.parent = &dev->dev;
}
if (devices_found == 1) {
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index fbf0ca939d72..c83a60fada53 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -219,6 +219,7 @@ static int __devinit of_flash_probe(struct of_device *dev,
goto err_out;
}
info->mtd->owner = THIS_MODULE;
+ info->mtd->dev.parent = &dev->dev;
#ifdef CONFIG_MTD_PARTITIONS
/* First look for RedBoot table or partitions on the command
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index e7dd9c8a965e..49c9ece76477 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -224,6 +224,7 @@ static int platram_probe(struct platform_device *pdev)
}
info->mtd->owner = THIS_MODULE;
+ info->mtd->dev.parent = &pdev->dev;
platram_setrw(info, PLATRAM_RW);
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index 771139c5bf87..572d32fdf38a 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -41,9 +41,8 @@ struct pxa2xx_flash_info {
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-static int __init pxa2xx_flash_probe(struct device *dev)
+static int __init pxa2xx_flash_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct flash_platform_data *flash = pdev->dev.platform_data;
struct pxa2xx_flash_info *info;
struct mtd_partition *parts;
@@ -114,15 +113,15 @@ static int __init pxa2xx_flash_probe(struct device *dev)
add_mtd_device(info->mtd);
}
- dev_set_drvdata(dev, info);
+ platform_set_drvdata(pdev, info);
return 0;
}
-static int __exit pxa2xx_flash_remove(struct device *dev)
+static int __devexit pxa2xx_flash_remove(struct platform_device *dev)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
#ifdef CONFIG_MTD_PARTITIONS
if (info->nr_parts)
@@ -141,9 +140,9 @@ static int __exit pxa2xx_flash_remove(struct device *dev)
}
#ifdef CONFIG_PM
-static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state)
+static int pxa2xx_flash_suspend(struct platform_device *dev, pm_message_t state)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
int ret = 0;
if (info->mtd && info->mtd->suspend)
@@ -151,17 +150,17 @@ static int pxa2xx_flash_suspend(struct device *dev, pm_message_t state)
return ret;
}
-static int pxa2xx_flash_resume(struct device *dev)
+static int pxa2xx_flash_resume(struct platform_device *dev)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
if (info->mtd && info->mtd->resume)
info->mtd->resume(info->mtd);
return 0;
}
-static void pxa2xx_flash_shutdown(struct device *dev)
+static void pxa2xx_flash_shutdown(struct platform_device *dev)
{
- struct pxa2xx_flash_info *info = dev_get_drvdata(dev);
+ struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
if (info && info->mtd->suspend(info->mtd) == 0)
info->mtd->resume(info->mtd);
@@ -172,11 +171,13 @@ static void pxa2xx_flash_shutdown(struct device *dev)
#define pxa2xx_flash_shutdown NULL
#endif
-static struct device_driver pxa2xx_flash_driver = {
- .name = "pxa2xx-flash",
- .bus = &platform_bus_type,
+static struct platform_driver pxa2xx_flash_driver = {
+ .driver = {
+ .name = "pxa2xx-flash",
+ .owner = THIS_MODULE,
+ },
.probe = pxa2xx_flash_probe,
- .remove = __exit_p(pxa2xx_flash_remove),
+ .remove = __devexit_p(pxa2xx_flash_remove),
.suspend = pxa2xx_flash_suspend,
.resume = pxa2xx_flash_resume,
.shutdown = pxa2xx_flash_shutdown,
@@ -184,12 +185,12 @@ static struct device_driver pxa2xx_flash_driver = {
static int __init init_pxa2xx_flash(void)
{
- return driver_register(&pxa2xx_flash_driver);
+ return platform_driver_register(&pxa2xx_flash_driver);
}
static void __exit cleanup_pxa2xx_flash(void)
{
- driver_unregister(&pxa2xx_flash_driver);
+ platform_driver_unregister(&pxa2xx_flash_driver);
}
module_init(init_pxa2xx_flash);
diff --git a/drivers/mtd/maps/rbtx4939-flash.c b/drivers/mtd/maps/rbtx4939-flash.c
new file mode 100644
index 000000000000..d39f0adac846
--- /dev/null
+++ b/drivers/mtd/maps/rbtx4939-flash.c
@@ -0,0 +1,208 @@
+/*
+ * rbtx4939-flash (based on physmap.c)
+ *
+ * This is a simplified physmap driver with map_init callback function.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (C) 2009 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <asm/txx9/rbtx4939.h>
+
+struct rbtx4939_flash_info {
+ struct mtd_info *mtd;
+ struct map_info map;
+#ifdef CONFIG_MTD_PARTITIONS
+ int nr_parts;
+ struct mtd_partition *parts;
+#endif
+};
+
+static int rbtx4939_flash_remove(struct platform_device *dev)
+{
+ struct rbtx4939_flash_info *info;
+
+ info = platform_get_drvdata(dev);
+ if (!info)
+ return 0;
+ platform_set_drvdata(dev, NULL);
+
+ if (info->mtd) {
+#ifdef CONFIG_MTD_PARTITIONS
+ struct rbtx4939_flash_data *pdata = dev->dev.platform_data;
+
+ if (info->nr_parts) {
+ del_mtd_partitions(info->mtd);
+ kfree(info->parts);
+ } else if (pdata->nr_parts)
+ del_mtd_partitions(info->mtd);
+ else
+ del_mtd_device(info->mtd);
+#else
+ del_mtd_device(info->mtd);
+#endif
+ map_destroy(info->mtd);
+ }
+ return 0;
+}
+
+static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probe_types[] = { "cmdlinepart", NULL };
+#endif
+
+static int rbtx4939_flash_probe(struct platform_device *dev)
+{
+ struct rbtx4939_flash_data *pdata;
+ struct rbtx4939_flash_info *info;
+ struct resource *res;
+ const char **probe_type;
+ int err = 0;
+ unsigned long size;
+
+ pdata = dev->dev.platform_data;
+ if (!pdata)
+ return -ENODEV;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+ info = devm_kzalloc(&dev->dev, sizeof(struct rbtx4939_flash_info),
+ GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ platform_set_drvdata(dev, info);
+
+ size = resource_size(res);
+ pr_notice("rbtx4939 platform flash device: %pR\n", res);
+
+ if (!devm_request_mem_region(&dev->dev, res->start, size,
+ dev_name(&dev->dev)))
+ return -EBUSY;
+
+ info->map.name = dev_name(&dev->dev);
+ info->map.phys = res->start;
+ info->map.size = size;
+ info->map.bankwidth = pdata->width;
+
+ info->map.virt = devm_ioremap(&dev->dev, info->map.phys, size);
+ if (!info->map.virt)
+ return -EBUSY;
+
+ if (pdata->map_init)
+ (*pdata->map_init)(&info->map);
+ else
+ simple_map_init(&info->map);
+
+ probe_type = rom_probe_types;
+ for (; !info->mtd && *probe_type; probe_type++)
+ info->mtd = do_map_probe(*probe_type, &info->map);
+ if (!info->mtd) {
+ dev_err(&dev->dev, "map_probe failed\n");
+ err = -ENXIO;
+ goto err_out;
+ }
+ info->mtd->owner = THIS_MODULE;
+ if (err)
+ goto err_out;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ err = parse_mtd_partitions(info->mtd, part_probe_types,
+ &info->parts, 0);
+ if (err > 0) {
+ add_mtd_partitions(info->mtd, info->parts, err);
+ info->nr_parts = err;
+ return 0;
+ }
+
+ if (pdata->nr_parts) {
+ pr_notice("Using rbtx4939 partition information\n");
+ add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
+ return 0;
+ }
+#endif
+
+ add_mtd_device(info->mtd);
+ return 0;
+
+err_out:
+ rbtx4939_flash_remove(dev);
+ return err;
+}
+
+#ifdef CONFIG_PM
+static int rbtx4939_flash_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
+
+ if (info->mtd->suspend)
+ return info->mtd->suspend(info->mtd);
+ return 0;
+}
+
+static int rbtx4939_flash_resume(struct platform_device *dev)
+{
+ struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
+
+ if (info->mtd->resume)
+ info->mtd->resume(info->mtd);
+ return 0;
+}
+
+static void rbtx4939_flash_shutdown(struct platform_device *dev)
+{
+ struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
+
+ if (info->mtd->suspend && info->mtd->resume)
+ if (info->mtd->suspend(info->mtd) == 0)
+ info->mtd->resume(info->mtd);
+}
+#else
+#define rbtx4939_flash_suspend NULL
+#define rbtx4939_flash_resume NULL
+#define rbtx4939_flash_shutdown NULL
+#endif
+
+static struct platform_driver rbtx4939_flash_driver = {
+ .probe = rbtx4939_flash_probe,
+ .remove = rbtx4939_flash_remove,
+ .suspend = rbtx4939_flash_suspend,
+ .resume = rbtx4939_flash_resume,
+ .shutdown = rbtx4939_flash_shutdown,
+ .driver = {
+ .name = "rbtx4939-flash",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init rbtx4939_flash_init(void)
+{
+ return platform_driver_register(&rbtx4939_flash_driver);
+}
+
+static void __exit rbtx4939_flash_exit(void)
+{
+ platform_driver_unregister(&rbtx4939_flash_driver);
+}
+
+module_init(rbtx4939_flash_init);
+module_exit(rbtx4939_flash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RBTX4939 MTD map driver");
+MODULE_ALIAS("platform:rbtx4939-flash");
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 6f6a0f6dafd6..05e9362dc7f0 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/err.h>
+#include <linux/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
@@ -19,7 +20,6 @@
#include <linux/mtd/concat.h>
#include <mach/hardware.h>
-#include <asm/io.h>
#include <asm/sizes.h>
#include <asm/mach/flash.h>
@@ -351,7 +351,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat)
static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
-static int __init sa1100_mtd_probe(struct platform_device *pdev)
+static int __devinit sa1100_mtd_probe(struct platform_device *pdev)
{
struct flash_platform_data *plat = pdev->dev.platform_data;
struct mtd_partition *parts;
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
deleted file mode 100644
index b392f096c706..000000000000
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * sharpsl-flash.c
- *
- * Copyright (C) 2001 Lineo Japan, Inc.
- * Copyright (C) 2002 SHARP
- *
- * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp
- * Handle mapping of the flash on the RPX Lite and CLLF boards
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <asm/mach-types.h>
-
-#define WINDOW_ADDR 0x00000000
-#define WINDOW_SIZE 0x00800000
-#define BANK_WIDTH 2
-
-static struct mtd_info *mymtd;
-
-struct map_info sharpsl_map = {
- .name = "sharpsl-flash",
- .size = WINDOW_SIZE,
- .bankwidth = BANK_WIDTH,
- .phys = WINDOW_ADDR
-};
-
-static struct mtd_partition sharpsl_partitions[1] = {
- {
- name: "Boot PROM Filesystem",
- }
-};
-
-static int __init init_sharpsl(void)
-{
- struct mtd_partition *parts;
- int nb_parts = 0;
- char *part_type = "static";
-
- printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
- WINDOW_SIZE, WINDOW_ADDR);
- sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
- if (!sharpsl_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-
- simple_map_init(&sharpsl_map);
-
- mymtd = do_map_probe("map_rom", &sharpsl_map);
- if (!mymtd) {
- iounmap(sharpsl_map.virt);
- return -ENXIO;
- }
-
- mymtd->owner = THIS_MODULE;
-
- if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
- || machine_is_poodle()) {
- sharpsl_partitions[0].size=0x006d0000;
- sharpsl_partitions[0].offset=0x00120000;
- } else if (machine_is_tosa()) {
- sharpsl_partitions[0].size=0x006a0000;
- sharpsl_partitions[0].offset=0x00160000;
- } else if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi()) {
- sharpsl_partitions[0].size=0x006b0000;
- sharpsl_partitions[0].offset=0x00140000;
- } else {
- map_destroy(mymtd);
- iounmap(sharpsl_map.virt);
- return -ENODEV;
- }
-
- parts = sharpsl_partitions;
- nb_parts = ARRAY_SIZE(sharpsl_partitions);
-
- printk(KERN_NOTICE "Using %s partition definition\n", part_type);
- add_mtd_partitions(mymtd, parts, nb_parts);
-
- return 0;
-}
-
-static void __exit cleanup_sharpsl(void)
-{
- if (mymtd) {
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
- if (sharpsl_map.virt) {
- iounmap(sharpsl_map.virt);
- sharpsl_map.virt = 0;
- }
-}
-
-module_init(init_sharpsl);
-module_exit(cleanup_sharpsl);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("SHARP (Original: Arnold Christensen <AKC@pel.dk>)");
-MODULE_DESCRIPTION("MTD map driver for SHARP SL series");
diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c
new file mode 100644
index 000000000000..1f73297e7776
--- /dev/null
+++ b/drivers/mtd/maps/vmu-flash.c
@@ -0,0 +1,832 @@
+/* vmu-flash.c
+ * Driver for SEGA Dreamcast Visual Memory Unit
+ *
+ * Copyright (c) Adrian McMenamin 2002 - 2009
+ * Copyright (c) Paul Mundt 2001
+ *
+ * Licensed under version 2 of the
+ * GNU General Public Licence
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/maple.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+
+struct vmu_cache {
+ unsigned char *buffer; /* Cache */
+ unsigned int block; /* Which block was cached */
+ unsigned long jiffies_atc; /* When was it cached? */
+ int valid;
+};
+
+struct mdev_part {
+ struct maple_device *mdev;
+ int partition;
+};
+
+struct vmupart {
+ u16 user_blocks;
+ u16 root_block;
+ u16 numblocks;
+ char *name;
+ struct vmu_cache *pcache;
+};
+
+struct memcard {
+ u16 tempA;
+ u16 tempB;
+ u32 partitions;
+ u32 blocklen;
+ u32 writecnt;
+ u32 readcnt;
+ u32 removeable;
+ int partition;
+ int read;
+ unsigned char *blockread;
+ struct vmupart *parts;
+ struct mtd_info *mtd;
+};
+
+struct vmu_block {
+ unsigned int num; /* block number */
+ unsigned int ofs; /* block offset */
+};
+
+static struct vmu_block *ofs_to_block(unsigned long src_ofs,
+ struct mtd_info *mtd, int partition)
+{
+ struct vmu_block *vblock;
+ struct maple_device *mdev;
+ struct memcard *card;
+ struct mdev_part *mpart;
+ int num;
+
+ mpart = mtd->priv;
+ mdev = mpart->mdev;
+ card = maple_get_drvdata(mdev);
+
+ if (src_ofs >= card->parts[partition].numblocks * card->blocklen)
+ goto failed;
+
+ num = src_ofs / card->blocklen;
+ if (num > card->parts[partition].numblocks)
+ goto failed;
+
+ vblock = kmalloc(sizeof(struct vmu_block), GFP_KERNEL);
+ if (!vblock)
+ goto failed;
+
+ vblock->num = num;
+ vblock->ofs = src_ofs % card->blocklen;
+ return vblock;
+
+failed:
+ return NULL;
+}
+
+/* Maple bus callback function for reads */
+static void vmu_blockread(struct mapleq *mq)
+{
+ struct maple_device *mdev;
+ struct memcard *card;
+
+ mdev = mq->dev;
+ card = maple_get_drvdata(mdev);
+ /* copy the read in data */
+
+ if (unlikely(!card->blockread))
+ return;
+
+ memcpy(card->blockread, mq->recvbuf->buf + 12,
+ card->blocklen/card->readcnt);
+
+}
+
+/* Interface with maple bus to read blocks
+ * caching the results so that other parts
+ * of the driver can access block reads */
+static int maple_vmu_read_block(unsigned int num, unsigned char *buf,
+ struct mtd_info *mtd)
+{
+ struct memcard *card;
+ struct mdev_part *mpart;
+ struct maple_device *mdev;
+ int partition, error = 0, x, wait;
+ unsigned char *blockread = NULL;
+ struct vmu_cache *pcache;
+ __be32 sendbuf;
+
+ mpart = mtd->priv;
+ mdev = mpart->mdev;
+ partition = mpart->partition;
+ card = maple_get_drvdata(mdev);
+ pcache = card->parts[partition].pcache;
+ pcache->valid = 0;
+
+ /* prepare the cache for this block */
+ if (!pcache->buffer) {
+ pcache->buffer = kmalloc(card->blocklen, GFP_KERNEL);
+ if (!pcache->buffer) {
+ dev_err(&mdev->dev, "VMU at (%d, %d) - read fails due"
+ " to lack of memory\n", mdev->port,
+ mdev->unit);
+ error = -ENOMEM;
+ goto outB;
+ }
+ }
+
+ /*
+ * Reads may be phased - again the hardware spec
+ * supports this - though may not be any devices in
+ * the wild that implement it, but we will here
+ */
+ for (x = 0; x < card->readcnt; x++) {
+ sendbuf = cpu_to_be32(partition << 24 | x << 16 | num);
+
+ if (atomic_read(&mdev->busy) == 1) {
+ wait_event_interruptible_timeout(mdev->maple_wait,
+ atomic_read(&mdev->busy) == 0, HZ);
+ if (atomic_read(&mdev->busy) == 1) {
+ dev_notice(&mdev->dev, "VMU at (%d, %d)"
+ " is busy\n", mdev->port, mdev->unit);
+ error = -EAGAIN;
+ goto outB;
+ }
+ }
+
+ atomic_set(&mdev->busy, 1);
+ blockread = kmalloc(card->blocklen/card->readcnt, GFP_KERNEL);
+ if (!blockread) {
+ error = -ENOMEM;
+ atomic_set(&mdev->busy, 0);
+ goto outB;
+ }
+ card->blockread = blockread;
+
+ maple_getcond_callback(mdev, vmu_blockread, 0,
+ MAPLE_FUNC_MEMCARD);
+ error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
+ MAPLE_COMMAND_BREAD, 2, &sendbuf);
+ /* Very long timeouts seem to be needed when box is stressed */
+ wait = wait_event_interruptible_timeout(mdev->maple_wait,
+ (atomic_read(&mdev->busy) == 0 ||
+ atomic_read(&mdev->busy) == 2), HZ * 3);
+ /*
+ * MTD layer does not handle hotplugging well
+ * so have to return errors when VMU is unplugged
+ * in the middle of a read (busy == 2)
+ */
+ if (error || atomic_read(&mdev->busy) == 2) {
+ if (atomic_read(&mdev->busy) == 2)
+ error = -ENXIO;
+ atomic_set(&mdev->busy, 0);
+ card->blockread = NULL;
+ goto outA;
+ }
+ if (wait == 0 || wait == -ERESTARTSYS) {
+ card->blockread = NULL;
+ atomic_set(&mdev->busy, 0);
+ error = -EIO;
+ list_del_init(&(mdev->mq->list));
+ kfree(mdev->mq->sendbuf);
+ mdev->mq->sendbuf = NULL;
+ if (wait == -ERESTARTSYS) {
+ dev_warn(&mdev->dev, "VMU read on (%d, %d)"
+ " interrupted on block 0x%X\n",
+ mdev->port, mdev->unit, num);
+ } else
+ dev_notice(&mdev->dev, "VMU read on (%d, %d)"
+ " timed out on block 0x%X\n",
+ mdev->port, mdev->unit, num);
+ goto outA;
+ }
+
+ memcpy(buf + (card->blocklen/card->readcnt) * x, blockread,
+ card->blocklen/card->readcnt);
+
+ memcpy(pcache->buffer + (card->blocklen/card->readcnt) * x,
+ card->blockread, card->blocklen/card->readcnt);
+ card->blockread = NULL;
+ pcache->block = num;
+ pcache->jiffies_atc = jiffies;
+ pcache->valid = 1;
+ kfree(blockread);
+ }
+
+ return error;
+
+outA:
+ kfree(blockread);
+outB:
+ return error;
+}
+
+/* communicate with maple bus for phased writing */
+static int maple_vmu_write_block(unsigned int num, const unsigned char *buf,
+ struct mtd_info *mtd)
+{
+ struct memcard *card;
+ struct mdev_part *mpart;
+ struct maple_device *mdev;
+ int partition, error, locking, x, phaselen, wait;
+ __be32 *sendbuf;
+
+ mpart = mtd->priv;
+ mdev = mpart->mdev;
+ partition = mpart->partition;
+ card = maple_get_drvdata(mdev);
+
+ phaselen = card->blocklen/card->writecnt;
+
+ sendbuf = kmalloc(phaselen + 4, GFP_KERNEL);
+ if (!sendbuf) {
+ error = -ENOMEM;
+ goto fail_nosendbuf;
+ }
+ for (x = 0; x < card->writecnt; x++) {
+ sendbuf[0] = cpu_to_be32(partition << 24 | x << 16 | num);
+ memcpy(&sendbuf[1], buf + phaselen * x, phaselen);
+ /* wait until the device is not busy doing something else
+ * or 1 second - which ever is longer */
+ if (atomic_read(&mdev->busy) == 1) {
+ wait_event_interruptible_timeout(mdev->maple_wait,
+ atomic_read(&mdev->busy) == 0, HZ);
+ if (atomic_read(&mdev->busy) == 1) {
+ error = -EBUSY;
+ dev_notice(&mdev->dev, "VMU write at (%d, %d)"
+ "failed - device is busy\n",
+ mdev->port, mdev->unit);
+ goto fail_nolock;
+ }
+ }
+ atomic_set(&mdev->busy, 1);
+
+ locking = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
+ MAPLE_COMMAND_BWRITE, phaselen / 4 + 2, sendbuf);
+ wait = wait_event_interruptible_timeout(mdev->maple_wait,
+ atomic_read(&mdev->busy) == 0, HZ/10);
+ if (locking) {
+ error = -EIO;
+ atomic_set(&mdev->busy, 0);
+ goto fail_nolock;
+ }
+ if (atomic_read(&mdev->busy) == 2) {
+ atomic_set(&mdev->busy, 0);
+ } else if (wait == 0 || wait == -ERESTARTSYS) {
+ error = -EIO;
+ dev_warn(&mdev->dev, "Write at (%d, %d) of block"
+ " 0x%X at phase %d failed: could not"
+ " communicate with VMU", mdev->port,
+ mdev->unit, num, x);
+ atomic_set(&mdev->busy, 0);
+ kfree(mdev->mq->sendbuf);
+ mdev->mq->sendbuf = NULL;
+ list_del_init(&(mdev->mq->list));
+ goto fail_nolock;
+ }
+ }
+ kfree(sendbuf);
+
+ return card->blocklen;
+
+fail_nolock:
+ kfree(sendbuf);
+fail_nosendbuf:
+ dev_err(&mdev->dev, "VMU (%d, %d): write failed\n", mdev->port,
+ mdev->unit);
+ return error;
+}
+
+/* mtd function to simulate reading byte by byte */
+static unsigned char vmu_flash_read_char(unsigned long ofs, int *retval,
+ struct mtd_info *mtd)
+{
+ struct vmu_block *vblock;
+ struct memcard *card;
+ struct mdev_part *mpart;
+ struct maple_device *mdev;
+ unsigned char *buf, ret;
+ int partition, error;
+
+ mpart = mtd->priv;
+ mdev = mpart->mdev;
+ partition = mpart->partition;
+ card = maple_get_drvdata(mdev);
+ *retval = 0;
+
+ buf = kmalloc(card->blocklen, GFP_KERNEL);
+ if (!buf) {
+ *retval = 1;
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ vblock = ofs_to_block(ofs, mtd, partition);
+ if (!vblock) {
+ *retval = 3;
+ ret = -ENOMEM;
+ goto out_buf;
+ }
+
+ error = maple_vmu_read_block(vblock->num, buf, mtd);
+ if (error) {
+ ret = error;
+ *retval = 2;
+ goto out_vblock;
+ }
+
+ ret = buf[vblock->ofs];
+
+out_vblock:
+ kfree(vblock);
+out_buf:
+ kfree(buf);
+finish:
+ return ret;
+}
+
+/* mtd higher order function to read flash */
+static int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct maple_device *mdev;
+ struct memcard *card;
+ struct mdev_part *mpart;
+ struct vmu_cache *pcache;
+ struct vmu_block *vblock;
+ int index = 0, retval, partition, leftover, numblocks;
+ unsigned char cx;
+
+ if (len < 1)
+ return -EIO;
+
+ mpart = mtd->priv;
+ mdev = mpart->mdev;
+ partition = mpart->partition;
+ card = maple_get_drvdata(mdev);
+
+ numblocks = card->parts[partition].numblocks;
+ if (from + len > numblocks * card->blocklen)
+ len = numblocks * card->blocklen - from;
+ if (len == 0)
+ return -EIO;
+ /* Have we cached this bit already? */
+ pcache = card->parts[partition].pcache;
+ do {
+ vblock = ofs_to_block(from + index, mtd, partition);
+ if (!vblock)
+ return -ENOMEM;
+ /* Have we cached this and is the cache valid and timely? */
+ if (pcache->valid &&
+ time_before(jiffies, pcache->jiffies_atc + HZ) &&
+ (pcache->block == vblock->num)) {
+ /* we have cached it, so do necessary copying */
+ leftover = card->blocklen - vblock->ofs;
+ if (vblock->ofs + len - index < card->blocklen) {
+ /* only a bit of this block to copy */
+ memcpy(buf + index,
+ pcache->buffer + vblock->ofs,
+ len - index);
+ index = len;
+ } else {
+ /* otherwise copy remainder of whole block */
+ memcpy(buf + index, pcache->buffer +
+ vblock->ofs, leftover);
+ index += leftover;
+ }
+ } else {
+ /*
+ * Not cached so read one byte -
+ * but cache the rest of the block
+ */
+ cx = vmu_flash_read_char(from + index, &retval, mtd);
+ if (retval) {
+ *retlen = index;
+ kfree(vblock);
+ return cx;
+ }
+ memset(buf + index, cx, 1);
+ index++;
+ }
+ kfree(vblock);
+ } while (len > index);
+ *retlen = index;
+
+ return 0;
+}
+
+static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
+{
+ struct maple_device *mdev;
+ struct memcard *card;
+ struct mdev_part *mpart;
+ int index = 0, partition, error = 0, numblocks;
+ struct vmu_cache *pcache;
+ struct vmu_block *vblock;
+ unsigned char *buffer;
+
+ mpart = mtd->priv;
+ mdev = mpart->mdev;
+ partition = mpart->partition;
+ card = maple_get_drvdata(mdev);
+
+ /* simple sanity checks */
+ if (len < 1) {
+ error = -EIO;
+ goto failed;
+ }
+ numblocks = card->parts[partition].numblocks;
+ if (to + len > numblocks * card->blocklen)
+ len = numblocks * card->blocklen - to;
+ if (len == 0) {
+ error = -EIO;
+ goto failed;
+ }
+
+ vblock = ofs_to_block(to, mtd, partition);
+ if (!vblock) {
+ error = -ENOMEM;
+ goto failed;
+ }
+
+ buffer = kmalloc(card->blocklen, GFP_KERNEL);
+ if (!buffer) {
+ error = -ENOMEM;
+ goto fail_buffer;
+ }
+
+ do {
+ /* Read in the block we are to write to */
+ error = maple_vmu_read_block(vblock->num, buffer, mtd);
+ if (error)
+ goto fail_io;
+
+ do {
+ buffer[vblock->ofs] = buf[index];
+ vblock->ofs++;
+ index++;
+ if (index >= len)
+ break;
+ } while (vblock->ofs < card->blocklen);
+
+ /* write out new buffer */
+ error = maple_vmu_write_block(vblock->num, buffer, mtd);
+ /* invalidate the cache */
+ pcache = card->parts[partition].pcache;
+ pcache->valid = 0;
+
+ if (error != card->blocklen)
+ goto fail_io;
+
+ vblock->num++;
+ vblock->ofs = 0;
+ } while (len > index);
+
+ kfree(buffer);
+ *retlen = index;
+ kfree(vblock);
+ return 0;
+
+fail_io:
+ kfree(buffer);
+fail_buffer:
+ kfree(vblock);
+failed:
+ dev_err(&mdev->dev, "VMU write failing with error %d\n", error);
+ return error;
+}
+
+static void vmu_flash_sync(struct mtd_info *mtd)
+{
+ /* Do nothing here */
+}
+
+/* Maple bus callback function to recursively query hardware details */
+static void vmu_queryblocks(struct mapleq *mq)
+{
+ struct maple_device *mdev;
+ unsigned short *res;
+ struct memcard *card;
+ __be32 partnum;
+ struct vmu_cache *pcache;
+ struct mdev_part *mpart;
+ struct mtd_info *mtd_cur;
+ struct vmupart *part_cur;
+ int error;
+
+ mdev = mq->dev;
+ card = maple_get_drvdata(mdev);
+ res = (unsigned short *) (mq->recvbuf->buf);
+ card->tempA = res[12];
+ card->tempB = res[6];
+
+ dev_info(&mdev->dev, "VMU device at partition %d has %d user "
+ "blocks with a root block at %d\n", card->partition,
+ card->tempA, card->tempB);
+
+ part_cur = &card->parts[card->partition];
+ part_cur->user_blocks = card->tempA;
+ part_cur->root_block = card->tempB;
+ part_cur->numblocks = card->tempB + 1;
+ part_cur->name = kmalloc(12, GFP_KERNEL);
+ if (!part_cur->name)
+ goto fail_name;
+
+ sprintf(part_cur->name, "vmu%d.%d.%d",
+ mdev->port, mdev->unit, card->partition);
+ mtd_cur = &card->mtd[card->partition];
+ mtd_cur->name = part_cur->name;
+ mtd_cur->type = 8;
+ mtd_cur->flags = MTD_WRITEABLE|MTD_NO_ERASE;
+ mtd_cur->size = part_cur->numblocks * card->blocklen;
+ mtd_cur->erasesize = card->blocklen;
+ mtd_cur->write = vmu_flash_write;
+ mtd_cur->read = vmu_flash_read;
+ mtd_cur->sync = vmu_flash_sync;
+ mtd_cur->writesize = card->blocklen;
+
+ mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL);
+ if (!mpart)
+ goto fail_mpart;
+
+ mpart->mdev = mdev;
+ mpart->partition = card->partition;
+ mtd_cur->priv = mpart;
+ mtd_cur->owner = THIS_MODULE;
+
+ pcache = kzalloc(sizeof(struct vmu_cache), GFP_KERNEL);
+ if (!pcache)
+ goto fail_cache_create;
+ part_cur->pcache = pcache;
+
+ error = add_mtd_device(mtd_cur);
+ if (error)
+ goto fail_mtd_register;
+
+ maple_getcond_callback(mdev, NULL, 0,
+ MAPLE_FUNC_MEMCARD);
+
+ /*
+ * Set up a recursive call to the (probably theoretical)
+ * second or more partition
+ */
+ if (++card->partition < card->partitions) {
+ partnum = cpu_to_be32(card->partition << 24);
+ maple_getcond_callback(mdev, vmu_queryblocks, 0,
+ MAPLE_FUNC_MEMCARD);
+ maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
+ MAPLE_COMMAND_GETMINFO, 2, &partnum);
+ }
+ return;
+
+fail_mtd_register:
+ dev_err(&mdev->dev, "Could not register maple device at (%d, %d)"
+ "error is 0x%X\n", mdev->port, mdev->unit, error);
+ for (error = 0; error <= card->partition; error++) {
+ kfree(((card->parts)[error]).pcache);
+ ((card->parts)[error]).pcache = NULL;
+ }
+fail_cache_create:
+fail_mpart:
+ for (error = 0; error <= card->partition; error++) {
+ kfree(((card->mtd)[error]).priv);
+ ((card->mtd)[error]).priv = NULL;
+ }
+ maple_getcond_callback(mdev, NULL, 0,
+ MAPLE_FUNC_MEMCARD);
+ kfree(part_cur->name);
+fail_name:
+ return;
+}
+
+/* Handles very basic info about the flash, queries for details */
+static int __devinit vmu_connect(struct maple_device *mdev)
+{
+ unsigned long test_flash_data, basic_flash_data;
+ int c, error;
+ struct memcard *card;
+ u32 partnum = 0;
+
+ test_flash_data = be32_to_cpu(mdev->devinfo.function);
+ /* Need to count how many bits are set - to find out which
+ * function_data element has details of the memory card:
+ * using Brian Kernighan's/Peter Wegner's method */
+ for (c = 0; test_flash_data; c++)
+ test_flash_data &= test_flash_data - 1;
+
+ basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]);
+
+ card = kmalloc(sizeof(struct memcard), GFP_KERNEL);
+ if (!card) {
+ error = ENOMEM;
+ goto fail_nomem;
+ }
+
+ card->partitions = (basic_flash_data >> 24 & 0xFF) + 1;
+ card->blocklen = ((basic_flash_data >> 16 & 0xFF) + 1) << 5;
+ card->writecnt = basic_flash_data >> 12 & 0xF;
+ card->readcnt = basic_flash_data >> 8 & 0xF;
+ card->removeable = basic_flash_data >> 7 & 1;
+
+ card->partition = 0;
+
+ /*
+ * Not sure there are actually any multi-partition devices in the
+ * real world, but the hardware supports them, so, so will we
+ */
+ card->parts = kmalloc(sizeof(struct vmupart) * card->partitions,
+ GFP_KERNEL);
+ if (!card->parts) {
+ error = -ENOMEM;
+ goto fail_partitions;
+ }
+
+ card->mtd = kmalloc(sizeof(struct mtd_info) * card->partitions,
+ GFP_KERNEL);
+ if (!card->mtd) {
+ error = -ENOMEM;
+ goto fail_mtd_info;
+ }
+
+ maple_set_drvdata(mdev, card);
+
+ /*
+ * We want to trap meminfo not get cond
+ * so set interval to zero, but rely on maple bus
+ * driver to pass back the results of the meminfo
+ */
+ maple_getcond_callback(mdev, vmu_queryblocks, 0,
+ MAPLE_FUNC_MEMCARD);
+
+ /* Make sure we are clear to go */
+ if (atomic_read(&mdev->busy) == 1) {
+ wait_event_interruptible_timeout(mdev->maple_wait,
+ atomic_read(&mdev->busy) == 0, HZ);
+ if (atomic_read(&mdev->busy) == 1) {
+ dev_notice(&mdev->dev, "VMU at (%d, %d) is busy\n",
+ mdev->port, mdev->unit);
+ error = -EAGAIN;
+ goto fail_device_busy;
+ }
+ }
+
+ atomic_set(&mdev->busy, 1);
+
+ /*
+ * Set up the minfo call: vmu_queryblocks will handle
+ * the information passed back
+ */
+ error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
+ MAPLE_COMMAND_GETMINFO, 2, &partnum);
+ if (error) {
+ dev_err(&mdev->dev, "Could not lock VMU at (%d, %d)"
+ " error is 0x%X\n", mdev->port, mdev->unit, error);
+ goto fail_mtd_info;
+ }
+ return 0;
+
+fail_device_busy:
+ kfree(card->mtd);
+fail_mtd_info:
+ kfree(card->parts);
+fail_partitions:
+ kfree(card);
+fail_nomem:
+ return error;
+}
+
+static void __devexit vmu_disconnect(struct maple_device *mdev)
+{
+ struct memcard *card;
+ struct mdev_part *mpart;
+ int x;
+
+ mdev->callback = NULL;
+ card = maple_get_drvdata(mdev);
+ for (x = 0; x < card->partitions; x++) {
+ mpart = ((card->mtd)[x]).priv;
+ mpart->mdev = NULL;
+ del_mtd_device(&((card->mtd)[x]));
+ kfree(((card->parts)[x]).name);
+ }
+ kfree(card->parts);
+ kfree(card->mtd);
+ kfree(card);
+}
+
+/* Callback to handle eccentricities of both mtd subsystem
+ * and general flakyness of Dreamcast VMUs
+ */
+static int vmu_can_unload(struct maple_device *mdev)
+{
+ struct memcard *card;
+ int x;
+ struct mtd_info *mtd;
+
+ card = maple_get_drvdata(mdev);
+ for (x = 0; x < card->partitions; x++) {
+ mtd = &((card->mtd)[x]);
+ if (mtd->usecount > 0)
+ return 0;
+ }
+ return 1;
+}
+
+#define ERRSTR "VMU at (%d, %d) file error -"
+
+static void vmu_file_error(struct maple_device *mdev, void *recvbuf)
+{
+ enum maple_file_errors error = ((int *)recvbuf)[1];
+
+ switch (error) {
+
+ case MAPLE_FILEERR_INVALID_PARTITION:
+ dev_notice(&mdev->dev, ERRSTR " invalid partition number\n",
+ mdev->port, mdev->unit);
+ break;
+
+ case MAPLE_FILEERR_PHASE_ERROR:
+ dev_notice(&mdev->dev, ERRSTR " phase error\n",
+ mdev->port, mdev->unit);
+ break;
+
+ case MAPLE_FILEERR_INVALID_BLOCK:
+ dev_notice(&mdev->dev, ERRSTR " invalid block number\n",
+ mdev->port, mdev->unit);
+ break;
+
+ case MAPLE_FILEERR_WRITE_ERROR:
+ dev_notice(&mdev->dev, ERRSTR " write error\n",
+ mdev->port, mdev->unit);
+ break;
+
+ case MAPLE_FILEERR_INVALID_WRITE_LENGTH:
+ dev_notice(&mdev->dev, ERRSTR " invalid write length\n",
+ mdev->port, mdev->unit);
+ break;
+
+ case MAPLE_FILEERR_BAD_CRC:
+ dev_notice(&mdev->dev, ERRSTR " bad CRC\n",
+ mdev->port, mdev->unit);
+ break;
+
+ default:
+ dev_notice(&mdev->dev, ERRSTR " 0x%X\n",
+ mdev->port, mdev->unit, error);
+ }
+}
+
+
+static int __devinit probe_maple_vmu(struct device *dev)
+{
+ int error;
+ struct maple_device *mdev = to_maple_dev(dev);
+ struct maple_driver *mdrv = to_maple_driver(dev->driver);
+
+ mdev->can_unload = vmu_can_unload;
+ mdev->fileerr_handler = vmu_file_error;
+ mdev->driver = mdrv;
+
+ error = vmu_connect(mdev);
+ if (error)
+ return error;
+
+ return 0;
+}
+
+static int __devexit remove_maple_vmu(struct device *dev)
+{
+ struct maple_device *mdev = to_maple_dev(dev);
+
+ vmu_disconnect(mdev);
+ return 0;
+}
+
+static struct maple_driver vmu_flash_driver = {
+ .function = MAPLE_FUNC_MEMCARD,
+ .drv = {
+ .name = "Dreamcast_visual_memory",
+ .probe = probe_maple_vmu,
+ .remove = __devexit_p(remove_maple_vmu),
+ },
+};
+
+static int __init vmu_flash_map_init(void)
+{
+ return maple_driver_register(&vmu_flash_driver);
+}
+
+static void __exit vmu_flash_map_exit(void)
+{
+ maple_driver_unregister(&vmu_flash_driver);
+}
+
+module_init(vmu_flash_map_init);
+module_exit(vmu_flash_map_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Adrian McMenamin");
+MODULE_DESCRIPTION("Flash mapping for Sega Dreamcast visual memory");
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 1409f01406f6..a49a9c8f2cb1 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -286,6 +286,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
gd->private_data = new;
new->blkcore_priv = gd;
gd->queue = tr->blkcore_priv->rq;
+ gd->driverfs_dev = new->mtd->dev.parent;
if (new->readonly)
set_disk_ro(gd, 1);
@@ -382,11 +383,12 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread, tr,
"%sd", tr->name);
if (IS_ERR(tr->blkcore_priv->thread)) {
+ int ret = PTR_ERR(tr->blkcore_priv->thread);
blk_cleanup_queue(tr->blkcore_priv->rq);
unregister_blkdev(tr->major, tr->name);
kfree(tr->blkcore_priv);
mutex_unlock(&mtd_table_mutex);
- return PTR_ERR(tr->blkcore_priv->thread);
+ return ret;
}
INIT_LIST_HEAD(&tr->devs);
diff --git a/drivers/mtd/mtdbdi.c b/drivers/mtd/mtdbdi.c
new file mode 100644
index 000000000000..5ca5aed0b225
--- /dev/null
+++ b/drivers/mtd/mtdbdi.c
@@ -0,0 +1,43 @@
+/* MTD backing device capabilities
+ *
+ * Copyright © 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/backing-dev.h>
+#include <linux/mtd/mtd.h>
+#include "internal.h"
+
+/*
+ * backing device capabilities for non-mappable devices (such as NAND flash)
+ * - permits private mappings, copies are taken of the data
+ */
+struct backing_dev_info mtd_bdi_unmappable = {
+ .capabilities = BDI_CAP_MAP_COPY,
+};
+
+/*
+ * backing device capabilities for R/O mappable devices (such as ROM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_ro_mappable = {
+ .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+ BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
+};
+
+/*
+ * backing device capabilities for writable mappable devices (such as RAM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_rw_mappable = {
+ .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+ BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
+ BDI_CAP_WRITE_MAP),
+};
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index e9ec59e9a566..763d3f0a1f42 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -13,39 +13,13 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
+#include <linux/backing-dev.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/compatmac.h>
#include <asm/uaccess.h>
-static struct class *mtd_class;
-
-static void mtd_notify_add(struct mtd_info* mtd)
-{
- if (!mtd)
- return;
-
- device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
- NULL, "mtd%d", mtd->index);
-
- device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
- NULL, "mtd%dro", mtd->index);
-}
-
-static void mtd_notify_remove(struct mtd_info* mtd)
-{
- if (!mtd)
- return;
-
- device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2));
- device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1));
-}
-
-static struct mtd_notifier notifier = {
- .add = mtd_notify_add,
- .remove = mtd_notify_remove,
-};
/*
* Data structure to hold the pointer to the mtd device as well
@@ -107,12 +81,15 @@ static int mtd_open(struct inode *inode, struct file *file)
goto out;
}
- if (MTD_ABSENT == mtd->type) {
+ if (mtd->type == MTD_ABSENT) {
put_mtd_device(mtd);
ret = -ENODEV;
goto out;
}
+ if (mtd->backing_dev_info)
+ file->f_mapping->backing_dev_info = mtd->backing_dev_info;
+
/* You can't open it RW if it's not a writeable device */
if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) {
put_mtd_device(mtd);
@@ -781,6 +758,59 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
return ret;
} /* memory_ioctl */
+/*
+ * try to determine where a shared mapping can be made
+ * - only supported for NOMMU at the moment (MMU can't doesn't copy private
+ * mappings)
+ */
+#ifndef CONFIG_MMU
+static unsigned long mtd_get_unmapped_area(struct file *file,
+ unsigned long addr,
+ unsigned long len,
+ unsigned long pgoff,
+ unsigned long flags)
+{
+ struct mtd_file_info *mfi = file->private_data;
+ struct mtd_info *mtd = mfi->mtd;
+
+ if (mtd->get_unmapped_area) {
+ unsigned long offset;
+
+ if (addr != 0)
+ return (unsigned long) -EINVAL;
+
+ if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT))
+ return (unsigned long) -EINVAL;
+
+ offset = pgoff << PAGE_SHIFT;
+ if (offset > mtd->size - len)
+ return (unsigned long) -EINVAL;
+
+ return mtd->get_unmapped_area(mtd, len, offset, flags);
+ }
+
+ /* can't map directly */
+ return (unsigned long) -ENOSYS;
+}
+#endif
+
+/*
+ * set up a mapping for shared memory segments
+ */
+static int mtd_mmap(struct file *file, struct vm_area_struct *vma)
+{
+#ifdef CONFIG_MMU
+ struct mtd_file_info *mfi = file->private_data;
+ struct mtd_info *mtd = mfi->mtd;
+
+ if (mtd->type == MTD_RAM || mtd->type == MTD_ROM)
+ return 0;
+ return -ENOSYS;
+#else
+ return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
+#endif
+}
+
static const struct file_operations mtd_fops = {
.owner = THIS_MODULE,
.llseek = mtd_lseek,
@@ -789,39 +819,36 @@ static const struct file_operations mtd_fops = {
.ioctl = mtd_ioctl,
.open = mtd_open,
.release = mtd_close,
+ .mmap = mtd_mmap,
+#ifndef CONFIG_MMU
+ .get_unmapped_area = mtd_get_unmapped_area,
+#endif
};
static int __init init_mtdchar(void)
{
- if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) {
+ int status;
+
+ status = register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops);
+ if (status < 0) {
printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
MTD_CHAR_MAJOR);
- return -EAGAIN;
}
- mtd_class = class_create(THIS_MODULE, "mtd");
-
- if (IS_ERR(mtd_class)) {
- printk(KERN_ERR "Error creating mtd class.\n");
- unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
- return PTR_ERR(mtd_class);
- }
-
- register_mtd_user(&notifier);
- return 0;
+ return status;
}
static void __exit cleanup_mtdchar(void)
{
- unregister_mtd_user(&notifier);
- class_destroy(mtd_class);
unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
}
module_init(init_mtdchar);
module_exit(cleanup_mtdchar);
+MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
MODULE_DESCRIPTION("Direct character-device access to MTD devices");
+MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 3dbb1b38db66..792b547786b8 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -13,6 +13,7 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/types.h>
+#include <linux/backing-dev.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/concat.h>
@@ -684,6 +685,40 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
}
/*
+ * try to support NOMMU mmaps on concatenated devices
+ * - we don't support subdev spanning as we can't guarantee it'll work
+ */
+static unsigned long concat_get_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ struct mtd_concat *concat = CONCAT(mtd);
+ int i;
+
+ for (i = 0; i < concat->num_subdev; i++) {
+ struct mtd_info *subdev = concat->subdev[i];
+
+ if (offset >= subdev->size) {
+ offset -= subdev->size;
+ continue;
+ }
+
+ /* we've found the subdev over which the mapping will reside */
+ if (offset + len > subdev->size)
+ return (unsigned long) -EINVAL;
+
+ if (subdev->get_unmapped_area)
+ return subdev->get_unmapped_area(subdev, len, offset,
+ flags);
+
+ break;
+ }
+
+ return (unsigned long) -ENOSYS;
+}
+
+/*
* This function constructs a virtual MTD device by concatenating
* num_devs MTD devices. A pointer to the new device object is
* stored to *new_dev upon success. This function does _not_
@@ -740,6 +775,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks;
+ concat->mtd.backing_dev_info = subdev[0]->backing_dev_info;
+
concat->subdev[0] = subdev[0];
for (i = 1; i < num_devs; i++) {
@@ -766,6 +803,15 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat->mtd.flags |=
subdev[i]->flags & MTD_WRITEABLE;
}
+
+ /* only permit direct mapping if the BDIs are all the same
+ * - copy-mapping is still permitted
+ */
+ if (concat->mtd.backing_dev_info !=
+ subdev[i]->backing_dev_info)
+ concat->mtd.backing_dev_info =
+ &default_backing_dev_info;
+
concat->mtd.size += subdev[i]->size;
concat->mtd.ecc_stats.badblocks +=
subdev[i]->ecc_stats.badblocks;
@@ -796,6 +842,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat->mtd.unlock = concat_unlock;
concat->mtd.suspend = concat_suspend;
concat->mtd.resume = concat_resume;
+ concat->mtd.get_unmapped_area = concat_get_unmapped_area;
/*
* Combine the erase block size info of the subdevices:
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 76fe0a1e7a5e..fdd6ae859397 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -19,9 +19,13 @@
#include <linux/proc_fs.h>
#include <linux/mtd/mtd.h>
+#include "internal.h"
#include "mtdcore.h"
+
+static struct class *mtd_class;
+
/* These are exported solely for the purpose of mtd_blkdevs.c. You
should not use them for _anything_ else */
DEFINE_MUTEX(mtd_table_mutex);
@@ -32,6 +36,160 @@ EXPORT_SYMBOL_GPL(mtd_table);
static LIST_HEAD(mtd_notifiers);
+
+#if defined(CONFIG_MTD_CHAR) || defined(CONFIG_MTD_CHAR_MODULE)
+#define MTD_DEVT(index) MKDEV(MTD_CHAR_MAJOR, (index)*2)
+#else
+#define MTD_DEVT(index) 0
+#endif
+
+/* REVISIT once MTD uses the driver model better, whoever allocates
+ * the mtd_info will probably want to use the release() hook...
+ */
+static void mtd_release(struct device *dev)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ /* remove /dev/mtdXro node if needed */
+ if (MTD_DEVT(mtd->index))
+ device_destroy(mtd_class, MTD_DEVT(mtd->index) + 1);
+}
+
+static ssize_t mtd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+ char *type;
+
+ switch (mtd->type) {
+ case MTD_ABSENT:
+ type = "absent";
+ break;
+ case MTD_RAM:
+ type = "ram";
+ break;
+ case MTD_ROM:
+ type = "rom";
+ break;
+ case MTD_NORFLASH:
+ type = "nor";
+ break;
+ case MTD_NANDFLASH:
+ type = "nand";
+ break;
+ case MTD_DATAFLASH:
+ type = "dataflash";
+ break;
+ case MTD_UBIVOLUME:
+ type = "ubi";
+ break;
+ default:
+ type = "unknown";
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", type);
+}
+static DEVICE_ATTR(type, S_IRUGO, mtd_type_show, NULL);
+
+static ssize_t mtd_flags_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)mtd->flags);
+
+}
+static DEVICE_ATTR(flags, S_IRUGO, mtd_flags_show, NULL);
+
+static ssize_t mtd_size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%llu\n",
+ (unsigned long long)mtd->size);
+
+}
+static DEVICE_ATTR(size, S_IRUGO, mtd_size_show, NULL);
+
+static ssize_t mtd_erasesize_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->erasesize);
+
+}
+static DEVICE_ATTR(erasesize, S_IRUGO, mtd_erasesize_show, NULL);
+
+static ssize_t mtd_writesize_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->writesize);
+
+}
+static DEVICE_ATTR(writesize, S_IRUGO, mtd_writesize_show, NULL);
+
+static ssize_t mtd_oobsize_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->oobsize);
+
+}
+static DEVICE_ATTR(oobsize, S_IRUGO, mtd_oobsize_show, NULL);
+
+static ssize_t mtd_numeraseregions_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", mtd->numeraseregions);
+
+}
+static DEVICE_ATTR(numeraseregions, S_IRUGO, mtd_numeraseregions_show,
+ NULL);
+
+static ssize_t mtd_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", mtd->name);
+
+}
+static DEVICE_ATTR(name, S_IRUGO, mtd_name_show, NULL);
+
+static struct attribute *mtd_attrs[] = {
+ &dev_attr_type.attr,
+ &dev_attr_flags.attr,
+ &dev_attr_size.attr,
+ &dev_attr_erasesize.attr,
+ &dev_attr_writesize.attr,
+ &dev_attr_oobsize.attr,
+ &dev_attr_numeraseregions.attr,
+ &dev_attr_name.attr,
+ NULL,
+};
+
+struct attribute_group mtd_group = {
+ .attrs = mtd_attrs,
+};
+
+struct attribute_group *mtd_groups[] = {
+ &mtd_group,
+ NULL,
+};
+
+static struct device_type mtd_devtype = {
+ .name = "mtd",
+ .groups = mtd_groups,
+ .release = mtd_release,
+};
+
/**
* add_mtd_device - register an MTD device
* @mtd: pointer to new MTD device info structure
@@ -40,12 +198,27 @@ static LIST_HEAD(mtd_notifiers);
* notify each currently active MTD 'user' of its arrival. Returns
* zero on success or 1 on failure, which currently will only happen
* if the number of present devices exceeds MAX_MTD_DEVICES (i.e. 16)
+ * or there's a sysfs error.
*/
int add_mtd_device(struct mtd_info *mtd)
{
int i;
+ if (!mtd->backing_dev_info) {
+ switch (mtd->type) {
+ case MTD_RAM:
+ mtd->backing_dev_info = &mtd_bdi_rw_mappable;
+ break;
+ case MTD_ROM:
+ mtd->backing_dev_info = &mtd_bdi_ro_mappable;
+ break;
+ default:
+ mtd->backing_dev_info = &mtd_bdi_unmappable;
+ break;
+ }
+ }
+
BUG_ON(mtd->writesize == 0);
mutex_lock(&mtd_table_mutex);
@@ -80,6 +253,23 @@ int add_mtd_device(struct mtd_info *mtd)
mtd->name);
}
+ /* Caller should have set dev.parent to match the
+ * physical device.
+ */
+ mtd->dev.type = &mtd_devtype;
+ mtd->dev.class = mtd_class;
+ mtd->dev.devt = MTD_DEVT(i);
+ dev_set_name(&mtd->dev, "mtd%d", i);
+ if (device_register(&mtd->dev) != 0) {
+ mtd_table[i] = NULL;
+ break;
+ }
+
+ if (MTD_DEVT(i))
+ device_create(mtd_class, mtd->dev.parent,
+ MTD_DEVT(i) + 1,
+ NULL, "mtd%dro", i);
+
DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name);
/* No need to get a refcount on the module containing
the notifier, since we hold the mtd_table_mutex */
@@ -124,6 +314,8 @@ int del_mtd_device (struct mtd_info *mtd)
} else {
struct mtd_notifier *not;
+ device_unregister(&mtd->dev);
+
/* No need to get a refcount on the module containing
the notifier, since we hold the mtd_table_mutex */
list_for_each_entry(not, &mtd_notifiers, list)
@@ -393,28 +585,38 @@ done:
return ((count < begin+len-off) ? count : begin+len-off);
}
+#endif /* CONFIG_PROC_FS */
+
/*====================================================================*/
/* Init code */
static int __init init_mtd(void)
{
+ mtd_class = class_create(THIS_MODULE, "mtd");
+
+ if (IS_ERR(mtd_class)) {
+ pr_err("Error creating mtd class.\n");
+ return PTR_ERR(mtd_class);
+ }
+#ifdef CONFIG_PROC_FS
if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
proc_mtd->read_proc = mtd_read_proc;
+#endif /* CONFIG_PROC_FS */
return 0;
}
static void __exit cleanup_mtd(void)
{
+#ifdef CONFIG_PROC_FS
if (proc_mtd)
remove_proc_entry( "mtd", NULL);
+#endif /* CONFIG_PROC_FS */
+ class_destroy(mtd_class);
}
module_init(init_mtd);
module_exit(cleanup_mtd);
-#endif /* CONFIG_PROC_FS */
-
-
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
MODULE_DESCRIPTION("Core MTD registration and access routines");
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 1a6b3beabe8d..1060337c06df 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -44,6 +44,7 @@ static struct mtdoops_context {
int oops_pages;
int nextpage;
int nextcount;
+ char *name;
void *oops_buf;
@@ -273,6 +274,9 @@ static void mtdoops_notify_add(struct mtd_info *mtd)
{
struct mtdoops_context *cxt = &oops_cxt;
+ if (cxt->name && !strcmp(mtd->name, cxt->name))
+ cxt->mtd_index = mtd->index;
+
if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0)
return;
@@ -357,8 +361,10 @@ mtdoops_console_write(struct console *co, const char *s, unsigned int count)
spin_lock_irqsave(&cxt->writecount_lock, flags);
/* Check ready status didn't change whilst waiting for the lock */
- if (!cxt->ready)
+ if (!cxt->ready) {
+ spin_unlock_irqrestore(&cxt->writecount_lock, flags);
return;
+ }
if (cxt->writecount == 0) {
u32 *stamp = cxt->oops_buf;
@@ -383,8 +389,12 @@ static int __init mtdoops_console_setup(struct console *co, char *options)
{
struct mtdoops_context *cxt = co->data;
- if (cxt->mtd_index != -1)
+ if (cxt->mtd_index != -1 || cxt->name)
return -EBUSY;
+ if (options) {
+ cxt->name = kstrdup(options, GFP_KERNEL);
+ return 0;
+ }
if (co->index == -1)
return -EINVAL;
@@ -412,6 +422,7 @@ static int __init mtdoops_console_init(void)
cxt->mtd_index = -1;
cxt->oops_buf = vmalloc(OOPS_PAGE_SIZE);
+ spin_lock_init(&cxt->writecount_lock);
if (!cxt->oops_buf) {
printk(KERN_ERR "Failed to allocate mtdoops buffer workspace\n");
@@ -432,6 +443,7 @@ static void __exit mtdoops_console_exit(void)
unregister_mtd_user(&mtdoops_notifier);
unregister_console(&mtdoops_console);
+ kfree(cxt->name);
vfree(cxt->oops_buf);
}
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 144e6b613a77..29675edb44b4 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -48,8 +48,11 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
struct mtd_part *part = PART(mtd);
+ struct mtd_ecc_stats stats;
int res;
+ stats = part->master->ecc_stats;
+
if (from >= mtd->size)
len = 0;
else if (from + len > mtd->size)
@@ -58,9 +61,9 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
len, retlen, buf);
if (unlikely(res)) {
if (res == -EUCLEAN)
- mtd->ecc_stats.corrected++;
+ mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected;
if (res == -EBADMSG)
- mtd->ecc_stats.failed++;
+ mtd->ecc_stats.failed += part->master->ecc_stats.failed - stats.failed;
}
return res;
}
@@ -84,6 +87,18 @@ static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
part->master->unpoint(part->master, from + part->offset, len);
}
+static unsigned long part_get_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ struct mtd_part *part = PART(mtd);
+
+ offset += part->offset;
+ return part->master->get_unmapped_area(part->master, len, offset,
+ flags);
+}
+
static int part_read_oob(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops)
{
@@ -342,6 +357,12 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
slave->mtd.name = part->name;
slave->mtd.owner = master->owner;
+ slave->mtd.backing_dev_info = master->backing_dev_info;
+
+ /* NOTE: we don't arrange MTDs as a tree; it'd be error-prone
+ * to have the same data be in two different partitions.
+ */
+ slave->mtd.dev.parent = master->dev.parent;
slave->mtd.read = part_read;
slave->mtd.write = part_write;
@@ -354,6 +375,8 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
slave->mtd.unpoint = part_unpoint;
}
+ if (master->get_unmapped_area)
+ slave->mtd.get_unmapped_area = part_get_unmapped_area;
if (master->read_oob)
slave->mtd.read_oob = part_read_oob;
if (master->write_oob)
@@ -493,7 +516,9 @@ out_register:
* This function, given a master MTD object and a partition table, creates
* and registers slave MTD objects which are bound to the master according to
* the partition definitions.
- * (Q: should we register the master MTD object as well?)
+ *
+ * We don't register the master, or expect the caller to have done so,
+ * for reasons of data integrity.
*/
int add_mtd_partitions(struct mtd_info *master,
diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c
index 00d46e137b2a..92285d0089c2 100644
--- a/drivers/mtd/mtdsuper.c
+++ b/drivers/mtd/mtdsuper.c
@@ -81,13 +81,16 @@ static int get_sb_mtd_aux(struct file_system_type *fs_type, int flags,
/* go */
sb->s_flags |= MS_ACTIVE;
- return simple_set_mnt(mnt, sb);
+ simple_set_mnt(mnt, sb);
+
+ return 0;
/* new mountpoint for an already mounted superblock */
already_mounted:
DEBUG(1, "MTDSB: Device %d (\"%s\") is already mounted\n",
mtd->index, mtd->name);
- ret = simple_set_mnt(mnt, sb);
+ simple_set_mnt(mnt, sb);
+ ret = 0;
goto out_put;
out_error:
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 2ff88791cebc..890936d0275e 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -334,7 +334,7 @@ config MTD_NAND_ATMEL_ECC_NONE
endchoice
config MTD_NAND_PXA3xx
- bool "Support for NAND flash devices on PXA3xx"
+ tristate "Support for NAND flash devices on PXA3xx"
depends on MTD_NAND && PXA3xx
help
This enables the driver for the NAND flash device found on
@@ -427,4 +427,23 @@ config MTD_NAND_SH_FLCTL
Several Renesas SuperH CPU has FLCTL. This option enables support
for NAND Flash using FLCTL. This driver support SH7723.
+config MTD_NAND_DAVINCI
+ tristate "Support NAND on DaVinci SoC"
+ depends on ARCH_DAVINCI
+ help
+ Enable the driver for NAND flash chips on Texas Instruments
+ DaVinci processors.
+
+config MTD_NAND_TXX9NDFMC
+ tristate "NAND Flash support for TXx9 SoC"
+ depends on SOC_TX4938 || SOC_TX4939
+ help
+ This enables the NAND flash controller on the TXx9 SoCs.
+
+config MTD_NAND_SOCRATES
+ tristate "Support for NAND on Socrates board"
+ depends on MTD_NAND && SOCRATES
+ help
+ Enables support for NAND Flash chips wired onto Socrates board.
+
endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index b661586afbfc..d33860ac42c3 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o
obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o
obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o
+obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o
obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o
obj-$(CONFIG_MTD_NAND_H1900) += h1910.o
obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o
@@ -36,5 +37,7 @@ obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o
obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o
obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o
obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o
+obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o
+obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o
nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c
index 9af2a2cc1153..4c2a67ca801e 100644
--- a/drivers/mtd/nand/bf5xx_nand.c
+++ b/drivers/mtd/nand/bf5xx_nand.c
@@ -552,7 +552,6 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd,
static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
{
int ret;
- unsigned short val;
/* Do not use dma */
if (!hardware_ecc)
@@ -560,13 +559,6 @@ static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
init_completion(&info->dma_completion);
-#ifdef CONFIG_BF54x
- /* Setup DMAC1 channel mux for NFC which shared with SDH */
- val = bfin_read_DMAC1_PERIMUX();
- val &= 0xFFFE;
- bfin_write_DMAC1_PERIMUX(val);
- SSYNC();
-#endif
/* Request NFC DMA channel */
ret = request_dma(CH_NFC, "BF5XX NFC driver");
if (ret < 0) {
@@ -574,7 +566,13 @@ static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
return ret;
}
- set_dma_callback(CH_NFC, (void *) bf5xx_nand_dma_irq, (void *) info);
+#ifdef CONFIG_BF54x
+ /* Setup DMAC1 channel mux for NFC which shared with SDH */
+ bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() & ~1);
+ SSYNC();
+#endif
+
+ set_dma_callback(CH_NFC, bf5xx_nand_dma_irq, info);
/* Turn off the DMA channel first */
disable_dma(CH_NFC);
@@ -632,7 +630,7 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info)
/*
* Device management interface
*/
-static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
+static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
{
struct mtd_info *mtd = &info->mtd;
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index 22a6b2e50e91..7c5b257ce8e4 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -654,6 +654,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
}
cafe = (void *)(&mtd[1]);
+ mtd->dev.parent = &pdev->dev;
mtd->priv = cafe;
mtd->owner = THIS_MODULE;
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c
index fa129c09bca8..10081e656a6f 100644
--- a/drivers/mtd/nand/cmx270_nand.c
+++ b/drivers/mtd/nand/cmx270_nand.c
@@ -26,8 +26,7 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa2xx-regs.h>
#define GPIO_NAND_CS (11)
#define GPIO_NAND_RB (89)
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
new file mode 100644
index 000000000000..0119220de7d0
--- /dev/null
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -0,0 +1,570 @@
+/*
+ * davinci_nand.c - NAND Flash Driver for DaVinci family chips
+ *
+ * Copyright © 2006 Texas Instruments.
+ *
+ * Port to 2.6.23 Copyright © 2008 by:
+ * Sander Huijsen <Shuijsen@optelecom-nkf.com>
+ * Troy Kisky <troy.kisky@boundarydevices.com>
+ * Dirk Behme <Dirk.Behme@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <mach/nand.h>
+
+#include <asm/mach-types.h>
+
+
+/*
+ * This is a device driver for the NAND flash controller found on the
+ * various DaVinci family chips. It handles up to four SoC chipselects,
+ * and some flavors of secondary chipselect (e.g. based on A12) as used
+ * with multichip packages.
+ *
+ * The 1-bit ECC hardware is supported, but not yet the newer 4-bit ECC
+ * available on chips like the DM355 and OMAP-L137 and needed with the
+ * more error-prone MLC NAND chips.
+ *
+ * This driver assumes EM_WAIT connects all the NAND devices' RDY/nBUSY
+ * outputs in a "wire-AND" configuration, with no per-chip signals.
+ */
+struct davinci_nand_info {
+ struct mtd_info mtd;
+ struct nand_chip chip;
+
+ struct device *dev;
+ struct clk *clk;
+ bool partitioned;
+
+ void __iomem *base;
+ void __iomem *vaddr;
+
+ uint32_t ioaddr;
+ uint32_t current_cs;
+
+ uint32_t mask_chipsel;
+ uint32_t mask_ale;
+ uint32_t mask_cle;
+
+ uint32_t core_chipsel;
+};
+
+static DEFINE_SPINLOCK(davinci_nand_lock);
+
+#define to_davinci_nand(m) container_of(m, struct davinci_nand_info, mtd)
+
+
+static inline unsigned int davinci_nand_readl(struct davinci_nand_info *info,
+ int offset)
+{
+ return __raw_readl(info->base + offset);
+}
+
+static inline void davinci_nand_writel(struct davinci_nand_info *info,
+ int offset, unsigned long value)
+{
+ __raw_writel(value, info->base + offset);
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Access to hardware control lines: ALE, CLE, secondary chipselect.
+ */
+
+static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct davinci_nand_info *info = to_davinci_nand(mtd);
+ uint32_t addr = info->current_cs;
+ struct nand_chip *nand = mtd->priv;
+
+ /* Did the control lines change? */
+ if (ctrl & NAND_CTRL_CHANGE) {
+ if ((ctrl & NAND_CTRL_CLE) == NAND_CTRL_CLE)
+ addr |= info->mask_cle;
+ else if ((ctrl & NAND_CTRL_ALE) == NAND_CTRL_ALE)
+ addr |= info->mask_ale;
+
+ nand->IO_ADDR_W = (void __iomem __force *)addr;
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ iowrite8(cmd, nand->IO_ADDR_W);
+}
+
+static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
+{
+ struct davinci_nand_info *info = to_davinci_nand(mtd);
+ uint32_t addr = info->ioaddr;
+
+ /* maybe kick in a second chipselect */
+ if (chip > 0)
+ addr |= info->mask_chipsel;
+ info->current_cs = addr;
+
+ info->chip.IO_ADDR_W = (void __iomem __force *)addr;
+ info->chip.IO_ADDR_R = info->chip.IO_ADDR_W;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * 1-bit hardware ECC ... context maintained for each core chipselect
+ */
+
+static inline uint32_t nand_davinci_readecc_1bit(struct mtd_info *mtd)
+{
+ struct davinci_nand_info *info = to_davinci_nand(mtd);
+
+ return davinci_nand_readl(info, NANDF1ECC_OFFSET
+ + 4 * info->core_chipsel);
+}
+
+static void nand_davinci_hwctl_1bit(struct mtd_info *mtd, int mode)
+{
+ struct davinci_nand_info *info;
+ uint32_t nandcfr;
+ unsigned long flags;
+
+ info = to_davinci_nand(mtd);
+
+ /* Reset ECC hardware */
+ nand_davinci_readecc_1bit(mtd);
+
+ spin_lock_irqsave(&davinci_nand_lock, flags);
+
+ /* Restart ECC hardware */
+ nandcfr = davinci_nand_readl(info, NANDFCR_OFFSET);
+ nandcfr |= BIT(8 + info->core_chipsel);
+ davinci_nand_writel(info, NANDFCR_OFFSET, nandcfr);
+
+ spin_unlock_irqrestore(&davinci_nand_lock, flags);
+}
+
+/*
+ * Read hardware ECC value and pack into three bytes
+ */
+static int nand_davinci_calculate_1bit(struct mtd_info *mtd,
+ const u_char *dat, u_char *ecc_code)
+{
+ unsigned int ecc_val = nand_davinci_readecc_1bit(mtd);
+ unsigned int ecc24 = (ecc_val & 0x0fff) | ((ecc_val & 0x0fff0000) >> 4);
+
+ /* invert so that erased block ecc is correct */
+ ecc24 = ~ecc24;
+ ecc_code[0] = (u_char)(ecc24);
+ ecc_code[1] = (u_char)(ecc24 >> 8);
+ ecc_code[2] = (u_char)(ecc24 >> 16);
+
+ return 0;
+}
+
+static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat,
+ u_char *read_ecc, u_char *calc_ecc)
+{
+ struct nand_chip *chip = mtd->priv;
+ uint32_t eccNand = read_ecc[0] | (read_ecc[1] << 8) |
+ (read_ecc[2] << 16);
+ uint32_t eccCalc = calc_ecc[0] | (calc_ecc[1] << 8) |
+ (calc_ecc[2] << 16);
+ uint32_t diff = eccCalc ^ eccNand;
+
+ if (diff) {
+ if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
+ /* Correctable error */
+ if ((diff >> (12 + 3)) < chip->ecc.size) {
+ dat[diff >> (12 + 3)] ^= BIT((diff >> 12) & 7);
+ return 1;
+ } else {
+ return -1;
+ }
+ } else if (!(diff & (diff - 1))) {
+ /* Single bit ECC error in the ECC itself,
+ * nothing to fix */
+ return 1;
+ } else {
+ /* Uncorrectable error */
+ return -1;
+ }
+
+ }
+ return 0;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * NOTE: NAND boot requires ALE == EM_A[1], CLE == EM_A[2], so that's
+ * how these chips are normally wired. This translates to both 8 and 16
+ * bit busses using ALE == BIT(3) in byte addresses, and CLE == BIT(4).
+ *
+ * For now we assume that configuration, or any other one which ignores
+ * the two LSBs for NAND access ... so we can issue 32-bit reads/writes
+ * and have that transparently morphed into multiple NAND operations.
+ */
+static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
+ ioread32_rep(chip->IO_ADDR_R, buf, len >> 2);
+ else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
+ ioread16_rep(chip->IO_ADDR_R, buf, len >> 1);
+ else
+ ioread8_rep(chip->IO_ADDR_R, buf, len);
+}
+
+static void nand_davinci_write_buf(struct mtd_info *mtd,
+ const uint8_t *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
+ iowrite32_rep(chip->IO_ADDR_R, buf, len >> 2);
+ else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
+ iowrite16_rep(chip->IO_ADDR_R, buf, len >> 1);
+ else
+ iowrite8_rep(chip->IO_ADDR_R, buf, len);
+}
+
+/*
+ * Check hardware register for wait status. Returns 1 if device is ready,
+ * 0 if it is still busy.
+ */
+static int nand_davinci_dev_ready(struct mtd_info *mtd)
+{
+ struct davinci_nand_info *info = to_davinci_nand(mtd);
+
+ return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0);
+}
+
+static void __init nand_dm6446evm_flash_init(struct davinci_nand_info *info)
+{
+ uint32_t regval, a1cr;
+
+ /*
+ * NAND FLASH timings @ PLL1 == 459 MHz
+ * - AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz
+ * - AEMIF.CLK period = 1/76.5 MHz = 13.1 ns
+ */
+ regval = 0
+ | (0 << 31) /* selectStrobe */
+ | (0 << 30) /* extWait (never with NAND) */
+ | (1 << 26) /* writeSetup 10 ns */
+ | (3 << 20) /* writeStrobe 40 ns */
+ | (1 << 17) /* writeHold 10 ns */
+ | (0 << 13) /* readSetup 10 ns */
+ | (3 << 7) /* readStrobe 60 ns */
+ | (0 << 4) /* readHold 10 ns */
+ | (3 << 2) /* turnAround ?? ns */
+ | (0 << 0) /* asyncSize 8-bit bus */
+ ;
+ a1cr = davinci_nand_readl(info, A1CR_OFFSET);
+ if (a1cr != regval) {
+ dev_dbg(info->dev, "Warning: NAND config: Set A1CR " \
+ "reg to 0x%08x, was 0x%08x, should be done by " \
+ "bootloader.\n", regval, a1cr);
+ davinci_nand_writel(info, A1CR_OFFSET, regval);
+ }
+}
+
+/*----------------------------------------------------------------------*/
+
+static int __init nand_davinci_probe(struct platform_device *pdev)
+{
+ struct davinci_nand_pdata *pdata = pdev->dev.platform_data;
+ struct davinci_nand_info *info;
+ struct resource *res1;
+ struct resource *res2;
+ void __iomem *vaddr;
+ void __iomem *base;
+ int ret;
+ uint32_t val;
+ nand_ecc_modes_t ecc_mode;
+
+ /* which external chipselect will we be managing? */
+ if (pdev->id < 0 || pdev->id > 3)
+ return -ENODEV;
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info) {
+ dev_err(&pdev->dev, "unable to allocate memory\n");
+ ret = -ENOMEM;
+ goto err_nomem;
+ }
+
+ platform_set_drvdata(pdev, info);
+
+ res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res1 || !res2) {
+ dev_err(&pdev->dev, "resource missing\n");
+ ret = -EINVAL;
+ goto err_nomem;
+ }
+
+ vaddr = ioremap(res1->start, res1->end - res1->start);
+ base = ioremap(res2->start, res2->end - res2->start);
+ if (!vaddr || !base) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -EINVAL;
+ goto err_ioremap;
+ }
+
+ info->dev = &pdev->dev;
+ info->base = base;
+ info->vaddr = vaddr;
+
+ info->mtd.priv = &info->chip;
+ info->mtd.name = dev_name(&pdev->dev);
+ info->mtd.owner = THIS_MODULE;
+
+ info->mtd.dev.parent = &pdev->dev;
+
+ info->chip.IO_ADDR_R = vaddr;
+ info->chip.IO_ADDR_W = vaddr;
+ info->chip.chip_delay = 0;
+ info->chip.select_chip = nand_davinci_select_chip;
+
+ /* options such as NAND_USE_FLASH_BBT or 16-bit widths */
+ info->chip.options = pdata ? pdata->options : 0;
+
+ info->ioaddr = (uint32_t __force) vaddr;
+
+ info->current_cs = info->ioaddr;
+ info->core_chipsel = pdev->id;
+ info->mask_chipsel = pdata->mask_chipsel;
+
+ /* use nandboot-capable ALE/CLE masks by default */
+ if (pdata && pdata->mask_ale)
+ info->mask_ale = pdata->mask_cle;
+ else
+ info->mask_ale = MASK_ALE;
+ if (pdata && pdata->mask_cle)
+ info->mask_cle = pdata->mask_cle;
+ else
+ info->mask_cle = MASK_CLE;
+
+ /* Set address of hardware control function */
+ info->chip.cmd_ctrl = nand_davinci_hwcontrol;
+ info->chip.dev_ready = nand_davinci_dev_ready;
+
+ /* Speed up buffer I/O */
+ info->chip.read_buf = nand_davinci_read_buf;
+ info->chip.write_buf = nand_davinci_write_buf;
+
+ /* use board-specific ECC config; else, the best available */
+ if (pdata)
+ ecc_mode = pdata->ecc_mode;
+ else
+ ecc_mode = NAND_ECC_HW;
+
+ switch (ecc_mode) {
+ case NAND_ECC_NONE:
+ case NAND_ECC_SOFT:
+ break;
+ case NAND_ECC_HW:
+ info->chip.ecc.calculate = nand_davinci_calculate_1bit;
+ info->chip.ecc.correct = nand_davinci_correct_1bit;
+ info->chip.ecc.hwctl = nand_davinci_hwctl_1bit;
+ info->chip.ecc.size = 512;
+ info->chip.ecc.bytes = 3;
+ break;
+ case NAND_ECC_HW_SYNDROME:
+ /* FIXME implement */
+ info->chip.ecc.size = 512;
+ info->chip.ecc.bytes = 10;
+
+ dev_warn(&pdev->dev, "4-bit ECC nyet supported\n");
+ /* FALL THROUGH */
+ default:
+ ret = -EINVAL;
+ goto err_ecc;
+ }
+ info->chip.ecc.mode = ecc_mode;
+
+ info->clk = clk_get(&pdev->dev, "AEMIFCLK");
+ if (IS_ERR(info->clk)) {
+ ret = PTR_ERR(info->clk);
+ dev_dbg(&pdev->dev, "unable to get AEMIFCLK, err %d\n", ret);
+ goto err_clk;
+ }
+
+ ret = clk_enable(info->clk);
+ if (ret < 0) {
+ dev_dbg(&pdev->dev, "unable to enable AEMIFCLK, err %d\n", ret);
+ goto err_clk_enable;
+ }
+
+ /* EMIF timings should normally be set by the boot loader,
+ * especially after boot-from-NAND. The *only* reason to
+ * have this special casing for the DM6446 EVM is to work
+ * with boot-from-NOR ... with CS0 manually re-jumpered
+ * (after startup) so it addresses the NAND flash, not NOR.
+ * Even for dev boards, that's unusually rude...
+ */
+ if (machine_is_davinci_evm())
+ nand_dm6446evm_flash_init(info);
+
+ spin_lock_irq(&davinci_nand_lock);
+
+ /* put CSxNAND into NAND mode */
+ val = davinci_nand_readl(info, NANDFCR_OFFSET);
+ val |= BIT(info->core_chipsel);
+ davinci_nand_writel(info, NANDFCR_OFFSET, val);
+
+ spin_unlock_irq(&davinci_nand_lock);
+
+ /* Scan to find existence of the device(s) */
+ ret = nand_scan(&info->mtd, pdata->mask_chipsel ? 2 : 1);
+ if (ret < 0) {
+ dev_dbg(&pdev->dev, "no NAND chip(s) found\n");
+ goto err_scan;
+ }
+
+ if (mtd_has_partitions()) {
+ struct mtd_partition *mtd_parts = NULL;
+ int mtd_parts_nb = 0;
+
+ if (mtd_has_cmdlinepart()) {
+ static const char *probes[] __initconst =
+ { "cmdlinepart", NULL };
+
+ const char *master_name;
+
+ /* Set info->mtd.name = 0 temporarily */
+ master_name = info->mtd.name;
+ info->mtd.name = (char *)0;
+
+ /* info->mtd.name == 0, means: don't bother checking
+ <mtd-id> */
+ mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes,
+ &mtd_parts, 0);
+
+ /* Restore info->mtd.name */
+ info->mtd.name = master_name;
+ }
+
+ if (mtd_parts_nb <= 0 && pdata) {
+ mtd_parts = pdata->parts;
+ mtd_parts_nb = pdata->nr_parts;
+ }
+
+ /* Register any partitions */
+ if (mtd_parts_nb > 0) {
+ ret = add_mtd_partitions(&info->mtd,
+ mtd_parts, mtd_parts_nb);
+ if (ret == 0)
+ info->partitioned = true;
+ }
+
+ } else if (pdata && pdata->nr_parts) {
+ dev_warn(&pdev->dev, "ignoring %d default partitions on %s\n",
+ pdata->nr_parts, info->mtd.name);
+ }
+
+ /* If there's no partition info, just package the whole chip
+ * as a single MTD device.
+ */
+ if (!info->partitioned)
+ ret = add_mtd_device(&info->mtd) ? -ENODEV : 0;
+
+ if (ret < 0)
+ goto err_scan;
+
+ val = davinci_nand_readl(info, NRCSR_OFFSET);
+ dev_info(&pdev->dev, "controller rev. %d.%d\n",
+ (val >> 8) & 0xff, val & 0xff);
+
+ return 0;
+
+err_scan:
+ clk_disable(info->clk);
+
+err_clk_enable:
+ clk_put(info->clk);
+
+err_ecc:
+err_clk:
+err_ioremap:
+ if (base)
+ iounmap(base);
+ if (vaddr)
+ iounmap(vaddr);
+
+err_nomem:
+ kfree(info);
+ return ret;
+}
+
+static int __exit nand_davinci_remove(struct platform_device *pdev)
+{
+ struct davinci_nand_info *info = platform_get_drvdata(pdev);
+ int status;
+
+ if (mtd_has_partitions() && info->partitioned)
+ status = del_mtd_partitions(&info->mtd);
+ else
+ status = del_mtd_device(&info->mtd);
+
+ iounmap(info->base);
+ iounmap(info->vaddr);
+
+ nand_release(&info->mtd);
+
+ clk_disable(info->clk);
+ clk_put(info->clk);
+
+ kfree(info);
+
+ return 0;
+}
+
+static struct platform_driver nand_davinci_driver = {
+ .remove = __exit_p(nand_davinci_remove),
+ .driver = {
+ .name = "davinci_nand",
+ },
+};
+MODULE_ALIAS("platform:davinci_nand");
+
+static int __init nand_davinci_init(void)
+{
+ return platform_driver_probe(&nand_davinci_driver, nand_davinci_probe);
+}
+module_init(nand_davinci_init);
+
+static void __exit nand_davinci_exit(void)
+{
+ platform_driver_unregister(&nand_davinci_driver);
+}
+module_exit(nand_davinci_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("Davinci NAND flash driver");
+
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index e4226e02d63e..e51c1ed7ac18 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -1773,4 +1773,4 @@ module_exit(cleanup_nanddoc);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver\n");
+MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver");
diff --git a/drivers/mtd/nand/excite_nandflash.c b/drivers/mtd/nand/excite_nandflash.c
index ced14b5294d5..72446fb48d4b 100644
--- a/drivers/mtd/nand/excite_nandflash.c
+++ b/drivers/mtd/nand/excite_nandflash.c
@@ -128,11 +128,11 @@ static int excite_nand_devready(struct mtd_info *mtd)
* The binding to the mtd and all allocated
* resources are released.
*/
-static int __exit excite_nand_remove(struct device *dev)
+static int __exit excite_nand_remove(struct platform_device *dev)
{
- struct excite_nand_drvdata * const this = dev_get_drvdata(dev);
+ struct excite_nand_drvdata * const this = platform_get_drvdata(dev);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
if (unlikely(!this)) {
printk(KERN_ERR "%s: called %s without private data!!",
@@ -159,9 +159,8 @@ static int __exit excite_nand_remove(struct device *dev)
* it can allocate all necessary resources then calls the
* nand layer to look for devices.
*/
-static int __init excite_nand_probe(struct device *dev)
+static int __init excite_nand_probe(struct platform_device *pdev)
{
- struct platform_device * const pdev = to_platform_device(dev);
struct excite_nand_drvdata *drvdata; /* private driver data */
struct nand_chip *board_chip; /* private flash chip data */
struct mtd_info *board_mtd; /* mtd info for this board */
@@ -175,7 +174,7 @@ static int __init excite_nand_probe(struct device *dev)
}
/* bind private data into driver */
- dev_set_drvdata(dev, drvdata);
+ platform_set_drvdata(pdev, drvdata);
/* allocate and map the resource */
drvdata->regs =
@@ -219,23 +218,25 @@ static int __init excite_nand_probe(struct device *dev)
return 0;
}
-static struct device_driver excite_nand_driver = {
- .name = "excite_nand",
- .bus = &platform_bus_type,
+static struct platform_driver excite_nand_driver = {
+ .driver = {
+ .name = "excite_nand",
+ .owner = THIS_MODULE,
+ },
.probe = excite_nand_probe,
- .remove = __exit_p(excite_nand_remove)
+ .remove = __devexit_p(excite_nand_remove)
};
static int __init excite_nand_init(void)
{
pr_info("Basler eXcite nand flash driver Version "
EXCITE_NANDFLASH_VERSION "\n");
- return driver_register(&excite_nand_driver);
+ return platform_driver_register(&excite_nand_driver);
}
static void __exit excite_nand_exit(void)
{
- driver_unregister(&excite_nand_driver);
+ platform_driver_unregister(&excite_nand_driver);
}
module_init(excite_nand_init);
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index 7815a404a632..d120cd8d7267 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -23,6 +23,10 @@
#include <linux/io.h>
#include <asm/fsl_lbc.h>
+#define FSL_UPM_WAIT_RUN_PATTERN 0x1
+#define FSL_UPM_WAIT_WRITE_BYTE 0x2
+#define FSL_UPM_WAIT_WRITE_BUFFER 0x4
+
struct fsl_upm_nand {
struct device *dev;
struct mtd_info mtd;
@@ -36,8 +40,12 @@ struct fsl_upm_nand {
uint8_t upm_addr_offset;
uint8_t upm_cmd_offset;
void __iomem *io_base;
- int rnb_gpio;
+ int rnb_gpio[NAND_MAX_CHIPS];
+ uint32_t mchip_offsets[NAND_MAX_CHIPS];
+ uint32_t mchip_count;
+ uint32_t mchip_number;
int chip_delay;
+ uint32_t wait_flags;
};
#define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd)
@@ -46,7 +54,7 @@ static int fun_chip_ready(struct mtd_info *mtd)
{
struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
- if (gpio_get_value(fun->rnb_gpio))
+ if (gpio_get_value(fun->rnb_gpio[fun->mchip_number]))
return 1;
dev_vdbg(fun->dev, "busy\n");
@@ -55,9 +63,9 @@ static int fun_chip_ready(struct mtd_info *mtd)
static void fun_wait_rnb(struct fsl_upm_nand *fun)
{
- int cnt = 1000000;
+ if (fun->rnb_gpio[fun->mchip_number] >= 0) {
+ int cnt = 1000000;
- if (fun->rnb_gpio >= 0) {
while (--cnt && !fun_chip_ready(&fun->mtd))
cpu_relax();
if (!cnt)
@@ -69,7 +77,9 @@ static void fun_wait_rnb(struct fsl_upm_nand *fun)
static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
+ struct nand_chip *chip = mtd->priv;
struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
+ u32 mar;
if (!(ctrl & fun->last_ctrl)) {
fsl_upm_end_pattern(&fun->upm);
@@ -87,9 +97,28 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset);
}
- fsl_upm_run_pattern(&fun->upm, fun->io_base, cmd);
+ mar = (cmd << (32 - fun->upm.width)) |
+ fun->mchip_offsets[fun->mchip_number];
+ fsl_upm_run_pattern(&fun->upm, chip->IO_ADDR_R, mar);
+
+ if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN)
+ fun_wait_rnb(fun);
+}
+
+static void fun_select_chip(struct mtd_info *mtd, int mchip_nr)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
- fun_wait_rnb(fun);
+ if (mchip_nr == -1) {
+ chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
+ } else if (mchip_nr >= 0) {
+ fun->mchip_number = mchip_nr;
+ chip->IO_ADDR_R = fun->io_base + fun->mchip_offsets[mchip_nr];
+ chip->IO_ADDR_W = chip->IO_ADDR_R;
+ } else {
+ BUG();
+ }
}
static uint8_t fun_read_byte(struct mtd_info *mtd)
@@ -115,8 +144,11 @@ static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
for (i = 0; i < len; i++) {
out_8(fun->chip.IO_ADDR_W, buf[i]);
- fun_wait_rnb(fun);
+ if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BYTE)
+ fun_wait_rnb(fun);
}
+ if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BUFFER)
+ fun_wait_rnb(fun);
}
static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
@@ -137,8 +169,10 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
fun->chip.read_buf = fun_read_buf;
fun->chip.write_buf = fun_write_buf;
fun->chip.ecc.mode = NAND_ECC_SOFT;
+ if (fun->mchip_count > 1)
+ fun->chip.select_chip = fun_select_chip;
- if (fun->rnb_gpio >= 0)
+ if (fun->rnb_gpio[0] >= 0)
fun->chip.dev_ready = fun_chip_ready;
fun->mtd.priv = &fun->chip;
@@ -155,7 +189,7 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
goto err;
}
- ret = nand_scan(&fun->mtd, 1);
+ ret = nand_scan(&fun->mtd, fun->mchip_count);
if (ret)
goto err;
@@ -185,8 +219,10 @@ static int __devinit fun_probe(struct of_device *ofdev,
struct fsl_upm_nand *fun;
struct resource io_res;
const uint32_t *prop;
+ int rnb_gpio;
int ret;
int size;
+ int i;
fun = kzalloc(sizeof(*fun), GFP_KERNEL);
if (!fun)
@@ -208,7 +244,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
if (!prop || size != sizeof(uint32_t)) {
dev_err(&ofdev->dev, "can't get UPM address offset\n");
ret = -EINVAL;
- goto err2;
+ goto err1;
}
fun->upm_addr_offset = *prop;
@@ -216,21 +252,40 @@ static int __devinit fun_probe(struct of_device *ofdev,
if (!prop || size != sizeof(uint32_t)) {
dev_err(&ofdev->dev, "can't get UPM command offset\n");
ret = -EINVAL;
- goto err2;
+ goto err1;
}
fun->upm_cmd_offset = *prop;
- fun->rnb_gpio = of_get_gpio(ofdev->node, 0);
- if (fun->rnb_gpio >= 0) {
- ret = gpio_request(fun->rnb_gpio, dev_name(&ofdev->dev));
- if (ret) {
- dev_err(&ofdev->dev, "can't request RNB gpio\n");
+ prop = of_get_property(ofdev->node,
+ "fsl,upm-addr-line-cs-offsets", &size);
+ if (prop && (size / sizeof(uint32_t)) > 0) {
+ fun->mchip_count = size / sizeof(uint32_t);
+ if (fun->mchip_count >= NAND_MAX_CHIPS) {
+ dev_err(&ofdev->dev, "too much multiple chips\n");
+ goto err1;
+ }
+ for (i = 0; i < fun->mchip_count; i++)
+ fun->mchip_offsets[i] = prop[i];
+ } else {
+ fun->mchip_count = 1;
+ }
+
+ for (i = 0; i < fun->mchip_count; i++) {
+ fun->rnb_gpio[i] = -1;
+ rnb_gpio = of_get_gpio(ofdev->node, i);
+ if (rnb_gpio >= 0) {
+ ret = gpio_request(rnb_gpio, dev_name(&ofdev->dev));
+ if (ret) {
+ dev_err(&ofdev->dev,
+ "can't request RNB gpio #%d\n", i);
+ goto err2;
+ }
+ gpio_direction_input(rnb_gpio);
+ fun->rnb_gpio[i] = rnb_gpio;
+ } else if (rnb_gpio == -EINVAL) {
+ dev_err(&ofdev->dev, "RNB gpio #%d is invalid\n", i);
goto err2;
}
- gpio_direction_input(fun->rnb_gpio);
- } else if (fun->rnb_gpio == -EINVAL) {
- dev_err(&ofdev->dev, "specified RNB gpio is invalid\n");
- goto err2;
}
prop = of_get_property(ofdev->node, "chip-delay", NULL);
@@ -239,8 +294,15 @@ static int __devinit fun_probe(struct of_device *ofdev,
else
fun->chip_delay = 50;
+ prop = of_get_property(ofdev->node, "fsl,upm-wait-flags", &size);
+ if (prop && size == sizeof(uint32_t))
+ fun->wait_flags = *prop;
+ else
+ fun->wait_flags = FSL_UPM_WAIT_RUN_PATTERN |
+ FSL_UPM_WAIT_WRITE_BYTE;
+
fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start,
- io_res.end - io_res.start + 1);
+ io_res.end - io_res.start + 1);
if (!fun->io_base) {
ret = -ENOMEM;
goto err2;
@@ -257,8 +319,11 @@ static int __devinit fun_probe(struct of_device *ofdev,
return 0;
err2:
- if (fun->rnb_gpio >= 0)
- gpio_free(fun->rnb_gpio);
+ for (i = 0; i < fun->mchip_count; i++) {
+ if (fun->rnb_gpio[i] < 0)
+ break;
+ gpio_free(fun->rnb_gpio[i]);
+ }
err1:
kfree(fun);
@@ -268,12 +333,16 @@ err1:
static int __devexit fun_remove(struct of_device *ofdev)
{
struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev);
+ int i;
nand_release(&fun->mtd);
kfree(fun->mtd.name);
- if (fun->rnb_gpio >= 0)
- gpio_free(fun->rnb_gpio);
+ for (i = 0; i < fun->mchip_count; i++) {
+ if (fun->rnb_gpio[i] < 0)
+ break;
+ gpio_free(fun->rnb_gpio[i]);
+ }
kfree(fun);
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 21fd4f1c4806..f3548d048014 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -866,6 +866,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
mtd = &host->mtd;
mtd->priv = this;
mtd->owner = THIS_MODULE;
+ mtd->dev.parent = &pdev->dev;
/* 50 us command delay time */
this->chip_delay = 5;
@@ -880,7 +881,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
this->read_buf = mxc_nand_read_buf;
this->verify_buf = mxc_nand_verify_buf;
- host->clk = clk_get(&pdev->dev, "nfc_clk");
+ host->clk = clk_get(&pdev->dev, "nfc");
if (IS_ERR(host->clk))
goto eclk;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 0c3afccde8a2..3d7ed432fa41 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -82,6 +82,20 @@ static struct nand_ecclayout nand_oob_64 = {
.length = 38}}
};
+static struct nand_ecclayout nand_oob_128 = {
+ .eccbytes = 48,
+ .eccpos = {
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127},
+ .oobfree = {
+ {.offset = 2,
+ .length = 78}}
+};
+
static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
int new_state);
@@ -748,6 +762,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ *
+ * Not for syndrome calculating ecc controllers, which use a special oob layout
*/
static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *buf)
@@ -758,6 +774,47 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
}
/**
+ * nand_read_page_raw_syndrome - [Intern] read raw page data without ecc
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ *
+ * We need a special oob layout and handling even when OOB isn't used.
+ */
+static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+ uint8_t *buf)
+{
+ int eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ uint8_t *oob = chip->oob_poi;
+ int steps, size;
+
+ for (steps = chip->ecc.steps; steps > 0; steps--) {
+ chip->read_buf(mtd, buf, eccsize);
+ buf += eccsize;
+
+ if (chip->ecc.prepad) {
+ chip->read_buf(mtd, oob, chip->ecc.prepad);
+ oob += chip->ecc.prepad;
+ }
+
+ chip->read_buf(mtd, oob, eccbytes);
+ oob += eccbytes;
+
+ if (chip->ecc.postpad) {
+ chip->read_buf(mtd, oob, chip->ecc.postpad);
+ oob += chip->ecc.postpad;
+ }
+ }
+
+ size = mtd->oobsize - (oob - chip->oob_poi);
+ if (size)
+ chip->read_buf(mtd, oob, size);
+
+ return 0;
+}
+
+/**
* nand_read_page_swecc - [REPLACABLE] software ecc based page read function
* @mtd: mtd info structure
* @chip: nand chip info structure
@@ -1482,6 +1539,8 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: data buffer
+ *
+ * Not for syndrome calculating ecc controllers, which use a special oob layout
*/
static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf)
@@ -1491,6 +1550,44 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
}
/**
+ * nand_write_page_raw_syndrome - [Intern] raw page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
+ *
+ * We need a special oob layout and handling even when ECC isn't checked.
+ */
+static void nand_write_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+ const uint8_t *buf)
+{
+ int eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ uint8_t *oob = chip->oob_poi;
+ int steps, size;
+
+ for (steps = chip->ecc.steps; steps > 0; steps--) {
+ chip->write_buf(mtd, buf, eccsize);
+ buf += eccsize;
+
+ if (chip->ecc.prepad) {
+ chip->write_buf(mtd, oob, chip->ecc.prepad);
+ oob += chip->ecc.prepad;
+ }
+
+ chip->read_buf(mtd, oob, eccbytes);
+ oob += eccbytes;
+
+ if (chip->ecc.postpad) {
+ chip->write_buf(mtd, oob, chip->ecc.postpad);
+ oob += chip->ecc.postpad;
+ }
+ }
+
+ size = mtd->oobsize - (oob - chip->oob_poi);
+ if (size)
+ chip->write_buf(mtd, oob, size);
+}
+/**
* nand_write_page_swecc - [REPLACABLE] software ecc based page write function
* @mtd: mtd info structure
* @chip: nand chip info structure
@@ -1863,7 +1960,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
}
if (unlikely(ops->ooboffs >= len)) {
- DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+ DEBUG(MTD_DEBUG_LEVEL0, "nand_do_write_oob: "
"Attempt to start write outside oob\n");
return -EINVAL;
}
@@ -1873,7 +1970,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
ops->ooboffs + ops->ooblen >
((mtd->size >> chip->page_shift) -
(to >> chip->page_shift)) * len)) {
- DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+ DEBUG(MTD_DEBUG_LEVEL0, "nand_do_write_oob: "
"Attempt write beyond end of device\n");
return -EINVAL;
}
@@ -1929,8 +2026,8 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
/* Do not allow writes past end of device */
if (ops->datbuf && (to + ops->len) > mtd->size) {
- DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
- "Attempt read beyond end of device\n");
+ DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
+ "Attempt write beyond end of device\n");
return -EINVAL;
}
@@ -2555,6 +2652,9 @@ int nand_scan_tail(struct mtd_info *mtd)
case 64:
chip->ecc.layout = &nand_oob_64;
break;
+ case 128:
+ chip->ecc.layout = &nand_oob_128;
+ break;
default:
printk(KERN_WARNING "No oob scheme defined for "
"oobsize %d\n", mtd->oobsize);
@@ -2569,10 +2669,6 @@ int nand_scan_tail(struct mtd_info *mtd)
* check ECC mode, default to software if 3byte/512byte hardware ECC is
* selected and we have 256 byte pagesize fallback to software ECC
*/
- if (!chip->ecc.read_page_raw)
- chip->ecc.read_page_raw = nand_read_page_raw;
- if (!chip->ecc.write_page_raw)
- chip->ecc.write_page_raw = nand_write_page_raw;
switch (chip->ecc.mode) {
case NAND_ECC_HW:
@@ -2581,6 +2677,10 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.read_page = nand_read_page_hwecc;
if (!chip->ecc.write_page)
chip->ecc.write_page = nand_write_page_hwecc;
+ if (!chip->ecc.read_page_raw)
+ chip->ecc.read_page_raw = nand_read_page_raw;
+ if (!chip->ecc.write_page_raw)
+ chip->ecc.write_page_raw = nand_write_page_raw;
if (!chip->ecc.read_oob)
chip->ecc.read_oob = nand_read_oob_std;
if (!chip->ecc.write_oob)
@@ -2602,6 +2702,10 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.read_page = nand_read_page_syndrome;
if (!chip->ecc.write_page)
chip->ecc.write_page = nand_write_page_syndrome;
+ if (!chip->ecc.read_page_raw)
+ chip->ecc.read_page_raw = nand_read_page_raw_syndrome;
+ if (!chip->ecc.write_page_raw)
+ chip->ecc.write_page_raw = nand_write_page_raw_syndrome;
if (!chip->ecc.read_oob)
chip->ecc.read_oob = nand_read_oob_syndrome;
if (!chip->ecc.write_oob)
@@ -2620,6 +2724,8 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.read_page = nand_read_page_swecc;
chip->ecc.read_subpage = nand_read_subpage;
chip->ecc.write_page = nand_write_page_swecc;
+ chip->ecc.read_page_raw = nand_read_page_raw;
+ chip->ecc.write_page_raw = nand_write_page_raw;
chip->ecc.read_oob = nand_read_oob_std;
chip->ecc.write_oob = nand_write_oob_std;
chip->ecc.size = 256;
@@ -2632,6 +2738,8 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.read_page = nand_read_page_raw;
chip->ecc.write_page = nand_write_page_raw;
chip->ecc.read_oob = nand_read_oob_std;
+ chip->ecc.read_page_raw = nand_read_page_raw;
+ chip->ecc.write_page_raw = nand_write_page_raw;
chip->ecc.write_oob = nand_write_oob_std;
chip->ecc.size = mtd->writesize;
chip->ecc.bytes = 0;
@@ -2676,6 +2784,7 @@ int nand_scan_tail(struct mtd_info *mtd)
break;
case 4:
case 8:
+ case 16:
mtd->subpage_sft = 2;
break;
}
@@ -2720,14 +2829,14 @@ int nand_scan_tail(struct mtd_info *mtd)
return chip->scan_bbt(mtd);
}
-/* module_text_address() isn't exported, and it's mostly a pointless
+/* is_module_text_address() isn't exported, and it's mostly a pointless
test if this is a module _anyway_ -- they'd have to try _really_ hard
to call us from in-kernel code if the core NAND support is modular. */
#ifdef MODULE
#define caller_is_module() (1)
#else
#define caller_is_module() \
- module_text_address((unsigned long)__builtin_return_address(0))
+ is_module_text_address((unsigned long)__builtin_return_address(0))
#endif
/**
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index 582cf80f555a..89bf85af642c 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -187,7 +187,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
return -ENODEV;
ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s",
- ndfc->ofdev->dev.bus_id, flash_np->name);
+ dev_name(&ndfc->ofdev->dev), flash_np->name);
if (!ndfc->mtd.name) {
ret = -ENOMEM;
goto err;
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c
index 75f9f4874ecf..86e1d08eee00 100644
--- a/drivers/mtd/nand/plat_nand.c
+++ b/drivers/mtd/nand/plat_nand.c
@@ -30,7 +30,7 @@ struct plat_nand_data {
/*
* Probe for the NAND device.
*/
-static int __init plat_nand_probe(struct platform_device *pdev)
+static int __devinit plat_nand_probe(struct platform_device *pdev)
{
struct platform_nand_data *pdata = pdev->dev.platform_data;
struct plat_nand_data *data;
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index cc55cbc2b308..30a8ce6d3e69 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -22,7 +22,6 @@
#include <linux/irq.h>
#include <mach/dma.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa3xx_nand.h>
#define CHIP_DELAY_TIMEOUT (2 * HZ/10)
@@ -171,7 +170,13 @@ static int use_dma = 1;
module_param(use_dma, bool, 0444);
MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW");
-#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN
+/*
+ * Default NAND flash controller configuration setup by the
+ * bootloader. This configuration is used only when pdata->keep_config is set
+ */
+static struct pxa3xx_nand_timing default_timing;
+static struct pxa3xx_nand_flash default_flash;
+
static struct pxa3xx_nand_cmdset smallpage_cmdset = {
.read1 = 0x0000,
.read2 = 0x0050,
@@ -198,6 +203,7 @@ static struct pxa3xx_nand_cmdset largepage_cmdset = {
.lock_status = 0x007A,
};
+#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN
static struct pxa3xx_nand_timing samsung512MbX16_timing = {
.tCH = 10,
.tCS = 0,
@@ -297,9 +303,23 @@ static struct pxa3xx_nand_flash *builtin_flash_types[] = {
#define NDTR1_tWHR(c) (min((c), 15) << 4)
#define NDTR1_tAR(c) (min((c), 15) << 0)
+#define tCH_NDTR0(r) (((r) >> 19) & 0x7)
+#define tCS_NDTR0(r) (((r) >> 16) & 0x7)
+#define tWH_NDTR0(r) (((r) >> 11) & 0x7)
+#define tWP_NDTR0(r) (((r) >> 8) & 0x7)
+#define tRH_NDTR0(r) (((r) >> 3) & 0x7)
+#define tRP_NDTR0(r) (((r) >> 0) & 0x7)
+
+#define tR_NDTR1(r) (((r) >> 16) & 0xffff)
+#define tWHR_NDTR1(r) (((r) >> 4) & 0xf)
+#define tAR_NDTR1(r) (((r) >> 0) & 0xf)
+
/* convert nano-seconds to nand flash controller clock cycles */
#define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) - 1)
+/* convert nand flash controller clock cycles to nano-seconds */
+#define cycle2ns(c, clk) ((((c) + 1) * 1000000 + clk / 500) / (clk / 1000))
+
static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
const struct pxa3xx_nand_timing *t)
{
@@ -921,6 +941,82 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
return 0;
}
+static void pxa3xx_nand_detect_timing(struct pxa3xx_nand_info *info,
+ struct pxa3xx_nand_timing *t)
+{
+ unsigned long nand_clk = clk_get_rate(info->clk);
+ uint32_t ndtr0 = nand_readl(info, NDTR0CS0);
+ uint32_t ndtr1 = nand_readl(info, NDTR1CS0);
+
+ t->tCH = cycle2ns(tCH_NDTR0(ndtr0), nand_clk);
+ t->tCS = cycle2ns(tCS_NDTR0(ndtr0), nand_clk);
+ t->tWH = cycle2ns(tWH_NDTR0(ndtr0), nand_clk);
+ t->tWP = cycle2ns(tWP_NDTR0(ndtr0), nand_clk);
+ t->tRH = cycle2ns(tRH_NDTR0(ndtr0), nand_clk);
+ t->tRP = cycle2ns(tRP_NDTR0(ndtr0), nand_clk);
+
+ t->tR = cycle2ns(tR_NDTR1(ndtr1), nand_clk);
+ t->tWHR = cycle2ns(tWHR_NDTR1(ndtr1), nand_clk);
+ t->tAR = cycle2ns(tAR_NDTR1(ndtr1), nand_clk);
+}
+
+static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
+{
+ uint32_t ndcr = nand_readl(info, NDCR);
+ struct nand_flash_dev *type = NULL;
+ uint32_t id = -1;
+ int i;
+
+ default_flash.page_per_block = ndcr & NDCR_PG_PER_BLK ? 64 : 32;
+ default_flash.page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
+ default_flash.flash_width = ndcr & NDCR_DWIDTH_M ? 16 : 8;
+ default_flash.dfc_width = ndcr & NDCR_DWIDTH_C ? 16 : 8;
+
+ if (default_flash.page_size == 2048)
+ default_flash.cmdset = &largepage_cmdset;
+ else
+ default_flash.cmdset = &smallpage_cmdset;
+
+ /* set info fields needed to __readid */
+ info->flash_info = &default_flash;
+ info->read_id_bytes = (default_flash.page_size == 2048) ? 4 : 2;
+ info->reg_ndcr = ndcr;
+
+ if (__readid(info, &id))
+ return -ENODEV;
+
+ /* Lookup the flash id */
+ id = (id >> 8) & 0xff; /* device id is byte 2 */
+ for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+ if (id == nand_flash_ids[i].id) {
+ type = &nand_flash_ids[i];
+ break;
+ }
+ }
+
+ if (!type)
+ return -ENODEV;
+
+ /* fill the missing flash information */
+ i = __ffs(default_flash.page_per_block * default_flash.page_size);
+ default_flash.num_blocks = type->chipsize << (20 - i);
+
+ info->oob_size = (default_flash.page_size == 2048) ? 64 : 16;
+
+ /* calculate addressing information */
+ info->col_addr_cycles = (default_flash.page_size == 2048) ? 2 : 1;
+
+ if (default_flash.num_blocks * default_flash.page_per_block > 65536)
+ info->row_addr_cycles = 3;
+ else
+ info->row_addr_cycles = 2;
+
+ pxa3xx_nand_detect_timing(info, &default_timing);
+ default_flash.timing = &default_timing;
+
+ return 0;
+}
+
static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info,
const struct pxa3xx_nand_platform_data *pdata)
{
@@ -928,6 +1024,10 @@ static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info,
uint32_t id = -1;
int i;
+ if (pdata->keep_config)
+ if (pxa3xx_nand_detect_config(info) == 0)
+ return 0;
+
for (i = 0; i<pdata->num_flash; ++i) {
f = pdata->flash + i;
@@ -1079,6 +1179,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
this = &info->nand_chip;
mtd->priv = info;
+ mtd->owner = THIS_MODULE;
info->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(info->clk)) {
@@ -1118,14 +1219,14 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
goto fail_put_clk;
}
- r = request_mem_region(r->start, r->end - r->start + 1, pdev->name);
+ r = request_mem_region(r->start, resource_size(r), pdev->name);
if (r == NULL) {
dev_err(&pdev->dev, "failed to request memory resource\n");
ret = -EBUSY;
goto fail_put_clk;
}
- info->mmio_base = ioremap(r->start, r->end - r->start + 1);
+ info->mmio_base = ioremap(r->start, resource_size(r));
if (info->mmio_base == NULL) {
dev_err(&pdev->dev, "ioremap() failed\n");
ret = -ENODEV;
@@ -1174,7 +1275,7 @@ fail_free_buf:
fail_free_io:
iounmap(info->mmio_base);
fail_free_res:
- release_mem_region(r->start, r->end - r->start + 1);
+ release_mem_region(r->start, resource_size(r));
fail_put_clk:
clk_disable(info->clk);
clk_put(info->clk);
@@ -1187,6 +1288,7 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
{
struct mtd_info *mtd = platform_get_drvdata(pdev);
struct pxa3xx_nand_info *info = mtd->priv;
+ struct resource *r;
platform_set_drvdata(pdev, NULL);
@@ -1199,6 +1301,14 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
info->data_buff, info->data_buff_phys);
} else
kfree(info->data_buff);
+
+ iounmap(info->mmio_base);
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(r->start, resource_size(r));
+
+ clk_disable(info->clk);
+ clk_put(info->clk);
+
kfree(mtd);
return 0;
}
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 821acb08ff1c..2bc896623e2d 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -58,7 +58,7 @@ static struct nand_bbt_descr flctl_4secc_smallpage = {
};
static struct nand_bbt_descr flctl_4secc_largepage = {
- .options = 0,
+ .options = NAND_BBT_SCAN2NDPAGE,
.offs = 58,
.len = 2,
.pattern = scan_ff_pattern,
@@ -149,7 +149,7 @@ static void wait_wfifo_ready(struct sh_flctl *flctl)
printk(KERN_ERR "wait_wfifo_ready(): Timeout occured \n");
}
-static int wait_recfifo_ready(struct sh_flctl *flctl)
+static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
{
uint32_t timeout = LOOP_TIMEOUT_MAX;
int checked[4];
@@ -183,7 +183,12 @@ static int wait_recfifo_ready(struct sh_flctl *flctl)
uint8_t org;
int index;
- index = data >> 16;
+ if (flctl->page_size)
+ index = (512 * sector_number) +
+ (data >> 16);
+ else
+ index = data >> 16;
+
org = flctl->done_buff[index];
flctl->done_buff[index] = org ^ (data & 0xFF);
checked[i] = 1;
@@ -238,14 +243,14 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
}
}
-static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff)
+static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff, int sector)
{
int i;
unsigned long *ecc_buf = (unsigned long *)buff;
void *fifo_addr = (void *)FLECFIFO(flctl);
for (i = 0; i < 4; i++) {
- if (wait_recfifo_ready(flctl))
+ if (wait_recfifo_ready(flctl , sector))
return 1;
ecc_buf[i] = readl(fifo_addr);
ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
@@ -384,7 +389,8 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
read_fiforeg(flctl, 512, 512 * sector);
ret = read_ecfiforeg(flctl,
- &flctl->done_buff[mtd->writesize + 16 * sector]);
+ &flctl->done_buff[mtd->writesize + 16 * sector],
+ sector);
if (ret)
flctl->hwecc_cant_correct[sector] = 1;
diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c
new file mode 100644
index 000000000000..a4519a7bd683
--- /dev/null
+++ b/drivers/mtd/nand/socrates_nand.c
@@ -0,0 +1,325 @@
+/*
+ * drivers/mtd/nand/socrates_nand.c
+ *
+ * Copyright © 2008 Ilya Yanok, Emcraft Systems
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+
+#define FPGA_NAND_CMD_MASK (0x7 << 28)
+#define FPGA_NAND_CMD_COMMAND (0x0 << 28)
+#define FPGA_NAND_CMD_ADDR (0x1 << 28)
+#define FPGA_NAND_CMD_READ (0x2 << 28)
+#define FPGA_NAND_CMD_WRITE (0x3 << 28)
+#define FPGA_NAND_BUSY (0x1 << 15)
+#define FPGA_NAND_ENABLE (0x1 << 31)
+#define FPGA_NAND_DATA_SHIFT 16
+
+struct socrates_nand_host {
+ struct nand_chip nand_chip;
+ struct mtd_info mtd;
+ void __iomem *io_base;
+ struct device *dev;
+};
+
+/**
+ * socrates_nand_write_buf - write buffer to chip
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
+ */
+static void socrates_nand_write_buf(struct mtd_info *mtd,
+ const uint8_t *buf, int len)
+{
+ int i;
+ struct nand_chip *this = mtd->priv;
+ struct socrates_nand_host *host = this->priv;
+
+ for (i = 0; i < len; i++) {
+ out_be32(host->io_base, FPGA_NAND_ENABLE |
+ FPGA_NAND_CMD_WRITE |
+ (buf[i] << FPGA_NAND_DATA_SHIFT));
+ }
+}
+
+/**
+ * socrates_nand_read_buf - read chip data into buffer
+ * @mtd: MTD device structure
+ * @buf: buffer to store date
+ * @len: number of bytes to read
+ */
+static void socrates_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ int i;
+ struct nand_chip *this = mtd->priv;
+ struct socrates_nand_host *host = this->priv;
+ uint32_t val;
+
+ val = FPGA_NAND_ENABLE | FPGA_NAND_CMD_READ;
+
+ out_be32(host->io_base, val);
+ for (i = 0; i < len; i++) {
+ buf[i] = (in_be32(host->io_base) >>
+ FPGA_NAND_DATA_SHIFT) & 0xff;
+ }
+}
+
+/**
+ * socrates_nand_read_byte - read one byte from the chip
+ * @mtd: MTD device structure
+ */
+static uint8_t socrates_nand_read_byte(struct mtd_info *mtd)
+{
+ uint8_t byte;
+ socrates_nand_read_buf(mtd, &byte, sizeof(byte));
+ return byte;
+}
+
+/**
+ * socrates_nand_read_word - read one word from the chip
+ * @mtd: MTD device structure
+ */
+static uint16_t socrates_nand_read_word(struct mtd_info *mtd)
+{
+ uint16_t word;
+ socrates_nand_read_buf(mtd, (uint8_t *)&word, sizeof(word));
+ return word;
+}
+
+/**
+ * socrates_nand_verify_buf - Verify chip data against buffer
+ * @mtd: MTD device structure
+ * @buf: buffer containing the data to compare
+ * @len: number of bytes to compare
+ */
+static int socrates_nand_verify_buf(struct mtd_info *mtd, const u8 *buf,
+ int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (buf[i] != socrates_nand_read_byte(mtd))
+ return -EFAULT;
+ }
+ return 0;
+}
+
+/*
+ * Hardware specific access to control-lines
+ */
+static void socrates_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct socrates_nand_host *host = nand_chip->priv;
+ uint32_t val;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ if (ctrl & NAND_CLE)
+ val = FPGA_NAND_CMD_COMMAND;
+ else
+ val = FPGA_NAND_CMD_ADDR;
+
+ if (ctrl & NAND_NCE)
+ val |= FPGA_NAND_ENABLE;
+
+ val |= (cmd & 0xff) << FPGA_NAND_DATA_SHIFT;
+
+ out_be32(host->io_base, val);
+}
+
+/*
+ * Read the Device Ready pin.
+ */
+static int socrates_nand_device_ready(struct mtd_info *mtd)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct socrates_nand_host *host = nand_chip->priv;
+
+ if (in_be32(host->io_base) & FPGA_NAND_BUSY)
+ return 0; /* busy */
+ return 1;
+}
+
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probes[] = { "cmdlinepart", NULL };
+#endif
+
+/*
+ * Probe for the NAND device.
+ */
+static int __devinit socrates_nand_probe(struct of_device *ofdev,
+ const struct of_device_id *ofid)
+{
+ struct socrates_nand_host *host;
+ struct mtd_info *mtd;
+ struct nand_chip *nand_chip;
+ int res;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ struct mtd_partition *partitions = NULL;
+ int num_partitions = 0;
+#endif
+
+ /* Allocate memory for the device structure (and zero it) */
+ host = kzalloc(sizeof(struct socrates_nand_host), GFP_KERNEL);
+ if (!host) {
+ printk(KERN_ERR
+ "socrates_nand: failed to allocate device structure.\n");
+ return -ENOMEM;
+ }
+
+ host->io_base = of_iomap(ofdev->node, 0);
+ if (host->io_base == NULL) {
+ printk(KERN_ERR "socrates_nand: ioremap failed\n");
+ kfree(host);
+ return -EIO;
+ }
+
+ mtd = &host->mtd;
+ nand_chip = &host->nand_chip;
+ host->dev = &ofdev->dev;
+
+ nand_chip->priv = host; /* link the private data structures */
+ mtd->priv = nand_chip;
+ mtd->name = "socrates_nand";
+ mtd->owner = THIS_MODULE;
+ mtd->dev.parent = &ofdev->dev;
+
+ /*should never be accessed directly */
+ nand_chip->IO_ADDR_R = (void *)0xdeadbeef;
+ nand_chip->IO_ADDR_W = (void *)0xdeadbeef;
+
+ nand_chip->cmd_ctrl = socrates_nand_cmd_ctrl;
+ nand_chip->read_byte = socrates_nand_read_byte;
+ nand_chip->read_word = socrates_nand_read_word;
+ nand_chip->write_buf = socrates_nand_write_buf;
+ nand_chip->read_buf = socrates_nand_read_buf;
+ nand_chip->verify_buf = socrates_nand_verify_buf;
+ nand_chip->dev_ready = socrates_nand_device_ready;
+
+ nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */
+
+ /* TODO: I have no idea what real delay is. */
+ nand_chip->chip_delay = 20; /* 20us command delay time */
+
+ dev_set_drvdata(&ofdev->dev, host);
+
+ /* first scan to find the device and get the page size */
+ if (nand_scan_ident(mtd, 1)) {
+ res = -ENXIO;
+ goto out;
+ }
+
+ /* second phase scan */
+ if (nand_scan_tail(mtd)) {
+ res = -ENXIO;
+ goto out;
+ }
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+ num_partitions = parse_mtd_partitions(mtd, part_probes,
+ &partitions, 0);
+ if (num_partitions < 0) {
+ res = num_partitions;
+ goto release;
+ }
+#endif
+
+#ifdef CONFIG_MTD_OF_PARTS
+ if (num_partitions == 0) {
+ num_partitions = of_mtd_parse_partitions(&ofdev->dev,
+ ofdev->node,
+ &partitions);
+ if (num_partitions < 0) {
+ res = num_partitions;
+ goto release;
+ }
+ }
+#endif
+ if (partitions && (num_partitions > 0))
+ res = add_mtd_partitions(mtd, partitions, num_partitions);
+ else
+#endif
+ res = add_mtd_device(mtd);
+
+ if (!res)
+ return res;
+
+#ifdef CONFIG_MTD_PARTITIONS
+release:
+#endif
+ nand_release(mtd);
+
+out:
+ dev_set_drvdata(&ofdev->dev, NULL);
+ iounmap(host->io_base);
+ kfree(host);
+ return res;
+}
+
+/*
+ * Remove a NAND device.
+ */
+static int __devexit socrates_nand_remove(struct of_device *ofdev)
+{
+ struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev);
+ struct mtd_info *mtd = &host->mtd;
+
+ nand_release(mtd);
+
+ dev_set_drvdata(&ofdev->dev, NULL);
+ iounmap(host->io_base);
+ kfree(host);
+
+ return 0;
+}
+
+static struct of_device_id socrates_nand_match[] =
+{
+ {
+ .compatible = "abb,socrates-nand",
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, socrates_nand_match);
+
+static struct of_platform_driver socrates_nand_driver = {
+ .name = "socrates_nand",
+ .match_table = socrates_nand_match,
+ .probe = socrates_nand_probe,
+ .remove = __devexit_p(socrates_nand_remove),
+};
+
+static int __init socrates_nand_init(void)
+{
+ return of_register_platform_driver(&socrates_nand_driver);
+}
+
+static void __exit socrates_nand_exit(void)
+{
+ of_unregister_platform_driver(&socrates_nand_driver);
+}
+
+module_init(socrates_nand_init);
+module_exit(socrates_nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ilya Yanok");
+MODULE_DESCRIPTION("NAND driver for Socrates board");
diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c
new file mode 100644
index 000000000000..812479264896
--- /dev/null
+++ b/drivers/mtd/nand/txx9ndfmc.c
@@ -0,0 +1,428 @@
+/*
+ * TXx9 NAND flash memory controller driver
+ * Based on RBTX49xx patch from CELF patch archive.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (C) Copyright TOSHIBA CORPORATION 2004-2007
+ * All Rights Reserved.
+ */
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+#include <asm/txx9/ndfmc.h>
+
+/* TXX9 NDFMC Registers */
+#define TXX9_NDFDTR 0x00
+#define TXX9_NDFMCR 0x04
+#define TXX9_NDFSR 0x08
+#define TXX9_NDFISR 0x0c
+#define TXX9_NDFIMR 0x10
+#define TXX9_NDFSPR 0x14
+#define TXX9_NDFRSTR 0x18 /* not TX4939 */
+
+/* NDFMCR : NDFMC Mode Control */
+#define TXX9_NDFMCR_WE 0x80
+#define TXX9_NDFMCR_ECC_ALL 0x60
+#define TXX9_NDFMCR_ECC_RESET 0x60
+#define TXX9_NDFMCR_ECC_READ 0x40
+#define TXX9_NDFMCR_ECC_ON 0x20
+#define TXX9_NDFMCR_ECC_OFF 0x00
+#define TXX9_NDFMCR_CE 0x10
+#define TXX9_NDFMCR_BSPRT 0x04 /* TX4925/TX4926 only */
+#define TXX9_NDFMCR_ALE 0x02
+#define TXX9_NDFMCR_CLE 0x01
+/* TX4939 only */
+#define TXX9_NDFMCR_X16 0x0400
+#define TXX9_NDFMCR_DMAREQ_MASK 0x0300
+#define TXX9_NDFMCR_DMAREQ_NODMA 0x0000
+#define TXX9_NDFMCR_DMAREQ_128 0x0100
+#define TXX9_NDFMCR_DMAREQ_256 0x0200
+#define TXX9_NDFMCR_DMAREQ_512 0x0300
+#define TXX9_NDFMCR_CS_MASK 0x0c
+#define TXX9_NDFMCR_CS(ch) ((ch) << 2)
+
+/* NDFMCR : NDFMC Status */
+#define TXX9_NDFSR_BUSY 0x80
+/* TX4939 only */
+#define TXX9_NDFSR_DMARUN 0x40
+
+/* NDFMCR : NDFMC Reset */
+#define TXX9_NDFRSTR_RST 0x01
+
+struct txx9ndfmc_priv {
+ struct platform_device *dev;
+ struct nand_chip chip;
+ struct mtd_info mtd;
+ int cs;
+ char mtdname[BUS_ID_SIZE + 2];
+};
+
+#define MAX_TXX9NDFMC_DEV 4
+struct txx9ndfmc_drvdata {
+ struct mtd_info *mtds[MAX_TXX9NDFMC_DEV];
+ void __iomem *base;
+ unsigned char hold; /* in gbusclock */
+ unsigned char spw; /* in gbusclock */
+ struct nand_hw_control hw_control;
+#ifdef CONFIG_MTD_PARTITIONS
+ struct mtd_partition *parts[MAX_TXX9NDFMC_DEV];
+#endif
+};
+
+static struct platform_device *mtd_to_platdev(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct txx9ndfmc_priv *txx9_priv = chip->priv;
+ return txx9_priv->dev;
+}
+
+static void __iomem *ndregaddr(struct platform_device *dev, unsigned int reg)
+{
+ struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
+ struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+
+ return drvdata->base + (reg << plat->shift);
+}
+
+static u32 txx9ndfmc_read(struct platform_device *dev, unsigned int reg)
+{
+ return __raw_readl(ndregaddr(dev, reg));
+}
+
+static void txx9ndfmc_write(struct platform_device *dev,
+ u32 val, unsigned int reg)
+{
+ __raw_writel(val, ndregaddr(dev, reg));
+}
+
+static uint8_t txx9ndfmc_read_byte(struct mtd_info *mtd)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+
+ return txx9ndfmc_read(dev, TXX9_NDFDTR);
+}
+
+static void txx9ndfmc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
+ int len)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
+ u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_WE, TXX9_NDFMCR);
+ while (len--)
+ __raw_writel(*buf++, ndfdtr);
+ txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
+}
+
+static void txx9ndfmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
+
+ while (len--)
+ *buf++ = __raw_readl(ndfdtr);
+}
+
+static int txx9ndfmc_verify_buf(struct mtd_info *mtd, const uint8_t *buf,
+ int len)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
+
+ while (len--)
+ if (*buf++ != (uint8_t)__raw_readl(ndfdtr))
+ return -EFAULT;
+ return 0;
+}
+
+static void txx9ndfmc_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct txx9ndfmc_priv *txx9_priv = chip->priv;
+ struct platform_device *dev = txx9_priv->dev;
+ struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+ mcr &= ~(TXX9_NDFMCR_CLE | TXX9_NDFMCR_ALE | TXX9_NDFMCR_CE);
+ mcr |= ctrl & NAND_CLE ? TXX9_NDFMCR_CLE : 0;
+ mcr |= ctrl & NAND_ALE ? TXX9_NDFMCR_ALE : 0;
+ /* TXX9_NDFMCR_CE bit is 0:high 1:low */
+ mcr |= ctrl & NAND_NCE ? TXX9_NDFMCR_CE : 0;
+ if (txx9_priv->cs >= 0 && (ctrl & NAND_NCE)) {
+ mcr &= ~TXX9_NDFMCR_CS_MASK;
+ mcr |= TXX9_NDFMCR_CS(txx9_priv->cs);
+ }
+ txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
+ }
+ if (cmd != NAND_CMD_NONE)
+ txx9ndfmc_write(dev, cmd & 0xff, TXX9_NDFDTR);
+ if (plat->flags & NDFMC_PLAT_FLAG_DUMMYWRITE) {
+ /* dummy write to update external latch */
+ if ((ctrl & NAND_CTRL_CHANGE) && cmd == NAND_CMD_NONE)
+ txx9ndfmc_write(dev, 0, TXX9_NDFDTR);
+ }
+ mmiowb();
+}
+
+static int txx9ndfmc_dev_ready(struct mtd_info *mtd)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+
+ return !(txx9ndfmc_read(dev, TXX9_NDFSR) & TXX9_NDFSR_BUSY);
+}
+
+static int txx9ndfmc_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
+ uint8_t *ecc_code)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+ mcr &= ~TXX9_NDFMCR_ECC_ALL;
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_READ, TXX9_NDFMCR);
+ ecc_code[1] = txx9ndfmc_read(dev, TXX9_NDFDTR);
+ ecc_code[0] = txx9ndfmc_read(dev, TXX9_NDFDTR);
+ ecc_code[2] = txx9ndfmc_read(dev, TXX9_NDFDTR);
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
+ return 0;
+}
+
+static void txx9ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+ mcr &= ~TXX9_NDFMCR_ECC_ALL;
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_RESET, TXX9_NDFMCR);
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_ON, TXX9_NDFMCR);
+}
+
+static void txx9ndfmc_initialize(struct platform_device *dev)
+{
+ struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+ struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
+ int tmout = 100;
+
+ if (plat->flags & NDFMC_PLAT_FLAG_NO_RSTR)
+ ; /* no NDFRSTR. Write to NDFSPR resets the NDFMC. */
+ else {
+ /* reset NDFMC */
+ txx9ndfmc_write(dev,
+ txx9ndfmc_read(dev, TXX9_NDFRSTR) |
+ TXX9_NDFRSTR_RST,
+ TXX9_NDFRSTR);
+ while (txx9ndfmc_read(dev, TXX9_NDFRSTR) & TXX9_NDFRSTR_RST) {
+ if (--tmout == 0) {
+ dev_err(&dev->dev, "reset failed.\n");
+ break;
+ }
+ udelay(1);
+ }
+ }
+ /* setup Hold Time, Strobe Pulse Width */
+ txx9ndfmc_write(dev, (drvdata->hold << 4) | drvdata->spw, TXX9_NDFSPR);
+ txx9ndfmc_write(dev,
+ (plat->flags & NDFMC_PLAT_FLAG_USE_BSPRT) ?
+ TXX9_NDFMCR_BSPRT : 0, TXX9_NDFMCR);
+}
+
+#define TXX9NDFMC_NS_TO_CYC(gbusclk, ns) \
+ DIV_ROUND_UP((ns) * DIV_ROUND_UP(gbusclk, 1000), 1000000)
+
+static int __init txx9ndfmc_probe(struct platform_device *dev)
+{
+ struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+#ifdef CONFIG_MTD_PARTITIONS
+ static const char *probes[] = { "cmdlinepart", NULL };
+#endif
+ int hold, spw;
+ int i;
+ struct txx9ndfmc_drvdata *drvdata;
+ unsigned long gbusclk = plat->gbus_clock;
+ struct resource *res;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+ drvdata = devm_kzalloc(&dev->dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+ if (!devm_request_mem_region(&dev->dev, res->start,
+ resource_size(res), dev_name(&dev->dev)))
+ return -EBUSY;
+ drvdata->base = devm_ioremap(&dev->dev, res->start,
+ resource_size(res));
+ if (!drvdata->base)
+ return -EBUSY;
+
+ hold = plat->hold ?: 20; /* tDH */
+ spw = plat->spw ?: 90; /* max(tREADID, tWP, tRP) */
+
+ hold = TXX9NDFMC_NS_TO_CYC(gbusclk, hold);
+ spw = TXX9NDFMC_NS_TO_CYC(gbusclk, spw);
+ if (plat->flags & NDFMC_PLAT_FLAG_HOLDADD)
+ hold -= 2; /* actual hold time : (HOLD + 2) BUSCLK */
+ spw -= 1; /* actual wait time : (SPW + 1) BUSCLK */
+ hold = clamp(hold, 1, 15);
+ drvdata->hold = hold;
+ spw = clamp(spw, 1, 15);
+ drvdata->spw = spw;
+ dev_info(&dev->dev, "CLK:%ldMHz HOLD:%d SPW:%d\n",
+ (gbusclk + 500000) / 1000000, hold, spw);
+
+ spin_lock_init(&drvdata->hw_control.lock);
+ init_waitqueue_head(&drvdata->hw_control.wq);
+
+ platform_set_drvdata(dev, drvdata);
+ txx9ndfmc_initialize(dev);
+
+ for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
+ struct txx9ndfmc_priv *txx9_priv;
+ struct nand_chip *chip;
+ struct mtd_info *mtd;
+#ifdef CONFIG_MTD_PARTITIONS
+ int nr_parts;
+#endif
+
+ if (!(plat->ch_mask & (1 << i)))
+ continue;
+ txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv),
+ GFP_KERNEL);
+ if (!txx9_priv) {
+ dev_err(&dev->dev, "Unable to allocate "
+ "TXx9 NDFMC MTD device structure.\n");
+ continue;
+ }
+ chip = &txx9_priv->chip;
+ mtd = &txx9_priv->mtd;
+ mtd->owner = THIS_MODULE;
+
+ mtd->priv = chip;
+
+ chip->read_byte = txx9ndfmc_read_byte;
+ chip->read_buf = txx9ndfmc_read_buf;
+ chip->write_buf = txx9ndfmc_write_buf;
+ chip->verify_buf = txx9ndfmc_verify_buf;
+ chip->cmd_ctrl = txx9ndfmc_cmd_ctrl;
+ chip->dev_ready = txx9ndfmc_dev_ready;
+ chip->ecc.calculate = txx9ndfmc_calculate_ecc;
+ chip->ecc.correct = nand_correct_data;
+ chip->ecc.hwctl = txx9ndfmc_enable_hwecc;
+ chip->ecc.mode = NAND_ECC_HW;
+ chip->ecc.size = 256;
+ chip->ecc.bytes = 3;
+ chip->chip_delay = 100;
+ chip->controller = &drvdata->hw_control;
+
+ chip->priv = txx9_priv;
+ txx9_priv->dev = dev;
+
+ if (plat->ch_mask != 1) {
+ txx9_priv->cs = i;
+ sprintf(txx9_priv->mtdname, "%s.%u",
+ dev_name(&dev->dev), i);
+ } else {
+ txx9_priv->cs = -1;
+ strcpy(txx9_priv->mtdname, dev_name(&dev->dev));
+ }
+ if (plat->wide_mask & (1 << i))
+ chip->options |= NAND_BUSWIDTH_16;
+
+ if (nand_scan(mtd, 1)) {
+ kfree(txx9_priv);
+ continue;
+ }
+ mtd->name = txx9_priv->mtdname;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ nr_parts = parse_mtd_partitions(mtd, probes,
+ &drvdata->parts[i], 0);
+ if (nr_parts > 0)
+ add_mtd_partitions(mtd, drvdata->parts[i], nr_parts);
+#endif
+ add_mtd_device(mtd);
+ drvdata->mtds[i] = mtd;
+ }
+
+ return 0;
+}
+
+static int __exit txx9ndfmc_remove(struct platform_device *dev)
+{
+ struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
+ int i;
+
+ platform_set_drvdata(dev, NULL);
+ if (!drvdata)
+ return 0;
+ for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
+ struct mtd_info *mtd = drvdata->mtds[i];
+ struct nand_chip *chip;
+ struct txx9ndfmc_priv *txx9_priv;
+
+ if (!mtd)
+ continue;
+ chip = mtd->priv;
+ txx9_priv = chip->priv;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ del_mtd_partitions(mtd);
+ kfree(drvdata->parts[i]);
+#endif
+ del_mtd_device(mtd);
+ kfree(txx9_priv);
+ }
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int txx9ndfmc_resume(struct platform_device *dev)
+{
+ if (platform_get_drvdata(dev))
+ txx9ndfmc_initialize(dev);
+ return 0;
+}
+#else
+#define txx9ndfmc_resume NULL
+#endif
+
+static struct platform_driver txx9ndfmc_driver = {
+ .remove = __exit_p(txx9ndfmc_remove),
+ .resume = txx9ndfmc_resume,
+ .driver = {
+ .name = "txx9ndfmc",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init txx9ndfmc_init(void)
+{
+ return platform_driver_probe(&txx9ndfmc_driver, txx9ndfmc_probe);
+}
+
+static void __exit txx9ndfmc_exit(void)
+{
+ platform_driver_unregister(&txx9ndfmc_driver);
+}
+
+module_init(txx9ndfmc_init);
+module_exit(txx9ndfmc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TXx9 SoC NAND flash controller driver");
+MODULE_ALIAS("platform:txx9ndfmc");
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index d1c4546513f7..e3f8495a94c2 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -15,11 +15,11 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/hdreg.h>
+#include <linux/blkdev.h>
#include <linux/kmod.h>
#include <linux/mtd/mtd.h>
@@ -818,3 +818,4 @@ module_exit(cleanup_nftl);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>, Fabrice Bellard <fabrice.bellard@netgem.com> et al.");
MODULE_DESCRIPTION("Support code for NAND Flash Translation Layer, used on M-Systems DiskOnChip 2000 and Millennium");
+MODULE_ALIAS_BLOCKDEV_MAJOR(NFTL_MAJOR);
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 9e45b3f39c0e..3e164f0c9295 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -46,6 +46,13 @@ int __devinit of_mtd_parse_partitions(struct device *dev,
const u32 *reg;
int len;
+ /* check if this is a partition node */
+ partname = of_get_property(pp, "name", &len);
+ if (strcmp(partname, "partition") != 0) {
+ nr_parts--;
+ continue;
+ }
+
reg = of_get_property(pp, "reg", &len);
if (!reg || (len != 2 * sizeof(u32))) {
of_node_put(pp);
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
index 5b69e7773c6c..3a496c33fb52 100644
--- a/drivers/mtd/onenand/generic.c
+++ b/drivers/mtd/onenand/generic.c
@@ -36,10 +36,9 @@ struct onenand_info {
struct onenand_chip onenand;
};
-static int __devinit generic_onenand_probe(struct device *dev)
+static int __devinit generic_onenand_probe(struct platform_device *pdev)
{
struct onenand_info *info;
- struct platform_device *pdev = to_platform_device(dev);
struct flash_platform_data *pdata = pdev->dev.platform_data;
struct resource *res = pdev->resource;
unsigned long size = res->end - res->start + 1;
@@ -49,7 +48,7 @@ static int __devinit generic_onenand_probe(struct device *dev)
if (!info)
return -ENOMEM;
- if (!request_mem_region(res->start, size, dev->driver->name)) {
+ if (!request_mem_region(res->start, size, pdev->dev.driver->name)) {
err = -EBUSY;
goto out_free_info;
}
@@ -82,7 +81,7 @@ static int __devinit generic_onenand_probe(struct device *dev)
#endif
err = add_mtd_device(&info->mtd);
- dev_set_drvdata(&pdev->dev, info);
+ platform_set_drvdata(pdev, info);
return 0;
@@ -96,14 +95,13 @@ out_free_info:
return err;
}
-static int __devexit generic_onenand_remove(struct device *dev)
+static int __devexit generic_onenand_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct onenand_info *info = dev_get_drvdata(&pdev->dev);
+ struct onenand_info *info = platform_get_drvdata(pdev);
struct resource *res = pdev->resource;
unsigned long size = res->end - res->start + 1;
- dev_set_drvdata(&pdev->dev, NULL);
+ platform_set_drvdata(pdev, NULL);
if (info) {
if (info->parts)
@@ -120,9 +118,11 @@ static int __devexit generic_onenand_remove(struct device *dev)
return 0;
}
-static struct device_driver generic_onenand_driver = {
- .name = DRIVER_NAME,
- .bus = &platform_bus_type,
+static struct platform_driver generic_onenand_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
.probe = generic_onenand_probe,
.remove = __devexit_p(generic_onenand_remove),
};
@@ -131,12 +131,12 @@ MODULE_ALIAS(DRIVER_NAME);
static int __init generic_onenand_init(void)
{
- return driver_register(&generic_onenand_driver);
+ return platform_driver_register(&generic_onenand_driver);
}
static void __exit generic_onenand_exit(void)
{
- driver_unregister(&generic_onenand_driver);
+ platform_driver_unregister(&generic_onenand_driver);
}
module_init(generic_onenand_init);
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 77a4f1446156..f2e9de1414df 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -294,6 +294,10 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
goto out_copy;
+ /* panic_write() may be in an interrupt context */
+ if (in_interrupt())
+ goto out_copy;
+
if (buf >= high_memory) {
struct page *p1;
@@ -672,6 +676,8 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
c->mtd.priv = &c->onenand;
c->mtd.owner = THIS_MODULE;
+ c->mtd.dev.parent = &pdev->dev;
+
if (c->dma_channel >= 0) {
struct onenand_chip *this = &c->onenand;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 529af271db17..30d6999e5f9f 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1455,7 +1455,8 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops)
{
struct onenand_chip *this = mtd->priv;
- int written = 0, column, thislen, subpage;
+ int written = 0, column, thislen = 0, subpage = 0;
+ int prev = 0, prevlen = 0, prev_subpage = 0, first = 1;
int oobwritten = 0, oobcolumn, thisooblen, oobsize;
size_t len = ops->len;
size_t ooblen = ops->ooblen;
@@ -1482,6 +1483,10 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
return -EINVAL;
}
+ /* Check zero length */
+ if (!len)
+ return 0;
+
if (ops->mode == MTD_OOB_AUTO)
oobsize = this->ecclayout->oobavail;
else
@@ -1492,79 +1497,121 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
column = to & (mtd->writesize - 1);
/* Loop until all data write */
- while (written < len) {
- u_char *wbuf = (u_char *) buf;
+ while (1) {
+ if (written < len) {
+ u_char *wbuf = (u_char *) buf;
- thislen = min_t(int, mtd->writesize - column, len - written);
- thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
+ thislen = min_t(int, mtd->writesize - column, len - written);
+ thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
- cond_resched();
+ cond_resched();
- this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
+ this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
- /* Partial page write */
- subpage = thislen < mtd->writesize;
- if (subpage) {
- memset(this->page_buf, 0xff, mtd->writesize);
- memcpy(this->page_buf + column, buf, thislen);
- wbuf = this->page_buf;
- }
+ /* Partial page write */
+ subpage = thislen < mtd->writesize;
+ if (subpage) {
+ memset(this->page_buf, 0xff, mtd->writesize);
+ memcpy(this->page_buf + column, buf, thislen);
+ wbuf = this->page_buf;
+ }
- this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
+ this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
- if (oob) {
- oobbuf = this->oob_buf;
+ if (oob) {
+ oobbuf = this->oob_buf;
- /* We send data to spare ram with oobsize
- * to prevent byte access */
- memset(oobbuf, 0xff, mtd->oobsize);
- if (ops->mode == MTD_OOB_AUTO)
- onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
- else
- memcpy(oobbuf + oobcolumn, oob, thisooblen);
+ /* We send data to spare ram with oobsize
+ * to prevent byte access */
+ memset(oobbuf, 0xff, mtd->oobsize);
+ if (ops->mode == MTD_OOB_AUTO)
+ onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
+ else
+ memcpy(oobbuf + oobcolumn, oob, thisooblen);
- oobwritten += thisooblen;
- oob += thisooblen;
- oobcolumn = 0;
+ oobwritten += thisooblen;
+ oob += thisooblen;
+ oobcolumn = 0;
+ } else
+ oobbuf = (u_char *) ffchars;
+
+ this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
} else
- oobbuf = (u_char *) ffchars;
+ ONENAND_SET_NEXT_BUFFERRAM(this);
- this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
+ /*
+ * 2 PLANE, MLC, and Flex-OneNAND doesn't support
+ * write-while-programe feature.
+ */
+ if (!ONENAND_IS_2PLANE(this) && !first) {
+ ONENAND_SET_PREV_BUFFERRAM(this);
- this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
+ ret = this->wait(mtd, FL_WRITING);
- ret = this->wait(mtd, FL_WRITING);
+ /* In partial page write we don't update bufferram */
+ onenand_update_bufferram(mtd, prev, !ret && !prev_subpage);
+ if (ret) {
+ written -= prevlen;
+ printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
+ break;
+ }
- /* In partial page write we don't update bufferram */
- onenand_update_bufferram(mtd, to, !ret && !subpage);
- if (ONENAND_IS_2PLANE(this)) {
- ONENAND_SET_BUFFERRAM1(this);
- onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage);
- }
+ if (written == len) {
+ /* Only check verify write turn on */
+ ret = onenand_verify(mtd, buf - len, to - len, len);
+ if (ret)
+ printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
+ break;
+ }
- if (ret) {
- printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
- break;
+ ONENAND_SET_NEXT_BUFFERRAM(this);
}
- /* Only check verify write turn on */
- ret = onenand_verify(mtd, buf, to, thislen);
- if (ret) {
- printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
- break;
- }
+ this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
- written += thislen;
+ /*
+ * 2 PLANE, MLC, and Flex-OneNAND wait here
+ */
+ if (ONENAND_IS_2PLANE(this)) {
+ ret = this->wait(mtd, FL_WRITING);
- if (written == len)
- break;
+ /* In partial page write we don't update bufferram */
+ onenand_update_bufferram(mtd, to, !ret && !subpage);
+ if (ret) {
+ printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
+ break;
+ }
+
+ /* Only check verify write turn on */
+ ret = onenand_verify(mtd, buf, to, thislen);
+ if (ret) {
+ printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
+ break;
+ }
+
+ written += thislen;
+
+ if (written == len)
+ break;
+
+ } else
+ written += thislen;
column = 0;
+ prev_subpage = subpage;
+ prev = to;
+ prevlen = thislen;
to += thislen;
buf += thislen;
+ first = 0;
}
+ /* In error case, clear all bufferrams */
+ if (written != len)
+ onenand_invalidate_bufferram(mtd, 0, -1);
+
ops->retlen = written;
+ ops->oobretlen = oobwritten;
return ret;
}
diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c
index afbc3f8126db..a18e8d2f2557 100644
--- a/drivers/mtd/tests/mtd_oobtest.c
+++ b/drivers/mtd/tests/mtd_oobtest.c
@@ -136,7 +136,7 @@ static int write_eraseblock(int ebnum)
ops.ooblen = use_len;
ops.oobretlen = 0;
ops.ooboffs = use_offset;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
err = mtd->write_oob(mtd, addr, &ops);
if (err || ops.oobretlen != use_len) {
@@ -189,7 +189,7 @@ static int verify_eraseblock(int ebnum)
ops.ooblen = use_len;
ops.oobretlen = 0;
ops.ooboffs = use_offset;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
err = mtd->read_oob(mtd, addr, &ops);
if (err || ops.oobretlen != use_len) {
@@ -216,7 +216,7 @@ static int verify_eraseblock(int ebnum)
ops.ooblen = mtd->ecclayout->oobavail;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
err = mtd->read_oob(mtd, addr, &ops);
if (err || ops.oobretlen != mtd->ecclayout->oobavail) {
@@ -281,7 +281,7 @@ static int verify_eraseblock_in_one_go(int ebnum)
ops.ooblen = len;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
err = mtd->read_oob(mtd, addr, &ops);
if (err || ops.oobretlen != len) {
@@ -522,7 +522,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = 1;
ops.oobretlen = 0;
ops.ooboffs = mtd->ecclayout->oobavail;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
printk(PRINT_PREF "attempting to start write past end of OOB\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -542,7 +542,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = 1;
ops.oobretlen = 0;
ops.ooboffs = mtd->ecclayout->oobavail;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
printk(PRINT_PREF "attempting to start read past end of OOB\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -566,7 +566,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail + 1;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
printk(PRINT_PREF "attempting to write past end of device\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -586,7 +586,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail + 1;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
printk(PRINT_PREF "attempting to read past end of device\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -610,7 +610,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail;
ops.oobretlen = 0;
ops.ooboffs = 1;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
printk(PRINT_PREF "attempting to write past end of device\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -630,7 +630,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail;
ops.oobretlen = 0;
ops.ooboffs = 1;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
printk(PRINT_PREF "attempting to read past end of device\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -670,7 +670,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = sz;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
err = mtd->write_oob(mtd, addr, &ops);
if (err)
@@ -698,7 +698,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail * 2;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
err = mtd->read_oob(mtd, addr, &ops);
if (err)
diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c
index 645e77fdc63d..79fc4530987b 100644
--- a/drivers/mtd/tests/mtd_readtest.c
+++ b/drivers/mtd/tests/mtd_readtest.c
@@ -71,7 +71,7 @@ static int read_eraseblock_by_page(int ebnum)
ops.ooblen = mtd->oobsize;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = oobbuf;
ret = mtd->read_oob(mtd, addr, &ops);
if (ret || ops.oobretlen != mtd->oobsize) {
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index e63c8fc3df3a..f8e0f68f2186 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -186,6 +186,16 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin)
return new_offset;
}
+static int vol_cdev_fsync(struct file *file, struct dentry *dentry,
+ int datasync)
+{
+ struct ubi_volume_desc *desc = file->private_data;
+ struct ubi_device *ubi = desc->vol->ubi;
+
+ return ubi_sync(ubi->ubi_num);
+}
+
+
static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
loff_t *offp)
{
@@ -1073,6 +1083,7 @@ const struct file_operations ubi_vol_cdev_operations = {
.llseek = vol_cdev_llseek,
.read = vol_cdev_read,
.write = vol_cdev_write,
+ .fsync = vol_cdev_fsync,
.unlocked_ioctl = vol_cdev_ioctl,
.compat_ioctl = vol_cdev_compat_ioctl,
};
diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c
index 3d1318a3e688..1c5344aa57cc 100644
--- a/drivers/net/3c501.c
+++ b/drivers/net/3c501.c
@@ -197,6 +197,17 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops el_netdev_ops = {
+ .ndo_open = el_open,
+ .ndo_stop = el1_close,
+ .ndo_start_xmit = el_start_xmit,
+ .ndo_tx_timeout = el_timeout,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/**
* el1_probe1:
* @dev: The device structure to use
@@ -305,12 +316,8 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
* The EL1-specific entries in the device structure.
*/
- dev->open = &el_open;
- dev->hard_start_xmit = &el_start_xmit;
- dev->tx_timeout = &el_timeout;
+ dev->netdev_ops = &el_netdev_ops;
dev->watchdog_timeo = HZ;
- dev->stop = &el1_close;
- dev->set_multicast_list = &set_multicast_list;
dev->ethtool_ops = &netdev_ethtool_ops;
return 0;
}
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index 5b91a85fe107..4f08bd995836 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -353,9 +353,6 @@ el2_probe1(struct net_device *dev, int ioaddr)
dev->netdev_ops = &el2_netdev_ops;
dev->ethtool_ops = &netdev_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = eip_poll;
-#endif
retval = register_netdev(dev);
if (retval)
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
index a8107f992fb4..2de1c9cd7bde 100644
--- a/drivers/net/3c505.c
+++ b/drivers/net/3c505.c
@@ -1354,6 +1354,17 @@ static int __init elp_autodetect(struct net_device *dev)
return 0; /* Because of this, the layer above will return -ENODEV */
}
+static const struct net_device_ops elp_netdev_ops = {
+ .ndo_open = elp_open,
+ .ndo_stop = elp_close,
+ .ndo_get_stats = elp_get_stats,
+ .ndo_start_xmit = elp_start_xmit,
+ .ndo_tx_timeout = elp_timeout,
+ .ndo_set_multicast_list = elp_set_mc_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
/******************************************************
*
@@ -1558,13 +1569,8 @@ static int __init elplus_setup(struct net_device *dev)
printk(KERN_ERR "%s: adapter configuration failed\n", dev->name);
}
- dev->open = elp_open; /* local */
- dev->stop = elp_close; /* local */
- dev->get_stats = elp_get_stats; /* local */
- dev->hard_start_xmit = elp_start_xmit; /* local */
- dev->tx_timeout = elp_timeout; /* local */
+ dev->netdev_ops = &elp_netdev_ops;
dev->watchdog_timeo = 10*HZ;
- dev->set_multicast_list = elp_set_mc_list; /* local */
dev->ethtool_ops = &netdev_ethtool_ops; /* local */
dev->mem_start = dev->mem_end = 0;
diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c
index 423e65d0ba73..fbbaf826deff 100644
--- a/drivers/net/3c507.c
+++ b/drivers/net/3c507.c
@@ -352,6 +352,16 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = el16_open,
+ .ndo_stop = el16_close,
+ .ndo_start_xmit = el16_send_packet,
+ .ndo_tx_timeout = el16_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init el16_probe1(struct net_device *dev, int ioaddr)
{
static unsigned char init_ID_done, version_printed;
@@ -449,10 +459,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
goto out1;
}
- dev->open = el16_open;
- dev->stop = el16_close;
- dev->hard_start_xmit = el16_send_packet;
- dev->tx_timeout = el16_tx_timeout;
+ dev->netdev_ops = &netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
dev->ethtool_ops = &netdev_ethtool_ops;
dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index 8c694213035b..fbb371921991 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -537,6 +537,21 @@ static struct mca_driver el3_mca_driver = {
static int mca_registered;
#endif /* CONFIG_MCA */
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = el3_open,
+ .ndo_stop = el3_close,
+ .ndo_start_xmit = el3_start_xmit,
+ .ndo_get_stats = el3_get_stats,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_tx_timeout = el3_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = el3_poll_controller,
+#endif
+};
+
static int __devinit el3_common_init(struct net_device *dev)
{
struct el3_private *lp = netdev_priv(dev);
@@ -553,16 +568,8 @@ static int __devinit el3_common_init(struct net_device *dev)
}
/* The EL3-specific entries in the device structure. */
- dev->open = &el3_open;
- dev->hard_start_xmit = &el3_start_xmit;
- dev->stop = &el3_close;
- dev->get_stats = &el3_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->tx_timeout = el3_tx_timeout;
+ dev->netdev_ops = &netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = el3_poll_controller;
-#endif
SET_ETHTOOL_OPS(dev, &ethtool_ops);
err = register_netdev(dev);
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
index 39ac12233aa7..167bf23066ea 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -563,6 +563,20 @@ no_pnp:
return NULL;
}
+
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = corkscrew_open,
+ .ndo_stop = corkscrew_close,
+ .ndo_start_xmit = corkscrew_start_xmit,
+ .ndo_tx_timeout = corkscrew_timeout,
+ .ndo_get_stats = corkscrew_get_stats,
+ .ndo_set_multicast_list = set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+
static int corkscrew_setup(struct net_device *dev, int ioaddr,
struct pnp_dev *idev, int card_number)
{
@@ -681,13 +695,8 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
/* The 3c51x-specific entries in the device structure. */
- dev->open = &corkscrew_open;
- dev->hard_start_xmit = &corkscrew_start_xmit;
- dev->tx_timeout = &corkscrew_timeout;
+ dev->netdev_ops = &netdev_ops;
dev->watchdog_timeo = (400 * HZ) / 1000;
- dev->stop = &corkscrew_close;
- dev->get_stats = &corkscrew_get_stats;
- dev->set_multicast_list = &set_rx_mode;
dev->ethtool_ops = &netdev_ethtool_ops;
return register_netdev(dev);
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
index ff41e1ff5603..8f734d74b513 100644
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -403,6 +403,20 @@ static int elmc_getinfo(char *buf, int slot, void *d)
return len;
} /* elmc_getinfo() */
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = elmc_open,
+ .ndo_stop = elmc_close,
+ .ndo_get_stats = elmc_get_stats,
+ .ndo_start_xmit = elmc_send_packet,
+ .ndo_tx_timeout = elmc_timeout,
+#ifdef ELMC_MULTICAST
+ .ndo_set_multicast_list = set_multicast_list,
+#endif
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*****************************************************************/
static int __init do_elmc_probe(struct net_device *dev)
@@ -544,17 +558,8 @@ static int __init do_elmc_probe(struct net_device *dev)
printk(KERN_INFO "%s: hardware address %pM\n",
dev->name, dev->dev_addr);
- dev->open = &elmc_open;
- dev->stop = &elmc_close;
- dev->get_stats = &elmc_get_stats;
- dev->hard_start_xmit = &elmc_send_packet;
- dev->tx_timeout = &elmc_timeout;
+ dev->netdev_ops = &netdev_ops;
dev->watchdog_timeo = HZ;
-#ifdef ELMC_MULTICAST
- dev->set_multicast_list = &set_multicast_list;
-#else
- dev->set_multicast_list = NULL;
-#endif
dev->ethtool_ops = &netdev_ethtool_ops;
/* note that we haven't actually requested the IRQ from the kernel.
diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c
index 2df3af3b9b20..b61073c42bf8 100644
--- a/drivers/net/3c527.c
+++ b/drivers/net/3c527.c
@@ -288,6 +288,18 @@ struct net_device *__init mc32_probe(int unit)
return ERR_PTR(-ENODEV);
}
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = mc32_open,
+ .ndo_stop = mc32_close,
+ .ndo_start_xmit = mc32_send_packet,
+ .ndo_get_stats = mc32_get_stats,
+ .ndo_set_multicast_list = mc32_set_multicast_list,
+ .ndo_tx_timeout = mc32_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/**
* mc32_probe1 - Check a given slot for a board and test the card
* @dev: Device structure to fill in
@@ -518,12 +530,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
printk("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base);
- dev->open = mc32_open;
- dev->stop = mc32_close;
- dev->hard_start_xmit = mc32_send_packet;
- dev->get_stats = mc32_get_stats;
- dev->set_multicast_list = mc32_set_multicast_list;
- dev->tx_timeout = mc32_timeout;
+ dev->netdev_ops = &netdev_ops;
dev->watchdog_timeo = HZ*5; /* Board does all the work */
dev->ethtool_ops = &netdev_ethtool_ops;
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index cdbbb6226fc5..c56698402420 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -102,8 +102,8 @@ static int vortex_debug = 1;
#include <linux/delay.h>
-static char version[] __devinitdata =
-DRV_NAME ": Donald Becker and others.\n";
+static const char version[] __devinitconst =
+ DRV_NAME ": Donald Becker and others.\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("3Com 3c59x/3c9xx ethernet driver ");
@@ -992,6 +992,42 @@ out:
return rc;
}
+static const struct net_device_ops boomrang_netdev_ops = {
+ .ndo_open = vortex_open,
+ .ndo_stop = vortex_close,
+ .ndo_start_xmit = boomerang_start_xmit,
+ .ndo_tx_timeout = vortex_tx_timeout,
+ .ndo_get_stats = vortex_get_stats,
+#ifdef CONFIG_PCI
+ .ndo_do_ioctl = vortex_ioctl,
+#endif
+ .ndo_set_multicast_list = set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = poll_vortex,
+#endif
+};
+
+static const struct net_device_ops vortex_netdev_ops = {
+ .ndo_open = vortex_open,
+ .ndo_stop = vortex_close,
+ .ndo_start_xmit = vortex_start_xmit,
+ .ndo_tx_timeout = vortex_tx_timeout,
+ .ndo_get_stats = vortex_get_stats,
+#ifdef CONFIG_PCI
+ .ndo_do_ioctl = vortex_ioctl,
+#endif
+ .ndo_set_multicast_list = set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = poll_vortex,
+#endif
+};
+
/*
* Start up the PCI/EISA device which is described by *gendev.
* Return 0 on success.
@@ -1366,18 +1402,16 @@ static int __devinit vortex_probe1(struct device *gendev,
}
/* The 3c59x-specific entries in the device structure. */
- dev->open = vortex_open;
if (vp->full_bus_master_tx) {
- dev->hard_start_xmit = boomerang_start_xmit;
+ dev->netdev_ops = &boomrang_netdev_ops;
/* Actually, it still should work with iommu. */
if (card_idx < MAX_UNITS &&
((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
hw_checksums[card_idx] == 1)) {
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
}
- } else {
- dev->hard_start_xmit = vortex_start_xmit;
- }
+ } else
+ dev->netdev_ops = &vortex_netdev_ops;
if (print_info) {
printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
@@ -1386,18 +1420,9 @@ static int __devinit vortex_probe1(struct device *gendev,
(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
}
- dev->stop = vortex_close;
- dev->get_stats = vortex_get_stats;
-#ifdef CONFIG_PCI
- dev->do_ioctl = vortex_ioctl;
-#endif
dev->ethtool_ops = &vortex_ethtool_ops;
- dev->set_multicast_list = set_rx_mode;
- dev->tx_timeout = vortex_tx_timeout;
dev->watchdog_timeo = (watchdog * HZ) / 1000;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = poll_vortex;
-#endif
+
if (pdev) {
vp->pm_state_valid = 1;
pci_save_state(VORTEX_PCI(vp));
@@ -2883,7 +2908,7 @@ static void vortex_get_drvinfo(struct net_device *dev,
strcpy(info->bus_info, pci_name(VORTEX_PCI(vp)));
} else {
if (VORTEX_EISA(vp))
- sprintf(info->bus_info, dev_name(vp->gendev));
+ strcpy(info->bus_info, dev_name(vp->gendev));
else
sprintf(info->bus_info, "EISA 0x%lx %d",
dev->base_addr, dev->irq);
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 4e19ae3ce6be..a09e3a7cac4f 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -604,7 +604,7 @@ rx_next:
spin_lock_irqsave(&cp->lock, flags);
cpw16_f(IntrMask, cp_intr_mask);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
spin_unlock_irqrestore(&cp->lock, flags);
}
@@ -641,9 +641,9 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
}
if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
- if (netif_rx_schedule_prep(&cp->napi)) {
+ if (napi_schedule_prep(&cp->napi)) {
cpw16_f(IntrMask, cp_norx_intr_mask);
- __netif_rx_schedule(&cp->napi);
+ __napi_schedule(&cp->napi);
}
if (status & (TxOK | TxErr | TxEmpty | SWInt))
@@ -1602,6 +1602,28 @@ static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
return rc;
}
+static int cp_set_mac_address(struct net_device *dev, void *p)
+{
+ struct cp_private *cp = netdev_priv(dev);
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+ spin_lock_irq(&cp->lock);
+
+ cpw8_f(Cfg9346, Cfg9346_Unlock);
+ cpw32_f(MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
+ cpw32_f(MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
+ cpw8_f(Cfg9346, Cfg9346_Lock);
+
+ spin_unlock_irq(&cp->lock);
+
+ return 0;
+}
+
/* Serial EEPROM section. */
/* EEPROM_Ctrl bits. */
@@ -1821,7 +1843,7 @@ static const struct net_device_ops cp_netdev_ops = {
.ndo_open = cp_open,
.ndo_stop = cp_close,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = cp_set_mac_address,
.ndo_set_multicast_list = cp_set_rx_mode,
.ndo_get_stats = cp_get_stats,
.ndo_do_ioctl = cp_ioctl,
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index a5b24202d564..29df398b7727 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -640,6 +640,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb,
#ifdef CONFIG_NET_POLL_CONTROLLER
static void rtl8139_poll_controller(struct net_device *dev);
#endif
+static int rtl8139_set_mac_address(struct net_device *dev, void *p);
static int rtl8139_poll(struct napi_struct *napi, int budget);
static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance);
static int rtl8139_close (struct net_device *dev);
@@ -917,7 +918,7 @@ static const struct net_device_ops rtl8139_netdev_ops = {
.ndo_stop = rtl8139_close,
.ndo_get_stats = rtl8139_get_stats,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = rtl8139_set_mac_address,
.ndo_start_xmit = rtl8139_start_xmit,
.ndo_set_multicast_list = rtl8139_set_rx_mode,
.ndo_do_ioctl = netdev_ioctl,
@@ -2128,7 +2129,7 @@ static int rtl8139_poll(struct napi_struct *napi, int budget)
*/
spin_lock_irqsave(&tp->lock, flags);
RTL_W16_F(IntrMask, rtl8139_intr_mask);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
spin_unlock_irqrestore(&tp->lock, flags);
}
spin_unlock(&tp->rx_lock);
@@ -2178,9 +2179,9 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
/* Receive packets are processed by poll routine.
If not running start it now. */
if (status & RxAckBits){
- if (netif_rx_schedule_prep(&tp->napi)) {
+ if (napi_schedule_prep(&tp->napi)) {
RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
- __netif_rx_schedule(&tp->napi);
+ __napi_schedule(&tp->napi);
}
}
@@ -2215,6 +2216,29 @@ static void rtl8139_poll_controller(struct net_device *dev)
}
#endif
+static int rtl8139_set_mac_address(struct net_device *dev, void *p)
+{
+ struct rtl8139_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->mmio_addr;
+ struct sockaddr *addr = p;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+ spin_lock_irq(&tp->lock);
+
+ RTL_W8_F(Cfg9346, Cfg9346_Unlock);
+ RTL_W32_F(MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
+ RTL_W32_F(MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
+ RTL_W8_F(Cfg9346, Cfg9346_Lock);
+
+ spin_unlock_irq(&tp->lock);
+
+ return 0;
+}
+
static int rtl8139_close (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index b273596368e3..cca94b9c08ae 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -1122,6 +1122,17 @@ static void print_eth(unsigned char *add, char *str)
static int io = 0x300;
static int irq = 10;
+static const struct net_device_ops i596_netdev_ops = {
+ .ndo_open = i596_open,
+ .ndo_stop = i596_close,
+ .ndo_start_xmit = i596_start_xmit,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_tx_timeout = i596_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
struct net_device * __init i82596_probe(int unit)
{
struct net_device *dev;
@@ -1232,11 +1243,7 @@ found:
DEB(DEB_PROBE,printk(KERN_INFO "%s", version));
/* The 82596-specific entries in the device structure. */
- dev->open = i596_open;
- dev->stop = i596_close;
- dev->hard_start_xmit = i596_start_xmit;
- dev->set_multicast_list = set_multicast_list;
- dev->tx_timeout = i596_tx_timeout;
+ dev->netdev_ops = &i596_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
dev->ml_priv = (void *)(dev->mem_start);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 435e2e3a82c8..16899eee397e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -26,6 +26,15 @@ menuconfig NETDEVICES
# that for each of the symbols.
if NETDEVICES
+config COMPAT_NET_DEV_OPS
+ default y
+ bool "Enable older network device API compatiablity"
+ ---help---
+ This option enables kernel compatiability with older network devices
+ that do not use net_device_ops interface.
+
+ If unsure, say Y.
+
config IFB
tristate "Intermediate Functional Block support"
depends on NET_CLS_ACT
@@ -963,6 +972,14 @@ config ENC28J60_WRITEVERIFY
Enable the verify after the buffer write useful for debugging purpose.
If unsure, say N.
+config ETHOC
+ tristate "OpenCores 10/100 Mbps Ethernet MAC support"
+ depends on NET_ETHERNET && HAS_IOMEM
+ select MII
+ select PHYLIB
+ help
+ Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC.
+
config SMC911X
tristate "SMSC LAN911[5678] support"
select CRC32
@@ -1042,7 +1059,7 @@ config NI65
config DNET
tristate "Dave ethernet support (DNET)"
- depends on NET_ETHERNET
+ depends on NET_ETHERNET && HAS_IOMEM
select PHYLIB
help
The Dave ethernet interface (DNET) is found on Qong Board FPGA.
@@ -1840,10 +1857,10 @@ config 68360_ENET
config FEC
bool "FEC ethernet controller (of ColdFire CPUs)"
- depends on M523x || M527x || M5272 || M528x || M520x || M532x
+ depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27
help
Say Y here if you want to use the built-in 10/100 Fast ethernet
- controller on some Motorola ColdFire processors.
+ controller on some Motorola ColdFire and Freescale i.MX processors.
config FEC2
bool "Second FEC ethernet controller (on some ColdFire CPUs)"
@@ -2030,15 +2047,6 @@ config IGB
To compile this driver as a module, choose M here. The module
will be called igb.
-config IGB_LRO
- bool "Use software LRO"
- depends on IGB && INET
- select INET_LRO
- ---help---
- Say Y here if you want to use large receive offload.
-
- If in doubt, say N.
-
config IGB_DCA
bool "Direct Cache Access (DCA) Support"
default y
@@ -2284,9 +2292,17 @@ config GELIC_WIRELESS_OLD_PSK_INTERFACE
If unsure, say N.
+config FSL_PQ_MDIO
+ tristate "Freescale PQ MDIO"
+ depends on FSL_SOC
+ select PHYLIB
+ help
+ This driver supports the MDIO bus used by the gianfar and UCC drivers.
+
config GIANFAR
tristate "Gianfar Ethernet"
depends on FSL_SOC
+ select FSL_PQ_MDIO
select PHYLIB
select CRC32
help
@@ -2296,6 +2312,7 @@ config GIANFAR
config UCC_GETH
tristate "Freescale QE Gigabit Ethernet"
depends on QUICC_ENGINE
+ select FSL_PQ_MDIO
select PHYLIB
help
This driver supports the Gigabit Ethernet mode of the QUICC Engine,
@@ -2312,6 +2329,7 @@ config UGETH_TX_ON_DEMAND
config MV643XX_ETH
tristate "Marvell Discovery (643XX) and Orion ethernet support"
depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || PLAT_ORION
+ select INET_LRO
select PHYLIB
help
This driver supports the gigabit ethernet MACs in the
@@ -2430,7 +2448,6 @@ config CHELSIO_T3
tristate "Chelsio Communications T3 10Gb Ethernet support"
depends on CHELSIO_T3_DEPENDS
select FW_LOADER
- select INET_LRO
help
This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
adapters.
@@ -2466,7 +2483,6 @@ config ENIC
config IXGBE
tristate "Intel(R) 10GbE PCI Express adapters support"
depends on PCI && INET
- select INET_LRO
---help---
This driver supports Intel(R) 10GbE PCI Express family of
adapters. For more information on how to identify your adapter, go
@@ -2531,6 +2547,23 @@ config S2IO
More specific information on configuring the driver is in
<file:Documentation/networking/s2io.txt>.
+config VXGE
+ tristate "Neterion X3100 Series 10GbE PCIe Server Adapter"
+ depends on PCI && INET
+ ---help---
+ This driver supports Neterion Inc's X3100 Series 10 GbE PCIe
+ I/O Virtualized Server Adapter.
+ More specific information on configuring the driver is in
+ <file:Documentation/networking/vxge.txt>.
+
+config VXGE_DEBUG_TRACE_ALL
+ bool "Enabling All Debug trace statments in driver"
+ default n
+ depends on VXGE
+ ---help---
+ Say Y here if you want to enabling all the debug trace statements in
+ driver. By default only few debug trace statements are enabled.
+
config MYRI10GE
tristate "Myricom Myri-10G Ethernet support"
depends on PCI && INET
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 471baaff229f..edc9a0d6171d 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -26,11 +26,12 @@ obj-$(CONFIG_BE2NET) += benet/
gianfar_driver-objs := gianfar.o \
gianfar_ethtool.o \
- gianfar_mii.o \
gianfar_sysfs.o
obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
-ucc_geth_driver-objs := ucc_geth.o ucc_geth_mii.o ucc_geth_ethtool.o
+ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
+
+obj-$(CONFIG_FSL_PQ_MDIO) += fsl_pq_mdio.o
#
# link order important here
@@ -219,6 +220,7 @@ obj-$(CONFIG_R8169) += r8169.o
obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
obj-$(CONFIG_IBMVETH) += ibmveth.o
obj-$(CONFIG_S2IO) += s2io.o
+obj-$(CONFIG_VXGE) += vxge/
obj-$(CONFIG_MYRI10GE) += myri10ge/
obj-$(CONFIG_SMC91X) += smc91x.o
obj-$(CONFIG_SMC911X) += smc911x.o
@@ -229,6 +231,7 @@ obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o
pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o
obj-$(CONFIG_MLX4_CORE) += mlx4/
obj-$(CONFIG_ENC28J60) += enc28j60.o
+obj-$(CONFIG_ETHOC) += ethoc.o
obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
index 7a60bdd9a242..d0d0c2fee054 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/a2065.c
@@ -552,18 +552,13 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
struct lance_private *lp = netdev_priv(dev);
volatile struct lance_regs *ll = lp->ll;
volatile struct lance_init_block *ib = lp->init_block;
- int entry, skblen, len;
+ int entry, skblen;
int status = 0;
unsigned long flags;
- skblen = skb->len;
- len = skblen;
-
- if (len < ETH_ZLEN) {
- len = ETH_ZLEN;
- if (skb_padto(skb, ETH_ZLEN))
- return 0;
- }
+ if (skb_padto(skb, ETH_ZLEN))
+ return 0;
+ skblen = max_t(unsigned, skb->len, ETH_ZLEN);
local_irq_save(flags);
@@ -586,15 +581,11 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
}
#endif
entry = lp->tx_new & lp->tx_ring_mod_mask;
- ib->btx_ring [entry].length = (-len) | 0xf000;
+ ib->btx_ring [entry].length = (-skblen) | 0xf000;
ib->btx_ring [entry].misc = 0;
skb_copy_from_linear_data(skb, (void *)&ib->tx_buf [entry][0], skblen);
- /* Clear the slack of the packet, do I need this? */
- if (len != skblen)
- memset ((void *) &ib->tx_buf [entry][skblen], 0, len - skblen);
-
/* Now, give the packet to the lance */
ib->btx_ring [entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN);
lp->tx_new = (lp->tx_new+1) & lp->tx_ring_mod_mask;
diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c
index 071a851a2ea1..eac73382c087 100644
--- a/drivers/net/ac3200.c
+++ b/drivers/net/ac3200.c
@@ -143,6 +143,22 @@ out:
}
#endif
+static const struct net_device_ops ac_netdev_ops = {
+ .ndo_open = ac_open,
+ .ndo_stop = ac_close_card,
+
+ .ndo_start_xmit = ei_start_xmit,
+ .ndo_tx_timeout = ei_tx_timeout,
+ .ndo_get_stats = ei_get_stats,
+ .ndo_set_multicast_list = ei_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ei_poll,
+#endif
+};
+
static int __init ac_probe1(int ioaddr, struct net_device *dev)
{
int i, retval;
@@ -253,11 +269,7 @@ static int __init ac_probe1(int ioaddr, struct net_device *dev)
ei_status.block_output = &ac_block_output;
ei_status.get_8390_hdr = &ac_get_8390_hdr;
- dev->open = &ac_open;
- dev->stop = &ac_close_card;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
-#endif
+ dev->netdev_ops = &ac_netdev_ops;
NS8390_init(dev, 0);
retval = register_netdev(dev);
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 9589d620639d..06a9f11669f3 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -437,7 +437,7 @@ MODULE_PARM_DESC(max_rx_desc, "AceNIC/3C985/GA620 max number of receive descript
MODULE_PARM_DESC(tx_ratio, "AceNIC/3C985/GA620 ratio of NIC memory used for TX/RX descriptors (range 0-63)");
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
"acenic.c: v0.92 08/05/2002 Jes Sorensen, linux-acenic@SunSITE.dk\n"
" http://home.cern.ch/~jes/gige/acenic.html\n";
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 7709992bb6bf..cb9c95d3ed0a 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -831,7 +831,7 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
if (rx_pkt_limit > 0) {
/* Receive descriptor is empty now */
spin_lock_irqsave(&lp->lock, flags);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
writel(VAL0|RINTEN0, mmio + INTEN0);
writel(VAL2 | RDMD0, mmio + CMD0);
spin_unlock_irqrestore(&lp->lock, flags);
@@ -1170,11 +1170,11 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id)
/* Check if Receive Interrupt has occurred. */
if (intr0 & RINT0) {
- if (netif_rx_schedule_prep(&lp->napi)) {
+ if (napi_schedule_prep(&lp->napi)) {
/* Disable receive interupts */
writel(RINTEN0, mmio + INTEN0);
/* Schedule a polling routine */
- __netif_rx_schedule(&lp->napi);
+ __napi_schedule(&lp->napi);
} else if (intren0 & RINTEN0) {
printk("************Driver bug! \
interrupt while in poll\n");
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index 54819a34ba0a..7f8325419803 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -171,7 +171,6 @@ static unsigned int cops_debug = COPS_DEBUG;
struct cops_local
{
- struct net_device_stats stats;
int board; /* Holds what board type is. */
int nodeid; /* Set to 1 once have nodeid. */
unsigned char node_acquire; /* Node ID when acquired. */
@@ -197,7 +196,6 @@ static int cops_send_packet (struct sk_buff *skb, struct net_device *dev);
static void set_multicast_list (struct net_device *dev);
static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static int cops_close (struct net_device *dev);
-static struct net_device_stats *cops_get_stats (struct net_device *dev);
static void cleanup_card(struct net_device *dev)
{
@@ -260,6 +258,15 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops cops_netdev_ops = {
+ .ndo_open = cops_open,
+ .ndo_stop = cops_close,
+ .ndo_start_xmit = cops_send_packet,
+ .ndo_tx_timeout = cops_timeout,
+ .ndo_do_ioctl = cops_ioctl,
+ .ndo_set_multicast_list = set_multicast_list,
+};
+
/*
* This is the real probe routine. Linux has a history of friendly device
* probes on the ISA bus. A good device probes avoids doing writes, and
@@ -333,16 +340,9 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr)
/* Copy local board variable to lp struct. */
lp->board = board;
- dev->hard_start_xmit = cops_send_packet;
- dev->tx_timeout = cops_timeout;
+ dev->netdev_ops = &cops_netdev_ops;
dev->watchdog_timeo = HZ * 2;
- dev->get_stats = cops_get_stats;
- dev->open = cops_open;
- dev->stop = cops_close;
- dev->do_ioctl = cops_ioctl;
- dev->set_multicast_list = set_multicast_list;
- dev->mc_list = NULL;
/* Tell the user where the card is and what mode we're in. */
if(board==DAYNA)
@@ -797,7 +797,7 @@ static void cops_rx(struct net_device *dev)
{
printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n",
dev->name);
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
while(pkt_len--) /* Discard packet */
inb(ioaddr);
spin_unlock_irqrestore(&lp->lock, flags);
@@ -819,7 +819,7 @@ static void cops_rx(struct net_device *dev)
{
printk(KERN_WARNING "%s: Bad packet length of %d bytes.\n",
dev->name, pkt_len);
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb_any(skb);
return;
}
@@ -836,7 +836,7 @@ static void cops_rx(struct net_device *dev)
if(rsp_type != LAP_RESPONSE)
{
printk(KERN_WARNING "%s: Bad packet type %d.\n", dev->name, rsp_type);
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
dev_kfree_skb_any(skb);
return;
}
@@ -846,8 +846,8 @@ static void cops_rx(struct net_device *dev)
skb_reset_transport_header(skb); /* Point to data (Skip header). */
/* Update the counters. */
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
/* Send packet to a higher place. */
netif_rx(skb);
@@ -858,7 +858,7 @@ static void cops_timeout(struct net_device *dev)
struct cops_local *lp = netdev_priv(dev);
int ioaddr = dev->base_addr;
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
if(lp->board==TANGENT)
{
if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
@@ -916,8 +916,8 @@ static int cops_send_packet(struct sk_buff *skb, struct net_device *dev)
spin_unlock_irqrestore(&lp->lock, flags); /* Restore interrupts. */
/* Done sending packet, update counters and cleanup. */
- lp->stats.tx_packets++;
- lp->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
dev->trans_start = jiffies;
dev_kfree_skb (skb);
return 0;
@@ -986,15 +986,6 @@ static int cops_close(struct net_device *dev)
return 0;
}
-/*
- * Get the current statistics.
- * This may be called with the card open or closed.
- */
-static struct net_device_stats *cops_get_stats(struct net_device *dev)
-{
- struct cops_local *lp = netdev_priv(dev);
- return &lp->stats;
-}
#ifdef MODULE
static struct net_device *cops_dev;
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index dc4d49605603..78cc71469136 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -261,7 +261,6 @@ static unsigned char *ltdmacbuf;
struct ltpc_private
{
- struct net_device_stats stats;
struct atalk_addr my_addr;
};
@@ -699,7 +698,6 @@ static int do_read(struct net_device *dev, void *cbuf, int cbuflen,
static struct timer_list ltpc_timer;
static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *ltpc_get_stats(struct net_device *dev);
static int read_30 ( struct net_device *dev)
{
@@ -726,8 +724,6 @@ static int sendup_buffer (struct net_device *dev)
int dnode, snode, llaptype, len;
int sklen;
struct sk_buff *skb;
- struct ltpc_private *ltpc_priv = netdev_priv(dev);
- struct net_device_stats *stats = &ltpc_priv->stats;
struct lt_rcvlap *ltc = (struct lt_rcvlap *) ltdmacbuf;
if (ltc->command != LT_RCVLAP) {
@@ -779,8 +775,8 @@ static int sendup_buffer (struct net_device *dev)
skb_reset_transport_header(skb);
- stats->rx_packets++;
- stats->rx_bytes+=skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
/* toss it onwards */
netif_rx(skb);
@@ -904,10 +900,6 @@ static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev)
/* in kernel 1.3.xx, on entry skb->data points to ddp header,
* and skb->len is the length of the ddp data + ddp header
*/
-
- struct ltpc_private *ltpc_priv = netdev_priv(dev);
- struct net_device_stats *stats = &ltpc_priv->stats;
-
int i;
struct lt_sendlap cbuf;
unsigned char *hdr;
@@ -936,20 +928,13 @@ static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev)
printk("\n");
}
- stats->tx_packets++;
- stats->tx_bytes+=skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
dev_kfree_skb(skb);
return 0;
}
-static struct net_device_stats *ltpc_get_stats(struct net_device *dev)
-{
- struct ltpc_private *ltpc_priv = netdev_priv(dev);
- struct net_device_stats *stats = &ltpc_priv->stats;
- return stats;
-}
-
/* initialization stuff */
static int __init ltpc_probe_dma(int base, int dma)
@@ -1027,6 +1012,12 @@ static int __init ltpc_probe_dma(int base, int dma)
return (want & 2) ? 3 : 1;
}
+static const struct net_device_ops ltpc_netdev = {
+ .ndo_start_xmit = ltpc_xmit,
+ .ndo_do_ioctl = ltpc_ioctl,
+ .ndo_set_multicast_list = set_multicast_list,
+};
+
struct net_device * __init ltpc_probe(void)
{
struct net_device *dev;
@@ -1133,14 +1124,7 @@ struct net_device * __init ltpc_probe(void)
else
printk(KERN_INFO "Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma);
- /* Fill in the fields of the device structure with ethernet-generic values. */
- dev->hard_start_xmit = ltpc_xmit;
- dev->get_stats = ltpc_get_stats;
-
- /* add the ltpc-specific things */
- dev->do_ioctl = &ltpc_ioctl;
-
- dev->set_multicast_list = &set_multicast_list;
+ dev->netdev_ops = &ltpc_netdev;
dev->mc_list = NULL;
dev->base_addr = io;
dev->irq = irq;
diff --git a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c
index 3ff9affb1a91..646dfc5f50c9 100644
--- a/drivers/net/arcnet/arc-rawmode.c
+++ b/drivers/net/arcnet/arc-rawmode.c
@@ -102,7 +102,7 @@ static void rx(struct net_device *dev, int bufnum,
skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
if (skb == NULL) {
BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_put(skb, length + ARC_HDR_SIZE);
@@ -122,7 +122,7 @@ static void rx(struct net_device *dev, int bufnum,
BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
- skb->protocol = __constant_htons(ETH_P_ARCNET);
+ skb->protocol = cpu_to_be16(ETH_P_ARCNET);
;
netif_rx(skb);
}
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index 6b53e5ed125c..d6d4ab3b430c 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -95,17 +95,16 @@ EXPORT_SYMBOL(arcnet_unregister_proto);
EXPORT_SYMBOL(arcnet_debug);
EXPORT_SYMBOL(alloc_arcdev);
EXPORT_SYMBOL(arcnet_interrupt);
+EXPORT_SYMBOL(arcnet_open);
+EXPORT_SYMBOL(arcnet_close);
+EXPORT_SYMBOL(arcnet_send_packet);
+EXPORT_SYMBOL(arcnet_timeout);
/* Internal function prototypes */
-static int arcnet_open(struct net_device *dev);
-static int arcnet_close(struct net_device *dev);
-static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev);
-static void arcnet_timeout(struct net_device *dev);
static int arcnet_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, const void *daddr,
const void *saddr, unsigned len);
static int arcnet_rebuild_header(struct sk_buff *skb);
-static struct net_device_stats *arcnet_get_stats(struct net_device *dev);
static int go_tx(struct net_device *dev);
static int debug = ARCNET_DEBUG;
@@ -322,11 +321,18 @@ static const struct header_ops arcnet_header_ops = {
.rebuild = arcnet_rebuild_header,
};
+static const struct net_device_ops arcnet_netdev_ops = {
+ .ndo_open = arcnet_open,
+ .ndo_stop = arcnet_close,
+ .ndo_start_xmit = arcnet_send_packet,
+ .ndo_tx_timeout = arcnet_timeout,
+};
/* Setup a struct device for ARCnet. */
static void arcdev_setup(struct net_device *dev)
{
dev->type = ARPHRD_ARCNET;
+ dev->netdev_ops = &arcnet_netdev_ops;
dev->header_ops = &arcnet_header_ops;
dev->hard_header_len = sizeof(struct archdr);
dev->mtu = choose_mtu();
@@ -339,18 +345,9 @@ static void arcdev_setup(struct net_device *dev)
/* New-style flags. */
dev->flags = IFF_BROADCAST;
- /*
- * Put in this stuff here, so we don't have to export the symbols to
- * the chipset drivers.
- */
- dev->open = arcnet_open;
- dev->stop = arcnet_close;
- dev->hard_start_xmit = arcnet_send_packet;
- dev->tx_timeout = arcnet_timeout;
- dev->get_stats = arcnet_get_stats;
}
-struct net_device *alloc_arcdev(char *name)
+struct net_device *alloc_arcdev(const char *name)
{
struct net_device *dev;
@@ -372,7 +369,7 @@ struct net_device *alloc_arcdev(char *name)
* that "should" only need to be set once at boot, so that there is
* non-reboot way to recover if something goes wrong.
*/
-static int arcnet_open(struct net_device *dev)
+int arcnet_open(struct net_device *dev)
{
struct arcnet_local *lp = netdev_priv(dev);
int count, newmtu, error;
@@ -383,7 +380,6 @@ static int arcnet_open(struct net_device *dev)
return -ENODEV;
BUGLVL(D_PROTO) {
- int count;
BUGMSG(D_PROTO, "protocol map (default is '%c'): ",
arc_proto_default->suffix);
for (count = 0; count < 256; count++)
@@ -472,7 +468,7 @@ static int arcnet_open(struct net_device *dev)
/* The inverse routine to arcnet_open - shuts down the card. */
-static int arcnet_close(struct net_device *dev)
+int arcnet_close(struct net_device *dev)
{
struct arcnet_local *lp = netdev_priv(dev);
@@ -583,8 +579,8 @@ static int arcnet_rebuild_header(struct sk_buff *skb)
} else {
BUGMSG(D_NORMAL,
"I don't understand ethernet protocol %Xh addresses!\n", type);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
}
/* if we couldn't resolve the address... give up. */
@@ -601,7 +597,7 @@ static int arcnet_rebuild_header(struct sk_buff *skb)
/* Called by the kernel in order to transmit a packet. */
-static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
+int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
{
struct arcnet_local *lp = netdev_priv(dev);
struct archdr *pkt;
@@ -645,7 +641,7 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
!proto->ack_tx) {
/* done right away and we don't want to acknowledge
the package later - forget about it now */
- lp->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
freeskb = 1;
} else {
/* do it the 'split' way */
@@ -709,7 +705,7 @@ static int go_tx(struct net_device *dev)
/* start sending */
ACOMMAND(TXcmd | (lp->cur_tx << 3));
- lp->stats.tx_packets++;
+ dev->stats.tx_packets++;
lp->lasttrans_dest = lp->lastload_dest;
lp->lastload_dest = 0;
lp->excnak_pending = 0;
@@ -720,7 +716,7 @@ static int go_tx(struct net_device *dev)
/* Called by the kernel when transmit times out */
-static void arcnet_timeout(struct net_device *dev)
+void arcnet_timeout(struct net_device *dev)
{
unsigned long flags;
struct arcnet_local *lp = netdev_priv(dev);
@@ -732,11 +728,11 @@ static void arcnet_timeout(struct net_device *dev)
msg = " - missed IRQ?";
} else {
msg = "";
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
lp->timed_out = 1;
ACOMMAND(NOTXcmd | (lp->cur_tx << 3));
}
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
/* make sure we didn't miss a TX or a EXC NAK IRQ */
AINTMASK(0);
@@ -865,8 +861,8 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
"transmit was not acknowledged! "
"(status=%Xh, dest=%02Xh)\n",
status, lp->lasttrans_dest);
- lp->stats.tx_errors++;
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_carrier_errors++;
} else {
BUGMSG(D_DURING,
"broadcast was not acknowledged; that's normal "
@@ -905,7 +901,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
if (txbuf != -1) {
if (lp->outgoing.proto->continue_tx(dev, txbuf)) {
/* that was the last segment */
- lp->stats.tx_bytes += lp->outgoing.skb->len;
+ dev->stats.tx_bytes += lp->outgoing.skb->len;
if(!lp->outgoing.proto->ack_tx)
{
dev_kfree_skb_irq(lp->outgoing.skb);
@@ -930,7 +926,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
}
if (status & lp->intmask & RECONflag) {
ACOMMAND(CFLAGScmd | CONFIGclear);
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n",
status);
@@ -1038,8 +1034,8 @@ static void arcnet_rx(struct net_device *dev, int bufnum)
"(%d+4 bytes)\n",
bufnum, pkt.hard.source, pkt.hard.dest, length);
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += length + ARC_HDR_SIZE;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += length + ARC_HDR_SIZE;
/* call the right receiver for the protocol */
if (arc_proto_map[soft->proto]->is_ip) {
@@ -1067,18 +1063,6 @@ static void arcnet_rx(struct net_device *dev, int bufnum)
}
-
-/*
- * Get the current statistics. This may be called with the card open or
- * closed.
- */
-static struct net_device_stats *arcnet_get_stats(struct net_device *dev)
-{
- struct arcnet_local *lp = netdev_priv(dev);
- return &lp->stats;
-}
-
-
static void null_rx(struct net_device *dev, int bufnum,
struct archdr *pkthdr, int length)
{
diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c
index 30580bbe252d..083e21094b20 100644
--- a/drivers/net/arcnet/capmode.c
+++ b/drivers/net/arcnet/capmode.c
@@ -119,7 +119,7 @@ static void rx(struct net_device *dev, int bufnum,
skb = alloc_skb(length + ARC_HDR_SIZE + sizeof(int), GFP_ATOMIC);
if (skb == NULL) {
BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_put(skb, length + ARC_HDR_SIZE + sizeof(int));
@@ -148,7 +148,7 @@ static void rx(struct net_device *dev, int bufnum,
BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
- skb->protocol = __constant_htons(ETH_P_ARCNET);
+ skb->protocol = cpu_to_be16(ETH_P_ARCNET);
;
netif_rx(skb);
}
@@ -282,7 +282,7 @@ static int ack_tx(struct net_device *dev, int acked)
BUGMSG(D_PROTO, "Ackknowledge for cap packet %x.\n",
*((int*)&ackpkt->soft.cap.cookie[0]));
- ackskb->protocol = __constant_htons(ETH_P_ARCNET);
+ ackskb->protocol = cpu_to_be16(ETH_P_ARCNET);
BUGLVL(D_SKB) arcnet_dump_skb(dev, ackskb, "ack_tx_recv");
netif_rx(ackskb);
diff --git a/drivers/net/arcnet/com20020-isa.c b/drivers/net/arcnet/com20020-isa.c
index ea53a940272f..db08fc24047a 100644
--- a/drivers/net/arcnet/com20020-isa.c
+++ b/drivers/net/arcnet/com20020-isa.c
@@ -151,6 +151,8 @@ static int __init com20020_init(void)
if (node && node != 0xff)
dev->dev_addr[0] = node;
+ dev->netdev_ops = &com20020_netdev_ops;
+
lp = netdev_priv(dev);
lp->backplane = backplane;
lp->clockp = clockp & 7;
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index 8b51f632581d..dbf4de39754d 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -72,6 +72,9 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
dev = alloc_arcdev(device);
if (!dev)
return -ENOMEM;
+
+ dev->netdev_ops = &com20020_netdev_ops;
+
lp = netdev_priv(dev);
pci_set_drvdata(pdev, dev);
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index 103688358fb8..651275a5f3d2 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -149,6 +149,14 @@ int com20020_check(struct net_device *dev)
return 0;
}
+const struct net_device_ops com20020_netdev_ops = {
+ .ndo_open = arcnet_open,
+ .ndo_stop = arcnet_close,
+ .ndo_start_xmit = arcnet_send_packet,
+ .ndo_tx_timeout = arcnet_timeout,
+ .ndo_set_multicast_list = com20020_set_mc_list,
+};
+
/* Set up the struct net_device associated with this card. Called after
* probing succeeds.
*/
@@ -170,8 +178,6 @@ int com20020_found(struct net_device *dev, int shared)
lp->hw.copy_from_card = com20020_copy_from_card;
lp->hw.close = com20020_close;
- dev->set_multicast_list = com20020_set_mc_list;
-
if (!dev->dev_addr[0])
dev->dev_addr[0] = inb(ioaddr + BUS_ALIGN*8); /* FIXME: do this some other way! */
@@ -342,6 +348,7 @@ static void com20020_set_mc_list(struct net_device *dev)
defined(CONFIG_ARCNET_COM20020_CS_MODULE)
EXPORT_SYMBOL(com20020_check);
EXPORT_SYMBOL(com20020_found);
+EXPORT_SYMBOL(com20020_netdev_ops);
#endif
MODULE_LICENSE("GPL");
diff --git a/drivers/net/arcnet/rfc1051.c b/drivers/net/arcnet/rfc1051.c
index 49d39a9cb696..06f8fa2f8f2f 100644
--- a/drivers/net/arcnet/rfc1051.c
+++ b/drivers/net/arcnet/rfc1051.c
@@ -88,7 +88,6 @@ MODULE_LICENSE("GPL");
*/
static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
{
- struct arcnet_local *lp = netdev_priv(dev);
struct archdr *pkt = (struct archdr *) skb->data;
struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
@@ -112,8 +111,8 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
return htons(ETH_P_ARP);
default:
- lp->stats.rx_errors++;
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_crc_errors++;
return 0;
}
@@ -140,7 +139,7 @@ static void rx(struct net_device *dev, int bufnum,
skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
if (skb == NULL) {
BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_put(skb, length + ARC_HDR_SIZE);
@@ -168,7 +167,6 @@ static void rx(struct net_device *dev, int bufnum,
static int build_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, uint8_t daddr)
{
- struct arcnet_local *lp = netdev_priv(dev);
int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
@@ -184,8 +182,8 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
default:
BUGMSG(D_NORMAL, "RFC1051: I don't understand protocol %d (%Xh)\n",
type, type);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
return 0;
}
diff --git a/drivers/net/arcnet/rfc1201.c b/drivers/net/arcnet/rfc1201.c
index 2303d3a1f4b6..745530651c45 100644
--- a/drivers/net/arcnet/rfc1201.c
+++ b/drivers/net/arcnet/rfc1201.c
@@ -92,7 +92,6 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
{
struct archdr *pkt = (struct archdr *) skb->data;
struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
- struct arcnet_local *lp = netdev_priv(dev);
int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
/* Pull off the arcnet header. */
@@ -121,8 +120,8 @@ static __be16 type_trans(struct sk_buff *skb, struct net_device *dev)
case ARC_P_NOVELL_EC:
return htons(ETH_P_802_3);
default:
- lp->stats.rx_errors++;
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_crc_errors++;
return 0;
}
@@ -172,8 +171,8 @@ static void rx(struct net_device *dev, int bufnum,
in->sequence, soft->split_flag, soft->sequence);
lp->rfc1201.aborted_seq = soft->sequence;
dev_kfree_skb_irq(in->skb);
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
in->skb = NULL;
}
in->sequence = soft->sequence;
@@ -181,7 +180,7 @@ static void rx(struct net_device *dev, int bufnum,
skb = alloc_skb(length + ARC_HDR_SIZE, GFP_ATOMIC);
if (skb == NULL) {
BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n");
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_put(skb, length + ARC_HDR_SIZE);
@@ -213,7 +212,7 @@ static void rx(struct net_device *dev, int bufnum,
BUGMSG(D_EXTRA,
"ARP source address was 00h, set to %02Xh.\n",
saddr);
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
*cptr = saddr;
} else {
BUGMSG(D_DURING, "ARP source address (%Xh) is fine.\n",
@@ -222,8 +221,8 @@ static void rx(struct net_device *dev, int bufnum,
} else {
BUGMSG(D_NORMAL, "funny-shaped ARP packet. (%Xh, %Xh)\n",
arp->ar_hln, arp->ar_pln);
- lp->stats.rx_errors++;
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_crc_errors++;
}
}
BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx");
@@ -257,8 +256,8 @@ static void rx(struct net_device *dev, int bufnum,
soft->split_flag);
dev_kfree_skb_irq(in->skb);
in->skb = NULL;
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
in->lastpacket = in->numpackets = 0;
}
if (soft->split_flag & 1) { /* first packet in split */
@@ -269,8 +268,8 @@ static void rx(struct net_device *dev, int bufnum,
"(splitflag=%d, seq=%d)\n",
in->sequence, soft->split_flag,
soft->sequence);
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
dev_kfree_skb_irq(in->skb);
}
in->sequence = soft->sequence;
@@ -281,8 +280,8 @@ static void rx(struct net_device *dev, int bufnum,
BUGMSG(D_EXTRA, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n",
soft->split_flag);
lp->rfc1201.aborted_seq = soft->sequence;
- lp->stats.rx_errors++;
- lp->stats.rx_length_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_length_errors++;
return;
}
in->skb = skb = alloc_skb(508 * in->numpackets + ARC_HDR_SIZE,
@@ -290,7 +289,7 @@ static void rx(struct net_device *dev, int bufnum,
if (skb == NULL) {
BUGMSG(D_NORMAL, "(split) memory squeeze, dropping packet.\n");
lp->rfc1201.aborted_seq = soft->sequence;
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb->dev = dev;
@@ -314,8 +313,8 @@ static void rx(struct net_device *dev, int bufnum,
"first! (splitflag=%d, seq=%d, aborted=%d)\n",
soft->split_flag, soft->sequence,
lp->rfc1201.aborted_seq);
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
}
return;
}
@@ -325,8 +324,8 @@ static void rx(struct net_device *dev, int bufnum,
if (packetnum <= in->lastpacket - 1) {
BUGMSG(D_EXTRA, "duplicate splitpacket ignored! (splitflag=%d)\n",
soft->split_flag);
- lp->stats.rx_errors++;
- lp->stats.rx_frame_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_frame_errors++;
return;
}
/* "bad" duplicate, kill reassembly */
@@ -336,8 +335,8 @@ static void rx(struct net_device *dev, int bufnum,
lp->rfc1201.aborted_seq = soft->sequence;
dev_kfree_skb_irq(in->skb);
in->skb = NULL;
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_missed_errors++;
in->lastpacket = in->numpackets = 0;
return;
}
@@ -404,8 +403,8 @@ static int build_header(struct sk_buff *skb, struct net_device *dev,
default:
BUGMSG(D_NORMAL, "RFC1201: I don't understand protocol %d (%Xh)\n",
type, type);
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_errors++;
+ dev->stats.tx_aborted_errors++;
return 0;
}
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index c2d012fcc29b..4bc6901b3819 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -27,9 +27,9 @@
#include <linux/crc32.h>
#include <linux/bitops.h>
#include <linux/platform_device.h>
+#include <linux/io.h>
#include <mach/hardware.h>
-#include <asm/io.h>
#include <asm/system.h>
#define TX_BUFFERS 15
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index 3ec20cc18b0c..cc7708775da0 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -298,7 +298,7 @@ poll_some_more:
int more = 0;
spin_lock_irq(&ep->rx_lock);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
wrl(ep, REG_INTEN, REG_INTEN_TX | REG_INTEN_RX);
if (ep93xx_have_more_rx(ep)) {
wrl(ep, REG_INTEN, REG_INTEN_TX);
@@ -307,7 +307,7 @@ poll_some_more:
}
spin_unlock_irq(&ep->rx_lock);
- if (more && netif_rx_reschedule(napi))
+ if (more && napi_reschedule(napi))
goto poll_some_more;
}
@@ -415,9 +415,9 @@ static irqreturn_t ep93xx_irq(int irq, void *dev_id)
if (status & REG_INTSTS_RX) {
spin_lock(&ep->rx_lock);
- if (likely(netif_rx_schedule_prep(&ep->napi))) {
+ if (likely(napi_schedule_prep(&ep->napi))) {
wrl(ep, REG_INTEN, REG_INTEN_TX);
- __netif_rx_schedule(&ep->napi);
+ __napi_schedule(&ep->napi);
}
spin_unlock(&ep->rx_lock);
}
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index 5fce1d5c1a1a..448487e22fa3 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -335,11 +335,20 @@ static int ixp4xx_mdio_register(void)
if (!(mdio_bus = mdiobus_alloc()))
return -ENOMEM;
- /* All MII PHY accesses use NPE-B Ethernet registers */
- spin_lock_init(&mdio_lock);
- mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT;
- __raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control);
+ if (cpu_is_ixp43x()) {
+ /* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */
+ if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH))
+ return -ENOSYS;
+ mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT;
+ } else {
+ /* All MII PHY accesses use NPE-B Ethernet registers */
+ if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0))
+ return -ENOSYS;
+ mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT;
+ }
+ __raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control);
+ spin_lock_init(&mdio_lock);
mdio_bus->name = "IXP4xx MII Bus";
mdio_bus->read = &ixp4xx_mdio_read;
mdio_bus->write = &ixp4xx_mdio_write;
@@ -473,7 +482,7 @@ static void eth_rx_irq(void *pdev)
printk(KERN_DEBUG "%s: eth_rx_irq\n", dev->name);
#endif
qmgr_disable_irq(port->plat->rxq);
- netif_rx_schedule(&port->napi);
+ napi_schedule(&port->napi);
}
static int eth_poll(struct napi_struct *napi, int budget)
@@ -498,16 +507,16 @@ static int eth_poll(struct napi_struct *napi, int budget)
if ((n = queue_get_desc(rxq, port, 0)) < 0) {
#if DEBUG_RX
- printk(KERN_DEBUG "%s: eth_poll netif_rx_complete\n",
+ printk(KERN_DEBUG "%s: eth_poll napi_complete\n",
dev->name);
#endif
- netif_rx_complete(napi);
+ napi_complete(napi);
qmgr_enable_irq(rxq);
if (!qmgr_stat_empty(rxq) &&
- netif_rx_reschedule(napi)) {
+ napi_reschedule(napi)) {
#if DEBUG_RX
printk(KERN_DEBUG "%s: eth_poll"
- " netif_rx_reschedule successed\n",
+ " napi_reschedule successed\n",
dev->name);
#endif
qmgr_disable_irq(rxq);
@@ -1036,7 +1045,7 @@ static int eth_open(struct net_device *dev)
}
ports_open++;
/* we may already have RX data, enables IRQ */
- netif_rx_schedule(&port->napi);
+ napi_schedule(&port->napi);
return 0;
}
@@ -1250,9 +1259,6 @@ static struct platform_driver ixp4xx_eth_driver = {
static int __init eth_init_module(void)
{
int err;
- if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0))
- return -ENOSYS;
-
if ((err = ixp4xx_mdio_register()))
return err;
return platform_driver_register(&ixp4xx_eth_driver);
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
index f3a127434897..35cd264abae7 100644
--- a/drivers/net/arm/ks8695net.c
+++ b/drivers/net/arm/ks8695net.c
@@ -1059,7 +1059,7 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
{
strlcpy(info->driver, MODULENAME, sizeof(info->driver));
strlcpy(info->version, MODULEVERSION, sizeof(info->version));
- strlcpy(info->bus_info, ndev->dev.parent->bus_id,
+ strlcpy(info->bus_info, dev_name(ndev->dev.parent),
sizeof(info->bus_info));
}
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
index 72ea6e378f8d..18b566ad4fd1 100644
--- a/drivers/net/at1700.c
+++ b/drivers/net/at1700.c
@@ -249,6 +249,17 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops at1700_netdev_ops = {
+ .ndo_open = net_open,
+ .ndo_stop = net_close,
+ .ndo_start_xmit = net_send_packet,
+ .ndo_set_multicast_list = set_rx_mode,
+ .ndo_tx_timeout = net_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/* The Fujitsu datasheet suggests that the NIC be probed for by checking its
"signature", the default bit pattern after a reset. This *doesn't* work --
there is no way to reset the bus interface without a complete power-cycle!
@@ -448,13 +459,7 @@ found:
if (net_debug)
printk(version);
- memset(lp, 0, sizeof(struct net_local));
-
- dev->open = net_open;
- dev->stop = net_close;
- dev->hard_start_xmit = net_send_packet;
- dev->set_multicast_list = &set_rx_mode;
- dev->tx_timeout = net_tx_timeout;
+ dev->netdev_ops = &at1700_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
spin_lock_init(&lp->lock);
@@ -828,7 +833,6 @@ set_rx_mode(struct net_device *dev)
struct net_local *lp = netdev_priv(dev);
unsigned char mc_filter[8]; /* Multicast hash filter */
unsigned long flags;
- int i;
if (dev->flags & IFF_PROMISC) {
memset(mc_filter, 0xff, sizeof(mc_filter));
@@ -857,6 +861,7 @@ set_rx_mode(struct net_device *dev)
spin_lock_irqsave (&lp->lock, flags);
if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
+ int i;
int saved_bank = inw(ioaddr + CONFIG_0);
/* Switch to bank 1 and set the multicast table. */
outw((saved_bank & ~0x0C00) | 0x0480, ioaddr + CONFIG_0);
diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h
index ac11b84b8377..e1658ef3fcdf 100644
--- a/drivers/net/atl1c/atl1c.h
+++ b/drivers/net/atl1c/atl1c.h
@@ -45,7 +45,6 @@
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/tcp.h>
-#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/workqueue.h>
diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h
index c49550d507a0..2bf63b4368e2 100644
--- a/drivers/net/atl1e/atl1e.h
+++ b/drivers/net/atl1e/atl1e.h
@@ -448,7 +448,7 @@ struct atl1e_adapter {
/* All Descriptor memory */
dma_addr_t ring_dma;
void *ring_vir_addr;
- int ring_size;
+ u32 ring_size;
struct atl1e_tx_ring tx_ring;
struct atl1e_rx_ring rx_ring;
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index bb9094d4cbc9..c758884728a5 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -1326,9 +1326,9 @@ static irqreturn_t atl1e_intr(int irq, void *data)
AT_WRITE_REG(hw, REG_IMR,
IMR_NORMAL_MASK & ~ISR_RX_EVENT);
AT_WRITE_FLUSH(hw);
- if (likely(netif_rx_schedule_prep(
+ if (likely(napi_schedule_prep(
&adapter->napi)))
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
}
} while (--max_ints > 0);
/* re-enable Interrupt*/
@@ -1514,7 +1514,7 @@ static int atl1e_clean(struct napi_struct *napi, int budget)
/* If no Tx and not enough Rx work done, exit the polling mode */
if (work_done < budget) {
quit_polling:
- netif_rx_complete(napi);
+ napi_complete(napi);
imr_data = AT_READ_REG(&adapter->hw, REG_IMR);
AT_WRITE_REG(&adapter->hw, REG_IMR, imr_data | ISR_RX_EVENT);
/* test debug */
diff --git a/drivers/net/atl1e/atl1e_param.c b/drivers/net/atl1e/atl1e_param.c
index f72abb34b0cd..b3be59fd3fb5 100644
--- a/drivers/net/atl1e/atl1e_param.c
+++ b/drivers/net/atl1e/atl1e_param.c
@@ -41,7 +41,7 @@
#define ATL1E_PARAM(x, desc) \
static int __devinitdata x[ATL1E_MAX_NIC + 1] = ATL1E_PARAM_INIT; \
- static int num_##x; \
+ static unsigned int num_##x; \
module_param_array_named(x, x, int, &num_##x, 0); \
MODULE_PARM_DESC(x, desc);
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index c0ceee0d7c80..43fc1b2ca3cd 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -105,7 +105,7 @@
* Default Value: 100 (200us)
*/
static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
-static int num_int_mod_timer;
+static unsigned int num_int_mod_timer;
module_param_array_named(int_mod_timer, int_mod_timer, int,
&num_int_mod_timer, 0);
MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index bc394491b63b..9fe06c3f4097 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -2854,7 +2854,7 @@ static void atl2_force_ps(struct atl2_hw *hw)
#else
#define ATL2_PARAM(X, desc) \
static int __devinitdata X[ATL2_MAX_NIC+1] = ATL2_PARAM_INIT; \
- static int num_##X = 0; \
+ static unsigned int num_##X; \
module_param_array_named(X, X, int, &num_##X, 0); \
MODULE_PARM_DESC(X, desc);
#endif
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 9c875bb3f76c..4274e4ac963b 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -81,24 +81,6 @@ MODULE_AUTHOR(DRV_AUTHOR);
MODULE_DESCRIPTION(DRV_DESC);
MODULE_LICENSE("GPL");
-// prototypes
-static void hard_stop(struct net_device *);
-static void enable_rx_tx(struct net_device *dev);
-static struct net_device * au1000_probe(int port_num);
-static int au1000_init(struct net_device *);
-static int au1000_open(struct net_device *);
-static int au1000_close(struct net_device *);
-static int au1000_tx(struct sk_buff *, struct net_device *);
-static int au1000_rx(struct net_device *);
-static irqreturn_t au1000_interrupt(int, void *);
-static void au1000_tx_timeout(struct net_device *);
-static void set_rx_mode(struct net_device *);
-static int au1000_ioctl(struct net_device *, struct ifreq *, int);
-static int au1000_mdio_read(struct net_device *, int, int);
-static void au1000_mdio_write(struct net_device *, int, int, u16);
-static void au1000_adjust_link(struct net_device *);
-static void enable_mac(struct net_device *, int);
-
/*
* Theory of operation
*
@@ -188,6 +170,26 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES];
# error MAC0-associated PHY attached 2nd MACs MII bus not supported yet
#endif
+static void enable_mac(struct net_device *dev, int force_reset)
+{
+ unsigned long flags;
+ struct au1000_private *aup = netdev_priv(dev);
+
+ spin_lock_irqsave(&aup->lock, flags);
+
+ if(force_reset || (!aup->mac_enabled)) {
+ *aup->enable = MAC_EN_CLOCK_ENABLE;
+ au_sync_delay(2);
+ *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
+ | MAC_EN_CLOCK_ENABLE);
+ au_sync_delay(2);
+
+ aup->mac_enabled = 1;
+ }
+
+ spin_unlock_irqrestore(&aup->lock, flags);
+}
+
/*
* MII operations
*/
@@ -281,6 +283,107 @@ static int au1000_mdiobus_reset(struct mii_bus *bus)
return 0;
}
+static void hard_stop(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+
+ if (au1000_debug > 4)
+ printk(KERN_INFO "%s: hard stop\n", dev->name);
+
+ aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
+ au_sync_delay(10);
+}
+
+static void enable_rx_tx(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+
+ if (au1000_debug > 4)
+ printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
+
+ aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
+ au_sync_delay(10);
+}
+
+static void
+au1000_adjust_link(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ struct phy_device *phydev = aup->phy_dev;
+ unsigned long flags;
+
+ int status_change = 0;
+
+ BUG_ON(!aup->phy_dev);
+
+ spin_lock_irqsave(&aup->lock, flags);
+
+ if (phydev->link && (aup->old_speed != phydev->speed)) {
+ // speed changed
+
+ switch(phydev->speed) {
+ case SPEED_10:
+ case SPEED_100:
+ break;
+ default:
+ printk(KERN_WARNING
+ "%s: Speed (%d) is not 10/100 ???\n",
+ dev->name, phydev->speed);
+ break;
+ }
+
+ aup->old_speed = phydev->speed;
+
+ status_change = 1;
+ }
+
+ if (phydev->link && (aup->old_duplex != phydev->duplex)) {
+ // duplex mode changed
+
+ /* switching duplex mode requires to disable rx and tx! */
+ hard_stop(dev);
+
+ if (DUPLEX_FULL == phydev->duplex)
+ aup->mac->control = ((aup->mac->control
+ | MAC_FULL_DUPLEX)
+ & ~MAC_DISABLE_RX_OWN);
+ else
+ aup->mac->control = ((aup->mac->control
+ & ~MAC_FULL_DUPLEX)
+ | MAC_DISABLE_RX_OWN);
+ au_sync_delay(1);
+
+ enable_rx_tx(dev);
+ aup->old_duplex = phydev->duplex;
+
+ status_change = 1;
+ }
+
+ if(phydev->link != aup->old_link) {
+ // link state changed
+
+ if (!phydev->link) {
+ /* link went down */
+ aup->old_speed = 0;
+ aup->old_duplex = -1;
+ }
+
+ aup->old_link = phydev->link;
+ status_change = 1;
+ }
+
+ spin_unlock_irqrestore(&aup->lock, flags);
+
+ if (status_change) {
+ if (phydev->link)
+ printk(KERN_INFO "%s: link up (%d/%s)\n",
+ dev->name, phydev->speed,
+ DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
+ else
+ printk(KERN_INFO "%s: link down\n", dev->name);
+ }
+}
+
static int mii_probe (struct net_device *dev)
{
struct au1000_private *const aup = netdev_priv(dev);
@@ -355,8 +458,8 @@ static int mii_probe (struct net_device *dev)
/* now we are supposed to have a proper phydev, to attach to... */
BUG_ON(phydev->attached_dev);
- phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
+ phydev = phy_connect(dev, dev_name(&phydev->dev), &au1000_adjust_link,
+ 0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(phydev)) {
printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
@@ -381,8 +484,8 @@ static int mii_probe (struct net_device *dev)
aup->phy_dev = phydev;
printk(KERN_INFO "%s: attached PHY driver [%s] "
- "(mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
return 0;
}
@@ -412,48 +515,6 @@ void ReleaseDB(struct au1000_private *aup, db_dest_t *pDB)
aup->pDBfree = pDB;
}
-static void enable_rx_tx(struct net_device *dev)
-{
- struct au1000_private *aup = netdev_priv(dev);
-
- if (au1000_debug > 4)
- printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
-
- aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
- au_sync_delay(10);
-}
-
-static void hard_stop(struct net_device *dev)
-{
- struct au1000_private *aup = netdev_priv(dev);
-
- if (au1000_debug > 4)
- printk(KERN_INFO "%s: hard stop\n", dev->name);
-
- aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
- au_sync_delay(10);
-}
-
-static void enable_mac(struct net_device *dev, int force_reset)
-{
- unsigned long flags;
- struct au1000_private *aup = netdev_priv(dev);
-
- spin_lock_irqsave(&aup->lock, flags);
-
- if(force_reset || (!aup->mac_enabled)) {
- *aup->enable = MAC_EN_CLOCK_ENABLE;
- au_sync_delay(2);
- *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
- | MAC_EN_CLOCK_ENABLE);
- au_sync_delay(2);
-
- aup->mac_enabled = 1;
- }
-
- spin_unlock_irqrestore(&aup->lock, flags);
-}
-
static void reset_mac_unlocked(struct net_device *dev)
{
struct au1000_private *const aup = netdev_priv(dev);
@@ -542,30 +603,6 @@ static struct {
static int num_ifs;
/*
- * Setup the base address and interrupt of the Au1xxx ethernet macs
- * based on cpu type and whether the interface is enabled in sys_pinfunc
- * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
- */
-static int __init au1000_init_module(void)
-{
- int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
- struct net_device *dev;
- int i, found_one = 0;
-
- num_ifs = NUM_ETH_INTERFACES - ni;
-
- for(i = 0; i < num_ifs; i++) {
- dev = au1000_probe(i);
- iflist[i].dev = dev;
- if (dev)
- found_one++;
- }
- if (!found_one)
- return -ENODEV;
- return 0;
-}
-
-/*
* ethtool operations
*/
@@ -611,199 +648,6 @@ static const struct ethtool_ops au1000_ethtool_ops = {
.get_link = ethtool_op_get_link,
};
-static struct net_device * au1000_probe(int port_num)
-{
- static unsigned version_printed = 0;
- struct au1000_private *aup = NULL;
- struct net_device *dev = NULL;
- db_dest_t *pDB, *pDBfree;
- char ethaddr[6];
- int irq, i, err;
- u32 base, macen;
-
- if (port_num >= NUM_ETH_INTERFACES)
- return NULL;
-
- base = CPHYSADDR(iflist[port_num].base_addr );
- macen = CPHYSADDR(iflist[port_num].macen_addr);
- irq = iflist[port_num].irq;
-
- if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
- !request_mem_region(macen, 4, "Au1x00 ENET"))
- return NULL;
-
- if (version_printed++ == 0)
- printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
-
- dev = alloc_etherdev(sizeof(struct au1000_private));
- if (!dev) {
- printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
- return NULL;
- }
-
- if ((err = register_netdev(dev)) != 0) {
- printk(KERN_ERR "%s: Cannot register net device, error %d\n",
- DRV_NAME, err);
- free_netdev(dev);
- return NULL;
- }
-
- printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
- dev->name, base, irq);
-
- aup = netdev_priv(dev);
-
- spin_lock_init(&aup->lock);
-
- /* Allocate the data buffers */
- /* Snooping works fine with eth on all au1xxx */
- aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
- (NUM_TX_BUFFS + NUM_RX_BUFFS),
- &aup->dma_addr, 0);
- if (!aup->vaddr) {
- free_netdev(dev);
- release_mem_region( base, MAC_IOSIZE);
- release_mem_region(macen, 4);
- return NULL;
- }
-
- /* aup->mac is the base address of the MAC's registers */
- aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr;
-
- /* Setup some variables for quick register address access */
- aup->enable = (volatile u32 *)iflist[port_num].macen_addr;
- aup->mac_id = port_num;
- au_macs[port_num] = aup;
-
- if (port_num == 0) {
- if (prom_get_ethernet_addr(ethaddr) == 0)
- memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
- else {
- printk(KERN_INFO "%s: No MAC address found\n",
- dev->name);
- /* Use the hard coded MAC addresses */
- }
-
- setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
- } else if (port_num == 1)
- setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
-
- /*
- * Assign to the Ethernet ports two consecutive MAC addresses
- * to match those that are printed on their stickers
- */
- memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
- dev->dev_addr[5] += port_num;
-
- *aup->enable = 0;
- aup->mac_enabled = 0;
-
- aup->mii_bus = mdiobus_alloc();
- if (aup->mii_bus == NULL)
- goto err_out;
-
- aup->mii_bus->priv = dev;
- aup->mii_bus->read = au1000_mdiobus_read;
- aup->mii_bus->write = au1000_mdiobus_write;
- aup->mii_bus->reset = au1000_mdiobus_reset;
- aup->mii_bus->name = "au1000_eth_mii";
- snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id);
- aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
- for(i = 0; i < PHY_MAX_ADDR; ++i)
- aup->mii_bus->irq[i] = PHY_POLL;
-
- /* if known, set corresponding PHY IRQs */
-#if defined(AU1XXX_PHY_STATIC_CONFIG)
-# if defined(AU1XXX_PHY0_IRQ)
- if (AU1XXX_PHY0_BUSID == aup->mac_id)
- aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ;
-# endif
-# if defined(AU1XXX_PHY1_IRQ)
- if (AU1XXX_PHY1_BUSID == aup->mac_id)
- aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ;
-# endif
-#endif
- mdiobus_register(aup->mii_bus);
-
- if (mii_probe(dev) != 0) {
- goto err_out;
- }
-
- pDBfree = NULL;
- /* setup the data buffer descriptors and attach a buffer to each one */
- pDB = aup->db;
- for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
- pDB->pnext = pDBfree;
- pDBfree = pDB;
- pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
- pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
- pDB++;
- }
- aup->pDBfree = pDBfree;
-
- for (i = 0; i < NUM_RX_DMA; i++) {
- pDB = GetFreeDB(aup);
- if (!pDB) {
- goto err_out;
- }
- aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
- aup->rx_db_inuse[i] = pDB;
- }
- for (i = 0; i < NUM_TX_DMA; i++) {
- pDB = GetFreeDB(aup);
- if (!pDB) {
- goto err_out;
- }
- aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
- aup->tx_dma_ring[i]->len = 0;
- aup->tx_db_inuse[i] = pDB;
- }
-
- dev->base_addr = base;
- dev->irq = irq;
- dev->open = au1000_open;
- dev->hard_start_xmit = au1000_tx;
- dev->stop = au1000_close;
- dev->set_multicast_list = &set_rx_mode;
- dev->do_ioctl = &au1000_ioctl;
- SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
- dev->tx_timeout = au1000_tx_timeout;
- dev->watchdog_timeo = ETH_TX_TIMEOUT;
-
- /*
- * The boot code uses the ethernet controller, so reset it to start
- * fresh. au1000_init() expects that the device is in reset state.
- */
- reset_mac(dev);
-
- return dev;
-
-err_out:
- if (aup->mii_bus != NULL) {
- mdiobus_unregister(aup->mii_bus);
- mdiobus_free(aup->mii_bus);
- }
-
- /* here we should have a valid dev plus aup-> register addresses
- * so we can reset the mac properly.*/
- reset_mac(dev);
-
- for (i = 0; i < NUM_RX_DMA; i++) {
- if (aup->rx_db_inuse[i])
- ReleaseDB(aup, aup->rx_db_inuse[i]);
- }
- for (i = 0; i < NUM_TX_DMA; i++) {
- if (aup->tx_db_inuse[i])
- ReleaseDB(aup, aup->tx_db_inuse[i]);
- }
- dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
- (void *)aup->vaddr, aup->dma_addr);
- unregister_netdev(dev);
- free_netdev(dev);
- release_mem_region( base, MAC_IOSIZE);
- release_mem_region(macen, 4);
- return NULL;
-}
/*
* Initialize the interface.
@@ -864,83 +708,170 @@ static int au1000_init(struct net_device *dev)
return 0;
}
-static void
-au1000_adjust_link(struct net_device *dev)
+static inline void update_rx_stats(struct net_device *dev, u32 status)
{
struct au1000_private *aup = netdev_priv(dev);
- struct phy_device *phydev = aup->phy_dev;
- unsigned long flags;
+ struct net_device_stats *ps = &dev->stats;
- int status_change = 0;
+ ps->rx_packets++;
+ if (status & RX_MCAST_FRAME)
+ ps->multicast++;
- BUG_ON(!aup->phy_dev);
+ if (status & RX_ERROR) {
+ ps->rx_errors++;
+ if (status & RX_MISSED_FRAME)
+ ps->rx_missed_errors++;
+ if (status & (RX_OVERLEN | RX_OVERLEN | RX_LEN_ERROR))
+ ps->rx_length_errors++;
+ if (status & RX_CRC_ERROR)
+ ps->rx_crc_errors++;
+ if (status & RX_COLL)
+ ps->collisions++;
+ }
+ else
+ ps->rx_bytes += status & RX_FRAME_LEN_MASK;
- spin_lock_irqsave(&aup->lock, flags);
+}
- if (phydev->link && (aup->old_speed != phydev->speed)) {
- // speed changed
+/*
+ * Au1000 receive routine.
+ */
+static int au1000_rx(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ struct sk_buff *skb;
+ volatile rx_dma_t *prxd;
+ u32 buff_stat, status;
+ db_dest_t *pDB;
+ u32 frmlen;
- switch(phydev->speed) {
- case SPEED_10:
- case SPEED_100:
- break;
- default:
- printk(KERN_WARNING
- "%s: Speed (%d) is not 10/100 ???\n",
- dev->name, phydev->speed);
- break;
- }
+ if (au1000_debug > 5)
+ printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head);
- aup->old_speed = phydev->speed;
+ prxd = aup->rx_dma_ring[aup->rx_head];
+ buff_stat = prxd->buff_stat;
+ while (buff_stat & RX_T_DONE) {
+ status = prxd->status;
+ pDB = aup->rx_db_inuse[aup->rx_head];
+ update_rx_stats(dev, status);
+ if (!(status & RX_ERROR)) {
- status_change = 1;
+ /* good frame */
+ frmlen = (status & RX_FRAME_LEN_MASK);
+ frmlen -= 4; /* Remove FCS */
+ skb = dev_alloc_skb(frmlen + 2);
+ if (skb == NULL) {
+ printk(KERN_ERR
+ "%s: Memory squeeze, dropping packet.\n",
+ dev->name);
+ dev->stats.rx_dropped++;
+ continue;
+ }
+ skb_reserve(skb, 2); /* 16 byte IP header align */
+ skb_copy_to_linear_data(skb,
+ (unsigned char *)pDB->vaddr, frmlen);
+ skb_put(skb, frmlen);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb); /* pass the packet to upper layers */
+ }
+ else {
+ if (au1000_debug > 4) {
+ if (status & RX_MISSED_FRAME)
+ printk("rx miss\n");
+ if (status & RX_WDOG_TIMER)
+ printk("rx wdog\n");
+ if (status & RX_RUNT)
+ printk("rx runt\n");
+ if (status & RX_OVERLEN)
+ printk("rx overlen\n");
+ if (status & RX_COLL)
+ printk("rx coll\n");
+ if (status & RX_MII_ERROR)
+ printk("rx mii error\n");
+ if (status & RX_CRC_ERROR)
+ printk("rx crc error\n");
+ if (status & RX_LEN_ERROR)
+ printk("rx len error\n");
+ if (status & RX_U_CNTRL_FRAME)
+ printk("rx u control frame\n");
+ if (status & RX_MISSED_FRAME)
+ printk("rx miss\n");
+ }
+ }
+ prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
+ aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
+ au_sync();
+
+ /* next descriptor */
+ prxd = aup->rx_dma_ring[aup->rx_head];
+ buff_stat = prxd->buff_stat;
}
+ return 0;
+}
- if (phydev->link && (aup->old_duplex != phydev->duplex)) {
- // duplex mode changed
+static void update_tx_stats(struct net_device *dev, u32 status)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ struct net_device_stats *ps = &dev->stats;
- /* switching duplex mode requires to disable rx and tx! */
- hard_stop(dev);
+ if (status & TX_FRAME_ABORTED) {
+ if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) {
+ if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
+ /* any other tx errors are only valid
+ * in half duplex mode */
+ ps->tx_errors++;
+ ps->tx_aborted_errors++;
+ }
+ }
+ else {
+ ps->tx_errors++;
+ ps->tx_aborted_errors++;
+ if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
+ ps->tx_carrier_errors++;
+ }
+ }
+}
- if (DUPLEX_FULL == phydev->duplex)
- aup->mac->control = ((aup->mac->control
- | MAC_FULL_DUPLEX)
- & ~MAC_DISABLE_RX_OWN);
- else
- aup->mac->control = ((aup->mac->control
- & ~MAC_FULL_DUPLEX)
- | MAC_DISABLE_RX_OWN);
- au_sync_delay(1);
+/*
+ * Called from the interrupt service routine to acknowledge
+ * the TX DONE bits. This is a must if the irq is setup as
+ * edge triggered.
+ */
+static void au1000_tx_ack(struct net_device *dev)
+{
+ struct au1000_private *aup = netdev_priv(dev);
+ volatile tx_dma_t *ptxd;
- enable_rx_tx(dev);
- aup->old_duplex = phydev->duplex;
+ ptxd = aup->tx_dma_ring[aup->tx_tail];
- status_change = 1;
- }
+ while (ptxd->buff_stat & TX_T_DONE) {
+ update_tx_stats(dev, ptxd->status);
+ ptxd->buff_stat &= ~TX_T_DONE;
+ ptxd->len = 0;
+ au_sync();
- if(phydev->link != aup->old_link) {
- // link state changed
+ aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1);
+ ptxd = aup->tx_dma_ring[aup->tx_tail];
- if (!phydev->link) {
- /* link went down */
- aup->old_speed = 0;
- aup->old_duplex = -1;
+ if (aup->tx_full) {
+ aup->tx_full = 0;
+ netif_wake_queue(dev);
}
-
- aup->old_link = phydev->link;
- status_change = 1;
}
+}
- spin_unlock_irqrestore(&aup->lock, flags);
+/*
+ * Au1000 interrupt service routine.
+ */
+static irqreturn_t au1000_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
- if (status_change) {
- if (phydev->link)
- printk(KERN_INFO "%s: link up (%d/%s)\n",
- dev->name, phydev->speed,
- DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
- else
- printk(KERN_INFO "%s: link down\n", dev->name);
- }
+ /* Handle RX interrupts first to minimize chance of overrun */
+
+ au1000_rx(dev);
+ au1000_tx_ack(dev);
+ return IRQ_RETVAL(1);
}
static int au1000_open(struct net_device *dev)
@@ -1003,88 +934,6 @@ static int au1000_close(struct net_device *dev)
return 0;
}
-static void __exit au1000_cleanup_module(void)
-{
- int i, j;
- struct net_device *dev;
- struct au1000_private *aup;
-
- for (i = 0; i < num_ifs; i++) {
- dev = iflist[i].dev;
- if (dev) {
- aup = netdev_priv(dev);
- unregister_netdev(dev);
- mdiobus_unregister(aup->mii_bus);
- mdiobus_free(aup->mii_bus);
- for (j = 0; j < NUM_RX_DMA; j++)
- if (aup->rx_db_inuse[j])
- ReleaseDB(aup, aup->rx_db_inuse[j]);
- for (j = 0; j < NUM_TX_DMA; j++)
- if (aup->tx_db_inuse[j])
- ReleaseDB(aup, aup->tx_db_inuse[j]);
- dma_free_noncoherent(NULL, MAX_BUF_SIZE *
- (NUM_TX_BUFFS + NUM_RX_BUFFS),
- (void *)aup->vaddr, aup->dma_addr);
- release_mem_region(dev->base_addr, MAC_IOSIZE);
- release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4);
- free_netdev(dev);
- }
- }
-}
-
-static void update_tx_stats(struct net_device *dev, u32 status)
-{
- struct au1000_private *aup = netdev_priv(dev);
- struct net_device_stats *ps = &dev->stats;
-
- if (status & TX_FRAME_ABORTED) {
- if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) {
- if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
- /* any other tx errors are only valid
- * in half duplex mode */
- ps->tx_errors++;
- ps->tx_aborted_errors++;
- }
- }
- else {
- ps->tx_errors++;
- ps->tx_aborted_errors++;
- if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
- ps->tx_carrier_errors++;
- }
- }
-}
-
-
-/*
- * Called from the interrupt service routine to acknowledge
- * the TX DONE bits. This is a must if the irq is setup as
- * edge triggered.
- */
-static void au1000_tx_ack(struct net_device *dev)
-{
- struct au1000_private *aup = netdev_priv(dev);
- volatile tx_dma_t *ptxd;
-
- ptxd = aup->tx_dma_ring[aup->tx_tail];
-
- while (ptxd->buff_stat & TX_T_DONE) {
- update_tx_stats(dev, ptxd->status);
- ptxd->buff_stat &= ~TX_T_DONE;
- ptxd->len = 0;
- au_sync();
-
- aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1);
- ptxd = aup->tx_dma_ring[aup->tx_tail];
-
- if (aup->tx_full) {
- aup->tx_full = 0;
- netif_wake_queue(dev);
- }
- }
-}
-
-
/*
* Au1000 transmit routine.
*/
@@ -1142,123 +991,6 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
return 0;
}
-static inline void update_rx_stats(struct net_device *dev, u32 status)
-{
- struct au1000_private *aup = netdev_priv(dev);
- struct net_device_stats *ps = &dev->stats;
-
- ps->rx_packets++;
- if (status & RX_MCAST_FRAME)
- ps->multicast++;
-
- if (status & RX_ERROR) {
- ps->rx_errors++;
- if (status & RX_MISSED_FRAME)
- ps->rx_missed_errors++;
- if (status & (RX_OVERLEN | RX_OVERLEN | RX_LEN_ERROR))
- ps->rx_length_errors++;
- if (status & RX_CRC_ERROR)
- ps->rx_crc_errors++;
- if (status & RX_COLL)
- ps->collisions++;
- }
- else
- ps->rx_bytes += status & RX_FRAME_LEN_MASK;
-
-}
-
-/*
- * Au1000 receive routine.
- */
-static int au1000_rx(struct net_device *dev)
-{
- struct au1000_private *aup = netdev_priv(dev);
- struct sk_buff *skb;
- volatile rx_dma_t *prxd;
- u32 buff_stat, status;
- db_dest_t *pDB;
- u32 frmlen;
-
- if (au1000_debug > 5)
- printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head);
-
- prxd = aup->rx_dma_ring[aup->rx_head];
- buff_stat = prxd->buff_stat;
- while (buff_stat & RX_T_DONE) {
- status = prxd->status;
- pDB = aup->rx_db_inuse[aup->rx_head];
- update_rx_stats(dev, status);
- if (!(status & RX_ERROR)) {
-
- /* good frame */
- frmlen = (status & RX_FRAME_LEN_MASK);
- frmlen -= 4; /* Remove FCS */
- skb = dev_alloc_skb(frmlen + 2);
- if (skb == NULL) {
- printk(KERN_ERR
- "%s: Memory squeeze, dropping packet.\n",
- dev->name);
- dev->stats.rx_dropped++;
- continue;
- }
- skb_reserve(skb, 2); /* 16 byte IP header align */
- skb_copy_to_linear_data(skb,
- (unsigned char *)pDB->vaddr, frmlen);
- skb_put(skb, frmlen);
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb); /* pass the packet to upper layers */
- }
- else {
- if (au1000_debug > 4) {
- if (status & RX_MISSED_FRAME)
- printk("rx miss\n");
- if (status & RX_WDOG_TIMER)
- printk("rx wdog\n");
- if (status & RX_RUNT)
- printk("rx runt\n");
- if (status & RX_OVERLEN)
- printk("rx overlen\n");
- if (status & RX_COLL)
- printk("rx coll\n");
- if (status & RX_MII_ERROR)
- printk("rx mii error\n");
- if (status & RX_CRC_ERROR)
- printk("rx crc error\n");
- if (status & RX_LEN_ERROR)
- printk("rx len error\n");
- if (status & RX_U_CNTRL_FRAME)
- printk("rx u control frame\n");
- if (status & RX_MISSED_FRAME)
- printk("rx miss\n");
- }
- }
- prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
- aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
- au_sync();
-
- /* next descriptor */
- prxd = aup->rx_dma_ring[aup->rx_head];
- buff_stat = prxd->buff_stat;
- }
- return 0;
-}
-
-
-/*
- * Au1000 interrupt service routine.
- */
-static irqreturn_t au1000_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
-
- /* Handle RX interrupts first to minimize chance of overrun */
-
- au1000_rx(dev);
- au1000_tx_ack(dev);
- return IRQ_RETVAL(1);
-}
-
-
/*
* The Tx ring has been full longer than the watchdog timeout
* value. The transmitter must be hung?
@@ -1315,5 +1047,252 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return phy_mii_ioctl(aup->phy_dev, if_mii(rq), cmd);
}
+static struct net_device * au1000_probe(int port_num)
+{
+ static unsigned version_printed = 0;
+ struct au1000_private *aup = NULL;
+ struct net_device *dev = NULL;
+ db_dest_t *pDB, *pDBfree;
+ char ethaddr[6];
+ int irq, i, err;
+ u32 base, macen;
+
+ if (port_num >= NUM_ETH_INTERFACES)
+ return NULL;
+
+ base = CPHYSADDR(iflist[port_num].base_addr );
+ macen = CPHYSADDR(iflist[port_num].macen_addr);
+ irq = iflist[port_num].irq;
+
+ if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") ||
+ !request_mem_region(macen, 4, "Au1x00 ENET"))
+ return NULL;
+
+ if (version_printed++ == 0)
+ printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+
+ dev = alloc_etherdev(sizeof(struct au1000_private));
+ if (!dev) {
+ printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME);
+ return NULL;
+ }
+
+ if ((err = register_netdev(dev)) != 0) {
+ printk(KERN_ERR "%s: Cannot register net device, error %d\n",
+ DRV_NAME, err);
+ free_netdev(dev);
+ return NULL;
+ }
+
+ printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n",
+ dev->name, base, irq);
+
+ aup = netdev_priv(dev);
+
+ spin_lock_init(&aup->lock);
+
+ /* Allocate the data buffers */
+ /* Snooping works fine with eth on all au1xxx */
+ aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
+ (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ &aup->dma_addr, 0);
+ if (!aup->vaddr) {
+ free_netdev(dev);
+ release_mem_region( base, MAC_IOSIZE);
+ release_mem_region(macen, 4);
+ return NULL;
+ }
+
+ /* aup->mac is the base address of the MAC's registers */
+ aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr;
+
+ /* Setup some variables for quick register address access */
+ aup->enable = (volatile u32 *)iflist[port_num].macen_addr;
+ aup->mac_id = port_num;
+ au_macs[port_num] = aup;
+
+ if (port_num == 0) {
+ if (prom_get_ethernet_addr(ethaddr) == 0)
+ memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
+ else {
+ printk(KERN_INFO "%s: No MAC address found\n",
+ dev->name);
+ /* Use the hard coded MAC addresses */
+ }
+
+ setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
+ } else if (port_num == 1)
+ setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
+
+ /*
+ * Assign to the Ethernet ports two consecutive MAC addresses
+ * to match those that are printed on their stickers
+ */
+ memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
+ dev->dev_addr[5] += port_num;
+
+ *aup->enable = 0;
+ aup->mac_enabled = 0;
+
+ aup->mii_bus = mdiobus_alloc();
+ if (aup->mii_bus == NULL)
+ goto err_out;
+
+ aup->mii_bus->priv = dev;
+ aup->mii_bus->read = au1000_mdiobus_read;
+ aup->mii_bus->write = au1000_mdiobus_write;
+ aup->mii_bus->reset = au1000_mdiobus_reset;
+ aup->mii_bus->name = "au1000_eth_mii";
+ snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id);
+ aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+ for(i = 0; i < PHY_MAX_ADDR; ++i)
+ aup->mii_bus->irq[i] = PHY_POLL;
+
+ /* if known, set corresponding PHY IRQs */
+#if defined(AU1XXX_PHY_STATIC_CONFIG)
+# if defined(AU1XXX_PHY0_IRQ)
+ if (AU1XXX_PHY0_BUSID == aup->mac_id)
+ aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ;
+# endif
+# if defined(AU1XXX_PHY1_IRQ)
+ if (AU1XXX_PHY1_BUSID == aup->mac_id)
+ aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ;
+# endif
+#endif
+ mdiobus_register(aup->mii_bus);
+
+ if (mii_probe(dev) != 0) {
+ goto err_out;
+ }
+
+ pDBfree = NULL;
+ /* setup the data buffer descriptors and attach a buffer to each one */
+ pDB = aup->db;
+ for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
+ pDB->pnext = pDBfree;
+ pDBfree = pDB;
+ pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
+ pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
+ pDB++;
+ }
+ aup->pDBfree = pDBfree;
+
+ for (i = 0; i < NUM_RX_DMA; i++) {
+ pDB = GetFreeDB(aup);
+ if (!pDB) {
+ goto err_out;
+ }
+ aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+ aup->rx_db_inuse[i] = pDB;
+ }
+ for (i = 0; i < NUM_TX_DMA; i++) {
+ pDB = GetFreeDB(aup);
+ if (!pDB) {
+ goto err_out;
+ }
+ aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+ aup->tx_dma_ring[i]->len = 0;
+ aup->tx_db_inuse[i] = pDB;
+ }
+
+ dev->base_addr = base;
+ dev->irq = irq;
+ dev->open = au1000_open;
+ dev->hard_start_xmit = au1000_tx;
+ dev->stop = au1000_close;
+ dev->set_multicast_list = &set_rx_mode;
+ dev->do_ioctl = &au1000_ioctl;
+ SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
+ dev->tx_timeout = au1000_tx_timeout;
+ dev->watchdog_timeo = ETH_TX_TIMEOUT;
+
+ /*
+ * The boot code uses the ethernet controller, so reset it to start
+ * fresh. au1000_init() expects that the device is in reset state.
+ */
+ reset_mac(dev);
+
+ return dev;
+
+err_out:
+ if (aup->mii_bus != NULL) {
+ mdiobus_unregister(aup->mii_bus);
+ mdiobus_free(aup->mii_bus);
+ }
+
+ /* here we should have a valid dev plus aup-> register addresses
+ * so we can reset the mac properly.*/
+ reset_mac(dev);
+
+ for (i = 0; i < NUM_RX_DMA; i++) {
+ if (aup->rx_db_inuse[i])
+ ReleaseDB(aup, aup->rx_db_inuse[i]);
+ }
+ for (i = 0; i < NUM_TX_DMA; i++) {
+ if (aup->tx_db_inuse[i])
+ ReleaseDB(aup, aup->tx_db_inuse[i]);
+ }
+ dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ (void *)aup->vaddr, aup->dma_addr);
+ unregister_netdev(dev);
+ free_netdev(dev);
+ release_mem_region( base, MAC_IOSIZE);
+ release_mem_region(macen, 4);
+ return NULL;
+}
+
+/*
+ * Setup the base address and interrupt of the Au1xxx ethernet macs
+ * based on cpu type and whether the interface is enabled in sys_pinfunc
+ * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
+ */
+static int __init au1000_init_module(void)
+{
+ int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
+ struct net_device *dev;
+ int i, found_one = 0;
+
+ num_ifs = NUM_ETH_INTERFACES - ni;
+
+ for(i = 0; i < num_ifs; i++) {
+ dev = au1000_probe(i);
+ iflist[i].dev = dev;
+ if (dev)
+ found_one++;
+ }
+ if (!found_one)
+ return -ENODEV;
+ return 0;
+}
+
+static void __exit au1000_cleanup_module(void)
+{
+ int i, j;
+ struct net_device *dev;
+ struct au1000_private *aup;
+
+ for (i = 0; i < num_ifs; i++) {
+ dev = iflist[i].dev;
+ if (dev) {
+ aup = netdev_priv(dev);
+ unregister_netdev(dev);
+ mdiobus_unregister(aup->mii_bus);
+ mdiobus_free(aup->mii_bus);
+ for (j = 0; j < NUM_RX_DMA; j++)
+ if (aup->rx_db_inuse[j])
+ ReleaseDB(aup, aup->rx_db_inuse[j]);
+ for (j = 0; j < NUM_TX_DMA; j++)
+ if (aup->tx_db_inuse[j])
+ ReleaseDB(aup, aup->tx_db_inuse[j]);
+ dma_free_noncoherent(NULL, MAX_BUF_SIZE *
+ (NUM_TX_BUFFS + NUM_RX_BUFFS),
+ (void *)aup->vaddr, aup->dma_addr);
+ release_mem_region(dev->base_addr, MAC_IOSIZE);
+ release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4);
+ free_netdev(dev);
+ }
+ }
+}
+
module_init(au1000_init_module);
module_exit(au1000_cleanup_module);
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index a4eb6c40678c..62d9c9cc5671 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -93,6 +93,7 @@ struct ax_device {
unsigned char running;
unsigned char resume_open;
+ unsigned int irqflags;
u32 reg_offsets[0x20];
};
@@ -474,7 +475,8 @@ static int ax_open(struct net_device *dev)
dev_dbg(&ax->dev->dev, "%s: open\n", dev->name);
- ret = request_irq(dev->irq, ax_ei_interrupt, 0, dev->name, dev);
+ ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
+ dev->name, dev);
if (ret)
return ret;
@@ -731,12 +733,19 @@ static int ax_init_dev(struct net_device *dev, int first_init)
/* load the mac-address from the device if this is the
* first time we've initialised */
- if (first_init && ax->plat->flags & AXFLG_MAC_FROMDEV) {
- ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
- ei_local->mem + E8390_CMD); /* 0x61 */
+ if (first_init) {
+ if (ax->plat->flags & AXFLG_MAC_FROMDEV) {
+ ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
+ ei_local->mem + E8390_CMD); /* 0x61 */
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
+ dev->dev_addr[i] =
+ ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
+ }
- for (i = 0 ; i < ETHER_ADDR_LEN ; i++)
- dev->dev_addr[i] = ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
+ if ((ax->plat->flags & AXFLG_MAC_FROMPLATFORM) &&
+ ax->plat->mac_addr)
+ memcpy(dev->dev_addr, ax->plat->mac_addr,
+ ETHER_ADDR_LEN);
}
ax_reset_8390(dev);
@@ -829,7 +838,7 @@ static int ax_probe(struct platform_device *pdev)
struct ax_device *ax;
struct resource *res;
size_t size;
- int ret;
+ int ret = 0;
dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
if (dev == NULL)
@@ -850,12 +859,14 @@ static int ax_probe(struct platform_device *pdev)
/* find the platform resources */
- ret = platform_get_irq(pdev, 0);
- if (ret < 0) {
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res == NULL) {
dev_err(&pdev->dev, "no IRQ specified\n");
goto exit_mem;
}
- dev->irq = ret;
+
+ dev->irq = res->start;
+ ax->irqflags = res->flags & IRQF_TRIGGER_MASK;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index dc5f051005fa..5c84541e0737 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -874,7 +874,7 @@ static int b44_poll(struct napi_struct *napi, int budget)
}
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
b44_enable_ints(bp);
}
@@ -906,13 +906,13 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id)
goto irq_ack;
}
- if (netif_rx_schedule_prep(&bp->napi)) {
+ if (napi_schedule_prep(&bp->napi)) {
/* NOTE: These writes are posted by the readback of
* the ISTAT register below.
*/
bp->istat = istat;
__b44_disable_ints(bp);
- __netif_rx_schedule(&bp->napi);
+ __napi_schedule(&bp->napi);
} else {
printk(KERN_ERR PFX "%s: Error, poll already scheduled\n",
dev->name);
@@ -973,7 +973,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
ssb_dma_unmap_single(bp->sdev, mapping, len,
DMA_TO_DEVICE);
- bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA);
+ bounce_skb = __netdev_alloc_skb(dev, len, GFP_ATOMIC | GFP_DMA);
if (!bounce_skb)
goto err_out;
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 63d593d53153..c49ddd08b2aa 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -100,9 +100,9 @@ struct be_drvr_stats {
u32 be_tx_wrbs; /* number of tx WRBs used */
u32 be_tx_events; /* number of tx completion events */
u32 be_tx_compl; /* number of tx completion entries processed */
- u64 be_tx_jiffies;
- ulong be_tx_bytes;
- ulong be_tx_bytes_prev;
+ ulong be_tx_jiffies;
+ u64 be_tx_bytes;
+ u64 be_tx_bytes_prev;
u32 be_tx_rate;
u32 cache_barrier[16];
@@ -113,9 +113,9 @@ struct be_drvr_stats {
u32 be_rx_compl; /* number of rx completion entries processed */
u32 be_lro_hgram_data[8]; /* histogram of LRO data packets */
u32 be_lro_hgram_ack[8]; /* histogram of LRO ACKs */
- u64 be_rx_jiffies;
- ulong be_rx_bytes;
- ulong be_rx_bytes_prev;
+ ulong be_rx_jiffies;
+ u64 be_rx_bytes;
+ u64 be_rx_bytes_prev;
u32 be_rx_rate;
/* number of non ether type II frames dropped where
* frame len > length field of Mac Hdr */
@@ -194,6 +194,7 @@ struct be_adapter {
struct be_eq_obj rx_eq;
struct be_rx_obj rx_obj;
u32 big_page_size; /* Compounded page size shared by rx wrbs */
+ bool rx_post_starved; /* Zero rx frags have been posted to BE */
struct vlan_group *vlan_grp;
u16 num_vlans;
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 897a63de5bdb..9b75aa630062 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -16,6 +16,7 @@
*/
#include "be.h"
+#include <asm/div64.h>
MODULE_VERSION(DRV_VER);
MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@ -245,19 +246,29 @@ static void be_link_status_update(struct be_adapter *adapter)
/* Update the EQ delay n BE based on the RX frags consumed / sec */
static void be_rx_eqd_update(struct be_adapter *adapter)
{
- u32 eqd;
struct be_ctrl_info *ctrl = &adapter->ctrl;
struct be_eq_obj *rx_eq = &adapter->rx_eq;
struct be_drvr_stats *stats = &adapter->stats.drvr_stats;
+ ulong now = jiffies;
+ u32 eqd;
+
+ if (!rx_eq->enable_aic)
+ return;
+
+ /* Wrapped around */
+ if (time_before(now, stats->rx_fps_jiffies)) {
+ stats->rx_fps_jiffies = now;
+ return;
+ }
/* Update once a second */
- if (((jiffies - stats->rx_fps_jiffies) < HZ) || rx_eq->enable_aic == 0)
+ if ((now - stats->rx_fps_jiffies) < HZ)
return;
stats->be_rx_fps = (stats->be_rx_frags - stats->be_prev_rx_frags) /
- ((jiffies - stats->rx_fps_jiffies) / HZ);
+ ((now - stats->rx_fps_jiffies) / HZ);
- stats->rx_fps_jiffies = jiffies;
+ stats->rx_fps_jiffies = now;
stats->be_prev_rx_frags = stats->be_rx_frags;
eqd = stats->be_rx_fps / 110000;
eqd = eqd << 3;
@@ -273,53 +284,54 @@ static void be_rx_eqd_update(struct be_adapter *adapter)
rx_eq->cur_eqd = eqd;
}
-static void be_worker(struct work_struct *work)
+static struct net_device_stats *be_get_stats(struct net_device *dev)
{
- struct be_adapter *adapter =
- container_of(work, struct be_adapter, work.work);
- int status;
+ struct be_adapter *adapter = netdev_priv(dev);
- /* Check link */
- be_link_status_update(adapter);
+ return &adapter->stats.net_stats;
+}
- /* Get Stats */
- status = be_cmd_get_stats(&adapter->ctrl, &adapter->stats.cmd);
- if (!status)
- netdev_stats_update(adapter);
+static u32 be_calc_rate(u64 bytes, unsigned long ticks)
+{
+ u64 rate = bytes;
- /* Set EQ delay */
- be_rx_eqd_update(adapter);
+ do_div(rate, ticks / HZ);
+ rate <<= 3; /* bytes/sec -> bits/sec */
+ do_div(rate, 1000000ul); /* MB/Sec */
- schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
+ return rate;
}
-static struct net_device_stats *be_get_stats(struct net_device *dev)
+static void be_tx_rate_update(struct be_adapter *adapter)
{
- struct be_adapter *adapter = netdev_priv(dev);
+ struct be_drvr_stats *stats = drvr_stats(adapter);
+ ulong now = jiffies;
- return &adapter->stats.net_stats;
+ /* Wrapped around? */
+ if (time_before(now, stats->be_tx_jiffies)) {
+ stats->be_tx_jiffies = now;
+ return;
+ }
+
+ /* Update tx rate once in two seconds */
+ if ((now - stats->be_tx_jiffies) > 2 * HZ) {
+ stats->be_tx_rate = be_calc_rate(stats->be_tx_bytes
+ - stats->be_tx_bytes_prev,
+ now - stats->be_tx_jiffies);
+ stats->be_tx_jiffies = now;
+ stats->be_tx_bytes_prev = stats->be_tx_bytes;
+ }
}
static void be_tx_stats_update(struct be_adapter *adapter,
u32 wrb_cnt, u32 copied, bool stopped)
{
- struct be_drvr_stats *stats = &adapter->stats.drvr_stats;
+ struct be_drvr_stats *stats = drvr_stats(adapter);
stats->be_tx_reqs++;
stats->be_tx_wrbs += wrb_cnt;
stats->be_tx_bytes += copied;
if (stopped)
stats->be_tx_stops++;
-
- /* Update tx rate once in two seconds */
- if ((jiffies - stats->be_tx_jiffies) > 2 * HZ) {
- u32 r;
- r = (stats->be_tx_bytes - stats->be_tx_bytes_prev) /
- ((u32) (jiffies - stats->be_tx_jiffies) / HZ);
- r = (r / 1000000); /* M bytes/s */
- stats->be_tx_rate = (r * 8); /* M bits/s */
- stats->be_tx_jiffies = jiffies;
- stats->be_tx_bytes_prev = stats->be_tx_bytes;
- }
}
/* Determine number of WRB entries needed to xmit data in an skb */
@@ -493,7 +505,7 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu)
* program them in BE. If more than BE_NUM_VLANS_SUPPORTED are configured,
* set the BE in promiscuous VLAN mode.
*/
-static void be_vids_config(struct net_device *netdev)
+static void be_vid_config(struct net_device *netdev)
{
struct be_adapter *adapter = netdev_priv(netdev);
u16 vtag[BE_NUM_VLANS_SUPPORTED];
@@ -536,7 +548,7 @@ static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
adapter->num_vlans++;
adapter->vlan_tag[vid] = 1;
- be_vids_config(netdev);
+ be_vid_config(netdev);
}
static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
@@ -547,7 +559,7 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
adapter->vlan_tag[vid] = 0;
vlan_group_set_device(adapter->vlan_grp, vid, NULL);
- be_vids_config(netdev);
+ be_vid_config(netdev);
}
static void be_set_multicast_filter(struct net_device *netdev)
@@ -593,28 +605,38 @@ static void be_set_multicast_list(struct net_device *netdev)
}
}
-static void be_rx_rate_update(struct be_adapter *adapter, u32 pktsize,
- u16 numfrags)
+static void be_rx_rate_update(struct be_adapter *adapter)
{
- struct be_drvr_stats *stats = &adapter->stats.drvr_stats;
- u32 rate;
+ struct be_drvr_stats *stats = drvr_stats(adapter);
+ ulong now = jiffies;
- stats->be_rx_compl++;
- stats->be_rx_frags += numfrags;
- stats->be_rx_bytes += pktsize;
+ /* Wrapped around */
+ if (time_before(now, stats->be_rx_jiffies)) {
+ stats->be_rx_jiffies = now;
+ return;
+ }
/* Update the rate once in two seconds */
- if ((jiffies - stats->be_rx_jiffies) < 2 * HZ)
+ if ((now - stats->be_rx_jiffies) < 2 * HZ)
return;
- rate = (stats->be_rx_bytes - stats->be_rx_bytes_prev) /
- ((u32) (jiffies - stats->be_rx_jiffies) / HZ);
- rate = (rate / 1000000); /* MB/Sec */
- stats->be_rx_rate = (rate * 8); /* Mega Bits/Sec */
- stats->be_rx_jiffies = jiffies;
+ stats->be_rx_rate = be_calc_rate(stats->be_rx_bytes
+ - stats->be_rx_bytes_prev,
+ now - stats->be_rx_jiffies);
+ stats->be_rx_jiffies = now;
stats->be_rx_bytes_prev = stats->be_rx_bytes;
}
+static void be_rx_stats_update(struct be_adapter *adapter,
+ u32 pktsize, u16 numfrags)
+{
+ struct be_drvr_stats *stats = drvr_stats(adapter);
+
+ stats->be_rx_compl++;
+ stats->be_rx_frags += numfrags;
+ stats->be_rx_bytes += pktsize;
+}
+
static struct be_rx_page_info *
get_rx_page_info(struct be_adapter *adapter, u16 frag_idx)
{
@@ -720,7 +742,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
memset(page_info, 0, sizeof(*page_info));
}
- be_rx_rate_update(adapter, pktsize, num_rcvd);
+ be_rx_stats_update(adapter, pktsize, num_rcvd);
return;
}
@@ -819,7 +841,7 @@ static void be_rx_compl_process_lro(struct be_adapter *adapter,
vid, NULL, 0);
}
- be_rx_rate_update(adapter, pkt_size, num_rcvd);
+ be_rx_stats_update(adapter, pkt_size, num_rcvd);
return;
}
@@ -861,7 +883,6 @@ static void be_post_rx_frags(struct be_adapter *adapter)
u64 page_dmaaddr = 0, frag_dmaaddr;
u32 posted, page_offset = 0;
-
page_info = &page_info_tbl[rxq->head];
for (posted = 0; posted < MAX_RX_POST && !page_info->page; posted++) {
if (!pagep) {
@@ -900,8 +921,11 @@ static void be_post_rx_frags(struct be_adapter *adapter)
page_info->last_page_user = true;
if (posted) {
- be_rxq_notify(&adapter->ctrl, rxq->id, posted);
atomic_add(posted, &rxq->used);
+ be_rxq_notify(&adapter->ctrl, rxq->id, posted);
+ } else if (atomic_read(&rxq->used) == 0) {
+ /* Let be_worker replenish when memory is available */
+ adapter->rx_post_starved = true;
}
return;
@@ -1305,6 +1329,34 @@ int be_poll_tx(struct napi_struct *napi, int budget)
return 1;
}
+static void be_worker(struct work_struct *work)
+{
+ struct be_adapter *adapter =
+ container_of(work, struct be_adapter, work.work);
+ int status;
+
+ /* Check link */
+ be_link_status_update(adapter);
+
+ /* Get Stats */
+ status = be_cmd_get_stats(&adapter->ctrl, &adapter->stats.cmd);
+ if (!status)
+ netdev_stats_update(adapter);
+
+ /* Set EQ delay */
+ be_rx_eqd_update(adapter);
+
+ be_tx_rate_update(adapter);
+ be_rx_rate_update(adapter);
+
+ if (adapter->rx_post_starved) {
+ adapter->rx_post_starved = false;
+ be_post_rx_frags(adapter);
+ }
+
+ schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
+}
+
static void be_msix_enable(struct be_adapter *adapter)
{
int i, status;
@@ -1422,6 +1474,8 @@ static int be_open(struct net_device *netdev)
if (status != 0)
goto do_none;
+ be_vid_config(netdev);
+
status = be_cmd_set_flow_control(ctrl, true, true);
if (status != 0)
goto if_destroy;
@@ -1856,8 +1910,6 @@ static int be_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, 0);
pci_restore_state(pdev);
- be_vids_config(netdev);
-
if (netif_running(netdev)) {
rtnl_lock();
be_open(netdev);
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 78e31aa861e0..9afe8092dfc4 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -415,11 +415,11 @@ static int mii_probe(struct net_device *dev)
}
#if defined(CONFIG_BFIN_MAC_RMII)
- phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0,
- PHY_INTERFACE_MODE_RMII);
+ phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link,
+ 0, PHY_INTERFACE_MODE_RMII);
#else
- phydev = phy_connect(dev, phydev->dev.bus_id, &bfin_mac_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
+ phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link,
+ 0, PHY_INTERFACE_MODE_MII);
#endif
if (IS_ERR(phydev)) {
@@ -447,7 +447,7 @@ static int mii_probe(struct net_device *dev)
printk(KERN_INFO "%s: attached PHY driver [%s] "
"(mii_bus:phy_addr=%s, irq=%d, mdc_clk=%dHz(mdc_div=%d)"
"@sclk=%dMHz)\n",
- DRV_NAME, phydev->drv->name, phydev->dev.bus_id, phydev->irq,
+ DRV_NAME, phydev->drv->name, dev_name(&phydev->dev), phydev->irq,
MDC_CLK, mdc_div, sclk/1000000);
return 0;
@@ -488,7 +488,7 @@ static void bfin_mac_ethtool_getdrvinfo(struct net_device *dev,
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
strcpy(info->fw_version, "N/A");
- strcpy(info->bus_info, dev->dev.bus_id);
+ strcpy(info->bus_info, dev_name(&dev->dev));
}
static struct ethtool_ops bfin_mac_ethtool_ops = {
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 8a546a33d581..44d015f70d1c 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1062,7 +1062,6 @@ static int miscintcount;
static irqreturn_t bmac_misc_intr(int irq, void *dev_id)
{
struct net_device *dev = (struct net_device *) dev_id;
- struct bmac_data *bp = netdev_priv(dev);
unsigned int status = bmread(dev, STATUS);
if (miscintcount++ < 10) {
XXDEBUG(("bmac_misc_intr\n"));
@@ -1240,7 +1239,7 @@ static void bmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *inf
{
struct bmac_data *bp = netdev_priv(dev);
strcpy(info->driver, "bmac");
- strcpy(info->bus_info, bp->mdev->ofdev.dev.bus_id);
+ strcpy(info->bus_info, dev_name(&bp->mdev->ofdev.dev));
}
static const struct ethtool_ops bmac_ethtool_ops = {
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 6500b7c4739f..ad446db8e186 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -57,8 +57,8 @@
#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.9.2"
-#define DRV_MODULE_RELDATE "Feb 11, 2009"
+#define DRV_MODULE_VERSION "1.9.3"
+#define DRV_MODULE_RELDATE "March 17, 2009"
#define RUN_AT(x) (jiffies + (x))
@@ -1497,6 +1497,8 @@ static int bnx2_fw_sync(struct bnx2 *, u32, int, int);
static int
bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
u32 speed_arg = 0, pause_adv;
@@ -1554,6 +1556,8 @@ bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
static int
bnx2_setup_serdes_phy(struct bnx2 *bp, u8 port)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
u32 adv, bmcr;
u32 new_adv = 0;
@@ -1866,6 +1870,8 @@ bnx2_set_remote_link(struct bnx2 *bp)
static int
bnx2_setup_copper_phy(struct bnx2 *bp)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
u32 bmcr;
u32 new_bmcr;
@@ -1963,6 +1969,8 @@ bnx2_setup_copper_phy(struct bnx2 *bp)
static int
bnx2_setup_phy(struct bnx2 *bp, u8 port)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
if (bp->loopback == MAC_LOOPBACK)
return 0;
@@ -2176,6 +2184,8 @@ bnx2_init_copper_phy(struct bnx2 *bp, int reset_phy)
static int
bnx2_init_phy(struct bnx2 *bp, int reset_phy)
+__releases(&bp->phy_lock)
+__acquires(&bp->phy_lock)
{
u32 val;
int rc = 0;
@@ -3005,6 +3015,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
skb->ip_summed = CHECKSUM_UNNECESSARY;
}
+ skb_record_rx_queue(skb, bnapi - &bp->bnx2_napi[0]);
+
#ifdef BCM_VLAN
if (hw_vlan)
vlan_hwaccel_receive_skb(skb, bp->vlgrp, vtag);
@@ -3061,7 +3073,7 @@ bnx2_msi(int irq, void *dev_instance)
if (unlikely(atomic_read(&bp->intr_sem) != 0))
return IRQ_HANDLED;
- netif_rx_schedule(&bnapi->napi);
+ napi_schedule(&bnapi->napi);
return IRQ_HANDLED;
}
@@ -3078,7 +3090,7 @@ bnx2_msi_1shot(int irq, void *dev_instance)
if (unlikely(atomic_read(&bp->intr_sem) != 0))
return IRQ_HANDLED;
- netif_rx_schedule(&bnapi->napi);
+ napi_schedule(&bnapi->napi);
return IRQ_HANDLED;
}
@@ -3114,9 +3126,9 @@ bnx2_interrupt(int irq, void *dev_instance)
if (unlikely(atomic_read(&bp->intr_sem) != 0))
return IRQ_HANDLED;
- if (netif_rx_schedule_prep(&bnapi->napi)) {
+ if (napi_schedule_prep(&bnapi->napi)) {
bnapi->last_status_idx = sblk->status_idx;
- __netif_rx_schedule(&bnapi->napi);
+ __napi_schedule(&bnapi->napi);
}
return IRQ_HANDLED;
@@ -3226,7 +3238,7 @@ static int bnx2_poll_msix(struct napi_struct *napi, int budget)
rmb();
if (likely(!bnx2_has_fast_work(bnapi))) {
- netif_rx_complete(napi);
+ napi_complete(napi);
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
bnapi->last_status_idx);
@@ -3259,7 +3271,7 @@ static int bnx2_poll(struct napi_struct *napi, int budget)
rmb();
if (likely(!bnx2_has_work(bnapi))) {
- netif_rx_complete(napi);
+ napi_complete(napi);
if (likely(bp->flags & BNX2_FLAG_USING_MSI_OR_MSIX)) {
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
@@ -5843,9 +5855,6 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
msix_ent[i].entry = i;
msix_ent[i].vector = 0;
-
- snprintf(bp->irq_tbl[i].name, len, "%s-%d", dev->name, i);
- bp->irq_tbl[i].handler = bnx2_msi_1shot;
}
rc = pci_enable_msix(bp->pdev, msix_ent, BNX2_MAX_MSIX_VEC);
@@ -5854,8 +5863,11 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
bp->irq_nvecs = msix_vecs;
bp->flags |= BNX2_FLAG_USING_MSIX | BNX2_FLAG_ONE_SHOT_MSI;
- for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
+ for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
bp->irq_tbl[i].vector = msix_ent[i].vector;
+ snprintf(bp->irq_tbl[i].name, len, "%s-%d", dev->name, i);
+ bp->irq_tbl[i].handler = bnx2_msi_1shot;
+ }
}
static void
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 3cf2b92eef3b..a329bee25550 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -25,6 +25,16 @@
#endif
+#define BNX2X_MULTI_QUEUE
+
+#define BNX2X_NEW_NAPI
+
+
+#include "bnx2x_reg.h"
+#include "bnx2x_fw_defs.h"
+#include "bnx2x_hsi.h"
+#include "bnx2x_link.h"
+
/* error/debug prints */
#define DRV_MODULE_NAME "bnx2x"
@@ -92,12 +102,10 @@
#define REG_RD(bp, offset) readl(REG_ADDR(bp, offset))
#define REG_RD8(bp, offset) readb(REG_ADDR(bp, offset))
-#define REG_RD64(bp, offset) readq(REG_ADDR(bp, offset))
#define REG_WR(bp, offset, val) writel((u32)val, REG_ADDR(bp, offset))
#define REG_WR8(bp, offset, val) writeb((u8)val, REG_ADDR(bp, offset))
#define REG_WR16(bp, offset, val) writew((u16)val, REG_ADDR(bp, offset))
-#define REG_WR32(bp, offset, val) REG_WR(bp, offset, val)
#define REG_RD_IND(bp, offset) bnx2x_reg_rd_ind(bp, offset)
#define REG_WR_IND(bp, offset, val) bnx2x_reg_wr_ind(bp, offset, val)
@@ -154,8 +162,6 @@ struct sw_rx_page {
#define SGE_PAGE_SHIFT PAGE_SHIFT
#define SGE_PAGE_ALIGN(addr) PAGE_ALIGN((typeof(PAGE_SIZE))addr)
-#define BCM_RX_ETH_PAYLOAD_ALIGN 64
-
/* SGE ring related macros */
#define NUM_RX_SGE_PAGES 2
#define RX_SGE_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_sge))
@@ -187,6 +193,43 @@ struct sw_rx_page {
#define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK)
+struct bnx2x_eth_q_stats {
+ u32 total_bytes_received_hi;
+ u32 total_bytes_received_lo;
+ u32 total_bytes_transmitted_hi;
+ u32 total_bytes_transmitted_lo;
+ u32 total_unicast_packets_received_hi;
+ u32 total_unicast_packets_received_lo;
+ u32 total_multicast_packets_received_hi;
+ u32 total_multicast_packets_received_lo;
+ u32 total_broadcast_packets_received_hi;
+ u32 total_broadcast_packets_received_lo;
+ u32 total_unicast_packets_transmitted_hi;
+ u32 total_unicast_packets_transmitted_lo;
+ u32 total_multicast_packets_transmitted_hi;
+ u32 total_multicast_packets_transmitted_lo;
+ u32 total_broadcast_packets_transmitted_hi;
+ u32 total_broadcast_packets_transmitted_lo;
+ u32 valid_bytes_received_hi;
+ u32 valid_bytes_received_lo;
+
+ u32 error_bytes_received_hi;
+ u32 error_bytes_received_lo;
+ u32 etherstatsoverrsizepkts_hi;
+ u32 etherstatsoverrsizepkts_lo;
+ u32 no_buff_discard_hi;
+ u32 no_buff_discard_lo;
+
+ u32 driver_xoff;
+ u32 rx_err_discard_pkt;
+ u32 rx_skb_alloc_failed;
+ u32 hw_csum_err;
+};
+
+#define BNX2X_NUM_Q_STATS 11
+#define Q_STATS_OFFSET32(stat_name) \
+ (offsetof(struct bnx2x_eth_q_stats, stat_name) / 4)
+
struct bnx2x_fastpath {
struct napi_struct napi;
@@ -228,20 +271,15 @@ struct bnx2x_fastpath {
u8 index; /* number in fp array */
u8 cl_id; /* eth client id */
u8 sb_id; /* status block number in HW */
-#define FP_IDX(fp) (fp->index)
-#define FP_CL_ID(fp) (fp->cl_id)
-#define BP_CL_ID(bp) (bp->fp[0].cl_id)
-#define FP_SB_ID(fp) (fp->sb_id)
-#define CNIC_SB_ID 0
u16 tx_pkt_prod;
u16 tx_pkt_cons;
u16 tx_bd_prod;
u16 tx_bd_cons;
- u16 *tx_cons_sb;
+ __le16 *tx_cons_sb;
- u16 fp_c_idx;
- u16 fp_u_idx;
+ __le16 fp_c_idx;
+ __le16 fp_u_idx;
u16 rx_bd_prod;
u16 rx_bd_cons;
@@ -250,8 +288,8 @@ struct bnx2x_fastpath {
u16 rx_sge_prod;
/* The last maximal completed SGE */
u16 last_max_sge;
- u16 *rx_cons_sb;
- u16 *rx_bd_cons_sb;
+ __le16 *rx_cons_sb;
+ __le16 *rx_bd_cons_sb;
unsigned long tx_pkt,
rx_pkt,
@@ -266,6 +304,12 @@ struct bnx2x_fastpath {
u64 tpa_queue_used;
#endif
+ struct tstorm_per_client_stats old_tclient;
+ struct ustorm_per_client_stats old_uclient;
+ struct xstorm_per_client_stats old_xclient;
+ struct bnx2x_eth_q_stats eth_q_stats;
+
+ char name[IFNAMSIZ];
struct bnx2x *bp; /* parent */
};
@@ -401,10 +445,13 @@ struct bnx2x_fastpath {
#define BNX2X_RX_CSUM_OK(cqe) \
(!(BNX2X_L4_CSUM_ERR(cqe) || BNX2X_IP_CSUM_ERR(cqe)))
+#define BNX2X_PRS_FLAG_OVERETH_IPV4(flags) \
+ (((le16_to_cpu(flags) & \
+ PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) >> \
+ PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT) \
+ == PRS_FLAG_OVERETH_IPV4)
#define BNX2X_RX_SUM_FIX(cqe) \
- ((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & \
- PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) == \
- (1 << PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT))
+ BNX2X_PRS_FLAG_OVERETH_IPV4(cqe->fast_path_cqe.pars_flags.flags)
#define FP_USB_FUNC_OFF (2 + 2*HC_USTORM_SB_NUM_INDICES)
@@ -478,11 +525,8 @@ struct bnx2x_common {
u32 shmem_base;
u32 hw_config;
- u32 board;
u32 bc_ver;
-
- char *name;
};
@@ -528,6 +572,7 @@ struct bnx2x_port {
/* used to synchronize phy accesses */
struct mutex phy_mutex;
+ int need_hw_lock;
u32 port_stx;
@@ -573,6 +618,10 @@ struct bnx2x_eth_stats {
u32 error_bytes_received_hi;
u32 error_bytes_received_lo;
+ u32 etherstatsoverrsizepkts_hi;
+ u32 etherstatsoverrsizepkts_lo;
+ u32 no_buff_discard_hi;
+ u32 no_buff_discard_lo;
u32 rx_stat_ifhcinbadoctets_hi;
u32 rx_stat_ifhcinbadoctets_lo;
@@ -651,19 +700,20 @@ struct bnx2x_eth_stats {
u32 tx_stat_bmac_ufl_hi;
u32 tx_stat_bmac_ufl_lo;
- u32 brb_drop_hi;
- u32 brb_drop_lo;
- u32 brb_truncate_hi;
- u32 brb_truncate_lo;
-
- u32 jabber_packets_received;
+ u32 pause_frames_received_hi;
+ u32 pause_frames_received_lo;
+ u32 pause_frames_sent_hi;
+ u32 pause_frames_sent_lo;
u32 etherstatspkts1024octetsto1522octets_hi;
u32 etherstatspkts1024octetsto1522octets_lo;
u32 etherstatspktsover1522octets_hi;
u32 etherstatspktsover1522octets_lo;
- u32 no_buff_discard;
+ u32 brb_drop_hi;
+ u32 brb_drop_lo;
+ u32 brb_truncate_hi;
+ u32 brb_truncate_lo;
u32 mac_filter_discard;
u32 xxoverflow_discard;
@@ -674,17 +724,16 @@ struct bnx2x_eth_stats {
u32 rx_err_discard_pkt;
u32 rx_skb_alloc_failed;
u32 hw_csum_err;
+
+ u32 nig_timer_max;
};
+#define BNX2X_NUM_STATS 41
#define STATS_OFFSET32(stat_name) \
(offsetof(struct bnx2x_eth_stats, stat_name) / 4)
-#ifdef BNX2X_MULTI
#define MAX_CONTEXT 16
-#else
-#define MAX_CONTEXT 1
-#endif
union cdu_context {
struct eth_context eth;
@@ -739,6 +788,9 @@ struct bnx2x {
atomic_t intr_sem;
struct msix_entry msix_table[MAX_CONTEXT+1];
+#define INT_MODE_INTx 1
+#define INT_MODE_MSI 2
+#define INT_MODE_MSIX 3
int tx_ring_size;
@@ -747,23 +799,26 @@ struct bnx2x {
#endif
u32 rx_csum;
- u32 rx_offset;
u32 rx_buf_size;
#define ETH_OVREHEAD (ETH_HLEN + 8) /* 8 for CRC + VLAN */
#define ETH_MIN_PACKET_SIZE 60
#define ETH_MAX_PACKET_SIZE 1500
#define ETH_MAX_JUMBO_PACKET_SIZE 9600
+ /* Max supported alignment is 256 (8 shift) */
+#define BNX2X_RX_ALIGN_SHIFT ((L1_CACHE_SHIFT < 8) ? \
+ L1_CACHE_SHIFT : 8)
+#define BNX2X_RX_ALIGN (1 << BNX2X_RX_ALIGN_SHIFT)
+
struct host_def_status_block *def_status_blk;
#define DEF_SB_ID 16
- u16 def_c_idx;
- u16 def_u_idx;
- u16 def_x_idx;
- u16 def_t_idx;
- u16 def_att_idx;
+ __le16 def_c_idx;
+ __le16 def_u_idx;
+ __le16 def_x_idx;
+ __le16 def_t_idx;
+ __le16 def_att_idx;
u32 attn_state;
struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS];
- u32 nig_mask;
/* slow path ring */
struct eth_spe *spq;
@@ -771,7 +826,7 @@ struct bnx2x {
u16 spq_prod_idx;
struct eth_spe *spq_prod_bd;
struct eth_spe *spq_last_bd;
- u16 *dsb_sp_prod;
+ __le16 *dsb_sp_prod;
u16 spq_left; /* serialize spq */
/* used to synchronize spq accesses */
spinlock_t spq_lock;
@@ -789,11 +844,11 @@ struct bnx2x {
u32 flags;
#define PCIX_FLAG 1
#define PCI_32BIT_FLAG 2
-#define ONE_TDMA_FLAG 4 /* no longer used */
+#define ONE_PORT_FLAG 4
#define NO_WOL_FLAG 8
#define USING_DAC_FLAG 0x10
#define USING_MSIX_FLAG 0x20
-#define ASF_ENABLE_FLAG 0x40
+#define USING_MSI_FLAG 0x40
#define TPA_ENABLE_FLAG 0x80
#define NO_MCP_FLAG 0x100
#define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG)
@@ -808,12 +863,12 @@ struct bnx2x {
int pm_cap;
int pcie_cap;
+ int mrrs;
struct delayed_work sp_task;
struct work_struct reset_task;
struct timer_list timer;
- int timer_interval;
int current_interval;
u16 fw_seq;
@@ -826,6 +881,9 @@ struct bnx2x {
struct bnx2x_common common;
struct bnx2x_port port;
+ struct cmng_struct_per_port cmng;
+ u32 vn_weight_sum;
+
u32 mf_config;
u16 e1hov;
u8 e1hmf;
@@ -848,7 +906,7 @@ struct bnx2x {
u32 lin_cnt;
int state;
-#define BNX2X_STATE_CLOSED 0x0
+#define BNX2X_STATE_CLOSED 0
#define BNX2X_STATE_OPENING_WAIT4_LOAD 0x1000
#define BNX2X_STATE_OPENING_WAIT4_PORT 0x2000
#define BNX2X_STATE_OPEN 0x3000
@@ -859,8 +917,9 @@ struct bnx2x {
#define BNX2X_STATE_DIAG 0xe000
#define BNX2X_STATE_ERROR 0xf000
- int num_queues;
-#define BP_MAX_QUEUES(bp) (IS_E1HMF(bp) ? 4 : 16)
+ int multi_mode;
+ int num_rx_queues;
+ int num_tx_queues;
u32 rx_mode;
#define BNX2X_RX_MODE_NONE 0
@@ -898,8 +957,6 @@ struct bnx2x {
int executer_idx;
u16 stats_counter;
- struct tstorm_per_client_stats old_tclient;
- struct xstorm_per_client_stats old_xclient;
struct bnx2x_eth_stats eth_stats;
struct z_stream_s *strm;
@@ -911,17 +968,27 @@ struct bnx2x {
};
-#define for_each_queue(bp, var) for (var = 0; var < bp->num_queues; var++)
+#define BNX2X_MAX_QUEUES(bp) (IS_E1HMF(bp) ? (MAX_CONTEXT / E1HVN_MAX) : \
+ MAX_CONTEXT)
+#define BNX2X_NUM_QUEUES(bp) max(bp->num_rx_queues, bp->num_tx_queues)
+#define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1)
+#define for_each_rx_queue(bp, var) \
+ for (var = 0; var < bp->num_rx_queues; var++)
+#define for_each_tx_queue(bp, var) \
+ for (var = 0; var < bp->num_tx_queues; var++)
+#define for_each_queue(bp, var) \
+ for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++)
#define for_each_nondefault_queue(bp, var) \
- for (var = 1; var < bp->num_queues; var++)
-#define is_multi(bp) (bp->num_queues > 1)
+ for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++)
void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
u32 len32);
+int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port);
int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
+int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
int wait)
@@ -992,13 +1059,12 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define PCICFG_LINK_SPEED_SHIFT 16
-#define BNX2X_NUM_STATS 42
-#define BNX2X_NUM_TESTS 8
+#define BNX2X_NUM_TESTS 7
-#define BNX2X_MAC_LOOPBACK 0
-#define BNX2X_PHY_LOOPBACK 1
-#define BNX2X_MAC_LOOPBACK_FAILED 1
-#define BNX2X_PHY_LOOPBACK_FAILED 2
+#define BNX2X_PHY_LOOPBACK 0
+#define BNX2X_MAC_LOOPBACK 1
+#define BNX2X_PHY_LOOPBACK_FAILED 1
+#define BNX2X_MAC_LOOPBACK_FAILED 2
#define BNX2X_LOOPBACK_FAILED (BNX2X_MAC_LOOPBACK_FAILED | \
BNX2X_PHY_LOOPBACK_FAILED)
@@ -1061,9 +1127,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define BNX2X_MCP_ASSERT \
GENERAL_ATTEN_OFFSET(MCP_FATAL_ASSERT_ATTENTION_BIT)
-#define BNX2X_DOORQ_ASSERT \
- AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT
-
#define BNX2X_GRC_TIMEOUT GENERAL_ATTEN_OFFSET(LATCHED_ATTN_TIMEOUT_GRC)
#define BNX2X_GRC_RSV (GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCR) | \
GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCT) | \
@@ -1120,12 +1183,13 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR)
-#define MULTI_FLAGS \
+#define MULTI_FLAGS(bp) \
(TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY | \
TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY | \
TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY | \
TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY | \
- TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE)
+ (bp->multi_mode << \
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT))
#define MULTI_MASK 0x7f
diff --git a/drivers/net/bnx2x_dump.h b/drivers/net/bnx2x_dump.h
new file mode 100644
index 000000000000..78c6b0353ad8
--- /dev/null
+++ b/drivers/net/bnx2x_dump.h
@@ -0,0 +1,526 @@
+/* bnx2x_dump.h: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2009 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ */
+
+
+/* This struct holds a signature to ensure the dump returned from the driver
+ * match the meta data file inserted to grc_dump.tcl
+ * The signature is time stamp, diag version and grc_dump version
+ */
+
+struct dump_sign {
+ u32 time_stamp;
+ u32 diag_ver;
+ u32 grc_dump_ver;
+};
+
+#define TSTORM_WAITP_ADDR 0x1b8a80
+#define CSTORM_WAITP_ADDR 0x238a80
+#define XSTORM_WAITP_ADDR 0x2b8a80
+#define USTORM_WAITP_ADDR 0x338a80
+#define TSTORM_CAM_MODE 0x1b1440
+
+#define RI_E1 0x1
+#define RI_E1H 0x2
+#define RI_ONLINE 0x100
+
+#define RI_E1_OFFLINE (RI_E1)
+#define RI_E1_ONLINE (RI_E1 | RI_ONLINE)
+#define RI_E1H_OFFLINE (RI_E1H)
+#define RI_E1H_ONLINE (RI_E1H | RI_ONLINE)
+#define RI_ALL_OFFLINE (RI_E1 | RI_E1H)
+#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_ONLINE)
+
+#define MAX_TIMER_PENDING 200
+#define TIMER_SCAN_DONT_CARE 0xFF
+
+
+struct dump_hdr {
+ u32 hdr_size; /* in dwords, excluding this field */
+ struct dump_sign dump_sign;
+ u32 xstorm_waitp;
+ u32 tstorm_waitp;
+ u32 ustorm_waitp;
+ u32 cstorm_waitp;
+ u16 info;
+ u8 idle_chk;
+ u8 reserved;
+};
+
+struct reg_addr {
+ u32 addr;
+ u32 size;
+ u16 info;
+};
+
+struct wreg_addr {
+ u32 addr;
+ u32 size;
+ u32 read_regs_count;
+ const u32 *read_regs;
+ u16 info;
+};
+
+
+#define REGS_COUNT 558
+static const struct reg_addr reg_addrs[REGS_COUNT] = {
+ { 0x2000, 341, RI_ALL_ONLINE}, { 0x2800, 103, RI_ALL_ONLINE},
+ { 0x3000, 287, RI_ALL_ONLINE}, { 0x3800, 331, RI_ALL_ONLINE},
+ { 0x8800, 6, RI_E1_ONLINE}, { 0xa000, 223, RI_ALL_ONLINE},
+ { 0xa388, 1, RI_ALL_ONLINE}, { 0xa398, 1, RI_ALL_ONLINE},
+ { 0xa39c, 7, RI_E1H_ONLINE}, { 0xa3c0, 3, RI_E1H_ONLINE},
+ { 0xa3d0, 1, RI_E1H_ONLINE}, { 0xa3d8, 1, RI_E1H_ONLINE},
+ { 0xa3e0, 1, RI_E1H_ONLINE}, { 0xa3e8, 1, RI_E1H_ONLINE},
+ { 0xa3f0, 1, RI_E1H_ONLINE}, { 0xa3f8, 1, RI_E1H_ONLINE},
+ { 0xa400, 69, RI_ALL_ONLINE}, { 0xa518, 1, RI_ALL_ONLINE},
+ { 0xa520, 1, RI_ALL_ONLINE}, { 0xa528, 1, RI_ALL_ONLINE},
+ { 0xa530, 1, RI_ALL_ONLINE}, { 0xa538, 1, RI_ALL_ONLINE},
+ { 0xa540, 1, RI_ALL_ONLINE}, { 0xa548, 1, RI_ALL_ONLINE},
+ { 0xa550, 1, RI_ALL_ONLINE}, { 0xa558, 1, RI_ALL_ONLINE},
+ { 0xa560, 1, RI_ALL_ONLINE}, { 0xa568, 1, RI_ALL_ONLINE},
+ { 0xa570, 1, RI_ALL_ONLINE}, { 0xa580, 1, RI_ALL_ONLINE},
+ { 0xa590, 1, RI_ALL_ONLINE}, { 0xa5a0, 1, RI_ALL_ONLINE},
+ { 0xa5c0, 1, RI_ALL_ONLINE}, { 0xa5e0, 1, RI_E1H_ONLINE},
+ { 0xa5e8, 1, RI_E1H_ONLINE}, { 0xa5f0, 1, RI_E1H_ONLINE},
+ { 0xa5f8, 10, RI_E1H_ONLINE}, { 0x10000, 236, RI_ALL_ONLINE},
+ { 0x103bc, 1, RI_ALL_ONLINE}, { 0x103cc, 1, RI_ALL_ONLINE},
+ { 0x103dc, 1, RI_ALL_ONLINE}, { 0x10400, 57, RI_ALL_ONLINE},
+ { 0x104e8, 2, RI_ALL_ONLINE}, { 0x104f4, 2, RI_ALL_ONLINE},
+ { 0x10500, 146, RI_ALL_ONLINE}, { 0x10750, 2, RI_ALL_ONLINE},
+ { 0x10760, 2, RI_ALL_ONLINE}, { 0x10770, 2, RI_ALL_ONLINE},
+ { 0x10780, 2, RI_ALL_ONLINE}, { 0x10790, 2, RI_ALL_ONLINE},
+ { 0x107a0, 2, RI_ALL_ONLINE}, { 0x107b0, 2, RI_ALL_ONLINE},
+ { 0x107c0, 2, RI_ALL_ONLINE}, { 0x107d0, 2, RI_ALL_ONLINE},
+ { 0x107e0, 2, RI_ALL_ONLINE}, { 0x10880, 2, RI_ALL_ONLINE},
+ { 0x10900, 2, RI_ALL_ONLINE}, { 0x12000, 1, RI_ALL_ONLINE},
+ { 0x14000, 1, RI_ALL_ONLINE}, { 0x16000, 26, RI_E1H_ONLINE},
+ { 0x16070, 18, RI_E1H_ONLINE}, { 0x160c0, 27, RI_E1H_ONLINE},
+ { 0x16140, 1, RI_E1H_ONLINE}, { 0x16160, 1, RI_E1H_ONLINE},
+ { 0x16180, 2, RI_E1H_ONLINE}, { 0x161c0, 2, RI_E1H_ONLINE},
+ { 0x16204, 5, RI_E1H_ONLINE}, { 0x18000, 1, RI_E1H_ONLINE},
+ { 0x18008, 1, RI_E1H_ONLINE}, { 0x20000, 24, RI_ALL_ONLINE},
+ { 0x20060, 8, RI_ALL_ONLINE}, { 0x20080, 138, RI_ALL_ONLINE},
+ { 0x202b4, 1, RI_ALL_ONLINE}, { 0x202c4, 1, RI_ALL_ONLINE},
+ { 0x20400, 2, RI_ALL_ONLINE}, { 0x2040c, 8, RI_ALL_ONLINE},
+ { 0x2042c, 18, RI_E1H_ONLINE}, { 0x20480, 1, RI_ALL_ONLINE},
+ { 0x20500, 1, RI_ALL_ONLINE}, { 0x20600, 1, RI_ALL_ONLINE},
+ { 0x28000, 1, RI_ALL_ONLINE}, { 0x28004, 8191, RI_ALL_OFFLINE},
+ { 0x30000, 1, RI_ALL_ONLINE}, { 0x30004, 16383, RI_ALL_OFFLINE},
+ { 0x40000, 98, RI_ALL_ONLINE}, { 0x40194, 1, RI_ALL_ONLINE},
+ { 0x401a4, 1, RI_ALL_ONLINE}, { 0x401a8, 11, RI_E1H_ONLINE},
+ { 0x40200, 4, RI_ALL_ONLINE}, { 0x40400, 43, RI_ALL_ONLINE},
+ { 0x404b8, 1, RI_ALL_ONLINE}, { 0x404c8, 1, RI_ALL_ONLINE},
+ { 0x404cc, 3, RI_E1H_ONLINE}, { 0x40500, 2, RI_ALL_ONLINE},
+ { 0x40510, 2, RI_ALL_ONLINE}, { 0x40520, 2, RI_ALL_ONLINE},
+ { 0x40530, 2, RI_ALL_ONLINE}, { 0x40540, 2, RI_ALL_ONLINE},
+ { 0x42000, 164, RI_ALL_ONLINE}, { 0x4229c, 1, RI_ALL_ONLINE},
+ { 0x422ac, 1, RI_ALL_ONLINE}, { 0x422bc, 1, RI_ALL_ONLINE},
+ { 0x422d4, 5, RI_E1H_ONLINE}, { 0x42400, 49, RI_ALL_ONLINE},
+ { 0x424c8, 38, RI_ALL_ONLINE}, { 0x42568, 2, RI_ALL_ONLINE},
+ { 0x42800, 1, RI_ALL_ONLINE}, { 0x50000, 20, RI_ALL_ONLINE},
+ { 0x50050, 8, RI_ALL_ONLINE}, { 0x50070, 88, RI_ALL_ONLINE},
+ { 0x501dc, 1, RI_ALL_ONLINE}, { 0x501ec, 1, RI_ALL_ONLINE},
+ { 0x501f0, 4, RI_E1H_ONLINE}, { 0x50200, 2, RI_ALL_ONLINE},
+ { 0x5020c, 7, RI_ALL_ONLINE}, { 0x50228, 6, RI_E1H_ONLINE},
+ { 0x50240, 1, RI_ALL_ONLINE}, { 0x50280, 1, RI_ALL_ONLINE},
+ { 0x52000, 1, RI_ALL_ONLINE}, { 0x54000, 1, RI_ALL_ONLINE},
+ { 0x54004, 3327, RI_ALL_OFFLINE}, { 0x58000, 1, RI_ALL_ONLINE},
+ { 0x58004, 8191, RI_ALL_OFFLINE}, { 0x60000, 71, RI_ALL_ONLINE},
+ { 0x60128, 1, RI_ALL_ONLINE}, { 0x60138, 1, RI_ALL_ONLINE},
+ { 0x6013c, 24, RI_E1H_ONLINE}, { 0x60200, 1, RI_ALL_ONLINE},
+ { 0x61000, 1, RI_ALL_ONLINE}, { 0x61004, 511, RI_ALL_OFFLINE},
+ { 0x70000, 8, RI_ALL_ONLINE}, { 0x70020, 21496, RI_ALL_OFFLINE},
+ { 0x85000, 3, RI_ALL_ONLINE}, { 0x8500c, 4, RI_ALL_OFFLINE},
+ { 0x8501c, 7, RI_ALL_ONLINE}, { 0x85038, 4, RI_ALL_OFFLINE},
+ { 0x85048, 1, RI_ALL_ONLINE}, { 0x8504c, 109, RI_ALL_OFFLINE},
+ { 0x85200, 32, RI_ALL_ONLINE}, { 0x85280, 11104, RI_ALL_OFFLINE},
+ { 0xa0000, 16384, RI_ALL_ONLINE}, { 0xb0000, 16384, RI_E1H_ONLINE},
+ { 0xc1000, 7, RI_ALL_ONLINE}, { 0xc1028, 1, RI_ALL_ONLINE},
+ { 0xc1038, 1, RI_ALL_ONLINE}, { 0xc1800, 2, RI_ALL_ONLINE},
+ { 0xc2000, 164, RI_ALL_ONLINE}, { 0xc229c, 1, RI_ALL_ONLINE},
+ { 0xc22ac, 1, RI_ALL_ONLINE}, { 0xc22bc, 1, RI_ALL_ONLINE},
+ { 0xc2400, 49, RI_ALL_ONLINE}, { 0xc24c8, 38, RI_ALL_ONLINE},
+ { 0xc2568, 2, RI_ALL_ONLINE}, { 0xc2600, 1, RI_ALL_ONLINE},
+ { 0xc4000, 165, RI_ALL_ONLINE}, { 0xc42a0, 1, RI_ALL_ONLINE},
+ { 0xc42b0, 1, RI_ALL_ONLINE}, { 0xc42c0, 1, RI_ALL_ONLINE},
+ { 0xc42e0, 7, RI_E1H_ONLINE}, { 0xc4400, 51, RI_ALL_ONLINE},
+ { 0xc44d0, 38, RI_ALL_ONLINE}, { 0xc4570, 2, RI_ALL_ONLINE},
+ { 0xc4600, 1, RI_ALL_ONLINE}, { 0xd0000, 19, RI_ALL_ONLINE},
+ { 0xd004c, 8, RI_ALL_ONLINE}, { 0xd006c, 91, RI_ALL_ONLINE},
+ { 0xd01e4, 1, RI_ALL_ONLINE}, { 0xd01f4, 1, RI_ALL_ONLINE},
+ { 0xd0200, 2, RI_ALL_ONLINE}, { 0xd020c, 7, RI_ALL_ONLINE},
+ { 0xd0228, 18, RI_E1H_ONLINE}, { 0xd0280, 1, RI_ALL_ONLINE},
+ { 0xd0300, 1, RI_ALL_ONLINE}, { 0xd0400, 1, RI_ALL_ONLINE},
+ { 0xd4000, 1, RI_ALL_ONLINE}, { 0xd4004, 2559, RI_ALL_OFFLINE},
+ { 0xd8000, 1, RI_ALL_ONLINE}, { 0xd8004, 8191, RI_ALL_OFFLINE},
+ { 0xe0000, 21, RI_ALL_ONLINE}, { 0xe0054, 8, RI_ALL_ONLINE},
+ { 0xe0074, 85, RI_ALL_ONLINE}, { 0xe01d4, 1, RI_ALL_ONLINE},
+ { 0xe01e4, 1, RI_ALL_ONLINE}, { 0xe0200, 2, RI_ALL_ONLINE},
+ { 0xe020c, 8, RI_ALL_ONLINE}, { 0xe022c, 18, RI_E1H_ONLINE},
+ { 0xe0280, 1, RI_ALL_ONLINE}, { 0xe0300, 1, RI_ALL_ONLINE},
+ { 0xe1000, 1, RI_ALL_ONLINE}, { 0xe2000, 1, RI_ALL_ONLINE},
+ { 0xe2004, 2047, RI_ALL_OFFLINE}, { 0xf0000, 1, RI_ALL_ONLINE},
+ { 0xf0004, 16383, RI_ALL_OFFLINE}, { 0x101000, 12, RI_ALL_ONLINE},
+ { 0x10103c, 1, RI_ALL_ONLINE}, { 0x10104c, 1, RI_ALL_ONLINE},
+ { 0x101050, 1, RI_E1H_ONLINE}, { 0x101100, 1, RI_ALL_ONLINE},
+ { 0x101800, 8, RI_ALL_ONLINE}, { 0x102000, 18, RI_ALL_ONLINE},
+ { 0x102054, 1, RI_ALL_ONLINE}, { 0x102064, 1, RI_ALL_ONLINE},
+ { 0x102080, 17, RI_ALL_ONLINE}, { 0x1020c8, 8, RI_E1H_ONLINE},
+ { 0x102400, 1, RI_ALL_ONLINE}, { 0x103000, 26, RI_ALL_ONLINE},
+ { 0x103074, 1, RI_ALL_ONLINE}, { 0x103084, 1, RI_ALL_ONLINE},
+ { 0x103094, 1, RI_ALL_ONLINE}, { 0x103098, 5, RI_E1H_ONLINE},
+ { 0x103800, 8, RI_ALL_ONLINE}, { 0x104000, 63, RI_ALL_ONLINE},
+ { 0x104108, 1, RI_ALL_ONLINE}, { 0x104118, 1, RI_ALL_ONLINE},
+ { 0x104200, 17, RI_ALL_ONLINE}, { 0x104400, 64, RI_ALL_ONLINE},
+ { 0x104500, 192, RI_ALL_OFFLINE}, { 0x104800, 64, RI_ALL_ONLINE},
+ { 0x104900, 192, RI_ALL_OFFLINE}, { 0x105000, 7, RI_ALL_ONLINE},
+ { 0x10501c, 1, RI_ALL_OFFLINE}, { 0x105020, 3, RI_ALL_ONLINE},
+ { 0x10502c, 1, RI_ALL_OFFLINE}, { 0x105030, 3, RI_ALL_ONLINE},
+ { 0x10503c, 1, RI_ALL_OFFLINE}, { 0x105040, 3, RI_ALL_ONLINE},
+ { 0x10504c, 1, RI_ALL_OFFLINE}, { 0x105050, 3, RI_ALL_ONLINE},
+ { 0x10505c, 1, RI_ALL_OFFLINE}, { 0x105060, 3, RI_ALL_ONLINE},
+ { 0x10506c, 1, RI_ALL_OFFLINE}, { 0x105070, 3, RI_ALL_ONLINE},
+ { 0x10507c, 1, RI_ALL_OFFLINE}, { 0x105080, 3, RI_ALL_ONLINE},
+ { 0x10508c, 1, RI_ALL_OFFLINE}, { 0x105090, 3, RI_ALL_ONLINE},
+ { 0x10509c, 1, RI_ALL_OFFLINE}, { 0x1050a0, 3, RI_ALL_ONLINE},
+ { 0x1050ac, 1, RI_ALL_OFFLINE}, { 0x1050b0, 3, RI_ALL_ONLINE},
+ { 0x1050bc, 1, RI_ALL_OFFLINE}, { 0x1050c0, 3, RI_ALL_ONLINE},
+ { 0x1050cc, 1, RI_ALL_OFFLINE}, { 0x1050d0, 3, RI_ALL_ONLINE},
+ { 0x1050dc, 1, RI_ALL_OFFLINE}, { 0x1050e0, 3, RI_ALL_ONLINE},
+ { 0x1050ec, 1, RI_ALL_OFFLINE}, { 0x1050f0, 3, RI_ALL_ONLINE},
+ { 0x1050fc, 1, RI_ALL_OFFLINE}, { 0x105100, 3, RI_ALL_ONLINE},
+ { 0x10510c, 1, RI_ALL_OFFLINE}, { 0x105110, 3, RI_ALL_ONLINE},
+ { 0x10511c, 1, RI_ALL_OFFLINE}, { 0x105120, 3, RI_ALL_ONLINE},
+ { 0x10512c, 1, RI_ALL_OFFLINE}, { 0x105130, 3, RI_ALL_ONLINE},
+ { 0x10513c, 1, RI_ALL_OFFLINE}, { 0x105140, 3, RI_ALL_ONLINE},
+ { 0x10514c, 1, RI_ALL_OFFLINE}, { 0x105150, 3, RI_ALL_ONLINE},
+ { 0x10515c, 1, RI_ALL_OFFLINE}, { 0x105160, 3, RI_ALL_ONLINE},
+ { 0x10516c, 1, RI_ALL_OFFLINE}, { 0x105170, 3, RI_ALL_ONLINE},
+ { 0x10517c, 1, RI_ALL_OFFLINE}, { 0x105180, 3, RI_ALL_ONLINE},
+ { 0x10518c, 1, RI_ALL_OFFLINE}, { 0x105190, 3, RI_ALL_ONLINE},
+ { 0x10519c, 1, RI_ALL_OFFLINE}, { 0x1051a0, 3, RI_ALL_ONLINE},
+ { 0x1051ac, 1, RI_ALL_OFFLINE}, { 0x1051b0, 3, RI_ALL_ONLINE},
+ { 0x1051bc, 1, RI_ALL_OFFLINE}, { 0x1051c0, 3, RI_ALL_ONLINE},
+ { 0x1051cc, 1, RI_ALL_OFFLINE}, { 0x1051d0, 3, RI_ALL_ONLINE},
+ { 0x1051dc, 1, RI_ALL_OFFLINE}, { 0x1051e0, 3, RI_ALL_ONLINE},
+ { 0x1051ec, 1, RI_ALL_OFFLINE}, { 0x1051f0, 3, RI_ALL_ONLINE},
+ { 0x1051fc, 1, RI_ALL_OFFLINE}, { 0x105200, 3, RI_ALL_ONLINE},
+ { 0x10520c, 1, RI_ALL_OFFLINE}, { 0x105210, 3, RI_ALL_ONLINE},
+ { 0x10521c, 1, RI_ALL_OFFLINE}, { 0x105220, 3, RI_ALL_ONLINE},
+ { 0x10522c, 1, RI_ALL_OFFLINE}, { 0x105230, 3, RI_ALL_ONLINE},
+ { 0x10523c, 1, RI_ALL_OFFLINE}, { 0x105240, 3, RI_ALL_ONLINE},
+ { 0x10524c, 1, RI_ALL_OFFLINE}, { 0x105250, 3, RI_ALL_ONLINE},
+ { 0x10525c, 1, RI_ALL_OFFLINE}, { 0x105260, 3, RI_ALL_ONLINE},
+ { 0x10526c, 1, RI_ALL_OFFLINE}, { 0x105270, 3, RI_ALL_ONLINE},
+ { 0x10527c, 1, RI_ALL_OFFLINE}, { 0x105280, 3, RI_ALL_ONLINE},
+ { 0x10528c, 1, RI_ALL_OFFLINE}, { 0x105290, 3, RI_ALL_ONLINE},
+ { 0x10529c, 1, RI_ALL_OFFLINE}, { 0x1052a0, 3, RI_ALL_ONLINE},
+ { 0x1052ac, 1, RI_ALL_OFFLINE}, { 0x1052b0, 3, RI_ALL_ONLINE},
+ { 0x1052bc, 1, RI_ALL_OFFLINE}, { 0x1052c0, 3, RI_ALL_ONLINE},
+ { 0x1052cc, 1, RI_ALL_OFFLINE}, { 0x1052d0, 3, RI_ALL_ONLINE},
+ { 0x1052dc, 1, RI_ALL_OFFLINE}, { 0x1052e0, 3, RI_ALL_ONLINE},
+ { 0x1052ec, 1, RI_ALL_OFFLINE}, { 0x1052f0, 3, RI_ALL_ONLINE},
+ { 0x1052fc, 1, RI_ALL_OFFLINE}, { 0x105300, 3, RI_ALL_ONLINE},
+ { 0x10530c, 1, RI_ALL_OFFLINE}, { 0x105310, 3, RI_ALL_ONLINE},
+ { 0x10531c, 1, RI_ALL_OFFLINE}, { 0x105320, 3, RI_ALL_ONLINE},
+ { 0x10532c, 1, RI_ALL_OFFLINE}, { 0x105330, 3, RI_ALL_ONLINE},
+ { 0x10533c, 1, RI_ALL_OFFLINE}, { 0x105340, 3, RI_ALL_ONLINE},
+ { 0x10534c, 1, RI_ALL_OFFLINE}, { 0x105350, 3, RI_ALL_ONLINE},
+ { 0x10535c, 1, RI_ALL_OFFLINE}, { 0x105360, 3, RI_ALL_ONLINE},
+ { 0x10536c, 1, RI_ALL_OFFLINE}, { 0x105370, 3, RI_ALL_ONLINE},
+ { 0x10537c, 1, RI_ALL_OFFLINE}, { 0x105380, 3, RI_ALL_ONLINE},
+ { 0x10538c, 1, RI_ALL_OFFLINE}, { 0x105390, 3, RI_ALL_ONLINE},
+ { 0x10539c, 1, RI_ALL_OFFLINE}, { 0x1053a0, 3, RI_ALL_ONLINE},
+ { 0x1053ac, 1, RI_ALL_OFFLINE}, { 0x1053b0, 3, RI_ALL_ONLINE},
+ { 0x1053bc, 1, RI_ALL_OFFLINE}, { 0x1053c0, 3, RI_ALL_ONLINE},
+ { 0x1053cc, 1, RI_ALL_OFFLINE}, { 0x1053d0, 3, RI_ALL_ONLINE},
+ { 0x1053dc, 1, RI_ALL_OFFLINE}, { 0x1053e0, 3, RI_ALL_ONLINE},
+ { 0x1053ec, 1, RI_ALL_OFFLINE}, { 0x1053f0, 3, RI_ALL_ONLINE},
+ { 0x1053fc, 769, RI_ALL_OFFLINE}, { 0x108000, 33, RI_ALL_ONLINE},
+ { 0x108090, 1, RI_ALL_ONLINE}, { 0x1080a0, 1, RI_ALL_ONLINE},
+ { 0x1080ac, 5, RI_E1H_ONLINE}, { 0x108100, 5, RI_ALL_ONLINE},
+ { 0x108120, 5, RI_ALL_ONLINE}, { 0x108200, 74, RI_ALL_ONLINE},
+ { 0x108400, 74, RI_ALL_ONLINE}, { 0x108800, 152, RI_ALL_ONLINE},
+ { 0x109000, 1, RI_ALL_ONLINE}, { 0x120000, 347, RI_ALL_ONLINE},
+ { 0x120578, 1, RI_ALL_ONLINE}, { 0x120588, 1, RI_ALL_ONLINE},
+ { 0x120598, 1, RI_ALL_ONLINE}, { 0x12059c, 23, RI_E1H_ONLINE},
+ { 0x120614, 1, RI_E1H_ONLINE}, { 0x12061c, 30, RI_E1H_ONLINE},
+ { 0x12080c, 65, RI_ALL_ONLINE}, { 0x120a00, 2, RI_ALL_ONLINE},
+ { 0x122000, 2, RI_ALL_ONLINE}, { 0x128000, 2, RI_E1H_ONLINE},
+ { 0x140000, 114, RI_ALL_ONLINE}, { 0x1401d4, 1, RI_ALL_ONLINE},
+ { 0x1401e4, 1, RI_ALL_ONLINE}, { 0x140200, 6, RI_ALL_ONLINE},
+ { 0x144000, 4, RI_ALL_ONLINE}, { 0x148000, 4, RI_ALL_ONLINE},
+ { 0x14c000, 4, RI_ALL_ONLINE}, { 0x150000, 4, RI_ALL_ONLINE},
+ { 0x154000, 4, RI_ALL_ONLINE}, { 0x158000, 4, RI_ALL_ONLINE},
+ { 0x15c000, 7, RI_E1H_ONLINE}, { 0x161000, 7, RI_ALL_ONLINE},
+ { 0x161028, 1, RI_ALL_ONLINE}, { 0x161038, 1, RI_ALL_ONLINE},
+ { 0x161800, 2, RI_ALL_ONLINE}, { 0x164000, 60, RI_ALL_ONLINE},
+ { 0x1640fc, 1, RI_ALL_ONLINE}, { 0x16410c, 1, RI_ALL_ONLINE},
+ { 0x164110, 2, RI_E1H_ONLINE}, { 0x164200, 1, RI_ALL_ONLINE},
+ { 0x164208, 1, RI_ALL_ONLINE}, { 0x164210, 1, RI_ALL_ONLINE},
+ { 0x164218, 1, RI_ALL_ONLINE}, { 0x164220, 1, RI_ALL_ONLINE},
+ { 0x164228, 1, RI_ALL_ONLINE}, { 0x164230, 1, RI_ALL_ONLINE},
+ { 0x164238, 1, RI_ALL_ONLINE}, { 0x164240, 1, RI_ALL_ONLINE},
+ { 0x164248, 1, RI_ALL_ONLINE}, { 0x164250, 1, RI_ALL_ONLINE},
+ { 0x164258, 1, RI_ALL_ONLINE}, { 0x164260, 1, RI_ALL_ONLINE},
+ { 0x164270, 2, RI_ALL_ONLINE}, { 0x164280, 2, RI_ALL_ONLINE},
+ { 0x164800, 2, RI_ALL_ONLINE}, { 0x165000, 2, RI_ALL_ONLINE},
+ { 0x166000, 164, RI_ALL_ONLINE}, { 0x16629c, 1, RI_ALL_ONLINE},
+ { 0x1662ac, 1, RI_ALL_ONLINE}, { 0x1662bc, 1, RI_ALL_ONLINE},
+ { 0x166400, 49, RI_ALL_ONLINE}, { 0x1664c8, 38, RI_ALL_ONLINE},
+ { 0x166568, 2, RI_ALL_ONLINE}, { 0x166800, 1, RI_ALL_ONLINE},
+ { 0x168000, 270, RI_ALL_ONLINE}, { 0x168444, 1, RI_ALL_ONLINE},
+ { 0x168454, 1, RI_ALL_ONLINE}, { 0x168800, 19, RI_ALL_ONLINE},
+ { 0x168900, 1, RI_ALL_ONLINE}, { 0x168a00, 128, RI_ALL_ONLINE},
+ { 0x16a000, 1, RI_ALL_ONLINE}, { 0x16a004, 1535, RI_ALL_OFFLINE},
+ { 0x16c000, 1, RI_ALL_ONLINE}, { 0x16c004, 1535, RI_ALL_OFFLINE},
+ { 0x16e000, 16, RI_E1H_ONLINE}, { 0x16e100, 1, RI_E1H_ONLINE},
+ { 0x16e200, 2, RI_E1H_ONLINE}, { 0x16e400, 183, RI_E1H_ONLINE},
+ { 0x170000, 93, RI_ALL_ONLINE}, { 0x170180, 1, RI_ALL_ONLINE},
+ { 0x170190, 1, RI_ALL_ONLINE}, { 0x170200, 4, RI_ALL_ONLINE},
+ { 0x170214, 1, RI_ALL_ONLINE}, { 0x178000, 1, RI_ALL_ONLINE},
+ { 0x180000, 61, RI_ALL_ONLINE}, { 0x180100, 1, RI_ALL_ONLINE},
+ { 0x180110, 1, RI_ALL_ONLINE}, { 0x180120, 1, RI_ALL_ONLINE},
+ { 0x180130, 1, RI_ALL_ONLINE}, { 0x18013c, 2, RI_E1H_ONLINE},
+ { 0x180200, 58, RI_ALL_ONLINE}, { 0x180340, 4, RI_ALL_ONLINE},
+ { 0x180400, 1, RI_ALL_ONLINE}, { 0x180404, 255, RI_ALL_OFFLINE},
+ { 0x181000, 4, RI_ALL_ONLINE}, { 0x181010, 1020, RI_ALL_OFFLINE},
+ { 0x1a0000, 1, RI_ALL_ONLINE}, { 0x1a0004, 1023, RI_ALL_OFFLINE},
+ { 0x1a1000, 1, RI_ALL_ONLINE}, { 0x1a1004, 4607, RI_ALL_OFFLINE},
+ { 0x1a5800, 2560, RI_E1H_OFFLINE}, { 0x1a8000, 64, RI_ALL_OFFLINE},
+ { 0x1a8100, 1984, RI_E1H_OFFLINE}, { 0x1aa000, 1, RI_E1H_ONLINE},
+ { 0x1aa004, 6655, RI_E1H_OFFLINE}, { 0x1b1800, 128, RI_ALL_OFFLINE},
+ { 0x1b1c00, 128, RI_ALL_OFFLINE}, { 0x1b2000, 1, RI_ALL_OFFLINE},
+ { 0x1b2400, 64, RI_E1H_OFFLINE}, { 0x1b8200, 1, RI_ALL_ONLINE},
+ { 0x1b8240, 1, RI_ALL_ONLINE}, { 0x1b8280, 1, RI_ALL_ONLINE},
+ { 0x1b82c0, 1, RI_ALL_ONLINE}, { 0x1b8a00, 1, RI_ALL_ONLINE},
+ { 0x1b8a80, 1, RI_ALL_ONLINE}, { 0x1c0000, 2, RI_ALL_ONLINE},
+ { 0x200000, 65, RI_ALL_ONLINE}, { 0x200110, 1, RI_ALL_ONLINE},
+ { 0x200120, 1, RI_ALL_ONLINE}, { 0x200130, 1, RI_ALL_ONLINE},
+ { 0x200140, 1, RI_ALL_ONLINE}, { 0x20014c, 2, RI_E1H_ONLINE},
+ { 0x200200, 58, RI_ALL_ONLINE}, { 0x200340, 4, RI_ALL_ONLINE},
+ { 0x200400, 1, RI_ALL_ONLINE}, { 0x200404, 255, RI_ALL_OFFLINE},
+ { 0x202000, 4, RI_ALL_ONLINE}, { 0x202010, 2044, RI_ALL_OFFLINE},
+ { 0x220000, 1, RI_ALL_ONLINE}, { 0x220004, 1023, RI_ALL_OFFLINE},
+ { 0x221000, 1, RI_ALL_ONLINE}, { 0x221004, 4607, RI_ALL_OFFLINE},
+ { 0x225800, 1536, RI_E1H_OFFLINE}, { 0x227000, 1, RI_E1H_ONLINE},
+ { 0x227004, 1023, RI_E1H_OFFLINE}, { 0x228000, 64, RI_ALL_OFFLINE},
+ { 0x228100, 8640, RI_E1H_OFFLINE}, { 0x231800, 128, RI_ALL_OFFLINE},
+ { 0x231c00, 128, RI_ALL_OFFLINE}, { 0x232000, 1, RI_ALL_OFFLINE},
+ { 0x232400, 64, RI_E1H_OFFLINE}, { 0x238200, 1, RI_ALL_ONLINE},
+ { 0x238240, 1, RI_ALL_ONLINE}, { 0x238280, 1, RI_ALL_ONLINE},
+ { 0x2382c0, 1, RI_ALL_ONLINE}, { 0x238a00, 1, RI_ALL_ONLINE},
+ { 0x238a80, 1, RI_ALL_ONLINE}, { 0x240000, 2, RI_ALL_ONLINE},
+ { 0x280000, 65, RI_ALL_ONLINE}, { 0x280110, 1, RI_ALL_ONLINE},
+ { 0x280120, 1, RI_ALL_ONLINE}, { 0x280130, 1, RI_ALL_ONLINE},
+ { 0x280140, 1, RI_ALL_ONLINE}, { 0x28014c, 2, RI_E1H_ONLINE},
+ { 0x280200, 58, RI_ALL_ONLINE}, { 0x280340, 4, RI_ALL_ONLINE},
+ { 0x280400, 1, RI_ALL_ONLINE}, { 0x280404, 255, RI_ALL_OFFLINE},
+ { 0x282000, 4, RI_ALL_ONLINE}, { 0x282010, 2044, RI_ALL_OFFLINE},
+ { 0x2a0000, 1, RI_ALL_ONLINE}, { 0x2a0004, 1023, RI_ALL_OFFLINE},
+ { 0x2a1000, 1, RI_ALL_ONLINE}, { 0x2a1004, 4607, RI_ALL_OFFLINE},
+ { 0x2a5800, 2560, RI_E1H_OFFLINE}, { 0x2a8000, 64, RI_ALL_OFFLINE},
+ { 0x2a8100, 960, RI_E1H_OFFLINE}, { 0x2a9000, 1, RI_E1H_ONLINE},
+ { 0x2a9004, 7679, RI_E1H_OFFLINE}, { 0x2b1800, 128, RI_ALL_OFFLINE},
+ { 0x2b1c00, 128, RI_ALL_OFFLINE}, { 0x2b2000, 1, RI_ALL_OFFLINE},
+ { 0x2b2400, 64, RI_E1H_OFFLINE}, { 0x2b8200, 1, RI_ALL_ONLINE},
+ { 0x2b8240, 1, RI_ALL_ONLINE}, { 0x2b8280, 1, RI_ALL_ONLINE},
+ { 0x2b82c0, 1, RI_ALL_ONLINE}, { 0x2b8a00, 1, RI_ALL_ONLINE},
+ { 0x2b8a80, 1, RI_ALL_ONLINE}, { 0x2c0000, 2, RI_ALL_ONLINE},
+ { 0x300000, 65, RI_ALL_ONLINE}, { 0x300110, 1, RI_ALL_ONLINE},
+ { 0x300120, 1, RI_ALL_ONLINE}, { 0x300130, 1, RI_ALL_ONLINE},
+ { 0x300140, 1, RI_ALL_ONLINE}, { 0x30014c, 2, RI_E1H_ONLINE},
+ { 0x300200, 58, RI_ALL_ONLINE}, { 0x300340, 4, RI_ALL_ONLINE},
+ { 0x300400, 1, RI_ALL_ONLINE}, { 0x300404, 255, RI_ALL_OFFLINE},
+ { 0x302000, 4, RI_ALL_ONLINE}, { 0x302010, 2044, RI_ALL_OFFLINE},
+ { 0x320000, 1, RI_ALL_ONLINE}, { 0x320004, 1023, RI_ALL_OFFLINE},
+ { 0x321000, 1, RI_ALL_ONLINE}, { 0x321004, 4607, RI_ALL_OFFLINE},
+ { 0x325800, 2560, RI_E1H_OFFLINE}, { 0x328000, 64, RI_ALL_OFFLINE},
+ { 0x328100, 536, RI_E1H_OFFLINE}, { 0x328960, 1, RI_E1H_ONLINE},
+ { 0x328964, 8103, RI_E1H_OFFLINE}, { 0x331800, 128, RI_ALL_OFFLINE},
+ { 0x331c00, 128, RI_ALL_OFFLINE}, { 0x332000, 1, RI_ALL_OFFLINE},
+ { 0x332400, 64, RI_E1H_OFFLINE}, { 0x338200, 1, RI_ALL_ONLINE},
+ { 0x338240, 1, RI_ALL_ONLINE}, { 0x338280, 1, RI_ALL_ONLINE},
+ { 0x3382c0, 1, RI_ALL_ONLINE}, { 0x338a00, 1, RI_ALL_ONLINE},
+ { 0x338a80, 1, RI_ALL_ONLINE}, { 0x340000, 2, RI_ALL_ONLINE}
+};
+
+
+#define IDLEREGS_COUNT 277
+static const struct reg_addr idle_addrs[IDLEREGS_COUNT] = {
+ { 0x2114, 1, RI_ALL_ONLINE}, { 0x2120, 1, RI_ALL_ONLINE},
+ { 0x212c, 4, RI_ALL_ONLINE}, { 0x2814, 1, RI_ALL_ONLINE},
+ { 0x281c, 2, RI_ALL_ONLINE}, { 0xa38c, 1, RI_ALL_ONLINE},
+ { 0xa408, 1, RI_ALL_ONLINE}, { 0xa42c, 12, RI_ALL_ONLINE},
+ { 0xa600, 5, RI_E1H_ONLINE}, { 0xa618, 1, RI_E1H_ONLINE},
+ { 0xc09c, 1, RI_ALL_ONLINE}, { 0x103b0, 1, RI_ALL_ONLINE},
+ { 0x103c0, 1, RI_ALL_ONLINE}, { 0x103d0, 1, RI_E1H_ONLINE},
+ { 0x2021c, 11, RI_ALL_ONLINE}, { 0x202a8, 1, RI_ALL_ONLINE},
+ { 0x202b8, 1, RI_ALL_ONLINE}, { 0x20404, 1, RI_ALL_ONLINE},
+ { 0x2040c, 2, RI_ALL_ONLINE}, { 0x2041c, 2, RI_ALL_ONLINE},
+ { 0x40154, 14, RI_ALL_ONLINE}, { 0x40198, 1, RI_ALL_ONLINE},
+ { 0x404ac, 1, RI_ALL_ONLINE}, { 0x404bc, 1, RI_ALL_ONLINE},
+ { 0x42290, 1, RI_ALL_ONLINE}, { 0x422a0, 1, RI_ALL_ONLINE},
+ { 0x422b0, 1, RI_ALL_ONLINE}, { 0x42548, 1, RI_ALL_ONLINE},
+ { 0x42550, 1, RI_ALL_ONLINE}, { 0x42558, 1, RI_ALL_ONLINE},
+ { 0x50160, 8, RI_ALL_ONLINE}, { 0x501d0, 1, RI_ALL_ONLINE},
+ { 0x501e0, 1, RI_ALL_ONLINE}, { 0x50204, 1, RI_ALL_ONLINE},
+ { 0x5020c, 2, RI_ALL_ONLINE}, { 0x5021c, 1, RI_ALL_ONLINE},
+ { 0x60090, 1, RI_ALL_ONLINE}, { 0x6011c, 1, RI_ALL_ONLINE},
+ { 0x6012c, 1, RI_ALL_ONLINE}, { 0xc101c, 1, RI_ALL_ONLINE},
+ { 0xc102c, 1, RI_ALL_ONLINE}, { 0xc2290, 1, RI_ALL_ONLINE},
+ { 0xc22a0, 1, RI_ALL_ONLINE}, { 0xc22b0, 1, RI_ALL_ONLINE},
+ { 0xc2548, 1, RI_ALL_ONLINE}, { 0xc2550, 1, RI_ALL_ONLINE},
+ { 0xc2558, 1, RI_ALL_ONLINE}, { 0xc4294, 1, RI_ALL_ONLINE},
+ { 0xc42a4, 1, RI_ALL_ONLINE}, { 0xc42b4, 1, RI_ALL_ONLINE},
+ { 0xc4550, 1, RI_ALL_ONLINE}, { 0xc4558, 1, RI_ALL_ONLINE},
+ { 0xc4560, 1, RI_ALL_ONLINE}, { 0xd016c, 8, RI_ALL_ONLINE},
+ { 0xd01d8, 1, RI_ALL_ONLINE}, { 0xd01e8, 1, RI_ALL_ONLINE},
+ { 0xd0204, 1, RI_ALL_ONLINE}, { 0xd020c, 3, RI_ALL_ONLINE},
+ { 0xe0154, 8, RI_ALL_ONLINE}, { 0xe01c8, 1, RI_ALL_ONLINE},
+ { 0xe01d8, 1, RI_ALL_ONLINE}, { 0xe0204, 1, RI_ALL_ONLINE},
+ { 0xe020c, 2, RI_ALL_ONLINE}, { 0xe021c, 2, RI_ALL_ONLINE},
+ { 0x101014, 1, RI_ALL_ONLINE}, { 0x101030, 1, RI_ALL_ONLINE},
+ { 0x101040, 1, RI_ALL_ONLINE}, { 0x102058, 1, RI_ALL_ONLINE},
+ { 0x102080, 16, RI_ALL_ONLINE}, { 0x103004, 2, RI_ALL_ONLINE},
+ { 0x103068, 1, RI_ALL_ONLINE}, { 0x103078, 1, RI_ALL_ONLINE},
+ { 0x103088, 1, RI_ALL_ONLINE}, { 0x10309c, 2, RI_E1H_ONLINE},
+ { 0x104004, 1, RI_ALL_ONLINE}, { 0x104018, 1, RI_ALL_ONLINE},
+ { 0x104020, 1, RI_ALL_ONLINE}, { 0x10403c, 1, RI_ALL_ONLINE},
+ { 0x1040fc, 1, RI_ALL_ONLINE}, { 0x10410c, 1, RI_ALL_ONLINE},
+ { 0x104400, 64, RI_ALL_ONLINE}, { 0x104800, 64, RI_ALL_ONLINE},
+ { 0x105000, 3, RI_ALL_ONLINE}, { 0x105010, 3, RI_ALL_ONLINE},
+ { 0x105020, 3, RI_ALL_ONLINE}, { 0x105030, 3, RI_ALL_ONLINE},
+ { 0x105040, 3, RI_ALL_ONLINE}, { 0x105050, 3, RI_ALL_ONLINE},
+ { 0x105060, 3, RI_ALL_ONLINE}, { 0x105070, 3, RI_ALL_ONLINE},
+ { 0x105080, 3, RI_ALL_ONLINE}, { 0x105090, 3, RI_ALL_ONLINE},
+ { 0x1050a0, 3, RI_ALL_ONLINE}, { 0x1050b0, 3, RI_ALL_ONLINE},
+ { 0x1050c0, 3, RI_ALL_ONLINE}, { 0x1050d0, 3, RI_ALL_ONLINE},
+ { 0x1050e0, 3, RI_ALL_ONLINE}, { 0x1050f0, 3, RI_ALL_ONLINE},
+ { 0x105100, 3, RI_ALL_ONLINE}, { 0x105110, 3, RI_ALL_ONLINE},
+ { 0x105120, 3, RI_ALL_ONLINE}, { 0x105130, 3, RI_ALL_ONLINE},
+ { 0x105140, 3, RI_ALL_ONLINE}, { 0x105150, 3, RI_ALL_ONLINE},
+ { 0x105160, 3, RI_ALL_ONLINE}, { 0x105170, 3, RI_ALL_ONLINE},
+ { 0x105180, 3, RI_ALL_ONLINE}, { 0x105190, 3, RI_ALL_ONLINE},
+ { 0x1051a0, 3, RI_ALL_ONLINE}, { 0x1051b0, 3, RI_ALL_ONLINE},
+ { 0x1051c0, 3, RI_ALL_ONLINE}, { 0x1051d0, 3, RI_ALL_ONLINE},
+ { 0x1051e0, 3, RI_ALL_ONLINE}, { 0x1051f0, 3, RI_ALL_ONLINE},
+ { 0x105200, 3, RI_ALL_ONLINE}, { 0x105210, 3, RI_ALL_ONLINE},
+ { 0x105220, 3, RI_ALL_ONLINE}, { 0x105230, 3, RI_ALL_ONLINE},
+ { 0x105240, 3, RI_ALL_ONLINE}, { 0x105250, 3, RI_ALL_ONLINE},
+ { 0x105260, 3, RI_ALL_ONLINE}, { 0x105270, 3, RI_ALL_ONLINE},
+ { 0x105280, 3, RI_ALL_ONLINE}, { 0x105290, 3, RI_ALL_ONLINE},
+ { 0x1052a0, 3, RI_ALL_ONLINE}, { 0x1052b0, 3, RI_ALL_ONLINE},
+ { 0x1052c0, 3, RI_ALL_ONLINE}, { 0x1052d0, 3, RI_ALL_ONLINE},
+ { 0x1052e0, 3, RI_ALL_ONLINE}, { 0x1052f0, 3, RI_ALL_ONLINE},
+ { 0x105300, 3, RI_ALL_ONLINE}, { 0x105310, 3, RI_ALL_ONLINE},
+ { 0x105320, 3, RI_ALL_ONLINE}, { 0x105330, 3, RI_ALL_ONLINE},
+ { 0x105340, 3, RI_ALL_ONLINE}, { 0x105350, 3, RI_ALL_ONLINE},
+ { 0x105360, 3, RI_ALL_ONLINE}, { 0x105370, 3, RI_ALL_ONLINE},
+ { 0x105380, 3, RI_ALL_ONLINE}, { 0x105390, 3, RI_ALL_ONLINE},
+ { 0x1053a0, 3, RI_ALL_ONLINE}, { 0x1053b0, 3, RI_ALL_ONLINE},
+ { 0x1053c0, 3, RI_ALL_ONLINE}, { 0x1053d0, 3, RI_ALL_ONLINE},
+ { 0x1053e0, 3, RI_ALL_ONLINE}, { 0x1053f0, 3, RI_ALL_ONLINE},
+ { 0x108094, 1, RI_ALL_ONLINE}, { 0x1201b0, 2, RI_ALL_ONLINE},
+ { 0x12032c, 1, RI_ALL_ONLINE}, { 0x12036c, 3, RI_ALL_ONLINE},
+ { 0x120408, 2, RI_ALL_ONLINE}, { 0x120414, 15, RI_ALL_ONLINE},
+ { 0x120478, 2, RI_ALL_ONLINE}, { 0x12052c, 1, RI_ALL_ONLINE},
+ { 0x120564, 3, RI_ALL_ONLINE}, { 0x12057c, 1, RI_ALL_ONLINE},
+ { 0x12058c, 1, RI_ALL_ONLINE}, { 0x120608, 1, RI_E1H_ONLINE},
+ { 0x120808, 1, RI_E1_ONLINE}, { 0x12080c, 2, RI_ALL_ONLINE},
+ { 0x120818, 1, RI_ALL_ONLINE}, { 0x120820, 1, RI_ALL_ONLINE},
+ { 0x120828, 1, RI_ALL_ONLINE}, { 0x120830, 1, RI_ALL_ONLINE},
+ { 0x120838, 1, RI_ALL_ONLINE}, { 0x120840, 1, RI_ALL_ONLINE},
+ { 0x120848, 1, RI_ALL_ONLINE}, { 0x120850, 1, RI_ALL_ONLINE},
+ { 0x120858, 1, RI_ALL_ONLINE}, { 0x120860, 1, RI_ALL_ONLINE},
+ { 0x120868, 1, RI_ALL_ONLINE}, { 0x120870, 1, RI_ALL_ONLINE},
+ { 0x120878, 1, RI_ALL_ONLINE}, { 0x120880, 1, RI_ALL_ONLINE},
+ { 0x120888, 1, RI_ALL_ONLINE}, { 0x120890, 1, RI_ALL_ONLINE},
+ { 0x120898, 1, RI_ALL_ONLINE}, { 0x1208a0, 1, RI_ALL_ONLINE},
+ { 0x1208a8, 1, RI_ALL_ONLINE}, { 0x1208b0, 1, RI_ALL_ONLINE},
+ { 0x1208b8, 1, RI_ALL_ONLINE}, { 0x1208c0, 1, RI_ALL_ONLINE},
+ { 0x1208c8, 1, RI_ALL_ONLINE}, { 0x1208d0, 1, RI_ALL_ONLINE},
+ { 0x1208d8, 1, RI_ALL_ONLINE}, { 0x1208e0, 1, RI_ALL_ONLINE},
+ { 0x1208e8, 1, RI_ALL_ONLINE}, { 0x1208f0, 1, RI_ALL_ONLINE},
+ { 0x1208f8, 1, RI_ALL_ONLINE}, { 0x120900, 1, RI_ALL_ONLINE},
+ { 0x120908, 1, RI_ALL_ONLINE}, { 0x14005c, 2, RI_ALL_ONLINE},
+ { 0x1400d0, 2, RI_ALL_ONLINE}, { 0x1400e0, 1, RI_ALL_ONLINE},
+ { 0x1401c8, 1, RI_ALL_ONLINE}, { 0x140200, 6, RI_ALL_ONLINE},
+ { 0x16101c, 1, RI_ALL_ONLINE}, { 0x16102c, 1, RI_ALL_ONLINE},
+ { 0x164014, 2, RI_ALL_ONLINE}, { 0x1640f0, 1, RI_ALL_ONLINE},
+ { 0x166290, 1, RI_ALL_ONLINE}, { 0x1662a0, 1, RI_ALL_ONLINE},
+ { 0x1662b0, 1, RI_ALL_ONLINE}, { 0x166548, 1, RI_ALL_ONLINE},
+ { 0x166550, 1, RI_ALL_ONLINE}, { 0x166558, 1, RI_ALL_ONLINE},
+ { 0x168000, 1, RI_ALL_ONLINE}, { 0x168008, 1, RI_ALL_ONLINE},
+ { 0x168010, 1, RI_ALL_ONLINE}, { 0x168018, 1, RI_ALL_ONLINE},
+ { 0x168028, 2, RI_ALL_ONLINE}, { 0x168058, 4, RI_ALL_ONLINE},
+ { 0x168070, 1, RI_ALL_ONLINE}, { 0x168238, 1, RI_ALL_ONLINE},
+ { 0x1682d0, 2, RI_ALL_ONLINE}, { 0x1682e0, 1, RI_ALL_ONLINE},
+ { 0x168300, 67, RI_ALL_ONLINE}, { 0x168410, 2, RI_ALL_ONLINE},
+ { 0x168438, 1, RI_ALL_ONLINE}, { 0x168448, 1, RI_ALL_ONLINE},
+ { 0x168a00, 128, RI_ALL_ONLINE}, { 0x16e200, 128, RI_E1H_ONLINE},
+ { 0x16e404, 2, RI_E1H_ONLINE}, { 0x16e584, 70, RI_E1H_ONLINE},
+ { 0x1700a4, 1, RI_ALL_ONLINE}, { 0x1700ac, 2, RI_ALL_ONLINE},
+ { 0x1700c0, 1, RI_ALL_ONLINE}, { 0x170174, 1, RI_ALL_ONLINE},
+ { 0x170184, 1, RI_ALL_ONLINE}, { 0x1800f4, 1, RI_ALL_ONLINE},
+ { 0x180104, 1, RI_ALL_ONLINE}, { 0x180114, 1, RI_ALL_ONLINE},
+ { 0x180124, 1, RI_ALL_ONLINE}, { 0x18026c, 1, RI_ALL_ONLINE},
+ { 0x1802a0, 1, RI_ALL_ONLINE}, { 0x1a1000, 1, RI_ALL_ONLINE},
+ { 0x1aa000, 1, RI_E1H_ONLINE}, { 0x1b8000, 1, RI_ALL_ONLINE},
+ { 0x1b8040, 1, RI_ALL_ONLINE}, { 0x1b8080, 1, RI_ALL_ONLINE},
+ { 0x1b80c0, 1, RI_ALL_ONLINE}, { 0x200104, 1, RI_ALL_ONLINE},
+ { 0x200114, 1, RI_ALL_ONLINE}, { 0x200124, 1, RI_ALL_ONLINE},
+ { 0x200134, 1, RI_ALL_ONLINE}, { 0x20026c, 1, RI_ALL_ONLINE},
+ { 0x2002a0, 1, RI_ALL_ONLINE}, { 0x221000, 1, RI_ALL_ONLINE},
+ { 0x227000, 1, RI_E1H_ONLINE}, { 0x238000, 1, RI_ALL_ONLINE},
+ { 0x238040, 1, RI_ALL_ONLINE}, { 0x238080, 1, RI_ALL_ONLINE},
+ { 0x2380c0, 1, RI_ALL_ONLINE}, { 0x280104, 1, RI_ALL_ONLINE},
+ { 0x280114, 1, RI_ALL_ONLINE}, { 0x280124, 1, RI_ALL_ONLINE},
+ { 0x280134, 1, RI_ALL_ONLINE}, { 0x28026c, 1, RI_ALL_ONLINE},
+ { 0x2802a0, 1, RI_ALL_ONLINE}, { 0x2a1000, 1, RI_ALL_ONLINE},
+ { 0x2a9000, 1, RI_E1H_ONLINE}, { 0x2b8000, 1, RI_ALL_ONLINE},
+ { 0x2b8040, 1, RI_ALL_ONLINE}, { 0x2b8080, 1, RI_ALL_ONLINE},
+ { 0x2b80c0, 1, RI_ALL_ONLINE}, { 0x300104, 1, RI_ALL_ONLINE},
+ { 0x300114, 1, RI_ALL_ONLINE}, { 0x300124, 1, RI_ALL_ONLINE},
+ { 0x300134, 1, RI_ALL_ONLINE}, { 0x30026c, 1, RI_ALL_ONLINE},
+ { 0x3002a0, 1, RI_ALL_ONLINE}, { 0x321000, 1, RI_ALL_ONLINE},
+ { 0x328960, 1, RI_E1H_ONLINE}, { 0x338000, 1, RI_ALL_ONLINE},
+ { 0x338040, 1, RI_ALL_ONLINE}, { 0x338080, 1, RI_ALL_ONLINE},
+ { 0x3380c0, 1, RI_ALL_ONLINE}
+};
+
+static const u32 read_reg_e1_0[] = { 0x1b1000 };
+
+#define WREGS_COUNT_E1 1
+static const struct wreg_addr wreg_addrs_e1[WREGS_COUNT_E1] = {
+ { 0x1b0c00, 192, 1, read_reg_e1_0, RI_E1_OFFLINE }
+};
+
+static const u32 read_reg_e1h_0[] = { 0x1b1040, 0x1b1000 };
+
+#define WREGS_COUNT_E1H 1
+static const struct wreg_addr wreg_addrs_e1h[WREGS_COUNT_E1H] = {
+ { 0x1b0c00, 256, 2, read_reg_e1h_0, RI_E1H_OFFLINE }
+};
+
+
+static const struct dump_sign dump_sign_all = { 0x49aa93ee, 0x40835, 0x22 };
+
+
+#define TIMER_REGS_COUNT_E1 2
+static const u32 timer_status_regs_e1[TIMER_REGS_COUNT_E1] =
+ { 0x164014, 0x164018 };
+static const u32 timer_scan_regs_e1[TIMER_REGS_COUNT_E1] =
+ { 0x1640d0, 0x1640d4 };
+
+#define TIMER_REGS_COUNT_E1H 2
+static const u32 timer_status_regs_e1h[TIMER_REGS_COUNT_E1H] =
+ { 0x164014, 0x164018 };
+static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] =
+ { 0x1640d0, 0x1640d4 };
+
diff --git a/drivers/net/bnx2x_fw_defs.h b/drivers/net/bnx2x_fw_defs.h
index 192fa981b930..e2df23803598 100644
--- a/drivers/net/bnx2x_fw_defs.h
+++ b/drivers/net/bnx2x_fw_defs.h
@@ -1,6 +1,6 @@
/* bnx2x_fw_defs.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -50,8 +50,10 @@
#define TSTORM_ASSERT_LIST_OFFSET(idx) \
(IS_E1H_OFFSET ? (0xa020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) \
- (IS_E1H_OFFSET ? (0x3358 + (port * 0x3e8) + (client_id * 0x28)) \
- : (0x9c8 + (port * 0x2f8) + (client_id * 0x28)))
+ (IS_E1H_OFFSET ? (0x3350 + (port * 0x190) + (client_id * 0x10)) \
+ : (0x9c0 + (port * 0x130) + (client_id * 0x10)))
+#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET \
+ (IS_E1H_OFFSET ? 0x1ad8 : 0xffffffff)
#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
(IS_E1H_OFFSET ? (0xb01a + ((function>>1) * 0x28) + \
((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
@@ -81,43 +83,54 @@
(function * 0x38)))
#define TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
(IS_E1H_OFFSET ? (0x2010 + (port * 0x5b0) + (stats_counter_id * \
- 0x50)) : (0x4000 + (port * 0x3f0) + (stats_counter_id * 0x38)))
-#define TSTORM_RX_PRODS_OFFSET(port, client_id) \
- (IS_E1H_OFFSET ? (0x3350 + (port * 0x3e8) + (client_id * 0x28)) \
- : (0x9c0 + (port * 0x2f8) + (client_id * 0x28)))
+ 0x50)) : (0x4080 + (port * 0x5b0) + (stats_counter_id * 0x50)))
#define TSTORM_STATS_FLAGS_OFFSET(function) \
(IS_E1H_OFFSET ? (0x2c00 + (function * 0x8)) : (0x4b88 + \
(function * 0x8)))
-#define TSTORM_TPA_EXIST_OFFSET (IS_E1H_OFFSET ? 0x3b30 : 0x1c20)
+#define TSTORM_TPA_EXIST_OFFSET (IS_E1H_OFFSET ? 0x3680 : 0x1c20)
#define USTORM_AGG_DATA_OFFSET (IS_E1H_OFFSET ? 0xa040 : 0x2c10)
#define USTORM_AGG_DATA_SIZE (IS_E1H_OFFSET ? 0x2440 : 0x1200)
#define USTORM_ASSERT_LIST_INDEX_OFFSET \
- (IS_E1H_OFFSET ? 0x8000 : 0x1000)
+ (IS_E1H_OFFSET ? 0x8960 : 0x1000)
#define USTORM_ASSERT_LIST_OFFSET(idx) \
- (IS_E1H_OFFSET ? (0x8020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
+ (IS_E1H_OFFSET ? (0x8980 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
#define USTORM_CQE_PAGE_BASE_OFFSET(port, clientId) \
- (IS_E1H_OFFSET ? (0x3298 + (port * 0x258) + (clientId * 0x18)) : \
- (0x5450 + (port * 0x1c8) + (clientId * 0x18)))
+ (IS_E1H_OFFSET ? (0x8018 + (port * 0x4b0) + (clientId * 0x30)) : \
+ (0x5330 + (port * 0x260) + (clientId * 0x20)))
#define USTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
- (IS_E1H_OFFSET ? (0x951a + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0) + (index * 0x4)) : (0x191a + (function * \
- 0x28) + (index * 0x4)))
+ (IS_E1H_OFFSET ? (0x9522 + ((function>>1) * 0x40) + \
+ ((function&1) * 0x100) + (index * 0x4)) : (0x1922 + (function * \
+ 0x40) + (index * 0x4)))
#define USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x9500 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1900 + (function * 0x28)))
+ (IS_E1H_OFFSET ? (0x9500 + ((function>>1) * 0x40) + \
+ ((function&1) * 0x100)) : (0x1900 + (function * 0x40)))
#define USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x9508 + ((function>>1) * 0x28) + \
- ((function&1) * 0xa0)) : (0x1908 + (function * 0x28)))
+ (IS_E1H_OFFSET ? (0x9508 + ((function>>1) * 0x40) + \
+ ((function&1) * 0x100)) : (0x1908 + (function * 0x40)))
+#define USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, clientId) \
+ (IS_E1H_OFFSET ? (0x8020 + (port * 0x4b0) + (clientId * 0x30)) : \
+ 0xffffffff)
+#define USTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
+ (IS_E1H_OFFSET ? (0x2a50 + (function * 0x8)) : (0x1d98 + \
+ (function * 0x8)))
#define USTORM_FUNCTION_MODE_OFFSET \
(IS_E1H_OFFSET ? 0x2448 : 0xffffffff)
#define USTORM_HC_BTR_OFFSET(port) \
- (IS_E1H_OFFSET ? (0x9644 + (port * 0xd0)) : (0x1954 + (port * 0xb8)))
+ (IS_E1H_OFFSET ? (0x9704 + (port * 0xf0)) : (0x1984 + (port * 0xc0)))
#define USTORM_MAX_AGG_SIZE_OFFSET(port, clientId) \
- (IS_E1H_OFFSET ? (0x3290 + (port * 0x258) + (clientId * 0x18)) : \
- (0x5448 + (port * 0x1c8) + (clientId * 0x18)))
+ (IS_E1H_OFFSET ? (0x8010 + (port * 0x4b0) + (clientId * 0x30)) : \
+ (0x5328 + (port * 0x260) + (clientId * 0x20)))
#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x5408 + \
+ (IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x5308 + \
(function * 0x8)))
+#define USTORM_PAUSE_ENABLED_OFFSET(port) \
+ (IS_E1H_OFFSET ? (0x2ad4 + (port * 0x8)) : 0xffffffff)
+#define USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
+ (IS_E1H_OFFSET ? (0x2450 + (port * 0x2d0) + (stats_counter_id * \
+ 0x28)) : (0x4740 + (port * 0x2d0) + (stats_counter_id * 0x28)))
+#define USTORM_RX_PRODS_OFFSET(port, client_id) \
+ (IS_E1H_OFFSET ? (0x8000 + (port * 0x4b0) + (client_id * 0x30)) \
+ : (0x5318 + (port * 0x260) + (client_id * 0x20)))
#define USTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index) \
(IS_E1H_OFFSET ? (0x901a + (port * 0x280) + (cpu_id * 0x28) + \
(index * 0x4)) : (0x141a + (port * 0x280) + (cpu_id * 0x28) + \
@@ -132,12 +145,15 @@
#define USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, cpu_id) \
(IS_E1H_OFFSET ? (0x9008 + (port * 0x280) + (cpu_id * 0x28)) : \
(0x1408 + (port * 0x280) + (cpu_id * 0x28)))
+#define USTORM_STATS_FLAGS_OFFSET(function) \
+ (IS_E1H_OFFSET ? (0x29f0 + (function * 0x8)) : (0x1d80 + \
+ (function * 0x8)))
#define XSTORM_ASSERT_LIST_INDEX_OFFSET \
(IS_E1H_OFFSET ? 0x9000 : 0x1000)
#define XSTORM_ASSERT_LIST_OFFSET(idx) \
(IS_E1H_OFFSET ? (0x9020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) \
- (IS_E1H_OFFSET ? (0x24a8 + (port * 0x40)) : (0x3ba0 + (port * 0x40)))
+ (IS_E1H_OFFSET ? (0x24a8 + (port * 0x50)) : (0x3ba0 + (port * 0x50)))
#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
(IS_E1H_OFFSET ? (0xa01a + ((function>>1) * 0x28) + \
((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
@@ -149,23 +165,23 @@
(IS_E1H_OFFSET ? (0xa008 + ((function>>1) * 0x28) + \
((function&1) * 0xa0)) : (0x1408 + (function * 0x28)))
#define XSTORM_E1HOV_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2ab8 + (function * 0x2)) : 0xffffffff)
+ (IS_E1H_OFFSET ? (0x2c10 + (function * 0x2)) : 0xffffffff)
#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
(IS_E1H_OFFSET ? (0x2418 + (function * 0x8)) : (0x3b70 + \
(function * 0x8)))
#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2568 + (function * 0x70)) : (0x3c60 + \
- (function * 0x70)))
+ (IS_E1H_OFFSET ? (0x2588 + (function * 0x90)) : (0x3c80 + \
+ (function * 0x90)))
#define XSTORM_FUNCTION_MODE_OFFSET \
- (IS_E1H_OFFSET ? 0x2ac8 : 0xffffffff)
+ (IS_E1H_OFFSET ? 0x2c20 : 0xffffffff)
#define XSTORM_HC_BTR_OFFSET(port) \
(IS_E1H_OFFSET ? (0xa144 + (port * 0x30)) : (0x1454 + (port * 0x18)))
#define XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
(IS_E1H_OFFSET ? (0xc000 + (port * 0x3f0) + (stats_counter_id * \
0x38)) : (0x3378 + (port * 0x3f0) + (stats_counter_id * 0x38)))
#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(function) \
- (IS_E1H_OFFSET ? (0x2528 + (function * 0x70)) : (0x3c20 + \
- (function * 0x70)))
+ (IS_E1H_OFFSET ? (0x2548 + (function * 0x90)) : (0x3c40 + \
+ (function * 0x90)))
#define XSTORM_SPQ_PAGE_BASE_OFFSET(function) \
(IS_E1H_OFFSET ? (0x2000 + (function * 0x10)) : (0x3328 + \
(function * 0x10)))
@@ -178,7 +194,7 @@
#define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0
/**
-* This file defines HSI constatnts for the ETH flow
+* This file defines HSI constants for the ETH flow
*/
#ifdef _EVEREST_MICROCODE
#include "microcode_constants.h"
@@ -196,18 +212,18 @@
#define IPV6_HASH_TYPE 3
#define TCP_IPV6_HASH_TYPE 4
-/* Ethernet Ring parmaters */
+
+/* Ethernet Ring parameters */
#define X_ETH_LOCAL_RING_SIZE 13
#define FIRST_BD_IN_PKT 0
#define PARSE_BD_INDEX 1
-#define NUM_OF_ETH_BDS_IN_PAGE \
- ((PAGE_SIZE) / (STRUCT_SIZE(eth_tx_bd)/8))
+#define NUM_OF_ETH_BDS_IN_PAGE ((PAGE_SIZE)/(STRUCT_SIZE(eth_tx_bd)/8))
/* Rx ring params */
-#define U_ETH_LOCAL_BD_RING_SIZE (16)
-#define U_ETH_LOCAL_SGE_RING_SIZE (12)
-#define U_ETH_SGL_SIZE (8)
+#define U_ETH_LOCAL_BD_RING_SIZE 16
+#define U_ETH_LOCAL_SGE_RING_SIZE 12
+#define U_ETH_SGL_SIZE 8
#define U_ETH_BDS_PER_PAGE_MASK \
@@ -229,15 +245,15 @@
#define U_ETH_UNDEFINED_Q 0xFF
/* values of command IDs in the ramrod message */
-#define RAMROD_CMD_ID_ETH_PORT_SETUP (80)
-#define RAMROD_CMD_ID_ETH_CLIENT_SETUP (85)
-#define RAMROD_CMD_ID_ETH_STAT_QUERY (90)
-#define RAMROD_CMD_ID_ETH_UPDATE (100)
-#define RAMROD_CMD_ID_ETH_HALT (105)
-#define RAMROD_CMD_ID_ETH_SET_MAC (110)
-#define RAMROD_CMD_ID_ETH_CFC_DEL (115)
-#define RAMROD_CMD_ID_ETH_PORT_DEL (120)
-#define RAMROD_CMD_ID_ETH_FORWARD_SETUP (125)
+#define RAMROD_CMD_ID_ETH_PORT_SETUP 80
+#define RAMROD_CMD_ID_ETH_CLIENT_SETUP 85
+#define RAMROD_CMD_ID_ETH_STAT_QUERY 90
+#define RAMROD_CMD_ID_ETH_UPDATE 100
+#define RAMROD_CMD_ID_ETH_HALT 105
+#define RAMROD_CMD_ID_ETH_SET_MAC 110
+#define RAMROD_CMD_ID_ETH_CFC_DEL 115
+#define RAMROD_CMD_ID_ETH_PORT_DEL 120
+#define RAMROD_CMD_ID_ETH_FORWARD_SETUP 125
/* command values for set mac command */
@@ -254,12 +270,16 @@
#define ETH_MAX_RX_CLIENTS_E1H 25
/* Maximal aggregation queues supported */
-#define ETH_MAX_AGGREGATION_QUEUES_E1 (32)
-#define ETH_MAX_AGGREGATION_QUEUES_E1H (64)
+#define ETH_MAX_AGGREGATION_QUEUES_E1 32
+#define ETH_MAX_AGGREGATION_QUEUES_E1H 64
+
+/* ETH RSS modes */
+#define ETH_RSS_MODE_DISABLED 0
+#define ETH_RSS_MODE_REGULAR 1
/**
-* This file defines HSI constatnts common to all microcode flows
+* This file defines HSI constants common to all microcode flows
*/
/* Connection types */
@@ -278,25 +298,22 @@
#define ETH_STATE (ETH_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
#define TOE_STATE (TOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
#define RDMA_STATE (RDMA_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
-#define ISCSI_STATE \
- (ISCSI_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
-#define FCOE_STATE (FCOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
/* microcode fixed page page size 4K (chains and ring segments) */
-#define MC_PAGE_SIZE (4096)
+#define MC_PAGE_SIZE 4096
/* Host coalescing constants */
/* index numbers */
-#define HC_USTORM_DEF_SB_NUM_INDICES 4
+#define HC_USTORM_DEF_SB_NUM_INDICES 8
#define HC_CSTORM_DEF_SB_NUM_INDICES 8
#define HC_XSTORM_DEF_SB_NUM_INDICES 4
#define HC_TSTORM_DEF_SB_NUM_INDICES 4
#define HC_USTORM_SB_NUM_INDICES 4
#define HC_CSTORM_SB_NUM_INDICES 4
-/* index values - which counterto update */
+/* index values - which counter to update */
#define HC_INDEX_U_TOE_RX_CQ_CONS 0
#define HC_INDEX_U_ETH_RX_CQ_CONS 1
@@ -330,16 +347,16 @@
#define ATTENTION_ID 4
/* max number of slow path commands per port */
-#define MAX_RAMRODS_PER_PORT (8)
+#define MAX_RAMRODS_PER_PORT 8
/* values for RX ETH CQE type field */
-#define RX_ETH_CQE_TYPE_ETH_FASTPATH (0)
-#define RX_ETH_CQE_TYPE_ETH_RAMROD (1)
+#define RX_ETH_CQE_TYPE_ETH_FASTPATH 0
+#define RX_ETH_CQE_TYPE_ETH_RAMROD 1
/**** DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/
-#define EMULATION_FREQUENCY_FACTOR (1600)
-#define FPGA_FREQUENCY_FACTOR (100)
+#define EMULATION_FREQUENCY_FACTOR 1600
+#define FPGA_FREQUENCY_FACTOR 100
#define TIMERS_TICK_SIZE_CHIP (1e-3)
#define TIMERS_TICK_SIZE_EMUL \
@@ -353,12 +370,9 @@
#define TSEMI_CLK1_RESUL_FPGA \
((TSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR))
-#define USEMI_CLK1_RESUL_CHIP \
- (TIMERS_TICK_SIZE_CHIP)
-#define USEMI_CLK1_RESUL_EMUL \
- (TIMERS_TICK_SIZE_EMUL)
-#define USEMI_CLK1_RESUL_FPGA \
- (TIMERS_TICK_SIZE_FPGA)
+#define USEMI_CLK1_RESUL_CHIP (TIMERS_TICK_SIZE_CHIP)
+#define USEMI_CLK1_RESUL_EMUL (TIMERS_TICK_SIZE_EMUL)
+#define USEMI_CLK1_RESUL_FPGA (TIMERS_TICK_SIZE_FPGA)
#define XSEMI_CLK1_RESUL_CHIP (1e-3)
#define XSEMI_CLK1_RESUL_EMUL \
@@ -383,12 +397,15 @@
#define XSTORM_IP_ID_ROLL_HALF 0x8000
#define XSTORM_IP_ID_ROLL_ALL 0
-#define FW_LOG_LIST_SIZE (50)
+#define FW_LOG_LIST_SIZE 50
#define NUM_OF_PROTOCOLS 4
-#define MAX_COS_NUMBER 16
+#define NUM_OF_SAFC_BITS 16
+#define MAX_COS_NUMBER 4
#define MAX_T_STAT_COUNTER_ID 18
#define MAX_X_STAT_COUNTER_ID 18
+#define MAX_U_STAT_COUNTER_ID 18
+
#define UNKNOWN_ADDRESS 0
#define UNICAST_ADDRESS 1
diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h
index efd764427fa1..03c62421d999 100644
--- a/drivers/net/bnx2x_hsi.h
+++ b/drivers/net/bnx2x_hsi.h
@@ -1,6 +1,6 @@
/* bnx2x_hsi.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -119,35 +119,15 @@ struct shared_hw_cfg { /* NVRAM Offset */
#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_BCM5221 0x00010000
u32 board; /* 0x124 */
-#define SHARED_HW_CFG_BOARD_TYPE_MASK 0x0000ffff
-#define SHARED_HW_CFG_BOARD_TYPE_SHIFT 0
-#define SHARED_HW_CFG_BOARD_TYPE_NONE 0x00000000
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1000 0x00000001
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1001 0x00000002
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G 0x00000003
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1004G 0x00000004
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1007G 0x00000005
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1015G 0x00000006
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1020G 0x00000007
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G 0x00000008
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G 0x00000009
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G 0x0000000a
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1023G 0x0000000b
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1033G 0x0000000c
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711T1101 0x0000000d
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711ET1201 0x0000000e
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711A1133G 0x0000000f
-#define SHARED_HW_CFG_BOARD_TYPE_BCM957711EA1233G 0x00000010
-
-#define SHARED_HW_CFG_BOARD_VER_MASK 0xffff0000
-#define SHARED_HW_CFG_BOARD_VER_SHIFT 16
-#define SHARED_HW_CFG_BOARD_MAJOR_VER_MASK 0xf0000000
-#define SHARED_HW_CFG_BOARD_MAJOR_VER_SHIFT 28
-#define SHARED_HW_CFG_BOARD_MINOR_VER_MASK 0x0f000000
-#define SHARED_HW_CFG_BOARD_MINOR_VER_SHIFT 24
-#define SHARED_HW_CFG_BOARD_REV_MASK 0x00ff0000
+#define SHARED_HW_CFG_BOARD_REV_MASK 0x00FF0000
#define SHARED_HW_CFG_BOARD_REV_SHIFT 16
+#define SHARED_HW_CFG_BOARD_MAJOR_VER_MASK 0x0F000000
+#define SHARED_HW_CFG_BOARD_MAJOR_VER_SHIFT 24
+
+#define SHARED_HW_CFG_BOARD_MINOR_VER_MASK 0xF0000000
+#define SHARED_HW_CFG_BOARD_MINOR_VER_SHIFT 28
+
u32 reserved; /* 0x128 */
};
@@ -198,36 +178,21 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
u32 rdma_mac_lower;
u32 serdes_config;
- /* for external PHY, or forced mode or during AN */
-#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_MASK 0xffff0000
-#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_SHIFT 16
+#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_MASK 0x0000FFFF
+#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_SHIFT 0
-#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK 0x0000ffff
-#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT 0
+#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK 0xFFFF0000
+#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT 16
- u16 serdes_tx_driver_pre_emphasis[16];
- u16 serdes_rx_driver_equalizer[16];
- u32 xgxs_config_lane0;
- u32 xgxs_config_lane1;
- u32 xgxs_config_lane2;
- u32 xgxs_config_lane3;
- /* for external PHY, or forced mode or during AN */
-#define PORT_HW_CFG_XGXS_TX_DRV_PRE_EMPHASIS_MASK 0xffff0000
-#define PORT_HW_CFG_XGXS_TX_DRV_PRE_EMPHASIS_SHIFT 16
+ u32 Reserved0[16]; /* 0x158 */
-#define PORT_HW_CFG_XGXS_RX_DRV_EQUALIZER_MASK 0x0000ffff
-#define PORT_HW_CFG_XGXS_RX_DRV_EQUALIZER_SHIFT 0
+ /* for external PHY, or forced mode or during AN */
+ u16 xgxs_config_rx[4]; /* 0x198 */
- u16 xgxs_tx_driver_pre_emphasis_lane0[16];
- u16 xgxs_tx_driver_pre_emphasis_lane1[16];
- u16 xgxs_tx_driver_pre_emphasis_lane2[16];
- u16 xgxs_tx_driver_pre_emphasis_lane3[16];
+ u16 xgxs_config_tx[4]; /* 0x1A0 */
- u16 xgxs_rx_driver_equalizer_lane0[16];
- u16 xgxs_rx_driver_equalizer_lane1[16];
- u16 xgxs_rx_driver_equalizer_lane2[16];
- u16 xgxs_rx_driver_equalizer_lane3[16];
+ u32 Reserved1[64]; /* 0x1A8 */
u32 lane_config;
#define PORT_HW_CFG_LANE_SWAP_CFG_MASK 0x0000ffff
@@ -265,7 +230,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073 0x00000300
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705 0x00000400
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706 0x00000500
-#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8276 0x00000600
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726 0x00000600
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481 0x00000700
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101 0x00000800
#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00
@@ -319,6 +284,12 @@ struct shared_feat_cfg { /* NVRAM Offset */
u32 config; /* 0x450 */
#define SHARED_FEATURE_BMC_ECHO_MODE_EN 0x00000001
+
+ /* Use the values from options 47 and 48 instead of the HW default
+ values */
+#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_DISABLED 0x00000000
+#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED 0x00000002
+
#define SHARED_FEATURE_MF_MODE_DISABLED 0x00000100
};
@@ -372,6 +343,11 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
#define PORT_FEATURE_MBA_ENABLED 0x02000000
#define PORT_FEATURE_MFW_ENABLED 0x04000000
+ /* Check the optic vendor via i2c before allowing it to be used by
+ SW */
+#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLED 0x00000000
+#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_ENABLED 0x08000000
+
u32 wol_config;
/* Default is used when driver sets to "auto" mode */
#define PORT_FEATURE_WOL_DEFAULT_MASK 0x00000003
@@ -512,7 +488,7 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
/****************************************************************************
* Device Information *
****************************************************************************/
-struct dev_info { /* size */
+struct shm_dev_info { /* size */
u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */
@@ -641,7 +617,10 @@ struct drv_port_mb {
u32 port_stx;
- u32 reserved[2];
+ u32 stat_nig_timer;
+
+ /* MCP firmware does not use this field */
+ u32 ext_phy_fw_version;
};
@@ -827,11 +806,7 @@ struct mf_cfg {
struct shared_mf_cfg shared_mf_config;
struct port_mf_cfg port_mf_config[PORT_MAX];
-#if defined(b710)
- struct func_mf_cfg func_mf_config[E1_FUNC_MAX];
-#else
struct func_mf_cfg func_mf_config[E1H_FUNC_MAX];
-#endif
};
@@ -862,7 +837,7 @@ struct shmem_region { /* SharedMem Offset (size) */
#define SHR_MEM_VALIDITY_ACTIVE_MFW_NONE 0x000001c0
#define SHR_MEM_VALIDITY_ACTIVE_MFW_MASK 0x000001c0
- struct dev_info dev_info; /* 0x8 (0x438) */
+ struct shm_dev_info dev_info; /* 0x8 (0x438) */
u8 reserved[52*PORT_MAX];
@@ -1212,8 +1187,9 @@ struct host_func_stats {
#define BCM_5710_FW_MAJOR_VERSION 4
-#define BCM_5710_FW_MINOR_VERSION 5
-#define BCM_5710_FW_REVISION_VERSION 1
+#define BCM_5710_FW_MINOR_VERSION 8
+#define BCM_5710_FW_REVISION_VERSION 53
+#define BCM_5710_FW_ENGINEERING_VERSION 0
#define BCM_5710_FW_COMPILE_FLAGS 1
@@ -1221,18 +1197,12 @@ struct host_func_stats {
* attention bits
*/
struct atten_def_status_block {
- u32 attn_bits;
- u32 attn_bits_ack;
-#if defined(__BIG_ENDIAN)
- u16 attn_bits_index;
- u8 reserved0;
- u8 status_block_id;
-#elif defined(__LITTLE_ENDIAN)
+ __le32 attn_bits;
+ __le32 attn_bits_ack;
u8 status_block_id;
u8 reserved0;
- u16 attn_bits_index;
-#endif
- u32 reserved1;
+ __le16 attn_bits_index;
+ __le32 reserved1;
};
@@ -1305,7 +1275,7 @@ struct igu_ack_register {
* Parser parsing flags field
*/
struct parsing_flags {
- u16 flags;
+ __le16 flags;
#define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE (0x1<<0)
#define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE_SHIFT 0
#define PARSING_FLAGS_VLAN (0x1<<1)
@@ -1336,8 +1306,8 @@ struct parsing_flags {
struct regpair {
- u32 lo;
- u32 hi;
+ __le32 lo;
+ __le32 hi;
};
@@ -1434,8 +1404,10 @@ struct ustorm_eth_st_context_config {
#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING (0x1<<3)
#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING_SHIFT 3
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<4)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 4
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0x7<<5)
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 5
u8 status_block_id;
u8 clientId;
u8 sb_index_numbers;
@@ -1460,14 +1432,18 @@ struct ustorm_eth_st_context_config {
#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING (0x1<<3)
#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING_SHIFT 3
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<4)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 4
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0x7<<5)
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 5
#endif
#if defined(__BIG_ENDIAN)
u16 bd_buff_size;
- u16 mc_alignment_size;
+ u8 statistics_counter_id;
+ u8 mc_alignment_log_size;
#elif defined(__LITTLE_ENDIAN)
- u16 mc_alignment_size;
+ u8 mc_alignment_log_size;
+ u8 statistics_counter_id;
u16 bd_buff_size;
#endif
#if defined(__BIG_ENDIAN)
@@ -1479,13 +1455,7 @@ struct ustorm_eth_st_context_config {
u8 __local_bd_prod;
u8 __local_sge_prod;
#endif
-#if defined(__BIG_ENDIAN)
- u16 __bd_cons;
- u16 __sge_cons;
-#elif defined(__LITTLE_ENDIAN)
- u16 __sge_cons;
- u16 __bd_cons;
-#endif
+ u32 reserved;
u32 bd_page_base_lo;
u32 bd_page_base_hi;
u32 sge_page_base_lo;
@@ -1496,16 +1466,16 @@ struct ustorm_eth_st_context_config {
* The eth Rx Buffer Descriptor
*/
struct eth_rx_bd {
- u32 addr_lo;
- u32 addr_hi;
+ __le32 addr_lo;
+ __le32 addr_hi;
};
/*
* The eth Rx SGE Descriptor
*/
struct eth_rx_sge {
- u32 addr_lo;
- u32 addr_hi;
+ __le32 addr_lo;
+ __le32 addr_hi;
};
/*
@@ -1697,7 +1667,7 @@ struct xstorm_eth_ag_context {
};
/*
- * The eth aggregative context section of Tstorm
+ * The eth extra aggregative context section of Tstorm
*/
struct tstorm_eth_extra_ag_context_section {
u32 __agg_val1;
@@ -1908,11 +1878,11 @@ struct eth_tx_bd_flags {
* The eth Tx Buffer Descriptor
*/
struct eth_tx_bd {
- u32 addr_lo;
- u32 addr_hi;
- u16 nbd;
- u16 nbytes;
- u16 vlan;
+ __le32 addr_lo;
+ __le32 addr_hi;
+ __le16 nbd;
+ __le16 nbytes;
+ __le16 vlan;
struct eth_tx_bd_flags bd_flags;
u8 general_data;
#define ETH_TX_BD_HDR_NBDS (0x3F<<0)
@@ -1955,11 +1925,11 @@ struct eth_tx_parse_bd {
#define ETH_TX_PARSE_BD_CWR_FLG_SHIFT 7
u8 ip_hlen;
s8 cs_offset;
- u16 total_hlen;
- u16 lso_mss;
- u16 tcp_pseudo_csum;
- u16 ip_id;
- u32 tcp_send_seq;
+ __le16 total_hlen;
+ __le16 lso_mss;
+ __le16 tcp_pseudo_csum;
+ __le16 ip_id;
+ __le32 tcp_send_seq;
};
/*
@@ -2075,44 +2045,44 @@ struct eth_tx_doorbell {
* ustorm status block
*/
struct ustorm_def_status_block {
- u16 index_values[HC_USTORM_DEF_SB_NUM_INDICES];
- u16 status_block_index;
+ __le16 index_values[HC_USTORM_DEF_SB_NUM_INDICES];
+ __le16 status_block_index;
u8 func;
u8 status_block_id;
- u32 __flags;
+ __le32 __flags;
};
/*
* cstorm status block
*/
struct cstorm_def_status_block {
- u16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES];
- u16 status_block_index;
+ __le16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES];
+ __le16 status_block_index;
u8 func;
u8 status_block_id;
- u32 __flags;
+ __le32 __flags;
};
/*
* xstorm status block
*/
struct xstorm_def_status_block {
- u16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES];
- u16 status_block_index;
+ __le16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES];
+ __le16 status_block_index;
u8 func;
u8 status_block_id;
- u32 __flags;
+ __le32 __flags;
};
/*
* tstorm status block
*/
struct tstorm_def_status_block {
- u16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES];
- u16 status_block_index;
+ __le16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES];
+ __le16 status_block_index;
u8 func;
u8 status_block_id;
- u32 __flags;
+ __le32 __flags;
};
/*
@@ -2131,22 +2101,22 @@ struct host_def_status_block {
* ustorm status block
*/
struct ustorm_status_block {
- u16 index_values[HC_USTORM_SB_NUM_INDICES];
- u16 status_block_index;
+ __le16 index_values[HC_USTORM_SB_NUM_INDICES];
+ __le16 status_block_index;
u8 func;
u8 status_block_id;
- u32 __flags;
+ __le32 __flags;
};
/*
* cstorm status block
*/
struct cstorm_status_block {
- u16 index_values[HC_CSTORM_SB_NUM_INDICES];
- u16 status_block_index;
+ __le16 index_values[HC_CSTORM_SB_NUM_INDICES];
+ __le16 status_block_index;
u8 func;
u8 status_block_id;
- u32 __flags;
+ __le32 __flags;
};
/*
@@ -2162,9 +2132,9 @@ struct host_status_block {
* The data for RSS setup ramrod
*/
struct eth_client_setup_ramrod_data {
- u32 client_id_5b;
- u8 is_rdma_1b;
- u8 reserved0;
+ u32 client_id;
+ u8 is_rdma;
+ u8 is_fcoe;
u16 reserved1;
};
@@ -2212,12 +2182,12 @@ struct eth_fast_path_rx_cqe {
#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG_SHIFT 7
u8 placement_offset;
u8 queue_index;
- u32 rss_hash_result;
- u16 vlan_tag;
- u16 pkt_len;
- u16 len_on_bd;
+ __le32 rss_hash_result;
+ __le16 vlan_tag;
+ __le16 pkt_len;
+ __le16 len_on_bd;
struct parsing_flags pars_flags;
- u16 sgl[8];
+ __le16 sgl[8];
};
@@ -2225,7 +2195,7 @@ struct eth_fast_path_rx_cqe {
* The data for RSS setup ramrod
*/
struct eth_halt_ramrod_data {
- u32 client_id_5b;
+ u32 client_id;
u32 reserved0;
};
@@ -2236,11 +2206,11 @@ struct eth_halt_ramrod_data {
struct eth_query_ramrod_data {
#if defined(__BIG_ENDIAN)
u8 reserved0;
- u8 collect_port_1b;
+ u8 collect_port;
u16 drv_counter;
#elif defined(__LITTLE_ENDIAN)
u16 drv_counter;
- u8 collect_port_1b;
+ u8 collect_port;
u8 reserved0;
#endif
u32 ctr_id_vector;
@@ -2251,8 +2221,8 @@ struct eth_query_ramrod_data {
* Place holder for ramrods protocol specific data
*/
struct ramrod_data {
- u32 data_lo;
- u32 data_hi;
+ __le32 data_lo;
+ __le32 data_hi;
};
/*
@@ -2264,16 +2234,6 @@ union eth_ramrod_data {
/*
- * Rx Last BD in page (in ETH)
- */
-struct eth_rx_bd_next_page {
- u32 addr_lo;
- u32 addr_hi;
- u8 reserved[8];
-};
-
-
-/*
* Eth Rx Cqe structure- general structure for ramrods
*/
struct common_ramrod_eth_rx_cqe {
@@ -2282,24 +2242,24 @@ struct common_ramrod_eth_rx_cqe {
#define COMMON_RAMROD_ETH_RX_CQE_TYPE_SHIFT 0
#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0 (0x7F<<1)
#define COMMON_RAMROD_ETH_RX_CQE_RESERVED0_SHIFT 1
- u8 conn_type_3b;
- u16 reserved1;
- u32 conn_and_cmd_data;
+ u8 conn_type;
+ __le16 reserved1;
+ __le32 conn_and_cmd_data;
#define COMMON_RAMROD_ETH_RX_CQE_CID (0xFFFFFF<<0)
#define COMMON_RAMROD_ETH_RX_CQE_CID_SHIFT 0
#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID (0xFF<<24)
#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT 24
struct ramrod_data protocol_data;
- u32 reserved2[4];
+ __le32 reserved2[4];
};
/*
* Rx Last CQE in page (in ETH)
*/
struct eth_rx_cqe_next_page {
- u32 addr_lo;
- u32 addr_hi;
- u32 reserved[6];
+ __le32 addr_lo;
+ __le32 addr_hi;
+ __le32 reserved[6];
};
/*
@@ -2316,17 +2276,17 @@ union eth_rx_cqe {
* common data for all protocols
*/
struct spe_hdr {
- u32 conn_and_cmd_data;
+ __le32 conn_and_cmd_data;
#define SPE_HDR_CID (0xFFFFFF<<0)
#define SPE_HDR_CID_SHIFT 0
#define SPE_HDR_CMD_ID (0xFF<<24)
#define SPE_HDR_CMD_ID_SHIFT 24
- u16 type;
+ __le16 type;
#define SPE_HDR_CONN_TYPE (0xFF<<0)
#define SPE_HDR_CONN_TYPE_SHIFT 0
#define SPE_HDR_COMMON_RAMROD (0xFF<<8)
#define SPE_HDR_COMMON_RAMROD_SHIFT 8
- u16 reserved;
+ __le16 reserved;
};
/*
@@ -2355,9 +2315,9 @@ struct eth_spe {
* doorbell data in host memory
*/
struct eth_tx_db_data {
- u32 packets_prod;
- u16 bds_prod;
- u16 reserved;
+ __le32 packets_prod;
+ __le16 bds_prod;
+ __le16 reserved;
};
@@ -2377,14 +2337,16 @@ struct tstorm_eth_function_common_config {
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3)
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE (0x1<<4)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE_SHIFT 4
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<5)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 5
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<6)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 6
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1FF<<7)
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x3F<<10)
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 10
#elif defined(__LITTLE_ENDIAN)
u16 config_flags;
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0)
@@ -2395,14 +2357,16 @@ struct tstorm_eth_function_common_config {
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3)
#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE (0x1<<4)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE_SHIFT 4
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<5)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 5
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<6)
-#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 6
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1FF<<7)
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x3F<<10)
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 10
u8 rss_result_mask;
u8 leading_client_id;
#endif
@@ -2422,7 +2386,7 @@ struct eth_update_ramrod_data {
* MAC filtering configuration command header
*/
struct mac_configuration_hdr {
- u8 length_6b;
+ u8 length;
u8 offset;
u16 client_id;
u32 reserved1;
@@ -2432,10 +2396,10 @@ struct mac_configuration_hdr {
* MAC address in list for ramrod
*/
struct tstorm_cam_entry {
- u16 lsb_mac_addr;
- u16 middle_mac_addr;
- u16 msb_mac_addr;
- u16 flags;
+ __le16 lsb_mac_addr;
+ __le16 middle_mac_addr;
+ __le16 msb_mac_addr;
+ __le16 flags;
#define TSTORM_CAM_ENTRY_PORT_ID (0x1<<0)
#define TSTORM_CAM_ENTRY_PORT_ID_SHIFT 0
#define TSTORM_CAM_ENTRY_RSRVVAL0 (0x7<<1)
@@ -2484,11 +2448,11 @@ struct mac_configuration_cmd {
* MAC address in list for ramrod
*/
struct mac_configuration_entry_e1h {
- u16 lsb_mac_addr;
- u16 middle_mac_addr;
- u16 msb_mac_addr;
- u16 vlan_id;
- u16 e1hov_id;
+ __le16 lsb_mac_addr;
+ __le16 middle_mac_addr;
+ __le16 msb_mac_addr;
+ __le16 vlan_id;
+ __le16 e1hov_id;
u8 client_id;
u8 flags;
#define MAC_CONFIGURATION_ENTRY_E1H_PORT (0x1<<0)
@@ -2544,24 +2508,28 @@ struct tstorm_eth_client_config {
#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0xFFF<<4)
#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 4
u16 config_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 2
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x1FFF<<3)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 3
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0)
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0
+#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1)
+#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2)
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<3)
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 3
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0xFFF<<4)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 4
#elif defined(__LITTLE_ENDIAN)
u16 config_flags;
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0)
-#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1)
-#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<2)
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 2
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x1FFF<<3)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 3
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0)
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0
+#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1)
+#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2)
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<3)
+#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 3
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0xFFF<<4)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 4
u16 drop_flags;
#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0)
#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0
@@ -2594,9 +2562,61 @@ struct tstorm_eth_mac_filter_config {
/*
+ * common flag to indicate existance of TPA.
+ */
+struct tstorm_eth_tpa_exist {
+#if defined(__BIG_ENDIAN)
+ u16 reserved1;
+ u8 reserved0;
+ u8 tpa_exist;
+#elif defined(__LITTLE_ENDIAN)
+ u8 tpa_exist;
+ u8 reserved0;
+ u16 reserved1;
+#endif
+ u32 reserved2;
+};
+
+
+/*
+ * rx rings pause data for E1h only
+ */
+struct ustorm_eth_rx_pause_data_e1h {
+#if defined(__BIG_ENDIAN)
+ u16 bd_thr_low;
+ u16 cqe_thr_low;
+#elif defined(__LITTLE_ENDIAN)
+ u16 cqe_thr_low;
+ u16 bd_thr_low;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 cos;
+ u16 sge_thr_low;
+#elif defined(__LITTLE_ENDIAN)
+ u16 sge_thr_low;
+ u16 cos;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 bd_thr_high;
+ u16 cqe_thr_high;
+#elif defined(__LITTLE_ENDIAN)
+ u16 cqe_thr_high;
+ u16 bd_thr_high;
+#endif
+#if defined(__BIG_ENDIAN)
+ u16 reserved0;
+ u16 sge_thr_high;
+#elif defined(__LITTLE_ENDIAN)
+ u16 sge_thr_high;
+ u16 reserved0;
+#endif
+};
+
+
+/*
* Three RX producers for ETH
*/
-struct tstorm_eth_rx_producers {
+struct ustorm_eth_rx_producers {
#if defined(__BIG_ENDIAN)
u16 bd_prod;
u16 cqe_prod;
@@ -2615,38 +2635,23 @@ struct tstorm_eth_rx_producers {
/*
- * common flag to indicate existence of TPA.
- */
-struct tstorm_eth_tpa_exist {
-#if defined(__BIG_ENDIAN)
- u16 reserved1;
- u8 reserved0;
- u8 tpa_exist;
-#elif defined(__LITTLE_ENDIAN)
- u8 tpa_exist;
- u8 reserved0;
- u16 reserved1;
-#endif
- u32 reserved2;
-};
-
-
-/*
* per-port SAFC demo variables
*/
struct cmng_flags_per_port {
u8 con_number[NUM_OF_PROTOCOLS];
-#if defined(__BIG_ENDIAN)
- u8 fairness_enable;
- u8 rate_shaping_enable;
- u8 cmng_protocol_enable;
- u8 cmng_vn_enable;
-#elif defined(__LITTLE_ENDIAN)
- u8 cmng_vn_enable;
- u8 cmng_protocol_enable;
- u8 rate_shaping_enable;
- u8 fairness_enable;
-#endif
+ u32 cmng_enables;
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_VN (0x1<<0)
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_VN_SHIFT 0
+#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN (0x1<<1)
+#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN_SHIFT 1
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_PROTOCOL (0x1<<2)
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_PROTOCOL_SHIFT 2
+#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL (0x1<<3)
+#define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL_SHIFT 3
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS (0x1<<4)
+#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_SHIFT 4
+#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0x7FFFFFF<<5)
+#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 5
};
@@ -2674,15 +2679,15 @@ struct fairness_vars_per_port {
*/
struct safc_struct_per_port {
#if defined(__BIG_ENDIAN)
- u16 __reserved0;
- u8 cur_cos_types;
+ u16 __reserved1;
+ u8 __reserved0;
u8 safc_timeout_usec;
#elif defined(__LITTLE_ENDIAN)
u8 safc_timeout_usec;
- u8 cur_cos_types;
- u16 __reserved0;
+ u8 __reserved0;
+ u16 __reserved1;
#endif
- u8 cos_to_protocol[MAX_COS_NUMBER];
+ u16 cos_to_pause_mask[NUM_OF_SAFC_BITS];
};
@@ -2702,16 +2707,16 @@ struct cmng_struct_per_port {
*/
struct xstorm_per_client_stats {
struct regpair total_sent_bytes;
- u32 total_sent_pkts;
- u32 unicast_pkts_sent;
+ __le32 total_sent_pkts;
+ __le32 unicast_pkts_sent;
struct regpair unicast_bytes_sent;
struct regpair multicast_bytes_sent;
- u32 multicast_pkts_sent;
- u32 broadcast_pkts_sent;
+ __le32 multicast_pkts_sent;
+ __le32 broadcast_pkts_sent;
struct regpair broadcast_bytes_sent;
- u16 stats_counter;
- u16 reserved0;
- u32 reserved1;
+ __le16 stats_counter;
+ __le16 reserved0;
+ __le32 reserved1;
};
@@ -2727,10 +2732,10 @@ struct xstorm_common_stats {
* Protocol-common statistics collected by the Tstorm (per port)
*/
struct tstorm_per_port_stats {
- u32 mac_filter_discard;
- u32 xxoverflow_discard;
- u32 brb_truncate_discard;
- u32 mac_discard;
+ __le32 mac_filter_discard;
+ __le32 xxoverflow_discard;
+ __le32 brb_truncate_discard;
+ __le32 mac_discard;
};
@@ -2743,17 +2748,17 @@ struct tstorm_per_client_stats {
struct regpair rcv_broadcast_bytes;
struct regpair rcv_multicast_bytes;
struct regpair rcv_error_bytes;
- u32 checksum_discard;
- u32 packets_too_big_discard;
- u32 total_rcv_pkts;
- u32 rcv_unicast_pkts;
- u32 rcv_broadcast_pkts;
- u32 rcv_multicast_pkts;
- u32 no_buff_discard;
- u32 ttl0_discard;
- u16 stats_counter;
- u16 reserved0;
- u32 reserved1;
+ __le32 checksum_discard;
+ __le32 packets_too_big_discard;
+ __le32 total_rcv_pkts;
+ __le32 rcv_unicast_pkts;
+ __le32 rcv_broadcast_pkts;
+ __le32 rcv_multicast_pkts;
+ __le32 no_buff_discard;
+ __le32 ttl0_discard;
+ __le16 stats_counter;
+ __le16 reserved0;
+ __le32 reserved1;
};
/*
@@ -2765,11 +2770,33 @@ struct tstorm_common_stats {
};
/*
+ * Protocol-common statistics collected by the Ustorm (per client)
+ */
+struct ustorm_per_client_stats {
+ struct regpair ucast_no_buff_bytes;
+ struct regpair mcast_no_buff_bytes;
+ struct regpair bcast_no_buff_bytes;
+ __le32 ucast_no_buff_pkts;
+ __le32 mcast_no_buff_pkts;
+ __le32 bcast_no_buff_pkts;
+ __le16 stats_counter;
+ __le16 reserved0;
+};
+
+/*
+ * Protocol-common statistics collected by the Ustorm
+ */
+struct ustorm_common_stats {
+ struct ustorm_per_client_stats client_statistics[MAX_U_STAT_COUNTER_ID];
+};
+
+/*
* Eth statistics query structure for the eth_stats_query ramrod
*/
struct eth_stats_query {
struct xstorm_common_stats xstorm_common;
struct tstorm_common_stats tstorm_common;
+ struct ustorm_common_stats ustorm_common;
};
@@ -2777,6 +2804,7 @@ struct eth_stats_query {
* per-vnic fairness variables
*/
struct fairness_vars_per_vn {
+ u32 cos_credit_delta[MAX_COS_NUMBER];
u32 protocol_credit_delta[NUM_OF_PROTOCOLS];
u32 vn_credit_delta;
u32 __reserved0;
@@ -2788,13 +2816,15 @@ struct fairness_vars_per_vn {
*/
struct fw_version {
#if defined(__BIG_ENDIAN)
- u16 patch;
- u8 primary;
- u8 client;
+ u8 engineering;
+ u8 revision;
+ u8 minor;
+ u8 major;
#elif defined(__LITTLE_ENDIAN)
- u8 client;
- u8 primary;
- u16 patch;
+ u8 major;
+ u8 minor;
+ u8 revision;
+ u8 engineering;
#endif
u32 flags;
#define FW_VERSION_OPTIMIZED (0x1<<0)
@@ -2812,9 +2842,10 @@ struct fw_version {
* FW version stored in first line of pram
*/
struct pram_fw_version {
- u8 client;
- u8 primary;
- u16 patch;
+ u8 major;
+ u8 minor;
+ u8 revision;
+ u8 engineering;
u8 flags;
#define PRAM_FW_VERSION_OPTIMIZED (0x1<<0)
#define PRAM_FW_VERSION_OPTIMIZED_SHIFT 0
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
index 3b0c2499ef17..39ba2936c0c2 100644
--- a/drivers/net/bnx2x_init.h
+++ b/drivers/net/bnx2x_init.h
@@ -1,6 +1,6 @@
/* bnx2x_init.h: Broadcom Everest network driver.
*
- * Copyright (c) 2007-2008 Broadcom Corporation
+ * Copyright (c) 2007-2009 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,12 +22,15 @@
#define INIT_ASIC 0x4
#define INIT_HARDWARE 0x7
-#define STORM_INTMEM_SIZE_E1 (0x5800 / 4)
-#define STORM_INTMEM_SIZE_E1H (0x10000 / 4)
-#define TSTORM_INTMEM_ADDR 0x1a0000
-#define CSTORM_INTMEM_ADDR 0x220000
-#define XSTORM_INTMEM_ADDR 0x2a0000
-#define USTORM_INTMEM_ADDR 0x320000
+#define TSTORM_INTMEM_ADDR TSEM_REG_FAST_MEMORY
+#define CSTORM_INTMEM_ADDR CSEM_REG_FAST_MEMORY
+#define XSTORM_INTMEM_ADDR XSEM_REG_FAST_MEMORY
+#define USTORM_INTMEM_ADDR USEM_REG_FAST_MEMORY
+/* RAM0 size in bytes */
+#define STORM_INTMEM_SIZE_E1 0x5800
+#define STORM_INTMEM_SIZE_E1H 0x10000
+#define STORM_INTMEM_SIZE(bp) ((CHIP_IS_E1H(bp) ? STORM_INTMEM_SIZE_E1H : \
+ STORM_INTMEM_SIZE_E1) / 4)
/* Init operation types and structures */
@@ -167,21 +170,24 @@ static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
{
- if ((len * 4) > FW_BUF_SIZE) {
- BNX2X_ERR("LARGE DMAE OPERATION ! addr 0x%x len 0x%x\n",
- addr, len*4);
- return;
- }
- memset(bp->gunzip_buf, fill, len * 4);
+ u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4));
+ u32 buf_len32 = buf_len / 4;
+ int i;
- bnx2x_write_big_buf(bp, addr, len);
+ memset(bp->gunzip_buf, fill, buf_len);
+
+ for (i = 0; i < len; i += buf_len32) {
+ u32 cur_len = min(buf_len32, len - i);
+
+ bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
+ }
}
static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
u32 len64)
{
- u32 buf_len32 = FW_BUF_SIZE/4;
- u32 len = len64*2;
+ u32 buf_len32 = FW_BUF_SIZE / 4;
+ u32 len = len64 * 2;
u64 data64 = 0;
int i;
@@ -270,6 +276,9 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
rc = bnx2x_gunzip(bp, (u8 *)data, len);
if (rc) {
BNX2X_ERR("gunzip failed ! rc %d\n", rc);
+#ifdef __BIG_ENDIAN
+ kfree(temp);
+#endif
return;
}
len = bp->gunzip_outlen;
@@ -422,57 +431,57 @@ struct arb_line {
/* derived configuration for each read queue for each max request size */
static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = {
- {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} },
- {{4 , 8 , 4}, {4 , 8 , 4}, {4 , 8 , 4}, {4 , 8 , 4} },
- {{4 , 3 , 3}, {4 , 3 , 3}, {4 , 3 , 3}, {4 , 3 , 3} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {16 , 3 , 11}, {16 , 3 , 11} },
- {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} },
- {{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81}, {64 , 64 , 120} }
+/* 1 */ { {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
+ { {4, 8, 4}, {4, 8, 4}, {4, 8, 4}, {4, 8, 4} },
+ { {4, 3, 3}, {4, 3, 3}, {4, 3, 3}, {4, 3, 3} },
+ { {8, 3, 6}, {16, 3, 11}, {16, 3, 11}, {16, 3, 11} },
+ { {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
+/* 10 */{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+/* 20 */{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
+ { {8, 64, 25}, {16, 64, 41}, {32, 64, 81}, {64, 64, 120} }
};
/* derived configuration for each write queue for each max request size */
static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
- {{4 , 6 , 3}, {4 , 6 , 3}, {4 , 6 , 3} },
- {{4 , 2 , 3}, {4 , 2 , 3}, {4 , 2 , 3} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} },
- {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} },
- {{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} },
- {{8 , 9 , 6}, {16 , 9 , 11}, {32 , 9 , 21} },
- {{8 , 47 , 19}, {16 , 47 , 19}, {32 , 47 , 21} },
- {{8 , 9 , 6}, {16 , 9 , 11}, {16 , 9 , 11} },
- {{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81} }
+/* 1 */ { {4, 6, 3}, {4, 6, 3}, {4, 6, 3} },
+ { {4, 2, 3}, {4, 2, 3}, {4, 2, 3} },
+ { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
+ { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
+ { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
+ { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
+ { {8, 64, 25}, {16, 64, 25}, {32, 64, 25} },
+ { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
+ { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
+/* 10 */{ {8, 9, 6}, {16, 9, 11}, {32, 9, 21} },
+ { {8, 47, 19}, {16, 47, 19}, {32, 47, 21} },
+ { {8, 9, 6}, {16, 9, 11}, {16, 9, 11} },
+ { {8, 64, 25}, {16, 64, 41}, {32, 64, 81} }
};
/* register addresses for read queues */
static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
- {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
+/* 1 */ {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
PXP2_REG_RQ_BW_RD_UBOUND0},
{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
PXP2_REG_PSWRQ_BW_UB1},
@@ -490,7 +499,7 @@ static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
PXP2_REG_PSWRQ_BW_UB7},
{PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
PXP2_REG_PSWRQ_BW_UB8},
- {PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
+/* 10 */{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
PXP2_REG_PSWRQ_BW_UB9},
{PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
PXP2_REG_PSWRQ_BW_UB10},
@@ -510,7 +519,7 @@ static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
PXP2_REG_RQ_BW_RD_UBOUND17},
{PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18,
PXP2_REG_RQ_BW_RD_UBOUND18},
- {PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
+/* 20 */{PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
PXP2_REG_RQ_BW_RD_UBOUND19},
{PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20,
PXP2_REG_RQ_BW_RD_UBOUND20},
@@ -532,7 +541,7 @@ static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
/* register addresses for write queues */
static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
- {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
+/* 1 */ {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
PXP2_REG_PSWRQ_BW_UB1},
{PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
PXP2_REG_PSWRQ_BW_UB2},
@@ -550,7 +559,7 @@ static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
PXP2_REG_PSWRQ_BW_UB10},
{PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
PXP2_REG_PSWRQ_BW_UB11},
- {PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
+/* 10 */{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
PXP2_REG_PSWRQ_BW_UB28},
{PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29,
PXP2_REG_RQ_BW_WR_UBOUND29},
@@ -568,7 +577,12 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
- r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+ if (bp->mrrs == -1)
+ r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+ else {
+ DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
+ r_order = bp->mrrs;
+ }
if (r_order > MAX_RD_ORD) {
DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
@@ -643,17 +657,18 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
if (CHIP_IS_E1H(bp)) {
- REG_WR(bp, PXP2_REG_WR_HC_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_USDM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_CSDM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_TSDM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_XSDM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_QM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_TM_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_SRC_MPS, w_order+1);
- REG_WR(bp, PXP2_REG_WR_DBG_MPS, w_order+1);
+ val = ((w_order == 0) ? 2 : 3);
+ REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_QM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
+ REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
- REG_WR(bp, PXP2_REG_WR_CDU_MPS, w_order+1);
+ REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
}
}
diff --git a/drivers/net/bnx2x_init_values.h b/drivers/net/bnx2x_init_values.h
index 9755bf6b08dd..1f22c9ab66d4 100644
--- a/drivers/net/bnx2x_init_values.h
+++ b/drivers/net/bnx2x_init_values.h
@@ -1,7 +1,23 @@
#ifndef __BNX2X_INIT_VALUES_H__
#define __BNX2X_INIT_VALUES_H__
-/* This array contains the list of operations needed to initialize the chip.
+/* bnx2x_init_values.h: Broadcom NX2 10G network driver.
+ *
+ * Copyright (c) 2007-2009 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, except as noted below.
+ *
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2007-2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ *
+ *
+ * This array contains the list of operations needed to initialize the chip.
*
* For each block in the chip there are three init stages:
* common - HW used by both ports,
@@ -47,12 +63,16 @@ static const struct raw_op init_ops[] = {
{OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_1, 0x10100000},
{OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2, 0x20100000},
{OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3, 0x30100000},
- {OP_ZR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x4},
+ {OP_ZR_E1, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x4},
+ {OP_WR_E1H, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x40100000},
+ {OP_ZR_E1H, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_5, 0x3},
{OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_0, 0x100000},
{OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_1, 0x12140000},
{OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_2, 0x22140000},
{OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_3, 0x32140000},
- {OP_ZR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x4},
+ {OP_ZR_E1, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x4},
+ {OP_WR_E1H, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x42140000},
+ {OP_ZR_E1H, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_5, 0x3},
{OP_RD, PRS_REG_NUM_OF_PACKETS, 0x0},
{OP_RD, PRS_REG_NUM_OF_CFC_FLUSH_MESSAGES, 0x0},
{OP_RD, PRS_REG_NUM_OF_TRANSPARENT_FLUSH_MESSAGES, 0x0},
@@ -71,15 +91,16 @@ static const struct raw_op init_ops[] = {
{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_1, 0x3f},
{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_2, 0x3f},
{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_3, 0x3f},
- {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_4, 0x0},
+ {OP_WR_E1, PRS_REG_PACKET_REGIONS_TYPE_4, 0x0},
+ {OP_WR_E1H, PRS_REG_PACKET_REGIONS_TYPE_4, 0x3f},
{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_5, 0x3f},
{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_6, 0x3f},
{OP_WR, PRS_REG_PACKET_REGIONS_TYPE_7, 0x3f},
-#define PRS_COMMON_END 47
-#define SRCH_COMMON_START 47
+#define PRS_COMMON_END 52
+#define SRCH_COMMON_START 52
{OP_WR_E1H, SRC_REG_E1HMF_ENABLE, 0x1},
-#define SRCH_COMMON_END 48
-#define TSDM_COMMON_START 48
+#define SRCH_COMMON_END 53
+#define TSDM_COMMON_START 53
{OP_WR_E1, TSDM_REG_CFC_RSP_START_ADDR, 0x411},
{OP_WR_E1H, TSDM_REG_CFC_RSP_START_ADDR, 0x211},
{OP_WR_E1, TSDM_REG_CMP_COUNTER_START_ADDR, 0x400},
@@ -92,10 +113,15 @@ static const struct raw_op init_ops[] = {
{OP_WR, TSDM_REG_CMP_COUNTER_MAX1, 0xffff},
{OP_WR, TSDM_REG_CMP_COUNTER_MAX2, 0xffff},
{OP_WR, TSDM_REG_CMP_COUNTER_MAX3, 0xffff},
- {OP_ZR, TSDM_REG_AGG_INT_EVENT_0, 0x2},
+ {OP_ZR_E1, TSDM_REG_AGG_INT_EVENT_0, 0x2},
+ {OP_WR_E1H, TSDM_REG_AGG_INT_EVENT_0, 0x20},
+ {OP_WR_E1H, TSDM_REG_AGG_INT_EVENT_1, 0x0},
{OP_WR, TSDM_REG_AGG_INT_EVENT_2, 0x34},
{OP_WR, TSDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_ZR, TSDM_REG_AGG_INT_EVENT_4, 0x7c},
+ {OP_ZR_E1, TSDM_REG_AGG_INT_EVENT_4, 0x7c},
+ {OP_ZR_E1H, TSDM_REG_AGG_INT_EVENT_4, 0x1c},
+ {OP_WR_E1H, TSDM_REG_AGG_INT_T_0, 0x1},
+ {OP_ZR_E1H, TSDM_REG_AGG_INT_T_1, 0x5f},
{OP_WR, TSDM_REG_ENABLE_IN1, 0x7ffffff},
{OP_WR, TSDM_REG_ENABLE_IN2, 0x3f},
{OP_WR, TSDM_REG_ENABLE_OUT1, 0x7ffffff},
@@ -118,8 +144,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_ASIC, TSDM_REG_TIMER_TICK, 0x3e8},
{OP_WR_EMUL, TSDM_REG_TIMER_TICK, 0x1},
{OP_WR_FPGA, TSDM_REG_TIMER_TICK, 0xa},
-#define TSDM_COMMON_END 86
-#define TCM_COMMON_START 86
+#define TSDM_COMMON_END 96
+#define TCM_COMMON_START 96
{OP_WR, TCM_REG_XX_MAX_LL_SZ, 0x20},
{OP_WR, TCM_REG_XX_OVFL_EVNT_ID, 0x32},
{OP_WR, TCM_REG_TQM_TCM_HDR_P, 0x2150020},
@@ -129,10 +155,16 @@ static const struct raw_op init_ops[] = {
{OP_WR, TCM_REG_ERR_EVNT_ID, 0x33},
{OP_WR, TCM_REG_EXPR_EVNT_ID, 0x30},
{OP_WR, TCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, TCM_REG_PRS_WEIGHT, 0x4},
- {OP_WR, TCM_REG_PBF_WEIGHT, 0x5},
+ {OP_WR, TCM_REG_STORM_WEIGHT, 0x2},
+ {OP_WR, TCM_REG_PRS_WEIGHT, 0x5},
+ {OP_WR, TCM_REG_PBF_WEIGHT, 0x6},
+ {OP_WR, TCM_REG_USEM_WEIGHT, 0x2},
+ {OP_WR, TCM_REG_CSEM_WEIGHT, 0x2},
{OP_WR, TCM_REG_CP_WEIGHT, 0x0},
- {OP_WR, TCM_REG_TSDM_WEIGHT, 0x4},
+ {OP_WR, TCM_REG_TSDM_WEIGHT, 0x5},
+ {OP_WR, TCM_REG_TQM_P_WEIGHT, 0x2},
+ {OP_WR, TCM_REG_TQM_S_WEIGHT, 0x2},
+ {OP_WR, TCM_REG_TM_WEIGHT, 0x2},
{OP_WR, TCM_REG_TCM_TQM_USE_Q, 0x1},
{OP_WR, TCM_REG_GR_ARB_TYPE, 0x1},
{OP_WR, TCM_REG_GR_LD0_PR, 0x1},
@@ -149,7 +181,9 @@ static const struct raw_op init_ops[] = {
{OP_WR, TCM_REG_N_SM_CTX_LD_1, 0x7},
{OP_WR, TCM_REG_N_SM_CTX_LD_2, 0x8},
{OP_WR, TCM_REG_N_SM_CTX_LD_3, 0x8},
- {OP_ZR, TCM_REG_N_SM_CTX_LD_4, 0x4},
+ {OP_ZR_E1, TCM_REG_N_SM_CTX_LD_4, 0x4},
+ {OP_WR_E1H, TCM_REG_N_SM_CTX_LD_4, 0x1},
+ {OP_ZR_E1H, TCM_REG_N_SM_CTX_LD_5, 0x3},
{OP_WR, TCM_REG_TCM_REG0_SZ, 0x6},
{OP_WR_E1, TCM_REG_PHYS_QNUM0_0, 0xd},
{OP_WR_E1, TCM_REG_PHYS_QNUM0_1, 0x2d},
@@ -175,75 +209,75 @@ static const struct raw_op init_ops[] = {
{OP_WR, TCM_REG_CDU_SM_WR_IFEN, 0x1},
{OP_WR, TCM_REG_CDU_SM_RD_IFEN, 0x1},
{OP_WR, TCM_REG_TCM_CFC_IFEN, 0x1},
-#define TCM_COMMON_END 141
-#define TCM_FUNC0_START 141
+#define TCM_COMMON_END 159
+#define TCM_FUNC0_START 159
{OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0xd},
{OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x7},
{OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x7},
{OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x7},
-#define TCM_FUNC0_END 145
-#define TCM_FUNC1_START 145
+#define TCM_FUNC0_END 163
+#define TCM_FUNC1_START 163
{OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x2d},
{OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x27},
{OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x27},
{OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x27},
-#define TCM_FUNC1_END 149
-#define TCM_FUNC2_START 149
+#define TCM_FUNC1_END 167
+#define TCM_FUNC2_START 167
{OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x1d},
{OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x17},
{OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x17},
{OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x17},
-#define TCM_FUNC2_END 153
-#define TCM_FUNC3_START 153
+#define TCM_FUNC2_END 171
+#define TCM_FUNC3_START 171
{OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x3d},
{OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x37},
{OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x37},
{OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x37},
-#define TCM_FUNC3_END 157
-#define TCM_FUNC4_START 157
+#define TCM_FUNC3_END 175
+#define TCM_FUNC4_START 175
{OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x4d},
{OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x47},
{OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x47},
{OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x47},
-#define TCM_FUNC4_END 161
-#define TCM_FUNC5_START 161
+#define TCM_FUNC4_END 179
+#define TCM_FUNC5_START 179
{OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x6d},
{OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x67},
{OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x67},
{OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x67},
-#define TCM_FUNC5_END 165
-#define TCM_FUNC6_START 165
+#define TCM_FUNC5_END 183
+#define TCM_FUNC6_START 183
{OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x5d},
{OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x57},
{OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x57},
{OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x57},
-#define TCM_FUNC6_END 169
-#define TCM_FUNC7_START 169
+#define TCM_FUNC6_END 187
+#define TCM_FUNC7_START 187
{OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x7d},
{OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x77},
{OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x77},
{OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x77},
-#define TCM_FUNC7_END 173
-#define BRB1_COMMON_START 173
+#define TCM_FUNC7_END 191
+#define BRB1_COMMON_START 191
{OP_SW, BRB1_REG_LL_RAM, 0x2000020},
{OP_WR, BRB1_REG_SOFT_RESET, 0x1},
{OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_4, 0x0},
{OP_SW, BRB1_REG_FREE_LIST_PRS_CRDT, 0x30220},
{OP_WR, BRB1_REG_SOFT_RESET, 0x0},
-#define BRB1_COMMON_END 178
-#define BRB1_PORT0_START 178
+#define BRB1_COMMON_END 196
+#define BRB1_PORT0_START 196
{OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0xb8},
{OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 0x114},
{OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_0, 0x0},
{OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_0, 0x0},
-#define BRB1_PORT0_END 182
-#define BRB1_PORT1_START 182
+#define BRB1_PORT0_END 200
+#define BRB1_PORT1_START 200
{OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0xb8},
{OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 0x114},
{OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_1, 0x0},
{OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_1, 0x0},
-#define BRB1_PORT1_END 186
-#define TSEM_COMMON_START 186
+#define BRB1_PORT1_END 204
+#define TSEM_COMMON_START 204
{OP_RD, TSEM_REG_MSG_NUM_FIC0, 0x0},
{OP_RD, TSEM_REG_MSG_NUM_FIC1, 0x0},
{OP_RD, TSEM_REG_MSG_NUM_FOC0, 0x0},
@@ -303,143 +337,166 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa020, 0xc8},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c18, 0x4},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa000, 0x2},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c10, 0x2},
{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad0, 0x0},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad8, 0x4},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3b28, 0x6},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3678, 0x6},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x810, 0x4},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3670, 0x2},
{OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x40224},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5008, 0x4},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
{OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x4cb0, 0x80228},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5008, 0x4},
+ {OP_ZP_E1, TSEM_REG_INT_TABLE, 0x930000},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5018, 0x4},
- {OP_ZP_E1, TSEM_REG_INT_TABLE, 0x940000},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5028, 0x4},
{OP_WR_64_E1, TSEM_REG_INT_TABLE + 0x360, 0x140230},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5028, 0x4},
+ {OP_ZP_E1, TSEM_REG_PRAM, 0x324f0000},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5038, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM, 0x30b10000},
+ {OP_ZP_E1, TSEM_REG_PRAM + 0x8000, 0x33250c94},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5048, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM + 0x8000, 0x33c50c2d},
+ {OP_ZP_E1, TSEM_REG_PRAM + 0x10000, 0xe4d195e},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5058, 0x4},
- {OP_ZP_E1, TSEM_REG_PRAM + 0x10000, 0xbc6191f},
+ {OP_WR_64_E1, TSEM_REG_PRAM + 0x11e00, 0x5c400232},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5068, 0x4},
- {OP_WR_64_E1, TSEM_REG_PRAM + 0x117f0, 0x5d020232},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5078, 0x2},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x6140, 0x200224},
- {OP_ZP_E1H, TSEM_REG_INT_TABLE, 0x960000},
- {OP_WR_64_E1H, TSEM_REG_INT_TABLE + 0x360, 0x140244},
- {OP_ZP_E1H, TSEM_REG_PRAM, 0x30cc0000},
- {OP_ZP_E1H, TSEM_REG_PRAM + 0x8000, 0x33df0c33},
- {OP_ZP_E1H, TSEM_REG_PRAM + 0x10000, 0xdce192b},
- {OP_WR_64_E1H, TSEM_REG_PRAM + 0x11c70, 0x5c720246},
-#define TSEM_COMMON_END 276
-#define TSEM_PORT0_START 276
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x62c0, 0x200224},
+ {OP_ZP_E1H, TSEM_REG_INT_TABLE, 0x9b0000},
+ {OP_WR_64_E1H, TSEM_REG_INT_TABLE + 0x398, 0xd0244},
+ {OP_ZP_E1H, TSEM_REG_PRAM, 0x325e0000},
+ {OP_ZP_E1H, TSEM_REG_PRAM + 0x8000, 0x35960c98},
+ {OP_ZP_E1H, TSEM_REG_PRAM + 0x10000, 0x1aea19fe},
+ {OP_WR_64_E1H, TSEM_REG_PRAM + 0x143d0, 0x57860246},
+#define TSEM_COMMON_END 297
+#define TSEM_PORT0_START 297
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x22c8, 0x20},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x2000, 0x16c},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x4000, 0xfc},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x4000, 0x16c},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb000, 0x28},
{OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b60, 0x0},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb140, 0xc},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1400, 0xa},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32c0, 0x12},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1450, 0x6},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3350, 0xfa},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3350, 0x64},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500, 0x2},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8108, 0x2},
+ {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1500 + 0x8, 0x50234},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500 + 0x1c, 0x7},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1570, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x9c0, 0xbe},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x9c0, 0x4c},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x820, 0xe},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x20234},
+ {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x20239},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2908, 0x2},
-#define TSEM_PORT0_END 294
-#define TSEM_PORT1_START 294
+#define TSEM_PORT0_END 317
+#define TSEM_PORT1_START 317
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2348, 0x20},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x25b0, 0x16c},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x43f0, 0xfc},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x45b0, 0x16c},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb0a0, 0x28},
{OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b64, 0x0},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb170, 0xc},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1428, 0xa},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3308, 0x12},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1468, 0x6},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3738, 0xfa},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x34e0, 0x64},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538, 0x2},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8110, 0x2},
+ {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1538 + 0x8, 0x5023b},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538 + 0x1c, 0x7},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x15b8, 0x12},
- {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0xcb8, 0xbe},
+ {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0xaf0, 0x4c},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x858, 0xe},
- {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb8, 0x20236},
+ {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb8, 0x20240},
{OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2910, 0x2},
-#define TSEM_PORT1_END 312
-#define TSEM_FUNC0_START 312
+#define TSEM_PORT1_END 337
+#define TSEM_FUNC0_START 337
{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b60, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000, 0x2},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3000 + 0x8, 0x50248},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000 + 0x1c, 0x7},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31c0, 0x8},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5080, 0x12},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
-#define TSEM_FUNC0_END 318
-#define TSEM_FUNC1_START 318
+#define TSEM_FUNC0_END 345
+#define TSEM_FUNC1_START 345
{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b64, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038, 0x2},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3038 + 0x8, 0x5024d},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038 + 0x1c, 0x7},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31e0, 0x8},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5010, 0x2},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x50c8, 0x12},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
-#define TSEM_FUNC1_END 324
-#define TSEM_FUNC2_START 324
+#define TSEM_FUNC1_END 353
+#define TSEM_FUNC2_START 353
{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b68, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070, 0x2},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3070 + 0x8, 0x50252},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070 + 0x1c, 0x7},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3200, 0x8},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5020, 0x2},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5110, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4010, 0x20248},
-#define TSEM_FUNC2_END 330
-#define TSEM_FUNC3_START 330
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4010, 0x20257},
+#define TSEM_FUNC2_END 361
+#define TSEM_FUNC3_START 361
{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b6c, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8, 0x2},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x30a8 + 0x8, 0x50259},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8 + 0x1c, 0x7},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3220, 0x8},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5030, 0x2},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5158, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4018, 0x2024a},
-#define TSEM_FUNC3_END 336
-#define TSEM_FUNC4_START 336
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4018, 0x2025e},
+#define TSEM_FUNC3_END 369
+#define TSEM_FUNC4_START 369
{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b70, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0, 0x2},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x30e0 + 0x8, 0x50260},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0 + 0x1c, 0x7},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3240, 0x8},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5040, 0x2},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51a0, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4020, 0x2024c},
-#define TSEM_FUNC4_END 342
-#define TSEM_FUNC5_START 342
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4020, 0x20265},
+#define TSEM_FUNC4_END 377
+#define TSEM_FUNC5_START 377
{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b74, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118, 0x2},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3118 + 0x8, 0x50267},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118 + 0x1c, 0x7},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3260, 0x8},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5050, 0x2},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51e8, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4028, 0x2024e},
-#define TSEM_FUNC5_END 348
-#define TSEM_FUNC6_START 348
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4028, 0x2026c},
+#define TSEM_FUNC5_END 385
+#define TSEM_FUNC6_START 385
{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b78, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150, 0x2},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3150 + 0x8, 0x5026e},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150 + 0x1c, 0x7},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3280, 0x8},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5060, 0x2},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5230, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4030, 0x20250},
-#define TSEM_FUNC6_END 354
-#define TSEM_FUNC7_START 354
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4030, 0x20273},
+#define TSEM_FUNC6_END 393
+#define TSEM_FUNC7_START 393
{OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b7c, 0x0},
- {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188, 0xe},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188, 0x2},
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3188 + 0x8, 0x50275},
+ {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188 + 0x1c, 0x7},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32a0, 0x8},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5070, 0x2},
{OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5278, 0x12},
- {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4038, 0x20252},
-#define TSEM_FUNC7_END 360
-#define MISC_COMMON_START 360
+ {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4038, 0x2027a},
+#define TSEM_FUNC7_END 401
+#define MISC_COMMON_START 401
{OP_WR_E1, MISC_REG_GRC_TIMEOUT_EN, 0x1},
{OP_WR, MISC_REG_PLL_STORM_CTRL_1, 0x71d2911},
{OP_WR, MISC_REG_PLL_STORM_CTRL_2, 0x0},
@@ -447,39 +504,39 @@ static const struct raw_op init_ops[] = {
{OP_WR, MISC_REG_PLL_STORM_CTRL_4, 0x0},
{OP_WR, MISC_REG_LCPLL_CTRL_1, 0x209},
{OP_WR_E1, MISC_REG_SPIO, 0xff000000},
-#define MISC_COMMON_END 367
-#define MISC_FUNC0_START 367
+#define MISC_COMMON_END 408
+#define MISC_FUNC0_START 408
{OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC0_END 368
-#define MISC_FUNC1_START 368
+#define MISC_FUNC0_END 409
+#define MISC_FUNC1_START 409
{OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC1_END 369
-#define MISC_FUNC2_START 369
+#define MISC_FUNC1_END 410
+#define MISC_FUNC2_START 410
{OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC2_END 370
-#define MISC_FUNC3_START 370
+#define MISC_FUNC2_END 411
+#define MISC_FUNC3_START 411
{OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC3_END 371
-#define MISC_FUNC4_START 371
+#define MISC_FUNC3_END 412
+#define MISC_FUNC4_START 412
{OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC4_END 372
-#define MISC_FUNC5_START 372
+#define MISC_FUNC4_END 413
+#define MISC_FUNC5_START 413
{OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC5_END 373
-#define MISC_FUNC6_START 373
+#define MISC_FUNC5_END 414
+#define MISC_FUNC6_START 414
{OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC6_END 374
-#define MISC_FUNC7_START 374
+#define MISC_FUNC6_END 415
+#define MISC_FUNC7_START 415
{OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC7_END 375
-#define NIG_COMMON_START 375
+#define MISC_FUNC7_END 416
+#define NIG_COMMON_START 416
{OP_WR, NIG_REG_PBF_LB_IN_EN, 0x1},
{OP_WR, NIG_REG_PRS_REQ_IN_EN, 0x1},
{OP_WR, NIG_REG_EGRESS_DEBUG_IN_EN, 0x1},
{OP_WR, NIG_REG_BRB_LB_OUT_EN, 0x1},
{OP_WR, NIG_REG_PRS_EOP_OUT_EN, 0x1},
-#define NIG_COMMON_END 380
-#define NIG_PORT0_START 380
+#define NIG_COMMON_END 421
+#define NIG_PORT0_START 421
{OP_WR, NIG_REG_LLH0_CM_HEADER, 0x300000},
{OP_WR, NIG_REG_LLH0_EVENT_ID, 0x28},
{OP_WR, NIG_REG_LLH0_ERROR_MASK, 0x0},
@@ -492,8 +549,8 @@ static const struct raw_op init_ops[] = {
{OP_WR, NIG_REG_EGRESS_PBF0_IN_EN, 0x1},
{OP_WR, NIG_REG_BRB0_OUT_EN, 0x1},
{OP_WR, NIG_REG_XCM0_OUT_EN, 0x1},
-#define NIG_PORT0_END 392
-#define NIG_PORT1_START 392
+#define NIG_PORT0_END 433
+#define NIG_PORT1_START 433
{OP_WR, NIG_REG_LLH1_CM_HEADER, 0x300000},
{OP_WR, NIG_REG_LLH1_EVENT_ID, 0x28},
{OP_WR, NIG_REG_LLH1_ERROR_MASK, 0x0},
@@ -506,11 +563,11 @@ static const struct raw_op init_ops[] = {
{OP_WR, NIG_REG_EGRESS_PBF1_IN_EN, 0x1},
{OP_WR, NIG_REG_BRB1_OUT_EN, 0x1},
{OP_WR, NIG_REG_XCM1_OUT_EN, 0x1},
-#define NIG_PORT1_END 404
-#define UPB_COMMON_START 404
+#define NIG_PORT1_END 445
+#define UPB_COMMON_START 445
{OP_WR, GRCBASE_UPB + PB_REG_CONTROL, 0x20},
-#define UPB_COMMON_END 405
-#define CSDM_COMMON_START 405
+#define UPB_COMMON_END 446
+#define CSDM_COMMON_START 446
{OP_WR_E1, CSDM_REG_CFC_RSP_START_ADDR, 0xa11},
{OP_WR_E1H, CSDM_REG_CFC_RSP_START_ADDR, 0x211},
{OP_WR_E1, CSDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
@@ -550,8 +607,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_ASIC, CSDM_REG_TIMER_TICK, 0x3e8},
{OP_WR_EMUL, CSDM_REG_TIMER_TICK, 0x1},
{OP_WR_FPGA, CSDM_REG_TIMER_TICK, 0xa},
-#define CSDM_COMMON_END 444
-#define USDM_COMMON_START 444
+#define CSDM_COMMON_END 485
+#define USDM_COMMON_START 485
{OP_WR_E1, USDM_REG_CFC_RSP_START_ADDR, 0xa11},
{OP_WR_E1H, USDM_REG_CFC_RSP_START_ADDR, 0x411},
{OP_WR_E1, USDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
@@ -568,9 +625,14 @@ static const struct raw_op init_ops[] = {
{OP_WR, USDM_REG_AGG_INT_EVENT_1, 0x5},
{OP_WR, USDM_REG_AGG_INT_EVENT_2, 0x34},
{OP_WR, USDM_REG_AGG_INT_EVENT_3, 0x35},
- {OP_ZR, USDM_REG_AGG_INT_EVENT_4, 0x5c},
+ {OP_ZR_E1, USDM_REG_AGG_INT_EVENT_4, 0x5c},
+ {OP_WR_E1H, USDM_REG_AGG_INT_EVENT_4, 0x7},
+ {OP_ZR_E1H, USDM_REG_AGG_INT_EVENT_5, 0x5b},
{OP_WR, USDM_REG_AGG_INT_MODE_0, 0x1},
- {OP_ZR, USDM_REG_AGG_INT_MODE_1, 0x1f},
+ {OP_ZR_E1, USDM_REG_AGG_INT_MODE_1, 0x1f},
+ {OP_ZR_E1H, USDM_REG_AGG_INT_MODE_1, 0x3},
+ {OP_WR_E1H, USDM_REG_AGG_INT_MODE_4, 0x1},
+ {OP_ZR_E1H, USDM_REG_AGG_INT_MODE_5, 0x1b},
{OP_WR, USDM_REG_ENABLE_IN1, 0x7ffffff},
{OP_WR, USDM_REG_ENABLE_IN2, 0x3f},
{OP_WR, USDM_REG_ENABLE_OUT1, 0x7ffffff},
@@ -594,18 +656,21 @@ static const struct raw_op init_ops[] = {
{OP_WR_ASIC, USDM_REG_TIMER_TICK, 0x3e8},
{OP_WR_EMUL, USDM_REG_TIMER_TICK, 0x1},
{OP_WR_FPGA, USDM_REG_TIMER_TICK, 0xa},
-#define USDM_COMMON_END 486
-#define CCM_COMMON_START 486
+#define USDM_COMMON_END 532
+#define CCM_COMMON_START 532
{OP_WR, CCM_REG_XX_OVFL_EVNT_ID, 0x32},
{OP_WR, CCM_REG_CQM_CCM_HDR_P, 0x2150020},
{OP_WR, CCM_REG_CQM_CCM_HDR_S, 0x2150020},
{OP_WR, CCM_REG_ERR_CCM_HDR, 0x8100000},
{OP_WR, CCM_REG_ERR_EVNT_ID, 0x33},
+ {OP_WR, CCM_REG_STORM_WEIGHT, 0x2},
{OP_WR, CCM_REG_TSEM_WEIGHT, 0x0},
- {OP_WR, CCM_REG_XSEM_WEIGHT, 0x4},
- {OP_WR, CCM_REG_USEM_WEIGHT, 0x4},
+ {OP_WR, CCM_REG_XSEM_WEIGHT, 0x5},
+ {OP_WR, CCM_REG_USEM_WEIGHT, 0x5},
{OP_ZR, CCM_REG_PBF_WEIGHT, 0x2},
- {OP_WR, CCM_REG_CQM_P_WEIGHT, 0x2},
+ {OP_WR, CCM_REG_CSDM_WEIGHT, 0x2},
+ {OP_WR, CCM_REG_CQM_P_WEIGHT, 0x3},
+ {OP_WR, CCM_REG_CQM_S_WEIGHT, 0x2},
{OP_WR, CCM_REG_CCM_CQM_USE_Q, 0x1},
{OP_WR, CCM_REG_CNT_AUX1_Q, 0x2},
{OP_WR, CCM_REG_CNT_AUX2_Q, 0x2},
@@ -620,8 +685,8 @@ static const struct raw_op init_ops[] = {
{OP_WR, CCM_REG_XX_INIT_CRD, 0x3},
{OP_WR, CCM_REG_XX_MSG_NUM, 0x18},
{OP_ZR, CCM_REG_XX_TABLE, 0x12},
- {OP_SW_E1, CCM_REG_XX_DESCR_TABLE, 0x240238},
- {OP_SW_E1H, CCM_REG_XX_DESCR_TABLE, 0x240254},
+ {OP_SW_E1, CCM_REG_XX_DESCR_TABLE, 0x240242},
+ {OP_SW_E1H, CCM_REG_XX_DESCR_TABLE, 0x24027c},
{OP_WR, CCM_REG_N_SM_CTX_LD_0, 0x1},
{OP_WR, CCM_REG_N_SM_CTX_LD_1, 0x2},
{OP_WR, CCM_REG_N_SM_CTX_LD_2, 0x8},
@@ -657,8 +722,8 @@ static const struct raw_op init_ops[] = {
{OP_WR, CCM_REG_CDU_SM_WR_IFEN, 0x1},
{OP_WR, CCM_REG_CDU_SM_RD_IFEN, 0x1},
{OP_WR, CCM_REG_CCM_CFC_IFEN, 0x1},
-#define CCM_COMMON_END 547
-#define CCM_FUNC0_START 547
+#define CCM_COMMON_END 596
+#define CCM_FUNC0_START 596
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x7},
@@ -666,8 +731,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0xc},
{OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0xb},
{OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x7},
-#define CCM_FUNC0_END 554
-#define CCM_FUNC1_START 554
+#define CCM_FUNC0_END 603
+#define CCM_FUNC1_START 603
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x27},
@@ -675,8 +740,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x2c},
{OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x2b},
{OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x27},
-#define CCM_FUNC1_END 561
-#define CCM_FUNC2_START 561
+#define CCM_FUNC1_END 610
+#define CCM_FUNC2_START 610
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x19},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x1a},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x17},
@@ -684,8 +749,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x1c},
{OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x1b},
{OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x17},
-#define CCM_FUNC2_END 568
-#define CCM_FUNC3_START 568
+#define CCM_FUNC2_END 617
+#define CCM_FUNC3_START 617
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x39},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x3a},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x37},
@@ -693,8 +758,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x3c},
{OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x3b},
{OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x37},
-#define CCM_FUNC3_END 575
-#define CCM_FUNC4_START 575
+#define CCM_FUNC3_END 624
+#define CCM_FUNC4_START 624
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x49},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x4a},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x47},
@@ -702,8 +767,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x4c},
{OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x4b},
{OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x47},
-#define CCM_FUNC4_END 582
-#define CCM_FUNC5_START 582
+#define CCM_FUNC4_END 631
+#define CCM_FUNC5_START 631
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x69},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x6a},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x67},
@@ -711,8 +776,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x6c},
{OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x6b},
{OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x67},
-#define CCM_FUNC5_END 589
-#define CCM_FUNC6_START 589
+#define CCM_FUNC5_END 638
+#define CCM_FUNC6_START 638
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x59},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x5a},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x57},
@@ -720,8 +785,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x5c},
{OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x5b},
{OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x57},
-#define CCM_FUNC6_END 596
-#define CCM_FUNC7_START 596
+#define CCM_FUNC6_END 645
+#define CCM_FUNC7_START 645
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x79},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x7a},
{OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x77},
@@ -729,8 +794,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x7c},
{OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x7b},
{OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x77},
-#define CCM_FUNC7_END 603
-#define UCM_COMMON_START 603
+#define CCM_FUNC7_END 652
+#define UCM_COMMON_START 652
{OP_WR, UCM_REG_XX_OVFL_EVNT_ID, 0x32},
{OP_WR, UCM_REG_UQM_UCM_HDR_P, 0x2150020},
{OP_WR, UCM_REG_UQM_UCM_HDR_S, 0x2150020},
@@ -739,10 +804,16 @@ static const struct raw_op init_ops[] = {
{OP_WR, UCM_REG_ERR_EVNT_ID, 0x33},
{OP_WR, UCM_REG_EXPR_EVNT_ID, 0x30},
{OP_WR, UCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, UCM_REG_TSEM_WEIGHT, 0x3},
+ {OP_WR, UCM_REG_STORM_WEIGHT, 0x2},
+ {OP_WR, UCM_REG_TSEM_WEIGHT, 0x4},
{OP_WR, UCM_REG_CSEM_WEIGHT, 0x0},
+ {OP_WR, UCM_REG_XSEM_WEIGHT, 0x2},
+ {OP_WR, UCM_REG_DORQ_WEIGHT, 0x2},
{OP_WR, UCM_REG_CP_WEIGHT, 0x0},
- {OP_WR, UCM_REG_UQM_P_WEIGHT, 0x6},
+ {OP_WR, UCM_REG_USDM_WEIGHT, 0x2},
+ {OP_WR, UCM_REG_UQM_P_WEIGHT, 0x7},
+ {OP_WR, UCM_REG_UQM_S_WEIGHT, 0x2},
+ {OP_WR, UCM_REG_TM_WEIGHT, 0x2},
{OP_WR, UCM_REG_UCM_UQM_USE_Q, 0x1},
{OP_WR, UCM_REG_INV_CFLG_Q, 0x1},
{OP_WR, UCM_REG_GR_ARB_TYPE, 0x1},
@@ -756,14 +827,14 @@ static const struct raw_op init_ops[] = {
{OP_WR, UCM_REG_XX_INIT_CRD, 0xe},
{OP_WR, UCM_REG_XX_MSG_NUM, 0x1b},
{OP_ZR, UCM_REG_XX_TABLE, 0x12},
- {OP_SW_E1, UCM_REG_XX_DESCR_TABLE, 0x1b025c},
- {OP_SW_E1H, UCM_REG_XX_DESCR_TABLE, 0x1b0278},
+ {OP_SW_E1, UCM_REG_XX_DESCR_TABLE, 0x1b0266},
+ {OP_SW_E1H, UCM_REG_XX_DESCR_TABLE, 0x1b02a0},
{OP_WR, UCM_REG_N_SM_CTX_LD_0, 0x10},
{OP_WR, UCM_REG_N_SM_CTX_LD_1, 0x7},
{OP_WR, UCM_REG_N_SM_CTX_LD_2, 0xf},
{OP_WR, UCM_REG_N_SM_CTX_LD_3, 0x10},
{OP_ZR_E1, UCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR_E1H, UCM_REG_N_SM_CTX_LD_4, 0xd},
+ {OP_WR_E1H, UCM_REG_N_SM_CTX_LD_4, 0xb},
{OP_ZR_E1H, UCM_REG_N_SM_CTX_LD_5, 0x3},
{OP_WR, UCM_REG_UCM_REG0_SZ, 0x3},
{OP_WR_E1, UCM_REG_PHYS_QNUM0_0, 0xf},
@@ -787,56 +858,56 @@ static const struct raw_op init_ops[] = {
{OP_WR, UCM_REG_CDU_SM_WR_IFEN, 0x1},
{OP_WR, UCM_REG_CDU_SM_RD_IFEN, 0x1},
{OP_WR, UCM_REG_UCM_CFC_IFEN, 0x1},
-#define UCM_COMMON_END 659
-#define UCM_FUNC0_START 659
+#define UCM_COMMON_END 714
+#define UCM_FUNC0_START 714
{OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0xf},
{OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0xe},
{OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
{OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC0_END 663
-#define UCM_FUNC1_START 663
+#define UCM_FUNC0_END 718
+#define UCM_FUNC1_START 718
{OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x2f},
{OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x2e},
{OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
{OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC1_END 667
-#define UCM_FUNC2_START 667
+#define UCM_FUNC1_END 722
+#define UCM_FUNC2_START 722
{OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x1f},
{OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x1e},
{OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
{OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC2_END 671
-#define UCM_FUNC3_START 671
+#define UCM_FUNC2_END 726
+#define UCM_FUNC3_START 726
{OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x3f},
{OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x3e},
{OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
{OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC3_END 675
-#define UCM_FUNC4_START 675
+#define UCM_FUNC3_END 730
+#define UCM_FUNC4_START 730
{OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x4f},
{OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x4e},
{OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
{OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC4_END 679
-#define UCM_FUNC5_START 679
+#define UCM_FUNC4_END 734
+#define UCM_FUNC5_START 734
{OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x6f},
{OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x6e},
{OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
{OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC5_END 683
-#define UCM_FUNC6_START 683
+#define UCM_FUNC5_END 738
+#define UCM_FUNC6_START 738
{OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x5f},
{OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x5e},
{OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
{OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC6_END 687
-#define UCM_FUNC7_START 687
+#define UCM_FUNC6_END 742
+#define UCM_FUNC7_START 742
{OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x7f},
{OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x7e},
{OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
{OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC7_END 691
-#define USEM_COMMON_START 691
+#define UCM_FUNC7_END 746
+#define USEM_COMMON_START 746
{OP_RD, USEM_REG_MSG_NUM_FIC0, 0x0},
{OP_RD, USEM_REG_MSG_NUM_FIC1, 0x0},
{OP_RD, USEM_REG_MSG_NUM_FOC0, 0x0},
@@ -887,69 +958,72 @@ static const struct raw_op init_ops[] = {
{OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
{OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4},
{OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5000, 0x102},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5000, 0xc2},
{OP_WR_EMUL_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x0},
{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1020, 0xc8},
{OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x1},
{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1000, 0x2},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2000, 0x102},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57e8, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8020, 0xc8},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57d0, 0x5},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8000, 0x2},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x57d0 + 0x14, 0x10277},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3760, 0x4},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1e20, 0x42},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3738, 0x9},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b68, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x3738 + 0x24, 0x10293},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x4b68 + 0x8, 0x20278},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3180, 0x42},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b10, 0x2},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4640, 0x40},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8980, 0xc8},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57f0, 0x4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8960, 0x2},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57d8, 0x5},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3228, 0x4},
+ {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x57d8 + 0x14, 0x10281},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3200, 0x9},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1c60, 0x20},
+ {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x3200 + 0x24, 0x102bb},
+ {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2830, 0x20282},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3180, 0x20},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x400},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2830, 0x2027a},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0x8, 0x20294},
+ {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0x8, 0x102bc},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0xc, 0x3},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b68, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x6b68 + 0x8, 0x20296},
+ {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x6b68 + 0x8, 0x202bd},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b10, 0x2},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x74c0, 0x20298},
+ {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x74c0, 0x202bf},
{OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c00, 0x10027c},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c00, 0x10029a},
+ {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c00, 0x100284},
+ {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c00, 0x1002c1},
{OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c40, 0x10028c},
- {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c40, 0x1002aa},
- {OP_ZP_E1, USEM_REG_INT_TABLE, 0xc20000},
- {OP_ZP_E1H, USEM_REG_INT_TABLE, 0xc40000},
- {OP_WR_64_E1, USEM_REG_INT_TABLE + 0x368, 0x13029c},
- {OP_WR_64_E1H, USEM_REG_INT_TABLE + 0x368, 0x1302ba},
- {OP_ZP_E1, USEM_REG_PRAM, 0x311c0000},
- {OP_ZP_E1H, USEM_REG_PRAM, 0x31070000},
- {OP_ZP_E1, USEM_REG_PRAM + 0x8000, 0x33450c47},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x8000, 0x330e0c42},
- {OP_ZP_E1, USEM_REG_PRAM + 0x10000, 0x38561919},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x10000, 0x389b1906},
- {OP_WR_64_E1, USEM_REG_PRAM + 0x17fe0, 0x5004029e},
- {OP_ZP_E1H, USEM_REG_PRAM + 0x18000, 0x132272d},
- {OP_WR_64_E1H, USEM_REG_PRAM + 0x18250, 0x4fb602bc},
-#define USEM_COMMON_END 787
-#define USEM_PORT0_START 787
+ {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c40, 0x100294},
+ {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c40, 0x1002d1},
+ {OP_ZP_E1, USEM_REG_INT_TABLE, 0xc30000},
+ {OP_ZP_E1H, USEM_REG_INT_TABLE, 0xd20000},
+ {OP_WR_64_E1, USEM_REG_INT_TABLE + 0x368, 0x1302a4},
+ {OP_WR_64_E1H, USEM_REG_INT_TABLE + 0x3a8, 0xb02e1},
+ {OP_ZP_E1, USEM_REG_PRAM, 0x314c0000},
+ {OP_ZP_E1H, USEM_REG_PRAM, 0x31b60000},
+ {OP_ZP_E1, USEM_REG_PRAM + 0x8000, 0x35ef0c53},
+ {OP_ZP_E1H, USEM_REG_PRAM + 0x8000, 0x36500c6e},
+ {OP_ZP_E1, USEM_REG_PRAM + 0x10000, 0x361319cf},
+ {OP_ZP_E1H, USEM_REG_PRAM + 0x10000, 0x37591a02},
+ {OP_ZP_E1, USEM_REG_PRAM + 0x18000, 0x7112754},
+ {OP_ZP_E1H, USEM_REG_PRAM + 0x18000, 0x286127d9},
+ {OP_WR_64_E1, USEM_REG_PRAM + 0x18ee0, 0x4e2402a6},
+ {OP_WR_64_E1H, USEM_REG_PRAM + 0x1ff40, 0x401802e3},
+#define USEM_COMMON_END 842
+#define USEM_PORT0_START 842
{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1400, 0xa0},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9000, 0xa0},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1900, 0xa},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9500, 0x28},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1950, 0x2e},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9640, 0x34},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d00, 0x4},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1900, 0x10},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9500, 0x40},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1980, 0x30},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9700, 0x3c},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4740, 0xb4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2450, 0xb4},
+ {OP_WR_E1, USEM_REG_FAST_MEMORY + 0x1d90, 0x0},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2ad0, 0x2},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b40, 0x4},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3080, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d20, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3288, 0x96},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5440, 0x72},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b60, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8000, 0x12c},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5318, 0x98},
+ {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x3238, 0x0},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4b78, 0x52},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5100, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e08, 0xc},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5200, 0x20},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5300, 0x20},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5400, 0x20},
@@ -966,23 +1040,26 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f00, 0x20},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b78, 0x52},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e08, 0xc},
-#define USEM_PORT0_END 818
-#define USEM_PORT1_START 818
+#define USEM_PORT0_END 876
+#define USEM_PORT1_START 876
{OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1680, 0xa0},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9280, 0xa0},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1928, 0xa},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x95a0, 0x28},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1a08, 0x2e},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9710, 0x34},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1d10, 0x4},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1940, 0x10},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9600, 0x40},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1a40, 0x30},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x97f0, 0x3c},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4a10, 0xb4},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2720, 0xb4},
+ {OP_WR_E1, USEM_REG_FAST_MEMORY + 0x1d94, 0x0},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2ad8, 0x2},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b50, 0x4},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3100, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1da0, 0x20},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x34e0, 0x96},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5608, 0x72},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1be0, 0x20},
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x84b0, 0x12c},
+ {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5578, 0x98},
+ {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x323c, 0x0},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5080, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4cc0, 0x52},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5180, 0x20},
- {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4e38, 0xc},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5280, 0x20},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5380, 0x20},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5480, 0x20},
@@ -999,40 +1076,48 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f80, 0x20},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6cc0, 0x52},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e38, 0xc},
-#define USEM_PORT1_END 849
-#define USEM_FUNC0_START 849
+#define USEM_PORT1_END 910
+#define USEM_FUNC0_START 910
+ {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a30, 0x0},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3000, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4010, 0x2},
-#define USEM_FUNC0_END 851
-#define USEM_FUNC1_START 851
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4018, 0x2},
+#define USEM_FUNC0_END 913
+#define USEM_FUNC1_START 913
+ {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a34, 0x0},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3010, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4020, 0x2},
-#define USEM_FUNC1_END 853
-#define USEM_FUNC2_START 853
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4028, 0x2},
+#define USEM_FUNC1_END 916
+#define USEM_FUNC2_START 916
+ {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a38, 0x0},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3020, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4030, 0x2},
-#define USEM_FUNC2_END 855
-#define USEM_FUNC3_START 855
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4038, 0x2},
+#define USEM_FUNC2_END 919
+#define USEM_FUNC3_START 919
+ {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a3c, 0x0},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3030, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4040, 0x2},
-#define USEM_FUNC3_END 857
-#define USEM_FUNC4_START 857
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4048, 0x2},
+#define USEM_FUNC3_END 922
+#define USEM_FUNC4_START 922
+ {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a40, 0x0},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3040, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4050, 0x2},
-#define USEM_FUNC4_END 859
-#define USEM_FUNC5_START 859
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4058, 0x2},
+#define USEM_FUNC4_END 925
+#define USEM_FUNC5_START 925
+ {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a44, 0x0},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3050, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4060, 0x2},
-#define USEM_FUNC5_END 861
-#define USEM_FUNC6_START 861
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4068, 0x2},
+#define USEM_FUNC5_END 928
+#define USEM_FUNC6_START 928
+ {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a48, 0x0},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3060, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4070, 0x2},
-#define USEM_FUNC6_END 863
-#define USEM_FUNC7_START 863
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4078, 0x2},
+#define USEM_FUNC6_END 931
+#define USEM_FUNC7_START 931
+ {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a4c, 0x0},
{OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3070, 0x4},
- {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4080, 0x2},
-#define USEM_FUNC7_END 865
-#define CSEM_COMMON_START 865
+ {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4088, 0x2},
+#define USEM_FUNC7_END 934
+#define CSEM_COMMON_START 934
{OP_RD, CSEM_REG_MSG_NUM_FIC0, 0x0},
{OP_RD, CSEM_REG_MSG_NUM_FIC1, 0x0},
{OP_RD, CSEM_REG_MSG_NUM_FOC0, 0x0},
@@ -1091,29 +1176,30 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11e8, 0x0},
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x25c0, 0x240},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3000, 0xc0},
- {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x2ec8, 0x802a0},
+ {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x2ec8, 0x802a8},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4070, 0x80},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x5280, 0x4},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6280, 0x240},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x6b88, 0x2002be},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6700, 0x100},
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x9000, 0x400},
+ {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x6b08, 0x2002e5},
{OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x13fffff},
- {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002a8},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002de},
+ {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002b0},
+ {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c00, 0x100305},
{OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002b8},
- {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002ee},
- {OP_ZP_E1, CSEM_REG_INT_TABLE, 0x6e0000},
- {OP_ZP_E1H, CSEM_REG_INT_TABLE, 0x6f0000},
- {OP_WR_64_E1, CSEM_REG_INT_TABLE + 0x380, 0x1002c8},
- {OP_WR_64_E1H, CSEM_REG_INT_TABLE + 0x380, 0x1002fe},
- {OP_ZP_E1, CSEM_REG_PRAM, 0x32580000},
- {OP_ZP_E1H, CSEM_REG_PRAM, 0x31fa0000},
- {OP_ZP_E1, CSEM_REG_PRAM + 0x8000, 0x18270c96},
- {OP_ZP_E1H, CSEM_REG_PRAM + 0x8000, 0x19040c7f},
- {OP_WR_64_E1, CSEM_REG_PRAM + 0xb210, 0x682402ca},
- {OP_WR_64_E1H, CSEM_REG_PRAM + 0xb430, 0x67e00300},
-#define CSEM_COMMON_END 944
-#define CSEM_PORT0_START 944
+ {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002c0},
+ {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c40, 0x100315},
+ {OP_ZP_E1, CSEM_REG_INT_TABLE, 0x710000},
+ {OP_ZP_E1H, CSEM_REG_INT_TABLE, 0x740000},
+ {OP_WR_64_E1, CSEM_REG_INT_TABLE + 0x380, 0x1002d0},
+ {OP_WR_64_E1H, CSEM_REG_INT_TABLE + 0x380, 0x100325},
+ {OP_ZP_E1, CSEM_REG_PRAM, 0x32290000},
+ {OP_ZP_E1H, CSEM_REG_PRAM, 0x32260000},
+ {OP_ZP_E1, CSEM_REG_PRAM + 0x8000, 0x23630c8b},
+ {OP_ZP_E1H, CSEM_REG_PRAM + 0x8000, 0x246e0c8a},
+ {OP_WR_64_E1, CSEM_REG_PRAM + 0xc930, 0x654002d2},
+ {OP_WR_64_E1H, CSEM_REG_PRAM + 0xcbb0, 0x64f00327},
+#define CSEM_COMMON_END 1014
+#define CSEM_PORT0_START 1014
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1400, 0xa0},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8000, 0xa0},
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1900, 0x10},
@@ -1123,11 +1209,10 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x5118, 0x0},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4040, 0x6},
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2300, 0xe},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6040, 0x30},
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3040, 0x6},
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2410, 0x30},
-#define CSEM_PORT0_END 956
-#define CSEM_PORT1_START 956
+#define CSEM_PORT0_END 1025
+#define CSEM_PORT1_START 1025
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1680, 0xa0},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8280, 0xa0},
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1940, 0x10},
@@ -1137,46 +1222,53 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x511c, 0x0},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4058, 0x6},
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2338, 0xe},
- {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6100, 0x30},
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3058, 0x6},
{OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30},
-#define CSEM_PORT1_END 968
-#define CSEM_FUNC0_START 968
+#define CSEM_PORT1_END 1036
+#define CSEM_FUNC0_START 1036
{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1148, 0x0},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3300, 0x2},
-#define CSEM_FUNC0_END 970
-#define CSEM_FUNC1_START 970
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6040, 0x30},
+#define CSEM_FUNC0_END 1039
+#define CSEM_FUNC1_START 1039
{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x114c, 0x0},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3308, 0x2},
-#define CSEM_FUNC1_END 972
-#define CSEM_FUNC2_START 972
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6100, 0x30},
+#define CSEM_FUNC1_END 1042
+#define CSEM_FUNC2_START 1042
{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1150, 0x0},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3310, 0x2},
-#define CSEM_FUNC2_END 974
-#define CSEM_FUNC3_START 974
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x61c0, 0x30},
+#define CSEM_FUNC2_END 1045
+#define CSEM_FUNC3_START 1045
{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1154, 0x0},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3318, 0x2},
-#define CSEM_FUNC3_END 976
-#define CSEM_FUNC4_START 976
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6280, 0x30},
+#define CSEM_FUNC3_END 1048
+#define CSEM_FUNC4_START 1048
{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1158, 0x0},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3320, 0x2},
-#define CSEM_FUNC4_END 978
-#define CSEM_FUNC5_START 978
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6340, 0x30},
+#define CSEM_FUNC4_END 1051
+#define CSEM_FUNC5_START 1051
{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x115c, 0x0},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3328, 0x2},
-#define CSEM_FUNC5_END 980
-#define CSEM_FUNC6_START 980
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6400, 0x30},
+#define CSEM_FUNC5_END 1054
+#define CSEM_FUNC6_START 1054
{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1160, 0x0},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3330, 0x2},
-#define CSEM_FUNC6_END 982
-#define CSEM_FUNC7_START 982
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x64c0, 0x30},
+#define CSEM_FUNC6_END 1057
+#define CSEM_FUNC7_START 1057
{OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1164, 0x0},
{OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3338, 0x2},
-#define CSEM_FUNC7_END 984
-#define XPB_COMMON_START 984
+ {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6580, 0x30},
+#define CSEM_FUNC7_END 1060
+#define XPB_COMMON_START 1060
{OP_WR, GRCBASE_XPB + PB_REG_CONTROL, 0x20},
-#define XPB_COMMON_END 985
-#define DQ_COMMON_START 985
+#define XPB_COMMON_END 1061
+#define DQ_COMMON_START 1061
{OP_WR, DORQ_REG_MODE_ACT, 0x2},
{OP_WR, DORQ_REG_NORM_CID_OFST, 0x3},
{OP_WR, DORQ_REG_OUTST_REQ, 0x4},
@@ -1195,8 +1287,8 @@ static const struct raw_op init_ops[] = {
{OP_WR, DORQ_REG_DQ_FIFO_AFULL_TH, 0x76c},
{OP_WR, DORQ_REG_REGN, 0x7c1004},
{OP_WR, DORQ_REG_IF_EN, 0xf},
-#define DQ_COMMON_END 1003
-#define TIMERS_COMMON_START 1003
+#define DQ_COMMON_END 1079
+#define TIMERS_COMMON_START 1079
{OP_ZR, TM_REG_CLIN_PRIOR0_CLIENT, 0x2},
{OP_WR, TM_REG_LIN_SETCLR_FIFO_ALFULL_THR, 0x1c},
{OP_WR, TM_REG_CFC_AC_CRDCNT_VAL, 0x1},
@@ -1219,14 +1311,18 @@ static const struct raw_op init_ops[] = {
{OP_WR, TM_REG_EN_CL0_INPUT, 0x1},
{OP_WR, TM_REG_EN_CL1_INPUT, 0x1},
{OP_WR, TM_REG_EN_CL2_INPUT, 0x1},
-#define TIMERS_COMMON_END 1025
-#define TIMERS_PORT0_START 1025
+#define TIMERS_COMMON_END 1101
+#define TIMERS_PORT0_START 1101
+ {OP_WR, TM_REG_LIN0_LOGIC_ADDR, 0x0},
+ {OP_WR, TM_REG_LIN0_PHY_ADDR_VALID, 0x0},
{OP_ZR, TM_REG_LIN0_PHY_ADDR, 0x2},
-#define TIMERS_PORT0_END 1026
-#define TIMERS_PORT1_START 1026
+#define TIMERS_PORT0_END 1104
+#define TIMERS_PORT1_START 1104
+ {OP_WR, TM_REG_LIN1_LOGIC_ADDR, 0x0},
+ {OP_WR, TM_REG_LIN1_PHY_ADDR_VALID, 0x0},
{OP_ZR, TM_REG_LIN1_PHY_ADDR, 0x2},
-#define TIMERS_PORT1_END 1027
-#define XSDM_COMMON_START 1027
+#define TIMERS_PORT1_END 1107
+#define XSDM_COMMON_START 1107
{OP_WR_E1, XSDM_REG_CFC_RSP_START_ADDR, 0x614},
{OP_WR_E1H, XSDM_REG_CFC_RSP_START_ADDR, 0x424},
{OP_WR_E1, XSDM_REG_CMP_COUNTER_START_ADDR, 0x600},
@@ -1249,7 +1345,9 @@ static const struct raw_op init_ops[] = {
{OP_WR, XSDM_REG_AGG_INT_EVENT_9, 0x29},
{OP_WR, XSDM_REG_AGG_INT_EVENT_10, 0x2a},
{OP_WR, XSDM_REG_AGG_INT_EVENT_11, 0x2b},
- {OP_ZR, XSDM_REG_AGG_INT_EVENT_12, 0x54},
+ {OP_WR, XSDM_REG_AGG_INT_EVENT_12, 0x2c},
+ {OP_WR, XSDM_REG_AGG_INT_EVENT_13, 0x2d},
+ {OP_ZR, XSDM_REG_AGG_INT_EVENT_14, 0x52},
{OP_WR, XSDM_REG_AGG_INT_MODE_0, 0x1},
{OP_ZR, XSDM_REG_AGG_INT_MODE_1, 0x1f},
{OP_WR, XSDM_REG_ENABLE_IN1, 0x7ffffff},
@@ -1274,8 +1372,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_ASIC, XSDM_REG_TIMER_TICK, 0x3e8},
{OP_WR_EMUL, XSDM_REG_TIMER_TICK, 0x1},
{OP_WR_FPGA, XSDM_REG_TIMER_TICK, 0xa},
-#define XSDM_COMMON_END 1074
-#define QM_COMMON_START 1074
+#define XSDM_COMMON_END 1156
+#define QM_COMMON_START 1156
{OP_WR, QM_REG_ACTCTRINITVAL_0, 0x6},
{OP_WR, QM_REG_ACTCTRINITVAL_1, 0x5},
{OP_WR, QM_REG_ACTCTRINITVAL_2, 0xa},
@@ -1576,8 +1674,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, QM_REG_PQ2PCIFUNC_6, 0x5},
{OP_WR_E1H, QM_REG_PQ2PCIFUNC_7, 0x7},
{OP_WR, QM_REG_CMINTEN, 0xff},
-#define QM_COMMON_END 1374
-#define PBF_COMMON_START 1374
+#define QM_COMMON_END 1456
+#define PBF_COMMON_START 1456
{OP_WR, PBF_REG_INIT, 0x1},
{OP_WR, PBF_REG_INIT_P4, 0x1},
{OP_WR, PBF_REG_MAC_LB_ENABLE, 0x1},
@@ -1585,20 +1683,20 @@ static const struct raw_op init_ops[] = {
{OP_WR, PBF_REG_INIT_P4, 0x0},
{OP_WR, PBF_REG_INIT, 0x0},
{OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P4, 0x0},
-#define PBF_COMMON_END 1381
-#define PBF_PORT0_START 1381
+#define PBF_COMMON_END 1463
+#define PBF_PORT0_START 1463
{OP_WR, PBF_REG_INIT_P0, 0x1},
{OP_WR, PBF_REG_MAC_IF0_ENABLE, 0x1},
{OP_WR, PBF_REG_INIT_P0, 0x0},
{OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P0, 0x0},
-#define PBF_PORT0_END 1385
-#define PBF_PORT1_START 1385
+#define PBF_PORT0_END 1467
+#define PBF_PORT1_START 1467
{OP_WR, PBF_REG_INIT_P1, 0x1},
{OP_WR, PBF_REG_MAC_IF1_ENABLE, 0x1},
{OP_WR, PBF_REG_INIT_P1, 0x0},
{OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P1, 0x0},
-#define PBF_PORT1_END 1389
-#define XCM_COMMON_START 1389
+#define PBF_PORT1_END 1471
+#define XCM_COMMON_START 1471
{OP_WR, XCM_REG_XX_OVFL_EVNT_ID, 0x32},
{OP_WR, XCM_REG_XQM_XCM_HDR_P, 0x3150020},
{OP_WR, XCM_REG_XQM_XCM_HDR_S, 0x3150020},
@@ -1607,15 +1705,18 @@ static const struct raw_op init_ops[] = {
{OP_WR, XCM_REG_ERR_EVNT_ID, 0x33},
{OP_WR, XCM_REG_EXPR_EVNT_ID, 0x30},
{OP_WR, XCM_REG_STOP_EVNT_ID, 0x31},
- {OP_WR, XCM_REG_STORM_WEIGHT, 0x2},
- {OP_WR, XCM_REG_TSEM_WEIGHT, 0x5},
- {OP_WR, XCM_REG_CSEM_WEIGHT, 0x2},
- {OP_WR, XCM_REG_USEM_WEIGHT, 0x2},
- {OP_WR, XCM_REG_PBF_WEIGHT, 0x7},
- {OP_WR, XCM_REG_NIG1_WEIGHT, 0x1},
+ {OP_WR, XCM_REG_STORM_WEIGHT, 0x3},
+ {OP_WR, XCM_REG_TSEM_WEIGHT, 0x6},
+ {OP_WR, XCM_REG_CSEM_WEIGHT, 0x3},
+ {OP_WR, XCM_REG_USEM_WEIGHT, 0x3},
+ {OP_WR, XCM_REG_DORQ_WEIGHT, 0x2},
+ {OP_WR, XCM_REG_PBF_WEIGHT, 0x0},
+ {OP_WR, XCM_REG_NIG0_WEIGHT, 0x2},
{OP_WR, XCM_REG_CP_WEIGHT, 0x0},
- {OP_WR, XCM_REG_XSDM_WEIGHT, 0x5},
- {OP_WR, XCM_REG_XQM_P_WEIGHT, 0x3},
+ {OP_WR, XCM_REG_XSDM_WEIGHT, 0x6},
+ {OP_WR, XCM_REG_XQM_P_WEIGHT, 0x4},
+ {OP_WR, XCM_REG_XQM_S_WEIGHT, 0x2},
+ {OP_WR, XCM_REG_TM_WEIGHT, 0x2},
{OP_WR, XCM_REG_XCM_XQM_USE_Q, 0x1},
{OP_WR, XCM_REG_XQM_BYP_ACT_UPD, 0x6},
{OP_WR, XCM_REG_UNA_GT_NXT_Q, 0x0},
@@ -1633,14 +1734,14 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1, XCM_REG_XX_MSG_NUM, 0x1f},
{OP_WR_E1H, XCM_REG_XX_MSG_NUM, 0x20},
{OP_ZR, XCM_REG_XX_TABLE, 0x12},
- {OP_SW_E1, XCM_REG_XX_DESCR_TABLE, 0x1f02cc},
- {OP_SW_E1H, XCM_REG_XX_DESCR_TABLE, 0x1f0302},
+ {OP_SW_E1, XCM_REG_XX_DESCR_TABLE, 0x1f02d4},
+ {OP_SW_E1H, XCM_REG_XX_DESCR_TABLE, 0x1f0329},
{OP_WR, XCM_REG_N_SM_CTX_LD_0, 0xf},
{OP_WR, XCM_REG_N_SM_CTX_LD_1, 0x7},
{OP_WR, XCM_REG_N_SM_CTX_LD_2, 0xb},
{OP_WR, XCM_REG_N_SM_CTX_LD_3, 0xe},
{OP_ZR_E1, XCM_REG_N_SM_CTX_LD_4, 0x4},
- {OP_WR_E1H, XCM_REG_N_SM_CTX_LD_4, 0xc},
+ {OP_WR_E1H, XCM_REG_N_SM_CTX_LD_4, 0xe},
{OP_ZR_E1H, XCM_REG_N_SM_CTX_LD_5, 0x3},
{OP_WR, XCM_REG_XCM_REG0_SZ, 0x4},
{OP_WR, XCM_REG_XCM_STORM0_IFEN, 0x1},
@@ -1663,8 +1764,8 @@ static const struct raw_op init_ops[] = {
{OP_WR, XCM_REG_CDU_SM_WR_IFEN, 0x1},
{OP_WR, XCM_REG_CDU_SM_RD_IFEN, 0x1},
{OP_WR, XCM_REG_XCM_CFC_IFEN, 0x1},
-#define XCM_COMMON_END 1453
-#define XCM_PORT0_START 1453
+#define XCM_COMMON_END 1538
+#define XCM_PORT0_START 1538
{OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
{OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
{OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1673,8 +1774,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1, XCM_REG_WU_DA_CNT_CMD10, 0x2},
{OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
{OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
-#define XCM_PORT0_END 1461
-#define XCM_PORT1_START 1461
+#define XCM_PORT0_END 1546
+#define XCM_PORT1_START 1546
{OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
{OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
{OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1683,8 +1784,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1, XCM_REG_WU_DA_CNT_CMD11, 0x2},
{OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
{OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
-#define XCM_PORT1_END 1469
-#define XCM_FUNC0_START 1469
+#define XCM_PORT1_END 1554
+#define XCM_FUNC0_START 1554
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1694,8 +1795,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
{OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC0_END 1478
-#define XCM_FUNC1_START 1478
+#define XCM_FUNC0_END 1563
+#define XCM_FUNC1_START 1563
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1705,8 +1806,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
{OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC1_END 1487
-#define XCM_FUNC2_START 1487
+#define XCM_FUNC1_END 1572
+#define XCM_FUNC2_START 1572
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1716,8 +1817,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
{OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC2_END 1496
-#define XCM_FUNC3_START 1496
+#define XCM_FUNC2_END 1581
+#define XCM_FUNC3_START 1581
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1727,8 +1828,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
{OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC3_END 1505
-#define XCM_FUNC4_START 1505
+#define XCM_FUNC3_END 1590
+#define XCM_FUNC4_START 1590
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1738,8 +1839,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
{OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC4_END 1514
-#define XCM_FUNC5_START 1514
+#define XCM_FUNC4_END 1599
+#define XCM_FUNC5_START 1599
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1749,8 +1850,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
{OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC5_END 1523
-#define XCM_FUNC6_START 1523
+#define XCM_FUNC5_END 1608
+#define XCM_FUNC6_START 1608
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
@@ -1760,8 +1861,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
{OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC6_END 1532
-#define XCM_FUNC7_START 1532
+#define XCM_FUNC6_END 1617
+#define XCM_FUNC7_START 1617
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
{OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
{OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
@@ -1771,8 +1872,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
{OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
{OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC7_END 1541
-#define XSEM_COMMON_START 1541
+#define XCM_FUNC7_END 1626
+#define XSEM_COMMON_START 1626
{OP_RD, XSEM_REG_MSG_NUM_FIC0, 0x0},
{OP_RD, XSEM_REG_MSG_NUM_FIC1, 0x0},
{OP_RD, XSEM_REG_MSG_NUM_FOC0, 0x0},
@@ -1827,10 +1928,12 @@ static const struct raw_op init_ops[] = {
{OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
{OP_WR_EMUL_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x0},
{OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3d00, 0x4},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3d60, 0x4},
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x1},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d60 + 0x10, 0x202f3},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x29c8, 0x4},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3000, 0x48},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x28a8, 0x4},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29c8 + 0x10, 0x20348},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2080, 0x48},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1000, 0x2},
@@ -1839,68 +1942,73 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9000, 0x2},
{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3368, 0x0},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x21a8, 0x86},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3370, 0x202eb},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3370, 0x202f5},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2000, 0x20},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3b90, 0x402ed},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3b90, 0x402f7},
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x23c8, 0x0},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3e20, 0x202fb},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x23d0, 0x2034a},
{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1518, 0x1},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x23d0, 0x20321},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x4034c},
{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1830, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x40323},
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2c20, 0x0},
{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1838, 0x0},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2ac8, 0x0},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1820, 0x202f1},
- {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2ab8, 0x0},
+ {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2c10, 0x0},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1820, 0x202fd},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2c08, 0x20350},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4ac0, 0x2},
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3010, 0x1},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b00, 0x4},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x4040, 0x10},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1f50, 0x202f3},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x4000, 0x100327},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1f48, 0x202ff},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x4000, 0x100352},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6ac0, 0x2},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b00, 0x4},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x83b0, 0x20337},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x8408, 0x20362},
{OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x0},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c00, 0x1002f5},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100339},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100301},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100364},
{OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80305},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80349},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80311},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80374},
{OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x2000000},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c60, 0x8030d},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c60, 0x80351},
- {OP_ZP_E1, XSEM_REG_INT_TABLE, 0xa90000},
- {OP_ZP_E1H, XSEM_REG_INT_TABLE, 0xac0000},
- {OP_WR_64_E1, XSEM_REG_INT_TABLE + 0x368, 0x130315},
- {OP_WR_64_E1H, XSEM_REG_INT_TABLE + 0x368, 0x130359},
- {OP_ZP_E1, XSEM_REG_PRAM, 0x344e0000},
- {OP_ZP_E1H, XSEM_REG_PRAM, 0x34620000},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x8000, 0x38840d14},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x8000, 0x38240d19},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x10000, 0x3e711b35},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x10000, 0x3e971b22},
- {OP_ZP_E1, XSEM_REG_PRAM + 0x18000, 0x1dd02ad2},
- {OP_ZP_E1H, XSEM_REG_PRAM + 0x18000, 0x21542ac8},
- {OP_WR_64_E1, XSEM_REG_PRAM + 0x1c0d0, 0x47e60317},
- {OP_WR_64_E1H, XSEM_REG_PRAM + 0x1c8d0, 0x46e6035b},
-#define XSEM_COMMON_END 1651
-#define XSEM_PORT0_START 1651
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3ba0, 0x10},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c60, 0x80319},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c60, 0x8037c},
+ {OP_ZP_E1, XSEM_REG_INT_TABLE, 0xb50000},
+ {OP_ZP_E1H, XSEM_REG_INT_TABLE, 0xbd0000},
+ {OP_WR_64_E1, XSEM_REG_INT_TABLE + 0x368, 0x130321},
+ {OP_WR_64_E1H, XSEM_REG_INT_TABLE + 0x3a8, 0xb0384},
+ {OP_ZP_E1, XSEM_REG_PRAM, 0x33660000},
+ {OP_ZP_E1H, XSEM_REG_PRAM, 0x34060000},
+ {OP_ZP_E1, XSEM_REG_PRAM + 0x8000, 0x38b30cda},
+ {OP_ZP_E1H, XSEM_REG_PRAM + 0x8000, 0x37960d02},
+ {OP_ZP_E1, XSEM_REG_PRAM + 0x10000, 0x3bb11b07},
+ {OP_ZP_E1H, XSEM_REG_PRAM + 0x10000, 0x3bc31ae8},
+ {OP_ZP_E1, XSEM_REG_PRAM + 0x18000, 0x2a2629f4},
+ {OP_ZP_E1H, XSEM_REG_PRAM + 0x18000, 0x382629d9},
+ {OP_WR_64_E1, XSEM_REG_PRAM + 0x1d6c0, 0x45280323},
+ {OP_ZP_E1H, XSEM_REG_PRAM + 0x20000, 0x124537e3},
+ {OP_WR_64_E1H, XSEM_REG_PRAM + 0x22220, 0x3bbc0386},
+#define XSEM_COMMON_END 1741
+#define XSEM_PORT0_START 1741
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3ba0, 0x14},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc000, 0xfc},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c20, 0x1c},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24a8, 0x10},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c40, 0x24},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24a8, 0x14},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1400, 0xa},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2528, 0x1c},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2548, 0x24},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1450, 0x6},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2608, 0x1c},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2668, 0x24},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3378, 0xfc},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x26e8, 0x1c},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2788, 0x24},
{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b58, 0x0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x27c8, 0x1c},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d10, 0x100319},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x28a8, 0x24},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d78, 0x20325},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa000, 0x28},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1500, 0x0},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d88, 0x100327},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa140, 0xc},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1500, 0x0},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29e0, 0x20388},
{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1508, 0x1},
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3000, 0x1},
{OP_ZR, XSEM_REG_FAST_MEMORY + 0x5020, 0x2},
@@ -1910,31 +2018,33 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5040, 0x0},
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x5208, 0x1},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ac8, 0x2035d},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ac8, 0x2038a},
{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50b8, 0x1},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b10, 0x42},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x20329},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x20337},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d20, 0x4},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b10, 0x42},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d20, 0x4},
-#define XSEM_PORT0_END 1683
-#define XSEM_PORT1_START 1683
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3be0, 0x10},
+#define XSEM_PORT0_END 1775
+#define XSEM_PORT1_START 1775
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3bf0, 0x14},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc3f0, 0xfc},
- {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c90, 0x1c},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24e8, 0x10},
+ {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3cd0, 0x24},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24f8, 0x14},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1428, 0xa},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2598, 0x1c},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x25d8, 0x24},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1468, 0x6},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2678, 0x1c},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x26f8, 0x24},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3768, 0xfc},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2758, 0x1c},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2818, 0x24},
{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b5c, 0x0},
- {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2838, 0x1c},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d50, 0x10032b},
+ {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2938, 0x24},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d80, 0x20339},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa0a0, 0x28},
- {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1504, 0x0},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3dc8, 0x10033b},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa170, 0xc},
+ {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1504, 0x0},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29e8, 0x2038c},
{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x150c, 0x1},
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3004, 0x1},
{OP_ZR, XSEM_REG_FAST_MEMORY + 0x5028, 0x2},
@@ -1944,68 +2054,68 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5044, 0x0},
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x520c, 0x1},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ad0, 0x2035f},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ad0, 0x2038e},
{OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50bc, 0x1},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6c18, 0x42},
- {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x2033b},
+ {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x2034b},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d30, 0x4},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4c18, 0x42},
{OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d30, 0x4},
-#define XSEM_PORT1_END 1715
-#define XSEM_FUNC0_START 1715
+#define XSEM_PORT1_END 1809
+#define XSEM_FUNC0_START 1809
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e0, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x28b8, 0x100361},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29f0, 0x100390},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
-#define XSEM_FUNC0_END 1718
-#define XSEM_FUNC1_START 1718
+#define XSEM_FUNC0_END 1812
+#define XSEM_FUNC1_START 1812
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e4, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x28f8, 0x100371},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a30, 0x1003a0},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
-#define XSEM_FUNC1_END 1721
-#define XSEM_FUNC2_START 1721
+#define XSEM_FUNC1_END 1815
+#define XSEM_FUNC2_START 1815
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e8, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2938, 0x100381},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a70, 0x1003b0},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50b8, 0xe},
-#define XSEM_FUNC2_END 1724
-#define XSEM_FUNC3_START 1724
+#define XSEM_FUNC2_END 1818
+#define XSEM_FUNC3_START 1818
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7ec, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2978, 0x100391},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2ab0, 0x1003c0},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50f0, 0xe},
-#define XSEM_FUNC3_END 1727
-#define XSEM_FUNC4_START 1727
+#define XSEM_FUNC3_END 1821
+#define XSEM_FUNC4_START 1821
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f0, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29b8, 0x1003a1},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2af0, 0x1003d0},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5128, 0xe},
-#define XSEM_FUNC4_END 1730
-#define XSEM_FUNC5_START 1730
+#define XSEM_FUNC4_END 1824
+#define XSEM_FUNC5_START 1824
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f4, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29f8, 0x1003b1},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b30, 0x1003e0},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5160, 0xe},
-#define XSEM_FUNC5_END 1733
-#define XSEM_FUNC6_START 1733
+#define XSEM_FUNC5_END 1827
+#define XSEM_FUNC6_START 1827
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f8, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a38, 0x1003c1},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b70, 0x1003f0},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5198, 0xe},
-#define XSEM_FUNC6_END 1736
-#define XSEM_FUNC7_START 1736
+#define XSEM_FUNC6_END 1830
+#define XSEM_FUNC7_START 1830
{OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7fc, 0x0},
- {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a78, 0x1003d1},
+ {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2bb0, 0x100400},
{OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x51d0, 0xe},
-#define XSEM_FUNC7_END 1739
-#define CDU_COMMON_START 1739
+#define XSEM_FUNC7_END 1833
+#define CDU_COMMON_START 1833
{OP_WR, CDU_REG_CDU_CONTROL0, 0x1},
{OP_WR_E1H, CDU_REG_MF_MODE, 0x1},
{OP_WR, CDU_REG_CDU_CHK_MASK0, 0x3d000},
{OP_WR, CDU_REG_CDU_CHK_MASK1, 0x3d},
- {OP_WB_E1, CDU_REG_L1TT, 0x200033d},
- {OP_WB_E1H, CDU_REG_L1TT, 0x20003e1},
- {OP_WB_E1, CDU_REG_MATT, 0x20053d},
- {OP_WB_E1H, CDU_REG_MATT, 0x2805e1},
+ {OP_WB_E1, CDU_REG_L1TT, 0x200034d},
+ {OP_WB_E1H, CDU_REG_L1TT, 0x2000410},
+ {OP_WB_E1, CDU_REG_MATT, 0x20054d},
+ {OP_WB_E1H, CDU_REG_MATT, 0x280610},
{OP_ZR_E1, CDU_REG_MATT + 0x80, 0x2},
- {OP_WB_E1, CDU_REG_MATT + 0x88, 0x6055d},
+ {OP_WB_E1, CDU_REG_MATT + 0x88, 0x6056d},
{OP_ZR, CDU_REG_MATT + 0xa0, 0x18},
-#define CDU_COMMON_END 1750
-#define DMAE_COMMON_START 1750
+#define CDU_COMMON_END 1844
+#define DMAE_COMMON_START 1844
{OP_ZR, DMAE_REG_CMD_MEM, 0xe0},
{OP_WR, DMAE_REG_CRC16C_INIT, 0x0},
{OP_WR, DMAE_REG_CRC16T10_INIT, 0x1},
@@ -2013,24 +2123,27 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, DMAE_REG_PXP_REQ_INIT_CRD, 0x2},
{OP_WR, DMAE_REG_PCI_IFEN, 0x1},
{OP_WR, DMAE_REG_GRC_IFEN, 0x1},
-#define DMAE_COMMON_END 1757
-#define PXP_COMMON_START 1757
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x400, 0x50563},
- {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x400, 0x50609},
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x420, 0x50568},
- {OP_WB_E1H, PXP_REG_HST_INBOUND_INT, 0x5060e},
- {OP_WB_E1, PXP_REG_HST_INBOUND_INT, 0x5056d},
-#define PXP_COMMON_END 1762
-#define CFC_COMMON_START 1762
+#define DMAE_COMMON_END 1851
+#define PXP_COMMON_START 1851
+ {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x400, 0x50573},
+ {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x400, 0x50638},
+ {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x420, 0x50578},
+ {OP_WB_E1H, PXP_REG_HST_INBOUND_INT, 0x5063d},
+ {OP_WB_E1, PXP_REG_HST_INBOUND_INT, 0x5057d},
+ {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x20, 0x50642},
+#define PXP_COMMON_END 1857
+#define CFC_COMMON_START 1857
{OP_ZR_E1H, CFC_REG_LINK_LIST, 0x100},
{OP_WR, CFC_REG_CONTROL0, 0x10},
{OP_WR, CFC_REG_DISABLE_ON_ERROR, 0x3fff},
+ {OP_WR, CFC_REG_INTERFACES, 0x280000},
{OP_WR, CFC_REG_LCREQ_WEIGHTS, 0x84924a},
-#define CFC_COMMON_END 1766
-#define HC_COMMON_START 1766
+ {OP_WR, CFC_REG_INTERFACES, 0x0},
+#define CFC_COMMON_END 1863
+#define HC_COMMON_START 1863
{OP_ZR_E1, HC_REG_USTORM_ADDR_FOR_COALESCE, 0x4},
-#define HC_COMMON_END 1767
-#define HC_PORT0_START 1767
+#define HC_COMMON_END 1864
+#define HC_PORT0_START 1864
{OP_WR_E1, HC_REG_CONFIG_0, 0x1080},
{OP_ZR_E1, HC_REG_UC_RAM_ADDR_0, 0x2},
{OP_WR_E1, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2049,8 +2162,8 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
{OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
{OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_PORT0_END 1785
-#define HC_PORT1_START 1785
+#define HC_PORT0_END 1882
+#define HC_PORT1_START 1882
{OP_WR_E1, HC_REG_CONFIG_1, 0x1080},
{OP_ZR_E1, HC_REG_UC_RAM_ADDR_1, 0x2},
{OP_WR_E1, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2069,8 +2182,8 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
{OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
{OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_PORT1_END 1803
-#define HC_FUNC0_START 1803
+#define HC_PORT1_END 1900
+#define HC_FUNC0_START 1900
{OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
{OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x0},
{OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2086,8 +2199,8 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC0_END 1818
-#define HC_FUNC1_START 1818
+#define HC_FUNC0_END 1915
+#define HC_FUNC1_START 1915
{OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
{OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x1},
{OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2103,8 +2216,8 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC1_END 1833
-#define HC_FUNC2_START 1833
+#define HC_FUNC1_END 1930
+#define HC_FUNC2_START 1930
{OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
{OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x2},
{OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2120,8 +2233,8 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC2_END 1848
-#define HC_FUNC3_START 1848
+#define HC_FUNC2_END 1945
+#define HC_FUNC3_START 1945
{OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
{OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x3},
{OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2137,8 +2250,8 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC3_END 1863
-#define HC_FUNC4_START 1863
+#define HC_FUNC3_END 1960
+#define HC_FUNC4_START 1960
{OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
{OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x4},
{OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2154,8 +2267,8 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC4_END 1878
-#define HC_FUNC5_START 1878
+#define HC_FUNC4_END 1975
+#define HC_FUNC5_START 1975
{OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
{OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x5},
{OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2171,8 +2284,8 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC5_END 1893
-#define HC_FUNC6_START 1893
+#define HC_FUNC5_END 1990
+#define HC_FUNC6_START 1990
{OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
{OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x6},
{OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
@@ -2188,8 +2301,8 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC6_END 1908
-#define HC_FUNC7_START 1908
+#define HC_FUNC6_END 2005
+#define HC_FUNC7_START 2005
{OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
{OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x7},
{OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
@@ -2205,10 +2318,10 @@ static const struct raw_op init_ops[] = {
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
{OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC7_END 1923
-#define PXP2_COMMON_START 1923
- {OP_WR_E1, PXP2_REG_PGL_CONTROL0, 0xe38340},
+#define HC_FUNC7_END 2020
+#define PXP2_COMMON_START 2020
{OP_WR_E1H, PXP2_REG_RQ_DRAM_ALIGN, 0x1},
+ {OP_WR, PXP2_REG_PGL_CONTROL0, 0xe38340},
{OP_WR, PXP2_REG_PGL_CONTROL1, 0x3c10},
{OP_WR_E1H, PXP2_REG_RQ_ELT_DISABLE, 0x1},
{OP_WR_E1H, PXP2_REG_WR_REV_MODE, 0x0},
@@ -2220,7 +2333,7 @@ static const struct raw_op init_ops[] = {
{OP_WR, PXP2_REG_PGL_INT_TSDM_5, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_TSDM_6, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_TSDM_7, 0xffffffff},
- {OP_WR, PXP2_REG_PGL_INT_USDM_1, 0xffffffff},
+ {OP_WR_E1, PXP2_REG_PGL_INT_USDM_1, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_USDM_2, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_USDM_3, 0xffffffff},
{OP_WR, PXP2_REG_PGL_INT_USDM_4, 0xffffffff},
@@ -2247,6 +2360,7 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1, PXP2_REG_PGL_INT_XSDM_1, 0xffff3340},
{OP_WR_E1H, PXP2_REG_PGL_INT_USDM_0, 0xf0005000},
{OP_WR_E1, PXP2_REG_PGL_INT_USDM_0, 0xf0003000},
+ {OP_WR_E1H, PXP2_REG_PGL_INT_USDM_1, 0xf0008000},
{OP_WR, PXP2_REG_RD_MAX_BLKS_VQ6, 0x8},
{OP_WR, PXP2_REG_RD_MAX_BLKS_VQ9, 0x8},
{OP_WR, PXP2_REG_RD_MAX_BLKS_VQ10, 0x8},
@@ -2323,9 +2437,8 @@ static const struct raw_op init_ops[] = {
{OP_WR, PXP2_REG_PSWRQ_BW_WR, 0x106440},
{OP_WR_E1H, PXP2_REG_RQ_ILT_MODE, 0x1},
{OP_WR, PXP2_REG_RQ_RBC_DONE, 0x1},
- {OP_WR_E1H, PXP2_REG_PGL_CONTROL0, 0xe38340},
-#define PXP2_COMMON_END 2040
-#define MISC_AEU_COMMON_START 2040
+#define PXP2_COMMON_END 2137
+#define MISC_AEU_COMMON_START 2137
{OP_ZR, MISC_REG_AEU_GENERAL_ATTN_0, 0x16},
{OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
{OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
@@ -2345,8 +2458,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
{OP_WR_E1H, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0xc00},
{OP_WR_E1H, MISC_REG_AEU_GENERAL_MASK, 0x3},
-#define MISC_AEU_COMMON_END 2059
-#define MISC_AEU_PORT0_START 2059
+#define MISC_AEU_COMMON_END 2156
+#define MISC_AEU_PORT0_START 2156
{OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xbf5c0000},
{OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xff5c0000},
{OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff51fef},
@@ -2379,8 +2492,8 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x0},
{OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_0, 0x3},
{OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_0, 0x7},
-#define MISC_AEU_PORT0_END 2091
-#define MISC_AEU_PORT1_START 2091
+#define MISC_AEU_PORT0_END 2188
+#define MISC_AEU_PORT1_START 2188
{OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xbf5c0000},
{OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xff5c0000},
{OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff51fef},
@@ -2413,7 +2526,7 @@ static const struct raw_op init_ops[] = {
{OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x0},
{OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_1, 0x3},
{OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_1, 0x7},
-#define MISC_AEU_PORT1_END 2123
+#define MISC_AEU_PORT1_END 2220
};
@@ -2512,72 +2625,64 @@ static const u32 init_data_e1[] = {
0x00000200, 0x00000001, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8, 0x00000000, 0x00003500,
- 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20, 0x00002000, 0x000040c0,
- 0x00006180, 0x00008240, 0x0000a300, 0x0000c3c0, 0x0000e480, 0x00010540,
- 0x00012600, 0x000146c0, 0x00016780, 0x00018840, 0x0001a900, 0x0001c9c0,
- 0x0001ea80, 0x00020b40, 0x00022c00, 0x00024cc0, 0x00026d80, 0x00028e40,
- 0x0002af00, 0x0002cfc0, 0x0002f080, 0x00031140, 0x00033200, 0x000352c0,
- 0x00037380, 0x00039440, 0x0003b500, 0x0003d5c0, 0x0003f680, 0x00041740,
- 0x00043800, 0x000458c0, 0x00047980, 0x00049a40, 0x00008000, 0x00010380,
- 0x00018700, 0x00020a80, 0x00028e00, 0x00031180, 0x00039500, 0x00041880,
- 0x00049c00, 0x00051f80, 0x0005a300, 0x00062680, 0x0006aa00, 0x00072d80,
- 0x0007b100, 0x00083480, 0x0008b800, 0x00093b80, 0x0009bf00, 0x000a4280,
- 0x000ac600, 0x000b4980, 0x000bcd00, 0x000c5080, 0x000cd400, 0x000d5780,
- 0x000ddb00, 0x00001900, 0x00100000, 0x00000000, 0x00000000, 0xffffffff,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003,
+ 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000003, 0x00bebc20, 0x00002000, 0x000040c0, 0x00006180, 0x00008240,
+ 0x0000a300, 0x0000c3c0, 0x0000e480, 0x00010540, 0x00012600, 0x000146c0,
+ 0x00016780, 0x00018840, 0x0001a900, 0x0001c9c0, 0x0001ea80, 0x00020b40,
+ 0x00022c00, 0x00024cc0, 0x00026d80, 0x00028e40, 0x0002af00, 0x0002cfc0,
+ 0x0002f080, 0x00031140, 0x00033200, 0x000352c0, 0x00037380, 0x00039440,
+ 0x0003b500, 0x0003d5c0, 0x0003f680, 0x00041740, 0x00043800, 0x000458c0,
+ 0x00047980, 0x00049a40, 0x00008000, 0x00010380, 0x00018700, 0x00020a80,
+ 0x00028e00, 0x00031180, 0x00039500, 0x00041880, 0x00049c00, 0x00051f80,
+ 0x0005a300, 0x00062680, 0x0006aa00, 0x00072d80, 0x0007b100, 0x00083480,
+ 0x0008b800, 0x00093b80, 0x0009bf00, 0x000a4280, 0x000ac600, 0x000b4980,
+ 0x000bcd00, 0x000c5080, 0x000cd400, 0x000d5780, 0x000ddb00, 0x00001900,
+ 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8,
+ 0x00000000, 0x00001500, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, 0x00000000, 0x00001500,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8,
- 0x00000000, 0x00003500, 0x00001000, 0x00002080, 0x00003100, 0x00004180,
- 0x00005200, 0x00006280, 0x00007300, 0x00008380, 0x00009400, 0x0000a480,
- 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680, 0x0000f700, 0x00010780,
- 0x00011800, 0x00012880, 0x00013900, 0x00014980, 0x00015a00, 0x00016a80,
- 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80, 0x0001bd00, 0x0001cd80,
- 0x0001de00, 0x0001ee80, 0x0001ff00, 0x00000000, 0x00010001, 0x00000604,
- 0xccccccc1, 0xffffffff, 0xffffffff, 0xcccc0201, 0xcccccccc, 0x00000000,
+ 0x00000000, 0x00007ff8, 0x00000000, 0x00001500, 0x00001000, 0x00002080,
+ 0x00003100, 0x00004180, 0x00005200, 0x00006280, 0x00007300, 0x00008380,
+ 0x00009400, 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680,
+ 0x0000f700, 0x00010780, 0x00011800, 0x00012880, 0x00013900, 0x00014980,
+ 0x00015a00, 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80,
+ 0x0001bd00, 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00, 0x10000000,
+ 0x000028ad, 0x00000000, 0x00010001, 0x00350804, 0xccccccc1, 0xffffffff,
+ 0xffffffff, 0x7058103c, 0x00000000, 0xcccc0201, 0xcccccccc, 0x00000000,
0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, 0x00000000,
- 0x00003500, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00003500, 0x000e01b7, 0x011600d6, 0x0000ffff, 0x00000000, 0x0000ffff,
0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x00100000,
0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x00100000, 0x00000000, 0x007201bb, 0x012300f3, 0x0000ffff,
0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x00100000,
- 0x00000000, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x30efffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
- 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
- 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xfffffff7, 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x302fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3,
- 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
+ 0x00000000, 0x0000ffff, 0x00000000, 0x00100000, 0x00000000, 0xfffffff3,
+ 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
+ 0xcdcdcdcd, 0xfffffff1, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c,
0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7,
- 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x31efffff, 0x0c30c30c,
+ 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c,
+ 0xcdcdcdcd, 0xfffffff5, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x310fffff, 0x0c30c30c,
0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
@@ -2585,41 +2690,41 @@ static const u32 init_data_e1[] = {
0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x056fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
- 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x30efffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
+ 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
+ 0xcdcdcdcd, 0xfffffff3, 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c,
0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffff8a,
- 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
+ 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
+ 0xcdcdcdcd, 0xffffff97, 0x056fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c,
0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3,
- 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xfffffff1, 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
+ 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97,
- 0x040fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xfffffff5, 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c,
+ 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffff8a, 0x042fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97,
+ 0x05cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c,
+ 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x300fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
+ 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
+ 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
+ 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
+ 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
+ 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
+ 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x040fffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
+ 0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff,
@@ -2641,16 +2746,26 @@ static const u32 init_data_e1[] = {
0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff,
0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c,
0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0x00100000, 0x00070100, 0x00028170,
- 0x000b8198, 0x00020250, 0x00010270, 0x000f0280, 0x00010370, 0x00080000,
- 0x00080080, 0x00028100, 0x000b8128, 0x000201e0, 0x00010200, 0x00070210,
- 0x00020280, 0x000f0000, 0x000800f0, 0x00028170, 0x000b8198, 0x00020250,
- 0x00010270, 0x000b8280, 0x00080338, 0x00100000, 0x00080100, 0x00028180,
- 0x000b81a8, 0x00020260, 0x00018280, 0x000e8298, 0x00080380, 0x00028000,
- 0x000b8028, 0x000200e0, 0x00010100, 0x00008110, 0x00000118, 0xcccccccc,
- 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc,
- 0xcccccccc, 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0xcccccccc, 0x00002000
+ 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c,
+ 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
+ 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
+ 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff,
+ 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c,
+ 0xcdcdcdcd, 0x00100000, 0x00070100, 0x00028170, 0x000b8198, 0x00020250,
+ 0x00010270, 0x000f0280, 0x00010370, 0x00080000, 0x00080080, 0x00028100,
+ 0x000b8128, 0x000201e0, 0x00010200, 0x00070210, 0x00020280, 0x000f0000,
+ 0x000800f0, 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000b8280,
+ 0x00080338, 0x00100000, 0x00080100, 0x00028180, 0x000b81a8, 0x00020260,
+ 0x00018280, 0x000e8298, 0x00080380, 0x00028000, 0x000b8028, 0x000200e0,
+ 0x00010100, 0x00008110, 0x00000118, 0xcccccccc, 0xcccccccc, 0xcccccccc,
+ 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
+ 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000
};
static const u32 init_data_e1h[] = {
@@ -2751,11973 +2866,13457 @@ static const u32 init_data_e1h[] = {
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8,
- 0x00000000, 0x00003500, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
- 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
- 0x00000003, 0x00bebc20, 0x00002000, 0x000040c0, 0x00006180, 0x00008240,
- 0x0000a300, 0x0000c3c0, 0x0000e480, 0x00010540, 0x00012600, 0x000146c0,
- 0x00016780, 0x00018840, 0x0001a900, 0x0001c9c0, 0x0001ea80, 0x00020b40,
- 0x00022c00, 0x00024cc0, 0x00026d80, 0x00028e40, 0x0002af00, 0x0002cfc0,
- 0x0002f080, 0x00031140, 0x00033200, 0x000352c0, 0x00037380, 0x00039440,
- 0x0003b500, 0x0003d5c0, 0x0003f680, 0x00041740, 0x00043800, 0x000458c0,
- 0x00047980, 0x00049a40, 0x00008000, 0x00010380, 0x00018700, 0x00020a80,
- 0x00028e00, 0x00031180, 0x00039500, 0x00041880, 0x00049c00, 0x00051f80,
- 0x0005a300, 0x00062680, 0x0006aa00, 0x00072d80, 0x0007b100, 0x00083480,
- 0x0008b800, 0x00093b80, 0x0009bf00, 0x000a4280, 0x000ac600, 0x000b4980,
- 0x000bcd00, 0x000c5080, 0x000cd400, 0x000d5780, 0x000ddb00, 0x00001900,
- 0x00000028, 0x00000000, 0x00100000, 0x00000000, 0x00000000, 0xffffffff,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x00000000, 0x00003500, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003,
+ 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20,
+ 0x00002000, 0x000040c0, 0x00006180, 0x00008240, 0x0000a300, 0x0000c3c0,
+ 0x0000e480, 0x00010540, 0x00012600, 0x000146c0, 0x00016780, 0x00018840,
+ 0x0001a900, 0x0001c9c0, 0x0001ea80, 0x00020b40, 0x00022c00, 0x00024cc0,
+ 0x00026d80, 0x00028e40, 0x0002af00, 0x0002cfc0, 0x0002f080, 0x00031140,
+ 0x00033200, 0x000352c0, 0x00037380, 0x00039440, 0x0003b500, 0x0003d5c0,
+ 0x0003f680, 0x00041740, 0x00043800, 0x000458c0, 0x00047980, 0x00049a40,
+ 0x00008000, 0x00010380, 0x00018700, 0x00020a80, 0x00028e00, 0x00031180,
+ 0x00039500, 0x00041880, 0x00049c00, 0x00051f80, 0x0005a300, 0x00062680,
+ 0x0006aa00, 0x00072d80, 0x0007b100, 0x00083480, 0x0008b800, 0x00093b80,
+ 0x0009bf00, 0x000a4280, 0x000ac600, 0x000b4980, 0x000bcd00, 0x000c5080,
+ 0x000cd400, 0x000d5780, 0x000ddb00, 0x00001900, 0x00000028, 0x00100000,
+ 0x00000000, 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, 0x00000000, 0x00001500,
- 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000,
+ 0x00007ff8, 0x00000000, 0x00001500, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0xffffffff, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8,
- 0x00000000, 0x00003500, 0x00001000, 0x00002080, 0x00003100, 0x00004180,
- 0x00005200, 0x00006280, 0x00007300, 0x00008380, 0x00009400, 0x0000a480,
- 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680, 0x0000f700, 0x00010780,
- 0x00011800, 0x00012880, 0x00013900, 0x00014980, 0x00015a00, 0x00016a80,
- 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80, 0x0001bd00, 0x0001cd80,
- 0x0001de00, 0x0001ee80, 0x0001ff00, 0x00000000, 0x00010001, 0x00000604,
- 0xccccccc5, 0xffffffff, 0xffffffff, 0xcccc0201, 0xcccccccc, 0xcccc0201,
- 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201,
- 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201,
- 0xcccccccc, 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x00000000, 0x00007ff8, 0x00000000, 0x00001500, 0x00001000,
+ 0x00002080, 0x00003100, 0x00004180, 0x00005200, 0x00006280, 0x00007300,
+ 0x00008380, 0x00009400, 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600,
+ 0x0000e680, 0x0000f700, 0x00010780, 0x00011800, 0x00012880, 0x00013900,
+ 0x00014980, 0x00015a00, 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00,
+ 0x0001ac80, 0x0001bd00, 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00,
+ 0x10000000, 0x000028ad, 0x00000000, 0x00010001, 0x00350804, 0xccccccc5,
+ 0xffffffff, 0xffffffff, 0x7058103c, 0x00000000, 0xcccc0201, 0xcccccccc,
+ 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc,
+ 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc,
+ 0xcccc0201, 0xcccccccc, 0x00000000, 0xffffffff, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
- 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000,
- 0x00007ff8, 0x00000000, 0x00003500, 0x00100000, 0x00000000, 0x00100000,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
- 0x00000000, 0x0000ffff, 0x00000000, 0xfffffff3, 0x320fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
- 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
- 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
- 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x31efffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
- 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0xfffffff3, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
- 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
- 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xfffffff7, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3,
- 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
- 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
- 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97,
- 0x056fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x320fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
- 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
- 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
- 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xffffff8a, 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
- 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0xfffffff3, 0x31afffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x300fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
- 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
- 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xffffff97, 0x058fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x300fffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff,
- 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c,
- 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
- 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
- 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0x00100000,
- 0x00070100, 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000f0280,
- 0x00010370, 0x00080000, 0x00080080, 0x00028100, 0x000b8128, 0x000201e0,
- 0x00010200, 0x00070210, 0x00020280, 0x000f0000, 0x000800f0, 0x00028170,
- 0x000b8198, 0x00020250, 0x00010270, 0x000b8280, 0x00080338, 0x00100000,
- 0x00080100, 0x00028180, 0x000b81a8, 0x00020260, 0x00018280, 0x000e8298,
- 0x00080380, 0x000d0000, 0x000000d0, 0x000280d0, 0x000b80f8, 0x000201b0,
- 0x000101d0, 0x000c81e0, 0x000002a8, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
- 0x00002000
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+ 0x00000000, 0x00007ff8, 0x00000000, 0x00003500, 0x000e0232, 0x011600d6,
+ 0x00100000, 0x00000000, 0x00720236, 0x012300f3, 0x00100000, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
+ 0x0000ffff, 0x00000000, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x30efffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
+ 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
+ 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3,
+ 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
+ 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
+ 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x31efffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x302fffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
+ 0xfffffff3, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
+ 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
+ 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3,
+ 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
+ 0xfffffff7, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
+ 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x31efffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd,
+ 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
+ 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff,
+ 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd,
+ 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
+ 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x056fffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd,
+ 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
+ 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
+ 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
+ 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3,
+ 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
+ 0xffffff8a, 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3,
+ 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
+ 0xfffffff3, 0x316fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
+ 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x302fffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
+ 0xfffffff6, 0x30bfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf314, 0xf3cf3cf3,
+ 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
+ 0xfffffff7, 0x31cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
+ 0x0020cf3c, 0xcdcdcdcd, 0xfffffff0, 0x307fffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd,
+ 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
+ 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd,
+ 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
+ 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd,
+ 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
+ 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
+ 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
+ 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
+ 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
+ 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
+ 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
+ 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
+ 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
+ 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
+ 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
+ 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
+ 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
+ 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0x00100000, 0x00070100,
+ 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000f0280, 0x00010370,
+ 0x00080000, 0x00080080, 0x00028100, 0x000b8128, 0x000201e0, 0x00010200,
+ 0x00070210, 0x00020280, 0x000f0000, 0x000800f0, 0x00028170, 0x000b8198,
+ 0x00020250, 0x00010270, 0x000b8280, 0x00080338, 0x00100000, 0x00080100,
+ 0x00028180, 0x000b81a8, 0x00020260, 0x00018280, 0x000e8298, 0x00080380,
+ 0x000b0000, 0x000100b0, 0x000280c0, 0x000580e8, 0x00020140, 0x00010160,
+ 0x000e0170, 0x00038250, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
+ 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000,
+ 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x04002000
};
static const u32 tsem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x19d9b38a, 0x22717618,
- 0xa70143f8, 0xa4303332, 0x10267103, 0x97e204af, 0xaf0c0c8c, 0x2fd78918,
- 0xcf608621, 0x38606610, 0x4206c402, 0x22450c0c, 0xa07af108, 0xfe407b9a,
- 0xb698a842, 0x76c30328, 0x3bf781d1, 0x34957035, 0x24a458a6, 0x458d5d82,
- 0xa0d7191e, 0x4494efc9, 0xd012d7e5, 0x4538d03f, 0x513f9509, 0x547f4201,
- 0x342fa684, 0xf95049f9, 0xa57f5039, 0x77376129, 0x001e542e, 0x61aa8a92,
- 0x00000360
+ 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x19d9458a, 0x1138fc18,
+ 0x5980a1fc, 0xd8181998, 0x88039880, 0x81b8803d, 0x91a18191, 0xdafd7891,
+ 0xbf760862, 0x6ec30330, 0x0211e620, 0x1082239a, 0xf354029f, 0x0f5fc806,
+ 0x6512b315, 0x3a263860, 0x06a77ef0, 0x298d2ade, 0xc1124536, 0x1e4586de,
+ 0x93476f19, 0xca8922ff, 0xff4041df, 0x65296340, 0x229dbe54, 0x04a65e84,
+ 0xe4d1a5a1, 0xd7f2a1ed, 0x5192fea1, 0x0dee6ec6, 0xf8003ca8, 0x6065495c,
+ 0x00606549
};
static const u32 tsem_pram_data_e1[] = {
0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x49999cce,
- 0x204e4cce, 0x30840909, 0x43511879, 0x7c061e1c, 0x201276f4, 0x06bf2ae5,
- 0x0ea2a17c, 0x2de42108, 0xebf8fea5, 0x092132fd, 0xf636c544, 0xda2f45a2,
- 0x05a855e1, 0xa180d03b, 0x4a00ee05, 0x7836daa1, 0xf5ab15bd, 0x62a2968e,
- 0x96ad2248, 0xbfcb17fe, 0x24fbdad6, 0x00664e73, 0xbbf7bdcb, 0x9fa7efd7,
- 0xece7d9dd, 0xebdaf7b3, 0x7b5ad7b5, 0x5d8a3ded, 0x19d7ea62, 0xa0ff873b,
- 0xc631b3ec, 0x9f2c19ae, 0x23a57cc8, 0x6ad8cbd7, 0x3127d43b, 0x0f623c16,
- 0x5b18926d, 0xb59fda32, 0x71ca0d30, 0xbc20be69, 0xebe16767, 0xc654c612,
- 0x9b4aadff, 0xe8f2c994, 0xf073b9f9, 0xf30f81dc, 0x58564b19, 0x63026530,
- 0xafcc6c2b, 0x8fba830f, 0xfc9c0fb1, 0x7ff8739b, 0xf61b24c1, 0xbf874233,
- 0xaf3edfa1, 0x814f682d, 0xedcdb37e, 0x1215494e, 0xd5db1993, 0x140bd2c4,
- 0x9c9abac6, 0x49b4fe54, 0x60282f4f, 0x26534f6c, 0x7935f7d5, 0x8d348ca9,
- 0x9a07e7a5, 0xb34f547c, 0xf7e3d7f5, 0x2b7c8e23, 0xce0d1595, 0x68ae5adf,
- 0x060b7182, 0x64cc7feb, 0xf9e00541, 0xafeec2a3, 0x5f9aef80, 0x8512989f,
- 0x802c99f2, 0xf7e86536, 0x45fb2ecf, 0x8ce1b4fe, 0x387c3d65, 0x6844da7f,
- 0xe139b127, 0x87459c22, 0xe25c6b34, 0x77b19f71, 0xcdc032a4, 0x6991802d,
- 0xb9b58c99, 0x4f2e6ffa, 0x44f5cc65, 0x0b9a7fb6, 0x5d0cdde6, 0x2eec648c,
- 0xde0c1056, 0xf81ffd00, 0xe80525b8, 0x614976a1, 0x4b26cd78, 0xd012cd15,
- 0x7ccedd8b, 0xa538709b, 0xd41479a2, 0xde60eefb, 0xe383bdc7, 0x9880c5dc,
- 0x46ccd8e9, 0x32a864e5, 0xa5dd87e8, 0xe2e53686, 0x15c5fd87, 0x2fb712e3,
- 0xd517f839, 0xf6f1a6eb, 0x078d328f, 0x7f13b9df, 0xcbe07597, 0xaef7d77d,
- 0x78842332, 0xe11f9853, 0xc657753b, 0xde25c7ba, 0x7d8f163e, 0xc70aab2a,
- 0x8e1567a1, 0x66dcfc0b, 0x367b74e7, 0xb18d4a17, 0x16663835, 0x9c62b563,
- 0x03d95a29, 0x3000b258, 0xb58cb5e7, 0xdda0bd20, 0x3abf6894, 0xdf4ae00f,
- 0x852a4b33, 0x0af1fa7a, 0xf2115e69, 0x10cf41a1, 0xb1259ff5, 0x9ef81d8a,
- 0x70ca92cd, 0xe71f3b1c, 0x8b50fe86, 0xe86ee007, 0xec9eddca, 0x6194fde5,
- 0x48553fbb, 0x3858b5f3, 0x7a4fd4bd, 0xdf038c17, 0x38c0f7a7, 0xa56b3ef0,
- 0xfe69bac4, 0xe1a614de, 0x32c67e78, 0x70a6a440, 0xa8d99099, 0x7867e424,
- 0xfc8165ae, 0x3f2e3364, 0x8be635a7, 0x9f737e00, 0xd0d47cd4, 0x783579ab,
- 0x69c85a3f, 0x266aa076, 0x01b630f3, 0x530593d0, 0x7ca8dd1e, 0xb3918d10,
- 0xcda37331, 0x9663fa28, 0x997b9f99, 0x9cf286d7, 0xcf3f341b, 0xbfd7376f,
- 0x2769dccd, 0xdc3f82ae, 0x8e4e7dcc, 0xc0e38f33, 0x12cf00d4, 0x6fc0ef21,
- 0xadbf2c6a, 0x5a19626d, 0x91396241, 0x5dce1c96, 0xb7687a89, 0xf7c073e4,
- 0x907b602f, 0x6ef890ef, 0x05d7a8bd, 0x0d5d8555, 0x1e282025, 0x958afc7f,
- 0x1fba406e, 0x101b6567, 0xbf4a0dff, 0x0d7c03aa, 0xa43faa8d, 0x17bf6d0d,
- 0xd7db1118, 0x4e03be2b, 0x99bfbf18, 0xf8c3d6f9, 0x197aec4b, 0xec3c97d6,
- 0xd798bd25, 0x7e472d1e, 0xea05d31d, 0xfbf0772a, 0x2767808b, 0xecf001c2,
- 0x97f4e3e4, 0xdfedfea3, 0xb9f5b12b, 0x77ef0e38, 0x165ceec9, 0xe70c4dcc,
- 0xfc4ecc73, 0xbc0b40b4, 0x267ee582, 0x02c62729, 0x83cc3d9a, 0xcaa968f4,
- 0x54394efb, 0xe9f7c69f, 0xf9ccf583, 0x00033233, 0x6618d657, 0xb3a557a2,
- 0x7af50731, 0x1cb84575, 0x25c3e2f9, 0x12c0acaf, 0x00ae9cf0, 0x2a388fbe,
- 0xea7ec75e, 0xa21636e6, 0xe870edc8, 0x7b1afe34, 0x7237d647, 0x1fa50f11,
- 0xd06fc02b, 0x1865306d, 0xff4595f2, 0xc60fbfc3, 0x989cba8a, 0x172a17ee,
- 0xe20a3f60, 0xf59fcb8d, 0x0f4207fd, 0xf8261e81, 0x957ecbbc, 0xb63c305f,
- 0xc17e7afe, 0x09500144, 0x13f0cbc1, 0x4552a2c6, 0x663dbd1c, 0xa561e977,
- 0xff3c3138, 0x7404f3d9, 0x001a7cd2, 0x7527c8b7, 0x1cb4356e, 0xa7753df0,
- 0xe075f23d, 0x5275ba93, 0xdb7501c8, 0xefbd173e, 0x11ebcb5d, 0xe9f5cab7,
- 0x0a83a846, 0x7f74706c, 0xb3e47afb, 0x8f5b329d, 0xf5858edd, 0x09ccf418,
- 0xc49b3b01, 0x174ae7d7, 0xdbadd6af, 0x5f7e1f7f, 0x2e60e5d5, 0xf76eafe8,
- 0x87af9ba2, 0x76c3a2fa, 0x36ea4d86, 0xa123ab35, 0xd7c438be, 0x0e32bea5,
- 0x4c97705f, 0xa79f4beb, 0xa076e33b, 0x2726c9cf, 0xd0f182f3, 0xb8ceeee2,
- 0x3aadf80d, 0xbf1cbdb4, 0xf92adeab, 0x7753ed10, 0x85943a6e, 0x9721faf3,
- 0xc92d9af3, 0x0fe06bcc, 0x29d13bfe, 0xef0ebe47, 0x193cc097, 0x7588bbf4,
- 0xac3ea394, 0xad14f4db, 0x4ebe0633, 0xce34e936, 0x10fe1c80, 0xeaef81c6,
- 0x387c925f, 0x0b1b7ac5, 0xeef63ca0, 0xa0d9cd76, 0xd59afce1, 0x6bce3742,
- 0x16ed8aa5, 0x72ede685, 0x75be1179, 0xafbc396a, 0xad4ebb5e, 0x9adf918c,
- 0x70cdc32d, 0x111fc9ad, 0x717d8f38, 0x6f0bec12, 0x1abd60e1, 0x45ea01f5,
- 0xaec6a425, 0xa9496f6b, 0x2d9adf44, 0xf89af332, 0xf83dd388, 0xedd68caf,
- 0x5f375ee0, 0x06dd05b7, 0xdba0aaf4, 0x51d05d69, 0x67892fe9, 0xe91b7c7f,
- 0x2074f000, 0x255ca09e, 0xc0dcf3e0, 0xdfe8154a, 0x2e3a67e3, 0xcbe217bb,
- 0xc79b3b0e, 0xcd39ac60, 0xac0afd9b, 0x7b2a1da3, 0xef99ed10, 0xd3fd86b6,
- 0x966dbd60, 0x8025b302, 0xaa05b65b, 0xce15baf8, 0x857f75c4, 0x946f6f58,
- 0x15af34bc, 0x809fc059, 0x25e98ef7, 0xc049641b, 0xcaf5869e, 0x4b9e3c1f,
- 0xfd43dcfd, 0xfe4fd0a8, 0xcbd1fb85, 0xd1fa98a7, 0x7e8cabcb, 0x493f5016,
- 0x474fd717, 0x786675f9, 0x7e8dabca, 0xcf1fa8ea, 0xff4bcdc5, 0x78660dc6,
- 0xfd4b51be, 0xb1f34ea4, 0xbaeb8680, 0xedd607e0, 0xb6bde197, 0xe3c27535,
- 0xca2f962c, 0xdcf1c61e, 0x7cb12520, 0xc9253291, 0xfea987c4, 0xf43aa661,
- 0x2cbad3a4, 0xe3df8ff4, 0x4754b924, 0x4a17a4aa, 0x9e093a47, 0xa46a4687,
- 0x2eba1e17, 0x87ae3970, 0x4bda3638, 0xab81a90f, 0x0d7c38f5, 0x132c4a70,
- 0x320fb04b, 0x695fbe87, 0x1b2878e7, 0x7df0b675, 0xd6c1bef8, 0xf50a985f,
- 0x3fe95b36, 0x959e3ce2, 0x24969db8, 0x976c46b3, 0xdef6e0e4, 0x0d92dcca,
- 0xb53c18c1, 0x4bfa068f, 0xdbb6fd83, 0x5fc89903, 0x0ebf4bcf, 0x18adbf22,
- 0xfc7d92ad, 0x22aff342, 0x2b8fd041, 0x22665747, 0xc82a1d3e, 0x2af8ec77,
- 0xe3445f8c, 0x7ff1c06f, 0x477c6098, 0xf8d314de, 0xd32a9cce, 0xc6154ef8,
- 0x26df7e07, 0x07c625bd, 0xd8c75dfc, 0xa1bfcd4b, 0x55391df1, 0xb44afe34,
- 0x4fc7634f, 0x27ff181a, 0x5bbb8c12, 0x90d2ebe2, 0x675de7f9, 0xb54e7f9e,
- 0x9f2afe79, 0xdfe95eff, 0x3449f8c4, 0xefcd7dff, 0x54e7f9f1, 0x783bf9f3,
- 0x7be303bf, 0x107ff006, 0xd1247fe7, 0x306ff3fc, 0xad4c7fcf, 0x3e0efe79,
- 0x0fa52ffe, 0x8d1af8c5, 0x13e6abff, 0x6a63fe7c, 0x11d57c69, 0xa91f21f0,
- 0xc91a92a3, 0xed06cf9e, 0x94748234, 0xdcb1ca9f, 0xf2976eee, 0x250f0f08,
- 0x3cfbbe71, 0x1b4df809, 0x042c77d4, 0xacfa0512, 0xcd7cf05e, 0x503552d6,
- 0xde83de24, 0x5d40285b, 0x5f1325d0, 0xd08ed5b3, 0x6f6f0065, 0xfac41c97,
- 0x0b5fd582, 0x71deb4c9, 0xb9cc007f, 0xc3ff3e08, 0xc7d6e3d3, 0x2e5acbce,
- 0x889fb0ec, 0xc388e49a, 0x63632c13, 0x6bbe011b, 0x67f09d25, 0x1e804fd4,
- 0x3f3fa065, 0xe58a3d00, 0x381fc287, 0xa9967a0e, 0x4cd372b1, 0x6f7741df,
- 0xeebcc116, 0x509ff010, 0x2c4fbe38, 0xff884295, 0x507a9fcf, 0xb0b4fd45,
- 0x3e901923, 0xa0834708, 0x476eff53, 0xf844bd68, 0xee7e22f4, 0xec645124,
- 0x5fbec277, 0xe9b866b4, 0xd42cb9bb, 0x1fed0996, 0xb46f3558, 0x67bff30e,
- 0x4c82638e, 0x947f9f7e, 0x8d98e48d, 0x318f81b2, 0xfb29f3a7, 0x39dca828,
- 0xefb26ec7, 0xeb980aef, 0xeb9954f7, 0xdd90f6bd, 0x62c6f686, 0x7e83ad89,
- 0xbf346def, 0xdbb1c637, 0x8c7b0986, 0x0647778f, 0x2c5ef787, 0x9d63e027,
- 0xce9f7ae8, 0x69e035bf, 0x22cec478, 0xd3465eb4, 0xc1678fd1, 0x02d7b274,
- 0x15b79f3a, 0x4eecfbde, 0x73c0057f, 0xe132c3df, 0x747f0ad3, 0x06dfb25f,
- 0xcd745c76, 0xe768ed1f, 0x8563e75a, 0xd665feff, 0xea2ae8f9, 0xeb4179fb,
- 0x5627ce73, 0x2ae86a7e, 0xa63c7e1d, 0xeff85d5d, 0xe18f1f87, 0xb32d9aaf,
- 0xa1c5f54c, 0x17ed4cbb, 0x7a6799ad, 0xb163b0bf, 0xed03fde9, 0xf3ea9a0f,
- 0xda9b0f82, 0xd9acbfdf, 0xc6defef4, 0xefef4cc7, 0x54ca7aa9, 0xacf02bbf,
- 0x739dfda9, 0x4bde99d6, 0x898f16fb, 0x8c0d5e92, 0xf2bb42c9, 0x7e43076d,
- 0x90ddf834, 0x329a8f87, 0xe4d93ca9, 0xe519b2a5, 0xb6dfe414, 0xeb0d979b,
- 0x63d18de7, 0xed0ff6ec, 0x4f28398d, 0xe2b7be56, 0xf0dfcad3, 0x75bc546f,
- 0xc16b28c8, 0xd73d475f, 0xe367d627, 0xf8648f79, 0x2e49cb07, 0xb72e556b,
- 0xcab23bb5, 0x55ae5fd0, 0x718d8523, 0x79018afc, 0x0f344b0e, 0x3a745686,
- 0xd5b80dd2, 0x137cd744, 0x65fb3d9c, 0x651ebf1a, 0xffdff417, 0xb2df1565,
- 0x1c883ea1, 0x1c75b9cc, 0xc87fe3c2, 0xa574f086, 0xd3dbfad3, 0x71f86334,
- 0x4157f105, 0x734d47e5, 0x14d13ca8, 0x5378f2a0, 0x341f9515, 0x6d195235,
- 0x7be5465a, 0xdf2a414d, 0xf2a76a6d, 0x541d4db7, 0x435a6b1e, 0x429a6fe5,
- 0xf936f654, 0x2bf01ca9, 0x26993d0c, 0xff614aec, 0xf5410ac3, 0x322e62d3,
- 0xf24dddfc, 0x7944cbe8, 0x5e7dad3c, 0xe9f37688, 0x72c60e63, 0xcacbe313,
- 0xcaf1090f, 0x545764fc, 0x4c394086, 0x95defa1c, 0xb2e4e9c4, 0xf40c19b1,
- 0xfd9763c6, 0x88bf37c0, 0x861b0aea, 0xb37c87df, 0x05fa71dc, 0x75e915df,
- 0x7f313a21, 0xa06cf17f, 0xfee789c7, 0xedfb04bd, 0xd70a75c1, 0xad3283cb,
- 0xc1b22c97, 0xc18af487, 0xfd3fad1b, 0xbe5e853b, 0xa54efe00, 0xceebf81b,
- 0xd8bb7f41, 0xa7ff53a6, 0x414c1d3b, 0x0e49ee3c, 0xf4eaa861, 0x5c1e0de1,
- 0xda6496ef, 0xf071e3f4, 0xe1759460, 0x5d8b5d5c, 0xf5ccba27, 0x0cd21dd3,
- 0xa6f2bf1e, 0xd67c86dc, 0x0bc7eba4, 0x5499fe90, 0xc92cfd1a, 0xe4e3f554,
- 0x3af8871f, 0xf89535b5, 0x6a36fc14, 0x470d1ff7, 0xe1067ea2, 0x87bf64e8,
- 0xc917c9ef, 0x337ef2ff, 0x7144fe53, 0xfec7b626, 0x0ee7ae39, 0xf91ceff8,
- 0x8dd50af7, 0x72c21b7e, 0x3e3571d0, 0x0f1a6adf, 0x3e1af3be, 0xf3bcb9f1,
- 0x4ec2abf1, 0xbdf9f8c4, 0x71f90638, 0xf7acdd2e, 0x86f54d53, 0xb4dd2cae,
- 0x201fe00e, 0x524aacf7, 0x056a5f90, 0x5a29f4f7, 0x1df004bb, 0x2e8979b1,
- 0x576f120d, 0x01aa8ce7, 0xcb4df22f, 0xb17bd71d, 0x2f1a8765, 0xe9b2716e,
- 0x125157b0, 0x9f235fc3, 0x8e22a87e, 0x8d1c3f9d, 0x368bd427, 0x67334f6e,
- 0x24fe83d0, 0x667a0ccb, 0x6d3409bb, 0x07e43f00, 0x753138c1, 0x21c59fa3,
- 0x75bc7f7b, 0xedc6c7b2, 0x05b8eb64, 0xf85174b2, 0xb47adfab, 0xc56de71c,
- 0xa7d77d63, 0x0be4806a, 0x883257fe, 0x47bf0347, 0x3205156c, 0xe5bd5ff4,
- 0x3f27b27d, 0x1f0b07b2, 0x1ade8f39, 0x7996bf0a, 0xde663922, 0xe38dd641,
- 0x5a7117cc, 0xdf3befe0, 0xe3f17581, 0xe30cecd7, 0xb42cecf0, 0x8303818a,
- 0x3fa8364c, 0x3bf36a20, 0xfb3e286b, 0x41db8db1, 0x0785580b, 0xd62ac29d,
- 0xe0768251, 0x819b6629, 0xdec53a78, 0xa18c4cf0, 0x25590cd3, 0x6ed03cfa,
- 0x7ec043b6, 0xad17d535, 0xd92bd731, 0x33d40cec, 0x2cedab95, 0x4cfcd124,
- 0x3ac8a7ef, 0x3588bbf5, 0xb9f5c0ae, 0xdfe3cec5, 0x8ca675f3, 0x5eeaf802,
- 0xe304be7e, 0xdcc8b7e2, 0x1be2308f, 0xf871878b, 0x54ebc3ab, 0x7dffbc3f,
- 0xae3bc4e7, 0x687df867, 0xc10fae05, 0x936f929d, 0xbf7e2877, 0x7856fc2c,
- 0x487bf58d, 0x51c0459c, 0x1b8a45b7, 0xf057bd37, 0x3f8fc1b7, 0xec36f312,
- 0x1eb197fa, 0xca37f763, 0x332aae22, 0x4a7ee919, 0x296d0677, 0xefe29ef4,
- 0x5f0e1dc1, 0xacefcc0b, 0xf22962ad, 0xc50fd817, 0x59dda62c, 0xf79e805b,
- 0xd257af48, 0xa11299be, 0x7b58107d, 0x357dd894, 0x8c53c939, 0x83376371,
- 0xf71f35f5, 0x241482d5, 0x9aaee158, 0x6e318ac9, 0xfa00fa0d, 0x7e53d27b,
- 0x4bba8258, 0x9fd864eb, 0x971cd323, 0xf5cd7977, 0xf703fc06, 0x8a32c67d,
- 0x558f251f, 0x308c782c, 0x9f6e1fd4, 0xe42fbe25, 0x1f13de11, 0xa1c5887b,
- 0xb9116a74, 0xe9461918, 0xf297f019, 0xf0e35fd0, 0xda007c53, 0xfb79d52f,
- 0x5f07117a, 0x88d976fa, 0x9789e761, 0x15819c35, 0xdd4c7868, 0x519fd388,
- 0x25e26858, 0xac2f55e8, 0xf57a31b6, 0x07e05b65, 0xa3d40f48, 0xe3049f08,
- 0x04f86204, 0x563d571c, 0xf85a0fce, 0x23866fe1, 0xfbf4998d, 0xe5e05b11,
- 0xcdfc7078, 0xe90e67fd, 0x687fe0ff, 0xfa4305ff, 0xfebc75ff, 0xb6de5eeb,
- 0x54fc082b, 0x3da7e3fd, 0x63ecccc0, 0x07c323a5, 0xd4ddaf74, 0xfcb941e6,
- 0x907a0948, 0x64871fae, 0xf2b3f7da, 0xe4315d81, 0x2549afd3, 0x47c43fc4,
- 0xe27c5f27, 0x3eb7b466, 0xc9d764df, 0x88e2dfbf, 0xeb298038, 0xf973173b,
- 0x9f78e2d8, 0x8a7e57d7, 0x65d0d9fc, 0x9bd517d6, 0xd2f0ce9f, 0xfe1415fa,
- 0x87fc846f, 0x287f8dfa, 0x81ac7b47, 0xb3de93f5, 0x9fe3877e, 0xc2f64619,
- 0xe865353c, 0xaebf637b, 0xa1a5e041, 0x654f89f3, 0xf9289612, 0x55f6d68b,
- 0x5cf80fc2, 0x9367fb16, 0x33e464d9, 0xc42c1f03, 0xe5f900fd, 0x8e318be7,
- 0x35f1b3d3, 0xcb14548f, 0x9def5c9f, 0xfdf03f0e, 0xcb137a9f, 0xc5e82f53,
- 0xb0db7b58, 0xc25dbcef, 0xcbc3d97f, 0x83c47b5a, 0x75dafd71, 0x1e105f76,
- 0xf0db6ed7, 0xae30e783, 0x77c3b6f2, 0xb35ff419, 0x5cdfd5ed, 0xed9af507,
- 0x7c99b4f6, 0x31949a1a, 0xf8069748, 0x4184d96f, 0xe4ff543a, 0x8e3bd555,
- 0xd8747f3f, 0xb66a3d20, 0xb8d957ef, 0x1a98f8a1, 0xb546afde, 0xbf097438,
- 0x867e8e5f, 0x2a17f2fc, 0x7de3fdd2, 0x1b911b12, 0x5eeb9f07, 0xf1197b25,
- 0x74147444, 0xa59ba01a, 0x05d0037d, 0x2741abf5, 0x4263fbeb, 0x6f3fb1de,
- 0x4bf3f111, 0x907dc53f, 0x387c3adf, 0xbe97aaff, 0x7c79c1e9, 0xbe7234a8,
- 0xc32dbe7e, 0xd956e30f, 0x953a1983, 0x0bd579fc, 0x5b7e22df, 0x195bf474,
- 0xfe60bf14, 0x0ad91b2c, 0xdf9c2cc1, 0xd3b7b5c2, 0x80592afc, 0x79eaaef8,
- 0xabd702b9, 0x633614cf, 0x78b91c7b, 0x87c5c844, 0x80f1c1eb, 0x0b887df9,
- 0xbc0bee07, 0x06de5321, 0x7c520f63, 0x7ec65be4, 0xf5425b0e, 0x4e9c9ccf,
- 0xefc315b3, 0x96279585, 0xecae375f, 0x1c9cfa46, 0x71811fed, 0x04a606df,
- 0x73a43e05, 0x747cafd0, 0x1f4e08fa, 0xc44a55e6, 0xa7efa077, 0xdf6c73e2,
- 0x8abbf76d, 0x73b1df4d, 0x2fe383b9, 0xdc03e315, 0x7ecf6849, 0x1f7f1198,
- 0xac62b37f, 0xc5576037, 0x7c8c57f0, 0xf8df7973, 0x436f9718, 0x66b343de,
- 0xbd3ffbe0, 0xbf07e5c9, 0xe0057b43, 0xf7a08c8a, 0x48936ffb, 0x2458381f,
- 0xb46f5c9e, 0xbf36b90b, 0xe004f837, 0x1ddd7056, 0x7fec17e0, 0xec9fe118,
- 0xf0d5cad8, 0x6cbe8c5d, 0x433cf1c0, 0x76e433fb, 0x87ff9091, 0xb3fcb314,
- 0x13ee5cb5, 0xc2411bfb, 0xf43dad4f, 0x5e50e783, 0x1f713e41, 0xbd9b76ba,
- 0xc9fde702, 0xb9bf83d6, 0x93e4e41b, 0x66a721b0, 0xd39569fd, 0xb0d71daa,
- 0x09fa7278, 0x93c413a6, 0x571e7853, 0xf128b54e, 0xfe957ff1, 0x82f7f034,
- 0x3e867f05, 0xab47844c, 0xf15ebc3e, 0xfaad3e12, 0xc9bdfe10, 0x9ff2864a,
- 0xbf0677c1, 0x6ea8ff55, 0x019dea0c, 0x6ef834be, 0xbe0d2f80, 0x342f121b,
- 0x3e886fe1, 0xf00cd8c3, 0x7feec549, 0x99fcc72d, 0x5f7c3dda, 0x843bbe14,
- 0x9f93c075, 0x871d61bb, 0xd6c5a546, 0xd87a9643, 0xa96fded2, 0x07da5857,
- 0x4b46f52c, 0x0bf710fb, 0x3caa0ebb, 0x6a62254f, 0x82ce5f6f, 0xef538c6e,
- 0xd21e2995, 0xc0af3007, 0xb9ada4bc, 0x6863cc21, 0x5338f173, 0x02baba7f,
- 0xde9f57f5, 0xb07b41ef, 0x73e3c5df, 0x9efd157d, 0xec3b18d4, 0xe9323dfd,
- 0xcd8868df, 0x822fe788, 0x8bf44187, 0x79ef44b2, 0xacba7ddc, 0xf8c32ce5,
- 0xc3ec874a, 0xe682cd90, 0xdfb83d3b, 0xff27b7df, 0x7cf03996, 0xb69911e1,
- 0xfed0faf3, 0xfb34414e, 0x3f18ac95, 0x7c1623ed, 0xa38c06e6, 0xdafee1ef,
- 0xbb165582, 0xbe22ad82, 0xaa96d4a8, 0xbfc117a8, 0x8fbcc0fa, 0x5abbf9c0,
- 0xd6b557f4, 0xdef8defc, 0x37abe3f0, 0x8407df9a, 0xf9167fdf, 0xf1d2ed1d,
- 0xbbf73c6c, 0x09378f19, 0x2e5d3afd, 0xe00e65ba, 0xccb0efbf, 0xef4e5f90,
- 0xa7ff0991, 0x737df2b7, 0x8b5f9f8a, 0x7a4fda7c, 0x0f53c0cd, 0x589a85ca,
- 0xfcecf4ef, 0xd023c95d, 0x3bd776a4, 0x6504ffc5, 0x0bb7aecf, 0x97f5867f,
- 0x8779cadf, 0x753f6d0d, 0x2bf68b9f, 0x69b9f6fa, 0xef6fb17f, 0xc11e732f,
- 0x8f876efa, 0xfdf6fef2, 0xa7f918b9, 0x0aa3b96f, 0x68df56f5, 0xecb667ee,
- 0x947173fd, 0xa256c9d6, 0xee76e5db, 0xf3de9ee7, 0x6949efef, 0x70acc258,
- 0x4c97dffd, 0x9f86b771, 0xd65e28ba, 0x25cff7b7, 0xa5fbf6b1, 0xec5ea7ce,
- 0xd9b9f623, 0x5f081d9c, 0x697fdf2a, 0x1bb5d9f8, 0xa20f319a, 0x00fabf73,
- 0xcffa9fbc, 0x3ea3145f, 0xedc1dbec, 0xf47b5e9a, 0x9b27dc05, 0xb962b6d0,
- 0x8bd5e81d, 0x64fb8142, 0x0b2f3f6d, 0xf2f0f16a, 0x2f01c505, 0x8f7f1f16,
- 0x9fff48f8, 0xf6890f80, 0xb8f76bbf, 0xe7094e43, 0xdef797fd, 0xcfb03d41,
- 0xcc697c41, 0x337093f7, 0x9a171dd9, 0x6e57d577, 0x62e452de, 0xbff2bde6,
- 0xedbbff39, 0x2acf825e, 0x7cf94307, 0xdf5443ef, 0xbc11f6e6, 0x9befc917,
- 0xdf746abf, 0x5cf77401, 0xfe87de78, 0xc8fdd2c7, 0x3aee827d, 0xfc3499e6,
- 0xdf0417f3, 0x2773d597, 0x3dd39bfe, 0xfb0dfcd1, 0xaf9b71fc, 0x6ce30f23,
- 0x3ac3fd68, 0xb767b9ad, 0xf1efd863, 0xb475b3b1, 0x2fb16517, 0x846f8569,
- 0x191ffdca, 0x5e3127f7, 0x3c899a37, 0xd10fee6d, 0xad0c1d96, 0x8f649568,
- 0x6e0ada2a, 0x6ebe2b27, 0xf1e5e03f, 0x28fbe72b, 0x384d8787, 0xf67ac016,
- 0x438a3e0d, 0x56c2fc5b, 0xb025f989, 0x6f2b9553, 0x8a7e8c3c, 0xe22dac7d,
- 0x7df2a628, 0xf88a572c, 0x4d575da2, 0x64568bfe, 0xe6bcbbae, 0xe7f443ba,
- 0x677e1c64, 0x9c610b26, 0x80e2be59, 0xf265f98e, 0x50498578, 0x208eb177,
- 0x4c8e09fa, 0xc47ff7f3, 0xb898d364, 0x11ebda2c, 0xbe7fd7b0, 0x07c50375,
- 0xfef8bd4e, 0xcd6fd8cd, 0x04e664cf, 0x756ef4bc, 0x8df208b3, 0xffd15212,
- 0xfd94eea8, 0x523c8f3c, 0x3ecc6b72, 0xd62761a0, 0x704dd8fc, 0x8470ef55,
- 0xd5f7c266, 0x4c5f7ebb, 0x7ef2f6eb, 0x2f8363b2, 0x3d4f3c4a, 0x7dc62d18,
- 0x0e716abe, 0xf1a74ac0, 0xf77f8f2a, 0x839e4eec, 0x85b4bafe, 0x875649e7,
- 0x623bb4ef, 0xaac64bf2, 0xf11da376, 0x1287f051, 0x7c20a9e5, 0x8679f9b1,
- 0x43f3da9d, 0x65d7c389, 0x65be610f, 0xbded96f5, 0x3ea87718, 0xd9a1f0e6,
- 0x53e5b0d7, 0xfd4f6b8a, 0x944f36f1, 0xe4d92cfc, 0xf7f10e77, 0xd744c8b6,
- 0xb23acefa, 0xf44ea15b, 0x8fc70fad, 0x2fc85c7b, 0xdef1f9a9, 0x6140415d,
- 0x7b364fcd, 0xb271ae30, 0xfc87937b, 0x8fe72dbe, 0xeff10cb7, 0xd79d8fc2,
- 0x7f893bbf, 0xb774fd80, 0xb78ff16a, 0x15fb270c, 0xb7892be0, 0x4df065df,
- 0x5ecfb6cd, 0xcf63f8c0, 0x405e4f8e, 0xfaff6b78, 0xfed017c7, 0x3a5cfb64,
- 0xbc3443ee, 0xbf14aff8, 0x2a5bbe31, 0x87f7aee4, 0xd5ee299b, 0xf6357e0b,
- 0xc3f7bbd6, 0x7a3ff41c, 0x0325ffb7, 0x7ba5e4fd, 0xf9c08fa7, 0x7539dd2e,
- 0xbf238b04, 0x1b7c8946, 0x9bb888ba, 0x3b075e95, 0x7c9d920f, 0x7e8de80a,
- 0x1ebf80ca, 0x0ff1e3ae, 0xb7d3f0af, 0x0e6f8fc6, 0x6f3bcbf1, 0x936be5bd,
- 0x50fbb4b0, 0x3fd05c0d, 0x78e8137f, 0x6fd045f5, 0x5fc263eb, 0x53bf4f89,
- 0xe9d007f8, 0x57f0aabb, 0xeb3efd04, 0xe7fdf85c, 0xf0e75df0, 0xe479fe84,
- 0xc466f022, 0xfd57ef4f, 0x3728abcf, 0xf1447e3b, 0x4cdba410, 0xb6ef6898,
- 0xee3072cf, 0xffbd91fc, 0xef579e3e, 0xad1fd1d0, 0xc916fbde, 0xa3ceef4f,
- 0x22649f14, 0x06cbd98e, 0x93b8f1fe, 0xd86b85c8, 0xbd7ee6e8, 0xfdfa3fc0,
- 0x173d0f5e, 0x63e73dfe, 0xe44fefc3, 0xf2a9bfef, 0xae23023c, 0x1df1b75b,
- 0xd20f3fe1, 0x74829a4b, 0x71bcff7a, 0x3a0f0368, 0x6c7261e2, 0x5c7e2afc,
- 0x29ce2065, 0xadc465e8, 0x5053e206, 0x4578c6cf, 0xc58b7a48, 0xebbd07d1,
- 0xd7abdc78, 0x199fce6e, 0x678f0fa4, 0xa72adafd, 0x638b8ba1, 0x2ffe085d,
- 0xea889f8b, 0x0c73c535, 0x8d9cf53c, 0xab4fc7af, 0x37fa9e3c, 0x902c87ef,
- 0x9f21fbac, 0x75d63f22, 0xf3f2afbe, 0xcbbcfc04, 0xc8b7bec0, 0x5179ebf7,
- 0x8ac878a6, 0xe3d241f0, 0xec617d56, 0x55e15997, 0xd54f5c1c, 0xa275f177,
- 0xa43b8767, 0x073d3f41, 0xd73f1376, 0x455f7d6f, 0x96d0f33f, 0x9edca89f,
- 0xeb83f2e2, 0xfe062844, 0x17f6979e, 0xcf1d78f3, 0x338eb63f, 0xd2f1c1cc,
- 0x38fe27b0, 0x353f5b0d, 0x0c13538d, 0xf37f3cab, 0x549de3fc, 0x7f6277fc,
- 0x0cedbb27, 0x864ef3f3, 0xf6f119e5, 0xeb133f67, 0x035e71a6, 0xb3ca4bd7,
- 0x33cfca3e, 0x89237a4c, 0x1e9798f2, 0x9e0ef19d, 0xe20a5b8b, 0x6760f68c,
- 0xced3e733, 0x428ff07f, 0xbd1e777a, 0x6a75c65b, 0xc637e217, 0xb3792c2e,
- 0xf41baa71, 0x15bbc942, 0xad5d9093, 0x31f266fa, 0x187e099b, 0x03ae0467,
- 0x9e0fd0ad, 0x27fcc02f, 0x94f64784, 0x647840cf, 0xe2bba6dd, 0xb5da95e4,
- 0x36f3ca0a, 0xe6ebb5fa, 0x76766e3c, 0xe9fb17a2, 0x0bc8c2bd, 0x3c4148aa,
- 0x3b7dd67d, 0x29159d2f, 0x99d679fa, 0xecbe848f, 0xef01f269, 0x581673f3,
- 0xbdf9106f, 0xd20e7b55, 0xb0aaa2b9, 0xaf80bcc4, 0xe483acc5, 0xaa4766e6,
- 0xdb335bc8, 0xfe7bd50f, 0x7757da85, 0x2c35f6f2, 0x3cf1ed4c, 0x1f24c446,
- 0x07762d13, 0x913eefe7, 0xa67b51d7, 0xf6624584, 0x7c13ef71, 0x9ba4d3db,
- 0xc22d7bf4, 0xa939e1a7, 0x2ea71a6e, 0x8e34dc3c, 0xcceeaed1, 0x93122c75,
- 0x74a7547f, 0x9dd5bf13, 0x671a3bf9, 0x329abe40, 0xfb890f09, 0x7b82651f,
- 0x2629ffb0, 0xbffb0778, 0xe6b5c681, 0xe6ce6677, 0x5bacc271, 0xce341979,
- 0x852654bd, 0xb76f005a, 0x0e25816b, 0x5ee99f68, 0xc32afb9d, 0x285356f3,
- 0x8761fa3f, 0x8cde50a4, 0x4a759f38, 0x583682d7, 0xd6d39f6f, 0xa303753f,
- 0x707f813c, 0x2793135c, 0x3e7422c0, 0xe43768d3, 0x208f25bd, 0x15013f1b,
- 0xf2f80b28, 0x68c11e45, 0xb4f3a516, 0x3cfcdd6b, 0xcd2d18e0, 0x106fdf86,
- 0xde71be76, 0x40f9c86f, 0x0bc0b9cb, 0x9b4c079d, 0x18e0fa5a, 0x396f631f,
- 0x798a9d3e, 0x967769e2, 0x83a51f6e, 0xa652c1df, 0xe9737d51, 0x97a82cf8,
- 0xf5e16fb5, 0xcf8e975f, 0xab957a81, 0x246bd793, 0xb35fabca, 0x60b4c172,
- 0xe5e825d1, 0x252300db, 0x11bcbd26, 0xe2aa71e9, 0x7a163bdd, 0x5fa14f31,
- 0x1565f8e5, 0x14f46ed8, 0xed6cb78e, 0xa788eddd, 0x3368b631, 0xefef93ea,
- 0xea2a73fd, 0x09d32f71, 0xd56b3a3f, 0x68f07e91, 0xe4f3b9ca, 0xc2f359c3,
- 0xa5d9fe0c, 0x1c227605, 0xd2c7f36d, 0xaae7bc39, 0x1fd13826, 0x6cf2235c,
- 0x0fc81d9e, 0x7ef1e7e4, 0x75fbe0ee, 0xeb0f2299, 0x29b9a3f4, 0x0fa3cec3,
- 0x5dbb321a, 0x7d5c0c4a, 0xb3ed3f4a, 0xff7d9df7, 0xc49bcc3e, 0x759c6a7a,
- 0x37fbf065, 0x93c90a5d, 0xe981ff39, 0x0b5fc469, 0xde217f04, 0xf879319c,
- 0xcaa0e48b, 0x8874c3cf, 0x8e9a6ef5, 0xb58297f3, 0xbeabb9f2, 0x68169e3c,
- 0xcf90f781, 0xbc8871df, 0x34be711b, 0x7be33ce6, 0x79eb4788, 0x8a8e8dc6,
- 0x55977e28, 0xe5072679, 0xa27ce06d, 0xf48591d4, 0x64779eb3, 0x9e2dbf4a,
- 0x9c5eb11f, 0xf7044c77, 0x3e819d8f, 0x9fef3f1c, 0x830e3bbd, 0x40bd5fdc,
- 0xe7ca61f5, 0xa526cbd5, 0x215cfc2b, 0x820d05d9, 0x5c6d32af, 0x1887b03f,
- 0x39f6d3ed, 0xebfa3f24, 0xc9d4df7d, 0x305ec80e, 0xbee6fc93, 0xe630dce4,
- 0xc23df513, 0xfd8297cf, 0x8f7ca120, 0x711293de, 0x3f3e4879, 0xe7e7c8b7,
- 0x3cc97b66, 0x6f39df6e, 0xd3fa9457, 0xc8607f45, 0x0f9e0c67, 0xfaf993ee,
- 0x25e4d7de, 0xe0b34638, 0x2f13b47e, 0xd38f3c76, 0xf017fe7c, 0xf0633baf,
- 0x811c740f, 0x426734f5, 0xc6708e3a, 0x1cf5a3a1, 0x204711ea, 0x587ddb1b,
- 0x86056879, 0x4fe7ac5e, 0x42cc1299, 0xdbe9593c, 0x6b3c74a0, 0xec662987,
- 0x16ec94f9, 0x2f577e83, 0xc32ba5f3, 0x8b1cf44d, 0xe7bd5e70, 0x6dc21b53,
- 0x527bf1d0, 0x8277bb7c, 0xd667af93, 0x44e632f1, 0xed38816d, 0x5095978b,
- 0x499f807f, 0x8f5cfc16, 0x14e29af3, 0xfc50c2eb, 0x2fed8f5c, 0x8bfe3f02,
- 0xc7e18fc1, 0xae3908d5, 0xa0277dc1, 0xb3bc1ff3, 0xdc60f233, 0x3e235972,
- 0xa649bc5d, 0x9fb42db8, 0x28319599, 0x6daf8bf7, 0x7e076fdc, 0x44bcfc59,
- 0x9c40b4fc, 0x9c44ff2f, 0xefe6b13f, 0x9209ce55, 0x1e70bd9e, 0x46f4885f,
- 0xf3f316cd, 0x7fc29dbb, 0xca1cb374, 0x47f715cb, 0xad7f82c8, 0x09ad3ff8,
- 0x6a905eb9, 0xc7a5676a, 0x299b46e8, 0xea6b3c0f, 0xd7e43f40, 0x6fbcda67,
- 0x17edfc51, 0x20f18676, 0x293692bf, 0x2498f882, 0x4b7ec34d, 0xfd197c85,
- 0xb666598d, 0xe68372eb, 0xedf979f3, 0x9779f3e6, 0xb5348c75, 0x9e4d7cbf,
- 0xa115fde9, 0xafef4d2b, 0x54c132da, 0xcebe171f, 0xaeeafed4, 0x7c7d5332,
- 0xfb5346e4, 0x9b678789, 0xdf74d7ea, 0xf93f6a6d, 0xfbd37cd8, 0xa6d5a36b,
- 0xb47fd7f7, 0x5aff54c4, 0xb531ffff, 0xfae42c8f, 0x665340eb, 0x7c98f1f6,
- 0xaa0f03e3, 0x3f9f1d36, 0x8bd36858, 0xf8679f63, 0x9658c5bd, 0x4e9fd1f8,
- 0x3aa767a4, 0xd763b2b3, 0x376652f7, 0x4ea99fe9, 0xf0643d73, 0x0bf00e4b,
- 0x45937f10, 0x6dbc80ef, 0xd5193941, 0x983b4378, 0xe2e46ca1, 0xa7941482,
- 0xc5f9f1a7, 0x9236d9c9, 0x9d08fab3, 0x0e738f8b, 0x17356dfe, 0xf7482ef9,
- 0x2e1980a1, 0xa33100ca, 0x9606e60c, 0x29060b0a, 0x28f99cd9, 0xeebad2ef,
- 0x15bdeb1b, 0xdc9c071f, 0x6178701e, 0xdfd9379d, 0x645fee21, 0x3129731e,
- 0xa8f590f8, 0x1ef0eea9, 0xd77fe2d6, 0xeb2e7a6d, 0x69754cc7, 0xffca4cd1,
- 0x3d970449, 0x1b4dfe73, 0xb3d9bf41, 0xcf1a5402, 0xe2d8e6db, 0x9d45f7e6,
- 0x9de79717, 0xf10bbed0, 0xfb18a5fc, 0x39748a2e, 0x33c6f695, 0x3f56af98,
- 0xeffc9fb7, 0x3f59872c, 0x237dd60c, 0x97963e78, 0xf9d4279f, 0xda9b6b9f,
- 0xdf75c26f, 0xb7c2e798, 0x7e606767, 0x7f027642, 0xe7c5c73c, 0xd55342f1,
- 0x8cf00b4d, 0x2589da09, 0x73b2e783, 0x68e50d22, 0xf9118d7f, 0xe2d8cfd4,
- 0x759d3de7, 0x047b7f72, 0x13b4682a, 0xcb3f7e34, 0x3d77caa9, 0x2455b298,
- 0x7f22ce07, 0xbbbabfce, 0xf65f9f84, 0x7c3cf265, 0xf437e09d, 0xf1568e5c,
- 0x1cadea0c, 0xb9bcd730, 0x3119e143, 0x2e4662b7, 0x661d6fbc, 0xef5469f3,
- 0xf05ce897, 0x870d8ca3, 0x957fadf6, 0x03d6be09, 0x905e52d7, 0xda1805aa,
- 0x993cc6e1, 0xf63037c8, 0xbb4b3e11, 0xd6d4fc8d, 0x05ce072b, 0xb55bf231,
- 0xf7ec6e8a, 0x0858bc33, 0x932d69c6, 0xb473ef4c, 0x010f078e, 0xc99d951c,
- 0xd6549714, 0x967e4cdc, 0x69e1c99a, 0xd962417d, 0xe3c3c112, 0x0f8e1ee6,
- 0x42ea83c0, 0x3f73fb3a, 0x869319b7, 0x2a2975f7, 0x9d1ceb9d, 0x8d719e20,
- 0x5b7ebf01, 0x9709d906, 0x5795e19b, 0x21e0fd3f, 0x89d903cc, 0xfde11637,
- 0x3d04cb22, 0x4b6df3cd, 0x5dcb7d9b, 0x4de5aed0, 0xb800c999, 0x30d8ca37,
- 0x0a1c879a, 0x41b7c1c5, 0x1afb802f, 0x535e5b84, 0x15ccf34e, 0x74045e74,
- 0xd32575c6, 0xe8833156, 0x3863619e, 0x37fc2b4f, 0x7fdcb8b8, 0x790ba5cd,
- 0xe369bcad, 0x90172c70, 0x9b5e81bc, 0xba97fd86, 0xd311da12, 0xdbf4715c,
- 0xa8ffee85, 0x087dd39d, 0x136fd94b, 0x61636d76, 0xfa0cbdac, 0xd7ec16f0,
- 0x8f29cba8, 0x17bf6316, 0x141bbbb2, 0xee617b5f, 0xb432ed85, 0x0cff90c7,
- 0x39e60c7b, 0xcfbbc70f, 0x31ebd665, 0xeb9e7c7a, 0x4ac9ece2, 0xdde1f76c,
- 0x12f6b891, 0x1bb271e8, 0xfaf8d5d3, 0x1e82fbee, 0x28caba0d, 0x3ec1302f,
- 0x5c5d77d1, 0x4ff3adae, 0xc85ddeb4, 0x611bc8ef, 0x14ec07ee, 0xa5583ff2,
- 0xa756fb4a, 0x58f75d1f, 0x68fbe621, 0x9bc79479, 0xcb519fa8, 0x0f3f20de,
- 0xe204f9f0, 0xbb5fc0c1, 0xc69e7f85, 0xc5d6f1f7, 0xcda7c05a, 0xd70ecf84,
- 0x7f9fd845, 0xf328b9fb, 0x815e9e79, 0x0ffbd077, 0xf5b83e92, 0xb38c12bd,
- 0x39fedfd4, 0x79bffde9, 0xb8e6399c, 0x802f1181, 0x9c716a71, 0x2aff5bde,
- 0x8a51bae2, 0xbcecb647, 0xab07ee9c, 0x49f4332b, 0x45ce93a3, 0x7d11e766,
- 0xf872ed4e, 0xc353ce11, 0xd4ec5c78, 0x3087c9ae, 0xd349f32e, 0x73d8bce1,
- 0x3a5ea759, 0xfe87625a, 0x5a38ed4e, 0x0f5e90a2, 0xf78cde11, 0xa5fee775,
- 0xe377fd04, 0xdf00c1fc, 0x4bafe339, 0xf9fc16bf, 0xf180f165, 0x525fda78,
- 0xcf68b3d8, 0xd6a5e00d, 0x2a7ff79c, 0xc412bdf9, 0x13ffe603, 0x463c045e,
- 0x8bb57bbc, 0xa45a9fc7, 0xc6e31060, 0x54f7522d, 0xff06d38c, 0x4073a317,
- 0x9256b799, 0xcc3dfe99, 0xd61abc03, 0xb7db0ca1, 0x3e667db1, 0x750b9b1b,
- 0x111d2bc7, 0x1dd49f7c, 0xed42bca6, 0x4b047758, 0x8fdfb44f, 0x47fa86db,
- 0x6f2c7efa, 0x86ff02d7, 0x0feb0fe3, 0xfdf2815e, 0x3313058f, 0x4ca12631,
- 0x62f61df5, 0x852ce21e, 0x7d3a6dee, 0x2275a658, 0x3d739663, 0xa8ceff3f,
- 0x5eedccfe, 0x9392375a, 0x81e9f38c, 0x15575c5c, 0xf611fa56, 0xf815d5bb,
- 0xc33ff904, 0x08785dd6, 0xfb1d73be, 0x79e60e6d, 0xeda2f71b, 0x8fd8ad2a,
- 0xbbfdc6fb, 0x367aef25, 0x9c9f6e34, 0x28dfe5c4, 0xbe3527bf, 0xc961f98d,
- 0x63a7db8f, 0xae7bebbc, 0x0547ba46, 0x999df9fe, 0x702b9fd0, 0x71854b0f,
- 0xc66da924, 0x876ea0d7, 0x7bf1e3f7, 0xd02b5b5b, 0x606a5761, 0xbbde0d94,
- 0x87ad73a5, 0x8dfc3df1, 0x49c965f9, 0x9ef15ae7, 0xe7493538, 0xb902d0f3,
- 0xba818748, 0x4c77750e, 0x2ba969dd, 0xabcc6ebc, 0x285fe0ee, 0x0f7eb3ef,
- 0xef07d7bf, 0x337dc333, 0xe50cb7bc, 0xe849353f, 0xb1698d09, 0xdacea1e7,
- 0x3c49e902, 0xe5c8593e, 0x265f88c4, 0x97e22f78, 0xe291ac85, 0x60f1236b,
- 0x5bda3e75, 0xb0e654dd, 0xf88d2a7e, 0x51f31e5b, 0xa82ac059, 0xa83acb1c,
- 0xa98592bc, 0x54dd622c, 0x2a7eb316, 0xb1974c7d, 0x547cc09c, 0x8f1ad9a6,
- 0xf97d474e, 0xcbe93b0b, 0x1e0f2dc2, 0x0508c918, 0x6aa5ba26, 0x69867e5c,
- 0x2864a1a5, 0x80388b57, 0x16a9ae71, 0x3545e669, 0xd07d90a0, 0x93ea6423,
- 0xee20b635, 0x2ab9b29f, 0xe715af3d, 0x3edf6b80, 0x27e47640, 0xaa79f8fe,
- 0x4b949353, 0xeb3287dc, 0x1ab586c7, 0x73e41be1, 0x1ebbe22a, 0xcdba82e1,
- 0x1ee74dd9, 0xdfc3cbed, 0x745f7196, 0x45f69d9b, 0xa026506b, 0x0c2ee35e,
- 0xa7984b35, 0x9f6a515b, 0xf24d7c44, 0xce1a9353, 0x9e0da098, 0x78fac407,
- 0xebdf906d, 0xc1ca9ebb, 0xf78ff67d, 0xf9eb4dbf, 0x34b9c9f5, 0xa3ceba9f,
- 0xfb4dc06a, 0xcdca2a76, 0xf603e9c7, 0x6d8dd937, 0x9e0a5f2e, 0x25ffe93b,
- 0xc0ca8fbf, 0x7e95f7df, 0xc7beec57, 0x745026e1, 0x37af632a, 0xabf95265,
- 0xbf952f26, 0x1f99d268, 0xf623b91c, 0xe11136a8, 0x11d02f4d, 0xf0f44fde,
- 0x612663eb, 0x179e7b1e, 0x7692d3e7, 0xd444d57c, 0x77d93e3f, 0x77638c19,
- 0xf7849f2f, 0xce64b627, 0x95947ca6, 0x1fe704da, 0xc5169e00, 0x71874ce7,
- 0x6876d35f, 0xd3794197, 0xb89d9317, 0xd696bfae, 0xdf7179a9, 0x3aedfc64,
- 0x7f4103ee, 0xfea56fab, 0x09bfa2ec, 0x18ff6c4e, 0xf60da3f6, 0x6fd45fb3,
- 0xc348ef72, 0x189a87f7, 0x7a537dc1, 0xf7f61a67, 0xaf85a2f3, 0xdf84984f,
- 0xbbdee2db, 0x3499d374, 0x67bb07e6, 0xe61c99e6, 0x737af587, 0x2895e359,
- 0x9a4ddfff, 0xf904e6d6, 0xab1b7257, 0x4dac5f51, 0x09cdb9ba, 0x3653efc6,
- 0xf54e93a0, 0x0015dae9, 0x1fae34c7, 0xbc36f200, 0x659ed06f, 0xfc3af8a3,
- 0x8e5eeba3, 0x8eb8fea0, 0x2d969fbf, 0xfda010f2, 0x9f9fc7cc, 0xad57768e,
- 0xe962f9c4, 0xd3ee8ced, 0x544f6448, 0xf3a2499d, 0x7afd4679, 0xf31104ba,
- 0x8fb483d8, 0x43c67552, 0xbe2efae7, 0x1ce9a73f, 0x34fed0e0, 0x95f0ef1a,
- 0x29f93f06, 0xbb74b36e, 0xf970cfc8, 0xefbb6047, 0x83f98dd9, 0x7c44edbd,
- 0x0a83d40d, 0xaa23dbe8, 0x6df9ff31, 0x6e7f40d3, 0xb3df0756, 0x658f9829,
- 0xf47e67bc, 0x89248f87, 0x7e3ab07a, 0xfb4b24fb, 0x4dfea33c, 0xe7856f6a,
- 0xbac1ae7b, 0x5f2bda13, 0x08ea0638, 0x4b3653df, 0xf18cc37f, 0x6afea11f,
- 0xbed16572, 0x12bf55f5, 0xaae0ef43, 0x667bd2f3, 0xad6dd3d2, 0x9011fdf0,
- 0x6ebf5a73, 0xa17eb467, 0xf462f9dc, 0x6eb14ce0, 0xd2b99d55, 0x3a418f44,
- 0xfee89b14, 0xec65c821, 0xada2eb3e, 0x2173a4df, 0xbcbc9333, 0xe7e4161f,
- 0x9be6d69c, 0x3fff57f6, 0x1c2b7f1c, 0x4c7004fe, 0x63862ffb, 0x41bc69ac,
- 0xf04c8a38, 0x51c3e7fd, 0xf28e0096, 0x561c14af, 0xc728c57b, 0xf642bda0,
- 0xb0f38f2a, 0xb7b236e5, 0x151552fb, 0x369897f3, 0x5204ec85, 0x8eea5e19,
- 0xf146f1f6, 0x8f7799ae, 0xf3b61e63, 0x995dac2a, 0xe82afa80, 0xed7dc3cc,
- 0xe07ef16f, 0x740561f9, 0x2754e8d0, 0x177b47ed, 0xfc60d454, 0xb2a73bdf,
- 0xf1bd4a8e, 0x33ffbc16, 0x3c7fa0a7, 0xb4eb77da, 0x98db17b4, 0x6905ef49,
- 0x241e97dd, 0x13ee76bb, 0x2c94dadb, 0xcf8d9bd4, 0x052c1da2, 0xce1db5b7,
- 0xeb9ef78a, 0x5f927bad, 0x542975a2, 0x3f44aec6, 0x850ae428, 0xda3d200f,
- 0x23d21f34, 0x7b5089f7, 0xc795d41e, 0x8066be6c, 0x6d0d4957, 0x2bf00f59,
- 0x9afa164f, 0xf5087de1, 0x527fb61f, 0xab3de109, 0xd9bc9a2b, 0x8b49bf78,
- 0xb7d68fb0, 0xdf31d4ce, 0xb30a9ed8, 0xb0ae5204, 0xf685de37, 0xd7e49afa,
- 0xe2d79cdb, 0x1f6be07a, 0x267af3ae, 0x8f39b5c0, 0xc55339e5, 0x437f587b,
- 0x1ea46ccd, 0x7f4af753, 0x5fbcf995, 0x80dff36f, 0x6a92fceb, 0x157fbfc6,
- 0x879b95e3, 0xefe17819, 0x5c7531bd, 0xc1e6944f, 0xf79834fa, 0xbeb9e786,
- 0x47fa147f, 0x13e61f7b, 0x1c6e3b24, 0x8c324f9f, 0x2710f78d, 0xf5a3cf8f,
- 0x8beb0435, 0x578fdf07, 0xb1963ce8, 0x671ce3bf, 0x6c1dfda3, 0xdce4f58f,
- 0x73ffda3c, 0x08be62ce, 0x6966ede6, 0xf150bf7c, 0x38fcc34f, 0xf8bf00f7,
- 0x8aa8de29, 0x926d0ffd, 0xa93fff79, 0x39b4bbf5, 0x7e64549e, 0xd7302cee,
- 0x1f37cc1d, 0xb66a9683, 0x592879f9, 0xb387efc4, 0xe457e891, 0x6c3682db,
- 0x510b0577, 0x908b1579, 0x458e3f5d, 0x86357ea9, 0x38f1f33e, 0x700e9794,
- 0x997e644d, 0x642b47c7, 0x68163bf4, 0xbf68cd81, 0xfe164c6f, 0x6fde48ca,
- 0x77c1454b, 0xbe297ba6, 0xc5e519b1, 0x559eafa8, 0x448df14e, 0x3c69a5f2,
- 0xdee2388e, 0xfbdef382, 0x8f8cf539, 0x3ce46379, 0xbb79e35d, 0xba31b70d,
- 0x0f61a28f, 0xf78ca3f7, 0x7ef324af, 0x2fc4121b, 0xc15fae41, 0x459f7c79,
- 0x74b9edcb, 0xd3dfc9cf, 0xda8fb03d, 0x17548218, 0x6dfb9b79, 0x513b7b16,
- 0x92cfd91e, 0x80f2fe79, 0x18fc235f, 0xce9035f2, 0xe0597fc2, 0xbe6ee832,
- 0xc7b8c1cf, 0x4dc84fa1, 0xc44aa55f, 0x09834068, 0x05b7e9ea, 0x4a801ee8,
- 0x35ca9f31, 0x1fe819a5, 0x177fd82c, 0xf570b9c1, 0x0e30352c, 0x23cdc9cf,
- 0x5d7818bc, 0xfe0ff160, 0xbcf131d8, 0x9ec332f1, 0xc303fc36, 0x09fab01f,
- 0x71bfbe89, 0x43a27eec, 0xed296679, 0x7b237edb, 0xc0eb0d96, 0x4fbc7e6d,
- 0x78af38ca, 0x9feecec4, 0x6439445d, 0xb3f9f033, 0x550f7e2e, 0x7543dc48,
- 0x0c3f9bd8, 0xff919bbf, 0xbe5815c5, 0xa86b0ce6, 0x7b3b5fb7, 0x1ff266f4,
- 0x7986b094, 0xee14a717, 0xc67519ff, 0xbf14c8ce, 0xc9bf7817, 0x8fdd06fd,
- 0xefee5370, 0x9d78bce8, 0x573a0dfb, 0x4ed3aa7e, 0xb9377279, 0xf7b169c2,
- 0xbb94dc67, 0xf87ced37, 0x2387fc31, 0x79c3de02, 0x6804e49f, 0xe19f915c,
- 0x4b9d20df, 0x35bdfc4e, 0x471ae33f, 0x61f23759, 0x5dd7e0b7, 0x8345205a,
- 0x21766db2, 0xacda4fc9, 0xbfde4e49, 0x94247f39, 0xc57c44cc, 0xff0647cc,
- 0x5905ef59, 0xe873f12a, 0x386ae089, 0xafad3363, 0xa884f783, 0x8af6beb4,
- 0x26774378, 0x907afa7b, 0xd1ac5997, 0xe26ffb4e, 0xc916957e, 0x313d476b,
- 0xdfb96fcb, 0x5551e447, 0x2df0f588, 0x6a051f91, 0xe63f55f1, 0x7d3f3175,
- 0x63ee2dd7, 0x8f602c61, 0xfd023f97, 0xaddaf49a, 0xdbf5cc33, 0xeb75cc2b,
- 0x1e46863d, 0x7a4d2bcc, 0x5d3dec76, 0x87e812d3, 0xa5db351b, 0xcd1a0fc5,
- 0xae2303f1, 0xc3f98757, 0xe3c2cfb4, 0x7c9dd37a, 0x8b88b2fc, 0x341a2ff6,
- 0xb8861d75, 0x3de19f51, 0xae35d3f6, 0x845e306f, 0x574d04f7, 0x436dfb8c,
- 0xef939f22, 0x6457a47b, 0x7dfdfb8a, 0x54af7499, 0x1ce99257, 0x386711ab,
- 0x494de05d, 0x3b7f0f3d, 0xad70d8d6, 0x54afa818, 0x07c89d1a, 0x5e79b32b,
- 0x871f20d5, 0xc754f14c, 0xfdee351a, 0x80fd0372, 0xe273c15e, 0xdb6fb12e,
- 0xd8f5f8ae, 0x5ec38478, 0xda7f23a1, 0x5edd65dd, 0xab55e5e0, 0xabc72cee,
- 0xbf305a0b, 0x4694ec17, 0x822bebed, 0xed3b4fe0, 0xaf78c3be, 0xf36dd3af,
- 0xacdc7ae2, 0xab3f68d9, 0xeb49d325, 0x56a90aef, 0xe8d2f5c7, 0x685519d7,
- 0x3cb5a73e, 0xe0897fd2, 0x669fc153, 0xbe631fb4, 0x6f3fea8f, 0x0dda8d3c,
- 0xe0eaffb9, 0x756714b5, 0xff946d79, 0x746816a4, 0x5fc19a8f, 0x6b9c7ed6,
- 0x24fdb894, 0xba427fc2, 0xd794a3db, 0xdfc5abd6, 0xbb497e5f, 0xb9eebcc4,
- 0xea777896, 0xf8230a6f, 0xe0f514bd, 0x8f902eb9, 0xab8c3497, 0xabfd3e8d,
- 0x47c92f52, 0xe1afcf06, 0x2da2db72, 0x5fbcf277, 0x89693df3, 0x4bc0d1f8,
- 0x47283c22, 0x4fdc51fe, 0xfab1601f, 0x563529c6, 0x68e1bed0, 0x138a6d85,
- 0x5cdc514f, 0x3e28b74f, 0x6bf95fe2, 0x075c4e15, 0x9ccad39a, 0xa6df9fb8,
- 0xd1725378, 0x33223c3e, 0xeab59b8c, 0xca31b966, 0x4f7ef1c7, 0x8898e380,
- 0x27df5a8b, 0x380bc825, 0xc7f5d627, 0xeddb5ff7, 0x009f0f3f, 0x491e68de,
- 0x7a8e8a79, 0x7873b641, 0xed7dc593, 0xc44dfa89, 0xe7ec4f1f, 0x8abbe0f7,
- 0xca8e749c, 0x38ab5e3a, 0xf00ad72f, 0x9adb9da0, 0xbee3e30d, 0xc9d157b8,
- 0xc49b1e8e, 0xa17c319c, 0xf7a24ea4, 0x3c34b5a7, 0x135ac7bb, 0xa7819df0,
- 0x1f552ed7, 0x97fc2c07, 0x978a5bfe, 0x5fdff0c7, 0x6bdff1e3, 0x1ce973c8,
- 0x2d7bd8fe, 0xbfbe5495, 0xc8d78567, 0xdb6677af, 0xc04bed4c, 0xa371e0b7,
- 0x032a1cef, 0x50311cd6, 0xf1870607, 0x71cf513a, 0x74e22e7f, 0x714fb60e,
- 0x55bca77f, 0xc39d3aa1, 0xebfcef83, 0xf74f6a34, 0xcea1d4d9, 0xf6aa3f07,
- 0xb0e98d4e, 0x4bd59f3e, 0x6f00ddd3, 0x7e01f749, 0x9d33a61e, 0xf88b5eff,
- 0x8def0ade, 0x1bf74e1e, 0x29953a3d, 0xc23ffcc7, 0xece83fdf, 0x1c62f24e,
- 0xfc5873b7, 0xcc7883df, 0x742fe46d, 0x28c8fd88, 0x4fa44bed, 0xff51ebe5,
- 0x8ff264ee, 0x99a7e286, 0xb16177df, 0xc1ee0637, 0x77642250, 0xc3bb0ad4,
- 0x2e64bf18, 0xf287aff3, 0xeed624d5, 0xca70fb04, 0x15dff8c0, 0x47802dfb,
- 0x9f96fb80, 0x4ffb455d, 0xc2af7f46, 0x33ed84b2, 0x92c5a232, 0x13fc097c,
- 0xcefba666, 0x42d19cea, 0xd97b1fdc, 0xf88e9816, 0xcd16386e, 0x1be77ac0,
- 0xbc1ec927, 0x72ee1e10, 0x7b9a7d73, 0x479f6195, 0xeb38d8d4, 0xe7a5edd2,
- 0x8b570f3d, 0xfd1890f1, 0x72b78836, 0x7e90ebc2, 0xe8af3fa1, 0xe92be31f,
- 0x3ae9f12d, 0x2c919f48, 0xf47cfc38, 0x89c161c9, 0x22a12e9c, 0xe7dc7f4e,
- 0x5d937983, 0xf59b741f, 0x8afeffc9, 0x130d37cc, 0xd29f80d1, 0xbef3c4a1,
- 0xde2cef78, 0xe3c4bb8f, 0x693fad35, 0x1d457b0a, 0x4987c316, 0xfa84e82c,
- 0x4be88e2d, 0x7518ff68, 0x0e2dfde3, 0xcfec69e0, 0x90c8e5c9, 0xf1b9dadf,
- 0xedc736e5, 0xc74df9e1, 0xf7dc1e22, 0x03e38e98, 0xbfc33bbe, 0x3ac77ba7,
- 0x3f8664bb, 0x6e62309d, 0x83680e40, 0x0fda1a74, 0xfc86abd7, 0x95793983,
- 0xed3fc85b, 0xfee32ee3, 0x8c67a1b5, 0x6b725eef, 0x8b8fa697, 0x7af39c86,
- 0xe408e509, 0xcb2e10ea, 0xbdf8cb39, 0x5ee2b577, 0x0f711e9b, 0xdfc207e2,
- 0xaff73a60, 0x3eb07b8d, 0xf7c81c28, 0xd6af3f23, 0xde0effe5, 0xca8ec343,
- 0x27fa6f94, 0xfdc29fdd, 0xd4bfb343, 0x31b9ee23, 0x66b6a5fc, 0x36736f71,
- 0x4936e7e7, 0xf6167fba, 0xf74a363b, 0xf0646718, 0xa738d3f5, 0xf4a332c7,
- 0x1f065a7b, 0x7fb3e225, 0x7a80f211, 0x8f97182f, 0xe32fe255, 0xeeb007f9,
- 0xb5ec6305, 0xd0151ff9, 0x98079bb9, 0x0f97e28f, 0x60b327b4, 0x5f3b5e0c,
- 0x732f9f88, 0x29db8c42, 0x456679ee, 0x7c835e7c, 0xb9d1e7ce, 0x0fdc3e3c,
- 0xe8fe70a7, 0x7779f714, 0xc464fe2a, 0xe175a253, 0xf65e80c4, 0x2b1f2327,
- 0x99bc1c5f, 0xc79af5c6, 0xfbf457bd, 0xe2cabfb3, 0x8f0004f7, 0x7b607f42,
- 0x1762c7a7, 0xf0feb25d, 0x419bd69b, 0xbd234fbc, 0x43fae972, 0x48fe80bf,
- 0xf2c2fa23, 0xe2bb41ee, 0x57bf30c5, 0xb6c3c5ed, 0xd0e3eb19, 0xe5c840ad,
- 0xdd0ae995, 0x84557643, 0xda89fbaf, 0xf7130c65, 0x5a3c0b0a, 0x8fcb4be1,
- 0x08b71fcf, 0xf196d43a, 0x9ef1917b, 0x942f9c76, 0xafe83e39, 0xd20b4ca7,
- 0xbc8bbff3, 0xdad17187, 0xfe2f0e1d, 0x0ecf524e, 0x85ea1557, 0xaa8e1d9e,
- 0xfa50daf5, 0x9bf42df9, 0xff8cec2c, 0x64bffae9, 0x2fe27fae, 0x4ba01f71,
- 0xad1c7ba6, 0x76e93dfd, 0xfa0377d3, 0xe5dd813b, 0x2d33fa10, 0x9ec5d399,
- 0xab4dd7c7, 0xf023dd5c, 0x67c08f76, 0x1e57b89a, 0xae2721d6, 0x39bb4643,
- 0x0094fde2, 0xef3f7b8b, 0xfa570863, 0xecf03ae0, 0xfbf632b2, 0x7d3bf8e1,
- 0x742b8a41, 0x839236fe, 0xf294f6fd, 0xfbf58138, 0x8c67c162, 0xc9e8ed99,
- 0xfd12bcd3, 0xd258611e, 0x807edf71, 0x4f7e61de, 0xb2770af0, 0xc5a2cfb0,
- 0xf73f92f7, 0x48a3f524, 0x0f1c50af, 0x0dbf366c, 0x0a7e88f3, 0x9e4c5b76,
- 0xbd16bde6, 0xbe678563, 0x13b7cf9b, 0xa3f637f5, 0xdde38b45, 0x5bac60ff,
- 0x86d3bcc6, 0x49e0e59b, 0x26c71f0f, 0x25974bc6, 0x6eba0f1a, 0xebe30c77,
- 0xe60bcf31, 0x479e127a, 0xc80b39e8, 0xfaee00e3, 0xfc6fc5fb, 0x59ce7888,
- 0x13d2b03d, 0x5da00763, 0xb095eb4e, 0xc6553bc3, 0x5d844bf7, 0x8274fa88,
- 0x90770b16, 0x6d974906, 0xf12b5f5c, 0x43cc35f5, 0x9b897efc, 0x2fb419fa,
- 0x4fb11db8, 0x389d6bcc, 0x8daafa3f, 0x21bd92b5, 0xe9c864f0, 0x6e9c8b4e,
- 0xec357cf5, 0x77e275b4, 0xf17e912d, 0x614ae1f4, 0xf31c95af, 0x95bcc78f,
- 0x1f342acb, 0xdd25a1fa, 0x9e600fb3, 0xfc1ee14e, 0x39419a61, 0x8cfc142e,
- 0xc18dcdfd, 0x6e3cefdf, 0xe6f7dd93, 0x857f0457, 0x7cc0d8c7, 0xebd18def,
- 0x7ae1eeff, 0x2dfc1d2b, 0x5fd38394, 0x785ebd11, 0x9e00e2ac, 0xba05aac3,
- 0xf830caa3, 0x6f3c33a3, 0xe1ed0bb9, 0xf687cc63, 0x9e786f74, 0x47f01c6d,
- 0x3f6e1aef, 0xd5f9e80e, 0x97a05f1c, 0x2f97a8c3, 0x2e4fe63b, 0xc296ba82,
- 0x7365eef5, 0x2967bf19, 0x5fa10eec, 0xf489e86d, 0xe2a7fadb, 0x727d6f3e,
- 0xe62bb363, 0x2efb40f9, 0xa83b9f68, 0xdf516a6f, 0xf3db1378, 0x79925323,
- 0xc71e7b3e, 0xe664f4cb, 0xaf3c0174, 0xdc6506e6, 0xb2f57cc7, 0xaf7809dc,
- 0x40a4a1fa, 0x7ef812d1, 0x0e3e0cf2, 0x2e8472eb, 0x47878dcb, 0x4433afae,
- 0xe44328dc, 0xf124676f, 0xe70a4572, 0x979d24f7, 0x1f9ce9f7, 0xe3f13c32,
- 0xbb44cb4c, 0x3bd71b3e, 0xb7c6978f, 0x914bae4b, 0x8b3ced2e, 0xdfc6b24f,
- 0x17494baf, 0x06db6af7, 0x3fc1b5f5, 0xc677c427, 0xfc6265f8, 0x89986745,
- 0x8d29167f, 0xce8b37c4, 0x8637c428, 0x3fe2245c, 0x1aeeff63, 0x14c6e047,
- 0x9fa3f79c, 0x209c6315, 0xdf0f6577, 0xdfdfc237, 0x7cb136b9, 0x4181eb18,
- 0x9df3d06f, 0x3d00cf18, 0xad0a693f, 0xfc8bcf43, 0x31a72e53, 0xf08ffa76,
- 0xbb3b1df7, 0x8e6bccaf, 0x7ac0eba1, 0x8cfee3e9, 0x85195d75, 0x89e9c049,
- 0x7298d5e7, 0xcaedfaa9, 0xf1787604, 0x5e1da97f, 0xe4813dd2, 0x578101f6,
- 0xc466be23, 0x7897f0b1, 0x8ab3bdb9, 0x1a7931f0, 0xffc06f97, 0x22ff8156,
- 0x1a7fff8e, 0x643dffc0, 0x79707427, 0x4bd688c9, 0xf45f24f9, 0x453bf19d,
- 0xa0df27b9, 0x293dce7c, 0xa9df7fdc, 0xbe409ffb, 0xbbf2255c, 0xa888cf27,
- 0x407b58de, 0x2ad17efc, 0x1af9c0fb, 0x591bc7ca, 0x0ecdfbcb, 0x189497ef,
- 0x8596d1f9, 0xf9802cc7, 0xf9f15767, 0x9bb14dac, 0x5875a7d6, 0x485f2e87,
- 0xbb2dfae1, 0x6015222a, 0x4a376b7f, 0x1237f40a, 0xf809877f, 0x0b236466,
- 0xd0fefec5, 0x4f1f1f48, 0x07a485f3, 0xd3e7068a, 0xa4559b6e, 0xcf695e83,
- 0xa0b5f648, 0x3606a4c8, 0xbed79f23, 0xf2fca11b, 0x2b76efc9, 0x9e5fc7e8,
- 0xcf82dfea, 0x6578f98d, 0xbefd247d, 0xce1cbbf9, 0x32f7610e, 0x71e1cd16,
- 0xfe0427ff, 0x887b0bd7, 0x23dfa61d, 0x94fdb8d2, 0xe9ac7cb1, 0xff0ce777,
- 0xfa73fd07, 0xb599693d, 0x70a78a33, 0xbcb196fd, 0x834bec90, 0x57e7a61f,
- 0xd3e7c46c, 0x01315c47, 0x5fc897ef, 0x77f05115, 0xd6ba7fa5, 0x94fef716,
- 0xc01f4243, 0xcec7f63c, 0x6b7242e3, 0x9d27b3b4, 0x67936f9f, 0x0ddbb7c4,
- 0x3e7d2c3e, 0x0fba6eed, 0xb86555b1, 0xffe064ef, 0x378ad4f2, 0xe1919e11,
- 0x46e11275, 0x49c4678c, 0xcfca39f0, 0x9cf9aa07, 0x5cf9425e, 0x82cc63b6,
- 0x556cf958, 0x2ceb3e89, 0xe86e13bf, 0xae14de8b, 0xad48efc7, 0x71f203f8,
- 0x1453d77d, 0x91bc59b7, 0x424c1eff, 0xfe245cfc, 0x78cdde60, 0xf80d5dcf,
- 0xa3ef7817, 0xeec89614, 0xf7c39dad, 0x72b76adf, 0x2aad657e, 0x1b5703dd,
- 0x7f411ede, 0x7ea3d462, 0xd5a76e1f, 0x2d2edd6c, 0xa8ebc18c, 0x27e510da,
- 0xe436ee5c, 0x2b19eb89, 0xd8dc63df, 0xc876fc05, 0x9eeaedc5, 0xff07ee52,
- 0x7ac9083f, 0x0080006b, 0x00000000, 0x00088b1f, 0x00000000, 0x7dd5ff00,
- 0xd5947c79, 0x6779f0b9, 0xcc93324f, 0x2133df64, 0x61262201, 0x01161212,
- 0xa0084933, 0x24584e08, 0x81ec36c8, 0x8bf628ac, 0x0c197e95, 0x6f62e452,
- 0xb90556ac, 0xda544076, 0x1a080962, 0x88b0e834, 0x148d6ad0, 0x43b05b05,
- 0x921088a5, 0x6f16b629, 0x79e7bd69, 0x799939ce, 0xf8b0ccdf, 0xabbf7ed1,
- 0x9cce1c7f, 0xf3cf6cf7, 0x273f679c, 0x2d675a5d, 0x2ba42229, 0xcae6c229,
- 0x9dbde424, 0x91488ee3, 0xe9769884, 0x55ae503d, 0xd034496d, 0x7483b5f6,
- 0x4eda16b6, 0x62909b88, 0x8e35a242, 0x12cfd0dd, 0x92adb26b, 0x49eab108,
- 0xc848d9a1, 0xeec4f1b0, 0xf0b7e5a6, 0xafad095f, 0x425cf5a4, 0xc1d334ee,
- 0x293fa0e2, 0xc9089874, 0x9c709b36, 0xc3211578, 0xac39090b, 0x34432e25,
- 0x8be0bb21, 0x89ac8411, 0xe399c472, 0xb10f1e60, 0xf196fed1, 0x4258f7f4,
- 0x5b891a6a, 0x6cd5f3a2, 0xf423adda, 0x76847277, 0x6524224a, 0xd6f384bb,
- 0x2d2cdf6c, 0x5e67bfa0, 0x075fb5d8, 0xa19357df, 0x7ab3f461, 0xd03b8d89,
- 0x7180cf62, 0xf61c7b49, 0x9654eb13, 0xbd70b884, 0xe9b7c6c3, 0x0e38b9ac,
- 0xbff4a3ee, 0x079f4ab6, 0x5666cfec, 0x9b3577e3, 0xa64feeb6, 0x626a91f3,
- 0xefc56fee, 0xe6c5dff6, 0xff89e8d7, 0x675864fb, 0xa2e75b2e, 0xc4baff5c,
- 0x2aaad7fe, 0xdfb4cd73, 0x5b08f8da, 0xb38b6d0b, 0x7ac18738, 0x0f3aa78d,
- 0x61918851, 0xa73a3ca7, 0x77febfd1, 0xd1848475, 0x58c3877e, 0x15b352ff,
- 0x47563ae1, 0xcebbf85c, 0xe3a56395, 0x8e17ee1d, 0x49b9bde3, 0xa4e01e35,
- 0x2773270d, 0x3793f9d3, 0xb454956d, 0xe6411b1e, 0x23d6023a, 0x5cc7bbd6,
- 0x062e6156, 0x1c227438, 0x706936ea, 0x473a15fd, 0xff5cf2f6, 0x2acc5377,
- 0xf4c0f79c, 0xfa5e74cf, 0x7c6fd3fb, 0x6ba9f884, 0xb06dec95, 0x748fd6de,
- 0xac00f2d3, 0x7893533f, 0xf6102642, 0x3e7b33df, 0xefe959d2, 0xfc337613,
- 0xa9deedd5, 0xaecb4059, 0x1a4ba352, 0x303c780c, 0xaeace807, 0x24c24f4d,
- 0x06739fc0, 0xa74943c0, 0x78841e02, 0x42be81d3, 0xe80233e1, 0x3aaa08a8,
- 0x67a47f77, 0xfa64e667, 0xdd346b7d, 0x8ee811bf, 0xd91883ed, 0xbec10fef,
- 0xc7e902e2, 0xafe60cb9, 0x801db708, 0x28515173, 0xac085ad9, 0x23ee18f3,
- 0x31c19cb6, 0x79953d70, 0x0ab3d6c1, 0x618b89e7, 0x378d12f3, 0xe713e61d,
- 0xd64d4e2b, 0xff7f4292, 0xfa578e26, 0x4efd87bb, 0xfcf239fa, 0x6de256eb,
- 0x75c259ab, 0x55a7a107, 0x53dacf80, 0xa7a30f1e, 0x93d00d4e, 0x8fa0bf58,
- 0xc6693657, 0x56e39e07, 0x6bc70eb3, 0x1d706b35, 0xa27e00cf, 0xe765a968,
- 0x065599f2, 0x198ff237, 0xf9488f63, 0xebf72f14, 0xabbe503c, 0xed0b5f9a,
- 0xf9b326ef, 0x0f54aad7, 0xa3ed7d40, 0xf882d246, 0xf0093fb4, 0x123d303c,
- 0xa55b52f1, 0x38e9eb73, 0xb126bf4f, 0x26e8cbba, 0xceb59ff4, 0x1fa10ba9,
- 0xbdb30d89, 0x1e737804, 0xf5334dd2, 0x3d2b27a5, 0xfbfa56f6, 0xce763684,
- 0xdb6a1e04, 0xdd015d18, 0x5c39bc23, 0xcb74f0fd, 0xc7c08dce, 0xa333289a,
- 0x00274a07, 0x616d9aef, 0x3606b3e6, 0xe804b7d7, 0x37ab22d2, 0xcf9927b4,
- 0x35ebf8e6, 0x83a00ff0, 0x8648c4ed, 0x75f075d2, 0xee72a1be, 0x19d43c02,
- 0x14b587bc, 0xfa4f43b5, 0xa2875cf0, 0x5fa69adb, 0x843b380d, 0x47896590,
- 0x55e714b0, 0x47ed8fdb, 0xc70eff7c, 0xd250cbfb, 0xba730ff1, 0xc36a29a9,
- 0xb67358f3, 0x71b1cf11, 0xc667e33c, 0x4d7e7253, 0xbf7c13c8, 0x8a9c71eb,
- 0x6ab1b688, 0x9f8af70a, 0x1216e64a, 0x912e5f9a, 0x8e8da388, 0x83a6c5f7,
- 0xbe00f391, 0xe355bf57, 0x7ed8c37e, 0xd0fe704f, 0x1c028db5, 0x4751bde9,
- 0x46f7ec82, 0xe39e23c7, 0x86bde012, 0x7b6bbec3, 0x513f88f9, 0x8b6d717a,
- 0xbdff01b2, 0xc3ca7db8, 0xeeeba27f, 0x53625ada, 0x38b4d903, 0x717c7e90,
- 0x942db661, 0x64d5627e, 0xbef144bc, 0xe460edaa, 0xcbefda48, 0xd42e0c5f,
- 0x7cdd7ed3, 0x535e179d, 0x1e5c0137, 0x9dc7657d, 0x96e35ed0, 0x778f8062,
- 0x3fe9fb6d, 0x6f57cf81, 0x9308006d, 0xa3bc5f96, 0x54efd2f3, 0xf7eccdee,
- 0xf866516d, 0x9f17cbee, 0xdde013bc, 0xed82d6d2, 0x8cdc5e17, 0xecaf03f5,
- 0xe9bffb78, 0x488eb577, 0xe1777c1b, 0x9788fdb5, 0x0ec6a75a, 0xd7450dfb,
- 0xcfdceccf, 0x849b64f8, 0x31548de7, 0x5ae825fe, 0xaf97efd0, 0x28111dcc,
- 0x8ed56a1f, 0x4fbe0954, 0x925edbd0, 0x9ca05e50, 0x688c3778, 0xdffee8c2,
- 0x9681a5a3, 0xfbe5ea15, 0x2ce780b5, 0xd908cfc6, 0xa7b5e42c, 0x6f7efe84,
- 0x75e6c449, 0x3eaeee70, 0x26e78d98, 0x1d1dd182, 0x31c7c0c7, 0x434438c0,
- 0x0fbeb0ec, 0xb2db6fd3, 0xa547ce8e, 0x924efb34, 0x47779c70, 0xce05bedf,
- 0x8c2f58bd, 0xda0f3937, 0x9e41532b, 0xf2d7df88, 0x670dae75, 0xe722edf2,
- 0xc6653537, 0x7c5e50b5, 0xf00aac35, 0x0ef3af53, 0x72fc00b0, 0x5b471d19,
- 0x6daebf18, 0x37adae5b, 0xe71c7f62, 0xa0a7ca13, 0xe9e7a3cc, 0xf49f3d1c,
- 0x0edfadab, 0xc97ef981, 0x193864f8, 0x3e98fb0e, 0xf0048ceb, 0xd46dc88b,
- 0x7f5c20d6, 0x9629dac1, 0xae87db02, 0x4947e760, 0x2316b9b7, 0xb73b1b87,
- 0x532bbbc9, 0xf4b7c8ad, 0xfa01feb6, 0xb3b57253, 0xbf7f44c5, 0xa6d3857b,
- 0xe6f774a6, 0x536363f9, 0x1c95fd68, 0xabd20869, 0xd8f2625a, 0xea79c465,
- 0xe7c8ca9a, 0x2d23bd74, 0x9bc75cec, 0x428ee689, 0x342a9e3f, 0xf8446344,
- 0xd5af90fb, 0x7af2e5ad, 0x31275b2b, 0x98a7d2f8, 0x8ef19fb0, 0x683aff68,
- 0xeb11a33f, 0xf2fbf4be, 0xaaba3e40, 0x755a3e50, 0x820bdeb8, 0xfe57117f,
- 0x7f3f3cec, 0x139b7aa0, 0x475e35e8, 0x8fe3234b, 0xfbfc7495, 0x9695a52c,
- 0x1f197f38, 0x7095dace, 0x74ed0f5a, 0x762dd79c, 0x8b6c8efc, 0x50afc991,
- 0xe39eb07c, 0xbbc919ff, 0xb5cce818, 0x740ccc37, 0x77a77f5d, 0x5c1f2040,
- 0xb07c616b, 0xf74dd39b, 0xef2f465e, 0xd82e54aa, 0x6e5bbbdf, 0xa8740cdf,
- 0xff03c794, 0x8695762b, 0x2edc9b8e, 0xc92f0199, 0xf0cb269b, 0x55baf547,
- 0xe5d657a0, 0x5f814348, 0x7fcbed48, 0xd7ad1b75, 0xbd41bc53, 0x9f3f377e,
- 0xef854f54, 0x172bdbeb, 0xb1297cc2, 0x12d4d977, 0x536347ea, 0x96bebd68,
- 0x7ff9c314, 0x37becd26, 0x9121f705, 0x4f20ac97, 0xf20d5ea9, 0xf50f2e34,
- 0x56e77af1, 0x8e49bfd4, 0x85bdcb8e, 0x27d7afa8, 0xf9c1b4ce, 0xf627c3ea,
- 0xaf7d42ae, 0x0b6e1ade, 0x684fdfa3, 0xfa601e97, 0xf5b0918e, 0x4fa87648,
- 0xc3748f70, 0xf8092e7a, 0x39db5288, 0xdeefe607, 0xda2e27a3, 0x71dedefe,
- 0xbd05cf28, 0xa3d75e98, 0x98d68f5c, 0x2fcbd025, 0xe7c9db36, 0x65982554,
- 0x05bc22b1, 0x67b66b3c, 0x5c9ce0aa, 0x9ff0ede2, 0x43cb9e35, 0x42dd69fa,
- 0x2d67d20f, 0xf563dbd7, 0x030782f6, 0x28f427f0, 0x82fc1d25, 0xa6f27fd3,
- 0x621c1243, 0xaeee7e25, 0xba069e26, 0xa937bbbe, 0xa8f9253c, 0x7c8fdd5f,
- 0x6c8e957f, 0xb78efa91, 0x8a8bf383, 0xf0014718, 0x46e98ac9, 0xaa7f205b,
- 0xc2abb708, 0x423cf402, 0xfa2a451c, 0x1378f9dd, 0xd875ffc2, 0xacbd1077,
- 0x63967fb7, 0x22bbc02b, 0xa7ed0c21, 0xf95d5a7b, 0x5d6d1fa4, 0xe7055e15,
- 0x2363f292, 0xed334df2, 0xdf8bbf4f, 0xe445f232, 0xd705a4b3, 0x6662d9b5,
- 0x8a38c4e3, 0x64b5811a, 0x39305639, 0xdb05b266, 0x3f7c7dcf, 0x29cfa607,
- 0x4c9d0150, 0xf4f4da35, 0x92dfa7bb, 0xb8dd23e6, 0xf384c0a8, 0xec715ce2,
- 0xd8af662e, 0x5388ee80, 0x7d56fa83, 0x9c1dc3a3, 0xd71d18ae, 0xf40bfd53,
- 0x88574a70, 0x2676fab7, 0xddb8227f, 0x50227c07, 0x4ae715df, 0xd7e05b9c,
- 0xde823740, 0xd1bdb9c4, 0xcfcdd9f3, 0x7fdd3747, 0xde9a7d20, 0x6eb97464,
- 0xda14b595, 0x731055d7, 0xb4aabda0, 0xf870ac83, 0x62fadd68, 0x11c61b84,
- 0xe2ce2e7c, 0xa8fc0b38, 0x35d1cb7e, 0x2f9cb648, 0xf8f9bfd5, 0x67e96b80,
- 0xcf1b0d06, 0x07708ee0, 0x82818fd2, 0xa58854db, 0x4473f80b, 0x12df5c93,
- 0xdcb93fe5, 0x65facef8, 0x7c01a4ae, 0xa8f2fd09, 0x0b4ff9ca, 0x45292fd7,
- 0xa626f490, 0xaf03c65f, 0x25b07e07, 0x24fc0dc2, 0x77389e3e, 0x97cf5905,
- 0xbc099cfc, 0x3e233b0a, 0x1c9f7d92, 0x5324f4cd, 0x8b2efb34, 0x0bf60197,
- 0xcaab079e, 0x43a88679, 0x8fd101cb, 0xc5db0bae, 0x1fed7a7a, 0xfc6f5b03,
- 0xacb603a3, 0xffa7c00b, 0x0856dd5c, 0xef5ace78, 0xfa37ccd1, 0x48f211e7,
- 0x7eb03f49, 0x9fb05b90, 0xdfd0dcca, 0x76e7eeb5, 0xcb9e829c, 0x633af9f8,
- 0xf2ddf821, 0x68eae718, 0x45159f5a, 0xff1431ec, 0x23d1deb3, 0xdf1c913d,
- 0x6b43b000, 0x8fa5c434, 0xdd6abc06, 0xfe3c00de, 0xfb40f00d, 0x2e0c98f5,
- 0x2d073d35, 0x68e2ce31, 0x8cab9e3a, 0xc7a03cd8, 0x0bf29f7e, 0x53c49738,
- 0x81a4fc0c, 0x8e012378, 0x239c982f, 0x757abbe0, 0xa9d43a67, 0xf30f931d,
- 0xecc11b3c, 0xb551df27, 0xc785207b, 0x47f78365, 0x2e7ae923, 0xb9b2c8af,
- 0xdfa738e8, 0xdf9efdfc, 0xed2fafd3, 0x19cd22f9, 0x0deb57c0, 0xc626832a,
- 0x4896ef5f, 0xbe105b55, 0xc99a233b, 0x09dbccd3, 0x68b804e9, 0xaeb7a87c,
- 0x8027b308, 0xbec567df, 0xe96b84d2, 0xca570df3, 0x9e603b88, 0xfa1fda06,
- 0x4b195c35, 0x8c8243dc, 0xf903c74b, 0x992570d0, 0x3cd862b8, 0x315437c0,
- 0xfbf8ce4c, 0xed1713a7, 0xaa455a7f, 0xe7fbad83, 0xbb5f0cd1, 0xac1f1909,
- 0xd7df077d, 0xfcec7eee, 0x6e4836fa, 0xaf160fb0, 0x14d47930, 0xcfe98ba4,
- 0x362d2fa0, 0x48aa3cbb, 0x8f943fe0, 0x4e34460d, 0x647b5035, 0xf467971e,
- 0xa028cd3b, 0xcf199757, 0xc39f93a1, 0x7defed79, 0xc589fe03, 0x4518621a,
- 0xb06f99c7, 0xbfa14e1d, 0x2638c9ff, 0xc2c4c412, 0x83c4a687, 0xd5984b1c,
- 0xbd2273a8, 0x7e83318d, 0xea51912a, 0xa5ae236f, 0x8f50690f, 0x74a27a45,
- 0xac718ba0, 0x3a00ba04, 0xf5983a04, 0xe26be320, 0x5e7e5cfb, 0x59f87495,
- 0x8ecf7c08, 0xf181cb29, 0x358e512c, 0x5e0fdf48, 0x6ebff192, 0xf3f2fbc9,
- 0x4dcba740, 0xdf4897b6, 0x70e13ffe, 0xd4e829ef, 0x2e5a2c91, 0xea3a47ff,
- 0x9def1da3, 0x675d3e04, 0xa0d47a30, 0x76d6ec57, 0x283ec579, 0xd945060e,
- 0xf073c29f, 0x739651c3, 0x02482694, 0xe3d71dfd, 0x03bf00dc, 0x0363db9d,
- 0x151adce9, 0xeba2740d, 0x10c38bc5, 0x490bc7ef, 0xd1f1c935, 0x31f11471,
- 0x01d760df, 0x1dd817dc, 0x5159beb8, 0x0cb3629e, 0x6feab9fe, 0xf871bf6f,
- 0xf9e7e7af, 0x61d28eb4, 0x83b07390, 0xc31543c3, 0x64e9c6f8, 0xd3a7af46,
- 0x282ef549, 0xf692d107, 0xd78fdd3b, 0x007d790b, 0xd59e2eff, 0x797e700f,
- 0xa77d9f3a, 0x3e33e79c, 0x7b18eccf, 0xf68bc007, 0x4f00e8f3, 0x41b9876f,
- 0xeafca64f, 0x8f13a700, 0x155f9025, 0x1f0006f9, 0xf8a629ec, 0x5759fba2,
- 0x013f4bea, 0xde9f64fc, 0x7d7ac5bc, 0xd7c27dbc, 0x97e59df5, 0xa1afca8d,
- 0x49f5f932, 0x885f9334, 0x1d12ba27, 0x11b2abd3, 0xea17483f, 0x5bcfc71b,
- 0xf4ee0c61, 0x51a3789c, 0x1cf2794e, 0xaffd7c01, 0x8f826e1c, 0xe3970e9c,
- 0xf7f7c5d1, 0xeb473f25, 0xde4ccda3, 0x30e97cd9, 0xe0e8e9ce, 0xc7ed5f78,
- 0x239e3747, 0x0c4e6fbd, 0xa8fbb7a5, 0x442ba0be, 0xf587ac7c, 0x734bb1f4,
- 0x73857f3d, 0x8980f0dc, 0x22bbdc80, 0xa1f22be6, 0x97ca937f, 0x4e8f0674,
- 0x87afd41d, 0x27d1f01f, 0xd4951a51, 0xd5a02274, 0x71c5621c, 0x9e3328c8,
- 0x3e5eb0b3, 0xf38989a2, 0xef3947c3, 0xc8af8e29, 0x0e734918, 0x36236af0,
- 0xa3e737e8, 0x29b34caf, 0x1b325c9d, 0xcf2a2a5c, 0xd19caaae, 0x79efe031,
- 0xbbea28f8, 0x019e74a7, 0xed20c6ad, 0xcf0bcf3a, 0xb9f6fe4a, 0x74bb533f,
- 0xeeef1cf4, 0x74c9faec, 0xa7677fba, 0xd8e706da, 0x1faff2b9, 0xa5bd030c,
- 0x4feb6b53, 0xd7aeae50, 0x991a3ec0, 0x254a767e, 0xefc5ff87, 0xc187edc9,
- 0x540f0c31, 0x133a409f, 0x5854e0fc, 0xeba13e64, 0xfd3c4259, 0x51e7ee81,
- 0xef4a17c3, 0x10f725f2, 0x181627ca, 0x7dfd22a7, 0xe85dc0f1, 0x9c485e6f,
- 0xb9e62fc8, 0xe40c7fb4, 0xcad60ba3, 0xe55a8beb, 0xc9cf25f5, 0xdffebdeb,
- 0x4effb972, 0x98635394, 0x0ba8ba5c, 0x863e3ede, 0x9777e3d1, 0xee5083c7,
- 0xf9c795f6, 0xe395a728, 0xaee5c3de, 0x1e42cb90, 0x84315c37, 0xe388c718,
- 0x7c1c5c5c, 0xf5f1f7fd, 0xa3315c37, 0x3fdbef7c, 0xd53ae516, 0x813bf0c4,
- 0x892b86cf, 0x0ba8bbf8, 0x2fdfd07d, 0x8ca3c715, 0xc22e7cdf, 0xdf85fe7f,
- 0x19efd057, 0xd0921889, 0xfb927b5e, 0xe0f9cc6b, 0xf2033a87, 0x39d9e29d,
- 0xa5edbc8e, 0x48f79c4b, 0x3f4d00d2, 0xf72b7d3f, 0x82e0e941, 0xd59f8037,
- 0x716298c6, 0x3064c1de, 0x73e82bcc, 0x5115c3ce, 0xb0ffdf20, 0x50213cb2,
- 0x6bf5eaff, 0x447d98e8, 0xaf265188, 0xcd9e4288, 0x2bf2a76b, 0x0188f51f,
- 0xef9f9740, 0xb9f4819b, 0x81e2d890, 0xe9f67b6e, 0xf7ffd1d3, 0x5898e51d,
- 0x3cd714cf, 0xa92fd32d, 0x65e7a090, 0x4a7f9f32, 0x5467d307, 0xf516bb06,
- 0x9ab13b15, 0x64a4d1e3, 0x130a96f2, 0x168fad0d, 0x5a1e2075, 0x2337c51f,
- 0xfeba7f41, 0xf324bcd1, 0x9e70899d, 0x1aaf30f4, 0x113b90d8, 0x361196ca,
- 0x9225942b, 0xc1d6c343, 0x34963cf0, 0x2af7c2a6, 0xf4cd5783, 0x7882ba25,
- 0x63e62fe8, 0xafaf1375, 0xce797a9e, 0x68ddf822, 0xe3af73c2, 0xf05578eb,
- 0xc031032f, 0xcf46f5be, 0xe24f1897, 0x8accaba5, 0x1faba876, 0x9c3fbb41,
- 0xd79811b4, 0x82e4bc68, 0x59899acd, 0xf9987a82, 0x0211e7b2, 0x52e8cd7c,
- 0xb6be460d, 0xf49af913, 0x7be062fe, 0x03e68f94, 0xaed90d1f, 0x2efea0f1,
- 0x5f3452f8, 0x4be70b5f, 0x21c18449, 0xbe71d886, 0x23169b1f, 0xae338a5f,
- 0x86ffa090, 0x97c8f1c8, 0xb4f001e2, 0x46bc663d, 0x1ce267c6, 0x95427af2,
- 0x94e49ebc, 0x14e40dd7, 0xe3c903ca, 0x0636fc48, 0xf01c91ed, 0xd8cb683b,
- 0xce1e99f9, 0xeb0dd5d6, 0x1139fba3, 0x937ffaa3, 0xbb7245fb, 0x475a3eb5,
- 0x4f150fd0, 0xa8c1e62d, 0x61889c07, 0x2e67c07a, 0x90fb5768, 0xfee09eff,
- 0x1de3a983, 0xdf8a1a15, 0x07c972fb, 0x8f9e5a76, 0xef869e73, 0xac691c67,
- 0xaaf5a5ab, 0x879e49f7, 0xe6250596, 0x9f14ed9a, 0x6c9b666b, 0x1afad28f,
- 0x576d2313, 0x22f51e9c, 0xb698f202, 0xa225566f, 0xfc01a3ff, 0x6bff74ad,
- 0x3a006f40, 0x5ed04fe8, 0x1ac87aa6, 0x79b7ed03, 0xcebcd99d, 0xdf2a7e0a,
- 0xfa07f058, 0x16f31116, 0x5c3ce412, 0xe28ce7a5, 0x53a845f5, 0xbe9c4a3c,
- 0xe15befc4, 0x2f562cf7, 0x1e760a19, 0x83ab2ffb, 0xcff02832, 0xfddce8e4,
- 0xa51d3d61, 0xcf5a38da, 0x7f43631a, 0x617ce131, 0x9f879898, 0x73fe91bb,
- 0xbc05ed80, 0x64f1dd9e, 0x978c3c45, 0xca7e504b, 0xd62c0dce, 0xca187f4c,
- 0x73c0edcc, 0xfff1077b, 0xfb95e307, 0x8dbc47c7, 0xceef6de1, 0x61d8f166,
- 0x387ecf1a, 0x597923d7, 0x8774cbc0, 0xa511fe54, 0xed8342d7, 0x802b1ee0,
- 0x7d86a1d4, 0xde3f350f, 0x708ff302, 0x7c03147c, 0xf281946c, 0x0cb65a03,
- 0x59ccd9b7, 0xf8156fb8, 0x42b5ba97, 0x40a3d91e, 0x92ad4dae, 0x7d00ff5c,
- 0xe11a8c60, 0xe53197f3, 0x7794d751, 0x3ab22a4d, 0xd6acce50, 0xf3f7fcc9,
- 0x65ff9963, 0xecd8ec5c, 0x2c079458, 0x962837de, 0xdba009f2, 0x7c03921c,
- 0xe71ce022, 0xa55d77c3, 0xce750ebf, 0x9cfcede5, 0xd10fb34f, 0xcfcb3ea2,
- 0x8eabe0bb, 0x669e7670, 0x74069210, 0x22349532, 0xba563dff, 0x7dfbcf14,
- 0x7805a5c4, 0xe0c65a7d, 0x653dd62c, 0x98af5cbc, 0xa7d790e6, 0x0ef52957,
- 0x7fbc7b3a, 0x794e19de, 0x3fa164fb, 0x8feb978e, 0x55cffeb3, 0x84b5ca0b,
- 0xcdbeeb97, 0x54f83f00, 0x03f81c6d, 0xfa33243b, 0x8c243bc1, 0x195434fb,
- 0x6c6fe0dc, 0x5bf16768, 0xefd05ab2, 0x7e80c7bc, 0x31da5653, 0xbedf571e,
- 0x80145a53, 0xb75a94af, 0x207cfc04, 0xc8275185, 0x9c77ae2f, 0x83f7bad0,
- 0x52c4fcbf, 0x9e74e24a, 0xe1df3c83, 0x143be410, 0x34cee9fa, 0x28fff987,
- 0x3c7fa315, 0x03611cd5, 0xaaad79bd, 0x6b85fd10, 0xbf324d23, 0xf655baee,
- 0xf84ef80a, 0xcafe4509, 0x6c693d74, 0x43a7fe63, 0xcc8d8cc8, 0x76e6e43f,
- 0xd32c7672, 0x6afb68cb, 0xce294ff4, 0x410c5c6d, 0x333711b9, 0x5580fd07,
- 0xe045051d, 0x07f2a587, 0xb1d9d3fd, 0xe55fec56, 0xd5ff402c, 0x1819c6dd,
- 0xd8e86817, 0xf46859ac, 0x82c3cfd3, 0x044822ee, 0x5faf5dd0, 0xfd1e9768,
- 0x8e555742, 0xd57d001f, 0x44f93cea, 0x7bf8974e, 0x84b2f928, 0xe65b5de3,
- 0xc288b198, 0x9d03e7a5, 0xaa3bec0d, 0x5ebe2040, 0xfe416bdb, 0x904c99a7,
- 0x252eafcf, 0x367b27c8, 0x17c8bf33, 0x687bea96, 0xb52d590b, 0x8eee1f22,
- 0x5ff08b1e, 0x7a843c66, 0x4a26f548, 0x7e7c014f, 0xbd7956d9, 0xb2fb3086,
- 0xba1f7b76, 0xf8247e44, 0x796efd55, 0xe4cd923f, 0xb9c38db7, 0x42d1f380,
- 0x054a6d87, 0x96cabd2c, 0x6244ecc5, 0xfc5e3e07, 0x0bfb8ebe, 0x85cf9967,
- 0x597b8b01, 0xd41e96ba, 0x66af3a63, 0xcdf198e7, 0x928f3e62, 0xfd73179f,
- 0x9d0d4ee7, 0xcfafd0a7, 0x3f561314, 0x2750eaa4, 0x2debfcaa, 0x1e84fde2,
- 0xc0a9f825, 0x4270e957, 0x3b3a5386, 0x8fddf020, 0xd37c03f4, 0x25ce91f1,
- 0xc68954c8, 0xef605df1, 0x51f3e48c, 0x5d01707a, 0x370654b9, 0xa91aefd0,
- 0x0188e511, 0xae5a65f4, 0x57c89c93, 0xa976a8df, 0x4823de01, 0x327b94e3,
- 0x4676bf81, 0x9d289c00, 0x9fa40e1c, 0xdf49e216, 0x08e8c929, 0xbf2cbbdb,
- 0x82474a0e, 0x653e7bef, 0xba04c0fa, 0x02a71863, 0x3cb40902, 0x3a412d24,
- 0x5a7c6719, 0xad7ffd03, 0x78d3f662, 0xfac0d6e2, 0xfc72cc2a, 0xd7944b8f,
- 0xa1f6b2ef, 0xdbff8c0f, 0xe4273c39, 0x82eddbc8, 0xdf39116f, 0x995724ca,
- 0xe1f8fb7d, 0x8eaec087, 0x10392268, 0x9d1aa3df, 0xf8907fad, 0x2dec4f49,
- 0xc4f7c3f7, 0xf7c3f106, 0xafbeb968, 0xc3faafa0, 0x27ace617, 0xe7143a7e,
- 0xa8d20ee1, 0x9370a44e, 0x8ef161de, 0x28fe803b, 0x90370c3d, 0x486fd05c,
- 0x8973f311, 0x6de821f3, 0xc545af28, 0x20cafa71, 0xa35f4019, 0xbfd0c3db,
- 0x19d00779, 0x3e02dba5, 0x42df90ae, 0xde196f2f, 0xa532ae87, 0x78e3942c,
- 0x1f1c84de, 0x7f9ed922, 0x72f41324, 0x01e5ea17, 0x87131474, 0x11d288fc,
- 0x723ecf9e, 0xa0aede52, 0xe3ef8133, 0x252cdf5c, 0x535f488d, 0x3d2c5655,
- 0x2f4ecc95, 0x40d54e37, 0x3326f7ff, 0x74031b3a, 0xcbdf0598, 0x20dca4e9,
- 0x90e92baf, 0x9c0aa8ce, 0xa1974957, 0xe8032ce8, 0x98c7c84c, 0xa8d9d3eb,
- 0x674e5bb8, 0x826ee2a3, 0xdadf04ce, 0x372e6619, 0x96aedc82, 0xf90c0e50,
- 0xea05bb20, 0x5132eb03, 0xb169dccf, 0x46f6c41d, 0x69d45ed6, 0x42de4357,
- 0x9ede0ad6, 0x7a8728e9, 0xa76d1343, 0x671f1743, 0x2bd90d79, 0xa3c17b59,
- 0xe04d078d, 0xfeb172c7, 0x46b97e6f, 0xdddb491d, 0xd2ff786b, 0x37a872d6,
- 0xbffd65ac, 0x60c87880, 0xb77287c8, 0xadb7efc0, 0xb331b4cf, 0x25b7e994,
- 0xa53bbf7c, 0x5fb1075d, 0xe4b7eb2b, 0xa09c21b0, 0xd6f4ccfd, 0x4b3ef93b,
- 0xc67db136, 0x78f77e7e, 0x458ba52b, 0x5fea173e, 0x43b554e7, 0xb085af91,
- 0xd6a54b3f, 0x51c72854, 0xdda50bb6, 0xeeab5b60, 0x5b61e2c7, 0x714d14e8,
- 0xe2217fcc, 0xaeaf1048, 0x9a67d00c, 0x245d98e2, 0x268f8bbe, 0x8d911fa8,
- 0x4437b426, 0x2cf3cb9c, 0x850ec091, 0x50bf423d, 0x5971af71, 0x8c2fa88d,
- 0x2ef110cb, 0x9d3e66af, 0xafdbe0b7, 0xaff306c6, 0x3d31c734, 0xbf8f3ce5,
- 0xddabdf8b, 0x13bf2e2c, 0xe0192488, 0x7057f87a, 0x3c42775e, 0x1727098b,
- 0x65780e19, 0x727e27f5, 0x6a5add60, 0x35512fbc, 0xcc205c6a, 0x23cc25d2,
- 0x3c49d49a, 0xd77d9151, 0x3c434e3f, 0x8407963a, 0xa2dc5feb, 0xc2203cc3,
- 0xc134d9f9, 0xc7f5469e, 0xe3953df3, 0x4fe0a369, 0xe010c843, 0xde38d34f,
- 0x3d5033ee, 0xab72e518, 0x5e37c156, 0x21b1be40, 0x6f2dfea4, 0x6a95f057,
- 0xae62ef3e, 0x3e252f77, 0x49ce4bd4, 0x6fcf2c6e, 0x8d777a60, 0x35ea38f1,
- 0x9e991b3d, 0xa8bc4b59, 0xcb752cf7, 0x36cd42f9, 0x4daebd79, 0x97686f5e,
- 0x5cf27bd7, 0x86cf4f38, 0x4fe0a1ba, 0x03ee7eab, 0x0b56dff4, 0xf396e2fe,
- 0x32564217, 0x20ecf2fe, 0xed28e7f4, 0xeef76a70, 0xa1f8c38b, 0xe82d6679,
- 0x58227305, 0x98da82be, 0x64c07c87, 0x14383b40, 0x39da501f, 0x8320ef42,
- 0x2a0f9f82, 0xcf000c69, 0xc6777800, 0x921edb5d, 0x21f02bb7, 0x39fb91ec,
- 0x7c50a63e, 0x93bf3cc3, 0x1cf768ec, 0x31f0ca5b, 0xe902b8cd, 0x0c65d3e1,
- 0xba2ec21f, 0xaec83b79, 0x90762efe, 0xce2e5fd2, 0xb09a7755, 0x8768ad4f,
- 0x29800036, 0xf37bae9f, 0x9fa00bc4, 0x358eef8a, 0xc04d3893, 0x2a563c79,
- 0x9e4e8ff7, 0xe4287a70, 0x2b0f6e3b, 0x93e00bfb, 0xffa1c474, 0xd8412eb0,
- 0xe9fc6c45, 0xf2eaff3c, 0xe8a8ccca, 0x89bdd96b, 0x009a619d, 0xc68f6cff,
- 0x4e760917, 0xe70955cf, 0x4825ba85, 0xffdfc91c, 0x87c41878, 0xf9dfcefb,
- 0x3f03dfbd, 0xe302217b, 0x3257977f, 0xa6f2ef7b, 0x7c079881, 0x0549c791,
- 0xde1c961c, 0xce17b6f6, 0x1c31d35b, 0x7f7246af, 0x1db687bd, 0xe2633bd5,
- 0x3caa0e41, 0x2c57463a, 0x1df6219e, 0x42e96fda, 0xc03ba6fe, 0x0a4face4,
- 0xfa4ebcc7, 0xb8c080fb, 0xe302524e, 0x7e0e42c3, 0x2d6afdcc, 0x17d8a5bd,
- 0xc4b42bf3, 0x3d60b3d8, 0xc1bac31f, 0x1691f43f, 0xbbf835f9, 0xa548ce21,
- 0xee89492e, 0xa3881ebb, 0x3881bd6f, 0xc99e2dba, 0xf694a583, 0x62cd3f30,
- 0xcef9802f, 0x79e1b8f3, 0x1f3a771e, 0x2350e2c9, 0x5f1f19e3, 0xe44dfbca,
- 0xf110f9e5, 0xd9ddf16e, 0x35618366, 0x9b1feb5d, 0x36756189, 0xf567f125,
- 0x339f988d, 0x67abed8b, 0x39f305af, 0xf8aabf45, 0x8eb0a5d2, 0x18c71621,
- 0x9eb61728, 0xa9fa05d1, 0xa83f607b, 0xf57db04f, 0xcc52b184, 0xb95f1557,
- 0x3ce01e34, 0xec788bc3, 0x75108fad, 0x33df8e07, 0xc24ff19a, 0xfc7510fd,
- 0x5b8a85fc, 0xa55e2f5d, 0xe6cefb8c, 0xefb889e3, 0x9914362c, 0x73bee3cd,
- 0x0a4d640c, 0x91db9f6d, 0x48d5ecc0, 0xdc5900d7, 0x537115d7, 0x87417771,
- 0xb8fe693d, 0x889bc6e9, 0xfe20fe9b, 0x7f4dc796, 0x6e241f10, 0xbfa78caa,
- 0xb6417a0e, 0x980f0f1f, 0xd42adc19, 0xcfe0e5b5, 0x6090bcbc, 0xe901731e,
- 0xd028ecf7, 0x89688eb3, 0x137c8adb, 0xe1ebe3f5, 0x22a1ce2d, 0x39df9956,
- 0xd603589c, 0x968ce49f, 0x0ee351d5, 0xa94c0fc8, 0x4ff5964e, 0xfb27ec6b,
- 0x9069a33e, 0x55d33dac, 0xad67ab28, 0x7df643bd, 0x5932d6ff, 0x7773e07d,
- 0xcdbfbecb, 0xbf56593d, 0x7e40ff0c, 0x767e46a6, 0x65fbb6fb, 0x1d1c97fd,
- 0xddca7e82, 0x9712fe5c, 0x287733bd, 0xfac0a373, 0xcbe6daf3, 0xc91e23c6,
- 0x45f6d123, 0x23174f1c, 0x85893dd9, 0x3f9fcc9d, 0x6c997db8, 0x2d751afc,
- 0x47194fe2, 0xc3be242c, 0x96ea3f98, 0x37d21e6c, 0x7db4b8ae, 0x9ebbf633,
- 0xfafc227e, 0xb14de207, 0x24c91748, 0x92b3d199, 0x70bd8c1e, 0x05197b80,
- 0xa3b3c064, 0x20f4648a, 0x1b851bc3, 0x6f2ea9fa, 0xd1de6137, 0x700ba392,
- 0x3944fa3d, 0xe559843d, 0x239110f4, 0x4d9307a7, 0xe1a8ff8e, 0xe12bfc72,
- 0xe9cbb16d, 0xffe97881, 0xcc7780d7, 0xfcbd3978, 0x1ddce0ab, 0x1c81e3cf,
- 0xd90e43be, 0x37088c5b, 0xec243f96, 0xa3b73d7b, 0xcfdcac49, 0x7fa7f425,
- 0x1578f3c6, 0xd5f8471f, 0xb42e48d7, 0x66e37bcb, 0x9ee93dc3, 0x1bcfb04c,
- 0x38f3f309, 0x41c50954, 0x7bf884fd, 0x80a13f28, 0x67ae54eb, 0xfa3b10d6,
- 0xfc4117a5, 0x2b67969b, 0x677fa297, 0x1d69f189, 0x9938bff4, 0xc4d563e9,
- 0x7afdfc8d, 0xdc256ff1, 0x01252f40, 0x1c25547e, 0x63c90ea5, 0xe5c33e02,
- 0x10e93240, 0xf2c9c072, 0x12fee5f8, 0x00b2f102, 0x5ef4253e, 0x9f80be31,
- 0x7c625fe0, 0xe059f83d, 0x19f8281c, 0x45e391c9, 0x63815fe9, 0x181a1860,
- 0xc092b12f, 0xafd28af8, 0x50a7f7e2, 0xa7ce92bb, 0x216cc8ce, 0xcc436f14,
- 0x15d7f476, 0xf099ce93, 0xa0a7f0bb, 0xd236e17f, 0x29085feb, 0x8f13ae9f,
- 0xbc92e29d, 0x8df667cf, 0x2eb88ac3, 0xbfe7c305, 0x49479da7, 0xe4f7c456,
- 0x01c60737, 0x2ff5f51d, 0x45be4eda, 0x7cab51c7, 0x3f7e8131, 0x4f7f5fe1,
- 0xee7ee2f2, 0x48c7f623, 0x4f519e80, 0xcccec6da, 0x952eff04, 0x3250918b,
- 0x5769143f, 0xf41ad9ea, 0x4ee8aaff, 0x486bde80, 0xd3329c40, 0x75758edf,
- 0xe68dfadf, 0xc13afcbb, 0x2cbd9dcc, 0xfe70935f, 0xd0c3ec27, 0x7d7c98f6,
- 0x330b8c0b, 0x82fbfa25, 0xc0dc75c0, 0x037e453a, 0x7884e3dc, 0x9f2a26c6,
- 0xb04bcf51, 0x17515ea2, 0x3b13ea7e, 0x99d4567c, 0x36d7a81e, 0x0301a8e8,
- 0x7aebf8f6, 0x936c9716, 0x4c3fcbeb, 0xa12ef960, 0xa8f3c0e1, 0xf5cc7614,
- 0x47911df4, 0x16e01135, 0x944b3eb0, 0x9f803fe3, 0x9ef49da4, 0xfefe5493,
- 0xcc2eea15, 0xaedcbc13, 0xf54efbc6, 0x1fc85da3, 0xf1aaf7ea, 0xe8777508,
- 0x756f3ef1, 0x93d441fb, 0x03299aba, 0x85c97aa2, 0xe6b33a66, 0xec57f01a,
- 0x207d9437, 0x4c5e8df2, 0x9f33fce0, 0x2be607e4, 0x8af83e51, 0xdaf60f8c,
- 0x4a79bdad, 0x93e304af, 0x28dcea15, 0x9bdae7b8, 0xa5f1a287, 0x8fc00e4f,
- 0x720f1f72, 0x1a37e43b, 0x5d025b47, 0xd4ce99d7, 0x0abc6067, 0x64e1c775,
- 0xc90acf80, 0x12b47106, 0xa87fbb3d, 0x35b72f57, 0x0375d806, 0x203b521f,
- 0xc57a795e, 0xbf70d183, 0x503b8c59, 0x393de152, 0xf67d7642, 0x9f8822fd,
- 0xa3adb2cd, 0x667ad9b5, 0x2f7e6657, 0xcf4593c2, 0x763a3bd7, 0xafdb4b3f,
- 0x7dfef311, 0xe3fa3516, 0x0c64d562, 0xaf5885d0, 0x7e2857b8, 0x70cefb87,
- 0x5efc4d7f, 0xf21be2d2, 0x071f2d00, 0xaff62cfa, 0x37dca4af, 0x87e8d1a4,
- 0x6e9c7d7b, 0xdd45e80d, 0x443f2606, 0x6b31159e, 0x30ad7cf0, 0xaa75f3b0,
- 0x3d9bb0bf, 0xeabfb026, 0x9851ecc3, 0x9a91f5e7, 0x17f95d80, 0x82ca3db3,
- 0xdea2b3fb, 0xfaccc2b9, 0xde7cf375, 0xa1969f15, 0x12d7165d, 0x7ce8cf3c,
- 0x6a9fb302, 0x7964a8af, 0x0f1ab546, 0x5ed50be6, 0x913e61d1, 0x148ffdf8,
- 0xfe01ae0e, 0xd9f3fcfa, 0x0b5d6163, 0x7c0d6d88, 0x046d60bf, 0x21e80571,
- 0x8958af22, 0x7c71efff, 0x44345bd7, 0xe7ef1833, 0xddf5ae3a, 0x0754ff5b,
- 0x9d12efbd, 0x5c71cec8, 0xa5ebcb39, 0xe1c60576, 0x2585df94, 0x6cfc8a4a,
- 0xecafde2f, 0x5bdb07cd, 0x61ae409a, 0xb15fd7e7, 0xebb3f2cb, 0x57e87f69,
- 0x228c657f, 0x4b8f9b3f, 0xfd1ab3c7, 0xe0a16079, 0x6604bdff, 0x9e43d4df,
- 0xdfc090d7, 0xe7f8fd19, 0x5b79e589, 0x7f3848de, 0xe3576f3f, 0x1f9fe3fd,
- 0x12df8d51, 0x12c3dd64, 0xc506dc19, 0xdc5cf069, 0xcdf621ee, 0xdf17e641,
- 0xe205fb89, 0x7d729c7e, 0x73bccbbb, 0xc6c3fd60, 0x72aeff30, 0xec89419c,
- 0xddeeb13b, 0xf51f0cd1, 0x607c536f, 0x9fcb08fe, 0x5ded1ddd, 0x2cc0fc8c,
- 0x8e7cf3c7, 0x7b77dde7, 0xcbbef1d3, 0x0e7ecc5d, 0xcd570f45, 0x4f8007ce,
- 0x42374ed4, 0xaa19192e, 0x01cc9469, 0xf47aebe7, 0x4abb87e0, 0x70bed786,
- 0xc57e21d7, 0xffdf42b8, 0xc63539f2, 0xc63cbff1, 0x1bb12dcf, 0xf77c80a5,
- 0xebf3092f, 0xa12ad97f, 0x49df3f9e, 0x2fe51348, 0xa0d6b6f3, 0xa5f8b85e,
- 0x03629821, 0x7ca4afbf, 0x21225e64, 0xfe72d277, 0x775c796a, 0x7e3efae1,
- 0x7f281239, 0x94469117, 0x969f8b17, 0xeb26abf7, 0x837a0cff, 0x3e8cde32,
- 0xcf176a4f, 0xf77ae44e, 0xf8143250, 0x7d2f03fd, 0x86b48ba5, 0x94f3ffa6,
- 0x806b669f, 0xecb01aaf, 0xb963366a, 0x28bed13c, 0x39a5c291, 0x089d59d1,
- 0x188f8cfe, 0x5ed72e3c, 0x2e00f266, 0x7e008e4f, 0xd33ca12d, 0xd8f164cf,
- 0x723dc21f, 0x9ebd0f0a, 0xd47575c9, 0x7093c9ca, 0xff846e95, 0x8e79af30,
- 0x2d8de505, 0xf63de811, 0x63c6e317, 0x222fd75e, 0x75bf00ec, 0xc197eea5,
- 0x556eb08f, 0x0d71fa38, 0xce0f167a, 0x82aa5eda, 0xedb703fb, 0x1f83f696,
- 0x5563a1a3, 0x37efdc0e, 0x8f31c35a, 0x5e63aa20, 0x6c639326, 0xc716d89e,
- 0x2c67c04e, 0xeba36bdc, 0x4ee9975a, 0xe99a7c64, 0xf61cf539, 0x3ff5923d,
- 0xebb39ee1, 0x21ef1aa8, 0xbcb0d65e, 0xe18441fa, 0xc12be455, 0x5cfa81dc,
- 0x241b8517, 0x939ef5d5, 0x8da3c936, 0x301c77c4, 0xa8fb50ce, 0xc8267e27,
- 0x30699f9b, 0xaebbd34e, 0x20ca9277, 0xcce4231e, 0xfcccc94c, 0x9d5f5c42,
- 0x2c7fc441, 0xe9c5539e, 0x53d70661, 0xf8304667, 0x74b627ce, 0x81bf77e8,
- 0xd1e8aa44, 0x56de5999, 0xd1abfb8c, 0x116f405a, 0x7ad08971, 0x4e7f7042,
- 0x7626cbfd, 0x0df2521f, 0x682e4180, 0x79d6b909, 0x43f9c3db, 0x97e600fd,
- 0x0ec4d925, 0xb7fab071, 0xf8866e07, 0xc59c3e87, 0x321f2959, 0xef277bc0,
- 0xfba63c82, 0x1856fa5e, 0xdc42bf7b, 0x0bdb3687, 0xc3617ee0, 0xcc42d4e4,
- 0xc3e9385f, 0xb5ba0877, 0xaf3c74de, 0x5448bf94, 0x38987e06, 0xa50d1eef,
- 0xaa64faf3, 0x3ffad16f, 0xbd581b12, 0x8ab1779f, 0x3d2407d6, 0xbc83eace,
- 0x4b6ea0e7, 0x0d1efa7a, 0xf42b63dc, 0xfad3562e, 0xac2da484, 0x324b060e,
- 0xcfd26f85, 0xf1d171ee, 0x3eb8582f, 0x3de2f363, 0x0737fad0, 0x84fd02aa,
- 0x7f189263, 0xbec610ba, 0xe64990bb, 0xe778064e, 0x873eff04, 0x5cf42f7f,
- 0x9fd15fb1, 0xf7ef0624, 0x4b7b9719, 0x92d03df9, 0x8c36b208, 0x915c95c5,
- 0x3a870f14, 0xec5c6206, 0xcb346240, 0xf17b35df, 0x8e31109d, 0x4f18a780,
- 0xe40cbbcc, 0xc9f311b0, 0xe2f964aa, 0x79d27e5c, 0xd93ce356, 0x727f7676,
- 0xe0016a72, 0xc34de28f, 0xbc01a6f1, 0x30d77b89, 0xf91f25ae, 0x43f010fd,
- 0xbf4aba1f, 0x5baff4cf, 0x38572749, 0x616d2c9d, 0x259f40f1, 0x24a9e90b,
- 0x513bbf82, 0x04c7df24, 0x4931bf0e, 0x5ecfb616, 0x384824bc, 0x63870b4f,
- 0xe4c077aa, 0x77df9bbc, 0xcf5b1278, 0x0077dead, 0x7ef0ecbe, 0xdbf6a1c4,
- 0x30fdb0b6, 0x473d017c, 0xa4f75ea3, 0xab0bbc6c, 0xd387fd14, 0x8dfb0903,
- 0x3ffec2ce, 0x100defe4, 0x5fb7a5b2, 0x3fd33e66, 0xf7152f41, 0x4eeb89e4,
- 0xed17e812, 0xc6df0fbd, 0xf7faadee, 0xdf114f79, 0xd3ef99a7, 0x96e9f6cc,
- 0xee392bd1, 0xea6a9f4b, 0xf0bdc74b, 0xb72f1def, 0x3b278f90, 0x83c6c1e7,
- 0x2f0a1d73, 0x316e93a3, 0x2a758a3d, 0x670bd9e0, 0x3c04fac5, 0xbf637ce1,
- 0x8a5d395c, 0x9d42da75, 0x38efccef, 0x57eb295f, 0xbfcb30f7, 0x5d395625,
- 0x54ceedd7, 0xf45bdc41, 0xee3e0a3b, 0xcb5fbf38, 0x98e3c499, 0x443524a9,
- 0xa4c2dcde, 0x30fea0b8, 0xe7695dfc, 0x3e5858f5, 0xefded2b2, 0xc275b389,
- 0x25d7343d, 0xa47a7f76, 0x71013fc2, 0x7f465d92, 0x917cbf3f, 0xf87177d7,
- 0xf8aff5f5, 0x91677ef0, 0xab35ecbe, 0x9bff908d, 0xebf20ef4, 0x07b2a8a2,
- 0xf57d6933, 0xdfc8fd86, 0xbeca528b, 0x7cfca4ca, 0xac0386cd, 0xafb2f6fd,
- 0xe93d41fa, 0xd897ab20, 0x4f7e035f, 0xc67bc1c8, 0x88f5f924, 0x7159261f,
- 0x0ab9755e, 0xd5eadfdf, 0xa3d1de5f, 0x1ae022fe, 0xabd22caa, 0x9fc5831a,
- 0x81e97b5a, 0xc38609c5, 0xa790ad3f, 0xaf78edc4, 0xf7c76646, 0xaffbb244,
- 0x86fefb3d, 0x4f9e19f7, 0xf004fe72, 0x35d110d0, 0x1fd69327, 0xe30cf88d,
- 0xea9d9250, 0xb0c7e021, 0xba2cc99a, 0x9d6ba95e, 0xb225f403, 0x20d066cc,
- 0x075fb95c, 0xf0a2f4de, 0x9fedeb7b, 0xa6c2923d, 0x463ac071, 0xf0d03e70,
- 0x435f37f6, 0x82e1b2dc, 0xe1ea06d1, 0x0f0d8e88, 0xa235be82, 0x30dfd7e3,
- 0x5feecc39, 0x008f7588, 0x7dfd1dbf, 0xd71ebb78, 0xb6e3a23f, 0xc8fdf045,
- 0x016476df, 0xe53e8c9d, 0xd0b60169, 0x148defb3, 0x2fcdfdf9, 0x186f99ae,
- 0xe0248e32, 0x54aa27f1, 0xde3c2145, 0x8ab8f060, 0x71dd51f9, 0xd178d6c7,
- 0xdfbf27b9, 0x8c76f542, 0xe1265e83, 0x8bd3f036, 0x7f4ac57b, 0xba4ac9e0,
- 0x68fbfa3f, 0x80415d1f, 0x85725cde, 0x7a01ffda, 0xc8b12978, 0x2486e5ea,
- 0xe615f7d9, 0xb8fb594c, 0xed64dbc4, 0x640b5977, 0x233909f5, 0xb44fdf64,
- 0xf7eaca95, 0xf64bbf0e, 0x52bda57d, 0xb4f02f56, 0x721fbec9, 0x7ede5da4,
- 0x0f01a89c, 0x076d2785, 0x6b3e2ca1, 0xd0e2b747, 0xa1078df3, 0x0617f11c,
- 0xf43fa50e, 0x076d2b8e, 0x0fe177e1, 0x1157de55, 0x6ae9d1fe, 0xdc175ba3,
- 0xa1a89a0f, 0x8bc925e5, 0x62ad44fc, 0x305e55f7, 0x6f01bb39, 0x094abee2,
- 0x122943f8, 0x625ee62a, 0x3167b2f7, 0x4049d87f, 0x19a7f00c, 0x9de3f426,
- 0xfabe36d4, 0x4ec7167b, 0xda37be03, 0x77db2557, 0x6ca715c9, 0xa964a5df,
- 0x65cb4f02, 0xc3f30af5, 0x25c7efb2, 0xdfb592ae, 0x815c7d65, 0xf56527a7,
- 0x0a0db689, 0xe0566d3c, 0x76b267e9, 0xdc1ddf41, 0xf836f53f, 0xca396895,
- 0x780e59db, 0x0fbcf3b8, 0xb3bc31f1, 0x74f01cb5, 0xc436c9c7, 0x51c79157,
- 0xe872ec0e, 0x5083c691, 0x05fda87a, 0x27340efd, 0xd9a87962, 0xc3a9fe8a,
- 0x1e5839cd, 0xefe1b669, 0x8e1e6abf, 0x76cdfbe5, 0x3cd37f2c, 0x66cecb1e,
- 0xcd6d9607, 0xaefdf86d, 0xdfe676e6, 0xd7bde98a, 0x807e069f, 0x1eb7956e,
- 0x27643eee, 0x7e044ec7, 0xedee1dd9, 0xaea3fa86, 0x2fc089e8, 0xa1130007,
- 0xcbcf9c78, 0x3df629b1, 0x0dbf94c9, 0x91756649, 0xb2a6d057, 0x5e1e8017,
- 0x09e331b2, 0x8f211a4d, 0x9a2472ad, 0xa06eac2d, 0xe6364475, 0x613c655b,
- 0x55e4254f, 0x60772510, 0x7bd4227d, 0x90fb58c2, 0x4113198d, 0xf1ceff0f,
- 0xbc9f7b60, 0x20e492c0, 0xcf57e0f1, 0xbfe04d5b, 0xa0757639, 0x8c71e009,
- 0xa4ecb1fb, 0x968f3b40, 0x2d029aa5, 0x0a93d9c8, 0x3d9444bd, 0xc9f1d2aa,
- 0xdb6fb071, 0xbe43cc34, 0x7e804b5b, 0xdecc4b27, 0x4ff5df15, 0x1317f9e1,
- 0x1d4f68f5, 0x6117d957, 0x7be493de, 0x64bce001, 0x7b8410e3, 0x0e97c98f,
- 0xb1b45bf0, 0x7ce3d590, 0x80b6482f, 0x67c196ba, 0x8982c6fa, 0x0a5bdcae,
- 0xe0c1059f, 0x666c9d53, 0x9ec7b6fa, 0xa8807a06, 0xd7b4af1f, 0x5e3e79c1,
- 0xa2fbc76a, 0x767a1cc7, 0xbc261d7e, 0xf63440e7, 0xfe0169e2, 0x5ac9b39c,
- 0x2e1537ec, 0xf35f819e, 0x739e357e, 0x29553c25, 0x3a470f4c, 0x46733b01,
- 0xc705da04, 0xb7deec55, 0x14ccfbf2, 0x0c5d1f66, 0xeb77ee0f, 0xa6cbdbc7,
- 0x87babdd4, 0x22b3d78e, 0x71ee870c, 0xac7d440c, 0x7bc251a7, 0x1be73db5,
- 0xbd76b12f, 0xe304838d, 0x5fe13392, 0x8ed5fdb4, 0x31faff07, 0x15b3fefd,
- 0x21943611, 0xbf0841e6, 0xb3c7f9fb, 0x3fa80c63, 0x569c9ecd, 0x26717206,
- 0x31cd738f, 0xdc31e269, 0xe0e8b1a5, 0xc685ba09, 0x82143582, 0xa56c7164,
- 0xa9cc9e0e, 0x06be5d4e, 0x4fd965ca, 0xf0ada2ea, 0x35ced77e, 0xd1d6c6a0,
- 0xfc8c5c23, 0x3341fbcf, 0x26dcd75d, 0x73d995b5, 0x6bdaae5c, 0x433f2a6e,
- 0x9e71efd0, 0x8081432f, 0x87166af6, 0xc597e8b7, 0x325b74e9, 0x91e4138f,
- 0xa7df763c, 0x1db00e37, 0xf66ba4e8, 0xc4420307, 0x5cede409, 0xc744fc7f,
- 0xbbbe55e6, 0x4ecde620, 0x71fe7a61, 0xd04ca51d, 0x7267ef27, 0xabeabf20,
- 0xfee98b47, 0x2acc3bf3, 0xadcfc38c, 0xb87803db, 0xa8f1cedc, 0x9e70ed25,
- 0x7de6b8a6, 0x8a4ab986, 0x93d79a7b, 0x734eb697, 0x2cbca079, 0x03ca3af2,
- 0x5f70e5e5, 0x45c8396b, 0x7c451f21, 0xcd5cd3d0, 0xf22372f9, 0x4dcd43d3,
- 0xecdc3f58, 0xf348f2c2, 0x5b97ce5a, 0xe6fdfdb1, 0x765f38e7, 0x0dbcbe73,
- 0xae68ef7f, 0x66edf2c2, 0x28969627, 0x7e016fc7, 0xcc4e0d53, 0x83777bef,
- 0xeb7c409e, 0xf31e8772, 0x7889e80e, 0xc858f9e1, 0xbde3d1a7, 0x8d5e653b,
- 0xd2f7cf92, 0x25f7df43, 0xf4f300fe, 0xbe80c3e6, 0x9e9a1198, 0x09ab118e,
- 0x92dfd2f8, 0xbe82269b, 0x356acc7d, 0x657d3e81, 0xa5f21363, 0x49ab7663,
- 0x24dfeb4b, 0x9ddacc3f, 0xd69e9356, 0xc3e37bff, 0x3565ddac, 0xdffad185,
- 0xeacfbf93, 0xc482c26e, 0xe7c8cd29, 0x0874894b, 0x21b947ce, 0x17150c73,
- 0x1e975e54, 0x2e317382, 0x3818de71, 0x56c97517, 0xacbb8fa4, 0x7d410eab,
- 0x0d66ce42, 0x1bb6c55c, 0xbf43560b, 0x0d4ad8b2, 0xba931bf4, 0x1bf4357c,
- 0x26a4fd9b, 0xdcf8dfb0, 0x7ea1ab9d, 0x06b36d8f, 0xce3ad3f4, 0xa238c4c7,
- 0x9f05da2e, 0x835e7916, 0x0f281c3b, 0x281ddbf2, 0xca5c040f, 0x063e56a6,
- 0x7686c77e, 0x3ac12cc9, 0xc1bd4aa6, 0xab91c86f, 0x291af787, 0xfe7a8ebf,
- 0xba2ad309, 0xdfa806cf, 0x5627f581, 0x9dfe5add, 0x97d71292, 0xe7e09f7f,
- 0xe43de41d, 0xb1d09f65, 0x001e32f7, 0x7de314b8, 0x2bbe1334, 0xd0269c49,
- 0x3cb89ab3, 0x6d25095f, 0x3bebcedf, 0xd9579c85, 0xdfd0a7fb, 0x7db85373,
- 0xd83f97d9, 0xfcf41d60, 0x8439ee2b, 0xa1fce768, 0x7b2cc530, 0xb08ea15f,
- 0xcbd7557b, 0x31e6531b, 0x9629f32b, 0xf6c3b691, 0x1479becc, 0xc7bd84b5,
- 0xae4fcca2, 0xad5eec27, 0xd7b94f32, 0xfc670aae, 0x0d780ab4, 0x2989e3a5,
- 0x6564f921, 0xe135f14a, 0x910f6f20, 0xb094bd97, 0xf93eec3c, 0x5b1f3c35,
- 0x8ce22fb9, 0xf25def63, 0xfee56cfc, 0xddf45d04, 0xbf832b5f, 0xea9fc186,
- 0x7d600b77, 0x044d7315, 0xfc8156fc, 0xf06be3e7, 0xbb3f251f, 0xfa727c55,
- 0x9f763adc, 0x6b1f2fbf, 0xc7c2094a, 0xb2975e44, 0xdc2a7a14, 0x3efc831b,
- 0xec060f78, 0x9c123bfc, 0x3d97402d, 0x55afbe65, 0xb2c68760, 0x2dbb93f7,
- 0xbbf035ce, 0x03f963a4, 0xbcf6af22, 0xd04bf5ca, 0xf94a9edb, 0x6ebbf215,
- 0x8cf41610, 0xe075a3ac, 0x8e2c4367, 0xe48fd0f5, 0xef817578, 0x1fca8730,
- 0xe1cb9a7d, 0xe59125be, 0xfe6cf655, 0x0fde86e6, 0x0a8f050a, 0xdc2f28f5,
- 0x3c3cb85f, 0x9767e502, 0xfef03c44, 0x3c69576b, 0x695d2dea, 0xb7940d3a,
- 0x4aee2eda, 0x2be3801b, 0xa4aee3ed, 0xef3606e1, 0xfe50f1d8, 0x115ce926,
- 0x790fbdc8, 0xcebb613e, 0xe037e435, 0x86111e1f, 0x257bfa71, 0x41c0116f,
- 0x1d775769, 0xcd66559d, 0xd35f6bef, 0xfd818dfd, 0x3d519ed5, 0xacddbf06,
- 0xf4db5dbd, 0xed3c8135, 0x09574d91, 0xbcdf8fe4, 0x9d19ddfd, 0xc2bd056f,
- 0x322402d9, 0x13ea8bac, 0xfcbd7eb4, 0xb5124ba4, 0xec0333d3, 0x66bfe1f2,
- 0x54bc4a79, 0xde7de7da, 0x92e65b4b, 0x7a95c3e7, 0x44df318a, 0xfbc48ded,
- 0x9ef62aaa, 0x7a57c882, 0xd4f3db8f, 0x829b3f5e, 0x74ceb87e, 0xfdfebd99,
- 0x823ce74f, 0xf30c207c, 0xff6d5e33, 0xfad60e3c, 0x9fb8ce87, 0xd3f565bc,
- 0x6bf98377, 0x5f679812, 0x565974db, 0xed7ee2ef, 0x2fbb2d56, 0x354ffb54,
- 0xc72a25ca, 0xc89e22d6, 0x0103dd01, 0xfdb495f2, 0x83de17b9, 0x04abbf29,
- 0x1d7ca180, 0xfb4ec939, 0x887b7255, 0x9d587790, 0x95c48fdb, 0xe271eac2,
- 0x7ab31ffb, 0xa9fef89a, 0x4f3a7649, 0xe7689265, 0x75e36ffd, 0x33d58797,
- 0x647ff7c5, 0xbb589bdf, 0x498ed37e, 0x3f05ce70, 0xdfcaa537, 0xddfca201,
- 0xcd7c5a92, 0x3b791a7c, 0xdde2ffe7, 0xdfef8a9f, 0x9c01f115, 0x730936d3,
- 0x6a576ae7, 0x317f5fd1, 0xf03f2dba, 0x7791507d, 0x613728e3, 0xebdd541e,
- 0x0b80b703, 0x1e3a6d53, 0x44ca7a0f, 0xa154ff9e, 0xe59c6236, 0xc7c67af2,
- 0x8b79e943, 0xe194de9b, 0x7f3b4fab, 0x9103178f, 0x4f4bbe74, 0x90f7b024,
- 0xee313bb3, 0xe995383f, 0x22bef0f1, 0xf915e7dc, 0xc459b15c, 0xec71f60e,
- 0x5dec611b, 0xc89db3c8, 0xc1bf175f, 0x1b75d7fc, 0x9b3ca20e, 0xffa2b6af,
- 0x673f5c68, 0x47c42a71, 0x30039d4c, 0x36f4ddee, 0x673fc39e, 0xcb9c7998,
- 0xcf081b97, 0x5fe17dd1, 0x97f81d7a, 0xbfe13bfe, 0x180dea9b, 0x8613dae7,
- 0xc6826cf6, 0x1c41b3ab, 0x577b24f3, 0xdb872172, 0xe23fced0, 0x7887ff7d,
- 0xc59daa3d, 0x959e4469, 0x54a1f798, 0x8f038313, 0x7e4dd487, 0x43c4147f,
- 0x224afe04, 0xb7f81b48, 0x1c6c1e29, 0x83c0360f, 0x2e3fb780, 0x0665fb42,
- 0xbd956b8e, 0x1ee02b5f, 0xe92b1cea, 0x195bac43, 0x3c665827, 0x5df80c54,
- 0x81799376, 0xbe38d297, 0xfbcc5e35, 0x410673fb, 0xb8f028b9, 0x5dde2fb2,
- 0xc4d771a9, 0x5ffdbcbb, 0xdc25778c, 0x8f2d6594, 0x7f7f297b, 0x2ff55521,
- 0x36ffe385, 0xc6ecea7f, 0xb9f6b2fd, 0xc86f474d, 0xa0fc2adf, 0xabbf2eff,
- 0x7a4eb7f0, 0xe20a896d, 0x7c7b4a32, 0x6be3ba5a, 0xdf7bbfa0, 0x09ee47fc,
- 0x00f57c58, 0x90793fcc, 0x51abe5ef, 0x11ecfb7f, 0x355f4f4a, 0xa9d43f32,
- 0xad6a5ffd, 0x63e97d79, 0xb11515f6, 0xecd5d007, 0x20b48fa6, 0xcd5366af,
- 0xea3c5822, 0x309e9cef, 0x81f2847f, 0xc6d1032a, 0x555ff3d2, 0xae73dec5,
- 0x344bc082, 0x6d271e96, 0x1e21a49f, 0xd2b5af78, 0x31e8f1a8, 0xb7bf241e,
- 0xb9efe7aa, 0x7652c352, 0x576d557f, 0xb4d37e63, 0x748e2ce1, 0xef0db1bf,
- 0xf238ce25, 0x6847a5e8, 0x2aed593b, 0xe2b77966, 0x54efd19e, 0xfa1f1337,
- 0x7e612a7b, 0x1dc78954, 0xee316b97, 0x61f7eca8, 0x4d63f32a, 0xbf2c4b52,
- 0x4fcb2f60, 0xee91e713, 0x90be88ef, 0xbbc3c1e5, 0x5a8d95a6, 0xd07cc0cf,
- 0xfea3f63f, 0x557c30d1, 0x61afe03e, 0x9f46748c, 0x1b03d7ef, 0xfd82fe9a,
- 0x5958fc95, 0xe9dfa8de, 0x4823e6b3, 0x3c5f422f, 0xbac1ecd5, 0xab350fd2,
- 0x6e303fe4, 0xee2fe233, 0x5e472816, 0x66189fb5, 0x95f6eefd, 0x9d84abb0,
- 0x04dbb4a5, 0xb5ef10bf, 0xc3fc140d, 0x777b11f0, 0xbccac351, 0x15ff3934,
- 0xd9f2957c, 0x7f8c3482, 0x006ff9ca, 0x7ff6c61f, 0xd3f61f17, 0xfc0da37d,
- 0xeca95535, 0xdd25737d, 0xf93226d7, 0x7577a4a9, 0x19f51ab9, 0x3a0bbd25,
- 0x19becfbf, 0x20b375fd, 0x31d74f56, 0xfbc241ab, 0xff5f2752, 0xba0643e1,
- 0xa7b6ae84, 0xe8f7b2b4, 0xfbee926e, 0xe9b381ca, 0x9677df30, 0x9c33a403,
- 0xf8665bdd, 0x47d69458, 0xbb4d2e8e, 0xb7951cb6, 0x17f18bff, 0xbe73ff64,
- 0xca241c9b, 0xd473057b, 0xd39f362a, 0x213ef2c8, 0xcdc7acef, 0x675579ee,
- 0xd37be2b6, 0x122fb864, 0x7dd2c8f8, 0xc58eb26a, 0x01493437, 0x117508ef,
- 0xe92327cf, 0xb1464bef, 0xf9943877, 0x4f3cf598, 0x37719973, 0xbe5213de,
- 0x3df22407, 0xca78f9eb, 0x7f448177, 0xf9582f71, 0x34c6d02e, 0x90ad7f7e,
- 0xf838b214, 0x3753f9b5, 0xff00c9c8, 0x66d5f770, 0xa4b673b4, 0xae47f1fd,
- 0x6f3c7e51, 0x3e7ee34b, 0xbf6c5d3f, 0xff6c5d0e, 0x6a1749ff, 0xef7c56d3,
- 0xe2e966e3, 0x3f7dab11, 0x8f9c5bac, 0x96fc73de, 0x78b1cf1e, 0xf967b80f,
- 0x471ef8ab, 0xe30437cf, 0xc3f3d740, 0x6bb17494, 0xbacfa33d, 0xaf144c5b,
- 0xd0b94f23, 0xb8e2303f, 0x0dbfef13, 0x990edf7b, 0x90e0a4c6, 0x16eb0d43,
- 0x1bd0827a, 0xdf80fcfc, 0x1d79e153, 0x6e37ca37, 0xaff1be36, 0xfb886b8a,
- 0x4f5add32, 0xdb9009f1, 0xbe82c37b, 0x8d257d97, 0xef50edc9, 0x9ca25a6e,
- 0x534f0057, 0xef15df38, 0xd9a8566f, 0x3b97b93b, 0x589fe8d5, 0xfedf83f1,
- 0xdf6b79f2, 0x58fa95f1, 0x5072f983, 0x0d9446fb, 0x5f2f962a, 0xbcc56e58,
- 0xc07bb02c, 0x17fc215f, 0x5847efca, 0xd1d3c2cb, 0x69d51ede, 0xc73cf587,
- 0x5f0a13d6, 0x123e4d0d, 0xa87ceef8, 0x15f61bf9, 0x9c07e79b, 0xbde9098f,
- 0x9cf99676, 0x1bef8fc1, 0x6dff8ba5, 0x3524fffa, 0xfe544971, 0xa66e49e6,
- 0x57a6124f, 0x589d22ce, 0x2c3e21ce, 0x4fe5849d, 0x2c3627cf, 0xaef61217,
- 0x670ca1f9, 0x8de83a49, 0x0fbe1f5a, 0xbff5e97b, 0x4cfbe2e7, 0x856c8e77,
- 0xe55ba89c, 0x55ea56b7, 0x8fbe053d, 0xd8ff03a7, 0x2b74f7f3, 0x7b1bffca,
- 0x94507aa7, 0x107a4a7d, 0x4a6ff6bf, 0xc4beecd5, 0x5e5107c9, 0x1f599a54,
- 0xfdf98632, 0xe2642627, 0xcdf3f1f9, 0x6f82cd84, 0xef2afc42, 0xdfc58a8c,
- 0x77f84a97, 0x2abdda79, 0x8b79623c, 0xa86add32, 0x79ed66ef, 0x44b71675,
- 0xc22379eb, 0x8b72fb58, 0x67ddf21b, 0xcb9e2f13, 0xaeed90b9, 0xbd13bff6,
- 0x7bf9d880, 0x127ebe06, 0xc3a8bfed, 0x89b6f2c0, 0x9bf61b37, 0x1049760f,
- 0xe997f73b, 0xee0fbcec, 0xe0fdf8c7, 0xe15fb932, 0x267ede21, 0xe013aca3,
- 0xfb74bbf1, 0x0d7ce0f7, 0xf75cee8e, 0x53f81154, 0xc2fc0454, 0x18788c5f,
- 0x5fa228e3, 0x11ecb598, 0xc4876ef8, 0xfb5d8bf2, 0xd2dde2f4, 0xfc7f40f8,
- 0x55f28ca1, 0x74daddf0, 0xc1429fc6, 0x942efe15, 0x261d8823, 0x8306d5f2,
- 0x427e886e, 0xed06ef82, 0x437d5890, 0x577bd8fa, 0xe977d11b, 0xcc33fd02,
- 0xec31fcea, 0x108eb063, 0xbfffac23, 0xd219bdf8, 0xef710e98, 0x55e82f25,
- 0x4a7c5fa0, 0x27dc31c5, 0x63b53df8, 0xed4d3ca1, 0x40ff2851, 0xcf2851ed,
- 0xca147b50, 0x0a3da9cf, 0x362ba2e5, 0x14971c78, 0xce7fd867, 0xbbf83ce8,
- 0x33a62f1b, 0xc32679b9, 0xc75b29d9, 0x63ae1d3e, 0xc7f3a587, 0xec75d14f,
- 0x82ad93d8, 0xe0a12cfb, 0x6fefb3d1, 0xf820cee9, 0x93dfcdec, 0x6ccbe782,
- 0xefe7f3e4, 0xcfdca0d6, 0x2e46f76f, 0x3daef80e, 0xc878875d, 0x123673db,
- 0xf736efc6, 0xd12ed5c2, 0xb1524ead, 0x330bfb7a, 0x0b9d5def, 0x0277b0fb,
- 0xeef9e8fe, 0xfdbf3280, 0xfb863fb7, 0x8c7c741b, 0xbe48f6c7, 0x532f4067,
- 0x6fb943ee, 0xffba2fb1, 0xc77fd075, 0x13b07e9e, 0x3b086fca, 0xfbd8fb2f,
- 0xbbf77db8, 0xaf7bd70a, 0xf70457de, 0x56fdee12, 0xf41f341d, 0xc229464c,
- 0x99d056bb, 0xba71b788, 0xaefaf812, 0x1e395ae7, 0x0017ef11, 0x3c82b50f,
- 0xfa091aba, 0x5b8f2560, 0xfeceefb6, 0x1cb9ef10, 0x3bf81351, 0xe5a38381,
- 0xc19d4ee7, 0xf3289dce, 0x801ce9f6, 0xcefb1daf, 0x9cfbc365, 0xf0d93f14,
- 0x4abf5b77, 0x17f32fef, 0x66f88de6, 0xfd0fd023, 0xe02eff1e, 0x02b9b20c,
- 0x0d33f3e2, 0x2d85dffb, 0xa99f36cd, 0xdcfcf880, 0x9430e944, 0x6399acf3,
- 0xf22f2e21, 0x94e4179a, 0x74a3861e, 0xf512ad8f, 0x2e6052b8, 0xdca17201,
- 0xe71fc110, 0x46287215, 0x98971f56, 0x2efefb22, 0x7dac966b, 0xb2edce42,
- 0x26fbdef6, 0xdffe21b6, 0x7c3c01fb, 0x465e20fd, 0x8efec1f7, 0x7dec4bd9,
- 0xc73dbcdd, 0xd69dbeef, 0x0d3cbd27, 0xc1db63df, 0x2aed27db, 0xd623bfc7,
- 0xa3a9e143, 0xe1f9d48a, 0x14f33f8f, 0x13b0a60c, 0x78bdf76a, 0xbe67de18,
- 0x1d709dae, 0xfbd420fb, 0xd2bfa2a1, 0xf2fca03e, 0x072fc0c7, 0x0cd53ebf,
- 0x231da1f1, 0x790649be, 0xefc19994, 0x21bb7187, 0x9ef4dd14, 0x61fac90f,
- 0x2528fde0, 0x28f210dd, 0x4e5643a7, 0x01eec63a, 0xfb3f2cdd, 0xb433f013,
- 0xf0245dc3, 0xfd2a08ef, 0xb6758365, 0xff041f0f, 0xb86a07ce, 0x3f7bd109,
- 0x5bfc316b, 0xb277a7ed, 0x4963f370, 0x0bbbf8b1, 0xee7ae0f4, 0xc1959b3f,
- 0x76a4ace2, 0x454963ff, 0xe2b276fe, 0xb27bec8c, 0xab235a52, 0xd794ceaf,
- 0x09ae97d7, 0x0f4a1fec, 0x3cdcfc5b, 0xee0f339d, 0xff4149f1, 0x7aef626e,
- 0xd85f3962, 0xecf904b7, 0xf14bfdb9, 0xbf2ab9ef, 0x81e3a7af, 0x08716fdf,
- 0xd3f82af9, 0xcf7b350c, 0x4cbed957, 0xb5bb67cc, 0x614a7df3, 0x6f5c798f,
- 0x69fbb930, 0x93275394, 0x7f4c19eb, 0xc9e1b4bd, 0x710d7c1f, 0x9eccbda4,
- 0x726164ba, 0x17f77f23, 0xcc7bf82a, 0x7d19c383, 0x2abd9be5, 0x53d327b8,
- 0xbc82e11d, 0x26a586ed, 0xdc1bb7cc, 0xa189f7cf, 0xfc1f9080, 0x1a7fd0f4,
- 0x0efe7d28, 0xc805bf2e, 0xb9d01ee1, 0x8cf1fd68, 0x49872843, 0xb86fcb2e,
- 0x9c7cfb55, 0xbfa864ea, 0x317e3194, 0xcb8fe807, 0x55cf422b, 0x57a463c3,
- 0x021f017e, 0xc0fd40b8, 0xf0fbdf4f, 0x1e33f069, 0xfc02fc65, 0x0f513307,
- 0x7ee51bb0, 0x1ef63685, 0x0bbd9598, 0x4242f222, 0x87658ff1, 0x5760755a,
- 0xf1fe6ade, 0xc4f9f5f2, 0x8f1409b1, 0x3e597b0d, 0xfe8ee5f7, 0x6f802451,
- 0xf0d7e128, 0xb7cf0a9c, 0xa87777a8, 0x5079c3c7, 0x70164bde, 0xb201e626,
- 0x181e78f7, 0x20c9b7fd, 0xa7d81f97, 0x50f44161, 0x1155acf3, 0x833cc06b,
- 0x8e51e9f7, 0x98f7f589, 0xf7d91f39, 0x5cd2e8d7, 0x220aae56, 0xa01ea94f,
- 0xa03d058d, 0xf5bb4252, 0x65097de3, 0x258fff00, 0xe216b1e2, 0x3a2f9810,
- 0xbf070d85, 0x899df11b, 0xe04d1cc4, 0x6ec27afb, 0x5a6fb69d, 0x3f57d07f,
- 0x63ff3dd9, 0x69f2198a, 0x879e1646, 0x1f8ef0e9, 0x16c7ef85, 0x43f81a47,
- 0xeb78f126, 0x175f16c7, 0x8f1fd5e8, 0x6fc0908e, 0x0d5fc749, 0x7d7d8be3,
- 0x35a475ac, 0xed17fa06, 0xfbd3be83, 0x42bda25d, 0x0274b2bd, 0x11678bc4,
- 0x5efcd77c, 0xc9a3d335, 0x0b3cec3b, 0x7520dabe, 0xc73be346, 0x32bb9319,
- 0xa684ff68, 0xab3da11f, 0x51ba27cc, 0x6ed7ba3d, 0x77b126de, 0x4e8c6c32,
- 0xfc5d47eb, 0x7f3a74c9, 0x41efb53d, 0xdf6babaf, 0x28a6ef8f, 0x7b5ef9ed,
- 0xbc2fe94a, 0x7fe83f8e, 0xca6fb100, 0x0080005b, 0x00000000, 0x00088b1f,
- 0x00000000, 0x58adff00, 0xe554700b, 0xdef73e15, 0x66cd927d, 0x421b22f3,
- 0x260ddde2, 0x9b709601, 0xf51e4357, 0x8ca4109a, 0x6388376d, 0xfadea56a,
- 0x59092040, 0xd6a27509, 0x0071a6e1, 0x3b634ea9, 0xb33088a3, 0x2331e1d2,
- 0x3054d353, 0x32d740a3, 0x5da96255, 0x66d42d8b, 0x88d46b98, 0xf1a6c935,
- 0xa1986655, 0x5ef7fce7, 0xd6086f76, 0xe6ccdd3a, 0xe73effec, 0x9cff8f3b,
- 0xaa36c01f, 0x5cfb0195, 0x8bdff016, 0xed2bf1f6, 0x8ca2c020, 0x06ac43b0,
- 0x27c8f2d8, 0xfb0dbd7f, 0x990dedd4, 0x47f18b63, 0x475f8e3e, 0x5c8054b3,
- 0x000ea580, 0xd4c0154f, 0xbee8b4fe, 0xf097f500, 0xd9b00350, 0x80453f87,
- 0x9c944e8f, 0x8ff1c6ed, 0x8703b0de, 0x9f1b275d, 0xdb107c9e, 0xf9a7f65b,
- 0x059e349c, 0xef8d3e6a, 0x38aa8d2b, 0x6a7e3ee1, 0x27073ba4, 0xfb4ba60e,
- 0xbdc3fc71, 0xc61fcfa5, 0xafe786f6, 0xaecd8897, 0xd9883c5d, 0x0d885fd8,
- 0x3e6dffea, 0xfd7e075b, 0xfd2e75dc, 0x92e0e15c, 0xf8d0379f, 0xce896cc1,
- 0xcb39a569, 0x75ec2e00, 0xf00e50cb, 0x7dcac419, 0x731f00c5, 0x1b8f18ea,
- 0xcf87f3b7, 0xb3c03c73, 0xe494a50e, 0x37fbb8de, 0x7947ab7f, 0xe77e0f9a,
- 0xdfc865e9, 0x40b93386, 0x5cf2c0fb, 0x787e0186, 0x1a728b98, 0x9708b5e7,
- 0x60085abc, 0x067158fa, 0xb4f89284, 0xdefb721f, 0xe2b81977, 0xd32073b7,
- 0xca1aeed2, 0x965fbdf7, 0x8e83b76c, 0xd9c3dc31, 0x7d0eff68, 0x65798608,
- 0x09d5f109, 0x0808039a, 0x97847298, 0x9c085400, 0x13ff840c, 0x65ff864e,
- 0xa490dcfa, 0xf8cf222d, 0x1941e0e8, 0x6cfce0f0, 0x702bf970, 0x97e3a2b9,
- 0xdf74a278, 0xad66c44e, 0xcd500598, 0xbd592df6, 0x8b7fc924, 0x15e9b230,
- 0x977a7fdc, 0xef627253, 0x0cee1bb8, 0xa73eae87, 0xeb64cc55, 0x053eb9d7,
- 0x7fb2765b, 0xadbfcf53, 0x51c810ed, 0x27d15f5c, 0xb48fde56, 0xafcbd0db,
- 0x0c35e1fc, 0x8f2781f7, 0xee78669e, 0x3a1de079, 0xe98794f7, 0xb8eb4e0f,
- 0x23683827, 0xd6fdcc39, 0x56c0a6b9, 0xc73efc49, 0xc7fb35f8, 0xae5b399e,
- 0x4763fee0, 0xda039716, 0x7c425df3, 0x67c459ec, 0xfe7e3d32, 0xa783a461,
- 0xf15732fe, 0x476fcd5c, 0xcfdb34cf, 0x1c738f6c, 0xe483b793, 0x829bfec0,
- 0x9e228de1, 0x09903603, 0x4b9dd1bf, 0x422d7e18, 0x9ff48328, 0xdfcac8f8,
- 0xfdcd3e4c, 0xfdccfe4d, 0xa43d79cd, 0xc261c42f, 0xc2cf2f11, 0xa24539fe,
- 0x6f09ae45, 0x43d33cbc, 0x3fd63efd, 0x14ed8591, 0x9fa36b7b, 0x1736dfa8,
- 0xbf9073d8, 0xea4e36b6, 0x42afd603, 0x0531a316, 0x2ffc3bc7, 0xd841b81b,
- 0xab767685, 0x93906761, 0x5a3f236d, 0xdf5dba03, 0x8bc7fb5a, 0x76e0179c,
- 0xfa03b018, 0xf7be39cb, 0xe3a42ec7, 0x13b4bf03, 0xbe10e87e, 0x4e5fb431,
- 0xbcbf877d, 0x4db96af8, 0xa58d804a, 0x5f831bc6, 0x22ca09b5, 0xcf84cfb8,
- 0x014bf2a3, 0x1b39119e, 0x8508579b, 0xa5c70f34, 0x3a81da18, 0x90fa94e8,
- 0x787c4b9f, 0xe1dfe12f, 0x1f939588, 0xf12eeb98, 0xe71feb0a, 0x7d23af4e,
- 0x1e562d83, 0x647d474e, 0x40cb803a, 0x65c52b9a, 0x0cfd43c4, 0x23015c58,
- 0x9518f1fe, 0x1d849ce8, 0x8f9106da, 0xfd37ea46, 0xaaa4ed13, 0x7a0c8f99,
- 0xfc93f392, 0x0195db5b, 0xb2aacfdd, 0x2cc0c8f9, 0xc327f1fe, 0x4060fb0f,
- 0xd617fdd0, 0x7ae710b8, 0x59006703, 0x64df7f20, 0x3cb937b4, 0x54e30131,
- 0x0552ebc2, 0x18febfe4, 0xf5db01ea, 0x44abd8b6, 0x07a1ebd1, 0x310759f5,
- 0x6b21bf7d, 0x8f70e6fc, 0xfc1c703b, 0xa91c598b, 0x8dbbd433, 0xd1e9008b,
- 0xee8cfd05, 0xd102e2e4, 0xa314c16f, 0x446cf832, 0x97467611, 0x15d19843,
- 0x25746110, 0x0aba33f4, 0x19bd1806, 0xa2c28ce2, 0xf8b01f58, 0x58df13ff,
- 0xdf6f921a, 0x5a465fc7, 0x66441b75, 0xc32987f3, 0x078dafce, 0xaf9af546,
- 0x500ac78f, 0x6baf8cfc, 0x8cbf32e1, 0x8b89b9d9, 0xd711ec93, 0x27ea21b9,
- 0xdb1a08da, 0x5c3206e7, 0x1046e7dc, 0x066ed46d, 0xbe5bb599, 0x9ab51e22,
- 0xb3425362, 0xbb3cd2e0, 0x70345c9d, 0xab2c25e9, 0x185afa93, 0xd4db5910,
- 0x149f201b, 0x27d6afff, 0x559f1114, 0x889f4d69, 0x03b22218, 0xc61b61bd,
- 0xa6caaad7, 0x2f6c62ee, 0xb7a93c08, 0xed2a9beb, 0xfbd39e12, 0x8c72f08b,
- 0xee0c2eab, 0x2845c46e, 0xa916a016, 0x0396f6e2, 0xb85395fa, 0x54ff225f,
- 0x10f100dc, 0x40b9e373, 0xc256d0fe, 0x3e2dbfee, 0x3aef3f5d, 0xda00f494,
- 0xe62ba777, 0x2de71115, 0x74792dbd, 0xe8776e0f, 0x2b9bbefb, 0x65057e2e,
- 0xae39e272, 0x383ca48a, 0xadb1baae, 0x4f776271, 0x57ee7920, 0x5020af38,
- 0x9af3ed7d, 0xfc488afc, 0x4804ab80, 0x3dc605cf, 0x2f58383d, 0xef9d3c49,
- 0xe96be763, 0x383ddd25, 0xbc3fa4f4, 0xa44bf690, 0x90b5f6eb, 0xd24dcff0,
- 0x94b90135, 0x27f667c6, 0x1a38bf7a, 0x1f137dc3, 0xaeb8c1e0, 0xd394a031,
- 0x56bc5db9, 0xf87a8954, 0x0779da69, 0x4fb4dfe9, 0x0772950e, 0x4327dbca,
- 0xbeecc1d4, 0xaf2577c1, 0x77da4e2a, 0x0fdc5ee2, 0x870aa871, 0x5c38ed9b,
- 0x493916d3, 0x6fe956b4, 0xa73a11c6, 0x12e9f89e, 0xbe91d6a6, 0x38cf3327,
- 0x37fe603e, 0x2333b75f, 0x313f1d2e, 0xde8170fc, 0x7f8a430c, 0xf8b89d75,
- 0x1e303ff9, 0x247b4d76, 0xec7f5e9a, 0x26f06e99, 0x3ab30afd, 0xfd30dc4b,
- 0x19c86eac, 0x85bcd813, 0xc6fcd2f7, 0x14c52333, 0xd1186f6f, 0x42dc30fa,
- 0x02d9f8e2, 0x7b8ddedd, 0xfb82fe41, 0x8b42f73a, 0xb8c74a80, 0x1088f9bf,
- 0x9b5ca275, 0xda304f29, 0x743fb62a, 0xd0649da1, 0x8f93d97c, 0xe437ad72,
- 0x83fe1cea, 0x6d3a8303, 0x1bbc92a3, 0xefd7fe0c, 0xca66fbb9, 0xed4436fb,
- 0xdf8ef8c9, 0x36e891f6, 0x90fdbbe2, 0x21229fb5, 0xac65dfc9, 0xabbca0ef,
- 0xeb37f298, 0xfc782ebc, 0xba97145f, 0x9bfdac86, 0x4c39e902, 0x063dc60f,
- 0x9f78be46, 0xa3e48731, 0x71f379bc, 0xb289d447, 0x2ddbde6d, 0xe85da8f9,
- 0xdd1c5891, 0x5bb328f3, 0xc9ec3e73, 0xfa623666, 0xc01d86e7, 0xc71360f2,
- 0x329c07a5, 0x81e963e9, 0x62df963c, 0x0af2ce5e, 0xcecc138c, 0x1c262297,
- 0x990bddda, 0xcf1e4153, 0x9978e179, 0xcbf37944, 0x6f78655b, 0x333f9241,
- 0x0e116f6f, 0x3ed03b37, 0x1f01efa6, 0x50357de5, 0xae0374f6, 0x87653eab,
- 0x834f8e28, 0x0be98fae, 0xebbfcb3c, 0x64fd2b86, 0x231cc207, 0x4f31f86e,
- 0x2dc3c14f, 0x253101ce, 0x75f135cf, 0x2b4b7a1a, 0xa78cb2cb, 0xeb2cf34b,
- 0xd6836a33, 0x0f1caaf5, 0xd69c50d5, 0x8bca67d7, 0xc341f32c, 0x306f1c3f,
- 0x5deedbe0, 0xb7ec8a71, 0x66feb3d1, 0x657b29c2, 0x53be6585, 0xff102638,
- 0x2cda9f0d, 0x8426fc7a, 0xce51d39b, 0x0f31b7da, 0xc6ea73c1, 0x4d6ee3ad,
- 0x7ee75a05, 0xa01f253b, 0x7b6b44fd, 0xf987b4c0, 0x1ed53f30, 0xae7b7892,
- 0x50f649e0, 0x782c0b03, 0x0aebc4cf, 0xf3071efe, 0x6ee1ba87, 0xd86e5fc6,
- 0x9b5e7b8a, 0xc57cf715, 0x7ac1738a, 0x1185ce2b, 0xf5d7ce2b, 0xa80d7158,
- 0x778adc56, 0x5fe659d4, 0x6964dfdf, 0x655aee97, 0xba30bf99, 0x7c5ed2da,
- 0xfccb76e8, 0x59770325, 0x6d0e97c6, 0xf69b8cb4, 0xdfff5335, 0x619e6d88,
- 0x5ff03c5f, 0x53caffa2, 0x99ce590f, 0x888077a9, 0x6bd6f840, 0x5703bb00,
- 0xedfabdeb, 0x578af07e, 0x0f029deb, 0xf5339de5, 0xa7fa453f, 0xffe86f38,
- 0xc629d233, 0x17bd37b9, 0xfd37271e, 0xcf1e9a6e, 0xb886845a, 0xb06d7a4c,
- 0xcfeb7ab3, 0x3a737662, 0x1ee303c5, 0x18f71b0b, 0xecc1dfac, 0xdbd3ec21,
- 0x493a5c52, 0x5ce2ac71, 0xaaf899b8, 0x512722d2, 0xd0b9a84c, 0xf3419cdf,
- 0x387d1065, 0xfaf0339f, 0x36072d5e, 0x7b613f8b, 0x5bcf126e, 0x03215ed4,
- 0x8a5fd727, 0x4b30b1f6, 0xbf9e0ec5, 0x6ae718da, 0x55a27bf5, 0x052d8376,
- 0xf35ac697, 0xfe3108fe, 0x316ffc4c, 0xe7cc08ea, 0x3cf941c1, 0x05f68aef,
- 0xa45fcb66, 0xafcb025d, 0xbd6f9614, 0xa27629ce, 0x22f15c6b, 0x9e4aeb8a,
- 0xb8882f32, 0xc892f24d, 0xeb4e33f2, 0x2412a123, 0x6a565d18, 0x754cab66,
- 0x30a39618, 0xd19f290f, 0xfb187aaa, 0x2f46ad3e, 0x1253e97b, 0x18838a54,
- 0xdf394717, 0xfb5c4ab6, 0x45c7dd66, 0xca2d6f74, 0xff501790, 0x3c8ef795,
- 0xabe30b94, 0x412a8bc6, 0xb1c43ea0, 0xda63e1fa, 0xdf8a5964, 0x7bb3b0ee,
- 0x6a7a8c0a, 0x599381ad, 0x9c61dd4f, 0xac5b8a3b, 0x76bdf8c7, 0x478675e8,
- 0xd59c7fbb, 0x926f689f, 0x7bbff70f, 0xea82a7be, 0x252b9049, 0xeb370ebd,
- 0x7fe102ab, 0x7acd47b9, 0xdbf35af4, 0x752c17fd, 0xefd61c2e, 0xafef6b97,
- 0xca4d7b32, 0xfa3fefad, 0x77bb1a58, 0x6c2b1f46, 0x7fdc9a22, 0x36bfed92,
- 0x3ec596f2, 0xbbf9ecee, 0xa47eeec5, 0xd7196bbe, 0x05eca672, 0x3476bf28,
- 0x100fc57f, 0xce2389bf, 0x5133aa1a, 0xa60fdf5f, 0x13dac1d4, 0xbce9cba5,
- 0x3fe72eff, 0x5b23be19, 0x905b60e3, 0xd6fcf394, 0x6dadac73, 0x299d18d5,
- 0x9a9759a7, 0x287bf1d4, 0xa67ea1b3, 0x6cd239b8, 0x41232cef, 0xb91f6f3d,
- 0xdd136e71, 0x0e8523bf, 0xf44b4e9b, 0x4bad7e76, 0x4958af6f, 0xecf76134,
- 0x8474baa0, 0x7b439903, 0xf9f79d18, 0x516e0701, 0x403ca797, 0xa69a2672,
- 0x2977a73e, 0x288ad1c8, 0x2a664c9e, 0x873f520f, 0x167e5fc9, 0xf284b3e3,
- 0xfabc0bff, 0x7018c06b, 0xad6ddf60, 0x7a4fd794, 0x647fbb75, 0x2aad2ddf,
- 0x199952e2, 0x40eb4ade, 0x917bd8d6, 0x8ef9afc9, 0xd52f7542, 0x4eb70921,
- 0x263907b7, 0x74198eff, 0x28d4d537, 0x1d064bdf, 0x384afbe5, 0x4edd87f2,
- 0x7e601fd8, 0x315e5320, 0xfba9cc7d, 0x8bc00d81, 0x711defe3, 0x3cf6473e,
- 0xbca67917, 0x9633b305, 0xcefc57ff, 0x6138a319, 0x14e4bfbe, 0xe10b3f8b,
- 0xec979cfa, 0x4c9fceac, 0xbfc86b17, 0xb2afbd3b, 0xa0a6ebbc, 0x40e4c032,
- 0x8c7e2849, 0xdbee751e, 0x2a4dfcc9, 0x7ffe9d5a, 0x103b677d, 0xa68c7564,
- 0x3bc691e7, 0x8b77299b, 0x7b9338f0, 0x4813977a, 0xe37b89ce, 0xbbd8854f,
- 0x7c445492, 0xdf3af28e, 0x7ca6bf26, 0x7dc91ca6, 0xcd6edcbe, 0x7be4a2f7,
- 0xf212f6d6, 0x7f51c403, 0x3bb813c7, 0xfeb2cf57, 0x9aabe90c, 0xa09da7bd,
- 0xa231b638, 0xf525a7bf, 0x3bc0ffde, 0x0f61b7a4, 0x5ad7638b, 0xcece533f,
- 0x0f0cc313, 0x2487f394, 0xa79c8a5f, 0x7eef2983, 0x3ecfc713, 0xbebf1215,
- 0x38c2897c, 0x3c4cdf7b, 0xc448b177, 0x5ec79df5, 0xd276473f, 0x33ffd469,
- 0x739da9df, 0x9acc7eb0, 0x6f1a7ded, 0xc97c9485, 0x6f9fae69, 0x04c7aeb3,
- 0x886cfc99, 0x0af291fc, 0x5e2927bc, 0x8be4f79b, 0x69c19d46, 0x4d78b1af,
- 0x6efd91e7, 0x5f7654e3, 0x7d05ef99, 0x5447de1c, 0x2cdd2b97, 0x79d70b8e,
- 0x17cfb224, 0x74e306d1, 0x34e4d8ff, 0xa33c2ef6, 0x54e79d8e, 0xd93b253e,
- 0x1e5356f2, 0x6f83b9d5, 0x27ea32ac, 0x36a91efd, 0xce9ab2ec, 0x1943fe27,
- 0x32a93eec, 0x4571abf8, 0x0cbade58, 0x177f4154, 0x1e19de30, 0x7752cd7b,
- 0xa2bf07fd, 0x17f0846b, 0x000017f0
+ 0x424e4cce, 0x4c22f212, 0x21a08812, 0x8a80af0c, 0x2201277f, 0x282039f5,
+ 0x4201d458, 0xd4837908, 0xcdedaf4b, 0x11102484, 0x0547f435, 0x5088768b,
+ 0x340da2d1, 0x0ec160d2, 0x6d7b1420, 0xc0faf06f, 0x480bf5ea, 0xb12f3141,
+ 0xcbc57e20, 0xe7dad6bf, 0x264ce664, 0xafdbd880, 0xb4fdffff, 0xece7d9b8,
+ 0xebdaf7b3, 0x7b5ad7b5, 0x75923ded, 0xc7bf9302, 0x03fc45d8, 0x8c4d4fe5,
+ 0xf2c109b1, 0x80f66667, 0xc9b18727, 0x473afebd, 0x6d55633c, 0x9da23b19,
+ 0x99ec258c, 0x50281421, 0x2c23d5fe, 0xbfdf8250, 0xf097c365, 0x4219b6ff,
+ 0xd0977c3e, 0xc3e611e9, 0x02d5e4fb, 0x933a876b, 0xea0c319c, 0x4b19b98c,
+ 0x126b2c64, 0x4b223fa3, 0xe0ff828d, 0x8f392573, 0x27fc34b1, 0x61467574,
+ 0xc678c0ae, 0x5c531e32, 0x38a9d0d4, 0x843f7815, 0xbcd2c67f, 0x0731b725,
+ 0xbc03cf63, 0xbcf071c9, 0x61de3a5a, 0xc22eefe5, 0x3af3a1df, 0xae58cd6a,
+ 0x32773e30, 0x416589a7, 0xf3e33ebf, 0x3d6346ac, 0x4fe3d99b, 0xec3fc346,
+ 0x8c517ecc, 0xb1138f30, 0xcb3c018c, 0x632f0e54, 0x5467b2bd, 0x6a9b1f10,
+ 0x2c32a258, 0x852f0f58, 0x56338765, 0xed975e03, 0xf8165c16, 0x2f6c39fe,
+ 0xbed7e631, 0x15ead66b, 0xa362593e, 0xb50404a1, 0x67eff4e4, 0x11bfcb11,
+ 0x2b30fef1, 0xea4ab2a0, 0xaf805595, 0xfb765aaa, 0x67edfe95, 0x54e88933,
+ 0x5bf6b929, 0x5adefc61, 0xf1866ae6, 0x02d59997, 0x91fb2fac, 0x7a83e5d3,
+ 0x21476366, 0x36d0fa83, 0xc1198981, 0x9e00afef, 0x007f91db, 0xa52b2a1e,
+ 0x740642de, 0xb02bddec, 0x871c0ce6, 0x776cbbf7, 0x0c65f306, 0x6658e70c,
+ 0x32e73826, 0x74893a41, 0xd2073071, 0xf324bcc1, 0xcea84289, 0xb0f3dc54,
+ 0x9de29f7f, 0xe7f4ed87, 0x38e60b49, 0xf25700bd, 0x57a06650, 0x9d3ab5b1,
+ 0xea563265, 0xbe442969, 0x8decb538, 0x9e025855, 0xf7c02413, 0x08a78b7c,
+ 0x5798a9fb, 0xa780cd9d, 0x8d1859e6, 0xff2db43f, 0x0cf80933, 0xc4c5f3ba,
+ 0x76313f21, 0xf04f843c, 0x5a11f1cf, 0xde981c5d, 0xb08b2b97, 0x05f1091f,
+ 0x1f011772, 0x26a0423f, 0x544d28e0, 0x29fc573a, 0xd0a0d86b, 0xc3595bfa,
+ 0xe50069c6, 0x3f0cbc11, 0x0843ac61, 0x1cbd4be5, 0xb0ff3bba, 0x3c303b94,
+ 0x04f3d3ff, 0xab7e1274, 0x1fc8b700, 0xbfd97615, 0xca61f812, 0xf7c0e6ab,
+ 0x362a3f80, 0xd40b7e0b, 0xe8dbaf4d, 0x5e26f77d, 0x3765d80f, 0x16d74ff2,
+ 0xbdf00ba8, 0x1bf1fda5, 0x155ebf91, 0x3b763359, 0xfa84ca22, 0x3b06a4e5,
+ 0xc0750f1b, 0x578db147, 0xbbef362b, 0x692fbf1f, 0xf41b30b3, 0xf17bb157,
+ 0x7d42371d, 0xc33361f1, 0x6b5b1526, 0x2fa814e5, 0x582d0bf1, 0xf0e029ef,
+ 0xfe8976f9, 0xc7bed0ad, 0x1b389ed1, 0xc6ba73e8, 0x63329cca, 0xc4f6f675,
+ 0xa567c059, 0xf8851dfe, 0xc176e95d, 0xf29f6885, 0xc943d6ea, 0xb917af38,
+ 0x8b6d977c, 0x7f1d4e66, 0xab64f7f0, 0xbc1ef818, 0x64f3065f, 0xd662efd0,
+ 0xb07a8854, 0xd93aeb62, 0xebe20f69, 0xe34a8d74, 0x8bdfc9f4, 0x577c0e30,
+ 0xc2e08af9, 0x989a5629, 0x7bb0e517, 0xf3ce6db7, 0x56afce0a, 0xbce3b6ce,
+ 0x6ed8cb56, 0x2efe7fb1, 0xfea5cd54, 0xbc2172cd, 0x59b4dd2f, 0xdb910e2e,
+ 0x8c836db2, 0x1ac86d70, 0xd7208dec, 0xd7807841, 0x52f583b2, 0x0fa803d4,
+ 0x233cbf25, 0x852acf84, 0xb2cbe258, 0x1a73226d, 0xddd388f8, 0x13fc2ef7,
+ 0x6bdbe5f0, 0x74eabc27, 0x1aa7d3eb, 0x1aa8cedd, 0xbcdea51d, 0xf8f81119,
+ 0xc003a471, 0x827884d3, 0x9f06ad72, 0x97cb3263, 0x9b877fa0, 0x3cbb02a9,
+ 0xd999365f, 0xf563067c, 0xd2dd07b0, 0xd99750f5, 0xf582e652, 0x7bb1fa50,
+ 0x0493d42a, 0x9f3867ef, 0xc25bc17a, 0x2496abd7, 0x9579e00f, 0xfce0e6c0,
+ 0x30d0218f, 0xc0c955af, 0xa6f7809f, 0x8bcf7969, 0x3c7b0682, 0xb17f8bd6,
+ 0x39fa8326, 0xa198fd43, 0xf7cbac9f, 0x324e16a3, 0x9616a3f4, 0x8dfcfde8,
+ 0x595db1fa, 0x37854d3f, 0x2c29e118, 0x0491fbd5, 0xbf6f5768, 0x37a979b2,
+ 0x73c2364f, 0x13f53973, 0xbcc5d53b, 0x1ae7ae0a, 0xb776b03f, 0xed95ef08,
+ 0xb0d763b1, 0x5028be50, 0x0edb8005, 0x17ca1252, 0x0ca29331, 0x8eeb187c,
+ 0x27a1d433, 0x4175e4f5, 0x958813fd, 0x45397c69, 0x9f90bd26, 0x43faa562,
+ 0x85e90a29, 0x5ef06e87, 0x8e20eb83, 0x2ea192cd, 0x11ab477b, 0x14e01af8,
+ 0x60961258, 0x7ff52417, 0xf1ccdabf, 0x217a9050, 0x5f7c18fb, 0x8ecdea65,
+ 0xa635fa85, 0x6f116bfc, 0xe5eb812e, 0x63559128, 0x230b28bb, 0x233ab4fd,
+ 0x085f79ef, 0x00871a9e, 0xbf6085fd, 0x126f668d, 0xdaf8d7f2, 0xc0127c67,
+ 0xcc086ab7, 0x12ba0527, 0x60f8099e, 0xa43d5a3d, 0x69f10938, 0x43be4191,
+ 0xfc6197c7, 0x06ff1a1c, 0xc71ba3c4, 0xbe3fe84f, 0x61927325, 0x897a6b7c,
+ 0x0cab7c61, 0x4fbf03e3, 0xc6d66dad, 0xc0ddfc07, 0x99a134d8, 0x97a4b7c6,
+ 0x65abf8d0, 0x3f186256, 0x5bfc6faa, 0x819efe70, 0x83799fe6, 0xa5e9fe71,
+ 0x7ccbf9c6, 0x5f6ab3fe, 0xa28fc6d2, 0x5e16cff9, 0x2f4ff3e2, 0xf0b7f3e5,
+ 0x77c6fb7e, 0x5effe1f4, 0x8077bf9c, 0x93592df1, 0x5a1ff38d, 0x85bf9c6e,
+ 0xbb545f8f, 0xa15f1b53, 0x3b0917f1, 0x9687fcf9, 0xc5b2f8d3, 0x923e42eb,
+ 0xfdaaa353, 0x81a44f68, 0x1d260c40, 0x0472a6e5, 0x1fa00518, 0x04990a86,
+ 0x9c5143c7, 0x0145ceef, 0x7d4129bf, 0x5120fcc7, 0x352acfa0, 0x9edb2f9e,
+ 0xa59ea32f, 0x376889f7, 0x6d453ff1, 0x6c37ad22, 0x1c3fc5bd, 0x136eede0,
+ 0x5a2f587d, 0xa45f937f, 0xe5db8ef5, 0xf005c660, 0x1c9e5ff9, 0xaf3a1cd5,
+ 0x935172f0, 0x418764f9, 0xbe3c388e, 0x1aa23602, 0x26476be0, 0x9fac1098,
+ 0xc60a3d04, 0x7a0e3b2f, 0x6653cb14, 0x009c8f6e, 0x50e4cb3d, 0xf6e5a9b9,
+ 0x93bd8f88, 0x5bbaf303, 0xc4a4ff83, 0xb9727df1, 0x9ffc47e0, 0x4654b75b,
+ 0x09a8b4fd, 0x7910e98c, 0xd4e8d2af, 0x6fe2dbbb, 0x4e9f0816, 0x243dcfc4,
+ 0x97fd8c8a, 0xde2fd766, 0xddf0c830, 0x486fe63c, 0xd70bf682, 0xc2a21fce,
+ 0xc7307ffc, 0x53ed1632, 0x13548490, 0x354b31c9, 0xa7316f81, 0x15399d75,
+ 0x31ccf72a, 0xb9faec1b, 0x07fd635e, 0xb77ac625, 0xa1366fd9, 0x6044b1bd,
+ 0xfbdfa19b, 0xf5ef8daa, 0x71093671, 0x78daae9c, 0x78722777, 0x2c72c3ef,
+ 0xae89563e, 0x5bfcabf7, 0x87aa9e1d, 0xeb402ccd, 0x43024765, 0xc812fa3a,
+ 0x7caaf35e, 0xdef0e1de, 0x3dbab66f, 0x3ffdcf00, 0xe19f0912, 0x1ebc77f0,
+ 0x1d8136ed, 0x4be1b1d7, 0xe1b7da33, 0xff8709f3, 0xf3e11581, 0xf7d46551,
+ 0xcfe17df3, 0xf3849f39, 0xfe5b5553, 0xed2113a0, 0x3fbe5a2a, 0x7f0844e8,
+ 0x619b6d95, 0xcff12fa8, 0xbc5fb435, 0xfde1be61, 0x8625a6a2, 0x971b0bf7,
+ 0x7df3ea1a, 0x7fb4323f, 0xe1ad4560, 0x8fd57dfd, 0xa0ffde18, 0x3ea19d64,
+ 0xd0d1bbd7, 0x9b399efe, 0xaf4def0d, 0xe513bc8f, 0x915deea8, 0x5671bae1,
+ 0xda38f939, 0xc9156783, 0xb4f8f485, 0xe0e48926, 0xca938d74, 0x5671b6ee,
+ 0xc583d72f, 0x5e9c4c0c, 0x71af9ce1, 0x4665ea32, 0xc2aff3fa, 0xea0f9f05,
+ 0x849c137f, 0xcc83713f, 0x02c2c002, 0xe3e3eb8b, 0x7de4315e, 0x6fde65c7,
+ 0xd71f4100, 0x11d8bdff, 0xf35579f9, 0x046aa1fc, 0xb72821ff, 0xb9d7152c,
+ 0x0f7d6d1e, 0x302e5f7f, 0xc673e84f, 0xd79c9256, 0xb94ceb69, 0xf941f5cc,
+ 0xf402e4ce, 0x40e5cbbf, 0xc6a5f576, 0xa2a4016b, 0x3ceb449e, 0xa401f901,
+ 0x592fc0c0, 0xdceef906, 0x955c1227, 0xaf4013a8, 0xc19e63ae, 0x8133d426,
+ 0x8d77e903, 0x49dc3842, 0xa04b6f54, 0x66b3bd75, 0x1213a0fa, 0xe543c7d2,
+ 0xa87335a7, 0xa5e3593c, 0x094d44f2, 0xaa6bc795, 0x59a8eca9, 0x35c7e541,
+ 0xaa3f2a3e, 0xcff2a469, 0x1e544d35, 0xe540d9ad, 0x2a7e357b, 0x54dc6bbb,
+ 0xba2bf9f6, 0xecd78dfe, 0x80afcd55, 0x67ea8795, 0x43d4b9b4, 0x739276db,
+ 0xf9ca1257, 0x365ce519, 0x8e67e3da, 0x31996382, 0xf9c2be30, 0xba3a606d,
+ 0xf6295ec9, 0xf5c7fd03, 0xe28b6f7f, 0xd899b274, 0xd9a67074, 0xe17fc323,
+ 0x7543905a, 0x16065909, 0x7b0cd724, 0xed617e84, 0x8e5d7a43, 0x9bddcc4e,
+ 0x71e8133b, 0xe5bf99f2, 0xda75bf61, 0x407517fa, 0x059875a4, 0xbd21779e,
+ 0xeb46f042, 0x9aabef5a, 0xfe0cbfbe, 0xd7f0faba, 0xfbfe8e9e, 0xfea54141,
+ 0x985ab4cf, 0x13dc7884, 0x67e607ed, 0xef3f0e67, 0x965c7940, 0x444f5264,
+ 0x565e83c0, 0x4aa864b4, 0x66d3fae8, 0x12699fac, 0x7ad0b7a6, 0x35998cec,
+ 0x554af90a, 0xfa430c4f, 0xf7a95127, 0x56492cb3, 0x9ebc804f, 0xc31596de,
+ 0x5f3f6fd7, 0x12c7b707, 0x485f82bf, 0xf0deffed, 0x0e8fd40c, 0xecad630f,
+ 0x03ea2b13, 0xedf59778, 0xfd2672fd, 0x6c57e295, 0xda1cf98f, 0x7bf8160b,
+ 0x1207e291, 0xab7ef5d5, 0x659f445a, 0x6edf3e34, 0x73be0f18, 0xc5f73eea,
+ 0xadf14bcc, 0xc4864ec4, 0xf169d611, 0x366db2c6, 0xc4aeb8d5, 0x6d55ea1a,
+ 0x9d61aac9, 0xfc807fc1, 0x42416ab3, 0xb8d729be, 0x1a5247a8, 0xdcaf8005,
+ 0xab7ea4e4, 0xc2aede04, 0xe17b21da, 0xa72b5751, 0x9df040db, 0x94ec39ae,
+ 0xac4bde40, 0x7c0201e0, 0xa7232d25, 0x6aeb9ea2, 0x7b444bad, 0xf33c4cb0,
+ 0xf7c22790, 0x8d024d3b, 0xee6fc4b7, 0x1aa3ae35, 0x57e8307f, 0x167e4e7f,
+ 0xd4864e53, 0xcedc4d3b, 0x80f7ef0e, 0xf0e5efd6, 0x48fdb953, 0xfece8de1,
+ 0xfb6caa78, 0x1c92f642, 0x82f2ffc1, 0x57f1d278, 0x401cf26e, 0xedba5a7d,
+ 0x9fa3d918, 0x0fd97d9a, 0xf53f425f, 0x44929f9f, 0x5e7d5271, 0x6129303e,
+ 0x7c5a059c, 0x9ef7f817, 0xfd3d610f, 0x6ccddfec, 0x2ec7c00d, 0x6f782b40,
+ 0x13335fd6, 0xa17d4133, 0x5ad05b56, 0xcfdd7146, 0x2a8edc4c, 0xd1071e62,
+ 0xa1e53581, 0x4cc5d91d, 0x5d4f11d3, 0xb8c76dec, 0x329c3a10, 0x1667a4c9,
+ 0x18ed1a36, 0xf50d7fb0, 0xf58c1bc5, 0x11333662, 0x7af149f5, 0x340bf333,
+ 0xf7fbc33f, 0x7fe12a4d, 0x855eab31, 0xf9a4aaeb, 0x26540b23, 0x157c02a5,
+ 0x6f3679bf, 0x4c5fc63e, 0xe3d10fdc, 0x38e24b23, 0x7ef1a5fc, 0x3fef0dd9,
+ 0xf7771d69, 0x8b06488d, 0x89c6157f, 0x6d730c58, 0xfbf1fd65, 0x870fe16d,
+ 0xfbaf5f57, 0x383469c5, 0xdb826dc4, 0x2f7f811f, 0xeba67c68, 0xd5445beb,
+ 0x8ddc17e0, 0x21bf10f5, 0xb2e2d446, 0xee911322, 0x67d5aa5d, 0x14f7a18a,
+ 0xb4edf7b7, 0xde80eab8, 0x0679373f, 0x4ec81389, 0xed2165c8, 0xd2f26e7e,
+ 0xade14ef3, 0x995bb462, 0x3b45c814, 0xe218d614, 0x07e35953, 0x8b91ca31,
+ 0x833b66f1, 0x6fe81475, 0x9fa0f841, 0xdb92f655, 0xbbc62e58, 0xbfa1de41,
+ 0x87851cc7, 0x94dba805, 0x59fd8656, 0x7cf18c92, 0xaf58d39b, 0x1d207fc2,
+ 0x3f8a3046, 0xc2908f45, 0xa86018f0, 0xe32eed0f, 0x84e851f3, 0x201fdd91,
+ 0x8b10763e, 0x02556943, 0x26cf8c22, 0xfe7d9d49, 0x7bfa2656, 0x2f8a7e1c,
+ 0x2ae5fb40, 0xc5a95f6f, 0x507f97cf, 0x12ee3830, 0x3ceaa8fa, 0x21419068,
+ 0x7fbe3d75, 0x71fe625e, 0x3a6f41df, 0xd10d5561, 0xde4d739b, 0xd40f4869,
+ 0x009f0893, 0x760d78e3, 0x2a1a9a60, 0xf8c20be7, 0x88e1aae3, 0x5dfd0667,
+ 0x2ddef26e, 0xe387f426, 0xea4ffbaa, 0x4882ffd7, 0xfeeabcf3, 0xbfebf587,
+ 0x15ff5232, 0x977979bf, 0xf4a9f80f, 0x803a4f57, 0x5267d999, 0xe80ba253,
+ 0xc1b5be5e, 0xa9f97281, 0x5d2073e4, 0xd38bf33f, 0x16e7c923, 0xb74f9751,
+ 0xff11e422, 0x7e9d1f10, 0xd03bd1e9, 0xd5b73aae, 0x607c52ac, 0x0160259b,
+ 0x5d6caca6, 0x9b63e5c2, 0xafaf18e5, 0xb3f902fe, 0x2fa8cdaa, 0x32785f4a,
+ 0x40cde311, 0x0e7fcd49, 0xb9507f90, 0x68852fe5, 0x5eb15577, 0xdfe17bd2,
+ 0xe3e7f8e1, 0x2f981ec8, 0xaf7ff4c7, 0x6955f3ef, 0x7d6aa978, 0x84910bf4,
+ 0xcdfc83a5, 0x9a25f6f0, 0x68a4ffbd, 0xdf38a78f, 0xf9113644, 0xf307c74c,
+ 0xeebf7b73, 0x8f73a7c5, 0x5b9d3c01, 0xe421ddfe, 0xd727f284, 0x165a677b,
+ 0xe735fcfe, 0x0dd4f2c0, 0xaed4317a, 0x6767d7d6, 0xeca7e69b, 0x39b965e1,
+ 0xb03f40e0, 0xe5d9b37c, 0xfcbeba43, 0xc19e2ffc, 0x1607ccb8, 0xbfe870d7,
+ 0xef83e5ec, 0xb2f500dd, 0xdbf8e61d, 0x211434f8, 0x2a974831, 0x6c62bbf8,
+ 0xbfa50e90, 0x473b283e, 0x8e3fe7f1, 0x6ca3d20b, 0x8d993ec7, 0x298f8fea,
+ 0x0ee4fb2d, 0x5a5d0225, 0x3fa2158e, 0x57e2f751, 0xcfafea32, 0xe0d8175e,
+ 0xdcf8088c, 0x62ec907c, 0x51d113c4, 0xdd1f53a3, 0x0157dac2, 0xeabf505d,
+ 0xff7f0a74, 0xc7fe9a2f, 0xc4399cfe, 0x86bcafcf, 0xb67f28fb, 0x25fe70b8,
+ 0xc0e83caf, 0xaa929c79, 0xdb3f5f39, 0x7186e890, 0x44becc4b, 0xbcfe4a95,
+ 0x121fb9e4, 0xf23e2dbf, 0x7f8a44c3, 0x89b27730, 0x325f056c, 0xa6d16fce,
+ 0x62bf34d9, 0x2bbe25e6, 0xe0f45679, 0x8959e0fe, 0x4111df4d, 0xae24522e,
+ 0x5b354f8f, 0xa7654d70, 0x7dc0e170, 0xff45b785, 0x2dff8a56, 0x0fcaf8a5,
+ 0xb620fdf5, 0xad67ea8c, 0x885f4e9c, 0xac1abefa, 0xbafca13c, 0xd23b7565,
+ 0xf710f4e7, 0x571b8c60, 0xe1a7c931, 0xfd08b843, 0x0da6478a, 0x4e61f4e6,
+ 0x0efb4f29, 0x7c14fdf4, 0xcddbed8e, 0xe1ae5b6e, 0x2331763b, 0x6d72fe38,
+ 0x0a3b807c, 0x8953d5ed, 0x9845ff60, 0xafa4a15f, 0x85576037, 0x7c8857f0,
+ 0xf2df7973, 0x5d6f9708, 0xa633fdde, 0xbebffbe3, 0xbf07e5c3, 0xe0057b43,
+ 0xf7a60c0a, 0xa40966fb, 0x102c2c0f, 0x98b7ae49, 0xbe36b935, 0xe004f9d7,
+ 0xeddd7096, 0x3fec17e3, 0x764ff08e, 0xf87af16c, 0x565f442e, 0xfe8e78e1,
+ 0xbb72e9fd, 0x04ff9358, 0x6cff28c9, 0x81fb9713, 0x8f1f09fd, 0xbffd984b,
+ 0x15e50678, 0xaff713e4, 0x7b365fcb, 0x6f9fde70, 0xbddef03f, 0xb79fa720,
+ 0xd46a72e8, 0x5a72e19f, 0x8b0273b2, 0x639fa724, 0x3924421a, 0xe511e785,
+ 0x3e20e954, 0x4fe947fe, 0x85377f1d, 0x87d74fe1, 0x5c31e103, 0x7459fe1f,
+ 0xf087d446, 0xd7961de7, 0xbe74ff9f, 0xf4adf9d3, 0x29431597, 0xa5f3a63e,
+ 0x7c7d77ce, 0xbf5df3a9, 0x7f01a378, 0x182defe1, 0x3cb80183, 0x4714cdbb,
+ 0xf7c3df28, 0x43bbe17f, 0x4f09e3a9, 0x58c65a6e, 0xf8d4a1d3, 0xac3fbad0,
+ 0xded612de, 0x84f7561d, 0xd586f7b5, 0xcbed0dab, 0x3cc80edb, 0x686025af,
+ 0x8678ae27, 0x1228327d, 0x5fb9fabf, 0xec85fada, 0x7a50be43, 0x4af37be9,
+ 0x3c63b3e6, 0xf148af7c, 0xf1c01e91, 0x67a7182a, 0xf31f867b, 0x3c6c1a24,
+ 0xf6a3d4ee, 0x6c5ed03a, 0xdef5e588, 0xea157904, 0xaf79fd3d, 0x7af5c78d,
+ 0xd88ebd3c, 0xd8edfb10, 0x76f4911e, 0x8f4d9f87, 0x8ac267e4, 0xc1d47242,
+ 0xe3cf7a06, 0x2544d3fd, 0x5fc6057d, 0x8617449a, 0xef6a8a74, 0x419e6071,
+ 0x3bac9ecf, 0x45f3c0e7, 0x8db48a6f, 0x7b7683d8, 0x2dc7920c, 0x77f88725,
+ 0x53df329f, 0xbf7e3193, 0x4579fb87, 0x11ecc36b, 0xa9f896b6, 0xa32e5958,
+ 0xecbf053e, 0x82ff71b8, 0xd6a945cb, 0xe326c95f, 0xdc7bfd7b, 0xbdfb45c1,
+ 0xbdf18b74, 0x34078b57, 0x863272eb, 0x71fcd18d, 0xf4d28f1e, 0xe73134f2,
+ 0x8f4039ce, 0xc322c39e, 0x7b33fbfd, 0x99c7a244, 0x9ebf7ced, 0x23d7f6e2,
+ 0x3e92f77f, 0x89d4f1d4, 0xac0f24f2, 0xfd5f3aaf, 0x9187bcaf, 0x987d766f,
+ 0x3b2833fb, 0xfd907d77, 0xe6ffac5b, 0x590ff4fd, 0x5e53f6ff, 0x493ed1b7,
+ 0xe276ebcf, 0x7fbd9ef7, 0xeb187f4c, 0x9f142dbb, 0xabfd79ee, 0x9e9fe45c,
+ 0xd4129695, 0x80433d77, 0xec1f68fe, 0x83b72afd, 0xa27ad7d6, 0x99251fdb,
+ 0xfe7b47db, 0x8f10b1f6, 0xed0acc25, 0x49a3d786, 0xb35eaa9e, 0x67ad3c51,
+ 0xa17957ef, 0x9d77ff76, 0x7fb6a54f, 0x736763d9, 0xb17c2276, 0xeaa7df7c,
+ 0x5f3fd7b7, 0xad17f98b, 0xf085e4fb, 0xbeefca7e, 0xda3d45c9, 0x43db93b3,
+ 0xe78ee6dd, 0x68ee7f70, 0x6695dcfd, 0x0a3773c0, 0x9bac0a55, 0xa014cf0d,
+ 0xcbc7f4dc, 0xbc271437, 0xfcf47c52, 0xc10f835f, 0xdd9df5cd, 0xde70156f,
+ 0x21fc7f5f, 0x2dd785ea, 0x7cfa97c4, 0x25a96f3f, 0xf372e57b, 0x9c799876,
+ 0x799dffe4, 0x992b810b, 0x3ff328f7, 0x2d7fbd37, 0xe12e8939, 0xcf9fd072,
+ 0xf5443ef7, 0x822eed97, 0xfdf90af7, 0xf9f27ff6, 0xefba6b7f, 0x2e3bba04,
+ 0x7ff2ef3f, 0x4c0f79f2, 0xd7ef37f7, 0x7e62aee8, 0xbeefd54b, 0xadbef821,
+ 0x4ffb5b9e, 0xcd03ef2e, 0xd7ebb75f, 0x994d5c98, 0xaf439f18, 0xc569d601,
+ 0xc311b33e, 0xcc466b85, 0x14ced154, 0xf52bf6c3, 0xfb99af72, 0x5bee224d,
+ 0x086f9c62, 0xcd31f38f, 0x3d2da28f, 0x8a525a18, 0x94958ec9, 0x96bedc55,
+ 0xc06eed5c, 0x176b9acb, 0x887728b8, 0xc5ea3d8d, 0x1764da7a, 0xfcc3afc5,
+ 0xb9817ac9, 0xa56fb005, 0x8c396f6b, 0x84798dfe, 0xa5c96029, 0xab9618f2,
+ 0x59a4b8b5, 0x8f7e0d95, 0xdbac6392, 0x45bac69c, 0x38cacfeb, 0xe624d6fc,
+ 0x38b4f8c7, 0x798abf72, 0x8918e26d, 0xb1b75009, 0x17fa1f26, 0xf7e32496,
+ 0x1ec0311b, 0x5abdcf12, 0xe1f6f63c, 0x1bbb6c71, 0x44d238f1, 0x2e4a6b71,
+ 0xfcb8bc25, 0x8d9e786b, 0x55d788d5, 0x094f88ed, 0x7f6e5ffd, 0x34ccdf91,
+ 0xbad2597f, 0xdc984690, 0xcd3b6336, 0x9d2cbe4f, 0xcbd25d38, 0x332d3a35,
+ 0x43a745d0, 0xe818fa04, 0xdbf9e3a2, 0x2e9c27d2, 0x6fdff8e1, 0x07fe1276,
+ 0x974e97a2, 0x50cdc534, 0xbf9acd5e, 0x49fd1530, 0x1879a7ac, 0xfe6b33ed,
+ 0x66ef1482, 0xea93a43e, 0xf42f4862, 0xb7e002db, 0xf3fb7efd, 0x7aea2714,
+ 0x081dd8e9, 0x456fd94f, 0x75fc0566, 0x00b3b76f, 0x65f92f7e, 0x5b4b43f4,
+ 0x33fb8a45, 0x57779029, 0x6eafbec8, 0xcafd97f7, 0xdd29f34e, 0x06dff169,
+ 0xfaee97df, 0xb0ec9724, 0xd7e4bd95, 0x38125ef8, 0xb91d7ddd, 0x2a5bafb8,
+ 0x9c23ff71, 0x9e65625f, 0x3bb9d027, 0x6dc60e7a, 0xdf3c6d84, 0x1ee5b4b6,
+ 0x7f90c5b3, 0x91dbd666, 0x28bdf05e, 0xc213be50, 0xa9e79a17, 0x2f9d1dfb,
+ 0x36be1c0a, 0x76f31fb3, 0xe8edb74b, 0xe953f8c6, 0xc30b8b51, 0xbedb55d2,
+ 0x298dfda0, 0xd1d97abf, 0x68b6fe41, 0xf3f43f88, 0xc489b7fb, 0x15ad951f,
+ 0x9d4087e4, 0x25b2a2f8, 0x72ebfc72, 0xafd969fe, 0x01f2eef6, 0xfd7ecb0a,
+ 0x5be30382, 0x3ab7dba7, 0x76dfffc8, 0x3f5bb8e9, 0x91e5bf3f, 0xa7f9fa4b,
+ 0xbfe01ff1, 0xc58720dc, 0x220db649, 0xcbe0047f, 0xadef948b, 0xcbd95bf3,
+ 0x38c39f67, 0xcfcee774, 0xcb78439f, 0xe7cbfbff, 0xaf609fd0, 0x88add4db,
+ 0xa5de9797, 0xddfe9e38, 0x9dc7992c, 0x817c5fbb, 0x1fdd9fe2, 0x7f01df80,
+ 0x4a9ef7ba, 0x7bb27f47, 0x1889d7c7, 0x77be592f, 0xef9c60da, 0x0ca757f2,
+ 0x88f41166, 0xfadf225e, 0x1afe20af, 0xad03af4e, 0xe9efc807, 0xdfa37a02,
+ 0x69b717d9, 0x3071e0a9, 0xd9af16a7, 0xddce391e, 0x7ad33e2f, 0x8d379dd7,
+ 0x72ecd2c7, 0xd3882bb2, 0x1c7403bc, 0xdbf4057d, 0x7fe688fe, 0x175fa646,
+ 0xb4e803fe, 0x677e8c2c, 0xfcfd175b, 0x3ad77c19, 0x4d38c068, 0xa6f00ae0,
+ 0x27bfd1c7, 0xa3227fbb, 0x25fced7c, 0x6e90c5c5, 0xbb44c1b7, 0x8e9b3e5f,
+ 0x9a9f0ffb, 0xe7e7ef7b, 0xc62a2c32, 0xbef74a1b, 0xfdd3f24f, 0x538a11ea,
+ 0xdd9e2d33, 0xf0fefacd, 0x5396a3f8, 0xcec5b559, 0xfe1a3be3, 0x74e3fe31,
+ 0xce2d73d0, 0x8f58f9c3, 0xf7140cff, 0xde799569, 0xafdf1e88, 0x16a1f2d8,
+ 0x4bd2094f, 0x3a748498, 0x08fdc976, 0xe22a0f1d, 0x1c686261, 0xad7c7233,
+ 0xd1adde2f, 0xf187e90b, 0x2538becb, 0x6e30d3d4, 0x67de17e5, 0xf741f411,
+ 0xecff1e66, 0xa3ce4736, 0xbf9ae3d2, 0xff53970a, 0x2f33c595, 0xc5b7ff07,
+ 0x52765f8f, 0xea78e1bf, 0x8f5910bc, 0x75f32dbf, 0xc5f7aaff, 0xbe4305ca,
+ 0x7bc9b941, 0xa2b1f904, 0xcfcc98f5, 0x52f3f0a5, 0xb53b7cfa, 0x97ced1bc,
+ 0xad778a44, 0x7a40396a, 0xe85f5c3c, 0xf0e1a6fb, 0xade0d09e, 0x44ebe36c,
+ 0x5fbb4ee7, 0xf73a7e81, 0xae7e26ef, 0xe28c7edc, 0xfdb6876d, 0x5908ee5a,
+ 0xf09d7157, 0xf9dfc087, 0x1e5cbeca, 0xec79e5b7, 0xd19ce3e1, 0x9ed561f4,
+ 0x6d54e3c8, 0x4e30c2ff, 0xe645af99, 0xc7a5fdeb, 0xefb92d3b, 0xb74efec1,
+ 0x79e6199b, 0xa7116e9e, 0xf5173a47, 0xea6eb6ae, 0xbd707ee7, 0x23fd7ca4,
+ 0xf8cc5cfc, 0x1f28a3b7, 0xe991f97e, 0x63c4c61f, 0xfe878409, 0x9f396b5a,
+ 0x9dc4feb6, 0x3d6ef48a, 0xeb88af72, 0x6fc42ed4, 0xf79f9d88, 0x3b14f54e,
+ 0x8fbc85e8, 0x5d91e33c, 0xc4cdf5c3, 0xfc0326a3, 0x5c60ce30, 0x1fa1ea07,
+ 0xf982a73c, 0xe88f086e, 0xf08e9c28, 0xb549aa88, 0x61e7fd09, 0x5e743c56,
+ 0xacd7ef40, 0xb003cf1a, 0xd89ce30b, 0x1e4cd24f, 0x8bbe4c47, 0x3cfd3e97,
+ 0xbf94714e, 0xa059e60e, 0xf02cd378, 0x7d7d927d, 0xe78641c6, 0xde5126bf,
+ 0x78c59676, 0x554bac6e, 0xdfd0267c, 0x596ce4cf, 0xf949d937, 0x4258d707,
+ 0x20580ff3, 0x6f51f917, 0x587defd7, 0x7e1a427e, 0x1a88fd02, 0x7e5a597c,
+ 0x21d610c2, 0xc9bd7da0, 0x0e27cfce, 0xf84de255, 0xbd9af3fd, 0xec3f9fa9,
+ 0xec315e77, 0xcee5e29c, 0xc94fc627, 0x05d43a5f, 0xcf7ab4fc, 0x8f5fcc14,
+ 0x477f27bf, 0x12798aaa, 0xe7829e7f, 0xc85fe257, 0xf50c931f, 0x9c1fab13,
+ 0xc8fff54a, 0xf50e931f, 0x8dff1a6f, 0xca04cbd7, 0x3d582d57, 0xebf22a7a,
+ 0x2cf9cb55, 0xce5188c0, 0x75bc40ef, 0x7bba3e79, 0x1ff31391, 0x5f8e657a,
+ 0x4376c1e6, 0xa5bc7126, 0x40ed1f29, 0x75350d3c, 0xfe7f22d4, 0xb157ef7c,
+ 0x4c9c17a8, 0xaca8fc25, 0xc1fa455e, 0x2f1749a3, 0x9e174791, 0x93eba64f,
+ 0x01f78acd, 0xf991e384, 0xe05ce823, 0xad332533, 0x98cf5f3c, 0x78d4c0c7,
+ 0x469167a2, 0x1ad3844f, 0x58bf8f92, 0x5cfcc9f4, 0xafa6934c, 0x9e38aaa6,
+ 0x2f172be0, 0xe1edf75e, 0x4be7507a, 0xc8695ced, 0x1087c679, 0x7de29f5e,
+ 0xffd092c8, 0x161de33c, 0x9f7c0acf, 0x1d3e7c5c, 0x9f3f5bf9, 0x91ce7e18,
+ 0x48a6bd49, 0x76b35ff6, 0x782071ce, 0x2aef563d, 0x77f3371c, 0x41879dce,
+ 0xc91746be, 0x1ccd4c2e, 0x827c62bd, 0x5215cfc4, 0x4695439e, 0x971324bf,
+ 0xa310f643, 0x8b1ed67d, 0xb9bf46e0, 0xf49541e7, 0x6dd15a77, 0x44f557e4,
+ 0x3e60b467, 0xfcc3cf50, 0x4c66295c, 0xd90d1ca3, 0xbf401313, 0x5ce0e40f,
+ 0x339c1c98, 0x71c673ae, 0xdb3a2e7b, 0x553fa83a, 0xb00c0feb, 0xe0b9e0c4,
+ 0xe5eb911e, 0xc1271a9e, 0xf6f98431, 0xa57efae1, 0x18b56de3, 0xde02fdcf,
+ 0xe8bc405f, 0xc0e5ff78, 0xa3457bf4, 0xe8912bdf, 0x74fe7e17, 0x6bfbc5be,
+ 0xf8aa7f6c, 0x15742ad0, 0x869dcfc3, 0x6a4ab5d3, 0x78ae88da, 0x682f9ee2,
+ 0x36e9d19d, 0x412b857a, 0xe3a0641a, 0xe8efd8eb, 0x10985f3d, 0x4f7e9d5e,
+ 0xfdef900f, 0xcf5f0b07, 0x9c4bc7c2, 0x8de291d3, 0x1060feb4, 0xcf58212e,
+ 0xf8d1e6b5, 0xde3c4d83, 0x10bdbfd3, 0x7fd03e71, 0x30f2a5e6, 0x2fde5573,
+ 0x50fdffe0, 0xf110ffbe, 0xfe22223f, 0x03bc463f, 0xf6c63ffe, 0x4fff8057,
+ 0xdd7f852e, 0xf4d32fae, 0x2bee1942, 0xc5fcff01, 0x13313339, 0x15142dc6,
+ 0x5b25ffe2, 0xd21f6d45, 0x62725b7d, 0xb92c8f50, 0x199f7abe, 0xb3c970f8,
+ 0x9169f102, 0x73fd5e76, 0x784b5ced, 0x1cf15f5e, 0xcbc9e91f, 0x49f9f7e7,
+ 0x336d950f, 0xe410bf3e, 0xc7ca74db, 0x93f3f1f5, 0xe11726a2, 0x68a33ff8,
+ 0xd628a2fa, 0x0e9c2ed0, 0x864daa43, 0x29e4f03c, 0x9f90fd7d, 0xbe726497,
+ 0x3fb5f14f, 0x07c61998, 0xf8fc52dc, 0xbc63e200, 0xcdfb1530, 0xef56e4d7,
+ 0xe30ae86f, 0x33e19f3a, 0x6acbfb9e, 0x1bfb9e34, 0x686294de, 0x4c86cd7f,
+ 0xfe91fbc3, 0xafef0d6b, 0x50d636db, 0x8372d51f, 0xb6e8fda1, 0x4c7d4302,
+ 0xfb4316e0, 0x1a678771, 0xefda13ea, 0x789fb435, 0xfde18174, 0x86a51df5,
+ 0xba7e37f7, 0xa9bf50cc, 0xed0d5ff7, 0x5eb88b03, 0x94935fdc, 0x740ae786,
+ 0x2a5fecbc, 0xbe7c549b, 0xe6a4db34, 0x744f3e86, 0xccb1733b, 0x357fa373,
+ 0xb14cbc90, 0xae85a726, 0x6cccf9cf, 0xac536bd0, 0x55817ac6, 0xe07497e3,
+ 0xcdfe2017, 0xa55ca356, 0x026bcf56, 0x2ca59bb3, 0xd2f94619, 0x58b75f20,
+ 0xc5bb7eb9, 0xedfa657a, 0xaa7f6c4e, 0xece74032, 0x444be5c3, 0xd2a2caf9,
+ 0xcca9fb47, 0x1b96f945, 0x4d3e466d, 0xccaf401a, 0xc3cf1ab3, 0x9b61ea8b,
+ 0xfd139064, 0xd0a8f9f9, 0xdbe2c2e7, 0xa0676f28, 0x05a4e57e, 0x7d016eb7,
+ 0xa97b2729, 0x9aaf9fd4, 0x97988a63, 0x3bf590f7, 0xfa1b49fa, 0x210f4fd9,
+ 0xde92bb7e, 0xccf30a7e, 0x92f5e72a, 0x316c94bf, 0x775825e2, 0x5479e60d,
+ 0x508e7e4e, 0x54dcffe5, 0xae2b78d3, 0x173cfaf7, 0x1133307d, 0x06d203f3,
+ 0xd55e9ff0, 0x4d5cf1e6, 0xc345adc9, 0x14d53fb0, 0x7a45bf7a, 0xfd10aaa0,
+ 0x1e5aa198, 0xc8a653f4, 0xd53f4af9, 0x0a8c19fa, 0x5503ed14, 0xaba0fb21,
+ 0x048723f8, 0x9377f8f3, 0x17c8a7f7, 0xe7b7460b, 0x6ecb73f1, 0xabb24cd7,
+ 0xd75f8254, 0xe78ae943, 0xe92bd429, 0x66731249, 0xf06787f4, 0x06636f3c,
+ 0x338fafbc, 0xf7aa14b9, 0xe59e380a, 0x820d8cc7, 0x5bffeaf1, 0xf7eaf824,
+ 0x3cf94f5f, 0xe29aa516, 0x993cfaa7, 0xc7afdfb6, 0xcd26cf8b, 0xd63c418a,
+ 0x6e77db5f, 0xacfd6187, 0x7ec76de2, 0xd337aecf, 0x8205f5b8, 0x6f3ebde1,
+ 0x741dc369, 0xe15d2b1e, 0x79862ef3, 0x3496dc23, 0x73fd570e, 0xb8234b02,
+ 0x43d2f7fe, 0x8aecbfe8, 0x0dbc6176, 0xe889b1f0, 0x6738ceed, 0xf30f27d2,
+ 0x34a418aa, 0x25fb21af, 0x96fa1fb2, 0x4cdbaf95, 0xf688959d, 0x4635f254,
+ 0x66f5c5b8, 0xc51707f2, 0xe0af942a, 0xd1a159af, 0x55ef38d5, 0x9cef3349,
+ 0xbdd4f00b, 0xfd4c3223, 0x2d347671, 0x15df043d, 0xfcbb46b7, 0xef78fece,
+ 0x01387272, 0x6e10b7ee, 0xcd214371, 0xdc21da9b, 0x33d8173f, 0xde77c819,
+ 0x14ff44e9, 0x977dc313, 0xd3fff870, 0xefc4e3ca, 0x879a5558, 0xeb7c549c,
+ 0x16584196, 0xb51ddc91, 0x7fceb80e, 0xfcebe568, 0xeb08d687, 0xfdeee5fc,
+ 0x7ed39f28, 0x6dd14b08, 0xeadaecd2, 0x197b50ec, 0xec49d6f4, 0x318baf57,
+ 0x7ec5ce3f, 0x3ccbb607, 0x9719d94d, 0x1ed0cbb7, 0xedd3fe43, 0x8d5abfb1,
+ 0x9e886476, 0xb3d34afd, 0x9ea15d5f, 0x4eed80bd, 0x68881bdd, 0x91c824c7,
+ 0x1b38dcf5, 0x2a957fc7, 0x1be3ca33, 0x6d9f9e20, 0x0e1f6c8b, 0xce5d0eb4,
+ 0xd68cc8cf, 0xefd754f9, 0xc560dfdc, 0x9c2fed32, 0x247fe0d9, 0xe329f71b,
+ 0xedde5187, 0xaea4fd40, 0xf10d83f8, 0x886de3ab, 0xc04f88cd, 0xf9c6d3a3,
+ 0x648b69c4, 0x1e03960f, 0x0e3c064d, 0xd903f6c7, 0xdfad5783, 0x6ee78c4b,
+ 0x837c35ba, 0xbc71979e, 0xce3ebbae, 0xe545b8c3, 0xe7a473ec, 0x399c7aaf,
+ 0xf74475c6, 0x011c61bf, 0xd77ddfe7, 0xb7716b7f, 0xd5178a0e, 0x0c4d7abd,
+ 0x0a2aa7c6, 0x9586f4fa, 0xa49985db, 0x5976bb07, 0x576708dc, 0xece7cf1c,
+ 0x10f135da, 0xaf3e39c6, 0x85299c39, 0xaf5d2dd8, 0x4333c91c, 0x8f3b5d7f,
+ 0x209449e4, 0xd17e27e7, 0xfc5c57df, 0x128f3ccf, 0xc7d0273c, 0x0ebe566f,
+ 0xf8f1b7ad, 0xc798d3c9, 0xf7b19a36, 0xfaf963a3, 0x1c7a6891, 0xe3bf479f,
+ 0x7f7ea1f3, 0xc7e57054, 0xdd262b00, 0xab664c55, 0x00a68de5, 0x6e0a8f96,
+ 0xbe55e311, 0x4d3cfc91, 0x911b1652, 0x4728fd01, 0x8e0803db, 0x8dd7a3a3,
+ 0xa7ea29db, 0x0b2c3eea, 0xc402ef14, 0x2baf5c7b, 0x37fc7d09, 0xa1b38d87,
+ 0xe14d215f, 0x7e77b77a, 0x29ef1f94, 0x8fb9344a, 0x6767aa80, 0xc58c2f0e,
+ 0xe68b7ff7, 0xd258f2f2, 0x8e5c2689, 0x38a03970, 0x5a669bd4, 0x710d96df,
+ 0xef822f27, 0xe7884d97, 0x9805e97e, 0x9639c87d, 0x0967e3c7, 0x00b90714,
+ 0x14e78178, 0xb53e02fa, 0x3317cc4b, 0x89b0f416, 0x0bf055b9, 0xee4293ec,
+ 0x68ffc1d9, 0x4d60fc76, 0x4d38f6ff, 0x45e0333e, 0xd5db1976, 0x5c0cee09,
+ 0xfc81774f, 0xb4fa030d, 0x7ca958d5, 0x184d46ad, 0xa7b8f206, 0xafea8926,
+ 0x0ca938d7, 0xe7a08cd4, 0x545c6bfb, 0xa7b5368f, 0x552c7ad3, 0xfe879baf,
+ 0x0b12fdf5, 0xbc23b7bd, 0x8e567bc4, 0x97f9c887, 0x0093e62e, 0x3d352fae,
+ 0x38d6fb52, 0xc6a7afe2, 0xfd31d400, 0x8ad9ffbf, 0x054d643f, 0xa3fa983d,
+ 0x415359c3, 0x78129f8e, 0x181e02fe, 0x552e748e, 0xb7329f2f, 0xf0a9a2c4,
+ 0x4df31b6b, 0xc8bcc24d, 0x8e153fde, 0xe8f6cc61, 0x1d4ea69f, 0xfdc7f309,
+ 0xf6c614fe, 0xc7abdeda, 0xfba9d873, 0x818bab3f, 0xfc6dc8f9, 0x82899f3e,
+ 0x7d4056a7, 0x0bf39b33, 0x98b53c93, 0x3773d9cf, 0xbefee273, 0x1b5ece3e,
+ 0xdb7613b7, 0x51399db8, 0xe6c1fce0, 0x411e5aca, 0xbae86e6f, 0xef3ede11,
+ 0x8f74d7c0, 0x2fb78c0f, 0x2f5e30d5, 0xfa0711c5, 0xd7ff752e, 0xe95c8eb4,
+ 0x491f3d77, 0xc4847cfc, 0xe6ba2bf3, 0xfda66e26, 0xba1f6878, 0x4723da8f,
+ 0xd2ded7b6, 0xed0681d6, 0x659fb7be, 0xa68372f0, 0xf5c62457, 0x05d16bff,
+ 0x61b947bf, 0x5fda38de, 0x09e2d3aa, 0xe57a3a93, 0x2f7e76f9, 0x13d43e5c,
+ 0x3c04784e, 0xd1a5d70f, 0x1e605533, 0x6048ffcc, 0x28028433, 0xdbcf36dd,
+ 0xc2d24fd8, 0xd197be4d, 0x7165d85e, 0xe3a3d9a2, 0xd903eeab, 0x6121fa8a,
+ 0x8fda31cf, 0x643a13aa, 0x8f97f7a4, 0xcb714d7c, 0x3275733a, 0x1b176dd5,
+ 0xbdb4feb0, 0x99d6237a, 0x6fa9ebef, 0xd60c3f00, 0x13e3e1ce, 0x90bb63d4,
+ 0x3b5829e8, 0x7e06ef57, 0xf5e665d8, 0x4b391f2f, 0x5ccbb1fc, 0xe18d9f3d,
+ 0xef987af5, 0xaa6f58ae, 0x52905409, 0xe1fd65fb, 0xb7aeb09b, 0x77da92ff,
+ 0x3f6e54db, 0xa40cde2a, 0x855d5f7f, 0x2ea43dba, 0xf2b33af1, 0xc55f9f52,
+ 0x7f29af81, 0xe70f72b8, 0xce1bc447, 0xc3cdef13, 0x7a8ce975, 0xa4eb51d4,
+ 0xd73673b8, 0x9f0301d7, 0xb753e7e9, 0x2a2cbc98, 0x085ecf44, 0xce42ff5b,
+ 0x84a8b1d9, 0x38b4fe90, 0xbb033a76, 0x6f182b34, 0x2a2e64cd, 0x950f3187,
+ 0xee96dbd9, 0xbb2db447, 0x7a89d5af, 0xfad73e2b, 0x68e89780, 0xd09e1ff4,
+ 0xe8fae2f4, 0x01a31bfc, 0x7782f59e, 0xf17a888d, 0xe74ab365, 0xb2243a2f,
+ 0x35b53b37, 0x5330ad8c, 0xf73b5cbd, 0x5de95e6d, 0xeef51233, 0x19ab9322,
+ 0x4f0cb3d7, 0x2fbe19be, 0xaae19ddb, 0xe7bcc165, 0xc496d8b2, 0xef304ab1,
+ 0xaa3faf59, 0xb546d9f1, 0xd2f786c9, 0x9543fbe8, 0x71d2eb6d, 0x7db3fb7f,
+ 0xbd3c901f, 0x7c41951f, 0x447ad15c, 0xbf69daf6, 0x29f3c64c, 0xd6fad99f,
+ 0xbef75a3f, 0x0b74196c, 0xeb2ff5ea, 0x79b8744d, 0x06f43d20, 0x38373fe8,
+ 0xac6a87c8, 0x5dc2fe54, 0xde9a2d7d, 0xd3295105, 0xbfb4606c, 0x9156e990,
+ 0xb9ade68f, 0x7c0ac1a6, 0x8eac82f4, 0x179b3e44, 0x5b7c4b95, 0xbe722b16,
+ 0xdd07b964, 0x0dcfb692, 0x6535d4f5, 0x3c53bed3, 0x6f68c8be, 0x88526d54,
+ 0xc80ec00f, 0xdca83e47, 0x7ee1f260, 0x4edac9a2, 0x45e77de7, 0x368fcd31,
+ 0xaf5c4f9e, 0x6cdf3be9, 0xdcbddf1e, 0xf392c539, 0x511e7451, 0xe51fbfaf,
+ 0x9128be24, 0x55ffb47c, 0xe741de72, 0x38fbbf18, 0xc879c356, 0x0428e3fe,
+ 0x794e3e87, 0x57d21c70, 0x27ec1fe5, 0x6b8df83f, 0x4dd67b75, 0x3be5ac71,
+ 0x9b05fcb4, 0xf3f6307b, 0x1827a6b4, 0x7780b1fa, 0xeeafa329, 0x1ccf4093,
+ 0xf933d3ec, 0x90d3530d, 0x6cf7c1be, 0xb90f4192, 0xc1d3a025, 0xfbeead28,
+ 0x51f6e47e, 0xf533ed61, 0xa986ccfa, 0xf3c3fb93, 0xb7582db4, 0x1be97b42,
+ 0xe11d5f4b, 0xa1f573a3, 0xe3e9c5fd, 0xe9fd4bdf, 0xb51a97fc, 0xf80fa0f0,
+ 0x27ac60ef, 0x7a7cf31f, 0xca273367, 0x8d4966e1, 0x21d08572, 0x37af8a35,
+ 0x35afe725, 0xf7883fe0, 0x4ffd035c, 0xfb0d38d5, 0x968b8b8a, 0x549879d1,
+ 0xc7cc5e9d, 0xca6d77cf, 0xfe27ec32, 0x16ae387f, 0x7000f70e, 0xc307fd4c,
+ 0x5e30c231, 0x031c8e10, 0x870b577c, 0x7a6b3b18, 0x8f6bda06, 0x280f2898,
+ 0x66b3e4d1, 0x6ff65da2, 0x0ca78a26, 0x880f3c67, 0xfb0de329, 0x2c7b99b4,
+ 0x9efe31f3, 0xd2c3b129, 0xb7279458, 0xa9d716b3, 0x5f64489f, 0x39ab73c1,
+ 0x726e870e, 0x204ffde3, 0x665fd495, 0x1f82b7b9, 0x82fbe6f2, 0x70d33efa,
+ 0xbde3e595, 0xe7a39ba0, 0xfb8d18df, 0xaa1e7366, 0xe7983cc2, 0x352ff195,
+ 0x92bc8330, 0x2c20d21d, 0xabe33b25, 0x701b87a8, 0x147076bf, 0xf6045bb7,
+ 0xe4e1c370, 0xbcb9ef48, 0xf0f35b9e, 0x341b8c34, 0x8b5e74af, 0xcdb353fe,
+ 0xf31fb2df, 0xe8531e76, 0x47acd6de, 0x50998dfd, 0x6899d717, 0xfd6314bd,
+ 0xdf719adb, 0x176cc9fd, 0x68cd11da, 0x47fb60bf, 0x566bf214, 0xf0d338d5,
+ 0x6d3a927e, 0x76b2d81d, 0xc1798ab2, 0x87148af5, 0x732addeb, 0x773c5cf5,
+ 0x8dd1ee31, 0x51ebd60d, 0x071ab98f, 0x949ebca9, 0x339aeb8c, 0x7b463ad3,
+ 0xae68c80f, 0xb1a8a675, 0x6ff0fac1, 0x3d20fac0, 0x9dc1b1b3, 0x2b2efd86,
+ 0x883bfad5, 0xe2178a71, 0xef68bc34, 0xd2f4fb33, 0xcbcc06c6, 0xf5836b12,
+ 0xaddf30a9, 0x353d72cf, 0xfb47fa18, 0xc3e3e60b, 0x877b057b, 0xca4e744b,
+ 0x603b6306, 0x9991b67e, 0x0cd7dfb4, 0x2bef117a, 0xdfc91dee, 0xf234fbeb,
+ 0xd3ed1370, 0x6f5c7b60, 0xbdbcc96c, 0x57df833c, 0x8a15db20, 0x307ac037,
+ 0x149ef315, 0xf371ffa6, 0x8fb6a4b8, 0x01f78511, 0x75a3f084, 0xf73a32ed,
+ 0xdc661d69, 0x8cd3979f, 0x16798975, 0xaa27bfa0, 0x4637e7c6, 0x8341f96b,
+ 0x6dda0a58, 0x133e4dc3, 0xfcc91bb6, 0x02c75e54, 0x628d8f64, 0x8d1f541d,
+ 0x1e16635e, 0x41d2725b, 0x2dcc71ab, 0x47aa38f2, 0x71313b44, 0xf2471eae,
+ 0x74be414e, 0x61766b47, 0x7e3fef0a, 0xf7ca2cc6, 0xcdef69f5, 0x313d8633,
+ 0x7eb5e60d, 0x50ceddc6, 0x2f5f4efb, 0x48adfb75, 0x68cbf983, 0xa0bda221,
+ 0x364575db, 0xe5984f5e, 0xc6147a7e, 0x26cddb11, 0x58ad9fbc, 0x6f16638b,
+ 0xbb444fc8, 0x5cdf68ac, 0x44d787b2, 0xd16cbb73, 0x77b219fa, 0x9af79e14,
+ 0xfe7f764f, 0x183109ba, 0xb9b06fa7, 0xfe47ae62, 0xdfbf23fd, 0xb1ed4af5,
+ 0x0a6bc4e6, 0xc19b1e50, 0x8ffbc6af, 0xcadd9a0e, 0x758be418, 0x6ccec8c3,
+ 0xc7d6f28e, 0xffcdbf42, 0x41d574ea, 0xf73667fd, 0x4e3823f8, 0x8f7f1443,
+ 0x6f2126f7, 0x3ff7edf6, 0x1e8c5c2f, 0xfdf0fc78, 0x91b183fe, 0x43bdf1ef,
+ 0xfed05fc3, 0xd9dd90f0, 0xdcc4f660, 0xcbbdf087, 0xead679e7, 0x112f5189,
+ 0x86b4fb67, 0xd67603e7, 0xe64058b8, 0xbd62d1f7, 0xdd3f68a4, 0x22d25caf,
+ 0x097cdc50, 0x3a3d226b, 0xeed5894c, 0xc5e631a7, 0x4dbd1696, 0x795b4bed,
+ 0x42d632fb, 0xe17a75ed, 0x8301b5bd, 0xf0ce3a1d, 0xdcd11dfd, 0x78acdd6f,
+ 0xfffb431f, 0xc4d91991, 0x1167c04f, 0x07e22df3, 0x31b977d8, 0x371faf9a,
+ 0xf6c8db62, 0xb863f128, 0xe05cb87d, 0xc207b3e7, 0x9379d553, 0xde0a3d61,
+ 0x7ad3219f, 0x49f9add4, 0xeb7c9387, 0x7ff9846f, 0x244af59f, 0x23bddaa7,
+ 0x425f8275, 0x33befaf9, 0x2d1bdeec, 0xa6ba680f, 0xcb43fe25, 0x6b3ef9ef,
+ 0xfd0dc379, 0xf402cedc, 0x9eed61dd, 0x48a41412, 0xafd01979, 0x3adc1f41,
+ 0xddbf58c2, 0x39dfac65, 0x7d3df229, 0xb4d46b6b, 0xd6aa7bd0, 0xf38e700e,
+ 0x575e8d2d, 0x0b12df7f, 0x0b7bebcf, 0xf9815ee9, 0xc17fb494, 0x1b14faf3,
+ 0xd91ea0f3, 0xfb46cfbf, 0xbc8a5521, 0x55164319, 0xbde2efe0, 0x9f9d8af0,
+ 0x17ff4037, 0x998a05e3, 0x97de0fb7, 0x1251f7c4, 0x3c5a493c, 0x633495c3,
+ 0x1b87b7d4, 0x0bca2afd, 0xdc46d896, 0x27e60d77, 0xe8edef1a, 0x0f38fe8a,
+ 0xcf9863fd, 0xe84f8c6c, 0x3e7d5a71, 0x2c7f28ff, 0x39cfbb5a, 0x346b6e9c,
+ 0xa30ba8f9, 0x39d23d73, 0xb973df07, 0x87bb52f9, 0x43c129ff, 0x26896879,
+ 0xb3ac171e, 0x9c528eb9, 0xea0ff344, 0xf306b8b4, 0x56ef5d7d, 0x1095ecc2,
+ 0xed7d22ff, 0x39f5f5d7, 0x38f377e4, 0x156a2d88, 0x360dc3ae, 0xfaa66ebd,
+ 0x00a6e6d3, 0x5aaffdf9, 0x831f189c, 0x6718ddef, 0x411dcdf3, 0x065d5d7e,
+ 0x0e7bc14b, 0xb4cbb0de, 0x6abdd6fe, 0xd8f5c669, 0xdb76f36d, 0xba49f242,
+ 0xf9d1efec, 0xf9fd08a6, 0xf90dfd0c, 0xf8c1fd76, 0xfd7788ad, 0xa7f61bfd,
+ 0xceff2202, 0x691bf949, 0xa17b1fed, 0x42cbb89e, 0xf7fd4f71, 0xe7cfca0f,
+ 0x7a8cfdd1, 0x4e14137f, 0xd51ace87, 0x8e5d8f90, 0xe507377a, 0x67f49da0,
+ 0x8320cb45, 0x69f5d4de, 0x681bf9c5, 0x57482cbf, 0xb5212e2d, 0x38aa5e93,
+ 0xbc68bfff, 0x349e903b, 0xf7e9124e, 0x3549c781, 0x38e0e3e8, 0xf7700c93,
+ 0xc132671f, 0xdac38fa1, 0x9fe70ca2, 0xae3ccceb, 0x33986672, 0x1e823626,
+ 0x83714bd1, 0x60ff70c9, 0x62b2e49d, 0x4eca75ff, 0x287f3435, 0xef005f7c,
+ 0xf02164c5, 0x867ac1d5, 0xf30b72c1, 0x3d405e52, 0x072213f6, 0x62a5d9a2,
+ 0xf8c262bf, 0xc62ef9e9, 0xbdb945fe, 0x33727d10, 0x8bd82df2, 0x7e3b583f,
+ 0x49ec0f95, 0x4769ecc9, 0x93764aba, 0x6b68f313, 0x45c51315, 0x64ac92eb,
+ 0xca12adff, 0xbd739455, 0x2243a95f, 0x8f7df438, 0x9f29e681, 0xc33cd077,
+ 0x9ffb3bef, 0x76a14f1b, 0x3b57eefd, 0x0f93d730, 0x93545bfd, 0x4e5d450b,
+ 0x2127d853, 0x47ef0ff4, 0xec4520da, 0x8e9dbc27, 0x6ce901ff, 0x3d2070ee,
+ 0x88a5e3ba, 0x951b1079, 0x310798ef, 0x271f4c2f, 0xe00ecd1c, 0x238742f7,
+ 0xe5f48323, 0xa5f50546, 0xdc9fccfd, 0xb4cbd24e, 0x7fafadef, 0x56a984e6,
+ 0xbc6c4f9e, 0xfe206f57, 0x7d62f1d3, 0xf3c641f3, 0x7f94bd53, 0x483c3972,
+ 0xfb43cb82, 0xe2297600, 0x425836be, 0x4938fc86, 0x354fe631, 0x63e21e48,
+ 0x56d54df3, 0x5b4927da, 0x927dc569, 0x063392d5, 0x37ded8fd, 0xf983fec1,
+ 0xbe793a35, 0x6bff786a, 0xb4661ef0, 0xc4531573, 0x06a379fb, 0x34baafb0,
+ 0x77d9acfa, 0xf501fe69, 0x3775c1e1, 0x71524e2a, 0x399b35dd, 0x4bad03bc,
+ 0xe103bf7a, 0xfc7dd1eb, 0x392c1bf7, 0xffae3f56, 0x4a35e3e1, 0xbc3e4f1e,
+ 0x7078046f, 0xcd31acdf, 0x546df84d, 0xd5fd1525, 0xcc5111e8, 0x656fea1a,
+ 0x67f7a2cc, 0xccf1e3e2, 0x8f8c6b22, 0xe3a3979c, 0x1df2b769, 0x186f1ded,
+ 0x8f7f0e5f, 0x7c21e8e2, 0xe84ca9d9, 0x91bb97cf, 0xfc381317, 0x5aa6f7a1,
+ 0xbc458633, 0x7f1fb27f, 0xde4df186, 0xf7e74664, 0x19b94306, 0xeed56efa,
+ 0xb5c0aa43, 0xf2f4fc0b, 0xc2a6147b, 0xe477e6fa, 0xc939405f, 0xcfcfdf6b,
+ 0xf026b4d1, 0xefb51e7b, 0x625dc7c3, 0x12c8fee7, 0xcc654abb, 0xf12ff751,
+ 0xdb5a37f7, 0x5e789ca3, 0xb22e35b1, 0xd763931f, 0xb49a68f3, 0xb41d0873,
+ 0xcfb7a14f, 0xcddcc79b, 0x1b3dc50a, 0x257fe0ad, 0xa9ffb5f4, 0x82023fb6,
+ 0xf9dce30b, 0xf99aebdb, 0x7f3e51f9, 0xfb62ab8c, 0x5c8ec4c4, 0x740efc41,
+ 0xf70cc6db, 0x3b5855db, 0xe7ce51b2, 0x7699bc9a, 0x68eaa718, 0x5bd62247,
+ 0x4e9d3edf, 0xb71d6f7e, 0x47777b37, 0x3fa0dc53, 0x79f96a7d, 0xcc29f3f2,
+ 0xdd3fa837, 0xad00a5ca, 0xd3e7e5ab, 0xcd1c6f99, 0x0b8d67db, 0xc2d3bfbe,
+ 0xc8b1a4d8, 0x884f1c00, 0x30f4489f, 0x7a064ddb, 0x675e3c80, 0x7881e8d7,
+ 0x76b7a3ea, 0x76a74bef, 0xcd71e0bf, 0xf72a615f, 0xa5fbf5d7, 0xe5f7678e,
+ 0x5b7dd05b, 0x13f736e5, 0x3b0b4f78, 0xe6be5222, 0xfefc29c2, 0x771685c4,
+ 0x0b57da0c, 0x6a1453ff, 0xf3937f69, 0x7f0d22fd, 0xf745cc9d, 0xdad6f80e,
+ 0x984ebef8, 0x54f1967f, 0xc23fb8fe, 0x44da8bf7, 0x305f1bca, 0xbf61f145,
+ 0xbf05ed79, 0xe2f9fdc4, 0x773a68c6, 0xae7bf0be, 0x2dd76893, 0xc4e6c27c,
+ 0xfe597bdf, 0x327e6641, 0xc9fcbbf4, 0xdf07d50c, 0x24f0af45, 0x27a05d59,
+ 0x8853db1f, 0x3083457e, 0x0630be7f, 0x0ec7cafc, 0x98b8c2ac, 0xcf94cdf4,
+ 0xf47f506d, 0x615677b1, 0x18b7e9bc, 0xf63b26e7, 0x63b442dd, 0xf4d0425f,
+ 0xc1c03ffd, 0x5a4d874b, 0xa9aac4fd, 0x4daff2a0, 0x2a293568, 0x562765fa,
+ 0xc4d939e1, 0x1318f738, 0xfd8ef78c, 0x6fec42b3, 0xcea313c1, 0xe7f7806d,
+ 0xbec817ed, 0xdf693a00, 0x014f370b, 0xb278bbbb, 0x582d975e, 0x86668f8f,
+ 0x3339be38, 0xd9da3e38, 0x8b7c7aad, 0x718cdd45, 0xd505e3f7, 0x3fe82453,
+ 0xceaea1c3, 0xc4d8c919, 0x1baaf9f5, 0xc476cfc6, 0x98f18cdd, 0x837dbed6,
+ 0x1f18d5f8, 0x03de656b, 0xd37f7866, 0xb66e43e3, 0x07e36202, 0x30a8c679,
+ 0x29d641ff, 0xf4dfa7ab, 0x4463e41d, 0x0d59f3bf, 0x939204f6, 0xf4d28843,
+ 0xc2defc15, 0xe34ef93e, 0x1f57db7c, 0xc3cfc1d1, 0x5e24f5e8, 0x59195d6f,
+ 0xc312dc5f, 0x2a35baf9, 0x4d66fbf2, 0x03be003f, 0x8b6d7f14, 0x08cf0ff6,
+ 0x1f900fea, 0xa79224eb, 0x807f5c75, 0x93b4cd1c, 0xefec46dc, 0xab6bcadb,
+ 0xab79af76, 0xf8c68ee4, 0x30c7ae82, 0xcce38682, 0xfa0d3bb5, 0x017daf39,
+ 0x3151d7e9, 0xc9c7872a, 0xc53093f1, 0xb59847a8, 0xdf743b3d, 0x3cda77fe,
+ 0xe3d3ae33, 0x7439013f, 0x8ef969df, 0x9f9e4bfc, 0x7f38c72d, 0x9c1dbd88,
+ 0x678a54c7, 0xfa17ebf4, 0xbbfd6a73, 0x5f04ae72, 0x15f065ea, 0xdcbaf84f,
+ 0x19fd833c, 0xfbfd2fe3, 0xc17db593, 0x223ae326, 0xa4f38647, 0x7f8027ce,
+ 0x2cfe8853, 0x9ea9f4d6, 0x6bbdd107, 0x064fe524, 0x31e7e5c7, 0xc4bfbe81,
+ 0x81f25ddf, 0x963d453e, 0xc56fb927, 0x71ed79f6, 0xc0efda2a, 0xbf1af56f,
+ 0x3a6fc849, 0xaae35b9d, 0xebbe69f3, 0xfa4bb204, 0x3ada41d9, 0xd024d79a,
+ 0x9e0d99ef, 0x87e715e7, 0x7beba7c0, 0xeb55bfe8, 0xe7e73c7f, 0xf9f8fb67,
+ 0xcd1f943e, 0x0eae679f, 0x1c3d5fba, 0x732885fe, 0xd5eb2109, 0xeb8a36ab,
+ 0x5abb78eb, 0x85edd7fe, 0x25d701f2, 0xf8377d07, 0x84e1c068, 0x1e518b76,
+ 0x7cb55f50, 0xb664f742, 0x7f0c89b6, 0x8de700b2, 0xd74f237a, 0x8795be93,
+ 0x5bb2240a, 0x49d97a82, 0x37ae8bf6, 0xb06b5603, 0x2bb5b9fd, 0xaf51eb0b,
+ 0xc7ecf76a, 0xc7c5a08b, 0x7348e106, 0x9277bb70, 0xddfc4597, 0x5dbb1cb8,
+ 0x8f3423d7, 0xe80a2b8d, 0x6d2a855e, 0xe1d49d3d, 0x345378a3, 0x104271e2,
+ 0x7d7afa1f, 0x15e3a5a7, 0x8197bced, 0xd83af51f, 0xaca69525, 0x7ef8ff60,
+ 0xe7df0866, 0x841f3839, 0xeabbe7d3, 0x0f83c027, 0x0d43f0f1, 0xc75009ef,
+ 0x04982d7b, 0xfde617eb, 0x6b5c50cc, 0x56e04232, 0x104e3eb8, 0x5d8f5c4d,
+ 0x07e22e46, 0x58f7ed31, 0x41cf24ec, 0xe5bb707c, 0xe7168701, 0x3f29eed5,
+ 0xa1390268, 0xcf3e367d, 0xd4c95dee, 0xddad6cef, 0x6f2f4bdf, 0x7496f2d6,
+ 0xb5e2b17b, 0xf846cdd4, 0x1cbb7f79, 0x47792f1c, 0x8ed063dd, 0x5c51ee19,
+ 0xb5e41fe8, 0xf98fdccf, 0xf07bd924, 0x7c820407, 0xe5c2dd9e, 0xc34bb814,
+ 0x43db9bcb, 0xd874adfb, 0xbbfb3975, 0x28fb23cc, 0xcba457e7, 0x5a72217d,
+ 0xbe3850e3, 0xc4167e60, 0xa3d464a7, 0x83f7f97a, 0xcf1fb3c3, 0x3e039525,
+ 0x78eb6d50, 0xbf996d6b, 0x7c7286d2, 0x8e50b994, 0x9be65bbb, 0x315d2146,
+ 0xa219cc11, 0x79f3d61f, 0xf02876e8, 0xe5f20b65, 0x1a10c73a, 0x7751f86f,
+ 0x1fbc0e74, 0xc613768e, 0x7eec5b7d, 0x0efc23f4, 0xe2072eef, 0x14ef5673,
+ 0x8cad4fdc, 0x85b5aeae, 0xdf6bef3c, 0x8f89ed06, 0x1fee22bd, 0xf8c03f95,
+ 0x7cdaf1bd, 0x02cfa9a0, 0x20c855e3, 0x0f5459a7, 0x655ade20, 0x3ef7bede,
+ 0x5611a5fa, 0xf97bf229, 0x95befd60, 0x536df3f8, 0xfd17d21c, 0xcb93b424,
+ 0xee1a4f45, 0x16c1b27b, 0xe003ae17, 0x1fbf1077, 0x06c931b4, 0x4a1efffd,
+ 0xc4d3d3d4, 0x6b8e74a5, 0xfb40965a, 0x8f7fba44, 0xa4fd0b7a, 0x4d17bf3b,
+ 0x3c2ec8fc, 0xd3e30c38, 0x4e9cd109, 0xeb558fd0, 0x1b1d6ac7, 0x48ffbf94,
+ 0x8efe491f, 0x141dbebe, 0xe0e7ea04, 0xd735d74d, 0xd841f885, 0x83ffea1f,
+ 0xa5b48cc2, 0x1f9affc8, 0x7c61f647, 0x7b45dd70, 0xce21ac65, 0xebe0d3e6,
+ 0x0a3e4748, 0x3ed147b5, 0x7d67b3ed, 0x0cdf57f3, 0xf4e2767a, 0x715e0096,
+ 0x6e8acb5f, 0x6fe817fe, 0x36b3d81a, 0x8d3ec3c0, 0xf8660e2f, 0x3d4fdc44,
+ 0xfba05c38, 0x79450fdc, 0xe095aa73, 0x5c5a8938, 0x33cb5120, 0xe5e28c4f,
+ 0x1eb8620f, 0xaf863cfc, 0xbca837d7, 0x1c88e89e, 0xbdad9847, 0xeb89a9ff,
+ 0x91f935f7, 0x684fd1f3, 0xedaaf5fa, 0xfc211cde, 0x8e13eebe, 0xdd7dda09,
+ 0xe3c76f94, 0xfe340bfd, 0xe8873b06, 0xf8abb414, 0x876e9d7e, 0x4d9f6d9e,
+ 0xf78213f5, 0x2c047bbd, 0x9f904f3d, 0xf148aef4, 0x6f58e2a1, 0x55a5e622,
+ 0xcb8e4544, 0xf4f0d20c, 0x38a30d59, 0xcfdc29ef, 0xb7bfe6cb, 0x1b25f585,
+ 0x1d7ba49e, 0xe29f994a, 0x1a1b45bd, 0xc8aebf68, 0x80a7302f, 0xc78799fe,
+ 0x943a3581, 0x710d116e, 0xb552c5e7, 0xe4139b1c, 0xae1dfc5b, 0x9b25f7d0,
+ 0x57ea19c6, 0x1816976f, 0x7a823bf2, 0xbfec90a7, 0x3e757ef0, 0x8f4fb70f,
+ 0xf10d38d7, 0x861b05ee, 0x78cdf217, 0x73217ede, 0x36177cd1, 0x11ef1966,
+ 0xb2b84c6e, 0x1ec1827b, 0x538445f5, 0x3fa8fd26, 0xf7f80e3f, 0x17f7c485,
+ 0xe08c3a7c, 0x7bc38bf8, 0x8e018c5d, 0xc433e668, 0xdff326cf, 0xf8f1b429,
+ 0xef8ff023, 0x7e407652, 0x07f577cc, 0x1fc01dae, 0xfa87fdc8, 0xb9937903,
+ 0x024d65fe, 0x9c4ce0e5, 0x66cfb46a, 0x6e75f0c7, 0xc1b44c76, 0x679a2b3e,
+ 0x6b57376c, 0x776b5737, 0xa84a38b9, 0xa164265d, 0xe9fde33e, 0x71951fbf,
+ 0xffca6dfa, 0xedc310dc, 0x6eaa9fd7, 0xbbf40c6f, 0xd0773b56, 0xefdade6f,
+ 0xf735ad4a, 0x5e5285e5, 0x1e6fe6e0, 0x09dfc3ac, 0xf601dde9, 0xfcc1e83f,
+ 0x7ba0df67, 0x6eeff4ba, 0xb432d15f, 0xa954f008, 0x8bb973c9, 0x15dcafcf,
+ 0x3f418790, 0xae1ce529, 0x827d96b4, 0x5a5df214, 0x22b76f09, 0x2ff06cc6,
+ 0xffd5a27f, 0x6549c635, 0x1840495a, 0x3652ed06, 0xec24116d, 0x0b577f0f,
+ 0x66a949e0, 0x93dfd0fe, 0xedcf194a, 0x6fc7db9a, 0x04e61616, 0x9a68d0f1,
+ 0x5c62a391, 0x85da3135, 0xaa47cceb, 0x50f10eb7, 0xce8051fe, 0xa8fc4c49,
+ 0xbdbb425d, 0x23d7755b, 0x7078eb7f, 0xae0a6a8a, 0x711fd1a3, 0xfcfa9b38,
+ 0x30bebe62, 0x4766a8f6, 0xe976eb37, 0x42edc661, 0x5712a75a, 0x3efc308e,
+ 0xb69c6261, 0xef32244e, 0x37da854e, 0xa327a232, 0xccae24f9, 0x2c76e66e,
+ 0x2cb4f7a7, 0x3e7c16cf, 0xb1c8f06d, 0xd647df78, 0xbf8480da, 0x26dafe3b,
+ 0x51fbc453, 0xc3fc359a, 0xf9c59e3c, 0x9cb8f3e9, 0x99dbd05e, 0xe84f8807,
+ 0x3d3d10f2, 0xd8c1dfb2, 0xff3ef4e3, 0xe97bf8d9, 0x997acafe, 0xc74e4f7e,
+ 0x69eab77f, 0xb4a6bc41, 0x3708166c, 0xdc7a78da, 0x5ca39f0e, 0xe78d971e,
+ 0xfb94073a, 0x16873b15, 0xbd7dca85, 0x1cd9f44c, 0xdbafe796, 0xe1887ff7,
+ 0x5890eaeb, 0x4bc43ecf, 0x8a3adb65, 0xc2d92cef, 0x4067f77f, 0xfe215cfc,
+ 0x07ee1284, 0xfbe1cf94, 0x4acff95e, 0x7ab2ff44, 0xe5acfbfe, 0xb8f077db,
+ 0x0b998fce, 0xcb7943f5, 0x0728a10e, 0x8773077f, 0x9f0428b0, 0xca7ee5a9,
+ 0xaec6bf83, 0x5bd71fcb, 0x718efce1, 0x0e53b462, 0xe87eb8d9, 0xb87c57cc,
+ 0xf669dc1f, 0xcebb6396, 0xe61768e4, 0xfff8e977, 0xe99b8efd, 0xa77db5dc,
+ 0xa3658025, 0x8ac939a9, 0xcad70efb, 0x6eabe42e, 0xe9127bd5, 0x5a792713,
+ 0x78d8fbf1, 0xbe16abbb, 0x58d85a75, 0x3c72b955, 0x8fe30c4c, 0x72e63f89,
+ 0xf43aa493, 0x24b186bc, 0xeb9daa37, 0x67d7132d, 0x1e7ccc87, 0xf787193b,
+ 0xb3ee3107, 0xe3878724, 0xf294dc68, 0xca1f9d00, 0x70d3bd38, 0x5fc830ce,
+ 0x1b7dbfee, 0x2c3fff7e, 0x00284ba1, 0x0000284b, 0x00088b1f, 0x00000000,
+ 0x7dd5ff00, 0xc5547c7b, 0xbddcf8f5, 0x0dd90afb, 0xdc3bf79b, 0x24280c10,
+ 0x01049e6c, 0x878424d9, 0x28026e20, 0x47796bc8, 0xd2026c92, 0x6dfad0fe,
+ 0xe5318316, 0x16d46b6b, 0x882ea945, 0x835ab696, 0xb80d06a2, 0x47d62228,
+ 0x2d8aa523, 0x2220a5da, 0xfb1b6484, 0x6fcb56c0, 0xec9999ce, 0x0f0d9bde,
+ 0x7cf9fb6b, 0xdcc98fe1, 0xe6739f79, 0x9ce7339c, 0xb5331d99, 0x228ca8cd,
+ 0x389aa6a4, 0xfd2d34bc, 0x84e90ee9, 0xf00b9085, 0x8321226f, 0xf121326c,
+ 0xbd3ca484, 0x582c524d, 0x1c5a7fbe, 0x052627d6, 0xaed84bbe, 0xa0af9686,
+ 0x84225ba9, 0xa0e4258c, 0x31cc7881, 0x2ae8b484, 0xfd68d947, 0x7b488496,
+ 0x663b2d13, 0x68db4573, 0x9d63967f, 0xeab4ac07, 0xa33e6398, 0xda4bf68b,
+ 0x4264c7e9, 0x121230de, 0x8c1ddb41, 0x6dd3ed60, 0x42229074, 0x07891b26,
+ 0x233d1bbf, 0xc1dfda14, 0xbfb083a1, 0xa6eab797, 0xc37b697a, 0x19d8b220,
+ 0x9b74ef32, 0x6ca5db0e, 0xe8e921dd, 0x5a48b8f7, 0x513f321e, 0x595b01ef,
+ 0xcc67cc26, 0x43844ed4, 0xae3d56dd, 0x1ce8c2a7, 0xb05466b6, 0x8fe868de,
+ 0xe6ed7bd6, 0xfa7e8c4f, 0xbd2fc7fd, 0xbf50246f, 0xc1b47255, 0x37df5bfc,
+ 0xa9a1c9ce, 0x4932e7e7, 0x613a6420, 0xf0bf36ff, 0xdfa151be, 0x70a6efa7,
+ 0x76eaf5a2, 0xa32fd2ef, 0xc5a95769, 0x24268d23, 0x8b6bccf3, 0xdefd2148,
+ 0x74112266, 0x5736dd6e, 0xfbce8d91, 0x0e535dcd, 0x58845149, 0x20f9339f,
+ 0xc421f015, 0x06b4e19f, 0x3a5225e7, 0x722fce30, 0x10b3fd2a, 0x55ef46b2,
+ 0x95ddf099, 0xb7eb4559, 0xccf830c6, 0x42e0cc1f, 0x157bec2c, 0x0b80975f,
+ 0x8c0a7f1d, 0xdce5915f, 0x2454fd01, 0x329bd846, 0xaff99e61, 0xebdc2999,
+ 0x823d92ec, 0x672b8d56, 0x579d0cf0, 0x79b84e65, 0xe2f1c06d, 0x44f8d963,
+ 0x7180cfef, 0xefb2f109, 0xf9216932, 0x3873f6c1, 0x1f77e9be, 0x3a864efb,
+ 0xd7f38273, 0x4d836fe2, 0xe861fac2, 0xa3ac116c, 0xc7cf98f6, 0x0f53ace8,
+ 0xe6799674, 0xd043e230, 0xeab6cfcd, 0xd5fd1531, 0x5fd88cd9, 0x708f4d9d,
+ 0x1a780cd9, 0x2c03534c, 0xcc1ba69a, 0xc7850f5e, 0x1f26f39b, 0x7e297292,
+ 0x20fa316e, 0xb4b7437d, 0x48dfca16, 0xe8b7e361, 0xdf216b74, 0x34859772,
+ 0x6e1d5e21, 0x376bcf98, 0x6a7e2147, 0x26bd1ae7, 0x9f8fcfda, 0x63de5897,
+ 0x67fa12f1, 0x72f66bad, 0x22e24768, 0xfe024fec, 0x738c075c, 0x4ae9fdac,
+ 0x51bf6e79, 0xb7a7dfa1, 0xf027fdb1, 0xe8c6db50, 0x0107ec4b, 0xbd3c20d7,
+ 0xf024fdaa, 0x8db07f31, 0x17a505d1, 0xcecd7780, 0x3349db08, 0x0102eb1b,
+ 0xe5568cfa, 0x6d93dbeb, 0xf3044727, 0xd007f035, 0x81620ec1, 0x79f2d679,
+ 0xeeb9d3ce, 0x6755fd83, 0x50341ff6, 0x0d1f16d4, 0x881f7ee0, 0xffd66b7e,
+ 0x0164fb3a, 0x0e93ab21, 0xadf62a61, 0x7f7aa861, 0x6f78e56f, 0x7bb69482,
+ 0x4d4dd382, 0xcbee1b61, 0xb80d939a, 0x19532d9f, 0x231cb35f, 0x133c508e,
+ 0xdebe43f2, 0x457db17b, 0x9964db64, 0x71e2bdc2, 0xfa44d6c9, 0xaba44fcf,
+ 0xa36ce224, 0xf5b67dfd, 0x0025a8f5, 0xc82eafdf, 0x37ae98a4, 0x3777ad82,
+ 0x3b5d3be7, 0xde91c029, 0xcc248c1b, 0x3fb72f7a, 0x01223be2, 0xec386b3c,
+ 0x1f2e9ebb, 0x17a529fb, 0xf6c1cecf, 0xcf92e8ab, 0xf6eb3d3e, 0xbbbce94f,
+ 0xcbb44c76, 0x4e4d3640, 0x7c409fa4, 0xa53b7d84, 0x4c99389f, 0x37de2895,
+ 0x351ebdb4, 0xfcfbb68e, 0x81f3a397, 0xf7cdbf6f, 0xe5e799fd, 0xbb9700f5,
+ 0x75ecf67e, 0x95e35e50, 0xce304d62, 0x95ffc7ce, 0xdea9fb42, 0x26100f51,
+ 0xd57cbf4d, 0x74f5a7e8, 0xfbec6dde, 0xa836c1ce, 0xf713f9f7, 0x6ef0075f,
+ 0xf2c26b6a, 0xc36c4f33, 0x7b3f6bfc, 0x683fdf76, 0x94675abd, 0x799dea1d,
+ 0xa5e23f7e, 0xc077a5d6, 0xeba2077a, 0x33f6bbcd, 0xe126d97e, 0x1973237e,
+ 0x2d74131f, 0x9ff3f7e8, 0x2a1b1e2d, 0x16f7c437, 0x833b9723, 0xcb391c98,
+ 0x994d6ff7, 0xb3d205a5, 0x85cc44cf, 0xfe8dbaf5, 0xcf9868ec, 0x1f174628,
+ 0xb6d47871, 0x2db831ad, 0xf9fb1ed8, 0x487bee80, 0x9e7d2873, 0x6b4ef4a2,
+ 0x0050b8ed, 0xeb0afde3, 0x11257ad3, 0x2f37be14, 0x7cc12e38, 0x18354722,
+ 0xbf9e706a, 0xd574e564, 0xebc5e5a1, 0xe96a3d18, 0x059b0be0, 0x907d8beb,
+ 0x4d32bbb2, 0xb2603e41, 0xd6ce3e33, 0x6aed5297, 0xd7efd2b2, 0x65d973af,
+ 0x4f97c78a, 0x4a9c9e1f, 0x211b3ff3, 0x65fe2015, 0x8f39c989, 0x5ba9c705,
+ 0xd04e465f, 0xd9a2eaf9, 0x11b0497e, 0x07c8b5fd, 0xd7ba31b6, 0xf205bd13,
+ 0x89f200fa, 0x072e16ba, 0x1279b077, 0x96632073, 0xae59db15, 0x83ce098d,
+ 0x3058b3b6, 0x29b8c81f, 0x678ee407, 0xc51dca2e, 0x233df388, 0xe4f101f8,
+ 0xee09cc2e, 0x711d04b7, 0x8c13fe01, 0x7e30b534, 0x4ffb4953, 0x8a4d2e8f,
+ 0x09a60a2e, 0x16b95883, 0xf2f0b74e, 0x923b451f, 0x3b5e01a2, 0x60f25563,
+ 0xdaf2be20, 0x6e4cddcd, 0xe91c72bf, 0x08740dd0, 0xaa4ebbe3, 0x6472f6e4,
+ 0xf70e94ae, 0x5c3a471c, 0xabf8cede, 0xb8d4bdbb, 0x259ba68c, 0xefe61732,
+ 0x7404f4e6, 0x9bf9a764, 0x7d71a3a2, 0xd9fcebee, 0x39baa7c0, 0x61ef75dd,
+ 0x4e86f6f4, 0xbcf801e7, 0x36e47db1, 0xf95a0790, 0x113b5528, 0x6f8a6edf,
+ 0xd67a0493, 0x67a0c3ba, 0x3b1355d5, 0x6ef757ec, 0x081a1fbe, 0x7b7707ee,
+ 0x2fe872e5, 0x5d9a6e35, 0x992f5096, 0xeef34a9c, 0xfb04525a, 0xd96b652d,
+ 0xd20ba01e, 0x20ab912e, 0x0ddced5f, 0xab8fafed, 0x2099cbb3, 0x9927b6f7,
+ 0x47ebfd69, 0xcdfb6314, 0xf4294ae9, 0xb620a9e7, 0x706f2127, 0x9cdb3ca1,
+ 0xf20ed23c, 0x88daedce, 0x0651177a, 0xb89ca1d9, 0xbea16bf4, 0x6c80b3db,
+ 0xe3ecc292, 0xcb03923d, 0x08de91bd, 0x3b7a7eda, 0xeddc7fd3, 0x139f1f6c,
+ 0xa1a911f0, 0xd78c1173, 0x788982fd, 0xbd9d20a4, 0x930a67b9, 0x509a2fb3,
+ 0x746d9ece, 0x34541390, 0x10568c8f, 0x358e02af, 0xa03a99ad, 0x9966425b,
+ 0xf8cb1e60, 0x4c0d5a3c, 0x3973446e, 0x9b2f7590, 0x1fbe72c7, 0x78eb4796,
+ 0xaffbe46a, 0x9b05c995, 0xe0e41727, 0x921e3e39, 0x73970245, 0xe5bae874,
+ 0xb527dc3e, 0xe2feb34f, 0xdbbc8e4c, 0xe855e842, 0x6c7a5a47, 0x6ca6e3e2,
+ 0x3301203d, 0xa55ad949, 0x57d7e7da, 0x5d3d5f13, 0x755bf5e7, 0xa8b989be,
+ 0xfc82dd37, 0x6c91837c, 0x77f7fa97, 0x5be3344f, 0x3cceb115, 0xcdd7e409,
+ 0xfa3fd416, 0x8720e9f6, 0xb8f4022e, 0x84dec97c, 0xea1670ab, 0x09d3bd68,
+ 0xede03b56, 0x5a8e1c47, 0xbdafab7d, 0xd19c0f46, 0x4325c9ea, 0x4186e969,
+ 0x549e0173, 0xa198b75f, 0xa7b68d9d, 0x8fb612f5, 0xf213627b, 0xf7ec26ab,
+ 0xeb1b68f6, 0xd859d627, 0xcb2e2c00, 0x27c98eb9, 0x7adc3dab, 0x9e85a3d2,
+ 0x074f28bd, 0x82db33f4, 0xafc7e1fb, 0xbd194b48, 0x01284151, 0x41fdb23d,
+ 0x5278fee8, 0x3d447a41, 0xf4e0ddca, 0xb647a786, 0xaf54dc5f, 0xd29b3d02,
+ 0x27a65ae3, 0x4fdb085b, 0xa7232e8c, 0x7c007932, 0x159f542b, 0xefbb54fb,
+ 0xedf6fd05, 0xefdccbfb, 0x1fb606dd, 0x801c29bb, 0xfce8fbde, 0x9be74665,
+ 0x48fdd036, 0xfdd137cb, 0xffc214d8, 0x981fe7b5, 0x04079c27, 0x73663dbf,
+ 0x745f0076, 0x19ab7f6f, 0x47f396c9, 0xc83fcbf7, 0x65de98be, 0x5fb4ca86,
+ 0xa1afdd33, 0xe0a663f4, 0xea63e6b6, 0xb9113901, 0x8947ad5e, 0x266883f4,
+ 0xdeb1bebf, 0xa3d24238, 0x55f1c3de, 0x007d73ab, 0x46f41e7c, 0x6324114a,
+ 0x131bd33d, 0xde00e640, 0x417a47b6, 0x20484e3f, 0xccc2e7ae, 0x67df3f67,
+ 0xfce29f02, 0xeac51090, 0xff7df2f7, 0x4ff7af29, 0x4b9c869e, 0x3a283f70,
+ 0x0f2271d7, 0x3b448f2c, 0x172c2f3a, 0xd73be9f3, 0x137cd998, 0xbedecaee,
+ 0xc18f0429, 0x3e75757d, 0x5eeb37e0, 0x25a97e9f, 0x8b908e38, 0xf981ba5a,
+ 0xf581fc83, 0xb81a8e54, 0x7e7eeb5e, 0x71d0d33e, 0x7b5fdf04, 0xb482b8a8,
+ 0x2bfbe0d5, 0x5635c7ee, 0x2522fa02, 0x9d2c4707, 0xe1befd57, 0x088d1f6c,
+ 0xeafb4364, 0x314dd758, 0x9331dfb4, 0xdfa0fef8, 0xa09ce0ab, 0x0c531e27,
+ 0xf5e0dde0, 0xd3f9e087, 0x8f7fd618, 0xe991ecd5, 0xd623b8fe, 0x3ded0d15,
+ 0x03eec465, 0xe5077339, 0x896fb027, 0x4df808af, 0x0147f13d, 0x5d58c79c,
+ 0xbf4031f1, 0xc9366772, 0xf257fca2, 0x63f7c2e7, 0x84b95111, 0xfb71f3f6,
+ 0x85799f6f, 0xcaf85ab6, 0x03df85b9, 0x22317afa, 0x18e2e803, 0x513b97d5,
+ 0x830656df, 0x944bddbe, 0xfc30b6c1, 0xcc0ba457, 0x20beb33a, 0x55663f98,
+ 0x7a442f9f, 0x6fc30c4d, 0xe214f9fd, 0x09fe8589, 0x627bbf9e, 0x1f5df614,
+ 0x56ea8230, 0x78833e7f, 0xeb1f7f68, 0x985b7548, 0x30c53771, 0xc84ddb7a,
+ 0xf7e570d4, 0x0f7671f1, 0xb030fb65, 0x7f02f24d, 0xe1bf5eac, 0x07e532cf,
+ 0x3eacebd5, 0xe831694c, 0x8f36d56f, 0xc7f3474f, 0xd11f8c0c, 0xc5cdb37f,
+ 0xeb47b941, 0x0e03c7e9, 0x4b20f43c, 0x2e52e0f9, 0xbc3596b7, 0x13d825f9,
+ 0x3cc4f5aa, 0xdcb3f69e, 0x4a983cec, 0x2cb33e8b, 0xbfb6028f, 0x25b73bf2,
+ 0x5c4a5c80, 0x32eccad0, 0xf40d9264, 0x4331c95e, 0x317910be, 0xfa8f4b3d,
+ 0xe29fe231, 0xe7188beb, 0x82f7c04c, 0x80f504c1, 0x7a45b705, 0xd07c213d,
+ 0xa5a1e1cc, 0x7eb84f9b, 0x767feda5, 0xfe81196c, 0x739ca23a, 0xdc163e81,
+ 0xcfc54e76, 0x53ff25ba, 0xad5d028f, 0x649fdab1, 0x433865dd, 0x623bfee8,
+ 0xc43af3bc, 0x675e4f53, 0xa04cfaf6, 0x87c640df, 0x30eacf60, 0x940a3cd9,
+ 0xa2cf111b, 0x291a9fdd, 0xe60ecbe3, 0x361e9e97, 0x196be819, 0xde0337b1,
+ 0x1244b597, 0x033f084f, 0xc3e81805, 0x3f609e7d, 0x3cde3b4b, 0xaddcfc0a,
+ 0x2c9d23f7, 0x8f105b35, 0x9c7af3ee, 0x74316907, 0x8a7b45f9, 0x8e5123fb,
+ 0x9e7d60db, 0x9f47c67b, 0x263f491a, 0x7eb8efd2, 0xfdf0edd7, 0xe228c8a1,
+ 0x4b78fa00, 0xf3a70ef6, 0x832b35ef, 0xeabc2863, 0x460e948d, 0x734e3763,
+ 0xd243fe88, 0x77fc6aac, 0xcc25f5bc, 0x65d9b967, 0xc2be3904, 0x32a7cf41,
+ 0x6457c9e0, 0xef8a151b, 0x9185f2f1, 0x45ef8f97, 0x6c7fbf7c, 0x661ff4a4,
+ 0xe1c7dd1f, 0xa5ea23df, 0x71f27db0, 0x0e7ea906, 0x4a686bd2, 0x943c7ddb,
+ 0x3e79f3e7, 0x604bd79b, 0x9f7c1df9, 0xeacb9c7c, 0xc5f1c769, 0x3b36fe30,
+ 0xe015b1d6, 0x8cf9db45, 0x22fb1740, 0x16b7a8bc, 0xfc077e52, 0xea3a6d6d,
+ 0xedaf94ad, 0xc4d97ac0, 0x4cf58d17, 0x03485728, 0xcfb07be5, 0xcf84148b,
+ 0x274a52a6, 0xd7b03cb4, 0x04aedb64, 0xa9f02af1, 0x8c7b63c5, 0xc3c9eff4,
+ 0xd43e9251, 0x61e5428e, 0xa3b30c7b, 0xd27f6118, 0x9e991899, 0x85f10c36,
+ 0x3e5f2274, 0x608c6ebe, 0xf4fba078, 0x7bd418b5, 0xfba1397d, 0x97c704e5,
+ 0x0f1f67e0, 0x8ab5e352, 0x5e6de1e3, 0x8d8c516f, 0x007b4fc9, 0x31c7ddf7,
+ 0x165c7eac, 0x0f424393, 0xcb8703ff, 0xc8549a4d, 0xd5533195, 0x1c4dc5fa,
+ 0x44c5379f, 0x087ebc09, 0x88f215f3, 0x345f17f2, 0x5e0b0fdd, 0x217f2135,
+ 0xb0d9031b, 0x63bd68ff, 0x2c0a6e58, 0xe472a58a, 0x18dfaa26, 0x22ddb1f3,
+ 0x3cefdf68, 0x85d04a3f, 0x3e9c8095, 0x1853d625, 0xe54f7e40, 0x296bae1d,
+ 0xba437ca1, 0xd037fe34, 0xd694c93a, 0xd8560c87, 0x03a64ef9, 0x208fed02,
+ 0xe147f40a, 0xb850e7fe, 0xc63bc76b, 0x319fe0e9, 0x96f11e92, 0x9f70f247,
+ 0x7585ffbd, 0x9cf2ed21, 0x51d1eccd, 0xceb8ffbe, 0xe9fa0175, 0xd42dfdba,
+ 0x7d198fcb, 0x3096add9, 0x63df46e5, 0xf2c1490f, 0x3d973fc5, 0x762fca46,
+ 0xe4fd7677, 0xa5eeba66, 0x861db29d, 0x5fe77a5c, 0x7a031ddf, 0x0ec1a775,
+ 0xdf2a46e7, 0xbcc3d5ef, 0x791e981b, 0x83a6a74c, 0x9f55dfb3, 0x1962d273,
+ 0x83dea8be, 0x3be09cfa, 0x4adf7e42, 0x5c81577c, 0x461c465f, 0x66b4ff48,
+ 0xe1420cd5, 0x0eb2c2b7, 0x6be7d1f9, 0xbc1ea1a7, 0x7cb07892, 0x4fe18b59,
+ 0x4561f2a1, 0xeabf3aab, 0x56fe7561, 0x67df3aaf, 0x2f0f2e7f, 0x32c7a7df,
+ 0xd94b3e3a, 0xb03fe03e, 0x3d05e4c1, 0x98af5b48, 0x3ca4cbd7, 0x24f813b1,
+ 0x4760fb95, 0x48e11758, 0x6ebebe04, 0xc5e2696f, 0xe7f57cec, 0x10de21af,
+ 0x37a8237d, 0x6c6f12e4, 0x63cb7eff, 0xf4238415, 0xe071f0ab, 0x2cb671bc,
+ 0xc6263afc, 0x10653d0a, 0x8bbe27f6, 0x45e3827e, 0xcfea3ce1, 0x8f98079b,
+ 0x5d9fdb05, 0x1b9c7e19, 0xa9b1c6fa, 0x7db064e4, 0xfc6b931c, 0xa3e82d1c,
+ 0x7e127cfe, 0x07a17917, 0x31a5db07, 0xd9a48afd, 0xf906454e, 0x8b63b094,
+ 0x224270fd, 0x3bb464e6, 0xebcfcfdd, 0x5fb05cf6, 0x083d009f, 0x6514e3f6,
+ 0x714e9f9f, 0x66c6f7d9, 0xf70687eb, 0x941d768b, 0x43f8ceae, 0x58b2eef8,
+ 0x6b8e1c6b, 0x57187627, 0xdba2fbd0, 0xe8bb062b, 0x6778ff7c, 0x546ba279,
+ 0x30f53f28, 0xe85189bf, 0x9c95165f, 0xbc391a25, 0xd42dfdac, 0x95bea8bb,
+ 0xd3e74c0d, 0xbd23b7bd, 0x04ce24af, 0xbd9ef3a0, 0xff5c33c3, 0xf315fc86,
+ 0x6259e599, 0x9ba79820, 0x2abfee98, 0x1d599f3e, 0x99d3ef4c, 0xc71c061d,
+ 0x025b1441, 0x7cd9a51e, 0xd3d4f329, 0xf9be84fc, 0x908e9183, 0x12fe7cf1,
+ 0x9df0a7b4, 0xd4b253c0, 0x36f30495, 0xbc74b8c1, 0x824de208, 0x5dac69b4,
+ 0xe4a27481, 0x3079b3d4, 0x0d264f3c, 0x675f5069, 0x9d6ccbf6, 0xd0090674,
+ 0x985e0fbe, 0xc6fcf2b7, 0x568bbdd9, 0x158b77c0, 0xcf9188f9, 0xe52c4763,
+ 0x2fe46687, 0xc9b75866, 0xfd1cfbe2, 0x94f53c64, 0x3d8fb829, 0x3bda0943,
+ 0x02369106, 0xe72c5ae3, 0x1b58b03c, 0x8f9049b1, 0xe0faf5b0, 0x66ce70fc,
+ 0x2346e8f1, 0x0b19dc9f, 0x677a527c, 0xf285e025, 0x19ff6665, 0xc3ef5ca8,
+ 0x73e0b773, 0x4d7e7c31, 0x1325cf9c, 0xe2588706, 0xb01ef1c0, 0x40419cae,
+ 0x49d65984, 0xd44b7ed0, 0x25eff454, 0x7969e000, 0x8abd54ec, 0xd53bc56f,
+ 0xeab9c4f9, 0x9d4bb27c, 0x3f93d337, 0xcf928be8, 0x16217499, 0xc02359cf,
+ 0xfce062de, 0xebcf99a2, 0x3d74a408, 0xfd3e71ef, 0xbb13f58d, 0x8eeebcfa,
+ 0xe3b41231, 0xd0cd9825, 0xde57d53f, 0xcafa658b, 0x97281e27, 0xf3cfc803,
+ 0xc0f9b626, 0x837cd3ae, 0x7e8bbf64, 0x1b2ab66f, 0x3d5494f4, 0xc76624d3,
+ 0xf54adbd1, 0x865b7cb4, 0xe689becd, 0x1d7ec1eb, 0xd5b7f30b, 0x49f68d3c,
+ 0x0247ab13, 0xdc8fe0cd, 0x8366c9b6, 0x81e5717a, 0x8bd046c9, 0x76db1057,
+ 0xbfbe8612, 0xce86fba2, 0x53c809f7, 0x5e9c48bc, 0xf3290f22, 0x7cbc0d71,
+ 0xc59dfc07, 0xe18b13f2, 0x65feca5c, 0x3a75e475, 0x90e0eec0, 0x77d62e51,
+ 0xa16ebde4, 0xcecd65e3, 0xb3bc3b43, 0x0973f99c, 0x3463f7df, 0x905c6afb,
+ 0x8f3cb1ce, 0x707587e7, 0x899c6ebb, 0x746d6bf9, 0x36666288, 0x8c71fac0,
+ 0xfc44edfe, 0x5af2fb63, 0xfd07fc12, 0x47fb0795, 0x5829343e, 0x7467dc1c,
+ 0xbdb37ca8, 0x1bd696a9, 0x87edf7a3, 0xa78e3c7d, 0xa37d3c79, 0xbf9406f4,
+ 0x628b3a9d, 0x6d7db1d4, 0x861302ce, 0x14b80653, 0x04d07edb, 0x7c904cfd,
+ 0xbd4c6698, 0x5fa609bf, 0xd147edc5, 0x06ef4649, 0x12a68eba, 0x77b4678a,
+ 0xd820f9fc, 0x4907e5a5, 0x88e9e001, 0x0739c841, 0x7a15d39e, 0x3a1afb1c,
+ 0xfd406c98, 0x2a932ffc, 0xd5013bf0, 0xd2bbce8c, 0xbe2116c6, 0x755f2c0f,
+ 0xe36a3f28, 0xb337e464, 0x6abf32a6, 0x57b35cfd, 0x10ce4092, 0xbbd277e6,
+ 0xb10a6f32, 0xc43f0897, 0x773206fb, 0x44f39857, 0x4fd31c6d, 0x3b3066ab,
+ 0xa346fd6f, 0x1d537fca, 0x335eecc7, 0x8c8f26e3, 0xfcc47943, 0x5c7179a7,
+ 0x46411b6f, 0xe10a9f00, 0xaf504523, 0x81edf4ab, 0x9cba8cf8, 0x8e3999f3,
+ 0xfdea0302, 0xbe08df9c, 0xf6c41cee, 0xd2423cf3, 0x9367ae81, 0x87ffe406,
+ 0x7e456f4b, 0x18f11373, 0x951f6f00, 0x310278b1, 0xd55359ef, 0xa71cd27a,
+ 0x5cf37f3a, 0xf0c51ead, 0xe79dc621, 0x09579752, 0x5aaa783d, 0xfff05e0f,
+ 0xb9468abe, 0xdd54f89a, 0xe7e02185, 0xc000f660, 0xe873f30b, 0x1bdc6e91,
+ 0xbebc3f99, 0x388def3d, 0x127767d8, 0x4976cfbe, 0xb2ffd1cb, 0x82115a4b,
+ 0xaf5ad4ff, 0xb8647204, 0x987dd855, 0x7934e4de, 0xc3df83f7, 0x91128359,
+ 0x49e3cebc, 0x493c400e, 0xadbe907e, 0x57165665, 0x30b51c41, 0xa45b349f,
+ 0x16fef41d, 0x65da3e5d, 0x2aaca25b, 0x0da6fa3b, 0x13d4054a, 0x44c558f6,
+ 0x6e9c6df2, 0xd7779dc2, 0xbafe31c5, 0x71766259, 0x9e333ccf, 0x9cb3e32b,
+ 0xbc413f2a, 0x9d828e4c, 0x229c6470, 0x63fda3ea, 0x5c95c1b3, 0x44af5340,
+ 0xd2171197, 0xd11b265e, 0x4fe1a8ae, 0xb476b1f1, 0xce0fc7eb, 0x9cfd3b41,
+ 0x2fb43c8e, 0xfd844b12, 0xffd8292a, 0xf4dbd99c, 0xdf53a710, 0xdcbf4db1,
+ 0x7bbba412, 0x8d5cb8e2, 0xaf409124, 0xe7ba767d, 0x7ba7684c, 0x5ffce75c,
+ 0xa35acba0, 0x2171ed0f, 0x07df8af4, 0x38ab8b92, 0x9cca18bd, 0xf9d056f3,
+ 0xb46bbcf5, 0x1d19f9c3, 0xe7ffb46d, 0x9da344f7, 0x50455f51, 0x652c6d3e,
+ 0xec07a47c, 0x9f1d745f, 0xf9e35745, 0x8ad4a360, 0x663ba3f2, 0x6af1d232,
+ 0x073c01cb, 0x74a56f57, 0x569f2218, 0x6be750ef, 0xdf9e2748, 0x47ee9f6b,
+ 0x0517c8cf, 0x56ef761f, 0xd4c323b7, 0xcb8f377c, 0x7da77c8b, 0x7d4c0556,
+ 0x9d8b3dae, 0x8641e9c3, 0x1de8a3ae, 0x2eefb723, 0x008a9db0, 0x7494fb56,
+ 0xc7adfd31, 0xfb665a7a, 0x2283c99f, 0x6e568e3e, 0xedbd7115, 0xe0bfca3a,
+ 0xb0f42afc, 0x07f2c222, 0x92721d74, 0x42df382e, 0x7fe84ede, 0x7c084e42,
+ 0x52109695, 0xa743f742, 0xc9434fe0, 0xed37c050, 0x0489f71f, 0xd8314391,
+ 0x7dce07bf, 0x9478f8e3, 0xb7203c1e, 0x17b33a3d, 0x6a59abe8, 0x06693940,
+ 0x9ba69f3d, 0x83ca1724, 0x323daa97, 0x692c7bc0, 0xd6833598, 0x8cee6f1b,
+ 0x3a513804, 0x3f4a1239, 0xb197c44d, 0x11d1524b, 0xbf457796, 0x848e961d,
+ 0xc47df33c, 0x74e998f4, 0x054fd0c5, 0x7a687e38, 0xc8e76240, 0xeb1f9629,
+ 0xbadbfda1, 0x53274869, 0xf30f5789, 0xf1a9b0ab, 0x9d49253f, 0xa3f4a69f,
+ 0x70c38c0f, 0x1f4e7870, 0x08772ea1, 0xfcd4477e, 0x857c932e, 0xc1f9187a,
+ 0x5d80efc1, 0x193d7221, 0xd50dfa01, 0x6a1f7144, 0xb8ebe0e9, 0xf26fdd6f,
+ 0xbf185c75, 0x13b70f49, 0x2bfc4b5f, 0xd3fa969f, 0xeb1bf759, 0x7a10a4e5,
+ 0x65e2fb14, 0x907f8b03, 0xa9fe655e, 0xe5193312, 0x642afa03, 0x3fb14576,
+ 0x8cfa05ae, 0x315dd209, 0xcf119eff, 0x19086ce9, 0xa1367402, 0x5327c23d,
+ 0xfef1e4bc, 0xcbba05ae, 0xe223ea0f, 0xd254d15c, 0xa532be8f, 0x705fd42c,
+ 0xa47d09df, 0xd26b6a40, 0xb91f0267, 0x1be609a7, 0xe3434f42, 0x512f808b,
+ 0xda7dc27a, 0xcbaace4f, 0xf026f435, 0x52e5f42e, 0x367480d2, 0xea60a75b,
+ 0xf2855cab, 0x5b32dcb5, 0xacdfed0f, 0x0936f462, 0xea0b31e8, 0xdca5e9ab,
+ 0xe96bceac, 0x0ba88e91, 0x9f4b571d, 0x10dbd103, 0x5f2137a0, 0x6f4d2f63,
+ 0x75bfe3d3, 0x7f1e9b7a, 0xd2d37a11, 0xbb5fe099, 0xa0e56c22, 0x4b57d73f,
+ 0xde0a0f28, 0xf904d61d, 0xa89975e1, 0xb68aef4f, 0xdf5d7ea3, 0x3b0bcac0,
+ 0xbdc4321d, 0xe5e3ad64, 0xc872ce99, 0xe5a7afd7, 0x23a2ebb4, 0xd8662e2c,
+ 0xef3cac9d, 0xadd786ae, 0x587867a0, 0x6f3f97fb, 0xb968a396, 0x2fb799b7,
+ 0x7c872d6d, 0xff6b0b7d, 0x46a9f819, 0xb79a7c43, 0x7d5fbe09, 0x1d9da66f,
+ 0x3efe99ab, 0x9777af91, 0xd8ebdcf4, 0x5bb595ae, 0x883cd075, 0xe99ff9e0,
+ 0x75f1d7e5, 0xd6cadc4e, 0xfae27719, 0x8ba50aa9, 0xea0f0115, 0xb574a76f,
+ 0x06dfc8c5, 0x4a973f38, 0x4e9069ad, 0x5217eca1, 0x22ded987, 0xcc7e650f,
+ 0x7b8874ed, 0x45fd99e2, 0xce20fff8, 0x9f4432a0, 0xd99e27b8, 0x84bd4563,
+ 0xa0018a18, 0xa8ac4787, 0xa4ff0b5f, 0x812221ef, 0x723587bc, 0xbfac243d,
+ 0x03564a72, 0x865311ea, 0x5fa53f08, 0x9b8e94bf, 0xc98be177, 0x3f43ece1,
+ 0xe69ee3e2, 0x7a7d1371, 0x075337b2, 0x880bb174, 0xf4800524, 0x7f41afde,
+ 0x487e05db, 0xa43ca426, 0xf2caf004, 0xbd7fe35b, 0x853c65a9, 0xef41aeaf,
+ 0x2196a101, 0xccc9dc61, 0x1c1be24e, 0x53fe7fd5, 0xc467c4f4, 0xff362638,
+ 0x1e544d95, 0x7e31d123, 0x8fe38736, 0xe90abf8c, 0xd3c73677, 0x2a7f05cf,
+ 0x9fc00520, 0xddbc70e6, 0x347aa664, 0x8356c3f2, 0x133c6f86, 0xcb6a720f,
+ 0xbabbfa80, 0xaa57c35c, 0xb92bb8f9, 0x092b7ede, 0x4a727ea0, 0x7a7a62f2,
+ 0x6bdbd30b, 0xbf50472c, 0xe98479e9, 0x8fc4b5ed, 0xbed68ffa, 0x9d53b359,
+ 0xe7536baf, 0xf9d5dbeb, 0x8e0f1c9e, 0xaea5b3d3, 0xd58aec18, 0x768bbf0f,
+ 0x5fc16aec, 0x42fe6abc, 0x5fc67115, 0xed06ba1e, 0x6f98df51, 0x6f4f4d3c,
+ 0xd0b8aac5, 0xfa9c02df, 0xb22f35ec, 0x613714f8, 0xeb1e8276, 0x4e70f988,
+ 0xa4791a25, 0x9c7927e5, 0x86fb089f, 0x84792fe0, 0x8e7a23c9, 0x8241d77d,
+ 0xd7ab5c7c, 0xbd73c4f5, 0x84d39f97, 0xfa0793fe, 0x35d3d00f, 0x4164480d,
+ 0xdb7f6439, 0x9fc88724, 0xc0668579, 0xee99be73, 0x6c978067, 0x545971c9,
+ 0xca05f0f4, 0x7bcf8199, 0xbd0d72ea, 0x2dd6f388, 0x81665e9c, 0xff8e8527,
+ 0xe781c97b, 0x32b7c3ba, 0x5963997a, 0xd1faf487, 0xe22f466a, 0xe7e577dc,
+ 0x4dfc873c, 0x747d79ce, 0x5ef54112, 0x17491e9a, 0x8fe67ce7, 0x1d1897af,
+ 0xf87d55d4, 0x82cfe818, 0x246e1c2f, 0x3e10faf1, 0x64cd34d1, 0x934a3b06,
+ 0xaa839d81, 0xbc5c7fa6, 0x38cf8434, 0x13134a22, 0x88ee5940, 0x5d6cfb47,
+ 0x669c7aa4, 0x7fbbf3a9, 0x4fd2f380, 0xd44ed123, 0x954130fb, 0x70eb77a4,
+ 0x6b3edb8c, 0x31527e60, 0x7707559f, 0x7ec3f3ee, 0x08ebff5c, 0x359f953d,
+ 0x5ac5f792, 0xe4c4b65a, 0x6a7186ca, 0xb3233e74, 0x5fa27663, 0xb03b8c57,
+ 0xf283d65d, 0x931af8d5, 0x106901c3, 0xefd2e1c6, 0xb5fea1d9, 0x4f8c89d1,
+ 0x2aeb11df, 0xca0f8848, 0xa43f614b, 0xc6a49652, 0xc126fd04, 0x376606f8,
+ 0x5c710bf9, 0x6361be32, 0xb69e7d88, 0x568f1b0f, 0xf5f8c096, 0x61ce29f7,
+ 0x1da307de, 0xd39f30e5, 0x9a7b8fdc, 0x474efdfb, 0xcce03f31, 0x752cfabe,
+ 0xf734f4f1, 0x518e9e13, 0xbd4487fb, 0x8ecc09a5, 0x6cd1b272, 0xbf07a8de,
+ 0x1c6f313a, 0x21ec4946, 0x93c60353, 0xea78602c, 0x6dbd13d9, 0xa5ff8853,
+ 0xfbf4a12e, 0xd87f9f30, 0xba43379c, 0x31b8f5bc, 0x23df0ed4, 0x0f77f3b1,
+ 0x089e97a7, 0xeb718a96, 0x0fbf2a12, 0xe799ec78, 0xe5f63c47, 0x13bc8ac7,
+ 0xc099effb, 0xfe5f6bf8, 0xb84f2c3b, 0xf5d843dd, 0x69f7f207, 0xd0547bfd,
+ 0x044073b0, 0xfd6bcfb3, 0x3f050bf3, 0x05f9fee3, 0xec2d1f9c, 0x45827e60,
+ 0x4a9cd266, 0x247717cb, 0x946e73b2, 0x9fe55b27, 0x515e44f7, 0xcba0863c,
+ 0x3ecef49e, 0x2123f67f, 0xee3aecfe, 0xeb13accf, 0xdf5eaddb, 0xbadf0903,
+ 0x8481fb3f, 0x6d6cfe30, 0xa08bc3dc, 0xe20b0c47, 0xc18dad61, 0x2dae42ad,
+ 0xef6f7b07, 0xe8718272, 0xd65adf6b, 0xb5e0f604, 0x2a0b003f, 0xa7d431f2,
+ 0x079c38eb, 0x53bc575a, 0x9d951447, 0x4251107d, 0x8aec9fe6, 0x4351e551,
+ 0x4d03890f, 0xb5514ead, 0xaa186f4f, 0xfd643faa, 0x4cf2aa35, 0x9f2abe4f,
+ 0xaaad72d5, 0x65ad55fe, 0x87f0fcaa, 0xcfd557af, 0xa3074323, 0x0c90ecfd,
+ 0xb57221b6, 0x3e554ab7, 0xaa2de772, 0x86919ff6, 0xbd69e3cd, 0x79fe42dd,
+ 0x8aa39d1c, 0x39ce7183, 0xed554b6d, 0x62b6a49b, 0x9f46f01f, 0xbd6893e4,
+ 0xcb5f1c15, 0x62ff993b, 0x556afb74, 0xd8a367ff, 0x5fad183d, 0xa32e7696,
+ 0x912ed61e, 0x7efea447, 0xfb8eeada, 0xa8ee219b, 0xf296bfbf, 0x356eda4d,
+ 0xfe80bf3d, 0x8e6fd5a6, 0x5d3f7026, 0x7461490a, 0x0b0ba5ad, 0x5bbd7fea,
+ 0xe627b465, 0xc687ec91, 0xc40cbc23, 0x5fc7f4ab, 0xae76612f, 0x76ada7de,
+ 0xf559ff88, 0x47a432d6, 0x2e9a9253, 0x5d351422, 0xd3508e44, 0xa6aed585,
+ 0x6a25c183, 0x3dc2d03a, 0x0ba6a1da, 0x43ffa7e2, 0x2ae02de0, 0x553b1ee0,
+ 0x785a374d, 0xda0093e7, 0xc95eddd9, 0xfc6123ee, 0x70dbede2, 0x1fd2975d,
+ 0xf86a89f5, 0x34701c16, 0x2c6e1059, 0x61e84cbe, 0x68ffae26, 0xaf4213fd,
+ 0x7ae44b89, 0xf847ef15, 0x0f259a17, 0xfe7d51ea, 0x865f12c2, 0xa7f4132f,
+ 0x44ecc206, 0xf0c4a4ce, 0x3efc4676, 0xc0519d90, 0x2620f675, 0x03886b2f,
+ 0x882be1ed, 0xc9ddf90b, 0x3ed15bca, 0x63f2cab4, 0xad9ebbf4, 0x35527a62,
+ 0xbf9f22f1, 0xaa02b8e2, 0xfb109287, 0x528e16ab, 0x02b3e487, 0x20f2e1bf,
+ 0x79087485, 0x1378c2e0, 0x62e6864a, 0xad471f95, 0x30df82e7, 0xbd097f84,
+ 0xe0278c57, 0x189af829, 0xe41a44cf, 0x1a17d824, 0x6846473e, 0x3b6a48fd,
+ 0xe0f3b08d, 0x22fe2160, 0x44265dad, 0xe9916e0f, 0xcc90f238, 0x57f14226,
+ 0xdda07360, 0xce7488af, 0xe625ef87, 0xc2bd26b6, 0x935713ed, 0x80c4fb3e,
+ 0xfe12eaf2, 0xc91e59e8, 0x7f6668ff, 0x6bf0b43f, 0xf89fe5d3, 0x5e3c6d03,
+ 0x55ef1052, 0x078f0f2f, 0xa76fea7a, 0x857d1fb4, 0x02eb23f6, 0xc3f6a1b1,
+ 0x9206fbbe, 0x1373d71f, 0x424ddc71, 0x693710f4, 0x133f3c9b, 0x4e54c4ec,
+ 0xecca4146, 0xab5da458, 0x8ed1eb07, 0x012ba3ac, 0x2121afba, 0x60ccda7e,
+ 0xfee5e639, 0x74371179, 0x42e27d29, 0x3fc78da2, 0xc22778b0, 0x5f38a0f9,
+ 0x139e740e, 0xcf701471, 0x2221fc16, 0x9139a84e, 0x4973839f, 0xf74ff42e,
+ 0xb444a6db, 0x29fdd01f, 0xbec7ee85, 0xef2c22b8, 0xeb351fb7, 0xb2147117,
+ 0x42ed10b5, 0x7bd742cb, 0x7a10f019, 0x3ea86fcb, 0x1234f780, 0x0dd7a615,
+ 0x0381f63a, 0x553b0b8a, 0x46f59e71, 0x7b01807a, 0x8e3c8bc1, 0xafad4daf,
+ 0xe3c89b3f, 0xe739f893, 0x181af052, 0x4eee3c1f, 0xf532e3e0, 0x27771130,
+ 0x7f42f8e0, 0xc151efb8, 0xd8bcefb5, 0xe13df707, 0x72e02ee0, 0x29f3a8ae,
+ 0x3d6c97c0, 0xeef00092, 0x83ee7288, 0xfd47e9fa, 0x705d24a7, 0x1772155e,
+ 0xb6f6cbc6, 0xcf3f78cb, 0x5bc5813d, 0xc8c8f7b9, 0x4c3bba1a, 0x6ead37e8,
+ 0xc2f51d7f, 0x68ca46ae, 0xa6761ea9, 0xbfa90e91, 0x0340bd88, 0x47ce81ef,
+ 0x681f3d62, 0x75e22fd6, 0x7f7f3ae8, 0x3efc3809, 0xe42a1c1c, 0x9ee18351,
+ 0x919c5f57, 0x1551903e, 0x75da1f42, 0xb0f4e66c, 0x013cef56, 0x4cef1dfd,
+ 0x55fd0cdb, 0x53071dc8, 0x24eb3e00, 0xd1357fbc, 0x26cbeec4, 0x2574fbf3,
+ 0xdc3b06fe, 0xb34a4e37, 0xe1a9fde0, 0xe09d91df, 0xdd78fe17, 0x4f70316d,
+ 0x5c3ff44c, 0x4efde1d2, 0xe4fb9e42, 0x57f0428e, 0xa26fb02e, 0x162685b9,
+ 0xddf99197, 0xe5165f48, 0x891aaf23, 0x61a3f619, 0x6bde0368, 0x68cb4409,
+ 0xc9938cb7, 0x313ba024, 0x561f716f, 0xfafb877c, 0x7c52ef70, 0x2814d89f,
+ 0x0ed34b58, 0xdd620f4e, 0x0503cb13, 0xfc20960d, 0x16a65c45, 0x3c385b3e,
+ 0x66c6f1dc, 0xcdbb17d0, 0x52c9fce2, 0x9f23d362, 0xfb666759, 0xe255d8e6,
+ 0xc2b3edfc, 0xe11dd4b9, 0xf6063c18, 0x7932fbdf, 0xb17f2692, 0xe3470639,
+ 0xc7d415fa, 0xbb58d9d7, 0xbf071e6e, 0x44b2a3ee, 0x6f8e5f88, 0xa66f1f0a,
+ 0x5c73b124, 0x8beff72d, 0x1f7ab5ef, 0x42d58dc6, 0xf04176bc, 0x6bc695fb,
+ 0x01fc788b, 0x27ad10e1, 0xef78d1fa, 0x7ab179dc, 0x0e4bfcaf, 0x3ebebe7b,
+ 0x0fe22749, 0xcf4defd1, 0x0be3615b, 0xf9d8934b, 0xe807182a, 0x7dc37bc7,
+ 0x4a7b85f1, 0xce45c913, 0x0ef3eefb, 0x889fdc55, 0x9f9f7737, 0xfd7e7184,
+ 0x29fda5fa, 0xe15c6096, 0x92dff040, 0x86e5e6c8, 0xd082bf78, 0xdefb0aef,
+ 0x8f1c4e37, 0xc147f3df, 0xbb45fd3e, 0x7feaf78c, 0x75374871, 0xd779987b,
+ 0x5db83127, 0x7dc7af13, 0x1c47d233, 0x2f8cc2db, 0x35fb89ea, 0x76aa9ee2,
+ 0xfccbbb7e, 0x10fe608b, 0xbc6e1c47, 0xc48e9ca5, 0x30c777bc, 0x99f7b87c,
+ 0xed059ef0, 0x77bde317, 0xe257f8c7, 0xf1a9b0be, 0xd7b73b7c, 0x9fdebeec,
+ 0xa6bcf781, 0x40c33b31, 0x728de0f4, 0xd8f504fd, 0x4a65699b, 0x06fac53f,
+ 0xffb216c9, 0x410f452e, 0x7854ebb8, 0x23770fed, 0xfbf457e2, 0x4fbe61f9,
+ 0xe702c389, 0xbe5c25b7, 0x8351d92d, 0x1f38affa, 0x8cb0fe7d, 0x139f17f1,
+ 0xbcf927e6, 0xcff3c255, 0xeb211752, 0xf95a1f29, 0x88334164, 0x844925b9,
+ 0xbec3175c, 0x46e909df, 0xf97c9fb5, 0x87ecfdbd, 0xaeae5424, 0x57280d20,
+ 0xdd58fe56, 0xfbdc9aae, 0xb49fd067, 0xdce1fbfe, 0xb1d6272e, 0x479e8939,
+ 0x2629ef40, 0xd61f20c5, 0x3185f93e, 0x1f78194a, 0x777ca69c, 0xaff81e98,
+ 0x46aed319, 0x48bfa61b, 0x44963c72, 0xc927b7f1, 0x9ed20db5, 0xbdff59f7,
+ 0x7e4cbdb5, 0xb9438d6c, 0x2efd64d5, 0x087975f2, 0xc0f7ebe3, 0x1e14093b,
+ 0x97d31326, 0x720d7412, 0x5e2dea14, 0xf1e387a4, 0x6266aa6b, 0x74049ede,
+ 0x29cbf71f, 0xefce3153, 0x800e9197, 0x4752a6f7, 0x3625d81e, 0x997bb255,
+ 0xb3f31366, 0xf6317f7b, 0x0c837035, 0x0cbfbb6b, 0x8eb6c1ce, 0xf7b03efd,
+ 0x7cfee8b4, 0x5a57e210, 0x8bf163ae, 0xfeff3a09, 0xe2f190d4, 0xe049bd23,
+ 0x691f8f87, 0x388f38c4, 0x21af34b9, 0xcdca5e24, 0x9edbd171, 0x1ec27685,
+ 0xb61bb083, 0xa8bde045, 0x8183a1da, 0x18435c8f, 0x1bdc459e, 0xdf5421cc,
+ 0x8470a2ed, 0xbf914ba0, 0x19f24da6, 0x12fdf0a2, 0xded4e3f4, 0x0f984be5,
+ 0x7ae7ea72, 0xf98983f4, 0x5c9abdc5, 0x212efe06, 0x364be69f, 0xfae34766,
+ 0xfe223cfc, 0x5cd97f31, 0xb8f3274e, 0x923f3f1e, 0xb1297bc1, 0x5bbb4067,
+ 0x474a24cc, 0xf2fcd4b7, 0x675c22b6, 0xf41a218d, 0x19f7e105, 0x6f08cf58,
+ 0x653f72ff, 0xa58df765, 0x72743640, 0x62e7c286, 0xf9c030fb, 0xdd9b3bb2,
+ 0x88c323bb, 0xee8cfc03, 0x81b7c37d, 0x8834c27d, 0x7f29aff9, 0xa3e49732,
+ 0x73866d5e, 0x44afadd4, 0x2f22f8f0, 0xc8ec4fbf, 0xfa9cf883, 0x8c7cb4aa,
+ 0xc01a3913, 0x0dba3777, 0xc7dc0cfe, 0x5448ef94, 0xf2da0e36, 0xb87a19fd,
+ 0xf54299af, 0xd92f9a35, 0x0fcb2f72, 0xd1d4aff5, 0x4f2d92fc, 0xfdd3d0cd,
+ 0x7fc6bee1, 0x5b35f20a, 0xbe7cb176, 0xf34ca57f, 0x655e5bcd, 0x4960e1f5,
+ 0x2dc1ec09, 0x68786707, 0xb9a267ff, 0xf1fbb7bc, 0xe5fbb59e, 0x3b50bae1,
+ 0xe332636b, 0x9db8675b, 0x59264cf8, 0x1ef0055c, 0xb2febe11, 0x5a0f1d64,
+ 0xac54c569, 0x4927b457, 0xf325dbe1, 0xf7e56e71, 0x924627a3, 0xb7e60896,
+ 0x3c5144f3, 0x8e18e81c, 0x93afc77e, 0x6e9e9862, 0x38fbe3f3, 0x4f011fa2,
+ 0x77189fd1, 0xe067c835, 0xac789acb, 0x3f8664ec, 0x1c46ce3a, 0xdd839867,
+ 0xcb4aae2b, 0xbc51fc03, 0xf4de39e9, 0x8dbbfcec, 0x1bf68fcd, 0xa0728b9d,
+ 0x07f8ec00, 0x33f5a2be, 0xd2d6f383, 0x93324149, 0x3136b72f, 0x3a206b7f,
+ 0x6269e90b, 0xa5677f24, 0x668ebd50, 0xe4c6870e, 0x466f7e68, 0xc2512bc0,
+ 0x1c389a71, 0xcf78fcd3, 0x5dd74af2, 0x775a1ff1, 0xf01cbe08, 0xf681ca5e,
+ 0xf5b3b7ab, 0xcd7bf0c4, 0xd4188cfe, 0xf557eef7, 0xa6836677, 0xb8c1097d,
+ 0x164c7736, 0x8227bfb6, 0xd93bf198, 0x332ed7de, 0xa0ade997, 0x2c778acf,
+ 0x123ae788, 0x7bec47ea, 0xc58da2af, 0x39d70667, 0xd3af90a3, 0x6369d7c6,
+ 0xe8aaf4eb, 0x64091c95, 0xa7f6b6cc, 0xf7f83ee3, 0x9f2a37f5, 0xe7daa7f7,
+ 0x7d83fae1, 0xd65e103d, 0xd6f93a73, 0xa9e622f0, 0x9c1f6781, 0xf013f335,
+ 0xed8dfd84, 0x52e9a946, 0x5926b3cc, 0xfb35939c, 0x8e1bf33b, 0xd5daca57,
+ 0xb9e2cedd, 0xeba6a289, 0x3a99ddba, 0xed102b88, 0x1027c16a, 0x3dffb41f,
+ 0x89edcc9a, 0x806d2469, 0x93c7c4f8, 0x0ddac28b, 0x9cf6bbf1, 0xe2cd13d8,
+ 0x8af6b5d5, 0x277b789e, 0x9cf4afdc, 0x8c0aef63, 0xc06fd8d3, 0x259cf4cf,
+ 0x5f282ed8, 0x9c73f9d4, 0x3fb7f63f, 0x7e603205, 0xe7b2a685, 0x47d53b15,
+ 0x7e431cb6, 0xecb8385d, 0x7f9a4cb6, 0xc88ff935, 0xcb530bcf, 0xfca4c8be,
+ 0x9fb27f7c, 0x7d9647e5, 0x5bf21431, 0x44feacfc, 0xefc0f3c7, 0x633fc789,
+ 0xaf507252, 0x41592d78, 0x3ae5c9b8, 0x02647402, 0xc7ae8625, 0xe309aaf4,
+ 0x075c04f6, 0xba4d0b4a, 0x6ff77086, 0x07a3eedf, 0x812957e6, 0xf3b0153f,
+ 0x5f803b71, 0xf403b2af, 0xdf7bb144, 0x8eff7b3d, 0x483e5df7, 0x1e027576,
+ 0x16bb23ea, 0x5dfcd265, 0x1fa09f91, 0x3dd0724f, 0xc515f601, 0xf9d01646,
+ 0x9c9b5d4a, 0xd5913fa0, 0xe11eb376, 0x745eedca, 0xfc28178d, 0xf3f7d95e,
+ 0x61b2a5ef, 0xb18f309c, 0xefd40f9c, 0xe06ff2fb, 0x633fadf7, 0x7af983b1,
+ 0xdb96c76c, 0xdb1aff40, 0x4c97f6f1, 0x39fbb30e, 0xc163de62, 0x97bf49ae,
+ 0xfe709bb4, 0x5eae3b63, 0xfdc7f501, 0xe80b23b6, 0x5f31c264, 0x9e85b013,
+ 0xaaa52fbd, 0xcf90e5ee, 0x39d71a2e, 0xc04ddfa0, 0x54aa53e3, 0xf478460d,
+ 0x857c7832, 0xf1dd67f1, 0x68fd9b87, 0x7fdf54fc, 0xfa3afaa2, 0x20c97b91,
+ 0xc433f83b, 0xbdad7a7d, 0x5d2568f4, 0x213efd1f, 0xa2106740, 0x6f3c4f4f,
+ 0x98248ca6, 0xaad1252f, 0x5939b97c, 0x96c2bf55, 0x929f2aa9, 0x7caab574,
+ 0xcaa7929a, 0x56311f4f, 0x7b06ff55, 0x637f2aa9, 0xfd5534c9, 0x2aa5474a,
+ 0x536be79f, 0xd4382fd5, 0x423f2eae, 0xfe43c064, 0x90ebfb51, 0xa0749d16,
+ 0x74f8b5d9, 0x8e90ebc3, 0x87030bfd, 0xed7c5ed6, 0xe1d7b6f9, 0x6b17b0bb,
+ 0xfb0933ef, 0xc5b2cdf1, 0x276f0c6b, 0x0567d24e, 0x75901fdf, 0x18d33eec,
+ 0x94eaebab, 0xa67de0a2, 0xa62f6089, 0x7c58a848, 0x00e347ee, 0x3d980b4f,
+ 0x062028ed, 0x68adbee3, 0x686a3c87, 0x2c0fe678, 0xf81d200e, 0x5cc084de,
+ 0x9e27bad5, 0x5dd6a977, 0xe0d56e4a, 0x5f2a8d69, 0x555dbb61, 0x06d24a7f,
+ 0xe534f955, 0xdd3c1a07, 0x60dfcaaf, 0xd3c1a2df, 0x7e9e0d36, 0xf4172aae,
+ 0x5aedc1dd, 0x451ec0fb, 0xcefef1d3, 0x75c3c072, 0x8f8803a7, 0x72d6ce92,
+ 0x47b5d3c0, 0x855f10db, 0xb039673e, 0x0d43e2cb, 0xa3ea43af, 0xf76831e7,
+ 0xa612635a, 0xb4151a07, 0x1c6c1d6b, 0x46a1e981, 0x75ff7e3b, 0xefa60963,
+ 0x7d303a34, 0xa62a71af, 0x4c4e8d9d, 0xb0db1adb, 0xed8d73fe, 0xdb162ecc,
+ 0x3a45def7, 0x75ba07d8, 0x8278377e, 0x77923f17, 0xeecbf003, 0xc86efe41,
+ 0x37ec45df, 0x25f9a24c, 0xbee844c0, 0x374f29fc, 0x80023aa4, 0xca1c3757,
+ 0x18f1828a, 0x1e473a6d, 0xa477e1e8, 0x3ea1f84c, 0x37bb909d, 0xd16c9338,
+ 0x79a66f2c, 0xb3c63644, 0x83a1f84d, 0x2033d712, 0x33a9d04a, 0xf7c806e1,
+ 0x7772b044, 0x401b84ca, 0xfec6ff0f, 0xff3f4773, 0x61291df9, 0x9ccfe7fc,
+ 0xd760ac56, 0x70d5fc39, 0x30e3c02b, 0x48396fb7, 0x4d09619e, 0x0679f54b,
+ 0x0747b390, 0x80f0b7b8, 0xe009b4ae, 0xcfb3a6d0, 0xebef78c1, 0xb7e8040d,
+ 0x5fe7624a, 0xca95cf51, 0x0dcf41e4, 0x1d4f3c26, 0x605639d1, 0x7814995c,
+ 0x3dbce00c, 0xdee112a5, 0x00640d63, 0x4e29bcfc, 0x3c0f8f96, 0xf243d926,
+ 0x079f0606, 0xb6fc6e52, 0x3858f3e1, 0x62913cf8, 0xcfb6fa63, 0x807a0e91,
+ 0x74a91fc8, 0x3e7ec1d4, 0x0ab8ea52, 0x4d38cfef, 0xad3aff6c, 0x3ed0abde,
+ 0x139a28e4, 0x9219e762, 0xd1f7606a, 0xd82262e1, 0x71916f3b, 0x39e16b9f,
+ 0x7be99521, 0xce702748, 0xe789179c, 0xf63a2382, 0xfeb6819e, 0xb3d70e02,
+ 0xe3dbc283, 0xbd32a616, 0xdd566ca2, 0xfed02f33, 0x6045d67a, 0xe1ce3dd7,
+ 0x34f58fa8, 0x342ae850, 0x8e70dd3d, 0x1cec9b95, 0x9dbfe824, 0xf2d17f0f,
+ 0xfb6e3a67, 0xfd68efeb, 0xda45d64f, 0xaed88651, 0xc2ddf841, 0x358c2f2b,
+ 0xb0b4fea3, 0xe40cbd2a, 0x07ee7ce2, 0x27d5645c, 0x1f503ba0, 0x1727846d,
+ 0x9af25b97, 0xcac90429, 0x3c234ab8, 0xb69d5525, 0xd5d219a6, 0xc237eec3,
+ 0xa3b52913, 0x1a833576, 0x70b7475b, 0xff3ff211, 0x5e748dbb, 0x0acbd78b,
+ 0xfb89cf3b, 0x145735ae, 0xf7e822cf, 0xa23b8f08, 0xeaf3c040, 0xd16f0e22,
+ 0xd787116e, 0x3fae1489, 0x0b9c90e6, 0x67d63f6a, 0x0b5def40, 0xc01ecddf,
+ 0xe72ea0cf, 0x4607e3fa, 0xfdf6ae36, 0xe2ee3112, 0x3afe7654, 0x0994a462,
+ 0x4c2de4fa, 0xfdcee40e, 0xba22aee2, 0x9b0edcfe, 0x1615e30e, 0x7800bdd7,
+ 0x78e76de8, 0xd8769034, 0x4b3cb34f, 0x221df93e, 0x8f754e26, 0xd2f252f7,
+ 0x0f2b69de, 0x7e859795, 0xbca87967, 0x96b4092c, 0xf2145c83, 0x7d4ff851,
+ 0x2f9cd58d, 0x3d3f2037, 0xf31eb8d0, 0x983d1b07, 0xe16c6a1e, 0xcb15b97c,
+ 0x987c69df, 0xe72f65f3, 0x7bf13bcb, 0x4c5ce347, 0x58ba35f7, 0x9519ca3e,
+ 0xecc4fb0a, 0x37c4f8c2, 0xf80898b6, 0x4c3b7ae7, 0x77419f18, 0xc68f63c4,
+ 0x0991fc41, 0xe36a71ef, 0xbe7cb490, 0xf7761e8f, 0x0525377b, 0x1f8be9c6,
+ 0xc8717d02, 0x9874f4c0, 0x4be05628, 0xe4fe8ff9, 0x0fafd006, 0xf4158a2b,
+ 0xcdd482e9, 0xac50ef2c, 0x7c2f9a06, 0x8a5de794, 0x22ac04d5, 0x5be421f5,
+ 0x358a3d87, 0x1f8be682, 0x7b95887d, 0xc7f33a09, 0x06f5ba3d, 0x2259f00f,
+ 0x51fd801d, 0x449cce6e, 0xd79505c5, 0x5f6007a5, 0x325a494c, 0xcec5f609,
+ 0x63e90514, 0x00e1b29a, 0xd88fa7e4, 0xfaab87a6, 0x46de4b0e, 0x57165768,
+ 0x937687a9, 0x846cd6d2, 0xdd879376, 0x376d0faf, 0x8daed475, 0xdf619f90,
+ 0x74fd07a6, 0xf8b1f027, 0x2f223f60, 0x169f05ca, 0x3ba37271, 0x720f289c,
+ 0x0f289ddb, 0x66ca5c04, 0xf60dde57, 0xc976facf, 0x663cc126, 0x0a417d4b,
+ 0x86e89310, 0xbf2949f7, 0x97f53ebe, 0x5db40dd6, 0xc5afe43d, 0x7c370ffc,
+ 0xa6fbfcbb, 0xfbfc30d4, 0x41dfbe43, 0xfbdc43de, 0x0ef64687, 0x2e1c33cc,
+ 0xac4b1df5, 0x712a8ef8, 0x7acf4159, 0x97f3cb9e, 0x9fe5a520, 0x7f8bb4f1,
+ 0x70e7407f, 0x52ab38c1, 0x3fb21fb9, 0x6549a87f, 0x8f735ffb, 0xce728064,
+ 0x6d52ea1f, 0xea3cf7aa, 0x76bfbb08, 0x6d3b38a9, 0xee36b89c, 0x3b693564,
+ 0x1fecc8e8, 0xf70b526f, 0xc7fab2dc, 0x6a788b7f, 0xdf781c6d, 0xe3106ab9,
+ 0xd78173a7, 0x496eba50, 0xde4f901d, 0xdc38097b, 0xfd0e0e1b, 0x9c5843d6,
+ 0x2438bf7b, 0x5daeef1e, 0xb3c57117, 0xfc798d77, 0x827d76bb, 0xafaffa2e,
+ 0xcf5fc195, 0xbbf54fe0, 0x157e60c7, 0xec04ad8b, 0xe7fca156, 0x3fe11777,
+ 0x6df67e5a, 0x179bc9f1, 0x65bbe1d7, 0xf3d8f861, 0xb898f8e1, 0x854dafcf,
+ 0xf3f70a9e, 0xde121e20, 0x7e738239, 0x1f6ba265, 0x1653d3f4, 0xce0e9bf8,
+ 0xddec71a1, 0xaed183f0, 0x325df0fd, 0x1106b8b2, 0xe75a7c97, 0x6de815f9,
+ 0x19fa3def, 0x106eb3f2, 0xbc8f7416, 0x97a0f341, 0x7ce6c3fd, 0x4647e013,
+ 0xefa18df8, 0x7f140f8f, 0xff2e1bfb, 0xdf6ca7fa, 0x9ed43889, 0xa0665f6d,
+ 0xfb12eefd, 0x54782062, 0x70fde3c8, 0x24b7a43f, 0x9767e512, 0xdef07c44,
+ 0x02695771, 0xe95d2dea, 0xdfa43d46, 0x2bb8b9f6, 0xd7fb1b3d, 0x92bb8f9e,
+ 0xdc6ccc4b, 0x7d2153c9, 0x2154f92f, 0xf0dfbdc8, 0xa376cbf8, 0xb03de0a7,
+ 0x408d8f0f, 0x928dfeff, 0xa0e010bf, 0xbd77573d, 0xc94ca0b5, 0xa6be7fed,
+ 0xeb049beb, 0xbbae3dab, 0xe95dbe1b, 0xfd76bb79, 0xb9c408df, 0x15ff5b8f,
+ 0xaeeff781, 0x19ddfcfc, 0x5e80ab93, 0x12026ae1, 0xf545d319, 0x54bf9a09,
+ 0x8939d6fc, 0x4333d39e, 0x6f25e5ce, 0x9e2e38b3, 0xfde7cf6a, 0xed5c09de,
+ 0x960dc751, 0x5e308afa, 0xe147f645, 0x7b1d60bd, 0x73c4436f, 0xf3cfc9bd,
+ 0x243ebcf4, 0x9d70ed0d, 0xfaf3aa19, 0xfa2d1f1d, 0x0881f21e, 0xa678ef8c,
+ 0xcc3c44fd, 0xf19d8ff5, 0x0945793f, 0xedbd77d2, 0x9df4246f, 0xbdf5dac0,
+ 0x86d77caa, 0x7056fbe0, 0x5ff6ab1f, 0x2a25ca32, 0x4f105ac7, 0xdae335e4,
+ 0xda4af910, 0xef07dcfe, 0x55df94d1, 0xbe50c002, 0xd074cf36, 0x3cfc9576,
+ 0x8de44844, 0x92aeda0e, 0x67891f9f, 0xe78f2b25, 0xb09f3df5, 0xff28ba7c,
+ 0x7fac4ce3, 0x1c6fe895, 0x79164f2b, 0x22d5dfde, 0x9623789f, 0x25f68a67,
+ 0xc6239f2c, 0xaded64af, 0xade4feac, 0x7a099cff, 0x33f7e08d, 0xe09cb8d2,
+ 0xfe5152ef, 0xba2b4cef, 0xba8ebc68, 0xf107cb9c, 0x1dc5550e, 0x85df22d3,
+ 0x6126dc7d, 0x9ded61ec, 0x9fe7b406, 0x0dcb698d, 0xe22f2fbd, 0x56e59c7a,
+ 0x7baaf38c, 0x9976f871, 0x1e813bc7, 0xe9fb9cb3, 0xfa0b642b, 0x65ef7a61,
+ 0x3d207e7c, 0x97fae570, 0x57ecf855, 0x46d3dfce, 0xef1d2547, 0xf1130fdc,
+ 0xd619027e, 0xee02f189, 0x27c44934, 0x116abde0, 0x45971757, 0x8e7e701c,
+ 0xbd82297b, 0x13b27aa7, 0x97caeff9, 0x6ebb7d98, 0xef28ebcb, 0xda0aca96,
+ 0xea1ebe97, 0xe9f0075a, 0x2f77b2b6, 0x87dfae57, 0xc531f4fb, 0x8160fdc6,
+ 0xbcf0a151, 0x3dfc3fb3, 0x8517f169, 0x3ffcbabf, 0x5dad7f0c, 0x5fd7dc5d,
+ 0x7ff1857d, 0x07e656dd, 0xfd3c73b6, 0x7314a749, 0xf0023d78, 0x33a2b73a,
+ 0x20865a3b, 0x778c4eee, 0x29df90ab, 0x6f56f382, 0xde009583, 0xdccea5bb,
+ 0x5fe0c30f, 0x9f38ae7b, 0x69715441, 0xf7c3fb3b, 0xf7d04be9, 0xfa4dffd3,
+ 0x8dfbd44e, 0x1f1bf076, 0x15e5ef65, 0x18c9fe77, 0x4ef41f1a, 0x0f073b1a,
+ 0x317e676e, 0x2c171711, 0x713c32b7, 0xd55d53ff, 0xffc1e33b, 0xc4c3f624,
+ 0xfe06d248, 0x76d74a04, 0xa076d74e, 0x41bf416b, 0x176d143f, 0xfa41be06,
+ 0x912e2c25, 0xfdb7e9c3, 0x25e1fae1, 0x7fe1fae0, 0xa9bbae13, 0xdbfe8c3e,
+ 0x4ed02217, 0x3ff385a3, 0xbc055c38, 0x0e2fd323, 0xfff4c8e7, 0xd3239c0c,
+ 0x439d9515, 0xf9207bc0, 0x988fc5a4, 0x5a7d9877, 0xe9f64df4, 0x4f9c1923,
+ 0x8f18fde9, 0x4c7bc5ab, 0x27bc3f7a, 0xef1c5fa4, 0x30fff2ea, 0xd370b5de,
+ 0x9fdcb5a6, 0x985efdab, 0xfbbf203e, 0x7ff8e056, 0xb0b04fcd, 0x7caabf61,
+ 0x54b7faf1, 0xef3c4be5, 0x415f965f, 0x5bfffbd8, 0x57e105fe, 0x2afcf998,
+ 0xb51ff81d, 0xc43741f2, 0xc7a023f9, 0x7afe5f1b, 0xf93087d4, 0xb78c6cea,
+ 0xe5af8dba, 0xff7ff18b, 0xbe947be4, 0xf66068be, 0x3ffb63d6, 0xfd392837,
+ 0x79e165e9, 0xd084711d, 0xeff5c2d9, 0x5acf401b, 0x54fbd848, 0xa60ffada,
+ 0xc6307b33, 0x30be5149, 0x710c4cd7, 0x9dcc1f94, 0xcf4beecb, 0x0c630705,
+ 0x2d173ea6, 0x3e27a99f, 0xd2bb8f78, 0xd099f7a2, 0xffbea9ef, 0x75efe26e,
+ 0xd558b893, 0x21d9783d, 0x9cdf9c63, 0xbd2fe612, 0xf786d2c5, 0xba1de787,
+ 0x60f7dceb, 0x14f46f2f, 0x7177b8b1, 0xbaf7f0ff, 0x3e83f12b, 0x9c2a7a08,
+ 0x5fee24fb, 0xff40635f, 0x2addb6ba, 0xca669fbe, 0xd9a38b12, 0xc533e2c3,
+ 0x3beba4fe, 0xf767ca64, 0x48f7e060, 0xbe0c1b2a, 0x67a0b9e1, 0xbb3d47ef,
+ 0x2e4364be, 0x927eafe0, 0x1b94dc74, 0xafd4ef3c, 0xd7b60bff, 0x7a6d67f2,
+ 0x4fd5f6b9, 0xbd210f1a, 0xb1d17388, 0xb5e61f46, 0x1305d6f6, 0x93fd17ff,
+ 0x6de2ff63, 0x57dc7482, 0xd0c70f8e, 0x3b1bfb75, 0x827b2dff, 0xbb0823b0,
+ 0x214ed682, 0xbf7888f8, 0xe36e97d2, 0xa296b2ef, 0x59e883df, 0xc1edf82a,
+ 0xd7f9fcfe, 0x27d717e9, 0x61ffe5d5, 0xf4b97cfe, 0xe4c49b5f, 0x8fee96aa,
+ 0xed0cfd56, 0xb5be82cf, 0x6200bff4, 0x0bf8e852, 0x27bc25ea, 0xab55773e,
+ 0xcdf49c61, 0xe5b57de9, 0x9b830664, 0xb15c2e46, 0x3c78503c, 0x0be78c87,
+ 0x0ec6bc93, 0x87810f76, 0xefd5d3af, 0x48bc5303, 0xab971719, 0xfafff2ea,
+ 0xa2e4e039, 0x8917266f, 0xcb489f4a, 0xe56eb7e8, 0xfe56eb12, 0xb90eeb9b,
+ 0xd648b4a7, 0x40e3ef05, 0x81c435fc, 0xfdd978f6, 0x56ccead4, 0x5203ddfc,
+ 0x7e028812, 0x995eeb77, 0xde8e9efd, 0x790e4fa1, 0xf88bad3f, 0x5c7a003e,
+ 0x3bbd9e35, 0x769b8da4, 0xd5ea78f3, 0xbf78dd96, 0x9a0efb51, 0xf376cb88,
+ 0xa1efb4fe, 0x9de2f689, 0x687bed03, 0x1c783253, 0x67c93e76, 0xe7172971,
+ 0xcf20dda3, 0xdd35fc43, 0x5da2355f, 0x4ac7c6e1, 0x05a4f3ee, 0xa32732f1,
+ 0x9799df1f, 0xa3be7171, 0xd32fff2e, 0x81dd6caf, 0x94aed8f7, 0x3a64477e,
+ 0x827f40dc, 0x9bf1f72f, 0x6fc84c57, 0x3df33bc4, 0xf7c19e6b, 0x24be7a87,
+ 0xd4bd97e8, 0xbb13e33b, 0x09c435d8, 0x564dbd27, 0xc771d78a, 0x1baf683c,
+ 0xf785c47b, 0xe3bcc776, 0x927f8880, 0xc329c077, 0x233e85bc, 0xff209bf4,
+ 0x78d9f7e2, 0xf2e5d59c, 0x37f52bb9, 0x8cfca7fe, 0xb75d5ee2, 0xbf0457c1,
+ 0x13d9e0e7, 0xa103bf81, 0x1993ff9d, 0x93be8bba, 0x7ae511dc, 0x8b34f012,
+ 0x5ef109cb, 0xdecc8572, 0x94edef49, 0xeeb85ed1, 0xabfb7e7f, 0xdb4b9547,
+ 0xbd6dea15, 0x2265cf61, 0x7bb1d7ad, 0x0ae5f92d, 0x79c249c6, 0xc287ec0d,
+ 0x7fada89e, 0x297b294a, 0xe35bed03, 0xdeda3df1, 0x067cd987, 0xfafd57c2,
+ 0x603f8e00, 0x7ebf1f39, 0xf42d916f, 0x19f3959d, 0xdb43e77d, 0xdf107329,
+ 0xff174b97, 0x332dced7, 0xa891e265, 0xbc91cd7c, 0x4c25ef4c, 0x3a405dff,
+ 0x02445d31, 0xbb08ba98, 0xd894b0cf, 0x9c4e5d31, 0x5c55ae98, 0x3718195d,
+ 0xf8c04814, 0x39ff17d3, 0xdce6e80a, 0x215ae375, 0xf2dbf146, 0xbef56923,
+ 0xbd853c9e, 0x3fc2f497, 0xd9f4077f, 0xcb863ff3, 0xa2471be2, 0x1848641c,
+ 0xa57bd33f, 0x54d7bb32, 0x17dc5df2, 0x325dfde2, 0x96e1f989, 0xfee26627,
+ 0xc4cdf209, 0x826f826d, 0xb8e7393f, 0xdcc3c58e, 0xc67be12a, 0x6e1d7eed,
+ 0x99159cb1, 0xb9ddf85e, 0x3cacddf6, 0x2bda2ea7, 0xd8ce7cd1, 0x26be5608,
+ 0x4ff70bda, 0xee3f1216, 0xfb70c5cb, 0x4bfb8644, 0xdf8a2f8c, 0x8227a00b,
+ 0xbf6d12a1, 0xeeccc3a2, 0x30ff1051, 0x70b9ffe0, 0x4f170a7e, 0xf1f18433,
+ 0xbf1943d1, 0xb6a65d1f, 0xe5e50c87, 0xdf6529f7, 0x0cb47807, 0x810d6471,
+ 0x9b9d31fa, 0x3b042c1e, 0x9f808e90, 0xb7b1b3e6, 0xb4535fa3, 0x1b29517b,
+ 0x959ff501, 0x67bfbc58, 0x4c6fbf2f, 0xfea10902, 0x794ab5b1, 0x1a2bd42e,
+ 0x40d3f8c2, 0x51df8570, 0x2f398674, 0xd1d1f88a, 0xbb436670, 0xd277c13c,
+ 0x7e58959e, 0x6f5be3f2, 0x5f4168dc, 0xe3f40782, 0x44d71517, 0x91b46f18,
+ 0xffcc0b10, 0x1b7efca7, 0xbb00c869, 0x4cc7aae8, 0x3e2fd03a, 0xee18e2a2,
+ 0x9e81fcf7, 0x98fd21b7, 0xfd219b9e, 0x43373d23, 0x9b9e9c7a, 0xcf413d21,
+ 0x38ae90cd, 0xccc7876f, 0x8e2189c9, 0xf0bfd0b9, 0x5be769f7, 0xd7f18439,
+ 0x1af7f1be, 0x14fbfc71, 0x0fb7c217, 0xfe087bdf, 0xd1b3edde, 0x8b989481,
+ 0xdecf5bd0, 0x749fa3bf, 0xff08b820, 0x0a7cb6a3, 0x6eee6bc7, 0xdcffca3d,
+ 0xcad47f76, 0x872b7a90, 0xce7db118, 0xa0a3270b, 0x1f5b6eff, 0x5d121d7c,
+ 0xcb1d4cf2, 0xb9fc7caf, 0x828e371b, 0x0fbe3bf9, 0xf9f74174, 0xdb73486a,
+ 0xfc00fb7f, 0x1fed2a5e, 0xa47a24e3, 0x2f3c66c0, 0x85a1d668, 0xb3d75883,
+ 0xa09b9dd1, 0x0c2fb3fd, 0xbe509585, 0x01bed843, 0xadc2923a, 0xe7ae0377,
+ 0x10a05346, 0x78dd0bee, 0xa71b0e41, 0x8a529f7d, 0x7a064e70, 0xcaddfe43,
+ 0x025f4653, 0x7f74df6f, 0xe223fb6b, 0xa5e015fd, 0xafa5c80a, 0xac2f40a2,
+ 0xed04f1e4, 0x06fd87bb, 0x2439e9d6, 0xdabdf813, 0xfdea31d1, 0x49e38bb7,
+ 0x8d7b39a4, 0xb3d7c04e, 0x830d4f7b, 0x7e2989f7, 0xc57bc186, 0x455c86db,
+ 0x31ef7f42, 0x8f97ec67, 0xf587183c, 0xe769f7f1, 0x10156d91, 0xbcdf3337,
+ 0xd2580dff, 0x0af1db42, 0x9c599b88, 0x74841d24, 0x19399289, 0x7dc465e2,
+ 0x4a236583, 0x9a96c20f, 0x7d44af61, 0x4c9814ae, 0x37287c88, 0xd847f247,
+ 0x558a3c85, 0xa524a7e5, 0x534feaaa, 0xd3e554b2, 0x95548c47, 0xd867718b,
+ 0x46f5540b, 0xc28604c7, 0x83ae8e79, 0xa4ff03bd, 0x3986f18c, 0x7eb91c2f,
+ 0x7ccfcd24, 0x43be0e6a, 0x9f2f2cf9, 0x17b95cf9, 0xe143d1f0, 0xd50aa469,
+ 0x6c1f92e9, 0xd33a107e, 0xf76a179c, 0xa1d0713e, 0xe179c65c, 0x8184e712,
+ 0xed164fde, 0xca04e7b5, 0xbe001f37, 0xd9c5fa39, 0x3edbf036, 0x14cbf63b,
+ 0xcdfd4788, 0x0caefe10, 0x440c3f3f, 0x43fb7d37, 0xbcdd1852, 0xc3279325,
+ 0xf2440dd0, 0xe9643a32, 0x7eecc3cc, 0xb5f295de, 0xa1af814f, 0x4243c0bd,
+ 0x6b577f7f, 0xb46d1bdf, 0xb036e6ff, 0xc32bbd47, 0x7bbea50d, 0x6fe12b93,
+ 0x64ef4839, 0x93bbb6f9, 0x07bbf0e3, 0xb73761f4, 0xb8520df7, 0xffbb553e,
+ 0x60c2e4ee, 0x5c775939, 0x29dc9f55, 0x1bf2ab35, 0x7bf9d533, 0xdb439b4b,
+ 0xad8fa40f, 0xd189787c, 0x6ef70395, 0x37bfb0a5, 0xfff3e62c, 0xd5800901,
+ 0x00800020, 0x00000000, 0x00088b1f, 0x00000000, 0x19b5ff00, 0x6554540b,
+ 0xcef7bbfa, 0x7860190b, 0x77421028, 0x840a4498, 0xb0285789, 0xd71ea08d,
+ 0x8f4c1ada, 0xe5935654, 0xe04d7903, 0xe3d8f4b6, 0xb68fad18, 0x695b6d07,
+ 0x9656356b, 0xb139e4e7, 0x36254644, 0xeb495bae, 0x66a254d6, 0x42d899e4,
+ 0x7a26704c, 0xf75a9d6d, 0x5efffefb, 0x5b602e67, 0xe74ed69d, 0xffffef9f,
+ 0x27ef7ffb, 0x70ca1490, 0xf60800ce, 0x9970ccac, 0xd6f70601, 0x8018e41a,
+ 0xe2eff4d3, 0xf9b8daf0, 0xcf03837a, 0x3a380057, 0x01cfe3cc, 0x031401d6,
+ 0x7b81295c, 0x5914f3a2, 0xff60e760, 0x2fbdf165, 0x00490801, 0xde8d179e,
+ 0xe38456ed, 0x6e67065c, 0xf08d9ef8, 0xd918064e, 0xbfefff72, 0x25f5c22a,
+ 0x8c0ee3b0, 0xbd0d43c4, 0x5c75d79b, 0x9fcd7114, 0x77d1d704, 0x98809679,
+ 0x55706b80, 0x00e207b4, 0x3c636a9a, 0x679e3e62, 0x2e990e86, 0xa6f1c804,
+ 0x01529bb5, 0xc0228a8e, 0x78074439, 0xe3ef14a0, 0x245f041b, 0xa4ef39a7,
+ 0x67c8b9df, 0xe7c72fcc, 0x35b03245, 0xe99432bf, 0x7ed77bc6, 0xbf1ce787,
+ 0xce91a203, 0x8f4a803f, 0x2e5c4c03, 0x19bdbb04, 0x3f233ffe, 0x1812bd4d,
+ 0xf0619f90, 0x605aba1d, 0x25a9ccd7, 0xa7e92b00, 0x061dfb4c, 0x196fd890,
+ 0xb2957f70, 0xe57cb2bf, 0xf08b10a5, 0x2040fd56, 0xa70fbd9b, 0x7fd5fff1,
+ 0xf198376f, 0xda53f57c, 0x530f427d, 0xfbe52f90, 0x77b3f03a, 0x3de277eb,
+ 0x235ef853, 0x8499fddc, 0x697636ef, 0xc7245fbf, 0xe0e60d24, 0x3828028f,
+ 0x916db12d, 0xf1366bde, 0xdf4ae6f7, 0xea097bbd, 0xc925e9b1, 0xd1adc46e,
+ 0x00e2d3dd, 0xa83983f9, 0xf2f1d4e4, 0x7a8cda6b, 0xa7c30c2a, 0xbdf34b76,
+ 0xca175f74, 0x5e319ea8, 0xe2c960ce, 0x5f1c2cf8, 0x0bd7c573, 0xf735f101,
+ 0x7ed0d0e8, 0x1146cf00, 0xcf3c08e4, 0xf2ae31ed, 0x07f4c39a, 0xfcc79c2d,
+ 0x66132f9e, 0x1d75f2e7, 0x1ced01d1, 0x98bf702f, 0x093e8021, 0x60b541f1,
+ 0x5f4b8edf, 0xc925724f, 0x9f004fbf, 0x589ec05c, 0x5cfd4264, 0x7da39fc1,
+ 0x8fe02433, 0xe11d6c94, 0xfdc8a859, 0x7c7fd28a, 0x8b77e023, 0x434f167b,
+ 0xd750e00a, 0x0cd43eb2, 0x0c6d906c, 0xe8f012df, 0xf17d2f49, 0xa416f4ce,
+ 0x604932f3, 0x1f17dff6, 0x7f10161a, 0xd0b4455f, 0xeff7b026, 0xbe55f7a4,
+ 0x74cef4fa, 0x8e6be337, 0x26f51065, 0x4e902e38, 0x47978f47, 0x183aae58,
+ 0x712bf554, 0x9c7f2177, 0xfb3edd2b, 0xd1dbf412, 0x223160a5, 0x684b97bd,
+ 0xabc30838, 0x49ab8fdc, 0xae5133d6, 0xe8813f82, 0x6e17966c, 0xe4bbf191,
+ 0x97417bd6, 0x1d372118, 0x2f5533f7, 0xd3c71caa, 0xf72de2a1, 0xd1bf903b,
+ 0x9fb3021d, 0xecccbb46, 0xe4fcb1b3, 0x7f104b83, 0x0bb25fa3, 0xeeb2cf48,
+ 0x7e4847bd, 0x403b6b1d, 0xe7401e77, 0x2eb66eda, 0x527d9933, 0xd98be31e,
+ 0x414688ad, 0x6056ad7c, 0x7c35a7c6, 0x0c7be61e, 0x7c3f51bc, 0x3804ce06,
+ 0x9e7ceb18, 0xfbf35bf8, 0x1096fbcf, 0xe3ca1bb5, 0xad901f99, 0x3fa61b9d,
+ 0x466000df, 0xa3db43fa, 0x3c304fbd, 0x6125af68, 0x27b13d7b, 0x9e0b70eb,
+ 0xcf53789f, 0xc55f75cc, 0x416ea7c3, 0x68f6cd78, 0x0913e726, 0xf3a549e0,
+ 0x3d7ba627, 0x18a56178, 0xb9216fea, 0xb7d8c677, 0x47f1f9e3, 0x13bb3fa7,
+ 0xa767dae1, 0xf24c89d9, 0x7de5191f, 0xda011d3c, 0x7d953e7f, 0xef1c2907,
+ 0xa52fc50a, 0x57dc6667, 0x24cfe74e, 0xaa8f09da, 0xa347a1bf, 0xfaf2801c,
+ 0x16797c12, 0x8293bd34, 0x87c45067, 0xc79dc4eb, 0xdbcbb404, 0xc483ae0c,
+ 0xfe47eaf7, 0xf90ca87a, 0x37e67aa9, 0xfa44cf0f, 0x0c9bdf6a, 0xaf584ef4,
+ 0x6c40e2e3, 0xdffc9720, 0x915ffdc6, 0x288edd4f, 0x7111c7cb, 0x5e23a1a6,
+ 0xa7753703, 0x888e3e5a, 0x65c07537, 0x8e82f50c, 0xfc57a9f8, 0x1d745eaa,
+ 0x201aba25, 0x8422e3c0, 0x0557640c, 0x78a0e092, 0xc8c7ba10, 0xced63fe4,
+ 0xd1916546, 0x8b822f51, 0x224179e2, 0x6fc85298, 0xc17e5c5d, 0x713fa67b,
+ 0x9266ca17, 0xfbf54135, 0x223385ac, 0xf1bfb3ed, 0xcdcfb215, 0xc39f6646,
+ 0x8d2f3c51, 0x391ff3c5, 0xc2bf7d9e, 0x87f305f4, 0xf5a4f933, 0x17385adf,
+ 0x0aef141c, 0x9bc2e4da, 0xf4516d70, 0x29c52c72, 0x1dee4958, 0xc03aeff7,
+ 0xe6f5b9e4, 0xbf7784a3, 0x0e0fe999, 0x0507b970, 0xf7d5279e, 0xa0429856,
+ 0xb77a242b, 0xfdd57a31, 0xf3872dc1, 0xe0fef85c, 0x8079390b, 0xf24cbcf6,
+ 0xe505fe0f, 0x7fc62a73, 0x3b5c36ec, 0x853bbff7, 0x7a58e0f2, 0xd9475beb,
+ 0x2c3c2a7b, 0x4f5438f0, 0xf7fee07c, 0xa264ce99, 0x8b08c313, 0xcd77030f,
+ 0x2b9bf260, 0xfe91c6e5, 0xf4b42783, 0x7d53a58d, 0x7d4fa55f, 0xcd37bd5f,
+ 0x8e39322a, 0x9479fc18, 0x90cc5ff7, 0xc48d7c35, 0xcde2f3fa, 0x75e16fb4,
+ 0x11c20244, 0x3f4356f6, 0x2635bf51, 0x5f48db8c, 0x6f608d4d, 0xa1efb603,
+ 0xcfab89b8, 0x29f5e785, 0x03722b2f, 0x78ed09a7, 0x906762b1, 0x6eecc894,
+ 0x5ebb7011, 0xabedc4ac, 0xe80f43a0, 0x75c4472f, 0xfda035bf, 0xa03c770d,
+ 0x5dc64577, 0x74f151cf, 0xbb8f4fce, 0xa6c84a9e, 0x31623df8, 0x9e66bab3,
+ 0x7bb1d055, 0xf74e90e9, 0x43eedcf0, 0x1a74f03b, 0xcf486ded, 0x8173a2e3,
+ 0x6f53e515, 0x1f91e5f0, 0x2e3ddfa8, 0xb0fed8ba, 0xe9056070, 0x3cbe741b,
+ 0x1bc4ef56, 0x233ac040, 0x77eed938, 0x25f65d50, 0xd412b8b0, 0xe2274d43,
+ 0xdd12aa2d, 0x3c70e69d, 0x5167e354, 0x5ca3ee0e, 0xf55f682b, 0xa29bb457,
+ 0x30fded7c, 0xb8f85a3f, 0x515dfb95, 0x98eee8a2, 0x576e5fc0, 0x1d06dcf4,
+ 0x9e67f712, 0xb914cb47, 0x4522dd63, 0x4a8d2dd6, 0x9ac60f9c, 0x53f2123c,
+ 0x82f51bb6, 0xb7ce9970, 0x028c5697, 0x9dfa8ad0, 0x5efe3e05, 0x539e36b7,
+ 0xf2ca590e, 0xcbcb0e72, 0xaf7514b3, 0x7a40dc17, 0xc2fe5135, 0x2fc12ef5,
+ 0x082bfad1, 0x1601d5b1, 0x06a8ad1d, 0x2701ceb6, 0x9b81e75b, 0x9da1f3ad,
+ 0x83a00bad, 0x9f8297ad, 0xaf8170ad, 0xb83e580d, 0xf98832dd, 0x52bd7e18,
+ 0xb45cbca4, 0xfc7ae264, 0x675e4571, 0xf9460797, 0x8f2f9f92, 0x614ae079,
+ 0x2e4d9d74, 0xdd99b353, 0x923172ab, 0x5177e27d, 0xb5a14de0, 0x9dec0202,
+ 0xf190c98b, 0xeb20d99d, 0x0702ae08, 0x48fee783, 0x5c069479, 0x04ee573a,
+ 0xd89aa972, 0x7628764e, 0x5d364c52, 0x87d7d61c, 0x54171e56, 0x49d201bd,
+ 0x3ebc60f9, 0x2ce88321, 0x5cfcae8a, 0xdaf190c6, 0x3a9df7b6, 0x8545a38c,
+ 0x84362d95, 0xe53f590f, 0xf3e55970, 0xd91f0899, 0x9ba9d276, 0x595e7649,
+ 0x1563b7a8, 0x39d86eba, 0x184dcf07, 0x4e50a3fc, 0x52824d92, 0xb1515d5c,
+ 0x677e8079, 0x74ebac94, 0xdbc657e8, 0x5719c580, 0xd59f8014, 0xe46568b3,
+ 0x7ebc3527, 0x7ae1635d, 0xbd706bdb, 0x60da7e4a, 0xc8cac5f2, 0x73759ad3,
+ 0x6e5f2993, 0x3ff7f030, 0xbce72c9a, 0x22327282, 0x9841533e, 0x44f73c4f,
+ 0xe4101c21, 0x186b5696, 0xf7c08fff, 0x77c21fcf, 0x5deb8a6b, 0x594dcf16,
+ 0x534ffa40, 0x676779f2, 0x245d8a59, 0x3f8616fc, 0xd2d59310, 0x5207478a,
+ 0x7bd21f9c, 0x776e18c1, 0x5eb95a1f, 0x329ab6ce, 0x27581f1d, 0xfbae0fd8,
+ 0xe28f977a, 0x084827d0, 0xd599f3be, 0x34744035, 0x428c8189, 0xd11dd7d4,
+ 0x27640cc7, 0xa80b1daa, 0x7fc8a5bc, 0x06bc039b, 0x96e51fe6, 0x2d98f533,
+ 0xe5c107ec, 0xa5ca1ef8, 0xd2ace9c8, 0x8d4971e3, 0xa5ad1f7b, 0x3c2af6ae,
+ 0xa2413c21, 0xad0a49a7, 0x1538bb20, 0x13e19eff, 0xb953a7e6, 0xabf12a3d,
+ 0x6def4f67, 0x42741c69, 0xed361f84, 0x0fabe6f9, 0xa34ddf50, 0x0f5d3b66,
+ 0x1696dffb, 0x1ab00bea, 0xd517c4d4, 0x1b75672f, 0x955fd47d, 0x397f3eed,
+ 0xaf78abdd, 0xfa7146df, 0x1b40fee2, 0x9ec1cb95, 0x2fdc69c3, 0x6bfe3ad4,
+ 0x93e4e7e1, 0x750512b9, 0x905ecbac, 0xabe446bc, 0x050bea99, 0xdc7c20f6,
+ 0x47137684, 0xa9bf79f7, 0xbd0d95f6, 0x2fa819af, 0xc43c67c1, 0xff42ad6f,
+ 0x5c37adaa, 0xad62f54a, 0xd62fdb57, 0x13d77bf5, 0xb43b75dd, 0xd9bf6afb,
+ 0x4f5f7ca4, 0xea8d9af5, 0x26bded3e, 0xa8f337ea, 0x67eed3fe, 0xa6fd2a66,
+ 0xa940ff92, 0x772a5733, 0xeb333f88, 0x235e0cff, 0x68fcd6f2, 0x7042dd8b,
+ 0xe2ced9ba, 0x6606fd6d, 0xd87deac7, 0x446cc89a, 0x8ddadbf5, 0x5567eac0,
+ 0x1b4ff98e, 0xfc8fa41d, 0x5d5993a7, 0xab3cf58c, 0xf09e3047, 0x22651efe,
+ 0x173ddda0, 0x1114ca1f, 0xd93d73cf, 0x5fb7aa76, 0x7f80eb5e, 0x4fa6179d,
+ 0x4ae7f7ad, 0xd40cab3b, 0x7d88dd47, 0xf7356e14, 0x4266d93e, 0xd01379b8,
+ 0x3b2d240d, 0xe2a6ea8e, 0xe97812fd, 0x503ef01d, 0x1a976b8e, 0xbeb0524f,
+ 0x9447908f, 0x09e4093c, 0xa2a379fa, 0x04ece8b7, 0xfd8c79cd, 0x71f7cd1c,
+ 0xefda99a5, 0x6e7f0e3d, 0xfe73c509, 0x02e3bc7d, 0xc136fdcd, 0xcd91f76d,
+ 0xbc3ff004, 0xb188ae57, 0xcd82bfc2, 0x17e7121d, 0x886fee68, 0xec9fb79d,
+ 0xdd0bfcbb, 0x4b703b18, 0x01657764, 0x2f504780, 0xe7b586b3, 0x21db07c5,
+ 0x1d47f116, 0x57998dd4, 0x16ea8078, 0x5fddaca3, 0x54c5daae, 0x4399aa98,
+ 0xb73b919c, 0x9121d1fb, 0x9c0945d9, 0x117970f7, 0x5e0f59c9, 0x46dcbc79,
+ 0x66fba569, 0x598bf303, 0x8a762dbd, 0x5a9d9347, 0x68d727f9, 0xd2ea9fe5,
+ 0x956d3bca, 0x6ee9de56, 0x6dcfbcad, 0xead7cad5, 0xb6cfcad1, 0xfee69671,
+ 0x0d4af6b4, 0x02f37d3c, 0xbdf3fdcd, 0xce70350b, 0xf734ab8e, 0xd32c7467,
+ 0xaf77e79c, 0x76ab9cd6, 0x2e0ed636, 0xb18f35f4, 0x08c41133, 0x567aabfd,
+ 0xff70a0ed, 0xff3c1aad, 0x1f6ffd6f, 0xc8a7ffa3, 0xbdde31d7, 0x37743b15,
+ 0xd165ebb9, 0x999dae3c, 0x59eb9427, 0x9cb6f6bf, 0x77431558, 0x54e6fc95,
+ 0xff941bf2, 0x0e16c391, 0x7df6fddb, 0x8e0acf14, 0xae88ab38, 0x1f7b80a2,
+ 0xa192f385, 0xba38aaf6, 0x32d900ef, 0xe89c8f85, 0x02a5e5fe, 0x857e34e8,
+ 0x3cb094f0, 0x93acf0af, 0xd972f0e2, 0x1636de77, 0x4be9c96e, 0xa120f3c2,
+ 0x6a85e794, 0x22e81447, 0xeca152e4, 0x29e92503, 0xf3abf961, 0xc007ec23,
+ 0x6880fd40, 0x2759b6f2, 0x9bec77aa, 0xb98f5625, 0x86f67d58, 0xa57362e0,
+ 0x067f2645, 0x25dff7c5, 0xc4cedebb, 0xb44a76b8, 0x139eaccb, 0x54c46d02,
+ 0xa4a31890, 0x76afa9e5, 0xed871f50, 0xff2bcd2c, 0xb56d4774, 0x6f919727,
+ 0xb6f09409, 0x67f5fe99, 0xa2648eba, 0xcb0407fc, 0xf6fc42fa, 0x332759ad,
+ 0x25197f28, 0xcd014494, 0xe9471c4f, 0x24dcccfc, 0x78c3f919, 0x0f65101b,
+ 0xab73c289, 0x9390fac0, 0x08ccd8f4, 0x67a8ddff, 0xbe940b79, 0x5e451aec,
+ 0x54b65f6a, 0x4f803fc1, 0x7e78c2ac, 0x4c1bf74d, 0xc329752e, 0x6dca1cca,
+ 0x37fbe0b7, 0x5017354c, 0x428e0a5f, 0xd5e7ef3b, 0xfa4d2d3e, 0xed557929,
+ 0xbf76cf6b, 0xd348652e, 0xc4cec32f, 0x6391e709, 0xbe615ee7, 0x9b03fbf9,
+ 0x1a1e59a2, 0xe6ce94d8, 0x4ff7e18b, 0x71aff7b1, 0x93b1a3bf, 0xd7df5aeb,
+ 0x9ef5dfd8, 0x81e7348f, 0x0d3e90a4, 0x4aec0ff9, 0xca35779d, 0x6305e46f,
+ 0xa8abf509, 0x715b38b7, 0x3dc0fdf8, 0xbe10e7d3, 0xa7e7cdff, 0x6bfdbe4c,
+ 0xa6ee6cfd, 0xed6c79f2, 0xd6070611, 0x963ad806, 0x55bfb54f, 0x20dfc357,
+ 0x90e5ea9b, 0xd13ec930, 0x1b31e6bc, 0x67fa83ef, 0x7ca4a94f, 0xd06e9fdc,
+ 0xc38b35f1, 0x0e26a5a9, 0x6b4f9bcf, 0x48de6f50, 0x00bf6dfd, 0x61ed010e,
+ 0xec7ce0a9, 0x3abbe47a, 0xa36b95d9, 0x2875727a, 0xd0fe874f, 0x56b81f94,
+ 0x1ebe7d40, 0xfe27caef, 0x53062c05, 0x599d1813, 0x890c37d4, 0x63013c9e,
+ 0x764f4dc1, 0x3ffd5357, 0x8a73c934, 0xadad7632, 0x83fa9aab, 0x8ff70321,
+ 0x847c9e5b, 0x16b7c3f9, 0xe77a4cd7, 0x31f24113, 0xf0497e7b, 0x16f6676e,
+ 0xf88c2c30, 0xaf3a82bb, 0xfa9b7ea1, 0x5f14609b, 0xdff8db67, 0xacc72a5f,
+ 0xae3c6d4b, 0x316b42dd, 0x2ceee5e9, 0xe8ca7bfa, 0x5f902366, 0x48873e20,
+ 0x5cf87af8, 0x40f20a76, 0x6f560d75, 0x78285fac, 0xf8a3e8d5, 0x1675cea1,
+ 0xbdecacdb, 0xd79f1b24, 0xf467dd24, 0xeefcb1b6, 0x3a46a8cf, 0xef58f5db,
+ 0x1070df50, 0x846d1cd8, 0x7a1161e6, 0xfde36c59, 0xc008dc17, 0xd1b793cf,
+ 0xc0ef4379, 0xdf278a31, 0x24aeba67, 0x72880c39, 0x8693c509, 0xdeacbdd8,
+ 0xecc9b66b, 0xf197a43b, 0x4ee1718f, 0x382fcfd2, 0xfa455c0f, 0x7805306d,
+ 0x03ccaadd, 0x91b726cf, 0x7287fee5, 0x9ecbfcd9, 0xf4a9f441, 0xb6cdfd22,
+ 0x4a9db988, 0x1f9df87f, 0xae750bf6, 0x5b83c2a5, 0x9f916436, 0xbcf85ea1,
+ 0x5bae1251, 0x0ff7c138, 0x963efa2a, 0xfe10f4e2, 0xf73e6ed5, 0xfb4ddb0b,
+ 0xcf4947cd, 0x271666bd, 0x58fdf6cf, 0xf4f61b3e, 0x9f207932, 0x117f12d7,
+ 0xc91bde7c, 0xe1cf48e7, 0x9fe57287, 0x9d305fcf, 0xb8291dff, 0x190c9bed,
+ 0xfdd86fbf, 0xbbb211c6, 0xdf1e7506, 0x18339da5, 0x9aff6127, 0x1d1cd130,
+ 0x5d444fb3, 0x9fbf5466, 0x8f7ed3aa, 0xa9cd3905, 0xa9dfc9bb, 0xbff0717e,
+ 0xb8f9a98b, 0x846be94b, 0x1f2cebc0, 0x87f23e10, 0xe58782f5, 0xd18e7545,
+ 0x23de6026, 0x585abadd, 0x35ce909e, 0xbb9ec9db, 0xe4fd06d0, 0x34473a07,
+ 0xe98f5f9b, 0xb835bfa3, 0xd6fc9176, 0x4c9953bc, 0x9be7767d, 0x8d7e940b,
+ 0xc562a9e7, 0x3f098b2e, 0xc71b9fd1, 0xa148b5ec, 0xf584c4af, 0x7c852650,
+ 0x15e7c48f, 0xd363fcca, 0xef3e9aeb, 0x685932bf, 0x001e0053, 0x00000000
};
static const u32 usem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x33ab678a, 0x32ea7830,
- 0x31e9c830, 0x43d24c30, 0xb712d388, 0x9fa65173, 0x8181859d, 0x81b98813,
- 0x5f881798, 0xbc303231, 0xff5e2466, 0x3b046147, 0xe181804b, 0x0b6f9013,
- 0x32089fa4, 0xb2075c30, 0x0371033f, 0x88073f90, 0x35b10057, 0x480fbf90,
- 0xa3e204df, 0x1845fc40, 0x095ff9bf, 0x42156fc8, 0xe3443fe5, 0xafc4159f,
- 0xf980825f, 0xb1e40472, 0xe42269e1, 0x0a6dc7c7, 0xde040ef4, 0x67ca86a6,
- 0xe0606553, 0xaac58a07, 0x91dbf843, 0x6281f3e4, 0xf610aaec, 0x8606396b,
- 0x1db9405f, 0x7dcdd86a, 0x0dff9403, 0x9a86ab94, 0xf1b90003, 0x03685054,
- 0x00000368
+ 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x1915c58a, 0x19d44418,
+ 0x18344c18, 0x20685618, 0xb58969c4, 0x9fd329b8, 0x90c0c2c9, 0x40b9c40d,
+ 0x7cc40f9c, 0xfc0c0c4c, 0x17ebc44c, 0xf5b04514, 0x84181904, 0x026ffc80,
+ 0x85d70c0c, 0x8bbe1818, 0x03083030, 0xf1402ef9, 0x01ce2004, 0x58a06f62,
+ 0x045e900b, 0x2c40ddc4, 0x7cdf8a22, 0x6bf20251, 0x37f95185, 0x847bf8d1,
+ 0x1057ebf0, 0x47af2fc1, 0x161b1e40, 0x3e3f22d1, 0x3bd02922, 0x015f5810,
+ 0xc7265f95, 0x0f27d0c0, 0xb8a87f8c, 0x4bfc9201, 0x0e5cbb20, 0x6096f6c2,
+ 0xf2062860, 0x9bb0150d, 0x2f9403eb, 0x857dca01, 0xcc0003ca, 0x688cbacc,
+ 0x00688cba
};
static const u32 usem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7dedff00, 0x45547809, 0xbedd70b6, 0xe9d3bb7d,
- 0x84849d25, 0x1674b090, 0x26c43510, 0x630a0840, 0x944c2127, 0x615151a8,
- 0x8408ec44, 0xf9707d90, 0x37d7d470, 0xdf95012c, 0x3e30eb89, 0x0e0c1a74,
- 0x1036a0c3, 0xc6c06a30, 0x680e8300, 0x8cc08378, 0x364584cb, 0x5c710921,
- 0x7f9e6466, 0xbb75539d, 0x48e9bdef, 0x9bdffc74, 0x3f6fef37, 0x556ea2bf,
- 0x5b3aaa9d, 0xaa753a9d, 0x42049462, 0x1be426ae, 0x71f4d1f8, 0x10921091,
- 0x69f2bb4e, 0xb910963a, 0x96bfca27, 0xff6e0d56, 0x401904fa, 0x5be6b9c8,
- 0x4254e65c, 0xc1513d3c, 0x39f969ab, 0x4cdf9e7f, 0xbcb60bcb, 0x7cd230ef,
- 0x08d116f5, 0x16ed86e5, 0x4ab9df6c, 0xd6be43f0, 0x55d8fedc, 0x45bddf34,
- 0x68286b24, 0x2066ceb2, 0x889c8439, 0xb467ec22, 0x2122481b, 0xad961665,
- 0x1663bd5e, 0x62de57f4, 0xfeda1626, 0x81e8b344, 0x82b582fc, 0xaafed09f,
- 0x4a665b5f, 0xf9e6f0a6, 0x45c58085, 0x371f6bf3, 0x2c84ecb9, 0xa381feda,
- 0x19c846c3, 0x9971145f, 0x81e51e70, 0xfc2a424c, 0xd324a71b, 0x041b15f6,
- 0xafc281b7, 0x13be7558, 0x2cd157c6, 0xbc29170d, 0xe25675ca, 0xfefac91a,
- 0x6d7f4086, 0x2dbfb0c7, 0x57f40652, 0x136ee17e, 0x929e6111, 0xd355da07,
- 0x95bcc071, 0x1af8cf7e, 0x18446b89, 0xa1bfd59f, 0x357ad1fd, 0x986e0b2f,
- 0x78818d62, 0xaf9d1c61, 0x60bfa659, 0x9bd5f983, 0xf3d5d846, 0xf30add28,
- 0x36aff0a8, 0xf8c1b14d, 0x32ca9b56, 0xd72af0c3, 0x515c493d, 0x4cadf1aa,
- 0x9555e81f, 0x3e33d3eb, 0x054f19a2, 0x06c05925, 0x6e9bf678, 0x7efe151c,
- 0x7a458858, 0x3513ae57, 0xf1e529f0, 0xfd3efcbb, 0xbc83c527, 0x9b5feecd,
- 0x02dba61a, 0x2bb7fd27, 0xa71eb74c, 0x1ceec742, 0x7d257c35, 0xc741e80c,
- 0x6273e8d3, 0x092f84fa, 0x2e7ca7d3, 0xbe33d3a4, 0xf4ae9891, 0xb3fbf1b9,
- 0x574c5cbe, 0x3e983cf9, 0xd4c22bef, 0x7ac12bef, 0x31d37c6b, 0xf179f26d,
- 0x72be8bfb, 0xeaf9d74c, 0xdf7afbf0, 0xf8374c42, 0xb2fefc64, 0x01a6396f,
- 0xbe4da74e, 0xfb369895, 0xab6f58fc, 0x2da61d6f, 0x5f7e00be, 0x98e7f1c1,
- 0x748cf248, 0x710f0efe, 0xb8937252, 0x449e4f62, 0x2c2571f3, 0xce53389f,
- 0xa27cd133, 0x3e29e697, 0x7982ab92, 0xae4f9a66, 0x1f43e563, 0x3451f924,
- 0xe566543f, 0xf93c2b69, 0x6b4f9a16, 0x5623e564, 0x34d1f9c9, 0xcacfc23f,
- 0xcc10db2f, 0x65fcd2b7, 0xd59e5601, 0x346c0a4a, 0xf964159f, 0x029ebdec,
- 0xb767cd3b, 0x87ce7cb3, 0xe6838172, 0x7b583a73, 0x1203de3d, 0x6d284d99,
- 0x3c8b959e, 0x6f3441c6, 0x37137722, 0xa37c8bc5, 0xe28138c7, 0xf9617241,
- 0x5827f976, 0xc2e4c9be, 0x367976f2, 0x1e4b3796, 0x572a3f2c, 0xc9b37961,
- 0x917fe583, 0x56fcc5ef, 0xa6e58bc9, 0xfac37ffa, 0x2c5e4d5b, 0x865faa4f,
- 0xc64916f9, 0x1beacbf2, 0x498b7eb1, 0x9627f2c6, 0x9933d2fc, 0xef04fb96,
- 0x8b67c053, 0x49396f05, 0x2409fe07, 0x69fe5095, 0xe074c810, 0xc98107d7,
- 0x20fcd1c6, 0x605dca13, 0x200bce57, 0x001bf8af, 0x1f17b2f9, 0xcf384549,
- 0xc2891c21, 0xc70e2f11, 0x03573bbd, 0x5cbbbdc7, 0xd422f381, 0x1fe96c5b,
- 0x2beec09c, 0x5dd9e3b5, 0x0579c0a1, 0x37fbd8e1, 0x26eff72f, 0xbbf3c76a,
- 0x0b4e052a, 0xdfed89c2, 0xd3ed3678, 0xbed367e2, 0x20767e10, 0x37fa127e,
- 0xb577ec9e, 0x377ec9f8, 0x70779f84, 0x07fa833c, 0x5abbd367, 0x377a6cfc,
- 0xe03f9f84, 0x6ff48678, 0x69efd95e, 0x5efd93f1, 0x221f3f08, 0xc1fed49c,
- 0x8b5f7e69, 0x43f7e69f, 0xe104f9f8, 0xbcdfef0c, 0xe2d41ec6, 0x10c1ec67,
- 0x3f113a7e, 0x4e0ff697, 0x7e2d41f3, 0xf0860f9a, 0x678e25f3, 0x35e6ff54,
- 0x3f1690f6, 0xf0850f63, 0x33800443, 0xd9e37fba, 0x3f1691fa, 0xe10a3f5b,
- 0xc67082c7, 0x393c6ff5, 0x93f16b1f, 0x3f0871f3, 0x42670871, 0xfd6ce0ff,
- 0xad9f8b58, 0x93f0871f, 0xf5267082, 0x7f395e6f, 0xe727e2d6, 0x64fc21cf,
- 0x3e3c9c20, 0xd8e1421e, 0xf2d386fb, 0x2d3f1689, 0x33f0849f, 0xf214e10a,
- 0x4e045cf1, 0x7e2d09ee, 0xf0844f72, 0xae708393, 0x969c1fe9, 0xb4fc5a13,
- 0xe7e1089c, 0x5d73846a, 0x7b95e6ff, 0xdc9f8b52, 0xa33f0c93, 0xc1b496f7,
- 0x40d7437a, 0x4c9b48b7, 0x08f1ee38, 0x64e8beb4, 0x26e9d179, 0x8a888760,
- 0x3dda417d, 0xdb6fad22, 0x08fd9b10, 0xf919db51, 0xec78c037, 0xdb52fad4,
- 0xd1b93119, 0xd62bbb1a, 0xc7c9a713, 0xea6b2517, 0x69a49427, 0xbf4e07ca,
- 0xc83e534c, 0xa7c9ad9b, 0xa9a95f94, 0x5f2ea43f, 0xf0b61f93, 0x54fd4d5a,
- 0x3e4d26f9, 0x344ff97d, 0xde3787f5, 0x64bf29a5, 0xfca68565, 0x4d02ff52,
- 0x3f75f2fe, 0x151fd4d3, 0xbf29a458, 0x4d11e5a2, 0x13e0e8f9, 0x3d98fc9a,
- 0x8fea6acf, 0x29a35f6b, 0xbd787f1f, 0xc7427ca6, 0x529e4d26, 0x72e279c2,
- 0xcf81179e, 0x07ebb309, 0x0b9ed099, 0x37984dda, 0x4ed0db25, 0x5ccbda0f,
- 0x4d1d29c7, 0x006baf06, 0x8486814d, 0xc979dbae, 0x507497e5, 0xa577df3a,
- 0xfd2712f7, 0x7bc99f7e, 0xfd823385, 0x902fe949, 0x065d4824, 0xcbe5f548,
- 0xf97fc624, 0x1c461729, 0x0d6beda1, 0x696223dd, 0xf790cbbe, 0xf1f94094,
- 0x7c80c159, 0x3a922d19, 0x266d17a8, 0x4b2ff768, 0x564179cd, 0x21f2e7f1,
- 0x3084ee54, 0x3792e5dc, 0xe78aec09, 0xc193dfeb, 0x421868ce, 0xc84c95e7,
- 0x82f784af, 0x3f6d0672, 0x4bc92ca4, 0xd44d99e1, 0x6ff7570e, 0x6267fda2,
- 0xffd04dff, 0x37fa3efa, 0xfa6ae5a7, 0xae5a1a8f, 0x44ca3fe9, 0x3b5277fb,
- 0xef10feb3, 0x4ae9129f, 0x0e115e42, 0xa1e6ff61, 0x32ffd8e5, 0xa88fdd13,
- 0xf50e8ffb, 0xf1f20cdf, 0x109ff43a, 0x5769fe61, 0xb43fe76a, 0x137f3b42,
- 0xfaf6ff9b, 0xa3fef33f, 0x0a6ffe71, 0x1ff3667f, 0x6fe6c15a, 0xfd437066,
- 0xdff8423b, 0xa77ff309, 0x4fa7f9af, 0x587fced4, 0x66fe7695, 0xf5bbffd6,
- 0x36ff7927, 0xe13dffec, 0xb0ff9b24, 0x64dfec2a, 0x7f81baf6, 0x75d1294c,
- 0x193fda7e, 0x40d1154c, 0x0fda1760, 0x28e323a4, 0xb0f21313, 0xb8e38690,
- 0xdbf19a2f, 0xdf94d117, 0x88c8bf50, 0x9aa7e21f, 0x6a43ee8c, 0x6e542cb8,
- 0x1e8133c8, 0x1fba72c2, 0x3a87cb99, 0xfe4445a7, 0xfd994f26, 0x3b78e9c3,
- 0xf219445b, 0xe49a9e73, 0x6b577d07, 0x40967726, 0xc209233b, 0x1e9e4ff7,
- 0x2f3d46b5, 0x51b73a7d, 0x91a1d13a, 0x391e362f, 0xa3ac8c9f, 0x26042be3,
- 0x9fce1718, 0x421dfba0, 0xe94711f7, 0x93d2027e, 0x7e8fed12, 0x43f74e3f,
- 0x9b96a4c4, 0x64476c7a, 0x7419fbcf, 0xe512b7fc, 0xde79c1e7, 0xe1452281,
- 0x4ffe1919, 0xd0357dd0, 0x95a36e63, 0x1e3c3f22, 0x6f9c1f3a, 0x5fe0a977,
- 0xd2bc7023, 0xf6f1b7f6, 0xe147c604, 0x36b272cf, 0x0f72511f, 0xb79f28a2,
- 0x67035e32, 0x4d2ff106, 0x5f6feda2, 0xb42243b1, 0x74a141ce, 0x97e002c8,
- 0xc4122407, 0x0247647d, 0x40cce4c9, 0x0c9d7be1, 0xa5d36dfe, 0x382a1de3,
- 0x4f28a4b3, 0xaccf1d09, 0xef1c45fb, 0xbcb6af0c, 0x63d5bb63, 0xcae9a2c8,
- 0x494224cf, 0xb6b97b7e, 0x6d3a8efc, 0xda85cefe, 0x098f9d3c, 0x5952b5d6,
- 0x874e9dff, 0xd0aef3ce, 0x69c4e9bc, 0x9b2f367e, 0x35925cbd, 0x686d8474,
- 0x034f2f0e, 0x13c413b4, 0x5def4fb6, 0x2681f29f, 0x0ea56f3f, 0xff8be71e,
- 0xddffff4f, 0xc96daff4, 0x1aae3f8b, 0x9ae07557, 0x7aaae3f8, 0xd46eeb95,
- 0x67fbe7e4, 0x5bcfea68, 0x9f29aa59, 0x535f38db, 0x4ff97b3e, 0xf952f935,
- 0x3bfd4d7e, 0xca6bd617, 0x587ba8ef, 0xf97b7e53, 0x0cfc9ae3, 0xf5352fef,
- 0x5abe9b6f, 0x9f6c2e53, 0xd703ac3f, 0x41b0ef4d, 0xa3fc0fe0, 0x299f0099,
- 0xfbf0acfc, 0xa6125f29, 0x4c2e7c67, 0x530f41eb, 0x8d786efd, 0x4a6bb5a5,
- 0x573e8187, 0x54a4fff8, 0xa5f41437, 0xfaf59f9e, 0xf4a7cf57, 0xcec91297,
- 0x812ad250, 0xd63ac094, 0xe55eedc5, 0xcebe39fb, 0xd308b211, 0xcb93132a,
- 0xf2834daa, 0xc1f20389, 0xbeb67511, 0x808092e1, 0xcde020f3, 0xa5ba004c,
- 0x4d4bb5d0, 0x38cd74d7, 0xb110eecf, 0xc9901aff, 0x94dcb009, 0xff40326c,
- 0x37a1b6c1, 0x78f1828f, 0x25be6336, 0xb3aded01, 0xe3f8a2be, 0x095fc046,
- 0xd37ca7a6, 0xf3e13d31, 0x57dc7a62, 0x5f51e98e, 0xbe1da61d, 0xec7e9885,
- 0xd0fd3193, 0x3fd31cb7, 0x3d311af9, 0xe9895bec, 0xd31f9f41, 0x53079f4e,
- 0x55ff4f85, 0xf0ca3ae8, 0x73d74edf, 0x328eba6a, 0x3878d938, 0xf1851f5d,
- 0x939bb046, 0xa71918c1, 0x563c47b2, 0xe02eabf4, 0x896a70fe, 0xef2b3f31,
- 0xd705317b, 0x7f8b768e, 0x9ee1e824, 0x011b7f91, 0xc39ee47e, 0xed480174,
- 0xfa7a7e7b, 0xe20789f5, 0xccbdfb41, 0x3187174f, 0xd12dcbbd, 0x0316af0c,
- 0xd4d92229, 0xa2fe1b5e, 0xcc4caefb, 0xb41c491b, 0xb46fbbf7, 0x6d4b8047,
- 0xc5efc041, 0xfed8baf0, 0x3bc01645, 0x39d7ecf1, 0xa4328e90, 0x4db8bb31,
- 0x0494bb44, 0x7e03705f, 0xecd67a43, 0x6d3f024e, 0x139370f7, 0xb8a7bdd7,
- 0x9fc15a9f, 0xfe0af2cc, 0xafe10e1e, 0x97f10931, 0x14bfc5f1, 0x3ba788fe,
- 0x6151a6eb, 0xbe139dfc, 0x39ca7f1d, 0x1bbfbe89, 0xe277e344, 0x0544aecb,
- 0x0943edaf, 0xe02de7ed, 0xa7bf0a7f, 0xc01892f9, 0xd93ec873, 0x87f7f662,
- 0x4e80e74e, 0x6abc30b6, 0x3d9ebc1d, 0xeec0382f, 0x7064905f, 0x67808f1e,
- 0xa40ead25, 0x3b6a6d3a, 0xef9b45a9, 0x028a1469, 0x62b8cf68, 0xfd028da6,
- 0xcf1e74eb, 0x84993d00, 0x416702a9, 0x3c79c992, 0xe4c3e91e, 0xca2c437a,
- 0x145f19fd, 0xc7a1fbd6, 0xf09c17d1, 0x31c99a38, 0xf9501eda, 0xf5df7a4d,
- 0xe353e4fb, 0x37e04c5f, 0x17d2ad23, 0xd144bf60, 0x0381bfff, 0xbcc46232,
- 0x2036b702, 0xe02be6ca, 0x7f4d06fb, 0x394b9db4, 0xed26fbc3, 0x48c1e4db,
- 0x4afc284e, 0xf0468a97, 0xbe038d49, 0xf6b538b5, 0x5f26ac51, 0xa9c832db,
- 0x1fe097b1, 0x72928f54, 0x577c08c1, 0xcba6d9c5, 0xd02e5b68, 0x538255f1,
- 0x6055f80a, 0x3aa3aaf5, 0xf0175e4c, 0xaf5be2cb, 0x46cd4172, 0x7c7eaf9c,
- 0x1a377e94, 0xbf8f7d8d, 0xafb9ec52, 0x6c7c8224, 0xcabb7ae1, 0x240afcc0,
- 0xf9c0764a, 0x1d924917, 0x6871d937, 0xd07e10b6, 0x51fb470f, 0xf33815e5,
- 0xd6b752fd, 0xcf91957e, 0xbf981acf, 0x6eefdf40, 0xe2e137e8, 0xb0d9abf8,
- 0x5bcc0a7f, 0x969ac78f, 0xca2f26f3, 0x272ffd15, 0xbf05478c, 0x6ec96295,
- 0x58afc291, 0xd5f70477, 0xc47924a7, 0x17a2df03, 0x96df8f7b, 0x9aaac274,
- 0xa1da4cb7, 0x7972bb9f, 0xdb75c447, 0x9f5f5407, 0x1e44bdfe, 0xa05cba01,
- 0xa0e354b5, 0xe4310516, 0xbbf5ed84, 0x618b2b9a, 0xfb0d3efd, 0xe72faa15,
- 0x38071290, 0x6349cb1d, 0xe7e7d80e, 0xf008a188, 0x87fc8e74, 0x4e8a8c63,
- 0xe2134467, 0x47efda89, 0xf6a3e3d5, 0xed4f26bb, 0x8cbe4d77, 0xe70894dc,
- 0x494f65d9, 0xfce02fc4, 0x127fe534, 0x79f7489d, 0xec01aea4, 0x5b12c59d,
- 0x1272efd7, 0x5f1d0a63, 0xe5cfabf5, 0x79fcd294, 0xca23d991, 0x38fcec79,
- 0xc08afe36, 0x9687936a, 0x731e6b1f, 0xda0455eb, 0xfd601bfb, 0xee08b791,
- 0xf8deaeb5, 0xd7e3aefd, 0x87b1578f, 0xf30b9d7a, 0x13af5471, 0x7648fe3c,
- 0x8533e711, 0x4e8c631f, 0x45237f8d, 0x9744bf97, 0x7fcba31f, 0x401f796f,
- 0x295ef234, 0xe38c537a, 0xfec37c98, 0x2376304e, 0xf86f7f3f, 0x5fe0bd49,
- 0x1fc283f2, 0xd13393ac, 0x8507e63b, 0xfc6bd19f, 0x5f824757, 0x5b4beafd,
- 0x2a9faa65, 0x41da795e, 0x6d3a7ea8, 0x53744c6c, 0x5dad57fa, 0x383e00ea,
- 0xc01d9465, 0x62fda7cf, 0xbe823f91, 0xf0a8d7bb, 0x8026c783, 0x49fe0dff,
- 0xff599fe1, 0xaeb0f5e8, 0x7256b17f, 0x9d6d5fa2, 0xf2a66839, 0xbf3cd35a,
- 0xfe616498, 0x3b2fcb08, 0x45be422f, 0xbf159fcb, 0x85d13a7e, 0x314e52fa,
- 0x8838ffa0, 0xd34d7ff6, 0xdd605327, 0x28dd25af, 0xd076fa67, 0xb87157ff,
- 0x629a953e, 0x46e3977a, 0xb3da113e, 0xa3f36d5f, 0xfc0745e7, 0x06fd03ab,
- 0xdce5fafa, 0xda332f8e, 0x1afea007, 0xfe83c64f, 0xfc41f052, 0x5f178ecc,
- 0xfc0b2e7d, 0x7e9b67a7, 0x785410ef, 0x27ace452, 0xaf57fb30, 0x97d6fabb,
- 0xd50e549d, 0x4f62a3f6, 0xfef85ab8, 0x55a595a3, 0x1571d052, 0xab5593d5,
- 0x3f4cb725, 0xc2f4bd57, 0x3f82cf8b, 0xf7668ff3, 0xf2bf0a70, 0xaf075da5,
- 0x8dcaf9a4, 0x366280d2, 0x18909b0d, 0xfd2d4ba6, 0x9876617f, 0x779b150e,
- 0xd8a35c99, 0xc2e307f7, 0xb8dca8f4, 0xf54644c3, 0x604147c6, 0x16c3a987,
- 0x23812e81, 0x12fec053, 0x09bbfd5f, 0xbb7a7ee8, 0x46a60640, 0x5deae7c0,
- 0x9e019f68, 0x4e9c8e90, 0xeae9ba21, 0x80ba52d7, 0xa4e8573e, 0xfae22f2f,
- 0x32b9e004, 0x7e5f9f91, 0xfe84e21d, 0xfcc37664, 0xdbbe5fcb, 0x6938f301,
- 0xfd7c63ac, 0x0f44d2dc, 0x925cb7ed, 0xb2989d13, 0xdfcfe5ef, 0x6f36fc8b,
- 0xcc89bdff, 0x6419e58f, 0x1e49b5c0, 0xbb9bf304, 0x5f9c16ea, 0xdf22f119,
- 0x96273f95, 0xdcfc7e80, 0x46368a48, 0x8d4f8b90, 0xb9380ecc, 0x74b81a86,
- 0xb2e9277e, 0xff337183, 0x14fc6221, 0x3f453f21, 0x2e7cbdd9, 0xfcc382d4,
- 0x4e8c51e7, 0x5c0d196f, 0xaf15a8ae, 0x65a6d7e6, 0x339f40ed, 0xe1033c43,
- 0x1896a5bc, 0xe10f8e65, 0xdc570a1b, 0xd190385f, 0x398cb887, 0xc3b51dbc,
- 0xd43be00a, 0x963c976f, 0xf23b4d2c, 0xffb86a4d, 0x74ff787b, 0x3f60d1dc,
- 0xbc8c4c9d, 0x2928180f, 0x71d74f72, 0xe4a97f15, 0xd37bc99b, 0x15be4cc3,
- 0x58dff779, 0x397fe504, 0xda07e4c0, 0xc748fac1, 0xe5881c15, 0xa809a63b,
- 0x1824cc0f, 0x249bae49, 0x72dad72e, 0xb8e84f85, 0x8a8c428d, 0x1c7e005f,
- 0xa6ed1fe2, 0x3b68a7b2, 0x85acbe95, 0xe1bd1cfe, 0x8f3b7229, 0x9009ffcb,
- 0xf2c3cbff, 0xb931564f, 0x95bedbef, 0x92553f11, 0x4167c5ff, 0xca7ca95e,
- 0xa957902e, 0xe9fde604, 0x3f83b686, 0x69f272a1, 0xad539140, 0x69cbd4fe,
- 0x097ba6f9, 0x4e5ea7f0, 0x475c1d3f, 0xfd29ca22, 0x074e511e, 0xea97fc77,
- 0x0e7f054f, 0x153fab49, 0x1e17d87d, 0xb7f0faf5, 0x53e21746, 0xefe90faf,
- 0xcde9c900, 0x29df0a7f, 0xdbf156fc, 0x77a061ea, 0xf0a97c42, 0x152f885d,
- 0x57cfd3be, 0xf97d3f8b, 0xd199f061, 0xf6bc9571, 0x4a1494fe, 0xc156aacf,
- 0xbb61766d, 0x78a790dd, 0xbfb330f2, 0x00ca7771, 0xcbafde75, 0x3df57407,
- 0xae897cba, 0xaf9757be, 0xb3f7d5d3, 0x9b4b487d, 0x041f2089, 0x45a5f535,
- 0xfc738644, 0xee226dee, 0x98e8bbbb, 0xaefb681b, 0x997ea90d, 0x16a583ea,
- 0x4eefbfb6, 0xfe803530, 0x3b7672ea, 0x616f20e2, 0x92aeb5fe, 0xcaac476e,
- 0x2ad23c3e, 0xf0edfea2, 0xfb48a293, 0x22d16a13, 0x5f483a9e, 0xa3bcece5,
- 0x5d0db450, 0x46977e08, 0x81ae0dd1, 0x39b7f539, 0xaba1bce0, 0xe986fd35,
- 0xb7dcfbf4, 0xe85f0c45, 0xc164768a, 0x31ec88b8, 0x0bed520e, 0x99f9114e,
- 0xb33e7489, 0x60fed95b, 0x5d9d0ace, 0x5f205641, 0x31eed994, 0xf6a45e81,
- 0x9fad51fc, 0x0577f19e, 0x4abe5787, 0x57b4ae5b, 0x4d158df6, 0xdf2f72da,
- 0x5c495667, 0xa3268c5f, 0x308f3ed9, 0xafd7093f, 0x0de66285, 0xbbfe29d3,
- 0xf80488f6, 0x4455a7a5, 0x106cf7fc, 0x226fe0fc, 0x4dca0272, 0xbd46e90d,
- 0x2ce9e0a6, 0x6fa985c8, 0xcb7673bd, 0xd00f3947, 0x3f5b552a, 0x9a77fac8,
- 0xc7fadd9e, 0xfe406f11, 0x3f4343d5, 0x17ebbd20, 0x79e0b76c, 0x3b76d76e,
- 0x6d76afc6, 0x01f437db, 0x7666bfc8, 0xb6bb38c3, 0xfc05997f, 0x5cc8b5d3,
- 0x6bab7a0e, 0x2cd7db08, 0x5665f6de, 0x4b93ae07, 0x90bf6e90, 0xa7aabed8,
- 0x858febf5, 0x59d29001, 0xddbffac1, 0xda9dfe8a, 0xa7182dd7, 0xcbedb5db,
- 0x87edaf1c, 0x3f0d4f9b, 0x93b2efbf, 0x7c609be9, 0xba7cecb1, 0x2f098df6,
- 0xabfed3d4, 0x6698779b, 0x3782f2d3, 0xfa059eff, 0xb3136bb0, 0x8ea53a6b,
- 0x7a7ce1e7, 0x8bedd2cd, 0x4ee78a24, 0x42648a10, 0x4df0d47e, 0x09199cbe,
- 0x7f477f2f, 0xf1f17f53, 0x7c18ffda, 0x53ef1808, 0x47f76ad5, 0xbfef3009,
- 0xe801fc7e, 0xe466ed81, 0x9fbe654b, 0xeed1ea06, 0x0fbcd8b8, 0xfdc7bcc3,
- 0x085bcd2b, 0x5fde67f6, 0xfbd393fe, 0xe385c921, 0x6f41cbd3, 0x1f76df3e,
- 0xbbb25fe6, 0xe4fdbc71, 0x7fa681f7, 0xa26fba31, 0x7c5c7774, 0xe4ff39de,
- 0xee9beef3, 0x74e2cf6f, 0x8c7de277, 0xe38eff37, 0xee7aaefb, 0xf3a1ffd6,
- 0xb373ec57, 0x8f3da4a1, 0x693a6f8e, 0x316183b4, 0x2f67a123, 0x8799c484,
- 0x8c0065fc, 0x8ae7e257, 0x332df1fa, 0x048ffdb1, 0x5fb4c6e7, 0xf7c08b72,
- 0x743f6c75, 0xae1fb73d, 0xf6865c1f, 0x661ef5e8, 0x496313af, 0x8858de49,
- 0x46e39aff, 0x3ec9273f, 0x2dfc85ec, 0xbb5e7893, 0x20577c2f, 0xe3da811e,
- 0xda2d0fd7, 0x0de9f603, 0x33418d83, 0xfa408f4b, 0xcf7f83be, 0x665feed5,
- 0xdbf9b578, 0xb7f36ba6, 0x82b77870, 0xbffb4571, 0x83f044b5, 0xf21a535f,
- 0x39f80254, 0x1112b9a5, 0xa9138804, 0x84fb0a5b, 0xedb44a5b, 0x767ec367,
- 0xf38f185c, 0xe153bca3, 0xa46a21fc, 0x61b8f880, 0x24fa8885, 0xf840532a,
- 0xc612b925, 0x28627e13, 0x173c01c9, 0xf35f198f, 0x0dce0633, 0xf1cf9df3,
- 0xd0ea4655, 0xbe1721de, 0x0e6266f9, 0xda0973f8, 0x843df34b, 0xf5ed475c,
- 0x304289b2, 0x3ce5ca9a, 0xb2639123, 0x9029cfc1, 0xa73f1aa3, 0x1fbf0f36,
- 0x5ce18625, 0xfc5f7eac, 0x7fa743f8, 0x347ffca6, 0x90cdda83, 0xf33bb9e2,
- 0xaafb29d7, 0x1e195b3b, 0x7f04ab6b, 0x5055f21a, 0x7c539f52, 0x85fe626d,
- 0x06383f3f, 0xe7ef2ae5, 0x7ed862a3, 0xcced032f, 0xf6676e5a, 0xf018aec8,
- 0xa6b4f46f, 0x02b1f3f3, 0x3f023787, 0xadfbe7ef, 0x3ef9c03f, 0x0b26bb4d,
- 0xfdd8228d, 0x78fd1ba4, 0x590b64f2, 0xee0e211b, 0xa7e29303, 0x1ffdc3a8,
- 0xa01cc4fc, 0xa3cdfb23, 0x54e2634d, 0xdd715b74, 0x6f566369, 0xa8efc03a,
- 0x1fe83cea, 0xefec2fc5, 0x2dfbaf00, 0x224a531d, 0x971cf7cc, 0xfeb7e2df,
- 0x6eb5f78a, 0x00954d6a, 0x164d372f, 0x9fa6e735, 0x75bef898, 0xe303190c,
- 0x1aeb7e2a, 0xcba004c7, 0xf70dd11e, 0xcf5b6ab3, 0xce11bc9b, 0x04f8f48f,
- 0x97dfe8f8, 0xcf8065dc, 0x42c7ff63, 0x8fb59f60, 0x4264e79f, 0x6e2674bc,
- 0x4fe03de5, 0x75e382fa, 0x7489d9aa, 0x4f38b9be, 0x66fda04a, 0xc3473b36,
- 0xaf325691, 0xad16153f, 0xc11c1071, 0x92f529da, 0x23bd58ab, 0xa44d6726,
- 0x128a2ff9, 0xfb8579f8, 0x9fe15cbe, 0x3f796e8f, 0x61f307b7, 0xeecc993d,
- 0x6be6f5d5, 0x53d1f282, 0xdf41f824, 0xf309fec3, 0xe03eecc5, 0x972b033e,
- 0x597a626f, 0x9e3d7be1, 0xcf0ccdd3, 0x3c05ff4a, 0xf0ccd23f, 0xc159e0a3,
- 0x4abc7eaf, 0xaeafaa7d, 0x6e21fb56, 0x32fd1968, 0xad3587ac, 0x4140d382,
- 0x4c3b18d5, 0x2db58720, 0x67e04b8f, 0x7062e19f, 0xa5907ae9, 0x6a9dd73e,
- 0x6debe766, 0x02cd57d9, 0x056cf93e, 0x7b684bb5, 0x0ef39ccf, 0x19f77758,
- 0xbdc1efdc, 0x915df949, 0x7d16fdac, 0x79cf81f5, 0x1aa364ed, 0xf38e2a6e,
- 0x093caae6, 0x57b726dc, 0xaa0690ed, 0x39aa69f8, 0xef95cb0e, 0x6cae55c9,
- 0xc3fb4ef8, 0x998fc871, 0x6787c409, 0x3ef1da06, 0xb175edda, 0x03cb0f8c,
- 0x4f984c3b, 0x7f4afac5, 0x797a3f4a, 0x8dac569a, 0xd05d99fb, 0x52f01831,
- 0xe3de0e6c, 0x9da7c08e, 0xbbe40e9c, 0xca1e13ae, 0x8bff59b7, 0x947b89d6,
- 0x2a43a275, 0x6c89c551, 0xa73d3335, 0x4606275a, 0xd416275a, 0x1d0206bb,
- 0x1f4b6c16, 0xe0b24208, 0x48c4c2ed, 0x3efbc4eb, 0x88785e76, 0x9aecdfdf,
- 0x2b89d746, 0x34c4eb54, 0xbe89f20b, 0xc4acdf9d, 0x9d645d61, 0x5ff6e850,
- 0x87de6fac, 0x7c822275, 0xd76b366f, 0x4b5b5b89, 0x75b89d71, 0x57b9a89a,
- 0xb17cdeb1, 0x712f2275, 0xb725e606, 0xbcff0235, 0x43e1edcf, 0xfa0ebe3c,
- 0x34e2f581, 0xde84ffe8, 0x7a5f46eb, 0xeafeb1fd, 0x3c26fff5, 0xc17d7a2b,
- 0x781eec2d, 0xc8243e6f, 0x50660bcf, 0x3f002ebd, 0xe0bebd32, 0xd317ee0e,
- 0xd012d9e9, 0x7ad563b3, 0xf1afb596, 0xb6a175b2, 0x3317f525, 0x1a4ff969,
- 0xad147725, 0xdeb093ff, 0xddeb51cd, 0x1377a0d3, 0x72dde822, 0x6b3f77a6,
- 0x53f6831d, 0x88fbf35f, 0xcfaa5beb, 0xf811dc32, 0xab4cfa63, 0xb1ce9ee6,
- 0xdccbbfd1, 0x4fb2f20c, 0x4fbb73c4, 0x77b01db8, 0x82c6eff4, 0x144a7a9f,
- 0xa71c4f1b, 0x5c8fa767, 0x81ea993b, 0x9ecc3982, 0x2220deae, 0x999a6afe,
- 0x4464d7fc, 0x3f345dfb, 0x26affb25, 0x636e57c8, 0x06746fe7, 0xfa2a79c5,
- 0x68ebee57, 0xe5703f00, 0x0fcf016a, 0xf019ce21, 0xb3e38f39, 0xfb895dcc,
- 0x80fc7d15, 0xe6ad17e2, 0xaeb7e6f5, 0x3ea9ff46, 0xe33aa0ae, 0xafb0d3da,
- 0x3a333628, 0xfc166f14, 0x1ce153ab, 0xfdcf575b, 0x541b9e30, 0xc7dfb407,
- 0x15cef9f0, 0x619b9983, 0xe89ef55f, 0x8dceb48e, 0xfca5e3d1, 0x7ecbc41f,
- 0xffb1978a, 0x17d2f1ef, 0x8f7da81e, 0x3e3d64fe, 0xbd7145c6, 0x82c64d92,
- 0xf0627e1c, 0xdf915ea0, 0x642e3111, 0x35c3e3ce, 0xa20bfef7, 0x67dabe98,
- 0xdc4036f0, 0xe2c35cae, 0xdaade647, 0xe6912bb8, 0x68c80667, 0x5bcf4770,
- 0x43875da9, 0x0bb37eeb, 0x7599f5d7, 0x1388051b, 0xfdefcb9c, 0xc71ffb94,
- 0x58ee12f7, 0x5a79d748, 0xd9b6767f, 0xfb9fe70b, 0x37a8dd2d, 0x105dbe15,
- 0x3a97ecc5, 0xc9638e3e, 0x7d7193dd, 0x289c116a, 0x5b0b418f, 0xe09d28af,
- 0x09b6871d, 0x74e14e5f, 0x16887e61, 0x4a5ac746, 0x29e79037, 0x8ebf3cad,
- 0x2bb781d9, 0x77e080f9, 0x7757a009, 0x085dec48, 0x9c0bc481, 0x11f5aa08,
- 0x12f2d5ce, 0x76de7455, 0x5afff184, 0xfc1f8dc1, 0x43efbff4, 0x9ef93ee7,
- 0xe5fd31d9, 0x0b4f0577, 0x6fde7474, 0x831e2f69, 0x1b8233e7, 0x8d68c7df,
- 0xe38573c5, 0x079dec8d, 0xcbd3b799, 0x5c3bec05, 0x8dcabf2a, 0x1f887030,
- 0x9c60b22d, 0xc69bf61e, 0xbded32ec, 0xd7135940, 0x4ee35df3, 0xda3b496a,
- 0x3178e163, 0x802637ef, 0xb5182457, 0xc8dd5c71, 0xfc003fe7, 0x02dfcdd7,
- 0x3139249f, 0xa76ef46e, 0xeec9ddf2, 0xdb7cf06f, 0x33439c90, 0x5b3f7e29,
- 0xdd79e22e, 0xc1d7066d, 0x1e6fa089, 0xcbc80891, 0x0f257b67, 0xb8ac075b,
- 0x3bee94ee, 0x4a5ef786, 0x2911ec59, 0x2fad887d, 0xfe78f8c7, 0x0f6dd744,
- 0x604844f8, 0x4dfbc41c, 0x7428ef73, 0xec64df81, 0x2e70a5fe, 0xf3817376,
- 0xe7a041e0, 0x93bdecc3, 0x700bcba3, 0x4ff7769f, 0xc3b79405, 0xfed06e94,
- 0x07a96996, 0xef7ed20f, 0xe7809e58, 0x093d335c, 0xd7b9c2b7, 0xdba2bdcc,
- 0xbecdeb45, 0x73836ec1, 0x4523a9af, 0xe7e155e2, 0x7e8ed20e, 0x3f75999a,
- 0x5dc605bd, 0x3143d74e, 0x85fdd215, 0x4abf2103, 0xb2b5f6c0, 0xb29034d7,
- 0xf3cafb4e, 0xffb4b1a6, 0xd00f5a32, 0xd58abb5e, 0xdc126dab, 0xd65b7a10,
- 0xcbea38fa, 0x1f0126b2, 0xf6a76896, 0xeb83146f, 0xdb70a28f, 0x34f6d157,
- 0x03da0f3f, 0x5bd8a6dc, 0x96ab3ce1, 0xe7db138e, 0x6479e3d6, 0x8b476d19,
- 0x4fd37b49, 0x55fcde11, 0x447b8102, 0x8fa9b9e5, 0xbdbc02e5, 0x0fca1b92,
- 0xc625f8ed, 0xfda2cc8d, 0x67f0a20d, 0xe8851d8b, 0x70407b57, 0x83233be2,
- 0x5d7e9033, 0x70686130, 0x64fd0d3c, 0x42e9d718, 0x71d51834, 0x1616c908,
- 0xb0b65cdf, 0xd5e601be, 0x1aa42721, 0x9bceaf90, 0x4e3f1d60, 0xf6a5edf1,
- 0x8b1331eb, 0x8f93686f, 0x7a543a99, 0x1d25bc74, 0x969cd8f5, 0x9f2f3c3c,
- 0xbcf04a4b, 0xeccf5bdc, 0x2d4b2391, 0x30ec017e, 0xbe1439c9, 0xe3352db7,
- 0xd897cef7, 0xa439d3fa, 0x27a1fd03, 0xee044957, 0x955e2d39, 0xf1d00cfe,
- 0xf90906e4, 0x424e7c4d, 0x25ef363d, 0x5b6b27e6, 0xbc9ee0c5, 0xcfdec4c7,
- 0x9f9a7281, 0xff651bf7, 0x6563d5ab, 0x53d40aae, 0x2bd4bd7a, 0x7aa9efee,
- 0x2f6cb013, 0x14cf757d, 0x741557d4, 0xeb4601dd, 0x3706afa5, 0xaf52bfa0,
- 0x4d896aaf, 0x10d953d1, 0x3d5a5237, 0xe04ad664, 0xc0583be3, 0xb5f07b76,
- 0x75869fcf, 0xe04ecab7, 0xf9d18d4b, 0x82f8c08c, 0x6cccbc80, 0xc839f8dd,
- 0x0b4cf941, 0x0273bbbe, 0xb37200e8, 0x59c59e22, 0xdf114bf9, 0xbce51c4a,
- 0x573e5a95, 0x7867b5ce, 0xaf51e245, 0xe256e55f, 0xf43bd551, 0xda57e510,
- 0x822d9dcf, 0xfe4022df, 0xc77beec8, 0xe389de62, 0x83edc85a, 0xe7e47615,
- 0x5f9ff743, 0xeb3afc0a, 0xbd808141, 0x036f644e, 0x2b3587ac, 0x65f81705,
- 0xdac83de7, 0x61eda3cf, 0xc97e87dc, 0xb7f28af8, 0x66bff80b, 0xb1bbe3d5,
- 0x02e0937e, 0x975687f8, 0x2e513da2, 0x9bcb048b, 0x81fee08e, 0x5f1853ae,
- 0x898b26d4, 0x4b35ffc0, 0x95304ecc, 0xf8523e14, 0x17bf08f2, 0x59dca24d,
- 0x9f76d337, 0xde849000, 0x174e28fc, 0xf029eb42, 0xf8ccad49, 0x924bc8ec,
- 0xe2e6d81b, 0xc3eec97c, 0xabebe49e, 0x532ddcf8, 0xd73cc106, 0xb68638b2,
- 0xb0260555, 0x05fa4e23, 0xcdef8f3c, 0xb6a6c497, 0x7cbe14a3, 0xfafa604e,
- 0xbda87162, 0xa5f38ef8, 0xa9947fc2, 0xb5595f71, 0x0f702257, 0x5e8fcf57,
- 0xc42b7029, 0x4cbe940b, 0x5bc743e7, 0xda3f70d0, 0x691e0aeb, 0x65f2113e,
- 0xa1ef1646, 0x91b543c8, 0xe77d05c5, 0x37fae9f1, 0x7961ec5b, 0x4adc5910,
- 0xbbfbf690, 0x9c602f0d, 0x47f5b9dc, 0xe6fb47ae, 0x8007ca0d, 0x12760dff,
- 0x1f87fdc4, 0xb34550f5, 0x4238c1e8, 0x66e73063, 0x895dbed5, 0xc57ca897,
- 0xd8aef88e, 0xd317f664, 0x8f5b15f6, 0xf5f9e165, 0xe78c6ea2, 0x680bd790,
- 0x23b9131f, 0x546fee0b, 0x86dc5918, 0x64582ede, 0xb3aa7e61, 0x83a759af,
- 0x63ac26dd, 0x045569ef, 0x2acc936e, 0x16fdeebf, 0xe787a949, 0x33a53229,
- 0xf18693dc, 0x5271dfa9, 0xfece35e2, 0x455ff186, 0x5cf6848b, 0x9d8dbac5,
- 0x71577f10, 0xdcfb8cd8, 0x31e775da, 0x95e0b89e, 0xae1df097, 0x135116da,
- 0xee2bd57f, 0xe7889d69, 0xd5cd351b, 0xf341bf18, 0x1351ce78, 0x77ff1c88,
- 0xca9cf8b1, 0x956db657, 0x372b0a29, 0xef81daff, 0x75afb572, 0x7593bde0,
- 0xd8771edf, 0xf029ce2b, 0x39c6b7f0, 0x507f819d, 0x45adfac6, 0xd644e71b,
- 0xc746bd31, 0x9ee91397, 0x7adec841, 0x21e7f3e9, 0xa6ecf70e, 0xf1879f4f,
- 0x67e7fd56, 0x061c43cf, 0x82716ed9, 0xfebb523d, 0x54638c7d, 0x30b2edda,
- 0x37f3affb, 0xcff8c6bf, 0xdd9a3fce, 0xdb73ad00, 0x6f60a1c9, 0x6bfc6e74,
- 0xde75c422, 0xfd10adb3, 0x296cf739, 0xf8224818, 0xf814940b, 0xf88fdfd6,
- 0xdabd3d53, 0x5e30db9a, 0x37a51ce4, 0xdc5087e8, 0xc59aa05a, 0xbc78ba01,
- 0x71c886da, 0xd3e2bdbe, 0x61be6f9a, 0x66c5e812, 0x345c1766, 0xa500ed4e,
- 0xa0fd15e3, 0xb98786df, 0xbf4c893e, 0x4a0ff073, 0xfa3a63a7, 0xf73cde7d,
- 0x5942cf57, 0x719f7c73, 0xe07ec16a, 0x0e23894d, 0x169d3c58, 0xbf4d9b90,
- 0xa040b8c5, 0xf40bb15b, 0xc143e7f3, 0xea4a7c2f, 0xf743ff46, 0x5bde3336,
- 0x0876d8ab, 0xcb73a7e5, 0x25d38c7e, 0x93b79e3c, 0xfe2c7e84, 0x6a7afb92,
- 0xbe2cec9b, 0xe21fe38d, 0xfc0e5cdf, 0x18dce3ce, 0x6ff12b1f, 0x0dbdc57d,
- 0xefe34e8f, 0xbcf8b02a, 0x780fa6ea, 0x5e98591c, 0xe9d02e42, 0x13c6b7c8,
- 0x0270782a, 0xe3abc61e, 0x17c72338, 0x397de286, 0xa07e80bd, 0x9a7143a7,
- 0xe2183f34, 0x21c2fcf6, 0x741f4112, 0x9ff166ae, 0x1ef6929d, 0x2c3e9868,
- 0xad15d3ae, 0xff7f5393, 0x362f39e2, 0x9f8aeffe, 0x269768d8, 0xd3c151ae,
- 0xf5910bd9, 0xf0b44178, 0x9a93dd8f, 0x05efe823, 0xc02747e4, 0x1311f979,
- 0x7c5e7bc1, 0x37dca4ff, 0xb3b4fee2, 0x0b8c45eb, 0xa1b4086c, 0x8bebd71e,
- 0xa24e7e1a, 0xd12def1f, 0xb4d54f4c, 0xece275b0, 0x46dfbb26, 0xeb7d9ce1,
- 0x9ae7e435, 0x324c470d, 0xdd7bb785, 0x2b8b1366, 0xeb03f260, 0xfe355f84,
- 0xc8ef2fb3, 0xdfcdbd42, 0x33f7d215, 0xdb53f79b, 0xda9fb91a, 0xfd35e70d,
- 0x9301ca54, 0xfef176d3, 0xb73d18ce, 0xed33bc01, 0x133a5ecc, 0xdd228b10,
- 0x2d12998b, 0x2373fdf1, 0xf5d373f3, 0xb257df12, 0x4494f7b3, 0x5fda3447,
- 0x0f73d8f7, 0xd4800cc7, 0x8b127184, 0xc55c79eb, 0xa024ee43, 0xb5fb62f7,
- 0x14bbc604, 0xc7daabf0, 0x012f4e4b, 0x2a4a4dbb, 0x673eab19, 0x1a6fc651,
- 0x157e2060, 0x17b1effd, 0x27fd840d, 0x6183ca31, 0x7da7d71c, 0xaff58469,
- 0xf7fcc7dd, 0x0cb1c2e4, 0x746edef8, 0x70a78aee, 0x6e0b27db, 0xe6f6bd70,
- 0xe43f067b, 0xdf68f04f, 0x7a588485, 0xdb8f5f98, 0xdda0f680, 0x2ad27410,
- 0x4f696ec4, 0x8bac0dc2, 0x18898cb8, 0xe8718f02, 0xa6a2f88f, 0x073abdc1,
- 0xd429e6a1, 0xef351b73, 0x1ae4c424, 0x9026ef75, 0xbd741903, 0x557e71b1,
- 0xf67672fc, 0x03b70a6f, 0xcd8863df, 0xbec0f524, 0xb45eec2b, 0xefe49e1b,
- 0x48dfd058, 0x23886788, 0x3bf56ed1, 0xcd5fb42e, 0x5fb410fb, 0xa3d63e4d,
- 0x1917c7cd, 0x5f5a478f, 0xa638f9e2, 0x43c43688, 0xd941a16c, 0x4f0f15af,
- 0x363b8f0c, 0x5083b881, 0xe30d9d7e, 0xc978a9c0, 0x6cd879ea, 0xf1d371da,
- 0x4c44f469, 0x606c8766, 0x777cd4e3, 0xf3809712, 0xd3bf68f7, 0xdbf26af1,
- 0xaa3c79a3, 0xdf411891, 0x09daa2d9, 0x068f7fc7, 0x7b8c4bdf, 0x7d022487,
- 0xcb57df08, 0xc411ee04, 0xfed079f0, 0xe09df535, 0x6bfd601d, 0x4ec190e1,
- 0x2bbf7df5, 0xccb7faf8, 0xe81ef25a, 0x75619c9b, 0x313bc818, 0xbde26489,
- 0xa801d6d5, 0xe616d29f, 0x2f346393, 0xcabe3234, 0x6e504158, 0x9c59ba32,
- 0x8d12590a, 0x8a39a8f6, 0xb86c96c8, 0x296444c7, 0xf3f17a1b, 0x22d725f3,
- 0x5c650503, 0xb68d794e, 0x37ceed6b, 0x0844a5cc, 0xbf851140, 0x31f3da37,
- 0xa370dff4, 0x1a30c937, 0x74b7de3e, 0xda9460e7, 0x6823c14b, 0xb5ddee10,
- 0xe90b0867, 0x089af781, 0xf01777b9, 0x4f286378, 0xbacf7082, 0xf7943a31,
- 0xdf7d5144, 0x67f2c698, 0xba5defa3, 0x3fbbc29c, 0x346ce4a6, 0x79ca278c,
- 0x05779e19, 0x17fe70e3, 0x71945f5b, 0x98ea6c8e, 0xf9963d12, 0xcf1de14d,
- 0x3dd0f6e1, 0xd7875c6a, 0x107c94da, 0xcd2511f7, 0x55af51fb, 0xb963f607,
- 0x1d34f201, 0x2531df16, 0xeb109625, 0x930b4ba3, 0xfd78852e, 0x9d0324d2,
- 0x974780e7, 0x60fb82ee, 0xa23c3c61, 0xb0d183c1, 0x499ed77c, 0xdf2c3c6a,
- 0x7f487605, 0xbac030f1, 0x89f2e97c, 0xe5379ffd, 0xc42b788b, 0xf019e43b,
- 0x87f1a5dd, 0xa15fe86d, 0x47ae0b3f, 0x3eeace1c, 0xfb2abfee, 0xc5270a11,
- 0x5fcc2e3a, 0xaf853b4a, 0x749be2fa, 0xbd8cbce2, 0x9fe5a7af, 0x0327ab62,
- 0x7ab70de0, 0xe1c6d9f6, 0xf63ef1fc, 0x3dd7af54, 0xaf984c79, 0x063bcd89,
- 0xb32ef7ee, 0xaaca35de, 0xcd4ecbf2, 0xd1a6205b, 0x2c8166f1, 0x93e78424,
- 0x8cb650b0, 0xf04cf3a0, 0x7ace3018, 0x063bd599, 0xef4c71fa, 0x8495d20e,
- 0x31de009a, 0x0b961882, 0x6d86bfa5, 0x50debf6c, 0x622ff06a, 0xc002bde7,
- 0x8747f30b, 0x19ba3f8e, 0x411cb47f, 0x3d69a8fe, 0xa5a3f8c2, 0x0bf81f3e,
- 0x9f60cdce, 0x47ba48df, 0x79afdd03, 0x48d0a9b4, 0xb5987ff9, 0xf28521bb,
- 0x14d64485, 0x788a5f16, 0xaf8c31fd, 0xf8f87d17, 0x45f57994, 0x693dc6df,
- 0x7ec2668f, 0xcf01af72, 0x85bc14bb, 0x8b2b07ec, 0xf7641c23, 0x6a7e834e,
- 0xc3763b73, 0xf9ed37f4, 0x70db8c0f, 0x0769bdec, 0xa34c77b4, 0xfb857214,
- 0x08bbdc6d, 0xa46dcbdf, 0x319000f3, 0x75865ba4, 0x307c6fbd, 0x03e109f9,
- 0xc04c9eec, 0x979411c7, 0x109efcf5, 0xffbc3b95, 0xdecacc3a, 0x65679865,
- 0xac07e7fb, 0x1d994f22, 0xc7b7b096, 0xdaadfb04, 0x9fac0625, 0x7aa66900,
- 0xdeb04bfe, 0x26a35603, 0xa7a14e5e, 0x93544fc2, 0x877de15a, 0x3def588c,
- 0xb389fe5a, 0x29e0a9a6, 0x11f31eed, 0x4a0c9cf7, 0xdd779d87, 0xe52aeb0d,
- 0xed351b9f, 0xc0164946, 0xf81f529b, 0x687d1233, 0xae8c45bb, 0x17b05671,
- 0x205cee36, 0x7f42f9c2, 0xef039ae9, 0x39fad1c7, 0x89b75256, 0xa189cfb6,
- 0x79e3e429, 0xa7cf207e, 0x43fd34b0, 0xdfa041b7, 0xebbf7357, 0x171e56b3,
- 0x065e7460, 0xcb3c53ef, 0x29313af1, 0x4505d71a, 0x8066c16e, 0x3f236b73,
- 0x4eeb4ebf, 0x14dd0033, 0x1b763639, 0x68ba7682, 0x065d19a5, 0xc7786388,
- 0xec6de747, 0x7b5cef5b, 0xa7bfbb29, 0xa732feff, 0xafb6f7f3, 0xaf75eabf,
- 0x4ba065f7, 0x63c75475, 0xcd7cd137, 0xf9e19fa5, 0xcd6b22e0, 0x3b73ea55,
- 0xff1faa7d, 0x3a4e173b, 0xfcec3ec0, 0xc9145cca, 0x32b0eece, 0x6f8f77fb,
- 0xec53b63a, 0xe815242e, 0x413df564, 0x5768a633, 0x1e5508fd, 0xc63651d0,
- 0x656afac1, 0x75aba4fe, 0x147f03f7, 0x42bd7e64, 0xf41238d2, 0x5fd58e64,
- 0xe5c38b8c, 0x481718e9, 0x51f662be, 0xce0ffd14, 0x79f90a97, 0x73b0e798,
- 0x397f2c27, 0xe3938d31, 0x2a4c7ea0, 0xda23cfc2, 0xe272b9f7, 0x5de82365,
- 0xf08a9e92, 0xe574a20a, 0xd1da0903, 0x30cb92e4, 0xa890ab9e, 0xbe3a31ec,
- 0x6fc6749c, 0xba964753, 0x9feff327, 0x6cfaf301, 0xd61319c4, 0x66b8d7f3,
- 0xec6b27b8, 0xe8374694, 0x5dffdfed, 0x3c5233bc, 0xe31b78c5, 0x12be3dc7,
- 0xeb339c37, 0x12ef9af1, 0xbd5dd896, 0x9fc7abf1, 0x3e0adf1e, 0xfbcb78f5,
- 0xce393dd0, 0x7a3f1bd5, 0x5074287c, 0xc7c7acf0, 0x8a6ff03b, 0xcd3277af,
- 0x3bdacef8, 0x77df8646, 0xdec8b9a8, 0xfda0f46d, 0x43c7c85a, 0x4fb457ed,
- 0x6eec120b, 0xe29e1ec6, 0x78f0c4c2, 0xe3d578f5, 0xe3bf8731, 0x7c446242,
- 0xe0377447, 0x0161f28b, 0x7ed04c1c, 0x7099b60b, 0x578248ff, 0x06fc7513,
- 0x47be061d, 0x17973577, 0xd6392f05, 0x00b19dba, 0xe78a9ccf, 0xa57f57d7,
- 0x5b0b67b5, 0x7f069ca7, 0x778c4e40, 0x8941f809, 0x5f384a98, 0x15f2d51d,
- 0xd535971f, 0xa8eaf9cf, 0x9198af8e, 0x0bcacf13, 0x74f2ba9d, 0x85507e82,
- 0x56f3f4ef, 0xf815ebf8, 0x9e37a130, 0xb2cafe14, 0x993bfb71, 0x387b060c,
- 0x31b1b5eb, 0x6b499fa0, 0xc3bf445c, 0x2125c3f8, 0x914f9c38, 0x0de2050f,
- 0xffa6777d, 0x9daa7a03, 0x3f2a82ae, 0x5bd10cc0, 0xa7a08b60, 0xc4993e14,
- 0xc88935e9, 0x347fc03b, 0x12ff1889, 0x5553f7b2, 0x99e657f3, 0x9e605242,
- 0x4c5d58af, 0x8679f3bf, 0x47cd4de6, 0xde44fba0, 0x1b28c4ff, 0xdd20b7de,
- 0xfc21b3c6, 0x32bbe1a7, 0x3c2e29b2, 0x27d7890e, 0xb308eb43, 0x7be266d7,
- 0xe42f14b6, 0x1c786b1b, 0xc4609b5e, 0x38f85677, 0x928badce, 0x79ed4e21,
- 0xec073bd1, 0xdec2b3b8, 0x319f9c2c, 0x37d60238, 0x2d67f97d, 0x9ca06b3b,
- 0x7ac32bd6, 0x2295fc7c, 0x6f742ff3, 0xa4d7fb33, 0x52876df6, 0x4075c671,
- 0x70899f91, 0x900af15f, 0x8c0a60b7, 0xca586afb, 0x7cfdba68, 0xf2fbee39,
- 0xd08db25a, 0x299eaecf, 0x4f9f9718, 0x5fb0463c, 0xe7af7cf5, 0xeb3f3d6f,
- 0x8fec37f9, 0xfb0a1ee8, 0x2fcaef90, 0xe2169d8a, 0x6f94c39b, 0xc29beb54,
- 0x1e7f942f, 0x8d75bc05, 0x3019e4fd, 0xfd8df7ab, 0x37d6112c, 0xdb0f0ec5,
- 0xa0c79e1b, 0xb8f65f5e, 0xbbff8762, 0xf034fbcd, 0xcf7491a3, 0x2369f682,
- 0xefb8065d, 0xf3cdb6fe, 0xec577c0c, 0x2bed8b93, 0xe1ba4ec8, 0x8b337ca5,
- 0x206021d3, 0xbcabdef8, 0x753d4040, 0xa096e907, 0x24ea3bbf, 0x9675fecd,
- 0x07e3fba5, 0xfeb03ce0, 0xf2078c12, 0x889a9442, 0x715c59ed, 0x31efbf03,
- 0xe0047bb2, 0xda85cef5, 0x64d8f8f6, 0xcd5df84e, 0xafb6058f, 0x48e9659f,
- 0xa5b47b80, 0xbebeb6b2, 0x7a1e657f, 0xb576fab8, 0x78219dfc, 0xb2add8b7,
- 0x31b55e0b, 0xde34263b, 0x03bbf877, 0xf006df14, 0xea5eb4d7, 0xff02247f,
- 0x2a37a92a, 0xaf18d32e, 0x99b62fb2, 0xff7a47a7, 0xc147e943, 0xaed24cf7,
- 0x916ff3e0, 0xe89a2fde, 0xc37dfb65, 0x79cd4153, 0x746692bb, 0x2ebb464f,
- 0x1da02023, 0x33c8155d, 0xf3d8d6cc, 0xcbdbbf6c, 0x2977879e, 0x0ef37ea0,
- 0xea07cf66, 0xd5505f71, 0xab37f6cc, 0x99398ce1, 0xed13240f, 0x15bed0fc,
- 0xe1aaa0e2, 0x1e563f9d, 0xe9e6ab84, 0xd7feac8d, 0x87a685b6, 0xe9df6033,
- 0x34dc924d, 0x86a1e2bf, 0x6a3fba28, 0x42162548, 0x5d7f47f7, 0x1594d0f1,
- 0xe2ca54b9, 0xc589023c, 0x426d837c, 0x5fc9f7ff, 0x01b078af, 0x7f74c9f6,
- 0xed5363d5, 0x8f92fb5b, 0xe21736e3, 0xeafdafb1, 0x5f2531fd, 0x077e54db,
- 0xa27bfd3d, 0x7fc0315c, 0xf47df30f, 0xc2ef0bb5, 0x92e581fd, 0xde21430b,
- 0xbba7226b, 0xa9fdced9, 0x3acf7656, 0xed9af45f, 0x5d6fdf20, 0xe27e0118,
- 0xc31e4677, 0x7f2b597d, 0xafaf716f, 0x8523ed1c, 0x6676718e, 0x697b5fd7,
- 0x15f6039b, 0x03fb8dd7, 0x673f0fde, 0x9d99ef64, 0xec6935cd, 0x856c87d8,
- 0x495f0071, 0xd044da29, 0xeec713cb, 0x7ceb0c3c, 0x5843eb5f, 0xd0047bff,
- 0xfec2e4ff, 0x69df3c44, 0xbf00e5de, 0xdf7e59cd, 0x5b735cfc, 0xad345de2,
- 0x0707f8de, 0xf9d2a7ec, 0xdb19cefc, 0xaa9b7df1, 0xcbbe222d, 0xbc4dfb40,
- 0xcdc7fc1d, 0x611e73b3, 0xd7a944dd, 0xd5dfc23f, 0x49bfec50, 0xaf9fb251,
- 0x12df8a87, 0xbab8e1df, 0x1c58f459, 0x73c0edbd, 0x2c9ed27b, 0xc9107a06,
- 0x1a3e1c3d, 0x0bb44ec9, 0xfd0df9f9, 0x7ef784ed, 0x9bccf3b7, 0x7cdd9fcd,
- 0x73913215, 0xd802e5c9, 0xcc01de47, 0xb0f4c739, 0xfd5dbf62, 0xa93fd695,
- 0x5bf31fb7, 0x21492f47, 0xdef60f88, 0x1fc9b77b, 0xec2ecec9, 0x9ed1129e,
- 0xc471e424, 0xf496f657, 0x4cfef0a9, 0x2706dbf6, 0xcec83bf4, 0xf9b6b1f8,
- 0xa51f7c33, 0x856f0486, 0xd1669af2, 0xa6df2419, 0x1efc979f, 0x57545efe,
- 0xbe02e4ab, 0x15dd6aed, 0x16f90595, 0xb55dfd11, 0x0e5e26fb, 0x2ad9d67c,
- 0xb5213be1, 0x80713edb, 0xf7d6501e, 0x7ef656ce, 0x31eb5748, 0xedc0aefc,
- 0x1cbf896c, 0x068d9dd6, 0xb9dcbfb6, 0xd0566ffb, 0xe85e6f0b, 0xad7dc789,
- 0xb6f73eb2, 0x052f117f, 0xbfe43176, 0x44bfdb55, 0xe200789c, 0x24630a9f,
- 0x3b610a22, 0xfcfad7b5, 0x27625921, 0x7ce9d7bd, 0x08c5f758, 0x37c735eb,
- 0xfc08cfed, 0xefbf5fae, 0x6a7b73b5, 0xf786c908, 0xc42e5af5, 0xcdbde257,
- 0x1173ab56, 0x5d985ffa, 0xccf3b5d2, 0xfbe15313, 0xdbdd915e, 0xdf2220bf,
- 0x72bdb5bf, 0x8d4d8758, 0xd7a406f7, 0x77ce8317, 0x7feb41be, 0xf99a2bb1,
- 0xcbee8da3, 0xc206f7d5, 0x5f1cfdf5, 0xae7664c1, 0xbbc32725, 0xeedbdf38,
- 0x2ef5eeec, 0xb47613d5, 0x80a7bb3b, 0xeab11dfa, 0xc5f40988, 0x53c97b20,
- 0xac040f4c, 0xe4991780, 0x6fda10a7, 0x07c93479, 0x27aeeafe, 0xdba3884e,
- 0x0060c7b2, 0x9b5d8cba, 0xeb2ef18a, 0xfcdfb9f9, 0x5529a340, 0xf3e65fa5,
- 0x9253a373, 0xf54e343c, 0xf4c1d93d, 0x155da9c0, 0xf93d42bf, 0x1e193347,
- 0x1bfc5d61, 0x4d9b67d7, 0x500dd4f2, 0xf701a8ef, 0xbf773b1b, 0x69de1bbe,
- 0x35d87f9b, 0x0399d61a, 0x5eb40f20, 0x0df5decb, 0xf2db2f10, 0x6aef4121,
- 0x68a9534e, 0x41befda0, 0x760fcc5c, 0xe0fb80c0, 0x7890ff90, 0xfb9e61e2,
- 0xf9bf6ced, 0xe6831ec6, 0xfe0de99c, 0x765be83e, 0x33b7c189, 0x3da6d43f,
- 0xb7a0f1f9, 0x6fbdd907, 0x8f6b1e00, 0x5c383477, 0x6299bf61, 0xb0384d27,
- 0xfa28ea69, 0x0d6709cf, 0xebb7204e, 0xe6111ac0, 0x48453aeb, 0xd97a40ac,
- 0x2ede144d, 0xce37bc35, 0x1c747832, 0x2a9c816f, 0xef2ba7f8, 0xff3499a3,
- 0x0e31bb46, 0xfc14a4e2, 0xfa50f32b, 0x67880577, 0xc9450db5, 0xfc5be9b3,
- 0xe69c4ab7, 0xde512718, 0x9cbe4727, 0xcfbcf76a, 0x3b4641f8, 0x68aed4f6,
- 0xf33647b4, 0x95248c75, 0x29fc030e, 0xa782fa74, 0xeafa78ca, 0x075f3cff,
- 0xf2bbf494, 0x25c97af5, 0x77f0df23, 0x30725cfa, 0xb1e21d2a, 0xeff1d25a,
- 0x55e2a8a1, 0xa93e03cf, 0x87f8d602, 0x060c3a5a, 0xb3554fb8, 0x67c5884d,
- 0xd769fa42, 0x18ccf886, 0x396bfe40, 0x2b8e504c, 0xf994fdd6, 0xe1bea8ef,
- 0x79e157ef, 0x3f0fc834, 0xd0241e97, 0xeaeb4274, 0xdf8829c5, 0x2ae403a0,
- 0x372a278c, 0x9a35d690, 0xdfe75f80, 0xfc79d2c3, 0x4afe777c, 0xd967ca2f,
- 0x67a7162a, 0x38e2a475, 0x257e71ce, 0x8864e886, 0x1bb068e3, 0x4fc9f134,
- 0xdd3dbe70, 0xf41b64fc, 0xd62bf94b, 0x6cafcb41, 0x1819fc79, 0xa7afc2ae,
- 0x5384249b, 0xff3dad1e, 0x7830744e, 0x7e300e5b, 0xe524d09f, 0x1349fbc3,
- 0x7f04e264, 0x6b4d1bf0, 0x6fdfd045, 0x32a73f00, 0xfd758739, 0xac47aed4,
- 0xeef5833f, 0xdf808188, 0x9489b379, 0xc5c9546f, 0x6aafd5ce, 0x5d62b7e4,
- 0x6ff454fd, 0xa009c477, 0x55b915e7, 0xe4d9bef0, 0xffe506be, 0x4ffc9d7a,
- 0x418bed66, 0x27bd6858, 0x593ffcb9, 0x7e9fe544, 0x158a6d8a, 0x5366ce00,
- 0x26b4f7e4, 0xff1fbe39, 0xf1eaf485, 0x92757a5e, 0x1de7ed83, 0x9affb4e9,
- 0x3f707aeb, 0xe71f1a1f, 0x2b27279b, 0x002a937c, 0x05291bfe, 0x145f0033,
- 0x68cfc0af, 0xcdbe82b7, 0x8277c34b, 0x22e3f37a, 0x234ddce5, 0xa6bd61b7,
- 0x06f7afc8, 0xe4ce4f18, 0x5f60c5ba, 0xc8cb17c7, 0xef05a7a7, 0xaeba38b0,
- 0x8e79069d, 0x394617a0, 0x42f91e98, 0x11de6af2, 0x920e3def, 0x4e5d7c0c,
- 0x2f306a77, 0x02704ab2, 0xd772947d, 0xe09fbe2a, 0x4aef94f0, 0xfde37bfe,
- 0xbdfcbd2f, 0xb8718e55, 0x6420999e, 0xad9f8473, 0x47c84467, 0x6b8620b9,
- 0xe6de4193, 0x27ec75d3, 0xb4ec75aa, 0xaafc88d4, 0xce3ee1e0, 0xb2c45fef,
- 0xfce70f79, 0x3f6c0d31, 0x173f37c4, 0x81468c13, 0x3028b5c9, 0xfe011779,
- 0x5e575de9, 0x5d7f7c83, 0xdcafbe64, 0x33f91ab0, 0xf789c8b6, 0xba349e41,
- 0x9199b12d, 0xd31fb1f4, 0x817f6b9d, 0x63e02bfb, 0xe4befb90, 0x80e41ca0,
- 0x3f7fe044, 0xfd157fe5, 0x7ca03e14, 0xa54384f1, 0xa17cf427, 0x7829df9c,
- 0xff3bacd9, 0xf5c1c8fb, 0x7d5d4f3c, 0xf328a1c4, 0x3e74def9, 0xbfce8bdb,
- 0xcb0e7461, 0xd15bd017, 0x9c818f13, 0xce5beb8d, 0xac4e316c, 0x6cd1f0d7,
- 0xe468fb8c, 0xde0140e7, 0xe7dd685f, 0x39d7d9fc, 0xf7ab32ce, 0xe0fe3575,
- 0x1995d1bc, 0x6e428fe6, 0x6b582ed7, 0x8df473c6, 0xbcb3c984, 0xbeafda33,
- 0x5234e9a7, 0xfaa29403, 0x09e7d01d, 0x21070ab8, 0x22685aef, 0xf83f7419,
- 0x4ee96a45, 0x71f9a788, 0x8a3c5cbb, 0x49a363ce, 0xee1d769e, 0x00d7dc0b,
- 0x0d8a6bfc, 0x88af884e, 0xf00538f5, 0x004ba043, 0xeb2f70e4, 0xfbba4c67,
- 0xbaafdc72, 0x1f4063dc, 0x52f4e01c, 0xa1e0abe8, 0x2faef5af, 0x9862daba,
- 0x72f0245c, 0x99791ebd, 0x4f034dcb, 0x6447ae2f, 0x41c9e411, 0x18448bbc,
- 0x07a644ff, 0x22647a43, 0xcfbe73c1, 0xf3e47a75, 0x7c8f5e1f, 0xb923d1ae,
- 0x08f5111d, 0xff9445fd, 0x68b9a684, 0x91c392cf, 0x862959ed, 0xb009c7ad,
- 0x097ad28e, 0xa1fbfb32, 0x52df3807, 0xc438c48e, 0xc63326c6, 0xc87a2b5d,
- 0xc3e48d31, 0xc0753bdf, 0xa6b50bba, 0x824f0f79, 0x9324d7f3, 0x4f83ce0b,
- 0xf748dd4b, 0xdcc374d3, 0x2251fc88, 0xe823bd00, 0x0b7e0223, 0x99834ff9,
- 0x456c5ddf, 0x48505939, 0xb9dd1d70, 0x55f23c76, 0x009a7179, 0x2eb15b7c,
- 0xb8f28056, 0xe8034ec9, 0xe31e652b, 0xc6481a17, 0x94839418, 0x8c1c9518,
- 0xc044eb97, 0x6f78b0d7, 0xc84b1492, 0xff4f3165, 0xb9b7ed58, 0x7ed5e684,
- 0xf65f9a1b, 0x9736fc5d, 0x65c9fcfd, 0x73c9b7e0, 0x8cc64678, 0x65cdff43,
- 0xac0ce690, 0x6f4a8913, 0xfb8ecc5d, 0xcb52fcbe, 0x40e443fd, 0xacec7f2f,
- 0xc7f42e75, 0xd47c024e, 0x06789f24, 0x153be1c0, 0x366eed11, 0x2f5c018e,
- 0xd2090f90, 0x9d494063, 0x4512fe08, 0x87035cef, 0x1ed428ae, 0x1433ce01,
- 0x85bd0379, 0xce3c6ee7, 0x7655fc01, 0x91fbd7f4, 0x931f208f, 0x2b47d61d,
- 0xdf110d8a, 0xc633be11, 0x67ea83f6, 0xd6f5fad2, 0xf8f0e59f, 0xe9e5115f,
- 0x3d9518ce, 0xd1f164f4, 0xc10e7644, 0x9bbbe5de, 0x45abf1f7, 0x192ef7ee,
- 0x615f7e10, 0x4324d9b4, 0x10f1293c, 0x4f155397, 0x410ab42c, 0xfea7c43b,
- 0x746e760d, 0x0337fdbf, 0xb7fabfa6, 0xb054a292, 0x6e0c5be7, 0x7c41196a,
- 0x7b83ca05, 0x267bc118, 0x616efe01, 0x23cd9b5e, 0x8843bf81, 0x3da0f7e2,
- 0xdc8df3da, 0x681ba1ee, 0x3356e2f9, 0xaebdcdfe, 0x1eefe53c, 0xb21ef1b8,
- 0x7dacdf82, 0xb8c48e4f, 0x1ba3634d, 0x858d6ce4, 0x51635fc1, 0x6062bbea,
- 0x1cebeebd, 0x64c2e27d, 0xfe29f7f4, 0x41dd89c5, 0xd692f011, 0xe0b032ed,
- 0xb18fd635, 0x957ce09b, 0xc700f5f3, 0x9b3de6fb, 0x73c75844, 0x862e3726,
- 0x764bcefd, 0xf3c00aef, 0x76b51395, 0x0ea158de, 0xb9246eff, 0x493ee086,
- 0x0ef88f91, 0x9a4c03b2, 0x1e1dc3d8, 0x9e573d50, 0xfd80ecf2, 0x11094c64,
- 0xae2a9e00, 0x5f2017e7, 0xb8478064, 0xbdfc006e, 0x08b7fe4e, 0x7bcd9c39,
- 0xf79005f2, 0x0593ed01, 0xfe6f6657, 0xeefb095e, 0x04fe2cb1, 0x07ecaae8,
- 0xb2f6fd87, 0x534fe0c9, 0x618d6fea, 0xaf2afc7a, 0xc45c00b7, 0x422f3e74,
- 0xfba613bf, 0xa929e0db, 0x9b72e5f1, 0xcf9aa5c9, 0x52f0827c, 0xc79c643a,
- 0x3cdec3a0, 0x62d9f748, 0x4f2bdfb1, 0x656e3105, 0x70c11d60, 0x07ed219e,
- 0x521a7ed0, 0x1d002ed7, 0x0b79ef37, 0x7db83bc7, 0x5cb94b27, 0x80f6e26d,
- 0x367dae32, 0xe3ee5eb6, 0xe70dd1e7, 0x7af97ad8, 0x92e3178c, 0xe4347994,
- 0x28ea9379, 0x6f1095fc, 0x78efb633, 0x4263b79b, 0x016f36f1, 0x77a76abd,
- 0xd3de06ec, 0xf7120dfb, 0x247a451e, 0xf1db642e, 0x08177b95, 0xce5627a0,
- 0x5037ec8c, 0xee4ac5f4, 0xb5c55577, 0x5aa317bc, 0xc696a72f, 0xfa54d359,
- 0x4cf76948, 0x3365ae38, 0x53796b8f, 0x52d46ed3, 0x0cd3f00b, 0x8c10e79b,
- 0x3f7bf95b, 0xd1dff9eb, 0x0ab1f651, 0x0c9d52be, 0xdcc7af5f, 0x8dce0fb8,
- 0xca4e4f00, 0x912debc7, 0x9c13c3e3, 0x306f6e06, 0x8ced217e, 0x6a1e605f,
- 0xb702ebbb, 0x78f2ae3b, 0x4f8c8c0b, 0xc93e453e, 0xdf01b7f5, 0xdb922f8e,
- 0x1087ff80, 0x8c4527ce, 0x1efcf44f, 0x7ce38ced, 0xef004dd2, 0xb1bde163,
- 0x3ff1fa08, 0x067cd863, 0xff23e7b4, 0x0af87950, 0x3a949bd7, 0x4923c251,
- 0xc38c54e7, 0x7e995584, 0x69eb931f, 0x7a737e03, 0xd39e504a, 0x07664ead,
- 0xa0fe32a5, 0x426705ed, 0x2ffe9e58, 0x4f842ce7, 0x00008000, 0x00088b1f,
- 0x00000000, 0x7dedff00, 0xd554780b, 0xb3dae8b9, 0x64932667, 0x6f264c92,
- 0x80849af2, 0x3c870108, 0x4e3d2878, 0x0f78601e, 0x02483508, 0x48042bc3,
- 0xd2d04132, 0x20196f1e, 0x83548086, 0xa96a1ea5, 0x5af11e0e, 0xd528368a,
- 0xf09d8360, 0x41d0582a, 0x396b42d1, 0x0a8a2341, 0xf41ea009, 0xfffde3d0,
- 0xcccdad7f, 0x228899de, 0xb9eefbf6, 0x62ecfd37, 0xdaf6bded, 0x8fdffaff,
- 0xfb0cd7b5, 0x33d6c60f, 0x2a1d76c6, 0x8cb96c96, 0x794bfbc5, 0xc5a398cb,
- 0x8cf3d8cc, 0xff40b595, 0x9dbbfc2b, 0x7463cfb1, 0x1630258c, 0x2b18916b,
- 0xa46fac64, 0x598dfa85, 0x187ae4ae, 0x15d236bf, 0x79c0496d, 0x26090e74,
- 0xecc27e19, 0xf8743065, 0x99997af2, 0xc4bf5e71, 0xd5acc664, 0xbc232296,
- 0x2ec6b537, 0x7efe60b9, 0x0b78ce91, 0x0b1703cd, 0x79d22da0, 0x2d73c0d7,
- 0x66a38ed1, 0x6792cf78, 0x269d2dc2, 0xc15f7f46, 0xb12db57f, 0x35bbbeaa,
- 0x2039d2c5, 0xff825fd0, 0x0eff8148, 0xc61b1331, 0xc5bf0d58, 0x2caec896,
- 0x6b57cc0b, 0x0e6878ea, 0xf37eebf4, 0x92c191b9, 0x805eb86c, 0x7943f9e3,
- 0x81cd7391, 0xd62adef5, 0x55c39b79, 0xcff187a2, 0xc66eb946, 0xf08e47e7,
- 0xa1e193ee, 0x7d9e65e1, 0xa40b687a, 0xb0517dfa, 0xd996365e, 0xae3f41b7,
- 0x4347b583, 0x8744f637, 0x47fa1a23, 0xa784b1cd, 0xb4743f5b, 0x62fac2e7,
- 0xe7c24c9c, 0x38f95f01, 0xe5778b1f, 0xde23073b, 0xe00ccb96, 0x61e90178,
- 0x8e3d36be, 0xdf04759a, 0x53873351, 0x4884c3a1, 0x5d0b28c7, 0x4f5ef467,
- 0xd7801b31, 0x95d04c37, 0x579e8379, 0x4cc5a75a, 0xcf1baee3, 0x307d309f,
- 0x7fdb599e, 0xe813f8bd, 0x32dff1bb, 0xf029dde1, 0xd617dd1e, 0xef09f3fd,
- 0x95e0ba26, 0x61f7533a, 0xdb51f009, 0x5864db26, 0x9664a0c2, 0xd8c719db,
- 0x0eadfb9a, 0x5a2783e4, 0x8c187b24, 0xb3660e67, 0x25643224, 0xdff9d622,
- 0xb7610cc7, 0xac170b40, 0x6293ce30, 0xde436ef4, 0x43337fd9, 0x02b1dc38,
- 0xc3e8068e, 0x05165d73, 0x0df50730, 0x459feaec, 0xf861f182, 0x6a4b982f,
- 0x80976f69, 0x30466b70, 0xdee00197, 0x3f1326d7, 0xe118d13e, 0x7ff9830d,
- 0xe1e2e3bb, 0xb9cfd099, 0x82cb875f, 0x339609bf, 0x43a8f891, 0x395a0afa,
- 0x0f4034da, 0x8472edf7, 0x2df1865d, 0x5843d111, 0xfb45630c, 0x9ad9f988,
- 0xbc0f307e, 0x047b4d67, 0x3f4d6fad, 0xe22c8f90, 0xff917b83, 0x591947f7,
- 0x04bf5c0a, 0x86e38372, 0x46378eb3, 0x74e80565, 0x59d3f5a9, 0xeefd617b,
- 0xd76f3e48, 0x91fd2bde, 0xe3fb957f, 0x97b5cc56, 0x2c5633e6, 0xf38a7ebb,
- 0x1d5fd729, 0xe2345ef0, 0x8234b19b, 0x0727e897, 0x378abbe0, 0x1cafc70b,
- 0x7475a7a5, 0xae3b08b1, 0x60e8c5bb, 0x29cf2748, 0x5e0adfce, 0x746f04eb,
- 0x709e15b5, 0x389efac1, 0xe7c76691, 0x852f5abb, 0xb37de0eb, 0x230f5c63,
- 0xeef4e5dd, 0xe22e6768, 0x1dcdd2f3, 0xe75eb8b9, 0xd2ef8446, 0xaeacf791,
- 0xdf5aebdc, 0x7d64df63, 0x49b9bd6e, 0x3fc9e98a, 0xda903e5a, 0x8690bfda,
- 0xd4309c90, 0xe60c9e5b, 0x6eeb035d, 0x49b43c1c, 0x634f4246, 0xc64f9436,
- 0x06672c2a, 0x313de805, 0x12ddb9c6, 0x188e5f24, 0x2f5c0ee7, 0x8f3527be,
- 0xde1cf9d6, 0x5e74721f, 0x5d7741be, 0xf4297ceb, 0xaf447d3a, 0x5a9eb15a,
- 0x0327d993, 0xe1976cfc, 0x3e450e93, 0x0bc27bb3, 0xf08bd8f4, 0x27ed8a79,
- 0xbfcf485c, 0x106bed9a, 0xc5bf7a1f, 0xeff04519, 0x11b1f7c7, 0xbd719273,
- 0xff1d236b, 0xf6fe8665, 0x83f38c55, 0x127f6114, 0xbf73b716, 0xe4f50235,
- 0x9fd718c4, 0xba81be71, 0xd09cb38b, 0x753bf02f, 0x781db973, 0x92fbac4d,
- 0x97a8e09e, 0x58ebfe71, 0xaf425fff, 0xfe1d07bf, 0x05074c16, 0x7d04a33f,
- 0x507e2147, 0x3feb7721, 0xf00530e9, 0x4f528123, 0x8f9cf6b5, 0x840c8eb1,
- 0x07f77db7, 0xbe603bfd, 0x983e57ba, 0xf75bf285, 0xb7111872, 0x639be5f4,
- 0x17cf8f90, 0x7316f2b1, 0xc9fa7d4f, 0x3ebb7aca, 0x4b4eb187, 0x1ad5e936,
- 0xbeb237e6, 0xda974fa8, 0x14fa41f5, 0x47fba620, 0x3809fe0c, 0x994291ff,
- 0xbbbe02ad, 0xc49e1f64, 0xa569e842, 0xb3256d7d, 0x7fd807cf, 0xf00e7a8e,
- 0x4177643f, 0xcda5e10c, 0x3b58fa4a, 0x6acac8fe, 0xef4e697b, 0x1a191df3,
- 0xbb45ee5e, 0xb0673121, 0xe588497d, 0xb4572576, 0x081d28a0, 0xa317b9e7,
- 0x74b81ebc, 0x68adef2e, 0xb73a7806, 0x0f7ccdeb, 0xe639cbf0, 0x9407f65f,
- 0x6ccd4f9f, 0xa1c76a1b, 0x8aafe56f, 0x0fdbc80a, 0xffb5f046, 0xd1a3a5e0,
- 0x613f1836, 0x4f78bee7, 0xc07efe10, 0xe55e9ff4, 0x2f7c2cdf, 0x7d30fc23,
- 0x07a47f47, 0x44d9c3fb, 0x7613b41b, 0x7ce7881f, 0x3a43a890, 0xeb7a172f,
- 0x64697877, 0x2b09be60, 0x948f88ea, 0x1365ed7e, 0xf505c6f3, 0x9a237ef5,
- 0x66cbdabe, 0x5f7185e6, 0x49e2a258, 0x7d61f47f, 0x537c7f50, 0x2baf69bc,
- 0xf4323b78, 0xefda066c, 0xf9a1e1f3, 0x77188464, 0x09323ec9, 0x4609a3fd,
- 0xc4258e5f, 0x34bcc638, 0x57aebb4e, 0xa5ecba57, 0x1be1defa, 0x96ae646f,
- 0xf4347c10, 0x99c37bea, 0xd97ae407, 0xa1d90356, 0x32fe57a3, 0xf7e81f2d,
- 0x658316c1, 0xfab3e035, 0x7ed2fbd7, 0x87abf70e, 0xe8245986, 0xe5f3607f,
- 0xfc2f1f20, 0x75c4ecb5, 0x5965b07f, 0x3f683ce2, 0x01ac7e06, 0x356e1638,
- 0xadeaf5d0, 0xb3f5d2f7, 0xfe174f82, 0xea10613a, 0xd7fba3f9, 0xab3ae227,
- 0x87f6b1ff, 0x1a762fa8, 0x4286832d, 0xb243b35b, 0xc5c90697, 0x55c2a7e2,
- 0x563a9dfd, 0xd650eb8d, 0xd5d724cd, 0xa78036fb, 0xddf7562a, 0x6afd97fc,
- 0x95fc05ff, 0xf204d8aa, 0x09dd2657, 0xbc2baeeb, 0xbee27e44, 0xc7641183,
- 0xc99668ff, 0xfd0df01f, 0x02df3fcf, 0xe87f92fd, 0x0843e4ed, 0xf42d1f3e,
- 0xa4c96332, 0xbc4caa87, 0x4f5bb25f, 0x944944fe, 0xf186f84c, 0xff70d1e6,
- 0x1f78c45f, 0x37e40de8, 0x34da8f26, 0x8e8dc612, 0x13f43031, 0x78b7c5ff,
- 0x7efd0302, 0xbbfd65fb, 0x29eb411d, 0xd003cd66, 0x06622911, 0x1e8775cd,
- 0xd49897af, 0x8ce747d7, 0x6e768b3b, 0x5d7d45b4, 0x58869b91, 0x0141ffe0,
- 0xf077dffe, 0xc3c647a3, 0xc88eaafa, 0x86bb0fdc, 0xe10d797e, 0x5f9d23d7,
- 0xcf01d8ad, 0x3958151d, 0x8683e57a, 0x11abe414, 0xfd0d5b12, 0x9584ae0f,
- 0x0b879285, 0xbca36fe8, 0x80efa033, 0xda277d00, 0xa3ed5d17, 0xb11e4c38,
- 0xe11f6af4, 0xee7ae6ff, 0x11d1e5eb, 0x6bf7a46b, 0x6e56a0f5, 0x383d2fbe,
- 0x0c81e861, 0x4fb5144f, 0x4ec9fb63, 0x7ab45fae, 0x14f7ab51, 0xd6f0b4b8,
- 0xf4a9d65e, 0x1b58d0dd, 0x3de80b8d, 0x1bbde923, 0x8d1d5f18, 0x815f110d,
- 0x797c265d, 0xae29e986, 0x0de1bf03, 0xb66b971c, 0x480115c5, 0x48ec960d,
- 0xcc33e7d4, 0xee50b7ae, 0xb03b7f32, 0x1ebd8194, 0x8759a3b4, 0xe24ba37a,
- 0x106edaf4, 0x0373f62d, 0x623bcff1, 0xbcb1edfd, 0xc50ff10f, 0x8a2bd98d,
- 0xfeb07bd9, 0x84f31330, 0xf7bd91e7, 0xf302f218, 0xa2e31cbf, 0x8c458d71,
- 0xdcb19dc7, 0x601ecbef, 0x7e6059d3, 0x87592036, 0x70265af4, 0x25a576b1,
- 0x7bf813b7, 0x6a64cadd, 0xe7c45fd1, 0x68237b3c, 0xce4bef5d, 0x6b772821,
- 0x7a5a7c05, 0xfe155b64, 0xf60ff676, 0x87141687, 0x56d1d3d6, 0xe8a7ad3d,
- 0xe81919d1, 0x7edfbc6f, 0xcfea0677, 0x3f5e01f7, 0x3dbd3fda, 0x84fcebe6,
- 0x3e3c8587, 0x8c44ec28, 0x267f2388, 0xc7d804e4, 0xb5fd13b1, 0xbfba4e95,
- 0xb539656e, 0xa0ae571b, 0x59b1ddfb, 0x91e8fef4, 0x81b3fbcf, 0x641b9d7e,
- 0x8c0b03b2, 0xf0b1fece, 0x8e934ede, 0xeaf7d1e2, 0xccbb65cd, 0x5c519d78,
- 0xf1d1e0b3, 0x142e50db, 0xf563ba38, 0xd6deeeb4, 0x3ebd6d99, 0x3acb5dfd,
- 0x5d1ed1a2, 0x0077c7e5, 0x7e01893b, 0x32bb219c, 0xc71809ad, 0x38e22474,
- 0xbfefe4b7, 0xee808283, 0x956ff40c, 0xeccafff7, 0x6216b6c8, 0xa106c39c,
- 0x7044b45c, 0x7385a37b, 0xd9f395a0, 0xc13695da, 0xfda80307, 0xef61f858,
- 0xa10a9da3, 0xcf116e57, 0x6e3b361d, 0x6630f7c1, 0xd6937f26, 0xda3bfa81,
- 0x42708791, 0xf78050bc, 0xcbd52587, 0xdbf90906, 0xf80df5c2, 0x771fdca5,
- 0x2c71c48e, 0x044d21de, 0xf9130c7a, 0x05f2de9b, 0xb4de385a, 0xe6d0f972,
- 0xc9569411, 0xf95a9423, 0x6b16fe7a, 0x6c77e551, 0x2a11cc2d, 0xcad5b07f,
- 0xc3b266f5, 0x7ada4721, 0xd702bb97, 0xf3191ebb, 0xdecce524, 0x51a49a0f,
- 0x3f98ed2d, 0xaef52949, 0x634afcc2, 0x3d0e56ac, 0xc95798e1, 0x3d12e976,
- 0xefd12e30, 0x1c02322a, 0xe912625b, 0x7eac497d, 0xc0abd215, 0x1745a3a5,
- 0x4af08fec, 0x4307904a, 0x047e85f2, 0x79470d09, 0x9ae51f1b, 0x5f9df843,
- 0xc368c6bf, 0x464793fc, 0x025672fd, 0x38fe013e, 0xa422207b, 0x228f773f,
- 0x1f7152b7, 0x4f05e934, 0x050f0819, 0x1662fd4f, 0xd4f05bc2, 0x28297a1d,
- 0x6ac87f4e, 0x3d9dfc20, 0xe29338b0, 0xac6193e6, 0x79cf565f, 0x545f051b,
- 0x60bf7c09, 0xab77cd0c, 0x5baffbc5, 0x7f82774f, 0xd3d2a893, 0x8109adab,
- 0xed5d4c7c, 0xb3d3d245, 0xfc3edcac, 0xb072df4a, 0x57f3e00f, 0xf11d99f3,
- 0xad99f8be, 0xc17ba794, 0x077632d8, 0xc74ea7ae, 0xffb00f30, 0xfb07cbe0,
- 0xdf387fa0, 0x83fd1436, 0xd91fcfab, 0x7fd788de, 0x2286cd55, 0x1bbc53fe,
- 0x7c07cc25, 0xf84cde1e, 0x185b7cfa, 0x5a4b055b, 0xec65ac74, 0xb9bfa04f,
- 0xaf50c746, 0x6f0dd768, 0xb192e832, 0x237419f5, 0xff51fd38, 0xc6077429,
- 0x143d2232, 0x50fe21ba, 0xf6dfed9f, 0xc0afc112, 0x46c625b5, 0xccfc5bf8,
- 0x27c8b1ce, 0x12ac6a7d, 0xb81467e6, 0xb89dabbe, 0xf7f3f681, 0x3f666fd6,
- 0x69fa465f, 0x6ed6a7ed, 0xf63b30ce, 0x86bbfe90, 0xf8231cfd, 0x0f4237f0,
- 0x41ed98db, 0x23b253cc, 0x68f7ca3a, 0xf82a52e9, 0x7a2f2831, 0x791d7ac4,
- 0x2b5661d1, 0x179b57bd, 0x7ae46edd, 0x66cad9b4, 0x87e5094f, 0x9b757809,
- 0x17688dba, 0x90a4dbe3, 0x99a8e97a, 0x9bd025eb, 0x9f7241ff, 0x86af5a1a,
- 0xc419efc0, 0x7c3bcddb, 0x5e54717b, 0xba244e6c, 0x0fcf805d, 0x7814f854,
- 0xe0aaf054, 0x88a631b3, 0xf0bb65f8, 0x70c4b733, 0x9970297c, 0x8e7194e3,
- 0x7a5f380b, 0x0bfafa2f, 0xff806781, 0xbf1fc232, 0xeaf2a99c, 0xbe3d3e4a,
- 0x0b1923de, 0xca302cd0, 0xb9c665bf, 0x5c601956, 0x7f6648f7, 0x1531fa12,
- 0x77d42296, 0x3b7b6ad6, 0xcf1bdde6, 0xe366bcf1, 0x4d5de652, 0x7ffe30f3,
- 0xa3ca6cae, 0xe69dde22, 0x5941769e, 0x532bd81f, 0x15c1215c, 0xf635f711,
- 0x45ca06ea, 0x9337dc72, 0x10b8f48b, 0x731b7b74, 0xc7210980, 0x4379c5f7,
- 0xaf0739d0, 0xb7ce8b5f, 0xe5e57889, 0xcd472998, 0x0cb56fc2, 0x4b5dd009,
- 0xdf91becf, 0xc4f78f51, 0x09716dcb, 0x61b2f13d, 0x1e806e82, 0xec22c9d7,
- 0xa4ceeca1, 0xdf3defb8, 0x442e293f, 0x54fe1fbe, 0xab13f4fe, 0x84dfafed,
- 0x5326be70, 0x4fc4f49c, 0x27988c3b, 0x0ad2f256, 0x812feebc, 0x773f40a3,
- 0x56a3a97d, 0x26d75eb9, 0x55dc63e5, 0xf90aefb4, 0x5fed5dc7, 0xa5dc7f92,
- 0xf7958ff1, 0x89ec03de, 0x365a31f2, 0xdc5fff13, 0x9978e3c2, 0x146dfed9,
- 0x643ee1c0, 0xf11b5e60, 0xb40ff92f, 0xc45fe85e, 0x633fc716, 0xe16f78a4,
- 0xf98617e1, 0x08cc52e0, 0xe105b31d, 0xc111d62b, 0x8af8416c, 0xfaaab32b,
- 0xaa3ece09, 0xd9e549f1, 0xae29fbaa, 0xa9fbaa81, 0x7eaa79d5, 0xaaadfd7a,
- 0xb76099f1, 0x9e59fb82, 0x7df1aa71, 0xfaaaa69b, 0x56ef9afd, 0x871e678d,
- 0x39d6073f, 0xa6f3ac5f, 0xe35573cd, 0x61f24f99, 0x2081647d, 0xc7dbc7f3,
- 0xc8fac21c, 0xb88f917c, 0x3558bbd9, 0x756682df, 0x08f0815e, 0x956aab78,
- 0xb78863d8, 0xd5fbeacd, 0x531b1b6d, 0x55e45da1, 0x758c5f5f, 0x53f9090f,
- 0x3af7fd7d, 0xe3f432e7, 0xcea7197f, 0xbe935dd3, 0x45ae9b9e, 0xc70fbb5f,
- 0x7f2288ef, 0x79e1e167, 0xc9614724, 0xdb86fa6a, 0x7f16be22, 0x9aac0391,
- 0xafbff0fb, 0x5d945fc1, 0xfc5a0fcd, 0xc1f759e9, 0xceab8054, 0xac7dd92b,
- 0xb516fe27, 0xb538256e, 0xede2d3f8, 0xbcea718f, 0xd748dace, 0x971bd45e,
- 0x0ccb975a, 0xbc65f3f3, 0xf5a978fe, 0x6c4721d3, 0x7ef97941, 0x5fe5e6bd,
- 0x97910b8d, 0xcb7ac2ef, 0xd41bec2d, 0x817df65b, 0x8b030878, 0xb27a0063,
- 0xd5d37611, 0x20784afa, 0x5bd5af0f, 0xfb7a0b4a, 0xcfa4716f, 0x35a97503,
- 0x98b0f4f0, 0xaf089db7, 0xef18b752, 0xb7bc1172, 0xe1232020, 0xa75f333f,
- 0xe1e00f32, 0x7c679c3d, 0xe3123591, 0xeffb9da7, 0xb58078a1, 0x073d73c5,
- 0x1f1e0f24, 0xfe9297e4, 0xa67fc16c, 0x48fc3d90, 0x704fc3d8, 0x321ec53e,
- 0x57bf959f, 0xe6dec3d8, 0xbd16ea51, 0x995ed2b5, 0x58dd2fea, 0xcfa1097f,
- 0xd1dff18d, 0x23d27cae, 0x0f8c69ff, 0xbdee0f8e, 0x3af51074, 0x1e3c3de0,
- 0x051519d6, 0xd80a52f6, 0x8c8b7fcb, 0x3eeb7926, 0x826f7b2c, 0xb64d170b,
- 0xa06e6b18, 0x7785a2be, 0xab9ac994, 0x6de3d20f, 0x365eda92, 0x23ff71e6,
- 0x1dfb9e31, 0x2fdccc93, 0xe9d62c1d, 0xeeebf8d6, 0x82971e26, 0x05b75434,
- 0xe38381f9, 0x3bfc68a3, 0x71834511, 0x5c455b3d, 0xd12598df, 0x89251afb,
- 0x312dfaec, 0x9dff74c5, 0x6c5ca2b8, 0x0ef789fb, 0xda089f46, 0x8f0e6ce6,
- 0x5013ec4d, 0xc710ffe6, 0x4c5b6217, 0x8b78e0ed, 0x0658efc8, 0x448fbd22,
- 0xa35e6838, 0x29fcab2c, 0xe78bcda5, 0x99a7447e, 0x2a937e29, 0xe8463c7f,
- 0x8717cc31, 0x26393091, 0xe40c4e8c, 0xea3c998b, 0xe45e31b8, 0xdc7a2589,
- 0x5dbc7481, 0xbcb7b1d0, 0x658063b1, 0x4439bc3f, 0x1c97d8de, 0x1f6c6f32,
- 0x78637943, 0xd2eb8f52, 0x0e918fe6, 0x3c80d691, 0xaabf8c4c, 0xdf50d26f,
- 0x3c756634, 0xe3f91e32, 0x127f6ca8, 0x13c77f41, 0xb6e00439, 0x7c7675d9,
- 0xb616e464, 0x0bfa1c3a, 0x2fca363d, 0x8afe2019, 0xefc80bca, 0x4e2cf892,
- 0xd33e13ff, 0xfc3fb810, 0xe63b671d, 0x634ffb93, 0xcdff5456, 0x1a24b9ac,
- 0x2c2d88fd, 0x2552bc64, 0xd17c66f8, 0x3ce5195e, 0x25f81ba1, 0xe2aa3d04,
- 0xbdbf8a75, 0xbc36e900, 0xf50975db, 0x4807a289, 0xb45c6195, 0xb27e475f,
- 0xe896f9f6, 0x07c42592, 0x9279d0de, 0xe387334e, 0x29738442, 0x57783fce,
- 0xcdf51187, 0xce6f4542, 0xd03d31d7, 0xbf414ef7, 0xbaf0b73b, 0xd5f2bb34,
- 0x5fe2b257, 0xa19f9a31, 0x2d38583e, 0x87798bca, 0x1e596d85, 0x5129cb82,
- 0x76ddc55e, 0x85fd89cc, 0x8c160505, 0x657f1d73, 0xe40199d2, 0x77ae319a,
- 0xa28cecf4, 0xc67ec807, 0xaa629d53, 0xb34eabe0, 0xfd04e08d, 0xe81221bc,
- 0xaacb70b0, 0xe12fb8bd, 0x54677fad, 0x7721388f, 0xa6c9c30f, 0xe4567203,
- 0x1567ab61, 0xaf30f879, 0xf3134c77, 0xf784be78, 0x9def029a, 0xd69876de,
- 0x3cc0c273, 0xae97e026, 0xd0d9773d, 0x304c6d4f, 0x457f89d9, 0xec94eb9d,
- 0x878c807a, 0x410ebbbe, 0x6916d19b, 0x58eb0f59, 0xafdc6463, 0x11d845d5,
- 0x1dcd13ff, 0xf897e27a, 0xf1e23d6e, 0xf467410d, 0x4fcfc9ed, 0x39274460,
- 0x96e9c755, 0x44fbe369, 0xbff9d472, 0xc1dd0497, 0xebc34c6b, 0x58df2313,
- 0x7cce036e, 0xc70fd376, 0xdea247e9, 0x1679637b, 0xdd365bf4, 0xfc8f4e35,
- 0xa7c6fa9d, 0xcfea2059, 0xf7e72a6f, 0x69f1bd07, 0x6d77f436, 0xdfefc19a,
- 0x5ecfbc46, 0x38f774dc, 0x74bfebcc, 0xf9f02f55, 0x12422097, 0xc395bfae,
- 0xe2a1f574, 0x92bc5f0b, 0x7c06665f, 0x4fedb38f, 0x3aced027, 0xc3b7fa95,
- 0x237faaa0, 0xdf8098c7, 0x62be0bc6, 0x0764d1f1, 0x8dfa09c6, 0x3f68fbd7,
- 0x23e4ce8c, 0x1ac4defc, 0x8037c82c, 0xe55f4dad, 0xc07f7cf7, 0x4bf9a9ae,
- 0x02b63072, 0x2cd92de8, 0x566b27c4, 0xda385730, 0x5ddd40fd, 0xcceeebc7,
- 0xe057ef89, 0x03dfde51, 0xdead202e, 0x16d70c1a, 0xab81479a, 0x0798686b,
- 0x9fb149e5, 0x525d5c0a, 0xf498e3f7, 0x0f2fd9fe, 0x75ba404e, 0x48677545,
- 0x7090dfd0, 0x95d8e890, 0x64b8fdd0, 0x381bea0f, 0x5a6ccf1d, 0xef03ce36,
- 0xce3b28d9, 0x1986dca0, 0x2692bef9, 0x3de0538c, 0x3cb8260f, 0xbe03cf58,
- 0xef90fbb3, 0x87a48dd2, 0x79d40b4a, 0x67c16e89, 0xdeb813cb, 0x5cd61d1f,
- 0xd2f80c7f, 0xab624bbd, 0xcafbbc60, 0x89da2325, 0x8da76d89, 0x76eb680e,
- 0xbea2369d, 0xcc3ec3aa, 0x18c5b753, 0x12796f52, 0xd43f6164, 0xf481f07e,
- 0xe3c40ffe, 0x12f985be, 0xd9eee255, 0xfb1a3b1d, 0x55c1ccf7, 0xa8f77632,
- 0x5d91a39d, 0x0fed9d2a, 0x759b3b60, 0x9a16401c, 0x7e5592e1, 0x48eacce9,
- 0x595b5f95, 0xcfeaa71f, 0x80ea066e, 0x915ecf5c, 0x181f8eaa, 0xcf00abc4,
- 0x43f8160c, 0xe82e56fd, 0x83792338, 0xccadf71f, 0x1d3c1970, 0x6c4df341,
- 0x22b7a55b, 0x9d92f5dc, 0xd987afd4, 0x7c99b9f0, 0x3dead085, 0xd1b0f5c1,
- 0x51893cad, 0x7f226e57, 0x80fb02bf, 0xd91a8ad7, 0x0f10936b, 0x6eefba46,
- 0x5bbee895, 0x4b5777dc, 0xec961d4a, 0xe3016cee, 0x46c73dcc, 0xe110b6d3,
- 0xcef02bdf, 0x4b3b2f2e, 0x7afc28fc, 0x36e55d65, 0x7d70b3b0, 0x06dbfa6d,
- 0x8ff6779c, 0x45971624, 0x50eceaeb, 0xafdd51e1, 0x19f757ac, 0x9e6030eb,
- 0xf50af67a, 0xc209e1f5, 0x83620e9e, 0x25469e50, 0x2f927a48, 0xfd24ffd1,
- 0x007cd7ed, 0xf3b2e3df, 0x83e004f6, 0xea8fa31a, 0x2ecb8f50, 0xe1f72bea,
- 0xb9231d7a, 0xe4807f03, 0x5cf92258, 0x8a587063, 0x95ae8fd0, 0xb2676f88,
- 0x2b217f20, 0x72fa9e30, 0x093dfecf, 0x135a5fdc, 0xf54e5cee, 0x65923db0,
- 0xd52a5c1b, 0x07e8f43b, 0xe74291ae, 0x70259643, 0x418d7879, 0xf5700ef4,
- 0xbb452647, 0xd78c677e, 0xffedef03, 0xf41e39c7, 0x03e7fbef, 0xee50d81f,
- 0x2f19bdb9, 0xf024cdec, 0xebffd12f, 0x9394b72f, 0x68c5bf7e, 0xec2efd21,
- 0x1c2fa290, 0xa1db51bf, 0x288769f1, 0x79b498fe, 0x8bd405c3, 0x791d7d39,
- 0x07be011b, 0x1ffbf9c3, 0x71792ddc, 0xee5d4e1f, 0x499fd241, 0xdef81ec0,
- 0x47a164ba, 0xacfbd55b, 0x21af5092, 0xa5c84cc3, 0x1498a6f7, 0x1e90776e,
- 0xbac57c94, 0x497e80af, 0x69a9bde2, 0xe257c236, 0xd70916e2, 0xab3cce9d,
- 0x45cf8ed0, 0xb40c2c21, 0x97cfedd7, 0xbe7f5a4a, 0xe4f9fc9b, 0x7bc5230e,
- 0x9df8dbac, 0xe73d73f2, 0xfcd432ff, 0x53aa7cb0, 0x2bf2e207, 0xb9a798d1,
- 0xafdf4f67, 0x9b24dfdd, 0xc1b771d4, 0xc7bb8ea2, 0x9feb500f, 0xdeb57689,
- 0xafa23c99, 0xc714feea, 0x3bfdd520, 0xfd55f2cb, 0x54dbcee9, 0x2f2aefe3,
- 0x92c3f551, 0x00f269c7, 0xe44abcea, 0x255e7500, 0xa3ceaeca, 0x7dfe1d84,
- 0x317804b9, 0x2e1d3c9a, 0xc81343c0, 0xc06b08c6, 0x368a0c8e, 0x22367151,
- 0x6d8cdc3f, 0x1f30d0d3, 0x1f5349f2, 0x1d87871e, 0x07d937be, 0x766298f3,
- 0xf104b098, 0x1c5bc95b, 0x9a007307, 0xf03a9ea8, 0x39bfb57e, 0x17db8532,
- 0xb825f5a5, 0x36844f5e, 0x2a5b19f7, 0x14fd67f7, 0x1822989f, 0x345e8bf7,
- 0xc4a45f91, 0xe93ccac9, 0x50074569, 0xefdee47f, 0x6b09baa0, 0x27cc1665,
- 0x7914693e, 0xbef917d4, 0x0ed6dcdb, 0xbe48239d, 0xfae44cef, 0xe2ce17e0,
- 0x5d7f38b1, 0x9459581b, 0x1aefcda7, 0xd7593eb1, 0xf68d1ed6, 0x5df3886c,
- 0x02ebe623, 0xd39d85d7, 0x5d604777, 0x722d77e5, 0x72cafdc8, 0x1febcf22,
- 0xf2bd7a14, 0x547c40de, 0xafa02c34, 0xf5f2772b, 0x92374e55, 0x46c2c13e,
- 0x7a0dbd28, 0x2ade67ba, 0xf28c1ed8, 0x03ba803e, 0xdc6ab7f4, 0x2e3c69ec,
- 0x8dbd00aa, 0x5cfa0c72, 0x91ad3f7d, 0x73e80bf4, 0x010bf5d5, 0x15fb9e7d,
- 0x19c2773c, 0xe8f65f7a, 0x3f375e14, 0xfc212ae1, 0x88f002ff, 0x7a2ff27e,
- 0xf3e38de0, 0x167af85a, 0x37441f69, 0x2929b8ed, 0xb67c7fdc, 0x433d7d17,
- 0xc949f5d0, 0xd4ca879f, 0xbe208ced, 0x8d72699d, 0x7a47ccef, 0xf588de7c,
- 0x4bdfca89, 0xdfeced0c, 0x7ed30fda, 0x03cee33d, 0xd28fb889, 0x912072dd,
- 0x18d5df01, 0x8fd0ab6c, 0xa3b0be07, 0xead753df, 0x5b6bf823, 0x7af1dbf2,
- 0x4764ab6d, 0x75deec55, 0x93ad0c61, 0xbd623475, 0xe05ec9ef, 0x76e44cca,
- 0x8da26064, 0x985c07e7, 0xc3e7c113, 0xf9095ebc, 0xc212f400, 0xcd625bb5,
- 0x9d727fd0, 0xb79d6429, 0xff7be052, 0x57c5233a, 0xae3cf035, 0x41fa60e3,
- 0x68f909a3, 0xc24bac27, 0x1e9b1c75, 0x372ff389, 0x142ff430, 0xfba5cef8,
- 0x4ffae14f, 0x070087ce, 0x2f99afae, 0x2e4fbe13, 0x05c87917, 0x58cfea06,
- 0xdd7e2464, 0x46bdff37, 0xac9defcc, 0x4bdcfbe1, 0xf9467c16, 0x248b19be,
- 0x8a993f65, 0xd57e159f, 0x7f96a7f2, 0xf569f07b, 0x98e9f1f5, 0x3a7cabc4,
- 0xd03ced04, 0xf212747d, 0xce218fcf, 0xb2b9f946, 0xf00490cf, 0xec5a3766,
- 0xb06bafb8, 0x11207dec, 0x7e3ec4f5, 0x56cd687f, 0xdb1beb89, 0xa98728dd,
- 0x1eb6464d, 0xae44cbfd, 0xbd206697, 0xdd69710a, 0x7bc52452, 0x4bd46cfe,
- 0x0ef7ca59, 0x13be5606, 0xae7a71f3, 0x94bf066f, 0x107d75bc, 0x39129adf,
- 0x707a2abf, 0x76b99190, 0xa5bfde52, 0xe79814cf, 0xdbaf0359, 0xfaf98864,
- 0x331eedf5, 0x089fda05, 0xe027997e, 0x0af7fa50, 0xcd4f67fe, 0x344efc20,
- 0x5b8fbc71, 0x75c0abe1, 0x8b5d1934, 0x84fee112, 0xd06bb78c, 0xbf6535ce,
- 0x42f94b9a, 0xa73b2366, 0x46fbe7c4, 0x1965b07e, 0xe6fc37ac, 0xf863a208,
- 0xe4168d9e, 0x057ef0e3, 0x7c10ae49, 0xcbeeb4a7, 0x3902e636, 0x4d9cbbaa,
- 0xb29fd2ad, 0xf691acf7, 0x185db721, 0x39727243, 0xcf2bae99, 0xf9114a2d,
- 0x53dfb12a, 0x9e825fc9, 0x0bc88fd6, 0xc0f0538c, 0x215e1770, 0xd114f3c2,
- 0x3652d96b, 0x37d1a794, 0xd667fad2, 0xc0e6931c, 0x1c19773c, 0xd6167306,
- 0x77c7cacf, 0x537ee0e6, 0x71fd5cc6, 0xb9899d9f, 0xcfdfb88c, 0xcaff7d42,
- 0xb1bfea64, 0x63ed46d2, 0xd0cfe726, 0x5fdf4cde, 0x4df68fdf, 0x2cea3fa6,
- 0x1d74f786, 0xb6be0831, 0x3a94be10, 0x9936a5d0, 0xa5fee099, 0x35d5125d,
- 0x5d67f815, 0x715cc3ee, 0xdf15fd8c, 0x5da9ef07, 0x3be926f1, 0x3185f57b,
- 0xad0d1718, 0x7d88dd39, 0xc6cf8af7, 0x0a713fa0, 0xf5f907ec, 0x4b27dfe0,
- 0x198e47a8, 0xc55d7f71, 0xf3cd2b65, 0x0c7baeac, 0x15e797ca, 0xa74dea89,
- 0x93182f5a, 0x08627db8, 0x9f5816ca, 0x1895d703, 0xb771f84b, 0xfa71d50d,
- 0x4ab8f0e6, 0xc0fb43f0, 0x1e91a32f, 0xd7b615a6, 0x0fe7c36f, 0x77e50cc9,
- 0xb477717d, 0x3dfe8425, 0xfeb2f301, 0x6ad81d7c, 0x3d1b97ef, 0x5cf0ecfd,
- 0xfef42eb9, 0x9f0557a8, 0x3e29a602, 0x11293fc0, 0x55ff99e5, 0xac6292c2,
- 0x22f8f714, 0xdb2b8e40, 0xb1eace4a, 0xbbd897ad, 0xbd8c78ea, 0xf7b7e41b,
- 0xb4df87c6, 0xf4f9c3ad, 0xe201f641, 0x07e41646, 0x54c8dc61, 0xbcf0f7ef,
- 0x924e7a52, 0xaf3ac42b, 0x1f4741ca, 0xd57a0366, 0xf3ba0135, 0x5207df91,
- 0x5af77e7b, 0x298fca1b, 0xb451fba2, 0x8ebfac13, 0x8f5a8ce2, 0x93d9ffda,
- 0x4f78e5cc, 0x77eb9732, 0x12f1d513, 0xa3ef45c4, 0x145c431c, 0xa0df858d,
- 0x9d7b4978, 0xca1325e2, 0x1077bc15, 0x10f9e7d0, 0x2e4e1f70, 0x3df908fe,
- 0x9f133583, 0xe473e033, 0x3f3aed2f, 0x9153f613, 0xd72819eb, 0x5cadbfc8,
- 0x1ef3b5ae, 0x0cfa2e4f, 0xfb8759e1, 0x8de842b5, 0x6b3ac557, 0x97c23337,
- 0xf095b37b, 0x766d8e74, 0x9e5f0316, 0xfeb03803, 0x4674e5df, 0xc67d62c6,
- 0x9ab48ce5, 0x6ea07a03, 0xb73d0473, 0xdc6a672e, 0x2447e81c, 0xdf3fbe71,
- 0x3c42625a, 0xe5ccdacf, 0x29df794f, 0x94388cdf, 0xb74342a7, 0xd3f70ed1,
- 0xa3474eda, 0xfbb857df, 0xc39438ce, 0x47fce0de, 0xed775f12, 0xe3c67b8a,
- 0x87f85df7, 0xfea54cf9, 0x33ed5ee6, 0x0578dd52, 0x7f6dfe23, 0x28756ff1,
- 0x22dbe7c7, 0xcf37682d, 0xa0f489ed, 0x257aeffe, 0x2893abcc, 0x80c4f0ee,
- 0xe8673b5e, 0xe5fe4498, 0xfe82d96e, 0x8f95fb9d, 0x7479451f, 0x9e8618bf,
- 0xb6d25b1e, 0xbdda02f6, 0x67b1b69a, 0x9f6843f5, 0x1e553ff9, 0x47dc576a,
- 0xffd2917e, 0x89c9a578, 0x9ebcf47a, 0xad2589eb, 0xbbbf902f, 0x21a5cae4,
- 0xb73ef758, 0xa186bfe7, 0xf1ff735e, 0x67d430d2, 0x1a5c3fee, 0x2fddf786,
- 0xf287d645, 0xc8a55657, 0x5ec57f44, 0xabd71d66, 0x0b1f43f2, 0x686ac8fe,
- 0x9bfdc32e, 0xd9a6c785, 0xdcab7f31, 0xa3a7ec2f, 0x6f85fafd, 0x082dc695,
- 0xafc1ae7a, 0x05ebc32f, 0xe7234ac7, 0x4765f107, 0x2fc941b2, 0x075e575e,
- 0x0587eaef, 0x3afc71e5, 0x5b8c3847, 0x7df3d7e7, 0x1792d5b4, 0x5ff00be3,
- 0xdf91cfb4, 0xce28b5d4, 0x04fc9ebb, 0x05c1f8e7, 0x5f67efd8, 0x62b5436f,
- 0xe413903a, 0xebf0cd27, 0x47c0617c, 0x3e616de5, 0xfafdeff2, 0xfe17d4d3,
- 0x1f0bacd3, 0x21496544, 0xde0333f2, 0x5c7a8d18, 0xbf81a79b, 0xf15b8428,
- 0x5dea2ab7, 0x36bf08e9, 0xfcbb337f, 0x690fca0e, 0x7e5937f3, 0x01626ebd,
- 0x4d79e7d6, 0x937f9d74, 0xf145e509, 0xbb7e9143, 0x67ffc842, 0x8a7e9c49,
- 0x75f8355c, 0x7f069744, 0xda0729b1, 0x2efee2f3, 0x1df8a730, 0x9ddb4347,
- 0xd08f30db, 0x48aee570, 0x1c355dac, 0x3bf0ca9f, 0xb14b2e8e, 0x773e1fa9,
- 0xf4d30ee5, 0x68bf00dc, 0x8927b7df, 0x9f80cbeb, 0x3deeda10, 0x9ff9e427,
- 0x27b6ff65, 0xffcfcd5d, 0x20ff6d5f, 0x9499df0e, 0x4cf87140, 0x71e1279e,
- 0x286ed6b8, 0xf79958fa, 0x9ee7415d, 0xf92cf8fa, 0x932f1037, 0xc9377e3e,
- 0xdad2e346, 0x1c51c4a6, 0x9c5a7c7d, 0xfe73dccd, 0xcebb7abe, 0x7e73db9a,
- 0x7b738fc5, 0x184c071c, 0x3ef838e7, 0x8934f731, 0x7e2ad5f6, 0x9129db9f,
- 0x30aeee3f, 0x029c7178, 0xcf1a7f97, 0x18774eab, 0xc052e1bc, 0xc7fc543f,
- 0x12edf7ab, 0x49fc57dd, 0x3bf46fc5, 0x5a771e79, 0x98ffbf01, 0x093275c9,
- 0x70be41eb, 0x92385eba, 0x79cc675f, 0x77fa1520, 0x246250fd, 0x549fc2ff,
- 0x6feb54f8, 0xfbeb6c5e, 0xb7e4fbb5, 0xe454fe08, 0x1f23432c, 0x108afd8a,
- 0xfb43aa78, 0xfbf6871d, 0xae5f950b, 0xf7ec179d, 0x8e7a24b9, 0x6f05f3d1,
- 0xe2a19de9, 0xfe6295f3, 0xa0fd207f, 0x2feff34d, 0x99d37842, 0xf6b9f69f,
- 0x85bb5766, 0xfddbd37f, 0xcf286f88, 0xf89d8403, 0x4e73c967, 0x790cfff2,
- 0xf617eabe, 0xe1dd9df2, 0xc9c1a2e4, 0xdeb97f48, 0xf7f2845f, 0xfac84367,
- 0x7f8115f4, 0x7c557388, 0xa8dd207c, 0x5dc8b8c3, 0x4d03f3cd, 0x29d7b6b1,
- 0xd32c397e, 0x1025ebfe, 0xb6ffa207, 0xda85b2f8, 0xa193f41a, 0x31ccf99d,
- 0x9997ea03, 0x9bf86ad5, 0xcf8b7730, 0xa2f2cd2f, 0x4ac95cdf, 0xd954af29,
- 0xfdc16b16, 0x2d094dcc, 0x3cae5107, 0xb6db64db, 0x06ebf1e0, 0x9e26f18a,
- 0xa58eab6f, 0xe34c93fd, 0x6bd65407, 0x5fb57dfd, 0x13c89b70, 0xfc1fe6f5,
- 0xeb9c3da1, 0xc9324395, 0x97e61d79, 0xd8cc616e, 0x7b82f5c6, 0x4de53845,
- 0xb8435e30, 0x79215c3e, 0xad77004d, 0xdea1f718, 0xaa27f94f, 0xb390c1a7,
- 0x51131b6d, 0x5d43992e, 0xea7daa3f, 0xda9bd22d, 0x9775923a, 0xad5d0ba8,
- 0xb0930d1b, 0x64f10b5f, 0x3697fa12, 0x3fc464db, 0x47daa7c0, 0x1705f8a6,
- 0xf147bd0f, 0xbcddcce7, 0x7ea3d3fe, 0xd78e34d4, 0x0d3ec48f, 0x76721e6d,
- 0xa903c1e6, 0x8dd76bb6, 0x198f5aea, 0xe1e8ae30, 0x8efc687f, 0xf3ab269f,
- 0x9e7a998c, 0x936ccdc7, 0xca9f982c, 0xbe1c7814, 0xeafc822e, 0x1f9f7f31,
- 0xa140fa87, 0x1c29f9d3, 0x7e4fe7af, 0x045b445a, 0x84b7aefe, 0x70febac3,
- 0xa99bf972, 0xd9336fbc, 0x91e5b9f0, 0xdff43df4, 0xbc4489ef, 0xdc5a01fe,
- 0x09d2f997, 0xa47cc87d, 0x1fe5c294, 0x93cfe1ec, 0x2fde1ed1, 0xb07ad2f2,
- 0x7c815187, 0x9b39f68e, 0xc209ae78, 0xee63ca14, 0xa6fdf5e6, 0xea38d714,
- 0x6d9b32ff, 0x41d0ff23, 0x8017e779, 0x345f31af, 0xf58b1608, 0x5822e7e7,
- 0x9a8bd603, 0x92af5c12, 0x6752fd1c, 0xe7823943, 0xd9e4cea9, 0x88fb2369,
- 0xce7ac328, 0x2649b010, 0xf7c0d7da, 0x74140c47, 0x1638814c, 0xcd0049eb,
- 0x0f37ac34, 0x219d7512, 0xf38f4c11, 0xad70683f, 0x48eb19bf, 0x2afb7aed,
- 0xdc7b0212, 0xf59ea894, 0xebc1c925, 0x499d4ae2, 0x56f78fa9, 0x3df09267,
- 0xaf0e1f7c, 0x727d892b, 0xfd893d4a, 0xae4549d0, 0x19ea2335, 0x6949adc6,
- 0x0bedbbec, 0xf9e759eb, 0xdab9c63b, 0xc047cf3a, 0xa13f3ce3, 0x1fae2bae,
- 0xe9f13cf0, 0x0e27adb7, 0xb8376648, 0xa3f1c5fe, 0xf620bb85, 0x5bc52262,
- 0x68cff8ff, 0x976db3b2, 0x75761ec8, 0xe53f3187, 0x9e783b1d, 0xef7f8dbd,
- 0x5b7105d3, 0xbd9d9042, 0x7b5bf843, 0xff884adb, 0x234bf977, 0xb0bd7c71,
- 0x4f8eebe3, 0xd3bf13bb, 0xb4f5f8f2, 0x1e31872f, 0xebf2ed87, 0xb96fd10b,
- 0x22f97481, 0xcdfd4429, 0x93edc114, 0x4b9e8e56, 0xe7a4f9e6, 0x947f3992,
- 0x97f1e49c, 0xa3af397b, 0x705e8458, 0x0f491997, 0x944f4c1e, 0x5279fc94,
- 0xeecb3aa8, 0x951bb26e, 0x3fda248b, 0x9675dd7b, 0xb76176d6, 0xb2e9f934,
- 0x7b37a431, 0xd5075bcb, 0x33f755cd, 0xe13ec452, 0xdd7f3cc1, 0xf5a16c9c,
- 0x1687eb5a, 0xaca64ba1, 0xe1d206ff, 0x5bf7ca68, 0xf3eaed67, 0x27bfcefd,
- 0xdc9c8421, 0xfb3ff9c0, 0x4397e79e, 0x381ba7e9, 0xefc4df7f, 0xf93fff17,
- 0xf79fe79e, 0x6467e33d, 0xfff43d28, 0x6d003eea, 0x2fbb5f9d, 0x0fef5b40,
- 0x83c0bc3b, 0x1b4ad6f7, 0x9ad07dba, 0x972c5fa2, 0x63eb5540, 0x1da1329f,
- 0xd792309d, 0x9a95d6c1, 0xc0a55bbc, 0x5f0500fe, 0x1c7953a7, 0xe0bdc961,
- 0x673c0389, 0x71a5fc38, 0xc91b2798, 0x0aee0e28, 0xa630f5e7, 0xa14ca4b7,
- 0x9496f6fd, 0x9b37a0a9, 0xe95ef97a, 0x6f5f3141, 0xad3d2476, 0x214a70e8,
- 0x943c8eff, 0xea2596bf, 0xbe569652, 0x6de996df, 0xbde95329, 0x87f414b6,
- 0xebf3f662, 0xd8e63ed1, 0xb2d9704a, 0x683c52a6, 0x1ef842cb, 0xeb5ef511,
- 0x9859feb8, 0x5f82b68f, 0x8dc0f588, 0x78a41758, 0x94e342d6, 0xc3eccdf7,
- 0xc0c47de1, 0x7adfac24, 0x99fbe66e, 0x5542f358, 0xc188ef3d, 0xa24739d7,
- 0xea275e7a, 0x5f3aa3eb, 0x825993ee, 0xb9bf0189, 0x67542cbb, 0xffe46d7c,
- 0x5bbfc01e, 0x65bdf5e2, 0x1f643e16, 0xc700cdc6, 0xc4f93db2, 0x8ef733bf,
- 0xc6054bfc, 0x1cfc391d, 0xa5711e90, 0x109c17c8, 0x5f250ef9, 0xdeb5d4a0,
- 0x53927911, 0xb6817f98, 0xd021f303, 0x37747d4a, 0xa1493eda, 0x1223c7ec,
- 0x8e790fcf, 0xbe50fcf2, 0x7837ded1, 0xc0b464df, 0xaf1f1ceb, 0x9ef9285b,
- 0xf93d62ed, 0x617d963f, 0x37e697e0, 0x9da2360e, 0x8f4c6fcf, 0xc38876c0,
- 0xef12c3ab, 0x753bf98c, 0xf142fd0a, 0xee1f7251, 0xd43bac8f, 0x17bd754d,
- 0x99fe7534, 0xff748c7d, 0x99c7e0b8, 0x97f5187d, 0x41afd3f5, 0x946631f7,
- 0x4f550e45, 0x18b884aa, 0xc4d39ce1, 0x5df056e1, 0xe095b3e9, 0xe81f4e7b,
- 0xaf36c46e, 0xf284ab3a, 0x1a1735ed, 0x5f737fd1, 0x76f074b9, 0x6d1997ca,
- 0xeacc4f18, 0x2edde750, 0x96fdf2a5, 0x7bfc482f, 0x3d58cf4c, 0x63f9c7c5,
- 0xd63fc4f5, 0x5f8a70ca, 0x9b2606ad, 0xfb853fb1, 0xf1657945, 0xd367d825,
- 0xcc1fc962, 0x5d8b643b, 0x83c81b90, 0x4f2ec759, 0xab5d3c40, 0xd3e4aabe,
- 0x4639331e, 0x6dbf3d22, 0xc8f6b57d, 0xaa57da71, 0x8bc14bac, 0xaded2752,
- 0x73ecaabe, 0xaa7d9770, 0xd6e197da, 0xfcc18f77, 0xd39efe63, 0xd2cfb146,
- 0xa8159c92, 0xbeefe6bf, 0xa5577540, 0xbfaeeace, 0x3c357e40, 0xe490e747,
- 0x4053f903, 0xc95aee4f, 0x022fafeb, 0xc2b6d83c, 0xd7001dfa, 0x6c7eb0cb,
- 0x78fd60db, 0x039595fd, 0xb4adf5a8, 0xe577bb53, 0x6ddd6a08, 0xeb5ea817,
- 0x7f63d3ea, 0x1ef3d524, 0xfaf39d97, 0x5247f7a8, 0x93ef5b5f, 0xc6be7823,
- 0xdf40c87d, 0x988fb82b, 0xb5177f48, 0xf8c4c9cd, 0xae63f3e0, 0x0ebb844c,
- 0x7c416deb, 0x0f61de71, 0xce3173c7, 0x58e1ed3b, 0x3f6fcb67, 0x2ffdc46b,
- 0x11bf7a75, 0x710061f3, 0x744d6e2a, 0xf7c0baef, 0x8515b6f7, 0x59af7e23,
- 0xfffd6b17, 0x536fb175, 0x202afb17, 0xf247a49f, 0x56c73a9c, 0xc2390f6c,
- 0x89e90417, 0x4f5e4e75, 0x4d939759, 0x99c9b872, 0x683f3b1d, 0x9e3286be,
- 0xcd8eb0bf, 0x3ebe0f09, 0xf340cd35, 0xa09cf15b, 0x156fef10, 0xea06ecfa,
- 0x213ed6ed, 0x47f3b6fc, 0x48ddf44d, 0x9985eefb, 0xea5fc41d, 0xb2badc7c,
- 0xfdf899f9, 0x1844e7bd, 0x75f3c7eb, 0xd31c7caa, 0xcb7ae3d4, 0xd32ccdcb,
- 0xce29c239, 0xbb40ceea, 0x319bcdad, 0xb706777d, 0x7e548eeb, 0x9527835e,
- 0xea3d608d, 0xde657f72, 0xfc6072b7, 0xd91d328c, 0x973ea50b, 0x2b67a657,
- 0x56f33f81, 0x9754bc18, 0xa69fd32b, 0x6c6e22fb, 0x22a5e4b0, 0x623a9f9f,
- 0x57da84b4, 0xaa7b2f6d, 0xb79e1b29, 0x5c7648d7, 0x77eab5d6, 0xa3edad95,
- 0x16fd6953, 0xf124e519, 0x53efa320, 0xf8f3d67b, 0xd63cef7e, 0xe30a54dc,
- 0x82ce8e58, 0x679b51f6, 0xbf433e43, 0xef879b44, 0x4bbbf612, 0x48c1cfd8,
- 0x8f9c04db, 0x73ca4bfb, 0x4d29fe5a, 0xaf36be95, 0xfdca905f, 0xbcb286aa,
- 0xdf483975, 0xf6863a09, 0xd8aca1a4, 0x9f341394, 0xe34f552e, 0x60fac11e,
- 0x907d707c, 0x75b501d7, 0xe5cf4541, 0x06317fb7, 0xf409bdf1, 0x7731da35,
- 0xe41faf32, 0x087452bf, 0x4e0046f5, 0xc94dbebe, 0x8eb7bf57, 0x0c5d7c65,
- 0xf679cbf7, 0xcb9f9448, 0xdee9f09b, 0x139fc448, 0xb5ea1eec, 0xcc6b3923,
- 0xe8268fa8, 0x1dfbf10b, 0x5aba53b7, 0xd27ac267, 0x8f57af9d, 0xf209efc3,
- 0x863d0fa7, 0x615e9f78, 0x7780fda0, 0x063e5ebe, 0x2ff62baf, 0xd5d6fa7f,
- 0x807f7811, 0xe1b70f64, 0xbc62b2fd, 0x0f877e3f, 0x226ce933, 0xdcfa0742,
- 0x8f53a47f, 0xc998f372, 0xf00a9d95, 0x75114fe6, 0xa76e0aa6, 0x314db7a7,
- 0xaa4fee30, 0xf4bee6ec, 0x741f29cf, 0xea9f2da9, 0xefb87147, 0xaf603721,
- 0x1d80f7f2, 0xb1d80a8b, 0x4abf6aef, 0xcf842d53, 0x218ec05b, 0xbc29d63c,
- 0xbfa5af3e, 0x37bfd04e, 0x1e9bd4bb, 0xe783fb46, 0x4a7ca0a8, 0xb8ed3dc9,
- 0xc33ef30d, 0xf0975fd1, 0xf95e9590, 0x6fd0a96f, 0x73f8bdb1, 0x7af80af7,
- 0xfad537dd, 0x2d33a9cf, 0x521ffd4d, 0x97f11267, 0xe2526f52, 0x9e04d7b5,
- 0xa175f695, 0x77f3be37, 0x435c680c, 0x0d60c77e, 0xacc31dfd, 0x44873a16,
- 0x80e18ef9, 0x8ced1591, 0xe2b3fdc7, 0x93af26bb, 0x8f03a4fc, 0x37f1b5fd,
- 0x935df8f1, 0x80672784, 0x76463c3d, 0xae8f395e, 0x9e63edae, 0xfbe16d6f,
- 0x435b6bc0, 0x9912eb9f, 0x297bedc6, 0x33ea87ac, 0x98ed7f62, 0xe44ea25d,
- 0x596d7a30, 0x4fbcb798, 0x74b79c1f, 0xca09fcdb, 0xc52f5dbe, 0x663cea7b,
- 0x3acb796f, 0x6afc3be5, 0xd1df8ec9, 0xd31e775c, 0x7ee1f7c1, 0x4be63cdb,
- 0xce3aeaa9, 0xad0b1481, 0xd125dcbf, 0x9d264cb9, 0xe7f686b3, 0x425922bf,
- 0x9a3eebed, 0xbc75e5ca, 0x6d3c83a8, 0xf4f1fce4, 0x8bed12ad, 0x90edefc7,
- 0xc2bf4fee, 0x3a79b7bf, 0xa36f7f8f, 0xef943dd4, 0xd40e6e68, 0x3b3be83d,
- 0xe51bfbe5, 0xfbe51a7b, 0x239b29cd, 0x07e23ce8, 0xdcc92d0d, 0x5f10f5ef,
- 0xf61e2bfe, 0x30d0f580, 0x5e4a1f56, 0xfd16a777, 0xbb8d2a6b, 0x476f71e1,
- 0x29ff086a, 0x7848e309, 0x5ed499cf, 0xa9b385e3, 0xfa8178ea, 0x46e178da,
- 0x4bee3dd5, 0xdd7a3765, 0x8df94203, 0x2dfe7037, 0x9bfcf3df, 0x4d6dd143,
- 0x15f3e878, 0x1d44d32b, 0x380e735d, 0x245df1eb, 0x924debb7, 0x51b72fed,
- 0xf540dd3d, 0x36af4574, 0x73f9f145, 0x7b4a7cc5, 0xb3d71a47, 0xf9d0864d,
- 0xdc62a9b2, 0x2831d946, 0xcf41da0d, 0x8397f3a8, 0xcbf9d45b, 0xe7d55a5b,
- 0xa9f50c85, 0x3fc903cf, 0xa61f3ea4, 0x1f3eafd0, 0xf509f866, 0x3b2330f9,
- 0xdcc3e7d4, 0x7cfaa1f6, 0xab741f98, 0x5fb797f3, 0x5ef9aa9e, 0x77cfcbd3,
- 0x7e0dce02, 0x4f34c4ae, 0x4e8d2e73, 0x844d2e73, 0xcd1a5ce6, 0xde622839,
- 0xcd1f4f2c, 0xf5ea34f9, 0x971eb159, 0xb8f5fd7b, 0x44d8fa67, 0x386fae3d,
- 0x5948f73e, 0x6dfa384e, 0xffd377ca, 0x97ccf821, 0xf48b9ae6, 0x5b1ead71,
- 0xb1d57c87, 0xf3032c2a, 0x29d5ae2e, 0x83f03c72, 0xbe8921eb, 0x9d5e2f9b,
- 0xe67bfb42, 0x3f250c35, 0xc8398f29, 0x638caa4f, 0x5873cf21, 0xd6f5c69f,
- 0x33037adc, 0x6ccbe0c6, 0xd0a81d46, 0x5b124d73, 0x798dedcf, 0x3561f022,
- 0xbb587ce3, 0xd53458ee, 0x59dd85bd, 0xaac151c4, 0xb9d217eb, 0x5d73da0d,
- 0x318b586a, 0xbc59e605, 0x41e49da1, 0x628bce7b, 0x9e62dc87, 0x7df516da,
- 0x8170db37, 0x1d6789ce, 0xee33b446, 0x86fdf556, 0xb32f5134, 0x8dca3b33,
- 0x1328beeb, 0x02c597fa, 0x4836732f, 0xce0fac16, 0xb84f686b, 0x0ef3fa0b,
- 0x296f14c9, 0xce3d6178, 0x73a5c9e1, 0xea1e2fd2, 0x45f3fe47, 0xc7092d9b,
- 0xbc79a2b9, 0xc35de920, 0x9c657af1, 0x5f9e386b, 0x0a327dd6, 0xa761f1bf,
- 0x5fc8eb2f, 0x08681f00, 0x36166df9, 0x3bcf3824, 0xc44960c7, 0xdd878b3c,
- 0xa6714c93, 0x75957b88, 0xc7104dbb, 0xe21f6346, 0xe93ebe54, 0x46e8892b,
- 0xfc1bad26, 0xf80f7c22, 0x9ac7143f, 0xfa156998, 0xcd6d673f, 0x3afae889,
- 0x5f90301f, 0x2c477731, 0x1b7315f9, 0xfe788c4a, 0xb15ddcc1, 0x79967fb4,
- 0xae31c71c, 0xba78e855, 0x3260ff21, 0x25b73bcc, 0xe9ab2ecb, 0x17138aa7,
- 0xe8569d37, 0xba0d79d6, 0x1ba28675, 0xfd754bd0, 0x17e134e5, 0xfbb17a08,
- 0xbdfbe8e3, 0xfa07a58a, 0x62efbe61, 0x0efd387d, 0xc038cf45, 0x5a64f5c3,
- 0x29de2abc, 0x8e3573eb, 0x2fba73a3, 0xba24286d, 0xf655e969, 0xe386f3df,
- 0xafec55f7, 0x8dfd0c51, 0xf66cbeca, 0x5b3eb854, 0xb955f2e2, 0xfa196c66,
- 0x7d0a6f39, 0x8b88baf8, 0x045c618e, 0x189bfc7e, 0x2dff4117, 0x05fd1711,
- 0x4f6822e3, 0x6d045c62, 0x4fff38a7, 0x00603391, 0x4293d7e2, 0xd55e4ebe,
- 0x3193cbf3, 0xdff6569f, 0x80ea166f, 0xb53c12e7, 0x33a74693, 0xf6a1d936,
- 0xa9a7cba7, 0x830ee9fd, 0xed324c65, 0x81f5e26b, 0x54dbceb9, 0x66de99e3,
- 0x1b073cc4, 0x4eb81f90, 0xc466c7f6, 0x098cc73c, 0x3ff1aa71, 0xf5554a6c,
- 0x0c5fa02f, 0xeb294df0, 0x777ebaab, 0x7f5520c5, 0x424065ce, 0x95af723e,
- 0xe22ce79f, 0x2794ca24, 0x9f0dea06, 0xfa4f0fd6, 0xe9fbc011, 0xd7dd0311,
- 0xeba143d2, 0xca3acdfc, 0x0cdbcedf, 0x3b79836b, 0x5c91e79b, 0x8a227c7d,
- 0xdc6987ce, 0x08daff91, 0x61de9fe8, 0xa764fda0, 0xc21ee21b, 0xef4faaf3,
- 0xefc68848, 0x328d5cf2, 0xb59e91f3, 0xe6559e90, 0x4558692d, 0xc7307fbf,
- 0xf947661b, 0xf3dfb39f, 0xfdc7d2b8, 0x0645b401, 0xecb8e3e5, 0x3f4449f5,
- 0x7b77e107, 0x3fc5e538, 0x058f3034, 0x1d79cbfc, 0x250fae1c, 0xb3fd80d6,
- 0xfff4efe1, 0x6e71c011, 0x0e957362, 0x48f928fd, 0xe7cbe902, 0x5b7c8665,
- 0xe740d4b1, 0x4b7a2f09, 0x267d8ade, 0x7a72a5e5, 0x1d3bf4cb, 0xcd187b6c,
- 0x4381bacf, 0xdff2dc60, 0x5eb93d84, 0xffa8b9e4, 0xf5dec1fb, 0x8f913f82,
- 0x8e658c3e, 0xe7960258, 0x963a3e1b, 0x009e7540, 0x7043bd3e, 0x3bd4bfdd,
- 0xbd83a5fb, 0x3bcaa8fa, 0xfddaf484, 0x5a572409, 0xb91a77bc, 0x1ca0f2de,
- 0x197d0148, 0x9dfe3390, 0x3d833cd5, 0xaafa4ed1, 0x55f50520, 0xe50306e7,
- 0x11de9915, 0xcf70ebcd, 0xef2b1f13, 0xc6dbd4e9, 0x4d9d7c20, 0xe11df459,
- 0xd9320ddc, 0x3e3fe43b, 0xebe3cbde, 0xe30bb28d, 0xe4934f75, 0xcb5d78c2,
- 0x0e96cb37, 0x9815dfa7, 0xd9193885, 0x4f9c0f53, 0xa50775e1, 0x3f0f78bf,
- 0x74159fd7, 0x0e0da7e8, 0x7f03475e, 0x5f9f325f, 0x26bc7739, 0xf0a74ffb,
- 0x878ba668, 0xf7e0c6fa, 0xcb8f6738, 0xb36767c4, 0x0325879b, 0xedd13f3d,
- 0xe823f61d, 0x73d13c7f, 0x70fd8f46, 0xebc454d7, 0x0c86dd12, 0xabba1efc,
- 0x6e87bded, 0x7a3ee783, 0x312760d6, 0xfa40915f, 0x45f6f163, 0x7df75f99,
- 0x3ef05810, 0x48e8cf3c, 0x4b9f0091, 0x30632d6c, 0x3980b07f, 0xf8e21d85,
- 0x79e0edb1, 0x9e26cb0c, 0x30af78d7, 0x67ee3d6a, 0x5bc9a79b, 0x13be27bc,
- 0xa92e905c, 0xa2ed84fc, 0xf9c74f3f, 0xf3c73d9b, 0xd2a7f059, 0xfbf16eff,
- 0x57de8a1e, 0x6b0d75f4, 0x7fa9f3a6, 0xf04d9e94, 0x34bc922c, 0x9a4f0eae,
- 0x65551506, 0xcd6af1e1, 0x8a5e6133, 0xe9606d47, 0xdd80fc82, 0x6e7a36e9,
- 0x47d9f1b1, 0x32176d91, 0x669f5f3f, 0x6f0647dc, 0xa7ab3f95, 0x6cb2a9bd,
- 0xfcd2b06d, 0x57ee3b06, 0xb4e4285c, 0xfaf259b6, 0x6ec83af8, 0x2cf3102e,
- 0x6b537610, 0x23d87a9f, 0xa05a1d8d, 0x59acb3b1, 0x5e01576d, 0x815b973a,
- 0x33a70b57, 0xb0f08a32, 0xcf9f99b8, 0x1ef2e551, 0x4b70449c, 0x0f64a076,
- 0x67321678, 0xe3ae2c69, 0x6b8f1e19, 0xabaed3e1, 0x9d62bc07, 0xecabb85a,
- 0x01727c17, 0xda0a3dff, 0x8759a9df, 0xbfad0f42, 0xcaa5d0a6, 0xd55bf1c3,
- 0xdf3d1126, 0x3207eabf, 0xf0aa07da, 0xff816b0b, 0x4e779ea9, 0x70b67d42,
- 0xacdfe813, 0xfc28ff00, 0x44b598b4, 0x31d4bf23, 0xd496235f, 0x7e5afacf,
- 0xcf0b3238, 0xe7463a65, 0x7d585547, 0x80b174fd, 0x1fdfcf42, 0x8041fb2a,
- 0xbe78b5af, 0x17af5d16, 0x11d44c6f, 0xd3c039e8, 0xfa64a782, 0x9c6827ae,
- 0x243d7f88, 0x8f1ed54f, 0xd5cbeb11, 0xdc3e7e7a, 0xeb74e0b5, 0x5d29eff9,
- 0xfc5ede13, 0xf70aefa4, 0xf9bde907, 0x4262fd59, 0x9d6529e9, 0x72bd08ef,
- 0xb7aefb4d, 0xbec8c5df, 0x8f984827, 0x575f4de9, 0x00bebb09, 0x67b43ced,
- 0xe740bf36, 0xe9bfbe2e, 0xd55f3a05, 0xda02ecf8, 0xf3667097, 0xf7f087bc,
- 0x98ecce23, 0xe17d7647, 0x775d8a63, 0x85fd8319, 0x9e73cd92, 0xafc85ff8,
- 0xdd5384cf, 0x4bbf6ab8, 0x47a039c4, 0x336d9c61, 0x136c9bd7, 0xd10ba3d7,
- 0xfd92e5fe, 0xddc709bb, 0x09bae557, 0x3ae83ef9, 0xe6fbc5d9, 0x07b77eb9,
- 0xb7efbde6, 0x2d0f7691, 0x79e3e2d9, 0xed0f8b67, 0x7f3ded5f, 0x0bbf4539,
- 0xeb791f25, 0x87bd8ac7, 0x577aedee, 0x97ca0642, 0xf2b5f3b0, 0xfa0b0cd6,
- 0xfc2ec205, 0x173df1b3, 0x14fe4df1, 0x4dbbf7c7, 0x6defcf1c, 0xdc6f78e0,
- 0xd3e297d1, 0x92fa9b77, 0x8eeef51f, 0xf9ef847e, 0xe4df01eb, 0x7ed4db47,
- 0x1be01354, 0x37c404e3, 0xbf7735c0, 0xcedbe04d, 0xf1c4ddf1, 0x76f036cc,
- 0x7abc0f7e, 0xfbf4fce8, 0x8ecc3dfe, 0xe187c17e, 0x3e97f23e, 0x99d329dc,
- 0xa59f8a67, 0xb19f39f8, 0x1fd1c7e6, 0xa8bdf053, 0xea087fbf, 0x7f8d8a97,
- 0x2fbc468a, 0x2393c9da, 0x1ccdf03d, 0x076fe849, 0x2fd57fde, 0x0848cb2a,
- 0x21be8bf2, 0x9398ea5d, 0xe1d723f6, 0x82436479, 0xbf2b3df6, 0xe7dda65b,
- 0xc8f9e36c, 0x99376630, 0xed349e10, 0x18b9afef, 0xbcfe7bee, 0xf75985df,
- 0xab771c90, 0x12634f7e, 0x9cf019f3, 0xd122d602, 0xe5da967e, 0x188ba34b,
- 0x4f5a3f9e, 0xe0cdac70, 0xbc2bbd76, 0xb2fc833b, 0xef1c613d, 0xf3aaf19d,
- 0x6fdd2789, 0xb457f98f, 0xf9f847fb, 0x763c93c4, 0x1a4e67ca, 0x2ab93431,
- 0x2e0bae88, 0xab8973f3, 0xf2e6032e, 0xc6fdf7f1, 0x0587bed2, 0xcea853cd,
- 0x496d055f, 0xbe5ef8f0, 0xc19b5bbf, 0xb8539be3, 0x973c3ca6, 0x9d7efc49,
- 0xea8d1738, 0x539b80b4, 0x373a4ee1, 0xc98254ef, 0x8bbacfce, 0xeffdf3a1,
- 0xa6707a16, 0x13ed20f9, 0xcc3c7987, 0xbfd6e78a, 0xab014069, 0x8b3c7530,
- 0xe4ecf021, 0xe935eef7, 0x837f6b70, 0x7773e445, 0x13d7157d, 0xd51d009e,
- 0x23b9b9e7, 0x9a3fe742, 0x87255e05, 0x610cea83, 0xbc047730, 0x3619e7ff,
- 0x6fec5d7e, 0x9e805b67, 0x85cf3d51, 0x0f33ae53, 0xa6b60f3f, 0x2b7dfe18,
- 0x7a848ce3, 0xfaa9d643, 0x7f7e4635, 0xc9c4c67b, 0xf631469b, 0xf7ac0306,
- 0xf194bf45, 0x8c4e7f38, 0x4d75f717, 0xaca373c6, 0xaf89ead8, 0x4799eaa6,
- 0x3326dbc7, 0x79c43bd6, 0xfe049351, 0xbe608fa6, 0xdf7de018, 0x89b9f561,
- 0xbe74f977, 0x93af009b, 0x21ba5cf1, 0xcd9cfe78, 0x38f78160, 0x8c3ca4cb,
- 0x7f566a4f, 0x64f77833, 0x94de4f94, 0x8e9d7d06, 0x9e63f9c3, 0xf989988f,
- 0x2cc3c079, 0xe72fdb3d, 0x5e237a71, 0xed1b56dc, 0x2a5ee8f3, 0x25147ed1,
- 0x7bd0af2f, 0x4f2f2068, 0xe0299c74, 0xa29a7983, 0x686379f1, 0x50ce1d7a,
- 0x8a16e8e2, 0xf90897af, 0xe5c8a25c, 0x9e5cb50e, 0x7e823a45, 0xc8893dc6,
- 0x0b453357, 0x6bf9a4eb, 0x73947bc4, 0xf064cfd3, 0x0c99e97c, 0xfe387f5e,
- 0xccc7df2d, 0x45469cfc, 0xf8c36b3e, 0x27fbcafc, 0xc333b68b, 0xf02bf34a,
- 0x1ff1f368, 0x7e43596c, 0xccb7f552, 0x1be907c7, 0xc6497baa, 0x7a88f9ee,
- 0x49c25fe9, 0x5b1a66ee, 0x7b9bd5fa, 0x1dce538e, 0x037e60ac, 0x55300faf,
- 0x6cb4741d, 0x2b2c73a6, 0x9afbfe24, 0x1e51455d, 0x6be60c5d, 0x8ada440c,
- 0xe973f31f, 0xfbe709de, 0xee632b3b, 0x607e849b, 0x4f51b445, 0x7f31ece7,
- 0x40565654, 0xc91636ef, 0x04214e74, 0x6eb19382, 0x7feb06b6, 0x23b0ffbc,
- 0xa24bb28d, 0x51d7b3ff, 0x02bb4d1f, 0x43fea7f4, 0x0f101d93, 0xf7101d75,
- 0x7cf4c3d9, 0x8f8203d7, 0xfde73f3d, 0x37f7285f, 0xe53afef3, 0xffde16fe,
- 0xe8bf3299, 0x5fdcd46f, 0x4bffb9a5, 0x627c4fde, 0xfa0f64cb, 0xa59cc5af,
- 0xe8956e2b, 0x05ca3577, 0xf6ac559f, 0x742b7e11, 0xcc5b797b, 0x6b82ba7c,
- 0x74ce2b8f, 0x211fa396, 0xa1467547, 0xe5909e9d, 0x75bb4728, 0x2b2bba6b,
- 0x53c5da13, 0xd6118f24, 0xc97b8ecd, 0x45ea4c6e, 0xbe0b971f, 0xf9f1b22d,
- 0x3cc37c14, 0xbf0b3303, 0x847e3cfd, 0x4f35412b, 0xf3c0f5fe, 0x798f5b6b,
- 0x3ccf5d46, 0xbaf52cba, 0x89e83f14, 0x385dc76c, 0x2e1ed69f, 0x063da9f9,
- 0x35ec50f3, 0xeae1fdf1, 0x987c8c96, 0xbb73c97f, 0xefd0aa33, 0x1d40fe12,
- 0x3c7cc3da, 0xc3db82e7, 0xf24fdb8f, 0xdabb707d, 0xbf30638d, 0x3db06d0f,
- 0xce05e9ac, 0xd89d4c8a, 0xd791b047, 0xab3b9ec5, 0xd12e7a47, 0x0c799cb5,
- 0x52adfbed, 0x1127dfe8, 0xe5ea9dcf, 0x66e68e77, 0x90d43d72, 0xeb8398e3,
- 0x3464c92c, 0xe84d64be, 0x9b7f9a73, 0x8572edc9, 0x86f37bb0, 0x806c9945,
- 0xaee3c2e7, 0xaabfb835, 0x1e564b6a, 0xa56785e6, 0xfcc92f17, 0x376abcda,
- 0xf1b6abcf, 0xd5856abc, 0x37941cbf, 0xedb33a7b, 0x633a5361, 0x914dffe3,
- 0x78591033, 0xe94c2cb6, 0x74b939bf, 0x617bcf14, 0x4713dd7f, 0x39b9461e,
- 0xfe60f084, 0x08e0f87c, 0x591d0bd4, 0xe80b3a91, 0x7369598b, 0xacfe469e,
- 0xda03fe1c, 0x1614532f, 0xcf0e7fd5, 0xcc5f13cf, 0x42ae734a, 0xe63c7138,
- 0x5f465c43, 0x0eb05dc2, 0xed32abd7, 0x890d7553, 0x4efc8574, 0xe9e1e059,
- 0xebe10b4c, 0xfd199010, 0xe50e0514, 0x2fe7e0fd, 0x9d7cc3f7, 0xe28653ab,
- 0xb4be4e77, 0x85996da2, 0xd2fbf781, 0xbf048f5c, 0xfac753bf, 0x4df1a863,
- 0xc05878e1, 0x06e90db1, 0xcc9473ad, 0xdef1411c, 0x5548d2d4, 0x3884da7f,
- 0xd7ce08e6, 0xf5554b4e, 0xaafa2bcb, 0x7f3ddfc6, 0xc4feea90, 0x7d417f30,
- 0xbbdbbf90, 0xe7e1e49f, 0x4545458f, 0xbfbcbee0, 0x36f67db7, 0xd7745efe,
- 0x7d1db253, 0xb67b45da, 0x03478dbd, 0xb39fc45f, 0x8da43ca0, 0x1d1f66f2,
- 0xd73f1992, 0xae0fa1c2, 0xfe639d0f, 0x1077f147, 0x2907ab7a, 0xcb12eef1,
- 0x801dfa7e, 0x3a0f5d1b, 0x41ea2998, 0xed0f2c79, 0xb7fac5e1, 0x67576f28,
- 0xb73bebe6, 0x8b4f9f9b, 0x057f53e7, 0x3e077efc, 0x65e1fe88, 0x4bb5e50f,
- 0xfd534f5a, 0xeb932aac, 0xa5b4bae9, 0xdd8bf47a, 0x181da2d0, 0x062afa03,
- 0xcedfc5f8, 0x7dc2ef06, 0xdc51596c, 0x953cbf5f, 0x2be438b1, 0x9439e79e,
- 0x53bf4b18, 0x8ca9a4bc, 0x8e5dd7ae, 0x975ff9a0, 0xcd4fb4fd, 0x754492f3,
- 0x95a98988, 0xc6bf71ab, 0xee4f08a1, 0xc4ef7832, 0x8651dddf, 0xc5dbab78,
- 0x944c91f7, 0x0a5828df, 0x19734d6d, 0x66513f3d, 0x17f02487, 0xfb7097c6,
- 0xbe6d113b, 0x46e0f715, 0x2bbb47ad, 0x7ffd7d1b, 0x18c67a85, 0xe6267a45,
- 0x7ef4ddf2, 0x3d1365f7, 0x88f425df, 0x35c383a1, 0xae93b2fa, 0x59f0fc2b,
- 0x77eab666, 0x4f090c7f, 0x91f7f1e9, 0xc68c1d0d, 0x903cbb8f, 0xafbd655a,
- 0xfa77f80e, 0xc2435b5d, 0xfa5fb4a7, 0x42c978d5, 0x0f46886e, 0x1e1faa5f,
- 0xa9e842c3, 0xf111efab, 0x5fea1848, 0x72ccbf68, 0x3012da44, 0x63d0e99e,
- 0x4d99885d, 0xffe44fb4, 0x0538cd00, 0x00800076, 0x00000000, 0x00088b1f,
- 0x00000000, 0x7dc5ff00, 0xd554780b, 0x399ef0b5, 0x66491e67, 0x99212726,
- 0x4ce21024, 0xe010245e, 0x0f080424, 0x860240cb, 0x084013a7, 0xbc80e834,
- 0x2b101025, 0x0337e95e, 0x60d22049, 0x45405283, 0x68b0503b, 0xaaf8ff6d,
- 0x0131f5a9, 0xe94a0fe4, 0x7ab7bd60, 0x52036b6f, 0xe08d4504, 0xb16dcfed,
- 0xbdad6bfe, 0x3267324f, 0xfdeded41, 0xbe3ef9ff, 0x3ef6759d, 0x7af6b1fb,
- 0xb30fb5ef, 0xcb5d8aca, 0x0afb188b, 0x9318137f, 0xbb302e8e, 0xda663286,
- 0xb1ecc67d, 0xb2816631, 0x96bea23c, 0x046b4f31, 0x2e4995ac, 0x19236323,
- 0x3950b6fc, 0xfbc1db0b, 0x631f77cc, 0x576ec64e, 0x4a6dff18, 0xb1832c65,
- 0xed04dfbf, 0x0fde7b53, 0x852ea01b, 0x968bc0b1, 0xbbf861e0, 0xc72fb65f,
- 0x89e1f505, 0xec39faac, 0x55670e47, 0xcddfa1d9, 0xda15b29d, 0x39559b31,
- 0x9ff806ec, 0x6f82ff34, 0x8ba77f39, 0x12b7ffcf, 0xfdfd84db, 0xb084c276,
- 0x7ed5e607, 0x921188ff, 0x31dfa7ab, 0x63b5332e, 0x5675d74a, 0xd7bad8ca,
- 0x603b5c12, 0xc1fb337d, 0x5ebb8033, 0xba0f04b5, 0xa43339e9, 0x68396960,
- 0x8e75fa80, 0x8c2f7cae, 0x5c7afe5f, 0x7e830d88, 0x19938f5f, 0xae52f38c,
- 0xa5e20c6f, 0x1541f5fc, 0xf24c0706, 0xa0cc8b15, 0x3c9ba4dd, 0x5f79f163,
- 0xaf5e8df3, 0xf9c60256, 0x18a7cefc, 0xadbbbdf1, 0x5529b5fc, 0x22624086,
- 0xc954d774, 0x16c608d8, 0x9b0d9b5f, 0x6b92d8c2, 0x5afb04f1, 0x75abf3f8,
- 0xdf705369, 0x49866eae, 0x6c963ac3, 0x017d0c36, 0x765cc5d6, 0x30f00f35,
- 0xada2c073, 0x5339e60c, 0x677ad232, 0xd60a490e, 0x71dbd343, 0x73e0c7bf,
- 0x664861d6, 0x3db97a6c, 0xd6f18460, 0xdfa8535c, 0x1a2e6bda, 0x64b5ed6f,
- 0xb35dd782, 0xdae4b952, 0xb96e7a60, 0x801e6466, 0x1c035e97, 0xdb273c00,
- 0x3fd70ab7, 0x4a96feb3, 0x35b7cf1c, 0x8b67d4a3, 0x82b317a4, 0x92f40574,
- 0xb3d6dcbe, 0x05f6fafe, 0x2fe85530, 0xb2f44bc5, 0x88f2ca14, 0x0e8265fa,
- 0x56b6f1a2, 0xa537ffec, 0x5f411a97, 0x3ca16c4b, 0x54c1e023, 0x856ea717,
- 0x71495cf9, 0x6cbc414d, 0x6fe38078, 0x6e5bc983, 0x786ef987, 0xcec2a0c4,
- 0xd9473bb0, 0x32f00cad, 0xb33addea, 0x176e822f, 0x5cc61b5c, 0xd739feb0,
- 0x7dbca972, 0xae336fa0, 0x79b5f17f, 0xa8c34f02, 0x2364d664, 0x46d8c51b,
- 0x4e1757dc, 0xb3ef9928, 0x7517df98, 0x85eed3a3, 0x6538bff1, 0xb88bfaa2,
- 0x5530252f, 0x9c09e04f, 0x51682997, 0x2ebcc00f, 0x8140589a, 0x9f73b8ad,
- 0xdf000591, 0x41f4a14b, 0xb07b5d09, 0x291de59d, 0x92ed8ed8, 0x04a92798,
- 0x2deb09f1, 0x057c63e0, 0xc2192eff, 0xfd42f7f9, 0x965b3327, 0x81e0731b,
- 0x86552a74, 0x9cf27e75, 0xbe7824c4, 0x4e1bfd6a, 0x95ab1e58, 0x5029640e,
- 0xcc10d1bf, 0x3d8c4937, 0xe2f6fb22, 0xd85a3eba, 0xd0656ffa, 0xf3cb7cee,
- 0x0d57dc0e, 0x2872adaf, 0x0569fb0f, 0xee60067c, 0x6552cdad, 0x26c346d0,
- 0xa1ed0d54, 0xa39e8d6f, 0xb5f57ce9, 0xaba7a26c, 0x2fa19675, 0xdd031d20,
- 0x415af3e2, 0xfd2177ef, 0xacea6943, 0xe9c8f414, 0x5aeba35f, 0x5aadcb99,
- 0x0030625b, 0xbff99bf3, 0xf500fe80, 0xf2a85f6b, 0x2bba444e, 0x5079a830,
- 0x32fc11ac, 0xe0f83a53, 0xcf83e458, 0x787ad452, 0x579af93e, 0xc1f3d73c,
- 0xc674fe4b, 0xbc4b19f2, 0xd5c690b6, 0xe822dfe8, 0xdff484dd, 0x2d83de8f,
- 0xd9fffe05, 0x77ff9edf, 0xdb90f3f8, 0x6be216f7, 0x7fca1c9a, 0x3b4b052c,
- 0x94e4d1d1, 0xe7e9192a, 0xb3cfcb9b, 0xd59e7e42, 0x7db5cfc9, 0xb7f0cfc8,
- 0x04d787e4, 0xd85a543f, 0x2e22de1d, 0x7bdb67df, 0x3d97ebfa, 0xea0b9ce9,
- 0x7819743f, 0xf343ff7f, 0xca5bf0fe, 0x86fd7ffd, 0x42afff72, 0x79cb47ee,
- 0x9ca1fd06, 0xc2d5ecff, 0xf781ea20, 0xd405e819, 0xb824af7b, 0x403d0b0e,
- 0x313e227a, 0xd03d2378, 0x5fe77b90, 0x7f03d0fb, 0xa3fdbc43, 0x3fa3407a,
- 0xfe345f8d, 0x9a21f8d0, 0x987e347f, 0xf13503fe, 0x401fdc5e, 0x1fe461cc,
- 0xae0cf039, 0x5095d6a3, 0xf1a97c8c, 0x0c17dad1, 0xf4bd67c4, 0x1e9be083,
- 0x0bebd13e, 0x3e341f8d, 0x56a6f8d1, 0x28b2c3f0, 0xb526387e, 0xde163c3e,
- 0x15f6eedb, 0xf87b53b9, 0xd173cd63, 0x7a4fa17a, 0xcb4f4862, 0xd218ea52,
- 0x91942d53, 0x83e964f4, 0xdfdd8a9e, 0x126e9e8e, 0x9e8ebfed, 0x6a66dc2a,
- 0x4f483ff7, 0x3191ee15, 0xfbb269e9, 0x5c57689f, 0xa97dfbad, 0xb573e60b,
- 0xbbace414, 0xbfa6de87, 0x90ddb8c5, 0x7e915763, 0x3af9e23a, 0x8303cc3b,
- 0x2beed8f5, 0xd4788756, 0x67db52e8, 0x86580ecd, 0xb6e50074, 0x9c2aef6c,
- 0xa07c476f, 0x9337fd68, 0x96cfb477, 0x53d9b094, 0xd61dfb84, 0xecbeffe9,
- 0x72dfb5c5, 0xdfdc6b9f, 0xddf86e4c, 0xd17b74ff, 0x272d8eef, 0x7d9dff02,
- 0x7f0e599d, 0x94f047f6, 0xf61e33d7, 0x660287e7, 0xcbf22f61, 0xfead32bc,
- 0x191e2d37, 0x3dfc03e5, 0x30f04696, 0xc381e12b, 0x0ae1d381, 0x87f4e798,
- 0x5803ebbb, 0xa27c793f, 0x0c798fe8, 0x8ffda7ac, 0x6e15bc0f, 0xc2defd26,
- 0x94ebeff1, 0xe02343bd, 0x11ed8052, 0xbc145970, 0xc877b79f, 0x7ea14c9d,
- 0xa0af9c82, 0xc209437f, 0x7e827f5a, 0x55f8e799, 0xc52cf3c0, 0x3ec076c0,
- 0xf0394bad, 0x6b9455c6, 0x7066066d, 0xfd81e045, 0x04c9ebde, 0x20c578ba,
- 0x7b08ffe0, 0xf85b1972, 0xb84f8702, 0xc812d4ff, 0xbe02fd15, 0x9b7408d7,
- 0x091e0d5a, 0x66535bfa, 0x7bbb6608, 0x5b84fbe3, 0x7cdaabd3, 0xdfea5540,
- 0x6f94e667, 0x6d1a3ef7, 0xbd367ef4, 0x8b7cb21f, 0x678fe7f1, 0x7b0c609e,
- 0x1f820ff8, 0x63134a2a, 0x4b779fd6, 0x01d7ff1c, 0x4787c6d6, 0xc1fd6073,
- 0x5975fc18, 0x1a3617f4, 0xd6ff3e05, 0x36167482, 0x6bfef86b, 0x327be20b,
- 0x8274dd63, 0x13e30374, 0x7fdc7ffc, 0x7cc936f5, 0x7c289eb9, 0x6fbd68dd,
- 0x2057c0c6, 0x372cbf6a, 0x6ee9f7c0, 0xbef3d0b9, 0xe87eff4b, 0x4ef5fb46,
- 0xdd05f1af, 0xd8e8d4ae, 0x44f7a3a3, 0x99f44bd9, 0x02506298, 0xbd6b8f40,
- 0x2fe8cd71, 0xa9a7f0f4, 0x8e14f10a, 0x87a9e3d3, 0x1555ccff, 0x448fb236,
- 0xe42eeb7b, 0xbbb1af5f, 0x6ec7e73d, 0x029e66ba, 0xd29a2bc0, 0x41d27ef8,
- 0x8d80aecb, 0x09ea82e8, 0x77988dce, 0x46b63f34, 0xf8a3e3c1, 0xc91ff057,
- 0x8007d40f, 0x6f943ca7, 0xaecd6729, 0xb3513a08, 0x313e9e39, 0xa7946ab0,
- 0x8edc49e1, 0xd2f3670c, 0xfaa06d9b, 0x1fbe6cb2, 0xe386511e, 0xa7a0f023,
- 0x2bfa109f, 0x3c26eb11, 0xd6d1482d, 0x0335505d, 0xe64e15d6, 0x73b2d3f5,
- 0x7b320577, 0x66fee8e0, 0x05541764, 0xcffb228a, 0x5d78833f, 0xcde6f020,
- 0xeb06741e, 0x4b507935, 0x11f44284, 0x8b507940, 0x4de861f4, 0xbdd9e91f,
- 0xf51033e8, 0x8374c7be, 0xbf7ab3f7, 0x9f7a89ef, 0xcdbe5299, 0x66df62fb,
- 0x656bed44, 0x4456bed4, 0x1c1a35c1, 0x4d5fc9d4, 0xdb692f2e, 0x7984e8d5,
- 0xe40475dc, 0xe7a48b2c, 0x77cf4451, 0x8efd1a29, 0xbb7a833e, 0x08cb9e87,
- 0xf62add9e, 0x1766302d, 0x942a9fea, 0xe07b63c3, 0x08872839, 0x19e55b1e,
- 0xc6afa91e, 0x3db942ed, 0x3f6b49bf, 0x6c2fda9e, 0x99bbfad0, 0x647db5ea,
- 0xd154ef81, 0xc3b90abe, 0x60ce1302, 0xf857eafd, 0x3d07f5fb, 0x0fc86e67,
- 0xd978512d, 0xa207051f, 0x1afeefda, 0xf510d6fd, 0xfaa8e6fe, 0x5f7828e6,
- 0x7fa4dc14, 0x0352f17f, 0xa062e1f1, 0x6888dc07, 0x8fa68cbe, 0xedbbb387,
- 0x6e7d6e9c, 0xa77d91b0, 0xf5e9abe3, 0xe0fc7e1c, 0xa2a6aacc, 0xd6fb3808,
- 0xdff700aa, 0x2697480d, 0x73207fc6, 0x83d01203, 0xf9b90fa9, 0xb2e8be83,
- 0xf3df5a20, 0x9fe13ffa, 0x332f6819, 0x4c725d9d, 0x92edc3d2, 0x6745ef36,
- 0x43e11636, 0x42a9ae0d, 0x5efa7a7f, 0x9fc0bafd, 0xaac2f015, 0xbb08cc8a,
- 0xcaa0b028, 0xad4eb113, 0xbf2f94fd, 0xe7bc7092, 0x1d5417b3, 0x499afa82,
- 0x983abca1, 0x2f324d67, 0xa84a5f41, 0xf889d7af, 0x255794cd, 0x9acbea2f,
- 0x86de50f8, 0xb27588a2, 0x675c7cd6, 0xed12fdfb, 0xf61ea04f, 0x98b4f007,
- 0x8f0a2381, 0x331e64ee, 0xc4fa81cb, 0xc24f4dc4, 0x97eec77b, 0x7e9ea136,
- 0x273f537f, 0x39c943fa, 0x963ceedc, 0x19739378, 0x7709edc0, 0xdf6dbc90,
- 0xa3ca993e, 0x975b6792, 0xd9dbd8c2, 0x856caaab, 0x78489f58, 0x69707d3a,
- 0xefa016d5, 0x7a2ed933, 0x38ac97df, 0xdeded0db, 0x5d876261, 0xe2952f38,
- 0x5a778b48, 0x7ce0778a, 0xa2710cb6, 0x47e4b9fd, 0xa0325355, 0x934692dd,
- 0xa754768a, 0xf9c2c951, 0x364c76f9, 0x06d2fd63, 0xa16e0651, 0xffbff5f2,
- 0xed01dea4, 0xa8371ebb, 0xcdfda107, 0x35beb45f, 0x4d15e00c, 0xd16e2a39,
- 0x2807e06b, 0x7db9ce30, 0xd0128283, 0x757107e5, 0xf6f16627, 0xb8afdb0c,
- 0xab3d3aee, 0xca4bdb14, 0x017f6856, 0x7cfda39e, 0xa0e901e1, 0xb0e5e701,
- 0x49601bc7, 0x1464be17, 0x68d0b9cf, 0xee7c6209, 0xfb77cd9c, 0x9f671c3e,
- 0x767d2d09, 0x1872e0c1, 0x1d9f0f00, 0x3d2ab7bc, 0xc45b9f03, 0xb49bdefe,
- 0xd8b0f018, 0xa43f4dd8, 0x7127964f, 0x7becb3f8, 0x3ac30eab, 0x88323c2e,
- 0x722b57e2, 0x80d95d3c, 0xcf5cc2af, 0x107e58e7, 0xebd6f5c7, 0x40ee977f,
- 0x97d7fe3b, 0xbe913897, 0xd6f426fe, 0x3896d76b, 0x55d84497, 0x89913fcb,
- 0xbb375e0e, 0x5f7ce236, 0x40681f8f, 0xa0e81b3f, 0x97c9c61f, 0xe805bf0a,
- 0x31f3d379, 0xcd7fabec, 0xdabf6896, 0xde3a907f, 0x6deba3a5, 0xdfc8a7a4,
- 0x93f6d800, 0xa002bbad, 0x365bcfdb, 0x8e500fb1, 0x7147ee6d, 0xc84ca5db,
- 0x82e26781, 0xf4b157e8, 0xf8c8fcd6, 0x8a1f374d, 0xd80c7ff6, 0x847faf09,
- 0xfdf7e8f6, 0x761ff031, 0x7eddeb66, 0x401ec385, 0xbb43e2e3, 0x78fdc65d,
- 0xb85ff65f, 0xfe5bde0f, 0xc0f489b8, 0x3753c7f2, 0x40b8e177, 0x8b571837,
- 0x1c82d75e, 0xf4638f13, 0x878197c5, 0xfe742aab, 0xbf24c3ca, 0xfccbe2fb,
- 0x75543c9f, 0x5f37d6c8, 0x7cb850ae, 0xc9b8f29a, 0x62b4fc8b, 0xa0665da4,
- 0xfe3d264f, 0xcfc461c6, 0x2571f58a, 0x8af89816, 0x5fb42dc7, 0x407b769d,
- 0xc39f7a81, 0x5941272e, 0xd6e5c39a, 0xed171cbc, 0x64c4b973, 0x0d95096b,
- 0x82bd6f18, 0x2f800de1, 0xcf787a6d, 0x23e71868, 0x1a379c16, 0xc3c577f0,
- 0x0bcaf4e9, 0x991dc512, 0x826791ec, 0xb8c95cbc, 0xf93da89c, 0xfc2279bc,
- 0xc56eb2b9, 0x5707f40c, 0x3ae74d05, 0xf18e0f85, 0xf9ac75d8, 0xea186973,
- 0xa273fd57, 0xf3d62704, 0x49d61adf, 0x35b6a372, 0xdaebfbf6, 0xe467cff4,
- 0x0c2e53d8, 0x2e431861, 0x2bb10c01, 0x067ca675, 0x03615c4b, 0x96f582fe,
- 0xbcd037ef, 0x82926c57, 0x79779816, 0x3e2f1e3f, 0x37fd87ef, 0x0a03bad3,
- 0x73762bc0, 0x1982b3bd, 0xf3f85682, 0x29ebfd96, 0xc84c797e, 0xe606c599,
- 0x20fefa45, 0x3f42cd4e, 0x71e3f97f, 0x4f15df84, 0x47b7faac, 0x2dcebde0,
- 0xfd225333, 0x174825ea, 0x9accbf1c, 0x87cfd3dc, 0x859fbe5b, 0x63fe5ff4,
- 0x3d618ff0, 0x2fd8922b, 0xbf71b816, 0xb65cb232, 0xb62b769e, 0xdbcf9fde,
- 0x7e0d7f81, 0x2407e2f4, 0xd17b075a, 0x78107a42, 0xdbc4895d, 0x669386d2,
- 0x5bff1173, 0xdafb0a71, 0x39bc7285, 0xe7fbc12c, 0x11b25ea0, 0x119d02fe,
- 0xb03bf271, 0x23920caf, 0x8d5f5c3e, 0x6cc770d1, 0x8ccba7ea, 0x8733bd7c,
- 0x441b43c7, 0xbd4b38b9, 0x0fcfe29d, 0x6eadd45a, 0x4a348fde, 0xbbfc03cc,
- 0x3978635a, 0x2fd981c6, 0x5957142d, 0x89e710d7, 0xe23f9073, 0x5dfa0e79,
- 0x9cd93327, 0xfa72fd8c, 0x72e2e35b, 0x2bbf9e03, 0x3b5af3c3, 0x49b58b97,
- 0x97ae6f80, 0xffe8463d, 0x872bfc33, 0xac3197f7, 0xf1eefde7, 0x85f53d0d,
- 0xfd5f10c3, 0x3ce355e6, 0xdf112e7e, 0x2c1e3202, 0xe7eefb43, 0xabf408d2,
- 0x6c703f17, 0xbbd9ca0a, 0xf0562d9e, 0xf8bfc5d5, 0xbb89e91d, 0xa2773ec4,
- 0x037a8f9d, 0x7ca167e0, 0x45cb8732, 0x42e3c49f, 0x687c0a4f, 0xd7d5adfb,
- 0xf1e2603e, 0x28e79079, 0xfcb76a40, 0xb5adfa9e, 0x67289d87, 0x8d345f6b,
- 0x94fc7942, 0x2d92ff98, 0x0bbfc703, 0x94c4b3f4, 0x5a5ea0a8, 0x46699813,
- 0x818b4d78, 0x52f79ee0, 0x3f1e90b3, 0x81c9786e, 0x5c41f274, 0x4ff50f28,
- 0xf538fad7, 0xe1402e20, 0x1b8fb971, 0xfc620ef2, 0xb612a966, 0xe97ea01b,
- 0x94649cc6, 0x212befd3, 0xdfbfd633, 0xec2236ea, 0x08f19451, 0x04e1e47b,
- 0xab220c7f, 0xca0fd055, 0xbe06b599, 0x399e6b9f, 0xf186ce66, 0xfdc3937e,
- 0xfe7e4f9b, 0xf38c7cbb, 0xf38566d4, 0x7ec07f51, 0x3c400fe7, 0xfd206d3f,
- 0xc919f6bb, 0x67ac3713, 0x7ee2d7bf, 0x16ad7f03, 0x85f6bcfb, 0xba45ee97,
- 0x5dfb8b5f, 0x805e9bd2, 0xf3d38f6e, 0x614c0ee7, 0x48e3fdfc, 0x02be9a17,
- 0x8c94c1b8, 0x9f0e3a71, 0x02fce1ce, 0xf3f82bcf, 0x4bc91140, 0x67682390,
- 0x5f7bd346, 0xd8b1fbfb, 0x2c5b25bf, 0x163f5724, 0xc0f9dbfb, 0xbfdc0e8b,
- 0xec7e7e4f, 0xd4a39e04, 0xd8da073e, 0x05ee8315, 0xfae1d63e, 0xb27f341d,
- 0x7ae1d623, 0xefeb3d1d, 0x6fc173a6, 0x9f5f18eb, 0xb275deb6, 0x2f56bf58,
- 0xd62cbfde, 0x7c0986b9, 0xf38830bd, 0xe427e097, 0xb4c7b457, 0xf992f9f5,
- 0x267d1afb, 0xffb972e7, 0x99ff2137, 0xfc40ead2, 0x9ca2fee0, 0x98f1fa01,
- 0x01b90947, 0x16793e4d, 0x5fb11fe6, 0x73b3fcda, 0xae403cf9, 0x7b929279,
- 0xc8d3b1f6, 0xb73ac656, 0x78e5c84c, 0x9698db3c, 0xfbf806d5, 0x892bfc18,
- 0x23957a71, 0x46e8d3c6, 0x67fcaf1b, 0xdd70d355, 0xfb087fd0, 0x3f7dc6d7,
- 0x3f632090, 0x1fce33ef, 0xbe35fcda, 0x345faf2c, 0xed81d8ad, 0x14e7b13e,
- 0xdd39bae1, 0x542ae766, 0x802ed07a, 0x066d3df7, 0x159f4f8a, 0xc6d9fcfe,
- 0x8a4b1c97, 0x25dde87a, 0xd93f8de6, 0x1a9e7bd9, 0x33d045fd, 0xfb7cb3cd,
- 0x6b0869fc, 0x4ba68df3, 0x7d1a6f0d, 0x64a9cdb2, 0xe9d344af, 0x66b3ccba,
- 0xb9fa2f1c, 0x807cb766, 0xffe415f1, 0xf2e3c654, 0x6e78ec0d, 0x9f863e84,
- 0xd1ea8d8d, 0xd79c9a0f, 0x14baf3f4, 0x2fc225cf, 0x43703a0b, 0x5366e736,
- 0xc72977bf, 0xfde039b7, 0x74c3e731, 0x87d9abfe, 0x92117f37, 0xf48e3112,
- 0x5224bb82, 0x7cb9adcf, 0x96b6e89c, 0xbfa1b785, 0xdf81f8b3, 0xf48d1ccd,
- 0xce8994f9, 0x4e37165b, 0xbddda336, 0xa39df0ea, 0x35cfdf70, 0xa9763d71,
- 0x6893e461, 0x7a6b9f37, 0x116779d8, 0x653e57be, 0xbc5f3c2c, 0xf5f698ab,
- 0x4cf0b883, 0x91eebb84, 0x6f7841d8, 0x9b91e1dc, 0xce3c0217, 0xae12537e,
- 0x5243fdef, 0x3a08d8c5, 0xcd94ca58, 0x934ed10b, 0x8be41513, 0xab3c85f7,
- 0x5a7df137, 0x517fe82e, 0x45f3e72e, 0xebcb7f62, 0x7cf1f3eb, 0xc800ebbc,
- 0x8d63c051, 0xc21ad5d9, 0x234d5f71, 0xd81d7fbb, 0x74c9e908, 0xd2764d4e,
- 0x66b3334a, 0x6b73d094, 0x693f3c06, 0xeb83df0a, 0xbd8f7939, 0x58e20b78,
- 0x096a3eba, 0x5f896fb7, 0xf1a5aec0, 0x3168edbb, 0x2e82658f, 0xded3fba3,
- 0x1ebb40ef, 0xff989ee5, 0xe6a786a5, 0x74babea1, 0xd7192f24, 0x71abe1ff,
- 0x7cdf684d, 0x4c72e268, 0xaeec1feb, 0x11f691f3, 0x183a5bd8, 0x0c1d2aec,
- 0x6f5e75f4, 0xbc256d8f, 0xb7ab9bdc, 0xad3a34ab, 0x18979f59, 0xcbd01799,
- 0x0a43fefe, 0x9cf7ff9d, 0x644e8cbf, 0x7742e431, 0x880fd5dc, 0x3c6c67ca,
- 0xcf18fada, 0xf9f2f84d, 0x2ddfda30, 0xeb02c516, 0x8e748f3c, 0x4a2f4be7,
- 0x72b7eedc, 0xe2ff3fba, 0x77fa2088, 0xe1c0ffcb, 0x2086ade5, 0xdf1edd1e,
- 0xf6c25db5, 0x4beec0cb, 0xb3d84433, 0x03cd77bb, 0x545767f2, 0x680cb6df,
- 0xcf08e57f, 0x5b6a8077, 0x227b1d94, 0x1db7d5c3, 0x5fb6cffb, 0x61c0b8b5,
- 0x532adf0d, 0x9e1adf11, 0x75e67f35, 0x92b287a0, 0xea7dbc1e, 0xebf6495f,
- 0xca8fbf65, 0x1f670ccf, 0x6c74871c, 0x5f91544f, 0xb0f6dd7e, 0xfbf70034,
- 0xe8ebe285, 0x25b58e97, 0x9fb7c82a, 0xb9d137fa, 0x1d7f65e6, 0x6b7eda95,
- 0x5f9bb171, 0x3ef7a768, 0xcaf11b6d, 0x35ef7838, 0xd790a25b, 0x35f731c9,
- 0xeee3bf3a, 0xf0d3a3f5, 0x8faeb6b9, 0xabfbe3ee, 0x23a3fbcd, 0x5d703a77,
- 0x7bf58fed, 0x6bee0c65, 0xf682a242, 0xdf910ad9, 0x971f6171, 0x89ad170f,
- 0xfd80ce4f, 0x8e7fb8bd, 0x5c9c8193, 0x1e773ed6, 0xaafe5f3e, 0x5cfb4141,
- 0x81cab57d, 0xcb3f8df1, 0x4b050e9d, 0xf3842f78, 0xca128391, 0x6c95b1a3,
- 0x1b1fb60e, 0xfa0b9992, 0xd3833319, 0x72cb98c9, 0x3e780f10, 0xb714e786,
- 0x714f1eb8, 0xc3f5f80b, 0xbf658dfc, 0x0d0ef1e2, 0x35df9aef, 0x04dbac4e,
- 0x2e7447ec, 0xf197979e, 0x7fee1fe7, 0x77f6167e, 0xc14990e9, 0xc87a7f79,
- 0x06affd44, 0xe308c97f, 0xfdc23c5d, 0xdce38410, 0xdfdcc7c8, 0xfdcadd58,
- 0x26f5da8d, 0x37b1398f, 0xb447963d, 0x9e0ebf43, 0x55dc70b9, 0x3a34de82,
- 0xebe1ed5d, 0x0d7a0d5b, 0xb74d1bd7, 0x1b75ac49, 0xe8ebe9e2, 0xedd29bf7,
- 0x135e90df, 0xe87cb758, 0xe8bed7a6, 0xf913e044, 0xa355e91d, 0xf8fbd587,
- 0x6b727a39, 0x3ba444f1, 0x79343e8d, 0x0ac49812, 0x9bd66f50, 0xdde60159,
- 0x2af18c04, 0x9b2a81ca, 0x7f7284cb, 0x05674a4e, 0x1e4965a2, 0xb952a797,
- 0xfd4463d1, 0x79216f53, 0x526f2d11, 0xdffcb8f2, 0xed074483, 0x2a14f28b,
- 0xfc8eac4d, 0x8584ad07, 0x5cfd440c, 0x9ffc9095, 0x5372682e, 0x65b383de,
- 0xb8d57f98, 0x54727be4, 0xede506c6, 0xe488f0e6, 0x97a82691, 0x5d9a1feb,
- 0x9e457001, 0x445e6067, 0xa70e97bf, 0xc0f5c40d, 0x8c1e5773, 0x97c53dbb,
- 0xb33ae583, 0x67f7e48d, 0x9b61ae86, 0xcfed3ddc, 0xff7f6abc, 0xb81eaed7,
- 0xd4b2c4d3, 0xcd198422, 0xcaef2b5b, 0xe3e60cf3, 0x612f9fe8, 0xe2f291ac,
- 0x5dfbff02, 0xe7e043b4, 0xdefec2b5, 0x8969e82a, 0xfdc216d5, 0xcba64d64,
- 0xa80576dd, 0xca26a67e, 0x04b30748, 0x872adc1d, 0x42fdf1da, 0xb05ca0d6,
- 0xffb3e992, 0x3a377eab, 0x05d995a7, 0x87a03fad, 0x3eb04ccf, 0x900367a0,
- 0x196026d7, 0x06b12003, 0x95e197e4, 0xd85ffdff, 0x75807d6f, 0x6b9e11c6,
- 0x067b9414, 0x057e33e6, 0x63826d65, 0x3c33c618, 0x3643d92f, 0x3f0dc7d8,
- 0x5fba204f, 0x5217ec25, 0xa65f98c6, 0x74b0f5f0, 0x8f7fde7e, 0xfd0fb7a0,
- 0x5817372c, 0xf47613fb, 0xb1e61953, 0x1b37ce2a, 0x78c6bdf1, 0x0b836b2a,
- 0x81deb4f9, 0xbf27c576, 0x09145490, 0xc8dd846b, 0x7e0aa50e, 0xa0134297,
- 0x785dc3be, 0x8d4bf510, 0x6ecb97a0, 0x606f7e46, 0xfaf2858b, 0x5963f5d8,
- 0x995c03f7, 0xfe8a8b7d, 0xb767e5e4, 0x7d832ee7, 0x0ed8c0b2, 0xe854e758,
- 0x6aa60cb3, 0x73a25802, 0x03f520de, 0x3c0701f5, 0x387ee6df, 0xf319d38b,
- 0xfdb47ae2, 0x6bdef0d1, 0xb468603f, 0x66568d2f, 0x90b1ff42, 0xff9057ed,
- 0x8c997db4, 0xfff03dce, 0x9c791786, 0x75818363, 0xf9af18c3, 0x8d780ad0,
- 0x4f6a5f21, 0x267641be, 0x27405bb0, 0x19dff657, 0x1d95ff5b, 0xffd76330,
- 0x98d83d6c, 0x315ff427, 0x037b262b, 0xadfd0697, 0x4b266d10, 0xd7192e35,
- 0x91556a93, 0x9e3c361e, 0x1d867a43, 0xa0f44dd9, 0xfbfb63b5, 0x736c9d11,
- 0x55ff844b, 0xcc4cb06d, 0x4feb69d3, 0xda338b79, 0x5c74a992, 0x97e7a74b,
- 0x94ab7c9e, 0x3fbe1bcb, 0x369a7f33, 0x7e83f289, 0x6d4a883a, 0xbd041b1e,
- 0xe2be7869, 0xc93e7815, 0xbb06d5f5, 0x397dfc99, 0x79489850, 0x0b121d8c,
- 0xe4f73c02, 0x57e2131c, 0x6d74e78a, 0x57323749, 0xc459bc0c, 0xe2b9c47e,
- 0xded22b99, 0x68c2780f, 0xf517cfd7, 0x51c90509, 0xe6df7cf5, 0xb7cfe589,
- 0xf3819cad, 0x75fdabb6, 0x4c776ce3, 0x92ba20e9, 0x5f38cb2e, 0xeb0304cb,
- 0x352be787, 0x3b987dfa, 0xc69b0f57, 0xd5f24e7f, 0xbf7a3e34, 0x4dfd0999,
- 0xfcff478b, 0x17a13cb5, 0xe461590a, 0x9fc2f63e, 0x0d7c4acd, 0x78ef79da,
- 0x9875e780, 0xedc5d058, 0xafc7b435, 0xb7442c78, 0xde04e3db, 0x21e9a50c,
- 0xa6589f68, 0x47925fc7, 0x957eaf8f, 0x7aa4fc7a, 0xab4878f5, 0x67d5d6ce,
- 0xeaeb06f8, 0xd12cac07, 0xc6eb03c1, 0xb4dfdaea, 0x760e9269, 0xdae9a607,
- 0xd6cd34e7, 0x0b2d79c1, 0xed07ed75, 0x2faba25b, 0xd5d6ae0c, 0x41b2390f,
- 0xfd6d0f07, 0xe1fb5d17, 0xf5755b6d, 0xba1da1c5, 0x0f1d11fa, 0xe191e0e9,
- 0x47ed7547, 0x57507bbf, 0x69f3a63f, 0x8bb8fd5d, 0x9be0e9cf, 0xb5d65ebb,
- 0xa8ed709f, 0xdec89e0e, 0xb72fb5d2, 0x4f074efe, 0xd743fe56, 0x0ff496fe,
- 0x5d53f574, 0xa7eaeb1f, 0xc1d55c17, 0x097d9877, 0xea97c8f9, 0xcdef74df,
- 0x8e1fae62, 0x9f9e3a07, 0x00435462, 0xfc85f3db, 0x8c977410, 0xdaed13fa,
- 0x7485965c, 0x1f1a593a, 0x336bba22, 0x4457e8a8, 0x63f927eb, 0x65e307af,
- 0x8a8325ec, 0xb044ac71, 0xf188e4eb, 0x70563c92, 0x7ee07b00, 0x4e0e8a95,
- 0xdaeba6f5, 0x74bb55a7, 0x02be19f5, 0x9580fd5d, 0x581e0eaa, 0x7f6ba657,
- 0x0e8f26d3, 0x752a0776, 0xbc9a73ed, 0xa5af383a, 0xd07ed75a, 0xbeae9f3e,
- 0x5752b830, 0x9d48e43f, 0xbada1e0e, 0x787ed749, 0x5f57405b, 0xd5d26a1c,
- 0xd168e88f, 0xfbc323c1, 0xbf47ed74, 0x8fd5d41b, 0xaba23ce9, 0x55b1771f,
- 0xd5dcdf07, 0xe13f6ba6, 0x4f07485a, 0xed752764, 0x7467adcb, 0x3de564f0,
- 0xd25bfb5d, 0xa7eaeacf, 0xeae92eba, 0x7a647b35, 0xe7fae7c1, 0xa9993ec2,
- 0xfdee97fe, 0x430f24c0, 0x673c08fa, 0xa05deb50, 0xb9b3f2ff, 0x2d13073e,
- 0xc67b424e, 0xc945f94b, 0x7207a098, 0x2060312b, 0x5b9542ba, 0x149ef143,
- 0x52a453d2, 0x0347985c, 0xde81de7a, 0xf68ddb93, 0x9d8f426d, 0x88d5f995,
- 0x7d676e6f, 0x30387d1f, 0x944db65d, 0x0de563aa, 0xc79f3f7e, 0xfbe50e39,
- 0xa2a7e436, 0x14ecf11f, 0xb157b3b4, 0xe79c36c0, 0xb128a964, 0x71a8e313,
- 0x568538fa, 0x645eb54e, 0x77dd8472, 0xb325ae32, 0xfcfe06e4, 0x2665eb54,
- 0x57e8888f, 0xb00c2fc4, 0xfd110dfe, 0x807e083f, 0x8b7f3e0c, 0x6c0af81f,
- 0x0afc87a4, 0xe9fdbbc1, 0xbbf1ef04, 0x2fe7dca8, 0xbf51f2a0, 0xfdfbf54a,
- 0xe13f0465, 0xf41c10f7, 0xd0795257, 0x87e7a5ef, 0x3f04d5fc, 0x96317e09,
- 0xc64fc047, 0x77f069f2, 0xf019feb1, 0x85fe117f, 0xab65403f, 0x3f9e89bf,
- 0xf8216fe7, 0x823eff05, 0x520fe97f, 0x423fe6d9, 0x56fecbe5, 0xdfc57faa,
- 0xfe6bf046, 0x7f21c110, 0xfd47c107, 0xfb8f8261, 0x84f825df, 0x0eca93bf,
- 0xdf2a45ff, 0xfd5177f4, 0x8235ff29, 0x6f53f67b, 0xf3e346ff, 0x65571123,
- 0x215c4ec2, 0x70a587e8, 0x273970fb, 0xd042b605, 0xa81269ad, 0xfa3fb457,
- 0x3cc41fe7, 0x574891d6, 0xa7574405, 0x1efd8dbe, 0x25697fed, 0x9bf719d0,
- 0x3c781bd7, 0x22efd346, 0xefd3405f, 0x7f70f735, 0xbbd81175, 0x43ffff18,
- 0xaf3fb71c, 0xd00a99d4, 0xc431ab8e, 0x5d2f68ab, 0xd933fba9, 0xafcf0c47,
- 0x78ee4581, 0x476072c5, 0x0356df84, 0xfde11bef, 0x18b45999, 0x4c3ac356,
- 0x332a2e74, 0x357c048f, 0x37efa076, 0x0f561fa8, 0x7fc80634, 0xd1f305b6,
- 0xa07dbb6f, 0x7ef48c2f, 0x09d96ea5, 0xd2a28fc2, 0x4b4ce0b9, 0xc63e7528,
- 0x144a4e49, 0x1f0bebdf, 0x785e44eb, 0x5daff59f, 0xbc3b44ca, 0x0f92eff2,
- 0xc9b4e7f7, 0x83718d5e, 0x1fb9f20f, 0x51be41fa, 0xe81e5e57, 0xfcf3873b,
- 0x76eebd8b, 0x2ff0a023, 0xe4ff59df, 0xbf1eeedd, 0x3d7456f9, 0x62ae5ec1,
- 0x29e5132e, 0x6e1bcf32, 0xe636eae8, 0x0b3e7823, 0xa67b7950, 0xd75c63ef,
- 0xd8241602, 0x1592d637, 0xf3d15d6b, 0x03908bfa, 0xea37c97f, 0xbe59feca,
- 0xf2f3e4ff, 0x8f4ebcd0, 0xd71f25b9, 0x616bcda5, 0x3fe68b96, 0x813d758b,
- 0xabcbfbf3, 0xe4305f9f, 0xff8fa6f4, 0x61b0ba01, 0x31da0598, 0xc7a8df3c,
- 0xafa81cc4, 0xf940cfbf, 0xd45d1ad9, 0xdf104060, 0xbca06cdb, 0x013a1efd,
- 0x2bbf40fa, 0xf1ee8ba5, 0x0f249d01, 0x23193a42, 0x4f60cc05, 0xf306369e,
- 0xbc5e740d, 0x84718ccc, 0x1f402915, 0xc1d37dd9, 0x409f715a, 0x95f40e7b,
- 0xfa7dfd89, 0x8805d1ab, 0x8daf75af, 0xeabe2171, 0xe80fb08d, 0xa929be27,
- 0x8b851f3c, 0x50dc697e, 0x5932578a, 0x34ce3155, 0xde5b12d3, 0xe9c41f8e,
- 0xa9ba74e7, 0xe9fd4832, 0x074a55cf, 0x1d2b7df1, 0xc373f7c4, 0x48d70ffa,
- 0x47d3ef30, 0x947dd12f, 0xf4dff35e, 0xc46e6166, 0x9db5d7bc, 0x2189e29d,
- 0xfe8be7bf, 0xcc91ba34, 0x5b01df76, 0xe9babce4, 0xfbae1c78, 0xc740492f,
- 0x17c74439, 0x9670fcf0, 0x1f3895c5, 0x09404eca, 0x1fbee9da, 0x2dffe42b,
- 0x4b952a61, 0x15ca9799, 0xb748edb0, 0x332ec0de, 0x6b357be2, 0xcb6be7a5,
- 0x1d2274ee, 0xc8fa372f, 0x99835e2f, 0xcb9e78b7, 0x01d22aba, 0x6d35b76f,
- 0xd01d2379, 0xd765a737, 0xcecf8c64, 0x037e2e0e, 0x8643aacb, 0x0a87980b,
- 0xe70b317c, 0x6ba869d5, 0x2fe30fec, 0xe362667c, 0x4b3e7800, 0xdec1fbe2,
- 0xc9a1fbe2, 0x0375e88d, 0x941bcc1f, 0xd0f2eb8a, 0xa54724ba, 0xb66a0f8e,
- 0xa5218f32, 0x9bbe1f27, 0xfaeeca2f, 0x5f9400d3, 0x07c51772, 0x4966bdd6,
- 0xcd5e7dc6, 0xf0603db8, 0xcd0ff168, 0xe744600e, 0x1578b177, 0xe8247ddb,
- 0x8c81a3fa, 0x0323fae8, 0x3d258438, 0xf2cb29f6, 0xf4e497a5, 0xc675ebe8,
- 0x9e218667, 0xe2d79f40, 0xd07f577c, 0x8dd8adba, 0x85983f72, 0x69e989f6,
- 0xd6ef5a8b, 0x55f615e9, 0xeb5c4f42, 0x3b8f1341, 0x50cbcf45, 0xd0bfe276,
- 0x5998b11e, 0x8039cf00, 0xe428d9af, 0xe266fee7, 0x2d447aab, 0x7926c7c6,
- 0x557cfc5d, 0x3169ffdf, 0xb92f8edf, 0xf5801c3f, 0xf7a49c60, 0x594f5c38,
- 0x21c67be2, 0x3464e1b9, 0x9c41cece, 0x98f1b57f, 0xed1333ad, 0x7de3fbf7,
- 0xd5fdc03f, 0x3f9a3de2, 0x30fee1d9, 0x8d99ee97, 0xf74354bd, 0xe858c637,
- 0x22addf7e, 0x196b760e, 0xaadd838f, 0x47c6bdc5, 0xe2a2bdc5, 0xec7c6c2f,
- 0x97269838, 0xefc95319, 0xd07f642d, 0x17f14fd6, 0xd2f60e4d, 0x3090b0ab,
- 0x145da5c5, 0xcb8ee8af, 0x1e799b14, 0xad306b8d, 0xe4e42cc7, 0x4f972f4e,
- 0xd569fbda, 0xfce8c2e0, 0xd5cb2b08, 0x0e8a11f9, 0xae97581e, 0x26d37f6b,
- 0x1ddeae97, 0xe7d5d028, 0x383aa934, 0xd74ca5af, 0x8f3ed07e, 0x560c2e0e,
- 0x390fdaea, 0x43c1d5e2, 0xed75ab5b, 0x74f9b787, 0x95a1c5f5, 0x1d11faba,
- 0x64783a75, 0xfdae9378, 0xba0377e8, 0x4d9d31fa, 0x1771faba, 0xcdf0745b,
- 0xed74fb5d, 0xea0b5c27, 0xa7b227ea, 0xd6e5f574, 0x64f07567, 0xf6ba57e5,
- 0x74fd0b8f, 0xeebb7a4b, 0x49d754f9, 0x0bd37bdd, 0xc7e0e8ce, 0x0f919f71,
- 0x0f899816, 0xe9efaa66, 0x10f267de, 0xe39b938a, 0x1dfdb3f8, 0x3ca3146f,
- 0x170c6fdc, 0x6e3e9f23, 0xf96374ec, 0xb5b5c184, 0xce49d01f, 0xd61489f8,
- 0xbc58abce, 0x3341cb15, 0x5d5318b6, 0x0f731fb0, 0x393d456c, 0xe8dda6a4,
- 0xd2e87804, 0x889d5bb3, 0x290635f7, 0xd1bdf10d, 0x88e58f5d, 0x74a513cd,
- 0xb0d91fa8, 0xe8e51eb8, 0x8b33e6e8, 0x007496d1, 0xfe3187cf, 0x3e887b25,
- 0x69186637, 0xc6471bde, 0xcedcde53, 0x9d1936b1, 0x9c3b9d96, 0xdc0f180d,
- 0x09a4a3b9, 0xbf606dcb, 0x358ccd07, 0xe58efd81, 0x83dfb00e, 0x3c6c8be0,
- 0xe424e7f3, 0x53a6e547, 0xbf2e78e9, 0xaa47d27d, 0x4a15c551, 0xbf438f73,
- 0x22f1a9cd, 0x3b9a515f, 0x4efb7411, 0xdf8049e4, 0x1730923f, 0xe1a370f3,
- 0xad788717, 0x72f7c805, 0xbaed1b8b, 0xac06fd5e, 0xfe017efa, 0x927afd66,
- 0x1e785fb1, 0xad216f33, 0xf7e1eb80, 0xde5a8c0b, 0x715be53a, 0xb04a1c53,
- 0x9e41123f, 0xf0e98f35, 0xcabc00ad, 0xee819d4a, 0x26fb8b09, 0xf8a6aa18,
- 0x26aff5ee, 0x2e9c03c4, 0xe451dbde, 0xfe802bcb, 0x9ca0606c, 0xf497a08b,
- 0xd04700a5, 0xefc05ec7, 0xf99edcb9, 0x0630ee98, 0xa60b9064, 0x1555789f,
- 0x516c79c6, 0x7b97393c, 0x223b7acd, 0xdc8de44f, 0xf7146057, 0x68a8e65f,
- 0xc057dcff, 0xfe23dcf5, 0xe7cff38b, 0xf35dff62, 0x329e03cf, 0x0f988696,
- 0xf54d99e4, 0x611a98aa, 0xb17567aa, 0xf19bc8fc, 0x6fbc0612, 0xee92763a,
- 0x702aafaf, 0xd4325e11, 0xff775a16, 0x646fd0a5, 0x33ae4d9c, 0xda403e60,
- 0xce033ae6, 0xaaf14d2f, 0xacc78e78, 0xbcfddd4e, 0x997f4db4, 0xa7e41e7f,
- 0xb155efc9, 0x46ba699d, 0x222b218f, 0x925aaafb, 0x47cc62c8, 0xfc9d6d2b,
- 0x7aafa8fc, 0x759bc947, 0x625a3794, 0xd111e173, 0xeab6c5e3, 0x7bf63103,
- 0x66efd895, 0x9b7c7e87, 0xe4203e76, 0x718555f4, 0xf7f8213d, 0x6b0e24ee,
- 0x5c5ddcfd, 0xf9c37692, 0xce7463ee, 0x30cdc1a9, 0xf9a9e20e, 0xd715bb7a,
- 0x0b798cdf, 0xe9182fa4, 0x547e2789, 0xa1876070, 0xa2f63ef7, 0xc4fca047,
- 0xce8fa412, 0x83f03d60, 0xa2acd8bd, 0xdefb645d, 0xdeea0372, 0x89475674,
- 0x1591b637, 0x1bb0f21d, 0x4f5aafcc, 0x3d3e6987, 0x97d9329d, 0x62faf941,
- 0x1c3d351f, 0xafa66fbd, 0xc872d272, 0xd979e2ee, 0x67fe4e1b, 0xef022f9c,
- 0x557c123f, 0xe4245ac6, 0x95acb193, 0x4c2cf1ca, 0x175877e5, 0xc8a61e95,
- 0x2a624e58, 0x4bcc1595, 0x475614e5, 0xa16b2565, 0xa56b1a72, 0x530b0672,
- 0x950afe09, 0x5f90a65e, 0x36f41b35, 0x97997396, 0x8eac79ca, 0x1d229fca,
- 0x59ab3e03, 0x590bc10b, 0xc06d952b, 0xfaa5787f, 0x586f9065, 0x0df202be,
- 0xe9fcd7cb, 0x2efc8654, 0xbf47cae6, 0xe3ca80bf, 0x13ca957e, 0x3b2a32fe,
- 0xf76a1efc, 0xca92bfa6, 0x952f7e53, 0x54d5fda7, 0x6a3efd86, 0x257fb6f7,
- 0xebf8ef95, 0xff37fca8, 0xf5df2a26, 0x77fca807, 0x7995137f, 0x39764666,
- 0xcf15082b, 0x7e67fc06, 0x60b8f660, 0x3c0aaf1f, 0x5318f31e, 0xff70530b,
- 0x4df18664, 0x2231c55b, 0x48cb9b0a, 0x5c9addf7, 0x289dd947, 0x3b734f07,
- 0x27669ecd, 0x72d6d03b, 0x613e619c, 0x4a53a19b, 0x793cbd80, 0xd6b98ee4,
- 0xaf93d042, 0x150486b0, 0xadbba5e1, 0x309e07a0, 0x027eeb85, 0x960bc7f5,
- 0xce82b5cc, 0xfb7f6b1a, 0x4c39a7e3, 0xb38e63f5, 0xdfe0057a, 0x1bb1591e,
- 0x3ce130af, 0x57bede50, 0xe62e7ab0, 0xf2155feb, 0x00c37c02, 0xb7ad2de5,
- 0xb16f3105, 0x3168e5b8, 0x7531b62a, 0x37d412b6, 0x1e28ed11, 0xe8bb57d0,
- 0xc7bded7a, 0xe2129d6a, 0x64cff9a1, 0x9cccb37e, 0x9dc63150, 0x7e35fb22,
- 0x7499f1b3, 0xdb23f183, 0xdfd06e19, 0x9fcf228e, 0xfffccf50, 0xfa68f3a6,
- 0xec757d36, 0x062efa59, 0x7e438aeb, 0xe5c4983e, 0xa5d8174d, 0x0b34dfe8,
- 0x364b79b8, 0xb507a9d9, 0xcbefb37c, 0x5e307f54, 0xf081d2bd, 0x378a5c96,
- 0xe2792734, 0x637db10b, 0xcc9dc936, 0x63794604, 0x8a13d53b, 0xe3ef822b,
- 0xb2fcb90b, 0x7285fcdd, 0xefe5ca27, 0xae8f0ccb, 0x3bfefa6f, 0xde00b71d,
- 0x05468d5c, 0xe6f12df7, 0x7e512a77, 0xa3cb3704, 0x18e32124, 0x12792fd5,
- 0xaa9da6fd, 0xf61f3e39, 0x0ea200f5, 0x1b26aced, 0xfd9959d9, 0xc377c542,
- 0xcf328d78, 0x6f968aff, 0x9cb90bb3, 0xc34bda37, 0xc0b76e74, 0x4478c2ea,
- 0xd9b0f25f, 0xf3c2caef, 0x6fbc6764, 0x287e0331, 0x4a676a7c, 0xa7732823,
- 0xa313db83, 0xf6483a9f, 0x27c8b344, 0xd2314c6d, 0x256c49f7, 0x445203ce,
- 0xc87336bf, 0x36f8e785, 0xb163e0a3, 0x3207e69e, 0xf7b75f29, 0xefba5d3c,
- 0x9855d915, 0x6e1c8447, 0xee817116, 0x3ff446f1, 0xcdc44520, 0x4a90966c,
- 0x4bfa69e3, 0x3fc76f1b, 0x914ede36, 0x678da927, 0x9f5fa51f, 0xf5a61cdd,
- 0xa1fd85d9, 0xd713b78d, 0xe30f2317, 0xf5c3c76b, 0x5a378e45, 0x25bb3ebf,
- 0x4bb3eb4c, 0x1ee95edc, 0xf1ec476f, 0x4f671afa, 0x569cfe54, 0x72e42fce,
- 0x7632cc15, 0xd33ff60e, 0x09f9e9c2, 0xd9c5d313, 0x7e7a0937, 0xa69788b2,
- 0x992e5c09, 0xcfba669c, 0x7179d133, 0x6db5d217, 0x9dce91b7, 0xc827296c,
- 0x4ed3927e, 0x40fc8931, 0x9fcf8ad6, 0x02f7f030, 0x7998e6a9, 0xe1fc7b2b,
- 0x7111b9f9, 0xceb534e3, 0x134ff980, 0xe30c1d9d, 0x3314b6ec, 0x6296dfad,
- 0xfca1c60d, 0xcd809955, 0xdb8004c1, 0x0b1b7c8b, 0x954e3d61, 0xc5338bf3,
- 0x92f3007c, 0xdfa1aad2, 0x84ff7d08, 0x772663a0, 0xee22abba, 0xc45b3cd7,
- 0xaf8d49ed, 0x7237e7a3, 0x41ff5f30, 0x4f31e7f0, 0x8f0c6ba7, 0xdc3e9c93,
- 0x5987fc9f, 0xd07bc60f, 0xc0fd3e8f, 0x77820ae0, 0xf5f3a58c, 0x4ec787d3,
- 0xd6627f41, 0x8246698e, 0xe303ac0d, 0x2c76b31f, 0xccf3e234, 0xdffb461c,
- 0xf24cd675, 0xd58ed675, 0x4cbffda2, 0xc665f6c1, 0x6e30cfc0, 0x91ef7650,
- 0x8c8b8c04, 0x00373fb5, 0xcec6d3cb, 0xa07df88d, 0x1bf6155b, 0x5bbcd734,
- 0xb228ed92, 0x36c81eab, 0x44f59fa1, 0x99bf3f21, 0x9e263cc3, 0xbf25e187,
- 0xf091fc7e, 0xfbb2bc31, 0x72aed69d, 0xb4f6c63c, 0x9cb1c729, 0xdaf15214,
- 0xf0e8ab32, 0x4a72c71e, 0xcd02aeb8, 0x5b77cad9, 0x3159638e, 0xe204f7dc,
- 0x46f7f0f7, 0xc614fc95, 0x6e6fbac9, 0xd93bda3c, 0x0f27435b, 0x44d65c50,
- 0x94f6c2f7, 0x18249b79, 0x6bcb8f6f, 0x27b43d45, 0xf248db25, 0x256ea935,
- 0x3c6073ad, 0x51ee75c3, 0x45c9717c, 0xbec97724, 0x11ec137f, 0xe7eeffdc,
- 0x33f9fcf1, 0x151afe82, 0xf88935af, 0x027ca140, 0x9acbb09b, 0x151d2799,
- 0x04f76ca1, 0xc7b72e31, 0xc078e5c3, 0x6c52fdc6, 0x58ec0dbe, 0xec6992ba,
- 0x95594fd9, 0x60c779f5, 0xb2bf60de, 0x10b28768, 0xa6bc5fed, 0x0fe8308a,
- 0xc61d5dfe, 0xe6dda1f5, 0x36be38a4, 0xfa14b97f, 0x9c33a08b, 0xcf5b6cff,
- 0x67b8da7b, 0x237e7ac4, 0x1f1ef4e4, 0xef9b4fef, 0x463728db, 0x465dbcd2,
- 0xe6248f9c, 0x4630eb03, 0x1da227cc, 0xde7bafad, 0xf7e74d4c, 0xdf8c3d4d,
- 0x392e6543, 0x8b0efd62, 0x1e912ad7, 0xbf482a34, 0xf948d576, 0x2fdb76fc,
- 0x7a3f0f29, 0x790a171d, 0x7287eabc, 0x365fa188, 0xe430f54d, 0x1e2a1fcb,
- 0x0164abb2, 0x0edc29cb, 0x624fc793, 0xcaf588a6, 0xdda89329, 0xf18f6834,
- 0x096569c5, 0x74ebd22a, 0x70a0dad6, 0x2e78e03f, 0x318f2fcc, 0x2cb75e5d,
- 0x9faac7e0, 0xf0bb72ab, 0x7b4b592a, 0xf745da01, 0x9dbca72c, 0x3ad30d86,
- 0x05e9be70, 0xa193dbeb, 0xdf39fbde, 0xe3cc5677, 0xcb760372, 0x8cdfbcba,
- 0x9e470095, 0x30f4fb5f, 0xbdae83d0, 0x43365746, 0x847682a5, 0xaefae131,
- 0xecbf983c, 0x2c1bfae0, 0x4637365c, 0x5d17ba3c, 0xfb6bfc09, 0x4b9c1f63,
- 0x1c6d94f8, 0xb54bacef, 0x89f7c6de, 0x84fe8de8, 0x6d81eaf1, 0xbebd1f31,
- 0x7de20a42, 0x7b777b4a, 0x1afb8a96, 0x96d94fbd, 0xb8795dae, 0xca4675fe,
- 0x2bc68f0f, 0xb9b711d8, 0xa4d6ce91, 0xa73c3d50, 0xe8cc6f7c, 0x8a47eee9,
- 0xe3f7eb05, 0xca3fdaeb, 0xbe78bb82, 0x7a79fea9, 0x059bc94a, 0x500714a5,
- 0xebeb36f9, 0xf7ea36f3, 0x283a6315, 0x1654d3c7, 0xfdbfb90c, 0x394b4e7e,
- 0xbd6cc158, 0xbba355f7, 0xe5b17ecc, 0xce421bfc, 0xd3282667, 0xa7ce500a,
- 0xf3fec91a, 0x23531aa6, 0x8329defd, 0xf09cfeb9, 0x37e48d92, 0xf74ac0fb,
- 0x3850d4d6, 0x49c4ed01, 0x3ec9185f, 0xd1d4e37f, 0x3941a787, 0x9b4b37f9,
- 0x0ce4ddb0, 0x86ed0e78, 0xc47d74be, 0x84b7649d, 0x5f5f910b, 0xed93a166,
- 0x4c3b1fa8, 0x2da7bdf4, 0x26536c9f, 0x4cabfee1, 0x6d29dcc5, 0xdc6215dc,
- 0x5e029b5f, 0x996ea792, 0x51e7e41d, 0xf6d2bfd7, 0x2865c789, 0xf036577f,
- 0xbad57bb5, 0x9997d23a, 0xf142cc45, 0xd22af0ee, 0x19e31bc7, 0xa56ccbf2,
- 0xcf08bbf5, 0x4664ecbe, 0xeab66fe8, 0xf3c62d32, 0xce676119, 0x44d35451,
- 0x3f95552c, 0x73e7f2b7, 0x9f3d0f15, 0x73f87aab, 0x6feff71b, 0x3f610253,
- 0x2d9b77f4, 0xddfd85d9, 0xfd797aa6, 0x9fd50b35, 0x172fff02, 0x171ac158,
- 0xb7ae5050, 0xf3f2345c, 0xd13c5f2f, 0xa4ada37b, 0x2bf385c3, 0x36fdd235,
- 0x3ee893b0, 0x4bc54ef2, 0x32f791f7, 0xf822065f, 0x64d9d2e5, 0x629cbf47,
- 0x2f4b7ba4, 0xbf0c8c7b, 0x91a81403, 0x41423df9, 0x67572f47, 0x3654f9d2,
- 0xebf71322, 0x43b256bb, 0x0fa0f11a, 0xe7f757db, 0xf6e642fa, 0x2951bec3,
- 0x6161ded4, 0x074895c9, 0x3bca6587, 0x1e78e1ff, 0x650f943f, 0x735ed107,
- 0x5df9e8d6, 0xe9c49d2e, 0xf20a6541, 0x25550cc1, 0xcddfafba, 0xf88ba354,
- 0x7d87de9e, 0x2cee75a5, 0x1fa2bb7d, 0x55546bc2, 0x93a18ce2, 0x6fa5f517,
- 0x8cf83c73, 0xb3be4794, 0x9befbc54, 0xd7c70874, 0xe0b07cf8, 0xf4ae4d4f,
- 0xf52a4396, 0xa49a4f63, 0x306800ee, 0xbffc800c, 0x51cf0ccf, 0x74cb242e,
- 0xa9706adf, 0xf586521c, 0xe8867df0, 0x4fe0b077, 0xcf9e88f9, 0xe1e90ef2,
- 0xeeff0447, 0x1fb92163, 0xe8c2dbf6, 0x8b406a5c, 0x3e781dbe, 0xd1639406,
- 0x22abfc7c, 0xd48f1683, 0x9e17a1e1, 0xd9d7b17d, 0x5c40aeb3, 0xc8cbad3e,
- 0x5de425d7, 0x3d2b6dae, 0xd56455cf, 0x2d62f385, 0x07fae36f, 0x40c1921c,
- 0x352afd85, 0x7801cece, 0x71264046, 0x49859337, 0xbadd7c5e, 0x2b5c451b,
- 0xebd19d7a, 0x44b065bb, 0xf1cccbeb, 0xca6ec979, 0x326ec990, 0x18c2006d,
- 0xbdb0d78e, 0xa3716e3b, 0xd4fb3b3d, 0xe6439060, 0x182b567b, 0xe4233e0f,
- 0x892be992, 0x56fdd7d3, 0xda5357a2, 0xfbc8828c, 0x4f86972a, 0xf318333a,
- 0x7ababfbd, 0x4f8f1072, 0xe5a3fe11, 0x7f455fdc, 0xf9f53a63, 0xc62ee386,
- 0xe9c7e547, 0x5c270df3, 0x1f951feb, 0x1f951397, 0x3f574437, 0x95111959,
- 0x2a2e371f, 0x075cae3f, 0xae982f4f, 0x9d533f6b, 0x2d6f83a3, 0x7daeaefb,
- 0x5d4ee795, 0xbbca9cfd, 0x79b7f574, 0xf3c1d6ef, 0xb5d7efab, 0xd7abe05f,
- 0xe5777fd5, 0x20f5740f, 0x8bc6622f, 0xf74a3c31, 0x613dd386, 0x3016a0fa,
- 0x3d8637bc, 0x57722920, 0xf471fea4, 0x1e4c5fe1, 0x71e3f7c2, 0x3b093fcd,
- 0xc4591c78, 0x838b595f, 0x7c5ab1e2, 0x9a763436, 0xb722fd15, 0xbd434d45,
- 0xf5cb7ece, 0x74380b06, 0xdf89cb71, 0x1b76a4ab, 0xfce9b292, 0xb3b051e3,
- 0xef30f97d, 0xe927cf20, 0x1c6b001f, 0x500ddbe3, 0xd7febb42, 0x2237cccc,
- 0x9e2c1e62, 0x3cb585c7, 0xe64f3107, 0x8bf3e049, 0x61f7cfe3, 0xfd1f313c,
- 0x0f952b38, 0x4173b53a, 0xf6bf6195, 0xf2807332, 0xed834b11, 0x036f9866,
- 0xc51447c8, 0xc74e5e12, 0xbd4db838, 0x7aaa3de1, 0xb3dd3a7f, 0x050d2db1,
- 0x3aa5d04c, 0x3d1fd1e4, 0x7cdbef02, 0xe314e28c, 0x11ffec87, 0x433ce1c6,
- 0xbb3f345c, 0xf7bcf1cc, 0x74b97ff6, 0x9265e518, 0x45f5ee93, 0xb1dda7d7,
- 0x6e37f3f9, 0xd177bf50, 0x765bdef7, 0xdf6ff7a3, 0xa231b674, 0xcbf9afbe,
- 0x13ccfeb6, 0x66590741, 0xad55fdfd, 0xfae10ef4, 0x3358dd7d, 0x49272fc5,
- 0x604399be, 0xfec6cfbc, 0xe1db7bf5, 0xbe2b4fbd, 0x3bfd1db8, 0xe7c5ee78,
- 0xfaf08ed0, 0x2c95e669, 0x04399e7c, 0xb3d47fec, 0xbe662c71, 0xadd05f9c,
- 0x45d3569c, 0x99aa79fe, 0x6b4e43e2, 0xb0f3fce7, 0xf1516def, 0xcbf46682,
- 0x447baf01, 0x8f8b447c, 0x59fa2ddf, 0xe9494a21, 0x660e73a4, 0x527dd00d,
- 0xc5ec5ecd, 0x86328e0f, 0x936ca37e, 0xc5ca442f, 0xc53354f6, 0x4cc52407,
- 0x3292e779, 0x2823be8a, 0xe78fa381, 0x985b7637, 0xd4f68cfc, 0x900f1451,
- 0xce286342, 0xa885b360, 0x2fb6bf3f, 0x77dfdeaa, 0xbcd3cf5a, 0x759feefa,
- 0xc7704f3f, 0x1e6a2718, 0x47d61e38, 0xccc0738f, 0xdcb9dfb8, 0xf1be331a,
- 0x0d8990e2, 0x5f915243, 0x82dd773b, 0xd8bbfafc, 0x312b5972, 0x81183e8f,
- 0x6486879f, 0xfe605d13, 0x5c62307c, 0x848f97cc, 0xdee80281, 0x6aa0c104,
- 0x71425a06, 0xa13c7083, 0x6acd9a07, 0xa087d93a, 0xf71f70fe, 0x0a7e7e09,
- 0x51fc8d68, 0x03ef87e1, 0x51f2c63e, 0xda7642bf, 0x843fe07e, 0xa8bbf09f,
- 0xa80bfa0c, 0xa957e83c, 0x8cbf90fe, 0x1efd27e0, 0x2bf88f82, 0xefda7ca9,
- 0xf8cfe7a5, 0x85fe09ab, 0xab6547df, 0x7f3d257f, 0xf0475fce, 0x044dfe0b,
- 0x42ed12ff, 0x9a27cf19, 0xdfd97ca8, 0xf8aff542, 0x9afc11f7, 0xc865483f,
- 0x1f9e847f, 0x7c12b7f5, 0xf046dfdc, 0xe0887f09, 0x95077f0e, 0xf4c3fa6f,
- 0x5dff94fc, 0x2758afde, 0xfc672278, 0x45b49780, 0x79da1746, 0xcc968b69,
- 0x6f7800ae, 0x6df74cb5, 0x4be40b9d, 0x1e2e8007, 0xf7f26555, 0x5234aef6,
- 0x2bb347dc, 0x486cd6f7, 0xb9faa72a, 0x1592df54, 0xbed9764f, 0x77ba66a5,
- 0xedc55b6d, 0x46ccb659, 0x32c56ded, 0x72ba3fd5, 0xcd8dd92e, 0xae300538,
- 0x07818c32, 0x25bb6326, 0xfbdf9246, 0xefbae2a2, 0x6f79fd89, 0x45efcc88,
- 0x2253891d, 0x5b6b21cf, 0xbaf07493, 0x7ce50cb6, 0x25dcdd04, 0x989b61c6,
- 0xc49df91c, 0x33bdf64f, 0x79d602af, 0x0f7be497, 0xfba7c8e5, 0x3403cdcf,
- 0xcbb5a331, 0xc8e4fc8c, 0xbea7ad89, 0x4b3fe4d4, 0xdbf8893f, 0xbf84caab,
- 0x69c6eabd, 0x2c5fe8b9, 0x137be992, 0xcfe48b69, 0xbfe99fd1, 0x997ba640,
- 0xc53255b6, 0xa322d903, 0x5a46c7c0, 0x7305ff77, 0xe9b95ea9, 0x9dd1c514,
- 0x27878eab, 0xf802dda3, 0x387da3ca, 0x4fdf8494, 0xd77110ca, 0x94f1297d,
- 0x9f3d1637, 0xf8bbff2f, 0x19f80cd9, 0x5f3f1315, 0xa3cfc2c6, 0x7f75fee2,
- 0x68857df1, 0x31df693c, 0xcf7c547d, 0xc791b03b, 0xa5dba3ef, 0xe62ab888,
- 0x4ff7d174, 0x1f92656a, 0x81f059fb, 0xc59d807c, 0x7de3dd32, 0xb3ead264,
- 0x733e6007, 0x114a7c8a, 0xc855039e, 0x26c65147, 0x6ffef257, 0x893f235a,
- 0xbaf40574, 0xb76849ea, 0x99fa617d, 0x05fb287c, 0x7f18ed5c, 0x9fde8fb5,
- 0x8df313e1, 0xc5b217a5, 0x447bf63c, 0x81e614fc, 0xaadb3b71, 0xf9c785dd,
- 0x504559b8, 0x657accef, 0x77fd5e2a, 0x9832edcd, 0x2c5feca0, 0x2cf1c7af,
- 0x893f4ddf, 0x3c06a5e3, 0x38c578da, 0x53c537de, 0x69157dd6, 0xf75deeb1,
- 0x4ebf0f25, 0x12288e0e, 0xb00674f7, 0x1f072801, 0x9c527531, 0xcb86703a,
- 0xd326a641, 0x71e8b87d, 0x98fbcafa, 0x6193f028, 0xd10de7e1, 0xf6eb4def,
- 0xee54025b, 0xa2aff4f7, 0xb2c9a83c, 0x233d0ef8, 0xc4c37b7f, 0x0dcb6578,
- 0x421e63ce, 0x36840bf9, 0x7e8988be, 0x7ef2a732, 0x9b9fbc8c, 0x27827ad9,
- 0x0dc094da, 0x8b7601ce, 0x5157507e, 0x95c2c45e, 0x3de11abb, 0xca265bfb,
- 0xbe4bb355, 0x7e77245d, 0xe47f912b, 0x3aacb634, 0x62dfd116, 0x1ced1eb1,
- 0x8a35f302, 0x88f39ee4, 0x91f01af4, 0xbdadf022, 0xd1c450b7, 0x6f7ebb1f,
- 0x1445e512, 0xfb438c6f, 0x12b32f6f, 0x214cd81d, 0x7f0238a5, 0x0eff0336,
- 0xebfcf44e, 0x1e5acc8b, 0x28e26d80, 0xfc64473c, 0x51ca30be, 0x3eabf798,
- 0xd1deff07, 0x0fa677a2, 0x17fc7807, 0x383f9d32, 0x7bf3c597, 0x52367fd0,
- 0x226bcf7e, 0xb59df85e, 0x2c3f7415, 0x4ff44b1d, 0x78054fd1, 0x86a666fc,
- 0x8d9f7df0, 0xaf9bc1fc, 0xed22e7c9, 0xec152412, 0x4645dc6f, 0x5d71e5f1,
- 0xd83eeeb2, 0xf6fa8b98, 0xfa12ffb0, 0xfa9de9b5, 0xfe426976, 0xe8da473b,
- 0x1f769d1e, 0xdee5f9cf, 0x13d272c2, 0x1fff24f1, 0xe7e26553, 0x076d4ac7,
- 0x2b76ddb0, 0xa27e84bb, 0x4155817d, 0x8ceed039, 0x1b6ab927, 0xf3f64f11,
- 0xd6a3ccf6, 0x659fc04e, 0xda0a3be4, 0xbe2d032b, 0x7ebb1803, 0xbcc668b4,
- 0xc72431f4, 0x5c03be7b, 0x2f077a06, 0x733c1037, 0xbda6920f, 0xe9df48d8,
- 0x63345fda, 0xb68c804f, 0x5b979a16, 0x7cf30652, 0x35786ec0, 0x9c760dda,
- 0x63b418fb, 0xd0e01ea0, 0x9401df70, 0x7529e947, 0xcd5748ed, 0x292ba3b6,
- 0x429a5d0e, 0xabe4d572, 0x689ca10b, 0x91ac4b56, 0xc9f1adfc, 0x1afbe5b7,
- 0x3afef711, 0x7ebafffe, 0x4df3e2fb, 0xfaef9c85, 0x7e68038a, 0x9a7f747e,
- 0x60c6ff5f, 0x90a37efe, 0xe6b381e7, 0x70bf7298, 0x65279728, 0x5661ef22,
- 0xaf7d254a, 0x53a0567d, 0xa1d3fca6, 0x9bd80fdc, 0x867ca76a, 0xc2166ebd,
- 0x016079f8, 0x2ba40fd7, 0x29b29e88, 0x086cd54e, 0x3c1c812b, 0x70b90d0f,
- 0x97e09c5f, 0xd17bffe1, 0xa418d0bc, 0x7d05d8ef, 0x393df871, 0x17e747e8,
- 0xc57b4ad8, 0xd77ec9ab, 0x1f78d0e2, 0x439bbf1f, 0xa09820ae, 0x7d236af6,
- 0xbdfa261f, 0xf0f4bb9b, 0x787a6b84, 0xe77fd322, 0x87aadca5, 0xf87a2b27,
- 0x6e472153, 0x9f3fd749, 0xfdc3d2ea, 0x338c1c17, 0x1415fbf2, 0x828ed2af,
- 0xc60ef7e1, 0x200806c5, 0xfca16a47, 0x6b9d01a0, 0x3f341e48, 0xbff88338,
- 0x7c7d1aff, 0x6dd59d38, 0x9c603649, 0x59dcff5a, 0xefd68674, 0x073fd1ac,
- 0xfc60e83c, 0x7dd209ec, 0x3c9f70c5, 0x387fe614, 0xe657e79f, 0x7869de48,
- 0x5a0263e4, 0xfdf915bb, 0xdb8fbe76, 0xfe0b5f64, 0x4adb16bf, 0xa0af2853,
- 0xb5f7c2cc, 0xf77c58ab, 0xdf8525a6, 0xbcb35edb, 0xa67f0dc9, 0xfba6cc8d,
- 0xfedd6dd8, 0x2be48fb5, 0xe291be3b, 0x646b7bff, 0x8676aefa, 0x85eb4035,
- 0xc5d15c75, 0x5cba34a9, 0x6049cfc0, 0x587aba3d, 0x3d3d15cf, 0xa874443c,
- 0x31f90bad, 0xe45eb110, 0xfb4440c3, 0x72fb86f7, 0x8fc8dd71, 0x72e3cf91,
- 0x0f744d3b, 0x2fa7ac59, 0x42e4d4be, 0xd68f3899, 0x10bed2f2, 0x69796a63,
- 0x695e451b, 0x878f439b, 0x5127aa2f, 0xf08be11c, 0x0c5f789c, 0x0fbe453e,
- 0xc7be73e4, 0x87bc3b72, 0xfae7bd7c, 0x1e38a9e2, 0xc44081ca, 0x084e1bf7,
- 0xed87fc3a, 0xbb2896ca, 0x3fbfecfb, 0xaec8cf59, 0xeb0a1cac, 0x8e781dac,
- 0xdf174fdf, 0xf4213ab7, 0xe9c094be, 0xebbcafa6, 0x56bc9efa, 0x8a5bae2b,
- 0x12bbe3ca, 0x020daf85, 0x57fbda5f, 0xd3c26c94, 0x6b728e95, 0x4262785f,
- 0x1f21323e, 0xb32a7bf1, 0x4c6ecfca, 0x3a5b1955, 0xf879b9f4, 0x7759887d,
- 0x02cd2d9d, 0xd7d0f378, 0xb3d3fc38, 0xa6800c2f, 0x2dfcfd1f, 0xf67c3f0e,
- 0xf9154c8b, 0xe1e73ff2, 0xe21c23f7, 0xaf9b45dc, 0xa1fade36, 0xb758dedc,
- 0x238f1ce9, 0xbf3a5ec8, 0xc97a77ac, 0xa52cffcf, 0x07e781cb, 0x9cbb52eb,
- 0xd7206e4b, 0x40ba6dd7, 0xe9860c71, 0x5f30a351, 0x9f129188, 0x57c7e5ad,
- 0x1de3f3ea, 0xd7c4d58e, 0x50501616, 0x3d59c5de, 0x7d7e7e74, 0x73e68ba8,
- 0xf9ab531b, 0x0f2bb9f9, 0x5dd667f7, 0x5ff69886, 0x8f9150e3, 0x68df42ca,
- 0xf2f2265c, 0x768994e7, 0x7117f8ca, 0x9e8cdb9c, 0xfffbd446, 0x2a51663a,
- 0xbf2d098a, 0x3dcf4869, 0xe6df43b7, 0x0face4fe, 0x24575c0c, 0x53f178f2,
- 0xcf345dc3, 0xea0038c8, 0xe5f6be85, 0x3d53d088, 0x38a1e2fb, 0x87b27d67,
- 0xe5d28bef, 0x92fb82d8, 0x5adce5d4, 0x7bfaf7d4, 0x3e144fed, 0xcd32875a,
- 0x7e90967e, 0xda7f0ebf, 0x607968fe, 0x1e5706f5, 0x87172bd9, 0x609fe2e8,
- 0xf6bcbbe8, 0x718df4d8, 0xa7360d4a, 0x648e297b, 0x300b514a, 0xeffeb84f,
- 0xe9bccc52, 0xb74e8273, 0xbee9e238, 0x4cc3bd75, 0x1ddabdf7, 0x61da183b,
- 0xc236db56, 0x89a3854b, 0x835c9e61, 0xb7d2b59b, 0x82f2a20f, 0x790bec1b,
- 0x659f2a7d, 0x8e4d54c3, 0xc6d67e71, 0xdc94aabb, 0x772a2e30, 0xa3affff2,
- 0xf2477aaf, 0xec1f9e34, 0xb07e5330, 0x8bae6894, 0x26dc1f95, 0x5c768dec,
- 0x83ae0a57, 0xf5b4c9c7, 0xaf3c5d58, 0x9c639f11, 0xd1f2eccc, 0xada2e3ff,
- 0x87ec4dbb, 0xaae2ded6, 0x25ef2863, 0xf942eab3, 0xff73c52a, 0x4147f51d,
- 0xc6d49c84, 0x89a87e7f, 0xae1b0bdf, 0x2b35fcf0, 0x7eb317d7, 0x7f19886b,
- 0xf3543abf, 0xbf19beb7, 0xdb32f469, 0x3461f3c8, 0x336b9ebe, 0x981ed07b,
- 0x7ca74b6b, 0x8040b99d, 0xda239317, 0xbf3e677f, 0xe9ab29bf, 0x1bbf4748,
- 0xdfc5e137, 0x4c36f801, 0xf6f4f117, 0x6bdd1354, 0x3cc0db7a, 0xe74652e8,
- 0x49bd7a23, 0xb79a7193, 0x80db38ce, 0x31d8786c, 0xcbe504be, 0x13728ee1,
- 0x3b0067de, 0xca186e21, 0x46eea599, 0xbf30efbc, 0x7fbe98a6, 0xd77fc5a2,
- 0x49303d09, 0xddb039f2, 0x9a3f6367, 0xde6c4155, 0x7fdf4595, 0x88dff114,
- 0xbb44fd76, 0xaca26ed3, 0xc03efa2e, 0x45e8e515, 0x83f68b9f, 0xf1a21af2,
- 0xf912fb89, 0x72698bff, 0x8b3bf502, 0xe123b3b2, 0x949d89ed, 0xa9e9af6f,
- 0xcdf23ea6, 0xf2130db6, 0x714fe351, 0x7cc7109e, 0x6493c456, 0xf37b72f0,
- 0x3f4fd3c8, 0x37b1eced, 0xa43d0877, 0xd05093f5, 0x2209954a, 0x78a0c4ef,
- 0x2564fe88, 0x75801e90, 0xfb197d36, 0x61dcf89e, 0x716d8e5c, 0xf6c74b6f,
- 0x3a6ab915, 0x79d14bfa, 0x51eef5de, 0xf57fc8e9, 0xaafd3553, 0xaff9235a,
- 0x7bff9ddd, 0x75b42f3c, 0xb9e45898, 0xc669747c, 0xe41bb573, 0xfdc59bed,
- 0xc7476dc8, 0xbcbe3158, 0xc61256cd, 0xb66dd9f3, 0xbb721294, 0x478f3c6c,
- 0xf1b36f6b, 0xca9b3abc, 0x1b36d5e3, 0xf2d37bcf, 0x27ddda6f, 0xbb5a0f08,
- 0xfef8c3e1, 0xff7e54d9, 0x520d5e21, 0x1bd938bb, 0xb8acbcc0, 0x66f64614,
- 0xc77f959c, 0xc8c0a12f, 0xf9fc31ac, 0xea266182, 0x49665b67, 0x9b54ec98,
- 0xd87642ec, 0x4e925e96, 0x0df11272, 0xbbdbd6e3, 0x19f745f1, 0x6b7c0856,
- 0xf3b7d4fd, 0xa9bede75, 0x08c56e72, 0x8bbd13b4, 0xd9b74e90, 0xbf315896,
- 0xde97b254, 0xc3f5bfb0, 0xca7cba0c, 0x7994fe9e, 0xd815bfa2, 0x512f649f,
- 0x8b133fb0, 0xfa0cfffd, 0xbbfebcc5, 0x819815e7, 0x60e3df46, 0x9e4fbb4c,
- 0x68cf4b1e, 0x439c55a5, 0x0ff7bf44, 0xfacd95db, 0x93d82578, 0x75830d0f,
- 0x3b9e66d5, 0x709e9131, 0x5e31b27b, 0xd849177c, 0xdbc2b285, 0x3df91a37,
- 0x637bed4d, 0x27289d9a, 0x73d0f1e9, 0xc3ef8a7f, 0x31c78555, 0xc518daae,
- 0xf9f9a257, 0xba63a9ea, 0x67a8107b, 0xc6dec23d, 0x8f48ed12, 0x3895cf19,
- 0x8efc6b5f, 0x3f28ba77, 0xf77f9aaa, 0x2918a6c4, 0xf400c25f, 0xddad744b,
- 0x8a4af9df, 0x115d7f69, 0xab486afb, 0x6dbf8951, 0xa32c42a1, 0xf3bf7bf9,
- 0xf3f22154, 0xfadd69fe, 0x6d75c156, 0xf7e5ca48, 0x564e4f17, 0x5fc3d962,
- 0x71c25f77, 0xa4ddc76e, 0xcf5c9d67, 0x3fbebffe, 0xaf34e8d1, 0x66debd44,
- 0x97f7fbd0, 0x50fddc85, 0x9afd8ff0, 0xdbbcf74c, 0x22ef7c8b, 0xde8c98bd,
- 0xfb07d46a, 0xbf9366eb, 0x501e0324, 0x30dfeeef, 0xc0af2a2d, 0x08b0fef7,
- 0x326b2e7e, 0x1aa677d3, 0xbf208fc0, 0xa31f6a2e, 0xb7eda7f1, 0xf9abdb06,
- 0xbfb69a39, 0x216cd313, 0x764bb791, 0xb9653387, 0xb398e501, 0xd9f067da,
- 0xec987db1, 0xfddabe8d, 0xad3bc84c, 0xb7fb0dbd, 0x3c4afce1, 0x8c4c7bfc,
- 0x6b24aef2, 0xec7fffec, 0x810f0a30, 0xcbac2b1f, 0x82aa7471, 0xeec24afd,
- 0xe8f9146d, 0xd5a94af5, 0x94bef113, 0x149d6a54, 0x7df52f41, 0x874a87c4,
- 0x942bdb77, 0xfce5a7e7, 0x60af684b, 0xbe4d9f5e, 0x20471ddc, 0x675e20ff,
- 0x47e36a2f, 0x9cf7bb9f, 0xbe3a73b3, 0xbd9294aa, 0xbb018f28, 0x4307ec00,
- 0x489bd2d2, 0x3f7c9a3f, 0x743c034e, 0xfca167bd, 0x3f05f7db, 0xec7e0a76,
- 0xd8056e4b, 0xb7dcba51, 0x4bc71d95, 0x2527401e, 0xf5274889, 0x39dd4699,
- 0x8b16568c, 0x5fb0c675, 0xfc8f87f2, 0x90cbf646, 0x17ec31e1, 0xcf224fb4,
- 0xf12ed1cf, 0xb445c844, 0xec313c4b, 0xf0a36697, 0xe779c4df, 0xadab9369,
- 0xfa70f013, 0xcefa44e6, 0xdbb469cd, 0xfb3ec04a, 0xdc5cd9e9, 0xee865994,
- 0x3b0853ef, 0x760c1191, 0x5e7077da, 0x1abbcc55, 0x1cd6ffff, 0x883f1bc9,
- 0xffd197e7, 0xfb75f2ab, 0x40b80719, 0xfbc76cbc, 0x1f744570, 0xf9d632ae,
- 0xe9baf7da, 0x88974504, 0x601e11c3, 0x5be22217, 0x5176e2bd, 0xa30c3a71,
- 0xe6fde774, 0xfdbf6ef4, 0xdae281ba, 0x882c7d3b, 0xb5bfb9df, 0x7b571f4c,
- 0xed99e443, 0xcf88ca5c, 0x86b41676, 0x53495fd0, 0xabc9c519, 0x73f6fa3c,
- 0xe3bfa32a, 0xddbf8fac, 0xcf4535e6, 0xd6ebbe97, 0xc06fac5f, 0x9714d5ee,
- 0x8b8f15eb, 0xfad1c38a, 0xf2943f50, 0x46adbc78, 0x6f655f9f, 0x7ddf419e,
- 0x12aeac66, 0x34cce7d7, 0xda8f8c32, 0xcff3a3ab, 0x1ecf0202, 0x9e1a5a12,
- 0xd878efb5, 0x7bfc8d8a, 0x540981a4, 0xe1c1e5af, 0x3a2705f7, 0x5b65d67b,
- 0x2c53e62f, 0xd881ace2, 0xf189daeb, 0x2e57cc46, 0x83c4830a, 0x302e70fe,
- 0xa30d464e, 0xbac299ef, 0x8705e775, 0xd0356f77, 0x03e147ff, 0x3c26ed71,
- 0x9813cfe8, 0x5afb40cf, 0x807f3fa3, 0x68e0ea75, 0xecebfebb, 0xb3bbc3f9,
- 0x58ff7e63, 0x5038b52b, 0x7610f8af, 0x383a4800, 0x6ca77c5c, 0xf68a1b28,
- 0x2378ad8d, 0x4c95c3ed, 0x0acaf79e, 0xa1bb9f62, 0x0ddf8f9d, 0x327c8a9a,
- 0xa679fd12, 0xf302cefb, 0x6f9f94c8, 0x3573e328, 0xa672f3f4, 0xd7c4622b,
- 0xb1307896, 0xbcfff04a, 0x1fa0f78a, 0x8c00b167, 0xdf1063df, 0xbdc4969f,
- 0x26062da4, 0xd514cc23, 0xb5e4f3ca, 0xe9043cef, 0x8d7d0f3b, 0x8b077da3,
- 0xda7bf805, 0x37dfd138, 0x74fbd1ba, 0x7e894d1f, 0x3ae282bf, 0xe17df8da,
- 0x17efafbd, 0x9dfcb1fd, 0x953e3c91, 0xc35a7449, 0xeba71fb4, 0x2b74ddc5,
- 0x53b83c93, 0x0f0f4eab, 0x773e7e45, 0xf74a824f, 0x0475b56f, 0x8eb44ba6,
- 0xf75fd96f, 0x595dd23c, 0x5881defc, 0xdbefe897, 0x117e8bae, 0x9301acf2,
- 0x1a8e816f, 0xcf91ef81, 0x2e93296c, 0xa10e74c9, 0xbf8bcfbf, 0x35fd1173,
- 0xf9493d1c, 0xbdc47b3b, 0xa75c6d70, 0x8a0433ea, 0x3c107ef0, 0xd08f118f,
- 0xdf8ca5ca, 0xf5e6d28f, 0x3504017f, 0x7fe05f6a, 0x00007fe0
+ 0x00088b1f, 0x00000000, 0x7de5ff00, 0x4514780b, 0x74f570b6, 0x9924ccf7,
+ 0xf2124c99, 0x00493de0, 0x210e0311, 0x9970c044, 0x46a2c024, 0x141a020d,
+ 0x84920275, 0x7e889790, 0x33feaeec, 0xa8a08901, 0x17acb9f1, 0x376141dd,
+ 0x0c06e8b2, 0x60e03518, 0xba2eb300, 0xe7c045c1, 0x36bc8026, 0xb9f04324,
+ 0x9d6f5ecb, 0xdd33d553, 0xc7c4099d, 0xffef7fde, 0xa55f9f8f, 0x71ebaaba,
+ 0xe9d4e7de, 0x278f3242, 0xdf210a64, 0x9f968fc1, 0xf890848b, 0x206f5950,
+ 0x8841922e, 0x6df466d7, 0x88cfa64c, 0x68e67a23, 0xd11d985a, 0xef435837,
+ 0x9ed5cbe9, 0x186934a4, 0x1c790f21, 0x23e21258, 0x5ab54e84, 0x16f50520,
+ 0xe0933ba8, 0x213e3a7d, 0x0ff8e8fd, 0x30f8e246, 0x1a18992d, 0xe0311067,
+ 0xf9ad537b, 0x421eb089, 0xc3e6476a, 0x213b16fc, 0x9f9f7bfd, 0xa7eb888e,
+ 0xf7c10def, 0xb59efa24, 0x6529efef, 0x13fd0e57, 0xf66ddff6, 0xf108146d,
+ 0x71c7fcef, 0x8699ef58, 0x5d130e39, 0xd9b7766f, 0xbeea053f, 0xb6899f6c,
+ 0xc0fb6ee7, 0xe5fed126, 0xda0944db, 0xf0233b0d, 0x8275cefd, 0xa695ea0f,
+ 0xa4ae47d6, 0x9136c0f5, 0xf8d30f3c, 0x4092062d, 0x613371c8, 0xeb15873f,
+ 0x5aac1145, 0x6dd77ebe, 0xa3495f30, 0xf7d04489, 0x2e88378f, 0x28d92fa8,
+ 0xaf9d08f8, 0x8c07b5fc, 0xc578e803, 0xc23ea13e, 0x1f1beb41, 0x3ee83a33,
+ 0xd8fcef97, 0x7ce146d6, 0x0e2663da, 0xa4a3ee23, 0x52908d3e, 0x03e996df,
+ 0x9ba5fbe8, 0xbe802705, 0x4ed9dd74, 0x83695f58, 0xe3a45c3c, 0x228bae2d,
+ 0xee6c918e, 0xd7cc08ef, 0xdbe7147c, 0xf9830f26, 0x65dfce4a, 0x6ee52404,
+ 0xca2e9193, 0xdf603ae9, 0x3da7bcca, 0x053e716b, 0xd22fe59e, 0x8abf68f9,
+ 0x6c270597, 0xdc40c2b1, 0xd7ce8eb0, 0xb05e0a22, 0x8daafec0, 0x7deaac23,
+ 0x7d876e14, 0x1bd6fa94, 0x7d605ba7, 0x69458deb, 0xd716f1a1, 0x7d76a7fd,
+ 0xdd13536b, 0xf3e3bd69, 0x748287b4, 0x4a5ea844, 0x4fe90b88, 0x8e8119f2,
+ 0x85e7e795, 0xe2f7c418, 0xcc38913a, 0x3a15f1a1, 0xe9c07ef0, 0xf1958774,
+ 0x12dbc701, 0x842ce03b, 0xc73b6eb7, 0x54c814a3, 0x8f94af8f, 0x7ae83e00,
+ 0x2c763d6a, 0x6124f71f, 0x81c7a4f9, 0x33da7b70, 0x1eb5cb12, 0xc67f3e27,
+ 0x75cb0133, 0xcf96171e, 0xe9606679, 0xbf63e4f3, 0x58053de7, 0xf1b8f06e,
+ 0x253d6ff9, 0xaa79d658, 0xcf26f9f0, 0x7b372c32, 0x65fcf8bc, 0xeb2c2acf,
+ 0x6e58b53d, 0xb2d17c05, 0x7ec3e3c1, 0x58753ddb, 0xf1ea7a36, 0x469eebf9,
+ 0x3870d72c, 0xb648b2da, 0x7360e144, 0x3b453b11, 0x6573cd89, 0x9b1eb4cb,
+ 0xf309eacf, 0x5a46d9bc, 0x3ad3704f, 0x3280cb85, 0xd689b67f, 0xf6b15407,
+ 0x1c92f721, 0xf10fad33, 0x3594f6b2, 0x5a089cae, 0xed65a94f, 0x7379d623,
+ 0x847d6922, 0xda8fb58f, 0xa289cfec, 0xacf551f5, 0xc9134c7d, 0x18fad0b5,
+ 0xefa7ab3f, 0x695ae573, 0xd595bd3d, 0xe6f13f33, 0xb33d68da, 0xa93fbd8d,
+ 0x2c3a27c3, 0x55b0f13d, 0x14202c76, 0xb9de4d57, 0x9bca892e, 0x5dc746ad,
+ 0x7bc849c4, 0x892ef9de, 0xd90687ca, 0xde6ded85, 0x746eacc5, 0x77b77b61,
+ 0x2edff629, 0xaa5db1bb, 0xb7db0fbe, 0x9ed8dd1b, 0xed835d50, 0xdb17b28d,
+ 0x8a3f5647, 0x2f468ded, 0x5eaa4fb6, 0x65d7f58b, 0x55e7b61f, 0xaffec7af,
+ 0xfed87d1b, 0x5c9bfdf8, 0x05fd6953, 0xe41dbdc1, 0x5dc10ade, 0x9e815242,
+ 0xee4093ea, 0xf9f970d5, 0x6d1d101c, 0x446fe9af, 0x6efadc3e, 0xbfc00be6,
+ 0xf507ebf8, 0x983edfa2, 0x89bce38c, 0x1c74c8e3, 0xa4e3e2f1, 0x334137bf,
+ 0x257bfa4e, 0x382d38ca, 0xc6df444e, 0x24defad9, 0x2bde7aed, 0x0fd9c655,
+ 0xdac2b4fc, 0xffa57db7, 0x9ebb4b39, 0xe329973f, 0x89eb847c, 0x1a7adbe9,
+ 0xa7c2d03e, 0x7c2083e1, 0xf138e28e, 0xc64f5b7d, 0x327c2d41, 0xd3e1060e,
+ 0xeff4e381, 0x070d38db, 0x3869f0b5, 0x97cf8418, 0x7dc19f08, 0x21c657db,
+ 0x0e327c2d, 0x5ff3e105, 0xbee49eb8, 0x53fdb38d, 0x7fb67c2d, 0x498f841a,
+ 0xef0cf580, 0x3f32bedb, 0xf327c2d3, 0xec7c20b3, 0x7da5ce38, 0x67fb671b,
+ 0xff6cf85a, 0xfe9f082c, 0xbee8ce38, 0xaff32bed, 0xfe64f85a, 0x149f0835,
+ 0xb633e001, 0xfc69eb6f, 0xc69f0b5c, 0xb9f083cf, 0xdf19c70c, 0x384cf5b7,
+ 0x84cf85ae, 0x64f841e3, 0xf626bee0, 0xe3c69c6d, 0x1e34f85a, 0x3267c20f,
+ 0x6fb9338e, 0x42709afb, 0x27099f0b, 0x8e99f082, 0xebbb64e3, 0xc7465198,
+ 0xce3ef6b1, 0xf0b467eb, 0x104cfd79, 0x38e3d73e, 0xa938e8d3, 0x52671f17,
+ 0x933e16a7, 0x29f0833a, 0xeaae71c0, 0x77af38db, 0x7af3e16a, 0x853e1067,
+ 0x7db5ce38, 0x2ea4d7db, 0x75267c2d, 0x3b8cf831, 0xa36b9550, 0x3a1754ed,
+ 0x95cafa45, 0x40972e1d, 0xd59da2eb, 0x8093bb45, 0xf62a225d, 0x89756906,
+ 0xe6cb7df4, 0x8907f498, 0xb9c8eeda, 0x4ac7e813, 0xddb531ad, 0x52213d11,
+ 0xb8c4e763, 0xb8f53562, 0xfd340319, 0x3453f3e3, 0xa30589ed, 0xddfded34,
+ 0xc0fa9ae9, 0xfe9a4992, 0x3472ab83, 0xaecba1f5, 0xf64ff4d6, 0xa7a9a0de,
+ 0xd359baae, 0x7ced787f, 0x6b25fb4d, 0x97ed354b, 0xea6896fa, 0x42fdd597,
+ 0xfd747fd3, 0xe5fb4d72, 0xda6a0f8d, 0xd71ffac7, 0x3cb5c7d4, 0xbe3fe9a3,
+ 0xfb4d79f5, 0x69378715, 0x6db627da, 0x3cafd4d5, 0xcecebaf9, 0x5f8fd8b3,
+ 0xd022ebc6, 0x7f76613d, 0xf8f7e67f, 0x1bac46ad, 0x8ed05807, 0x722d65df,
+ 0x35f8a31c, 0xd1c0b5be, 0x7017e28f, 0xf6457e0a, 0xda4b9280, 0x267bf3e8,
+ 0xd3b12fb9, 0xdd18f7e7, 0xd8c3db97, 0x041e94a7, 0xc3a50492, 0xfdbea500,
+ 0x63d19901, 0x23f3c0ce, 0x95fbe9da, 0x1888c086, 0xb312cf5a, 0x777e811b,
+ 0x8a2fcc0a, 0xf4154914, 0xf411348b, 0xce481e0b, 0xa2abc17c, 0x298355d7,
+ 0x71a10a1f, 0x24eec957, 0xaade33b0, 0x1d82f76e, 0xee983352, 0xcd21006b,
+ 0x4bdfbb42, 0x0607b4fd, 0xe9b92517, 0xb5232678, 0x1bf3d5d3, 0x3869fce9,
+ 0xebd00b7f, 0x7c7f307b, 0x294df9cf, 0x9bf33413, 0xe6689487, 0xfce91b37,
+ 0xafde4276, 0xa7e7c53e, 0xc8449848, 0x3853845f, 0x094869bf, 0x9180ffce,
+ 0xf9ea2bfa, 0x1ff38323, 0xd67ffd86, 0x2653fedb, 0xa43ff769, 0x237fbb54,
+ 0xea91ffdb, 0x48fe7cb3, 0xe151ffdc, 0x90ffdb2c, 0x137fb652, 0xbf38371b,
+ 0x93ff082d, 0x2f677f30, 0xb3529bf3, 0x5a1ffbb4, 0x89bfdda6, 0xfd5ddfcd,
+ 0x82df9f2d, 0xbe139ff3, 0x5a1ffb65, 0x4d1bf386, 0x8fd0276e, 0x95646071,
+ 0x1d4fce8f, 0x04490761, 0x40f3a172, 0xfd163239, 0x148497e4, 0x913dc75c,
+ 0x8abede8c, 0xf286f4a4, 0x58fccbc6, 0x996c951f, 0xb4e2efd4, 0xb67378be,
+ 0xb612e411, 0x21657f53, 0x8d1dea5f, 0x7937d222, 0x4e1be4d2, 0x28d9dbd7,
+ 0xc77ea17a, 0x207d9393, 0xe44d2aff, 0x4f787cf6, 0xfe787e22, 0x9fa353f9,
+ 0x5f4bef57, 0x8f95ac2e, 0x2df8a9b7, 0x90e547e8, 0x98165591, 0x1fa9aed7,
+ 0xa1107ea1, 0xd427c5fe, 0x249420cf, 0xbe6cca8f, 0x04bfa8cf, 0x2fea36f5,
+ 0xd5213b41, 0x75e25fb8, 0xae8c307d, 0x3f289f3f, 0x26f3ee17, 0x9e3a2964,
+ 0xc8f7f8c4, 0xf807c11a, 0x14597db8, 0x3d687e05, 0x4d38de85, 0xfb0fee9d,
+ 0x7c12ae07, 0x86380bcf, 0x9333e01b, 0xbd60478f, 0x67605eb4, 0xe8a21cef,
+ 0xb0514fef, 0x8a40d560, 0xb338d08b, 0xa44e4b88, 0x5a59cfef, 0xa2e84328,
+ 0x2f061055, 0x2059fa01, 0xe0119753, 0x69278de7, 0x7ae8389c, 0xf1b3b66f,
+ 0x63e4ba67, 0x14f5aa6d, 0x3e5766c8, 0xa1414f5d, 0x359feb88, 0xd1fedb43,
+ 0x619728ce, 0x3d572d0c, 0xc9ccf381, 0x54dfb6d7, 0x75cfada0, 0xef54eb6b,
+ 0x6ef7a0c9, 0xa73fd129, 0x9cfba160, 0x5d2b8417, 0xade75d28, 0x56b70e1c,
+ 0x5e0d5ec9, 0xda556dc1, 0x26e0a021, 0x5f7c2fb8, 0xf6ffd9ec, 0xa17ada65,
+ 0xb05f5b57, 0xa73e374a, 0xff1ce39b, 0x683e8047, 0x83e80279, 0xa718f3c2,
+ 0xd55c908f, 0xc18dc7d2, 0x50fa306d, 0x625c71f6, 0x8ebe3828, 0xdac2c7d1,
+ 0x50f4f0a8, 0x9707a418, 0x7a14be9a, 0xc3d38db8, 0x8a1e9ca7, 0x6ae96ad7,
+ 0x4cadf12e, 0xb2dfefa2, 0xe9e21766, 0xe8c850a0, 0x3d0a97e1, 0xc1e869b4,
+ 0x8f41e9cd, 0x3d38dbbf, 0x4673f6dc, 0xb67c7a0f, 0x5b687a71, 0x29264e7b,
+ 0xf14af13d, 0x3c53a9a0, 0x376ef0e8, 0x7c503d02, 0xf987a584, 0x8dd37dc1,
+ 0xde02fad3, 0x9c5f03d6, 0x053db01e, 0x4e104ec0, 0xcf6a7ef8, 0x684e54fe,
+ 0xc36bc5ea, 0x31b2bfe3, 0x6a98ee3b, 0x57f5e55d, 0xf5531dc5, 0x53375c5b,
+ 0x9be45f53, 0xbc5fe9ab, 0xbed350b6, 0xa69176b0, 0x3baac17d, 0xef42f535,
+ 0x6ffd35cf, 0x69ad565f, 0xb56ab5bf, 0x9296fda6, 0xb9f534c7, 0xfa6b5fee,
+ 0x5eb054df, 0xff273ed3, 0xacfb4d45, 0xf5345b19, 0x34d7ae99, 0x2f3b0dfd,
+ 0x31e81ebd, 0xc048a0eb, 0x71e638fe, 0xf71fdd20, 0xa4f2c48c, 0x717c89c7,
+ 0xcb0133da, 0x4fcd8d7d, 0x7cbb495c, 0x26882819, 0x91167f4c, 0x2cf64218,
+ 0xcaaf5777, 0x504e7d02, 0x7971feef, 0x1077b551, 0x07065395, 0xad6f39c2,
+ 0x11c7f891, 0xe2528022, 0x50c407f3, 0x6d1b567b, 0x3dbdeb8f, 0xb614ad6f,
+ 0x0a4dab3d, 0xe3e56e3b, 0x61ed4385, 0x7e2133e2, 0x3ec10326, 0xb9f6e2ea,
+ 0x204cbdbe, 0x84e7eaf9, 0x8ffe472c, 0x5cfd3031, 0xa2726466, 0x1cff6b6c,
+ 0x7fba8362, 0xe685d544, 0x95cca7ab, 0xaa91f408, 0xb5e2e3e1, 0x3ce46997,
+ 0x3c6de881, 0xcd38d9d0, 0x5775c5f3, 0xd8ebde6a, 0x2bbae225, 0x7d508640,
+ 0x07e48c3d, 0xfd97a00c, 0x8d6643cd, 0xceba7586, 0x355e401a, 0xd8fda3c6,
+ 0x771199e1, 0xe63c024c, 0x53d27963, 0x8f71e580, 0x9e63cb1b, 0x788f2c12,
+ 0xf36cb0aa, 0x33f2c32c, 0x4fcb178f, 0xfcb0ab3c, 0xe58b53c8, 0x2c5acf61,
+ 0x587c7a0f, 0x61d4f01e, 0x1ea7bef9, 0x234f56cb, 0x171e9d96, 0x29bf0a96,
+ 0xddd3d0f0, 0x4fa7ae49, 0x805dfd03, 0x07c4e2ce, 0x0a0d57aa, 0x8ae259d1,
+ 0x59bdab87, 0xd6f371a1, 0x249d389a, 0x0861e868, 0x81e364f8, 0x5e9c4c5e,
+ 0xade7b7c2, 0x9ed82f95, 0x1d8726d5, 0x7ff9f2bf, 0xf9cdbd0d, 0xa216f491,
+ 0x7a3a81a7, 0x3d18bd4a, 0x87c7124d, 0xc18e69e8, 0xa71ff4ce, 0x1f6087a7,
+ 0x628ffc61, 0xabc6ea30, 0x14573aec, 0x73f3678b, 0xb2d16a07, 0x7b9f3678,
+ 0x15ae1d05, 0x48df3fed, 0xc8f773c0, 0x78808fbf, 0xaa61f77d, 0xdf7b9328,
+ 0x7a5e9e9f, 0xfd0bbb87, 0x551f22a0, 0xb67ae3a2, 0xb8324447, 0x0cc81846,
+ 0xeac84e92, 0xce75bfe1, 0x44bac34f, 0x9f7de162, 0xf3986673, 0x4f670228,
+ 0xeb871789, 0x6357eb0a, 0xcfe3bc60, 0xca1323fc, 0xe6148639, 0x688b34df,
+ 0x0bff13df, 0x506f804e, 0x499c991f, 0x0c0f0710, 0x3ed1da37, 0xf0b459f0,
+ 0x667ad2f3, 0x29ab7e08, 0xdf515a8c, 0xfc2126d7, 0xa2357d86, 0x77e01f7f,
+ 0x317f3931, 0x0df7ce78, 0xf3c097f8, 0x62f1f262, 0x1cb89172, 0xfdd2372f,
+ 0x9d1ced77, 0xe403a0fe, 0xade185e0, 0xd7e95f9c, 0x7d28bcf3, 0x4aee3a2f,
+ 0x75b8e850, 0x88f3a108, 0xefc71da2, 0xc984b86e, 0xdbeec52f, 0x05f5f266,
+ 0xb59267af, 0xf9c53de3, 0xbbaf194f, 0xf81b05e5, 0x0c924b5b, 0xf06163f6,
+ 0xf5e594a0, 0xda8b76c9, 0xd6d46cfe, 0x19856bbb, 0x3a2768f5, 0x068f67a2,
+ 0x1fb7613d, 0x3b72061b, 0x9c654b09, 0xfb464925, 0x4ef72a31, 0x3346a5d7,
+ 0xe4c7cf3f, 0x9418e6c1, 0x663da717, 0xaf53ffec, 0x9471b7a7, 0x40d210f5,
+ 0x1e419a8e, 0xded4b6d3, 0xcf4af7fb, 0x3c4617d2, 0xbf926df7, 0x4cd0fb02,
+ 0xfc0effff, 0x5d61220d, 0x5eb2b719, 0x872e9af4, 0xf3359be7, 0xca1cf7d1,
+ 0x2977eb19, 0x891be217, 0x96e8571c, 0x5c638bea, 0x8bae2c9f, 0xcfed6bb0,
+ 0xb2bd4d18, 0x635dbfb1, 0x541fc28f, 0x412a92fe, 0xe329fa02, 0x5925d3e4,
+ 0x7d740956, 0x1090426f, 0xfd6056e8, 0x466dcdca, 0x95ce03b7, 0x5b7ade19,
+ 0x4cdfc51f, 0x897c9289, 0x61cf16b9, 0x9d2fea4b, 0x4ce67a0a, 0x88048ac3,
+ 0xbb162c1b, 0xf30fc9ef, 0x79312cbe, 0x0727c8bf, 0xa73df6b4, 0x55c7420f,
+ 0x945c639e, 0xeaab8e58, 0x8f16061d, 0x009b8fd1, 0x1c5fc6e3, 0xf79b153e,
+ 0x413b074f, 0xc68aa70f, 0xca3746b3, 0x665ffa45, 0xfc0a4e08, 0x13f314de,
+ 0x697e3a24, 0x2dc63b5d, 0x11deca4e, 0xbc80bcbf, 0x4b3fb9ec, 0xd528f1d2,
+ 0x15a4bcbe, 0x813f99e6, 0x371c444f, 0xf8e54c7d, 0x04c93fa9, 0x4f3910e4,
+ 0x4862657b, 0x063bfb86, 0xf90cc862, 0x161bf33b, 0x4fbc01e7, 0xe547bf81,
+ 0xdf241de6, 0xb5207886, 0x9cdfe099, 0x00198621, 0x7de433a7, 0x1e1538db,
+ 0x87232572, 0x94829533, 0xf1c14c1e, 0xefc1fddd, 0xb4d41532, 0xb9e0638a,
+ 0xc23ff8a4, 0x72471877, 0x50b7980b, 0x897b9ec0, 0x97e81ab9, 0x3f1a51fa,
+ 0x9a51fa8d, 0x34a3f53a, 0x437222f5, 0x1425e402, 0x9f13293d, 0xb4d27080,
+ 0x88ec928f, 0x555262c7, 0xafd1f603, 0xbe6dfc79, 0xe903489d, 0x7d5fcb3e,
+ 0xee90b336, 0xc5896ae7, 0xf57394fd, 0x0e0cb145, 0xa33e25a5, 0x7f73d2cb,
+ 0xddc61b47, 0x8c3f2548, 0x6fcfcec7, 0x051e6236, 0xdc994ab4, 0x7de949f4,
+ 0xa20d89ff, 0xfd06c22b, 0xbd6573e8, 0xff7fdfc9, 0xf212fdfa, 0xb4a3ee38,
+ 0xfa01266e, 0xc02791eb, 0x09d723f7, 0x7e185f2e, 0xaf74e42a, 0x013ba7e8,
+ 0xf143e37e, 0xf574fbac, 0x4abe1cd5, 0xfb5d29fd, 0xfd2f960f, 0xbcbe4688,
+ 0x93efba29, 0x027933c6, 0x00a417f0, 0x1e0fd7f2, 0xf8c7a93f, 0x7f1f81ab,
+ 0x6907f1b2, 0xff8e9ef9, 0xfeba4fd4, 0xbfd63d61, 0xcbfadc3e, 0xbb697d5f,
+ 0xd297ea97, 0x23653c3f, 0x494edf94, 0x8a4e09b5, 0x2b8db2f7, 0x3b902e6d,
+ 0x7c06d792, 0xce27ca71, 0x870f4708, 0x06a57cb8, 0x78804588, 0xc749fc2b,
+ 0xa1e9bd3f, 0xf89ec0eb, 0xc76ca36a, 0xc99d6a38, 0x5cf4a26f, 0x8f28b0d1,
+ 0x3b7ac18c, 0x16703fab, 0x51b2bfe8, 0xd3a6a23e, 0x953ddfd2, 0x94357900,
+ 0x921a0652, 0x7fa3f4a0, 0xf3e1b152, 0x546f60e9, 0xabf20092, 0xff983dfe,
+ 0x87d4589b, 0x9ee8c685, 0x499818ed, 0xafd9f780, 0xb3a1e1b2, 0x6afe0da2,
+ 0xbe9038c3, 0x37f7097f, 0x3f6b245a, 0x82b9273c, 0x54f2015c, 0x31f10781,
+ 0x8bc5637f, 0x4ed31abf, 0xe1b1d3d7, 0x0541364f, 0xea4fc527, 0x9bf05fae,
+ 0xcbbd1dd7, 0x87ca4eef, 0xd156bb6a, 0xee468e4f, 0xb2b13527, 0xaedbf64c,
+ 0x6ca4f2a4, 0xd2f4ecbd, 0xbd2f65c7, 0x2067dbf0, 0xc9a1fd7e, 0xbf8e9c39,
+ 0x073da5f8, 0xe2fad127, 0x3cbf722d, 0x908b0db6, 0x254bc210, 0x7a597ffd,
+ 0xafa50f08, 0x463a31ec, 0xc6f7e7b3, 0x78b1f086, 0x19232ecb, 0xb91e13dd,
+ 0x6d8cbbf5, 0xa9783096, 0x760e9f6f, 0xbf178adf, 0x3bbc8236, 0x892053b5,
+ 0xb9e061c9, 0x85da0f7e, 0x23c42700, 0x6f1053c7, 0x1495feba, 0x145fa02f,
+ 0x37dbe93c, 0xe3027971, 0x9e90d239, 0xce9d7e5f, 0xc991f25f, 0x792ffb09,
+ 0xec1b2ef9, 0xc55484e3, 0x95d9fae8, 0x4adf2009, 0x1d826f64, 0xe4bcf64b,
+ 0xde91bbb9, 0x9ddff78a, 0xae92e2c0, 0x95d406fe, 0xbfb0fede, 0xe0e6eb85,
+ 0x1b888afe, 0x59e4aee9, 0xcb47df31, 0x6332252f, 0xb8be184b, 0xf2726656,
+ 0x2354f3c4, 0x509dfdd0, 0x22fbc0f4, 0x627703d7, 0xbe6ef3dc, 0x62316a17,
+ 0xc3334bfd, 0xc0d930d3, 0x2bd32ce5, 0xf0dd7a41, 0xd38bea00, 0x70895d83,
+ 0xd21956be, 0xc437a80f, 0x1912d3fd, 0xc19e987e, 0xc99ea8f7, 0xbfd0e785,
+ 0x8c457655, 0x7a87bcd1, 0x297f9945, 0x3bae9f9f, 0x13b5ec12, 0x8ffde109,
+ 0xdf0acb9f, 0x4542bb53, 0x66fe2a5f, 0x3561befc, 0xdf856fe3, 0x4067337d,
+ 0x180717fb, 0xa07bc0ff, 0xfcbae967, 0x6bbed889, 0xc0f280b6, 0xf8e1fc44,
+ 0xf9cc837a, 0xd0aedb5a, 0x24b75d09, 0x05e8ab44, 0xf8458fc6, 0x7a2f5ea3,
+ 0x92a7be92, 0x9f309597, 0x0a78e7ad, 0xfe7316df, 0xf96b219f, 0xef8bac9f,
+ 0x99653e53, 0x33edfbec, 0x3f94afc0, 0x57e00ebd, 0xfdf61f39, 0x07cdcdb7,
+ 0xfa7ca66f, 0x4f857ab7, 0xcf53f2b5, 0xef5b25a7, 0x7a9f4026, 0xa0dbfd3e,
+ 0x4f96122a, 0x7cb0f3e9, 0x7feda83a, 0xf02a7e54, 0x45f802ab, 0xc8a7e085,
+ 0xa8e0dec3, 0xd9568797, 0xd21e5611, 0xd99201df, 0xba14fe93, 0xf4ade853,
+ 0x4143e5f7, 0x52e904ee, 0x5d20bba1, 0xdfa7742a, 0xfa7e16af, 0xc13249f6,
+ 0x26bfe575, 0xd65cffa3, 0xe942f2c4, 0x66077b7b, 0xa85c9c20, 0xdeed48c6,
+ 0x75d4fd81, 0xaf5eae9f, 0xd5d2efeb, 0xddfd75f3, 0xa6957aba, 0xb363597f,
+ 0xfdfe2091, 0xb2e27e9a, 0xb8d1c867, 0x63eaf470, 0x59c3597e, 0xc2e817a3,
+ 0xe5f7c012, 0x790bc4e5, 0x221d8186, 0x28ba05c6, 0x7e206b8c, 0xe7d939b1,
+ 0x656372a5, 0x743f8b04, 0x58b603d9, 0x618cae5a, 0xb1bc40f5, 0xf29ee406,
+ 0xe2c1103c, 0x01f95d8a, 0x9fca8c5b, 0x51126f6a, 0xc8f9b76e, 0x167e708c,
+ 0x47c828d5, 0x76b7a46d, 0x4d35ee76, 0x06590cb4, 0xd15aa571, 0x1df83609,
+ 0xe0d937d5, 0x29aba9dc, 0xfa02faf5, 0x451fe17c, 0x8ae97b4c, 0x75818db4,
+ 0xea4baf11, 0x4e6ff2af, 0x59d3ef12, 0x9a0b7f74, 0xc7739f98, 0x423d9d1a,
+ 0x153d20d6, 0x411a9659, 0xe27f529e, 0x86bcf688, 0x1f2945f1, 0xb69d64af,
+ 0xd29f795d, 0xa5f3fa01, 0x6eedb41b, 0xa07f0fee, 0x3258c9f0, 0x2ca3fb96,
+ 0xf2e5c30e, 0xfaed3134, 0xae8f8a02, 0x68989116, 0x4449bbbd, 0x166f747c,
+ 0x234f107c, 0xb7e478de, 0x7940120a, 0x03a9c0a8, 0xbbd8c9f8, 0xf6d8eabc,
+ 0x812fe669, 0x3c7fb66e, 0xd9693fe6, 0x11c3fdb1, 0xd5fd406f, 0x263e4343,
+ 0xeee7fb3d, 0xff73c08c, 0xa4569dae, 0xef1daef7, 0xd425f90e, 0x6139335f,
+ 0xbf3b5d9d, 0xd3f4031e, 0x0254dcb5, 0x306baef2, 0xd8aec78b, 0x3698f5f1,
+ 0x33f7afd4, 0xfe6461fd, 0x3fd37761, 0x41fa133e, 0x76057749, 0xe428cec3,
+ 0x23d7caa7, 0x6bbbdf30, 0x6e99d7c7, 0x9fb74fcb, 0xd1e79e0a, 0x5b052565,
+ 0x2c317d61, 0x8df2a18f, 0xd3542f89, 0x761bcbf9, 0xf6d01719, 0x39ff37dc,
+ 0xd768e406, 0x750f6656, 0x41cf6dca, 0xf194431e, 0xe29972dc, 0x8a9813ab,
+ 0x33bfcd3a, 0xdf02e466, 0x3fcb84f4, 0x57d63e31, 0xaffca478, 0x62e08781,
+ 0x33eacef2, 0x6fefb00b, 0xe318fb3f, 0x4ba4269a, 0xab7fbf65, 0xe57b46af,
+ 0xfecefb62, 0x82df6e7f, 0x76fb2fbf, 0xfbef9bff, 0x7abbd738, 0xe749e83e,
+ 0xfac1ee3b, 0xae27564b, 0xeef48fb7, 0xffc7fd85, 0x7bffeefb, 0xc52b7de3,
+ 0xfbe2edbb, 0x5affcdfe, 0x36f1ffbc, 0x7e3b778e, 0x3fe6f3d7, 0x57df7d71,
+ 0x6ff9bdce, 0xf6def78e, 0xadf5d8af, 0x067b2a86, 0xa9015f5d, 0x316182b5,
+ 0x92dbbe37, 0xd76c80e1, 0x8f30fd73, 0xc34bce0e, 0x23014df8, 0x904d0bf3,
+ 0xfb7e0747, 0x0b89411c, 0x1d751fa2, 0x1bae1fb7, 0xc8768254, 0x9987ae75,
+ 0xb55520dd, 0xadfed366, 0x989c0b39, 0x0fd24973, 0x7b3ea1bb, 0xfd6baf32,
+ 0xe204f7c9, 0x7f1da812, 0x2d35ce5d, 0xef5ed760, 0xa5eed112, 0x1fbbda25,
+ 0x9ece990c, 0x3dfad04f, 0xfadadd73, 0xfada054d, 0x8dde3e1c, 0xc6ffad84,
+ 0x7107c17c, 0x13f65355, 0x356710f1, 0x9089942d, 0x5542f90c, 0x98bfc12b,
+ 0x7f7daf93, 0xe3c1f81f, 0x531c3c7f, 0x971c0a4d, 0xb6485c20, 0xfa48dce8,
+ 0xeebe4700, 0x7d63d9d6, 0x244ccf90, 0x8de38327, 0x838c4ee5, 0xe65b7f73,
+ 0x5596cbef, 0xb2cfc0ad, 0xfc56cfce, 0x4de0dee5, 0xe38dffb8, 0x2fe084a4,
+ 0xbff444bb, 0xadff9d65, 0xe2fbe5e0, 0x8fe3c143, 0x3a97cbc5, 0xb8b20cbc,
+ 0xccabf008, 0x16a985fd, 0xca0fab27, 0xc8de7827, 0x9fa905fd, 0x42d3788b,
+ 0xcc8bdf79, 0x5f386ce6, 0x30148f33, 0x1afd71de, 0x3983f511, 0xe575c04d,
+ 0x8f31904f, 0x7e4373f8, 0x6f3be026, 0xbf1515dc, 0x0270cb60, 0xb871173c,
+ 0xb42a9117, 0xeff9c95f, 0x84cacbbe, 0xf6820673, 0x211722ef, 0xadbf52d7,
+ 0x47f04b28, 0x4b157852, 0x0e9d1bc4, 0x1c816f71, 0xb5bdc4d1, 0x47fdf875,
+ 0x8b9c6842, 0xbe4deff5, 0x5fe5d4fc, 0x323b3ca9, 0x1e41fa8c, 0x5849bb9e,
+ 0xaff156dc, 0x70626f6f, 0x7c132cac, 0x7e774829, 0xee755f39, 0x83e71cf8,
+ 0x0e3bdebf, 0xa3f664e5, 0xefd1a3a3, 0x6fd03977, 0x437ee4a8, 0x0d11d7b7,
+ 0xa6eeae71, 0x9b3e7e54, 0x55cb536b, 0xfdcfdca5, 0x7e40bfee, 0xa6bb2d21,
+ 0xf822b50a, 0xf1802471, 0x08d4ef5c, 0xfe4c31b2, 0x1931ffeb, 0x6154fd38,
+ 0x627e001c, 0xfd91e026, 0xd1abe98a, 0xadbc2ab1, 0x3494f6b9, 0xe01e27a6,
+ 0x0e754477, 0x0be163f9, 0x75c03e7e, 0xf4db447f, 0xadfb30fc, 0x5638b135,
+ 0xe2df5bde, 0x34379c77, 0x9700cb25, 0x9a8aa61b, 0x2655fb73, 0x238d97ee,
+ 0x795d60e3, 0x9b655d6f, 0x11697808, 0x66ddf09d, 0xa359d365, 0xb079cc3b,
+ 0x3e309e1e, 0xca8fd5c4, 0xe78022ce, 0x082387d1, 0xf2efd1f8, 0xf834c673,
+ 0x430d226e, 0x2b882e3a, 0xb5c39afe, 0x72c764d3, 0x1cb65e56, 0x6b4de74f,
+ 0xa3858fb0, 0x7fbc01d4, 0xe3211827, 0xbd878921, 0x501bf4a7, 0x1bb5fac6,
+ 0xf6e115ed, 0xed823c3f, 0xef3898bf, 0xfbfc2099, 0x51fb2de1, 0xec073fab,
+ 0xae3ca983, 0x09ae83d2, 0x0cf747f2, 0x1bfa07c1, 0xe7ac61fc, 0xdf84efb1,
+ 0xbeb3be55, 0x8559e981, 0xde70f5ee, 0xccace1cb, 0xe2c4dc7f, 0xfce27faf,
+ 0x8159c0a5, 0x4abd7eaf, 0xa6af2a7f, 0xd751e3a8, 0x197d8e37, 0x268a9bec,
+ 0x43a06ec1, 0x466d4855, 0xc6cac3e0, 0x6f3864c7, 0xe360eb99, 0x8c7f2912,
+ 0xd3a09f3a, 0x9a3bf2c4, 0x0dbcafd3, 0x1adce4e8, 0xe242e813, 0x0dace3ba,
+ 0x06bbf0e4, 0x7be19fe7, 0x227bef6a, 0x790178d9, 0xcea7b1f5, 0x8f525535,
+ 0x9ceb8c9b, 0x432d9655, 0xb296ecf8, 0x8aa2725d, 0xb14d3a9e, 0x1f3caed8,
+ 0x8748e650, 0x5c3e74e7, 0x1311f787, 0xd242ef81, 0xfbf15bea, 0x62aa5bd4,
+ 0xd4961d18, 0x3d6232ef, 0xf32bfb19, 0xf9e8f329, 0x369e7669, 0x6e4178ef,
+ 0x4b8020db, 0xd4bfc99e, 0x1f4e8619, 0x8ee72b33, 0xb84f53df, 0xf98edd28,
+ 0x2c4f48ff, 0x1b44f455, 0xef2bb9e6, 0x3e3335cf, 0xc489e957, 0x49627a70,
+ 0xf01123b5, 0x6a4764b0, 0x92c93022, 0x084b4e3f, 0xf03e27a7, 0x43e373b0,
+ 0xaeeebbfc, 0x5c4f54d9, 0xb313d2ae, 0xf44e9023, 0x959ae5ef, 0xe88b8d73,
+ 0xff6f0509, 0x03e6f2c3, 0xf86113d0, 0x56b346fb, 0x54d8dc4f, 0xc6e27a88,
+ 0xfbe6a2d9, 0x17cd6baa, 0x09d913d3, 0x3b2eb173, 0xcfd0c2a3, 0x39bfdc07,
+ 0x61fbf3c4, 0x6b17d01e, 0x9b8476cc, 0x26f46f5e, 0x55f6c7d7, 0x825fffae,
+ 0x97d722b3, 0x43f761cc, 0x8243a4f4, 0x2e64bcf4, 0xd002eb95, 0x4beb9323,
+ 0x4e71e56e, 0x07cd9c9d, 0x96a19b39, 0x0afdecb3, 0x950bd337, 0x9abfc98d,
+ 0xae6fdb47, 0xda669d95, 0xdc90e6ff, 0xddcb54cd, 0xe1096635, 0x96ee43dc,
+ 0xae7bb930, 0x4fda1c69, 0x53efedbd, 0x3ca96f2e, 0x430ce61b, 0xa2f3051f,
+ 0x1ddfdf34, 0xda76fb1d, 0xef2fc02b, 0xfb7e788a, 0xf603b739, 0x033b7d8d,
+ 0x7c53e9ec, 0xfcb8db3d, 0x5cf8f4eb, 0xc81ca953, 0xd3d983bd, 0x84459be5,
+ 0xe303455f, 0x91618aff, 0x4fad073e, 0xcf16ff4f, 0x60ef1761, 0x0774b0e7,
+ 0xfc2ad979, 0xadb77e2f, 0x1605ce06, 0x1cf017af, 0x005fbe19, 0x78731678,
+ 0xe3173916, 0xdaf14a39, 0xe53fe7f0, 0xa6a2dfbc, 0x5f0f18f5, 0x2bf6d3e4,
+ 0x29f5761f, 0x4cf247f0, 0xaf790f0c, 0xc9f5be08, 0xeba0cf90, 0xe78d5ce7,
+ 0xdaf5e547, 0x7ef907e7, 0xb4fe8a17, 0xe4fbe857, 0xd3bfcccf, 0x1ea0fbc3,
+ 0x123f252e, 0x5c29fb2e, 0x70f5fe32, 0xd40e0de9, 0x01f3c7be, 0x2b0e3c3d,
+ 0x649d2572, 0x6e7e1f00, 0xf15ca170, 0x42e143be, 0xb1e3bbe7, 0x40fb9ae1,
+ 0xbcb8738e, 0xf4d7706b, 0x02157e87, 0xb75e2bf6, 0xad024f65, 0x6327abcf,
+ 0x78a178e1, 0x070f56ad, 0x03837ef5, 0xaabcfaf5, 0xc7e4022d, 0xfbdfe42e,
+ 0xc31ef895, 0x5d6e547b, 0xed3cf546, 0xe4dd20bf, 0xfdf07386, 0x9b940111,
+ 0x47c6dd0a, 0x8e25fb30, 0x03a3a1cb, 0x3f515302, 0xe4760a35, 0xd3047f47,
+ 0x704f1457, 0xc4f34bbf, 0xbc73a7af, 0x2352b8b0, 0xc52563c3, 0xf4f3f01b,
+ 0x63af5e26, 0x4a2de076, 0x39f05ebd, 0xbbab9004, 0x8c5f7664, 0x8e04e240,
+ 0x847e9504, 0x04ecd5f3, 0xb4779e15, 0x28dffa33, 0x8f81f138, 0xf043f7fe,
+ 0x33dd2bdc, 0xf4afa63b, 0x3e29c0ae, 0xfde78b42, 0xe379ad11, 0x9bf9c1fa,
+ 0x737bc4e0, 0x9cf0629a, 0xbb2d58e8, 0xbf9525ff, 0xf00be7a7, 0xd1f7d43b,
+ 0x438584cc, 0x088cf37e, 0x79c50fcc, 0xa65d9853, 0x7bfa4f96, 0xfe6fbe80,
+ 0x45692551, 0xc7942c7b, 0x04de7ee8, 0x3410cde3, 0x09104ef9, 0x09ff3a03,
+ 0x7cd5bfc6, 0x9249f181, 0xef96f31d, 0xedcf2bb2, 0x5e2cbbec, 0x799c1e6f,
+ 0xef851e68, 0x13a255b9, 0x0c9ba85c, 0x2059838e, 0x09941e6f, 0x7db9cbf0,
+ 0x81e98bb2, 0x853bd428, 0xefc51eef, 0x0e590ad9, 0x8fbc291a, 0x7ca397e9,
+ 0xbd511f3d, 0x0a5882ed, 0xf70f1fa9, 0xee76cce0, 0x7880e69a, 0x95fec64b,
+ 0x2b39ce70, 0x20f07ed7, 0xbb3573e0, 0xaac8e907, 0xeed3f45c, 0x7e4053ba,
+ 0x06f14c3b, 0x9d99cfef, 0x9d20f07c, 0xf155d6f7, 0xcf396e78, 0x9c237f15,
+ 0x27dbce63, 0xdfb41d3a, 0x16adeb82, 0x66bcc738, 0x2adc48a4, 0x5a4adcf8,
+ 0xaf33be31, 0xb039ceea, 0x0faa12ee, 0xf72864c5, 0xfa844b4f, 0xafdf013a,
+ 0xf08dbaf4, 0xdaeb66bd, 0x3a0cc6b3, 0x07ed117f, 0xc75caf60, 0x106e55fa,
+ 0x5dfa909c, 0xca18f4d4, 0x020da2cb, 0x4ad3345e, 0x1b335fed, 0xe3a667d7,
+ 0xefa3aeb6, 0xbc317ad3, 0x886ee30f, 0x27ce11b9, 0xf13ae92b, 0x78d509fd,
+ 0xdf445d2e, 0x75a4cda3, 0xde389dc3, 0x810275a2, 0x264b03ef, 0x01323f24,
+ 0x3b27dbc6, 0xaed0fda1, 0xdd611b5f, 0xfaf9d1b7, 0x8817f1d3, 0x3fa0d36d,
+ 0xc760a5f9, 0x46ea87fb, 0x0baddc60, 0x542f0c36, 0xe63ac70d, 0x0c103b13,
+ 0x651f3a92, 0x4efb0447, 0x755968b8, 0xcdabec0d, 0x406c9f1b, 0x046b3aba,
+ 0xc28c7e3d, 0x3c874ddb, 0x2e79646a, 0xc6a3decd, 0xfd1c9536, 0xdf152228,
+ 0x1b31a3bf, 0x921626f3, 0x709bcc7c, 0xa47b3357, 0x0f84657d, 0xb2ed6ae2,
+ 0x6f3c087d, 0xe7c2695e, 0xfd312f9d, 0x0db839d3, 0xd627dbe3, 0x5fbe04c9,
+ 0xf52eb15c, 0x89e3c069, 0x9bd232cd, 0x1bcb2cf8, 0xc5897e28, 0xb1d79ac9,
+ 0x352c4f71, 0xa0b57bb2, 0x5f8bd69d, 0xb40af254, 0x51c8ac72, 0x2f4a728a,
+ 0x6b72f497, 0x46d593d1, 0xf21ed920, 0x9474e96a, 0xef54a557, 0x90f5a100,
+ 0x306a8357, 0x5797aa6e, 0xc8a2c495, 0x5f8874a9, 0xbe0f9616, 0xf1d02d6d,
+ 0x8183ecad, 0x5f6bff56, 0xb77a053e, 0x49e04acc, 0x5a7f6485, 0x80417460,
+ 0x6d35e65f, 0xa0f812f9, 0xde045e64, 0xf01c75c7, 0x26b37c00, 0x8bafcf0e,
+ 0x6f08857c, 0x78b72f25, 0x95ce96ad, 0xb75ce3f8, 0xfd6a5c48, 0x5c451255,
+ 0xee877eaa, 0xe74af4a3, 0xf051bdb9, 0x743ca881, 0xbbdefb5f, 0xc76eb033,
+ 0xf6e32d75, 0xd22b1ac1, 0x9f9fa1f3, 0x7af4095d, 0x0102bddb, 0xdd789d7b,
+ 0x2b0fa035, 0x880e0ad6, 0xcbdf170f, 0xefa62fde, 0xfd0fbac3, 0xa515d19a,
+ 0x7fd0076f, 0xf6c7bac5, 0x820dff62, 0xb43fc603, 0x89ed10be, 0xb048af12,
+ 0xfa3b437d, 0x614f540f, 0x57b3599e, 0xaffa004c, 0x0764dfb8, 0x23a14953,
+ 0xf9db2e85, 0xecc4087d, 0xbe8b331c, 0x15160ab7, 0xc51e93df, 0x4fa82102,
+ 0xbd2a4e81, 0x5fdace8c, 0x36409d92, 0xf64ba717, 0xae09fc1d, 0xe767c55f,
+ 0x74ef874c, 0x047ea98a, 0x975e6d3a, 0xe23b046b, 0xfcc04f84, 0x49749e8a,
+ 0x4a3b6a2c, 0x0567cba1, 0xd07baf26, 0x7b0e8ea3, 0x4ba71dd0, 0x5128fe85,
+ 0xb6595fa3, 0xfdf0264f, 0xdd1e9ebd, 0x908dfd72, 0x32f851ff, 0x6f5d0fdd,
+ 0xd1cfcd6e, 0x48e0575e, 0x2f5009eb, 0x8fde5892, 0x12e50fc2, 0xdefb0fcb,
+ 0xbfcdd3eb, 0x87e78229, 0x2c883f01, 0xe74fc97f, 0x0bf37b7d, 0x66792f98,
+ 0x6875fb53, 0xe941bcdf, 0xd9bfe000, 0x7fe8fc4a, 0x950e50f8, 0x6f988836,
+ 0xe67f244d, 0xaedf952c, 0xfe2cbfe4, 0x5de11583, 0xcbe4d5ba, 0x6e97efa3,
+ 0xf3063a3f, 0x30079611, 0x49bbc7bf, 0xde1fe760, 0xfdf031b6, 0xf2c4a950,
+ 0xc176f470, 0xe71648f0, 0xaa2d78ea, 0xa136ec00, 0x57b3dd8e, 0x6c937f5a,
+ 0x0775c552, 0x2f38ca45, 0x63e787ed, 0xb8678a5e, 0xa7d6011f, 0xc94ddfbe,
+ 0x9178e9bf, 0xa3695fd1, 0x695cf68c, 0xc84e96dd, 0x6c3d2cc3, 0xb2b73f42,
+ 0xfc11acee, 0xbc3fdcd8, 0x55f3f784, 0x3c9a8a36, 0x6ff91ebc, 0x04dfa275,
+ 0xe50d5bf9, 0xeb437e78, 0x0faf58ed, 0xb17a079f, 0x7fc5ad3c, 0x4bddb1d8,
+ 0x95f8b841, 0xbef0d9df, 0x368dd6be, 0xeea9eefc, 0x3da7f9c2, 0x57eaddf2,
+ 0xeddf305f, 0x0941fc34, 0x5d48baeb, 0x931d60be, 0x997d746b, 0xc4e261f9,
+ 0xa5eb7b41, 0x7c839f2f, 0x7fad8eec, 0x5bd60e7b, 0x9ee75ff6, 0xb21abc83,
+ 0xf60ec233, 0x0fa6e548, 0x79559f30, 0xd99224af, 0xfe2f9d7f, 0x3b80f30e,
+ 0x6139343f, 0x271dceb4, 0xd1bd8086, 0x04dbe5b9, 0xba5defc8, 0x73c61a63,
+ 0x4dcb6e96, 0x05e26124, 0xeb74094a, 0xb21e43eb, 0x0dcd5f1e, 0x73ff98cd,
+ 0xe41be286, 0xb17f3043, 0x83e59cbe, 0xe2de783a, 0xdef9f0e6, 0x1b14f23d,
+ 0x193f5d66, 0xb30362e4, 0xaf9a2e0b, 0xf1e28078, 0x6fe03ef2, 0x4f2e6af3,
+ 0x0cefe3c2, 0x54f141fc, 0x57cda913, 0xe161b2fc, 0xb6819e6f, 0xf35eb886,
+ 0x807dfd15, 0x3e4f929b, 0x58f5d22b, 0xd6cdf024, 0x287e63df, 0x01cf2de0,
+ 0x21cbf9f2, 0x293e1710, 0x10fe3007, 0xefc261d8, 0x1c774b2c, 0xdce9fe42,
+ 0xb5f31fb6, 0xeeebcf09, 0xcb1fc124, 0x9eb1e5c3, 0x96560dca, 0x0fe1c8e7,
+ 0x1b0e9079, 0x8ef9e73e, 0x3c958e8c, 0x1ff2dec8, 0xf853225b, 0x4f2c2a7d,
+ 0xc7c37cb3, 0x8430af3c, 0xe002612f, 0x7982fda9, 0xec1c0aa5, 0xd42b8700,
+ 0xf3e1bcf9, 0xdf79834c, 0x3f805f1c, 0x7cc1d390, 0x041f5a5d, 0xe13e9bf9,
+ 0x0f230910, 0x3cb3d73a, 0xfc394ee0, 0x7e4accf7, 0x4f9eb36f, 0xebcb7d7d,
+ 0xbffad8bd, 0x221a7c2f, 0x1eae381d, 0xc3e71d4e, 0x9ce3f1cb, 0xf7f07fef,
+ 0xfe826521, 0x81cf93fb, 0xda1bcb1e, 0x899f788d, 0xfdf13fe2, 0x5a78f076,
+ 0xf31126c7, 0x9bea6b3e, 0xe5eb8e51, 0x273f0545, 0x1bf7afd1, 0x468adebe,
+ 0xb63a27a6, 0x3a167d5a, 0xaf5bc74e, 0x6c573d21, 0xd3bcc76e, 0x18af75bd,
+ 0xcbe754db, 0xaa7c27a0, 0xbcbc77f5, 0x6dca0c6b, 0x7e98bf7e, 0x9b14631e,
+ 0xfc29b2a7, 0xcf9b953c, 0xec59e66a, 0x2dda37ad, 0xb4ef9f17, 0xc609bae4,
+ 0xeccadd3b, 0xe2f5d3a5, 0xf9985f0c, 0x49bd714f, 0x0f3b2d48, 0xef12faa5,
+ 0x7bb2b359, 0x245b44d5, 0xad4b5fda, 0xf7470e13, 0x7988d283, 0x79aa2b2f,
+ 0xce7dcc9e, 0x0af7c024, 0xd604d5eb, 0xabe012bb, 0xbb65e3f2, 0x26dd809b,
+ 0xa867e527, 0xf59459cf, 0x8819fb1b, 0xa5ff854f, 0xe08919d6, 0x3bc9127f,
+ 0x5d71d608, 0xe812d7ca, 0x8b0f56bf, 0x47f393df, 0x56f3c187, 0x8e27bec9,
+ 0x553adb8e, 0xb5e84270, 0x34fbdd27, 0x2e998671, 0xf8b17ded, 0x5fdd1c0d,
+ 0xf680d3b7, 0xb7e0d5a0, 0x1ac42ed3, 0x0e849ad1, 0xa43883ac, 0x0214fc04,
+ 0xf41e21f3, 0xfdc16798, 0xcd4236c8, 0x94e7e853, 0x449ff734, 0xf774904f,
+ 0xc30390a1, 0x385abd28, 0x39712abd, 0x8e9bfb2b, 0xacf786db, 0x6a91a4c4,
+ 0x5635df20, 0x4f0dda37, 0xe869fbf0, 0x41e4246f, 0xa74892c4, 0x3a26fefa,
+ 0x38fbe6af, 0x1ea6af3a, 0xe3d6d2e3, 0xc2c74866, 0xbe3897e9, 0x05a2e98e,
+ 0xcd3310e1, 0x796bf8a0, 0xeb4213c3, 0x4e27898e, 0x6b5fb43f, 0x2801efc1,
+ 0xfbd5797b, 0xebb458b0, 0xc8d3eba6, 0x36b4e889, 0x53ad81af, 0x1c4edcf3,
+ 0xa5dfee02, 0xabd74e7d, 0x714617a9, 0x09112779, 0xdcc59de4, 0xbbfc384a,
+ 0x5fbef035, 0x013837da, 0x5fb843f0, 0xcf9025ed, 0x41f7cd12, 0xb7f4d7e7,
+ 0xcd807443, 0x0c871daf, 0x43bfabb2, 0xbfeb9cbd, 0x25fc9651, 0x329e9451,
+ 0x62615687, 0x49125676, 0x9ba5efc3, 0x4a7ca1fa, 0x79839659, 0xa32d4227,
+ 0x086b61ab, 0x00b0cdf2, 0x3fba9bcf, 0x9351ed12, 0xd2237899, 0xe2367be1,
+ 0x1661d395, 0x7043cf1f, 0xa1d0372c, 0xd69455a4, 0x814d7be8, 0x8a42c31c,
+ 0xa2687a84, 0xb94657e3, 0x9f28a3aa, 0x2774ccd6, 0xf6c2c619, 0x3bb95ede,
+ 0x52f6b90b, 0xaa1a0888, 0x1969eef7, 0xef04228c, 0xbdde20f1, 0x6bc6807b,
+ 0xec153a95, 0x6d7f9df0, 0x32eeb064, 0x9b5f7953, 0x3e8feac2, 0xdc2577b4,
+ 0xcf6e9337, 0x49f6147f, 0x7851f6cc, 0xd58fe5de, 0x9bddf3dc, 0x39d6517e,
+ 0x173f8372, 0x3abe05ee, 0x1df5eec0, 0x777e0d6e, 0xa3787a8f, 0xd1fba945,
+ 0xd86fc88f, 0xbcad728f, 0x1bb63f7e, 0xa1cb4ea0, 0x81dcfe71, 0x472f9f74,
+ 0x74969a1d, 0xa1af1d29, 0xd93e0930, 0xd0ea357f, 0x30eef81e, 0x578f8704,
+ 0x82141eee, 0xc3fcb483, 0xd5932d3d, 0x0f70f870, 0x857d21d8, 0x7d0fabc3,
+ 0xebe87088, 0x6c5d29be, 0x935cbc07, 0xd6fbc06d, 0xc16c38ae, 0x45fd0af8,
+ 0xe3e23ea0, 0xbbe5efac, 0xa11fc56c, 0xd354ece3, 0x429ef297, 0x4dd1bd57,
+ 0x628fb12a, 0xe96a6cf7, 0xf5ca2ba7, 0x25abac36, 0x358f75ca, 0xf78ff71e,
+ 0x76e35c00, 0x0b8ea73b, 0xb8b135d1, 0xeefdc1c7, 0x5bf32ca3, 0xf2f254a3,
+ 0x6225ec9a, 0x81c9c40a, 0xfb43e217, 0x8de65f89, 0x19f74118, 0xde6032ef,
+ 0xfb8b28fc, 0x2b63cc20, 0x7721f808, 0x1ee20aec, 0xbe218827, 0xd9abe650,
+ 0x9af5fcc1, 0x396f8342, 0x6015ef3b, 0xb47d10bc, 0xc023e8e9, 0x1db1a3e8,
+ 0xa9a2a3e9, 0x6347d19d, 0x06644e75, 0x3f03373b, 0xc60496bf, 0xa23bde02,
+ 0x51269abe, 0x151a1ffa, 0x91ba01a8, 0xe5a6e7bd, 0x3d708a5d, 0x7c3f161d,
+ 0x7abeca7d, 0x4b6d6fc3, 0xe06943ca, 0xe033ee4f, 0x37029779, 0x858c5fa5,
+ 0x58b6c5e5, 0xfc035fdd, 0xedb4272a, 0x6d6fed85, 0x36f31f79, 0xd86efb6c,
+ 0x66dbef05, 0x42390c53, 0x5beed6f3, 0xd767f78e, 0xd87dd806, 0x05e024d1,
+ 0x3c3bdebd, 0xe104ff18, 0x1a4f7601, 0xf91da3c0, 0x5eff1365, 0x7051ab2c,
+ 0x1a1f9e81, 0x890deec5, 0xebf3b0b4, 0xd7111621, 0xcec2c439, 0xbdf7e259,
+ 0x95bf8225, 0xfb01bf75, 0xa69943c7, 0xbcfdffde, 0xaf89a4bf, 0xe854f82b,
+ 0x28d24a89, 0x4ce47fb8, 0xa2d13b8c, 0xa8d89fa1, 0xca78d514, 0x88788f7b,
+ 0x47aa0ef3, 0xff3dd8af, 0x94abd02e, 0xfc00be7e, 0x968dfb04, 0x4a6e0023,
+ 0x70cfa07f, 0x0defa1f8, 0x1e60f987, 0xecb617b0, 0x3de2225e, 0x6bc47d1a,
+ 0x491bdc26, 0x914667fb, 0xfdf4adaa, 0x425a68cc, 0x13d78e3d, 0x2b207d79,
+ 0x1a713f53, 0x3d7cfa04, 0xb64ebb8f, 0xc931fcf0, 0xd186ea3e, 0x5c766750,
+ 0xea245256, 0xe16f8505, 0xb738080e, 0x75f9f896, 0x00c5204a, 0x58f85378,
+ 0x56fc180a, 0x2452b4aa, 0x18f20187, 0x7dd0f1de, 0x9dcbbd4b, 0xdf652fab,
+ 0xcf9fea71, 0xc1f9ebe4, 0x3d17f5f6, 0x099eefbe, 0xb7372df0, 0xad03723d,
+ 0x0e7a5c57, 0x479707cf, 0xa1795c55, 0xebf42f7b, 0xdbfce77f, 0x4d874051,
+ 0x7ec298df, 0xe1c3550f, 0xc029e2d6, 0xbdf932f7, 0xc951242e, 0xb1e55633,
+ 0xcbb71b42, 0xf8299510, 0xffaced1c, 0xf8081140, 0xf0b14af4, 0x9e32547e,
+ 0xe5d14e1f, 0x9f87fead, 0xc132f9c5, 0x71250030, 0xcf3628c9, 0x324ecc37,
+ 0x9ce0ffd3, 0x173f1a69, 0xaf72477b, 0xdef1d2b0, 0x357cec21, 0x19aaae33,
+ 0xc6c4c4ea, 0xfbda26cf, 0x6b13320a, 0xb8c2c6a7, 0xdf18c9d1, 0xdaeb35ca,
+ 0xc812bd53, 0x8c9a9269, 0x88d38979, 0x7a633eca, 0x08eeed03, 0xe3902eba,
+ 0x742c8cd7, 0xe7ede54e, 0x4d43ffe8, 0x2a99f6e4, 0xc72ae37f, 0x8d54e75c,
+ 0xf78b52fd, 0x9fe9fd01, 0xf2e1ede2, 0xfce33e2c, 0x77c9e2df, 0x1eb3f9c2,
+ 0xe10e399e, 0x27a3ab7e, 0xd470f5dc, 0xab815dc3, 0x9fd98e1e, 0x86c6a738,
+ 0x2e1e9381, 0x48ed48d3, 0xdc0a63d0, 0xc77970f5, 0x9de2e8cc, 0xabde1334,
+ 0xe0c48ef8, 0x23350ef8, 0x9ba41ea1, 0x01ef1168, 0xf5e28cce, 0xbab04737,
+ 0x64a8ef82, 0xae1eb7c4, 0xc666387a, 0x58e3f7f1, 0x2f00bdff, 0xe202e509,
+ 0xcc9ba147, 0x31ddaad4, 0xec507a2a, 0x2e1c69eb, 0xfb46bed4, 0x8ade3739,
+ 0xafb02671, 0xe08425a7, 0xd6ce5b96, 0xf2dc3b95, 0xf4a9f83c, 0x72bfbc75,
+ 0xff3fe10a, 0xca2f3c14, 0xce0555e4, 0xdad1be53, 0xa69ad3c9, 0xc338829f,
+ 0x7efb9350, 0x1080cfa0, 0x1475e783, 0x707447ee, 0xd767bed7, 0xf870f5d6,
+ 0xb131fc03, 0x3a14bc27, 0xe3c2c0fb, 0x20c8034e, 0xbcc797b0, 0xf20d1196,
+ 0x86c5349b, 0x715c4b8d, 0x0e383f38, 0x63a457a7, 0xcf83b881, 0x423fa9ed,
+ 0x5aa3ed8e, 0x36c72552, 0x96d3ee8b, 0x4c729ef8, 0x8e64d3c1, 0xbbc4c987,
+ 0x934be20b, 0xd045f489, 0xed0e481f, 0xe7d95bbf, 0xf6103240, 0xc1c58379,
+ 0x67df3fe4, 0xbcd4df70, 0xf8b3f984, 0x0b6659fc, 0x02435f7e, 0xce104752,
+ 0x91df7829, 0x5a1b18d7, 0x4fbf9287, 0x66115486, 0x7bc3cdcf, 0xc85c29ae,
+ 0x75a15177, 0x8482ac98, 0x75f0fdf7, 0x7b33a99c, 0x5bad8f21, 0x9d814774,
+ 0x1bec21d7, 0xfc93fb83, 0xe9ff4023, 0xee35cfdb, 0xda7680ae, 0xf1fb08af,
+ 0x59162ff5, 0xc3b021fc, 0xb93e7be4, 0xb2953b77, 0x8509ea35, 0xfbe0b37e,
+ 0xde81cbd4, 0xdd6103fd, 0xd1d54053, 0xf659e772, 0x6376431d, 0xecf304ba,
+ 0xff7966e9, 0x8125c439, 0xdfa7ab7d, 0xa1a74bef, 0x08604578, 0x5d8a29f8,
+ 0x1eead536, 0x57cfa569, 0x9b66eff3, 0x05188ece, 0xf4c1f978, 0x4f4b4074,
+ 0xba511d0a, 0xecf00f1a, 0x69fcf8ca, 0xcddfc730, 0x7a009738, 0x43dfb151,
+ 0x026b8a76, 0x3b37a7ac, 0x3dd5897e, 0x3b017ac5, 0x2e67b15e, 0xdd9087e6,
+ 0x74a641d4, 0xcbc71b74, 0xccab733c, 0x600fcdee, 0x48eafdfe, 0x473b5ee5,
+ 0xb791d824, 0x54d94ead, 0xd586e707, 0x6b7efe2c, 0x83f1ac95, 0x86dd90dd,
+ 0x66fbb3ef, 0x6da65f6f, 0xfe604cff, 0xfb57a17e, 0x3412589c, 0x9cf6edf7,
+ 0xc035e0d7, 0x3123c3bc, 0xaf3f413f, 0x79fa7f7e, 0xe6adf3f5, 0x636ad57e,
+ 0xcaa748ed, 0x6560592e, 0xaaf750f6, 0xcae0ebc7, 0xe7e0deba, 0x93480f36,
+ 0xb5abf754, 0x082c8ead, 0x328c6f77, 0x79ef029e, 0x00e2cfc4, 0xc3dff255,
+ 0xe59b83dd, 0xde81f166, 0x98161de6, 0xe1a0768a, 0xf608bf49, 0x4100b0fc,
+ 0xe02b3bfb, 0xf8d02c32, 0xee4fcc01, 0xbdc007e1, 0xd65eb426, 0x01f98bb0,
+ 0x4fe8d5f5, 0x027f5194, 0x387accf4, 0x17c01e9b, 0x41fe8694, 0xfc85dfd0,
+ 0xcfb82ca9, 0x12c3fb92, 0x5ad497a5, 0xf5a37fd6, 0x096ae35d, 0x927755fc,
+ 0xe363294c, 0x98d7efc3, 0x93555fa9, 0xf508224c, 0xf8785eab, 0xc06be9fd,
+ 0x09758e5f, 0xad287f70, 0xf7fa58d7, 0xf8debfdd, 0xb81afef0, 0x65fa946f,
+ 0x7f2aaceb, 0x78fe37b7, 0x0b918c04, 0x3dba47f0, 0xa1f0237f, 0x8a68af12,
+ 0x111f7ce0, 0x8068bba4, 0x57274297, 0x7e8f9b2f, 0xe725c445, 0x589e4087,
+ 0x16ffc716, 0x46c38f2b, 0x129ff7b1, 0xbf905bdd, 0x023f3adf, 0x8cefcbe2,
+ 0x5cfe8a3c, 0xe7c59593, 0xd04a79f7, 0xb9f0527e, 0x3f702acb, 0xf8103fc9,
+ 0xcdf1daed, 0x6497e071, 0x43de02c9, 0x9efb24da, 0x7900cf4c, 0x82bedb34,
+ 0xa26b296e, 0x6b13bf11, 0xbc0ff08a, 0x35a7655b, 0x9b4cfbf1, 0xa81deece,
+ 0x661e63ce, 0x4565ddcd, 0x308bf3fa, 0xeec6567e, 0x7befa0c3, 0xfd212fd3,
+ 0x7f4012e1, 0x13fbf390, 0x61a8fcf0, 0x42e20d8f, 0x827efc1d, 0x09cd0d33,
+ 0xbe5969f3, 0xf0362fe5, 0x70e7ded7, 0xe2b52338, 0xdb654a3d, 0x83ffbc44,
+ 0x0b709bce, 0x161ba7c4, 0xf7efb264, 0x8a6777d8, 0x67ff4cfe, 0x167cc0f3,
+ 0xc8efc434, 0xb2727b14, 0xf583ebd9, 0x188b5535, 0xbbac9e2f, 0xbf0a6c37,
+ 0x5f6f4c37, 0x712ab49e, 0x87cc04e9, 0xf3676a5a, 0x594fc6f4, 0x9f12c4df,
+ 0x24b2df8a, 0xcfeb08bf, 0xc08126fa, 0x5a679715, 0x03c89e52, 0xcec89e3f,
+ 0x44ac30e1, 0xcafda376, 0x6fe89fcf, 0xbe43dc37, 0x6cde5793, 0x4aeb3738,
+ 0xfdfb6624, 0x77600997, 0xe0b1fbb9, 0x8a07d322, 0x1be5377d, 0x6f557c6d,
+ 0x8d34e6e7, 0x41207fbd, 0xa77fb378, 0x55eec022, 0x06ff61eb, 0x7bb587a6,
+ 0xe10c7909, 0xf52dbe90, 0x2947b81a, 0x3b068ffd, 0x7c02dbcc, 0x3cf80f11,
+ 0x54fcf787, 0xd08dff10, 0xda20d15e, 0x927eb0fd, 0x95f01971, 0x70283762,
+ 0x6cdf3c69, 0x91d7431e, 0x5f60d675, 0x3378874e, 0xcffa05f0, 0x2fbcfee3,
+ 0x5357f40e, 0x8273c240, 0xa3bbb3ac, 0x60e4a816, 0x3e0379d3, 0x5bfcf37f,
+ 0xd881e7da, 0x2dbde0cb, 0xef17e606, 0x28f7fbde, 0x9e6f4b90, 0x82f1c6ef,
+ 0xbb4f4376, 0x6b91e118, 0x67718315, 0xc44c5db5, 0xb79003ac, 0xaa9a2d35,
+ 0xbb77a131, 0x7213fb37, 0xb4f495bf, 0x1ec0721f, 0x11d8c311, 0x3e74ce1c,
+ 0x6f48f809, 0xe36e5c57, 0x24c1e6f1, 0x6ca3ee1d, 0x18b71f3c, 0x8a6e1fbf,
+ 0x7d472fb2, 0xaea5eccc, 0xbf1fa7dd, 0x13ef9e06, 0xe711fdd9, 0xb7a7e445,
+ 0xda1e2e76, 0x2a5be2a6, 0x5f4f1139, 0xf9db3ff5, 0xd5ffed06, 0x4716489e,
+ 0xa9979c97, 0xf50877bf, 0xf97871f7, 0x38f3b007, 0xd7b800ef, 0x2fdb07e9,
+ 0xfafc3d1d, 0xc3da1b3c, 0x1ea0e981, 0x376bac46, 0xac5bfe02, 0x90d9d7f9,
+ 0x00a3eadf, 0x33925e2e, 0xf3804c90, 0x7403927a, 0x7626a815, 0xb5b627f0,
+ 0x97800c18, 0x98c98d8c, 0x9f89b3a7, 0xafaa2e57, 0xe8ab2635, 0xef3f1162,
+ 0x877b293a, 0x1f9eaac4, 0x72f931b0, 0x6fe94f72, 0x43e34f30, 0xc61e1913,
+ 0x31b06cde, 0xd18afb7d, 0xe866cd7b, 0xdf80c477, 0xfbdeed0d, 0xcfb85efa,
+ 0xc761d178, 0x3dff8858, 0xbf607362, 0x6a9b7dc6, 0xf1b7cf20, 0x5452d013,
+ 0x14286caf, 0x37de740d, 0xefc58388, 0x1fd0180e, 0x893dc60f, 0xf9f60e2b,
+ 0x1bcf5f10, 0xf9cd062d, 0xdefc1bd8, 0x326d7bdd, 0x89b12fb6, 0x2dadc788,
+ 0x37a07139, 0xbbeeac5a, 0x8e2fa06d, 0x12c0d5b5, 0x629f7894, 0xb03c4daf,
+ 0xf4d19af5, 0x061d89cf, 0x71dba03b, 0xf61179e0, 0x484938eb, 0xd87a408c,
+ 0x8f3c746f, 0x3a37bc7a, 0x1d7478d8, 0x2abf016f, 0xff9aa7f0, 0x7f5a34a1,
+ 0x858a55a3, 0xfe052efc, 0xf9943eca, 0xb5c4f51d, 0xe4ac82de, 0xb8817ada,
+ 0x3a5f92b3, 0x7f944ece, 0xd2e9012f, 0x6a3d7368, 0xda0ef663, 0x30f727d7,
+ 0xae15e8bb, 0xe1524947, 0x829f8050, 0x8b1b7aa7, 0xe9eb2a33, 0xdbdffe6d,
+ 0xca549e98, 0x9bd74bef, 0xe9178764, 0x0fcb1b66, 0xe6fd7877, 0x6b23c854,
+ 0xcf7fc54c, 0xfb679549, 0x93e7a47b, 0x1b057bda, 0xf8060cdb, 0x8762ac0e,
+ 0x6de68310, 0x20ebed1f, 0x48f5499d, 0x09878d7f, 0xdd6971f2, 0x48ee2c9d,
+ 0x7fbf0de5, 0x81d1cf0d, 0x7a79f87f, 0x1396817f, 0x18afd69b, 0xdbf5f088,
+ 0x7042af80, 0x65037ca2, 0xe811ad55, 0x5652d175, 0xe973f316, 0xc8dd6b45,
+ 0x58eb459f, 0x5b1ee17e, 0x0ce7ae32, 0x886257a7, 0x27f9001c, 0x657f0e2e,
+ 0x6e9c79dd, 0xd13c354f, 0xfa52f30c, 0x73e013fa, 0x4f63e352, 0x7a1572c3,
+ 0xc641b53d, 0xb5224a71, 0x7cadf6e7, 0x18076dbc, 0x20dc4fbd, 0x5ffdc0e7,
+ 0x0ec4bd13, 0x3637ec71, 0x7e41146c, 0x9cf401bf, 0xf41cf8cc, 0x0f3dc9ed,
+ 0xf402fd46, 0x4081bb5c, 0x2315fcbc, 0xe2a2d929, 0x5febdd8b, 0x696ff0d5,
+ 0x1835f55d, 0x158b6f97, 0x7c2bce40, 0x15fdc0ab, 0xe42af3a3, 0xfc74ebff,
+ 0x2fbd953f, 0xdfb03b47, 0x9fff9c13, 0x9ff94198, 0x10d98a3e, 0xaf38c023,
+ 0x07dfc318, 0xa40ff5f7, 0x6d5ca0bf, 0xbf5721eb, 0xcdb57266, 0xafe74a96,
+ 0xe31bb6b8, 0x71f5c10c, 0xaa6279ba, 0x02c93742, 0x6296bfc0, 0x8bc01870,
+ 0x99e815c2, 0xdfb7cdda, 0xd95c8690, 0x0f39e122, 0xf9e2473f, 0x0277ca1f,
+ 0xe486bf0a, 0x6eb7c299, 0xd5d83473, 0x8056ab53, 0xe7971f5d, 0x253cfa45,
+ 0x52c687b8, 0xf80a767d, 0x383c8c38, 0x57c7e5c1, 0xf762fbb2, 0x7a000fee,
+ 0x221ea12e, 0x13ac87ec, 0xa51780ec, 0xdd8eb1dd, 0x5a3c3ac3, 0x2bbf9cd0,
+ 0xef0c1ff5, 0x41fb8f40, 0x7c634787, 0x3c84603a, 0xa63e11d5, 0x839088c7,
+ 0x570c40fc, 0x5b3e000f, 0xcdd7f544, 0x4a75fd2a, 0x553a45ae, 0x347970e0,
+ 0xc55f5f93, 0x95ff7db0, 0xe21585d3, 0x2f73aa85, 0x024890ea, 0x605167e3,
+ 0xf8c22e7c, 0xba4cf6a7, 0xdafde90a, 0x076ef4f0, 0xfe162aff, 0x48f5a73d,
+ 0xec33319f, 0x13cb1df8, 0x46223392, 0xb0f91f63, 0x57f1bddc, 0xfd01d7e8,
+ 0x46f7bf02, 0xff4025ff, 0xfbdd0c24, 0xf0abdd28, 0xa501d0a7, 0x55a26b8b,
+ 0x174f41f2, 0x02a379ca, 0xe7745797, 0x33474f95, 0x9780b079, 0x66f25e8e,
+ 0x60fcfd94, 0x81ec9f3c, 0xcf0cf9e7, 0x7c02be21, 0x67e1f22b, 0x3dafe117,
+ 0xaf6c76d1, 0xe60174f9, 0x73f2d4a9, 0x9f3e7aab, 0xd1a5eeb2, 0x4b7ce682,
+ 0xca34ee7f, 0x5a2bbee2, 0x48ea3e77, 0x34c7d10b, 0xd92ecf6e, 0xff73c268,
+ 0x7802d02d, 0xbdfecddb, 0xbb3de56c, 0x0a4f0d44, 0x4cd115ea, 0xe1f42b8e,
+ 0xc3246658, 0x55f2ffa8, 0xc86ee172, 0xab59f9ff, 0xdd346f37, 0x77a316c7,
+ 0x07e8b5f6, 0xf182af38, 0xd833caaf, 0xc6241f21, 0xde201765, 0x7c0a2481,
+ 0x33cd8fb8, 0x1979d52e, 0xe70ec9fa, 0x0f079038, 0xf8297c73, 0x9bd0e055,
+ 0xaf0deb9e, 0xe27c387b, 0x8e5ebb79, 0x9efe7314, 0x5c5dfbc2, 0xe045788e,
+ 0x2f711b27, 0x59fd6117, 0xe505fe4c, 0x73c11648, 0x727597c9, 0x5e9fe5e4,
+ 0x91acbc8e, 0xc2da1323, 0x0bfa11ca, 0x1bf1ffcb, 0x4b1da216, 0x63b7870e,
+ 0x3d334677, 0x93fa0f1c, 0xb2f78bf6, 0x3987def3, 0xc48a52dd, 0x0ddac9bc,
+ 0x5713cc26, 0x366d90e4, 0xaf7f81c9, 0x16fa06d9, 0x1f76cd7a, 0xc5e70c9e,
+ 0x9c074649, 0x03929f5f, 0xd453f788, 0xfa45af01, 0xc7fbc7c8, 0x0223c8c3,
+ 0x47ef12f1, 0x9cefd083, 0x9f213626, 0x5046992c, 0x78deee7f, 0x4955d205,
+ 0x74008a5e, 0x23175a5b, 0x54ec7b40, 0x94e401bb, 0x962b8fb2, 0x71b0c819,
+ 0xd40707c8, 0x6f0ae472, 0xcdbbfe15, 0x49dce343, 0x47210c72, 0x33fb3d1f,
+ 0x8da8bc75, 0x22f1d5d6, 0xfbe07f5a, 0x468e8bc4, 0x78801e07, 0xae6c3fd1,
+ 0x94779876, 0xea28ff25, 0x912ac4b7, 0xc5d6e4a8, 0x4a1fb7ec, 0x2e3c952f,
+ 0x34a95a45, 0x81c4d04e, 0x6073ab6f, 0x582bf81c, 0xe380c54f, 0x7870c34f,
+ 0x7b5846af, 0x1fa3ad9b, 0x13e40b97, 0x97e8f882, 0xfc42255f, 0x063b9145,
+ 0x2fe2ac7b, 0xa197900b, 0x037fdbf0, 0xd7b57d1c, 0x00008000, 0x00088b1f,
+ 0x00000000, 0x7dcdff00, 0xd5947809, 0xe77df0d5, 0x24cb2d9d, 0x7642c993,
+ 0x03bbec26, 0x4eb1ab09, 0x04906008, 0x8d441007, 0xb0900938, 0xd2910364,
+ 0x208196d6, 0x2b188a06, 0x0eb154b5, 0x4551fa14, 0xdb1ab61b, 0x1a4013a0,
+ 0xad563414, 0x61a5afd8, 0x80891d91, 0xe58ad3fd, 0x7bdce73b, 0x264ef333,
+ 0xe79f6a02, 0xcdcf0f0f, 0xcf7bde5d, 0x773dfb3d, 0x79632d49, 0x9b19223b,
+ 0xed50b390, 0xccc9a906, 0x831b163c, 0x43632f1f, 0x087a3e79, 0x6b9859e6,
+ 0xf26b6320, 0x01de7975, 0x9fc75d8c, 0xa269fd3b, 0x678e3e15, 0x30d6fe6c,
+ 0xb53349eb, 0x7fe1d767, 0x268c5d79, 0x649f595f, 0x9fc7d93d, 0x24bf8f9f,
+ 0x4c33ffc1, 0x2b1812cf, 0xe1a7e263, 0x70ffdfcb, 0xdfc7b418, 0x54dec655,
+ 0x805689dd, 0x12dcdca7, 0xd8ceddd5, 0x13c7f933, 0x52d491dc, 0x223ddf87,
+ 0xb97178c6, 0x71debde3, 0x55de798c, 0x0fc816d9, 0x4a3d1936, 0x64e2fc34,
+ 0xe8826b76, 0x06947e0f, 0x041967c5, 0x55437ff9, 0xfe97632c, 0xc5f4a3ad,
+ 0x32f2b89f, 0x7a8afbe0, 0xb439639d, 0x185068ab, 0xd1cc62cb, 0x19cd7995,
+ 0x4785d58c, 0x5fd0620d, 0xa748bece, 0x292fca01, 0x8329af66, 0x870800d1,
+ 0xa23fc241, 0xd41b7d35, 0xd8983757, 0xca5ec86a, 0xe119ac61, 0xd9a23bd5,
+ 0x077e3f00, 0x0fa67e1d, 0x6bca00cc, 0x630b2e1d, 0xff78c29b, 0x7b64c29b,
+ 0xb483347b, 0xecd192db, 0xd7a7c004, 0xf40d1633, 0x6983c481, 0x036e92f6,
+ 0x1f3099f4, 0x8018f33d, 0x3eadd94e, 0xadd2f115, 0x9163aed5, 0xadf471fe,
+ 0x4ddbe68c, 0x6039d76f, 0xf7813afc, 0x543b4d9d, 0xd873e03d, 0x156ada98,
+ 0xf728d2d2, 0xa8f3c458, 0x2c6aaaec, 0xa8f7cd8f, 0xa59f686e, 0x00b3ed54,
+ 0xe678d85e, 0xcce502d8, 0x848f8307, 0x18d616fa, 0x2398d905, 0x2828ce2d,
+ 0xd9c6751f, 0x1de60038, 0xf60a62ed, 0x1a32d8c7, 0xcba45fbf, 0x38b2fd85,
+ 0xfd0052a7, 0x2307fb0c, 0x767ec8bc, 0xec568d36, 0xf35c6f00, 0xc01ec518,
+ 0xe24d305f, 0xfeccf5ab, 0x73d7ec53, 0xba40e748, 0x7398ebda, 0xfaefb423,
+ 0x2c31bf72, 0xd2bedfca, 0xb778d0aa, 0x46b9ddbb, 0xd879f346, 0x9c8fdf0a,
+ 0x0067ddee, 0xf1cf8678, 0x03da33ec, 0x519733e6, 0x1e2d297f, 0x11d2479a,
+ 0x8ba60e77, 0xcfd4312d, 0xc6be33a8, 0x4baed001, 0xca07cc15, 0x543f9ad3,
+ 0x5569af10, 0x71d20acd, 0x825ed367, 0x3f79b537, 0xea11814f, 0x7201dd20,
+ 0x8f301755, 0xcd1d16c5, 0xa145b163, 0x99c5e574, 0x7fa82e89, 0x6c5eeac4,
+ 0xc79fea19, 0x62771cca, 0xbebff415, 0x7cfb5ba9, 0xb7bc027b, 0x278867c1,
+ 0xab72dfd9, 0xb269fa91, 0xf3847fb8, 0x72de9cab, 0x476f7900, 0x48a39fd3,
+ 0x88e21a2e, 0x8e8709be, 0x96123d13, 0x78a0ce00, 0x0a85a1fd, 0x85f5aa83,
+ 0x23a53340, 0xddb8279e, 0x8899318e, 0xf89f806f, 0x09311ac7, 0x8c62f2f8,
+ 0x91c706bb, 0xd91427ed, 0xb45f5022, 0xcf77c5e7, 0x598e652e, 0xfbcf003d,
+ 0x6eb2778b, 0x12f77748, 0xbb7b7ba4, 0x21878f81, 0xb38b313f, 0xa4bbfb16,
+ 0xce38e9b0, 0xf942984b, 0x979e064b, 0x95abfaf8, 0xeb11ebe3, 0x7896c5a4,
+ 0xf02b278e, 0xbc614bf1, 0x7a1eb05d, 0xb3bfcad7, 0xcd617e0b, 0x1e705f9c,
+ 0xbb64bfa8, 0xdbdfa2dd, 0x3d5cee9d, 0x08cd93e7, 0xde11c8e7, 0xc3b7c87d,
+ 0x90fb3cf3, 0xe098d3ff, 0x27ce3c93, 0xcfbefcc1, 0x467ea36a, 0x8865699d,
+ 0xb9852cf7, 0xd32ee902, 0xa1ae10d7, 0x89a3dfc8, 0xb61e407f, 0x52c378e3,
+ 0x800354aa, 0x13acc712, 0xdec67758, 0x5da9dab6, 0x3ee708e6, 0xd3ab37e4,
+ 0x207cf245, 0x2be54ac2, 0xc07f3833, 0xfc407ff7, 0x2ed3cb05, 0x7e01a394,
+ 0x7e438a39, 0x8fc8ec8c, 0xbcf013bf, 0x63a5e42d, 0x613feeff, 0x3acd71ff,
+ 0x0c9d02a7, 0x65e9123f, 0xa2f874d0, 0x8fe1152a, 0x00ffc063, 0x358e6da0,
+ 0xa52ce507, 0x5d20a1cc, 0x875c229b, 0x230fd4ad, 0x4732b9bd, 0xef86ade7,
+ 0x893b46e6, 0x3ed8df7e, 0x366667ec, 0xc01f6fcc, 0xe115fc1e, 0xb6b07b03,
+ 0x6ff4f508, 0x3d4469ff, 0xd7f2976a, 0x38a22434, 0x48ae3f80, 0xf7a7e0bd,
+ 0x410bd271, 0x73d60ef4, 0xebf6f4c1, 0x039ead05, 0xf4e05d7c, 0x9f226770,
+ 0x522f35c5, 0xead07eb9, 0xd1e8ceb5, 0x3a083f41, 0x7e708a5c, 0x0c5cf881,
+ 0x7ae38832, 0x583eb346, 0x0e1d99de, 0x76a4898b, 0x1c3b45ff, 0xd1df1316,
+ 0xadcceb0e, 0x47c01507, 0x576a8379, 0x8fd50a61, 0xff489cd9, 0x8714eb17,
+ 0x41a4e509, 0x71787e25, 0x4bd93865, 0xbb67ef09, 0xdbb107a3, 0xcff21520,
+ 0x8ec9dddc, 0xf188c656, 0xf18790ed, 0xd679592f, 0xc5277568, 0x1793e804,
+ 0x4308be1b, 0x644ff73c, 0x62c64e03, 0x0ed6a70b, 0xf0290883, 0x537f09bd,
+ 0x6b83af10, 0x69ac1454, 0x95269dee, 0xfb1dd6e8, 0xfe5ace1b, 0xbd700d9c,
+ 0xceb46dbc, 0xf537c81d, 0x05ec6757, 0xb8232bf8, 0xf7b4be5d, 0x33e42f5a,
+ 0x92f77f59, 0x3f7bd262, 0x13192b07, 0xeedf1fa0, 0x61eb8273, 0xd53d6856,
+ 0x2a76871f, 0x850023d7, 0x7a3ee651, 0x70d427f4, 0x27f5aa87, 0x7baa3988,
+ 0x7f107e02, 0xbf84e18d, 0x77209eea, 0x48e70419, 0xc5bf7fec, 0xfca092c8,
+ 0xb623c80a, 0x037f7093, 0xe2074778, 0xaa6f0fd1, 0xe08454f5, 0x5f0fd50b,
+ 0x0e905d3b, 0xd16abfd0, 0xb12e3cd3, 0xb3d20770, 0x4864e8ce, 0xe151cf7f,
+ 0x55ba081f, 0xd4bb9e08, 0x1b88f430, 0x91e2f7e6, 0x7f7e0754, 0x984afea9,
+ 0x46fd122e, 0x979c14f7, 0x851ad69a, 0xc35f70f6, 0x032dbe95, 0xc54dbf48,
+ 0x4e872bf2, 0xbe03dcd8, 0x8466fcd1, 0x7e7687a6, 0x9ac8fa95, 0x6150ff40,
+ 0x7cc17e7c, 0xfe3434a4, 0xf244194b, 0x7a1f50c7, 0x1ab799d2, 0xa072bde6,
+ 0x997ba7e0, 0x983ee51d, 0xabab46de, 0x6e402622, 0xaaed15ff, 0x9c70b842,
+ 0xcf342194, 0x741f9885, 0x41a66678, 0xc31bf387, 0x7f4a6ed0, 0xb0effd0f,
+ 0x4eff7e21, 0xfe7dafce, 0x3a0daf3d, 0x3fbe68c4, 0xf80071c6, 0xaf803ae5,
+ 0xeac18c12, 0xfb79c08c, 0x62e51e88, 0x48e6e57e, 0x61f30a9f, 0x5a170cbb,
+ 0xd6e81ea4, 0x4fa07e11, 0x19e7c20d, 0x46e238ed, 0xd235fefa, 0xd1f88d51,
+ 0x5fd15b37, 0xc6acf985, 0x28a2367a, 0x2fdfe711, 0xf505b9d2, 0x18cb4bfc,
+ 0x57a5f3f1, 0x4c137798, 0x1d7efb76, 0xd646cbf1, 0x9fbef88f, 0x570cf2ee,
+ 0x3af3c924, 0xb9ab3b84, 0xb77a8756, 0x43aed7a7, 0xb9b7da7d, 0x3e23a74e,
+ 0x8622ff70, 0x5799e4fc, 0xff5f00f4, 0x37ea556d, 0x686f07e4, 0xaf40ef7e,
+ 0x92f481cd, 0x7c16cb78, 0x43788d90, 0xbfaad083, 0xe3f662d0, 0x52c3e80d,
+ 0x63fb1d6c, 0xf11d25ac, 0xe9faf8d4, 0x5fd02d5e, 0x67a71bc5, 0xfe2a5e20,
+ 0x18262260, 0xd1be87f3, 0xe59fefc8, 0x2e67f684, 0xe872ad2c, 0x257a9fc1,
+ 0x85d91ba6, 0x446cd632, 0x6ebca13f, 0xa01f4381, 0x76ffa5cf, 0x8f9cd0c8,
+ 0xaa1a1ffd, 0xe78065b2, 0x5de18e2b, 0xd13b0858, 0xbfa12fee, 0x472fb006,
+ 0xafcf11d8, 0xff734567, 0x20f646d1, 0xa5a1fdb8, 0x7a631c73, 0xa1dfde74,
+ 0xbdd361c1, 0x907e7df0, 0x8634741f, 0x18b6b5db, 0x2141876e, 0x8bce113b,
+ 0x3d78b7bf, 0xc8717450, 0xfd0c5147, 0x641f5dcc, 0x2e8f807a, 0xfe47e6b2,
+ 0x35767288, 0xf971d692, 0x5cca3f83, 0xe5cbf166, 0xdcf8231d, 0x70ed78ef,
+ 0xe7da1d94, 0xe717df6f, 0x1ddfc009, 0x9db57f4c, 0x5c7033af, 0x7d33e346,
+ 0x07a42f4b, 0x04d9e3fb, 0xaff9a43b, 0xf9c715bf, 0x74874120, 0xdbf4245e,
+ 0xc028b0ef, 0x525fcedf, 0xf3247c41, 0xe6666de5, 0xebc80d8d, 0x04b88d9b,
+ 0x648b6f2e, 0x37b7685e, 0x7a4712c6, 0xa3259926, 0x5f14e99e, 0xe0cf8937,
+ 0x43cf8972, 0xa3a6cf83, 0x2759f15f, 0x1b6f70fe, 0xf7ced76f, 0xd74fc14b,
+ 0x7ceff3fb, 0x0aec3ea5, 0x8d845df1, 0x638ae9d3, 0xf7f41764, 0x1ebe8df2,
+ 0xe4ed10d6, 0x4f1832fa, 0x8d2b5f6f, 0xdf7f7ec0, 0x050bca66, 0xfba6de97,
+ 0x21ca7e76, 0x1fc02a80, 0x53baa6dc, 0x9c1fc26d, 0xbe8af90c, 0xbad1c657,
+ 0xd08bf25a, 0x4f30777b, 0x306fca23, 0xf77a487f, 0xfadd01b0, 0x296672a3,
+ 0x318bb748, 0x4237ce76, 0x047ca41e, 0x9d3831e3, 0x50ee6460, 0x62af80eb,
+ 0x98c35e24, 0x23e1f407, 0xdf640d1b, 0xf8fb5f0f, 0xf7e04cde, 0xd60c1bd3,
+ 0x9ce430e5, 0x3ea5f617, 0x0673f503, 0xe40aac9b, 0x3d7ddb4f, 0x5f4bee50,
+ 0x0fc85d50, 0x923c37a7, 0xf3d21330, 0x0065bf20, 0x0346e947, 0xf8d9cf95,
+ 0x159f9528, 0x42fa5d72, 0x97d47f7c, 0x4eaff787, 0xf9ce3a40, 0x486989ea,
+ 0x6b46ed97, 0x9690c1ff, 0x631c536d, 0x6f3df002, 0xbf269873, 0xe0e6c75d,
+ 0x995d243c, 0x47af6ee2, 0xa6d53f13, 0x1f7176fb, 0x04dfd69f, 0xa0aa72ff,
+ 0x3029c4e3, 0x57a18aef, 0x77dfafc8, 0xc9ec9c20, 0xf92a919b, 0xffc1be8f,
+ 0x20db9def, 0xde95fb9f, 0xa09dbe41, 0x674158f3, 0xb7a45cb0, 0x9f3ccc4b,
+ 0xfc9ebafb, 0x4a8b5ccf, 0x91f686f8, 0x7bfea163, 0xf40fbda2, 0x5321ca2c,
+ 0x848dd7b3, 0x0da36376, 0xf7d0ed0c, 0x19f2f37c, 0xdb3bc9d8, 0x025bc7f4,
+ 0xd59a33e6, 0x387f41f6, 0xca821987, 0xcf2c7a9d, 0xc7cb6b35, 0x2cfbb8f6,
+ 0xad630ffa, 0x77c972da, 0xfab4d88f, 0x7381df62, 0xf3009b3f, 0x92a4392b,
+ 0x7d237cff, 0xafc22efc, 0x5dbf3a47, 0x3bbe0db8, 0xf872b02c, 0x4915e9da,
+ 0x142357c8, 0xd3acf186, 0xe3cb42d7, 0x665ea41f, 0x7e3edf40, 0xe63816fa,
+ 0xdc51e7b6, 0xa0b119ef, 0xdff08f3d, 0x7afb1ebc, 0x8d9b753d, 0xed8233c7,
+ 0xfcdcb046, 0xfe46ecb7, 0x3dd2b7e0, 0x837f4a16, 0x5ced85e9, 0x89eb06ef,
+ 0xe1213b60, 0xbcb7860a, 0x0fb1a74d, 0x191ea15f, 0x8c27681a, 0xc3be2764,
+ 0x6d8370f5, 0x30f5c768, 0x2f8431f8, 0xad3d30cf, 0x6adfc1c3, 0x220376c4,
+ 0x0039b1ed, 0xb76b0ad2, 0x167fb208, 0x405b7ef7, 0xb6ffaa1c, 0x8dea1d5a,
+ 0x418cf8f6, 0xeb91a71b, 0x9d8477d5, 0x1cfa13a8, 0xceb4abd6, 0x4eee18df,
+ 0xc9b8e3d4, 0x8c96c746, 0x48f9f88e, 0xcfccefb4, 0xbeac7e95, 0x8fb1fb86,
+ 0x389a5d58, 0xa893eb19, 0x5fa2fb89, 0xd9edf28e, 0xfcf34e1b, 0x420d7154,
+ 0xe733d439, 0xf4016ddf, 0xf87036a9, 0x8f89e183, 0x319276e5, 0xb207f917,
+ 0xd0e8f67c, 0xd5895c7a, 0x679cfb53, 0xff474fef, 0x07c6d3ed, 0x7ebf51d2,
+ 0xede7141a, 0x169e1e4c, 0xb0a4faf2, 0x2e223123, 0x11ca14f0, 0x9dda41e4,
+ 0x55fbe1db, 0x57245d4b, 0x9d3a5d3f, 0x2e9667d2, 0xb613faa1, 0x9adf1a0c,
+ 0x775767f3, 0x35c9d3c0, 0xd989d92a, 0x18af5746, 0x59a4eef8, 0x1385f147,
+ 0xbb799155, 0xd19cb122, 0xb3f6727a, 0x0278b613, 0x6c277ee2, 0x6743a27a,
+ 0xfd8f8cf3, 0x9cbdfa66, 0xbda144b5, 0x23d7e76a, 0x2db5ec1d, 0xac7fe316,
+ 0x55db0125, 0xb6bdcd2a, 0xb7c71d29, 0x2c7c6732, 0xf59197f2, 0x0ba9b947,
+ 0xb828f6e7, 0xe72c4a5d, 0x1fa1bfc3, 0x8a7efd0b, 0x9e842b76, 0x2f3a0bb1,
+ 0xb1ed38b4, 0xc922efa4, 0x81b8275f, 0x728cbe5f, 0x60b84776, 0xd313d65d,
+ 0x7c785d61, 0x2ac5b16e, 0xf0a9c3f8, 0x5fab8e75, 0x5bf8886c, 0x609ef167,
+ 0x7811de38, 0xc9038e0d, 0x8681c654, 0xbcf9f2c6, 0xe26ab36d, 0x0eff1842,
+ 0x79f9ff15, 0x1ba3d72c, 0x2a3c5bc3, 0x7c03c3ca, 0xdb25de3d, 0x2b7c60a3,
+ 0x0736bf25, 0xc5775fe3, 0x2da5b8f2, 0xeb889dcf, 0xa344e4f6, 0x3736e303,
+ 0xea038f2b, 0xc05f7c9c, 0xd63823ad, 0x7ac27b37, 0xcd095c01, 0xa4231cee,
+ 0x0d317153, 0xaac2edf8, 0xa0dd2196, 0x6b23211d, 0x9157b87f, 0x92686c8b,
+ 0x4028f429, 0x6772861a, 0x454f728c, 0x559b0cba, 0xfa718d55, 0xffbe3294,
+ 0x77715670, 0x9c9f01b5, 0xa43c2b7d, 0xe8225c3f, 0xc9d194cf, 0x36b3fa68,
+ 0xacae081b, 0x819f3fcd, 0xf9b59f7c, 0xa012bd2e, 0x1ac79687, 0xdf67fe68,
+ 0xe295d79a, 0x58989f16, 0xea7a10cf, 0x1e5f8287, 0x69d87410, 0x8b7fcd0c,
+ 0xac6fbb45, 0x55405bcf, 0xe2f9f569, 0x5b3880d8, 0xd265f945, 0xed6393e7,
+ 0xfaf3ce34, 0x80c903ba, 0x3167e7cf, 0xe68a0787, 0xf148dd6d, 0xbac69dd7,
+ 0xe4efb8f1, 0xa431d0a9, 0x7f03fefb, 0x7e8c9038, 0x60fb2ce4, 0xbfda23f4,
+ 0x4ad2f43f, 0x0e7e7f2c, 0x4ff88c1b, 0x60ad3ef2, 0x619fe63c, 0x7faf84b5,
+ 0x65b1316e, 0xbf7db718, 0x210ffc6e, 0xc74cbebf, 0xcf04bf50, 0xe832461b,
+ 0x19f53112, 0xfd382374, 0xba4a0f51, 0x91190303, 0x886e921e, 0xee90edbf,
+ 0xc11af2df, 0x2a9ae12f, 0xb6f3dee2, 0x7c8f1f6e, 0x53665c92, 0xe1204e30,
+ 0x793d91ba, 0xd9dbf631, 0x0ed0ef93, 0x221b12bf, 0x0ec21d2e, 0x610d88ef,
+ 0x2fed8387, 0x637738b3, 0xe1d91bbb, 0x36ff82e1, 0x7fed06c6, 0x08597ee0,
+ 0xed8d0dba, 0x1fdf0f10, 0xe3ff621b, 0xdef0f146, 0x43ff72b1, 0xc97f0f1b,
+ 0xad6ff5c8, 0x293c3d8d, 0x1374bc84, 0xb5d6ebe3, 0xc67ed11a, 0xf5212835,
+ 0x518b62d9, 0x1c7e1fee, 0x125fb01b, 0xe0438fac, 0xefb628f7, 0x17b7cdbb,
+ 0xe9890d5b, 0x5bee8111, 0xdeb0ebbf, 0x29ce310d, 0x22fb3f81, 0xf6a6fb46,
+ 0x0afa462a, 0x141e5ef2, 0x371429f4, 0x934f38b0, 0xbec1badd, 0x1cd69dd5,
+ 0x3ee483f2, 0xd6ab54d5, 0x938b8c4f, 0x239f9ced, 0xd89d699c, 0x3c097f89,
+ 0x70dbfcc1, 0x4c45b8dc, 0xf7231fb3, 0x3caae261, 0xcd0b318a, 0x6af8a311,
+ 0x32f758d7, 0x1d6bb403, 0x209b1cc9, 0xcd685d1f, 0x9b6a7d41, 0xfdc468e3,
+ 0x7917959a, 0x02e57e3c, 0xfd4e5de6, 0x7732f9f0, 0x17ca2f37, 0x2e302dd2,
+ 0xe1c71110, 0x72e38888, 0x1cd27606, 0x8f0ae1c7, 0x9293b00b, 0x3e75ba1e,
+ 0x1adae895, 0xd0054eda, 0x77df46d5, 0x50efd742, 0x3771ed2e, 0x8cf71fe7,
+ 0x19be05bb, 0x7c737718, 0x4b4c14f3, 0x8f04dfec, 0x0ff38997, 0x2cf80f1e,
+ 0xf826ee2b, 0xee2deaec, 0x50881e8f, 0xa5dc5dbe, 0xc4275e23, 0x6b77d085,
+ 0x487d75f2, 0x4770b35f, 0x233abb28, 0x7dbff22e, 0xa086645e, 0x179d2df7,
+ 0x2d27f179, 0xdcb3a446, 0x06f090f7, 0xe591139f, 0x264a0d15, 0xf6733fae,
+ 0xc075a35d, 0xd37fc6a5, 0x79e3a03a, 0x42ee3e0f, 0x678003e4, 0xcea03aac,
+ 0x7977f207, 0xea56919b, 0x22ffb32a, 0x4df6e31b, 0x53b5e606, 0xefb6337b,
+ 0x7efb78c7, 0x633656db, 0xd31faadc, 0x547ac47b, 0xa8fdceb9, 0x7ee39468,
+ 0x8d5b2a4d, 0xbebcadf9, 0x6197998a, 0x847a3a5c, 0xf003d98e, 0x670ce319,
+ 0xc67c00f6, 0x7934d9e6, 0x2f9e4eb9, 0x25778dc6, 0x32efbe6b, 0x7da69bbd,
+ 0xa69fbb92, 0x10ce653e, 0x6aad3e4d, 0x577da694, 0xf981cfb0, 0x9addcf0c,
+ 0x266bddf6, 0x6b3df26b, 0x3fb4d01f, 0xcd9eaacd, 0x9c7a79c6, 0xce003dcd,
+ 0xdece0259, 0xdf358beb, 0x0dd5d7f5, 0xf920a1f3, 0xffee1f14, 0x326c16cd,
+ 0xfa73c44b, 0xfa69e77a, 0x5e6aff3d, 0x9df80293, 0x19386b5d, 0x7c219f18,
+ 0xea4b7e00, 0x8c1cf615, 0x5b5eba5b, 0xe9e1a73f, 0xce902995, 0xe7cb6af5,
+ 0x829cbee1, 0xdf2dadfc, 0x823d73ad, 0x71ed9deb, 0xe228ce22, 0x7f03ac3d,
+ 0x97b8d244, 0x9778f037, 0xc41de9ea, 0xb13a5a1f, 0x762fc96f, 0x44a62fc1,
+ 0xd984bf2d, 0x7a52fcb5, 0x1f30e770, 0x88ff88eb, 0xe47c413e, 0x78017f81,
+ 0xf895f897, 0x7cb438b7, 0x9de15df5, 0xdb91af31, 0x3ff96d0d, 0xb5f1b4e2,
+ 0xe3ee917e, 0xd4aeb7a8, 0xbf71522f, 0x7df1e58d, 0x57f52bfb, 0x6bb21d07,
+ 0xdb3ad7f6, 0x17173a4f, 0xfb175718, 0x3f709749, 0x137636f1, 0xfefb89fb,
+ 0xd900f885, 0x1f801b77, 0xb98708d8, 0xcc30ff7d, 0xac147fbf, 0x760a6537,
+ 0xb238cbe3, 0xd77dfe27, 0x587af86a, 0x085c5ff4, 0x9387dcaf, 0xf9e472e7,
+ 0xe7c91621, 0x3c01fb29, 0xf143f1a8, 0x022d9ffc, 0xf7dbadd7, 0x96f5a42f,
+ 0xc4c43f3c, 0x7e10bfb9, 0x3aefe93f, 0xfc8935fc, 0x6e78f081, 0x6d3123cf,
+ 0xf9c407f7, 0x3bcf692e, 0xb7ee47eb, 0x7b2a9675, 0x6c3fda55, 0x9b1dc255,
+ 0x5e93d842, 0xfd72dff1, 0x1c43a675, 0xe07c57ba, 0x2bd1ebfa, 0x00aed007,
+ 0xb962fbde, 0x5af602c5, 0x5febdbf1, 0xbf114444, 0xbd541eb6, 0xb2e0a1bd,
+ 0x036d1ed9, 0x6984363c, 0xab4c88ed, 0xf403c9cc, 0x3daf58b1, 0x11f727e7,
+ 0x6367db83, 0x27fd80fb, 0x8fe34ef8, 0xfdc21cac, 0x6e78ecb5, 0xe488bfdf,
+ 0x9114c1fe, 0x175a0caf, 0xbf70d655, 0xe9f8236c, 0x4cfd010d, 0xfb50b789,
+ 0x533911a5, 0xc08e29e2, 0x332bbbd7, 0x5627f214, 0x21f90a2a, 0x5347a267,
+ 0x9cb8b5fd, 0x623fc4c9, 0xbbe8299c, 0x6edaffc1, 0x38bb1e1c, 0x37fb238f,
+ 0xe6f6f3c7, 0x4e94d1f8, 0xb88ab789, 0xf21fb5b3, 0x93846547, 0xa1aa35fa,
+ 0xc7a6a5f7, 0xb5ad79f3, 0x6a27e930, 0x84e3fee2, 0xbf38c4de, 0xf9a3fb89,
+ 0x71fc1363, 0x7f66a67e, 0xf1138c68, 0x773e857d, 0x53ba9ea2, 0x78b3bdd0,
+ 0x758fb3bf, 0x75276e3f, 0x12fbf78c, 0x1dfbc643, 0x0fde28e3, 0x5e71ea5f,
+ 0xa47f71c1, 0x2fcd8443, 0xb7c48f3f, 0xd45483db, 0x7746f54f, 0x5abbae35,
+ 0x0eff8377, 0x2dbc7dc5, 0xf0301fb4, 0xae077750, 0xb06656af, 0xb7e416bd,
+ 0x7fa18c65, 0x5ba2df5f, 0x6bf5061e, 0xf58acc3c, 0x75f03723, 0xbb7ae95b,
+ 0x8069a703, 0x8865b075, 0x8bac1f5f, 0xd7bc218f, 0xc46e4cb7, 0xf73581fd,
+ 0xa19a1b32, 0x1b9b565a, 0x06d0fe85, 0xf8dd7216, 0x09b39094, 0xd4557b39,
+ 0xdfe8f117, 0x53d3a087, 0x0fa04e82, 0x879d22d6, 0xf0afbab7, 0x4fae38fd,
+ 0xfae22548, 0x1bcebf74, 0x373f3d6a, 0xf21d773a, 0xe86f40c1, 0x0b5ac3f5,
+ 0x1175b7e7, 0xdda8e7ae, 0xb5ee7e2e, 0x59dfea54, 0xba07a63a, 0x9d74114f,
+ 0xdf9f81b2, 0x5faed760, 0xc89fa557, 0x7a867fa8, 0x8b5ef4a5, 0xa543e317,
+ 0x821e190d, 0x7a38a5cb, 0x7868bea2, 0xd2f985df, 0xc62b2cac, 0x657f9c23,
+ 0xe43ea9ca, 0xbfae3262, 0xd494ecf4, 0xe3c76427, 0xb269df68, 0x16b5b7e0,
+ 0x0d473f3b, 0xfc008e28, 0xb6586e97, 0x7cefcf17, 0xfb466bf4, 0xd6d4474b,
+ 0x54d9d861, 0x2192ce40, 0x2159ea98, 0xfef82bc5, 0x1fa2bdd5, 0x5c61bfcf,
+ 0xa9dc7fb3, 0x3e69070d, 0x63cc0c47, 0xb4ba3e06, 0xfa3b3ee7, 0xcde32bdb,
+ 0xfb93c714, 0xf75547b2, 0xf48464e3, 0xda0815ad, 0x56110dfd, 0x43fc7f8c,
+ 0x82465df0, 0xc7d21f7b, 0x057c7cbd, 0x6596c1da, 0xa3c474a6, 0x1a92797b,
+ 0xd7ba7007, 0xd1ef342a, 0x788c93cb, 0x8ae6617e, 0x4f50e3c1, 0x95ce610d,
+ 0x2879df18, 0xd3948596, 0x9d7cf1f3, 0x60655c58, 0x849a68c6, 0x172fe311,
+ 0xbf8a146b, 0x015bfee0, 0x988e67d0, 0xf7aaf95f, 0xec3f88a3, 0x1e186ff0,
+ 0x733fe5cb, 0x1e494aaa, 0xe46bcec1, 0x19d58ca7, 0x799fa093, 0xdb39606b,
+ 0xf1fdec8d, 0xc043fe0e, 0x3af2ef79, 0x5b257d6d, 0x7f9d39f3, 0x5befe061,
+ 0xeb682ed0, 0xe8f2953f, 0xaba40e60, 0x8cc5b17b, 0x0b4684e7, 0x51ad14bc,
+ 0x665fa8ac, 0xbf8c68ae, 0x9b33f20f, 0xb4f20754, 0xe8eb0bc4, 0x8f39d3ef,
+ 0x693d4dcb, 0x6ed9703d, 0xdced82ef, 0x2bff5c51, 0x2c70f77a, 0x3dd6287f,
+ 0xadf1d71c, 0x9e18589f, 0x06d6399b, 0x1ec618fe, 0xc5106ccd, 0xd06cac1f,
+ 0x5a3b00a4, 0x6026b064, 0x16c3dfbc, 0xb7be3226, 0x779c0e65, 0xf90d79a5,
+ 0x07e89581, 0x1f91f9f2, 0x672c50f8, 0x15d7d6d5, 0xeac39f3a, 0x9a07e40d,
+ 0xd6781f85, 0xae009b5e, 0x6e3d7317, 0xde2d3920, 0x687e4316, 0x235c8af1,
+ 0xaef16ff2, 0xe043d218, 0x63d87e07, 0xc78e9f98, 0x481e6456, 0xeb8b7e84,
+ 0x96aa1c32, 0xb8ff5a7e, 0x5ba498e6, 0x4b4fbf47, 0xe8a193b7, 0x94d2f406,
+ 0xff0824a7, 0x3d8bd04e, 0x477e4b16, 0x7ab782e1, 0xcb9e019a, 0xee746155,
+ 0x83ff33a8, 0xbed1c6a5, 0xe6175c9e, 0xdfafb725, 0xcafcdf68, 0xb744a19a,
+ 0xfde57a60, 0xb470e667, 0x16afec27, 0xa1ec7a86, 0xc9e1ecee, 0xc2b0fe50,
+ 0xeaa1ebe5, 0xa72879f1, 0x6f5c0959, 0x6614b7be, 0xfdec6468, 0xece666a5,
+ 0x4b07d8c5, 0x68ff94ad, 0x3fe52269, 0xf4a76a5e, 0x287da593, 0x68e2293d,
+ 0x0180ce52, 0x25475f88, 0x951af970, 0x6cdee220, 0x8caa2251, 0x307cffbc,
+ 0xa1c56754, 0x4d8c27d2, 0x271eec63, 0xdfc02320, 0x046f7e99, 0xdf3db912,
+ 0x4b8eb062, 0x9571ff44, 0xd8befa42, 0x3da6bb75, 0x3c4625f8, 0x64facdff,
+ 0x9ce9cbfa, 0x1938dd98, 0xfcfef0f8, 0x69fb4d58, 0xfc9a2935, 0xcd3b04e4,
+ 0x775e527b, 0x8503f94d, 0xa2f935fd, 0x9e024036, 0xf8db302f, 0xb7d8aafe,
+ 0xd7c6cc67, 0xf6de56eb, 0x2ef0d56a, 0xaf7807df, 0x7d50321e, 0x5d243d30,
+ 0x31d7ad67, 0x73368037, 0xfa0dcc3d, 0x933b593d, 0x11fceae4, 0x95fdd90b,
+ 0x1ddf32db, 0xdb63f901, 0x7ebfb40c, 0x5aec456c, 0xb63e3fdc, 0x418a3e2d,
+ 0x32a95eea, 0x7ac1fa1f, 0xe80591ab, 0xcb15dcb7, 0x9156fce8, 0xf940e4d7,
+ 0xf9efda2f, 0xd1dbcc95, 0x5120441f, 0xbd543e3e, 0xe7e8853e, 0x14befc24,
+ 0xf902dde6, 0xf1afa033, 0x16ccf8c8, 0x8519d70e, 0xd9fcc0ad, 0xfaf5bfb0,
+ 0xb171c03e, 0x8744b6a0, 0x50f501eb, 0x1dcbe93c, 0x2dbe432a, 0xfda0605c,
+ 0xa91fb9bb, 0x94cf311b, 0xde9c2921, 0x64479d2a, 0x7fa8992f, 0x021c0ad6,
+ 0xd6fd16ed, 0x77d689b4, 0x0f77e44c, 0xfc16aef4, 0x26747c89, 0x08633986,
+ 0x3de08558, 0x46fc7ef7, 0xd3e3f7ac, 0xfde7083b, 0x32b5dea5, 0x5cebf801,
+ 0xe9107789, 0x49e2c7b5, 0x7ef182ae, 0x96f5c8d2, 0xf140e507, 0x9cbf4beb,
+ 0x9d3e272d, 0x38247069, 0x25655f48, 0xb93abea1, 0x98e740c6, 0x3519de99,
+ 0x3b3fd689, 0x38e58f88, 0x71f6f527, 0x9ac9df08, 0x96fb860c, 0xf2546bc5,
+ 0x78ff9007, 0xffe72f7b, 0x1b3755a7, 0x28d6fd0e, 0x23a5d66e, 0x60b23cdf,
+ 0x9a639d38, 0xc141d621, 0x9033e07a, 0x7f2f7755, 0x7e1ede7e, 0xb56586ce,
+ 0x181defe8, 0x7c158f38, 0xbfde44bc, 0xd650073c, 0xd1474fed, 0xd4dcbee5,
+ 0xf0ed1a3d, 0xe2550fd9, 0x6addb3b3, 0x3d022587, 0x0ef6e82f, 0xcfe43efb,
+ 0xe94e7817, 0xb854ff21, 0xae02677b, 0xd26b7457, 0x3e786e95, 0xdbdac4f6,
+ 0xaf73bbe1, 0xe6241c18, 0x7f49e24b, 0x6e697bcc, 0x8ef3c0d7, 0x2f97f51d,
+ 0x38bfef99, 0xe7c01493, 0x38dd7b7c, 0x775c00eb, 0xe21d84bb, 0xe6e3b1f8,
+ 0xbac5e02a, 0xc343c14e, 0xcb50c4ec, 0x3d773c6a, 0x3024c413, 0xec42784e,
+ 0x7a101f8f, 0x1109fa45, 0xa67e785d, 0x7b37f38e, 0x0dbf2155, 0xbffa347e,
+ 0x944f9c52, 0xebea5f7a, 0xfb4b5632, 0xf81247c1, 0x8ab9c639, 0xe055da97,
+ 0xa8a82ece, 0x420f2b12, 0x79356d97, 0x97d419bd, 0x480fd035, 0xfbe762ee,
+ 0x9e57c643, 0x652db645, 0x417e7ccd, 0xbc19ceed, 0x1d19cd25, 0x75894ded,
+ 0xf51b0ae3, 0xfc60706f, 0x69c854a4, 0xf5e2ad79, 0xdd9079f1, 0xd98af194,
+ 0xdb066ec2, 0x28f60ea7, 0x0ecd0ec8, 0x56acb3b2, 0xde01576b, 0xc2471c48,
+ 0x2ba70c1b, 0x987842c2, 0xbda17007, 0x0f7b712d, 0x15b8244c, 0x03b25007,
+ 0x35cca53c, 0x01e70626, 0x477b3ef5, 0xd5e782f8, 0xcf315e01, 0x1c4bb860,
+ 0xff70fb9f, 0x5187cf18, 0x1e6829bc, 0xfec11e92, 0x894ba49a, 0xa4b7e387,
+ 0x7e7a2141, 0x3207eeda, 0x7e491b8a, 0x9d500581, 0x44d77bf6, 0xeba567d4,
+ 0xf866ff40, 0xd3f247f9, 0x8517563c, 0x7cc152fc, 0xbe50932b, 0x46d3757c,
+ 0xe1bedfa2, 0x49ca237d, 0x53d7cda1, 0x5c288317, 0xb4bcd3fb, 0x1044f580,
+ 0xd7446f9e, 0x9c378a6f, 0xbdc65e95, 0x37b34f00, 0x41b0ceab, 0x1ce2769a,
+ 0x60e48791, 0xc463c78e, 0xb11cc6f8, 0x9c11bfee, 0x6e7e7a95, 0x76f086fc,
+ 0x5b7d27e2, 0x68baf3b8, 0x9fbf62fd, 0x943a33d5, 0xaff76a9e, 0xdffaec82,
+ 0x217e3c0c, 0xbd55f1f5, 0x5025e293, 0x2aaefc2e, 0x079b8f2b, 0x2cb4f1e9,
+ 0xc225e3d2, 0x4e71cbae, 0xf149dfad, 0xf768d9b7, 0x5d3fca03, 0xfee293b7,
+ 0x476657c6, 0x6a7dffa1, 0x78b5ccfd, 0xb6d4ebbe, 0x4be76499, 0xde76939f,
+ 0x1ff40c6d, 0xbd17d772, 0xdfe463f8, 0x9f1461ad, 0x16efd92f, 0xabd01eeb,
+ 0x9ebeced0, 0x8eb651eb, 0xb452d5eb, 0x1ec80387, 0x8b76c6f6, 0x51bddc4b,
+ 0xc9ca020e, 0xe99e2e4e, 0xe81eddfe, 0x11cbf177, 0xc2a10f0e, 0xdf91d3ea,
+ 0x3da1f56e, 0xf1f85f2c, 0x0ee73c51, 0x1fa3fff6, 0xd90ffb48, 0x92f77a8d,
+ 0xc26f282e, 0x1bab97ee, 0x27e8add3, 0x5ff13b08, 0x3439bfc0, 0xfe1087fe,
+ 0x01ff118b, 0x6bc720fb, 0x06679e38, 0x1ac4ffe1, 0xdb95974e, 0xfae147ba,
+ 0x774d78f1, 0x6f8eb3f2, 0x9ff849eb, 0xcff01ab5, 0x3f5a5fe3, 0x8ff006ab,
+ 0x3fc408eb, 0xdfbc5bc0, 0xe0eff02e, 0x78e1aff8, 0x3a786b67, 0x3d9e03ab,
+ 0xf1618e74, 0xf40e4daf, 0xf984ce1b, 0xb33a9fc8, 0x01d5655d, 0x83f4987e,
+ 0xbfb560be, 0xe24d7f42, 0xe6af6e7f, 0x0a7fa841, 0x1453fe9f, 0x76ee61d2,
+ 0x80efa41e, 0x82ece67f, 0xfc7fb8fe, 0x95e9bf76, 0x7e01f12e, 0xa9d24dd3,
+ 0xd918b982, 0x1d3f86c5, 0xe28375c1, 0x786d4f84, 0xd7dc468f, 0xd7ded7a8,
+ 0x851933c0, 0x382f8c36, 0x278466cc, 0x8a1ef835, 0xf91c619b, 0x9f3f3d9f,
+ 0xbce490b1, 0x6dbe7355, 0xba19f322, 0xa758ffa0, 0xf2c6fdd0, 0x39513945,
+ 0x55d4e30c, 0x2ee9c704, 0x78fce68a, 0xff23aab9, 0xfdc8ccb1, 0xf93fb948,
+ 0xde0ff0ae, 0x25d7c2ed, 0xd2b175ef, 0x18c29777, 0x164b81d9, 0x23ef17a3,
+ 0x112a7ac0, 0x31ecf7c7, 0x228edd11, 0xd57f804c, 0x6036e228, 0x1f4f9102,
+ 0x1f4f9c64, 0x38a26c8c, 0x5e54ac39, 0xd0f8bb40, 0xfc839312, 0x8a68b8da,
+ 0xf4203ed7, 0x2b9183dd, 0x1e1f685d, 0x313a348a, 0x783d7e85, 0x1a30ce88,
+ 0x0df18786, 0xafba46c9, 0x796e6853, 0x0fbe9705, 0xd4789e27, 0x06dea00c,
+ 0x55c637ee, 0xd75dd7e0, 0xc5d23b63, 0x9c6d1f4f, 0x743c32a7, 0xe055a3dc,
+ 0x293a714b, 0xbe82639e, 0x2b8e01c3, 0xdcb12f68, 0x9df1e56e, 0x8b27400d,
+ 0xe5c1be9f, 0x03f7c3cc, 0xe35cf0ca, 0x6419c628, 0x935fe104, 0xfaf2332f,
+ 0x26afc4f0, 0xec66cbac, 0x103ecccf, 0x3a8656e9, 0x45f7d704, 0x978c5ed1,
+ 0x25f183df, 0xe27aa61b, 0xe67ac997, 0x26b4f1d1, 0x89cccf12, 0x8144d378,
+ 0x9823a9cf, 0xeef01a2f, 0x778da83b, 0xf9d3e7dd, 0xef7e037a, 0x911afbd1,
+ 0xbb66753f, 0xb8e30ac1, 0xb82194f2, 0x7e5b292e, 0x25a6f073, 0xa5d7f39a,
+ 0xcfc75e42, 0x80feb585, 0x041e21c7, 0xcdbc4561, 0xeafdb3d0, 0x8807ce10,
+ 0xdd9b4a97, 0x2816ed43, 0x71950f14, 0xc1ff4936, 0x1d207dd0, 0x41f0141f,
+ 0xf851353f, 0xbd3431bd, 0xf5ca26fa, 0xabad1d73, 0x9bb90be7, 0x9b6de52f,
+ 0x27c6de56, 0x82bda9da, 0xede0307e, 0x26769141, 0xff44e317, 0x5cb912e3,
+ 0x78e2dd64, 0x9d35b22c, 0x7908b7ce, 0xfef13729, 0x88f7f8e5, 0x8da24c74,
+ 0x00f095fa, 0x7ec71ebf, 0x9001a074, 0x56d64f5f, 0x87347f93, 0x33b5c405,
+ 0x5f24edfc, 0xebb7cc77, 0x4c75dd11, 0x10b3ad8d, 0xc2f7caf5, 0x1f47a81c,
+ 0xacf5d634, 0x4ed8ec8a, 0xb214dbee, 0x3d230366, 0xc261e229, 0x23558cfe,
+ 0xa1407ce9, 0x5e0fefc2, 0x7478b1ca, 0x31a718d1, 0x630b6910, 0xf13f3a14,
+ 0xf27fb137, 0x89e2f450, 0x5185d728, 0x33a63d46, 0xfbf52b58, 0xe8b76b77,
+ 0x33de18fb, 0x0e763156, 0x77c88f03, 0xa8d5b8c2, 0x8d7e7877, 0x4aa29b33,
+ 0x21c77f22, 0xdee1e027, 0xca7f406b, 0x09df2f7f, 0x4b7a5ffd, 0xe93bb3d4,
+ 0x0b8f4bfb, 0xf2e4f63e, 0x7d65cffc, 0x92afcf1e, 0xff3cf9f5, 0xe45feca4,
+ 0x5faa0e9f, 0x4bff5416, 0x3ebc5f9e, 0x7e83df3f, 0xd2ce68eb, 0xd214a385,
+ 0xbe847b53, 0x23ee5c28, 0xf6ea16fc, 0xf33474f2, 0xdc6eb2e9, 0x6ba2536e,
+ 0xd51fda0f, 0xf682d272, 0x2764d5f7, 0x704f9fe5, 0x75c44b2f, 0x63c524d4,
+ 0xa1fb7d44, 0xc4c1ec97, 0xed1fce4e, 0xf8e3c2e9, 0xbfa0929b, 0x05fb7ea1,
+ 0x8c4eacfd, 0x1c7ef5bf, 0x80ae1c49, 0x26f99e7e, 0x23a7fcf0, 0x49be1b3c,
+ 0xb592b33f, 0x487f48fd, 0x86be7549, 0xe32763f3, 0xe645e734, 0x8d11c4ff,
+ 0xe78627f1, 0xf3f50045, 0x67a5d797, 0x5ff3ff42, 0x04bd3d7d, 0xe76125fd,
+ 0xcc74da2b, 0xdb34f789, 0x1be7a518, 0x7de2313f, 0x8d5d8ab3, 0xaed071c6,
+ 0x00dcd212, 0x9c04cab8, 0x93f4e760, 0x8373ec03, 0x3d8c1bd0, 0x5f37f7cd,
+ 0x7a47ab3d, 0x9dd5d7ce, 0xf6ed0e7a, 0x3ee42528, 0xddf166cd, 0x17ce4ed1,
+ 0xe87a15ef, 0x11b39a6a, 0x8c6bf9e7, 0xb73e4021, 0x60fb93ba, 0x855f1c49,
+ 0x1ccdeec2, 0x01db3166, 0xe43f43cf, 0x1b2554fb, 0x3c608632, 0xd184cdf8,
+ 0x6d7e24ef, 0xc795b53c, 0x3c781b53, 0xbcd6d0b5, 0x33379408, 0x31ad9526,
+ 0x84d8c1df, 0x0339485f, 0xf36f8591, 0x9d5f324c, 0xc79b263f, 0x767f30bb,
+ 0x506b63fd, 0xb9c29a6e, 0xf0d0fb1f, 0x17a8e181, 0x7422325a, 0x37e79056,
+ 0x498c8be3, 0x8efcb143, 0x639e5871, 0x222af4b2, 0x8be232fc, 0xc75de337,
+ 0x3db05f90, 0x46dc41c6, 0x307dfc5f, 0x2adbf70f, 0x0f75a79d, 0xda87708a,
+ 0xc087fa77, 0x4ac931ab, 0x19901369, 0x870917fd, 0xf9fc1f1c, 0xdfd0cd45,
+ 0x8349e5c9, 0x9f71db57, 0x3490c725, 0x467e3fd4, 0xe072fb82, 0xac7527f8,
+ 0x6e292e17, 0x024b8e16, 0x5dee030e, 0xd95dbe03, 0xac06732a, 0x898f26f3,
+ 0xcdefe4d0, 0xc0ce658f, 0x29bded38, 0xc2f4fc9a, 0x0ff69aee, 0xa9afeacc,
+ 0x6735302f, 0xb1f80555, 0x1e49fb9d, 0x62d2a782, 0xee7f4709, 0xfc5f0def,
+ 0xfff441e5, 0xf40eab36, 0xd9eee755, 0xa1db97f2, 0x4e3c65d5, 0x3b47f145,
+ 0xc9cecbc5, 0xa77a28f3, 0xe85f703e, 0xf3a66b22, 0x03ed9d3e, 0x7cee75c9,
+ 0x773a7eeb, 0x03ef5df6, 0xeb124af5, 0x086c21dd, 0x55cbc3da, 0xaebc511f,
+ 0xefcf9222, 0x8cc7ebe2, 0xfb8a0fb8, 0xdf81d78a, 0xd10fc2ef, 0x50f36c3f,
+ 0xfeb73b3c, 0x1d9bed18, 0xba7ae448, 0x1e817522, 0x42551def, 0x1c68768a,
+ 0xe068abe8, 0x3646e697, 0xbbee1770, 0x1fb85866, 0xb19936de, 0x1e2be458,
+ 0x884a69df, 0xf3d77ba1, 0xbca8f26b, 0xfa9c2da2, 0x1e6d4f7f, 0x5f09e747,
+ 0xa1ff6853, 0xe5a1e520, 0x29b87e78, 0x11e033dc, 0x77e0b718, 0xde21e577,
+ 0xf3f1762a, 0x9fea05b5, 0x5a4016b3, 0xdf479b56, 0x49aca817, 0x42617f01,
+ 0x05bfb72e, 0xaf21f368, 0x46acb30e, 0x7d1aabbb, 0x3d479ebd, 0x9e90b463,
+ 0x807b6e89, 0x336cafc6, 0x24f7f7d3, 0xd0d77f71, 0xdb1ae1c2, 0xc972a2e6,
+ 0xba93530f, 0x860fd669, 0x7c7acdf8, 0xc2d0c397, 0x6dddfda8, 0xf39528fd,
+ 0xafcfbb7d, 0x21ae3ee9, 0x14b8eafe, 0x71dbf798, 0x90dc958a, 0xa57c3d20,
+ 0x0b34786a, 0xc7daa7a1, 0xf4e7e369, 0xdcfc6d4c, 0x738a615e, 0x31c0127e,
+ 0x3d16b1f1, 0x48b107ee, 0x35f115b3, 0x7b60c471, 0xa97c8049, 0x2237ef7b,
+ 0xdeeb0c7d, 0x369da237, 0x501b9a41, 0x33ce2e5f, 0x05e9eb04, 0x2f4f5249,
+ 0x1dda54a3, 0xf9067576, 0x82ac33a9, 0xccfc8501, 0x7e54fa10, 0x1a6b4cdf,
+ 0x1e6ee3a0, 0xc5347fc7, 0x45f502bd, 0xbe9b0e73, 0x7366f483, 0x7cc3ee3a,
+ 0x9d03f057, 0x89f90acd, 0x751e742d, 0x0ebb08e2, 0x04abffe3, 0x6f8e525c,
+ 0xa2c58f34, 0x5b2a7bfd, 0x77befd82, 0x4ecd9de7, 0x47f1afe8, 0x0f689999,
+ 0x25cfb8e4, 0xcc297bf1, 0xd70d7ada, 0x446f9583, 0x0bde51d8, 0xfb863170,
+ 0xb44c7b9d, 0xda72814e, 0xc37ca8cf, 0x89ef09b4, 0x7ac14654, 0x7dcfc615,
+ 0x7c87cc33, 0x9866f8dc, 0xef46ed1e, 0x4873f774, 0x7b37dccf, 0xa1f5c18f,
+ 0x67a4c1b3, 0x9f38f7e4, 0x09db3d27, 0x5bd237bc, 0xe5267cc1, 0xe5c35dd3,
+ 0x69f048a5, 0xb73f90b1, 0x552ba390, 0xaf0e485d, 0xe340063c, 0xca63e93e,
+ 0x27e85dc0, 0x7ef42dd8, 0x02cb9493, 0x79410f5c, 0x3a18ff41, 0x8dfd2bff,
+ 0x6b2c3960, 0xe5bf52b3, 0xef21766d, 0xb94bca36, 0x6372162b, 0x2cc67e12,
+ 0x53bbe7c1, 0x5e20efdc, 0xee41aa0a, 0x3f1f68a3, 0xcfc9e50b, 0xf22b4637,
+ 0x624df017, 0x54fc8049, 0xd0cfde37, 0xb9c5313f, 0x41666f88, 0xcc9fe81a,
+ 0xac4ff76e, 0xfe0012e3, 0x74322b89, 0x9da9df78, 0xe6f9db7f, 0x8f7ff8e6,
+ 0x48e29790, 0x67f44f5f, 0x0e61550d, 0x397e873c, 0x2cf7ef8e, 0xb8f1c55c,
+ 0x45cae0d0, 0x2fe162ff, 0xa1978a15, 0x697a81df, 0x632a91d8, 0xfee51c60,
+ 0x0ecc41b6, 0xd6d29878, 0x1337d283, 0x0f1147dc, 0x04d36d45, 0xa37d06be,
+ 0x4ea1c5fd, 0x7832471e, 0x198d8e4d, 0xab724718, 0x6933e748, 0xe04cfacc,
+ 0x1d7ade7e, 0xbee4c3c5, 0x992b8ca3, 0x807cbcf0, 0x5f42fd1d, 0x37ef4e9b,
+ 0x7299c704, 0xb0bfddb8, 0xbf7640d9, 0xc3cff1ac, 0x2e7f5074, 0xed05d9c3,
+ 0x777a97c9, 0xbcf5f21b, 0x0d57dec9, 0xe4ff9f90, 0x7691a8ce, 0xf4eb3e3f,
+ 0x47689ebe, 0x188f00eb, 0xa35baaef, 0xbfb979e6, 0xc9f7c113, 0x7e4b7f38,
+ 0x79f3e60e, 0x9f88dd6d, 0xc89954ae, 0xbe015d0e, 0x48760165, 0xe7a91dda,
+ 0x7c91fda5, 0xfae7ae5d, 0xda323cab, 0xb408c9eb, 0x395c933b, 0xf87d77c8,
+ 0xddbf1a79, 0x1476b4d9, 0x38a5c1ca, 0xed28b73a, 0xbc1cb046, 0xd31c14b6,
+ 0x8eed1d5e, 0xcf52ebd4, 0xfa35bb4b, 0xfe772fe5, 0x8a55cd15, 0xe032407b,
+ 0xb73d6eeb, 0x2deb775f, 0xe3633fc4, 0x6f91e926, 0x1e8f5e6e, 0x98f47a13,
+ 0x74568f46, 0x27060762, 0x741c9adf, 0x4cf3ed15, 0x3d447fdc, 0xa3dfd81f,
+ 0xe0c7a329, 0x7327c63c, 0xc15dfb3b, 0x1ffe99dd, 0xfa6b7c9f, 0x88b2587f,
+ 0xff40ddf7, 0xfd732617, 0x99efac1f, 0x73a7bf95, 0x2f5f4f69, 0x0ca383da,
+ 0xc1da03ec, 0x16fb0886, 0x5ec80f61, 0xbf7b4784, 0x4d5c1ece, 0x7888599b,
+ 0x1e0f610a, 0xf616fe4a, 0x94a1f240, 0x5227291b, 0x48e5822e, 0x9f84c5ca,
+ 0xe9113ac2, 0x57bf1ef4, 0x6cf7ae50, 0x7b46fda3, 0xcf9460c4, 0x976e3f76,
+ 0xc1d6f242, 0xf1f9084e, 0x6ed68bcb, 0xf290b948, 0x5ca7e522, 0x20ecc5c8,
+ 0xd6a7d8b9, 0xf70a333d, 0x6bdd92cb, 0x72fde393, 0xd823b652, 0x57ca743e,
+ 0xb3645918, 0xf218aae3, 0x81a43955, 0x44ea657c, 0xbe499e1e, 0xd968bf35,
+ 0x6fd3f24d, 0xf4fcfbfe, 0xe9f84e9b, 0x3f0dbe7f, 0x3f63f475, 0x3c03b2ce,
+ 0xdf40b257, 0x6df9f866, 0xfb8c3bc2, 0x7af9dd0f, 0x0497d600, 0x8d319377,
+ 0xae133ee2, 0x2f8a2ab3, 0x7494be0a, 0x6cc0fe96, 0x93387711, 0xe1077ae2,
+ 0x82c0f5c5, 0x447bd39b, 0xb35c5367, 0xb327d711, 0x03f40d21, 0x9b7ff33a,
+ 0xbdef516f, 0x3e749371, 0xfb9dfc96, 0x4392c78d, 0xb1c78dfb, 0xb5d29bfc,
+ 0xf8899720, 0x300b8fde, 0x29e138de, 0x0acb6791, 0x46d38f10, 0x3c9ffac8,
+ 0xfa81ece9, 0x38b8c981, 0x53de39c5, 0xf4b3de45, 0x3f6818f0, 0x8fe619e1,
+ 0xd8fd439b, 0xb8f6e8ec, 0xedfcc288, 0x3b1fe795, 0x51e886bc, 0xddcce5cb,
+ 0x3ffbe7a2, 0x79059f22, 0x447e404b, 0x6f037e50, 0x616fa51f, 0x9045e781,
+ 0x9c21949f, 0xff00aece, 0x7fdf8601, 0x5585ed05, 0xa8d71861, 0xd6f8db8c,
+ 0xf56bd415, 0xb545ed0a, 0x14d581e3, 0xfbc55338, 0x735f94b9, 0xc23e09d8,
+ 0xbe78bb03, 0x93ed4a4f, 0x37e8bd1e, 0xa1bddce0, 0xb9d2714e, 0xb78a1183,
+ 0x7c47465b, 0xdad149f7, 0x6bd1fc27, 0x1e7867bf, 0x6fbe56ef, 0x8dd6cfbf,
+ 0x6e99f7be, 0xb2fbfc61, 0xfe7f9f43, 0xefe70a5e, 0x21d15931, 0xa8a5c7eb,
+ 0x37111fbc, 0x68a1f1a0, 0x7be85d4a, 0xb8c513b0, 0x425fb8cd, 0x24f6dcf8,
+ 0x28d9b7e2, 0x93f2fdf1, 0x196377c8, 0x60cfc4d3, 0x9fdfca7c, 0x8d4172f2,
+ 0x19d74f9e, 0x9bafaf84, 0xa91480ef, 0xf2f8fdbf, 0xf4cbd104, 0x8476f835,
+ 0xfb5db7c0, 0xe8ebefbd, 0xf7c3ac35, 0x48e76f82, 0xf86a763e, 0x22ef5a3d,
+ 0x538e8cfe, 0x5747e8ac, 0xe0d6c2b8, 0x9f2fc17a, 0x6cbe27bf, 0x1d03fb96,
+ 0x02b5efe4, 0x890abf94, 0x4febcf47, 0x74bafca2, 0x3cb9eded, 0x7335f3b6,
+ 0x52bc01f6, 0x7fbe0fc8, 0x27faf9e4, 0x7c092e31, 0xd794f541, 0x2c1dc007,
+ 0xf941758f, 0x15f920ec, 0x03fa47f2, 0xa9e001ed, 0xb8b7ea27, 0x007b4663,
+ 0xd04cfc9f, 0x27b8a2e9, 0xfb9a3cda, 0x78ddcd93, 0xfb8523ba, 0x7c09cf8f,
+ 0x9bed126e, 0x90f003c3, 0x1f1fe1aa, 0xe6025bae, 0x3fba784d, 0x93fbce4e,
+ 0x63d07c82, 0xbf5e36cd, 0x27a3e52d, 0x7cfed93d, 0xa6af7f70, 0x7880527c,
+ 0xf1fff7f1, 0xee23f461, 0x91db7817, 0x27b0e472, 0xc139d052, 0xf0214eff,
+ 0x5163bd07, 0x74a1fc8e, 0x761f8fe4, 0xd04f4fe4, 0x774ef4f7, 0x3a7bdf67,
+ 0xfa0cef7e, 0xea3de19e, 0xd05eff9b, 0xae883f2d, 0x1d744179, 0x942f9413,
+ 0xff46af79, 0x5c5cbd4a, 0x09e3f4ff, 0x54df1871, 0x9fbf38e8, 0xbd934f9f,
+ 0xfc956f99, 0xf230e67b, 0xcf9f9fab, 0xd7279e12, 0xce79ba09, 0x787a893d,
+ 0x51e1ea12, 0xd414fcfe, 0x5f3f9443, 0x7e61fb80, 0xea81757b, 0xed91abef,
+ 0x7afd922f, 0xefec8560, 0x3a4bca33, 0xb225cf32, 0xbd0bf777, 0xa4ad3cc3,
+ 0xf035e7f7, 0xfe7d3fef, 0x2b5fc3f3, 0x7841b50f, 0xf79410d9, 0x775fb504,
+ 0x22b6fb03, 0x82c7fbe8, 0xe504d7ea, 0x6be507d7, 0xcd17dfb4, 0x8b0e4852,
+ 0xc9fdf046, 0xe60cb960, 0xda522f8f, 0xf6ed63e3, 0xff24895c, 0x1357234e,
+ 0xfafe79aa, 0xa829fff3, 0xa7c80c89, 0xb21e89b0, 0xc05a30ef, 0xb9d041fd,
+ 0xc1f8151e, 0xbcde89d0, 0xecde99d8, 0x79ef6c13, 0xd7f03ffd, 0xd22fda24,
+ 0x54fb25f8, 0x9551be6d, 0xbbbd4770, 0x5f603228, 0xe2265995, 0xfdf3baba,
+ 0x6389889b, 0x22fc0352, 0x6744f84f, 0xfb653cc0, 0x575d5f71, 0xd4f8bc71,
+ 0x719b89f0, 0xd8b4687f, 0x14f1b4d7, 0xf68aa5ec, 0x6fc452ba, 0x5d39e1c6,
+ 0xebee176c, 0x0fd030b9, 0x70bd7562, 0x523f8d9e, 0xd550bbf9, 0x53c01f40,
+ 0x79d3b311, 0xea7899d3, 0x47d43bbe, 0x0df92f47, 0x47efb77c, 0xd3b412ea,
+ 0xd2c49747, 0xa945a639, 0x17dcefdc, 0x366135dd, 0x1e231be4, 0xf8db7d26,
+ 0xf74a58c4, 0xad95ceaa, 0x353ae856, 0x5f646279, 0x3c268fac, 0x4fc43639,
+ 0x9dfc065c, 0x38276a99, 0x426b36dc, 0xabdbfa3d, 0x085fb40d, 0xfc457e2d,
+ 0x3069a4f3, 0x968bb7ae, 0xb0fda7f5, 0x1a4f9fe2, 0x8ab0f787, 0x3ed0371f,
+ 0x4ace8b49, 0xeaf72271, 0x6a2e74b1, 0x7a910ad6, 0xcdf4a2ee, 0x1abafcff,
+ 0xbeb569ef, 0x0efbd0a0, 0x7bad5c77, 0x9b9e1067, 0xf74ee9ac, 0x7580de2e,
+ 0x3efb9e00, 0x17b7bebe, 0x089f21cf, 0xa473a2ab, 0x8bee9ed0, 0xbfb35e95,
+ 0xdb0b313b, 0xd0e5d6ab, 0xa39414fe, 0x956a7cff, 0x41ef09ba, 0xc2594515,
+ 0xa9f6fcf1, 0x75c518af, 0xa26e3d4e, 0x478e2277, 0x8fac67ba, 0xe8b8fba3,
+ 0x8a53b3e9, 0x3c014a3d, 0x67d0da4c, 0x96126262, 0xfb7d049b, 0x1e011544,
+ 0xfced748a, 0x24a4f643, 0xa527e786, 0x05b899f6, 0x97ea71e6, 0xd87ce9bd,
+ 0xe4e754c1, 0x2fd7c054, 0x52539cd2, 0x6e5e11e3, 0x0ffcdeb7, 0xe3fc8fdf,
+ 0xe404e285, 0x395287af, 0x56d1bf5f, 0xbef8109c, 0x3d45c977, 0x469bc1f1,
+ 0x277a22fb, 0xc14d3c30, 0x41f03675, 0x67cdc62c, 0xf00b7589, 0x219d92f3,
+ 0xa9e1abfc, 0xf1abd12a, 0x48d9f1a7, 0x0f5f3f5f, 0x19f5177f, 0x5f2037ad,
+ 0x2d7321b1, 0xa693b9da, 0x0f44ec25, 0x91fe7ed6, 0x3c230bed, 0x7985b619,
+ 0x7e3032c3, 0xfc871cea, 0x7aeb12cd, 0xc804b64d, 0x77ff68a1, 0xfbe73f0f,
+ 0xeb8f6877, 0xfe7bbfbe, 0x9fb812d7, 0x4697db21, 0x5ce83c59, 0xf458b69c,
+ 0xfaa38f48, 0x3cf0a7a5, 0x060bc95a, 0x2f2503b2, 0x8ad63fc4, 0x06f807fa,
+ 0xf3c16be3, 0x81aa63fa, 0x933a31c7, 0xad18cf4b, 0x1331b25c, 0xc99dbe71,
+ 0xdc86cd65, 0x3b239b89, 0x2b52cb97, 0x5ee34fd7, 0x9651efe0, 0x71e8b50e,
+ 0x0bf4737f, 0x7ba16d6f, 0x86c20b74, 0xd289bde0, 0xaf444c17, 0x63c58b16,
+ 0x13ef0dbd, 0x9031f458, 0xedca9b3e, 0x9f90bd69, 0xcde9955c, 0x7ba52843,
+ 0xf0df7212, 0x9e6792ec, 0xe797e3c5, 0x70da7798, 0x2765dfc0, 0xbbcbd3e7,
+ 0x063f8a54, 0x1f9623ef, 0x61cc69dc, 0x788fb137, 0x32c3fd83, 0xdfde22d6,
+ 0xf07dfd0d, 0xa9abe1fe, 0x0687fbc1, 0x2a5e4fba, 0x37730ff6, 0xe9770428,
+ 0x3fcf7e12, 0x8dc79637, 0xfa052e4f, 0x1ede691b, 0x0f3c10eb, 0x294eedcd,
+ 0xf866bc53, 0x0b0daef5, 0x13d98e28, 0x6e7184f1, 0x89e26ef1, 0xae3a4730,
+ 0x085e4bf3, 0xfe96fc23, 0x7e5fee6a, 0xfaf78599, 0xd702e20a, 0x2f91fbd5,
+ 0xde197e38, 0x9cfd941f, 0x7a63f65e, 0x45f731a7, 0x7cc31f58, 0xabd8634a,
+ 0xbd2067f7, 0x9f71d292, 0x5d2bb653, 0xbc5ea3fe, 0x61afac1d, 0x4ab45d1d,
+ 0xecc7efe5, 0x041d9136, 0x01644f59, 0xad672cf7, 0x72346838, 0x8712c63b,
+ 0xeedaff09, 0x1c769fbf, 0x6eeaf1ea, 0x2687b8a5, 0x51ef27f1, 0xfbf8e915,
+ 0x853a8574, 0x268157ee, 0x97497ba3, 0x7b5fb953, 0x679f953a, 0xd0774a28,
+ 0xb5f29cfd, 0x0cf2c726, 0x7dfb4fde, 0x95df584f, 0x684b9aeb, 0x26f7f33f,
+ 0xae54ab8a, 0x45867308, 0x3b17f3f1, 0x6af9d006, 0x51f011bd, 0xe2fae766,
+ 0xa56f98b2, 0x745dd27d, 0x8ecf419f, 0xdcbea1e8, 0x7963f5c2, 0x923de00c,
+ 0x186e8a33, 0xe8c767be, 0x9bf624dc, 0x7c602834, 0x3f439445, 0xbf7f28f6,
+ 0x83563a4d, 0xdf6c1b71, 0x31e21077, 0x8474da76, 0xe49515ef, 0x76b49019,
+ 0xaf7dfa04, 0xdeb899a8, 0x6fb55a2e, 0xf9dfea1c, 0x8de307db, 0xeaf45609,
+ 0xe63f6407, 0x88b7fa0b, 0x90c56773, 0x22b677c7, 0xb93cb8d2, 0x8a2f1e55,
+ 0xef345348, 0xf2fac910, 0xbf1e0655, 0x8a8f3d07, 0xc7d97ca5, 0xa5b96fd4,
+ 0x6ff50139, 0x30c36ef9, 0x6951d3d4, 0x978b2e5c, 0x011f65a5, 0x44362abe,
+ 0x6583bbd3, 0xe623029e, 0xca156acb, 0x4f8bbffb, 0xbf3d3e47, 0xe428b5e2,
+ 0xbe61139f, 0x5a97689e, 0xe8398417, 0xc795a1de, 0xe8afceeb, 0x6695f749,
+ 0xf82d9b59, 0x45acc19e, 0xbfa86ddd, 0x467d5a8f, 0x975a3fac, 0xd3bcc3a1,
+ 0xbcc6cd6a, 0xe51b7f53, 0x2df38bcf, 0xa57c83f4, 0x6d973a70, 0xbfc467db,
+ 0xcc44324f, 0x1f2be2f7, 0x4ff8c2f4, 0x2f737a79, 0x07c02bb4, 0xcf1052bd,
+ 0x9764292f, 0xf3f1b62b, 0x2a0f92ee, 0xee400f90, 0xa83e09e6, 0xf7daf5d8,
+ 0x902a1e51, 0xf23a43fe, 0x7ef3f011, 0x71b1df2a, 0xefdfe31c, 0x76913e47,
+ 0x0c2bf20c, 0xf1df8c36, 0xa71a667c, 0xe18f943f, 0xfc019ee5, 0x39fb5d1c,
+ 0x741c8d04, 0x1a575f46, 0xcbc587b7, 0x5d6fa44c, 0x5a1e5c69, 0x428eed56,
+ 0x657c5dfa, 0x67dc01df, 0x5601df29, 0x1e421eda, 0x712a3e04, 0x3f0451fe,
+ 0x389517f9, 0xfcff28df, 0xc85ef9db, 0xf3e32561, 0xd4adf393, 0x7acbf98b,
+ 0xc124fdf1, 0xe04c652f, 0x2e6f576b, 0x50ce4277, 0x0ebde98e, 0x4db73f31,
+ 0xf7e50efb, 0x22dcfcc5, 0x28bad665, 0x17d20fc4, 0x103e0ff5, 0x04fa9469,
+ 0xbedc5c9a, 0x4bf1ce91, 0x57f8497a, 0xdf403809, 0x7e6c6339, 0xf274b63a,
+ 0xe095644e, 0x778f639b, 0xfc07af49, 0xcf4adf9d, 0xeabf116c, 0x7c93c603,
+ 0x7dcbc723, 0x38ddd279, 0x87dfe86f, 0x8f71cbfd, 0xd8f4227a, 0xe5c651cf,
+ 0xe52fc243, 0xa1fab732, 0x614707bb, 0xee968bbb, 0x9cde7003, 0xacd2ab8e,
+ 0xfd13bdf4, 0x59def805, 0xfadc50af, 0x1fe75898, 0xa8b5fc7b, 0x7e7e01e2,
+ 0x277c427f, 0x307f0cf9, 0x6de1263e, 0x7038f1b2, 0x0f52dc30, 0x9f73b849,
+ 0x2c6eefb8, 0xbee3f097, 0x4a9f2051, 0x957e4a3c, 0xf982f5f7, 0xda4e7896,
+ 0xfe73b54f, 0x463d4cae, 0x943a77e7, 0xfc27f707, 0x5ce213a2, 0xe33c6b79,
+ 0x8915ff71, 0x8af735fb, 0xb40c8b18, 0xc08ed23f, 0x807d1acf, 0xa7bf69fd,
+ 0x8b3ce716, 0xd690bb74, 0xc73ffa8d, 0xd0398cea, 0xe699d96f, 0x9dcef871,
+ 0xb8ef43f4, 0x31a353ea, 0x9f8bb55e, 0x52fc9377, 0xc93f6176, 0xffb8b941,
+ 0x83eab454, 0xefc8e182, 0xbed035bf, 0x63e3d14e, 0xcfdfe88d, 0x187332dd,
+ 0x41ef01a2, 0xbb3f5ea0, 0xbf266879, 0x984d6059, 0x3621f786, 0x01ed333f,
+ 0xaf559f28, 0xd80dbbd2, 0xd16fca0f, 0x5f1499a3, 0x52d6113d, 0xf8fd0a30,
+ 0xf456a81f, 0x32df6fe3, 0x7f6c31f4, 0x0c6ba5bb, 0x39b1b63d, 0x7d4ef296,
+ 0xe907d934, 0x8073caf7, 0xc7dee2d5, 0x3fde845f, 0xe22a9edc, 0x2f755ffc,
+ 0xdd6f8fdc, 0xacef4618, 0x75ed1a14, 0x4f6f1c3e, 0x54675a17, 0x23eaf11a,
+ 0xbf255bdd, 0x99918e6c, 0xb9508693, 0x0fca0939, 0x451f9a1a, 0x51f0723b,
+ 0x3f7c60cb, 0x86d7a992, 0x9a7f7315, 0x6ac63bef, 0x70912ddf, 0x0fc6247c,
+ 0xdf7e4fee, 0x1b08eb84, 0xefa44fdd, 0xedf8aecf, 0x6783b434, 0xe1b4f6b7,
+ 0x09ef4fbc, 0xa703fba3, 0xcf77da0d, 0x57def56e, 0x79297df0, 0x9a74f56f,
+ 0xfc938fd6, 0x377bc37e, 0x839ed37f, 0xa5b9d1bc, 0xdd194b0b, 0x8d397efb,
+ 0x2263f7d1, 0xe789dabe, 0x4d6a4b08, 0x7307bc56, 0xf71ef912, 0xfcab76b3,
+ 0xcb99a5fe, 0x99ddc9c1, 0xe4b7bf74, 0x525f3c6f, 0x3ef178a7, 0x9fa7fef2,
+ 0xb30af3a0, 0xabc4cfc1, 0xf3feed09, 0xa1a7a7ba, 0xb8765c38, 0xfe7de257,
+ 0xf9f95bcb, 0x32ef0e8a, 0x2079dc1c, 0xdfb9dec9, 0xcbfb5dfc, 0x9f110e32,
+ 0x2fcfbdae, 0x4fd72cf1, 0x8c3f026f, 0xdbc7e218, 0x90e74b67, 0xa9617cbf,
+ 0xca4bd29b, 0x23b7b5b1, 0xe9a25b1f, 0xeb1fc0be, 0xbdf1519f, 0x835df2a8,
+ 0x783ae1af, 0xbd346454, 0xd2d9f293, 0x7a8fb425, 0xa5156961, 0x0e32de92,
+ 0x46aec777, 0xfab3eefa, 0x9fbc06cc, 0xb46446fb, 0x90b603b0, 0xdeeced74,
+ 0xb9d79cb1, 0x4afa701f, 0x9d6dcfb8, 0x6af38519, 0x61b63e7c, 0x2235d224,
+ 0x5f7e8ada, 0x724738a9, 0xabf73d6a, 0x7fa398cf, 0x3df40f93, 0x024a61b3,
+ 0xbb3737be, 0x5869def1, 0xb147b25e, 0xb1c07ae2, 0xae145267, 0xb7d53edb,
+ 0xa8fde144, 0x7bcbd74f, 0x3bfa5e55, 0xd8f2a354, 0xca3f6c14, 0x0cf667a7,
+ 0x7c8d75be, 0x9e82f232, 0x879ebfee, 0x5c938a72, 0x0938a70b, 0xb9e2c4fc,
+ 0xf3afd991, 0x3afb4af8, 0x6ef3ac57, 0x347ef317, 0x31f726dd, 0x04773ca8,
+ 0x61bd3f2f, 0xefec44e7, 0x158366ec, 0xb36cfee1, 0x079ffa81, 0xc01d33eb,
+ 0x5f2b667b, 0xd71e60f7, 0xf2b767cb, 0x3abccdf5, 0x5f29bebe, 0xfbf27060,
+ 0xcc7e5aa2, 0xef47680d, 0x5ef274fb, 0x9f273cc8, 0x97b03cdf, 0xbe60df38,
+ 0x7475618d, 0x9e9bec8f, 0xdbe60d17, 0x855f92f9, 0xd7e7687e, 0xe044f8ce,
+ 0xf91de513, 0xbcc3f255, 0xdedf7cf5, 0x07383756, 0x47f24ef9, 0xd5593bf0,
+ 0x57dfc646, 0x7bd385d4, 0xed2293b8, 0x530fb406, 0x20c65ae2, 0xe74e3e5a,
+ 0xab9a807e, 0x37bde273, 0xf90a6d56, 0x748acece, 0x744557ee, 0xdeefc465,
+ 0xcf3f2b74, 0xc97fee29, 0x86922614, 0x84527b76, 0x343b0bed, 0xaefd3a79,
+ 0xcfc0f47b, 0x3db76e93, 0xd8c1ddda, 0xee0bd32f, 0x267cc3d1, 0x7776da65,
+ 0xbff3fc83, 0xb7f3c09a, 0x201a86d9, 0x78994cbf, 0xd7c818cf, 0x4a9f3ba7,
+ 0xece7180f, 0x38692e96, 0x19ff283f, 0xbbc5d796, 0xa5698e7f, 0x49760fb8,
+ 0x24b41d69, 0xfdfedfc3, 0x7fa3963d, 0x2df3fbb4, 0x18ee9606, 0x7f097980,
+ 0xdd25b4e8, 0xf8f4abf9, 0x8cc5e58e, 0xf5e74e3d, 0x0e1efc3c, 0x09ccb8fc,
+ 0xf38a4f78, 0x97bcb15b, 0x2f741353, 0x9fefc1c7, 0xf252fbc9, 0xff5f543e,
+ 0xb70db27d, 0x92ec9f72, 0x2a1dff81, 0x0fbda9c5, 0x89fc34a6, 0xf6a9f9de,
+ 0xa23096b0, 0x4d9ef683, 0x7753be39, 0xa20bdd1b, 0x6f4c87fb, 0x57337d27,
+ 0xac683bfa, 0x29dff987, 0xfcfc8960, 0x1f82a3c1, 0x3d652f4f, 0x9fe8807a,
+ 0xca39b77f, 0x985c700e, 0xfa85ebe8, 0xfddc3220, 0xe9d7c427, 0x0ba9d50d,
+ 0xaa1ef0e3, 0xed0f91c9, 0x7df978cf, 0xb7e132ce, 0x42f1cdb2, 0x3bbea82f,
+ 0x46535da1, 0x87684ddf, 0x757c17de, 0xfe97c321, 0x192bd423, 0xed049d7c,
+ 0xde5d3ce8, 0xb1e2bbf2, 0x4fed85dd, 0x700d98f4, 0xbc06009b, 0xfa1e35a7,
+ 0xf7a3611c, 0xfb4a98aa, 0x7efe5ecf, 0xa2799e92, 0xd5eef86c, 0x3ee2e933,
+ 0x9413dd11, 0xeff89274, 0x1a181740, 0x999d59fd, 0xbeee1019, 0xfdfd036c,
+ 0xf91f492f, 0xddc2e2ce, 0x7742fe3c, 0xe31e4524, 0xe2cda748, 0xb0759fef,
+ 0xbf916f8b, 0xd1e9620a, 0x330d9fe8, 0x11c9db43, 0xf5d88d1b, 0xff2f6d77,
+ 0x92fc2e9d, 0xe0706cc1, 0xa2a5923b, 0xd0b558cd, 0x2d5bef8e, 0x7bd3378c,
+ 0xe85f0b25, 0x96c1fc4e, 0xb60590fc, 0x89621b63, 0xa866565f, 0xf5b9ff84,
+ 0x2a1dde8c, 0xf3a64fa8, 0x36f5f994, 0x12daa34a, 0x6fecfca9, 0x7ae2c9de,
+ 0xe0a7d389, 0xa68cba7f, 0xd3ff4b73, 0xd9d6529b, 0x6691a77b, 0xf0bbcfba,
+ 0x0b6bb720, 0xc7bfcaa7, 0xbbafefc2, 0xc8ae3804, 0xb90b8a1a, 0xe753dc3a,
+ 0xf0ba57ef, 0xe77e00be, 0x677d5034, 0xfc4a57ef, 0x82dd049a, 0x7a9cb3df,
+ 0xde913330, 0x59ef147f, 0x9aed174e, 0xceb3bdc5, 0x4fbcb5de, 0x6a227bb4,
+ 0xddf2135c, 0xc8696774, 0x9ef52d77, 0xcffa0730, 0x7a48d486, 0x373ee147,
+ 0xf59a97f8, 0xf11e8b4c, 0xbf9b2d30, 0xba753973, 0xfd90deb6, 0x4373e939,
+ 0x92778776, 0x4d8fa80c, 0xecfb6d2e, 0xf50ec2ae, 0xf6bf7d65, 0x2354d15d,
+ 0xbe3d4fd9, 0x69f90b3b, 0xf4515de2, 0xbfffd10f, 0xff10b4ec, 0xb83bc49b,
+ 0x112b2ccd, 0xbeadc2f5, 0xdbfffb27, 0xefc1b1fb, 0x03bf06c4, 0x42eb7fdb,
+ 0xdd607e4d, 0x6fed350f, 0xa9ae5fab, 0xad5bec1f, 0xfa6ccfa9, 0xb43f2699,
+ 0xfb4d39f9, 0x693647e1, 0xbcb647ea, 0xfdbfa9a4, 0xfe4d0ecc, 0x683fd68e,
+ 0xb6d9dfda, 0x61cf9357, 0xe7da68ef, 0xe4d03f9a, 0x57ff5ac7, 0xc4aefed3,
+ 0xf1fa9a13, 0xfa9af3f6, 0x68ae7d09, 0x2f8e05f2, 0x373fed35, 0x457757ba,
+ 0x0cea22bf, 0x433aadf1, 0xf944f861, 0x6629a6e5, 0xba6b07d4, 0xf8247d0a,
+ 0xd3b0b96f, 0x7ba307ac, 0x6cd563ac, 0x3d5ff11f, 0xc1a0bbff, 0xde7f4f76,
+ 0x1ff8c4e5, 0x6bdf8d7b, 0x527f068b, 0x8c7e301f, 0xff02ccd3, 0x9e6c5dee,
+ 0x778f9355, 0x77da6a25, 0xd4d76e99, 0x68fbb927, 0x38e653ea, 0xaab4f934,
+ 0x5df69a11, 0xf9353897, 0xa69e4f0c, 0x971af77d, 0x76b3df26, 0xef7da6ba,
+ 0x7d4d6ef5, 0x4d1cef5f, 0x55adff7d, 0xbac0fc9a, 0xb7f69a25, 0xf5347bd5,
+ 0x9a357d83, 0x5aa6ccfa, 0xf3687e4d, 0xe1fb4d7a, 0xfa9abc47, 0x355b2d91,
+ 0xa99fb7f5, 0x68efe4d3, 0xbfb4d7ad, 0xc9a7cdb3, 0x9a83b0e7, 0xf7e6b9f6,
+ 0xd6b1f935, 0xefed344f, 0xa9a63c4a, 0xab3f6f1f, 0xce7e97a9, 0x6b9f3e84,
+ 0x53df85cb, 0xe697f8e0, 0x6ef7f6fb, 0x1f742877, 0x6ed75cea, 0x96c57df2,
+ 0x24fd1530, 0x6c99c517, 0xf5111078, 0xb727de15, 0x8539f3f1, 0x238aaf14,
+ 0x944c887f, 0x810bcf1d, 0xab8510df, 0xf40c8cb6, 0xfefc23ab, 0xccf5ea5b,
+ 0xdadff79b, 0xd5dcff84, 0xf288beee, 0xfb6eaf31, 0x989f7a38, 0x1c225679,
+ 0x77bffdf2, 0x956dde83, 0x19f378e9, 0x17f00fa6, 0xa6d5860f, 0x389af90e,
+ 0x05f378c1, 0xb6c1ef86, 0x22e22bf7, 0x17bdc7f8, 0x16bff406, 0xf7f817d6,
+ 0x9a976b23, 0xffc76fe9, 0xf295a96c, 0x522696eb, 0x3a00fffe, 0x0047bf29,
+ 0x000047bf, 0x00088b1f, 0x00000000, 0x7dedff00, 0x4554780b, 0xeedd7096,
+ 0x9d248fdb, 0x777579d0, 0x493cdc9e, 0xf09d0848, 0x3a3e00d8, 0xc0406021,
+ 0x490435e6, 0x41a8c1a4, 0xf881ba43, 0xbb75744f, 0xb2021031, 0x10d191b3,
+ 0x0186c195, 0x099d1964, 0x09d1a32e, 0xe09af09a, 0x1c604c3a, 0x3719d9c5,
+ 0x8ee2a3a0, 0xcfe31e10, 0x7fc38fee, 0x937ba9ce, 0x380e9dbe, 0xf7ff3afe,
+ 0xb4fbfa3f, 0xab755538, 0x739d554e, 0x2aaa3cea, 0x89895ead, 0xde6d6322,
+ 0xf39f4a1c, 0xc99899da, 0x316f36d8, 0x0ebddbc1, 0x72defd82, 0x9d7a774a,
+ 0x5bcbbf94, 0xaf1ef041, 0xdebdd28b, 0x79f74a1a, 0x92fe543d, 0x9fe081b7,
+ 0xb6947d7a, 0xff299b7b, 0xc10b6f15, 0x046dbc07, 0x53f5eabf, 0x4bdde1da,
+ 0x76de1be9, 0x76f4ef2a, 0xb7a6fc10, 0x6f2ee08b, 0xbc87c10f, 0xf11f04bd,
+ 0x98f8269e, 0x1ed28fb7, 0xbe9467ef, 0xf2a7eded, 0x0957bc77, 0xdbbf8ebe,
+ 0xcd2afc19, 0x2631e49f, 0x7ae69730, 0xc9ccc21e, 0x00f63226, 0xff824bfe,
+ 0xcc8846e2, 0x8cfdd8c2, 0xb0d73eff, 0x9413769a, 0x3ff2fe77, 0x74c60285,
+ 0x1f8d8ca5, 0xf662690f, 0xc634c6ce, 0xe675b026, 0xd318724f, 0x63d75740,
+ 0x4e09fb07, 0xd6191319, 0x2d75dfc3, 0x58c7dffe, 0x94bffc3c, 0x834c78e5,
+ 0x14095369, 0x55befb42, 0x1a777f82, 0x3e20d755, 0xbf1c8dab, 0x95135a69,
+ 0xf82c3e57, 0x5563020d, 0x8be9f322, 0x587dfb18, 0xc11b0154, 0x2e8f25d8,
+ 0x2172c447, 0x04830edc, 0x443a8ff8, 0x2c5d7e0e, 0x9da5b18e, 0xd29b1d86,
+ 0x84aaf106, 0xfdf035ef, 0x0c1a562b, 0x3a3d64ab, 0x1df203c4, 0x9ec618da,
+ 0x4ba6b8b7, 0x8a60ff90, 0xf687a7c6, 0xed9fc999, 0x2dec648c, 0xe6066b8b,
+ 0x77dcf25f, 0xc07f1b0c, 0x7ec6cf6c, 0xe2ba1b66, 0xfdff4117, 0x9df6b5c7,
+ 0xe1f3f0d2, 0x6c67296e, 0xdfca0ddc, 0x02ec973c, 0xa2ffca3c, 0x9ffce175,
+ 0xf85645d0, 0x492f01f3, 0x1a4a78e0, 0xeadb3a55, 0x7cf8825a, 0x47b9e919,
+ 0xe5f85303, 0xacf6ab6d, 0xae552181, 0x82e11aca, 0x2582eeef, 0xcd8c1963,
+ 0x418e9265, 0x38e67cf9, 0x2d4d069a, 0x17822e64, 0x6fa51f31, 0xb1aabbc5,
+ 0x4fccc59d, 0x21b26bb0, 0x82b8d435, 0x78cb72f1, 0x947c65b9, 0xabab71f4,
+ 0x20e5e38e, 0xba4c4ebc, 0xa5c71b23, 0x5596f5e0, 0x58737aa2, 0xefc476ff,
+ 0x3f1783cb, 0xd2863211, 0x174077c7, 0xeb1e6826, 0x73ac3d31, 0xf7d18ea3,
+ 0x7e088f8d, 0x2e856ba4, 0xb791992a, 0x0be418fb, 0xf4027481, 0xd2fc8451,
+ 0x92373a9f, 0x0949e4e8, 0x92707c1a, 0x0b1fa7d6, 0xb3f8d4e3, 0x87d12d05,
+ 0x1efc005e, 0x48fa0388, 0xea0e9e1f, 0xe00d219a, 0x67afa01f, 0xaff3bdb0,
+ 0xce0e5dff, 0x49cdfb97, 0xa357ce12, 0xe801d606, 0xd6b6f7d8, 0x99925bbe,
+ 0x94ed6014, 0x6ba47e31, 0x73edda26, 0xb17ae0c7, 0xdfa84ea5, 0xfb0d65ad,
+ 0xfbf687f3, 0xb417ae2a, 0x2ba6c27f, 0x9cbb53f7, 0x9ff295cf, 0x63c5fae2,
+ 0x5eadebca, 0x16ad69f5, 0xe8713ff0, 0x131a5e9c, 0x6f0d1c62, 0xe00666e7,
+ 0x3338eeef, 0xe44261dd, 0x45e7f2fa, 0x949fe60e, 0x1fa144e9, 0xb5d23ead,
+ 0x178814c3, 0xf9e817ef, 0xd13744e7, 0x4419cf40, 0xe0f89fcf, 0x690639d3,
+ 0xfb4822c4, 0x20ba6a60, 0xd660bd75, 0x672cdd23, 0x99ab4a76, 0x6007d293,
+ 0x9d7e91f9, 0x38f4a7be, 0x76b20fef, 0xbe2bafca, 0x7cf482d7, 0x8a95c6bf,
+ 0xa5eb2d70, 0x2feb377c, 0x2dfcc1b3, 0xd47b5e6c, 0x6fcf5806, 0x025a6a79,
+ 0xff3cefcc, 0xce98a3b2, 0xe27c25dd, 0x7a3f8893, 0xc13eaf10, 0xfa113eb3,
+ 0x92a5fbbf, 0x3f9049f5, 0x85d7cb47, 0x175f2bfd, 0x8f047e45, 0x97a1f81b,
+ 0xe341cb8f, 0xab9546d2, 0x09f2a1f8, 0x9da010e6, 0xff0683fe, 0xfe00b4ce,
+ 0xdfe87e28, 0x898e5093, 0x7ae0f7fd, 0xc434dfbb, 0x083f7ae0, 0x29c71be2,
+ 0x806b1838, 0x2ad690fe, 0x882a8863, 0xe1621fde, 0xb9f7ac76, 0xa79fdf4c,
+ 0xcfefa230, 0x4060e605, 0xa67417bf, 0x5ae50166, 0x0456cbaa, 0xbe60acf8,
+ 0x6ee50626, 0x38054bcd, 0xd725234f, 0x1fd744a7, 0xa61537b5, 0xa7f7fca1,
+ 0xf7ff280a, 0x698dec19, 0x5d84fdaa, 0xe321408f, 0x3f9f3861, 0x0ec776c0,
+ 0x3e284bc5, 0x14429ff6, 0xf33d0663, 0xbf888b19, 0xebe444d9, 0x57f13d44,
+ 0x066d4e23, 0x3c94e3f6, 0x9feda1a6, 0xf9edf190, 0xef744b4a, 0x16ecf183,
+ 0xf7c3f542, 0x60f8432b, 0x2c3f243f, 0xa7d1fa8c, 0xfa563e71, 0x64bea663,
+ 0x6a75d027, 0x86974b84, 0xc716c182, 0xcb998be5, 0x4fb49e97, 0xe67d7133,
+ 0xc8a8de4c, 0xdd8f6a65, 0x09d1e5c6, 0xf843e49d, 0x1d9a4944, 0x9c80d724,
+ 0x97f8abbd, 0xbb8f11a7, 0x2d2ea68c, 0xdd16eca4, 0x7d94fa9f, 0xff707d30,
+ 0x7fd94bbd, 0xeffbe16f, 0xefb5991c, 0xf1babb12, 0x3aecc67b, 0xfd972fc4,
+ 0x6d8f995e, 0xf22adfb8, 0x0b7ec871, 0xf9c5eb03, 0x832b2513, 0xc7c0b574,
+ 0xdc253abf, 0x36c47c8f, 0xf4f8d2e7, 0xfe0cfcb2, 0x58c15ade, 0x13c651a6,
+ 0x19704bfe, 0x20ce6659, 0x5663549c, 0x9b1e29c1, 0x06c8feaa, 0xe69e5549,
+ 0x679551cb, 0x7055db34, 0xaab14b56, 0x8736a8fe, 0x97f5ce0a, 0xede7eaab,
+ 0x31e0aa75, 0xfaaa15ed, 0xaa5c3b63, 0x1aaec2f2, 0x1eb8f955, 0xd09e0a8f,
+ 0xffaaa0db, 0xaa7da777, 0xcd7d49f2, 0x9f29f2aa, 0x5be0a8b5, 0xf554dbfb,
+ 0x57eabf6f, 0x7fb09795, 0x354f9556, 0xd3c157ee, 0xeaabafcc, 0x16fb80bf,
+ 0xb61dcff0, 0x0cfe556e, 0xbbeab8e9, 0xaa4e733b, 0x75e417e0, 0x270e2df6,
+ 0xe72d68be, 0xfb6cd1fb, 0x5876aa07, 0xfebe68e7, 0x7b6f3c61, 0x510b1fcf,
+ 0xf4d76e4e, 0x4add21a7, 0xf222735a, 0xdcf16671, 0x2c664043, 0x14aab1db,
+ 0xf94e5bc5, 0x1d308753, 0x8a5fdced, 0x715f926c, 0x05a610f2, 0xd0a58bae,
+ 0x44d7b31c, 0xc8b4c61f, 0x8ad53853, 0x3dcc34a8, 0xdf44e98c, 0x5728a9aa,
+ 0x3f5c785f, 0x2a28f91a, 0x074fa146, 0x827d67d1, 0x7eb9f886, 0xf28fc9b1,
+ 0x24c532c7, 0x96139032, 0xb1d65a1f, 0x9a8b4c02, 0x1af66d31, 0xfa0f5f99,
+ 0xba519780, 0xfe666bc9, 0xaf67206c, 0x93fae08d, 0x43a795f7, 0x44ab233b,
+ 0xe699aa33, 0x48258f51, 0xe5f5bed0, 0x765d9c96, 0xb0edd6c6, 0x42e5d7cf,
+ 0xc59e19ff, 0x4e01a23b, 0x30058e63, 0x2398167f, 0x25b19936, 0xfa76df3b,
+ 0x97c287f2, 0x244d9d33, 0x5cf6c417, 0x7694ffd4, 0x6e7e9637, 0xdf2198d7,
+ 0x11e74bf7, 0xf1adf798, 0xc21df4e1, 0xa75f9925, 0xb60b475d, 0xf69ef90b,
+ 0x4cfc7c10, 0x977fdf1a, 0x0a7d73a4, 0x66eb8487, 0xacc6cbe5, 0x808ca7a0,
+ 0xa93adcb9, 0xf0ea0ce1, 0xa027d9a2, 0xe0d7627c, 0x892b907b, 0xe0832958,
+ 0x4e01c3db, 0x6c625840, 0xc7eb967f, 0xc5d5afd8, 0xfa00d9d8, 0xc351a849,
+ 0xcf9e615b, 0xa3e20e66, 0x89f1aa5b, 0x8fdd0630, 0xf43b769d, 0xc60aadb3,
+ 0x3d56f00b, 0x7a9437d7, 0xf68c34a3, 0xf8d32ff7, 0xcdaece7e, 0xf49ea3b7,
+ 0xe79e3ca5, 0x3e8bfdbc, 0xeb7b44ce, 0x3589a52a, 0xf205c11e, 0xb4e95acd,
+ 0xae9ea0fb, 0x8423e611, 0x348bf2de, 0x1dd7be91, 0xa090447e, 0x1269a7de,
+ 0x7e9589c1, 0x0d52771a, 0xbf801bb4, 0x6609f44d, 0xe63db7c8, 0x9b3f1013,
+ 0xf06769d9, 0x885a331d, 0x3cc8d7fe, 0xcbf86b61, 0x0f418fa2, 0x769d79d3,
+ 0x13bba7ac, 0x271f33e8, 0xb86663d4, 0x47e3c94e, 0xa3eb10b0, 0x0d3e86a4,
+ 0x9f40dc73, 0xd47d4a8f, 0xddc5fb43, 0xe80b2926, 0xa6c585fb, 0xda211d8a,
+ 0x9f9e54fb, 0xfeea310d, 0x1f3e5a2d, 0x6cbedc8a, 0xf0a8ebe6, 0xa6689af1,
+ 0x526be392, 0x846f5bc6, 0xc8cdb5af, 0x6ef8015c, 0xd0cc7e85, 0x55abe1be,
+ 0xe83f1c66, 0x4fea4ed0, 0xc764f2e4, 0x6ec8728f, 0x21c75e0a, 0x3f9408f4,
+ 0xa3e908a2, 0x7c08dfcf, 0xdbd2a868, 0xfeb26f51, 0x7b809343, 0x116b2273,
+ 0x5358be50, 0xdc447aca, 0xae5744d7, 0x793e8433, 0xd654ba33, 0x839fd94f,
+ 0x3d774bd7, 0x9c12fde3, 0x31d57fef, 0x1f56c7d4, 0x05718f8f, 0x3a4c53d0,
+ 0xd662cba7, 0x98fe45a2, 0xbd29dacc, 0x7a52f585, 0xd4a7eb1b, 0xa622ccc1,
+ 0x694ecca5, 0x3a527319, 0x2d28799d, 0xce942d67, 0xce94ed64, 0x8294bd62,
+ 0x93a9433d, 0x9aeec999, 0xa637fb07, 0xd293980b, 0xa50f31ef, 0x7e9ce999,
+ 0xc10b582b, 0x4a76b377, 0x24ef803b, 0x8c01fa3d, 0x9c827694, 0x904df4c3,
+ 0x79769873, 0xa3652625, 0xd287201f, 0xa53b5e23, 0x94c5bcc7, 0x541d78f6,
+ 0x396f6def, 0x9d78efa5, 0x56f09e94, 0x75ebda50, 0xde53bd51, 0xf5df4a1a,
+ 0xcf7d287a, 0x69e940db, 0xdfd28faf, 0x1d299b79, 0xc67e07a5, 0x2be9cdf9,
+ 0xf53e7d44, 0x0243bd23, 0xe591ecf9, 0xe68761d2, 0xb8f1dc99, 0x40661a6e,
+ 0x235b283a, 0x7359fd20, 0xa43f0e34, 0x0b56729b, 0xe1ba42f7, 0x0cdfd704,
+ 0x0fd248d6, 0x82f56dad, 0x0876ed04, 0x5808da7d, 0xa9e9e9cb, 0x9f208d73,
+ 0xbad93a4b, 0x19c23b08, 0xee81194f, 0xfd3ce876, 0x64bca03b, 0x08d734a7,
+ 0xc8e4d67b, 0x8fb1ff53, 0xe93e54c3, 0x03346b08, 0xfb3d2b3c, 0xe38138a9,
+ 0x7befc281, 0xaee6733b, 0x253c44cd, 0x34c5f3c2, 0xbf512c30, 0xfa44c47e,
+ 0xd9db6175, 0x93c00d42, 0x68454c1a, 0xebd40617, 0xae1fba42, 0xf2b9705e,
+ 0x9655b6dd, 0x0d879c46, 0x0e5a809f, 0x7d19a959, 0xd5f3ab85, 0x5ebe6aed,
+ 0x837b4cff, 0x09eb03fe, 0x7f6f6837, 0x7d32a396, 0x3a7effc2, 0xdd6fa60f,
+ 0x6bf68ff5, 0x8e640fc8, 0x5774fdc1, 0xfd339734, 0x04ee9fa0, 0xc8c577bc,
+ 0x1a4cc6f0, 0x5c43ca17, 0xd29b0db7, 0x77803efd, 0x1f573985, 0xd47ff2c7,
+ 0xd14277d8, 0xa6d770ae, 0xc933825c, 0xc621b13f, 0x8f931393, 0x97df3cfa,
+ 0x0d1f935a, 0xbff80293, 0xafcb9d39, 0xe95cb7ad, 0x447681dd, 0xc16586b3,
+ 0x979b3b77, 0x7681cc6f, 0xf419bc7e, 0xdc478007, 0x0b31bd5a, 0x6a37d3ca,
+ 0x19656a26, 0x78fc7887, 0x4d9ef573, 0x8f255fa8, 0x7686c98e, 0x99796433,
+ 0xb857db1a, 0x55bce806, 0x95a7b6af, 0x7e649ff4, 0xce6686a9, 0x954d6c82,
+ 0x3a1df4ed, 0xdfb81156, 0xefc64cfd, 0xd53c5957, 0x57fdcedd, 0xfee19186,
+ 0x25fc6027, 0xc3bfb923, 0xfe48ceb2, 0x7ff24b0e, 0xca03bc9d, 0x7634db2d,
+ 0x6b44e954, 0xea1d5aed, 0x3b598bfb, 0x810ee3f2, 0xe14bef7f, 0x0a28217a,
+ 0xec0373e9, 0xd3deadf2, 0xfc03328b, 0x9f0ab684, 0xc97bf680, 0x0fa15ac8,
+ 0x07e49ff7, 0x2dfbb405, 0x15c12e15, 0x8781f689, 0xb965cfca, 0xf80e927e,
+ 0xfbe12ad9, 0xb992fd40, 0xa15d7012, 0xd2768adf, 0x605158f3, 0xf8b3a77f,
+ 0x3b07ac3c, 0x75d5f499, 0x782bc27a, 0x97654ebe, 0x95f6c01e, 0xff2e0c75,
+ 0xabb7067e, 0x5d013d77, 0xe24c1f20, 0xdd89f376, 0xce3fa489, 0xa0770d69,
+ 0xa9e274fd, 0x6f0465d1, 0x3d40ec99, 0xc9eec4f2, 0xb39d31d3, 0x3bd52665,
+ 0xb41eb021, 0xb96ce787, 0xd4fcc45b, 0xdb0bc00c, 0x7a27a33b, 0x41e5b39c,
+ 0xcb47fbf9, 0xe358bcb0, 0x91da09fb, 0x22fb8dc5, 0x1c9e4ed0, 0xa6124af9,
+ 0xf57d3427, 0x5dffd0dd, 0xdc2bf666, 0xe31b9d9e, 0xfe1cb1fe, 0x74a9f731,
+ 0xbfd7ea1d, 0xf5a74f4b, 0xc41ccf9c, 0xec835007, 0xf6f65bba, 0x8a4d061e,
+ 0x3fded6dd, 0xe65ccc15, 0xc11f30e8, 0x5ecbb4b4, 0xd657d386, 0xe9823ce3,
+ 0x194f5ef4, 0xa7e52faa, 0xba608e5b, 0x3bf5d724, 0xff179f9c, 0xbcaf7be1,
+ 0xc7c8f008, 0x07a8cdeb, 0x37d13e65, 0xebf92763, 0x21f90c74, 0x45a7926b,
+ 0x746c048b, 0x787ca0c6, 0x835169f6, 0xad21b9fb, 0xc3610c25, 0xb41ae97d,
+ 0xb745770b, 0xb3b8d0d4, 0xe3ce19c2, 0x210fb0db, 0x3b45645d, 0x809f9063,
+ 0x3e1d692f, 0x10d3e993, 0x634731ed, 0x1fcf187e, 0xe1ce17a8, 0x5af503f3,
+ 0x27ea04c2, 0x13fb2046, 0xbfdc06d4, 0xddfef26d, 0x38093cc6, 0xcf48d61f,
+ 0x64ebf40e, 0x67fe7095, 0xb02e9c91, 0xfa44d37a, 0x96cd9c84, 0xb89dcf16,
+ 0xe897560e, 0x3ba40beb, 0xf40706d8, 0x19827491, 0x055bd7da, 0x219c830e,
+ 0x7e87f0bc, 0x42c98b0c, 0xbf828d7a, 0x0bda02b5, 0x1c7033d0, 0xdf834cf3,
+ 0x9b177429, 0x4235c7c1, 0x65acbfa6, 0xdf053dbc, 0x9f2e0cb8, 0x83496f01,
+ 0x7c6568f8, 0x009a1c60, 0xd1ea027c, 0x66f006f8, 0x05d21b76, 0xa7817a48,
+ 0xc703124c, 0x8471ad5f, 0x7a645da1, 0x4fe8fbf5, 0x02394289, 0xf753fe78,
+ 0x69f22324, 0x327238f0, 0x46df08d2, 0x6f5187d0, 0xfce2e99f, 0x11e958db,
+ 0x18423ec8, 0x3a2c9fc7, 0x35681fd0, 0x017416ad, 0xf326b5e3, 0xa5667a7d,
+ 0xcae51ba7, 0x3b08e2cc, 0xac9df7d2, 0xf3999d7d, 0xc04c91f7, 0xf81b146f,
+ 0x41c4d899, 0x4f47f0bd, 0x97127bbf, 0x97b59934, 0xf9fee2e4, 0x70b3fdf8,
+ 0x3a3eb6fd, 0x4ff107b3, 0x3baa79cc, 0x5e741a06, 0x197dd794, 0x6ca4ebf7,
+ 0x1c0e3f13, 0xe0079247, 0x8d44bf40, 0x41e81cba, 0x65742b05, 0x71a21a13,
+ 0xe444d1bf, 0x7a819ccf, 0xe486944a, 0x6129c83b, 0x33fd4841, 0xf9e4ae88,
+ 0xaee7d657, 0x375a4c8c, 0x03af89ab, 0x171bb7eb, 0x5583ca46, 0x6dfa09d6,
+ 0x011f3604, 0xa658df74, 0xd7680bf5, 0xac28fd62, 0x919de2cf, 0x8769d743,
+ 0x03399a4e, 0x1ac3f4e5, 0x74366ef3, 0x7edc815e, 0xc3ed7a4b, 0xf90e5471,
+ 0x7dfc91a2, 0x436af801, 0xb8f5eac1, 0xac6dfd59, 0xb48cee6b, 0xc989f9a1,
+ 0x3ee2660b, 0x68cb589b, 0x47cb83fd, 0x575ea63d, 0xa3c737b2, 0xbbf988ff,
+ 0xce7ac1be, 0x8655de4c, 0xbaf07cfa, 0x1a97742a, 0x105f7a1b, 0xa65f3933,
+ 0x954fd846, 0x92215e93, 0x114ce09e, 0xa2ed03e3, 0x1f7c190d, 0x1335fdba,
+ 0x23ec43ed, 0x5cb71fa3, 0x93ef577b, 0xa50eb0b9, 0xae683457, 0x1cefa3b0,
+ 0x484ce1fa, 0xddeafda7, 0xf50affd5, 0x1a657da6, 0xb06ff987, 0x10e819be,
+ 0x9d80f5f1, 0x2fdaf001, 0xa3a0b4f6, 0xd992b1a4, 0xfa55df71, 0xf3f723d9,
+ 0x49df9d0b, 0x645735f2, 0x820e493b, 0x2f401e65, 0x7e896900, 0x56731978,
+ 0x68dd90b6, 0x5907cccd, 0xf6bd6e8d, 0xfe5fb425, 0xefd0cf49, 0xd242af38,
+ 0xe7f8c095, 0x65ba4a55, 0x5917c7e8, 0xf311ea39, 0x3f94ec2b, 0xf3ced2bf,
+ 0x417f3c8d, 0x17f28385, 0xbe783a54, 0x3e61f209, 0x7bf85616, 0x42eed0bd,
+ 0x41a48c53, 0x93a5783f, 0x50355f97, 0x0f603bf9, 0x87c90264, 0xde49f987,
+ 0xe1a67cb7, 0xb84f12f1, 0x0d5c005f, 0x123d4591, 0x1a7ddfce, 0x8624167b,
+ 0x01999114, 0xe9c2b67e, 0xf3f942d7, 0x13809fcc, 0x6af546f9, 0xbfe43667,
+ 0x719a2c91, 0xc0386f7c, 0xabf9c66e, 0xe9de6915, 0x351bf007, 0xd8cf14c9,
+ 0x7dadfb21, 0x67e48c2b, 0xfc875d05, 0xa2456cac, 0xf2f0c7ac, 0x7ecdcb6d,
+ 0x0e40c7d4, 0xdff63ad2, 0x001e9227, 0x1cedf0f2, 0xca5e8bd4, 0x484987b4,
+ 0xb37e6ab7, 0xa12f2f54, 0x19992af6, 0x9559f2ed, 0x97c6bdbc, 0xea0d7e34,
+ 0x3379a655, 0xf71a0e91, 0xafda3b32, 0x2a9f56cf, 0x9b78458b, 0x87e5cedd,
+ 0x56342e5a, 0xe12e396f, 0x731a3c78, 0x7ee7d516, 0xe94f46ad, 0xc830ad2e,
+ 0xd2deb4cf, 0x2a18fca0, 0xd83dec6f, 0xa955424e, 0xb3d4137d, 0x8fd138c0,
+ 0xf3cf4dbd, 0x1488f77d, 0x8b54b067, 0x4182e65d, 0xa7914efe, 0x187c82d0,
+ 0xc545f245, 0x525fa35f, 0xf9923fc3, 0xc45df814, 0x3176f971, 0x5d95c93b,
+ 0x27207aea, 0x52af2835, 0x67f9d4da, 0x2fc504b2, 0xe0879aa5, 0xb87ab679,
+ 0xe71e0bdc, 0xc2bab8e0, 0x34b8d146, 0xd7285c7c, 0x74d73f20, 0x2b73f288,
+ 0xa124bb45, 0x853f6bbc, 0x92f51fe3, 0x9e00bac8, 0x13345d55, 0x66d669e9,
+ 0x6643b90d, 0x0b925eb3, 0xe2b71b37, 0x671e08df, 0x6436f8f0, 0x1cdf6968,
+ 0x1bd707d0, 0x7d6c1f49, 0xb8c1a4c4, 0xe15be822, 0x973857e8, 0x099e1a55,
+ 0x532230f3, 0x6bafd7d6, 0x34693cb9, 0xacea9d11, 0xfa04e58f, 0xa5d1841f,
+ 0xeebeb023, 0x72bcec7a, 0x68e91b8a, 0xac72c1dc, 0x93639658, 0x2a7c60fa,
+ 0x933873ff, 0xd6f7e602, 0x7c1518fe, 0x5544d5fb, 0x2e1012fd, 0x8d53e581,
+ 0x69f2aa79, 0xf82a71e6, 0x5514db0e, 0x54d219fd, 0xce677c15, 0xb3faaa9d,
+ 0xf055f3ed, 0x544bc55d, 0xee3ae7f5, 0x2fcf9555, 0xbe55487f, 0x0546b9d0,
+ 0x7bf8aa2f, 0xaec5fd55, 0x92f95546, 0xe555279a, 0x9293f6c1, 0x3f726696,
+ 0xe79b56cf, 0x8be483a4, 0x0e46704b, 0x14a967ad, 0x3dd703fb, 0x53eb822a,
+ 0xe51af5c1, 0xe04178f5, 0x48feb1fd, 0xe29df20d, 0x91ed637f, 0xd75cff2a,
+ 0x3ec6c9e4, 0xec72fa13, 0xb2dd23ef, 0xc51fdc13, 0xc53bfcfc, 0x04fdd57f,
+ 0x56f683d4, 0x715ba647, 0xabbf43bf, 0xf9fd0f4b, 0xb7bfe435, 0xb40bd736,
+ 0xe7ae6e0f, 0x7aab957e, 0xc00d8ae6, 0x7ef38583, 0x828e78e5, 0x70447327,
+ 0xcf1860ff, 0x95fb26df, 0x52bf439e, 0xb03f6336, 0x17787e28, 0xac509bb5,
+ 0x467fa1f7, 0x7a08f6a8, 0x662e5b94, 0x07284836, 0x97ff5397, 0x5823ec2b,
+ 0xd2567988, 0x398daf56, 0xbd5b7da0, 0xc61ead6f, 0x69399756, 0xbcd0b3cb,
+ 0x1fc8c3cd, 0x94e668f3, 0xe7816b2d, 0xa25321ff, 0xf9104975, 0xf75f3f3c,
+ 0xd03db9c6, 0xa5956b5f, 0x706ae508, 0xf3bb9279, 0x941bb1e2, 0xd5f2bf3f,
+ 0xd1bfee0f, 0x671d75f7, 0x87ca029a, 0x24568bf5, 0x1d004732, 0x7ed08648,
+ 0x74c81ff9, 0x27ac9ee5, 0x5a33d63f, 0xcfc893d7, 0xd7ff2617, 0xddf0bdc4,
+ 0x3dcae979, 0xfe43a7a8, 0xea1f300f, 0xcf9ebcd1, 0x29e744bc, 0xbf40f352,
+ 0x2c3bfd47, 0x941edd34, 0x95ad17db, 0x5a07e8fd, 0xd097a91d, 0x7e324fce,
+ 0x0eea7e46, 0x83abb71d, 0x07e7f7ed, 0xb276edec, 0xedcbf7bf, 0xad5396ec,
+ 0x8ccf7f99, 0xe45a263e, 0xf98840f8, 0x09b546d0, 0xab12af28, 0xf9024fc5,
+ 0x4f523ba2, 0x498b047e, 0x6a983bf6, 0xc5017e54, 0x791dd06f, 0x6f7480bf,
+ 0x7e415ae9, 0x6017f47a, 0x75e5077b, 0x2417f609, 0xe8b4ff19, 0xb51bd8e3,
+ 0x23f206cf, 0x04fd1084, 0x27f8a1e1, 0xa3f1fb82, 0xccfb813e, 0x27d270ca,
+ 0x397dc782, 0x6650e4b3, 0xff48f23c, 0x7e503bc9, 0x7ed1d29f, 0x84bd1c38,
+ 0x1fcce149, 0x266f7ed0, 0x7223efb7, 0x91f95462, 0x0fe644f6, 0x64b35ff4,
+ 0x321127f3, 0x48cc5b0c, 0x51c6df7d, 0xbcdbdfd8, 0xbb3a13bf, 0xd841f48d,
+ 0x7bfed0f6, 0xeee7e64f, 0xab69465c, 0x01b7976c, 0x9cfa631f, 0xd9fa4cd7,
+ 0x843fe036, 0x4a257bb7, 0x4a1cdefd, 0x54ed7a77, 0x4c5bcbbe, 0x83af1ef0,
+ 0x72debde0, 0x9d79f74a, 0xb792ff94, 0x7a9fe082, 0x7bb6945d, 0x15ff286b,
+ 0x03e087af, 0x5f8206de, 0x44507d45, 0xa533753f, 0xa85b786f, 0x46dbd3bc,
+ 0x3f5e9bf0, 0xbdde5da5, 0xdbc87f94, 0x6f11f04e, 0xbcc7c107, 0x78f7045d,
+ 0xdb7d287b, 0xeff94bdb, 0xdc134f78, 0xb1938f2b, 0xfa2f5ee6, 0x84a25c2b,
+ 0xaeb3ddfa, 0xd7ea336a, 0x331a65b6, 0x9736f38a, 0x39fa0566, 0x78f255b6,
+ 0x86956d9f, 0x87a040fc, 0xb39f51fa, 0xf8fa7b2d, 0x405f2a34, 0x49b15be5,
+ 0xabac4a30, 0x56cafeb8, 0x159ea9ea, 0x77c1020f, 0xfd2b6adb, 0xb25b805a,
+ 0xbadca9c3, 0xedbb244a, 0x3a278d79, 0x245deb9b, 0xae3aadbf, 0x1074283f,
+ 0x22e9fb21, 0x974a44b2, 0xa3fc7365, 0x23ef4232, 0xfc4a5919, 0xc707b9a4,
+ 0xf182ab67, 0xf555be21, 0x5a5f8c46, 0x49f183ef, 0x3aae3fa4, 0xc3247804,
+ 0xc07f1178, 0x6cc2fc87, 0xad97d719, 0xaf08eb55, 0x94f365e4, 0xda346778,
+ 0xfa9e6de9, 0xa56f84b9, 0x36cd7e48, 0xfbe8a1d7, 0xe7ca4e50, 0xe1f1ac7c,
+ 0x50fe7f4e, 0xf082327c, 0xddb8c6df, 0xd2fa0c90, 0x00e310fe, 0xc7a9478b,
+ 0x198f78fd, 0x26f1fa43, 0xb2627acb, 0x3d8ff9c0, 0x6dff122c, 0xc1f7a067,
+ 0x7e81cf77, 0x503943e7, 0xfa156fba, 0x72cd1eab, 0x3c02cc4d, 0x3f8d247e,
+ 0x531c0224, 0xaf4fdbce, 0x1ea0f717, 0xae7deb0d, 0x3e37f209, 0xb689d9b8,
+ 0x6966ec71, 0xdb5bb22d, 0xd01357b2, 0xa82c95ff, 0xcb4947d7, 0x3bb63c65,
+ 0xd5cf7b78, 0xb64fe48b, 0x76903aae, 0x865bf784, 0xfa8e26fd, 0x61ba187d,
+ 0x1a481632, 0x55c91914, 0x2fec45e2, 0xe5cda1ec, 0x66fc5fd8, 0x215fd287,
+ 0xe775f7f6, 0x65e3e469, 0xbc085756, 0x37279386, 0xb38b2393, 0x8e48e322,
+ 0x9424b124, 0xb8ebcf23, 0xe49df2dc, 0x861d24fa, 0x1fb43499, 0xc4ae7e25,
+ 0xe8e383d3, 0x243d3235, 0x61c74219, 0xfde80d57, 0xddb7aa3e, 0xe749c9b1,
+ 0x0b3e304b, 0x6c75ab45, 0xeaf3ae05, 0xdaf37092, 0xa4a0f410, 0x018e505b,
+ 0x468bdfdf, 0xb9b3b523, 0xe1a3b79c, 0x56cadced, 0x32625c11, 0x6bc842fb,
+ 0x6e5a7d25, 0x4e2c81e7, 0xbe0f49b7, 0xae18f1b4, 0x3a3adbef, 0xc69cf413,
+ 0x04ed11bf, 0xc92d09df, 0xfb6d44d7, 0x78013d8e, 0x79e3cb35, 0xb5cfef4e,
+ 0x7b40ff23, 0x915728f9, 0x7fc9f25f, 0xcc0566c1, 0x5addf2bb, 0xa3fd8fd9,
+ 0x29a21b6b, 0x2eb55cbe, 0x36a3f50c, 0xb07a2466, 0x85d13cea, 0x4560f401,
+ 0x1f410cba, 0x4af4b2fb, 0x3254d53c, 0x7c32e311, 0x728a9e5f, 0x583ef009,
+ 0xe1fb451d, 0xdeef65d4, 0x5be01639, 0xd47688ae, 0xe5ab9ecb, 0xfd2713e7,
+ 0x26e74351, 0xdb9c7cde, 0xb7fdb77d, 0x7bf41eb2, 0xb3e9c827, 0x7a41e768,
+ 0x77b3334b, 0x52dcbac1, 0xcdff226d, 0xb3c557ad, 0xb91a7681, 0x7da3c7a4,
+ 0x5335fdc1, 0x803ca1fa, 0xa67d26fe, 0xaa330fae, 0xa1233d45, 0xab6f9d4f,
+ 0x1a66703a, 0xcb56d3f4, 0xf6bb6e3f, 0x7d8471fe, 0x93f21af5, 0xf429f500,
+ 0x4dfe4093, 0xe78097d1, 0x191a3716, 0x32eb73c9, 0x41e519a3, 0xe49c25b7,
+ 0x1362db5f, 0x321ba1e9, 0x9ea18757, 0x8faaa86c, 0xdea474c6, 0xa77d03b7,
+ 0x7dffbbdd, 0xe4812d9e, 0x817f3f2d, 0xfa0c5984, 0xae7abdc0, 0xb6faf8e4,
+ 0x7944cb4c, 0xc3f2a1a9, 0x8b7dffbb, 0xac077d0f, 0x3490f085, 0x7e0f912c,
+ 0xe29bbe00, 0x2fdf02d4, 0x444e6740, 0xabae74f8, 0x4243e507, 0x8b1baf9c,
+ 0x56ce9ab6, 0xcae2f9d2, 0x5d33e238, 0x31e987b5, 0x18c8b2bf, 0x9f0ae7c8,
+ 0xfffcb5fc, 0xbbe71cb4, 0x59b81c99, 0xf7e337bb, 0xbe73a59f, 0x369ece19,
+ 0x154f230c, 0x9acf18fb, 0x4b6c8a63, 0x7d59eafb, 0xf6eafd48, 0xc567ce6c,
+ 0x643e7e7a, 0x72f4c54e, 0xfaf8c38a, 0x96c73c44, 0xa9f9cd93, 0x714912cd,
+ 0xd674b6e2, 0xdf037185, 0xf7f70d72, 0xdafff1c4, 0x3fc9d32a, 0xa2782ad4,
+ 0x3e78197d, 0xeb8695c2, 0x147306d7, 0xa6b7fd09, 0xfcceb972, 0xabc6331e,
+ 0x409a9da1, 0xf3dec1fc, 0x9198e9a9, 0x0bfe4c3e, 0xa49ef12d, 0xa3b7f00f,
+ 0x17fd1c5f, 0xdadddfc1, 0xbf6f86af, 0x984b86aa, 0x354f054e, 0x6669e1aa,
+ 0xe6c96c35, 0x361dfa7a, 0x490cfe75, 0x1ca7270d, 0x73f0d309, 0x7f01a6ed,
+ 0xbbf044b3, 0xa07e0199, 0x01769a0d, 0xafa525e7, 0xadb2fc96, 0x93dfdca9,
+ 0x73f6af5c, 0xb596b224, 0x6df90231, 0xfcb6f954, 0x73fa0255, 0x7cead56c,
+ 0x8c150798, 0xbff48acb, 0x9f95d724, 0x02e9718d, 0x4b3aee7e, 0xc5cde9eb,
+ 0x238b6875, 0xcf934a3e, 0x1fdd0d05, 0x95b8d0b7, 0x7c0f9076, 0xfa45e301,
+ 0xe62f840f, 0xc76726ba, 0x05f03e73, 0x7df997ee, 0xa503e43a, 0x41f8e1bf,
+ 0x3962c7e1, 0xab9ca26e, 0xa5b722b9, 0x97a9ab9c, 0x0475c7cf, 0x92b9c79d,
+ 0x81e7465c, 0x09aef4ae, 0xc877c50f, 0xce6cbe67, 0x946e9877, 0xdf20d7cf,
+ 0xef9cf4f9, 0xd5f0df30, 0xfd28672a, 0xafbcbcf0, 0xcc37b43c, 0xf8c071fc,
+ 0xab47b656, 0x82477760, 0xd3bcf039, 0x740ff843, 0x3a3337ba, 0x0f2b5a47,
+ 0xbf338be7, 0xe908d3db, 0x0b975a5b, 0xd66567d7, 0x338f3d59, 0xfe51ebf5,
+ 0xdff7979e, 0x38dd820d, 0xdb94c05a, 0xbb668da5, 0xccbdfd11, 0x57f2a19f,
+ 0xd5877e28, 0x31acd22b, 0x0188ff80, 0x4cd3823f, 0x33e34de7, 0x35118fc9,
+ 0x2b3771d5, 0xccf73c04, 0xa2046f98, 0x554e85dc, 0x658fc790, 0x97d0fd97,
+ 0x035e383c, 0xce02abfa, 0x0f441923, 0x3573b923, 0xe7014995, 0xff655bca,
+ 0x9b1f00c5, 0x7f609796, 0x7896cc3f, 0xd679863c, 0xda9fff72, 0x6ab8665f,
+ 0xd833b553, 0xdfaab27e, 0x722fd956, 0xfed5f6f3, 0xf4d5c337, 0x0ecfda61,
+ 0xb21cdf6a, 0xd576c1fd, 0x11afbc7e, 0x3e436f1f, 0xb5ffce18, 0x1ba7965f,
+ 0xf45e9e6c, 0xd818e97f, 0x06071495, 0x6a8898fa, 0xc369ff23, 0x5d5379f9,
+ 0xa60fdab2, 0x1f927e63, 0x90d647cf, 0x3e6048fc, 0x9859df8a, 0x47d7f287,
+ 0xbbf1e74d, 0x1371b960, 0x8798c179, 0xfd00dea1, 0x3f57f2a9, 0x46d3f7c2,
+ 0x3c42eec1, 0xfff3c783, 0x89abdd8a, 0xfa4bdf1c, 0x64b84a73, 0xdbde81b8,
+ 0xe32575ea, 0x3dc21bf7, 0xfeeb1835, 0x762ebb3c, 0x1b3de83d, 0x7c08c630,
+ 0x71bb3576, 0xfb84cfbe, 0xf58fa724, 0x27a21a71, 0x1d96ddcb, 0xb27a00da,
+ 0xa8695de8, 0xf2345af7, 0xa1fc2f39, 0x65bd6cbf, 0xfd10a6e7, 0x029bfa2b,
+ 0x8f002b5b, 0x956dba00, 0xfe81e6f5, 0xd0ee2496, 0x3163b406, 0x3fa90ab8,
+ 0xd2a35ce5, 0xeb37d35f, 0xf7ecab6f, 0xdeb3fa52, 0x559f1ea3, 0x59f1a1ef,
+ 0xe947fde5, 0x2f8e2b6f, 0xb4dd5f04, 0x1e8ed93f, 0x7aa96fe8, 0x8783567c,
+ 0x72d567c6, 0x7f40e1ff, 0xbfacdf4d, 0x931ef936, 0xe1d3e64d, 0x0e37fdce,
+ 0x1a76ab9c, 0x29b4ae51, 0x7f7940fe, 0xbfb414bb, 0x37f796ad, 0x714bfbe5,
+ 0xbddfe4e9, 0x18df33d4, 0xfdc35f6a, 0x247ac98c, 0x2648f593, 0xcf0891eb,
+ 0x3ea67a99, 0xf0b0e81e, 0x22f9b6c5, 0x1e73e3ec, 0x153e333a, 0xf62f19e0,
+ 0x5f6117cf, 0x99e2f39a, 0xc9f04903, 0xccbe2fcb, 0xe6787fcb, 0x9b94324a,
+ 0x2fcdef7c, 0x962a3803, 0xde0ac7ef, 0x8db7bf4a, 0xbba37ae2, 0xbfee73e1,
+ 0xfb8af904, 0x87aa6356, 0x42f17fa1, 0x32d47f72, 0xe94eefa8, 0x310f2cb7,
+ 0x6eea4a2f, 0x467e4f38, 0xff287914, 0x40bfe1e6, 0xee53cfb4, 0xefab9467,
+ 0x6d454467, 0x8c2ffd22, 0xef28cdf9, 0xba0e8c22, 0x28d6f84f, 0x642c1fbe,
+ 0x376e0af6, 0x39f25948, 0x31cfba0d, 0xd76e58bf, 0xb1cfcb7c, 0xb1c6a17c,
+ 0xdfd9ed1e, 0x478aaa4e, 0x173958f5, 0x7f783797, 0x1bf5d772, 0xbe0e1f9c,
+ 0x23e7393f, 0x23c2eb81, 0x3ba5bfb8, 0xb9f7e257, 0xa886fc02, 0x9f370ef7,
+ 0x7db8a3b5, 0x0e9f383f, 0x0e319f3e, 0xfee69f3e, 0xfeb0b5a8, 0xcb7ee8ee,
+ 0x5d9fc413, 0xc86be721, 0x5fcd06bc, 0xd8a628fd, 0xb7a45a79, 0x32b7cd9b,
+ 0xc1f9caaf, 0xa2ca4146, 0x794feafd, 0x3183fd2a, 0x8e2a14bb, 0xb819f483,
+ 0x4e6deabf, 0x5d19fe86, 0xcf073d9c, 0x45fe3795, 0xde5cf21b, 0xd63e796e,
+ 0xb9d38546, 0x3d28c6ce, 0x51dddbd9, 0x97fa1933, 0x9a74d345, 0x72a8b297,
+ 0x8da96f3a, 0x8f68ed65, 0xd7239f06, 0xce9bb88e, 0x68ad6901, 0x703a4041,
+ 0xa461d92e, 0xe8b989f8, 0xc5c8e786, 0x8f239d9b, 0x91cfc999, 0x7425e947,
+ 0xea45b459, 0x7f239e43, 0xf7df146c, 0x713c71bb, 0x278c3f88, 0xa21c706d,
+ 0x31d1c799, 0xf5f2023f, 0x7f231766, 0xc7de3cba, 0xea5075e4, 0x861ecc1b,
+ 0xb7ab40f2, 0x68a7a84b, 0x613ef9c3, 0x4e5869b0, 0xf7c8bf08, 0xfbe8e947,
+ 0x34cd724f, 0xd7231aaf, 0x5afce7cb, 0x7a4fe908, 0x4fe29475, 0xc3674d0a,
+ 0x0d3cc9d1, 0xf0a7473f, 0x9e9302e1, 0x302df7ce, 0x0fd14ad9, 0xef0800b2,
+ 0xfa8098b3, 0xf7e22db7, 0x0dbb4581, 0x5337e7e9, 0x6ff9ff6e, 0xb9f9ba18,
+ 0x43353e7c, 0x4ee3f747, 0x8f61cc09, 0xd57e7a19, 0x869e8ce9, 0x66bb9a6e,
+ 0xec87599d, 0xeff2e2f7, 0x867b6115, 0x167553e3, 0x779fec89, 0xa85ca146,
+ 0x0f1f5b4e, 0x42caa2f0, 0x94dfdd1d, 0x08ee44e3, 0xd19fc72e, 0xa28e4eba,
+ 0x51e7d178, 0x624748a5, 0xa3e22a7f, 0xea0289c4, 0x9e2a37bd, 0xd7e1cdea,
+ 0x18dea0c5, 0x7f67d394, 0x1eb462ef, 0x127a50b6, 0x302c4fda, 0x07cb236e,
+ 0xf302a3b4, 0x01627ed1, 0x2f2c27eb, 0x9085f6b6, 0x609a4a17, 0x0d5292db,
+ 0xd0909e7c, 0xff92a942, 0xee5b43ac, 0x57aeb10f, 0xc6fd75e5, 0x601b4c76,
+ 0x8ed0713b, 0x2ae5fb01, 0xd517dbce, 0x61e32ca7, 0x17657548, 0xe9b18ec9,
+ 0x88933e15, 0x1e6106bf, 0x45fb04af, 0xd5b0de75, 0xfba14beb, 0x6d38f2fe,
+ 0xa346d62b, 0x1c55031d, 0xbcdb9f48, 0x9965296d, 0xcec8e383, 0x8d13e991,
+ 0x17a889b6, 0x5c725ff3, 0x97f40ccb, 0x74349b24, 0x5326013e, 0x6e612f75,
+ 0x38b4f459, 0xccdd4534, 0x2ed0926e, 0x3f3d25ef, 0xf896bae1, 0x62f0e120,
+ 0xa4ab7186, 0xef0176b8, 0x23f40d03, 0x97ae6fdf, 0x5c57b9e3, 0x048e3465,
+ 0xcefec0eb, 0xf38d0ec8, 0x747945cd, 0x518e69e5, 0xe5d58fc2, 0xdcfc71c9,
+ 0xe1d5fdc2, 0x3ae8097e, 0x4057b6a9, 0x380c0138, 0x5c27c5f4, 0x426b4c6f,
+ 0x045af279, 0x6db58bf9, 0xf207cc99, 0x45745527, 0xfb3ce0e5, 0xc9a6ffa5,
+ 0xdf0b0790, 0x9c207cad, 0xa136b3f4, 0x25d90665, 0x285869f7, 0x1c98cf3f,
+ 0xc828c7ee, 0x609ffce1, 0x1ea94d6b, 0x44d3e987, 0xcf975f37, 0x1db39067,
+ 0x9f11d9f4, 0x1c58fa2d, 0x759a7bd4, 0x9b73e9a1, 0x7ec0efdc, 0x185fcf21,
+ 0x7f911973, 0x3b9382b5, 0xdbeef739, 0xce82cfb7, 0x55e74613, 0x8d7ac936,
+ 0x4e444ed2, 0xd846153b, 0x45cf0c1d, 0xdf07660a, 0x9b3ecc07, 0xf9abd60f,
+ 0x7b486d2b, 0x791cc1eb, 0xb26b491f, 0x4cb2fd61, 0x94fd0dbb, 0x1a55f7c1,
+ 0x70da26d3, 0x0c671a7d, 0x7031a9d0, 0xcb4ee85f, 0x53cf1f7e, 0x2c747a99,
+ 0x70591cf0, 0x2173c7aa, 0x972837b1, 0x1d3797cf, 0x9b42e7e2, 0x78bd454c,
+ 0x14c9a10e, 0xfec74457, 0xa99cfc4c, 0x3a64df52, 0x64def246, 0x1356f1e7,
+ 0xa2020fee, 0x3ba1e7c7, 0x83cd18ed, 0x0e5a6f52, 0x7b26ab97, 0x5bfbc317,
+ 0xd53f76e1, 0x3e9d130b, 0x161fe00d, 0x4ffee8c7, 0x55f39198, 0x318fac04,
+ 0x7e95ef80, 0xd1d1cb6f, 0x172535bc, 0x7e1096f5, 0x6704de22, 0x1b22b64d,
+ 0xdf38dbed, 0xb4636fd0, 0xaf9cdf42, 0x5be7971f, 0x3e51a769, 0x434f7aff,
+ 0x58b2fcce, 0xd73913f4, 0xa6bb60e4, 0x83b446e5, 0x6fe391b4, 0x6186ded8,
+ 0x285e6bdb, 0xf238f7b7, 0xc8b23685, 0x50e9ed8c, 0xc3a0845e, 0xfe76e467,
+ 0x30ede357, 0x97df74b3, 0x9f305a60, 0xa3de942d, 0xa38c46a4, 0xddfa1b8f,
+ 0xebbf9637, 0x90247ed4, 0xfc717bbf, 0x1ecf932b, 0xee1ca12b, 0xdb2eda3f,
+ 0x619d8a27, 0x2ededb91, 0x3ee87bf0, 0xef4edc21, 0x8776c836, 0x0f3d4c25,
+ 0xf941f783, 0xe0ae5c3a, 0xc72ee6e7, 0x046b8a31, 0x77e5f3f3, 0xb40e8a3e,
+ 0x73ef504f, 0x04bb7364, 0x1c4bb453, 0x610d9fb2, 0x9da01bf4, 0x80fdf0a2,
+ 0xfa42b75f, 0x3f005ba7, 0x0d6fc803, 0x7b242bb4, 0xc90dbe88, 0xe7c8697d,
+ 0x053bf2a9, 0x5cd7f643, 0x4785a72e, 0xfe434b3f, 0x4feb8b2e, 0xf982efc0,
+ 0xae4785fc, 0x5e78e026, 0xce703198, 0xab43e286, 0x7bf3a717, 0x1cffc7d9,
+ 0xfed10aed, 0x457feecd, 0x86b4dd9d, 0x5ce5c0f4, 0xdf5bfc0f, 0x8cbedb07,
+ 0x821d9deb, 0xcda4efda, 0x5fe77ae5, 0x7acc7de4, 0x2df7a455, 0x2eb965ce,
+ 0x0ab61f20, 0x7f28e5e6, 0xe7e11f53, 0x5e3f56e6, 0x2103d9ff, 0xed1841f8,
+ 0x804e73fa, 0xacdc5c3d, 0xa35a3f27, 0x8dc47d29, 0xafc31ce2, 0x71cb87b3,
+ 0x1e4b7d79, 0x24f3f235, 0x5b17ae2e, 0x39d3f75c, 0x23f3e095, 0x243bd5c3,
+ 0xbea53dcb, 0x7947db01, 0xfe479a62, 0x23684b80, 0x964dbfa0, 0x7678c17b,
+ 0xf3c864e2, 0x12b90463, 0x18456875, 0xed93abb6, 0x3f8aedb1, 0xe8c8a2a3,
+ 0xb75ef808, 0x1a58c8b8, 0x8c8d2f40, 0x6e0ddf9f, 0x01dcceff, 0xafa55a7d,
+ 0x459f70e8, 0xf89c50df, 0x433901a7, 0xcab8658a, 0x0ffa518e, 0x70163f3e,
+ 0xf38c2c5e, 0x5a67b729, 0xe818dcf1, 0x962b6bb7, 0x6df9c48f, 0x582f5d15,
+ 0x3ffa1e61, 0xe739d030, 0xecbe650f, 0xb872f993, 0x43b1f3f5, 0xf6318ca0,
+ 0x97823b04, 0xc64e80d6, 0x68fe408f, 0xfb94d4cc, 0x5cb38c43, 0xfd08671e,
+ 0xafdcd6fa, 0xe6975fa7, 0x51afd086, 0xc504767f, 0xd461021f, 0xf4211d9b,
+ 0xec8213eb, 0xedcf900f, 0x1d49d09c, 0x270f307d, 0x6f611d6e, 0x919ee894,
+ 0xf6045ec3, 0x32678bc3, 0x239f6f51, 0x23c7bc0c, 0x608c31db, 0x221623b0,
+ 0x6799735e, 0xc50203df, 0x48ee5a51, 0x5c04eea3, 0xa7ad9b8f, 0x3711fb24,
+ 0xdc613ac2, 0xb2daf5a1, 0x0ce2a119, 0x274038ff, 0xef02ba28, 0x042ac007,
+ 0xc48695c4, 0x63e282cb, 0x38194e18, 0x5a1dabff, 0x7562aeff, 0x35e36afc,
+ 0xac30bfee, 0x0427fe60, 0x2eaa1f3c, 0x0bae5f9f, 0xe2a9cf8e, 0xba9d0b5a,
+ 0x887c7c60, 0x6f8cb26f, 0x2907b6ca, 0x452d3e0e, 0x64acfde4, 0xc707cf64,
+ 0xbd850cbd, 0xc3ea2d0e, 0xf7f48c15, 0x9e363f60, 0x5eff2517, 0x09cf6305,
+ 0x7d5ade74, 0x59e9e4df, 0x1cfbf8e7, 0x8fd8e52d, 0x50c3532d, 0xafbe0e3f,
+ 0xf09bc4a0, 0x7de04c98, 0x22dde569, 0xe10d62cb, 0x53b77cc7, 0x8797e2b9,
+ 0x4b12a6fa, 0x55eeb9c0, 0xdd3ea06c, 0x1e85f2a3, 0x59d6d6f7, 0x1c4fef14,
+ 0x82ec29ef, 0xa33b24a2, 0x66aa4879, 0x3cc00764, 0x86fae2a8, 0xce345d94,
+ 0xc58c354b, 0xaaa038f2, 0x7076013c, 0xbf184fa4, 0xe30fce2a, 0x76c1c154,
+ 0x4deccde7, 0x0de64a43, 0xfccdf9e5, 0x5e39068d, 0x646e46f8, 0x633be91c,
+ 0x77d418d8, 0xa69f8b2c, 0xeb04b8f5, 0x34597e81, 0x03c54284, 0x68fb4337,
+ 0x5f90ba07, 0xc4dfd1e2, 0x30caef54, 0xc9f74887, 0xb38e6284, 0xf1e4eb10,
+ 0xfc467ce1, 0x9507086d, 0x9859f80b, 0xbce0706c, 0xc3000c1b, 0x333d0590,
+ 0x56be4026, 0x15af37f6, 0x33308898, 0x4fdc8ddb, 0xe36bbca8, 0x866d77a7,
+ 0xff7407eb, 0xcfec30be, 0xfa53bfc7, 0xdb8ef219, 0xfb27be0d, 0x7dfc1ccd,
+ 0x951df919, 0xff9b87fe, 0xfb6ddee1, 0x2777d4c3, 0x3267bf70, 0x20e56bd1,
+ 0x4cbc12bd, 0x1efc47a6, 0x4abdc2e5, 0x0c77adb1, 0xfb3c37de, 0xfd1d8470,
+ 0xf0e303e0, 0xefe5a9dd, 0xed75fdd1, 0x9361e00d, 0x8c0fbe48, 0xafef6e4b,
+ 0x02fd171d, 0xbc06dae4, 0x4fe78434, 0x279d192a, 0xcf4ab8b0, 0x000e7489,
+ 0x1392a0c6, 0x4013ef01, 0xf10e1b7b, 0xf15baf73, 0xb0710b9d, 0xd02bd45f,
+ 0x4255b06e, 0x483b087e, 0xbf19ab49, 0xd5e0ac1f, 0x1a3d07a8, 0xf5c352e9,
+ 0x3ea6d9e8, 0xe935cf11, 0xe445fae2, 0x2e68e71f, 0x37e807c7, 0x0bf9d19e,
+ 0xce7c926d, 0xdfc4a471, 0xfbe4cb4d, 0x84cfd29b, 0xfe591ad1, 0x47fbd2f7,
+ 0xd54e23b3, 0xf2c6764b, 0x442fc5f6, 0x11ecfcff, 0x00d3eaa7, 0xe167d82e,
+ 0x2ba9d270, 0xecc66669, 0xd10bacfb, 0xef3b3f9f, 0x807495d4, 0x78d9f68b,
+ 0x464614f9, 0x097df8ce, 0x319fd10b, 0xd559b461, 0xd7385bfe, 0xd53cdff1,
+ 0xcf21341a, 0x5a36df63, 0xe8c94f39, 0xf3b3ad3e, 0x2e31a797, 0x47f654e9,
+ 0xdf482e87, 0xde0b2281, 0x717f9323, 0x9d0f1451, 0x9dd9d329, 0x1452eef8,
+ 0x68bb2dfa, 0xfa0d477e, 0x6bfe9fe9, 0x4382f4fc, 0xccca9779, 0x1bff812a,
+ 0x2c2b981b, 0x99ee8023, 0x9f9d7343, 0x81b8a603, 0xffd28f82, 0x6960bc10,
+ 0xbc4098c5, 0x0a3b51b6, 0x0d0a175e, 0xc70587a4, 0xfd082e87, 0x549cf1db,
+ 0x2fd6cfc4, 0x10ba75c2, 0x002a9fd9, 0x9eb79e1c, 0x7c42edd6, 0x1ec176ff,
+ 0x3af8eb00, 0xa22bef56, 0xd6a3fc75, 0x027a3d51, 0xdfc5dbbe, 0xe396686f,
+ 0xbbc64f50, 0x019f687c, 0x32b9d1dd, 0xfc9e8a5f, 0x05e36548, 0xb03fa047,
+ 0xcbf7346e, 0x69d3925c, 0x49cf1686, 0x01f74ba0, 0xfa85ad81, 0xf5976bee,
+ 0xeecc9fa8, 0x3d47a33c, 0x19c0eeba, 0xad4bde3d, 0xa9da1843, 0x8477a6db,
+ 0x32feffd2, 0x97f2ab5a, 0xd1d77629, 0xe8f5ec94, 0x16abab77, 0xeade1ee8,
+ 0x6e1fb9d7, 0x251c32f5, 0xb2df7763, 0x55b8fc9f, 0x98f5eece, 0x477d652e,
+ 0xc588ddf1, 0xdceaad2e, 0x089a92c0, 0xcabe3c55, 0x9782ab13, 0xc0eac0b6,
+ 0x21b4bb3e, 0xc31df549, 0xef82cf5d, 0xd0fe0e28, 0xd790affe, 0x736db171,
+ 0x16bbfa2f, 0xcc7ad4bb, 0x62b5ceec, 0x11ede20c, 0xfece1aec, 0x84b77e12,
+ 0x00d2108f, 0x7de60abd, 0xa3d7075a, 0x648c2aea, 0x0c22549f, 0xab595af3,
+ 0x7393e3f5, 0x54f45347, 0xa810eeee, 0xbb972ddc, 0x576e046b, 0xa975f2cb,
+ 0x8392e38c, 0x75d1a727, 0x37a39f52, 0xa5df0033, 0x88e7e515, 0x437d651e,
+ 0xc4855719, 0x290d8df5, 0xddb0e9ef, 0x5817dfa5, 0x4b8d1a6c, 0xa92d47a5,
+ 0x1e55c351, 0xd59e905d, 0xbdf943a7, 0xff9d41b4, 0xbef2d1f3, 0x90f2c79e,
+ 0x2d18de9f, 0x07189f88, 0xbca53fe1, 0x81ef0277, 0x0f3ad25d, 0xead67d22,
+ 0xdf700abb, 0x1175a4bb, 0x7e4394ac, 0xb8afdf1d, 0xce01a2be, 0x751befc3,
+ 0xa7de330e, 0x8814adf5, 0x00b0976e, 0xb06d27bd, 0xa1dac13e, 0x7722bf70,
+ 0xe4f59cc3, 0x98283d0f, 0x13286f51, 0x83de221d, 0x8fc61c6f, 0x83e6517e,
+ 0x1f2fac13, 0x2246caf1, 0x9eca7585, 0x99f6823f, 0xf996b7ec, 0x3d948e30,
+ 0xc4bf204e, 0x4371809d, 0xc922a611, 0x37b03991, 0xad9a4184, 0xf920af6d,
+ 0xe66f563e, 0x58da62ef, 0xfc70bca0, 0xbe701333, 0x0bb27510, 0xfde87b93,
+ 0x9b6d39bd, 0xcc5ca22f, 0x3d1470cc, 0x193df805, 0xf27ffbc6, 0x16bfc175,
+ 0x3fcba9da, 0x0ad3f246, 0xd6fd81e4, 0xda3964d9, 0x5acff6a1, 0xc121ae51,
+ 0x7ea7cacc, 0x32f89413, 0xc3ed15d0, 0x9fa4a55d, 0x9f7ee558, 0xddb8942d,
+ 0x2e7ca0fc, 0xe2d6f98d, 0xd1befaf9, 0xf495f28c, 0xcaabfb1b, 0x5e283104,
+ 0xe61a3750, 0x4fada579, 0x5be9de75, 0xe901bf6c, 0x187db82c, 0x395e2abe,
+ 0x8a2d7b4d, 0xcc1d77ee, 0xfee8deb0, 0x3ea8d694, 0x8733a4b7, 0x53bbdd07,
+ 0xf6d99fcb, 0x777ba0a4, 0xeef74119, 0xddee82f2, 0x2df9efa9, 0xba094e74,
+ 0xe7bea777, 0x54cdb067, 0xe6930fd5, 0x9c88e0a9, 0x23f555bb, 0xe7d5cbed,
+ 0xbcff8eae, 0x77c74842, 0x2e7d7d06, 0xe0668798, 0xc198e28d, 0x0a2f247d,
+ 0x3e1a432a, 0x6984cc2e, 0x0ba1a173, 0x9139a4e9, 0xe386e7db, 0xa0badb0f,
+ 0x9788e31d, 0xfc6fe88c, 0x452fe089, 0x9f28c4fb, 0x18fd1953, 0xaf33ed53,
+ 0x52be7015, 0x5cf2dbd2, 0x7d61f3b3, 0x494af7f2, 0xdee01dfc, 0x463eb8d1,
+ 0xf9036c7c, 0xaf7e55e6, 0x476cac78, 0x5f3ced28, 0x0f353258, 0xcc7fcfbe,
+ 0xece28331, 0xf07efc1d, 0xa78f3d4e, 0xe7e55ef8, 0xfa3bf35b, 0xfe008e34,
+ 0xf5c7993e, 0xa59c6790, 0xeba91f14, 0xf9165d84, 0x1eaceda9, 0x75d465ef,
+ 0x7ee14776, 0xab3ce056, 0x60c9bf47, 0x89cfbcbe, 0xaf68e1fd, 0x743dacff,
+ 0x9e6d6d3c, 0x98e3f89e, 0x1eabd72c, 0x91bb72d6, 0xb9e16639, 0x575e4571,
+ 0xabe3e7ed, 0xe7e7a85a, 0x1d1a3160, 0x9c836e42, 0xc396ab3e, 0x707ef50e,
+ 0xca3d7f8b, 0xaadf900e, 0x4c174b7a, 0x12b7bb27, 0x31f236e4, 0x797573c8,
+ 0x17c91372, 0x7caae790, 0x3c80de77, 0xdf0ebfcf, 0x426a769d, 0x8170f38e,
+ 0xda78f348, 0xffe69535, 0xf4479819, 0x64333da7, 0xde7cf8de, 0xc65ebe6c,
+ 0xb7580fb5, 0x2ebf7ae0, 0xf2f6ebe0, 0x7dfaf230, 0x0a775d79, 0x4c2845bd,
+ 0xa270cedd, 0x634625db, 0x387b9e09, 0x1365f296, 0x7eaae1c6, 0xfd3dd02e,
+ 0x6e3eeb7f, 0xbf5ffd41, 0xfd05a8ff, 0xa3f6ee61, 0x594db016, 0x8b5a4ead,
+ 0x85d03c7a, 0xba9ef51d, 0x7fc22e8e, 0x6eb8fb65, 0x21d95fcc, 0xee3dfbd0,
+ 0xd3a71703, 0x135f5938, 0x0e770bc6, 0xf28fd783, 0x37befeb8, 0x307ee24f,
+ 0xfb89f417, 0xdf8301fd, 0x801d202f, 0x5ebc425c, 0x35e5f017, 0xb1a373b6,
+ 0xf51e9422, 0x1f7cf26f, 0xe867a8d9, 0xef85afaf, 0x52c71c71, 0x488de98e,
+ 0xb205fb47, 0x27edddb5, 0xfb604617, 0xfa863af5, 0x17df8285, 0xe21fbd29,
+ 0xd6a83ff8, 0x3580a7a1, 0xbe696b56, 0x52d7a83f, 0x74fbda3b, 0xc15e2f04,
+ 0xae1c55cf, 0x0929a8fe, 0x56a0fdda, 0x530c7ba0, 0x31f3fbef, 0xe0af1784,
+ 0x3d305afa, 0x4c1af42b, 0x3bf4c19f, 0xbe6b4e84, 0xc91e9d19, 0xe4d5ef93,
+ 0xe7dc02b1, 0x59a7dd61, 0xe11e7e91, 0xae2be3f7, 0x7fa1d61d, 0x6cc9bd33,
+ 0x31e0027f, 0x0b7aff5a, 0xbcc389ca, 0x8776b0bc, 0x748de5c0, 0x5261f237,
+ 0xbda19eb3, 0x971e7efb, 0x7ae3ef4b, 0xfad0e3c5, 0x31af8c05, 0xe51d37b1,
+ 0x4f1c9a52, 0x2ac7457a, 0x905c53f6, 0xaf319bcb, 0x96ef54d9, 0xbd71e537,
+ 0x40839143, 0xe4fdaee6, 0xc44f6d97, 0xcb2f147b, 0xe55341e7, 0xfa32b2f6,
+ 0xf485cfa7, 0x672f4caa, 0xf8143c64, 0x6cff4cb2, 0x1f68cfdb, 0x59c72d9f,
+ 0xd1743666, 0x833ccc79, 0x879453eb, 0xabdf52b3, 0x39ae7dc5, 0x3a7cedfd,
+ 0x25378d67, 0xc9fbe226, 0xd27877fc, 0x60d6dba7, 0x9c372fdc, 0xe0ec31d6,
+ 0x381e7453, 0x35bc6b2c, 0x49439c54, 0x7a2557dd, 0x6aeeb08f, 0x3c0aa53a,
+ 0x7d39d0f7, 0x1701d91f, 0x5c9f13a7, 0x2ddea9b5, 0x7bc654fc, 0x5d3ef28c,
+ 0x80f3f727, 0x8b8b169c, 0xf329eb06, 0x1c659e80, 0x2ed6586f, 0xab35af5a,
+ 0x75a92158, 0xcefe29ec, 0x0149ed66, 0xa458bddf, 0x304ce873, 0x608defdf,
+ 0xfc8b1f25, 0x3657241d, 0x748c4dc6, 0xd784fb2f, 0xd7af704c, 0xaf29f046,
+ 0x61ade944, 0x687c88ce, 0x4f11e167, 0xe1dbce16, 0xde275694, 0x8ef0bc57,
+ 0x336ba64e, 0xd32e2fbf, 0x2d4ee5da, 0xeb9c6233, 0xc2e3e800, 0x5cf7fe20,
+ 0xddfba44d, 0xa0fec3bf, 0xbf0d959f, 0xaf677921, 0xed1d38b9, 0x33dac2a2,
+ 0x1bbb084d, 0xf51d3cfe, 0xff610f89, 0xf41ebd20, 0x72809b7b, 0xd3bd24e4,
+ 0x8635795d, 0xd35979da, 0xcbf91d3f, 0xf740a6f7, 0xb8ec3e6f, 0xfdf2b7a8,
+ 0x7873dc89, 0xf2fd1c2f, 0xb9a3f2b3, 0xd42ce91c, 0x243afad0, 0xddeb3bd5,
+ 0x0a2bffa3, 0x20d8c3d7, 0x7e0a7afd, 0xc865a3df, 0xfb4a9bbf, 0xe421cca3,
+ 0xdff469ef, 0xb071f365, 0x15e5a1ec, 0x9e165f7a, 0xe990ac93, 0x3cbcb838,
+ 0xa13fc07f, 0xebefca73, 0xa1fe0108, 0x3fdfc62a, 0x2ba7bb05, 0xaab8f81c,
+ 0x67f92a73, 0x0dc23caa, 0xd1c333fd, 0xeb4dd7e1, 0x28cff718, 0x818dda30,
+ 0x1bb44d7e, 0x1f7faa99, 0x252b077f, 0x74f786f3, 0x14897ddc, 0x666bafcf,
+ 0x795aef14, 0xe7a53475, 0x2120df5f, 0xfbc318ff, 0x6b7ee95b, 0x8cec86b6,
+ 0xfeb53e95, 0xcb80a533, 0x7c052985, 0x60f95cde, 0x01b0e52f, 0xa2ec097b,
+ 0x5db9f37b, 0xa9887514, 0x7ce0a5ec, 0xf28c97b2, 0x13101d3d, 0xe04257ae,
+ 0x6941477d, 0xca977e0d, 0xd9ce885a, 0x72fefc3b, 0xe4d738f0, 0xf8553e73,
+ 0x35f2317a, 0xe7076fd2, 0xe776e0eb, 0x41ac9415, 0x4c38da3e, 0xe65cab7c,
+ 0x8c6d95fb, 0x16ddcbe6, 0x05f4f343, 0x0296736b, 0x78017e5d, 0x0bd23de0,
+ 0x3444674e, 0xe5c17f7c, 0x3df3c08c, 0x6ba81c8a, 0x36efa70b, 0xc58bce66,
+ 0x48cda373, 0xf9ded0f7, 0x9c46a98e, 0x38da7be7, 0x7dfd29ff, 0x1638b5d8,
+ 0xae8269f9, 0xf2876f5f, 0x5133cee4, 0x784df7a8, 0xf22c7e7d, 0xfe7870e1,
+ 0xcf1918fd, 0x1e12c486, 0x70bd8797, 0x004f6ca2, 0xba27ee7e, 0x87fa9de8,
+ 0x6fd1181a, 0x56ffabf7, 0xbe7c7c87, 0xfb8cc233, 0x230717e6, 0x0bcabde8,
+ 0x3de81a6f, 0x7df95a9a, 0x7d742fd5, 0x7cbf4873, 0x22f74b5d, 0x47fe6fdd,
+ 0xfba3f22b, 0x3b9d0355, 0xc373a87c, 0x6af7dc45, 0xc39c673b, 0x5f6b5677,
+ 0xc3f2dbfa, 0xd25486ca, 0x3ff8148b, 0xbe2746bc, 0xe45e7bf3, 0x8ea1e272,
+ 0xf77d217f, 0x0b976ba1, 0x17ca7cf0, 0x44c7ff07, 0xb7ee6b94, 0x79444f2e,
+ 0xe5c5fee6, 0x7eee5889, 0x4a13c22d, 0xc05eb95f, 0x7eca3efd, 0xa8aef699,
+ 0x90ad0ff2, 0x5d6d23e9, 0x3d07bd0b, 0x7b02e4e1, 0x130fbbe0, 0xac4e34b2,
+ 0x65b7e13f, 0x7c05f7b1, 0xa457aeb7, 0x93f8e338, 0x01d51165, 0x814f7974,
+ 0x7e2ff14e, 0x930ebf23, 0xf019c7df, 0x77f2f4e3, 0x8af6367f, 0x1aa37dfc,
+ 0x83a1ee81, 0x5ee432fe, 0x8affad1a, 0x88df7a58, 0xc73bce89, 0x8b38478c,
+ 0x3e6205de, 0x00ccd1e3, 0xaf71693d, 0x7400cba6, 0xe869d154, 0x57befd22,
+ 0xacb0433c, 0xf173dd3f, 0x2134c8d3, 0xe7267f84, 0xe39434d4, 0xf81a7ec1,
+ 0x8ade2245, 0x71e955be, 0xc1fe20a5, 0x15a59bfe, 0x287f9077, 0xd6937fd8,
+ 0x8f666a2b, 0xe9dff7c7, 0xf78c2f3a, 0x8bf22369, 0xfae287a2, 0xffc1081d,
+ 0x3970c66b, 0xbad5f0a6, 0x5dff1e5e, 0xcc6a5bd7, 0xe656b484, 0x9db003ab,
+ 0x75fda0fa, 0xa377f39d, 0xb5dd611f, 0x60631145, 0x3bbdd6be, 0xfc813d8f,
+ 0x66352e6f, 0xeed777e1, 0x1fcc2e30, 0xfee097a4, 0xf2e18ca6, 0x184f4072,
+ 0x97cbdf66, 0xed5bfaf1, 0xe463397f, 0x87ff6cf3, 0x87607fef, 0xedc31d8f,
+ 0x4fdc25f0, 0xe0f0edc2, 0xc791437d, 0x792ebb4a, 0x63ca879d, 0xc04877fe,
+ 0xec79265e, 0xbd51231a, 0xb1b9cee4, 0xbbbf4764, 0x0d325620, 0xb4433f6d,
+ 0x87f2626b, 0x71e8afb6, 0xa8e39f6e, 0x871ced11, 0x1749fb96, 0x99bef408,
+ 0x9db9f7a2, 0xeee3e902, 0xeb1f9d4a, 0x2ef57829, 0x85d57ee0, 0x4c3f9d0e,
+ 0x150fd418, 0xdca071fd, 0xa2b9502e, 0x637a2a4f, 0x71fb93af, 0xe5e78c17,
+ 0x16b986b7, 0xd87d7ce1, 0x13f94615, 0xc67cf126, 0x0093479c, 0x813df45e,
+ 0xfacbff11, 0xc1a742a4, 0xcea5e6fa, 0xd7be1b8c, 0x4fa64db3, 0x8352cf85,
+ 0xbfd943f8, 0xdd39f39a, 0x1dfee1d7, 0x7ff7fb8b, 0xe0f2f4aa, 0x7eff6176,
+ 0x466ff108, 0x1fbe121d, 0x19d15bff, 0x4aff3eca, 0x5efe0bd6, 0x23debf59,
+ 0x72af8825, 0x7db8764e, 0x6fd64eb5, 0xce6f2b86, 0xbcfc7aff, 0xdfdf1e47,
+ 0x8e779f8a, 0x9f43bff9, 0xf50bd01d, 0x4779c7a1, 0xc64fc941, 0x6b86bcc0,
+ 0x739e743d, 0x1ecdf7b8, 0xb055f595, 0x7c745573, 0x41af4534, 0xc35dc8bb,
+ 0xd1cd03fd, 0x7ec9afd2, 0xf7a5ae39, 0xef921e57, 0xd5783e73, 0xea2d694c,
+ 0xd92e90c9, 0xd9de927b, 0xc6a3525d, 0xb77d19bf, 0x34aafdf8, 0xb157eb8a,
+ 0x552bf232, 0xf19b4675, 0x7c737fbc, 0x2be431fb, 0xb4ad6edf, 0xc6feb03b,
+ 0x237d72d1, 0x44d5b7f7, 0x618fdfd3, 0x95407a41, 0x57df5827, 0x645305eb,
+ 0xfa70d13f, 0xc3ba2fc1, 0xd1e95cb8, 0x39d79f12, 0xd055dff9, 0xe0b97277,
+ 0xbf23086e, 0x886bda09, 0x820d67d7, 0x5f3ddf1f, 0x4cfbd729, 0x13ff25ec,
+ 0xcaa0d3c5, 0x2ca7ceb9, 0xd4dfb20e, 0xbb95a3f1, 0x33724b7e, 0x73148e38,
+ 0x0d0b8e40, 0xd2268dc4, 0x60959079, 0xbc9fe24f, 0x5dd24b72, 0x1f80ff38,
+ 0x71dc93f3, 0x9730fca8, 0xfb223e7a, 0x3cebc973, 0x7e2433fe, 0xc7933cd4,
+ 0x95ddf08f, 0xa5c87e10, 0xc51d8f23, 0xb374a3bf, 0xc75d51b8, 0x3247ba49,
+ 0xd208ff44, 0x518dae3b, 0x8a4719fb, 0xb23b8fdc, 0x7fa33053, 0x8f3ca46a,
+ 0x9c31b77f, 0x7fe9eaf4, 0x79458ea8, 0xf9d3aca0, 0xcf5e7cb9, 0x04a5707f,
+ 0x07f89bbf, 0xe3061cd1, 0xf507c5fa, 0xb0e249bf, 0xbbf09464, 0x63b408fa,
+ 0x7561ffce, 0x2febce04, 0x2fbfc520, 0x3169daf1, 0x2bd23fa4, 0x0fd82dcb,
+ 0xbfc80ba3, 0x45a5fb2c, 0x07230fd8, 0xdfc139fd, 0x6bbf976d, 0xfc853306,
+ 0xf8f3af98, 0x6b82737e, 0xa6cfc126, 0xa61efe33, 0xffcefc83, 0xfe8d7402,
+ 0x2c183ca2, 0x1a7f9fc6, 0xbc61d6ce, 0xf5de39a8, 0xb3d1f136, 0x08f9091a,
+ 0x9338a7be, 0xfb44bf6f, 0xc6194e23, 0xfcf40a73, 0x0cea465d, 0xbcb46bd6,
+ 0xc760098e, 0xb0093c62, 0xe6f18059, 0x53ae393c, 0x6c44ce10, 0x6b9d49ff,
+ 0xf997be13, 0x5f68b764, 0x8f604c4b, 0x83bf77c5, 0x83824be3, 0x3895c5c7,
+ 0x1f1f1293, 0x6024ce2e, 0xee9c053f, 0x8715b9f8, 0x25737180, 0xe7bec49e,
+ 0x635720a4, 0xf7ce87b1, 0x48c8533f, 0x718b7fae, 0x21f9259e, 0xc83548e2,
+ 0xd5cf2463, 0x394dc571, 0xfe9d10af, 0x3dc4f1b5, 0x1cb7d863, 0x13f3e2ff,
+ 0xe8f8f78c, 0xb7b2164b, 0x51effabe, 0x5e76cfb4, 0x42f0fda6, 0x8fbe41bf,
+ 0xecfdc7d0, 0x2ff23a9d, 0x2dbb005c, 0x3d9f603e, 0x3ddbcf9a, 0xe89539d4,
+ 0x596f40ff, 0x2f3fd604, 0x777c6fe7, 0x48d9fcc1, 0xbd22bd97, 0xe3e78b07,
+ 0xd03b0ed0, 0xbd404e2b, 0x975c5be5, 0xb1098fef, 0xd0f0c62e, 0xcbe44cef,
+ 0xc05f947c, 0x07ea63e9, 0xd772fedc, 0x598a38f3, 0x72ee0b96, 0x63c1c93d,
+ 0xf1411629, 0xc5435b9f, 0xa7ef5e59, 0x856aa37d, 0xbe1cf740, 0xa3a59c71,
+ 0x82b7de5b, 0xd3e5d3fc, 0xe70e6e49, 0x9b880eb7, 0x15b7caab, 0x23879c0c,
+ 0x815475ff, 0xe31dc699, 0xb3c12c29, 0xbff8ca87, 0x73b875c5, 0xfb3a086c,
+ 0x695fdb16, 0x9fdb6eff, 0xb6ddf792, 0x6e3be6bf, 0x77de6d7f, 0xf1dee71b,
+ 0xf57fe31d, 0xccff6e3b, 0xaf3f3c77, 0x73ffffe5, 0x70700300, 0x5cf83f9c,
+ 0xdfbc7040, 0x1f3efc70, 0x36106d96, 0x6a4177f7, 0x42b57a8c, 0x462d5100,
+ 0x0877a2ef, 0x71e24d66, 0x46658db0, 0xf0610eff, 0x5f32807c, 0x1db90b4b,
+ 0xe8bfce61, 0x4e79858b, 0xc596f475, 0x126c9fa2, 0x82fd877f, 0x132acefc,
+ 0x18cef4cd, 0xfbc04cd4, 0xa161cdf1, 0x7261aae3, 0x23edc37b, 0xdc9617cf,
+ 0xfe9e3631, 0xfbc8436c, 0xfec82f1d, 0x23077347, 0xa51324bf, 0xafd47984,
+ 0xd0fa8094, 0x3f3c2388, 0x76398baa, 0xda525e10, 0xa507b23c, 0x8b6fc434,
+ 0x998def1c, 0xfe869d99, 0x0bd018e8, 0x14f81e31, 0x8e2905c6, 0x4a7aa665,
+ 0xe58c1f7f, 0x31d16dfd, 0xe55bee81, 0xac4cf3f2, 0x9e2aa0f9, 0xebae8ef7,
+ 0xc50265e3, 0xfe2396f3, 0xe574d2bf, 0x89934cef, 0xff37e618, 0x8ce29980,
+ 0x48bd2627, 0x8956777f, 0xf331adef, 0x6ed1872a, 0x1cd63c06, 0xbbf4471c,
+ 0xf7a4d0e4, 0x7733e9f1, 0x750f68a6, 0x17f1514f, 0x1dfd969c, 0x8940bf8a,
+ 0xf65efd6b, 0xfe887c93, 0x221fba17, 0xab1dea51, 0x27f7b6f9, 0xfc10d8ef,
+ 0xfee045bf, 0xb8afdf21, 0xde9c687f, 0x6e78119e, 0xaf3cb372, 0xdc78bacb,
+ 0xecf7f142, 0xee33c793, 0x01976d11, 0x4d71d2f6, 0xcfb8f463, 0x094a6b8f,
+ 0xe1c0b4c7, 0xf07de0d7, 0x35fbd5c5, 0xa285faca, 0xb2b1d6a3, 0x9fa7a31f,
+ 0x12ff7ae2, 0x60ffe714, 0x30bf3f2c, 0xf1e390af, 0x0824d801, 0x1b12c9af,
+ 0x711c7d51, 0x2a1b598b, 0x7605549e, 0xacb9e231, 0xccade399, 0x34975577,
+ 0x7339fb15, 0xd309bfb4, 0xa9b49aa2, 0xbdaf6fe4, 0x9bfa84d8, 0x63e5dafb,
+ 0x4cbf93b7, 0x713da12f, 0xefda9f4f, 0xa5a30ab6, 0xfd2784f1, 0x0cdf5a9d,
+ 0x71e3ec91, 0x9fa24433, 0xb230aa98, 0x4c74635f, 0x2e78426b, 0xca8a8bd7,
+ 0xcc22a6e3, 0x3e934416, 0x4523d458, 0xe83f97df, 0x51998b07, 0x74f38f1f,
+ 0xe2aaf8b3, 0xcc35bb4f, 0xe7ae1af1, 0x5d5f1b5f, 0x74bbcef9, 0x971954ae,
+ 0x9c4a2f32, 0xaaf8b874, 0x5dc1ce72, 0x2e75457e, 0x4ff62dc3, 0xb8e3ff47,
+ 0xf2f46783, 0xfe334b39, 0xfe25611d, 0x8bf5ee3a, 0xe2557714, 0x45cf6eac,
+ 0x3be1abd2, 0x0e3f7e3d, 0x06213f96, 0xf1e217df, 0x9ef157d7, 0xffef1e94,
+ 0xd4bee999, 0xc5fdf21b, 0xe63f184e, 0xa1cde9bf, 0xa76bcbb4, 0x98b790f4,
+ 0x45e77752, 0x387ed78a, 0x53ef1d56, 0xb49779e2, 0xd56333ce, 0x0e0923e7,
+ 0xc369f78e, 0xddc6bfb9, 0x97bfa3a3, 0x48c77ee1, 0x73a4bbf2, 0xfaebdd19,
+ 0x246ba4f2, 0xf1875de2, 0x38ba00b6, 0xe187b0ef, 0x9de7613b, 0xb38c30f6,
+ 0xa73eeb8d, 0x752ff3c7, 0xfd1eaf62, 0x12718061, 0x1f744d1e, 0xf7cfc8b8,
+ 0xdfd09676, 0x5c69bae3, 0x136fe3ac, 0xe59ffb17, 0x00210141, 0x00002101,
+ 0x00088b1f, 0x00000000, 0x17b5ff00, 0x67534c5d, 0xb7b77cf4, 0x0bdf96e5,
+ 0x72223f2a, 0xa29862c1, 0xa740c2dc, 0xac741631, 0x4a8a5c13, 0x66b50102,
+ 0x2d09922e, 0xcbc2ccd9, 0x01893ad2, 0xb8b2c3dd, 0x26a9f364, 0x87b6e883,
+ 0x6ead93fa, 0x840b0b55, 0xc3e22e25, 0x52c9719c, 0xba33330d, 0xd8dc6281,
+ 0xdf39d85c, 0xd8bdb5bd, 0xa4da2cbd, 0xdf3f3d39, 0xfff9df39, 0x0730000a,
+ 0xb956e7da, 0xf84ce706, 0xffc6cfa5, 0x4fa43d0f, 0xbddde38c, 0x1726eb4b,
+ 0x3ebbf1c4, 0x036935c9, 0xce9c5df8, 0xf6002b94, 0x1c5ace87, 0xaccf1f04,
+ 0xedfc2176, 0x4ab5dfc2, 0xd2f7803a, 0xee202d4c, 0x96a666fd, 0xd2afdef8,
+ 0x4fe9027a, 0x8ed77bdb, 0x70045e97, 0x106b4196, 0xc12e55f9, 0xb8e08271,
+ 0x4546fac3, 0x25c06e5c, 0x80fce938, 0xe89b34ad, 0xd9a55cc7, 0xf5f4137b,
+ 0x00674539, 0xdaaf39e9, 0x09f489ac, 0x06a019bb, 0xc15c0ce9, 0x556bf624,
+ 0x7fdfdb81, 0x4a4f2ad2, 0xdbf11c7a, 0xe036cc1d, 0x3c8150de, 0xf7c71e59,
+ 0xfc028fd3, 0xd422666e, 0xb9e97402, 0xd77264b8, 0x3bafa8aa, 0x52816a3f,
+ 0x5c5b4ca2, 0xdf5e30ab, 0x12acfd4b, 0xbefcf860, 0x170568e2, 0xa0172095,
+ 0xe0373f4d, 0xb19c5bdc, 0x3d7fc010, 0x4698ca05, 0x4adf9113, 0x2a8e143f,
+ 0xa769da22, 0xb6e5785f, 0x4c27f7fc, 0xcdba11ab, 0xbdc268fe, 0xc3829dda,
+ 0x2eedc99a, 0x7920ce6d, 0x212fce31, 0xb74bd3a5, 0x51cc22ad, 0xf413e428,
+ 0x025ac217, 0x36ada8d2, 0x0406ef6e, 0x7ca1b07e, 0xa488539b, 0x70d69da0,
+ 0x6f50044a, 0xdf045395, 0xcd7b088b, 0x7c461281, 0x2be726f1, 0xbf11366f,
+ 0x042aae4f, 0xcbe7e3f4, 0x09417916, 0x3464dfbf, 0xf3aa8e21, 0x3c52fed3,
+ 0x953176af, 0x34ef6adc, 0x4193f1f2, 0xe3d6ee7e, 0xfc3433b2, 0x5ff72172,
+ 0xcb9e0136, 0x8e38031d, 0x18f67776, 0x756eedcf, 0x3f7461de, 0x337fa0f8,
+ 0x904d81ca, 0x6bde8907, 0x3b3aa394, 0x001ff18d, 0x43d62670, 0x0d41d537,
+ 0xe7e1c641, 0x45d513e8, 0x582a0615, 0xbf373f11, 0xf974467e, 0xf062faf9,
+ 0x5117f10c, 0xd80d567d, 0x024dbf28, 0xf5e10194, 0x9f412d92, 0x9eb9155f,
+ 0xfc01650f, 0xde17d728, 0x7e30c83e, 0x915f8f7d, 0x4a6e505a, 0xd2ca97ae,
+ 0x32f7b8e3, 0x401653d6, 0x036cf0f5, 0x9858fbc5, 0x794d1581, 0x28bef1f3,
+ 0x6eb17d57, 0xbc4ead9c, 0x31dfe6a7, 0x3a44f9cc, 0x0d9a81d5, 0x61205f9a,
+ 0x5817fcbc, 0x55ed1060, 0x491c3d35, 0xb2b9f8a3, 0xec8532d5, 0x23a50ed8,
+ 0x6b126dee, 0x3c2ee118, 0x160ef840, 0xf6e7f090, 0x005b9d2b, 0xd8b754ed,
+ 0x5bdc52af, 0x15aacc3a, 0x40dade88, 0x50596bf4, 0xff122937, 0xc4a97bc4,
+ 0x55aa672f, 0x9eb3be21, 0x445f8df8, 0xade7aa44, 0x7865a514, 0x8d28cbb7,
+ 0xeac1b37d, 0x551f500e, 0xf411a337, 0x3587476f, 0x84b5fe40, 0xce90cd9b,
+ 0xbea041eb, 0xedcf5b7b, 0x328f45b7, 0x099f48a3, 0x5f916757, 0x16d3cc0b,
+ 0xea356115, 0x7841c82e, 0xb005bee1, 0xb4e2bc1f, 0x73b94645, 0x05ac4c3e,
+ 0xc49f4be0, 0x8327c861, 0xd7c03963, 0xc30e7cbe, 0x2fd3853e, 0x8c39cafa,
+ 0x470e54f8, 0xa8356b7c, 0x959e3cca, 0xdd02fbe1, 0x7059a727, 0x7e6f9b25,
+ 0xf9623ebd, 0x29ef0baa, 0xba3e7ba6, 0x93962eea, 0x5a20c7c8, 0x6ad6142c,
+ 0x6730c9fd, 0x06c3e75e, 0xe881e3b2, 0x60a73a61, 0x460d61be, 0xef308421,
+ 0xaa6febbf, 0xd96f9b52, 0xf193b802, 0x04faf467, 0x3cd02287, 0xfad24b7a,
+ 0x5fc5787f, 0x48529e3c, 0xf31eb2b9, 0x413719e6, 0xd48fd20a, 0xbe7f736b,
+ 0x4f18eb9e, 0xc0ddb8c0, 0xcf9c1278, 0xcbf8b56f, 0x74ad1f28, 0xa7e7248f,
+ 0x0ac4faf4, 0xb432bb30, 0x4fbc329c, 0x600e6c47, 0x8f30b220, 0x4916211d,
+ 0x19df3ec5, 0x244774de, 0x96e0c3d8, 0xd73c7e71, 0x46e6d87d, 0xb6f389a5,
+ 0xf9268d33, 0xd54a5c13, 0x34592ce2, 0xf6d56fd8, 0x8b5d935a, 0xb56e0c73,
+ 0x9471756b, 0xfbeb059a, 0x381679e8, 0xa9e7fd88, 0x734ebb18, 0xd001cf2c,
+ 0x93c7c38b, 0xd1311e9f, 0xef990f3c, 0xd8e3993d, 0x0c8a791f, 0x3794391d,
+ 0x41f6260c, 0x24077e81, 0x63946dc0, 0x6e611c91, 0x192dca25, 0x9f7d259f,
+ 0x2f6e15d8, 0x01905777, 0xfe0450ba, 0x465f3483, 0x1a77502d, 0x639d77ed,
+ 0x3bfa9070, 0xf70502e0, 0x1bf1e8fd, 0xdd214f87, 0xb4c98e73, 0x5783ba8e,
+ 0x16ef9ef9, 0x78ff7827, 0xbc2d77c2, 0x3537831e, 0x0239887a, 0x403af249,
+ 0x6eed1dfb, 0x6e687f46, 0x05301f74, 0xc36ed052, 0xbdafad39, 0x41404b0e,
+ 0x1de8ac7c, 0xe79df091, 0x1cd1e419, 0xa5162653, 0x1980ff11, 0xafdc2502,
+ 0xfd84baa6, 0xfc855f84, 0xd8cfed8e, 0xf4c0f1fe, 0x6bd52158, 0x0a235327,
+ 0x8cb73fdf, 0x922f05fb, 0xed2fdf1b, 0xcd3361a1, 0x0643dc1b, 0x868eddb9,
+ 0x713f343b, 0x4be918cf, 0xf9e7df0e, 0x53af2880, 0x7e062fdc, 0xe1633d8d,
+ 0x58092c6d, 0x38731509, 0xca5536cf, 0x6eaddf3c, 0x1f18dcc6, 0x91757049,
+ 0xc991709f, 0xc7e76f34, 0xf5aed1ab, 0x419fa341, 0xc877e62f, 0xd0c7d5a2,
+ 0xa3f0163a, 0x94a2237c, 0x7b8ba1f7, 0x1cfd0cfc, 0x40aa62aa, 0x8c2120f1,
+ 0x3e3d16c7, 0x6e1f802f, 0x70a9fc4b, 0xe01aae6c, 0x2b61ac35, 0x5ea353d6,
+ 0x6e01000f, 0xd4e3f9a7, 0x8e23bd08, 0x2af9839a, 0xf9f8977f, 0xe055677d,
+ 0xe814d4fc, 0x6bafd649, 0x6ab375ec, 0xf33dc90d, 0x7b2ed3f7, 0x47d3f792,
+ 0x3b2276f8, 0x244ced7b, 0x2bbe30bf, 0x15efbfa9, 0x411ccb5d, 0xb5c981f4,
+ 0x5975ce8f, 0xbea9ab22, 0x1cdc981f, 0xee91f18f, 0x8b82fda1, 0x91f516ef,
+ 0x87cf8c00, 0xcc67e523, 0xa2769794, 0x125beec7, 0xe9b8e397, 0x0aa1fc69,
+ 0xa1efdacf, 0xfda79aca, 0x17fa867e, 0x7f57cfab, 0x1dbcb26e, 0xa497f9a2,
+ 0xe7d27e7e, 0x9912c01f, 0x3893cbf7, 0x6487b683, 0xaa3c75e0, 0xa67ef5ef,
+ 0xc87b48fc, 0x06199dff, 0xed5cf895, 0x7ff4d0cf, 0xc18beba6, 0x9bf61d51,
+ 0xf6f9b935, 0xfc39f427, 0x8a71c98b, 0xa4f2bdee, 0xdf824a00, 0xa0a982ab,
+ 0x195df824, 0xf6e031ca, 0x7c8362c8, 0x81a978f5, 0xc2b1335f, 0xbd735fc0,
+ 0x14bf80ca, 0x5f90675d, 0x01bd6bff, 0xc5bd30df, 0xcff1bf20, 0xd63c066d,
+ 0xb95875bf, 0x4936e789, 0x0ae41baf, 0x157e8d3b, 0x2afd18f5, 0x15fa35ee,
+ 0x37e25bd3, 0xdfacb7fa, 0xf64e5fe8, 0xde855c83, 0x91fcffa1, 0x2060fb49,
+ 0x34f3c33c, 0x13029d35, 0xa8c44734, 0x66c21fb6, 0xf0a617be, 0x84a2e2ff,
+ 0xd7a72c3c, 0x0919da3f, 0xb9d2b32f, 0x2b369d0f, 0x512edbbd, 0xfe3e600d,
+ 0x2e76d705, 0x000ee017, 0x00000000
};
static const u32 csem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0xe733ff00, 0x51f86062, 0x39fbc10f, 0x716e1819,
- 0x0143f822, 0xd9433117, 0x1017fa40, 0x606463bf, 0xbc48cf78, 0x040e357e,
- 0x033b2f7b, 0x3e200ac3, 0xfef03ec0, 0xc95c481a, 0x4ebb3f4d, 0x622ed1d0,
- 0x067e2ef0, 0x0c023d86, 0x1082590c, 0x54417ffe, 0x08fcddf9, 0x651898b6,
- 0xf5012976, 0x93320003, 0x038009d3, 0x00000380
+ 0x00088b1f, 0x00000000, 0xe3e3ff00, 0x51f86066, 0xb8d3c10f, 0x72361818,
+ 0x0143f821, 0x684333b7, 0x0606163e, 0xc77e2001, 0x9ef0c0c8, 0x38330491,
+ 0x207eec10, 0x27880abb, 0x7dcf5071, 0xe52f1143, 0x5f5d9fa1, 0x153d76a0,
+ 0x837f7818, 0x031083b0, 0x03309b83, 0x8408b483, 0x55045fbf, 0xc10851de,
+ 0x99412e7e, 0xfa819f5d, 0xbbeb8d01, 0x00038031, 0x00000000
};
static const u32 csem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7dd5ff00, 0xc5547c0b, 0xbddcf8d5, 0xeecddd8f,
- 0x21079b26, 0x086e3c21, 0x4bc60a22, 0x9bade102, 0x88b46204, 0x7d608a89,
- 0x8420182d, 0x96d22247, 0xedf7ed7e, 0x5ab11062, 0x68db151b, 0x34105db1,
- 0x060b28da, 0x2df0980c, 0xaa5694a0, 0xd1f58df1, 0x90cbc8a0, 0xf87e8784,
- 0xce7feb69, 0x7bbbb999, 0x7c486eef, 0xfefdfbf4, 0x730ecfe9, 0x3399dee7,
- 0x9ce735e7, 0xc92b3339, 0x210cb102, 0xbbf81be4, 0x22ad909c, 0xa46c6421,
- 0xe5a22aec, 0x79fc4218, 0x8126c08e, 0xafaed090, 0x4234908e, 0x54cd364e,
- 0xec84d9ad, 0x2e8473ce, 0x0327eda7, 0x6d2b0185, 0x76f6de2f, 0x4beb44a2,
- 0xb41289b6, 0xf1d9765b, 0x4275cefb, 0xd6d5ea00, 0xd12607b6, 0x9136f77a,
- 0x935da06c, 0xd242d390, 0x23623909, 0x61754fec, 0x559dbe7d, 0x7ddfac97,
- 0xd9578c2b, 0xfa76256c, 0xd12691fd, 0x9b65f503, 0xe3a10084, 0x8f71d92d,
- 0xb7f68032, 0xed042020, 0x7a6fad2a, 0x845d5150, 0xfdebb5dc, 0x212776c4,
- 0xa2367c27, 0xca8f382a, 0xaa4228e0, 0x064a5b02, 0x1aabefd0, 0xfb42cd05,
- 0xaa775aaf, 0x6aabe013, 0x69102f92, 0x1c1a8b7f, 0xc6c11d44, 0x78c086fe,
- 0xbc703b7b, 0x1830f26d, 0x3bebf2af, 0x3cc22215, 0xb77c0f65, 0xf301c284,
- 0xe13dc7d6, 0x74f1c7ab, 0x9a792e7c, 0x5bdf478e, 0xc1a09cfa, 0x885a9714,
- 0xdce8e017, 0x84fd9f61, 0x52b7e613, 0x9e8aee19, 0x30ed9cc7, 0x7ac0aa8f,
- 0xf009c4a5, 0x8fe657ad, 0xa8b7f48a, 0xf846f7e1, 0x7bfa73ea, 0xe5cddaa3,
- 0xe9451f09, 0x8abd48f0, 0xf6904f10, 0x5280a44b, 0xf9e4497e, 0xd2324207,
- 0x4883517b, 0x7fa45b54, 0xfa42794a, 0x9b7fffd1, 0xc1e293fe, 0x6c0aeadf,
- 0x6dd08eca, 0x16681b99, 0x3769dba1, 0x5dd4a3a7, 0x5ebfdd10, 0xa0f4003e,
- 0xdcf9d4f0, 0xcbe43e58, 0x4fad72c0, 0xd6fdbc45, 0x7acb0237, 0x1fcf869f,
- 0x72c78df3, 0xe583cf9d, 0x58a57c1f, 0xf8657c06, 0x6cdf06de, 0xbcfa372c,
- 0x5f49fcf8, 0xbe0d9625, 0x8cfe7c1a, 0x8d96056f, 0x7f3e3f3e, 0xcb06b7ce,
- 0xcb0eafa0, 0x5a2f40ad, 0xf802f936, 0x035f76de, 0x20becd96, 0x6be9df3e,
- 0x8e7ef2c6, 0xa4c9c4c7, 0x4878a250, 0x253710f4, 0xee99493b, 0x3d699429,
- 0xd3d58ca5, 0x2a17f66f, 0xa5ee9eb4, 0x01978a75, 0x5685438b, 0xc3501f5a,
- 0x92ff07da, 0x7d68d914, 0x0fb59fb0, 0x6453dfbd, 0x75a1f5a7, 0x3af87dac,
- 0xad02517f, 0xf6b00f0f, 0x45431b8b, 0x38bf5a0e, 0x5b73dac8, 0xd693b148,
- 0x9eac4373, 0xec53c077, 0x36bcf5a2, 0xc0f82f56, 0xeb489c5f, 0xfbeced05,
- 0x51011d89, 0x61d2c675, 0x4edeacab, 0xf9d6ad28, 0x1348f4af, 0xef515d68,
- 0x8fc51a24, 0x948f5aff, 0x7b21f149, 0xbfe43db0, 0x149bdb09, 0xe1bfb60f,
- 0x76fac0af, 0x87ed8bd9, 0x5d584bfd, 0x17fb62f1, 0xbd629ffe, 0xbb63f659,
- 0xd58fa56d, 0x0fb63f15, 0xfb06b958, 0xb00729df, 0x07cad47d, 0x12a77db1,
- 0x5687f6c0, 0x4a99e63d, 0xf782b5eb, 0xb48fc0b7, 0xc03924ac, 0x328cc14f,
- 0x05ab4fca, 0xf7f81b32, 0x28e980bf, 0x54ceae5f, 0xfeb70e50, 0x9009e0ad,
- 0x834bfc5f, 0x7f27fcfa, 0xffdf8d95, 0x6991fb11, 0xfdef623f, 0xde3abde4,
- 0xabde4fd0, 0x0d3f7a95, 0xbdad5ef0, 0x7d6cfd6f, 0x9e11a275, 0x7ef4ab57,
- 0xae3c20b6, 0xef2bcdbe, 0x7846c9b5, 0xf7ac5b5e, 0x49e113b3, 0x4d3c1bee,
- 0xd3f11b6f, 0x3f1876f4, 0x7e9e117b, 0xcc67837d, 0x8cfc463b, 0x9f8c2779,
- 0x664fd803, 0x7a69fadf, 0xa69f88c7, 0x79f8c277, 0xa835e71b, 0xf31af36f,
- 0x633f11ae, 0xe7e30dde, 0xbb278423, 0xff6cfd6f, 0xed9f88d0, 0x73f1861f,
- 0xa0b9fb14, 0xf82af36f, 0x829f88c8, 0xe9f8c28f, 0xea2e7ec6, 0x3fdb3f5b,
- 0xfb67e232, 0x7cfc6147, 0xd25cfd89, 0xfc1579b7, 0x829f88c3, 0x63f1847f,
- 0xd19fa011, 0xf9a7837d, 0x9a7e2353, 0xc7e30d3f, 0xed8cfd81, 0x8fe33c1b,
- 0xfe33f118, 0x693f1848, 0x427dd002, 0x3e69fadf, 0xf34fc462, 0x067e3091,
- 0xfa533f61, 0x47f1af36, 0x7f19f88d, 0xe19f8c34, 0x2a42af38, 0xa10f00f7,
- 0xee7ab8fd, 0x2349e767, 0x0c9e767e, 0xec52e7e3, 0x27ed1a67, 0x267ef7a7,
- 0x33f11a76, 0x9f8c33b1, 0x95cfd8f1, 0x6767eb7d, 0x3b3f11a7, 0x29f8c33b,
- 0xdd5cfc44, 0xec4d79b7, 0x6267e232, 0xfe4fc317, 0x89c5355b, 0x85ae9db4,
- 0x993f489a, 0x08f1e1d4, 0x59ba2eb4, 0x046b745d, 0xb75112ec, 0x479b4837,
- 0x1b3bdfa4, 0x457ef393, 0xa28eeda2, 0x8b979872, 0x76d1635a, 0x04f8d247,
- 0xec939d83, 0x53d43149, 0xde18074b, 0xd43657ef, 0xf67fded0, 0x4cf686c5,
- 0x9ea19e6f, 0xf0d13955, 0x229aa0fe, 0x8ac87d43, 0x67ef0cab, 0xd435affb,
- 0xd8fcd673, 0x7505fef0, 0x17ed0d73, 0xda1957d6, 0x332c0a2f, 0xfc3647d4,
- 0x4bfde187, 0xda197782, 0x95fe6d2f, 0xe8747da1, 0x7f3d4321, 0xf78663ff,
- 0x306db6c7, 0xf83b8fb4, 0x427da18c, 0x7d4356fb, 0x269db1d2, 0x3ee9cf3b,
- 0x45d79232, 0xecc27be0, 0xed054cfe, 0xc14b90bd, 0x89c032ba, 0xd76efc76,
- 0xa530f57c, 0x76e7b2af, 0x17d28d35, 0xbae84a68, 0xf2a0385e, 0xfcfa76c2,
- 0x17bd13a7, 0x9ff3e9ba, 0xdd4bde2a, 0xca53ec71, 0x80c9020f, 0x6940b552,
- 0x6647bf6e, 0xf59458fc, 0xf443f0f5, 0xf74b6afb, 0xb75a64f0, 0xc0f58588,
- 0x2c107fbf, 0x2209a7c8, 0x12f781a9, 0x82fd04ac, 0x9e0bb27b, 0xebf147f0,
- 0x0e54419a, 0x6bbf4885, 0xd8066f64, 0xbe561b19, 0x643b07ee, 0xaf3a20f5,
- 0x213c8401, 0x0ff21ebc, 0x9a0fdfa3, 0xfda5e19f, 0xa76a1559, 0xd0af8f47,
- 0xf8e147f1, 0x73fe300d, 0x1d6f8c3d, 0xbe30de3a, 0x61a5706d, 0xc7429b7c,
- 0x607b5377, 0x7c7c7be5, 0x8489844a, 0x87bc2f3c, 0x57075be3, 0x28f7f8e2,
- 0x1e895fd4, 0x7e3c213f, 0x2ecbc833, 0x9c6c7f18, 0x689d0ff9, 0x2ae0ff9c,
- 0x3615fce3, 0x0f2b3dff, 0x7013f1f1, 0x43857bfe, 0xab83fe6c, 0xacadfcd8,
- 0x89f8f0df, 0x87effc61, 0xd3dabff9, 0x1b2673fc, 0xb1643fe7, 0x3656fe71,
- 0x8f2b1bfe, 0x389df1f3, 0x71c29bfe, 0x8b21ff36, 0xeac57c71, 0x947f80d5,
- 0x009a84ac, 0xa40c9f1d, 0xb03fa98a, 0xca071d0b, 0xa9942911, 0x30b5f909,
- 0x69f8e114, 0x2fb7e302, 0xa1bf2812, 0x73e3f1be, 0xad9aa012, 0x9c5dfa80,
- 0x163517d7, 0xb097a02a, 0xf32bfa9d, 0xcd15a838, 0x5937f222, 0x405c0d6b,
- 0x166cede1, 0x58af50fd, 0xfa00253b, 0x6e4adaaf, 0x24ef832b, 0x9fe78212,
- 0x86c9723e, 0xcb9979e8, 0x91f27579, 0x0b7928f6, 0x644551fb, 0x6f850d44,
- 0xd8c1301a, 0xea63fd48, 0x5fea1107, 0x0cfd407c, 0x13f25942, 0x11f78d99,
- 0xdea097f5, 0x6825fd4e, 0x7e256427, 0x2b7bbb47, 0xc65fc283, 0x6258ffe1,
- 0xcdf1faf2, 0xe54fc042, 0x8f9f8bf3, 0xb6f53f46, 0xf48a0e15, 0xfc731c08,
- 0x9d3a86a9, 0xd4e81f97, 0xd81ac3bd, 0x557e2020, 0x8a3957c0, 0xafb72126,
- 0x8eb8a2c9, 0x252effbc, 0xfd45267b, 0xf723c40d, 0xb2dfefa7, 0xa6e4185c,
- 0x58f4cee3, 0xe13ad8f3, 0x5ca0b2c9, 0x78cb2c93, 0x1a6dae42, 0x481ed32d,
- 0xb8fe47b9, 0xebdc6a3d, 0x99f58d4a, 0xa77ac665, 0x142d91ec, 0x8172ceae,
- 0xcefda7ac, 0xd76c6d9a, 0x525a71c7, 0x78f99d18, 0xbe0ce965, 0xc1e65059,
- 0x79d23763, 0xab7d9bb6, 0xbb7d53c3, 0xa0585d4c, 0x011fbfa7, 0xf0d3faba,
- 0xd9bb1fbd, 0xcef0cdbc, 0x329e6d96, 0x73d9cf3a, 0xb7f000c4, 0xefbffe19,
- 0xb92c7872, 0xb0f35cb4, 0xf3b12c4c, 0xa37fc331, 0xa09f3cd7, 0x4df0eb0c,
- 0x8ce7e695, 0xfa708e6f, 0x41fc0c7f, 0x1fc0a3cb, 0x9cc3fe14, 0x957a223f,
- 0xd5b547f1, 0xa1f8033b, 0x209151fb, 0xdcbf395d, 0x5e65f9c0, 0x082f919d,
- 0xc740caf1, 0xbc85b305, 0xc1f1455f, 0x0b07ce2c, 0x737c8dea, 0x99cbf10b,
- 0xe372e871, 0x6777f5da, 0xfbf3b1a8, 0x4dcdf390, 0xfc46eff7, 0xd193cec4,
- 0xa74e56e9, 0xed8c6a5b, 0xdeba7037, 0xbb3ae9c2, 0xa997c1fe, 0x563f20fa,
- 0x7bc83203, 0x7a742ff5, 0xe9e81bb6, 0xc334f4e5, 0xe7a72b79, 0xf4673fad,
- 0xcedbc334, 0x7f5ed9e9, 0x63432646, 0x77c335e1, 0xf9988adb, 0x39cf4028,
- 0xacf4f8fe, 0x3d4c2e6e, 0x497cf51c, 0xc3d4caf0, 0xa8b67251, 0x5f50dca1,
- 0xf0d1b818, 0x39fa82fe, 0x7579f686, 0xb7ed0d0b, 0x50c3b9af, 0xb9ffe39f,
- 0x56dbfde1, 0xdfb434ac, 0xa1af7352, 0x07caa6fd, 0xbd1bf50d, 0x9fde1a8f,
- 0xa1bd7b35, 0xd3d9667d, 0x4aebf686, 0xe5ea18b7, 0xf7861d9e, 0x870b5d85,
- 0xeabae3b4, 0x887f63fd, 0x4567be27, 0x3beb353e, 0xf61e2f5d, 0x88fcf8a9,
- 0xc796046f, 0x3f3e1a7c, 0xe58f1be1, 0x74dfd04a, 0x60ecb05d, 0x7343f565,
- 0xe2a3b886, 0xdac89f1e, 0xbdb3d060, 0x7dfd43e9, 0x7fa3deb3, 0x14ecf159,
- 0x902c5cbd, 0xbb075832, 0x3fad1db8, 0x49d7c53f, 0xb942ee42, 0xb930ac5c,
- 0xb335bc5d, 0x3d422488, 0x4e26bc34, 0xcf2c267c, 0x33e70141, 0x00c72eaf,
- 0x91fa82e7, 0xe036f826, 0xf9030b38, 0x1a8be786, 0xebbe1926, 0x7c222dd8,
- 0x27c6414b, 0xb65672c0, 0x85f002c7, 0xeebe0ef6, 0xb3d78012, 0x4beb02d7,
- 0xe7b43f73, 0xa9a57c3a, 0x73c02587, 0x7cc79619, 0xe23cb1b3, 0xd87962f3,
- 0xc7e58957, 0xdb2c1abe, 0xfcb02b7d, 0xf2c7e7c8, 0x2c1adf03, 0xc3abeeff,
- 0x1eafa0f2, 0x017c77cb, 0x35f2df2c, 0x2f86f960, 0xaf9b6588, 0x9f4ecb19,
- 0x5e5d4b07, 0x4865f8a2, 0xe8bf1466, 0x8fd74ffa, 0x9cbf38c7, 0xc7897e00,
- 0x7c8c1b17, 0x41ae5471, 0x43eb30be, 0xfacc1d33, 0xc3f2bbef, 0xdbb30b58,
- 0x443f2fbe, 0xa2659de8, 0xf46f4e77, 0xbd146226, 0x0cdc5ac7, 0xfbef4e1e,
- 0xf638de00, 0xb8b025fa, 0x83b28bf7, 0xff160e3c, 0x6a7a71e5, 0x2ff8b201,
- 0xbe96bb1f, 0x52f686db, 0xe3e80460, 0x77fe23d3, 0x4fb7c438, 0x6752b41f,
- 0x99f9e7aa, 0x1e23d7e9, 0x86fd0788, 0x28ba01f9, 0xdbb6c7e4, 0xed5e1813,
- 0xe84a5216, 0x05ef717a, 0x47736a4f, 0x29225d61, 0x2b407df0, 0x97e9c577,
- 0xdf80a0da, 0xeb5af0de, 0xfa1722fa, 0x57d8f23b, 0xb58e5005, 0x61343b30,
- 0x30f688af, 0x01a13d09, 0xdefac37e, 0xdc4065aa, 0xc502fbb8, 0xc071eb8d,
- 0x9f9fc469, 0xf8220bd6, 0xa8e297bb, 0xbab3d70d, 0xb0dfc40c, 0xf667862f,
- 0xe9bd7f01, 0x39f0dec9, 0xdfe03037, 0xf4decf82, 0x8b7a6f57, 0x9ae7d478,
- 0x76bbfce9, 0x2bf7925d, 0x50d4f415, 0x80f4ffe6, 0xc7bf7d6f, 0xf0254f0c,
- 0xf3bed8f1, 0xceba5771, 0x09836dc7, 0x906de71d, 0xe9ffda17, 0x80930ba6,
- 0xb41fb42e, 0x71b7bbbb, 0xba17b9fb, 0xf636cc9e, 0x2fe5cd57, 0x42925fdc,
- 0xb8e94b84, 0x4921452e, 0xbd161d74, 0x1bf4442b, 0xf83f76b4, 0x5a1cbbe3,
- 0xd8fe0aad, 0x2a435789, 0xdbf468f4, 0x227fef4f, 0x659bfc11, 0xe1f71619,
- 0xcbd47438, 0xb76cc125, 0x680fda33, 0xd74fd636, 0xf441a509, 0xeba4d493,
- 0xc075812f, 0x0c3c3eed, 0x960672f4, 0x32cb3f7a, 0x54e1f714, 0x23d33fa4,
- 0x67a8c98d, 0xf86cf84e, 0x470d0fde, 0xe044fd4f, 0xd09f2268, 0xdf1481ef,
- 0x7efcf4e4, 0x9d20728f, 0x485e2055, 0xc02fe45a, 0xffd3b37f, 0xfd0a19be,
- 0xfbd7584a, 0x7e8a0ead, 0xbcf0a5eb, 0xfd1e30d1, 0x32f7d54e, 0xe59ebbe1,
- 0x7447224d, 0xdb74a77e, 0x175bf7c2, 0x46ddd835, 0x50d930bb, 0x74ce6eaf,
- 0xf844ec1b, 0x95c21807, 0xb77c0482, 0x975db398, 0x7c035ce4, 0xe3043f74,
- 0xf605df80, 0xbb5b12de, 0x4c5155e2, 0xe72f80da, 0x5ef9d78e, 0xd53ef59d,
- 0x915fc74f, 0xf917c809, 0x1055429a, 0xa0ae8fe9, 0xb7eb42c4, 0xa6dcdaf3,
- 0xbd61d345, 0xf6616e3a, 0x4b290578, 0x92b37f04, 0x7c4015d4, 0x94b124f2,
- 0x249e5c82, 0x47e6246f, 0xa2fbe1c9, 0xbedcf082, 0x531768c6, 0x5f50d97f,
- 0xcfac6f50, 0xc3a6d727, 0xb5fcf2be, 0xa0080932, 0xafed8c2f, 0x168e4c88,
- 0xb0d59a90, 0xd995afbe, 0x4dd7363a, 0xdf0a2ca4, 0x2f1e1792, 0x1feb4398,
- 0xd31ecc8b, 0xa61745f7, 0x82abf830, 0x6d0f15eb, 0xff29a4ff, 0xe879aa06,
- 0xb0d581f7, 0x09b7f95e, 0x963526da, 0x7e16df7e, 0xfafabc33, 0xcb3fb31f,
- 0x20d258e1, 0xec710278, 0x0ebe6e80, 0x4d2e7aeb, 0x08e21b72, 0xe2a3d42a,
- 0x9f99df0c, 0x9f8188d2, 0x36bd17ee, 0x1fe31fa9, 0xa904a7f0, 0x9f7ef15b,
- 0xfa6233fe, 0xfec6934f, 0xa40ffd80, 0xfa1817fd, 0xf8507f57, 0x3fc0c587,
- 0x4bff5e2a, 0xbb76785e, 0xaa93ea9f, 0x12248fcd, 0x971e3eba, 0x4a35d2ea,
- 0xee9bc5df, 0x1f3a044e, 0xc089fc93, 0x6203c7af, 0x7ace2069, 0xe9d25735,
- 0x100a71ed, 0xd27f82c7, 0x733c4ffe, 0x5ff7fa1f, 0x18dd926c, 0x86b06a9f,
- 0x971e54ac, 0x4e9c2d36, 0x887eb172, 0x2539efd5, 0xc8d9bd42, 0x3d4f557f,
- 0x0af90e92, 0xbc785394, 0xecf68426, 0x969f8dd2, 0xba44bae0, 0xdfcc8e51,
- 0x52e7f8c1, 0x51cdff50, 0x29db6292, 0x5777e89c, 0x3754bc73, 0x4c4a77dd,
- 0xa3b57f84, 0xbf7e6c3f, 0xd7a5db92, 0x23b4ae49, 0xe32704d4, 0x87d038c8,
- 0x80483e3a, 0x0be2a5d9, 0x1c42e78f, 0x2be363b2, 0x9e144289, 0x1d3a3974,
- 0x3b8ffdbc, 0x6df59ed5, 0x68b39527, 0xaf5f47fb, 0x4f6e66d4, 0xb172b0b7,
- 0x449c4a1c, 0xf5e2e0f5, 0x8fa7e6b2, 0xc4fb3f17, 0x5c418f93, 0x76ab3df0,
- 0xd17fed01, 0x33bf2fb3, 0x6d17d691, 0xb3a6d391, 0xf4853869, 0xe9aa5d08,
- 0x22f22b7f, 0xfe7aa874, 0x84bd4565, 0x4a65ff3d, 0xb68b1e84, 0x25c856ec,
- 0x0e28f8b1, 0x9dda56ee, 0x3c12e871, 0x81f60254, 0x153fc2f8, 0x5df1fba0,
- 0x1d9fe902, 0x5feb9f07, 0xf01ff5c6, 0x74e47484, 0xf4cdd30a, 0x0ba5357e,
- 0x4e9d6be8, 0x5cb1f6e6, 0xea7f40bf, 0xe7e7e428, 0x54fc5276, 0xc1aaddfe,
- 0xbb9f2bfc, 0x71e61133, 0x7c61aa54, 0xe9ddf8fd, 0xa56e3a1e, 0x63774fec,
- 0xfe579ec9, 0x6fc827e1, 0x49ff5e0b, 0x8867c63a, 0x6b82d327, 0xe6133f8f,
- 0x4cdd6f37, 0xe27cdf9c, 0x7cabbe45, 0xfd032c5c, 0x4a44b9f7, 0x8b91c4b7,
- 0xe3b31283, 0x06a06e8e, 0x51df9d18, 0x7e60acba, 0xe6221bca, 0x07721129,
- 0x09fff901, 0x10b50b9f, 0x8db9feb0, 0xa4b369d1, 0xcad461fb, 0x8dd7e68c,
- 0x7d01b4f7, 0xf4f20c4e, 0x6a8b7d87, 0x3e39f922, 0xbf686f84, 0xfad3ebe2,
- 0x5550fa33, 0xa3bfc05b, 0x3c317ceb, 0x64dbf787, 0xf0d73d8f, 0x3b26f91d,
- 0x3e72fe32, 0x013b853e, 0xe9a3e7d6, 0x4954edf1, 0xdaf87416, 0x457f1448,
- 0xf79337c9, 0xf932f78d, 0x503de5d6, 0x67ed0a5e, 0x03f262df, 0x47fac1df,
- 0xc7f50ae1, 0x0bd7ddf6, 0x24ac0fa8, 0x37ae4f14, 0x8dae5cca, 0x509f3aed,
- 0x292125b8, 0xffa05f8a, 0xee3fc414, 0x4b5fcc57, 0x97d28bbf, 0x625e30d5,
- 0xdcba7f6c, 0xfff2e02e, 0xc8ffc826, 0x7593fc88, 0xb67bee4c, 0x17a8fc9f,
- 0x2781cb17, 0xa579031f, 0x4157e9f2, 0x9832e55e, 0x7b8d67f7, 0x9531f9df,
- 0xba82cf93, 0xa7f51a9c, 0xb72b4e59, 0xe4f1258e, 0x46a733f4, 0x7d29cae2,
- 0x9d4e571e, 0xffc7c8ed, 0xc753fa57, 0xfc2657df, 0x27b0fae9, 0x61f59a3c,
- 0x3e22a4bd, 0xfe90facd, 0x620a45bd, 0x3be74ff9, 0xfeaadf9d, 0xe80864b4,
- 0xea5f309d, 0x4be6177c, 0xe262ef9d, 0x99fc06a1, 0x18865fdb, 0x816b8510,
- 0xf032fead, 0x809a6c23, 0x87617e72, 0x6ceef305, 0xbff40463, 0x584bd446,
- 0x1ee2dd7f, 0x8ce8760b, 0xf67c2f49, 0xededf273, 0xbe5aefff, 0x307b63e0,
- 0x861ca03b, 0x74d14be0, 0xe0c2d71c, 0x02403eac, 0x781f5143, 0x7f28b2c4,
- 0xf7970e79, 0x9ad83e17, 0xec2c780f, 0x8ed4951a, 0xfa30727a, 0x6f5cd593,
- 0x49abf69c, 0xb74f4fa0, 0x78bfa0e4, 0x8ae8bf7a, 0x34f7ff97, 0x209fefa7,
- 0xaecb463e, 0xa44ea48d, 0xba45d6fc, 0x6ff06ed1, 0x714d91b4, 0xcba6aff6,
- 0x5f7e2f4c, 0x01fd007c, 0xdbdb4f1f, 0xd8e2ca4b, 0xf9f2b7b1, 0x25f3d8ce,
- 0xb7178fae, 0xbd80b7ac, 0x8b46f174, 0x41bfefc1, 0x479d7ce6, 0x67af80f2,
- 0xc6bbb1ec, 0x8bf71e00, 0x5649e41a, 0xbc529cb7, 0xf342fc71, 0xb07fa1fc,
- 0xdd93eeb7, 0xca2f4fc8, 0x0f01dbc1, 0x11b49e2f, 0xa1db2fd8, 0x078a2dd4,
- 0x830a9de7, 0x4661c773, 0x2f0a1f97, 0x50ce5d85, 0x3673c411, 0x58dbe412,
- 0xf3e4133a, 0xb0240dd3, 0x2de81b32, 0xc1237ab2, 0xca0a57bc, 0x77c327af,
- 0xa35ed35f, 0xe6c2f3e4, 0xe8127f2d, 0x045b4b7b, 0x2fb685b7, 0xe015da95,
- 0x64e6ea97, 0x68d8f411, 0x74ffcf55, 0x147d725f, 0x4b27ddff, 0x13bd9788,
- 0xf009bc5f, 0x2143a672, 0x79efcfb0, 0x68f31ba9, 0x23e4b4cf, 0xaf34f5bf,
- 0xb2e47de7, 0x43f412a9, 0x3a665f10, 0x304c6a8e, 0x7b1527d4, 0x335c0007,
- 0xb5cbedac, 0x2bb77838, 0xa1fdeecc, 0xb2b7b3e4, 0x96fbf2cf, 0xb15ebf2e,
- 0xfeef8a2c, 0xfdbf2b1e, 0xb2efc9e3, 0x987f6a95, 0x9cd6b2f7, 0x65cf80fe,
- 0xc5fb917f, 0x7d67abe3, 0xccdc2fcc, 0x9abb65f3, 0x1a5efca8, 0x544dbf25,
- 0x01c4e37e, 0xe581fa5f, 0xdf9059f7, 0x2bbdf038, 0xf2e8fa33, 0x0872db9b,
- 0xc9b737e5, 0x7933c862, 0x7d76e655, 0xf42bf28f, 0xea0d3ebb, 0xa388e6b2,
- 0x100f01af, 0xe3ccdcc7, 0xc80e30fc, 0x71b8a4b1, 0x63957d9e, 0x8e59bfdf,
- 0x98236d97, 0x6f4b1317, 0x76cbc726, 0x80163950, 0x978e4cee, 0xce3952b5,
- 0x11df958e, 0xbecbf231, 0xdf621a5f, 0xff673757, 0x5e3a66ee, 0x6cd6479e,
- 0x88bcfdf4, 0x968d8f3c, 0x70914967, 0xbcf231be, 0xbcf26fbf, 0x9533cb8d,
- 0x1c5aa1d3, 0xc62d6aba, 0x2717acfc, 0x1e7c6d1c, 0x226ff2f8, 0x5baf49fa,
- 0xeafb5d98, 0x8063a384, 0x7870a62f, 0x743a7086, 0x7fd8fcfa, 0xd347c4c9,
- 0x5f8a4e41, 0xe42dfbaa, 0x28d92f35, 0x4b87d013, 0x1fa10e9b, 0xe8ab8e6a,
- 0xbe399576, 0x7311eba2, 0x8351659c, 0xc7c79eb1, 0x11db172f, 0xa89af25e,
- 0x77c38a6d, 0xb9c13d79, 0xe71deebf, 0xbd9c0898, 0x79f47dc5, 0x3e9706f4,
- 0x970a31af, 0x1f24d197, 0x8f1489e2, 0xbffe2f28, 0x2a87188a, 0x90c0bc2b,
- 0xeb913fef, 0xc2bafcc9, 0x944b0862, 0xf80e3e43, 0xec77f551, 0xb1b27d83,
- 0x303cd507, 0xb44d27a7, 0x7a9fc17a, 0xf28ddeda, 0x0965d3ac, 0xbc0dcba7,
- 0xd407179f, 0x55bf0114, 0x586e0b37, 0x5f43aa77, 0xbd86b9e2, 0x02517e8f,
- 0x55b0b47c, 0x0f915b70, 0xe7e0294f, 0x17f5d095, 0xe5bf29f8, 0x0bbdda14,
- 0xf8450b5b, 0x010ee17e, 0xc37bd213, 0xb6e95f4f, 0x59e3d388, 0x7009df80,
- 0x8d75b376, 0x57b7a7c3, 0xfc037e4b, 0x5b9d8fc5, 0x56e0c59d, 0xde046aad,
- 0xe77861b1, 0x3eaf3888, 0xbde3abc2, 0x98977837, 0xe4daf8e8, 0x220f1833,
- 0xf27dc92d, 0x5c6dbe6b, 0xa1b49aaa, 0xa7c7a67f, 0xf3bd17ee, 0x951b8864,
- 0x8e31920a, 0xedf18ddb, 0x8fffa01f, 0xf83fd7ce, 0x6eba2117, 0x09f1b9fd,
- 0x67c9f7c4, 0xba00cd0e, 0x24517a2c, 0xce974a36, 0xe1091746, 0x0140483e,
- 0x8935543a, 0x48f78c1e, 0x5ceb82a1, 0x65a8f8d1, 0x42ecd8f8, 0xd5b5583d,
- 0xbf4e981a, 0x49fedaaf, 0x9d33d82e, 0xcbef7577, 0x19ffbf02, 0xf898e501,
- 0x1f6173db, 0xfb624aa8, 0x6efc663b, 0xd8fad854, 0x1b31c3b1, 0x606841e4,
- 0x82aa8be7, 0x946b64b3, 0x457bfc3d, 0x7be971c6, 0x7fe6d798, 0x30bcc05a,
- 0x5cfa2f80, 0xd36f9e8b, 0x4bf334f1, 0x00e59aaa, 0x6aaa539c, 0x7109d2d8,
- 0x5683aa92, 0x1baad75c, 0xb75c614e, 0xa8b3f378, 0x459bab7f, 0xe31c9f83,
- 0x2188369f, 0x4d57f82b, 0x4ece304b, 0x1eb087eb, 0xe9a71f8c, 0xb45a8fcd,
- 0x1fbb75b9, 0xa7f9e4e4, 0x529cf112, 0xf444a6db, 0x1fce1b53, 0x47f18a1f,
- 0xd79ef783, 0xf9c13d1f, 0x318a6fe3, 0x521a479e, 0xf0a54fd1, 0xb1c59415,
- 0xff7cc3d7, 0x807fe7ec, 0xd6c76978, 0xf000fecf, 0x99d7fe2e, 0xe282fc3f,
- 0xbbb2ec91, 0x3f55ff41, 0x9bc636f3, 0x728eeff4, 0xf4f9d5bd, 0xeba71853,
- 0x41aacf7c, 0x47ad9d6f, 0xaabc4307, 0xe997cb73, 0x6f2c9f60, 0xd6f6869d,
- 0xfdc56df2, 0x40fb1c49, 0x036f812f, 0x9a13887d, 0x69b7b5e9, 0xf38060ef,
- 0x6c37a524, 0x0be38609, 0x5e2c25c1, 0x42b8f2a3, 0x6c78fc63, 0xe9a11c4c,
- 0x8ca66bba, 0x54d65281, 0xc27887d2, 0x978e945b, 0x8d7e81f6, 0x89ef6fcc,
- 0x1fe1277e, 0xd5b24e94, 0x9bcfbf48, 0x31f1fde6, 0xed4a6b68, 0xea109e31,
- 0x78f4de03, 0xc78a1bef, 0xdaf9056d, 0xdf8c27fa, 0xd3a6dd00, 0xfb3e7689,
- 0x938860f9, 0x6fbb931f, 0x56d57dc5, 0x5797ee2b, 0xf28bbeb5, 0x75edb9d3,
- 0x8f0937b4, 0xf09276bb, 0xf1938b1f, 0x8dead3dc, 0xe087162e, 0x853887f8,
- 0x79cf889a, 0xb1f1823c, 0x29e8a71e, 0x7585713e, 0x6523cf28, 0x1b259471,
- 0x298857df, 0x8f8c23ee, 0xd13df3ac, 0x1b83c749, 0x3a2e30f0, 0x0e3f16de,
- 0x72cb8e14, 0x20fd017a, 0xa78e16ce, 0x8840fad1, 0x778404af, 0xd07d1c49,
- 0xe9c59eb9, 0xfe63653a, 0x2c3e8449, 0xa26456fe, 0xdecf3eb3, 0xe0dea7d6,
- 0xc9f8b6ff, 0x6c79c587, 0xbe3a9e2c, 0xe7c7af8e, 0xb7ef8559, 0x98215a5f,
- 0x802a6ff7, 0x1d34971f, 0x513f2052, 0xf9f4c75f, 0xbc3b7076, 0xf31119e3,
- 0xf707576b, 0xeb371ea2, 0xde70a58b, 0x3fbc0e21, 0x6d2ef0e3, 0xc744eb66,
- 0x49c05756, 0xb3d8e9fb, 0x6979f903, 0x4fc521e3, 0xf0d7dbfb, 0x46fcc2bc,
- 0x4eb03f26, 0xefe0a204, 0x2e776e78, 0xbb322f8b, 0xddce3cdf, 0xd3a79e56,
- 0xea9c7f12, 0x718653c6, 0x0a83f916, 0xff3e97cb, 0xcf242778, 0x44efe82c,
- 0x5f204c9b, 0x2c5044f2, 0x593fb78d, 0xdc799569, 0x74958eba, 0x25f3c4bd,
- 0x449e762e, 0xde30514c, 0xfe35dcb1, 0x941a5260, 0x507e0a8a, 0x5fb64aed,
- 0x5a9ffb5b, 0x36bbd006, 0xc78c06f9, 0xebf099d6, 0xc217734e, 0xd4f71339,
- 0xaec031b2, 0xec937d66, 0x5fe018b1, 0xafed2aee, 0xd1573852, 0x275ce07e,
- 0xef3c3491, 0x94962622, 0xb7447cc2, 0x138f6dc5, 0x659d9307, 0x17851bc4,
- 0x9f3c6dd9, 0x57cebe42, 0x9f7d1fa1, 0x6dadb175, 0x3dba361f, 0xc495f002,
- 0xaf0bd5f7, 0xbbbce377, 0x580d051a, 0xd563aa9c, 0x05f2ce9d, 0xdae8dd60,
- 0x2e4b949a, 0x87890fc5, 0xfe0e27ae, 0xbddc685c, 0xaad1f41b, 0xa649e244,
- 0xaab14672, 0x4e70398a, 0xc84db467, 0xf53d3e01, 0x5fb48bea, 0x60488b7b,
- 0xa9cbbf8b, 0x92790be7, 0xe41cce41, 0x010bcc7e, 0x3526fe56, 0x5f39a702,
- 0xe92bc084, 0xd3bc7391, 0x39c62744, 0xd113af4e, 0xc5c9159f, 0xfccc9bbf,
- 0xf8001273, 0x88b27af9, 0x4a1a79c3, 0xc142bf78, 0x7f05da3c, 0x4420be79,
- 0xf1a21d18, 0xf46a5a95, 0x89edeb17, 0x436fb0b9, 0xc8369efc, 0xfde0ae4b,
- 0x9e332bf5, 0xe7e2a1f3, 0xcf52fb07, 0x7e6cffd3, 0x7fd07ec9, 0xa8f9de15,
- 0x36cffbd7, 0xdb32039e, 0xe42f08ef, 0x7bb9500d, 0xe7b5884c, 0x5c1e5b2b,
- 0xb1e0f90d, 0x0464f3fb, 0x91541be4, 0xa1f20d04, 0x077df6cd, 0xf1c84de8,
- 0xe0271271, 0xd97d67b1, 0x87db7e0b, 0x98f26eff, 0x0b57e2f3, 0x2e8dfbc1,
- 0xf058dfdc, 0x3f51db97, 0xf88c3359, 0xfc46abb5, 0xf198463a, 0x4bb3c468,
- 0xb28de233, 0x787ce079, 0x3c6f1a4e, 0xb3c6655f, 0x0e1da844, 0xd0404af6,
- 0xf931fe80, 0x11ebcd0f, 0xa6fcdeee, 0x8f5f1b34, 0x5fe95e38, 0xa99d2d99,
- 0x533b806c, 0x985ca10a, 0x19cb28e5, 0x83dfe012, 0xf12b02d2, 0x7e85cd2b,
- 0x8f9f0649, 0x73bec150, 0x00891c80, 0x047286af, 0xcf402827, 0x6e07c83b,
- 0x7c85a7a0, 0xd919be42, 0x2cef3d33, 0x5cd0e97f, 0xe03ad5fa, 0xae514bdf,
- 0x14a939d8, 0x06cda812, 0xb0dcd539, 0x367d076e, 0xf38242b5, 0x18ad44e6,
- 0xddcce706, 0xc7903e58, 0x451aefde, 0x182c5f30, 0xfa0e9b3a, 0x291e7aa9,
- 0x80f7fd03, 0xfc033dd2, 0xccedfbdb, 0xaec8b94f, 0xa5ff3ea0, 0x9cafdf5d,
- 0xa9cb97fa, 0xc8b5763c, 0xebc39c2a, 0xbb64d96a, 0x22cdea00, 0x4eaef79e,
- 0xc608bbae, 0x19916cef, 0xc0b6155c, 0xb7c7e005, 0x741eb8ca, 0xf3c64c56,
- 0xadbb612c, 0x7613ed85, 0x78927cb5, 0xef3e947b, 0x22f87e6c, 0x6a3c3388,
- 0x793fbf89, 0x9df2cdbd, 0xfaf0d4fc, 0x3f9314db, 0xe58dbd71, 0x94303c4f,
- 0xf96963ce, 0x330ebe69, 0xe9c49879, 0xabfcd2fc, 0x5adbfe70, 0xe74f3fa8,
- 0xfcde2251, 0x3ce84ba3, 0x312dbc27, 0xd33c4afd, 0xa3b3a4e7, 0x0efef03c,
- 0x3e0065a2, 0x02214c26, 0xf784f3c8, 0x8febee08, 0x7e8f99a9, 0x94898bd5,
- 0x4c5f29cf, 0x0b7ca16d, 0x89c3ae7a, 0x36d8fbf6, 0xc997c0c9, 0xc17bbd53,
- 0x90771ccf, 0x771dbea0, 0x9e3ed8d0, 0xa71c4404, 0xd27cf8dd, 0xc6bd6331,
- 0x1233f7c6, 0xf7f03a49, 0x8445afda, 0x689babab, 0xbb7ed177, 0xfde0062a,
- 0xe1675d02, 0xbf2d1494, 0xade34b16, 0x8c6d2bf3, 0x08551e2f, 0xce8f2fae,
- 0xc13ee277, 0x9855f99e, 0xcfc5fd27, 0x9de243bd, 0x4bd28bbb, 0xddff6c49,
- 0xa7814493, 0x604abd7c, 0x8ccbaef8, 0x4bd297de, 0xbe758f9d, 0x7339f9d6,
- 0x5e37827e, 0xcec38ade, 0xf9a29dec, 0xfc050423, 0x01025db2, 0xe5de76bc,
- 0x9b5fe435, 0x2bb93f4b, 0x6ea9e00b, 0xb676833e, 0x1e7e25ad, 0x225b06d4,
- 0xf2eefbf3, 0x8d7c84af, 0x04a1529f, 0xbf73d8fd, 0x5aafd16b, 0x88534103,
- 0xe6ead9eb, 0x79a7b9e0, 0xe201b236, 0xe65d52b0, 0xfbe02eb5, 0x53572be2,
- 0xb32b1f78, 0x951f9d20, 0xbfdf8435, 0x2f8c1084, 0x077e4c48, 0xa3eb20ce,
- 0xda357fcf, 0xb46d9b0a, 0x1b9b66df, 0x6af54ffb, 0xfdafc002, 0xc1127ff3,
- 0x673ae99e, 0xe00e3a45, 0xddfe8ffe, 0xaf66369b, 0x6cf762dd, 0x9527fe05,
- 0x9a1f2869, 0x48ad5137, 0x14a07385, 0x4fe271ef, 0xe29a5dba, 0xc28dbaa5,
- 0xe0b4e293, 0x78f110be, 0x979eb754, 0x517bf840, 0x024240f2, 0x5d05bc81,
- 0x422d0a9f, 0x7ff945c8, 0x0219cd8c, 0x92a5233f, 0x60829bce, 0x5fd63627,
- 0x3e11d49b, 0x907986c7, 0x200b2f94, 0xde609df9, 0x415a2403, 0xd59ebaff,
- 0x64aaf3f5, 0xd566fa82, 0x96a05283, 0x6a4eb3f6, 0x24fc43b7, 0xc116a3db,
- 0xa48a7356, 0x41baf9e2, 0x1d1e4c95, 0x87278f39, 0xec2a15ed, 0xde25ffa3,
- 0xef8e2f16, 0x8b757ce6, 0xe03efbdd, 0xf77f773b, 0x346b301e, 0x7b4f1b3b,
- 0x79f686d9, 0x3b706f58, 0xbbaf84ac, 0xfb653e13, 0x397424c6, 0x71e863e6,
- 0xa0deb37a, 0x08a6f072, 0x44a9f572, 0x87943cf0, 0x4f40affe, 0x1fd288c9,
- 0x682c9d7c, 0xb68bd9ae, 0x2f6a389b, 0x57a4e3f0, 0x8c73ecf0, 0xc077191e,
- 0x7ef00b5b, 0xe661fd57, 0x2a21d187, 0xa33e9c8f, 0xec173854, 0xfda1d70e,
- 0x937d265f, 0x3fa63e56, 0xcf9cb5da, 0xe5d5f8cc, 0x79ef2cda, 0x56bdb42b,
- 0x488035ec, 0x84438f30, 0x0e6a1c08, 0x2203a3e8, 0x855df7d8, 0x5c285f94,
- 0x28ee411b, 0x0d9f26bf, 0xb37c095c, 0x3b0ae5b6, 0x5e77c7c8, 0xebf4423f,
- 0x7fe3b8a8, 0x7681de88, 0x08983f96, 0xfbba5878, 0x423f5f2c, 0x5d30e748,
- 0xc7447ca9, 0x37be7443, 0x172eb9f3, 0x394070b5, 0x009b9d87, 0x104288fa,
- 0xeb256b09, 0xe8a760dc, 0xd86d75f6, 0x7cc64d9e, 0x366ee5ef, 0xdbacad5e,
- 0xe60d9ae5, 0xd455dcbb, 0x2efb7cff, 0xffa8e7d5, 0x5d2f9512, 0x7fa3752d,
- 0x214e7d56, 0x81efd481, 0x7a3a16af, 0x455f01ba, 0xf8b17ef6, 0xd472081a,
- 0xf9cbffef, 0xcf9e6cdc, 0x3e646a3d, 0xc5f78893, 0x0a17aa76, 0x64cfacee,
- 0xcade417c, 0x7e0be688, 0xf927b1de, 0x1be54f1e, 0x7918c7dc, 0x84f1c936,
- 0x96c72a16, 0xe4d63958, 0x4827bc32, 0xbea0756b, 0x59f5cb33, 0x076aaf3e,
- 0xa24dfbc3, 0x9f3067f7, 0x60f74b6a, 0x955cbbe0, 0xc0a74ea4, 0xe88b36e6,
- 0x54b69007, 0xbb123ac3, 0xdc59fbbe, 0x7a07af8a, 0xa668529c, 0xb3e74d7c,
- 0x0bbdeec9, 0xcdd6a5e4, 0x58384afc, 0xa3707604, 0x3c377bcd, 0x12d85077,
- 0x88c75ce0, 0x838b3650, 0xd4720c84, 0x4c38dc93, 0x490c1172, 0xe9f93eb8,
- 0xd08174fa, 0xf6c53c33, 0xd52f0664, 0x0c7f6016, 0xb06c202c, 0xf9f304a5,
- 0xf3b2e606, 0xd8f303f8, 0xd84f59fd, 0x91b9bad9, 0xd97a07af, 0x075b2b68,
- 0xe2259378, 0x777de6b7, 0x885401b8, 0x7bb26e0b, 0x6cfe831e, 0x479c1ea5,
- 0x02689b96, 0x292ca3e5, 0x53fec028, 0x605562ca, 0xd6c240f1, 0x7f692813,
- 0x42d5d359, 0x20b28f58, 0x07de0097, 0x9c8e263b, 0xefe5dab4, 0x8e6ac717,
- 0xb95ba3b1, 0xe853ec1c, 0xb3a7537c, 0x3c70e43c, 0xf80f8286, 0x80dd74ed,
- 0x9cfced93, 0x93f835e5, 0x7ecd9e19, 0xe60c1015, 0xddfaf125, 0x29ec910a,
- 0x2df8f7e8, 0x86c59df0, 0x68838f7e, 0x078bd041, 0xce5ceced, 0x035b416a,
- 0xdd48dff5, 0x40b7b836, 0x2607ebe7, 0xf449ab5f, 0xa729c495, 0xa517c173,
- 0xf026fe7c, 0xd3e4e75b, 0x0ce157c3, 0x7e3307ba, 0xbc8688f3, 0xcd6e9d47,
- 0x766e81b2, 0xeb447388, 0x7e829761, 0xa090a77b, 0xb9d39f81, 0x0a706050,
- 0x2a179e36, 0x5c2fe319, 0xfdfae9cf, 0xe9bcd82b, 0x8ff1f307, 0x6c567bc6,
- 0xd1e00d9a, 0x1b9f0fe1, 0x31eb9d32, 0xc8c9fb9f, 0x3263c709, 0x4cab4f31,
- 0xc852bb81, 0xda0716e9, 0x4c89d555, 0xd0fccdae, 0x79c2941f, 0x7c50cbce,
- 0xedf4097d, 0x8324d72f, 0xcb7fed1e, 0xafa044e1, 0x825d0f19, 0xd83ef47f,
- 0x1c9bfab7, 0x2f5b7f77, 0x94063233, 0x91999d83, 0xfea58199, 0xc529debc,
- 0x26a5ef8d, 0x6bb8cf7c, 0x46dbe580, 0x026a6bf1, 0xf7a4efed, 0x283c778d,
- 0xf718ddee, 0xf8604fae, 0x3c7457ae, 0x672049aa, 0xc496ba91, 0xb32779ce,
- 0x8cdc1c7b, 0xb67d6b9e, 0x7e8a4972, 0x467683cf, 0xf2b9e23f, 0x6b025046,
- 0xf909b265, 0xf465c59a, 0xe8aa5c7c, 0x1992fd18, 0x8df5bf5c, 0xff7d872e,
- 0x9c6484dc, 0xd3b5d9ef, 0x7274bc70, 0xc5387d97, 0x8b32fceb, 0x939af106,
- 0x089eff73, 0x66e6ff47, 0x3c1015b5, 0x1ab35a62, 0x16ffaefc, 0x9409b9bd,
- 0x54f5694e, 0x3e32a511, 0x74a3b900, 0x13f712b9, 0xe6e258e7, 0x604d8ddf,
- 0x76a7f57e, 0x919b8e37, 0x22bcb831, 0x103eba3f, 0x23f3a4e9, 0x8accc395,
- 0x61739131, 0x24a63f94, 0x2ea791c4, 0x7ec33499, 0xd30fae80, 0x7d75fe38,
- 0x1a43cbac, 0xefec19c8, 0xa8fd5195, 0x7f2873d3, 0x90e31d35, 0xfcb427f8,
- 0xf3b04bf9, 0xa114a713, 0xbff2a3be, 0x0465e506, 0xd076dfd3, 0xc7f151a7,
- 0x0777d6ae, 0x87debec1, 0x05c679ff, 0x90ff3bfb, 0x3fa05dba, 0x4df2fd8f,
- 0x7c11e417, 0x87164bf8, 0x1fe4d5b8, 0x9e981379, 0xcd94260f, 0xe6dd7982,
- 0x378167fb, 0x0ac92f8a, 0x90b15fb6, 0xf3c6bb2e, 0xbcf3c683, 0xf3e6824b,
- 0x77ec7ebb, 0x8e3f1489, 0xc3a708fe, 0x4af5c6c2, 0x7be30a96, 0x8f3d0217,
- 0x58efff71, 0x4367bb13, 0xe36e6787, 0xa27c0568, 0xf958b47f, 0xcc9b76be,
- 0x74cf05d6, 0x72f2a7d8, 0xdce199bc, 0xfd81cbb7, 0x44447bcd, 0x1d0e64bf,
- 0xafd5056b, 0x679616de, 0xbcc79e6b, 0x3812d50f, 0x5eef3f2f, 0x785dfd01,
- 0x9d7497ff, 0x07b8aef2, 0xf3ccb3f7, 0x603fdf34, 0xfba4b73e, 0xfd380b49,
- 0xe517882b, 0xa20f262f, 0x9b3bed85, 0xf7a77ae3, 0xfe6038e7, 0x3f7025f7,
- 0x838c80a3, 0xfbad877c, 0x2f9d2687, 0x9f83aacf, 0xf3c13ed7, 0x08f98f33,
- 0x5412b396, 0xe5ba2e76, 0xabe012f5, 0xf05bcda5, 0xab6f96be, 0x1cb4966f,
- 0x8931fc4f, 0x1f6a1de8, 0x21fe07ae, 0x3760c15e, 0x467f5d2e, 0xc32c7e61,
- 0xf9fccdc3, 0xdc5f30cd, 0x72f76527, 0x3e58bcdc, 0xcb9f7d1b, 0x7cc609d3,
- 0xf9f08eeb, 0x258f3673, 0x9f481f7c, 0x679f999f, 0x5e78b025, 0xd5f2c6c5,
- 0x6b94e803, 0xe60e8f5b, 0xdf300ae7, 0x3317e75a, 0x65202c3f, 0x14429925,
- 0x8d7e5bdd, 0xa9f4ea70, 0xe7c39ba8, 0xfbe0cfe3, 0xe710196f, 0xcc0f8de9,
- 0xdb94eef4, 0x9a7c8307, 0xc3d9dde9, 0x09adf0f9, 0x50afdd6c, 0xffa0253d,
- 0xd5b291e6, 0xe3bb28ee, 0xefb75498, 0x1b372017, 0xad46df19, 0x7b38cca7,
- 0x79f5c645, 0x0fed4b99, 0x1d210cf7, 0xbdfec026, 0xe9ef0fd5, 0x79f11ce3,
- 0xe01261b4, 0x13cb14b9, 0xd86d32be, 0xfcfb48b0, 0x4224cf47, 0x046bb53c,
- 0xa74b78c1, 0xc7ef08cb, 0xf3c22209, 0x62c3a731, 0xef5feda9, 0xd8d9ce83,
- 0x47097986, 0x9af1e6be, 0xf1a5adaf, 0xbe4ff9e6, 0x9f7e11fe, 0x6e5cadca,
- 0x36e1ff74, 0x5b5bb74e, 0xdcf3bed8, 0x0f48e575, 0x0720fdf3, 0x16497704,
- 0x1c1bcaed, 0xcdfd00ad, 0x5da799f4, 0x6bf41c71, 0xfdc89d0c, 0x98bd2f9c,
- 0x2f51534f, 0x4cc27c62, 0x9b870abf, 0x35abcde5, 0xea2d6fe8, 0xe55dcf41,
- 0xafae7a60, 0x63cf31f3, 0x7a80934e, 0x82ff0ccf, 0x0f572b8d, 0x367f3020,
- 0x8479d8bf, 0xe19ea206, 0x55e7d4f3, 0x473c3441, 0xd38fb31a, 0xce89397e,
- 0x72d85cab, 0x2ec1e63b, 0x2c27f3a5, 0x1bf183de, 0x5e1d7e1d, 0xc44a3cf3,
- 0xf106d90e, 0x068215d6, 0xdef636fa, 0x5ee18f16, 0xbb0d39a8, 0x8efd0207,
- 0x21abed48, 0x2fc47bfe, 0xf5d6ffa0, 0xb445c101, 0xfb808d6b, 0xafd23d5e,
- 0xf4ede585, 0x051ac74c, 0x58aa39ee, 0xe3a5c427, 0x6d42fa82, 0x59de9458,
- 0x1b52b818, 0x88378066, 0x1a8b1c79, 0xa7cf0dca, 0xb8fa8c38, 0x35237937,
- 0x74d2f3f1, 0x4de5d2f9, 0x870abf97, 0x52ffe2ca, 0x36565f60, 0xd107e9e8,
- 0xf67aa0cf, 0xc38b076a, 0x7d23703c, 0x67a3e965, 0x79fc710c, 0xe67d19e3,
- 0x79f1d389, 0xc503eb4f, 0xcedf4183, 0xedf51872, 0x3e8f9df7, 0xf42e5d0f,
- 0xc2e599f9, 0xfe3d7f8c, 0x1983a665, 0xd81700ff, 0x1d5a07fb, 0x9004bb81,
- 0xbfa70677, 0x76708ed5, 0x70691466, 0x7c00e59e, 0xd2dcf540, 0xfd631fcc,
- 0xb96cb126, 0xee34fd03, 0xf3f16907, 0x0ff6c26d, 0xfec463b7, 0x1e301196,
- 0xc8341311, 0x2cb3170b, 0xbce95b35, 0x1cb421c4, 0x9ac1e905, 0xeb9fe708,
- 0xe1132f8a, 0x7e5a86de, 0xc2d6ba3e, 0xfde96dce, 0x75b071ad, 0x39772f49,
- 0x683b56ca, 0x6b5f27ff, 0x78b0702b, 0x3819fa2f, 0x93ee114f, 0xd8317ea4,
- 0xcc132fb3, 0x234bcd4f, 0x0ebe817b, 0xf20f19e2, 0x85238cfd, 0xfb655f9f,
- 0x0b2ff46c, 0x796acd4a, 0xf908d55e, 0xa6077dfd, 0x5a703dc1, 0x6ccee592,
- 0xf1c27f5a, 0x5967ab3a, 0xa9bb64ce, 0x8378edff, 0xce5a47d5, 0xa7f5a50c,
- 0x3ab26f1c, 0x0551086c, 0xade3b4f3, 0x3051fe69, 0x3fdf9b8e, 0xf20919e0,
- 0x5f985920, 0x3051ed2b, 0xa3efacfe, 0x2c06a2af, 0x00cfaff8, 0xba9f82ff,
- 0x0e4fe8b2, 0x7915ef88, 0xbf1fd854, 0xfdb6821f, 0xe3a97bbe, 0xf0587455,
- 0x01280a5e, 0x3e385bff, 0x2690ba75, 0x23c848cf, 0x48cf4124, 0xe5d877d8,
- 0xdd0136f0, 0x5db40ff3, 0xf4d47206, 0xf00bdfc6, 0xac21ccfe, 0x28ca7c9f,
- 0xc9e6df70, 0x8fad0617, 0xe5dbbfde, 0xf401dc28, 0x3b4064a1, 0xe4dd5041,
- 0xd4176a66, 0xc95e3f52, 0x68c47f01, 0x7e713787, 0x6ca12d7b, 0xc0d9f237,
- 0x8e1fd310, 0x8fd0bdb2, 0x2da4572e, 0xa77c4fa5, 0x4110aee4, 0x3564a63f,
- 0x720b9c1f, 0x9cecdff8, 0x60f1e0ac, 0xf0e6dbfe, 0x3f6c20fd, 0xe9fb01dd,
- 0x9235afa0, 0x71e74fe1, 0x238f1605, 0xfe510569, 0xfd079f05, 0x37dc2a7e,
- 0xf6c1ce32, 0x44bce95b, 0x13461f58, 0x887ccb15, 0x6a00e413, 0x49df58bd,
- 0x417f0782, 0xcec87ffb, 0x035b74fc, 0x2c5dc431, 0x5f7eb64e, 0x7dd992e8,
- 0x5af0722d, 0xa709e3d0, 0x78f41b88, 0x848ae3d7, 0xfb9218f9, 0xb09fb847,
- 0xde0042cf, 0x1b80e4a7, 0x17ddd9e2, 0x1206ea49, 0xd38bafe9, 0x21f7ef5b,
- 0xe208bd45, 0xcc5ca31d, 0x90aa78be, 0xf768fe60, 0xfb002571, 0xb659294c,
- 0xfabf689a, 0xef7b072b, 0xcfa2a4d6, 0xd6c11e81, 0x8fe30204, 0x440d45db,
- 0x353f874a, 0x1f81d9e6, 0x288e0336, 0xeeac521e, 0x94bfa03b, 0x6cde1433,
- 0xfc41ee7c, 0x24e8ea4a, 0x5789df8a, 0xbfb85539, 0xf07b29e1, 0x7b9fcc2a,
- 0x24f782d6, 0x72b4566d, 0xad3e6fa8, 0xf35e21ba, 0x01307654, 0x05acf3e7,
- 0xa139b3e7, 0x1465e2fb, 0x608d5fee, 0x20e4bf7e, 0xe4052d92, 0x83bd48a8,
- 0x32704f3e, 0xc2cab87d, 0x938a68e4, 0x0243cfc9, 0xde0f3f1d, 0xd1f9442b,
- 0xbaba1bf3, 0x7e8879d9, 0xc089b7d7, 0xbae509c7, 0xc1121e3f, 0x465c9e8f,
- 0xec9cfd70, 0x3a2a0394, 0x1ce71e9f, 0x08cbff4a, 0xfb2e1f5b, 0x5fc63160,
- 0x82de0529, 0xebd80bdf, 0xf052f7e4, 0x39cb987d, 0xed214c9f, 0x53e7ac22,
- 0x442d11ce, 0x9cfcbbc7, 0x9f3d7714, 0x527dfbc6, 0x7d125220, 0x2aacf0af,
- 0x1215df01, 0xad3b7ae3, 0xc438e4be, 0xa66d8b7b, 0x235eb0e7, 0xf4091e3c,
- 0xb1b734d7, 0xaf93a47d, 0xe0c9834f, 0x3d1abce8, 0x1c4d3e6e, 0x0bda28f5,
- 0x78068aa5, 0xbcf4e2d9, 0x7e44fb0b, 0x2f9e26ea, 0x8fa4f33e, 0x388d3fe5,
- 0x72f18097, 0xe04e9fca, 0xebeb8b8b, 0xef3a76fc, 0xfeb1878b, 0xaf410f81,
- 0x5a78f85c, 0xf7f9e82a, 0x4bd1beb9, 0xbf80ef9d, 0xbf8c49dc, 0xe44697dc,
- 0xc49214b3, 0x0de446c6, 0xd9fa0ef8, 0x8a6e0729, 0xa92f7e7b, 0x0fd9d4a8,
- 0x4ed041e6, 0x36d32fbe, 0x1f4ce41b, 0xe32701e7, 0x7ab9736b, 0x10ddb2e5,
- 0xce7ff707, 0x03a98bd6, 0x5a1e61ce, 0x62488fd8, 0xd6ad567c, 0xf203375d,
- 0xc6329c62, 0xf9f9d3bb, 0xc97e68ab, 0x9d17e28c, 0xcc9d3aef, 0xa7f9d68f,
- 0x989bc778, 0x39fc5fdf, 0x126cee21, 0xfe7507b6, 0xf8cfccb9, 0x6cfdb2f0,
- 0x7f8de89d, 0xa9eedd3c, 0xf8631ea0, 0x9be33f66, 0xf81fca22, 0xf03d10fb,
- 0x966f998f, 0x5f37caf5, 0x967e0227, 0x779f16b7, 0x67d9a59f, 0x973393cc,
- 0xf3f11c13, 0x624d9f28, 0xa943b1fc, 0xe82e51fb, 0x1a2dab8b, 0x15ca03e8,
- 0x3e52d759, 0xdfa091df, 0x03935a7b, 0xd3122df5, 0xac5a5b3f, 0x38b67fa8,
- 0x678c5ebd, 0x68f3b065, 0x43b6f244, 0xc036b41e, 0xf3df46a6, 0x8d93a57c,
- 0x13439413, 0xf41d828e, 0xf1ff4617, 0x8dc1e757, 0x82b32430, 0x31cc61d1,
- 0x0d98bd65, 0x8f853be9, 0x00bd7f00, 0x577e833a, 0x73c1587d, 0x2b0f4bfe,
- 0xd85f17a8, 0xc4097af5, 0xcb7cf48d, 0x2f5f3b71, 0xef051a29, 0x9c7b3e33,
- 0x8ebd63eb, 0x27a0e7a9, 0x4ea6f74d, 0x997f4c20, 0x032d3def, 0xb48dc9fe,
- 0x9d03ef9b, 0xd61e4545, 0xb5db6b9d, 0xcc16a069, 0x0ace81f7, 0xfff6855d,
- 0x699e83cc, 0x7dce352e, 0x6e1f9ca0, 0xc1db6d20, 0x4fdf3525, 0x6de7d749,
- 0xaf93ff30, 0x2f881484, 0x919a9506, 0x9aeebeec, 0xba3fd01c, 0xc51fe1dc,
- 0x11c3f05b, 0xbf68fb86, 0x5fbef3e4, 0x08bdd893, 0xbfee0aed, 0xefb09afc,
- 0x7add7c82, 0xdde2c9d3, 0xbb9fcb79, 0x7e61f409, 0xb9f707a5, 0x9f98934a,
- 0xb2121bfc, 0x34bd00e5, 0x41c8e309, 0x2a3e2d59, 0x5223de44, 0x0f3808d9,
- 0x425fb3b5, 0xb9af8c3e, 0xc138efbc, 0xf7ba90ae, 0x26e377c3, 0xde83e5e6,
- 0x955e8e76, 0x0e98eb0a, 0x74ab8537, 0x87023393, 0xbe5ed70e, 0x39ae68ce,
- 0xe1fcc0ef, 0xcd43d03b, 0xe0d88e87, 0x820f9d7b, 0xfd18a7ad, 0xe801f8a3,
- 0xe107e11f, 0x78eba836, 0x87e707f8, 0xfc6dff2f, 0xf159fd40, 0xfe00fc3c,
- 0xe2f7e260, 0xe689ff87, 0xfdaf6a07, 0xaf6519d3, 0xa7961505, 0x3e75d7a5,
- 0xc428e458, 0x608534f7, 0x65d905be, 0xe2dfbf67, 0xf038c64d, 0x46366ef3,
- 0x064787d7, 0x76e22f83, 0xe37930a5, 0x0e8f5df7, 0x8e576809, 0x66e10aa6,
- 0xa206e3b4, 0xbe38d43e, 0x804111c8, 0x1730ac7b, 0xcbec0b37, 0xc5c82a50,
- 0x10f4eb68, 0xc756fff0, 0x1f605965, 0xe72639e6, 0x1f6d7f00, 0x5815fcb1,
- 0xa80fb6b2, 0x1aa37e7c, 0xbd749fb1, 0xab7797b7, 0xc5c43f8f, 0x0f72e1f8,
- 0x7a014f3b, 0x5d0e1a3b, 0x005903ff, 0xcb34210e, 0xf5038df2, 0xe83b4b75,
- 0xe2838073, 0x9a40b775, 0xb4283ec0, 0xc18ad278, 0x9217ebce, 0xd6aece00,
- 0xbc43072f, 0x9fcb7a68, 0xd3bc020f, 0xcd267df5, 0xb664cfb8, 0x477b75a3,
- 0x7b742bf7, 0xd088a248, 0xb76826ed, 0xb86ee7f0, 0xafd61b1f, 0x71cf0d90,
- 0xbd5a743e, 0x57e5c3c8, 0xce98f3a2, 0x690d71e7, 0xd7c8b843, 0x99337cdf,
- 0xc70667d2, 0x24fdf4c7, 0xed0b9094, 0xf14d5c84, 0xfc44b570, 0xab9c7449,
- 0x1c7c8135, 0x8cd727c5, 0xefe1d637, 0x3f48f4b2, 0x5e6fbdbd, 0xe299261f,
- 0xdcb7dff1, 0xabe763ef, 0xe763eaff, 0x150e2767, 0xa82c12fd, 0xb9d933e3,
- 0xc3c33759, 0x7afe257e, 0xc98b88f5, 0x7b4b44f1, 0xdc1b9c2e, 0x5c2bf3bd,
- 0xfcecf71f, 0x13b01dea, 0x08971c27, 0x3c4e01e4, 0xf709263e, 0xe067c73d,
- 0x6fde9d3e, 0x0e4da7f5, 0xff239ec2, 0xef82f7e8, 0x1478f0a3, 0xe586cf80,
- 0x3d0f1d8b, 0x3d9dfd0c, 0x3ce8912c, 0x3bc512f3, 0x2569e20c, 0x7df87efc,
- 0xf497b302, 0x5efc7df6, 0x5972ffe6, 0x9b6b7ef8, 0x625efdc4, 0xd5f3a28d,
- 0xe524f354, 0xf57ae845, 0x52e3d2b1, 0xe07d2c6e, 0x0f9d63ef, 0xdc6793cf,
- 0x579fa95b, 0x23f8e3ae, 0xf3c3df7b, 0xdd345700, 0x7e7d8121, 0x3c488645,
- 0xa95ee351, 0x2a3e0f52, 0x8b8f71ee, 0x76eae5e7, 0x1fa7deca, 0xf706919e,
- 0x7a988859, 0xe5b2dd55, 0xb7a85c95, 0x71cf7189, 0x457bf19b, 0xf0121dcb,
- 0x262e17ff, 0x3f8dbd1f, 0x27ca62f1, 0x09dd0297, 0x040af3b3, 0x7d332394,
- 0x7dfcecf7, 0x9ea8fb6a, 0xfd13ddf1, 0xb17874cd, 0x2ff708a3, 0x9987a37a,
- 0x79d1776f, 0x42fce9fa, 0x6a7e9e74, 0xb9f1ed8f, 0x2f92feb1, 0xbf3aeb03,
- 0x913eb756, 0xce9cf60a, 0x1952d3a7, 0xf1d84cdf, 0x46712a70, 0xdbc665e8,
- 0x66fd395f, 0x0ce66d11, 0x826dcffa, 0xe17d42e6, 0xcf906d27, 0x9c61c652,
- 0xda0956f5, 0xcfe7841f, 0x59b1d79b, 0xd7bc28e2, 0xd97bd7ba, 0xa0ca1587,
- 0x15ebcd6e, 0x7c0e17dc, 0x4aa75e6d, 0x7049d40f, 0xb48958ad, 0x6e31e99c,
- 0x9970eba7, 0x2936fce9, 0x04f479c3, 0xcc0f99a7, 0xb9f6eaf0, 0xc5394f7e,
- 0xda14b4c7, 0x216ab5df, 0x1d662fce, 0x69e978e6, 0x5e69edfd, 0x7ffc4d47,
- 0xd7d4d8e6, 0xc93dbd00, 0xe66e999b, 0x947f5d76, 0x587900c0, 0xf91ec1fa,
- 0xf48e95c2, 0x10a7392d, 0x0f1bec0f, 0xa24f93b4, 0x7d3221d6, 0x9ddbf208,
- 0x27acf66e, 0xce7a5b7e, 0x11a9bc42, 0x1f9b93be, 0xeddf0074, 0xb01cea90,
- 0x59c533af, 0xf1449b5e, 0xa2d3f535, 0x74bcf1eb, 0xc84085bb, 0xa9cb5a6c,
- 0xa84710bd, 0x9f30483e, 0x7765a8ba, 0x4be9f031, 0x51fa1b52, 0x7909675d,
- 0x6cceca30, 0x8075a96e, 0xc69cd61d, 0x4bed03ce, 0xcdbc8626, 0xbf191247,
- 0x3d3e1f36, 0xfda713c3, 0x8ebf6f00, 0x7172d278, 0xfc61765d, 0x058d64a3,
- 0xd0553fe7, 0xbb034e5e, 0x0f7646e5, 0xb8eb5763, 0xbc28d397, 0xa324b79d,
- 0x7cd6999e, 0x4a6e1dcf, 0xf33fe088, 0x1cf779f1, 0xdf40db41, 0xac35512b,
- 0xe3645497, 0x7fb8f8be, 0x1d375ea5, 0xd194afda, 0x2e2699bf, 0x751e2096,
- 0x03c84332, 0xd0a7717f, 0xa77e12be, 0xc6ce5fcd, 0x2a7f6e21, 0x4c6f9ff8,
- 0xbf8d1d4f, 0xf5eaa26d, 0x6bf7f00b, 0x5b4fc988, 0x6eccedbe, 0x3e5f6d2b,
- 0xc77cc053, 0xe22cee69, 0x929fe28f, 0xf99e9435, 0xfa5b2f94, 0x5f5f0117,
- 0x673c6a57, 0x41ccb335, 0x63f1d102, 0xc2c32dc1, 0xb5e78fb3, 0x7efc0b76,
- 0x57e72e59, 0x359f7e71, 0x5df0d53b, 0x66766139, 0xdd9136f5, 0x7ec85257,
- 0xaf975127, 0xbc39711f, 0x37c7fb8a, 0x700cb37a, 0x0d28874c, 0x693334fd,
- 0xd75dda28, 0xe5c76d9c, 0xe0fc5cb9, 0x78e89bad, 0xf2611a3f, 0xabc5c56b,
- 0xd8322f90, 0xc84cca7e, 0x6f41122e, 0x66bbdf1a, 0x471eb1bc, 0x27abcf8e,
- 0xb3307d74, 0x9bfdc455, 0xcf148599, 0xd3b18902, 0x18beadbf, 0x865ed167,
- 0xe7b5d078, 0x04bbf83c, 0x83e2fa31, 0x2fa4efd2, 0x3832a05e, 0xd2f5ca9e,
- 0x0fdfee44, 0x6f408322, 0x1f1b134c, 0xa2ea3e06, 0x0e35a6eb, 0x8eebe91f,
- 0x5097efee, 0x21be0639, 0x8f18691d, 0x032e769d, 0x7f7449f3, 0xa847ac3f,
- 0xb1c5a25d, 0xcc4bee97, 0x1307dc31, 0x76512bd6, 0xfdf05c89, 0xd46992ed,
- 0x00f2551e, 0x9fc481be, 0xe30cfa8f, 0x70902592, 0x8cc1f102, 0xa9e71853,
- 0x8affa896, 0x4c13f3eb, 0x097fd1cf, 0x30f91129, 0x9c7a2bdb, 0xdba49ad9,
- 0x093e4653, 0x97af1bc7, 0xf3a3ee31, 0x13e00949, 0x117affe4, 0xf1bd3ae3,
- 0x6f7e3e8d, 0xfaa212fc, 0x0f384928, 0xfbf970bf, 0xbcf2fcb6, 0xc8c327ce,
- 0x89f0beb0, 0xbf3a1fce, 0xa609d8c4, 0xeb4f5078, 0xe9894bcd, 0xd69edf88,
- 0xc847979b, 0xb37bd7a8, 0x3126766b, 0x744aee3d, 0x5d577f63, 0x7609d334,
- 0x11eb958d, 0xc70add7d, 0x9f19eab5, 0x573edcbc, 0x6aa3fd82, 0x11d91fd0,
- 0x60f1e83a, 0xae972f9d, 0x9cff1821, 0x6756f5ce, 0x56078b2b, 0x7003154f,
- 0xe5b8a284, 0x9d5987c1, 0xd3a2cbdd, 0x27ce6af7, 0x096ed285, 0x1af3777e,
- 0xbe20d04d, 0xc4f1e1e4, 0x8094e719, 0xafab1d9a, 0xc75fba74, 0x0bbf07bf,
- 0x23c6bfde, 0x1c4ba804, 0x3baecfa3, 0x188aecc7, 0xcfbc2a7b, 0x891e62ab,
- 0xeb4e5f99, 0x86421f74, 0x0aed3bfc, 0x76fce921, 0x6f7dfe85, 0x1e064e74,
- 0x65ee7a06, 0x1d80aef7, 0xe2be740f, 0x3afd849c, 0xccf18c93, 0xbf791db3,
- 0xbf93df41, 0xcdafbe6f, 0xc6de9f3c, 0x17f746ff, 0x8fa0ffb8, 0xcec4957b,
- 0x27d79bc7, 0xd75e9c7d, 0x99bdfe23, 0xe293c37e, 0x3eba7ddb, 0xd73fc18e,
- 0xafd13dd7, 0xebad7d37, 0xbeb77fc5, 0xd7d7fbd6, 0xb35c7d13, 0x8fc9ef1e,
- 0xeaf2f5d4, 0xdf8c16f5, 0xfafee14c, 0x9e2f1e14, 0x6ce2c499, 0xeedeb8b3,
- 0x0166dcfa, 0xb3282ebb, 0x6eff30fd, 0x36a1c627, 0xd0f662ef, 0x724e3c9b,
- 0x9c6220b7, 0x16b1eee4, 0x17d4dbd4, 0x4b7987ca, 0x808c8445, 0x2c01dcfd,
- 0x8528df4e, 0x6bef50ca, 0x6f738112, 0xefdfeaaf, 0xfd04dff1, 0x70f1fddf,
- 0xa3c62d4b, 0xc7e06d43, 0x7093cb8f, 0xaad92c5f, 0xb3bafc62, 0x03f78ad5,
- 0xd9f8ed75, 0xf9fa196e, 0x5ae0689c, 0x0d6ad4be, 0x1e814bef, 0x101e2699,
- 0xaba33f21, 0x59fde09b, 0x8a876793, 0x429b3fc1, 0x0e216ada, 0xf9615130,
- 0x3d3c66e8, 0xcc31f7ca, 0x7de114fb, 0x9f665689, 0x7644bb15, 0xfb4f580f,
- 0xe60acd12, 0x2fb6f757, 0xa0967851, 0x2fb3169d, 0xd2f4ccd1, 0x9897ddb7,
- 0xdf87b808, 0x9ff9d367, 0xc3d227eb, 0x8566c4fe, 0xbf7567ed, 0xbfb0132e,
- 0xb8b4b1c9, 0xf6dea371, 0x4aec7629, 0x1d3dc0f0, 0x4deff99b, 0xc035d8ec,
- 0xfcf6e6a3, 0x777b6e7e, 0xcda4a811, 0x984ad78d, 0xb9e3c6f7, 0x19a0b8e1,
- 0x66ff1caf, 0xc8156e7c, 0x07c4072a, 0xe0a9b45b, 0xbfb8f517, 0x71c1edd3,
- 0x5d478afa, 0x491f364e, 0x6f9f00f0, 0x03c0323e, 0xfc003fe3, 0xab59710a,
- 0x93f015fb, 0x9d3e1c77, 0x8abcfb80, 0xa4bf0547, 0xb1a6d93b, 0xef8c8973,
- 0x03c39983, 0x9abd0fb0, 0x84e6f9f3, 0x4c8ebfee, 0x61afde8b, 0x39fa33fb,
- 0x60855aff, 0xc2df883e, 0x78cc41f2, 0xeb66e41b, 0xebc4e6b5, 0xa69c89c3,
- 0x35f2f18a, 0x7f9662b5, 0x807e7e60, 0xf03977f3, 0x7147ed01, 0x8956b833,
- 0xaeff8465, 0xcef58128, 0xbfe5af5c, 0xc67b4387, 0x1cd565df, 0xed2a3396,
- 0x67d278e3, 0x40efc057, 0x3b96f96b, 0x2f70dc73, 0xf2ca5083, 0xb2f92c3c,
- 0xc493c846, 0xd6953a52, 0x0ecb922b, 0xb883f526, 0xe40d73b1, 0x479e4333,
- 0x2f445a5e, 0x0ad747dc, 0x2e245e5b, 0xbf12b0eb, 0x3d70ec1d, 0x79e79fcf,
- 0xfbebb52c, 0x3eecedd1, 0x86fe8aea, 0x850e4e73, 0xbfbf477e, 0x9a3deade,
- 0xa14cf984, 0x7dd29544, 0x78698ef9, 0x76e2907f, 0x3e477ce3, 0xf803293f,
- 0xd9f5c281, 0xff5c31ff, 0xc82e0f1b, 0x3a71816f, 0x062c8eb6, 0x087231fd,
- 0xd08b599c, 0x7c41aa87, 0xbc120f6e, 0x01fff12f, 0x512809c2, 0x00008000,
- 0x00088b1f, 0x00000000, 0x5bb5ff00, 0xd554740d, 0x79bfff9d, 0xbe4cdef3,
- 0x21264cdf, 0x012f0842, 0x1c424242, 0x61f08062, 0xc4443e1d, 0x602a0320,
- 0x43e196eb, 0x9a1af909, 0x7ab76eba, 0x2904930e, 0xb693db02, 0xb654e56e,
- 0x28bb560e, 0x82609d89, 0x04ec2681, 0x6eb50314, 0x5b604040, 0x6a445477,
- 0xbb8d3243, 0xb29eec54, 0xf7bdffff, 0x60c33325, 0x392dd9e9, 0xddf73739,
- 0x7ffdeefb, 0xf75ffefc, 0x595c003e, 0xc9a00392, 0xe7b73aa6, 0x001aa802,
- 0x6dbcdc64, 0xa0556052, 0x324e4018, 0x63240a6d, 0xd4da669b, 0x668a6d86,
- 0x9aa9e362, 0x70805ace, 0x6c14b2ce, 0xf2ce70b4, 0xc6efbc29, 0xc34b9656,
- 0xfdec32c1, 0x45f38a5d, 0xe1d90a9c, 0xfec49e0f, 0x39148ffb, 0x42ff63b7,
- 0xa4096a62, 0xe7f2ac01, 0x3fb08535, 0x1b1fe2d5, 0x69ceba44, 0x1a6d2c9e,
- 0xfe2dd7c0, 0x7be32089, 0x68529bc9, 0xf005c97d, 0xbab63b1d, 0x22948f06,
- 0xd5d02e7d, 0x60a300f1, 0x08a976b7, 0xeb82a900, 0x05f6f1e9, 0x58074c2b,
- 0x8eff1339, 0xf19217d8, 0x53d22679, 0x741b9fce, 0xb405fee0, 0x30cf41bf,
- 0x5dad901d, 0xeff6024a, 0x96eff63a, 0x8fb81851, 0xdf9313f7, 0xbf8b6122,
- 0xa2fd7fd4, 0xbfc3efc9, 0xdb9f6807, 0x792bb669, 0xc43674cd, 0xebf999f6,
- 0xeb119946, 0x3e7c1fc3, 0x65092f8d, 0x9015d59d, 0xf33efd8a, 0xd8ab2147,
- 0xf4677f07, 0xe327e67a, 0x45ce337b, 0x8175c73f, 0xd62d9fe8, 0x0cbf072d,
- 0xa1998f28, 0x61b379e8, 0x5c641fe7, 0xe8e5f677, 0x14b40be7, 0x3467e307,
- 0xf8cebe8c, 0xbd70aa43, 0x6f5f2b7a, 0x34bc9de8, 0xcd9bfd40, 0xbb945328,
- 0x8e50cbaa, 0x77fa75ed, 0x66fb4017, 0x700f979c, 0xb595b360, 0xeb6b4e53,
- 0xcdcefe88, 0xe0152008, 0xd62ce6d0, 0x98c69aaa, 0x561a729c, 0x3ec44943,
- 0x90c7df1a, 0x2e39d0e3, 0x82a1a9c7, 0x5f60e6e7, 0xafc055e9, 0x4b39f08f,
- 0xb80869c8, 0x9534879c, 0xf1fa79c9, 0xc411dd9f, 0x132c9647, 0x25fc11e8,
- 0x17a089e8, 0x0a93f48c, 0xd97d51ec, 0xd5cf8fd0, 0xdfeb8597, 0x714fd621,
- 0x075a8e8e, 0xa113f8fc, 0x85f643bf, 0x71f212bd, 0x05657247, 0x9e5693f1,
- 0xd96eb517, 0x427ab13b, 0xd3cbe1c1, 0x209fc890, 0xc69fa69e, 0x33f988f1,
- 0x00923e1c, 0xfa26ff94, 0x4cb34039, 0x62eb3476, 0x6f27f3f4, 0xc99bb7a6,
- 0x9b9e4a13, 0xe5ebf8e3, 0xcb457369, 0xb4517d33, 0xd1dc333c, 0x2ab51cf2,
- 0x79b76e5a, 0xa632e5a2, 0xf8d47272, 0x51a54dd8, 0x99df71fd, 0xd73f3515,
- 0x3faa2f37, 0xa8e2db7e, 0x979b13f9, 0xed27f547, 0xfcd47afa, 0xa8daff42,
- 0x55bda2f1, 0x29ffa4b7, 0x79a8fa81, 0x57d35e24, 0xcef6ffe8, 0xf3ed46ef,
- 0x2fffd6b7, 0x9c7ff463, 0xd234d97c, 0xf447fa17, 0xf24a838b, 0xd99f0936,
- 0x93f25690, 0xafb7aeb6, 0xbe976849, 0xe88fba79, 0x67062df0, 0x2b3d8e13,
- 0x6bf225bb, 0x26d45063, 0x4c5b1bf4, 0xfefe4950, 0x6ad326fb, 0x9d88f277,
- 0xb624d71f, 0x982af3fe, 0xf3d1ec13, 0xcc8f1796, 0x14d3da33, 0xf88da61f,
- 0xf45bafd9, 0x3df210a6, 0x147ee655, 0xf269ebfd, 0xa7a417af, 0x8a997214,
- 0x8a78a7c3, 0xed59bc59, 0x0e06d6c6, 0xb4db1ea9, 0x5faebf11, 0x505ce547,
- 0x98ff2ffd, 0x3b213fe8, 0xdffa465f, 0x86dc8125, 0x89bb56bf, 0xc361f3ec,
- 0x9a7ae96f, 0x21ae822d, 0x048fa5e4, 0xd0d3d66c, 0xfad0c3e7, 0x9dafccf1,
- 0x4805a6ff, 0xce55e7ff, 0xb2ff318f, 0x099f6bf0, 0xfe4fd6bf, 0xbc647f2c,
- 0x528fcf72, 0x7ce75c74, 0x440a2c01, 0xe42c29c8, 0x58d06604, 0x75cd99bc,
- 0x876aa176, 0xbfae18f2, 0x44d87df2, 0x13fcacfb, 0xef7c8a6c, 0xdec29acf,
- 0xb326b3fb, 0x59360576, 0x1815e728, 0xaca56ccb, 0x5db0941f, 0xe40a0bda,
- 0xe4f32c01, 0xf794242a, 0x03a679c0, 0xa292b4b7, 0xc107bdf1, 0x3fff90ad,
- 0x14dacdfb, 0xcebc379a, 0x4fdd4fdb, 0x8a815d38, 0x7dff61b6, 0x44c94f9b,
- 0x53be107f, 0xf711f162, 0xf773d2b1, 0xa69e6323, 0x3c167338, 0xbea0ce57,
- 0xad938396, 0x600bac67, 0x1733f28f, 0xe3a60854, 0x160bbe3a, 0x4748cbff,
- 0x4561b23d, 0x8f77d4fd, 0xb0647e62, 0x3fad8fea, 0xc7ab79c6, 0x9c52c684,
- 0xa7f550be, 0xc3f3d27c, 0x20afd0bb, 0x3d124b6f, 0x118cb619, 0xff5f9c39,
- 0x638d0a79, 0x867a65bc, 0xcbe7167d, 0xd8fb7e4c, 0x71bcc67b, 0x6da3b9b6,
- 0x5c72e724, 0xf88de664, 0xb00a5a33, 0xa9549f94, 0x177e9ffe, 0x0a1384e9,
- 0xcbc0cf5b, 0xfa978146, 0x24547d5c, 0x8653ea5e, 0xf08a32f1, 0xccb2ff52,
- 0x3bbea6ec, 0x97280fc1, 0xde770233, 0xfb5ed77d, 0x9e1d4eae, 0xb88c7cef,
- 0x9f2711d1, 0x8c746e20, 0x6e229f7b, 0xd90dffa8, 0xfde8953d, 0xa9c7e778,
- 0xc1f75a1e, 0x507ba35b, 0x06fd9f0a, 0xc738f7c9, 0x9d0c10fb, 0xbdba7e65,
- 0x1d21f750, 0x3b5c0ff3, 0x5d5cf94b, 0x60b745bb, 0x742d8aff, 0x7f9a79ec,
- 0x5f9a0250, 0x4e604c17, 0xf25daeab, 0x5578e027, 0x31d6db67, 0x596aafd8,
- 0xc3614656, 0xbbc10a9b, 0xe4bf7c68, 0x4bf1c46f, 0x1725839b, 0x87bae027,
- 0x75a25dae, 0x75f10e07, 0xe60e6f2f, 0xb0300e53, 0xb407cd7f, 0x05bb4d5e,
- 0xb1bf2812, 0xb431d505, 0xa0149b5f, 0x3f032afd, 0xcafd6950, 0xa04d9697,
- 0x6f7aa6f4, 0x1109c4cf, 0xc0e06b7e, 0x39475549, 0x60ffb655, 0xc65798a1,
- 0xe19f97c3, 0xa37fe0d7, 0x1cdf27bf, 0x6ff13fe9, 0xf093d91f, 0xf216bfbf,
- 0xbe35d55f, 0x7e89c489, 0x8979e3a5, 0x84d595f9, 0x5b870ba7, 0xda4bfb7f,
- 0x4ebfe0ef, 0xd940dc24, 0xdc1bc9ad, 0xeb17163e, 0xf9703ec4, 0x429dd53d,
- 0x452e53f2, 0xff3e73fb, 0x435dcd90, 0x2a9861fb, 0xc48444d8, 0xd0db87e4,
- 0x93e4801e, 0x43ecc89b, 0x6bab0e4e, 0xd1ef9e90, 0xacc7a404, 0xd8b5d585,
- 0xf31766df, 0x97feacf2, 0xafa46f73, 0xf26666c3, 0x2781e6b1, 0xed186fd2,
- 0x3a471a7e, 0xa67de68e, 0x4ebc7086, 0x6e12acbf, 0x53bf82eb, 0xdbdfa475,
- 0x5742e1f9, 0x3602f79c, 0x9314afee, 0xd94f72bb, 0x4bd47d88, 0xf089218d,
- 0xce92707e, 0x2f9b58f2, 0x48ebe8c4, 0xf98f89d0, 0x3d377e07, 0xefdeb114,
- 0x26131f11, 0x7eebf48c, 0x428961f1, 0xc3fd7b72, 0xc8ca7312, 0xe4cc81f3,
- 0x3a5c7f4a, 0x3a78bc78, 0xf6997dd5, 0xd1603dad, 0x13be191b, 0x77c2419c,
- 0x3d139257, 0x6d5be135, 0xf7c48b2c, 0xbaee8cc3, 0x4889d92e, 0x65ceba87,
- 0x3f36069e, 0x906a49c5, 0x08fae73b, 0x66e6b267, 0xc1ff8478, 0xa54710fd,
- 0xa3fa37f4, 0xcfcf3695, 0xe4e67f49, 0xbc48c4e0, 0x394299d5, 0xcfe9128d,
- 0xc2373cd3, 0x9f64e4fe, 0x7920e8de, 0x7d653ba6, 0x898a7f44, 0x0f4065eb,
- 0x8e29daa5, 0x50f5c66d, 0xdfc1031e, 0xb7fc92a5, 0x92b3ae76, 0xa6c77fdd,
- 0x55593d31, 0xff61ae9f, 0xbe47d4db, 0x4aeea9b7, 0x996dabb2, 0x0d764089,
- 0xef8676d9, 0x01d784bf, 0xbd5457b2, 0xb8a01e02, 0x36f0203a, 0xff981630,
- 0x708fdca5, 0x37be5326, 0xa3c8cc9e, 0x676f3cd1, 0x08c5c94f, 0xae0e077e,
- 0x4a7d1274, 0x321f7f22, 0xf7635e39, 0xc3814ffd, 0x9b6b4da7, 0xe1c446e7,
- 0x15bf79d8, 0x00e43478, 0xab165f66, 0x8cf13107, 0xdb3adf87, 0x1fe433bc,
- 0x0bbbb69f, 0x899b0fc8, 0xaea3c230, 0xe703a5c6, 0xcde907ff, 0xc85c7f98,
- 0x1a3c5555, 0x214df5c9, 0x33754557, 0xeb61a339, 0xfcc3c764, 0xed71a9e5,
- 0xdfc10bec, 0xbd68dcb6, 0x2abbcec7, 0xbe4c53f8, 0xe744b5ac, 0xcdd99961,
- 0xfa661ea0, 0x060de637, 0x77fd71af, 0x8bbf7e7d, 0x05773cec, 0xaf67e7c3,
- 0x11ca9614, 0xcdb38eeb, 0xffe22ffb, 0x8a0f0313, 0x0ee88b2f, 0xdeb1f0c5,
- 0xf892fee6, 0xc83bf236, 0x4e12dc76, 0x4e07d440, 0x3eb0ef11, 0xabe33028,
- 0x24e89083, 0xf226deff, 0x19b83360, 0xa9c0924e, 0x05d77ab3, 0xfc8d9abf,
- 0x6098f535, 0x9b53763b, 0x8139ca24, 0x9ccd608d, 0x228c9b2a, 0x52c565c2,
- 0x0c8c88af, 0xf6ed53c7, 0xbd20b77b, 0xf327c107, 0xfeba39ba, 0x92e49705,
- 0x37deeb22, 0xbdd7e2ab, 0x644d3dbb, 0xeea97fd7, 0xad34199d, 0xfafed351,
- 0x1d8277fa, 0x1822e8f3, 0xdb27a3ce, 0xa0544675, 0x102fe380, 0x7b33f44c,
- 0xf09f54c4, 0x1a7e4fdb, 0x922bf9e5, 0xa553ce29, 0x0dab0281, 0x78eec4a0,
- 0xda365b66, 0x3fce04d7, 0xefe89bf5, 0x0c679e5e, 0x4e6fd3d7, 0xfa277966,
- 0x93d59921, 0x4625a09a, 0x1f98656f, 0xd88d3a41, 0xe0f1eaa3, 0xc9532fb1,
- 0xf5dab6ef, 0x84bd277f, 0xf940cb8f, 0xa439825b, 0xd5d8e2da, 0x3163ca01,
- 0xcedc790f, 0x9dac6bcf, 0xfb8fcb92, 0x5017755b, 0xb4d04f7c, 0x7d8472a9,
- 0x3625d815, 0x85d8f6af, 0xc7f3151c, 0x5277a62b, 0x9afd718b, 0x74a9fd8e,
- 0xfe7d53ac, 0xed4a74d4, 0x0a9ecd8b, 0x4cfbce3b, 0xa56f93da, 0xbf9b70bc,
- 0x0813e484, 0xbc51a5e6, 0x9f06629d, 0x7a46f4b9, 0x594abbbc, 0xcbb75591,
- 0x5d29dace, 0xbca06c77, 0xfce41bd4, 0x0e0a1ed2, 0xeb027615, 0xd936740f,
- 0xbfef3d69, 0xff268f75, 0x56032fb4, 0xf578ff91, 0x7dfcc98b, 0xfe699833,
- 0xe04dbb1a, 0xf3a26fdc, 0xdce27da7, 0x130be06a, 0x3fec679b, 0xacae73a5,
- 0x838a0e21, 0x0fc847cd, 0x58597424, 0x12f0951e, 0x61747970, 0x38e7477e,
- 0x8a01ef87, 0x70368343, 0x9ade384a, 0x4f796618, 0xbfa2dbb8, 0x9adc9128,
- 0x55bcec81, 0x214af5e5, 0xf27f7202, 0xbf6373c8, 0xe8e7ae84, 0xe170898c,
- 0x6097b8a2, 0x933b866e, 0xc29de523, 0x73b46ee8, 0x0626b53c, 0x9794c94d,
- 0x9178044f, 0x274235d1, 0x3a0d7db0, 0x6f7f990b, 0x9e97c355, 0x34ba3074,
- 0x702141c2, 0x926ba13a, 0x412dfe4e, 0x123e3173, 0x93e9dd34, 0x5bcba46e,
- 0xda178982, 0x611bf7cd, 0xaec98ed8, 0x7d2389bd, 0x6b42da2b, 0xf835c71e,
- 0x20b33e16, 0x0e4fa23b, 0xfde47ca6, 0x3ef7ece7, 0x9d9b25b3, 0x5464f917,
- 0x29b61275, 0x6753e276, 0x74d7a27c, 0x39729465, 0x494e5138, 0x3c3e3e56,
- 0x4c9e711f, 0xcf3e64fd, 0x1692d169, 0x017b32e7, 0x2f2317b2, 0x5e0a5c7b,
- 0xb5ed0bba, 0xb4ee07ff, 0xdfabe462, 0x1689e474, 0x35fbf79c, 0xf620fc81,
- 0x179ea94f, 0xfc6f9f09, 0x298eed66, 0x155b6fe4, 0x9df90567, 0x2c87ef90,
- 0xd1557dff, 0x1dd847b7, 0x09338764, 0x78fbb1bf, 0x90fe37cf, 0x83c1dbf2,
- 0xc9d56e92, 0x887386ef, 0x4faebaee, 0xdee7f255, 0x7cb21f83, 0xe7ba6e76,
- 0xafea3b35, 0x3e61b3bc, 0x342675c9, 0x2ebf9137, 0x20417912, 0xa193fb8b,
- 0x362ff9d3, 0xb4e1e844, 0x7b0837b0, 0xea7c51c6, 0x987af612, 0x3b6c4eea,
- 0x4f1e1e7a, 0xba8877eb, 0x01af78d8, 0xb9218c8e, 0xac9bc237, 0x7e378e1d,
- 0x59c222f3, 0x6aeb59d1, 0x77fcc457, 0x7abf3ced, 0xbdf3ced7, 0x379ee9f5,
- 0x3dd53e49, 0xc4a9a91f, 0x0e40c5e7, 0xac0193d5, 0x7e38b58f, 0x637ed864,
- 0x0e6bc9ec, 0x7bdf34ab, 0x415f9819, 0x43496f7d, 0xdb3bedfd, 0x3e0d7939,
- 0xa49d40ef, 0x9e709e51, 0x8a1d87d7, 0x6fcd0c7b, 0x84b57338, 0x2201d8fc,
- 0xdab9e902, 0xe48e3d5d, 0x979ff886, 0x06d67648, 0x7619afcc, 0x8a764c5a,
- 0xfe1317ef, 0xc85fa8cb, 0xdaab72fc, 0x65d998b7, 0x2ec80987, 0x1eccff11,
- 0xc51aff10, 0xed0d62e3, 0x893fbd81, 0x9f6b79d9, 0x58f2c5c9, 0x5913ebf4,
- 0xd403de7f, 0xa05bed6f, 0x21373b31, 0x5ec94b9e, 0x3ad84783, 0xa4898001,
- 0x91dc093a, 0xf60503e7, 0xc337a654, 0xf6174e5f, 0xd3d0281b, 0x9247c89c,
- 0x47d9472c, 0x7de49c44, 0x3f5d4711, 0x9e67c7fa, 0xfb4f839d, 0x44d09c44,
- 0xfdc73c7c, 0xac45b7fe, 0xd66b7faa, 0xc7ca16d2, 0xf1b32d7f, 0x227ce2c3,
- 0x44727028, 0xdc504f9c, 0x6f3f51d0, 0x69d7738a, 0x1fa177d8, 0x34daee9d,
- 0xf2aa729f, 0xa947cd45, 0xcc0ee59d, 0xce7154a7, 0x0aa3beaa, 0xc222f337,
- 0x7b91fb5f, 0xf7e4cc8b, 0xaefaf3ce, 0x07f0cbfd, 0x9e1ca2af, 0x8ff28c38,
- 0x1d90a713, 0xafcc3f86, 0x8dd640c6, 0xe19283e3, 0x4bde7647, 0x97681c78,
- 0x4848fa47, 0xfa9b021d, 0x9fdbe919, 0x9fdf61f1, 0x474acaee, 0x78711e79,
- 0x9e51d2b2, 0xccbf2783, 0x38ecb324, 0x9bab11fd, 0x115755db, 0x0f3da7e1,
- 0x3838cd4b, 0x73f3a735, 0xf44b3294, 0xced18af9, 0x3071e74e, 0x243b07df,
- 0x9acb1756, 0x76e6ea9f, 0xfe62a5d9, 0x2b7c1973, 0x11bf9366, 0x828f81e7,
- 0x1fc2e7f8, 0xa263cfd4, 0x2be528fb, 0x7b1eb718, 0xaf398956, 0x3c2264db,
- 0xe092e86d, 0xe57bc827, 0x1771d8ee, 0xc46a5bcb, 0xf73b1b3a, 0xfa831b1c,
- 0x7a297aac, 0x2be50d5e, 0xc03c9cec, 0x169acfea, 0x499f3a25, 0x78cb7917,
- 0x0b794f18, 0x07f989e2, 0x16bd0cc5, 0x8745efc4, 0x6b4c90a7, 0x09cb899f,
- 0xcbb32afd, 0xb4bf9142, 0x28fee3ce, 0xccfc057c, 0x8e06f66e, 0xb3dd22a6,
- 0xb49d725a, 0x1f332cc7, 0xcb99d59f, 0xfd980ce2, 0x445432f2, 0x90b3cbb9,
- 0xd73ed3e5, 0x47942ce9, 0xa093f0a5, 0x8daef3f1, 0x914aaf82, 0x47f46dcf,
- 0xfc133dd3, 0x86cfb44d, 0xa83392bd, 0x1280f9d3, 0x8af3af37, 0x9d766a75,
- 0x7bc7463c, 0x79e881b5, 0x6f1f215e, 0xfdf3f467, 0xd58136c0, 0x347ce2e9,
- 0xf9d87207, 0xd5adef78, 0x7857bf53, 0xac4a717e, 0x166f8c63, 0xf243a9b8,
- 0x7e35bf48, 0xa9b84fd9, 0x3ca97c94, 0x35e485bf, 0x033af748, 0xa0fe3a2f,
- 0xf90bd63c, 0x617813ac, 0xb5fbe17c, 0xdd3f25bb, 0x19dfad2b, 0x81a3ff4d,
- 0x0f090b35, 0x6caab8b1, 0x5b7e5851, 0xca549b05, 0x5571636f, 0x66978c35,
- 0x2c58e295, 0xd23cea9e, 0x79e6e84d, 0xee95fff9, 0xcec8256a, 0x59ffaa7d,
- 0xfe88fa72, 0x74a96ff6, 0x7da378fe, 0x1956fd70, 0xfd7c1138, 0x6f3cfcb5,
- 0x4c327fe0, 0x945dfa66, 0x50758b7e, 0xa6dd3e74, 0x3218fb72, 0x0362f3f3,
- 0x2fefb13f, 0x3df8f914, 0x57b580bb, 0xa54f3f3a, 0xbec1dff3, 0xad6054a1,
- 0x3fc51169, 0xf0884fea, 0x79d2fb3b, 0xeb35b89d, 0xbe53efe3, 0xe29b4f7e,
- 0x6a0e4cc4, 0x8a6e2ac6, 0xdf6335d3, 0x11109cca, 0x79d2da57, 0xdb4f79fd,
- 0x74098da3, 0xe48af0ce, 0xec1bf324, 0xd423fbfa, 0xce48b5f7, 0xb1fef889,
- 0x6777a1be, 0x92b23e93, 0xde7ad3a6, 0x5a8bbbee, 0xc5ec7fb1, 0x75919c3b,
- 0xe73b31e5, 0x0ab19eef, 0xa3fd9b8b, 0x41567e93, 0x3dae80e7, 0x0ffb8ecc,
- 0x9d92aebd, 0x904ab60f, 0xcb1d1b85, 0x8f9afa3a, 0x27039cea, 0xe7c64a55,
- 0x43549fb7, 0x5c0f915f, 0xc82b72c1, 0x559b49ce, 0x1ddc6baa, 0xca21a89f,
- 0x90fa5e8f, 0x75553f9d, 0x548fcc4a, 0x3afd96ed, 0xfbb479fe, 0x5470950d,
- 0xa8c122d7, 0x8571c8dc, 0xa3bf938d, 0xdc2da7fe, 0x5cf81a7f, 0xe068f02b,
- 0x5aebc0d3, 0x6dd667e1, 0x63e3c68b, 0x1a3adae0, 0x65b47fdf, 0xcd794a8d,
- 0xfdf1cda3, 0x36afe18c, 0xfe88fd50, 0xe8aec37f, 0x71871b79, 0x387e63e8,
- 0x1bf59fd6, 0x42842c38, 0x7050e1c2, 0xe23338ed, 0xaac9eafe, 0x5ee71071,
- 0xb7111de4, 0x3379b88d, 0x7e740eb9, 0xf3bc52ae, 0x6eac2b66, 0xb7ff66f0,
- 0xab93891a, 0xbb0b2702, 0x53f4c0fe, 0x80b3d5d1, 0x9e025bf6, 0x92ef921a,
- 0xf28d24ae, 0xb7108ae0, 0x165dc5db, 0xfa225fbf, 0x2dce2c4c, 0xd216c081,
- 0x0b61e0ff, 0x243c773f, 0x84087cb1, 0xe420db1f, 0x77c841bd, 0x6359d603,
- 0xe62f294a, 0x82c6f475, 0xa528c73d, 0x6bcf13af, 0x254d1f8e, 0xee062f39,
- 0xb8071667, 0x65f4319f, 0xe31b89c4, 0xa49bf861, 0x0b2eeaef, 0xf708f7d0,
- 0x5f733f09, 0xe919fa0b, 0xbc1fbb46, 0xc5e1892d, 0x8de9c1d7, 0xed758b8d,
- 0x0e4df3d1, 0x890e5f9e, 0x11cf36bc, 0x308aafad, 0x7ae31524, 0xe9d9758b,
- 0x99f56f67, 0x12deff69, 0xf5d3dd89, 0x3cd3e3ea, 0x9c38f471, 0xdd7c8b57,
- 0xf3a52fe8, 0xd01f9c2d, 0xeb23939a, 0x9e0e9df1, 0x94cd577f, 0x88ff247d,
- 0x696965fa, 0x65fadc6e, 0xbfe703a6, 0xe76ebd9d, 0xc5fac8d4, 0x709f27b5,
- 0x1facbdf8, 0x7f929455, 0x64fee168, 0x4dd71ca0, 0x581c7ca3, 0xb16deb7e,
- 0xf0cea9f8, 0xef288e22, 0x427087ba, 0xdd25d9f6, 0xfcc1384d, 0xcd126eff,
- 0x437aba32, 0x627597fe, 0x97e5c63c, 0xc303f82d, 0x9c09f1dd, 0xa8db946f,
- 0x5180f578, 0xc17dd407, 0x79e34df3, 0xeac4399d, 0x892eba81, 0xc8fdb6e1,
- 0xa45c9cb5, 0x8ffbb077, 0xfdb06b39, 0xa38f0707, 0x1f02f3ed, 0x572077d1,
- 0xf371ad5b, 0x2dbf61ca, 0x5276616d, 0x593284a7, 0xf31071de, 0x3f5819bb,
- 0xd58cfa9c, 0x1247ed0f, 0xf6b9d356, 0x38cf5ac0, 0xd4f42bed, 0x3f2c8d00,
- 0xac2d846d, 0x3225fca5, 0xf1a0db9f, 0x131e4aef, 0x4ffa8ef1, 0xc31fae21,
- 0x8d2b5fb9, 0x5b7c17e7, 0xfa374b67, 0xd4afc303, 0x1757bc0a, 0x294ad9ef,
- 0x539e6c57, 0x3308ec2b, 0x62df1678, 0x0e9d9bf3, 0x9c08bf91, 0x644a9c36,
- 0x71e0eaf9, 0x5d33a359, 0x474feb94, 0x7986fe53, 0x739c5e7a, 0x2e04cfcc,
- 0x65fdc5fb, 0xe4ccb943, 0x5bc99a66, 0xf9421f23, 0x9e0cbc31, 0xbe53f64c,
- 0x8df8745f, 0xf57fd23c, 0x69179c5e, 0x0f3fa877, 0xcfc7aefb, 0x481b5c70,
- 0xc6327762, 0x6fc3bef8, 0x359c264c, 0x9f32fa9c, 0xbe5ae5eb, 0x7d39b8ea,
- 0xbc492b46, 0xbc49358e, 0x8730ed8e, 0xf27ea952, 0xfedd941e, 0x7a1a7d08,
- 0x476117fe, 0xfaf5e660, 0xface871e, 0x171c5d0d, 0xe2de6ea6, 0x79f82bfe,
- 0xbff6c28d, 0xe21e7c61, 0x1ae22be5, 0x7ba85d10, 0xb86612af, 0x31349ef3,
- 0x8727bc7a, 0xbbe32332, 0x451dd68f, 0x06a1af7e, 0x02491f98, 0xc7e8b3f2,
- 0xdef7547c, 0xe5812e77, 0x76f2c74b, 0x95bf3054, 0xadf90327, 0x4d554e27,
- 0xf90f8c8a, 0x27e7990e, 0xca2c8724, 0xfbe59e56, 0xc234390b, 0x73ef5172,
- 0xce92bf1c, 0x527580e5, 0x6c71d937, 0xf9ab749d, 0x05b7436e, 0x7bd81ce8,
- 0x13bec2c1, 0x81bddab9, 0x85f0e1d5, 0x19f91267, 0xa76e78f0, 0x1bc389f6,
- 0xabf3d126, 0xcede3787, 0xc6a52fce, 0x23e5f8a8, 0x2f28b2fa, 0xe3a9933a,
- 0x99f76d78, 0xc2ad604c, 0x647ea7e8, 0xc1d77afc, 0x4f60d7e3, 0x90a73b02,
- 0x00e38f20, 0x5bad4426, 0xcb16fed3, 0x653a6a23, 0x8c1e2457, 0xf0703ef7,
- 0xc223eafc, 0x9013f101, 0x6dcf4c5c, 0x7ce9adbc, 0xad53d19d, 0x1b1e9804,
- 0xde3e145a, 0x2fcc5bca, 0xb03e1d19, 0x36fe88fb, 0xf7e6bf3a, 0x02bcec1a,
- 0x18fb3267, 0x6ff4282a, 0xe8affec7, 0xc875ca11, 0xdcfe026f, 0x9b83eec2,
- 0x11a7c77a, 0x5f7a87ee, 0x178bc477, 0x083dd0ef, 0x97227a92, 0xe3b117d7,
- 0x39f8327b, 0xdcf389c2, 0xeb989d8f, 0x9fcf1499, 0xaf1e60f9, 0xef2125b7,
- 0xbc516576, 0x3217b4fb, 0xdecf39f8, 0xe209df6c, 0x812dbfa7, 0xdbf5a7dd,
- 0xfce8b9f8, 0xe9cdc7fd, 0xa5db7714, 0xaa3f1469, 0x405fde0b, 0x2fd8f8f7,
- 0x782b7e63, 0xd61bdd90, 0x742db4b6, 0x2ea3a1c5, 0xc5f1fb83, 0xc8fbfc6a,
- 0x7bf8c5db, 0xf510cce0, 0xee130ed1, 0xa2855ef7, 0x8679676d, 0xf436f92b,
- 0xff0bf7bf, 0x8512c0fb, 0x81ef25e5, 0x077bf0ae, 0x54b03f7e, 0x85fbd1f8,
- 0x1e5a5e5f, 0xed9727ed, 0x7ee9a786, 0xbe2b9960, 0xac487e1f, 0x6c5c1cbf,
- 0x451607dd, 0xe4487bcf, 0xa3b90f77, 0x10ca4f9f, 0xf21f37fe, 0x3006ffc9,
- 0xebbe901e, 0x5c58130b, 0xc4ca6fbd, 0xb1c179b8, 0xfdeec0cd, 0xbffdc57b,
- 0xc286f7a1, 0x3abc59f7, 0x35fe73d1, 0x09dbf31b, 0x5ee71790, 0x195e246b,
- 0xd720fef6, 0xa82fb8b7, 0x868d38d5, 0xe560afde, 0x652e7913, 0x90b17de8,
- 0x04def57f, 0xaf9ef22d, 0xea8b6036, 0xd36f3b7b, 0xf9f8462e, 0xf46f816a,
- 0x73c8e6fd, 0x67b29d8a, 0x0bdd0671, 0x3e59fb58, 0xb8b01c8d, 0x08e57c85,
- 0x112c72be, 0x6dcae8f1, 0x77e2e26b, 0x8fbb3f84, 0x6b077dfb, 0xcc2d0a7b,
- 0x92036aee, 0x6aa3ee9f, 0xac9ebc83, 0xc9ebc05d, 0x579e76fc, 0xf25078ae,
- 0xbee624bb, 0x067d134e, 0x795a967e, 0x327036fc, 0x1f812f2c, 0x7e78a71a,
- 0xb1e788bf, 0x7d049a38, 0x779ce90b, 0xd2724ba5, 0x78b171f7, 0xea6abe5a,
- 0x6f9ee45b, 0x9bc41f86, 0x16327e42, 0xf0cf3f47, 0x1a632b7c, 0x4c570bab,
- 0x144f75c1, 0xb8439a7e, 0xdd89bba9, 0xdb7a14ec, 0x413bec9b, 0xbf66bef1,
- 0x5fdf07b8, 0x792219d8, 0xf7cb02f4, 0x5b7d6dfa, 0xcc1e79eb, 0x836bc1ee,
- 0xdefa4e09, 0xc92bb6b5, 0xf6fd4099, 0x54c9c486, 0xcec9761f, 0xb457ec24,
- 0xf2405c9f, 0xdfe328ac, 0x61a9d465, 0xb4ae6f96, 0x5e92b679, 0xa27b3897,
- 0x3a0dbfee, 0x58f3866f, 0x0902f6bf, 0xe76fe327, 0xe0c85e6f, 0xf8feaef1,
- 0x719399e7, 0xcf36e9ab, 0xf07ba26e, 0xba5557ad, 0x7e4ef326, 0x4eba6163,
- 0x6f3674f3, 0x16cf4b49, 0xe8357e3a, 0xee343b0f, 0x367f155f, 0x6f8b23cb,
- 0x86907bed, 0x50976f83, 0x73d03cde, 0xc08d44bc, 0xfa3d7f77, 0x6bfa38e7,
- 0x5bb09300, 0x69256b33, 0xb86fc8b9, 0x8fbb7b1d, 0x41b9d266, 0x316fd93f,
- 0x295267b5, 0xbdb6d62e, 0xf2913a97, 0x1ade0e8c, 0x92e95deb, 0x87303cd9,
- 0x894a1ff2, 0x4669efa4, 0x5f0095df, 0xff942007, 0xf1c894c0, 0xfb6fffa6,
- 0xae38413f, 0xeca286b5, 0x561390df, 0x47563eed, 0x7bb0b61e, 0x8927ba75,
- 0x92ea9efc, 0x2c0cf5c0, 0x674ec86e, 0x78f0bdd2, 0xf0ccc54a, 0x10cdf508,
- 0x9ee9db34, 0xeff32836, 0xff99b2cc, 0x9ff62e9e, 0xd0f60e61, 0xc53396f7,
- 0xe82ce2bd, 0x06bef363, 0x40bad661, 0x0f3b5333, 0xb72dac9c, 0x32a3ef06,
- 0x901038af, 0x4cc1ff49, 0x9592edb3, 0xf1007f7d, 0x37223df4, 0xe4325c33,
- 0x13fdd321, 0x962f5eff, 0x8f02eb9f, 0xefdc5c33, 0xdf412a50, 0x80439659,
- 0x09df77dd, 0x1def7121, 0x58d98f9f, 0xd77dd1a7, 0x893b689d, 0x367e1e4c,
- 0x23f10e7f, 0x7427e3c7, 0x2c33531f, 0x293e88d0, 0x9eba6998, 0x0c7ceb74,
- 0x375b0266, 0xe0785d75, 0xfb91b2c9, 0xdbd76742, 0x50bbe8e7, 0xdf62e5c9,
- 0xc9ad3a8d, 0x04975641, 0x7ec3fdcd, 0x39200f2c, 0x66626d73, 0xf777c8c6,
- 0x3df601e0, 0xf777ec45, 0xcce5eec4, 0x8cb4ef91, 0xfaf73fef, 0xc426eb97,
- 0xd5872ac7, 0x4a3e2329, 0xd07739ad, 0xcd39e0f9, 0x8d399893, 0x996d03be,
- 0xfb3116c8, 0x53bcb1a7, 0x5c092ae0, 0xe4bfc4e5, 0x07fbbe32, 0x389f1786,
- 0x8265f6bf, 0x9252ae9f, 0x91587c30, 0x43881dae, 0x5fa19dab, 0xe159efa7,
- 0xe53af9a9, 0x566d5bb7, 0x166fe527, 0x846937a2, 0xff2b26de, 0x7ef8c1ee,
- 0x4d8e562b, 0x663e8328, 0xcb2b4e7f, 0x628fd78b, 0x6b8f34f7, 0xb27fbf9c,
- 0xfd10a678, 0x1bcca78f, 0xd16ef945, 0xb164e62f, 0x30e51bfc, 0xe98390c7,
- 0x80e7ffc6, 0x3c91977c, 0x817fff63, 0x802a2fc1, 0x72134681, 0x48d7f834,
- 0x5c6f143f, 0xbf431fa8, 0xd9722379, 0x57f9c891, 0xf18f4be8, 0xec9d5dec,
- 0x836f9634, 0xcf05ffbf, 0x10785073, 0x00107850
+ 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c0b, 0x733ef7b5, 0x9993331e,
+ 0x420f264c, 0x084f0042, 0x21842a20, 0x38880840, 0x8d069009, 0x8808089a,
+ 0x420100ca, 0xa9113248, 0x676d5e97, 0x6ad11422, 0xa36d2d1b, 0x4101da97,
+ 0x180d45a3, 0x1d0340e8, 0x5abc414c, 0x5b4a0a8d, 0x3c3141b5, 0xe878490a,
+ 0xef5bd6c5, 0x33ef6b5e, 0x42667399, 0xfddfb6a2, 0x7f17dfbe, 0xecfb36fe,
+ 0x7b5ef673, 0x7b5affad, 0x231fb5ed, 0xd313c659, 0x057c8415, 0x7213d77f,
+ 0xf4842448, 0x0b3b4eeb, 0x108e3a68, 0xb0398e7f, 0xb4242055, 0x24edefef,
+ 0x4db39085, 0x267355b3, 0x98c7fb21, 0xf2d3d743, 0x80fc81b3, 0xdd4f9699,
+ 0xd121c479, 0x514ed57c, 0x3ed37282, 0xb1df7e2b, 0xde400851, 0xf1fd6e6b,
+ 0xb5df34b5, 0x699b2453, 0x376424d5, 0xda425491, 0xa9fd842d, 0x6a5f98f1,
+ 0x4daad965, 0xf682effb, 0x626683ca, 0x37b7dfa5, 0xafc86e89, 0x08042adc,
+ 0xf76aaf6d, 0x5a00ca83, 0xd080b2df, 0x7e695568, 0x1a8a63eb, 0xfb03c84f,
+ 0xb368ecfe, 0x67da7213, 0xfd82aa21, 0x491c6f28, 0x7b604548, 0x7dfa00e1,
+ 0x65c136c5, 0x6c57f5a2, 0xf401d73c, 0xc3c93455, 0x8adf5a44, 0x47511b06,
+ 0x22bfb6b0, 0x07cb5ed0, 0x794eded8, 0xfe57b428, 0x110a3de5, 0x1bb29fa1,
+ 0x74a2abbe, 0x76b5bf40, 0xb1eafb4f, 0x559f8d3d, 0xe8f6d1cf, 0x0a2fd57b,
+ 0xb562e82e, 0x8e807889, 0xb9d6dd8e, 0x7fa1db4f, 0xf8f0cab5, 0xdc2c7ec8,
+ 0x08a8fd05, 0xed0a526c, 0x6526df40, 0xfaeec8e9, 0x87fc3456, 0xacfabe9e,
+ 0x72889efe, 0x47da7a63, 0x3bbc3a59, 0xbb88415f, 0xa44bd691, 0xaa3a5280,
+ 0x4207f9fb, 0xa1e32122, 0x96a8917e, 0xe4a9faee, 0x23fe0711, 0x0f949ff4,
+ 0x81f1bdfe, 0x72dd99ad, 0x9904e95b, 0xbcedcb75, 0xea51cb93, 0x5fac8dca,
+ 0xf20c7f4b, 0xf9d4f4a0, 0xee3e989c, 0x8374c34b, 0xfdbe454f, 0xd30237dc,
+ 0x9f0b9f7a, 0xc3cbe93f, 0x8dcfa374, 0x22be53e9, 0x12be034c, 0x6fb36f7c,
+ 0x7c5ba62e, 0x8cfe7c1e, 0x06d31caf, 0x7f3e0d5f, 0xd31ab7de, 0x3e3f3e6d,
+ 0x1eb7d17f, 0x1d5f46d3, 0x5e403ba6, 0x05f26d34, 0xbe5dbdf0, 0xbe834c06,
+ 0xc7be7c46, 0x11f4c417, 0x64c747ce, 0x3e512f92, 0x49c4dc38, 0x8a924ec5,
+ 0xcd32f9dd, 0x7cb09527, 0x7cfe1dea, 0x3d53e685, 0x32f94f34, 0x6f9432a0,
+ 0x3501f9a6, 0xfdf07cac, 0xf342c0a4, 0x7cacfd83, 0x02ee23c8, 0xa90fcd2b,
+ 0x37c3e563, 0x68e20bfa, 0x9580787e, 0x542dbd5f, 0xabf9a360, 0x7679591b,
+ 0xa76a9933, 0xcb10ecf9, 0x9ee1bce7, 0x39f34f1a, 0xfb9f2cad, 0x83aa7f81,
+ 0xd8db73e6, 0x04ce93f7, 0x2d1ed544, 0xbab21d87, 0x6d595098, 0x4b70cff4,
+ 0x515e6913, 0xca2e21ef, 0x6eadff1f, 0x43f29d29, 0xc8796376, 0x9bcb1f3f,
+ 0xbf963714, 0xfcc32fe3, 0xe583d92e, 0x2c55fdc7, 0xfcb078af, 0x98bdff73,
+ 0x2c7eca0f, 0x58fad4b7, 0xf963f15e, 0x58f5da80, 0x80391eff, 0x1f6b23e5,
+ 0x4a3df2c3, 0x5f1fcb00, 0x1a7ba4fb, 0x3c11afcd, 0xd23c073f, 0x01649cb4,
+ 0x4ad31a9e, 0x09d69e28, 0xf7e02e64, 0x8a3a0007, 0x0ae975cb, 0x3f8ee1ea,
+ 0xfa0d3ee4, 0x90297f8b, 0xc3ccfa5f, 0xaffdf899, 0xd6991eb0, 0x4f5ef623,
+ 0xba799bce, 0x2cde727a, 0x8069ead7, 0xfb58d6f7, 0x378ecf56, 0x79e9e927,
+ 0x67ab42b3, 0xdf13d23b, 0xbce57eb7, 0xcf4f5935, 0x3d5a955b, 0xc49e907b,
+ 0x74d3d1be, 0xa69fcf44, 0xb4fe6123, 0xfafd3d20, 0xf7b8cf46, 0xf719fcf4,
+ 0x6f3f985e, 0x7de93d60, 0x3de9a7ab, 0xde9a7f3d, 0x08e7f30b, 0xdf506bf6,
+ 0x7dee35fa, 0xbdc67f3d, 0x47cfe61f, 0xdf664f48, 0xa1f5d9ea, 0x3ebb3f9e,
+ 0x04e7f30c, 0x6fac33d6, 0x48fdcafd, 0x8fdc9fcf, 0xc2e9fcc2, 0x5beaae7a,
+ 0xd23ebb3d, 0x47d767f3, 0x817cfe61, 0x5bea8cf5, 0xa2ff72bf, 0x5fee4fe7,
+ 0x0931fcc2, 0xbe98cf50, 0x54fc13d1, 0xa7e09fcf, 0xb0d8fe61, 0xa37df19e,
+ 0xcf5daf27, 0x30f6bc9f, 0x9004527f, 0xd5bec4fb, 0xf3d76c13, 0xe61ed827,
+ 0xe7ac20cf, 0x2bf5beba, 0x3f9e84ef, 0xfcc22779, 0xcafd8e19, 0xf40f7aa7,
+ 0x7c4f5a10, 0x39ecf5cf, 0x9ecfe7ab, 0x8cfe61b3, 0xd3a67ac6, 0xaf7ab27a,
+ 0x9e875267, 0xc23a933f, 0x7ac3c9fc, 0x9eadf466, 0xfe7a1d3d, 0xf308e9ec,
+ 0x73f91f27, 0x35fadf53, 0x9fcf53a9, 0x3f8c9d49, 0x4cd70f63, 0x3a72d075,
+ 0xfa44ba16, 0xdc67b5c9, 0x45e6816e, 0x4e8bcb27, 0x44bf0117, 0xd20dfcd4,
+ 0xf7e916ea, 0x39896df6, 0xbf48930f, 0xfa14a0a3, 0xb1bd4f15, 0x2123bf48,
+ 0xe7e74e2f, 0x7493ba24, 0x01a2e4f9, 0x95fbf7ba, 0xf795d10c, 0xaeb57b9f,
+ 0xa393dd3c, 0x4f9467cb, 0xa83fbdd2, 0xbf9740a6, 0xba0df562, 0xb7fd33f7,
+ 0xeb59f2ea, 0x3fbdd76f, 0xae916eac, 0x0afacafc, 0x8155f95d, 0x35fcba95,
+ 0x7baeff0d, 0x03e3547f, 0xc1d1f2ba, 0x63e57587, 0xf2eb8f42, 0xa93d0f63,
+ 0xeb7c7f7b, 0x84f95d66, 0xcaebcfa3, 0xd0edb627, 0xb93dafe5, 0xd9e7e0c7,
+ 0xf0d7ed9d, 0x27b808bc, 0x574fefcc, 0xc50bdfd0, 0x0657982b, 0xdf8fd1d8,
+ 0x3d54bf1f, 0xbcabe54e, 0xa14d58b2, 0x129905f2, 0x0fe7ae3a, 0x8db2bf28,
+ 0x9277bf3e, 0x7d274ae7, 0x19e2af7e, 0x9fe18ced, 0x24083c52, 0x04d5520d,
+ 0x41fcb1a9, 0x20b1e199, 0xc7e1cbe3, 0x535ef7e8, 0x9a44f0d7, 0xd7e62fef,
+ 0x129e5e03, 0x38d3884c, 0x7bc0d491, 0xf3826671, 0x73330782, 0xe047f69f,
+ 0xaa20fd75, 0xbd774287, 0x1a4f65eb, 0x6b9b19f8, 0x1f83f6df, 0xed106eb2,
+ 0x9e4200d7, 0xf90ede16, 0x07efd287, 0xd0f34d2d, 0xf50accfa, 0x57db23d3,
+ 0xb123fb68, 0xff6806fd, 0x37da1ec5, 0xb5d3c90f, 0xae5c196f, 0xd0a2df6b,
+ 0x1fd49df6, 0x6f23fda8, 0x12610a9f, 0x7f0b2f21, 0x83cdf6c4, 0x07fdb1cb,
+ 0x895f3a15, 0xdc2e3f6c, 0x77f4107e, 0x3e3fb41f, 0x4c87ff46, 0x707ff7d2,
+ 0x0affbe85, 0xb52bffeb, 0x71fb78c7, 0xe116ffd8, 0xe0ffeb18, 0x337fd60a,
+ 0xbedc37ab, 0x43ffcc23, 0x7b37ffd0, 0x64d67fea, 0xa8afff7d, 0xccdff7d4,
+ 0xf6a77fda, 0x8edf6f14, 0x9c2bbfed, 0xa2bffd62, 0xcc57db12, 0x47e0171e,
+ 0x09ab88c9, 0x40c9f6d0, 0x03fa986a, 0x903b685c, 0xa0a2488e, 0x6151e426,
+ 0x6f71d208, 0xe7dbc31c, 0x686f1471, 0x9cf8fc6f, 0xcb65a804, 0x8e2ef3a5,
+ 0xf2db15f5, 0x584bb015, 0x4b2be74e, 0x4165a938, 0x364df111, 0x28c30398,
+ 0xd1411dbd, 0x0db2f90f, 0xfec005d7, 0x4164cd79, 0x91277c09, 0xf4ff3c10,
+ 0x4736a367, 0x2e98cbf6, 0xdbdb93a9, 0x3c2df422, 0x23202a8f, 0xd37d286a,
+ 0xbbe30401, 0x79d31ff3, 0x8bf3a110, 0x833ce80f, 0x227e4850, 0xa23ef6b3,
+ 0xb7c825f3, 0x9412f9d1, 0xdf8b5213, 0xa70eead1, 0x384bfa51, 0x4c4b1ffd,
+ 0x43be3f5f, 0x7ea9f808, 0x31bdfe7e, 0xb05d4f38, 0xde9946da, 0x7f42c74d,
+ 0xfb4f2eb2, 0x753907e5, 0x360736ed, 0x155fc80b, 0xaa8a55f8, 0xf5e2c849,
+ 0xddd79419, 0xc54fbfef, 0x7f594e9e, 0xfdcb711b, 0xae77fbe9, 0x69390612,
+ 0xe6ddb3bb, 0xb84e361c, 0xd7a84c33, 0x4794c324, 0x634dadc8, 0x29035a64,
+ 0xb71fcb75, 0xb33bb445, 0x5d9f9f48, 0xc877cfa2, 0xe944d96e, 0xc81528ea,
+ 0x9cef5a26, 0xad72fab9, 0x8929bb1d, 0x57b799c9, 0x9be8ca92, 0x3c0e6903,
+ 0xe79ca276, 0x1ab7d93a, 0x32c5de3d, 0x3c82c29d, 0xc808fdfd, 0xef829fd5,
+ 0xfd64eedd, 0x573bd236, 0x684bb8b6, 0x142ee73f, 0x236f8003, 0x67da7ffd,
+ 0x69b29b73, 0x32a7feba, 0xc7f74531, 0x8f3cff48, 0x328d3fb1, 0xcbf3c38c,
+ 0x6e19cf8d, 0x3ffcb9da, 0xf4d07c06, 0xd283e004, 0xa3e39c7f, 0x7c32aedb,
+ 0x9b9ecd78, 0x4f5d0f01, 0xcae50488, 0xc71b72f1, 0x3d3a92cb, 0xc8f1082e,
+ 0x7365c720, 0x23879c85, 0xe3873070, 0x1ebd5960, 0xbf127737, 0x2e431e9c,
+ 0xfa6c36f3, 0xdd1a9a61, 0x6e390fbf, 0x1fb23fe6, 0x4fdd13f9, 0xb8bba726,
+ 0xd1acee9c, 0xe5c6df97, 0xeb97277a, 0x0ec7fadc, 0x6e41f350, 0xe8320357,
+ 0x4d3ef7bb, 0x793a6d9e, 0x8d3cb87a, 0xe5c5de74, 0x98f7d779, 0xb6f48d3c,
+ 0xd5b67971, 0x90c9905f, 0xf48d7a68, 0xd51d582d, 0xb9e4051f, 0x9e5b1fd0,
+ 0xf27e60de, 0x55e788f1, 0x8f92338d, 0x8ad9e847, 0x7e5d5286, 0xee9e6079,
+ 0x0bf565fd, 0xea4be575, 0x17caeb96, 0x975bbfaf, 0x9effe85f, 0xab05fdee,
+ 0x77e5756b, 0x2ba43cd6, 0x98fe5f9f, 0xf3cf3f2e, 0x39fdee84, 0xcae93773,
+ 0xa73c9767, 0xb4599f2b, 0x752f975d, 0x6fbdd6ef, 0x2dd577da, 0x8e37cf80,
+ 0x89fc0488, 0x30275ccf, 0x4b99f82e, 0xc73bc176, 0xbae22a7d, 0xd30237dd,
+ 0xe2173e93, 0x0f2fb4fe, 0x8b608ed3, 0x3a09c61d, 0x89252e2e, 0x6e9bccd4,
+ 0x103f5dae, 0xe38269c6, 0xacd316e9, 0x4264ff5a, 0x91526d7e, 0x0af5c5df,
+ 0x44258d09, 0xd386c180, 0x944625d1, 0x5e52f5b7, 0x727f0d4f, 0x5b717974,
+ 0xc7dee7ec, 0x8ce15e17, 0xd6e97711, 0x7e019253, 0xbbf7274f, 0x0295e58d,
+ 0x4e7c8929, 0xd7a803c8, 0x5bb8f8e7, 0xaffd30a9, 0x405e91dc, 0x0d0f901c,
+ 0x7b5cb9af, 0xfde4148d, 0x3a592701, 0x7f565e3d, 0x13bece8d, 0x03f6ca88,
+ 0x3dd58dbc, 0xad70d15f, 0xfb33bbee, 0x1abba445, 0x1844c56c, 0x375e4b16,
+ 0xb50e1d81, 0x0a399e0c, 0x61bf74e8, 0xd82a7182, 0x33c2fd0f, 0xe3e4a2be,
+ 0x04afc812, 0xb9be93d3, 0x3cfbb698, 0x95f71e98, 0xafb1fa63, 0xdf36d306,
+ 0xf23f4c6a, 0xc0fd31f9, 0x3fd31eb7, 0x3d30eaf9, 0xf4c7abea, 0xd3005f3d,
+ 0x4c06bec3, 0x6235f1df, 0x620beada, 0x6373e1da, 0x6f5de9aa, 0xc7c93bb8,
+ 0xbf80d3e1, 0x78eb3818, 0xfaed5560, 0x3b38ddc9, 0xd6afba6f, 0xcf9bb03f,
+ 0x8e66f5c5, 0x1e1d5487, 0x336080be, 0xf297ace2, 0xb0e3997a, 0x9763efa7,
+ 0x6bff377b, 0xc4de36f0, 0x8a6fccfc, 0x653c6eb7, 0xd594f018, 0x89fa9e1b,
+ 0x34f1bbe3, 0x7e64e4de, 0x8fd3c70f, 0xe6311fa0, 0x84e00515, 0xd7f08bf4,
+ 0xa71636dc, 0xd409ebe6, 0x6a716553, 0xfa1af6de, 0x75fa2b6e, 0x6e301181,
+ 0xb7f11f9c, 0x3f8710e1, 0x274cd47f, 0xcff73d7d, 0xf99e9388, 0xcdf9c6ee,
+ 0xbc1d00d2, 0x5b9746c6, 0xad5f18e3, 0xe8445226, 0xb0d0f6b8, 0x468b5c67,
+ 0x49225e62, 0x55c07df0, 0x5ea31f1a, 0x7f032bea, 0x9aebe37b, 0xa1b3cff8,
+ 0xff27f6be, 0x78e90b9e, 0xe397f313, 0xdbf4445a, 0x1769e849, 0x2e3c37f0,
+ 0x10695d99, 0xa61aeedf, 0x086fd138, 0xf3fcf5d8, 0x376e7cd3, 0x3ca21eff,
+ 0xb771c56a, 0x37f90d2e, 0xe9e1f3f4, 0x6f5fe07d, 0x7e37bdf6, 0xf80c0a2e,
+ 0x37b3f097, 0x5d9bd8fb, 0xc5f56e24, 0xe77fed20, 0x0f3951be, 0x870760ab,
+ 0x0f5a79b0, 0xa5d6d6fc, 0xff7cf48c, 0x33b8e26b, 0xeb71c355, 0xf9db4260,
+ 0xf9cbeb88, 0x40132ba6, 0x9c1eb42e, 0xe4ed741f, 0x722f7e7e, 0xafa99b3d,
+ 0x2fac6bcf, 0x68c22141, 0xa2bc6eda, 0x6a420490, 0x22a3cf44, 0x6d5c6fce,
+ 0xec1b887e, 0xa8d6b9b3, 0xfd3c6f30, 0x1a854866, 0xf385f1f5, 0xc0769e87,
+ 0x9a656c3c, 0x863c79c9, 0xaab4b51c, 0x8f69d331, 0xf504af9c, 0x4275f3f9,
+ 0xe7ce2351, 0xa35984d4, 0x3a719c60, 0xbb050f8f, 0x56a9869f, 0xc534cacf,
+ 0xddda9c79, 0x09590dd3, 0x6017fe6c, 0x225b64f6, 0x3ed39bda, 0xcfffbe0b,
+ 0x7aa7a7a6, 0x69087a34, 0xc0589f22, 0xacb2d39e, 0x51efdf9e, 0x0a8ba41f,
+ 0xb34937c4, 0x37cc39fc, 0xaffff4ad, 0x12bd4086, 0xbd7ab5e6, 0x3cdfa28d,
+ 0xd36f9e1a, 0x53bf47b5, 0xf857b5b5, 0x93bd67ae, 0x7b86bb48, 0xf957bf2a,
+ 0x068af0fa, 0xc7ef53ab, 0xdef2ea26, 0xe753ba60, 0xc03fc2d7, 0x2411af71,
+ 0x87255fc0, 0x5f64a75f, 0x0cda780f, 0xbf9843c1, 0x2abdec08, 0x51e29b4b,
+ 0x015a5d51, 0x34f28b9f, 0xfe73abfc, 0xa9d4ed4c, 0x7a0265d7, 0x54a4be46,
+ 0x20a9f2e5, 0x4c44cde2, 0xbf98bf34, 0x4569a8bd, 0xa75b8c31, 0x50fe6c4c,
+ 0x301c4a46, 0x75272e3f, 0x3d4f10b9, 0xa0454c4b, 0x3bc9679f, 0xfa11b18e,
+ 0xb0544e78, 0xf5ebc5d2, 0xdf9d3c7e, 0xeacbf2eb, 0xe4a5f9f5, 0x075854d6,
+ 0x2641ba5f, 0x86ec0101, 0xe898fcbe, 0x91977ac4, 0x6e30759a, 0xbbc79cff,
+ 0x94893916, 0xfaabe941, 0x17732fcd, 0x892e3a52, 0xd6d5fc6c, 0x31279771,
+ 0x05662bfa, 0xff7d3714, 0xb7b1a693, 0xbf440b51, 0x7583ac0f, 0x71297f6d,
+ 0xf2d1256d, 0x1bf4bafb, 0x81fcd5e9, 0x4e64f5a8, 0xe0834a47, 0x63b0c40e,
+ 0x3d30248a, 0x6aeef6e3, 0x838ba9c9, 0x223e42e4, 0xf18df20e, 0x78744294,
+ 0x067a2cda, 0x7e19e34b, 0xd4820f00, 0x4dbe78a5, 0xf55169fd, 0xfbf52d5f,
+ 0x903fd627, 0xabab9fd6, 0x4a9ff73f, 0xfa28d0ff, 0x5fd5620b, 0x76179bf5,
+ 0xa93da9f9, 0x0e67e978, 0x53c9c742, 0x8baa5d52, 0xeb72b5ca, 0x9a6e1d0f,
+ 0x0efc949e, 0x80a9ebc0, 0xde4b1458, 0x76f2c3ab, 0xbb8805db, 0xfd693fc1,
+ 0x11ff9fa7, 0xdf3e23c6, 0x9e313b2a, 0x990e60d6, 0x37563ea9, 0xd9262f2d,
+ 0xf2c63f98, 0x21139e0f, 0xafe3d41f, 0xa59fd9e2, 0x8a0afec2, 0x0a5f1e14,
+ 0xbd5b3fa1, 0x1c42d3e5, 0xea17489f, 0x683bf191, 0xda1252ff, 0x424a85bf,
+ 0x13a53974, 0xce5e04e3, 0x8fd36f17, 0xf80e89ce, 0xdfce1b57, 0x7397ef8d,
+ 0x14b974ff, 0xa36ed29f, 0x26409eff, 0xf8d43d80, 0x3fcc0241, 0x2fdcf35d,
+ 0x7a518fb2, 0xdd796cce, 0x49f04421, 0x8df3a3d3, 0x47b57f8b, 0x76ded9ed,
+ 0xf48b3d50, 0x4af1b483, 0xbabf720d, 0x7295a599, 0xd52d71c8, 0xb24dcafb,
+ 0x571f4fcb, 0x33f4f0be, 0xf31c424f, 0x30d7668f, 0x178aff5a, 0x8937bc0e,
+ 0x976c57e6, 0x37598a53, 0xb76a42ec, 0xfff4bc5c, 0x72dd39d5, 0x80f978a8,
+ 0xcf628ea2, 0x96ea4fef, 0xfbed8ac7, 0x9a2a3215, 0xf71b531f, 0x18f66d2b,
+ 0x563c6972, 0x9ac27e08, 0x814bfee7, 0x7da9e2f8, 0x199fe902, 0x0e9b9f83,
+ 0x7c001fa0, 0x39723942, 0x7866e585, 0x02e54bdf, 0x93935af6, 0x6e46fcb1,
+ 0x753ea04f, 0xc5f9e224, 0xf2fdb43d, 0xd05d993f, 0xef17f2ff, 0x4e3f4071,
+ 0xd70c3548, 0x2a61fcbf, 0xd972afd8, 0x94c4ea9f, 0xea7f2f3d, 0x65b788bb,
+ 0x15377f6f, 0x9dc449e3, 0xc7b1c26e, 0x5bfd0e9f, 0xf63671b2, 0x20f1296f,
+ 0x297fcaee, 0xfa680496, 0xb68a4499, 0x0e8bd0c7, 0x362717ae, 0xf68c4753,
+ 0x1fcc04ef, 0x23bf5ec1, 0x422abee2, 0xffa026ee, 0xa17de5df, 0x3fe6021e,
+ 0x1d3930b3, 0xaf5c4c90, 0x8919b7a8, 0xb60f2dd7, 0x0f4e7c82, 0x7587f772,
+ 0xfc912f16, 0x57c21f9c, 0xedf15eb4, 0x7c99fde9, 0xf2e52a88, 0x3f38e8ef,
+ 0xfbc39e15, 0x9adbb2ad, 0x7c8efbad, 0xfeddd995, 0xa53ede2a, 0xe7c60e3b,
+ 0xfdb1a913, 0xa6b201d5, 0x8e9c74f7, 0x7e8457c0, 0xf2df7d33, 0x4d6fd310,
+ 0x45a503df, 0x30f17e50, 0x0ef81fd3, 0x574a3fc6, 0xef963fa8, 0x3da0259f,
+ 0x58e6f3a0, 0xe645bd7a, 0xd72fad7a, 0x96e94270, 0xbc088484, 0xc849fd40,
+ 0x595f5c7f, 0x177e81ba, 0xd0bd2f61, 0x3eba239e, 0x71976f4d, 0xfa053ffd,
+ 0xfeb74d7f, 0xef4c8d93, 0xfc9ff67b, 0x07236e2c, 0xf412799e, 0x5fa7ea95,
+ 0x4b957d05, 0xdd7fdfa0, 0xeddef2d6, 0xdaff4f54, 0xdea9e9a8, 0xb4f51a7e,
+ 0x1278c77c, 0x6aff4f4b, 0x7a989177, 0xd4c79f4a, 0xe21b7b53, 0xfd94fff8,
+ 0x2897f8d4, 0xd9a7f9eb, 0x68f89ec3, 0x4a2f87b4, 0x68d3f22a, 0x61dfe90f,
+ 0x3f8d1b92, 0xde1a770d, 0x755d7e2a, 0x309dd805, 0x85dc352e, 0x2ee1a971,
+ 0xe3ab7e2a, 0xcffcb19f, 0x74a26b10, 0x4fd4b7cd, 0xa5847981, 0x2bbce08b,
+ 0xeb88967f, 0x048b96a6, 0xc880bef5, 0x7df06fb8, 0xf078cd53, 0xfdfca743,
+ 0x52f7b3b6, 0xbf13e77a, 0xebe5d6cc, 0xbfebf464, 0xc9abeafc, 0x73b73fb4,
+ 0xeca7cefe, 0x63ca89be, 0xe28424ae, 0x24f39d28, 0x82484fe2, 0x3e40acf8,
+ 0x7e63a08e, 0x7f0f3eb9, 0xebbb5253, 0xaffdede9, 0xa6f90f3b, 0xb63edbe9,
+ 0xa42ef576, 0x2979b143, 0x20a54f12, 0xef3fca57, 0x04302138, 0x549b52ed,
+ 0x7aaf3112, 0xb79ddb9c, 0x0f1ccda7, 0x9cfe4bfe, 0xe70c0951, 0xeb7e7183,
+ 0xbcebf6e5, 0xbb004d5f, 0x0b39be7e, 0x0fe7afe7, 0xb58f8e2d, 0xe385b26f,
+ 0x575f00ec, 0x750bb4e9, 0x277dc522, 0xc5ff42e9, 0xad92b76f, 0xbefdd631,
+ 0xe4f89b2f, 0xfe8dcb83, 0x736e5489, 0xd1e70e39, 0x2272134f, 0xa6eb36e4,
+ 0x5a239253, 0x71f7f00e, 0xdbeb3cc4, 0x0d7017f2, 0xb6b16dfc, 0x88c49615,
+ 0xf384fdd7, 0x5f2bca6f, 0x69d5fee0, 0xf012f9cd, 0xd45d9a71, 0xd41e39c5,
+ 0x192475f4, 0x794d7409, 0xe3a3f965, 0x87bd8e29, 0x57ec1744, 0x539f36f5,
+ 0xbbe6313c, 0xfd427e46, 0x901e47e0, 0x23afc89d, 0xe012c972, 0x56d991eb,
+ 0xef96eb02, 0x58aaae2a, 0xb3374e74, 0x523cc878, 0xe138d9f2, 0xe6fe3eff,
+ 0x150f89cf, 0xb79c7e50, 0xd1c0fdb3, 0x7f7a63f8, 0x6a0429de, 0xc8a1c005,
+ 0x004229f2, 0xc48564e2, 0x0164e8f3, 0x48fafdf5, 0x2c1f95fb, 0xd5f6017d,
+ 0x4e0b3754, 0x96af2d13, 0xb1c014da, 0x025db837, 0x9546fcff, 0x20de31b8,
+ 0x159a8cd5, 0x203ad711, 0x96afc84b, 0x277eddbf, 0x2cc2f7f0, 0xdcba0133,
+ 0x6039cf23, 0x3cd0bfdc, 0xa7a0f516, 0x47c1fd7e, 0xa0934ca6, 0x30f8821e,
+ 0xc530a1e2, 0x9ecfcba6, 0xa8ba064a, 0xdb98a6dc, 0x90c571ee, 0xe18532df,
+ 0xcdf6cfac, 0x7d99fff2, 0x1bed4c9b, 0x691cb5c3, 0x512b46df, 0x2c7fadf6,
+ 0x56b2b6fb, 0x58b80fed, 0x3fab37b9, 0x6be575c8, 0xb2c5fa4b, 0xd8faaf6f,
+ 0xbe35fdfc, 0x2073bb0f, 0x23a36fb5, 0x6a40dbec, 0x6dc462df, 0xffcd15d3,
+ 0x59bec5ec, 0xeff477fe, 0x316fb055, 0xd1523bfa, 0xe6a2b7db, 0x456fb45a,
+ 0x7edd4503, 0xcf852ca8, 0x6fb47ae7, 0x1b367f0b, 0x16cbb2f3, 0x57c03f03,
+ 0x71af6fb0, 0x80ed073b, 0x38a45b9d, 0xdabefdb1, 0xdabed2b9, 0x3e25ffb9,
+ 0xe56e766b, 0x239e7620, 0xcecc871a, 0x7664ccad, 0x665ee56e, 0x630e56e7,
+ 0xdf68ce76, 0x1beca20a, 0x047abefb, 0x8be71efd, 0x83b8bf99, 0x95cf1796,
+ 0x7efa165d, 0x5f9daab1, 0x691f19a8, 0x122916ef, 0xdeca39f2, 0x39e1ceb9,
+ 0xddecde90, 0x86ef605b, 0x0a1b1da2, 0xc7c4647a, 0xba6d430d, 0xbe4772fd,
+ 0x4bf5ff68, 0x107f2fa0, 0xbefd9e71, 0xf68bcd89, 0x163ed17d, 0xa7376ef4,
+ 0xc98551e7, 0x47e7c3b3, 0x24753a7b, 0x43aaf7d3, 0x544e3871, 0xbfac0937,
+ 0x15010bf7, 0x5dbf81c6, 0x9df2f9c2, 0x797cd97b, 0x83f1998e, 0xcec89bfc,
+ 0x2c16505d, 0xdcc3c08c, 0xd718154b, 0x0b112b9c, 0x0e0baff8, 0xfc0a70dd,
+ 0xd69705d6, 0x00bbbfa3, 0x89bec39e, 0x32eb6ded, 0x2e77bb68, 0xa1de7017,
+ 0x1798efed, 0x3f7a97b6, 0xec737e76, 0x38531a7d, 0x13ee533d, 0xa72fb002,
+ 0x2f107db7, 0x239bfd72, 0xc8bf21b6, 0xf8cc625b, 0x985ef6a4, 0x97c62e4f,
+ 0x6fcc55aa, 0xf289f30e, 0xf9a2154d, 0xbc5d2544, 0x2f9bb530, 0xfda4ee77,
+ 0xbfb9e94d, 0xf7a2df1a, 0x3e71b8e1, 0xd7bf80b3, 0x3e341f13, 0xf39ff547,
+ 0xb8a9fa9d, 0x8fc8c79f, 0x5ccecd46, 0x5e814643, 0x3cf26fbe, 0xf4701e3a,
+ 0x942f949f, 0x0de6dbce, 0xd9e79dd3, 0x9372f9c5, 0x54b4d8e7, 0x6a48f815,
+ 0x97b76700, 0x4a903f6f, 0x3b8b77fb, 0xe6420733, 0x78a6ffb3, 0x62d0fe20,
+ 0xa83b42ed, 0xcccd30e1, 0x8e57f870, 0x9c0323c3, 0x09bc70d3, 0xafd44e0a,
+ 0xf1cec190, 0xca5e647d, 0x6f5fd067, 0x144f8f90, 0x859fa09f, 0x720578da,
+ 0xa9bcffa1, 0x5bc5c999, 0x6e5ca023, 0x81075d26, 0x8229d5ef, 0x2aab442b,
+ 0x21ff6e0c, 0xd57ab7ec, 0x9e839f4a, 0xcdae0b97, 0xf4f61d8c, 0x963898d4,
+ 0x3718e162, 0x9b8c4609, 0x24bde00b, 0xc668b7d8, 0x1efceff6, 0x3f4647b3,
+ 0xf5b98a65, 0xe533d008, 0x09b264df, 0x7fe8061e, 0xfa303811, 0xf07a5131,
+ 0xa4fdf735, 0x2afdfb72, 0xfc0ec1c8, 0x1fc052ee, 0xf8d886f2, 0x257b95a3,
+ 0x4df21a75, 0x8e904393, 0x1c98e32f, 0xc8dfa960, 0x3cb45be7, 0x6fde1fe0,
+ 0x7ef86416, 0x324f9506, 0xfa6a9a2d, 0x7786a0e2, 0x2fcd1ab3, 0x47a42788,
+ 0x6fb00dd8, 0xd596eb91, 0x4f91b7c1, 0xeea2ac37, 0x27cd1a99, 0x07603e4d,
+ 0x28afc72f, 0x8fee09fd, 0x9bea7fb9, 0x599a4fea, 0xacfb3faf, 0x868faf5d,
+ 0x015eda38, 0x4e690aed, 0xf20fc5d4, 0xd65e6ccc, 0xce20f562, 0x5d935ebb,
+ 0xfb68d59b, 0x0b971573, 0xcf2257cc, 0x0e854def, 0xd3b1bac1, 0xfad13e4a,
+ 0x2ce1843d, 0xd5783c72, 0xf5f941ea, 0x5e04ff54, 0x98fe4f7f, 0xb40eff96,
+ 0x5516fb07, 0xf1c67b7d, 0xf5278b48, 0x6669afd6, 0x69be3f66, 0xbe76b4bf,
+ 0x9783baee, 0x4dfc62b4, 0x2cd87f5b, 0xc32e7e7a, 0xd048b8fc, 0xca5073ad,
+ 0x9ff2fd71, 0xe558ff50, 0xfc43f532, 0xfcf94428, 0x31a7b6ea, 0xf9f67d5e,
+ 0xfe833763, 0x48adf8ac, 0x3a9f542c, 0x1093c5b6, 0x80a207db, 0x24d1509f,
+ 0x91167ae2, 0x2333b942, 0xd6420cfc, 0x14bc7e30, 0x62a7768f, 0x4c503987,
+ 0xf5d8afbf, 0xddc43649, 0xf6601e3a, 0xc73cffcf, 0x1b2dbfa3, 0x242bfbd6,
+ 0x946f8eb6, 0x9f1cbdcf, 0xe6db7667, 0x1a16fd82, 0x8ad779d8, 0x39b239c6,
+ 0x6550ce22, 0x7b5c5996, 0x59f70db7, 0x70139ffb, 0x17d0329f, 0xdb52ce79,
+ 0x39e679ff, 0x822b9766, 0xcdce0072, 0xef6c3456, 0xc5783880, 0xaffa3351,
+ 0x0a7386de, 0x5f53a7f8, 0x23fd017a, 0xc5d4506f, 0x8fe2a341, 0x0cc8620d,
+ 0x2aa6b3f1, 0x7f3403b4, 0xb18df30c, 0xc5bdf0e3, 0xb4bc56c9, 0xb29f9777,
+ 0xcfcbc570, 0x6cdcf03a, 0xc60756eb, 0x1f2e1b21, 0x378a8fff, 0xd9743e36,
+ 0x8e69e378, 0xf5995f8f, 0x21a435eb, 0x9490e319, 0x1892dcbe, 0xee308b71,
+ 0x29ecf85f, 0xb33b0f58, 0x014fafe3, 0xb8ff95bd, 0xe07dd4f0, 0x3ab3ed8f,
+ 0x3ef6bc61, 0x13d7047f, 0x7376efb4, 0xee78ef3d, 0xe9875c59, 0x05d9a3f8,
+ 0x3dec75b5, 0x23d61831, 0x917fb63a, 0x55db710a, 0x3ce3a77b, 0xa9ced56d,
+ 0x798c49fd, 0x6e029680, 0x07587d03, 0xa5abca32, 0xd03065a9, 0x1bca9679,
+ 0xfc70b65c, 0xc58ab1b8, 0x371e55e3, 0xbd7b16de, 0xdc4e2a2d, 0xeb96f334,
+ 0x926efc60, 0x43e92a5d, 0x9530f8bc, 0xc83ee8e3, 0x9a43db6f, 0xbf298fbd,
+ 0x2a0ff0b3, 0xf20df7a7, 0xc969acfb, 0xb2849eaf, 0xe31ee4a6, 0xf03ea1c5,
+ 0xdbcf5b4d, 0x6c7f7662, 0xf1d9bd06, 0x83cf8c6b, 0x835ce8dc, 0xd9f0bc74,
+ 0x9cb38860, 0xc2eebb94, 0xcd7b33fd, 0x62aa2fb8, 0x3fa8fbef, 0xc6df3b1d,
+ 0xd7c232f5, 0xf8483ad5, 0xf083ad8f, 0x4b779c39, 0x73338b3c, 0x5a1c43fe,
+ 0x1e73e075, 0xd638666f, 0xc53dd0e2, 0x6c2dd39f, 0xceb6913f, 0xcfe5b558,
+ 0xf5c4310a, 0xd3903c85, 0x8baecbb1, 0x02707c6a, 0xae44261f, 0xf38ec4a7,
+ 0xb8ddd787, 0xe07e40bc, 0x4bd7857f, 0xc4207e68, 0xfbc203cf, 0xe83d8624,
+ 0x61d6c4d8, 0xfbd8e43a, 0x95f5b50f, 0x4f418b14, 0x575b7d03, 0xaffe8de9,
+ 0x26191fcb, 0xf9a3e39b, 0xd8cbe674, 0x45827c76, 0x61fb76f8, 0xf5a8852a,
+ 0xcfac0b7f, 0x60531d37, 0x638da1fe, 0xf0cf7f5a, 0xe799f279, 0xb1ef3c45,
+ 0xed05b1ae, 0x545ed1b8, 0x341f1613, 0xd3833bd2, 0xe3641d5b, 0xf11d99c4,
+ 0xe7ad3b01, 0x11bb2bcc, 0x8edbd5cf, 0xdf5a7e29, 0x959786c1, 0x52fd88b6,
+ 0x22044e30, 0xe2f33fe8, 0x7eb66cfe, 0xc6e5e6c4, 0x76f0e676, 0xdbb1cdbc,
+ 0xa73b6ef1, 0xbf85676b, 0x77e76151, 0x69dedf2e, 0xea073dc9, 0x132add3b,
+ 0xba7fbfd8, 0xc40a2c51, 0x45927f68, 0x4cf2e2d6, 0x8978e86f, 0xd9e31de7,
+ 0x493146f9, 0x557aff41, 0x84d1de7c, 0x15154814, 0x6a6b14e2, 0x35d2fed9,
+ 0x81a577df, 0xde24d7bc, 0x756deb86, 0x533afe06, 0xbf10f99c, 0x192b4e70,
+ 0xda357007, 0x49b7449b, 0xf8aaff47, 0x1e70fea2, 0xc7f72d7f, 0xf3c2e488,
+ 0xb0a3a297, 0x3a23fa08, 0x8c6b4e4d, 0x5ed905f5, 0x7c113c42, 0xf3fa9d91,
+ 0xb1cbe492, 0xeda3d42a, 0xb4b4a9a3, 0xa742c41e, 0x4b0ab71b, 0xfcddec79,
+ 0x77ec4e59, 0x4f3e36e7, 0x99d51370, 0xc183f6ca, 0x23b9d1b8, 0xc68c9b21,
+ 0xe29b890f, 0x0b9fc6d1, 0x07eff6db, 0x41d6b47b, 0xcf5489dc, 0x31555728,
+ 0x8e8dce0b, 0x805908b1, 0xfe6f73d3, 0x6d6bd696, 0xd0fe7116, 0x85f6d769,
+ 0xcf4113ba, 0xdc11e46c, 0xfe5007ff, 0x4e9bb92a, 0x0240bee3, 0xdf76a4af,
+ 0xb45d312b, 0xfce7bce3, 0x10071646, 0x98bfd5c9, 0x2470e2cc, 0xf1f3f400,
+ 0xf3a70564, 0x7ef0a43c, 0x3ae78299, 0x72f6bd96, 0x3930886e, 0xb92bf244,
+ 0xb4be7f48, 0x86c8eade, 0x77e27975, 0x9939c2b7, 0xbf5f5e32, 0x53b9fd12,
+ 0xd07e7eaa, 0x4f5c25d3, 0xf0b4baff, 0x32bfd810, 0xebb452cf, 0xcfeae7fd,
+ 0x59f71aa5, 0x2fb0bd21, 0x93ddea8c, 0xabbef442, 0xd6c7e6f2, 0x7a397cc1,
+ 0x011915ff, 0x482ac9fb, 0xe7ce0b9c, 0x97d068ac, 0x79bb03ef, 0xd893b015,
+ 0xebef172f, 0xc36dbf95, 0xdc79317f, 0x0aebf965, 0xe2dbfbc1, 0xecb2ae31,
+ 0x9f68c5b5, 0xfe7a69cc, 0x7f3d555a, 0x7c8c236d, 0xde39f3d4, 0x369be7a5,
+ 0xcf89ecff, 0xf3fa7909, 0x4b3e46be, 0x021bc784, 0xb5110e2c, 0x09b82dbf,
+ 0xd9f236e9, 0x0b76d7c8, 0x7ce2f75f, 0x96257fa5, 0x81b26654, 0x842974ee,
+ 0xa3d4617a, 0x80487b0c, 0x094a0f7f, 0xae57e2d4, 0x69efb478, 0x19423fbc,
+ 0x7a06cefb, 0x2ebd0224, 0xd13823d4, 0x46de7607, 0x5bb6703e, 0x909f5841,
+ 0x59e9aeaf, 0xfe94f79e, 0xfa22d8fe, 0xefc046d5, 0x762bd468, 0x0489376e,
+ 0x9e8264d6, 0x6e309cba, 0x6a2cfa37, 0x9ff70499, 0x286cb510, 0xc4e27bdc,
+ 0x1f7cc7f4, 0x8248e74a, 0x431b82fb, 0x3ec15317, 0xeba738fd, 0xde7bb066,
+ 0xec04a425, 0x6c71cde0, 0xa798b29e, 0xdc2ab77f, 0xed7b4eae, 0x59bef87a,
+ 0x785ce156, 0xcb56f367, 0x4507c830, 0x9bc47fbc, 0xb4157758, 0x332cd1df,
+ 0x812ccaba, 0xd8bf1061, 0x1dbb632b, 0x7cf19365, 0x6b6fd865, 0x3a40fb66,
+ 0x2c713f9b, 0x1de7b08e, 0x055e9fc1, 0x4c27acf1, 0x0c9ff7b1, 0xfdf89ab7,
+ 0xfc70df35, 0x7fda8c6d, 0xf6cadc37, 0x0878fdc7, 0xe97547ed, 0x330e3e79,
+ 0xcb96b87d, 0x6f4bf7f9, 0x6ceffec0, 0x47185416, 0x6e3bc50a, 0x39fb451c,
+ 0xe3c488f1, 0x392e2c30, 0x9bbfbf8e, 0x1f80d2b8, 0x0223af13, 0x3fc4f3e8,
+ 0x35b7dc12, 0xce2966ae, 0xa0eb7eab, 0x7586cf38, 0xb05b8a52, 0xe8ec6773,
+ 0x956f8fbf, 0x9c4cb874, 0x798169e6, 0x04a384e6, 0xa384eded, 0x123cf2fa,
+ 0x369db110, 0x4f6bf3fd, 0x5605f3ea, 0x49076f8e, 0xf86f7c05, 0x3aba4452,
+ 0x01eb88bb, 0xd9676f5a, 0xa6efbc00, 0xda9c22f3, 0x6297e9a5, 0x7e71ac51,
+ 0xf281e026, 0xe08509eb, 0x52c4f2f8, 0x5fefc63b, 0x05715a59, 0x7f9feb8c,
+ 0xac4573cf, 0x7611e073, 0xafed8129, 0xe2502772, 0x0ad7ae29, 0xe975df8c,
+ 0xebf63125, 0x70d6386b, 0x7d39e1ad, 0xd6279c69, 0xad0fc4be, 0x58290fcc,
+ 0x6050423a, 0x204fb65e, 0x078ed7c0, 0x373d973c, 0x640f27e3, 0xe0de3d00,
+ 0x2db3f405, 0x963b82cd, 0xeacab19f, 0x07bef360, 0x1fb0b5fc, 0x94aa5eef,
+ 0xae7b1f60, 0xabce0377, 0x2ba0876e, 0x5ba9677c, 0x9770e788, 0x8866c858,
+ 0xe9754b67, 0xee03c6b7, 0x4758cea7, 0xc4b27de9, 0x427e7284, 0xfefd2176,
+ 0xbe30422a, 0x03b5e3c0, 0x229b266f, 0xc0ff23cf, 0x95b0ff9a, 0xd5b0fbd6,
+ 0xf6497289, 0xdfa004b8, 0xe5ffdff5, 0xbceebd00, 0x0e394664, 0xed1ff3e0,
+ 0x4f9cadbb, 0x6bdce3a3, 0x3ca4ff01, 0xe5c3f505, 0xc965a871, 0xe5012f70,
+ 0x54758c7b, 0xf24d2fcd, 0xe946db50, 0xf09bb249, 0x76e22e7e, 0xdf6d4eab,
+ 0x45efe119, 0x090903e8, 0x69a5f604, 0x166854f6, 0xff14f142, 0x10f62ce3,
+ 0xca9233cc, 0x0929bf69, 0xf5616256, 0xc2674ab5, 0x9f71aae7, 0x2e65c53b,
+ 0xb8226e1c, 0xd2360daf, 0x9d9afd42, 0xdaf3ecd5, 0x66f68244, 0x605263ed,
+ 0xa367ad0d, 0xf88566d4, 0x2d5ba649, 0x4944ad80, 0xbde78a92, 0x7d339507,
+ 0x32fd65b4, 0x50afec31, 0x0ff31f65, 0xf5ac4171, 0xfcc38fba, 0xfc00bcf2,
+ 0xf5d43eca, 0x2e35b80a, 0x75cf6b2b, 0x79fe82c0, 0x3f706ed8, 0xbb8f90ac,
+ 0xb1353f13, 0xeba102fd, 0xb69dbf71, 0x1bb4668e, 0x15de0f54, 0x953eaf41,
+ 0x75cf9e08, 0xb572ffd3, 0xf611772d, 0xb9938f83, 0xf4169ac1, 0x2d91c4dd,
+ 0x5f6bc780, 0xa238bbc7, 0x3784c8ec, 0xde806b3c, 0x8c3f6a6f, 0xa2131878,
+ 0x33e5c8fa, 0x2a7b8552, 0x943ce19c, 0xfcf95ab7, 0x949bdb8e, 0xd1fd71d2,
+ 0x3338e5af, 0x6bd357f2, 0xace7bea3, 0xb198b576, 0xc13200d6, 0xba110ed8,
+ 0xc0b350e9, 0x8221bd1e, 0x4f99df7f, 0xbae942f1, 0xfc0ef417, 0x19818bf3,
+ 0xcd0d9b80, 0x7e82b1df, 0xa3f1e37c, 0xb11d7e99, 0xa227fabf, 0xf6cac3a7,
+ 0x0f803b87, 0xf22ffbd5, 0x728423f1, 0xea95cb0e, 0x443c6447, 0xe711bdc3,
+ 0x81ac5e9a, 0xf0b2330b, 0xf9011c7c, 0x0a234288, 0x3a364cd6, 0x7f9aaf81,
+ 0xcfec26bd, 0x9eb9e226, 0xded64e55, 0xcbf3591a, 0xefe8165d, 0xfe82f8aa,
+ 0xf5175b97, 0x97f3a25e, 0x5e30f388, 0x67e70ba9, 0x090a4bde, 0x7e0b7f24,
+ 0xb9eb6905, 0xc4a57e3a, 0x0757e0c5, 0xfff8d1e8, 0x6d93fb27, 0x6a83cfec,
+ 0x25ae7f77, 0x51b6df9e, 0x4f7b90bb, 0x05c33a7d, 0x89169c39, 0xd95ebe0b,
+ 0x51e77e93, 0x2dd706fd, 0x7a0d9f4a, 0xea99b13c, 0x8f5a29b1, 0xde09725d,
+ 0x6bdae75b, 0xd4677b43, 0x5fbc8beb, 0x7be31b5e, 0x1199e88d, 0x5371f307,
+ 0x5dc060d7, 0x8b924ab6, 0x41d9b129, 0xb6afad91, 0x91c6eb26, 0x8fddf1e8,
+ 0x2ff35276, 0xf8d2bf35, 0xe4afd85e, 0xcf1686e3, 0xff148214, 0xc7f7dfb4,
+ 0x5f01e679, 0xfcd938d7, 0x829a0e13, 0xab03fcbf, 0xcfa00ee7, 0x0710fb46,
+ 0x42231aeb, 0x125e2c99, 0x4f5be9d2, 0xe83365fa, 0xc248634f, 0xc74fcc71,
+ 0xcf4261b1, 0x4b8bf4f4, 0xab52f464, 0xc0ca7e02, 0xab1ac25c, 0x7bafb826,
+ 0x47bb3660, 0xbb0e6066, 0xe3dff1f7, 0x7dcc7ad8, 0xd0dc6c71, 0x4b581fd2,
+ 0xc97e81ee, 0x739bf112, 0x40dd39be, 0xef0fc42a, 0x0ddf738f, 0xb914b0fc,
+ 0x4e191fb1, 0xde2812e2, 0x0146a432, 0x552437f6, 0x1b8b02aa, 0x40ee3612,
+ 0x28cbeb4a, 0xdc61f356, 0x16b6a0ca, 0xcd1920e2, 0x6cf5cfb1, 0x5dbf9388,
+ 0xea29abbc, 0x3886ca3c, 0x541f6fe6, 0x8b937f68, 0x709479d9, 0x0f9286dc,
+ 0xbf88edfc, 0xf1db3b0d, 0xf50f5b19, 0x1b3e3227, 0x30205fe7, 0xf3c497e8,
+ 0x6488543f, 0x91f9c24d, 0x99df04df, 0xb23f382c, 0xd8235711, 0x58e297cf,
+ 0xe09d755c, 0x9ff90f5a, 0xb8165d48, 0xffc3476f, 0xeadf278f, 0x8e2be892,
+ 0xc367ceeb, 0xc3ea959c, 0x8eaf20f3, 0xaf87e7c9, 0x0d741ec5, 0x8b737866,
+ 0x9aeffdba, 0x4eb282dc, 0x8788566e, 0x78ebda44, 0x1df7e705, 0xe60b9c42,
+ 0x05cb1d43, 0xe160a746, 0x7d2403e7, 0x43db869c, 0x27781c6d, 0xb7e9132e,
+ 0xbc18ff11, 0xb2e2cc1f, 0xfd1a3d00, 0x86a473e1, 0x73c69e73, 0xe15969a0,
+ 0xee3a4db8, 0xe0512d93, 0xbe722f8e, 0x97fe86d9, 0xdff4c1d7, 0x60fe8788,
+ 0x6e732e3c, 0x15abf292, 0xae5fdbe4, 0xdb7b0449, 0x0ee3ceff, 0x0f91af90,
+ 0xcc7f829d, 0xfadf5841, 0x9f731c83, 0xa5a69688, 0x7f05280d, 0x0d3d2d34,
+ 0xbd79ed53, 0x07198a5d, 0xeef5cd3c, 0x9eb5e31b, 0xc3f30c58, 0xb39fd0d3,
+ 0x73de779e, 0x6177baa3, 0x8e3ebc7c, 0xd15ebbf1, 0x8026a8f8, 0x5de7759e,
+ 0x927eec09, 0x90ff7644, 0x8373c993, 0x492a52cf, 0xd1b9ef91, 0xdc47e91f,
+ 0x1181e633, 0xad9320d8, 0xbf166b88, 0x5065ced1, 0x97e4c743, 0xb9fae8c8,
+ 0xec294c6f, 0xcc6d919f, 0x30dc5d2e, 0x254bdb1d, 0x5387580f, 0x312d2ebe,
+ 0x73ae20b9, 0x1c9fd176, 0x517c1470, 0xe02e6b46, 0x91e888fd, 0xd431e36d,
+ 0x65b7f38d, 0x88409573, 0x9ea52a42, 0x9726241a, 0xb8eeb819, 0xff7314d0,
+ 0xe6c6ddb3, 0x4e71cddf, 0x06d2d34c, 0x8d8d9697, 0x39440fcc, 0x7aa47869,
+ 0xae365e98, 0xc5309cfb, 0x6fb40a47, 0x994ea7d4, 0x40dd6104, 0x9c2987b3,
+ 0xd63d9aff, 0xf40521f4, 0x4b01d60c, 0xe4d47da8, 0x9abf8439, 0xfc4af18a,
+ 0xfd5f9a13, 0x8e03e602, 0xded00aeb, 0x8f5ffd51, 0xd98232fa, 0xd3d82b6f,
+ 0xe7653888, 0xc107f7de, 0xdf87dffa, 0xeb0f10bf, 0xba917f40, 0x9e7ec1e2,
+ 0x78ddffbc, 0xe1f43738, 0x715e2cfd, 0x351e6197, 0xfaecc6c1, 0x6c92b6a3,
+ 0xdf02d7e8, 0x227ae77f, 0xb3564970, 0x01e58d75, 0x5c9e70d1, 0x554f2f7f,
+ 0x9ee1b263, 0x5bd63f1e, 0x32e7efc5, 0xcb92a1ca, 0x4db6f961, 0xed0a864a,
+ 0x7eb6dc7b, 0xa08f6e70, 0x14d93cbd, 0x8d11f38f, 0xc6db459e, 0xfa773028,
+ 0xaf99b34b, 0x6ccab77f, 0xc317705c, 0xf387967a, 0xc1e748cd, 0x6fac367d,
+ 0xfed8cfc9, 0xadb48594, 0x7abed4d5, 0x0b79d99a, 0x7c963f63, 0xa7f616a8,
+ 0x90f25bc2, 0x7862f380, 0x4e3a7eff, 0x883f5679, 0x7ec65eeb, 0x31cdef1a,
+ 0xe6d55f9e, 0xfcb8cb53, 0xf50788cb, 0x6b5cea2f, 0x369f5b33, 0x1fceffc6,
+ 0xff61b2ca, 0x91fe3c6d, 0x79c0264b, 0x86871de8, 0x3eee5c24, 0x1efc33e5,
+ 0x1a57b826, 0x823e93d2, 0x654db669, 0xbf3464f7, 0xaae02f7d, 0xef1db83a,
+ 0xf6bafb19, 0x94f9aaa6, 0x6b30f603, 0x91fa8776, 0xa43f01ab, 0x97f9d04c,
+ 0x282e9bd5, 0xf8cbbe6c, 0x7e7f0770, 0x1b37f407, 0x3fab59f6, 0x7ce54c9a,
+ 0x317ca547, 0xbf321ef2, 0xa6ee7f4d, 0xfad5fdaf, 0x2b5bf5a9, 0xd1fbe2af,
+ 0xf869df8c, 0x2c78e6cf, 0x6eba52db, 0x9ad16500, 0xf30627bd, 0x4e7868f3,
+ 0x1197c347, 0x4948cb3f, 0x8110ba61, 0xb147e693, 0xcb3c9a5f, 0xfef216ea,
+ 0xbaf8d3fb, 0x8fc41a5e, 0x118dc37a, 0xdb721d1f, 0x2367d060, 0xb87a3a3e,
+ 0x3627e45f, 0xa99427e6, 0x678842ee, 0x9d763751, 0x394fc233, 0xbc1dd529,
+ 0x0b6cf40f, 0xf8c479c3, 0xd7b99ccb, 0x57cf1c65, 0xe1fdabc6, 0xdb943d3e,
+ 0x6017d844, 0x5a7bc3f6, 0xb73eed3b, 0x7c04a86b, 0xb4f4c22f, 0x7435c4af,
+ 0xd2f97768, 0xc0382e27, 0x411cee8f, 0x11d38e30, 0x77f7a7af, 0xf9e91136,
+ 0xa543971d, 0x3f8ffad4, 0xd2da8d83, 0xda1dfb8a, 0xa071e4bf, 0xb145cd2f,
+ 0xfe27f9fa, 0x86f7e11d, 0x4cf5c5dd, 0xe02c979b, 0x99abbb72, 0xda2f67ad,
+ 0x30f28a58, 0x437ad7ee, 0xd0661670, 0x638d3caa, 0x51bf9014, 0xdf5c4b3e,
+ 0x51607dc1, 0xf08f2272, 0xdc1e017d, 0x2f5653a7, 0x28c3dc62, 0x93bb7cbf,
+ 0x6b57a39d, 0x42b71e70, 0x790ebd8a, 0xb5f4dda5, 0xc7ec63fa, 0xed0126c2,
+ 0x65fe91a4, 0x0dd76a5b, 0xd67fd020, 0x847ee8bf, 0xe25da206, 0x55fad4fd,
+ 0xff785c46, 0x50fad440, 0x7224f5db, 0xe6f2f53f, 0xbf2fb8c5, 0xb09ff69a,
+ 0x85c61238, 0x7a35fa34, 0x1428fd8d, 0x8816c8cf, 0x5c16aee3, 0xefa39f60,
+ 0xeeeb7327, 0xb0d85c3f, 0xafc8207f, 0x66fb625d, 0xce02fddb, 0x203f3b0b,
+ 0xbd607d6c, 0x3d69eb80, 0xed99afca, 0x8e59ea07, 0xe7dc0a35, 0x8851b657,
+ 0xf565c729, 0x11a1aef9, 0x60796a76, 0x8ea86b86, 0x1fdc46de, 0x54a1a2b2,
+ 0x9d807cf7, 0xfdb893c7, 0x48df4dee, 0x38cc624d, 0x9a5fa693, 0x97fa69be,
+ 0x3cd9576f, 0xcc1c0a47, 0xfebb04c8, 0xa84bce18, 0xcedabe5d, 0xd1e607d7,
+ 0xb89faa57, 0x581f5ba0, 0xb3e4c792, 0xe7c62c44, 0xca57d93d, 0x1e7d9d07,
+ 0x7fefd767, 0xd1fdb6f8, 0x85e9a1fa, 0x5ea33fd6, 0xc5aff918, 0x30728cd5,
+ 0x82e81ff2, 0x7b1bc1f9, 0x0407816d, 0xa74677d0, 0xe915af7f, 0x702b48ec,
+ 0x3fc839c1, 0xce9407c0, 0x31dbf4ea, 0x9496235f, 0xc75e71da, 0xfae34de7,
+ 0xe1c83f16, 0xab4ed67e, 0x473b2c7b, 0xb80c9254, 0x36db5298, 0xf8a4e2d3,
+ 0x2174647c, 0xe53a2bdc, 0x1099b6b1, 0xc8f25efa, 0x5fb84298, 0xb6d6ca7e,
+ 0xea2e2d77, 0x2d8ed5d7, 0x57e5fb84, 0xf680dd80, 0x10db9607, 0x89e53d57,
+ 0x9579f2e7, 0x5cce3fbd, 0xcbdd9f32, 0x292bcacc, 0x3c742d8f, 0xfc3c3cab,
+ 0x959fa0f7, 0x1045c5ad, 0x8884a9b7, 0xaacf1d37, 0x2d908edc, 0x93e78d9b,
+ 0x6cdb7be8, 0xf076559e, 0xc5ad2eeb, 0xb0f2adf1, 0x0e44fa84, 0x44a8b8b1,
+ 0xdfa56afb, 0x7ea38dad, 0xdaefe52f, 0xe60b8b24, 0x1fb9f4af, 0x936bb5e6,
+ 0xf11aaadc, 0x7c1f935c, 0x35ac7407, 0xfdfb75b1, 0x684f0daf, 0xbf78ccbb,
+ 0xc32647df, 0x67c5a43c, 0x9e58d4c1, 0x7cf138af, 0xc589be44, 0xbfe58c35,
+ 0x512cecd2, 0xd5170033, 0xaf161487, 0x4fe07fa6, 0x17a61156, 0xeb9d84d5,
+ 0xf04c3aaa, 0xa1f54b1c, 0x02c73c42, 0xd63ffcfb, 0x735ff0e1, 0x571ba58e,
+ 0x92054f8c, 0xc08a5930, 0x55bb34f5, 0x9bfb1797, 0x887f4046, 0x7382e718,
+ 0xa9866218, 0xbfed0766, 0x294d0578, 0x4ba7243f, 0xea5afb84, 0xe1114ea6,
+ 0x3235a9be, 0x62623fdf, 0xf6b5cce7, 0xb47f389a, 0x64bdb4f4, 0xecfdc807,
+ 0x36b9ad5b, 0xf3817eb6, 0x6bbfad61, 0x60113704, 0xe08075de, 0x149c80f9,
+ 0xb3fc02d2, 0xe01e7711, 0x127b3ded, 0x375b37e7, 0x90197fa6, 0x97a6ccba,
+ 0x57f78a55, 0xfa84591f, 0xdd304ae0, 0x6ff34993, 0x7cb197d9, 0x2642e986,
+ 0xf6dbf085, 0xc6bf9672, 0xcd086174, 0xce5f6bbf, 0x49c0b0f2, 0xf623b607,
+ 0x48ff428a, 0x7de38768, 0xc01afb9b, 0xf16264b7, 0x0515e917, 0x7db453d7,
+ 0x44e96b21, 0x1ef8f00b, 0xa7884dd8, 0xdafc16d4, 0x02eaf106, 0x3dfb0ab7,
+ 0x837bf336, 0xf1aa69be, 0x7099b455, 0xf02903fe, 0x4fce43ff, 0xc9a42e4d,
+ 0x8bec0d7d, 0x6bee8d25, 0xb4ed1d60, 0xf606d3dd, 0xad1bec66, 0x377ec053,
+ 0x5ca7f3bd, 0x0afc9fbc, 0x37d8cf56, 0xf6909ce8, 0x066fece7, 0x8f5c8a6d,
+ 0xffcf6d3e, 0x62a3be14, 0x5054ff40, 0xaa0ee49d, 0x44dc6b87, 0xbe60b255,
+ 0x362f9fac, 0xb69f6611, 0x82ce4ad9, 0x10c0c95c, 0xf6455b8e, 0x6bc84e92,
+ 0x26b49cf6, 0x9b5f69f5, 0x845abd92, 0x23293971, 0xd8117478, 0x7bb1dfff,
+ 0x1bb7043d, 0x14be73f7, 0xed8cd7be, 0xfec1b10f, 0x177fd010, 0xf2a7f349,
+ 0x2f8b17f8, 0x88dc9493, 0x07ef3079, 0xec1a7efd, 0x63609f37, 0xbf6807fb,
+ 0x63abb044, 0x58e98a88, 0x81656788, 0xdf983d28, 0xde8f1a43, 0xdc7feb47,
+ 0x9649e2ca, 0x0f8ba206, 0x38b3c766, 0x8b074ccb, 0x8dc9c60f, 0x10ff82b7,
+ 0xc1388e77, 0xa5fce87f, 0x22fee122, 0xae2379c9, 0x11341d8f, 0x3959f7a0,
+ 0x99f584e0, 0x7524abae, 0xafaee933, 0xab5bcb93, 0xbd4571f7, 0x7372e20a,
+ 0x7d3fcc1d, 0x7ee09f36, 0x4a53aee8, 0x934dd600, 0x91352c32, 0xf92b9ff1,
+ 0x0b390f77, 0xfe21e332, 0x408e37bc, 0xc5f613fb, 0xbf0e4099, 0x056396de,
+ 0x3c04bc3c, 0x32487ca2, 0xfa86ef3b, 0x7a502e92, 0xdb39f133, 0x63a92f27,
+ 0x277f2812, 0xe15760dd, 0xad67a9be, 0x7ee0378d, 0x784c17d0, 0x8a4beebf,
+ 0x2ff214ab, 0x609d579d, 0x6ccd9f7f, 0xbcfec38c, 0xbcfec260, 0xf575d714,
+ 0xc3f74a4a, 0x4a7c5823, 0xec0911b2, 0x502a64b2, 0x73cfa6ef, 0x493cd9e3,
+ 0xe3cbd3b3, 0x2e3cfe99, 0x200f3c10, 0x7f51f299, 0x9d3afdb4, 0xebf7045d,
+ 0x2ad59bf4, 0x4ae38e02, 0x4851b8b5, 0xe4cf7884, 0xdb7e8212, 0xe78cbb64,
+ 0x307f6072, 0xc29b1b9c, 0x0f94efed, 0x813d712a, 0xdc30e04a, 0xe762d97f,
+ 0x75f168f7, 0x4e39ebc5, 0x226d23ae, 0x5dd791f8, 0x07882e22, 0x8a497f5d,
+ 0xe74e47e9, 0x10233ef5, 0x97be8129, 0x0095517f, 0xef44f977, 0x2faf4de7,
+ 0xe0e3053c, 0x39e18b54, 0x8f4889f8, 0x4ff7cf1b, 0x4fee1a77, 0xd6f3e78e,
+ 0xe47064c1, 0x1d6d313e, 0xf238ba68, 0x8b53f409, 0x65f01714, 0x3efdddbb,
+ 0x5bfa7bac, 0x38b97265, 0xb63e33e2, 0xa5c46f9f, 0xa1ff5c38, 0x2e03b4f8,
+ 0xf3afaeae, 0xafbf695b, 0x07eaca1e, 0xb95d821c, 0xc92997f2, 0xf1cde760,
+ 0xa968decc, 0x97c03b86, 0xcbe18133, 0x3f5bba39, 0xe267c557, 0x01be9a7b,
+ 0x3d9ea0ee, 0xac7e6072, 0xd78a6575, 0xedd78055, 0xb3f38276, 0xe65ba51f,
+ 0xed699e82, 0xf86789ec, 0x6aeba637, 0x7587ee57, 0x6c67ff1d, 0xe03698bc,
+ 0xde391292, 0x3864e87f, 0x3375aaf3, 0xf3fda66f, 0xbf5c65da, 0x8be7e549,
+ 0x1e92f122, 0x770d1781, 0xef16761d, 0x7533f0d1, 0x3c22bbf7, 0x2119fa9f,
+ 0x9e124cce, 0x99f86887, 0x9c3867e2, 0x138d8872, 0xddc7e1bd, 0xe6069ce5,
+ 0x87370a31, 0x280a6e18, 0xb7f7f03e, 0x118fc07a, 0x8af54f37, 0x3cf12f9b,
+ 0x53bdaafc, 0x186ebb2f, 0x7df7e9f4, 0xb689d31a, 0x8f82fbd8, 0x56ef7e72,
+ 0x06cc6eea, 0x8993717b, 0x48937f9d, 0xe714adc6, 0x7bb4e3bb, 0x20b26be5,
+ 0xf6625dbf, 0x19b37b67, 0xbb76cfed, 0xd77183c7, 0xcb9e0b34, 0x0da79226,
+ 0x06bbf5f6, 0xdfc8d458, 0xc72ef8d1, 0x9a1ca361, 0xeffc0278, 0xf3fc98d7,
+ 0x1b81ca6e, 0x197a48ec, 0x93b8c393, 0xe21126ca, 0xfdfc8e42, 0xe04faf80,
+ 0xc3c02d4e, 0x25ef0571, 0xa0ae3eaa, 0xbecdfc5d, 0xbe210bb7, 0x9e1feda9,
+ 0xc2ede7b0, 0x3ef09182, 0xdc6bd9c3, 0x3c796aae, 0xd276014a, 0xc4fd2f70,
+ 0xfd2679f0, 0x8025f2bd, 0x72eeec9f, 0x73eb7de3, 0x1d1784e0, 0x736d6e77,
+ 0x60b3074d, 0x4e7d6fbc, 0x9b1f9d88, 0x1d3dd47d, 0x7dd4654c, 0xb70f1ceb,
+ 0x715dd691, 0xdffdf462, 0x163e7c74, 0xd7fbf10f, 0xc1c40a43, 0x6b9a951b,
+ 0x26a27cd8, 0xa68fec0b, 0xf947f877, 0x08e1f8d6, 0xc3ff7ddd, 0x88f3f8f8,
+ 0x38f7624b, 0x4eb829b5, 0xdf6128f8, 0xeb71f235, 0x39f7ae2b, 0x0f9c5eab,
+ 0xb96c70f6, 0x576dd71b, 0xfe7c4539, 0x64b21213, 0x125cbc81, 0xca3477ae,
+ 0x4213d4ea, 0x2a447bf7, 0xe5a76119, 0x8dc5fa7b, 0x70eff685, 0xf00e4c78,
+ 0x43aea42b, 0x4984ddf0, 0x6ec16339, 0x4dacc7db, 0xa34c7186, 0xb455d29b,
+ 0x874dded5, 0xc7275746, 0x858e1dc9, 0xf678c726, 0xe0a1d81d, 0x7c0b76b1,
+ 0x71a0e1af, 0xff2639ef, 0xfc803c08, 0x2c20f1bb, 0x07c6bc80, 0xfcb54f1b,
+ 0xa10f1f3f, 0x1e9f2081, 0x087100f1, 0x43c2b7c7, 0xc355f016, 0xaed7f503,
+ 0xfe68fe02, 0xf6c2a35a, 0x0d796a1d, 0x7cf64507, 0x10a5cf7c, 0xf6443fdc,
+ 0x6d39d959, 0x57ae224f, 0x6d64ecbc, 0x3ed87e74, 0x6498ba98, 0xebf983b2,
+ 0x8c89efda, 0x57e80909, 0xe106a18e, 0x06e3f40e, 0x71743da2, 0x4176917e,
+ 0x71377b80, 0xf806796f, 0xd064a197, 0xe2e6318b, 0x877fe010, 0xf8064a6d,
+ 0xc9b63987, 0x5daf8059, 0x0ebd5623, 0x01aed643, 0x516f2fe5, 0xcd27fdbb,
+ 0x6af0b5ee, 0x746ff6b5, 0xbd74fb30, 0x020f9d9b, 0x87491dbb, 0x2c41ff66,
+ 0x9a108740, 0x86cafa63, 0x0db9baf6, 0x41d039ec, 0x205fbaf9, 0xe41fe04d,
+ 0x5329dc9b, 0x17ebcfc1, 0xcece8092, 0x860c5fbd, 0xf3716538, 0xde8147ab,
+ 0xd43d6d62, 0x350f5fa5, 0xbf9ad1fa, 0x342bcda3, 0xcf9b487f, 0xe504df82,
+ 0xd3b9fcd9, 0x26add6cc, 0x6e782c87, 0xeaf3f1f9, 0xbfae6e55, 0x3147ed12,
+ 0xa42dc7ef, 0xeed2e915, 0xf399b91d, 0x9d10f8a3, 0x39436687, 0x3e513721,
+ 0x1defc4dc, 0xbfa5c9b9, 0xbc96e157, 0x688ef7d8, 0xbef6f4f5, 0xd6b87c71,
+ 0x6df46eb0, 0x763e43d3, 0xfa7fc8cf, 0xd2773cd8, 0xc12fd110, 0xce979a80,
+ 0x327069ee, 0x62521c3e, 0xb9fb578f, 0xb5324efe, 0xe5b9c365, 0x8efe7bfd,
+ 0x7b2be3e3, 0xf81efefe, 0x494f1389, 0x4eb5f604, 0x012e353a, 0xd2f3e7d7,
+ 0xab593d70, 0x9369fbd7, 0x88e7b08d, 0x5777ed1f, 0xdc7a520e, 0xc167d00a,
+ 0x1e67b7f4, 0x77d429ff, 0x2244b8f1, 0x2a144dcf, 0xc710a19e, 0xbfbfe42d,
+ 0xfe605073, 0x907e5692, 0xf3c5eeff, 0x21b0b71c, 0xc48fbb42, 0x9be7211c,
+ 0x9a193df8, 0x593a6f5c, 0x8eca4a74, 0xfdfc0f96, 0x5a0be233, 0xf399a15c,
+ 0x11fcb48f, 0xa77cb7cf, 0xfc096ee9, 0x89a4eff3, 0xeed11dc4, 0xe0ce950c,
+ 0x2f1ce223, 0x4a7e0c3b, 0xbd3f73cb, 0xde2b8e99, 0x4adc4437, 0xfede6de8,
+ 0x5be4367a, 0x8ff798c5, 0x9dfbf918, 0xfef1bbe6, 0x2a092191, 0xfb5bd3d2,
+ 0x38a6ae93, 0x27720d19, 0x65cbcfcc, 0xe51877f7, 0xff9ecafb, 0xd91b6e48,
+ 0x927bbf33, 0xbf0e51bf, 0xeb80533d, 0xc3c9bd4e, 0xb47ddb88, 0xbfda7e9f,
+ 0x9fa7ed10, 0xf8af63fa, 0xbdff989c, 0x1af30d2f, 0x9f7bbd5e, 0x4e7f064e,
+ 0x64f4e9c3, 0xbb899b86, 0xec4c9a7f, 0xf232f2dd, 0xf30773ed, 0xd710e66b,
+ 0x3fe99bec, 0x78ae0a77, 0xd27e17b4, 0x4ab3fb0a, 0x0e738d38, 0x41ffa217,
+ 0xe31079f8, 0x1c473638, 0x7bdee789, 0xa19bddfd, 0x5b9832f9, 0xbf0578e3,
+ 0x36b802c7, 0x6f45538e, 0xb2e049d4, 0x98ab4a15, 0xba7ee31d, 0xce519746,
+ 0xf6094847, 0x8d3a27a3, 0xabd23038, 0xefdae7f9, 0x4c7e50c0, 0xddf5a24f,
+ 0xff63e6aa, 0xce61c6a2, 0xdfc69e97, 0x9c95fa9e, 0x1cdee3c0, 0x4e4e17ff,
+ 0xdbd80b7b, 0xe519be93, 0xecd72c66, 0x90342147, 0xfc1fa983, 0xa9092191,
+ 0x97850fa8, 0xe3a6e214, 0x3fa8190c, 0xaf8a4eff, 0xe3ddbc40, 0xc27acf64,
+ 0x1325f55b, 0xe37724f1, 0x663e0e4e, 0x96eddc03, 0x1f106cea, 0xba5ecebd,
+ 0xda6f5406, 0xf0b305a7, 0x1336879e, 0xf4d99081, 0x102d73e6, 0x251ef047,
+ 0xa0a03e78, 0xc054ff79, 0x56a5efe9, 0x5e75479c, 0x08b1e424, 0xbcd8333f,
+ 0x587e06c6, 0x6f9d8530, 0x7448983b, 0x27f790fb, 0x8f06bc30, 0x1dd9bf9f,
+ 0x2f12fca3, 0x29dc499f, 0xc72e38d9, 0x70a3fc63, 0x3ffb09bd, 0x481d704d,
+ 0x9e65bf01, 0xce85f380, 0xa40e13bd, 0xee3b7a50, 0x333b444c, 0xdde0f83d,
+ 0xc6882a4e, 0xcf8b1eff, 0x780a16bb, 0xeaa140cf, 0x59617cc2, 0x98dfee26,
+ 0x99e48ff0, 0x433e50c5, 0x74cdf9c6, 0x788252b1, 0x2134d9d4, 0x7b8be607,
+ 0xf85ab684, 0x297f5c1d, 0xfd38876b, 0x7cff30c9, 0x0c7938a7, 0xaa9c76fe,
+ 0xefe187e5, 0x3cc31203, 0x0bced56d, 0x7cb4cdfb, 0xf7016cd5, 0x66774eef,
+ 0x7e047f10, 0x7953d70a, 0x6cb8a58e, 0xb8005fee, 0x3fa4599e, 0xc4bb3837,
+ 0xeb910246, 0xef138216, 0xf7c83b21, 0xfc097769, 0xe7ae7c5e, 0xcfbc7037,
+ 0xfbac9b99, 0x3f3094ae, 0x6453bbd3, 0xb3e471f7, 0xf4d6a1df, 0x87ae46eb,
+ 0xf1f9f037, 0x8e864f3c, 0xd288628e, 0x5b3f4088, 0x62e5be47, 0xa5cf0e1b,
+ 0xe78707e2, 0x1c6ef6d3, 0x8ad79861, 0x17116b95, 0x6f1d6c69, 0x1382ec36,
+ 0xdfea6ec1, 0x9f4f25bb, 0x97c7a18f, 0x3d9a13b5, 0xc457bd98, 0xf9d9c375,
+ 0x8902cf94, 0xaebfd3f2, 0x726098bd, 0xd078801d, 0x78dc97ad, 0xbd944e8f,
+ 0x1be8a0f8, 0x50df8bd9, 0x7aa3cc1d, 0x1f0264fd, 0x41910737, 0x8ba63760,
+ 0x380a7edb, 0xa6e3a4ea, 0xb48e0639, 0xef9b4771, 0x063d5217, 0x6c3390dc,
+ 0xa5fa659d, 0xa4efdc34, 0x76c3f7cd, 0xae25fa84, 0x6fd2fe18, 0xf774b212,
+ 0x4aed847a, 0xe7225f84, 0x64bf7b7e, 0x9547f53a, 0x206fa01c, 0x7b458ff1,
+ 0x42c97186, 0xf10518d8, 0x1873b4c1, 0x744af1e7, 0xf3e38afe, 0xb02f88d3,
+ 0xb752427f, 0x15fd187e, 0xd63cce2d, 0x7a53f9a9, 0x8de3849c, 0xa57dd8b3,
+ 0x810a4e1a, 0xb3ffa09f, 0xf4eb8c44, 0xfdad1b86, 0xa212f0de, 0x564c08f6,
+ 0xfae1788f, 0xf2f175f7, 0x197c6d17, 0x05f6864a, 0x343e1a27, 0x9bc718bc,
+ 0x83c434ff, 0xba6f1a7a, 0x0e6f197a, 0xaed1908c, 0x7cd7e6f7, 0xeaf3e4ea,
+ 0x37a62704, 0x7f1b355c, 0xd82c6897, 0xf937f011, 0x6b8e15b8, 0x1c9c33d5,
+ 0xc1245b68, 0xec1791fa, 0x1cb76647, 0xfff078b4, 0x81c4c600, 0x008000d5,
+ 0x00000000, 0x00088b1f, 0x00000000, 0x7cbdff00, 0xd5547c0b, 0x67b7efb9,
+ 0x332479ef, 0x49926649, 0x1d843c32, 0x09212108, 0x11bc210e, 0x11084937,
+ 0x88a80ca2, 0x1f01d68f, 0x4d092060, 0x6f53d5ad, 0x52812133, 0xbd583d6c,
+ 0xf4f47bd6, 0x41ed5837, 0x0108750d, 0x26702783, 0xd0f098a0, 0x7ac0f820,
+ 0x452968da, 0x5a18921b, 0xf5cf6a0f, 0xf6b7df7c, 0x8326664e, 0x73def7a5,
+ 0xd62e9f87, 0xf5af6b5e, 0x5ff9efad, 0x4a9b5adf, 0x500a9fc0, 0x982015b3,
+ 0xe1f95006, 0x06484a86, 0x01203be8, 0x96d40314, 0xfe1b41c9, 0xb1fdb4b5,
+ 0x0cdd45c7, 0x51df8956, 0xf5c02661, 0x950b7e20, 0x06e6c50e, 0xbc95e658,
+ 0xd6801672, 0xe1bfde2e, 0x62a82592, 0xf9af7afd, 0xe89b1ee3, 0x5fff35fb,
+ 0xb800c803, 0x197f7f51, 0x2ffb0ffd, 0x1860a4d3, 0x3b365d5f, 0x978dffba,
+ 0xa6913fca, 0x62d72c02, 0x3e4fc39e, 0x22f2a793, 0xac24becc, 0x8fb74457,
+ 0xcfb92673, 0xe32ff1d9, 0x32d7fc61, 0x65f3c5c0, 0xaff7516f, 0xc8ed77e9,
+ 0x523d48f2, 0xace80166, 0xdb1971b7, 0x7f016e5e, 0x4d2581c8, 0x0065c450,
+ 0x9d0a0152, 0x581998b8, 0x0d0164bf, 0x136308f9, 0x3ab9f7e0, 0xdf86131d,
+ 0x07e3883f, 0x8e30dc70, 0x3801c81f, 0xfae4ef54, 0xae1ef56b, 0x2f82935f,
+ 0x877fe3a4, 0xb8a8b0bf, 0xdfedc59e, 0xdf38fc51, 0x8f0a4be2, 0x93d69b3b,
+ 0x71830b4f, 0xf73f9eb4, 0x0de3fd16, 0xb6bfdc30, 0xbf8b33fd, 0xf9ebf2f0,
+ 0xa7e7f35b, 0xcd3f3ca8, 0xcf0c15ab, 0x180144bb, 0x9a5ceb83, 0x635fcd1b,
+ 0xc6f9589e, 0xfeb96fca, 0x56fcac7e, 0x90c7acc4, 0x32a2f40f, 0xffc38a8d,
+ 0xa6d0264b, 0x437e5e5f, 0xb3f8b1f2, 0xdb2305bd, 0x72c97e01, 0x974f1e1a,
+ 0xbe2b7417, 0x19974142, 0xb752baf5, 0x40efd40b, 0xb2b9ca0a, 0x4889c213,
+ 0x2be7f5d8, 0xf4a8513e, 0x9471f04a, 0x6c7c033e, 0x1e1e5bc8, 0xe425d17f,
+ 0xbcf0da6b, 0x7764148b, 0x0b1f3d11, 0xa8eb3881, 0xea1471a1, 0x6c39601f,
+ 0x155a61d9, 0x635c75c2, 0x547d3b81, 0xe0328a26, 0x937db894, 0xf6e3c4d3,
+ 0x8266c5ff, 0x3e5e01ab, 0x48025998, 0x3cead79f, 0x42011306, 0xbff7e066,
+ 0xdfb9524e, 0x240824e6, 0x74a0fce0, 0x945ec8db, 0xb45c8012, 0x25b4653b,
+ 0x364388d8, 0xd91f612b, 0x8157bf61, 0x2fdbb406, 0x050ef78d, 0xc914076e,
+ 0x4c738fe6, 0x7ef4598d, 0xf61e7bb8, 0xa8a4559b, 0xcb8bb0db, 0xda877eaa,
+ 0x9d580efb, 0xfeff5ef4, 0x699877ef, 0x1780bf9c, 0x0ed78429, 0xe7da8158,
+ 0xf241cc3b, 0xe3e48b1f, 0xfdeb09b2, 0xec560003, 0xb8557f3f, 0xd76e5014,
+ 0x13a37740, 0xc724b9cb, 0x8d7bf238, 0xfece9bd6, 0xe50a31c3, 0xd39740b4,
+ 0x956fdd02, 0x8fd9901e, 0x41c92694, 0x53f61ac8, 0x5a32ead7, 0x3a256c80,
+ 0x7ae1b416, 0x4bdafdb1, 0xb4bf5c4a, 0xe1771f48, 0x9321419f, 0x7ad1085c,
+ 0xf84da8bb, 0x14d012a3, 0x6d4b29c0, 0x97e4ed31, 0xce459e90, 0xc973e7e8,
+ 0xef5ea277, 0xf84bf18e, 0xf7bcd133, 0x8bbcc53b, 0xf726bfe4, 0xb65ffae0,
+ 0x43cdef68, 0x9a4e077a, 0x0e7c59e1, 0x6732b1e7, 0xd0da5f24, 0x973983ae,
+ 0x07fd8bb7, 0xe9153513, 0xc7f49979, 0x9ad1f541, 0xfdf2f53a, 0x940cf6a7,
+ 0xb9787760, 0x13028579, 0x7b4f1d58, 0x3df98632, 0xff3aaf82, 0x22d9f963,
+ 0xf91d9341, 0x5bddb0bc, 0x0465ae46, 0x8f913b1f, 0x80c95ef8, 0x295cf3c6,
+ 0x78fb0d1f, 0x46a25cf9, 0xb9f2fefa, 0xffcd1ad1, 0xfa6be92a, 0x3feffeb0,
+ 0xfe48983b, 0x2aa8f913, 0x2e0317a8, 0xd659f79b, 0xa1f7a15f, 0x6dc13951,
+ 0xf5d16f58, 0x81c4e5fc, 0xefc4f9a3, 0x67de4deb, 0xe3651a69, 0xe48515c4,
+ 0x9c96b737, 0x0d2477c5, 0x7ed107a4, 0x7709d524, 0xfb401960, 0xa40b7d21,
+ 0x1993eb02, 0x36f34042, 0x9534f06a, 0x29abe60b, 0x1c41efc4, 0xe341dbb3,
+ 0xe7a429a9, 0x338bd7f0, 0xf923857d, 0x0a8f52de, 0xd6b4f385, 0x1b2534db,
+ 0x93bd5f60, 0x1ef56deb, 0x57ad5f2e, 0x2c74dcb9, 0x8e20c1f9, 0x3459ab53,
+ 0x7df86d25, 0x8fb0aa57, 0x8867e805, 0x052005ae, 0x0b73a803, 0x5ef5d61e,
+ 0x249b8291, 0x27ae1392, 0x97289f82, 0x08dc9ec1, 0x4d2936fe, 0x35b26693,
+ 0xf28bbcb0, 0x063efc4d, 0x59f3e0ff, 0xdca3fb23, 0x4baaeaa3, 0xbae67e62,
+ 0x961724b4, 0x52f8743f, 0x6e916ca8, 0xb8017c39, 0x5bf512ee, 0xfe380be5,
+ 0x7842f0f4, 0x74c3e310, 0x15f10c14, 0xfd13b77f, 0x402c3a33, 0xca80c1f2,
+ 0xd3a45976, 0x492e7da3, 0x323e70e7, 0xe0c7af9d, 0x30cad67b, 0xe83ed1e9,
+ 0x17be2349, 0xb4767cdb, 0xc843a428, 0xf66e9355, 0x9cde3848, 0x26578b74,
+ 0xa6fa26d2, 0x75fe446f, 0xd884e3a4, 0x6323a3bf, 0xa6f68aac, 0x4fbc6f29,
+ 0x1cd9ad76, 0xcc2b8161, 0x71113dbd, 0x719e133c, 0x9f22bc52, 0xbdf235f6,
+ 0x01c977f3, 0x73886bf6, 0x9e758fc8, 0x7186f64a, 0xd92e6b9e, 0x7fd256bc,
+ 0xf5ed117a, 0x54f26260, 0x5dd0cff2, 0xd6b8ebc6, 0x6f91d626, 0xd8bb17f6,
+ 0x9f0f859f, 0x6dfef7c0, 0xe9fc8010, 0xca1fdd35, 0x9a94f480, 0x907b32f2,
+ 0xe4d2c3ce, 0xfc9f2a14, 0x9701725d, 0x897b92a7, 0x764d073f, 0xa77de695,
+ 0x46ce2d5e, 0x72ded17d, 0xd61d0098, 0x0a1cb782, 0xa1ea2795, 0xe5f51b38,
+ 0x971b7aad, 0x5c9deb27, 0x70f7aa9e, 0x49db1879, 0x76c75e9f, 0xb037b7d2,
+ 0xd85dea9d, 0x1c31e54e, 0xdba2ca97, 0x96bc7893, 0xb42c92db, 0xd0c9838e,
+ 0xfa4fcc6c, 0xb70c4e14, 0x3fe01782, 0xab6afb1e, 0x978c2aed, 0x34a17f56,
+ 0xb3f4f90d, 0xac142aaf, 0xee3c5b1f, 0xbb60bfa1, 0x1fa667f9, 0x9bde90db,
+ 0x8f5a394e, 0xaa9edd63, 0xfa41d8fc, 0x9d112c79, 0xb9b59923, 0xa63a434b,
+ 0xcd1c6f93, 0x3660d76c, 0x7af4d3d6, 0xd95d7cc0, 0xa595807c, 0x42e0f93d,
+ 0xaf597125, 0x577f21b3, 0xa3dffdda, 0xabb025ba, 0xaa2aeca2, 0x7b248863,
+ 0xb641cc97, 0x7b92b1f7, 0x95bbc605, 0x127fff0e, 0xd17b0dbf, 0x91a43fa4,
+ 0x49a9987f, 0xbcb372e0, 0xe1a49383, 0x95bf46e7, 0x49ff458e, 0x25debafa,
+ 0x98cd7db3, 0xc741692f, 0xfa35fb48, 0x96ab38cd, 0x9e66fc91, 0x72a26f2f,
+ 0xeb8b8559, 0x9ab355be, 0x1ccbfec8, 0x94bf7b97, 0x65d07fdf, 0x512dbd66,
+ 0x389c5fb0, 0x8e9bf468, 0x7bb8464a, 0xf8312ba0, 0x69f5e92c, 0xd612637f,
+ 0x8ab27917, 0x0337dd64, 0xb63b5dd7, 0xebe57b51, 0xde576cad, 0xf2e12f24,
+ 0x6990a899, 0x21d0bed8, 0x2a64c379, 0x4a6a3ff3, 0xe4a776a3, 0xd42db625,
+ 0xa6289da6, 0xbbd96cf6, 0xd5a7ea90, 0xa7510a32, 0x2ef38594, 0xb9c5bf60,
+ 0xbe1b5e29, 0xd0fc2a77, 0x85dfd245, 0x04de49b9, 0xf04af3f2, 0x7baa1ae9,
+ 0x9506dead, 0x6958f1d6, 0x4aa38d32, 0x5bd6135e, 0x1ffd286e, 0x2f894744,
+ 0xda892405, 0xd7e10a5d, 0xc3f77f27, 0x6bf62732, 0xd9012719, 0xde70a9cf,
+ 0x85fe889f, 0x026a899d, 0xb38b69f9, 0xb16bde8c, 0x5c4dce48, 0xff5295f7,
+ 0x7d598e40, 0x7e3dc71e, 0x41e39d9b, 0x8c055be5, 0x36df8e83, 0xe542e386,
+ 0xa84bf35b, 0x78126e3c, 0xcaadf2bd, 0x41376e0a, 0xe54a9c98, 0xf7e2dfed,
+ 0xb0fe97b6, 0x1fe38dcc, 0xdf62ef1b, 0x562a7282, 0xf624fc22, 0xbfde8907,
+ 0x77fb9abd, 0x9d0f9948, 0x0b17fec5, 0x38ac8a52, 0x213bb97f, 0x58c57faa,
+ 0x497d5457, 0x2562a8f6, 0x16564fc2, 0x6fd54564, 0xb38a9628, 0xe6fbfa23,
+ 0x57d54427, 0xb38ab994, 0x54dffa23, 0xbeaa2a39, 0xa8aca6f2, 0x1cd342fa,
+ 0x61ea3fe1, 0xf3b0997e, 0x20d965f9, 0xa9fc898c, 0x037df453, 0x3b26efdb,
+ 0xa9f812ef, 0x09f885c8, 0x55d652e5, 0xd8b971cc, 0x00affbae, 0x92667b74,
+ 0x2ebf17ff, 0x83de8f1c, 0x4999fe20, 0x16fc4878, 0x201e2376, 0xdc60a47c,
+ 0xcca7a08e, 0x2bc71d11, 0xff27cd40, 0x84b9d15b, 0x67b954f1, 0x319a1979,
+ 0xbdfa31f2, 0x8161f90a, 0x2ee86243, 0xa5c732ea, 0xf46c62b7, 0xabae06fb,
+ 0x316be9d0, 0x09529bf9, 0x6eb4058b, 0x7ac635c2, 0xb72e3a0c, 0x8ef90a9e,
+ 0xdfff1432, 0xfd2c575c, 0x7f791b00, 0xa0d74b11, 0x8881c74b, 0x760718a7,
+ 0xc43e32a6, 0x3e1e3b9f, 0x254f7030, 0xa45737fa, 0xee48737f, 0xf79785e5,
+ 0x97b8c66f, 0xb8c67bc3, 0x2cd0fbc6, 0xfbc6fcf3, 0x2955cf43, 0xd89df3fe,
+ 0x73ce293f, 0xf9ff14b7, 0x17fdd173, 0x03a36a28, 0x4828f8ed, 0xfbf100de,
+ 0x2410aab8, 0x35ad3d2b, 0x43e8b951, 0x747842bf, 0x1340d9f1, 0x837af395,
+ 0xfeb8adc7, 0x956572eb, 0x1e060df2, 0x8cd75d8a, 0x3a4fb154, 0xabb5497a,
+ 0x5012ded8, 0x68bfb4ed, 0xd3b55879, 0x8345aa3e, 0x6a2fda0a, 0x691b4d13,
+ 0x63e5a1bf, 0x549cf589, 0x52f3e7e1, 0xca318e05, 0x5e7f6567, 0xb6d5962a,
+ 0x8b09479e, 0x60317cd4, 0x94703021, 0x48c15e70, 0x0954779c, 0xa3be683a,
+ 0xbe1d070f, 0xa57e3f08, 0x29146f38, 0xa7e93a5b, 0x91fa45a4, 0x16825b52,
+ 0x391637e9, 0xaff5515d, 0xc7d8aa9c, 0xbd45467b, 0x159a9d77, 0x6bf10fd5,
+ 0x46a0e12e, 0xe42ae40b, 0x5e894d47, 0x7cb177c2, 0xfd7d17fc, 0xe093875e,
+ 0xaadd9813, 0x97138fec, 0x7f82a5bc, 0xa457cfb1, 0x6fea7d8a, 0x6e583d68,
+ 0x35f4154f, 0xe2013ec9, 0x3e933710, 0x4f71d6c4, 0xc3c68aba, 0x77a43d91,
+ 0x22e9bb5e, 0x4ef86f42, 0x29d7d5ea, 0xe9decfa8, 0xc44eefa6, 0x8ba923fa,
+ 0x699e7d44, 0xffac04cf, 0xd45cb534, 0x374d36af, 0x057e017b, 0xc32baf8b,
+ 0xe7dbba7a, 0xfb79c54f, 0x12ad8ecd, 0x24c519e2, 0x787b9141, 0x0588fbff,
+ 0x160a29e3, 0x21734c95, 0xd8ab76ad, 0xa024d72f, 0x25fea3ff, 0xaafc4a9a,
+ 0xdce43049, 0x1d714193, 0x9134ceee, 0x6ff630bf, 0x87be0b76, 0xfcd8e7ef,
+ 0xc25f42b5, 0xa5fa2ac9, 0xca2ff7fb, 0x9ed8bd24, 0xe7f5e4ea, 0x21e799ef,
+ 0x7d74857f, 0x7ffdfa97, 0x3c536ba4, 0x62cc9aba, 0xfc96de9e, 0xf9bb8a52,
+ 0xd21c51e3, 0xbb70bcb0, 0x4213cfcf, 0xcb8c2ba8, 0xf5848f35, 0x4bc59746,
+ 0x90fb7d38, 0x6cacaf7c, 0xb213f3d4, 0x9c8de85d, 0x1bb8da62, 0xfaeb9fcb,
+ 0x3bcd14f2, 0x1819e683, 0x01f51cb7, 0x56e3039c, 0xe93a8a14, 0x0d172c83,
+ 0xf81ede10, 0xf7979256, 0x7e0763c7, 0xbfac03fb, 0x97be4777, 0x8907f470,
+ 0x82ab3f82, 0xb07b1a13, 0xbc1acd3e, 0x3e748c2a, 0x967fe694, 0x6b36e0f4,
+ 0x9beb1270, 0x8d126363, 0xfbc0692f, 0x877f6310, 0x32d538fb, 0x1fee2471,
+ 0x88d82f39, 0x11ccb7cf, 0x45e6367c, 0xee28da9e, 0x3c5b37bc, 0xf9c0e837,
+ 0x06ff885b, 0xc074433d, 0x03c72758, 0x45a47910, 0x61e443b2, 0xbce260ff,
+ 0x1f192d49, 0x359cf7d6, 0xcfaebef1, 0xe68057d8, 0x9b933d58, 0x27399e78,
+ 0x6c4cc936, 0xd4ccff00, 0xb6af4859, 0xfa7de7ad, 0x7de8ee8c, 0x7f4eacfa,
+ 0x9bdf03a9, 0x7cfc7ef5, 0xdc7d3cc8, 0x299410d9, 0x89e9cf5e, 0xdf4f37ee,
+ 0x1f3bcfa7, 0x54cdfcfd, 0x868dbe3d, 0x8e7991d1, 0x33ff7d3a, 0x0a427c78,
+ 0x3af929e9, 0x516ef919, 0x3a9d9865, 0xeb5a37ec, 0xf90e5fb1, 0x85971b47,
+ 0x11779da7, 0xa8f56dfd, 0x93f216d0, 0x7b0d2e1e, 0x770d3c2a, 0x7988d4c2,
+ 0xf837bd74, 0xe0bef838, 0xdc9eb4e3, 0xbac7cf9f, 0x410cd3b9, 0x739d7875,
+ 0x820d3e75, 0xd3a0f3e0, 0xd99e7cc2, 0x61e9cbf5, 0x98f5647c, 0x5f588d40,
+ 0x6a089a82, 0xe7b53f84, 0x65d546a6, 0xce3a3e43, 0x9f8fae98, 0x351d1de4,
+ 0x0c37818e, 0x5a9abdf9, 0x643849de, 0xe31d63ba, 0x13d9948e, 0x3e2dc6a2,
+ 0x64272b1e, 0x2476e11c, 0xd7089ff2, 0x70a2569f, 0x80772cc6, 0x3fb30038,
+ 0xc9706254, 0x68ec9976, 0xe7e8d9ee, 0xc8cbb4e6, 0x84fc72ed, 0xef9f3fa9,
+ 0xe9f9fbfe, 0x99f9a2d2, 0xcfcd1156, 0x3f345f74, 0xf3455733, 0x9a3f946d,
+ 0x4dd6632f, 0x6abf6a89, 0x7d545163, 0xa37383fc, 0x006167fa, 0xdc4fac8c,
+ 0xffaa24ba, 0xa22beda4, 0xba9f93ea, 0x5e7faa2d, 0x7b544d70, 0x2baacefe,
+ 0xa8617f92, 0xb11faa2e, 0xf20df4d7, 0x1fedbabf, 0xeff9e6a2, 0x34a2ff96,
+ 0xcbaf2f3d, 0x438e997f, 0xc7fa1a5c, 0x4538e1a2, 0x93f215e9, 0xbe37f6ae,
+ 0xa04bfca0, 0x53bce544, 0x1b780960, 0xd909edb1, 0x1b5f9127, 0xa136ac83,
+ 0xc13268df, 0x8ff7f23a, 0x879c4c9a, 0x2abcec34, 0xaa8be04d, 0x9ff7e134,
+ 0xf8a69b46, 0xeccff066, 0x78449ede, 0xa0993643, 0xe29ae29b, 0xc671bf65,
+ 0x716be101, 0x7034793e, 0x7934ab5e, 0xa899b2f6, 0x329bf287, 0xd1e51fef,
+ 0x7d71507e, 0x3f1fc78d, 0x8b9ff941, 0xfa4a9b0e, 0x03faa72a, 0x7d70b714,
+ 0x2461e7a1, 0x3eaf795e, 0x49f6893c, 0x67957d46, 0xbfea66e3, 0x93858eea,
+ 0xf43aff68, 0x498e8efc, 0x88721165, 0x388adf5c, 0x697be8f8, 0xc4673f22,
+ 0x6aacdb87, 0x6bca0f63, 0x3ffc2c9a, 0xa5ef85c6, 0x903ffae1, 0x9c0b361e,
+ 0xbad33015, 0xde724e31, 0xba8085df, 0xe194cb0e, 0x8d7ea478, 0x84c1f54a,
+ 0x26f9dc68, 0x08fb4411, 0xffc72a5b, 0xbb7f0d5b, 0x36f98f2e, 0x3fee88e8,
+ 0xc144f778, 0xd7236fcf, 0x2c67df90, 0xdd061d62, 0xfc3f75e7, 0x7b87eea9,
+ 0xe446ffc9, 0x78edd79b, 0xf5f0893c, 0xa7815c99, 0xe8cfe78d, 0x4d267d72,
+ 0x3bf5e9e0, 0x79919c13, 0x2b90eac7, 0x36db5eaa, 0x423679ca, 0xeb1bd70f,
+ 0xad0a4bf0, 0x3f6e8363, 0xc93d9dd5, 0xf1e301b7, 0xdc70d3a7, 0xbf171d9a,
+ 0x37de8fbd, 0x3888640d, 0x6ef9e01a, 0xd7180f79, 0x4415f2df, 0xd297d2e1,
+ 0x25e57e44, 0x95cb0ba2, 0xdf513858, 0x776c6256, 0xfcc6f951, 0x7c3bb272,
+ 0xbeb0961e, 0x84cc13ac, 0xb3fb96d3, 0x53f4c4cc, 0x2f677de0, 0x9a5f6d2e,
+ 0x04dcf3ca, 0xc5c5333e, 0x9d5dbf77, 0xc686fd44, 0x4319c633, 0x2bd459b9,
+ 0x419cc057, 0x246b9af9, 0x9f380dc6, 0xeefb9e8d, 0xe299b318, 0xbbdf31af,
+ 0x0ef0bfe0, 0xf00ac5ea, 0xf8c6b8f2, 0x7e51a900, 0x90cb03f8, 0xbf24ed1c,
+ 0x98532eba, 0x677539f2, 0xd1fe7cac, 0xebf030df, 0xdfce9007, 0x57b17d55,
+ 0xbb7fba42, 0xfb57e07a, 0x4fadf9f0, 0xb5c5dfa1, 0x87fddb66, 0xc3ce22d3,
+ 0x917ddcce, 0xc8f10ced, 0x33924ff3, 0x25eac97a, 0xeaa0f8fb, 0xbc489ca5,
+ 0x616d227f, 0xb307bd27, 0x479ee2d3, 0xab2beec4, 0x6ed93f48, 0x8699c655,
+ 0xeba7de5e, 0x930bdd65, 0xd25d79f9, 0xfd447ad0, 0x57f39979, 0xbcac0775,
+ 0xd7477fbf, 0xbf17aa87, 0x9f991998, 0x54bd416b, 0x7274a873, 0x2a9ce749,
+ 0xf1cf66f2, 0x6fd4a9c1, 0x21efeca3, 0xe978393d, 0xefaa64e3, 0x5e4bf379,
+ 0x6574dc0f, 0xf323f7f4, 0x9b5cf922, 0xf92ef034, 0x567dea93, 0xa550f295,
+ 0xdd8ef2fb, 0x4e9af58e, 0x9eb83bf4, 0x239eae0b, 0x6a7ed34f, 0x979404bf,
+ 0xb02709aa, 0x9569af73, 0xaac79482, 0x65bddb6a, 0x9aabd60c, 0xba931797,
+ 0x3f0b26d6, 0x0522d356, 0xa7f03c69, 0x748a7f31, 0x357d28db, 0xb00b1fef,
+ 0x18a8efbd, 0x787d5cff, 0x4ff459ea, 0x9d9f2d7d, 0xb4363a23, 0x763f3959,
+ 0x196c292e, 0xd85ef383, 0xea02852d, 0xb9f6ddb0, 0x5d6a3ec4, 0xcd0b31e8,
+ 0xe5b9eebb, 0xfb0f04d9, 0x90b49df6, 0xfad75c7f, 0xbcfeb958, 0x20fb8458,
+ 0x9dfac5db, 0xf322931d, 0xfc21f749, 0x81f8c883, 0xf70805f4, 0x09e39082,
+ 0xdaab3e5d, 0xbb123627, 0x7dedafd0, 0xe6bf625a, 0x3bdf9374, 0xffdfebb8,
+ 0xffdde695, 0xff98932f, 0x7fc657c5, 0x4f1805f0, 0xc0f3e8d4, 0xda1653f9,
+ 0x9ab4d61f, 0x173bc5cf, 0x77dbbefa, 0xf0c67b95, 0x571636fe, 0x3880b16f,
+ 0xc10099b7, 0x381e29e7, 0x91ab2c06, 0x07511f9e, 0x0e7147a4, 0xdd60d658,
+ 0x71467646, 0xc608e3c2, 0xb9d717db, 0xf70f9e15, 0x9de31b08, 0xedead657,
+ 0x858f6aa5, 0x9e3570f2, 0x75e90b5e, 0x7113f84d, 0x51f6df5e, 0xbf6716b9,
+ 0x7e16ed5c, 0xc303d0d3, 0xa7d2ebde, 0x87985db0, 0xc6c860e2, 0x66b85f76,
+ 0xdd53e280, 0xda0ed47e, 0x03fcb817, 0x6f607744, 0x2beb4a82, 0xccc9f7dd,
+ 0xfe79889e, 0x5187dba4, 0xa3f979af, 0xe7e266a9, 0x2aa68f9e, 0xfbcfc349,
+ 0xe2eb1c32, 0xddaa55e5, 0x4e6f4e22, 0xb68f9df6, 0x186f0483, 0xb769ade7,
+ 0xda07f9f3, 0xe28e96c1, 0x75b83b48, 0xf3d20edd, 0x168bd976, 0xcb6d3501,
+ 0x3fdc0dfd, 0x91e24bc9, 0x480616db, 0x8fa7650f, 0x8afe13f5, 0xcfd4cdf3,
+ 0xae52267d, 0xe91b7fdb, 0x4f08e291, 0xd46bcc8a, 0xd17e7a98, 0xb75c9121,
+ 0xaf9a266b, 0xc96fd808, 0xef0f5f0e, 0x54338a9f, 0x9e1ec7da, 0xa7c40e51,
+ 0x38901e9f, 0xf54e6b5f, 0xf922cd6f, 0xbfb9951e, 0x010bf0e5, 0x9bee973a,
+ 0x9f44c506, 0x4e9fdeb1, 0xe38c830b, 0x2f042e6c, 0xff79bb4d, 0xdfd21e2d,
+ 0x611fa69f, 0x86f7617c, 0x234afc80, 0xe7ca06e2, 0x61420bd8, 0xd721271a,
+ 0x3ce32c57, 0xf3276e79, 0x7bf562cb, 0x4d941f29, 0x4d875c75, 0xfa23adf1,
+ 0xb144ee6c, 0x657b1e9f, 0xb23eba79, 0x1bce857f, 0xe92f9cfd, 0xed3d0b33,
+ 0x5f180abb, 0x399d1df3, 0xbe09a4d4, 0x6b2e76c1, 0x46a63adb, 0xf044dbc6,
+ 0xdf79e8db, 0x44bc5bfe, 0xd75139bf, 0xb6448cf7, 0xfff9d88b, 0xe499f499,
+ 0x35b35a6e, 0x7c4cf88b, 0x7bf64753, 0xf067ef5a, 0x2e7f1403, 0xaa922bd9,
+ 0x8d0fcbc5, 0x4e3c9777, 0xea9cdd72, 0xf01575cb, 0xc300acf1, 0x76b8c49e,
+ 0x57fffd87, 0xe91fff64, 0xf8a2dcfc, 0x4ddfc46d, 0xf16cdd7a, 0x7fb64ea9,
+ 0x0ff34a9f, 0xfc746fad, 0xf6e9b5f5, 0xff8265ba, 0x4fb7d71b, 0x15399f5f,
+ 0x4bc68df5, 0x4e67ee06, 0xff48060e, 0x78a0929a, 0xec3e3e13, 0xdd90f72a,
+ 0xc5f4396d, 0xa6f7b238, 0x2807af24, 0xd66075af, 0x2dfbb22a, 0xfd636fa3,
+ 0xbc85f4ff, 0x9e623922, 0xad256913, 0x697ebfe4, 0xcfe2cbac, 0x42fc75a5,
+ 0x5d6323d7, 0xabdf6ee9, 0x11bc88ee, 0x915f758c, 0x9fbe80fe, 0x17f1eaf3,
+ 0xff9c73f7, 0x2f4487eb, 0xd6ee279d, 0x3e02b771, 0x783b1bd6, 0x1a55c655,
+ 0x1f7ba31c, 0xd8261d8d, 0xe4a6cb46, 0x5d39c454, 0x36326cb2, 0xb70d9a7d,
+ 0x4c6c74e6, 0xebba6fed, 0xbd213496, 0x0b2021fb, 0xaf9d167c, 0xa4d24d00,
+ 0x6bc53cc8, 0x14f3f155, 0xc91bf8cf, 0x9e56ff2e, 0xb4d84e62, 0xf7f292da,
+ 0xbace2be7, 0x9f3df7a3, 0x2a2655ba, 0x31f42b94, 0x8a0c4e14, 0xa74c17bc,
+ 0xf133537d, 0x067bff12, 0x2df6cad7, 0x5cdae5f5, 0xfbee4f68, 0x8b1d6db7,
+ 0xd62d9776, 0xfa46f54f, 0x3dc0a77b, 0xd78ff943, 0x46ee30a6, 0xfef3273f,
+ 0x12d3a9df, 0xc462b723, 0x88f7c06b, 0x27f2a352, 0x265f23e1, 0x4aed7e93,
+ 0xb922df55, 0x7cc9740c, 0xe941244f, 0xd8e2b8b1, 0x03c23ed9, 0xd38bf7e8,
+ 0xd6c43ec5, 0x6d17ce26, 0x317ec6aa, 0x269ce9c1, 0x79c5d847, 0x579fc8b7,
+ 0x9c60f91f, 0x05dc3105, 0x02e4f1d3, 0xdec37f1c, 0xc34a6496, 0xf6f33fad,
+ 0x5392ba4c, 0xe91df8a2, 0xa54ffeb8, 0xc236391d, 0x53835ba9, 0xf0a13f89,
+ 0x93f21484, 0x94040a85, 0xf1f138a2, 0x14de22a9, 0x87c53cd7, 0x3ed850ff,
+ 0xe5e12d7d, 0x2f58b0da, 0xa6c661cd, 0x7ae036bc, 0x2a635b5f, 0x6ffb578d,
+ 0xbf934607, 0xe05d297a, 0x4d2f179a, 0xa02bef11, 0x74acff50, 0x41e7ae97,
+ 0x5f0be513, 0x7d8cf3d2, 0xcfdc4c97, 0x6db0bf98, 0x3d44eca1, 0x3f6f0828,
+ 0x76cd79c4, 0x4df24aab, 0x3f040e78, 0x771813da, 0x0c5c1ed6, 0x5dfae714,
+ 0x7db095e0, 0x6fc0e257, 0x0e061f49, 0x773a5558, 0x876e704d, 0x977f1c54,
+ 0x0f2b4f7e, 0x31c5b215, 0x2f98dcfc, 0x94e7fda1, 0xe0bd2413, 0x6504dff3,
+ 0x88e35c3b, 0xd31277e4, 0xd5eba25d, 0x89b0c4ae, 0x260645ce, 0xe9875ee1,
+ 0x7813a61a, 0x3cce835e, 0x2cbbfbf6, 0xe07ee703, 0xa49cba66, 0xe8207907,
+ 0x2ac9f684, 0xa704d1f9, 0x7048ebc6, 0x3480deaa, 0xa9daae92, 0x6ed0fc08,
+ 0x35e7251e, 0x6baed877, 0x36eb8713, 0x135d85b4, 0xff8f3f40, 0x8f3a36d5,
+ 0x8393aa1f, 0xfefc3d99, 0x6c2fe92d, 0xf9cb1a6b, 0xa28c80bd, 0x949963b6,
+ 0x7954eb4a, 0xb545e87d, 0x07c122f4, 0xb767afba, 0xfea1f689, 0xaa0ee7a8,
+ 0xaf3f443b, 0x925f69d5, 0x8742f6c5, 0xf07843d7, 0xee7c297e, 0xded7b45a,
+ 0x05297cc7, 0xd35eaeb8, 0xb19a07a1, 0x87569fdf, 0xe93ee872, 0x1aff5673,
+ 0x3e57cfd2, 0x2148f35c, 0x665ddbf9, 0x9df9256f, 0x18cfc09e, 0x5668bf87,
+ 0x1dd845b7, 0xe0c81d8c, 0xf33180fb, 0xf4d99ed4, 0xfdd7c233, 0xce9525fb,
+ 0x03cdfbbd, 0x9aee88e3, 0xe85a3ff6, 0xfeed64be, 0x4b4f188f, 0x9a1afe19,
+ 0x035b766f, 0x039b6bdf, 0x1b5ef9db, 0x9fbe43fa, 0x7f08f218, 0xe73a7832,
+ 0x390886d9, 0xec2e913c, 0xe3fc060d, 0xebb55e29, 0xf6907af6, 0xedee58dd,
+ 0x8d2275b8, 0x07cf57bf, 0xc035ef18, 0xf7c431a1, 0x971af04d, 0xa0fef3c6,
+ 0x967a4152, 0x4eedaeff, 0xa3ffa22d, 0x3dbf02e9, 0x66702e9a, 0x89bf8676,
+ 0xf1df5de8, 0xd69925b1, 0x8e343679, 0x4521b9f6, 0xf1c6714d, 0x1bf64323,
+ 0xcab54f63, 0xd7fa8580, 0x2bf6079e, 0x14a6ef28, 0xef4bdf94, 0x8d594db6,
+ 0x4ca2f7cf, 0xe2ae2852, 0xefe294fe, 0x0c6fb35e, 0xe7786ff5, 0xc7e4a9f3,
+ 0xe74f481e, 0x607e7ff5, 0x1be278fd, 0x22497fea, 0x606ed9d9, 0x69d866bf,
+ 0xbe29d901, 0x5ffa405f, 0xf63cf54c, 0xdd2cbbcb, 0xf72ed84b, 0x12ec809a,
+ 0x01ed9ff5, 0xf849dff5, 0xf689c0ae, 0x664fefc0, 0x6dd5df3b, 0xa32718d2,
+ 0xf5c49f5f, 0xbea91b92, 0xc9ccbbab, 0x05f74e76, 0xc35ec88a, 0x109c7887,
+ 0x9d1224c0, 0xfca8be04, 0xe9993b88, 0xe7e5fc36, 0x86e3d06e, 0x75c5e29a,
+ 0xca3965d8, 0xa4e2223e, 0xf4711ba8, 0x9edb33c9, 0xee817b40, 0x0fdc28d4,
+ 0xffbf0bef, 0xd5563d5d, 0x59773ebd, 0xeeb3ae33, 0x07edcc84, 0x585e7df5,
+ 0x7a4393d7, 0x86e2867e, 0xefdc5d3a, 0xb033e7a5, 0x675df74e, 0x094b1b6a,
+ 0xd8aecd63, 0xb9ca987e, 0x412950be, 0xbaabf9c8, 0x99859b0f, 0xb5fe93e7,
+ 0x9f2eba1e, 0x9ff5cdee, 0x920242b1, 0xc0e5fad8, 0xb5c45f6f, 0xf910703d,
+ 0xe14e271f, 0x10ff5872, 0xcf018d6f, 0xc97ef6c8, 0x4bbd23f0, 0x5afb1f48,
+ 0x123ae1e5, 0x4d8a8352, 0x3fd277f5, 0xbac016dd, 0x9f7b433f, 0x99c7e254,
+ 0x3f49f7fe, 0x997e4ffb, 0xf7b96641, 0xb7c7d8b4, 0xd27cb45a, 0xb809d69f,
+ 0xa7a38db5, 0x3c8ba5af, 0xe215b14f, 0xa57e4b9e, 0x009cc1c7, 0xfef1223c,
+ 0x5106765c, 0x655a17ee, 0xe7f882cd, 0xce56043c, 0xe7a37f23, 0xfd01ef6f,
+ 0x941fe1a7, 0xf57abdcf, 0x182bc21e, 0x627deeb7, 0x89bfb9c4, 0xbb6d69f4,
+ 0x6b84ff04, 0xfc4cf75f, 0x5e46097b, 0x1db6beeb, 0x3ca0c647, 0xee8b9eab,
+ 0x9ee861b7, 0xbdf7887b, 0xefa39a1b, 0xae957c1b, 0x308996e3, 0xea0b7091,
+ 0xb307fb13, 0xd4569d02, 0xfd3257df, 0x7e5e109f, 0x84f824c9, 0xf2ed957e,
+ 0x671eb713, 0x1a3f844a, 0x8f7c00b8, 0xe8676f28, 0x99d7dd30, 0xa5e59cdb,
+ 0xa22ae639, 0x165b6e7d, 0x825019c7, 0x9837dd32, 0x19cbf9ad, 0xd3b4075f,
+ 0x9d642f74, 0x89c127ee, 0xa3bf287f, 0x8e9d6baf, 0x460beee7, 0x82073dd3,
+ 0xdacf348d, 0xd1fee29d, 0xbff19dfa, 0xc7d5a813, 0xc9d4f0d9, 0xac0e9423,
+ 0xabf7450e, 0xdb53f9d5, 0x05bcfd16, 0x9f181278, 0xfccf7d11, 0xfc43ef4a,
+ 0xc5f02cc9, 0x4638fadb, 0xc219b5fb, 0x7920d67f, 0x410ddf24, 0xb37a4839,
+ 0x0b240a4e, 0xd58e0b7c, 0x865df748, 0x65f7e8be, 0x73f9d6ef, 0xbc2fae97,
+ 0xfabf7c2e, 0xe7482919, 0x24ff7780, 0x427bfe9a, 0x1f49cbab, 0x5d6af562,
+ 0x6df199b3, 0x10b46c15, 0xabd58dbe, 0xd97d21aa, 0x1638a16e, 0x7e354fab,
+ 0x0b7432e9, 0x4b7ffe5c, 0x98737af7, 0xffeb4cf3, 0x3ca5e4a7, 0xdfadbdd4,
+ 0x745e50b1, 0xf9087da4, 0xa27a1956, 0x5defebaf, 0x7c86edcf, 0x9614c0a7,
+ 0x15da456f, 0xf1a283ee, 0x50cb6ef4, 0x7cf3929e, 0x38139d83, 0x51e86e3f,
+ 0x3ae538ec, 0x14fc5f2e, 0xada17970, 0xa2f84ed4, 0x2bc9b8ff, 0x4c7f9ca9,
+ 0x4c3e442e, 0xe103203f, 0x89f6fe8d, 0xfe90078f, 0x37c513a2, 0xfa7cbe52,
+ 0xd83f8c09, 0xf8b3a7be, 0x115fe457, 0x7d91a4e1, 0x4ecaec2f, 0xc783bdfb,
+ 0x7fddf8e1, 0x4af1e8bc, 0xcbc7c3f2, 0x095c698a, 0x787ee9db, 0x1a871e91,
+ 0x7bd9178e, 0xfdd1e222, 0xbedf2219, 0x47fbf3c5, 0x78b05f69, 0xf94bd9b7,
+ 0xff66c58e, 0xafa404a6, 0xdbc905e8, 0xe91db380, 0x8d24f43e, 0x52a4f68b,
+ 0xeef166be, 0xf6a21def, 0xd3125dda, 0x28bedfdf, 0xc7c5177f, 0xb8a5eca0,
+ 0x577edfd7, 0x7384bdc1, 0x7053dc0e, 0x477cc457, 0x595f8552, 0xe399957c,
+ 0xfb68ef71, 0xcf292b2f, 0xff60eda9, 0x1eeafbd0, 0xb0577f0b, 0xae0f024b,
+ 0xf0e788f3, 0xbd0f89af, 0x085a4efb, 0x9eb697e4, 0xf1c4f4b4, 0x017946cf,
+ 0xce6171b7, 0xf0b76ebf, 0x7fbdca3d, 0x6b7ad0b0, 0xf388fb9e, 0x126d5569,
+ 0x67aaa7fb, 0x794aa0e4, 0x58af039e, 0x9a6b3f48, 0x8accc825, 0x3b73376c,
+ 0xffaa51f9, 0x65f859b1, 0xe8d7ef43, 0xbde86e7a, 0x746b0761, 0xd6d775ff,
+ 0x17bf3d68, 0xf1a32db4, 0x579a7bfd, 0x7ba03df3, 0x5ff7c7b6, 0x4b5c1f86,
+ 0x2b8c52fb, 0xee8a9f6b, 0x7e90df77, 0xc7bfd807, 0x3257c9fa, 0x3cd8f3f4,
+ 0x1efd23c8, 0xaf19af0c, 0x7e7d3da0, 0xc43c6ab2, 0xd71e3bc9, 0x8f1180f1,
+ 0x8e26c307, 0xfafdb167, 0x285a2eda, 0xfe76d68e, 0x796bf199, 0x872c67fb,
+ 0xbe0ef6ca, 0xf83d7aaf, 0xaf1f1037, 0x093bb76f, 0x08f65747, 0x6ed25fbb,
+ 0x6a25060d, 0x7c91350f, 0xef8a0ffb, 0x4aaf023b, 0xf740a38c, 0x7e756b7f,
+ 0xb7f9d5ae, 0x6367f716, 0xbe8adee8, 0x772fbeff, 0xe2ba11c7, 0xdf3fa351,
+ 0x993875d0, 0x8404b8f8, 0x12125a7f, 0x8790c9fe, 0xc6465f11, 0x936f81d1,
+ 0x5bb7d73c, 0x52f8bef9, 0x6d2d3fdd, 0xc593df16, 0x51fe8bfa, 0xddff9176,
+ 0x8d8de82b, 0xd1ad35a7, 0xd232bbfd, 0xea0fdfd9, 0xc313f878, 0xa8f2e8df,
+ 0xe53b001c, 0xb2a897e7, 0x756fc837, 0xe77f342b, 0x63cf8954, 0x2989d53b,
+ 0x194beef1, 0xce3a9be5, 0x28cbea37, 0x43fd864f, 0xc88eedce, 0x998dfc7d,
+ 0xcd54af02, 0xcf240391, 0xb2cf7d88, 0xfbb8aca2, 0xba44c81e, 0xd77b18df,
+ 0xee45a64f, 0x391db47b, 0xf23f67a4, 0xf7495e3c, 0x859b6a8c, 0x8d9be87f,
+ 0x8e10a6e3, 0xb5c5c607, 0xed20d6cd, 0x4f516a4f, 0xd2307bf8, 0x76bfb20f,
+ 0x07e91169, 0x991c1bee, 0x3a72cf48, 0x2ff5c4aa, 0x8e38c36f, 0xfb2f2fc3,
+ 0x2baaf58c, 0xf91bac5b, 0x1f6f1996, 0x6a1fec61, 0x6a9c092e, 0x7a51af3c,
+ 0xd3511f78, 0xb749ee2e, 0x5c62fa1e, 0x7fdbd216, 0xadc63fe0, 0xa64172c6,
+ 0x25adbf88, 0xbee98fa1, 0x6cbbe7cf, 0x90e8f171, 0xd89a97bf, 0x3dcc6a0e,
+ 0xf6578c19, 0x859c2e23, 0x4fedf37e, 0x7ad1df79, 0xca4ee128, 0xf1adf5c7,
+ 0x837e778f, 0x13601a9c, 0xd04ddae3, 0x9ee125c4, 0xd6b81c48, 0xdd0fee29,
+ 0xaa49c7ab, 0x7d7a8c3f, 0x505df62f, 0x03eecf14, 0x2349e65b, 0x1bf0dded,
+ 0xafbebad5, 0x85b1d82f, 0xf163e08e, 0x476eb551, 0x2e39fc88, 0x1ba2e2c6,
+ 0xb4f5a333, 0xc644ede1, 0xb25dfdb9, 0xc8c47293, 0x268c5fd7, 0x7ef887dc,
+ 0xeb3c9c42, 0xf65ebaa7, 0x0dbee7ea, 0x9be665b3, 0x0d288e69, 0x63fc851c,
+ 0xe93fe97d, 0xcb1c5208, 0x04caf83f, 0x9dfaff92, 0x2445e7d1, 0xdfdf3f3f,
+ 0xaafcb20a, 0x433e7643, 0x3a5fda32, 0xd214caf8, 0xbfb786b3, 0xf97211cc,
+ 0xbee2c722, 0x29467d3c, 0x6bff6249, 0x77fec492, 0x4c93d2af, 0xfddaaefb,
+ 0xfef22fb2, 0xbbe721bc, 0x4501fd75, 0x65d7f3ec, 0x686f5caa, 0x3a617a17,
+ 0x7f9c4a20, 0x98f3c8a5, 0xed11fe79, 0xdf2fa825, 0xe880b710, 0x9ad7d942,
+ 0x6aef5807, 0x9e989a4f, 0x198393da, 0x05ef11d9, 0xf24cdc68, 0x801b0d7b,
+ 0xc81d88fd, 0xefa52ebf, 0xf4beb10f, 0x59c604fd, 0x523c2647, 0x64adce29,
+ 0xc0f5bf20, 0x239355db, 0x3d05fffd, 0xc1f103ee, 0x09e72843, 0x87cebf31,
+ 0xcf42b04d, 0xae3d0813, 0xee2c71d2, 0x8ec89aaf, 0x5757f763, 0x0e1b938a,
+ 0xc7f28158, 0xf9581fb5, 0x07e7d03e, 0x1dfef2d6, 0x9327f92e, 0xffbf019f,
+ 0x381f2a6a, 0x3d3276b8, 0x7de0fcff, 0x53de7357, 0xaf9514da, 0x1e7d1008,
+ 0x797f51c2, 0x97c276f7, 0x90e30a5d, 0xefd3aea2, 0x9eeaf9d2, 0x9b7f3356,
+ 0xc677bd59, 0xc22481e3, 0xe94b454f, 0x9d3d9dbb, 0xe21feb0a, 0xd947032a,
+ 0x289d4719, 0xe3851c66, 0x165c82f8, 0x71a4ab1f, 0x5314944f, 0xc9db0937,
+ 0x1c274d9f, 0x55c618e5, 0x9cff3d06, 0xdfd9f829, 0x13f9c091, 0x3d082609,
+ 0xba28ec83, 0xcebeb437, 0x9b436438, 0x86bdf51c, 0x4ceedef1, 0xd7b0ae71,
+ 0xa490b3d0, 0x16ed1eb1, 0x3db686e5, 0xf58eb419, 0x49eb10e6, 0xb459b343,
+ 0xd02512ef, 0xfe0ccdf9, 0xfc4038d8, 0x508f4639, 0xc12c4b2e, 0x77db84b1,
+ 0xea079d0f, 0xe28239f7, 0xe7635d5e, 0x686efe44, 0x3b8f73b0, 0x4e39fc5e,
+ 0xda4833e7, 0xcfb12cd1, 0xf3af6d89, 0xd1c67c88, 0x1e2fc233, 0x1c9fe85d,
+ 0xa0063fcf, 0x25fbec44, 0xe6ad7e5d, 0x86e7788a, 0xdf223d1b, 0xe06c73b4,
+ 0xef71e928, 0x373e04ee, 0xfc8975ec, 0x974b696c, 0xac9fdf42, 0x5066956f,
+ 0xfb9f5a3c, 0x829f7f1e, 0x83f662f5, 0x6e7cfde1, 0xbbbcdd5a, 0xc7438b5c,
+ 0x1f111eb5, 0x01dfe897, 0xbd57d08f, 0xd37814fd, 0x23da7df5, 0xaa735e74,
+ 0xdf14ecd2, 0x4aef8999, 0xf9fdd06f, 0x199bd78d, 0xd5029d37, 0xc43fce2c,
+ 0xdd32c539, 0xfba0df2f, 0x3bdf11f9, 0xe99b033f, 0x7bf6229c, 0xdfafc367,
+ 0x02bf8fac, 0xf6371e34, 0x759bf5bb, 0x2fb3783c, 0x4ca5f9fa, 0x40e6071d,
+ 0x10f3f90e, 0x1fbe17c6, 0x71c09791, 0xa4e1697a, 0xbe8338b8, 0xeff55703,
+ 0xe434a9c0, 0x1ef790de, 0x1da3bfc7, 0xdfcd7e67, 0x80499c13, 0xc5ce7109,
+ 0xe19fe386, 0xf2126e3f, 0xaa2dcfd6, 0x4346829d, 0x077017ee, 0x331f9916,
+ 0xe7463ee4, 0x3df1ffff, 0x22505ca0, 0xcacf25f3, 0x3a1e31fe, 0x32f5b09f,
+ 0x7015c6fe, 0x8d75c41c, 0xce35d7d3, 0x2edf111a, 0x571d5a8c, 0x97d7877f,
+ 0xc471101a, 0x9e4765cd, 0x75627195, 0xfbefe248, 0x5f62c3aa, 0xf6265d5b,
+ 0x02ad39b5, 0x49bcaea7, 0xbb126a0a, 0x9f44d3c3, 0x6ccb3fa1, 0x7a180f02,
+ 0x5d2fc432, 0xf09da87f, 0x3e3a0dc1, 0xc9a3d588, 0xf94e5dd0, 0xc9345be6,
+ 0x472af74b, 0x6abf3f7c, 0xeee4ebda, 0xa83fa72f, 0x22effc6f, 0xf7d1eac4,
+ 0x0f12fe3d, 0x07bad3e5, 0xb8e21657, 0x38fef347, 0xe6a6f48e, 0x2df37632,
+ 0x3b13888f, 0x7ca3811d, 0x3f45a4df, 0x6bc96fef, 0x747e21eb, 0x5ec7e302,
+ 0x3a96f757, 0xbcf9ab81, 0xc09c3abf, 0xb75643df, 0xb0bbf9db, 0xc486d6ea,
+ 0xdb7fe429, 0xeb1daf65, 0xcb27ad95, 0xc5959f88, 0xad4a3ee2, 0xb38bdc5d,
+ 0x10b7fdb9, 0x3b7bd77d, 0x2df9cfa2, 0xfba8bf3d, 0xf58f3d06, 0xa3091b6b,
+ 0xf9f7ffa5, 0x5f3a8d9b, 0x662ebaea, 0xfea9c14c, 0x26afe690, 0xfd7fec7d,
+ 0xd71d0b45, 0xa5794ed5, 0x6d88ae9c, 0xefdca8f4, 0x268ee6fa, 0xf41af34a,
+ 0xf93a6477, 0x707351f9, 0x82d2e32c, 0xd30fbb2b, 0xa98dffb0, 0x3afaa714,
+ 0x225aa6ba, 0x0eb7bbf4, 0xf91c73fd, 0xb7498035, 0x494b855b, 0x25e3a15a,
+ 0x07b5c761, 0x3e50670e, 0xb7ec97a2, 0x9277ca80, 0xdeacb1b3, 0x12792a7d,
+ 0xa2bd96e1, 0xed19c21c, 0xa503f732, 0xa4e6e727, 0x3336fa48, 0x6242177d,
+ 0x9c9e801c, 0xdb230b1b, 0xdb5fff1b, 0x27a4d3ff, 0x289eb6d5, 0x84f837fb,
+ 0x3efe7cbb, 0xcad07037, 0xbce808f7, 0xc72115c6, 0x347f7457, 0x644b370b,
+ 0x7ce873a7, 0x3b41227a, 0xbaa0ee05, 0x95256102, 0xb2c38bce, 0x96377fb8,
+ 0x7d4cf7fd, 0xb84a59fe, 0xcee9ee83, 0xe737cfd1, 0x5bf73742, 0x6a5c0300,
+ 0x8befe4e0, 0xe5cbc04b, 0x29785b6c, 0x5082f1c1, 0x099fbf88, 0x73ae2867,
+ 0xe63bfd36, 0xe61ef238, 0x0ce7029b, 0x0e74c87e, 0xc51bee26, 0xd75ba7ae,
+ 0xf09a59c7, 0xe81d043b, 0x086cee7e, 0x35fbb9f1, 0xbf9fa3d0, 0x3cc75fc7,
+ 0xb9d1f7dc, 0x3b6835db, 0x208fcc89, 0xeb4f9ff7, 0xa7ade391, 0x198b2967,
+ 0x9f449cca, 0x7d30ce14, 0x75f2bf6d, 0x4d6dd3f4, 0x35df57ca, 0xe283f7d0,
+ 0x6f4b73e1, 0xd3ef1bfb, 0xd349627d, 0x97b1bef8, 0x7da6c7be, 0x1de9584e,
+ 0x001363f2, 0xe6b3ddfe, 0xc66f6437, 0x07e01af7, 0xfb11e7be, 0xf72d06bd,
+ 0x3df0c67c, 0xedfee335, 0x950ae0ce, 0x72ac6fee, 0xaddff8db, 0x9b8db229,
+ 0x87ca794e, 0x21bffcd2, 0x6a40fabd, 0x2883c49e, 0x638c19c1, 0x83b2bd75,
+ 0x2fd69b36, 0x22f7c669, 0xf432fac0, 0x006401ef, 0xb763b77f, 0x1e69ef8a,
+ 0xa5b43d41, 0x74abf6b2, 0x2e1e1a0f, 0x6f2f0955, 0xf4bcd971, 0xe895ae5d,
+ 0xdbd30fb5, 0x2ff71368, 0xb16bfb8c, 0x19b46c7c, 0x8daf4a79, 0x77cc7671,
+ 0xfcda773e, 0xbfe89bff, 0x9324a93f, 0xcbfe6070, 0x3f7c3df3, 0x7758c129,
+ 0xc3eb8d89, 0x37191af7, 0x6a7dd136, 0x1d31aba4, 0xe1e21ef8, 0xba149ca4,
+ 0x25d8d51f, 0xa63753ee, 0x9b7fd807, 0xf3fb12fd, 0x4ed2cec6, 0x0e83078a,
+ 0x6eabdf0b, 0xaa34f974, 0x4421d207, 0x3ef89ffe, 0x69bbe0df, 0xfd21ef98,
+ 0xed91505e, 0xde5157d7, 0x4a1b9a7f, 0x6169bde9, 0xc0f1126d, 0xe5061ef8,
+ 0x4e9519e0, 0x7befa3cf, 0xfbe4e281, 0x501c8617, 0x9d995831, 0xb90d7cba,
+ 0xf8ef8d38, 0x3bea2535, 0x8f5e437e, 0x98b90a24, 0x44cc26e9, 0x71a5577e,
+ 0xf061e563, 0x8f00bffd, 0x30b1ae40, 0x0030b1ae
};
static const u32 xsem_int_table_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x94f3ff00, 0x51f86066, 0x257bc08f, 0x799c1819,
- 0x8968c550, 0x1819390b, 0x0bf1030e, 0xda005620, 0xc0c5caeb, 0xfdc406e0,
- 0x88013c40, 0x3eb100bf, 0x01830337, 0xd902a710, 0x736e6852, 0x17ba0264,
- 0xd8815d88, 0x32bf881d, 0x637c3030, 0x767ede20, 0x623da021, 0x2039fe08,
- 0xfd04b2fb, 0xf0d83ffc, 0xdafa655d, 0xc0c2a817, 0x2a83a310, 0x8fc68b16,
- 0x466fc1d3, 0x027c9a3c, 0x8f113f1a, 0x5473717e, 0x2a019d7e, 0x8188c93f,
- 0x9a920f61, 0x6efc037a, 0x81afc741, 0x3100df7a, 0x74769a00, 0x0003685d,
- 0x00000000
+ 0x00088b1f, 0x00000000, 0x243bff00, 0xa3f0c0c3, 0x4aef811e, 0xf1303031,
+ 0x12d18aa2, 0x6064e3ef, 0x6062e010, 0xfbe20530, 0x330c0c3c, 0x204cf480,
+ 0x6066e516, 0x1ae20310, 0xc40dde20, 0x19f8807b, 0x1039fc50, 0x1be200ef,
+ 0xbefd103c, 0xfe0c0c4c, 0xc4081c40, 0x95fc40c1, 0x1be18181, 0x73f6f103,
+ 0x4c30330a, 0x2ff04715, 0x249fd903, 0xc1ffe7e9, 0xe90c4386, 0xa071df6b,
+ 0x10acf37d, 0x7b20467c, 0x9aaa15be, 0xcdf85605, 0xbf268858, 0x18bf8d08,
+ 0x0372fe8f, 0x4d5afe54, 0x81b5b334, 0xcd4909e9, 0x6efc4d3a, 0x40aac741,
+ 0x3101a9ff, 0x5ff1ad00, 0x000368ca, 0x00000000
};
static const u32 xsem_pram_data_e1[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0x45547809, 0xbedd70b6, 0x4e9def4b,
- 0x62585908, 0x81511007, 0x05e42ce9, 0x62d9b1c4, 0x970621f4, 0x66854611,
- 0x44749ecb, 0xf9d1c1c6, 0x153610d3, 0xc713309d, 0x60ec44e0, 0x81a0d050,
- 0x60241009, 0x3cc0ea03, 0x64ffe31d, 0xb83066dc, 0xc5a4c6b0, 0xfcb8df0d,
- 0x4dd54e75, 0x11d37bdf, 0x7fef999c, 0xca3fbff3, 0xfb5ba957, 0x539cead9,
- 0x2c922aa7, 0x4222e910, 0xab9f83be, 0x409bf908, 0x4d171908, 0x69e5a909,
- 0x24e05295, 0xbfa2e024, 0xe1521366, 0xd3cb4254, 0x43b29909, 0x48955f0e,
- 0xc8428df3, 0x7da6f34c, 0x6eef2c56, 0x53b0f960, 0xfe5a11f1, 0xd3cd1371,
- 0x8ee6033e, 0xe5a0ae87, 0xd9221d91, 0xb28edd08, 0x21124899, 0xfd842dc7,
- 0x0e7cd364, 0x96568521, 0x3fdc68ad, 0xb717da07, 0xf6958999, 0x68bbb157,
- 0x5f3415c6, 0x50264874, 0x32d362a5, 0x97cd1065, 0xc8168484, 0xf3664cf7,
- 0x4314ee0b, 0x1efd689b, 0xcdd24757, 0x574e420e, 0x2147885b, 0x91d9c6a4,
- 0x4268d374, 0xf2db434a, 0xb3695da0, 0x581135e0, 0x5397a6c7, 0x045b5d61,
- 0x4843d9af, 0xf13b66d9, 0xf873628c, 0xde3bfe8e, 0xa2af862a, 0x3ae98be5,
- 0x88b7ed09, 0x1111e6d4, 0x78a75fc6, 0x9df8519c, 0x38e376ae, 0x0b62be6a,
- 0xabb6871d, 0xc2f0567c, 0xc44d2b12, 0xefc742df, 0xf59d6dde, 0xb7d60384,
- 0x84e9194c, 0xa056ad75, 0xde68515e, 0xe607ab4e, 0xd1e4a8d7, 0x4686d2f2,
- 0xb47470a5, 0x03cdb2bf, 0x1faaf3f4, 0x94d7ec9e, 0xd5d3d31b, 0x46467884,
- 0xf884a5f3, 0x44bf685a, 0xc733290a, 0x407fbf44, 0x081909e2, 0x63c48bfd,
- 0x214ff689, 0x4783df89, 0x5e14afe8, 0x844ebdc1, 0xc5b78aab, 0x27bbfa6e,
- 0x6eb3b78a, 0x9229478e, 0x4d5feda3, 0xd03c021f, 0x9c02d4f9, 0xcf96ba68,
- 0x4c9135cf, 0x2eff6892, 0xe903711f, 0x351eb7f5, 0x3cc995ad, 0x185ac742,
- 0xc693e31c, 0xee42bcd3, 0x7e425e20, 0x37c722bd, 0x241fe695, 0x6f3039fe,
- 0x062fe4d1, 0x92d2113c, 0x4abbf402, 0xfd60b320, 0xd349813f, 0x94a955f2,
- 0x6bdc293e, 0x213ce5a7, 0x89ee7c0a, 0xf27c2f90, 0xa7ec74fe, 0x6851fb08,
- 0xdfcfc33f, 0x572f3b8f, 0xaf3b8fd7, 0x0aa7ed58, 0x585db1fb, 0x1379b53f,
- 0x2bc9f3f4, 0x1bb9fb55, 0xd85d71fb, 0x4f57dcba, 0xeae7cfd4, 0x7e27ec72,
- 0x69f897aa, 0x07a5517d, 0x6913e1d2, 0x3e39a3b9, 0xa5a27ef3, 0x812bc98b,
- 0x4b949dff, 0x971174b4, 0x61d1d36b, 0x97412fbc, 0x8fb93da7, 0x30f3ce5f,
- 0x7c82cb88, 0x50520ca9, 0x641a4c2e, 0x35dcf9c1, 0xe17281c8, 0x4bfe09ae,
- 0x301e74dc, 0x79a54936, 0x7723ffc5, 0xf3a6ba0c, 0xa40a4814, 0xc6a4131e,
- 0x8332d5f2, 0x5fc1e4c3, 0xdb463c8f, 0x91914c07, 0x4ebf34f1, 0xac38f498,
- 0x21311363, 0xa9226c7c, 0x33367a82, 0x3ab4f941, 0xa089e73d, 0x866b4e06,
- 0xd10bfc52, 0xfec8d77e, 0x2dafa014, 0xd020e6e4, 0x94a1aadb, 0xf21107c9,
- 0x70a6f074, 0x87eda250, 0x3c00a616, 0x6fe50acd, 0x1d0af8ed, 0xff8e347f,
- 0x03bf8c1c, 0x77d71fc6, 0x5cb0f37c, 0xb496f8dd, 0x16f8dd62, 0xe94f8e85,
- 0x9db9377d, 0x37e14f8f, 0x83e79081, 0xe6f8e1b7, 0x7f1c62b4, 0x758a42b5,
- 0xc77adbe3, 0xfdd6017f, 0x1feb7f52, 0xfebf4136, 0xfafd52b4, 0xc3feb615,
- 0xdf1f1164, 0x63ffeb86, 0x7f5b2170, 0xbf5b295a, 0x3bdbf599, 0xfe17abbe,
- 0x8fbac1af, 0xe1feb7f4, 0xbfebf513, 0x7ebf5ca8, 0x6dff1b33, 0x77c7c152,
- 0x04eff8e0, 0x2ffad9cb, 0x15f1c72a, 0x740bdfb3, 0x55b60ca4, 0x64f8e885,
- 0x64886508, 0x4c3e5194, 0x42102547, 0x6191d7db, 0x6cbb8708, 0xb0beee8c,
- 0x44737a51, 0x51091de5, 0xacf2a28e, 0x597cd392, 0xe40524f3, 0xb953962c,
- 0x754f88b7, 0x74889b61, 0xa1ccea4d, 0xbb7ce98b, 0xe420c4db, 0x195dd617,
- 0x23bf7112, 0x9da00b73, 0xfdf0c244, 0x6cc787a3, 0x98cbaed4, 0x8f95aa2e,
- 0x88f8ea77, 0x993827cd, 0xf3a2aa8c, 0x3044069b, 0x4e3f9a2e, 0xf2a128e5,
- 0x472a7df3, 0xd3213d21, 0x0ff7e8f1, 0x8a259ca9, 0xb1966f96, 0xde483c7d,
- 0x72049518, 0x971cfd82, 0x2f8fbc18, 0xff004211, 0xa1ddd62f, 0x545a7c80,
- 0x8f40a76b, 0xf1c023ce, 0x0e6dd914, 0x9e10146d, 0x2dcf801e, 0xfc848ac8,
- 0x9535a295, 0x7ea8b682, 0x6dddae80, 0x8532b424, 0x76b05fd6, 0x5d3750de,
- 0xccb3adff, 0x1fec2299, 0x84d837c4, 0x9b064c7c, 0xd5990972, 0x4c1e4eba,
- 0x92ccb733, 0xb4d4efdf, 0xe7d7ed9f, 0xe7d62d6f, 0x6c90e5bb, 0x44a37d02,
- 0xdfb48d20, 0xe5f4abdb, 0x42f138ea, 0x1f2bc302, 0x6c4927ef, 0x9a43b7be,
- 0x88dd9f09, 0xd66e39d7, 0xe04f9d56, 0x7184991e, 0x481cecbf, 0xb103ff10,
- 0xd6cddf9e, 0x1cef9c6d, 0xa02be2d9, 0xb77399f3, 0xce34f088, 0xdd9f73bf,
- 0xd34b1a67, 0x20654ffa, 0x8c7ae341, 0xd4bb9ff3, 0xea371eb8, 0xc682f361,
- 0x8c4e8cef, 0x9b6814f4, 0x4d43e034, 0x6b968abd, 0xa1a87c06, 0x33cdb2af,
- 0xd092f975, 0xa2fd5d6c, 0xf2ba79fa, 0xba25b545, 0xee6b05f2, 0x05e7e5d0,
- 0x9fd5d6ef, 0xae9974bb, 0xfbaaf6fc, 0x16b7e574, 0x67e5d3af, 0xeaebd7fb,
- 0x51ab32df, 0x2bec2e57, 0xe513a8b9, 0x54a2ffaa, 0x36df2bd0, 0x9547a013,
- 0x387e55de, 0xe9829d59, 0xa60f6ae9, 0x294f80cb, 0xb3769bff, 0xde71b034,
- 0x2aefc045, 0x55c84e9c, 0x464fc069, 0xd3c237ba, 0x67f4df48, 0x487dac70,
- 0x5205cb4d, 0x87ae7200, 0xf7eacfef, 0x120e5c73, 0x72d31cb2, 0xf96df185,
- 0xc4c9d4f6, 0xc8f0f905, 0xfdff472a, 0xd7011692, 0x1e8b4041, 0xd4a37808,
- 0x70ebc3aa, 0xf6bb3cdd, 0x257e388b, 0x0078eef0, 0x0132c155, 0x307c21f8,
- 0x3031c6ed, 0xcc72df1f, 0xfdc40db7, 0x7f3aabb7, 0xc01287c0, 0x93d300af,
- 0x3d30b3d5, 0xf4c7ed5e, 0x4c62eac3, 0xc2aeafdf, 0x297ab3b4, 0x83ab47a6,
- 0x7aa5fe98, 0x54efa60d, 0x56fa62d7, 0x7fa63d75, 0xda610eae, 0x54c3ed5d,
- 0x395edba5, 0x4af5c899, 0x1dd3ffae, 0xf967f302, 0x7bfa445a, 0x37a3f207,
- 0xacf1f805, 0xa0918be3, 0xcb7d9f37, 0xef2f404c, 0x7a465e0f, 0xc4ae17e8,
- 0x61457a87, 0xac870a88, 0x1b56e5be, 0x44d593c3, 0x1b9509f2, 0xa4fc5df7,
- 0xcc68fe77, 0xda01244b, 0x9d33bc87, 0x411dfa31, 0xc3e75f10, 0xc645f113,
- 0x71f140de, 0xe5bfd1fc, 0xf8e7bf40, 0x283b653e, 0xc2497ee2, 0x5f01784f,
- 0xfee1b81a, 0xe5c1d913, 0xf7e079f2, 0x7e1540f1, 0xa684691d, 0xd2370413,
- 0x3356d9df, 0xed8e0091, 0xfda110f6, 0x84f43d9c, 0xc5bbf60b, 0x87f72629,
- 0xa6a0e031, 0x6ee92d15, 0x689f7687, 0xd6cfe7d3, 0x282df90a, 0x37713d37,
- 0x72ba018d, 0x011c3fbb, 0x54c14ff8, 0x8a7167ed, 0x0070fee2, 0x45f18fc2,
- 0x29d23c73, 0xdeb0dbb5, 0xfd1e7b3f, 0x479d13f5, 0xb680f92b, 0xf8645b47,
- 0x3e91edf9, 0x533e96f8, 0xed4f000a, 0x9fb017f2, 0xefbfe8db, 0x12bf4186,
- 0x037ed5e6, 0xfcd0622d, 0xacdef823, 0xf3b68f1b, 0xb43136a8, 0x255e9feb,
- 0x27a55c72, 0x0bfeda2a, 0xce3b403a, 0xfdcbd6ea, 0xd03e5d78, 0xedd6ea96,
- 0xe50bf003, 0x482c527b, 0x9ce52f40, 0xc7247a7a, 0xefce811a, 0xf461e088,
- 0x157ab026, 0xefc54e96, 0x00ec3241, 0xae7e603d, 0x5b9e6f4a, 0xf972a5de,
- 0xe4c87fd4, 0x9aff287e, 0xda272ace, 0xc4c0951f, 0x780bf344, 0xd96b7e6e,
- 0xa7779074, 0x5e1f6c4c, 0x605c0a48, 0xda931494, 0x3e43d01c, 0xa07ca626,
- 0xffc98ffb, 0xec696576, 0x05261181, 0x8d60b3e7, 0xfaa41f7e, 0x545f2e93,
- 0x9217cfaf, 0xce80921b, 0x1264eb0b, 0xf51f8012, 0xc62689e5, 0x6aa4450f,
- 0x2b0fec15, 0xdf313db8, 0x74c1a44d, 0x1ebb157e, 0xe74799cb, 0xc989b971,
- 0x2ebed56f, 0x2ff36049, 0x7c54696d, 0xd683fcb4, 0x415c9fac, 0x15687da0,
- 0x3b8219f8, 0x4f26ef04, 0xd0fdfc5f, 0xabe71bf9, 0xec7d1fee, 0x8a8f3e7c,
- 0x142f82cd, 0x6f191f63, 0x13fef812, 0x035e3844, 0x99e8d6eb, 0xa8387337,
- 0xf28679f9, 0xeffe430a, 0xa244b7a6, 0x8223b7a3, 0x40d366ff, 0x5fa05f46,
- 0xf1445209, 0xa7fd23ff, 0x9e7fe9f4, 0xb13fdc69, 0xffb421ff, 0x15ff5d1c,
- 0x47fed4ff, 0xddff99f4, 0xd8affab1, 0x906775b5, 0xe7d29bca, 0xba11761e,
- 0x6a929cff, 0xff14bc93, 0xba569be5, 0x4a4e0e80, 0xf3d01741, 0x1f9890a9,
- 0x3f57618a, 0x3e0f4bd7, 0x0f760087, 0x3ffb4afc, 0x3303f4fd, 0x62f97f60,
- 0x7b46ec93, 0x6c39b366, 0xd95afca6, 0x8c9d325a, 0x9631fcc5, 0x0889fd5f,
- 0x7d3d36f9, 0x70f53e96, 0x28c7f812, 0x3f7d70a5, 0x6552fa8c, 0xb07947d3,
- 0x044804ff, 0x0ed8ccf9, 0x80973fc6, 0x129e71f2, 0xce9cb7d7, 0x00f0f513,
- 0xf5a04b87, 0xf0444f81, 0xe64e924d, 0x2fd434a7, 0xc84f7ae6, 0x4e3c4ce4,
- 0x6ff23c55, 0x5e40dfe4, 0x2120f0aa, 0xbb88f7a6, 0x760b1b1e, 0x7fd3576b,
- 0x9c0d04b8, 0xdb3b3e54, 0xe7f1e0b2, 0xe3cbfd3d, 0x45876e6e, 0x9db085db,
- 0x6beb8da7, 0x972d2ced, 0x63f02ec3, 0xdeca3796, 0xbe5cfd20, 0x1f2789f5,
- 0x6df23b05, 0xda62f7b3, 0x97d6d97f, 0xe6813cfe, 0x89c9b6cb, 0x1c32d9d3,
- 0x2f145242, 0x696ffa01, 0xa50f1466, 0xf1497fbf, 0xefdf618c, 0xa3e2884d,
- 0x857edb6c, 0x8f0be98c, 0x95fb2d29, 0xbc0c474e, 0x03cb1cb4, 0xf5dc4abd,
- 0x3f78028d, 0xc9204fb5, 0xd9e031e9, 0x07ea12f8, 0x23c42700, 0xde2f53c7,
- 0x1403f50c, 0x55cf202f, 0x97cb193c, 0xfd037973, 0x3d234679, 0xf83cfb3f,
- 0x7b31df7d, 0xcfc5fd61, 0x7582e9de, 0x18aa909c, 0x32b63f5d, 0x2dc747c9,
- 0x6e498396, 0xe2f7d94c, 0x7a433f0d, 0x67fd7a2b, 0xf35ecc49, 0x6f709aa5,
- 0xfac2a60a, 0x8cdc3516, 0x7e242beb, 0xc7e2bba4, 0x8f9002c4, 0x7f244b9f,
- 0xb8be0c5b, 0x717c6458, 0xb4552362, 0xd04efae8, 0xa0fd076d, 0x6d0c5bff,
- 0x1dc57f42, 0x67fff804, 0x2c9affaa, 0x16e7fcc6, 0x4dafa786, 0xb54f9eaa,
- 0x36bd2d3c, 0xfc00eead, 0x4bea1e9c, 0x80573f06, 0x0f0e4148, 0xafda3be1,
- 0x64b4faf8, 0x91e21f86, 0xaa3b7872, 0xef814c07, 0xf643bf50, 0xdaeac759,
- 0xa3d2ef91, 0xe3e12fe3, 0x60db79d3, 0x44913eff, 0xac625b8a, 0xf2a8a66f,
- 0x35c7dd3d, 0x6fe1a5f4, 0xf74defc6, 0xf956fe31, 0x1f33343d, 0x837b3fca,
- 0x83b40ff1, 0x2bce91fd, 0xfbe58c9c, 0x1e50126f, 0x16384998, 0x9cc9375f,
- 0x2ae5f5af, 0x4b79d09d, 0x5e869c42, 0x8404ffa0, 0x0ab7fa3f, 0x8d3b68eb,
- 0x78c00cbc, 0xa9fdbeae, 0xf9c45b7c, 0xf9ea23df, 0xbe30349f, 0x0abf5fef,
- 0x2e573ee2, 0x147c9e87, 0x67f295f8, 0x2afc03d0, 0xcfbac017, 0xf3fc1f34,
- 0x9c9f294f, 0x54f95169, 0x7c8d3f2f, 0x5c7dbc5a, 0xb33d3e4c, 0x9f362336,
- 0xf931efd2, 0xd3e32d74, 0x53f25bff, 0xc03e5f85, 0xfc28f2ef, 0x1fd87954,
- 0xf0f28d1c, 0xe1079323, 0xf4879469, 0xd3920de7, 0xba54fe97, 0xf4ade953,
- 0x408b8a99, 0xa5d2f4ee, 0x74bd774a, 0x1f5dd2a9, 0x7e0e88ff, 0xa004f2c6,
- 0x05274a05, 0x0de48fbb, 0x6f2cf8a6, 0xb440e767, 0xa790cbdd, 0x36e1f270,
- 0x1e5f6a46, 0x87cda89c, 0x4316f90c, 0x5f219f7d, 0x37efa860, 0xf50cabe4,
- 0xd03fcc43, 0x48215076, 0x7d5d6107, 0x3a093979, 0x57b72fc1, 0x87affb44,
- 0x6d1579ce, 0x1e9cd3df, 0xb079520a, 0xeaeccad2, 0x156540c8, 0x771eafc8,
- 0x790095c4, 0x7b6bd32b, 0x78ae220a, 0xac787e8d, 0xdbf9445d, 0x5af92219,
- 0x1f94457f, 0x9d7f106a, 0xe672bfa4, 0x3a269c67, 0x3d8296d2, 0xc17a2b59,
- 0xecb85d44, 0x3cb81716, 0x5f87da7a, 0x5f7e8b3f, 0xe3c45874, 0x6b9b1e8b,
- 0x048bcc2c, 0xc6aa527d, 0x8249382e, 0x7e089dbf, 0x1f6676c3, 0xd06b5c2c,
- 0xa45ac82b, 0x12c7428b, 0xd522e405, 0xfbd7dfe7, 0x977d194d, 0x1b8afef2,
- 0x7b6ae5f4, 0x3b023938, 0x5f49b4ad, 0xce76e7ee, 0x67bd2a93, 0x17940c90,
- 0x7d80c060, 0x34ebe5cd, 0xb3f5f471, 0x0e7bfc28, 0xe5e80489, 0xf088bb6c,
- 0xceccdb3f, 0x20704909, 0x89254df2, 0xe1535ca0, 0xa17c05d4, 0xba772ff4,
- 0xe735fc76, 0x7ca55a1e, 0x7f63bbe7, 0x9daed347, 0x03dc8f6f, 0xa66f5df9,
- 0xd6fa4bbd, 0x8acfb29f, 0x7d9ed9fe, 0xe94f3c4e, 0xda6afbd9, 0x6ddf903d,
- 0x7b3cc2f6, 0x16397df6, 0xb967a7e8, 0x56e418b9, 0x7f8a50cf, 0xfdecd69a,
- 0xee276c72, 0x6f102b93, 0xd30a8baf, 0x76ffda73, 0x94844854, 0xfff60aae,
- 0x33f4767d, 0xa2b79e04, 0xef67a07f, 0xc77e3997, 0x953d6f3f, 0xc7a4dcfc,
- 0x876d6649, 0x7f33c5f9, 0xf8cf6073, 0xb9c19627, 0x657eeb6f, 0xf29f2d01,
- 0x416337c2, 0x676cf61e, 0xdcb74d7a, 0x05ce01b9, 0xeef352fe, 0xb9c29932,
- 0x1062981b, 0x862bb995, 0x623a0e4c, 0xf41be5c1, 0x3c285c7b, 0x067ffd3e,
- 0xf79e021e, 0x433bb795, 0xfdd60116, 0x4177d1d5, 0x2333ec0e, 0x3debaa5d,
- 0xf50cb2d3, 0x3badf38e, 0xf5f66241, 0x0b759cff, 0x77590be1, 0x8daff486,
- 0x07a25def, 0x83e462f1, 0xf7be74be, 0x756fcc2e, 0x17be717a, 0xff33ef48,
- 0x83ffd7c5, 0xe29dbef1, 0x75fe75dd, 0xaf8bfd57, 0x1fbc7fbb, 0xeef1c39e,
- 0xc0f57386, 0xfce0df0b, 0xab9ca87e, 0xf7e717fd, 0xeaafd6fe, 0x79307fe7,
- 0xf5a0c8de, 0x03ad49f3, 0x2a6b8b14, 0xa0ce1c0e, 0x72187fa5, 0x3be61e30,
- 0x18c39f99, 0x125fb7e7, 0xc164fdb0, 0x891d7684, 0xc75db817, 0x5cc1a1ec,
- 0xa4bc187f, 0xc190f510, 0x7a641e43, 0x83a9e483, 0xa43fbe73, 0xcc62f02d,
- 0xcb7cc902, 0x95f7790f, 0x0bb7af3c, 0x1f10277f, 0x4e0e411c, 0xa043f7fb,
- 0x22190e9f, 0x534afea2, 0x745f5bd4, 0xe5efb3e5, 0xb97ece8a, 0x67b7a3c6,
- 0x76f512f2, 0xdfde54cf, 0x3fe6c234, 0x428421cd, 0x87930e14, 0xfc1126fe,
- 0x962f939c, 0x79f34089, 0xec02bfc4, 0x7d0ea984, 0x19c18f7f, 0x580fc68c,
- 0x16bb6964, 0xaf16dffc, 0xd25dfd80, 0x62794265, 0x0e9016c9, 0x984bd546,
- 0x1ee4dd7f, 0x719e7007, 0x7733aec5, 0xfa97f013, 0x528f1614, 0x5fdefcc0,
- 0x44ddf77f, 0xf0e2e388, 0xaeffa22b, 0x036eff03, 0x7ae8db09, 0x18244917,
- 0x4efe0097, 0xf3afbc81, 0xf0f3ea77, 0x68a4e3f3, 0xdfabe73f, 0xb3fe1d1f,
- 0xee945dd3, 0xdbb0a7df, 0x1c08e90d, 0x53dad25e, 0xe0ced6ff, 0x84857815,
- 0x6ef3b186, 0x2e7340b1, 0xeccca974, 0xd97f5dee, 0xccf6059e, 0x71d19ea4,
- 0xa0471f8c, 0xfae0197e, 0x89e259e5, 0x1f803af3, 0x79e1c787, 0x19d121d7,
- 0x0b6bde2b, 0x819eb3b7, 0xf69a5073, 0x115a9134, 0x41127df4, 0xc9b05dff,
- 0x88c53642, 0x4d94483b, 0xe39c5cfc, 0x3988fe8d, 0xe36787e0, 0xe34da22f,
- 0x9aeb78b4, 0xdb1a4a7e, 0xf3f00f17, 0xe21ce6be, 0xd82f851f, 0x2ddf0075,
- 0x82bcced6, 0x923b7c18, 0x81c66fc3, 0xbe9ed0af, 0x04d1bdac, 0x93597e7c,
- 0x969e7749, 0x3dfd7326, 0xbcc26493, 0x3ab01c66, 0x872f01b3, 0xd9c42f44,
- 0x513fda05, 0x83ce31fc, 0xfe84f08c, 0x9b7a8fc1, 0xed7846ec, 0x00165b91,
- 0x6c7cf75c, 0xed676021, 0x62cb6a56, 0x0a4ff3cd, 0xd222e79b, 0xf4d8e772,
- 0x4ef83d7f, 0x278471ea, 0x44d2bd83, 0xd2fbaf90, 0x3e3a411f, 0x408499bb,
- 0x037d831e, 0x336ce172, 0x8280fdc1, 0xd3b041e4, 0xa55fbf28, 0x692fdfb5,
- 0xec0cf6db, 0x82ed9523, 0x95cb5c1b, 0xfe02a752, 0xbc5b40b9, 0xc33b7208,
- 0xba21c6a3, 0xe1a4dcc7, 0x0964db8b, 0xc2707be1, 0xdc615b9e, 0x0214bb4f,
- 0xc5ef9afb, 0xfee40b88, 0xc859eda7, 0xebadfd07, 0xdae4d5f7, 0xc3f412a9,
- 0x1e919ae4, 0x74db3746, 0xff442bf9, 0x19afe020, 0xde25cee6, 0x96fbf818,
- 0xcb05d9d3, 0x67ffd0b7, 0x550dedf2, 0x02c5f9be, 0x2cbd1f0d, 0x23557db3,
- 0xc96392df, 0x2782c5b7, 0x78bee019, 0xc064f0ef, 0xf2c3e2eb, 0x6df258c0,
- 0xdf3b356b, 0x8fc78e7a, 0xf952b4f6, 0x7c8d23f6, 0x2df2a56b, 0x8b7ff9c6,
- 0xcf5ffaac, 0xff42df23, 0x15b7fc3d, 0xf58c5be4, 0x53f0e41e, 0xf6d8dbe5,
- 0xc6df2863, 0x71749ab6, 0xdccbcf96, 0x7cafd99f, 0x04de0613, 0xd921d4fa,
- 0x3f418f6b, 0xf6feb95b, 0x819f8f1c, 0x7dce4071, 0xdce503f5, 0xe72a173b,
- 0xace09bfe, 0x3bc5b9ca, 0xf69fc608, 0xe72643a5, 0x72a6ef16, 0x647a004e,
- 0x5ef16e72, 0x0638fcc2, 0x8faa36f9, 0xbf58237c, 0x07dacc32, 0xb91fd2da,
- 0xe997f68d, 0x5a16bd93, 0xef2a333f, 0xdde569c6, 0xbbc9fd57, 0xef261743,
- 0x47797076, 0x9030d8e5, 0xf0fa46af, 0x74e3ebb6, 0xd13f8cf7, 0x97e07bfc,
- 0x673c4557, 0xcec4dd7a, 0xfe34fe05, 0x57d03644, 0x33e6c281, 0xd7f46142,
- 0xfec41d5d, 0xd6c8bca7, 0xf160e157, 0x4cad95bb, 0x166cac3f, 0x6bfa1e42,
- 0xf0af84de, 0xaf64a8bc, 0x7e699240, 0x27d599a6, 0x24e7a94f, 0x86867a64,
- 0x96e6161e, 0xa1777fa1, 0xbfe02c44, 0x9de4732d, 0x2cb63d02, 0xcb7bf997,
- 0xc392f7f8, 0xdfc0ab9d, 0xc05eb259, 0xee353273, 0xecbf8d50, 0xbede5e73,
- 0xc681fd0c, 0x3c19f373, 0x33c6664e, 0xc631a842, 0x66d97fb9, 0xa71a7e7d,
- 0x276299e7, 0x26bc8bc2, 0xe0c5377a, 0x2f5eb51f, 0x38710e9c, 0x9fb88935,
- 0xc289c2f6, 0x17de93cd, 0xd3d3144e, 0x70a29233, 0xae957929, 0xf5ffbb37,
- 0xae3370aa, 0x9677f55b, 0x83fa7ef1, 0x3ee70a83, 0x2770e7eb, 0xd2728424,
- 0x95ab8f08, 0x16683f5e, 0xba50a7c4, 0xfc133941, 0x0d7188a3, 0xd62e9305,
- 0x8eb843dd, 0xed564fd3, 0x8c7029a4, 0x7de2133d, 0xfeaddce1, 0x6e21978e,
- 0x9e5bdc6f, 0xaf4ed84c, 0xc3f66098, 0x6b16dbf9, 0x4aa0e504, 0x87408d87,
- 0xf0f7ae14, 0xaa0cf67e, 0x61768c9a, 0x3d06e09b, 0x22b61024, 0xae14035c,
- 0x20242f70, 0x2806fc31, 0x1dff023d, 0x8305ff5c, 0x03c15ee3, 0x753c80fe,
- 0xd0bc02bf, 0x0ced59fa, 0x8090812f, 0x1126c978, 0xd657bbf4, 0xc030de0b,
- 0xe111adaf, 0xfa67caa7, 0x49e2d0e3, 0x2c52bf43, 0x9a4ac5fa, 0xd78cb2fd,
- 0xfdae619b, 0x8cf3d033, 0x88d264a7, 0x7dffa6e0, 0x279f3d1f, 0xa788c3fe,
- 0xb6bc39c7, 0x001d3c02, 0xbbd308b7, 0x3de15fc2, 0x203cb515, 0x9cf07505,
- 0xefb9e8f2, 0x1538d785, 0x20c7405e, 0x89e7dadf, 0x136c2f90, 0xbef480c8,
- 0x307385eb, 0xec97bf2d, 0x7ffac63d, 0x1892f04c, 0xba60beeb, 0x8b9e87ee,
- 0x7f82dd29, 0x36ba3fbd, 0xe151a9c2, 0xe7a726fb, 0xaf23593f, 0xef3d0164,
- 0x49cf9015, 0x3ceebc7b, 0xf4c2bf6b, 0x4a562d88, 0x91dd74f7, 0xa377b2c3,
- 0xd83cafa7, 0xf60be1ce, 0xd01ef683, 0x8810b0a5, 0xc16cdc0f, 0xc79c2f38,
- 0x6a9fa630, 0x2b56f3e5, 0x76537819, 0x7987fdff, 0x47e9fdff, 0x8c0c7e6a,
- 0x6dcd7107, 0xd151bc74, 0x83fb8cf1, 0x6f9ff76a, 0x3972af5d, 0x4baef7f7,
- 0xc687e71d, 0x074804c1, 0x878d55e2, 0xc7f82239, 0xe5cfa0c8, 0xae3e920b,
- 0xd6e5c22c, 0x1fffdc3f, 0x927fafbf, 0x4e7bc6e2, 0xefd5ba77, 0x02cfa46e,
- 0x41e7e137, 0x7d84df13, 0x3b1f53ff, 0x9136caf7, 0xff611323, 0xa0132c98,
- 0x915f4fab, 0xe9f96fd1, 0x79671654, 0x2507abfd, 0xcf5cdd70, 0xf5c8a162,
- 0xb3b404e3, 0xc7ae875e, 0x216e1e83, 0xbf0891be, 0x954fb82c, 0xc53b54d1,
- 0x733af943, 0x5206a873, 0xe24894ef, 0x936f009f, 0xeb780244, 0xe2980df0,
- 0x3f3bf9a0, 0x32e01922, 0xb601faa3, 0x06443ccf, 0xbe09bd42, 0x8cc66881,
- 0x8decfd6f, 0xc63ce91b, 0x3d7a22bf, 0x83ccdeb4, 0xfaa1070e, 0x1306a8f4,
- 0x35e06bf1, 0xc06a8481, 0x43fe346f, 0xef308ddf, 0x40efaa62, 0x7b717efc,
- 0xf20b8d63, 0x0fb6020d, 0x2e79fd04, 0xf5ad9eba, 0x0e5de49f, 0x83d68172,
- 0xac0d026e, 0xf049a05e, 0x616a4842, 0xe5053afb, 0x17809346, 0x0486b6bd,
- 0x86fd6162, 0xaddfb42c, 0x367db40d, 0x3db45fec, 0xc9f4dbf4, 0xdc82371b,
- 0xf6c4f3a1, 0xb63ceccd, 0x00f3b690, 0x81dd34bf, 0x083495fd, 0x1419ee04,
- 0xa97db337, 0x0bd915f8, 0xd7fbade5, 0x9d3b7ee3, 0x0e9a978e, 0x2a7850fb,
- 0x12c8d7de, 0x6d8f78dc, 0x5fc450fa, 0x23f8610f, 0x1c984389, 0xdb9e7813,
- 0xf7deaa3d, 0xe430f32b, 0x32ef4283, 0xe7ed0065, 0xd303b94f, 0x9f57484d,
- 0x7da7a028, 0xa7ede148, 0xc79d7ef0, 0xfdcc1c29, 0xecd4e940, 0xe1e6cd8b,
- 0xdb617ed8, 0x5a7f8c24, 0xfcf00a44, 0xa678c67e, 0xa576be6f, 0xbafe0435,
- 0x10c8e4d7, 0x4af07ef8, 0xdeef7e33, 0xf770e4ca, 0xcff44ed0, 0x0990689e,
- 0x69a82fdc, 0x9c5e5110, 0xbcf19668, 0x464c7c5a, 0x95b45db9, 0x1b071fe9,
- 0x4027bf58, 0x393f036f, 0xd17cd394, 0xfbdb8116, 0xf6ab4e4c, 0x9d9ba167,
- 0xb772abbb, 0xcfbbaf82, 0x4cb7543e, 0xca359201, 0x8f2e0adb, 0x02a4a94b,
- 0xddca3342, 0x7577380a, 0xe31a5f01, 0x3b511c83, 0xfc20e806, 0xe575d215,
- 0x3b01322b, 0x2ba0f846, 0x6a7de60f, 0xee7e80af, 0x0f82edf1, 0xdf8bbdce,
- 0xff508732, 0xfb9bcd0e, 0xde5fd80b, 0x55081336, 0xa0780e3d, 0x1cd72a72,
- 0xe86fcbf9, 0x5baf53f7, 0xd2841220, 0xbb843ccd, 0xbd99df1a, 0x6471c589,
- 0x04975ebf, 0xd4c92cf7, 0x8a072801, 0xd7e245ea, 0x825389c8, 0xb29fc6ef,
- 0x8dadc1fd, 0x6a56cce3, 0x3d7f610b, 0xd1f2666a, 0xd88649b3, 0xccd2b208,
- 0x0fb534e4, 0x64b2fe30, 0x4524baf7, 0x7b250743, 0xf48925d7, 0x071e2afb,
- 0x2bfb0351, 0xb0a2576d, 0x09f64a71, 0x38cd46ee, 0xbf6a3f6a, 0x6ed66eca,
- 0xf6965ef8, 0xcc097fd7, 0xb9f9d70f, 0xd8c2f202, 0xfbf19f4f, 0x3ff727e9,
- 0x7409d5cf, 0x89afb95e, 0xfb9ca418, 0xdae1f4c1, 0x55350073, 0xde7215e3,
- 0x069f1130, 0xb17fb97e, 0xdf069f11, 0xdf28e3ad, 0xd75dfc53, 0x02ac8426,
- 0x15298fe4, 0x037798d9, 0xff72579f, 0x7654e573, 0xf19ad3be, 0xfbe00afa,
- 0xd202d9e9, 0x95fa0903, 0xafa88901, 0xb8ce2079, 0x2fb59b28, 0x1f81eda2,
- 0xfe33d75b, 0x03c272a4, 0x61b2a472, 0x6fd61e5d, 0x7fd03c12, 0xd43ce36b,
- 0x45738a47, 0xc74de582, 0x6e2a3f50, 0x7c08963b, 0x0eb6f94c, 0x89ca81f4,
- 0x71c83766, 0xfe551f95, 0x05c78d7e, 0x0c7b8b13, 0x0067e3c4, 0xcbec0df3,
- 0x4c2be2d7, 0x199a07ae, 0x1972063f, 0x55b6bebf, 0x085e1586, 0x9f3f237f,
- 0x55f8ccd8, 0x3ce6ec7c, 0xb45ca7b8, 0x1ca7c589, 0x80a2986c, 0x24227d3e,
- 0x97d37ee0, 0x6ade99bf, 0x811aefe4, 0x543f7bed, 0x5bf954bf, 0x73fa63e5,
- 0x4e578c1d, 0xb5ee14f9, 0x867af919, 0x3be7f2dc, 0x7faf7ce9, 0xce87ae96,
- 0xef8fca77, 0xe46a7576, 0x4127cd24, 0x716250be, 0xa95caa3c, 0xd7bc5890,
- 0x619f9e0f, 0x7acd1bfc, 0x734ac8ff, 0x6e6b8b3c, 0xcfee9192, 0xf87d9fc7,
- 0xf3f902ec, 0x7ceaf942, 0x2f8ea9fc, 0xb3f7d5ee, 0xb19bd392, 0xd70a6ebf,
- 0x1feb8530, 0xb8c09f9a, 0x3e9f8fb1, 0x53f00336, 0x39d287b6, 0x93b357d0,
- 0x49ce4184, 0x4aafdc21, 0xc61f455b, 0x9ce14abf, 0x3e5a9d1b, 0x653e7166,
- 0x9e9139cf, 0x439bb74a, 0xd2fb69d3, 0xc58c1f9d, 0x11e58bb8, 0x3e0a438c,
- 0x60e5f5cd, 0x83e058e7, 0x1bc58952, 0x00c2e519, 0xe8673b0b, 0x059f6dda,
- 0xb33613eb, 0x2da5fd7b, 0xcd66c8b7, 0x22cd84b9, 0x1cf0f5ab, 0x18e94830,
- 0xfcc255ee, 0xd5c9f7b4, 0x2daea338, 0xb6944e4c, 0x960768c9, 0x0dd6de6e,
- 0x6fa5a371, 0x15dfd199, 0xc609fcd8, 0x6e794fc1, 0x0253fa2b, 0xfceea26d,
- 0xdebc4fac, 0x866c3166, 0x0ad6b378, 0xf9a3ef3c, 0x896f9863, 0xbe7ab71d,
- 0xe7b2b2b8, 0x520ceef6, 0xfefd9610, 0x97c81729, 0x5c9b1dd3, 0xf9b7b718,
- 0xfb65e3fb, 0xdcb5e7c4, 0x79f1bdf7, 0xca17e1a7, 0x862d1338, 0x03cdc6f8,
- 0xf3a48f50, 0x718829cb, 0x97abd1ce, 0x037cfd6f, 0x6d778fc4, 0xe601b33f,
- 0xa7edfe5b, 0x887e201b, 0x7ee2b3ec, 0x08fa7817, 0xedaadfc6, 0x7ee1627e,
- 0x614f2d8f, 0xdbf772dc, 0xd6f42f66, 0x1a44f7bd, 0x6f758fc4, 0xfc092afb,
- 0x4ef64b96, 0x92eebf43, 0x4992531d, 0x4d42fd8c, 0x17436e81, 0xc46d3710,
- 0x83d6c1d7, 0x31f4e718, 0xbfc837c5, 0x96cb78de, 0xeabf160a, 0xcd9671e1,
- 0xfbd3e3b1, 0xdeb655c4, 0x2095fd78, 0xfe995bf7, 0xcaf8de78, 0x7f1e2837,
- 0x6bf80174, 0xb102fd56, 0xfc31f7f1, 0x76e21e32, 0xbcfbf8f5, 0x8fe3d175,
- 0x80eb5942, 0xc32be37e, 0x35370017, 0xc5927dfe, 0xbe016d57, 0xc60cfed9,
- 0xa6de02b3, 0xf9ff607b, 0x0dee0d3c, 0x7323949c, 0x5ed93ef0, 0x09e21bb3,
- 0x89bef74b, 0xe3bdd3fc, 0x1343f475, 0x4dde871e, 0xdc587f7a, 0xd9d7c0b0,
- 0x997164e4, 0xb710fe1c, 0x77e171e9, 0xe8c99f1e, 0xecdb8d58, 0xa7735e2f,
- 0x6ad9e985, 0xd3457e5c, 0x31fe3cbb, 0x17212f8a, 0x7bec74f0, 0x70a811ef,
- 0x1c397370, 0x1d8e3f8d, 0xa71bdb17, 0xf805f1ce, 0x37a87d83, 0x87e698be,
- 0xe8dfa264, 0x1e43124d, 0xb8b23774, 0x7f596ee5, 0x1f8a33df, 0xcdbc8f16,
- 0x0ba1a7c8, 0xdf3e438b, 0x7c287ffc, 0x33f28236, 0xba9c2fb0, 0xc72d8ebe,
- 0xff7ce0df, 0x5967df77, 0xb3ef1828, 0x63d027fc, 0x0531eb45, 0x3b5ee0ec,
- 0x8bb7af9b, 0x9ebbd5fb, 0x759e3116, 0x9441cb55, 0x517946e3, 0xc458ef09,
- 0x0b71ef98, 0xd8dbc3d7, 0xddb5d13e, 0x7ed07219, 0x46ec0eba, 0x3e6cae7a,
- 0xe09c40a6, 0xaf7f9bcb, 0xc629f3b0, 0x844fb03f, 0x7aeff334, 0x1658ff76,
- 0xf8fccd6f, 0xe33e71c6, 0x63da04e3, 0xfe68138f, 0x594e3744, 0x3b7145b0,
- 0x69de3fce, 0xf40b77c9, 0xe983ba77, 0xc45ba783, 0xb9f758fc, 0x66fbe4de,
- 0x743d7bef, 0x4177c4bf, 0x101dec9c, 0xfd4365d1, 0xf7338972, 0x4844b8ad,
- 0xa9ef8c15, 0x81e3c659, 0x014de97e, 0xaf38d77c, 0x95df3025, 0x9f8d5f00,
- 0x09fb7647, 0x4a72a5e8, 0x15f83641, 0x4946f28c, 0x06909134, 0xf99c4bff,
- 0xef3c1ec9, 0x7c010f08, 0x2138cd1e, 0x19efbf43, 0x49ef54fc, 0x9d325564,
- 0xc1417bdf, 0x4bf68cbb, 0x6860febe, 0xff6fb381, 0xaf7fde6a, 0x552bf3a8,
- 0xc147239a, 0x582f212e, 0xdc41be31, 0x17f7c567, 0xb8ac1b02, 0xbe3b83de,
- 0xebf5127c, 0x9d84cdc7, 0x85eb50fb, 0x9b915fd2, 0xc76271f5, 0x06fe1b97,
- 0xa63433fa, 0xa06d17e3, 0x686ec1f5, 0xd39da3b6, 0x2c6e3db3, 0x5e8a45f8,
- 0xc80667b8, 0xa33b22b3, 0x92e7a2c7, 0xbfb43543, 0xfe5903e3, 0x78a1d6f8,
- 0xbb6cbfdf, 0x0f0ce313, 0x0955d8ee, 0x73f752fb, 0x52fb0276, 0xcf5c0bf7,
- 0x1fbf867f, 0xb47b2f54, 0x4425c6f1, 0x71ef68f2, 0x959e4194, 0xfc107de3,
- 0x047ce1c9, 0x38b6aafe, 0xf541ffbc, 0x1f3f5d5f, 0xbcbb91cb, 0x41c1c748,
- 0x784bdeec, 0x6303c810, 0x4afcb53d, 0x8f7e30eb, 0x4473b698, 0x489407eb,
- 0x0ed7cb21, 0x03a4f262, 0x656b5feb, 0xf796affc, 0xcfd597ed, 0xd5d30eb7,
- 0xf257db53, 0xf48c41f7, 0xe055b37b, 0x2e6fc1fe, 0x45fef589, 0xf7e3f98c,
- 0x6824099f, 0x9b653d02, 0x8225df15, 0xdf10f37b, 0xe76153be, 0x30aee55a,
- 0x87b23fbe, 0x5b72e3cb, 0x1943df18, 0xf501e7c4, 0x9d2c4f21, 0x56bbe2cf,
- 0xde04acbb, 0xc178a9c7, 0x577c03e9, 0xf8f2fcec, 0x8e21b2ef, 0xd4718ecd,
- 0x1cfc2f15, 0x1cc2a0e9, 0x10fc039e, 0x1b2666d9, 0x1db7cf81, 0xed7e034e,
- 0x0969c392, 0x575e73df, 0xbc3662d1, 0x71d6c01f, 0x0afebaba, 0xdeace7b8,
- 0x47ed2ca7, 0x656b3cce, 0x585fe87e, 0x78ad4b7d, 0x677fadae, 0xacf574e7,
- 0xaf57b82c, 0xc4b52fd6, 0xad6b8b96, 0x4f763ff2, 0x5ee7d1d8, 0x40eb5ae2,
- 0x923a63d0, 0x4953efc0, 0xe7906ef5, 0x87d39ba5, 0x80e09f80, 0xee77bd55,
- 0xe8fd8389, 0x7b41ec80, 0x3eed521a, 0x9bdab273, 0xff008d25, 0x892ca8cd,
- 0xf1a7a3ae, 0x0441c293, 0xb3ad0ee2, 0x0dbdc962, 0xa3c23b56, 0xc5f662d4,
- 0x0cf8d7ba, 0xc107d7a7, 0xc6c71fe8, 0xc750fe03, 0x5087203d, 0x79b70f0e,
- 0x2ed43f58, 0x9b65ef82, 0xdee96767, 0xb16a90c5, 0x8453e51e, 0x53a90967,
- 0x5bf235b2, 0x6964af1d, 0x05949676, 0xeaffa5df, 0x8a3157a5, 0x444c1267,
- 0x30e250bd, 0xbaa97526, 0x5c9204fb, 0x29f80160, 0x892dc0a4, 0xc8b52a40,
- 0x82d236ef, 0x5baa83a9, 0x2aa8fdec, 0x64f27202, 0x0417bbef, 0xeebc28d3,
- 0x1c1fb946, 0xe9c5c84a, 0x13dfff70, 0xafc0d6e7, 0xf9c2eacd, 0xc22aa598,
- 0x3774c5e4, 0xd04223e8, 0xf4a3be4f, 0x9f9d5354, 0x7f48f405, 0x0cff707c,
- 0x3f3a0f4d, 0xafe5fb97, 0x74a20f40, 0xfb59deca, 0x50d50931, 0x28f84310,
- 0x132755fa, 0x9ad83ef6, 0xded688b7, 0x6fe72bf8, 0x728fdc12, 0x3fa241cc,
- 0xb1079a11, 0x26b6f20a, 0x385cdbee, 0x49b87447, 0xbb42f418, 0x34ed8483,
- 0x4e968c75, 0x95dff96b, 0x3a1af34d, 0x97d44f75, 0xca82f91b, 0x2db8c335,
- 0xefda3f08, 0x3f7e8667, 0xd9fbf433, 0xc2abf5f7, 0xe8d96029, 0x5609f785,
- 0xb8701756, 0x1c2cf1b1, 0xa33e146e, 0x62337de0, 0x79f979b2, 0xc6d5c238,
- 0xfa866367, 0x6c83af14, 0x07a708e9, 0x2045f6e2, 0xd624966e, 0x577bb013,
- 0xa69f6c08, 0x4d0e053f, 0x20b6e23b, 0xc7c7de1f, 0xf4636419, 0xef5bdeae,
- 0xe78adf5b, 0x5bea7d1a, 0x8b6fabfb, 0xdfd9df5d, 0xe731ec7c, 0x4ce543f3,
- 0xfe6f0be5, 0x7b61ce09, 0x829b8de5, 0x6f274732, 0x9c28d906, 0x7f8fe22a,
- 0x985f89db, 0xa21968de, 0xe80d9fc7, 0x6d8fd295, 0x11bbfe84, 0xcbd1fdef,
- 0x9a0ebe3c, 0x75d2a477, 0x3f8f94fd, 0x639d89b5, 0xf984b6df, 0xe7b9a8dd,
- 0xf2b7fa83, 0x14b53ffa, 0x18e0ffa1, 0xb6e9177f, 0xde17a67a, 0xe788af76,
- 0xfdde7dcd, 0xff285f81, 0x0854bedc, 0xbd63d385, 0xe09a4463, 0x3e5cd47e,
- 0x205df1be, 0xade4f13f, 0x0bbd6311, 0xbd4ce8c4, 0x6f7c6557, 0xe0292160,
- 0xbfe93def, 0x91bab26f, 0xd61e410e, 0x4bee8e8e, 0x8e9475c1, 0x74a49f41,
- 0x70ece70c, 0x3ce3063d, 0xf38b0a5c, 0xe78a18e8, 0x3b3caa63, 0xe1c4f1eb,
- 0xd34deafe, 0x78b817bd, 0x5e3927bc, 0x73a5af23, 0x2b7bdd36, 0x0537b235,
- 0xee7c95e4, 0xa6a1e232, 0x1e8d42af, 0xea9ca68f, 0x10ccc8a1, 0x277284a6,
- 0x9c810a45, 0xa405dc93, 0x9958f408, 0x5f5aa7d1, 0x57acbc49, 0xfe8d7c6f,
- 0x878801bb, 0x3be2e5d2, 0xd728c93c, 0xe00b05ed, 0xf5cae893, 0xe97d1dfa,
- 0xad95b821, 0x9dd606bb, 0x353d77de, 0xfa8bd78a, 0xf7de84f3, 0x3f302c69,
- 0xd379ecd1, 0x0ffbf303, 0xa51f8099, 0x27bc7c2f, 0x677e1443, 0xde318343,
- 0x3e9b8c43, 0xdf57c612, 0x9d535c45, 0x2bade782, 0x2b897bf8, 0xfe6147aa,
- 0xe59efe7e, 0xa60f6aaa, 0xde2cfc2a, 0xcfc77c5a, 0x6ff58232, 0x24fc7371,
- 0xfc7c389a, 0x52592fa8, 0xd01cf0aa, 0xc30aaeea, 0x086459fb, 0xda6027dd,
- 0x9f845aee, 0x87e826e2, 0x6f31f5a4, 0xe54d3c86, 0x0f88d1fa, 0x8a455dc9,
- 0xddbe7968, 0xcdc020ff, 0x7ba419ea, 0x329cd01f, 0x03df7bec, 0xf5a7a5ec,
- 0x72262e4c, 0x27c2327a, 0x65ef6151, 0x9fd474aa, 0xe3c3555e, 0xf6ae1f74,
- 0xdfc35a62, 0x7781aa81, 0x3d48147f, 0xedc81f98, 0x470a1ac4, 0xdf08fef8,
- 0x73aa6b37, 0x972cfcb1, 0xaaa68957, 0x25c032fd, 0x66ff3081, 0xc90c9062,
- 0x14042c21, 0xc482527e, 0x9cf57903, 0xe6c69dd0, 0x7441e9cd, 0xdc77864b,
- 0x5e008f3c, 0x26cb0eea, 0x4b8b93f0, 0x681f25af, 0xe59c59e8, 0x99bf078b,
- 0xb00bf0e8, 0x78003dff, 0x4759f3a5, 0x96ef85e7, 0xc9587a72, 0xd39abef1,
- 0x1f407dc3, 0xd3907d34, 0xfae8afc5, 0x65e35f21, 0xe6d601f7, 0xc4b778b3,
- 0xc77f130c, 0xf1b44c2c, 0x16def164, 0x2275d0a2, 0xc5307a8f, 0x5bc8ea77,
- 0xfb17a466, 0xa113e268, 0x43bbadfc, 0x82c91dec, 0xe337d854, 0x272377d5,
- 0xe367e27a, 0xc4b0d545, 0x991373df, 0xf311d1dd, 0xef1ac67d, 0xefd80b01,
- 0xeec7cdfd, 0xa4afa5f5, 0xd9ebd9e3, 0xfe01c5bd, 0x688bd982, 0xf54f51de,
- 0x8ce5026f, 0xde741d2e, 0xc67d1a45, 0xbffd8fde, 0x51cd7ed4, 0x7be7c51b,
- 0xe45141b0, 0xb87ebaff, 0x614be015, 0xc73f01ed, 0x2a4172c3, 0xf1c3fff0,
- 0x8735fdb1, 0x83d2326d, 0x1d32fb2b, 0x3ec9d73d, 0x989ee76c, 0x3afba3a9,
- 0xa612772e, 0x577dd04e, 0x6defcce5, 0xb12eef4c, 0xbcc2cffb, 0xc5d1ce92,
- 0xbc4a7e51, 0xa9dcb621, 0xdc209591, 0xc319afdf, 0xa6705ce4, 0x3eabf4c2,
- 0xa7c98472, 0x6f32e4b3, 0x645f4350, 0xf03d4114, 0xee8a998b, 0xc035c1dd,
- 0x7e5e941f, 0x057ee9cd, 0xc54d01f0, 0x4dd20a11, 0xda1374c2, 0x5f38aba9,
- 0x68f9cfdd, 0x87a3e72d, 0xc2467f80, 0xdf8cae3b, 0x051de224, 0x8b8d48fb,
- 0xc0258fbd, 0x8d49b4ff, 0xe85cfe6d, 0xb32de6af, 0x350fe700, 0x11752f92,
- 0x977e29e4, 0xef8f307b, 0xedeb06ea, 0xbbf1589e, 0x9293ed4b, 0xc95e14ec,
- 0xdfbf8676, 0xfe2167d4, 0x316f6e2c, 0xd8724bac, 0x19afaed0, 0x658e2969,
- 0xbdecd81f, 0x53b74ef0, 0x9fc80f78, 0x817f6bd0, 0x666ea17b, 0x37fdc20e,
- 0x06399f70, 0x33b18cfd, 0x04864079, 0xff0d08c9, 0xdcf7f1d7, 0x46482788,
- 0xf2c0e469, 0xf808f38b, 0x7ff2fa77, 0x136ff23f, 0x02357f93, 0x780c57df,
- 0x5531f755, 0xd78049fe, 0xb9e77d01, 0xdd5ca2f2, 0xcb997b3d, 0x3cbd636f,
- 0x4f9d9dbb, 0x2fc46f11, 0x70a72df4, 0xce6bb3ca, 0x09c49495, 0x5d95efbd,
- 0x461d6315, 0xf61277b9, 0x9225903f, 0x5905df1f, 0x191e78a8, 0x8fe4f20f,
- 0x3fa5fe2c, 0xaf1d40fd, 0xee315ce8, 0x72e785f3, 0xae299f71, 0x20fe45cf,
- 0xd8d78de0, 0x7e1a2749, 0x9dbc02e6, 0xa3e7e7a8, 0xe208720d, 0xbc6ff652,
- 0x14d9a1e7, 0x88370b9e, 0xd7fefeec, 0x6a277ddf, 0xb6481be2, 0xf53af507,
- 0xa113b43d, 0x73da5d3b, 0x58dfc2ec, 0xf62fa07d, 0x3614cfb7, 0x6bdfb6c4,
- 0x53d057e0, 0x1e801f29, 0x4881f54a, 0x5f85f418, 0x08bdf15b, 0x68dc1f35,
- 0x540ef98f, 0x195a7dbe, 0xddbe67d0, 0xc4a42777, 0xfafe8091, 0x8ea1e6fe,
- 0xa67c1c7b, 0x28f64e70, 0x70a5b38f, 0x9ff3a99f, 0xe3b273b1, 0x2c421fdc,
- 0x78db94fd, 0x729fa7b9, 0x21678b17, 0xeae5d8ee, 0x3b714e7c, 0x7b46e170,
- 0xfd8c7968, 0xefbf217c, 0x479f90b7, 0xd53ff8a8, 0xba3137ab, 0x3f2ffb51,
- 0xdfe18a37, 0x53c26740, 0x3eae9063, 0x7fa3243d, 0x4aea784d, 0xf2a52f7c,
- 0x97eb059c, 0x415fde8b, 0x4d79161c, 0xf3bbba44, 0x873c38f0, 0xc3bc32ea,
- 0xb7f387b8, 0x2b9e169a, 0x8599e9d5, 0xec0a05a1, 0x2ae785cb, 0xde211e91,
- 0x1397ee11, 0x934bf6f2, 0x13574e24, 0x6991fda0, 0xa2bd69cb, 0x64bf464e,
- 0xfd12b062, 0xef768d84, 0xdae431fd, 0xe747bb1e, 0x2cea2837, 0x2389fec7,
- 0xe7351248, 0x7bf90bf5, 0xd8e745e1, 0x1dc4847b, 0xcf402924, 0xe944de5c,
- 0x6c6eff52, 0xcbe18997, 0xf857deb8, 0x5de95f3a, 0xd67e84ef, 0x5eb663fb,
- 0x7517cfbe, 0xf5d61ae6, 0xd6b1f1bb, 0x44cf5d15, 0xdfce5f6c, 0x31372df9,
- 0x9fe5abbc, 0xf4d5f1f3, 0xb82cf578, 0xf84a4361, 0xa185903b, 0xff78153b,
- 0x3e21b0a8, 0xb3acd041, 0x5d56fea8, 0xfd61495c, 0xaaff7c3c, 0x329e61a8,
- 0x7a47235f, 0xecfc14f1, 0xa22349a5, 0x81fcfa78, 0x1dcb699e, 0x1c14afb0,
- 0xfe3b3e03, 0xe79cc564, 0xf0cbf409, 0x8e095276, 0x72b942ad, 0x3dd62ba7,
- 0x788dcf94, 0x1b78e7ab, 0x35a32411, 0x97c54672, 0x4df1fdb1, 0xf9c17765,
- 0xecf5f1f4, 0xe5fe8f75, 0x1a7c6c4c, 0x3076e8e1, 0x71e9a9f8, 0x2ffb2fba,
- 0xeb978e08, 0x85fa9be2, 0x0abfc723, 0xd53bf527, 0x1c0eacab, 0xa37bb097,
- 0x0417b9f5, 0x8cf8e8bf, 0xbe2a4e3e, 0x7e41eb91, 0x7c093951, 0x07c9ea7a,
- 0xe5db6ac6, 0x840d27db, 0x85ed4871, 0x6fdd8f9d, 0xfd41a7f7, 0x21ef64e0,
- 0xd15bca0f, 0x5dd7435b, 0x7768f712, 0xdfab5718, 0x935656bf, 0x4a5fc12b,
- 0xc12b87ed, 0x05b5436f, 0xe6a8a3d4, 0x847d05e0, 0x7ac5f156, 0x83926a17,
- 0x5656b3f9, 0x95bfa157, 0x0dc48258, 0xf8c23d7e, 0x42cc9c92, 0xd0e497ff,
- 0xec8a01eb, 0x4dbf8377, 0x6591f7e1, 0x3d26bfc9, 0xc4d9ec1b, 0xbe06a08c,
- 0xbc583957, 0xc594dac4, 0xb7438841, 0x38719f80, 0xeace37fa, 0xa517fbec,
- 0xdd280385, 0xda7dcfa9, 0xe5cbe846, 0xfe8216c4, 0xbbf4d1b4, 0x74891e76,
- 0x4c7dbade, 0xe2c9170f, 0x890f73c2, 0x8715bf70, 0x7282fd07, 0xc3973578,
- 0xdc2eedcb, 0x645d567f, 0x8ea0fb42, 0x0b7ec3fb, 0x8b84307e, 0x84327684,
- 0x257d40dd, 0xb0eb882e, 0xd0447ac2, 0x7798c3db, 0x22328bc2, 0x4025b13e,
- 0x04789e3e, 0xe1200fc8, 0xf687a055, 0x0bbcea4c, 0xfd58a7be, 0x5fbf01b3,
- 0x151c76a4, 0xe05a0fc0, 0x5ce004bf, 0x3c33062f, 0x62e3feb4, 0xa5ea0324,
- 0x12b7a2d1, 0xc4117a58, 0xe735fb41, 0xce1dec2b, 0x9bec5e68, 0x64a968bf,
- 0xfaf86f38, 0x2ff96d12, 0x0762beac, 0xf656fbec, 0x07e24d7e, 0x9ab9ca02,
- 0x01773f5e, 0x71a9dbde, 0xd23d7f30, 0x21d5d005, 0x959f4fb6, 0xe809713c,
- 0xf5951b3f, 0x5e1e6ea2, 0x76e25e5d, 0x53a5134d, 0xf4ab8bf0, 0x99f24231,
- 0xae2e8e80, 0x78b5dfa5, 0xc15fa18c, 0x39fa2338, 0x47e7504f, 0x157a45c7,
- 0xfdb0e5cf, 0x7b0f40d6, 0xa0ff3604, 0x0fecced5, 0xaf011412, 0x93c255b3,
- 0x3c7cb056, 0xddf07f51, 0x3f55b7cf, 0xf2c15937, 0xcc0b966e, 0xc66ae767,
- 0x5f6eccf9, 0xe5fe01dd, 0x0ba9edd9, 0xb6659ce0, 0x208ff2e5, 0x0e4723dd,
- 0xfc4e41d8, 0xf9a3bd8c, 0xca2f23d3, 0xbc778a20, 0x43ef11b1, 0x71f9ce3f,
- 0x80c8890e, 0x2b713f7f, 0xc21e4fcc, 0x5e27cdf5, 0xc1916f9e, 0x1c2dbd7e,
- 0x9a3af9ba, 0xd0c5fdbb, 0xcd5a6075, 0x09791439, 0x716fe6d0, 0x5a2fa1e7,
- 0x7de6d76d, 0xbb59e599, 0xdff81c28, 0xb82c90c1, 0x2dbae8ae, 0x9d750708,
- 0xa3e226b4, 0xfdfc4e17, 0xbd2e1520, 0x7adfb6eb, 0xfb0bf82d, 0x2db36f93,
- 0x71623e63, 0x465e6cb9, 0x45067d38, 0xc3915ef0, 0xf2e807b7, 0x1daf8761,
- 0x12dca4f8, 0x21869349, 0x5f2184df, 0x4a2ffa29, 0x78f870a2, 0x8192ffa8,
- 0x018e8f00, 0xbe67a417, 0xd5fce9ca, 0x83f7def4, 0xbe99d113, 0x66c1f986,
- 0xb55b7a70, 0x9b8c4de3, 0x7b30f8fc, 0xf442a90f, 0xfa0f7f5c, 0x4b1244bf,
- 0x57d355ef, 0x2de61fb9, 0x9d1f7a87, 0xc48673ad, 0xd5a33de0, 0x667af78e,
- 0xfd3a8b64, 0xc0b6467b, 0xc63ad7e3, 0x4bd3a4de, 0xeeba7057, 0x11c40fdb,
- 0xb059fb18, 0x55da3274, 0x24f7153b, 0x0dc1ff90, 0x4c16ce8c, 0x671089f5,
- 0x808d613c, 0x1ff188fe, 0x87901276, 0x09e2ea0b, 0xb82f839c, 0xbc16717b,
- 0xe1d95097, 0x3904eb69, 0xe0bc1219, 0xef164b47, 0x9d25f8c8, 0xd807c3d7,
- 0x3bf90c3e, 0x9f0e9e60, 0x2bf1a1c7, 0x1955c977, 0xdbeba06e, 0x0b903e1d,
- 0xbdf26ef3, 0x922d780d, 0x76b5fbc2, 0x3cdbbcc8, 0xf31f40b9, 0x4c3eac5a,
- 0x51b2442d, 0x224f36b9, 0x15934816, 0xdf215922, 0xece7d4fe, 0x3bad86b0,
- 0xec2c46d9, 0x80afe1fb, 0xacdf2e4e, 0xa63dd6e8, 0x51ff9f45, 0x119f3e9b,
- 0x0eb3e7d6, 0x80b7f3e9, 0x87d1a31a, 0xe765ec0e, 0xd86765dc, 0x05e7c13d,
- 0x7fc083d8, 0x37b9466a, 0x073daca5, 0x3ccf4dce, 0xf94134eb, 0xfd986f9e,
- 0xc562d916, 0xbff6cbf7, 0x44b62363, 0xbad4c778, 0xd8cfca11, 0xffc0725a,
- 0xfc63eb44, 0x4735dd03, 0xf3b1fd82, 0x0cced532, 0xcec49c61, 0x7b9c596f,
- 0x04398b64, 0x7667b1e7, 0xd02cf53f, 0x832d99dd, 0x5e79ef51, 0xdfa09a08,
- 0xaf0c7de0, 0x9d2e6c13, 0xacdb29fc, 0x3846ebb7, 0x73d53e99, 0xf10b994a,
- 0xebd4974f, 0x48697dd7, 0x64ed1f9f, 0xd13e67f2, 0x73874f7c, 0x14aacf66,
- 0x48278ba0, 0x5983fbcc, 0x9f7f264e, 0xed515a7e, 0x33bf916c, 0xd1493c46,
- 0xa27b4f7b, 0x064b3fe7, 0xc0001c43, 0x7bf45862, 0xb55c6199, 0x7cb96fff,
- 0xfa7ee44f, 0xc222abc8, 0xb17574e7, 0x57b89cee, 0xa6f6ad3f, 0x33ecd54c,
- 0x93fbf585, 0xb85ea1e6, 0xd6be693f, 0x3072db2e, 0x738856e9, 0xdfe12cd9,
- 0xfd9f2a4f, 0x121343e4, 0x02d8bbe1, 0x1f7285f3, 0x2f2d1fd8, 0xd51ea0b9,
- 0x71b5333f, 0xe3f54523, 0xf66aa652, 0x974a1fd7, 0xbb4aefbd, 0xe5767c19,
- 0x1d78dc16, 0x835977c5, 0x656a85e8, 0xfbff372d, 0x837b8018, 0xcb5cf78c,
- 0xbef8c9b7, 0x0af1a079, 0x359413f4, 0xef879ebf, 0xe79fade8, 0x48e57985,
- 0x44cc40a4, 0x904dc0d7, 0x81df6c9e, 0xfd95d5ef, 0x3c914eb5, 0x7d3d5f30,
- 0x3f437a50, 0x7280d517, 0xf01e006e, 0x54f8c32d, 0xae11bbf5, 0x7b7d2125,
- 0x17febe23, 0x33fa37a7, 0x63778b4a, 0x83d301bd, 0xca4877f8, 0xa3b95297,
- 0x3fca2fb1, 0x38f8c5ac, 0x542838e3, 0xb0d0e735, 0x1f90797f, 0x271f7cad,
- 0xc7872582, 0x79670e8f, 0xe80f377c, 0x197fd60b, 0xfb81ea99, 0x7c90378d,
- 0xc2179f48, 0xe322890f, 0x6c3bf46b, 0x775f23b5, 0xfc9f3bb9, 0xf343d01d,
- 0x18c73c18, 0x767befc4, 0xdef8c279, 0x0ff7faa0, 0x5f2cdcba, 0xf8c56eda,
- 0x2b1f338a, 0x4196cf28, 0x7fd4175c, 0xd1326ad6, 0xb6cce67d, 0x4e219301,
- 0xbd85abb0, 0x65ba7b2f, 0x7be564c0, 0xff2347f6, 0x31d6fbaa, 0x6fee95f8,
- 0x1b7d384f, 0x15df009c, 0x79328e2c, 0x55465540, 0xeda93c0c, 0x0caa9512,
- 0xb7221fb0, 0x991bbc3b, 0x720e93be, 0x053facff, 0xdc79f9ed, 0xae37b17f,
- 0xd7e819e0, 0xe8faeb49, 0xe24384bf, 0x0fafa046, 0xee5def44, 0xb5f3d1e1,
- 0xbc7ed985, 0x30564a4f, 0x4481663b, 0x4fd512c2, 0x1fbc8017, 0x8394798b,
- 0x8c041a0b, 0x56b85a2b, 0xef781ebf, 0x0377fb54, 0x5e2fe18a, 0x9138870d,
- 0x1b8b4c16, 0xb025e5f4, 0xfe30b87f, 0x4bcfcf03, 0x70e5f49b, 0xbdf41093,
- 0xccefe6f2, 0x39f6e0b1, 0x7be7d751, 0x1f93a9c9, 0x8f8fca32, 0x5f5c02c4,
- 0x909b5819, 0x702afdf2, 0x42ca6e77, 0xa59ee20a, 0x66165213, 0x04183be1,
- 0x1645a7f6, 0xb2657412, 0x8003bc3c, 0xc9fc83ac, 0xf5825bde, 0x9487ef69,
- 0xa1e1254d, 0x613ae8ae, 0xf272da7d, 0x5963c306, 0xe31e10bb, 0x8237de8a,
- 0x95eb6a75, 0x3797f5f3, 0x837e759b, 0x84f3880a, 0xefd69538, 0x797ebacc,
- 0x37dd1cfc, 0xe7e29589, 0x1bb95ee1, 0xfc5634ba, 0xa70e51f9, 0x4c2e6f87,
- 0x15fcbe05, 0x388381e8, 0x3da97320, 0x0271c20a, 0x8e85b803, 0xcdeacb63,
- 0x72ce7963, 0xf9d4ff96, 0x10fd5e55, 0x7ec9376a, 0x2058573c, 0xf70cbc16,
- 0xfdba669a, 0x17fc025f, 0x12697c98, 0x246fa7f2, 0x652e47c6, 0xb3247feb,
- 0x18aad2ea, 0xc78aa9f6, 0x782d0adf, 0xcddc17be, 0x76673df6, 0x3bfad644,
- 0xee4c5de3, 0xc4e81dc4, 0x0ec8fe78, 0xae11ef01, 0x3de18e17, 0x78d7f5bb,
- 0x29cfd808, 0x17206f14, 0x05640bd7, 0xdd9563bc, 0x978ef33a, 0x36d97f00,
- 0x5a2a77d4, 0x0e158927, 0x77d33f5c, 0x708d55ec, 0x773c98ce, 0x33d02654,
- 0x1bdcf75d, 0x83cbbbe0, 0x183aa5e3, 0x0f2ca41d, 0x0d1e2fa6, 0xf1dc17e3,
- 0x18dbf012, 0x4d3fde1b, 0x2672b0a6, 0xf406ba60, 0xb1921497, 0xca77e41f,
- 0xf8264f74, 0xb1761f5a, 0xc49a0671, 0xcf4133b9, 0x84f964ca, 0x46df057b,
- 0xb875ae24, 0xc93364fe, 0x77c2f987, 0x602d13d0, 0x887963cf, 0x554a79e1,
- 0x3c9f8c06, 0x4a89a59c, 0x5e82e318, 0xcedef151, 0xb89673e2, 0x25e3ca09,
- 0x4e4a4d5f, 0xe95feda0, 0x952d86a2, 0x510caf53, 0x03b0e1f5, 0x623210f4,
- 0xf5cfab14, 0x2c1925e1, 0x4d313dee, 0xbd5857d5, 0x9717d91e, 0x75f3f205,
- 0xe67f17a6, 0x9c41c5f0, 0xec4a15da, 0x1c49dbb8, 0x3673814f, 0xfff8d212,
- 0xc0beb303, 0x73811c7b, 0xecd2122e, 0x9b2ef007, 0xbcb37e36, 0x17be00f8,
- 0x303a415c, 0x45a2b80e, 0x857a6f1f, 0x2ab8f62d, 0x99ce079d, 0x42ed1048,
- 0xc0271f0a, 0xce0ab227, 0x057b8271, 0xce06aff4, 0x19a82429, 0x412e703f,
- 0x679def9f, 0xad13f612, 0xdaf5f447, 0x247ac4be, 0xe305d3b7, 0x713bbb74,
- 0x939c08bf, 0xafba9db0, 0x414c84f4, 0xdd6fea99, 0xc3de561e, 0xeb55a3df,
- 0xcf75fdab, 0x977df852, 0x55dbf608, 0x8511054d, 0x9feda3cb, 0xbcb39fa0,
- 0x45c23f7d, 0x7c2887a5, 0x81a824ec, 0x474d524f, 0xfb7944d8, 0x584d0fe7,
- 0x4a52fa3d, 0x1f38075a, 0xf6ae2707, 0xa2e5a44d, 0xf6d7c749, 0x473e5eec,
- 0x49b0f2f1, 0x2bc8fee4, 0xa89d4f57, 0xbdfaf3c9, 0xbe3f83ed, 0x47b3ca1a,
- 0x1ecbf6b3, 0xcb0feaba, 0xa25ca8a5, 0x702b48eb, 0x4316f26a, 0x63f341de,
- 0xa1b77934, 0x9e50d13c, 0x610fc862, 0xe19cbbf5, 0xc84bd134, 0x5ca687da,
- 0x03dfc12d, 0x81cf0d4a, 0xc56bfb9b, 0xefe1abbc, 0xb364562b, 0xd95817bf,
- 0x3859782e, 0x655f8313, 0xa76cf9ef, 0xc03460b2, 0x9065e3a1, 0x826de503,
- 0x4770f41b, 0xe630b6cb, 0xd3479da1, 0x7bdd85ae, 0x86396f2a, 0x7fedfaed,
- 0xf8f90994, 0x63ef51fe, 0x15c5f3bd, 0x78fae991, 0x19e2fef3, 0x26fe088f,
- 0x3be8b8d7, 0xdedb5dbd, 0x37bdfe8c, 0x53ba472a, 0x8e51077d, 0x067fee1a,
- 0x288e3e60, 0xbc70a89f, 0x7c59d47f, 0x31ddf0b7, 0xdb6047ed, 0x64f92fb7,
- 0x7f91e819, 0x0e3138ad, 0xfb782af4, 0xdf8df610, 0x614ba10a, 0xf8947a1f,
- 0x6f71852f, 0x3f78b8af, 0x547d913c, 0xde0c7cee, 0x87cffdb5, 0x7f0d5ee6,
- 0xb3a8eeef, 0xa9fc2873, 0x52ae239e, 0x81d1c7c4, 0x4292f89d, 0xcb195c66,
- 0x6a1ced0f, 0x5db7f9a2, 0xe2fe59eb, 0x2f20c7ce, 0xed632dc4, 0x150e74c7,
- 0x2c3260dd, 0x726dfc47, 0x3ff7e6c7, 0xcea33972, 0xbee1eeef, 0xa42e0097,
- 0x7037ed9c, 0xe542d0bd, 0xd3d29ce9, 0x7851375b, 0x1d85f9cc, 0xaea6dce5,
- 0xfa65af1b, 0xe200b070, 0xbc39928d, 0xb9443f71, 0x90dea12e, 0x42607b0a,
- 0xb4ce9f14, 0x17ee0f0e, 0x036d5597, 0xce79207d, 0x1a2fdc68, 0xb8acbe9c,
- 0x4374d171, 0xe2b34b22, 0x8bae4cdc, 0x961fbc26, 0xf5138f7c, 0x77f15fa5,
- 0x21df29ae, 0x5e38387d, 0xbb3173de, 0xf3173dec, 0x4e741c2b, 0x11de7ec3,
- 0x222deb7c, 0x056824a4, 0x50d896bc, 0x91b5b90f, 0xd72a15ca, 0xebbcf8eb,
- 0xfe8a5dd6, 0x5fc15b82, 0xfbbe1a3b, 0x47461352, 0x0cbafcf5, 0xed44779a,
- 0xbe99bab0, 0xda7bed54, 0x5cac8d75, 0xe9755b95, 0x5fbabdac, 0x71b0d725,
- 0xe9757f92, 0x5d875846, 0x8bf5e762, 0xb8dc8d66, 0x1bfff70c, 0x1fc0e2b2,
- 0x82a5f3e2, 0xc961fcdd, 0x9fe81330, 0x861a7e2a, 0xd172befb, 0x73f29ff2,
- 0xbd4f1516, 0x5b1c65f6, 0xea9102f7, 0x3fbd740f, 0xfd71fb72, 0xcb189f54,
- 0x3e99b30e, 0x4cd74591, 0x5225f034, 0xfef838e7, 0x694e083f, 0x147feeb0,
- 0xbc777f4e, 0xf73ef4f4, 0xbe61325e, 0xe84f4b15, 0xb870bdef, 0xcb0856ff,
- 0xf79ad9c9, 0xb077e848, 0xfa76bf33, 0xce69c7c7, 0x53dce7e7, 0xbaa77a81,
- 0x77cffb1e, 0x64dfc3e5, 0x51a7f234, 0x8efa3c2f, 0x3ff82d65, 0x282d2a8e,
- 0x4b5e8f8f, 0x51c5fef0, 0xaa941efe, 0xa2fce6d7, 0xd3b015ec, 0x4889c536,
- 0xbe09f71f, 0x7dc78054, 0xfee01e94, 0xa28f1ab6, 0xf175c7ee, 0x4085f5a1,
- 0xc68f370f, 0x881eef73, 0x4b7a848c, 0x2eb8df99, 0xf0ed13be, 0x371ef1ba,
- 0x07d0099d, 0x5b3231e2, 0x5d4fff41, 0xbab3a306, 0x3ef0cb92, 0x2097a505,
- 0xe8cd9fb6, 0x41266eae, 0x766ea1bb, 0x959bd20a, 0x9f30ac84, 0xa927e8fe,
- 0x10a3c586, 0x7b5637c9, 0x638c1d6e, 0x767b117e, 0x41378ee7, 0x456b5d8f,
- 0x8950163d, 0xc9b51de7, 0x074a5f38, 0xaa5748c5, 0xd49bf67d, 0x0f68fdd0,
- 0x5feed17a, 0xc3cdf4ed, 0xeed2fff9, 0x5837f981, 0x264b1ac9, 0x05643598,
- 0x1f3e49ca, 0xc608fb52, 0x7ae5cc2f, 0x67c57be1, 0xfc7fa09d, 0xff504e3c,
- 0xec0fa52e, 0x9584f9f0, 0x7ed7bfcf, 0xf9a9ec0c, 0x6277b2f7, 0x3e699ac9,
- 0x9d05f9fd, 0xb9f8126b, 0xc47d4ff9, 0x87e37409, 0xffe82e76, 0xff709cbf,
- 0xbb2f7fc6, 0xb4824acf, 0xfb68a8fd, 0xc1df81fb, 0xf9b22e5f, 0x27bb6a93,
- 0xf7a0fbd6, 0x44bf71c7, 0xed3e23ed, 0xc638ea78, 0xf8bda97e, 0xc28bc000,
- 0x8cf70c3d, 0x7f64bf22, 0xdf38c097, 0xa0f22544, 0xa9cf9695, 0xefe1e316,
- 0x3a97fb88, 0x7ceabd71, 0xae4726e7, 0xa1847f44, 0xcaf6e3ff, 0xab67f01c,
- 0x57b90ff6, 0x5c21ef63, 0x845e6894, 0xb411f87b, 0xe77cfaa3, 0xeed1b1f6,
- 0xb35be424, 0xdc6f5eb6, 0xcc3047be, 0x4795d39f, 0x7e6f0090, 0x28af1e7e,
- 0x5ef83991, 0x2ade6194, 0xba73773c, 0x08c2e953, 0xc0fdddef, 0x1ce9513b,
- 0x97fafd0a, 0xc64e119a, 0xf4fdd5fe, 0x1fe52b11, 0x82f5774a, 0x7f5af480,
- 0xc7f71db7, 0x49e46b1e, 0xefb8d7bc, 0x7777c46a, 0x4103cd89, 0xb5528f5a,
- 0xf633cf1d, 0x9e8cf3b1, 0x81239d91, 0x9ae9ba9f, 0xdd3f147d, 0x418d8aaf,
- 0xd5049d41, 0x37155e8f, 0xef77fd02, 0xb3f586be, 0x89dececc, 0xbdc30806,
- 0xaadfe0c4, 0x81f39fc1, 0x002fbd89, 0x6b458f7f, 0xd1bdc377, 0xbca8cce2,
- 0x180281e8, 0x573d4dbf, 0x38e097f2, 0x3df0dab7, 0xe0934a81, 0xb2abbd03,
- 0x67bc32f4, 0xd1dff840, 0xa568e551, 0x99a3da89, 0x34afbe51, 0x31723fbd,
- 0x491293f3, 0xf5a347e3, 0xb03b045e, 0x03b6b2dc, 0x49bb51ef, 0x6843eff4,
- 0x6b95a5fc, 0xf3037ccf, 0xf8356caf, 0x83fe0c11, 0xa53d2d52, 0xf504e947,
- 0x531f907e, 0x775bde09, 0xbf3dbcf2, 0x018efd03, 0xf030ce7e, 0xd6d77b00,
- 0xc042dd99, 0xc9381aaf, 0xed0996f4, 0x0ec1078d, 0x18efcf8f, 0x700dcb0a,
- 0x9ef19f3f, 0x75f6f8c9, 0xaa95d822, 0x6bb1a3be, 0x8c61bd2f, 0x4df76536,
- 0xf1864ec1, 0xf013e13a, 0xc9f6c48d, 0xf74803ff, 0x800023ad, 0x00008000,
- 0x00088b1f, 0x00000000, 0x7dc5ff00, 0xd554780b, 0x733ef0b5, 0x9992bcce,
- 0x9264cce4, 0x0927de4c, 0x27010084, 0xd4500421, 0xe6a2bc21, 0xa2d101da,
- 0x3c2438b5, 0xa0992112, 0xf7ad8b95, 0x24844032, 0x111a0804, 0xa284e028,
- 0x17edaf62, 0x04c0622c, 0x16c45407, 0x6b5ec5fb, 0x46f7f6d5, 0x485ca008,
- 0x6c5cb046, 0xad7bfcb5, 0x67324fbd, 0xde952892, 0x1e9f7cde, 0xecfbd9f6,
- 0xaf6b5ac7, 0xa5b3def7, 0x90d74b32, 0x44b44849, 0xc8485488, 0xbb11a6c2,
- 0xfe840957, 0x5b6673b9, 0x862a7909, 0x83c9e03c, 0x33c8abb2, 0x72599086,
- 0x9e3c8c71, 0xb1722390, 0xf7878e59, 0xda1e9181, 0x08e3f88e, 0x55c84499,
- 0xe075bbf8, 0x24203693, 0x625dbfbe, 0x8d7e4d76, 0x0e76e865, 0x83a7fd03,
- 0xd8b6d090, 0x8f986ec0, 0xd1796024, 0x0d2df46f, 0x613a3f38, 0x7687df3a,
- 0xfe600666, 0x40c9a415, 0x4a5909b2, 0xd2220602, 0x8fe22676, 0xda4fa029,
- 0x173e962c, 0x2512356f, 0x55dfe097, 0x40655ffa, 0x6ccd265b, 0xe0a54b5e,
- 0x90862111, 0xfb13a425, 0xdb57b259, 0x1234e96e, 0x2afad2b4, 0xc3460913,
- 0x5f5b55b3, 0x0f38424d, 0xa355db5f, 0x44d27fa6, 0x36db8508, 0x3b662133,
- 0xf99dc9cc, 0xe87f9d38, 0xb76bbd6d, 0x6869c842, 0x870fd492, 0x38e2d88e,
- 0xa8947380, 0x568675c3, 0xd3760745, 0x48eb7675, 0xb70a3ec5, 0xc0f2364d,
- 0x59ecfa6c, 0x0d8738a9, 0x9d8c7043, 0x3c20663d, 0x2b990e1b, 0x6e7f1402,
- 0x55708759, 0xd5895fdf, 0x40cbb963, 0x7d695a2a, 0x5fda6ad1, 0xf57d7f5e,
- 0x7c2f163d, 0x70165337, 0xbbe780de, 0x0d64cf00, 0x3ded077e, 0x71a8fc74,
- 0x777ea9ec, 0xcdfb5f67, 0xfe14df0c, 0x952dff30, 0x27802d51, 0x0493b922,
- 0x04759407, 0x63cf2ee9, 0x0fefd2f0, 0xfd7e7405, 0x5849f40d, 0x31ad7f7b,
- 0x97b62cf0, 0xe5a0ade7, 0xb9e69f43, 0x489c281a, 0xd03e7bae, 0x5173d2c1,
- 0xf1c1d00a, 0xff5f3f73, 0xf17f5a5b, 0xa4628353, 0x36800bf5, 0x090f1e28,
- 0xe7684ade, 0x3c8a37bf, 0x352ddf4b, 0xbb8c3710, 0x8088c0f4, 0x807bf69f,
- 0xb0feb196, 0x1a59c715, 0x90b6dde3, 0xa5f4b3f6, 0x40a51778, 0xf03eaaf2,
- 0xdf5073c2, 0x4b3d7661, 0xc51a5dfb, 0xa1e971e8, 0xbe7efc14, 0xf014bbd9,
- 0xfc0c6c93, 0x7be92fc7, 0xf5d19af2, 0x245c7d2c, 0xff3045c1, 0x0166ad8b,
- 0x75849dda, 0xad27d2c5, 0xed5d6013, 0xbfb63c74, 0xefd21692, 0xb227d54e,
- 0x9d387175, 0xe91a30da, 0x8d9e8b79, 0x60283fe7, 0xcf7a93fb, 0x3e5a248c,
- 0x6bbe72f9, 0xf5eaad15, 0x4a068218, 0x4b4dbe7f, 0x84b1904e, 0x5d94eb94,
- 0x38722700, 0xe2abe71a, 0x7171b7c3, 0x1efbd429, 0x124eec7c, 0xf4fef433,
- 0x310919b5, 0x0f6bd3f5, 0xfd03a509, 0x6ac8af6f, 0x7b71d20d, 0x44ba47da,
- 0xe45275ac, 0x5990fa53, 0x833d6edb, 0x8f43a86b, 0xfb5af4fb, 0xb44af587,
- 0x5bfc1f1f, 0xf0dd2784, 0xbc017eea, 0xc1c59787, 0x747f14ca, 0x8943bebd,
- 0x7ac8af08, 0x0bbbd5b3, 0x13f553f8, 0x0af1f3ff, 0xf9086f84, 0xc78a6919,
- 0x1de7467d, 0xbbefd134, 0x5f7159b7, 0xb4a63c65, 0xf77e0175, 0xb69d70db,
- 0x0ad16e69, 0x58991de5, 0x314571be, 0x86c71539, 0xaf940925, 0xa4ffa44c,
- 0x49122efd, 0xdf00a9ad, 0xeda36ce7, 0x869cbccf, 0x24645cf8, 0xcfba2675,
- 0xebc32349, 0xa7ca1699, 0x8dca7c28, 0xc967c85d, 0xe804087f, 0x85abb685,
- 0x20e94b76, 0xe1030549, 0x034b7c06, 0x395840b7, 0xb5abce8b, 0xff742445,
- 0xfaa7ca10, 0xcfd59fd6, 0x693f80c7, 0x337f27be, 0x57e8e16a, 0x63ee2df9,
- 0x59c4a8ba, 0x51f9fa63, 0x18e7ac47, 0x12c3f3e3, 0x44677e01, 0xf29972ef,
- 0x8fc4c5b7, 0x0492b1fc, 0x478ea9f1, 0xbbe32df9, 0xe177c626, 0xfc0d7519,
- 0x8ad241f7, 0x380ab37c, 0xf77c60d2, 0xc777ca31, 0x0977cd0e, 0xb807c9a9,
- 0xb8b7eefa, 0xf803ce00, 0x2aefe72f, 0x8c0d131e, 0x58f8df0f, 0xfd792440,
- 0xeadd7870, 0xcfa0e73e, 0x06e242e8, 0xc0fbe7fe, 0x806e5264, 0x516487b2,
- 0x4eb0ecf8, 0xad027ef9, 0x0dc449f7, 0x93ba337c, 0xfbe85bb8, 0x87e2669d,
- 0x2826a6fe, 0xc0d38fd8, 0x792f42e8, 0x2fad3e48, 0xea0cee2a, 0x13c49f60,
- 0xb5bdf819, 0xd3bff593, 0x802bbf4a, 0xaefc04ef, 0xa9137bef, 0xbefb0a8d,
- 0xe91990f8, 0x6b41f2e8, 0xd0f288c0, 0xfda3619b, 0x48d1fc25, 0x873dbd60,
- 0x7be7c8ac, 0x2b6e64f4, 0x4910ef6d, 0x73e22b4d, 0xd827f62d, 0x27e9f132,
- 0x680429c5, 0x053db857, 0xab2132b6, 0x65575f91, 0xf283de76, 0x81519f76,
- 0xd6d97c7d, 0x74ca1cb5, 0xe5a7e23c, 0xdb05652f, 0xcd4ff6f9, 0xef7d09ff,
- 0x0c5c58f3, 0xa07cdeba, 0xa3f8a317, 0x6f144c7b, 0x42c7c433, 0x5679d28f,
- 0xe06459a5, 0xfe32d3c7, 0xb4bdfef4, 0x3d7ed9fc, 0x9fde0231, 0x64973a9d,
- 0x2a27cd0d, 0x5d93fa03, 0x64baf461, 0xd55cb6af, 0xdafb2daa, 0x9b54e5b4,
- 0x1a2671d5, 0x2aeba6f7, 0xb1a327a5, 0x3a16d3e6, 0x46abe35f, 0x967f9be4,
- 0xe03699bd, 0x31d0ba0b, 0xe331a380, 0xe02f58fc, 0x0173fdb9, 0x1b4a469e,
- 0xbe0c799d, 0x9b2eafb0, 0x79c867e7, 0xfe97cf43, 0x47087499, 0x93c189b7,
- 0x9b1f07f1, 0xee57dd12, 0xf5d08ecf, 0x251d9a2f, 0xee37c6af, 0xa045f1d2,
- 0x891ce0af, 0x9f6deb6f, 0x5db16309, 0x5989f225, 0x579d1db4, 0xb7c656c5,
- 0x18ce9297, 0x54d50fd8, 0x145131af, 0x78636c3e, 0x2a1b5258, 0x367fd20a,
- 0xc2464bdb, 0x25afa53c, 0x1d7fe00f, 0x87a61bf4, 0xb1d366dd, 0x72cd7bf6,
- 0x368e06b7, 0x96d7d94d, 0xed877724, 0xff7c2597, 0x60904513, 0x7af94b3d,
- 0x6f782f7e, 0x9955f803, 0xe8530cba, 0xfd7eb7f8, 0xc5efca05, 0x75c6ca2b,
- 0xdbd70b8f, 0x1757c88c, 0xf7c5ea3f, 0x399b6faf, 0xcdb7d71f, 0xcfdc00ac,
- 0x9e9014ec, 0x025aa717, 0x5bcffa26, 0x5b9f4c6d, 0x8413bf4c, 0x848c7081,
- 0x331dd9db, 0x6747409d, 0xdfcf1b09, 0x59e4e4ca, 0x9b2bc299, 0xcefe81b5,
- 0xebbe31b6, 0x33f33adb, 0x778b4fe0, 0x67902e8a, 0x1aeac3a4, 0x7d3ca04e,
- 0xf40b42e4, 0x0a6e2977, 0x6bbcdf6d, 0x7be22cba, 0xfd8013d1, 0x6f3bb923,
- 0x5da5efa5, 0x78df5013, 0xcd91a763, 0x0e7a66d3, 0xd7eb71d6, 0x92c7ea22,
- 0x2f41788e, 0x47b8366b, 0x76557ec2, 0xf0033b3c, 0xb2567672, 0x42ffdb0e,
- 0xc3c03220, 0xde0122b6, 0x0f24162f, 0xad8acfec, 0x72e1a595, 0x11136cd9,
- 0x1e32535f, 0xe0b2e84b, 0xe407ba7e, 0xba4ed554, 0xd9fc607f, 0xaf7fbd1f,
- 0x3d3f7c23, 0x6174445c, 0xbfc77672, 0x5fc13d20, 0x34f808b0, 0xeef5c583,
- 0xbab4632b, 0x80726a2f, 0x5d5e2e5f, 0xa20f2393, 0x8bedf7bf, 0x8e1f741d,
- 0x4d836426, 0xb0755720, 0xfd1aed31, 0xdfbd2876, 0x0373ab92, 0xe22e4ddc,
- 0x133e967e, 0xa0bf548d, 0xa025f07c, 0x1a78788f, 0x97d23e10, 0x877ded0f,
- 0xcd926bae, 0xc7a053fb, 0x07cee20c, 0xb9212bbc, 0x005baa98, 0xc80fd462,
- 0xb7d3230e, 0x6defa624, 0x81cf2789, 0xfb8ea0be, 0x1e2fe84b, 0x1b1ec2f9,
- 0xc3e7b7ed, 0x5c018eaf, 0x8fcfd3ab, 0xbbecf905, 0xa14185f2, 0x0bb4b5eb,
- 0x2e2dafc8, 0xf17a010f, 0x0b22cfb5, 0xacf9faf2, 0x40e4c5cf, 0x6afebae4,
- 0xcfb67a63, 0x4e7ec211, 0x6dfed9db, 0xdcfa31b6, 0x002a22be, 0x23bb75fc,
- 0xff498660, 0x7c94fbbd, 0xc538a545, 0xe189a573, 0x57e7b4d9, 0x3be8116e,
- 0xa1c3c820, 0xd1fdb0ac, 0x202f315b, 0xdb3e71d2, 0xf2c7ed93, 0x912e29fe,
- 0xfcf659d6, 0xe00b2eac, 0x4177a6d4, 0x2bab8b7b, 0xd9f7d606, 0xb031539e,
- 0x223d8abe, 0xf022bbae, 0xbcc2c279, 0xbaf0be7e, 0xc00dfde0, 0x4b04388b,
- 0x6cf87f38, 0x0584a5cf, 0x98395416, 0x1c1c2c7c, 0x29e4472e, 0x5bb7809d,
- 0x3978616f, 0x00630bf7, 0x3339def8, 0xfc615f95, 0xc9959cf6, 0x263693b3,
- 0x4d69091f, 0x57d37907, 0x07573fbe, 0x6648ffe3, 0x5a1877eb, 0xfe3f61d3,
- 0xe7eda0b7, 0x091d3ac1, 0x595ede50, 0xf9434147, 0x5e17b9d1, 0xff7e0749,
- 0xa4afb3d9, 0x2fcd8597, 0x79f53bf2, 0x9aedc6de, 0x26dda7a6, 0x51195e3a,
- 0xc2a60bc7, 0xe32e6578, 0x485fc027, 0xdf7774dd, 0xcf62c9be, 0xab64f6f0,
- 0xaf60f91b, 0x1d00a8cb, 0x56f5dfaa, 0x804db944, 0xfe426217, 0x062ed657,
- 0xdb9fd08d, 0xfa01cc3d, 0x447dfab6, 0x4638aeff, 0x809b424f, 0x5e746976,
- 0x77f1f908, 0x2d4ef7e6, 0x7f9e293e, 0x32ae7801, 0x10a58e85, 0xc0030fa4,
- 0x916d50cd, 0xac253e40, 0x7a15f461, 0xbffa8744, 0x0169d921, 0x4e6b767e,
- 0x6e8ead54, 0xcc544744, 0xa7f54258, 0x6c5ce4b4, 0x74662fef, 0x81204fef,
- 0x590c0235, 0x96bf2023, 0x3a9c5e99, 0xb40dc891, 0xd33b3df8, 0xb5c49c57,
- 0xbc46cc55, 0x507fe00b, 0x05caa1e1, 0x8fe01fa0, 0xd21304e7, 0xa02ed08f,
- 0x5aea289e, 0x43bf41e7, 0x5d9e53d1, 0x3d1953b5, 0x49ff95f5, 0xe76454f4,
- 0x9e803bf4, 0x93d20abc, 0x3d3834d3, 0xbbf90229, 0x07bf13da, 0x0e44acec,
- 0xef9c4daf, 0x31311e84, 0x19050abf, 0xf794b7ac, 0x04b26a57, 0x2e1f9045,
- 0x30aef9fd, 0xd507627b, 0x494ec16f, 0x3e9e7d02, 0x57ccd653, 0xb3a46f10,
- 0xe8daec0b, 0x8f942609, 0x999d75eb, 0x8e24afa0, 0x7407d9aa, 0xaf2f3891,
- 0x67da0d60, 0x079036a9, 0xbfd15b20, 0xd3d8a2b0, 0x2fa6171d, 0x2fa80874,
- 0xc6ea3f54, 0x99db53f7, 0x661be07e, 0xd7d77d40, 0xcf01f826, 0x00431ed5,
- 0x817aa0f4, 0x1bfc01f9, 0xefd80acc, 0x156536cd, 0xbff34fd0, 0x5d3f2e29,
- 0xf9806f47, 0xd7497a13, 0xbd009fae, 0x3ed05855, 0xb605b66f, 0x7776822d,
- 0x03bb61e7, 0xf8d9137f, 0xdf8e09c3, 0x7a8adf9c, 0x0a6df37a, 0xfc7003f3,
- 0x2772cf35, 0xa81f40d9, 0xe6e7eed3, 0x9d927716, 0x52b5efbe, 0xcaf1d0c0,
- 0x8788cd1a, 0x99c19164, 0xfc989ac4, 0x4c17c819, 0x8984f700, 0x4f4d311c,
- 0xb7d3bea3, 0x80a729cf, 0x6faf3272, 0xd0e3a4ce, 0x3cf35879, 0x9f79a099,
- 0x3c7e5a6a, 0x024fd28a, 0xc46e87f8, 0xebd07e26, 0x564c61a3, 0x4f70c376,
- 0x9244e8e9, 0x86cef6a1, 0xcac39369, 0xf7ff7dbc, 0x69f6efff, 0xfb7728a9,
- 0x54da61ea, 0xb765ab1e, 0x9d6bce99, 0xa25ebfb5, 0x4da9aefa, 0xd7fbdf60,
- 0x8a9d3edf, 0x1d415ee8, 0x377aceff, 0x44cca9f8, 0xfcf85e33, 0xf5fe88a4,
- 0xa28b7fb4, 0x02565fb6, 0xa0553dfd, 0x73aedf96, 0xd26df9d3, 0x9043fb6b,
- 0xa0a1eff2, 0x4f8be78e, 0xdc9c686a, 0x3d5017af, 0xdf1f6021, 0xfbac1faf,
- 0x06e9b4a8, 0x7cb4563a, 0x577200c9, 0x873ef395, 0xe447fa80, 0xef897d7e,
- 0x57ccefd7, 0xba3d5187, 0xbf47a348, 0xdabe4764, 0x24b60335, 0x6f903fb5,
- 0x10f31efb, 0x3ea8e7d0, 0xfa8ec072, 0x4733f9c8, 0xeccf7d68, 0x514b1cbf,
- 0x79b2dda0, 0xaefaf7a0, 0xbeb74848, 0xa04062bd, 0xfbe26b74, 0xc0f1ca85,
- 0x9e9fa170, 0x9d39941e, 0x0744fcda, 0x8c21df74, 0xd57d23f7, 0x714ddfa4,
- 0x3ee71299, 0xb7ef8f62, 0xfdd7231b, 0x0fd99d91, 0x6de2dcbe, 0x1effd039,
- 0xd09e8081, 0x61327b90, 0x9f4dda01, 0xfb0c2c24, 0x29edb2ae, 0x5ee56784,
- 0xfc70a0fd, 0x1c222ec8, 0xecbe0fab, 0x2e71be06, 0xa84f2020, 0x37f50290,
- 0x854572d2, 0x5241340e, 0x2f7f9818, 0x35cc8fac, 0x7d74e190, 0x409bd041,
- 0x977bda8f, 0x375846ff, 0xafa04ffd, 0xa1167bb6, 0xd73edd3c, 0x30992164,
- 0x0865b2cf, 0x0dca3907, 0x2dc86870, 0xaa71824e, 0x4590cd67, 0x1c7aa7a8,
- 0x7a3f57d4, 0xd30c405f, 0xf4da1b03, 0x14e7a025, 0x57ee7d51, 0xf669de74,
- 0x745c4bdb, 0xfb88a71f, 0xe5a61ff2, 0xf1f0432d, 0x6e4c1c47, 0xff1e0ad4,
- 0x5fd10af7, 0x6ffdc247, 0x6f4c6d19, 0x683768bc, 0xed17affc, 0xd9377e12,
- 0xc81539df, 0x15d4b0e7, 0x8fb4fa0d, 0xfb073fb8, 0xca2c7899, 0xc62788b3,
- 0x152b1c8f, 0x1c992bf4, 0x806feb5d, 0xda12c9fa, 0x7aea442f, 0xa9edc612,
- 0x081ab877, 0x7e5007df, 0x9eed0f34, 0xabde71f9, 0x5c454740, 0x3839ed4f,
- 0xaf2cbf33, 0x7faaef5f, 0x0d581ad6, 0x3caad4fc, 0xf4fc0251, 0x24f9094b,
- 0xa73a8531, 0xff2a7ed2, 0x1b7ec76a, 0x7151bda2, 0xe6f5fe74, 0x81d03d40,
- 0x76c445bf, 0x20a6d98e, 0x73d9f3f4, 0x2fd016d6, 0x02268ef5, 0x15cd4c74,
- 0x1c9887f4, 0xf2d0a21e, 0x497cff54, 0xa1117900, 0xbf054ccf, 0x0e2bda11,
- 0xf3162bf4, 0x529c31fd, 0x6e1319c1, 0x71abda85, 0xf1cdfafd, 0xf048e6af,
- 0x747bd552, 0x9de7e626, 0xc08a3736, 0xe86d64f8, 0xcafc0e98, 0x7a024e8e,
- 0x80ab5570, 0xbee554e3, 0x65bb0064, 0xdfdb2b49, 0x50676e3e, 0x5e83a5f8,
- 0xcd171d91, 0x465acbf5, 0x58f3a4ef, 0x45f9c00a, 0x68424f86, 0xbdb86b3b,
- 0xd5d98ab2, 0xf7033fbc, 0xbf715787, 0x58849511, 0xd54e363f, 0x67f35633,
- 0x71f27b13, 0x6e9d08b7, 0x2f99e011, 0xeab6fc68, 0xe31c7a73, 0x4347b13b,
- 0x86ff6033, 0xff817d28, 0x6b309b68, 0x7d749bd9, 0x728fc6db, 0xa4e60a81,
- 0xc01624e4, 0x148a4a7b, 0x9f6d85ee, 0x21ba00cf, 0x6bf70425, 0xb114db75,
- 0x400dc78a, 0xae8c485f, 0xc4fa8169, 0x3e517207, 0xfc1f1f83, 0xb87077ff,
- 0xff985926, 0x9fdab9ce, 0x8c1e50f9, 0x26f659ef, 0x0a263f8c, 0x148915e3,
- 0x3e3b5637, 0xe57fc0eb, 0x4047f924, 0x954b3afe, 0x1a8f9802, 0x89d78a37,
- 0x43cacc0f, 0xbb658e3e, 0xa6ef704b, 0x6ce3bbcf, 0xdf6a2eb8, 0xe17cc095,
- 0x0ddb807d, 0x4e274760, 0x7187c9ad, 0xcf044e21, 0x84a0a49e, 0xcf2a68fe,
- 0x6d3a059f, 0xaf00ca33, 0x3eb7b6d2, 0x6a5b7900, 0xe822ad22, 0x4b7a113f,
- 0xf35dcc56, 0x2f7b6e80, 0x38f5d99c, 0x03eeebcc, 0x47e22f2e, 0x7adc8fab,
- 0xcfcbd30b, 0x80ad1b3d, 0xf39bb91e, 0xb23faa6d, 0x982fc138, 0x47a9191d,
- 0xb5a7123e, 0xffcafa4b, 0xcd923d70, 0xf7e74fcf, 0xf77f186c, 0xb7afbb71,
- 0xc80c62e2, 0xf47d55af, 0x517fe546, 0xb6529ebf, 0xd813fa27, 0x45767d67,
- 0xb5223e84, 0x840538b0, 0xdaef90d9, 0xe2fe3c0c, 0xff07ce76, 0xf9072d87,
- 0xa2e7f1cf, 0x173740fd, 0x97a8cd5b, 0x10433649, 0xb2fb55e6, 0x8013a031,
- 0x7578720f, 0x818ab8f0, 0x39ec6bc7, 0x0714280a, 0xfbe41e0c, 0x2cf497fe,
- 0x781312ae, 0x5e5a39e1, 0xc789387a, 0xeff6085d, 0xf08d183f, 0xc4a51a5e,
- 0x7f4bff42, 0x9e20471d, 0x03c74bd2, 0x7b37cf3c, 0x4d780a7f, 0xc9feb236,
- 0xc585466b, 0x36398279, 0x0096870a, 0xe54effd3, 0xba0682ea, 0x17d016ee,
- 0x3546dfa0, 0xd9d6c2fe, 0xc58521bb, 0x0119400f, 0xfb9eacbb, 0xcab8d5e9,
- 0x2b87e661, 0x5393f1e7, 0x033d17b3, 0xa15ab4a1, 0xb4ec04a6, 0xd0530dcb,
- 0x89fcbd6f, 0xaf2cf859, 0x17dbfad3, 0xaf7c1a91, 0x3f5527c6, 0x19711977,
- 0xefdcfe98, 0x7d51d43f, 0x8a93a946, 0x12667e41, 0x03c83579, 0x37b14fc5,
- 0xe96b3e81, 0x81789413, 0x93b69942, 0x80511dea, 0x3ab575ef, 0x5afe5b94,
- 0xa9da1b9d, 0x1c56f2f4, 0x57fd23f3, 0x5097f31c, 0x1c600750, 0xe7ab59f5,
- 0xdfde7efe, 0xc20ba22a, 0xe7b02753, 0x192a593a, 0xfdab7e4c, 0x4c6bead5,
- 0x4e6f4053, 0xfb3fa1d3, 0x173dc1b2, 0x1cf6c5fd, 0xb5ad53c4, 0xd584aea6,
- 0x6cba5ee3, 0xfeb0790e, 0x96298966, 0x3f03b144, 0xfa6388ed, 0x16dc2445,
- 0x91cb6936, 0x80ca9071, 0xbc4e5cb6, 0x59b29223, 0x7dfc20dc, 0x9767e707,
- 0xbc39321b, 0xbbe0065d, 0xa557faea, 0xd2e9b832, 0xad2b33d8, 0x41d02e78,
- 0x3285f816, 0xaafcc9e1, 0xff382574, 0x021d9bac, 0x7cc447d2, 0x9e8c6d6b,
- 0x0fccf5fc, 0x3fcef7f9, 0xe367de72, 0x763ef812, 0x56be213b, 0x5e301b2e,
- 0x12fead7a, 0xdf6b4393, 0xf1ff95f6, 0xe7b32df6, 0x2fc645eb, 0xa97c8c88,
- 0x396b664c, 0x0b9eb825, 0xd50b7bc2, 0xf51d601b, 0x91f00162, 0x705977a9,
- 0x2987d51d, 0x55f5a11f, 0x83a5758f, 0xee2eaf5c, 0x80bc81ca, 0x6cc2f848,
- 0xd19f9525, 0x6a0e6576, 0x50de808f, 0x0d878da7, 0xd3ba038c, 0xeec1e31c,
- 0x2defb539, 0xccfb5f90, 0xbfe8bf28, 0xff61188e, 0xbe44cc1f, 0x3bc589f6,
- 0xbe3ee21c, 0xe7aee0a8, 0x618f4133, 0xbb55547a, 0xc4f405b1, 0xf8b0dab2,
- 0x51affc1a, 0x75236f1b, 0x93bbf476, 0x8afbed66, 0x0ddf111d, 0x2135bf88,
- 0xbc18b65e, 0x53bf6123, 0xf1f18439, 0x023a950b, 0x5d172df8, 0x5d48408b,
- 0xf3f56b30, 0xaf86560b, 0xfe550e69, 0xcf0072b8, 0x7801e57d, 0x9e00e576,
- 0x1bc475cb, 0xe0154fde, 0x2977e299, 0x9785f3c7, 0x9e00e427, 0x909befcf,
- 0xa2de7803, 0xbec3726f, 0x4b7b2599, 0xd3dd8e00, 0x415fa83d, 0xd1f613bc,
- 0x7de3d2b5, 0xf464f37d, 0xf390df78, 0x5bf8c7fc, 0x8b8f9286, 0x95a1e6fa,
- 0x92830e8f, 0xcca0fc0a, 0x3946fc64, 0xfa837f09, 0xf4464cf3, 0xeafe1c7f,
- 0x1bcc46d2, 0x3f511768, 0x2c3bfb51, 0x3f41b379, 0xd381fc3a, 0xee8617e5,
- 0x8afc0adf, 0xe0fcffc5, 0x02ed5167, 0xe48cbf55, 0xfbe63fc7, 0xfdc3b37a,
- 0xd83bfd99, 0xb8ffaaa7, 0x0531b782, 0x77bd312e, 0xfe62e08f, 0x27f456e3,
- 0x97cc7757, 0x69fc5fc1, 0xab8ff980, 0xff47ce5f, 0xf5e06571, 0xdfc80a60,
- 0x7b064176, 0x27cf72a4, 0xfd2c8b31, 0x73b52f76, 0x886e809b, 0xfa471b49,
- 0xa62a7034, 0x3ef382dc, 0x768ef30d, 0xf7400c84, 0x23fed4d5, 0x52d54974,
- 0x5bf418e8, 0x17a820ed, 0xed69b614, 0xb8054a41, 0x031eedee, 0xededddf2,
- 0x75f80042, 0x999bc182, 0xa48d720a, 0xe40718ca, 0xc3976cfb, 0xe8f301dd,
- 0x03bb6b8f, 0xa33cb08e, 0x48b16dae, 0xe27a5dbf, 0x6d9f8196, 0x267e72b3,
- 0xf3fb7f21, 0x21a05b0e, 0x73f86f4c, 0x9509e980, 0x4491be6a, 0xd7c51282,
- 0x0fee39a2, 0xefc0df01, 0x3efc1183, 0xa3c6acbc, 0x3cfc4097, 0xde1dee22,
- 0x1f8e2fae, 0xf4d6f716, 0x95f26a43, 0x5bdc6d42, 0x7667ef5b, 0x2b0fdd33,
- 0x57e9fa0a, 0xbf4a83c5, 0xed1fdcd5, 0x16b938ab, 0x26d7d7e8, 0x2f5f60c8,
- 0x5dfa3175, 0xe32fed4a, 0x9dfb81d8, 0x0dfa52b4, 0xed4377e3, 0xe4228fff,
- 0x7bff47d1, 0x3b5068f2, 0xf8df74fd, 0xebabdf6c, 0x7df7fd57, 0xd8176ceb,
- 0x57588cbe, 0xe91adda4, 0xceed5777, 0x5f87e56b, 0xafc3f045, 0xa1f88ffe,
- 0x7e287e29, 0xfc6b8da8, 0x7ff0fcdd, 0x4cf1be39, 0x3a31d3c7, 0x332a2aca,
- 0xd7a64efd, 0xe2f135b9, 0xcdc5a219, 0xcb22a6e2, 0xbb8c8897, 0xdc78332b,
- 0xd7e7ed9d, 0x5f11165f, 0x5c3e3c55, 0x417561d5, 0x62cb0ad3, 0xc646cf8c,
- 0xfb241f4f, 0x228a0066, 0x614ba8e3, 0x7b7f671f, 0x9e3f353c, 0x5ce947c5,
- 0xa14f2132, 0xdfcb58a8, 0x8a5cb75f, 0xbbe186f3, 0x021a8f38, 0x49b5d083,
- 0xd87b13f2, 0x99e35bfb, 0xcf3afd3e, 0x481a71e7, 0x6ca1e41d, 0xc1bb46b2,
- 0x58ea718e, 0x9c4a51be, 0x78fc4a67, 0x9e1cefe0, 0x744fbf07, 0xe8cf2e14,
- 0xf89f915b, 0xe02e2cab, 0x471faa7f, 0xf7077fed, 0x9d2b5e83, 0xddaf1bdf,
- 0x7fe57df7, 0x572fbed2, 0xe37bfbc7, 0x6c295b76, 0x2081fb34, 0x38809efd,
- 0xba40e653, 0xa19faa1d, 0xbc7977e8, 0xee3c5967, 0xcc58f73b, 0xfe46bd9f,
- 0x3a185d12, 0xb222fe05, 0x7f80a8df, 0x2825fc13, 0xb8931b17, 0x022aeebd,
- 0x2ebe4338, 0x0c7d6be4, 0xb4349cff, 0xb7d8d8fe, 0xd8fe99ff, 0xe907fe57,
- 0x9ec8378f, 0xeeceb08d, 0x901cee29, 0x74aceb6f, 0xbe1760fe, 0x768cf2c0,
- 0xee7d1998, 0x925d1810, 0xe4d77115, 0xaf13d977, 0x867b9fe5, 0x2efff79c,
- 0xa7fd6cff, 0xc4bfcff1, 0xe8751f80, 0x2f2cfc7e, 0xcdd3b8b7, 0x776469e3,
- 0x07db7f98, 0xfbf466f9, 0xeabe7c23, 0x2e5c9dfb, 0x47dc125a, 0xff9c1f81,
- 0xb12264d0, 0x6429e554, 0x63dab17c, 0x7542f8c1, 0xa97bcb2b, 0xff208c7e,
- 0x69ff06ae, 0x6715f81e, 0x26f7d011, 0x0027bcd9, 0xb23eebcf, 0xf058c5f8,
- 0xa026cfbb, 0xc87cf5df, 0xbd967fca, 0x7bef509d, 0x19e30bac, 0x61cfb3cd,
- 0xd5d155de, 0x0a4b6b4b, 0x47e8be71, 0x4d491870, 0x1afe9e38, 0xd596f2cf,
- 0x783e95e7, 0x7fafd1bb, 0x11e582be, 0x196e1cfb, 0x5faa11fc, 0x44e95a3c,
- 0x7ef5533f, 0x8915b4a6, 0x27e43d6c, 0xd54f48a9, 0x83e4a7fb, 0x9ab494ff,
- 0x2dcf41f3, 0xed05a3fa, 0x268ff3bd, 0xfcc49e63, 0x9859ef38, 0x7030b5af,
- 0x19a5e81b, 0x77d01c74, 0x2dbbefcf, 0xf2ade61f, 0x3fe02dbf, 0x58b7eda7,
- 0x62717eb5, 0x95ddf962, 0xfea8a7cf, 0xb7f410f3, 0x6243ef85, 0x359a2a69,
- 0xf757bec8, 0xc3a8a27b, 0x607f13fe, 0xcab938c2, 0x89e8b60f, 0xcfdd94d7,
- 0xcf10fe47, 0x3c1cfbde, 0x167db15f, 0x65e14fcb, 0xf0aa7f0b, 0xfe98ecdc,
- 0x1fc79807, 0xcbeba5e2, 0x4b05930b, 0x75eb3c78, 0x7887fbc1, 0x8032cf16,
- 0x8a314e7d, 0x2be8967e, 0x92ce7f4c, 0x5647480d, 0x3e30dfba, 0xf408e943,
- 0xcea1c9f8, 0x9d74b1a9, 0x93839ac3, 0xaf87be01, 0xd24f10e8, 0x9f1813ac,
- 0x78d81589, 0xf55d8dd9, 0x22ffc023, 0xa03377bf, 0x8b926952, 0xc937d421,
- 0x404e49e6, 0x2e4d7a7f, 0x7bfc578c, 0xec93cb3d, 0x42bf4688, 0xcc52fa73,
- 0xc8f9ec93, 0x489cfe88, 0xfd3ea0f9, 0x45e63564, 0x27fdb566, 0xfbac09c6,
- 0xd4dc0d05, 0x0b04f8e7, 0x3bf95f8b, 0xcd6e6067, 0x57f20764, 0x188fe3a9,
- 0x25ea969f, 0x56a43ce0, 0x8199d6ef, 0xe822ad7f, 0x2cde1ce7, 0x195f00eb,
- 0xf7a62f3c, 0x7ac75ff0, 0xe3514ed1, 0xd7960102, 0x0b5aefa4, 0xaab497f6,
- 0xe03f16eb, 0x574dbf63, 0x85fd079d, 0xd2cfd1aa, 0xcf804d11, 0xaf65b467,
- 0x339689be, 0x838c64ea, 0x925a1ef5, 0xba557e81, 0xac83e1ce, 0xe5813d33,
- 0x18133921, 0xd11d48bd, 0xd267903a, 0xd182e266, 0x32dd6b33, 0xcb8779f8,
- 0x25b9d212, 0x70025bc1, 0x807ce68d, 0xb8c288ac, 0x7e6255a2, 0x8f8aeb11,
- 0x44e7017e, 0x03f3f176, 0x9e8f0f47, 0x7abdfe8d, 0x5fb80049, 0xc9bcb1b6,
- 0x73da0939, 0x3ef0fd07, 0x59a7f98a, 0xe4c9ff1d, 0xfa0b1d17, 0x3e8cf497,
- 0x0b477aa4, 0x587711f8, 0x7b6f98bd, 0xc4506d73, 0xfddc9938, 0x66128964,
- 0xf2656ccf, 0xb32f7aa4, 0x97ed23bf, 0x5523936f, 0xd2395a09, 0xe927fe57,
- 0xae122b27, 0x5a212ed3, 0x4f522e7b, 0x06dfb489, 0xfd11dbe8, 0xa8afa50d,
- 0xfdc52779, 0xd9bd30e3, 0x7e43eaaa, 0xb14e5e4d, 0x4c4b8d85, 0xdb27feda,
- 0xcc8f9665, 0xd61274f3, 0x9024ab28, 0xd046ff57, 0x0be6a72f, 0x5e598bf9,
- 0xf9475f8f, 0x97c4265f, 0x284f309a, 0x01050485, 0x045d66fd, 0x7c844bbe,
- 0xe3ddfa21, 0xef385909, 0x2755c49d, 0x04547f22, 0xf219b798, 0x352f304c,
- 0x8c116db0, 0xc705b773, 0xc99e4331, 0x70154838, 0x3a7e036f, 0x11c582b5,
- 0x05dca992, 0xc61e4dfa, 0x973cd0e8, 0xf9a89be5, 0x87fe6a24, 0x0e62870a,
- 0x8b11e4df, 0xd5ef8132, 0x4017de0b, 0x1817a9cf, 0x981bfc7c, 0x46d9a11f,
- 0x6e5a68f5, 0xf9851cae, 0xf584bd7e, 0x21d0afef, 0x80f9aa5d, 0x7615c3cd,
- 0x226fe53e, 0xf9cdefea, 0x4064bf2c, 0x5c044a1e, 0x6e943cd5, 0xf603b7ab,
- 0xe4c8b26d, 0xa2379aa8, 0xfe1849d2, 0xde3a66fc, 0xbfa60ef6, 0x70185717,
- 0xb795bd1d, 0xb7b1ffa3, 0xce404752, 0x191bb717, 0xb78c45dd, 0x0481ae7d,
- 0x60295fa1, 0x8e79fcc6, 0x5fd36fff, 0xc1735e29, 0x65747bbf, 0x0a6eb8c9,
- 0x7a5637e3, 0x166bd9f0, 0xd7c8455a, 0x01e68731, 0xf89cda47, 0x49a43ba3,
- 0x4a135790, 0xecc92817, 0x54a0fe70, 0x37a072a2, 0x9431f43e, 0x9c7c4c5f,
- 0x76878795, 0xd1fdb409, 0xd8a51da7, 0x9931681e, 0x98253f90, 0xeb96fd4b,
- 0x40646f90, 0xc0a7c6be, 0xd748aa87, 0x0bf44eda, 0xc856f971, 0x669921f8,
- 0x94bf300c, 0x77b1fe82, 0xee513293, 0xf6b3725b, 0xaa7d4277, 0xb469fd11,
- 0xddfde91e, 0xbd5853e1, 0x524ef0c2, 0x836f2cad, 0x9f81f974, 0x05399bbd,
- 0xb055d2fd, 0xf4fea81f, 0x057bc5a6, 0xe8417af0, 0xe0fb0e5c, 0x9affe9dd,
- 0xe17df407, 0x01864fc0, 0xa06999bf, 0xfc20f97a, 0xe32771e5, 0x4b7abd2f,
- 0x79fb409d, 0x1215e2dc, 0xe883f969, 0x95203379, 0x14dc6e7c, 0x200d1c03,
- 0xe04417fe, 0x7f1cf177, 0x5f4c39b6, 0x08f34db4, 0xc6b9f790, 0xef11e6cc,
- 0xbfa8dc95, 0x7708e778, 0x11aff5d3, 0x94433eb8, 0x143bb458, 0x8eec1625,
- 0xc21e2ba5, 0xef916fbc, 0x9bad49e7, 0x7f97d045, 0x4df8f2b7, 0xe5a1b0d2,
- 0xf6115df0, 0x1254fa85, 0x8b663ad9, 0x8fa018ca, 0x6fe342b5, 0x3de0934a,
- 0x31e9b3a3, 0x5f210a2b, 0x4d74667a, 0x22cdc621, 0xf7d2c7df, 0x23656179,
- 0x14d4b76b, 0x3d28974a, 0x61decd3b, 0xf3cb9700, 0xfb0e593f, 0xbbf27977,
- 0xc2be431f, 0xd6e27abb, 0xe24d3ec3, 0x1f2a4371, 0x32c7bf01, 0x286e2c6c,
- 0x031a9d6f, 0xef866ce5, 0xe30048db, 0xd873a5d4, 0x483bc139, 0x6d176d67,
- 0x57a9d337, 0xece8c2ba, 0xbe5b4536, 0x2e5b5723, 0xff1179e5, 0xbfbed2e2,
- 0xc0248493, 0x7e26f7ff, 0xfdfc223d, 0x1beecd8f, 0x0aaffe61, 0x3fd28f2c,
- 0x87a8c889, 0xe83f043a, 0x495fa305, 0x5926e7e6, 0xb9cfdfbe, 0x44caf31d,
- 0x7b09f582, 0x0f21bb4d, 0x8b07f55f, 0x93b47ebc, 0xc8ec3298, 0x84ae508f,
- 0xe8379e04, 0x390918c0, 0x7e664cb0, 0x40d6da51, 0x5f3039fb, 0x5824b841,
- 0xa016e474, 0xd21342eb, 0x298a5175, 0x28e0e80a, 0x3f1f23a7, 0x55d2a387,
- 0x903c4491, 0x9e8740bf, 0xf577cf03, 0xfff011f2, 0x78233ffa, 0x29908a4e,
- 0xf231e612, 0x855908b1, 0xbd39a7e5, 0xedf9551e, 0x6fc849bf, 0x701ab4df,
- 0x16bf895f, 0x439f805b, 0x5fd6991b, 0xf3851c6c, 0xdd03f753, 0x091cc3bd,
- 0xfde672e8, 0x44983a4a, 0x2acaccae, 0x38f862bd, 0x410fe401, 0x738d523d,
- 0xbefa99a5, 0x4977c373, 0x74bb9fbc, 0x8a4cde2c, 0xdc9d1c78, 0x3f7cc465,
- 0xbfb42f5e, 0xf7e025f5, 0xdc4cc4f1, 0xb7887b74, 0x3446e80b, 0x4ba014b8,
- 0xdae5ce95, 0x9d29bf43, 0x79c9eb04, 0xbb73d704, 0xe4f58655, 0x6b9c3252,
- 0xae3ba7c7, 0xf461fa00, 0xefb1462e, 0xfb792aef, 0x3e8c2926, 0xec55f7e8,
- 0xf7ed68fb, 0x3dbdfa4e, 0xfa18fbec, 0xefc0de7d, 0x72220909, 0xbff3e76e,
- 0xee89e79d, 0xba829ab1, 0x917fd0b1, 0x13bf45d2, 0xc3f7d813, 0xe07be862,
- 0x7cdab9fb, 0x65d1320c, 0x88de3cc2, 0xc2998bfc, 0xd7404963, 0xdaaa99b7,
- 0x6fff68bb, 0xd4ccfc71, 0xf380bf79, 0xcbcd6f66, 0x57fc0379, 0xbfba2625,
- 0x055f60b2, 0x7ad202d7, 0xb19f78a7, 0xddfee365, 0x2d5ff401, 0x69d8477a,
- 0x69be82f9, 0xdc4cb2d8, 0xe3133b17, 0xc55fce07, 0xa00ebabf, 0x3ea7a003,
- 0xb798883a, 0x67722f8a, 0xedac262b, 0x3c087aa4, 0x9084bd55, 0xac9f961a,
- 0x8baff5a4, 0x530ccb12, 0x0bd030cd, 0xe3f4aade, 0x7b699dbe, 0x9e97f312,
- 0x04bef24f, 0xc37b9df3, 0x3412e9e7, 0x011fce76, 0xdf3a207e, 0xce5ffd5f,
- 0x06bfd557, 0x667ee7e4, 0x0ee7e4d0, 0x71d47fb5, 0x8957a07d, 0x82dbc790,
- 0x39beb6f9, 0xab9c1716, 0x68be41f0, 0x5079c621, 0x30243aaf, 0x982fd57d,
- 0xad741eb8, 0xe984bc79, 0xfa7d554b, 0xbd0f2692, 0xbbcd9f39, 0xfa829979,
- 0x6b02abd6, 0x984f9fef, 0xd78b363e, 0x5eb1942f, 0x6e6f57cd, 0xe6b5fe61,
- 0xd0284797, 0x50a3d52f, 0xae58931e, 0xfe3265a7, 0x91493cda, 0x44dc0cfd,
- 0xafcfe848, 0xfa67a2de, 0xab9d76df, 0x0c41f308, 0xf1623f54, 0x869fc65b,
- 0xfd23f1b3, 0xaa275f70, 0xc3f30076, 0x41ff95f5, 0xb259b87e, 0x7f693897,
- 0xe9dcf30b, 0x17982cfa, 0xfa51c7f3, 0x2049d1dc, 0x1866ac4d, 0x91b7cde8,
- 0xd974f79a, 0x68069f48, 0xa534773f, 0x7d0d6ccf, 0x8cf19d1a, 0x22bcc21f,
- 0x1d2441f9, 0x6578c566, 0xd6d9a7e8, 0xd06ac7fa, 0x2e8ddb37, 0xf2ca7f96,
- 0x40f922e9, 0x48167cd8, 0x510e3e6c, 0x0738f9c4, 0xecb5cf9b, 0x4cfa7093,
- 0x0c3f6c24, 0x25125fb5, 0xf416b7e2, 0x9b1f97ef, 0xbd6023bd, 0x2d66fb7d,
- 0xcc062fb3, 0x7d20b45b, 0x8b2f73dd, 0x99a2f837, 0x43b8835c, 0x167f1d12,
- 0x7a9eff1f, 0xfcf78746, 0x4b7480d0, 0xf9841fa7, 0xb3f5e6cf, 0xdf30abda,
- 0xfd34f668, 0xff0d2ec9, 0xe7bc2375, 0x1c7376f2, 0x02d87af9, 0x71b54a73,
- 0xb3f7b985, 0xa4ddc6b8, 0xbdf30f46, 0x9fb68e67, 0x73f1a4b9, 0x7b9a9fc8,
- 0x54fdf6bf, 0xc9b9df67, 0x788f1011, 0xbde1db83, 0x7ec0bf74, 0xf17e337a,
- 0x7e94658e, 0xaf34fc47, 0xd303fc00, 0x6cf72a13, 0xb7e7e5a6, 0x9bf2c28f,
- 0xd1f83f09, 0x2bbf50bb, 0x20d3cb07, 0x08ec0c19, 0x6f208fd8, 0x3dbdee8a,
- 0x86fb8e93, 0x8cbbf799, 0xa33bdbe5, 0x68b3cdbc, 0x2cd8e73b, 0xc69c1bcc,
- 0x42ef4df9, 0x0dc77f56, 0xfa1a9656, 0xb97e8280, 0x79a15169, 0xf227ff40,
- 0x790050ff, 0x78b2d3ac, 0x51d5e0b9, 0xf8437e50, 0x4dd81e7c, 0x0916553d,
- 0xcc9d5fe0, 0x73a399fc, 0x0a48e085, 0xde766997, 0x575b157f, 0xc90bc169,
- 0x15a63fb0, 0xbb467eb3, 0x4367d4a6, 0x2c45dd3b, 0x629b24f7, 0xfbaa1f80,
- 0xfb93996c, 0xe49eb807, 0x15fefbe1, 0x71b527f7, 0x498f5fb4, 0x3d12c170,
- 0xfb413f13, 0x39d85894, 0x533b8f2c, 0x54e87f02, 0xdc73cb37, 0x02ac8aba,
- 0xcdeb647d, 0xad0d696e, 0x7a226a9f, 0xce946b90, 0x9b7a011f, 0xf4f3e13b,
- 0x8b2e2018, 0x3a55ce96, 0xf7d2a59a, 0xd31d2d34, 0xe713f9fd, 0xcfe76ff8,
- 0xf7363a1a, 0x7a50f1d3, 0x1d579d39, 0xb49bbfee, 0x9c6faaf2, 0x39187d88,
- 0x01fc50ee, 0x67f9c2fe, 0x715afcff, 0xb642a5bf, 0xc7ec3658, 0x6e3f7526,
- 0x7418f803, 0x24fe789d, 0xc28d7043, 0xe8439b03, 0xd2fcea15, 0x305927c0,
- 0x27f05e70, 0xfb1d7aa9, 0x9b1d8073, 0x77e9ebca, 0x9fef626e, 0x05ff1d17,
- 0xd96b7fe4, 0x350a767c, 0xbd709f8c, 0xab7fb55a, 0x69b6f5d5, 0xc5145bd7,
- 0xc13b7bce, 0xe93e814f, 0xf37d51fc, 0xa83c06be, 0x3971f1eb, 0xb1e4c73d,
- 0xeedae81a, 0xfd2395b6, 0x5ff89f7c, 0xa0e87d06, 0xe6187bc5, 0xefe75479,
- 0x2163fb00, 0x925c6371, 0xce6bc7d2, 0x9d42fd30, 0xaa9c246f, 0x919fe087,
- 0x4f8489eb, 0x513ade3f, 0x77cf539f, 0x1af7adf5, 0x21eaa9d7, 0x3fd6830e,
- 0x1cfee764, 0x00dff73b, 0x2e3c8145, 0xd02e5125, 0x04baa7eb, 0x894a27d4,
- 0x6970f909, 0x76df9309, 0x5437d30b, 0xfed43f39, 0x8216f5b8, 0x2974a9fc,
- 0xd8c9e7e1, 0x30e922ba, 0x823d7491, 0xd9499e76, 0x39f600b6, 0xff4a25e8,
- 0xcc2d4bfc, 0xa9c57bcf, 0xf1aef5ca, 0xcafbd720, 0xd77ae403, 0xf337e078,
- 0xa3fc6d44, 0x2ff30af4, 0x7c10afda, 0x193eba96, 0x5edd720f, 0xf81e35d2,
- 0xeeb1add6, 0x1f9f012f, 0x361f98eb, 0x24fa8e12, 0xbc5fea9d, 0xdc8cfa26,
- 0xe95c6a3f, 0x94d78b4d, 0x1fdfbe34, 0x2ce84171, 0x38ae4682, 0xcdeff799,
- 0xf4a63a04, 0xf2897288, 0xc157abc7, 0x837f8398, 0x532c721c, 0x092d9bf9,
- 0x2e08dbf8, 0x8f8c3dc7, 0xdb758b9c, 0x0d1c5893, 0x8710f2e1, 0x572e74cb,
- 0xd110ee2f, 0x9dcd3f9f, 0xdcb834fb, 0x24f5c77d, 0x8dd7fb80, 0x5f097172,
- 0xa53a45d7, 0xd17fb420, 0xe2c67a8a, 0x1e31cbb7, 0x8eab6231, 0x72726128,
- 0x734a2064, 0xbde8c47f, 0x4c794d76, 0xfda6b26b, 0x9a596d0d, 0x28e0fcfa,
- 0xe3b8fd4d, 0xf8f29a05, 0xed351bce, 0xac507c27, 0xbaea4f29, 0xa6fed35d,
- 0xca6b674f, 0xac123014, 0x0283b9fb, 0x7dd74ed9, 0xcd3ee873, 0x7dbdfff7,
- 0x0b8871c6, 0x33f6e29e, 0x733bbbf1, 0xa8161c29, 0x4ca57c74, 0x08505fdb,
- 0x07c0450a, 0x4682dfd8, 0x853cd796, 0xdfbc2e42, 0x7d5a4d85, 0x6d56f162,
- 0xf37da2b9, 0x0395e05a, 0x8a6a21f3, 0x646c88e1, 0x7934c43e, 0x75e80ebe,
- 0x2fd51276, 0x91c63040, 0x1ac7c838, 0x1b7fdf6a, 0xb0c873fe, 0x6b3fc36f,
- 0x7a80d5bf, 0x7fb7e2fd, 0xafa41455, 0xfe2d4e8c, 0xff168acd, 0xfc5ab9d1,
- 0xfc5a5d5b, 0xe2d44ec7, 0xe2d6e6df, 0x8b44ae3f, 0x168f78ff, 0xb57389ff,
- 0x6af24ff8, 0xa1529ff1, 0x8d5a7fc5, 0x2b19df16, 0xf4ccf8b4, 0xffbda83f,
- 0x2aff0224, 0x7baeccff, 0x149ee228, 0xd185d11d, 0x0b474a81, 0xe798153c,
- 0xc7e9bc32, 0xe922719a, 0x3a8dda81, 0xda8b87bc, 0x6b85db71, 0xbdca0fa7,
- 0x491a5fd0, 0xf1244f1f, 0xb13b183c, 0xeef9455f, 0x40f8127e, 0xf2a15ea4,
- 0x1e3970ad, 0xc50eff6e, 0x27c806cf, 0x290f0f6e, 0x361ec09f, 0x43c3dbf7,
- 0x9087e9d1, 0x53fa838d, 0xee8bfa23, 0x2e3cd995, 0xe049abc1, 0xf225fd5f,
- 0x04e90fbb, 0x7ef9d227, 0xe3a1eb08, 0x1a35187f, 0x203f18fd, 0x7fcfd441,
- 0x74871908, 0x712007b0, 0x13e73e99, 0x5ce59f05, 0x7ee42f5e, 0xdbd9a70e,
- 0x16a97006, 0x300919bd, 0x9e276a6e, 0xe227221f, 0x855ee9ae, 0x976fe093,
- 0x7f06e908, 0x98f67d3b, 0x519c7d19, 0x289b87f9, 0x9678308e, 0x5172154d,
- 0x30a3157f, 0xfbeca80f, 0xb2a5ca02, 0xcecf61ff, 0x4707a624, 0x50acd73e,
- 0xf5c4d9e1, 0xfc0fa600, 0xe3c29277, 0x416bc433, 0xe064b9b8, 0xe63fb4fb,
- 0xf319feff, 0x4925d193, 0xec78ec57, 0xf80cf10a, 0xa241f386, 0x8c73cd89,
- 0xe8574c44, 0x8bc4d1fb, 0x49c7dffa, 0x7aee3859, 0xd632b289, 0xb7e828ef,
- 0xefa3c60b, 0x045c5ba7, 0xd3a2bdfc, 0xabffd045, 0xc32b0996, 0xf55bac1f,
- 0x7a72a5eb, 0xcc2563d8, 0xe7e1157f, 0x2729114b, 0x3d157c85, 0x94ed0f3b,
- 0xf0bb32b6, 0x18ceab98, 0x792a2eb6, 0xed7e706d, 0xc81cf4db, 0x96133d2f,
- 0x5ee14e0f, 0x3f1c9833, 0xa8e2cc9e, 0x6e9a566b, 0x0f497886, 0xbe3d078f,
- 0xf80cdc92, 0xe6172514, 0x417dc181, 0x0defb0b6, 0xb61f5a0e, 0x498b24df,
- 0x3c5bd653, 0xdac65978, 0x17483595, 0xd1af7e7a, 0x6487d4ba, 0x217f986f,
- 0x4c4f8f9a, 0x1027227e, 0xbfd2f2ae, 0x5812a74f, 0x674b28af, 0x9feaf634,
- 0xdc0146ae, 0xa93d38aa, 0xe93a35f3, 0xdeed6138, 0x2557f4e1, 0xfe601a77,
- 0x741c50ef, 0xea413c42, 0x56bde074, 0xffb8e975, 0x37f0e4ef, 0x908217ee,
- 0xe0946ff7, 0xd2f4268c, 0xd28e3cd9, 0xf477dae9, 0x6b25e204, 0x7e44cfc7,
- 0xb8d7b066, 0x1e4f05a8, 0xeca1677e, 0xea9e041d, 0x2e94e8d3, 0x61a3f387,
- 0x9e0edcc9, 0x3e002640, 0xca0f9906, 0xf66587a7, 0x59e3c3cd, 0x3fc3c1be,
- 0x4c7f9824, 0xa2bfd056, 0x13c4f87e, 0x1b1bf217, 0xc6cbe109, 0x50037495,
- 0xa561b71b, 0xa8737889, 0xa835221c, 0x3710251f, 0xfe6351d2, 0xfd395709,
- 0xebf052ce, 0x3787b05c, 0x0d53ff8c, 0x1f45ad94, 0x61b94055, 0x90ad8be4,
- 0xb981642b, 0x23bf3038, 0xa2b66700, 0xef7cfd46, 0xef07686a, 0x425f3e21,
- 0xacf9d3df, 0x821ed31f, 0x0f63d1f6, 0x51f50a7d, 0x9b29a096, 0x3f75177e,
- 0x45b04971, 0xb253855c, 0x4856d3e9, 0x8e28a17b, 0x4f47dfe6, 0xc646fd64,
- 0xbb2d1203, 0x93217dd9, 0xb1678f09, 0x1faaec73, 0xbbb2de3e, 0xc6f818a9,
- 0x53fd6d30, 0x96711e1c, 0x41678e97, 0xe7612a7d, 0x93fd7957, 0x7966debc,
- 0xe598b3a9, 0xdfbe681c, 0xb58ffbcc, 0x50bf18e8, 0xb1b78f08, 0xdebc4dfa,
- 0x093bd6ac, 0xfab1a78f, 0xb46f5e7a, 0xba12fcb0, 0xafdf35ad, 0xdc27e3e3,
- 0x30de23af, 0x89cc74fa, 0xfa30de22, 0x35da97b0, 0x9d85bd65, 0x25a79523,
- 0xfb53be6b, 0x1b8f9c7d, 0xf34b3933, 0x28d8699d, 0x34cefb6d, 0x710f2394,
- 0x0b521b38, 0xf9eaf534, 0xb3a7226c, 0x276b3276, 0xf4d46e39, 0x6251517b,
- 0x999fff61, 0xcbadd2a4, 0x90fb7404, 0xe2112b35, 0xb99581b4, 0x1f0144a0,
- 0x3f994fe1, 0x6674789d, 0xcb054acd, 0xb8bfdc99, 0x2c44e566, 0x0b74a6ef,
- 0x74accff5, 0x2d277961, 0x53f9f42b, 0x58950fda, 0x07ed1b64, 0x7ed34fca,
- 0xed14f9e0, 0xd24f9e07, 0x337ea0f1, 0x9bca0efd, 0xde507f68, 0xe58dd2b0,
- 0xb04b2bf5, 0x83d2bf5c, 0xe72b75e5, 0x95f1f3e2, 0x59ae7c5e, 0xbbf58159,
- 0x3beb8593, 0x22485f7f, 0x93bbb9e3, 0xdde7f7c7, 0x16dcf1ab, 0xd476e0c3,
- 0x32ffce01, 0x8988e788, 0xa5c63fd1, 0x8f5b1ad2, 0xe719bd80, 0x6a48f861,
- 0x5b7ac1ac, 0xfd471b09, 0x24fc388e, 0x331d88b5, 0x5950fc64, 0x230df98d,
- 0x7317cb09, 0xc45289fa, 0x9fc25fcf, 0xbcff4214, 0xabe5ab94, 0x71f91199,
- 0x9923b3ea, 0xb0e279d9, 0xc72c371a, 0x8413d134, 0xcb8b5e7c, 0x33b1e78b,
- 0xa9ced0ae, 0xe57b1cbd, 0x5f80a216, 0xbfab54bf, 0x6815a7da, 0x4af144f4,
- 0xa533b635, 0x6769a7de, 0xda699470, 0x5cc92d95, 0xa47804eb, 0x1b1875b0,
- 0xbd101157, 0xe3379b0b, 0x999367b8, 0xebd74bbd, 0x3efbff47, 0xeb97ad81,
- 0x7ccbcf4d, 0xe446a6bd, 0xac6c23ab, 0xd7eb1398, 0xff3c3f01, 0xafdc58ab,
- 0x43a33dcf, 0x1248dfff, 0x46be01d0, 0xf50cf153, 0x96174863, 0x4aee006f,
- 0x1144f9cb, 0x848e3ca1, 0x7aa4bed0, 0xb3257fd3, 0x6633d0b8, 0x79a50b88,
- 0x23f9679f, 0x392b9441, 0xaa391f1c, 0x8a55b8fe, 0x4e9da7f4, 0x7b56fb46,
- 0x5b8d449e, 0x2516b2ae, 0x33d13e82, 0xb44f7e44, 0x169bbef3, 0x27463850,
- 0xfaa7c5cd, 0x1ba2bd7e, 0x55e57cf4, 0x4cefaf0e, 0x77c601e7, 0x6afce8c2,
- 0x0bbfa532, 0x0c83bf79, 0x2c3d5219, 0x1af0f684, 0x941fcabd, 0xfd0fe058,
- 0xe62c5765, 0x2127b473, 0xc199447c, 0xde95b9e7, 0x7fa9249b, 0xf997e29d,
- 0xe49be432, 0xbdb67cf0, 0x34dd972b, 0xc75fea4d, 0x5fb614e8, 0xf22b4973,
- 0xce875cfb, 0xa735ecc5, 0x0f33bec6, 0x79c3726b, 0x7114715f, 0x48c42e41,
- 0x5ee784d2, 0xc889bfc5, 0xb7a3c47f, 0x17ea8511, 0x40807251, 0x2fda873e,
- 0x8fe276e1, 0xc2fcbf38, 0x2de70d32, 0x94f7aba6, 0xf9af51b9, 0x90c97642,
- 0xb345f2cf, 0x4f123f1e, 0x6573eb6a, 0x4a5e07d7, 0x47f68b97, 0x517a60bb,
- 0x5f784db9, 0x204bb89b, 0x83ce02a9, 0x99d9a7e5, 0x5adfaa7e, 0xe0e3fc44,
- 0x2e37aed0, 0xa5dae005, 0xc2a9d01c, 0x8aabb69e, 0x3f06ec33, 0x0b8008d4,
- 0x2e5873c0, 0x5f2171c2, 0xab95deef, 0x14ee4e10, 0x6935e786, 0x7cf9dc2a,
- 0xf70ddb88, 0x566a2dbb, 0x3aed5bed, 0x7f15e7d7, 0x3b6bea0f, 0x8bd3cc45,
- 0x9885e784, 0x286263f7, 0x3346cba2, 0xa79d0cff, 0xc129e61b, 0xbe00e3bc,
- 0x58b3d704, 0x5ce00436, 0x5ad08f66, 0x31a97182, 0x971e123a, 0x53339f52,
- 0x277aff18, 0xb467c659, 0x0b4dde73, 0xef9785c6, 0xc31eba47, 0x122c4fd7,
- 0xbb7093cb, 0x5abf7095, 0xf0676a83, 0x3e28ea3c, 0xa0fbbedf, 0x2f3cb146,
- 0x0adce90b, 0xd9431779, 0x614c3f11, 0x3b7ef2f1, 0xe806a282, 0xf309bc67,
- 0x7cd41a1b, 0x055de514, 0x13e96bf3, 0x9c4c51f2, 0xd959d74e, 0xfaea043d,
- 0xbe30a656, 0xa3e392b9, 0x22ecc4d7, 0x27e4db88, 0x6f9f9d84, 0x58fb472f,
- 0xb6f4f38d, 0xd552fcb3, 0x49c950ff, 0x060df7a0, 0x221dde87, 0xdb2a77c6,
- 0x0ef760ef, 0xf7893c76, 0x14bed235, 0xde7287a0, 0x6b4ebcbe, 0xe3d82f0f,
- 0x0ca51b59, 0xc117bbb4, 0x03d9ab7d, 0x3b48eded, 0xae14b1fb, 0x3e48babf,
- 0x354e71c4, 0xa28b1f66, 0x126435f3, 0x2297bf3c, 0x6ef784be, 0x09b3ed53,
- 0x79243bee, 0x488fbeec, 0x6a92bfbc, 0x15ef3840, 0x5a5b8f08, 0x8ef7fe90,
- 0xef7ffb67, 0x0e778b91, 0x93dcfda7, 0x7ea6e0c1, 0xcb064f77, 0x0607dd33,
- 0x4adf7d15, 0xf960c948, 0xdc38bb3c, 0x9b9f33bf, 0x5573e5ac, 0xa2c75d6d,
- 0x3b77e415, 0x8f7bde81, 0x0f2625fd, 0xef0847f7, 0x833f7f2d, 0x0de607cd,
- 0x74fbf479, 0xa70bcf9f, 0x12297d83, 0xfaeeb79f, 0xda698cf4, 0x7bc85d79,
- 0x3676e12f, 0x579856af, 0x4264f04f, 0x3ab47e78, 0x83c57daf, 0xfd7cef9f,
- 0x9133e77a, 0x5068a7ce, 0x26fd1d38, 0x0c33ed38, 0xf80f9f3e, 0x0de3fe7c,
- 0xc0c0ef76, 0xd3d4ebfa, 0xefc04476, 0x807bcec5, 0x7ef9d35d, 0x847a0290,
- 0x63013bb3, 0xad7e1c4c, 0x0b3e9c85, 0xa171df39, 0x1f7c444d, 0xa4bcc04d,
- 0xfbd58956, 0xab028bec, 0x8ebafd28, 0x7900c82c, 0x88d0fd60, 0x86f8c5f7,
- 0x4b8b37c8, 0x97d8eb65, 0x870a0c2c, 0xe47f5e18, 0xb7f61944, 0x012303fe,
- 0xf5cb507e, 0xab72f5f4, 0x5501ee09, 0x02e508e1, 0x4219f4fa, 0x2e505c8b,
- 0x58a4c2fc, 0xc74f1906, 0xb114dbc6, 0xd4f1d46f, 0x973529a7, 0x3785ddf9,
- 0xdea3c844, 0xbc3df934, 0xa15367af, 0x3bf73c84, 0x4b59bfc3, 0xef82172f,
- 0xe8c9dc25, 0x7a0a94c5, 0xe63a7094, 0x13ecb47b, 0x03cdbf42, 0xb8bc19f8,
- 0x4647df7e, 0x840c22d2, 0x2f4e25d3, 0xf5d4faea, 0xdeb6f3ab, 0xd6f300bc,
- 0xf1301f01, 0x7a9d5498, 0xd5f21e2f, 0x60f72e58, 0x2627285d, 0x7d0f2c4b,
- 0xdd7884bc, 0x3c46f134, 0xc78fb027, 0x0c93439b, 0x7e43de83, 0xfd7f1f0b,
- 0x04ecff95, 0xaedfd5fb, 0x44d9f3c7, 0x45de72ea, 0x8ef7c8e9, 0x52bdf784,
- 0xfb812a7a, 0xb89c8e67, 0xdd7a0318, 0x847aa94d, 0x0fc04df3, 0x115c3e41,
- 0xff7f304b, 0x18b217c4, 0x5393ff46, 0x7497ae45, 0xfe5e4276, 0x979602c6,
- 0x807ae16c, 0x057744e5, 0xf132dfcc, 0x4c2146c7, 0x1aa5e6ce, 0x868dbbf1,
- 0xf68b8250, 0x4910ebe7, 0x2e81f510, 0xefab47bc, 0xe0cc91dc, 0x05485d50,
- 0x47dc1e4c, 0x9ad7eeca, 0x3e30aa9c, 0x807de74b, 0xf91a8fbe, 0xf50e5c85,
- 0xacbc7485, 0x32adeffe, 0x78d467c3, 0xa6c59f76, 0xe193bfc9, 0x8158aefe,
- 0xafb43de0, 0x7935eaa4, 0xe8649ffa, 0x9d9dbf78, 0x65f9bfa0, 0x5b09f309,
- 0x40990f83, 0xc5f757af, 0x86dd54d3, 0xfdf8eb76, 0xe626ebaa, 0x805ce006,
- 0x4a7fc74a, 0x61527af5, 0xbc5f747d, 0xa7577a84, 0x47c22a67, 0xc97c87ce,
- 0xef13a431, 0x0685210d, 0xae4be419, 0x6fd9a74e, 0xea6f1c2d, 0xa8a5ea93,
- 0x69c23cef, 0x62f79559, 0x39e0898b, 0x62b32ba3, 0xd3152f41, 0x25cf3d54,
- 0x6cff1c03, 0xe1fa8399, 0x8d2d37d9, 0xf57cf1e1, 0xb3da9a79, 0x797f4341,
- 0x0333cba1, 0xde222fda, 0x2e8fa0b5, 0xe735166a, 0x7df2cfae, 0x144af0be,
- 0xf5e98609, 0x87de270b, 0x5e1647e7, 0xaa412189, 0xe7e59d27, 0x3cf2ce7d,
- 0x654f7f9f, 0xaf81b2f2, 0x75ea4b67, 0x08aefbea, 0x0ff3b97e, 0x7e3195cf,
- 0xf700eff9, 0x00cba12a, 0x8de36e7c, 0xfe3cc17f, 0x0f4ed4d3, 0x3ad37ce6,
- 0x6c3048e3, 0x5776be9c, 0x7e9eb84c, 0xff3828bc, 0x105af5fe, 0xfda9a70e,
- 0x4c70cdff, 0xbfb1c0d1, 0x1c0d2cff, 0x839ff607, 0x995e9fe3, 0x8ffd2dfb,
- 0x457fa21e, 0x7efeff33, 0x3db8e187, 0x8f9ecb47, 0x68e5fba6, 0x57f6f570,
- 0xb0ed5f21, 0x272fef11, 0x78c5ad6d, 0x0417e89e, 0x3f2d99cf, 0x90c7e5fc,
- 0xb77cb687, 0xf46305c1, 0x5cf343ea, 0x6187c883, 0x7dc3f644, 0x6f73ea3e,
- 0x27ae366a, 0x0a49bdf2, 0x666f90c8, 0x55e495ca, 0x9d65e80a, 0x1fb8d581,
- 0x549fc84c, 0x6fdab83f, 0x9ea88a6d, 0xad7dc567, 0x10d0dbde, 0x7c00eded,
- 0xe6a5167f, 0x8237f91d, 0x67f2ad1f, 0x85eecca2, 0xa21da1b3, 0xe225b1fa,
- 0x91a3bf45, 0xe5e40878, 0xdf7865e7, 0x53fefe00, 0xafc006ca, 0xe3d98e2d,
- 0xb723ff45, 0x3b9836f7, 0x7e30ae9d, 0xe954fbf7, 0xd6fce4fa, 0xfe333908,
- 0x4c82e7fd, 0xe61efcce, 0xfe762551, 0xf2132cb2, 0xbdf8bb08, 0xe3018a3d,
- 0xf0c78505, 0xd532afbe, 0x8c8baf5e, 0x40d9a75f, 0xeefd55ff, 0x044f9031,
- 0x9646c23a, 0xcd1e5dbf, 0x89bfe5ca, 0x907573c3, 0xf0079fc2, 0xec5d156e,
- 0xe119379e, 0xa1af917a, 0x1d31b4d7, 0xe1cbd9e0, 0x75fdb17a, 0x62ee57bc,
- 0x7fc470dd, 0xc13f6bf9, 0x25f6a17b, 0x0ea77cf3, 0x729fca2b, 0xee08aba3,
- 0xcc97db2d, 0x2956ccf4, 0xa6105318, 0x2d4bae77, 0xbe7abe46, 0xf40eb86e,
- 0x7fae1572, 0xa360fce6, 0x4293efea, 0x2ebbf045, 0xbf830be7, 0xdfb7f945,
- 0xa267bf8c, 0x1165f03b, 0xd1b76fde, 0x1782f788, 0x65b9181f, 0xcaafad2e,
- 0xa59e61d1, 0xe71980ee, 0xdd81a173, 0x82df03af, 0x903aae9c, 0x52c3bf82,
- 0x3cc21d1e, 0x5728aaa9, 0xca41c40e, 0xf784dc0f, 0x30da9f7a, 0xe5f81d32,
- 0x1d2578c9, 0x40dd35ef, 0x7dd74e81, 0x7b0463b2, 0xcf013f5f, 0x463759ad,
- 0x5ff3077b, 0xf22472a8, 0xc97d9efe, 0x006d3df9, 0xd726919f, 0x2d3e5a6e,
- 0xeb9c58b8, 0x82b66878, 0x9e171671, 0x9cb72bdf, 0xdbef1afb, 0x7ee4fe6a,
- 0x481def82, 0x161daab7, 0x97395e39, 0xa10cfb33, 0x387bf079, 0xdc386be5,
- 0xab9f2c0d, 0x839f975c, 0x8df70e65, 0xe65cf711, 0xab7831a5, 0x242753cf,
- 0xca8c2fbc, 0x67c874ff, 0x88d8753e, 0xe36a7674, 0xaaaf3c68, 0x614e578e,
- 0x797dd322, 0x058caed2, 0x634b8ebc, 0x0d7caafc, 0xf7d52fb3, 0x25cdbae5,
- 0x8750e780, 0xbd2bf988, 0xe2062872, 0xb53b6a1c, 0x769eb7dc, 0x65d77f11,
- 0xc411f25f, 0x0227a537, 0xcd7ba4f4, 0xf7d5f28a, 0xe037719a, 0xf1217cf3,
- 0xfe5c8347, 0xce4efd80, 0xea230ed1, 0x321fbdbd, 0xfdc074bb, 0x3a509649,
- 0x7be81fdc, 0x58f9052d, 0x17685a6f, 0xeccd93d3, 0xbd77b55e, 0x2c3c7813,
- 0x9647df89, 0xe5d9fa04, 0xf410730e, 0xf8c4fa33, 0x71ec9f86, 0xd1c3fbe2,
- 0xf436fc04, 0x53854019, 0xdfc4efd8, 0xfc4d2095, 0x7efc4efb, 0x0477ba79,
- 0xd9e5e5f0, 0x7c0b7fb4, 0x2eed8ddf, 0x806f7967, 0xe64bfd32, 0xbf6325e3,
- 0x7c0cde69, 0x64e17c2f, 0xc4d0a7bf, 0xdeb13beb, 0xc04ef467, 0x4ad1fc75,
- 0xe759065a, 0x55bbdef5, 0x7887169c, 0xe14de754, 0x245efa8c, 0x98d26a5c,
- 0x23c2a47e, 0xf0fb2e92, 0x03f32df9, 0x97c009bf, 0x363c33b4, 0x3e30348c,
- 0xf51a3f52, 0xa51b525a, 0xd55a13c9, 0xf761cec1, 0x9e22b06c, 0xa7eef57b,
- 0xde851e41, 0xaf7613d5, 0xc008d515, 0xf07130bf, 0xe78e72fd, 0xb3d65709,
- 0x2f73a27c, 0x6f9f4d9c, 0x678af381, 0x5515e735, 0x24ed1f3f, 0x1628fc06,
- 0x96531297, 0x116cf4c7, 0x377ec7e7, 0xc15ea367, 0x6ff207df, 0x847e8918,
- 0x00e50653, 0xc3518efe, 0x55d01d18, 0x1ef18bbd, 0x9f5b137f, 0x7a8e5f7a,
- 0x7c244def, 0xd9b2d35a, 0xef1091ef, 0xf2877003, 0xf024a249, 0xffde1a60,
- 0xa2ff0155, 0xa618afa0, 0x3f919b73, 0x185ca0d4, 0xe196cf78, 0xe83f7e5b,
- 0x3fbcb6ff, 0xeb3ae09d, 0x9018fe5d, 0xccca9fab, 0x53d8a3de, 0x6c8bae50,
- 0x69a7789d, 0x4f6bc812, 0xd63c5a5b, 0x54fc3f23, 0x9f2af560, 0xa07eb01b,
- 0xda07e817, 0xa78ebed1, 0x3219bf31, 0x8ca7b809, 0x8f900df8, 0x9f27caa6,
- 0x3ce0e920, 0x894db76d, 0xaeec7a01, 0xbd83b6cf, 0x1253665c, 0xc2e8c20a,
- 0x73c106f7, 0x37dc0aa4, 0x5f7e013c, 0xfc163dc2, 0x5aecfb75, 0x7ce4417f,
- 0x35d29a5e, 0x77febc2f, 0xedff4c69, 0x8a28fbe2, 0xdf9063c3, 0x2fbc4279,
- 0x77af78e6, 0xfb416f79, 0xe2dda231, 0x1e9cb1ad, 0xbd37de22, 0xf798affa,
- 0x4f7b43b1, 0x78f8cfdc, 0xf8371e9f, 0x19e01b85, 0x15baf985, 0xab9f199b,
- 0xe734bb78, 0xf3c65651, 0x1e5a53d5, 0x58e3dfc7, 0x0e7a7bb0, 0xf10b7c61,
- 0x82e3d2a0, 0xe80e7774, 0xa26da171, 0x62a2fb0c, 0xa9f388ab, 0xdb4c9a97,
- 0x5b33fbe8, 0x55dfa8f5, 0x499cf9f0, 0xde20c6f5, 0x28192224, 0xde48cfdc,
- 0xb75fd418, 0x891ddff1, 0xf76d0758, 0x0830549e, 0xcf0c4c7c, 0x41ec9f08,
- 0x1d5de0e8, 0xfc0169e2, 0xa3cc197e, 0xe4bf4045, 0x03ef3499, 0x76a6ee50,
- 0xdbffde3b, 0x59f78954, 0x8cfbc244, 0xb9f48bc9, 0x8547af98, 0x2a38e467,
- 0x9e017b3c, 0xdf1d2fa0, 0xf7cf728e, 0x4b140894, 0x425fb48e, 0xc74a7a7b,
- 0x826f8ff4, 0xdea99bf7, 0xcd9c80a2, 0x400fedfa, 0xf889d5ce, 0x1d65267b,
- 0x422409d9, 0x58dd835e, 0x189ccef6, 0xac9c985d, 0x7e31166f, 0x766c3f52,
- 0x7f6c42cc, 0xafa04ef1, 0xa12b8a93, 0xe8ddac20, 0x8178bef4, 0x9be55f06,
- 0xe3031aff, 0x71ea3454, 0x7a5e2a5d, 0xff909ce9, 0xbfa34536, 0x843537a8,
- 0xea78aafd, 0x83c06fa3, 0xddb44f4a, 0x1f32e95d, 0xa8fc8fc7, 0xe45bd33b,
- 0x164e841a, 0x85c7493d, 0xf15ab6fe, 0x1d6bc2fe, 0x1f478557, 0xc6bef9be,
- 0x5771e032, 0x75bffa26, 0x4c984aef, 0x6669b27d, 0x72e3ec3a, 0xdfc02f2a,
- 0x3e842e50, 0x3b247bc6, 0x6b0f788c, 0x0f25e6f9, 0x1fe578c0, 0xdf50751a,
- 0x58e6787d, 0x5e04579c, 0x07d29c29, 0xccdef7a3, 0x0c2bba50, 0xc09f547e,
- 0x27aeadfd, 0x0f38de6c, 0x7de14f6a, 0x1499bd24, 0x607c619f, 0xbbd33a76,
- 0x80d97b68, 0xc3eecdf4, 0x1caf5be9, 0x62395eb1, 0xa411efbd, 0xe2f2e26f,
- 0x647c167a, 0x05fbc1d4, 0x0391dc4f, 0x86eeb5fe, 0x6eaeb8a9, 0xec2c7bbb,
- 0xda74eeaf, 0x72fc20ff, 0x9d7413c1, 0xceb0df79, 0x6be23326, 0x43da75c8,
- 0xac37c8bb, 0x50e9c7d3, 0x4969e75d, 0x2bdfc189, 0xf012283b, 0x3cd2f897,
- 0x65626f1b, 0x9f289dfc, 0x6f83d19e, 0x31e63473, 0xfbb3b4f6, 0x403e55c9,
- 0x7a46bbc7, 0x743d21d0, 0x265b2b17, 0x106d7d02, 0xed8bc865, 0x5bf7186e,
- 0xeeaf1df8, 0x7a0ca28d, 0x83317742, 0x2807e51f, 0x3dd3bbb7, 0xb0f96277,
- 0xea8f7f1e, 0xdf5fd354, 0x1de173c7, 0xfae0857a, 0x42e71b3c, 0xf817ce99,
- 0x3dcb851a, 0xe3d55f4c, 0x9eebebfa, 0xff7a83aa, 0xfcf01bd6, 0xacf940c3,
- 0xa3457385, 0x4487d9a8, 0xdf3c7052, 0xaf782913, 0xca670a83, 0x1ec07361,
- 0xe501e152, 0xe1fa6339, 0xa0e7e3e2, 0xf7602f41, 0x067e7120, 0x7262c9f0,
- 0x0081ce02, 0x28f3831f, 0x48abc943, 0x47a913fe, 0xaf8fbcfd, 0x6571f968,
- 0x3e18efc4, 0x125e5118, 0x469637c1, 0xd44557d4, 0xe77cf953, 0xe4e7fe60,
- 0x2b5f2d0c, 0xfd5470e3, 0x041bbda0, 0x24cb43b4, 0xcff600c5, 0x7c98534b,
- 0xe988972e, 0xec97dc16, 0x44994b7c, 0xf0058d6a, 0xb70865de, 0xb57f6893,
- 0x472d3b46, 0xdb443e31, 0xcac21895, 0xe755bf2a, 0x878701f3, 0x7ecefcfa,
- 0xe321d281, 0x8fa41f15, 0x28af181f, 0x757eb310, 0x83abec02, 0xbe95da22,
- 0x21fc99b7, 0xf2da5d5f, 0x97ee03a2, 0x30bcc6cd, 0x7091fd75, 0x14bb6dec,
- 0xd7ebbf03, 0xe780dc73, 0xe3dacb93, 0xb2fed18a, 0x7b850687, 0xda9f5f0f,
- 0x15d48f5f, 0x6f5c2b33, 0xe1315d26, 0xd65aa3bf, 0xd8256976, 0x7e7e14b3,
- 0x9f8f8c31, 0x062f88ea, 0xd7fcb2bb, 0x7e70c5c9, 0xdaa196d6, 0x1acfcafd,
- 0x341cdf61, 0xe7a23fa2, 0xf83ab9ed, 0x0aede7be, 0xf78e5cfe, 0x3e9cf5b8,
- 0xc7e30e95, 0xfee7b4e8, 0x5b6fdc0d, 0xd764fbae, 0x0fffc0cd, 0x09ae6625,
- 0xeb9737f3, 0x7e1ed00a, 0x079a1f51, 0x7e7aa6f3, 0xaa57e41d, 0x1432d8fd,
- 0xf071af96, 0x0fe02eec, 0x15a636a7, 0x39e95b00, 0xdfed0238, 0xe5c70f9e,
- 0x247f68c8, 0xbc2f80b9, 0x339657a8, 0xdaeac57b, 0x1fdfd99d, 0xc671038c,
- 0x8a13839e, 0xf3d05fc0, 0x2d2f9b21, 0xb680ffa3, 0xa51e43f3, 0x4e8c6fda,
- 0xdd7904d9, 0xb47ad7e4, 0x3afa1e23, 0xb9ee113b, 0x1e0c3188, 0x41bb019f,
- 0x1abcd79b, 0xabdeade7, 0x2c57691d, 0x4f961e20, 0xa97f611b, 0xda4773f7,
- 0x69a41589, 0xd030976d, 0xb88aa45e, 0xfb009fc9, 0x456bfd5a, 0xef64bf79,
- 0xbef6a355, 0x9fdf3f62, 0x65c7e426, 0xa0363f74, 0xfcc029bf, 0xa0e2757b,
- 0x65efd771, 0x9e3ae264, 0xbcdbfe8e, 0x9ebc30ae, 0x49c911d4, 0x40d27ae1,
- 0xc182ce4c, 0xe9cbc6ec, 0xb40d9f60, 0x1fa2cf17, 0xbefc3ca3, 0x6ed03230,
- 0xc01c593c, 0x0d93bdbc, 0xc09efe22, 0x918ddaf5, 0x97bfabdf, 0x2c20c9e0,
- 0x6772191f, 0x3764dfed, 0xc2abe76b, 0xc77fccd3, 0xe2fdb222, 0xca37160c,
- 0x6e245afd, 0x7a1df7d8, 0xdd13bf3c, 0x1f96c5f2, 0xebb67d00, 0xe3054ce5,
- 0x0b7bf82b, 0xf988a0e4, 0xa7edbd7f, 0x39041e62, 0x1e1c7073, 0xd793eb23,
- 0x938c4507, 0x4a5db4f4, 0xed0a7880, 0xbec6e307, 0x405ca78e, 0xe3cd43bf,
- 0xfaf10cd1, 0x08eef9fc, 0x1f8f28bf, 0xc99cb4f7, 0xf94efe01, 0xb019a3e0,
- 0xe2be733f, 0x15756cf7, 0xf9d1fd01, 0x1bdefea1, 0xa5fa8cb8, 0xf41c5da9,
- 0x19f5aafe, 0xcfe3eb86, 0x8bf20325, 0xf7c467d6, 0x095ab3cf, 0x7ece4019,
- 0xb4c51e5b, 0xc3570b83, 0x4dbd33fd, 0xb77f0b82, 0xb9445db9, 0x3a3da0b5,
- 0x4cbc50a0, 0x72c1611b, 0xee764ef9, 0xf9388663, 0x2e6ff07d, 0x7fa220de,
- 0xf2cb48f3, 0x6798f5f7, 0xe58327a1, 0x5de7f461, 0xc6147c3c, 0xdc14fc59,
- 0xc4ff4312, 0x6fd00dfb, 0x8102d3e5, 0xcc884a9f, 0x779818bf, 0x144f35d1,
- 0xc05de607, 0x6907e5f9, 0x466d15bf, 0x3c0faff4, 0x1bc840ef, 0x21f7fd09,
- 0xbc6f0ee5, 0x9f6d28ef, 0xf96062db, 0x3e35667f, 0x0ef685d5, 0xd0f3b209,
- 0xa74f073d, 0x877d1e03, 0xb1fd07fe, 0xd20fed43, 0x0e3cf2ce, 0x57dfb066,
- 0xd2fafdcc, 0xda419e9d, 0x8b3cf237, 0x327f7abd, 0x5b47b1e8, 0xe83f232e,
- 0x6cfcc83d, 0xfc4ff643, 0x0aefe666, 0x570fd19a, 0x0edf2ad8, 0x83ea84fb,
- 0xeedf5eb0, 0xd377b3b5, 0xbd55f9b2, 0x6f95aa02, 0x0bf705b8, 0xdff08fec,
- 0xc9f75203, 0x53a71e5e, 0x791a47f3, 0x3f9a8dbe, 0x4493e6a2, 0x27cd43ce,
- 0x7c614c69, 0xf3c32f23, 0x945bd001, 0xe77ecfce, 0x68cf2233, 0xc8a1bca8,
- 0x71910773, 0x8ae24182, 0x46c0af2c, 0xc6a06e30, 0xbe540d17, 0x31d647c3,
- 0xd06537b3, 0x227bfd7a, 0xc5434fda, 0x1c75d51b, 0x79865139, 0x8b2f5556,
- 0xb0bfafe8, 0xbce3cf5f, 0xe9438c21, 0xc8617c4f, 0x7ece7e44, 0xcb47c95f,
- 0x5937def0, 0xd28efcd2, 0xe71e1c57, 0xd9f07233, 0x978fb923, 0xe47b7ed2,
- 0xf5e80332, 0x4a0b13fa, 0x9de8de40, 0xd7980665, 0xa6c51391, 0x4d9bc04c,
- 0xb6b37dc2, 0x53b71d5d, 0x3ffffe86, 0x1f012a80, 0x00008000, 0x00088b1f,
- 0x00000000, 0x7db5ff00, 0x55945c0b, 0xe779f8da, 0x380c2b9d, 0xa5117280,
- 0x380a0ee1, 0xdb95902a, 0x9784268e, 0x4d32d45a, 0xe5450757, 0xdb698032,
- 0xcbbaeee7, 0x5acd4d78, 0xb5aca8dd, 0xbcc0c1be, 0x1a163b60, 0x25a3b614,
- 0xb68b9599, 0x3f9b5b99, 0x0286f328, 0xffb9f562, 0xcffebf6d, 0x3af39cf3,
- 0x7e988ef3, 0xbf67dfbb, 0xde73877e, 0x73ce7d73, 0x9339cf3f, 0x196e39a6,
- 0x9eb19fd3, 0xcadb2d1c, 0xc87b3b18, 0x630d81bc, 0xf7fc07ec, 0xacf2c653,
- 0x18036312, 0x319abafb, 0x3e57deaf, 0x7c81fb3f, 0x02d8c196, 0x316358e6,
- 0x33235a43, 0xbfd191af, 0x1d1fb01f, 0xf281ee9b, 0x988357f9, 0x5dafc237,
- 0xb63d14f4, 0x94357f9b, 0x3d424779, 0x3677af13, 0x4f285204, 0x1872f1c0,
- 0x9de912cb, 0x6edf2d22, 0xebf69cb2, 0xa613c2bf, 0xc53557ca, 0xf9a74e58,
- 0x47f8e5f2, 0x636ffc0c, 0x98c91646, 0x97627f93, 0xdb74fc5e, 0x913f485c,
- 0x5856091c, 0x9ed48557, 0xb10c0f7f, 0xef57ba26, 0x2d3ae330, 0x63f29bcc,
- 0x5e608ceb, 0xd5ae71bf, 0xf5a46abb, 0x2566e0f8, 0x6bd6f9b8, 0x5d7c3826,
- 0x38137d1d, 0xe8e0aac6, 0x05413feb, 0x4ffbebc7, 0xaebff1a1, 0xff49bb4e,
- 0xbfd06f43, 0x5f7f3555, 0xee3449bf, 0x0b0d0caa, 0xa4f486cd, 0x5e00cdc1,
- 0xcb235500, 0x1d80cc65, 0x795654c1, 0x66ad19c7, 0x75257b5f, 0x6cb171b1,
- 0x946f7c14, 0xfdf0dc0b, 0x25ae6592, 0x985d5219, 0xa1dbb186, 0x705ecebd,
- 0x086bf417, 0x41708f0b, 0x89ac133f, 0xc2efaeb4, 0x28301516, 0x08f06eff,
- 0x838f15d9, 0xfcc42a2c, 0xf2c541aa, 0xe37f1c7a, 0xb5f70c73, 0x0fc7c8ca,
- 0xfc332fd9, 0xba30eece, 0x777ea193, 0x7996c7cb, 0x06dfce30, 0x3ee0e639,
- 0xc909f32b, 0x3ee19779, 0x6dc726b3, 0x3d8c2185, 0x0dac616e, 0x50f6daf3,
- 0x725eaf5c, 0x405de7fc, 0x06afec0f, 0x77c90f56, 0x25aa4726, 0xcabed7c3,
- 0x01f9a7aa, 0x68b2c435, 0xa50d5f5c, 0x08574d55, 0x8916d6ce, 0xaf7ca5d6,
- 0x77043d62, 0x8851e586, 0x7d2b5a93, 0x16a4726f, 0x71e6fa66, 0xccf7ffad,
- 0x9fd00d2e, 0x433fff61, 0xdadd9e11, 0x906dfb9e, 0x60e45a7a, 0x11aef87f,
- 0xf0763974, 0x50ed5937, 0xfaed895e, 0xdbd8f631, 0xf30ca9e5, 0x9c2c9e86,
- 0xffb7c1f7, 0xe90ed591, 0x6fcbfb77, 0x50edf2c3, 0x6ef90adf, 0xcda54f7d,
- 0x6624bfaf, 0xf9466971, 0x0fb16ad2, 0xf7dbe581, 0xf3881caf, 0xdcc1d068,
- 0xa59c61c3, 0x474f2365, 0x9fd83a20, 0xb5b8478e, 0xec3d58e8, 0x54d35747,
- 0xe54af919, 0x43058c27, 0xf619bb3e, 0x83d9f207, 0xfb035b99, 0x93ffb953,
- 0x955fb8e9, 0x068b7a39, 0xbc341296, 0xbe02bdcd, 0x2d18e507, 0x2c53e212,
- 0xeccf5f1f, 0xfb62258c, 0xb7dc08bc, 0x2a310637, 0x41f997ff, 0x6bdbc71d,
- 0xbc7bc0fc, 0xabc601b2, 0x47efdb90, 0xa17c003e, 0xf2a5f11e, 0x668e6fa3,
- 0x4f46b158, 0x78cfee24, 0xd0f8171c, 0x369fa2c7, 0xac0ee16b, 0xfbe0fdd7,
- 0x2de8b06b, 0xf5c0e1c9, 0xb68c62b8, 0x68cfc47a, 0xbf14c277, 0xaacd7d7d,
- 0x4ff0f6a1, 0x221dbc42, 0xa07bbae6, 0x22587167, 0x470ee5fe, 0x30d2a87c,
- 0x3643f207, 0x077a8009, 0xe66165e2, 0xe9ebcc94, 0xd415b18a, 0x7b56dbdf,
- 0x57c735b3, 0x336993ff, 0xd07d1d33, 0xc12a6221, 0x0479ef53, 0x6153d9e7,
- 0x7d856db6, 0x827e0bf8, 0x334f2f76, 0x5850e578, 0x56bcce8f, 0x193a3c02,
- 0x0075bb3c, 0xd9b57fac, 0x73ae1ef1, 0xd7e343fa, 0x183a5e60, 0x788c5d61,
- 0x8b9ed459, 0x726d12fb, 0x3be3807c, 0x22db8e8d, 0x06978961, 0xc1fb523b,
- 0x08c2b356, 0x98566f0e, 0xfce7d859, 0x797c7cf9, 0x54b841a6, 0x36f4b808,
- 0x7c43f626, 0x5fad7aed, 0x74f98316, 0xca095869, 0xdf312e87, 0x988f2073,
- 0x712e9f1f, 0x4117d31f, 0x63bad2fd, 0xeb7eb9fa, 0xeecc60af, 0xfc7eb8c9,
- 0x301fb88b, 0xffd785fe, 0xa1afddf8, 0xf76fceab, 0xc004b0a5, 0xad22e913,
- 0xc71dbbeb, 0x9df58b66, 0xd63ff5c5, 0x87a713db, 0x073d3975, 0x887f9cf4,
- 0x527b69f5, 0x5d7d6c7e, 0xc27cb69a, 0xa5927d8b, 0xaed7de3e, 0x7e58f1a2,
- 0x497be02c, 0x9908d85d, 0xe20a59e3, 0x061ba959, 0xa55bc3f1, 0x8b3e051f,
- 0x5debbf05, 0x1413e02a, 0x5af2859a, 0xfe328f81, 0xccf800a9, 0xe1e4f6d6,
- 0x0b2f663c, 0xea7e70d3, 0xbe51fc26, 0x1eaa59cf, 0x30e22577, 0x1bf5cfcc,
- 0x66f34dc9, 0x2b86ff3c, 0xf21ebdcc, 0xbf95cd06, 0x21bd454c, 0xbd436353,
- 0xf0104b61, 0xfd8c1180, 0x8bcfec59, 0xe18c1fc0, 0xcb16be54, 0xfb7883a3,
- 0xee3567e8, 0x70bed095, 0xe1e1336c, 0x9b6695cb, 0x3115630c, 0x8530ac60,
- 0x47aecc79, 0xe63d7fb8, 0x61dbfb1f, 0x1de2839d, 0xfeb0f151, 0xb89a1139,
- 0x1c3cd0bf, 0x9c032743, 0xc70e68d8, 0xc207b840, 0xe8b30a7f, 0x36c65fb0,
- 0xa7ee9068, 0xe652f858, 0xa78e9c4b, 0xc70ebb32, 0xa839907b, 0xbd2ef1de,
- 0x1c1d019d, 0x3060f407, 0x8b9887ef, 0x373067ca, 0x979933a5, 0xb59cffea,
- 0x03a15e53, 0xfd39ffc0, 0x8d9ffe39, 0xb26f0992, 0xc7be01e2, 0x2f06b382,
- 0x7e4c7585, 0x6199352e, 0x0803359f, 0xf79b373e, 0xb1c38964, 0x1db8eacd,
- 0xf05bdfd7, 0xd0354bed, 0x25e8c68f, 0x27c6bbfc, 0x78100dc6, 0xa27ce3f8,
- 0x09e397ad, 0x06398390, 0xd8af70e0, 0xe5ed7bd2, 0x8cbd7093, 0xfe9e4859,
- 0x9e5fd04c, 0xb3fd666c, 0x6dd97c71, 0xa5d8b9c0, 0xbe42468f, 0xd6cc8c60,
- 0x5bde3cc3, 0xbede48ce, 0x13765c37, 0x869f20ae, 0x7e8bf7f6, 0xba998d27,
- 0xcbd41faa, 0xdb3dbeff, 0x20c1690b, 0x7eed97dd, 0x7fbe35f8, 0x4830aaed,
- 0xcba92427, 0x2d36b227, 0x065275c2, 0xf3f1fb94, 0xf5d5b3fb, 0xe198e00e,
- 0x2328db98, 0x0f8ccdfd, 0x18267fe9, 0x90d843b2, 0xbd1f641f, 0x9de9eb28,
- 0x0ddf4574, 0xef10d8f3, 0xb2fb8b98, 0x67afbef8, 0x2d33bd23, 0xca2468fb,
- 0x5d7ca3a9, 0x00dd025f, 0xd5d3b206, 0x7e80d120, 0x883e80ce, 0xb7a073f9,
- 0xdaa17a61, 0xd045e94a, 0x577bf0b3, 0x9ef28db5, 0xec72c2f8, 0xcbdaee77,
- 0x4e06475a, 0x6df0852b, 0x36b7c089, 0x8c13578d, 0xb255b4f4, 0x625c7ca1,
- 0x0c1b1b6a, 0x1f525bf0, 0x671d836f, 0x569e4d65, 0xb7b17e9c, 0x75b71f30,
- 0xad45e1c1, 0x055c5698, 0x6cbd078c, 0x1ff85cae, 0x7f5d0788, 0x7dda72f9,
- 0x7ab67e50, 0xbe7f8d14, 0x77e34eda, 0xfa501756, 0x37e3bc7e, 0x4b7b0f38,
- 0x15846b47, 0xe132e577, 0x1d0d7dcb, 0xe7c858da, 0xd23b25d9, 0xe676dde1,
- 0x6d3d0376, 0xb5b971d6, 0xd216e419, 0x29cc98e5, 0x50ca3e2f, 0xc71e38ae,
- 0x509c1ef1, 0xdcfd879a, 0x8b48aa3f, 0x9efa1ef5, 0x1f7888b1, 0x8f0cddde,
- 0xbf5f0059, 0x7844b6f4, 0xfd634978, 0xae59ea19, 0x0be93223, 0x2a985abd,
- 0x727bdff4, 0x7b05db88, 0x626f78bb, 0xc5b7f214, 0xb8546b3a, 0x0ceb5f1f,
- 0xbb9d6be0, 0x97f68f6f, 0x9ee19d77, 0xbe433eef, 0x4be705f4, 0x5e6733b0,
- 0x8e65be40, 0x76fee1b6, 0xf404bb09, 0xcf9460c9, 0x47417a95, 0xdf3057c0,
- 0x14e6c419, 0xd5f73e42, 0x1748b1d8, 0x7caa1e38, 0x7949df0a, 0x5f84b9f5,
- 0x6de37d5b, 0xecffccf7, 0x725fc805, 0x903a5c6b, 0xa7989753, 0x575c4deb,
- 0xfa86d99d, 0x0da49a63, 0xea784a5a, 0x934c3a26, 0xc0a5daac, 0xfabc7657,
- 0x303fc0e2, 0x1b181bd4, 0xdadfdf05, 0xe77c4c14, 0xd4ed9d2d, 0x22ff6c52,
- 0x53caff6f, 0x09b2fcbf, 0x462b27d3, 0x3ef112fc, 0x5ae09c3e, 0x21d2fbfc,
- 0x63436788, 0xbfa01b61, 0x5e486f5d, 0x99631653, 0xc4560735, 0x6d867cc0,
- 0x840cd0e9, 0xb49d7874, 0x21a1d312, 0xf8658705, 0x95bc5efe, 0x21b231e6,
- 0x72458e5e, 0xecfee819, 0xa87fa4a7, 0x9a8c92f5, 0x320763cb, 0x44327e9f,
- 0x7dc05cf2, 0x62721959, 0xb63fc904, 0xdbd9fa91, 0x99e3f532, 0x7cd00eb4,
- 0x7a45de70, 0xb70bc91b, 0xecf116ab, 0x46cd2392, 0xeba17afa, 0x4bdfdc79,
- 0xca1b488e, 0x571a7d8f, 0xff589de8, 0xf9d69694, 0x50b1dd46, 0x35fbe41d,
- 0xbe0998ea, 0x21ef0c57, 0xd83159b9, 0xc1dc70ca, 0x805bdd2f, 0xdc6ca9f0,
- 0x38fd4b5b, 0xea09368d, 0xd2bdec95, 0x8d94728a, 0xc464b667, 0x7f9e46af,
- 0x86dd9c62, 0xf6a4b572, 0x2b6f9e5b, 0x58217ca4, 0x3fac5a13, 0xcf69eb8f,
- 0xdac53909, 0x117f88b3, 0xfb7d5aca, 0xc67c04f5, 0x5de39bef, 0x3ecc8b31,
- 0xe97206f9, 0x8c59d202, 0x1b6fb79e, 0xe08e333b, 0x49728b72, 0x3d39e7e9,
- 0x4e509973, 0xacfcb9ea, 0xf8817e07, 0x17fffd01, 0xd1c8aff6, 0x6cca5958,
- 0x3ec77584, 0xb4adb067, 0xd338fade, 0x3921adfb, 0x5575e8aa, 0x89585f42,
- 0x36fda055, 0x804e43b3, 0xb90be671, 0x0cd6b4cb, 0x319e43d4, 0xa409b5db,
- 0xa3de81d7, 0x4c667921, 0x0658bd40, 0x4fd12f3d, 0xdf8733cf, 0x366b3c92,
- 0xfdb143db, 0x2fefd6ad, 0x3157f9e6, 0x444b424f, 0x31c85748, 0xf23de03b,
- 0xa127764e, 0xeb0357aa, 0xe790701b, 0x6dfa1213, 0x7aba055a, 0xfa958252,
- 0x7c11f801, 0xca19e761, 0x243ca509, 0xb841e39b, 0x47fa48c3, 0xe1a2c454,
- 0x9af0fc8b, 0x1123bd69, 0x5bffeb0e, 0xbfa84af6, 0x1bb33ffd, 0xbe7025f1,
- 0x3fdc0945, 0xb9890bf1, 0x97578834, 0x45af54f5, 0x8febbed7, 0x34a5aed0,
- 0xed7686c3, 0xd821e43e, 0xf49ea84f, 0xe61096a9, 0x99697a42, 0x7d46e91c,
- 0xa7b42dec, 0x88661e90, 0x7c4626f6, 0x40c665ba, 0x0d0387e2, 0xf35c1800,
- 0xaf6f034a, 0x2641f45b, 0x963cbff6, 0xc94ac7e4, 0xf48136bd, 0xcbe49935,
- 0x6a8fc149, 0x6533bcc2, 0x9cb9af28, 0x939c70c2, 0x61569760, 0xa22092bd,
- 0x7b309abb, 0x7dd7f20c, 0xdf132dff, 0x790e19ab, 0xf225f133, 0xb64cd4c7,
- 0xfe4184c7, 0x351fb161, 0x67faeeb5, 0x69c9bfb1, 0x3281aeb4, 0xe2f5445b,
- 0xe99f3f79, 0xfdc73b78, 0xdbd45ac1, 0x20c50241, 0x4e285efc, 0x2a07c866,
- 0x44cec613, 0xf7ec52bc, 0x28df82e9, 0x630363fd, 0xfc63ea2e, 0xf5f98cdf,
- 0x07aba426, 0x201d4c4b, 0x92c9d839, 0xbf682115, 0xbd90e83e, 0x1e5bd406,
- 0xd35fb3c8, 0x7fb0120b, 0xb3c24cfb, 0xf27ec562, 0xbdb843ce, 0xeb6463dd,
- 0x7d847f49, 0xdf1ebccd, 0x22633c2a, 0x52c7edfc, 0xf397a703, 0xd7482f38,
- 0x714a3b07, 0xe34d55de, 0xcaedfc23, 0x8757f319, 0xf18bdd12, 0x23db562e,
- 0x5ea1274e, 0x32a94050, 0xc14e329e, 0xea5da314, 0x818df68f, 0x4239aaf4,
- 0x7832ad0f, 0x4dfd21a7, 0xa31e3937, 0x642eca71, 0x7fd8bea1, 0x9c3f5a4a,
- 0x32fbf77f, 0x253d3c43, 0x3214f5f6, 0x45a7c46c, 0x4c2f8421, 0x8ebf1de4,
- 0xf41cfd20, 0xc737c21a, 0xde5286ef, 0xccc7b7a1, 0x1c5cfc47, 0xca71f84c,
- 0x729fbfc2, 0xcd7e1186, 0x87f95dfa, 0xaa7be00c, 0x78784f50, 0x3f2645aa,
- 0xca96dfcf, 0xb9c03d5e, 0x67d5ca6b, 0xd75da053, 0x3772afb2, 0xe2beda43,
- 0x3f9438f3, 0x4c5456b3, 0xcab376c2, 0xfc8fdd96, 0x3d7446f9, 0x441069cb,
- 0x35b6e1cc, 0xd711bec1, 0xd5ca7fd9, 0x03cbe47c, 0xcfcf9dcb, 0x0983f287,
- 0xcf88678e, 0x112bdbe8, 0x7d6f951e, 0x73fa8711, 0x7b2bf377, 0x6dfd215a,
- 0xfa79e388, 0xf8dee2be, 0xb099d8d5, 0xb0b52abf, 0xb73f805f, 0xc45e3a27,
- 0xbce355ef, 0xa2eed829, 0xe11f2dae, 0x9add96c6, 0xa5a17dde, 0x76849f7e,
- 0x254b5060, 0x0b3bb2a5, 0x7929d1e7, 0x8444a543, 0xb00be823, 0x6f168bee,
- 0xb9e21868, 0xb7cbc3d0, 0x5347d7ab, 0x077e148b, 0x91ee5768, 0xb3d226ed,
- 0x6f9c7add, 0x2872fd60, 0x58b77aa7, 0xbc3cc65e, 0xa9e9ac3c, 0x7b7ef8bb,
- 0x179fb0bd, 0xc56f2476, 0xf7b4befd, 0x3b7f1495, 0x7ebd3038, 0x17fd7cbe,
- 0x8e00bf11, 0x8744a117, 0x5060d5f8, 0x3b5d7fd9, 0xd5f85462, 0xbdd523b5,
- 0x762f8fde, 0x6cc1be09, 0x88c9dc9e, 0x2e4f76f7, 0x9f0a55ea, 0x164f4660,
- 0x9e696fd9, 0x1457b42c, 0x3d0ac33e, 0xf6ee5429, 0x7dfd60a4, 0x7d9acf68,
- 0x8aed96e3, 0xfdcf5dad, 0x364d2e8e, 0xc56e87e6, 0xcdefd2bc, 0x59ba97d6,
- 0xbba7caaf, 0x09d3f9d5, 0x73b69fdc, 0x83b15ea7, 0x30476165, 0x568fb2ab,
- 0x5c11afae, 0xe057aafe, 0x2e6c68f2, 0xafe00dfa, 0xe7379a04, 0xddb93be3,
- 0x23b86fbc, 0x62a9f916, 0x830bef9f, 0x51ca067c, 0xaf256f3e, 0xde7021c0,
- 0x20bafe2b, 0x967bfd16, 0x4e508d44, 0x3f88516c, 0x2f9c4d2b, 0xbe81d4ad,
- 0x4976819a, 0x5ad3c8c9, 0xd16c57b4, 0x1c1f5ac5, 0x6e1e6c16, 0xb85d3a44,
- 0x1fd1b865, 0x1f6e561f, 0xf30ad879, 0x6b5db8bc, 0xd4af29c3, 0x7d429fba,
- 0xd976e56c, 0xddf462e3, 0x17fa8768, 0x628f07cd, 0xb85b05bd, 0xbf69429f,
- 0x744e7370, 0x873cdfb1, 0x33c3576e, 0x0fcea3d3, 0x07e7526b, 0xf391aea2,
- 0xdc376f3f, 0x3c8fceab, 0xfd9fceac, 0x10d3a3cb, 0xd7644aed, 0x87ea3253,
- 0x461fe79f, 0xdf6e71b9, 0xdfe4a11b, 0x15b8a2f9, 0x9b85def5, 0x7d8670d5,
- 0x701f5093, 0x2e48936d, 0xe903ba96, 0x65ba6fa3, 0xd7e2b96c, 0x93c7f34b,
- 0xd56ae632, 0xbf5f5fc6, 0xd9a67993, 0x74b48fd1, 0x23d3c8f1, 0xe1defd7d,
- 0x7b47a4d9, 0x1bdc7027, 0xdb3329d1, 0x165f68ad, 0xeedfe28d, 0x7d963a5c,
- 0x6d882205, 0xf88f9638, 0x4484f457, 0xf5e8b6f2, 0x2f9177d4, 0x3199ec77,
- 0x0569d281, 0xcfc50f04, 0xf245b0b2, 0x32de4086, 0xfcede38a, 0xc19b92cd,
- 0x32aee7bc, 0xc541fca8, 0x58f3d41b, 0xbefea350, 0xdfc0e9b0, 0xc4bfe825,
- 0xe51e92f8, 0x4316c956, 0xfdcb1f80, 0x65e1ea0e, 0xd9d918e7, 0x183f7565,
- 0xcd73f2fa, 0xbae1d657, 0xb8fae19b, 0x07d3e78a, 0xf806634f, 0x857efef8,
- 0xfea11233, 0x32b5359d, 0x3982adc2, 0x9224b31e, 0x860de99d, 0x7d002c79,
- 0x9069f509, 0x2baeb4b7, 0x0db9fb9b, 0x4cce54f1, 0xb5857e50, 0xbe1ca2e5,
- 0xe36218d2, 0x5cb6b0fe, 0x4217e40b, 0xc256e11e, 0x9c7c1236, 0x8e657fc8,
- 0xf9bf762f, 0xe7f93ee2, 0x8fae46d9, 0x03deb53b, 0xd6728708, 0xff70ed4e,
- 0x6139ebfc, 0x51c3275d, 0xcf6808df, 0xaf0fe46c, 0xdf69eb32, 0x307e9aaa,
- 0xec577ff8, 0x512ec500, 0x59ff6dfc, 0xe21070f6, 0xfec96af5, 0xd4c651bc,
- 0xf115a7bd, 0x724cd4b8, 0xce5ae1fe, 0xd9d06bcf, 0x6cd7fd02, 0xf37d274a,
- 0x829ec961, 0x4c9b65eb, 0x1e810764, 0xdb3abf18, 0x3e81d7a7, 0x9fa132e8,
- 0xbdc834b8, 0xe70fbf15, 0x8ccd79f6, 0xde17d214, 0xe45e3c92, 0x3867aec3,
- 0xe64cd4bd, 0x64f353f8, 0x0cff7d0c, 0xfa831aa7, 0x6a4bd722, 0x3d72a536,
- 0x60f3e656, 0xfe210bbf, 0xe62f1358, 0xf34ac035, 0xc9f5f452, 0x8973c716,
- 0x5e2ceb7e, 0xf4247a01, 0x995bfc5f, 0x95829fa1, 0x3c92dc44, 0xaa7217af,
- 0x8dc99367, 0x52d3eefe, 0x3f9e2b61, 0x13dfb35c, 0x1dcfdf39, 0xea26df6b,
- 0x58bc5f91, 0x4ffd7933, 0x3567bc71, 0x7ef195d6, 0x53dbb7f0, 0xbd3fcf50,
- 0xf70234c9, 0xce70d4e9, 0x72c773b7, 0x25d801bf, 0xee90adf6, 0xfca8d449,
- 0xb9127bab, 0xd13fb09d, 0x3ce9e94a, 0xc90c47ee, 0x0cff242e, 0xf1f115ec,
- 0x17ec75c0, 0x85f58aed, 0xc7d27e47, 0xb0f8147c, 0x4e7f7c71, 0x5c91223f,
- 0x58a4f584, 0x7bfb9f20, 0x4e75f913, 0xeca2f90b, 0x0e51e00b, 0xbfc15bc9,
- 0x49fc459e, 0x27f014c4, 0x51fc2fbb, 0x60c3c7e3, 0x7f1098ef, 0x1f683f00,
- 0x327afc15, 0xf011f693, 0xe7a1f087, 0xf00dd349, 0x285f6d47, 0xe5a9adeb,
- 0x5da047f6, 0x3270f801, 0xa0bcefd1, 0x0427ac26, 0x3c14b7cf, 0x8e775a60,
- 0x205a39ff, 0xe6c9e41e, 0x4befe434, 0xea1b20a4, 0x7f844bdd, 0x467cc97b,
- 0x8b658df3, 0x68d7a424, 0x0ec895e6, 0xec266d66, 0x003d27ef, 0xfc3a3f73,
- 0xf32355e9, 0x58637b97, 0x8f7f2a98, 0x3f554631, 0xfaaf12cf, 0xba746f7e,
- 0xeb78fbea, 0x627e5570, 0xfaaa1dda, 0xa8c6d9f7, 0x351b3ff2, 0xb27f555e,
- 0x6f2ab27d, 0xce2d1667, 0x60baa5bf, 0x6f1fda24, 0x5e921757, 0xd1970810,
- 0x5baf8386, 0xea46206d, 0x00b453b4, 0x0efdd1bf, 0x7c87892e, 0x14d33aff,
- 0xe8c7e02d, 0xe25783d8, 0xd5a2602d, 0x43eff105, 0x80495e0f, 0x305d747c,
- 0xc8c5dfcf, 0x67581f1e, 0x9332e29e, 0x093630bf, 0xeaed3ce0, 0xf66843a2,
- 0xca7cb27d, 0x75a478fc, 0x3ff33267, 0x7566d8b7, 0xe53d6184, 0x547f52bb,
- 0xefb52152, 0xfcf9ccbe, 0x393fb827, 0x760a7aff, 0xb18fc917, 0xac6c341c,
- 0x5be74cd1, 0x78bba8cc, 0x7c0cafcd, 0x8633b253, 0x6a96b9fe, 0xc22d67d8,
- 0xb7a948cb, 0xc1e942da, 0xdf4a68ea, 0x62b2b6ad, 0x756b6780, 0xab87a51a,
- 0xa47e546d, 0x1fa5147a, 0x3d29db56, 0x69405d5a, 0xa521755b, 0xb34f2812,
- 0xb36c6f90, 0x3c21d5ad, 0x33b0da5c, 0xd9fe3e30, 0xe1f2df17, 0x519d96ad,
- 0xff2a15f6, 0x4dcf64ca, 0xb20d75a2, 0x945b9f90, 0xa9ffda1f, 0xe8d1f915,
- 0xf5e1236c, 0xd59b7368, 0x48f3cd98, 0x99977567, 0xebca1357, 0xf5ebfd69,
- 0xfe470cf7, 0xa669da30, 0x50bd497a, 0xbdeb0b2f, 0xf2c5a317, 0xca1b7a45,
- 0x3f04e7cb, 0x901cd10e, 0x5e909c71, 0xc834367e, 0x144ef9c0, 0x5df85fa8,
- 0xf5d5a3f1, 0x8706f1f2, 0x9df3a22f, 0xc4cdb3c1, 0x15b9147f, 0xc18de11b,
- 0xd12ec5f9, 0xe6887953, 0x2efd15b8, 0x09ded55d, 0x84e3af88, 0x67a71f9c,
- 0xa60f3869, 0x94f92209, 0x1adf7f27, 0xcdc5f90b, 0x398c70d2, 0xdc286718,
- 0x96a1f642, 0x6feb31d3, 0xb6b8fae2, 0xa815f4ad, 0xd6323c77, 0x15a11eb6,
- 0x81258fbd, 0x5557959e, 0xf2728190, 0xf448db38, 0x31d43f3d, 0x6a6df10f,
- 0x46bdd006, 0x13f40920, 0xfc4c105d, 0x6a7f7bb3, 0x53cdea0e, 0x0cbdd60c,
- 0x292ca2e8, 0x4a7ef087, 0x648e6b3f, 0x445dfcc1, 0xaca25327, 0x9e1b257b,
- 0x194ce49e, 0x71bfc777, 0xd2493d2e, 0x7ca9c7fa, 0xc31e3922, 0x5c1455f9,
- 0xf5f9f3d2, 0xebf89e90, 0xb3f12b24, 0xc9190701, 0x21f19edf, 0x7fd15fc4,
- 0x61f918b5, 0xeb073586, 0x427ae9c5, 0xfba0ee31, 0x5dc52d7b, 0x07d0cd40,
- 0x2f1efcfc, 0x8c78f0b5, 0x9a1bbc40, 0x554de5cc, 0xaa038f12, 0x291a368c,
- 0xcf9cb96d, 0x30a24e28, 0xd036ed09, 0x5794fb1e, 0xdcb99383, 0xe7a35f8b,
- 0x49643afe, 0x107b6530, 0x8c2ef253, 0x2c7da907, 0xecee5148, 0xc7a64e00,
- 0xe87f9476, 0x5492e3f7, 0xdf58edf5, 0x11d99df7, 0x9dfb4a9c, 0xbf7e9375,
- 0x43c62b4a, 0xdcc0597c, 0x7e4084b8, 0xb87245fe, 0xfb411e72, 0x137f62fc,
- 0x324993d9, 0x71e037e0, 0xfc87b06c, 0x8e26757f, 0x9e1a49ef, 0x77f869d6,
- 0x93e8107d, 0x790c1f90, 0x3efa773c, 0x1e49e1d9, 0x0599ed40, 0xa87bcbdb,
- 0xd0f30c7d, 0x28f7ca78, 0x9d435ef4, 0x304f2041, 0xfa6b2d1d, 0xe498db84,
- 0x7d211f31, 0xf91f0177, 0x775f8fda, 0xf52e8705, 0x6c4aa7df, 0x376ff66f,
- 0xed29da96, 0xd86a962b, 0xffc411d7, 0x922a5f08, 0xb7377634, 0x5095df37,
- 0x7a6d604f, 0xbb4a6b94, 0xbeefc013, 0x05ff7806, 0x27a61ff8, 0xf8e1ef81,
- 0xc3df019f, 0xf7c06ff4, 0xf014fcb0, 0x81db4c3d, 0x97f961ef, 0x9d30f7c0,
- 0x1b243336, 0x69aaa4e9, 0x855afb0c, 0xff873af7, 0x3189ddf9, 0xd9cbe37d,
- 0x9ed76e24, 0xfbfbef88, 0x7c71277f, 0xdf37713a, 0xd7906eb7, 0xfe019fa8,
- 0xdf84b2ad, 0x87776e58, 0xef9e73f0, 0xd77eb8d2, 0x5ff3c31d, 0x3fa8e926,
- 0xc66d86bb, 0xe9a5dff6, 0xe649ef29, 0xf85ba372, 0xa8ff012f, 0xc31e657f,
- 0x7aaa4a86, 0x814d24ee, 0xdef98fbb, 0x23c7cc9d, 0x1c3d44fc, 0x0fde31f1,
- 0x84ad2b3f, 0xf178819f, 0x249ba085, 0x58bbc703, 0x27c8f1e4, 0xbe744ca3,
- 0xe3b5f30a, 0xc49d7479, 0xfc3af1f1, 0xe77b70d4, 0x7e84fc3a, 0xe7804e08,
- 0x093fa412, 0x35251fc0, 0x45b77988, 0xe082fc86, 0xa0b3a2dc, 0x3227efff,
- 0x6bdb1600, 0x84ce8f7a, 0x10c8d8f2, 0xe41d9e2b, 0xd45e6e3d, 0xebb8ff17,
- 0x35ff5ddf, 0xffaf547a, 0x738b75ba, 0x375d5b93, 0x97e413f1, 0xf07d3f88,
- 0x1fc82187, 0x33f87c72, 0x849ed926, 0x264b74fd, 0xbb81fa2d, 0x022f1c4d,
- 0x1a5dfbd7, 0x3f055fc7, 0x18fc40be, 0xbac3fd80, 0xb9eb7d12, 0x80a0ff36,
- 0x14642df5, 0x8fb8110f, 0x5bf15f0a, 0x39c91dd7, 0x2601b83e, 0x041efc92,
- 0x71fd1bf2, 0xc70b649e, 0x676701f3, 0x81f9426f, 0xffea0272, 0xfafdc341,
- 0x56bedf0a, 0x2673c92e, 0x39f8a867, 0x67b07b43, 0xcbe881bf, 0xaf2561ab,
- 0x43825da1, 0x8f59d9f9, 0xf6f5f325, 0xa0d64f4e, 0x9df5d4de, 0x27f145d9,
- 0xa14e7b03, 0x59b5d67d, 0x6d3db8c7, 0x3c81249f, 0x057e8f9b, 0x8dc5fa2b,
- 0xa17b6e74, 0xd43d991a, 0x853e5cf3, 0xf3d56176, 0xe8023332, 0x9dbfe7e4,
- 0x60b2f886, 0x7a82cebf, 0x4fcdcac7, 0x3b7c461f, 0x515928d3, 0xc23577de,
- 0x457ea1b2, 0x04db884d, 0x8f21f3f5, 0xf59a17f5, 0x8f1f2b6e, 0x18a74cf4,
- 0x65536bef, 0xefa5fa02, 0x70475e79, 0xc783b05e, 0x79b3bc31, 0x9f639d09,
- 0x0a2c4b71, 0xcbcbe5da, 0x9fd0635a, 0x3364a2f8, 0x39a73b40, 0xefda3cff,
- 0xcd983b65, 0x3d8afe8b, 0xb2be7421, 0x7f1d46a0, 0xa4dee250, 0x64a27d47,
- 0xacbcba8b, 0x9d879d4e, 0x6ceb7e21, 0x3c33c750, 0x15e22c92, 0xf270d9d2,
- 0x9384d633, 0xd3f0a01e, 0xf631d91b, 0x324f9cc5, 0xfa244df6, 0xdffde549,
- 0xe6697dc6, 0xdf22c9f9, 0xdf4bf901, 0xe0517df2, 0xbf9ca952, 0x4f6cb0c7,
- 0x99dfc636, 0x55c7682c, 0xca157f36, 0xa82cee30, 0xcfa27efd, 0x538a6537,
- 0xbb24d75a, 0x2d15be10, 0x3e3197a6, 0x31ef72af, 0xe10435bd, 0x01e908fe,
- 0x1ad732f7, 0x1abcbfb4, 0x3c236b0d, 0x15ff236a, 0x202cf7b3, 0xc9b370bf,
- 0x6f3de742, 0x133ada7e, 0x66257bf3, 0xdc1c7dc2, 0xe0b2784e, 0x75ce9979,
- 0xb93e6a19, 0x71913c3e, 0x3d9f715f, 0x16bf68fd, 0x3ee3bee2, 0x3ee3bec3,
- 0xd89fb8cb, 0xe6ef443e, 0xccedc278, 0xfef9db33, 0x2f9efb2a, 0xdf93d06f,
- 0xf3ef96b8, 0x3fd7cf3d, 0xa078441b, 0x680f0263, 0xe16ccfdf, 0xbfdfaefb,
- 0xf1103f5a, 0x0f0036b7, 0xf0d70d9a, 0x1d77e700, 0x7fec041e, 0x07cbf0a9,
- 0xfee041e2, 0x44f82bdf, 0x10fa3c9e, 0xfe2cd9c6, 0xf1571f05, 0xef0ecd73,
- 0xaa0478ac, 0x11ff1a9c, 0x392cdd9a, 0x049635fa, 0xb421bd72, 0xc0f909b0,
- 0x86bb09f1, 0xfc099c53, 0x9c524633, 0xddefc11b, 0x053dfd5f, 0x7e3bbfe9,
- 0xe23796f2, 0x703aff69, 0xc161dd1d, 0x96ee7e5c, 0x1b9512dc, 0x538006bc,
- 0xa451f01e, 0x81b6f643, 0x07ba91ce, 0x31e8f43c, 0x693f77c8, 0x48f6e1b6,
- 0x951f6e76, 0x1277bcb7, 0x31ac86fd, 0x9fb2aecf, 0x8e537d84, 0x6f7e15f6,
- 0xefcafb00, 0x7cb24e3c, 0x4f3eed44, 0xcaf5a04e, 0xb266db1a, 0x9598ea83,
- 0xe3af63ce, 0xbdf88cf7, 0xa1ba07e2, 0xf7c0163e, 0xeb9efc7d, 0x2835cc61,
- 0xb14be90c, 0xb47e14b3, 0x0f4bf850, 0x1b44763d, 0x03aceb81, 0xb5bee3b8,
- 0x8fea1f00, 0xdb9d3d7e, 0x8dd1f92a, 0xf1167fa8, 0xce78e00a, 0x469f68b5,
- 0xd332fc46, 0x0f029d7c, 0x605f112b, 0x07d9659d, 0x775f5142, 0x6ce1fe0a,
- 0x497f210e, 0x8f98db19, 0xe30655f8, 0x9bc0fb79, 0x487bedb2, 0xde19bfcf,
- 0x655bfa28, 0x3fdebaa3, 0x250c9f90, 0x03f9927e, 0xfc69dfe0, 0x37c7c73b,
- 0x7e8ce4f2, 0xcbdc0718, 0x6e90fdac, 0x52d7246f, 0xfb290337, 0x36ee9bf5,
- 0xcfcaad32, 0x33e5516f, 0xfaaad13d, 0xaaac9ac3, 0x69bdc3ef, 0x0f23efaa,
- 0x9cf954db, 0xfaaa51b6, 0xabb49fb7, 0x17b477f2, 0x75dfeaa8, 0xef9550ae,
- 0xfcf580cd, 0xbdd739c8, 0xfeaa92d1, 0xd549ab78, 0x042a683f, 0x6169899f,
- 0x335ef2aa, 0xfa8dd387, 0xeea6cfbd, 0x7f6fb157, 0xffdd4a36, 0xdfbabb64,
- 0x6d87dd5b, 0xa0b52720, 0xb9076f6f, 0xd04ee989, 0x6fa0b5cb, 0x8e5e8037,
- 0x2f4157f9, 0x7a03d4c7, 0x06bf9639, 0x1be6397a, 0xfcc72f41, 0x3023b03e,
- 0x405d54df, 0x85d59be9, 0x78337e54, 0x0f718ab5, 0x888f718b, 0xc4db1971,
- 0xe04dfee5, 0x7f68a1f2, 0xc36fb454, 0x3c3e49f6, 0xd64828ac, 0x1d3a055c,
- 0x8f5e7e13, 0xc5f65ae7, 0xd768f9ed, 0xb32fbcf7, 0xcc2740ad, 0xdd5c3ee1,
- 0x0452e51f, 0xec2faf3f, 0x0efd00f9, 0x2d137b95, 0xaeb06e78, 0xf8a3e3e9,
- 0xb651abbd, 0x6c1ddd22, 0xfb142afa, 0x141578b9, 0x9e4291bc, 0x77f9de41,
- 0xf0f5f946, 0xc7d5e31d, 0x964501ef, 0xe48794e4, 0x2524c5d4, 0x0e7ba6ef,
- 0xf47b0d85, 0xb6fe74ed, 0xefbfbe87, 0x6fbfa9d1, 0xb77d55af, 0xf73c7d60,
- 0xcec9bad5, 0xf4a4d0be, 0xcefaa5e7, 0xfa8ec924, 0xefed85f1, 0xb738c1ac,
- 0x11453d8a, 0xde567e78, 0xde722c70, 0xd2ffc08f, 0xc8195dbe, 0xa19a2bd7,
- 0xbfafb33f, 0xc89d668a, 0x933bf9f3, 0x2387e4f6, 0x18906edf, 0x6c8b928a,
- 0x950dc523, 0x913bd537, 0xcda7952f, 0x4e39e1d4, 0xf61647b7, 0x73c38f3f,
- 0xc7d7185a, 0xe742573c, 0xf27fbf41, 0xe31fba1c, 0xde5bba69, 0xbb71c509,
- 0xdf869ef1, 0xc2913efe, 0x5227daf5, 0x8b87bdf8, 0x6284ef8d, 0xcf3ac5fc,
- 0x5aee1c3b, 0xa0ffad2f, 0x4a4377c8, 0x69926ef0, 0x3557a5fd, 0x7f4a0fb4,
- 0xd4c8a6cf, 0xe4a6f8cf, 0x71d75c10, 0x8dcf1f0f, 0xce3005c1, 0x62a2a4f8,
- 0xe891ff9c, 0xe9323919, 0xdc6fdc75, 0x3d62643d, 0x8e7813ea, 0xf5dd97de,
- 0x55b7e89a, 0x9fbdf7c4, 0xf22b7af4, 0x110523db, 0x880649c3, 0xb8533b7a,
- 0x77af919d, 0x389ca124, 0x1f92b66e, 0x62414579, 0x41efee08, 0xe0bcb14c,
- 0x97cbf265, 0x8ef1f235, 0x1142da5b, 0x8e378eef, 0x516f5194, 0x71c3abfa,
- 0x6facf8fd, 0x4fb45cdf, 0x335aee25, 0x3fdbe3f6, 0xb14eee5e, 0xee23bb50,
- 0x3f50d363, 0x4c169e3a, 0x9eab45fa, 0x37977b9f, 0x78f6fd70, 0xecad6c4b,
- 0x16e15e77, 0xa69dd1fb, 0x6aed7da1, 0x337a89d2, 0x9eaa99eb, 0x9d57ef8e,
- 0x77163e7a, 0x57a853c7, 0xe9945f3b, 0xb7538eee, 0x7fd71228, 0x7e7a8b76,
- 0x4ece0225, 0xd232379d, 0xcd9d5f0f, 0x4cc6e8d7, 0xd0acde78, 0x53f69589,
- 0x69e3c7d9, 0x1e3b2f5c, 0x390befcd, 0x5e13d4f7, 0x5b7de4fb, 0xb11dea3c,
- 0x4ee3c1ff, 0x2ad7666f, 0x5d9f80fa, 0xd3aed0c4, 0x68e62415, 0x3f727c12,
- 0x79fec52b, 0x97b400ca, 0x040ec90a, 0x3f210f64, 0xfdc3ea08, 0xedfeff90,
- 0xb7b71c59, 0xd440f411, 0x134d8c83, 0xaf4afef0, 0xe604080d, 0xe745bbdb,
- 0x198bf616, 0x4205d2f5, 0x756b3d2f, 0xbe78cae4, 0xeb435cb8, 0x81dd8272,
- 0x825d8a71, 0x13da5ddf, 0x07d233ff, 0xb416cb0e, 0x70f1ee67, 0xc0d9d63d,
- 0x4f4ad2f5, 0xa346effc, 0xb3a0ddde, 0x535a0559, 0x2fd0ac5c, 0xf5bd08ce,
- 0x3d1ef2cc, 0x25fb27d9, 0x5ff434f6, 0xce89b4d2, 0x7e842bab, 0x90372151,
- 0xb370b09e, 0xbd002f5a, 0xdf2f9545, 0x0837a81e, 0x5d47907f, 0x7277d8ae,
- 0x21fd35ea, 0xd011ed1d, 0x0e90a34b, 0xdcad53a2, 0x93ec266f, 0x28b69925,
- 0x5a75f7a4, 0x4fc504eb, 0xdaaaf080, 0xce297aff, 0xb20ceddb, 0xf4b0bd91,
- 0xf76b824d, 0xe90edc37, 0x8f04668e, 0xdbe1c66e, 0xbbf1c4dd, 0x8db9274a,
- 0x95d01ed8, 0xee4a33fa, 0xba87a8e5, 0x2f89437a, 0xf4805631, 0xb70678b0,
- 0x0be8ed37, 0x850bf485, 0x29f9140e, 0x5bbfba71, 0xf9872edb, 0x54e487f1,
- 0x138e77ae, 0x424b3b71, 0x06bf246c, 0x9d9eb91a, 0x8e19e257, 0xec1030f8,
- 0x9f9f8368, 0x2dd9a07a, 0x52babd61, 0xe45717ee, 0x45ad64f3, 0x7e2bfd87,
- 0x4cfce522, 0xb7895fe9, 0x16ff69bf, 0xebecdfe8, 0x0fdde01f, 0xdb257de1,
- 0x6e39f246, 0x6d2f72b2, 0xb2a3d111, 0x6f808b9e, 0x1f451fe8, 0x739bee0a,
- 0x7e7c81cb, 0xf746ddfe, 0xf943f2cc, 0x5c45f23c, 0x4f107e73, 0xbf72a4c7,
- 0x0e54cacc, 0x2a9166b7, 0x549beb7c, 0xc854d8fb, 0xf23aa7b7, 0x42dca953,
- 0xdae4b9f8, 0xa88c807d, 0xeef83ef6, 0xbdf88fe2, 0x0f402bbb, 0xbe7e7fc8,
- 0xa926b248, 0xe78e22f4, 0xe308bc55, 0x468c4e1f, 0x6decb838, 0xce789169,
- 0xce6be9ce, 0xc9359352, 0xec2e4fdf, 0xc4db0c2f, 0xd1529c73, 0x4a52c4be,
- 0x4b1c15f7, 0xd7e8ad23, 0x487a42af, 0x07fe39b8, 0xdbfc3de2, 0xc956f882,
- 0xde7e360c, 0xa6ddf81e, 0x417b3d45, 0x09c45d00, 0x4875ad3c, 0xfb598e74,
- 0xb9fb96bd, 0xd7e44966, 0x790a107a, 0x57a8b7bc, 0xa3e28632, 0x9d2c841e,
- 0x17f4d503, 0xe9fdafe7, 0xb101ea7c, 0xdc4507fe, 0x279d21c0, 0x8730fd1e,
- 0xcdf9f82a, 0x73a1e60c, 0x8dac59e2, 0x95c113d2, 0xb9d4bd7b, 0xd1da306b,
- 0xe40c3a9f, 0xb55da9ff, 0x6bf90435, 0xc1655b16, 0x93202373, 0xbc8c3fed,
- 0x78119eb1, 0xbdc4a4be, 0x9edcfb2a, 0xf11ab85a, 0x51ec1ce0, 0xdbeb88f4,
- 0x97b27f97, 0x1f3a69e2, 0x43da7d7d, 0x1e9bed0c, 0x5b28778a, 0xee9a3c34,
- 0x5b58b855, 0x7f6fae5a, 0xf654fd95, 0xaaacca0f, 0x0cb5857d, 0x674cf802,
- 0xe95eb93d, 0xc0a9fbe6, 0x33d74e39, 0xf2094115, 0xe050f88b, 0xaf702b3e,
- 0x3dc48b64, 0x674745a0, 0x5787fd40, 0x4fa8ac69, 0x37efb75e, 0x89af1fd9,
- 0x4886f27f, 0x68dea764, 0xfa7d94bf, 0x742fb8b9, 0x3bb78c32, 0xfc9973f9,
- 0xfbdbff7d, 0x63aa4df5, 0x3bc92a7f, 0x1b749f4b, 0xa237a748, 0x034b39cb,
- 0x4e8037e8, 0x0da5d1af, 0x3fdbf3fe, 0xa250d2c7, 0x9d7f6547, 0x517fb056,
- 0xd884b5fe, 0xfdfaecdc, 0xe7163b44, 0xb128d653, 0xa15ba417, 0x7bb276d7,
- 0x700bf703, 0xe0f28ec5, 0x553a00f3, 0x7c46f1f6, 0x277be14b, 0xbb9e5cf4,
- 0xfce9931e, 0x7bc90bf0, 0x2c7c82c8, 0xd7dd38fd, 0xb17fea52, 0x23f06dbc,
- 0x6317cfd0, 0xcf427a78, 0xbc94f9e3, 0xe5fb883d, 0xb83188be, 0x485ffd70,
- 0x9e5163e9, 0xc7fd217f, 0xa51f3cfd, 0x467e62b7, 0xe40b58d4, 0x3f14e84f,
- 0x87c10ade, 0x3c7fdcdd, 0x5471f6e3, 0x32ef624f, 0x2ff5bf7f, 0xcf5bf225,
- 0xf38e9601, 0x5cfb1f8b, 0x9f940241, 0x70e255fa, 0xac5b5f3a, 0x62e50fee,
- 0xb8fff93c, 0xd5f776dd, 0x86515d1e, 0xf26b9c6f, 0x5e65dc6c, 0xf64c9c5e,
- 0xad808941, 0xdb9d3c3d, 0xcf7e6ea9, 0xbd379150, 0xfb375f87, 0x0bcf27fb,
- 0x7cb5ee7f, 0xfe7193fa, 0xb6c0eaf2, 0x9fb05227, 0x0b2bbd12, 0xab9f1bef,
- 0xca1c43fd, 0x8f6d92f5, 0xb99e90a7, 0xda0a5d6d, 0x9f5b250b, 0x3e53b148,
- 0x8af641d8, 0x73bbaf96, 0xaf2f1df7, 0xeb6bd3f7, 0x3f9eb9d3, 0x0f2078cb,
- 0x4309cdf5, 0x3f46ad2f, 0x24aff278, 0xd6f44c8b, 0xe0e51ab6, 0xef8e34ec,
- 0x7c48c6ac, 0xa2fde199, 0xbefed8fe, 0x47c7e43a, 0x15d2bed2, 0x34ecbd43,
- 0x3663c12d, 0x82886f73, 0x64ad6cef, 0xf5fe67a9, 0x6139d307, 0x1f492ad1,
- 0x5be51fdd, 0xe3b470d8, 0x68c2d3b2, 0x0ed7731e, 0xd9f2c56f, 0x04f978cb,
- 0x38f1bb83, 0x9e9cf3f6, 0x804067e2, 0x9bc7f825, 0x3b71a767, 0x8906ce6a,
- 0x9c656bf4, 0x6b2367e4, 0x9d99d7fd, 0x39f3e426, 0xe521f137, 0x65a4db1e,
- 0x868ddec7, 0x1d6a0f7e, 0xf7c1a677, 0x499ccfa3, 0x2e333e42, 0xda067cfc,
- 0xc77ac919, 0xeeb8a50b, 0xcb8a06ad, 0x958aceca, 0x88fea0a3, 0x8d3cc747,
- 0x45659ce9, 0x3fa2942f, 0x3871b375, 0xf3e56f0f, 0x35592c5b, 0x53be3f68,
- 0x845cd0fb, 0x8c67b9db, 0xae2f1fa4, 0x3f628d4d, 0x02bfef62, 0x614d6ffb,
- 0xfbd8076c, 0x7b02ee98, 0xed4bef1f, 0xfca68eae, 0x94adab1f, 0xbf1ce9b2,
- 0x1f385b16, 0x237f51b9, 0x02b78ec1, 0x0b5ec91f, 0x78fe81fd, 0x107f6f46,
- 0xa43c99d7, 0xb13aeb62, 0x3f6864ae, 0x0f7f15dc, 0xdd7b21c2, 0x5aa8ad23,
- 0xe7e3498e, 0x5f1c1f7a, 0xf1fa471b, 0x4a978eb2, 0xb486fbe1, 0xded8d9c2,
- 0xd932e5b8, 0x3f34efef, 0x5de11b3e, 0xd7c0d5b2, 0xee7dd627, 0x17a89499,
- 0xfbd77fa0, 0xaba7b23a, 0xb4bc74b6, 0x1b79d20e, 0xe3fbd11e, 0x77aeadfb,
- 0xcdcf9896, 0x7046eae8, 0xd5d39ff8, 0x3f447113, 0x32ae815b, 0xaaba75fe,
- 0xe09cb65a, 0xe15a5af7, 0x9fc834ea, 0x90e2b9d3, 0xffa5ce9e, 0xb5dcf084,
- 0x2bf8225f, 0xbf6955fc, 0x9bdb8d32, 0x06cf1ae5, 0x7f04efd2, 0x3a2c16fd,
- 0xe681ef84, 0xdfa829b3, 0xe334db7e, 0xafbdd747, 0xd233bf9a, 0x7ff5f004,
- 0x734942c7, 0x1b448ef5, 0xc4572fac, 0xdf7e07dd, 0xce51a69d, 0xe05e48f1,
- 0xae2fc93f, 0xd62602a2, 0x92e51c2f, 0x7b420de4, 0xf3dee9aa, 0x379450da,
- 0xad52fb12, 0xfd2fb21f, 0xe68dede4, 0x12b4b37b, 0xf8fad1fb, 0x3527edee,
- 0xee43f7aa, 0xbd520f68, 0x8ecd71c7, 0x9d3d3280, 0x2ad4c4a3, 0xbf18f6f1,
- 0x4e9cd5d3, 0xc5e7fdf1, 0x7daea27d, 0x3f712f60, 0xdefd9309, 0xdcdf3835,
- 0x367c8599, 0x6f95bd70, 0x387e1276, 0x4cbf1e9b, 0xf8d364f6, 0x9bacdaf3,
- 0xb6c0ffaf, 0xe2677a4e, 0x173daebc, 0x7d2ea2ed, 0x43ee167b, 0x9f9c5be5,
- 0xa0e14fff, 0xd5ae9794, 0x649dbf73, 0x4f2efb21, 0x79f648be, 0x9f6e61d7,
- 0x4cbf3657, 0x85b7b4fc, 0x34aa47fb, 0xe851f96d, 0xd1d4584f, 0x37acfc8a,
- 0x954bdb9a, 0xe8ff9ee2, 0xb5072144, 0xff78713d, 0x9f3892e0, 0x7c34ec55,
- 0xb5e90037, 0x5271e34a, 0x305650dc, 0x0b8f73c3, 0x3e50cf48, 0x1afc697b,
- 0xee73f3c4, 0x3f902301, 0x8ff5907e, 0xfda7f24a, 0x9322d829, 0xe2ab297e,
- 0xc3adaf9a, 0x14c0f32d, 0xc1abe8a6, 0x2adef8aa, 0x6467f5bd, 0xe7e11eef,
- 0x3843555e, 0x3937b13d, 0x3aac553d, 0xebf68fa0, 0x9e82afef, 0xc26f3d14,
- 0x7441fe9f, 0xfb64cff9, 0xa33f217f, 0x5fd86ffb, 0x24b73f74, 0xbeb97a89,
- 0x8b733e73, 0x640bafb0, 0x24d55efa, 0x62ef3c33, 0x1e7421d1, 0x5236c05f,
- 0xe604e09c, 0xb17a4d19, 0x7c29fdb6, 0x9fe26587, 0x371891e4, 0x9d2e7a05,
- 0x3907e71b, 0xe8ae3092, 0x70124684, 0xf64f64f5, 0xe9396793, 0x968d4e5c,
- 0x3d639225, 0xa7a4c131, 0x315e9f8c, 0xfa7f5fcb, 0x4fedc487, 0x26f487e8,
- 0xf7e1eee6, 0x593dbc40, 0x4c64effe, 0x22f053fb, 0x93cc8b92, 0x9c6fcd3d,
- 0xa71e74fc, 0x9dcf0571, 0x89549f81, 0xf93ccdf3, 0x0ed167fb, 0x9f9fbc5a,
- 0xc4d09deb, 0xc9714a7f, 0xc258af78, 0x1efcbbfb, 0xbb307337, 0x7327e91d,
- 0xa95fdd00, 0x8c312dda, 0x366cab2f, 0x4d7f456c, 0x123daea5, 0xd35d79f1,
- 0xe7c47a27, 0xccef3c2a, 0xb97ff7e4, 0xf742daff, 0x8c2cabb9, 0x534557e4,
- 0x47e8a7ea, 0xa5cc38ab, 0x18f68568, 0xb7c8e9d9, 0xc6f2bc71, 0x3b97643d,
- 0x72ec9799, 0x6f1a8367, 0xf6fba37a, 0x5ba7e7a3, 0x8c62ef55, 0x63e9ccdf,
- 0x9ac3c61a, 0x43f939a9, 0xd54747c7, 0xc9bbdffa, 0xb5f0e74f, 0x51ab9dcb,
- 0x904ee98f, 0x4a8ef86c, 0x156b9077, 0x14ae47ea, 0xbf74d7ae, 0x017b2bbd,
- 0xf67717f1, 0x077c4cd4, 0xe3b1eb86, 0xcad26ed7, 0xdf19f37e, 0xdd7ffdc2,
- 0x1f64ac41, 0x1063bbed, 0x29fdc7ee, 0x39e90585, 0xd1cc7ef4, 0x234fd0bb,
- 0xae04e9ee, 0x9f0a68e3, 0xdff411cf, 0x3de6f864, 0xf3963631, 0x3c26e633,
- 0x62f7156a, 0xa516f894, 0x578116fd, 0x8917ecd7, 0xc46e9dfb, 0x04bcf05f,
- 0xbcf132e3, 0x229dd304, 0x4bcf137e, 0x88aaff30, 0x12f3c4df, 0x12f3c72c,
- 0xf88a37cc, 0xc12f3c4d, 0x60979e3c, 0xdf88a6fa, 0xa553823c, 0x1ae6b3b8,
- 0xa4568bc4, 0xfcbe81b5, 0xfc80f089, 0x13fd7540, 0x3f3a92e1, 0x8bfaa250,
- 0x5c6b9bd2, 0xb4a7e819, 0xfdc57908, 0x1d83eb94, 0x2af840bf, 0x15cf0ef7,
- 0xe90fbd3c, 0x8cf85c68, 0xbd5f4859, 0xf90c0dfd, 0xc774aed0, 0xf877ac32,
- 0x9b493df0, 0xe89a3f88, 0xc3c4f8fc, 0x05f75543, 0x5c8da4c7, 0x31f90d95,
- 0x6bdc4966, 0x50ac38de, 0x5cf0fbb1, 0x5b28a5bc, 0x0582f9cb, 0xd93ce4f5,
- 0x2ce38c59, 0x448d318e, 0xd53c3bfe, 0x1fba78f1, 0xb81fcebf, 0xa1f50930,
- 0x53f59d56, 0x3eba97f4, 0x9bb431d2, 0x529abf14, 0xe63a90cf, 0x3e376c19,
- 0x08d5712d, 0x0c881fec, 0xcf5d9cf9, 0x767e701a, 0xdfc4b04d, 0x916ab08d,
- 0xf6233c0f, 0xeb95ac7b, 0x55bd5ec5, 0x76768e1b, 0x78fe98d0, 0xf62ada7e,
- 0xdfd8b0f7, 0xf17f6223, 0x969c69bc, 0x8a61379f, 0x2a984de7, 0xd2c75a71,
- 0x274a5f0a, 0x21c4f6f8, 0xddbf157c, 0x1a3ee504, 0x9ea1c4f3, 0xd7c099f0,
- 0x919f0407, 0x79eb0ad2, 0x2fdd0f3b, 0xb4fe172c, 0xa0be714e, 0xe76953ac,
- 0x9dc7cf6b, 0x67f38c32, 0x13dc4fd6, 0x185cc41b, 0x8de53af7, 0x7507f218,
- 0xce3df9b9, 0xc8db4029, 0xfc1bd8bf, 0x73459dfc, 0x7af2993a, 0x295bd514,
- 0xe1159afc, 0x0718296d, 0x49e825df, 0x76f72bc9, 0xde40462b, 0xafab8bec,
- 0x8296d298, 0x925df571, 0x54788349, 0x3f7f95b1, 0x22ade82e, 0xbca7f441,
- 0xc4f46087, 0xef743ee1, 0xef0e237f, 0x7b37ad89, 0xef7e7017, 0x98f2f7e5,
- 0x84e30537, 0x29cf253a, 0xdfad878c, 0x8c41f939, 0x79d4ed87, 0x8efcc25e,
- 0xc41f539d, 0x694ed878, 0xff8b29cf, 0x389e01f7, 0xdfad978c, 0xf7e44539,
- 0xf36614bc, 0x3b5eebcb, 0x2bf5df85, 0xf1883ea6, 0xee0d13b3, 0x2f88d5c3,
- 0x6578e47f, 0x0cf7bdda, 0x99bca7c2, 0x7763ebeb, 0x1af8bdef, 0x21bde3ca,
- 0x55ff6e74, 0x7bc13c7a, 0x1b2bf365, 0xf6bacf10, 0xd60e88e8, 0xd2f27c37,
- 0x819ea9af, 0x689b2b9e, 0x6ba364f0, 0x979dd5e4, 0x2771c01f, 0xc1be7b06,
- 0xcc869ffc, 0x8c4c79a6, 0xeefc74e0, 0x3107a290, 0xef6bbd9e, 0xee90c7ee,
- 0xfc63f626, 0x132ef5de, 0xebd94fed, 0xaed0e3e9, 0x9b690aef, 0xee57fd8d,
- 0xfdf3f034, 0xbde8a3d7, 0xee749e88, 0xb21d2e6f, 0xabe50e31, 0xdb1dcde6,
- 0xc67e8d7e, 0x6f3a269d, 0xfae70aa9, 0x9b5c995d, 0xdfed08fb, 0x80fedbcb,
- 0xa261def3, 0xf452cff3, 0x74be40ad, 0x17bf325b, 0x66afcffe, 0xc9e43ee3,
- 0xca7ee85b, 0x0d267537, 0xdeb8e1c2, 0x83ef0fde, 0xc8eb8eb8, 0xf9152cce,
- 0x7c1113d2, 0xf9edc13e, 0x37fd7fb4, 0x2d7ca1c6, 0xfde5f88b, 0xf289ef38,
- 0xced097c6, 0xf7f0af61, 0x00efcecd, 0xf3bb41b8, 0x0e8a3af5, 0x4211daed,
- 0xa53bb6f7, 0xddf1b38d, 0xaf3d570c, 0x48da69d7, 0xa7d574f0, 0x76bdf7f2,
- 0xb0c3a740, 0xf95526de, 0xb257faf9, 0xb0bd0ed0, 0xa3d92273, 0xf42b9e0a,
- 0x78175652, 0xafdf8c2f, 0x337f132c, 0xfd998b8b, 0xf6174afc, 0x02f5df3d,
- 0xd0bfb5f3, 0xc8fba3a0, 0x0ab606a5, 0x7a1571e3, 0xb7bd8b28, 0xa657d700,
- 0x7d414da9, 0xfb6474a5, 0xf38ba46c, 0x868c6626, 0x39081f7a, 0x7cb8d655,
- 0x37bdea32, 0x431dcf9a, 0x56fa1f38, 0x4db7e1d0, 0x79ffb726, 0xb7fa605f,
- 0x50fd666a, 0x7cffcbeb, 0xdc9efa91, 0x138f7a07, 0x70cab3ed, 0x414e3fce,
- 0x5fe006fd, 0xfce10fb7, 0x7552ce62, 0x3c218cfd, 0xdf52b10e, 0x4ef2829e,
- 0x887d3fe9, 0xda83eb85, 0x2a277a76, 0x5944ddb0, 0xfc5d9bf0, 0xa35969de,
- 0x1df741d4, 0x3e91a410, 0x5d199678, 0xe9d38c6e, 0x73a21f6b, 0xbde03ec5,
- 0x34f12182, 0x8983595e, 0x07972dee, 0x7ea287b5, 0x0f690ce4, 0xeba7bd45,
- 0x8bde994d, 0xafebedc4, 0x1be09ff4, 0x9617f14f, 0x5376747a, 0x72c1e35f,
- 0x885e2ed0, 0x3e28037f, 0xeb40921b, 0xe60a692e, 0xed2da4f7, 0xf0386f74,
- 0xd3ae211e, 0x5d8f47e2, 0xfa472f4d, 0x87b3e7db, 0x57ff0bc4, 0xf74dd107,
- 0x438cbf3f, 0xb0d3283c, 0x785e7855, 0x15f7e241, 0x15f74f20, 0xc773882e,
- 0x41ccefb2, 0xbe173f88, 0x771d1275, 0xe7c4ed49, 0x88aabbcc, 0xdae9743f,
- 0x4349cf89, 0xae7c417f, 0x367dac2b, 0xd0f32df2, 0x4c7bfc35, 0x4fbc6cfb,
- 0xc8886173, 0xf724660f, 0x40daee07, 0xcca264fc, 0xcbd818e3, 0x0bf70b3a,
- 0x142f7871, 0xed6c6270, 0x3bb26a89, 0x8fd45674, 0x424a8762, 0xd6fbd7ff,
- 0xa9e8fb2f, 0x3777598b, 0xf0967d22, 0x9f406277, 0xf50d786a, 0xf49119be,
- 0xdc204dce, 0xfebe7394, 0x805f7fe1, 0x710a64fb, 0xe7821cac, 0x64ed19d5,
- 0x93b60057, 0xb6f95efe, 0x6ecbec81, 0xe436cf5d, 0xc7661d5f, 0xa9cf58e3,
- 0x2d935b6f, 0xf6fa7de1, 0x9bdf3c56, 0x7be3dca0, 0x575be385, 0x9efccbc6,
- 0x7c273882, 0xbe03ec4e, 0xf88b5881, 0x7e7df121, 0x0ff5e9a7, 0xb574df91,
- 0x0e9f1225, 0x4df3a7a4, 0x0a7bd34f, 0xbbae4127, 0x93ffecfc, 0x79d0af45,
- 0xc38c74fc, 0x3f7f5f30, 0xa9fbf7b5, 0x0db20764, 0x8f88e57e, 0x207cea35,
- 0xbd2f105c, 0x11703a2a, 0x5ba78fdc, 0x63a3bbf8, 0x821de8db, 0x9029f96b,
- 0x07f2fd97, 0xf501f203, 0xea3b5ef1, 0x2f51c70f, 0xf60e3840, 0x7dbb209e,
- 0x5d938f37, 0xf28d7209, 0x9ce9837b, 0xe41bb358, 0xb72e7f56, 0x87945e50,
- 0xaabf91b6, 0xce81af6b, 0x9f345637, 0x03f5c38d, 0xa65f923e, 0x488df9bc,
- 0x12bfe7b4, 0xc7c80376, 0xd94b8a48, 0xf6891cdb, 0xd4ee5287, 0x7c445278,
- 0x0ff2167c, 0xf642bca5, 0x553dd0a6, 0x39de8da9, 0x4de70af8, 0x632f21f5,
- 0x9c3ad19e, 0xd67ba712, 0x0a6bdfcc, 0x8213b7dc, 0xa07f019f, 0xbc572777,
- 0x0a05fdc9, 0x7c15283f, 0x679620e5, 0x28b7fa70, 0xde7843e7, 0x07df7483,
- 0xe140789f, 0xf9116c7b, 0xb10f8e73, 0xf68ab872, 0x37f72fd4, 0xb7b8b8f1,
- 0x3212b33a, 0xdaf59db0, 0xfc6b8f7d, 0x5fc7d128, 0x13440f90, 0x8ba1581f,
- 0xbd957584, 0x3abbd124, 0xe796b3a5, 0x50b67543, 0xe7bd08fb, 0xae718259,
- 0x15e7ebe6, 0x43154788, 0x34ca9c38, 0xdb2eeedc, 0xcf39d126, 0x3f3f1d05,
- 0x71437e03, 0x2dc70bf4, 0x9bfa47cf, 0xef42bfdf, 0xacdf1f6f, 0x5beeebff,
- 0x1f9e5a2f, 0x979d07d5, 0x3ad4dd2d, 0x5fdf5d80, 0x3f36a3a9, 0xb97d7ad2,
- 0x260bef32, 0x75639e65, 0x31e1fc03, 0xbe3e797d, 0xf8d0b8fb, 0xaf83c2af,
- 0xc1b342fb, 0xe017728b, 0x77b5e74b, 0xf2a45d5f, 0xbfacdeab, 0x73a6e652,
- 0x3fcd1b8f, 0xde4a7530, 0x0ad71413, 0x744f55f4, 0x37e37406, 0x024363de,
- 0x452511fc, 0x157bd1b7, 0xfcdba28e, 0x298111fd, 0x1a81ca30, 0x5170d98a,
- 0xdb38740a, 0x943c07d6, 0xb94389fa, 0x8131f55f, 0x962703c7, 0x231aff3f,
- 0xe86d8e3f, 0xc7df1b80, 0xfff043b8, 0x718fbe5b, 0xb7af304f, 0x574164df,
- 0xbffef74b, 0x7bb83f93, 0x3f3a79b5, 0x18b33067, 0x9d1adef8, 0xefdfd5b9,
- 0xb7b889fb, 0xe996f780, 0xee9a79fe, 0x1949fdc7, 0x49fcd721, 0x04646fa4,
- 0x574af9d3, 0x6f9215d3, 0x16392ddd, 0x6ae9073c, 0xde919b73, 0x5ff9feaa,
- 0xbb872891, 0xb8a6be5a, 0xcfefaeb0, 0x3ad8bc52, 0xb077b711, 0xb55bc449,
- 0xbcb04359, 0x7cabe0bb, 0xa45eb7ac, 0xf7027f3e, 0xe2a92ba7, 0x9f7bf02f,
- 0x1cd0d667, 0xdd6b3f7c, 0x3e30d953, 0x45cc6e33, 0x7376007e, 0x9f0dca38,
- 0xf51ac11f, 0xe88bf163, 0x72d24847, 0xe8a6023f, 0xe24a4847, 0xa3cc047e,
- 0xf453011f, 0xfa396023, 0x7e8f3011, 0x1fa3cc04, 0x47e8f301, 0x08fd14c0,
- 0xb88dfe58, 0x8c0dd12f, 0xcd39fb8b, 0x6097f7c4, 0x6fc030fc, 0x78bf7889,
- 0x777f3d49, 0xa04bef07, 0x7e2ebbfc, 0xcfc451a6, 0xf9d13678, 0xd95ed55f,
- 0xf7845b86, 0x18295c2a, 0x0873d347, 0x7b553ffd, 0x2b72db24, 0x79a74f96,
- 0xf9c96bac, 0xd7961674, 0x5ef86ceb, 0xdf13e016, 0xe2895acf, 0xea5aca98,
- 0x2e355fc9, 0xcdc53f6a, 0x0c483557, 0x0cd3acfd, 0x90ae4edc, 0x9d0474a1,
- 0x5d1e9297, 0xfb236861, 0x64bb7ca5, 0x5c9fbff5, 0xf132ea35, 0x78dce509,
- 0x2ac4ff01, 0xb16b263c, 0x79dace4a, 0x69fe13fc, 0x9137c5f5, 0x17a7e21e,
- 0x64f3c02d, 0xa7bf972c, 0x60151b7b, 0x374846e0, 0x6b2a7f8f, 0xe306b3d9,
- 0x0e356ea6, 0xe2a1e5ea, 0xbf3878fc, 0x4cf0518f, 0x30bdeef1, 0x0346ef5e,
- 0xd2bb29e9, 0xbf113b1d, 0xe4ece90e, 0xdfb4396f, 0xe9d67644, 0x7f2aa94d,
- 0x883c9e4b, 0x758b1dfc, 0xe1efc912, 0xb60f0ea9, 0x1e60a7bb, 0x89ee59f9,
- 0x563a210e, 0x5a90d0f0, 0x81f21af8, 0xf25699c5, 0xd819e56f, 0x113fa82f,
- 0x53eca557, 0xde894ade, 0x36622e4d, 0xc7305fba, 0x5389dfce, 0xc39b75de,
- 0x82839c78, 0x49378b57, 0x364eddfc, 0x5b3ce088, 0xcb4e73c0, 0xc74ef47b,
- 0x5778833c, 0xbfcfc34e, 0x78f3d763, 0xc2f8f986, 0x8177be11, 0x7c9327d8,
- 0xca1dbb7d, 0xe283c11d, 0x8d6f7eb8, 0x8e8bfec2, 0x373e28e8, 0x14beea2f,
- 0x71f9c907, 0x7920c714, 0x0c3fca67, 0xa9fe31fd, 0xa438638e, 0xeb841c2b,
- 0x253c456e, 0xd2838eff, 0x9425d523, 0x251c7e2a, 0xff7bb06e, 0xfc707b1b,
- 0x6efe2abc, 0xc5ef0dec, 0x3f7df505, 0xf027b94c, 0x0e29c619, 0x1f1ff5c0,
- 0xc4dbef89, 0xe1b6677e, 0xf6a2f3fa, 0x44aabdd3, 0x933fffd1, 0xfee0cf0b,
- 0x0b9943d8, 0xcc39e1db, 0x3e678046, 0x3f42402e, 0xf78ec7b9, 0x4bf67a53,
- 0xbe5f8a16, 0x5a6e6f8e, 0x5521f18d, 0x6bbd1249, 0x31b41f9d, 0xcffa122f,
- 0x21b7884f, 0xe26aaedf, 0x482ed67e, 0xe5dfbef9, 0x18aaf7a6, 0x826a3f7f,
- 0x53fbb7d8, 0x3a1f7f1c, 0x513e57c0, 0xcb7755d0, 0x7bb71e15, 0x1d6c3f73,
- 0xf8c73fbd, 0x0ff41f7b, 0xe87135e6, 0x2ac7f260, 0x10dbd378, 0x26f115b5,
- 0x9bb78324, 0x0e98eb35, 0xcd2906f5, 0xfc80cc61, 0xabcbe2ec, 0x7d9d6923,
- 0xf894c5fb, 0x98bf40f6, 0xbffd7f3f, 0xb0ff6b88, 0x47a5117a, 0xda5297ab,
- 0xefa2ed56, 0xcb6e1720, 0x6a7f35b8, 0xfe1f464a, 0xf6b46654, 0xf40ab923,
- 0x01d6fdcd, 0x6ba053fe, 0xdf5d1f8d, 0x773612d3, 0x351dea2d, 0x128f7a7a,
- 0x98978ce3, 0x32d80f89, 0x2aa3f4fa, 0xdf933370, 0x469997b5, 0xa6c7fc20,
- 0xf0356a25, 0x490ccefd, 0x74865e75, 0x3a43eb82, 0x44e914c1, 0x7cefe7eb,
- 0x9c240f51, 0x1700f5cd, 0xda2601e9, 0x81cb35d7, 0xeef8487f, 0x3fc5458f,
- 0x0ff0062e, 0xa61e5830, 0x062d55fb, 0x8946877a, 0xc90b1cb7, 0xf07d11d5,
- 0x27e70f13, 0x3b3c8383, 0x657fbee8, 0x1ef3c510, 0x3afc71d2, 0xc9c78eb4,
- 0xfe42b315, 0x7cf5d0de, 0xcccbee85, 0xf539e88b, 0xef3fa807, 0x33e93309,
- 0xe416626b, 0x257c3bfe, 0xe0106507, 0x4b2c6b9d, 0x9be0b8c3, 0x03bbcaa5,
- 0xd021ded7, 0x271cf78b, 0xaa6a77f0, 0x5953fe84, 0x54fa216c, 0x6a5661ee,
- 0xb06b1d3d, 0x1e10ff5e, 0xf465a1ef, 0xcd71c8ce, 0xa9eefe40, 0x13e3b3a0,
- 0x1b9fc912, 0xc5e3d2b9, 0x93ee7b7e, 0x71da7de8, 0x831dfcc1, 0xf3a14d3c,
- 0xaefef815, 0x7d47df86, 0x9029df11, 0x5fb95f71, 0x93ef77c4, 0x05b169eb,
- 0x7fb95b21, 0xb3fbbf98, 0x00fe1252, 0xb74b6ef1, 0x1fdde03b, 0x374aeef1,
- 0x08f59c2b, 0xcae981f2, 0x27d68ffb, 0xa6a07cf1, 0xf7788874, 0xcf7fe387,
- 0xf90da364, 0x3e70cd59, 0x04d29aff, 0xac948fee, 0xb98e51cb, 0x1c68c37e,
- 0x833fbbdf, 0x1fb2bbe9, 0xa72e3bca, 0x43bf1c43, 0x9ef811be, 0xe152b3cb,
- 0x4fd8f98c, 0x27af9f26, 0x43e3f399, 0xb93c8633, 0xc838e10d, 0xf87a839a,
- 0xb96151dc, 0xac47e012, 0x800cb996, 0xa69be87f, 0x69d66e77, 0xbc602bdd,
- 0x2f715a41, 0x3df82b5f, 0x82341974, 0x90f5dbea, 0x217a7a2f, 0x8abca3b3,
- 0x6c5ef465, 0x879f9192, 0x29863b43, 0x946469ba, 0x85fb8c83, 0xfef1fa8a,
- 0x7b98a28b, 0xd9fd4485, 0x673c4a35, 0x020efe2e, 0xb6173f23, 0xed411d0f,
- 0xdede1a5d, 0xb6f485ae, 0x51defe44, 0x9d036acf, 0x3e3d1683, 0xa4e3e498,
- 0xedfbeab1, 0x38f067df, 0x985d2505, 0xf9d15569, 0x74e955dc, 0xd577389e,
- 0x43d40a8c, 0x74c10d1c, 0x81f3af1f, 0x9df0bb97, 0xbdd972f1, 0x6bb413e0,
- 0x216f1d32, 0x5920b95f, 0x0a85ef67, 0x477c1f73, 0x0e31718f, 0x6f4be4cf,
- 0xed70dca2, 0xbaef8a39, 0x4c80ffdd, 0xfc67efed, 0x8ab6647d, 0x9f7903bf,
- 0x1a36b2eb, 0xb46fbffa, 0x0ef27e44, 0xf50e2593, 0x5fb122ba, 0x14ff82ad,
- 0x829c19ad, 0x787df576, 0x9c87dece, 0x3d793291, 0xf76dfbe5, 0x635d9530,
- 0x990ddf10, 0x25b7bd7c, 0x6bc5eff2, 0xa1891d0d, 0xa9bcea98, 0x8d86da90,
- 0x65f118fd, 0xdfcb0252, 0x25fc708c, 0x987633f7, 0x97ce9798, 0xae0933eb,
- 0xf1d3d60e, 0x6ea3ae38, 0x63a3ad28, 0xde8e258c, 0x8aef10bf, 0xfe70b7ce,
- 0x8f8631d4, 0x1ed2ca73, 0xe9c19e12, 0x9d17df07, 0xebf4b627, 0xba9f2ba5,
- 0x5bcdea1d, 0x927ba466, 0x4a999ff3, 0x1abcca76, 0xb247ee99, 0x45f7ea0d,
- 0xe2749e41, 0x0bdf02fc, 0x14177c0d, 0xa0f11cf7, 0x78448378, 0x9b4adb74,
- 0x7bdfcf1e, 0x009e8136, 0xdecd8bdf, 0x8a0bd424, 0x0adb266d, 0x43778fa9,
- 0xe5b807bf, 0x8ccbbbe2, 0x592126fc, 0x6e38ab8e, 0x7a22c6d1, 0xc33833a7,
- 0xdbb0fe41, 0xfd441ec0, 0x4e4c8ee7, 0xbc00933f, 0xb683cef4, 0x9fed063d,
- 0xaf1c193d, 0x525b8526, 0x269784cc, 0x3bbbf786, 0x9c149674, 0x936ac75f,
- 0x499ef506, 0x027e382b, 0x23b518dd, 0x059fbe30, 0x111efd21, 0xd72d67ed,
- 0x7e42d616, 0x90ed8810, 0xe19bc470, 0x0e8f9f84, 0xf119fc73, 0xd86fdcef,
- 0xf39fe428, 0xf3e26c36, 0xb4cffb12, 0x9ef0e36d, 0xf8fab9e5, 0xa0571811,
- 0xc3a3c3e0, 0xfd325ac6, 0x8901e0f1, 0x73d61ff6, 0x6d8de518, 0xccc8dcd8,
- 0x007e5401, 0x58d263f1, 0xe421c52f, 0xe7864ec9, 0x8cd1bdf8, 0x197be9e2,
- 0xb5ded7a7, 0x0a6fe25a, 0x01f8509f, 0xef1d83e0, 0xadfb2ac7, 0x2bff85f0,
- 0x43e0043d, 0x1be1457c, 0xf0517f0a, 0x8133e14b, 0xc01b3578, 0x6a08f77c,
- 0xe14cfc4f, 0xcd0eb863, 0x517f1f08, 0x76b759f6, 0xadfc868c, 0xe4f39f62,
- 0x40dfbb8b, 0x49989438, 0x1706b96f, 0x12e091b3, 0xf84d67a7, 0x47caea3e,
- 0x402cf70a, 0x416dfc7c, 0x331fea3c, 0x18f7d44b, 0x7d48be7f, 0x52ce717f,
- 0x59c5fdf5, 0x843e3f4b, 0x5086a77e, 0xbfdc04c7, 0xf33dbf53, 0xfe50a7e2,
- 0x90bdbf9f, 0x8becedcc, 0xb8e1cff5, 0x3cc482cb, 0x96bcf9da, 0xdcbe49e9,
- 0xfc30f426, 0x9732fb87, 0x8a2d3a71, 0xf28a3b0f, 0x29c22e6f, 0x611fdf0b,
- 0x89bfcf04, 0xf62539fd, 0xf73568a7, 0x24b8743b, 0x5dcc43f2, 0xad74e825,
- 0x97f25efa, 0x383dac31, 0xf97f77d1, 0xc4a4dfcb, 0xf72b5d21, 0xf96b1d95,
- 0xe969667d, 0x1c5fd261, 0xae50fbca, 0x96a1f780, 0xcf7bf2b6, 0xc4fbeaed,
- 0x3d76d9c1, 0xb71829f9, 0x1da6e6a3, 0x1b35f1e4, 0xb28a0b25, 0xbc5e5162,
- 0x57dd5256, 0xdf93247b, 0xd0cc6b17, 0xfa0bbf72, 0x1f38949c, 0x7c04be3f,
- 0x15cfee83, 0x5fae1c6f, 0xe747c7e0, 0x6979f28a, 0xf2954a1a, 0x571e0cc6,
- 0x03448c1a, 0x4b4faefd, 0x7e27cfd0, 0xa8bf2567, 0xda6e7f52, 0x37e83588,
- 0x7f01bb98, 0xfed7c79d, 0x6a5a9937, 0x26f428df, 0xfcf80de7, 0xfc2a38b5,
- 0x379a0ef3, 0xaf65d3d9, 0xdf157aee, 0xdcfb2fbd, 0x6ca67240, 0xcf5f3898,
- 0xa54ee770, 0x9f7e63f3, 0xf7ec52aa, 0x845f5db8, 0xd5509da2, 0x8671dfc8,
- 0xcad303b4, 0xef642565, 0x1e80da57, 0xf78fafc2, 0xcfd5f77e, 0xd95fb943,
- 0x9f41ab15, 0xa59df888, 0xc8afc6ca, 0xdefca0ef, 0x2abb6052, 0x6e50fbe9,
- 0xff985abf, 0xede411ef, 0x549d11d7, 0xb97b7335, 0xf215ef6a, 0x5fed579b,
- 0x63e8e91d, 0x13dfd7fd, 0xe8e2abb1, 0xcb86d8ab, 0x06fe0f74, 0x4c9eeaf1,
- 0xedc3eef1, 0x538a76ec, 0x2b8a32d7, 0x2ebbf6ba, 0x8d1fe4ee, 0xacdaac8f,
- 0x5ea078a1, 0x9e1fb5ad, 0xfb8b75c7, 0xbef58151, 0xd776e4cd, 0x7c23a025,
- 0x41bba377, 0xee9df3a6, 0xabbfee06, 0x15ba786c, 0x8256a5ef, 0x5ec30ce1,
- 0xd9543fbb, 0x7fa33328, 0x1fc61adc, 0x9e78dc45, 0xe842bbe5, 0x8f52981d,
- 0xf987af64, 0x34bd82f4, 0xc73e6fc0, 0x1b955e05, 0x2fb4b93c, 0x0387fe62,
- 0x96d29df4, 0x2b9ee9a7, 0xfd22ebd4, 0x8cc18fe4, 0x1cf5939f, 0x6e7679c5,
- 0x5ae74919, 0x953d9ea5, 0x086c77e4, 0x0b9578a6, 0xe9bdf53a, 0x53bc6253,
- 0xafee3c99, 0xb124e313, 0xe932abfd, 0xa44f38a7, 0x3a920bc7, 0x68b4e38e,
- 0x6dc05a77, 0xa54ba09d, 0x23a7a97e, 0x9fea0934, 0xd298fa6d, 0xd4bf512e,
- 0x728596dc, 0x30636cf3, 0xdb3d63dd, 0xb7fc87f8, 0x9e4bbc60, 0x3f25fd31,
- 0x74b292fa, 0x88b63f7c, 0x08eeb8fb, 0x43c4cf71, 0x886ce9eb, 0xacbed095,
- 0x9d5ef110, 0x6a87af8d, 0xff5d7e88, 0x4d5defde, 0xb15deebf, 0xfea046ef,
- 0xbd576c62, 0xd5bff62b, 0xff28a57f, 0xe3142a44, 0xb9c5e8f4, 0x101dff30,
- 0xe13ba08b, 0xcc3d9d8f, 0x7fde10fa, 0xdff01f65, 0xffbd030d, 0x668fb439,
- 0xec8239ff, 0x0ffdfc4f, 0x21f37fcc, 0x3d9b2f3f, 0xe895f052, 0xd7f41cf6,
- 0xfd73c477, 0x2816b9c1, 0x0e5a4011, 0xf802e5f8, 0xe61add39, 0x2cd0fc80,
- 0x02753f6e, 0xe187ebfe, 0xe58e3cc8, 0xf877d814, 0x35eb8c9e, 0x4cec8e7e,
- 0xbde0a6f0, 0x4f114ebe, 0xa6f70ce0, 0x17bf4044, 0xa7389e05, 0xdffc5378,
- 0xf56e74a9, 0x45cd3c52, 0xdf873f11, 0x1ce79fd1, 0xc475ebc1, 0xdee8ba5b,
- 0x8610dec6, 0x8de6aafa, 0x8ac3c210, 0x0d5b4c57, 0xa8d2767e, 0x5f0fae2c,
- 0xad77f3d4, 0x7cf8db5d, 0x5237434a, 0x7e05173f, 0xa46d0697, 0xf7129df9,
- 0x3cf54b83, 0xf463a1df, 0x0ecf7c9e, 0x85cf6efe, 0x387db698, 0xe91d85ce,
- 0x11da6714, 0x44d05eef, 0x497c79df, 0x17834ed9, 0x477e75e7, 0x2a03dd08,
- 0x3a66edf8, 0x33adec5f, 0xceffc848, 0xcf74600f, 0x00fd7ce1, 0x25e7d792,
- 0xcf37f92b, 0xfd411fbf, 0xa52f5595, 0xc0652cfb, 0x84ef5026, 0xb5f500b4,
- 0xc7cff5f3, 0x7e42fd21, 0x6c1de62d, 0x215fece3, 0x260f6e9d, 0xcec2f33b,
- 0x9ffba47f, 0xe06928f7, 0x9fb289b9, 0x59e9f7ca, 0x2e986edc, 0xcb2b34e0,
- 0x832dcfc2, 0xd026cf3d, 0x037d38fa, 0x002ec99c, 0x7177a27a, 0x239a794e,
- 0xeca7e825, 0xca3b108d, 0x379d0ef7, 0x87040fe5, 0x30bbf160, 0xf3c2ec8c,
- 0x2ec822db, 0xfa9a2d07, 0x932dbf39, 0x389543e2, 0xaba84993, 0x12663ed1,
- 0x2de4f37c, 0x706ef459, 0xe1c5305d, 0xbb7e3d94, 0x644ee286, 0xbd9777ae,
- 0xc8926f3a, 0xa69cf1db, 0x56bf57ec, 0x49fe45e0, 0x29d48e25, 0xe3c568f8,
- 0xb8c3f577, 0x9967f65b, 0x68aee3e2, 0x20639c79, 0x0964765c, 0x45efba3e,
- 0xe0275ba2, 0x502efe39, 0x2f0388b9, 0x2cfdc9df, 0x7aee6be5, 0x51e3f88e,
- 0xdf38c31d, 0x43a79e8b, 0xb4fee1fd, 0xded7c7e8, 0xa1cbf546, 0x41ff6f3e,
- 0x9b67cd28, 0x0392e28e, 0xdb96ebf7, 0xa5ff94ef, 0xd01e65f6, 0x0738fa03,
- 0x1edac2be, 0x40f91cfb, 0xa2e6c983, 0xd7b71e52, 0xe02cf3a9, 0xc44c19f7,
- 0xc4c33a1f, 0xf35689ef, 0x35f281f8, 0x71477f13, 0xd2a7c70a, 0xee85a61d,
- 0x36e9cfbe, 0x115cfe0b, 0x7487eb61, 0x41fb0158, 0xbf1f09f7, 0xb375ee8b,
- 0x7da8eb3f, 0x131e7ae0, 0xe1d1aeed, 0xdcff1e6e, 0x4bef9039, 0x24a9abe7,
- 0x38c23a77, 0xc97cc35e, 0xe30ced4e, 0x60480529, 0xe3858ddc, 0x0f18e743,
- 0xd29ddfd9, 0x743b4a1e, 0x52d95dbc, 0x5e177bf1, 0x44e2371e, 0x77c44d9c,
- 0xa1b43677, 0x38fc81be, 0x5ea50477, 0xeff5f843, 0x931e0386, 0xc593d77d,
- 0x7f129be5, 0x93d6ef43, 0x47a3d35f, 0x7a10ea7e, 0xfae1b39f, 0x7ba033df,
- 0xc5120def, 0xe959ff1d, 0x94ffc447, 0xcacf0e73, 0xe39d125d, 0xa47aaf97,
- 0x7cbef114, 0x4899a6d1, 0xca3aca0f, 0xed00acb5, 0xa6490eaf, 0x3f5d80f9,
- 0xf5c64a67, 0xfdf029e3, 0x513fd04c, 0x8067228e, 0x59654ed6, 0x6d953d15,
- 0xab9cfe84, 0x4e340da4, 0xf27762bc, 0xc27029f5, 0x638c1f73, 0x3701fc54,
- 0xcf32bf5a, 0x57a7cd1b, 0x788ea1f0, 0xe346efeb, 0x13247f7e, 0xfdf2b93f,
- 0x3fe17ec8, 0x2fd1b7a2, 0xe1fd2a59, 0x11d4127d, 0xc8839fa1, 0x046e30cf,
- 0x3cc0bb6f, 0x8087e853, 0xd5a6e37c, 0x1a43f3a9, 0x468cf9d4, 0x45ab3e75,
- 0xabbdb79d, 0xe3159fce, 0x3b42702a, 0x6c3def18, 0xd01ff717, 0x4bfbc60e,
- 0x1e630768, 0xd14c60ed, 0xb472c60e, 0x768f3183, 0x0ed1e630, 0x1db9eab6,
- 0xc1da298c, 0x8c359e58, 0xcb59c9c3, 0x0fb090fd, 0x9f8f3a76, 0x026efca1,
- 0x8fa885d8, 0xbd220e96, 0xa8be7d0e, 0xedfff437, 0x478805d5, 0xd44710a6,
- 0xc38c1cb0, 0x83135b6a, 0x93e203f5, 0x664c239c, 0xafb437f4, 0xd506bb3e,
- 0x63b30e90, 0xe257d610, 0xbe962a96, 0xd6efbf43, 0xe7fadcbe, 0x227df29f,
- 0xfbf287bf, 0xbef86543, 0x2e7e4cbb, 0x391dff23, 0xf7afb19b, 0x8ce303a3,
- 0x22f895fe, 0x368e8abb, 0x53fe5c12, 0x7c8313d7, 0x461dabfe, 0x2bf5677a,
- 0x4d931f71, 0xe77ea8b7, 0xde79daf1, 0xcb9d1293, 0x9c2c3ddc, 0x061ef7da,
- 0x790fbbfd, 0xd0f3a4aa, 0x9f77ef59, 0x4906de78, 0xa6dce383, 0x276470e7,
- 0x1c6f1164, 0x4ea77fca, 0xf51531cc, 0xa7f9bf73, 0xf85483bb, 0x787b7433,
- 0x0c35efc0, 0xd61fd554, 0x7bf01094, 0xbfd4430d, 0xf2c0f023, 0x4f676803,
- 0x555230dd, 0x6bd20aef, 0x28d5ca36, 0x85c597e2, 0x27c40577, 0x4f7eaa86,
- 0xa7ae896f, 0xbfa871e3, 0xc90c6f64, 0xb7986283, 0xf388a47d, 0x49c7a581,
- 0xb7c435ae, 0x3dfa256b, 0xde4279b2, 0xf96aa5b0, 0xe7e5a25b, 0x3646f87a,
- 0xbdce83ea, 0x84fef451, 0x16258f82, 0x811b0f66, 0x596dbcf1, 0xde1fb45e,
- 0xf117397f, 0x8dae42aa, 0x781bdfc3, 0xc36f7254, 0xc217a78b, 0x01de44f7,
- 0x38d63fdf, 0x2f0f112a, 0x3a39ce1e, 0xb17ce00a, 0x4b7ba641, 0xe46f3a71,
- 0xff0fb308, 0x209674e2, 0x8ddaffdc, 0xf41bfdfc, 0x3ee1c95b, 0x18dda8fc,
- 0xf6649411, 0x87c15bad, 0x41def4db, 0xaf5d704b, 0x02af4899, 0xd3e49a3d,
- 0xe932c395, 0x2463256f, 0x62b9e917, 0x4b7dca9d, 0x85a73d65, 0x78d2c83d,
- 0xef8a8fbf, 0x640fd317, 0xce1d6159, 0x1938a6ea, 0x61a6b8f9, 0x63a40c5b,
- 0xc3758e8c, 0xa8efe006, 0xef8a7f25, 0x227d9497, 0xf8ef8c33, 0xd09ee6ba,
- 0xdccf503b, 0x824db3ad, 0x5f1be3fc, 0x6595fba6, 0xed1eb75a, 0xb51d92d2,
- 0x5ee68f74, 0x82d26ef1, 0x9f6445ed, 0xc88b642f, 0xc4a73cce, 0x94780b9d,
- 0x58b6958c, 0x823dde60, 0x7788946f, 0xf1f7942b, 0xefe76cae, 0xb8503f3e,
- 0xf5e77e87, 0x902f5165, 0x9c3f7a5e, 0xfd00379a, 0xf6c91e4d, 0x1f4cf763,
- 0xc03fa0c4, 0xad57a987, 0x75703e94, 0x9fb9d908, 0xa184afe0, 0xb008c8bc,
- 0xf1e43f77, 0xbbf8bd19, 0xef78f148, 0x2a7fdbd2, 0x3adbc3ee, 0xc00a87da,
- 0x7823519f, 0x909dc33c, 0xdf568e16, 0x171aa9f7, 0xe9f7c2ac, 0xa08e8fcc,
- 0x7c1869bf, 0x607f97ee, 0xfeaaa252, 0x0d0c0f43, 0xbe1187a0, 0x742e74ef,
- 0xb44e2aa7, 0x4acb9962, 0xe4f1f4f7, 0xd21cbfce, 0x13678465, 0xd82bed54,
- 0x78bd5f14, 0x45ba3bfe, 0x7a6d7f84, 0x344a97b4, 0xba7d6e3c, 0xb79443a3,
- 0x442c3953, 0x25b79745, 0x72e53eda, 0x83e3c751, 0x3a7b1f85, 0x97d89dfe,
- 0x168d845c, 0xc9efe2e3, 0xa1c1ffa1, 0x54da3bd6, 0x3fc22271, 0xfdc69154,
- 0x36ae1543, 0x01df9e3d, 0x00b1b5fc, 0xfc8dca92, 0x6fa8085d, 0xf9e70d8c,
- 0x7fae2365, 0xc3fb0f2f, 0x0f2ac877, 0x2f4845cb, 0xf12bdf81, 0x0f9c027d,
- 0xe94273fa, 0xbfde719d, 0xcfc157e8, 0xc09438c0, 0xb5f1b27e, 0xdf7a1c9f,
- 0x9aa3de8f, 0x89efc85a, 0xf9933d3b, 0x3c00fbbd, 0x15fdf853, 0xfd12cf7c,
- 0x43be1fdb, 0x5dbbd678, 0x00b76367, 0xf73b4a8f, 0xdfe20677, 0xbe0f5802,
- 0x51a0b86f, 0x5e25b9b2, 0xfff2e10f, 0xf482dc01, 0x00800036, 0x00000000,
- 0x00088b1f, 0x00000000, 0x5bcdff00, 0x6595580d, 0xf3be7e9a, 0x700e01c7,
- 0x0427e540, 0x094a880f, 0x44101df6, 0x18293b53, 0x54da1595, 0x021f44a2,
- 0x9a2824fe, 0x2edb52ed, 0x4c7350c7, 0x4a976867, 0x57a3ab1b, 0xb5accd39,
- 0x8cce9a98, 0x7e927bbb, 0xa772b268, 0xa9aeae69, 0x66b663b5, 0x3b448dae,
- 0xb5b4d45d, 0xdfbefdcf, 0x23bef9c7, 0xb5cced4c, 0xd7175c3f, 0xfff79e73,
- 0xe7defe7d, 0xbbf79e7d, 0xc89132a3, 0x1befe24d, 0xffe56ffe, 0xd5a212ec,
- 0x441f9d07, 0xabe5a30a, 0xae0decfb, 0x60fd65cb, 0xcbf5c5da, 0xc32a63f1,
- 0x9c284a23, 0xd70770c7, 0x4d5dc69b, 0x27b53edb, 0x97f1ca03, 0x3463fc69,
- 0x284a83c3, 0x1e3c5ca4, 0xca8d9055, 0x0c61d689, 0xf1c0d11f, 0x3f685d3b,
- 0xaf214bb0, 0xa09d9a22, 0xd41eb974, 0x62bbdeb7, 0xc8614d3e, 0xf5e6cc63,
- 0x11741c2d, 0x1b8d1295, 0xe6e5c27f, 0x1487fd7e, 0xbbf70f75, 0xca21d065,
- 0x10e41d5b, 0x6a21acfb, 0xf9bdf867, 0x9dc1d117, 0xefeb269d, 0x60f37865,
- 0xbb17e8ba, 0xe87a21ce, 0x6e88b9f4, 0x7645c274, 0x798dfed3, 0xa22ff1f5,
- 0x71ff4c53, 0x1af6e9e3, 0x0a27510f, 0x7f0cb8b2, 0x8fb90257, 0x86688ca8,
- 0xccfa349a, 0xb2efc264, 0xf21e786f, 0xa3d3a0f0, 0x512162ed, 0x8f0c6890,
- 0xc7ad22eb, 0xd2593c03, 0xb8e92bd9, 0x48cbe9ce, 0x99dfe22d, 0x3bfa56c9,
- 0x3728297c, 0x61d869c6, 0xa3d31f23, 0x3d363eca, 0x8c68e3c2, 0xc8b43e83,
- 0x345f036b, 0x1bcdbc7d, 0x4c46e7c7, 0xce4db4fd, 0xb9f6e274, 0xd809461b,
- 0x574def10, 0x8361beb9, 0xf0c426bd, 0xa467ef83, 0x7d1cb057, 0x7a39c9b0,
- 0xc1f10f3e, 0xa97353dd, 0x80957818, 0x5b8c1fa7, 0xbc5cf214, 0x26d506af,
- 0x37fad1e8, 0xf9dae4ef, 0xe3b627e7, 0xfe788bc9, 0x92874d96, 0x559c782b,
- 0xf72ade9b, 0x6ddd13e6, 0xde54dad3, 0xf76539ff, 0xe5e82f5e, 0x86a53ddd,
- 0x52015dc7, 0xd8ee5f30, 0xdc419554, 0xdeebe5ae, 0x79e3bdc7, 0xe99c1bbd,
- 0x8f9f9636, 0x3b276d7f, 0x2759cfcb, 0xe24cbd05, 0x7e52f1b3, 0x18953ecf,
- 0x3f7964ea, 0x9e2050ab, 0x5fda57cb, 0x5b718298, 0x75888e3a, 0xbd1db2ac,
- 0xb5fff305, 0xc32de79b, 0x99bda1bc, 0x4e0d5798, 0x86dabcc4, 0xd15a2909,
- 0xb35afcc8, 0x75d044a3, 0x99f7076f, 0xa8817448, 0xba7b7c1a, 0x9ff02dc3,
- 0x59a13076, 0x6475f7d4, 0x0ed9fc0a, 0x1d3d809f, 0xbbbca285, 0xddf92bc8,
- 0xc75fefd9, 0x50e704f3, 0x7c079b61, 0x783a14f3, 0x092a77fd, 0xa8029c6a,
- 0xf7c17866, 0xff04b327, 0x5d88790c, 0xa27eaccf, 0x5e7c9326, 0x26a6e839,
- 0x455efc93, 0xae7c16a9, 0xbed2cb3b, 0xa9679bca, 0x52f33abf, 0x3e35fd4b,
- 0xaebf05bf, 0xfda5ba70, 0x1655eaf5, 0x6b8ac6fc, 0x0417ed2c, 0x9bf05816,
- 0xed2d6baa, 0xb069ae6f, 0x68badfd4, 0x56bea5a5, 0x97c16b5b, 0xd2dbb8ac,
- 0x0db6b6fe, 0x7900fa96, 0x7272c41d, 0x63e3f994, 0xf313ffba, 0xd7cef005,
- 0x7ccc7827, 0xd6d7399d, 0xdc8c33d6, 0x32dc861e, 0x07f5de7f, 0xe47c839e,
- 0x321ca4d8, 0x53cb100c, 0xf513eaaf, 0x305614d9, 0x2cbd9b0f, 0xbb6c4dc8,
- 0x8999fad8, 0x31f33ec7, 0x7ffd730f, 0xf6c1c8b1, 0x63b4e660, 0xbf19e3a5,
- 0x916fbfc9, 0xccc8ed83, 0x067d8e2b, 0x19ff0dfc, 0x5dc4df89, 0xf6fef067,
- 0xf20a2c37, 0x995e673a, 0x3d654dbf, 0xea9d37a4, 0x7cb23453, 0x0e4ddf62,
- 0x30c06fb9, 0x31e023cb, 0x17c04796, 0x0a9b1e59, 0x79665e88, 0x50ebec04,
- 0x3b2ff945, 0xde3c042a, 0x8df01011, 0x4f016a8e, 0xf808d474, 0x02458eab,
- 0x1343bafe, 0xb1d37efd, 0x3a77c042, 0x6ff944da, 0x7c05da3b, 0xca2823af,
- 0xa11557df, 0x8202bcff, 0x0339c2dd, 0xf6ed5df9, 0x2e7ced84, 0xf9e711d0,
- 0xfacabb21, 0xeed804ad, 0xdf14dd33, 0xd863aa68, 0x449146d9, 0x91c465e8,
- 0x8bf9867a, 0x37edc39f, 0x741d476a, 0x1b8f18c6, 0x381f13df, 0x3442bb07,
- 0x31267bd6, 0x1fc07e5a, 0x03e504f8, 0x2539f505, 0x3ebd9fcc, 0xf9f053ed,
- 0x4dc692e6, 0xae376c29, 0x09cdaafc, 0x46db7939, 0x8f93862b, 0xb23e5d5e,
- 0x638c141d, 0x29b8177e, 0xf0269298, 0x0e618b80, 0x88eec397, 0x0177de3f,
- 0x81e43e60, 0xb963e508, 0xb670cdde, 0xf10a793b, 0xe5c394f9, 0x142f2176,
- 0xc27ac870, 0xb41e5c78, 0xa9e745a5, 0xdf61241a, 0x84716d66, 0x1c921f60,
- 0xc895b614, 0x7225c9f6, 0xdcb3e05e, 0xe5857e3d, 0x478b5664, 0x327ef20d,
- 0x2255deb8, 0x0cec07da, 0xf73dfc9f, 0x514c229b, 0xd444a130, 0xbd72f58b,
- 0xa0d54758, 0xcff40146, 0xef4e3524, 0x41f596ef, 0x6bc59ff4, 0x30c15f80,
- 0x9c79f184, 0x7689d600, 0x185db289, 0xce7c14e3, 0xf49b24f3, 0x9642fec5,
- 0xdf65fb83, 0x9f6152e9, 0xe44ed273, 0x3f31eec1, 0xfeb9f9c6, 0xdbd9d4a6,
- 0x9a9fcc23, 0x26bfef38, 0xf34a5f32, 0xff9402b4, 0xc13f194a, 0x4c17e60f,
- 0xc4935319, 0xe7c6c4f6, 0x39f630e4, 0x3f062f96, 0xf41bba0c, 0x48dbe58d,
- 0x4f891afc, 0x1aa9fcb1, 0xf41bd28c, 0x512f991a, 0xff9505fe, 0x754cbe7b,
- 0x7ac6ecf4, 0x2adc5ae2, 0x7c6df3d6, 0xe69fbdba, 0x869370a5, 0x80cbdf41,
- 0x5eb4f267, 0x5d2351e8, 0x9a0bcf35, 0xe0c5ed79, 0x0bbb6c4f, 0x03e3b423,
- 0x779c56f7, 0x6d273e7d, 0x8b5ff9e5, 0xa0a73a67, 0x33f1e03c, 0xf6eae61f,
- 0x84da8fa2, 0x2937673d, 0xea54fe08, 0xb45b9aac, 0x9597f85c, 0x36bfab1e,
- 0x8d9aabef, 0xe8de7798, 0xcd95ff18, 0x6bd1ce32, 0xa6af71f5, 0xf56e312e,
- 0x6bbb6b58, 0xdaf0bf75, 0x5df96b02, 0xcbafdd7e, 0x91d83ca3, 0xbae5524a,
- 0xcbf09b68, 0xdc72bd2a, 0xe3af9d6c, 0x099a767d, 0x80e691be, 0x77f17af1,
- 0x7bd600ae, 0x7e050535, 0xbc04850d, 0x9c62c28e, 0x01d0d9eb, 0x09c891bf,
- 0x9fddc5bc, 0x5e9162eb, 0x87ded76d, 0x8e49f3df, 0xeb852936, 0xfbb5e333,
- 0x89bd17a1, 0xe1add437, 0xce96e6f9, 0x63bf402d, 0x2fe13e95, 0x178f731c,
- 0xdfe40bfe, 0x8fd51699, 0x17fed957, 0xf97adaf0, 0x897c007c, 0x160287cf,
- 0x7cf857f6, 0xe16d7e00, 0x79bf4206, 0xa61c853e, 0xaffd1b7d, 0x4721cef3,
- 0xf7f6c8e9, 0x1b3f29ba, 0xbc9cb1ab, 0x92a93a96, 0x55a70192, 0xa5afbf62,
- 0x8c24d866, 0x7c580973, 0xff3860b8, 0xe8bf90ca, 0x31c8f37c, 0x1b3a646a,
- 0xa7a58d74, 0x813fe741, 0x470dcfae, 0xc4955ed7, 0x3ee03639, 0x313d9ab0,
- 0xf6944d6a, 0x89387020, 0xd77e5932, 0xa087b21d, 0x89631f8f, 0xd25f1859,
- 0xbfa50a89, 0xef5f5ebe, 0x16341d47, 0x53a7a6f4, 0xba5df944, 0xcfb736cc,
- 0xd65cfb10, 0x7dfa215e, 0x88bda719, 0x092f9c75, 0x820f644f, 0x99d5da3e,
- 0xf9e7833c, 0x0abb59e4, 0xeec5bbff, 0xd742a6db, 0x4fabb35f, 0x55f4b8f1,
- 0xe842ee6f, 0x86a393d3, 0xb8b467bd, 0x7b8d1d25, 0x357957c6, 0xc8ef38bd,
- 0xf5299a5b, 0x85e81490, 0x8d8f3e71, 0xf2c2bb63, 0xe125cbbb, 0x7975e748,
- 0x12a7db02, 0x49d85ed1, 0x4fdc7f83, 0x4e3cd9e0, 0x0fc8ec39, 0x7e3f8413,
- 0x9ef0252e, 0x9256f31f, 0xbf659fc5, 0x81add857, 0xb38e92d1, 0x3323e269,
- 0x73ecaf19, 0x07eb8852, 0x1b5da52a, 0xdd85b8f0, 0xd1b57aac, 0xa9dcfb01,
- 0x4cb88bdb, 0xf498f7be, 0x4097de3f, 0x26fc933e, 0xf059a616, 0x4b12f524,
- 0x7c8a94fb, 0xe06a7d4b, 0xa8fd4b32, 0x3e0b12ea, 0xa58666a6, 0x39a2c67d,
- 0xbb4b3c16, 0x7b3ed2d6, 0x6e0b42c5, 0x596ca1d8, 0x8b6d3944, 0xb5c7fd2d,
- 0xcfb4b52f, 0xa961de0b, 0x44e060a7, 0xd6aff721, 0xb2df8ffb, 0xe4cf5ace,
- 0x2f4395b5, 0x928fdfe4, 0xe614fbab, 0xd967b55f, 0x84e5e87c, 0xebac7bae,
- 0xc7657fb1, 0xa29d9039, 0xffa628d0, 0xddab3ed5, 0xe2b4caab, 0x8bff5e95,
- 0xaf5cdd60, 0x9fb2eed5, 0xb29e40a7, 0xf2961cdb, 0xddba25b1, 0xc453429c,
- 0xf8dbf87d, 0xe1665daf, 0x2ebd2c7f, 0xfe038796, 0xb49bb730, 0x97072ac3,
- 0x3072ac86, 0x1cab69f9, 0xe558f714, 0x5623f2e0, 0xad87f039, 0x67da5072,
- 0x13b28395, 0xf6983956, 0x0c0e558e, 0xd7e58cf9, 0x3e5588f4, 0xe5345348,
- 0x8aebf08f, 0x89f956b3, 0xbf510fe5, 0x8f3cdfe0, 0xfde68f42, 0x185afcf9,
- 0xfe21afc3, 0x77e1bd30, 0x4e4f0ece, 0x67d55e01, 0xf7cf10a7, 0xabcfbe98,
- 0xf279b727, 0x74ee9ed9, 0xd0257568, 0x3aae5d73, 0x0d5ca4b3, 0x87881df4,
- 0x198fafdd, 0x5a59c7ff, 0x1a2fda03, 0x0bae59f5, 0x4dafd1f2, 0x39e97dc2,
- 0x1ddd8495, 0xe7c72097, 0x4758b27b, 0xa87b1ef0, 0xd271d793, 0x3ec0a5d6,
- 0x2b6b2737, 0xa2f6ffd1, 0x07708536, 0xfe82a0a3, 0x971cfff5, 0x1c7ebc0b,
- 0x151e7b89, 0x2416ca45, 0x7d62ed45, 0x7af39736, 0xf7e896d6, 0xb9eb9514,
- 0x1912fadf, 0xbd5248b7, 0x290f112e, 0x20e200a2, 0xadc8bd7c, 0x8e3d062f,
- 0x3d024fc7, 0x9b2a6dba, 0x7d388a38, 0xf067d829, 0xa53d3b55, 0xfe113f48,
- 0x7fee8e5e, 0x4eff5365, 0x0ed273ac, 0x97ab9cb2, 0x30e4dc86, 0xd3f27dd1,
- 0xdc5e0b5e, 0x7f696993, 0xa59f11f9, 0xb42e1fde, 0xa9f697d4, 0x44ecbc16,
- 0xb4fda585, 0x7c160277, 0xd2daa47a, 0x35b38afe, 0x229c7c16, 0x5f7fafef,
- 0xe3e92f92, 0x7de44563, 0xba9fdfd6, 0xf788ab7b, 0xe1ad7bc9, 0x23d7534f,
- 0x4ce23701, 0xdec71cba, 0x404c5c87, 0xfec5cff0, 0xb183ce2f, 0x6b47e96e,
- 0x294fbaf7, 0xdd3f51c9, 0xff0db3f0, 0x01558295, 0xfdc3b9f3, 0xfba2f9e4,
- 0x6d7f86f3, 0x8bd3cdf8, 0x721ce27d, 0x26cabc6e, 0xc911c1e4, 0xc7d79c82,
- 0xfdf7b0d1, 0xbde44be7, 0xc6fd7621, 0x9fe762ba, 0xed95ec5e, 0x729f71f5,
- 0xc335edd3, 0x5cba33f9, 0x735f1c2d, 0xb8f9f214, 0x79677d53, 0x9e7f7fde,
- 0xb3cfa4ce, 0x2e5cde84, 0xb3675fd7, 0x31a3f889, 0x52a991cf, 0x7f380d5e,
- 0x7e3bfb0e, 0xe37deea2, 0x1fd87876, 0x21ddbc79, 0x9fc708e2, 0x2c1b515b,
- 0x01443f80, 0xef8e338c, 0x7c0fe003, 0xae1fdc0a, 0xfd176a99, 0xbd4897cf,
- 0x1265da8b, 0x24807976, 0x5dda07ff, 0x0c317ee2, 0x181c85bf, 0xcc7c41fb,
- 0x62e32051, 0x398b8880, 0x062e321c, 0x4031711c, 0xfe50c5c4, 0xf02a875c,
- 0x02151d83, 0x2023be7f, 0xd51d23f0, 0xa3bcfe02, 0x721b9446, 0xe32f4b13,
- 0x1ff0663e, 0xa373886a, 0xe71e4620, 0xe5f927df, 0xd9aceb5b, 0x6f9c5bc3,
- 0x24a56aa3, 0xa6dbcf4a, 0x2dc8794a, 0x3b407495, 0xed48ffe8, 0x2945ecaa,
- 0x900ea788, 0x47fbc52f, 0x53ff86e2, 0x6ee830f4, 0xfaa357dc, 0x2461f526,
- 0xbfee34bd, 0xd0acfba6, 0x8c7d58bb, 0xba58dbd5, 0xbdeb3f8b, 0x8d7bde59,
- 0xa7ae85f8, 0xbd0c5f06, 0x16a45276, 0x605425f6, 0xef7d06ab, 0xd1eab24f,
- 0xbe92a5f5, 0x8623d003, 0x74de7ca7, 0x7687ce1b, 0x5607f0af, 0x90ccb6e8,
- 0xec87e6d3, 0xf3e27ce2, 0xed37e3d6, 0x7db779b7, 0x6eef9ea8, 0xe215bfbc,
- 0x201d9d5c, 0xda5f1f71, 0x737684a5, 0xf5a086bf, 0x2521147c, 0xfae46fae,
- 0xe35fb817, 0x33f3d896, 0xf221d620, 0xe6b5bc2c, 0x72fd6b2e, 0x33c91efd,
- 0x632760ba, 0x96570af3, 0x4aa0e7ea, 0x5f7237ea, 0xdd105ee2, 0xa1572e97,
- 0x873829f1, 0xcbb4af70, 0xce3846b8, 0x21f3af74, 0x8a2a3fce, 0x0a133d33,
- 0x746e4e71, 0x177c13a8, 0xcf41a1cb, 0x9e833ca1, 0xeae7184f, 0xe23f753f,
- 0x8bc7cf8b, 0x7fcf057b, 0xbe76e823, 0xff40aecf, 0x7a08f287, 0x3b41f3fb,
- 0xe73e99d9, 0xba09c60f, 0x7e3b627e, 0x94cfbe4b, 0x5f28b877, 0xb015c941,
- 0xa8c6fb1f, 0x65d661c1, 0xfb222d40, 0xe1bf588f, 0x99ee3250, 0xfcc8cf2d,
- 0xbd33cb44, 0x7b2605e9, 0x10ea5cd8, 0xa6dbbbfb, 0xff2294b5, 0x8b9ddf60,
- 0x5f1dde7b, 0xce00a686, 0xb12de3d7, 0x77b219fb, 0x47211533, 0x613fbc03,
- 0xb115aaef, 0x0497b63f, 0x989b7b3d, 0x02ce3c9b, 0x34068f0a, 0x96da00f2,
- 0x2307c10a, 0xae10d00f, 0xb9b8fb10, 0x8133b973, 0xde76449b, 0x8be0955b,
- 0x392207e6, 0xc7fe08b4, 0x9b827948, 0xde315506, 0x886706f7, 0xcd281e71,
- 0xc6d0fe93, 0x1fe16bed, 0x3934f65e, 0x53888741, 0xa74b138e, 0xf3ca943f,
- 0x1d3c1320, 0xbadfdd13, 0xe7b08a0d, 0xc02ba0eb, 0x9ec22bb7, 0x5d67f81b,
- 0xf1255e3a, 0x3c49373b, 0x516cf4e2, 0x117ee452, 0x013ec02f, 0x6bdc1fb1,
- 0x05f1e9f7, 0xfb1003ec, 0x18ec3940, 0xe031d870, 0x61c063b0, 0xc76100c7,
- 0x6a94be50, 0x43e71172, 0xacd2a33e, 0xaa6e8327, 0xc825f934, 0xe4719867,
- 0x91edcc33, 0x23d730cf, 0x47ae619f, 0x238cc33e, 0x8f6e619f, 0x4719867c,
- 0x1edcc33e, 0x8e330cf9, 0x3db9867c, 0x7ae619f2, 0xf5cc33e4, 0x719867c8,
- 0xedcc33e4, 0xd730cf91, 0x58aededf, 0xb3b71df2, 0x35dc86f9, 0xf21348ee,
- 0xa6af3631, 0x7efe720f, 0x3977d7e2, 0xa3e7c1f3, 0xebb7212b, 0xc954135a,
- 0xc96aaee7, 0x3e491b77, 0x3e0ad7f7, 0x7892ebdf, 0x1de19a95, 0x1e422fc6,
- 0xe640b2a1, 0x47910011, 0x011e4400, 0x4a847910, 0x0023cc87, 0x72808f22,
- 0x910011e4, 0x1e440047, 0x04791001, 0x0011e440, 0x3f404791, 0x910011e4,
- 0xf2394047, 0x23c88008, 0xaf24fca0, 0x6304f903, 0x0ba3f05d, 0x963cf72c,
- 0xcf3dcb43, 0x47e1c16b, 0x8fc3db9b, 0x8fc3d736, 0x8fc3d736, 0xa3f0e336,
- 0x47e1edcd, 0xa957719b, 0xfc17e84f, 0xf83f7369, 0xb8bc66d3, 0x6212f82b,
- 0xfaefd744, 0x91808bdd, 0xc571e524, 0x41ec67cb, 0x4f7c8c5a, 0x4dc95e24,
- 0x545cf955, 0x192b8b5c, 0x844b06d7, 0x7ea14fde, 0xf22df81b, 0x2d37ccb7,
- 0xcde4214c, 0x14c8bf8b, 0x513e46f5, 0xfddf31fc, 0xe7f84907, 0x5d7245dd,
- 0xbc957f46, 0x7da34076, 0x5dbe1f14, 0x3b46fcec, 0xeb4d2f61, 0x1f9b0be0,
- 0xbdff7cf9, 0x2cad929e, 0x8a6d7b4f, 0xb2f74ff0, 0x1870b59f, 0xf74b34bb,
- 0xf6daf69b, 0x7ee04b1f, 0xba8a0dfd, 0xe89e8787, 0x09673ea0, 0x0256d4e8,
- 0xd4c2623f, 0xd47f3d54, 0x71616336, 0x3c46dd74, 0x0044ed8f, 0xfd99e779,
- 0x79e26ae4, 0xb907fd66, 0xb9cfe19a, 0x7e811fa4, 0x0e4dcfb8, 0x263d812a,
- 0xaa7cbef9, 0xe0b4ff3c, 0x5c4d19da, 0xdb5f793e, 0x77f8668c, 0x8fdfb209,
- 0x7416489f, 0xb2a361bc, 0x99fbcec7, 0xbb028fb9, 0xbe855db9, 0xbcfbc9ee,
- 0xaf3126ae, 0xce6cd5d7, 0x75caefbf, 0xa45f70f9, 0x88a66548, 0x3c842bc5,
- 0xde37419d, 0x1fd88bdf, 0xc43ef89b, 0x1d3d5765, 0x24d0fdef, 0xa93dad1f,
- 0x91cd7c16, 0x2687ef2c, 0x1f855b39, 0xeec4172c, 0x16adce21, 0xf5abe59d,
- 0x9a95b7f2, 0x9e784bcf, 0x0bbf7756, 0x35359bf4, 0x6c346ab5, 0x275251ff,
- 0x36a6ee40, 0xebc31a6c, 0xd50142d2, 0xdabd03ee, 0x93f8125e, 0xe2170235,
- 0x27d62e53, 0x4149c3ce, 0xa4c89c25, 0xdbb821b8, 0xebf19a36, 0xe99c1b83,
- 0x548fbf68, 0xf89303b8, 0x7449767f, 0xc274455f, 0x5e40af16, 0x499477a8,
- 0x7c72d8fe, 0x57e2f20f, 0x58f9049d, 0x613af0e0, 0x8dfd626f, 0xec0f77d8,
- 0xec2adc7f, 0x21d39f54, 0x3fdd3afc, 0xb5caf06a, 0x29d1b67e, 0x43868ffc,
- 0x3ea07fec, 0xde30dfc6, 0xa1dfb043, 0x1f8e7186, 0x720d4ebc, 0xb7dacb55,
- 0x7383bbc5, 0xa9bda179, 0xf2e7d72c, 0x0152dff7, 0x0aed90bf, 0x0dfb29ec,
- 0xb9654e77, 0x52f4d86b, 0x915dee32, 0x6fe101e0, 0xa1f1b67c, 0x905f1964,
- 0x9d2689f9, 0xa6fc464e, 0x9347e759, 0x03e5eefe, 0xa96c5bb6, 0xf186ee71,
- 0x2bd7815e, 0x3f588afc, 0x9bfbc891, 0x82bf5c99, 0xb195b3f7, 0x361adbe5,
- 0xfec5d267, 0xae6fe1a2, 0xb95de7d2, 0xb7de29d1, 0x3890a0ac, 0xac86560f,
- 0xfee957ed, 0xada7aae7, 0xca983fe5, 0xa1f2277e, 0xdfa9df86, 0xdbd4ee93,
- 0x7bdebc34, 0xda7bf0b3, 0x5075c89c, 0x07e906dd, 0x4d0a7ed1, 0xb5cf8050,
- 0x775e33c5, 0xc32aa028, 0xba9bcdc8, 0x931f343f, 0x0c173d32, 0xb23b0826,
- 0x8112f070, 0x299832df, 0x8583ade0, 0x19b11cb2, 0x4aa473e6, 0xe3c7dd09,
- 0x41fba5bf, 0x265e0f37, 0x198207ea, 0x58078e42, 0x14c5318e, 0x165d3edd,
- 0xd6117a50, 0x36d4ef9e, 0xf9fae18d, 0x95f849bb, 0xe25fc3d7, 0x9ff0458a,
- 0x7907a14a, 0x6f9f1855, 0x0f21346f, 0x9756b07a, 0x1203d67b, 0xec202376,
- 0x1082e559, 0xd22c93de, 0x6fc0dbf6, 0xe0b5fe43, 0xebf00729, 0x57cb8a83,
- 0xe215ee24, 0x77c86cfe, 0x27d41eac, 0x8f26f1ea, 0xc50d278c, 0x5e58b09b,
- 0xc5b5051a, 0x47afae01, 0x9d12f06c, 0xa4aa4cb1, 0x77df5922, 0x91bc5b50,
- 0x353fbdcf, 0xb367511e, 0xb3f57e09, 0x8a07b79f, 0x32aa274a, 0x94db27a0,
- 0xe8bead92, 0x9f289e7a, 0xba665033, 0xf5d52f27, 0x032ef58a, 0xdf758ef7,
- 0xc341909f, 0x6c0605f8, 0xbf433a64, 0x772253ea, 0xfeea4c29, 0x64a814a9,
- 0xbe92d6d6, 0x79fe244f, 0x3c758b9d, 0xdff6d0f7, 0xfa08f16e, 0xd4fcfc08,
- 0x45838b35, 0xac1d867f, 0x77d01c53, 0xadbe0ec3, 0xb7a0e768, 0x3cc8eead,
- 0xa8b135f0, 0xc5be05df, 0x6db6e7d2, 0x3127db3d, 0x24cb721d, 0x5d5ceaff,
- 0x80b8f14e, 0xd3dc4e42, 0xb9e48b1a, 0xee5f0e42, 0xf11f9112, 0xb19fb889,
- 0x6fe00fef, 0xf497430f, 0xc36fe932, 0xa4b9f63f, 0xff080c7f, 0xe04fef18,
- 0x7f87031f, 0x18ff080c, 0x818ff0e5, 0x0e063fc3, 0xfc3818ff, 0xc7f84063,
- 0x16d87f28, 0xf33f7538, 0x685b51f3, 0xd39661ff, 0xee6b47c7, 0x51ef9e32,
- 0x238f92ea, 0x63fb1348, 0x627611b9, 0x7cb13ec8, 0x72a3cbb9, 0xf4fdb4b4,
- 0x547e5b21, 0x7cb69a9e, 0xdc29f3ba, 0x841fd983, 0x945b6b3e, 0x9194dc70,
- 0x3b89ece5, 0x3cbe8412, 0xd84b8f71, 0x89d73add, 0x5179dc97, 0xfedbbe7a,
- 0x27694eb7, 0x3c7c13c3, 0x78b6e2ee, 0x89ff7615, 0xac1c9af2, 0x1548b137,
- 0xd9c0197c, 0xb256f88e, 0xa5f28796, 0x4ce5e274, 0x57ff576e, 0x7ea2e7af,
- 0x173cd1cd, 0x11c36fec, 0x1f4ce6ff, 0x21136bfa, 0xaf1e0daf, 0xeac5fe0b,
- 0xbce2a98d, 0x7190cfad, 0x9140965c, 0x31f83307, 0xdfc64cbb, 0x80ef79fa,
- 0x127bf417, 0xc0b9c813, 0x2df24ed2, 0xb88cdf56, 0x2b5c6c62, 0x72795f1a,
- 0x22e23e4b, 0xf4ed49a3, 0xc42f4c5d, 0xd1255c3d, 0xfc6c4ab8, 0x5d5f4863,
- 0x19e78964, 0x7e994d70, 0xa9efd74f, 0xd4f743cd, 0xf01979a2, 0xbc541fe7,
- 0x79373f88, 0x674eb77c, 0x89cfa9bc, 0x3f348817, 0x62cae7cd, 0x8afbffbc,
- 0xbdf80f77, 0x56ec2fde, 0xebc2781d, 0x2151da69, 0xc429b6f4, 0xfac8d470,
- 0xdec1e4bd, 0x5f619f9c, 0xeb0b80e1, 0x5c06f26c, 0xa77f2669, 0x98094bb1,
- 0xf819fddf, 0x8e3265ed, 0x07d7c758, 0xf5b6efd0, 0x88a5ae79, 0x83dbb25b,
- 0x746b6ef7, 0x71fa3139, 0x625ef13b, 0x0cbd3e7e, 0x7de7eab9, 0xbe616ec1,
- 0x4bf8d312, 0x7e69be31, 0xb5fc2f6e, 0x62496595, 0xef2f06bc, 0x2bd00f3b,
- 0x1074c9d6, 0xcedfea74, 0x3cc4f9e3, 0xe18dee82, 0x7ac55390, 0xf1834ef0,
- 0x1390dec5, 0xe8dd2cf3, 0x6d7ef117, 0xdb479c9b, 0x862aea92, 0xbaf0e73f,
- 0x1e7ecc72, 0xb2e41dcb, 0xd1fa970e, 0x0fc2bd62, 0xa53a626e, 0x634cffc1,
- 0x3173d7bf, 0xf5f41abd, 0x5aa57537, 0x07aec6fd, 0xad4fe09d, 0xf2c4ae7e,
- 0x8e5d31e1, 0xcabc6e97, 0x08efe845, 0x533ef0b8, 0x6ffde9d3, 0x22b7e36b,
- 0xfddb523f, 0xf18f3388, 0x4fd265ed, 0x46740c7d, 0x3c3f383c, 0xfa53ef01,
- 0xf78bc6d7, 0x2edeb5b6, 0x7a21dfb1, 0x81f4c43f, 0x11ade25f, 0x093966f4,
- 0x535afde2, 0xd1bf95b7, 0x718924f5, 0x841bba9b, 0x68732dfe, 0x1d79af2e,
- 0xa0985e3b, 0x596a5d30, 0x3f9c15ef, 0xf2172d5e, 0x5ba1e673, 0x793ec573,
- 0x9273a09d, 0xd8879bea, 0x908dcb04, 0xea7e436b, 0x1b3ea54b, 0x932c1df3,
- 0x65839cf1, 0xbfe9c7c3, 0xb69b4f4d, 0x71005035, 0x15524cbc, 0xd4f5dbe5,
- 0x5f434fd0, 0x6538f56b, 0xa405b6e3, 0x9f0dec99, 0x0dcf6ddf, 0xdd019f43,
- 0xf9d62c9e, 0x917cf4c9, 0xf7baf14c, 0xe5d67e74, 0xe31ef55b, 0x7557dc61,
- 0x139bafbd, 0x28b6b09e, 0xb798deda, 0x83f64d2e, 0x5ece43fc, 0xf682e9d5,
- 0xdd7b44eb, 0xa376e99e, 0xec6ec871, 0xbb0e94db, 0x79115fb1, 0xa5db75ab,
- 0x99eeb75f, 0xfadf1124, 0xdf8775f7, 0x9ddb85b8, 0x3d77787b, 0xabac6bf6,
- 0x44ed2c29, 0xb053fb33, 0x73f4cb1b, 0x7b58b3bf, 0xc7a4cca7, 0xccf77f4d,
- 0xe2c5e844, 0xdf99ff1e, 0x1877d892, 0x67bde6f6, 0x0cf6f17e, 0x357cf45f,
- 0xcb74b1f6, 0x3c1b38bf, 0x7dc9ba66, 0x2a5c2d6e, 0x5f8139de, 0x6e357fb8,
- 0x81de4454, 0xffc25dda, 0x2b1df834, 0xbfac0d07, 0x1ca89e8d, 0xc91ffc18,
- 0xe50d726f, 0x0dff24e7, 0x60721b7e, 0x13e0dbf0, 0xf9359ce1, 0xffbac6fd,
- 0xb17bafa0, 0xeb5fbf2e, 0x4578b77a, 0xd0996b9e, 0x23573cf7, 0xafaf5ee4,
- 0x0f96b26d, 0x643bc9f1, 0x2f4337df, 0x9f247a06, 0x6539b606, 0x45df721c,
- 0xb9c5ca7c, 0xb963ac6f, 0xd66c6f1e, 0x74cb86e3, 0x94f9983f, 0x6a665e54,
- 0x53e484f7, 0xffafb3e3, 0x627dcfeb, 0x6d8ed27f, 0xe2fe138f, 0x82fd9ed2,
- 0x1e5bb55f, 0xbb71e674, 0x7719729c, 0x6df3b21c, 0xe7e22f7e, 0x76ecb78b,
- 0xca73ff42, 0xe562dd25, 0x077f4ebd, 0xe715d06b, 0xf73a628f, 0x7bb0f68c,
- 0xf59e79fb, 0xf193e36b, 0x6798c6ae, 0xe394b95e, 0x34d4b6c6, 0xd6d8d7cc,
- 0xabdc03f0, 0xab1fbb0c, 0xa5e3a777, 0xf1e52c3e, 0xafa797a0, 0x15d77352,
- 0x332f9c5d, 0xc972ace0, 0x79311fb7, 0x3b258ef1, 0xe227e7b1, 0x049ac41d,
- 0x82e5f915, 0xf3084882, 0x6eb18e42, 0xbc45db17, 0x89682987, 0x14758a7c,
- 0x02ff7c90, 0xf3269498, 0xef8ce91f, 0x305765e1, 0xd84bb7cc, 0x2107d3a8,
- 0xe8d3d434, 0x1ff61948, 0xf246b76b, 0x34f90c2b, 0x53b589c6, 0xc96fed23,
- 0xe9dfdc77, 0x525e3d3c, 0x79bae6a8, 0x4e1ffade, 0xfa3f1152, 0x12ba7db6,
- 0x6869be64, 0x15ac2cbf, 0xb7ecc369, 0x4683de40, 0x55776fde, 0xbdfb30fa,
- 0xebac0f28, 0x7bd6f189, 0x25d23f28, 0x15a723f3, 0xdfb8b73e, 0xe2f1b5e9,
- 0x2fb199bd, 0x5dff3e23, 0x9477e7df, 0x8b71e9a7, 0xc9fc1248, 0xff5d04ba,
- 0xf94712c3, 0x71b95302, 0x46f49fde, 0xf64cd292, 0xfd36c3f9, 0x76c8a43c,
- 0x1f6f8311, 0x9c73884f, 0x649d3aec, 0xca7c822b, 0xd6fd19f5, 0xed93d53b,
- 0xe29b73b0, 0xf66efbc4, 0x8e23369b, 0x154c1cd4, 0xdadb99f1, 0xe0eccf4b,
- 0x98db6e71, 0x5ebf0aad, 0xe997f3f7, 0x7d712ff6, 0x6869e6c3, 0x0bcf23bf,
- 0x53d9be3f, 0x2dfc42e3, 0x2b817bb1, 0xf2bdf85f, 0xabe4601e, 0x03542bd6,
- 0xfb0e5bfd, 0xbdb2bd08, 0x66f38050, 0xffe90ef9, 0x16d1b7cf, 0x75c73be4,
- 0x82cbccd6, 0xa8a9d87d, 0x176927f0, 0x7ee351db, 0x6923b6c6, 0x72cecd4a,
- 0x962bebd0, 0x32ff1e3b, 0xec76b19c, 0x7b8027a7, 0x817fb127, 0xa03d60fd,
- 0xb4b9564b, 0x4fbb278f, 0xa28af925, 0xbf53fcf4, 0xc2e4317f, 0x23359bc8,
- 0xf20a33ee, 0xf90e9751, 0x63f3d268, 0x0ae7bb9b, 0x4df779bc, 0x4e973be2,
- 0x647be634, 0x0f5583d3, 0x733e5907, 0xb5347a75, 0x7e01bdce, 0x713d8ad1,
- 0xe35ee2a9, 0xfd9ae60c, 0xf7dda6d0, 0xce5eef8b, 0xdf178eee, 0x177a54bd,
- 0x3ef2a654, 0xf54aed97, 0xc2e74ddb, 0xddfeba2b, 0xf2d73ad1, 0x8f334afd,
- 0x7ff1e5e9, 0xde2893df, 0xa5df192f, 0x8ed6e55c, 0xfbe34ec1, 0xf93ee994,
- 0x68964a5d, 0x3e361bef, 0x1d33c06f, 0xd3073bf2, 0xd4373677, 0xd696ff72,
- 0x6718c903, 0x956f43d5, 0xd7108533, 0x1a7c037a, 0x8766cefa, 0xf9a6cefc,
- 0x77bfe1a1, 0x3e435c81, 0x4b211c57, 0x50b6f17e, 0xb543f08a, 0xef90b930,
- 0xfc24bcd6, 0x6a76b3dc, 0xf86eb9c7, 0x44794625, 0x94d9c3a7, 0x7ff05cae,
- 0x7247dee5, 0x9c7c6e71, 0xbdbaf124, 0x7612feb7, 0x4e327b48, 0x120edffa,
- 0x50636dfe, 0xf7c6cbfa, 0x1baa4453, 0xe573f0f7, 0x95bc6289, 0xc63877fa,
- 0x10bfd8ba, 0xa83b1fe5, 0xf7c0eb1a, 0x77e79035, 0xf066e11d, 0x47f65df3,
- 0x4578ef91, 0xbb77bf97, 0x7bc4f3ec, 0xf8045622, 0x1d76ef15, 0xd11e4248,
- 0xecaac3f0, 0xf0ec05ef, 0x7e290e97, 0x4589c39c, 0x863dc427, 0x6ac978f4,
- 0x75b794af, 0xcbce733f, 0x2afc2d1e, 0x08e2d251, 0xd7e386bb, 0x34dfba1d,
- 0x2fdc1f84, 0xfb2d65ee, 0xd2d05fa4, 0x05f84a73, 0x7c619f86, 0xdf6ab747,
- 0x1827e129, 0x941f56fd, 0x283d6974, 0x6d0a1bcb, 0xa025bc46, 0xacbee014,
- 0xd9727c08, 0x38364bfd, 0x25e6f8cc, 0xbd000a1b, 0x5fa43c7a, 0x0b5be5f8,
- 0x33ee257f, 0x71f51bad, 0xe69a7719, 0x4636994b, 0xe5c5c77e, 0xefe83de3,
- 0x5adfdcb3, 0x50fbca0f, 0x8b6135b8, 0xdabb1778, 0x6cec00e3, 0x7cf388f5,
- 0x10ad9b57, 0x4a03c9ef, 0x8ee7f082, 0xc6b9efea, 0x3c4dfaac, 0xd45904e2,
- 0x13cb6bdf, 0xa7f2b8ef, 0x14193cf1, 0x8cbaef14, 0xfc2e67ef, 0x18a547e3,
- 0xe45c767f, 0x97802200, 0x096c7b4e, 0x53b325f2, 0xf8a0a522, 0x951f87a5,
- 0x00e44678, 0x60de50e2, 0xe9ca92f7, 0x695c467f, 0xaf8962be, 0x6568adbf,
- 0xe0eb4120, 0x6b8c9779, 0xfe7c8bf4, 0x8e52698c, 0x7be31cc6, 0x5f51ee24,
- 0x303dc478, 0xf89b5463, 0x228a8bae, 0x147768a5, 0x823e587d, 0xf084265f,
- 0xc93c8c3e, 0x983ccf32, 0xa8ef121f, 0x30df32dc, 0xf02e9fd0, 0xb431ce30,
- 0xda2dd4ff, 0x5dd1cac7, 0xa0fde4d3, 0x63e64e26, 0x399c546f, 0x9b9300ff,
- 0xfa0b5da7, 0x8bdbe4d5, 0xdef1e3fd, 0xbf03be4e, 0x0d6de7a0, 0xbe8e797f,
- 0x9efd1caf, 0xd324bae7, 0x0253fd03, 0xe5ddf101, 0x1ac7457d, 0xfd03ff31,
- 0xd0fe426e, 0xa738c778, 0xabde413f, 0xe716a92e, 0x5073e2ab, 0x563fb71d,
- 0x1de30b64, 0x16e403ff, 0xc7726579, 0x78b6d9f8, 0x395b1ef1, 0x3817cafa,
- 0x9fedb267, 0xfef0a6f6, 0x5152ffb3, 0x07eb8361, 0x26f63cce, 0x3dc1bac3,
- 0x7d8fb1fb, 0xf6235ac9, 0xfaa07271, 0x7e24c694, 0x56e3dbc0, 0xe645f9e5,
- 0xfbbd1ff5, 0x5b34e48b, 0xfa175d74, 0x78733ccf, 0xc45ba02a, 0xb51ce7a5,
- 0xcc5638cb, 0xfa642e7a, 0x6e70bbc4, 0xc17ee827, 0x5ee10b63, 0xef68e738,
- 0x1cdf583b, 0x7dc677bc, 0x6f3cedc1, 0x97c8e73e, 0x1af78a93, 0x64df9d30,
- 0x1ac0ed47, 0xef4a3cfd, 0x0579bdf4, 0xed57c9ce, 0x73037884, 0x963ff052,
- 0x1fc16f7f, 0x699ce3c1, 0x2a36def2, 0x4d3826bf, 0x072863e8, 0x3ed338fa,
- 0xd0b53bfc, 0x638f4534, 0xfc1a7e49, 0xf063f832, 0xdd33a0c3, 0x14a5e270,
- 0xf8b7d045, 0x3fae9287, 0xe2fd7410, 0x4b5626f8, 0xd70fe4ba, 0x7ffefa0a,
- 0xfbc8eba3, 0x0d85df93, 0xde1eefed, 0x7f659e5f, 0xda5ffd3f, 0xeff7d09f,
- 0xd613bfbc, 0x8677a5fd, 0x4e4127e3, 0x7f09b21e, 0x28bdf62a, 0x97b09215,
- 0x1104f6f5, 0xe412d537, 0x276c06f7, 0x349d825f, 0xeab8e3ec, 0x8afc3148,
- 0x638f4493, 0x8f5b115d, 0x5a78ff28, 0xb19390be, 0x7c4b2274, 0x9488e137,
- 0x54ed6fc1, 0x76dd3b02, 0x8733c8c0, 0x7a565f61, 0x42edde44, 0xf27416c8,
- 0xa1a9ddf8, 0xde78cb9d, 0x448b9bee, 0xd102e51e, 0x1f382394, 0x7f082457,
- 0x84953bb4, 0x9daeeadd, 0xe796fc28, 0xc2e7b6bf, 0x4dafed5f, 0x6edbf910,
- 0xfc3b647f, 0x3e09eecf, 0x7f4dc835, 0xf844d0a1, 0x6e05c1ab, 0x02f74f31,
- 0xb7bb0769, 0x83f7c8e7, 0xf209fa14, 0x48ae8f48, 0xeec17910, 0xc42c81dd,
- 0xd24c3ecf, 0x2e1f434e, 0xb873cbb1, 0x19cb8f3b, 0xd4d4ac3e, 0x62bc6336,
- 0x6d48eeb9, 0x797bb3c2, 0x3602f894, 0xb27e5c99, 0x6be4493d, 0xe2317d0d,
- 0xa782e3d5, 0xc64e8276, 0xebefb677, 0x5dd065f2, 0x0eefc809, 0x721bfa0d,
- 0xbba75a36, 0xb794af72, 0xabc7f7a1, 0x1e3fbc49, 0x77c04bcb, 0xaa71f56a,
- 0x32be740f, 0xeb12fb45, 0x7ccb5cee, 0x92fd63b1, 0x1df127fe, 0x95fe30e1,
- 0xd38f42b3, 0xd45fdfe8, 0xf523b493, 0xed16f7c6, 0x282defd6, 0x79153632,
- 0xdc47213b, 0x9abef7ff, 0x8dd80ab8, 0xc125df82, 0x4fff1c6e, 0x80efb0fb,
- 0xbcf215bc, 0x296bc4f0, 0xfdfebda2, 0x1f5fe189, 0x83947ff7, 0xdde4e273,
- 0xfc058caf, 0xad26a92a, 0x70f5d782, 0x70f3e7ed, 0x159fbd74, 0xbccddf11,
- 0x8e65fb5f, 0xfbdfb788, 0xeff7908a, 0x02ffceba, 0xb38b7a5f, 0x000040d0
+ 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5947809, 0xe77df0d5, 0x9926665d,
+ 0x6c81bc99, 0x44d84eac, 0x4242740b, 0x61db101a, 0x8311688b, 0x9817054b,
+ 0x264f6408, 0xdac7f520, 0x0040cfef, 0x8b435151, 0x03b45a35, 0x341b0504,
+ 0x024180d8, 0x2d82e00e, 0x5d6ad8d5, 0xc8a0d2da, 0x1b80931a, 0xcefc5dfe,
+ 0xc9bef739, 0x82264efb, 0xf5ffffb5, 0xf8f8fefb, 0xf77bee5c, 0xce73ddb3,
+ 0xe28ef73d, 0x8b94c718, 0xff12fb18, 0xdd98c7be, 0xd71b18c6, 0x2356329d,
+ 0xcf2d4ad2, 0x03d058cd, 0xac62ccff, 0x9785addc, 0x653633a7, 0x5ef91a87,
+ 0x4837e412, 0x6de43b61, 0xde549d7b, 0x23e79ebe, 0xa0cfcd6e, 0xc83aa3fc,
+ 0xdeded04b, 0x5065c0f2, 0x6643b9de, 0x91dbb11b, 0xc2963671, 0xe30731d8,
+ 0xcf90597f, 0xc9c0ac66, 0xf61be5b3, 0x45f6c5cd, 0x84e6764d, 0x1577cafe,
+ 0xf20cbcce, 0x86550785, 0x2f37ca55, 0xbe43fad3, 0x60352c38, 0x9f3263be,
+ 0x1ca7685f, 0x3bf50cde, 0x37292d3c, 0x553b18b8, 0x8d5e60e5, 0x4b776ab1,
+ 0x18a3f5ca, 0xcf6f092b, 0xf52576c5, 0x3a970f92, 0x97e6c765, 0xb6bae1fb,
+ 0x97bb3e4a, 0xf12dd2b1, 0xcf923bcc, 0xfff84be1, 0xf91ca358, 0x862f941e,
+ 0xb7e83275, 0x32e4d590, 0xab5fc719, 0xf0dddd79, 0xd3a5553b, 0x7cbe4638,
+ 0xed038c2b, 0x7c969e2a, 0x1b0ac4b8, 0xf8c0340b, 0xb39cbbed, 0x7d70b937,
+ 0x6e11b4cb, 0x1addd75c, 0xe70c2bd6, 0x717a74ef, 0x5cb41b7e, 0xbf592f28,
+ 0xd5182b41, 0x96e95fdd, 0xd579d6be, 0x980d4d0e, 0x53d3a3ca, 0x47798c55,
+ 0x184be774, 0xbf4037f3, 0xb36b094c, 0xff7f7746, 0x96322580, 0xcccbfd8c,
+ 0x1feee8eb, 0x43df4920, 0x013fc16f, 0x6e3da15e, 0xb781ab82, 0xdbfc3ac5,
+ 0xb3b78ddb, 0xd2a3c0ba, 0xdfee6d99, 0x3c401f48, 0x106a7cc0, 0x11ae904e,
+ 0x644cf3f3, 0xdfe81493, 0xc4ba67e3, 0x918f5f7a, 0x9f2ca8d6, 0x420b58c1,
+ 0x78cafda3, 0x116c6bc8, 0x93f631f3, 0xa9fed915, 0x059fbf90, 0x57bce2e6,
+ 0xc4228148, 0x690d6313, 0x24abbf48, 0xffd71b36, 0x94349c03, 0xf407eaaf,
+ 0x99af7009, 0x9649bd96, 0x3093dcc4, 0xbdc4f05f, 0x214fd4e9, 0x3f42a3f5,
+ 0x8fdfcf43, 0xe9639b9e, 0x322dcf47, 0x7ea4a9fa, 0x4fd6179c, 0xeb04ee4d,
+ 0x8c4b727c, 0x7ea4ee7e, 0x2eb617dc, 0xd6898afd, 0x46515cf9, 0xf54e24fd,
+ 0x97d400b1, 0x2d607a0d, 0x5dca197e, 0xef6389f5, 0x98ba6665, 0xdff912bc,
+ 0xa6625c0d, 0x389c848b, 0xfa261d0b, 0xd0f258fb, 0x5bec7e93, 0x44830f22,
+ 0x5f1a3512, 0x5c91afeb, 0x41dfd498, 0xbbfa3bf9, 0x31dc2e48, 0x0eb17021,
+ 0x59b1c0f3, 0x816bc83f, 0xe831eb6f, 0xb129e61a, 0x36bd4c34, 0xefcba34c,
+ 0x261c3956, 0x88dbf80f, 0x683ed023, 0x08911ceb, 0xa4d2f5f9, 0x365c205f,
+ 0x27c11b33, 0x5895664e, 0x48cece2f, 0x9e9ddd3e, 0x826429bd, 0x8041ead3,
+ 0xdfbba97f, 0x0d206ad5, 0xbb2b6be9, 0xb6f48421, 0xa7ac106a, 0x854f633f,
+ 0x14848fae, 0x20a83f68, 0xd769e10d, 0xe3cdbf80, 0x28fe306b, 0x1c19ff1a,
+ 0x3f8e0777, 0xf6f8e7ae, 0xf1963921, 0x2c8b831d, 0x18343be3, 0x177de81f,
+ 0x0f8c55bb, 0xd8c09bf0, 0x685ba1f3, 0x22e0fb7c, 0x8d6eff1a, 0x8fc65915,
+ 0x05ff1aeb, 0xdea5f71c, 0x82643fd6, 0x4b83fd75, 0xf8d7ebac, 0x0b655ffa,
+ 0xb471f8c5, 0x16875ffe, 0x2e0ff5f0, 0xf3b7ebe1, 0xf7c6bb7e, 0x75ffc174,
+ 0xdeadf71c, 0xa2743fd6, 0x9517fd75, 0xe76fd759, 0xcacbbfe3, 0x1a2ef8c5,
+ 0x1950bdff, 0x6545ff5f, 0x0f66be34, 0xb48e90f8, 0x61957101, 0x040d9f18,
+ 0x19254886, 0x6474a7e5, 0xfda0c61f, 0xe084363a, 0xa71c4770, 0x80e2cfbb,
+ 0xf2dd5cde, 0xa381858e, 0x08559e40, 0x9fad2f9a, 0xa59ca1a4, 0x0b7b9072,
+ 0x341754c5, 0xb0dfb4c9, 0x70f0f675, 0x937b6f98, 0x82fcc21c, 0x65879775,
+ 0xbcd8efda, 0xb0a76c3c, 0xf0ff7e08, 0xcd1bd1a1, 0x174e8aeb, 0x5ac7a8d6,
+ 0xe7c47c2d, 0x46cc9a13, 0xa6fcc256, 0xeb8c1121, 0x39031fce, 0xbe7e40ca,
+ 0xd314720f, 0x078c2ae3, 0x9c828fdf, 0x6f999a65, 0x3c7df196, 0x991cdec4,
+ 0xff827282, 0xbc38531d, 0xc2912d8f, 0xd6cfff08, 0x3e50d22e, 0x0789ac2d,
+ 0x23cf77a0, 0xb9d4f028, 0x28de1ecb, 0x08bd3c11, 0x15891b9f, 0xa033fb19,
+ 0xb6801fb5, 0xa5afb6b0, 0xbc2c2ddd, 0xcfea0d32, 0x483f935f, 0x3cdff587,
+ 0xc6563edb, 0x07f983fd, 0xd98f88d8, 0x630e5b00, 0xaad71bb3, 0xe3732003,
+ 0x56fdf56c, 0x0139fb53, 0x22e6fe6b, 0x0d5dbe6b, 0x37d436ab, 0x01b6258a,
+ 0xd2b5bdfa, 0x938c6e5a, 0x78e1f528, 0x20fde315, 0x56f7cf85, 0x67e2c74c,
+ 0x573af09d, 0xf98d6de7, 0x5952ef04, 0xd6cbf684, 0x4ff84664, 0x9d017aa6,
+ 0xbe7a3baf, 0x3f875573, 0xf733e60f, 0x19e0994e, 0xbdd6ff3d, 0x18db7ef1,
+ 0x563f6b48, 0xd7a30491, 0x79ff3d13, 0xa3d7a34b, 0x1f961e93, 0xe9cefe8a,
+ 0x829e9a24, 0x1efa934d, 0x6f2bd535, 0x51efb2b8, 0x6e957d13, 0x17c96599,
+ 0xea58e787, 0x5be6d617, 0x14d617ca, 0xafe7ca5b, 0xe7c9645e, 0xd4b4ee87,
+ 0x9974b79f, 0xcad6fca5, 0x37e52c7b, 0xe4b5ad17, 0xb11e04e7, 0xf671bfd4,
+ 0x6db94b06, 0x20d725ef, 0x25bf551f, 0x3e37dc33, 0x007b1d75, 0x5d4fc1f5,
+ 0x71f10f8a, 0xf88d2aa2, 0x979554e0, 0x4ca6f6d2, 0xc1cb8047, 0x16715402,
+ 0xad086b2e, 0x9972889e, 0x5e2cfc91, 0x1a1433b6, 0xe4adda08, 0xb5c9f825,
+ 0x09008b1a, 0x174fac4b, 0xa6ca771d, 0x94f3d6f2, 0x67a302d7, 0x5b972cf6,
+ 0x6e0f7f63, 0xe508bfcc, 0x00f26f4e, 0x3ee006fe, 0xf7f621d7, 0x8932f2e8,
+ 0x33bf99e5, 0xfcf89cb6, 0x65b3909c, 0x6507971a, 0xcc9bf6cf, 0x8c8f983c,
+ 0xf1aafca8, 0x28a8001a, 0x4f3b5127, 0x2e007a46, 0x50cbd0b0, 0xedb77f0b,
+ 0x155e6993, 0xa3c61328, 0x235bc9c8, 0x1c899ca1, 0x68dd7c18, 0x7eff879c,
+ 0x29aef909, 0xb6f5f699, 0x8f7de9aa, 0x3c9f882a, 0xcd544f4a, 0x5558f4a6,
+ 0x55a3d280, 0x5fbe9445, 0x6b694955, 0x0f4a52d5, 0xfd288557, 0x4a6ad553,
+ 0xa1aaabdf, 0x5aaa9df4, 0x1550ff4a, 0xcabdb4a6, 0x0fc1a94f, 0x4937f25d,
+ 0xaec2abe8, 0xf2879d80, 0x565ac567, 0xe216dd40, 0xf21a5f73, 0x67d759f9,
+ 0x3f1f5023, 0xa19d8efb, 0xbc1bdfbe, 0x77ade9a2, 0x5f49fa3c, 0xfe030829,
+ 0x3b967b33, 0x9c9e38e3, 0x819d3636, 0xf867ba3c, 0x46dbbe13, 0x92415e51,
+ 0x37c90d81, 0xdfa31dcb, 0x75f08c61, 0x7f313c3e, 0x016b98e7, 0xfd1ec71f,
+ 0x7bf6366b, 0x717fec4e, 0x87da6407, 0x0f936459, 0x1b8265f1, 0x3b9d6bed,
+ 0x0f3fbc84, 0x82ea3efc, 0x0660cb5f, 0x274904e9, 0x68db3bfa, 0xb1c20a67,
+ 0xc40c3e39, 0xdc1ececf, 0x5c7e41e4, 0x8fd3669c, 0x918380c6, 0xeba43796,
+ 0xd3fef32e, 0xad9fcd64, 0x9037a691, 0x5c26f63c, 0x4ae91a3f, 0x430e8fd7,
+ 0x6a51a7fc, 0x4d38b3f4, 0xbf028fd3, 0x3432da9e, 0x61dfef81, 0x27d60fbe,
+ 0x5d82bd12, 0xd5fff548, 0x1fade9f3, 0x358c3e63, 0x281c0fb2, 0xe86ca00f,
+ 0x1e9dedf9, 0xd13e5778, 0xcd5f10f2, 0x2fa867ea, 0x5fffc1c4, 0x157ec10e,
+ 0x06fd1bca, 0xfd90e41b, 0xdebdf8db, 0xf3b41e32, 0xb637361a, 0x156e9deb,
+ 0x2ba0cc76, 0x1a1a5790, 0x3a2764cb, 0x92beeb75, 0x9b07c968, 0x7d96e9fa,
+ 0xfc01ff06, 0x4152820f, 0x541329ba, 0x56b8a1d4, 0x23bf304b, 0x2f013f28,
+ 0x2bd78941, 0x016ab477, 0x0b63912f, 0xe5b719ea, 0xbde77418, 0xef208ff1,
+ 0x6546fe4f, 0xdff962f7, 0xae505660, 0xf720c51a, 0x2f9f906c, 0x9635b772,
+ 0x77b940ce, 0xf9f7c6d2, 0x83cf2c05, 0xab114f46, 0xe73d46c9, 0x8e9b6623,
+ 0xfb11fff4, 0x64d3279d, 0x1a6cf86f, 0x6afe73ad, 0xfa0b3eeb, 0x585f2599,
+ 0xb017cd6b, 0xde90536b, 0x2ca9d60b, 0x5a5f212c, 0x9d36bdcb, 0x95642dfa,
+ 0x41dec8ab, 0xbdc6057b, 0x00ca674d, 0x73f95f98, 0x43e7658f, 0xae363bfe,
+ 0x7bf61ba7, 0xff3e1f71, 0xe6b0a492, 0x1a0ff287, 0x19707f33, 0x55e1f6c3,
+ 0x6e42a728, 0x7accdbe6, 0xceebefe2, 0xc6be7a3f, 0x8fc3d27e, 0x6f21e620,
+ 0x18e1fc91, 0x9b34da76, 0x10adf424, 0xbae037a5, 0xbe6b7a4d, 0x2f918380,
+ 0x19dfca8f, 0xe9a7ff95, 0xe859892d, 0xc81488ed, 0xfa7325b7, 0x52417d42,
+ 0x37c0b53a, 0x47ad3fe9, 0xd2ffe5ff, 0xff4207fe, 0xeffe96d9, 0x3ff697fc,
+ 0x57fcc7ac, 0xfcbfeac6, 0x433b6db9, 0x9e4a6f20, 0x60c3c879, 0xd4a93a1f,
+ 0xef00f8a4, 0x7a579b65, 0x284e0e90, 0xf3d20f21, 0x3d3cb0c9, 0x46ec3d16,
+ 0xa23f207a, 0x5da125df, 0xfe84ff85, 0xdf753d4f, 0x3e67dc4c, 0x64eaacdb,
+ 0x47b16d2f, 0x15afc0ec, 0xd833c58d, 0xe11fca18, 0xc8cfbbf9, 0xd2b26f98,
+ 0x0f93c967, 0x0dffa0a5, 0x13d84528, 0x2a97d211, 0xc5cc3eea, 0x3ac8287d,
+ 0xdba2cf89, 0xfae7f8e1, 0xd7cc7c90, 0xc3967a12, 0x0fcf493c, 0x1b04b80a,
+ 0xa3233bef, 0x72b593ef, 0xfd54683f, 0xd4ffa122, 0xc749dcdb, 0xdf6274c0,
+ 0x7941df61, 0x8583c069, 0xbd53feb9, 0x4731e1f5, 0x756d3e60, 0x2648f1bf,
+ 0x767c1938, 0x2ffe61b6, 0x2ef6f79e, 0x9d85db8f, 0x4c2eddd7, 0x424dbced,
+ 0x69e66b6f, 0xa0f11a99, 0x41b65c5e, 0x73e085f5, 0x4f4db6d9, 0xea768a3c,
+ 0x70df76bb, 0xdb74bfe8, 0x00987f4b, 0x6aedd2f9, 0x0cbe0cd2, 0x8dd29497,
+ 0xbffc2097, 0x1e376c74, 0x92f57e4a, 0xbfcd1de6, 0x374fb8ff, 0xefb74a3e,
+ 0x9ee8d8d3, 0xb0d298f0, 0xc5756b4f, 0x91c34bc0, 0xaaafd45c, 0xa1ae7eb7,
+ 0xaf72793d, 0x63d352c4, 0x4bc373c0, 0x9c2027a4, 0x4f028f08, 0xaa8b785d,
+ 0xa0bc041f, 0x14f0373c, 0x9080fe5d, 0x779fd83f, 0xd3f3d114, 0xf95fa3cf,
+ 0xd70fbb3d, 0xedf4f45f, 0x71c75c1e, 0xf5d392a5, 0xfc532b63, 0x1a916e30,
+ 0xe529d14a, 0xff1e8bdf, 0xe15bd121, 0xe14c3f1b, 0x9fbfa0f6, 0x50a6f68d,
+ 0xc2df5c3f, 0xfad037f5, 0xe880580a, 0x3931e8ae, 0xa7e90c2f, 0x3dbe9b0a,
+ 0xc8645f06, 0x6f8e2f9c, 0xd60b8504, 0x12ed1c77, 0x4efeb3f4, 0x7f266f0e,
+ 0xfc8622c8, 0x3fc343ff, 0xfe5316ce, 0x93c70753, 0xbe09b643, 0x4ccf6d02,
+ 0xb77775af, 0x0d4e7e20, 0x1fa2a7f2, 0x9094c82d, 0x25f48780, 0x31bf2bf4,
+ 0x87e3952d, 0xd16c9579, 0x2980f40e, 0xb7eb1df8, 0x18e77ea8, 0x65f63b4b,
+ 0x4bf8f77a, 0xef30f8c4, 0x8fbfdc38, 0x86a2b0a7, 0x55bbeb18, 0xf61ef836,
+ 0x997d1371, 0x7bf39bf8, 0xbf9c3ddd, 0xcf0f7e0d, 0x9fe58e9a, 0x07f9c9bc,
+ 0x08fee1db, 0x52a48af3, 0x25ebbef9, 0x16760792, 0x75d7c589, 0x6b6be0aa,
+ 0x302741b9, 0x304a456f, 0xdff60bd1, 0xfe4fe087, 0xd07582b3, 0x832f24ce,
+ 0x67a79e38, 0x16df067f, 0x251ffe0a, 0xad9ff95b, 0xbbdf7ce7, 0x7da2157e,
+ 0x3f0d4cae, 0x2bf228f1, 0x8bc867f0, 0xe1e6aafc, 0x1fd74fba, 0xc04dc3f8,
+ 0x0c1ba7a7, 0xcfcab53e, 0x7a2d3e68, 0xf484b376, 0xa7a7cd19, 0x891b408b,
+ 0x3df0a7c5, 0xb5169f26, 0x9f953ffe, 0x8faefc06, 0x0f219f82, 0xb463837b,
+ 0xf3633c3c, 0xe5a33c12, 0xc9bdfc21, 0x9fd27bb2, 0xbd067741, 0xfcb2fc95,
+ 0x1817f222, 0x5dd06974, 0x741a5d17, 0x62ffc3d7, 0xf9745f81, 0xa005a460,
+ 0x2a5dbc93, 0xcd6555d9, 0xda0c3cfc, 0x8b203cbd, 0x6da7e4e0, 0x3cbcd58c,
+ 0x0f9cc920, 0xa21be547, 0xf2a3fbea, 0x03f55179, 0x4b4af951, 0x03a6b2fd,
+ 0x47fc231a, 0x4becf52c, 0xc41f651f, 0xfd8c87b0, 0x4678d826, 0x0c5d210b,
+ 0xde50d4ec, 0x0541cba9, 0x1ee0ff45, 0x0ec5ec99, 0x182af180, 0x3d3ea3a7,
+ 0xb1b9021c, 0xf0edc9d2, 0xd3d3bd0e, 0x8995d207, 0xac99df3c, 0x67b942ad,
+ 0x7274ef7c, 0x5e47473f, 0xe4d127a7, 0x2cd238a7, 0x0d6edc93, 0xfcb1e9b3,
+ 0x10a3b020, 0x6f595bde, 0x39ffdce5, 0x5e0d764d, 0x8d68f68a, 0x771343ec,
+ 0x3d1bb2c1, 0x68e92ae8, 0x6ccd7a1e, 0x55f0bef8, 0x3a558e99, 0x70633ce2,
+ 0x57e42c5e, 0x89ec99fa, 0xb3f42c13, 0x6ccfe889, 0x82c576e6, 0x08fa5135,
+ 0x54f4435b, 0xa1a25ae0, 0xe03b053c, 0x973fab7d, 0xe88945f3, 0xb5bd68af,
+ 0x278f68dc, 0x95df685a, 0x03cb59d4, 0x65da3ec2, 0xcb0649f0, 0x86833920,
+ 0x42e7da0f, 0x47934f2e, 0xf01b335d, 0x665071d1, 0xb6799e78, 0x9c7c2659,
+ 0x97e7e7ad, 0xfc4c942c, 0x493ac156, 0x6a701a1e, 0x7ad27e43, 0x3b6d5797,
+ 0x177d9cfe, 0x3fcecdd2, 0xa439f98e, 0x1ddf3b6d, 0xcff31bb1, 0x8ff83dbd,
+ 0x29fd67ac, 0x37e49d7b, 0x26ebd8ee, 0xf3d8ef7a, 0x6177c1db, 0xfc9d977e,
+ 0x3f7b1d75, 0xd7f4831f, 0x845edcb1, 0x1063aef2, 0xf7aa87b7, 0x95a63e7c,
+ 0x8415d7f6, 0xc6b2a3b7, 0xbfe6a3f5, 0x3092961e, 0xdea15585, 0xf89e37b0,
+ 0x93bcf829, 0x7b1d0bfc, 0xb80ecf3e, 0xa9eb75fe, 0x1d39e710, 0x59fb366e,
+ 0xf7225f9c, 0x8f770783, 0xcf0cb4df, 0x69f71ba3, 0xca7ca1f3, 0x831f7f0b,
+ 0x59e3b472, 0xabb50fae, 0x79e38fad, 0xe1fc8745, 0xdce01532, 0x9fd54c8e,
+ 0x1194fbb1, 0x62a34393, 0xe4efe5c1, 0x7850b937, 0x4fb70a68, 0x21e1fdff,
+ 0x73bcb9f9, 0xae121d87, 0x7fc38bfb, 0xd7b0b944, 0xac69744e, 0x32c374f7,
+ 0xb7ce57d2, 0x7fcae1ee, 0xd0b83a17, 0x0b914b75, 0x7fd4f759, 0x5aff7c73,
+ 0xa2fcd2f6, 0x9d27a0f9, 0xf283b9ef, 0x9a3edcdb, 0xfbd205ef, 0x7869ff82,
+ 0xeef0167f, 0xabbaff39, 0xddd7cdff, 0x9d5fde3b, 0xe3aef02b, 0x85f07f79,
+ 0xbefcd3bf, 0xf4db9cae, 0x0dee94df, 0x9b15febd, 0xa80ccdf7, 0xb8d59d3f,
+ 0xb2b8b150, 0x19abff7c, 0xc0cafa50, 0xdf388903, 0x37e751c9, 0xc2a6fa46,
+ 0x92c9a6ed, 0x9641ec8d, 0x907b0928, 0x840351db, 0x496030fe, 0x0321e901,
+ 0xf5cfde06, 0x0ebbc506, 0x195f1fcf, 0xb147df3c, 0x3bec6c14, 0x97ebcc01,
+ 0x9ed5bc8b, 0xfcc4b9fc, 0x603a3478, 0xa20ff7f0, 0xa0703b5e, 0xa42f7a4c,
+ 0xe8beefa4, 0x97bfce99, 0xe7bb1669, 0x0ed5af4a, 0xdab24dca, 0x7f45534b,
+ 0xff9f18d3, 0x0e149734, 0x0f261c03, 0xfa1269fa, 0x570f2747, 0x5cf90499,
+ 0xf6815816, 0xb59754c5, 0xc33c06bf, 0xe1cdf719, 0x380d5768, 0x8797590e,
+ 0x93241c70, 0x70bcf49f, 0xdc1379c4, 0x2f18c232, 0x871f14c3, 0x1f729f63,
+ 0xbd859df9, 0x904d474d, 0x5aab5c57, 0xb4159f90, 0xc81c3997, 0xe5ec36ce,
+ 0x84cde0de, 0x2188adfd, 0x032bf80d, 0xdad3bf65, 0x06dfd91f, 0x3e2ebe5e,
+ 0x537e3c0c, 0x851bbcbc, 0x45ae8197, 0x74ebf20a, 0x62fa17b4, 0x1f9e0cfd,
+ 0xdce85218, 0x570bd84d, 0xa4291778, 0x50cc0cf7, 0x8e855f10, 0x1cf0aba6,
+ 0x6893e1c4, 0xd9b7171e, 0x64707f68, 0x91f70449, 0xdfe50ab5, 0x10e3e9b0,
+ 0x7b2f33df, 0x0c9df4ee, 0x8d7ee6fd, 0xf1e53dc7, 0x7dbf8ff3, 0x8c44e5f9,
+ 0x2c781417, 0x46afff84, 0x167aff3f, 0x2d380389, 0xa1285854, 0x25bdfa0f,
+ 0xefc5bef6, 0xdfe3cd6d, 0xfbba5377, 0xdefd5f39, 0x3abfcae4, 0xd8e40e7d,
+ 0x5df300fb, 0xe1a30e98, 0xfd5db315, 0xaf0e669d, 0x1e1621e0, 0xe42ae3c2,
+ 0xe139d33c, 0x9ffe821d, 0x99b3d3fb, 0xea4ed768, 0xe5c09518, 0x17b230eb,
+ 0x385ec282, 0x3e09bccb, 0xa1d7ca17, 0x79fe7409, 0x8ac77650, 0xec2adc2b,
+ 0x7c625fed, 0x751da409, 0xfb4646ac, 0x1f92758d, 0x60e75437, 0xb7c4639b,
+ 0x9f86abe4, 0xfe0de04a, 0x8f3c6ce4, 0x842fe3e1, 0xbc6609a6, 0xa938cdb5,
+ 0x0789e98c, 0x74df7bfc, 0xe14df51e, 0xc23df68b, 0x35b3ab77, 0xfc862f37,
+ 0x6fc05db8, 0xc82ffee6, 0xf36979ff, 0xefd21b06, 0xcb3675a5, 0x2aa96af9,
+ 0x6cb1b1ec, 0xe66bce2c, 0x0b3ba77e, 0xf65072f1, 0xb0673c61, 0x88168cf9,
+ 0x0d182e71, 0xfd1fec4f, 0x9d555be9, 0xdab76bf8, 0xbae11f30, 0x430723fb,
+ 0x56977a3b, 0x9e6b1a53, 0x9e7cec03, 0xedc3590b, 0xfdffd263, 0xc3a93be0,
+ 0xf68c9915, 0x7e131d67, 0x63fa688f, 0xb767c744, 0xafee30b0, 0x5ca2af68,
+ 0x68cf5b38, 0xdc90077f, 0xf037768f, 0x7eccf7fb, 0xb69b8b9c, 0x82f512ff,
+ 0xc749668a, 0xa50a8623, 0x6d3f4355, 0xc65129b0, 0x6bc3387d, 0xa3eabbc4,
+ 0xc5f137af, 0xf8215556, 0xfbb0981e, 0xe3f71c66, 0x9ea18d36, 0xd3b17fe2,
+ 0xc7f8fb83, 0x07c499cd, 0x57ebadbd, 0xa9aaec55, 0x972a3748, 0x30f4d187,
+ 0x92ce3eaa, 0xf40e4cbf, 0x699afe47, 0x8be25d6f, 0x6befbf81, 0xbc173892,
+ 0xfe16f940, 0xbdbe4cff, 0x80b7c869, 0xa3e2679c, 0xf90f5abe, 0xbe4b1a96,
+ 0xa9bc962d, 0x7bc5f708, 0x5e22a686, 0x26aabf17, 0xdb6f92c7, 0xe739f8aa,
+ 0xb94e2233, 0xdbe411a3, 0xadf24db7, 0x8c5be411, 0x5fbf9078, 0xff0b7ca8,
+ 0x36dff0d7, 0xd6316f94, 0xf9566bab, 0x08f9a636, 0x8d31b7c9, 0xaf3c4b36,
+ 0x7c9f3b5d, 0x47af9293, 0xeaa0f8fd, 0x3f418f8b, 0xfe3e84db, 0xc44b888c,
+ 0xe5ce5071, 0x7f8d3a6a, 0xe2ee72a1, 0xff73950b, 0xe4367045, 0x8c1de2dc,
+ 0xd27b9ce2, 0x8b739721, 0x939c8177, 0x9cb91e90, 0x7187bc5b, 0x7c945cbf,
+ 0xbe43d91b, 0x115faa31, 0x4d83ede1, 0x02df0fe9, 0xabf58dfd, 0x1fd4073e,
+ 0xc6ef2ddb, 0xae5de599, 0x7adc10a6, 0x1783bbc8, 0x0876ef26, 0x6c720779,
+ 0x68d7ca08, 0x5b35f0fa, 0x8f77c1e3, 0x2bff5e3f, 0xcadf97e4, 0x86f8de74,
+ 0xbd0f9f8d, 0x1678fe36, 0x6263d7d2, 0xdc848b3e, 0x510aaf6b, 0xe45e53ff,
+ 0xf1772beb, 0x468af138, 0xd4561fae, 0xfc2f614b, 0x17c27733, 0x78bfce1a,
+ 0x2152c48f, 0xebcecb3f, 0xf38d27b3, 0xc3233632, 0x720b0f44, 0xbfcfc94a,
+ 0xf40e6140, 0x72ba97e3, 0x5bfea24f, 0xfefdc39a, 0xf17be2a5, 0xd0abadab,
+ 0x88fc5dff, 0x46a5e744, 0xe711ab7c, 0xa26e23db, 0x77f91979, 0x6627e3a3,
+ 0x99a9b88a, 0x1bc294bf, 0x947fc462, 0x7fe6b16e, 0x966ff822, 0x62f04adc,
+ 0xe331cbaf, 0x5d7a8c38, 0xe0283a70, 0x7ed32754, 0x802705da, 0x27bd379b,
+ 0x33d3009c, 0xe1ba5232, 0x585bfc52, 0xebef566f, 0xbd16e035, 0x5d7fc36e,
+ 0x0de9fa2a, 0x7b9c060e, 0x1dc05fac, 0x939202ec, 0xa758f0d1, 0x33b5f975,
+ 0xe8094e31, 0xe84ce486, 0x181700d7, 0x70d26f2f, 0x47977dcb, 0xd664fd05,
+ 0xe1829a4c, 0xae30b30c, 0x6a0bca1c, 0x0fdcbd17, 0x1dee31e0, 0x4edc58ef,
+ 0x0f609b2f, 0x56ec39e0, 0x41c92767, 0x35db0e83, 0x141c07ae, 0xbfddddf0,
+ 0xf9d93272, 0x7a8e924d, 0x24e23048, 0xae0106b8, 0xa828ff78, 0x8106fc70,
+ 0x0eff911e, 0x8719f23c, 0x8bc91ee3, 0x635c9dfe, 0x40bc42bf, 0x8e66ccfd,
+ 0x22586097, 0x4eb164bc, 0xa8a97f3a, 0x84117c95, 0x8206d35f, 0xe19f219f,
+ 0x93c665cf, 0x58957e89, 0x4c954bf4, 0xa8a965fb, 0xf35ed337, 0x99e7a407,
+ 0x036caa4f, 0xfbfe1b81, 0x4f3e7a2a, 0x9e34501c, 0xb6bc04da, 0x085d3c21,
+ 0x77ae4eb7, 0xfba0be45, 0x50794650, 0x39e05909, 0x5f73d1e5, 0x0671af09,
+ 0x518e90bc, 0xcbe735be, 0x92682f98, 0x9ef4df58, 0x50f3c5eb, 0xef17bf33,
+ 0x7ffbc239, 0x18b1f24c, 0xba60beeb, 0x8b9e85ee, 0xbcf16e80, 0x8eba37a4,
+ 0xd23b5386, 0xe9bab7f3, 0xe76735f9, 0xe7a44ca1, 0x43f7123d, 0xce5a2734,
+ 0x1e763d35, 0x09d5b5f7, 0xeeeb0f74, 0x6df5557c, 0xcb90c6f4, 0x7ed1ee82,
+ 0xbb37df30, 0xf1821704, 0x141c5ba2, 0x18f347ef, 0xb353f5c2, 0x64e6de7c,
+ 0xf567d7c9, 0x2edbbfde, 0x37278cc5, 0x3f2323f4, 0xf8c3c71a, 0x6f1826f9,
+ 0xd178f764, 0x2fe183fb, 0xfabadf38, 0xbad9bfdb, 0x6ebe718c, 0xb590543c,
+ 0xb88d5e10, 0xe05223a8, 0x73ea2a47, 0xfc4b25d3, 0xc85ccc15, 0x7fdc6fad,
+ 0x7bdc96aa, 0xa74d2cff, 0xebb774fb, 0xe89d77c6, 0xe2674f33, 0xdbe26f7c,
+ 0xec7fefb8, 0x5998e7e7, 0x44d6f636, 0xab263fdc, 0xe3eae90c, 0xa1f92a43,
+ 0xe3ca9e3f, 0xedf9af6e, 0x3e5d0501, 0x3898f0d7, 0x8938cd76, 0xb037acec,
+ 0x87a8f1eb, 0x047f983b, 0xef132fc1, 0xd5d465ed, 0x5f02f14c, 0xae12dd8f,
+ 0xa537d4c6, 0xc435e933, 0x219924db, 0x7dfc5ade, 0x7f20b8a7, 0x032c87fb,
+ 0x1fa0a05d, 0x07b1fb50, 0x9bd63259, 0x33264fe0, 0x27e37c66, 0xf3075e6f,
+ 0xf6487f18, 0xacdea179, 0x03172e03, 0x7ae47a7d, 0xe0980b1b, 0xab858135,
+ 0xfe34dfd1, 0x9c3affa8, 0x3be81177, 0xa8a44f78, 0x07b54379, 0x6a25ebf3,
+ 0x72050c1f, 0x6d9eb03d, 0xbf7267b5, 0xea017285, 0xf5c13761, 0x4eb05ebc,
+ 0x728861f2, 0x8a5af341, 0x93a82a2f, 0xb6e142e8, 0xbc1cc4b0, 0xfa03b0df,
+ 0xda1eb6dd, 0x05fee167, 0xbadfb1ed, 0x875e6f33, 0x49e60772, 0xb9f9ebed,
+ 0xf3b4017c, 0x2dd4bf22, 0xd78afea2, 0xb3ef0c4b, 0x7df3d514, 0xea90e8a9,
+ 0x7dc6f2c3, 0x3b7ed08f, 0x97ebc603, 0x6450fb8e, 0xca0bdd2a, 0x2fba7494,
+ 0xf84c1a19, 0x7f1c60eb, 0xf220fa6c, 0xabbc520b, 0x98a0c097, 0x64fe63e3,
+ 0xb3f2421f, 0xeb4cb7c0, 0x96bcfd0b, 0x236e9c93, 0xe7433aba, 0xde0147ed,
+ 0x1bf78001, 0x40e55e22, 0xab5a07ce, 0xc2fc5f69, 0x9b9f943e, 0x38a24d34,
+ 0x8f2c858e, 0x8e6638e2, 0xebe6fae7, 0xe8c33b97, 0xed5d7be7, 0x0fdf881c,
+ 0xefa76e5c, 0x1cb8dbed, 0x4ad41f6e, 0xebe3f6fe, 0x58f78655, 0x24cbd7aa,
+ 0xabd78e2f, 0x7e563f74, 0x1431c78c, 0xc7fae36e, 0xdfbcf581, 0xe1b7a8e3,
+ 0x439607b9, 0x11ab70be, 0xb4e5c0e7, 0xe8167f61, 0x90c2fe3c, 0xdd62e5bb,
+ 0x75a1f63d, 0xd92434cb, 0x2e5b7968, 0x8b0971e4, 0x2d1cbd90, 0x1cf1cb77,
+ 0x197c83dd, 0xeae6271d, 0x0e9063b6, 0x5d105f22, 0x19521c57, 0x07d231da,
+ 0x9714b96d, 0x73a247b6, 0x92cdf18b, 0x8a1ae31f, 0x4987b1de, 0xcfe70eff,
+ 0x2fee11fb, 0x8619daef, 0x3c431f2c, 0xb1ca9c80, 0xa7e9fe77, 0x1be4fdf0,
+ 0x02088c0e, 0xb827c9ba, 0x59be711b, 0x4f3c799b, 0x52eb1bd6, 0x9b2f3ef0,
+ 0x40e497da, 0x02ccad61, 0x52713926, 0x13775ff2, 0xd4741fdf, 0x667c0c77,
+ 0xb8053569, 0xc1cb7ebf, 0x66ef55f7, 0xd8646315, 0x043d84ef, 0xf51f81f6,
+ 0x6b5de29b, 0x1d133453, 0x9b59ef14, 0x55f7c322, 0x1aa61e22, 0x576857f7,
+ 0x8a71f1ac, 0x06fa4af7, 0x3f4638d3, 0x2edabf46, 0x1ee86ede, 0x7fd6f69e,
+ 0xd68fce31, 0xf286a9f9, 0x1e9fba22, 0x4fd2f7e3, 0xadcfefce, 0x395e6093,
+ 0xac14cbaf, 0x8cc1f39e, 0x1d73e6a1, 0xcafc3523, 0x98da6fd9, 0x9cbf04df,
+ 0xbf31c53f, 0xe38ddf09, 0x7f01ef80, 0x61493757, 0x23f984a7, 0xe516795a,
+ 0x0af3e475, 0x98ae7fe1, 0x1aebcfca, 0x8158de33, 0x4b233f7c, 0xa1607a22,
+ 0x8937d680, 0xfa2f35f4, 0x78b30bfd, 0x8f6842fb, 0x08f8d8fc, 0x13904fe7,
+ 0x1523945e, 0x52e6d7eb, 0x8bc93afd, 0xc86e37fd, 0x28a47d27, 0x5e546647,
+ 0xa3f48477, 0x4923a6a2, 0xb7c0c7c8, 0xa81f50eb, 0x51d76898, 0x68fc1b8e,
+ 0xe2ebf7f0, 0xe8732b3e, 0xc67ef1a3, 0x8be646ff, 0x21f2d7c1, 0xf583d72e,
+ 0x39831f9c, 0xdf5f5f9c, 0x2f0ae2a6, 0x9f89bf84, 0xfce16f8f, 0x43763f2a,
+ 0x2f87de2e, 0xc3efccdc, 0x453f581f, 0x78fa7d43, 0xa6fda258, 0xbd737f27,
+ 0xabbf9a35, 0x7defbe25, 0xe0d2fd5d, 0xe18f836f, 0xaf1c6aef, 0xef14f80c,
+ 0xf5f3464f, 0x0fe1b54c, 0xaf7cc3b7, 0x03d61a79, 0xddf29df3, 0x26ad3d3b,
+ 0x14f90939, 0x3c2817cc, 0x2b90cb9e, 0xfb8f0ae5, 0x8bf3dafb, 0xb76c3f1a,
+ 0x677e47fa, 0xebf1e44f, 0xfdd12a75, 0x07b3f8f9, 0x7f205d9f, 0x9d5f285e,
+ 0xf18d3f8f, 0x7ed63de5, 0x2de8277e, 0x8076bfba, 0xfae0046b, 0x8a26fd4a,
+ 0xa9e8fdf3, 0x3f113323, 0xce81bba5, 0xddeabe91, 0x4e72822c, 0x557ed309,
+ 0x3dd328d2, 0xb244a601, 0xf99b73af, 0x956dc798, 0x7a26e33e, 0x1ed6792a,
+ 0x4bed019e, 0x86307e76, 0x779668e2, 0xe85a5c52, 0x872fa129, 0x1f20c75a,
+ 0x7e3c2894, 0x042e5a2c, 0xd70fdc1c, 0x367e2bb6, 0xc2da4fae, 0x69288fdf,
+ 0x9bb551b8, 0x746e25ce, 0x3a3d46a8, 0x1d010dd7, 0x9c5dfde3, 0x02ddf99f,
+ 0x6dac6e23, 0x2513972b, 0x81d92a4d, 0xb7b65b25, 0xc970fc63, 0x77f2763b,
+ 0xa19cb705, 0x9e5310fb, 0x94fe46d9, 0x396c9360, 0xb711eb7f, 0xd88e45b9,
+ 0xb1b0ee31, 0x211dce9c, 0x0df2847f, 0xcf97e3b1, 0xfa585f17, 0x219d9ecc,
+ 0xafe96100, 0x7ca0f49e, 0xd9b2d539, 0x7e877083, 0xba6e32bf, 0xc3669c47,
+ 0xa7195f3d, 0x01ff0a79, 0x438f738c, 0x9c4635d8, 0xa4be96eb, 0xb2fcc247,
+ 0x739c62f3, 0xdbe5e974, 0xef1c7d3e, 0x7b3db411, 0x6f9c71fa, 0x7e3e3fd9,
+ 0xd8c1e31c, 0x77ed275e, 0xa2dea7c1, 0xdda36c38, 0xb5dfb126, 0xe2927d6f,
+ 0xb5dfdbd7, 0xf6b7b0fb, 0x6307c73d, 0xf6fb603c, 0x6fd0522f, 0x34cf64b9,
+ 0xd92eebf2, 0xc5952531, 0x148c2fd8, 0x017c36e9, 0xf8d1f3f1, 0x8078d03a,
+ 0x023ed6e2, 0xebfca37c, 0x286dbb8a, 0x5ecc71e7, 0x1f5b6f11, 0x8f429efb,
+ 0xebc6daf8, 0xe51cb9ae, 0x1fd7237e, 0xfb671bcf, 0xdbf1e026, 0x7abf8017,
+ 0x1b102fc3, 0x3fe11f7f, 0xa2fb4f00, 0xe369f7f0, 0x8a3c5fc2, 0x7b7d8d65,
+ 0x5c8db38d, 0x7b8cdc00, 0xfc380f10, 0x88c91c87, 0x5c525fe7, 0x866de233,
+ 0x4f9ff717, 0x91fde307, 0x5ce76a13, 0xc7b85fba, 0x68bc63ae, 0x89b79ec9,
+ 0xbc77da7f, 0x26687e41, 0xb3b423ee, 0x3f1e3fae, 0xd675892e, 0xae7c79b9,
+ 0xefc63f80, 0x5df43d7a, 0x3a72e9c4, 0x7b77e236, 0x9d95db8b, 0xee36cf5c,
+ 0xfdd79467, 0x76c3c451, 0x41ca4be3, 0xcaf91d3c, 0x0e036878, 0xddc390ba,
+ 0xe3b1e871, 0x2beebba3, 0xfe217c08, 0x8aea1f70, 0xc0fc8733, 0x7a37e4b1,
+ 0x0790c59b, 0xfc781bed, 0xfb1abb7a, 0x9711b05e, 0x3e688ffe, 0x3c585f0d,
+ 0xffe6f9fa, 0x81d3e175, 0x4f724fca, 0x2dfdb538, 0x774f1cb6, 0x9eecdf4a,
+ 0x7d149961, 0x1cebca6f, 0x473b7187, 0xbb83b434, 0xdeb16cec, 0x6f57e136,
+ 0x78a64a7b, 0x070d55e5, 0xcb478e48, 0x2f7c0a8b, 0x337cc625, 0x9a2b7cc5,
+ 0xf6d13ef8, 0x82ec3bac, 0xeff6da7e, 0xa8ae7a22, 0xd2f1423f, 0x95f96f2f,
+ 0x8b8a6ad6, 0x6c227dc0, 0xd3db7f9a, 0xdc90c6fb, 0x44b2ef16, 0x8c49338f,
+ 0x3d8e6c13, 0x8cfeb04e, 0x50d29c65, 0xcebba683, 0xc529de3f, 0x77f6237f,
+ 0x83eb85aa, 0xe9e41aa7, 0x0fe318e1, 0x77d6aa73, 0xa4bf60a1, 0xfcdc67f7,
+ 0x13d919bd, 0x12e5fa47, 0x093bce77, 0x146a9849, 0x4cbd55af, 0x87fd77c4,
+ 0x5df10d2f, 0xe18abeed, 0x7c22577c, 0x551e7e4d, 0x4bd4300f, 0x2cbcb4d5,
+ 0xcb442bf4, 0xc6c92d1b, 0x2ffc26c2, 0xf54f4f71, 0x644779d2, 0x70f3e220,
+ 0xfb1571c6, 0x9f944bfd, 0x5b0a2fea, 0xfbf30a95, 0x2df2484b, 0xdfd97e83,
+ 0xe794183e, 0x977fd9ee, 0xd963f11e, 0xb0aa57e2, 0xbb461e77, 0xa4e0bd84,
+ 0xaf7906f8, 0x08f9de93, 0xf5a4ee3e, 0xf9f1d81e, 0xff5fa413, 0xb9f8cec2,
+ 0x202f580f, 0xde750aaf, 0x9f1df1c7, 0xd457fe3f, 0x8c31b19f, 0xd438f85f,
+ 0x3ea1bb47, 0x8e9cec9e, 0xa0c61367, 0x85f0a45f, 0x3ca266bb, 0xf4e78c2b,
+ 0x6a4cf858, 0x3bfa1ab8, 0xc7f3cc96, 0x77a20db6, 0x759f4a25, 0x81e8dc53,
+ 0xe055cf1d, 0x4cfed4be, 0xa97dc33c, 0xe7a105fd, 0x53bc52ff, 0xcd7aab55,
+ 0x4cc5e3f1, 0xf3ef9af1, 0x12de6294, 0x2fc8c4af, 0xfe847c41, 0xba04a6aa,
+ 0xaffa0407, 0xd48f9fa5, 0x447c3bce, 0xfcfea1c7, 0x3fa453fe, 0x7ae883ca,
+ 0xcebdf946, 0x395ee221, 0xd77573b4, 0x059d6a0f, 0x9fd35f3c, 0xaa1693cb,
+ 0xf853b0ff, 0xcf79458f, 0x87fd797e, 0xeeeefc84, 0x10afb787, 0xd344d0ef,
+ 0x6fd146ef, 0x5fbf96e9, 0x959deb1c, 0xefa7f318, 0xc858943f, 0x76ca7a86,
+ 0x857fbd27, 0x7de028ef, 0x3f1a9d85, 0x44f32ad7, 0xdd9b9de8, 0xc5971e42,
+ 0x9ddde845, 0x581e62fe, 0xd1ccf31f, 0x9fbd34fa, 0x61939cf6, 0x0bf9595c,
+ 0xbbe23f6e, 0xc7e7e77c, 0x71859e7e, 0x1714f189, 0xffc2fe5f, 0xb7283a22,
+ 0x3f22e647, 0xb3b76e74, 0xdbe7c88d, 0xfc8c1d5f, 0x0646a6da, 0xf38af9f7,
+ 0xbb06f2ba, 0x58bffef5, 0xdaaaa9c7, 0xbbbef0cb, 0xa4b6af71, 0x57f33917,
+ 0x5fa3d727, 0x725ffa71, 0xdf5bbf12, 0x35553a73, 0x59df133b, 0x3897ea30,
+ 0x77c5cb62, 0x137c5e51, 0x71eaee39, 0x9c5df53f, 0x25ac47cf, 0x153efd05,
+ 0x3ca377a0, 0x3e92d92f, 0xfb04fd10, 0x043bc69d, 0x8fdc04de, 0xb25eabf6,
+ 0xef3531a7, 0x7caa2733, 0xf430ca99, 0x54cc8cdf, 0x1b1d1d60, 0x67f414ce,
+ 0x9cea4718, 0x9dee4b1d, 0x3ad3c676, 0x98f61c4a, 0x09cf9df7, 0x8d0f7aba,
+ 0x1e3e64fe, 0xee3187f2, 0x724c357e, 0x2f388ef8, 0xbb012bd5, 0x6e97bf08,
+ 0x79699399, 0xa1a9457f, 0x04a7c07a, 0x4eb662cf, 0x6fc932cb, 0xa5e2bc63,
+ 0x264a9959, 0x4ffe577e, 0xddcabd17, 0x24a16678, 0x01150bd2, 0x9faeb663,
+ 0xa2887ee5, 0x7e1039e6, 0x15d3cb1a, 0x86a54919, 0x358e3df8, 0x7502ea50,
+ 0x5653bf8b, 0x9e4e50c9, 0xe8f6e710, 0x1bb4c2ef, 0xdc92775e, 0x6c620d0f,
+ 0x07be3a78, 0x4dd04de1, 0x10f153f0, 0x5763e61e, 0x1797192a, 0x93b47433,
+ 0x7d8050a5, 0x5d54f409, 0xe9133d35, 0x18fcfe11, 0x07a64907, 0xbfa3cfcc,
+ 0x41ea05fc, 0x3dfca740, 0x70b2efbf, 0xc3188035, 0x3aafc981, 0xe877f199,
+ 0xccc3bf56, 0x71a5c6f6, 0x68e77892, 0x1731c91f, 0x84ebfeeb, 0x94558a3c,
+ 0xff09d5b7, 0x4473c1c8, 0xa822ce97, 0x58bbc617, 0xd7521e24, 0x9994e528,
+ 0x90593dff, 0x3ea9d137, 0xcd1e5ad1, 0xa2d72017, 0xf8206dc6, 0x449fbf41,
+ 0x5449fbf5, 0x557c9fbf, 0x829c06bf, 0x7c3e8d8e, 0x556562a7, 0x1f1b809e,
+ 0x06e021cf, 0xef8919f0, 0x9c5b31e8, 0x13879c4f, 0x6cc4e35c, 0xf01f58ec,
+ 0x4e971e5a, 0x612fb978, 0x41c6276f, 0x865aa4b3, 0x890aef76, 0x97f0d3ef,
+ 0x63b532e7, 0xf0f883ba, 0xb94e311e, 0xc30af380, 0xbea3d53f, 0x1eaff493,
+ 0xd5bd9df5, 0xdf5d8b8f, 0xe27cdbdd, 0xb127cf63, 0xe26bfe97, 0x75fff663,
+ 0x0bc552e5, 0xe786bf6f, 0x49f25db6, 0xf55bd007, 0xd438f2cc, 0xfd8f1333,
+ 0x70be95a3, 0xd031d33d, 0xa438ef8a, 0xb8b7a06f, 0xd1efd661, 0x7d1bd274,
+ 0x40758be5, 0xe00fd5de, 0x7f189370, 0xf73f1d6a, 0xf70965be, 0xe87981d3,
+ 0x8b37fac7, 0x0a3937fa, 0xc470dfc9, 0xbabfdfc6, 0x91eb96a5, 0xa658fcb7,
+ 0xef1ee9f3, 0x803fe151, 0x2a5d6edf, 0xb1e92385, 0x7562d7de, 0x9e6e3f78,
+ 0xbdfa3f18, 0xe6f300aa, 0xbd6396ae, 0xd2e9c557, 0xfd1757b8, 0x9602c54e,
+ 0xb321de27, 0xd4eb3f7e, 0xcd67e4bb, 0x2c7deea8, 0x1ee816b4, 0x7ba04ff5,
+ 0xebc7973c, 0xe2171462, 0x485c78d1, 0x4f3a20cb, 0xd9dfe433, 0xdc04de91,
+ 0x307f99af, 0xeff3aeff, 0xa6f4af8b, 0x2a1def9a, 0xef2ce2e7, 0xbeab54f5,
+ 0xea6f9434, 0xc15fd039, 0x0dced654, 0x39535e61, 0xfcc4ade8, 0x7249be18,
+ 0xa3094d2a, 0x3cf4545c, 0xaf7a8856, 0xa8c3ef78, 0xd55d25af, 0x0ebe67a5,
+ 0x4b8e6fff, 0xbc5cbe26, 0xb6f74bd6, 0xdbcf8b3f, 0x7b24f489, 0x57017c72,
+ 0xed087a4f, 0xc6aeebe0, 0x5cf7a775, 0xf3e6b54f, 0x157dbe91, 0x6ffc8080,
+ 0x4fce073e, 0xf6df7bb6, 0xa37efce2, 0xf4bbf432, 0x44ef8f84, 0x86cfca18,
+ 0x887c5007, 0x0463309c, 0xbc46bf8e, 0x6ababa6f, 0xaa2ba524, 0xbc794898,
+ 0xaf2a8adc, 0xea447348, 0xaa74e917, 0x1a556f77, 0xf95557e5, 0xebe03528,
+ 0xfbd0d5f0, 0x7c618e93, 0xf02e877c, 0xf0136497, 0xe5fe900b, 0x73a4ab48,
+ 0x195ea745, 0xd8df77c1, 0x7077d840, 0xc10d7a59, 0xf919d357, 0xe53ea135,
+ 0x548798ed, 0xf8419dad, 0x564af452, 0xc56fe508, 0x5c228e07, 0x2d4bde9d,
+ 0xd3da5aef, 0x7fbd46c6, 0x836f051a, 0xb871b6de, 0x7a712fdf, 0xfdfb868b,
+ 0xe3178b6a, 0xb2bfee22, 0x82295deb, 0x1c43983b, 0xe7e6bfee, 0xdee13db4,
+ 0x09be7b32, 0xe9eceeee, 0x04fbf704, 0x7016ef9c, 0xa87816ad, 0x46acf016,
+ 0xa47e53b8, 0x3a44fbc8, 0xc47bd29d, 0x112bb7fb, 0x08ca901f, 0x7d878077,
+ 0x30c98854, 0xf179ba1e, 0x7412eecf, 0x1fc8dbab, 0xfcf2bb2a, 0x127b7708,
+ 0x05c3bb87, 0x06ba2078, 0x3cb17bb8, 0x5d54f044, 0x9f50ce1c, 0x15e441e3,
+ 0x7e267b84, 0xb800f8e7, 0x871f8df7, 0x058270f2, 0xe4d25ace, 0x23fb830b,
+ 0x124b7f7c, 0xbf0d1e7c, 0xafbf8d24, 0x6f77f06b, 0x88b571fa, 0xef16aeb7,
+ 0x511c2227, 0xe00879af, 0x4f0e34c3, 0xc8a47dfe, 0x164d28fb, 0xe0357ff6,
+ 0x161fcb01, 0x19c210fa, 0x73c51fd3, 0x56c93cfb, 0x38454fb9, 0xf2efe1f5,
+ 0x1b10a4b0, 0x6878cd98, 0x85a5fe2f, 0xc6f31798, 0x4ad7aff9, 0x44aeb23f,
+ 0x7de903bd, 0xdd6de918, 0xcf0daaab, 0x57a5e43f, 0xcb67ee59, 0x5e89fdb3,
+ 0x42407f82, 0xc13ee6bd, 0x5e916b87, 0x1edc7e68, 0xe0e8295e, 0xeefef16e,
+ 0xee7e823d, 0xa0fcfc17, 0x7e3e3741, 0x74cd643f, 0x9498c71e, 0x20ef1361,
+ 0x4e399846, 0xc0d7d130, 0xd9179834, 0xe94a5e36, 0x8ef64b9d, 0x7e36f89d,
+ 0x7d23f314, 0x6773be25, 0x9b43bf98, 0xa1f50fd7, 0xd9dde344, 0x39c4de89,
+ 0xa23d3174, 0x6520f788, 0xc4b64f6e, 0xdab5df7c, 0x7e81dfb7, 0x13e6de99,
+ 0xafa7f3ef, 0x6be2f184, 0xf54764dd, 0x59cde40d, 0x2d577908, 0xcb0c55d8,
+ 0xc1707cb9, 0xf44d0bbc, 0x5f8bdf11, 0x595d7547, 0xf64af480, 0xa93fa438,
+ 0xf844ea1d, 0xe8bdac02, 0xcd487abf, 0xc1fb87eb, 0xfdb18943, 0xb9e2b370,
+ 0x7593c4bf, 0xb09fc5a9, 0x3b53f54e, 0xde55a27d, 0x43fb13ac, 0xfe56a99f,
+ 0xcb83f630, 0xc59f7f44, 0x0f147e07, 0x6e729674, 0xa4cfc92a, 0x0fef636b,
+ 0xc216aad5, 0x47aa39f7, 0xe50ebe73, 0xee6f5c6b, 0x9d187721, 0x8c0d9c83,
+ 0x2ffe88d8, 0x3396be83, 0x8c42e72e, 0xbac693eb, 0x3ef4867e, 0x9d01f702,
+ 0x01f71ee8, 0x34c3cbcc, 0x5b949ba2, 0x587fe46c, 0x5eecf825, 0x046b5fc1,
+ 0x7c803d5f, 0x81df0235, 0x13fa51f6, 0x90eb4fc1, 0x12dd20ff, 0x78f5ce9f,
+ 0x6197bef1, 0x8c772cc7, 0xab1cf7a5, 0x0fda365d, 0x61ed7794, 0xfb05da17,
+ 0xf7e8ebc6, 0x7a59dd91, 0x59e58dc0, 0x43c03f0e, 0x91d2cc4a, 0x2f733e5e,
+ 0xe2abe8b8, 0xf4fd015b, 0x72a2b0ae, 0x949ea47f, 0x451fdec7, 0x9ef453a7,
+ 0xcb5faa80, 0x70fd3fd0, 0xe113a552, 0x8f3c70fc, 0xcfcdaad3, 0x3e03b826,
+ 0xe29bc5b6, 0x5f6752a5, 0x1f1ef5d5, 0x2f70ff76, 0x12ec12ef, 0x0c0d82f2,
+ 0xf92661b1, 0x7bde2b50, 0x1b10de64, 0xcb139269, 0xf432e787, 0x0f94f5eb,
+ 0xcdcbc8bd, 0x90ae5e5c, 0x434bcb62, 0x65e4377f, 0xd2315cb4, 0xb74d1795,
+ 0x5d54a7dc, 0x66f2463e, 0xc1ff6c64, 0xfcede3ef, 0xf3e66a1d, 0x2cf7a7e5,
+ 0xdefd7807, 0x83d42f0c, 0xf7c57f0c, 0x5a27ac62, 0xcab89e3e, 0xf40357d8,
+ 0xcd02d03e, 0xaff8f0fb, 0xfbad57dc, 0xd5b9e141, 0x9c140fa4, 0xa8b4a1cb,
+ 0x11f13a76, 0x9318d3c3, 0xfd7c7c9d, 0xdf883d0f, 0x7ce2b5e3, 0xc61abd7c,
+ 0x1b7da4b8, 0x0e607aef, 0xe3c175c0, 0xe38f9d32, 0x14d90d3d, 0xbcb2c2df,
+ 0xef1ba7a4, 0xdf0f1e23, 0x31c731ee, 0xe9d4fc14, 0x37bffd47, 0x1f582c7a,
+ 0x8d537fdb, 0x83bb44ff, 0x5da246f9, 0x675dfa01, 0x9fbff504, 0x18dde938,
+ 0x18da1f23, 0x8fc733ef, 0xf15be918, 0xdc21ced3, 0x33f78adf, 0xab9dd217,
+ 0xf4d79d0f, 0xdc7c17ce, 0xc733e863, 0x4547d273, 0x7dc0359c, 0xca7fc596,
+ 0x098f49cf, 0xf473187f, 0xca271e52, 0x7b94bdbd, 0xd3133c78, 0xd3ff9763,
+ 0x3d51a47e, 0xb821b4ec, 0xd3daf2fe, 0x2fa5deab, 0x6280f3d6, 0x60bdc711,
+ 0x79787c63, 0x2059be0c, 0x102f07ee, 0x7d065de7, 0xd0df7f15, 0x465d39b3,
+ 0xd4f4add3, 0x1fa74425, 0x5fc9541f, 0x87f4015b, 0xd4f4987a, 0x698f7a78,
+ 0x3d9713d9, 0xf9c00b78, 0x95324393, 0x10739d97, 0x87ffb65d, 0x3bfce28f,
+ 0xefd2ab7f, 0x70727c26, 0xb7ebc51a, 0xbb9ef78b, 0xedc5cef8, 0x5c5c1bda,
+ 0xbb9c14ae, 0x8bbbe897, 0x35f3c2ae, 0x7382dbe4, 0x565e900f, 0x4ebdef80,
+ 0x788f75c0, 0xe8229279, 0x1fb60277, 0xea1cbb92, 0x3e72b615, 0x15431361,
+ 0x10de8fe4, 0x0637bbef, 0xf2e0df3f, 0x0b45e25a, 0xff50d75b, 0x24c3f40c,
+ 0x02c85c53, 0x8507fbf1, 0xe584b878, 0x21a5887a, 0xd6f908df, 0x77d6ff4d,
+ 0xd69ddbb0, 0xc2e91a75, 0xb04e75ae, 0xebdd61d8, 0x73e72efc, 0xb6146fa1,
+ 0x7579f0e6, 0xe3e7e7ad, 0x7ba7ad63, 0x7da9131d, 0xf1ec627b, 0x1fe317ef,
+ 0x9bc22aab, 0xbc44ac5b, 0xbe105bb7, 0xd5f7c35d, 0xf627d60a, 0x2aeb4c91,
+ 0xc4b52dac, 0xe6d4152b, 0x857afbd3, 0xdbb5f3eb, 0x1753fb4c, 0x97fe425e,
+ 0xc6eb0d27, 0x2e6bfdcb, 0xaea8bc23, 0x7e913bbc, 0x7c553d8f, 0xec5e7bc7,
+ 0x84e9e397, 0x49531a16, 0x4f76eaf2, 0xf74dfbac, 0x56a9e347, 0x80ec09e0,
+ 0x0c9e132c, 0x3fb744fc, 0x8efcb9b6, 0xe21cf0f7, 0x509afe11, 0x0a2bf2ef,
+ 0xe1b1e97f, 0xd7a0a4f7, 0x040fa063, 0xdf7e082e, 0xf5cbc4b2, 0x6f813f0a,
+ 0x77c63e03, 0x08c2e7d0, 0x379127b7, 0x4e3fb193, 0x5b83e70f, 0x1e82f8f7,
+ 0xcf5ec526, 0x59eb5d6b, 0xc7a042ca, 0x3eb8d49c, 0xee7afbd1, 0x05c72162,
+ 0x4f8ba7ac, 0xfa7c2df3, 0x385b9ada, 0x9ffc0a9f, 0xd10f7fdc, 0xbc70b1f5,
+ 0x7a54e30f, 0x486bcf5b, 0xd062e307, 0x1b10b0c1, 0x8f7ffd95, 0xfe684e0e,
+ 0x3ee08f11, 0xee15fb02, 0xde4fc5d3, 0xbf3cc63f, 0xfd27e2b7, 0x9aa5f69e,
+ 0x0ea73b0b, 0xf41df64d, 0xfb277ed2, 0x434961aa, 0x633f815d, 0xa3cf12fb,
+ 0x6e9fa19f, 0xc6cfe245, 0x578bd2c4, 0xc72e0556, 0xaaea8bf3, 0x8fd1cba2,
+ 0x973d0aaa, 0xce9b9ea1, 0xd623177f, 0xcdcc7d7b, 0xaab2bbf1, 0x983fce92,
+ 0x94f4c423, 0xd80077ee, 0x47f24c89, 0x7eab2e2b, 0x1d01a9a6, 0x789adffd,
+ 0x025540a7, 0xd0b3d3ab, 0x1194945f, 0x1fefc132, 0xb2ee7e2e, 0x8ebf6d26,
+ 0xe8761ae7, 0x8e60fd1f, 0x8b59ca81, 0x6545ecff, 0x93c05f41, 0x1c731cf1,
+ 0x124bf06b, 0x46cf13f9, 0x5acf13f9, 0xf30491e6, 0x5b3b0afe, 0x1ce87871,
+ 0x8fc26152, 0x5f01e02c, 0x5bbb1f68, 0x1e5cebe7, 0x607d21ef, 0xb23645d5,
+ 0xff09d6eb, 0x2fd0cff4, 0xe851704d, 0xe0c301bc, 0xc096beb0, 0x73c4e1d7,
+ 0xaded190c, 0xf8dde508, 0x4f4c9762, 0x4f984a1f, 0xf3095e64, 0x1564597d,
+ 0x931d0fda, 0x3f20ef5a, 0xe69033a0, 0xd67ebc06, 0x84b0e5af, 0x817912e7,
+ 0xb5ce118b, 0x0bc32872, 0x77217ff5, 0xc1bd6066, 0x1f4ef450, 0xf7845e9e,
+ 0xf3a60212, 0x8eb421ce, 0x33dcbcee, 0x2552d17f, 0x6feffcea, 0x5fcb9b17,
+ 0xc62ffa71, 0xf93b5479, 0x1f4960fb, 0x57be7448, 0x94ee75dd, 0x64f2fb47,
+ 0xd123c737, 0x41d5d205, 0x559d37ae, 0xc87d09bc, 0xf3323d9f, 0x7c3ccb45,
+ 0xec22bc96, 0x53a03ad1, 0xe832a73c, 0xb7e29863, 0xaf0d1d21, 0x3c66ef81,
+ 0xfb77d0c6, 0xf079e8b8, 0x31b9fa98, 0xe897183f, 0xcb973e55, 0x7a28e3f7,
+ 0xf9f12dd8, 0xdced8a87, 0x1921646e, 0x20c73af1, 0xcf05653c, 0x8fe33227,
+ 0x8d77b5ec, 0x82b62773, 0x0b9e75e7, 0xb9cfc6de, 0xa733e7a3, 0x3c16eef9,
+ 0xdcd399ef, 0x7b9e3e6f, 0xf8ba29ce, 0xab774c43, 0x51e3fb9d, 0x2250fc5e,
+ 0xb7a6f67d, 0x21e3545e, 0x46e6f1dd, 0xae609f7a, 0x73bfef9b, 0xf88aa759,
+ 0xe35d300f, 0x5a6156e7, 0x27cc6ddf, 0xfa2a0df2, 0x84896e1d, 0x721ab86f,
+ 0xbe18beb7, 0xb9bdd51a, 0x425f3b07, 0xf41a05b4, 0x321b3a5c, 0x5ef935da,
+ 0xaede79e6, 0xf14e0e0b, 0x838a47fb, 0x6ebdd5d6, 0x58c1c107, 0x7c24d427,
+ 0xbc49c174, 0xa5c066cf, 0x37f1dd6b, 0xf8fe855f, 0x1cdce4de, 0x790fe8c7,
+ 0x579f3c9c, 0xc13e9c34, 0x0b939022, 0xb91ffedd, 0xb77afca1, 0xcb4c2eff,
+ 0x95839d1c, 0x5537c421, 0x0390af98, 0x1c00a517, 0xb8141a3e, 0xd1e11938,
+ 0xf482f7d2, 0x2e4ec3fe, 0x1ba70e0f, 0x1bab6d7a, 0xc8bd9be9, 0xf7e35af5,
+ 0x38ed5632, 0x008dff7e, 0xe55e8f9f, 0xcb95cdef, 0x22ee6bde, 0x62ccb2ff,
+ 0x7a4621d9, 0x1e0df858, 0x7bc4db76, 0xf39d7cd1, 0x79ef0e14, 0xcf74f18d,
+ 0xd952de6e, 0xbcfdbef2, 0x957e3ca5, 0xae632d29, 0x2b09d8b7, 0xecf75d04,
+ 0xd11afd07, 0x3a5fccfd, 0xd92dde99, 0xc893e9a9, 0xa738f1cf, 0xfd53f9b3,
+ 0x4ffdc632, 0x1f912d58, 0x6f51fc69, 0xe7e42b53, 0xc87d1387, 0x5ceff3ae,
+ 0x97ef899c, 0x3f70b454, 0x28bcaa67, 0x7d203fe3, 0xefdf3f68, 0xe108bf31,
+ 0x5d7bf2e4, 0x369af3a6, 0x474332b5, 0xe5d5be7a, 0x7f907947, 0xc45dffbd,
+ 0x30e7e1a7, 0x40e7ddf6, 0xce38c00f, 0x39bc5bfc, 0x0df91f48, 0x0ea53f4e,
+ 0x5c81c4a6, 0x039857cb, 0x298d54d3, 0x98e34c4e, 0xe5ecd303, 0x9daa7f42,
+ 0x2783fa45, 0xf7c34f27, 0x9f9bf3c4, 0x17db14fc, 0x927d912a, 0x9bf29e89,
+ 0xee82fd5f, 0x28f3f9c3, 0x5b5bf74e, 0x39dd8b34, 0xff9ac1ba, 0x9f359376,
+ 0x33e6b111, 0x03f35a0f, 0x7d266d70, 0x1e1eff73, 0x9a7a529f, 0x1e7defdf,
+ 0x3c22a060, 0x3e49d9b6, 0xce6d294e, 0xd38778c6, 0x586dbb4f, 0xdceffbbe,
+ 0xeadceeee, 0xf72577a4, 0xe2c717bd, 0x6a1df092, 0x3f2c46e7, 0x8d90d71d,
+ 0x4fa845fe, 0xbbb04b71, 0x71bb408e, 0xbd06a5e7, 0x69be2986, 0xfdf83fe7,
+ 0xf6adce94, 0x9c51c630, 0xd3e4f5de, 0xb7a79f48, 0xec7d200e, 0xc3642979,
+ 0x70f7437e, 0xf3884ffc, 0xe954e458, 0x7e3dab16, 0x1d01e842, 0xe879b527,
+ 0xd6b8ba17, 0xc24beeba, 0xa8a77cd6, 0x7d331b7f, 0x10f8c74f, 0xdc34aaef,
+ 0x7ec53767, 0xc173fdbf, 0xa53d4f17, 0x8b2b7419, 0x37991ef7, 0xe2befba5,
+ 0xdb73eeee, 0x8e800325, 0x4316114a, 0x4697bfba, 0x0f85db8d, 0x38927fd1,
+ 0xadfceb2f, 0x5539f04c, 0xef896455, 0xaafbd2e8, 0x4d53697c, 0xed4151fb,
+ 0xd27c94be, 0xdca5f757, 0xca67da66, 0xb9481eb6, 0xdb6bfa19, 0xebefd0a2,
+ 0xe279cd95, 0xf8490981, 0xf9c06e5d, 0xe7fa3962, 0xf25e1ada, 0x8bd03d60,
+ 0xbde39ac7, 0xa5c76b0a, 0xe9f1354d, 0x834ba5d7, 0x0e74ca9f, 0x5a72e79f,
+ 0x461ef172, 0x1dff2d69, 0x1b86d2be, 0xe11abbae, 0x4fdf9ebe, 0x9e5856cf,
+ 0xb653fc0c, 0x8fef86fd, 0xc7c1ef86, 0x3e70f9c6, 0x2d24f8d9, 0x3fadbbde,
+ 0xee76f743, 0x44ff71b5, 0x7b465c34, 0xfdef7e38, 0xe508ab81, 0xa2f7f412,
+ 0x3fb52c6d, 0xe47d0368, 0x6bd0e4c4, 0xd3954337, 0x570fe1ac, 0x95965c53,
+ 0x253e809e, 0x373ab7d4, 0xf48dbe4b, 0xb5f67975, 0x97fb5aa8, 0x943a3c51,
+ 0x8a37b4c7, 0xa27ed6c3, 0x47a57cf1, 0x68f77e32, 0xa25e99a4, 0x119df5eb,
+ 0x2ab7dfa2, 0xcd720a5b, 0x1d97efa4, 0xd878a1ad, 0x19c871e8, 0xc13b8a68,
+ 0x7c4bd1fd, 0x027a14ec, 0x22d91c93, 0xcf287c5e, 0x48a7bbd3, 0xa5104097,
+ 0x5ea9b297, 0x6cb5eb84, 0x4bcfa63a, 0x99640791, 0x33f203cb, 0x79278b6d,
+ 0x3eb7a6d0, 0xa3a473f1, 0x1e74d1fa, 0xefdc5fd6, 0xe846f36e, 0x77e358bd,
+ 0x9e74da71, 0x5276692f, 0x8fe9d53c, 0xcb979234, 0xeb138e30, 0xd9b4ed3f,
+ 0xbd3b5f40, 0x8c64efbd, 0xe06b6e0b, 0x6a9f8aef, 0xfb593be8, 0x9a37fd8a,
+ 0xf17d8def, 0xdf13fe08, 0x8bf8f54f, 0xacdfb83d, 0xa9d371e0, 0x2a332b7d,
+ 0x68c9e063, 0x6655a497, 0x79d2bda0, 0x91b7cbab, 0x0ae953eb, 0xc8d3ddf9,
+ 0xfc2f92af, 0x79e9f749, 0xbea07877, 0xe1faea1b, 0xe5073eff, 0xfc77e88d,
+ 0xa1ddf640, 0x1f3eed0f, 0xa015905f, 0x03f4e3fb, 0x7cfe3036, 0xa0144585,
+ 0xafb8f9b7, 0xc93ca18c, 0x25ebf9cf, 0xb05c238a, 0x7c1ebac6, 0x1fbcdae7,
+ 0x292fe116, 0xb0b8c50e, 0xd68b4a06, 0x718bcb5b, 0xbc50f0ff, 0x94cbc517,
+ 0x19cb59d4, 0xad1f908b, 0x7b4bfeac, 0xca7db82c, 0x6bf9f58c, 0xa3b9163c,
+ 0x50f9dc92, 0x95f5a3ce, 0xd20037a2, 0x1cfec49b, 0x6d2733bc, 0x4b1da401,
+ 0xc82da427, 0x7cee7bc4, 0x8ed3231f, 0x8fbf98f8, 0x45953a57, 0x7177f106,
+ 0xa58fee18, 0x346452cd, 0xe42c1de6, 0xe3bfcb19, 0x6eb820fb, 0x63313df3,
+ 0xf35eb8dd, 0xc726f677, 0x10cf71ab, 0x2f2e6bd7, 0xab287013, 0x3afc5bb7,
+ 0x90a5ea13, 0x7f78dbfb, 0x55da95a9, 0xb7697e34, 0x5ff62bf4, 0x1399b7d8,
+ 0x68a135f0, 0x798b8c83, 0x878e4ba8, 0x0f75892f, 0xdf80b0e5, 0xf4143743,
+ 0x107d7e43, 0x02fecff5, 0x9f2439c0, 0x45809f84, 0x5c5e301c, 0xca9e5766,
+ 0xfcf397b3, 0x8ae04f3e, 0xaf6081da, 0x873a01a9, 0xbde72f9a, 0x471bf78c,
+ 0x425e0626, 0xf9b7ccbc, 0xb7c42b07, 0x17e411fe, 0xf0e1ca5d, 0x4bcad8f0,
+ 0xc5d9632a, 0x933fbf02, 0x3e5ce81a, 0xa3ef8bb4, 0xd54eacee, 0x8bfef7ec,
+ 0xfb094790, 0x4f5ee95b, 0xee890ee7, 0x1d223f13, 0x8fb6fba1, 0x6865e95c,
+ 0x9e01a7c7, 0x223eee50, 0x5ef815b1, 0xace3565e, 0x9e212f45, 0x787ce2b3,
+ 0x38de5fde, 0xd1772e49, 0x15beb9fa, 0xcf01b95f, 0x8de75283, 0x0e748b1c,
+ 0x2d779eeb, 0xe3d0ff7c, 0xb9faf1a5, 0x96d3de38, 0x8f17d287, 0x16f3f1c2,
+ 0x387c84bd, 0xa1ee8e3a, 0xdcac02a7, 0x8d5d287d, 0xcb1a547a, 0x60fa87d8,
+ 0x58ef0cda, 0xe43fb9f4, 0xdb24e3e1, 0x50b379e4, 0xf3cb1bcf, 0xf92c7e7d,
+ 0xae111237, 0xed5271a5, 0x17ce3a6c, 0xe85ea3bf, 0xcb823f40, 0x9529ef84,
+ 0xea7e3819, 0x69269e50, 0x3c0f8a11, 0x99bde064, 0xd12de9c7, 0x25e9c919,
+ 0x454a4c5f, 0x1b50ee3b, 0xbf20d418, 0xec340d0e, 0xf48b88cc, 0x792361f0,
+ 0x2df7617d, 0x5ff7e0c9, 0xfa1b0692, 0xa1d7af0f, 0x513213fa, 0xf5c1beae,
+ 0x7e5c4ff1, 0xa65f57f2, 0x4fbf8ec5, 0x0a78e048, 0x61638b9e, 0x3838ff93,
+ 0x13d233fb, 0x2c3ce783, 0xf027da6c, 0x1c734dbd, 0x7ed15977, 0x72841dfa,
+ 0x01f742d6, 0x71ac1bca, 0xc5c597e7, 0xf3a0d71e, 0x0b1b39e0, 0x1e3225f5,
+ 0x21d7f688, 0xc2d573a9, 0x4b17ba24, 0x73c13be7, 0xc6990b1a, 0x63eb9e0f,
+ 0x33cd77cd, 0xaee9fa85, 0x9af5acc7, 0x2c7aa73e, 0xe383d5a7, 0xb4adebb4,
+ 0x29cf048f, 0x6fd8ced4, 0x90b6c23a, 0xeedcfc0a, 0xe21de5e5, 0x6fa8cf3c,
+ 0x5b3ed7f4, 0xf8def713, 0x556de8bb, 0x2e007820, 0x219f368f, 0xf359747f,
+ 0x418b823e, 0x89f0dd0f, 0x7c132167, 0x225baa52, 0x69ede036, 0x7bb86e0f,
+ 0xc990d814, 0x871f05fb, 0x9feddd36, 0xbbf8e508, 0x8ebe260f, 0x73e2eacf,
+ 0xd90f3312, 0x42172e64, 0x9d4f7775, 0xfa8bca68, 0x9b43ed5d, 0x340a98af,
+ 0xb78a3595, 0x27c1e6bf, 0x4e4e595e, 0xdf111a8b, 0xcf3839df, 0xa23bca6d,
+ 0x8fc82ef2, 0xa8f5e536, 0xf2a8a4f2, 0x40fca8b4, 0x1dcdbf5e, 0x40fb2c19,
+ 0xd4f83fde, 0x9efbf815, 0x7322fd6d, 0x358f05f1, 0xf02bb6f2, 0xb3cb7cf7,
+ 0x56d3eff8, 0xc93e4b34, 0xba2b3f24, 0xb55bf3ce, 0x0e10a3f9, 0x1ca32f2d,
+ 0x74926b28, 0x0d5debd4, 0xc79423db, 0xbb535e76, 0x963f6e06, 0x76a11c35,
+ 0xd23ff6bd, 0xef7c7c46, 0xdea9f7c8, 0xd89fcef9, 0x5befeb0c, 0x751e76f5,
+ 0x4e2c0a44, 0x7f7eee48, 0xdbfb6dbd, 0x0a2fbfdd, 0xf9fbdbdf, 0x8d1c900f,
+ 0xc41e07ba, 0xf9bab8f9, 0xbde380c4, 0x7bd2cf23, 0xdd1c7fb4, 0x03aa16fc,
+ 0x2cce4bf1, 0x9fdda053, 0x438f8fcb, 0xb4df0b7d, 0x67e37dc5, 0xdc12f852,
+ 0x81651e8f, 0x5bdc704b, 0xc3ef87cb, 0xac384c9f, 0xef863eb6, 0xf0786f95,
+ 0x98142be5, 0xeb7761df, 0xb709fc20, 0xf06f094d, 0x7f2b727c, 0x1dff4551,
+ 0xa0f0e7e1, 0xc83641d6, 0xa6c0993f, 0xeb787e53, 0x3d7f9863, 0x3faf04e1,
+ 0xac9075ba, 0xf27209a3, 0xdf90a98a, 0xf7e6c7ac, 0x37ae04da, 0x369bf31b,
+ 0x8453ffdc, 0xfbe32b0b, 0x76335e0d, 0x5b9d3c80, 0x66db6a72, 0x1fdcc780,
+ 0xdb9c93c5, 0x55dd76dc, 0x50870479, 0xa611c61e, 0x7ed3780a, 0x215d7248,
+ 0xee1fa27d, 0xf1ba7d81, 0xe2dc1ee9, 0xd2e2fda5, 0x37a8edca, 0x451dcea4,
+ 0xc7a145fb, 0xddc9e92f, 0x52193869, 0x3ae92fa8, 0x8db2eb97, 0xef5223e2,
+ 0xf51e9372, 0x033df8a0, 0x0fa23be0, 0x36cbc097, 0x096d9eb1, 0x80f6bfdc,
+ 0xf3f51a67, 0xc47fe49e, 0x42ca6321, 0xc5a7f24e, 0xf372be91, 0x202b9006,
+ 0x7989d7d7, 0x097b5baf, 0x466e29f9, 0xfc28f13f, 0x67d7efee, 0xbffeb754,
+ 0xaef2032e, 0xdd6ebb6e, 0xf33f7f2c, 0x0dbaf6b9, 0x5b90dcbc, 0x7b79d2eb,
+ 0xad4abf63, 0x3ea4e3e6, 0x5c46c978, 0x28c2bc47, 0xece17b7e, 0xd1971b11,
+ 0xad2d7ffe, 0xfdfdf99f, 0x5a3f0ed0, 0x7a86c43c, 0xc29f81a9, 0x1257fee1,
+ 0x89373d60, 0xf035efdf, 0xb74f8c64, 0x907f51e2, 0x3b407f41, 0xeb403135,
+ 0x0c627d07, 0xfae06e0f, 0x3316d204, 0xad2997c1, 0xfffbf0e3, 0xfdb53820,
+ 0x4ff4e02b, 0xc947779f, 0x0c379021, 0x7a5f2ffb, 0xedff72dc, 0x23d1013f,
+ 0x8000702a, 0x00008000, 0x00088b1f, 0x00000000, 0x7dc5ff00, 0xd554780b,
+ 0x733ef0b5, 0x9992bcce, 0x924c2664, 0x84e3c849, 0x71100840, 0xf0444312,
+ 0x51888431, 0xd4503b69, 0x20717ad8, 0x9926023c, 0x4b62d5a8, 0x79120cff,
+ 0x22341809, 0x0281c150, 0x06f55bc5, 0x701a8c45, 0xaf7a8a44, 0xb7ad8ef6,
+ 0xff7f6c57, 0x4a8f8808, 0xd2f5a232, 0x5ad7fd97, 0xce64ef7b, 0xb6b4a924,
+ 0xdc3ef9bd, 0xd9cfb3ee, 0xd7b5ed7b, 0xf6b5af6b, 0x4cf5a61e, 0xd8c05c0a,
+ 0xce6a2566, 0x7c2c64ae, 0x61edf148, 0x67cf07f0, 0xf7fb193b, 0x95d5a0b4,
+ 0xf19fd8c9, 0xe6c60aef, 0x2729bf7e, 0x8ded0658, 0x61cb1823, 0xcfbbf52c,
+ 0xd500ded4, 0x7a3f4bb9, 0x3f7c0f7c, 0x8ca97bf7, 0x43ef03e9, 0xf7c18c8f,
+ 0x5b6dbcef, 0xd2842ecf, 0x793519d2, 0xf986bca0, 0xef7bc056, 0x27435898,
+ 0xbe0ef7f4, 0x5563097a, 0x35e5bbdf, 0xdbb19136, 0x93632a5d, 0xf8ab5b18,
+ 0x258a9873, 0xbbe0db0b, 0x644b2cf0, 0x7d63114f, 0x0cd85311, 0x23b875fd,
+ 0xb8c1175b, 0xf995d71d, 0x1f5fd0c2, 0xef867e63, 0xf7a54b2d, 0x4c3ddc3a,
+ 0x744bf6c3, 0x0ec24017, 0x19faa17e, 0x5a37e3d4, 0x7814bb22, 0x76c2ce5e,
+ 0x3e325f6c, 0xf3fa8612, 0x7f7d0e30, 0x0f644a63, 0x8f82cfb6, 0xa371dea0,
+ 0xfe861237, 0x47622cec, 0xfa763a78, 0x8c1c3273, 0x05acaae5, 0x8228efe1,
+ 0x2b59943a, 0x0701cdd9, 0x713fcfe2, 0x0f007396, 0x6899775f, 0x3d95a93e,
+ 0xf437ff4f, 0x7ddbd6c7, 0xe1b0a063, 0xcf6f58ab, 0x3b997826, 0x66f88558,
+ 0xb803fc1a, 0x89c81fea, 0xcce7c3ac, 0xb1eb8557, 0x479fe9da, 0x5520fff0,
+ 0xb61ff847, 0x0ab635b3, 0x66d61528, 0x0bfc00cb, 0x43fb5878, 0x37630c00,
+ 0x978000e3, 0xd670d7ff, 0x2bf3c3a9, 0x07ad0a5d, 0x556df9fc, 0xbc67cd8c,
+ 0xd4f2fe7d, 0x58899577, 0x1a6b51aa, 0xa5735b3c, 0xef46c7bf, 0xe28f3fb1,
+ 0x0bfa0da5, 0x25b7f132, 0x09ba44ee, 0xd86977e2, 0xba9defff, 0xfdf0eb03,
+ 0xf8765c44, 0xfbe074be, 0xf9a3173a, 0xfc3955cf, 0x475535ac, 0xc8fc4afc,
+ 0xd7c24eb2, 0x713f90fe, 0x724e393c, 0xfcbaf7bf, 0x00be2237, 0x0f74d1ef,
+ 0x75a545e2, 0x63d7864d, 0x43b06f89, 0xd556dcfb, 0x33e0377d, 0xf349ccb8,
+ 0x9cdef095, 0x158cbf1d, 0x74ffee0f, 0x8695736a, 0xe9c65ff3, 0x02b72d9d,
+ 0x62f112e2, 0x5d03a819, 0x63f1642c, 0xe7886526, 0x8445f45a, 0xc247517f,
+ 0x2fdff4f7, 0x49ef89ac, 0x92ba617e, 0x2ba0bf04, 0xdd70d15d, 0x375f0a82,
+ 0x373e258b, 0x6e183650, 0x82d5cf89, 0x245d24ee, 0xe2357be3, 0x7c60d27b,
+ 0xf93d2c7b, 0x99706fd8, 0xdc94f095, 0xfa11633f, 0xf03b21ee, 0x16ddd00f,
+ 0xdd7a2145, 0x646a5772, 0x3da7f225, 0x19f117be, 0xad157c3a, 0x1492ef77,
+ 0xdb2bc19d, 0x9441302c, 0x9c9d8733, 0x4a7a4b8f, 0x617a9f90, 0x9f587ece,
+ 0x9dd5d7de, 0xc1024561, 0xeaebf358, 0xdeffa42e, 0xfde6af67, 0x19d548ac,
+ 0x618843d4, 0xfe143718, 0xbc032b43, 0x2cc5349e, 0xe0175e34, 0xff09c257,
+ 0x435fe17a, 0xe8bc80c5, 0xbf1c06c3, 0x9807cb8b, 0xe71a12e1, 0x1d6c29db,
+ 0x526cdb8c, 0x6f6826fc, 0xb23e3a5e, 0x4361c392, 0x20146a3e, 0x9b589b35,
+ 0xf7c03152, 0x2513a6cd, 0x36f195b7, 0x85bbde0d, 0xf78175f1, 0x5f002a8e,
+ 0x4c7d6da3, 0xfa45ba45, 0xd8a5f687, 0xff80345e, 0xf9bff5e6, 0x7cdfc213,
+ 0x8d1748c0, 0xb1e7198f, 0x8a9e9134, 0xb524e806, 0xd589e392, 0x8018c8b0,
+ 0xa9ea29d7, 0x8a88b1b5, 0xcd565a78, 0x66e9024e, 0x8199e91e, 0xecace3f4,
+ 0x0ca1f364, 0x11fcc07d, 0xf74a7b80, 0xc24697ce, 0x58daeefb, 0xb4374e3e,
+ 0x4e8bb6ec, 0xbeb0345d, 0xba4bce12, 0x41cca937, 0x0077d1e3, 0x83bf7f8a,
+ 0xfb371bde, 0x6ef2c482, 0xa4d32efa, 0xe0f6bd12, 0xcd1be423, 0x38c0a39f,
+ 0x328c979b, 0x82a67ae1, 0xbcb9437c, 0xaeec7db0, 0x7f678415, 0x07b7ca09,
+ 0x09ce80d3, 0x942abe9f, 0xeaeea52f, 0xbfa0bb5f, 0xffd5dca7, 0x138e258d,
+ 0x47f4e270, 0xa648be90, 0x23bd64e7, 0x6e2ecbdf, 0x0c716f29, 0x17f01eff,
+ 0x35be2de1, 0x4d0fcb9d, 0xffa2faa1, 0x475cef30, 0x374469f0, 0x222f6db7,
+ 0xdac0dc79, 0x591ade89, 0xbbf482c4, 0x69c2c6c8, 0xe08b1740, 0x172874b5,
+ 0x3d32b16f, 0x4496fd61, 0x2146f58c, 0x31616e0f, 0x7d96fefa, 0x2c35ed49,
+ 0x26f684ea, 0x62a68b1b, 0x6f6c69d9, 0xef417166, 0x3e26b67f, 0xbe7c1d67,
+ 0x77758b37, 0x20d444d7, 0x1dab7bcc, 0xbe065774, 0x33eb4ed0, 0x5a4ef965,
+ 0x7f0af4cf, 0x4fa83dd1, 0x76fb355e, 0x27bedd01, 0xe7e24bd6, 0xbbf5575e,
+ 0xd514f788, 0xdf8ff344, 0x9cfc2563, 0xeb8dbd02, 0xdd9b9f7f, 0xdeca1b3c,
+ 0x7a3bdd56, 0x55c9a234, 0x1839db30, 0xb39eebcf, 0xb8dd2037, 0xb7c226dd,
+ 0x65cc7e7c, 0xddd57aa6, 0x522bff02, 0x088abb23, 0x9e9113dd, 0x7d4946aa,
+ 0x82ce26ca, 0x5666bbfa, 0xe6f509d7, 0xec411deb, 0x07ed07af, 0xb9b817a8,
+ 0x5b7028de, 0x2eb27e68, 0x06e92be7, 0x52fea1c6, 0x84a5e22e, 0xc85b8c63,
+ 0x7f89b641, 0xe6eff427, 0x493b2925, 0xafd3f6ff, 0x96fd1189, 0xd7882c05,
+ 0x795c84e7, 0x3695ca4e, 0x9a2b972b, 0xa832ee6b, 0x9941f73f, 0x95e01d6f,
+ 0x83de8295, 0x4a3f1bef, 0x5e9e91d1, 0xef5fe8f9, 0x9fb419fd, 0x5ba2c0fd,
+ 0xd2017da1, 0x73dbac18, 0x6047970a, 0x8fd4307f, 0x38f6c08d, 0xb1c1e36e,
+ 0xb41c7f64, 0xc846fb08, 0xe0b4c6cf, 0x4fd085d6, 0x3e9993e3, 0xbcf664a0,
+ 0x5ee8f239, 0xf7643f6c, 0x1b7e81ed, 0x1b5e3853, 0xdf491b9f, 0x4e0f613f,
+ 0x733cc377, 0x3c9f91ad, 0x05e37281, 0x677bd92b, 0xc2117459, 0xaed3b67f,
+ 0x70277be0, 0x4250e95e, 0xeaf3829b, 0x043d9276, 0x10b39a7c, 0x36b93bbe,
+ 0xe04bcf9b, 0x0986e4e9, 0xcd9b17c4, 0xb3f0bc7c, 0xc27fbd0a, 0x0391981c,
+ 0x974f13f5, 0x534056fb, 0xb512c05f, 0xee873d00, 0xbd5e76e3, 0x7881df49,
+ 0x09538762, 0xa11eb95e, 0x62678b8d, 0xf2e9687b, 0x1c7ca3af, 0xde51cf8e,
+ 0xd9b904b3, 0xc805e2cb, 0x461adb4f, 0x9f514675, 0x91f38f74, 0x585e655a,
+ 0x171ba07c, 0x9994f77f, 0xc87e35e3, 0xbe7cf44c, 0xb57ce3fd, 0x707fae2a,
+ 0x65c8109c, 0xe48ff926, 0x1d5d4272, 0xfec8ceaa, 0x2d973d0c, 0xfb633aec,
+ 0x1de0ceeb, 0xe6bfa06e, 0x9de7fffb, 0x38df8465, 0x9ed645c9, 0xca797c49,
+ 0x748b9fec, 0x5a89aeeb, 0xf3e827e6, 0xeaaf820d, 0x63fec2ad, 0x1f224b51,
+ 0x6aaaf6ca, 0x72cbdd23, 0x677fa0bd, 0xc1f7cb8c, 0x1fc126ed, 0x1ea2b4df,
+ 0x6641c29b, 0x1c47a885, 0xfd4ebfd8, 0x6a20f94f, 0xe17a87a9, 0x9165a8f2,
+ 0x004f9128, 0xcc1b51df, 0x2756d4fb, 0x03406fe7, 0x3268b3f6, 0x48b97d23,
+ 0x02b5fb05, 0x3d5deb9f, 0x9fa72eb0, 0xfafa7376, 0xf0056023, 0xf7898f3d,
+ 0x82ef60ac, 0x4da67b1c, 0x607ee289, 0x2eeb16de, 0xb5f2117b, 0x7ae2755f,
+ 0x8e48576e, 0x569b6bcd, 0x4bea15b2, 0xeb405c0f, 0xd399369f, 0x9b88d2e5,
+ 0x2114e2f4, 0x11adeb1f, 0x3fdfd90b, 0x01f21851, 0x74764ff4, 0x53947c23,
+ 0x280f1831, 0x10f40dd7, 0x5d83a849, 0xcb93a534, 0x9cf20655, 0x524bd825,
+ 0x671ca3de, 0x919ff649, 0x1f52c23e, 0xf4c7b971, 0x527b946c, 0x0aebdf2e,
+ 0xae49b974, 0xf5c6ce8d, 0x72e4f585, 0x7842bf73, 0xa42d626d, 0xe81ea44f,
+ 0x91e8571f, 0xeb986ad3, 0x2a26eb2b, 0xd117775f, 0x27594b78, 0x57a913e9,
+ 0xd783a386, 0x7e0e84bf, 0xed007486, 0xe8b01f8d, 0xe35e3065, 0x9a6d1672,
+ 0x44e74bc8, 0x4f5c8fd2, 0xc49eb8da, 0xf43ce532, 0x4c7eb265, 0x7ac987d6,
+ 0xf5c2db30, 0x69675c9d, 0xe74f64cf, 0xe594c076, 0xfcc19511, 0x3ff9a636,
+ 0x60349cce, 0xb2de84d7, 0xb10bf4d9, 0xe0a3601e, 0xd369c5bd, 0xf686ca6e,
+ 0xc8fcc690, 0x9780a957, 0xbb7cf09d, 0xb36b7bb0, 0x2d7bdd39, 0x5acd7e9c,
+ 0x703b9580, 0xcfb4625d, 0x1732678d, 0xe7c4a3d2, 0x577c2776, 0xfd71df81,
+ 0x8dbdffd4, 0x7c24a5b5, 0x9d9cfd5f, 0xcfe7eae4, 0xb256233a, 0x6e858247,
+ 0x57eb2fe8, 0x7b53b256, 0x3e92739f, 0xd0fa15ed, 0xd128f683, 0x5fae2acb,
+ 0x21275d71, 0x648f5535, 0x35cafb48, 0x4a045123, 0xcdc9acfb, 0xf6c1aced,
+ 0x8a2f6890, 0xcae9cf5d, 0xcfccfb4a, 0x62773ddd, 0x6861e01d, 0x588fff9f,
+ 0xe981d0e7, 0xe787dfe5, 0xc7c380a1, 0x472c1fb1, 0xdfaab57a, 0xf406deb9,
+ 0x1e5d4335, 0xd1e60bbf, 0xa170ef94, 0xfc29ab9e, 0x846f2ff5, 0xcc0787fa,
+ 0xbceb8acc, 0x1b1d7a67, 0x5dfcbc35, 0xe89f3112, 0x5b97e049, 0x4deb19f6,
+ 0xa87ac69d, 0xc82f58cb, 0x4f4e7a70, 0xfbe1d920, 0xd5b5d033, 0x4ec1f2da,
+ 0xbcfad780, 0xa7d1f495, 0x067160ee, 0xfc535bca, 0x5ad9e218, 0xf444f1f8,
+ 0x3fba846f, 0x02b4b051, 0x38cac4ed, 0x3faf91fe, 0x742bcfb7, 0x01b7810d,
+ 0x899b31fc, 0x3ad60cf0, 0x85ce492f, 0x2c789f04, 0x845f0ffe, 0x9d9a2ff9,
+ 0x9e9bbae2, 0xaa4e67f8, 0x60927b42, 0x572da164, 0x2dfb887f, 0xae096f78,
+ 0xf059e9ff, 0xb0d5c01e, 0x46c3eb85, 0xbe434b16, 0xd3bb066d, 0x477c4b06,
+ 0x5b875f06, 0x5155e2da, 0x8c8edff8, 0xa70871da, 0x802d27f6, 0xfb1ab1f4,
+ 0xaf93b04d, 0xe07ae0cd, 0xd7767d96, 0xdd1e0329, 0x2ba87a86, 0x912a75c7,
+ 0x61fc84ff, 0xb8968a79, 0x09577a1f, 0x6bf88b5e, 0xa658f5b2, 0xfc57f8c1,
+ 0xf79233e9, 0xa7cd978b, 0x5d80c47d, 0xb4f9256d, 0x3d20aef8, 0xdf2b697f,
+ 0x6ade9e17, 0xa7ef11d7, 0xe3fdf3b7, 0xc4473ce2, 0x857bff06, 0x8bdbdb9b,
+ 0x19453be1, 0xbc64c78c, 0x55f0ffbd, 0xf7a3a45e, 0xdc2f1f19, 0xf78fedc9,
+ 0x62af805d, 0xf7f60efe, 0xefd8177e, 0xaaf9e20a, 0x2e2e510f, 0xd0faaede,
+ 0x9c87604e, 0xbc598fe4, 0x0b71cafd, 0xa7dfd81d, 0x5fa1a623, 0xe895c768,
+ 0x02f7c289, 0x89d7ee11, 0xb5cf015d, 0x1d93171d, 0x95bb7477, 0xedb6e9c3,
+ 0xf15c79c5, 0x4af89527, 0xda20b133, 0xff161dc7, 0xfd67e438, 0x70333de1,
+ 0x959fde5d, 0x1ff7a26b, 0xf10b9857, 0x85965ee1, 0x5a2b17cf, 0x61b7f900,
+ 0x899992cb, 0x866a4ef6, 0xad35eb4a, 0x8f567970, 0x7ae9f883, 0xdb4da3d4,
+ 0xfc707f81, 0xf2ff6fd9, 0x3f224f46, 0x4cc55edd, 0xc3cbf609, 0xc27a235f,
+ 0x6be028bf, 0x57d7c0b1, 0xaa6b2be5, 0x12968be4, 0xef8ba394, 0x0d71296e,
+ 0xf3f45761, 0x0f9cc3c5, 0xb850cbef, 0xc32f20ff, 0x6e18cfb0, 0x3528e65f,
+ 0xf9b15e91, 0x940f7f98, 0xc62db0d9, 0x0c81f7fd, 0x640fda8d, 0xfb5f7b70,
+ 0x5efb6ddd, 0xcd4d7987, 0x80cf6e08, 0x97f3217a, 0x71ebbae3, 0xb1983557,
+ 0xbbb26288, 0x6e56c3d8, 0x8edc6ac7, 0xf6c99cde, 0x8fd84bae, 0x997f6277,
+ 0x62f61724, 0xffc7bd3f, 0xdaf10c78, 0x44f1f05c, 0xe7420fb4, 0x1fa0b33e,
+ 0x90add1cd, 0x02f8773c, 0xd425e90c, 0x282d8b3d, 0x21c3901b, 0xc913d71f,
+ 0x0653faf3, 0x3c84efdf, 0xfde7ea71, 0x3b7f9c11, 0xb73e9cdc, 0x3f214b2d,
+ 0xc44f36e4, 0xb5ff408e, 0xa5ed2a7c, 0x67efc225, 0x5f94fddb, 0x288efa45,
+ 0xd75831ae, 0x35f47f39, 0x30a88dcc, 0x8bbb87ce, 0x77d9dfc9, 0x854f9a60,
+ 0x1feec736, 0x788519ad, 0xf0fb32ea, 0x27af877d, 0xe1f7e70d, 0x386993ee,
+ 0x2add86bf, 0xf221bbcd, 0xb2c2d649, 0x33f0b901, 0xca3af825, 0x1c52e601,
+ 0x0f94be38, 0x34feee1f, 0xfb83816b, 0x567f480b, 0xa7978d0e, 0x8e7ed3dc,
+ 0x39715fdf, 0x1e8f975f, 0xee5046b7, 0xfd07647d, 0x3f6f2096, 0x777d7272,
+ 0xefee432a, 0xdf500b3a, 0x2a6fd7f4, 0xf89ca135, 0xdfcf8b8e, 0x402ce963,
+ 0x628dfc7e, 0x1ae967ec, 0x6c808b13, 0x5006b25f, 0xa3e8f203, 0x40299f47,
+ 0x9ee1ff79, 0x27e60a67, 0x9dfc97c0, 0x78e57b2c, 0xfd266fc2, 0x344b1ea8,
+ 0xef9bc70f, 0xe57f72b3, 0xf9547e30, 0xfdc2db3e, 0xab3e7da1, 0xbf28748e,
+ 0xf1486beb, 0xc7db7da3, 0xe6ff246c, 0xacbf0b77, 0x83da3fdf, 0x7df918fb,
+ 0x1e15ff52, 0x974a4f4e, 0xd483fe42, 0xe3c938b2, 0x7bde59bf, 0xe4133d60,
+ 0xbff3ac3d, 0xd9345f21, 0x3246c7e2, 0xe20b0fa2, 0xd0ecd2cd, 0xad653f50,
+ 0xbf15f4e4, 0x2afb44c3, 0x81d7ae4b, 0x928aecf2, 0x30133694, 0x6d2527a2,
+ 0xf201c622, 0xfde94b73, 0xfba73570, 0x7f231670, 0x516b0e5b, 0xb8bb5e48,
+ 0x326f3edf, 0xea83ad73, 0x9edc11ac, 0x16df32f1, 0x5dd698b5, 0xc490ff41,
+ 0x480bd487, 0x3f1f283f, 0x3f446c52, 0x7642b74a, 0x9cea6aa7, 0x470efd8b,
+ 0xc847134f, 0xa7a73ffd, 0x893ffafe, 0x188f269e, 0x3a829e8e, 0x36d793d1,
+ 0x3f093d34, 0xcfbf79f1, 0xbfdc01c2, 0xdd7c0b66, 0xfc4ee427, 0x9bf49b0e,
+ 0x99df382b, 0x3699bfa2, 0xfd455447, 0x9c7f33e1, 0x187dffe8, 0x27dc5fec,
+ 0x0efda0e5, 0xf395c8e5, 0x16375a74, 0x417f41eb, 0xd236c5ea, 0x629af78f,
+ 0x64af6845, 0x8fd96f8f, 0xb73d9174, 0xed2562ac, 0xa8dcf2ff, 0x92b7500f,
+ 0x7559741f, 0x0488d4e0, 0xdf10e17b, 0xe5df34cf, 0xbbd3e7a7, 0x1a107db9,
+ 0x387b216d, 0x7184a5d4, 0x96039b9d, 0x6b41da08, 0x095fee15, 0x3cebb06f,
+ 0xa0afa3ee, 0x740fcfb8, 0x488a171e, 0x8ecf6fff, 0x35bd23ef, 0x91efc838,
+ 0xf83a3f1c, 0x1fc7ca85, 0x8efc68c3, 0xeaaf1e72, 0xfee75ab8, 0x1d7eb115,
+ 0x6e39fcb3, 0x18d607b4, 0x85c659f9, 0x18809cfa, 0x7afe6f18, 0xae43ad3b,
+ 0xd2ccf1ca, 0x0cff5c6d, 0x67e40b96, 0x162c9ace, 0xfa6fc446, 0x05241cf9,
+ 0xbb4573d6, 0xcb39378c, 0x79684502, 0xb7e9bbbf, 0xbd00a4af, 0x8e9fa166,
+ 0x68c2ca6f, 0x987f93f7, 0xfc7dc9d7, 0xc90009a0, 0x5cffd6c5, 0x42697357,
+ 0xf03fbc5d, 0x6b6bdcfd, 0xf6ef48f2, 0xa0d823b7, 0x6fdd658f, 0x351e31d7,
+ 0xbd81aed0, 0xf852eb6b, 0xb5c761f7, 0x3c068e57, 0xfffc7228, 0x7f47eb5c,
+ 0xc6199da1, 0x4b4f844b, 0xfd0cdfea, 0x7ef9743b, 0x784af6bc, 0x590ac1e1,
+ 0x1fad66bf, 0x6ccfbbe0, 0x2a508fec, 0x1c8ac7be, 0x6dacd6ef, 0x0de7d6eb,
+ 0x276005d8, 0x39911aec, 0x7eac1f60, 0x85fb667b, 0xebaa5630, 0x5dea0b53,
+ 0x1e43e7a9, 0x648fec85, 0xe4203d7e, 0x572cdfc3, 0xf47641f5, 0x57241181,
+ 0x4b20667b, 0xe483fec2, 0x80796876, 0xf6073da1, 0xdbc21748, 0xd3e3fc7b,
+ 0xef7b422f, 0x1b1fdfec, 0xb77be3a9, 0x37bb45ce, 0xba234e74, 0x2353ed0d,
+ 0x4dadd00a, 0x71e80bf0, 0x7a480b8a, 0x7412ea5a, 0x8c330eea, 0x521c7473,
+ 0xbe898526, 0x83ae0a5a, 0xf8f7ccb5, 0xe438425f, 0xde7932be, 0xf7c11ebf,
+ 0xead2a10f, 0xffd825ad, 0x9da1856e, 0x44f4aeb0, 0x37da02d6, 0x30b59bbd,
+ 0x5d25bbe1, 0x973e120f, 0x890f33ec, 0xe08f5fc7, 0x67e6de71, 0xdca3f69f,
+ 0x90a228f8, 0x22d0684c, 0xbd40a76b, 0x9684c1a1, 0xcc8cab20, 0x1ce291bb,
+ 0x06361675, 0xed0477e6, 0xdf638426, 0x7053c337, 0x814ff0de, 0x8b02db47,
+ 0xab6e9f48, 0x4e2839b3, 0x56ff3a54, 0xc52b83c2, 0x5758788f, 0xe3839d5a,
+ 0xe19acf34, 0xd808f8a2, 0x7cded871, 0x2fc8b7d7, 0xd75ae124, 0x3b45ae65,
+ 0xb9ec0aa7, 0xfcee00a7, 0x7d6a6b8c, 0xd523c7c0, 0x3bb7e5fd, 0xb43e5e30,
+ 0x266eff1c, 0x25368ba7, 0x2546fe10, 0xa25941f9, 0x8bb0b35f, 0x8d9f8ddb,
+ 0x2be218b0, 0xf6e08d9f, 0xd8e1a5ec, 0xc39f2474, 0xda2a4f5a, 0xffe621d3,
+ 0x2ccff704, 0xd0f7d0e0, 0xe479713a, 0x3fc9d569, 0xdcf4f366, 0x5fb6217b,
+ 0x85fed1aa, 0xe00f3d69, 0x3d6bbdb8, 0xf04c75be, 0x2aefd601, 0xbd4f7da3,
+ 0x3278a827, 0x7d70bcf9, 0xaabd9f7b, 0xd288fd1c, 0xa8fb5aee, 0x5ae6f49d,
+ 0x2d7f7ea7, 0x69dfd3ca, 0x16c01f3c, 0x7e874d8f, 0x833efe96, 0x8f6b5dc6,
+ 0x0ff5c5ac, 0xbda954ef, 0x607411d8, 0xb9be4bbf, 0x2bd22265, 0x504a4473,
+ 0xed3d9a8f, 0xb618e90c, 0xb12fe42b, 0xe30c0279, 0xf3c3d3c4, 0x45f50534,
+ 0x1d333d92, 0x5fb455fd, 0xb6bf90f1, 0x18c7f05a, 0x36d382a0, 0x3fb68562,
+ 0x6fb0188f, 0x1ce3f95e, 0xbb4a1f0d, 0xfee364c7, 0x14ba9af3, 0x5b2df686,
+ 0x42663f15, 0xc627bd7f, 0xea6e0ed0, 0xa69c6854, 0xb82d27d2, 0x93a5b96f,
+ 0xec4877f3, 0x057f0033, 0xf18c5768, 0xa07b0aa4, 0x5839fb8d, 0xc448d8ec,
+ 0x3d7c63f3, 0x12f78319, 0xad8cabfc, 0xf440f2e0, 0x86711167, 0x0257e126,
+ 0x3eed484d, 0xef5bb48f, 0xf3b7fd16, 0x59bb8c52, 0xc455f989, 0xf062b96b,
+ 0x2af2cb87, 0x91fa7df1, 0xdfe40cf8, 0xfa17d038, 0xb32ab697, 0xcc29fd6e,
+ 0xf1a4eb6f, 0xbcc1343e, 0x056a4e40, 0x0452073e, 0x7d7657bc, 0x86e90332,
+ 0xd7e232d5, 0x6a69aee6, 0x6fc78393, 0x4ec85ed0, 0xed89d96d, 0x929737d9,
+ 0xc8f8c67e, 0x35fe786c, 0x1cb3e70f, 0x79d7f707, 0x61170eef, 0x48fd33bc,
+ 0xe29fd6e0, 0x90a417f8, 0xd61b35bf, 0xe54199c6, 0x796ff41a, 0xa88bf959,
+ 0xf533bd7f, 0xc647840a, 0x382e30f5, 0x38e48cab, 0x8a7c33d5, 0x3794177f,
+ 0x0e34dc78, 0x116aefec, 0x711e7c5e, 0xd119c40c, 0x62e3876f, 0xdecb0f1c,
+ 0x7e46a89c, 0x7be7d07e, 0xacbb4e90, 0xccd7c42e, 0x42df97ae, 0xc6d33b7d,
+ 0x9aee293a, 0xd3c4b764, 0x3a4419be, 0x7a733bed, 0xd7083dc7, 0x947d0775,
+ 0x8f6492cf, 0xb739715c, 0x93da3fcb, 0xec3f23aa, 0xec1b7212, 0x797f1e47,
+ 0x9323ef9c, 0xf6efc8ed, 0x23b72faf, 0x777febfb, 0x17c3923b, 0x28f3c3de,
+ 0x890f7ca4, 0xc35f5f7d, 0x5fd434d9, 0xaed23d2b, 0xd8f7ca4d, 0xba3df22d,
+ 0xd0f7ce87, 0x0ff8f276, 0xee494186, 0xae222dba, 0x43cef7e5, 0x84bb87ff,
+ 0x7b2bc0e4, 0x3748c353, 0x64ed3b67, 0x4b6e6997, 0x7b6ae114, 0x3cc11ada,
+ 0xe0453688, 0x578890eb, 0x2c1c4459, 0x834744a3, 0x4025a0e2, 0xa4fc3f72,
+ 0xd2abc799, 0x85ee8f22, 0x1ce1e37a, 0xd462cf11, 0x54d9f87f, 0x8a6377c2,
+ 0x37fd8e9e, 0x8608fbfe, 0x183eaa71, 0x09f9d70f, 0x87bb707b, 0x7fbc5ae2,
+ 0xe75582f6, 0x8968b3f1, 0x33b0f01b, 0x93bfedc2, 0x05a8a6a5, 0x8993bde6,
+ 0x32f59f3c, 0xd9e7c5ae, 0x8f2461b7, 0x8231a0cb, 0xdcb5b2fb, 0xe32f545f,
+ 0x1fb98755, 0xa5c45eae, 0xf45ece4e, 0xb458a608, 0xb8b52d29, 0xdd7cfb4f,
+ 0xdf9ff234, 0x2a2cff79, 0xfd18d7eb, 0x3fd08bfd, 0x3f103c5f, 0xf9f77e96,
+ 0xf6e167cc, 0xd0ff80f3, 0xbe8cf604, 0xfd46ab46, 0x775cc459, 0xc3d03ea3,
+ 0x43177ab0, 0x1a2506d9, 0x19600af1, 0x7ad6d3de, 0x57bd7052, 0x6f4899b7,
+ 0x7e4cdb85, 0xcbd24f7c, 0x67ae1eab, 0xbd70f5df, 0xe08ea803, 0x336cb238,
+ 0xe883788b, 0x4533056f, 0xbc2934b1, 0x6ad2ed5c, 0xb2dfd287, 0x8b7336bf,
+ 0xcdda1a6d, 0x77f226f9, 0xd7f16e7f, 0xa338bf91, 0xcda9d684, 0x96a6b2d9,
+ 0x7d2f13b7, 0xa8078f6e, 0x1b8d32fd, 0x40cf4c96, 0x8782fa79, 0xf19217c7,
+ 0x58ddb0b6, 0x2cc38e4f, 0xf5eb1889, 0xa736382c, 0x120dc798, 0xf420bf9f,
+ 0x8aebe7c4, 0x167dbe04, 0xfe72bb94, 0xde38f22b, 0x1cbcf94c, 0x875d5f95,
+ 0xe30a3074, 0x725845ca, 0x84cc2abf, 0x99751fe0, 0x48fa2147, 0xcdcdb782,
+ 0x96bc29e9, 0x5aff21fb, 0xfee193f8, 0xf82593d0, 0xb8c5efd8, 0x42cbbd65,
+ 0xf5f3e871, 0x1a64a497, 0xf5fdb7f7, 0x96feffbf, 0xaad7e7ef, 0x45c6bf22,
+ 0x8bbe6972, 0xe2a4e5cf, 0xe7c51bdb, 0x701fb00e, 0x0ad56b1e, 0xbfd32394,
+ 0x3479a0e9, 0x8239061f, 0x3de5ac71, 0x9bd7a805, 0x304a7bab, 0x5f8c935e,
+ 0xf2935684, 0xef9bde0c, 0xda08fd81, 0xf18c6b0d, 0x55f1c1b8, 0x2666617f,
+ 0xee4e7bee, 0xd7f5197f, 0x2fe93b7e, 0xad17bff8, 0x16cfffc8, 0x388b5c91,
+ 0x2e316383, 0xee894a14, 0xda1171f8, 0x6a8edc31, 0x44eeb6ea, 0x5b7e713b,
+ 0xff0f7c42, 0xef18deb3, 0xc8326b63, 0x8c3aceef, 0x4e1e1bcf, 0xfc506efa,
+ 0x65d69daf, 0x0e3825b3, 0x10f41df9, 0x599c1de5, 0xbeb86262, 0x116faaf5,
+ 0x7633a92a, 0xc67e7da3, 0x466bd7c9, 0x3e3fd4a6, 0xebfabfb2, 0x57d9d683,
+ 0x6f5ceb82, 0x7ec4c162, 0x619d709a, 0x3ac51b7d, 0xe2fa799f, 0x8fe75c12,
+ 0x825c5ff7, 0xdcd9bceb, 0x29be47ee, 0x41af0775, 0x32ba9cfc, 0xe615f640,
+ 0x9d1f20ef, 0x94de3d2f, 0xfd378f44, 0x2eb1e8e3, 0x59321f31, 0xe3f4363f,
+ 0x3d1fa8cb, 0xe50f3d16, 0xf59b7cc1, 0xfc49ea2f, 0x679fd21b, 0xe3ff92b3,
+ 0xdd3f1ff0, 0xdd18f948, 0xb227d92a, 0xb05ac3bf, 0xc3a3ed18, 0x617d796f,
+ 0xd3fef865, 0xb5e5fd85, 0x59fa30b1, 0xda40bee4, 0x78f2c997, 0x03cf98b9,
+ 0x8cdffe99, 0x3ce21bf8, 0x20dc7fd2, 0x3e45b1de, 0x6eef76e5, 0xc7fdc7c5,
+ 0x6e4fe49d, 0x85cf343e, 0x220fe2fe, 0xfcdc7fdc, 0x8ff93974, 0x8a5e4497,
+ 0xeb193e62, 0x1fb85c56, 0xddfbb259, 0x9003cc34, 0xe7d85efb, 0xf9499fde,
+ 0xeffdc635, 0x69939107, 0x70003798, 0xa7708fbf, 0xa416e27a, 0xffd866fb,
+ 0xb360de61, 0xfd863f16, 0xd9187b36, 0xc65d9505, 0xef8ca0fd, 0x48580b6e,
+ 0x56eb6eee, 0xb3af2822, 0x3ca2c12c, 0xcf2c6bd4, 0x80753a75, 0xfe9922cf,
+ 0x077e9017, 0x5dfeeae2, 0xa7fe9758, 0x44e9ad9e, 0xe6663dbf, 0xdb3ca177,
+ 0x4cf214ea, 0xdbf6f923, 0x7591dd87, 0x6fc37609, 0x584edc23, 0x34c1f322,
+ 0xbd60d516, 0x1ff1cd16, 0x7946f5c7, 0xf7924d1f, 0xaf197589, 0x494585bf,
+ 0x9eb1352f, 0xc4b0bcfe, 0xf9e392f7, 0xf4370718, 0x75ca5ac3, 0xe4dd93f4,
+ 0xab9c51f0, 0x6356cfeb, 0x9bef987b, 0x55961f81, 0x5cafd00c, 0xcdbf4907,
+ 0x6a1d1fc2, 0xe90ab138, 0xb8a5d437, 0xe8dd7f70, 0x08dbf4e3, 0x9bcc2ffb,
+ 0xd677e64d, 0x1d13cc69, 0xdd7fff8e, 0xff9c77cf, 0x9cac3d7f, 0x5bf8c7fa,
+ 0x3f97efdf, 0xfce5ef9c, 0x7fbeffa5, 0xe70add9e, 0x2579a4cb, 0xfd935bef,
+ 0x79df72ee, 0x8bf0f2be, 0xf17c7c24, 0x70c7c60f, 0x6b2530f2, 0x7242fde8,
+ 0x96afe35c, 0xf8e0ff87, 0x1e8723c6, 0xa881334a, 0xf6145258, 0x6fcebb72,
+ 0x50cf1788, 0x371e7e1d, 0x453e7955, 0x9f5ddc72, 0x9ceee221, 0x5a7a5f9f,
+ 0x126af5a5, 0x43a6e1f1, 0xdabe1f4e, 0xf14c58e0, 0xe9f8e4d9, 0x067fb652,
+ 0x1c72512e, 0xb8f911b5, 0xa9e3cbf8, 0x3d396517, 0x56749f24, 0xc90a7984,
+ 0x392f5a79, 0x4c111d3e, 0x32eaef58, 0x410c08d8, 0xcc2d36d7, 0x4f9e1232,
+ 0xf4f6e2cb, 0xc89f224b, 0x05e7e16b, 0xfaa673ee, 0x35e31f71, 0x7ca77cf1,
+ 0xd67a604f, 0x02ef9424, 0xc0decf9f, 0x4797804c, 0x4f249dcc, 0x1f0e4dc2,
+ 0xc7e93fca, 0x10effd91, 0xa5f38b71, 0x19676ff3, 0xfebfbce9, 0x85fbe24f,
+ 0xdaffbe92, 0xc016ddb8, 0x181f818d, 0x186befd1, 0x4c1a2a67, 0x33f5c3b7,
+ 0xcb2efd1c, 0x459edc0a, 0xa44ff178, 0x94f3e6fc, 0xf195a92f, 0x622fe893,
+ 0xfa3aac07, 0xfce26d37, 0x239f5b0b, 0xaabeebf6, 0xcd979459, 0x73c88fcf,
+ 0x8fd9c336, 0x9ff9fb1b, 0xf5fd8fdb, 0xc8fd93bf, 0x9c7681dc, 0x7e69a9e7,
+ 0xed5ffbca, 0x5f71f804, 0xc875a8f8, 0xdcf22cf3, 0x5df997c5, 0xcdc3f6f6,
+ 0xb0ef6ae9, 0xe563ff70, 0x34ff93e7, 0x34fbf9f9, 0xdf0ea3f4, 0x7be4584f,
+ 0x9e22fcc6, 0xf82576c6, 0x9e3143b7, 0x8092f7af, 0x447f3e57, 0x6cf4c5e8,
+ 0xa75c51ff, 0x6cdb8f8f, 0x9e4c1d2c, 0x9b172e4a, 0x2f8a0e03, 0xbcf27734,
+ 0x8ce5e697, 0xfa3377e4, 0xafd0cb4f, 0xbda18b38, 0xf8233537, 0xf57efc33,
+ 0x9ab08edb, 0xd9f77e8e, 0xdebbed0c, 0xa9febce3, 0x6c73f83b, 0xa1ef2d0f,
+ 0xecc74678, 0xaaef288f, 0xae9fcfea, 0x7824adaa, 0xb1e08fc9, 0x7cadcf1a,
+ 0x0fe3c591, 0xbf43fcb2, 0x5f93f13c, 0x9e06e3ff, 0xf8f21d9f, 0x908fe85d,
+ 0x3d54f17e, 0xe6a67e46, 0xab68dc03, 0xd87cf952, 0x9e88f3f7, 0x2b4c0f9a,
+ 0xeb29ff47, 0x9da397b4, 0x072bf55b, 0xbe3ef7ed, 0x24f2972b, 0x0fc13dea,
+ 0x2b3a3e51, 0x5da35723, 0xa0e3085a, 0xfef1fbbd, 0x6e11cbab, 0xa336ff29,
+ 0xdfc61cff, 0xc7fa34ec, 0xd9e78d99, 0x4f9bdd2f, 0x4762cbfb, 0x6fec53f0,
+ 0x11c39db3, 0xa3ce23de, 0x3279bf08, 0xcfbe4bff, 0x4e344d56, 0x146db7f6,
+ 0x6172972f, 0x6d0599b3, 0xe4f203c5, 0xf22e9678, 0x635e444c, 0xa79e2cf7,
+ 0x8f0eea22, 0x81f3bf31, 0x238f2bcc, 0xb4b3c73c, 0xe61f96af, 0x402f9418,
+ 0x187e62fd, 0x9c5805c5, 0xe7a92dfc, 0xca3d1db8, 0x727a2165, 0x9c51df02,
+ 0xed09e806, 0xb1e34bf9, 0x6b9e78e9, 0x52f44774, 0x73e1f3c4, 0x3693c226,
+ 0xd38a35eb, 0xbc7c2ba4, 0x6b3df5e2, 0xc61fa2c7, 0xb865e6f5, 0xabbb7aa4,
+ 0x353a511a, 0x4d9f9023, 0x52968cfb, 0xbffaaf1c, 0xf29f3ccc, 0x17f92a50,
+ 0x291a0a3a, 0x6df7b29f, 0x4e3ce1ab, 0x77661972, 0xa8e4fe53, 0xbc505fae,
+ 0x194079c0, 0x72762f32, 0xd6f083b6, 0xa0cd8e1c, 0x3d4b9b1c, 0x43b56724,
+ 0xb538a2bf, 0x094356b6, 0x7eccdac4, 0x0b439e13, 0xefe460af, 0x32e1d31c,
+ 0x8a157ae1, 0xc3be98fc, 0xa418987f, 0x0f8c8afd, 0x937e7844, 0xee1567b9,
+ 0x3d15b4c3, 0x3d718797, 0xcd4db80e, 0xbc5fd865, 0x872dfc99, 0x4fd21952,
+ 0xddf15761, 0xb85ea153, 0xb0f145c6, 0x296ee7be, 0xcc2aff24, 0xf310cc73,
+ 0xf336ca2c, 0x9aa50ffe, 0x9b699f50, 0xd5470f98, 0x04d559dc, 0x875083f7,
+ 0x3c8a467e, 0x453f1955, 0xa9ea143f, 0xd7e0ecf4, 0xffb63f30, 0x14b2d21c,
+ 0xe3490e7e, 0xb2e712fe, 0xf3c71fb7, 0xfc2c3b3d, 0xc391e79c, 0xdf936613,
+ 0xe0a6ad6f, 0xe6ee7c3a, 0x663794f9, 0x42e70c9b, 0x847ff006, 0x1d4756f2,
+ 0x6bd705fa, 0xaff61630, 0x68bd3999, 0xd13b3d6b, 0x2d38b8bf, 0x97ba7948,
+ 0x8a5545b5, 0x3d4eb99f, 0xec27ab50, 0x3d70b673, 0xef8fbcd3, 0x35f793cb,
+ 0x6e5fa65f, 0x2dda36cb, 0x927ff5fd, 0xfe83f2dd, 0xfdc6fff1, 0xf3ee330a,
+ 0xe497ed92, 0x3b20dd7d, 0xe1bfa93c, 0x8f9918ec, 0x0e303d52, 0xd29da7b7,
+ 0xf21b0a4e, 0xe21daa75, 0xd8cda17c, 0x5c23e5ff, 0xbf995f34, 0x5f52b593,
+ 0xf1fa7981, 0xd7f2301f, 0x70a23cc9, 0x09f7cf35, 0xee746c9b, 0x29dacbd0,
+ 0x8b24687f, 0xd3f90a2a, 0x6d7ce87a, 0xc111e636, 0x47b2eb77, 0x99dbbf51,
+ 0xf24a8d6f, 0x6e105752, 0x509fe63b, 0xeb646abe, 0x3ae71c22, 0xc7638d07,
+ 0x308b93fc, 0x15bfc085, 0x06f4ebe5, 0x05c85f1e, 0x9bf48c7d, 0xa1d39a3b,
+ 0xa1e78ebd, 0x99133cc8, 0x50f12217, 0x3b9bf02d, 0xca115176, 0xf04ab5c1,
+ 0x99ae7151, 0x4e0dffcb, 0xec195e71, 0x79c0cf6b, 0xfbc63ee4, 0xf898370f,
+ 0xaf376479, 0xf9d18c77, 0xf82fa079, 0x728ebb39, 0x2832779e, 0xaf09253f,
+ 0xc9e53f32, 0xe411e0b4, 0xcbf3e497, 0xd6124e92, 0x6f47ce8f, 0xfaedc43b,
+ 0xcd0b06ea, 0x35c96fa3, 0x5bec97e4, 0xffa86262, 0x9cadbbab, 0xdbc692ee,
+ 0x51616756, 0xd88b57ec, 0xf5ca7e51, 0x16bb32ff, 0xfd14b5d6, 0x6b5a47be,
+ 0x38053a2f, 0xa01ada3e, 0x74aecfb2, 0xf9d217aa, 0xa928b9d2, 0xf9f2d89e,
+ 0xe60e5ab5, 0x140bc4db, 0xb7e79920, 0xea93347e, 0xb077f199, 0xcf16eafe,
+ 0xc39034d7, 0x3be2637d, 0xffff7814, 0xdbc47f79, 0x19731691, 0x87a1f77b,
+ 0x5f1d8666, 0x91fddf41, 0x9c71e725, 0xc4d3bd41, 0xc8c5567a, 0x5df4245f,
+ 0x5e879725, 0x25ec8587, 0x653fc8af, 0x151f2235, 0x5f503b23, 0x714e5399,
+ 0x0fd3077b, 0x8f3db0c4, 0x7682cf9f, 0x6395ffa2, 0x26da7fb8, 0x49e582e8,
+ 0x184f54bf, 0x22cadbe5, 0x2fdf7d37, 0x23580f8f, 0xc7c63fdc, 0x0be9e37f,
+ 0xf325be28, 0xe573196a, 0xf280b9cf, 0xfbf50c6c, 0xa61ce2ec, 0x73c7cae6,
+ 0xc2cd2bec, 0x36f515ee, 0x8bc53067, 0x043e44f3, 0x2b8dee7b, 0x7c865bbf,
+ 0xf7e0e674, 0xbb5ca347, 0x82fb02ca, 0xeed8e421, 0xfac72e1c, 0x0a358ecc,
+ 0x0ce3577c, 0xfac2f08e, 0x773a95bf, 0xa8291e06, 0x82cd311b, 0xf8581747,
+ 0x9af11551, 0x3dc4e829, 0xaee7c387, 0x77982809, 0xc7ced2ba, 0x7e6a0ccd,
+ 0x9c10f73a, 0x70075ca3, 0xbcb854af, 0xc9d28f86, 0xd3d52a8e, 0xa3611cf1,
+ 0x0aaad738, 0xe74971b9, 0xf5ed1526, 0x35beb79f, 0xe006d355, 0x878885fb,
+ 0x78c8a2ff, 0xcbdca23e, 0xce5962ed, 0x900bf556, 0xf0ad56fe, 0x12f336bc,
+ 0xf8e9ce7c, 0x9565b4ca, 0x557da798, 0xfa254b6a, 0x4f3d0769, 0x0965e787,
+ 0xaf7f2b75, 0xc02f16d1, 0xed0be673, 0x8f8849c1, 0x7bbde7cf, 0x3b87ca27,
+ 0x0778df73, 0x30de24f3, 0xaf91390b, 0x98eef588, 0x79eb069e, 0xf22dd8ac,
+ 0x0f446c3c, 0x3f72c6c7, 0xdb1e7f64, 0xfaf28538, 0xe7e1ce66, 0xb165af49,
+ 0x9ef81eb6, 0x3ed0159c, 0xd9117263, 0xde453391, 0x02b78cc5, 0x9817e869,
+ 0x435c4371, 0x5d9c3a39, 0xacd79574, 0xc3f024f7, 0x7eb1bad5, 0xfeb1a96d,
+ 0xfeb19f35, 0x1a7fc98d, 0xd97f589b, 0xf48d9fee, 0xf3c2bcf4, 0x3097c33e,
+ 0x47bdd117, 0x32fda309, 0x715c99e1, 0x27e7970e, 0x77d8abfe, 0x5199333d,
+ 0xdb3ed67b, 0x20373c2e, 0x68aad7fd, 0xb665e09f, 0xef7e0cc2, 0xb8bbea03,
+ 0x3d1cf222, 0x0761d314, 0x3f71756f, 0x816bbc2e, 0xd3ce0e7e, 0x46aa3f89,
+ 0x4e9052da, 0x76261cb2, 0xa552f239, 0x239aec8d, 0xb9e4ee82, 0x058d2aea,
+ 0x8602cf30, 0x1be5839c, 0xe88bd766, 0xc87f0ea7, 0x69dbe718, 0x8a5be51a,
+ 0x415b1831, 0x5d0487f5, 0xfff2911f, 0x57589a07, 0xef1840e0, 0x1e5cfaec,
+ 0x74652e87, 0x656cfe5e, 0xdd25d509, 0xae01fe4b, 0x41a18d1e, 0xe927f445,
+ 0x0b4ea7f9, 0xbf7a83d1, 0x34bbf849, 0xea590213, 0xb8807092, 0xc93d42c9,
+ 0x7195fec8, 0x6c9b7cba, 0x7ef8fcd7, 0x7e75930e, 0xd44b2bde, 0xaa6a29a1,
+ 0xf2fcfd40, 0x3b7f48ef, 0x879c417c, 0xe746cd25, 0xa3e38693, 0x767f825d,
+ 0x4b91f125, 0xe8f89abb, 0x3b92cea7, 0x9c6bee08, 0xa5afd42e, 0x0cba9730,
+ 0x2a23fd2a, 0x4fce3bf0, 0x474f8a6a, 0xed66f9be, 0x825aa9f1, 0x9bef869c,
+ 0xc6a9f7f8, 0x7df0bdef, 0x69f7c246, 0xe0d97df0, 0x6d3b77ef, 0xec44d351,
+ 0x21ef4aa7, 0xc9a5187d, 0xade6235e, 0xaeeff166, 0xa3b17911, 0xd47de0d3,
+ 0x3cc6a55b, 0x67d93613, 0xa4e4fca3, 0x94ab92bc, 0x57c839e5, 0xba9adb57,
+ 0x97bfa07b, 0x655e3ac5, 0x82e67e0a, 0x2dcf2fe7, 0x57fc8a39, 0x98688b6b,
+ 0x8b2d77d7, 0xedc5c2ae, 0xc47c169b, 0xe1f24c5d, 0x6693e459, 0x03363835,
+ 0xedcc67ea, 0x222d6fa3, 0x9bce79fe, 0x495e1839, 0xa45e1227, 0x493fa417,
+ 0xf770c92f, 0x3bd7e7af, 0x3b6f1129, 0x4a5851d8, 0x16b18abb, 0xe7ad779e,
+ 0x880bcc0f, 0x65ad8668, 0x2f35da34, 0xdc93092f, 0x00fdcab8, 0x9cbd65e5,
+ 0x944ffc1b, 0x7e177567, 0xcbe1a052, 0x716379de, 0xc6f000df, 0x95e137fe,
+ 0xbca0e3f6, 0x862d0fe3, 0xf8e1e3bc, 0x421b8e4c, 0xfcc550bb, 0x47949de4,
+ 0xf0e39a1c, 0x109179e1, 0x5256c1e6, 0xc2ec8afc, 0x6f6e14e7, 0xb09b1587,
+ 0x3f37cee3, 0xaf7b7199, 0x33dedfa9, 0x9477d7e4, 0x6e3bb873, 0x35fde5d5,
+ 0xc79c5edc, 0x4b393db8, 0x51742fb4, 0xefc3ccbb, 0x86fdc9d8, 0xd58f4f1d,
+ 0x03b05fb1, 0xe9607ec9, 0x322ccec2, 0x7f839bde, 0xde40d64a, 0xb73366f8,
+ 0x7c99b75f, 0x62e79455, 0x9ce2f7e1, 0x318cfe91, 0xff64fc7c, 0x628e6e62,
+ 0xd7f74f88, 0xc5fe4eff, 0x3f307752, 0x585bfa07, 0x4c502fe6, 0x33f71708,
+ 0x1c3e7d02, 0xd6fe9863, 0xfeed1a32, 0x9bcb59ab, 0xcfa262a6, 0xcfa41ce2,
+ 0xc59f4009, 0x9d1cfa06, 0x24e5c993, 0xb3e925c2, 0x934b2e9f, 0x1782caf3,
+ 0xee1d3f60, 0xa3355fce, 0xf56ddcbd, 0x9e5abcf1, 0x072c9827, 0xa059e012,
+ 0xaa3c7871, 0xc24cf04a, 0x39e19371, 0xa4493e1f, 0xf9c66ccf, 0xc97e3861,
+ 0x59d858d6, 0x2f2fc031, 0x083583db, 0xacdf3f7f, 0x41a3fbe2, 0xa20eab70,
+ 0xe46febaf, 0x2a509471, 0x4f1847d7, 0x67f181c9, 0x5faff189, 0xfaf0e9cb,
+ 0xdd10b17f, 0x8451f802, 0x9f68b67f, 0x7944ddd5, 0xcc6bb354, 0x00ed1227,
+ 0x13a9b719, 0x94f1cdef, 0xe605919b, 0x4bc634cc, 0xf1e26eea, 0x8b58eb9a,
+ 0x7ebde119, 0x3a9fb18e, 0xcc13feb6, 0xc9bbab0b, 0xd3983cf8, 0x8b19671f,
+ 0xc2a39671, 0xfc07d08f, 0xd3f4fc82, 0xdf0fc5cc, 0xf63bf40a, 0xe8156587,
+ 0x6b32ba77, 0x504deec9, 0xf1b6f1ff, 0xd669ff54, 0x06f3bfb7, 0xa128efb6,
+ 0xb9260d7a, 0xf9083ee1, 0xd54df511, 0xc114d78d, 0xa2ed47b8, 0x39f95bdf,
+ 0xb04a6f02, 0xe7bc1663, 0xf28a389d, 0xbc846b21, 0xdbc85be9, 0xc9d0bdaf,
+ 0xd66f5e53, 0x9358dfc9, 0x79f5efc2, 0x2bbffcad, 0x66b73f30, 0x3c57a894,
+ 0x47eb1e3f, 0x1ee84f95, 0x8726de80, 0xce6ff886, 0x09da7ee5, 0x1c744aa5,
+ 0x4326a5e0, 0xe7c4dff4, 0xd1e2b335, 0x9a8fe45c, 0x04cfde6a, 0xc5b5b4df,
+ 0x2ce99ef8, 0x6d737bd5, 0x250f2869, 0x70e7b59f, 0xa9ed2cfd, 0x67fbe080,
+ 0x8db6effc, 0x36037e80, 0x0c5387c5, 0xdf977e4c, 0xe7e0e55f, 0x22fe02cb,
+ 0xd3bcfd0d, 0xb37f3cfd, 0x0722b6da, 0x0f5fe7f7, 0x5e712a5a, 0x51f95b2e,
+ 0x27d26fb4, 0xf9449b4f, 0x466636be, 0xdf74073d, 0xf1787c41, 0x48690527,
+ 0xdd230e6c, 0x259aba4b, 0x48c6bde9, 0xdbafc0d7, 0x5cbf3272, 0xdae81b5e,
+ 0xc3d7403e, 0xd700b9d9, 0xa9ae098f, 0x3fd5fd46, 0x265f124e, 0xbc9c3b8f,
+ 0x7944bfc0, 0x275f003a, 0x661e5ff1, 0x7f2315c5, 0xecfe4bb6, 0xa62c3842,
+ 0x29b39d18, 0xe9e37c54, 0x7630ea60, 0x1f2f8486, 0x8315ae7d, 0x4d3fc2e1,
+ 0xcffc7fda, 0x3cf2fb83, 0xf9df0ed1, 0x5c00c659, 0x242bfe30, 0x7871570f,
+ 0x5c2d2bb6, 0x5c7b08be, 0xe59be7ee, 0xf38cbb7c, 0xe7e14aad, 0x77e8bdde,
+ 0xf97bdf21, 0xcfb87ef8, 0x7ce41d63, 0xcf6f4242, 0x169c05b1, 0xee75db98,
+ 0x1b9fa27a, 0xb469f858, 0x8339968f, 0x74f117ff, 0x843e14c4, 0xcc859cfb,
+ 0xa057f14f, 0x1272778f, 0x6f090dec, 0x879a9e32, 0xf3c9a791, 0xc0cfc649,
+ 0xbec8c5ba, 0xfad8e793, 0xf39e7be7, 0xc7897694, 0x6577f462, 0x8654ff08,
+ 0x452147f0, 0xc99e7ea1, 0x2fb87c52, 0xc853ee98, 0x6cc998be, 0xd6679724,
+ 0xe19e7d72, 0xd487f6e0, 0xc7f1c3fb, 0x92339715, 0x991b3357, 0xe7c73738,
+ 0xd9874c95, 0x2c0ee7ac, 0xadf4da67, 0xd1ef900b, 0xe007d14e, 0x7ee0e99f,
+ 0x215cecec, 0x24cf583f, 0xf5fdf3d4, 0x67be7a41, 0xe49fca12, 0x9e66c9fb,
+ 0x8cd2fee3, 0x99ca8c73, 0xa12777be, 0xeda8cf9e, 0xcc728499, 0x737bf2e9,
+ 0x1fdc0d27, 0xd1c78c98, 0x871926b9, 0x4cfa2f3b, 0x3f191fe6, 0xc706736b,
+ 0xcfd238e2, 0x55894671, 0x1e154be1, 0x583fe897, 0x76ec7484, 0xff434d15,
+ 0xe81b1cc5, 0xcbba1823, 0x1730bc15, 0x008fede9, 0xf10e6e0f, 0x75e3c055,
+ 0x347bc135, 0xe1e12c3e, 0x2b878136, 0xfb3d5e85, 0x89f14ab0, 0x43e97f1a,
+ 0xbd084218, 0xe2116662, 0x45e93f57, 0x59d8bf79, 0xf8a2a030, 0xb24e63fe,
+ 0x5abf1633, 0xb195f14f, 0x4f4c4c5b, 0x22e393d0, 0x327b8629, 0x30cbec26,
+ 0xcce82fd4, 0x617fbc35, 0x7b4328d7, 0xa1bc7479, 0x2a57a2fd, 0xb149f50c,
+ 0x2ff78629, 0x50daab7e, 0x1ae7a4bf, 0x3f53fbc3, 0x83a86d98, 0xde70d0c6,
+ 0xd8559f7b, 0x65f79836, 0xbe196ff1, 0x19b6cdff, 0xf3bc60af, 0xb2f7d8a4,
+ 0x0a563fb0, 0xe9205878, 0x637cdcf6, 0xaa25517f, 0xf3df2154, 0x79eb05bf,
+ 0xc034f6be, 0x0bbf625c, 0xc4f68ddb, 0x7ac62de2, 0x55a6f743, 0xe7071b28,
+ 0xe354b479, 0x79c93955, 0x79ae351e, 0x50cfa426, 0xe317d82e, 0x62ec1110,
+ 0x8e1b33cc, 0xfd6cbfcf, 0x2fe8d84b, 0xfefe7f5b, 0xf5d90b16, 0xaa7d5f8b,
+ 0xac8f0a2a, 0xdbfae35e, 0xa7fae375, 0xdfd71a96, 0x7fae33e9, 0xfae364fa,
+ 0xf5c6fdbb, 0x5c6b511f, 0x7180ccff, 0x8cebb3fd, 0x34139feb, 0x06c8ffae,
+ 0xb7e7fae3, 0x70bbd718, 0x8b3d7199, 0xed0d4bc2, 0xe52febc9, 0xdb9af165,
+ 0x7a01ef8c, 0x2074094d, 0xa04168e9, 0xc677f281, 0x30cf7fb4, 0xc03d324e,
+ 0xf744d1be, 0x6e3ec1bf, 0xf4fe729b, 0xfc8ad201, 0xf1f4c9bd, 0xeec2b96f,
+ 0xfa017414, 0x0ae513a8, 0x614f17d8, 0xd8563759, 0xeda181fb, 0x12bf290b,
+ 0xbee279f5, 0x36b93878, 0x7d894f48, 0x0a7ab0f2, 0x81f6c9f7, 0xf470f27d,
+ 0x8fb31c7b, 0x4f5a8ec8, 0x5d1ba57e, 0xf14f8e1c, 0xcfe825d1, 0xf2f4827d,
+ 0x32700071, 0xe71c7bc0, 0x4f1fe303, 0x8dfe4099, 0xd928b36f, 0x1982ffed,
+ 0xcdd83096, 0xe2ada898, 0x953a4f3d, 0x2f6f42f5, 0x858ffe14, 0xb95be0f6,
+ 0x9851efdc, 0xc5e6e385, 0x7b14bce8, 0xdd79c46d, 0xe3027123, 0x4f782008,
+ 0xca011c61, 0x9ba73b5e, 0xf8ae52d3, 0xc049ee99, 0x4ae9fce7, 0x6ab5d929,
+ 0xcd3de50a, 0xfd2141bf, 0x787fff34, 0x2cfa1719, 0x4cb95cb9, 0xd85db3e2,
+ 0x482edc03, 0x149ac3c7, 0x07416277, 0xc2e7cde1, 0xb8fe8675, 0xfc47ff1f,
+ 0x0ae3cd7c, 0xd06726d3, 0x675a3331, 0x0f3c6f5c, 0x9c38daa5, 0x0d999b8f,
+ 0x058139f1, 0x57bc0ec9, 0xfbc6d103, 0x7bfbcf1b, 0xd3fa1463, 0x7cfff554,
+ 0xcfe306ad, 0x9ffa2e38, 0xfe863e1d, 0x63ebd566, 0xf41abfe8, 0xba14c0fc,
+ 0xcebfa324, 0x87f87bf8, 0xc27e9178, 0xbb2f413c, 0xbdfb8c9d, 0x2386fc92,
+ 0x98c09055, 0xe7e663bf, 0x16dabdc3, 0xe63c9fbe, 0x984d635b, 0x37666337,
+ 0x32fbe79e, 0x6df3087b, 0xc7e4274f, 0x790cbac3, 0x3cb4e98f, 0xb657efae,
+ 0x71865c36, 0x07115ea2, 0x7835a7bb, 0xaab7ae19, 0x0e2f28f9, 0x277257ef,
+ 0x40f16f7c, 0x6a9f027b, 0xdd43068e, 0x5e1008ec, 0x10b6b556, 0x3dc598dd,
+ 0x6ef3ab50, 0xfc130573, 0x148e1712, 0xcc2d86f6, 0x984c595c, 0xc1f7f0c6,
+ 0x55f38674, 0xc4e9da5d, 0x0bd5a87d, 0x2bca25fd, 0xfa2590ad, 0xb6b4d7ad,
+ 0x94abdc10, 0xb33b1060, 0x3b51668e, 0xe1aadbe0, 0xbe785459, 0x67922af5,
+ 0x3e6de716, 0x3867f7bc, 0xdabd59fc, 0xc87289e7, 0x8728d23f, 0x5db56fee,
+ 0xd95af88e, 0x93c68cba, 0x756f6b78, 0x8df58e5d, 0xbed15ead, 0xb54dda82,
+ 0x71f482ba, 0x8621681a, 0xc7ad1671, 0xb03d7189, 0x03c61933, 0x045b5ecd,
+ 0xe1eac899, 0x05a3b2f0, 0x5d731f44, 0x8df4061c, 0xbc7d03e5, 0xfb4cccb3,
+ 0x1df3dbd3, 0xafedfef4, 0x0fd1798f, 0x1e01607c, 0xf98aff51, 0xf0238ff4,
+ 0x88721167, 0xf200c169, 0x23572595, 0x6b86747f, 0xdfe3ad36, 0xbbc49fda,
+ 0x1f28cec5, 0x20ef92d4, 0xe17cebbb, 0xf7148d0c, 0x27bc0950, 0x44f00fe3,
+ 0x8176f472, 0xe2efdba7, 0xefdbbe7e, 0xcec79460, 0xd55fc196, 0x148d5d00,
+ 0x059b25f2, 0x056f6ca8, 0xeb8252c1, 0x0b416365, 0x49d675e8, 0xbfd1db2f,
+ 0xcd7eed83, 0x4deaa18d, 0x58599e35, 0xaa7c9c6e, 0xbef1d91d, 0x618b3f4b,
+ 0xc474be89, 0x4581ab97, 0xc51fccf0, 0x1d783d8e, 0x89a7af35, 0x5e3ab4f6,
+ 0xe9ed174f, 0xf7cf5e01, 0x20d4a93f, 0x97f14960, 0xd5c6477c, 0x2dbe51a3,
+ 0xb27cfc60, 0x3b60e7b8, 0x91c2f213, 0xdb06ab31, 0xbe74626f, 0x50ffb640,
+ 0x4e38e7b4, 0x394629ac, 0xfdf8c73c, 0x6c878156, 0xe9f689c7, 0xb6319f14,
+ 0xa64af8cb, 0xf42bece3, 0xfdb1997d, 0xd3bdf141, 0x1d363671, 0xc71b47db,
+ 0x53da20df, 0x08ef3c1d, 0x473f21c4, 0x15efda2f, 0xc76c76ed, 0xed8d4bf1,
+ 0x2bf8c56b, 0x43ad0095, 0xf8899f3f, 0x9d568ee4, 0xf67cc9ea, 0x7e0cc8ea,
+ 0x99f0598e, 0xf21b196b, 0x23abfcdc, 0x9a4cbe79, 0x0ff7e3de, 0x7b650f21,
+ 0xb8a34b86, 0x10b5eaaf, 0x421d591d, 0xec3e088e, 0x8b4a2397, 0xf717138f,
+ 0x3d197f97, 0x8e7ee103, 0xfe00acf2, 0xbef39e90, 0x04c16263, 0x98db9679,
+ 0xef0982c2, 0x1864177b, 0xe53759ea, 0xccf7de1a, 0x77686519, 0xb4378e54,
+ 0xf13e58b3, 0xae826dc7, 0x0c2aca52, 0x02bef2ed, 0x923e73a6, 0xf479b576,
+ 0x677bc314, 0xa474f54b, 0xcb57d3ed, 0x367cabfb, 0x39b70b94, 0x1f236547,
+ 0x3275a4fe, 0xef20df1a, 0x8974a26c, 0xc9474bd2, 0xa2eab656, 0xc7f54a5e,
+ 0x7aaf3cdc, 0xd78fab65, 0x6f9d188b, 0x4b5ad95e, 0x2f81c7f5, 0x56d7fcb1,
+ 0xa07b953f, 0xfb0e160e, 0x43aff411, 0x7fa13b3f, 0xfd023fac, 0xfa1db963,
+ 0xd087f2c7, 0x856fb63f, 0x10feb17e, 0x83e585c0, 0x7f3e0fd0, 0xfac7fa00,
+ 0xd500d6a6, 0xa3ad6bef, 0x20d686fa, 0x36b6f795, 0xadb5f3d0, 0xdd5f542d,
+ 0x7bca8cba, 0xae54c35a, 0xed435d6c, 0x1f37a116, 0x1f1fe713, 0x7dcfc69b,
+ 0x467faf27, 0xeed5f29e, 0x4504a8bb, 0x93c8655e, 0x7dc3c8c8, 0x2f31a775,
+ 0x7047f110, 0x931e39d8, 0xe02b18e1, 0x2b62cf18, 0xa0dcb952, 0x2e98eb38,
+ 0xc0a9dddf, 0xf85b23a7, 0xc57517ba, 0x81a73da9, 0xcc56378f, 0x2cc27993,
+ 0xef1f8aaf, 0x957af7c5, 0x8f2a7558, 0x831f9337, 0x553f0179, 0x9133dce2,
+ 0x7084c479, 0x7f419369, 0x1fb3cc27, 0x270e6e5f, 0x78286de2, 0x7c78f22b,
+ 0xe4ecad43, 0xb6d49bf7, 0x52cd9147, 0xbf742dfc, 0x102ead89, 0x04f4a0d5,
+ 0xc24f7482, 0x603373f8, 0xed720593, 0x874ce5dc, 0xb8d1af32, 0x505dcaff,
+ 0xa8e7d861, 0xfd3236e7, 0xccb7e822, 0x194a4fb8, 0x3be19b7d, 0x0cf7de5b,
+ 0xddcf16ed, 0xb7f9f686, 0x22f2ad14, 0x8a32473e, 0xafd7593b, 0xd7003960,
+ 0x044d8ec2, 0xbde05057, 0xfdf9d157, 0xefc5fbed, 0xfffb0844, 0x2f812ec7,
+ 0xd7da7adb, 0x6af3758e, 0x84d87a49, 0xa7e3e7fa, 0xee8e49d2, 0xfe44c47d,
+ 0x622c71ed, 0x01337942, 0xbf6c48cc, 0x56726f00, 0x151ccae9, 0x574ce5eb,
+ 0x8b117eb1, 0xec08bed3, 0x17a43aff, 0xb11fffb0, 0x7e4cfd43, 0xbf3cc7f0,
+ 0xba7a4a2b, 0x8967ac44, 0xd16d07dc, 0x73c3fd92, 0x635fc8f3, 0x26d6073c,
+ 0xdc2b01f6, 0xef18d955, 0xff261ded, 0xd6fde9ce, 0x1eb005d4, 0x2a3a9cce,
+ 0xba0df3e5, 0xd173c869, 0xbf2abecb, 0x623d016c, 0x086597e4, 0x9fca99ff,
+ 0xaabba167, 0xf89c7479, 0xe52ccda6, 0x728e9e98, 0x4beea06c, 0x3ba2bb27,
+ 0x89a3f087, 0x1adbd9f5, 0x3900fca4, 0xd377ed4f, 0x560f985c, 0xf74ff222,
+ 0xb53adeb5, 0x661f2126, 0x52dfa0b7, 0x3d45ab16, 0xf2665a5a, 0xaf27a845,
+ 0x1f617fc1, 0x73c7eedd, 0xf3055afa, 0xc71e18a1, 0xbabce9da, 0x794a85f6,
+ 0x4b91da40, 0xb0760e98, 0xe16511c3, 0x997e81b2, 0x477c83f0, 0x5ccff5c8,
+ 0xad0f3435, 0x3e47da40, 0x33ecddd4, 0x74863f87, 0x998759f7, 0x6309e5b3,
+ 0x9183a97b, 0x6a545b9e, 0xa60ae889, 0x3dd3b423, 0x850eda8b, 0x1c2115e5,
+ 0x50f3bdd3, 0x254c1f8f, 0x52dd4dba, 0x7bc35745, 0x79f5c14c, 0x1e99c700,
+ 0x1a49a0fd, 0xd35ef057, 0xb42ecb04, 0x5e22c71b, 0xa5d19c70, 0x6285c784,
+ 0x575afbbe, 0x159e9e10, 0xefcb68f3, 0x87873bc7, 0xcf78fcf9, 0xe90ea2e9,
+ 0x73ce31bf, 0x37f56543, 0x95c6def0, 0x74d85531, 0x33ae7c46, 0x53ce26c7,
+ 0x3802e006, 0x5538459f, 0xbffc9b84, 0x8f4d7e7c, 0xc819bf70, 0xbb8a5ab1,
+ 0xc4b1324e, 0xa32cabb8, 0xc8cdfe42, 0x4ebc1173, 0x0ba9dcef, 0xdfac4a2e,
+ 0xb8fd7444, 0x761fe7c2, 0xcd2f3c6a, 0xfd13d7ef, 0x7ee4ebc4, 0x487f9c59,
+ 0xdff6f011, 0xe79e36e3, 0x6c583a61, 0x0d2de60b, 0x25fe1fb7, 0xc4a4ca2e,
+ 0x18e830fd, 0x649d5718, 0x759f3ca3, 0x7f4b8f32, 0x337cc743, 0x8afcf12c,
+ 0x6ae9d04d, 0xe4af31a7, 0x77b71e5c, 0xe8f589ce, 0xc6be71b3, 0x567964b8,
+ 0xdd17bdc2, 0x91ffe4f5, 0x6ebecc71, 0xfd2e0f9e, 0x09044b6b, 0x78e51df4,
+ 0xa5587be8, 0xee92e5f8, 0xa17df96b, 0x7ba01e87, 0x1d2fa156, 0xbc5ea1e9,
+ 0xe8c6bf5f, 0x3bb059ef, 0x1f452ab0, 0xc45a57ec, 0x48d7e4c2, 0xfb2527f6,
+ 0x279b7e91, 0x563e69f6, 0x93ca718e, 0xa58f8beb, 0x88a67ee0, 0x91dbb9d1,
+ 0x8f7493ea, 0xedfb5831, 0x2b294f78, 0x24f4f7e3, 0x0525fbaf, 0x3ef3c216,
+ 0x1c63aeb9, 0x37d867e4, 0xbefff389, 0x7d7ecf17, 0x96f3f40c, 0x81ce18ae,
+ 0x099ba5bc, 0xae81e38f, 0xac64ecb1, 0xa0fba876, 0x5f4df3b2, 0xa5c0bced,
+ 0x68d7dfc6, 0x9639eaea, 0xcbbc93aa, 0xfa7807ca, 0xad3efd8e, 0x4e27f88c,
+ 0x575107bf, 0xb841e1c4, 0x7ecbfcf1, 0x137327d3, 0xbe7c60e9, 0x7c83edc6,
+ 0xbf9357d3, 0xceb84635, 0x7599bd94, 0x1c6b870d, 0x3d1bd5c2, 0xb7689591,
+ 0x0ff6b848, 0xa5fabf73, 0x934f155f, 0x0120fa8d, 0x12ff534f, 0x865bf69e,
+ 0xc0966786, 0xf28e4fcf, 0xb70642fb, 0xd5fd457f, 0xccf78461, 0x51ebb163,
+ 0xb3bc023c, 0x53de7f08, 0x15331459, 0x14acebf8, 0xe42959f4, 0xa8ce8f8e,
+ 0x17dbd0b0, 0xa75e7e53, 0x7743dbc6, 0x79e08a2e, 0x0b8bdf02, 0xe0dfd10a,
+ 0x7ba56e3c, 0x7949429e, 0x2f5cb222, 0x573fb1e6, 0xab0f1219, 0x78bcb9f3,
+ 0xd4f9b5f1, 0x596fbddf, 0xed83ca19, 0x5ef5df22, 0xef0da757, 0xc47895ef,
+ 0x2194057a, 0x2a117c4b, 0x3f2b7bba, 0x218ee9b3, 0xf1f133c6, 0x1be24bee,
+ 0x572c9e39, 0xbb7297e4, 0xe2aa3954, 0x2efb8739, 0xd9ee937d, 0x2352afba,
+ 0xe337fb99, 0xfe127d7f, 0x7d666fa3, 0x8acbd39d, 0x2aa3f47c, 0x037da5ef,
+ 0xfe2521ea, 0x9fc432b3, 0x0ff34825, 0x3b656dbd, 0x6a78c195, 0xe72bf414,
+ 0xe12fe727, 0x80b65e76, 0x7ae099ce, 0xc5abe020, 0xa44f52fb, 0xf387bd0b,
+ 0xa9713d22, 0x4c89cfc6, 0xef5d68d2, 0xce853c9b, 0xf917ecf5, 0x2c4bf114,
+ 0xc32efe43, 0xf76f0233, 0x0c45fb9e, 0x770da9ef, 0x055ee99b, 0xbf78f5a6,
+ 0x7a147409, 0x9a7ba35d, 0xf16a9e81, 0x5f17a8de, 0xfb869b3b, 0x66f903e8,
+ 0x3e40fb82, 0xe77d8797, 0x6f3a5ad4, 0x2e67daf3, 0x9ffe8135, 0x5d8557ce,
+ 0x39e18b12, 0xfc158d9a, 0xd84380dc, 0x4ed78e01, 0x8efc2035, 0x2ab3dfc9,
+ 0x4f767a09, 0xdbbe95be, 0xf9678968, 0x48740e30, 0xdfee5165, 0xfaeffba1,
+ 0x38ba0bcf, 0x8f2b9a1e, 0xe8e09d92, 0x3de2f7e6, 0x5c13af9d, 0x7841f708,
+ 0x33ee329e, 0x57b63d57, 0x06a378c2, 0xf8ba77be, 0xe24ca67a, 0x77dcd0f7,
+ 0x785dcfe9, 0xc2ba5eef, 0x4be8fee8, 0x3906cc0a, 0xd7c45f5e, 0x1632b3a1,
+ 0xe5fc851b, 0xb6af28d2, 0x0d9b7a33, 0x17c97aed, 0xf4a947a3, 0x97916add,
+ 0x29727abe, 0xe3a499f1, 0x57c105b9, 0x02366e91, 0x76493c5f, 0x9d302c4e,
+ 0xc72ae3f0, 0x95c7e3fc, 0x3fb71d58, 0x2fd42e2c, 0x819326a5, 0x380b8adf,
+ 0xec12c8dd, 0xee77b252, 0xf52cb410, 0xc6c45b7d, 0xb7ffbf30, 0xa3a566e7,
+ 0x2796da5d, 0x0dbf3ced, 0x095db5f1, 0x38e117a4, 0xbed2a5ff, 0x4ed7c5ef,
+ 0x6db8e034, 0xdbe42f30, 0x58ea7e7b, 0x9b49f68f, 0x2a7c4fcb, 0x26dcd7c7,
+ 0x9fbc1eb1, 0x2bff16fd, 0xbb8c6fe8, 0x47447df9, 0x43635ca6, 0x4cf787fa,
+ 0xad7bcfd8, 0xd81a0bf8, 0x07f90d4f, 0xcf66ba16, 0xb116efc0, 0x6bb42ae0,
+ 0x86a87517, 0x11ee177b, 0xb9e162f2, 0xd84d1614, 0xfc9c2c1f, 0xb6373a2d,
+ 0x8b1a5cf0, 0x8f75bd82, 0x8f7d1738, 0x0ac45738, 0x443b3d38, 0xdfe515e9,
+ 0x24bef7cc, 0xcbf995bd, 0xdf39f3bd, 0xb7e802b3, 0x14b1e949, 0xa71b10c1,
+ 0xebce9efc, 0x62ead7bc, 0x780492d1, 0x0473cd07, 0xd38c268b, 0x1b39deff,
+ 0x7d6067cd, 0xcc0efd39, 0x787841d7, 0x784bd5af, 0x91ffbe1c, 0xf40e3c06,
+ 0xc780ca3f, 0xd097fdc1, 0x96b5eff8, 0x13ff497e, 0x375fe986, 0xefd03fc0,
+ 0xf7b71a68, 0xa71ffcc8, 0x891ddf02, 0xf9edbdde, 0x331dfc4a, 0x017efd2b,
+ 0xa6aceaeb, 0x338f8473, 0xe77a673a, 0x83bddfe1, 0xee779af9, 0x8c70f8b2,
+ 0xae7c733e, 0x333d086f, 0x78c2b99a, 0xc72c979f, 0x7cd31417, 0xb4db9f92,
+ 0x32f30b88, 0x0b9aa56d, 0xc6d11f7f, 0x71bb9162, 0x236952df, 0x42e32739,
+ 0xe53fdfb2, 0x3b3cf2a9, 0x6f7907c9, 0x979112cb, 0x5e08ec57, 0xd4beeb81,
+ 0x13fcded4, 0xd283f6f8, 0xcc373a36, 0x33f69b98, 0xe1a36e32, 0xa315bf2f,
+ 0xf0c0305f, 0x7a13cdfc, 0xf77e0670, 0x18271043, 0xd82f51c7, 0xb5bcc41d,
+ 0xb8df620d, 0xfaf31ec1, 0x0de6e412, 0xb357da05, 0xe893da17, 0xf72fd276,
+ 0xdedd3946, 0x227e8050, 0xfcc4f635, 0xedb7cc22, 0xe976f711, 0x55778a16,
+ 0xfefba31e, 0xff7dcbe6, 0x8ebce49a, 0xd1da377c, 0x8694ce32, 0x6b687779,
+ 0xbef7e46c, 0x7af2a7d5, 0xa08c7ffd, 0xffb01073, 0xf9432d49, 0xfee55fb2,
+ 0x3adf1120, 0x67d0e62b, 0xf94058db, 0xe41f22f7, 0x744bf76c, 0x35d9e4af,
+ 0xebfd6863, 0xdd3ef85f, 0x973fb70b, 0x43beb1eb, 0xf563d24e, 0xde155f56,
+ 0x973fb85b, 0x5a9dabdb, 0xc122ad34, 0x579d5d7e, 0xe3f9f24d, 0x894c6335,
+ 0x0aef8ff1, 0xfa51b079, 0x1578b537, 0xb8f9679e, 0xd233fa32, 0xf4ec07a3,
+ 0x83a6513b, 0xfba2abbf, 0xe95a372d, 0x0faa0177, 0x875cdb8e, 0x8d34c3fb,
+ 0x074d91f2, 0x99cf04ed, 0x2d7efc75, 0x5de516fc, 0xf491c1d3, 0xa9f556fb,
+ 0x6c27ca71, 0x6095f14a, 0xe0feafdc, 0xffd7ba54, 0x057186e4, 0x644eff28,
+ 0xaf7405ea, 0xf43c06f1, 0x6343f509, 0x17b5f3f9, 0xe75579d3, 0x50e0d4c6,
+ 0x8fa9107e, 0xdaefef92, 0xdbde5b9f, 0x6719f885, 0x7dfca1f3, 0xb8f1f14f,
+ 0xd9f12bef, 0xf915c53a, 0xd77ad2f9, 0xbc7dfa69, 0x6f778efa, 0x43dcf462,
+ 0x73f72b74, 0x0bd5e3c9, 0x12dfb57d, 0x4bbf8b9f, 0xe052bf56, 0x624efc5d,
+ 0x7e9ca9bd, 0x7de24faf, 0xb73dd263, 0x24fd084f, 0x69af93cb, 0xd8205f74,
+ 0x1fe80511, 0x4ad8793a, 0xe3727674, 0x2eaf3a04, 0x9c07abc7, 0x4f2f80b8,
+ 0x7113e864, 0xf2169f5d, 0xdf257eaa, 0x30e7caa7, 0xe77f0c7e, 0xa5487e30,
+ 0x573eaebc, 0x92e30d3c, 0xef593df2, 0x4ab74f9f, 0x3fb597bf, 0x6f5a45f7,
+ 0xf48627a0, 0x49c17a64, 0x82f43a7a, 0xe7ae1775, 0x8c2c95c7, 0x5bf0cffe,
+ 0x8ec7f7fc, 0xfd92b21c, 0xef9c77dc, 0x9fdd076f, 0xe01788e6, 0x17a1a1fd,
+ 0xeb1c9246, 0xe0ef8fcb, 0xdf9db6f6, 0xf046f8ab, 0xcdff1162, 0xe611f711,
+ 0xf9f79da0, 0xed147b21, 0x9e29283c, 0xbdbb6610, 0x2a70fcf4, 0x940fff43,
+ 0xca63cf14, 0xeefd2f01, 0xdf176b0c, 0x3bfbe8c7, 0x5163820b, 0x0c59df2e,
+ 0xfbf03bfd, 0xe7def453, 0x521782a3, 0x5cb18a0c, 0xf52e5e31, 0xa42c1f9b,
+ 0x5e67cae7, 0xed2a7bfe, 0xed463da2, 0x62f06b21, 0x9cafc79a, 0xf310e76c,
+ 0xeef7aafc, 0x41182d1d, 0x06e128eb, 0x98dd933c, 0x05b3978c, 0x3b7bf126,
+ 0x74c91f1c, 0x5f9ebfd9, 0x5ffa1f02, 0x21f6bce8, 0xc6eb8ebe, 0x591cb859,
+ 0x63ec813b, 0xc86296d6, 0x88715b9f, 0xbbd0c3df, 0xdceb49c1, 0x843ff667,
+ 0x86fe28fa, 0xed7bf199, 0x3f4022c0, 0xf9a1e4c5, 0x4f9123e5, 0xcf2d64bf,
+ 0xd1e8fbb3, 0x39e60bf7, 0xfbf25cf0, 0xd2c97386, 0xa49d085f, 0xe1c63fa1,
+ 0x97e6d3d3, 0x255d7b71, 0x7aeff8f8, 0xf4eb346d, 0x0de16bbb, 0x711fc8e3,
+ 0xa41fa2d2, 0x775b87df, 0x4ae90981, 0x77f2172d, 0xbc9f9f13, 0x7bde4b2f,
+ 0x8a9f8c95, 0x7f9262c2, 0x33782c4d, 0x827ea1de, 0x61c259e9, 0x91fff746,
+ 0x6984df7b, 0xe29f9a88, 0xf485acb6, 0xf67be0c2, 0xbbf25f2c, 0xf5bbff6c,
+ 0xf42b5c2a, 0xd38795ef, 0xe07eaf50, 0x3a46fbe2, 0x5d7a8f7d, 0xc36cf3e5,
+ 0x83af300f, 0x4e14a605, 0x879276a2, 0x5dbc281f, 0xf341b9ca, 0x7ec17a47,
+ 0xebe83df0, 0x7fee429a, 0x710cae63, 0xc16c2bc8, 0x9fa94d3c, 0xc2668a42,
+ 0xdca7f373, 0xe3d21a7a, 0x19c5b5a9, 0xc60f302b, 0xda2567ad, 0x8ca3a1d5,
+ 0x78eb8bce, 0xf8c5f8df, 0x89fe32fb, 0x9fdbf7e8, 0x243bf461, 0xb4e4f3c3,
+ 0xed89b99e, 0x9eb90a73, 0xf6285f9b, 0xe44c8599, 0x8de32657, 0xb162fbaf,
+ 0xf0796aee, 0x2687da72, 0x4b78b7bd, 0xa487a0ba, 0x7fcfede7, 0x1ea0f297,
+ 0x4913de36, 0xef185fb1, 0x612c5783, 0x532c42e5, 0x61bdaf28, 0x0d739713,
+ 0xb92cceaf, 0x5ee9d78b, 0xef3b6985, 0x59e3dfa1, 0x12caebb0, 0xad16e5c6,
+ 0x05c7a483, 0xb412fe05, 0x555be2e3, 0xc345f217, 0x51e09516, 0x56d73ecd,
+ 0x8b7a7e78, 0x06bbec99, 0xbce9cf01, 0x9bad1a60, 0xe00b34c6, 0x4c16b4fd,
+ 0xab75fb23, 0xa4a1ddf8, 0x6f7bc079, 0xe043156a, 0x99d7c6c7, 0x043c53f0,
+ 0xa261bc1d, 0xbf805a75, 0xec70890b, 0x79bfc854, 0x33783f3a, 0xfec14fd6,
+ 0xabe9cf1f, 0x7dd0969b, 0x3ef8c936, 0x7d120b6d, 0x91f3162e, 0x471e4cf8,
+ 0xf10fb3e2, 0x2bd2f689, 0x85ef4853, 0x6291541e, 0x9fdd8bd9, 0xda7cbed2,
+ 0x99df2ba1, 0x8137cf8a, 0x9ea3a2dd, 0x6fb3f51d, 0xa35b9ea3, 0xfe7a8c52,
+ 0x962ce2a1, 0xff71afa4, 0x39f5ff39, 0x3d04a669, 0xf1c83ea9, 0xa4e73aa4,
+ 0xcff7a42d, 0xebe91d7e, 0xaacbee84, 0xf1ef7848, 0x83b8fec2, 0x37eabd61,
+ 0xc70d21fd, 0xa66f5869, 0xe975c979, 0x7ca079c3, 0x208d4f6b, 0xc5e5f7fd,
+ 0x4eb95fa9, 0xeb8df4fd, 0xde09e920, 0x9742affb, 0xf24c2718, 0xb05154e8,
+ 0x9d0437ca, 0xc6007a2c, 0x38b6fec5, 0xf3d2fee9, 0xa3e2571d, 0x5f05bd7f,
+ 0x71d71d53, 0xd1f91147, 0x74686f4d, 0xfb44e0c8, 0xc7c80555, 0xd02fa0f5,
+ 0xc4af516f, 0x647ba1df, 0x1ee9590f, 0xb74dfae6, 0xd5e38cdc, 0xb09ab71f,
+ 0xabe1d4fd, 0x495c1226, 0x2a780aeb, 0xfbde8a18, 0xbe05e28a, 0x3d81fc04,
+ 0xe72dfc41, 0xc1370093, 0xba29fb01, 0x08afa88f, 0x0e4133d6, 0xedc859bc,
+ 0x65df782e, 0xf7e6fa21, 0xd7cff561, 0x575f3495, 0x64df7cd2, 0x17ccdf44,
+ 0x782cf9a4, 0xe7c26adb, 0xb6bfee0b, 0xa73df704, 0x79a74dd6, 0x4ff0ca9d,
+ 0x553afe44, 0x210ffd00, 0x0fdc172f, 0x0bfb2cf3, 0xd3b76cf3, 0xcf3b0d7a,
+ 0xf60ef88c, 0x89f9e617, 0xcf3943a0, 0x0d3d34f7, 0xcf43f9f3, 0x2efd0caa,
+ 0xc6c0fca1, 0xbf4ebca9, 0x73321713, 0x4a6d087a, 0xdedf7ca5, 0x04fbfe6e,
+ 0x78c00e52, 0x260f49e7, 0xd55387a2, 0xd0c9e6fa, 0x3f07ffdf, 0x00b71737,
+ 0x0000b717, 0x00088b1f, 0x00000000, 0x7dcdff00, 0xd554780b, 0x733effb5,
+ 0x64932666, 0x08124c92, 0x3c984081, 0x49849009, 0x768a8802, 0x02d10478,
+ 0x89794f0d, 0x42100793, 0x69b5a05e, 0x0240cd6b, 0x350d45a2, 0x01d45a2a,
+ 0x0da2a281, 0xbc150a0a, 0x45622a03, 0xb68b57c5, 0x514026e5, 0x5ea0c679,
+ 0xffd7b5ae, 0x4e7dadfa, 0x5490ce72, 0x7dfbdedb, 0xdf1f7cff, 0x5afd9f66,
+ 0xd7b5ed7b, 0xe7bdaf5e, 0xcbaa3dc2, 0xe4e216ef, 0xff6f05dd, 0xf7a517bc,
+ 0xfc812eaa, 0x02cddf58, 0x2cc38ff9, 0x934a14fe, 0xfe70a68b, 0xa56b9b65,
+ 0xa689c422, 0xa141fdbf, 0x367d85fc, 0x0bf2a0b7, 0xcef74529, 0xea8f7e46,
+ 0x2fed415a, 0x259f680c, 0xd8b97386, 0x5deae544, 0x2e509a23, 0xcae61e1e,
+ 0x0df2f2a0, 0x09644261, 0x6856fbfe, 0x3be9237f, 0x6ba50b52, 0x34786f55,
+ 0xfd2f4da5, 0x6fa5c944, 0x578f3756, 0xf724abf3, 0xb97e34dd, 0xf9ed5855,
+ 0x399edca8, 0xf388472d, 0x03136d7b, 0x233f32d9, 0xb03fcb87, 0x5d8d7952,
+ 0x7bf85af8, 0x0e6a7dad, 0xd2b6e28f, 0x0fa98b38, 0xfae94a91, 0xea60ef18,
+ 0x938d317f, 0x8b7de342, 0x0e5c1fbf, 0xe7cb0edf, 0x9fa88a0b, 0xf6626d7b,
+ 0xf55dd973, 0x4ddb34f4, 0x6d46f61d, 0x553b577b, 0x3cc62588, 0x2422a1e1,
+ 0x477914bf, 0xa432be57, 0x7ca42abc, 0xa7cfbf47, 0x1f2f3914, 0x1fc6037f,
+ 0x12c785d1, 0x2c3b8f0d, 0x72eb1df4, 0x44d8128f, 0xbab12dff, 0xfe09cbed,
+ 0x9b88c6e7, 0x55a94fd1, 0x47cdae38, 0x5f9e0ebd, 0x86345589, 0x87bbe3e5,
+ 0xa6f3e9eb, 0xe2c31afe, 0xced11f28, 0x89bd53e3, 0xda9e4376, 0xab9ae09b,
+ 0x4ba7a3c1, 0x4ebb85b7, 0x7fa0f3ea, 0xa6b12d55, 0xbeeecd7c, 0x7c0693ae,
+ 0xfa7fc52f, 0x3449bfd2, 0x8bc091fb, 0xdddaabfc, 0xe892307a, 0xcdf14da7,
+ 0x17bf5375, 0x9d1d7e0e, 0x1f75e6ed, 0x9beb4459, 0x7f3ea6af, 0xbedbe698,
+ 0x426cf547, 0xfdd86fbf, 0xe7fd0c4a, 0x6e0f8b9b, 0x2fd5efa7, 0xddbb89a7,
+ 0xc50ff35d, 0x17dd85e3, 0xfbe953a3, 0x08f643f9, 0xb9e68c31, 0x9dac7e37,
+ 0x5c4762e8, 0xaf78b77b, 0xef5dd6d5, 0x35b5bcef, 0xdea1aa7a, 0x3d1ad179,
+ 0x252f40cd, 0x8bd62fbb, 0x5f9fc65c, 0xefc2efcd, 0xc7bd7d89, 0xf4bdf4aa,
+ 0x5ac6fdf7, 0xc35fbd28, 0xf736bddb, 0x6e096b13, 0xcf309eff, 0xfcfb8216,
+ 0x682db31b, 0x728dfe7f, 0xcbcdbd2d, 0x244f5fe9, 0x8b68fc63, 0xbc7d77a4,
+ 0xf70b6e35, 0x7b696a53, 0x8fda1aec, 0x93ebbfa5, 0x55d290d2, 0xcfc96a5e,
+ 0xb76f3ac4, 0xdc002fb5, 0x46b115e7, 0xe7eaeb89, 0xdb9bb77e, 0xc9f3df9f,
+ 0x270fe063, 0x4f901dee, 0x41f94d64, 0x3f2a3eb9, 0xa64151ff, 0x7f3dfa8b,
+ 0xf80f5f4f, 0xfb9b76c2, 0xbbb7a636, 0xf7d83ca2, 0xa7187f7a, 0xb9effd16,
+ 0xe90fa462, 0xca5e1247, 0xb8e4fae7, 0xabbf257e, 0xfb8b68df, 0x17e0d1be,
+ 0xb679b7bf, 0xeffcb250, 0x31627d69, 0x6ee7ec3f, 0x4d74a1d6, 0xf89b7098,
+ 0xbb864ac9, 0x22ec7844, 0x030b964d, 0x228995bd, 0xc9b0befe, 0xf1117dfc,
+ 0xbc5f7c09, 0x5cbdfcde, 0xa56ead34, 0x98092df9, 0x3fda0bbf, 0x6bec04fe,
+ 0x5ec5affd, 0xff7a0514, 0x4f54cc36, 0x40fe35f8, 0x255f091f, 0xc7c11fb4,
+ 0x8102519e, 0xbbdf5895, 0xe8679e54, 0xa775debc, 0x2287bb70, 0xab4167ff,
+ 0x5b8f5d61, 0xf0913584, 0x1c2edc7a, 0x47e8f989, 0xf5fa8508, 0x6c0b0bef,
+ 0x0f7726a1, 0x04b92afe, 0xc231af7c, 0x5bbe0822, 0x427ce05d, 0x49f7d8ac,
+ 0x5d29fa32, 0x356de853, 0xe6c177c0, 0xd4e7e87d, 0xe25dfdbe, 0xf8ef54d7,
+ 0x58d340d8, 0xddf8eb82, 0x1ba1a7aa, 0xb1af4eb8, 0xe1014088, 0x02212ee3,
+ 0xf27f94f1, 0x5a62e493, 0x7cb6cf97, 0xa4625c92, 0x36cc457f, 0x129ea3d2,
+ 0xef3ebc24, 0xfcd2ef61, 0x305cd38e, 0x5d7ad09f, 0x57866beb, 0x2ab867c7,
+ 0x87a3bb6a, 0x54f740cf, 0x5577f59e, 0xf7efb178, 0xcfa002d9, 0x3c5f8dc8,
+ 0xb9f40f38, 0xa14ae6d7, 0xa9f66bb1, 0x2de6955e, 0x0c81a8f6, 0x4f7b639c,
+ 0x9ce05744, 0x52e053d9, 0xd9aef30d, 0x7ce116a3, 0x62fbbf39, 0xf7366942,
+ 0x44edc533, 0xa03c07fb, 0xf8e09edf, 0xf7fd5b9b, 0xccd79ff8, 0x7f65ceff,
+ 0xf8037090, 0x9953c6c0, 0x07c4efe0, 0x79a6e6ff, 0xc6fccf9e, 0xad10bc8e,
+ 0x047f4123, 0xe09bb45f, 0x2af810bc, 0x8e5c105a, 0xd037aabd, 0xa5443acd,
+ 0xff4f19d8, 0x09137c32, 0xf82e84be, 0x94a89e08, 0x56705d11, 0x38eddbbb,
+ 0xa2382f67, 0x694fc173, 0x12f29342, 0x0dc9f3b4, 0x493a5afe, 0xbf1d7f10,
+ 0x70cae167, 0x8a4d0bc8, 0x97be8c27, 0xdcf955ed, 0x191bdb2a, 0x3f1816c0,
+ 0xd2f9c9c8, 0x1840d547, 0xa3a827e5, 0xea9b30ff, 0xf547be2f, 0xfb148ed0,
+ 0x07f6de37, 0x8375d61b, 0x881ca04d, 0x344b5c03, 0xfdec96b8, 0x8d0a67e1,
+ 0x2ddf78b3, 0xe2ce3007, 0x170f1407, 0xe8edf3a8, 0x8a43c977, 0x67405788,
+ 0x3a46e3b6, 0xce64d85b, 0x0bad122f, 0xc1fc1554, 0x9ef09dfc, 0x96fd415c,
+ 0xdd730eef, 0xa102f18d, 0x4abc42e5, 0xff68d4f0, 0x3b58cacf, 0xcfd500f7,
+ 0x3c6768da, 0xe2170f9c, 0xb5abf608, 0x0d204135, 0x1d6326b6, 0x6bf9efcf,
+ 0xe6b1d632, 0x2995ff77, 0xcebf59ba, 0xaa37b4fd, 0x2148a9d7, 0xc4514eae,
+ 0xfba0a9b7, 0xba8a538b, 0x201b6fa9, 0x9b36c5f7, 0xca879fbf, 0x8afc6c0f,
+ 0x3d85c1f9, 0x6eae81be, 0xbf6bb7e8, 0x892dc3fa, 0x02e18348, 0xd716f0e9,
+ 0x2427d80d, 0x35be620f, 0xdb4f569b, 0x97f0f944, 0x44b9386c, 0xf793864d,
+ 0x42c7f60b, 0x3efabf43, 0x80be06d9, 0x0fe48474, 0x1cf201b6, 0x7b9daa3d,
+ 0x4c77f6db, 0x9e06e8c9, 0xd71b6ea3, 0x5c100db3, 0xd17759ef, 0x845bd05c,
+ 0xbe0d1fc5, 0x775ebc2d, 0xa2b3c22f, 0x5d4357d1, 0x89ef82ad, 0xfed389a2,
+ 0x47d385a2, 0x5139f085, 0xc05c785f, 0x620310b3, 0xf3de3f81, 0xccbecf8c,
+ 0xadac7f37, 0xe8357821, 0x022b1fc4, 0xeaffe85b, 0x63508746, 0x46b5ed20,
+ 0xce5451a3, 0x5206fbb4, 0xd503edb9, 0x1dde40a2, 0xc7a7afa0, 0xa5f7fd85,
+ 0x718c4673, 0x2e1ff6fd, 0xaafe8899, 0x8c22a976, 0xd3b73bfa, 0xd44e8226,
+ 0x7c02fda7, 0x9ec2fe1c, 0x57b4be02, 0x6b979011, 0x35ef8f28, 0x80deada3,
+ 0xa4772f01, 0xd50f18d8, 0x9cf29929, 0x4d0f7ab6, 0xbbcf7ea2, 0xeb90ec4a,
+ 0x26cb876d, 0x25b1bce2, 0xd701d896, 0x1d63c3fe, 0x58b75829, 0xd59bef2b,
+ 0x8f71f57b, 0x547fd0b8, 0x6f0c07ec, 0x4445b663, 0xa3c6bb53, 0xa6460161,
+ 0x30a1f243, 0xc18daf0d, 0x37770ef1, 0xe317e3eb, 0x2a28c493, 0x044ea9df,
+ 0x255ce79c, 0x2da3ac2e, 0x0aeee896, 0x4ef36f6a, 0x0dfa9abc, 0x078b8d8b,
+ 0xd2526b7c, 0x8abf3d78, 0xbf3865ad, 0xcfc2f122, 0x08b6b7fb, 0x65fec6f9,
+ 0xe9bee32a, 0x35cfde21, 0xd47e390e, 0x51cf953e, 0xe343a571, 0x4abbefdb,
+ 0xc9059c69, 0x0f4147be, 0xc46dfc9d, 0x39fc02ab, 0xf96162cb, 0xe735f1ac,
+ 0xbd21f05a, 0xa48a6cfc, 0x563d7d37, 0xc0bab2f5, 0xe8d51e3f, 0xc8ab9573,
+ 0xa7986f91, 0xc345b7ad, 0x78039157, 0x3a2f61da, 0x9da5f384, 0x3cdce3be,
+ 0x01cd3890, 0x59ea853d, 0x7aa9cfd0, 0xf47631da, 0xfc01c33b, 0x3255ea2e,
+ 0x8b16ed01, 0x6fd8d5da, 0x22abd78b, 0x8dabe068, 0xa2ee3936, 0x1822114b,
+ 0x22ee35df, 0x7f6e3f5a, 0xe9045a29, 0x970c6ddc, 0xe4a31af5, 0x452379fe,
+ 0xb50f9fee, 0xf969b4f9, 0x7baf997f, 0x5cfd7ccc, 0x96b61fec, 0x46fefe48,
+ 0xa55bf50a, 0xa1484eb4, 0xec4eadf9, 0xa7bf03b0, 0x98225dea, 0xb2f78069,
+ 0xa08bc679, 0x7acedc61, 0x9f3c1c97, 0x3370f5ae, 0x75f35dfc, 0xd54e1e32,
+ 0x7b1e3227, 0x84c93fee, 0x53feaec7, 0xbcbc784d, 0xff1e4cff, 0x77d67d54,
+ 0x87b43ff4, 0xf826ddfe, 0xe74dfabb, 0xdf6ec571, 0x3b97f040, 0x980fc45d,
+ 0x505f886e, 0x3df15db9, 0xdbe4357e, 0xe404c28f, 0x7dc2afbe, 0xfe065c83,
+ 0x65ce0df0, 0x4982e7d6, 0xd17eb7e0, 0xeecd69cc, 0xded0138b, 0xfb017c4d,
+ 0x11af2f49, 0xf8270ced, 0x3583e885, 0x7cb9bab4, 0xf4106fb7, 0x4e8e1d22,
+ 0xa775e679, 0x20fb42df, 0xa3dfdf6c, 0x582f8fb1, 0x2878a7db, 0x46abd96d,
+ 0x7c75f71a, 0xb1a7a4aa, 0x6dc8be03, 0x68d5efa5, 0xb6ef7c47, 0x020e9797,
+ 0xdac3aa7e, 0x81f70173, 0x8b96ff97, 0x7dabe473, 0xfbe2074b, 0xf2cfaa36,
+ 0xdabdbd87, 0x5d2fe863, 0x5196fcb8, 0x5533a95d, 0xefd0ffee, 0xf435f6db,
+ 0x89db1c03, 0x0b9209bd, 0x0a2aebab, 0x0d83c64e, 0xff07ef79, 0x58b7c412,
+ 0x5d3dda1f, 0xeef9031d, 0x28799243, 0x948f7c3f, 0x100f861b, 0xe40a4b01,
+ 0x83670fbe, 0xb08f544f, 0x470aa0bb, 0x79611de4, 0xc384623b, 0xbffd50a5,
+ 0xdbe397f7, 0xa1a42f21, 0xe83c617d, 0xf164caf9, 0x1b6dc9ef, 0xf04ff642,
+ 0x34edeabd, 0x3ada955e, 0xfbc29c65, 0x7c153f28, 0xde2fadfb, 0x04d7f4d6,
+ 0x9c01cfac, 0xfbcf046b, 0xa9653f5a, 0xcf502bbe, 0xe7bd68e7, 0x7337aa0a,
+ 0xe864df56, 0x7e9ac547, 0x52112626, 0x947e64ae, 0xe5c83b03, 0x83d4b6e7,
+ 0x3e7c525e, 0xd7dfc1e0, 0x35f9c1e1, 0xfa384934, 0x62455e12, 0x8d1a7520,
+ 0xa2d5213b, 0xc0140fdb, 0xe39b443d, 0x965afd33, 0x1939f2c7, 0xfd1d0388,
+ 0x4b4ee3b3, 0xfc064ef5, 0x670ffd7a, 0x75f1cbcd, 0xf2e86e73, 0xb2deddbc,
+ 0x57b6700c, 0xfc7f5939, 0xeed44500, 0x41615989, 0x8a7a1a35, 0xf9f40d73,
+ 0x0e0b91a3, 0x8c7c26f6, 0x43cdf28f, 0xbc6fb3ff, 0xcaf2357e, 0x72f77881,
+ 0xeb7173d0, 0xc2efd648, 0xbca3377d, 0x981be1d2, 0x373c5340, 0x062837c0,
+ 0xbc517c87, 0x9451275c, 0xfc2dd453, 0x45629e12, 0xe518df8e, 0xc53f472b,
+ 0x5d8f2396, 0x23d66f81, 0x8d106f6c, 0x739fb9bd, 0x9dde5176, 0xe1e3affc,
+ 0xfd8f3698, 0x25ed7136, 0x75fedf9a, 0x82069e31, 0x1bceecb7, 0xba50d417,
+ 0x109452d0, 0xdf704d54, 0x575d4a96, 0xf6078bfa, 0x9cee7925, 0x4ebb834d,
+ 0xcaeadb83, 0x50e7ee34, 0x79741bb8, 0xeb0a17e5, 0xf947fc83, 0x81b1fd17,
+ 0x661f29bb, 0x74c1f8b9, 0x16395b9c, 0x886c93b6, 0x7a45bda0, 0x9c1a3be4,
+ 0x73bed28f, 0x35f7f1c4, 0x21189ef8, 0x683e27db, 0x507ec009, 0xaf0f7634,
+ 0x4ed513d3, 0x15634a8f, 0x721db70b, 0xb2f0a950, 0x31d7fcfe, 0x4ad7db7f,
+ 0xf54e6af3, 0xddbc07dd, 0xfe496f1c, 0x0df0e180, 0x6b790a9d, 0x3fc79cb4,
+ 0x1e793790, 0xc6cb84d3, 0x6b589942, 0xcd31fc81, 0x50b2a725, 0xba63fb91,
+ 0xde30daf0, 0x7ae3e14c, 0x7bb79def, 0x07bc4fa1, 0xbee0885d, 0xfbf9f851,
+ 0x74e0111c, 0xfd72089e, 0xe72b449b, 0x7d137c75, 0xd24bdcdc, 0x547d27c7,
+ 0xc056ffc6, 0xee646efd, 0xc79a3a80, 0x650687d4, 0xdcd57eb0, 0x5df3f19b,
+ 0xe8d54f70, 0x6feff686, 0xbfd88eb1, 0x699fa833, 0xdfec8437, 0xf5f5bdf1,
+ 0xfb47f8cc, 0xa74748e8, 0x4bece4fe, 0x5b4eb878, 0x4bbcebd2, 0xc2127f59,
+ 0x8fd1f2c5, 0xa85b7db4, 0x5a2f453a, 0xd26e239f, 0x89960897, 0x62259663,
+ 0x10afafbe, 0x3ad0156f, 0x15463ebe, 0xcbd35c0d, 0xfd68a6ed, 0xe13fe94d,
+ 0x0f5bd833, 0xe1af608b, 0x92f0aed4, 0x8218d5ef, 0xbdba8a7b, 0x27ca9631,
+ 0xc6bd27f6, 0xefaeefc0, 0xfd0ac3b5, 0xf37486ee, 0x66d949f7, 0x68b267fd,
+ 0x94fe3152, 0xfb7ae6e1, 0xb3a22781, 0xfea553f7, 0x21888622, 0x0b7af2df,
+ 0x1d3e718b, 0x2fda2e93, 0x69111c10, 0x2eb18fbe, 0x75ff27cb, 0x5615c601,
+ 0xb7ea9f39, 0x1debb655, 0x288b7927, 0xa7ac9c50, 0xca532293, 0x4a7fc825,
+ 0xd3d203f2, 0xcf4e6ef5, 0xf28f79d2, 0xce1ef5f3, 0x9d15a417, 0x6b25bf40,
+ 0x7d62b73e, 0xf8970cee, 0x9a696f2e, 0x762ab000, 0x5a441cb7, 0x809a2c16,
+ 0xa1d17663, 0xef4883da, 0x6adbd4ec, 0xe1d3be59, 0xd3a345be, 0xfda6a25b,
+ 0xe1d68730, 0x87aa3d96, 0x4da603f3, 0x790bdc9f, 0xa27be71b, 0x444baaa3,
+ 0x54572433, 0x012fdeab, 0xdb6f7797, 0xdf9a78c1, 0x18a3f527, 0xbdeacfee,
+ 0xfa99f70c, 0x4a4e9c89, 0xe81bfa2b, 0x673e2bcc, 0xf6f26c79, 0xd5126b36,
+ 0x5e2af42f, 0xbd6bdbec, 0xfda01022, 0xcf26deb7, 0x0e74f581, 0xc98f1f60,
+ 0xade8f699, 0x67da7c02, 0x6671a34b, 0x10a4b0de, 0x55194ce3, 0x1bbd456c,
+ 0x201921bf, 0xbf4e8ba5, 0xf9f5ee8b, 0x76eb6957, 0xf18565ee, 0x2d33b1d8,
+ 0xf2c17206, 0x907d695d, 0xf5d4bf12, 0xade048dd, 0xe18592e3, 0xc11a38ec,
+ 0x6ede86fa, 0xe648aef9, 0xd807cb3b, 0xb760c203, 0x2ceb433c, 0x99e6f20c,
+ 0x36e27e67, 0xe2672b9e, 0x18fabe5a, 0x922fedfc, 0x736491bf, 0xbff011ea,
+ 0xa03cfdfe, 0x9c9af393, 0x24467a4d, 0xcd6abfce, 0x84fe08ae, 0x690899fc,
+ 0x6cf91dcf, 0x2fec58d2, 0x4e1c478c, 0xf32bfce8, 0x7f5287d9, 0x6f1aeeee,
+ 0x8fc2cb5b, 0xb9fca11f, 0xa36fc580, 0x689ce9f3, 0xf03bff39, 0xb64ecddf,
+ 0x10a9ddeb, 0xb77f383c, 0x967ce3f4, 0xc3a88d62, 0xbc022bf9, 0xb714b3bf,
+ 0x55f88eb5, 0xf70f73e5, 0x44bdfd03, 0xe5451838, 0x648bad2f, 0xcd92f67e,
+ 0xfd0eac73, 0xfbfb2a3d, 0x3d3fbdcd, 0x3de91bbe, 0xc53ff955, 0x31c5a4f2,
+ 0xb57ecbfe, 0xd3da0864, 0x52fa2ef9, 0xa8bf4f7f, 0x3f69c304, 0x5fef34e7,
+ 0x1be097d9, 0xd2cda1b6, 0xcdbcd28f, 0xa1d2034a, 0x04386e03, 0x690df3bb,
+ 0xb05f6e6e, 0xc24d453d, 0xf817ec36, 0xee7c07f8, 0xec81e59b, 0xf6c7cfe6,
+ 0xc1725d13, 0xf4e5a510, 0x2c358246, 0x8fbe68f9, 0xf3c4d7f1, 0xfa77b5d9,
+ 0xe604f3fb, 0xe0071241, 0xf87bb62e, 0x37f80a1c, 0xf9cf3d62, 0xd7ac3cb2,
+ 0x061ff915, 0x25f39d9d, 0xbd2e7078, 0x55fc7a40, 0xcacc7fa8, 0xf3717cf3,
+ 0xebb0d1bb, 0x1c7e90c4, 0x5e487f0e, 0xafd404fb, 0x7e16e01a, 0xb1e03f6a,
+ 0x3f0226eb, 0x6d773bd5, 0x1d2a7ee4, 0xe5b9e81e, 0x4c1e2ebb, 0xbd789c82,
+ 0x0e8064f0, 0x2ffcca77, 0x2a3d7bc7, 0xe37cb54d, 0xa47f3297, 0xa445f388,
+ 0xbf515a75, 0x0f47ca54, 0x689fe769, 0xc8fe65cd, 0x5aeeeda4, 0x31525faf,
+ 0xf8a7d7ca, 0xadaec2fb, 0xde749b9f, 0xab61a555, 0x23fb65d8, 0x3325e763,
+ 0x79e7be5e, 0x2dced767, 0xec87bfbd, 0xfd4e1fc2, 0x3b036cc0, 0x3cbb06fa,
+ 0x7f10b7a7, 0xe7e8bd01, 0x0bfb8d34, 0xef6a5fec, 0x524d3f05, 0x849d9c95,
+ 0xc287a48f, 0xbef8ce58, 0x598ecfe3, 0x2eb6e7cd, 0x4844d567, 0x0567c83e,
+ 0xe5185fb5, 0x5bf30bbb, 0xc2f39da8, 0x1c86ceea, 0x7bca2332, 0x3a57be37,
+ 0x073193da, 0x45ef3f3a, 0xb9255abe, 0x7720cd2b, 0xd7bee339, 0xe51759f9,
+ 0xbe7cc66d, 0x91b1fd6f, 0x520c6704, 0xad22cf5d, 0x9c7e5ba3, 0xfc05bdba,
+ 0xc93081f8, 0x980aa38f, 0x0bf3e91f, 0xda15ffed, 0x33e23ef7, 0xe279d1af,
+ 0x738fdc23, 0x7af2b18e, 0x3ca96abe, 0xa170e748, 0x6c84011c, 0x79ce1d8d,
+ 0x6fe1146f, 0xbe1553bc, 0x3d45f46e, 0x1e7af5a5, 0x2bd099f8, 0xb0af54d2,
+ 0xfb1dac57, 0x5bcefbf7, 0x8d47d6d5, 0xbba9f9d0, 0x37767097, 0x5bcf396f,
+ 0x01f447c2, 0xdf2ac65e, 0x5b0ebe6f, 0xc3ac41d1, 0x9f1e6738, 0x539ce38b,
+ 0xc304f98f, 0x43df187f, 0x1f3a19e7, 0xf27ef8e1, 0xe1158fd2, 0x7dff60b7,
+ 0xdafb676e, 0xd3eb5b5e, 0xee7c25bf, 0x81ed925d, 0xf005e89d, 0x68cff05e,
+ 0x7bb3cb3b, 0x7c1f84a3, 0x84d4ef65, 0x2f45ec00, 0xdf044f41, 0x79642de8,
+ 0x77bfacb8, 0x7f53950e, 0x5f68c2fd, 0x2f345ec0, 0x069feb42, 0x7d15fb46,
+ 0x52837db8, 0xda0e66fb, 0xbe6488af, 0xf9203473, 0x706c7378, 0x9bdf4a9e,
+ 0xa814cf3f, 0xd6045477, 0xeddea2a4, 0xe5435fd2, 0x6fd43549, 0x122192f3,
+ 0xf951ffce, 0xf3ce68dc, 0x32738df6, 0x4cfb671f, 0x5f6f54f3, 0x697aaff8,
+ 0x51bcd5eb, 0x3d83f796, 0x9429e514, 0x9b63f4a7, 0xab573fac, 0x974691f7,
+ 0x0f99cfb4, 0x5a44a6f8, 0xd2fde741, 0x99d2c24b, 0xc2fb7929, 0x5948f3ef,
+ 0xe728db06, 0xc29f5c56, 0xcbd9a3f4, 0x5b7c6b66, 0x1c0d0fef, 0xcb2f2123,
+ 0xb70b39bf, 0x679e8384, 0x41b78796, 0xbe5a3bee, 0xfb7a0a32, 0x0c1a9f4c,
+ 0xa3395c83, 0xaf29dbd0, 0xaf5c62a5, 0xd74cb71c, 0xc0a582ff, 0x0eedcbeb,
+ 0xf7cb3771, 0x3ea302c1, 0x556fafa5, 0xa37898cb, 0x27615cde, 0x2cf042fe,
+ 0x9a6df6d1, 0x7d3bd7d3, 0xebe9f404, 0xf4fa8de3, 0xe40f65a7, 0xc6d2fef2,
+ 0x8def5b3b, 0xb90e993f, 0xfaa7226d, 0x0f7a9d78, 0x57e74dd6, 0x25db97a0,
+ 0xfb6b08bd, 0xdf298b47, 0x07887b30, 0xd389eaf6, 0x1d6f4c1c, 0x1f2ce12d,
+ 0xf08ecc37, 0xb0d76ec2, 0x06ed8c2b, 0x83fb6b37, 0x1ba628f4, 0xee28beff,
+ 0xf32ed2a7, 0x3065cf95, 0x0f60bcdd, 0xe515b93c, 0x7fb3872f, 0x8e5a32b6,
+ 0x24bbf95b, 0x29bd2e8d, 0x5fb17aab, 0x32a5e98e, 0xe5c31dc2, 0x7a678fbf,
+ 0x57dc367a, 0x7d127c00, 0xd2bc5db2, 0x258ccc1e, 0xe8d31ffc, 0xfb237a0f,
+ 0x98a36af5, 0xf796856e, 0xf59e3cfd, 0x797f9238, 0x437ddf3c, 0x7bb3ef39,
+ 0x3ec42efb, 0xf0c91e5a, 0xf2c9731c, 0xbcb19563, 0xb7dfe60f, 0xc5fc30f4,
+ 0xbcec8ac7, 0x55ed8e5f, 0x73fade59, 0x9f841a9d, 0x9acfa75b, 0x86dfc725,
+ 0xe1baa8f9, 0xd4dde4a3, 0x5595fccf, 0x7e6ed093, 0x7053edc5, 0xf69af6de,
+ 0x4369fb29, 0x4afcf3f7, 0x97d47fb3, 0xf98c9dee, 0x760764d5, 0x1e7ea41c,
+ 0x116a739c, 0xee9fd3d6, 0x3ef5869b, 0xe17d6f6f, 0xeb77044f, 0x5eb23f8a,
+ 0x6fb47d74, 0xd85fbe26, 0x5fae1bf3, 0x16bff2bd, 0xb6afce41, 0xcfd17a4a,
+ 0x7e8d1ae3, 0x1e6f8645, 0x7cae57ea, 0xc881f59d, 0x7f9223ec, 0xf8fdfede,
+ 0x5bbde9ce, 0xdda8505e, 0xd5bd88d2, 0x5c81aa9c, 0x94676b9c, 0x0692b460,
+ 0xed3d4a7c, 0x8d182bac, 0xa459f175, 0x5b74b89c, 0x4b181f88, 0x7fd9a091,
+ 0x16d2dda8, 0xf242bf19, 0x19f41d82, 0x7d297f5a, 0xf3df7ae7, 0x9168857b,
+ 0xdf7763df, 0xf75cb57b, 0xfc387060, 0xb09b19ae, 0xfd76e7ee, 0x77e8d326,
+ 0x872f4d0d, 0xacffce57, 0xeace5fb6, 0xbdb665fb, 0xb9005ed3, 0x7d33fceb,
+ 0xfe76744c, 0x3f9cc1c9, 0x112bb4ad, 0x577f974a, 0x72465a78, 0x65b78d7c,
+ 0x07e7e424, 0xe34befb5, 0xaf82465b, 0x384e7ce9, 0xff59725a, 0x85c96acf,
+ 0x47f3abbe, 0xc992d451, 0x992d03df, 0x4582ff68, 0x8ff853da, 0x3a78a8e0,
+ 0xd2dde369, 0x0cb7e10f, 0x26e87e47, 0x1a71f5e4, 0xe91f25c2, 0xa58fbe69,
+ 0xf9e63b4b, 0xbd9bf639, 0x7ad07f54, 0x707ca9bb, 0x9adf9cc0, 0x03e7ed2e,
+ 0xfa6fe243, 0xc3fbeda9, 0x213c8e70, 0x3fd7f5ba, 0xd4f38da3, 0x3c719d53,
+ 0x0acfa6aa, 0x6e1f4eb7, 0x80dbdf29, 0xf13a8fef, 0xf1126b7d, 0x6398a5e5,
+ 0x9e5fcf2a, 0xfb494f67, 0xbe790bcd, 0xe7179c24, 0xff821781, 0x67ca5885,
+ 0x7892be43, 0x3e3af3d5, 0xf2bfe743, 0xb04945a3, 0xae947edf, 0x7d3cf9db,
+ 0xde3a9740, 0xefa46c1a, 0x2e3f4364, 0x8569382f, 0x2c49ecde, 0xdaec1ab3,
+ 0xd81cf3eb, 0xe4378b57, 0xd6748c39, 0x10e0adb0, 0xece21c49, 0x2007ab36,
+ 0xf7035837, 0xd86f7e42, 0x05f8b6a6, 0x54bc3b97, 0xc0f3acff, 0x68b7a8db,
+ 0xe43e6c43, 0xe2fdbd6d, 0xcb1223f5, 0xdd0e700c, 0x9c875e66, 0xd87e7316,
+ 0x04fe736e, 0xffde80ce, 0xa0bcbb7c, 0xc8705f39, 0x83e4ff9c, 0x9c81675b,
+ 0xbdff55cb, 0x3f89f42a, 0xf384384d, 0x5e17d3f1, 0x2cfac68c, 0x41d94bfd,
+ 0x71a149e8, 0x0a6eb422, 0x56ff08f4, 0xb2e3e985, 0xf81e9178, 0x810f1e81,
+ 0x93a4619d, 0x683fe10a, 0xfebcb94d, 0xcb32d119, 0x5955744b, 0x64e0bcb7,
+ 0x57bf5741, 0x43b3acb6, 0xb71d0bce, 0x9c2ffda7, 0x6aec375e, 0xd964a3c5,
+ 0xc5637555, 0xd62df809, 0xf4013bbe, 0x854bfc57, 0xe7e28ae5, 0xbe0abd07,
+ 0xce63b6df, 0x9ace9c0d, 0xedd0f8c8, 0x2af78b7d, 0xbbca28c1, 0x5dba4946,
+ 0x7d615eb8, 0x1cd1a4bd, 0x36b65747, 0xd9a6de24, 0xf778be5c, 0x9f86fffe,
+ 0x18f1dcbe, 0x1e5c33c7, 0x05781827, 0xa7c55b7a, 0x153ded82, 0x330dbf9b,
+ 0x2d79cb97, 0xbfe1e7d4, 0xaee1e396, 0xcf3a5592, 0xd0c893b7, 0x574bf0f9,
+ 0xe1066a51, 0x8de6aafd, 0xbd9b94aa, 0x7597ecc5, 0xb0ce39da, 0x918221ca,
+ 0x28a1cf04, 0xdf45d7bb, 0x628fae2f, 0x18516179, 0x9cf99fc9, 0x438e708a,
+ 0xdda0c4f4, 0x965477a9, 0x25e2aa83, 0x571eaa1e, 0x56c5b002, 0xfc8a48c1,
+ 0x04bf3213, 0xd25526de, 0x3f00d78f, 0x1798cdd6, 0xab6f524d, 0x03f706b4,
+ 0xc0e79d2f, 0x4abd7336, 0x38d1e79a, 0xefe659c8, 0xeb9da2d5, 0x36feecd7,
+ 0x60ddf8cc, 0x527d65df, 0xc8556bd7, 0x7aa70433, 0xb3cb0447, 0x402398c4,
+ 0xef14ab57, 0x29150ec3, 0xefa0e39d, 0x2f964e25, 0xe7946ee6, 0x838c3347,
+ 0x0dd78390, 0xae67b966, 0xbe04cde2, 0xd670bac4, 0x1fdca9a7, 0x64e58bde,
+ 0x4e484396, 0x7daa3966, 0x12e39d8e, 0x825af39b, 0x1f9ac790, 0x0ad0f148,
+ 0xf3e47f32, 0x96709ee8, 0x4aa79a7b, 0x5d79a7b9, 0x31ff6e1f, 0x390beb40,
+ 0xf9b9e25a, 0xb71e1c9e, 0x89db2a9f, 0x200f523e, 0x7a133ab9, 0x41e5c102,
+ 0x67472eb9, 0xb04afac5, 0x9bfcfaee, 0xe0a3db63, 0xf1e512c7, 0xd86e4bdf,
+ 0xed879da2, 0xf003c2eb, 0x8a549c53, 0xf60c5a0e, 0xe4325ba9, 0xac7231f9,
+ 0x8f56ab77, 0x966519fd, 0x80ff77a9, 0xd07b29e0, 0xe9486ee2, 0xf5e1075a,
+ 0x27fe6266, 0x83e785d7, 0x958e46ee, 0x7963a7f6, 0x0e479f92, 0x73bf1c17,
+ 0xedefd6bb, 0x9a531619, 0x48f44118, 0x942c9cfd, 0xe1a8edf6, 0xa4076c45,
+ 0xbbb9ba35, 0x19359038, 0xb32a9cf2, 0x9afefd17, 0xa4e9e06e, 0xde52f18b,
+ 0xd94cb93d, 0x72f2e124, 0x5fc8dfbc, 0xf0fdb385, 0xe8de76a4, 0x347441eb,
+ 0x8d71cf82, 0xe8d3ad9f, 0x74cf5d66, 0xb98ba263, 0x3741b790, 0xd8b9e473,
+ 0xfada5749, 0x7af0dd12, 0x485d13b7, 0x6be211ba, 0x4b742fb4, 0xdf443b79,
+ 0x7bb7d4ea, 0x0e88b7d0, 0x6de8c89e, 0x074217a8, 0xf1181ac2, 0x252cfc8f,
+ 0x2a4762a3, 0x564904b4, 0x2cdc47e1, 0xd7c646ce, 0x4ac0d65d, 0x55bfa782,
+ 0xab00cbae, 0x653a3ba4, 0x5cf911fc, 0xd9f88bdf, 0x0b17fbe2, 0x4e2fd52f,
+ 0x4ab76c12, 0x2626f927, 0xa409db8e, 0xb0aa0770, 0xf68a50e7, 0xffb231c5,
+ 0xc46fa262, 0x5e7f51b3, 0xdcc69c4b, 0x2a7fc246, 0xfb407e58, 0xef6e7ce8,
+ 0x5ef6c8b7, 0xd303a52b, 0x5f6a3ee4, 0x2bf8c615, 0x264073be, 0x58d264e8,
+ 0x66249d33, 0x4f41394a, 0xbadd331b, 0x7e0890dc, 0x9838d250, 0xf08699cf,
+ 0xd85daaa2, 0x7d48cfa7, 0x4df578a3, 0xbe004793, 0xd83de367, 0xeca7a7c2,
+ 0x494aff60, 0x7f1f9ce3, 0x5b653d08, 0x98df7f38, 0x780f7be9, 0x17b8ad3f,
+ 0x250fa2ec, 0x27b15f33, 0xcb5f7b52, 0xa3bf73d4, 0xc77f8a74, 0xa62390db,
+ 0xfeb950cc, 0xb9ed2114, 0x338e51a2, 0x35b9ffd9, 0x3c9bfa91, 0x94f0e15a,
+ 0xf25770b6, 0xb455f832, 0xd1a63df5, 0x98b84377, 0x70139cfd, 0xcd4cc80d,
+ 0x24821f86, 0xe4e46ed4, 0xfd5a9901, 0xc806ca31, 0xc9c70343, 0x47d7a7fd,
+ 0x2d37e83f, 0xcfb7ee53, 0xe7a77db4, 0xbf5caf09, 0x5b584d6c, 0x5b52345a,
+ 0xf3a51070, 0x039ec6b2, 0x2a94999f, 0xde07ac26, 0x4d8aaa7f, 0x317b6f0c,
+ 0x4ca885f3, 0x8f82f837, 0xfba65914, 0xee99836d, 0xb7b4c6db, 0xb6f949dd,
+ 0x7ed2392d, 0x0bf3e9a7, 0x82e5825d, 0xef9231b6, 0x64896fb5, 0xd5cc73fe,
+ 0xed27151a, 0x97dfac5d, 0xd7f1246a, 0xe17b86ba, 0xda752e37, 0x2c7e70db,
+ 0xfb3a607c, 0x499b4bfb, 0xfd5c47bf, 0x4f7eb35a, 0x6658787a, 0xa87afa37,
+ 0x019a0e5e, 0x55ad951d, 0x36070e98, 0x997dec78, 0xcc2e29cf, 0x4c19ccaf,
+ 0xf32fff07, 0xf05c7384, 0x37fb7a65, 0xb091f784, 0xba0e0b1f, 0xd7c83a1a,
+ 0x3716e30b, 0x1a7eb315, 0xfe63ed99, 0xbc255035, 0xd4cf1d10, 0xec126fe8,
+ 0xd64be0a0, 0x97d8bed6, 0xdf6865af, 0x4e995ce3, 0xbe70eba6, 0x7366d06f,
+ 0xb6be0265, 0x9c16e155, 0x4a5693b7, 0xe77da6fa, 0xbb80bdc0, 0xfc0222ac,
+ 0x7ed6b8e0, 0xd16b0afe, 0x77f7ca46, 0x1c546b08, 0xe98f2be8, 0xfbe5903b,
+ 0xe9f7eb0c, 0xc828c42f, 0xd76ba50d, 0xfa34b849, 0xe323d610, 0x4f9c69e3,
+ 0xc3e4a4b7, 0x53d3a0ae, 0x766c6b20, 0x5d0308e6, 0x1e9850cc, 0x60873e68,
+ 0x55979d9f, 0xfa728f92, 0x32f41fbe, 0x1d306c69, 0x6a85d871, 0x76abc725,
+ 0xe20f0a24, 0x3b443a87, 0x241d23cb, 0xea3f808f, 0x27e7467c, 0x475e1744,
+ 0xeb7ad742, 0x3d6b657c, 0xde784681, 0xf4e0ef56, 0xb0977aa9, 0x5ed84f12,
+ 0x67f9c89f, 0xb69cddeb, 0xf7f167d4, 0x9c3deae7, 0x8a3f59df, 0x7bd42ff3,
+ 0x7ebbbf39, 0xabbfa722, 0x84efe22f, 0x3a4be61f, 0x93f9d1df, 0x9f3a5f4e,
+ 0x05aba50a, 0x33dc6684, 0x0fccf6a0, 0x79883e75, 0xf8bbf258, 0xa9cebe93,
+ 0x113f914a, 0xceb450fc, 0x5428ff01, 0x22f33ecf, 0xdca3b9e1, 0x1da1f1c9,
+ 0x0ec1f242, 0x8dcf83a7, 0x0dd8bb64, 0x32c340fb, 0x869ddb6f, 0xb95e7873,
+ 0xba06ac22, 0x5c36a9bd, 0x7d740d58, 0x29ac5d73, 0xfdeebf3f, 0xff50fad7,
+ 0x2df18b3f, 0xbb1cfac2, 0x7fa3d4e3, 0xdf8fefa4, 0xeb033a71, 0x796c704e,
+ 0x1edee308, 0x2ad1c1a1, 0xceddbae1, 0x08c0d2f2, 0xcfe14fa9, 0x2d738861,
+ 0xfb7d894e, 0x31e70437, 0xda061d6d, 0xc146b35d, 0x754ab32e, 0x1f2aa4ad,
+ 0xfbe8bd63, 0x2af5b59f, 0x7c630ba9, 0xfb6a3496, 0x4cff18d4, 0x57de3cf8,
+ 0x78a75cb0, 0xe91f8085, 0x41ec2ff8, 0x71c41192, 0x685011c5, 0xad94851c,
+ 0xae17b0f9, 0xe428fd79, 0x10eea574, 0x873ed5cb, 0x8428e393, 0xd8d676df,
+ 0x9077529f, 0xfed689eb, 0xc8c838a6, 0xf83b5ee1, 0xeb1b6805, 0x40759256,
+ 0x268b9f60, 0x94f1ef85, 0xd6cbdf69, 0xe2f8a628, 0xe655337b, 0xac32878b,
+ 0x14ca0e9c, 0x89a5139a, 0x5e9d29cf, 0x3c707f89, 0x9e535963, 0x2f81917d,
+ 0x4bdf6897, 0x78a62cb3, 0x321943c7, 0x98106a2e, 0x6777a505, 0x3217daa5,
+ 0xdc7373df, 0x24bf5ebd, 0xea757f2b, 0xe883f470, 0x8ff6aea0, 0xddb95a64,
+ 0x84970ca1, 0x59e741c7, 0x74e9c714, 0x72e82e7b, 0xeff8a7cc, 0xeb3f0c95,
+ 0x3ecf1559, 0x7bfc2cfd, 0xe30a7f15, 0x9862a9f3, 0x0ec8df66, 0xf2ce9c8c,
+ 0x8ca9d78f, 0xd72dfc84, 0x7fd3fc7f, 0x547c4689, 0x57694ecd, 0x690db4a5,
+ 0x6ce5edf5, 0xd0f6ab57, 0x9f0388fe, 0x5fcdfb35, 0xd14ff67d, 0xf897acad,
+ 0x5bf8b493, 0xdeaaf78e, 0xc0e38279, 0xd0afb8f4, 0x37ca3576, 0x71eaa7ac,
+ 0xb63fba01, 0xf78d9f70, 0x851ecd4d, 0x5d9a98f5, 0xe7c01317, 0x4aadf66a,
+ 0x272e2ee8, 0x5e3d5fb4, 0xd5bfb740, 0xc39fb588, 0xc384487f, 0xffad0ff8,
+ 0xaf546676, 0x62054353, 0x3b60aed5, 0x1c705588, 0x8e2d72c7, 0xc19023b3,
+ 0xe49ee17e, 0xc4f59aed, 0xedbf49f0, 0x1063bab0, 0x88417caf, 0x53addd89,
+ 0x7e7920fc, 0x047da39f, 0xed85f0bf, 0x1791cb2a, 0x7ef147b6, 0xff7edea8,
+ 0x55dbc441, 0x8dd8566f, 0x308e2557, 0xaa77aade, 0x0fe061c2, 0xc50bb035,
+ 0xd2e70cf7, 0x416aa3a7, 0x145a4b5f, 0xadf816ef, 0xde98ee1d, 0x35da7806,
+ 0xd61a5afa, 0x45d79232, 0xf814ff83, 0x5cce419a, 0x8e7ef7b2, 0xe77aa413,
+ 0x6df9ae59, 0x51b3c724, 0xce036f0f, 0xd80a1b33, 0x65a4bd4f, 0x05cb3547,
+ 0x105d23db, 0xccdb4e69, 0xd1be29f7, 0x9346fbc6, 0x4fc0ced3, 0xaacff682,
+ 0x4e030f2c, 0x5ad3cbec, 0xcedeab3c, 0xb3b64832, 0x0dfb7868, 0xae88e7f6,
+ 0xda5a4bfa, 0xfea9d3a2, 0xe7dfbb27, 0xee4839d4, 0x23ce25e3, 0x3f4738b9,
+ 0xf7c919d9, 0xf9d93eed, 0xd12f09eb, 0xc65ae778, 0xfb0c52f4, 0x1b20e06c,
+ 0x41b73fd7, 0x25f301c6, 0x5a0fd611, 0xb6673e78, 0x27ac2927, 0x9f84df03,
+ 0x8f9f3b33, 0xf63ef0b6, 0xab717bff, 0xc86b15b3, 0xb2eb847d, 0x5bfe8047,
+ 0xed11fbb5, 0x7fe5fd9a, 0xed6affa7, 0xa4529b7b, 0x3bef238d, 0xc20e3d08,
+ 0xd53beda5, 0x796efbc9, 0x2fef9d94, 0xbee6182c, 0xe8f81e71, 0x518e329b,
+ 0x043f77f4, 0x3bc16ffd, 0x596f6cf1, 0x41f7736e, 0x36c38bfe, 0x282c13f6,
+ 0xa1f51cf0, 0xed9d8c7e, 0x75b1224a, 0x6dadec04, 0xa8be5229, 0x933b435c,
+ 0xe88fdc50, 0xacf84fcd, 0x8f84580c, 0xa50793f2, 0x523ebaf2, 0xd9daf16e,
+ 0xfbe413ff, 0xc2ecc792, 0xfe2f7b8f, 0x5d7ea4e7, 0x0efd2a99, 0x517f608f,
+ 0xcc17195a, 0x4edd878c, 0x69ca9ba3, 0x9fa06e54, 0x4cc14dca, 0xed674fc8,
+ 0x72891ed2, 0xf9954de8, 0x46835eb2, 0xfd07e8a7, 0xceb8a5b6, 0x2bbbbcb3,
+ 0xb0ef404a, 0xed2518bc, 0xdf09bf21, 0xaf386614, 0xe9241a6f, 0x07f341b8,
+ 0xf848b7fa, 0xf8e41700, 0x4ca6f625, 0xb8fab9c8, 0x789ba24b, 0x78dab3bc,
+ 0xa49a224b, 0xc78b44ff, 0xdf1e7d43, 0xd3bfd826, 0xcb1864fe, 0x1efba7cb,
+ 0x9fe30179, 0xc730727e, 0x04a5b411, 0xf2e6ed16, 0xaee38e70, 0x082c2a78,
+ 0x327b3f78, 0x9f58ed8a, 0xf61ca4d9, 0xcb025459, 0x1ea28761, 0x3afe805c,
+ 0xe0298736, 0xc2299fa3, 0x2df2889e, 0xa80e59bd, 0x3f63afa8, 0x17b10549,
+ 0x4e94afc8, 0xd9f7dc84, 0x276cc196, 0x950decfa, 0xf7d0292f, 0x13eef835,
+ 0xc67e0b4d, 0x3ff4bff2, 0x6fea7e9e, 0xaff3bb83, 0xdb366c54, 0xd7f5f4c3,
+ 0x2418efcb, 0x0c7703ed, 0xcac97a92, 0x7fe92e41, 0x30796c8b, 0xf929e795,
+ 0xeb03ad03, 0x131fb47f, 0xd63f6f60, 0x714127b2, 0xccc1cf02, 0xdbef035f,
+ 0x7a759ea4, 0x42fd8dbb, 0x79462f15, 0xe774fed9, 0xb0ef7c15, 0x78729542,
+ 0xdbde4585, 0x99eed0ab, 0xb2674456, 0xcdf08b7d, 0x16fb6d7a, 0x8e471b55,
+ 0x01d6d9fb, 0xd4109fd2, 0xf0e42ff2, 0x7149b83d, 0x2c69e6e2, 0x05c86d5f,
+ 0x8e6e2f5e, 0x1a79f8e4, 0x87b88bc7, 0x5cfd9f8a, 0x116633e2, 0xae7407eb,
+ 0xd4ae7f31, 0x9dd573f8, 0x5ee0c757, 0xe5477881, 0xad1712fb, 0xbfe03e9e,
+ 0x4f7af8a1, 0x5f4b63e3, 0x41f99478, 0xc417ed25, 0xfcd52d59, 0x529f4bcb,
+ 0xba5c9e58, 0x9887eafa, 0x136dbeef, 0xb6705fb8, 0xe368fee5, 0xf8d5ec7a,
+ 0x0f7b5767, 0xf54a5fd7, 0xa337fb65, 0x36ad9e19, 0x5d09e00f, 0xfeddefc7,
+ 0x6a5ff529, 0xf242d15f, 0xf3e5ee45, 0xdc8e28bf, 0x95f027f6, 0x676ce1ed,
+ 0x7be7f5a3, 0x2d6c6746, 0x33ff308b, 0xbf3384cf, 0xf72b1339, 0x9e7427fd,
+ 0xe780edfa, 0x5db1f787, 0x02e9bded, 0x80e2d0e7, 0xae1d5fb9, 0xafdf1afd,
+ 0xc0c4f78a, 0xeb45534f, 0x7d68fe81, 0xdfedc47e, 0xd0fb71b1, 0x768e3cf9,
+ 0xf4fb0c23, 0x9ba64899, 0xbae4fd33, 0x1076799c, 0xb16d679f, 0xde09de92,
+ 0x674be864, 0x1b8a6562, 0x0a87a03e, 0x3387a497, 0x1ed85a63, 0xc1d94670,
+ 0xb64d9b69, 0xfcd3a8ab, 0x897f44da, 0x26d01fa0, 0xb58ea9ec, 0x80c72047,
+ 0xe7cc8fcf, 0xcefb8834, 0xd07376a1, 0xbebfce29, 0x84dcf259, 0xcf3e0578,
+ 0xe3f61b7e, 0x733df0b4, 0x564f269f, 0x4fdcbf6e, 0xdcaa7588, 0xeb3fb0ae,
+ 0x02fe7692, 0xddba5eea, 0xa972e89f, 0x6e22f15f, 0xb2e3696b, 0xa5fba025,
+ 0x81e6ebb5, 0x2c79f5ee, 0xb75feed5, 0xd3c32a29, 0x27fb4e16, 0x74f1f2fb,
+ 0x8a59aafc, 0x5c279f1e, 0x7b45f9fa, 0x2dcb2c38, 0x4db288e9, 0xa3655fd4,
+ 0x49c796b2, 0x395bf5d1, 0xb84f1d3f, 0x5efb02cd, 0xb9df769b, 0x70ebf9a7,
+ 0x524f04f6, 0x6d4fe496, 0x6f9ef229, 0xbef25bfb, 0x0a6fc5f6, 0x81fee262,
+ 0xfa91c83c, 0x7f047f7a, 0x72106816, 0x96e7c68f, 0x704eaec2, 0xfb306e66,
+ 0x9b36b273, 0x9bb643f3, 0xcd3bd9f3, 0xe6bddcf9, 0x7355e7bc, 0x7b7185de,
+ 0xfa09e177, 0xa103e236, 0xbe85236f, 0xfa94ceed, 0xb7d0f236, 0xc6df4291,
+ 0xc8dbe877, 0x1e46df43, 0xd0f236fa, 0xdf4291b7, 0x1a39f7c6, 0x7b352a9e,
+ 0xe381d629, 0xeb84f6d4, 0x5fbc00f1, 0x6049cc2e, 0x52ac2a3e, 0x24b0bd1f,
+ 0x4ec7e59b, 0x0754d33b, 0x38f499db, 0x7ca2b7a7, 0xc37ab2e3, 0x75647b7f,
+ 0xc76e14df, 0xdf9ae7f6, 0x6573fb49, 0xf613b87e, 0x9f55d68e, 0x13d886ac,
+ 0x444df288, 0xf6b60bfd, 0x556fc0ad, 0x6fec2bdd, 0x7ee15d6f, 0xfd7207e7,
+ 0xc7a2eed8, 0xdce3152d, 0x7d26df03, 0x7b6fc649, 0x6a3b461c, 0xac485fa8,
+ 0x3f21e435, 0xa1f39b35, 0x35f0207e, 0x355f69af, 0x6e3c1d31, 0xbe0bef6b,
+ 0x0749e27f, 0xa13af3df, 0x6cc4edd9, 0xba63cb17, 0x8f29df3c, 0xc26ca3dd,
+ 0x2b24bdf9, 0x1c77db8e, 0xd3dd30ca, 0x2f4b4d0b, 0xdabcb3e5, 0x58ab5f99,
+ 0x8cd94e30, 0xaf59fb15, 0x73e68c4e, 0xb60d16e9, 0x0dff9041, 0x440e0f70,
+ 0xe868e898, 0xbf10b8b6, 0xfd533f65, 0x4353bb61, 0x4c4396fc, 0x16d7d3e5,
+ 0x17b5ef98, 0x1f2a6d5d, 0x878cef68, 0x96ff4873, 0xd64b9f06, 0xe7cce8b9,
+ 0x4bd686f9, 0x847f3c56, 0x25bc56bf, 0x9a32d3e5, 0x7b40b787, 0xfe1f239f,
+ 0xe014ef39, 0x16c5bcaf, 0x54bef38b, 0x9d44873b, 0xb72e5cf9, 0xae2bbf0a,
+ 0x5dcaee8b, 0xed4b1bc2, 0x2536b4bf, 0x71dd1d33, 0x14255934, 0x2472192d,
+ 0xe57d0837, 0x8246278d, 0x8dd4aaae, 0xbf2a2ec9, 0xc56c0955, 0x71d3ec45,
+ 0xa4ae123b, 0xf8b4fff2, 0x75a2c91e, 0xef05b64a, 0xba3e0f9d, 0xbde04d23,
+ 0x9f6b1391, 0x3cb8e68f, 0x6d92fe8d, 0xc1d008ae, 0xf59526c6, 0xd4cdd814,
+ 0xd93a2eb8, 0x011f14d8, 0x8c7ca6bd, 0x717297e2, 0x0bdf49b4, 0x9aa147c5,
+ 0xe69b8efd, 0x2a90f17b, 0xf36a40ef, 0xf592ee5c, 0xaf6cba45, 0xe7d7b3df,
+ 0x47d3527b, 0x96be362b, 0x3f7d0b79, 0x2e7f783b, 0xd65784ae, 0x2f79e6ef,
+ 0xdadf6cb5, 0x1d7bd297, 0xd7985dbe, 0x45c6b7f2, 0x7ce3495f, 0x87c65db9,
+ 0x89f9b5ff, 0x4fc4fcc7, 0xc27a6cef, 0x8541fb0e, 0x1e876035, 0x46e4fe5c,
+ 0xae18e23b, 0xbf91b6db, 0xcc56da2f, 0xbefd00f6, 0x7c7aa7da, 0xf28f86b3,
+ 0x1706cab1, 0x60ffb3cd, 0x23ca4fc9, 0xa14b1c64, 0xdc35fa3a, 0x4db8b813,
+ 0x66bcc3c9, 0xe3b0ed14, 0x1a3bff1e, 0x37dd09df, 0x17a7871d, 0xabbd86f6,
+ 0xdf20f145, 0x89993ed3, 0x0f4472cb, 0x39b92fd3, 0x0869719d, 0x0a1fd5eb,
+ 0x8e70bed2, 0xd7e88764, 0xcf695587, 0xad123c43, 0xd83db973, 0x85e43a6b,
+ 0x0ffbe597, 0x8d0e7455, 0x2ede87ca, 0x169455c4, 0x744d568d, 0xd23e335e,
+ 0x0b660fb4, 0xfea2bec3, 0xa67e8966, 0x69498cfc, 0xce37faa6, 0x67e21a18,
+ 0x672aefce, 0xe99575fe, 0xdbaa975d, 0xe3856efd, 0xbf9ac67b, 0xd33b7a53,
+ 0xf6a60dd9, 0xe99a6255, 0x9b25975d, 0x133c65df, 0x8fa1d995, 0x41f76b95,
+ 0xb4dafb66, 0x9dfcadef, 0xafda6226, 0x7f3cd303, 0x8da5e794, 0x1dba08fd,
+ 0x9ffe367d, 0x1979ddd6, 0x898f19d1, 0x3bd85bf8, 0xe479667c, 0x42a9eb08,
+ 0x669543ae, 0x92caaa8f, 0xff2aa8f6, 0x9be23b11, 0x24d6ff09, 0x93754942,
+ 0xaa46f6c2, 0x938a48ef, 0x7df1dbf9, 0x075ef9a7, 0xf284bbfa, 0xf6316a43,
+ 0x35796857, 0x42e71bcd, 0xb047ec35, 0x6bfde983, 0x19f4eafd, 0xb43ecf7a,
+ 0x3760df1f, 0x6d8ae7ef, 0x23f60e3b, 0x8a2f4cbc, 0x497c43cd, 0x5b54cb65,
+ 0x74e5f671, 0x8bfdf3a6, 0x7fb616e5, 0x857e1c75, 0xdca3ace9, 0xddf191ea,
+ 0xd51f18ff, 0x0d6f695e, 0x3445bfa5, 0x1799f81f, 0x013c54ed, 0x5e03d645,
+ 0x432e81fa, 0x0dd492f0, 0x753c74be, 0x7ca42de2, 0x1c33fe31, 0x004a11f1,
+ 0xbc32f27c, 0xfad478e8, 0x2c13e45f, 0x013c1267, 0x3fa42786, 0xff742a31,
+ 0x20efc2dd, 0x84506c74, 0x3c6ef94b, 0xed24bb4c, 0xe4d30336, 0x2977dbbc,
+ 0xb3ebc81e, 0x7bf9592e, 0xc914bd27, 0x9319f538, 0x93b3fbcc, 0x7ee48a7e,
+ 0x81297999, 0xd36ffddb, 0x8fd177d1, 0x8d099fee, 0x5defd6ff, 0xddac1a2d,
+ 0x46211a4b, 0xc44ffb7c, 0x4072ebaf, 0xe749e74f, 0xf0d2e379, 0xf6ed4cef,
+ 0x951e5e1c, 0x3edaf1ca, 0xf3a88ecd, 0x4ed69f63, 0xca98b71f, 0xefa005dd,
+ 0x17b009fe, 0x4b4c6eaf, 0xe317be36, 0x3b63655b, 0x788af26f, 0x5dc38b4e,
+ 0x8a473809, 0x4d77c857, 0x27d5df8e, 0xe388fe01, 0x26bd6cab, 0x7fc7d751,
+ 0xe4593c3a, 0xe9c85f20, 0xb3617589, 0x3d78768d, 0xed2c1a6d, 0x7e39fa35,
+ 0x7a3872ce, 0xaadff636, 0x0508d15d, 0xfdeaba5a, 0xcf3a2e91, 0x8f7c5957,
+ 0xef7f660f, 0x85cf3e46, 0xec2e636b, 0x513cba70, 0x0fb0aab1, 0xffcafdce,
+ 0x9c31e579, 0xb615befb, 0x9fa3c804, 0x840aa07d, 0xc679d0ce, 0xe1a7c472,
+ 0xdd3fae92, 0x10f7c912, 0x1784553f, 0xea25a6fe, 0xe9975cfe, 0x0b3bdd5c,
+ 0x41deffe3, 0xb8c08ee3, 0x1889ad81, 0xc4cfe3d7, 0x1915beb8, 0x57d9dd31,
+ 0xbd66b4f4, 0xeab6f394, 0xeecd64f6, 0x791ef90c, 0x6270f7c8, 0x1e47be41,
+ 0xc8523df2, 0x4dbef8f7, 0x6c0c2ff3, 0x7e83cf68, 0xb22b1fea, 0x75bcf96a,
+ 0xbf7e4166, 0x80f08945, 0x78a2dcff, 0xc1bc70fa, 0xc4def966, 0xd57590f2,
+ 0x49da6bd3, 0xedd03306, 0x84392e0f, 0x8c6e6e31, 0xc7e53588, 0xea9afa39,
+ 0x4c52ba17, 0x0e25d7e5, 0xef5f9536, 0x7fe533ce, 0xa9a57598, 0x18cf64fe,
+ 0xa347fe53, 0x9fd537ae, 0xca6a9dea, 0xc7389f4f, 0x51667f54, 0xc6fca9b1,
+ 0xe54c4bd9, 0x4ccb7c73, 0x3fe579f9, 0xa9bfd535, 0xdca98576, 0x9c565c2b,
+ 0x77a17b77, 0x865fde11, 0x2de945de, 0x8d38656f, 0x9c7a3aeb, 0x7977dba5,
+ 0x5072694e, 0x36dea1bf, 0xd7ee25d0, 0x68070e80, 0xc0be67f7, 0x7e1bd2b9,
+ 0xf522a0c9, 0x417d23de, 0x42f5a137, 0x1e4747cb, 0x35a6e8b8, 0x7a2a7a2c,
+ 0xc4f895a6, 0x140e2be8, 0xf57e51a4, 0xad338553, 0x5f465fc4, 0x54f9e07d,
+ 0xb53d37ca, 0x3b0f964a, 0x51e51170, 0xf320df4f, 0x1a8b05d3, 0x7af90c8f,
+ 0x31e69f86, 0x6ba907fa, 0xd26ed23d, 0xa769bc6d, 0x80f0883d, 0x01e04d78,
+ 0x13e89069, 0x4fa201e9, 0x7d12afa4, 0x710ba596, 0xe913e890, 0xf13fd221,
+ 0x7fa4f7fd, 0xfa4c3d22, 0x49b7d227, 0x847a44ff, 0xefa44ff4, 0xf4e6cfd5,
+ 0xb71f7a83, 0x397d43fb, 0x6beb47a7, 0xf5c7fbf9, 0xb9fe9c75, 0x5ddfcfde,
+ 0x433b7443, 0xba31ed90, 0x7e1aabff, 0x76edd847, 0xfd1acedb, 0x9e578ac2,
+ 0xb2bfbaa7, 0x46b456a1, 0x5ab69f62, 0xba394f63, 0xf33d90fc, 0x6538ab5b,
+ 0x0f5ebf90, 0xe10d26f7, 0x98bbfbf1, 0x8fdf6b6f, 0xf203e989, 0x520a9d69,
+ 0x9f28297d, 0x2aba5f99, 0x0fc7f886, 0x81b5a9be, 0x74b43e5e, 0x0bfb7f7f,
+ 0x87da4e8d, 0x8c873378, 0xebbbf2e8, 0xf8ceef7e, 0x1e5f831a, 0x8e3d6cfe,
+ 0xf3c7f747, 0x473e219f, 0xf1eb93f7, 0xef6ad741, 0x707ee923, 0xef47fe3d,
+ 0x6092f0b7, 0x1acd77be, 0x512dcb2b, 0x38c41156, 0x35cf9c7a, 0xc43c968e,
+ 0xe9535c3b, 0x3eb738e4, 0x23ef1df4, 0xde2f3d52, 0x25fcdb99, 0xf2edcfd5,
+ 0xe6d1f7bb, 0x8f3ce541, 0xb63e4bc2, 0xc5a35ed7, 0x43bda01d, 0x753bf396,
+ 0xfc831188, 0xe1db2941, 0x7da8551e, 0x001c577e, 0xfaca47ea, 0xfe97f441,
+ 0xdd178d15, 0xc4068fb5, 0x6e21e4b5, 0x93b5406c, 0x8c36c6e3, 0xb9bdf209,
+ 0xded7b1e9, 0x4e22aad3, 0xd8c7e638, 0xfaa74f47, 0xefcf0266, 0xf00f73ee,
+ 0x5c5a7e50, 0x53a46f5a, 0xebb5de43, 0x62e67d66, 0xe97c755d, 0x4bd7d778,
+ 0x9e21b7c7, 0x5dfcf18a, 0x6eba17eb, 0xafa5eba1, 0x2ea5e153, 0x977f03fc,
+ 0xfad74faf, 0xfffb3ec1, 0xb70cfacb, 0xcc7df0b6, 0x07874ab0, 0x7ad77d70,
+ 0x262edcdd, 0xf1783ee0, 0xa441f725, 0x5f7cd24b, 0x8a967f80, 0xc05c1331,
+ 0x81cd4b91, 0xdeb4279d, 0xef59eff2, 0x077a90e1, 0x7cd60ae2, 0xbd79769d,
+ 0x1af521dd, 0x7ed60b62, 0x374ced2d, 0xe43d7ce2, 0xed1fb1b6, 0x1e3d70cd,
+ 0xa3ccebc3, 0xf1a71c75, 0x96a243a3, 0xd7120fcf, 0xf1df58fc, 0xcb8f52da,
+ 0xee72cc5e, 0x6e59a778, 0x514df09c, 0xd09dc623, 0xd68e442b, 0x6837e1fc,
+ 0x9a275efd, 0x7bd0dfb8, 0xf26837f2, 0xf93de869, 0xf26886e7, 0x01488a65,
+ 0x3c2f1a9f, 0xbded2e12, 0xd92ef183, 0x2f46926f, 0x8c556e69, 0x9f083d06,
+ 0x55f1cc15, 0x8b9077bc, 0xbf9cfd71, 0xfd38045e, 0x3f7208a1, 0x22918993,
+ 0x6c2123ff, 0x79039df2, 0xf55ab33f, 0x2ce427fd, 0xc2e65efd, 0xd8abdf70,
+ 0x4e44af77, 0x28f78f99, 0x4b8c15c6, 0xe303bb47, 0x1c9f2cdd, 0xbcb1a470,
+ 0x8b657d84, 0x6f7fdaeb, 0x6e92f9d0, 0x9106f795, 0x3a60dee2, 0xe9d7966d,
+ 0x86fe41fc, 0xed0215ac, 0x71cdb826, 0x1ffb7a38, 0x6b0ac6ba, 0xfdfccf41,
+ 0xfa7bb987, 0x66f3aec3, 0xb0f1a0ec, 0x7b19bf83, 0xf7cc78c5, 0x163ed8cd,
+ 0x39d98699, 0xbd3179cd, 0xa74e793b, 0x26f1aee7, 0xcf7c6b08, 0x1af1d678,
+ 0xcf1d4f8a, 0x2f5e02ff, 0x2fd78774, 0x37290b06, 0xa23e4a47, 0xac2ab7e3,
+ 0x1f671ef3, 0xa5445c63, 0x33e9e243, 0xb87b8c80, 0x3cf15775, 0xfd17a93e,
+ 0x7545ef81, 0xd43cb8a3, 0xc736250e, 0xc77f5e70, 0xef83ccec, 0x7c122746,
+ 0xea7c39d7, 0xd9cbc250, 0x492660fc, 0x0d93e230, 0xfaef7c0d, 0x07aab3dc,
+ 0xeaa57ff2, 0x4f01eb5e, 0x3f655379, 0x95e6f8a0, 0xc509f864, 0xa3e3eee6,
+ 0xaf121d2b, 0x32b3feba, 0xa7f788ad, 0xca241570, 0x3de4d5f7, 0xe81e5d72,
+ 0x8be3261f, 0x3dccfbf5, 0x232307c9, 0x1feb1f24, 0xbeaef926, 0xf38ed49e,
+ 0x48cfd449, 0xf74953e2, 0xb03eb045, 0x1a4de5db, 0x78ca7f0a, 0x75a79261,
+ 0x97a3bfbd, 0x5af03f7c, 0x68d0f991, 0x643f8fca, 0xef2a0113, 0xf14c2f18,
+ 0x946f8564, 0xfa16bbf2, 0x44b098fd, 0xfc0cafd2, 0x611ddc20, 0x32346f7a,
+ 0x8f94ce2b, 0xd533f4f2, 0x6a95198f, 0x0ef58f2a, 0x4fc79531, 0x7be537cc,
+ 0xaa655d17, 0x58f667df, 0xefafbe53, 0xa4fd5306, 0xbca669f2, 0xe49297ce,
+ 0x76a03127, 0xc0fda9ae, 0xfd5312ba, 0xf9857f14, 0xf7bf54fd, 0x9e025648,
+ 0x697f9477, 0xbc87966b, 0x96116aaf, 0x90ef5d91, 0xde5a3afc, 0x5ce89907,
+ 0x6491efc4, 0x0cccfd34, 0x8a8dfa8f, 0x46292673, 0xae24f7e1, 0x60f99b73,
+ 0x3f39a261, 0x2af795de, 0x2b9c6e96, 0xa828fe34, 0x6a929e80, 0xf3efa6ad,
+ 0x347c6a86, 0x9eb2e457, 0xefeb5dfe, 0xff5a621b, 0x4e5d7c50, 0x05e7cf0f,
+ 0x6f9ed2dd, 0xf9ec179c, 0x9ec0bc46, 0x9ec3cc6f, 0x7b0fac6f, 0xf61cb1be,
+ 0xc179637c, 0x8c1d3321, 0x83a66238, 0xe99a8e2b, 0xd0cfa740, 0xd5b2baf5,
+ 0xa7c21f4c, 0xb07f94f8, 0x6a7f575e, 0xf5d09fa6, 0xd78b0921, 0x1153826f,
+ 0xfbfca48f, 0x642eb5eb, 0x87d73abd, 0xf6f90df0, 0xbe50e0da, 0x48785b27,
+ 0xe4b77815, 0xd79e6d51, 0x27e5ad0d, 0x7d5bb6c3, 0xae7de6bf, 0x5f4355d1,
+ 0x871d5749, 0x1f070f9e, 0xffa4347d, 0x02f9fbd7, 0xfe3b3fa8, 0xf41db262,
+ 0x45df2ed1, 0xee1f036b, 0x49b715dd, 0x77bcba7a, 0xe39533f2, 0x9a598e18,
+ 0x82ebf014, 0xf036df18, 0x6bb39bcb, 0x1367f815, 0x458ed145, 0x8ff9cb88,
+ 0x17e464b0, 0x77f7940c, 0xdf2b7645, 0xe2f9d07f, 0x17192482, 0xf35432d8,
+ 0xdc647af3, 0xa543f3ce, 0xe3ca24dd, 0xe2e338e2, 0x83bf796c, 0x05e499d4,
+ 0xe1c7c039, 0x47c041f0, 0x69df85b3, 0x39b9b56c, 0x86ffc46e, 0x83f7e02a,
+ 0x72f90b1c, 0x35df2680, 0x0070e47c, 0x85eb41fe, 0x1c1d9ce9, 0x5be29870,
+ 0x99736e87, 0x892d39f2, 0x76c3faa6, 0x79e54dbb, 0x79532cc1, 0x298f21c1,
+ 0x28c8e23f, 0x8e2bfd53, 0x2bf94d7a, 0xea9a275b, 0x9169fd5f, 0xda249f29,
+ 0x077e061f, 0x3e8f522a, 0xe2553433, 0x7e382dc9, 0xb19dc16f, 0xa6a7def2,
+ 0xba72eb5f, 0xd3ecf71e, 0xde5439e8, 0x71f7681f, 0x5f43751c, 0x187be1e1,
+ 0x129f4d0e, 0xa7c03d66, 0xde772dc5, 0xe39bf0a3, 0xe578f596, 0xd3417d4e,
+ 0xdd39740f, 0x35ecaf10, 0x082f2bc6, 0xe03dfeeb, 0x3dd6d2ff, 0x7681fe14,
+ 0x9f86df39, 0x88def9da, 0x3c28570e, 0xda38b533, 0xefee8e2d, 0x25b2d8f5,
+ 0x1465259d, 0xfef41dfd, 0xcad3cd98, 0x365fdd6f, 0x4fd5a79e, 0x0bf0d5f4,
+ 0xfba567bb, 0x305bc7bb, 0xbe67ce4c, 0xd4f372c5, 0x32cf8e6c, 0x3bdf83bd,
+ 0x51fdea5b, 0xf3b74ab9, 0xe323105b, 0xdd8c44a7, 0x79edfa0d, 0x44cf893c,
+ 0xfbe468bb, 0xff9c5a47, 0xee5b6b4d, 0xf3454419, 0x7bda4ded, 0xe81b0160,
+ 0x9258d261, 0xd884f2c3, 0xb35765b6, 0xc7a2e493, 0x3f6cacea, 0x35ddbfe9,
+ 0xceb8248b, 0x49031bfb, 0x407d01ef, 0xb4be81b6, 0x71e54721, 0x1b9ec1ae,
+ 0x4df6fd81, 0xfb3d9c67, 0xced08405, 0x754fa90b, 0x874c6f43, 0xaffe3cfa,
+ 0xf143ede3, 0x42adeba4, 0xd74c338b, 0xd7f1d2e0, 0xf0d07769, 0x707fdfa7,
+ 0x6d15b32f, 0x8a3df272, 0xd2db8889, 0x4725afd7, 0x86ad65d2, 0x3f03d40f,
+ 0xa15ea9ea, 0xfb031d9a, 0xc7708772, 0x43a1bab8, 0xc2bffd3d, 0x9eff8e8b,
+ 0xc4f557ee, 0xc2f9421f, 0xeab7dd77, 0xd9ff4e89, 0x3e06577b, 0xb468e321,
+ 0x5ba40975, 0x677d3fd8, 0x6f3f7994, 0x8d7696cc, 0xa2beda71, 0x6799ddf3,
+ 0xf60217e6, 0xaa5586f1, 0x39e42fc6, 0xc4529c5e, 0x3a8b11ef, 0xe533cb17,
+ 0xcfd62f1a, 0xc80f85d7, 0xf5aee0f7, 0x455c2516, 0x9b6692f9, 0x15a048d8,
+ 0xf38fbbfb, 0x1b93bf66, 0x449efe71, 0x3726cdc0, 0x49b4b71a, 0xb94fec09,
+ 0xc5ecbdfc, 0x5c7ef94e, 0x8bd9bbe8, 0x2f17fd35, 0x86df602a, 0xcfee65fa,
+ 0x8f6bced6, 0xe12b7cf0, 0x0ba5bd67, 0x02de8d7e, 0xe8311df2, 0xf3b4aac3,
+ 0x8e969c70, 0x24fc3737, 0xc2795df1, 0xce16446f, 0xb76b46f3, 0xf89d7471,
+ 0x9d2afdd5, 0x1cc3c27e, 0x171a1faf, 0x4affd670, 0x1a7e7774, 0xd3d37fdd,
+ 0xdff4e83e, 0xa85f877c, 0x1e8969c3, 0xff043e05, 0x57e8dbbf, 0x8248f3f9,
+ 0x3127fd90, 0x6ab48ff0, 0xb98d89fd, 0xf44fdddd, 0xf1c5d8ad, 0xbe2cab10,
+ 0xf25c40ff, 0xef1fea19, 0x3ce5deb0, 0xf8fb8090, 0xd3bb3493, 0xe4d6f3e5,
+ 0x7ef2d1b0, 0xe55f8740, 0x2898eef5, 0x1f1373ef, 0xba77d815, 0x08aa7f1f,
+ 0xfbaa42f6, 0x466b7c49, 0x3f75fe31, 0x14707149, 0x61b339c3, 0x484f0db1,
+ 0x7b7c3eb6, 0xcbbb8461, 0x403ad27f, 0xe4f4e7c6, 0xc97e9947, 0xb8cdfdc3,
+ 0x73f71574, 0xca453b2c, 0x2cf78d6b, 0xd90d9d03, 0x67986c26, 0xdffbadab,
+ 0x23929819, 0xf852d1f7, 0xe21b7bd2, 0xac28567e, 0x84572c07, 0x7cc4071e,
+ 0x6c5fcf5e, 0x3285f2d2, 0x992acb7f, 0xc5ded56f, 0x3bd9aada, 0x98a44f30,
+ 0xedf0f40f, 0xf3043d9a, 0xe0798a40, 0xf21af83b, 0x83c86be0, 0xbe0f21af,
+ 0x0d7c1486, 0x51444bdf, 0xfd2a9e72, 0xfb0de33d, 0xf19efe03, 0xfe09b906,
+ 0xfe1e631e, 0xf87d631e, 0xf0e58c7b, 0xe1cb18f7, 0xe1e631ef, 0x87d631ef,
+ 0x8798c7bf, 0x1f58c7bf, 0x1e631efe, 0x7d631efe, 0xe58c7bf8, 0xcb18f7f0,
+ 0xe631efe1, 0xd631efe1, 0x58c7bf87, 0x629d737e, 0xacdd07f2, 0xba503bbd,
+ 0xa3e98e3e, 0x2928b539, 0x3ff7d687, 0xc7e7ff23, 0xf3ac54b6, 0x6efc25de,
+ 0x47845560, 0x44d373ae, 0x2116eeb9, 0x0e7db9d7, 0x76edf3af, 0xf1942f99,
+ 0x03f4a1c2, 0x74f8cabf, 0x0a4157e9, 0xf8520abf, 0xafc29055, 0xfd2ade32,
+ 0x57e1482a, 0x55f877c1, 0x82afc290, 0xa4157e14, 0x8520abf0, 0xfc29055f,
+ 0xbf07682a, 0x55f8520a, 0x157e1df0, 0xe0abf0a4, 0x038231fb, 0x2e1d15fe,
+ 0x26e9f9c8, 0xd0e8943d, 0x4cba87a4, 0xc6f9c879, 0x8df390fa, 0x8df390e5,
+ 0x8df390e5, 0xc6f9c879, 0x8df390fa, 0x88f11bf9, 0xef296f71, 0xde41db1b,
+ 0x9a73e637, 0x86c1affc, 0xf9c37935, 0x46b69157, 0x2e298f29, 0x9e72eb92,
+ 0x58ff059a, 0x1c92b86b, 0x763921eb, 0x8d676fc5, 0x89f892bf, 0x2b976f16,
+ 0x6f582dda, 0xbad37bf6, 0xe38282f9, 0x3bfe7383, 0x7f75cb91, 0xbad1ff2b,
+ 0xac14ede7, 0x90cb6c37, 0x3dede970, 0xd522a5c2, 0xbbe577eb, 0xbe3a17af,
+ 0xa5f98f5e, 0x28520e01, 0x910710f3, 0x1f33bb77, 0x2d5bedf1, 0x5d0b8c8a,
+ 0x4372e329, 0xe349aae9, 0x3b2d5b4b, 0xbb50440e, 0x83c562f6, 0x5699077b,
+ 0x0f96c871, 0x43e6d53c, 0x89cba89e, 0x6b83e2d5, 0x903c42af, 0x7f6eb70e,
+ 0xf7c13e24, 0x0bb746dd, 0x738d197b, 0x8ec217cd, 0x64985bdf, 0xda04f297,
+ 0xea1cdf41, 0x0c9bbc57, 0x4732bdf4, 0xff3e7b9e, 0xe8caabb2, 0xb5edd0fb,
+ 0xdd1ee157, 0xeed908a4, 0x33478f37, 0x2a34a71e, 0xc9fef09b, 0x8bc2ede8,
+ 0xd4bfb1fb, 0xddba1ee0, 0x71e32f65, 0x4eff7c5d, 0x4378b7ef, 0x2c17df32,
+ 0x13e3ad16, 0xf0a127d9, 0xde3ae6fb, 0x62af7e68, 0x0fe2c47e, 0x2ffc8ec1,
+ 0x7121c3df, 0xc3dcfbf1, 0x6c7866b9, 0xc4dbe221, 0xe40ef95e, 0xabc5e1e4,
+ 0xbe5c137a, 0xf2077c80, 0x5f6a2f9a, 0xf966fce3, 0xcf93240e, 0xcf8f8648,
+ 0x857e41c3, 0xe298ffdf, 0xe5e968df, 0x15e0bdc6, 0xdfd404b6, 0x0b503c2e,
+ 0xaf790906, 0xb6579f55, 0x57096238, 0x95e22f40, 0x11fd0378, 0x7a0198e7,
+ 0xf8d8f3c9, 0x56a9907d, 0x46fc0d97, 0x5d8a7397, 0x7542ec72, 0xf7df0c74,
+ 0x2e13910b, 0xb8e6f636, 0x8e3d7f8d, 0x93ef83a4, 0xce15df2f, 0xf88f8572,
+ 0xb9e6f807, 0x5977193c, 0x91c3ecb9, 0x38aed496, 0x8129d392, 0xf3df78ad,
+ 0xe88eea74, 0x11cb0a51, 0xdb5fc087, 0x7be79f1a, 0x5eabc582, 0x1710fbe3,
+ 0x96881f1b, 0x7fa4aaf7, 0x9bc34ca5, 0xa85a6f6e, 0x16994fad, 0x5ebc743f,
+ 0xe74bcfbe, 0x71f7bf30, 0x72c6d1b1, 0x28bca846, 0x880feb84, 0xb46f2b73,
+ 0xc5d3ddf1, 0x27578b6b, 0x777eee8a, 0xcfe32bc5, 0x349771b5, 0xa84e38da,
+ 0x2b477b5c, 0x965877f4, 0xd2e8726a, 0x27efe66d, 0x4fe44272, 0xad44fdfd,
+ 0xaf5bf14e, 0xa83964cc, 0xee71c6d6, 0xb94857f3, 0x0110ec48, 0xbf9867dc,
+ 0xef059c62, 0xe5dfcc58, 0xd0dd28f5, 0x7c9a3bd1, 0x12830934, 0x8a5ea7de,
+ 0xed32be60, 0xcfce3f52, 0xe9c894ba, 0xe4b2978d, 0xd11dac77, 0xbca16b4b,
+ 0x26beff5f, 0x1c44cd17, 0xb2e40165, 0x1dd74c3e, 0x2218d744, 0x4357e357,
+ 0x302bcabc, 0xf9b24fc3, 0x734e2156, 0xf7c146d2, 0x7e432691, 0x90d982a2,
+ 0x2fb00aa7, 0x3ef90a52, 0xef8544c6, 0xbe1e4cb7, 0xb407db4c, 0x11f3042f,
+ 0x37c3f77e, 0xf1006a7e, 0x3b7db337, 0x7d77582c, 0x6dfcf83f, 0x64e60efc,
+ 0x7bc762bf, 0xcf4d3e81, 0x743de9d6, 0xd4882c5f, 0x694e63ec, 0x8fb4eaff,
+ 0x9c7e5801, 0xc446f227, 0x2d802eb3, 0xb0b69fb3, 0x6ca8aa84, 0x1b9c9e59,
+ 0x94236379, 0x6ed37fac, 0x9162df32, 0xfe489ff7, 0x717578e3, 0xe50fb0a4,
+ 0xf92ad78b, 0xe1d79788, 0xd8d87afa, 0x777ac349, 0xe74941d1, 0x03eeccfe,
+ 0x5df960bd, 0x4cff2619, 0xf84a5a68, 0x105a3ec6, 0xfc63fad3, 0x5c84d0d2,
+ 0x889f1de1, 0xf9f5c877, 0x02e2208a, 0xdbf96ae7, 0x8ff2bd9e, 0x278c9c6b,
+ 0xedcd8fce, 0x3fe22377, 0x38fe65fe, 0x7f1ab15f, 0xf14daa37, 0x3de57379,
+ 0xdf5809c8, 0x7e76ecc8, 0xa66660c7, 0x212f9e4b, 0x72db9676, 0x845df2dd,
+ 0x694b7b10, 0x846f3cb6, 0x8f3c9dd5, 0xb66e3afd, 0x3ef3ea57, 0x33df336e,
+ 0x5cead3d5, 0xbff83769, 0xa0f127ba, 0x7ffbde45, 0xf1d812c4, 0xa06bd122,
+ 0xe6016fb7, 0xbde208fb, 0xcf1f7e19, 0xa3477f4f, 0xef694f93, 0x74f4e865,
+ 0xdf22eeac, 0xda712897, 0x9e81aadd, 0x7c28d6ca, 0x4ea4b11f, 0xadf627de,
+ 0xfcbde451, 0x8f57ec1e, 0xdf9af9cf, 0x17fc7a51, 0xc350b211, 0x91fb7cef,
+ 0x5d291cd7, 0xdd53fdf8, 0x7f926caf, 0x6f103306, 0x9c36b73f, 0x7afe41df,
+ 0x018fd158, 0x87b6647f, 0xf11269d7, 0x1a9fd434, 0xbe29fbe3, 0x07238897,
+ 0xf05c6f61, 0x7df8b7f3, 0x29bd9ae1, 0xf161eefc, 0x78d5bcee, 0x61ebe547,
+ 0x89723bbe, 0x2e9d8b7e, 0xea90e43b, 0x973e58c6, 0xeed1f417, 0xf6768ba9,
+ 0xf3ebe9e7, 0x0794ae60, 0x9c723c8a, 0x453e9a0b, 0x354db308, 0x7fe793d5,
+ 0xedd43ee8, 0x95f6a1a2, 0xbe2af7d0, 0x7b029ecb, 0x5760dd89, 0xb631edd5,
+ 0x7073e3ac, 0x77b7cf9e, 0xaf8dbbff, 0x4d4776eb, 0xa9d85d9f, 0xe84f66cf,
+ 0x9d7fb903, 0xbd1d82e2, 0x11bee9cc, 0x8765f5f1, 0x14f0886c, 0xf2dce293,
+ 0xe4bb92dd, 0xb72525bb, 0x9b3f31e6, 0xc7c9358f, 0xbc5187bd, 0x9402cb8f,
+ 0xdfbcf7c6, 0x657bade7, 0x53d01ec0, 0xe0f7cbd0, 0x7b5e5ccb, 0x2a2e419c,
+ 0xef4c526d, 0x17f9e818, 0x721da573, 0xc019a93e, 0xa6b74ddf, 0xd086f1d8,
+ 0x108f127c, 0x46baf837, 0xaa3b7a27, 0x932571c7, 0xf941c552, 0x9dc114ae,
+ 0xfe33c722, 0x9349514e, 0xaa063df9, 0xfedd72cf, 0xafee28dc, 0x4ef345d8,
+ 0x3862ea41, 0xa78c0f09, 0x3fa87bf6, 0xebc38f37, 0xd80c1a51, 0x8f983760,
+ 0xcfca1678, 0x186c0575, 0xbe51a4a7, 0x2b5be28f, 0x89adf1c7, 0x2e40e7b5,
+ 0x03ecbab0, 0xa360f28c, 0xbe78cf7c, 0x0411fbf6, 0x65cbcb2f, 0xf3dc2784,
+ 0x867defd2, 0x8358abe2, 0xd629acbf, 0xad365f2c, 0xe67d61b3, 0xc35ef0f4,
+ 0x971d1a97, 0xfbe18e34, 0x2f5665f5, 0x69f097df, 0xb2ebfef8, 0x27e1bbf0,
+ 0x90fcd399, 0x8d79052d, 0x3c097d2f, 0x829e06f7, 0xd23efc19, 0x678e70b2,
+ 0xe26ae39e, 0xfbe276f9, 0xe40fc201, 0xe3115715, 0x8fc4e89b, 0x66b2c038,
+ 0xc176faf3, 0x65df2513, 0xfde62e6f, 0xb3eac8b7, 0xac708cbb, 0xfb819fdf,
+ 0xdf68735b, 0xe127fde3, 0xcc7df1f2, 0xc8dc0f53, 0x3806fbbf, 0x8f28e781,
+ 0x3bde027b, 0xba61ba22, 0x4167e9d6, 0xfacfdc81, 0xacc35178, 0xec3f0ed2,
+ 0xf7a9f6bb, 0x06f3e420, 0xffd86f5a, 0x76a7da7b, 0x71a4005c, 0xddf265ed,
+ 0xab7dd0ba, 0x9f7d57ef, 0xdf56fbea, 0x8ad98fcf, 0x174a8982, 0xbdf3a1df,
+ 0xf06eb9f6, 0x77834934, 0x84aeb6ae, 0xc18557d7, 0x986237ae, 0x53f3dfdc,
+ 0xfd1ffbcd, 0xbd54dfa1, 0x03306c7c, 0xfaf53df7, 0xe3f3b8fa, 0x03ec3b64,
+ 0x30ea5bd0, 0xe5fd674b, 0xe262df5c, 0xfc9da51f, 0x04aafb63, 0x0a1d8ff0,
+ 0xdf96e1fb, 0xe5bee523, 0xe17bc8cf, 0xf8bf9667, 0x77aa2cf6, 0x0b8dc1fa,
+ 0xca2ff78c, 0x2c5f9282, 0xfc0b7924, 0x0f269163, 0xe5f4cc6c, 0xe7ec330d,
+ 0xc99ffbb2, 0xdb98fec4, 0x6f0a7792, 0xf9bcd1a8, 0x3f3fa3bd, 0x5787d2f3,
+ 0x5dcebbb9, 0x6b251e7d, 0x3b15b5de, 0xf493788d, 0x0756777e, 0x38a55b9f,
+ 0x6953e8b7, 0x61f33163, 0x8f7a4891, 0xa1eeb5d2, 0xa8dc50f4, 0x5a579cb0,
+ 0xfea03237, 0xd2ebf22f, 0x8df953b5, 0xf4bd7d28, 0x73f45f77, 0xa67f8757,
+ 0x35734eb6, 0x4c3d9e7a, 0xe5b9c3ee, 0xbc45f629, 0xf8ec53ff, 0x5a39cdbd,
+ 0xf3329cf9, 0x72f5cef7, 0xd5fbf275, 0x9fb827d8, 0x58eaf584, 0xcbf6936b,
+ 0x57ad97ed, 0x1d02e432, 0x9d9ac58e, 0x6f66a172, 0xcbc9a45c, 0x8d8b5eb4,
+ 0x71f8b5eb, 0xcfa55eb9, 0xbc17f5be, 0xd3f34653, 0xef93a3de, 0xecb4940a,
+ 0xb39b75e0, 0x852d9d66, 0x5864fdea, 0xa8fe298a, 0x05cf36b4, 0x35dcfd3b,
+ 0x07e06d1b, 0xf126193f, 0xf3f74a16, 0x1d62f8b5, 0x148f38af, 0xaf473f83,
+ 0x83b83e0f, 0x5975b9c6, 0x77f1b478, 0x3d1a02ed, 0xc6c6d697, 0xdad2bc61,
+ 0x7fa17be2, 0xe840e7e9, 0x2e113bfe, 0xf50945f7, 0x6279fd87, 0x55ef878c,
+ 0x377ed7cf, 0x43feb42f, 0xdafddd1a, 0x4cbfdf26, 0x92796c8a, 0x226a3be3,
+ 0xe913e03c, 0x8c01ade9, 0xdc067a0b, 0x2f7c8b76, 0xf5b2bd33, 0xa241c073,
+ 0x20f5c73c, 0x105b7bc5, 0xbf2813ed, 0x79ef22c9, 0xdd32aaa5, 0xa607e1a7,
+ 0x5e8b9437, 0x5f1efcad, 0x2151bbe7, 0x9b176af4, 0x1fdde0d7, 0xefc12f7b,
+ 0xa9f4e9a6, 0xa7d3a3f7, 0xcd3dbf4e, 0x9cf7d76f, 0xcd1489df, 0x49e592ce,
+ 0x0bb8d076, 0xbfc41bee, 0xf35df16b, 0x35ef6bb4, 0x4c37ce76, 0x65c7defe,
+ 0xfa974df3, 0x6df3cf52, 0x66e84c2e, 0xd4f3a1be, 0x431e89f7, 0x694fe9df,
+ 0x1394fe92, 0xd4639d0a, 0x70b2c4ee, 0xe7d3ab8e, 0xbff5dba5, 0x8f87bdef,
+ 0xf669c586, 0xc828d6aa, 0xdfb5f397, 0x99411151, 0x86a9f7c7, 0xaff9faef,
+ 0xf3a75fbf, 0xdab593e9, 0xef5a28f9, 0x75167ec1, 0xf50f7c69, 0x2889d358,
+ 0x627313bc, 0x6f4f848c, 0xde4dab77, 0x76511673, 0xbbcfde37, 0xfe3cd6e9,
+ 0x8d8594bd, 0xbd9f587d, 0xf98d2ea9, 0x587e4dc2, 0x1ea74517, 0x83e348b0,
+ 0xaf16b791, 0xd7f502be, 0xc2eff0a7, 0x4e7a742d, 0x43f6e7ad, 0x2313903d,
+ 0x53daa79b, 0xfa961e59, 0xbb17ee82, 0x7c451155, 0x127c0d4f, 0x3fb2cbfb,
+ 0xe2cfe71d, 0x983f52f5, 0xe06b1164, 0x50d81d3f, 0xf82fa134, 0xfc8ac3c4,
+ 0xe60d9a3d, 0x0e86bcf7, 0x7c02fa2a, 0xbc5df426, 0x5e2d6d5b, 0xe482a7e8,
+ 0x16d1d80e, 0x9e588b3a, 0x93e345bf, 0xf8db9ac7, 0xaf1d7ebd, 0x78bfe08f,
+ 0x7ec42aa7, 0x1a276a14, 0xff07d9a8, 0x7b8faf1f, 0x0080003d, 0x00000000,
+ 0x00088b1f, 0x00000000, 0x7cb5ff00, 0x65545c0b, 0xce7bf8da, 0xc0cc2b99,
+ 0x1245c880, 0x85848b87, 0xd780c034, 0x508151da, 0xb9bba0bb, 0x658e21ba,
+ 0x500665ca, 0xd7775ddb, 0xa6a18cfe, 0x45fa7d66, 0x80ed65a6, 0x76c36a97,
+ 0xa8283448, 0x59990bc9, 0x6a37627f, 0x5b63b92f, 0xba402de6, 0x6dbfedfc,
+ 0xbcf3cf7d, 0x511730e7, 0x6fbefddb, 0x797bf9fc, 0x9f5ef3df, 0xcfbcf3fb,
+ 0x8c346339, 0x63181b75, 0x418e8b2a, 0x89486839, 0x8d8c9964, 0x615f6909,
+ 0xf6c3894c, 0xc645db25, 0x7cfb4046, 0x1962c893, 0xfa31d72b, 0x1fbf8f7d,
+ 0x3c1f7631, 0x42f3c337, 0x07d634a9, 0xcc37d7fd, 0xd6c972a0, 0xf1ae6dc2,
+ 0x2509258c, 0x606393b1, 0xb66ae3c0, 0xce258a07, 0x2b307719, 0x8da4d3cc,
+ 0x73c325d2, 0xc7292bb5, 0x496f9fe0, 0x0c4943e3, 0xd4699dc6, 0x7b4377cf,
+ 0x414e6981, 0xba5f8c14, 0x325b2a33, 0x6f5dfbfb, 0xc91b1811, 0x4673a558,
+ 0xcc614b1c, 0x67e1ddf1, 0x1fb0a94c, 0xf304d398, 0x7709e57f, 0xa38ba0bb,
+ 0x82492dae, 0xb3aa3c23, 0x7fa058a7, 0x6f31d895, 0x4e73cc12, 0xa04def70,
+ 0x5338e6fe, 0xe5a1fac0, 0xccc63ae9, 0xff398ce9, 0xcf3487cf, 0x3b89e2e7,
+ 0x8778c016, 0xce047f73, 0x1ff8f553, 0x6c3201f2, 0xb2cf689d, 0x8dbce1e4,
+ 0x1c124d7b, 0x56637b74, 0xbee39c09, 0xda46c7c7, 0xf79f2f33, 0xa8b668b6,
+ 0xdbcbda04, 0x6957c118, 0xd48ee85f, 0x5eeddc20, 0x696131a6, 0x28689a62,
+ 0x956c48cf, 0x52dbca07, 0x06b9a2d8, 0xe10dbb7f, 0x899eeb00, 0x025492dc,
+ 0x9f7b15ed, 0x79433248, 0xa5ebc8d6, 0x9c7a7f7b, 0xddff4045, 0xd5e20d5a,
+ 0x0b1a62ae, 0x25d7bb8c, 0xb250dcd8, 0x12c668f2, 0x7d6ea310, 0x59b19199,
+ 0xaf9a7096, 0x630e7b62, 0xc17dfeb9, 0xab3f6a73, 0x8fb8c562, 0xd903f531,
+ 0x8bfca1cb, 0xe21f7bca, 0x7ab52ff3, 0xf1192b8b, 0xfcbc2662, 0x84548b65,
+ 0x05fbaeed, 0xfac05636, 0xac1a637e, 0x6ac9165f, 0xf4a17c71, 0xcf049b57,
+ 0xb2101c57, 0x787b30b5, 0x1ee6b766, 0xd1169103, 0xd389b559, 0x75768ad9,
+ 0x7fe02251, 0x2d408b45, 0x3357950e, 0x2f2abe1c, 0x80e6664d, 0xb6b656fd,
+ 0x8eb0cc68, 0x09ce19a3, 0x539e1dfd, 0x5e78a59a, 0x7cb185b6, 0x89fe27c0,
+ 0xa53e6bf8, 0x3f0037b9, 0x2e1cadd5, 0xbede56ce, 0x3b900338, 0x1362b699,
+ 0x26dea0d2, 0x6b3ebd50, 0xaa35fcc2, 0xfcfe7ac0, 0x9a586935, 0x354c4e08,
+ 0xf0025490, 0xa3d194dc, 0xd73bfc41, 0x5d42f3ca, 0x0d5eb01d, 0xde48e512,
+ 0xf1c06a9e, 0x3caf1a66, 0xd146b677, 0x6c33af78, 0x3609bb03, 0x61506d51,
+ 0x4434ef59, 0x56b3b960, 0x715950cc, 0x09166173, 0x1611dfe0, 0x6122c591,
+ 0x3d5eaaca, 0x3b501240, 0xf6845870, 0x83fb48dc, 0x0c719f48, 0x33e802b8,
+ 0x06057991, 0xf9dfdff4, 0x7fce2e59, 0x17df18cb, 0x5eaeb60c, 0x017e7d33,
+ 0x8b26c3d0, 0x5f4c8e7c, 0xc8f1d22e, 0xb0af4043, 0x6cd5a7bf, 0xcf073e83,
+ 0x42e6c257, 0x08c2cc3b, 0xb984dfcf, 0xafdfc0f7, 0xce226f31, 0x54de74cf,
+ 0xcc9af71c, 0xc35a25a7, 0xf5f60106, 0x63fb149b, 0x053b8fb8, 0x116cf8f5,
+ 0xc58d2071, 0xfe6afd7e, 0xc2796d9c, 0x4ffc03a6, 0xa367e8e7, 0x4062e645,
+ 0xf1519aa2, 0xc163a406, 0x60ab6366, 0x0f3307fd, 0x2e80cbdd, 0x31d01e1e,
+ 0x5eaf9c2d, 0x7d3dcfcf, 0x0094ec20, 0x2a8f46fd, 0xf4165916, 0x2958ab37,
+ 0x29943ff4, 0x9fd8557a, 0x9fd8dce9, 0xbe6d0ae9, 0x8196590c, 0x7a88d0fc,
+ 0x78eff51b, 0xca011bf3, 0xe1e2e944, 0xe2573848, 0x3d4b052f, 0x3c1b29f4,
+ 0x85fff4fd, 0x5352f4b2, 0xfca1efcb, 0x19bda475, 0xb0727751, 0x501d94f8,
+ 0xa3c9b0f6, 0xf9f264b3, 0xf1dff702, 0xa2226fab, 0xfabeff45, 0x7bef4e07,
+ 0xcea58ad9, 0xe9b8c022, 0x9b57921d, 0xfa7ef975, 0xa9e361e3, 0x39e18fd4,
+ 0x5ba20dfb, 0xe1ffb010, 0xd37f710f, 0x14af0675, 0x17d4e381, 0x38ff3a7c,
+ 0x751d1e66, 0x284646fa, 0xb1913ef8, 0x8c3cdc58, 0x7068b81f, 0x6fb9c137,
+ 0xa14ff991, 0x488b1eaf, 0xf191e9f8, 0xe991c0a4, 0x7e9122b2, 0x5e8ad5eb,
+ 0x4cb385f0, 0xe8d67f3f, 0x5e0cff38, 0xff386d12, 0xcdd6b960, 0x8ec18a60,
+ 0x5727d254, 0x007fa792, 0xd740ca79, 0xfb6a97bc, 0xf90fc233, 0x78fc074a,
+ 0xc02f0c97, 0x25f9c33f, 0x64bbfe79, 0x1065ddb8, 0x127e9c39, 0x6e992702,
+ 0xf650ba14, 0x5863982f, 0x9f1fb469, 0x47ddd7ec, 0x8f099323, 0xe383ffe3,
+ 0xdfc213ef, 0x01d62737, 0xff51b11b, 0xfc784598, 0x579fc05f, 0xf80bfeb4,
+ 0x9fc50eeb, 0xe23d7f57, 0xd2d171ef, 0x0880fc84, 0x26d2a1c8, 0x0658f9c2,
+ 0x932ffe23, 0xe09b2cc2, 0xffe4767c, 0x8fef889b, 0xfc2bdf22, 0x37d8a63e,
+ 0x49e4f51e, 0x7dc19ec6, 0xb50f44f9, 0x10a766a7, 0xbac75f9f, 0xf01db013,
+ 0xf117379c, 0xe876d82e, 0xfb7d2c24, 0x5df5865e, 0x1ecb0615, 0x5bbf6f38,
+ 0xfe61a974, 0x8ef72886, 0xc36eb0a5, 0x1716995d, 0xd59633b6, 0x3ca07286,
+ 0xbe7a82cc, 0x85cb8a21, 0xa4e90586, 0x277e0f87, 0x73c2ad25, 0x34b3082c,
+ 0x6c86ff41, 0xa01323df, 0x6cd630de, 0x57d74171, 0x1dbe9605, 0xd1d1cfc7,
+ 0x38730d3a, 0x323c36dd, 0x057a8dda, 0x7af3cff4, 0x1e593fa8, 0x0d9cf0c6,
+ 0x6884b68d, 0x2297cba0, 0x61b3a3ec, 0x4e24a3ff, 0xd0c90dd7, 0xa136e50e,
+ 0x387dc164, 0x6fbe78df, 0x17b082df, 0xfa2cc2f7, 0xd0591034, 0xb195727e,
+ 0x42a5e509, 0x73a57797, 0x75c63779, 0xc9c2076a, 0xd4659d35, 0x937ffcc2,
+ 0xbb814be9, 0x556c6360, 0x0afe1fb4, 0x70c8c59d, 0x7a735617, 0xe5974d73,
+ 0xd7733562, 0xe65f080b, 0x96f8070b, 0x42414169, 0xadd93469, 0xe5faefb8,
+ 0xf7091780, 0x527fe1cf, 0x619ee564, 0x2847e7f8, 0x4c88f32c, 0x328fe404,
+ 0x0ca3f9c6, 0x6fe908e9, 0x0051d015, 0x75df31fd, 0x65c3a751, 0x6bf1823a,
+ 0x70d3258d, 0x3f85cfbd, 0x89e363e4, 0x87f34a7f, 0x3656675b, 0xf40b0397,
+ 0x9fd899f6, 0x51148eed, 0xf130ae5f, 0x7f644ef5, 0xc5f51a36, 0x79bd5fc9,
+ 0x23c7961d, 0x86cb6e4a, 0x7c16dbfe, 0xfce2845d, 0x353e096f, 0x0b6fe39e,
+ 0xb468fffe, 0xbf56ca43, 0x43fef449, 0x192859f7, 0xaf4e5032, 0x15a67d04,
+ 0xb074e4b0, 0x74463ef2, 0x896ac890, 0xfd65e36e, 0x47a30c05, 0x00f37539,
+ 0xbcca8ed8, 0x9747fff0, 0xce896c74, 0xa2c69f5f, 0x7433ea82, 0x0bfd4109,
+ 0xcf41c94d, 0x171f8d6f, 0x39a67cf4, 0x3b3ea83b, 0xff505263, 0x82d32ddb,
+ 0x9c4e77ea, 0x8e7fd419, 0xdd504e6d, 0x1f244cc6, 0x738aea3a, 0xe1bb013f,
+ 0xdc92bab5, 0xe397544f, 0xd0f6aa63, 0xe805b37e, 0x5f3bdb24, 0x91ea0935,
+ 0x43265687, 0x11cb537d, 0xf43c4f5e, 0x66e03245, 0xf9d1cb73, 0x53dbd02a,
+ 0x45f43c6f, 0x6d1fd40a, 0xa7cfe2e9, 0x40a362c0, 0x39bcb6ac, 0x9af805df,
+ 0x8adf629b, 0xa9779af8, 0xf98a28f6, 0xbdccd7f7, 0xb942592f, 0x06746730,
+ 0xc53727ec, 0xbf3e10fe, 0x759ef62b, 0x1ffb0091, 0x46ab5b7d, 0x5d98bf3c,
+ 0xa1e915b2, 0xf3a722ff, 0x91978853, 0x96097eff, 0x8a61d903, 0x3c92bd9c,
+ 0x03adf854, 0x1512c6f4, 0xa54749c2, 0xe544ceb7, 0x2a78baa1, 0xd999d48f,
+ 0x57638012, 0xc795065d, 0x7ed42cea, 0x95226ebc, 0x546cea27, 0x4c575bbe,
+ 0x095d7765, 0xb2ff0a95, 0x6a0d96bd, 0x2a974224, 0x4fceb4ea, 0x63d2578f,
+ 0x69d92820, 0xf9d09f05, 0x39adbd4d, 0x9d75ce9b, 0x6959e909, 0x81f9da3f,
+ 0x9dfa0459, 0x3d11d56a, 0x9b74354f, 0x475e5675, 0x22fbb8b9, 0xbc118af3,
+ 0x5fb02a9f, 0xfd1b278c, 0x030ea998, 0x841b4bf5, 0xefd8597e, 0xf79404cd,
+ 0x16356b53, 0x509e63b4, 0xf61e9733, 0x90df146f, 0x20e31d70, 0x05d86cca,
+ 0x903ad518, 0x6ba07157, 0x63f439f1, 0x0f77283a, 0x4746f5f2, 0xf9472ed7,
+ 0x60ccba34, 0x95f2e7a9, 0x08e24be4, 0x2fee026f, 0xda86a571, 0x198f628d,
+ 0x9d5f60e5, 0x69d21677, 0x0ae72c81, 0x30ef5c34, 0x80bde411, 0x576dfb7c,
+ 0xedf3da22, 0xd02f9edc, 0xfa44ec96, 0xfe7156ae, 0xf77a3165, 0xd5475c1e,
+ 0xf42cf15d, 0xb44d89eb, 0xc568426c, 0x6069641f, 0x14d617b7, 0xeddca267,
+ 0xaf885b61, 0x13fd5ec1, 0x338fdbd2, 0x9945df81, 0xf89e6048, 0x4da6f0e2,
+ 0xd7adda02, 0xce5d21e7, 0x300f9ad5, 0xf65f07e0, 0xdcfbd100, 0x7a1e7348,
+ 0xafecbe0a, 0x7cce3d79, 0x26e78040, 0x00bf3036, 0xe9cf55ea, 0xf0049f4d,
+ 0x1513d3a9, 0x4b69af54, 0xc0127d30, 0x07f855a7, 0x09b747fa, 0x0ebb942a,
+ 0x04a72b79, 0xb7c405fb, 0x0d73f8b3, 0x0680dfdf, 0xd98bd8ed, 0xb06fa266,
+ 0x0fef4997, 0x9bba34cc, 0x2371bf60, 0xa057b36a, 0xce6994fd, 0xea497ec3,
+ 0x63f40881, 0x1555bffa, 0x19efc9bb, 0x78c9f888, 0xd33d7d3f, 0x287b5121,
+ 0x70e6b5dd, 0xcd26af7f, 0x50f119b0, 0x51d3af1d, 0x88b171d9, 0x92569d91,
+ 0x4db97686, 0xd0cbfdc3, 0xb8737bf1, 0xaf5e491e, 0xa240b921, 0x0b6cb608,
+ 0xc5dd4a63, 0xf8d63226, 0xbf21b08b, 0x34c9c007, 0xc83f6563, 0x41476235,
+ 0x1b7f505a, 0x8e7a1ff6, 0x8ff31cf6, 0xbb49794f, 0x5e4aad63, 0x2965e90f,
+ 0x183fa373, 0x72abc72a, 0xc0b965a3, 0x8c74fcf1, 0x9cf111be, 0xe77d0126,
+ 0x504cc950, 0xb2338626, 0xd75f1337, 0x773e91bb, 0xa7fd39eb, 0x2ddcbc89,
+ 0x309afef2, 0x577a42e6, 0xb94d87fc, 0x79b929f6, 0xe6978f34, 0x91b25a91,
+ 0x879813ae, 0x24ec57d6, 0x43d81fa5, 0xaa02127a, 0xd7c47481, 0x161c4954,
+ 0xa672279e, 0x448ce515, 0x4fb1b0fe, 0x5f77e403, 0x40aac478, 0x78e355fc,
+ 0xe9b8e043, 0xef194e34, 0x4fb2255c, 0x245c9047, 0x89a6723a, 0x4b562fe4,
+ 0xfe8088ec, 0xa0d6eb16, 0xf5c6539e, 0x14fc1c82, 0x9047f0f0, 0x087e588b,
+ 0xffd710f2, 0x2c43c833, 0x10f20aff, 0x3c824fdb, 0xf207d2c4, 0x063fdb10,
+ 0xbce58879, 0xe4568dbb, 0x69b69a9f, 0x7e20d3ec, 0x017ddb50, 0xc369def5,
+ 0xa64391d3, 0xe1e4dea3, 0xe1cbaf9f, 0x2def457e, 0xa0fd9f1c, 0x00ffd1bf,
+ 0x8a6b5cba, 0xef1eb2be, 0x1ef9b237, 0x7cb6d380, 0x27f4876e, 0x1cd2faf0,
+ 0x226dd535, 0xb7e38edb, 0xfaf86be5, 0x3e396229, 0x79f345b7, 0xb245d37b,
+ 0x9e4ea69f, 0x9e0724b6, 0x3da162db, 0xbdef5fc7, 0x8db73f81, 0x7a43ede2,
+ 0x253e7e56, 0xeff8a4d7, 0x652fdce9, 0xbd012764, 0xff4afcd3, 0x3e7226f7,
+ 0x4eefed0c, 0xc3dd8b13, 0x992de3c0, 0xd02f896f, 0x483e469e, 0x6a8be00e,
+ 0x4285f133, 0x55fd0a87, 0xa73872e5, 0x073a6569, 0x43f042dd, 0x3a72831d,
+ 0x25f64f4e, 0xe0c6c5c0, 0x9905bb3c, 0x01f9425f, 0x0a07d44a, 0xa07c283f,
+ 0xf0227bd0, 0x3fed1099, 0xf421cdc7, 0xca8f94aa, 0x358ee8e7, 0xdaf09cfe,
+ 0xdfa136a1, 0x87cc3377, 0xc1c513e3, 0xfe46ef77, 0xd19a358c, 0xc87c2cf5,
+ 0x1c9c3b50, 0xc2effaeb, 0x570b9143, 0x7065c780, 0x5ff2f0d0, 0x39c90385,
+ 0xbf48e394, 0xfdadc8c3, 0x5db2d139, 0x44f7e9ce, 0xd21f6d8e, 0x57a0bf51,
+ 0xafd0dfa1, 0xd9dac367, 0x7f39f2db, 0x05547428, 0x89eb103a, 0xcbd4ce78,
+ 0x9e729ee5, 0x632e73a1, 0xc2d2ff24, 0x9e287b78, 0xc8057395, 0x0139c3bf,
+ 0xb8c61ff1, 0xd81d717d, 0x4d4fe817, 0x3ed335c9, 0x567e47fa, 0xcff995b6,
+ 0x6f0e477f, 0x88944a7f, 0x32fd141e, 0x8b482ed4, 0xe90664e6, 0x3f42661d,
+ 0xfc4b53af, 0xe67f05ee, 0x3e871825, 0x3fe49b21, 0x71e320bf, 0x1158fe70,
+ 0xafbebbed, 0x63d42e0d, 0x4e06a37d, 0x6fbe300a, 0x6436183b, 0x136ed897,
+ 0x07deef40, 0xd4f5063a, 0x2c7b9005, 0x7273b19d, 0x73cfa11c, 0x73fa24f1,
+ 0xa6243b35, 0x3b4a5003, 0xf4879abe, 0x6d53b4b4, 0xf6d0b8a2, 0x3d218ec7,
+ 0xcc156e9e, 0xb5f49768, 0xbfa1f1c2, 0xd6e8c1b3, 0xa822ff43, 0x0665ff63,
+ 0xd7ccdb8d, 0x4383f8a3, 0x7d53ef5e, 0x85c60a75, 0x1350ec66, 0x2f3e97dc,
+ 0x3b3ed1b9, 0x0aa57dbc, 0x02dda7eb, 0x4571838b, 0x04aeead2, 0x2d3e57a8,
+ 0xce30b458, 0x8b3a2861, 0xe7ca82f1, 0xf30bc599, 0xc918b657, 0xa0da5dcf,
+ 0x6017d8fe, 0xb7bb945f, 0x29eed06a, 0x5edc19df, 0x0eb83bb9, 0xeff922f8,
+ 0x00f68668, 0x8e6dfcf9, 0xcdec8631, 0xed1b2c71, 0xe3c0d64d, 0xbf7c8ab9,
+ 0x71756edc, 0xcb82ba39, 0x8cbec66d, 0xea5f7f45, 0x63e92afc, 0x91cfaf03,
+ 0xfea0a7eb, 0x2f1c57f9, 0xe5aa5c0a, 0x604f3fb5, 0xb79c0f56, 0x426f53ba,
+ 0xfdbabfff, 0xb71811ef, 0x51f309af, 0x22bd9f7c, 0xdbded099, 0x10b926d8,
+ 0xfd0ecebe, 0x56e0112e, 0x8d3de07d, 0x5f7088d9, 0xadcaf64e, 0xe31eb5cc,
+ 0x64515edc, 0xdd4744dd, 0xb666a714, 0x4f38a581, 0x84debb5f, 0x2bf54076,
+ 0x8ddd741f, 0xd30203f5, 0xfb471e23, 0xee964e88, 0x2da58640, 0xfbe426dd,
+ 0xbc4244e9, 0x913d9e22, 0x8865af84, 0xe033c477, 0x212cf11d, 0x51bc713e,
+ 0x2274e6e3, 0x73f4fd51, 0xde0abf1c, 0x1acda48b, 0xe46caf6c, 0x63b19e78,
+ 0xa230b6cf, 0xe9933503, 0x7a7ef080, 0xa6bbc727, 0x14669d73, 0x08636fd2,
+ 0x876bb41d, 0x77f700e8, 0xe0841d19, 0x8df002bf, 0x0e942072, 0x93dff142,
+ 0xd806e5c3, 0x429fa7df, 0x7e08dbfb, 0x23c7f301, 0x1ef55646, 0xcaf5818d,
+ 0x973bcfa2, 0xf8d8fb43, 0x08da5897, 0xe4157f8a, 0xe66bfc62, 0x5d10eb3b,
+ 0xc85eb33d, 0x57a97a46, 0x813cf6fb, 0x70a88b71, 0x27f4e38a, 0x32f9d9cf,
+ 0xfa20bb9c, 0xd816a49b, 0x5a6bcd7f, 0xc928deba, 0x35ec8715, 0xf129978c,
+ 0xc533c074, 0x5a1d9cc9, 0x2d6b171e, 0x73fa05b4, 0x5cfc09fd, 0xb2819a85,
+ 0xc017e8e5, 0x608eb87c, 0x555e7ee3, 0x28178f07, 0x1295597e, 0x8e0e6837,
+ 0x77a6081b, 0x2e455fa8, 0xc6a55f8f, 0x3b466cdd, 0xb3017ebc, 0x4d5ea587,
+ 0xcc78f03f, 0x74dfb2d3, 0x0af1fb45, 0x1bb1427a, 0x6e382b99, 0x65a9c8a1,
+ 0x8f1ef913, 0x6ab8e2fe, 0x76fdc604, 0x8a8f840b, 0x704f900e, 0xdab70ade,
+ 0xf802166d, 0x19ffee49, 0xedc01bd2, 0xa0f6ab8c, 0x19dd2128, 0x990ebf68,
+ 0x8e91ab3e, 0xd695bce0, 0x9cf02237, 0x38ae590e, 0x7f148dda, 0x8a5b64ab,
+ 0x612aee90, 0xf430ef3d, 0x0b5cf954, 0xa2d729f9, 0xaccec527, 0xb7ee0d6e,
+ 0xce487731, 0xe01eff8c, 0x396401bb, 0x992e7bd7, 0xf12332fe, 0x99906fde,
+ 0x879f9123, 0xedc09ff4, 0x5cfe4537, 0x3c581dbf, 0x6e71de60, 0xac05531d,
+ 0xa673e37f, 0x4f78faa0, 0x9bff507c, 0xcf41ccda, 0x4119bdb3, 0x598f73cf,
+ 0xdd79ea82, 0x4ffa8313, 0x5416d0f8, 0x0e2be49f, 0x4ce53fea, 0x307d5049,
+ 0x9573ce13, 0xe35bc1fb, 0x33fea085, 0xf9a0facd, 0x05446767, 0x320d07d5,
+ 0x52bb647c, 0xce5f77b1, 0x686ef6e5, 0x76f7c0a9, 0x8a3af04b, 0xc4e77ebf,
+ 0xd8e6f5e0, 0xa1fbd782, 0xfa0bd978, 0xc27e0554, 0xb15fa073, 0x13f81dfc,
+ 0x9a13f02a, 0xfac09fc1, 0x604fe08b, 0x027f01e9, 0x7f025fdb, 0xe0adeb02,
+ 0x20fd604f, 0x6f583ff8, 0xf2a62bab, 0x6a12ba95, 0xbafc16bf, 0xc98f75e4,
+ 0xd7971eeb, 0x74e177fd, 0x5def9e42, 0x9c6ebe79, 0xdcffcd2f, 0xbc563c59,
+ 0x2d3cfc04, 0x87c6acfa, 0x5f0ac37e, 0x062dc611, 0xc61892de, 0x7ddd99a5,
+ 0xf5062eac, 0x338a08d9, 0xb78192b3, 0x7d52ae31, 0xc9b4d520, 0x0fecfa8c,
+ 0xbef3e2ef, 0x7c8cc956, 0xefeda879, 0x85cf3811, 0x5f74614b, 0xef107a4a,
+ 0x5461bf1b, 0x31cf04df, 0x05b33a0e, 0x37e90804, 0x0bb7e90f, 0x4ddd4a69,
+ 0xcd25bdf7, 0x53c41a2d, 0x3c29f215, 0x0ea3cb7f, 0x635cfe7e, 0xf61373d0,
+ 0xe54ab287, 0xb9c238a6, 0x2f3e6536, 0xf1a477f5, 0xcf73cf7b, 0x053f5e1d,
+ 0xe2cb6ff5, 0x5e7f7811, 0xec5efcd5, 0xc7c157bd, 0xc85f07e7, 0x76cafba4,
+ 0x9fe0cf98, 0x96aed9cf, 0x8eff7ceb, 0x68a296b4, 0x02cd1c54, 0x05c50b1b,
+ 0x5fee85b6, 0x38f6daaa, 0x65556e50, 0x0066addc, 0x248f7e9f, 0xbdf837c7,
+ 0xb8c4c391, 0x22f9e71d, 0x5f57ef02, 0xc3bd1cf7, 0x38edf886, 0xf6eb811c,
+ 0xfe414ab7, 0xb72b68d3, 0x355b478f, 0xad0bbf84, 0x5ef02387, 0x30e7a377,
+ 0x4bcabb87, 0xd7243fe7, 0x7824a1fb, 0xfe7449b7, 0xd0624b8a, 0x5586763d,
+ 0xb66679a2, 0xb9e2358d, 0xbd7c3c7a, 0xb799ab1c, 0x825e2da7, 0xbf1e3ffb,
+ 0x7b224f20, 0xca350410, 0xef661bf1, 0xcaa43b41, 0xf386d923, 0x79e40aef,
+ 0x4e9cd4bb, 0xdfdb4adf, 0x78f8f285, 0xd26c88f1, 0x699f8a11, 0x916f76e5,
+ 0x7a869ec6, 0x3660c7a4, 0x583f9d22, 0xfc446a9c, 0xdb12c21e, 0xec69778b,
+ 0xe6c7bc06, 0xba98f5eb, 0x7aee9023, 0xb425735a, 0xf2f99477, 0xe88775e5,
+ 0x2e6f087b, 0xbbb953c2, 0xf8f380d1, 0x73dbc7f1, 0x7fea26ac, 0x3cdefddc,
+ 0x327aabb4, 0xe92ec9c2, 0xa7f230d2, 0x5db99aab, 0xd891d3dc, 0x924f7818,
+ 0xf2fd9563, 0xdaf0910c, 0xfb96a6d7, 0x0587bddd, 0x39d353f5, 0xde0eec2f,
+ 0xea7dc98f, 0x1dc7b451, 0xf50c4b4f, 0x1b5d43a2, 0x6cffe78b, 0xcafef067,
+ 0xd43b3865, 0x00d8d8de, 0x0fb4757a, 0xe8818df1, 0x13e15dbc, 0xc153e133,
+ 0xb7064f63, 0xf9e27ae7, 0x65a3a4bd, 0xe5f5d10f, 0x64eea4f1, 0x7f121ff4,
+ 0xe778a3a9, 0xc567fcb5, 0xaff0086e, 0xea8bfa18, 0x313cd4e2, 0xbc1f6fc5,
+ 0xb6ab6b96, 0xabbf448e, 0x1ecafc84, 0xac2cf606, 0x3a7b44e9, 0xb61ff292,
+ 0xad83bae1, 0x76bfba6a, 0x7d66daea, 0xa0d97602, 0xf6051805, 0x2d53b83d,
+ 0x0cd97bdf, 0x952ed768, 0xcccfdaed, 0xf4097cf6, 0x488d73af, 0x866473e7,
+ 0x27d31f91, 0x5bcfbdcb, 0xbb24ef92, 0x426498e1, 0x8786687f, 0x668ec1db,
+ 0x7b56d76e, 0x2a63ff92, 0x6acdedda, 0x8a60d4cc, 0xed94e21d, 0xddb2d390,
+ 0x80cd7a7b, 0x4e9bfc86, 0x8c963d81, 0xbb5b2a79, 0x33b9e112, 0xb3d91673,
+ 0xec99a94e, 0x83db6589, 0x6fb007ed, 0xcf55ea82, 0x7217da85, 0xdc13cb7c,
+ 0xdb87f8ae, 0xc67643ac, 0x0a67f438, 0xc871a9a5, 0x78c82f0f, 0x959bfc55,
+ 0xb7942de3, 0x9e6551b3, 0x1021c4a5, 0xfb9d355e, 0x6edf702b, 0xfc859847,
+ 0x10af558d, 0xe4bffb5c, 0x3c7f4c7e, 0x33f47823, 0x36fedf0e, 0x6a35e74e,
+ 0x48f98dc1, 0x34b64035, 0xaf704e9f, 0x6bb338c1, 0x13e48230, 0x17c8c563,
+ 0x7f70162b, 0x5f3186d5, 0x7e156b28, 0xb7abd108, 0x54527ca8, 0xb3689c80,
+ 0x02bf50a6, 0x3ea3b30d, 0x90b4695b, 0xe3a31b7e, 0x6ae17a76, 0xc3d2364f,
+ 0xb5c7f018, 0x31f8f101, 0xfb010186, 0xc7807eed, 0xc27895ff, 0x1d49951c,
+ 0x191fa015, 0x95fd435b, 0xf0a241f9, 0xdf9ad7f1, 0xfc1bf304, 0x23bc03f3,
+ 0x585fde11, 0x93b7a42d, 0xfff728e6, 0xca97c4b5, 0xbd002e79, 0x63181c61,
+ 0xc7378834, 0x9fc837ce, 0xf5eeb273, 0x8228ae38, 0xf708a3ef, 0x5e30f583,
+ 0xe79651fe, 0xbcbc79b1, 0xf9152e4d, 0x7b6790d5, 0x95f50adf, 0x593ff679,
+ 0x8899ae49, 0xb4ca573e, 0x9c4cf602, 0xbbf9186f, 0xf0891de2, 0x03f005fa,
+ 0x5ac2fbf2, 0x64169cc1, 0xaf3a712f, 0x3cec4de1, 0x454ef4f3, 0xdd6cb838,
+ 0xc6d79819, 0x5a2d7f38, 0x05a737a5, 0xbd2007de, 0x0251ffa3, 0x2fd1f2ff,
+ 0x5372bfe3, 0x57946dc5, 0x8cd62ab5, 0xc83517f7, 0xa6d7290f, 0x87ba50ff,
+ 0xb7a44edf, 0xa0b5a66a, 0x0b69a97e, 0xa1516e7d, 0x084dfe3d, 0x74c9245f,
+ 0xe81768da, 0x5bf1bd7e, 0x95a38f15, 0xbb37140a, 0x4e911a0b, 0xcafd87e9,
+ 0x7e71b9a7, 0xfba0b3cc, 0x391886ae, 0xee862bef, 0x9f227ee1, 0xf7952eff,
+ 0xa3efe40d, 0xc6324f6a, 0xf93a8e71, 0xe602d53d, 0x52dd7ba1, 0x6f654dd6,
+ 0x2f01f578, 0x8d1aee4d, 0x7607f87e, 0x1a91c52d, 0x511936d7, 0xb5b166ce,
+ 0x031fbc26, 0xfbee7936, 0x1bdb2bdc, 0x9468f7a1, 0xc7e7959f, 0x92bccaf3,
+ 0x83a03cf8, 0xf8a38033, 0x57c7cb9c, 0x02207fbd, 0xfefe7ee1, 0xca7ef3fd,
+ 0xb9020fd0, 0xd654f305, 0xbdd064b6, 0x67758b8c, 0xabf1fbe4, 0x1fc153e0,
+ 0xf08399b4, 0x0eb9670a, 0x0d9f33e0, 0xd36e63e4, 0xc0a9f0b5, 0xf03d4939,
+ 0xe8250463, 0xa1439231, 0x5ee05678, 0x3cd56acd, 0xeefb56fe, 0xb3ffe802,
+ 0xed19a2b5, 0x7ef0cbca, 0xf578fc0d, 0x28d791fc, 0x257b3f90, 0x5a78297c,
+ 0xff54bcc8, 0xfb8f8a30, 0xf144a170, 0x7c69ffc3, 0x4bd9e435, 0xb7c2aef2,
+ 0x257a7ca1, 0x2ab45cbe, 0xf8437f84, 0x2d2f8874, 0x7f002ff0, 0xc41155f6,
+ 0x1d7e0a8f, 0x5193f066, 0x2d1875ff, 0x3e39766e, 0xfdc5dfd1, 0xec0ab654,
+ 0xf087e149, 0xe3fc8fab, 0xad017c50, 0x541f50d8, 0xa9f305e7, 0xc92bc782,
+ 0x7dee452d, 0x4d47bcc4, 0x7067dd02, 0x9685fe3e, 0xfb94e9f2, 0xe2dee50c,
+ 0x6fae3cd1, 0xc08fcb42, 0xa27bc16e, 0x233d194d, 0xd5ebded1, 0x7bf0f328,
+ 0x74d68fd7, 0xcd7cc68f, 0xb2f1a68f, 0x4cf3c357, 0x8c2dba94, 0x4a3f03c7,
+ 0x6e10bad0, 0xa6e3091f, 0x91f01da3, 0x783bcbf0, 0xc6634e3d, 0xe9b882fa,
+ 0xaaf7a826, 0x83e1f895, 0x5376fcb2, 0x0982d1f9, 0x604fd405, 0x661e1047,
+ 0x3ad09581, 0x0c5d1082, 0xe7e8f9fb, 0x5ef07363, 0x03ff3940, 0xf48e3c79,
+ 0x431cf91b, 0x095ff6f1, 0x045f6f14, 0xf784c3aa, 0x289fd302, 0x93f6814e,
+ 0xa6cd4ebf, 0xc115cafb, 0x4dfea3eb, 0x56e538a6, 0x4b96e79a, 0x99c5ea03,
+ 0xe90d7dfe, 0xbc8b82cd, 0xa0d8c97d, 0xf45b667c, 0xbb27ee38, 0x8f512353,
+ 0xf06d7a29, 0x60437ed8, 0x1cacf51c, 0x8faa1e77, 0x5029247b, 0xf7b1be2f,
+ 0xa79c74e1, 0xb2cae35c, 0xf98f3018, 0x1fb424a9, 0x943ef7ca, 0xdeed764e,
+ 0x9fe8e98d, 0x9c3d3794, 0xb87aa36e, 0x1523fc9d, 0x7df9f73f, 0x0a6d7693,
+ 0x9d6fa3b0, 0x52fbedc0, 0x68851bdd, 0xf1bacedf, 0xb71875f3, 0x816bfb1f,
+ 0x590b70e2, 0xb7d43af7, 0xaf9c1965, 0xe48e8358, 0xf747cc3f, 0xddc67ba4,
+ 0xfee51bbe, 0xabbf8cf1, 0xcdfea097, 0x657cd153, 0x0e39bdcc, 0x041b6fe3,
+ 0xfbf9bf8a, 0xd77ba68f, 0x4d056bc5, 0x51ea0c7c, 0xc7fd779e, 0xe38228bc,
+ 0xbbb21b3d, 0x356cbdb0, 0x75a59f6f, 0x3ce0f6b7, 0xcf28684f, 0x4a65140a,
+ 0xf63dc049, 0x3df8f31f, 0x72cda2dd, 0xcebcb1be, 0x8db16dd8, 0xa3fce781,
+ 0xfe567f8c, 0x3b83c901, 0xb6dcbc65, 0xf123bdfa, 0xdaa46f30, 0x2b9467fe,
+ 0x3a7e3eef, 0x4159e50d, 0xa44cd9f4, 0xfb1ab1f3, 0xee781593, 0x2bc52d26,
+ 0x528959ad, 0xb9cff41c, 0x5863da7f, 0xf8bd5a2e, 0xfb8c0ac9, 0x1f91d76e,
+ 0x856feca6, 0x5fd11660, 0xd3f8dc3d, 0x676e107b, 0xa479e71e, 0x8faf1a2b,
+ 0xe2fe5abb, 0x1f3c75b3, 0x1d3af9fc, 0x99d42f95, 0xb88e1998, 0xea9e2eaf,
+ 0x5333afbf, 0xfa73e6c9, 0xaea6f252, 0xa5ee5f34, 0xb65bca30, 0x1e51d06e,
+ 0xf6d6ae7d, 0x6bc01e55, 0xa6ce0dec, 0xc6b9f28d, 0x576cf8c2, 0x83840cf2,
+ 0x2ef2e375, 0xe54f6134, 0xedeaff71, 0x64490d9e, 0xf53eaf87, 0xcf3c054c,
+ 0x0ef92fcc, 0x5e76ebc7, 0xe1c178a4, 0x10ca87f6, 0x5a4de5de, 0xdcf93e7e,
+ 0x8f4f1e67, 0xbce3127b, 0x7fc9a96f, 0xea79d9af, 0xde508d99, 0x26b979bb,
+ 0xe87fde90, 0xf795bf79, 0xbabe2d73, 0x75fe1c12, 0x89387abe, 0xf809a7f8,
+ 0xe7dff32a, 0x6bd59aab, 0xf3737e08, 0xc3e6c64b, 0x5da8cffe, 0x674fc849,
+ 0x744cddc6, 0x0814eaee, 0x571c8afe, 0xf3e6a7c6, 0xd12ae8fb, 0x48ec99b3,
+ 0x057f8e59, 0xf7c2239e, 0xd2cff68d, 0xaafe8ed1, 0xcf55c16d, 0x3d0eb07d,
+ 0xe99b8c22, 0x9e7d0ca8, 0x62a7b1af, 0xc8be715e, 0xe7d0e7ed, 0x712be7b7,
+ 0xc5b71e78, 0xa790109f, 0x458d84e2, 0x13fea346, 0x972061bc, 0x9eb76d9d,
+ 0x06ffa155, 0xc1c7e17e, 0x38fb2876, 0x695faf40, 0xab2ad7bf, 0x5f951e71,
+ 0x50f84eee, 0x3d00de64, 0xc617c93e, 0x0eeb01bc, 0xa6d02bf9, 0x049efba1,
+ 0x37880b92, 0x6bea87cc, 0xf584d71f, 0xc78e1ab3, 0x97e083be, 0x930cb8f1,
+ 0x3ce7fdf2, 0x0b3e7edb, 0x79e86ce5, 0x4f395fab, 0x7b68e1f4, 0xe740a2e8,
+ 0x9556799f, 0xbff3ed75, 0x167cf7b1, 0xdaacefe2, 0x57fe8f97, 0x8597c69f,
+ 0x957ea878, 0x157ff3cb, 0xc57b4a0e, 0x138f0d06, 0x23f2260a, 0x140ba50b,
+ 0xc63be807, 0xedd500e3, 0x0e9e48bb, 0x4c78f076, 0x145dd88d, 0xda8bf187,
+ 0xcf285d53, 0x5fb9e306, 0x28dbf306, 0xd65521cf, 0xa481aa83, 0x1ed72039,
+ 0xee07a219, 0xfe419e0f, 0x1e3ce0d5, 0x6561e507, 0x2bb43385, 0x433f21ce,
+ 0xe4aad97b, 0x67e748f5, 0x507323dc, 0xf59dbe3e, 0xdf8a6a8f, 0x926e1ebd,
+ 0x30958ec8, 0x4e0878c7, 0x4b70e743, 0x2987d13c, 0xb3387176, 0xd1abf405,
+ 0xbf24ef98, 0x9fbf38fa, 0xf381b9ab, 0xf3857b13, 0x1bed7393, 0xf980f89a,
+ 0x93f3257e, 0x7ace4f62, 0x97c41ffd, 0x9edae70f, 0x470cbe40, 0xc5f38859,
+ 0xb51e5247, 0x72871ef2, 0x90e8691f, 0x8962f8fd, 0x49b4d79e, 0x58e5ef0c,
+ 0x0af291bc, 0xca16d98a, 0x3cc59cb7, 0x8f5e7953, 0xf029d1ef, 0x52ebf67c,
+ 0x81a1e62e, 0xdbf74d3d, 0x34f66145, 0x15ead3cc, 0x1eae1905, 0x7d009ceb,
+ 0xf73e7ef6, 0x024aa757, 0x8481b1e9, 0x6653b270, 0xe29677ce, 0x5a7e957e,
+ 0x9833eb91, 0xe62cec87, 0x7bc2c81e, 0xc81de655, 0xa556fbc2, 0xc3d7bcdf,
+ 0x322f496b, 0xc05e758f, 0x79f3a73a, 0xbc0bf3bc, 0x5279071f, 0x16c3df23,
+ 0x436edf4a, 0x27456b7f, 0x15ec7fbf, 0x3cc03f93, 0x19c01733, 0xf01e7af1,
+ 0x63fd436a, 0xf21b3667, 0x6e91f8cf, 0x7d9a9fe4, 0xbd7cc302, 0x136d76ea,
+ 0xd5aa85c6, 0xe7a458be, 0x6bef6d8d, 0xf06b9e90, 0x8e3c765e, 0xdcbc7267,
+ 0x35bf7944, 0xf5efc626, 0x00ffaeda, 0x63ce76e3, 0x553a8b5c, 0x003c51ef,
+ 0x57ae36e5, 0xfe42dad5, 0xc97983bf, 0x073477ff, 0x3c60cdd3, 0xf287e78f,
+ 0x737ce9c9, 0xdccc7f10, 0x1e63f9ce, 0x681b73e6, 0x675fc538, 0x5d91c7c6,
+ 0xf1c71fe2, 0xafce9360, 0x3fa63b43, 0xfc7ca045, 0x5ad730fe, 0xe95c8fb4,
+ 0x7fe9aedc, 0xbd2b05ed, 0x5b73a3f7, 0x3cf98c7f, 0x733bddb2, 0x149556c3,
+ 0x1d999fb0, 0x1fd8de3c, 0x120fcac6, 0x21d7edde, 0x25b97c3e, 0xbe31f267,
+ 0x777819a3, 0x4483c60a, 0x3d0d1f1e, 0x6b8e5d87, 0xfdfc671c, 0xb3df6528,
+ 0x3cb91313, 0xa3a26e63, 0x5bbf392e, 0xc651d7c9, 0x504132df, 0x9fb8d1ee,
+ 0xfaae5824, 0xd7de1a5e, 0xde2b9e60, 0x3bf960d7, 0xef161f39, 0xa2feb06b,
+ 0xf78b0f9c, 0xf78ed835, 0x956f5835, 0xbef161f3, 0x5f78eb06, 0x722be583,
+ 0xdc71ec3e, 0x6df1e52a, 0xa2e90a7c, 0x946d790b, 0x1d1bdebf, 0xdc151f52,
+ 0x085a37bf, 0xa8128fae, 0xc6c269bf, 0x78ff30a7, 0xc52f9293, 0xc3b446cc,
+ 0xfbf9c22a, 0x7b06a91a, 0xf3f404ec, 0x45ed778b, 0x9bf81e7f, 0x882b9fde,
+ 0xef4a505e, 0x1968c497, 0x27dba3ca, 0x804f47d8, 0xcd8ec7f1, 0x724adb48,
+ 0xecf74f52, 0x31bb3fbd, 0x6f7ae292, 0x25824c49, 0xaee465a7, 0x9a7d42b5,
+ 0x85fa2041, 0x512a6ef9, 0x67984cfc, 0xab62c746, 0x1307cb8a, 0x9285cbda,
+ 0xb3ae0963, 0x8b9f4122, 0xd588f872, 0x51fb819e, 0x6a345de0, 0x45da1a59,
+ 0x07f36a5d, 0xbd759f18, 0x57e866a3, 0xa53c7129, 0x69d693df, 0x99bfb8f9,
+ 0x736ba919, 0x36607e70, 0x0d367794, 0xd9fdc66b, 0x9ea170c4, 0x855997e4,
+ 0x027f20f2, 0x66e99ba7, 0x357b1f6e, 0xfa345566, 0x62d361f5, 0x4bb75ef0,
+ 0x1931f3c6, 0x3c65c7cf, 0x81573de3, 0x6173df8a, 0x585cf789, 0x2da3e686,
+ 0x4db12fcf, 0x240f7820, 0xcdb3e605, 0x0097df92, 0xd4f7a10a, 0xf31c729c,
+ 0x34ee594b, 0xcadc95e6, 0x9e6879c7, 0x778e392a, 0x6f7c1d5e, 0x8ff38ca8,
+ 0xbdce5467, 0x166bcb89, 0xbf79e1a9, 0xe61731d7, 0x397dcf15, 0x7d50e281,
+ 0x06a5d16e, 0x5e05cfbc, 0x5ec67947, 0x8b2efee6, 0x77337ce7, 0xabf51c7f,
+ 0xcea9e397, 0x7c74eee8, 0xe64fa3af, 0xf07ea52f, 0xe4979e3b, 0x81ba81cc,
+ 0xf3a123de, 0xa776e739, 0x4fbd4147, 0x5f488bd0, 0xbcfe26ce, 0x673fe647,
+ 0x7c9f3c8a, 0x24f3a61e, 0x3bfa3e21, 0xf7c24e5f, 0xbc193710, 0xf7fcb94b,
+ 0x66dc93a6, 0x6fcc74de, 0x4e782f3a, 0xadf1be62, 0x98a5296d, 0xed5e7f6f,
+ 0xb3eb0679, 0x5d78d2db, 0x0a693968, 0x93d23e7c, 0xb7c8f984, 0x6296a5b6,
+ 0x91f9f23e, 0x5944cf2d, 0x97eaea02, 0xcd73e24e, 0x98a56983, 0xeb5b3c9f,
+ 0x7487563e, 0x5f4e7bf3, 0x4e077dfa, 0xdaaa7c23, 0x7d3efdb9, 0x2f0b81df,
+ 0x603e7ea1, 0x7582bca4, 0xdf099213, 0x6ecfedf5, 0x6beb7a46, 0x6c3f1351,
+ 0x99ff7e6a, 0x2d3f50df, 0x6b665985, 0xc90c563d, 0xba1db494, 0x3b35f71b,
+ 0xd625f3dc, 0x89bc4f17, 0x047b31f6, 0x13a5ebe7, 0x4f914a73, 0xfbec0efb,
+ 0xd9b3ea05, 0xe2d86091, 0x13d05e7e, 0x8ff72a7e, 0x40b8c02b, 0x0cbbb19f,
+ 0x9dfeafe7, 0xec1fe796, 0x718e9b8f, 0xc09cff82, 0x6e2a31f3, 0xfa8492d8,
+ 0xf9e57c56, 0xf8c1bfbd, 0x74f4efe6, 0xcd1353df, 0xa94abded, 0xe1397f31,
+ 0xcc5ed76f, 0x5e7be95b, 0x15aff74f, 0xe2b39318, 0x2963ac7b, 0x3feaff3e,
+ 0x78865eff, 0xee769428, 0x772ff6c5, 0x438445eb, 0x7916c68f, 0x8f61f233,
+ 0x0acefc9a, 0x3bd15eb9, 0xdc27ef82, 0x8bf84457, 0xfa8492d9, 0xafc472b6,
+ 0xcf7dc0ee, 0x833cb696, 0x567b0f7e, 0x670e774b, 0xc1b8079f, 0xd47bb3b8,
+ 0xfb034998, 0x5e90aa30, 0xca5b0bce, 0xf7f9c49e, 0xf5e77ef0, 0xae9e085b,
+ 0x5c33d73d, 0xd431fa0f, 0xad85e7c7, 0xf767ed41, 0x7e859b3c, 0xcddfb9e9,
+ 0xa154ff26, 0x2a5f8573, 0xf4836b77, 0x58824922, 0x3fca5b8c, 0x02198b93,
+ 0x0ee759e2, 0x927be8ee, 0x6b9fc7f9, 0x00357b56, 0x5b2d0aa3, 0x0acdf98b,
+ 0xde26543f, 0xabe78c5a, 0xd1d31b14, 0xf5c8a97e, 0x9c5f2195, 0x3c5d33d5,
+ 0xd65b7bf4, 0x6bad955b, 0x7c1da0e6, 0x45fcfda5, 0xc95f4796, 0x9b55f87c,
+ 0xdf781dde, 0xb5fe5a18, 0xa84f998e, 0xb585f5fc, 0x95e5b25a, 0x78d6def9,
+ 0x55afe81c, 0x71f97347, 0x8337fa12, 0xac93fb1c, 0x0aad16ef, 0x04eeffee,
+ 0xad594f9e, 0xfea3a5f1, 0x7b7fe653, 0x87db8982, 0xca3a5f2a, 0xb371d0ab,
+ 0xbcde5925, 0xa9bc9020, 0xd14e156c, 0xd20824fb, 0x2b3c3f58, 0xe6372e75,
+ 0x87870d13, 0x0f197cf8, 0x70f1e612, 0xd66caabe, 0x4f30f4db, 0x022f9855,
+ 0xd18725ed, 0x50768117, 0x6b122bdf, 0xa317d192, 0x5fe29fcc, 0x5653894f,
+ 0xfd36d478, 0x71c1eb70, 0x865e4fd0, 0x5628037f, 0x537ce44f, 0xeb4e16de,
+ 0x1f2f9331, 0x677cb6e9, 0xa73c38f0, 0xfb1f8029, 0x06c576da, 0xf70cebfa,
+ 0xa751f74d, 0xfffa6f88, 0x07bd31f9, 0xb5b2295e, 0x4e794f78, 0x4083efe0,
+ 0x3907de9d, 0x5677df27, 0x43086d7e, 0x95f739fa, 0x4fb8f883, 0x7b9c91f0,
+ 0x7246cdb1, 0x23ed4fac, 0x626bb739, 0xf947af11, 0xbd6e50ca, 0x24a7f138,
+ 0x7c12fa3f, 0xd29ef865, 0x2f8ea566, 0xd01d81cc, 0xe490b6d1, 0xe7896cc9,
+ 0x6a5db051, 0x71138f13, 0xe1932f78, 0xde86d8c4, 0xd443f23a, 0x3a97b466,
+ 0x42f72a27, 0x25f9ff1a, 0x31f53f3f, 0xe456bef3, 0xc50372cf, 0x6abec07d,
+ 0xc0ed097e, 0x8c16b105, 0x4dc287a7, 0x898c5fb9, 0xe22966fe, 0x7da31de9,
+ 0xbc3cc4ec, 0x9f91f4cf, 0xf64ed401, 0x5a6bf57c, 0xd5fb37f2, 0x7e517b03,
+ 0x71f68db9, 0x0e9e0113, 0x547af74d, 0xbed41771, 0x67ed342e, 0x1c91bd21,
+ 0x97d6f4e1, 0x07bf8bb9, 0x4e4fdf22, 0xfa00f192, 0x7d22358c, 0x87cf1c08,
+ 0x409ff6db, 0x9dd7d379, 0x943a724a, 0x3db6ce9f, 0xe3728116, 0xaeefd043,
+ 0x87c07880, 0x7ca59f8b, 0x0798f980, 0x6b3de502, 0xf837cf83, 0x2fc98fed,
+ 0xda039b64, 0x821b1e91, 0x4170a1eb, 0xf106f4ba, 0x7df68b81, 0xc01bf23f,
+ 0x777a6aa7, 0xa861c235, 0x52ea173e, 0x4850fd40, 0x2b3fa43d, 0xfdc3f6e1,
+ 0xebcd1813, 0x25eded18, 0xcf1f7e3f, 0xbd07adef, 0xe103f546, 0xee2d3f74,
+ 0xc315bd03, 0x8bea16f5, 0x8a6e88aa, 0xd01df55f, 0x83cabdd2, 0xe1259fed,
+ 0x291e81f9, 0xfed5534e, 0xf7fa2c72, 0x699826eb, 0xb18fd07e, 0xa0731794,
+ 0x11fd163d, 0x7a21dda5, 0x0cf7e5d2, 0x287e50b2, 0x9bc94eed, 0x42e5794e,
+ 0x5f3e1677, 0x8719cb27, 0xeb097508, 0x10e1ce8c, 0x76b3df38, 0x287ce489,
+ 0xf4c956de, 0x8b21f20a, 0xe15e39f2, 0x1e4503f1, 0xe572c854, 0x7267b610,
+ 0xf72937fe, 0x84cf7852, 0x9c8c3f7c, 0x23815af8, 0xcef8a5ab, 0xbccd13fd,
+ 0x79a78f2e, 0xe789fc79, 0x3e7abded, 0xc713252b, 0x45f79599, 0xd528f2fd,
+ 0x0e505f2f, 0x781c93c4, 0xe70b1d50, 0xb0467caa, 0x8a90c3d4, 0xd04535d2,
+ 0x2d532d9d, 0x1ab8a22f, 0x2e1ae7e6, 0x1d2857df, 0xf8e44e45, 0x1fb914ad,
+ 0xa057b95e, 0x6a73a5fb, 0xf2076f7e, 0x580fde86, 0x08a6b056, 0x18beeff9,
+ 0x5fd026a7, 0x4bfcd6be, 0xcbeb821b, 0xc514d76a, 0x95e7c30d, 0x8d76b6ab,
+ 0x57cf9764, 0x8a2c6f61, 0xaede5f35, 0x5e9cfbec, 0xf574e7d9, 0xcc7840c8,
+ 0x1234535f, 0x7fba65ca, 0xdcfc1e17, 0x5eb5dae7, 0x5d2d57ca, 0xb7c4f743,
+ 0x8a0daa5c, 0xbe6b5eb3, 0x7ba6e60a, 0x3fed2b90, 0xde0874b4, 0x312b8c5e,
+ 0xc43dafe0, 0x0137c067, 0xf4cbc5eb, 0x289f143a, 0xfd063c5f, 0x3c5f6653,
+ 0x113e3026, 0x339be25a, 0xb88ae522, 0x2c3e04a8, 0x0f030cb3, 0x89d1ffa5,
+ 0x3f1ace3c, 0xa8f1d391, 0x5e3b55d9, 0xe9d71462, 0xa57bf941, 0x22fe4cf7,
+ 0xbf07efef, 0x9c233267, 0x9bd4ebf7, 0xdfd3fe30, 0x87c50df9, 0xe619d7fb,
+ 0x03077bf3, 0x5de7804b, 0x029be3f1, 0x26abc0e3, 0xdc243b71, 0x9a9dedca,
+ 0xe3d5f50c, 0xa1c6994b, 0x1bd912f8, 0xdf74e199, 0x05f6d7d2, 0x8efeb7e9,
+ 0x8bde133c, 0x0dbb75f4, 0xff356fc8, 0xa8b17ffc, 0x3e3afb87, 0xbeb4bca5,
+ 0x7ca33f6f, 0xde728db5, 0x3936a1e0, 0x6cdbabdf, 0xe2fef6c4, 0xbf6117bf,
+ 0x8fe9724d, 0x98f8f02f, 0x83f12a52, 0x3bf9ff00, 0x4c7b53d4, 0x54c51f1b,
+ 0x2db0ca99, 0x7fc0bf24, 0xe1bd468e, 0xe3982b8f, 0x04c38b86, 0x54d215c6,
+ 0x2580ae3c, 0xd2d215c6, 0xeb015c78, 0x12c05718, 0x8ed80ae3, 0x63ac0571,
+ 0x18eb015c, 0xc63ac057, 0xb8c4b015, 0x297fb602, 0x0fd1e7bf, 0x3dc78b82,
+ 0x57f7240d, 0xc0337e62, 0xbf27656f, 0x47b95abf, 0x7c617ba2, 0xdff503cf,
+ 0xad3b7965, 0x678ede72, 0xd607dd2b, 0x882c901c, 0xc41f7c22, 0x3bf98e95,
+ 0x1e314703, 0x5822d354, 0x7db198d6, 0x6363ed3e, 0xa507de47, 0x6d47bed8,
+ 0x4f44cd11, 0x828d9f1c, 0xd57c8f5b, 0x57e287b1, 0x949d7105, 0x2cd35fef,
+ 0xcebb8c30, 0xd93f72d3, 0x0e6b4129, 0x1d92abdd, 0x9376d4ed, 0x9cf552ff,
+ 0xef7c0e60, 0x45e266bb, 0x7dca1392, 0x88fe52f5, 0xf37a3d39, 0x6b3d2092,
+ 0xf85779e3, 0x29c7ec27, 0x1d9377e7, 0x2d176012, 0x6c6c7bc5, 0xf7a5be97,
+ 0xe0e09c4d, 0x9dae108e, 0xd1d95577, 0xb5f31eb2, 0x55fe687e, 0xdef924e1,
+ 0x47bf9b3a, 0x92f8fc52, 0xbd60077d, 0xb25a2dc1, 0x609f6e53, 0x1e526dbf,
+ 0x28d819e6, 0x53b472ee, 0x27d67e4f, 0x8a0faf5b, 0xd74a14bb, 0x8563dc51,
+ 0x7dfd205a, 0x3b9f6ac4, 0x4672e809, 0x6f14bdf1, 0x246f1199, 0xf0e8563e,
+ 0x4fc96b49, 0xe315de70, 0x0a9877f9, 0x34e7ecb5, 0xa5cf9c9f, 0x5eb0a9e0,
+ 0x2cf7e370, 0xbd0b3316, 0xc008b03f, 0xe5517187, 0x188b1ffb, 0xe850afcf,
+ 0x8156c56a, 0xbcbe8ae8, 0x84bdf010, 0x103df845, 0x6af77fd0, 0x289bfdb9,
+ 0xc4f27bf2, 0xe28f3c4d, 0xfca7663e, 0x7d486591, 0xd7d7e912, 0x0f6ed07c,
+ 0xdb892ebf, 0x9c38e6f7, 0x3571f17f, 0xc61707e5, 0x276e9edd, 0xf9405f3d,
+ 0x6ef78213, 0xaf1bfbe9, 0xf3833f26, 0xb9aa8e27, 0x927801dc, 0xf485d59f,
+ 0x3b1ef14a, 0xcaebc795, 0xbf229ca9, 0x5efa161f, 0xcbe77f43, 0xb0be382d,
+ 0xf84160c6, 0xc03df15f, 0xffbfabb0, 0xebf394e6, 0x5c9ec512, 0x6be3c233,
+ 0x51e10583, 0xef49d718, 0xf3caa589, 0xb25b9c3f, 0x8b69f109, 0x1f5c2e60,
+ 0x00b669ef, 0x40f08b7c, 0x3dd1c602, 0x66cf7c36, 0x513053a0, 0x7265f53e,
+ 0xcc3aeb74, 0x1349a953, 0x2daf184c, 0x1852db0a, 0xa517f30b, 0x7677d324,
+ 0x1c78da6a, 0x4e4a0fb6, 0x92dc5307, 0x62aac7c0, 0xf1cf7e31, 0x3fb5cbe8,
+ 0xdfcf293d, 0xb3e65b3e, 0x782f8efe, 0xe3b5f11e, 0xfbe9bbb4, 0xef4f4c1c,
+ 0xf60fd3af, 0xd1c6fb35, 0xe855af14, 0xae39b068, 0x45a8e909, 0xa5a513d6,
+ 0x8ed1a9ef, 0x37b3cc68, 0x96ca1c23, 0x4b175c5c, 0x4e3e1ce7, 0x87dfe4a6,
+ 0xe502c9c6, 0xde46ffed, 0x5aba89fd, 0x5baddf2a, 0x9d776545, 0xe8079e8b,
+ 0xbf08238b, 0x7d6f101f, 0xf130d27b, 0x4733a656, 0xbe05be92, 0x90edf1e7,
+ 0xbbf02af8, 0x33efc018, 0xd9eea23a, 0x8348f680, 0xcdf782c6, 0xd2bcff98,
+ 0xfde1f240, 0x59c6c349, 0x2819f815, 0xf4c83b2e, 0xe9878839, 0x112aa919,
+ 0x926dff9e, 0x44e71410, 0x2273c1be, 0x7c8960df, 0xf9f952a3, 0xa30d69e6,
+ 0x7da194ef, 0x40fb22e0, 0xbf5df84f, 0xd40ae406, 0x20a665ef, 0x442172b9,
+ 0xf32380ae, 0xac5f7a33, 0x0936cb43, 0xe9cffcfe, 0x19ca5c50, 0xb878ce46,
+ 0xe61d199c, 0xb3be9e79, 0xf9461d50, 0x44efc0c5, 0xf2374767, 0xac25bdbc,
+ 0x461dd684, 0x3e7bd0de, 0x38188ef7, 0xbff414f9, 0xd90361f7, 0x9613eb39,
+ 0xe477ffe6, 0x71279fcd, 0xdf813c78, 0xed5d5073, 0x059b0e7b, 0xb15d8fbc,
+ 0xbe236590, 0xc439ef95, 0x7bf218c1, 0x39eff5ff, 0x123c988c, 0x0ae0e7bf,
+ 0xdc439efa, 0x30e7be15, 0x6171b26a, 0x461cf7e0, 0x30b11e4d, 0xc60e7bf8,
+ 0xb29df885, 0x39efc1ff, 0xbbce4fa4, 0x370e7bfc, 0xa0ff364e, 0x3d8039ef,
+ 0x4fe3899b, 0x63c6d8e4, 0x3b9f2899, 0xe3e5fdf4, 0x97643df2, 0xb2c52f68,
+ 0xa2a5c228, 0xc56dd176, 0x73d16df2, 0x5f03b63f, 0x1578444c, 0x037d963d,
+ 0x5125977e, 0xf2bca1eb, 0x49b6ad27, 0xb96bff38, 0x3cf8c9b6, 0x2f5fde34,
+ 0x73f60f9f, 0xcd0bf60b, 0xe2e8531f, 0x0e5cc9ae, 0xa9cb93cd, 0xc7bfc3f5,
+ 0xbf326f3f, 0xbed6be4f, 0xe077bf61, 0xd9feca7a, 0xdc56c596, 0x4ef7ec0f,
+ 0xb7ec27dc, 0x88664b04, 0xf80f7a0e, 0xc9757a72, 0x2e7462fb, 0x3fb38f90,
+ 0x9528f6e1, 0x14772ae9, 0x1ea30dda, 0x7ee14770, 0xe80e3547, 0xdf907df1,
+ 0x68f406ba, 0xf576fc3f, 0x7fdb1e80, 0xdaf9e36b, 0x9f6ff3a1, 0xf491fdcc,
+ 0x7e3403a9, 0x4dddfc0c, 0x1440c1fe, 0xe5e96dda, 0x14ae3447, 0xf66d4f7a,
+ 0x93764127, 0x8c7bf899, 0x01e636dc, 0x8c3d2191, 0x1e78c1d9, 0xe90c4163,
+ 0xef1d4ab9, 0xfdc0f95a, 0x38d1d222, 0x803bec37, 0xaedfaefe, 0xaf7e0c1a,
+ 0xaae34bd7, 0x5ec025e4, 0x64ee7a0b, 0x9474bf3c, 0x5ed08f2c, 0x39d9efc4,
+ 0x77d08fcb, 0x0b8ec0a6, 0x79be8f99, 0x594f9430, 0xe6bfb3ad, 0x62be5333,
+ 0x77a5bf50, 0xfa3d66ff, 0x5ba5e5b5, 0x2f17e435, 0xa58f5969, 0x269ef1c3,
+ 0x197d918e, 0xcbec1fd4, 0xfb65faa0, 0xf547d90c, 0xc7d717fd, 0xd02eb30d,
+ 0x13a456c1, 0xaa8e0e85, 0x4fd0e33d, 0xb30cea3d, 0x3c1df7f0, 0x269a5df4,
+ 0x5df4bdf9, 0xcadd39ff, 0x5d3965f3, 0x3f1df8c0, 0xa9ea8e8c, 0xaf1df2bf,
+ 0x1c8a956b, 0x8dcefa1c, 0x5e28b986, 0x7248cb39, 0xfff646ae, 0xc89897aa,
+ 0xbaf8511e, 0xb539e55a, 0x18c5fb1e, 0x8a9bfe79, 0x7aabf7d1, 0xcf9451c4,
+ 0xcfac3f4d, 0xacfba54a, 0x178f7ad8, 0x5db81de7, 0x15b9efa0, 0x5ab97384,
+ 0x9e389628, 0x4447e785, 0xa7815dfe, 0x98487e51, 0x37bfc147, 0xbf972530,
+ 0xf8cf103f, 0xca98db77, 0x369df21c, 0xed7a1e39, 0xeff1b4ef, 0xf7e7cd92,
+ 0x25510d72, 0xf9f1cba5, 0xf9e81b82, 0x1f52efc1, 0x2afee2b1, 0x71b4ef94,
+ 0x4e61bf7b, 0x557f3d06, 0x3d41af30, 0x5d807ae1, 0x7a6d3be9, 0xef80fbe4,
+ 0xf887bdb3, 0xd9f7d6ba, 0x1c0fef94, 0x23c3705d, 0xbd1c397b, 0x3355ef78,
+ 0xafe418cb, 0x3c3117ff, 0x56c0d29e, 0x000056c0
};
static const u32 tsem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x33b3af8a, 0x21716830,
- 0x9f0143f8, 0x38606664, 0x8167c40d, 0x81859798, 0x818997c1, 0x78898fc1,
- 0x10c533fd, 0x0611416c, 0x5e203b06, 0xf0c0c42e, 0xce21044e, 0x10c0ce28,
- 0x20c0ca2d, 0xafe10a2b, 0x6266d204, 0x40ff71d4, 0x4c194663, 0x089207b1,
- 0x79161336, 0x268ccc64, 0xca8520ef, 0x7fa02167, 0x2517f1a0, 0x22acbe54,
- 0x8a846e84, 0x9793457f, 0x432bca83, 0x094df5fd, 0x502ab9bb, 0x1aa00079,
- 0x03605f82, 0x00000360
+ 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x3370278a, 0x45e39c30,
+ 0x8381e9f0, 0x5fd32918, 0x50c0cec6, 0x4055c401, 0x3f880bbc, 0x7c3032b1,
+ 0xff5e2566, 0xdb042935, 0x21818248, 0x88d7881e, 0x49a83031, 0xa41dc422,
+ 0x03261819, 0xb150a1f9, 0x5f3a4047, 0x0f77328a, 0x80a69c16, 0x872ae629,
+ 0x9163a760, 0x6819c647, 0x50e54bf2, 0xf40499f9, 0xa2be340f, 0xa2ffca8e,
+ 0xa013a10a, 0xe4d157e2, 0x3be542bf, 0xa6bafea0, 0x4edcdd8e, 0xc35dfd32,
+ 0xfc01a102, 0x9847b099, 0x009847b0
};
static const u32 tsem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780d, 0x733ee8b5, 0x49999cce,
- 0x21264cce, 0x61021309, 0x40a02092, 0x200c7e18, 0xf7f09d78, 0x803aa568,
- 0x07515a56, 0x43f21081, 0xbd1f5202, 0x24266bed, 0x1bd568c1, 0xab45a8fa,
- 0x68a90076, 0x62348ed1, 0xa80740a8, 0x0db6a85c, 0xc7f42ad6, 0xc405ad1b,
- 0x96aa4490, 0x6bb94abe, 0xe64fbdad, 0x4019939c, 0x6f5fb7bd, 0x6fd697bf,
- 0x67d9cfb3, 0xdfd7b5ef, 0xb5ed6b5e, 0x897628f7, 0xec650ee5, 0xc75dfe02,
- 0x319902d8, 0xf4a27576, 0x0d0ebbc1, 0x07f8adfe, 0xccdd2832, 0x2862b12f,
- 0x2f6e2cfd, 0xfc707281, 0xd65e9618, 0xf37e18c9, 0x959905f1, 0x3271e632,
- 0xb09417f1, 0xdaf2f5ee, 0x6d87b2b7, 0xd5b28428, 0x6cc653f7, 0x67aaed8c,
- 0x44f66181, 0xff57873b, 0x91c17e2e, 0xfa4870cb, 0x877560cb, 0xbb87c187,
- 0xb6e2e7a4, 0x8ef58c89, 0x7e2d8161, 0x5dde0718, 0xcffd059b, 0x316dec61,
- 0x704605e6, 0x8a50b85c, 0x4b8231df, 0xe73af8fb, 0x0ee76842, 0x00c55fad,
- 0x7334cf5e, 0xb9a26d7b, 0xf50d18ee, 0xa5fa8991, 0x6ca603da, 0x881de00c,
- 0xed5c03f0, 0xd79a4ef5, 0x81bdeb8f, 0xb6305761, 0xf547dea7, 0x2a7ef57d,
- 0xe923f5e3, 0x00fa81f9, 0xb05873d5, 0xeac7f090, 0x66ca2c36, 0x8536f1ac,
- 0x7412c7dd, 0x8c3d66f9, 0xfea24577, 0x222cd1a7, 0xa4fee4c3, 0x00423bb0,
- 0x132bc36b, 0xbca13a32, 0x7f41db1f, 0x28018d0f, 0x3fda26c6, 0xdce5f6bc,
- 0xcb181399, 0xdc91eafb, 0xbde00399, 0x46c616c4, 0xd2ad78e3, 0x9df031bc,
- 0xdbd1fbca, 0xeb6325eb, 0xed9a0f88, 0x65afdfc9, 0xf2cf0212, 0x7e60ac0e,
- 0x0f6bf437, 0x07013be7, 0x04c644b7, 0xb8c3065b, 0x186bec48, 0x111b32fb,
- 0x370e0089, 0x8c799761, 0xf342d0ed, 0x5f1cbbf0, 0x91230a48, 0x299c40c3,
- 0x2cab658c, 0x470a4b1c, 0x2b71c103, 0x4b0733fe, 0x0f4bd53f, 0x7ef571f2,
- 0xe711b2f4, 0xcee4e507, 0xde2c5b30, 0x77fbe197, 0xe862d242, 0xe7c5d9bf,
- 0x736302f3, 0x1249bc70, 0x12b9610b, 0x2dfa1299, 0x312732c7, 0xe5c60aee,
- 0x6173bae1, 0x547e8416, 0xc785985f, 0xfc837ef0, 0x6c8ca6fb, 0x1b7f9b9a,
- 0xda9443f1, 0x474ddb1b, 0x88b6fcb8, 0xedc7033d, 0x23ed883d, 0xf6c3163e,
- 0x39b6682f, 0x3b44b45b, 0x6e499e1d, 0x968b685b, 0x16c82fe8, 0xe5d3fa9b,
- 0xbe72764d, 0x81def9d3, 0xda9c809f, 0xc228fbe1, 0x3705983b, 0xbdebc127,
- 0x07a5be62, 0x3c06415d, 0xa3542ead, 0xafa9242e, 0x39eb0cb5, 0x0640594b,
- 0xe5eb4e1a, 0x0703b8f3, 0x3bcc49c9, 0x37c003e7, 0xfec01d94, 0x08e3e60c,
- 0xda03a8b0, 0x826b79ab, 0x1f4f5065, 0x1b02d5cc, 0x3672631c, 0xcdc473c9,
- 0x97a1c3fa, 0xfc13c7da, 0x00df1748, 0x0604ef5d, 0x41dba832, 0x78020ca1,
- 0xa83b8f1a, 0xe5dc8fff, 0xfd33b143, 0xf1f553bb, 0x3e414b71, 0xa61fd74e,
- 0x83beabb2, 0x63faeeca, 0x0f1aa654, 0x26c6d124, 0x60df8c03, 0x5dca2741,
- 0x075d12a1, 0xffee37fd, 0x218ff32a, 0x878823f8, 0x2d16cd74, 0x4e665e42,
- 0xf815cd59, 0xe12b7c45, 0x8e6ef9bc, 0xbdb3c45f, 0x866d0950, 0x2ad9cf32,
- 0x786d1aad, 0xfc40740e, 0xb87c1e97, 0x2ea4f101, 0x855ce365, 0x4f9c2f28,
- 0x97c89f11, 0x5f381abb, 0x284efd62, 0x029539af, 0xef1c5def, 0x53a9dada,
- 0xc06099df, 0x5c82c29f, 0x28bf39ae, 0x78c77ff0, 0x7b343a80, 0xbde82645,
- 0xbc077fbc, 0x9e7d268e, 0x906b95c1, 0x9e2adea1, 0x30ddebac, 0xabd27e23,
- 0x5079edc0, 0x97cfac1f, 0xf8897ff9, 0xfa04dcd8, 0xd57eeb09, 0x21fbc2af,
- 0x70e0f5a2, 0xca545cc5, 0x1ee7cb5b, 0x62bc6092, 0xa8fde3f9, 0x29d487de,
- 0xf41a776f, 0x6042c165, 0x86c622bc, 0x2f3f35ae, 0x30eb988c, 0xf3042d80,
- 0x3f316e2f, 0xd9dcce3f, 0x2e19d227, 0x80906e48, 0xbd5af37e, 0x849a45ec,
- 0xf58dde95, 0x0dd9ae2c, 0xf427a175, 0xdc99e4ba, 0xadf98119, 0x900592be,
- 0x449269c6, 0xefc56c78, 0x141e8f80, 0x7e96fde5, 0xac9952f4, 0x02ef50d9,
- 0xf4c983de, 0xd654be58, 0x56bc748b, 0xfd8bde9a, 0xe6312ba6, 0x54bf90d5,
- 0xfb6b13e2, 0xf1a14934, 0xa08e94d3, 0x14deeb8c, 0xb6adeebe, 0x9e51c6f7,
- 0x03f99756, 0x028f5c11, 0x4cdf9251, 0x5e50b358, 0x363c013f, 0x9363c389,
- 0xf5189c68, 0xdb2beb03, 0xbc38e122, 0xfa57d5df, 0x0d4a4459, 0x2d191fe7,
- 0x1698ec62, 0x3cfec4ce, 0x709ca492, 0x58d3e826, 0xb36ff451, 0xc372eaa1,
- 0x7513abfb, 0x7c739ddf, 0x4379c7c8, 0x772bf4cd, 0x7f2015d6, 0xb3628654,
- 0x7a4e7f91, 0x0edeba7e, 0xf602def3, 0x9ff80282, 0x61e50ce4, 0xea8b353f,
- 0xf30aa386, 0xe303a2e3, 0x1eb7b26e, 0x39824b07, 0x5ff48859, 0x0175cccb,
- 0x67dbde05, 0xf03b712a, 0x01f27da5, 0xac5c57b2, 0xc9c7eb8e, 0x07b43291,
- 0xef83239c, 0x455ef0ca, 0xdee78079, 0x75c32b60, 0xbccc39c4, 0x9b3c83ce,
- 0xb9b64aea, 0x5ccf4a9e, 0xf8ca5caa, 0x84069efa, 0xb267fc22, 0x995fe228,
- 0xf841281c, 0xf3e6bc1e, 0xaa67847e, 0x84a5d7c4, 0xde72e2fe, 0xbfb5ef47,
- 0x00361dc8, 0xf972b79f, 0xee4afb5f, 0x8f8809b0, 0x73979a56, 0x0b926ac6,
- 0x7323f115, 0x13b90ff9, 0xf878ebdf, 0x961bcf7b, 0xf4979a05, 0x5027f393,
- 0x6f3e363f, 0x9f9ea3f7, 0x7e3dbcf1, 0x366bd41d, 0x6df7a44b, 0x9f845cfb,
- 0x3d7947ee, 0xd88356ee, 0x5013ccfe, 0x3ad57c07, 0x8a9c1e3a, 0x665e7bf8,
- 0x0b3d085b, 0x4ecfa86d, 0x3b68f6e8, 0x78bb97af, 0xfef366b5, 0x8afbf1db,
- 0x7d430776, 0xf97bb35c, 0xbea1530d, 0x619db0fc, 0x0d6d9a93, 0xafa820ea,
- 0xac314a88, 0xf4e74cf7, 0xa392ec89, 0x8f7da0db, 0x66f723a7, 0x271dd70d,
- 0xb8008ff3, 0x37b91ddd, 0x46571f01, 0xdf8d9b9f, 0x0290ee55, 0xc7983140,
- 0xf07943b6, 0x5253cd5d, 0x5c7c01c0, 0xf99d3db5, 0x89e5f60d, 0x1d7e3936,
- 0x93cc19ca, 0x59cbbf41, 0x4fa46ceb, 0xaa0db6cd, 0xd39f40df, 0xdf9923f5,
- 0x3cd7a891, 0x77c0e305, 0x02959f2b, 0x3695c538, 0xef753f6e, 0xaadc2d76,
- 0xd41afce1, 0xd79c6ee1, 0x5bb62a3d, 0xcbbc5d1e, 0x36f847e5, 0x7de1b3ab,
- 0xd59ba3e5, 0xa85e8372, 0x640a3eda, 0xa6d700c9, 0x24e181e2, 0x0f01237a,
- 0x8953c133, 0xedd6867a, 0xa5768aa8, 0x2daa7cfe, 0x6ab1f893, 0x5fea6cbb,
- 0xd7e47ba7, 0xc887ec8c, 0x55e1375e, 0x2f6adba7, 0xa08eebe3, 0xa0af59db,
- 0x6a5bd2a3, 0x1f2f5fec, 0x50383a44, 0xfca97b5f, 0xca8fbd56, 0xa27ef58d,
- 0xbf8843cf, 0xc64edc11, 0x97d760e7, 0x827b2f21, 0xc3ec0bcc, 0xcb06e6b2,
- 0x0acf50ec, 0xa2ee7af1, 0xc8bfe4b0, 0xec12f5fc, 0x04e0c5de, 0x7afdfac1,
- 0xf63b0150, 0x8abc3521, 0xa6fc6005, 0x04ce08ff, 0x528ff77b, 0x4afa8638,
- 0xb82b85b6, 0x287cc5dc, 0xfac5eb77, 0x13f25db3, 0xa9e7d61e, 0xba1f6fa4,
- 0x2cab74ad, 0x6366b989, 0xf7fbfcbd, 0xbb3f5215, 0xfa151fa9, 0x3f74be29,
- 0x364fb7b9, 0x7b7b93f5, 0x01cfde85, 0xf2ed27ea, 0xf6e879fa, 0xdcf0cc6b,
- 0xf3f7a95e, 0xb9e3f532, 0xdee579bc, 0xcf0ccd31, 0xcfd4d51d, 0xd20145c0,
- 0x3fceb2b7, 0xb43bd60c, 0x8e647717, 0x5341fa37, 0xc0dfd36d, 0x520dc5f5,
- 0x8ca3e465, 0x792669c9, 0x99660cca, 0x0ce603ea, 0x09cfb532, 0x0fde9915,
- 0x8595785c, 0x89ef352f, 0x408ea251, 0xf68b43a1, 0xf49520f1, 0x2720d94e,
- 0x20f77fc1, 0xddcef48d, 0xe04784d7, 0xa2b08e3a, 0x1ab7737f, 0xea4deb1e,
- 0xcc4874c7, 0x86dfa587, 0x3dfdf5a5, 0x9e9c1ec2, 0xb7f0f1ff, 0x5b5afbe0,
- 0xa84cf0ef, 0xfb2b6bbf, 0xbcf9e233, 0x3269ffd0, 0x6976c3ab, 0xeffa460e,
- 0xadd2c29e, 0x5b5e0311, 0x48bf0086, 0xec5b7e89, 0xa3f21f61, 0x901a9364,
- 0x510fd73f, 0xfa041b19, 0x1fdb1d74, 0x9ee73581, 0xc43ee521, 0x2ffd03bf,
- 0x8c2af8e3, 0x77c69a3f, 0xb77c60d8, 0x8ef8f92d, 0xf1a6c9a2, 0xa615059d,
- 0x8c2a9df1, 0x6991f20f, 0x9df18973, 0xad6617e4, 0x8ef8d273, 0xff1a0a82,
- 0x9855951e, 0x1beb4fc6, 0xc60da07f, 0xfee3621d, 0x17f9bf4a, 0x7f9e635d,
- 0xfe79a541, 0xa17f9f2a, 0x9f8c532d, 0x5a2ff346, 0x2ff3e5e7, 0x77f3e4a8,
- 0xc6fb7ef0, 0x7fe1f4f7, 0x263f8e04, 0xe28ef8c5, 0x0ff9e669, 0xdfcf36ad,
- 0x671fc7c1, 0x6be313cb, 0x75f8fe34, 0xa1ff3e3e, 0xeabe34d5, 0x8f900708,
- 0xbab4fcd4, 0x8343da28, 0x240dfb41, 0x72a4181d, 0xbb93f724, 0xe38222a4,
- 0x77ce34ee, 0xbf01a51f, 0xca7d0969, 0x9e29eba2, 0x74f052b2, 0x35328ed5,
- 0x07bc5a3c, 0x00997f7b, 0x4cbb6975, 0x3a36cd7c, 0xbc0057a2, 0xf932eddd,
- 0x5e374b3b, 0x3d69951b, 0x1808fee5, 0xfe7c7190, 0xd98f6fc7, 0xb5979c62,
- 0x3f6ad65c, 0xab9069d1, 0x9d3efd3e, 0xf803ac8d, 0x535e4836, 0x69e804fd,
- 0x06dea674, 0x49e58c7d, 0xf3c0338c, 0xb38f4077, 0x7ffdfd11, 0xd1b5eee8,
- 0x0a2faf30, 0x1c284ff8, 0x48d627df, 0x47ffc451, 0xa8a9561b, 0xa6b596cf,
- 0x07d3d1a3, 0x53a0ad47, 0xd9076eef, 0x3f4f8055, 0x1216e7e2, 0xbf7ec645,
- 0x24870bef, 0x6f967bb0, 0x6efa601a, 0xfb368b11, 0xfb92fda0, 0xc2f10f17,
- 0xe85d6ffc, 0x1f932f18, 0x91b7cc18, 0x1b7cb31c, 0xdb0b4ef8, 0xa1f3d836,
- 0xbb42cb72, 0x52f94fc9, 0xb5bf5cd8, 0xb6ef5cc2, 0xcf18ed47, 0xb1215eea,
- 0x6defd0cd, 0xff8b7675, 0x6159c7c3, 0x08f112cb, 0x8117de3e, 0xe8f07986,
- 0xe3c72c36, 0xf5d12f63, 0x56ff2f76, 0x6bf6a787, 0x90547076, 0xe8399d7e,
- 0x0e48b347, 0x2f6177f9, 0xde15b79f, 0x60ceeddb, 0xfdb9e008, 0xd3e132ab,
- 0xbee77f0a, 0xec0da0f4, 0x7f4dced1, 0x6e7da3b2, 0xfe158f9d, 0xe75ad63b,
- 0x7d7155e3, 0x3eb11c58, 0x5aec988f, 0x2f6dacbd, 0x818efadb, 0x9f626a9f,
- 0xe18efadb, 0xf3edaabb, 0xd115f54c, 0x2fda992f, 0xf4d8b4df, 0x0aeb597e,
- 0x2d25fbd3, 0xc5f54cab, 0xda9aaf91, 0xc1b6b1df, 0xbab6fef4, 0x6fef4d7b,
- 0xaa60d8ad, 0xb0fc297f, 0x0b2dfda9, 0x4bde9b37, 0xed0c56fb, 0x1e1abd24,
- 0xeb76879a, 0x59f90771, 0xf2ebbf3a, 0x16ec0a70, 0xdd834f2c, 0xca036582,
- 0x6dbfc829, 0xb76b2f37, 0x35ea1e2c, 0xed2761f8, 0x4f280575, 0xe2b7be56,
- 0xf0dfcad3, 0x1d6c9f97, 0x8c6acbd2, 0x3dbf4143, 0x24393f16, 0x1f1ea0f4,
- 0xdcb956ac, 0x9bccef56, 0xb57ffe8e, 0x975e1f1a, 0x93ec4fc4, 0xf34498e7,
- 0xe7a56860, 0x5b80dd20, 0xdaab780d, 0xb3826c5e, 0xe34cbf6b, 0x05d944af,
- 0x0a5f37fd, 0x88f5c71d, 0x2c160fc5, 0x04f08318, 0xf6f5437f, 0xbb7f5a1c,
- 0x7d6ce7ea, 0x0bf88ec7, 0x7eaa7951, 0xea279521, 0x53be54c3, 0xdbe5415f,
- 0x765475f5, 0xf2a5afd6, 0x9508facd, 0xa16fabbf, 0xadf537f2, 0xdfab1e54,
- 0xf5ebe544, 0xebbb2a51, 0x7cea5483, 0x4327a7db, 0xfe156ec2, 0xb7224805,
- 0xe45cc55b, 0x96b8bedc, 0xacf1e50f, 0xb470d1f6, 0x031ecfcb, 0xc6a61722,
- 0x521f9597, 0xc90595e2, 0x028f28ae, 0x7ff4079d, 0x74e34aef, 0x1cd8d972,
- 0xdee37a06, 0xc01fbe2b, 0x15d41338, 0x47df8596, 0x49dcf303, 0x107f05fa,
- 0x3a2975e9, 0xc96f60b1, 0x89c7a07c, 0x8a5afe47, 0x456c86fd, 0x28385edc,
- 0xe2c97ad3, 0xaf48035b, 0xe9378a4f, 0x402fbf27, 0xa39339b9, 0x00a3afe3,
- 0xb2df04e3, 0xb39fa979, 0x20a60e6d, 0x47a4f71e, 0xf67d2431, 0xae0f56f0,
- 0x727dab77, 0xb31f18d4, 0xc2b13596, 0x4f9866a8, 0x7eb9bb6d, 0xc39a55b6,
- 0x8cfe69e3, 0x5f20c69b, 0x50efa379, 0xa547d15c, 0x9f6acfde, 0xfee8e34a,
- 0x4991db38, 0x217e0a7c, 0x86affbb5, 0x093f5523, 0x1fd8da38, 0x2e287700,
- 0xb93f8a17, 0x0f94ce5f, 0xb1bb8c54, 0x708ff63d, 0x7fc0773d, 0x6591d017,
- 0x7ef5d50a, 0xc472636b, 0xef9f1631, 0xdf078d30, 0xfb9f75f9, 0xf8c5d142,
- 0xf4276155, 0x9b6a8279, 0x0e443e8f, 0x6a2b95f2, 0xa699fbd6, 0x5e7b6d7a,
- 0xe00eb4d4, 0x59ee403f, 0x3ae0a485, 0xa8b82d58, 0x245ad147, 0xec8c6f80,
- 0xf126fce7, 0x4ece3576, 0xbe47ec35, 0x54e2fc69, 0xa56cb63f, 0x3be15af9,
- 0xabd87f5d, 0x5c7e245c, 0x3bbd9f25, 0xffc8bed9, 0x48bef996, 0xd3db8db5,
- 0xa0f119cc, 0x117ccabf, 0xe18bc60f, 0x0fc3eb4f, 0x8e304df9, 0xb3f7aea1,
- 0x4def6a22, 0xd9764eb6, 0x1d6c9db8, 0x7b8c45b7, 0xdcadfc29, 0xce367471,
- 0x95c78adb, 0xb4abefed, 0xffc0a31f, 0xd478134a, 0x0e463bf1, 0xdfc0c8b5,
- 0x22dfdb95, 0x3d94f27b, 0x176bfc32, 0xe1fd5bd1, 0xb7147cd7, 0x611de7d5,
- 0x9dce381d, 0xff67f17d, 0x7585bf2d, 0xed97ddf1, 0xf62cbe3c, 0x70387437,
- 0xf506d0d3, 0x6776a225, 0x9bc5155b, 0x3d75dddf, 0x594b6fd9, 0x644e83c8,
- 0x452d6b05, 0xb30cf03b, 0x9d3c41cd, 0x267aaf61, 0x43b4e818, 0x974e4956,
- 0x10ed98b4, 0xf54d5fb0, 0xf5cc9be5, 0x173f3672, 0x46f94cf5, 0x344a8b3b,
- 0x47fbd33f, 0x7fe12f65, 0x8f5bab39, 0x9da373eb, 0xe9ddb3ef, 0xe83e4a65,
- 0x1e179adb, 0xff38c52b, 0x7ebe648f, 0x1593f1ea, 0xab8edc59, 0x31566d8c,
- 0xb687ffbe, 0xca9c5f09, 0x7ae8fbf0, 0xcf221f5c, 0xfe6d814b, 0xa4fdf8fe,
- 0xd5e15bf0, 0x717eefd7, 0xcd47011c, 0xbc692976, 0x892cbf77, 0x63f39ff5,
- 0xbaa5e286, 0x5be7d76e, 0x22c9afea, 0x19332c1e, 0xebc67ee9, 0xe832d88c,
- 0xf38e207d, 0x3408e9db, 0x72c2fcc2, 0xf64c98e8, 0x1984bc44, 0x30e585da,
- 0x5e92ef3d, 0x93bb4729, 0xb412f129, 0x21ed6123, 0x3f05553e, 0x129e69c8,
- 0x31bb778c, 0x67718bbe, 0xd60b6797, 0xe62bbbd7, 0x16b51c62, 0xf7f401f5,
- 0x61f66780, 0xb2709fdc, 0xf81078d6, 0xef33e1d7, 0xe6fcb82f, 0x75ea3a7a,
- 0x00f877d4, 0x8c02f9f7, 0x23e954e2, 0x01dcedcd, 0x1f6cfd73, 0x5f7ce29e,
- 0xf71c589c, 0x0cb8b5c7, 0x4ac9b3e3, 0x54bf9f57, 0x871afe84, 0x5a64ec1f,
- 0x7978d6ff, 0x7e2295fb, 0xf4f8e6bf, 0x89175981, 0x939ed547, 0xceb0d458,
- 0x2abd2ad4, 0x39ed61f2, 0x6a7f9e85, 0xd587eabd, 0xf357a0d6, 0x929a70e5,
- 0xc228f5c3, 0x6138c127, 0xe3809f03, 0xf9ca35ea, 0x7c3f0b08, 0x99b2386a,
- 0x918fbf49, 0xe0c9f9c3, 0xfbfdd4f8, 0xe23ff5fa, 0x61ffb4bf, 0x909ffafd,
- 0x179affac, 0x8115d99e, 0x87f2a2f5, 0x3300f6df, 0xd69577b3, 0xbdd000dc,
- 0x07b35b7a, 0x1294f2e5, 0xdf5d20f1, 0xa273ca8d, 0x52a1f849, 0xa82ef9d1,
- 0x3fc4a549, 0x9fa747c4, 0xe80de6fe, 0xcdb47fc7, 0x7eff25ee, 0x00ee23bb,
- 0xb6d95ca6, 0x76c7cb82, 0x7ebc5bc7, 0x9fc8fbcf, 0x7d66edb5, 0xb7e4f951,
- 0x7eb4fd73, 0x1bff8445, 0xe561ff27, 0x8d9c7f13, 0xeb2d58f6, 0xfd67bd25,
- 0x973fc70e, 0x62c2f645, 0x7bffa335, 0x56b21f7d, 0xedb6a5e0, 0x3ee3ef9b,
- 0xe7db6d44, 0xe9a1724e, 0xfad1bf24, 0x07f0855d, 0xd9dc556e, 0xc49baf14,
- 0xe9bf2126, 0xee516178, 0x3c2fc80f, 0x9cf18256, 0xf65e27ae, 0x7c8da348,
- 0xd9dff5ca, 0xfdef92d8, 0xae5a9fd8, 0x1a3f41ba, 0xcedd6eed, 0x3f0bb7f3,
- 0xab2f0f66, 0xee0f71ed, 0xb66f541f, 0xf55cbed3, 0xffbf5b33, 0x8e57c608,
- 0x4057023b, 0xbccf55ff, 0x5035faf4, 0x9ece7aaf, 0x434f973d, 0xf4137293,
- 0xd6ff85a9, 0xa3d04f8e, 0xa92f47f2, 0xcf8d0fb8, 0xa0959ebf, 0xfb73d54b,
- 0x3fa63655, 0xf6c4663e, 0x125a9dab, 0x9adec4fa, 0xfc86fe8d, 0xe91579c2,
- 0x893eeeff, 0x824c2c0d, 0x912fcdcf, 0x22788cdd, 0xf57a0a7a, 0xbed2cfd1,
- 0x7a42e816, 0x6b2f42d1, 0xfe4269bb, 0xa78c5fb1, 0xfb3f7f03, 0xf977dc63,
- 0x7880238d, 0x2ef678a8, 0xa4e7ce0f, 0xfcf9c752, 0xcc5ce6b1, 0x47b0a8b3,
- 0xf254bd72, 0x7f8f15e7, 0xf96ff885, 0x52e4afd1, 0xf305833c, 0x443b646c,
- 0xcb9e70f2, 0xe699bd1e, 0xc4c2ce59, 0xc98f1587, 0xa1f0ff94, 0x973ce6c2,
- 0x16de4e44, 0x8b727272, 0x4e859283, 0xfb8242e2, 0xd1caaf10, 0x5bcf146d,
- 0xaf92f145, 0x6c47fbe8, 0x743fd535, 0x2bb57a72, 0x4b0c1fba, 0x9f7f9189,
- 0xe903a7b8, 0x70487a74, 0x6b81c620, 0xf8111299, 0xbf402e90, 0x0359d1f2,
- 0x5f989d39, 0x81df1529, 0xcf819ffe, 0x3d877db1, 0x7d312ae8, 0x26142ec7,
- 0xc6235fc6, 0xd0d3b807, 0x0b993dbe, 0xf99260f6, 0x3d25d865, 0x0cc1d46e,
- 0x7790667c, 0xdc4fff2e, 0x975de5cb, 0x39bce8ff, 0xd783fef8, 0x77e11cb8,
- 0x5c00bf68, 0x7ef481f1, 0xe9124dff, 0x278b0707, 0xec27f393, 0xefcdce42,
- 0xf002fcad, 0xf71eb82b, 0x938e0df1, 0xfb207445, 0x7c237cb6, 0x38abd46f,
- 0xbf7fa7ae, 0x172f1cba, 0x8af7e0fa, 0xfa100fc8, 0xf5ca3d80, 0x243f6a40,
- 0x7b75edc2, 0xa08ffbf4, 0x46bc82fc, 0xf6bf28fc, 0xbdffce10, 0xff5f071d,
- 0x7bcdc832, 0xcd6e5d31, 0xb72ad57a, 0x66af3b15, 0x3df6e4c9, 0xca92c02d,
- 0x2a4f3c2d, 0xf1275ab7, 0xaf5bdff3, 0xed5478ea, 0xebaabd66, 0xb4f854c9,
- 0x8acdc9ea, 0xd56af09f, 0x1af7f093, 0x8fcfed2b, 0xfcea1f3a, 0x9a83f957,
- 0xfa8fa8a1, 0xc3e754f8, 0xf9d53e3e, 0xd13c5fb0, 0xfbeb4784, 0x18dc605f,
- 0xfbb425f8, 0x81f3b3d7, 0xf87bd5ae, 0x777c2cbe, 0xaf80eb08, 0x5ad37720,
- 0x1b67e50f, 0x3d4b51eb, 0xb41f6966, 0xf69643d4, 0xcebd4b61, 0xe3ca3ed2,
- 0x5507ed69, 0x37139f9e, 0x63afb7b5, 0xb1c63711, 0xc714caf7, 0xd79801ee,
- 0x3b3df7c3, 0xc291a30a, 0x6f5b5e44, 0xf51eba8e, 0xd7b78f59, 0xaf62f683,
- 0x7aefc78b, 0x4c9ebd42, 0xd6f69d83, 0x71f4991e, 0x49cd9467, 0x05824fe6,
- 0x64ebf44d, 0xb8f3dea9, 0xddda0f7c, 0x592cde30, 0x718b582b, 0xf2995698,
- 0xdc369667, 0x8cfcc1e2, 0x37c53d9e, 0xcbe7842e, 0x9b7cc88e, 0xf2541230,
- 0x29dc7e0c, 0x9a687916, 0xf7c7fb84, 0xec97fd13, 0xd2dd7ee1, 0x73f393fb,
- 0x5caef8a5, 0xdea2a35b, 0x6dec7f04, 0xde83bee3, 0x96a3c54f, 0x17ae7be7,
- 0xfdfdcf7c, 0xefcc27ca, 0xb03e22c3, 0x71fbe74c, 0xcff71c6c, 0xae77e519,
- 0x96777a16, 0x85c6fa3c, 0xc39e8740, 0x39be4332, 0x3a2647bb, 0xf7c1dd9c,
- 0x3ece29ef, 0x97b5f905, 0xaf8e9df4, 0x118f942e, 0xd750f5a9, 0xfd2fbff3,
- 0xdea9341a, 0xef92dbf5, 0xebb5d942, 0xb117f0f8, 0x051bc2fe, 0xdbfd65bf,
- 0xa2e7d8cf, 0x7d9e8d7d, 0xec87da6e, 0x82f3fbd9, 0xb77d61af, 0xf6708023,
- 0x0973fbec, 0x3acf51f2, 0xb1ea0547, 0x1fdc219e, 0xe7fbdc6d, 0x3f5a4e92,
- 0x937e789b, 0x67c3fb9d, 0x4df5fcf7, 0x984b1b29, 0xfb07da15, 0xa87f69d2,
- 0x8a2ec7f6, 0xfdecf5ab, 0xced1a973, 0x59f3acff, 0x7b1bf629, 0x4ee16cdc,
- 0xef932f84, 0x38bed4d3, 0xe6036b65, 0x57edb463, 0x19fbc097, 0x825f393f,
- 0x2767b1fa, 0xedba7bb7, 0x7ee38f9d, 0x2fed77da, 0xbd03b3ae, 0x063851ba,
- 0x3f529a81, 0x92d11e9e, 0xc53ce5e1, 0x1f172f0b, 0xe0c7ff3b, 0xf57da243,
- 0xa8ee3dea, 0xff79c253, 0xa2dfcde5, 0x20e7d83e, 0xfbe7d4be, 0xec81ac5e,
- 0xfbcd4b91, 0xbcdd3fe8, 0xcce5f8a5, 0x7c1ff7bb, 0xf26377de, 0xe5fdd5db,
- 0xef9f3fa0, 0xcfea9bbd, 0xef0403b8, 0x57bbf265, 0xfd1c7955, 0x9ffe741f,
- 0x813bee98, 0xcf4b9eee, 0xf83fec7b, 0xfdd353bc, 0xee82edc8, 0xa947cc5e,
- 0x8279c9fd, 0xb9ea93ef, 0xce87ff1b, 0xefd7b75f, 0x315a05b3, 0xbd1d3b2f,
- 0xe1e73c01, 0xe182df9e, 0xce46fbc1, 0x28dda2f7, 0x2b4bfd8b, 0xfb95117c,
- 0xf3c4b27d, 0x1e10d9d6, 0x4fc263cf, 0xd710f342, 0x272b454f, 0xd6d154bb,
- 0x94ccdd93, 0xf0104740, 0x7755df72, 0x87d72806, 0xc6163f8d, 0x0169e0fa,
- 0xfc5b578a, 0x058926c5, 0x9557b025, 0x187f3eab, 0x48fb16fd, 0x4251dc5b,
- 0xde585be5, 0x7690e223, 0x67f26aaf, 0xbae6d1b4, 0x3bae6fcb, 0xc64e7f44,
- 0x58fa77e1, 0xf2d1e314, 0x98bc0795, 0x538f26cf, 0xbb2ea618, 0xfd046b58,
- 0xfccf8706, 0x73f422fd, 0xb45bf10d, 0xb060e3db, 0xad8efbfd, 0xf3383f14,
- 0x60375bf4, 0xca2f55bf, 0xe97809cc, 0x7166e1de, 0xaa251be4, 0xd9523fa2,
- 0xbe290726, 0x174bc4a2, 0x750bf618, 0x87eab17b, 0x72ab826e, 0x173a23a7,
- 0xf5dcafbe, 0xb75a1287, 0x3d92f5d7, 0x0a5a791b, 0x3be1a36c, 0xb03f704b,
- 0xbe7e4952, 0xe79511e4, 0x4eed751b, 0xbc7e885f, 0x6be79db4, 0xb16ec656,
- 0x28790c3b, 0xdebb541b, 0xf228f88e, 0x2cf94494, 0x4f319f08, 0xbb57b750,
- 0x7c38929e, 0xe628f6ed, 0x7f6e567d, 0x11e31bae, 0x011cc795, 0xb76b1b74,
- 0xeff14fbf, 0xc67c3f19, 0x977e49d3, 0xfb43f26c, 0x65db7ff9, 0xb6caeba2,
- 0xa15bb21a, 0x195df44e, 0x27d6fe13, 0x7eaa4ff4, 0x1e1777b8, 0xd1faa894,
- 0x778c1e93, 0xe6d8ee9c, 0xfb703f21, 0xfd31e3c5, 0xbdd8bdfc, 0xc2fbdfc2,
- 0x54e3e449, 0xfc69defe, 0x3f51d807, 0xf37e2d55, 0xc76401f6, 0xc9a59c02,
- 0xfe74c7f6, 0xc3e67aa9, 0xd95e31c7, 0xc7bdf3b5, 0xbfeaee11, 0xb471e9fd,
- 0x973ed943, 0x6a2df717, 0xc535fe9f, 0xdeeff477, 0xa25c7954, 0x2927a9fb,
- 0xfe0dd63e, 0xbdd6f636, 0xfa0164f7, 0xfdcfdd23, 0xe7fd1725, 0xd1677b35,
- 0xcf358ff9, 0x92c818cf, 0x225eb1c8, 0x232f46ff, 0xdba5673e, 0x6483b6c1,
- 0xba019f2f, 0xe7d2bfa3, 0x786ac7c7, 0xfc2fc47c, 0xe3c91df7, 0xf5fcfda1,
- 0x5e3705b6, 0x6db8f98b, 0x83aa00f6, 0xafedfa4b, 0x5ec73d01, 0x88771d06,
- 0x0bec4cf8, 0xcfdbf517, 0x5e803fe0, 0xfc742de7, 0xf7d96db0, 0x6d77c11e,
- 0xedfa5203, 0x9fc0cbf1, 0xa23d6f1e, 0x940e9d06, 0xa03f9db7, 0x6fd20978,
- 0xfbb84c2e, 0x300b0f99, 0xdeca7d5e, 0xb1e53b7b, 0xd17875ef, 0xfbdcad4f,
- 0xf753c906, 0x9e2947f3, 0xb3dc44c9, 0xf1fdf59b, 0xa1c894f8, 0xcdc27dab,
- 0x07417dfd, 0x3df8078c, 0xfdf85cf4, 0x78f5af9c, 0x4038aa40, 0xe4f3c1d0,
- 0xcd7038f4, 0x7e15bf13, 0xd26e8275, 0x5bd7a464, 0xeb5f8d17, 0x1e22f078,
- 0x5ce31926, 0x7d2ee3c9, 0xdd0b2e71, 0x5f56f8f4, 0x83ea0b1c, 0x95119e31,
- 0x371648de, 0xe3ccdeed, 0x7376dd63, 0x4e824dfe, 0xd535ee3c, 0xe8d38e61,
- 0x2f254df3, 0x6a5edcba, 0x4f149f1e, 0xbb08d0a3, 0xbabe3fba, 0xdfae4e3e,
- 0xde5c776f, 0xfdca757e, 0x7592a594, 0xc736e53f, 0xbc3f68d5, 0x57ca32a5,
- 0x0c79e5e8, 0xc8b9befa, 0x5a7aec17, 0xfac978a6, 0xefd241d8, 0xefa1fd56,
- 0xade159b7, 0x6caef013, 0xd747ebe7, 0x8354774e, 0xec0eba7e, 0xb95ebe26,
- 0xfd152de3, 0x7fdb43cf, 0x8b3b72a4, 0x1fae11cb, 0xba7cc351, 0xc25fdd9e,
- 0xdf3c7ae3, 0x37ce3ad9, 0xa93edc1c, 0x9c7c93dd, 0x9bef1dda, 0xc48aa9c6,
- 0x79ff9e54, 0x2b4ef1f1, 0xbfb05bc1, 0x3a761dd3, 0x263a73cf, 0xbfb649cf,
- 0x1761d8bb, 0x2f2b41f6, 0xbca51d61, 0xbcfca3ee, 0xd357c4c5, 0xcd7a0f28,
- 0xc5bf39d1, 0x406b8c73, 0x6c4ed1ac, 0xda7ce06b, 0xf9827ff6, 0xa3b6ef48,
- 0xfd71965f, 0x35f885da, 0xafa58bd8, 0x8370cdd5, 0x5dfd287e, 0xabb22268,
- 0x3a4cef55, 0x0fc13366, 0x75c40ce3, 0xc1fa09a1, 0x9fcc7dfc, 0xcf647842,
- 0x8f0839ec, 0x5d79b5ec, 0xed52f249, 0xcaf2885a, 0x5eed7ef5, 0xc338de73,
- 0x4fd086f3, 0x5e7a95f7, 0xf1032851, 0xcdc761f4, 0x328674bc, 0x775917bc,
- 0xd9bd094e, 0xf1601f55, 0x081cfc11, 0x7e456bd6, 0x839ec570, 0x560f51b3,
- 0x2fe624c4, 0xada473c4, 0x763f3724, 0xa573f264, 0x515db351, 0xd457e7b9,
- 0xb78db2be, 0x6a3162af, 0x8c45e78f, 0x6c4d5bf6, 0xe11ec582, 0xf223ddfc,
- 0x95cfaa42, 0xff21b8b2, 0x9f8267eb, 0x26bdeaba, 0xf08d5f3d, 0xd61afb41,
- 0xc4d4e341, 0xd1c69806, 0x9b9cd5db, 0x46afea6a, 0xab7e20e9, 0xf42ff739,
- 0xeabe4fbc, 0xd487847d, 0xe09be7fd, 0x853ff44e, 0xeb2427c5, 0xb73d1a7f,
- 0xe6fa87e6, 0xde6378f3, 0x882cbd02, 0xe88cfea2, 0xd3ca73e7, 0xbf808da2,
- 0x3ff85a23, 0xdcf81f50, 0x625f0b1b, 0x326cde78, 0x709f59e5, 0x0f047c88,
- 0x047cf0f3, 0x7583622d, 0xcb6d11f8, 0xf28c6986, 0x8c3b4e0d, 0x5e2c06f9,
- 0x6f447a82, 0x25bdefd7, 0x7e30611f, 0x1650aa02, 0xde631670, 0x8d07ac3f,
- 0xb05b3cf3, 0x9f9ba8fe, 0xbd602c93, 0x60ff31fb, 0x0a03f0ab, 0xdc58ce31,
- 0xa7e4bcff, 0x3d99273d, 0xd0d56ca3, 0x9cb36300, 0xa02a6723, 0x296fb32f,
- 0x0bdf2e7b, 0x3d9b1966, 0xb3d0f313, 0x971b2c9f, 0x4b58f507, 0xcbff7f27,
- 0x500571b2, 0xe2eae63f, 0xca24abef, 0xbe5b57d3, 0x7da2333b, 0x137d3d06,
- 0xa4d4a660, 0x409cb3a7, 0xdfa133cf, 0x1f99717d, 0x557a1ef3, 0xc216678e,
- 0x73264376, 0x7ed60dfc, 0x75fa1cf7, 0x0d9d6d43, 0xb7be5fa8, 0x7499cff7,
- 0x23f30fde, 0x6b1e9cf0, 0xe11d22f2, 0x170be4d1, 0xe6b3afc9, 0x74fce999,
- 0xec5c3b95, 0xdf363a04, 0x23ce9239, 0xde31523e, 0x26e37e89, 0x70f3b791,
- 0x3f21be5f, 0x93b57897, 0x44f9f7ef, 0x0fd9d75e, 0x2eb2330a, 0x7d6a1fa2,
- 0x0628278b, 0x5e947ab8, 0xf9efb7da, 0x31dbadf8, 0x99eb130f, 0xc499d649,
- 0x7be94bf7, 0xf3053e6b, 0x2d9f1366, 0x78867c15, 0xfaf21a73, 0x9511cb97,
- 0xc55bda07, 0x8bd337fa, 0xd52297f3, 0x9f5185f2, 0xb4c74f1c, 0xd3c45cf0,
- 0xcf299ce7, 0x7a45ce75, 0x6675cf5a, 0xe0374339, 0xe7e57977, 0xfaee500a,
- 0xad4a69ce, 0xeb3f4879, 0xf4a64fb9, 0x19f992da, 0xcfb9c45b, 0x710f7054,
- 0x71c36f85, 0xdfe27e8a, 0x7fe41879, 0x803552ec, 0xd763a4a9, 0xa4280c4e,
- 0x45de789f, 0x3c2be0ad, 0x1ee74eae, 0xcfb466ee, 0x8290e3db, 0xdcf7d7e8,
- 0x60bb25e5, 0xe4b9d2f0, 0x17a4f75f, 0xa93f30c6, 0xda7e6be7, 0x427b040f,
- 0xb21f3942, 0xf2ee2327, 0x647e9c90, 0xcc8fd391, 0xb71e6972, 0xbdbf82e7,
- 0x8af3fa93, 0xcfd0c0fe, 0xee9f9c4d, 0xdf7af991, 0x3827ef53, 0x7ec8b086,
- 0x772f1fb4, 0x853bafbc, 0x03e8281d, 0x1186fff8, 0x66c740ff, 0x3a43afac,
- 0xc74a4c8e, 0xb47464e6, 0xe49dc79e, 0xfd87df0c, 0x443f2c9c, 0xe7ad72e7,
- 0xc9129970, 0xe9593c43, 0x3eb4ab5b, 0xb9d25b8c, 0x3b27de7b, 0xd8dfa746,
- 0x4e88e3b5, 0x843e7a06, 0xf3dd8c70, 0xd6e10dbe, 0x291df8e9, 0xc14c1db9,
- 0x8ffbabc0, 0xd3b0bb97, 0xbed24e16, 0xf5296d64, 0x82d9f807, 0xf3f018e3,
- 0x9fbfd614, 0xe14f3f1a, 0x3f032fbc, 0x7e0e5ecf, 0x4aaf3f74, 0xee1571c8,
- 0xff9d015b, 0x5b9f9fe8, 0x96cee304, 0x15d3e235, 0xef8a64db, 0x79b9fb42,
- 0x5fb909b9, 0x3f6ea531, 0xf15c579e, 0xb4fc4498, 0x7fbf9c54, 0xb7bf9c4f,
- 0x2f9603e6, 0xbd9e908c, 0x94605e74, 0x76d546f4, 0x09c3f3f3, 0x3ca02afe,
- 0x89ef715f, 0x15805f7e, 0x213567ff, 0x365d4bd7, 0xfd02bde3, 0x66ceb7e4,
- 0x9bcf2bca, 0xf90fd7d1, 0xff9b3efd, 0xfdd38a0d, 0x6e30cecc, 0x27b25414,
- 0x131f11c6, 0x6fd899a5, 0xbd2f9099, 0xcd6ba1bf, 0xc4615e76, 0xb8b03e7c,
- 0xf03e7cc5, 0xf9f3568a, 0xcc9b11c0, 0x8caf03e7, 0x8e07cf9a, 0x54de3eda,
- 0xc6bb131f, 0xfb6c7ed4, 0x5c7d5374, 0xf6a6f3fc, 0x37cf0e13, 0xf8eeafd5,
- 0xa4fda9b2, 0xde9a7763, 0x34ace94f, 0x6a7a9fbd, 0x6d7ea9b5, 0xda9abfef,
- 0xfd7197c7, 0xe47ea075, 0xfa9e6354, 0xcdaa5581, 0x0d57cf8b, 0x8c4b79b7,
- 0xfe8373cf, 0x834b2c12, 0xd2a767e8, 0x579c33b3, 0xf7ae354e, 0xd26ecc65,
- 0xe69c333f, 0xe225c7ba, 0x2fc00510, 0x2e01fc40, 0xbc815cb3, 0x1e40bae5,
- 0xb5a6ebf2, 0x83c7870c, 0x40cb0c56, 0xcb390279, 0x9c9e5d75, 0x93bb63e5,
- 0xb1ebe32b, 0x003eec9e, 0x2ef910b5, 0xb29bf942, 0xe32ff738, 0xfe32173d,
- 0xc2a5443f, 0x5e4a1122, 0x7c860167, 0xf5f75d6f, 0x8f8adef5, 0x27c78b80,
- 0x04f0fe1d, 0xdc3f2cc5, 0x4c55f0df, 0x92f80c50, 0x76a675bd, 0x499cff0e,
- 0xef89f7c6, 0xdfcc9342, 0xa5d5342d, 0x7f2973e5, 0x765c1528, 0x4f5192df,
- 0xe7b37e80, 0x7f52a62d, 0x96d0bcde, 0x06f05f34, 0xc3f467d7, 0xc9ff3ca3,
- 0x80dddf60, 0xfd933974, 0xf79843ea, 0x2f5172b6, 0x0e79e3f9, 0xd4487eb3,
- 0x3a2f3df9, 0xb3d68f3c, 0xebdeb8d1, 0x4196dae7, 0x9a6dd621, 0xf3e3b2ef,
- 0x61af3173, 0xfd3f0a70, 0xc79f3101, 0x96a323eb, 0xa7306322, 0x41793ce9,
- 0xda3676bc, 0x9e454361, 0xe4b643f6, 0x2e5553f9, 0x440caebe, 0x82f68d45,
- 0xc13ed2a6, 0x79dff299, 0x55abf530, 0xff21570e, 0xa3b639de, 0x0ea39f94,
- 0x3f7e78f8, 0x77d75b87, 0x21e85a05, 0x60055fd4, 0xfb0bf9b6, 0x517033c3,
- 0xbc214e68, 0x05b2ca6f, 0x4af7aa34, 0xebf8de74, 0xbed03320, 0xc1326fe9,
- 0x0a6074d7, 0x5aa915e5, 0x27464598, 0x7e44c9e6, 0xf0efbe82, 0xe44df661,
- 0xd55d36bf, 0x9188de77, 0x3a85ab3f, 0x370fdfb0, 0xa6dc69da, 0x7de992e9,
- 0xeabad681, 0xde51c010, 0x4bf14e96, 0xe40dd365, 0x0e3ea97f, 0x12e3d34f,
- 0x3c112c1b, 0xe1eece3c, 0x7c3c00f8, 0x2670f105, 0x4d91f858, 0xafbc349f,
- 0xbce950c9, 0x711490e8, 0xfc3a6d8e, 0x3a2691c1, 0xc3308de7, 0xf6fc6f2d,
- 0x3f9843aa, 0x807a7cf2, 0x2e3ea4a4, 0x779e6ae8, 0x1bfcf673, 0x1aed04bf,
- 0x1e19935f, 0xc277f0f9, 0x91f34f1a, 0x7824d1a3, 0xf006e9d7, 0x957e436f,
- 0xf9a6cd37, 0x2f7a0a16, 0x3ae37a07, 0xe685b3e3, 0x6d73fd10, 0x9d6be70c,
- 0x07a10ec7, 0x8579719e, 0xf97396fc, 0xf51d2df3, 0x73d204c4, 0x73ffd86d,
- 0x73f694ae, 0xdd892b9b, 0x517ba975, 0x1c7617aa, 0xca0e52c2, 0xd427ee01,
- 0xcfda370d, 0xe27f1fa0, 0x72cdf832, 0xb04bd7c6, 0xe1d94bdf, 0x65a04ab5,
- 0xeda5e178, 0x90cfb434, 0x0cfb750f, 0xe71479e6, 0x9e8b0bf9, 0xa3f5e837,
- 0x4499e6c9, 0xed8ebfaf, 0x9e397e4e, 0xbd027ed4, 0x8e64764e, 0x65ff5c9a,
- 0xd47a71a4, 0xf946557a, 0x97f62985, 0xedc9696c, 0xdfeb54c6, 0xa290fca5,
- 0xc07ee681, 0x847f216e, 0xdfb4ab95, 0xcd83f675, 0x3cc70ef7, 0xf288ad21,
- 0x93f55383, 0x04c976bf, 0x22bfcf81, 0x9dfc741e, 0xf015e0b3, 0xeba4d7f9,
- 0xd3e03564, 0x4b27c266, 0xf47b0cbb, 0x32bb9fd3, 0x16ea179f, 0xe0758778,
- 0x16075a2d, 0xf18a59bc, 0x7f379597, 0xa7c0eb44, 0x39a1671e, 0x0fc7a08e,
- 0x21df9c60, 0xfc17ba9e, 0x3b7dc44d, 0xf8d95e29, 0x17ba08fc, 0xaeba66af,
- 0x749cea4f, 0x117072ee, 0x2ecce7d1, 0x3ce11047, 0x66e3c593, 0x3a4d7667,
- 0xf799f184, 0x19670fea, 0xd9e67ce9, 0xe876a5a3, 0xa3ceccef, 0xf7e90aa5,
- 0x9ddee9a8, 0x2abf0b9a, 0x3f5e7f45, 0x77c7d0df, 0xd3ebe4ce, 0x3f3f8275,
- 0x5e301e29, 0x0a51fb4f, 0xbbed187b, 0x9b54bc3e, 0x499c15cf, 0xf114b37f,
- 0x0eb97800, 0x43d3aee9, 0x332b878f, 0xdc60663a, 0xfc0bf7b6, 0x2e8da93e,
- 0xe352a71e, 0xcd769875, 0xe35b879c, 0xc475a658, 0x3b50ef28, 0xd2c711d6,
- 0xc41bd9d3, 0x7676a7ed, 0x5fb1e7e7, 0x7eef29ef, 0x06f567ac, 0xd0c7873e,
- 0x06afe765, 0xbb7c03bd, 0x71fade71, 0xf7e94fe8, 0xd98af96b, 0xe0b1c2c8,
- 0xe25e61bf, 0x2dcb8a58, 0xe607efc0, 0x71c41eda, 0xf37325a5, 0x6c5c8196,
- 0x8794a8f2, 0x1c08cca9, 0xf37c23f6, 0xecef8214, 0x17df9961, 0x85b9cf32,
- 0xfc67bf9f, 0xfd9b921e, 0xa7d4beb4, 0xc3e3e7e9, 0x2afeb885, 0x1a516cac,
- 0x85a707d4, 0xd732c0ef, 0x10fc31d6, 0xf63ae77c, 0x609c029b, 0xd0bfc1e9,
- 0xcabb3abd, 0x3f71fb42, 0xe4b777ba, 0xc7fac2df, 0x7e85ebfd, 0x48efcbd0,
- 0xef31c775, 0xebbefeac, 0xec7c6166, 0xba3aae3b, 0x82fe05f7, 0xe7f41f4e,
- 0x32cadf0a, 0x6a691c61, 0xa16b9cf3, 0xe3f7876e, 0xcd69fbf0, 0x577ed04d,
- 0xaf1f3866, 0x534b71c2, 0xc10f0f9a, 0xb5bca33a, 0xcd29b4fa, 0xfe663011,
- 0xe3cbcd35, 0x10b85aed, 0xf757d4e9, 0xa86ddd42, 0x85752d3b, 0xd579f5d7,
- 0xe50bfc1c, 0xc3dcae95, 0xd9ca2def, 0x1bdf8f33, 0xee8f3ed7, 0x134e6b8d,
- 0x9a63447a, 0x58563cf1, 0xf88bdf0e, 0x195e92ea, 0x8f48e5ce, 0x2f78a67b,
- 0x59c39ee2, 0x06e3c51d, 0x62eec1e1, 0xbc78cbb4, 0x52f580b3, 0x8aebc7a9,
- 0x61ca8058, 0x48e5442c, 0x55e54ad6, 0x68e5462c, 0x096541d6, 0xc032a5eb,
- 0xe39632bc, 0x6cca8059, 0x59d1dd5b, 0x667f4fa8, 0x7c3a7d27, 0x8303aafb,
- 0x44de9118, 0xc78d66b7, 0x656bd6e9, 0xdcbc1ad9, 0x3f50f828, 0x348d5557,
- 0xdb62be03, 0xe87ec8f3, 0xdef63212, 0xf7045b26, 0xf9a3d963, 0x9c5abcf4,
- 0x7e3eae47, 0xf7cdec80, 0x60f3c982, 0xbb8bc05f, 0x963ed33e, 0x3ed67f59,
- 0x41be11aa, 0x39405f7e, 0x41708959, 0xa0ece6dd, 0x75f69773, 0x3ee907b1,
- 0xb4ec67b8, 0x18555abf, 0xbd43b32a, 0xa061776a, 0x7a8720c1, 0x6655703e,
- 0x96bc772c, 0xf5888f38, 0xdf825a71, 0x286fb657, 0x77fb7dc0, 0xf5a71ff7,
- 0x85e987fe, 0xb69a9f34, 0x4dd86aa3, 0xca2a7efb, 0x7d39bbcd, 0x97d93af6,
- 0x0640aecd, 0xfde9779e, 0x4b6fbf39, 0x94f7dfc7, 0xdf71975e, 0x283d70e4,
- 0x5ee9b042, 0xf951f7a9, 0x953f7a8b, 0xb2f7ab3f, 0x4700f820, 0x04da9dec,
- 0x30ce4f9c, 0x7bfbca2f, 0x432bd8de, 0x7cbe6227, 0xe601bf91, 0xcefd98d7,
- 0xded013fd, 0x7401c80c, 0x75eeec0b, 0xf3b42513, 0xcf29f37c, 0xbc6d1ee5,
- 0x4f008ff3, 0xe67012a3, 0x6b2fb8c0, 0xa02bb53b, 0x24fcfebc, 0xe5ffce27,
- 0x0fcd36ec, 0xddc61bf5, 0x247dc5ec, 0x02e36fe8, 0xfa2ecfea, 0xf6c4ef1b,
- 0x5a3f62f7, 0xa2fd9fa2, 0x677bbd7e, 0x543fbe36, 0xebee08cf, 0xb1b2da73,
- 0xbd1f7fbf, 0x13f195ec, 0xba477ee9, 0x17caca2f, 0x66cb9fd7, 0xe6cbb041,
- 0x41602b9e, 0xd393c7a0, 0xf942aeeb, 0xd1bfd357, 0xa0fd04ec, 0xa255d614,
- 0xb7a6f0be, 0x1f413b34, 0x9d01b06c, 0xa59f54bc, 0xcc70095d, 0xb181fae4,
- 0xa432e696, 0xc62bb03b, 0xae8fe1e3, 0xfa82399b, 0x7efe1ae3, 0xd79160e6,
- 0xf7e3ed00, 0xed0b31bd, 0x918a6ab2, 0x66e6b630, 0xa479f746, 0xce2a37b2,
- 0xc1a8b3a5, 0xba61fbae, 0x42a7e49f, 0x4c3ed089, 0xbd0f39c5, 0x5cfefcbf,
- 0xfd8873a6, 0xfde8d3fb, 0x7e74abe1, 0x679c520a, 0xdf2273cd, 0x881c15c3,
- 0xd763beed, 0xb8f60fe7, 0x57d5f113, 0xcc3e288f, 0xffe7d043, 0x49ffcd28,
- 0xef1ef135, 0xf7d81cf5, 0x7fd1059e, 0xea26923e, 0xb7922791, 0x2fb4b34f,
- 0x34cfebd2, 0x1fd69ccf, 0x12b8ef9e, 0x57b42775, 0xeafa3bce, 0x9b06df08,
- 0x7d2cbfa5, 0xfc69e7fc, 0xb45942aa, 0x5052f7df, 0x723bd031, 0xabef19a8,
- 0x78ef454d, 0x9b9b2fda, 0xae23fbe0, 0x5fad1950, 0xbf5a3337, 0x0602ee50,
- 0xe34f183d, 0xb9c555fe, 0x247a2651, 0x7a6250e8, 0xd2e4127e, 0x7cbb4fb8,
- 0xfe745dc7, 0xe7e69e24, 0x3f08b0fd, 0xb168f557, 0xfff67f69, 0xe169f1c3,
- 0xc7014b28, 0x1c33bfcc, 0x3fe49a57, 0xd368c701, 0x387efff3, 0x6380a466,
- 0x1c153ff6, 0x2f457b56, 0x2bda2fff, 0xcabda357, 0x9d6c41e3, 0xf7fdce8d,
- 0xe52a2a64, 0xc99369ef, 0xe195204e, 0xdf68eea7, 0xcd779f2f, 0x8b1c7bfc,
- 0x615f9db1, 0xd478ca2d, 0x11671157, 0x857f87ee, 0x0fcf03f7, 0x8683a02b,
- 0x1f693a64, 0x5434bfdb, 0xfe05fb85, 0x5435e585, 0x546eeb7a, 0x587a5f70,
- 0xefb438ef, 0x4fd96b36, 0xde933337, 0x2fbad08b, 0xb6bb22ad, 0x9b279be3,
- 0x6078df71, 0x68c3dd5a, 0x93914b07, 0x24a787cd, 0xd6f5cf7b, 0xd14fd32f,
- 0xce9d14ba, 0x293f42ae, 0x0ec68aea, 0xb59a3d20, 0xf0a3d200, 0x2296d19b,
- 0xdaf72ba8, 0xaf000d02, 0xbedd1992, 0x1e57e005, 0x4d764e18, 0xb61ff514,
- 0x6e89407f, 0xfa9dfcc1, 0x1bb7c500, 0xa5b47d85, 0xf317ae69, 0x3099ed98,
- 0x7ae5204b, 0xd097dd7b, 0x7534d75e, 0xae0a73bd, 0x01968107, 0x01f75e5e,
- 0xb1164f5c, 0x78a66722, 0xb46feb0f, 0x1af20d81, 0x6fe97eea, 0xbab79f32,
- 0xd70d383e, 0x8c95d5f9, 0xf7087f7f, 0xd2cc9e89, 0xfbdfc2f1, 0x4f5c750d,
- 0x7d448694, 0xeb7bcc26, 0xf7df5c63, 0xd1ebaba6, 0x44f987de, 0xc31b8ec8,
- 0x630e93e7, 0xf4fe007b, 0xbeb44571, 0xf17d6146, 0x0a71fbe0, 0xf7d2f79d,
- 0x6c639c83, 0xed841fb4, 0xc2ea7ee9, 0x742fda22, 0x388163ce, 0x69e703e6,
- 0x09517f7c, 0x3b3cc4ce, 0x04bf1f77, 0x8aa6ce29, 0xa26d12fd, 0xad205f39,
- 0x99b45be9, 0xfcda369e, 0x5ccc39dc, 0x9dc0b077, 0x60ec8f74, 0x2681be4b,
- 0xb00687f6, 0x1457e841, 0x6c3622db, 0xca85da07, 0x76df7851, 0xec811e31,
- 0x0c58faa4, 0x31e31691, 0x0c1d3f2b, 0x3282c09b, 0x6486a38f, 0x698e3bf4,
- 0x07947ce1, 0x66e2269f, 0x8dbf7883, 0x36ff61a1, 0x8ff14fcb, 0xf5efb47c,
- 0xb379c6fa, 0x4a91fe29, 0x889a22be, 0xec36dee7, 0xce9af7a2, 0x19100738,
- 0xc68e6ff4, 0x6f6b81f3, 0xd779f7e2, 0x947ee1ee, 0xe8b27efe, 0x9c4536b7,
- 0x327ae413, 0xd63df9c2, 0x485edb39, 0x0e7cacf7, 0x75f356e9, 0x6b4fc31b,
- 0xdfb9c7e2, 0x53b7b166, 0x158da1e5, 0x5f9f4dfe, 0xf218fc23, 0xc2ce902d,
- 0xd2ea597f, 0x4fbe6ee9, 0xa247bf42, 0x4f4dc847, 0xa8c44ab9, 0xea098345,
- 0xe9853739, 0x3172821e, 0x654df29f, 0x2c1fe8b9, 0x8225ffdd, 0x79c6d973,
- 0x5e4bde2a, 0xe13171be, 0x52ebc745, 0xa7f07f8b, 0x8d1709d6, 0xb4f6e9a7,
- 0xfee81fee, 0x484fd580, 0x47e7fdf5, 0xcc3a27ee, 0x3ed195f6, 0x3c1affef,
- 0xe07586cf, 0x67de20b6, 0x473ffba5, 0xf98eecec, 0x73655cf8, 0x2ec3f9f0,
- 0x54560f7e, 0xd87583dc, 0xdf859c5f, 0x7f3e29cd, 0x3b2f9625, 0xedea1a63,
- 0x7a3e3f97, 0x4a0ff903, 0x8d3cc34c, 0xfff70a33, 0xe7633af4, 0x0bf38a64,
- 0x7eef5fbc, 0xb867ee95, 0x74f7f0be, 0xfdc6bd3e, 0x3f639d2a, 0x3ca766d3,
- 0xb15debbb, 0x1dfde36c, 0xcdee17d7, 0x747e18be, 0x8088e1ff, 0x7bd170f7,
- 0x571a6105, 0xb70473e4, 0x53d2174a, 0xe7cd6f7f, 0x3e98ecd8, 0xa669e513,
- 0x2ff9e926, 0xcd97c88d, 0xfc9387f3, 0xe89bcf64, 0xf39bfde4, 0xc791b24d,
- 0x47cfeeae, 0xef59ff3a, 0xf1235925, 0xe0a9ef73, 0x19b405aa, 0x3dc4d1d7,
- 0xef3d2a25, 0x0e86f116, 0x54f6fb1f, 0xac799790, 0x75fb4ece, 0xfd177ee2,
- 0x4179975e, 0x2242fdcb, 0xd6242aff, 0x5e4437c3, 0xa7e63cd5, 0x376817ef,
- 0x75bf51d9, 0x6e60fb88, 0xf1bb6162, 0x425ea67c, 0xb6bd26bf, 0x7eb98e60,
- 0xb75cc873, 0xe7a8a3de, 0xdeb4fccd, 0x89ef153f, 0x999dfbd3, 0xd3ec3f42,
- 0xb03c5d3e, 0x67507e2f, 0x71e81f8e, 0x43cc1abf, 0x1e18fda6, 0xe4e59bf7,
- 0xbb8f4fe3, 0x56a37f68, 0x16e33753, 0xc5b3ea0c, 0xc6967cf0, 0x8bc60df5,
- 0x59a29ef0, 0x6f1f7e8a, 0x80e7bf54, 0xf909cbbe, 0x0ddc6336, 0x5ee930f3,
- 0xdf1e70ab, 0xa0721157, 0x0ece19c7, 0x5e6467f3, 0x4db5bf84, 0xba9ee9b2,
- 0x13b895fb, 0x00fee0f9, 0xf04ac3cf, 0x6f14d471, 0x49a936d5, 0xebebb7ef,
- 0x9e0af407, 0x3ee0724f, 0x01f7d02f, 0xc635e825, 0x887b3423, 0xf4f776ea,
- 0xf2f23f0e, 0xe3661b03, 0x988d1055, 0xca760c1f, 0x6957da3b, 0x03db767d,
- 0x621ef187, 0xc7e6dbb7, 0xb341b8f5, 0xa357bed1, 0xefeb49cf, 0x8bdaa97a,
- 0xebf7a4fc, 0xae0854ee, 0x06515ab3, 0xabff08bb, 0xda334fe0, 0x87df31af,
- 0x9e37dff5, 0xddfaed46, 0x0a7075bf, 0x131d59c5, 0x17bc016d, 0xb1ac1d5c,
- 0xcfc9243f, 0x936f1bec, 0x549fb492, 0x77494ff8, 0xf507a77b, 0x7c96b743,
- 0x2dc8ba3f, 0x3fc2fb89, 0xb22c3ca5, 0x5f33c3c4, 0xefc71e1f, 0x8a1bcea5,
- 0x8a3e490b, 0x2b6f20dc, 0xccf59dc7, 0xe47c93f0, 0x2e1c7cf2, 0xabda8db7,
- 0x6c379e4e, 0x152da7be, 0x4978ea3f, 0xc8e50785, 0x37e78c5d, 0x7f719986,
- 0x43c52dce, 0x4e32d794, 0xb8afba49, 0x51a1e056, 0xcabf1009, 0xb89c86d7,
- 0x4f64340e, 0x7ffee277, 0x28cfe2b3, 0x88f0fb44, 0xd66e30cc, 0x8dcb35e4,
- 0xfb88b65e, 0x6dbae745, 0x7559ef49, 0xeeff92da, 0xbe6e5dce, 0x9fecb44e,
- 0x52dee742, 0xd46809f1, 0xa5a5d910, 0xf3ef178a, 0x5e1ced96, 0x04fc8a57,
- 0xfc54dfbd, 0x177eef71, 0x61993dff, 0x659f3a4e, 0x9c49af1d, 0x78026bc3,
- 0x1a6dced0, 0x6c7841dc, 0xd178a89a, 0xd3f9768e, 0x5ed0d398, 0xef489cc9,
- 0x78d96acf, 0xa5359026, 0x4f1d3be0, 0x9f6db9d7, 0x16c2ff8d, 0x0df9cbfe,
- 0xfc0dcbc5, 0xff193ab7, 0x983c875d, 0xde37e1c3, 0xf264a9ab, 0xbc2b3ffd,
- 0xde3e7e7a, 0x9fcc6e87, 0x845f052a, 0x1c8e8dc7, 0xec0c3e9a, 0x303abedd,
- 0x86d78c38, 0x73fb8e7a, 0xd133a771, 0x647dd1be, 0x75429376, 0xdf07df3a,
- 0x6cf7f105, 0x39fdc4da, 0xc1f3a835, 0x45beaa8f, 0x9f585e63, 0xbb2ccaef,
- 0xda51e717, 0xab9f8071, 0xf9a1cb69, 0xadef8b57, 0x9c3dc6f0, 0x2f1ee39f,
- 0x82c71995, 0x77dfc03f, 0xf348eb68, 0x2db71c63, 0xd639db8b, 0xf5bbceef,
- 0xb156873c, 0xfb49d1df, 0xf8333912, 0x3bbbd47a, 0xfea3fc9d, 0xf7e069f8,
- 0x8dec5869, 0x94367bbe, 0xd51dd938, 0xc7d0eec2, 0x82c45d2f, 0x2f4bbbf8,
- 0x2716b1a5, 0x843b87d8, 0x2df6321c, 0x780a5fb1, 0x7c6fb804, 0x3fed1471,
- 0x04bdfde9, 0xcfb612cb, 0x912cedcd, 0x3fc0cfe4, 0x6fba6631, 0x39d9c6ad,
- 0xbe47f51c, 0x46edde1c, 0x6758e33f, 0x5edbd62e, 0xe0f64d3d, 0x73f0f0a5,
- 0x51c2bf81, 0x571e7dba, 0x35d6718d, 0xf45d95cf, 0xc6355d7c, 0x50fe0c43,
- 0xe9b36f02, 0xa17ebf79, 0x1fe8bf3f, 0x8d392be3, 0xa09ae9c9, 0x4c8b3e4f,
- 0x0a7d18b8, 0x25d23de8, 0x1fd39a3a, 0xde60f9f7, 0x607fd764, 0x09ef27d1,
- 0x9f4ffd7a, 0xae26366f, 0x40e53f01, 0xf188e789, 0x9fbc5bde, 0x6fc794f7,
- 0x15b27f5a, 0xcb3553f6, 0x2c6987c0, 0x8dfa84e2, 0xd167ce8e, 0xfaebd3fe,
- 0xc7c11bfb, 0x39fd8c9a, 0xf2e91cb9, 0xb928bd5b, 0xedcb7edc, 0x3c0efc21,
- 0xbee0f716, 0xfc628bc7, 0xe81fd8b6, 0x76b6b3be, 0x3d4fe199, 0x96145c0c,
- 0x4e825ac3, 0xebe1fbfd, 0x60ff2e8f, 0x0b728e4e, 0x4a3947f9, 0x6bfdcb5f,
- 0xdfe8cf5d, 0xcfb47915, 0xee8f1f66, 0xc8ac4e77, 0x75724393, 0x05f44308,
- 0x7bbdf96b, 0xa2ff0b6f, 0xd39fdc5a, 0x18c7dfa5, 0xde33691c, 0x5a76f5bb,
- 0x87fd1441, 0xe5f787b7, 0xed1ae609, 0xf0576aaf, 0x1bbef0df, 0x7ca65476,
- 0xc1bc0fd5, 0x9a2fee0c, 0x712ea7fd, 0x3fee8eaf, 0xffdf8b35, 0x7f398362,
- 0x1dd24b37, 0x91ffb0f3, 0x72af749d, 0xa75f2e6e, 0xcc7f73f5, 0xf64259d7,
- 0x54abe0b7, 0x0f39f77c, 0x83d40f97, 0xad7ca491, 0x0dbf9e9a, 0x70c460eb,
- 0x53cee84e, 0xcf1ce8c3, 0x78a01612, 0x749692e6, 0xbde03116, 0xf9e4f1ed,
- 0xbe848b35, 0x4ef7136f, 0x5e7cd1b3, 0xf3e7be09, 0x1c975b68, 0xbe0c9eee,
- 0xfb89b70e, 0x6094dbc5, 0xd529e23a, 0x078fa13a, 0x3ca74b04, 0x6f07f387,
- 0xe6fd71a0, 0xfa257f71, 0xb26ff17d, 0xc0037df8, 0xd827d0a3, 0x9b1e1bfe,
- 0xe2bebe49, 0xb3faacf9, 0x24feb4cc, 0x9e933ef0, 0x927d767f, 0x927d0979,
- 0xf251ef4d, 0x3a78ced0, 0x7b75efc6, 0xce6db0fa, 0xdb742496, 0xaaf4e424,
- 0x3fee851c, 0x76e7151b, 0xb976aa40, 0x639ee259, 0x7c2b4781, 0xf9c9c5d9,
- 0xfe0ca5e3, 0x7e74f57d, 0x1bde334f, 0xb285f38f, 0x75fd0020, 0xf422d74d,
- 0x6fe25ffc, 0x7ab49c62, 0xbf8fc3a7, 0xd3b5d7cf, 0xa27a8155, 0x62a3a76b,
- 0x7e9fd68b, 0x3b663cbb, 0x4ccf99f7, 0xf58c7fbf, 0x705174a0, 0x5fd1cfc2,
- 0x3ee99768, 0x927f6b49, 0xecf34dc7, 0xec29e7d3, 0xb9b9afb0, 0xe74ecd3e,
- 0xf117b174, 0x572ad475, 0x1d3c8547, 0x2d90f215, 0x75876bee, 0x92eb89c9,
- 0x0217eede, 0x2cc393df, 0xe7c17de9, 0xb12e02dd, 0x76bc3c2e, 0x04c3fb06,
- 0x08ce7dfc, 0x7eda19c5, 0x7ec02f13, 0xdc78cabb, 0x16fdfac0, 0x998c67c1,
- 0x3349eaed, 0xb9e612fd, 0xc5e498b0, 0xfdbd7c7d, 0xb7bf18a4, 0xd3b9fff8,
- 0xdbc5ecfb, 0x807bbfc8, 0xf49a2eff, 0x81eb8a53, 0x61b4170d, 0xc18fd15e,
- 0x5ff8338e, 0x1de8b2bf, 0x0baf3c2b, 0xefc4da78, 0xeb8d3287, 0xf55d2b61,
- 0x779f4c75, 0x1cb300f6, 0xd7ff82c8, 0x9647328a, 0xb9743c68, 0x7d7c591c,
- 0x5cc4f9e6, 0x49d2e24f, 0x1e5859cf, 0xbcaf7003, 0x90e6fc43, 0x95dcef88,
- 0x31ef3e19, 0xe9da3df0, 0xbb097eb4, 0x6fdc4dbc, 0xa889dba9, 0x466bc74f,
- 0x0e0223b8, 0x4ad7d71b, 0xf30d7d72, 0xe2a7bf10, 0xf6127ea6, 0x262bb706,
- 0x166dfc0a, 0xb25f51e7, 0x3fb226b1, 0x39749e04, 0x9661951d, 0x7f8ca2d3,
- 0xacdd390e, 0xa4727cf2, 0x787d325f, 0x9427ed1e, 0x71c16387, 0x4572c798,
- 0x5fa00b48, 0xff31da5a, 0x0cf1e600, 0x943f83df, 0xe1e39093, 0xbfb19f82,
- 0x2dfc0645, 0xf09b70c8, 0x7f8cf9f7, 0xf877bb0e, 0xdf37d631, 0x7d7a0cdb,
- 0xe5c68655, 0x942ffc00, 0x9a7f8a83, 0xe00e86f9, 0xa06aae39, 0x9d0caa3b,
- 0x8b62da3f, 0x3ed0b9d7, 0x6802c63e, 0x16c7775f, 0x7f00c6db, 0xf6e26f74,
- 0xdf9e9f63, 0x7a05f1c8, 0xf97a8639, 0xf4c1638a, 0x275f50d1, 0x458ae3f8,
- 0x14e7df8c, 0xcfd14773, 0xce44f5d6, 0x7033bd4d, 0x7a6577df, 0xf0cb835d,
- 0x3b7dafbc, 0xe84c2fb4, 0x37d46a9b, 0x7df6d4fe, 0x8d3a466b, 0xe209eb87,
- 0x733a5665, 0x979e00ba, 0xee32230a, 0x4574be6b, 0xe7bc78e1, 0x785a50fd,
- 0x7ef86af4, 0x0e3e1cd2, 0xaf44776b, 0xd2ff1248, 0x88ae75f5, 0x7c8ae54f,
- 0x5e34dcef, 0x45f42c7e, 0xc1f39783, 0x9ebcbdaf, 0xcf1e49eb, 0x17ef11ea,
- 0xdcef5cc8, 0x2edc9657, 0xc67c6589, 0xb24063f8, 0x1963e3c6, 0x6f9ee239,
- 0xeb5f425b, 0x7c4273fc, 0x2edf8fa7, 0x9cfcb5e6, 0xe59fe264, 0xcdf11d4a,
- 0x3d0a73f2, 0x1522e5d7, 0x79fbe9ff, 0x78e11d9b, 0xbe7bd406, 0xc60961fe,
- 0xe9ef0a0d, 0xf848fbe2, 0x5253407b, 0x1ebe87cb, 0x3d06f4e8, 0x0df186df,
- 0x2713f3d0, 0x18f43ad3, 0x9c85975f, 0x1ff4ec1a, 0xb659efe0, 0xd4555c75,
- 0xdf6ba060, 0xfee0197a, 0xd95d758c, 0x57c4c980, 0x89d79ea7, 0xa3ef2ccf,
- 0x25e1d852, 0xbc3b577f, 0xc93c63b4, 0x578112ed, 0xc7a6de3d, 0x507b18b5,
- 0x13f731f8, 0xe4cd277e, 0xdff80df2, 0x9a3ff021, 0x7dbbffe3, 0xec95bff8,
- 0x2f2e5684, 0xa52b9db9, 0xfa2f9262, 0xa4ddff4e, 0x52afd3c2, 0x2f78e77e,
- 0x13ffe7f7, 0xc9555084, 0x00008000, 0x00088b1f, 0x00000000, 0x7dd5ff00,
- 0xd5d47c79, 0xcefdf8b5, 0x3324b677, 0x5f64ccc9, 0x25849308, 0x2126126a,
- 0x26504109, 0xc5116109, 0xfb094049, 0x515983b0, 0x2fb5696c, 0x4a444103,
- 0x505d8bdf, 0xd101da94, 0x101ac55a, 0x83b06034, 0x6795622c, 0x05b054a4,
- 0x2108ee3b, 0xf16b43c9, 0x3dde5a57, 0x999bdee7, 0x006677ef, 0x7e7ebe7d,
- 0xdeb8ff0f, 0xdef7cbb9, 0xfb3dce73, 0x3ab3c9bd, 0x21094b25, 0x0b62a21b,
- 0x99941c48, 0xc84b125e, 0xbd3e0988, 0xe90844dd, 0x95242448, 0xa423aefe,
- 0x475aea0b, 0x2423c932, 0xbd389ead, 0xbed19eb4, 0xfad2d25f, 0x8637f865,
- 0xc94ad310, 0xfe9e30b9, 0xd3b694be, 0x3a166ddf, 0x9ed03130, 0x1609ebcc,
- 0xd025213b, 0x820d27cf, 0x936f36f9, 0xb4be74b4, 0x62908976, 0x2f13365a,
- 0x4b8c0ac9, 0x99efb073, 0x01695e1c, 0xbb48dfed, 0xac849191, 0x59e754d3,
- 0x14996812, 0xbfa568e3, 0x07bab06d, 0x4fea7ec0, 0xda667cf9, 0x2ea9c465,
- 0x7b8e9bad, 0xb4cceac2, 0x63f60624, 0x24692d97, 0x53989087, 0x366d9d6c,
- 0xfb05d732, 0x174cfe23, 0xc63f240c, 0x15b211f5, 0x93289bd7, 0xab46c423,
- 0x2f7e87d0, 0xd6ee7569, 0x7d6052f5, 0x6ee23649, 0x49496da7, 0x84d3bdc4,
- 0x2291d7fd, 0x7048d7da, 0x87ab493f, 0x059f5d6c, 0xde7179f3, 0x36d71caa,
- 0xf92abdf8, 0xfa56a2ba, 0x9f06ce7b, 0xb71d3e76, 0x0266b377, 0x2bcc53ec,
- 0x0916d1ca, 0x8c7dd1c7, 0x7d89fd80, 0x9289fba8, 0x5bae0f10, 0xb345d3f4,
- 0x5bf685fd, 0x4cc6f385, 0x6d0df060, 0x2f6c77ff, 0x0cc265ff, 0x1afd6f58,
- 0x0148313d, 0x75613ff8, 0x4d7002dd, 0x0122df6b, 0xa68c3e6c, 0xf02c3474,
- 0x29a30fdd, 0x76b0153d, 0x87f3853b, 0x79474a7a, 0xb48a3a01, 0xb295fafe,
- 0xa0f0e173, 0xe23d1afa, 0x2c9e8b69, 0x5e0bcf6d, 0xdf5c6adf, 0xcb068b22,
- 0x2cd756a3, 0xc7634f80, 0xfbc07ac3, 0xe81f6db2, 0xcef857dd, 0xee91c2b5,
- 0xe296957f, 0xb25daebd, 0x4ae92818, 0xe81392ed, 0xe8d6bea0, 0x6fd47805,
- 0xd64b7467, 0xa183bde8, 0xa7c3bede, 0xf7e9eda1, 0xfd321d3b, 0x0efb6eb9,
- 0x7c105169, 0x12bdebd3, 0x59a86bac, 0x1e9f2b9c, 0xfe8a95cf, 0x4578510f,
- 0x1c3bba51, 0x5a463c45, 0x3c9b9776, 0xb76f8512, 0xfd0f5dce, 0x1c6353ba,
- 0xf5efda1e, 0x488fe31d, 0x779adcf4, 0xae507c1a, 0x314d6cd3, 0xd775f6d2,
- 0x41ad1deb, 0xbad36774, 0x6b38c176, 0x8ab1d982, 0x206eca7e, 0x9c131645,
- 0x47fe2577, 0xc5cecfdc, 0xa32c4b6e, 0xe08a4223, 0x316e3c5c, 0x82893d63,
- 0xf7d28cbb, 0xd75b1d61, 0xe1e8c24e, 0x836b9c52, 0x23e3bf05, 0x3ade3a0e,
- 0x3a979d81, 0x7e891fba, 0x2ef36eaf, 0x623927dc, 0x6fa7b843, 0x75bbf097,
- 0xb9e0b7db, 0x73bb3ace, 0x2ffa1ebf, 0x2451a525, 0x1b9cce98, 0xd5efcf83,
- 0x426235f0, 0xade81ebb, 0xf2a1f38e, 0x3e936e5f, 0xafdfda0a, 0xa3c2322d,
- 0xfdb6f36e, 0x647bf469, 0xb60cb129, 0x13fdbf63, 0x06b5f7d9, 0x607fc412,
- 0x9d6c799d, 0x8ff8828b, 0x3e187fd8, 0xaf585bf4, 0x41d754e9, 0x487c87c6,
- 0x6afd628f, 0x7e7076bc, 0x3c4f4e38, 0x93debbf8, 0x1df3a76b, 0xf9c68ece,
- 0x73805f04, 0xa5f9c35c, 0x6213d686, 0x5a0eb9e8, 0x9e6f588f, 0x82d3a2b5,
- 0x3842e870, 0xe2d66c34, 0xaef4abfa, 0xce83cb41, 0xb9f9efc3, 0xfbda6d79,
- 0xfdfd3f7a, 0x83bf2fe7, 0x936869f8, 0x48cfc09c, 0x3bfa3bdb, 0xbfac01f2,
- 0x21124991, 0xb7fb0893, 0x7a3bf771, 0xd27dfd3b, 0x86bf862e, 0x0bb43b5d,
- 0xccfa014c, 0x1cdafb3a, 0x7686b3a0, 0x00928903, 0x582eee7f, 0x054e9a8f,
- 0x8ddf043c, 0x0998cf84, 0x0f128f8c, 0xcf485f3d, 0x731aacee, 0x8a5f6f80,
- 0x353a30d3, 0x2dbbdfb1, 0x1fa01eac, 0x974007f7, 0xd78ed155, 0x15545ce0,
- 0x02568e49, 0xfb863ceb, 0x7064a848, 0x754f5e0c, 0x997e647e, 0x85e5cf18,
- 0x63599fd6, 0x7eaf9c0e, 0xf7c7cfbe, 0xfc995e02, 0x49dfb1f0, 0xb03f2bb6,
- 0xd2de356e, 0x0ff612ad, 0x01174f43, 0x26b96a7e, 0xe3e82fd6, 0x0ab59bd7,
- 0xeab061f9, 0x55833e71, 0x08dbeb8b, 0x7e72a1f8, 0xcb9d8ea3, 0x5e8cab8d,
- 0xc7d31fe4, 0x9f28911d, 0xfbd0cf36, 0x99a43ca0, 0x87ed0f5f, 0xd7f7d8d2,
- 0x43773469, 0x136add7d, 0x3a7c4569, 0xa044d68d, 0x4bc4589b, 0x6bdead7d,
- 0xfcfcf3a0, 0xeabfc645, 0x012f263d, 0xba9ee83e, 0x8491c610, 0x8053c728,
- 0xfd41f737, 0x7a50e61d, 0x6f63d3b2, 0x6a4fbfa7, 0xe04ce767, 0xa451f281,
- 0x04bf212b, 0xf4f0035c, 0xc08dce2a, 0x0b38a5c7, 0x2cee5be7, 0x33dd7780,
- 0x738fde51, 0x132eb7d9, 0xa2ab4ba0, 0xea91d4de, 0xa818d8fd, 0x00ffc1d7,
- 0x52a76c1d, 0x83ae94ad, 0x765d33af, 0x6efb075f, 0xeb0ffa30, 0x4f4b6a28,
- 0x8eb9e1f6, 0x2b75b744, 0x98fb4cdf, 0xa57743ea, 0x38a581bc, 0xa56cbaaf,
- 0x78e52e3c, 0x9bcbc01f, 0xd41f8cac, 0x79e3b715, 0x19b8fbac, 0x0269b1cf,
- 0x53a667e3, 0xc84d7e4a, 0xb2beb84f, 0xc557c701, 0x29938fb4, 0x257eabdc,
- 0x64495a59, 0x2244b97e, 0x9fa7902e, 0x3b103e6d, 0xe97be00f, 0x8dfb8cb2,
- 0x6c9dfb62, 0xfba8e765, 0xa4700a19, 0x093d66f7, 0x9d6bdfb3, 0x4b8ef88f,
- 0x0e3af780, 0x95edeeeb, 0xf4a13f23, 0xce2679e2, 0xdcf7fc01, 0xf83f29f6,
- 0x7bbbae84, 0x9b9418db, 0xa42ead09, 0x28c4be9f, 0x3f4a56c7, 0x20993209,
- 0x6aafbc51, 0x8a3b103f, 0xb9fcfb8e, 0x8f204561, 0x9e75f117, 0x095e517d,
- 0xebfd5970, 0xf6866e17, 0x0f14af3a, 0x99fbbc7c, 0xf813fd5f, 0x4d6dd2fc,
- 0xd69149a0, 0xf7a77ee7, 0xef1a7ed3, 0x33fbf616, 0xf7e81671, 0xdf0f93f9,
- 0x6d6ef00c, 0xb3f6c56f, 0xfac16e4f, 0xe17ebf6b, 0xf207ffd5, 0x80eb15de,
- 0xdc5f677e, 0x77a9788f, 0xdfb09d6b, 0x71bd7448, 0x27c67ec7, 0x39c3ae41,
- 0x4bfc65a8, 0xdfa0b5d0, 0x773d7fcf, 0xa87cb064, 0x12195d97, 0x38364ff4,
- 0x5e50929e, 0x14389ca0, 0x7451b445, 0xd2d3afff, 0x792acb48, 0xe01d7ef9,
- 0x33f18739, 0x790921aa, 0x7f431bed, 0xcc4c7dbf, 0x2f3bd416, 0xcf0833dd,
- 0x3ba30c4d, 0xcf918f3a, 0x88798463, 0xf33ea096, 0xa875e676, 0xcd2952d7,
- 0xce1249fa, 0x1ba6e873, 0x17b9c2b6, 0x6af985eb, 0x3abda1f2, 0xf889e403,
- 0xe75f1d7d, 0xdf2668ba, 0x537e71ce, 0x075a6157, 0xa3e7b9e5, 0x8d3f016a,
- 0x2b10ff7a, 0xd18f2fc0, 0x265643f1, 0x97dbea87, 0x384d1aeb, 0x9779e71e,
- 0xf32829f2, 0x94fa79e9, 0x6bda579e, 0xf0e1e5db, 0x3e32dfbd, 0x60ca4d19,
- 0x7d66d31f, 0x62fc0120, 0x75759af2, 0x58e7d708, 0x7052c53b, 0x760ae97b,
- 0xfb74d47e, 0xcfc4d5a4, 0x69b73b0f, 0xec33aabb, 0x8e0cb7c8, 0x53fa41c1,
- 0xab7752da, 0xcb7efe99, 0xa643b70a, 0xccf7b774, 0xb4e971b1, 0x695cebfe,
- 0x2cabd238, 0x31ec7931, 0x561a77e1, 0xe88f9256, 0xcfc9dfb9, 0x68859275,
- 0xe00a2c6f, 0xb44b4aa9, 0x1f7f8426, 0x7586b5f2, 0x636f5e5c, 0xbec624eb,
- 0x1c6629cc, 0x16d1ba67, 0x671d0758, 0x2fbd6132, 0x907ccef3, 0x945a9e8f,
- 0xae3d768f, 0x5fe0acf7, 0x3b3053c4, 0xa81fc03f, 0x7a06e6de, 0x7b33d24d,
- 0xb563f805, 0xf2e6f419, 0x4092d623, 0xdacd1499, 0x6d9270d5, 0x3bae9db4,
- 0x7ec4e6df, 0x857899e4, 0x07c48afc, 0x37fe391b, 0x40c5fe4a, 0x513d9e67,
- 0xc6eba016, 0x1443fd9b, 0x53870976, 0x9e9ba70f, 0x0e5e8c3d, 0xd81e3469,
- 0x37ada1df, 0x4295696c, 0xae50f1e5, 0x4875a79f, 0xda4bc016, 0xfe051ae6,
- 0x0ab75ea8, 0x5c86caf4, 0xf7f514a9, 0xbfbfe58e, 0x291bd68e, 0xb8dea0de,
- 0xaa4f9f8b, 0xc6ff42a7, 0xf085ea8e, 0x8984f4bd, 0xfd42590e, 0xad3a5c68,
- 0x1293d637, 0x071bff38, 0xe3a4f738, 0x94f2243e, 0xd529e41d, 0x269e41ab,
- 0xde3ea3e6, 0xfa86dee8, 0x73d5c937, 0xf510b7b9, 0x9994c6f5, 0x215f380e,
- 0x2acf627c, 0xed1af7d4, 0xda288ed1, 0x7487527f, 0x4c77d337, 0x7247ad84,
- 0x77927d42, 0x73d61794, 0x9447c05e, 0xf039aeba, 0x06dd9efd, 0xafeda1e2,
- 0xf28f19ef, 0xf98bd05c, 0x75ca0325, 0x8122d69b, 0xc5ae7e5e, 0x4c1a3e49,
- 0x9cb81fc8, 0xdbacf011, 0x7381a59e, 0xc3b79e72, 0x97127b3f, 0xc36bb487,
- 0x67d21f42, 0x13dbd73d, 0x7bc2ce0c, 0xf427f082, 0x641d3528, 0xd35e18db,
- 0xe0941f36, 0x73f1ab10, 0x6be252cb, 0x65bbeba2, 0xa637c6b3, 0x19abf500,
- 0xe957f7c8, 0x742956c9, 0xc63621be, 0x5de2aa2f, 0xab27c085, 0xc11c99a6,
- 0xda2aa9fc, 0xd20a89a9, 0x157108f3, 0x26763d83, 0xcff08cc9, 0xeac3d9b7,
- 0x79f6a165, 0xb74fda14, 0x480a79b6, 0x155d6d36, 0x92e70b5d, 0xf21363f2,
- 0x0f1d0b4d, 0x51d6fdf6, 0xbefb324f, 0xb14de715, 0x8ef9d859, 0x83371577,
- 0xb5c7203f, 0xb331c982, 0x8e7edc23, 0x3e1e855a, 0x740350a7, 0x00e4d532,
- 0xafe7f2bb, 0x6e91f348, 0xc260543c, 0x38af7179, 0x2bd99136, 0xe23ba00e,
- 0xd5bea2d6, 0x86f2ecd8, 0xc7462ba7, 0x02ff548d, 0x15d29c3d, 0x83b1ade2,
- 0xf7611fc9, 0xd6089f03, 0x12b9c577, 0x35f816e7, 0x37a08dd0, 0xf5af6e71,
- 0xf3f0f67c, 0x1ff743d1, 0xbde69f4c, 0xafd72e8c, 0xfb4397b2, 0x09622afa,
- 0x76d557b6, 0x1f0e1d90, 0x8c9fdbad, 0x823cc2f1, 0xbab06dcf, 0xbd60da66,
- 0xab58df5b, 0xd4be0125, 0x21a1f7b8, 0x8ccfd257, 0xd19f365a, 0xa60de31b,
- 0xb705231f, 0x0f4b08b9, 0x9598e7f0, 0xf723fde1, 0xcf4c4cda, 0x65fab6fb,
- 0x7c05a49e, 0x5f32fd09, 0xe36bdf76, 0x08a525fa, 0xe992b992, 0xebc04997,
- 0x8d6c1f81, 0x113f02f1, 0x7af5267e, 0x099cfcdc, 0x233b0abc, 0x7ff59629,
- 0x359b9f98, 0xbc63dfbc, 0xf05fb20c, 0xee35d83c, 0x591c880f, 0xdf71880e,
- 0x7c4bdf95, 0x3523c847, 0x41fac0fd, 0xaa7ec16e, 0x6bf722f3, 0x38edcfdb,
- 0xe1ef3d15, 0xe016abe7, 0xbc627a08, 0xe700effb, 0x19c47159, 0xeb3ff14f,
- 0x27a40677, 0x0437db92, 0x2d3ad0ec, 0x806c18f1, 0x1fd79d57, 0x78a6b784,
- 0x6cd7be36, 0x1cf4c8f4, 0x6f778a5c, 0x153c7987, 0x3d03e1c4, 0x5f9487f6,
- 0xbe24b9c0, 0x4d27e012, 0x700b1fc4, 0xdbbac5b4, 0xaee53e91, 0x3b53a84c,
- 0xf3be00a6, 0x9fb30c48, 0xbd90defa, 0x2e3c2943, 0x3efffd18, 0xc2e7ae8a,
- 0x87871c8a, 0xef7a73ce, 0x99ff779f, 0xfbbf3ef6, 0x7ec101b3, 0xeca346ac,
- 0xea07c6d2, 0x6da9123d, 0xbb77c30f, 0x986fcc6c, 0xbbf08375, 0xbadea1f5,
- 0x0c99ca22, 0xfb159f7e, 0xa4af93ca, 0xac5d37cf, 0x3f20de24, 0x0f1d135c,
- 0x8e2e9ae3, 0xe643dfc3, 0x7c81f3a5, 0x4e98ba68, 0x77d9c33c, 0x30fc6f80,
- 0xc0dbf19e, 0x3f6c4cf8, 0xf3fa51ad, 0x3c45e5fa, 0x422ed7c3, 0x1f6b8426,
- 0xb5f6cf1a, 0xdf9d9b2b, 0x17924dbe, 0x2bc583ec, 0x82993ecc, 0x19fd3174,
- 0x16c5a5f4, 0x0b134f8f, 0xb1f287fc, 0xa9c68861, 0xcc8f6a46, 0xf68cf2e3,
- 0x7a068ed3, 0x1cf058f5, 0x9c39f9ba, 0xd7faf1d7, 0xac589fe0, 0x74d1c625,
- 0xc746f99e, 0xfbfa74e1, 0xb1b1a627, 0xde162620, 0xe409253b, 0x66acf258,
- 0x32122ff4, 0xa9fa02d6, 0x97cb4644, 0x0fa4ae63, 0x458f5169, 0xf074a27a,
- 0x2faef16f, 0x1d021d04, 0xf187bacc, 0x49ffd135, 0x17f3869b, 0x1fbe1d25,
- 0xc6efdf01, 0xe80afc57, 0xd738c1ec, 0x7bde703f, 0x5ff82bce, 0xfa7fe48f,
- 0xe5d3a071, 0x2453c766, 0xc389bc74, 0x4bb0b7bd, 0xdef1fe0f, 0x44c8ffe5,
- 0xf5f3b47d, 0x1ba7c093, 0x0c9f268c, 0x5d2ec57a, 0x03ec5fb7, 0x339c62e4,
- 0xf38e9e3a, 0xfada383c, 0x9209a529, 0xfdc77f4c, 0xde144ed2, 0xbc191b77,
- 0x5b778ddf, 0xee9113e3, 0x757d82e7, 0xb38f68c1, 0xfbe8bd01, 0x2632e3f1,
- 0x3243f005, 0x74bc4acc, 0x997881be, 0x01ea746f, 0x2e9c0bfe, 0x38ace75c,
- 0x8145895f, 0xf2f93c87, 0x078ed70d, 0xd3eb9f99, 0x730e5fe0, 0xb872861e,
- 0xd1fa10fc, 0xa31a74f2, 0x6499d3db, 0xaf284ee9, 0x771d25a7, 0x8bd79b3a,
- 0xef087d78, 0x37eac497, 0x5d3dba72, 0xbfa9fac0, 0xceff2773, 0x62cef1bb,
- 0xe71d1380, 0x5ebe03d3, 0xbe82f28d, 0x8dd6f94c, 0x7c5e8cf1, 0x55be60d6,
- 0xf80437dc, 0xc5096f61, 0xfacfdd1b, 0x13ccbef2, 0x19f657c0, 0x57ed5b2c,
- 0xbe64dfc7, 0xc72d6fae, 0x958e541c, 0xe4d8e42a, 0x10c72678, 0x7a25744f,
- 0x420d5fa6, 0xc87d20fc, 0x1b9f8ed7, 0xe9dc19a2, 0x478da979, 0x77cbe579,
- 0x86f7f105, 0x044e7678, 0xad1d393f, 0x38dfe3c4, 0xfbc79c1f, 0x6616f1c9,
- 0x32fa39ef, 0xb6d39e61, 0xbbff78f0, 0x8b1f1fad, 0x1967be81, 0x53c4e6fa,
- 0xea93bb7a, 0xc422fa0d, 0x09eb0c87, 0x7cf34fb1, 0xdcf3857f, 0x8099b774,
- 0xef866bfc, 0x589e2225, 0x7d97297c, 0x3d4f7297, 0x1f86afd4, 0x52a7d5f0,
- 0xf4c9243e, 0x563c3643, 0x1aa71676, 0x16f3c16d, 0xee4fcfd5, 0xfa8f860f,
- 0xbe38a7bb, 0xda4bc6d6, 0x0e8f014f, 0x737180e2, 0x3cc2f9de, 0x79c9d29b,
- 0xa1a3d18b, 0xbb2dcd72, 0xbb7ec3d7, 0xea06f07f, 0xbef4a7bd, 0x30a66d21,
- 0x13df7aed, 0xf681488f, 0x3d91bfb9, 0x778e7a7a, 0x62ff7575, 0xbbbfdd1a,
- 0x39c0764b, 0xd7ffdf76, 0x7f4023a3, 0xc039d2e9, 0x75f2a0ac, 0xd1f61683,
- 0x53b4f4cc, 0xcffc251a, 0x47694f7d, 0x46f1c33c, 0x33a40af5, 0xf14e0fc1,
- 0x6212e5b8, 0x159fba41, 0xea15bb1d, 0x6e4be5fe, 0x7ce63885, 0xa4ec38e2,
- 0xeeecfff0, 0x5e77e889, 0x2fc89c44, 0x1f7479e6, 0x05d3f306, 0x45f594eb,
- 0xfd3aca6d, 0x92efd222, 0x73bfd547, 0xf865707f, 0x78d1daf8, 0xd39d27a6,
- 0xcfdf6f87, 0x7cbdbfdb, 0x837881be, 0x7c8080f4, 0xd5dfc02d, 0x39021ef3,
- 0xd390125c, 0x5d373e42, 0x8f308a8c, 0xb73f7f09, 0xdffafc38, 0xe9a37ce6,
- 0x79e515a2, 0xfc04f8e8, 0xd8666a9d, 0xe9b5e04f, 0xc4f12a62, 0x3f42ea07,
- 0xc0cb8c0c, 0x2c002a76, 0xf804c69f, 0x0b03f080, 0x2240fe3a, 0xdfb454c6,
- 0xac7ae61e, 0x52fc00a5, 0xa7bc801f, 0x278f76f8, 0x12e9faaf, 0x3a97dde7,
- 0xa01d9b44, 0x283ef573, 0x07f59c3d, 0xe24fb9f1, 0xae7809cd, 0xf0619186,
- 0x73a7415d, 0x0715507e, 0xf72ffef2, 0xeb072657, 0x0e7efd63, 0xa897b33d,
- 0x2dc85524, 0xf36b92a2, 0x2b1ca83a, 0x0862bd40, 0xf68f8d30, 0xb93e474d,
- 0x80923890, 0x19f77b8e, 0xf81fd132, 0x5899e52d, 0x3ccf14cf, 0x1337d31d,
- 0xf0d70e50, 0x64e94fef, 0xe8c68dfa, 0xe2fea1d4, 0x124b7624, 0xee4c989a,
- 0xa5a2a152, 0x1d449bf5, 0x47d68788, 0x3048cdf3, 0x26ffae9e, 0xeef9925e,
- 0x06573814, 0xec0caef8, 0x65029bc8, 0x1d8748eb, 0x4b9231ca, 0xf0c1d6cb,
- 0x67348e3c, 0xd18d7f40, 0x89fd332f, 0xc60920ae, 0xbab1ef8b, 0x4cd7d799,
- 0x116730bd, 0xe3326efc, 0x75f3d7f9, 0x7ca0490c, 0x246df60c, 0xc1b7d846,
- 0xe31cfbe4, 0x54f4bc4b, 0xf52ed1d8, 0x03f41364, 0x02769344, 0xce9935df,
- 0x16b3607b, 0x1ea09162, 0xbbe0b965, 0x337f008f, 0x90c33479, 0x009f5dbf,
- 0xade96f7e, 0x28ffc0c5, 0xf3802d3f, 0xeb5db11f, 0xf05e7d43, 0x5f5f1b27,
- 0xa94fe72b, 0xfec24054, 0x7e9fce65, 0xfc8c5e6a, 0xf6b88129, 0x14da7f03,
- 0x53f9013b, 0x7ae37132, 0x156827e2, 0xa5d1267c, 0x6ad727ac, 0x23c87c55,
- 0xdd52fac1, 0xe48ddfca, 0xc907ca14, 0x1cb94ae7, 0x2e4a768f, 0x157423f8,
- 0x44f51cec, 0xb4fd78b1, 0x9aceb668, 0xbff31b04, 0xfdb8b145, 0x2101f4d5,
- 0x017ad5ff, 0xb5da5629, 0x413d368d, 0xb512553f, 0x7ea187a8, 0xf4c09350,
- 0xd03df783, 0x5f21f72e, 0x0bfdc13e, 0xaab82753, 0x77df14b4, 0x4ea391e6,
- 0x724b2e5a, 0xba5026d7, 0xb9a47e99, 0x6bd69ea1, 0x3ef922df, 0xb18e165a,
- 0xf8a76dd4, 0xecdb3b5d, 0x6beb4d58, 0x3dd48ccd, 0x97d40689, 0xda69c808,
- 0x829345be, 0xf02691fe, 0xb47e52c7, 0x4011e216, 0xda098317, 0x593f54d3,
- 0xb6e3a46b, 0xd658b7ac, 0xd58fc1db, 0x85fc0e37, 0x65888b7d, 0x3e73092b,
- 0x4773d12e, 0xd424fcf1, 0x4e255e29, 0x6df7e26f, 0xab0e7bf0, 0x3b05298f,
- 0xe9cbfd90, 0xfc0b0ca4, 0x4f2cb937, 0x5cb3a9a0, 0x39eb4897, 0x4fe81d63,
- 0x8c4f9c26, 0xe7e1df10, 0x5ce05470, 0xaf217b60, 0xb87cea0f, 0xcbe6092a,
- 0xaeee0e23, 0x58239c0b, 0x50fe85ac, 0xe0f1ccca, 0x09237c73, 0x2af983fc,
- 0xde23f303, 0x43b6f2c6, 0x76bc59b3, 0x1fb7d684, 0x5e28f9ce, 0xd332f216,
- 0x43be5525, 0xe8c8bfe9, 0x0edbb038, 0xb0c97520, 0x43cb52ef, 0x91fdf0ad,
- 0x81e277ae, 0x52368daf, 0xd6cb40fe, 0x92c38732, 0x80d6fb83, 0x2747a9ff,
- 0x0e3393e4, 0x11606b73, 0x9cd5fbf4, 0x96d6a696, 0xfb0c5edf, 0xec0992eb,
- 0x5c1ca22f, 0xc1359329, 0x8be787f2, 0x09fbfa88, 0x207fbfcc, 0x21379c61,
- 0x74f82e28, 0x7283d702, 0x8ff02e49, 0x2cfdf3a0, 0xf9775bd0, 0xbfce919b,
- 0xff9f9db2, 0x75c39c3b, 0x3e72efa8, 0x8badf820, 0x274cc5e7, 0xa7c01d4e,
- 0x01f28a2b, 0xbe563f5a, 0x34c0f90c, 0xdfdfc6e2, 0xa6f060ab, 0x7cc1d788,
- 0xf5282653, 0xca5c3b8d, 0xb55ab4fa, 0x9ebf423e, 0x74eef814, 0x46bdb2b7,
- 0x941397e8, 0xeface5fa, 0x9ca2b25f, 0xe1ba7e4d, 0x97f040f2, 0x8225d54f,
- 0xe793b0df, 0x184a74bb, 0xf9e26a1f, 0x921d4d2e, 0xa9a5df22, 0x8903de73,
- 0x8d2ef941, 0x77cb571d, 0x09c8fa61, 0xf83f779d, 0xa32c4fd5, 0x39dfa63b,
- 0x0e22f3c0, 0x51445e42, 0x73ccfe80, 0x52909f98, 0x33d1fa33, 0xd00e312c,
- 0x8a69d7ab, 0x2eb8afd0, 0xfff0acd6, 0xace55fae, 0x9fc27e82, 0xa65cf228,
- 0x3b734819, 0x641d53f3, 0x8fcc5cf9, 0xb4f6e5e4, 0x7e124137, 0xc7e835e1,
- 0xc4df9d52, 0x24f28278, 0xfa2e6671, 0x0b3b6b0b, 0x4b5fc18b, 0xb1fa12e5,
- 0x1c7609bd, 0x442eeb5f, 0xa62dd73f, 0x683f18e9, 0x5da2dcea, 0xcfd00a68,
- 0xc5dd055f, 0xbba01890, 0x4ed1ff7e, 0xdc8ffa03, 0xa06bebb2, 0xafbd7aaf,
- 0x12e92880, 0x77248f7f, 0xebbc7096, 0x17d35c2a, 0x1ef4b851, 0xfec03bd5,
- 0xe2058aa3, 0x563dc5eb, 0x1ada83e4, 0x4d7efc82, 0xd97e4139, 0x4ff985bb,
- 0xbd2eb33e, 0x9afef815, 0xaa72826a, 0xe10e36c7, 0x0f788cbf, 0xa5b8e93b,
- 0x053d299b, 0xb6bbfff1, 0xa4f5eb29, 0xfd78f91d, 0x44ba10f6, 0x56f824be,
- 0x3acbb103, 0x52ec6b88, 0x9883278e, 0x7870777c, 0x3abe7217, 0xadb18efc,
- 0xae1f6f10, 0x2c85fc61, 0xa0d7a474, 0xf2cb34fd, 0xbab01469, 0xe92ba5a7,
- 0x33e6bd47, 0x8cc73b32, 0xf9f0967f, 0x84bd7cd5, 0x6b3745eb, 0x1450a1a9,
- 0x7f6873d0, 0x74d41fac, 0xc09a29ca, 0x38f98b3a, 0xbe095fa1, 0x5e55f02a,
- 0xa5194846, 0x39139bb3, 0x3649b3be, 0x8fce9be0, 0x46412e74, 0xf7e70d8b,
- 0x8a343d80, 0x83d28f7f, 0xa3cae807, 0x7e817a31, 0x28cd4ad7, 0x47a08c4f,
- 0xe4bd72d3, 0xf2fafe46, 0xf40c8f52, 0x4f349231, 0xf80b35b9, 0xf00c576c,
- 0x15274a1f, 0xfa018989, 0xccbe2569, 0x8e82921d, 0xfadbbdb0, 0x123a5866,
- 0x1ef7dffc, 0x11260bd3, 0xefd1bfaa, 0xf4c4ff3a, 0x12d28397, 0xc7aa13a4,
- 0xe5fd041d, 0xafb30d4d, 0x406dd226, 0x128b2abf, 0x9453e3ff, 0x10f689f5,
- 0x013cc0fa, 0xbd3c3f67, 0xa4cf585a, 0xa73f655c, 0xc9445fe0, 0x25c8b2bf,
- 0x743f0766, 0xbfb05ef8, 0x5c925663, 0x8d520788, 0x4c3831cf, 0xf13ea5bc,
- 0xd7dbf73b, 0xdbf18627, 0x3db8eaf7, 0xc6b3a2a0, 0x6ce767c3, 0x147a0120,
- 0xd246e2e7, 0xf850a72c, 0xf163bf49, 0x0e811b91, 0x19945d29, 0x3be81e49,
- 0xc3f998a4, 0x7410f9c4, 0x1b6bca57, 0x240d9d04, 0x6ece8103, 0x7f4288ea,
- 0x6f408de8, 0xf90b7e94, 0x0b9e42bc, 0x2cb5bdbd, 0xa4b2be84, 0x39eb941c,
- 0xae424f40, 0x8f1c970f, 0x7a0597df, 0xf6f507bb, 0x436a7a20, 0x3d28927a,
- 0x4427bfa1, 0x55db2a5e, 0x7ef026f4, 0xe5a3eb9c, 0x85ed19a4, 0x4e4cd1a9,
- 0x3d99aafa, 0xd224d94f, 0x8c35ebdb, 0x1388aade, 0x289cade9, 0xa8d2a4e9,
- 0x91e9abac, 0xa4a3517e, 0x9bd23737, 0xd1234e9a, 0x37a040db, 0xafe32f21,
- 0x137b6f4e, 0xff33ff4d, 0xedbd285a, 0x76b92c4d, 0x6c7c137a, 0xd2a59447,
- 0xa97c7204, 0xf8617284, 0x50ad41d1, 0x8590da1f, 0xab0ee7fa, 0x37b600e3,
- 0x2ee2f6b3, 0x0ef90ca7, 0x7b782b39, 0xea12ab96, 0x3b692b4d, 0x38e4ba9d,
- 0x741887cb, 0x5c2f6b3f, 0x0cc07cdd, 0x1b0f2f7e, 0xb5f3f7bf, 0xf76d2c72,
- 0xcbe3e5ae, 0xdea12adb, 0xff8d8eb4, 0xc328e20c, 0xdbca8f20, 0xb75fbf0a,
- 0xccc1cb21, 0x8ef7a657, 0x21ddfbe1, 0xe3803ced, 0x25b8d8da, 0x04d18d87,
- 0xcfa66ced, 0x39f7ccde, 0x67db3366, 0x4cb747c2, 0xa7bf83b0, 0xd8fa83cf,
- 0x52fa9aa7, 0xec1173e4, 0x2da972d4, 0xc0f1ca03, 0xbbc064bf, 0xcd9c9d63,
- 0xe95b68e2, 0x644abe27, 0x7f110e7e, 0x75773882, 0x55f37e90, 0x8a13f322,
- 0x8236497e, 0xcc7912fa, 0x8888768c, 0x211ef98f, 0xd84f9c12, 0x148b8c23,
- 0xd39f1b2f, 0xf8c3fa8c, 0xe64e2281, 0xdfa7ced7, 0xc5fcbc2d, 0x987e70b8,
- 0xbd32247f, 0xdb8f0ce5, 0x7a97df8b, 0x077f3c59, 0xc01a4910, 0xd626f755,
- 0x2b0844ad, 0xbc03290f, 0x46cc7ab2, 0xa8ebc7e9, 0xd344bf91, 0x7080f5ac,
- 0xff3094cb, 0xf1177268, 0xae86c5c5, 0xf896bc7f, 0x087f2cf4, 0x55b8bfd7,
- 0x8443f98f, 0x383bb5f3, 0xc1e8c8fe, 0x72a7ce78, 0x7124a53c, 0x19387dbb,
- 0x0eea7c0e, 0x8d3bb78e, 0xa7263acd, 0xfe2a74db, 0x7a049191, 0xfa88a6cf,
- 0xc55db2b8, 0xeff2965f, 0xf87ae62e, 0xfe87d232, 0x1eb94fc2, 0xd313667e,
- 0xed22efc3, 0x7dec2fe8, 0x0d9de98c, 0x2f407b74, 0xbe4abccb, 0xb28cf750,
- 0xacaed0de, 0x0eb15237, 0xa87537f3, 0xf31e4ef8, 0x6a6ef6c3, 0xdbff0528,
- 0xa28f47d2, 0xe0a977df, 0x9f255e33, 0xc67ee421, 0x1eb91e67, 0x7b6a3ffd,
- 0xd4e9d85d, 0x0929be3e, 0x999690e3, 0xcc37a0f5, 0x0f796189, 0xf91f29b2,
- 0xf688d982, 0xa0be2472, 0x5e8483b6, 0x7f0fae42, 0x3204a85e, 0xe0823ec2,
- 0x5fef82ef, 0xb6525ec1, 0xec23f0ab, 0x3f1c1995, 0xe1fe2853, 0x76127f3b,
- 0x9f8632d2, 0x0875c4a9, 0x5ddef3f0, 0x6ec23f0c, 0x9276e6fa, 0x93b60e53,
- 0xad75bd84, 0xefda92f6, 0xcf5bce2e, 0xdacf6100, 0x026d9ed1, 0xddfe5340,
- 0x13c4f7b0, 0xefd02455, 0x68710b58, 0x72f54175, 0x66b57fa5, 0xc852e9d2,
- 0xae88cc9f, 0x46e017b8, 0xffd1133a, 0xec2c90d8, 0x34ff3627, 0xe175cf9e,
- 0xdb38accb, 0x29c4fc95, 0x836b86f3, 0x6d5ee3ec, 0x43d82c5f, 0xfc2497bd,
- 0x61add42e, 0xf18151e2, 0xe87c710b, 0xf7bebbf7, 0x4f73e067, 0xf13c60c4,
- 0x2ecc97c2, 0x2879b0bc, 0xe39f15e6, 0x87015771, 0x799f8725, 0x70e70fd5,
- 0x10e182e5, 0xbc93aebf, 0x6da6ed5f, 0x9fee8c23, 0xd3adf9c3, 0xbe8cf4f8,
- 0xec445c58, 0xd3dfb23b, 0xff4f7c83, 0x7dbf931a, 0x89e63452, 0x0487dfd2,
- 0x273687c7, 0xf081f8b3, 0xf93909c7, 0xe56f5e47, 0xa35a9ef7, 0x3f98fec4,
- 0xf3bc52e2, 0x1fff8029, 0x57e0fd61, 0xfc87477a, 0x10e6fc1c, 0x9952a4b7,
- 0xd742dba4, 0x6df9f105, 0xdf9f10d7, 0xc5e4c499, 0xb08b4a39, 0xe73645be,
- 0x33bdf08b, 0x86790e3c, 0xc4ceb1c7, 0xbed6b8b2, 0x7cacfefe, 0x2267979b,
- 0xbf45d1c4, 0xae8c5b8f, 0x3ede9435, 0x35ae216c, 0x1fd83e54, 0xde633431,
- 0xafb62ccf, 0xcc563dde, 0xfee31513, 0x0e7e5494, 0xd5acf1d6, 0x85ca1875,
- 0x347bca6d, 0xd41fb0bd, 0x7abed837, 0xbe2958a3, 0xeaa4a7f7, 0xdecf8073,
- 0x67c47ee9, 0xa8a47d7f, 0xdefe70bb, 0x5fc8fc9b, 0x345bf709, 0x2918f3f0,
- 0xf8b5760e, 0x3c8e3a97, 0x1e6f9c5b, 0xa6c59e47, 0x1c79b322, 0xac918e79,
- 0x73eda74d, 0xffd1933b, 0x33d634be, 0xf6471144, 0x78a37cc4, 0xdec7a0be,
- 0xec388101, 0x0e20df63, 0x3be9397b, 0x4e5ec38f, 0x5587130a, 0x025fe9c7,
- 0xc01741bd, 0x0616ddc3, 0xbeb92ab7, 0x17a0fc12, 0x8fcc1216, 0x8fd9242e,
- 0xec3d068c, 0x91788e88, 0xfa3d326f, 0x744b786a, 0xe15d8869, 0xf6268ebf,
- 0xbaa4fda0, 0x6a3a8a6d, 0x877941e6, 0x14d34be9, 0x673407e3, 0x5c0ffa2b,
- 0x3da2bd79, 0xa8a453cb, 0x51bbace7, 0x5b707fd1, 0xf43ea285, 0xfd145bd1,
- 0x28d6f3af, 0x7fe017ea, 0xc8c9af90, 0x66786ed7, 0x92fc6286, 0xf52c5e37,
- 0x7cb9b6c1, 0x8b72e56e, 0x795d9c78, 0x02fdcca5, 0x9f6fc8fb, 0xf89798af,
- 0x0a549f24, 0xeff64971, 0x87bb2c5c, 0xc58bb0b1, 0xdc758607, 0x684ef8a5,
- 0xa32ed25c, 0x9121d5de, 0xf8d0a4c7, 0x87ced2e4, 0x8ade42d7, 0xffa17f5a,
- 0xa0c5b572, 0x3e6344ef, 0xa99f5aa4, 0xa027364a, 0xd24691de, 0xe9ab5d18,
- 0x0f0fd4c2, 0x4851f7b8, 0xba323c86, 0x0a174158, 0xa1f851fc, 0x76c2eb7f,
- 0x2d35e633, 0xd2016379, 0x494521a3, 0x25765117, 0x2ae4c45d, 0x50ecc2e9,
- 0x995c41d2, 0xf0d40e92, 0x74953ab6, 0xbff4fc41, 0x7e3bc02b, 0xd46e9282,
- 0x7d222ef0, 0xd80f3187, 0xdf00392b, 0xeb2f786a, 0xbafb82d8, 0x3cb8be9a,
- 0x3917c799, 0x741f877c, 0x6e109ab6, 0xf8493f2c, 0xeedc0c03, 0xbf4a0926,
- 0x56abd098, 0x8dbd7325, 0xf2fc23cf, 0xda0f256b, 0xb871fdf1, 0x2fa65f32,
- 0x66f9ec0b, 0xae43fcc2, 0xc3139207, 0xf7f117fa, 0x0145fe48, 0xff5ca9d7,
- 0xff2c23ac, 0xf31478e6, 0xbd5c7d0b, 0x8b42fd0c, 0xd1ea3349, 0x73c66ae7,
- 0xfb07a1ff, 0x0219e1a9, 0x529d353f, 0xf904957d, 0x1aa2ef5f, 0x142726b2,
- 0xe4a7529e, 0x533dc333, 0x81e429d2, 0x5013dd9b, 0x84e857fa, 0x12bf3052,
- 0x5f98b0fa, 0x31f04fc0, 0xfc01af31, 0x540e7032, 0x2ae48d7c, 0xc7f6a2f1,
- 0x963031c0, 0xec5bc706, 0xa33e3824, 0xfc04c3f6, 0x84fed42f, 0xacc0e178,
- 0x3a07b856, 0x3f44e2dc, 0x9ae9095f, 0xff0bbf09, 0xae21fa0b, 0x887efd23,
- 0x2aea7288, 0x1e29ddf1, 0x5678ffc9, 0xc4575c68, 0x3e182989, 0x3c1d33fa,
- 0x800fb25a, 0x1decd475, 0x1474089a, 0x9c7497ea, 0x23ce857c, 0xa1e2fa6b,
- 0x2824155f, 0x5f7dc507, 0x9fb8fc97, 0x81f3893b, 0x8dddfbe0, 0x4cdc7da4,
- 0xf95307f4, 0xf3250b18, 0xb50e915b, 0x7f45adde, 0x04ee86b1, 0x048ebde8,
- 0x02b33bc5, 0x439758ed, 0x479ad7eb, 0xc2c53933, 0x3e5809f3, 0x4ffce128,
- 0xed9191d8, 0x16fae535, 0x49661698, 0xc105f7f4, 0x7586b8eb, 0xb8097c8a,
- 0x90710a27, 0xd7042981, 0xc76c95d3, 0x4fa21bdf, 0x6e84ebbd, 0xc1995dc5,
- 0x9e936e7a, 0xb760361a, 0x716064bf, 0xfea576cd, 0xf4c29d1c, 0xe070c8e0,
- 0xbb2a59f9, 0x8f7a6ae6, 0x4aeacfc8, 0xf7d628b6, 0x362b9c60, 0xc06f7e85,
- 0x92a7ff49, 0x4abe3026, 0xc43cc6ee, 0xde321d0b, 0x89bc6aa7, 0x3dc687f1,
- 0x9ea11e32, 0x17de034e, 0x0071da5e, 0x16eea5f5, 0x7ea880ca, 0x7e85b672,
- 0xe015f079, 0x246fdaaf, 0x31e4417b, 0x7ee1490d, 0x10520288, 0xf105079c,
- 0xf1b094fd, 0x27fcfeff, 0x93e73b65, 0x1c5e7255, 0xcfeda3dc, 0x65f6d16b,
- 0x47e104d6, 0xb8af8fbd, 0x73aa525d, 0x70a14f0d, 0x632ba0fb, 0x2557cc23,
- 0x034e1e77, 0x1c90acf8, 0x631b7f10, 0x0d1bf760, 0x734772f2, 0xf4379d90,
- 0x7105d95e, 0xee2bd3ce, 0x69fdc1b1, 0x4950ef31, 0xa8f0f783, 0x0ffef185,
- 0x36ee218b, 0xd69eb1cb, 0x9d981b66, 0x18bdf599, 0x5f3d0e5f, 0xfbb3d3bf,
- 0x66ecba5f, 0x67d057bc, 0x976fd195, 0x40b19320, 0xe2bd6217, 0x1df8a2de,
- 0xfe4353ee, 0x4c7df8a6, 0xbbf0df6b, 0xb14a6969, 0x187bde2b, 0xbc37d953,
- 0xbb8014d9, 0x4c6ad7c8, 0xfd05afd4, 0xeac8c7a8, 0x7a8b99c4, 0x3b230ae4,
- 0x3db8a75f, 0xb0b06a76, 0xe0e67da7, 0x28c6a83c, 0x93e61c67, 0xb01323bd,
- 0x38b4bf3b, 0x5fb8ace3, 0xc2c79b0b, 0xf9e1e9e6, 0xabde2bc3, 0xb12d7b40,
- 0x531e7c35, 0xbbd30a43, 0x8aca2feb, 0xad7aa63c, 0xea91f30f, 0xbf15ea2f,
- 0xe2e1487f, 0xf3ea0431, 0x071a0ccf, 0x1c405beb, 0x82ffa16b, 0x13c43175,
- 0x3c8897a4, 0x7c3d3566, 0x68dff1cd, 0x30ed12d5, 0xbaec0fbc, 0xfe57bf52,
- 0x5fbd8729, 0x468a48f3, 0x1e61a1e4, 0x3037b531, 0xf7eea79e, 0x7cea29ef,
- 0xe7de3f33, 0xdb37cfec, 0x77c57e53, 0x962f1a19, 0x1bc1f22b, 0xd71878e9,
- 0x2aac7178, 0x4bcf9c1f, 0x029bb3e7, 0xe0916679, 0x5b3275ff, 0x91e42357,
- 0xceff07c5, 0x9df029e8, 0xe6179e04, 0xf8f3858f, 0xf78c876c, 0xa23d9f9d,
- 0xcc35b099, 0x5c393bba, 0xe2d44fae, 0x47c1b939, 0x7cc25b9c, 0xf713f45f,
- 0x3c7dc419, 0x5576faf5, 0xfac0e7f8, 0x7e658c47, 0x2f3cf561, 0x758af870,
- 0x7c31b2ef, 0xf14abe34, 0x2c28f981, 0xcd97774f, 0x83f918bf, 0x4fe78945,
- 0x763ad992, 0xc4cfe2dd, 0xcc899cfc, 0x0f448eae, 0x7fdd58f7, 0x9a6e3d45,
- 0x48d57209, 0xb259b6a9, 0xabb79d04, 0xee0043d1, 0xa1af02b2, 0xbb63d770,
- 0x63f3f798, 0x7e7edcec, 0x61539d8c, 0xa8fe7c0f, 0xf401f98c, 0xa0a49b40,
- 0x09cffb3c, 0xde7c0b8b, 0x3ffea126, 0x4ac84ddf, 0x6de677ca, 0xe2fa63ab,
- 0x7531c353, 0x9fbf7e07, 0x547997f2, 0xcb4cddde, 0xf1546bf9, 0x08576e61,
- 0x8370bc39, 0x1b21deca, 0x3cc64bfe, 0x279466cf, 0x1cae7f8b, 0xa4db74bf,
- 0xea7be0cf, 0x4afa3638, 0x71fcfda9, 0x4bcbd70a, 0x83c82949, 0x42fa9fbb,
- 0x7c8f6b1f, 0x7e50ce1e, 0xf030683b, 0xdd96235d, 0x2f2c162d, 0x41bb38a6,
- 0xdd53e83e, 0x7bd7c0bd, 0xbaf061df, 0xc9817f50, 0x39bcb80b, 0x84b9f812,
- 0x9330cef2, 0x841f79c5, 0x2e14ec7b, 0xfb930306, 0x35fddc72, 0x5e957193,
- 0x7e118ba4, 0xca2b1ccb, 0xd00a4723, 0xe373c27f, 0x13fc0027, 0xc2718b9f,
- 0x7b97d6be, 0xc37f069f, 0xe8d155fa, 0x581a35ff, 0x7b67399c, 0xc0ec06b9,
- 0xfb4976eb, 0xd4d1dfc1, 0xde172ab9, 0xa3d93017, 0xae213f31, 0x93165e73,
- 0x093bec73, 0x801daead, 0x57b804cf, 0x3eb5d747, 0xf8c29bcb, 0x1a83d338,
- 0x257bcc39, 0x3dc07ffb, 0x321bcf6b, 0xa0bc83de, 0xd7fcf965, 0x915f8613,
- 0x0edf050f, 0x29baf7d6, 0x40d0c8dc, 0xc976fafd, 0x77c58ba7, 0x515e3024,
- 0x3497dabf, 0x6fd1e413, 0xe9ef18b4, 0x52efd75f, 0x23ae202b, 0xc94cd0e4,
- 0x5c47fcc2, 0xc44e9d9f, 0xaa17163f, 0x9d3274e5, 0x6333b1eb, 0x13e77c18,
- 0x9b8c2647, 0x1ab12461, 0x5666947a, 0xfee097b6, 0xd05674ea, 0x237c4407,
- 0xde111eb2, 0xb4f8d3ef, 0x94c7dd99, 0x24c086fa, 0x72a7c167, 0x3a37f385,
- 0xc69dc995, 0x4b8fcc21, 0xc4271106, 0x1d5f1ad3, 0x72ec05ba, 0xdb8b3443,
- 0x8464be52, 0x810e56f7, 0x5efba6bc, 0x7b144af6, 0xc7dc433f, 0xe10b38b6,
- 0x4d53637e, 0xb7de1146, 0xef87d93a, 0xfce8f420, 0x297e7899, 0x4ca891bf,
- 0xb6d373bc, 0xce94b55b, 0x3ea8d31b, 0x366beb46, 0x0b55bced, 0xfdb2e4f7,
- 0xfeb4358b, 0x58b7a6fc, 0x4ffef5fb, 0xa6f2fea1, 0xc8bdac13, 0xf5a658bf,
- 0x613e9b63, 0xa4d060ed, 0x4d97f211, 0xe87ab7dd, 0x5cad67fc, 0xf1f871df,
- 0xdee36a1e, 0x7f609aa1, 0x8ca99be2, 0x628d9d5f, 0x9166cefd, 0xef0035b9,
- 0x5ffdf0dc, 0x24f0d548, 0xc52c368d, 0x9278c57e, 0x22dc7e12, 0xbf196e3e,
- 0x86263a87, 0xf1628bac, 0xc52c4f29, 0xa1cec1c3, 0x989b5f18, 0xf370e36a,
- 0x62253be3, 0x314f011e, 0x5deef89f, 0xbe599720, 0x9e706d5a, 0x7f1cddfa,
- 0xf06b3bf4, 0xec9c833b, 0x464d66fe, 0xe28fe021, 0xa6f1cb4d, 0x7b89bc05,
- 0xb5af30df, 0x70fff900, 0xbc1f5bf0, 0x0567fb44, 0x93a6add6, 0xa7c65496,
- 0xb8b2b597, 0x07359f62, 0x0c4c69e9, 0x58a2f77f, 0x1c638fb9, 0x5aa66f0e,
- 0x01073df9, 0xbf0964af, 0x98e1cad3, 0x93521fe1, 0xfdf7cdff, 0x77cf5f30,
- 0x7c20efbd, 0x8afde139, 0x6dd71d83, 0xb1b1fb65, 0xcf4a54bc, 0x1ef3d436,
- 0x7677cc56, 0x197c6a95, 0x5fb0903d, 0x7f8e0e5b, 0x2077bf90, 0x7182f3de,
- 0x3f4c0559, 0xdc55bd05, 0x9b9e27d3, 0xb4ffb049, 0x3b7e3eff, 0xd81b37bb,
- 0x7cc5ade7, 0x4fbe169f, 0x57a7db0b, 0x78e4af41, 0x7354e65f, 0xc3f71d28,
- 0xbcbe7fbf, 0xe29f3e22, 0x0f9b879c, 0xbc2475ce, 0xf1aefc1c, 0x82a9d622,
- 0x559c3f67, 0x84f013eb, 0xf2e38df3, 0xd6297494, 0xf3a472f9, 0xbf2df59d,
- 0x35c6ce57, 0xf7e580fc, 0xae92bb12, 0x6965761b, 0xc62e7e20, 0x2ecf03e5,
- 0x3ebdf809, 0x6076e54b, 0x9088c906, 0x352e778f, 0x7f0cbfbc, 0xbd81db57,
- 0xacef9656, 0x26f407f6, 0x109cba3a, 0xeecf3a47, 0xf9528f6f, 0xb29e202f,
- 0x171814d3, 0xfaca2f90, 0xbf0634c8, 0x1f4bff50, 0x362d2fde, 0x7768bc54,
- 0x31eebb50, 0xbfc06dcd, 0xee2ae38b, 0x98f5a2c9, 0xc06ddd34, 0x2bd38bbf,
- 0xfca2c8be, 0x67a69cdc, 0xbe2a1bf5, 0x63fa86c8, 0x8c7fd67a, 0xf7e045f3,
- 0x6dbfa3c4, 0x8f406a6c, 0xb3b34d88, 0x1a9553fb, 0x5fabff7c, 0x019df97f,
- 0xd70117f5, 0x41b16548, 0x4e2e1cd3, 0xe8269c95, 0xca13c581, 0x90ed7fe0,
- 0x7cedc4f7, 0xe76156bf, 0xfbb2c6f7, 0xfefbbdb7, 0xb227f786, 0x6919dcd3,
- 0x314d5d74, 0x68b273dd, 0xfbcc757d, 0x9c92af18, 0x3f010f54, 0x6642dd87,
- 0xdd4af5d1, 0x2fa05deb, 0x461cbb91, 0xfb95c22d, 0x314de07d, 0x5e57bf0a,
- 0xe97dcdfd, 0x582e33ec, 0x07ce48c7, 0xfafd5e9a, 0x3673882b, 0xc039359d,
- 0x73b23e2d, 0x6fa03dd3, 0xf37cec8d, 0xd987266b, 0xeeb10f7d, 0xa3d7e091,
- 0x187597bf, 0x3b23fd70, 0xfd045baf, 0x33a1fd47, 0xa6e4e807, 0x6056be53,
- 0x5efbbd0b, 0x1fde574e, 0x798aecfd, 0x4de3118c, 0xe89f1e02, 0x1499e809,
- 0x7833371e, 0xab7cc25c, 0x6b63c49e, 0x2b97a8fd, 0xbd50d3ef, 0x17a6e31d,
- 0xfc03b448, 0xb35ee2f8, 0xb2785fda, 0xfe8fee9a, 0x5d1f537e, 0x3cde9041,
- 0x3291a2e6, 0x9cbd4092, 0x4af51558, 0x7fa2aa63, 0xd14b2595, 0x3ae53e3e,
- 0x7b44fb45, 0x293ea2a1, 0xffa2a477, 0x45728e6d, 0x89b2f6fd, 0xced5fe8a,
- 0xd0bd456a, 0x3fe8aed7, 0xb28748fc, 0x019138fd, 0x1d27450f, 0xf92ca007,
- 0xc76e89d8, 0x07cd33d2, 0x25f91ca0, 0x5fda8703, 0xf6c5e37a, 0xf0bbf003,
- 0xc7efaa97, 0x34e9ff08, 0x87d5e4d9, 0x68a693f7, 0xf25e7969, 0x35913f23,
- 0x2d8c7eec, 0xe02f7dd6, 0x198fdc4d, 0x8a52fe03, 0xe7b9aa84, 0x59f0bdd9,
- 0x12765fcc, 0x69fc0310, 0x7cfd19ba, 0xcfcd7527, 0xbdc599ff, 0xbbdf0007,
- 0xb156afa9, 0xdd1731ef, 0x93977d8a, 0x2d3c2a65, 0x2cabd457, 0x1ff4503f,
- 0xd14ab29f, 0x90fed13e, 0x2b0f4f0a, 0x3639b7ea, 0x45b4f0a9, 0x28dfa785,
- 0x70edfbda, 0x157abfee, 0x1cb44efc, 0x04aaefed, 0xa67cdc3c, 0xd651f10f,
- 0x780956d5, 0x3b64f1ba, 0xe7d8abe2, 0x597604aa, 0x00f9a47a, 0x7f6a3e94,
- 0x5ad7b8c1, 0xd83cb052, 0xd5ff4762, 0x2c5c96e1, 0xf038b48f, 0x94b7dff7,
- 0x8b56f961, 0x6cffcb13, 0x57658099, 0xf6cb0b8b, 0xbfec7696, 0xf983a5b3,
- 0xdffbe2bf, 0x7e001815, 0xbf8d1e81, 0x3c56ee11, 0xe434d8f7, 0xfed13d9f,
- 0x26afa81e, 0x9636de77, 0x81e78d32, 0xcc9d8089, 0xcee9a3cb, 0xbf94e9d1,
- 0xac1c85ed, 0x41fe4092, 0x0859c6bb, 0xb4e1f87a, 0x0ed13f05, 0x5581e420,
- 0x958b14ae, 0x8eb48dd5, 0x643186c8, 0x199c4fc1, 0x25105e74, 0x70584c18,
- 0xa37bd41b, 0xb4defb58, 0xf279b705, 0x637107fe, 0xe17e4867, 0x7130b4e1,
- 0xd8cfe7e3, 0x39cfe0cd, 0x19a86976, 0xfb8c71e0, 0x50a49cb5, 0xe5968f37,
- 0xc81d42da, 0xbd2a93d9, 0xe4539444, 0xde61b7f2, 0x0ee38d76, 0x45be6fcc,
- 0x6b7e8047, 0x8aef6624, 0x99d3db7e, 0x9b7bd0bd, 0xe3a9ed01, 0xbc22e71a,
- 0x3df52717, 0x49ee7001, 0xa9ca3efb, 0x265f735e, 0xed3bafc0, 0xd89eac7b,
- 0x08e484f7, 0x7c18ebaa, 0xf7bb4fde, 0xd9cf86bb, 0xf85092b4, 0x5859a6f4,
- 0x1ce7c0dc, 0xaf007a80, 0x3676af1f, 0xdcac9c60, 0x71f61839, 0xe76065cc,
- 0xfbc665d7, 0x2ceb4413, 0xbfc823b9, 0xc3ae9753, 0xa2e15371, 0x6739f81b,
- 0xd5ce78c8, 0x9d287cf0, 0x27481fd9, 0x8f4e6760, 0xb8e0bb41, 0x5737dd86,
- 0x9d267ff7, 0x1173d9c9, 0x0dfd83de, 0x94c57b87, 0xd377e786, 0x44577af9,
- 0xaebdd4e1, 0xf58fa8a1, 0x9f784b36, 0xf34cf7b7, 0x706ed679, 0xdc609070,
- 0x1ffc2672, 0xf3be7f6d, 0x91febf9e, 0x457f7ff6, 0x8865038c, 0xdf847ae5,
- 0x7679de0c, 0xa7f511bc, 0x2a0335d9, 0xe4ce2e40, 0x6639b071, 0xc386126d,
- 0x3c3d56b4, 0x54d0b89d, 0x904296b8, 0xd6a84e2c, 0x4b4553c3, 0x85af9633,
- 0x0f41aef2, 0x9f09e1eb, 0x6b1dbcfa, 0xa06d8d41, 0xf904b847, 0x0b68ff9f,
- 0x95dcd75d, 0x73d99db2, 0xeb3aae5c, 0x871e51be, 0x3ce3dfa0, 0x010286af,
- 0xd367d5ed, 0xfb7f8525, 0x61af0e59, 0xcc7f5ce9, 0x1eecf927, 0x609c7f51,
- 0xeefb9c38, 0x448747d9, 0xdb282388, 0x2ef8feb9, 0xfd56e77f, 0xeef883ee,
- 0xc7ef1c73, 0x413294f5, 0xe4c19c9f, 0x17ed4140, 0xfee84bab, 0x1a2d3a0b,
- 0x6dcfd38c, 0xb8780dd8, 0xa8f1c1d0, 0x9e701d23, 0xbde678a6, 0xaa4d398f,
- 0x9357a17b, 0x4b2e8e97, 0x2cbcb065, 0x832abbf6, 0x5f5965e5, 0x45c8255b,
- 0x2d7d1f21, 0x6e3f394b, 0xb07a3e46, 0x0fd62565, 0x3cb078b7, 0xf38eb2d2,
- 0x7f6c36e3, 0xce51e5ab, 0x1f9cbd8f, 0x77bf833f, 0xf962d4b6, 0xcb1b8b6a,
- 0x33dce307, 0x3e226e00, 0xc6e8d539, 0x9b43d1bc, 0x5fe2040c, 0x980d3a17,
- 0xc44f4097, 0x40278f13, 0xef018dde, 0x6ff3a9f5, 0x9fbe7cd4, 0xb7df421e,
- 0x189e9c58, 0xfa033794, 0xf4c8c0e2, 0xcdd88c74, 0xedfe97c0, 0x0f9057f1,
- 0xcddbb31d, 0xa4b74fa0, 0x38bca277, 0x759bb4e6, 0xbc79eeb4, 0xedbbb593,
- 0xafad0366, 0xdac7df4a, 0x1473763d, 0x7c7eafad, 0x12f76b1f, 0xf83f220c,
- 0xc7c86bf8, 0x107489ca, 0x31a547ce, 0x17152c6b, 0x1f975e54, 0x3e317384,
- 0x3858de65, 0x3d725f17, 0xd57da27d, 0xca4fa841, 0xab85a2dd, 0xe1534edf,
- 0x9157181a, 0x7185ad50, 0xaf963363, 0x06e37181, 0x1e0dac3d, 0xc76f2137,
- 0xeadfa81a, 0xfd05a2d8, 0xc7ce4bf4, 0x2ea23cc4, 0x169f05da, 0x3ac360f9,
- 0x0a0f285d, 0x0f285c3a, 0xa62a5c04, 0x7e003f56, 0xc90ea6c7, 0xa63ac122,
- 0x71c1fd4a, 0x846ba5c8, 0xbf2922f7, 0x8efe98de, 0xd71d1579, 0xb11bf504,
- 0xa65593fe, 0x6f7f94ef, 0xdf230f4d, 0x0ef3f04e, 0xbbf21ef2, 0x3bd9e84f,
- 0x5c035f1d, 0x9b9ef04a, 0x24b5df19, 0xe3fa336e, 0x3d833641, 0xb69e7204,
- 0x1965e70f, 0x6453fb97, 0xcef876e7, 0xc3f9918b, 0xabfcfccb, 0x68444dee,
- 0x4f61fce7, 0x4bd985ba, 0x06875dfc, 0xd07e86d2, 0xa997e5ab, 0xf9d5a1f3,
- 0x59ff2216, 0x4f515f9d, 0xa1307bd8, 0xdeecce79, 0xb39e486e, 0x19a2abb0,
- 0x5e05ad3f, 0x78f8e943, 0x0957cf3a, 0xabc9c385, 0x3864e1c0, 0x87ec8438,
- 0x2eef3178, 0x74c6ff24, 0xdeacf11c, 0xb2277117, 0x3f8936f7, 0x5d04feec,
- 0x8dafee84, 0xe0cb5fc1, 0xb3bbf54f, 0xb9aae780, 0xab7e0266, 0xc7f3fe60,
- 0x351ff02b, 0xf8aefb5f, 0x0db9b4e5, 0x5080fdec, 0x1c39763e, 0xc2f7131f,
- 0x53d0a5d5, 0xe41a3ee1, 0x343bc201, 0x4befe760, 0x80674776, 0xf7d1567e,
- 0xd0ec0695, 0xf37ef604, 0x9cdb9b22, 0xe922e141, 0xc8817e59, 0xf1a33dc3,
- 0xb6f416fc, 0xc9e6cdb4, 0xb0832fa8, 0x4ac767a0, 0x7e3fe0eb, 0x878aead6,
- 0xafd72471, 0x3a077e0f, 0x7a699e52, 0xa17f9306, 0x5fe45125, 0xfaf96ef6,
- 0x8a2fde9a, 0x792a8f04, 0x41ee1fb4, 0x418b285c, 0x112dd9f9, 0xdb3fbc1f,
- 0x7a849e5d, 0xbd00f74b, 0xdaefca16, 0x301eee2e, 0xdb57e704, 0x65a9ddc7,
- 0x71ddf646, 0xd0eca013, 0x079d1fbb, 0x0691e0fe, 0xcdbc938c, 0xc7270ff3,
- 0xb7c3fcb0, 0xc980fdf9, 0x004a5e1f, 0xf65938f9, 0xa1481525, 0x1bf77676,
- 0x05ec2ab3, 0xdd36f6a1, 0xefd858ef, 0x976eecd5, 0x6006cbb1, 0xf5dfdb55,
- 0x9022bf2b, 0xe56a3de7, 0xe3f90225, 0xbc7b73ff, 0xa4f5132b, 0x9533e4ab,
- 0x415b79f5, 0x897318ff, 0x228e39e5, 0x9525ce2c, 0x9bf2c9bd, 0xdbb6a978,
- 0xbda868e7, 0xa76a1d9e, 0xa5fd92cf, 0xd421ef50, 0xd809cf5e, 0x374ec2eb,
- 0x45bf9610, 0x3806f7ed, 0xddb9e717, 0x8f13314e, 0x7c3f2179, 0xc87dce6f,
- 0x9f30a217, 0x8f8ef9e3, 0x7fad6112, 0xc5fc4ae9, 0xbd00f62b, 0x22be5937,
- 0xf5fa79c1, 0xc120bf2b, 0x7375bcef, 0x8e9b773f, 0xffaa43dd, 0x8a728ca7,
- 0x8075b5ca, 0x9af27aa7, 0x7920eefe, 0xabffda4b, 0x28c3de1f, 0x3586abff,
- 0xb4f5bc81, 0x7ed2764c, 0x223edcd5, 0xac76f91e, 0x32927b73, 0x289ed646,
- 0xeacbbffa, 0x13ff4403, 0xbbf49d93, 0x9da2a9d5, 0xd78ebf8f, 0x6c76ee89,
- 0x0df312cf, 0x6b337565, 0x72f8cb6f, 0x8231e832, 0xe0cc6fbf, 0x47bf91f2,
- 0x63fdf944, 0xcc578919, 0x73b651bf, 0x1fde2079, 0xc4e1faaa, 0x6e70a398,
- 0xb5cc25db, 0x875fbfab, 0xb673fbfe, 0xf7e082f6, 0x8e9e454a, 0x798cd2ab,
- 0x0d2f0d53, 0x22740add, 0x81278f9b, 0xe3c5d2de, 0x09b255f1, 0x36172ee3,
- 0x491ebe30, 0xf2bc5bef, 0x42be0515, 0xc0fbf9da, 0xdfa49818, 0x6493ff3b,
- 0xa0f33ef6, 0xe80bcc2e, 0xde0c7ce0, 0xc37b847b, 0x212bff22, 0x5ec13887,
- 0x8a39784e, 0x71f953bd, 0xc5dbf217, 0x767f332f, 0x2803a6c3, 0x76cbe6df,
- 0xc89d27f4, 0xf00abf76, 0x0d7731e9, 0xcaf838c1, 0x3f5d7157, 0xdc785bb2,
- 0x182f2fab, 0xe143879e, 0xc0abfbff, 0x4afff7ff, 0xfc82eff8, 0xbb73e032,
- 0x4dbed0a3, 0x0ef5fad6, 0x649e6b88, 0xe79e5cef, 0xfaed2b70, 0xf815df10,
- 0xd3b30667, 0xdc583ae2, 0x8965e446, 0xc333feef, 0x1e74eccc, 0x79a8691f,
- 0x47c4346b, 0xc4c6fe04, 0x77f07690, 0x38383c53, 0x07801c1e, 0x9c40ef01,
- 0x0acb8e84, 0xb0aed79e, 0x23dc050f, 0x7d35639d, 0xe3ab7588, 0x0e997706,
- 0xef7e0096, 0x847986fa, 0xb0b4cfdf, 0xcc7eb4f9, 0xf011fc13, 0x1e00c4ca,
- 0xef940375, 0x46bc5180, 0x22b9280d, 0xffed95de, 0xc35778cb, 0xf3d65d4d,
- 0xf7fa9838, 0xff3403a1, 0xbffc70ab, 0xdd9d5fe6, 0x3ed15fbc, 0xd71be577,
- 0x7e157fe4, 0x1f957fd1, 0xf5ff9236, 0x16ee992f, 0x2fc9bba0, 0xfc40d12e,
- 0xffbdf6e6, 0x8b013bc8, 0x5e303bf7, 0xcbdf0f74, 0xf6ffa317, 0x9e947dfe,
- 0x7e6668be, 0x3ffb53a9, 0x43f3d9d7, 0x45f663e9, 0xe8833899, 0x77caf66a,
- 0x669f2074, 0x5c22cd53, 0xa70d6a7c, 0xa127cc27, 0x48d6a07c, 0xfcf40974,
- 0xf7b2d6d7, 0x10216ba5, 0xe7d2c363, 0xb593eda6, 0xc7ef07c4, 0x3eb49b56,
- 0x9487c603, 0xfc0d61f7, 0x686a597d, 0xcac5ee2a, 0x9ef3194e, 0x716328ee,
- 0x76a619a5, 0xfd38dfbc, 0xf7f3eac8, 0xe35dd9c1, 0xba796129, 0x9fd27ee2,
- 0x5e24df34, 0x37e406b4, 0x1e259ff8, 0xc3ae5c87, 0x5c7aa438, 0xfe7600ed,
- 0xcb12cb26, 0xf2c3d837, 0xa479c4d7, 0x28623bfb, 0xf0f37962, 0xb3756ace,
- 0x00b437ce, 0xa8fd8ff4, 0xad95347f, 0x353c002a, 0x303e958d, 0xc0f40414,
- 0xa25f95a6, 0xc7e6a37e, 0xfd5af2ea, 0x1cb7ef50, 0xfa117a41, 0x1f16a9e2,
- 0xa97ed5d6, 0x8c7e6359, 0x5f919c71, 0xd470bd32, 0x1189e725, 0x6f6f6ff6,
- 0xd84b3b09, 0x4e3b6a5d, 0x5ef10bf0, 0x0b00fb5c, 0x77c6bb93, 0x5a8ffbd8,
- 0x4034be56, 0x5f057729, 0xef767ca5, 0x4a5fe400, 0x87c41bfe, 0xc55ffdb1,
- 0xdf740387, 0x4dff00ec, 0x6f7b066d, 0xf5f74d5d, 0xaa7e4c29, 0x94ae5de9,
- 0xd3519f51, 0x3bf3a0bb, 0x7fd05b9d, 0xd2c60b37, 0x926acc75, 0xc9d59ef0,
- 0xd7bc1e97, 0xddd09748, 0xe29d33fe, 0x486fbc3d, 0xe072a1f7, 0xbe23b463,
- 0x5d201cb5, 0x33feecd1, 0xa84f47c3, 0xc0a0bd1c, 0xbd1ca84f, 0x5fc4aff0,
- 0xf9cffd98, 0xf0907276, 0xc8bb7f3c, 0x6b239ff3, 0x26dcf7d8, 0x790a0796,
- 0x765ebd68, 0x56696c2f, 0x4d7fbe1b, 0xe058b20d, 0xc9f6cb23, 0x778b3d64,
- 0xde835368, 0xbe26ea2b, 0xe0494777, 0x9bf9624f, 0xf7b3464b, 0x9a79d43e,
- 0x91b3ff22, 0xb4cbbb8f, 0x54788f4b, 0xe62443bd, 0xd443bf51, 0x67fc7a38,
- 0xf7e7ff18, 0x0fefd58b, 0xf9e4ca0d, 0x88a4459f, 0xccafc7c5, 0x5e407aa7,
- 0x7b8df906, 0xbda0b52e, 0xf4399793, 0x01193c3f, 0x8665177c, 0x99a5d7e8,
- 0x94b3d657, 0xfa62ffed, 0xf0dbcd90, 0x4a6f913d, 0xe72c861f, 0x38b75824,
- 0xf9e7fd27, 0x679e0315, 0xef713ef1, 0xbdf1e7f2, 0x09afde8f, 0xe6ae87c6,
- 0xcdd3199f, 0xf4dd03ae, 0x4cd5b7b1, 0x94ea3ef1, 0x2304fd07, 0xdef1bb8f,
- 0x9cb788dc, 0x0a4c8190, 0x5864ba0f, 0x841bd0b7, 0x0be0111e, 0xcf0b7efc,
- 0xfe56b8f7, 0xdc4bfff1, 0xe9b3dc43, 0x4e4af9d1, 0x13defc80, 0xef1df615,
- 0x2b9a99d5, 0x60f9ffbe, 0xe0357b9c, 0xbfe70a69, 0x2ad01de2, 0x7bdbbd99,
- 0x3f464ba1, 0xfd1f8ac5, 0xdb8fb7e1, 0xeb57e743, 0x2f964d67, 0xd247ae50,
- 0x2c349bd7, 0xd2a8beaf, 0x605af98e, 0x42df80ff, 0xfdd431f8, 0x7e2bd90f,
- 0xf776899e, 0xac272ee8, 0x9eb651e7, 0x5a6af848, 0xbf0a5ff9, 0x37efa449,
- 0xccb12bed, 0x7f1f3a0f, 0xfd0494cc, 0x06353e5b, 0x74ad7df0, 0x0ecd7ff1,
- 0x8f132c98, 0xbe70e544, 0x257a65e4, 0x2ce5fa61, 0x1ce585d2, 0x9ba587d2,
- 0xf9eabcb0, 0x42e581c4, 0x65d3cf7e, 0x0991bf77, 0x1f5d55fe, 0xfe7b53be,
- 0xe1e7bfa5, 0x8f37503b, 0xa95c836a, 0xad9fcaef, 0x0b7aafd6, 0x0d38fefb,
- 0xbfeec7f8, 0x0f51da67, 0xb377b6b8, 0xd3ce71bd, 0xddfc6199, 0xb32e59ff,
- 0xee97157b, 0x5a4def65, 0x363218d8, 0x2574fb11, 0x09f9e167, 0x2de4cdf0,
- 0x5c426f82, 0x0d03ff2b, 0x932fcb8b, 0x7505eff0, 0xc47835f8, 0x796517f2,
- 0x62efa865, 0x560df9ed, 0x717904af, 0xfb58a323, 0x5dfe2b72, 0x8fc4d9cf,
- 0x3c2e72e7, 0x3dc32b65, 0x0b963b09, 0x54d4fbf8, 0xe896cee3, 0x469d45f8,
- 0xfc4dcf96, 0x05bf6083, 0xb1849f60, 0xf206cb77, 0xe3367438, 0x542ac3f7,
- 0x0fce05fe, 0x3315ec1a, 0xe172d206, 0x48192740, 0xad987ee9, 0x20cffd6b,
- 0x86b7606f, 0xcfafbdc0, 0xe300fe46, 0x2fdc622b, 0xe83a15ec, 0xf2c482f7,
- 0x0cfb3d8e, 0xa4d4bde2, 0xcbbd3f60, 0xfd03195e, 0xa8b6146c, 0x2b80451f,
- 0x572abdfc, 0xe44c7b18, 0x1d030db1, 0x0485fd11, 0x417a25df, 0x819cf562,
- 0x4d7dbe3f, 0x3d30fa1e, 0xc2fe87a0, 0x7d80ceee, 0x6213d30c, 0x92fff582,
- 0xcd21afdf, 0x5f0f1099, 0x034184f2, 0x547bc67a, 0x833dc31c, 0x167b533f,
- 0x2ed4d3ca, 0xd42ff285, 0x03f2852e, 0xf942976a, 0xa14bb511, 0x10b1745c,
- 0xbe2224de, 0xd862ce81, 0xa83b888f, 0x903f9bd7, 0xbb06cdc9, 0x1d62867b,
- 0x8eb8f4fb, 0x3f5dac17, 0xc75d19fd, 0x6907bb0b, 0x244bbee0, 0xfbeef478,
- 0xfe95e65b, 0x7f888d3e, 0xf107dba8, 0xd2ec17ef, 0xe82fdca2, 0x0e2ec7f0,
- 0x503157ea, 0x77f3e38f, 0xf30b1c7f, 0xe1fa58f7, 0x56e894ea, 0xbd586b27,
- 0x845e57e2, 0x39dd836b, 0xcf4bf603, 0x4fd838f7, 0x7e1fc741, 0xe83af70a,
- 0xeda718fc, 0x8236fa95, 0x87dea67e, 0x5f62df7a, 0x61ebff74, 0xb3bb0bfc,
- 0xdf942761, 0xf65e7610, 0x437977b1, 0xf70abbf7, 0xafa1bb73, 0xdc2bee18,
- 0x9b0e597e, 0x2f60da27, 0xc57f7847, 0x38fed0f5, 0x812ba71c, 0xae7b6faf,
- 0xf111f3d5, 0x50f001ee, 0x4ba3c83b, 0x560fa0b1, 0xc76678f3, 0xe36f41ae,
- 0x322397fd, 0x385fbf81, 0x773ca6cc, 0x1278e13f, 0xbd3efe65, 0xc2f5f00b,
- 0xc1074fbe, 0x3f14a07b, 0xc9efe083, 0x60e068fe, 0xfe7dfe45, 0x031fafc8,
- 0xf1fda1fa, 0x274e15ef, 0x6e20aa5b, 0xffb8d33f, 0xb6696c10, 0x882a83e5,
- 0x914dcfdb, 0xcf39430e, 0xe20e359e, 0x79df22f5, 0x61f96e41, 0x3ab74a38,
- 0x2b8f51aa, 0x2412e607, 0x318d2a17, 0x216051fc, 0xf515e287, 0x8ae929f1,
- 0x39ed13fe, 0xb949f68a, 0xfbda2837, 0x8638a1ef, 0x06cf7e07, 0x4365f478,
- 0x83ee8d1c, 0xa7b57dfd, 0xca77cc64, 0x96fc7ddf, 0xf27d681b, 0x7be077d3,
- 0xf6f02f6f, 0xf12b3bc9, 0x52f59bef, 0x22a9ea78, 0xa1eca675, 0xc9833f8d,
- 0xfd42f654, 0xc30f27be, 0xd8dfd0bb, 0x2760885e, 0x97a611d4, 0xd417b246,
- 0x9be50276, 0x39be053f, 0x16a9a5ec, 0x617f0fc8, 0x2069d7e4, 0xe40fb697,
- 0xfb7066ef, 0xf4fd1221, 0xfec9139f, 0x29fdf076, 0xbf88fd35, 0xc9ca2d6f,
- 0xa13dd8c7, 0x3ed7ca6f, 0x7686be01, 0xafdb87b9, 0xcff954bc, 0x6f1de986,
- 0x9efe03df, 0x94dc32a3, 0xb5bfbfe8, 0x0e5ffe18, 0xb8593dd0, 0x04d481e5,
- 0xfa03ddfc, 0xa7f72370, 0xeb90367d, 0x1ffbf553, 0xb40e2d48, 0x281f1593,
- 0xa5fb93fa, 0x9afa8ab5, 0x437d652c, 0xf1e0daf9, 0xc5b1f491, 0xbbd3ce8f,
- 0x9f9ee1f3, 0x3aeff614, 0x8127aff6, 0x4b7d87f3, 0xba7edf90, 0xbdfe197f,
- 0x46ff7559, 0x01f81f3a, 0xb3904717, 0x974d4f82, 0xeac23bd9, 0xef8abff6,
- 0xefdbbe39, 0x8f6147bd, 0x332f5e79, 0x9c5efbf9, 0x13a0af5b, 0xf9eefb3b,
- 0xe8ff0f4d, 0xed2b882b, 0x79d57661, 0x051f932b, 0xc0d33ebb, 0x161e8bdf,
- 0xc0abe8cd, 0x3dc0d7e2, 0x7e06ff9a, 0x00334c2b, 0x0000334c, 0x00088b1f,
- 0x00000000, 0x18adff00, 0xf514707b, 0x7bdbdbf9, 0x79724b92, 0x71211240,
- 0xc220572f, 0x4849ac91, 0x92ea4903, 0xf03ea410, 0xa2a21900, 0x799e0fae,
- 0x2a93a84a, 0x028d361d, 0xd6d36d52, 0x4f4e2a2a, 0xd1954a2c, 0x2562bc34,
- 0x40569478, 0x2f2a7b1d, 0x419cca69, 0xee421923, 0x8cc38a8c, 0xbf7dfa1d,
- 0x5eddcddd, 0xc9a75502, 0xf6fbbf1f, 0xcfdef8f7, 0x05048af0, 0x571a0192,
- 0x02a62a26, 0xc8dc8280, 0x00b5fb71, 0xbb4c6176, 0x94e00b3d, 0x157004c9,
- 0xa5029fd0, 0x30276100, 0xf0efdd38, 0xbdbf423d, 0x225f1c91, 0x9e5eef7e,
- 0x77dc2323, 0x4055a560, 0x5dfd12f8, 0x361b5d17, 0x709563df, 0xd480197f,
- 0x0fb91ce1, 0x1d300ad0, 0xe7f015df, 0x32a3a458, 0xe784db92, 0xf716faee,
- 0x2412fc55, 0x828f9d20, 0x76048f4e, 0x15798f80, 0x0624279e, 0x8df3c49f,
- 0x22b07847, 0x3810033f, 0x8ec7077e, 0x004ab339, 0x814fd396, 0x815877be,
- 0xc005bf67, 0xefb42bef, 0xdf97cbcb, 0x6f084904, 0xf286f4b1, 0x4970fbd8,
- 0x90e30343, 0xaadced7e, 0x9d5bb7bf, 0x78c9feb4, 0xff1e01ae, 0xb5fbc782,
- 0xd7ef6410, 0x7b7dc0ed, 0xf5f97ecc, 0x0dfbd39f, 0x0af78cbb, 0xbef4c485,
- 0x0a03f4a9, 0xb3ecf12f, 0xb6adf089, 0xf9aaf8ab, 0xb1bc3f6f, 0x837af918,
- 0x69f86d17, 0x64c4df68, 0xd98fe2f0, 0x91aca428, 0x8cdc6c72, 0xe145a48f,
- 0x5cfc7dc1, 0x47379d3f, 0x1b4fe672, 0x44906f29, 0xb561c913, 0xbab7c54b,
- 0x80059be2, 0x9b7756f8, 0xe02bb801, 0x1083c8d9, 0xdba0a783, 0xa33bf3e6,
- 0x2a5d87f4, 0x5fdd058f, 0xaaf2cea7, 0x01d12b6b, 0x405e2aed, 0xa67a41bb,
- 0x47496071, 0x139f307c, 0xac72e1b7, 0xe492a33b, 0x80838c74, 0xb89ec850,
- 0x2df48ed5, 0xefa39f54, 0x1fc5484e, 0xc2667999, 0xcbd340b3, 0x2f77d2c2,
- 0x516f7872, 0x4889a2f7, 0x75df1c01, 0x1cd431ef, 0x0c3c152c, 0x2c5062df,
- 0x296397a4, 0xa466ecbe, 0xddcf1e73, 0x1c12f3ed, 0xff10e019, 0xae048ab1,
- 0x3fef638d, 0x7cebef42, 0xb2f8b31d, 0xb35f189b, 0x37a87d5d, 0x5fc29a4e,
- 0x8f29184a, 0xd0cd5ca8, 0x5797eba7, 0x59ec86dd, 0xd7e6afdf, 0x1d31bace,
- 0x5c04b8f5, 0x16fba436, 0x610c0d1e, 0xdfe6cb78, 0xe03126e6, 0x5f2819ef,
- 0xf44a982e, 0x2d0584fa, 0x68cfde02, 0xd39835f9, 0x5667e462, 0x8fd74efd,
- 0xf491cf2e, 0xf9abf8a8, 0x7c84a0f2, 0x98e76d0e, 0xaa88351d, 0x9f94369d,
- 0xc462c3fb, 0x45e410df, 0xefa9e90e, 0xe492703a, 0x03aeb1d8, 0xce8016cc,
- 0xad6c5d75, 0x7c033bb7, 0xd98fe33e, 0x838d09af, 0xc1a55bf8, 0x74775f8c,
- 0x1c7fca3f, 0x3032cbbc, 0xf802e70c, 0x13bf7d93, 0xbf359f90, 0x62d8f2f8,
- 0x794376a2, 0xb207f30a, 0xf4a3abb9, 0x9c015817, 0x5b647f48, 0xc32b7f82,
- 0xa27eaa23, 0xfeff6dd9, 0x719a2749, 0x0b1dffbf, 0x1583db33, 0x1cfe0f4f,
- 0x12db35e1, 0x53fb9c98, 0xfda2c941, 0x0afd93ad, 0x8a6e581e, 0xdc9334f4,
- 0x6dc5133b, 0xf3f9ffb8, 0x81dd5f93, 0x2757caf0, 0xf926448a, 0xdf845091,
- 0xefa011b3, 0x3dd8b33b, 0xcbbc5590, 0x5fe4ff34, 0x729bf69e, 0x4d397fda,
- 0xfeba3c24, 0x90ef3ece, 0x35f5e500, 0x685df204, 0xa538e782, 0xd70f84cf,
- 0xe69c769a, 0x36ad3ed0, 0x75e92779, 0x397fb3d5, 0x54fc865e, 0xd3f37cbd,
- 0x95be9033, 0x7a058d1f, 0x11d7aa27, 0xe42920f1, 0x51e038a5, 0x9f2680e3,
- 0xff0eedda, 0xa57131a7, 0x00c523be, 0xf9657637, 0x47898d3f, 0x18caa0b5,
- 0x1f98e7ee, 0x35fe69d5, 0x20df978d, 0x4843d47d, 0xb110938d, 0xf2155d92,
- 0x2171449c, 0xc98d84f2, 0x3ecede3f, 0x2ecc4c10, 0x53204ceb, 0x034c2f7c,
- 0xaff9267b, 0xfc2fcaac, 0x9bade4c4, 0x42fd3650, 0x93ffeeaa, 0xb58b4c16,
- 0x37869ecf, 0xdb373ec9, 0x380e7d98, 0x3c67f980, 0x290b7f9e, 0xfb32fcec,
- 0x861fcc57, 0x45cb4bf3, 0xc0c51730, 0xee28905e, 0x4509b615, 0xacdae00f,
- 0x964a65e9, 0xadfc442f, 0x9eedf8ea, 0xb73c98f7, 0xf08a783c, 0xfd32761e,
- 0xdcaa7bc1, 0xc4d41cc3, 0xf665a9e6, 0x7bff342f, 0x7dcfe0c1, 0x97c89ccf,
- 0xddbefdf1, 0xed01f353, 0xd83e5ef9, 0x67ca1cf7, 0xfa783130, 0x0f3b5c61,
- 0xf28e387f, 0x75bd3c62, 0xe01a5f2d, 0x478d4e01, 0x7e07c475, 0xbbeb913f,
- 0xe181f640, 0xde87c584, 0xfc98d34d, 0x326f79aa, 0x6fdc3fe9, 0x4e9e2fa4,
- 0x3e9d7dfd, 0x9cfd7dfd, 0xebeaadd9, 0x9f9835bc, 0xcc9fdf8a, 0xefac1811,
- 0xe60a4f9f, 0xbbe938a7, 0x8a973d4b, 0xd5bd8c70, 0x6fd44fd0, 0x37e31d8d,
- 0xc35357d2, 0xbec06d89, 0x713f142b, 0x5fb8c80d, 0x26a6f997, 0xd1d9f037,
- 0x766916ce, 0x6669e906, 0x82b73bca, 0xb48bd76a, 0x743b7df8, 0xe5fd0058,
- 0x67f5a9a4, 0x3a075c76, 0x63916f7e, 0xca72afe3, 0xf7ea6974, 0x254abf8f,
- 0x3f1c51e4, 0x3ab272ef, 0x339ba267, 0x90d973b3, 0x5f70e74d, 0x281da00c,
- 0x0db1369d, 0xdf7991e9, 0x57bc6e35, 0x93e40d67, 0x64f7e81f, 0x07df665e,
- 0x9196f7b8, 0xc81cc1be, 0x8a4ff567, 0x3bac3815, 0xa0c563c2, 0xbe50f284,
- 0xe2571606, 0x02d865e3, 0x47489d35, 0xfdd77d05, 0xb8a4ed11, 0xe9d4d4ca,
- 0xc65e251c, 0xbd3407c1, 0x9a99a715, 0x8ff1463a, 0xe91f68db, 0x5e0e836b,
- 0x7f355ff5, 0xc6726996, 0xd6c7cf84, 0x5c5a0d33, 0x15d9270f, 0xdb2fe91e,
- 0xb8407a87, 0x40381ccc, 0xb43d7a2b, 0x42673ea0, 0xcbaf7d40, 0x6729bf18,
- 0x78f9612c, 0x33238b2a, 0xe7aef535, 0x68f4809a, 0xeb857ca7, 0xd3c82e26,
- 0xb08813fa, 0x99970255, 0x5b3b1456, 0xad8f8367, 0xad89a073, 0xad9da173,
- 0x5b074037, 0x5b20826f, 0x0da04a61, 0xeb5ffc58, 0x0c3cc3ea, 0xa26e5d3f,
- 0x18bc5c7c, 0x87f3469a, 0x2ebc9ab5, 0xea8c0f2f, 0x1e5c3f25, 0x64ce4073,
- 0x2e4e5d74, 0x9d98f213, 0x91b172eb, 0x073de23d, 0xad6933f8, 0x877b1080,
- 0x99de925c, 0xe0998205, 0x5c18902a, 0x51e51dfd, 0xb2cd921a, 0x54b91477,
- 0x8f276e8d, 0x9171726a, 0xea8d8f0d, 0x605baf6b, 0xcc37aeb0, 0xff1499d0,
- 0x7213ea47, 0x84e2ce88, 0x0c052fca, 0x21f77e11, 0x6be3199f, 0xb3655171,
- 0xf74ee107, 0xe3199f49, 0x65597168, 0x6ac44591, 0xdf63f5b3, 0x4765846c,
- 0x1fa03e52, 0x3bc831d9, 0x87bc3e50, 0xfa54d287, 0x7ca7e39e, 0x101fe369,
- 0x07654fc9, 0xadd59040, 0x17e45568, 0xaeef357e, 0xba7aa971, 0x4b3f26d9,
- 0x0f6f587e, 0xc3c80924, 0x0cead69a, 0xac1b87ca, 0x8c9fbbea, 0x89bea615,
- 0x1e21b172, 0x2f94617b, 0x081c57dc, 0xb9a13887, 0x47a51dc5, 0xf01dffc7,
- 0x784af9fe, 0xafca650f, 0x09bf29b9, 0xc61beb22, 0xb3bb796b, 0x97c44cb3,
- 0xa3170e90, 0xa9389423, 0x26dc85b9, 0xde97b7cb, 0xf6aa270b, 0x7b6c97b6,
- 0x75ed747a, 0xd3ddbb4b, 0xb70f7e47, 0x8027b37e, 0x433f86ef, 0x5def78c4,
- 0xce8fbcb7, 0x39429a35, 0x5f97a845, 0x92b69c26, 0xcaf6e83d, 0x209692a1,
- 0xf8126ddf, 0xca0fccad, 0x9675c35d, 0xe1ef6a27, 0xca1ef8a5, 0xabe7d8a3,
- 0x4a0fb2c2, 0xd20e9a6a, 0x57b72a5a, 0x39e10ee1, 0xf236f442, 0xffa46591,
- 0xac8f94c1, 0x9c7f319f, 0x169ddaa0, 0x1ff7baa7, 0x0abc7879, 0xdfc620fa,
- 0xbc5ff71a, 0x8f8c2ff0, 0x914e438d, 0x7bed978e, 0x7dea99a6, 0xcab0cfdd,
- 0xdd11c433, 0xd97666ef, 0x773b3c02, 0x5f3a52cd, 0x878f51f1, 0x3d75efe2,
- 0x832a36a1, 0xc627ddc3, 0xd7aff6ab, 0x3f70dfe9, 0x6e7c4f24, 0xa6487b47,
- 0xa7ca8b3c, 0xef37683e, 0xab7f21b7, 0x60d07ea9, 0xf6abf185, 0x58ff7a95,
- 0x561fe47f, 0x19f03bea, 0xa95df885, 0xcb62bfd1, 0x5d91377d, 0xfb1bf4ad,
- 0x6cafbd41, 0xf6d5ced4, 0x1f13d7f8, 0xe78ddbb5, 0xccafa91a, 0xeb0cfaa7,
- 0x75d50f31, 0xaa5bfb71, 0xd8d95f58, 0x1ffefc65, 0x2495f637, 0x81bf2d60,
- 0xd72e4756, 0x4e7f10ce, 0xfd59e7d6, 0xf56de436, 0x8ba2cdf3, 0xc8a76ce0,
- 0xf5d1ebe2, 0xb61e7b10, 0xd15b31a4, 0x46e575fd, 0xc3c7d58e, 0x364bdffd,
- 0x7828e889, 0xbdd58329, 0x7ab3af58, 0xd9881d03, 0x86ca016b, 0x3d7bfb43,
- 0x426b9225, 0xe777af3c, 0xff4f5489, 0x67049d75, 0xf4fa512c, 0xdf9abe7a,
- 0x3ea56551, 0x93ec7ee9, 0xef210ec8, 0x37bc72e9, 0xfc05b0fd, 0xaa043fb8,
- 0x9ace863e, 0xf33e5d58, 0xe49e4ec8, 0xfd518fcf, 0x026996d9, 0x0e1e4621,
- 0xa3080c61, 0x4d36f5f4, 0xa979097f, 0xf144fd86, 0xe4fdc32a, 0x7ec35cd2,
- 0x2b69239b, 0x0a4501e1, 0x8e284b7a, 0x48a4efab, 0x20f70c53, 0x5fb8ff84,
- 0x437189ae, 0x64c39cd2, 0x15ce15cf, 0x3690de6c, 0x9e78d0b7, 0x5f13cb5f,
- 0x87b833b6, 0x657f957c, 0xe675e836, 0x7e9e1180, 0x10921db4, 0x39a8e3af,
- 0x00a16e6e, 0xc13625d5, 0xd5ca5df8, 0x4c0262ec, 0x861bcc30, 0x961ceee5,
- 0x0945d92b, 0xf720c8fc, 0x1ea1b978, 0x3434dd58, 0x422a29c1, 0x7d630f54,
- 0xd467f946, 0x259fe518, 0x7e3de51b, 0xd9de5185, 0x5f79464d, 0xab9462dd,
- 0xcdca315b, 0xe1a671b3, 0x4af6c4fc, 0xf3793c03, 0xd7f3860d, 0xe01817f8,
- 0x376fdba9, 0x71d69f9c, 0xa0bf61af, 0x5f61956b, 0xd9cbb3b7, 0xd581b5c1,
- 0x0266f671, 0xa0ec15d3, 0x0643f0e8, 0xff7af17c, 0x12aaf831, 0x47a5ce51,
- 0x48c2de51, 0x1484703b, 0x6f1878a0, 0x57faf107, 0xaadff4e2, 0x93f793e5,
- 0xee4e3ece, 0x8f412f3a, 0xa0bcda7f, 0xb1fac2dc, 0x55690a7f, 0xcb567489,
- 0xaf2d3e6b, 0x644df6c1, 0xa973e024, 0x0f1418b0, 0x3c2b1c52, 0xbb22abe9,
- 0x1d350e2c, 0xe4a0f644, 0x32557b6c, 0x7040979d, 0x4b47538d, 0x5296fe74,
- 0x72b1cc0e, 0x8f366742, 0xa171ca8b, 0xe327cad2, 0xfd6fb2e1, 0x54ecc96d,
- 0xcfa7c33a, 0x3552b87d, 0x1c97cc6f, 0x47918e60, 0x4f9ea945, 0x5d5e8cbc,
- 0x089cfaee, 0x52b07deb, 0xfbb26fbd, 0xd5a3dcdb, 0x9e66e237, 0xab325fd5,
- 0x32710ec7, 0x6add1f9b, 0x7d90e60f, 0x5f90c99f, 0x317cc5c9, 0x56051268,
- 0x36a171bf, 0x8c4c2a62, 0x6e52f251, 0x9f512f9b, 0xcd2aed86, 0x8bf21727,
- 0x465e2be7, 0xa2542bbe, 0xb7f4c5b6, 0x99de5727, 0x739e794b, 0xbbc22fad,
- 0x973ccfef, 0x9fcc7943, 0xf7a2ed2c, 0x1921e787, 0xd9c617c8, 0x48504990,
- 0x1c43ca04, 0xd1ce2feb, 0xfc623323, 0xe585a376, 0xadfad02b, 0xe939353b,
- 0x0d12d6fd, 0xb13e2f6f, 0x9df8e302, 0x3c98875d, 0xb407336a, 0x7449ad3e,
- 0x4df7fbe1, 0xbf521670, 0xa8915209, 0xff7ae9f6, 0x3eff9e35, 0x57ef5579,
- 0x36be772f, 0x07d0dfb3, 0x51b48ec3, 0xf3f18de7, 0xeadf28ac, 0x258fbdfb,
- 0xfbd3fcb0, 0x1f9b3658, 0x641fdf46, 0x9b3b8173, 0xc7d8303e, 0x1b1f2ddd,
- 0xe51eeeec, 0x287ec313, 0x8f19623d, 0x64f687fc, 0xe503b9cd, 0xadb77e77,
- 0xd450fa84, 0x4c6e7f57, 0x627a1c9f, 0xf7c26cf2, 0xc73cf9bf, 0x1759e8e8,
- 0x9d34f364, 0x4eebd3cf, 0x2eb43832, 0x3e78d6c4, 0x5f55bef5, 0x3c837fad,
- 0xc227ea33, 0x9b47118d, 0xd479d4c3, 0xd667beba, 0xc3ca4ab8, 0xb356d93d,
- 0xe1524eba, 0x0abb52ac, 0x6b4b99cf, 0x48dce2d8, 0x070f6b7d, 0xd0f68712,
- 0x9785d57b, 0x7744f8ac, 0x50f56c86, 0xb9195a5d, 0x482b7340, 0xe379b10f,
- 0x41d954d2, 0x062c39df, 0x9d1952b3, 0x383fa893, 0x035e526b, 0x2f25018c,
- 0xf53e71fe, 0xaa498301, 0xf8be27dd, 0xe9057cdc, 0x97c5257e, 0x0a40f74c,
- 0x94e76359, 0xfa859cfa, 0xc253ea62, 0xf0cd750e, 0xcc8f8c70, 0x478a75b8,
- 0xd3d7578d, 0x9af5ef8a, 0xe47126da, 0x80dacf0f, 0x07e8a7e6, 0x4317d512,
- 0x1faa6cfb, 0x70920198, 0xdb6eccff, 0xe3cf640b, 0x5faa6690, 0x7d635ab0,
- 0xb65be141, 0x7d09c500, 0x11ee933e, 0xfbc5e57e, 0x6c2d7be9, 0x2898300e,
- 0xd77f9094, 0xf5601d27, 0x595c89d7, 0x15f9b0f2, 0x7a3f1448, 0x6eb6d8f7,
- 0x3991e752, 0xafff120b, 0x0f12b873, 0x6a4233eb, 0xe1cda95d, 0xf9abbe74,
- 0x43df19c7, 0x7c406d9b, 0x7c1a5f9e, 0x4ee6cbca, 0xd9d10e62, 0xd6e9526b,
- 0xd3f9d5e9, 0x73be88f9, 0xe7d5bb65, 0xd779d149, 0x07e44986, 0xce754728,
- 0x2f7773c7, 0x7dfee518, 0x7cb2beba, 0x558f88f3, 0x2dbcea4d, 0x07f6f7aa,
- 0x8ede914f, 0xbb1c5938, 0x3e78fddc, 0x611ff7eb, 0xef3e40f2, 0xf862fe22,
- 0x9989e25c, 0x3eef9e0b, 0xf85794f1, 0xb385fce1, 0xf878f9d5, 0x02398b85,
- 0x77dfafde, 0xc9d924e8, 0x6e3c1cf0, 0x831b6d8e, 0x68ea657d, 0x0acc6bf3,
- 0x4d92f531, 0x6cc13fbf, 0x9f218fbc, 0xfc8bacfc, 0x5d89eb11, 0xf9421f5a,
- 0x9eb6e292, 0xb1d9772f, 0xe2df454f, 0xb8b36f42, 0x8ec9784d, 0xcb0a73d7,
- 0xa15cfa5b, 0x44bcc38d, 0x599b963a, 0x76afe73c, 0xbba7648a, 0xd482f6d0,
- 0x04a59ad7, 0xeb8e3f36, 0xe4dbd76f, 0xd65ec947, 0x4199507c, 0x3be76ffd,
- 0x957d6837, 0x6ba64f9a, 0xf09d39f6, 0x64de1f13, 0x358a5796, 0x4dec4afa,
- 0x3321d53c, 0xf9d5e140, 0x788f3681, 0x8fd66dec, 0x775717fd, 0x1c70ea99,
- 0x00001c70
+ 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x7993331e,
+ 0x31e424e4, 0x1e4e1081, 0x03086820, 0xb78a8884, 0xf6301027, 0xd57876d2,
+ 0xaf0e2d58, 0x6b86f210, 0x7fb6bd2d, 0x78490806, 0x111fc1a8, 0x29e1d5ad,
+ 0x311d82f6, 0x0388b622, 0xbdabd228, 0x557c5837, 0x0bd11feb, 0x2a44908a,
+ 0xe5b5ef6a, 0x3ef6b5ee, 0x09939cc9, 0xafdb7b04, 0x7cfdffff, 0xc7ecee9f,
+ 0xf5ed7bd9, 0xfdad6bda, 0x8131c918, 0xe4230da4, 0x06fbfc22, 0x109d9221,
+ 0x9d37a132, 0xd72120e3, 0x66924218, 0x92ddfd2f, 0xbadc4214, 0xa349bfe2,
+ 0xe4febba9, 0x5f5f9a1a, 0xa4aff0ec, 0x4d1f5b4d, 0x2d096a78, 0x2fa1efbf,
+ 0x7cd04fc3, 0xad79ecfa, 0xce7eb4c5, 0x5d0fc924, 0x10ab1a1d, 0xd8e7ed02,
+ 0x520176c2, 0x9097e581, 0x927fa130, 0x45f8e8af, 0x9fe8b884, 0x37fe9724,
+ 0xa5b21c89, 0xd1e43e60, 0x99029ea0, 0x31364846, 0x7e6055fe, 0xf509fc36,
+ 0xd0677744, 0x779e75ef, 0x7fec13e5, 0xdb0a5f8e, 0xf27347e9, 0x4dc87203,
+ 0x6d08c6d3, 0xfb1dc749, 0xf908395d, 0xe4990cc0, 0xd8b68763, 0x0fca6ffe,
+ 0xd214754c, 0x080b67fe, 0x49d9f9ff, 0xcc82da36, 0x3be1eda6, 0x1a1f4e22,
+ 0xd99f67cc, 0xe0dfb8e8, 0x40dfdddf, 0x5fc0a7ff, 0xe5a1094b, 0x9e0c1ccb,
+ 0xc5d9d9e4, 0x1989ce30, 0xbf4316d7, 0x3213a673, 0x9d4d5688, 0x4490f63d,
+ 0x891aebf3, 0xcddb4edf, 0xcf1c0d29, 0xcbf8d981, 0xe80293a7, 0x60ee8e97,
+ 0xffc45f7d, 0x64ef38eb, 0xcc3fde3e, 0xfa102b1e, 0x8a97f641, 0xa0725da9,
+ 0x4bd153f9, 0x2d056a48, 0xee53191f, 0xd09a769f, 0xe6e9e4f2, 0x721340f6,
+ 0xc425211d, 0x1aea7293, 0xc91677fa, 0xad4228ba, 0xee8c0b6a, 0x4a6b0fe5,
+ 0x22f9fdff, 0x12fa01d0, 0x6a1fd6fb, 0xa0e9e99c, 0x7b375af8, 0xf4d08796,
+ 0x0f2cc0f5, 0xd9f5efe0, 0xd68f10b3, 0x676673f6, 0xfb5e0227, 0x06feef1b,
+ 0xfa08d03a, 0xb5b3c73d, 0xea48907e, 0x39fbf423, 0x31c3d13a, 0x9301dffd,
+ 0x0964254d, 0xb34d1b30, 0xd2a6d525, 0xe88d6cfa, 0x95e33891, 0x3b69b102,
+ 0x28994992, 0x0ff352e3, 0x2637bb61, 0x71c34ad9, 0xef0773e6, 0xb81a55c7,
+ 0x6fa50e67, 0x751274d6, 0x2912ba51, 0x75e2c6aa, 0x1a548a5d, 0xddc7038e,
+ 0x68425e1c, 0xe1c0cf7b, 0x02d86571, 0x47329fd0, 0xf5c2c40c, 0x42678003,
+ 0x4ca24a6f, 0x18f8e6ee, 0xfbbf72fd, 0x338f506c, 0x8e00bb8f, 0xecaa9009,
+ 0x0c8f0e3b, 0xb201937c, 0x43fc8296, 0xe02463c2, 0xb91eccfb, 0xe5070124,
+ 0x17f0a18f, 0xa42dae15, 0x1412d47b, 0x47ec56b2, 0x0324a4f4, 0xde1157bd,
+ 0x4f51290f, 0x42157e51, 0xd78b84ab, 0x129e6a5c, 0x35f06539, 0x193ba9f0,
+ 0x5e1cbfc7, 0xe518a048, 0x88d43152, 0xe307c078, 0xed4df92b, 0xbacba502,
+ 0x947ee5d1, 0x90218a6f, 0xe17e4333, 0x3bf457df, 0xbdccff37, 0xca91d29c,
+ 0xd3396b91, 0x2cdf8a8f, 0x8e92eb67, 0xc82008b5, 0x0f49b964, 0x40241210,
+ 0xeb6f0377, 0xbc78a2be, 0xfb5bbf04, 0xe7c86fdd, 0xc9983260, 0x053f9327,
+ 0x79bd07fa, 0xf0077ed3, 0x5edf3af5, 0x5d6bcc07, 0x7a825efe, 0xe8c7d38a,
+ 0x5daf95d7, 0x81d6ce52, 0xee808d7c, 0x9ea748c3, 0xc6a7d1f2, 0xa6767e02,
+ 0x748bf72a, 0x08933b7e, 0x6b75d9ea, 0xd02b7848, 0xb5e594b5, 0xb5e1696f,
+ 0x9d3b8e74, 0xd698bebc, 0xed06bcd3, 0x3adbbea9, 0x68870b49, 0x8d8b6b7e,
+ 0x85ab1fb5, 0x311f9a45, 0x8a148491, 0xc2c56d4f, 0xbe5a4e95, 0x17eaa375,
+ 0x34fd5eb5, 0x2d6725a2, 0xdeb2dfb4, 0xbdf00aa6, 0x3b23ad8f, 0x443849f3,
+ 0x39b1dfc7, 0x69239bf9, 0xf9b2143e, 0xf24fd387, 0xd945faf8, 0x022844a5,
+ 0x9c3a31b4, 0xae5c7921, 0xa9e50204, 0x7ecb7cbc, 0xa48ebfff, 0x5d363df0,
+ 0x45a0aff2, 0x4ccfd63b, 0x769e28d0, 0x3f048168, 0xc0f07f4d, 0xccefcc7c,
+ 0xdd00260c, 0x9f9c6e76, 0xc0f14c00, 0x461b99e6, 0xd2617b41, 0x6ce91d61,
+ 0x1f47ffd6, 0x00ec3a28, 0x9e994b38, 0x7e0d6a4f, 0xbcf9a253, 0x89b91249,
+ 0xadcf214e, 0x1fdbdc21, 0x4f5811b2, 0x8b6de8fb, 0xcdd44ebe, 0xb4eb5779,
+ 0x5d7f818f, 0x2009160f, 0x86353bda, 0x923741e7, 0xbeec8af0, 0xc85cefe3,
+ 0x5d2913ea, 0xbf2e0e80, 0x96675962, 0x4756f85a, 0x3c717079, 0x1c755ab9,
+ 0x897a488f, 0x578bd690, 0x62469ffa, 0xf07ae9f0, 0xe9f58128, 0x8163e78a,
+ 0x7ca05d27, 0x9cab830f, 0x1c1eb9ef, 0x6357caf7, 0x21b1f1e3, 0x7fa01eef,
+ 0x6177c522, 0x50eb0424, 0x0a24617a, 0x57c9e2fc, 0x9a0bb034, 0xc5c93109,
+ 0x7cfbd1a1, 0x1337201d, 0xaf583e22, 0x837e8dd7, 0x81568fc9, 0x6fe630f8,
+ 0xb7e4f7b4, 0xc1fb5893, 0xf87287a8, 0x697853ce, 0xcb87bb39, 0x847f4f59,
+ 0x732447ad, 0x4f75c21c, 0x5e7561e1, 0xc84c7d1c, 0x97cb940a, 0x817ae049,
+ 0xedcddea6, 0x6c06a751, 0x7900dfae, 0x910240b7, 0x134ddf38, 0x42d27ad8,
+ 0xe9a05d74, 0x162f44a3, 0x664b9d70, 0x2eb2d7fa, 0xbc9fd1f5, 0x16e9165d,
+ 0xd468df40, 0x8734803e, 0x23cd31f8, 0x92474c01, 0x26af4c56, 0x49f34c11,
+ 0xa405a63b, 0xaf43531b, 0x422a89f8, 0xfac4c47e, 0xa4e720c9, 0xe58b63da,
+ 0x3264d0bb, 0x3cce3eb2, 0x73782d9a, 0xf8ebf890, 0xe75f021d, 0xfc8aa648,
+ 0xf17af843, 0xe818b06e, 0xfc2854c5, 0xefccdbbb, 0x0ebe24e2, 0x693dea38,
+ 0xdd335780, 0xcd54548d, 0xf06d5a7c, 0x1c2444a9, 0xc41f32c7, 0xd6b8cc63,
+ 0xfb7356fe, 0x9c9f98c6, 0x491f23a2, 0x50cf666e, 0x71bdf438, 0x0828d1f0,
+ 0xab419e7c, 0x29b23adc, 0xb6494bbf, 0x6b9a5ac8, 0xe8764f74, 0x893f2f38,
+ 0x7ceb6747, 0xbe2af0ac, 0xa9b3c181, 0xcb0a9e07, 0xc297fa3a, 0xfea64ff3,
+ 0x1db24ca4, 0x86a20bd6, 0xbc56de70, 0x42def9f6, 0xd2e4fe8f, 0x57d66991,
+ 0x02d78a4a, 0x069f8587, 0xe37c7f68, 0xe47fea4b, 0x211bfac3, 0xa9ec2a41,
+ 0xe60101f9, 0x1a40ad7f, 0xc85e2913, 0xa0eda268, 0x6af5cd70, 0x698b8ecc,
+ 0x91f41937, 0x74c90b66, 0xee92cfbe, 0xe43ed023, 0xf41d9127, 0x6df367b3,
+ 0x7d695ba5, 0x63b69faa, 0x1e4005fd, 0x0b6d1dae, 0x9fd1b940, 0xf5329e4e,
+ 0x112efd47, 0xe836e1f0, 0xe4c3f163, 0x1fb436b1, 0x6fa27c95, 0xc75f2389,
+ 0x1d157cb9, 0x9eb0ea71, 0xb094cab8, 0x8ffa1b33, 0xb53e4314, 0x5d61f89a,
+ 0xe6cdd49f, 0x30e1c651, 0x59fa9de6, 0x6a7e0040, 0xc03b31f7, 0x3fd04855,
+ 0x74da3254, 0xb4dd1ff0, 0x7e42f50e, 0x50531754, 0xd83fa23f, 0x5f3d9e1f,
+ 0xd00bed3d, 0xb9d47d7e, 0x92be076a, 0x9fa0e9fc, 0xc8568f57, 0xf8bdfa60,
+ 0xfff63b3b, 0x1862a7b9, 0x47cf9989, 0x0bb1d10d, 0xa670c1a9, 0x67a618e1,
+ 0xed31da1b, 0xd30b786c, 0x594ae9fe, 0xebceda8e, 0xc0d7e27e, 0x3f0f101e,
+ 0xc00f3447, 0x5c75d51d, 0x12a21c17, 0x82802eb3, 0xd36fff06, 0xdaf0bcd8,
+ 0x086bc46c, 0x67d54de6, 0xe0367878, 0x9e000a5b, 0xc2223887, 0x77867cd2,
+ 0x01d03fc0, 0x3c8e8bca, 0x5cf102b7, 0x9e02c64d, 0x0ca4c937, 0x13e03cf4,
+ 0x827d89d6, 0x03800eed, 0xfe69f3f2, 0xc1fa8ffa, 0xf78659fb, 0x9e29978c,
+ 0x4b494e00, 0x8eadc664, 0x913b95f2, 0x27d7120b, 0xf9927abd, 0xbdf6bdd9,
+ 0xcf00eff6, 0xac894696, 0x68a6bc85, 0xf7b7114a, 0x15824a41, 0xdcdfc1d3,
+ 0x28fd3e56, 0xe2b90bd8, 0x5a648757, 0x3a5eb43e, 0x4f2311d9, 0xfd746559,
+ 0xb0c276a4, 0xecf2e6e5, 0x074f3990, 0xb7347f40, 0xc43e5cc5, 0x87aef5c6,
+ 0xad1e4078, 0xe8b65af3, 0xd3fd7157, 0xea240d55, 0x02f26396, 0x1791a7c3,
+ 0x423b13bc, 0x46cb7e74, 0x4c038c11, 0xb3f5b1b7, 0x7ca3be15, 0xd74f2f71,
+ 0x5231fa5b, 0x46dba269, 0x193d30c6, 0xddba7d6f, 0x46ce3c56, 0x4db06bfb,
+ 0x72a3671e, 0x042292e4, 0x5b9777ec, 0x93f9e3d1, 0x8e126dd3, 0xebb5209f,
+ 0xfbab8522, 0x4adfe23a, 0xee4cbef1, 0x2c7c828e, 0x21fcd62b, 0x30fe4750,
+ 0xd51263ca, 0x15f66261, 0x700253c1, 0x6c4a7850, 0xfb044e38, 0x0738a6e9,
+ 0xcc997dfb, 0x4a365dfa, 0xf6376823, 0x3655e703, 0xd80ce119, 0x34fd0904,
+ 0x1555974e, 0xa34df739, 0x9f554ed9, 0x2667fd05, 0x78c16705, 0x7e6fb946,
+ 0x1963fa29, 0x2bf4ccc3, 0x0167d477, 0x2206547f, 0x4e7f80d3, 0x926c5f7b,
+ 0x36b7bce9, 0xf144bf10, 0x702b9eff, 0x7357f41b, 0xb008fd7b, 0x5e06df7f,
+ 0x3b2a0098, 0xa5ac7a80, 0xa25fa564, 0x148972e5, 0xca3f2995, 0x25bf0f13,
+ 0x2a1a4017, 0x938b3886, 0x477d33d4, 0x35224bf5, 0xf5231cbd, 0xa27e218f,
+ 0x72d03c80, 0x60256f55, 0xdba8380f, 0xef863270, 0x1e734c94, 0x7cd8fa6c,
+ 0x72e37a7f, 0x27e79829, 0x09fe0387, 0x49dde9da, 0x26927fcc, 0xde000bfa,
+ 0xa6ffaf7b, 0xc4fcf006, 0x67f93366, 0x5a4d7f56, 0x79696ffe, 0xfee26810,
+ 0xd5fcb4b6, 0x80f1bcb4, 0x979c5697, 0x9432ca63, 0x24f0050b, 0xbf07f932,
+ 0xe41d67be, 0xcf5bf878, 0x572f58db, 0xf835bc37, 0xa720e1c3, 0xa43f831d,
+ 0x052d59c4, 0x3e42ff91, 0x1c28b5f0, 0x098f9992, 0x62134f78, 0x18176e52,
+ 0x5a9c9bf6, 0xdc947488, 0x988ea9d2, 0x8fc0ddf5, 0xc1ddfcb2, 0xf4878e1f,
+ 0x78ad4c6d, 0x0120a455, 0xd768d03f, 0xe018b713, 0xe234effa, 0x1fc479a9,
+ 0xa47338a5, 0x7a6a78b0, 0xf30a285e, 0x09fd5272, 0x233dd3eb, 0xf0c56b5f,
+ 0x3b0fc581, 0x3f20ad94, 0x61b68cb4, 0x7865b35c, 0xf90290e4, 0xd1406a0c,
+ 0x5dca677a, 0x4c6d8821, 0xe37c63cd, 0xd4f5b3f4, 0x7e8c3c35, 0xbdbfa198,
+ 0xad5e1f1c, 0x67b3f51c, 0x31ded9a2, 0x2b2701d6, 0xdb36f4a2, 0xa694ce51,
+ 0xbe82c54f, 0x9b539a7e, 0x69e51a76, 0x233fb9a4, 0xe36ed1de, 0xc96b8bf1,
+ 0x593768b5, 0xe1fd12e2, 0x71f86bcd, 0xdcbcd913, 0xfc1849d3, 0x5189f4e6,
+ 0xcfd79bc4, 0x9bd866f0, 0x9bbf3e1e, 0xfc04234a, 0xf3f89ebe, 0xeb6f0ccd,
+ 0x7fa28baf, 0x29ec7eb7, 0x85bd67b4, 0xce3f261d, 0xa1ca1ef8, 0x76c4fcfe,
+ 0x18f6a1a8, 0x23711bcb, 0x19e9a78a, 0x61ebbd69, 0xaddbb72b, 0x92275374,
+ 0x4763d062, 0x8315a747, 0x84b7bede, 0x3cab4ec2, 0x6297587a, 0x7ef2adf0,
+ 0xdf867cd4, 0x7cd8cb7b, 0xd3f47b69, 0x93989def, 0xf266e304, 0x7f11b0f8,
+ 0xebcbf1ee, 0x284f78cd, 0x2d85c4b4, 0x67eab77e, 0xcc4b52f4, 0x5f39abe5,
+ 0x57a7222b, 0xe8ce192a, 0x4f3e3035, 0x84bcf832, 0xdf3279f1, 0xd12f4837,
+ 0x921d010e, 0x4dff994a, 0x4df37e2c, 0x5e8c1d29, 0x00c88f37, 0xa9fefc3f,
+ 0x97663edd, 0x7126ba30, 0xc6efbc7e, 0x71c80211, 0x40268972, 0xc33e727d,
+ 0x13c53253, 0xa5c977ac, 0x4ef6efcc, 0x525db0d4, 0x0b5ba309, 0x5fe14c7c,
+ 0x898a7403, 0x5b4b3b1f, 0x6b7fa075, 0x741d4ef1, 0xe1c53259, 0xd4cf0a20,
+ 0xd81b0a52, 0x805fb49d, 0xc51853d7, 0x49525ab8, 0xfca5d870, 0x82a2427a,
+ 0x10f887cd, 0xe94b686c, 0x7e58253c, 0x20b26268, 0xa7ef7ed0, 0x80f1c07c,
+ 0x8f173c71, 0x785fdfa3, 0xfddcf512, 0xc8364df0, 0x1cebf6a9, 0x36a5279a,
+ 0xf707f83f, 0xf108e697, 0xbcc6e7e2, 0x2acb83fb, 0x35f812c7, 0x9572fc31,
+ 0x16dee3c8, 0x22475dfe, 0x57c82e6a, 0xa5f76f48, 0x830feaf5, 0x65e47aff,
+ 0xfecbe312, 0x87a189f4, 0xb21824dd, 0x1fd5f765, 0xdef8ce92, 0x7940179e,
+ 0x24ef03eb, 0x8a52afc6, 0x9136fcb9, 0x5e867fdb, 0x140792d1, 0x00a12727,
+ 0xd72277ae, 0x02da4f4f, 0xf054c50b, 0x4eb8c3bb, 0xae74c8b8, 0xca9f1937,
+ 0xe6a6ff9c, 0x4ae2bd33, 0x9776b089, 0x903aa78d, 0xa834d6df, 0xc65a1fa8,
+ 0x439ed5de, 0x7866b0f1, 0x73be1f93, 0xb9196b8c, 0x3cdbf68d, 0x2b70797c,
+ 0x30fdc00c, 0xac22bfd4, 0x8d5f8c83, 0x0e03307d, 0x61d21992, 0x7e09cc9f,
+ 0x2467e011, 0x24905fdb, 0xeb8fb512, 0x4795df1d, 0x6967cde1, 0x0dc19f28,
+ 0xb6ebc9fe, 0x6f9c2ae0, 0xa2946b7e, 0xc99bce9b, 0x42216acb, 0xebcc225c,
+ 0xb21e7c72, 0x9f8ebe31, 0x025df7f6, 0xe1c4d3ec, 0xdb22dddf, 0x472d59a7,
+ 0x7e085088, 0xf289ed1b, 0x6a6ceac9, 0xa381c797, 0xd56bf391, 0xc3f8672e,
+ 0x89ab7e18, 0x75f29924, 0x1fc233fb, 0x7711fac6, 0x514fb80a, 0x4358d1cd,
+ 0xcf00b23a, 0xf61a29ef, 0x48eb6b57, 0xe9177c83, 0x78025b4e, 0x8b8f0310,
+ 0x5277fd74, 0x90b8c4be, 0xd6eb607b, 0x81a7f0e5, 0x4085d10c, 0x0fa9e4cb,
+ 0x178e9879, 0x69e307dc, 0xd2bf2b2a, 0xf5f0e371, 0x4d7cb10b, 0x6a5957c4,
+ 0x147f6be5, 0x129ddaf9, 0x9fb77ac5, 0x8fc1b5f1, 0xad1f9c89, 0xbf8c687c,
+ 0xd6afc79e, 0x335f3e72, 0x708549a1, 0x9b51dadf, 0x2ce69e30, 0x7c015cda,
+ 0x25aa32de, 0x64de7c0c, 0x17df35f0, 0xdb2efea1, 0xa35ad31f, 0x72264eb0,
+ 0xeed456be, 0xeb7b9006, 0x38935d7c, 0xbe0534bc, 0x5f39b806, 0x93f807bf,
+ 0xae08ddfd, 0x076bd7c1, 0x45bad7cc, 0xfed39b6f, 0xc2d927fc, 0xf1891ed7,
+ 0xd7c067e7, 0xb30a4f00, 0x963edc63, 0xdfea7eca, 0x06e7e9c7, 0x6b99f989,
+ 0xe5ac1cb9, 0x1fb6b072, 0x223ff839, 0x9afe03f3, 0xc98b3072, 0xe5a24381,
+ 0x8cae9389, 0xd3b0251f, 0x9e7bc8e3, 0xe1b5fc24, 0xbc4334de, 0x27fe3c72,
+ 0xbe84cd30, 0xcfd234f4, 0xe4c0e744, 0x73c98f3b, 0x76be727f, 0xfe387c68,
+ 0xa7f46453, 0x26922ef8, 0xffbe395c, 0x7215705a, 0x43f0367e, 0xb728c582,
+ 0x3a667a31, 0x86a92bc0, 0xd304799e, 0x28ad79a9, 0x81be86a7, 0x2bfa0a58,
+ 0x3bc62b6a, 0x68ad999c, 0x98f3399f, 0x24fc31be, 0xb88d7ceb, 0x33d71378,
+ 0x02217949, 0x853d9feb, 0x9eaa3f70, 0xcc9951f9, 0xd5e2301f, 0x18a8fd86,
+ 0xbbd0d47e, 0x79a79f70, 0x97da3d78, 0x3bd637cd, 0x36c3ede2, 0xf077eefb,
+ 0x3ed35f4d, 0x0e5a1aeb, 0xbbc9aefd, 0xc3b3c49f, 0xfb18798c, 0x6e3e4e46,
+ 0xa8b51e73, 0x32df5c60, 0xc76adefc, 0xfeb26734, 0x7ae7be7a, 0xbbd1ee57,
+ 0x54768f2c, 0x6f9f8c6e, 0x03e0c7e9, 0xa343e885, 0xe4183710, 0x4ce7091e,
+ 0x3f04849a, 0x924dc7d8, 0x90729d20, 0x5aa97b1e, 0xff401689, 0x9cbc6627,
+ 0x3db2f685, 0xbce406b8, 0x0380abe9, 0x53aba9e2, 0x96c6f35e, 0xe6f19d9f,
+ 0xa56cc1b7, 0x7ee2d5df, 0xb148838e, 0xdc2763fb, 0x4b7ed1db, 0xe9c737c8,
+ 0x09ae149c, 0xcc13c402, 0xbf8f0ae5, 0x72e69928, 0xa45fc799, 0xe7394b14,
+ 0xbe34b90f, 0xeb93795e, 0x7602df15, 0x1cc4e74e, 0x713bd716, 0x30674f2b,
+ 0xdbc73efe, 0xc234f375, 0x535feef5, 0xf6e5251f, 0xe29befc2, 0x9922f8c7,
+ 0x3ebb4765, 0x2b9d852b, 0x26e7b120, 0xa26b5fe0, 0xccfc6244, 0xff9781a1,
+ 0x61d4f108, 0x06cabe0b, 0xea156b3c, 0xdb465861, 0xc79c6ca5, 0x28f74263,
+ 0x3ae6cf18, 0x02f5fb8b, 0x6a72e345, 0xdbf40b12, 0xef8521db, 0x3a52c0bd,
+ 0x91057b8f, 0x37c0ecbf, 0x8c29d022, 0xb1448ba9, 0x303a43de, 0xe61b089f,
+ 0x5187e0b9, 0x33c44bbf, 0xc61b614c, 0xf6cc7e8d, 0x7888d643, 0x03a8836e,
+ 0xedc9bfb4, 0x4297f82a, 0x1ae77e88, 0x40be77f8, 0xc4c8316b, 0xc608b2e0,
+ 0x7cedad93, 0xa039d853, 0xaffb7a3e, 0x5237df4f, 0x548f8173, 0x1ce8372c,
+ 0x694ef514, 0x5ff2df42, 0x12f38189, 0xdc58abc6, 0x2a5f5acd, 0xde4017e9,
+ 0x0bc2e5ac, 0x7e053a7f, 0x6467aaf4, 0x3ca7a3f4, 0x41bf4723, 0x045b35f3,
+ 0x076d53f4, 0x770fe89d, 0x51f2c23e, 0xfb43a28f, 0x8c05db73, 0xdbd9d507,
+ 0xe201bdef, 0x0488cf8a, 0x19708dfd, 0xe29d8bee, 0x59fb2673, 0x80079cbe,
+ 0x9a1cb66a, 0xec57df0b, 0x77d813b7, 0xf16e79a8, 0xf9a06fb7, 0xf464c7c5,
+ 0xac766a51, 0x657f6050, 0x40885849, 0xc1326bbe, 0xc4fb43f1, 0xbeda0ef0,
+ 0x369edbcb, 0x2bfb0dc7, 0x455da20e, 0xa7b4f6e1, 0xa9f4a6cd, 0x0d353f0c,
+ 0x2ddcabbe, 0x98ffc1f8, 0xa38eccf2, 0x9abbf419, 0xa73c0427, 0x45cbb550,
+ 0x9cba18b4, 0xdfa3136a, 0x9d33f880, 0x8bc5f827, 0xc034eb49, 0x0d8ecd7b,
+ 0xb713168a, 0x9230d33c, 0x7cdef668, 0x1c7413cd, 0x93ed5dfa, 0x58a61f82,
+ 0xe041236b, 0x9ce7ce8f, 0x30dcdb65, 0x08ca15bf, 0x59abcc0f, 0xc38b7681,
+ 0x7ec1f6f3, 0x8b78657a, 0x57d68d32, 0x2945b23e, 0xaaa7e18f, 0x2d10d75d,
+ 0x6d4e3f86, 0xd4bf4dce, 0xae867b7a, 0x54f0b15b, 0x88b7a612, 0xc4665614,
+ 0xc8767bec, 0x453f9c49, 0xdf06ff53, 0x18275e87, 0xef3d0ac7, 0x741abc41,
+ 0xbd32a65b, 0xbcedd060, 0x7528e9ca, 0xb388cd17, 0xd02f7aaf, 0x2af10ec1,
+ 0x1bfbd315, 0x6c6e987c, 0x9b3e90d0, 0xe1577f00, 0x7b9606be, 0x88629127,
+ 0xa275788b, 0x3c9f52c2, 0x21962f5d, 0xf960124e, 0x8283dbb4, 0x1bf98976,
+ 0x383926e9, 0xb75c820f, 0x964c4fc9, 0x49bebae8, 0x7e252e09, 0x77b4be3a,
+ 0x6075c972, 0xc8e705a7, 0x1d9fb0a9, 0xe8f160ac, 0xa2e40f88, 0x7ccbef89,
+ 0xd6f2664b, 0x7c60a194, 0x8bf7d364, 0x41eda1b6, 0x7d365e18, 0xec277cbf,
+ 0xe67ed1ab, 0x1aae54ca, 0xee4fda65, 0x9b49fbe5, 0x4fd4d13b, 0xa30adcda,
+ 0x8fd8c59f, 0x6cfd6073, 0x19bd7b9a, 0x4695b99e, 0x8fd8f53f, 0x4af36067,
+ 0x199263bb, 0xb1aa3b9e, 0xfddbf49f, 0x06881f68, 0xdc7690ff, 0x4eef7517,
+ 0xc496b71a, 0x1fe4d1f2, 0x2a1e78c3, 0x947cb155, 0x24c13138, 0xb27a494f,
+ 0x74a83f29, 0x6a7da9b0, 0x9f54c720, 0x85b5765e, 0xbfa8dd2f, 0x8a814f31,
+ 0xab38b126, 0xbd415832, 0x81d83c53, 0xbb06bbf9, 0x75dcef51, 0xb02af07d,
+ 0xd05600f7, 0xc12977f3, 0xbe1c6a31, 0x0812f3a1, 0x1b34cfc6, 0x32ec7da4,
+ 0x7939efbe, 0xde2357c8, 0xd9d7dfa7, 0xd12447ba, 0xf14a43fc, 0xadef3023,
+ 0x8de3b332, 0x9d824338, 0xce6bfea0, 0x8a16da2e, 0x50cb6bc1, 0x6f422fca,
+ 0xd0722dbf, 0x73b8fc07, 0x4a576ff5, 0xa1a6be14, 0x7a6e1e0a, 0xe1edfe5c,
+ 0x9b99b510, 0x00fb9687, 0xea8576ff, 0x15f1d88f, 0x8e3e7e3a, 0xdfc61bbf,
+ 0xd93b332b, 0x673dbe3a, 0x477c69a2, 0x7c698556, 0xa7c74287, 0xf56fb1f2,
+ 0x8a7c7c3b, 0x7909ebbf, 0xc7077e56, 0xe05567b7, 0xa90acdf8, 0xd09f8d30,
+ 0x9001fe33, 0xcdfdc39f, 0xf37ae73f, 0xcd2ab3fc, 0xfcd857f3, 0x80feae8f,
+ 0xf3809f8f, 0x80fe597f, 0x92ab3fcd, 0xfacedfcd, 0xdbdf19ed, 0x6157ff83,
+ 0x37f5affe, 0xe649dcff, 0x36ab0ff9, 0xc6cedfcf, 0x27f5637f, 0x8e377c7c,
+ 0x09fca6ff, 0x6ab0ff9b, 0x07b15f1c, 0xca47c0fd, 0xf07a8490, 0xa461a99f,
+ 0xa35d4061, 0x923a40e3, 0xc837a9c5, 0x5dc70839, 0x3eef8c09, 0xe6fca04f,
+ 0x24a7d5ee, 0xea90254c, 0xd3ce5acb, 0x158bbb55, 0xd0842fe6, 0x41c4585f,
+ 0xc45fb85d, 0xb46c8cf5, 0x78538787, 0x218bf73b, 0x78dc2fc8, 0xac5b9e23,
+ 0x77dc13b3, 0xfa3056a7, 0xc0f1ff1f, 0xf3b1ade8, 0x5a8ba6b2, 0x13fecb65,
+ 0xef38c783, 0xa6ab2454, 0xa78829fc, 0x127c3d50, 0x9e9a1ffc, 0xb478e996,
+ 0x83f043fc, 0x1b958aae, 0x768c2e76, 0xce9f2277, 0xfe1cbbeb, 0xf7c31253,
+ 0xdc053ba9, 0xc37cf847, 0xd9f40552, 0xc99756a2, 0x74e3a86f, 0x8ece7eea,
+ 0x79c68dfb, 0x14505bbe, 0xc1fdf909, 0xbb051d6f, 0x41e6f171, 0x276eefa6,
+ 0x1470d5e1, 0x79fac173, 0xff3a5543, 0xe3eccadb, 0xeb6b8c44, 0x9c1c5843,
+ 0x49b8810c, 0x7906db59, 0x52dccd08, 0xf9ec9b26, 0xfce6835b, 0x7ce6156d,
+ 0x6d961ca7, 0x112ccf60, 0xefda16c8, 0xcb65ebf7, 0x8e3600b9, 0x76e64957,
+ 0xbbef1b25, 0xb4198694, 0x8e90fbe8, 0xe9156283, 0xdf65573a, 0xddd4f01a,
+ 0xae28932d, 0xb8a91dc7, 0x454a140f, 0xb2a82dbf, 0x9de15b79, 0x00f43b2b,
+ 0x8fee6785, 0x15a7c444, 0x2e838efe, 0xf3ed46dd, 0x907fcd8e, 0x9d6c7e21,
+ 0x3bfe158f, 0xa3e75b96, 0xcc3eb02a, 0x19cb590b, 0xa9f9589f, 0x36f17f6e,
+ 0xf37b3db3, 0xb5fb58b6, 0x530cd76a, 0x56f8497e, 0x9bc5fb53, 0x17ea99e7,
+ 0xd5312eb5, 0x6a59682f, 0xfd0bcfca, 0x8efed4c8, 0xf54c2be5, 0x635fafdf,
+ 0x62adbfaa, 0x6b7f2983, 0xfb5321f0, 0x98b6ca5b, 0x47076dea, 0x68e4077d,
+ 0x9e22ebd5, 0x3ee0bdfd, 0x9bd82f75, 0xee12dc17, 0xed447e73, 0x33839015,
+ 0xb4815ed4, 0xf478ff73, 0x2c1ea9a7, 0xf9a24d87, 0x2d5598ca, 0x0997a099,
+ 0x6572cfea, 0x24d0aac2, 0xd7b0178a, 0x9b887ca9, 0x041d1215, 0x0f724cce,
+ 0x318b771f, 0xa9971df5, 0x7d054cdf, 0xb17adf7c, 0xdd797e23, 0xd4c379d6,
+ 0xaf6a7e38, 0xb02192dc, 0xce5975ce, 0xb569189f, 0xb1a73ce5, 0xeb817dbf,
+ 0xe9856ad9, 0x19bdea83, 0x86736193, 0xe223e5fa, 0xf9ec9b9d, 0x0db0223e,
+ 0x53feb048, 0x98861f81, 0x76aa6bf6, 0xfbe49ae5, 0xe11121ec, 0x409d05aa,
+ 0x5217eaf5, 0x72028d60, 0x35923d16, 0xa1c0346b, 0xef4055af, 0x75c54fec,
+ 0xe9436cfd, 0x3fafd836, 0xf4c010d3, 0x4c3286a3, 0x3104354f, 0x02a1b0fd,
+ 0xf50d93d3, 0x2c347698, 0x86bdf4c7, 0x36efa610, 0xbbfa60b4, 0xdf4c5686,
+ 0xe98cd86a, 0x4c610d1b, 0x4c741b3b, 0xd1e8790d, 0x0f6e01bf, 0x84d71b1b,
+ 0x2e7cc3db, 0xe73da98d, 0xf7ff70c2, 0x11f3fbbc, 0x7f9fef60, 0x6cfb8ecb,
+ 0xcacbe1fd, 0x51d3fd6f, 0x3ca57b47, 0x639d083c, 0x8133bd6b, 0x2369c9d1,
+ 0xec1c64a5, 0xcff4ecff, 0xc4bcc7cf, 0xfd84f52e, 0xfa713c33, 0xfa5d7885,
+ 0xf444e9e5, 0x949982ee, 0xfe1ea71e, 0xf7e822af, 0x607fac02, 0x71111c07,
+ 0x6dd1261d, 0x95d7a07e, 0xe1784de2, 0x2f1059f7, 0xbf83d73b, 0x8b882cf6,
+ 0xd8a8ab5d, 0x3b36f9ff, 0xf9d2f881, 0xcfbc2e03, 0x36d8fe75, 0x32e3c82f,
+ 0x3d8e189f, 0x6b4d6147, 0xb761d922, 0xe736efc9, 0xa50ab7cf, 0x689a1e78,
+ 0x0347b389, 0x3861a95f, 0xe0d9d20f, 0x67e8d4c3, 0x71c14f99, 0x65caecce,
+ 0x5e7e3371, 0x424eec83, 0x277ea57e, 0x869fffb6, 0x0c7ebfa7, 0x23690878,
+ 0x5e08381f, 0xdb98bb71, 0xf97efb7f, 0x814cfa49, 0x20392af8, 0x82f60e7f,
+ 0x1177fe9d, 0x6122651c, 0x2eb7e8de, 0x63ec8622, 0x69b77ca0, 0x669dfa3c,
+ 0x7317f4f8, 0xe6b7c52e, 0x042234fb, 0x9c46bf68, 0x80fe0aa4, 0x02f530f3,
+ 0x788cabc6, 0x6ee49749, 0xc6f4c611, 0xbc78ea4b, 0xa1d1c6b8, 0xb9d16904,
+ 0xee4bdcb6, 0x38699e9f, 0xaf39c2a6, 0x02ab470a, 0x64454fce, 0xb9e80954,
+ 0xd2ab6d73, 0x12ac1ec0, 0x2f15dfcf, 0x67679b7e, 0x6125bd71, 0x8ebcdbb9,
+ 0xb420fe72, 0x1d9ca35f, 0x8a9f7472, 0x31b59fc9, 0xefdadb3b, 0xf6c0fb04,
+ 0x1f776a2d, 0xd683769f, 0xfbb54f17, 0x3e30553f, 0x5c53112e, 0x7bdfc0c9,
+ 0x9d82604a, 0xd772a9e2, 0x7e8f68fb, 0xdc468724, 0xd4fd097d, 0x9f6e7e77,
+ 0x88727ce9, 0xf338c3b4, 0x8881f227, 0x743bcb76, 0x15f8fd3d, 0xe4db9d99,
+ 0xf67b80e7, 0xfebef995, 0xdf9b9e02, 0x84e78556, 0x8ff7de3e, 0x242dff68,
+ 0x81d22f01, 0x1d8116b4, 0x4ad88e79, 0xc8e74f01, 0x31f1de6b, 0x3a95b874,
+ 0x05ef404a, 0x863b662d, 0xfca6bfda, 0x7ce6cde2, 0x06999939, 0xa37ca4fa,
+ 0xce02c24c, 0xb37f54cf, 0x177ec55d, 0x5826fa93, 0x8fee2557, 0x348957cc,
+ 0x9ad5ea84, 0x34567f67, 0xb411c28f, 0x88c83f33, 0x66492cbf, 0x4a656076,
+ 0xc27d8158, 0x7fc6da0f, 0x832006f7, 0x7104dc3d, 0xfc489228, 0xfc5f483b,
+ 0x56fc295e, 0xbaf58d78, 0xc3881c4f, 0xe212ee21, 0xdad603ee, 0x86cf6e05,
+ 0xe7c03d30, 0xc705f86d, 0x7615f92c, 0x2452de7e, 0x9cfdd022, 0x12d908ea,
+ 0x851fdeb1, 0xbb5edc78, 0x7106957f, 0x7b6ac0fc, 0xdfdc6f6a, 0x0f649768,
+ 0xe159f962, 0xf73c72d5, 0xf00b4520, 0xef8f21de, 0xc41f9c2b, 0x9c016f04,
+ 0xdc40f523, 0x3a75ce1e, 0xdf215bbd, 0xf3c0a9e4, 0xef20751f, 0xbc7bbfb4,
+ 0x9c418ed3, 0xa35a41da, 0xbb5fe53a, 0xa01fb2cf, 0x902ef399, 0x5067d04b,
+ 0x09a2e780, 0x235cb9c6, 0x7e3cedcd, 0x2e31fe73, 0x4381748f, 0xdf39ee3e,
+ 0xe14770e6, 0x2899093c, 0xb7f1ed9d, 0x63dfc072, 0x56fdc3f0, 0xcaa77f68,
+ 0x7df2d7da, 0x9edf3bdd, 0x097c9e9c, 0xa5f7547d, 0xeb31c240, 0xadd49d48,
+ 0x7dd61f00, 0xd7f96129, 0x5d1a9bd6, 0xe6f46355, 0x59f04a2b, 0x27a604fb,
+ 0x8e813e01, 0x64dfbb13, 0x027087bd, 0x2f4261f8, 0x386d7c3f, 0x7f498852,
+ 0x8f04a7bf, 0x6be383c5, 0xd3ebeff7, 0xbbe009ff, 0xf3feb1ff, 0x11dff4fa,
+ 0x679afe0f, 0xd10becf7, 0x17f2b5f5, 0x10e1780f, 0x6b52c7d3, 0xacef9c1a,
+ 0x0bdab1de, 0x1491f972, 0x3f5d02f2, 0xef718b0e, 0x0c3ba6e7, 0x70ddd3be,
+ 0xf396b08f, 0xaf9f99dd, 0x2ff836fb, 0x5590ef9f, 0xb2ec0f8c, 0x2994ed47,
+ 0x3096db6b, 0x7f65d8f9, 0xf19be59f, 0x7edd53bc, 0x7ca8beb3, 0x0d3481fc,
+ 0xb885550f, 0xff451cff, 0x7ffb76a0, 0xabbb034c, 0xdea3748e, 0xe3077eb3,
+ 0xf68c997f, 0xb1253cc0, 0x0e71bd6f, 0xa5e38eab, 0xde1d6dae, 0xbb6baf13,
+ 0x9a1334f9, 0xad3bf40e, 0xbb7055df, 0x9f30e1df, 0x42f034df, 0x5feeccc2,
+ 0x0583c4f5, 0xceb853ef, 0x2bc57f6e, 0x29f2c7e4, 0x23e77fd3, 0xa5fb1e0b,
+ 0x755cbfd6, 0x6b18fd52, 0xb4eb1b5f, 0x2bfb9fb6, 0x2d5a5807, 0x0fe0bd47,
+ 0xf1916f56, 0x9ef57bbc, 0x861f3b6d, 0x76dbccf8, 0x7fda70ff, 0xde979ed5,
+ 0xabe69eb8, 0xa653929e, 0xe1b869b3, 0x9f41a29e, 0xf2dffa3a, 0xa8f4bd71,
+ 0x4525fa7c, 0x7fcacd1b, 0x974bdc9c, 0x290ea7aa, 0x7c5f7464, 0x521c894c,
+ 0x85b67ed8, 0xa7f7913e, 0xeab15f81, 0xd0142f89, 0x141f1f5f, 0x1c767a48,
+ 0x09796e7c, 0x13c063ed, 0xabd393d2, 0xf6967e87, 0xa82e9475, 0xb2f42d17,
+ 0xaf98fbb6, 0xc42fd007, 0x3f7f29e3, 0xb7d84bf9, 0x0fdd9df9, 0xf278a878,
+ 0x9f30bc9f, 0xe33d52d3, 0x4ead9ff3, 0x1520fb83, 0xc54d2872, 0x3c579594,
+ 0xbfe403fa, 0x907fc7c5, 0xeac5cec6, 0x575cfc19, 0xd173cc06, 0x9e707323,
+ 0x7c8824e5, 0x7633f158, 0x4482fccf, 0x238a9f4a, 0xd839f727, 0xab7a763a,
+ 0x4f11371d, 0xfb0242c3, 0xe189af18, 0x640f181d, 0x607f0de7, 0x65913fec,
+ 0x60e0bf98, 0x30e45af4, 0xa5d1f1ee, 0xb77f9624, 0x9d03b737, 0xd3d50cce,
+ 0x475c8e21, 0x87c710a4, 0x2bf69170, 0xce9a9f1e, 0x52681dcf, 0xea8eff11,
+ 0x0e5029ff, 0xdd65dbed, 0x8efa6059, 0x1deecc5c, 0x3e3e4eff, 0xec013b85,
+ 0xd469d3d7, 0xbf338c1e, 0x9d630e03, 0x0c5676a6, 0x3bc8c59f, 0x6bedff93,
+ 0xf21bbc98, 0x0a519e1f, 0x609d9ff5, 0x81df0472, 0x8ae142fd, 0xa1fd63a6,
+ 0x07ea02d9, 0x93c6893b, 0x9732edf3, 0x95bd7373, 0x12fc285f, 0x7c3dc7ac,
+ 0x2324e303, 0x2dbed01d, 0x8fbf48df, 0xae30abd5, 0x86bf6fb7, 0xfae62f1c,
+ 0x1f45ad60, 0x07524790, 0x2d5b7fb4, 0x0c3e7787, 0x35e54bf2, 0xcafc81a4,
+ 0x27c15ef8, 0xf1bc8fbb, 0x9fb72a3d, 0x35b90c44, 0xdcab55eb, 0x409dec56,
+ 0x27edc9e2, 0x2b893f6e, 0xae3cb4b7, 0x903bbadc, 0x7ad6ff9f, 0xd3e3c0d5,
+ 0x7a1a3c16, 0x5a7c3fb2, 0x1db7e4f5, 0x493d5c5a, 0x45209dff, 0xe0d1f97d,
+ 0x2aff8343, 0xcf06a5ff, 0xa9f0f50b, 0x7c3d87c1, 0x9f61f06a, 0x8f09a478,
+ 0xe1bbfad6, 0xc0853a6f, 0xcfc63273, 0xfdb00fab, 0xd1ddfa67, 0x2f888521,
+ 0xd239971d, 0x4a48747a, 0xc96c3e6c, 0x75ed2c47, 0x69603e4b, 0xebe4b41f,
+ 0xf7abed4d, 0xb9d8511f, 0x9da9a89e, 0xe4a7fcb8, 0x01f13883, 0x6baa1d63,
+ 0x010954fb, 0xf1bbb87f, 0x0925797b, 0xfe5e2079, 0xf2f188bc, 0x26e38a2e,
+ 0xeed74e3a, 0x608f7c6c, 0x57c593b5, 0x2f6ed4ba, 0x93ab93d8, 0x553bbe58,
+ 0x683d0269, 0x593b7794, 0xd02bafdc, 0xb18a4ded, 0x203fdeef, 0x08ef1ea2,
+ 0x7e78d293, 0xa140de28, 0xfd20edf8, 0x80fdb3d5, 0x61d7b02e, 0x30ac84bc,
+ 0xd154e3f0, 0xe21cb59d, 0xde22ad35, 0xe2b85b6b, 0x239c2f16, 0xfb903ae9,
+ 0xbe5a329d, 0xdb22d7e8, 0x52e90ca6, 0xf81f8c46, 0x9a6d0911, 0xf5fec024,
+ 0x059fe47a, 0xb85f9807, 0x797c7d70, 0x95dfe4a8, 0x4054efbb, 0xee7f52ef,
+ 0x87beec64, 0x23c54fd1, 0xff03f296, 0x15a6e5c8, 0xdb951fe3, 0x1e41f5cd,
+ 0xe4ec183f, 0x92c7bee7, 0xb77fdcb1, 0x9e0fdec5, 0xa77fe62a, 0xeba7d28c,
+ 0x3ce04898, 0x2203f9c1, 0x6efce7d2, 0xe3007e76, 0xbf01d7fc, 0xe7b12b77,
+ 0x7c82cea9, 0x1ebfd55d, 0xefccfb3b, 0x3e06ee8b, 0xc14ef7da, 0x767a694f,
+ 0x7e23dbdf, 0xdf67f905, 0xf4877acc, 0xa0e53f6d, 0xba55f713, 0xff907a0e,
+ 0x4dff9ebb, 0x7f90ddd6, 0xecf18ece, 0x145f83ae, 0xad753f00, 0x1e8057b4,
+ 0xefe7e2ec, 0x45ff3d56, 0xbfae0741, 0xa9c7488d, 0x9f4fe64e, 0xef5ff03f,
+ 0xf381fdc1, 0xc0ace807, 0x42e838be, 0xa5fbaaf9, 0x5d6fe313, 0x14517fcf,
+ 0xa5fc27eb, 0xfbe5a9f3, 0x521e5d9d, 0x4be017b6, 0x7544fb62, 0x1b6ebabf,
+ 0xd3512fbc, 0x40594876, 0xf0bca7eb, 0xafd002a7, 0xdd997b5d, 0x3c7729d4,
+ 0x8179fb0a, 0xca340f35, 0x209d5e94, 0xff698364, 0x0128de6b, 0x978bea39,
+ 0x715c613f, 0xfc58f8a0, 0x043e0d7f, 0x4f3fe99d, 0x29854c18, 0xdef8ff07,
+ 0x0e27a03b, 0x8d2f91da, 0x59127ef9, 0xe5ccf681, 0xfff4dde6, 0xe885bcdc,
+ 0x03bde640, 0xefe13de6, 0xc0d7de77, 0xbed4a1a1, 0xcf97d072, 0xf30bbf9f,
+ 0x847e3c7b, 0xfefc8077, 0xfcf9dfd2, 0x7bee98af, 0x97bddd29, 0x7f87f79f,
+ 0x9feef3e7, 0xcb9ebfee, 0x79c2aee9, 0xfe17ba98, 0xa95df084, 0xfe12939e,
+ 0xbfbde5be, 0xfef61bf9, 0x35bf9b5a, 0x93cf1b27, 0x70b0c03a, 0x40b6667b,
+ 0xc8ed7178, 0x9dd82a99, 0xd5ef3f62, 0x7e60484c, 0xf7b02895, 0x1650c821,
+ 0xcfdc240f, 0xf80d6382, 0xdd9b880e, 0x4ddc933b, 0xc9137768, 0xbc53aedf,
+ 0xbe7abdac, 0x911acf1f, 0x21056f71, 0x8fc9399f, 0xbf8b6ef1, 0x5d1028d9,
+ 0x74aef6a0, 0x818f37f5, 0xb48f23df, 0x9805ed45, 0x33690fbe, 0xaaca638f,
+ 0xdc87f262, 0x53bce6f9, 0xbcede733, 0xf061073f, 0x0c247c3b, 0xd4716cf1,
+ 0xd3ce1561, 0x02256389, 0x4938a54f, 0x0efc086b, 0x7dfccfbb, 0x7ee10252,
+ 0xc7865fef, 0xa716048a, 0xed718512, 0x9471e03a, 0x78dce30d, 0xe2f11b48,
+ 0x08baf7c7, 0xf17baff7, 0xf80ed4da, 0x663fc094, 0xd5fa17f6, 0x12d3fb84,
+ 0x691a42ef, 0x76e69dd3, 0x2cbe8fdc, 0xb25d189d, 0x969d39aa, 0xd062e899,
+ 0x4c7d0e21, 0x7cf03174, 0xd2b1f4a5, 0xebff8ac5, 0xf75f1813, 0x2e832f47,
+ 0xef1d6e99, 0x7fdcc9d7, 0x133f0128, 0x820199f2, 0x7fdcabfb, 0xbc745290,
+ 0x7eaa24a7, 0x7e0097bc, 0xe01a945c, 0x86deef2f, 0x3f73a4f1, 0x00dbff7f,
+ 0x44afd54f, 0xebf8a0e2, 0x5121eddc, 0x2b0a5ef8, 0xb6569fe0, 0x404fb889,
+ 0xacd168a4, 0xc3627d98, 0x85faa80f, 0xb953e707, 0x4e9e1ed7, 0xf7dcafbf,
+ 0x61da0141, 0xcfd1bb2b, 0x605cfd09, 0x14750f74, 0xa5703ec0, 0x2b11fcc4,
+ 0x6049acbf, 0xcfb396f1, 0xae20cab9, 0xe762ec23, 0xb7232b7f, 0x7398f6c8,
+ 0x9904a14d, 0x739e9bc5, 0x3d085ea1, 0x28f9e021, 0xdcf62f80, 0x9c87e1a9,
+ 0xf060427d, 0x9df197ed, 0x4f5dca98, 0xaa7c4275, 0x1fbb2df2, 0x5dbaf8cc,
+ 0xc87ee29f, 0xf1ec5f94, 0x2e1fa076, 0x7d12e29a, 0x44bb01e2, 0xb6da8fe4,
+ 0x6843f41a, 0x36a2f91e, 0x2beffdc2, 0x7eab57f4, 0xb83efcf1, 0xf4f55670,
+ 0x7f885ee3, 0xe1df699d, 0xaec0b8c5, 0xfae7c74b, 0x3591fff8, 0xd6ffffdc,
+ 0x3b4f7669, 0x067fffbe, 0xf176a0fe, 0xfb9609d3, 0xb106bbab, 0xb44914f7,
+ 0x71ef52e8, 0xf0b9ed55, 0xcfafc428, 0x51e4fdee, 0xcffabb80, 0xfc14787f,
+ 0xa9d0720a, 0xba827dc2, 0xf18ebf9f, 0xdfbbe33e, 0xf9d03d70, 0x2f18e3c4,
+ 0xfa9b7ced, 0xe75ff41f, 0xc0b3a7f3, 0xea7ceccf, 0x4f10698f, 0xa9f9f3b9,
+ 0x9dce6ef8, 0x27494ccf, 0x9189f471, 0x0786ff02, 0xd2b5af10, 0x11db48ed,
+ 0x51ce7ff4, 0xd9ff83ba, 0xd489d713, 0xc69978b0, 0xe3bb39e3, 0xc4fbc7c7,
+ 0x7d66da6f, 0x4842c6e7, 0x0646bf65, 0x4139c710, 0x006639e9, 0xe3cddc74,
+ 0x5d6f9175, 0x0e738e32, 0x3af4a0fe, 0x85e3a16b, 0x3d8f45b6, 0x836d750c,
+ 0x44e38dfa, 0x233f8007, 0x413fbefe, 0xe40122ff, 0x60bfef68, 0x37e80cfc,
+ 0x73b84e9d, 0xd82c85cf, 0xee48f8bf, 0x85ef8b9e, 0x21576f3c, 0xfcf9511e,
+ 0x9d4f289b, 0xf8c71ccf, 0xf071e136, 0x8ff3d24e, 0x99f92bc5, 0x1eedbacc,
+ 0x74e1ff16, 0xe690f880, 0x071e72c5, 0xc46d7c62, 0x0b8bfa87, 0x73b1718d,
+ 0x40bec627, 0x7877f6cd, 0x6e97a5bc, 0xd7a044c2, 0xcfdc97fb, 0x02a0f030,
+ 0x8d8dae1e, 0xc38fc67b, 0x2d3dc4f5, 0x427a0374, 0xae27b3bc, 0x7b13d849,
+ 0xcde16175, 0xcef47178, 0xda5e2c2d, 0x8f3fc729, 0xaf41c465, 0x9fe25976,
+ 0x3fc581e1, 0x2b8f372f, 0x9760d3c5, 0xf15afd86, 0xf8abf675, 0xae5bfdfa,
+ 0xe85f9d81, 0xdaad7f77, 0x3de61f7c, 0x05dd3825, 0xef6d6bfb, 0xa7cf042b,
+ 0x2b73b374, 0xf967be7c, 0x3fb3d3f9, 0xd62e3117, 0xfa823914, 0x8c3faadd,
+ 0xbc2b57fd, 0x6b787077, 0xe3f5b3f7, 0xd84f5eec, 0x7b39fb4d, 0xebe439f8,
+ 0x63efddda, 0xaee8ee5c, 0x988e95a7, 0x8fd616f5, 0xce7ccc70, 0x80a8793e,
+ 0xdfe379c5, 0x3171ab1b, 0x40eeb37b, 0x76ea71fc, 0xa71a6a7f, 0x9851142a,
+ 0xf1e9701d, 0x2dfa48ce, 0x7699dfd0, 0x3a4ddf19, 0xbee31113, 0xc9701c17,
+ 0x95a11f7c, 0x475d0fc9, 0x71c09ef1, 0xf0a77f76, 0x573c04b5, 0xd2f1e77f,
+ 0xb7fde077, 0x8358a93b, 0x82b6dfdd, 0x4fdb69f1, 0xef4021f4, 0x13dfe3b6,
+ 0x07dafd61, 0xffb18df8, 0x4fd44e8b, 0x50fd50f1, 0x10a06ef4, 0x77aad5d8,
+ 0x66cb7dae, 0x938e9f82, 0x2342eb0e, 0x83ee07ed, 0xbc39b9c0, 0x569dee57,
+ 0xaa88f00a, 0x7d0a754d, 0xf9bb21e7, 0xafde557d, 0x21ef9aac, 0x6bc6af90,
+ 0x266f8fd0, 0xcc664b8b, 0x9f165232, 0x87f7190c, 0xabc213ca, 0xaf7f7ce8,
+ 0x28bb3706, 0x8d9e7c5e, 0x78112fd9, 0x06a26a27, 0x2e63d3f6, 0x4bc1de7e,
+ 0x83bcecbc, 0x7aa3643b, 0xf6ff61fd, 0x9e08930d, 0x7c06d867, 0x819e73d9,
+ 0x2f800b44, 0xea7d768d, 0x321de72d, 0x5a2a13e1, 0x17338722, 0xfd5025ee,
+ 0x77866ab2, 0xf11fe42b, 0xb2cdf7b0, 0x3821f748, 0xdb8db0df, 0x1560d9a3,
+ 0xe77df6e7, 0x6fbeebec, 0x78a53296, 0x853f30e9, 0x535ff5d3, 0xca7c5ce1,
+ 0x0d4fc52d, 0x2d856951, 0xa3dc1a63, 0x78bc7949, 0xcfcd066c, 0x34f4ff5f,
+ 0xe2f7ffac, 0xff3459b1, 0xb20e7b93, 0xcf012afa, 0xaeb0bec1, 0xeff01a76,
+ 0xd9fb96d7, 0xb9663314, 0x77f0057f, 0x77eef02e, 0xae706917, 0xefe15ba2,
+ 0xdda00465, 0x7f0c89d0, 0x9f77ee99, 0x98657f02, 0xf00563ad, 0x7fcf63eb,
+ 0x16f78491, 0x2aa1fbf9, 0xdce15469, 0x789a2d15, 0xf3e712f1, 0xccfbbcfa,
+ 0x498dcbf5, 0x3f8177c1, 0xbc8de79a, 0xef1d1a6f, 0x0e718ae1, 0xf2d00e76,
+ 0x829aa34e, 0xe9c85d74, 0xcb3df84a, 0x8b3e7c45, 0x02c290c5, 0x7f5caddf,
+ 0x5751ef19, 0x1ef4578b, 0xdbab8735, 0x67fbefd5, 0x3378007f, 0x007f8293,
+ 0x3fdf59fc, 0xb815c57b, 0xe519f500, 0x5c7de25f, 0xeb333de3, 0xea4468bb,
+ 0xfb3efb8e, 0x5a2efe56, 0x9bfef07f, 0x69ba283b, 0x682f39ff, 0x39518f7b,
+ 0xf150b31b, 0x31cfd1c3, 0xd2fd0bcb, 0x0426c220, 0x1fa71076, 0xf788cf3c,
+ 0xb822ee1f, 0x1765db5f, 0xbbaff074, 0x7d4549fe, 0x3a70b99e, 0xae5d5ffa,
+ 0x339c08ec, 0xc35bbaea, 0x018a3d7d, 0xe869e401, 0xf828c481, 0x3e1e5487,
+ 0xe7c3c8b7, 0x8f37fe66, 0xdb5175db, 0xa9fd81df, 0xa06a3fbc, 0xed8bdcc5,
+ 0xee9e9912, 0x8e10d06a, 0x087424a1, 0x8e81fdd6, 0xebe6e397, 0x46cfa737,
+ 0x9eeb9e9b, 0xee1ff880, 0x28ffc18e, 0xcc74bf77, 0xe63a3377, 0xd1d0e3bb,
+ 0x7bdd6efa, 0x6858e0ae, 0x28fcba77, 0x7d675fbe, 0xdf4aceaf, 0x21f5a93a,
+ 0xed2b3b78, 0xfeb8a7c0, 0xb31bf418, 0x29d22c7c, 0x00939e86, 0x3e07318e,
+ 0x06bc01b5, 0xe7ec1f1d, 0x9ba9793c, 0xf1d673ad, 0x063acad2, 0x9fb4e307,
+ 0xf74cd6e5, 0x451c0a0e, 0x69ca897e, 0x87c58dba, 0xb7efb6fa, 0x9d4b9cff,
+ 0x59502cf3, 0x73ff14bf, 0xfe064f00, 0xfbf3756f, 0x7ff17dea, 0xf8a3b43b,
+ 0x3fe61dbf, 0xbbcffc00, 0xfb0dfe14, 0x87eb8abf, 0xa29fd82a, 0xda1ff47c,
+ 0x3a1cb4cc, 0x8dd134ee, 0x8764b072, 0xd931f7c8, 0x3e865ffb, 0xfd5d7259,
+ 0xb917b821, 0xf20267e4, 0xfefe42eb, 0xfdfc27e5, 0xc1b9eb4b, 0xea10b2f2,
+ 0x1f9fcbcb, 0xaa3ea30c, 0xff2e65da, 0xbbcf7767, 0xde785997, 0xad352417,
+ 0x2b4ebdf7, 0xb9bbcffe, 0xb4e858de, 0xd72f7bc5, 0xdbd68748, 0x33cce74c,
+ 0x83f4f4a6, 0xa6cfa0fe, 0xb8f189bd, 0xc409957f, 0xa5297413, 0x2019de10,
+ 0xf4094285, 0xd7e5cc5b, 0x72d86fe8, 0x1d9ffaf3, 0xcc43df32, 0x43df316d,
+ 0xbe6ade1c, 0x66d57887, 0x51c43df3, 0xc43df361, 0x338d766b, 0xae4747e5,
+ 0xb31fb537, 0x3f29b27f, 0x534dfa36, 0x66c7f1fb, 0xda13f29a, 0x7f6a67bf,
+ 0x4df35bed, 0x5475d7f5, 0xf86fea9a, 0x7f299968, 0x9b3ff763, 0x311747da,
+ 0x61b878fd, 0x5bdc1179, 0x7872f030, 0xa15362a9, 0x9b08e97c, 0x9e5b105a,
+ 0x90056ba6, 0x7fe0e916, 0x532f27f5, 0x8a2a3f1c, 0x898ba75d, 0x536fd26c,
+ 0xd47ce61c, 0x8f7dfe6d, 0x35722c97, 0xcb527ea4, 0xbc1d9a08, 0x63cf0f24,
+ 0xc63af953, 0x01b1dbf5, 0xa0dfb7ea, 0x9b46d57c, 0x2f956f20, 0x9a01bde3,
+ 0xad8fd886, 0x1f9f77b0, 0xd4f99a72, 0xf95e8fd7, 0x0738db9d, 0x53facad4,
+ 0x264bc6cb, 0x3fca3139, 0x172d8c2a, 0x73c74f16, 0xabf5fd40, 0xb35c16f8,
+ 0x3bbc107d, 0xa3530f3c, 0x16cca9bc, 0x67dfdcf7, 0x7fd0bfee, 0x8ec7dcda,
+ 0x7cf00cfa, 0x26daf7ce, 0x7b56bf38, 0x51fa377b, 0x5e337619, 0x5decf37a,
+ 0x479e0363, 0xac3e481a, 0xb6fdc6f7, 0xebe13445, 0xd177ce36, 0xe0d333db,
+ 0x3f66419c, 0x87a155fe, 0x1b47ebe9, 0x042cd742, 0xe98711c2, 0xb456795e,
+ 0x39f81a6e, 0xeb79f8c3, 0xe7f8b64d, 0x0c3c92a0, 0x48a0e92f, 0xdd505ec1,
+ 0x2b9c2f68, 0x4f0bd77f, 0x0f68dcc7, 0x38e87926, 0x17b4c7f3, 0xbad4fbb1,
+ 0x5ee8e67f, 0x947d0db8, 0x026c0ee5, 0x93e592fd, 0x17dd9688, 0x83dbf49e,
+ 0x788ef02d, 0xefcdb263, 0x00b77cc6, 0x4c7fd9e3, 0x5e3a20c8, 0x84459fe3,
+ 0x75f0f1af, 0xeec83e78, 0xabb8c7ae, 0xcfc24f31, 0xe6711809, 0x89d9be0b,
+ 0xabc6cf80, 0xe107ee7b, 0xdc17907b, 0xf7e876c1, 0xc71946c2, 0x982c9c6d,
+ 0x4b798dea, 0xf78dbf9b, 0x6cdcb2be, 0xde74e5de, 0x933db700, 0xa8f8d5c1,
+ 0xae113240, 0x28f4bdff, 0x5cfb35f8, 0xc507def8, 0xc7c010c7, 0x73fb3d39,
+ 0x3a79319b, 0xee419aaf, 0x9ed16bad, 0x4ea7ef89, 0x8fa1e637, 0xe33bd134,
+ 0xe2fc332a, 0xc6fd1946, 0x3c6e4945, 0x886e10ef, 0xe79afa72, 0xf99be4df,
+ 0x5c295b9d, 0xf8884eab, 0xd1d6b6de, 0xfd28f4ba, 0xe5cdbcae, 0xf17d6b0f,
+ 0xf0634e7f, 0x7ba7f852, 0x4f36de40, 0x79e3f9c3, 0x31ff806a, 0x0d9c3c81,
+ 0x452c17fc, 0x236c183e, 0xc7d36fb0, 0x7930f04e, 0xd951ed9e, 0x72be357b,
+ 0x85be8726, 0xfda76cd7, 0x5dfa7995, 0xb0f36ff7, 0x4f36ff75, 0x72ff759c,
+ 0x975707ef, 0x54851fb5, 0x37b445d4, 0x111fa908, 0x3d53476b, 0x1bfd0e56,
+ 0xc7f13179, 0xff6fd005, 0x65bf9a76, 0xede5f644, 0x80cfb034, 0xecfb0d0f,
+ 0xaed98f4e, 0x3fbbd18c, 0xfbbd30f4, 0xf4c0cf43, 0xfda18fee, 0xe345efe9,
+ 0x4aa935da, 0xb4f7bd7c, 0xac1fdd87, 0xe7821553, 0x0fd9fb03, 0xdae5c9d8,
+ 0xd6feef3a, 0x1ff9cba5, 0x4f832e39, 0xfcfefacd, 0xf4112d31, 0x4207ca54,
+ 0x86b777dc, 0x3c6dbf2c, 0xad9b6bd0, 0xf7cc3378, 0x78fe1667, 0xf59f4d68,
+ 0x18f1cc2b, 0x6ac78b8e, 0x099b478a, 0x973c3b8f, 0xb6bf0fb0, 0xdf30afbe,
+ 0xf8e4e9f3, 0x09bf7aa6, 0xeb373bc6, 0x6b8822bd, 0x1cf9ced4, 0x1ed7fef5,
+ 0xaebccca7, 0x1d397e18, 0xa1e00567, 0x799fd673, 0xe303ae7c, 0xb99eab4a,
+ 0x58e2112a, 0x7a0d9335, 0xaa7df044, 0x4839f9f3, 0xecfb7397, 0x2e79c03a,
+ 0x3d139d99, 0xa3daefb7, 0xa4f8f710, 0x2c7258e1, 0x793dcf7d, 0xfda648bc,
+ 0xbc7bdb9d, 0x7703c248, 0xd43bd361, 0x5b7f1735, 0xdef77014, 0x37e1e84b,
+ 0x368f5b07, 0xe57c593a, 0x37173841, 0x6abfda86, 0x7a65f212, 0x285eed9a,
+ 0x1dbf1d17, 0x395c21fc, 0xa62fe63f, 0xd04ab259, 0x7ec11633, 0xee373cd3,
+ 0xc972f967, 0x9dfa6cc8, 0xe387ad12, 0x6af9c4cc, 0x04efc098, 0xf1444eb8,
+ 0xef3c02f7, 0x3ef86076, 0x02b243f1, 0xbdffc29e, 0x78093c1a, 0x09ab3a4f,
+ 0x77c41a89, 0x471e6e8a, 0xd30a6953, 0x3ab7ddbf, 0x848cf7f0, 0x53aaaf05,
+ 0x3cdafea8, 0xdd8efd93, 0x920b63f9, 0x55691fc0, 0x0df2de99, 0xb463e1eb,
+ 0x6be7078b, 0xe6231737, 0x40577c75, 0x921d1955, 0x8a6b6c33, 0xf9c78c35,
+ 0x25fe98f3, 0x3dff1a52, 0x1eb7ca29, 0x1c43a6cd, 0xc5cef8d8, 0xfc522bbf,
+ 0x7803cebf, 0xf0fcdb46, 0xabfb8f4e, 0x92ca386f, 0x28ccfb69, 0x945e5fbe,
+ 0xc39de1c0, 0xfbef07de, 0xd345e34e, 0xd4b5187d, 0x27b74efc, 0xe214b4d0,
+ 0x6defd0fc, 0x8bcef8c9, 0x38a29eb9, 0x0bbb9691, 0x0aaee5cd, 0x47e18f9a,
+ 0xf6d677eb, 0xae925f86, 0x37f63832, 0xbf0f1038, 0x79fd506c, 0x340e8f94,
+ 0xb07f30f8, 0xda34c341, 0x0fcb1230, 0x2f31f837, 0x986cf4da, 0x7faffa4f,
+ 0xeebb1490, 0x9d54efc2, 0x75c3e18c, 0xf9ade472, 0x88df8f80, 0xaf15af88,
+ 0xdefe478e, 0x3a8e9a34, 0x7367bd86, 0xfefec632, 0xd257f2e9, 0x0d5f284a,
+ 0xd3afd1f9, 0xefc3c64a, 0x17f3b096, 0xf63a4170, 0x257aee1e, 0xe093f9a0,
+ 0x34c63477, 0xfbc2863b, 0xc95bc1a4, 0xfd239458, 0xbbf089c5, 0x6c337b0b,
+ 0x949a7eb4, 0x07f8ecd7, 0x64deab80, 0xe7e7afe7, 0x6c9f1f33, 0xbce3afd6,
+ 0x0a66ff4c, 0x71bce3c5, 0x537e09f8, 0x39acfd00, 0x3307b9c6, 0xbf54891e,
+ 0xeb8a76e1, 0xdfb3efe6, 0xc754485f, 0xf7bde1fb, 0xcec35ecd, 0xbec5f7a9,
+ 0xff99bee7, 0xe1e2440e, 0x29176825, 0x103bf63e, 0x0f7b0a29, 0x4d930489,
+ 0xe5cdedef, 0x0606ccfd, 0x1f57d09a, 0x15fde6cf, 0xfb0e791d, 0x8897df83,
+ 0xf087eff5, 0xccd8c3df, 0x3574d3f5, 0xed4dec50, 0x5bd4676d, 0x7759ebbf,
+ 0x0bd1216d, 0x890143f6, 0xed04bd80, 0xd4bb698a, 0xdc02030f, 0xd7ce33ef,
+ 0xcdf80b3e, 0x93ddfdef, 0xebc3027d, 0x8a7d3c93, 0xd4494eff, 0xe3079813,
+ 0x123c16fb, 0xca7603da, 0x6206bb3e, 0x8fe47452, 0xf8947ef8, 0xe701c53b,
+ 0xbc0f53fc, 0xd9e5eecf, 0xbf38143a, 0x7c5bd2b8, 0x4551c413, 0xf3033ea5,
+ 0x816f4ef7, 0xfa9e83fc, 0xdda3d887, 0x1f0137c5, 0x06f7f3a4, 0x01000408,
+ 0xe1aa080e, 0x43fd638f, 0x64654eb3, 0x2bf2cc9f, 0x873637bd, 0x3f5f2132,
+ 0xf208f80f, 0x7dbfb48d, 0xc021c149, 0x86e16e47, 0x423763e6, 0x037f68de,
+ 0x5789ffb6, 0x3b8ffe65, 0x4af60d98, 0x79a55e4f, 0x625e4c4f, 0xa960e279,
+ 0x239abf31, 0xd073c47f, 0x3bd807b5, 0x6607a95d, 0xd4cf3008, 0xff1033fd,
+ 0xbcb7d5e7, 0x878c342b, 0x04eb608f, 0xf41b978b, 0xa6e1ee30, 0x79f783d9,
+ 0x9d61f863, 0xc4c76cd7, 0x0fbc27dc, 0x1fd3ddf0, 0x36cbaf8f, 0xf74a9ef6,
+ 0xc6efd88f, 0x547b030d, 0x86b9b884, 0xa3dc2e69, 0x70c1fea7, 0x98395c12,
+ 0xcde35fd6, 0xb55e3a41, 0xa9cdfb3b, 0xa75f2f5a, 0x80772964, 0xf8b54e3e,
+ 0x3f5cd935, 0x7f8b508f, 0x372b4893, 0xf0b5c10a, 0x8f686c9e, 0x937de2ac,
+ 0x4728195d, 0x228eb967, 0x5f3183f5, 0xcbbfefcd, 0x476b832b, 0xc4591e81,
+ 0x76556ef4, 0xdfa658a0, 0x8d973d57, 0xf0670bbf, 0x2452555d, 0xf7bb9c6d,
+ 0x3791b75c, 0x21e4477e, 0xef09d5b5, 0x5afb18f2, 0x6437fbb5, 0xc7fd3ec1,
+ 0x3b46de87, 0x36624971, 0x76d359c2, 0x69df815c, 0x7ca36da9, 0xd8fbbf47,
+ 0xa3c763d9, 0xc887f25f, 0xbe026fa0, 0xc368d0fe, 0xd9fdddcb, 0xfd522f55,
+ 0xea85d3a6, 0xd3038368, 0xd5fd7a9d, 0xf09c0ae0, 0x49c9b82e, 0x1cf1e9f9,
+ 0xeafe055d, 0xf51eb7bc, 0x3a8ae3d8, 0xd3aff80a, 0xe066c3fb, 0x9124aae7,
+ 0x5f0febf3, 0x7ef8f3d6, 0xb9efcd3d, 0xbfa6edb7, 0xa160df68, 0x7ba9fed9,
+ 0x41fc8dc4, 0x02df92ed, 0xb66ed51f, 0xb3fd6085, 0xbef1da39, 0x1be82773,
+ 0xfbe65fd4, 0xa6051b99, 0x5873430f, 0xf772fa1c, 0x74be2b34, 0xfd8c7091,
+ 0xe99124bd, 0x84290aab, 0x5f1576fb, 0x2ffeb17a, 0xba69c71f, 0x1c77da0f,
+ 0xe31bd637, 0x838ef754, 0xf6fd527c, 0x5fcff461, 0xafb0dabc, 0x77ffd475,
+ 0x61cfc53e, 0xe874f538, 0xd0d941e7, 0xa4cfd427, 0x1ee78678, 0xf9243e79,
+ 0x47a97908, 0x2e6dacff, 0xf6fa04c9, 0x7eb313d6, 0xb74a25d2, 0x3e781297,
+ 0xc9737f74, 0x13ed38a4, 0x8c73ed2c, 0x7fb14ffc, 0x3a0f3c2b, 0xda0ef37b,
+ 0xbd93fa5e, 0x6df00f27, 0x4bfa59b0, 0x86dfc636, 0xb7fc19fd, 0x65fbbbc7,
+ 0xa5e9ef78, 0x10f140a4, 0x2068df66, 0x15245b87, 0xc0d1877f, 0x3ebe1ef3,
+ 0x8d797c55, 0x78bdff09, 0x9f95302f, 0xfb4cd06e, 0x2e178ba1, 0x7b3f7bc3,
+ 0x41563af8, 0xdb3eec42, 0x7da6b923, 0xc70fffd0, 0xb8a385d7, 0xfe4a381f,
+ 0x328c70c6, 0x385e81e9, 0x5fe54df2, 0x69310e17, 0xec366976, 0xa1b1ad53,
+ 0x0b66909f, 0x6ec07239, 0xf7ec5ffb, 0x0734201a, 0x61a899e7, 0xce57da6c,
+ 0x079f6039, 0x448e79c6, 0x40e3498e, 0x056d749e, 0x913f53ac, 0xe5a1afd0,
+ 0x8619390e, 0xfde1d56e, 0xd8952a2b, 0xb0754e5f, 0xe6f51986, 0xab876277,
+ 0xe5a258a4, 0xb879d5e3, 0xdd94e5ee, 0xfdf60755, 0xcfe17736, 0xbc931357,
+ 0x5ab27da2, 0xc7f68a58, 0x9b17c49a, 0x3d38df61, 0x0233d981, 0x58f9b179,
+ 0x267abc46, 0xbdf72daf, 0x31c41378, 0xaed4aeb6, 0xab6e7f06, 0x0c391c33,
+ 0x6e3df9eb, 0xdcaa3dfc, 0xf816e175, 0x83710abd, 0x314bd70d, 0x2b6bbc29,
+ 0x6078179c, 0x8bec1f84, 0x40d760ad, 0x5c6e35fb, 0x421a5bff, 0xe2af2f68,
+ 0xf5f6c0eb, 0xe7385493, 0x9296e8dc, 0x916bbd61, 0xb8056feb, 0x64efba5e,
+ 0xd03ae3b3, 0x4196fe63, 0x80cbef3c, 0x71cb4d75, 0x14f5e58c, 0x68575b19,
+ 0x3485c183, 0x44ffc3f2, 0x33d412ad, 0x6b0ed127, 0x04ab2f74, 0xbfd68e3b,
+ 0x7a78a0ec, 0x85e3993c, 0xe8f4e7d7, 0xa0cd93a5, 0xbd15c507, 0xef3a12f9,
+ 0x7a633f1d, 0x3fda09ea, 0xe7452bbc, 0x18778213, 0xe84947bb, 0xc1242587,
+ 0x74d0c76f, 0x9dfb0e74, 0xbd17aa5b, 0x3849c7e8, 0x491f635f, 0x0f7ec519,
+ 0x7ac3da1d, 0x83919093, 0x0cca98fb, 0xe2835ef6, 0x66fde371, 0xdd5677e3,
+ 0xb3a7f8c4, 0x67df2978, 0x43de5971, 0x895fae70, 0x784ee99b, 0x4f862137,
+ 0x0b7bcb15, 0x07cc0912, 0xcd544b7b, 0xe449bfe5, 0xd8834afb, 0xb70eadef,
+ 0xa32ed085, 0x35e98452, 0xd9f68a24, 0xf981d268, 0xe66de031, 0x0d2c35c2,
+ 0x278d8e2f, 0xbbe2c8ba, 0xc7ec1101, 0x788d5bb4, 0x44f5f04c, 0x96bfdeba,
+ 0xfc36e3c8, 0x66538c77, 0x7d7ee214, 0x5fab1266, 0x0fbbc815, 0x338dbcec,
+ 0xc69c61a6, 0xf58cefb0, 0x16dfb0d2, 0xab579872, 0xc17b5c42, 0x3a16ebb0,
+ 0xb6753e59, 0x8868e0fe, 0x0b53b66b, 0x2fee1b34, 0xf96af8b3, 0xb034e2e6,
+ 0xba1e16cb, 0x4ce4ed15, 0x8b65d995, 0x8250ce36, 0xdadee1a3, 0x8a07f43c,
+ 0x84484c37, 0x4ed5847d, 0x8575e27f, 0xfbe267e8, 0xc7b503b9, 0x355da6b6,
+ 0xab71e419, 0xca90128d, 0xeeb24bfb, 0xb17c0b1e, 0xcced0f21, 0xc6c109ad,
+ 0xd6efda24, 0xabfcd67f, 0x4ea7fe68, 0x8c38f0bd, 0xd5813ab3, 0xc051bbc3,
+ 0x12e73d9b, 0xc9bbe1b6, 0x3d6f8dfd, 0x1252f097, 0xa8ca7f7b, 0x7e536fff,
+ 0x80007d7c, 0x00008000, 0x00088b1f, 0x00000000, 0x7dbdff00, 0xd5947c0b,
+ 0x66fdf895, 0x666579be, 0xf263c992, 0xc2130922, 0x9e4e5e4b, 0x124c2280,
+ 0x4cb443c2, 0xe8202a10, 0xa79034f0, 0xbadc5d48, 0x30040cff, 0x5706b650,
+ 0x84ea2b11, 0xbbaac562, 0x351ba341, 0xb88080ea, 0xda446dd6, 0x8ffd16d2,
+ 0x4810154a, 0xfed2b58a, 0x39cf65dd, 0x7cccdef7, 0xb5f01993, 0x3efeb4ff,
+ 0xe7ddf7ee, 0xce73df79, 0x12e973bd, 0x2c614dfc, 0x5630a494, 0x51c1d8ca,
+ 0x618cf58c, 0x24dea98c, 0x064dcf06, 0x34e2d26f, 0xa37efac6, 0xf5e1bb67,
+ 0x926f6617, 0x25d8c6c3, 0x79fa2ed1, 0xa0b199aa, 0xcdb3b189, 0xc11c166e,
+ 0x336699d8, 0x1f966b95, 0x9fa0c698, 0xb9850e9a, 0xc55b19f2, 0x3f6336da,
+ 0x69923baf, 0x3d0155dc, 0xf4648e0b, 0x5bfe0977, 0xd528fcbd, 0xebc9dd5f,
+ 0xaa0eb2d7, 0x4f3192bf, 0xf76b3c07, 0x1cd0595a, 0x51df5fae, 0x4a1f69ac,
+ 0xd7bf51d2, 0x3b06fb25, 0x5bdd8c9c, 0x2abefc3d, 0x5d569f78, 0xfae1f662,
+ 0x13e38e58, 0x87afa8ab, 0xebe63af7, 0x77aeb188, 0x49de5c04, 0xac4e8a82,
+ 0x32b1d0ed, 0xe03ad6c6, 0x1ec62e9f, 0x6c7cd850, 0x15f7f6b7, 0xc2632919,
+ 0x9e2ad6ed, 0xf898c70c, 0xa8bc6a70, 0x88d48167, 0xc467dab2, 0x345e35f5,
+ 0x0ef3fbd2, 0x63075fb3, 0x3ff4c91e, 0x7fac2d70, 0x1953eb26, 0x909f53cc,
+ 0xcd5d8e38, 0x71258b58, 0xba673e37, 0x08a17d0c, 0x53333038, 0xf8337e71,
+ 0xc4ebf62b, 0x71944769, 0xed403ed8, 0xa98ed967, 0xc473400c, 0x8303735e,
+ 0x90b037f7, 0xce060aca, 0x28fdfa0f, 0x2359dfb2, 0xdd1be5b5, 0x09ecf2da,
+ 0x7e6332da, 0x9a4fd782, 0x1a4eca9b, 0x04fefdc2, 0x0311d6a6, 0x5802b72e,
+ 0x5eed7eb1, 0x0464e04b, 0x923beb1e, 0xaec6e535, 0x88c9c0ac, 0x1ff16a71,
+ 0x135ff059, 0x589d775f, 0xdf4607f7, 0x5bc00ead, 0x71190b3d, 0x46c140dd,
+ 0xacc658ef, 0x7c45e616, 0xf16fd81d, 0xcfe812b0, 0x00b76e66, 0xabbb1b7c,
+ 0xdef02595, 0x30ef876a, 0xe196273f, 0xfaf03569, 0x0e88058c, 0x39da8fe0,
+ 0x5bed99bd, 0xb713e415, 0xcdfedaab, 0xff00dde7, 0x4f0293dd, 0x24ac3d95,
+ 0x0ea3ac46, 0x5e1e91d6, 0x07eb39c7, 0x582f8865, 0xa5ec6fcf, 0xa6461748,
+ 0xf3d78524, 0x5cb5e1ad, 0x5dc6af0b, 0x1837a236, 0x1844bde7, 0xcea761a7,
+ 0xceb2846f, 0x7e4463dc, 0x3ce917b9, 0x1c72de06, 0x6f3c4c4a, 0xe0c73c43,
+ 0xfcaceda7, 0x1cc7e43e, 0xc7181fe4, 0x6527eeb6, 0x8f818b27, 0xfa1737aa,
+ 0x054dbea0, 0x547186fe, 0x08a9bff8, 0x6d3bd9c8, 0xe9d03255, 0xc3e73b29,
+ 0x7a2e890d, 0x0abc50ee, 0xe75d35e2, 0xd5fa47c9, 0xcc43b827, 0x66a3f1c1,
+ 0xcb601942, 0xf962c1ae, 0xefe81ebd, 0xcb1b9821, 0xf0098416, 0xcbc2c878,
+ 0xefca392f, 0x6ee308dd, 0x0de5e64a, 0xd5b9bd3f, 0x16ca093f, 0xe5439e59,
+ 0x416d0c87, 0xffdde03d, 0x44f5c982, 0x28f7b53e, 0x32305e58, 0x4d4c04f0,
+ 0x2365843f, 0x4226a65e, 0xf4b720e7, 0x9b769a2f, 0xeed05ea0, 0xa78427fb,
+ 0xfb39ff5c, 0x26363cf1, 0x4d7e7f66, 0xacdf797f, 0x53bf183f, 0xfbf87577,
+ 0x419dc4d4, 0xc2e76f3d, 0xe7a72c76, 0x9ff43f03, 0x6d89a2fe, 0x0623e285,
+ 0xda179b76, 0x632c5dd5, 0xd43908c1, 0xb679f023, 0x5b7241d9, 0xf943afbe,
+ 0xa9f9063d, 0x7d70e487, 0xfe46aa47, 0x7f5cb94a, 0x7f4d5af1, 0xc27c8e39,
+ 0x43dabd57, 0xe2feadf2, 0x121efa64, 0x736cf4f2, 0xf889e926, 0xc8d20ce3,
+ 0x1338f0f5, 0x72f8b059, 0xefa24ce3, 0xcbe61c72, 0x06bdb922, 0xa4240ce7,
+ 0x87bc8237, 0x750c2e71, 0x465f2525, 0x0276d99f, 0x67ac4591, 0x63341a9b,
+ 0x07dcdbff, 0xfc18be1c, 0xb844e520, 0x1edb51bd, 0x811b23f4, 0x4863edf4,
+ 0x7aacffb7, 0xd4fa91cc, 0x5038f066, 0x8af6a86f, 0x34372e23, 0x86647e4d,
+ 0x5169280a, 0xd97f3d39, 0xd1e881b6, 0x411f706e, 0x3aeddafc, 0xafbe1f97,
+ 0x483ce9b7, 0x730e2d27, 0x51bdf100, 0x7281c1b9, 0x076bf643, 0xb8f38f31,
+ 0x7a421b60, 0xd57ade3d, 0x0f54898b, 0xa9199266, 0xc6f7ff1f, 0x0f17c583,
+ 0x31bd8f1c, 0xfa0b88f1, 0x6e744b57, 0x910be00b, 0x1d0471fa, 0xdf63f744,
+ 0x779cc6a9, 0xff093d74, 0x8436f8b8, 0xe7fe1112, 0x8119ba6d, 0x4d2ef318,
+ 0x9e9bbe56, 0xdf25145a, 0x3c3b7f93, 0xd095ed88, 0x49f20a0f, 0xa32696fe,
+ 0x90bc2dfc, 0x3922e958, 0x73b5ee9f, 0xb6e385b1, 0x7d9a8ed8, 0xed988fa4,
+ 0x3ebfd913, 0xb849fd3e, 0x64aade18, 0x04601f88, 0x4ae37a86, 0x412bb070,
+ 0x1597e22f, 0xd3e50caa, 0xa76f3a40, 0x77d7f4f9, 0xeb11e743, 0x0edd516f,
+ 0x75fd6ba4, 0x99ca331e, 0xe6398ef5, 0xaa379410, 0x20f9d9ae, 0x02defa87,
+ 0xb7d6127b, 0x1cc8ad29, 0xc15a8f8b, 0x2df9c46e, 0xd669d64d, 0x1d669f23,
+ 0xf7e8dfe7, 0x9eb9925b, 0xb13fdd68, 0x9f1253c7, 0x79d2407e, 0xcb9b8f51,
+ 0x5856c754, 0xe7c0de9f, 0x0763896b, 0xc1e37eca, 0x0b7ecb6b, 0xa87569c9,
+ 0x44f68039, 0x549b78f4, 0xbe078f77, 0xf8f9826f, 0xc7c39cb1, 0x3aa254df,
+ 0x16d74376, 0x47330257, 0x4b3837d4, 0x6c17fe08, 0xdf0f4c69, 0xc63d2137,
+ 0xd3849798, 0x68efe4bc, 0xe8a2f93f, 0xc3b7f732, 0x5d0d10d9, 0xcba2c6b6,
+ 0x4b37a879, 0x3999fcf9, 0x9343fe72, 0x8c7c8ebe, 0x49b29ba6, 0x977c83cc,
+ 0x5876cf01, 0x66caa76f, 0x807d43ec, 0x9844d6b6, 0xe636cddf, 0x393e9900,
+ 0x32677cb5, 0xe7acb7ac, 0x3f219180, 0x1d693a74, 0xf47da275, 0x8e14a6b8,
+ 0x838a533f, 0x3dc7499e, 0xf8014f4f, 0xb824f676, 0x99d4f814, 0x0630fa02,
+ 0xbc088f7c, 0x9fc6d633, 0xf21c686a, 0xb65fac8f, 0xc3767988, 0x6b0250f3,
+ 0xb2bd8335, 0xc607c84f, 0x154fe7ee, 0x99c61718, 0xdde8cafd, 0xf58a2f64,
+ 0x80b5021f, 0x43d3d3f5, 0x77fd14e3, 0x585edbc0, 0xeade047d, 0xdbc221cd,
+ 0x6bdf46db, 0xe3c69f08, 0x772c74a1, 0x87933d1e, 0x70b670f8, 0x25efb5fb,
+ 0x6ee9006b, 0xd3d67e20, 0x0e2eeafc, 0x81e2fe62, 0x8353ab78, 0x2eeb5fa4,
+ 0x5877d1e6, 0x129cdfb7, 0x6c1b3efe, 0x2eb00986, 0x4270e666, 0x47c2c4f8,
+ 0x896be0bb, 0xa3eb500f, 0x081f02ed, 0x3ec48fa7, 0x4eef1fa7, 0x780666e3,
+ 0xefe66b3f, 0xdf246799, 0xfe7d0987, 0x005e4251, 0x0d1f33f7, 0x7a46ce07,
+ 0x91e95d50, 0xe2cea77a, 0xac3e6fb9, 0x67abbd9b, 0x5963c04f, 0xed15ada5,
+ 0x4f2665ab, 0xcb5dda12, 0xeb2bd3de, 0xc48409f3, 0x3c042b07, 0x5df732cf,
+ 0x36ff3f88, 0xc209e38b, 0x97ff769f, 0xf8bca3bf, 0xa2bf681d, 0x9346ef4b,
+ 0xcda56971, 0xf596fd8f, 0x876d3c54, 0xad5b2bf7, 0x2efd062e, 0x04fee29b,
+ 0xf765bded, 0xf21b5c59, 0xa438bf71, 0x5dfa0b3c, 0x03be60fb, 0x9d7581e5,
+ 0x06ecd337, 0xeb7ee093, 0x6de02b4c, 0x8964b293, 0x7dac0852, 0x1516ca7f,
+ 0x57feacf0, 0x281667e5, 0xc17f755f, 0x8c75f316, 0x1cb282bd, 0xd0ff59ed,
+ 0xfedf6899, 0xf646a712, 0x7f6fb72e, 0xca274479, 0x82a65bc5, 0xece5180a,
+ 0xce60d9d4, 0xb78a532b, 0xf4fc6198, 0x0ea14f14, 0x32935bc6, 0xb7f62661,
+ 0x7fb1bef4, 0x77df09dd, 0xa99acca4, 0x44de13e6, 0xcaccef7b, 0x926ed0a1,
+ 0x54b3cf2c, 0x56697f42, 0x27a7b616, 0x090fbf00, 0x77f68f8f, 0xbdfdbf67,
+ 0x1cd4e660, 0x53454bc0, 0xbffd0aa5, 0x96db729e, 0x36315731, 0x877281fe,
+ 0x983fc607, 0x15a664b2, 0x9469dff0, 0xf16d97f5, 0xcc9d58c0, 0xbe0186f7,
+ 0xbafef1ff, 0x9fa86699, 0x742dea96, 0xcd53fac0, 0x91996ff7, 0x65f81dfb,
+ 0x4fbd12a4, 0x1271482c, 0x90461cdf, 0x33ebade6, 0xf82afd72, 0x71d3873d,
+ 0x9424797f, 0x4ce511ed, 0x10dcee5e, 0x4e9c7e5b, 0x33b972e5, 0x8f77f621,
+ 0xef004b90, 0xb3e90ea0, 0x96181acb, 0xc027961f, 0xc409e64f, 0x3cb9db5f,
+ 0x639abe01, 0xd98e3e27, 0x5fe537df, 0xd3f53b80, 0xe8ac7aa9, 0x0d7290bf,
+ 0x71c56666, 0x69764cbe, 0xcf5975e4, 0xbfb79252, 0xeb7c154a, 0x5671f0e2,
+ 0x330ae56a, 0xb8470cf7, 0xc58b76c8, 0x4b47f33a, 0x88d052ff, 0xe2d6b9fc,
+ 0xacf9c0c9, 0xc19e57dd, 0xd787632e, 0xf8d72c5d, 0x98ebc24b, 0xf407ef4a,
+ 0x44b9fd0b, 0x5f31eeff, 0x57c95e07, 0x7d1a5780, 0xc33ad2bf, 0x3bfd69fd,
+ 0x7ee3fb03, 0xc57a019e, 0x1b9e7b18, 0x415eb853, 0xe422ebf8, 0x5f214ada,
+ 0x3d916a41, 0xabc5fe7e, 0x8fcd6f76, 0xf503771c, 0x7a7df80f, 0x412fee0a,
+ 0x2b1ca2be, 0xb0b33d53, 0x8a4f597e, 0xa079ed03, 0xde828db7, 0x8937a454,
+ 0xa694cee7, 0x76ef5a72, 0x863bb1c5, 0x3913f81d, 0x83c536af, 0x22c649f6,
+ 0xc4497e9f, 0x87fca4fc, 0xff453bfe, 0x1f9e9c25, 0xc5e7a7ed, 0x2fc23fc8,
+ 0xdf40dcc4, 0x5fce0763, 0x08ce36c1, 0x2582f5fd, 0x7091f380, 0x2ff4b6fb,
+ 0xb8ba87ed, 0xda912a7a, 0x260f1c65, 0x219ea0ba, 0xb9f9c5c5, 0x6bc4e3e3,
+ 0xe9755f51, 0xebe2e299, 0x2651b946, 0xe7bfa4e5, 0x764a8548, 0xbb2e584c,
+ 0x72919ec8, 0x87366833, 0xbdbfdfeb, 0x9446c667, 0x2fbe26ab, 0x1483d34f,
+ 0xe3cf0a2f, 0x2fae14e5, 0x2798f827, 0x24781d96, 0x08e52ed9, 0x75e1e3ad,
+ 0x5863ec95, 0xd7e85d9f, 0xf93f2109, 0x664c9eb3, 0xf0e13ec2, 0xb67bfa90,
+ 0xdcaff429, 0x47a5a64f, 0xa53b0659, 0xee105741, 0x89cfbf1f, 0x8263fba0,
+ 0xf3f1a20e, 0xc013e55d, 0x48708fc1, 0xc872e14d, 0xed056509, 0x17f4150b,
+ 0xb55cffc0, 0x3f35bdcd, 0x2e36de62, 0x1d7a9d8f, 0xe0576397, 0xfe54b48b,
+ 0x3b25efbd, 0x1e1873f1, 0x2ff98edc, 0x1d76f701, 0xc17dc1ab, 0x09f01d21,
+ 0xaf8da2d2, 0x598bfcf3, 0x29e7efd4, 0xeffeb93a, 0x1bb72e45, 0xd7ce3c61,
+ 0xbfd63f64, 0x3b5da83c, 0xdcdfde7f, 0x658f4e54, 0x68853dc7, 0xdaf30cc7,
+ 0x285fb8dc, 0xc07399eb, 0xdde1e500, 0x4b6b038a, 0xc1de1f3a, 0x4ba814f9,
+ 0x67ade5c0, 0xa5b5fb22, 0xbefa3a72, 0x38fc31d6, 0xcbc457a7, 0xcd3e08e2,
+ 0x7871b54d, 0x084cfac1, 0x472b554f, 0x9bfbf3e5, 0x0180f787, 0xf0075bd6,
+ 0xe12db140, 0x64b1d9d6, 0xf8f90583, 0x1f237338, 0xa258ef9f, 0xdd788b1b,
+ 0xebbec8c9, 0xf00f0f97, 0x147b4875, 0xe903b2e8, 0x5cd4eaf2, 0x71d86f1a,
+ 0x7c0c758f, 0x1376861f, 0xec3b95fa, 0x4c57dc01, 0x4dcdf54e, 0xedce7845,
+ 0x4a2064ab, 0xeb4dac1a, 0xfbef112d, 0x7d4177eb, 0x7e9f63a2, 0x36f3ce2c,
+ 0xc2bab6c6, 0xfaa981eb, 0x6f5a1fd1, 0xa02d3e04, 0xd6e11072, 0xfbf5e469,
+ 0xcf8a3316, 0x8cfbe834, 0xf7f41df8, 0xa3cfa22c, 0x2fc414ba, 0x6ed09bee,
+ 0x737bd3ae, 0x67d7dc14, 0x07a8dc98, 0xf4421f60, 0x54c2c87e, 0x26fff40b,
+ 0x574e513c, 0x8fd8efe9, 0x502aaaf0, 0xae242ddc, 0x60dc85da, 0xcd37dc41,
+ 0x7a25629e, 0x39dd5f64, 0xbff51ab4, 0xfa09e395, 0xcc7e8b31, 0xff30a2e6,
+ 0x2aef3afd, 0xfd48ffda, 0xa8514876, 0x8dd7439f, 0xb112ddde, 0x50fec22f,
+ 0xaa521ffe, 0xfa40ee73, 0xb23afb17, 0x7ac2d30f, 0x2295ed17, 0xfdde245b,
+ 0x3ca17e62, 0x7b48a3a4, 0x7ed3ed14, 0xb1dfd67b, 0xd9c83a65, 0x823a33f1,
+ 0xd152073a, 0x01ff33f3, 0xf60551d6, 0x70e005ac, 0x33972a5b, 0xfafdf287,
+ 0x30df9c44, 0x3abc3f58, 0xd31be09c, 0x938f0b64, 0xe90ffc2e, 0x482fee46,
+ 0xbfcfe04f, 0xe73b72a7, 0x1e5c6927, 0x978d21fe, 0xfb6313d3, 0xf510be2b,
+ 0x1f971354, 0xfcb9cb5b, 0x41b7ae8f, 0xedadfbf4, 0x668a31de, 0xef760f7f,
+ 0xf76e5486, 0x885fb91a, 0x0a9613c7, 0x873b06fa, 0xabb614f0, 0xda503c78,
+ 0xccf45fa1, 0xf372f2a3, 0xbfe8d97b, 0xe69fedbf, 0xb6f487dd, 0xf27a37f2,
+ 0xf1149c57, 0xbec99582, 0xbfdc64f4, 0xabf6c427, 0x75d6273c, 0x1f9199ba,
+ 0x1b8c53f8, 0x893dec82, 0xaf284371, 0x34e0f9da, 0x2cd5bfe4, 0xe5e0fe40,
+ 0x5c51373b, 0x61407970, 0x69f7052e, 0x1627ee5e, 0x47bd58f8, 0xdf4bf1af,
+ 0x931936ae, 0x77e984c7, 0x6e369b45, 0x58abb358, 0xf6f6fe53, 0x440b2569,
+ 0xfcb0a1c8, 0xa3ef4699, 0x1ef495fb, 0xd47ea76d, 0xc3f8d2ec, 0x461cee97,
+ 0x97f597eb, 0x77ad3731, 0x66816b59, 0xf395acde, 0x49f9bc49, 0xd4bb45ba,
+ 0x469e731f, 0x008ffbcd, 0xff08fefe, 0x4353d2ff, 0xa92d1e69, 0xba40ffbe,
+ 0xcac3cf09, 0xdabf1afc, 0xb027c724, 0x7ee16656, 0xff23a049, 0x5081ece5,
+ 0x6fffa72a, 0x71d1f70f, 0xfee305f6, 0xca0beebf, 0xcc397126, 0x0c3614da,
+ 0x6aa7e31e, 0xa0bfb4ed, 0xa7c52bbe, 0x616beb95, 0xa45f2d47, 0xd45177ad,
+ 0x5dea28bb, 0x6912bfc9, 0x2805299f, 0x0d7f78d7, 0xcff38f82, 0xa0ba351c,
+ 0x6e34f8de, 0x3d3916c7, 0x6cef5097, 0x438e24b3, 0x4b36ca7f, 0x52f5005e,
+ 0x38bafaff, 0x48336d1d, 0x033b8a3f, 0x5ffed6e1, 0x88a8b677, 0x0fb07dc7,
+ 0xfe587900, 0x8a1641e8, 0xae375390, 0x01cb3c53, 0xef2176de, 0x7d7cdcea,
+ 0x71a0ee75, 0x5d93f428, 0xd395e7c7, 0x23515fb1, 0x08d4e5da, 0x419a5f7f,
+ 0xc1cccfb3, 0x8d254e32, 0x9a9ce3cb, 0xea1432a0, 0xa3daef65, 0x875fd8a8,
+ 0xbb337a42, 0x41130009, 0xdc25d957, 0xa4b1b9be, 0x2636595d, 0x5d56870c,
+ 0xe00718f5, 0xeadd35a7, 0x8f737d46, 0x0d2437d3, 0x182279e7, 0xf8fcedc4,
+ 0xda2a3d13, 0x7a753fef, 0x619cd20a, 0x8ef4b838, 0xd6a7d46c, 0x6d9e7c13,
+ 0xae63fbfd, 0x4da22867, 0xdcddabfe, 0x23b3d19e, 0xa487db8c, 0x8c37d2af,
+ 0xe727bd24, 0xf4229e97, 0x3df33a45, 0xadfaa367, 0x68c9f08c, 0x861be93d,
+ 0x2cf6e6ef, 0x815577c7, 0xafbe0f77, 0xa8aab8ca, 0x6c17de05, 0xa14baa0b,
+ 0x62bbcbdd, 0x85cb83fb, 0x4c75813e, 0x75c9f5c2, 0xc82e495c, 0x7e38867a,
+ 0xd60fc90a, 0x1ff7b119, 0x2f7d2230, 0x216d347f, 0xa36eb7ce, 0x30949991,
+ 0xf4ea7ffc, 0x64f9c6ce, 0x082bb477, 0x93dfe91b, 0x1dff4ae3, 0xfcfe477e,
+ 0x96f928c8, 0xfe5c5fd3, 0x2cf7a75f, 0x1b67948f, 0x6927848d, 0xc7e7873f,
+ 0x69d5fded, 0xeabecf5c, 0xf9c12ef4, 0x276d7434, 0x3daacf7f, 0xf9631a1f,
+ 0xe2f9a3ab, 0x6a54704a, 0x6ea0bef8, 0xeb8039be, 0x25547f2f, 0x68dda83a,
+ 0xdd5938a4, 0x9fb8fb33, 0x46e61ee7, 0xb1d75139, 0xe30e594f, 0x4fb33ed6,
+ 0xd7011159, 0x05017541, 0x2ec233e7, 0xafcb90f9, 0x3f47ba68, 0x872dda32,
+ 0x9c4e5c2d, 0x15f9b72d, 0x8359eb80, 0x9deb0eaf, 0xfdbab2cd, 0xbc3c61f9,
+ 0x11fa6fb9, 0x3fb037cc, 0xb3e20a67, 0xd33bb755, 0x475af50c, 0x5f48dd19,
+ 0x36fa753f, 0x54525c23, 0x4fb6276f, 0xd7bbb34e, 0x89975b43, 0xfbbca115,
+ 0x1f1870ba, 0xefe32745, 0x85d3fce1, 0x91db8872, 0x813fc845, 0xa7b4bb34,
+ 0x361dae48, 0xc73c75f0, 0x9eff7cf8, 0xe89079ea, 0x8d0a48f8, 0x54175d9b,
+ 0x7f9d9fd0, 0x6b9239e6, 0x9d30ffb2, 0xe4891e79, 0xb3cf2bdf, 0x56f488c3,
+ 0xf950e42b, 0x8f947ba3, 0x4bfde623, 0x6e91f430, 0xba019fb2, 0xfdf7d1b4,
+ 0x3ea8d333, 0xbdf0b933, 0xe16aed42, 0x79088afb, 0x4311d723, 0xf5c3ecee,
+ 0x1cf44ed8, 0xc82772e4, 0xbe628dfd, 0x157cf8d1, 0x9a7c1fe5, 0xde99ea06,
+ 0x3123fd1b, 0x48787a2e, 0xe527f502, 0xbedf3440, 0xe51ce82a, 0xfe46cea5,
+ 0xe52bb25a, 0x22bd64fc, 0x34fec567, 0xc10f4382, 0x4a977ea1, 0x7a32a9eb,
+ 0xc111de87, 0xfd16bf0f, 0x03f9b81d, 0x07fdca23, 0xa25dfdfe, 0x8536fac7,
+ 0xedacf1e2, 0xd43ce35d, 0xf4a7fe47, 0xe2ce6768, 0xf1db0126, 0xa784bbc2,
+ 0x2e5c9d59, 0x53ee77d7, 0x74c2d997, 0xc0e67f9a, 0xf56748ad, 0xfb86261d,
+ 0xdfbfa022, 0xe9a27c20, 0xca47c254, 0xb4f878dd, 0x9472e0ce, 0x47e48df9,
+ 0x3e54fd85, 0xdca429fa, 0x4eaa7bfe, 0xfbf809f8, 0x1cbc690b, 0xa7df1fa6,
+ 0xdcb08f08, 0xe45f10b5, 0x603a299f, 0x5bb87dc6, 0x5a7f3f21, 0xe4678725,
+ 0xc6c7aabc, 0x54ce9b97, 0x50d437a1, 0x587b1cde, 0x7fcbf7be, 0x810bfed1,
+ 0xe41f786f, 0xd410d9ef, 0xd1fe72f3, 0x7277cbf8, 0xce831b7d, 0x11d71bfe,
+ 0x3da4dfad, 0xc9e6e920, 0x8f46aa5d, 0xea469dd8, 0x731b0ecf, 0x728ec79c,
+ 0x61d8cf1e, 0xc76cfae0, 0xe500737a, 0x780b9bc9, 0xa17d995e, 0x43cf8831,
+ 0xf875a5ba, 0x1f3650fd, 0x5ba755bf, 0x0dd6e583, 0x7842d636, 0x4b3a24f5,
+ 0x19127e91, 0x1e5c8f97, 0x973cf03e, 0x5b7e7567, 0xeb3fc180, 0x5397737c,
+ 0xe2cd39dc, 0xf333b8c6, 0xb3ce341d, 0xd72ba40f, 0x2e8dfb73, 0x83ab3f78,
+ 0x03c49ff3, 0x2fa253c8, 0xae120fc9, 0xb8727861, 0xf8927e4b, 0x67f4bbf8,
+ 0xa77cbd03, 0xda3daabc, 0x46dbdc78, 0xbe4ed5df, 0x706c3acf, 0xc7869fa1,
+ 0x6fd1e217, 0xb3b7baed, 0xb51d824f, 0x7a2df33a, 0xfd85be4a, 0x27bf86ac,
+ 0x3817bc09, 0x74afbeb9, 0x2da9ba72, 0xacbe20e9, 0xfc44d93d, 0xe5c19b6c,
+ 0x5684ed9a, 0xcff6331e, 0xa8dbbd62, 0x63b5955d, 0x5477e61a, 0x7038ae3d,
+ 0x6e4f1fbf, 0xfcf0aede, 0xbd774fb8, 0x72f98891, 0xf2b02bec, 0xe1629e31,
+ 0xe4eb9deb, 0x5eece272, 0x7bd13800, 0xf672f193, 0x63fa95fb, 0xc20a63c1,
+ 0xfac056b3, 0x139533ec, 0xec7e84ff, 0x61ee49bd, 0x9ecfe4b0, 0x3feee9b9,
+ 0xeecfbcc1, 0xf746e299, 0x978b5a65, 0x69cfa7e8, 0x037ee371, 0xf40cf7c4,
+ 0x78efae17, 0x685af123, 0xabe9fa77, 0xd76e508b, 0x799e798a, 0xe10ebf5e,
+ 0x7fc9e1b2, 0x6bdf8c9b, 0x09aa4a03, 0xf8fbd9c7, 0xbe63677f, 0xf2469eea,
+ 0xfd3cb517, 0x17f311ba, 0xfe768174, 0x03926f7e, 0xf9fe9deb, 0xef08c9f6,
+ 0xfa168e96, 0xede7e67e, 0xe4f03e54, 0x77f6bdbf, 0x1378e3f4, 0xccef58dd,
+ 0x2f09fbf3, 0xf2953e75, 0xf5d1e2db, 0xb9fb7d8e, 0x8f3d44bc, 0xcb9f307c,
+ 0x92d74931, 0x793f4f7e, 0xbd48c4db, 0x0ab7df21, 0x026b4e7f, 0x099f23d7,
+ 0xe0adadfe, 0x9ecfcef1, 0xfda7ccb5, 0x1c343181, 0x6375c5f7, 0x2ddc5d38,
+ 0x71d751e0, 0x46c1a187, 0xdf9fa9ed, 0x73e3df02, 0x27e7d02c, 0x64852923,
+ 0xd7ca25cf, 0x0faa57f9, 0xbfa026f5, 0x1f45e6e7, 0xeb1f382a, 0x2d432698,
+ 0xfe69f3cd, 0xf91d561d, 0x6c6d6cbd, 0x38bffb3f, 0xe02ec26d, 0x59dd907c,
+ 0x3922e39d, 0x8b0f7260, 0x6bb387b0, 0x27182d7c, 0xcfad7ebe, 0xbe3c07ad,
+ 0xb4e8ea7c, 0x727e5041, 0xf84c52a4, 0xcf5c2bd7, 0x4e346df9, 0x81c1fa3d,
+ 0x3e0b768f, 0xf5307749, 0xdc03921a, 0x32a5501f, 0xaa7e46d5, 0xf513923e,
+ 0xee0f42ad, 0x736e7e11, 0x764dde5f, 0x26bb676a, 0xed061f62, 0xf72a366c,
+ 0xf310fde5, 0xe7f8674a, 0x1971de93, 0xa467be69, 0xf27e603c, 0x8b7e4a7b,
+ 0xbca11bf6, 0x57d1fcc1, 0x285de59d, 0x3d33e51f, 0xefe4bf8e, 0x74b8fbe2,
+ 0x15ca174f, 0xa35537b6, 0x95c9e20f, 0xe79f3703, 0x0f95fb7a, 0x901b0e89,
+ 0xdf7c710e, 0x5ede8d49, 0xe815c24e, 0x890fa5f0, 0x7177970e, 0x55d0daf9,
+ 0xd4fdc46e, 0x69d7e10e, 0x7484f410, 0xbfe8fb84, 0x9c69933a, 0xe1a1c986,
+ 0x0bcea728, 0x12ff3bba, 0x3a43b7a7, 0x0e01f91d, 0xdedd1eed, 0x8fd40ca2,
+ 0xf0978d4a, 0xe6f800dd, 0xa3daf376, 0xd7d56768, 0x6bf23730, 0x07e0a743,
+ 0xbe117bb0, 0xcbd55d0d, 0x6941bfb1, 0x0ddfc933, 0x41b4c976, 0x63a86e50,
+ 0xd96fc8a5, 0x425e2abb, 0x7c5d60ba, 0x035d9e3f, 0x4dd22cf6, 0x9f5bbd5a,
+ 0xdb8f7a8f, 0x2c8fd7bd, 0x723bf6a3, 0xf2e7145d, 0xf38a3157, 0x19fb40ef,
+ 0x68d65df5, 0x36fb3f6e, 0x5cc5dd92, 0x6537e409, 0xd60d753e, 0x622ff06f,
+ 0xcd11d794, 0xb4292fc7, 0x5808680f, 0x56681f29, 0x1a7fb717, 0x9f1f38ba,
+ 0x4f91f093, 0xe4adcf43, 0xc4c17f8f, 0xd0fe11fc, 0xce9a5f37, 0x268becf5,
+ 0x359fb3d2, 0xb0c7d87b, 0xbc85b7a0, 0x6dac7097, 0xdd21d7cb, 0x09937632,
+ 0xcc4cb1e7, 0xf5c0cda3, 0x03d0b246, 0x3cf8db05, 0x77e174d4, 0xa789d74c,
+ 0xe2e79b51, 0xe17f93f0, 0xc88f189c, 0x39e85d22, 0x797eba18, 0xeea4f890,
+ 0x9a5fde19, 0x677853c9, 0xfb4abd04, 0x0b1e9a28, 0xbbd9b8c4, 0x4c282a0e,
+ 0xd1cd77b2, 0x35f5f9f0, 0xeb08d82c, 0x2e977ebc, 0xd91c6538, 0x9e490b4d,
+ 0x58b237af, 0xd2232af9, 0x9556fdb9, 0xbf442dea, 0x36cdd576, 0xb93fa477,
+ 0xb3a3c12a, 0x24571da0, 0x12ded8fd, 0x4a9d1b8c, 0x6f11bbb7, 0xd25dd2e3,
+ 0x5bd8d30e, 0xdcdff703, 0xcda1bc0e, 0x1ff70e3f, 0xf309f581, 0xda09ae29,
+ 0x0edcfc8d, 0xf7fb8f68, 0x9cfed7dd, 0xb85bdfef, 0x070402ff, 0x6f5499c9,
+ 0x9d8ffa09, 0x5cb5de05, 0xb1ddd93f, 0x93aaf3d6, 0xcdc0e7af, 0x3ee216b7,
+ 0x8dae61b1, 0x5781e1f8, 0xde9ca594, 0xbee21140, 0x83f9c7da, 0xe13c7f01,
+ 0x3b247a22, 0x1bc9a1aa, 0x9c8f4d88, 0xaec01a5f, 0xe81b3b42, 0x93b70d71,
+ 0x13f38c6d, 0xbfb94ba7, 0x6915b947, 0x8d3e4acf, 0xbf497be6, 0x35ff7cfd,
+ 0x81bcfdf9, 0x8079e3f3, 0x3f7bd203, 0xe9ccbf9d, 0xe07aeb7c, 0x15bef847,
+ 0x4225b1f8, 0x7fef47fe, 0x1fb89e70, 0x1ef6f290, 0x3a5177a7, 0x6fdda1ca,
+ 0xab50c66d, 0x2f0d8f94, 0x397e196f, 0x958ccbbb, 0xf0335fa1, 0x60fd246b,
+ 0x445ed68c, 0x09ea3f4f, 0xfed8baeb, 0x6dd2bb8f, 0x3f3fcddf, 0xaee52f30,
+ 0x7981d2f4, 0x73a8e929, 0xadbb6f10, 0xa58fb401, 0x3e7a291f, 0x499f044b,
+ 0x03fdca7c, 0xfeb021c6, 0x37ef82fd, 0x888f7a89, 0x84bec467, 0xf3a5c1f8,
+ 0xf679487d, 0x6c91f471, 0xb5f97df7, 0x2f5238e4, 0x8c8dd346, 0xaa7ae0a3,
+ 0xd7afc4c7, 0xcfec5fb6, 0x29f8e8a2, 0x800b5fc1, 0x6dde7037, 0xc417e086,
+ 0x19d8778f, 0x99f813e5, 0x71e31527, 0x7ce08daf, 0x386fb234, 0xfa66b7b6,
+ 0x92ba44be, 0x8f7c5d7e, 0x115aaa71, 0x6bddacbf, 0x7f9e4408, 0xd18337b9,
+ 0xb376bd38, 0x91fc0f5f, 0x87dbe99b, 0xcc15fded, 0xf33d441d, 0x2b8a168f,
+ 0x8a5b8181, 0x8591a6f2, 0xefce1112, 0x205efb25, 0x0cf7d5fa, 0x39e3bf47,
+ 0xdf0e3425, 0xdafe109f, 0xfb5fc213, 0xcf7bd77e, 0x17ad02be, 0xf16e72bf,
+ 0x5ece918f, 0x7d21e4b4, 0xe7f4b09c, 0xdda125bf, 0x92b9817d, 0x690e772e,
+ 0x55ef5991, 0x2767fc23, 0x7ffdb1ec, 0x373c0b6f, 0x532b788a, 0xb7c3ed19,
+ 0x19f97067, 0xe3c4bf3e, 0xb4ebefad, 0x1cf937fe, 0xdfe1c193, 0x501ce719,
+ 0xd7df0661, 0xfce10e74, 0x50aed7d8, 0xdd66afbc, 0x41eb3ffa, 0xb5acd42e,
+ 0x9f09e907, 0x71ab8ed1, 0x283a83f8, 0xb970309f, 0xcd737f04, 0x07fd6165,
+ 0xc849d4f5, 0xc5077e33, 0xfd0a96bf, 0xcde9acb5, 0xa15fa1bf, 0x49e66546,
+ 0xf2c71845, 0x9f041e1e, 0x4f2db53e, 0xf2bff144, 0xa3a67747, 0xd458ca7e,
+ 0xa6c1f226, 0x55fed03a, 0x2fe8373c, 0x6f672f59, 0x132764a9, 0x1ede001d,
+ 0x22f6f0cc, 0xe24a2f1f, 0x7745c17e, 0x08fe035a, 0xf057b879, 0x7cfd3461,
+ 0xcdbce710, 0x01151997, 0xaa616fec, 0xefd46ff7, 0x7234e79d, 0xfa12bced,
+ 0x5f4823c5, 0x4fddd877, 0x22f2eef0, 0x05d263f3, 0x0e316bfc, 0xb7b1a204,
+ 0xbaf867b0, 0xbee3a47c, 0x5fa1dfbc, 0xf0e4dbab, 0x91bbf0bb, 0xf176cbbe,
+ 0xe3f141e2, 0xd2232e40, 0x8545c347, 0xf76961e8, 0xae51c79b, 0xa221a837,
+ 0x1b66a593, 0xa2e1b1e1, 0xd5a9e9ca, 0xdb243670, 0xa4d7ee03, 0x6032d27a,
+ 0x277bfe9e, 0x093c5325, 0x17c389f8, 0xe39c452a, 0x37c332f8, 0xf7e00328,
+ 0x36f13590, 0x305d7fdc, 0x8f3092bb, 0xf408d1ad, 0xe7753570, 0x43d84735,
+ 0xa5aec72c, 0xfeb7ee83, 0x6e5af386, 0xaf5119f6, 0xd134f0af, 0x4945b179,
+ 0x98c752c1, 0xd24fbc48, 0xf5fd1a5f, 0xc8497ef1, 0x3c8df797, 0x9d20646f,
+ 0xcf6c3c73, 0x39b2f510, 0xc79fbcbf, 0xe7c39e6a, 0xbb427828, 0x728887f7,
+ 0x170f2891, 0x7979d2f5, 0xf797e09a, 0xd17af1c7, 0xe3152ce3, 0x99e1997c,
+ 0x7682708c, 0xc7d22341, 0x673a166b, 0xfe404ac4, 0x935bbca1, 0xc82c764b,
+ 0x770869b9, 0x4c982718, 0x67a44cf5, 0x41c81358, 0xa96f67c0, 0xb5b3e08b,
+ 0xe305e81c, 0x289aaf41, 0x2bf1241e, 0xcf8d1af1, 0x77ca1985, 0x181f4fcb,
+ 0x51985ebf, 0xcd7e303a, 0x17c250d8, 0xf38c4bd1, 0xf5f0f11f, 0x03c73b6b,
+ 0x0cf2ebf0, 0xb1c183d2, 0x49b37c91, 0xb5ca51c0, 0x78b413f7, 0xe39d3cfd,
+ 0xbbd45ea1, 0xda1f7684, 0xe23eeed1, 0x7853f7bf, 0xae02b4fd, 0xfe5da497,
+ 0x5f2e024f, 0x529f6ba6, 0xd1fb44cf, 0xe2f214bf, 0x47ee74cb, 0x8ddebc07,
+ 0x09fa95f3, 0x19304ce4, 0xebd178f8, 0x6c339226, 0xd5e51f63, 0x83ffbd40,
+ 0xea645af0, 0xf41535bb, 0xdec10fca, 0xbb511631, 0x0647284b, 0x48c7efec,
+ 0xd433b0ba, 0x0e19addb, 0xf4941f6e, 0x48d7b8f1, 0x0ca5aebe, 0x657287e4,
+ 0x210c63fc, 0x6bf0e40b, 0xc142bf22, 0x6214aebc, 0x07f61767, 0x8c97ff70,
+ 0xa3dc30d2, 0xe8213bc7, 0x450cd1e0, 0xb215bc25, 0xaddbc442, 0x5f6e7eef,
+ 0x139e5d0c, 0x4d9365e7, 0xe7ec76be, 0x916fddec, 0x18c27e9d, 0x8b66de1c,
+ 0x7c18ddf1, 0xfc2521ec, 0xf4a7b6fd, 0x98d5e37e, 0xc1f67e7f, 0x4bdd619b,
+ 0x1c6ef47b, 0x5f3de972, 0xed1e33bc, 0xc5031eec, 0x6fdf406b, 0x4dde7153,
+ 0xa13caedc, 0x67c1d2d3, 0x3df76977, 0x907a0baf, 0xdca572e7, 0x157cfa91,
+ 0x93797373, 0xcb1bb890, 0x3b71dd1f, 0xce5dcb9d, 0x003d87bc, 0x666bd3f7,
+ 0x3b7c5d92, 0xcf5e51f3, 0x39ed56b2, 0xda6d15db, 0x073bedf2, 0x3925c39c,
+ 0xfd102abc, 0x2ba5f85e, 0xf3fbeb63, 0x333f2e82, 0x7afdf88a, 0xfdf8cc53,
+ 0x09fc85ef, 0xb4fbd9c7, 0x2f57fbf1, 0x8c6fbf1f, 0xed87df8a, 0x3df8e888,
+ 0x6113f7ef, 0x91bf606f, 0x2acffc71, 0xa3e3af62, 0x58b7690c, 0x9f19f935,
+ 0x125bb00c, 0x45e37be9, 0xd8f99c4b, 0x2b67fde8, 0xd7d38f63, 0x5f368e3f,
+ 0xe79edc20, 0xb5fdc809, 0x8bc693a4, 0x6567a459, 0xe1c7da59, 0x3df43976,
+ 0xf4babcfa, 0xf8be4b6f, 0x2ce66158, 0x176d47f2, 0xf29bbc76, 0xbb463f33,
+ 0xba72f908, 0x4c10b5eb, 0x278fd971, 0x8487570e, 0x1d7a26f9, 0x42675f40,
+ 0x98d8f211, 0xfd234f69, 0x3a6e66eb, 0xfee82797, 0xe8abbbd6, 0xbdffcf7c,
+ 0x322332a7, 0x53f72a6e, 0x8f69460d, 0x96fa34d9, 0x65e3e945, 0x1d916f5d,
+ 0x70d7f606, 0x7a7f3e14, 0xc3d26ef5, 0x1d37992b, 0xd5f7bde9, 0xe56e7411,
+ 0x3961eadb, 0x4bfc9b9f, 0x35bf3c0c, 0x3987ec8d, 0x75373e62, 0x67503b73,
+ 0x1c6818f6, 0xd239730f, 0xe7cd8b69, 0x8554420b, 0xf3fd75f2, 0x631de747,
+ 0x15fcc493, 0xbdf00f6c, 0x52d93c4e, 0xdbce265f, 0x31eae384, 0x8990260d,
+ 0x6e8996cf, 0x28a73e17, 0x83cf955e, 0x6b1a79e3, 0x3afac1ca, 0xd7cf4873,
+ 0xc7483309, 0xa2f0fdf6, 0x37945db2, 0xeb70bdce, 0xb36f7c0a, 0x8a313c93,
+ 0x04cf4c79, 0x6dfc88b9, 0xb75c6666, 0x4d3c16c9, 0xf4f133f1, 0x8f88b857,
+ 0xf91843fd, 0x07581241, 0xd9b53f9d, 0xb171f9ce, 0xb050e60e, 0x085c716c,
+ 0x9ce27ee2, 0xf3c7e6c3, 0x672f20c4, 0x5f3fa265, 0xc44ad5f9, 0xee67c80b,
+ 0x5df78a17, 0x11f3f20d, 0x88a5de42, 0x7908b5f9, 0x8adcc597, 0xe480c7b8,
+ 0x95f6fddd, 0x267ee037, 0xa3f7798d, 0x71387bbc, 0x32fdc506, 0x93e68f98,
+ 0xc8d5433a, 0x5b57a72d, 0x46af98ce, 0xe7053bcb, 0xbed3e597, 0x9413b337,
+ 0xbd04a497, 0x69529799, 0xfd12361f, 0x37210631, 0x3e78598e, 0xcf3166c2,
+ 0x8853333b, 0x78598e6e, 0xb6b7c25e, 0x7ddadc5b, 0x3f0a437d, 0xdd3e7fbf,
+ 0xc0f1c66c, 0xe113b98e, 0x07cc7607, 0xdfce167e, 0x41d29c2c, 0x6f9b0279,
+ 0xe01bdc54, 0x6bbb66fd, 0xeba40abd, 0x7f70a99f, 0xc728ea8f, 0x3cf69c7c,
+ 0x44f31b87, 0xf7be451b, 0xf6a38b66, 0x9a63f219, 0xb7d63d78, 0xed96e319,
+ 0xac0e1d5b, 0x37d95697, 0xaafb88cd, 0x9bb1cc15, 0xaff7a0c5, 0xbe608f80,
+ 0xe032c73f, 0x63f41149, 0x85bae23d, 0xefbe20d6, 0xf0177fc1, 0xdc3294f2,
+ 0x82bff2bf, 0x773a42ee, 0xd27a3cc9, 0x85dd8d97, 0xbc60d86f, 0xe485b982,
+ 0xf256f7af, 0x72132fb8, 0x571cbc60, 0x61b5d9f0, 0x85efa7ba, 0x5bb43ca2,
+ 0x4cd37ff8, 0x80ebae3c, 0x91c4ca21, 0xc69fac43, 0xe4cdc1f9, 0x6bd3e71f,
+ 0xfb0ff858, 0x4ff70cab, 0xf86a6972, 0x60ef9873, 0xbbb322a8, 0x8dea0ea5,
+ 0x91fb8357, 0xcf15afaf, 0x543cf142, 0xe5e9237e, 0x65cd9d1e, 0x373e71d4,
+ 0xc3aba017, 0x94b847ab, 0x60b4b639, 0x4129d73f, 0xd8cde67a, 0x9fd382de,
+ 0xc94cfc23, 0x9e00c699, 0x00996b37, 0xc8bf2678, 0xffa30f9f, 0xac2fff5a,
+ 0xcc74f118, 0x279ef520, 0xb9ffe789, 0x0ed53d68, 0xce97593e, 0xc22e7b33,
+ 0xcf3f28f9, 0x8b74d0c6, 0xa997fef8, 0xd7974955, 0x300f3cbb, 0xe5cf4b25,
+ 0x871e0ce3, 0xa66f9c6d, 0x7146e5bc, 0x7d53030f, 0xf08c3ff9, 0xc5b8c8af,
+ 0x7f3606bb, 0x46fd8c5f, 0x07b7164a, 0xfdc0dce6, 0x1f228dc2, 0xcc4f7e47,
+ 0xbfb27ee2, 0x377b4e64, 0x1e3dec93, 0x949dfd6f, 0x48d9235f, 0xf2115f94,
+ 0x5f248fe5, 0x278edfca, 0x85dfb47f, 0x29e799fc, 0x40bed036, 0xef2921c8,
+ 0x68ef22bd, 0x1018f301, 0x1ee23d4f, 0xabe5a395, 0xccdd0e48, 0xf7fef47c,
+ 0x00ff3c15, 0xfd80d308, 0x6b4334dd, 0x6af3cd3f, 0x8fcf37cb, 0x3e38afb6,
+ 0x7c0bb8e4, 0xa473efda, 0x6b433c9d, 0x87fa2f27, 0xcf4992af, 0xfea2fc67,
+ 0x3e70e0d2, 0x3e546351, 0x27c88351, 0x3c2aec6a, 0x4f911694, 0xf3cdd8d4,
+ 0xaeba1a89, 0xedc44f94, 0xb029af29, 0xde24e31f, 0xec94d25a, 0x727f910d,
+ 0x8a4ff310, 0xaf6e74c2, 0x0c3cf3b0, 0xa2bca1e6, 0xce95871c, 0x8aeab45d,
+ 0x9adb8fc8, 0xddf8d768, 0x5577aeb7, 0xbfe93d61, 0x4843f995, 0xc3f6b137,
+ 0x5f7c59d9, 0x7ee143b3, 0x3302ff74, 0x059d3bed, 0xc15c4d5e, 0xd1c767a9,
+ 0xa66ef8af, 0x3f27d64b, 0x2f830ec9, 0x019e18ab, 0x8979d185, 0xb67af6fe,
+ 0x5190fc91, 0xea99ca72, 0x338038a6, 0xf5f92c69, 0x921775e7, 0x2cd9923f,
+ 0xb84a61ee, 0xdb7379ff, 0x69ebcc55, 0x97576eec, 0x3774c2db, 0x43ec4b36,
+ 0xf48accac, 0x7bd7efda, 0xbd7e44ce, 0x30b79364, 0x19d7da0b, 0x8bbfe483,
+ 0x1f7a57a0, 0x2ede5f4f, 0xe150c5e8, 0xe602b05d, 0xd18efbd7, 0x0a6bfb8d,
+ 0xcfff41cc, 0x7e4c94bf, 0x230e7549, 0x9cb1b53d, 0xf45e93cb, 0x3e3ac193,
+ 0xfaf7e64d, 0xa466ac6c, 0x4ca7cf5f, 0xc55e3a23, 0xe83d8702, 0x7405db47,
+ 0xd2cf7918, 0x8eb96d1e, 0xa9fe9075, 0x3d00667b, 0xf2947c93, 0xf4b99eb8,
+ 0x741b8c06, 0xa1b3db6a, 0x285c395a, 0xbcf147f4, 0xff982da9, 0xf2e3ac50,
+ 0x0f772d91, 0xf5fb439a, 0x2c4f8e45, 0xa17f7228, 0xebaece5c, 0x73d29fb5,
+ 0xa17ae7fe, 0xad1ff454, 0x3d854abf, 0x17e41937, 0x7da56fee, 0x7ca9f506,
+ 0xcfadd750, 0x59e785d4, 0xbb49da22, 0x890bea50, 0x8c09f2af, 0xbbb579e1,
+ 0x1a7c84b2, 0xbe2086c2, 0x13e27fa1, 0x29583705, 0xf71fbfd4, 0xf18ad785,
+ 0xa8fc1e80, 0x733afdbf, 0xb36be900, 0xd2fa44d2, 0x3c3ff68c, 0xd23e2ab7,
+ 0xe35eff0b, 0x4c7d23d7, 0xdd374d64, 0x9926f500, 0xb728ac7b, 0x31fe4e80,
+ 0x585a7e92, 0xa29f6f30, 0x7efa23a1, 0x98edf936, 0x5af52474, 0x9edcf7f0,
+ 0x74bcc599, 0x0fe793cf, 0xa83aeedc, 0xd8267df0, 0xeed1079f, 0x93375b7a,
+ 0x2c2664e8, 0x3955eb03, 0x9e9ff8b4, 0xdf472da9, 0x5ad0c50f, 0x48744328,
+ 0x9c540678, 0x51bdf44f, 0x98f7291e, 0xb3e5ee56, 0xf8de78af, 0x423fc396,
+ 0x1d7583ff, 0x0ef6891b, 0x8fc4aa58, 0x27b0f4d1, 0xb78f7beb, 0x118ac9ec,
+ 0x7e15e96f, 0x68586be5, 0x40ca33e5, 0x687f3b7a, 0x82333e9d, 0xbc7f252e,
+ 0x1379e06c, 0xae3cebca, 0xc6ccc135, 0x252e1104, 0xf928ffdc, 0xd3a41ae3,
+ 0x95fd3094, 0xa487f789, 0x06cc197c, 0xd75dbd23, 0x01ea0965, 0xbfa2853f,
+ 0x8afe906b, 0xdc89f6c2, 0x184cb477, 0x98f96740, 0x4cf60e17, 0xb495d201,
+ 0x8e958a4f, 0xfde73c16, 0xb6f74bfc, 0xe8237ce0, 0xc3842dea, 0x8ae80559,
+ 0xf4036afc, 0x147bf6ad, 0x4bfc49dd, 0x359cba7b, 0x6e677ed1, 0xc1b3d702,
+ 0xcf49dbea, 0xba24b882, 0xa70e737b, 0x21e62abb, 0x5a672bba, 0x6b34a97a,
+ 0x0974d1cb, 0x74b4ea23, 0x8bba23e7, 0x7478d7a6, 0x4ee91837, 0x2bd4dbea,
+ 0x48e7ddd3, 0x8fc5df77, 0x3eee9039, 0xa7c672cf, 0x937a68bb, 0xc59f6cf2,
+ 0x75768951, 0xfa428d63, 0xa19df8a1, 0x511e582d, 0xf6764f9f, 0xd93764be,
+ 0xfc4d8ddd, 0x478f497b, 0x0533798f, 0x7cf7c56b, 0x1b96256f, 0xe877c1d7,
+ 0xcf18f4ba, 0x0f7a19ab, 0xa1b85eff, 0xbfbc0de9, 0xdbcfd1a0, 0x337a7cbf,
+ 0x6c0a879d, 0xdbcbed16, 0xd8dcb12a, 0x8a7fdbca, 0x31abae71, 0x82d02dbf,
+ 0x96daafef, 0x6fdbe6ef, 0x114fd76e, 0x3ca7ddeb, 0x6bb506f7, 0x3f6eede3,
+ 0xe4604e6c, 0xfaf6e027, 0x29ceb164, 0xd33af8bb, 0x867ebe3e, 0x4563e80b,
+ 0xb9ec9f9f, 0x6575744f, 0xece2ef24, 0xb695cbb3, 0x474e7c1c, 0xbc47a639,
+ 0x43f55bbb, 0x37741c78, 0x3675710c, 0xf8c8d3f7, 0x5429e621, 0x5717d847,
+ 0x443b7367, 0x614f4bd6, 0xfd8d7e74, 0x72fe4ecc, 0x3e0cdf19, 0x07d414c4,
+ 0x976146b8, 0x4e778cc4, 0xbb22682f, 0x1960fa62, 0x4ba90ce7, 0x4bc2dc61,
+ 0xe58b4f9f, 0xe6cb2a47, 0x9129f3f6, 0xd7df2177, 0x4875f204, 0x4890fb17,
+ 0x90f0fce8, 0xdb9ed077, 0xe734cc97, 0xf3e5f6dc, 0xbcecd4f2, 0x01cd6e7f,
+ 0x549aeaf8, 0xe58bf7bc, 0xf2b79429, 0x4c161e83, 0xff381c4a, 0x1a0b2ae9,
+ 0xcf8a0f29, 0x518b657f, 0xe5c257dc, 0x3f813cda, 0xd1186936, 0xa7815cef,
+ 0x17a16cea, 0xca31598b, 0x6f0279a9, 0x1937343f, 0x336ebeb8, 0x798fc944,
+ 0x1e3f28d9, 0x6bcf6b8e, 0x97c947bf, 0x4aee311a, 0x62afc761, 0xfd3fe47d,
+ 0xa7f1d844, 0xfc76e61e, 0xfe41d66a, 0x719fded3, 0x961ebe3b, 0xed12f487,
+ 0xabddad07, 0x6877d72d, 0xdea00dcb, 0xaec6ffb1, 0x8633b928, 0x1f7ba5fb,
+ 0x3f432fae, 0x77cecd64, 0x235dffc8, 0x2b404ce5, 0xe740c067, 0x51a1e672,
+ 0xd6fabfe4, 0xd819e3f2, 0xf26995d5, 0x76c9ef4b, 0x5e77f846, 0x0d2e79e4,
+ 0x7a11fb8c, 0xc16f23ed, 0xd28b2c7d, 0xa572d14f, 0xe915c850, 0x5bf290ff,
+ 0xc6429bca, 0x77ec14f5, 0x9b60f1df, 0xe1ef3b28, 0xc4afa16c, 0x4dfa4dfe,
+ 0x88547da4, 0xd7d211f6, 0xba2226a8, 0xbf727eb0, 0xe847d26d, 0x662505a5,
+ 0x19917bc4, 0xa6e11bf8, 0xd9f58db7, 0x68f1f434, 0x83f7e5f6, 0xf451efda,
+ 0x0b63f723, 0x84dcfd05, 0xff181891, 0xb81f720f, 0x5ccfd38a, 0xf4843de6,
+ 0x9cd5fbf3, 0xf0bee47e, 0x3d03ef9b, 0xa07dc8fa, 0xdd7e4fdc, 0xdd3f60fd,
+ 0x863ec058, 0xe95cb1e7, 0xfdf1e017, 0x45d38546, 0x3ddf9cfd, 0xf2c2c556,
+ 0x733368e2, 0xb97086ab, 0x8cc9a665, 0x0316977e, 0x99cd2fdf, 0xd2d97ef5,
+ 0xb413f908, 0xb8401f97, 0xf9276eb1, 0xdaadeb77, 0x3d2b3671, 0xf711fd77,
+ 0xc95a8f55, 0x08e174af, 0xc2e59323, 0x0f9411ae, 0xc78199fe, 0x6e7ce55b,
+ 0xb5f7bc3f, 0xb95bd410, 0xcc6296ee, 0x0255a82f, 0xb7c1d62f, 0x77beac0f,
+ 0x756bbf91, 0x672f7141, 0xe427c50f, 0xbafdf1b8, 0xc6c7927e, 0xf73f5c03,
+ 0xdf940929, 0x4787ef0b, 0x38fee9c6, 0xdcefcb88, 0xb807df4c, 0x5b47a91e,
+ 0xf827f3fa, 0x1b30b413, 0xa7ce1294, 0x704de708, 0x985fcb7f, 0x13798ae7,
+ 0x04e2231b, 0xbe663ed0, 0xcf2179db, 0x01726147, 0xba6567cc, 0x7fd717a7,
+ 0x4f85c44a, 0xa9e23889, 0xfc571e44, 0xfe7d7f7b, 0x7ae20db4, 0x3b8894e8,
+ 0xc6d14a9e, 0x44bd649b, 0x6cd93cf1, 0x60346ef6, 0x37799ebc, 0x3d70fe82,
+ 0x7ca26a64, 0x5f1c4595, 0x6b252fbd, 0x1ac811ee, 0x106a3e54, 0xd399fbb4,
+ 0xe3041fab, 0x9ed36f2c, 0xf715ea83, 0xba0af6db, 0xa7f0b5e9, 0x506b371c,
+ 0xd76c28f5, 0xb3df80bb, 0x289e5fda, 0xbfea5ecb, 0xc910baf7, 0x8ff2fea3,
+ 0x3a9ce242, 0xf8c893f7, 0x61f8bc40, 0xfa30bc74, 0xbc74699c, 0x37e4b17f,
+ 0x245fef11, 0x6ee2d4e4, 0xd5b86f1e, 0x820f36cc, 0x6775b7ef, 0x26b8fc50,
+ 0x135c3fd1, 0xbf5bf7ef, 0xa4879e51, 0x9edcdecf, 0xcff8f8fe, 0xf5e3e222,
+ 0x2f5a3e22, 0x5da9d7d7, 0xcf0164df, 0x3e3e31ef, 0x60739079, 0x9f3a3c7c,
+ 0x33b445e2, 0xac3c610c, 0x55b87071, 0xd12aebe9, 0x39617c4f, 0x35f73ca3,
+ 0x416b2d6f, 0x2d9af23f, 0x615596e2, 0x380bd777, 0xd3975bc7, 0x8d2e63ab,
+ 0xb9813ebf, 0xe593d622, 0xc994d14b, 0x33c88f92, 0xad93541d, 0x34db9f69,
+ 0xf07f5344, 0xef9a51ba, 0x4d22fef9, 0x1af5a0b9, 0x6d61fd4d, 0x88f29a15,
+ 0xea6bd79d, 0x4921b217, 0xa23b6fe4, 0xbb125f47, 0xf347302a, 0x85def47d,
+ 0xb29ff69a, 0xa0931da6, 0x7b45a75e, 0x7bf3332f, 0x8594c67a, 0x76c7a9f3,
+ 0xc3f4d52c, 0x29504a82, 0xf633df0b, 0x79a7b899, 0x878f0f79, 0x5ab5dd5c,
+ 0xbead4e33, 0x1d18f08e, 0x7d622def, 0x086e37e4, 0x1b20ee28, 0xd55dff18,
+ 0xaeed4ed5, 0x78c8f764, 0x2241c6c8, 0xb2cd97de, 0xd3475d39, 0xc3ec8d85,
+ 0xe4f4bb0b, 0xc3642c7f, 0xf0449a1f, 0x6b80b032, 0x302efe20, 0xf0bb17ee,
+ 0x798ddd8c, 0xb5bfb745, 0xca63e68c, 0xde05d2d4, 0x5eb9181f, 0x5d2d48eb,
+ 0x3a5addd8, 0xa5a09a48, 0x27786883, 0xc174b47b, 0xcbbff042, 0x86753bc0,
+ 0xb7fe6e96, 0xf081dce0, 0x5be186b5, 0x62d3d07c, 0xbcf1b823, 0x999f6935,
+ 0x1d143d84, 0x4e7690d7, 0xbbb09070, 0x2e323f45, 0x93f159b1, 0x771fd55d,
+ 0x0bcc109c, 0xd53da3e6, 0xc95fb8c4, 0x6fe5107b, 0xbd24bf0c, 0x9497e78f,
+ 0xc09b9d70, 0xf32d67f5, 0x663efc92, 0x93a4fee1, 0x9fc8abd5, 0x913592b4,
+ 0x9cd9fddd, 0xe8efc2e9, 0xca577aa7, 0x9f901853, 0x8b29f600, 0x06aed7f0,
+ 0x1fef1a8b, 0xd2a7868a, 0x78ed04ad, 0x4b75986e, 0xfca3e07d, 0xedde0f15,
+ 0x68ff89a9, 0x51e65fed, 0xb497e522, 0x1278e587, 0xc9ae529e, 0x49ac4c71,
+ 0x117c899f, 0xc8d8e725, 0xd693f8e8, 0x41fd239f, 0xe3238e32, 0x9bfed14c,
+ 0x55b8bb08, 0xc1d2718f, 0xce782df9, 0x21e1d8b7, 0xeb29613f, 0x4fdf05b9,
+ 0xa8b47730, 0xb8bfe12e, 0x2ffbf58a, 0x2babeae2, 0xf26fb5c4, 0xf247a12b,
+ 0x65b3c607, 0xff961c7c, 0xf1a11ff1, 0x8b95c524, 0xf2f398f3, 0xd3d22708,
+ 0xfba6bf40, 0x8fd02bf8, 0x8a97d75e, 0x3130aaf5, 0xfdde223d, 0xf5a212a6,
+ 0x367990fc, 0x6fdb9e45, 0x6ed31d60, 0xe8327f21, 0xa727bc49, 0x58bbfb93,
+ 0xac3db457, 0x0759bf92, 0xafba412b, 0xde711165, 0x2a77f0fc, 0x659607eb,
+ 0xec95d21e, 0x82f1a789, 0xe0a3ca72, 0xc84c53f9, 0x8cffb941, 0xf993cfb7,
+ 0x4f7ef218, 0x94547799, 0x1c75f823, 0x03fd871b, 0x94e595bf, 0xf8017fa2,
+ 0xc7e48953, 0xfa253cfe, 0xa31f803e, 0x31f32fd6, 0xf212f6f4, 0x5c8b2d1b,
+ 0x8780d7ef, 0x9c7e5bb4, 0xc8e9e8c3, 0x3eb3d171, 0x3d6fc4e1, 0x47a4b9f8,
+ 0x68da3f93, 0xfa0d0d84, 0x79145e13, 0xbb5a1d81, 0x9d1c96fd, 0xf7df1b80,
+ 0xf15e095c, 0xf8f221f1, 0xaebe3e04, 0xf8f3261d, 0x0c971c24, 0x0d0afb84,
+ 0x8ff7fb5c, 0x115f70fd, 0x2e12ee0b, 0x7e7b4ae7, 0xdbd2f881, 0xbc23a58f,
+ 0x577aa617, 0xe3dcfd63, 0x5d144fa1, 0xfa555e78, 0x7b8794b3, 0xe74f4ba1,
+ 0xe3ae1aff, 0x25e1b072, 0xf386893d, 0xb38a26dd, 0x41bd74d6, 0x66d9e176,
+ 0xfc06b410, 0x72180cbd, 0x08fc65d8, 0xb78ef051, 0xd9eb924f, 0xe5f62390,
+ 0xef32fd62, 0x39b9d607, 0x475e6627, 0xdfb41c3f, 0xf4aa1c05, 0x1cf09263,
+ 0x92be7f59, 0x791797da, 0x3af45f5f, 0xfe78722a, 0xf7b329db, 0xc3efec3e,
+ 0xd81d9c9e, 0xfbbe955f, 0x67c23670, 0xbbe742ad, 0x79f898a6, 0x5e712cdc,
+ 0xc9a8426f, 0x3399e78d, 0x667df873, 0xf7a47e23, 0xfdf91c62, 0xe0a677b5,
+ 0xffd93439, 0xe7474508, 0xee7b1947, 0xc12c7f83, 0x3722e6f8, 0xd8bf6fde,
+ 0xba2fee24, 0x002c1acb, 0x91baf239, 0x186547df, 0x66e744d2, 0xe4f592fa,
+ 0xb3d34cd7, 0x727748a9, 0xadbcf2de, 0x01f78f7c, 0x7cb15e60, 0xafa5a53f,
+ 0x7bfa0d78, 0x75c83d04, 0x2beca94f, 0xe185b26e, 0xa33cf32f, 0xf82553e1,
+ 0x1b43ee43, 0xd05b5ef0, 0xbccde7bf, 0x6daf7d1c, 0x5874feff, 0xf6363dff,
+ 0x837eb8c8, 0x1e3493c5, 0x6bdc51f9, 0x278717fb, 0xa477df89, 0xbcf6a7bd,
+ 0xbf97b7c8, 0xdeef1253, 0x51ccff9b, 0x827b97be, 0xcb85e5e2, 0x7078ffbc,
+ 0x99564869, 0x739d357a, 0xdeae5ef7, 0x8fadff2b, 0x28bedfb9, 0xd3dff7be,
+ 0xbcec6af9, 0xceb15ec5, 0x88617e70, 0xe7f729ce, 0x7e54be2d, 0x1a477bd9,
+ 0x08d23ef0, 0xf6bcc838, 0xb48fbc06, 0xd0bf4638, 0xe576cb9f, 0xc4aa877b,
+ 0x8f301abc, 0x3df23530, 0x38f0b7a7, 0x302f2269, 0xfb7c8894, 0x9d3d2ecb,
+ 0x11e5ffe3, 0x31dd8cdd, 0xcb9b9de6, 0xa9ca32e1, 0x0e8d1f12, 0xe3b5fbf2,
+ 0x79e793d5, 0xe8d8b9e4, 0x845675f9, 0x63f9c56e, 0xf1ac729e, 0x3f7cb91c,
+ 0x99dde72b, 0xf0d1f1c2, 0x9bdf899a, 0xf27cf2aa, 0x4ad094ce, 0x168713e2,
+ 0x1e04c3cf, 0xe50faf3b, 0x99b2b9d1, 0x8f10efdc, 0xfaa7261e, 0xc8be51ca,
+ 0xd4caee7b, 0xc111c526, 0x87a2578f, 0x1af5dc30, 0xbb840ebc, 0x7ecbbe91,
+ 0x7c151f4f, 0xdc363ccb, 0xfa112dcf, 0x5a9ec96e, 0x7ee587b2, 0x3d4ef4e9,
+ 0x669c6fe5, 0xba72ae3c, 0xd0fda14d, 0xeb631f52, 0x7cad2e40, 0xaa3378a2,
+ 0xb09925ae, 0x1efe1496, 0xe9661f7f, 0xbaf8a8c6, 0xbd495fd8, 0xbe5fc72a,
+ 0xd7176b4d, 0x467f6db0, 0x51f4e9fb, 0xb0563f2e, 0x2b3fd226, 0x57f6d01f,
+ 0xa7d667b3, 0xbce8cf38, 0x8fc21180, 0xec572d37, 0x1958ca57, 0x4f358fea,
+ 0x9fc46e7c, 0x17c78960, 0x434ffbf8, 0x7ddff187, 0x8efe27c2, 0xc96f3e08,
+ 0x1720fcf5, 0xf2ef3efd, 0xf5ceaef9, 0x7f45c9cd, 0x7e7cbbc9, 0x702eea17,
+ 0x8d2bb33d, 0xfd8b5bf4, 0xfaff922e, 0xdffe5cc1, 0x0035f78b, 0x71264c9c,
+ 0x49aeba6f, 0x4df6489f, 0x43ece880, 0x7e731de7, 0x26776540, 0xd3da43f2,
+ 0xbf6067d3, 0x1eada7ce, 0x72d6df5c, 0x2ffa214f, 0xf3f356b6, 0x8f1366a1,
+ 0x397e07df, 0x538600f1, 0xaf6c7686, 0xa39d1740, 0xfd107f7b, 0x3fbaad42,
+ 0x98bcc61f, 0x5f3cc9d6, 0xda175d32, 0x3c62283f, 0x899035a7, 0x68e77df1,
+ 0x9a4e6f7e, 0xcb90bcbe, 0x36276e7f, 0xe85c5c08, 0x627f202a, 0x17fa41af,
+ 0x2e742c3b, 0x2eff8eab, 0xf1c628c6, 0x70eaf32f, 0xf176910e, 0xf9a666d9,
+ 0x1d51869d, 0x4890d04a, 0x3c50a8f7, 0x30436ea8, 0x67d416fd, 0x4f14a94f,
+ 0x7b4bf393, 0xe302ab3d, 0xdd8f5266, 0xbfb838a2, 0x0bfdd84d, 0x71e3fc98,
+ 0x9e82f9b7, 0xff7b0816, 0xf7872b16, 0xc3cee652, 0x2ccd0b76, 0x76ac0751,
+ 0x2947654b, 0x90d6b3ad, 0x8c85768c, 0x47b7c51f, 0x1ac9fb62, 0xe7e7617e,
+ 0xe1be959e, 0xf419c9d8, 0x3f865d41, 0x693c85db, 0xffcfce18, 0x83cca1b1,
+ 0xd786caf1, 0x30efd046, 0x3c781299, 0x1996e41c, 0x843a11ef, 0xbdd61efa,
+ 0xc88b15ea, 0x73880a5b, 0xd8defccd, 0x453939c6, 0x78f11e74, 0x71ffdd1f,
+ 0x23ca10de, 0x847906fe, 0x92bea637, 0xe01fbbfb, 0xd90debbd, 0xf941d760,
+ 0x789fee74, 0x25684879, 0x92991bde, 0x47978977, 0x72c13e85, 0x6cc25e4e,
+ 0x5685172a, 0x3e3ca1ea, 0x7197932f, 0x36040a03, 0x6cf06f35, 0xc92dda3f,
+ 0x87702ec2, 0xc377bce8, 0x917423cb, 0x1e7758fe, 0x84676797, 0x3e4cf93f,
+ 0xc20e6dbb, 0xfaec647b, 0xded27969, 0xc9f5a36e, 0x2cf6caf5, 0xffbb7633,
+ 0x957e7210, 0xc53da738, 0x3c2d5aca, 0x044fe7fe, 0x1eec1c3c, 0x7fcbf141,
+ 0xfde14dcd, 0x4f74423b, 0xfa27ec8f, 0xb8e41c77, 0x7bfe15ab, 0xf2a3e759,
+ 0xcb977ebc, 0xb38c2be5, 0xea19c691, 0xe79be7e1, 0xfe2214e4, 0xc0aa6f00,
+ 0xc9f7ca9b, 0xd07e7ced, 0x13fefe2f, 0xf46287e8, 0x0afc1ffb, 0xe787e7ea,
+ 0x27274d1d, 0x5aab38c5, 0x2fb6dc78, 0x69e880b9, 0xf7dc558a, 0xc75da252,
+ 0x9f6e3cf8, 0xc592f3ba, 0xaf091d79, 0x69c6850c, 0x09cc7011, 0xf6339f0d,
+ 0xaffbaf9b, 0x8eeb4bff, 0xef0797c0, 0xc5d8396d, 0x9f1e37ef, 0xf485f1c7,
+ 0xe076429c, 0x677f4d76, 0x9fb547d6, 0xae5f28c0, 0xda80a521, 0x6fee2bdf,
+ 0x61d9f795, 0xdc71fcbb, 0x57bb45be, 0xfcc1a7de, 0x1c645993, 0x8cdeffb2,
+ 0x70bf710e, 0x286f3aff, 0x8874eb11, 0xef223a75, 0xcfe7ec33, 0x73797d63,
+ 0xb8e903ed, 0xfdfdfe1f, 0xfd12298d, 0x563cf869, 0xf1d7c87f, 0x1e5572f0,
+ 0x1bdf2797, 0xa33ce45e, 0xe70fd9e0, 0x7849f9a8, 0xbb537f22, 0x94ba5a31,
+ 0xf411ccf3, 0xf3bf8039, 0xe278e5bf, 0xbbfad97e, 0x7338be79, 0xbebae969,
+ 0xf9875f33, 0x07ddb209, 0x34a0c078, 0x21bc27ec, 0x7327ec4f, 0xbc9c4e58,
+ 0x339e6f47, 0xde917fa6, 0x7b27ef47, 0xd9efe593, 0xbd1afd69, 0x397bfe4e,
+ 0x7efc73fe, 0xfca36b83, 0x7a8f183c, 0x176e16ce, 0xf2da2fd6, 0x037e0263,
+ 0x797d54fd, 0x5312bf38, 0x3bf8f3c5, 0x4af3ab5b, 0x7760ab67, 0xdc552494,
+ 0xa6e50f99, 0xfc93c6c7, 0xf154192e, 0xf3c83e79, 0xe04d8f35, 0x7c5747df,
+ 0x79cb043e, 0x8a797913, 0xf79479e7, 0x9eccb460, 0x2bb6159a, 0xd173ccee,
+ 0x1d4afab8, 0x42676bdd, 0x63d60623, 0xf944dd7a, 0xf1ae1280, 0x5d26259e,
+ 0xbff3ac53, 0x03d3f4f7, 0xc04cbf8f, 0x1fd0ba7f, 0x2105fc28, 0xe82fe355,
+ 0xcfe7e44d, 0x92fd5f7b, 0x9bdcd7ce, 0x079f5be7, 0x67ad1bed, 0xf287cd6f,
+ 0x1407eb06, 0x603c53ef, 0xc61fa087, 0x608b60e5, 0xadd9cabe, 0xd89fb45e,
+ 0x2559b76a, 0x18ff0ab8, 0xf007a9de, 0xa7b5e57b, 0x0f883c7e, 0x4c79c5e3,
+ 0xf1a07214, 0x15fdbfb5, 0x678dc4e3, 0x1b346e6c, 0x7c3f7627, 0x135fda27,
+ 0x1bfedfbb, 0x3cfcc3d7, 0x44f79c90, 0xfbc27ff4, 0x9a265d09, 0xabeec4ff,
+ 0x6bfd6056, 0x402eebdf, 0x44eeb93a, 0x42c505b0, 0x3effabef, 0x880e7348,
+ 0x7cd97a7d, 0x39f1b8d1, 0x013f8f09, 0x1e0893a0, 0xf8f0e73f, 0xced9f28a,
+ 0x0e6e8f3b, 0x7b549391, 0x78ec0ade, 0x605f3b8a, 0x7b8c6e09, 0xd1fd73c8,
+ 0xd5e3d57e, 0x7f783eb0, 0x20cc1f5d, 0x729e9ec2, 0x24820cd1, 0xc9672e5c,
+ 0x39a5729a, 0xcabf534b, 0x3ef9af91, 0xcd2af33d, 0x42ae99f7, 0xc8d6794d,
+ 0x37fa9a89, 0xe535cbba, 0x6a6613d9, 0xaa7b57ea, 0x60c2e535, 0xf17ea687,
+ 0xf7ed2e91, 0x788f4c63, 0x7eee3a28, 0x27a59f03, 0x2d9ee43d, 0x06f4d53b,
+ 0x85fe273e, 0xafda2383, 0x8ec5cd7c, 0xf4bdf037, 0x9f9f472b, 0x9be67e92,
+ 0x3180b6f5, 0x53393fb6, 0x83df082d, 0xf3f1d7a0, 0xfb25ef53, 0x937880fe,
+ 0xa0a6a7e7, 0x5090195f, 0x9fb9db75, 0x5c32efe2, 0x6efdc458, 0x943111c7,
+ 0x7f276e4f, 0xd34371e5, 0x79e47fb3, 0xf728b903, 0xaf9bebae, 0x8b94f759,
+ 0xcbbacd3e, 0x3c28aad9, 0x5729a1dd, 0xd4d6ee39, 0x5eb99e9f, 0x6ba67df3,
+ 0xb69e144b, 0xba37ca6b, 0x53c28e1f, 0x9e9e147b, 0xf4977cd2, 0x5ffc2ddd,
+ 0x0adfa1af, 0x3d42939e, 0xc9878895, 0x1f08faa7, 0x2ada7a13, 0x1cd74f11,
+ 0x957c20ef, 0x2895bd04, 0x348ecb2e, 0x20cf81bd, 0xddb0cbec, 0x7a4ce681,
+ 0x91766c1e, 0xf370ebff, 0x691e7a48, 0xfffbd376, 0xcf409e68, 0xe87b355f,
+ 0x33cd9ff9, 0xecd3d9e8, 0x734767a5, 0xae7fd507, 0xcffb8bb9, 0xddeffb52,
+ 0xc1bf45c8, 0x01a85d79, 0xc18ec623, 0x9e9e495b, 0xc79d084f, 0xeb7f06f2,
+ 0x3420a9ec, 0x901d67f0, 0x9e207f2f, 0xfb4f2e45, 0x1e0e7860, 0x19fdf8cc,
+ 0x43a37f22, 0x3b4429e7, 0x0fe3f47c, 0x32e6a7de, 0x37bd69b6, 0x183a7f13,
+ 0x132866cb, 0x90f7e9b2, 0x93cfbc1e, 0xa8b3d8c3, 0xf7bee84a, 0xb9636707,
+ 0xe79efc57, 0x241fc7e0, 0xc75bfc3b, 0xe2033dd9, 0xc707a3ec, 0x7b3fb388,
+ 0x7f4765ca, 0x46afd1cf, 0x471e11d8, 0xc3cbdf85, 0x3bf80d0a, 0xa16ae51c,
+ 0xf1ecf501, 0x5421e738, 0xe0c97953, 0x7bb75c52, 0x5f91e51e, 0xe1dfa06f,
+ 0xfdf0a39b, 0xec97acaf, 0xf7a0fae2, 0xa7ed1346, 0x2b3ce98e, 0x957a3f90,
+ 0xce10c7be, 0x14fe3d37, 0x7b5ea9e9, 0xafc21e5f, 0xbcbdf1fa, 0x4c7becec,
+ 0x0d944771, 0x8f953e1c, 0x6fdb393f, 0x33e15efb, 0x0d11d71b, 0x1d83b99f,
+ 0xf4115f7c, 0x201da2e4, 0x3daac7cb, 0x2c5714f5, 0x75c30cf7, 0x389af51c,
+ 0x81ed7aff, 0xf237e461, 0xf08bce94, 0x360cf4ff, 0xa2e7fad0, 0xe83f44de,
+ 0xd6207d42, 0x1f9e15ef, 0xa23dedcc, 0x2e67dc13, 0xe0bed2b0, 0xa3df8e98,
+ 0xeedf5d10, 0xcfa3fbe2, 0x9c87dce2, 0xdc57be28, 0x0becff54, 0x5aef5fd0,
+ 0xebdd750b, 0x58f6411d, 0x1740136f, 0x54f7ba68, 0xddfe39d3, 0xa12016e4,
+ 0xf82def38, 0x6cfef82f, 0xfc5f9df7, 0xb07fea06, 0x1d26ead6, 0xf04518e2,
+ 0x2f2a285b, 0xfd93354e, 0x6e4e78b4, 0x5bc5ea05, 0x56f0bc44, 0x614e9abb,
+ 0xe8d93543, 0xdb967e80, 0x0403370a, 0x6ab4cad9, 0x5364fe23, 0x9b1dce4d,
+ 0xe87ab9f1, 0x58f22376, 0x9b7d98dd, 0x07ad8cd1, 0xf9252e16, 0x19a77a17,
+ 0x3adb75e6, 0xe7ef8bbd, 0xdadaf9e4, 0x22f7946f, 0xc898f7e9, 0xd020024f,
+ 0xa5c9357e, 0x4949f668, 0x181f4e82, 0x6331e22c, 0xda4bd8d9, 0xe44ed778,
+ 0xdf8bb3a3, 0x1e271e19, 0xec2efda1, 0x7b8adfc7, 0x4fefa39e, 0x5c3ae391,
+ 0xcc75ff7c, 0xf6899408, 0x07ae42e4, 0x7cffcdc6, 0x7fac2943, 0x4743b75c,
+ 0xd5b70d79, 0xb87880bf, 0x68f025d0, 0x4fc85d60, 0x7c97f937, 0x4c421bf0,
+ 0xf0dce69a, 0xbba5f495, 0xa91951c7, 0xde424b2f, 0x397d48ca, 0x12adafa1,
+ 0x8fd4a2f5, 0x211ae6c1, 0x8e489b8f, 0x475e6c1e, 0x7ecdc3e5, 0x6e691e7a,
+ 0x8db8f215, 0x79aaffbe, 0x01c790a7, 0xd2f78f21, 0xf9e6eefb, 0xd9ad7cf4,
+ 0xa985cf47, 0x6e11d7be, 0xd73b8e32, 0xdcbca3ec, 0x189b0f43, 0x742ef1c6,
+ 0x038f289b, 0x47b1e238, 0xc94f30d2, 0xa344e744, 0xe5a295f3, 0x743d3f7c,
+ 0xe5b7b80e, 0xfef7e46d, 0x17b4233c, 0xa7a7c707, 0x4765cca3, 0xe0f1f4b9,
+ 0x8e8724f3, 0xb4765cba, 0x2e3e4fa7, 0xdd971eca, 0x0d3fe500, 0x71fd25ee,
+ 0x9bb2e7d4, 0xe3c9fca0, 0xdfbbfcbd, 0xf940b765, 0xfc7dc1d3, 0xd051807b,
+ 0x2fe0ecff, 0x33958e48, 0x47f220e5, 0x2a7f39a5, 0xd7d00ba8, 0x2f9107e5,
+ 0x992e67a6, 0x60b17c8a, 0x72e88bb0, 0x41fd6ba6, 0xd91acf2c, 0x1515e2ae,
+ 0x46e15b1e, 0x5691576c, 0xa9bb62ad, 0xc46c7739, 0x6e86d376, 0xcddb2357,
+ 0x236fb318, 0xb7706f96, 0x2e9f68ab, 0x1a563940, 0xe59647ee, 0x65a72977,
+ 0xddd5dd3e, 0xe307d25e, 0x0fa4bcba, 0xe62a5c24, 0xff426f56, 0xe2976367,
+ 0xa9a5dfc0, 0x27f4ab98, 0x62ee6033, 0x0a93de03, 0x3dfffaf2, 0x87ac77ae,
+ 0xf9623675, 0xadb72a1a, 0xedfa06ff, 0xe2f6007f, 0x8000e831, 0x00008000,
+ 0x00088b1f, 0x00000000, 0x3cd5ff00, 0xe5547809, 0x9dcee7b5, 0x4c92642d,
+ 0xe2420836, 0x96249964, 0x26b6432c, 0x0c486410, 0xf90130ee, 0x10196544,
+ 0x044816c2, 0x7eab17eb, 0xe0171a19, 0xd16b8d69, 0xb5c46faa, 0x61e4b6af,
+ 0x1d0958d4, 0x87d252aa, 0xb410553a, 0x88a47479, 0x119099f0, 0xc7d278dc,
+ 0xf7fce73b, 0x24cee666, 0xbefd1480, 0xff938607, 0xcfd9fbfe, 0x005ffff9,
+ 0xb3f85380, 0x34607f02, 0x3d2538fe, 0x0468048c, 0xd1bf67f1, 0x0395b26d,
+ 0x8c0734ac, 0x412fa3a0, 0x6010aba3, 0x76960eaf, 0x24a40014, 0x0b7afcc3,
+ 0x74b08d96, 0x5de7960b, 0x05480368, 0x20bada68, 0xda85816e, 0x6066e3bb,
+ 0xe21745fb, 0x52ce38af, 0xe0546e05, 0x9bd40a93, 0x4f34899c, 0x1fd24d9a,
+ 0x856fc7ca, 0x064a7850, 0x3d9ab7e8, 0x448004ba, 0x0dac7b93, 0xfb9bedc7,
+ 0x8758834e, 0x31d688af, 0xeb1ebd6c, 0x6c3200e3, 0xca1f1e56, 0x5e541982,
+ 0xc846ed09, 0xcff5b846, 0xda22a4fb, 0x2327c597, 0x5f434e84, 0xf9ec5f20,
+ 0x63fe1654, 0xe0543d06, 0x6e03e97a, 0x70d79969, 0xea566020, 0x743967f1,
+ 0x226670ec, 0x7ed45ede, 0x18bf046f, 0x7dfb43bf, 0xbe8de215, 0xbf697537,
+ 0x0f5b5403, 0x0230438d, 0xd9dfb8cb, 0x855efe12, 0x878f0dff, 0xc3c06749,
+ 0x10f0a1a4, 0x1af01fb5, 0xd7de8e41, 0xa66ecb0a, 0xc0bee473, 0xd1fcca9d,
+ 0xf7218108, 0xf445f2a7, 0xfe05dafe, 0x25ff02f5, 0x5a74e736, 0x38fcdd5f,
+ 0x8e005390, 0x4d79356d, 0xa9ffdc99, 0x1744293d, 0x2d837593, 0x5b5b3e9a,
+ 0x00de8367, 0xcdd5adb0, 0x14bad7d0, 0x3f8076f4, 0xf97336b5, 0x2e16d6ad,
+ 0x30f568ef, 0x8ebad9dc, 0xdb5a5fe1, 0xeb577eb9, 0xdbbf2e46, 0x6fe865ea,
+ 0x5fbf917d, 0x86657f3b, 0xff4d12db, 0x45cec9d5, 0x7b9e8fc4, 0x3e9913aa,
+ 0xc853f7b8, 0xc81a9eab, 0xc344b66f, 0x9d658301, 0x8f65c094, 0xd9e1f711,
+ 0xc36de316, 0x8c73fd7d, 0x19c689bb, 0xad7e09a8, 0x4a437c43, 0x30d0f180,
+ 0xbe9abdd2, 0x3a1c464b, 0xe4f56689, 0xeb0efe12, 0x6407bf3c, 0xd39b56d9,
+ 0x383e47a5, 0x17558f1a, 0x6582dc00, 0x78f3ce0f, 0xfa85abaa, 0x48c07e41,
+ 0x3fa29ce3, 0x097c7193, 0x3af07766, 0x0e1ca210, 0xb1e808c4, 0xd18f2c49,
+ 0x40ddc850, 0x60f99fba, 0x1913e9e0, 0xcb3382b6, 0xa8f870c5, 0x9e03ab93,
+ 0x6567a432, 0xd584c3ac, 0xa4f8127d, 0x46538412, 0xd38e00d6, 0x13d46e97,
+ 0x5644149c, 0x9fc3c750, 0x6322dfc9, 0x14cbf186, 0x6b94d448, 0xed35a3cd,
+ 0x9a99aceb, 0x5cf4befa, 0xb4d2ff1e, 0xfaed348b, 0xc59a5746, 0x232f53bc,
+ 0x6f7465d8, 0x0974805c, 0x9b1c9956, 0x98bdfeb0, 0x062822f8, 0xbf1b1698,
+ 0x317be089, 0x376a5e19, 0x14c9c0ed, 0x934e7dc0, 0x108b237d, 0xc6db9755,
+ 0x99edc76b, 0x76c36353, 0x6957e657, 0x25c121d7, 0x1dabdfb4, 0xa7df3453,
+ 0xe9ae5e57, 0x93fb32ef, 0xcef5ad08, 0xc6f7cd7a, 0x9f41af96, 0xe5b1300c,
+ 0x014be824, 0x343afbc6, 0xecee94e3, 0xbf1fb4d2, 0xeb12641b, 0x378e7d92,
+ 0x741f9609, 0x152ac4ca, 0x24df9b87, 0x3fa5f558, 0x4e01f683, 0x9f5159b0,
+ 0x83dc8a4b, 0x963d0247, 0xcae52927, 0x812db7a0, 0xf21270e8, 0x89bf48f5,
+ 0x6321c230, 0xbff2a963, 0x4c1f104e, 0x32002052, 0x16abf607, 0x3a79804b,
+ 0x4598d78b, 0x1be5056a, 0xc906c1f5, 0x3847a691, 0x50540e47, 0x8a0428f9,
+ 0x973aca08, 0x2a6bf89e, 0xb2a58f34, 0x0469dc09, 0xbf74483f, 0x2fdc7c4f,
+ 0xe2c4da05, 0xcfc4c982, 0x68ff3f75, 0x17ac6dde, 0x5c261c62, 0xfebaefdf,
+ 0xfd6b4a91, 0x91f53fbb, 0x7e216c37, 0xcd7eb26f, 0x8dcb5278, 0x7f19c72d,
+ 0x2d6fb96a, 0x92e177cc, 0x9f680ddb, 0xaffe3610, 0xed0a76cc, 0x53a23ada,
+ 0xb8c9fc23, 0x1ed420ba, 0xc418be3a, 0xbfea3177, 0x04d35a7a, 0x5ddfd7c2,
+ 0x6f576c4e, 0x9e087210, 0x1c4ef545, 0x29463ea7, 0xa7d44f83, 0xb2a1ed2a,
+ 0x6ae9cb9e, 0x6f68957d, 0x587bc757, 0x96ad1fb4, 0x522ef195, 0x9ca2cdcb,
+ 0xa0f7cea9, 0xe5aa1728, 0x397170ff, 0x613fb44e, 0x29ef559b, 0x53ffe908,
+ 0x0f18ddaa, 0xa06ec9e3, 0xc933903d, 0x1abb481e, 0xeda21f98, 0xb15eb685,
+ 0x237ff317, 0x44c58c7b, 0xdf63cb8f, 0x90eeb921, 0xf1bae480, 0x8bd38376,
+ 0xd49e7ff3, 0x12c6b451, 0xb7e7dfc2, 0x6abb7c08, 0xb6329ce3, 0xde6af95f,
+ 0x3923e226, 0x85c8f76e, 0x563addf8, 0x4ea77ac7, 0xe88138b6, 0xfbd0af7b,
+ 0xd848ff6a, 0x8686f2d0, 0xb2f5519e, 0x6cc1f3c4, 0xfaf9c1fc, 0xf4f51bef,
+ 0x8e59c206, 0x9370973f, 0xdcf42999, 0x95add448, 0xea36f3f8, 0x3dd23359,
+ 0x3a9c1b25, 0x1af29f6c, 0xf1a267ea, 0xc7d0bf41, 0x24f8c5af, 0x8f959c14,
+ 0x6ff6c9bd, 0x8e528ca1, 0xcf2d7bf8, 0x7c89979d, 0x9fce347a, 0xd0db7c4b,
+ 0x75d78db2, 0xe3cadd8d, 0x10583583, 0xcce2cf8e, 0x9e97fc28, 0x3fa5ff01,
+ 0x8271fe26, 0x75cfa403, 0xbeb47428, 0x78b796e5, 0xef95cbbf, 0x43325fac,
+ 0x472cb8ed, 0x39c68f97, 0x0e1f0832, 0x74074e85, 0x5f050ab6, 0xfabe1357,
+ 0x1373fb17, 0xf9f0ecb1, 0x3ed9ba47, 0x88972aec, 0x4071cdee, 0xf92a3f74,
+ 0x410ef68b, 0x0ed68eff, 0x5a5bcbb6, 0x84be18bb, 0x55bad073, 0x8d10dd7c,
+ 0xc067f9df, 0x131ffcef, 0x01f4a3bf, 0xadfb03a3, 0x4e3c07da, 0x1180ff85,
+ 0x2b4cf4c2, 0x27e225f1, 0xfae24ba1, 0x2120b93a, 0x138fa9a0, 0x738e52fe,
+ 0xcae9f13c, 0x37aabb19, 0x98792148, 0x311d0b1c, 0x0ed7cc49, 0xc41daf85,
+ 0x22ff2ad7, 0x11ea963f, 0xc49d6fcf, 0x37e0437e, 0xf3c0bfc4, 0x3bba78a8,
+ 0x881baf1a, 0xabc1a78e, 0xc607feb6, 0xc7fa276b, 0xaf8237a4, 0x653778c4,
+ 0x77f9e346, 0x7c555e0a, 0x7fe4536f, 0x236f3c38, 0x7f9ea73c, 0xb4cb6f3c,
+ 0xf891b8f1, 0x453ece1e, 0xf75d47d2, 0x7e5a7210, 0x2d3a722e, 0xdff8aadb,
+ 0x461677e8, 0xa26dfdd3, 0xf74359bb, 0x53c8339e, 0x4f298fcf, 0x848b7891,
+ 0x3ab8128d, 0x3fdfd12c, 0xdf561ccb, 0x4e3c179d, 0xf8d6ce0a, 0x75bf9367,
+ 0x29b3fc6b, 0xfd696118, 0xe5349bd8, 0x9aadeb3a, 0xada697f6, 0x6e5fd4d5,
+ 0xbfa9af5b, 0x4d01ff32, 0x63c76af9, 0xd3e67e11, 0xe77afa9a, 0x73f5346f,
+ 0xea6bb79b, 0x68f4b7e7, 0xfe7817ea, 0x78ab29aa, 0x1c0adadc, 0x356b6d2f,
+ 0x65d3f12b, 0xfe03ab0c, 0x8b83125a, 0xdfd9070f, 0xd7b7f4ac, 0xafb24bb2,
+ 0x32d1fd83, 0xc296ab9f, 0xcd9d8aaa, 0xb5f4126f, 0x2d78955a, 0xad5be18d,
+ 0x3befd636, 0xee19f35a, 0xf128756c, 0x5dc3255a, 0x4e254ead, 0xb48c3173,
+ 0xbb66af0b, 0x3d2164a7, 0x44bcbda6, 0xe980b807, 0xc167f87f, 0x77bc5a5e,
+ 0xdce28ebc, 0x8e5eca35, 0xffb37f57, 0xe3afe436, 0x950726cd, 0x311fb77b,
+ 0xf9a30ad8, 0x32b7ee65, 0x6cf8c338, 0x0d5fcb6e, 0x45cd67e4, 0x0863ba0f,
+ 0xa59a9d39, 0xf7207e63, 0xcc2f5003, 0x05218336, 0xd9ecc1f5, 0xf80da392,
+ 0x189207bb, 0x3f58dcfa, 0x133e0f4d, 0x7a2deb96, 0x979e299f, 0x3fa332e6,
+ 0x132c4b3d, 0x50f07a4c, 0x7324a43d, 0x7d0d7e9c, 0x383ca1b4, 0xbf18b865,
+ 0x1c3f22cf, 0xe96f5dfb, 0xbddd9030, 0xfa2fe76e, 0xb87ac36f, 0xf1ce53d3,
+ 0x25625c3d, 0x3e792dfd, 0x371a9dd6, 0x3520bcbc, 0x5f1850e1, 0x4e19254f,
+ 0xe1d1f8a5, 0x7adc5277, 0x9cf1c193, 0x05dfba2d, 0xc9a77eca, 0xc16ffb12,
+ 0x4dde4dd7, 0x713e4852, 0xb84d3b7f, 0x01e226cf, 0xc1b367da, 0x7e445797,
+ 0xb3f676f6, 0x16d72a9b, 0x2e9a9d11, 0x15313e91, 0xa69de285, 0x8fd92f96,
+ 0x91cfd48f, 0x90f14cf0, 0xfe656fc3, 0x93badfdb, 0x8b8d45f9, 0x5c7d5b7a,
+ 0x6ab80b2e, 0x39a3e3c3, 0xa64dff93, 0x4beaa7b8, 0x3c4cff11, 0x53fbdce9,
+ 0xd5a077dc, 0x17e52fff, 0x9a82bcd4, 0x5bcc8867, 0xde647aa8, 0x6e0975ad,
+ 0x2c9aefdc, 0x94f30651, 0x5ea3a674, 0xdedf5540, 0x9765159a, 0xbd3ac8ef,
+ 0xffd6d67e, 0x6cf9fac0, 0x4d31bff9, 0xbe48d5d8, 0x05e337df, 0xe553ad03,
+ 0x9ffe48ef, 0xfe707d43, 0xd7924d39, 0xf67a7a83, 0x44c37692, 0x7df9dce9,
+ 0x88a0e5b9, 0xc2ed238b, 0x3607b6f7, 0x2b5c9ba6, 0x92617c73, 0x1e50726f,
+ 0x4743a544, 0xcf3add34, 0x1fceb740, 0x76d16e93, 0x73bce0f1, 0xf1a08bb3,
+ 0x8acbdfcf, 0xc83e27f2, 0xa91fbd3a, 0xf781ffad, 0x636b1d6d, 0xef4472b8,
+ 0xea27593c, 0x01627c45, 0x80eff21d, 0x74b8e657, 0x3c7b6669, 0x195033c5,
+ 0xb77d278c, 0xf2065bac, 0xd4ef410f, 0x5cfe468f, 0x1f67f0a2, 0x7e243ef8,
+ 0x7ef7055c, 0x25980941, 0x22ae4bd5, 0x09f4b73d, 0xfc4f0843, 0x27f393af,
+ 0xcb7e94ab, 0xda469d2d, 0xb567f2ef, 0x1a71d4ed, 0x1fc88a5f, 0x19fa5f57,
+ 0x73f0ddb0, 0xa7556fde, 0x5977dfb6, 0x62872971, 0x084b1659, 0xa7d267ef,
+ 0x1baec947, 0x5b27cac2, 0x3f20bf39, 0x9e03e0f3, 0xc4fa21b1, 0x71f14764,
+ 0xf9e9f65c, 0x23ff5b58, 0xf71cb1f3, 0xf9e891ac, 0xbf78f97d, 0xeb4599dd,
+ 0xa0f3f556, 0xc4c379de, 0xdca0677a, 0x37a4f226, 0x9e2daefd, 0x3804e4f8,
+ 0x2a161d88, 0x6a85d2f9, 0x369d74be, 0xcfb93a5f, 0x49b979c7, 0x716dbd07,
+ 0xbd89f748, 0x55dbce1e, 0x59b776ed, 0x5dd3fcb0, 0xa3fc994e, 0x64b96ff1,
+ 0xdfeab75a, 0x484efea8, 0xbeb0e58f, 0xf66bbce3, 0xd53bebd9, 0x30f6aa2e,
+ 0x06560ed2, 0xfec96bdb, 0xe3b6f84d, 0x2be7824d, 0xf7691eaf, 0x7a138bde,
+ 0x57c1a8e2, 0x8cfc97be, 0xcf1c63d7, 0xaffaf441, 0xc67e16cb, 0x0302cf4c,
+ 0x1f091fcb, 0x450cdbca, 0x764fae6e, 0xf54d975f, 0x99d0bd8a, 0xa3b2069d,
+ 0x23df7275, 0xf95f12d7, 0xde1bce65, 0xbf07c77c, 0xccedb5ff, 0xeb2685f9,
+ 0x863ff671, 0x749a338b, 0xa2f8a6e0, 0x4a56d6a4, 0x6dc50c7e, 0xf3544794,
+ 0x9fed918a, 0xc8acd7b0, 0xb5573ce6, 0xd9eb49df, 0x1c33d628, 0xbe5a9abd,
+ 0x8731e4d0, 0xbba9bf9b, 0x4c30badc, 0x16ca5e3e, 0xdbd22ef1, 0xa21cc87a,
+ 0xc5f2d9f7, 0x65f8b7ff, 0x091e0c9a, 0xe4a16ced, 0x082ffe15, 0xf80e783f,
+ 0x2083ce19, 0xf9583743, 0x38216a7c, 0x17022e18, 0xdbbb7cc3, 0x60337c4b,
+ 0xbe248e08, 0xbbf57fea, 0xfe9be202, 0x57b6278b, 0x5f3bf9c1, 0x06fff48a,
+ 0xfe78dbc6, 0xdbbe5781, 0x7039fc43, 0xf4ace187, 0x6764eac6, 0xe451f127,
+ 0x53bbcb79, 0x01d73e64, 0x8b967afd, 0x03e8ab7a, 0x1b72a497, 0xe64cd8eb,
+ 0x1cde908b, 0x37aab4f5, 0xc2bf6017, 0xd7ac744f, 0xb5e49960, 0x80aed363,
+ 0x70ac458e, 0xa657a671, 0x2fa8a772, 0x95e8995c, 0x15585cb0, 0x4a6fea23,
+ 0xc52642f4, 0xcb960143, 0x0fac00f9, 0x8bd08017, 0xf7938237, 0x96419189,
+ 0x6f17fd84, 0x3e709735, 0xa4390216, 0x8e288bff, 0xb74e221a, 0x2f7908e6,
+ 0xbefa12ce, 0x179b46b8, 0xc95b30f9, 0x4a6bdb1b, 0xe7561072, 0x1d12f738,
+ 0x1bfc938b, 0x7ca32a1e, 0xa1360e90, 0x75567d7c, 0xaa779f2b, 0x35ed1afd,
+ 0xcdbf84bd, 0xe2bc7012, 0x9f7936e9, 0x238ce713, 0xf2cdcfc3, 0xa807b5ed,
+ 0x7b5a11dd, 0xc578f0f9, 0x47f71c7e, 0xd78795cb, 0x1bb14c57, 0x43f1fbe7,
+ 0xe5cbcf25, 0xebe679ff, 0xf80b3bfa, 0x7e43c14c, 0x7ddda372, 0x046fd79c,
+ 0x9ffad0b0, 0x40147114, 0x47e50673, 0xd2653c97, 0x11f19f91, 0x03c8639a,
+ 0xddc61bf8, 0xe31bff04, 0xc77f8267, 0x27e099f8, 0xfc133f18, 0x04cfc607,
+ 0x1e3b7f17, 0x8d802283, 0x4e4b4e39, 0x301ce879, 0x1c86bd72, 0xf9c1cf81,
+ 0x7f3c8dbb, 0xf8cddd9d, 0xebf7a41d, 0x9973a5e0, 0x0bc189cd, 0x6fc34e92,
+ 0xf0dfdd03, 0x7870e9f9, 0x2325cf51, 0xe853bfeb, 0x67a9d45a, 0x15d45ffb,
+ 0x6b086f88, 0x918e4177, 0x395f0beb, 0x1fe34f18, 0xd7e20eb5, 0xa796e129,
+ 0x82f944e9, 0x08332d67, 0x677675bf, 0xe51bed09, 0x51f6833c, 0x83c1f5d4,
+ 0x7c78cb13, 0x75a364ab, 0xb8e51f04, 0x911f6221, 0xb5f75078, 0x81bfd139,
+ 0x257e6ffa, 0x7a82768b, 0x10dc8407, 0xed43491f, 0xcff32d77, 0xccb05374,
+ 0x7e9deb8a, 0x0a1e6e4a, 0x29f675ff, 0x5477e78c, 0xc7cf537e, 0xe952fe15,
+ 0x1df2ae76, 0x6b901e39, 0x6ae77e84, 0xb236a5d2, 0xc9e3274b, 0xee57ac2f,
+ 0xe6757419, 0xf4fb47bc, 0x6ec194ec, 0xc8d63e63, 0x5f8562df, 0x6dd85854,
+ 0x36bd1174, 0x59ca1f77, 0xe4fa6164, 0xb3f6c62c, 0xbc9aec72, 0x89d56167,
+ 0xe14a1fc7, 0xea9a56f6, 0xceba783a, 0x60dfe38a, 0x6d36fede, 0x93f5ae69,
+ 0xcf2c44ba, 0x1076934f, 0x9ccb605c, 0xe5a3649a, 0x37fd797a, 0x41d94fe6,
+ 0xa3957522, 0x29b9fd9e, 0xecc264a4, 0x9639ad43, 0xcb071f0e, 0x4d64d675,
+ 0x31b4d2f9, 0xdb97f69a, 0x57f535b2, 0xd4d38fe6, 0xe55ef3ab, 0x2bb4d528,
+ 0x51660a4e, 0x60fb875c, 0x64e780b9, 0x7da25daf, 0x1c62beef, 0x3f3da796,
+ 0xca6e41cb, 0xda7ea566, 0xd12f5a96, 0x69f10063, 0x70ea8744, 0x1f47fae5,
+ 0xe222c1a2, 0x67eec686, 0xe76d3876, 0x130c3710, 0x7100ac2f, 0xdc5c3f8e,
+ 0xa02f1910, 0xf4907cfe, 0xd7abf167, 0xdc70db58, 0x2e2755cd, 0xef3ee1b0,
+ 0x8238c1cc, 0x47128dec, 0x833fc70c, 0x04d92272, 0xf0c8f4ff, 0x03fc10dc,
+ 0x1f850bf0, 0x3ef69c05, 0xdf0533fa, 0x4a7dbf5f, 0x07f38dfa, 0x57efc51e,
+ 0xafbe4460, 0x6f78e8d8, 0xdea7e50d, 0xf9ce8191, 0x03ae24e1, 0x77e81beb,
+ 0xb0f7c439, 0x46bbe9e8, 0x0f77f0a7, 0x94aba6b9, 0x731fdffc, 0x71aabf14,
+ 0xcba35dfb, 0xf370f542, 0x70f69a27, 0xa6b774bb, 0xb6a6677c, 0xbb94ef7c,
+ 0xe70ffbc3, 0x5c6c3597, 0x9ca37460, 0x392c3c36, 0x8be843bd, 0x28a4f5c1,
+ 0x097ba1fa, 0xdb43dbeb, 0x716d1997, 0xe157edd1, 0x6cb79478, 0xaadec618,
+ 0x193aea7a, 0x7faa879a, 0x71cf9d47, 0x08fbe77e, 0xcdf64f71, 0xc3b09af3,
+ 0x8db8251f, 0x2fb27ce1, 0xf47b9c47, 0x1dc0f63f, 0xee79d35f, 0xeabe22eb,
+ 0xa3f6144f, 0x9d33f3a8, 0x08f1610e, 0xd6455fc1, 0xd2ec8e80, 0x0f58d2c0,
+ 0x2d359ca0, 0x8ae8f38b, 0x7e088fc9, 0x5e4f1e68, 0x9a0f2dc7, 0xeb1fce91,
+ 0x3cbb1a74, 0x9616c140, 0xd9fd9efb, 0xf7e93b8c, 0xe92f7102, 0x2fb3ed7c,
+ 0xad7d8407, 0x1e637a11, 0xb7629ff1, 0xd3565500, 0xc768305d, 0x5e10cf48,
+ 0xbf6b9ca8, 0xc987fdf5, 0x7a11efcf, 0x370af283, 0xb4e05fb0, 0x1d0df368,
+ 0xbbf8e72c, 0xd73efc2d, 0xb78feb59, 0xf3968dda, 0xd84647a8, 0x218779b5,
+ 0x57fbc5f4, 0x5e9b3d22, 0xd05ef997, 0x04f6adb1, 0x911fd308, 0x28da6c78,
+ 0xe5ab9cb3, 0xcbe55ba3, 0x830f6cbc, 0xd185f519, 0x83a706f8, 0x55b57fe5,
+ 0xd27ab7cc, 0x4ec83337, 0x8bd6eeaf, 0xcdc32f4b, 0x5b064eb3, 0xb79b3cd8,
+ 0x5d929699, 0x603fd753, 0xf749f455, 0x0a534957, 0x843b5c04, 0xc0bf457d,
+ 0x417e4290, 0xecf1c4bd, 0x3551ee9e, 0x123da784, 0x3c256cf8, 0x5c6635c4,
+ 0x1c314cdf, 0x5e50b77d, 0xf9f2d214, 0xd71aa59e, 0xacecf1aa, 0xf27659ee,
+ 0x5cec3f63, 0x072907b8, 0xccd9ec93, 0x8782d74f, 0x893deefd, 0x93ca74ae,
+ 0x3fee534c, 0xf60c49ec, 0x67bdbf91, 0xf744ac52, 0x3bfc7019, 0x5f757c69,
+ 0xf4ae0c7b, 0x9297de66, 0x44fe752f, 0xf67b153e, 0x67aaa271, 0xa7dbe4eb,
+ 0xf7e7495c, 0xf14ac073, 0xf85974ec, 0x2147f0d5, 0x6d5eaacf, 0x6c49fc92,
+ 0xa633edaa, 0xa34f11db, 0xe4a97e5a, 0xf735db7d, 0xafd6cf00, 0x5fa38c1e,
+ 0x567f9894, 0xb1bc4439, 0x47f3faaa, 0x57f9c5ae, 0xfe4fbc61, 0xedaec2dd,
+ 0x917f08fb, 0x7c60fdf1, 0x7be62ff5, 0xd733e3a3, 0xcddfda32, 0x73df1c77,
+ 0x69c7442d, 0xea817183, 0xcb173e5f, 0x58a8d6e7, 0xfc287c85, 0xee5b647a,
+ 0x7f5835de, 0x66062fe4, 0xfd2737d7, 0x58ade8ea, 0x58b9f9be, 0x2491f3c6,
+ 0x391d90f0, 0xebcf29b2, 0x744b06c1, 0x6fb25ec1, 0xcf8e25b0, 0x327b3e69,
+ 0x512fb7ef, 0x76b7f27e, 0x7e4843f6, 0x7cc2e86c, 0xe88ff746, 0xb9a3cbfb,
+ 0xbcc5b81f, 0xca5c8a0d, 0x5fde142f, 0x242ff54d, 0xa5427e73, 0x6327e1df,
+ 0x7dac149c, 0x2b22be05, 0x92e7deb2, 0x5bdd10e7, 0x697ba15c, 0xf97c84bf,
+ 0x06f708d5, 0xc7f2f7da, 0x89c3f3ff, 0x17da9fb8, 0x1555feae, 0x07d96fae,
+ 0x84e340a9, 0xdfb43ae8, 0xb66b6c70, 0x3f057f90, 0xf18c5e2b, 0x27d30c1e,
+ 0x35123b2b, 0xd1aea6e5, 0x7a6183de, 0x729ef068, 0x04e7c4a3, 0xed5c8a8d,
+ 0xeddbba37, 0xfba5d794, 0x713f4ca9, 0xce84b51f, 0xf7ff08ab, 0x91ff1899,
+ 0x5da2f67c, 0xf3566739, 0x4e60c93c, 0x0b75b923, 0x97dc0dfc, 0x31e289b7,
+ 0xf1493d9f, 0x33b9823b, 0xb3f9c30a, 0x9c1bd577, 0x7b8931e7, 0x9f43318f,
+ 0x13da77eb, 0xf9837db9, 0x699e4d4b, 0x4d09cb55, 0x015567fe, 0xd2501fb0,
+ 0x89bd2b66, 0xba1487ce, 0x7aee9fdc, 0xf1def18d, 0x18bbabc0, 0xf2dc4f9f,
+ 0xd3bbcd31, 0x5d83f4c2, 0x11163c4a, 0xbf98356f, 0x69efe450, 0xe87e7f8d,
+ 0x9445bdb1, 0xcaf438ff, 0xd3ca22b8, 0x87fd942e, 0xf7c99d7e, 0x86dff69c,
+ 0xf7cecb70, 0xb91e2f39, 0x0c7ba8de, 0x8d43d092, 0xba648fb4, 0xc77ae3ff,
+ 0xf42e72ce, 0x850d81c3, 0x1f353f8c, 0xe864703d, 0xa75d5078, 0x3ebabe3a,
+ 0xddb57c75, 0x5f22ecdf, 0x17f46fd0, 0x415ffd91, 0xfb6130e7, 0x17f78fea,
+ 0xbbe85a25, 0x4913f855, 0xb7e30e58, 0x2abcf57f, 0xf06a7cf2, 0x47c9565c,
+ 0xfdadd3ed, 0xaff91199, 0x8321e3af, 0x7eef5c3b, 0x752a73cf, 0xdafdeabd,
+ 0xfd85ab7e, 0x2576939b, 0xe90e9f1f, 0x1deb0ed4, 0xb7bff23e, 0xc7e41c98,
+ 0x905c9a27, 0x3469f88b, 0x9afef8fa, 0xe4d12fda, 0x7991efe6, 0x234481f9,
+ 0x81e5bdd0, 0xf7fce554, 0x42bd602b, 0x9c16e871, 0xd756acb7, 0xd212c5bc,
+ 0x2cfeaa87, 0x0bdf871b, 0x3ea91ee8, 0xdf2027e4, 0xdb6b1594, 0x2da3f687,
+ 0xa0ae7bff, 0x6eb25963, 0x24b938c8, 0x1b65c857, 0x9e42c874, 0xa89d1d85,
+ 0xbf0d1de0, 0xacd7ee1c, 0x40fcf452, 0x0743d9bc, 0x8ab713bb, 0xf513ab7b,
+ 0x5104edbe, 0x124b400b, 0x89f4995d, 0xfab4baf1, 0x1cc86c9c, 0xd8e3cbb6,
+ 0xc8504f2e, 0xccd4b77d, 0xf7435bf7, 0xc132fd5c, 0xd0c8218b, 0x413d5609,
+ 0x4bc30324, 0x2a70c5c0, 0x0cbc3334, 0x015e19da, 0x02af0c1d, 0x89f8433f,
+ 0x1ed80daf, 0xff656edc, 0x3a25f2e9, 0xd765cbb2, 0xcf97ed0e, 0x3c35f052,
+ 0x57cb503e, 0xa63e3b9c, 0x8772f72a, 0x7cd8cbc5, 0x2f157be6, 0xec4fe226,
+ 0x34de0317, 0xc0209382, 0x46264ce3, 0xdd78a6ce, 0x6b7ef7c6, 0xbae5c9c1,
+ 0x6547c4b3, 0x1777adc0, 0xda97810c, 0x9e64f9a1, 0xb90327c2, 0xe951f8c0,
+ 0x8dae48f5, 0x30dd2acb, 0x7b234c50, 0xc84f4d10, 0xc59675a0, 0xa7a71cd6,
+ 0x5f3fb722, 0x7a8f5336, 0x66b4acb4, 0x5f90a90d, 0xe5154ee6, 0xd32f3589,
+ 0xf3fb7d51, 0x71728a97, 0x81c1a94d, 0xcbdae85e, 0xfa825e66, 0x27dcadd9,
+ 0xa011a337, 0xb672637b, 0x2b761738, 0x724dcaf7, 0x2fba5ae6, 0x580dba66,
+ 0x0063b8df, 0x22d7ecfc, 0xb8bc91b7, 0xb37b1c45, 0x3aafd055, 0x2e4b7dd6,
+ 0x2fb333d9, 0xb87486de, 0x28dd6d79, 0x18f79bb2, 0xa49ff8c5, 0x81bdc6da,
+ 0xc49932f8, 0xbf7556bd, 0xc189ef58, 0xadb24072, 0xad0cc969, 0x59c75d4b,
+ 0xe9d77bcc, 0x774fcde6, 0x023d206f, 0x15c70736, 0xbefb1463, 0x34c4cb65,
+ 0x1d7030f4, 0x20475e56, 0x0b4d772e, 0xee91dd56, 0x1bc6847a, 0xf87c1388,
+ 0x7529d108, 0x75cbe878, 0xc43b943e, 0xdfb581f7, 0xbd23eabc, 0x042e29f4,
+ 0xae4df9c7, 0x475a71fb, 0x51902e93, 0x45fbf48a, 0x05007a2c, 0x9096be21,
+ 0x0f107398, 0x1af04e6d, 0x77945e59, 0x99f9ca36, 0x8b03172a, 0x4fc43c71,
+ 0x8b55cb99, 0xcc5422ee, 0x60937e6e, 0x16bdbba5, 0x179e686b, 0x724d3d68,
+ 0xe4f881b0, 0xc607e268, 0xc76e594f, 0xf454fe0a, 0x9eb6f759, 0xa288c6db,
+ 0xb2e4c20b, 0xaf89db69, 0x6f7486ff, 0x5071663a, 0x3e3c90f3, 0xe79c46b6,
+ 0x46fa345a, 0x5d09d395, 0x9c383e26, 0xc5a2f5b8, 0x07d26ed4, 0xb7a4d9bd,
+ 0xda06f727, 0xe81e7dc8, 0xc8463bde, 0x7fd7ea89, 0x7d8b9d23, 0xfc8cccf9,
+ 0xf9104091, 0x839c5e23, 0x8af4fc73, 0xad5f0738, 0xeca93de4, 0x788b7de1,
+ 0x573b8d54, 0xde2dbcf6, 0x6ff07985, 0x122bbd05, 0x713e967f, 0x6fc455e3,
+ 0xd48bef91, 0x6949b478, 0x7bd7a2b7, 0xf227ed37, 0xc51351bd, 0xbfc345a3,
+ 0xa27a6a37, 0xc8d1e396, 0xb9bd46f7, 0xb14afe4a, 0xa1f8a08f, 0xb436944b,
+ 0x87c70b3f, 0xf709af46, 0x35c9fab6, 0xd3952b0e, 0xc7d60e2d, 0xe10e3d57,
+ 0x6489e1ed, 0x9e5519e6, 0xd893ad97, 0x5af156bf, 0x49c9bcfc, 0x7e7e28eb,
+ 0xe8cdfb14, 0xe97b8bef, 0xde913e4a, 0x837bd012, 0x2cc189cd, 0xb9ba67ba,
+ 0xfe41df3b, 0x9d5a1ff8, 0x68430ff0, 0x503c6a7d, 0x4b54bf27, 0x2d8e87ef,
+ 0x3f0b38c2, 0xa679eead, 0xd5e58ccd, 0x1055e9eb, 0x13f384a5, 0xdf2aafc8,
+ 0xc6978329, 0xd543ef01, 0x39153b08, 0xc0e9a537, 0x188f8616, 0x0db008db,
+ 0x29300f91, 0x4fcd8bf4, 0x39c7d4d2, 0x4ff4d02e, 0xd4d2cca8, 0xf788c5b7,
+ 0xfa71e032, 0xef422a0b, 0x3f9d1248, 0x0083f4d1, 0xbd08adfe, 0x7e27b917,
+ 0x4f7e4eea, 0x3ce06fe2, 0x2565f245, 0x7926f69a, 0x5dfc4cab, 0x435ea5fd,
+ 0xa6529fcf, 0xb956f11b, 0x9c1cfd1b, 0xb69f4267, 0x01e0263e, 0x5bb317ea,
+ 0x984bc9af, 0x85f2da6c, 0x629e4a79, 0xe4d58c2c, 0x2ef10629, 0x61d8fef8,
+ 0x0545f31d, 0xbaaafce4, 0x006cf08c, 0x6f1a2daf, 0x5df840c7, 0x1c5ac6c7,
+ 0x426a96f4, 0xc932cbcf, 0x8b4baa41, 0xb5b351ff, 0xd6ed1ff8, 0x52cc7be2,
+ 0x9bd3be2d, 0xb0bef8b5, 0x4cd78b45, 0xd96f168f, 0xda6826eb, 0x346bdbdb,
+ 0x578dbce5, 0xe45fda68, 0x8f29a19d, 0x4d7af17b, 0x858ec2fb, 0xaee2fa9a,
+ 0x957a9ae5, 0x83e386cf, 0x11d5bef1, 0xdd03a6fc, 0x74a0f869, 0xf335cfe7,
+ 0x9ff450fd, 0x05e8a79f, 0x2bd7fe85, 0xf8dde576, 0xb892f7c3, 0x7a158b4e,
+ 0x50df3070, 0xee78e06d, 0x6d725b3d, 0xc505e91c, 0x7b14b9de, 0x894f3907,
+ 0x1d9455b2, 0xa2bf717e, 0x36ab9f64, 0x2cf746de, 0x8a8afdc4, 0x09b5edc3,
+ 0x1de23ed4, 0x494af4d6, 0xf91dde73, 0x67a66b2e, 0xd1209cad, 0x3f7144bd,
+ 0x841ef231, 0xdeab3efa, 0x2739a319, 0x96bdee1f, 0x78c25f9a, 0x2f148c01,
+ 0x3efccce8, 0x721fda31, 0x5fd9946c, 0xf6ffb373, 0x79cdc967, 0xfecc6ba7,
+ 0xecefe20c, 0x79f5eeb1, 0x3aa3b788, 0x3dfd8d87, 0x00d6fde5, 0x2fdf8c6d,
+ 0x3ca4ccf5, 0xbb8600e9, 0xdfd4d794, 0xbd2663b3, 0x5be5c45b, 0xac221503,
+ 0xe68f3fa6, 0x71a41fb9, 0xbbd6480e, 0xbbefb14b, 0x20cf3e13, 0x73a2667b,
+ 0xff3e12fe, 0xfc2f387e, 0xee147bfc, 0x406df50f, 0x79f0f367, 0x8e25cfee,
+ 0xc1a73e53, 0x77e4c2aa, 0x4f79419d, 0xb9b6e22a, 0xb8d4be0a, 0xff328e6d,
+ 0x29621c01, 0x5db9f3ea, 0xacbc667f, 0xe253eb48, 0x158766bd, 0xac71bfc7,
+ 0x7bef84a5, 0x221d4b39, 0xb8e357de, 0xb1f7f231, 0x87ba67b3, 0x88ed22b5,
+ 0x97869e26, 0x57cc8792, 0x42c5e646, 0x1fe316fb, 0x76cb1f58, 0x74fac0e8,
+ 0xc6863fce, 0x85f9ca3f, 0xfbdacdb9, 0x3e5bf3dd, 0x02dff0d2, 0xfa9a27cf,
+ 0x30d04a40, 0x781ff706, 0x1bd4f475, 0xaffd7f10, 0x9e282a98, 0xe4f5ba45,
+ 0x0fc68795, 0x897797dc, 0xb4ce1bf0, 0x1d79cfcf, 0x5afdcabd, 0x5bfb9f75,
+ 0xd03971f7, 0xefb8881a, 0xbfc4d1e4, 0x09fe342a, 0x0e8fc9f2, 0x431c234a,
+ 0xe76673e5, 0x57a9388b, 0xabda7779, 0x55ed3bbc, 0x2af689de, 0x957b42ef,
+ 0xbbeaa177, 0x9c095edd, 0x8e64bf74, 0x816a7ae4, 0x0f76efc4, 0x969b3ed1,
+ 0x5de88b07, 0x60715363, 0xbbf3249e, 0x7df423dd, 0x45bb7788, 0x69f49592,
+ 0x6ef435ea, 0xcf08f0f7, 0xd9d8b251, 0x50d789f9, 0x28d870bc, 0xc5f4a3e4,
+ 0x7bd2666f, 0xdd53c7bd, 0x3fbf89c7, 0xf31f6495, 0x9f12ebf3, 0x6033832b,
+ 0xef16719c, 0x13cbbf7a, 0xf32734e7, 0x0a89b9c4, 0xbd0be647, 0x9cb04a56,
+ 0x2e6f72e8, 0x68dabbbf, 0x385777e2, 0x7617539f, 0x7df2221f, 0x4d1fc95c,
+ 0x6a1fd23e, 0x5f2127de, 0xbbd3379c, 0xca675a39, 0x6ef126fd, 0xa0cfe02e,
+ 0x0f747677, 0xbdf245ca, 0x1de29c1b, 0xf0a6de5e, 0xf90930f7, 0x45bd3dca,
+ 0xb7a779a0, 0x7ec0e7b2, 0xe5af27d2, 0x53f393b9, 0x56c7ef43, 0x7f676fc6,
+ 0xc6df20af, 0x797ae2f3, 0xee17a8ff, 0xc79cfa24, 0x7e56617c, 0xd7fff479,
+ 0xf5bc3860, 0x5a3ff62f, 0xf77a1990, 0xaddef616, 0xaf2c3f20, 0x343faea7,
+ 0x42e5e9ce, 0xe5a97bcd, 0x93dd8f43, 0x7486724b, 0x5948f911, 0x88633f9a,
+ 0x05f3d3fe, 0x774feffd, 0x97f9a04d, 0x60bc8b37, 0x6fda6f88, 0xdce898f9,
+ 0x3ef21963, 0x723fdabf, 0xf5b72b9f, 0x9f703e30, 0x617f68f3, 0xf08cbcfb,
+ 0xbfb3eea5, 0x05a3ef7b, 0xdfdf73b6, 0x6e777df7, 0x6d71811a, 0x767950d2,
+ 0x7e613eb4, 0x3fed4999, 0x8fedaf56, 0xb1e5390e, 0xd1de48bb, 0xe254e96f,
+ 0xc4cbb21e, 0xee5daa17, 0x2920e254, 0x02ed83b0, 0x71724bcd, 0xfb61e4b7,
+ 0xda3be6a8, 0x947fb424, 0x61af7057, 0x685f217b, 0x775f1071, 0x49f9ef22,
+ 0x58cef41e, 0xc44773ce, 0x758b3fd7, 0xbc7844df, 0xa335aff9, 0xf2defe28,
+ 0x38942b97, 0x72abd84e, 0x69cb3f85, 0x4147da7e, 0x996df302, 0x730abeb2,
+ 0x55c9fb33, 0x5e4591e0, 0xac93c943, 0xdff1c1df, 0x141a01ff, 0x43d0aaaf,
+ 0x000043d0
};
static const u32 usem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x33a98f8a, 0x32e8f430,
- 0x31e8a430, 0x43d4dc30, 0xcf12d388, 0xbf4ca2e1, 0x83030b30, 0x038b1028,
- 0x7f1024b1, 0xf8606463, 0x7ebc48ce, 0xbb04115e, 0x81818045, 0x070fc80f,
- 0x1905ffd2, 0x330b3e18, 0xf903f030, 0x6dfc80b3, 0x88087c40, 0x376280c3,
- 0x2067f480, 0x02c40fbe, 0x17cdf822, 0x417f2024, 0x07ff9508, 0x1042ff8d,
- 0x61637ebf, 0x0496f2fc, 0x4de1b1e4, 0x0f8cdc04, 0xef40a77f, 0x6a87e040,
- 0x557d7ca8, 0xa02b0606, 0x843a8758, 0x7e4908ff, 0x40cc5016, 0x93e6c215,
- 0x05506067, 0x61ab1ff2, 0x281f9737, 0x5f9406af, 0x00073506, 0x15e5ac6f,
- 0x00000368
+ 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x1894738a, 0x18357a18,
+ 0x326b3618, 0x31686830, 0x20318830, 0xaf8568e4, 0x9fa65371, 0x8181959b,
+ 0x81f98817, 0xd7881058, 0x6c303133, 0xff5e2260, 0xfb045111, 0xc303209e,
+ 0x197f2051, 0x6614ee90, 0x64055860, 0x2fe2031f, 0x1080be40, 0x100c8303,
+ 0x606115ff, 0xc1d20530, 0xc4036c40, 0x9bf145c7, 0x7c80827f, 0xbf2a08bc,
+ 0x279f8d1b, 0x25ff5f8c, 0x0ff2fc11, 0xc363c808, 0xc7e41632, 0x7a052247,
+ 0x29370207, 0xca8ff2a2, 0x543c3033, 0x51d06060, 0x919bf082, 0x6280ede4,
+ 0xec21e4c7, 0xb8c09229, 0x28b5ca07, 0x2a773762, 0x5004fe50, 0x34894bce,
+ 0x41d3dcf7, 0x8434afe5, 0x3ebc00d0, 0x03a8e414, 0x000003a8
};
static const u32 usem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7dedff00, 0x45147809, 0xf4f570da, 0x73264cf4,
- 0x10909264, 0xa70930ae, 0xe15c380a, 0x1084ca30, 0xa8ea2416, 0x1388a888,
- 0x2e421081, 0xf57175d1, 0x11c3a7fb, 0x9e375941, 0x1d47facb, 0xa22cdc10,
- 0x60188806, 0xb200c1c0, 0x1761bb8a, 0xc363d715, 0x01921a0d, 0xe5c58f15,
- 0xeaadf7ab, 0x44ceee99, 0xeff3eba2, 0xe3fdfb7e, 0x575453e3, 0xef555bf5,
- 0x5dbd6f5d, 0x71024a31, 0x02e426f6, 0xf211c6fc, 0x4908488c, 0xe36d9689,
- 0x1749c7c3, 0x92cde442, 0x8840ad6b, 0x343dbaf0, 0xfb21046e, 0x33010956,
- 0x587687ad, 0xd3f5a109, 0xcc07d735, 0xd43eb419, 0x9afac1ec, 0xbee7ac1c,
- 0x48c3aefa, 0x8aafa5eb, 0x761ba846, 0xdb34729c, 0x37372908, 0x7d05723d,
- 0x24557e1e, 0xc450e9ab, 0xb240c535, 0x471e3908, 0xad196fd8, 0x685212a7,
- 0x55d2d561, 0x3cc2673b, 0xc4cc1a8a, 0x6e94e142, 0x15ed7b99, 0xaf773eb4,
- 0xe94ba044, 0x77534ada, 0x10179f5a, 0x68bea0ea, 0x4e3887c7, 0x545278db,
- 0x4f908837, 0x35c471fd, 0x4d1dd680, 0xe7d137a9, 0x130d81c5, 0x7af17fa1,
- 0xfda06dc1, 0x7e766b8b, 0xeb8bf004, 0x8522bea5, 0x4ad6bf3f, 0xd8d9035c,
- 0x63ac0817, 0xdf30b5ce, 0xc4483fd2, 0xe745eb4c, 0xc01136ef, 0xe4dab191,
- 0x8ff8c3b5, 0x18765c9a, 0x51c716a7, 0x7bfa59f0, 0xaf7d0e3a, 0x0dc165ec,
- 0x10332b4b, 0x75a7cc1f, 0xf3fa658b, 0xa5575836, 0xbfbc3fa9, 0xf41341e5,
- 0xd8281b9b, 0xfcc1716c, 0xc2269956, 0x99566b3c, 0xe145070a, 0x517dafcd,
- 0x2be3af33, 0xa9f574fb, 0xa7e5f5da, 0x735a8a7e, 0x884c5eb4, 0xf306cea7,
- 0x1fae980e, 0x547e7d1c, 0xcf7a4448, 0x2b8915af, 0x529f0a2e, 0xefcb9f1e,
- 0x1f027fd2, 0xd607b76c, 0xb5e94466, 0x8eff09c0, 0x93acebd2, 0xce18cfd3,
- 0xca57c352, 0x740e8047, 0x277ed53e, 0xd3f98f96, 0xefc27cb0, 0xe53dbc42,
- 0x4ae5881f, 0x3f9f1bbf, 0x658d1fed, 0xe583df8d, 0x5849feb3, 0xec5efc06,
- 0x1d3fdab7, 0x1f7e35cb, 0x5fc17f3e, 0xbfad6584, 0xf3af9f02, 0xbd72c42f,
- 0x2fe7c65f, 0x596197fb, 0x72c6afe7, 0x96257fa3, 0xf600fef5, 0xd7e9ccdb,
- 0xe7c3afe0, 0x580dfd5b, 0x2c21fd06, 0x62f7f877, 0xd5e382b9, 0x8c724d91,
- 0x0f0e2f14, 0x20715271, 0x1c9ef949, 0xbc93d689, 0x433a9eac, 0x7ad131ce,
- 0x29d68faa, 0x8497ba9e, 0xdeb4cc72, 0xa7b582bd, 0xc7c6403f, 0xccba7ad1,
- 0x785733da, 0x3d685bc6, 0xf7b59ab3, 0xc7c791af, 0x00ff7ad3, 0x7d74bf6b,
- 0xd695bc68, 0xed63ad2f, 0xd7248243, 0x4243eb46, 0x9f6c3eac, 0xeb4ed727,
- 0x3d589ac3, 0xd73923eb, 0xcd59eb41, 0x2db1fdec, 0x5a04dca1, 0xed661b1f,
- 0x166f9d57, 0x67f8315d, 0x459be4b3, 0xf2032d28, 0x1bb18f14, 0x777c9bad,
- 0x97c53713, 0x1c63d53c, 0xc923f143, 0xbe4bbed8, 0x4c1bdb1d, 0x27bfb632,
- 0x56fb6217, 0x27ed8029, 0xdf6c72e5, 0xfb600a6a, 0xac42f2b7, 0xb610a507,
- 0xb12b2adb, 0xc214d07f, 0x87caf4f6, 0xd4877db0, 0xcaeeed8c, 0x877db1c7,
- 0x1fdb19a9, 0x99e3525b, 0x0b0feb40, 0x2f81a7be, 0x22be0b17, 0xadf807d2,
- 0xf94bcd2e, 0xd3204aad, 0x0117bf81, 0xaaf6d253, 0x47d4266e, 0x7ace3f9b,
- 0x6f38145e, 0xe17a8176, 0x20650f0b, 0x8e11e79c, 0x1788e144, 0xc9f59387,
- 0xac9c0d68, 0x38148a4f, 0xa58e11eb, 0x7f367073, 0x9f3b5632, 0x38158a4f,
- 0x149192af, 0xeb73bd8e, 0xb65bfaca, 0x2b7f3e76, 0xc0ece051, 0x6e7624f9,
- 0xb4c70d3e, 0x163869f8, 0x389bcfc1, 0xcdce949f, 0x2d71f467, 0x8f1f467e,
- 0xe109a7e0, 0x9c1ceb74, 0xfc5ae386, 0xe08f1c34, 0xd38403e7, 0x1aeb73ab,
- 0x9f8b427d, 0xf82227d1, 0xc9f88c39, 0xad9c1ce8, 0xd9f8b5a7, 0x9f823a7a,
- 0xbf4e10cf, 0x6c6badce, 0x633f16ab, 0xf9f8235b, 0x4975d702, 0x6d6ce0e7,
- 0x6b67e2d5, 0xdf3f046b, 0x9dc19c21, 0x36d8d75b, 0xb6c67e2d, 0x1263f045,
- 0xced0ce00, 0xa5f827cd, 0x2fc13f16, 0x4049f823, 0x373b2338, 0x5a73ec9f,
- 0x8b9f64fc, 0xe10d27e0, 0x9c1ce98c, 0x7e2d39e0, 0xf822e782, 0x573840c9,
- 0xd95d6e76, 0x93f1695f, 0x3f0455fd, 0xf7400a97, 0x421f3e1c, 0x863bd8e1,
- 0x2d3be3b3, 0x177c767e, 0x9c70cfc1, 0xcf9f1e4f, 0xf55ce045, 0xae7e2d0f,
- 0x3f0447fa, 0x726708d9, 0xf8ece0e7, 0x3b3f1687, 0x4fc111fe, 0x9aebae1e,
- 0xaaebadce, 0x5cfc5a0b, 0x67e18175, 0xdcbad1d4, 0x6d4eda04, 0xafa45ba3,
- 0xf1ef3b8c, 0x3a2eb408, 0xba745d59, 0xa22df809, 0x26908fe2, 0xb7df488f,
- 0xf61c4fad, 0x25fb5110, 0x75826fe3, 0xa697a9d9, 0x46124bf6, 0xa0fc6bc7,
- 0xa6924f44, 0xbba93c9e, 0x378a7fa6, 0x75ded353, 0xf69aa5fa, 0x9a61be6e,
- 0xb1a28f7a, 0x2abdfe9a, 0xbdea6bc6, 0xe9ad5e17, 0xa0df219f, 0x7659f7a9,
- 0xbf7fa6ab, 0xed353bea, 0x6b165603, 0x2c092fda, 0xab2fd4d0, 0xffa6a5fd,
- 0x9a45bae0, 0x1e1bcbf6, 0x0d0fb4d2, 0x0fa9a63d, 0xa6b4fbdf, 0xd5a6c8ff,
- 0x0751f69a, 0xc7da69d7, 0xd4d46f34, 0x55b938af, 0xf0caffd3, 0xb8fa9a1b,
- 0xf4d2dfaf, 0x1e7394a7, 0x45d78cbf, 0xfb820b90, 0x099bb902, 0xdd90c5fd,
- 0x77537584, 0xd827db1b, 0x29475d0b, 0x9f064ddd, 0x812d0bab, 0xfdda84e6,
- 0x0345ee9c, 0xdc5f299a, 0xc037d63b, 0x6bdf9f49, 0x8cee5df2, 0x7e509fe1,
- 0x941a4811, 0xfa94032e, 0xc62507f6, 0x9c7be3af, 0xbe887fef, 0xf7086e5f,
- 0xbff5a44f, 0xc002721b, 0xd4082fdf, 0x157ca7eb, 0xe80a922f, 0x1e266f17,
- 0x3307dfe0, 0x55979eb2, 0x17acbcfc, 0x0a215395, 0x4be49977, 0x5d643f03,
- 0xf832bbe5, 0xe8bd5529, 0xf213baba, 0x486ef0a2, 0xefdf4bee, 0xa3e69855,
- 0xea26ccf0, 0x37c7abe7, 0xe107f1d1, 0xcfc075f8, 0x94fc619b, 0x339be3f6,
- 0x8fc66b47, 0x8cd22f4b, 0xe3a2671f, 0xafbea93b, 0x4f8f98fc, 0x90963289,
- 0x38c7c26d, 0x08bd39be, 0x44d07fc7, 0xf1ea3df7, 0x87e323e3, 0x3a7bfd60,
- 0x58e67f5a, 0x8bd3faed, 0xb137ebb5, 0x7955bff5, 0x8f1f8f8c, 0x385b7feb,
- 0x5e9fd6c6, 0x666fd6cc, 0x3be32370, 0x826ff822, 0xd1d7bff5, 0x6b64fbfa,
- 0x44bbdfd7, 0x1b337ebb, 0xa795afff, 0x1c36f8f9, 0x34e143ff, 0x12ef7f5b,
- 0xf664df1c, 0x4c7f81b9, 0x022be23d, 0x93d27c74, 0xc0aeae2a, 0x281c742e,
- 0xa6512607, 0x2149e427, 0x6f71e713, 0x73b7e33c, 0x50df94f1, 0x9cf8c91f,
- 0xa3e6a804, 0xce329cfb, 0xe7d7f3fb, 0x616f4098, 0xccefdd3b, 0xdd9d53e1,
- 0x937f2220, 0x7e81cc27, 0x0dadbe74, 0xd9f50ca2, 0x00195c4f, 0x266e58fd,
- 0x3de17877, 0xf3c10923, 0x5e0e4f63, 0xbe975ead, 0x1d2d539c, 0x17c8d66f,
- 0x9e3c8f9b, 0xf3a0ac0c, 0x182603cb, 0xa71fad19, 0x98d829fb, 0x12fba61e,
- 0x74484f28, 0x28fcfa3c, 0x01916fdd, 0xc4a9b96a, 0x79ec88f7, 0xff9d2fb7,
- 0x3cfca234, 0x51dbceb8, 0x233c28a4, 0x1af1ffc3, 0x98f40021, 0xf9f74d53,
- 0x372ff92a, 0x170ef933, 0x02d58108, 0xff7d2bc7, 0x813efe66, 0x33f851f9,
- 0x8f9dec9d, 0x47b35c77, 0xedfdd070, 0x9c0d64ca, 0x6960485b, 0xb6ff7d1a,
- 0x62253b15, 0xe828be00, 0xe5f800b5, 0x7084897e, 0x429cda9f, 0xa0667106,
- 0x064e7df0, 0xd2e9e6ff, 0x9c1566d1, 0xc79c5299, 0xf333e74b, 0x7be7113e,
- 0xdedb4f8b, 0x31eac3bc, 0xcae5a10c, 0x494225cf, 0xb6915b7e, 0x6d0af6fd,
- 0xda858efd, 0xee0f5d3a, 0xfd640bf3, 0xba1cba73, 0xeb233bce, 0xf5a70ba6,
- 0xd66dbc59, 0xd0d64932, 0x4d736e91, 0x133dbc59, 0x4f104ed0, 0xf69f7ef8,
- 0x681f29fd, 0xea5773ea, 0xf8be71e0, 0xdffff4ff, 0x86f2ff4d, 0x5547c59c,
- 0x9bad2af3, 0xaaa8f8bc, 0xebdafcdf, 0x8179f535, 0xe7fd345b, 0xb4d02cae,
- 0xa79ea9cf, 0xecb59f69, 0x40bd4d2e, 0xffd34fbe, 0x9a95858e, 0x962bdbf6,
- 0x2b6fda6b, 0xbf53547a, 0x4d5bf7c5, 0xafa79bff, 0x3b0bb4d2, 0x466ef5e6,
- 0xddebe9bb, 0xf4fe928d, 0x7c026607, 0xc2b3f0a6, 0x69fd27ef, 0x77ea7e58,
- 0x7a095961, 0xc377ea98, 0xaf965616, 0xfa0de82e, 0x13ffe15c, 0xe83a4552,
- 0xeb3f3d4b, 0x4f9eaff5, 0x2c47afe9, 0x4b29433f, 0x3b05e204, 0x64fdc6d6,
- 0xdc37f9e5, 0x0ce782ce, 0xc9898965, 0x6ec6c965, 0xea0389e3, 0xb615fea1,
- 0x3a92e18e, 0x2041d701, 0x74029a4a, 0x976d41eb, 0x347dae9a, 0x29d96cf3,
- 0x2065f8e2, 0xdcc06393, 0x60187778, 0xfa6350fc, 0x3e61838d, 0xdeb1d79e,
- 0x56fe8290, 0xe2d27f8b, 0x7f00fda3, 0xfa4f2c5e, 0xdc7963a7, 0xa8f2c3ef,
- 0xc3cb08bf, 0x9b2c0afe, 0xfcb10bfd, 0xf9632fc4, 0x96197f91, 0x6357f57f,
- 0x12bfd079, 0x01fcf7cb, 0x1efd5b2c, 0xfd3e152c, 0x18eba14f, 0xae9cbfc3,
- 0x3ae9a8df, 0xf364e0c6, 0x187d74e1, 0x6fc31be6, 0xc8ce0fee, 0xe23f9548,
- 0xdb718c99, 0x4ece3c05, 0xc71624c8, 0xa62f63e5, 0x6fd09ae0, 0x3d040c09,
- 0xb7e0767c, 0x7d4e21fd, 0x4a2520f6, 0xd3ebc746, 0x3c43afd3, 0xeffa0f10,
- 0x974a0185, 0x96edf6e4, 0x8b578678, 0xc3224c81, 0xefde5908, 0x839df705,
- 0x49246eb0, 0x7dc07ef0, 0x5c063dbd, 0x7e020bea, 0xc5d7862f, 0x004373f6,
- 0xffa7f1de, 0x18e5059e, 0xe307f303, 0x4bf4451b, 0x3779e849, 0x67a237e0,
- 0x8834eecd, 0x99fb86f7, 0x9af7689c, 0x4fe2d6ae, 0xbf835abe, 0x55fc11e5,
- 0xfafe21a7, 0xc28ffb9e, 0x8784f11f, 0x8a3830dc, 0xef846fbf, 0x1e729fc7,
- 0x36ef1fa3, 0xf883f8d1, 0xc1552db2, 0xa13a536b, 0xf811fce3, 0x5b3fc29f,
- 0xf001203f, 0x1173811c, 0x7faf08fa, 0xe8fa0e9c, 0x16c9d034, 0x0e9f7785,
- 0xcfbdd9de, 0x5fefc03b, 0x47ca2690, 0x2959e063, 0x6432eb4b, 0x6a4fda9b,
- 0x56cfd6d0, 0xd0ea930b, 0x4c25719f, 0xd7fa0c1d, 0x40951f29, 0xa961a64f,
- 0x669059c0, 0x7d2871c2, 0x4faf5c98, 0xd4ffb944, 0x7efd871f, 0x047479ea,
- 0x7a8f3a27, 0x0fbe8472, 0x4fa17f2c, 0xe43bfdc7, 0x2617e353, 0xa091b388,
- 0x97fc0e74, 0x05fffa38, 0x46237838, 0xcb702bac, 0x7cd944eb, 0xaf5f3c39,
- 0xe7be8f19, 0x2f06ce52, 0x3c9f7e64, 0x8571c918, 0xa8a9a95f, 0x48d61881,
- 0xac8b5be0, 0x35128ff5, 0x6e86f2f5, 0x825fc6b2, 0x4a3d507f, 0xf023048a,
- 0x9f67094b, 0x996da336, 0x0bf7e740, 0x3e816208, 0xd2bf5810, 0xcf9366b8,
- 0x78b2fc05, 0xe82e15da, 0xd5eb8d59, 0x2fd28fcf, 0x3c7528c3, 0xd9e2f9ff,
- 0xe431bd7b, 0xdbd72763, 0x57160625, 0x03b27120, 0x9a48d7ce, 0x8ec1b8ec,
- 0xf045b353, 0x3a3b7183, 0x0a0f0a8e, 0x2901799c, 0x995ff5ac, 0x5818b65c,
- 0xee3f40bc, 0x94dc619f, 0x6cafe38b, 0xb089fefd, 0xcb1e3d6e, 0x7c98ce1a,
- 0xbff45728, 0x151e28ac, 0xf442fefc, 0xeba459fe, 0x843dae2a, 0x9293eafb,
- 0xeffeffdc, 0xe7ed8bd1, 0x6e3b4b6f, 0x265bad55, 0x9dce304d, 0xc440f9a3,
- 0x5487f375, 0x5b7a9f5f, 0x5d010f22, 0xaa5ed3ce, 0x828f5079, 0xfea2b218,
- 0xf3f59dfa, 0x9f7ec1f3, 0xf7053cda, 0xd789b32b, 0x22ca4101, 0xfe059d52,
- 0x986269f9, 0x4d3a7804, 0xae18ecfe, 0xd139d3a2, 0xfea1f484, 0xfcf561fb,
- 0xa9aeffa8, 0x535dff53, 0xa437242f, 0xe178f9c2, 0x08091213, 0xfb4d3eb8,
- 0x7089d171, 0x2a8a92e7, 0x4b1677f0, 0xe9dfaecc, 0x541ec624, 0xf6be979f,
- 0xad01564c, 0x7f32277f, 0x9def3944, 0x377b7547, 0xb75c5eda, 0xeda1e4ca,
- 0x4f87ea47, 0xfbc082bb, 0x3fb02a81, 0x7b82abf2, 0x7e3dabad, 0xf5fce87f,
- 0xa1fc55f3, 0x7ccee776, 0x82b5a51e, 0xcf831027, 0x67c646ac, 0x30f63f0a,
- 0x8df1353a, 0x70faba01, 0xae9c7d5d, 0xbde5a3fe, 0xfbc8d10b, 0x00df442f,
- 0x6f930a63, 0xc609dfd8, 0x8ff3f230, 0x0ed69f86, 0x149ff0fe, 0x9cad4f7e,
- 0x7ee3f851, 0xdb7df852, 0x2c4a7fcd, 0xbdafa5f8, 0xfaa659b4, 0x2795f8a9,
- 0xa7ea841d, 0x54eac653, 0xc97fa537, 0xe00ea5da, 0xd9469383, 0x2a7cfc01,
- 0xc40a4e20, 0x8c8b77d0, 0x3daff702, 0x6fe20136, 0xff0a4ff0, 0x5f0f75d3,
- 0x7387710b, 0xc627256b, 0x21cd6ad5, 0xb2d39533, 0x64f979fa, 0xb10fd608,
- 0x446783fa, 0xf96837a8, 0x4f77f8b3, 0x5f50baa6, 0x180c3dca, 0xffa10e3f,
- 0xd8e6b65f, 0xe5fbb044, 0xa6728c24, 0xffc60f7f, 0x53ed093a, 0x7da12981,
- 0x53e46e3b, 0x2bf67de1, 0x8cf87faf, 0xf27280e8, 0x7427d009, 0x03f184e7,
- 0xdc457bfd, 0x68dbbf9f, 0xf3f182ef, 0xe8146451, 0x242f0531, 0xf179fcc0,
- 0x408667b5, 0xcd65b51c, 0x85410edb, 0xcede452f, 0x6e7acdd6, 0xbd63abab,
- 0x51e54ad9, 0x7e2a47ed, 0xef81ab85, 0x2cac8243, 0xc80e4291, 0x255929ab,
- 0xb8fa65b9, 0x5fe7a5e4, 0x9ae21a78, 0xfddd981f, 0x2ff9fc28, 0x2c6f7eed,
- 0x20dfcfad, 0xcb67c975, 0x51a909b0, 0xffd394fa, 0xd28b0e17, 0x6ed378a3,
- 0x7b306b93, 0x945240fe, 0xec37f32e, 0xedc19134, 0xb75b91f1, 0x8b6cd4d3,
- 0x43ba9f41, 0x130fc113, 0x04cefb5f, 0x43b53ff4, 0x62335d20, 0x6ed573e0,
- 0x4f00d3f4, 0xaf4e4f48, 0xfd74fd08, 0x405d29cb, 0xa5e9ebaf, 0xf41537ef,
- 0x0b830a4b, 0xbf9412f9, 0xf90ade5f, 0xbb357f48, 0x2f450f01, 0xf580eddf,
- 0x3056309c, 0x69667f3e, 0x5f8e87aa, 0x4ea9c924, 0xa2f3d92c, 0xfc8e7f67,
- 0xcfff7737, 0xcb5c5953, 0xb680cdd3, 0xeb06ee4a, 0x1373539c, 0xf890b3ae,
- 0x9e8b0f90, 0x2fa0bd11, 0x499234bf, 0xc9c8621b, 0x4e4e5cb7, 0xa5c4a6ac,
- 0xcd413ceb, 0xfce9e610, 0xc5ac0c59, 0x185dfa38, 0x5f39fb37, 0xb0e8f50b,
- 0xa31c65fe, 0xc0d19357, 0xeaf52ef5, 0xe6bbfcd5, 0xd3a026c1, 0x5d3cbda7,
- 0x9ca5fce1, 0x0f8e6518, 0x2b8502e1, 0xcaebcfee, 0xc65c44e8, 0xf51efe2c,
- 0x39e172cb, 0x3c926ff4, 0xf79a2196, 0xe88c85c8, 0xf1f0f7f8, 0xc1e3bce9,
- 0x1a913a9f, 0x40305f7b, 0xb502ec52, 0x533e2aeb, 0xff933bc9, 0xbc99cb35,
- 0xb81ff22b, 0x7fb4127e, 0x11c98071, 0x92f607bc, 0x15d42bce, 0x154e77db,
- 0x49983f50, 0xaf9c9628, 0x6b9cb891, 0x42fcf5db, 0x12146fe7, 0xe3037c54,
- 0xd01d2124, 0x827c2a9f, 0xa3d2afbe, 0xa3ae30e5, 0x8e455c3d, 0xf07d72e7,
- 0x6b03e825, 0x1a901f54, 0xf63a07a6, 0x53c4657b, 0xe1781489, 0x2a5f9069,
- 0xe40bb2af, 0xfac2f257, 0xf8df5b3f, 0x6e54adde, 0xe453ab3e, 0xf557ab56,
- 0xf1b45b72, 0x54f804e7, 0xf59fb72f, 0xe53120ac, 0x298f3e96, 0xff9b3db7,
- 0xc1557a25, 0xd5a4ba63, 0xec9e8aab, 0x3d7a9f08, 0x42e8c5b9, 0x24f5eabc,
- 0x59201dfd, 0xe151f9ed, 0x8aff8543, 0x0ded2c5f, 0xa7c228fa, 0xf8461f0a,
- 0xfd43e154, 0xd478b5ba, 0x9e7c63b7, 0xcb778bf2, 0x507b13bb, 0x050496ba,
- 0xef85d9b7, 0xc53a81ed, 0x0b6d8797, 0xe8f4f7aa, 0x7407aea2, 0x7f5d3af5,
- 0xd5eeae8f, 0xeae9f7f5, 0x01feba15, 0x68694fb6, 0x87e41134, 0xb4bfa690,
- 0x9f90c888, 0xe22ede16, 0x9d1b41b9, 0xbf7d1573, 0x40467d6d, 0xa961faa6,
- 0xc3dbed85, 0xd02aa629, 0xb0ce6d67, 0x16ea0923, 0xf36b7f16, 0x2a891d86,
- 0x5050f1ff, 0x1cdc7d44, 0xed629320, 0x8bc7a85f, 0x1d266bf4, 0x90f3b3b5,
- 0x10c778b6, 0xb44f2f18, 0xf8842fa5, 0x86e8b54c, 0x95d98e23, 0x5ce03b37,
- 0xe7d82da2, 0xf9f4e9ba, 0x2c883f9c, 0x18f6422d, 0x0df6a9bb, 0x54fc8927,
- 0x95f900b6, 0xb3fe902b, 0x311f6c82, 0x7e6c457b, 0x15efe62e, 0x8131eeda,
- 0xfffea4de, 0x5f5c7561, 0xa3545381, 0xc29c1e7b, 0x2fed9ef9, 0xdb68d78b,
- 0xfa3f7c7d, 0x0fdf0a5f, 0x7ed94325, 0x0838b090, 0xe279bbd7, 0x53a6eba0,
- 0x15edb43a, 0xd9cdf009, 0x387488a0, 0x40085ebb, 0x29c88a5c, 0x24653f28,
- 0xc14efa8c, 0xc7c80b57, 0x50f58e80, 0x671fabcb, 0x94bb4fdd, 0xc870fe6c,
- 0xcb65a5ff, 0x6ffa0fe6, 0xef6bfa83, 0xda487fa7, 0x61ddcff7, 0xb6df73c1,
- 0x27cc761d, 0x4efedb6e, 0xdf50fdfa, 0x3cc37662, 0x357c76db, 0x6da8f804,
- 0xf408b991, 0xb62f5b58, 0xfdbc59ff, 0x68cd21ab, 0xfd20973f, 0x8b13256a,
- 0xfeff04d7, 0x4a05d089, 0x0ff02aba, 0xf9727e78, 0x20804b56, 0x7cb2affc,
- 0x3d6e9fb6, 0xbf9cfc65, 0x6fa64ecd, 0xb225f984, 0x6df2ec73, 0xa4af9e63,
- 0xefd697e3, 0xeda2cd34, 0x377fafb9, 0x3791f304, 0x55a7bf32, 0xce167e6a,
- 0x6f4937b1, 0x9e28922e, 0xba38415b, 0x299d7213, 0xc5b6572e, 0x1877cbc2,
- 0x3e2cea97, 0x7ed892de, 0x1f1fdff4, 0x9511e602, 0x3881ed04, 0xcdfdd601,
- 0x3e821f27, 0xbe4661d8, 0x59fbd654, 0x23fa255d, 0xa9f75b17, 0xd07c31ff,
- 0xa10b75d9, 0xce3bacce, 0xeebdeff4, 0xce172447, 0xed072f4f, 0xbdfb7cf9,
- 0xeec97f58, 0x9276f9c6, 0xfe9a07df, 0x237df8c3, 0xe2e3bba5, 0xbfd9feeb,
- 0xa63bbaf9, 0x72661ffb, 0x1f213bba, 0xeff5fcac, 0x543f7e70, 0x1ffdcdcf,
- 0xbf8af7ca, 0x9b78366e, 0xa6fce872, 0x383b6a93, 0x9ca4b716, 0x73a907dd,
- 0x745f5ee6, 0xfc4af981, 0xbf3f51fc, 0xefb62695, 0x997ce093, 0x126e4b8e,
- 0xed8f7ef8, 0xfee5ae93, 0x0b3db5c5, 0xd6bd2fd1, 0x6277fcc3, 0x46737af4,
- 0x6cd89e40, 0xc943c637, 0xa83e83b0, 0xaf2574df, 0x7f8bf76b, 0xa0478814,
- 0xe9b5f9fe, 0x9f82f693, 0x634f5d7a, 0x43caccc8, 0xe0ebbe50, 0xf76b47cf,
- 0xb4f8b733, 0x6ba79bf5, 0x787137eb, 0xa2b9c0d3, 0x0af34fe3, 0x4a7f8801,
- 0x81489ebd, 0x4734a878, 0xf9008222, 0x614b1524, 0x579370df, 0xb03dfefb,
- 0xc5191dcf, 0x82b8bce3, 0x114e70f9, 0x7c405037, 0x4442b75c, 0x4837127d,
- 0xd1def840, 0x1e1de612, 0x00b37833, 0x47c3f9cf, 0x8192fd95, 0xe77ac373,
- 0x92157c71, 0xc877f40a, 0xb2170bf9, 0x4bee20b3, 0xe79a5fd0, 0xea1ae421,
- 0x0b6617b7, 0x63c878a1, 0x61391231, 0x0543c418, 0x0f135872, 0x77e1d6d5,
- 0xce146a55, 0xc477fac5, 0xf9753f8f, 0x87ffca37, 0x433fea25, 0x2cf3e789,
- 0xb3eca7ae, 0x3c3208ee, 0x81089796, 0x90abe44c, 0xb0cf3ea4, 0xfdff1999,
- 0x28e181ed, 0x1ebf3957, 0x7ff6c09c, 0xa0bbf023, 0x9e67ee72, 0x10095d95,
- 0xec1b38f7, 0x72d1cfc3, 0xfc18be1d, 0xbbef9fbc, 0x007902fe, 0x209b6cb4,
- 0xffe08b54, 0xfbc63093, 0xb21609e4, 0x5cbe4636, 0x8739498b, 0x207dc0af,
- 0xa02cc4fc, 0xa5cdfb23, 0xa92426af, 0x9ae2b6e8, 0xed21c653, 0xc3bf00e9,
- 0x7e4bce31, 0x3cfb096c, 0x4b7eebc0, 0x8c6f44f3, 0xcb83fef5, 0xdf1bfe6f,
- 0x376377e0, 0xc0243304, 0x44130dcb, 0x39eaf9cd, 0x87e3f713, 0xaf30e193,
- 0x3b2637fc, 0xf65d00c6, 0x4ef86e8a, 0xc6783cac, 0xce718be4, 0xc027c7a4,
- 0xc90073c7, 0x3cf8085d, 0x810b2bf2, 0xfc3bd6fd, 0xe41067dc, 0xadc20f61,
- 0x4ce207bd, 0x0b8b3366, 0x713b30cd, 0xe7e6379e, 0xdc742948, 0xa1cef541,
- 0x9dd5f470, 0x46019ff7, 0x5124246b, 0x7e94f7b0, 0xbf584bdd, 0x59672643,
- 0x113ff5ac, 0x733ae2c7, 0xd1defb89, 0xdd1fbfc2, 0x0f6d7e72, 0x327b078d,
- 0xd8e77d81, 0xca09af9e, 0x4249d9c7, 0xec3df400, 0x2f9eb09f, 0xc779bda0,
- 0x1be5dac0, 0xf8565e98, 0x11e78f5e, 0xf8cacf1c, 0x0c7d7953, 0xcf052f97,
- 0xf3f57e0a, 0x7d53fa55, 0x8f1d4e35, 0xe861aeb8, 0xcb0f60cb, 0x40d38282,
- 0x9b199541, 0xe587204d, 0x104a8f0d, 0xc5c5bf8f, 0x307b52e0, 0x3bfe7d44,
- 0xe1ceccc3, 0x315d871b, 0xf3e4f813, 0xa12fd415, 0x9f667bef, 0x7ddd8071,
- 0x13fee0c7, 0xff29077c, 0xbf6b2451, 0xe87d5f47, 0x904f1677, 0x703370d4,
- 0xe496379e, 0xb93e1048, 0xd4a764ad, 0x334fc555, 0xaed849cc, 0xe25eef3c,
- 0xe9cf061a, 0xf90f3878, 0x3c813311, 0x4d7541f2, 0x6ddbfdf8, 0x0f8c8915,
- 0x9a76ea8b, 0xfd819eb0, 0x7194f195, 0x3534f2f4, 0x341f9b5f, 0x27b9b72b,
- 0x1cdf25e0, 0x831dc7ba, 0x95982f4f, 0x681f8873, 0x6f943c27, 0xb22ffc87,
- 0x7628f713, 0xaaf259a2, 0x34de49f2, 0xd9573933, 0xecb1ae89, 0x574a82c4,
- 0x82c3a057, 0x82ba7ded, 0x43f82c90, 0x3b2c6a5e, 0x9d9faef1, 0xbfcfbe2b,
- 0x4a9b6d23, 0x2ae5c4ed, 0x82d5313b, 0x6f7fa27c, 0x7693b983, 0xffdba142,
- 0x2ef37d63, 0xf21889d8, 0x4fe38bbd, 0x82d313b1, 0xa6276805, 0xdf35154d,
- 0xf3336c5f, 0x76877178, 0x16f52722, 0x6b6e4bac, 0x9779fe0c, 0xf3efc3fb,
- 0x07183c3c, 0x5cb7c5ec, 0x46edebff, 0x371d7a47, 0xa13b2335, 0x7845ffd7,
- 0x02faf456, 0x339b2fea, 0x4121f162, 0x0b705e7e, 0xf002ebd5, 0x0bebd323,
- 0x3171e76e, 0x82f59e9d, 0xd6a11d9e, 0x32fdecb3, 0xe50bb31f, 0x99bf190d,
- 0xad6fdb41, 0xb471dc96, 0xbd51adff, 0xbbd6a59b, 0x77a476df, 0xfdde988b,
- 0xfd1c383c, 0xf7d68ea7, 0x54b7d731, 0xc775f59f, 0x33e98fe0, 0x77ef9aac,
- 0x737d0c8e, 0x979026d0, 0xd73c4477, 0x80fdc63b, 0x1cdf437d, 0xe9eaf101,
- 0xbbe44671, 0xad9e9cbe, 0x813c527e, 0x36772fe2, 0xd74ba7f3, 0xb2bf888b,
- 0x65ff267a, 0x45c042b5, 0x7d8713eb, 0xfcfa8263, 0x8e7ceced, 0x473f20ae,
- 0xeff9ff45, 0x3c415734, 0x012afe78, 0x1f2117cf, 0x9739f01a, 0x3dd0b3e3,
- 0xfa2bf71f, 0xf1e5833c, 0x72e4d58e, 0xd3f18784, 0xdf3fde52, 0x72f8c61c,
- 0xf704effe, 0x1f3ed22a, 0xd5efb4a1, 0x319f60a7, 0xdcf756bf, 0x11cf1cbd,
- 0x718b5fa8, 0x6d3ad2d4, 0x4ff71e7b, 0x41a188e6, 0xf57f609b, 0xcb1dd127,
- 0x22fd29de, 0x27fa29f8, 0xe29fb3f1, 0x874fc467, 0x9dc1799f, 0xa1fe5f18,
- 0xe3e3d178, 0xbf5c7167, 0x4023230c, 0x3c198f1e, 0xb7e45fa8, 0x9923cc44,
- 0xcd3f68fd, 0x7137043d, 0xe0c779be, 0x5f3c82ab, 0x9be58cb9, 0xb0d9adcc,
- 0x67d6953b, 0x10a191d4, 0x52bb9e96, 0xf6238f6b, 0xfcc5debf, 0x020d8a82,
- 0xe1ce15e4, 0x051509df, 0x1b7bc51e, 0xed485f6e, 0x6b3fed3d, 0xe707d998,
- 0x612dfba3, 0xff0a9fd4, 0xf263892e, 0xe3cf88b4, 0x04f0f748, 0x820d53b4,
- 0x6432e513, 0xd28b7661, 0x6893ee09, 0x44d5f31c, 0x8f16174e, 0x2c746068,
- 0xb90374a7, 0xf5e4189e, 0xde0fe63a, 0xcec33c16, 0x253b82b5, 0x40852f76,
- 0xb9df5192, 0xd8acff71, 0xcb673847, 0x77d15549, 0xffc621fb, 0x3e37056b,
- 0xfeffd008, 0x4076fa19, 0xe99fc557, 0x3c157d2c, 0x79d1d12d, 0x7f29a5bf,
- 0x08d79e38, 0x23a7bc6e, 0x0be78898, 0xbdd9ab47, 0xfe718f13, 0xec05cbd7,
- 0x60f7d43f, 0x87130f5c, 0x1649d37c, 0x71c3ebcc, 0xa67f9933, 0xd6508efd,
- 0xd0fd01e4, 0xd272953c, 0x34597e84, 0x34e7ccbf, 0x249fdd83, 0x5f79b518,
- 0x9ffb9461, 0xdfdbfe00, 0xc5a49f07, 0xdbb97da1, 0xf6369ec9, 0xf4191132,
- 0xf90932fb, 0xeb8366e8, 0x2fd06cbd, 0xe404490f, 0x237df3e3, 0x05d19fdf,
- 0x8fe445da, 0x97867782, 0x80a48841, 0x829126e5, 0x3a5d98fb, 0x2bffc7c2,
- 0x019ed7b5, 0x83f0487c, 0xf80189fd, 0x7baa6cae, 0xe20b9e67, 0x2ff62326,
- 0x1bb1f385, 0xbdef9d73, 0xce5c7407, 0xbc395bee, 0x69f7172c, 0xa025df77,
- 0xf4a41d9c, 0x4d373802, 0x3def78cd, 0x97dbbf3a, 0xd739e0a5, 0x34ca4f0c,
- 0xb19af738, 0x68bb744f, 0xd9d759bf, 0x364e706d, 0x7c48a065, 0x4edcbc2a,
- 0x334e309a, 0x9baee2a3, 0xa88a4e40, 0x547b843d, 0xf3fb828a, 0x46bd42ba,
- 0x65cbf7c0, 0x9d2ba99f, 0x33cad35f, 0xfc7411a6, 0xd00fda42, 0xfac35e5d,
- 0xdc11af95, 0x185baa90, 0x64f5147c, 0x2f011ae1, 0xfea268aa, 0x1b831c6f,
- 0x9b70a388, 0xb4fbe86a, 0x07de173e, 0xa7126bb8, 0x395679c1, 0x3fbe279d,
- 0x25cf12ba, 0xb47be90b, 0xb9ad3499, 0xabcde10b, 0x6f7c0811, 0xe33a3454,
- 0x6f00d191, 0xf686e49f, 0x16fe77f7, 0xd2664af3, 0xf851baf1, 0x3ce6c4b3,
- 0x2fddab8c, 0x93bef138, 0xee517dd9, 0x91dcb8da, 0xb9d87d81, 0xef9440b4,
- 0xfcea8c7e, 0x96164184, 0xb0b85d07, 0xd5d60ab2, 0x1864a72c, 0x98ce9f90,
- 0xa51f8ec0, 0xff51f6f8, 0xe58988f5, 0x47ca343d, 0xfd2acd4c, 0x07d2d939,
- 0x437671e5, 0x3999ea0e, 0xe7e78bc4, 0x8fe64abe, 0x096a5a1c, 0x4987e008,
- 0xde7874ce, 0xcf8cd4b8, 0x76625f5b, 0x3357b5a7, 0xd44f43c6, 0x87be0448,
- 0xe7d35c5a, 0x89e3a029, 0x139e12f5, 0xa848cf8b, 0xc4bee6cf, 0x358d64e2,
- 0x5a89ee0c, 0x9f72dfa6, 0xe82269b9, 0x956bb9ed, 0x1ead6573, 0xa315742b,
- 0xc2c67a9e, 0x5f5e92f4, 0x5154f5e9, 0x76d8aaf5, 0xb1899ee8, 0x2acf50ed,
- 0xc0ecaf16, 0x9b13973e, 0x4186a7a2, 0x6941495e, 0x812b99af, 0x89676f9f,
- 0x2da14dde, 0x76093e5f, 0xf78ec4b7, 0x9d199503, 0x3f8c094f, 0x19ffe808,
- 0x825f0dc1, 0xb0cd143c, 0xc73ffde0, 0x47201e81, 0xdcf1922b, 0x805030b3,
- 0x2ef25778, 0xf2d4aee7, 0x7dce72bb, 0x1e244f8b, 0xb22afdb5, 0xdfaa8f12,
- 0xf945fffb, 0x47738e96, 0x08b01083, 0xe7b43f50, 0xeeb023e7, 0xe42d79c4,
- 0x3b0ac1fe, 0xf7fbf5f2, 0x7c0a599d, 0x8101f33b, 0x644edf80, 0xc3d8155f,
- 0x0b8295b2, 0x1f73b3e2, 0xa5cfef60, 0xdfbcc3ef, 0x2fe32dff, 0x902ee7ca,
- 0x479ab283, 0x35ff60f7, 0xbfe00b82, 0xfd00aabf, 0x24592289, 0x10e6bed8,
- 0xbda823ee, 0x46a3fcc2, 0x39054c59, 0x76625b28, 0xc2b779c2, 0x1e7f0a4f,
- 0x9351dfe2, 0x1b90f738, 0x00e77be9, 0x14be0c48, 0x7b110ba7, 0x2e53fc0a,
- 0xf43b7e33, 0x1106e492, 0xb27f38b9, 0xfe1567ef, 0x46ff8113, 0xb1aff944,
- 0xfc04d726, 0xe0202278, 0xf02e7cb9, 0xefe7f02f, 0xb10cf895, 0x8ba8fda9,
- 0x0f9ea7f1, 0xe51ff1db, 0x0af3d03b, 0xa8fc2a7f, 0x46c3c3e7, 0x7de60d32,
- 0xae0b52f7, 0xcb6ab723, 0xce4c85b4, 0xb7273cf0, 0x9054beea, 0xcb2342eb,
- 0x5af050fb, 0x4279646a, 0x44f5e6ed, 0x675ba9a5, 0x479ba7e6, 0x2a3d8b37,
- 0x63cb220f, 0xde71d109, 0xe63cff5c, 0x775e9dd3, 0x6ff45ae8, 0x003e51b6,
- 0x93b7affc, 0x0243ee10, 0xeb8a8fa8, 0x1be60f45, 0x3759431a, 0x4aeff6aa,
- 0x57fcc4fe, 0xe2ef88ec, 0x3e40e68d, 0xf378bf7d, 0x8e782191, 0xdff988bd,
- 0xfd013af2, 0x0f372263, 0x8a3def81, 0x438f2c8d, 0x613c17ef, 0x96f0fb61,
- 0xe0e9d62d, 0xecb509b7, 0xbae2af5e, 0x2ab3259b, 0x45b0fbbe, 0xb9e1fa52,
- 0x0ce94c8a, 0xfcc355df, 0x294af7d4, 0xbf2d1bf9, 0xdc57fc67, 0x573fa120,
- 0x15a1bb5c, 0x0f8af3f2, 0x5bbf719a, 0xf3067b5e, 0x795f738f, 0xd63fdd89,
- 0xb2f26a20, 0xd543e5da, 0x51ce788a, 0x798a5f56, 0xe78eb41c, 0x3c75651d,
- 0xe607e8ff, 0x657fcceb, 0xa29966fb, 0xdfa6fe70, 0xb09ef039, 0xfc0eb5a6,
- 0xfbf6a54e, 0xe5db13f3, 0xe72dd53f, 0x9cd74ff9, 0x631fa820, 0x0a7d3fe7,
- 0x947b80ff, 0x27fcda2c, 0x1bf4cb52, 0xac56679d, 0x7e2213ef, 0x3e5f4bd7,
- 0x2dbbf90b, 0x167b3f1b, 0x8ff25de6, 0xbc859fcf, 0x09d00a0c, 0xbaf94a7e,
- 0x51df3177, 0x85a0ef79, 0xff7e83ef, 0x6d17cc3b, 0x06ecc0fd, 0x4fdbad68,
- 0xd1ff83a4, 0x549be1ba, 0x67bd03c8, 0x77c61e7b, 0xb73579ee, 0x6f15892b,
- 0x6ff025e3, 0xaaf913a0, 0xd635ba7a, 0xc8fe6237, 0xd0774a69, 0xb6bc9113,
- 0x2f9652ba, 0x6cf9e2e8, 0x07e763eb, 0xab5fcbb7, 0x2bbaf1bf, 0x33d63f41,
- 0x79a2e13f, 0x3d28076c, 0x1d04ef2f, 0xc57cf3d7, 0x37be6bba, 0xfc34ed8f,
- 0x2bebd283, 0xf01f368b, 0xcf39facb, 0xf56d0d3d, 0xb1e61dc9, 0x3f813a85,
- 0xd1b8ff25, 0x83c431e2, 0x117c6d1c, 0x7e8107f3, 0xd7d02ef9, 0xbc43a65f,
- 0xc614a4f8, 0xbb7844b8, 0x2b7bbf19, 0xca3efede, 0xfbabeb53, 0xf097bf31,
- 0x1256e03c, 0x4d7cb1f9, 0x5f2a031e, 0x6ff96763, 0x1f900e9c, 0x73e072e7,
- 0xf8c7079e, 0xeb8fc95a, 0x6c6e2f28, 0xe38b267c, 0xd2e8bcf1, 0x3cf21f35,
- 0x84dd28b3, 0x43af40d1, 0xa8779bdf, 0x7809c1e0, 0xfbcea518, 0x18879d8c,
- 0xd1d4fbc9, 0x7a09e80d, 0x49d7923c, 0xbf213deb, 0x1fbc202f, 0x75b88f2b,
- 0x6d17cb15, 0x93dfb495, 0xf2c4e946, 0xebc64740, 0xb9d036e4, 0xad8bcffc,
- 0xa9e287e3, 0xc34bbc5f, 0x5abe0a37, 0xefd6c7ce, 0x7f85e3d3, 0xd9ab7bee,
- 0x82fbfe82, 0xfbe1e39b, 0x2643fa82, 0xf18bdf82, 0xddf2957d, 0xb5b78f12,
- 0x7f3113ac, 0x11aeaab0, 0x7f5ebbf5, 0x1473f194, 0xe38b7cfd, 0x6b2ade99,
- 0x65a3f660, 0xa3603da3, 0xd8de5a70, 0xb65d7c82, 0xf20990fe, 0x6ed4f6b1,
- 0x03bcb132, 0x3f604726, 0xb7f9aa02, 0x0873bcbc, 0x9f7e73ea, 0x859c7e91,
- 0x60f29c7c, 0xd7ca71ec, 0x338cd19f, 0x3933ae5f, 0xef1f176d, 0x66e7a353,
- 0x1369f780, 0xad3ea3f3, 0xfac52713, 0x78b6e6be, 0xababef89, 0x3b50fc99,
- 0xd93af78a, 0xa24e3dd9, 0xb2fd1e23, 0x0fa3ec7b, 0xf780fdc2, 0x47984dd8,
- 0xe792b8b1, 0x3b97fc5d, 0xd8bde80d, 0xf981357e, 0xaafc052e, 0xd392f7f6,
- 0x939fc047, 0xd423bcd2, 0xfcca30e7, 0x240c5d4d, 0xb7bf3ea0, 0xfb0aea4f,
- 0x7b946253, 0xcdae3cc2, 0x7608cafc, 0xe2cfc9b1, 0x91fce4fb, 0xc9bcf0be,
- 0x4c9ddce8, 0x104d36e1, 0x6d9a10dc, 0x7e0cf7cf, 0xd1e0ce24, 0x39095fde,
- 0xb3beb0f8, 0x89fa036e, 0x49c84376, 0xa5bb10bb, 0xb8370d29, 0xa632e22e,
- 0xe63cea62, 0x8fe43faf, 0xe7df0beb, 0x5b750839, 0xa8db9fa1, 0x61216fb9,
- 0xff7751b4, 0x97d03902, 0xe71b1fda, 0x675e2557, 0x70a6ff67, 0x875ef19b,
- 0x12a441c4, 0xdd8577d8, 0xe3c4fe87, 0x5f7e0f0e, 0x21037f46, 0xc48921df,
- 0xc1f7d5bb, 0xf73571d0, 0x3571d04c, 0xb68f44f5, 0x78c93c9e, 0x49bd9634,
- 0x2898f3e6, 0x890f10da, 0x2fee0679, 0xa5fbf27b, 0x989de746, 0x6821dc42,
- 0x7986c6bf, 0x64bc54e3, 0x366c3af5, 0xfce9bced, 0x61227a34, 0x606cb350,
- 0x773cd4f3, 0xeb809712, 0xd39f68f7, 0x7fea6af9, 0xcdf6e789, 0xefa08c48,
- 0x844d716c, 0x06acffe3, 0xde8c4bdf, 0x4cc254a4, 0x4e93cc26, 0x483fbe13,
- 0xe3a0ebe0, 0x213bfa6b, 0xd7c6c07a, 0x9d3d21c2, 0x2f06efea, 0xc6b076e7,
- 0xfa0a3dea, 0x0577ab26, 0xa766fa26, 0xc3a39e09, 0x0bb05b69, 0x85cca7ea,
- 0xad08e4b9, 0xaf8cd50b, 0x2820aefa, 0x2cc37d37, 0x892c858f, 0x1cd53f47,
- 0x30cb6447, 0xc88a1ef8, 0x251830d2, 0x5c9fcfc0, 0x94140c8b, 0x35e51971,
- 0x3c305efa, 0x128730de, 0x289a0ea1, 0x9ef143fc, 0xaafc61cf, 0x86697deb,
- 0x793cb0a1, 0x946caee9, 0x62204bda, 0xeff4a868, 0x4b257bde, 0x9f7b81f9,
- 0x0ddfec88, 0xa95ab876, 0xdf0ec553, 0x47c7576b, 0xaa389eea, 0x5933abef,
- 0xbfd8785d, 0x424f5974, 0x0af04b1e, 0x7107d056, 0x3cf14bce, 0xeb84942c,
- 0x517d98bf, 0x4d7039e6, 0x11f8c4f3, 0xf70a9e2c, 0x47b3f68a, 0x7b46c7be,
- 0xd4a6d6bc, 0xf0bfb843, 0xbd47efd6, 0x1fb75a56, 0xa7500ddb, 0xe6e4ef65,
- 0x29123d89, 0x79d5ac56, 0x5f809769, 0xa066905b, 0x5ac4bceb, 0xc1a8dbbd,
- 0x3c1a13c3, 0xa63d1718, 0x3f63c3c3, 0x3c970f08, 0xa1e218fc, 0x7ca6ebb3,
- 0xe94ad031, 0x80c72537, 0x3a8d37f7, 0x0bf8c368, 0x1ed059fd, 0x3aab3871,
- 0xd9568ef8, 0x6e3850a7, 0x97f0a380, 0x57c29ef2, 0x1f4df11d, 0xdd94bce2,
- 0x9fe5a7eb, 0x0c67ab02, 0xf56b1bc0, 0xe0a5b31c, 0xeebbf1fa, 0xef02be29,
- 0x5f28e484, 0x386f9b13, 0x635c277c, 0x55bc73bd, 0x929daf15, 0xa4cc40b3,
- 0x5905cdf3, 0x4f5d1918, 0xd2d942ca, 0xc533ae9f, 0xec3cc063, 0x126fab1a,
- 0x1e98e38c, 0x48f5510e, 0x70df005d, 0xa38e8c41, 0x76d547c8, 0x2aaf8fb6,
- 0xb1160430, 0xe00160f3, 0x59a3f945, 0xc6611fc7, 0x90870d1f, 0x8782ca3f,
- 0x54347f18, 0xe7e78f8e, 0xae8fb06a, 0x40a1e126, 0x57d699f7, 0x28bd8cf2,
- 0x55c358df, 0x485f283d, 0xfcbcfaf2, 0x33af104b, 0xcf87d262, 0x4757594b,
- 0x9bdeadf4, 0xd820f0f9, 0xe033ee67, 0x37829879, 0x2b62dfa5, 0x661cb3cb,
- 0xfc03cdf7, 0xde6e8f95, 0xb8dbe403, 0xd798cff7, 0xc377d8e1, 0x31df784e,
- 0x15c85295, 0xdf7ab71d, 0xb7bfbc22, 0x4003ae9a, 0x0cb09026, 0x7c63bd76,
- 0xe089f930, 0x419efc03, 0x28438f80, 0x77f8eb2f, 0xf0ee5445, 0x56deda3b,
- 0x03c3bf76, 0x52079656, 0xc979156d, 0x7d94b0fc, 0xffb04d67, 0xc0625f2a,
- 0x0e5029fe, 0x097faf52, 0x1ab6abf6, 0x0a74f935, 0xa27e155d, 0xf70ad49a,
- 0xe8955c44, 0x9fe5ae5b, 0x0aa66b24, 0x23def29e, 0x4d9de27e, 0xaed46519,
- 0xbb06ef3b, 0xd0a7f94a, 0x53d3b2aa, 0xc0164b06, 0x287f845b, 0x0fa2c67f,
- 0x3037ef7d, 0xfe038c1e, 0x0b5d86c2, 0xe8773844, 0xe0b35d2c, 0x3fda3a1e,
- 0x362a4acb, 0x12b3f7d2, 0x64f50968, 0xebcaef5e, 0xe7d9583d, 0xa041b723,
- 0xb8f157cf, 0x9e562bec, 0x5e746037, 0xbc5cf70a, 0x9d9af1c2, 0xa0bb4566,
- 0xa291adc8, 0x8db5ce0f, 0x333b7cfc, 0xba00699c, 0x0c6c7229, 0x6a76421b,
- 0x2e8d32b4, 0xbc39e403, 0xe179f7e5, 0xbd23b0bc, 0xec25f573, 0xf3fd3fbb,
- 0x1f9f3e46, 0xdd7f5fed, 0x46e0fbee, 0x5c696fc0, 0xd03723f3, 0x9f25d97a,
- 0x91769c63, 0xf50aecb5, 0xd4be9e79, 0xf3adffcf, 0x1fe01c27, 0x9e6d7eb6,
- 0xfecfcb14, 0xdffccaca, 0xf8e9febd, 0x2177e29e, 0xab2740a9, 0x63342fbf,
- 0x55d57e89, 0x8e80f2a8, 0xec0931b2, 0x99c595ab, 0x2bbee9c6, 0xaec7ce54,
- 0x5fb8b10a, 0xe833e816, 0xdd8335df, 0xf335fe57, 0x7fe8e28f, 0xc794ee70,
- 0x32dec9cf, 0x69db16fa, 0x3b08b7bf, 0xa84acd6f, 0x93ef8468, 0xcf033988,
- 0xf688732b, 0xe4acafbe, 0x8f3809ea, 0x479c0c84, 0xbdae9c6e, 0x40346cab,
- 0xcc0c9f7b, 0x2a23cc57, 0x23ce8cbf, 0x78c10fab, 0x29701916, 0x194d85e6,
- 0xb79ff948, 0xeccc0e7f, 0x426711b7, 0x764fef54, 0xa09de2dd, 0xddaa5bf1,
- 0xfedfc7a0, 0x5623bc4e, 0x3675c5fe, 0xfd7b9fc6, 0x03e42f5e, 0xde3cf1e8,
- 0xbbb12c25, 0x8f5be3da, 0x15fe3d4f, 0x98f1eabc, 0x427b91f3, 0xe93c0c52,
- 0xbf3d12f1, 0xba00ac0c, 0xd1140de4, 0xd074297e, 0xcbf689e3, 0x5f6f7e87,
- 0xf9c1fb42, 0x08c2b8ab, 0x43372f76, 0x457fdc20, 0xc22f36ff, 0x257fcc1f,
- 0x3748ed5d, 0xe3db5e3d, 0x979f93d1, 0x1edf5d1a, 0x37e617c0, 0x3e400fb9,
- 0xc24da359, 0x1c684971, 0xbc7be751, 0x04e4f102, 0xbbef1e1c, 0xaa40c71b,
- 0x5762aef8, 0xff2888e2, 0xeb5afb8c, 0x2705e6e7, 0x39ff029e, 0x04b7c12b,
- 0xcc44a6e2, 0x8a3a3cc0, 0x3e5ac3bf, 0xcd6bfce3, 0xf8a13e40, 0x0c43b6d4,
- 0x664fde07, 0x5d4e79ed, 0xf4cf8ebb, 0xecf857eb, 0xa6307815, 0x3e14be3d,
- 0x7ee3689b, 0x13d27779, 0x5b21e4fc, 0xde802446, 0x98a4c126, 0x075188f1,
- 0x9c3811bd, 0x051f915f, 0x773c8be2, 0xf427f9f6, 0x8eb51357, 0x1cc0f8aa,
- 0x2d9b77d1, 0xf852fe86, 0xb74e4ae3, 0x13bc892b, 0x12574be2, 0x7d9117e3,
- 0xfd744640, 0xde3c6cb3, 0x80f483d2, 0xbab2ee75, 0xaf997ed8, 0xea6eb233,
- 0xb3dd0256, 0x71d9f8f9, 0x834efc36, 0x112d8d84, 0xbde267fc, 0x2929b235,
- 0xf7890f3a, 0x8415e927, 0xf03371f9, 0x178a5cbe, 0x9d1ac172, 0x609b42c7,
- 0xf85c7bc4, 0xc6d74e3c, 0xb6df90c9, 0x003df44e, 0xf6116ceb, 0x19f5c10d,
- 0xeec1fd43, 0x6f3fdbe9, 0xed0655d8, 0xf6215fb4, 0x2f9ff3e3, 0x7843b8b2,
- 0x3ab039bb, 0x94ff63a3, 0x07da358a, 0xe1b22e45, 0x41cbc8bb, 0xcc22c2ce,
- 0x53cfc83b, 0xc2299c76, 0x3887a0fd, 0xe1465c97, 0x113b3eed, 0xa973f9f3,
- 0x7a7e81ba, 0xb7f3d7be, 0x90279f9e, 0x4f784cf0, 0x363fc7cf, 0xdff1400f,
- 0x90737c22, 0xeeca8df2, 0xf942fc29, 0x5d1b79e7, 0x6388db77, 0xfdbb814f,
- 0x53cf88ce, 0xfe29eec1, 0xf10fd479, 0x3afd00bc, 0xff15d3f2, 0xf7cd937c,
- 0xc233f412, 0x99fbe87a, 0xf8065d03, 0xcd90fe7e, 0x573c32f3, 0xed8b96fc,
- 0x232ec837, 0x3be74819, 0xcea1d393, 0x593ef040, 0xf6808179, 0x961276ec,
- 0x2bdbbc60, 0x76becd24, 0xc9fc25a6, 0x587e70fd, 0x99ed0039, 0x14fabe0f,
- 0x8f967df1, 0x13bfc55c, 0x0fee1819, 0x163bbefb, 0x43c7df6a, 0xbde8acc2,
- 0xbed09f9d, 0x6e0092dd, 0x877c0a73, 0xfb6b205b, 0xd657c7eb, 0x7fab87a1,
- 0x63df9caf, 0xbb22f704, 0x9fc2fe55, 0x8d8fcc6c, 0x7e2df7cc, 0x37c5018f,
- 0xc1b3d5d8, 0xc50f024b, 0xf4a55fe0, 0x8c7b25c5, 0xe6f5a3c3, 0xb1e9e6ed,
- 0xc65117ee, 0x833df051, 0xfcf82934, 0x65ff1636, 0xc01c58fb, 0x734844f0,
- 0x7d94af4e, 0xdfd013c3, 0xa0275beb, 0x97525d7f, 0xf1a59863, 0xb83ed9f3,
- 0xf70f9f9d, 0xfaff405d, 0xafcfcc9d, 0x42fdc4ab, 0xf7db3d49, 0x5cef82ac,
- 0x0c89f3ba, 0xb23fff42, 0xa9bc859f, 0x9047b852, 0x53e087b5, 0xacd53ef5,
- 0x897db27f, 0xf611b969, 0xc934bea3, 0x5abfeb4d, 0xf747155e, 0xc419554d,
- 0x29bee842, 0x27cb57f1, 0xb54d18ae, 0x20479273, 0xb2af5889, 0xfefce98d,
- 0xcb57f939, 0xe36596aa, 0xaede2bbe, 0x2476cfda, 0x2e6de71f, 0xfb4763c4,
- 0xbc12c7d8, 0x3c5576c9, 0xb3ff4f42, 0xe004ae71, 0x7f7ce5bf, 0x59c2f57d,
- 0x0cb06fb8, 0xf90e9f38, 0xee9cd961, 0xb38f3b2e, 0xdcf7d95a, 0x00f4d6e5,
- 0x456ba9e8, 0xd9e60b9f, 0xfef9c6f6, 0x6b7e4710, 0xb7dc11e0, 0x8ebdf905,
- 0x5e45fcfb, 0x65fabe75, 0x5f67e676, 0x03a3497d, 0x8cd71df6, 0x677e0bfc,
- 0xeec8da7e, 0x6d196b4d, 0x4fb9f8d2, 0x032ef2da, 0xd1494af8, 0xce7e8227,
- 0x20ebb11e, 0xec8efbd8, 0x780ed444, 0xe403b004, 0x3c54fefc, 0xeddfaa07,
- 0x0b65d880, 0x74fd6eff, 0x9dea637d, 0xf0dd2cb4, 0xb7ec0717, 0xcfccedb2,
- 0xc26c6d3b, 0x5e4a747b, 0x079ef115, 0x6dea6e3a, 0x9fae5f10, 0x1b10f595,
- 0x076d4e26, 0x43afbf09, 0x8caf07f1, 0x2edc0393, 0xbc4d712a, 0xbd5c63df,
- 0xda38b1e8, 0xf7a785fb, 0x0f9e3e66, 0x1b922174, 0xd92325dd, 0x3f227e85,
- 0x5dbfa1e7, 0x0ef0af70, 0xfebd795e, 0x40af1bf3, 0x4276a266, 0xd7c93f00,
- 0x98ef0585, 0xb7fc563e, 0xe36b5f71, 0x527f7a97, 0x83e33bb1, 0x20f49743,
- 0x8dd71780, 0x5ec21df8, 0xe94de623, 0xf0bccdfd, 0xcafc0ec4, 0x363f9147,
- 0x02b1f7d6, 0x19d9873d, 0x7fd7965f, 0x94aef78e, 0xb834d091, 0x5eaca6ff,
- 0xf7c88674, 0x6f25e9e9, 0x6ac1dfc3, 0xe02e4a0b, 0xeee0b6df, 0x6f5021b8,
- 0x561e3110, 0x65f64efe, 0x41ad67c0, 0x291fef09, 0x01cc7edf, 0xf3b140fa,
- 0x2f7641ad, 0x08f05b49, 0xb6e0573e, 0x065f2436, 0x818367f6, 0xed773fed,
- 0xfa0ad6f9, 0x67f3f5e1, 0xabdf7193, 0xff9d69d8, 0x7377c4ab, 0xbe2462ed,
- 0x896ff6ab, 0xf2007d98, 0x2412f2a7, 0x7f510a22, 0xfe9d9db5, 0x93b12c88,
- 0x823af6f6, 0x8231e27f, 0x77edeb9c, 0xfb3adf04, 0xfb9d88fd, 0x30c8bd8f,
- 0xe1afc7b8, 0xfc7cf27c, 0x756833ee, 0x0cf8c22e, 0x76da4ff3, 0x14d8fa7d,
- 0x644fbe78, 0x179ffddf, 0xd8dfef91, 0xb377bf31, 0x2af78d4d, 0x6eb9d7a4,
- 0xd1b75a67, 0xc776e7fe, 0xd1b578b3, 0xbbfa997d, 0x00ff6883, 0x3ba857c7,
- 0xbb92f73b, 0x3f3b7dc3, 0xb70cffda, 0x45eaffbb, 0xb8d2f790, 0xc35044f0,
- 0x990e6bfd, 0xb30c5f40, 0x7a625f7b, 0x7a0acea0, 0x7be32640, 0x516e3a10,
- 0xfc0f193c, 0x4e24ae15, 0x757bc3c8, 0x7400c1af, 0x0336b119, 0xf1d664f3,
- 0x7579c173, 0x950ca6d5, 0xcfc7997e, 0x724a4e95, 0xf9ea927a, 0x03d30770,
- 0x3f177727, 0x03f2fa87, 0xc317e933, 0x983b263e, 0x9264dbbd, 0x7e87aca7,
- 0xefb80d87, 0xeb67b5d8, 0x6e0fb81e, 0x50d741de, 0x41a737b0, 0x86bc281e,
- 0x20aaeb7d, 0x23e1b6cf, 0xbf5416b0, 0x0d1029af, 0xc46ddc74, 0x0764e2c5,
- 0x8dffb80c, 0x278917c4, 0x29f9d619, 0xf6dbbfd7, 0x50e7341a, 0xa43df8db,
- 0x39d9da1f, 0x8b3b7ed4, 0x3bdc6d53, 0x944ef93e, 0xd001df43, 0x9b47e5ff,
- 0x68ae1cab, 0x97f14d5c, 0x38d81cc6, 0xe7fd3065, 0x13831698, 0xb03aedc8,
- 0xbaf5845a, 0x25db524e, 0x13fe7690, 0x1a89f785, 0x0616b6de, 0x0de3ce8f,
- 0xff055390, 0x3c3f02d4, 0x35b7d688, 0xbf209319, 0xb2bfc14a, 0x577c650e,
- 0xb2acf11d, 0x367928a1, 0x577c4f7e, 0xb87cf7b9, 0xa0f72893, 0xb6ce5f23,
- 0x3f195a7b, 0x3f50e9c8, 0xfd1e3bb9, 0x9edc4d92, 0xde82b491, 0x4e853f80,
- 0x7f660e09, 0x3474f994, 0xbfa73c7e, 0xbe50fe52, 0x64b9275e, 0x1f7e1be4,
- 0xc50e4ba0, 0xae3c81f5, 0x77f83e86, 0xae79545a, 0x47c00ef1, 0xd47e368b,
- 0xc0306cd0, 0xdb6558f7, 0x66bc4485, 0x6dfe93a4, 0x758ccf84, 0x070d7fc8,
- 0x7171ca09, 0xbe2c5ded, 0xf83d4247, 0x5e7858bd, 0xcfc3f20d, 0xb409bbad,
- 0xb55c131c, 0x37e207b8, 0x8ab900e4, 0x0dca89e2, 0x26d51594, 0xf779d7e0,
- 0x3f2e72b0, 0xd2b79dff, 0x5859f287, 0xfafbf2c3, 0x7cd8323a, 0x4312bf38,
- 0xfbc8777c, 0x7fdb8e78, 0x022fde65, 0xa9fad2df, 0x611bc7fa, 0x975fca5c,
- 0xdeee203a, 0x3053e8f0, 0x4f5f855d, 0x4e1091ad, 0x7cf6bc51, 0xd74e72fc,
- 0x7e300f57, 0x1a46b31f, 0x8d31f70f, 0xe2138991, 0xacd6dbc5, 0x6f7f4115,
- 0x60ce7e03, 0xfd760e72, 0xac87eee4, 0x773b04bf, 0x2e2040c8, 0x8a44c9bd,
- 0x62e4a836, 0x34d7aad7, 0x5b5c5bf2, 0xdfe30539, 0xe80249cd, 0x156e4579,
- 0xb9326fbc, 0x5ffca327, 0x09ff93ab, 0x0e39fdec, 0xb9c79746, 0x893e3ffc,
- 0x947d3fca, 0x005126b8, 0xb14c9b38, 0xf69ae9ef, 0xa22ff923, 0xd3b68f57,
- 0x6c1cd3ab, 0x43e8ef5f, 0xe6bb2fc7, 0x23ebee2c, 0xf37ce3f3, 0x6f8504f8,
- 0x7fc00432, 0x5f60a535, 0x2bc517c0, 0xaffa33f0, 0x32736fa0, 0xf6a1bef1,
- 0x3948b8fc, 0x6dc8d397, 0xf229af54, 0x7a022beb, 0x58a84d67, 0x72767e0c,
- 0x7a7c8cbe, 0x4ef5f04a, 0x14ed76a2, 0xbd0c73c8, 0xf4c1d130, 0xa7c939c8,
- 0xfdbcafb9, 0xe077483c, 0x63ba22eb, 0x1a917583, 0x51f409c1, 0x6c355dda,
- 0xc394b15f, 0xf52b9e53, 0x2ff78d1f, 0x9783c5da, 0x333d983a, 0x7fb056c1,
- 0x2233d980, 0x20b9478c, 0x83bbab86, 0x76a3cdbc, 0x1d9556ec, 0x2355253b,
- 0xf8782abf, 0x73f7e735, 0x57dd6c89, 0x829679f1, 0x673aa7ef, 0xa3041ba2,
- 0x145ae4c0, 0x008bbc98, 0xb1eed4ff, 0xafef9193, 0xf3f7cd89, 0xfe42afd7,
- 0xc4e49c4c, 0x371e48ef, 0x83892dba, 0x00e3e962, 0xfed6bb96, 0xc059f706,
- 0x1df720c7, 0xc81141c9, 0xffc18901, 0x2affca01, 0x407c29fa, 0x8745e2f9,
- 0xf9e84f4a, 0x53df3942, 0x7749b2f0, 0xeb8e783e, 0xba5e46f9, 0x5153c83a,
- 0xe9a3f3d6, 0xce8ed2dc, 0x473a306f, 0xade80be5, 0x81df89e8, 0x2c74a59c,
- 0x9c12fd67, 0x8faa9f38, 0x485e6167, 0xaa273f35, 0xf329e3e3, 0x42f5c03e,
- 0x353ce747, 0x1c5fdf56, 0xd748f3ba, 0xe47f28a0, 0xc176bf71, 0xb39e335a,
- 0x9e4c206f, 0x01f15de5, 0x4e9e77f5, 0x294c7523, 0x3e808faa, 0x3856891f,
- 0x42d77504, 0xc74be913, 0xb051973d, 0x7e6df20b, 0x0fe724d6, 0x60d8eba6,
- 0x835ea792, 0x64f701fb, 0xdf393f80, 0x6f7884e0, 0x4029c7a2, 0x0343023c,
- 0xd8fb8720, 0xb8fbc338, 0xab7dc32f, 0xf41c3dcb, 0x2f4e69c1, 0x1e0abe85,
- 0x1d77b23a, 0x025fb5d1, 0xede3a73f, 0x26f23d7a, 0x38e79b97, 0x47ae2f1e,
- 0xc9e41164, 0x448b7c41, 0xd3367f98, 0x923d1183, 0xd01cf04d, 0x9e55c7c1,
- 0x509ff52b, 0x5212388f, 0x74647a54, 0x423d4c73, 0x3fe5317f, 0xf41ccd65,
- 0xd8c1c967, 0x027a6cfe, 0x6029c7b3, 0x14bf6947, 0xd33dfd99, 0x503edcd3,
- 0xc57cc48e, 0x8c6635ea, 0xc87a2be3, 0x878c9531, 0x00eacfbf, 0xa6bd0bbb,
- 0x095e0efa, 0x2669b3e7, 0x9f179c17, 0xf748c292, 0x5cc37453, 0x15e1fc8d,
- 0xf431de80, 0x85f88111, 0x2c9ed7fc, 0x51062efe, 0x11e4164e, 0xd6bba3b4,
- 0x2abe428e, 0x8014cfca, 0x136b8b6f, 0x9a4f6805, 0xbe8034e0, 0x6a31d652,
- 0x49fc88a1, 0x824460e5, 0xe4a31e8a, 0xd5f0110a, 0x2697d93b, 0xd6fdd225,
- 0x4cfd57af, 0xd0f1bf1d, 0x68b48afa, 0x1fd686fc, 0x7ceb75b4, 0x213726fc,
- 0x3fe420f0, 0xe4f0eadc, 0x5635b8c0, 0x59942e6f, 0xce302b5d, 0x88bcd9db,
- 0xe52fcb1f, 0x0e444e3c, 0xcecb8bb4, 0x5c6175ac, 0xa7cc1a76, 0xa7f1fbac,
- 0x73de1c00, 0x66efd311, 0xf5c2e8f3, 0x2088f902, 0x2b78ba3d, 0x28978844,
- 0x384ee77a, 0xf6a14594, 0xa1ae7008, 0x2de81bc8, 0x3c95a7f0, 0xd95b8808,
- 0x401f6e31, 0xc27a823e, 0x5a3ea8b0, 0x79886f91, 0x04c2f15f, 0x9faa4fdb,
- 0x9beff049, 0x477ca97f, 0x2d3ca228, 0xebe9504c, 0xa70ff3c7, 0x7608f3b2,
- 0x7cdddfaf, 0xb916e78c, 0x4ba034ff, 0xa1867ef4, 0xf90c9366, 0x5c43c4a6,
- 0xb1fe554e, 0x76421410, 0x56fd63c8, 0x874a1e20, 0x2c456fb6, 0xde3ffb9f,
- 0xcfe01949, 0xd4dc1837, 0x0bfc8233, 0x6f770794, 0xd4a7df82, 0x73127bf1,
- 0x091e6d1a, 0x1c421de2, 0xa3da8eff, 0x1d18e73d, 0xdb4f5f4e, 0xf8cd0717,
- 0x72dafdb7, 0xe0afbf94, 0x1598efc6, 0xe7790efc, 0xd79881f1, 0x8376ac69,
- 0x30b6ad9c, 0x2c2dabf8, 0xa2dab76e, 0x004ae7bc, 0x79d1ddbb, 0x1ec2f67b,
- 0xe253ff18, 0x90e1d98d, 0x0cc9f808, 0xc92c0cbb, 0x0c678d8d, 0x72b75c13,
- 0xf1c75f0e, 0x46ef69bf, 0xd679ec11, 0xb0c5ea84, 0xf763d9ef, 0x6bfa00bd,
- 0xdfd6b66c, 0xf3f0211b, 0xf704c9e1, 0x249c8a4b, 0xe09d9337, 0x6c1e24da,
- 0x1a0a80f6, 0x13b3d27b, 0x5e0995f6, 0x553c0022, 0x8006cffe, 0x8478ba4b,
- 0xdfc0ba6b, 0xfb7fe5eb, 0xb4d9c390, 0x7200bc77, 0x8269a5df, 0x9ed41ae0,
- 0xfec257cf, 0x53cb047b, 0xfb2afa01, 0x5e2fdec2, 0xa5f0013a, 0xfae26ff4,
- 0x2f9f0afc, 0x74c64217, 0x7718213d, 0x2340f4cc, 0xaa35495c, 0xb9346e48,
- 0x4799eb54, 0x668f5e10, 0xedd1d719, 0xca072fa0, 0x1c44b663, 0x10c9ec77,
- 0xad74b7e6, 0x43f69020, 0x401d357a, 0x4557aa3f, 0xdcf40093, 0x9c0df7b4,
- 0x5da6cf6f, 0xb5f2e4ac, 0xca05fb91, 0x98d98ebc, 0xcfc63cdd, 0x334eaba9,
- 0xc12079bb, 0xca4bf987, 0x7c72aa3a, 0xfe141569, 0x19cbc84a, 0xce5e71d1,
- 0xb2930491, 0xd608ffdf, 0x79bd3e57, 0x3ea0f00f, 0xefba907e, 0x7523d230,
- 0xaf96db21, 0x0040b7dc, 0x4672b17d, 0xa281f8ec, 0xf8f25637, 0xe5ff2aab,
- 0x4f4f5a94, 0x66b24829, 0xf292f4aa, 0xfcd153de, 0xff3c4d97, 0x7bcd03e5,
- 0x805a9783, 0x79b2ee9f, 0xe573c0ce, 0xe3ad0bef, 0xd947b77f, 0xbaf82acf,
- 0x80fcc9c2, 0x1fd70903, 0xc0247383, 0xf1f29393, 0x3cec4b3a, 0x069dcbf2,
- 0x7e3077ee, 0x5f8c4d21, 0xff6a1d60, 0xb001bfeb, 0x00d7432f, 0x0000d743,
- 0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0xc9332666,
- 0xe4cc9924, 0x40275e49, 0x21c40a30, 0xeb141021, 0xef0c0124, 0x02415041,
- 0x8042120c, 0x2a941324, 0x8065bd6d, 0x8d520318, 0x8bd4b45e, 0xd7a5783a,
- 0x2941b622, 0x84ec1a86, 0x3a0bc157, 0x94b62a28, 0xaa54141b, 0xa5ac4090,
- 0xd7f97b96, 0x661f7b5a, 0x962264ce, 0xbfefbf62, 0x767e9fff, 0x67d9cfb3,
- 0xfbd7b59f, 0x649ecfb1, 0x1258c4ab, 0xdd3b3763, 0xd8c67a65, 0xc1b758be,
- 0x88d8c45a, 0x596edf62, 0xb9786c61, 0xda1eb777, 0x3bbf564c, 0x94061136,
- 0x6826c733, 0x3dac1dec, 0xa384da0e, 0xb838ce1d, 0xa36adfdf, 0xacfa6e79,
- 0x8c2db98b, 0xab98950d, 0x97631065, 0x60d6eff0, 0x31d56a9b, 0x0627f306,
- 0xe306254a, 0x6cb8c436, 0xe961bef8, 0x4001b2f5, 0xf1d66449, 0x03631fac,
- 0x2b8d0aad, 0x96ee762c, 0xa7563de1, 0x8b79c64b, 0x9ef4ac63, 0x6a771cc6,
- 0x1d3e7f3d, 0x4e89679f, 0x37c02269, 0x5b18bfec, 0xfb6ddd03, 0x1065254b,
- 0x6f1467be, 0xc0b67319, 0x056057f8, 0x115970a1, 0x9f7c249e, 0x39ebef44,
- 0x4acf3bbf, 0x129ceaf0, 0xa8fc324c, 0xe860c7c5, 0x32f5a5f0, 0x02c89fc2,
- 0x6d000312, 0x2312d6d5, 0xc6bd37bc, 0xfe61b921, 0xf95c629b, 0x0e635cf8,
- 0x6d0a1c5c, 0x0ab7ce89, 0xe7103b9e, 0xf981653c, 0xf668bf17, 0xfa31349e,
- 0xd5ff04bb, 0xfa6824b6, 0xef34d69e, 0x7f60bcc9, 0x0d23fe31, 0x4ccfdbfe,
- 0x3563186c, 0x407b16fc, 0xef8cdf76, 0x3c7535a9, 0x75fa173a, 0xc8caf8bf,
- 0xae0a4960, 0x6578e017, 0x3dcc417f, 0xa77ae096, 0x9977a4f5, 0xbd27a935,
- 0xde824a87, 0x4ade8163, 0xb29f7a4f, 0x3b7a0824, 0xfac107db, 0xc24c5de2,
- 0x135f01e7, 0x85dc3d39, 0xb788c1ae, 0x380332a5, 0x587a455e, 0x538f4cae,
- 0xa71fce16, 0x2a1e9c2c, 0x38c6e61d, 0x75d2b4ef, 0x96f5ef46, 0xbebc3cb2,
- 0xdcae8276, 0x16cf8117, 0xee342d59, 0x05fcf1aa, 0x99e287d3, 0xfb6dfdb5,
- 0xc1efa10f, 0xf784cb7f, 0xc0378845, 0x583f5c7b, 0xf84ebff7, 0x53f91928,
- 0x203aea67, 0xdb6a3e01, 0x25864564, 0x9c954c0c, 0x5b190b27, 0x89cda0f5,
- 0x8b5cf07c, 0xf18288e4, 0x6b14c9cc, 0x22564332, 0x75fd9d62, 0x11bb3e7c,
- 0x8360b85a, 0xa334de71, 0xcef2136f, 0x8c33c01e, 0x380824f3, 0x001fe01a,
- 0x0555a747, 0x0df749cc, 0x559ff2ec, 0xf851fb82, 0x6a4b982f, 0x80976f69,
- 0x998aab70, 0xef7000db, 0x1f89936e, 0xf68c6b9f, 0x2ffcc145, 0x607f396d,
- 0x3ffbf426, 0xc165c3a8, 0x27eb04df, 0x53a8f831, 0x1cad04ba, 0xc3d3ca67,
- 0xed1c877d, 0x4b7c6190, 0x8b3e5c74, 0x3764ac67, 0x955b3f31, 0x7bc0f30b,
- 0xd347b556, 0x82e556fa, 0x1f10e47c, 0xd9f8863c, 0x69646b13, 0xe41bbd70,
- 0x670dc706, 0xcc8cef1d, 0xbba9d209, 0xbbd9cbf5, 0x189efd60, 0x2627af3e,
- 0xde00c7cb, 0x07175dce, 0x5b8f1f20, 0xca35cf36, 0xd924d8ce, 0xafe91ebd,
- 0xde66f73e, 0x6f8871c7, 0x5e0832c6, 0x841c9fa2, 0xacde32ef, 0xac72bf1c,
- 0xc9d1d69e, 0xeeb81da2, 0x2193a316, 0x39c7bc9d, 0xad78ab7f, 0xd9d1bc13,
- 0x0dd47456, 0x68ee7beb, 0xef9f0386, 0xeb36ed6c, 0xe2cb7de0, 0x75c0bfdd,
- 0x715d99c9, 0xcf8841ae, 0x063bebee, 0x097a1e91, 0xfc1f77af, 0x741ee6d8,
- 0x86dbeb55, 0x7d695fcf, 0x49a5bd1e, 0x3fc9ef8a, 0xb5207ce1, 0xca55ffb5,
- 0xa8613927, 0xcc59bcb7, 0xddd60ab7, 0x93487838, 0xc69e848c, 0xc64f9414,
- 0x0c9fac2a, 0x2abbd20c, 0xf107b5de, 0x8cd7caac, 0x843ed778, 0x5e93df0b,
- 0x8fdceb40, 0xf343fcfd, 0xabba0d0a, 0xc8e1e75a, 0xfe13f4eb, 0x6a7ac56b,
- 0x0cbf164d, 0x866db3f0, 0xf9543a2f, 0x5e13dbec, 0x0e31c7a0, 0x1ba8e3af,
- 0x8b7bf9e9, 0x43e21563, 0x62bab01f, 0xf8e3fe09, 0x373c563e, 0x21bbd715,
- 0x858f69c6, 0x30579bf1, 0xb4520fce, 0xdc5879e3, 0x68b63dd6, 0xf15593d4,
- 0xdf3853ee, 0xb3f3ba0d, 0x02c7685d, 0xdc3ddd2e, 0xd7867c0e, 0x7adddd61,
- 0xc65ea382, 0xfd62aff9, 0x71f322e7, 0xd9fc3a0f, 0x54e7a21a, 0xf4148cfc,
- 0x41f8891d, 0xffa5dc85, 0xc414c3a2, 0x3d4a048f, 0x3e73d6dd, 0x10b23ac6,
- 0x9f1df6de, 0xf980e80e, 0x74f8deea, 0xdd6fca36, 0xb888a26f, 0x7d737ea3,
- 0xd9f1f23c, 0xc5bd3612, 0x7e9f53d2, 0xa5debcb1, 0x1ffae607, 0xcbd25f6b,
- 0x44602c35, 0xb2db5d3b, 0xd10fa5c4, 0xe93100a7, 0xc08683dd, 0x60ff9c04,
- 0x0056cc91, 0x863b75df, 0x7a08b0a7, 0x5adf6d5a, 0xb9955cce, 0xf512fd8c,
- 0x8ed7f21c, 0x9784f1a1, 0xe3e91b36, 0x9707f1f0, 0x1946bb57, 0xe0ef9f7a,
- 0x1f74f310, 0xcc213f3c, 0x8131b90f, 0xa23195db, 0x44e94505, 0x8f6ccf38,
- 0xd2e179f5, 0xe2f78299, 0xcce9e018, 0xbd0b77b6, 0x58672fc0, 0x51d7bee0,
- 0x30b4be7e, 0x0c267bf4, 0x4570af79, 0x6ede506c, 0xbf6be629, 0x7143b5e5,
- 0xb09f8c0a, 0x37a27775, 0x30b77f04, 0xf99797fd, 0xcbdf0737, 0x1df4c7d7,
- 0xec1e9003, 0x0ac9d3f5, 0xec7613b4, 0xa07ce44d, 0x4bce90e8, 0x15fade85,
- 0x9c111a5e, 0x3ab2c26f, 0x60c2a8d7, 0x9982f6bf, 0xfafb42f9, 0x5f4d1180,
- 0x5d0b05ed, 0x26c427b7, 0xc3e8fe92, 0xf8fea0fa, 0xbf0b78b6, 0xe0ede2ae,
- 0x6859d390, 0x239acfbf, 0x62edc9f3, 0x4463b75c, 0x1347fa0a, 0xd6fefe8c,
- 0xf318e308, 0x75f0b8d1, 0xeddcb9bd, 0x3bdb951a, 0xcc8de37c, 0x1cafc91d,
- 0x9afdc09f, 0x7999876e, 0xdbefae41, 0x743b2068, 0xd307e2e8, 0x9f7e810a,
- 0x5758306e, 0x9fab3e02, 0xaff19dd9, 0x487abf70, 0xfe825594, 0x3fbf8aa7,
- 0x6782f1f2, 0xfbae1764, 0x25f70dd3, 0x73f683cf, 0x801ac7e0, 0x0346c163,
- 0xf8deaf5d, 0x5a7eba7d, 0x6782e9f0, 0x9ea20692, 0x4d67b43f, 0xfab3ae32,
- 0x13be1fbf, 0xa356c5f5, 0x6810e075, 0xae48b66b, 0xb1722151, 0xa6b305e8,
- 0xaac755bf, 0xbaea1d71, 0x7cbee499, 0xbc78015f, 0xba0fdc09, 0x8f65ff6a,
- 0x7f017fd6, 0xfdc09bc5, 0x61534995, 0xdd4575dd, 0xdeee27e4, 0xfc764d17,
- 0xfc9916b7, 0xbf90ff01, 0xd08de7fc, 0xbd6ffb2f, 0xc1087c83, 0x5e85a3e7,
- 0xf48f2c66, 0xf7899550, 0xc9e876cb, 0x958b289f, 0xd07edf09, 0x08c8a313,
- 0x61a32d39, 0xe7d4f7dc, 0x46eb91e4, 0xf1d1b8c0, 0xe27e8606, 0x268bfcf7,
- 0xb7efd030, 0xd47fd05e, 0x529eb211, 0x23a3d4e6, 0x9a0cc252, 0xe3a3abeb,
- 0x08ff479e, 0x1ea3d326, 0xef69332f, 0xee3fee8f, 0xd1bbda34, 0x5575ed56,
- 0x39439e7e, 0x83941818, 0xf4fefbdd, 0x675878c4, 0xfb9941d5, 0x33d05763,
- 0x72bae16f, 0x566fde91, 0x0ee7816c, 0xba1cec09, 0x1a4369f8, 0xc4b157f2,
- 0xd3ff4256, 0x91e5518b, 0xd54622e4, 0x9ce80c37, 0x44f3a417, 0x7dcbc2c7,
- 0xc5c98b14, 0x11f72e4b, 0xefaf6ffe, 0xef2e59be, 0xfbd2304e, 0xb861f5c3,
- 0xfa577cfc, 0xbd90c270, 0x6a58de59, 0x17ed8e7f, 0x099eb95b, 0xfae18fd7,
- 0x1c2b854f, 0xb20bdade, 0x4f8def46, 0x505c6850, 0xfee919ff, 0x3eb38c35,
- 0x6710884b, 0x7c267d81, 0x29e98779, 0xe1ff03be, 0x641b8e0c, 0x0025ec51,
- 0x6fb58352, 0x25f5ea0c, 0x5e177716, 0x86e97ecf, 0x0c17e851, 0x43acd2dc,
- 0x7129d1fd, 0x88366d7a, 0x8283fb16, 0x045fd071, 0xfa131cdf, 0x53a0e200,
- 0x2efb6816, 0xc31f632b, 0xcc4ca2fa, 0xbb202e6b, 0x041435ef, 0x7e023fe7,
- 0x8d99c60c, 0x9fc78c25, 0xebffdc09, 0xace8a79b, 0xcbc3ff30, 0xc093cead,
- 0xa797abcf, 0xf2f2cb52, 0xfbbf4874, 0x6fd06e04, 0xbbbce7c4, 0xa75d69a2,
- 0xca3e5724, 0xbe02c3e5, 0x62dc7a70, 0x35dbf953, 0x9a2fd420, 0x5f591a5f,
- 0xd3d36f5f, 0x66a792f8, 0x71dfa164, 0x2ceefdaa, 0x00a7a3d4, 0x41da00de,
- 0x9bfe23bd, 0x84c785fc, 0xec223e3c, 0x2788bc45, 0x04e4227f, 0xd5b9c7d8,
- 0xd174eb82, 0xa7cbd5fd, 0xf2f8fb53, 0xc63f7465, 0x12fc4396, 0x4095e237,
- 0xc9dfa05f, 0x83d932b5, 0x80d746f9, 0x49ef7804, 0xd2e28e93, 0xe52deb8f,
- 0x9d782cdb, 0xff337c51, 0x509bf1a9, 0xb5cb2e2e, 0xeb6f4758, 0x7576c5bc,
- 0x7596bc7a, 0xba5da1c4, 0x00c78fcc, 0x7e41c93b, 0x6fbb2f9c, 0x3c6115b2,
- 0xe38c91d3, 0xc060523c, 0xba060a16, 0xaa3f50b2, 0xe2d57fef, 0x8496c5bc,
- 0x881b0ef1, 0xcd12d172, 0x9c384eed, 0x1efd05a3, 0xbe08ae5e, 0x88d6a3c8,
- 0xddc624be, 0xe822af68, 0xb9e27195, 0x38e71613, 0x42dfd11b, 0x03ad277e,
- 0x38eee5f8, 0x0ebc44e7, 0x6c64c371, 0x3cf0a587, 0x558b29cf, 0xe2538bf0,
- 0x9a6bb97e, 0xa71e422d, 0x3841bcb7, 0x3c6d671c, 0x4f9e138f, 0x9f355b50,
- 0xe7ac4730, 0x26ab04ab, 0x30b4a3cf, 0x423ca467, 0xe348cd9b, 0x394e9d52,
- 0xee5de946, 0xf23fba86, 0x992f98ca, 0x4e281cce, 0xda5b2329, 0x36928f31,
- 0xf302b7ca, 0xe1098d2c, 0x6335e872, 0x5bafa57e, 0x7185ec97, 0x897701c9,
- 0x1ed8e011, 0xa5f04c9f, 0x4815fab0, 0x1d6ea1af, 0x9ee87a2d, 0x06a49f68,
- 0x50a4307b, 0x509047e8, 0x655bca33, 0xa441fbac, 0xfacab0f3, 0xf3054655,
- 0xf5195e50, 0x9dc969cb, 0x38fe036d, 0xa23a37bd, 0x9b13f75f, 0x6952fbd0,
- 0xef0a961f, 0x7840c179, 0x93c2fa18, 0xa1de11b3, 0x97a6dc2f, 0x5ff5e242,
- 0xdf040cd8, 0xb28bbde9, 0x30fe7e29, 0xf4e6e58a, 0xe0a3779c, 0xdf02158b,
- 0xf3231aaf, 0xdc6233dd, 0x93e9eb55, 0x6b24e7e0, 0xb633f4f4, 0x5d4cbc90,
- 0xd3d279ed, 0xf429b03f, 0xb7d37f9e, 0xf803ebec, 0xe64ab7fc, 0x7a2fbc40,
- 0xebe52371, 0x8cb6355e, 0xa9eb82dd, 0x07cc31d3, 0x9bf7d9ec, 0x4fd07d7d,
- 0xa08654ac, 0xf9f9707f, 0xf11b9b83, 0xb355bffa, 0x34ff8821, 0xe612e3df,
- 0x3732be05, 0xdabebe13, 0xc056c514, 0x6e1e1692, 0xe843fb19, 0x31d1afaf,
- 0xebe12bd4, 0x74193786, 0x0dfad8a9, 0x7f4e62ba, 0xdd2a7fd4, 0x488cb181,
- 0x886e950f, 0x7b67d43f, 0xf046bd36, 0x8f6d70ab, 0x7a2d70e7, 0xe458eb71,
- 0x36353e93, 0x2a34f309, 0x9da8ff5c, 0x33f686b8, 0x2572e820, 0x8e1ef9fb,
- 0xe19fb70b, 0xc5897376, 0x5dc71479, 0x15ce7ec9, 0xe847b5fc, 0x8f298561,
- 0x1d92be60, 0x27de51d4, 0x6c732e9c, 0x9fa3f23d, 0x3f22aeda, 0x8b66c53a,
- 0x6cdd1f98, 0xd9b47ae4, 0x894ce6c6, 0x04130f20, 0x5d75babc, 0x898bb446,
- 0xbd44526d, 0xf5c2ca74, 0xafcde812, 0x23d3ee49, 0xf808d5eb, 0xff70ec95,
- 0x5dfe2dfa, 0xa120aa38, 0x5dba0c7f, 0x3d9d4f80, 0x8f029f14, 0x7c555e2a,
- 0x884be2fa, 0x3f0b365f, 0xa4bc7b73, 0xb3aee389, 0x169ce3ab, 0x2f664f7c,
- 0xced13afa, 0xedf8039f, 0xa5c4def8, 0x575f934c, 0xf589eaf3, 0x1438c95e,
- 0x3ca302cd, 0xbdddb65c, 0xbae300c2, 0xf3c73046, 0xb0af8fd0, 0xb3bea096,
- 0x31da3b55, 0x8678deff, 0x971b37e7, 0x9a4adf30, 0x73fff187, 0x2a7ca5f7,
- 0xe965dde2, 0xf5d41769, 0x67eabd81, 0x22e570e7, 0xabd9bd5c, 0x8517286b,
- 0x17276ff6, 0xd6e891c5, 0x6bf5cf15, 0xebdff184, 0xe2b7ce85, 0xf9d12bf5,
- 0x390f510e, 0xfc853f12, 0x6b3f944d, 0xe1ee907e, 0x918e2cf4, 0x7b7cb1fe,
- 0x19dcbc4f, 0x276b2f09, 0xb8f4f2e8, 0x88ed164e, 0xda167764, 0xffbcf3bf,
- 0xcf527b42, 0x69fc3fbc, 0x56e7e7fc, 0x0ebede3a, 0xa64b7ce1, 0x1fb9e938,
- 0x5f311877, 0x55a7e6ac, 0x4b5f3d78, 0xb9fa09cc, 0x5a996bf3, 0x9b5d7af5,
- 0x57718854, 0xe48beec9, 0x7fb6771f, 0x6771fe4d, 0xbeac7f98, 0x4f605ef7,
- 0xb2d18f94, 0xfcfff885, 0xcbcf1e06, 0x48e9f94c, 0xdfb3c380, 0xf10a7cc0,
- 0xb40ff92f, 0x679fe85e, 0xf1c7e1cc, 0x1ec9625b, 0x8f30382e, 0xac5f1cf0,
- 0xbe084a63, 0x4cd19c12, 0xbd97c109, 0x27e9a6dc, 0xc668fab9, 0xabef4ca7,
- 0xbee69fb9, 0xbd3f7341, 0xcfd340ba, 0x3349bfac, 0xa9597b3e, 0x1de39fa6,
- 0xafdf19a7, 0x3f4d76e9, 0xcd6ef9b7, 0xb8e6cdf8, 0xe00ea9e7, 0xc3fa0675,
- 0x7ac52b7a, 0x8f7f5baf, 0x97e639e6, 0x992f58fc, 0xf9fdc82f, 0xb1fb31e6,
- 0xf229525e, 0x16fbd713, 0xdf9de669, 0xe82fcdac, 0x74bed759, 0x4f9d5fc0,
- 0xbfa1f872, 0xfef6bd60, 0x848dd6c2, 0xed3e85cf, 0x6a2fc5f5, 0xa687f9fb,
- 0x4c71c40e, 0x7f442aef, 0x6d76d7ee, 0x748ae2be, 0x55775ef6, 0xd54a8e74,
- 0x68acd9d2, 0xbf8e1ce9, 0xd85b3c98, 0x37dff87d, 0xa1d62fe0, 0x0aef8be5,
- 0x6bb07f7f, 0x621b9cf3, 0xcf51c7dc, 0x952eb775, 0xcbebe619, 0xbbb23d79,
- 0x83fccbf5, 0x7d3c844a, 0xfd3c8f6e, 0xbb10f627, 0x3be9e6a6, 0x2372feb1,
- 0x97f516fb, 0x3c457fdd, 0x31e58144, 0x8acdff80, 0xf5cba61d, 0x2f307316,
- 0xd4bfae1f, 0x5ff7f416, 0x83d7a4ec, 0xf055aa75, 0xf7f8b0f4, 0x5aa7085d,
- 0x9eef18c7, 0x88def04b, 0xff808c80, 0xea9d7c2c, 0x4b87803c, 0x12f8cf38,
- 0x51c60c5b, 0x4bdcf75b, 0x4b6b0171, 0x480efae4, 0xc43e3a1e, 0xda3d253f,
- 0x234cff82, 0xe44c68bb, 0x1894d176, 0xbf31c712, 0xd857bf8d, 0x51e6dec5,
- 0xb5bd18eb, 0xea992ed2, 0x8f585d31, 0xfbd7a089, 0xf683fe26, 0xf91e8be5,
- 0x4589bed0, 0xf7c27121, 0x7ea1f7bb, 0x26e7bc07, 0x63627bc2, 0x414a6ec1,
- 0x98d3f9bb, 0xaeb79238, 0x3aefb203, 0xa4de70b8, 0x0506dbc4, 0xf0e12deb,
- 0x9dd9348e, 0xde7d10fa, 0x66ed6926, 0x43f70163, 0x9db9120a, 0xf8f0b2ad,
- 0x7be8ac75, 0x4f76fcc2, 0x414f8f13, 0x42dbaa1a, 0x89b1c1fc, 0x5cfe34b1,
- 0x5c58c974, 0xdf1146cf, 0xf448e637, 0x224946be, 0x5f1e5efb, 0x75d7163a,
- 0x8e525ec1, 0x3e044ae3, 0x046fa2c7, 0x0e5f736d, 0x0df6228f, 0x13ebf3a8,
- 0xb6127c61, 0x4d8ed4a5, 0xc83f0ab4, 0xfbd2037a, 0xde93b444, 0x8d65946b,
- 0x93b6a55f, 0x2ebaf912, 0x0a2acda2, 0x2168c9ca, 0x1e846337, 0x1471fcc3,
- 0xc2739309, 0xde4d64e8, 0x513188f8, 0x7a258de4, 0xbc7489dc, 0xb7b1d055,
- 0xcf33b23c, 0x69d507ba, 0xad791e78, 0xd591e799, 0x3c8f733c, 0xc44c63b2,
- 0x21d2323c, 0x879416c6, 0xf5978985, 0x9bea0673, 0x278e9cc6, 0x1c7f23c6,
- 0x23cf1d92, 0x31bcc7e8, 0xe2b700f9, 0x91f039d0, 0x4ad81b11, 0x7817f433,
- 0x1933ca15, 0x2d8b0e20, 0xc3efca08, 0x9f843989, 0xa6fd47c1, 0xfc3fb87c,
- 0xf31dab98, 0x31a603ca, 0x66ffaa1b, 0x87165cd6, 0x1606c4fe, 0x29596e31,
- 0x64be39e8, 0x9e728c97, 0x12fc05d4, 0x052b1e81, 0x578e403d, 0x77873d20,
- 0xeec9bbb9, 0xaa403d08, 0x3da3e30c, 0xc397f23a, 0x57103f9f, 0x7bd230f6,
- 0xbe722fb0, 0xc385a2e4, 0xfd718c61, 0xbc1fe704, 0xfa88c3ad, 0x37aa8166,
- 0x0f4c752b, 0xe82a9df4, 0xaf037537, 0x978bb353, 0x9faac92e, 0x867e68c5,
- 0xb4c160fa, 0x1fe61f58, 0x78e5b416, 0x44972e09, 0xdb4f15f9, 0x17f61761,
- 0xc56a1d0c, 0x7bf9d778, 0x47927d26, 0x7ae31a2e, 0x513ecf47, 0xcfd900f5,
- 0xdc5baa44, 0xa2eaf82e, 0x41382145, 0x018daf3f, 0xb0d82c3a, 0x53ee1762,
- 0x19dfef78, 0xca8e27d5, 0xb270c35d, 0xcb39003b, 0xb3d5b00a, 0x387c028a,
- 0x2699e695, 0x0d7ef1e6, 0xdf0535ef, 0x01db477b, 0x0351cf5a, 0x5f809af3,
- 0xa5de773a, 0x98dabfa0, 0xff107264, 0x71d7ba8a, 0x1910fdd9, 0x1d577d0f,
- 0x2da33682, 0xd606bac6, 0xb8c8cab1, 0x768bab7f, 0x5a27fe20, 0x2fc4f43a,
- 0xc47a5d89, 0x674159e3, 0xdfc9f1f4, 0x2744624f, 0xe9c75d39, 0x7df0ad96,
- 0x79b5fd23, 0x751377c0, 0x1902fe42, 0xcc627d78, 0xe0154b3b, 0x2aeb03cc,
- 0x7f41e9c7, 0x677f8c4f, 0x0ff40e69, 0x4e3f9bae, 0x313dfc0f, 0x732f9dfd,
- 0x5adfd440, 0x0fefc557, 0xbecbe77c, 0x5bac0fd0, 0x4cdfefc0, 0x59decfbc,
- 0xf30e3d57, 0xd65eeffb, 0x07fe7c0b, 0x57ef2e64, 0xba51cadb, 0xc67148fa,
- 0xcf3544b1, 0x1ef80ccc, 0x8eefdb57, 0xa9759da2, 0x41a770f5, 0x8e470f53,
- 0x8dbf0131, 0x12c57c17, 0x8c0ec8e3, 0xaf1bf413, 0x18fed3f7, 0xf84fc99d,
- 0x58358ebd, 0x5b006f91, 0xf6152eeb, 0xaed07f7c, 0x724bf969, 0xe80cb632,
- 0xe256292d, 0x98cb5593, 0x3f768cdb, 0xf1d78758, 0xe1733c3a, 0xd47855fb,
- 0x0b80f7f7, 0x85b7ab48, 0xe681b5c2, 0x1ceae151, 0x7945e512, 0x0aa7ed52,
- 0xf5d4a757, 0xb7bf262c, 0x013fbda4, 0xdb19d6e9, 0xff412595, 0x4423a4c5,
- 0xaea4cec7, 0x48472567, 0xa8e9c0df, 0x38c5727b, 0x19e7bc2f, 0x024ba9d9,
- 0xf91946fc, 0x8c26933e, 0x8f3de057, 0x58bdb924, 0x73be03df, 0x32ef91f8,
- 0x4687a48d, 0x27e6d50d, 0xcf9c492c, 0x3a3b459a, 0x30feb9aa, 0x9b67a5f0,
- 0x78c056c4, 0x236ec5cf, 0x6d8989da, 0x684e8c27, 0x309db6eb, 0xc3aabea2,
- 0xb753cc3e, 0x6f5118c1, 0x7992486d, 0x0fcc329e, 0xe0399bde, 0xc7dc44a1,
- 0x45512950, 0x091ddeee, 0xef7fb1a3, 0xf8255c5c, 0x8eb7232d, 0xb966c7c6,
- 0x76c21fda, 0x8bd8eb0e, 0x2dc3342c, 0x99d2fc6b, 0xbf1a31d5, 0x5dbd5676,
- 0x0cd39fd3, 0x9eb901d4, 0x1b5d2cb3, 0x5b88303f, 0x2c199e01, 0x6dfa87f8,
- 0x8ce3a0ba, 0xdc01b5d4, 0x6dc332c7, 0xcc8476f0, 0x856db137, 0xd77086de,
- 0xbf520e4b, 0x73e0a65e, 0xa10af933, 0xeb437bd5, 0x795ba362, 0x86aea332,
- 0xd815fbfb, 0x5456bc07, 0x42453e4b, 0xbee9183c, 0xfba255a7, 0x47c7d69e,
- 0xcf323ee1, 0x26f28952, 0x3c447dc9, 0x1cefec24, 0x51e82b01, 0xf333ce03,
- 0xa3b312fb, 0xbefe10de, 0xe99cff0a, 0x3f89a7e5, 0xaeaf9f85, 0x7602ba73,
- 0xc9cfae17, 0xfe80c4fe, 0x64efac35, 0xda9f0687, 0x6d7aacfe, 0x6d32ce7f,
- 0xf0926a7f, 0x81b207df, 0x93d34f28, 0x55ea3d24, 0xe645ffb5, 0x01f96ffb,
- 0x6bb2cd9e, 0x8d67f226, 0xa8f54fd1, 0xfa9bb2cd, 0x5eb87dea, 0xc0ee48c7,
- 0x9639201f, 0x19573e48, 0xf412d69c, 0xe2256ba3, 0xc42c99db, 0x8e09c85f,
- 0xb3dcbea7, 0xd71268ff, 0xaeccab3b, 0xdb1754a5, 0xc1375929, 0xa77a51a5,
- 0x55c0fd1e, 0xc8bce452, 0xdedc4963, 0x8a20c5be, 0x2006b807, 0x9f5da293,
- 0xc2f3ef1a, 0x76fc077b, 0xfbfd17ae, 0x07c08501, 0xb73dca0a, 0xbd85e337,
- 0x25fe0499, 0xe4037ffa, 0xdfa4e996, 0x495a346f, 0xa43b0bbf, 0x2fe70bea,
- 0x7c6876b4, 0x3f8a7ec6, 0x7b5fad26, 0xff62f50e, 0xc782ce7e, 0xcc47be01,
- 0xec8ffdfc, 0x2fb87c90, 0x3ed06ea7, 0xc0299fd2, 0xbadef816, 0x5b47a154,
- 0x52aefbb5, 0x2e61af50, 0x7a20c27f, 0xe5499a6f, 0x41e92776, 0xbbaa5fc9,
- 0x4529fa04, 0x0ca6f7bc, 0xbc95f085, 0x75c245a8, 0x0aef3267, 0x463fe3b4,
- 0xb60a4c21, 0x8fcfed57, 0x79fdc292, 0x65e6124b, 0x148c3b52, 0xe32eb1ef,
- 0xeba7943f, 0xf2327f39, 0xb0fcf859, 0x0757aa7c, 0x718bf2e3, 0x77b9af98,
- 0xdc6fbf67, 0xb49b24ef, 0xaac1b771, 0xe7c7bb8d, 0x44cff569, 0x4cef5687,
- 0xb9a7ee2e, 0x5039c53f, 0x796a7f73, 0x877fa6a1, 0xf8cd66eb, 0x6997a6bb,
- 0xe3a951fa, 0xda00f2c2, 0x9e4c4afc, 0xeb12bf36, 0xa251e6d0, 0xba7afc0e,
- 0x9a317804, 0xc06e1dbc, 0x46c81343, 0x47682db1, 0xa899c606, 0x685d1b48,
- 0x34db60b6, 0x7c8fca24, 0xc787d4d2, 0xbe0751e1, 0x7987ea9f, 0x4c5bf14c,
- 0x49788a58, 0x8a6295f2, 0x7544d018, 0xd41e1bd5, 0xd3d39bfa, 0xeda95cb8,
- 0x99f724b1, 0xbc1bac64, 0x7f73a4a8, 0x89f14036, 0xbf719a29, 0xfc89bb68,
- 0xbe4e3522, 0x9465a71c, 0x0eba409c, 0xf549d07a, 0xaccad613, 0xde7c5798,
- 0xdba9f228, 0x41dc3ef9, 0x673a1dad, 0x492f7c88, 0x49e0fae6, 0x9c58e957,
- 0xac0daebf, 0xfad3ca2c, 0xa7588c8f, 0x8f6b6bac, 0xef967b43, 0x7988c8fa,
- 0x6175e0bb, 0xd15df4e7, 0x55f95f58, 0xff711c8b, 0xf7cc92b2, 0x7a13ec6b,
- 0x83f7d67d, 0xb0c951f1, 0xb59e7ea0, 0xc32fcbb5, 0x5e8167fb, 0x4a6bf2f3,
- 0xfa0d3d24, 0x3ccf1359, 0xa7eea699, 0xc1ec6a71, 0x037ec5dd, 0xed6a9fd9,
- 0x78d339f8, 0x5c7a045c, 0x91a33d7b, 0x1d630bf4, 0x815bcc06, 0x8fdcd75e,
- 0xd271164b, 0x12e83640, 0xaea381e8, 0x2bb5fbc8, 0xc744f4d3, 0xa232eea3,
- 0x4f8093c3, 0xec9f97f4, 0xd78e3f81, 0x65ede12b, 0xfa1081e4, 0x4fab8f85,
- 0xcbf47ee3, 0x07ede8bd, 0x979f7d04, 0x54a80502, 0xe268ae3d, 0xb9a699df,
- 0xf73f718b, 0x1aafccbe, 0xeb315eb1, 0x7b4312d7, 0x03f687fb, 0xb8cf8fb4,
- 0xee326f75, 0xecb4f4af, 0x7fc0664d, 0x05650635, 0x1fc0f3fa, 0xea7ff40e,
- 0x7f04fd5a, 0x3b614b6d, 0x956daf5e, 0x3d92a81c, 0xa18dcedb, 0x468eb275,
- 0xdf3dffac, 0x93235c0b, 0x5b755fb9, 0x04f3c2b2, 0xda27786e, 0x3e516dfd,
- 0x00fc849f, 0xdae109fa, 0xe866b121, 0x14dabf3f, 0xa0fbeeb1, 0xd59ef7c0,
- 0x6ab38a46, 0xc75c79e0, 0x467dccbe, 0x56d3f213, 0xeb849758, 0x0c477c38,
- 0xc0d4bfce, 0xe150cfd0, 0x3819933b, 0xb0ffeb8e, 0xb81d0212, 0x2652aabe,
- 0x54b87f7c, 0x9fe723e4, 0xb8c74c6a, 0x77ef96a6, 0x4dd95ddf, 0xab0fbe79,
- 0x36569fb9, 0x397240df, 0x57f70963, 0xe55af9c2, 0x9f05a7db, 0x386ff386,
- 0xd7e0f6df, 0xd7e3abea, 0xe6bf20ca, 0xfa07dda3, 0x3e414e8f, 0xeeff01fa,
- 0xddc5fa65, 0xbb801486, 0x81d5a36f, 0xcb06bdfb, 0x519287be, 0xf7e6ec6f,
- 0x946cd487, 0xee51feb8, 0x37a5f5c6, 0x091ad919, 0xedd389f9, 0x85374101,
- 0x14314975, 0xa2fa05ff, 0xbf51ca9e, 0xe9b03087, 0xa73f315b, 0xf067fae7,
- 0xd71ba96b, 0x6e6ff084, 0x555be732, 0x32340e2f, 0x07aa56f7, 0x0299f4b4,
- 0xe06cbcf3, 0x312c9cf5, 0xaebf6e5f, 0x5da05331, 0xe4f5cc9f, 0xda87010a,
- 0x80e4275f, 0xf84ddc65, 0xf8e2689c, 0x5fccb71f, 0x99f8eb81, 0xea30fdd1,
- 0xef5909d5, 0x6bdda0d7, 0x20e6fbea, 0x07321fca, 0xbc6ae1f9, 0xa7c47bbe,
- 0xf583ee1b, 0x268faf9a, 0x3e779afa, 0x367e456e, 0x714d0ee7, 0xb53fe047,
- 0x61c85cf5, 0xd5f03b6e, 0xaad47e85, 0x4ebb29fd, 0x729f691b, 0x2431b9db,
- 0xe8d2172f, 0x535cfaba, 0xc1cf971a, 0x9aa83f62, 0xadbd04cf, 0x8e082e2f,
- 0x70c0f153, 0xc2115e77, 0xebd102f3, 0x086c25be, 0x4e3fab4f, 0x73599feb,
- 0xf30b9a58, 0x1a7065dc, 0xf7ef802c, 0xc62fa7e3, 0x2e6f2ffd, 0x851dcc67,
- 0xcc4ceffb, 0x03ee1d7d, 0xb03f52b4, 0xeffa953c, 0xdda8572c, 0x84bd7262,
- 0x4f63ba78, 0xabed2e7d, 0x55ca7ccc, 0x3ce9ef0a, 0x053b1068, 0xa827e44d,
- 0x36eea1f5, 0x7ee09999, 0xea8936f7, 0xb3fc2a9d, 0x3733a42f, 0xe3df97e8,
- 0xdac1e0fb, 0xde92ef65, 0x1b9f5473, 0x90d27183, 0xd88d139a, 0xf3fb2cf7,
- 0x8e2ff418, 0x3e413d83, 0xa59fbf03, 0x0e4fa84a, 0x5ddf711b, 0xcd3b05c5,
- 0x6baeb2f3, 0xf79dca0c, 0x50ea890d, 0x19cf5bc7, 0x62bdb853, 0x5806ca08,
- 0xffe0139f, 0xeb813922, 0x3a21b693, 0xdca1df4e, 0xd0fc11af, 0x71d7c37e,
- 0x32d30f48, 0xf19bede5, 0x4332fdf9, 0xda535eb9, 0xa08d6715, 0xbcc28f87,
- 0x75c15c98, 0x7f7e1b60, 0xeb9bd1ba, 0xeba6e780, 0xfa9bef22, 0xbe72f92c,
- 0xff14e482, 0x0ab7e024, 0x60b36fc1, 0x8a36f149, 0x20d1fc83, 0xcadab3cf,
- 0xadb1eb4e, 0xda47d897, 0x147d8cf8, 0xc6f7c7e2, 0xadb6df87, 0x8372f9c3,
- 0x59238c7d, 0x71845f88, 0xdfbcd324, 0x994cf3cb, 0x11dc53fd, 0x0e5979d6,
- 0x03bfc03a, 0xe381d57a, 0xdf91d8a4, 0x767b5207, 0xca0ac3c7, 0xebba298f,
- 0x6c17b429, 0x8ee28e80, 0x1fd6af5a, 0xe5ca963a, 0xc0aa58e1, 0x7e368a5b,
- 0x4e493882, 0x1c5271e1, 0xe2438416, 0x14ebf0a7, 0xae50993f, 0x8103bde0,
- 0xa244af3e, 0x29a96a4f, 0xabe50925, 0x019cf899, 0x857f239f, 0x229ed3af,
- 0xae42d9f2, 0x235ca067, 0xb972b6ff, 0x3bb79f0e, 0xf38ec4b5, 0x5c7dc6ae,
- 0x69c6f411, 0xf5daceb1, 0xb3cbe112, 0x3a784ede, 0x4abbd6c3, 0x00cf2f81,
- 0xa02fb81c, 0x498ae5d3, 0xdb8d7ac0, 0x04b36315, 0xfadd40f5, 0x756e7a18,
- 0x73eddbff, 0xc2979fa1, 0x6b6cfef9, 0x3cf10999, 0x3f973d7b, 0xfdc77df5,
- 0x4f28ec33, 0xa32e8645, 0xb467ee03, 0x3f43889d, 0x54c768b0, 0x6f61ca3b,
- 0x70a86670, 0xf16fbb2e, 0x07e73b49, 0xf5aa6fcc, 0xbf4acf38, 0x78bff111,
- 0x6dfe2319, 0x3a87fedf, 0x6db3e394, 0x87b45631, 0x78c67667, 0xbe77ff51,
- 0x49d3e511, 0xe3788714, 0x319daf41, 0x7f224c74, 0xc56c8773, 0xc6f3d1f8,
- 0x3ca14fe7, 0xa147b67a, 0xb716c7e7, 0xed0e7c3d, 0xd8db4d5e, 0xda7cfad3,
- 0x954ffe87, 0xf765da87, 0xfed57ad3, 0x0a4dcbe7, 0x7ab3d1ea, 0xb71627ae,
- 0xeffe4abe, 0xf9dd8be2, 0xb33f0f58, 0x50c36ff3, 0xdb7e79af, 0x99f50c3d,
- 0x61eef5e7, 0x5af3df78, 0xbf247d4c, 0xf3c697c5, 0xccbdaa40, 0xe4d7a239,
- 0x5d85a28b, 0x2e6869c8, 0x459d7dc7, 0x3039a787, 0x2fdeab9f, 0x7ed1d5ca,
- 0x46f7a2fe, 0x3c87e7d9, 0x97d010d7, 0x87a1f5e3, 0x8654c547, 0x41aa65f2,
- 0x555e37cd, 0xeaef079e, 0x75e48587, 0x19a73a02, 0xe80eadc6, 0x6adafef9,
- 0x06f187c9, 0xcfe12ff8, 0xb9d53f91, 0x435beed0, 0xfc6b827e, 0xcfd8a1e0,
- 0x5051ac75, 0xf6f698ad, 0x6697f10f, 0x28fe7404, 0x6de9a3e0, 0xf7f27e51,
- 0xd413fa03, 0xecd47e17, 0xe6c69f73, 0x34f21148, 0x468cef79, 0xaf9e1e3d,
- 0x8458bf81, 0xdeaff55b, 0xa3f9e34f, 0x0eab7a8c, 0x345667f7, 0xb5e22b30,
- 0xfa675e47, 0x0a2f946d, 0x8128efcf, 0x4e7c2675, 0x22b3afe9, 0x8a5faabc,
- 0x4116dc74, 0x72a6240f, 0xaf9544bf, 0xe88e8086, 0x352810d3, 0x563687f5,
- 0xab36d7c8, 0x68f7be8e, 0x09ba9b68, 0x170d0bf3, 0x0c198aef, 0x723869ef,
- 0x3defc33b, 0xa6a5ad3a, 0xe2ee7c5c, 0x063ba66d, 0xfc26f905, 0xb852c77d,
- 0x0bfa0cde, 0x21dfed91, 0x59fecfa1, 0x8a40f076, 0xff3de44e, 0x1083b6ef,
- 0x7852079f, 0xe7933e7c, 0x1e7c784f, 0xbd543f6e, 0x092bceac, 0xcbd4f73a,
- 0x81cfc9a7, 0xb2f49a38, 0xb8d0aa94, 0x7629b68c, 0x4c8faf8a, 0x9e962bb3,
- 0x3bd3f7f3, 0x3d41b674, 0x39fd57e7, 0xd7b9d78f, 0x938f7184, 0x4cf323ef,
- 0xaddf6893, 0x5c79ffea, 0x9ee5f912, 0xc70f830a, 0xa60570a9, 0x1dec7cf1,
- 0x2ccf834e, 0xd544fd05, 0xdf7cbc8f, 0xd57dd121, 0xc7fd54af, 0x77e78b80,
- 0xf7e50da7, 0x17dc98b7, 0xf71f2ed0, 0xd17ae99b, 0x319d7e08, 0xab8c5ed7,
- 0x6253baee, 0x5f8407a4, 0xb869f2a9, 0xadbe79df, 0xa3ee37df, 0x53f820df,
- 0x30acb395, 0x58ed50f9, 0xc7970a5e, 0x85e3b43a, 0xaaffc768, 0xe7c3cff1,
- 0x496e3b05, 0x3d18e7a5, 0xbd3df43f, 0xfebc522b, 0x0ca790ac, 0x3d817e95,
- 0x266f0825, 0xd83ed00b, 0x7c6becde, 0xded7971a, 0xb909e7ee, 0xdf3c92b9,
- 0x3fccf426, 0x52cb9e4b, 0xb5f877ff, 0x5ec3fd97, 0x2cfbc7be, 0x2a4264b5,
- 0xae5a35e0, 0xfca0940f, 0x6221a7fd, 0xd85d3add, 0x3577886b, 0x699bd9f4,
- 0xe47c61d4, 0x83f9e6a9, 0x6de504a6, 0xc80e638a, 0x317b3fb4, 0xc7e883c4,
- 0x4090ba2d, 0xcbfa0d6d, 0xf17cced0, 0x6623d530, 0x6fe16b56, 0x3e2e9cc2,
- 0x87c724bf, 0x362cf3fe, 0xb34cf28a, 0xb8ac12da, 0xa929b9df, 0x95ca1f65,
- 0x6cac9377, 0x50bf1d0a, 0x79e26f1d, 0xb46965b8, 0xf98592bf, 0xc3eab303,
- 0x7fad7efd, 0x1bc8b370, 0xbc27e6f5, 0x7ae66ede, 0x724cbf65, 0xa6f9875e,
- 0xb633191b, 0x59e0bd71, 0x7524f3c6, 0x7be82b6d, 0xff715aac, 0xf2807d33,
- 0x835f5450, 0x1edba7a1, 0x6479464f, 0xa93d6d4e, 0x48f785f6, 0x95d7865f,
- 0x5eb8db6c, 0xa2c8d4f2, 0xc24c348e, 0x93c42d7e, 0x2a5fe829, 0x3bc464ca,
- 0x57d9a5c0, 0xcf05faa6, 0xf9d2ba8b, 0x1c531ffd, 0x2f47733a, 0x71a6a475,
- 0xf6248ebc, 0x23acf46f, 0xae9bdbed, 0x548eb95c, 0x80d87ad7, 0xea95c5f1,
- 0x5ea4cf49, 0xde5127ae, 0xf3cf5b31, 0x926dd9bb, 0xd955f315, 0xc3dd7c6d,
- 0x7f934757, 0x958fe63d, 0x2a07d476, 0xe14ece9d, 0xe1fb3df8, 0x75b42597,
- 0xab7a8fe0, 0xfaf5d619, 0x4ddf4b87, 0xa4c57de7, 0x634b73e0, 0x3fe9bbe8,
- 0xf8831bde, 0xa45a1d7d, 0xf5476bcf, 0xc193f391, 0xa92bf57c, 0xf9167794,
- 0xc3d83d6a, 0x275e60d8, 0x855bb9fc, 0x70826bbe, 0x3b9af285, 0x29bfdd78,
- 0xfa8e3dcd, 0x36cbeb3f, 0xa4e89f91, 0xc0abf47c, 0x1a3798d7, 0xbac58b08,
- 0x59a32ff4, 0x9a91d603, 0x926fdc92, 0xa74cfd1c, 0xf3c11ca0, 0x6ef27f54,
- 0x623ec855, 0x3ceb0bea, 0x858046f9, 0x7df03bf6, 0x3a083713, 0x8b3c41a6,
- 0x33402571, 0x03d0eb0d, 0x3f27bd45, 0xfe71e99a, 0x35ee0c47, 0xa97d63d7,
- 0x4158ef5d, 0x4fb0e042, 0x7759ed89, 0x5ebc9c92, 0xd49fd6ae, 0xf56f79ba,
- 0x93df0927, 0xea8ff9cf, 0x9cff624d, 0x7762675a, 0xb5f8a8ba, 0x619eb8aa,
- 0x832c3afc, 0xd2faeb5d, 0xd42392df, 0x4c294c7f, 0x7ada67f8, 0x57bc9ae3,
- 0xdeff4f88, 0xa96de33a, 0x1efb1fec, 0x0adc07a6, 0x0c322eff, 0xe709a1ee,
- 0xfaee2993, 0x91c4bfef, 0x26eb6d9d, 0x15d9d87b, 0x7f9402c5, 0xf779e0ec,
- 0x503dfe36, 0x496fc427, 0x7e767621, 0x57779f0a, 0xfff1195b, 0x18a8c0b6,
- 0x0a58ff1c, 0x23eac7a7, 0xbfa2a6d3, 0x69e80def, 0x3c630ebf, 0xd016db1e,
- 0x72dfa117, 0x9a92e90d, 0xd12e891a, 0xcb853edc, 0x7f6121d1, 0xba72a50f,
- 0xe3c87d95, 0x5e52cf30, 0xbd0ab15f, 0x75e7a9e0, 0xc9997df5, 0x4f4f9a92,
- 0xd97f5489, 0x637645d1, 0xf68942d6, 0xfadb7ed5, 0x916913cb, 0x5b33f1eb,
- 0xbfae444f, 0xfd218f94, 0x3b3e5bd9, 0x4b7d8f3c, 0x0f63c89a, 0x5fec79e6,
- 0xbd695aa5, 0x2521fab6, 0xfaeab2c8, 0xbe1d21af, 0x87408b48, 0x5c7f386b,
- 0xdf5b77fa, 0x7d5230fd, 0x6fce1af7, 0xe16efe4b, 0xa7e92257, 0xf3bf386b,
- 0xfd7f9e3b, 0x8aff3c77, 0x77ff18ef, 0xff9844a5, 0x01fdd5ff, 0xf0fff5e1,
- 0xfbe102fd, 0xcc0ea200, 0x87bde2f7, 0x7e5db5a5, 0xdb714d68, 0x07a04ba7,
- 0x982f09f5, 0x184e8ed0, 0xab61ebc1, 0x1b7c9947, 0x01bee0a5, 0x832c5f15,
- 0x41d611c7, 0xc076bce7, 0x30339673, 0xb2f98eca, 0xe0e28c11, 0x8baf334e,
- 0x6d35bd31, 0xb7c3ed0a, 0x7e0edda6, 0xdf2f5349, 0x174e6d33, 0x762f6171,
- 0xc9466464, 0xacefa867, 0xd5a5fb61, 0x6aea29d6, 0x0fbe56d6, 0xb495e997,
- 0x4abde9db, 0xf143fa1a, 0x38f5f87b, 0x246e733f, 0xdb9c94b8, 0x72541e29,
- 0x4427be10, 0x6e36d7fd, 0xa5e60e40, 0x6217e06d, 0xac71f05d, 0x6b3c520f,
- 0xfbea71a5, 0xbf87d87e, 0x930309ef, 0xbdeb9eb0, 0x6273ef9e, 0x5d4d6a96,
- 0x7fc1a0ef, 0x7544ae72, 0x8c0fb93d, 0x0ff3a43f, 0x30473e7a, 0xd077e031,
- 0x1bd52b36, 0x1ff11adf, 0x26bbfc79, 0xcfbbe75e, 0xc6ec87ca, 0xb8e019b8,
- 0xf121676f, 0x235dccef, 0xf8c0a83e, 0x2f3f3fa3, 0x295c47a4, 0x454705f2,
- 0x17cd43be, 0x63adf5a8, 0x1c724f22, 0x76d02ff3, 0x5a043e60, 0x5aee8fa5,
- 0x4fa527db, 0x84f2fd04, 0xde43f3c4, 0x543f3c43, 0x0bf47468, 0xb8394fdd,
- 0xb9abe70f, 0x50bf5e7e, 0xc59b3df3, 0x207f0a7a, 0x2fc0a3fb, 0x6c1c6c2d,
- 0xd85f3b44, 0x6d8d1998, 0xc3a7d3be, 0xca8cef52, 0x7e953aad, 0xb868f891,
- 0xfdeae758, 0x7bdf545d, 0xffeeac35, 0x3f7c3ec3, 0xc7e0b743, 0xd461f61f,
- 0xbf572fbf, 0xf8c7dd0a, 0x52395691, 0xc416695d, 0xdce708c5, 0x8ab70e26,
- 0xa57e59ef, 0x6273df0c, 0xb623576f, 0x6539d505, 0x39af7794, 0x9bfe88d7,
- 0xbef762e7, 0x665f295b, 0x989e3054, 0xbbcda1dd, 0xfe7832d9, 0x7f8955fd,
- 0xab1de9af, 0x70b8f8a7, 0xc7f89eac, 0xf14ccb36, 0x64c0cdab, 0x70a7f60b,
- 0x3ca0a8bf, 0x6cfb0cb1, 0x83f9025a, 0x8495fb05, 0x798283f9, 0xa5d8db30,
- 0x2ba78849, 0x7cd559d5, 0x739316da, 0xeff3d23a, 0x1ed6b3ad, 0x4dfb423c,
- 0x78a975d5, 0xbda5eb51, 0x7dd559d5, 0x2ff29e0f, 0x3c34fb35, 0x9831aefa,
- 0x79dc2c7f, 0x5ff628c2, 0x8273535a, 0x1dc2d875, 0xaafea8e7, 0xf53d5bd6,
- 0x86afc8e7, 0x929ce8e7, 0xfd79cb6d, 0x81c03b75, 0xdbac2b6d, 0x06fcf009,
- 0x1b6d8dd6, 0xbfaf1bac, 0x5a8f3cb1, 0xb50772ff, 0x531796bb, 0x93ec085b,
- 0xedbac366, 0x2edbaa39, 0xdf63d3ef, 0x36f5d524, 0x2895aecb, 0x3f7521ef,
- 0xfdd787ea, 0xaf9e68e4, 0xd037ecf1, 0x839e0c77, 0x25dfd226, 0x31b3736d,
- 0xb0eaf83e, 0xaee11b3b, 0x085bbac3, 0x3a759c5f, 0xc66e78cc, 0x8cc39759,
- 0xf6c2b6f5, 0x0fdc46d3, 0x180fa753, 0x90061f31, 0x4596e3a7, 0x7c73b6cf,
- 0x895b6fdf, 0xc57bf119, 0xffeb58fa, 0x3dfd8faf, 0xa0acb1f5, 0x291e927c,
- 0x1b9ce970, 0x34efddb1, 0x13d10fcf, 0x9ebc5dab, 0x5f7fbab2, 0xae75c392,
- 0x219509be, 0xf39435f3, 0x6c6d85fc, 0xf5e8737f, 0x1e061925, 0x4239e047,
- 0x41ffde11, 0x8e35dd1f, 0xf41fdd5f, 0x9d57e089, 0xefa2643d, 0x2c77da49,
- 0xc418eec8, 0x1f343f05, 0x32bcbab7, 0xf7cfbf1b, 0xb9628d1e, 0xc9a75f3c,
- 0xbab0b1c7, 0xb9796f5c, 0xa73ae599, 0x750bf699, 0x0edda165, 0x7d319fcf,
- 0xebb71657, 0x9e7e74ce, 0x159d3783, 0xb9f51eb3, 0x7bdf33df, 0x8cfc61fd,
- 0x0bd91d72, 0x50574eb5, 0x81cb67ae, 0x19960b3f, 0x2b9f547c, 0xfba09fd7,
- 0xb06c6e22, 0x9f23a416, 0xb4683f1f, 0x3c2d5e62, 0x7f28e63f, 0x3c2fa9a1,
- 0x1c91a8ef, 0xd52bacb8, 0xe07dd4f1, 0x47db5ab3, 0x086dbe63, 0x051a6e6b,
- 0xafe90fcf, 0xe9fee2b3, 0xbe3cf59e, 0xf840bbff, 0x3679e139, 0x4bf433e4,
- 0x71f0f3c2, 0xe20f9ce9, 0x9cfdb9d2, 0x0a2db480, 0x173ea3ce, 0xd2f33fce,
- 0xf0bf75b5, 0xfdc553fb, 0xd582f286, 0x13be91fd, 0x49ed0c74, 0xa9a97943,
- 0x397cc87f, 0xdb7f7ce9, 0x4c1f5813, 0xf20fad0c, 0x5d78603a, 0x8573d550,
- 0x831d7fed, 0xfa075ef8, 0x2798ed1a, 0x0a0fd795, 0x8fd928df, 0xa708237a,
- 0x7a953fd8, 0x04ec7bf9, 0x70c5d7c6, 0xa7779cff, 0x82b9f944, 0x8aee5f09,
- 0x81733e81, 0x76bd43dd, 0x0b2affb0, 0xfa09a3ea, 0xc7aefc22, 0xd72e92e3,
- 0x349eb099, 0x71eaedf5, 0xe1419df8, 0x230e431d, 0x30a8ee5d, 0xd540fed0,
- 0x7b7d4dee, 0x7f7e18fa, 0xbc68cae3, 0xcc39279f, 0x2f2f5e0a, 0xb7e3ebc5,
- 0xce9331f8, 0xa0742226, 0x4f0703cf, 0xb66e51ea, 0x1825dc98, 0x114e173f,
- 0x6e0aa675, 0x9b68efa7, 0xe7e46062, 0xeee6ed69, 0x1f28afcc, 0x4856ddd4,
- 0xee3b23f5, 0xb414187f, 0xc13b8537, 0x3b5ec58e, 0xdd2f363b, 0x11bcf84a,
- 0x63c218ec, 0xf4ebc29b, 0x11cff4e1, 0x2ecdeff4, 0xd187a6f5, 0x2b39e0fe,
- 0x6a529f28, 0x60ae3b4f, 0xfa3867de, 0xc21e12eb, 0x35ff2bd2, 0xd096fd0b,
- 0x4eb73f8b, 0xfbaf7bf0, 0x39ff5aa7, 0xf4e6a675, 0x63751dff, 0xeb52fe35,
- 0x76bc6a4d, 0xda81f046, 0x3fed159e, 0x1a037dfc, 0x37df88d7, 0xdf7f22d8,
- 0xce85bb30, 0x6fbf5129, 0x25646bd8, 0x3f71135b, 0xc9def8ad, 0xa4fc8537,
- 0xbeff4fbd, 0xf88917f1, 0x278493bd, 0x3c3d806b, 0x3d5e764c, 0xedaeaeaf,
- 0x6d6f9e73, 0x6bc3fbe1, 0xfb9f235b, 0x77da0372, 0x2728ef78, 0x2b51bd23,
- 0xd98edbf6, 0x9744ea26, 0xebf796f3, 0x1e96f343, 0xeea49025, 0xbc51f5e3,
- 0xf663cda7, 0x53acb796, 0x96afcfbf, 0xae1f681c, 0x59b70fb4, 0x35edd7ec,
- 0xe6fce98f, 0x79e1b97d, 0xb5d3f7cc, 0x69939c75, 0x74ff5a56, 0x36e744b7,
- 0x1aae7499, 0x86ffb7da, 0xcfb48d64, 0x87610bfb, 0xc83a8bc6, 0x3f9c8dcf,
- 0x44937e7e, 0x77e0dfdf, 0x9ff74878, 0xc3bfc1bf, 0xff0179f9, 0x7bad470e,
- 0x5cd7dfa8, 0xd07bac1f, 0x77ea77f7, 0x3677ea39, 0x539d77ea, 0xb9d347d6,
- 0x5a188fc5, 0xebdfb952, 0x3a7cbe25, 0xe8fdd19d, 0x491f5628, 0x97a68f5e,
- 0x845e9d3c, 0xdc79aee3, 0x423d297b, 0xe30c3bdc, 0x218f7848, 0x3c85e203,
- 0x305e2916, 0xe2691465, 0xc787ea05, 0xeeaad70b, 0xcfc0a4f1, 0x6df75c35,
- 0x6bc6fc91, 0xdfebff38, 0x45affcf1, 0x732adba2, 0x1f17f3e4, 0xbe8490cc,
- 0xce179ed7, 0xc92f7c7a, 0xa4937aed, 0xd533707c, 0x4f540dd3, 0x536af557,
- 0xbc7f9f2c, 0x6da9a7c8, 0x0c9b6895, 0x4b65f391, 0x6467fdc4, 0x93e438e7,
- 0xf36a2f81, 0xb45b8397, 0x5b1bcbf9, 0x0c88e7b5, 0x09cf6bf1, 0x3dafdc29,
- 0xa028a63f, 0xf8663f3d, 0x31f9ed51, 0xe7b43a23, 0x99fcdcc7, 0x5b98fcf6,
- 0xcbf9b4ba, 0x1edc2f5b, 0x8fa71df6, 0x9c09479f, 0x995cfa1b, 0xb9d85e69,
- 0x73b0ba35, 0xcec3a26b, 0x1f3b09ad, 0xe39bcc45, 0x7e7613ed, 0x367d768d,
- 0xba0dc7ac, 0xefdc7afa, 0x1ea228fa, 0xcf8ccfd7, 0xdfde513d, 0xfa9b7e8c,
- 0x097ff53d, 0xe1913b3e, 0x71f4815e, 0x875b1caf, 0x22b1d57c, 0x2ef30b2a,
- 0x726995ee, 0xfb83f022, 0xa7be8951, 0x46995d2f, 0x35e67bfb, 0xa93f210c,
- 0x4fc93980, 0x1167659a, 0x9cd879cf, 0x3decf5c1, 0x8c6606f5, 0x462997c7,
- 0x33d0a81d, 0xc35b124d, 0x22658ded, 0xe33561f0, 0xfabb587c, 0xbdd51c70,
- 0xc859dd85, 0xebaac151, 0x0e79d017, 0xa8bde7e1, 0xc623c676, 0x6316b0d5,
- 0x68bbcc1a, 0x47c93b6d, 0x1e3079f8, 0xea1cf6b6, 0xb096dae1, 0x7db7f5eb,
- 0x1ff7f8ca, 0x3c8bf446, 0x2ffbdaad, 0x99ba8864, 0x7e503983, 0x9ac7f7dc,
- 0x152ccfd0, 0x56bb99f8, 0x709d62b2, 0xd27b435e, 0xb79fd05d, 0x4bb8a65f,
- 0x71eb0fc5, 0x3a20cf4e, 0xfefcfd57, 0xcfa3f25c, 0x8e0a4a2b, 0xb8f1c773,
- 0x87bbd241, 0x7659f5e3, 0xe73c70f7, 0x58c3ebac, 0x9d87f6fc, 0xdf9320b8,
- 0x3e50be00, 0x96566ff9, 0x9def9a1f, 0x6326b06b, 0xeecbc5be, 0x5378a54d,
- 0x7e2abfc4, 0x6788263c, 0xf10fb0e3, 0x749f5f2a, 0x91fa2249, 0xff02eb69,
- 0x7e03df08, 0x26b3c510, 0x7e815a66, 0x39a569d0, 0xd7605d19, 0x2ff20643,
- 0x4092d9ee, 0x0d3dc5fe, 0x1f3c4665, 0x096d9ee1, 0x79969fb4, 0xbe30479d,
- 0xa279e955, 0x2a5f70a1, 0x4b4f7bcc, 0xd2d6438e, 0xd137e4f1, 0x09d35171,
- 0x7b277e95, 0x48c9dfa1, 0x69ba03f4, 0x4321ffae, 0x6e8209f8, 0x7d3b41ec,
- 0x64b157e7, 0xffe62e6f, 0xe99bd7ce, 0xc67a2bf7, 0x37ae5e05, 0xc4d26f2b,
- 0x2e7de53f, 0xbe7475c7, 0x22daf777, 0xdd385fa2, 0xde67ffca, 0x8afefc70,
- 0xa1963efd, 0x1fab31ff, 0xc63b739b, 0xb79712c9, 0x96c6ab59, 0xa5f3bfa3,
- 0x8b6fcfd0, 0xc630e938, 0xbfd7e049, 0xf412718b, 0xd27113df, 0x41271807,
- 0x49c621fb, 0xe7149ed0, 0x0772aa05, 0xfb7c408c, 0xafb790b5, 0x6378d433,
- 0xd7e62a69, 0xdde7ffca, 0x5f159d22, 0xa349e3f5, 0xec9b1933, 0xd3d7fad4,
- 0xebfd69a7, 0x4c75830e, 0xd581da2a, 0x8f705ebc, 0x78cd66eb, 0x988c57a6,
- 0x857960f7, 0x8f64ebc1, 0x3de62314, 0x6bb04c66, 0x94d9dfc6, 0x32dbe9ae,
- 0x94f75a15, 0xeb9a7ef2, 0xd40c5777, 0x005ee7f4, 0x5df90cc7, 0x59f92629,
- 0xc626e22a, 0xac5d398a, 0xf597ec7c, 0x001e53c3, 0x683cbf78, 0xf4e1fba0,
- 0xb95ae950, 0xee7ca65e, 0xf312f5bc, 0x9b278802, 0x7d7c91e7, 0xce96347e,
- 0x52dc6991, 0xf43156f8, 0xd0316c4f, 0x0d13b2fe, 0x7cf147f6, 0x925b13eb,
- 0x3dbbf0e2, 0xfccca377, 0xa4ad77a4, 0xcb79d577, 0xefd0561a, 0x45f5cc26,
- 0xcc0f5039, 0x567de3dd, 0x4ddfa3ed, 0x4e50665b, 0xbf3ec88e, 0x1273f444,
- 0x299b377e, 0x8199fe4f, 0x92a7f179, 0xb87075e6, 0x0358933e, 0x8f9b4ff6,
- 0xe000780d, 0xb9b13338, 0x957e874a, 0xf489307c, 0x43322be7, 0x6258adbe,
- 0x1787f3a0, 0xc46f27be, 0xd20a933e, 0xfa65bd39, 0x39b60f7d, 0x5d67e68a,
- 0x6e3021c0, 0x9ea22fe9, 0x5ef2235f, 0x60f5ffd4, 0x9fc11adf, 0x259f47c8,
- 0x01026730, 0x7f0ff3cb, 0x75449c3a, 0x7d3e209f, 0xffeeb8f9, 0x64c6bbd0,
- 0x54fefd02, 0xfd27cbe5, 0xc91260f6, 0x4fde3855, 0xf2feb91a, 0x41481ca2,
- 0x339419bd, 0x3cd5fdfe, 0x41d92383, 0x1a686b7a, 0x6b93adea, 0x6467940d,
- 0xaf1c677a, 0x7c42bdcb, 0xa4e7beac, 0xf083195e, 0xa1ca6c9d, 0x59ef0cef,
- 0x43fd932b, 0x7de3e3fe, 0x971fff9c, 0x7bbf18dd, 0xc637249b, 0x737ce1ef,
- 0xf4e192df, 0x11b3047b, 0xea7a2327, 0xbc69b381, 0x17f6a10e, 0x07bfe4ed,
- 0xe87686c0, 0x5d0e0da7, 0x9f7f0347, 0x4e7358bb, 0xdfdf4d79, 0x9c23c71d,
- 0x17efefce, 0x9ce9df8f, 0x9f13223e, 0x3cdbee9d, 0xf9e8152c, 0xb0d76e85,
- 0xf9ffa007, 0x7a27ef44, 0xfbb46fa4, 0x62ebc43e, 0xfc2cdadd, 0xedb3ba6e,
- 0x866f47e3, 0xb2f4fee7, 0xbe6241c1, 0xc7f4892c, 0xb30bcda2, 0x21bbe9bf,
- 0x787dfcc6, 0x2699d1de, 0x2b173e01, 0x9f30632d, 0x84b99f30, 0x51f8e23d,
- 0x86bcf0b6, 0x73cf1d75, 0xbb145c7c, 0x79b4e306, 0x8f8c7961, 0x8d83f7c5,
- 0x6fc69299, 0xf5c99838, 0xe71d3cd7, 0x38b7886f, 0xb1a631bf, 0x5edeaa03,
- 0x220fbf8c, 0xaa80ed07, 0x33586bb7, 0xb3fd6b9d, 0xff34becc, 0xbf47c942,
- 0x27875223, 0x2af8c354, 0x6b638f2b, 0x51f28c5e, 0xe580aa9c, 0x8e0ff10b,
- 0xe7813ea1, 0x7e5f1916, 0x0177d90a, 0x8675f00b, 0xc193fb8d, 0xe9c81557,
- 0xacaa7f69, 0x346c1b1b, 0xfb81c1bf, 0x79081719, 0x7c966dad, 0x25075e7e,
- 0xcc5f3a3b, 0xd1d85f33, 0xc3d4fb70, 0xa3d9852e, 0x977661f9, 0x2ced6b35,
- 0x79e74bc0, 0xc386f0ab, 0x25898ae9, 0xe66a2c3c, 0xdcab3efb, 0x08937dbe,
- 0x1401c96e, 0x02cf01ed, 0x80951ae6, 0xc79178eb, 0x85f0e1e9, 0xbc07abaf,
- 0x70e19d62, 0xd1ce3957, 0x5b35e5f7, 0xf857c224, 0x847a543a, 0x5d2a71fb,
- 0xbf1cbcaa, 0xd1126d55, 0xff65d4f3, 0x50fed190, 0x0b586f95, 0x79e42ffc,
- 0x5d608f95, 0x2dbf5093, 0x38fa0758, 0x2d3f27a7, 0xc8712d62, 0xdfcc7537,
- 0xd3f72588, 0x473b96fe, 0x4e79e0e4, 0xa9dce987, 0x573f9b0a, 0xeca88097,
- 0x96fcb47c, 0xe3879f20, 0xbdf44afb, 0x5131fc5a, 0x00e7a067, 0x905ff35f,
- 0x909ffbe9, 0xf63e2271, 0x7b557c92, 0x3fac46bd, 0xb9f9eb57, 0xd3825772,
- 0xcbbfe7a3, 0x05784574, 0xdc35af3e, 0x7f5a59d1, 0xe577e839, 0x5bd247c6,
- 0x098f3aea, 0x7b45733d, 0xc5dc77af, 0x4927dec8, 0x4de9af98, 0x3b09577f,
- 0x3eed1f3f, 0x7fac9fb4, 0x3c6bce95, 0x3a55eeb5, 0xf2f8d59f, 0xf0b7da7c,
- 0x8f79fac9, 0x7c4fefe2, 0xd91e65b2, 0xab4f05f9, 0x0c6dde76, 0xd6ca1ff5,
- 0x5fee7dcf, 0x345f6f90, 0x6ab95d53, 0x41c45b8f, 0x9c6157a0, 0x51eb9eb2,
- 0xd5eb8eb6, 0x070f6805, 0x0ebc3d91, 0xe55fddc7, 0x3ff90ebe, 0xc9d93ae4,
- 0x7fb9e7fb, 0xbde613b5, 0x8718a5ff, 0xf56c9697, 0xd5b4bcf3, 0xf6b0f68f,
- 0xd38e0fde, 0x07c94bef, 0x6a81fbdf, 0x139e19ff, 0x42ce2ee5, 0xbf761339,
- 0x6598de56, 0xec223b45, 0xdf1b3fc4, 0xc9be20f7, 0xfef8e2bf, 0xf9e389a8,
- 0xef1cb5e3, 0x51fa5b8d, 0x5351fafc, 0x3eabf23f, 0xf84b92da, 0xf8035cae,
- 0xd15abf26, 0x804d55fa, 0x101f8c6f, 0x3dd700df, 0x6f81147b, 0x1377c707,
- 0xcb5b33c7, 0x781ecadb, 0xebf9d2f5, 0x947bfff7, 0xcf84fd03, 0x9ff27ecc,
- 0xd32adb3e, 0xdfaa6959, 0x7f3dfaa5, 0xa2cfcd66, 0x7be2a67f, 0x3e4080e1,
- 0xc78a97ea, 0x7887177f, 0x2795b85f, 0x9be07a4f, 0xbce85339, 0xbfefcbfd,
- 0xce2d27ec, 0xbe93f50a, 0x98ea5d25, 0xd72bf68b, 0xf96639e1, 0xd5a2fb21,
- 0xdf0b3fdf, 0x7cf0ad07, 0x98731465, 0x464f084c, 0xb9b8eff8, 0xfe8bee19,
- 0xecdcf72a, 0xbb8e497b, 0x31c7bf34, 0x780df989, 0x916b019e, 0xed4bbf68,
- 0x257125d2, 0xad2dcf0c, 0x67363827, 0x69df3b71, 0x3f22caee, 0xc714676d,
- 0x359ba8fb, 0x07a4d1f1, 0x423ff11d, 0x3f20e03f, 0xd79278df, 0x49cef941,
- 0xab5243c5, 0xff3ae842, 0xb8d73f02, 0x9cc482ea, 0xc09dfc76, 0x622fb4b1,
- 0xda14f37e, 0x6d055007, 0x5ef8e859, 0x9cdbcfbe, 0xc7a2f3c5, 0x78054d71,
- 0x1df8939e, 0x1a9e713c, 0x370171d5, 0x3a2ecdc7, 0x9278ef6f, 0xc8cfc1c9,
- 0x07dfa78b, 0xc1e85bb8, 0xb47d9699, 0xf1e61c8f, 0x7b9e1b32, 0x0501aeff,
- 0xf1d4c2ac, 0x73c68632, 0xbefe3f52, 0xff5b8749, 0xdf22ac1b, 0xbd92edbb,
- 0x3a413c27, 0xf381cf6a, 0x8fce4744, 0xfdc59abc, 0xa4e9c929, 0xcc14443a,
- 0xdfef0d1d, 0xebf0a59e, 0xdb3bff62, 0xed8cf400, 0x7a9c9e79, 0x39f9799d,
- 0xf0a535b2, 0x67189bef, 0xb21bd424, 0x31afd34e, 0x9e87fbf2, 0x5d793d9d,
- 0x30ef6306, 0xf43f7ac0, 0xff8f1953, 0x70fbc6e7, 0x3c64d7df, 0xad86ca6f,
- 0x76eaf89e, 0x78eaf33d, 0x7ac164db, 0x6a673888, 0x1ddfc092, 0x0f1fccc5,
- 0xa03fefbc, 0x2ef16f3d, 0x1d7fcebf, 0x9e3275e0, 0xe78f9767, 0x2b0629d6,
- 0x2e55c7bc, 0x52bc6015, 0xc1dbf2b3, 0xc2ecf1db, 0x4246ebc9, 0x70e3a75f,
- 0x29e780fe, 0x1efe6266, 0xcf5b30f0, 0x9c05c8f6, 0x8f1788de, 0x207da14d,
- 0xda244b5d, 0xede6a2af, 0x090f7a55, 0x8e89ede6, 0x307c0533, 0x3e1c534f,
- 0xaf4c8c6f, 0xb8d4b22f, 0xede285ba, 0x173e42c5, 0x45b972ab, 0x6c96972b,
- 0x8ff44741, 0x45336f01, 0xf9a4eb0b, 0xd47bc46b, 0xd9cdd773, 0x36737e7c,
- 0xf2ffe38f, 0x598fbe77, 0xaa8ef9f8, 0xf146d67c, 0x4ff7d5f9, 0xb6546d16,
- 0xe155e68d, 0x7fd7cf09, 0xf91561ba, 0x677fd549, 0xdf443ebe, 0x324c5d50,
- 0xea225576, 0x4999efa5, 0x5b1a66ee, 0x3d2deb72, 0x15e7a9c7, 0x8180b056,
- 0xbe440fd7, 0xd1a3d84c, 0xbfce85b2, 0xeff890ac, 0xc4967674, 0xe720757a,
- 0xbf7cccc7, 0x1ff079e7, 0xc0153df1, 0xef31f817, 0x27fbf8ac, 0x11583fa1,
- 0x7b63d467, 0x73cfcccc, 0xb102c39e, 0xfd413939, 0xd32258db, 0xfbcc8739,
- 0xafac64f4, 0x213ac2ad, 0xcce63fef, 0xe894aca0, 0xea36f73f, 0x811769a5,
- 0x9befa80f, 0xa93884ec, 0xcfb8af73, 0x9df3d236, 0xf67e090f, 0x27fde26e,
- 0x279bfbd5, 0xab9df3e3, 0xe4bffbd5, 0xf3a89ffd, 0x61e3fe8b, 0xdd8457f7,
- 0xdfef19ff, 0x272fdcf4, 0x2d8fd17b, 0x715dace5, 0xcfbf4493, 0x1bd423f1,
- 0x562b0fa0, 0x15cf09fa, 0x2dbc5dba, 0xd0dd7e65, 0xcaab8f2b, 0xed08fd76,
- 0x327b1c95, 0x92f5ed16, 0x67f5271c, 0x6747ba66, 0x8a68bb43, 0xbac235e4,
- 0xd91f11d9, 0xe8bd498f, 0xbd091fe5, 0xf9f0a55c, 0x3cc37c54, 0xfe8bb293,
- 0x9cfe79fe, 0xbb9e63dd, 0x5d9e06ae, 0x66914f08, 0xc0d5f71e, 0x768e5d73,
- 0xda1fd51e, 0x23f9d7d3, 0x2edc2b84, 0x23b1fe2e, 0xec53f31e, 0xe29df12d,
- 0x42ac96ca, 0x2ff17f98, 0xa1556477, 0x82fc25ff, 0x768bb43a, 0xdb83173c,
- 0x3fdbcfc5, 0xb6e5fbe4, 0x60c71bb5, 0x50da001d, 0x0bd358bb, 0xb56cde9c,
- 0xaf38ffce, 0xb4f2fe1b, 0x58b9e91e, 0xd3c9f2d7, 0x926fe768, 0x59777e22,
- 0xde3b9e2d, 0x3525efcb, 0xe03f7366, 0x87cefea5, 0xb20b6f10, 0xb291e919,
- 0x79cf9155, 0xb1e85b7e, 0xe6ff610a, 0x29358b0d, 0x23a2e780, 0x0fb855ee,
- 0x4e436aab, 0x978de601, 0x963e9667, 0xd6f98dfd, 0x6d6f9e2e, 0x0ad6f9e3,
- 0x2829605b, 0xf666f671, 0x32998f5b, 0xa9fe0fc1, 0xb220672a, 0x94796cf0,
- 0x79353fda, 0x0f9e48d4, 0xcfcbfec3, 0xe50c7f1d, 0x83c23f66, 0x83e1f5f9,
- 0x743f51a3, 0xace8c4e4, 0x25fe47a0, 0x089bee63, 0xb7e1acc7, 0x929a7ed0,
- 0x7301d8a8, 0xf89efe79, 0x5c325fe2, 0x38dd709b, 0x6e24f31e, 0x2ee93fa3,
- 0x4dfb8758, 0xbab3f699, 0x91dc63f3, 0x2efff3ea, 0xb666f0f0, 0x3afdda95,
- 0x0820b380, 0xf07efa87, 0x600697f7, 0xd32b93be, 0x50f7e086, 0x0e4a3227,
- 0xdf051764, 0xbdc3227f, 0xdf53e11d, 0x06c7527f, 0x6df1c860, 0xd05578e1,
- 0x0dd200f7, 0xe048d75a, 0xefb890b7, 0x9a3151f6, 0x7609b4fe, 0xe3cd0ce6,
- 0xf4d74b4e, 0xd3f457a7, 0x72bbbf8c, 0xc4fee6a0, 0xfad0c0a8, 0x77b7bf10,
- 0xf7cbc97f, 0x46c6c4ef, 0x3fbdfee3, 0x7df9fdb6, 0xcee9fdfc, 0xfa076417,
- 0x6e770bb6, 0x168f1f7a, 0xb5f40f3e, 0xa1527e53, 0xf69fda7c, 0x839f8ccb,
- 0xd687d4e1, 0xc0b0ce91, 0x60a52353, 0xeb6dfb7c, 0x7bad8b47, 0xae0577e8,
- 0xf3e8dd55, 0x287f516c, 0x1f680560, 0x47bfd7cf, 0x0b3abd79, 0x1d99e75f,
- 0x3c5b9cfc, 0xf012fae7, 0x20f86dfd, 0x40178bfa, 0x97fc83f1, 0x7aa09eb5,
- 0xae6c9adb, 0x9632ebaf, 0xf64fd1e8, 0x65f68b40, 0x78ade80c, 0x3b409be0,
- 0xf70dbc1b, 0x72c4e5bd, 0x54c2fdff, 0x8fef9bca, 0xfd9ff9e6, 0xfbf409c9,
- 0xc69b8bc7, 0x0bbaf5d2, 0xdbff3431, 0xb5f68072, 0xa8935f79, 0x7d31314e,
- 0xcf5c4ad6, 0xdf4401ff, 0x80006da0, 0x00008000, 0x00088b1f, 0x00000000,
- 0x7dcdff00, 0xd554780b, 0x399ef0b5, 0x67091e67, 0x99212726, 0xe4c21024,
- 0x4e010249, 0xaaf08042, 0x9e180903, 0x6831004e, 0x0cfde1d0, 0xaf4a8809,
- 0x04819bf4, 0xa86c1808, 0x3bd15014, 0x6ad480a4, 0xa6a3ea6f, 0xd004c7d6,
- 0xa0d2941b, 0xdef6b7fe, 0x22c01b5b, 0xda046a28, 0xfad2de9f, 0x3ef6b5af,
- 0x82499cc9, 0xbf7b7b72, 0xdbe3ef9f, 0xb3ef6759, 0xd7bdeb1f, 0x6b4cfb5e,
- 0x7eef2074, 0xff99b185, 0x1b297b72, 0x97dad8c6, 0x1e609e4c, 0x857bd2c0,
- 0xd35ca0eb, 0xbeb19530, 0x5356b308, 0xd731631c, 0x046c61ef, 0x2c018cc1,
- 0x64ec728d, 0x435a5031, 0xc3c64fd9, 0x3b43ab33, 0xeaac66ec, 0x37bd147a,
- 0x3011d8bd, 0xdbbc7d43, 0xc648d8c4, 0xe953ed2c, 0xcbd7c9fd, 0xfc6bfea8,
- 0xfd631b77, 0xaf54e9dc, 0x438496c3, 0xdb0522f2, 0xb4fda89b, 0xaca843eb,
- 0xca873ebc, 0x147e7277, 0x84fac3ef, 0x17fa536b, 0x526f1c02, 0x64ac4a71,
- 0x628d999c, 0xa33b7eec, 0x47ab577f, 0xaba530c7, 0x72d2c8df, 0xe81e625d,
- 0x44dd76cf, 0x8f74c0e5, 0x6c604ee6, 0xd976a6d6, 0xec51eb8e, 0x8034e1ea,
- 0xcbddf28b, 0x93debaf2, 0xbab7cd8e, 0x7bfbc287, 0xd03d58ce, 0xe2ca0dbf,
- 0xc64afab0, 0xdd794d3c, 0x36e51bc7, 0xdb193ad3, 0x6c2ce54c, 0xcbb3ef07,
- 0xef3865df, 0x6f3e557b, 0x912611b6, 0xb60658cc, 0xbf7ae84f, 0x60c1d00d,
- 0x6d97815e, 0x77f0c3c1, 0xd4afba51, 0x4db4fd0d, 0x602fe564, 0x6a5b723f,
- 0x371fe399, 0x38b799ff, 0xfe6271ff, 0x46d896bf, 0xb7d7efec, 0x81e6d6dd,
- 0x3c3cb579, 0xeee48462, 0xb75ef7ea, 0x76abf795, 0xcf4060dc, 0xb8fa37aa,
- 0x66fac277, 0xdc208f02, 0xd82dbaf1, 0x99cf4698, 0x5b4b1e29, 0xabea09a3,
- 0x5ed91d9c, 0xcdf8bf18, 0x6ff210a8, 0x32519bcb, 0x9f7e7183, 0xe917bbe9,
- 0xa0e6fc58, 0x26139312, 0x464d9af9, 0xd036583e, 0xef3e1f73, 0xf1bdbe6d,
- 0xd69c6009, 0x535fc911, 0x18814cca, 0x1d5f6fe0, 0x82859397, 0xef5d173f,
- 0xc84fb043, 0xc4ead5cf, 0xabb74829, 0xb0d2609b, 0x4c9b458e, 0x75825f43,
- 0xcb43b731, 0xeccc3c02, 0x730b60bf, 0x69995ca2, 0xc48733bd, 0xe9a06b06,
- 0x06b1eb9a, 0x9ebcabf9, 0xbdaffd46, 0xeb9e97de, 0xc848b672, 0x19f90d87,
- 0x9f8225e0, 0x197e45ef, 0x1b8725d3, 0xe28f7dd3, 0x80d667fa, 0xbe78c3bc,
- 0x2885c92d, 0x62fc5d47, 0x80af9155, 0x8596925f, 0xcb4d4dc9, 0xf42a987c,
- 0x7e25ef1f, 0x71650259, 0xc152fd58, 0x7b789107, 0x65f916ec, 0x48bf68b3,
- 0x01996509, 0x28ea960f, 0xe7cc0b6d, 0x0a7bbc4a, 0x0efd65e2, 0x16f5bf8e,
- 0xe603b16f, 0x9371febb, 0x8b619406, 0xa8ec3947, 0x587d4687, 0xf185f56d,
- 0xc3ebfced, 0x30f01b98, 0x95267ae7, 0x83be01fe, 0xd785feb8, 0x0d3a09e7,
- 0x8bb992a3, 0xd8c5cccc, 0x1baba406, 0xe9c45427, 0xad77e62c, 0x43e2747a,
- 0x53b5fe30, 0x88bfaa16, 0xa9802d78, 0xe34f027a, 0x9b412cbc, 0x75e61076,
- 0x2a02c2d1, 0x7ef169d0, 0xdfa00589, 0x46fa5025, 0xd83d52d0, 0x1481f6ce,
- 0xb176c16c, 0x805b13cc, 0xe6f584f8, 0x86be31f0, 0x6d4c97ff, 0xfd410fd9,
- 0x961b33e7, 0x81e03399, 0x86412a74, 0x82fe7e75, 0xbe7824c4, 0x2e5bdd72,
- 0x94ab1e58, 0x50aaa60e, 0xcc14c1bf, 0x7be280b6, 0x86bdf646, 0xbbd3e07a,
- 0x08adfe9b, 0xf0dc7dda, 0xaae913a2, 0x0e49b5e3, 0x4d3f6165, 0xcc00cf80,
- 0x2a5ea9bd, 0x6c342a0d, 0x5da1b29f, 0x73f3adfc, 0xbaaf9f24, 0xba78419e,
- 0xfa1b6d5a, 0xf031f212, 0xf5d73e2d, 0xae3aeaf1, 0xbefd75d7, 0xcebff056,
- 0xd73295d7, 0x4c4a955b, 0x6e169030, 0x13bcca6f, 0x4c72ef91, 0xb70b165a,
- 0x8e8f8d37, 0x32f83945, 0x5d61ab5e, 0x839742f6, 0x8049fc57, 0xa47b2ebc,
- 0xc7ae81cb, 0xf3aebd75, 0x26af6ebd, 0x2f2fe4fd, 0x79fc3bfe, 0x81d7cd32,
- 0xe64d307c, 0xec9a6b76, 0x1c9a3e20, 0xff23265f, 0x79fd7b7c, 0xb3cfe856,
- 0xb6b9fd06, 0xc7f9fd17, 0xf387945b, 0xda967f42, 0x3cde7dd8, 0x3b67dfae,
- 0x4a2bfaba, 0x834b649f, 0x1334947e, 0xcd47fbb5, 0xf3e3495b, 0xfef3b6f8,
- 0x6fceb12f, 0xd303fbd2, 0xa46fd4ac, 0x1fd0679e, 0x5f2ff9ea, 0x1da20dcf,
- 0x5d8188f8, 0x5af7bb40, 0x6161f71f, 0x444ec807, 0x666f04c7, 0xb9927e07,
- 0xa7e22078, 0x4ee03b07, 0x80ec3bfb, 0xbcba57ce, 0xcba1f2e8, 0xe8fca443,
- 0x11fd30f2, 0xa421e62d, 0x30e6200f, 0x781c8fca, 0xe951d70e, 0x728f93ee,
- 0xf811cba9, 0xdd672461, 0x9b9083ec, 0xda31392e, 0x742e5d0b, 0xa6e5d139,
- 0x52c5c852, 0x3cba1721, 0x1e9a971c, 0x3def0b1b, 0x432be697, 0xb1f2e87c,
- 0xbb4885e6, 0x313f2bd0, 0xf1a5a7e4, 0xa9f90cd5, 0x7e70ca12, 0x4fc2f5b2,
- 0x9f916ef3, 0x9dbed24a, 0x8d32b11f, 0x40ff11fb, 0xd6995a7e, 0x0ab15fb3,
- 0xca7fecf9, 0xfd5ab8af, 0xcc37429b, 0xe8216ae7, 0x7e2eb4d9, 0xe32efe9b,
- 0xf806437e, 0x46b450d9, 0x5ab675f3, 0xb06b0407, 0x1aacd7dd, 0x01fba8f1,
- 0x7dee914b, 0x27f4f8bb, 0xfe71ff60, 0xc15bfd3a, 0xedf75fff, 0xd9d11df4,
- 0xf566df16, 0xdbbd21e4, 0x37bff60c, 0x5bb1f17f, 0x6fe6f3a4, 0x4243e749,
- 0xfa0ffc6f, 0xd17a878b, 0x1eff8713, 0x862cceba, 0xfc21fb3f, 0x3c67af7b,
- 0x02fbe7d0, 0xa2f39c0e, 0xd22bccbc, 0x3c1bdbeb, 0xe01fa899, 0x8234b1cf,
- 0x0f09d987, 0x56db3e02, 0xfe9cf302, 0x007d6758, 0x8f8f27eb, 0x8f33ef11,
- 0x3fb57589, 0x5b51f691, 0xd60bda3d, 0xaf8dedc0, 0x0d0ef65d, 0x76010b83,
- 0x1145c184, 0xdede01f0, 0x9533b729, 0x972084fc, 0x54dfe82b, 0xfd15f340,
- 0x9e65fe09, 0xcf015713, 0xdb1354b3, 0x8aaa7409, 0x55d6f83f, 0x26cd6bd4,
- 0xe1877266, 0xebc97021, 0xf6fd0149, 0x9fc0499a, 0x37c079b7, 0x0e25fbb8,
- 0xabf0767f, 0xfa2c8086, 0x8d6c7f05, 0xc9a5b740, 0xbfa091e4, 0x60a64535,
- 0x7c775a7a, 0x67c9d67f, 0x54c07cfa, 0xd667df1a, 0x1f7b5bf8, 0xa7ef4de9,
- 0xdb21fbd3, 0xd77f8c2d, 0xf609e678, 0xd29b0fe0, 0x292c5db9, 0x3eb1e98c,
- 0xf8e25d2a, 0x3eb001bf, 0xd39a3c3e, 0x91e5f7c4, 0xf9d363ed, 0xb3666db8,
- 0x3763a7c0, 0x559b59f2, 0x1bb2b7c7, 0xb1993df1, 0xbe413e4e, 0x4e09f181,
- 0xeaca5469, 0x4f5cbe64, 0xb66ebe04, 0x74d32fde, 0x5f0ba63f, 0xd97a0881,
- 0xabef826e, 0x6ddbe03d, 0x33743f7c, 0xdbb9fd7a, 0x576f82fb, 0x31ec7ce8,
- 0xec8c7bf0, 0x898cfe25, 0xe001a937, 0xa8deb5c7, 0x742fdc7a, 0x195267c9,
- 0x88ca2de1, 0x4bf92ea7, 0xc8512b2e, 0xfdf5123f, 0x7afca377, 0xb9ed9dcd,
- 0x0d7cea3c, 0x5e00e7ef, 0xf7c695d1, 0xdbf7a547, 0xbe23c81d, 0xe5827aa0,
- 0xca4779b0, 0x3c045363, 0x857e423e, 0x40fe91fc, 0xca78007b, 0x7f16fd42,
- 0xe30eead6, 0x7f053b93, 0xe5626e7c, 0x26db4fa8, 0x2db23f71, 0xa40f979d,
- 0x02ccb8f3, 0x754b97c1, 0xc30e8a7e, 0x427f9183, 0x5b095fb8, 0x7e69e137,
- 0x63cf2ebc, 0xbac066cb, 0x7d78e2da, 0xdda8e355, 0x382e9481, 0x8d75bfb2,
- 0x2f10cb63, 0x8a07fd9d, 0x997da0ce, 0x40f6f02f, 0x813398e3, 0x1767413c,
- 0x7fda19d9, 0x50047f01, 0x7f22541f, 0xc7f3ba98, 0xfc6ef484, 0xdf788819,
- 0xfbc9b963, 0xf7dfddc5, 0x2ccfbc44, 0xbef2b7f1, 0x088cdba0, 0xd04696ba,
- 0xae0224b5, 0x41a0e1d0, 0x797aeaff, 0xadeef351, 0xeac7982e, 0x5967a0a3,
- 0x2d4f3f38, 0xad5fb943, 0xed3bfcea, 0x176bf20c, 0x3c274f3f, 0xf9d26ecf,
- 0xd46ec675, 0x87a865c3, 0x73c176c7, 0x3c110f50, 0x1313ccb3, 0xed66af6e,
- 0x57757b46, 0x0efede9d, 0xad777f6a, 0xea979fde, 0xcf423a75, 0x42d74465,
- 0x3ecd5edd, 0x5eabf583, 0x4d1fefe3, 0x9026739f, 0x68791379, 0x81cbc088,
- 0xd1103808, 0xd837cf7e, 0xf788dab7, 0xd7d44537, 0x23fbc047, 0xfbe33ae0,
- 0x4898970b, 0x3f02170e, 0xe5222120, 0x9a3f9232, 0x9cfd3bd3, 0x526e7b4e,
- 0xc833bfc8, 0x0e1af4d5, 0x95f74b1f, 0x706129d5, 0x2e32c2e3, 0xf01a3017,
- 0x7ff185a5, 0x120373a0, 0x17a583f0, 0x1bd4d9bd, 0xda44e65f, 0x7bff5e7b,
- 0xfd1933fc, 0x4bf06665, 0xb8464b8e, 0x0ef31245, 0x90d99d54, 0x78750f87,
- 0xa7ee196d, 0xae33efa7, 0xa2b3f60b, 0x49594d7e, 0xd6c45fb8, 0xd6c27994,
- 0xf29fb7a9, 0x1c25afd7, 0xd5c6c3ef, 0xbea08765, 0xab285262, 0x5e38cb1a,
- 0xd094bd82, 0xf889575e, 0x25d794cd, 0x8acbda2f, 0xfad650e8, 0x35883f70,
- 0x5b3ae365, 0x3e88961e, 0x0fa01a81, 0x732169e0, 0x2eced15b, 0x832b1e66,
- 0x4c4b5cad, 0xf023c6cc, 0xa587f1de, 0x3fa7688d, 0x85d7d8da, 0x19d1a1fb,
- 0x3c717f7c, 0x296ba066, 0xee7d2dc0, 0xb2db7d23, 0xc795327d, 0x0eb6cf24,
- 0xdbffb195, 0x929970f8, 0x8431f58b, 0x0fe9aba7, 0xf9066d95, 0x9bba53f8,
- 0x538beaf0, 0x6fe8cd5d, 0x8c30b4ef, 0x51a63397, 0x2ee1691c, 0x9c4efe5b,
- 0x2e21e6cf, 0xfd173ff4, 0x324a6cb0, 0xd5b45bb4, 0xd51fa1a2, 0x7153566e,
- 0x939dbe7e, 0xa4bf58ad, 0xdb819456, 0x6ff37ca9, 0x4271aa3f, 0x4ca78efb,
- 0x9fb4235a, 0xdde9ad70, 0xaf2f0061, 0x4490d0cb, 0x33375c6f, 0xb739c615,
- 0x0250507f, 0x551f3cbe, 0xde2cf6fd, 0xe5fb619e, 0x67a7dc37, 0x497b6215,
- 0x2fed02dd, 0x9ff473c0, 0x1a90ec2f, 0xa72f384d, 0x4b04da23, 0x4657f0ba,
- 0x5b0b9cf1, 0xcf8c416d, 0xf77c539d, 0xf671c7ee, 0x67d3d05b, 0xa76e4c17,
- 0x9f10f009, 0x292cb3b1, 0x04db9f19, 0x2ec6773d, 0x685f3904, 0xb21fe4ee,
- 0x3962cb27, 0x1da3ff1c, 0x1d618765, 0x441f1e17, 0x195dabf1, 0xc00c849e,
- 0x1e991df7, 0xa3e79617, 0xf37addb8, 0xe87dd26f, 0xf2f2ffc7, 0x97f21722,
- 0xd3cb833b, 0xb917d71b, 0x55f98516, 0x89973ecb, 0xbab4de0f, 0xdf7ce037,
- 0xc2601e8c, 0x41f0367d, 0x2f938c5f, 0xe016fb11, 0xf62f8de7, 0x97fd5fe0,
- 0x1e5ac7f0, 0x36ef1849, 0xd27ef5f0, 0x00dfb49f, 0x87e33f38, 0xc7c003bb,
- 0xb236db1f, 0x9b8c28f3, 0x75dc52fa, 0xe07a1309, 0xee20a8b9, 0x535258ab,
- 0xa6fc7876, 0xfb450e53, 0x841c05df, 0x7b41dfd7, 0x2efdf7dc, 0xf08e1ff0,
- 0xfdbd0bf3, 0x8023a772, 0x0e27c5ce, 0xf8f48c87, 0xf85ff648, 0xecb7bc2e,
- 0x81d90b29, 0x6c254f65, 0x8171c0ea, 0x16ae306f, 0x867f2eb9, 0xabd5d685,
- 0x6523b25c, 0xfbe12925, 0xbfa4c395, 0xe9cb937b, 0x0ecb8719, 0x972ef5e5,
- 0x9fae55cb, 0xf1653ca6, 0x1f2d3ca2, 0x70d990e9, 0xf53d26c6, 0xcfc461d6,
- 0x055175f2, 0xf2f89836, 0xaf446ca7, 0xa0238776, 0xe9cfbd42, 0x9ca16390,
- 0xd6f5c19f, 0x3f2e0ca6, 0xed9312c5, 0x62d65405, 0xcc0af5bc, 0x97c02fa7,
- 0x77b63e36, 0x29f38c34, 0x0d1bce0b, 0xe1e2bbf8, 0x25e57a7c, 0x4c8ee289,
- 0x4133c8f6, 0x5c60ae5f, 0x7c9e544f, 0xfe113ad1, 0x5ff562ac, 0x5c1fb049,
- 0x067cbd51, 0x06570bee, 0xc5dae72d, 0xb16bfc5e, 0x55b3d45c, 0x5bd811fc,
- 0xfefebd63, 0xfa4ed61a, 0xa229b2a3, 0x4ff6fabe, 0xd5537e30, 0x3ebe7c6c,
- 0xa17f11c3, 0x7258c30f, 0x5d8a6001, 0x3364b6a9, 0x0572ea58, 0x5dd60ce4,
- 0xf344c07c, 0x0a51be5f, 0xc5fe60da, 0xf8dc797d, 0xc1f03f63, 0x407f5a20,
- 0x1ef97805, 0x33967f6e, 0x7f0ed053, 0x1d607ede, 0x0a2f31c5, 0xc4d0b37d,
- 0xe7e7c8bc, 0xdc54b4a3, 0x2a7b2fef, 0xfcbcf08a, 0xf6ff95e9, 0xbed7bc38,
- 0xf87c6679, 0xf90ebafe, 0xd999e383, 0xf9fabae3, 0x52f7f364, 0xff8a0e51,
- 0xb0c9f619, 0xecb1e5de, 0x90d3f3a7, 0x6ea9c96e, 0xf2ddaba5, 0xf3670f2d,
- 0x86cfb076, 0x21dc2f75, 0xcbd83ad1, 0x2087b236, 0x3e386af3, 0xb49ed497,
- 0x633db95a, 0xd9f84baa, 0xf5e7d46e, 0x7fbc126d, 0x8525ea0e, 0x0f6817f0,
- 0x87df978b, 0x3e93257d, 0x2afae1f1, 0x66fba6cc, 0x561d3f53, 0x3317ef94,
- 0xd9f45c78, 0x2ee7ee0c, 0xa5eed54c, 0x36a3f438, 0xef1a4b6d, 0xe6251a47,
- 0x4abcfb01, 0x3a32db73, 0x8db9fcc7, 0xb5552be2, 0x27289e51, 0x2f3c4bed,
- 0x3255bf40, 0xd871ad93, 0x1ae75f2f, 0xf01fd737, 0xcf1943fc, 0x3f5c1c67,
- 0xbe02c656, 0x6638ce15, 0xfc4bffe8, 0x97f7832b, 0xfdebac3c, 0x5d4df1ce,
- 0x10c3b9f5, 0x95e77d5f, 0x979e3ce3, 0x19017e48, 0x9fa1168f, 0x0234bcf7,
- 0x770bd7f7, 0xfa829f1c, 0xf2cff576, 0xe1757c55, 0x7b27df4f, 0xb9d05ab1,
- 0xb47dfd1d, 0x0cff001f, 0x7e4253ca, 0x0f8f127c, 0xd0f8129d, 0x57d7ade9,
- 0x38f0b0ee, 0x5475e83d, 0x7f9b9524, 0x3a56fd43, 0x6fa85cda, 0x8cb65f2b,
- 0x6bfcbd42, 0x5fb43f9c, 0xf8c079b4, 0x167f810f, 0xb4546259, 0x33026b4f,
- 0x69af08ad, 0xf5dc1130, 0xf22a425e, 0xafb567e3, 0xce4f9138, 0xd0b28547,
- 0x8bac750e, 0x01711ad2, 0x7dcf8f2a, 0x88d59b56, 0x6a259c71, 0xf504c39b,
- 0xc464364b, 0x48febea1, 0xfeb1590d, 0x3334a6a3, 0x1d551ec2, 0x1e47b08f,
- 0xa067f04e, 0xff049aba, 0x6b59bea0, 0xf35cf4e2, 0x3a6b71dc, 0xac55778c,
- 0xdfe7f3f7, 0x4f78c6cf, 0x365b6a65, 0x77a011da, 0xf3c47f76, 0xc3b226b3,
- 0x3c939f6b, 0xe8bac351, 0x0de916bd, 0xd04ab5f2, 0xaf4bed79, 0xbf7c843c,
- 0xd05de916, 0x6f805f9d, 0x17f3d04f, 0xfc614e0e, 0x17c813fd, 0xb802ddba,
- 0x377182d6, 0x09af872b, 0x25e7803e, 0x8f2079fc, 0x11e826f4, 0xf92337f4,
- 0xc6fa37bd, 0xb7fb7266, 0xf48db368, 0xe7266c6b, 0x2f1df6fb, 0x9f7e913b,
- 0x6dfc7f3f, 0x7ca94f3c, 0xbbb2ac01, 0xf817be07, 0x3bf5c2a8, 0x4fe4fe69,
- 0x9d7ae154, 0xe4efeb5d, 0x556f2173, 0x5f4faf8c, 0xd62c956f, 0xf78bd7af,
- 0xbc8532e3, 0x97af8130, 0x12f97106, 0x8af284f2, 0x3ebe997e, 0x5f7f1c5f,
- 0x4ca2cfe7, 0x62699fce, 0x726d4c9d, 0xbe907e22, 0x7f8067a8, 0x4251d63c,
- 0xcf93406f, 0x0ff3067f, 0xff3e97a3, 0xd00f3152, 0xb8d89e6b, 0x9bb63a2e,
- 0xce9e8ad9, 0x3933f32f, 0x9add9cdf, 0xf80cda98, 0x59f60cfb, 0xfc006794,
- 0xa78d872a, 0x5e3e8df3, 0xa6ca4ff1, 0xffa1bae1, 0x8faff610, 0x8fa051fb,
- 0xc47cfd8c, 0xf3e87cb8, 0xb8b2e5d7, 0x7cb4c166, 0xdcfbb627, 0xeb879191,
- 0x6697e3e6, 0x07bef4aa, 0xdf7803fd, 0x38a26cd3, 0xafb159f5, 0x15f5bb3f,
- 0x2ebca2e7, 0xde229f7e, 0xabb27fc3, 0xfe753cfb, 0x9a67e30b, 0xbbf6f167,
- 0xcfac21a6, 0x752f9237, 0xc9fce9bc, 0xdf902536, 0x55a7c912, 0x38ad6729,
- 0xdd73e45e, 0x718f397f, 0x5fff9416, 0xff248298, 0x6644ecb5, 0x7f865d98,
- 0x65d51b0a, 0xb3af361f, 0x51cb7b51, 0xbd75076e, 0xaaebdbaf, 0xc425cf78,
- 0x79328ff7, 0xf56ac91e, 0xf42736c4, 0x36e3e633, 0xfdd60f3a, 0x42d709c5,
- 0x95c60c52, 0x082b4a5e, 0x2e6b77b7, 0xadfe209f, 0x70db6d64, 0xc770b3ff,
- 0x234733fb, 0x42d8fe9f, 0xb70b2fe7, 0x1fa2b64e, 0xe2f0f2be, 0x73ff4851,
- 0x5d9edc75, 0x04791daa, 0x7573e8fd, 0xe716b98f, 0x53c57be1, 0x85f3c2c6,
- 0xbe89f3bb, 0x66daa3e7, 0x80f1dc22, 0xbde11ac4, 0x6e478771, 0x71e01bba,
- 0xb8b1818e, 0x490e8fce, 0xf8c36325, 0x37530961, 0x9b7e8ddd, 0x7ca2a31c,
- 0x5af4247c, 0x6bd3858d, 0xdaffe097, 0x79cb92ce, 0x364d4d71, 0x1c77979e,
- 0xf80a7d04, 0x9bbab0a9, 0xebee3842, 0xa80fb489, 0x524b6d82, 0x935b9d1c,
- 0xcac2b4df, 0xf405c9ec, 0xcf0c9edc, 0x1eda5a4f, 0x7c9cf5c0, 0x19bf91c0,
- 0x18dd2b71, 0xbbfb88b5, 0xe7e03724, 0xbe3af8d2, 0x0bd479f4, 0x4fec8b3e,
- 0xfd15bf7f, 0x627fd47c, 0x7f6a97fe, 0xd6ed0f3c, 0x7159a3a5, 0x5e4ffeb8,
- 0x3f43aa8f, 0xd70b13e7, 0xe0ff7a67, 0xee1c7d7f, 0x65bf8127, 0x32bfc180,
- 0x1f67c0c0, 0x2db5fd1b, 0x33a7af34, 0xce95fe8d, 0xb2eb15af, 0x04f3c262,
- 0x99e3f9ba, 0x744796b7, 0x02880fd9, 0x318c5d16, 0xf6ef8c0c, 0x6d8bebf9,
- 0xd8378fe8, 0xf3ac1b54, 0x3c77e463, 0xe2597a6f, 0xe73b00fb, 0x1e5f8fff,
- 0xdefdc411, 0xf0e4ffb2, 0x105326b2, 0xec4ea553, 0xfb612ede, 0x25ffe0a5,
- 0xdbfcc29a, 0x01e7bb3d, 0x9a2bb3db, 0xb4325b6f, 0xe79472bf, 0x12b5403f,
- 0x9dbed7e1, 0xf7dffeec, 0xc178f567, 0x6bbc74af, 0xebbc434c, 0x39f7d6f8,
- 0x145f026f, 0xefe17415, 0xf20aff0b, 0x7dfb2f67, 0x3a697e54, 0xe438e8fb,
- 0x868c4767, 0xe6cbf372, 0x48fea4c7, 0x6ff297f7, 0xac757ee0, 0xfca2a312,
- 0x48dfe17e, 0xfd978c87, 0x74ea54d5, 0x1365e3d7, 0xf7a16a5e, 0xf11e68be,
- 0xef7838da, 0xeb86250d, 0xf7cf0f6f, 0x646fa488, 0xebfdc7de, 0x73e22746,
- 0x7e9f5d7d, 0x9f59d397, 0x1747a7f7, 0x2d5d713b, 0x6d7df64f, 0x4fb7d20c,
- 0xdafe8a8c, 0x71f79172, 0x13d73f61, 0x4731ed17, 0x2f9d0066, 0x62e3981e,
- 0xb69737a0, 0xcf879dcc, 0x526ebd97, 0x5ed75fd1, 0xfee2732f, 0xbb720fea,
- 0xde12c553, 0xe47ce10b, 0x697a84a0, 0x839b296c, 0x6486c7ed, 0xc67e86e6,
- 0x32fce0cc, 0xc41cb2e6, 0xe0cf9f83, 0x6e33c539, 0x033c5344, 0xbcc5f5fe,
- 0xe0bfa58e, 0xef1d1071, 0x9c6c7efa, 0x1030f758, 0xf177e243, 0x3f88b8bc,
- 0x8bc0e4ff, 0x4bbfb0b3, 0xce2a2c87, 0x16438bfb, 0xec157fea, 0xde30cca3,
- 0x5f7ca3c5, 0x1a547082, 0x7fdf33ca, 0xfbe26aac, 0x1675ca8f, 0x3ba6358f,
- 0xb587165f, 0x3c1efdc3, 0x2bb8e373, 0xfcea1f05, 0xd7c3caba, 0x1cec0ab7,
- 0xf89bf7ae, 0x6d359637, 0xc6f5bc43, 0x7f96dfc7, 0xfa8cb333, 0x7b6f93a2,
- 0x578117e3, 0x5be47f94, 0xed562f9d, 0x71ece7e7, 0x9113f94d, 0xd13e74ff,
- 0x12604bf5, 0x5a7b41cb, 0x98396563, 0x47301397, 0xca17a86b, 0xed05b714,
- 0xf6f89cc0, 0x23cf4412, 0x4abf5c59, 0x198f66c5, 0x8d8d51ed, 0x78b747f4,
- 0xc7d71677, 0x283e6421, 0x7952ccef, 0xa6ab25be, 0x825e857d, 0xed0032e3,
- 0xb89f5976, 0x49a1ba3f, 0xd9c6e1e9, 0xd975f032, 0x3207b8b8, 0x87bcc634,
- 0x4478728f, 0xd40b48dc, 0xb333d2cb, 0xccae004b, 0x0ac94cf2, 0xe1d2f7eb,
- 0x1eb801c4, 0x9f153e78, 0x37de28ff, 0xea246b23, 0xf9f4857f, 0x618ea697,
- 0xdabad31b, 0xf1dd799f, 0x5ddd2fd1, 0xa585bb70, 0xeb08796a, 0x9ee5e5f3,
- 0xec1ccf2c, 0x22f9f227, 0xde52b6c6, 0x3f5fe05c, 0xfe04ff44, 0x8f40ed79,
- 0x2d5f043b, 0xa4212bb2, 0x5cb3ab33, 0xc037f4ee, 0x8c5a6015, 0x259b748c,
- 0x390ee4f8, 0xe7ef82d4, 0x82f55ab2, 0x03a25c9d, 0x5dedf75f, 0xd80603af,
- 0xe03fbd05, 0xb02d2f87, 0x136be03e, 0x1046dfb0, 0xb120131d, 0xe998f402,
- 0x33fd7fb5, 0x60135bf6, 0xe78451ed, 0x10c2f50a, 0xccface0c, 0xd959435f,
- 0xe30c39c7, 0x1c579e1d, 0xb8e80521, 0xc43ef9fe, 0x1f852bff, 0xc4457cc3,
- 0xbe541bcf, 0x4b1be61e, 0xe080f6fc, 0xacfc4fb7, 0xf044133a, 0x0bec7673,
- 0x70f1e619, 0xc461ef94, 0xa9f31afb, 0x946ef5d4, 0xfa271ad7, 0x54ff9f19,
- 0xac3550d2, 0x3b24fe11, 0x5ee42094, 0xf506dd0a, 0x8db969ad, 0x0ab66f68,
- 0xc69cb97e, 0xd81c3f68, 0x3fbca36c, 0xea78e376, 0xa69700c3, 0x3ee1aedf,
- 0xb6cff2f3, 0x3a052e67, 0x38bd40d9, 0xa1539d61, 0xb75822cf, 0xce896005,
- 0x4f448381, 0xe1380fa8, 0xc7b4b6f9, 0x319f3952, 0x4eb5ca2f, 0xddef1d1f,
- 0xa34301e8, 0x33b669df, 0x732bee0b, 0xe51501d9, 0x27cba74f, 0xe01bc076,
- 0xfe6e327b, 0x7fac1f41, 0xeb7ffb99, 0xa613ac4d, 0xfb374eb8, 0x9ff916f7,
- 0x83016e20, 0xf8b0397e, 0xa2c3d9db, 0xe21c5683, 0x81e2ed96, 0xcaf51ee2,
- 0x257ae8bf, 0x1f93e59f, 0xf1844b82, 0x93368b96, 0x8cb70aa5, 0x6bb049eb,
- 0x9feb17c8, 0xc3bb20ca, 0x8590fc66, 0xfa0763b7, 0x4b6cbf12, 0x2b0e8893,
- 0xd7944d9b, 0x3fb9b338, 0x8cd54373, 0x3a54bee6, 0xf3d327af, 0x2dde474b,
- 0xd3877ae4, 0x8933e669, 0xe88f2893, 0xea544199, 0xf82f58f3, 0x15f3c74e,
- 0x1cb3c72f, 0x1e37ddc8, 0x2d5a13cf, 0x3f26e82c, 0x35cfd784, 0xb4afde11,
- 0x7f91979e, 0xb1304ee6, 0xd14b00be, 0x496dcf9c, 0x01eee666, 0x9f4136bf,
- 0x73347728, 0x6a0bed87, 0xf88d9ca2, 0xda780b1e, 0x97701f70, 0x2727d768,
- 0xa74ed0ce, 0x8e813ce7, 0x331594bb, 0x9ddb1d70, 0xbf915a53, 0xc33f5a1c,
- 0xb14936b8, 0xabcc1f20, 0xee63d230, 0x196c235c, 0x5be915ff, 0x73e378cb,
- 0x5f08c79b, 0xcb98e9d4, 0x18e9c372, 0xfa0f3f86, 0x363c57e1, 0xdee63f8e,
- 0x79e01e37, 0x7cc3f861, 0x32292b96, 0x147b6fe1, 0xade017c7, 0xa63cf911,
- 0x58b788c8, 0x7d4f118f, 0x48f88d4b, 0x9bd71af0, 0xa86e9e58, 0x360df64f,
- 0x515ff7d4, 0x54078060, 0x1fb4358f, 0x019271b8, 0x334c0b4e, 0x9ba8cfb4,
- 0x1ab3806d, 0x1fb436ee, 0xa1917fb4, 0xcab8373e, 0xe8e43f50, 0xb43c037a,
- 0xed0c9fe9, 0x316f3787, 0x7687e7d4, 0xb447ea1a, 0x8f00c0fe, 0xd0c27b6c,
- 0x8d87f47e, 0xed31fa86, 0xc7ea1acf, 0x00c17c5d, 0xd578e84f, 0xebb6fed0,
- 0x44f00cc7, 0x7da1aef6, 0x037dfdb1, 0x0ffd593c, 0x93dbfb43, 0xa7ea1bce,
- 0xd4333fba, 0x6ab9cf4f, 0x7f6a6780, 0xb6afb431, 0xa36546fa, 0x265d2aff,
- 0xc059aab9, 0xeb4aeae5, 0x71ca3b1c, 0xdff03651, 0x7fc9d610, 0xd29ed0e3,
- 0x62a5857e, 0x34b264fc, 0xd9f2443e, 0xdf70d26c, 0xe4af6911, 0x8c1ebccf,
- 0x4c57b1ab, 0x06234f74, 0x361c8ecc, 0x0ec7ac7e, 0xb82ec41b, 0x806aa96f,
- 0x8649bc13, 0x6ee589f6, 0x2fb27d43, 0x7fdf50c7, 0x07806685, 0xda191754,
- 0x31e8dc0f, 0x528169c0, 0x3a8cfb43, 0x6ace01af, 0x1fb43728, 0xa867dfb4,
- 0x30ae0dcf, 0x5a390fd4, 0x3687806d, 0x1fb4346d, 0xd4301cde, 0x0cea87e7,
- 0x1b5a23f5, 0xb6c8f00c, 0xa3f686fd, 0xea1a0c3f, 0x351fb4c7, 0xd8bb8fd4,
- 0x74278064, 0xdfda1b34, 0x80643d76, 0x8693b227, 0x33f6c5f6, 0xfab27806,
- 0xdbfb435b, 0xea1ace93, 0x192fbaa7, 0x64ff75ea, 0xc657ce7a, 0x995fc2e7,
- 0xf0d9fda9, 0x8792607e, 0x5e047f21, 0x6e356930, 0xa766f6c6, 0xde817f13,
- 0xd0928f6e, 0x3e52f1bf, 0xf4261c52, 0x04c65f01, 0xe857c44c, 0x5c5057ea,
- 0xafe29e28, 0x98dc5a64, 0x1f760377, 0xb4e67fe3, 0xfb77f434, 0x295df974,
- 0xf6f88f5f, 0x6cd1d77e, 0xdb6bf646, 0xa7bca944, 0xd9a3c33c, 0xebf20e3c,
- 0xd953df6c, 0xf8bfb809, 0xbbf414d9, 0x36c0b257, 0x2964e79c, 0xde1da62f,
- 0x8c651d3b, 0x54e5e863, 0x6c2de03b, 0x1aa3273e, 0xb26e0a52, 0xbf6a9fdf,
- 0xfb3bed4c, 0x130df115, 0x587d7fac, 0xbec28fff, 0xadbf0640, 0x05720fc1,
- 0xfc0fecbe, 0xfc7bc12a, 0xf5ef0449, 0xefdca9bb, 0x09f2a1cf, 0x07f546bf,
- 0x3f0445fc, 0x1c10f7ed, 0xd95297f4, 0xf3d2f7e8, 0x8272fe43, 0x197ec08f,
- 0x7fb0a3cb, 0xd859f2c6, 0x73fd6307, 0xf8462fb0, 0x9500fea7, 0x7a3afe4d,
- 0x81bf82fe, 0xfbfc97e0, 0x3fb9fe09, 0xffb36548, 0xfaaf9528, 0x35fea89b,
- 0x6fc1337f, 0x870443f8, 0x1f04adfc, 0x7c11b7f3, 0xc121ffc2, 0xa9dbfb6f,
- 0xa45ff56c, 0x077f1df2, 0x5ff29fd5, 0x9e8bb827, 0x12387f46, 0xf88a9f9f,
- 0xe37e132b, 0x2c3fc172, 0xcb8bfb9e, 0xe5b02b38, 0x932d6f82, 0x78c10dc0,
- 0x46ecbf60, 0x891d7bcc, 0x7c43957c, 0xfc56ea75, 0x98fdc8f9, 0xf19f025e,
- 0x133af4fd, 0x76e8d78f, 0xe817e45e, 0x03c5527e, 0x00bb1f7c, 0x273c5ffc,
- 0xee28cff8, 0xb6a95eaf, 0x573fa0e4, 0xf0d68a61, 0xf54ae51c, 0x610fc81f,
- 0x220dde78, 0xb66bdf72, 0xf6c33b83, 0xbef01571, 0x4eafde19, 0x54f9a34d,
- 0x9d0b56b0, 0x23cccaa3, 0x33dd5c81, 0xf89d77c0, 0x4039807a, 0x98256afb,
- 0xff38fb8d, 0xf05fdf00, 0xa5ea95f9, 0x547e136f, 0x670fce8d, 0x770942da,
- 0xa4e4fc61, 0xdebff144, 0xf22551f0, 0x7fad7bc8, 0xfa0a52e3, 0x937fa5e5,
- 0xd39f487c, 0xc6394716, 0xf8839c13, 0xc839d4be, 0x5263286c, 0x30418e7d,
- 0xaa393f9f, 0x0a0335ef, 0x759df4ff, 0xeb4fee47, 0x81df47da, 0x9bf0515b,
- 0x42db98cb, 0xf3cc8d79, 0xb85d5e16, 0xbe08f993, 0xfca8058b, 0x35cf8a5e,
- 0x0fe62468, 0x8df60905, 0xb4f6a5b5, 0xa579c8ae, 0x207ae20d, 0x50d9906d,
- 0xb9f5484e, 0x393fbfb1, 0xd3af343c, 0xc6cf6e63, 0xfaf3e975, 0xdf9baa5e,
- 0x4f1d609f, 0xf4fefce3, 0x4c1757fa, 0xe3f9dd19, 0x0a17c01f, 0xc7686f9a,
- 0x06a41cf0, 0xafdf0764, 0xf289aef9, 0xa8be75b9, 0xbe2180c0, 0x7944c9b7,
- 0x027c5dfe, 0xb0fb81fc, 0xf7ba0ef8, 0x01327c07, 0x8c6ab9d7, 0x5f82b014,
- 0xcc1cda79, 0xf2b9d136, 0x15c62b52, 0x7f03c796, 0x07cef7a4, 0x03fdc56b,
- 0xd7f039fd, 0x2fcf48ed, 0x073a317e, 0xc6f555f1, 0xabe23718, 0xc0740cc6,
- 0x923be37d, 0xb857f3c6, 0x0dc697ea, 0x932678a5, 0x4fe30d35, 0xeb3d6d33,
- 0x7f82e5db, 0x4a59274e, 0xf19fd483, 0x413ee5fc, 0x3d04fbb7, 0x64fbafd7,
- 0x3ef3048d, 0xdd12ec7d, 0xff36e95f, 0x983c8f8d, 0x55c7c619, 0x78a767cd,
- 0x5bdfd07a, 0xdf3a7f44, 0xef875648, 0xaf3e12a0, 0x465e3e4e, 0x7c0b12fc,
- 0x7c7c419c, 0x6719cf01, 0x7731dcd9, 0x280ed941, 0xfbe94109, 0x81f69567,
- 0xe546988b, 0x72a5e612, 0xf91d9039, 0x6dd81bd6, 0x62af7c45, 0x6d7cf44d,
- 0xf21762d1, 0x8fb332f1, 0x306bc9f6, 0x7dcf1753, 0x12494759, 0x36ea4bc6,
- 0xe80495bf, 0x7bb0d39b, 0x676fc632, 0x85be1707, 0xd321d965, 0x055bcc05,
- 0xce2ef8b9, 0xbd54ddab, 0x7f8c1fb5, 0xb71373f7, 0xb3e787f6, 0xf60f4e24,
- 0xae87a72e, 0x0dd72237, 0xe499b072, 0xeb43d633, 0x06a59c92, 0xc2d8a839,
- 0xaef8a63c, 0xb94ef9fc, 0xfbfd5a28, 0xe4bfa8fe, 0x54178a0e, 0x438b61bd,
- 0xdc62af3a, 0xf479301f, 0x07ee8878, 0xd5f3e230, 0x76c35a2c, 0xfebe0a9f,
- 0xbe230074, 0x1b04d4fe, 0xff2e82c2, 0x92faa594, 0xecba320a, 0xb9f99575,
- 0xb0278861, 0x9f89fbe7, 0xcb6d37cf, 0x1fbd434f, 0xc4ff454c, 0xab4dacf2,
- 0x15d83349, 0xae9f75f6, 0x16a3d738, 0x9c8a871e, 0xede8a997, 0x623fa33f,
- 0x9e00b2b3, 0xb35c8083, 0xfdcf2851, 0x355724ac, 0x978c5a88, 0xf9baf24d,
- 0xffb1ac39, 0xadbe62d3, 0xdd71e57f, 0xe307ac00, 0xe1c7dd26, 0xdd16ca76,
- 0x0de90e35, 0x9a71a317, 0xead19107, 0xed298f1c, 0x37bfe829, 0x8e7efb44,
- 0x3fe3d1f4, 0x35b2befa, 0xba4c93ed, 0x52f63697, 0x18f7dd05, 0x80fba363,
- 0xd8b88877, 0x2e3c451d, 0x071e8776, 0x07111f1b, 0xb0c7888b, 0xc5c73df1,
- 0x98ccbd74, 0xe4f9c166, 0xd7d4ffb2, 0x5d18f14f, 0xabb3760f, 0x8a3690b0,
- 0x6e29bb57, 0xc99f19d1, 0x4cf8f2b7, 0xd5c53249, 0xee4f42ad, 0xa4fd72f2,
- 0x0e589fbf, 0x3ec3185b, 0x0d32cec2, 0x00d508fb, 0x324ea80f, 0xd1b81fb4,
- 0x0b4fa86d, 0x33ea18e4, 0x9c0334ea, 0x686450d5, 0xc7bf683f, 0x4b06e700,
- 0x1c87ed0d, 0xa1e01af5, 0xf686e54d, 0x867d9bc3, 0x0ad0fcfa, 0xd688fd43,
- 0xb23c036a, 0xfda1a36d, 0x86030fe8, 0x75ed31fa, 0x1771fa86, 0x84f00c1b,
- 0xf686fd8e, 0x1a0f5db7, 0x1fb227ea, 0xed8bea1b, 0x93c0333f, 0xda185fd5,
- 0xd3ec253f, 0x862d49ed, 0x5c4407e7, 0xa4fbaa62, 0x39e9fde1, 0x53f00c67,
- 0x87946f48, 0x879256f9, 0xf783f596, 0x07fd0055, 0x186b37ac, 0xfda999f3,
- 0xab2fd0d6, 0x6dfc47ee, 0x52cfe28d, 0x947cb6a4, 0xedcca7db, 0x6d3e5869,
- 0x7dc16f72, 0x89f8c66f, 0x2acef614, 0xcb05b859, 0x9b363341, 0x9f40dc13,
- 0xa0b707b9, 0x68a90c98, 0x1e00bb31, 0x16ece4ba, 0x8d61d217, 0xfc444a49,
- 0xc1ab486f, 0x89a6c472, 0x8fd41252, 0x83585dac, 0xfd71757a, 0x61cb8599,
- 0xd837a35e, 0xa09dcd89, 0x3e30da0b, 0x6f887b26, 0xe29b0037, 0x8c8c363a,
- 0x5dbbfca6, 0x37191563, 0xba76bb33, 0xb86e316a, 0x1d41676b, 0xafc0db96,
- 0xac620e0f, 0x2c7afc0e, 0x1f5f8277, 0x386e8584, 0x945887f3, 0xa9e07553,
- 0xdfd73c24, 0xcd53e93e, 0xfb0ae1ac, 0xe3013dcd, 0x8b4427d6, 0x737ec7bc,
- 0x7f426627, 0x0f00ab28, 0xdcfa71f8, 0xbe1dd280, 0x2a3bc436, 0x372a1707,
- 0xd7bfa1a4, 0xc0c0dfad, 0xc3e227b9, 0xa27805fa, 0xf5fa6dfc, 0x785fb078,
- 0xc3de63de, 0x9f6e1ce4, 0xf59ae407, 0xd7ca023c, 0x943a2ee2, 0x80c497e0,
- 0xd31fab9e, 0xf80e5bea, 0x136ad595, 0xf71637dd, 0x4da43056, 0x5f1be071,
- 0x700f16df, 0x64ef7892, 0x8e0e6f9e, 0x72e380ab, 0x927f8c2e, 0xc61c0096,
- 0xbf00fb1f, 0xf35d2ce7, 0x0e67dcb1, 0x2c2fa0c8, 0x069a65c5, 0x20b93ce3,
- 0xfb9d369a, 0x22ff46ac, 0xfc9de44b, 0xfbcc473c, 0xfd0d1cc6, 0xf58b9fa2,
- 0x8df7ee3c, 0xfd82d8fe, 0x7932a0af, 0x40f98849, 0x579a29cf, 0xcb0ad4c3,
- 0x8cda3fd7, 0x07c04ef7, 0x8a3b426a, 0xf98737cf, 0xb8732b1b, 0x5af9625f,
- 0xa5baf8a2, 0x85c5abc6, 0x4c916f8d, 0x4fed3dd5, 0x1065e237, 0x5186af7c,
- 0x49f8e5bd, 0xac9f4fba, 0x52969835, 0xe786213f, 0x3f884a21, 0x4d05a7ef,
- 0x923e004b, 0xff7c36e3, 0x9812dfa1, 0x4fbc787f, 0xbe6136ae, 0x6aa6e242,
- 0x5121e213, 0xbe786af5, 0xc35edcc8, 0xc6e275f9, 0x1e3fa3b5, 0x6af6f381,
- 0x99610798, 0xc87df3ae, 0x9cb5448e, 0x703262d7, 0xea5ee2dd, 0x1316b755,
- 0xf43ac3df, 0xe7e76952, 0x3bd5bd5b, 0xa6a9de0b, 0xc502d7bc, 0x4f58478d,
- 0x07e52be5, 0x23b3e07b, 0xa92fdc39, 0xa3e71a77, 0xc217e7e8, 0x19555c6e,
- 0x6f425bb7, 0x61cb1fdc, 0xf3fb9fbd, 0xcdd9120b, 0x44dfbbe6, 0x5c3ab1e7,
- 0xde20e30f, 0xd8b46fea, 0x98f56f11, 0x8bf64167, 0xfa7add91, 0x77073987,
- 0x4ff3ba9a, 0x89003937, 0xbe40298b, 0x01ac1b3c, 0xadf239fc, 0xca69fa1a,
- 0xe84ccb83, 0x6ab1240b, 0x4652184a, 0xc3cab496, 0x72bf326e, 0xfa27ff23,
- 0x64c1f28c, 0x37dd325f, 0xfdd57410, 0x7474ee82, 0xde206627, 0xe579e5df,
- 0x89dcd3eb, 0x5f9d4748, 0x63fc9fd7, 0x0e8c2f94, 0x2e7e081f, 0xca120d62,
- 0x44d658eb, 0x46d678e5, 0x075877e5, 0xcaa61e95, 0x1a624e58, 0x4bcc2595,
- 0x4d5614e5, 0xa06b2965, 0xa26b1a72, 0xa36b0672, 0x5453f612, 0xfb4a997a,
- 0x57e0d9be, 0x79973960, 0xaac79ca9, 0x7c80bca9, 0x672df80e, 0xcddf040d,
- 0x066ca89a, 0x841ee03d, 0x953b0971, 0xc59e81af, 0x127f0df2, 0x9bbf2195,
- 0x97186db9, 0x84f2a1c8, 0x6df2a35f, 0xad95117f, 0x7bb50f7e, 0xe54a5fc7,
- 0xca97bf29, 0x2a72fed3, 0x6a3efcdb, 0x057f9ef7, 0xabf81f95, 0xff37fca9,
- 0xf43f2a46, 0x77fca807, 0x59951d7f, 0x06fb4656, 0x9fca1396, 0x3948f40d,
- 0x81b8f56f, 0x1cb905ae, 0xe63dc78f, 0xa478dc84, 0xfe30cca7, 0x271c94aa,
- 0x66dc5126, 0xe757bfba, 0xa316c63e, 0xfdcd3e3e, 0x83a24748, 0xe1a554fc,
- 0xc8bcc304, 0xd4bb5366, 0xcf6b6807, 0xe7b5cff5, 0x8d7f1d82, 0x10d1f6d5,
- 0x0763ddae, 0xa5b4f47b, 0x5047faad, 0xf378fd2f, 0xced83b5c, 0x3ef78eb1,
- 0x54c3967b, 0xab04e63f, 0xe6760151, 0x5783df6e, 0xa81e70b2, 0xbc7e93f7,
- 0x4ce6ee63, 0x27d7279c, 0x500d77b0, 0x853ad5fe, 0x1bf2aff2, 0xa1a3e58e,
- 0x14ad531d, 0x6b0bdda0, 0xde8af147, 0xebd645da, 0xe9593def, 0xf50f1092,
- 0x01eda07f, 0xe508c94b, 0xbc2c5c63, 0x1bb7f35f, 0x1937499f, 0xe99dbc3f,
- 0xcc9dfd26, 0xfee6a4f3, 0x91e7c07f, 0xfaf96dfc, 0x3be8cff8, 0x0a23ac1f,
- 0x9631bbe5, 0xf00e9feb, 0x55ff719b, 0xcdfae02f, 0x3747e4e9, 0xdf7379ea,
- 0x31bea993, 0x8ad2bb5a, 0x8a4ce6f0, 0x7ac7d487, 0xfdb173a2, 0x43d274d6,
- 0xe5187d29, 0xded2edbd, 0x7261dd56, 0xeb97353f, 0x35c2655d, 0x8bea3175,
- 0x8f0cc9ef, 0xef7e07da, 0x01dbd683, 0x66adee6f, 0xcc529efa, 0xd14a0f84,
- 0xc937042e, 0xf3a124a3, 0x3a2fd518, 0x5dbafb82, 0x1b3a359a, 0x51107ae8,
- 0x9d5ffe87, 0x4a5ffe42, 0x7e3e50df, 0xccab6a57, 0xf522d7f3, 0xbe316edd,
- 0x86d851d9, 0x6f9fadef, 0xa4bc6377, 0xef58fd37, 0xf9e3e40f, 0xb7da2bb7,
- 0xac3c8190, 0x7e3e7dc8, 0x2e15382b, 0x1e6bf727, 0x17363dcc, 0x8bd543ef,
- 0xf1add8bc, 0x8adefa66, 0x283ae052, 0x58abf585, 0xb3b26e43, 0x62c72166,
- 0x523bf53d, 0xfbb8ef28, 0xd7f68d3c, 0xc23cc1a1, 0x88bd74f4, 0x378e745b,
- 0x2941dfa2, 0xd8a7ae2c, 0xa78d1a42, 0xbc7d33db, 0xf1bdff9d, 0x4f7c8976,
- 0x28c73c7d, 0xd61cfae3, 0x439f5a36, 0x78fa41f8, 0x3d7d70bb, 0xe37c8de4,
- 0xf0beb878, 0xd71b46f1, 0xd1b5b0e7, 0xf7121cfa, 0xdbc73a6b, 0xbd78f3d9,
- 0x2237b38d, 0xf72f4fff, 0xdc13ff0a, 0x180e7643, 0xf9c6c534, 0x330b69f9,
- 0x92bc039c, 0x1ff3edcb, 0x595f38f2, 0xc97ae36e, 0xfdd2b2e2, 0x8bae89a4,
- 0x95af91bb, 0x173a663d, 0x26dfe253, 0x3c4e4b3f, 0xa7da24c5, 0xfe7c26b2,
- 0x17bf89b4, 0x98f6b048, 0x5fd7b367, 0x2c333a34, 0x55a89dae, 0x6b6f309b,
- 0xe195aba2, 0x6f128039, 0xf12bf5a5, 0xea1460f6, 0xd8098d5f, 0xfe83ec1a,
- 0x8bdf50c4, 0x974f30b9, 0x15c5e5c6, 0xf9883d6f, 0xd0e58954, 0x9e3e186f,
- 0xe4cc7c16, 0xb0b2b4f6, 0x791d42fb, 0x5cba1f1c, 0xc36fce47, 0xc6878e60,
- 0xea2af049, 0x8e3c31cd, 0x3f70fa73, 0x7accc7da, 0xfb83da34, 0x063bd3fc,
- 0x73bc1097, 0x9c01e52c, 0x0a763c3e, 0xed666bee, 0xd826669c, 0x3e315ac4,
- 0xdde76b33, 0x929e7c66, 0x1dfe88c1, 0x5fa4ad67, 0x255ced67, 0x14d3ffda,
- 0x0e645f6c, 0x1ae304fc, 0xed1d0f45, 0xb19b7183, 0x63fa178e, 0xbedcda79,
- 0x7477bf01, 0x857eca87, 0x73779bee, 0x7d4d039c, 0x0b748ed9, 0x977ec5c6,
- 0xe697cfcb, 0xe7858f30, 0xee29788d, 0xdb68fe30, 0xfc82bc71, 0x628ea69d,
- 0x34f76e3c, 0x9cb027ab, 0xc84ad214, 0x9ef56c2d, 0x5b4a72c0, 0xbbba0975,
- 0x9c361fa5, 0xb861b2c0, 0xdf8877ef, 0x2a8e0fc3, 0x49c60678, 0x68dceefd,
- 0xb7d277f4, 0xa41e4e84, 0xee85b1b8, 0xf22dedb9, 0xde3049d6, 0x8ed7b75e,
- 0x7c6f6876, 0x6bf499ba, 0x5a0af56c, 0x866880e7, 0xfaabdceb, 0x6fbfd0a2,
- 0xef46e714, 0x2c4731f8, 0x7f3479ec, 0xbfe099fe, 0x1ed7aaad, 0x52a0724b,
- 0xfc2283be, 0x49e67ab4, 0x3b284342, 0x1b8c413c, 0x3d70f5ee, 0x7ef8501e,
- 0x036f9b19, 0x98ae8ebf, 0x29e8bb9a, 0x7f31b26b, 0xec1bdc1a, 0x50ed1657,
- 0x883fa217, 0x06116ed7, 0x13bfc1fb, 0x743db8c4, 0x673a2e28, 0x172fe7d0,
- 0x7c617f42, 0xad9ff386, 0x8fa7bd74, 0xf6160eab, 0x5ed3f041, 0x9f4fef1f,
- 0xb760ec6f, 0x731b5ef8, 0x923e719b, 0xc3ac0f98, 0xb09f361c, 0xcebeb476,
- 0x892d3379, 0x30f59fdf, 0xb996af7e, 0x3bf5b0e5, 0x44bb5e6d, 0x22acd076,
- 0x33343aff, 0x28704bdd, 0x04fba73f, 0x1ac8eb91, 0xdf69e3cc, 0x051f6197,
- 0x79a699eb, 0xf7e5ca18, 0x55f90f55, 0x78e580b2, 0xe3c987ee, 0xd84b3127,
- 0x49f8e57a, 0xb41a6ed4, 0xb4e7f8c7, 0xf21a3ea2, 0x54d674eb, 0xc17df2ab,
- 0x5f984c89, 0xfc866316, 0x4fc05974, 0x9650bf96, 0x71abc6e6, 0xe8392d0d,
- 0x8cb03d17, 0xd76a8cf2, 0xf9c56b4f, 0x6bace526, 0xef7a8389, 0x2cee9c57,
- 0xfb0dc79f, 0x790d91ef, 0x002bc9cb, 0xf75f3f0e, 0x07e06119, 0xaf9d7b43,
- 0x8aa95314, 0xcfb9847e, 0x3059dd8d, 0xedc9d97f, 0x6cb87837, 0xf2f10f6e,
- 0xf0257c6e, 0xc667d3af, 0xa7c24ce0, 0xb3bc70ac, 0x277ecd0e, 0x1bf113a7,
- 0xd5e309fd, 0x3e62d880, 0x14894d7d, 0x8ea1fbc4, 0x012cf6ce, 0xa7491ae9,
- 0xeec75b74, 0x957f5c2c, 0x23dbf299, 0xc47e0af1, 0x67c8699d, 0x1ea9e26b,
- 0x3abe539e, 0xf6752266, 0x1b04f523, 0xed4df1e9, 0xddc1609f, 0xf8d64f3c,
- 0xe0be293c, 0x8a429c9d, 0xcc9c6847, 0x0dacfac6, 0x8c62ba46, 0xa278f509,
- 0xb4a182c6, 0xb4e7a75b, 0xa612c6f8, 0xceaba774, 0x7b7d2977, 0x10f2f3d6,
- 0xea03b093, 0xf3d41cb4, 0xfff26609, 0x84e609bc, 0xd6f07df0, 0x725f7cc1,
- 0xe90a2bdb, 0x4ede766f, 0x50b4eff7, 0x13f41f5b, 0x93335d27, 0xa9d6fe7f,
- 0x834d8f63, 0x96aff272, 0xc9bb61d4, 0xbf46edb0, 0x372be862, 0xbf262c46,
- 0xe5172da5, 0x3a1655f5, 0xb1f682d9, 0x827142d5, 0x536f9fcd, 0x35fd2127,
- 0x7d3e7146, 0xb98323dc, 0x25a5fa9d, 0x9a7d25e0, 0x7e46b326, 0x6be3765e,
- 0x3e3c4e9d, 0xb2c77944, 0xabddaf89, 0xbd935755, 0x3663c94c, 0xadb7c78a,
- 0x21bc7b24, 0xccbca19a, 0x41ee9b56, 0x1765f678, 0xb37f4333, 0x2165b735,
- 0x3f091f9e, 0x59aa8e73, 0x69a96226, 0x3f9db9fc, 0xe87aab9f, 0xc3cd5cf9,
- 0xbf7c2b9f, 0x681aa77f, 0x777f43f3, 0xec6e712a, 0xcbcd4eef, 0xa8dbafeb,
- 0xffec14fe, 0x47b4efd0, 0xebd45405, 0xfccd170d, 0x4d17ce7c, 0x2955befc,
- 0xfce37568, 0x4f74cd0a, 0xba24fc0f, 0xf54bbd5f, 0x7deafdd2, 0x088c97cc,
- 0x3670b57e, 0xc6afd1f9, 0xd5fee99b, 0xe5331eab, 0x642a0581, 0xf0521f7e,
- 0x29e5abd1, 0x8e967e74, 0xdd7a44c8, 0x643f2763, 0x62441e2b, 0xdc7ef2fb,
- 0x7fdcc85e, 0x9e2a3fd8, 0x2c6d3bda, 0xe0f914ae, 0xf2f94cb0, 0xe3cf1fdf,
- 0xf4a1f298, 0xae6bfa20, 0xcbbca30a, 0x3f389385, 0x39454c68, 0xc469a198,
- 0x987b35f7, 0xdc937666, 0x5740fbd3, 0xc2aee75a, 0x22fa4af7, 0x24d346bc,
- 0x7d06182e, 0x1ef85351, 0x4ccf83c7, 0x0abbeff9, 0x49befbc5, 0x5d7c7087,
- 0xf90b07ce, 0x774af5d4, 0x3f51a43d, 0xda49d88e, 0xc306804e, 0xfbff2800,
- 0xf51cf0ad, 0xf74c9c42, 0xca1706c6, 0x97587521, 0x7e8b27dc, 0x94f90b07,
- 0x2ce51a8f, 0x7e1190eb, 0x7eefc85c, 0x62fb9216, 0xce8c0dbf, 0x1837facd,
- 0xc7cec1db, 0x522c7a84, 0x3f0baf8e, 0xdd0f1233, 0x79ebecf0, 0x0aeb5d9d,
- 0xbad36544, 0x425d7ccc, 0x5b2a65df, 0x2aa679e8, 0x179c6e6b, 0xd70f786b,
- 0x0c90ffdf, 0xabd02a0e, 0xe31b3cd0, 0x3202333c, 0xac99bba9, 0x37c5f48d,
- 0x88ab7bad, 0x33ae4573, 0x06db7d72, 0x64bf5c4b, 0x37e4bcf8, 0x37e4cb25,
- 0x6303d659, 0xe56bc70c, 0x23b79dde, 0xeece875d, 0x59da0433, 0x62a5581f,
- 0x7a155a5c, 0xc4b5f2c9, 0x3b61ebf9, 0x7125abf1, 0x7df84e46, 0x24da919b,
- 0x51c50875, 0x841c9eaf, 0x2d77c771, 0x3d48ff84, 0xc7086637, 0x637698f3,
- 0x8bb8e45e, 0x7c7911d1, 0xdbc8bcc6, 0xc88bf7ae, 0xc888cbe3, 0xa8621be3,
- 0x888eac9f, 0x171be3c8, 0x6c57c791, 0x4ce7a780, 0x9be3c88f, 0x28ef8063,
- 0xbed0c7ba, 0x50d8b3cc, 0xb574a73f, 0xef4efea1, 0xaef806fd, 0xed0d87f2,
- 0x0c6afbe7, 0x78acf7f5, 0xfa0f50c4, 0x73b8c7a2, 0x87ae10f1, 0x6d3c936b,
- 0x103081f4, 0xfe0f6f78, 0x1dcaa480, 0xd9c7f6e1, 0x56a2fecb, 0x7d29e3d0,
- 0xe248127f, 0x8f116671, 0x10c47705, 0x9d8d0daf, 0x517dc766, 0x444b4d9a,
- 0xcd7ecebb, 0x585806ed, 0xc4e6f9c3, 0xdda94b07, 0x3a74d8fa, 0xfc027987,
- 0xc0e81f6c, 0x77cf20da, 0x6f0017e9, 0xabf79e1c, 0xf5da1285, 0x78a56ebb,
- 0x583ce76e, 0x5577f529, 0xf3ea2f9c, 0x43f18fdc, 0xecdbee1b, 0x54cf3254,
- 0xe28e3f1e, 0xe9751eed, 0xc31a96e7, 0xd6451d7e, 0x164be500, 0x30ac5b06,
- 0x8fd05adf, 0x97849af8, 0x55dda1ec, 0x3de9bb45, 0x127f1ab0, 0x96520fdd,
- 0xe8160284, 0xbf27eab2, 0xf0e3e1f8, 0x1463e2be, 0x27f878a7, 0x7e21fcbf,
- 0xc43fc407, 0xc871744d, 0xeefbcf1c, 0x874ba7fd, 0xbac65f51, 0x64625ee8,
- 0x9b7de27d, 0x26eb7abe, 0x3c16fbf5, 0x37a5dbf8, 0x8ddeff7b, 0xd586b767,
- 0x597f36f7, 0x613cc7e9, 0x356a907c, 0xcbd5c3de, 0xaabe0bef, 0xf8a56b1a,
- 0x57c92ce5, 0xe5fcf28f, 0x707affd8, 0x45f7bc3b, 0x717bb5c9, 0xbfcf077f,
- 0x1da1cf8f, 0x948bf5e1, 0x3cf8a92b, 0xfff80865, 0x58a36768, 0x6f7cf98f,
- 0x8b7ee10c, 0x41d1589c, 0x2b04f3fb, 0xf65c87c5, 0xee3fa3f9, 0x447358cb,
- 0xf71ea0bc, 0xf7a760e5, 0x1e88f88a, 0xf4417f2f, 0x92944473, 0x41ce9f3a,
- 0xf7403d98, 0xb17f7562, 0x8b383c9b, 0x651bee18, 0xae10be45, 0xac125b17,
- 0x54901f14, 0x4b77e52b, 0x2efa28ea, 0x7d1b04a2, 0x2872473c, 0x68cfb46d,
- 0xf1451849, 0x86342900, 0x128a0ce2, 0x40defea2, 0x7ee024ba, 0x77dfb8c6,
- 0x5d682bd9, 0x3acff7bd, 0xeb49f79f, 0x79889c61, 0x1f5878e0, 0xfc41ce39,
- 0x9bda1c2e, 0xe31ef665, 0x4c86d71b, 0x4af48e3c, 0xbeefb5b3, 0xfdf5e51d,
- 0x5eb2f59e, 0x307f9e62, 0x86673f0c, 0x605f13a4, 0x6c307f7e, 0x0fe3cc5c,
- 0xe8038187, 0x60c1079e, 0x42d8066a, 0xb9f88351, 0x6f578d05, 0x3fc892d5,
- 0x7487f304, 0xe7908dfc, 0x61af023f, 0xc3ec57b9, 0x635c83f7, 0x255f84f9,
- 0xc800ed3f, 0xfb4fc21f, 0xfd0654dd, 0xfa365439, 0xe43faa35, 0x88f8222f,
- 0x51f043df, 0xcf95297f, 0xfcf4bdfa, 0xc1397f39, 0xa8fbf53f, 0xa0aff26c,
- 0xabf82fe7, 0xbfc97e09, 0xa39fe091, 0xe785985f, 0xbe547513, 0xfaa06fea,
- 0x09fbfcd7, 0xa41fc37e, 0x4a3fe432, 0x9bf98fcf, 0x6fe13e08, 0x7f6df826,
- 0x7f56e088, 0xf8ef952b, 0x29f9e8db, 0xa30487ff, 0x45fee23a, 0xe03f19d2,
- 0xd9817125, 0xe25e7e8d, 0x4bb34582, 0x2e57de00, 0xd7617dd3, 0x41d2f97c,
- 0x34278be0, 0xfb7bf699, 0xee299856, 0xfb95fba3, 0x16c7d62a, 0xaa5cfd53,
- 0x268d486f, 0x12ff6cbf, 0x571fdd2b, 0x967f7256, 0xbda8552d, 0xfd532f92,
- 0x92e62b13, 0x538f58df, 0xd92ae700, 0x1931d81c, 0x93322ddb, 0x111fdefe,
- 0xe3ca4dd7, 0x4f293f76, 0x8faff7e6, 0xcfc20546, 0x629b2b29, 0x7355700d,
- 0x30e3e072, 0xc62d59be, 0x1c991b61, 0xcfc7ddfe, 0xaf307ff7, 0x90f9d604,
- 0x03ca4be4, 0xe0717c7c, 0x99d83cdc, 0xc3bdb332, 0xcce4f28a, 0x8d4ed9e8,
- 0xebcfd3cf, 0xfe224e92, 0xe13269f6, 0x61b69f6f, 0x2fee265a, 0xddf4c816,
- 0xf205c48c, 0xe99fb857, 0xfba65f37, 0x994acaa4, 0x816c81e2, 0x0363e059,
- 0xfcdfbbad, 0x0eaf54b9, 0x7471453c, 0x6d13cad7, 0x016fd193, 0x1d11657c,
- 0x39e2c50e, 0xbb88b26e, 0xa68f8fee, 0xf9c8b6bc, 0xf17bff8c, 0x33f009b3,
- 0x8cfc47aa, 0x4f3f09ef, 0xfde3fb88, 0x222277c4, 0x977fa4f1, 0x7df109f5,
- 0x1e06c0f2, 0x376c8fbf, 0x731fcc47, 0x2e3be8ce, 0x8fe93295, 0x23b82c03,
- 0xf998e31b, 0x7e43dd32, 0xb3aad27c, 0x3f3e6107, 0x91ddf3c8, 0x2c9fed07,
- 0x8ea18f91, 0xfde52b8d, 0x1f235c0f, 0x7e02be41, 0xda04795d, 0xe93bbf6d,
- 0x7d94364c, 0x8c16ee03, 0x1f463abf, 0xf989f648, 0x161764f6, 0x80fbbf0a,
- 0x2b4fc447, 0x651a3df9, 0x13dc9ee5, 0x3805dc7c, 0xb5f52bae, 0x0309f8a9,
- 0x930edcf7, 0xf97eca05, 0xcf1c3af2, 0x49d24f76, 0xe0212f1c, 0xc7cbc7d1,
- 0x9e2dbef1, 0x925bbf52, 0xf1bdd3d8, 0x37e1f4de, 0x79f5c1e9, 0x7f513ee2,
- 0xe0f51fd6, 0x8a7696e3, 0x70ce0753, 0x38b4c83d, 0x3917bfba, 0x27f96f4e,
- 0x649f8101, 0x886f3f1b, 0xe7476f7c, 0xf02025be, 0xf28cafd8, 0xe2cb26b4,
- 0xf68cfabb, 0x4627ebdb, 0x726f9bab, 0xd403f31e, 0x1eafa0bf, 0x9fa263ce,
- 0x1fbca994, 0x0267ef33, 0x44f0475b, 0xe4dc0d45, 0xe88f601c, 0x00fd8fc7,
- 0x7bbf1f7e, 0x18adeec5, 0x42d77cb7, 0xc90e74b9, 0xcef49bb7, 0x1fda25af,
- 0x2b0dccb9, 0x17f5878f, 0x9fa97c14, 0x48de6043, 0x79d7565e, 0xec055244,
- 0xadf0c291, 0x88b8f7bf, 0xe3793fa3, 0x9bca58a1, 0x8510dfc8, 0x663edffe,
- 0x2c503e27, 0x0c3f3521, 0x7f898a7f, 0xfe7227cf, 0x7aacf2c7, 0x7132805e,
- 0x32239e14, 0xf519cf7e, 0x75fbcc28, 0xb77f939f, 0xd307c169, 0xfe3c0387,
- 0x0fe74c9a, 0xfcd1a5ae, 0xcc1ff6fe, 0x86f46794, 0x677e1788, 0x63dd096d,
- 0xf712c24b, 0x054fb8a7, 0xa626fc78, 0x9f7df085, 0x09c1fb42, 0xe173e5d7,
- 0x0ab2097e, 0x22ee37f6, 0xb8f2f8a3, 0x6f70d90e, 0x6345cc6d, 0x84bfa07b,
- 0x76a4dafb, 0xa144bb63, 0x15235dff, 0x7e8ffefa, 0xd7f5d06f, 0x64c5b97d,
- 0xff49a227, 0x24c9a93f, 0x2a164fcf, 0x76ddb107, 0xfb84bb3b, 0xbb7cc744,
- 0xc5a07a8a, 0x557a4d15, 0xfe4d1119, 0x6394f6f3, 0x9fc076f6, 0x2a07e46d,
- 0x6c032bfa, 0xbb1883be, 0xab73edfe, 0x218d25e7, 0x5df5de3d, 0x3bb022e3,
- 0xf282f978, 0x9decd699, 0x1579899c, 0xd8eefa66, 0x7ab73c7f, 0x2277f86f,
- 0x307524d3, 0x84ec57cf, 0xe0dfa157, 0x418fb9c0, 0x33ea063f, 0xd7c61cf0,
- 0x29217a8e, 0xf905babe, 0xb6395eaa, 0x85d0e282, 0x2d57a4f1, 0xea10eabe,
- 0xc0ad7a89, 0xbadf2e1e, 0xdcaadc9c, 0xd5ce293f, 0xbffe49be, 0xe4dedfa9,
- 0x2e5c95fc, 0x01c5bd77, 0xb77e7df4, 0x5ebec4fe, 0xdfdfc21e, 0xe079f42a,
- 0xbd47b5ac, 0xd72866bf, 0xef224517, 0x297c5661, 0x567e7f7d, 0x3cc65da0,
- 0x2e50cf50, 0x1c12fb47, 0x2fb0cf94, 0x7e30858d, 0xedcf981e, 0xe20ad903,
- 0x538a74a7, 0xd4da9bd5, 0x0a43d200, 0x2e2e91b9, 0xefe187d8, 0x6ddfd478,
- 0xf977d20e, 0xfc28be82, 0x63f41e3e, 0x852817d8, 0xe4d5e2dd, 0x6871ebbf,
- 0x7e008efc, 0x82b687ff, 0xca3a82e0, 0x9b9df4cd, 0x7426f7c8, 0xaedbe118,
- 0xcc89e11b, 0x629abdf8, 0xac9e11bb, 0x43a1e11a, 0xf6e2bef9, 0xa9f3e324,
- 0x6fdc236e, 0x9994637e, 0x78a0ffdf, 0x0c147e95, 0xb8c03eff, 0x64017f58,
- 0x60f7e20c, 0x21afb7fb, 0xe8ff507d, 0x7eff920c, 0xcae2226b, 0x8195b00c,
- 0xf3e36a71, 0x2d859cc4, 0xaaed7e98, 0x87be2390, 0x2ce746d2, 0x73c30f80,
- 0xf20b7cfc, 0x9e6ce1ff, 0xdc30d9ff, 0xc8e87937, 0xde1c79ae, 0xcfce9b33,
- 0x035f562c, 0x28c74efd, 0x36d2ec99, 0x9b75d399, 0x35ba72a6, 0x5779d327,
- 0x60b44aa2, 0x5d5f3645, 0x4723c61a, 0xc91e299a, 0x3df9e21a, 0xd3fae7f4,
- 0x2c6241f9, 0xe773439f, 0xfa47dbfe, 0x40d89d97, 0x2afb03e7, 0x788efa64,
- 0xf9403db2, 0x2bceb053, 0xce963886, 0x39f9f3b7, 0x50d7ac0a, 0x62bceb0f,
- 0x101f97e4, 0xa2f5f49d, 0xf0c206bc, 0x081a7280, 0xbe699b8f, 0x940788e5,
- 0x51e7f0d7, 0xba16ed99, 0xd3d62d4f, 0x7aeadc9b, 0x579c48a3, 0xd76c79eb,
- 0x1e7a98c4, 0xff9106db, 0xe234ecda, 0x24f95ae1, 0x6b5c338a, 0xebed139b,
- 0x2f418e49, 0x2f5c6c04, 0xde1db960, 0x7bdfb943, 0x1c54e163, 0x2044f50f,
- 0x16147bec, 0x6dffa7c1, 0xc221b3bf, 0xeffb3f2f, 0xf9186a47, 0x9e208f9d,
- 0xe39c072a, 0x77c5edf7, 0xb6782cbc, 0x3ea5cf07, 0xcb7aaf9c, 0xcae9af1b,
- 0xbae3b5bf, 0xbfbc88a5, 0x5af8112b, 0xbfa5f02f, 0x274d457f, 0x2d695d3c,
- 0x2786f7b6, 0x1327f426, 0x332f13fa, 0xbb3e2ace, 0xec634121, 0x9fdfe799,
- 0x671d0327, 0x985b3ead, 0xcf9bf00a, 0xcfc39eff, 0x3fa97d9c, 0xec361d34,
- 0x3df879f3, 0x9d8f598c, 0xa1a296bd, 0x85de26dc, 0x8a70c3df, 0xbe7d1973,
- 0x092f78fa, 0xf1b5597d, 0x90671e1e, 0x357724bd, 0x01c52f2e, 0x70ef8cbe,
- 0x5542f9e2, 0xd16b8742, 0xd57ef44d, 0xfbf97bc6, 0x0a353e98, 0x5cb889f3,
- 0xfbf3d6cd, 0xfdf98d4b, 0xd22ae74e, 0x5016367b, 0xd9442f51, 0xeebe743d,
- 0x3a26e619, 0x72b4c9dc, 0xceeebe7e, 0x5accfa42, 0x3fd1ea6d, 0xe7aa1d6c,
- 0xd5be86fb, 0x2bdc4cb8, 0xda245398, 0xc65fe3a9, 0x7b34ee71, 0xf05fa2b6,
- 0x482cc67f, 0xcf41b740, 0x75d21a7f, 0xadd0ef4f, 0x759cffdc, 0x496dc4de,
- 0xff278f0c, 0x575f3871, 0xed009c78, 0xf9746f46, 0x3c5d1bac, 0x89ad0714,
- 0xa8ba70f3, 0x48cdce1d, 0xd70ed897, 0xd7debc96, 0x113e8ddf, 0xf82ab8f8,
- 0xe42bfd1e, 0x9fc26fd7, 0x4f3d1f4e, 0xcee4c6ac, 0x40e67f22, 0x147c437f,
- 0xaf6e0236, 0x76fe67a3, 0xc88f7d87, 0x38a5e49a, 0xcb5e2593, 0x9ae67cc1,
- 0xe63d49bf, 0xe30f6777, 0x6766f37e, 0xaf17dd34, 0xbee95a71, 0x27738b5a,
- 0xaecd3f43, 0x94bc236c, 0xe618eb38, 0xb3a6d5d1, 0x06edfe26, 0xad715e63,
- 0xef5e6ef3, 0x9dacb3e2, 0x2e31eba6, 0xb4e7b5cf, 0x8103b418, 0xaf2edfd3,
- 0xbfe76e58, 0xbd5bd25b, 0xcf1a6e33, 0x295a762b, 0xb18a58af, 0x5794f756,
- 0xc7c117fc, 0x78beb82d, 0xa78f0f5c, 0xbbb2ebe9, 0x3e23fe79, 0xd59a78c7,
- 0xafdfa3ed, 0x97ffd7d1, 0x7a2e9ca1, 0x9abb9b7b, 0xac97dea1, 0xacf51b9a,
- 0x884fbe24, 0x4c272476, 0xffe3ea5f, 0xef85a869, 0x4a953597, 0x8ddb9db3,
- 0x39eebf59, 0x30f47c3f, 0x9dc92dd3, 0xcdb337ce, 0x97466f3c, 0xd58ab9ef,
- 0x5cc37e83, 0x7af28925, 0x2fea02e6, 0xffb585c6, 0x1efc5dce, 0x2125acaa,
- 0xee3fbd3f, 0x07df97b6, 0x2e983df0, 0xa9bde9e2, 0xf59fba16, 0x7079899e,
- 0xb79919eb, 0x4ec6f5e8, 0x1de3edc6, 0xa2d6ce33, 0x620c6638, 0xb0e43f74,
- 0x78e762b3, 0xccc3fe46, 0xae60d061, 0xde326caf, 0x9e5d98c7, 0xafb616ff,
- 0x8f407612, 0x49f55717, 0x91fe520d, 0x6c339be4, 0x3f8dc624, 0x6242559d,
- 0xdf4a91df, 0x4f6aecbd, 0xf6b0e371, 0xd3fb45f3, 0x1d71c469, 0x2b83ddf4,
- 0x3e8bb1ea, 0xf287d137, 0x8bf12221, 0x9dff0a74, 0xa07f5d35, 0xfe1167dd,
- 0x48fc3879, 0x13dd394c, 0xbd57edd0, 0xf578e7a5, 0xbd0986af, 0x38adcba9,
- 0x1f33b087, 0x4c91345d, 0x1ea7ee5e, 0x67d9f67d, 0xea7e5d5d, 0xf49f610e,
- 0x8333a27e, 0xf98d1954, 0x549a502a, 0xaca3f10f, 0x60052756, 0xdaffdb9d,
- 0x27f7fdf3, 0xf01e7975, 0x2fb61260, 0xb072fb71, 0xdf17cc8c, 0x072cba96,
- 0x34db72e5, 0x946aeedd, 0x9cedbe37, 0xbe7437fb, 0x1bcf0efa, 0x9d90196f,
- 0x4a517988, 0x59be45ab, 0xe415a65e, 0x3d137dd5, 0x3ff7156e, 0x631b1db7,
- 0x36f4f8c7, 0xcf0da0a5, 0xf129b777, 0x536db405, 0xde901e78, 0x5e78515e,
- 0x78f1a29e, 0xbcf0a2b7, 0xa77f3d39, 0x84dbc065, 0x03ddbd0f, 0x8d15af82,
- 0xd288e3df, 0x5d9da81a, 0xb2f7d2f6, 0xe28cf1ec, 0xff957652, 0xa67450ee,
- 0x907bd999, 0x2cc3b5d7, 0xe5b61f64, 0xa24db415, 0x146ec9f9, 0x05496d93,
- 0x1147a449, 0x8d7ef0ef, 0x316f13a3, 0x0a9fc788, 0xd4fdebbc, 0xde75f0b4,
- 0x417771bb, 0x23f45f49, 0x5f9087bd, 0xec8b29b7, 0x7246ef78, 0xbfb4de14,
- 0x432661e6, 0x7f57663e, 0x7f450a97, 0x24fec53f, 0xfd8a8147, 0xbfcf5859,
- 0xe8b6f8bb, 0xef3defe7, 0xfa360cc0, 0x226308de, 0xd494268f, 0x2761f9d3,
- 0x631cf0fd, 0xfef7f744, 0xbd677edb, 0xfe09de31, 0xbf516fe6, 0x7b9de654,
- 0xe13d127b, 0x68d6e6fe, 0xbf742fae, 0xfb795651, 0x0f7e66ad, 0x9abeff55,
- 0xb1ca47ee, 0xdd743c46, 0xb874e303, 0xc838f2aa, 0x7c518555, 0xafae5226,
- 0xb86e3a9e, 0xd8768147, 0x2c71fc23, 0x0cf4cfd1, 0x2e2973c2, 0xa3dcbadf,
- 0xebfd444e, 0x1f7f7728, 0xa8a4abbf, 0x30b7ca66, 0x5f12ff01, 0x9243de77,
- 0xc6cff47a, 0x3574e70d, 0x24685625, 0xb7284ae7, 0xe03f3927, 0x728b953a,
- 0x1ecba07d, 0x03aeb8ab, 0x1389dce7, 0xbf5ce4c3, 0xbff7a21f, 0x3564e4fe,
- 0x74df5d7c, 0x6e79c2ff, 0x8f64fde7, 0xff1edc5d, 0xd8c7df6f, 0x40aeb2ea,
- 0x326cdffb, 0xc391e5ea, 0x86d63eb9, 0x75e0f88b, 0xb3b7ee99, 0xe1b4bea1,
- 0xd98b3f80, 0xf97a8e5b, 0xdfdf3540, 0x1499b1ca, 0x7eb03987, 0x829e445a,
- 0x30f0d06f, 0xb3aa2c79, 0x85abbe92, 0x03ed077d, 0x491ae823, 0x3afe9d2f,
- 0xe7e728ec, 0x27bd3a72, 0x91212a26, 0x89fe4c07, 0x09997e2b, 0xdcab9af5,
- 0xb039f267, 0x81d91b7d, 0x115ddade, 0xaf6f4ffa, 0xce0aff60, 0x73e280af,
- 0xa0e75057, 0xfcf6a49f, 0x51976cfb, 0xec7e0498, 0xb1e72eb0, 0x2bf62aa9,
- 0xab793f09, 0x51af6fc8, 0xb09eed0b, 0x42d8a5f7, 0x3e30a4fb, 0xde25e9a9,
- 0xc7ae1fe4, 0xefb4439b, 0x4810efd7, 0x9e60d7e8, 0xee5f22a0, 0x7ed0478c,
- 0x9df0d4a2, 0xdefc7d45, 0x5f39edcf, 0x690b555f, 0x018f281f, 0x0bfc017f,
- 0x8192ec53, 0xbe2d3764, 0xfcc44e7f, 0x28dadf95, 0x2123f79f, 0x3e42ed9f,
- 0x0163d37b, 0x2d2e8c76, 0xf027616e, 0x49f008d2, 0x49f20c41, 0x70d98a4d,
- 0x9b97a3ae, 0xe26f3ac4, 0xbf0f54e7, 0xc1e73f35, 0x39f83de1, 0x9f84c7e8,
- 0xe2ffa3cf, 0xe89bd309, 0xf07a78bf, 0x62cdea73, 0x53ce27ff, 0xcddc5b4f,
- 0xd39780ed, 0x3be86213, 0xf87d193f, 0xe8d3df3d, 0x7f8015f7, 0x4cd9ccf7,
- 0x532cd624, 0x843a77e7, 0x0608c99f, 0xca276f3f, 0xaef31945, 0xd5bddfc2,
- 0xdf8988e5, 0x3a26f9a3, 0xe0dc06cf, 0x3de3b6bc, 0x87ba3cbc, 0x39d3da57,
- 0xfe4eb1de, 0xc7a61301, 0x401f08fb, 0x5a38b09d, 0x4460f8b7, 0x31c3103c,
- 0x19c5f99d, 0xbf6fdbdd, 0xf9f8a261, 0xe20b1f2e, 0x51dc02ef, 0xbddf8c64,
- 0x76d9f225, 0x7f24612d, 0x429a72bb, 0x6a245fe8, 0x65f1e28c, 0x39fb631e,
- 0xbddf91a5, 0xeef9c636, 0xe7225af4, 0xebb5df4b, 0x7fd7d627, 0xff8a2acf,
- 0x22fdc645, 0x3eb47de3, 0x3c8523b4, 0x1854afee, 0xf51cb8f3, 0xd8bbe833,
- 0x714af860, 0x3314ae7d, 0xa3ac38c3, 0x2dcf323c, 0x21ecf020, 0x59e3a665,
- 0x92899eff, 0x6bdfe66f, 0xf546dc0d, 0x7e1dbe7a, 0xaba27177, 0x3aca5d6b,
- 0x117c9f31, 0xbcf40dcf, 0xd7185dae, 0xbce8bcc4, 0xd084d036, 0xc605ce1f,
- 0xf460ae49, 0xb75857bd, 0xf0e25ce1, 0xfa262d9e, 0xa31f0f1d, 0x1e01a1ef,
- 0xcc16e78c, 0x5850f147, 0x039ce1bf, 0x238069d6, 0xe4df01f7, 0x93de1fff,
- 0xa277e3de, 0x278f52f5, 0x61338b75, 0x2fa48007, 0xbdf38b86, 0xfa286ca1,
- 0x06fe4a41, 0x1495c3a2, 0x72cb5f9e, 0xdbdf3e7a, 0xf7e1fd09, 0x72887e93,
- 0x01718092, 0x04def866, 0x0f74c8f3, 0xe7c454c0, 0xe5ebea6a, 0x48c79742,
- 0xccd16dbe, 0xa684798e, 0xea0f6882, 0x600d9b13, 0xf8852efc, 0xee24b74e,
- 0x283ffd3f, 0x00812bd4, 0x0000812b, 0x00088b1f, 0x00000000, 0x9095ff00,
- 0x50c34b31, 0x97bf8514, 0x4a36ac46, 0x1056dac1, 0xa8508a09, 0x755a5095,
- 0x97375433, 0x221d0e8c, 0x38ba383a, 0xfc5d251b, 0x09f9ce01, 0xe6e284fe,
- 0x482ae0e6, 0x22bf8290, 0x26a697de, 0xcbbd0820, 0x77dde779, 0xddf73dce,
- 0x2e8dcc2b, 0x5eca7550, 0x75619047, 0x444506d2, 0x9aea1152, 0x47e17536,
- 0x3cd6a5a4, 0x7c22c128, 0x4c12092e, 0xecbbaa75, 0xfbd45ab2, 0x5ffed246,
- 0x73e4ec6f, 0x7569fd73, 0x27e7cad2, 0x22ff8eba, 0xba77e898, 0x00839d12,
- 0xe4e3e1d6, 0x65f68fbd, 0xc8773d13, 0x5f94dcac, 0xd53da3e8, 0x3970079b,
- 0x3adf376b, 0xdbe20d46, 0x0aa8f38a, 0xa567047b, 0xfd398f74, 0xed34737e,
- 0xb0a56f2d, 0xef37e657, 0xbf89695e, 0xc21b71a5, 0xc1ec8481, 0xc81447a8,
- 0xbe0daad1, 0xb9417dcd, 0x3e99cb8b, 0xbf05c593, 0x67eb81f0, 0xf3ba7931,
- 0x8416bf0f, 0xcb62bcbf, 0x5f1dd7ff, 0x7f74f68d, 0x6b7d238c, 0xbb92f72c,
- 0x50a8dce1, 0xd9f695f8, 0xf4112ed5, 0x738dbcf3, 0xf3e569f1, 0x742b007e,
- 0x02505747, 0x00000250
+ 0x00088b1f, 0x00000000, 0x7de5ff00, 0xc5547c0b, 0x3d9cf8b9, 0x926eece7,
+ 0x2126cddd, 0x26c2bc21, 0xb80d4401, 0x41a00c40, 0x94520f37, 0xa2a1e1a8,
+ 0x24786c22, 0xf622ef21, 0xddbf1f62, 0x52c488f0, 0xd4c51f1b, 0xb051768b,
+ 0x40368bd1, 0x5c1758d0, 0x6d8b459e, 0xd5a045e8, 0x5e40137a, 0xa540b206,
+ 0xcffd45b6, 0xdd9ccdf7, 0x26364e73, 0xf6ffef6a, 0x9fdbfffe, 0xcccce61d,
+ 0x7cdf3337, 0x9be6bdf3, 0x91be6489, 0xf21387d8, 0x256efc25, 0x108951e4,
+ 0x9b4e1892, 0x9fc6933c, 0xedb10994, 0x3bea247e, 0x9e0c8499, 0xd146706b,
+ 0x64085fa2, 0x21064b4e, 0x758d65c9, 0x793dfa46, 0xe8bc7d91, 0x9819c308,
+ 0xbdbae47c, 0x720c8409, 0x8266f6d3, 0x7fe92fbf, 0xc637b73f, 0x79c87491,
+ 0xe131a285, 0xbc9a4afa, 0x877bfa48, 0x149bbeaa, 0x48dda675, 0xfd51fbfb,
+ 0x9085b720, 0x4678c31f, 0x40cba942, 0x78b8e8b2, 0xfd2e6f5d, 0xaf0e3a3f,
+ 0x295be8cd, 0x1c1a2210, 0x242444b1, 0xa0482326, 0x679fbe9d, 0x49d7ed3c,
+ 0xaa36a708, 0x49e74ac8, 0x0896b4c8, 0x808972f5, 0x76cd8878, 0x78e97b25,
+ 0xe22e7d57, 0x220d57bc, 0x27d69da4, 0x684ed392, 0x61c4953a, 0x232dc7bd,
+ 0xd57e4206, 0x07123fae, 0x199b1b85, 0xdc155e24, 0x0e210f06, 0xc7afc513,
+ 0x8f2ae98c, 0xc4c9a79d, 0xab210d71, 0x574c0e3d, 0xfa634679, 0xdb27d0d8,
+ 0xf9d00673, 0xe9d8320c, 0x63834848, 0x1191dda6, 0x2dc72786, 0x0938e730,
+ 0xae2926c9, 0x2f5a54c4, 0x4dc840d1, 0xf342dc84, 0x19082375, 0x5084ec49,
+ 0xbc933dfc, 0x019dca2c, 0x45e60779, 0x7cc37103, 0x2e033263, 0xc62de291,
+ 0x1c95cf69, 0x1bf8efe1, 0x785fdf80, 0xc1d6152c, 0xefcc1b7d, 0xf0ece219,
+ 0x46dd9e02, 0x7f5a26e7, 0x5e4ceca5, 0x468ae14a, 0xad832eda, 0x1e1094bb,
+ 0x1fc04cdf, 0xc9cc8fed, 0x30d7acd5, 0xb4224718, 0xeb05dc73, 0x75b27164,
+ 0x1574095a, 0xf2e61d61, 0x77655875, 0x38fd19d9, 0x11fa2449, 0xb1fa5aed,
+ 0x8fe96864, 0xba9fb17e, 0xbf69e79e, 0x3bed424d, 0xbd3ce953, 0x4dce0c4b,
+ 0xa160dbf4, 0x0af80051, 0x80c425bc, 0x41f92afd, 0x63a05265, 0x179e1ab4,
+ 0xf6f7e9cb, 0xefcf730e, 0x52e2062d, 0x2a5372e8, 0xcec4777c, 0x6626e3a0,
+ 0x6b4cec47, 0xe987f1cf, 0xc925d924, 0x4c0eef40, 0xac47041b, 0x477ce300,
+ 0x9c049b24, 0xf6a4727f, 0x08edd3ff, 0x377ae1f1, 0xda5475f0, 0x3d203c51,
+ 0x468b1f79, 0x3450883c, 0x17e70c39, 0xad17cf1c, 0x4a434f45, 0x5868e348,
+ 0x875f9a5f, 0x79a663f4, 0xb09be62b, 0x3fca1edc, 0xacc9e58b, 0xba5e5d3e,
+ 0x55e3bd18, 0x6eda1759, 0x4291c203, 0x38445e70, 0x9bbf5096, 0x94203f30,
+ 0x1fd625ff, 0xb7f7eaca, 0xceed251f, 0xf9c29e0d, 0x003b2ebf, 0xd6dbc29f,
+ 0x2e94adc0, 0x7c106e0e, 0xec0f9a26, 0x75fe418c, 0x9f0cfd7e, 0xd767e289,
+ 0xea0b9338, 0x8398df9f, 0xefedbcf9, 0x5e5a24db, 0x20945db5, 0xd679d86f,
+ 0x5bf141d6, 0xfc7f6a63, 0xb83dfa66, 0x602f245d, 0x9f71d377, 0x48b4e29d,
+ 0x92f9633e, 0xdaad9628, 0xc01e6bb0, 0x91336b2d, 0xeaa70a28, 0x6f3bd2cd,
+ 0x03d2f9a6, 0x552a8132, 0x838cea9b, 0x4f897e69, 0x8afc8168, 0x3f601f9d,
+ 0x0ca4b9dd, 0xe039f7f6, 0x752f945b, 0xee93dadb, 0x7dcbdfa6, 0x7ea00a5b,
+ 0x09c166f9, 0x7ebe5c4b, 0xbf0087d7, 0x211e55bc, 0xcd15f852, 0xdaa1c431,
+ 0x17db792f, 0xade309df, 0x9426477a, 0xabb291ed, 0x1891190f, 0xe02346a4,
+ 0x13d36ab5, 0xe79be046, 0x1fb0073c, 0x2f559f05, 0xbb687ed3, 0x2704d7ea,
+ 0xc0daad4c, 0x3785cdf8, 0x68bce6a3, 0x19d57981, 0x37fb4147, 0xbd42351f,
+ 0xebf15f52, 0xdf180e51, 0x8c016306, 0x6306fd73, 0x566f8a89, 0x3356ff34,
+ 0xe94d53ae, 0xbd19dd03, 0xce39e7af, 0x397c95b7, 0xdf484015, 0x4338cf92,
+ 0x339e87c5, 0x57fd21c4, 0x11c48b34, 0xdf781f81, 0x8760fbe7, 0xbe03f195,
+ 0xc0ed4b5e, 0x75ebc21a, 0x4fd7cec9, 0x88cd660a, 0xe71ee7c0, 0xcb91a3f2,
+ 0x7e41278f, 0x2e69f4d0, 0xf971d63f, 0xe271e4d1, 0x933d67f7, 0x71ef5d30,
+ 0x67bcfa61, 0x4f3ea61a, 0xc17bd611, 0x8dd30733, 0x7f7e371e, 0x698653c9,
+ 0xbf16a7b3, 0x8e59e2bf, 0x178f66e9, 0x59e6bfbf, 0xa78b6983, 0x9eadd311,
+ 0x3d5b4c26, 0xbaf7ac3e, 0x36d319a7, 0xff7e0b4f, 0x530da7b5, 0xe98027bf,
+ 0x9a5f584e, 0x98ed3c06, 0xc31cf6ee, 0x03a7af74, 0x9cf7eddb, 0xc72d74c1,
+ 0xe49b2dbb, 0x366f1448, 0x18394117, 0x91cae85f, 0x88be3e69, 0x7ae693e5,
+ 0x9f348c73, 0x8a79a6e4, 0x8195c1c7, 0x0fcd131c, 0x29e565ae, 0x66b9243f,
+ 0xb2f14f9a, 0xaeb5b4f2, 0x4f9a28dc, 0xa3e5646b, 0xa3737bd6, 0x8f947e69,
+ 0x39b75f95, 0xf3431b90, 0xf2b0b5d7, 0x67927eb1, 0x01b1f9a1, 0xd07f1f96,
+ 0xf9a56795, 0x9f2cedf1, 0xcf37a1f5, 0x1d59f346, 0x5d4dfdac, 0x9a58bc81,
+ 0xcac829bf, 0xf24ab96f, 0x2e4003ed, 0xb5cf980b, 0xd1c7e4e4, 0xe59dae7c,
+ 0x4b16860b, 0xb7f4088e, 0x0858ee53, 0xb0867c22, 0x7e5125d1, 0xf1d8d3b3,
+ 0x647d1510, 0x4baaf0a1, 0x2033fca2, 0xfe504593, 0x963af0b0, 0x19648c07,
+ 0xbc2a3f94, 0x65bbe58d, 0x5cff9607, 0x46f2c038, 0x87ff9607, 0x7bf30870,
+ 0xef961765, 0xf2c4fe10, 0xff961746, 0xf981385e, 0xcb1bb2fd, 0x962e853b,
+ 0xfcb1ba37, 0x5753e949, 0xdf2fed3e, 0xdc2e9ee0, 0x5ddb7208, 0x6a597286,
+ 0x597e0649, 0x04fff9cf, 0xaf2d0640, 0x3944641f, 0xacf3f3b8, 0xd3814517,
+ 0x97c800f6, 0x05fa04bc, 0x485b3385, 0xc2827d04, 0x7386fb11, 0x349317cb,
+ 0xa2f96e70, 0x20f3814c, 0x1fea89c2, 0xdc5f9d9c, 0x17cf1da4, 0x129c0ae5,
+ 0x7fb5979c, 0xcbe5baf3, 0xbe78ed6c, 0xd4e054ac, 0xfeb89c20, 0x4f20278d,
+ 0xc809c0d4, 0xe59c0aa5, 0x7fb12708, 0x271971e3, 0x8cb8e06b, 0x7538144b,
+ 0xff506708, 0x378c04e0, 0xac63c76b, 0x863ce050, 0xbfd61e78, 0x534cb979,
+ 0x5531e3b4, 0xc29e7029, 0x0ff6a4f1, 0x16ab6ece, 0x21adbb3f, 0x3847acfc,
+ 0xaf37fb23, 0x3f169b5c, 0x7e10b6b9, 0x6b9c2136, 0xb76707fb, 0xdd9f8b4d,
+ 0x5e7e10b6, 0xe98cfc43, 0x6372bcdf, 0x8dc9f8b5, 0x0de7e10d, 0xfeb8cf1c,
+ 0xa26f678d, 0x137b3f16, 0x2009f843, 0x37fb1b9c, 0x2d24fc9e, 0x4293f27e,
+ 0xe10779f8, 0x9c1fee4c, 0xfc5a49bd, 0xe10a4dec, 0x67080fe7, 0x95e6ff4a,
+ 0x9f8b503f, 0xfc2181fc, 0x7270807c, 0xa94ccddc, 0xbdac70a4, 0x4c3fd9c3,
+ 0xc3fd9f8b, 0x8939f842, 0x3852a670, 0x29c37de9, 0xa7e2d148, 0x9f842520,
+ 0xb6e708f3, 0x9fd9c1fe, 0xfecfc5a2, 0xae7e1094, 0xfa3b9c20, 0xe182af37,
+ 0x0c14fc5a, 0x55b9f867, 0x8672871a, 0xd8274eca, 0x9a19dfe7, 0xc13212e3,
+ 0xd179624e, 0xf7a024ee, 0x433e8a88, 0xad225dda, 0x371cd96f, 0xd6a231fe,
+ 0x068d726b, 0xaa56cf4a, 0x9af5a9e5, 0x1ad149d8, 0x15ce2a3d, 0x4c27c9af,
+ 0x9fa9ac1b, 0x29a69458, 0x3ae7381f, 0xf720f94d, 0x487e4d78, 0xfa9a4dd9,
+ 0x35736ac3, 0x6fcbe1f9, 0xf54fd4d7, 0xd3e4d4ce, 0xa9afdcd7, 0x8171b23f,
+ 0xa69afca6, 0xb5f94d72, 0xfc9aa5be, 0xd7dfcdf5, 0xb2d31fd4, 0x437e5342,
+ 0xf29a63db, 0x35278171, 0x9e0709f9, 0xb1bfd4d5, 0xf94d05fd, 0x68af63c4,
+ 0x6c7727ca, 0x3e6fe4d5, 0xfd4d6bf3, 0x9addc129, 0xbd9fadfc, 0x439fa9ab,
+ 0x6fab53fe, 0xd4d03f9b, 0xa13f6a9f, 0xf24eff29, 0x553d3a27, 0xccaf1f6b,
+ 0x32afcc21, 0x01afd988, 0xc6f311ab, 0xa76616c1, 0x271c4b58, 0x7718fd29,
+ 0xa00c742f, 0x033403f4, 0xe0ce5176, 0xe83a6bb2, 0xe4ddeff7, 0xbf4ec6be,
+ 0xbee8cf7f, 0xbf411ec1, 0x9026f4a1, 0x061d4864, 0x8fe5f548, 0x73de8cca,
+ 0xd51d5c87, 0x18d7db49, 0x68e2a382, 0xe73123fe, 0xf9c7a03e, 0x83ee0306,
+ 0x42d49168, 0x411368bd, 0xd4d1e9bb, 0xaabd17ac, 0x1866b0fd, 0x308433d5,
+ 0x3bb235dc, 0xc328f519, 0x9bd03af8, 0x79d187ea, 0xd164260d, 0xbcbb718a,
+ 0x61fb6823, 0x8fe0c925, 0x3f991930, 0x91bfd424, 0xfd819ff6, 0x6bfe812f,
+ 0x94dfe97a, 0xbfd34936, 0xd34ca539, 0xfb48d9bf, 0x90f213b7, 0xbfde26e1,
+ 0xcb36fd19, 0xfec64c56, 0xd865294d, 0x6a46a3ff, 0x8ffba977, 0x88fff50e,
+ 0x31ebf681, 0xc7b9bb30, 0xd26ed3fc, 0x5ca53fce, 0x9b237f3b, 0x2e434aff,
+ 0xe71a3fef, 0x0e456abf, 0x394a7f9b, 0xc189bf9b, 0x0b6ff50d, 0xfa01bfe1,
+ 0xfd2f69ff, 0xb5b3d29b, 0xa95e1ff3, 0xf589bf9d, 0x76e194ff, 0xfb05bfde,
+ 0x6dc57a7f, 0x2bc3fe6c, 0xc9a37fb1, 0x31fa04ed, 0xf5ae890e, 0x50c9fed1,
+ 0x040d256a, 0x40fda172, 0xfd1e3a3a, 0xd21a7708, 0x8bdf1c70, 0x2576f466,
+ 0xf21bd29a, 0xc3b32f33, 0x5273947d, 0xd39aaabb, 0x1ce6c57a, 0x2c3df023,
+ 0x3164224f, 0x36a2ea1f, 0x3c9be911, 0xa48df26d, 0x26d0bde3, 0xe8bf217a,
+ 0xe03e29e9, 0x322635af, 0x49da08bf, 0x3fdf0024, 0x1798d9fe, 0xa7d2f3d4,
+ 0x53e51b8b, 0xde45fc91, 0x96ba325c, 0x1002ef8e, 0x9c7f2a81, 0x186071da,
+ 0x1eed487f, 0x139fed42, 0x23efeb32, 0xbe41ef6a, 0x687bda83, 0xe63a9338,
+ 0xdebaf357, 0x5fc7411f, 0x0b9f9444, 0x6e2f79e7, 0x624f0a29, 0x5af8f7fb,
+ 0x31eb07c1, 0x450c797f, 0xc53c787e, 0xbe4d04de, 0x07eac4c6, 0x2f7c136f,
+ 0x0dc30808, 0xe1c199f8, 0xcd2f1811, 0x36b3b1cf, 0xb1de7747, 0x7dd1b05f,
+ 0x5d0866b4, 0x599c308b, 0xa40f25c4, 0x565eefed, 0xa76b832c, 0x8186105d,
+ 0xa166b09f, 0x3768024c, 0x0649137b, 0xde3a0e27, 0xfe0cedfb, 0x527c970c,
+ 0x239b47ed, 0x74455d9b, 0x458a733c, 0x69acff1c, 0xed3ff2da, 0xc619718c,
+ 0x53cd74d2, 0x45ddcfd8, 0xe77bf2da, 0xb9f7f368, 0x572a79b5, 0x0fab9065,
+ 0x53bfe994, 0xdf8124b4, 0x001bf431, 0xe3907ce3, 0xd95ac1e1, 0x6a5759ab,
+ 0x72951b76, 0x09b88470, 0x8bdb0bce, 0x5fcfeb3d, 0x7b17cdae, 0x6b85f9b5,
+ 0xdd39f074, 0x7febe29c, 0xa683e81c, 0x283e81a7, 0xfa724f3e, 0x2d55f308,
+ 0x9a13dc7d, 0x650fa306, 0xb624a71e, 0x33d6a704, 0x18dc58fa, 0x8a1e9913,
+ 0x52e0f443, 0x0f4297d3, 0xfc3d38f3, 0x6943d399, 0xeeae9693, 0xc9d5be23,
+ 0x6b03fdb4, 0x1d3ae177, 0x3d198a11, 0x87a140fc, 0xb83d0d0e, 0xd7e83d39,
+ 0x87a71e6f, 0x7a308f79, 0x0767afd0, 0xa68e87a7, 0xeb4932cb, 0x1d74aeb9,
+ 0x0eba7934, 0xa3b775ba, 0x47ae8a1f, 0x10587a44, 0x389d379a, 0x65e42fcd,
+ 0xd38bd63d, 0x01a79603, 0x09e209da, 0xacf7a7db, 0x2684f94f, 0x7914da5f,
+ 0x36da6bfd, 0xfaa93dac, 0xf2f2d55e, 0xbb7fb55a, 0x268b79a2, 0xa6f7c4bf,
+ 0xd3697ea6, 0x717e4d2e, 0xfa9a3be3, 0xd21cd70b, 0x7fbd8be4, 0xbf9fd4d4,
+ 0xfe5353bc, 0x4d59ed60, 0x176503f9, 0xdcfbf935, 0xbfd4d37f, 0x13f08e77,
+ 0xa2eefe75, 0xeba89fa8, 0xa7169acf, 0x0d70cfc9, 0xec37d4d2, 0xa02ef6bc,
+ 0x8bef83c7, 0x4f8ff404, 0xffd1a79d, 0x7653a9f9, 0x1e939d42, 0x5383ee07,
+ 0x9e98d19e, 0x9f7138f1, 0xc24cf39c, 0x1edb42f4, 0x2a15c80b, 0xc8e04b47,
+ 0x96e574a6, 0x20d935ba, 0xdfca09d7, 0xd46f958a, 0xb2128779, 0x8a639414,
+ 0x2326c2ef, 0x44204c09, 0xc7c4e100, 0xe5551415, 0x37947d1d, 0xd0914151,
+ 0x23b0bcb3, 0x279af7f2, 0x23db878b, 0xf7847f9c, 0x7a021935, 0xe72f7752,
+ 0x29029524, 0x64277f52, 0xad81f205, 0x34a94f5c, 0xb9517e32, 0xb12e5075,
+ 0xaa303e41, 0x6bfaabf6, 0x206c9ba1, 0x66ba49d0, 0x5d36973f, 0x04f7e1af,
+ 0x4089cfbc, 0xdf34136f, 0xd66f9a2b, 0x25daebb4, 0x81abb8e2, 0xfdb95097,
+ 0x527a292a, 0xd8153e04, 0x0c6b3293, 0x14f5d38c, 0x5112dbe6, 0x34f2ec8f,
+ 0xc7f385af, 0x4c169e73, 0x30da78cf, 0xac09e53d, 0x93c07385, 0x1e98039e,
+ 0xda63b4f7, 0xe98639e1, 0x4c0e9e47, 0xc19cf43f, 0x209e4ff4, 0x9f3cc7a6,
+ 0x43c47a61, 0x0e70027e, 0xfe98cc7b, 0xb4c763c1, 0xe98c93dd, 0xfb0f8f05,
+ 0x5f5df651, 0xcb867774, 0x7f4073ed, 0xbb6ce811, 0xcd6eac78, 0xbd9d30d0,
+ 0xa423f2b9, 0x85cf0533, 0x0f4e264d, 0x087a1a49, 0x2377ed80, 0xe51f4bd0,
+ 0xc3a7324d, 0x2e47dade, 0xbfe179af, 0x7caede87, 0xd30b7a4b, 0x3d1d10d3,
+ 0x4f45f7a5, 0xe9e9aa1f, 0xe4cec18a, 0x1fa7a720, 0x7d6b73f3, 0x3b1251bf,
+ 0x77e90ca7, 0x800cdbae, 0xdcfca5aa, 0x98699084, 0x5efbc4bf, 0xa3b5c149,
+ 0x0d1be81e, 0xe8d2eb72, 0x73828fbf, 0xe8c74b87, 0x3ef6a7e2, 0xf49d3d3f,
+ 0xda17778e, 0xba3e2543, 0xc61109e8, 0x1af0cd1b, 0xc8d32065, 0x461a4278,
+ 0x905ce4be, 0xc4897981, 0x739f7b43, 0x3af38446, 0xc06b7542, 0x5d785f6f,
+ 0x1632bd69, 0xf67a9de0, 0x5e90591f, 0xf475fae1, 0x7cf5111e, 0x09d17812,
+ 0x25c90df8, 0xfc193393, 0x4691c1f3, 0x6409ea3b, 0xde7f16ba, 0x6bf835db,
+ 0xcfce5548, 0x7f11931b, 0x1a8cae23, 0xf5fc0fd4, 0xc2fbdfc5, 0xf79802e7,
+ 0xfb3e037f, 0xf17d8fe2, 0xbc72e245, 0xdfe746d6, 0xf8cc73bd, 0x07c01cc7,
+ 0xcadf1abf, 0x3c7e9c79, 0xb5f492f9, 0x493bb8e8, 0x14f6e3a1, 0x24d85b88,
+ 0xa5fe11da, 0x61626bd6, 0xfa70425d, 0xede14f58, 0xbd80a73f, 0x0b553e7f,
+ 0xef074b2f, 0x6d1781d2, 0x4d2d7760, 0x3270d85e, 0x69283ac2, 0x835d4b55,
+ 0xb687ad45, 0x1a97f369, 0x382d6985, 0xecec472e, 0x6a272031, 0x5edf181b,
+ 0x6702a98e, 0xf6097269, 0x3d39ae73, 0x3e7bd996, 0xc7360fc6, 0xe738bf21,
+ 0xfffac329, 0x06f4f1ec, 0x210f1947, 0x1984e4ad, 0x4b2d31f8, 0xaf7ebdef,
+ 0xc5fd2cf4, 0x7edde788, 0x89e80af9, 0x97dffa66, 0x09107760, 0x9adc0af3,
+ 0xba6bd116, 0xd66fbe01, 0x39db47f4, 0x2fe23394, 0xdf6abed3, 0x4294e448,
+ 0xd45e54b7, 0xe780bd83, 0xd41a4b9b, 0xcb55597a, 0x9af93577, 0xd41a47b6,
+ 0xfc055c7a, 0x525ff283, 0x3740482b, 0xba8c9c95, 0x811acb25, 0x8218af8e,
+ 0x088f804f, 0xb9955eac, 0x9fa6e8c3, 0x75b2b7ce, 0xe77c6deb, 0x8854e63c,
+ 0x3733283b, 0x597239e2, 0x20f9b5cb, 0xaeb7ce67, 0x5bf9024c, 0x5efa5e21,
+ 0xbff68451, 0x5f2e0494, 0xcf56a0e4, 0x2841f4e7, 0xe9bcd55c, 0x17c212cf,
+ 0x981977cd, 0xb70f465f, 0xbe91cb8d, 0xf9bd53f0, 0x8ecdc150, 0x6eaa789e,
+ 0x237468bb, 0xcbffa45f, 0xc149e30a, 0xd454b15f, 0x9771d126, 0xffa27737,
+ 0x1dec8ce2, 0xe0af83f5, 0x67e73d97, 0xa3153e49, 0xb497979a, 0x260b3f43,
+ 0xe3888ef1, 0x1f280fde, 0x995bfb3f, 0x57221f00, 0x742cad69, 0xc7bb70cd,
+ 0x61590c40, 0x6b4167bb, 0xfbe02145, 0xd1d3ebec, 0x8a445bee, 0xa40eb86c,
+ 0x9cec0b31, 0x7180c4f3, 0x1fc9e755, 0xeb54136c, 0xe464b1f0, 0x305ca678,
+ 0x1034bb89, 0xd8107bbe, 0xf539a65f, 0xf858e2ed, 0x9076292e, 0x15ca25f0,
+ 0x17f180b7, 0x2f77d873, 0xfd01d731, 0x634a7b52, 0x4a7b51af, 0x94f6a793,
+ 0x66425f26, 0x453c4126, 0xf132d3c9, 0x4d278809, 0x8ec941f9, 0xb5252be3,
+ 0xfd1fa0f5, 0x16e1fb9c, 0x843489d8, 0x37aa87ca, 0xa62acb9e, 0x9892e9f3,
+ 0x0f894bff, 0xc5654258, 0x5e5e5a20, 0x2cba33e6, 0xa277e73d, 0x943dc275,
+ 0x163c03f3, 0xd1bf7007, 0x886be2c7, 0xaae2ca43, 0xf3ef5a4f, 0xba2ad81f,
+ 0x8f506ca2, 0x9bc6577e, 0xafe7f5fa, 0x4f212f9f, 0x9bca3ce2, 0x561c6067,
+ 0x3e07788f, 0x7059b91f, 0x27ec22f9, 0xf1341651, 0xc332092e, 0x1ad7e29f,
+ 0x0f5fcbae, 0x6bdf9579, 0x1bfcaea2, 0x440197f3, 0x258a5fc3, 0x913970f7,
+ 0xbfc013f1, 0x7f710520, 0xc9f8637d, 0x2f5fe03d, 0x844ff8df, 0xefbb543f,
+ 0xff89fc29, 0xe88ff1d4, 0x48bcfe31, 0x78deabf0, 0x778875f5, 0xcfd5ff2c,
+ 0xb7ee846c, 0x926352b3, 0xe57bae93, 0x1736d5a6, 0x6bc91df0, 0xd6717d83,
+ 0x448b4e27, 0x7997df0f, 0x59711fdc, 0xc2bbf004, 0x73fc293f, 0x4ef8fcaf,
+ 0x6caea3b0, 0x4fe8ed92, 0x4c05366d, 0x5bab9e94, 0xb1921497, 0xf964ef98,
+ 0xfd022f47, 0xc7c9b4d7, 0xfe5a74d5, 0x41259fcb, 0x94a5107c, 0x48648621,
+ 0x549f6803, 0x00b8fc6f, 0x121a8df4, 0x6faafdc4, 0x167ffd07, 0xd8b0f28f,
+ 0x1cb3db18, 0xd049341d, 0x5a6afd9e, 0xb4517c7f, 0x69db7a41, 0xb2d46fe0,
+ 0xbe90bf44, 0x3bb7195d, 0x00eb642a, 0xc913abe4, 0x0aabe044, 0xd98f885e,
+ 0x7e5f2b1d, 0x1d276c66, 0xdfc6d757, 0xbe1504da, 0x52e97b14, 0xfc5fc2cb,
+ 0x1f3bd1da, 0xa3f740bf, 0xe455bf5a, 0xdb8da394, 0x56967e4b, 0xc41b01ca,
+ 0x906e5573, 0xb9fa5e9d, 0x5f17d5f2, 0xd9fc167a, 0x4739347f, 0xaf15f852,
+ 0x13723bee, 0x916c57cd, 0x69b21407, 0xf0a48458, 0xffd0d4fa, 0xaf0f8f96,
+ 0x7db6f947, 0xf618c746, 0xe1f187fd, 0xb2d8a975, 0xf4c648cb, 0xcb5e47c4,
+ 0x2587632e, 0x74b4fac2, 0xb7fe8016, 0x1abfe5f2, 0xdd9def81, 0xa9819029,
+ 0x61b9f011, 0x8087ea1f, 0xbe4f5c27, 0xd3f5a15e, 0xeba1afd5, 0xbf467202,
+ 0x857afa5e, 0x5c00bf9c, 0xf4a1b388, 0x21afdafd, 0x264fee0e, 0xeca1e027,
+ 0x306c87b5, 0x2d52d39f, 0x56e7f3a3, 0x2bbf0127, 0x7649bd93, 0xb2f7d94c,
+ 0xfa461fe7, 0x70f43d2b, 0xba57f312, 0x76501906, 0x3cc1077a, 0x1bbfaf17,
+ 0xdc4259e7, 0xcf658748, 0x9a3e4589, 0x69912a7e, 0x93ec225b, 0x9c9f7c4b,
+ 0x2e2e817e, 0x4569e79d, 0xe441fc2e, 0xe8bbe172, 0xcf987d0f, 0x98906a85,
+ 0xd6ccd4ff, 0xd06c80eb, 0xfd10d1c8, 0xe5147c6e, 0xae61b9c7, 0x56ee7081,
+ 0x28179613, 0x5343c447, 0x6275b207, 0x51db0772, 0xdf0793b9, 0xecbb7ea1,
+ 0x69ab1a8a, 0xe9467287, 0x9fef197f, 0xf41a3b8e, 0x9149d3b7, 0x46e191ed,
+ 0x3d500f85, 0xaa674543, 0xfff6cefd, 0xdfb606c6, 0x9beffd95, 0xffca0d31,
+ 0x23ed9872, 0x97720768, 0x10302b8e, 0x16cd77cb, 0x48983f90, 0xdf3ed220,
+ 0xae7df328, 0x0bd3d72d, 0xc424bf1d, 0xfa06e8aa, 0x4075c789, 0x34f25f79,
+ 0xa3e2af6d, 0xadafd035, 0x1f655c27, 0x707e7297, 0xf5c1f81e, 0xd6407e61,
+ 0x5e2bf627, 0xbdf652b4, 0x5fec2cf4, 0x0ebd5fba, 0x1172bfd8, 0xcd93ffcc,
+ 0x4fdc8e7b, 0x2d27edf7, 0xf2d5beca, 0x2dbefd55, 0xc630fadb, 0xedf7eb9f,
+ 0x496b4327, 0xbf4b7dc4, 0x43b7dc47, 0xf847fe3b, 0x24c782aa, 0x2aaf96a3,
+ 0x7c37b27c, 0x16e4f9ea, 0xd57881d9, 0x3bfa49f3, 0xd27ab24c, 0x0a8742a3,
+ 0x47ff95fd, 0x47e070d5, 0xe8553a21, 0x0aa74430, 0xade7ea1d, 0xfcbea3c5,
+ 0x522df023, 0x537a297a, 0x4a95f3c6, 0xa6038b3f, 0xc90ff6ed, 0x50b97c44,
+ 0xfdc691cc, 0xf3a80643, 0x45be5d3e, 0xcba5df57, 0xbbeae917, 0x4d5af975,
+ 0x3db6cafd, 0x10748246, 0x9713d4d0, 0x31393bff, 0xfadd1221, 0xf5a1bf98,
+ 0x39ee11a2, 0xd88258d4, 0xbc415e5e, 0xdc191f10, 0x51b9e221, 0x3d71c537,
+ 0xa73637f8, 0x8f94bcfa, 0x7e628eac, 0xd07b6e85, 0xd5d34f16, 0x4c1f2c71,
+ 0x1f03d634, 0xa307be54, 0xbbb1df98, 0x538b6828, 0x7e9d5bd9, 0x8778f911,
+ 0x0dbdf22f, 0xdd70692a, 0xd7b97a3b, 0x758f9ca1, 0x62c6db47, 0x3e29d17f,
+ 0xa2a9c7a0, 0xf8396525, 0x27451aa1, 0xea8bece8, 0x79c1b5ee, 0xfd3fb755,
+ 0xfbf439ae, 0x164477e2, 0x4975e38e, 0xd0765483, 0x975de219, 0xf05c402d,
+ 0x859fa45a, 0x2d17667e, 0x3f791b5a, 0x2576f394, 0xe0466596, 0x390ed4bb,
+ 0x51ef3eae, 0xd7ad94e0, 0xe74ff77d, 0xed11a6fb, 0xda8df2ff, 0x9fb73772,
+ 0xfce4647f, 0xc7191c67, 0xbfe657ed, 0xaa7b7ce1, 0x1cd77198, 0x07dd3eba,
+ 0xf9a26244, 0xd7117e4b, 0xc166d2e7, 0xe237fe07, 0x57fdc44d, 0xf546824d,
+ 0xd82e887d, 0xcef4d75f, 0xffb6bac7, 0x4007eb39, 0x307faf47, 0xda69dff6,
+ 0x471ffaf5, 0x37f905bd, 0x407ca68e, 0xdbcfd67a, 0x02f18519, 0x48ad3bdd,
+ 0xde3bddff, 0xe401f94b, 0x613934df, 0xff3bdd9c, 0xa9e8163a, 0x0ca9857b,
+ 0x30f760f8, 0xb95dbfe6, 0x3b63afe3, 0xc2aefe50, 0x1a366c75, 0xffc99f99,
+ 0xdee08f8f, 0x9d3f25c2, 0x3c17e815, 0xd7e6beae, 0xf0823e51, 0xbea59aff,
+ 0xe76df40f, 0x43e3cd53, 0xce64adba, 0x1c5f1856, 0x79a87f8b, 0x758bf26b,
+ 0xd6aaffb4, 0xb485c65d, 0xcfedef3c, 0xfd1c62c7, 0x5d37a656, 0x879e3b90,
+ 0xc66d87f8, 0x2994acef, 0x26c02f9e, 0x5df646a3, 0xb07935a6, 0xe5e27a8f,
+ 0xf5a7f473, 0x1aef1f17, 0xaffd7d99, 0xc5c10f8f, 0x67d59ff8, 0x7fde6016,
+ 0xf403e8fb, 0x2e909a83, 0xd27ef995, 0x4cfa8752, 0xfb3ef35f, 0xfa0e86bf,
+ 0xd0216f3b, 0x4d9b799f, 0xfdebdaff, 0xeb81d1b8, 0x3d07dfa2, 0xf7c77ce9,
+ 0xd5aaff30, 0x27ede389, 0xfd368fbd, 0x5beeb63f, 0xfadbbae9, 0xfe77f79e,
+ 0xfbdde7c5, 0x8f33bfba, 0xce1dbbaf, 0xfede6b53, 0x75f7c71c, 0xffe95cf9,
+ 0xf457ba52, 0xad4376fd, 0x6f8e933d, 0x82b4690e, 0xe25f7162, 0x03a64b25,
+ 0x0f2f70a2, 0x383bf8c0, 0x57608d5f, 0xbf989935, 0x581824cd, 0x82dddabc,
+ 0x3b4447e2, 0x5fae4eeb, 0x0cb439dc, 0x5d3b90f5, 0x827d413f, 0x39edb548,
+ 0xee7b7eb4, 0x6ac62742, 0xdcc7f192, 0x853d9f90, 0xe6f6b5e7, 0x12e204ef,
+ 0x677f7ea8, 0xa003f4ee, 0x12e5dee7, 0x29a60f51, 0xa7efbfea, 0x93efb014,
+ 0x7dd0f6b4, 0xdefe6d6e, 0xddfcda39, 0x843dde1c, 0x229eff8d, 0x587e07c1,
+ 0x8953ce53, 0x2d3597e0, 0x0a908996, 0xabb54671, 0xbbb8eec1, 0x197edb48,
+ 0x7f2a6728, 0xe3c537e3, 0x5c78436f, 0x3921788a, 0xed03de22, 0xdc7c8f13,
+ 0xf9c7b3ed, 0x489ace20, 0x7bc7864e, 0x37e89caa, 0xccb8f6e7, 0x3596cbdb,
+ 0x659fb0ed, 0xd8ae1d9d, 0x9be1bdd3, 0xe11cfb70, 0x2ff185a4, 0xcfb444bb,
+ 0xae7d9d65, 0x5dd7cbac, 0xbf1d650f, 0x073cbaed, 0x786372eb, 0x5c5a865d,
+ 0xccabf604, 0x8b7c87ed, 0x1687e593, 0xe8ae7611, 0x00d2fac3, 0x8466f117,
+ 0x9897d1e3, 0x9ce02b8b, 0x405a3ccc, 0x6b5dc87f, 0xe60f9445, 0x55c7010c,
+ 0xf8c64934, 0x450d8fe3, 0x85deb059, 0x7f562613, 0x09c30d9f, 0xf1c25cf8,
+ 0x516a425e, 0xbf57257f, 0x0b3b32fc, 0xea0825ce, 0x845c4bbf, 0xb8ed41dc,
+ 0x10216c92, 0x126af10d, 0x078ec6f1, 0x8e40b93f, 0xdae4fc6b, 0x496efc3c,
+ 0xabe9c30a, 0xe5fc6f7e, 0x17fe9d9f, 0x29c767e5, 0x3a427491, 0xd497bb12,
+ 0x3f7cf776, 0xa54d63c3, 0xba434be0, 0xfbeac80b, 0xb66605d3, 0x87ebfe0f,
+ 0xe64f9013, 0x2c4c74fc, 0xe26407f3, 0x6e1ac47d, 0x3af25c37, 0x760fc162,
+ 0xcfce9fc9, 0x6a6cf373, 0x87a4aabe, 0x9ffe1db8, 0xd3489710, 0x51a17cee,
+ 0x048b3b04, 0xcdebffd1, 0xc57bc28f, 0xcca376fa, 0x6bafbe06, 0x3f002fd1,
+ 0xf2afee11, 0xa6d29479, 0x75aaf1b1, 0x59c77b5b, 0x75cf6c69, 0xd571df80,
+ 0xc5b7ddf9, 0x80fdd82f, 0x1d5143d7, 0xe6114505, 0xafe3893b, 0xf0dff770,
+ 0x7f4ceafe, 0x99780caa, 0xce6a2f99, 0xee669df9, 0x264098cf, 0x770ab8c0,
+ 0x0c9b66df, 0x744072eb, 0x1ad57dc2, 0x3ba345ff, 0x1eb1f9c2, 0xfc1f009f,
+ 0x676427f0, 0xc4f3e009, 0xd808a24f, 0x73f1efd5, 0xcfb80cc9, 0x1eae8191,
+ 0x731df817, 0xb84fcccc, 0x74c76cce, 0x9c8e6156, 0x68cdfb48, 0x50838fb5,
+ 0xfebcc1b5, 0xcb03b33a, 0x4a76f087, 0xac95c1bd, 0x5ed1a75e, 0xbffe691d,
+ 0x79f8128b, 0x937bf399, 0x75bd7f84, 0x35a9f9cb, 0x41fa0b90, 0xd167e2be,
+ 0xfdc135d3, 0xe09a6971, 0xf60df903, 0x050be630, 0x53de1fd4, 0x64cfafee,
+ 0x7ba15672, 0xcdab9e3d, 0x1e02f7da, 0x887f78e7, 0x678287d3, 0xf1fabf05,
+ 0xbf29f52a, 0x9fed55ba, 0xdc6dabba, 0x54dfa06b, 0x81bb05fb, 0x3a96aa82,
+ 0x6b0fb08c, 0xe1909eda, 0x073ee67c, 0xa2a44b83, 0x83f8eab1, 0x0f166675,
+ 0xcdfc67b2, 0x2e4e80f3, 0x2c8135af, 0x1745ae24, 0xdf87c06d, 0x0f7f3833,
+ 0xdfde6c71, 0x57d36489, 0x3c0fabf0, 0x597cf2f6, 0xe715370d, 0x4732ab33,
+ 0x03da7706, 0x81e4bb95, 0x675a7a2a, 0xe572c78e, 0x074ae0fb, 0xfb420fbe,
+ 0x1f7871c3, 0x4fb81137, 0x8ed2d192, 0xa81f6cf7, 0x5874638d, 0x88cbb2d6,
+ 0x7bcd54f9, 0xfa3f4a22, 0x50bb34fd, 0x30bcaf1b, 0xe02863af, 0x5814d0a5,
+ 0xa7408ce6, 0x7394a393, 0x2729afca, 0xc76e945c, 0x27247ffe, 0xa2722996,
+ 0x95e3e303, 0xe7df02f6, 0x3031392a, 0x5a589c92, 0xeb0818e7, 0xfa4774b0,
+ 0x4b24d840, 0x149a99df, 0xefbc4e49, 0x47cce761, 0xeef67df9, 0xdc4e54d9,
+ 0xb31392a0, 0xf44e90a3, 0xf6513eed, 0x42725f49, 0xcbffb759, 0x907de6fc,
+ 0xf7f61113, 0x71393a17, 0xe518bf8f, 0x45b33dc4, 0x4facbdcd, 0x391394fb,
+ 0x5e61f749, 0xa044c676, 0x7db9f79f, 0x0bdf9473, 0x5e407e80, 0x11d94664,
+ 0xd1b97a6f, 0x53ff5f1b, 0xfffaf97f, 0xbe159e10, 0x3fda94be, 0x7448d4a6,
+ 0x979e9048, 0xbaf947de, 0xf8c8f400, 0xb907d2fa, 0x67c7539f, 0x66cf808b,
+ 0x6b2cf9aa, 0x7266ed5f, 0xf52da6a1, 0xfcb4b999, 0x09d946fe, 0x30fef2a2,
+ 0xf352cddf, 0x5ea8ccdd, 0xe3196ef8, 0x13fd97bb, 0x6dea7f50, 0xfce67f7e,
+ 0x11b3f296, 0x31f408ce, 0xe68c6e67, 0x7189dede, 0x06d8c9bf, 0x113de5fb,
+ 0xe63f79cf, 0x71c1c07a, 0x7d04c9bf, 0x9e3e49fa, 0x2f3d7c79, 0x3e794878,
+ 0x22de5fc5, 0x6d574fa6, 0xd57f1116, 0x57ff6cad, 0x073e0b37, 0xff8c17cd,
+ 0x56d79e1b, 0xb5e760ec, 0x39850674, 0x78aff5aa, 0xce1ea3af, 0x08362a09,
+ 0xf70cde78, 0xa59f001e, 0xce259f1c, 0x29573c0a, 0xc1fad26d, 0x2f6da21b,
+ 0x1e101b90, 0x78abc3fa, 0x105342fd, 0x7f0a1dcf, 0x20373829, 0xabb6d49f,
+ 0x59fb711a, 0x9a2a4fb0, 0x0d9ddf75, 0x3704ae78, 0xadaf41d4, 0x7b96d16a,
+ 0x8b17bcf8, 0x146d8c81, 0xb33df93e, 0xf778f4f3, 0xf653f1e8, 0x8873f12d,
+ 0x9ff327e2, 0xfe259f87, 0xf05e785d, 0xc7a2f175, 0x3f145d47, 0x324f181f,
+ 0x6c7e3f61, 0xf17f2170, 0xbbe22bbe, 0x189e8b4e, 0xe50f79a9, 0xef2f1ca7,
+ 0x83f5dc19, 0x80b55ea0, 0x6fd74af5, 0xf34497d9, 0x38c85b73, 0x6d286638,
+ 0x90e3cad2, 0xa0756ffc, 0xbb5b9f7c, 0xdab88045, 0x60befcc5, 0x7c09ef99,
+ 0xe5c1e63f, 0xfad3de54, 0xdc9bc70b, 0x287e5e70, 0x53fc882a, 0x409ddfa1,
+ 0xfa6f94bf, 0x0c4e38f9, 0x9ca3e60e, 0xb8ec136a, 0x4c51032f, 0x8275d16e,
+ 0x4cf66d77, 0x5f016bfe, 0x6a5fe617, 0x4358eb63, 0x75f60dd7, 0x5be79f81,
+ 0x80f83e98, 0xe73b22ff, 0xd992eff4, 0x490238fb, 0x44e77e40, 0x8f915cfb,
+ 0x939aee70, 0x1ddf5aa4, 0x37fe8c9d, 0xe0fc4e09, 0x36fbffa3, 0xbacbdbeb,
+ 0x7f4cfa2a, 0xd3c157d7, 0x1f3add4e, 0x9c2f6a8a, 0x8272e780, 0xf20bdf13,
+ 0xd179e1c7, 0xfef646c9, 0x1fae41cd, 0xd805f7e9, 0x78f7ea1f, 0x21c0c066,
+ 0x145a7a2e, 0xbf6295c6, 0x533f4c69, 0x3bfd29f3, 0x6e375f48, 0xa3b486a9,
+ 0x7f8e165e, 0x066edf74, 0xd04d3fb9, 0x19d149c4, 0x27ffbee1, 0xbea397c0,
+ 0x36493e02, 0xc8797ca3, 0x19eebece, 0x1ef02466, 0x3235e5da, 0x06bdd1d2,
+ 0xe06c91c7, 0x04c98f2f, 0x83e5c7f6, 0x3b9d1e37, 0xa445ca00, 0x26f7e28f,
+ 0xa56b8354, 0x91aac598, 0x5c9847e2, 0xfffbc13a, 0xaed79513, 0xa097786b,
+ 0x7ce27b07, 0xb674bf70, 0x0754d773, 0x0f325bf8, 0xcf7386ad, 0x23f67959,
+ 0x1b1d6047, 0xc74fbbd8, 0x9da1e4d7, 0x0577d0f6, 0xe8c767dc, 0xbb9c017a,
+ 0x391ea767, 0xe0f7c742, 0xb73c449a, 0xbc4aeb9c, 0xe731ce07, 0x0e9d141e,
+ 0x5de16f5a, 0x7f9c0b56, 0x122d1f4e, 0x0f2f0ab7, 0xeff47692, 0xeefdadcc,
+ 0xca4fb0dd, 0xf7843ca8, 0x87fcca9c, 0xfc840ea6, 0xd7db017a, 0xb846dd78,
+ 0x74ded9e7, 0xfb4998d1, 0x00f5a12f, 0x59eb35dd, 0x028d9abd, 0xe25817be,
+ 0x64f9027f, 0x1f0146c9, 0xfaa769c4, 0xf5c199af, 0xbed12981, 0xf9a7b69e,
+ 0x700f6852, 0x03ddc637, 0x743593e7, 0x527ed89c, 0x97539e1d, 0x98b476d0,
+ 0x2efc6fb4, 0x5eb25bc2, 0xb0af7020, 0xe3ea526c, 0x41de0093, 0x47e509d9,
+ 0x08dcfd77, 0xfb479ee3, 0x2fe1441b, 0x42a63b14, 0xc103f27d, 0x152eef8e,
+ 0xbafb8b5e, 0x623bef9b, 0x14e2cd1f, 0xefdca204, 0x2af1d493, 0xb869d125,
+ 0xd7964a9f, 0x3abcc3d5, 0x06a989bc, 0x468ba7a4, 0x2927e390, 0x7f54ddbe,
+ 0x7164613d, 0x27bc7b30, 0xfe2a1d8c, 0x1d3a32b9, 0xcb6a2fdb, 0x98b33e41,
+ 0x853c6114, 0x23e98ebb, 0x7ca3ab9d, 0x94eb57e0, 0x7df029ed, 0x7e136acf,
+ 0x932af0bf, 0x7586173b, 0xf4fb7fa0, 0xbdc0997a, 0xd3eb95c7, 0x9e3ac1d7,
+ 0xe13b2cde, 0x8e7c40dc, 0xbe9411c5, 0x7b64fcca, 0xa7b833d6, 0xcb7f199b,
+ 0x02eeee7b, 0x94a5dbe0, 0x7e70994f, 0xe2563e5a, 0xf53e4728, 0x4be3145c,
+ 0xe7a57e7a, 0x1b8d6553, 0x65a1cb22, 0xd0e59105, 0x37ee7ad0, 0x6b9f2c8d,
+ 0xbbe98588, 0xf078c9e3, 0x0d571663, 0xf404d79b, 0x70bb20fc, 0xf3781ed0,
+ 0xdc819fd3, 0x3be2b4ad, 0x7d92d565, 0x83e8c09d, 0xeb9fff00, 0xec29f2df,
+ 0x51b9b287, 0x29d90ef8, 0x47d80f58, 0x1cf0136b, 0x8c57c4bb, 0x79e25778,
+ 0xf4b49b4b, 0xef21f8ae, 0xa5c48b73, 0x31655f96, 0x77aaa5c4, 0x6e9447f4,
+ 0xdbf33f69, 0xcab01f04, 0xdcea3fa3, 0xe62670ff, 0xe5ae38ed, 0x6b583f5c,
+ 0xfa3eba45, 0x40d5c5c8, 0x287ef3b7, 0x89dbd010, 0xf20f5dd7, 0x7049bab0,
+ 0xf4b89f80, 0x297dac87, 0x3ee30f6d, 0x5f4673fa, 0xb01dce94, 0x3fd7aa0f,
+ 0x6feb1fb1, 0xff001c14, 0xd46286e8, 0x22bcca27, 0x9d8df2c1, 0x79504768,
+ 0x7b68f185, 0xec1262bc, 0x2655ea83, 0x1562b83b, 0xb3e8527a, 0x40a7bf93,
+ 0xb3b1cecc, 0xb4673b68, 0x9eb2f903, 0x4239c52e, 0xfd029e48, 0xbd1978d4,
+ 0x3b2abe75, 0x4df48b61, 0xbd1eec9f, 0xd0227f42, 0xfe98665f, 0x33cfacf6,
+ 0xf69e3d02, 0x91671809, 0xf40bf407, 0x9fe2b2f9, 0x1eb51621, 0xea7d17d5,
+ 0xfd07b0e9, 0xe958cbc1, 0xe854fa61, 0xc7874f51, 0x8c0f7225, 0x51d5a1fb,
+ 0xfabc8f38, 0xce59ef37, 0xcf9e19f6, 0x923fd5e5, 0x44bafb04, 0x0a407162,
+ 0x1624ab5e, 0x5c63d637, 0x0719d74f, 0xba7c67f5, 0x0e8acc71, 0x20f1edc9,
+ 0x4a3ea9b7, 0xdf9fb402, 0xe3117e6c, 0xd2bfcf2b, 0x37ea2779, 0x003a516f,
+ 0x92b66ffc, 0x3e21da00, 0xade547e4, 0x1369c622, 0x4b359029, 0x712bbf65,
+ 0xb2bf1531, 0xb7cbbe22, 0xb4857c9a, 0x27ebf97d, 0xc25c62c6, 0x7b7fa60a,
+ 0x39d8115f, 0x2c63b788, 0x972a3bdc, 0x5e8e7c58, 0x345df82f, 0xdebbc3b3,
+ 0x7a03998c, 0xdeccd09b, 0xb96f2c17, 0xfca93657, 0x65a2fbbb, 0x939e1ea5,
+ 0xc33ae979, 0x3e300afb, 0x4a76fbf5, 0xcbd74e5c, 0xdbcafe8c, 0xcae7d464,
+ 0x805cb79b, 0x63f2cd78, 0x6b77b426, 0xc11a2f9a, 0xd5fbcd9e, 0xc41decab,
+ 0xa7135136, 0xae3e23d7, 0x20980c59, 0x0ab5abae, 0xbe6871cf, 0x3c2df313,
+ 0xc66bed1e, 0x6afc556f, 0x8a5eebc7, 0xbf6d8ac2, 0x857be1b4, 0x786c9bed,
+ 0xabf9aa5f, 0xc47b55e3, 0xf034b5c3, 0x4e3bb878, 0x918fe413, 0xc1cee1e3,
+ 0x7d21283f, 0x878dad16, 0xbf8ccd23, 0x456671d1, 0xa4350f7a, 0xe9fabd77,
+ 0xddcf10f3, 0xe793f5b5, 0x5f95dc61, 0xe21e7e5c, 0x6882a86c, 0xe6a53d07,
+ 0xfe31f795, 0x1f176955, 0x97a0edc3, 0xc3f1897f, 0x7268fe17, 0x3b0bb402,
+ 0xfe80a74e, 0xdfcb6171, 0x782e2092, 0xe8a98ed9, 0x3db659df, 0xedbddf0f,
+ 0xfa059ecd, 0x7e23f5f5, 0x7b6ebf59, 0x3c60f75a, 0xeeba79d0, 0x714227c0,
+ 0x2c552d8e, 0xe3c1d47e, 0x8e47371b, 0xcf11ef17, 0xaeeb3ad8, 0x5b1fc029,
+ 0x67d09e99, 0xba61e35c, 0x63f4379e, 0xf8f3371d, 0xbe3b96d5, 0x3cf1ae32,
+ 0xd7ae83fc, 0x7c6d18b8, 0x8bada7e8, 0x942cf17f, 0x1af426b5, 0x07e818d7,
+ 0xf47894fe, 0xd95da3cf, 0xdeb08931, 0xa4f181ff, 0x0e857eb0, 0xa69fd7e0,
+ 0x8cf8bf80, 0x44bf441c, 0xef098770, 0x38ef966b, 0xc2e9fb8a, 0xef1843f6,
+ 0xf85c784d, 0xb1fa1205, 0x03ee5df8, 0x6568d9aa, 0x1d7c90f1, 0x61d25e20,
+ 0x2e3cefc3, 0x12b5d192, 0x9c5bd92f, 0x3498b2e4, 0x8b0b3efe, 0xf8daace7,
+ 0x0c3f8f01, 0x09309baf, 0x2bf3abd6, 0x3c1550e3, 0x130f01d8, 0x91c071d5,
+ 0x714352e3, 0x8375bac0, 0x1e3e04f5, 0xf9a5f38a, 0xe9ef10a1, 0x8a468e13,
+ 0x81b0bf2b, 0x905f0fc5, 0x568fdf23, 0x626b82e2, 0xd7d6fb74, 0xbee078bf,
+ 0xf175f1e6, 0xa1c63f34, 0x5f051ba1, 0xf323575d, 0x846327f7, 0x85b7646f,
+ 0x0a549bee, 0x4f2cfbfa, 0x997dc0c4, 0xbe234ed6, 0x55d8a293, 0xdc5dbe7c,
+ 0x8af5d6df, 0xf5a27188, 0xbf907b2d, 0x3547f9eb, 0x8fd1473f, 0x6f1f2377,
+ 0x1f931b75, 0x3ead5b5d, 0xb5d3850b, 0xeba44dfb, 0x189dcdea, 0x79bfbaa7,
+ 0x7543b19b, 0xc3f20cfe, 0xd77f1aa7, 0x22c6bb6b, 0xa2efe73f, 0xcad9fbe9,
+ 0x3f8d63f9, 0x9b353f72, 0xa9fa6a2f, 0xed18b6f0, 0x3bfbbe96, 0x05eeb927,
+ 0x99dae778, 0x45ae751e, 0xd08be69c, 0x6462cfff, 0x3237576e, 0xa395383f,
+ 0x959c3ef8, 0xda2707bd, 0x5b2f51a2, 0x0c749d66, 0x665d21de, 0xcc5c6235,
+ 0x471e3aca, 0x326723f3, 0xeb4af7ac, 0xbbc604ed, 0xb2abf01a, 0x9bbb65ef,
+ 0x27273e80, 0xcfaa6517, 0x1bf19461, 0x4f881807, 0xd3ad8fbd, 0x4a7d8206,
+ 0x1850ef24, 0x7f699dc7, 0xb62e4095, 0x9f7f987b, 0x02313d5c, 0xf64bb7be,
+ 0x6e14097d, 0x04e0be7b, 0xba4f6cd7, 0x7e43f067, 0x1df69706, 0x4753bc5d,
+ 0x69c977e7, 0x6ad13d40, 0x1569d808, 0x4f6a8d62, 0x41d70346, 0x5e12521c,
+ 0x8978c0a5, 0x11e63cc7, 0x46d43f70, 0xf50adaa8, 0x5de6929c, 0x9249d895,
+ 0x72159dee, 0x57a50478, 0xc557a70b, 0xff65675f, 0xf03b70a6, 0x0cb896fd,
+ 0xbbe40752, 0x7d46ead6, 0x0b9b29e2, 0xdfd23fef, 0x88938868, 0xf54ed127,
+ 0x5fb450bb, 0xda3b7dcd, 0xe71f26af, 0xa613e6d2, 0xc9232749, 0x8e3e049b,
+ 0x7882d102, 0xe06a9b88, 0x70abb2fa, 0xdc785264, 0x19c48971, 0x2c3bf280,
+ 0x6e808f78, 0x1e7aaf2f, 0xdc768b16, 0x3e1a7c74, 0xe1d19b11, 0x6a71b035,
+ 0x0389dbbe, 0xe3a747df, 0xaf1bae3d, 0x70b56f26, 0x0911277e, 0xdcc59df8,
+ 0x2ffe384e, 0x4abdf069, 0x224f8a2a, 0x38c2644c, 0xde2130e9, 0x83cf9625,
+ 0x6fa9aff6, 0xeb01ef07, 0x0c870b5f, 0xb5efabb5, 0xe0e5c0de, 0x8a514b11,
+ 0xac93ee85, 0xb818b5e1, 0xb82c9d9d, 0x65a04e4e, 0x9fc801fe, 0x61e796d2,
+ 0xc8d08a5c, 0x5ac46ae8, 0x4466fb82, 0xad55c790, 0xd53d468a, 0xa8de2664,
+ 0x8e3f70f1, 0xd0f1e578, 0x3f9f8f8b, 0x28185639, 0xa50d6928, 0x1fceda35,
+ 0xa62c35cc, 0x4502d08b, 0x8b10fe14, 0x5ff40c6b, 0x6c9dc33f, 0x1bd30718,
+ 0x2877bf56, 0xc16bdaee, 0x1ba86863, 0x14c0ffba, 0x2ef82164, 0xdd0ef108,
+ 0x51b8720f, 0x0ec653c9, 0x463406ef, 0x332ef287, 0x698df7e5, 0xdaf37f2c,
+ 0x7ef0f5a1, 0xe8bda74d, 0xc78c0b66, 0xcf0ebf6c, 0x9af102c3, 0x937bd5f7,
+ 0x4738ca2f, 0xc1e40c6f, 0x07b7c7fb, 0x23c5fbd9, 0xfc7ba1ad, 0x59378f28,
+ 0xed007c94, 0x43d6a28b, 0x5aaad7c8, 0x01b9610e, 0x9e1d34f2, 0x421bc810,
+ 0x65bf79e7, 0xb5f2414c, 0x716b5e14, 0xb1c13c32, 0xbf6632d0, 0xb8c3c1a4,
+ 0x61d9bdfa, 0x6e2b483c, 0x86e1e1d0, 0x858785af, 0x87a86f6b, 0x3bfa55f7,
+ 0x0b174a6f, 0x73d35f00, 0xdb8ef80c, 0xf41663c4, 0x145fd0bf, 0x670e23ca,
+ 0xbcf72f43, 0xc2853b15, 0x97d35729, 0xaba14ed2, 0x9d26e8de, 0xef63afd8,
+ 0xe7e96a83, 0x87ae2ddf, 0x8b32de00, 0x8896dd2b, 0x0577c7f3, 0x8b8bbba6,
+ 0x74c213f2, 0x09ee2c4d, 0x11feaef0, 0x5a1f82cb, 0xe9dafe54, 0x34c54b39,
+ 0x011fde3a, 0x3c31b823, 0xdee5c49f, 0x9e7451a8, 0xc6032e89, 0xb8b11fd5,
+ 0xdb3b4057, 0x6200609c, 0xf71226cb, 0xf70c4104, 0xfa8feca3, 0xaf8ecc1d,
+ 0x56f8362f, 0xfc60f3b0, 0xfa611dbb, 0x47d1d0e8, 0x5b47d190, 0xb547d227,
+ 0x47d193bf, 0x346e5d5b, 0x3b03573f, 0xc70491ba, 0x5937bac1, 0x61a40b0a,
+ 0x82626e94, 0xb23740f5, 0xc282b6f7, 0x3aebc428, 0xf58f5f18, 0xe652e3e1,
+ 0x36fadbd5, 0x71fb481e, 0x0799d806, 0xa61e780d, 0xb7a94de0, 0x46e2c2c3,
+ 0x7ee6cdff, 0x99a9fa11, 0x961fb1d4, 0x3f81eb6f, 0xed875c60, 0xd05dcce0,
+ 0xae9b36de, 0x6fdc2390, 0xf815c1e3, 0x7f23784e, 0x04963bd7, 0x7bd720bd,
+ 0x3fdb07c7, 0xde807c21, 0xe8f80193, 0x0af2fdc4, 0xdd9667bf, 0xce40b826,
+ 0xef618f0f, 0x616ebc90, 0x16bbf576, 0xaf4ca791, 0x5bb83c49, 0x7b2bfb04,
+ 0x27eb0195, 0x9ea19a42, 0x5f5e2aff, 0x95ddf8d2, 0x89e85575, 0x7818d272,
+ 0x78f9e4cf, 0xfd2d1ef7, 0xa9a4c7c4, 0x1eed29e0, 0x45a290f7, 0xee265094,
+ 0xc810f05d, 0x3e3f4a55, 0x7231bb4d, 0x442de014, 0x233e943f, 0x776d0fad,
+ 0x7c6bad88, 0x5b0be80c, 0xf1152ef6, 0xae7e8e5d, 0x47bc166b, 0xc567eb49,
+ 0xb4adda90, 0x4d2c567d, 0xf3c09f21, 0x087e7903, 0x743fd34b, 0x7dfa041a,
+ 0x9ecbf703, 0x922578e5, 0x6399bafd, 0xb8f4cf20, 0x9418e4ec, 0x85beca0b,
+ 0x5ce05467, 0xdbe7e25b, 0x0334c169, 0x8fb29bac, 0x6021a0a5, 0x4d2b42a5,
+ 0xce201872, 0xbb8f5de1, 0x7b0bce08, 0x5fb73be3, 0xea81eecb, 0xc7ce7fbf,
+ 0xebf58df3, 0x2fb8f4bf, 0xb7e039fe, 0xf8f1dcca, 0xbeaf9a4c, 0x69fa32f6,
+ 0xdf54c457, 0x68ef55fc, 0xeeffc7e8, 0x00c4dfd5, 0x333ffa1d, 0x353fbc45,
+ 0xf1e8cace, 0xb60e6780, 0x04efe2cb, 0x1c4a8192, 0x15ce2ab2, 0x865eb8ca,
+ 0xdf86994b, 0x05bacf51, 0xa7ac2059, 0xf6878a57, 0xae78a931, 0xae2eab78,
+ 0xbb2f3955, 0x80fcc025, 0x42beb159, 0x74faefec, 0x3e49f7f6, 0x9992fa63,
+ 0xa1ce0ffe, 0x3373f2a6, 0x5efb31d7, 0x09598710, 0x3f08f98d, 0x5afd1536,
+ 0xfefb4439, 0xaf40d641, 0xf4f28064, 0x67978454, 0x13a795d6, 0x6b915bf4,
+ 0x4df9c3ae, 0x0cfd2a25, 0x13a346e5, 0xd1f4f1f8, 0xf7f9fe94, 0xe1bff4cb,
+ 0x867f3226, 0xcdb8ceca, 0xbe515f71, 0xc4696f46, 0xfb7e8577, 0x523f38b9,
+ 0x2163c5fc, 0x4115173c, 0x8f1e803c, 0x95610eb9, 0xdf13d1d5, 0xf1e9fc7a,
+ 0x8f51e0ad, 0x9d0f9cb7, 0x9e8ef1f9, 0x23e3d1f8, 0x5be97e7c, 0x7530eb0b,
+ 0x4bf288b4, 0xfc4f7bc1, 0xedfaf5b0, 0x009eb4b5, 0x0df142f4, 0x30174cf8,
+ 0x862b27be, 0x3a6c4fd3, 0x140b37e2, 0x0f4801c0, 0x55e3d798, 0x04acc78f,
+ 0xd5813ede, 0x1af80fdf, 0xed00fc89, 0xb2dd6521, 0xc6f76bd2, 0xe8c4de41,
+ 0xa7abd14c, 0xbd50bc72, 0xbce6f51a, 0x9bfa2b44, 0x9a9eaf40, 0x5e5bc614,
+ 0xde571b15, 0x600bcb48, 0xfc0afe9f, 0x0608b1d1, 0x95bcc5df, 0x56e05ff0,
+ 0xe2ca5f3c, 0xb7df0559, 0x93d5a67e, 0xce0bfaa7, 0xdc3dfe82, 0x05655ee4,
+ 0x87108c7f, 0xff1479e7, 0xd7f875c7, 0xf36bb3b6, 0x0afc7c7a, 0x27b931fe,
+ 0xab7a14de, 0x7cfd72b3, 0xfa0a1930, 0x3337d8f2, 0x137f8163, 0xbf447c7f,
+ 0x4563c4c4, 0x6e9c3821, 0xe2059e91, 0xa7b77d0e, 0x763e0b7f, 0x15494a90,
+ 0x7253bb1f, 0xd8deb3af, 0xeb298f93, 0xc7af8535, 0x05dde214, 0x4429a67e,
+ 0x1ec84bfa, 0xffcf0d48, 0xb3f72b79, 0x6043210d, 0x1c585f9e, 0x79f3ff8c,
+ 0xd54de686, 0x9b3fe84b, 0xb66d9ff7, 0x121bfde0, 0x7842ba94, 0x93f7c34e,
+ 0xf0f8c6bc, 0xbd656438, 0xd3096a53, 0xfbe2e6e7, 0xe42f14d9, 0x38f098cb,
+ 0x090559b6, 0xe3e20fdf, 0xf66cdf38, 0xd3db9c42, 0x2b0dfb92, 0x83843df8,
+ 0x527e7163, 0x3fc81460, 0xb6e5f97d, 0x4e50d5bd, 0x3d6095eb, 0x910afe3e,
+ 0x3b821ff9, 0x5217be4c, 0xe953d77b, 0xa13946f6, 0xdc3671d0, 0xe801bd7b,
+ 0xb8c2283e, 0x655cfcfd, 0xcf7645e7, 0xabec45c1, 0xf6f0a7ae, 0x02f7625d,
+ 0x81db28f2, 0xedfa7a7a, 0x49f34e8b, 0xd3b41e70, 0xcf22abd3, 0x5bfdf81b,
+ 0x68bb3f45, 0xeb0fbf75, 0xe3efc0de, 0xba8e2ffa, 0x1be7d60e, 0x2d61d5d3,
+ 0x44f4295d, 0xf438ebe9, 0xf1f99dd3, 0xdfcb503a, 0x049cbccb, 0xe3d151f2,
+ 0xeb8afac3, 0x9bd7a863, 0xe6dc3f3e, 0x857eb2ee, 0x35e8af3e, 0x6423d97d,
+ 0xd34644af, 0xebe3ce71, 0x2edcd733, 0x41c68bb3, 0x886fd38c, 0x73cbde56,
+ 0x393e8344, 0x95ed21af, 0xac573866, 0x07f97e63, 0x3d8d656b, 0xbedb86ec,
+ 0x67bd9ed8, 0xb6b97f3b, 0xef8a23fc, 0xcef8f141, 0x868ed6ad, 0x7e1491fd,
+ 0xbf67b7cf, 0xc9c82f06, 0x31a32379, 0xafdf4e7e, 0x7efa7e7e, 0x7035fdf5,
+ 0xd8c1aafb, 0xd2a9da38, 0x1636ec4f, 0xcd697d47, 0x14f0cd93, 0x73f86f5e,
+ 0xd4b8879b, 0xa3ae6f7f, 0xa44e7a21, 0x781468f7, 0xc2e7be0a, 0x0fe098cb,
+ 0x1eff95a8, 0x6cdd9de9, 0xf413f337, 0x6088efd6, 0x8683ea3e, 0xe82203a7,
+ 0x048223f5, 0xa0ecf0f5, 0x6350b0cb, 0xb97b300f, 0xef003d87, 0x657cd0a4,
+ 0x0f662eeb, 0x5da1d4b4, 0x0aed4951, 0xe01b3b90, 0x7cc1901d, 0x27681940,
+ 0x885eec84, 0x7786caaf, 0x0c5db932, 0x37a5a74f, 0x1f33fab2, 0x8c35374f,
+ 0x9dd5bb00, 0xce932f0c, 0xa8fb5db4, 0xf557da99, 0x508a24a9, 0x76c8aafb,
+ 0x4ed677ed, 0xde3bdca2, 0xa4bbc025, 0x65a8ff34, 0xecedff72, 0x8fd1b699,
+ 0xda81bf82, 0x54d9b767, 0xfb6f6f76, 0x039b66e3, 0xfedbd9f1, 0xcd17b4e8,
+ 0xdf8a3804, 0xe421f282, 0xbe28fe07, 0xf442a3ff, 0x53780b17, 0xe5f6e5e8,
+ 0x88ced10b, 0x0a6ae6ba, 0x736593c4, 0xb8db703a, 0xc186365f, 0x706189a9,
+ 0x376e4a26, 0xfbbdd3f4, 0x3bf028ea, 0x04fa3bbf, 0x2b7e79da, 0xf41fdbf3,
+ 0xe3a91594, 0x026d6bdb, 0x10c097a7, 0xdc777fd8, 0xec0127b8, 0xc0596c95,
+ 0xb2fd4ef7, 0x99f1e9ef, 0xdb669fc0, 0x6629d257, 0xfde2364f, 0x60547f32,
+ 0x3d2ac3c8, 0x4ddfcfce, 0x3fdc5ff5, 0xdcff1d44, 0xb5abcd6e, 0xc022f831,
+ 0x7bdccecf, 0xde80f40c, 0xae584ee4, 0x2b9004b8, 0x24a1eae4, 0xdd6a5f3c,
+ 0x689f0367, 0xe0e77f17, 0xa49eeb7c, 0xdaad3405, 0xb0369ff2, 0x3e38eae3,
+ 0xf8ed4bce, 0x76e5535e, 0xa113df11, 0x003d26fd, 0x85d6eb7e, 0x1fdeec59,
+ 0xc8a6afbb, 0xef9ff1d5, 0x9cc45219, 0x4cff7889, 0x98a737d1, 0x9f183ebd,
+ 0x1dfd8ebf, 0xf7ba29cc, 0xefe56ec9, 0xcff5e993, 0xe2b26c67, 0xa9f8c32f,
+ 0x4fd67665, 0xfb2bfb6f, 0x53e204b3, 0x296cbfed, 0xb3f8c220, 0xefc24b3f,
+ 0x3da40fe7, 0x3df60855, 0x01239d91, 0xa2f644ac, 0xa7cfcb7e, 0xbc2f6fe8,
+ 0x6793be7b, 0x3cbd6ede, 0x6e2466eb, 0xd004d72a, 0x9803dcc7, 0x07c991d3,
+ 0xf5bbff45, 0x55dfad33, 0x722b07af, 0x6e3fd732, 0x780210d5, 0xfbc2cc77,
+ 0x8c240713, 0xc9ebd2f7, 0xbd058353, 0x204fc3e8, 0x4d6d6d7d, 0xfe7b018f,
+ 0x009f60df, 0xc65eb6dd, 0x49aa83f7, 0xc7781ee0, 0xb455baa9, 0x24fc6007,
+ 0x67d87af3, 0xe0a13e8a, 0x1eeaeda5, 0x7fda58f3, 0x7d8345f6, 0x76f10505,
+ 0x57682ff0, 0xc1fdf84f, 0xfe679004, 0x07e784a0, 0xc6f717d9, 0x45f1542c,
+ 0x7e0355ff, 0x6eeafb7f, 0xfc60f7ed, 0x8b6ed0f5, 0x7bcbd981, 0x063dfff7,
+ 0x57dbd4f8, 0x90bc212f, 0x6f53d13e, 0xcf3bfd46, 0xd1fc862a, 0x8899bd6a,
+ 0xde2187d9, 0x152c6a6b, 0xfaef426b, 0x6487ce70, 0xd4f49595, 0x2778422b,
+ 0xd0f0092e, 0xf0561f43, 0x3e33d3ac, 0x773d71b2, 0xef0f1918, 0x4d5db65e,
+ 0xc77bc0a8, 0x0afb18fe, 0x8f4ccf94, 0xee7bdeea, 0xfdf0e9c9, 0x9ddec8a0,
+ 0x7ee22ab8, 0x62b3bdda, 0xdf6a8778, 0xeb8a4e52, 0xc5d06576, 0xfad16f0b,
+ 0x3345f657, 0xbce4baff, 0x224f7d5e, 0xf1c7df5c, 0xcecc1815, 0xe183bce9,
+ 0xac6fa8bd, 0xb0f574cf, 0x4361fff7, 0x0058393d, 0xfad462e2, 0xffac234e,
+ 0x3e8ad9bf, 0x25a5fc67, 0x978bf806, 0xb4210ee4, 0x9268b2df, 0xac15740b,
+ 0x33b07623, 0x18301fb6, 0x37325d60, 0xcf5c62a5, 0x731cfc2b, 0x31a34b49,
+ 0x4b174555, 0x19d839f8, 0xaf129bd9, 0x9632befa, 0xfb3397f1, 0x71817fca,
+ 0x91347f1d, 0xd0f41191, 0xfe4cb185, 0xa77a336e, 0xc77a866f, 0x68df780d,
+ 0xef5ffeef, 0x97937787, 0x038c731c, 0x5894e0bf, 0x0eda0fb6, 0x710f52be,
+ 0x821f6dc1, 0x6672a2d4, 0xa068b163, 0x1c45befd, 0x9877afcc, 0x90d6bdfd,
+ 0x12b8943f, 0xc5379e60, 0xd6fdbe32, 0xdce68301, 0xbefe2dec, 0x8cb1f5ef,
+ 0x32c6a50f, 0x03d6dabf, 0x700b09b9, 0xc447b9ff, 0x64f01f82, 0x456c3d47,
+ 0xe8a80fc5, 0x6f0f936f, 0xfe863e9d, 0xc1977273, 0x38edcb0e, 0xf30882fc,
+ 0x24219c75, 0xf43d204e, 0xac6f0a39, 0x5d5bde1a, 0xc71d1e0c, 0x0aafd86e,
+ 0xfe04a9fe, 0xbfcd0671, 0x43c52ed5, 0x7f82983c, 0xff4a1e65, 0xdae2168e,
+ 0xe4adc160, 0xfe15fada, 0x31efe568, 0xe513b04c, 0x5d2033ef, 0x6eb9b76e,
+ 0x6f72c589, 0xeccfe40a, 0x36d27a63, 0x72494f2e, 0x9fc070f1, 0x79f34eb2,
+ 0xb7a78caa, 0xe3e7effe, 0x4bafd254, 0x0ec8afd7, 0x76cdd22f, 0xf0ee4f16,
+ 0x10e9cc06, 0x8e96d677, 0x154a9f7f, 0x8e3f7b97, 0xfdf68cff, 0x830eb6c2,
+ 0x558fee01, 0x50e210ef, 0xbea7eddd, 0xa933a21d, 0xedafe905, 0x5c7dc118,
+ 0xe65dfcde, 0x9f72a48f, 0xe786ebbf, 0xf87fb0eb, 0x8120fb39, 0x1bfd93a6,
+ 0xfc410e56, 0xafb06c06, 0xfba278c2, 0x46dad206, 0x92ebd023, 0xe52d2c65,
+ 0x9a4bd5e7, 0x4b3fb8dc, 0xc478b3d6, 0x4ca9b165, 0x257a733e, 0xf8c1e886,
+ 0x7b4dbade, 0x5c1ff08f, 0x7d6d9e7e, 0x4bf40f6a, 0x80fbebe9, 0x9eda9b8f,
+ 0x55c30758, 0x46ecf5e8, 0x4594e119, 0x3df3cf6b, 0xb8cfccb1, 0xf7a330fd,
+ 0x5ce51bc9, 0xb26c4f78, 0xbfc1d897, 0x4dc6d6fd, 0xb7eff022, 0xd9539e80,
+ 0x7b79073e, 0x3163df66, 0xd6f907df, 0x47e02069, 0x652466df, 0x62fb545b,
+ 0x343786ef, 0xb9bcb7fb, 0xebfa3a6e, 0xe005e23b, 0x55becaf3, 0xe8cdbef0,
+ 0xfff70dbc, 0x9ffdba9d, 0xc2b7dacf, 0x4f7ad0ba, 0xd4fffdf1, 0xe9ffba34,
+ 0x718db8a7, 0x66d9c002, 0xdccefc8c, 0xfe90df4b, 0xa3b57c42, 0x297d5f07,
+ 0x6c1ff996, 0xeaffb4e9, 0xffa12e3b, 0x4e3e3421, 0x2be54f37, 0x002a9374,
+ 0x0ae91bfe, 0x517c008e, 0x533d02bc, 0xccfe7a3d, 0x0795dc0c, 0xe1ff3c24,
+ 0x2e3c4be7, 0x6a947704, 0x99f986bf, 0x6fdd6fb2, 0xf2b238c0, 0x9e82576b,
+ 0x45e8509f, 0xb82b3cfa, 0x7953c787, 0x71f61676, 0x8eb07e04, 0xec8ae3e3,
+ 0xff7debee, 0x65cf40c1, 0xf98462d4, 0x1d82f590, 0x772945d6, 0xbdef67ac,
+ 0x94f0e61e, 0x2dbf87ef, 0xde3d83be, 0xf0cc3d21, 0x5c42341d, 0x931f28eb,
+ 0xc5c84463, 0xb70c40fd, 0xb67d860f, 0xfbafca84, 0xacebf255, 0xaa7488dc,
+ 0xce23e1e0, 0xb1c4aeb7, 0xc7ce3f79, 0x5d1f07e9, 0x82ff0aa2, 0x3f6c0924,
+ 0xe7db028b, 0xbb3fc022, 0x90dba6ef, 0x4c88efde, 0xb7b076ef, 0x47efe1e2,
+ 0x8cfa406d, 0x7bc7669b, 0xce494f2f, 0x7e8d38a8, 0xef74c3e4, 0xced067a6,
+ 0xfd85fa03, 0x97fd1bde, 0x0893fd01, 0x74a3ef74, 0x853f5aaf, 0xfc5d280e,
+ 0x7ca5f01d, 0x7285d3d7, 0x65e0a90e, 0x731cee9b, 0xe9e19daa, 0x8d5200ff,
+ 0x8000b56e, 0x00008000, 0x00088b1f, 0x00000000, 0x7dbdff00, 0xd5547c09,
+ 0xf37df8d5, 0x3332c966, 0xb2764c99, 0xa00c4930, 0x80490e2c, 0x084ed8b0,
+ 0xc3884a20, 0x93a0d752, 0x364b0900, 0x94569510, 0x8b062081, 0xb62d1518,
+ 0xef858320, 0x106d1b43, 0x268358a8, 0x622d1110, 0xa57fb1dc, 0x41459041,
+ 0xed1fa822, 0xe73bf587, 0x33337bdc, 0x6a02266f, 0xefc7e1ff, 0xdf77dee6,
+ 0xcf7ece5d, 0x6ec5f739, 0x843631d3, 0xae630731, 0x7d8c01e6, 0xf4bf3f8f,
+ 0xa12d8c97, 0xcf3773e7, 0x8224715e, 0xf0f7cfd1, 0x5e79babf, 0xc776bd50,
+ 0xe91c57af, 0xc5cfafe7, 0xffe0525f, 0x8967a671, 0x47f1558c, 0x89ef4cac,
+ 0xfbc025b5, 0x6cd69d11, 0xe266b498, 0x03846319, 0x8319789f, 0x1c636ff6,
+ 0x6faa3e54, 0x1f2bd3de, 0xe9cc31ca, 0x9b39a685, 0x998f1533, 0x1b3605b1,
+ 0x27f967ad, 0xb0dd93d3, 0xc6c646de, 0xc59bbae3, 0xd9dd727c, 0x99c68536,
+ 0x8f7329e0, 0x66678389, 0xa07b9e4f, 0x6607f9ff, 0x886d964f, 0x70a13ebf,
+ 0x4018eabe, 0x7ec48c4b, 0x0c985563, 0xc9bf9fe6, 0x326533e4, 0xc49f05b6,
+ 0xa3db2ac3, 0xfd329b7c, 0xccf4d9ef, 0x9633b7a5, 0x75a4cb6b, 0xb15aeac1,
+ 0x646858ee, 0xdfbcc197, 0x9bb59666, 0x1dd5d1e1, 0xb081e2de, 0xef462d8f,
+ 0x389989d4, 0x1c1af398, 0x9d629aff, 0x6a5801ed, 0x38a6cbac, 0x6992d007,
+ 0xcf8fb65e, 0xeced9793, 0xeea1b2cf, 0x2db9e670, 0xf8128d8c, 0xc930ad62,
+ 0x421c3f70, 0xd9e1c6f1, 0x20175e13, 0x1750867c, 0xd5e27e7a, 0x667d1ba8,
+ 0x0144f3ff, 0x78632fbf, 0xd3c1adf9, 0x1d0e66db, 0x553e6027, 0xcacc6649,
+ 0x5c554b3c, 0xdb6628ff, 0x773ff0e4, 0x1c2e628c, 0x57189a7f, 0x8ffacbb6,
+ 0x10aeafa6, 0x78869afa, 0x22e88ead, 0xd053eaba, 0xbcc07469, 0x8bdd194c,
+ 0xee98fac1, 0x80ac5eda, 0xbd71eaba, 0x29554800, 0xf6c7ebe0, 0xd7338d84,
+ 0x01d99e23, 0x0cc9cb13, 0xcdb567dd, 0xd1b6e1c0, 0xe866fa30, 0xb865e097,
+ 0x838bc003, 0xde3585e3, 0xdc6bf88a, 0xd7886268, 0xdc39636f, 0x68d953ac,
+ 0x42b7f403, 0xc6f7247f, 0x57039ea9, 0xd931bd41, 0x9e6050e8, 0xc22e8613,
+ 0xa0ab89fb, 0xadc3e88d, 0xbc4fbe20, 0xdf9ae23a, 0xa277bb40, 0x8bc0e58e,
+ 0x05b08d5b, 0xa7bfc3a4, 0x482936f9, 0x27c42da7, 0xc1b2c7f3, 0xbede7826,
+ 0xd5d11869, 0x052ce2ac, 0xe6ce76e9, 0xdb9f0558, 0x2a74d8c7, 0xd863eff3,
+ 0x13e89542, 0x16dea0f8, 0xde618f80, 0xd5e1153a, 0x6c93ce3b, 0x11ec6588,
+ 0x23e335db, 0x32ce81d2, 0xcc1b2459, 0x5f5043d8, 0xb46b7009, 0x4b1614bb,
+ 0x0a7306f5, 0x236321f1, 0x0cadae08, 0xd518d4f0, 0x6045775d, 0x7f5e2cff,
+ 0x86eaf1a4, 0x9ec63486, 0x22357189, 0xbb303e9e, 0x87f9c11f, 0x44a9d526,
+ 0x7fae82e7, 0x127ece80, 0x2c2ed4bd, 0xe0f38762, 0x0e660ef7, 0x47901ba4,
+ 0xf8066eb7, 0x9b3de895, 0xbd355d70, 0xc38e3e8e, 0x657cb6d5, 0x7ba184f4,
+ 0x21788eb9, 0x8cc7d817, 0xaeef11f0, 0x7ecdcb53, 0x66c5b3b9, 0x52ed4c17,
+ 0xfcfc5b26, 0x79eb7286, 0x593b9733, 0x98229a50, 0x7ec762d7, 0xac23a23e,
+ 0xe5fae4c7, 0xdd62cad1, 0x3e185f78, 0xeb890d7e, 0xaccf9467, 0xf2ff7fe5,
+ 0x1fd0a19b, 0x9f89577f, 0xc4fce35e, 0xc5a3f5e5, 0x3c22269f, 0xbdf09390,
+ 0xeb1cc5db, 0xeadf3a97, 0x5fb9748b, 0x3ea09b65, 0x2af464d8, 0xe66db831,
+ 0xf18a25b0, 0x945b0d90, 0xa820cb56, 0x2e614bff, 0x7fe9c3c0, 0xbfae54a9,
+ 0x133e3dd7, 0xa1d9afde, 0x7e852e73, 0xf10a2d35, 0xf337b383, 0x371d0045,
+ 0x31075947, 0xb770af18, 0xf68065d9, 0xc9044ad3, 0xd7009c65, 0x2feb9061,
+ 0x8268cae8, 0xc02df5e7, 0x5d3d507f, 0xf5c6a808, 0x6c319dea, 0x83be1f80,
+ 0x1fb47cde, 0x1bda00ec, 0x4f67c89d, 0x9ff1f245, 0x81f0cc8a, 0xbe528310,
+ 0x4a0188e7, 0x6e825961, 0x62c67af4, 0x78504f00, 0x30b51cb1, 0x3c07a5db,
+ 0x35e67a2b, 0x7546be00, 0x9f08aab5, 0x8e872eac, 0xe9f3fd99, 0x3bed18bb,
+ 0x39d0ef4b, 0xd6d5f403, 0x7aabcfbd, 0x31d0eb80, 0x942af58d, 0x6f9e3189,
+ 0x4623de10, 0x7b63d5d5, 0xf557b15c, 0xa57cff40, 0xe905b76e, 0x44e61aec,
+ 0x24f92ab9, 0xc1b593ae, 0x81ec5972, 0xda15974e, 0xb5771c47, 0xc7fd800d,
+ 0xe38299b8, 0x7c0dfd49, 0x0e9162c6, 0x44ca5de3, 0x3fe86718, 0x8e47c118,
+ 0x68ef75b3, 0xbe3ef905, 0x18e28c63, 0x6be74a10, 0x38b7e398, 0xce9f77ae,
+ 0x3475f889, 0x9406d733, 0x62ba7f13, 0xf64bc20c, 0xf5cb1def, 0xa78f48ca,
+ 0xee154408, 0x1de70627, 0xb76fa37e, 0x6c33d601, 0xd1b77796, 0xd99fb011,
+ 0xed4bc68c, 0x523ed2f4, 0xb10a780e, 0xd2c6b6cc, 0xb78e2338, 0x7e800db6,
+ 0x1fb07549, 0x78ef4f68, 0xa6b8414f, 0x882875d7, 0x777badcf, 0x3ad37ad1,
+ 0xf82979da, 0x176179eb, 0x5603db74, 0xdb23ed1d, 0xf2cdf5ca, 0x666f5c53,
+ 0xadb27ac7, 0x2c7dfe09, 0xd724f42f, 0xf66bf8c1, 0x17ef7566, 0x2895eee5,
+ 0x52e403e4, 0xc691ac6e, 0xe9eacbb9, 0xbdabfb8f, 0xd20f73b1, 0xdf7bf3e0,
+ 0xb47f12b1, 0x137e13c4, 0xf84a7df7, 0xba485c48, 0x37d9ad98, 0xb179415f,
+ 0xa67014a6, 0xca59c284, 0x7eb8358d, 0xf45b1fa2, 0x27cfa024, 0xd8829eed,
+ 0xcca57b40, 0x20159d1e, 0x8f7be497, 0x19ee662f, 0xed6190b0, 0x16595be5,
+ 0xb17ef7c9, 0xc27df201, 0x9122fbc0, 0x2e2c9a9e, 0x569fb617, 0xcf388dd8,
+ 0xfb425833, 0x975e0633, 0xe0407af0, 0x52763b33, 0x870875b6, 0xf8e80d93,
+ 0x4fde4899, 0x8dee8f2b, 0x83bb09d5, 0xe0eb0bd3, 0x08fb82f4, 0xc666bfb4,
+ 0x748c3c72, 0x9cf48a79, 0xfee2a64e, 0x76f81786, 0x1b0edd23, 0xf48dddef,
+ 0x9d04ce9f, 0xa274e78c, 0x63dbf7a5, 0x711d7cb9, 0xdc218bbc, 0x0ee615f3,
+ 0xc654ef67, 0xbe29bb72, 0x0fd13463, 0xce1943f0, 0x4eb53437, 0x66dca035,
+ 0x7fa809b6, 0xa0eb137e, 0xae05797e, 0x366f48dd, 0x79f89b97, 0xe9c6d9be,
+ 0x07d39326, 0x1c273fbc, 0x3e436d3f, 0xa3e7e01a, 0x7347a478, 0x26de3d28,
+ 0x011bf4e0, 0x3df1d0df, 0xf1f8e177, 0x02973a1d, 0x603b0c83, 0x3ae831f6,
+ 0x49e8016c, 0xf40653e4, 0xcfb40b0f, 0x9f2215b2, 0x153956a5, 0xb302ebc4,
+ 0xd7dc1efb, 0xf98d9472, 0x5f3acf48, 0x6c97bc3d, 0x7efe1173, 0x67689eb4,
+ 0x90686c11, 0x2c40f59d, 0x9557e3b7, 0xfa7ebca1, 0x53ca235b, 0xbdbfe487,
+ 0x01e5d1b9, 0x50c7f1f4, 0x0e123f7c, 0xa7395adf, 0x2e5fb7c5, 0x8039cb04,
+ 0x0f8e5ad7, 0x77c7e76e, 0x7cb9502c, 0x3d6b9608, 0x3e4423e1, 0xc1fc3c08,
+ 0xeb84daec, 0x4045c6cc, 0xfacd1de9, 0xfa4f7b61, 0xf358c5f8, 0x2f67b34f,
+ 0x8c5f8fac, 0xc7d5084d, 0xd7ae88ba, 0x75478015, 0x6150ea8b, 0xec8bf50b,
+ 0xfaffc42e, 0x7689c566, 0x9516eee1, 0xf2fd61e8, 0x729bd228, 0x8f6e5fbd,
+ 0x84aec419, 0x6b3ff052, 0x5a7d258f, 0x5fe62b1b, 0xfcc0bf06, 0xbabc6da7,
+ 0x3d79e6dd, 0x6fad0e50, 0xe11226f9, 0x71593fdc, 0x4abb411d, 0x85818fab,
+ 0x84df7814, 0xd70829bf, 0x322a0dc1, 0xad9ef5d6, 0xf6f09526, 0x8c378e2e,
+ 0x0a33be75, 0xa6a7f5d6, 0x7b40bad1, 0xaf8eeceb, 0xeb05dd6f, 0xfae68daf,
+ 0xeb9a36b9, 0xcebbd3e7, 0xbb7a41f7, 0x9274e176, 0x9ef4c37b, 0xdce5038f,
+ 0x730efd1b, 0x6d4acc39, 0xd4e3fb47, 0x68fbe52e, 0xa235a100, 0x0aed1e9f,
+ 0x06a9ca35, 0x1c4415db, 0x1f0039f5, 0x145b5f84, 0x073eafc1, 0xd6932ef8,
+ 0xd9d70279, 0x14b2316e, 0xfc0b3f68, 0xbae4fd88, 0xcf7ac47f, 0x9a6f5f84,
+ 0xa0b468ed, 0xbebfd50b, 0x1e20bc6e, 0xa2d57c60, 0x669c7da7, 0x67c44e51,
+ 0x10c5d1b3, 0xc283deff, 0xab78103e, 0xba773411, 0x0f01c865, 0x81fd6fec,
+ 0x7fbe2734, 0x48d9c77a, 0x47ed199d, 0x7d876a8f, 0x565de9a9, 0x5bbb87d4,
+ 0x39de5ece, 0xc19be480, 0xbb3beb0e, 0x33ddb0ef, 0xcfed47e0, 0xfd88bf6a,
+ 0x0dcdead5, 0xaa227681, 0x1a945259, 0xda5a523a, 0x220ca9fe, 0x0f2863fe,
+ 0x57cc19bd, 0x3e5efb0f, 0x54d3d050, 0xd7be40e6, 0xcdbb7be2, 0xe00f619d,
+ 0xb736cddb, 0xf385d703, 0x3ed2e6a4, 0xe83eb0b3, 0x0679e9cd, 0x0c6fee1d,
+ 0xed29bd43, 0xb44fb93d, 0xfd7323c7, 0x5ef693fb, 0xce73fef7, 0x68c7da0f,
+ 0x74ec83df, 0xc52c740e, 0x282d5a73, 0x03320785, 0x784adff7, 0xacfb16a9,
+ 0xaab7308e, 0xcdb62fb0, 0xca53b270, 0x7dd0ac83, 0xf3869e00, 0x780f387d,
+ 0x377fcf10, 0x4e11eb3b, 0xda1b0efa, 0x91afb0af, 0x50560fb8, 0xf8708c96,
+ 0x8c9aecc0, 0x2599fef2, 0xf4fae88c, 0x14f7ccb3, 0xbb4b7a6c, 0x0366e88e,
+ 0xffe882bb, 0x5b99dd0a, 0xebe266dd, 0x7e7ef8b1, 0xe50ea347, 0xa1cf8e6f,
+ 0x797ab943, 0x474eb347, 0x2f19e0f4, 0x0f5674e0, 0x54dfebeb, 0xba48fea7,
+ 0x2e9e1498, 0xabf6f042, 0xb849bc40, 0x30f4128d, 0x3286e10a, 0xb27f4bb9,
+ 0x370fc233, 0xb54b0bc0, 0x58c78e87, 0xa9c20667, 0x7d63c5ed, 0x9abc613a,
+ 0x8add8f97, 0xabf9a970, 0xcc618889, 0x418f2f5f, 0x30b2ffba, 0x72735dbc,
+ 0x0f5b9d71, 0x3dab78c4, 0x157be48b, 0xbda230eb, 0xaddd7200, 0xd2eb900f,
+ 0xe867db8e, 0xf7f1c628, 0x12d9510d, 0xe759f380, 0x461624b0, 0x3f72c85f,
+ 0x00396dda, 0xe155f47f, 0xfcc5e4f9, 0xda476e18, 0xb25afc83, 0x9678b7dc,
+ 0xe7a18c7b, 0x8e0df6f1, 0xb14e7f24, 0xc87a1ec6, 0xa78dedce, 0x81cf5ced,
+ 0x3ae17660, 0xe2c5fd4f, 0xa9d342f3, 0x0cadf7dc, 0xdb6a74e0, 0xa05e79bb,
+ 0xe3ac53a3, 0xdf9097f6, 0xb9d336be, 0xfbf078ae, 0x7e2c4b79, 0xfb8abcfe,
+ 0x2f55d852, 0x407569bc, 0xbb2de2ff, 0xf001bde3, 0xbfe98abb, 0x4ceba6ee,
+ 0x8fef979c, 0x20fb3be9, 0x274bd83e, 0x16501d12, 0x3c6af8bf, 0x373803a7,
+ 0x14ff450d, 0x633f8fe7, 0x5ddd8053, 0x3dc6b0bc, 0x1fc02f26, 0xf9922e73,
+ 0x0efaeb02, 0xab891e23, 0xfda999cf, 0x9e25bb76, 0xd62f4de4, 0x8f4de50b,
+ 0x7848baf0, 0x3c25db6a, 0x913e0df7, 0x97c5f681, 0x07c5d83d, 0xaf7ec1ec,
+ 0xdc7b1637, 0xf5fc7263, 0xdea77dbf, 0x5ef30ee6, 0xacff188b, 0xda127873,
+ 0xd6c6c57d, 0xe1f9c2cb, 0x0b5339e4, 0x57ce37a7, 0x7fb8e346, 0x1f1a6739,
+ 0xeddb5d6e, 0x3fe69fba, 0x0aab07d8, 0xf44b0bb0, 0xdced379e, 0x326ab05f,
+ 0x3f2e6bd4, 0xd9ce8e3b, 0xdc845e92, 0xdb798abb, 0xf4b57f90, 0xbefdf121,
+ 0x4b2a5bc4, 0x693dbc45, 0x11ba7077, 0x43f920fc, 0x396d470b, 0xe13cc8c1,
+ 0x75cf03ce, 0x799235c3, 0xbede1e41, 0xfe7a40c1, 0x4e1ff3cd, 0x3f7a03cd,
+ 0x5b60d6b6, 0x5ace530a, 0x51ed3bb7, 0x360da7f4, 0x1fa814d9, 0x865eb473,
+ 0x4eb95f7c, 0x1c3d2375, 0xe27b7b5b, 0x00bf2874, 0x7582adfe, 0x50306e54,
+ 0x770dacfb, 0xc109fb50, 0x12eb95d7, 0x7cbca3fa, 0x4481fdb3, 0xeface3c4,
+ 0xf11ebfee, 0xeb68c5b2, 0xaaca183f, 0x263dc526, 0x3673de00, 0xb7d50646,
+ 0xdc2cd8e8, 0x532bc487, 0x1dcfdd3c, 0xdc631eb0, 0x6b63c44f, 0x18d51f88,
+ 0x92ccedc7, 0x9aefb029, 0xbec96721, 0x8a27bddf, 0x662bc9f4, 0xd6c8ec95,
+ 0xb7f3ffc1, 0xf45ea12b, 0x3649de9d, 0x58f3c09e, 0xce866781, 0x8a8fa040,
+ 0x7a2f5e08, 0x68764f51, 0x78254591, 0x1d5c82b7, 0x65de4a43, 0x7efd0b1e,
+ 0x4753df21, 0xfd0e1ead, 0x1818c6c6, 0xb45fa1ea, 0xa06629ce, 0x4e797f27,
+ 0xc06769ff, 0x9733467e, 0x42e2ed1e, 0x5f6a0866, 0x0a7d6511, 0x4c185aed,
+ 0x28b0fa8f, 0xd8f9f822, 0x813daecb, 0x5b58c4f6, 0xbfa4bb70, 0xbfa0389c,
+ 0xb1b97efe, 0x8fe7cf7b, 0x567d804c, 0x9ec953ec, 0xde5c90be, 0x41cafb8f,
+ 0xda51bf7c, 0x29bdef04, 0xf9e6f3a0, 0x9052cb63, 0x86140abe, 0xe763ae7e,
+ 0x5ce5f3c3, 0x018c9f41, 0xf1f9fb9e, 0xbb39d13c, 0x7f6c8ebb, 0xeebcc15d,
+ 0xe2ffae3a, 0xcb0fd9e5, 0xf73b4eab, 0x87f5686f, 0x53fe7f96, 0xf078a3fa,
+ 0x0b5e19ab, 0xe585ff95, 0xfe5c2dc9, 0x5685e56a, 0x6975c85f, 0x4e7d5bd7,
+ 0xcf13d20d, 0xd7e27909, 0xfe7a4617, 0x6b8f9e33, 0x9e8486e2, 0x219ec18f,
+ 0xea877978, 0x760e5ce9, 0x6fd8edd7, 0x5711d980, 0x665a4b08, 0xb9468acb,
+ 0xdcf164d6, 0x97e01719, 0xa8d4dfea, 0xedd1f943, 0xfb0431af, 0xf5f9e46d,
+ 0xffbe389e, 0x875e38f2, 0xfb9d2bf3, 0x92794437, 0x2f6f38f5, 0x7e3033a3,
+ 0x85fbcb25, 0xaf7690fc, 0x9da577b4, 0x7d59ed2b, 0xb367b703, 0x7e41dd63,
+ 0x5fafd633, 0xed183f90, 0xef73e474, 0xe7da28ae, 0x107b8a67, 0x731569f2,
+ 0xa017143d, 0x7c0deb07, 0xbcf5dafd, 0x13ec2716, 0x413b26e6, 0x1d1ccfb6,
+ 0x8d6f9e5e, 0xc2ff53d3, 0x40ca6fc7, 0xb6b3ee3b, 0xce50339b, 0xfff1a67e,
+ 0x0f0fc4f6, 0x507d7e0b, 0xe15893e8, 0xf9087827, 0xedc0ea08, 0xfef02dae,
+ 0xe26ec58a, 0xbe2edfab, 0x1747ca91, 0x8fe7a42f, 0xfcd265c5, 0xdc77c2b6,
+ 0x23a700d9, 0x17d2552b, 0x3eee8d33, 0x91def0b1, 0x1bf91d08, 0xc799d70e,
+ 0x3b63336f, 0xcce5f3a3, 0xf26c27c7, 0x1f01f806, 0xe90c7dc3, 0x09af9f79,
+ 0x9d2a5ebc, 0x2b4eb356, 0x7a6eadea, 0xb7a2103d, 0xa72f11db, 0xf6226759,
+ 0xfa3a55ab, 0xf3a12934, 0xaf5cc83f, 0x2366bf61, 0xd37c8feb, 0x92f5c51c,
+ 0x029bdfb6, 0x9ed0ab7f, 0xd433f285, 0xcce4615f, 0x7b5e823b, 0xc4ef5d5b,
+ 0x9333bc91, 0x56eb4edd, 0x3ef44e29, 0xb4e707ce, 0xc639f10f, 0x975fd089,
+ 0xc775b56d, 0xc779f855, 0x185c71fd, 0xfe4f5c7f, 0xee3aed1f, 0xd570e789,
+ 0x296485fa, 0xc4c742fd, 0xd9c5167e, 0xe844fc82, 0x0fe70f0f, 0x48de3aba,
+ 0xd510dbfb, 0xa8b8c5e9, 0x3e7e66f7, 0x55e51a4f, 0x5a95dfd0, 0xfe8858dc,
+ 0x71c67fb0, 0xbc7da63f, 0xf1cf1927, 0x4e8d92bd, 0x2c5ce3f4, 0x76680e3f,
+ 0x478138f1, 0xd358eb47, 0x03ec8de1, 0xf0ec4aeb, 0x34a11a14, 0xf8d226c4,
+ 0x096eac49, 0x11fa0de2, 0xa3dbf230, 0x743c8a7c, 0x213c9743, 0x91a56147,
+ 0xaddb77c8, 0xbc3c531e, 0x5d467437, 0x53edfa3d, 0xe23c78ab, 0x6de9e284,
+ 0x1b8d0ecf, 0x5e3932cb, 0xbb88aff0, 0xd0346fe6, 0x3e37f2ba, 0xfcd1f146,
+ 0x95eb578d, 0x1f943900, 0x27fea06f, 0x9bd39d5e, 0x851f18fc, 0x880ebf8f,
+ 0x4662f4e7, 0x8a10e11f, 0xbfa58687, 0x313ff17e, 0xf609dcae, 0xef3cb050,
+ 0x20243f17, 0x0cfaa16f, 0x3c7d73c9, 0xc07f23d7, 0xd358057c, 0x7cc8661f,
+ 0x8fe40d85, 0xbe6c6add, 0xde51e306, 0xbc431d1a, 0x2bf9efb7, 0xcd676bc5,
+ 0xb6bc5070, 0xcf7dfdfb, 0x3ff6c72c, 0x118362cc, 0x87be29fe, 0x7ccff415,
+ 0xc9e3c91b, 0xb1326edf, 0xd9a5b025, 0x3c53376f, 0x8e954d78, 0xeed17ca1,
+ 0xe832661b, 0xa0db5c78, 0x47f8e02b, 0x0ef12839, 0x7c446404, 0xfc21bc48,
+ 0x6e3198b6, 0x5fad02fc, 0x7e80cbae, 0xc7dc04f0, 0x4e906b96, 0x15d9557a,
+ 0x75c817f4, 0x4c9f485d, 0xfa69ff8a, 0xc3d467e4, 0x9c5fc5b7, 0x74819e1e,
+ 0x5ac3d5ae, 0x7164dbfd, 0x0bbf6255, 0x4213e1e9, 0xd7894dfe, 0x7e3043c4,
+ 0xc76f0616, 0xf00c1c84, 0xff19df8f, 0x1fe3fc23, 0xe3091ca1, 0xc8c67f1f,
+ 0x9da36fe5, 0x0c2936dd, 0xe627bcbf, 0x32eeadd7, 0x6f8cfea2, 0xb3cac251,
+ 0xc651ab6c, 0xfae05713, 0x2b44fc64, 0xb7c0c38f, 0xde5ffb11, 0x7b0bbad4,
+ 0x165ec6e5, 0x15dbe68d, 0x37b9c3df, 0x046b3ccc, 0x30163b9f, 0xea3aa38a,
+ 0xa82bc918, 0xb093b8fb, 0x0023f295, 0xb8e04f1f, 0x9d638a17, 0x1d9215b6,
+ 0x8656e324, 0xf8f3e0d8, 0xcfd9789e, 0x6fc447f5, 0xe27a0f7a, 0xb05d624f,
+ 0x5fb067ff, 0x141602fc, 0x9971919f, 0x62af3af8, 0xc47547cc, 0x3bdadfc8,
+ 0xf304b3ce, 0x3386ba3f, 0x8f5053e7, 0xa215b529, 0x72cfb53c, 0x66fc61b6,
+ 0x9fee29f9, 0xf98f3e5f, 0x79012a96, 0xca2c9e05, 0x05bc4203, 0x0a7607fa,
+ 0xac53b6f9, 0x5fe4f41b, 0x5abaf9e3, 0xa4f403e2, 0x756e87c4, 0xed784aab,
+ 0x02a7af0a, 0x43fedaf0, 0xf919fd78, 0xe48b9df2, 0x852f0fcb, 0x9171fe6e,
+ 0x8c4bf374, 0x3b090c6f, 0x578867df, 0x67407ced, 0xbef88347, 0x78db3a07,
+ 0xf9d2f189, 0xa7a89fe6, 0x5dfae142, 0x5c28427c, 0xfaeb1657, 0x5166bc91,
+ 0xd57a70ce, 0x4ffe6096, 0x12d891e7, 0x1e7a5c86, 0x3b7bfac9, 0x1967888d,
+ 0xd5eb9107, 0xf6c88fe6, 0x0f25169a, 0xbb859fcf, 0xe039d3cf, 0xe8bfdb74,
+ 0x079a101c, 0x0f9de7c2, 0x39fc8de4, 0xdcd01d56, 0xa677fc0a, 0x752748c9,
+ 0x377e3995, 0x7bf7fd0a, 0xa0e7cc0d, 0xffd811fe, 0x5ffbc60a, 0x03bcb4d1,
+ 0x305757fd, 0x479c57bd, 0x1db9ef95, 0x7c7c8315, 0xf2955ec5, 0xfe66d8bf,
+ 0x2c458ebc, 0x4c74ff41, 0x02398e81, 0x8aeb19e0, 0x78008e62, 0x07b78dc6,
+ 0x7939e5d5, 0xc13798ae, 0xfde82bdd, 0x82b31ba4, 0xae78a7fa, 0x3a9e7a08,
+ 0x9ea8372b, 0xa822375e, 0xa385ef7f, 0xde99ea83, 0x67fa836b, 0xaa0e4c37,
+ 0x1cde34e7, 0xab18ffd4, 0xec147c7b, 0x5bfa3fb3, 0xebcc3f00, 0xd60cb8ea,
+ 0xb7ac433b, 0xa0f29aef, 0x5afd81f7, 0x53381e31, 0xcf17c990, 0x00abdf8d,
+ 0xff08671c, 0x39bee5ce, 0x55cfe341, 0x677e88ab, 0x048e1a36, 0xacf469fa,
+ 0xc02a4f6b, 0x38a7c6b9, 0xb95ea15b, 0xecf9f826, 0xbde81b1d, 0xf6e0bed9,
+ 0xeb839bb9, 0xd29cde83, 0xb901e79f, 0x4672bf29, 0x87dfb042, 0x9989d085,
+ 0xb599f4e4, 0x7aa5ffdc, 0x24e86afb, 0x27ec5f18, 0xd0438dd2, 0x9839298d,
+ 0xc11d226e, 0xfaf95374, 0x0708a1d6, 0xfba3fc2d, 0x0bc9e869, 0xfe007eff,
+ 0x7d306716, 0xfb4ee169, 0xec567583, 0x95efd850, 0x6acfb850, 0x2a797879,
+ 0x633b850b, 0x1fd7233e, 0x688fedc1, 0xd981fde0, 0x89ca18f3, 0xa8163bb3,
+ 0xe3638718, 0xecff3c79, 0xed07af8e, 0x2f898473, 0x97c484e5, 0xf80425d6,
+ 0xe97c647f, 0xaf19c634, 0x67111764, 0x844ffddc, 0x8f00c807, 0x0b11f301,
+ 0x71dd119c, 0x3c7f48c5, 0x653f2b49, 0xb9e3fa09, 0xfe2bd204, 0xbc3d6c78,
+ 0x03e6343d, 0xc653ae37, 0x8ebe64e5, 0x930a2bcc, 0x8497fc9f, 0xb40fcc04,
+ 0x75f9e347, 0x3a7cfb4b, 0x22bcc977, 0xc302f226, 0x4fa4ffd8, 0x14d7f19a,
+ 0x26760bb2, 0x0afebd70, 0x176dd78e, 0xa92fbc88, 0x471a7bd7, 0x2a7adfc6,
+ 0xc52a5d95, 0x2894bb13, 0xf46153e7, 0x3f0947ca, 0xe685bf51, 0xa8147f8f,
+ 0x38ee6a47, 0x0bf507bb, 0x6c63fdc0, 0x6f4058b7, 0xfdbd7e2b, 0xd12b68bb,
+ 0xaaebd76b, 0x9c342faf, 0xd8c47089, 0x222d8e01, 0xe445afdf, 0xd6f5c9fb,
+ 0xf4baa445, 0x9c1ed879, 0x8ae327ff, 0xc28dfdda, 0x3afe71fe, 0x976417bc,
+ 0x76e5cf2c, 0x870169db, 0x276e160d, 0x9db91318, 0x1f39ab50, 0xfb7036d5,
+ 0xacd7a40c, 0x8c718096, 0xdfea1689, 0x4c685cdf, 0xdf8471c4, 0x42a67965,
+ 0x4572c576, 0x77e47b21, 0xfcf4d1b6, 0x868509cf, 0x6fffe844, 0x6011af31,
+ 0x16636588, 0x93438f5f, 0xe892fe17, 0x68c252ff, 0x36898d2a, 0x5db67fe1,
+ 0x6a91f481, 0x5da91976, 0x8aa71f0d, 0x1afbe44e, 0xb464f229, 0x42718071,
+ 0xdfdfa26e, 0xe2d2edc4, 0xfe4189b1, 0xf18cf7fe, 0xd0afdfc2, 0x53942eeb,
+ 0xef7814bf, 0xeaefffc9, 0xf1476b67, 0xaffff5ad, 0x7ffee48c, 0xf1081f19,
+ 0x85c73bff, 0x1e23fff5, 0xfe7eeda2, 0x2dd893e9, 0x3e50d29f, 0xea7a30ed,
+ 0xb5d5fcf1, 0x6878ec1d, 0xa4ebe7ee, 0x7dc0c0b8, 0x673c4ed9, 0xbb64cf2d,
+ 0x4b6f482c, 0x7f3b4318, 0x696ea747, 0xe95f3c24, 0x3e7c3665, 0xbf3f2d7c,
+ 0x3871ae55, 0x0e529b71, 0xfdc89d5c, 0x1f380687, 0xbdf1725b, 0x27186dc9,
+ 0xd9953958, 0xb2350d51, 0xda2b22c6, 0xd8596b45, 0x4168e3f3, 0x770a134f,
+ 0x4276fe51, 0x0fb7cf17, 0x7693a7ed, 0x73e2217e, 0x2ce79758, 0x7971cf8f,
+ 0xcf112242, 0x5f3aeda9, 0xb27d73b8, 0xa46ae8ad, 0xf0be81af, 0xc29188e7,
+ 0xbb32e64f, 0x03f8e227, 0xd87cf1b7, 0x677f294a, 0xf01e98e8, 0x75e0453e,
+ 0xd79e5aca, 0xff7fcec1, 0x45ed2abd, 0x9433e346, 0x2d53952b, 0x5513f43e,
+ 0x697a64b6, 0x99c56e5d, 0xe5a2f283, 0x2bd6376d, 0xe86df3f3, 0x9dfd7097,
+ 0x91fb4729, 0xfcb8c9a9, 0x52a3b3d2, 0x8f1e909e, 0x64d438a7, 0xf1236f41,
+ 0x72409cb0, 0xc034657e, 0x92ed72bb, 0xf3d7985d, 0xc5191ffe, 0x5da80e9b,
+ 0x5fb07143, 0xe6167001, 0xa567a962, 0xa648b7e4, 0x718aa671, 0x7982ffbc,
+ 0xfef3fc23, 0xda75e5aa, 0xf30301cf, 0x9d1d0046, 0x038379de, 0x09e5eeed,
+ 0x93cfe411, 0xaa83da71, 0x42523ee7, 0x5c1aaefa, 0xd12d4dda, 0x9c83f436,
+ 0x3a61f9de, 0xb93e4dc6, 0xed05ace7, 0xbbe87fd8, 0x7c2f982c, 0x16bbd17c,
+ 0x93f1c017, 0x9de52a45, 0x86f42add, 0x897dfb84, 0x271fee1c, 0xdc2117ba,
+ 0xddfc5b6f, 0x2a3cc0d0, 0xe88130b6, 0xa54fb679, 0x9cb75c90, 0x168d1cdd,
+ 0xbabd774a, 0x2ea82e39, 0x89b540f5, 0xbf3b85d5, 0x69e824bc, 0x6306d376,
+ 0xf7e703aa, 0x38fa42ac, 0x7474e7ae, 0xe7c59b7c, 0xa7aff4cd, 0x11b069bc,
+ 0xb47f83ed, 0xea2b5898, 0x81877d33, 0x8abb49e7, 0x8f0ba015, 0x9d76bfc0,
+ 0xa68e5e7b, 0xc63e66f1, 0xcc1947e5, 0xebe010b5, 0x724d9969, 0x998fbb41,
+ 0x25c6389f, 0xae675c01, 0xe3fa1850, 0xc022ffb0, 0xfde1679f, 0xa5fda15f,
+ 0x379967dd, 0xf9480e58, 0x3cf02955, 0x79f821bd, 0x696fcb65, 0x43cc199c,
+ 0x27602079, 0x735f9e69, 0xd80af50c, 0x67ed4147, 0x519b66f6, 0x14496f8f,
+ 0x6ca1edf1, 0xfef0f7d8, 0x18ec88ae, 0x927e184f, 0x36c5c9e5, 0x17cfd622,
+ 0x7c795047, 0x5172a331, 0xaae3a722, 0x44efb796, 0xc766a97b, 0x738e2316,
+ 0x9681f1c9, 0x999bd613, 0xe896ef5f, 0x1e21af3d, 0x28252cd9, 0xe1b3504e,
+ 0x32ec91ac, 0xd1529f01, 0x00f08a5e, 0x1cc2dc3c, 0x503cf1ab, 0xc7f0655a,
+ 0x5bffe0e9, 0x60c3bf72, 0xd1da80bf, 0xb5173991, 0xb94fb95f, 0x5abcf96f,
+ 0xf30c7a05, 0x4583e4be, 0xd8cd1f42, 0x2f796938, 0xcefd5100, 0xfc9d1963,
+ 0x78f649bc, 0x516bc091, 0x8f64fdc4, 0xe3d88517, 0xb7dc3dec, 0xe64ac7a4,
+ 0xa5a23d24, 0xcc07493b, 0x23f7a06c, 0x4ddebd84, 0x120f2d6f, 0xcc3d245c,
+ 0xe4685d5c, 0xc8c79be6, 0xb26f4aed, 0xa326d7f0, 0x30e816bf, 0xba063ec8,
+ 0xed6baa0b, 0x9d0d2ff1, 0xb41f2819, 0xe7ccb876, 0x60e7c2d4, 0x9a5fcf22,
+ 0xb38d70e1, 0x8073c00d, 0x85f9397b, 0x10ca46f1, 0x3dc6dbe4, 0x6edf2377,
+ 0x0ff37ce4, 0x92b30f41, 0xf049113c, 0x9af4b3dc, 0xe77fc41a, 0xf2065312,
+ 0x8a6967b3, 0x3dfd0f1a, 0xc39214ab, 0x18a697a3, 0x97d3ce11, 0x7c871e0d,
+ 0x345ccb9d, 0x1638b4fe, 0x9c186ed6, 0x7947e5c4, 0x6319819d, 0xf4462908,
+ 0x506a9f0b, 0x9a8c2fc8, 0x6be02264, 0xf557c096, 0xa4adb78a, 0x6ff01caf,
+ 0xe01f5e28, 0x2aeab33f, 0xee701f09, 0x52c7cb08, 0x66b154af, 0x3b8c0a63,
+ 0xd11b6567, 0x82479c31, 0x95b2d7fa, 0x66eaaf84, 0xd5dd7b4d, 0xb9d83f84,
+ 0xb589cf11, 0xf79f823b, 0x8276124f, 0xbe913993, 0x225a773d, 0xb471af30,
+ 0x4ad94f80, 0x6b7286c5, 0x84b6b2fa, 0x7d3ea01b, 0xed84eaaf, 0x8587c374,
+ 0x1f2823fa, 0x1cdecced, 0x719c57f2, 0x9fb09238, 0x52edcac7, 0x8619ef45,
+ 0x3ce2d3ed, 0xd8cfd0c3, 0x618591f5, 0x73a1df7e, 0x11e4732a, 0xfca20f95,
+ 0x341b1b2a, 0x2fbec029, 0x3112d833, 0xf365e91e, 0xb83dc593, 0xd4f84088,
+ 0x7e24ac46, 0x887e45a8, 0x34c3f3f0, 0xdda17b8c, 0x7942a2f3, 0x30476c84,
+ 0x34709fbd, 0x9091c226, 0x9033efb9, 0x8a6f2e9c, 0xf971f3a5, 0xea2322b2,
+ 0xb16df2d5, 0xf9c11f64, 0x86cbbdf4, 0x6879f1fa, 0x649ede59, 0x39bcb718,
+ 0xe306a9d3, 0x19dcf431, 0x0d39ceb0, 0x8efe2487, 0x23bf80f4, 0x7807f0e1,
+ 0x4f2f6a0b, 0xe0497212, 0x238a2d8d, 0xef3a5abd, 0x58089cd5, 0x48ba99d7,
+ 0xe9ec93ca, 0x8c66c47c, 0xe903fca0, 0xabdf1abf, 0x7944cfdb, 0x0e57673e,
+ 0xf169fc21, 0xd3dffe36, 0xcbbda187, 0x68616efe, 0x66cb4d67, 0xf6864db7,
+ 0x6fce14db, 0x19afead3, 0xddc4768f, 0xbd9e5c49, 0xd5d07205, 0x41b7b197,
+ 0x0e40ba0e, 0x11f20bbe, 0x4e2fefeb, 0x8b87faa6, 0xb47e541d, 0x47951fb8,
+ 0xf25fbf84, 0xd102101d, 0x2e2492ed, 0xc9249717, 0x6482faf8, 0xffc66934,
+ 0x3a21ddfb, 0x6c67de1b, 0x9d36309b, 0xc15cebb1, 0xa9c6f7fa, 0xd3b5fac1,
+ 0x8c971b60, 0x0a15dbe7, 0xeee5a3d9, 0xe1fd4191, 0x7bc464dc, 0x9e5fac2b,
+ 0x86f49dbf, 0xe81938c3, 0xb8e2a6f1, 0x37d7fea0, 0x9fd506a4, 0xfad07248,
+ 0x0ecf8d26, 0xb4b9bf6a, 0xecbd507f, 0xa431919c, 0xf1014777, 0x679102cf,
+ 0x8e770704, 0xfbef1b17, 0xa4b0dd75, 0x5fbd60bb, 0x73d033ef, 0x5e243e2d,
+ 0x9951ac67, 0xbe9bc607, 0x2c1fe406, 0x74e348f1, 0x0e2fafe2, 0xb25ce858,
+ 0x7f6f29bc, 0x350fd401, 0xe80f2819, 0x55b8b2d0, 0x6a1daf68, 0x2832b04a,
+ 0x6155cb3d, 0x2c8cd8d7, 0x2d15de40, 0xa6f9425b, 0x93933e65, 0xef7697ec,
+ 0xc0eeb293, 0x122e2af3, 0xd53de4f9, 0xfe10aad7, 0x67df045c, 0xe15ee922,
+ 0xf127b071, 0x4ef4e12a, 0x0ae3aebe, 0x13f5865b, 0xb9f71f91, 0x6a71d60b,
+ 0x0e856362, 0xbeea15fd, 0xcf9f9204, 0xb6e90cab, 0xf2819e74, 0xafbf660c,
+ 0x533ac06e, 0xbe395372, 0x66a3ca55, 0x7c6898cf, 0x021405d6, 0x6d3c16fd,
+ 0xae01ea7a, 0xfb7d78ff, 0x8203df40, 0x8e8e913e, 0x2c5732c7, 0xf5a1562d,
+ 0xc276fe7e, 0x87ee7c06, 0xee106fa7, 0xfdc1bd7b, 0xefe01266, 0x20df0af3,
+ 0x128b6f92, 0x70b4af88, 0xf2e4623f, 0xa07c8bcb, 0x9fa6e5f8, 0x7e9296cf,
+ 0x26706e98, 0xe56e493a, 0x3adca0a7, 0x7640d2b2, 0xacbbd330, 0x3e8f4893,
+ 0xe72c744f, 0x8c77a239, 0x691df5c3, 0x5f9864c8, 0xa552be51, 0x1fd20af3,
+ 0xe7e3efef, 0x0f5587d4, 0xdbcc24d8, 0x525878a0, 0x3edcdd28, 0x5de5186f,
+ 0x596ded6a, 0xeabc097e, 0xe64bb009, 0x8179e4ec, 0x3f53bf2c, 0x3ee06075,
+ 0x3cf9f196, 0x4af94105, 0x1daf5955, 0x2ec8eb34, 0xc273c18c, 0xa254f789,
+ 0x8d5913b3, 0x9f019343, 0x86bb7527, 0x2ff505de, 0xea8f7a26, 0xda223ea1,
+ 0xeb842ff3, 0x0ccadd5c, 0xfaf30b25, 0x091aaf0f, 0xacfe7def, 0x2e6c49c1,
+ 0xcf39fcec, 0x43fdeecc, 0x1bd815f6, 0xe1ddb8bd, 0xcffbc14a, 0x1acd1d73,
+ 0xc7c3807b, 0x00204981, 0x056adb17, 0x7876376d, 0x3c01e588, 0x31d74f57,
+ 0xe079e04f, 0xb1e3c8b0, 0xa873f324, 0x24a61bb4, 0x5d333973, 0xbd9be9c7,
+ 0x037a70ac, 0x0f502afb, 0x173db948, 0xbf55aaf3, 0xbb72901e, 0xfe52358a,
+ 0xdb99238a, 0x1f15b32f, 0x9835ddd9, 0x2bfd0289, 0x56683c6c, 0xf3e4d9b5,
+ 0xb698d265, 0x7a60fb40, 0x73279732, 0x8e3ecf8c, 0x3ac95be4, 0xfd353ef8,
+ 0x2af8373e, 0xf543323a, 0xc36d854f, 0x6f8d3b32, 0xb79fa270, 0x756bf052,
+ 0x256be2a3, 0x51eb853b, 0x299d57e9, 0x3f56a8f4, 0x8d25e885, 0xd1a99a3e,
+ 0x5831acbb, 0xe97ac2cf, 0xaf5cb2de, 0x68ee9d76, 0x0e61c10b, 0x6ff50bac,
+ 0xa7b7c785, 0x38add684, 0xeb21a301, 0x31ee64a9, 0x780fb8b1, 0x5d08eade,
+ 0x215f769f, 0xd4fb15eb, 0xf9c2bbae, 0xbbe62b55, 0x04293554, 0x243eed2f,
+ 0x9c76b43e, 0x97854bc4, 0x45a2b7c3, 0xd67e7c21, 0xf2321f6d, 0x61ba4b6f,
+ 0xe02ff0cd, 0xb047497d, 0x6f9412af, 0x1e41ab95, 0xd3d28667, 0x456cd61c,
+ 0xad61a9ba, 0xdf9053cb, 0x1faf9b5a, 0xb5867e8e, 0xa9f9d36f, 0xa39aded4,
+ 0x7a50058b, 0xbf8e5773, 0x17e74fca, 0x5cfc278a, 0xe9ddc3f0, 0xe01e9fa5,
+ 0xeaa37335, 0xd4141c8a, 0x7a3fe44f, 0xbcb38e09, 0x63fa235e, 0xe53f0967,
+ 0xab59d685, 0x2e5ff7e7, 0xcf015eb8, 0x0fdd7b9f, 0x7764f727, 0x76173f85,
+ 0x3d1a5bdb, 0xfb81b1ff, 0xfe7ca55b, 0xff22ef5a, 0x3b0bb42e, 0xe3c6ceac,
+ 0x9eb91a7d, 0xbd724f9e, 0x3979e842, 0x5b35d1cf, 0x13305e29, 0xf68080ed,
+ 0xa56f56cf, 0xd9f1a578, 0xcbb45699, 0xbe99ae8f, 0x8f52f30a, 0xbd274d36,
+ 0xa97bf95f, 0x40c63df7, 0x4d68a27b, 0x907bfad9, 0x5247378e, 0xdda2b15c,
+ 0x2045ce23, 0x639fa167, 0x6cab970d, 0x95b39735, 0x90071fa8, 0xfd8bec7e,
+ 0xf4f0acee, 0x68087e45, 0xe779bd27, 0x779fcf74, 0xfe77b8c2, 0x25e9da29,
+ 0x755ad850, 0x5adbcf64, 0xcf563f51, 0xde20f0ff, 0xe07b01d3, 0x7b4b5ffd,
+ 0x0645aa00, 0xea325b4f, 0x54076121, 0x6c321bab, 0xbd083768, 0x7f801ff1,
+ 0xe7f87844, 0x11cbfc12, 0xdbf101fe, 0x9c381b4f, 0x7fe06ba7, 0xcbc72578,
+ 0x2b6ca6f2, 0x6d3f2f9e, 0xebbb26c8, 0x821ca6d3, 0x00078cff, 0x1f5fdcfe,
+ 0x0035776c, 0x817cf1fc, 0x96f587f0, 0xfc043bb7, 0x0dfe1c9d, 0x256cee1c,
+ 0xc084672f, 0x57f94bd9, 0xe4d1fe77, 0x78e23b44, 0x57d92b64, 0xaca8b7c7,
+ 0x932ec03e, 0xac37d176, 0xdfb449f1, 0xf767fc24, 0xf28418e9, 0xd7e1f4a7,
+ 0xd98788ac, 0x3150785b, 0x95ccfe04, 0xeec7f144, 0xa8edbbf9, 0xdd5f116f,
+ 0xe245d476, 0x19b986a9, 0xd796c7e9, 0x4239e00e, 0x45bf7171, 0xb66fbc8d,
+ 0x19bef823, 0xda9592e6, 0x8ce2c5d1, 0xa4f5c088, 0x79d3ef69, 0xbebdc618,
+ 0xd6eaf9cd, 0x5de7c4f9, 0x25b97941, 0xfe80d5ac, 0xd0acd636, 0x05eaed3d,
+ 0x8642d685, 0x5a3ab571, 0x09453387, 0x56aecbca, 0x564f6475, 0x447c4519,
+ 0x892455e4, 0xdc29497e, 0x629c902f, 0x2474f2a3, 0xda707d23, 0x7de1f462,
+ 0x255f382a, 0x9ddefce3, 0x41dbc226, 0x5fc0135c, 0x333f0a35, 0xb7a442a8,
+ 0xd3a7185b, 0x297bcc5b, 0x972707ae, 0xa71fa875, 0xc939342d, 0xa18f8dce,
+ 0x42cdd2f8, 0x5e62ddde, 0x313d46ee, 0x61746ccd, 0x317ae309, 0x1a30d7f9,
+ 0x0df987a6, 0xef748cbd, 0xf3a234b0, 0xdf123c59, 0x8ef87c96, 0x95ea5808,
+ 0x1fa38e60, 0xf6dd7e18, 0x5e285c7d, 0xf609f8fc, 0x8546d74b, 0x170c8bf7,
+ 0x2e5c5070, 0x609b3ff2, 0xc75828ec, 0x6f0714a8, 0x3fb8d877, 0xc9e02d7a,
+ 0xb6afc7e2, 0xfc79799d, 0xb1f30ab2, 0xbc58f7f9, 0x5d541f24, 0xc8cabd50,
+ 0x62794f9f, 0x34eaf143, 0x8e61dec6, 0x2ab78881, 0xee782194, 0x61f18b2f,
+ 0xf43aef7c, 0xd4b1db87, 0xd64cbd13, 0x978eaf33, 0x0e3b660d, 0x25e3fdc7,
+ 0x2abf9e02, 0x0031ad60, 0x83d7d6f7, 0xb437f3fd, 0x02fb5aea, 0xb7d3af7c,
+ 0xea7d21b6, 0x1b061c22, 0xaf1ee3cc, 0xa539e2e4, 0xadc5e96a, 0xa689e2b7,
+ 0xa0a3d5e2, 0xacf9e3ae, 0xfee6bf5d, 0x59805b89, 0xeab76e11, 0xcb9abb59,
+ 0x52e100e9, 0xa978776b, 0xe2853cdf, 0x202e3237, 0x86183ff1, 0x2de3c40f,
+ 0x4e307d62, 0x37df1583, 0x7cd7c786, 0x8ccc2f81, 0x15cfb846, 0xf257377c,
+ 0xbf30535b, 0x0478823d, 0x2ed0553e, 0x22ddb806, 0xe2f89eca, 0x476e14a1,
+ 0xcfc2943f, 0xe25cf7ef, 0x95dccc7c, 0x82797941, 0x7c4daa5f, 0x75ff397c,
+ 0xc5307ca2, 0xf5cbe34e, 0x8a7ebd00, 0x0240e8e3, 0x691ebd20, 0x68fb27ac,
+ 0xc3880b16, 0x49fbfa65, 0x77ad0eba, 0xf7dd11cb, 0x66bb1a58, 0x5f95e820,
+ 0x8e513a44, 0xce6c62de, 0xf68733a9, 0x52e67193, 0xefa061d6, 0x993f4903,
+ 0x55633fd0, 0x9535e533, 0xf41efc2a, 0x578b42e9, 0xc7e27607, 0x067bbe22,
+ 0xa79c46ec, 0xfca15634, 0x773169af, 0x975f2096, 0x2c7a8d5a, 0xdff1163f,
+ 0x8d17595b, 0x2b2d89ff, 0xdf8606e6, 0xe631504d, 0xa4f80b07, 0xadfb05d8,
+ 0xebc3f947, 0xe4695d2b, 0x4ff5128d, 0x665c61f7, 0x03a079ea, 0x762e1faa,
+ 0x5fa7bcc1, 0x91d9cf15, 0xfa7e7c62, 0xdecf413e, 0xe9de34e3, 0x53f3e4c7,
+ 0xf90af9fc, 0x7f5e2bfc, 0xea2f8e50, 0x2f9e6b0f, 0x827f3cd1, 0xf89f5bd7,
+ 0xf68bd8aa, 0xda4e68eb, 0x921423a5, 0x37214657, 0x12b6974a, 0xbb754b9c,
+ 0xb59a3978, 0xdc2ff2ea, 0xdb8a64ef, 0xf7809298, 0x50588fce, 0xd533ff0f,
+ 0x7e814c65, 0xfe79269f, 0x499ce586, 0x7288d78a, 0xe91f3df7, 0xf21e9285,
+ 0xae428d27, 0xa6e5ea9f, 0x831ea5f7, 0xf1c3de71, 0xbb9c752f, 0xe4f9c743,
+ 0x4d738cc7, 0x4738c86a, 0xfebecc7f, 0x24e1ca9c, 0x517691c7, 0xe94bba71,
+ 0x663afc85, 0x70bf9064, 0x18cebdee, 0xcc314bf4, 0xcfd00377, 0x919cda5d,
+ 0x7dcfe307, 0x0a8cc5ee, 0xbe849bb4, 0x32a739af, 0xdaa3c817, 0x5f950a73,
+ 0xc4647db4, 0xdb35b37b, 0xa0e38cda, 0x45942d5f, 0x12aaeb01, 0xa77d04eb,
+ 0xa7a01c9f, 0x4274bd8d, 0xf3cc3c6e, 0xa13b9e32, 0xd5ce7c47, 0x3dfd1f35,
+ 0x4a11efea, 0x97f2f8d8, 0x7b077f62, 0xee611fb8, 0x6151e5c5, 0xee34576f,
+ 0x390614f3, 0xfaa2fc60, 0xbf02f9f0, 0x1528eb12, 0x50fa6ffa, 0xe003844b,
+ 0x1e3de43c, 0x9b58af5f, 0x62fe8b99, 0x04e8f263, 0x7e8f5b82, 0x67ee2ed6,
+ 0xd67ee16d, 0x02c77b52, 0xbb994efc, 0xf883ec57, 0xbf09b2dd, 0x2c067c93,
+ 0x378eef0b, 0x89bf7ac9, 0x3f714663, 0x7ef3d618, 0xf220f99f, 0x6e28decd,
+ 0x361b4ecf, 0x43e50a30, 0xceb46667, 0x4facfc06, 0x4af7732a, 0xc6abf6c0,
+ 0xc9a17b61, 0xe08ca7d2, 0xf42e88cb, 0xb8feee49, 0xfe8fec4e, 0x35b18f11,
+ 0x87d806e1, 0xee950de7, 0x45067803, 0xcbc5c27b, 0xe5c5ef2f, 0x8d97bbb9,
+ 0x0757b1e0, 0xaff5cceb, 0x760fce43, 0x180e82fd, 0x94d2c8ef, 0x30380fc1,
+ 0x5d78531e, 0xfcff04af, 0xa33c92b3, 0xa23fe702, 0x68f07d63, 0x18ebb171,
+ 0x1d71f02e, 0xf74a06c2, 0x80b7a028, 0x31e4def3, 0xa9f541d1, 0x15cc71c5,
+ 0x9a9dbfe8, 0xb1bf541a, 0xffa83b34, 0x07fa33cd, 0xea689f3d, 0xb00bafc8,
+ 0x97b67b67, 0x5a9f04bc, 0xed0a258b, 0xbe5a4fba, 0xb416e0f9, 0x4eaa3703,
+ 0xef6759b4, 0x48c1f4dc, 0xf00675e8, 0x497e471b, 0x3ed1f907, 0x7a747997,
+ 0x7e303e97, 0x50758a74, 0xd73ca2be, 0x68dc6c5e, 0xf29dadae, 0x78ae7f09,
+ 0xe25ebcd1, 0x72cb9bfc, 0xa99e3f51, 0x79fc9f7b, 0xcfbe6635, 0xe21e2f53,
+ 0xbd442ddf, 0x357f7402, 0xe2f688be, 0xc0fc1039, 0x0e3b45ff, 0x86cd9c51,
+ 0xf7b44dc1, 0xf1e9e6d3, 0x942d64fe, 0x81c65fa8, 0xba018adc, 0x036368e9,
+ 0x48de61b7, 0xe5db85a6, 0xbf90a6e7, 0xf7146f7c, 0x8c4decfb, 0xcc48efa5,
+ 0xda86b86d, 0xd345ce6b, 0x1da96ff8, 0xfa2f28e3, 0x13e28505, 0x2da75313,
+ 0x8decfdc5, 0x1db80ef2, 0xe7f89de6, 0xdc23c7ab, 0x7bf1b66a, 0x77d51302,
+ 0x5941e7f2, 0xbd0d78d5, 0x7b65513f, 0x621fb015, 0xe342ddce, 0x001b444e,
+ 0xcb50eaea, 0x5597a803, 0x3f9f6b63, 0x5a31bca0, 0x9ed4de48, 0x26f7a48b,
+ 0xfdfd7114, 0x0c4f217b, 0x635d7c9d, 0xe7a24dcf, 0xbd7c2e92, 0xf7f282b2,
+ 0xf51b090d, 0x4321bdf8, 0xaffd42a7, 0x4a9fd73d, 0xfa37dfb9, 0x2fbe91fd,
+ 0x7af84860, 0xbe8de61c, 0xc8d8af11, 0xe3c8d12c, 0x62c375b3, 0xd5791858,
+ 0x9e39cf3d, 0xc73a6c6f, 0x3bff8ff3, 0xe417f5cd, 0x9d4592c3, 0x31178c7a,
+ 0xe10d8473, 0xd8305255, 0x67c01151, 0x8c9baeea, 0xeac31f88, 0xafa88db7,
+ 0x0516504d, 0xf916af3c, 0xdd795a58, 0xfc83e422, 0x3fd49b8e, 0xd106792c,
+ 0x4136ade7, 0x9e8f82a0, 0xdf2c7c16, 0x0e33a0ef, 0xf73b71e0, 0x79a6b7f3,
+ 0xd13942de, 0x7c6ec851, 0x4767e49e, 0x7e69c606, 0x9e03f5ae, 0x1bb21423,
+ 0xbeaf293b, 0xc3a1c0a4, 0xdd7bc0f8, 0xf3f3877a, 0x26d1f685, 0xca96fdf6,
+ 0x6fb8e216, 0x1d97f2fd, 0xedaf182e, 0xd43cbcee, 0xcfde720b, 0x0b7bf17a,
+ 0x1e75d6cc, 0x2fb587cf, 0xef903b47, 0x0ce1e227, 0x4d3ba2e3, 0x76816e74,
+ 0xbed4778a, 0xef0a7a6c, 0xe15ad5bb, 0x17f30afc, 0x8ad912bd, 0x4af6dc74,
+ 0xc7f51ea4, 0x9f3dbd1d, 0x5e8a7c21, 0xcf063be9, 0x9316ae8b, 0xe3fd919e,
+ 0xb6f24a3a, 0x485ef587, 0x4ce9697e, 0x81a7a7f2, 0xa0994bf3, 0x7fc172d3,
+ 0x6747c11e, 0x0f8892eb, 0x45822ecf, 0x91753c63, 0xda1b7032, 0x7d0b0e0b,
+ 0xe5f24e97, 0x411f3c44, 0xb1fec4fb, 0xeaa18f74, 0x1f106c5c, 0x14cb9f56,
+ 0xed471dfc, 0x05cadf92, 0x7d84989f, 0xb5d04331, 0x3f245bb4, 0x624f74b2,
+ 0x6263ec2a, 0x95bdf03d, 0xc8f9fee2, 0x31ba7e4f, 0x80be90da, 0x022b926e,
+ 0xedbea7f8, 0x8a768626, 0x744dde29, 0x40ca0333, 0xb766653b, 0x971b629d,
+ 0x592feb08, 0x7bc3a996, 0x6a79f29b, 0x7fd1a5ea, 0x27c8aa44, 0xa0e6b730,
+ 0x8ba86b5d, 0x9a7de274, 0x1e3cf133, 0x87057f34, 0xbb837ce3, 0xf98ced08,
+ 0x3fe4284f, 0xe503fb43, 0x7503d0d2, 0xcabf40c6, 0x5106e74d, 0xb9ca7d3c,
+ 0x2634a8cb, 0x38472e7b, 0x5ebb9d94, 0x8fd06be0, 0x710e3f8a, 0xc192bf71,
+ 0xc86e7267, 0x4792bf44, 0x4f1f3c45, 0x0347b667, 0x546b7de3, 0xb8c98ff2,
+ 0x9933f4a4, 0x804fdef0, 0xdf46fd3e, 0xa3df4198, 0x0a9dfad1, 0xb93ffeb9,
+ 0xbffa40d1, 0xa19dedaa, 0x79fe783a, 0xf5092ba6, 0xa7837ac9, 0x6733f708,
+ 0x0339efb2, 0xb83ee7d4, 0xe1dc3ad5, 0xbeb36787, 0x69f50735, 0xfd11c033,
+ 0xd52bcd5f, 0xf76e3ef1, 0x1a38f344, 0xcf496fa7, 0x739f3a5a, 0x73e09b2e,
+ 0x7a44ceb6, 0x2dd02ce8, 0x5243d00b, 0x2f3948ef, 0xeba48ff5, 0x5f973d6a,
+ 0xca18e6d5, 0x9debf323, 0xa442ee49, 0x1f3c7ebb, 0x9e77afd0, 0xf902355a,
+ 0xe53c74e0, 0x21bd4b5d, 0xc585e0f9, 0x244794c9, 0x03e492f5, 0x7ca5cf29,
+ 0xf52f7497, 0xfd3fe8d6, 0xc3bfd6ef, 0x3cd293af, 0x7d02a577, 0xfae7ab5d,
+ 0x85bd5aeb, 0xfc6c67e8, 0xcdd23d24, 0x43d1cbc5, 0x0a1e8e42, 0x3d35a392,
+ 0xa94581e8, 0x1c5e7e52, 0x7c11cc1f, 0xedc4de33, 0x81f39448, 0x8da6b5e3,
+ 0xb1f7087e, 0xd9eb953a, 0x3ddd6b9f, 0xa9d5ffc9, 0x97ff2697, 0xfc9c5ea4,
+ 0xfe54efff, 0xbcad0a9d, 0xa3710fc7, 0xf3bd3fbc, 0x83ea1f72, 0x03f40c83,
+ 0x6896c1ea, 0x0fa126c7, 0xc5445f48, 0x1f487ef8, 0xfe9ef614, 0xf5e1a9df,
+ 0xff6c66c1, 0xd240fab1, 0xc91be497, 0xb42f9227, 0x62f9247c, 0xbce16fc2,
+ 0x8b7a7888, 0xd6aa8fdf, 0x0e289b7b, 0x8c1e88e9, 0xc76dd9fc, 0xdf88536d,
+ 0xe084f442, 0x04bf3f1f, 0x1fc90deb, 0xff245f92, 0x98fe0b54, 0xf243f829,
+ 0xf9b56ec5, 0x0a9811d1, 0x08f9e690, 0x93e488e5, 0xfab5e7aa, 0x42ba47a1,
+ 0x199b234f, 0xae90c75f, 0xa40ca1aa, 0xfc0f532b, 0xf512f070, 0xa48bbec2,
+ 0xf3feafa7, 0x0f55f4f4, 0xa7e674f4, 0x1da853d0, 0x03be61fb, 0x1f3673d6,
+ 0x9fa66de4, 0x8dfc26de, 0x9b21fb71, 0x46f6079f, 0x35ee7df1, 0x67ff93a6,
+ 0xcf3cf7c2, 0x3303da57, 0xd241bf85, 0x01d81e69, 0xf8fc4369, 0xbcc0f3c7,
+ 0x847b938b, 0x877c5367, 0x3327cf11, 0x03b40ca1, 0x537fb27a, 0xee4d2ed3,
+ 0x17fe8a45, 0xb480f3c2, 0x1c6edd9f, 0xaf1e1690, 0x027ed303, 0xa262275e,
+ 0xb22bf92a, 0x00a35c4b, 0xba890f3f, 0xc2094fb7, 0xf902faf1, 0x2e55b2fc,
+ 0xd607ca3d, 0xf475ddfd, 0xcaa5bc77, 0x31fece7a, 0x8f099eb0, 0x1d1fbf32,
+ 0x151d8f9e, 0x511fedd3, 0x717fbf98, 0x95fed65a, 0x451be7a4, 0x9ea74ade,
+ 0x3d4483c7, 0x8096ea1f, 0xbea6817a, 0xeab7f796, 0x3e60593b, 0x928dd209,
+ 0x0eecf1cb, 0xfa601fb0, 0x2fa8b3f6, 0xff430a6c, 0x86fc6d46, 0x5ca2cf57,
+ 0x6c50a1db, 0xde0e1baa, 0xfa070481, 0x07d5383e, 0xc65d77ef, 0x78dbcdd8,
+ 0x43b5f6fd, 0x132f7956, 0x1bdc06e3, 0x2e2b3432, 0x502847ca, 0xa199597c,
+ 0x4d3dbef0, 0x1eb913ca, 0x0214f746, 0xaf9867de, 0x77ef2977, 0xd1674de7,
+ 0x4ba6adfb, 0x5186ff98, 0xac6fefe1, 0xe4c6fd10, 0xfe7d84c7, 0xe1ca9a70,
+ 0x3406fc2f, 0x694d343f, 0xff9f7f0e, 0x1d2fc109, 0x78213f18, 0xfe855a4e,
+ 0x84a30eed, 0xc2157bb7, 0x41632c7b, 0x9f98347e, 0xbad71bea, 0x7cf41a4b,
+ 0xbc0d2ebb, 0x77bf687e, 0x03db05a5, 0x5f069bf4, 0xf7801fa6, 0x77de61dd,
+ 0xfadfbf04, 0x125af843, 0xdba0bef2, 0x5d8e9259, 0xa31ef441, 0xc67d1377,
+ 0xb4362bc4, 0x91dc6ba3, 0xe0bcf12b, 0x12d2cfe7, 0x138c9b82, 0xb4dff084,
+ 0xc8033192, 0x6fcf124e, 0xebfc855b, 0xe7f775d6, 0x1ae928fc, 0x5c0136af,
+ 0xef07f5c9, 0xeb769cbf, 0x024ff42a, 0xaa73d05d, 0xadd603eb, 0x4d66c7e5,
+ 0x7f86947d, 0xfc91ff05, 0x70007d40, 0x16f941ca, 0x08e8c87f, 0x044f93a0,
+ 0x7c894e9c, 0xdcd18ef2, 0xe2c8ec9e, 0x3c6977e5, 0xa099f52e, 0x9e9253cb,
+ 0x90e002a2, 0xf43f4416, 0xf60221f7, 0x29ba704d, 0xbdf3f25e, 0xbfc0c525,
+ 0xfcfe761d, 0x66fed67f, 0x5fcd3795, 0xcff78ed7, 0x2096f7b5, 0xf7c7ba5c,
+ 0x768fda2e, 0x6e024dc4, 0x67bdaddf, 0xc08077bf, 0xbbffa273, 0xf41f40ab,
+ 0xa46a9e3d, 0x3e94250f, 0x2fa50d5e, 0xfa7de6af, 0xbd3d043b, 0x7950b7ff,
+ 0xcfbcd2e0, 0x17107bf0, 0x5bc0beff, 0xe3af06b1, 0xa31d7835, 0xbaca97a9,
+ 0x4afe482f, 0xe3be5cb9, 0xe312fbe1, 0xd0a9afd1, 0x3d3f2475, 0x3cf4483f,
+ 0x77e926d7, 0x4fd5c115, 0x47ed0fcf, 0x2cdc9dfa, 0xf491b5e9, 0xc39424cf,
+ 0x29f5fc23, 0xfea88728, 0xc5c60970, 0x91eafafc, 0x6fb72855, 0x1ffd9068,
+ 0x2f37fea5, 0xa6ade393, 0x8c8f12e7, 0xeefa463d, 0xafa97ca6, 0x3fb9271e,
+ 0xefbf85a7, 0xfeddff4c, 0x4687e41f, 0x6ad65c0d, 0xff4d5eea, 0x6fd017d5,
+ 0x2fef34cb, 0xa95f3cd2, 0xd4d1afa9, 0x2fdf821b, 0x1f10a19b, 0x38f01596,
+ 0xb52f96a5, 0xef4ae1f4, 0xf5ba73b6, 0xfb2662b9, 0x26af882e, 0xb5faf3d4,
+ 0x1a4b1be9, 0x75f501cc, 0x5f384a9b, 0xf7016cc0, 0x7ae6419f, 0x4307a055,
+ 0x20b3720f, 0xd9b907bd, 0xf9efab4f, 0xafe07ff3, 0x0a371429, 0xab764bb2,
+ 0x5536f5c1, 0x75bbdbac, 0x810182ff, 0x4be7d5f1, 0x63dd5cf0, 0x5cdbc71c,
+ 0x2ed02632, 0xae25cd62, 0xfeca7d80, 0x5efbbee3, 0xeb3cf9c5, 0xd1b25cfe,
+ 0x114f718c, 0x12f3b4df, 0xfa8aa5f4, 0x6ff856ba, 0x2f1e61c6, 0x5aa293c6,
+ 0x080fe673, 0xee6b27d8, 0xbb6cfb83, 0xb7dfe55b, 0x00fc07ab, 0x8398ca9c,
+ 0x33a750f2, 0xb6a5e517, 0xfc2cc4c5, 0xf76f782f, 0xd442eadd, 0xc61707d3,
+ 0x2bd35e51, 0xb17cfce9, 0xe277a63b, 0x45b7a84c, 0xb6f246df, 0x54b1feed,
+ 0xcb5d52ee, 0x2d8c6cbb, 0x894af75e, 0x1e7c72f9, 0x3bba7043, 0x2592a5fd,
+ 0xa6f7ef40, 0x8f7de83b, 0x03b896dd, 0x0c07eded, 0x0e043714, 0xe7e89278,
+ 0x3c60d341, 0xe92d976f, 0xf2b1714f, 0xc38d26c7, 0xf7e5a47b, 0xd25e2819,
+ 0x9f91b3a9, 0x58c0f3c8, 0xb19a93ca, 0xabde944c, 0xdfe57ca9, 0x7bc7ac7f,
+ 0x14eb5da6, 0x55cd4efa, 0x6dff375f, 0x1b2bd410, 0xc67ee9b2, 0x9474e7cb,
+ 0x9ae9fe17, 0x53cc3ebe, 0x47591c3e, 0x9fd0a5f9, 0x9e56bbee, 0xc92fec77,
+ 0x0daafec7, 0x428e3853, 0x47cfda3b, 0xe14fa857, 0xab32ce3d, 0xbbf30a25,
+ 0xc8c77e8f, 0x3ef473af, 0xe6ef7d13, 0xd6e7b353, 0x8f74f135, 0x767d2d09,
+ 0x15587154, 0xf4dac380, 0x29c925fd, 0xf8126ed8, 0x032d6fdc, 0x75d32f3e,
+ 0x93e90fd3, 0x5f5e588a, 0x92cdeebb, 0xa38fb04d, 0x7ca5f44f, 0xd70c84b1,
+ 0xd78074ba, 0x93d70ce1, 0xd9fb8a54, 0xc79bfcaf, 0x593a5f25, 0xb5f4889e,
+ 0xcbf5d059, 0x0313cae7, 0xc5416eff, 0xc1d13d29, 0x02c7462b, 0x5469eefa,
+ 0x6ce782ba, 0xf43883a0, 0xe710cf9b, 0x85e7a016, 0x57d8c35b, 0x3db9d34b,
+ 0x84dbf6d6, 0xba208e51, 0x29e498fe, 0xfea0379d, 0xa447fa62, 0x16988ee7,
+ 0x77752e62, 0x1ddb243e, 0x34327049, 0x3322fa45, 0x1aea7fd1, 0x4ff3a2e7,
+ 0x96c99f73, 0xfd143e00, 0xfcf2f13f, 0x3fa04fdf, 0xf13efb9e, 0x604b3ffe,
+ 0xaff6433c, 0x68bc5ab4, 0x58b31c5c, 0x838f88f4, 0x3147c5fa, 0x9d62ad3f,
+ 0xc540f481, 0x5d4584ba, 0x6e807f28, 0xdda6bfd0, 0xc0c32997, 0xc63d18fd,
+ 0x192f3f57, 0x5e781693, 0xbbf24139, 0x377cbe27, 0xc6c944fd, 0x65f33d01,
+ 0xa7cb8da5, 0xf7f8eb71, 0x58872b75, 0x7bbf74f4, 0xe89babdd, 0xc8bcf01e,
+ 0x5157bc5c, 0xf844ceb9, 0xbc58b4ea, 0xbef12bb6, 0x0b1f4581, 0xae74a1e5,
+ 0x0e19f54f, 0xca9147c2, 0x54b911f4, 0x190a3dd2, 0xf0b13c3f, 0x1d31c7d1,
+ 0xbbe673f3, 0xefc0187e, 0xe9d38b8c, 0xf92a6d99, 0xc4f1b51f, 0x1ab7d7ea,
+ 0x888fd90b, 0x4710f627, 0xe29d62ac, 0xe3e1e2bb, 0xe238da89, 0xbdc5d2bf,
+ 0xa238eeb3, 0x5187be81, 0x4588e229, 0x7f5a156b, 0xbdfe42e5, 0xee38a292,
+ 0x18b23e3f, 0xed2fa0e8, 0xc5cb6bdf, 0x7fae693c, 0x8be2992a, 0x5eaf5f80,
+ 0x99fc8f3b, 0x5e1ce975, 0xb03be265, 0x199d2387, 0x58afde78, 0xae704917,
+ 0x07f6727c, 0x7de3e44f, 0x81f189c0, 0xa09b6be7, 0xe19f180f, 0xce39683d,
+ 0xd0f725b1, 0xd68b6777, 0xf31939c3, 0x73d963b4, 0xde226537, 0xde303252,
+ 0x2e55fb29, 0xef0fbbbd, 0xd86ce707, 0x950ad977, 0xbb6b0f7f, 0xf021f489,
+ 0xb80b327c, 0xd9633e2f, 0xd72346eb, 0xa8792c67, 0xfe1db3b0, 0xc29f6cfb,
+ 0x4104fc73, 0x26b7b8ad, 0x5bef27e1, 0xf7f8e995, 0x0a754b36, 0x8902c3dd,
+ 0x7e97f746, 0xa3fdc191, 0xcedc1979, 0xd270cb2d, 0x55ea9e3d, 0x4cd2e726,
+ 0xbdf74e3e, 0x55e73875, 0x282a3aeb, 0x1317f9ae, 0x976a57f9, 0xad22ba45,
+ 0xf9e31f3c, 0xad779401, 0xaa3c0237, 0xfc6e5c1c, 0xad63d042, 0x94d5d263,
+ 0x0767ae9f, 0x5607eff0, 0xac9cb85b, 0x9bb8058e, 0x86e90139, 0x1939f7e2,
+ 0xb8e253e5, 0xe6028329, 0x8c3b4457, 0xc7fab0e3, 0x0d63abdd, 0xfec1a7e8,
+ 0x38420f97, 0x237f5dc6, 0x9559efae, 0xb4801af8, 0xbfed00aa, 0x3c3cd567,
+ 0xd8ad9777, 0xf0e50e3d, 0xf1832ddc, 0x7b2b0546, 0x23d25dee, 0x3bfe0573,
+ 0x395a3e45, 0x81bbf1d4, 0xb9706437, 0xdfb951e9, 0x2f0106e8, 0x79f20749,
+ 0xf7030af5, 0x47bc83e3, 0xe4bd5301, 0xdab71a43, 0x728891d2, 0x81bb7ab8,
+ 0x8cdf87ee, 0x973806eb, 0x751f492f, 0xdcaae800, 0x51df4310, 0x344ef2ad,
+ 0x51aabd62, 0xbdffbaa1, 0xd3a40c84, 0x60bd962f, 0x1c39fa45, 0xfa839ad9,
+ 0xa45e6ba9, 0xda29ee93, 0x8beedfb8, 0xaf743965, 0xc3ad8669, 0x9965df82,
+ 0x8edb20b1, 0xada0fc72, 0x0fcf88d5, 0xb0ea6736, 0x46d9b2ee, 0xbfa5dd61,
+ 0x885fea92, 0x41fa177c, 0x9e3852ba, 0x1b769aab, 0xdd2feff1, 0xd4e2e82b,
+ 0x41f6efb3, 0x4675503f, 0x2fd41f47, 0x527d0740, 0x28cfce11, 0x9a6b9fa4,
+ 0xa4bc1e78, 0x03a41a83, 0x8239bbe0, 0xbdb66a0e, 0x43f21770, 0x373fe20d,
+ 0x9e808e94, 0xf9fda9db, 0x7f18e30d, 0x44e91dbf, 0x2fa833ea, 0xce3fa033,
+ 0x058bebc8, 0x0c7da1fe, 0xe00ef76f, 0xf9dd75f9, 0xd07c4108, 0x66d77e13,
+ 0x4c3e04e8, 0x8ad77724, 0xd8ae76fd, 0x9dfc456e, 0x1ef7767a, 0x3f54b78c,
+ 0x11dada0f, 0x3c041f86, 0x56ff716a, 0x19d93f5a, 0xab5fb8b5, 0x74ddff7f,
+ 0x96b0f82f, 0xfdc9fdf1, 0xfec5ead6, 0xfef173e5, 0x2acfb13a, 0xadb5e026,
+ 0xc13be72f, 0xf4c7c867, 0x3fb121dd, 0xbbf83d8f, 0xfec5bbba, 0x6cc9449a,
+ 0x0f8456cd, 0x0fe517e2, 0x28cb8fd0, 0x397409e5, 0xe50365b5, 0xc97c4bf7,
+ 0xd7efbff5, 0x93fc2e2b, 0x9d8f1254, 0xb6f77c3d, 0xa1c9f045, 0x763292fb,
+ 0xd8befc00, 0x240d9f4c, 0xcc07d57a, 0xce46e927, 0x49a7f457, 0x61bee2d7,
+ 0x5f1c56fc, 0x1bd07bce, 0x0e71c7ad, 0x721fce32, 0x8b2f92fd, 0x3b5da7ea,
+ 0x4efd8ad8, 0x5ed1b259, 0x3f7c7811, 0xbbef46c3, 0xf7806ed0, 0xf2143b5d,
+ 0xe7121f5f, 0xbdf743fd, 0xe01f2d60, 0xc577f7a7, 0xe19d25ba, 0xe4c9fa0f,
+ 0xb9daf77a, 0x6ebb583f, 0xbae48729, 0xe1bfee8b, 0xeb976c5a, 0x2051f8c7,
+ 0x4a384a9d, 0xfaf7957a, 0x344b74b4, 0xdaaaf527, 0xa6d77d33, 0x9dfca21d,
+ 0x78ed7690, 0x2c3a3ec2, 0x9ebbcdf2, 0xe77df956, 0x41edc965, 0x33188ef7,
+ 0x259fea07, 0x15b6aef3, 0x49b73c62, 0x521e7ba1, 0x4acfc0af, 0x923e807d,
+ 0xdef0c1f6, 0x36a57f3c, 0xf10275de, 0x63bc7559, 0x44927e1c, 0x7d57a5da,
+ 0xa0c6aadd, 0xcf1b6aff, 0x53749383, 0xf89db275, 0x93dc5aa1, 0xeef15b2a,
+ 0xf74861c4, 0xce281b4f, 0x58df7653, 0xb3fbda23, 0x8a1f4d37, 0x127bc0e0,
+ 0x6c4fdf28, 0xe047921c, 0xebc4b661, 0xc6c4bef1, 0xbfc7af47, 0x87633a5f,
+ 0xc1a1df4a, 0xcb8f9071, 0x7f23c8ee, 0xcec8e1eb, 0xaed02389, 0x436ab5ff,
+ 0xa6e47ebb, 0xffb08b21, 0x58ef4b48, 0xc6d078fa, 0xf4bbaa38, 0xa427a431,
+ 0x03f32c1d, 0x90bdc5eb, 0xaf9cdeec, 0x8a97757a, 0xefac0bc8, 0xaef9f183,
+ 0xddf4910d, 0xa3a352a8, 0xdbe715b9, 0x8ee74499, 0x2526385a, 0x2b9ee9db,
+ 0x8cb369d9, 0x9725222c, 0x453023da, 0xc74375f9, 0x5e4fa81d, 0x1832c3bf,
+ 0xd4cb8bbf, 0xb9cb43f3, 0x90e3cd7d, 0x61dfc171, 0xeac8eb92, 0x3b57e9cd,
+ 0x2f7f7c9e, 0x74ec2b9e, 0x3fde919f, 0xebe9ecb1, 0xd89e1f51, 0x7dc7639c,
+ 0x4919db1f, 0x198e0bf7, 0x78e7bf82, 0xb4c2f7a9, 0x3de4a9f7, 0xc1defcd7,
+ 0xfba49cf6, 0xb9cbde0b, 0x98f2d2ec, 0x74662e4e, 0x065cfc4f, 0xe8e4fee3,
+ 0x7e62b6ef, 0xc9a34561, 0x8e64f786, 0x7c63fd20, 0xdf4abb6b, 0xdfbba201,
+ 0xdb23af80, 0x703ee8f3, 0x5ebcc7c5, 0xf0f8acd1, 0xc3fb72fe, 0xc2fe53f7,
+ 0xf137b04c, 0x3db7796a, 0xebe1fabd, 0x38ce0d91, 0x3bf1cb3d, 0xf3366700,
+ 0xef908b7c, 0x75bebc3a, 0xffe38a4f, 0xfd2cfdbf, 0x077bd313, 0xf09347df,
+ 0x57aae796, 0x720a2e80, 0x72fbf0fd, 0x9fb22cf1, 0x50f62e4f, 0xb4395a79,
+ 0xb3d2246a, 0x15ee8625, 0x51e3b4bc, 0x5373bf15, 0x79f06dbd, 0x308f1f3c,
+ 0x9ff7d0c7, 0x90bc5cbe, 0x17279a82, 0x8a3f89d7, 0x15f854b6, 0xb55e547c,
+ 0xfbde8dad, 0x0b5e4772, 0xd97debde, 0x9ac5c31c, 0x3be820ab, 0x3dbf1299,
+ 0xfb9657dd, 0x1cd7fcfa, 0x9fdd72cf, 0xc56e9e6f, 0x21fdb57d, 0xe23865ae,
+ 0x86c63a37, 0xc8a56076, 0x86ba392f, 0x23c7d9db, 0x18abfe62, 0xed7c7cf0,
+ 0x0efc4494, 0xa9b6ccd1, 0xc57b63d7, 0xe786c54e, 0x49cee703, 0x7dcf3c56,
+ 0xe2b4efa6, 0xd6cfaa3d, 0x3e57fbc8, 0x237bbbfa, 0xd829b3c6, 0x9eab447f,
+ 0x84293239, 0xfc32f44c, 0xcbee9ea4, 0xe4ed017e, 0x451f393f, 0x89f813fe,
+ 0x99927cc3, 0x4bbf722f, 0x9c57f9f7, 0x7d8a46ff, 0xcbb6f7b7, 0x17b506f8,
+ 0x63f6f015, 0xd096b76b, 0x68de4fdf, 0xbfbae1b0, 0xf1a068dc, 0x4db9c0e7,
+ 0xbe3deb07, 0xb0839f99, 0x13e8e78e, 0x6779f99b, 0xef3f334e, 0xb833cf54,
+ 0x60d2fdf8, 0xe80a2cba, 0xeb2ddf47, 0x7323bbe1, 0x737f7c5c, 0x7ee27f40,
+ 0xb1bf442f, 0x9fee99ac, 0xa93e6a5d, 0xaaff7e96, 0x74dd1791, 0x08bd13db,
+ 0x23ff22b8, 0x98ba4add, 0xf5c786b3, 0x0b83cded, 0x9d24fe91, 0x5803bf68,
+ 0x3bfc646f, 0xfa28bab2, 0xb324f7ee, 0x62fa80c3, 0x18e77c4a, 0x075f4f04,
+ 0x916aaf97, 0xe4f785ce, 0xec29bd58, 0x15dec477, 0xbc1a78f2, 0x7abbf74b,
+ 0xcff7f8db, 0x59317dc4, 0x474abe82, 0xda293e7d, 0xba038dfe, 0xf2ffae74,
+ 0xf5d03d3a, 0x3bf691a4, 0xd7809db2, 0x7af35ff5, 0x167b7d9e, 0x7def3fd4,
+ 0xec3d3af6, 0xf695d26f, 0x2fa80621, 0x75cdf259, 0xc9b9e063, 0x3bd83ae1,
+ 0x9b139e60, 0x7f71d292, 0xdb087ed0, 0x8e7a27a7, 0xee2b5960, 0xba569d8f,
+ 0xf4cc2d06, 0xa77b7ff7, 0x0e4be0e5, 0xc0d3bd7f, 0xa73bbbe8, 0x87f5cb7b,
+ 0xd70e9d2f, 0xa109dea9, 0xdd8ce5ed, 0x5e7cf947, 0x7e076f7e, 0x788911dc,
+ 0x5dd38aaf, 0xd3c7bcb9, 0xe3c7b9a0, 0xe4d5f7e4, 0x7f792afd, 0xfdff72ea,
+ 0x7297b5b3, 0x00ffecff, 0x4fb2f369, 0x00008000, 0x00088b1f, 0x00000000,
+ 0x7de5ff00, 0x5554740b, 0x55b9e896, 0x2a493eb7, 0x54842549, 0xaa84a925,
+ 0xc0902b7c, 0x310c7c25, 0x0403e548, 0x6a285888, 0xa205a0d4, 0x01148280,
+ 0x55f4741d, 0x9a7c3061, 0x179f8ee9, 0x102d4622, 0xdd787195, 0x866db1d1,
+ 0x3220538f, 0xb40e9afc, 0xd38ceb63, 0x68d1d01d, 0x38311b63, 0x6f360cf4,
+ 0x4dce7def, 0x802a56ea, 0x6f7be7be, 0xf65e97ad, 0xee739f61, 0xffb3ecf9,
+ 0x5f5bdf67, 0xa5eb2c19, 0x0f24c664, 0xa153ab63, 0x63595a74, 0xff7b9419,
+ 0x68d2cfe9, 0xac839ac6, 0xc18f2e3b, 0xd3f5a35f, 0x7ccf5051, 0x2e504bba,
+ 0xcd1a484b, 0x139960c6, 0x996fd062, 0x12aeb189, 0x6d3b26e8, 0x12d8c2cc,
+ 0x019dfe09, 0x19caf9ff, 0x956c674b, 0x44edfe15, 0xf08742b8, 0x7f466683,
+ 0x3f98059f, 0x1fd8c0df, 0x3925744f, 0x9d9d8cf5, 0xbb0c2e1d, 0xbc65fb18,
+ 0x009ce6cf, 0x8ecd1ded, 0xbec634a6, 0xd4a4c37c, 0xd09eff43, 0x60f927df,
+ 0xe67aa5fc, 0x6d9284ef, 0x24d8ce1f, 0xc3ea2f28, 0x61dfa053, 0x8db6f157,
+ 0xa9cbbcf0, 0x3f9e0c63, 0xfce70aeb, 0x82c678f5, 0x32f2932e, 0x32777ea3,
+ 0x9f1eeb80, 0x9dfb1c3e, 0xfe5d7d7d, 0x936eb03d, 0xec1258cc, 0x598c067b,
+ 0x0030780e, 0x07c32fac, 0xb40e3442, 0xbea09307, 0x0e74f5c5, 0x2f307c23,
+ 0x0dd8c89b, 0x06ebef8c, 0xf11fbc39, 0x196494c5, 0x6f9b37f7, 0x3283db0f,
+ 0x3333a38c, 0x98bbae03, 0x4d3f5875, 0x8eb19800, 0x7f60c34b, 0x3263c066,
+ 0x24c78096, 0xa1eaa6c6, 0xe9afac13, 0x0990fa97, 0x7884d7d6, 0x85d07014,
+ 0xd72c7a23, 0xc58bf8c3, 0xbc8ecbbc, 0x58c1c46b, 0xeb07fe10, 0x5de62259,
+ 0x3d7771dc, 0x9092cb9e, 0xc0b74ce1, 0x7ffa25f5, 0x72c79d0f, 0xf2feefd1,
+ 0xe29c46ad, 0x7eda1dfe, 0xafa6d9cb, 0x52fcf0f5, 0xfdc46dd6, 0x6a8ceb2e,
+ 0x0cf9a8ef, 0x977cbbd7, 0x99debeb6, 0xc2748698, 0x97b1b2c6, 0xe74d54f4,
+ 0x99f448bd, 0xca746faa, 0x66e19fb8, 0x371304c5, 0xf4479f3d, 0xb00cdec2,
+ 0x63ac7ec8, 0x8b4fd118, 0xb1e74f4b, 0x9cc49764, 0x7ebb18e3, 0x42731657,
+ 0x61aefd53, 0xc85d2654, 0x5fcffaa0, 0x57de3639, 0xd75e7032, 0xc6ab6abf,
+ 0x6aff5df5, 0x3aea9511, 0x4e1d049a, 0x867497d5, 0x2ce71d61, 0x9b800eb0,
+ 0x8162c08e, 0xd66e9a7e, 0x99e11887, 0x57bfb199, 0x596bc72c, 0x424fa5df,
+ 0xfd8a0e58, 0x3a24974a, 0x1f3c6484, 0x433d61ef, 0x031e627a, 0x79993bb5,
+ 0xa05ca5cd, 0x398ebb1b, 0x24dfe063, 0x19ce2fce, 0x81ee9ccf, 0xfc583976,
+ 0x87584ab3, 0x0941ae61, 0x5c737b41, 0x33e436d2, 0xe574f416, 0xe20d73c3,
+ 0x4e38aeb9, 0x54ee0937, 0x1d2af3cd, 0xadfa2adc, 0x18769a4b, 0xb3c1b2e9,
+ 0x5121e888, 0xc7acd4c9, 0x406a5fa4, 0x67d5b9fa, 0x623ba4f8, 0x585fa21c,
+ 0x295e0dc7, 0x7378fc84, 0x50ddb683, 0x44ad75f9, 0x8e47d425, 0xfbf6d5e7,
+ 0xd003d229, 0x717e103b, 0x9c0c3d24, 0xc3a3c583, 0x1224f073, 0xb9cccbbd,
+ 0x5be012b9, 0xee181b0e, 0xf7cf14df, 0x97310e79, 0x0f80fd86, 0x8875e260,
+ 0x2e4fa817, 0xc537e2d7, 0xb0e7c5a3, 0x867e2d3a, 0xb7fbb57b, 0xda6ae435,
+ 0x35237c33, 0xcb8b59ed, 0xbfb67034, 0xc47fd342, 0xec0d6aea, 0xf4d4ce0a,
+ 0xa37f5bcf, 0xbd682e06, 0xa8bfd35d, 0xbda6817d, 0xa69f7438, 0x268ed47d,
+ 0xf9da5c0d, 0x98ffa688, 0xda6b8f5d, 0x6a3786c7, 0x7e1dc7da, 0xe84f034a,
+ 0x7fe9a2da, 0x34db07cd, 0x5fba93ed, 0xdb5fb4d3, 0x9e0686f3, 0xd35bbbdc,
+ 0x0385ca7f, 0x1d8ab81a, 0x31aff4d3, 0x4f0356ff, 0xa6abfeb5, 0xc7fb74ff,
+ 0xce19f69a, 0x67da6a3f, 0xd2d1bfb9, 0x93973c6b, 0xa5ff2bd7, 0x9359ee79,
+ 0x5f50dfef, 0xdd954b34, 0xebf48641, 0x35ba3e24, 0x0184a74d, 0x972a83fe,
+ 0x1c9e1d04, 0xc1392561, 0xb78e59f2, 0x32b0e914, 0x6e7c7c8c, 0xe0f24497,
+ 0x28bd28ab, 0x91ebd1ff, 0x4afd9da0, 0x22765e52, 0xc45d41dd, 0x331e29fc,
+ 0x39d62393, 0x81aaceac, 0x9aed7b87, 0xa706b6fe, 0xe7c33da6, 0x2d67b4d6,
+ 0xb6703456, 0x7fd35cbf, 0x068f6ac4, 0x34eb0576, 0x7bd6f3fd, 0x6b417035,
+ 0x517fa683, 0x5ed34fbb, 0x69ac5a1c, 0xafc3b51f, 0x573b4b81, 0xd98ffa6b,
+ 0x8fb4d415, 0xb4d7af0d, 0xaadc3b8f, 0xb5742781, 0xf35ffa6b, 0x3ed34841,
+ 0xa6877ba9, 0x4e9edafd, 0x77b93c0d, 0x94ffa697, 0x5c0d610b, 0xfa688ec5,
+ 0x6a4f98d7, 0x0fd6a9e0, 0xdba7fd35, 0x67da6b4f, 0xb4d73f38, 0x2cd076ab,
+ 0x7adad7f7, 0xaf5d1761, 0x7cf359fc, 0x90c3dab0, 0x486f823e, 0xd613b34a,
+ 0x3fe102eb, 0x777ce49c, 0x28ed1e9c, 0x8c14182f, 0x41ad2901, 0x420c92fd,
+ 0x480ae90c, 0xe2a6358c, 0x20ac4028, 0xc15549b7, 0x4f68c9f3, 0x73aa9000,
+ 0x1fa0fcb9, 0xeb5ad813, 0x1bb266a7, 0xdf40971c, 0x29bfc25d, 0xa0944b83,
+ 0x85ebaa9f, 0x4ea166f9, 0x726f3a02, 0x582e3cf9, 0xaf9d7dcf, 0x6862cb4f,
+ 0x705b0427, 0x9307a01d, 0x9e6f41bb, 0x79776388, 0x378f064b, 0x89780cc3,
+ 0x5c48ef98, 0x32cca3ab, 0xcc33fcf4, 0xff7fa967, 0xae3e06b8, 0x8a6bfb04,
+ 0xa0a7ff18, 0xfbb065ee, 0x37c0035a, 0x153d8c05, 0x4cfc12b0, 0x5b704ec0,
+ 0x7b6549c0, 0x96e54dc0, 0x1ded4280, 0x5f827281, 0x0e087808, 0xdca8ea05,
+ 0xfd52f016, 0xc10340f6, 0x547c04af, 0xa62c08ee, 0x9f80b5f2, 0x560677da,
+ 0x40f3fc13, 0xc0ceca90, 0x237faa7a, 0x9bf04ad0, 0xdf827681, 0xdca8840a,
+ 0xe541d815, 0xb52740ee, 0x22ec0def, 0x9840edf8, 0x30e070e0, 0x5d0207c1,
+ 0x7c0c1f04, 0x40a1f040, 0x03879537, 0x0d1e543d, 0xf1fb52f4, 0x078205c0,
+ 0x576b4bce, 0x2e576133, 0xd2c07412, 0x2f793db8, 0x85f6523f, 0xbb462d8e,
+ 0x43a09177, 0x87983543, 0xcc867740, 0x2ecd6dc2, 0x13a06a3c, 0x71c9d137,
+ 0x96af2fb4, 0x4070d04e, 0x33560d7a, 0x5a9bd237, 0xc9e954b6, 0x90ae0cfe,
+ 0xbb732f42, 0x336feb88, 0xb537f553, 0x85283e37, 0x079b9ed0, 0xf811b276,
+ 0x9f6123e6, 0xe5c7147c, 0xc1bf39f5, 0xa35f768d, 0x66c0af14, 0xb277fe01,
+ 0x8c2fe03b, 0x5ed77fa4, 0x9fb456d3, 0xc235f5d4, 0xe7183a38, 0x5a2eecbf,
+ 0x6c3b2357, 0xbd40f5c0, 0x72fc0f47, 0xe2dbe6c6, 0x2fbeba02, 0x2234175b,
+ 0x85425913, 0x8cc644de, 0x48f3df76, 0xf7fce7e7, 0x17c1c21c, 0x9c429559,
+ 0x78537ae7, 0x7f30adf8, 0xb2bd11ef, 0x5e3439cd, 0x00ceb796, 0xf6997de1,
+ 0xa0773fb7, 0x17f75f1d, 0xe1cf0fbd, 0x21b12184, 0xe9dd7404, 0x3acf8892,
+ 0xd94d3a5d, 0x02fdf766, 0xa26df9d7, 0xa01d4eff, 0x56ebdbf2, 0xb612b2bc,
+ 0x20a2b8d4, 0xf055ed19, 0x5f680c0f, 0x034e61cf, 0x989b87ca, 0xea1c5de7,
+ 0xf823e666, 0x52a41656, 0xe176f9b6, 0x21636ebe, 0xa6157d82, 0x8afb589c,
+ 0x383bd75e, 0x752c70d8, 0xdd90f29a, 0xfbc70077, 0xeb43d136, 0x7a69313a,
+ 0x5d4bee21, 0x49c33997, 0xdeb366fd, 0xdf7d7017, 0x53fafbee, 0x9d306f29,
+ 0x61f488fc, 0x3fb06981, 0x3779c233, 0x38e0ef03, 0x214b0fcd, 0x3e9573a4,
+ 0xa74cc11a, 0x7a851ff1, 0x805e9229, 0x4b7fd04e, 0x9399cdeb, 0x4dd2f448,
+ 0x3e926ff2, 0xfa7b0468, 0x28542e84, 0x8c4e89e9, 0x5173ac12, 0xee49d01a,
+ 0xc0f0f4d0, 0xe423287a, 0x17d9d020, 0xfe9fde38, 0xe2371ae1, 0x93dbf96d,
+ 0x66b7889c, 0xd0079c1d, 0x9ea8f073, 0x442604ec, 0xd2dafebb, 0xb207f910,
+ 0xc529cca2, 0x7172e373, 0x7ead9ebf, 0x4ddc863d, 0x74f4e5c8, 0x0ba86ec2,
+ 0xef9cb8d1, 0x2e7d76d5, 0x2e7d473f, 0x15a6df3f, 0xc3d52d9f, 0xf81c4ffa,
+ 0x8d2ce8dc, 0x3fd58fb1, 0x823f2879, 0x3aef97ae, 0x7e83cd3d, 0xb92eeb17,
+ 0xbea07131, 0xd2abcc50, 0xe898de91, 0x5c896adb, 0xc75d3f57, 0xa75d22e7,
+ 0x11e75d00, 0x768a7f5d, 0x33936cf9, 0xbb2856f9, 0x28613501, 0xc95a2f7d,
+ 0x14c05c7f, 0x2f32172a, 0x0c808b95, 0xc1bd8e90, 0xf7888d27, 0xd52758fb,
+ 0x777e503f, 0xbdf5d23a, 0xd9f91f3a, 0xd517594b, 0xb5bd672f, 0xaf37b478,
+ 0x1daef35f, 0xeb537d56, 0x44915393, 0x7fcd0c6f, 0xdb39cb17, 0x4e834fa5,
+ 0x5cec93e2, 0xe4b747c0, 0xe613227f, 0xd5677dbf, 0x3f505913, 0x85cfcf5b,
+ 0xa2e7e31d, 0x7de891ca, 0xe0145f03, 0x78a6dff3, 0xa4fa5f68, 0x345f0d3a,
+ 0x123cce3e, 0xcfbbd38c, 0x8ae6da14, 0xfbf293e0, 0xf28590ff, 0x13bdee4c,
+ 0xdbf97bcf, 0xef3c54a6, 0xfbd718fb, 0xaf8d4792, 0x119efaa8, 0xe2cfdfbd,
+ 0x85f7ec15, 0xb22fefa0, 0x17f7d119, 0x658a3812, 0xcb287603, 0xf2cbd9f1,
+ 0x72f6f406, 0x88d1cedd, 0x95ebd027, 0x7df70e78, 0xd632d9dc, 0x9420fa85,
+ 0xe1887683, 0xecd29335, 0x7617e8d2, 0x8d850129, 0x7f3e219f, 0x198ee38a,
+ 0xfca92ebc, 0xeed19fd0, 0xd0591930, 0xce7c465c, 0x677f2226, 0x9abf891a,
+ 0x3879b511, 0xb7e9d78f, 0x84ff1e0c, 0xefe1ef58, 0x841d3fb8, 0xc52cbcfd,
+ 0x2feb879a, 0x3cc0fc53, 0x19d24724, 0x2e4773cd, 0x3e7563e7, 0xa076e966,
+ 0xc1347e9d, 0x8f9e3b77, 0xfd52471a, 0xcfaec3c8, 0x667cf1f2, 0xe5506c57,
+ 0xaec78d33, 0x84e972e3, 0xf84419c1, 0x014b9544, 0x6f2fd609, 0xa7ff286f,
+ 0x371d700f, 0x8c612d98, 0xc34ab077, 0x35ff7ed9, 0xdf1f4077, 0xcae3eaa0,
+ 0x1a8ef8a8, 0x018a61f7, 0x3ecc57d7, 0xf141f152, 0x0e4e551d, 0xb1b0bfd2,
+ 0x889fc42e, 0x79c7f597, 0xce3fb9fe, 0x8d79c3a3, 0xe6328e42, 0xf8237b77,
+ 0xae00d6d4, 0x307fc68b, 0xff8d7cb3, 0xd9c0d560, 0xffa6bb7e, 0x4d4ed588,
+ 0xd6e82bbb, 0x57ade7b4, 0x6b417034, 0x517fa6b9, 0x170347bb, 0xfd34ea87,
+ 0x6af0ed47, 0x06ced2e0, 0xbb31ff4d, 0xb1f69a7c, 0xf69ac5e1, 0x1afd8771,
+ 0x6ad74278, 0x3e6bff4d, 0x27da6a08, 0xb4d7af75, 0xaad3db5f, 0xb6f72781,
+ 0xb94ffa6b, 0x57b4d210, 0xb4d5bfb1, 0xd75f98d7, 0xf1c62fc0, 0xeb54e778,
+ 0x9b9e683f, 0x81afdf6e, 0xf1e7885f, 0x23ce199a, 0xf9c5e7da, 0x278b6f06,
+ 0x3ee5987e, 0xffdf69a9, 0x8dcdc8c8, 0x47a12fc0, 0xb67fe474, 0xc53d71d5,
+ 0x1d39aa1a, 0xd7bef1c4, 0xe66a1f2b, 0xbaf7d1cb, 0x7a9d8e90, 0x75f2266b,
+ 0x039cf97e, 0xd0ac7640, 0xc51aa2b3, 0xc9eebb9d, 0xf48e5803, 0x6c8d5ebe,
+ 0xf270d253, 0x7da39600, 0x1903575f, 0xca716533, 0xf996583b, 0x70d8d6c7,
+ 0xbce7ab89, 0xe0c4e583, 0xb3941a8a, 0xb17e2660, 0x3e7dd608, 0x846d9238,
+ 0xaa652575, 0xd10f5e71, 0x1d0caaed, 0xdbaaf9f1, 0x4b37142c, 0xa322d6bf,
+ 0xe81cdf3e, 0xec10791a, 0xd3a7f4dc, 0x69dc62d7, 0xa1f9d83d, 0xc017b022,
+ 0x59f2c7ee, 0xe043ebb0, 0xbb046d1c, 0x604dcb1f, 0x73fd63f7, 0x9c23f760,
+ 0x7ad974fe, 0xc9d56e7c, 0x6172ea7b, 0xca0f11fc, 0xd7533456, 0x0e2b7539,
+ 0x0fec7ac0, 0x4b28ad1a, 0xe267ae8c, 0xec8eb09c, 0x0a8eb065, 0x51078b42,
+ 0x3052ecfd, 0x1c39321c, 0x2becfd07, 0x1db81a74, 0x2eb045ff, 0x97cf8b58,
+ 0xaedee93e, 0xb6f9f630, 0x8a1937b3, 0x5d799f61, 0x014d6db7, 0xe6799738,
+ 0xf1d3be02, 0x93fc602c, 0x09cd8f79, 0x97860c96, 0x48ff7a14, 0x2cee4972,
+ 0x16b53e46, 0xeb81947d, 0x85fd50da, 0x3ce2b3a2, 0x0839cc8f, 0x787e7eeb,
+ 0x23e758bc, 0xaff2aa73, 0x79cf5c66, 0xef50ef94, 0x47218cef, 0xffe853fe,
+ 0x2f5c7993, 0xe5159fc3, 0x08938d93, 0x949d81b3, 0xf376f20c, 0xd1a7d5a4,
+ 0x41ad90a7, 0xbb23e509, 0x144fcf08, 0x7823c828, 0x1e44fc4a, 0x537947b2,
+ 0xe733e454, 0x1f3678c1, 0xf1914ed8, 0x785ac5b1, 0x19e79c33, 0x0c7ac0c3,
+ 0x3282e977, 0x92f0c1ec, 0x9e605157, 0x5fb0798e, 0xb51b3780, 0x8e9165fe,
+ 0x9f717d91, 0x378beeba, 0xdda76829, 0xf0f5c797, 0xecbb8096, 0x7ffa0313,
+ 0x4027d94a, 0xfd8b9947, 0xabe40f92, 0x04abd1ad, 0xd2e19fa1, 0x2237efdf,
+ 0x3ac5df61, 0xfd639f51, 0x27bb089a, 0xb86b8c47, 0x19bc27a4, 0x6a4abd9a,
+ 0xbd06fcc4, 0x618cefe4, 0xc9e69577, 0x4666b9fc, 0x1e7786ed, 0x5f309c96,
+ 0xba486366, 0x4bf1c687, 0xc2dbd40a, 0xb1ab3ebc, 0xf0085a53, 0x3a4e791d,
+ 0xac9c7507, 0x08feb0c5, 0xa0e5d93c, 0xede78564, 0xc425068f, 0x55eadd83,
+ 0xdae22258, 0x52bdfc4b, 0xf57db4f0, 0x864fb2c4, 0x8abdbae1, 0xa59be717,
+ 0xcadf9bf2, 0x2b1f3d70, 0xbd42a9bf, 0xc33d1bf6, 0x9c6f8cfb, 0x8c5a724a,
+ 0xa9a5a87d, 0x973ccf5b, 0x729267f1, 0x9e93f11e, 0x2ce2ddbc, 0xf17dfe00,
+ 0xd6c34b36, 0x47767418, 0x75b3a71e, 0xe2deaa99, 0x73d749eb, 0xeafaa93c,
+ 0x1fa72b1b, 0x4cad6e55, 0xce3ab0e1, 0x24f1ecca, 0x8f5a8637, 0xf98e3dad,
+ 0x19bbd622, 0xfde2b1e6, 0xac2b77cc, 0x21f03788, 0xcc9f34bc, 0xe7d6e9e5,
+ 0x4637e4dd, 0x3e20cfd3, 0x5c9bd100, 0x1dd97486, 0x31ba066a, 0x682a33cd,
+ 0x5bfeda2f, 0x2472848b, 0x284ab593, 0xb5d96d47, 0xe7d46587, 0x1bd8afb2,
+ 0x12be8ec3, 0xa9e7a83f, 0xcf8325da, 0x2abbf9cf, 0x0c0d43b2, 0xe5c9b6e9,
+ 0xa9f9e1b4, 0x6474da74, 0xe22faa78, 0x3a0bd73c, 0x7aad672e, 0xd60ad3e4,
+ 0xeb256549, 0xd63af2a2, 0x5987a54b, 0x99ab2c65, 0xf32d6542, 0xf98d3952,
+ 0xad63aca9, 0x9d64ce54, 0x2eb3d654, 0xa3bfc12a, 0xe4accbd2, 0x7608de87,
+ 0x9973960c, 0x985bca97, 0x482dca9f, 0xfef013df, 0xdbe095a1, 0xbb952759,
+ 0x459dff80, 0x53311f18, 0x39e417b9, 0x3c836f96, 0xf20c32c7, 0xf8c269dc,
+ 0x83ca9b88, 0x43ca8501, 0x0f2a7281, 0xefd43c07, 0xca8ea068, 0x952f01e3,
+ 0x540d0227, 0xd47c0576, 0x316054ef, 0xfc05ef95, 0x581fbe54, 0x8107e54d,
+ 0x12ff9520, 0x91654f58, 0xe20ae411, 0x163ddddb, 0x8f9c9afd, 0xe8271e8d,
+ 0x84f34fa3, 0xfdd1ebff, 0x78f1e2f7, 0x83ba3a8e, 0x94aed5b1, 0x6e6d1e90,
+ 0xe504279d, 0x74937746, 0x4eeb9437, 0x64d63b70, 0xd93b244b, 0x724abed6,
+ 0xa4bbb8c2, 0x9c027d6e, 0x0fbcdeed, 0x4f4198e7, 0x6b65ed54, 0x7f841413,
+ 0xe819a4ff, 0xdfc1ab70, 0x7fda15bb, 0xcebfd2f5, 0xaece8331, 0xc7f53c48,
+ 0xed4c38d7, 0x66b20e93, 0xf207c02b, 0x26993f4e, 0x10a075f1, 0xc7d2fe3e,
+ 0xe3e4d673, 0x791cb93a, 0x368e05d5, 0x5b0f19fa, 0xdb18cfc8, 0x0eac667e,
+ 0x2dab49e0, 0x471fe865, 0xf5b8a3f4, 0xdba2fd50, 0x563ae7d5, 0x1e2337a4,
+ 0xee0a7dd6, 0x65e51389, 0xcf8c58f7, 0xbbab8e45, 0xfe99f9ba, 0xf647f332,
+ 0x5e332e93, 0x54e79151, 0x7403ffde, 0x86df4d1e, 0xaebf1f4b, 0x3598f8a3,
+ 0xf6faf515, 0x7a772e14, 0xdb43e3b3, 0x53dbdd60, 0x9f21bc05, 0x610eb5f6,
+ 0x8dbad7d8, 0x6fc764b9, 0x1d36f38f, 0xd1bff6c1, 0x69a0db29, 0x636fbc7b,
+ 0x14f9c131, 0xea9759af, 0xca5ea377, 0xb1fae049, 0x9c48f1cd, 0xffff8233,
+ 0xe6eee422, 0xadaebeca, 0xd7ad4fe8, 0x6e7802b1, 0x1b05fadb, 0x4bce30dc,
+ 0x022ec09b, 0xc2f27938, 0x9ed0050d, 0x513741bb, 0xae1e642f, 0x0b4da5e3,
+ 0xe128d95f, 0x0b5323b8, 0x213cdc61, 0x7586733f, 0x74095d8f, 0xc6d466de,
+ 0x63f5fa15, 0x8597e73e, 0xd019cc30, 0x5e2239bf, 0x1ac0d5b1, 0x4166f522,
+ 0x35b7973e, 0x4c34bc45, 0xd33cf1e1, 0xe3d0f888, 0x11aaffb0, 0xbe93fe3c,
+ 0x9ff14cd6, 0x9e7fc774, 0xe9ed0e9c, 0x4d053a1d, 0x74b6d95a, 0x9efd018d,
+ 0xf22758db, 0x3f8956e3, 0x76e6cc1f, 0xb92c1832, 0x1efc2273, 0xf2ca37b0,
+ 0xf6a7e223, 0x7184a086, 0x4b11aa8c, 0xa7378c25, 0x3093ee3b, 0xe0de91fe,
+ 0xe8897c93, 0xfda9f927, 0x2b9f22ae, 0x6f67d61f, 0xf735e784, 0x3c0cbeb1,
+ 0x81b79857, 0x566409f2, 0xecdf3916, 0x27878e22, 0xb43d2064, 0x691ad7df,
+ 0x9af8d15d, 0x991eaee5, 0x1ce07c3f, 0xccbfdba3, 0xfdb8e7e7, 0xf9029871,
+ 0x1f8f1260, 0x9339789c, 0x6dd9e5ec, 0x23f41ef1, 0xb2393c4f, 0x2aa7e096,
+ 0x9eff683c, 0x1a62b978, 0x9a9fb396, 0x484efd49, 0x05c630ec, 0xbb753f66,
+ 0x7939f58c, 0xef1c2eb0, 0x71e891b4, 0x89f753f6, 0xc5a91fe7, 0xf05d72f6,
+ 0x2e9fd0ef, 0x012d7e6f, 0x891505e3, 0x7961646f, 0x6abdd742, 0x837fcc3f,
+ 0xd51afd95, 0xda4377b5, 0x3fc1d4df, 0x6b993ce6, 0x378c78c0, 0xf3ce973f,
+ 0xf031e626, 0xf92f077c, 0xba3b95b7, 0x8e8b01de, 0x5bd9d75d, 0x9ebad783,
+ 0x5883d65d, 0x34158756, 0x61ed59a3, 0xa72c41ef, 0xd16bf975, 0xa0fba9bc,
+ 0xdd9620f5, 0xc45e7d23, 0xedffabff, 0x055e3796, 0xab63c478, 0xe68768ac,
+ 0x633dde3f, 0x0d2fc51b, 0x60a1f90c, 0x8f55bf92, 0xa6f66c04, 0xf6787ca2,
+ 0xfa875919, 0x8d6ae4dd, 0x4f74d843, 0x4ce30eae, 0x175a53db, 0xe20bbed3,
+ 0x28f1e219, 0x8ba421e8, 0x2a6f1482, 0x25f013f2, 0x829dc39d, 0x7e294d3e,
+ 0x8bd60a6b, 0x7efe8e7b, 0xd85e1cf1, 0x4e35afdf, 0xa55279a2, 0x08cdc4a0,
+ 0x42ec23b4, 0x7f33b79f, 0x96c3e206, 0xf18adfe8, 0xce2a82ad, 0xd3912cff,
+ 0x996f7605, 0x10508f48, 0x3fd5bd3e, 0xe6c1cf0b, 0xe01bcfeb, 0xb06a0774,
+ 0x25c93edf, 0x367fee98, 0x39061c4b, 0x3fc2eb43, 0x5ba4e78c, 0x51cec9d2,
+ 0x806b6fd7, 0x0eec22f1, 0x968dc7dc, 0xba54e781, 0xf5f620db, 0xe60b2884,
+ 0xf5d4f1f3, 0x7ae7cc6e, 0xd4edd61d, 0x62f47ae1, 0x5d0fb03d, 0xfa227ac4,
+ 0xd7fafed1, 0xd23b14cd, 0x897e6305, 0x4729cc97, 0xcea17fee, 0xd71a3713,
+ 0x615fd6ff, 0xe509295c, 0x67f3ac08, 0x919927fb, 0xf1f7a34f, 0xfb88be42,
+ 0xfe8cbd80, 0xe71f4cc3, 0xbf46e6df, 0x0d94fe84, 0x43bfdc61, 0xd45c60f6,
+ 0x0c926966, 0x39b5fb11, 0xd99e9eb8, 0x728fdfe8, 0x82796665, 0x8b3df482,
+ 0x72b5ae75, 0x0f983efe, 0xfd622beb, 0x7136167f, 0xfe7c4ec0, 0xe24ef799,
+ 0x67583a91, 0xcfea3155, 0xbca5eec7, 0xcc8fcd89, 0xcfeb8c3c, 0x3fb93f74,
+ 0x7ef40615, 0x3e7dce2d, 0x77656f8f, 0x87bc9ac8, 0xc9acbf2c, 0xac58c88b,
+ 0xd07a076d, 0xd95d2ac0, 0xa829d5a5, 0x2509746f, 0x9da06733, 0xf923a492,
+ 0x9a4a720e, 0x8d1ed31b, 0x7f812ba2, 0xcdde7cf5, 0xb373a7cf, 0xb039f859,
+ 0x737cc55e, 0x7aacd8a2, 0x336f304e, 0xd03279b0, 0x3ead737d, 0x8f1fa124,
+ 0xb232f1fd, 0x26f70d97, 0xada73e0e, 0x19cce706, 0xd41fa728, 0x2aaf2959,
+ 0x67a0af0a, 0x94fc99fe, 0x1da8d307, 0xc53365ea, 0xabd6233d, 0xcf6b058f,
+ 0x3bfd4ae3, 0x0cce7858, 0x4cfae0d7, 0xa899dcc7, 0x32973367, 0xf6e8ff3a,
+ 0xe7b547a2, 0x78ef7e4a, 0x50b1a38c, 0xe79c07f8, 0x5af6c74c, 0xcfa3efb4,
+ 0x9cbba555, 0xc2f5b161, 0x2f5c0523, 0xa72824e4, 0x90aec8ea, 0x66f04ec9,
+ 0xfd23c3cb, 0xb9f2efa4, 0x57e5301f, 0xec43d216, 0x1f087363, 0x3f5dc255,
+ 0xa8738629, 0xfba1d3ee, 0x7e3ddec2, 0x5099e9e0, 0x7bf5fd4e, 0xdfa0c74d,
+ 0xe32cefd4, 0xeb377eb0, 0xa081819e, 0xf90361e0, 0x7cbe6b8d, 0x440315a5,
+ 0x414c8dcd, 0xe3ceabbd, 0x6efae028, 0x25e4218f, 0xb32c5af9, 0xd907246d,
+ 0xf4114bc5, 0xe89e9002, 0x6f31b787, 0x91f92b63, 0x8612fcb6, 0xaccd3c79,
+ 0x97d20ef3, 0xe30c8d67, 0x383637af, 0xffb0550d, 0x869d1b1b, 0x219f78f9,
+ 0x23b43ab3, 0xa8506a6e, 0x8546a6fe, 0xfd799bd7, 0xd50f06dc, 0xf0f46dcf,
+ 0x5bd40b7a, 0xd4290f30, 0x6f718015, 0x753aa4b6, 0xe8d01f78, 0x4c17ede5,
+ 0xfc1c7ed4, 0x8c27cc01, 0xbc910b8f, 0xf1d1ed6f, 0x7c7f237b, 0x9ab58248,
+ 0x3b0ecb12, 0xe8f77f11, 0xcc175014, 0x2b332d94, 0x7836cfc0, 0x7f687a43,
+ 0x1032858e, 0x3617bb91, 0x7ea10b79, 0xe2b643b7, 0x7b8376fe, 0xc147f98b,
+ 0x9de132a5, 0xbdde00fe, 0x3af741d8, 0x3efc455b, 0xf14cc4b8, 0x2875b066,
+ 0x6496ccde, 0xb7863b0a, 0x86b02c77, 0x39031ed0, 0x7bd8e748, 0x00764c8f,
+ 0x6ea3c3c8, 0xe6768bb4, 0xca9f182b, 0xb7e5aa5c, 0xaa0b85f4, 0x6646bc68,
+ 0xbebd3f45, 0xbcd78f91, 0xa1d21753, 0x71b9655d, 0xf341d226, 0x3fa0a60e,
+ 0x53c2ecfb, 0xee10c3b5, 0x3f2e1450, 0x79a172b4, 0x9c4753e1, 0xcebf1fb8,
+ 0x79fd405a, 0x5fd9af1c, 0x0d2f5dbd, 0xb79d33f0, 0x0c7e4073, 0x61ca3796,
+ 0x5e63271c, 0xc1f182b5, 0xc627d874, 0xbc8c3bf3, 0x4ca7783e, 0x0be92df7,
+ 0xf475b0e5, 0x0b677f00, 0x1f23a614, 0xd17c9126, 0x9dc8d7f0, 0xc179f85a,
+ 0x32efc0a7, 0x9db82bee, 0xd1673e51, 0x903f6d76, 0x57943a93, 0xfadaedd9,
+ 0xe3fa8b5b, 0x443c1a02, 0xe7e6d9e3, 0x9f7a2f72, 0xc70afb03, 0x74bed115,
+ 0xd7285f7c, 0x72d8bea0, 0x1b8bea80, 0x44e9c565, 0x0a79d779, 0x53b45ff7,
+ 0xeb806166, 0x44cd9617, 0xa4dfaa7a, 0xf5c8f0a3, 0xc2e48bac, 0xc6adf695,
+ 0x19f7a23b, 0xf2efbfbd, 0xa88e5cf5, 0x6613e0f6, 0x1edb07b2, 0x9ef0e8b6,
+ 0x78adec15, 0x55dc2b8c, 0x402c1d54, 0x1dc8407b, 0x973d25c3, 0xa216cd27,
+ 0x51ed8353, 0xa1fc6477, 0x13f55465, 0xd86fd405, 0x6e3c758d, 0x968efb41,
+ 0xe3173f63, 0xe6d6ea4d, 0x13db5de3, 0xa63f951f, 0x729bc7cd, 0x7f2a3321,
+ 0x7f2a2f2c, 0x7da6946c, 0x545c75aa, 0x51b5d8fe, 0x1a3563f9, 0x967b9678,
+ 0xcaf5ffa6, 0x86f81a4d, 0xfd343bf2, 0xd6ee78e7, 0x7754dfb4, 0x66fda6bf,
+ 0x7c0d4aef, 0x6b5fc36b, 0x6be6dffa, 0xb1dfb4d6, 0xf69a27f8, 0x2d49ff68,
+ 0xf9701577, 0x3feed9be, 0xd06c0149, 0x3df791f7, 0x28de996a, 0x7b9e46f7,
+ 0xa7b70252, 0xb9fdfba2, 0x8bfbd380, 0x058f9f12, 0x1c789aed, 0xf135d8f3,
+ 0x854570ba, 0x71c61bb9, 0x21df951a, 0x0ee262dd, 0x6bb6bfbf, 0x3ff6d9ee,
+ 0xbc60fd0e, 0x1b5cc4a6, 0xff8c3bea, 0x37b940fa, 0x5f747487, 0x4abf5b61,
+ 0x69b83d22, 0x5cab8f15, 0xaf3c5230, 0x8eac1d7f, 0xdc46fbc6, 0xeceba96b,
+ 0x2da47110, 0x85424718, 0xfd4199e4, 0x7ef1c656, 0xe3574d3f, 0x371a3e8e,
+ 0xa418dca3, 0x7e85bcfc, 0xcdc0e309, 0x7bc5663e, 0x02cb7493, 0x069bff9a,
+ 0x265d9925, 0xb016da2e, 0x67cc0f33, 0x635c155f, 0x527dbd84, 0xb3d4f7d0,
+ 0xcfddbcf0, 0x5bd31e28, 0x1853edf0, 0xe143e98f, 0x219d7408, 0xf73f3c73,
+ 0x5fcfeec0, 0xe6daf981, 0x5ca197a5, 0x5acf6e8d, 0x43ebf7be, 0x6e7f6997,
+ 0xde1f5bd9, 0x1fe7b97b, 0x25ba75d8, 0x38c87da2, 0xf3264369, 0xe001d044,
+ 0x80fde62c, 0xf9f5c85c, 0xc5230af2, 0xfc01aeb1, 0xbfbe0215, 0x89cff8aa,
+ 0x3fb9e03b, 0x44eefb39, 0x65ea1d3b, 0x847e87ac, 0x9fe53fd7, 0x9c92fca3,
+ 0xa3df6051, 0x9b171dfd, 0x7215c76e, 0x8d6d95ba, 0x6a0718bd, 0xd13a344a,
+ 0xbb32cfcf, 0x07193eca, 0x7ee06d74, 0xfeffb475, 0xddbfbf5c, 0x9177fe49,
+ 0x944b2718, 0x9e7f2b7a, 0x4e4c8399, 0x3114f717, 0x6a4fa1f0, 0x655e5097,
+ 0x8d3f942e, 0x89fd8be4, 0xa4238a46, 0xc1dc445b, 0x171358b2, 0xfb06e350,
+ 0x9095ef13, 0x4bc3d3ee, 0xf18f9e28, 0x5c6f1c02, 0x11d693a1, 0x32c82f1d,
+ 0x86bad3e7, 0xd7f59f1e, 0xe6314827, 0x1a875a89, 0x279e889f, 0xea04f684,
+ 0x64f16599, 0x7bef444f, 0x79556149, 0xd7e470e1, 0x51d393de, 0x90329f7e,
+ 0x5e8a1c3e, 0x143ccf30, 0x42b4fe31, 0xfe63dfee, 0xe63d6478, 0xe3228787,
+ 0xef41ccd9, 0x2a0c102b, 0x7bb18466, 0x77ce1143, 0xc277cf94, 0x1ec9d8a0,
+ 0xfe87b504, 0xd7217d5f, 0x9730d303, 0x19f2386d, 0x81dbcbf7, 0x12dcb1af,
+ 0xd67d92b0, 0xf087fc01, 0x9527010b, 0xca9b80a1, 0xda85016d, 0x09ca07b7,
+ 0x21e0257e, 0x8ea04778, 0x5e02d7ca, 0x6819dfaa, 0x01e7f820, 0x819d951f,
+ 0x46ff54c5, 0x9bf04fc0, 0xbf04d581, 0x0160f685, 0x53d7a9c6, 0x4ad03bb9,
+ 0xed037bed, 0x081dbf04, 0xec0e1951, 0x8103faa0, 0x060f824e, 0x287c1176,
+ 0x70f82610, 0x479530e0, 0x7f545d03, 0xc101f03c, 0xc93ee337, 0x15df58ae,
+ 0x4f8578c0, 0xf77da276, 0x15a16fac, 0x7cfb6bed, 0x79c5159d, 0x04b74fbb,
+ 0x8d1d1ce3, 0xef131efc, 0x040e3123, 0xed086876, 0x67fcfb39, 0xf6a54c8e,
+ 0x19bed4b9, 0xc4a70487, 0xafdb82b6, 0xfa91996c, 0x0a2130d9, 0xda58eb9e,
+ 0xdc03d218, 0xed4f185a, 0xf93215b6, 0xfce9cf6d, 0xeedc8529, 0x336df922,
+ 0xa541fb70, 0x5c853583, 0xe429aede, 0x161f5cf7, 0xca4a73f1, 0x9e47ad8b,
+ 0xa6ed542d, 0x7f7187f5, 0x3fb079f6, 0x55bcef5c, 0xb597bc66, 0x72b3a3dd,
+ 0xcbdf937b, 0xb8bf603a, 0xc50f587e, 0x6e7cd985, 0xade6db2f, 0xe63975a5,
+ 0xd6ed48df, 0xd05347a2, 0xaff76f4f, 0x6deb439a, 0xd9ae2994, 0x82903bee,
+ 0x89cf6cf7, 0xf0db277c, 0x64a86f78, 0x8d9e7af0, 0xe3077f5a, 0xec03837e,
+ 0xec63d7a5, 0x496ed303, 0xc71130cf, 0x331cd47b, 0xe829d78e, 0xfe7121d7,
+ 0xc4ca0f63, 0xb0302f7f, 0x2db9e0fb, 0x5105df60, 0xb6bf540e, 0xbd55e302,
+ 0x289dbe85, 0x8e779f37, 0x9c03203f, 0xcfc7c75a, 0x82bf255d, 0xf79c3476,
+ 0xbf502de7, 0x5e4dbee1, 0x4db0ea5c, 0x6ec835ce, 0xcadff3ed, 0x4397f8c0,
+ 0x5a8f9ed2, 0xf9f62dbe, 0xb78f8782, 0xf14c9565, 0x378adb64, 0xbcf9075d,
+ 0x33ff91bb, 0xc38a3e8b, 0x5cde4c30, 0x86450ea7, 0x35fc9e63, 0xff7717ce,
+ 0xcd423aa6, 0xdf3a8f26, 0x6aef9c58, 0xb1e234f1, 0xc62f9b5a, 0x279286ba,
+ 0xbf239257, 0x81ef1429, 0x942cb164, 0xb819cf23, 0xe49e0adc, 0x052524f6,
+ 0x8f3c1a4d, 0xe6a02f9a, 0x0be7440f, 0x29e05efc, 0xde62c4cb, 0x4fd67ee7,
+ 0xd73a41bf, 0xbd1b3c17, 0x92e36794, 0x35874931, 0x7a12d819, 0xde2aa7ef,
+ 0x3d0626ba, 0x2853e5a8, 0x1fc100c7, 0x2e713216, 0x38f8ea9b, 0x64ce3e3a,
+ 0x2ae082b6, 0x4318358b, 0x33e5ab5e, 0x2b7f9c62, 0x759b74e4, 0x870dcedf,
+ 0x1a8f7cf0, 0x8b6a3728, 0xfd01b42e, 0x3d09e084, 0x7d4cd7c9, 0x2257d6e7,
+ 0x4117f5d6, 0xa18c5b9f, 0x6e87bc62, 0x504af187, 0x94bf22ae, 0xd582fc50,
+ 0x7d5de047, 0x1d843fee, 0x75c5fcf0, 0x3cff7429, 0xda1c6d6f, 0x4ccced47,
+ 0xf83360f4, 0xd046c653, 0x32e90d83, 0x8b387d06, 0xfc0e348c, 0xe226aa59,
+ 0xcbd70cbd, 0x60972835, 0x2616fbdd, 0x99ac3e91, 0x31acdeff, 0xc9f65700,
+ 0x65b2cf94, 0x9cd3cf29, 0xca3aeff4, 0x31fb7913, 0xf75df7ee, 0x9fbd2d50,
+ 0x67ca2194, 0xb283cfd1, 0xc2533d72, 0x0b952e70, 0x99bf142d, 0x133e417c,
+ 0x4851a7e9, 0x17fa3c7a, 0x6d735e3c, 0x0f79acaf, 0xb68f526d, 0x8f54603f,
+ 0xb7464676, 0xef3edeb6, 0x6153d3cd, 0xfca5f69e, 0xbf8bf6e1, 0x7070823b,
+ 0x24e28e95, 0x5064fbea, 0x4df14193, 0xf9819839, 0x8ccc1b9b, 0xbe6db9e4,
+ 0x60f28ad9, 0xc93c7a7f, 0x2cdbf6bf, 0xcbae8764, 0x3b438a6f, 0x556f34d9,
+ 0x8c23960a, 0x3b18adc1, 0x2dd5e6bd, 0x9127d937, 0x55f355bc, 0xec1cac82,
+ 0xdc8dbb81, 0xf73e09c8, 0xe51954f4, 0x9967cf25, 0xa796eaf4, 0xadd8f983,
+ 0xd4e1d695, 0xf9be4cb1, 0xba76f87e, 0xbeb896b7, 0x1da11a70, 0x7ca379e0,
+ 0x7b4115d7, 0x3f705a46, 0x9cb66d36, 0x6b7ca469, 0xf982324c, 0xccfd0b0d,
+ 0x658df588, 0x573e48e6, 0xf2fbe4f9, 0x87c63c7f, 0x0e595f87, 0x2bdc695c,
+ 0x3e417bf1, 0xfca19be7, 0xf210d369, 0x1f8ff554, 0x8bfce029, 0xf57a4b6c,
+ 0x7da6318c, 0xce22abf5, 0x9e46e567, 0x61bb32a7, 0xc3dd1d5a, 0xcc65bb04,
+ 0xdc517be7, 0x27a7b50b, 0x7b713dd2, 0xbde30b2e, 0x8e817041, 0xf8d27bc7,
+ 0xb98ded7f, 0x936a1f14, 0x3cc129fc, 0xb9f097cc, 0x01dafcf0, 0x7f308947,
+ 0xeb970e5b, 0xe2b7e42c, 0xb38c357d, 0xe0fd7238, 0x74b505ef, 0xa61ec8cc,
+ 0x789e85f8, 0x888c69cf, 0x1c5c63b7, 0xcfd117e3, 0xc2d5ee4d, 0xe1682e53,
+ 0xc0d0662a, 0x3c2d6635, 0x3785aad5, 0x7d3b7115, 0x3f5b5dba, 0x1d85a9c3,
+ 0x74e307d9, 0xc2dfcf3c, 0xf049e222, 0x447e5ef7, 0x68dd681c, 0x765f3efe,
+ 0xcb8a52f7, 0x78f0e5b6, 0x3695638f, 0x42c591ce, 0x732fe212, 0xd63c5469,
+ 0x863f66bd, 0xa30bed97, 0x5efc41e3, 0xa9a1f002, 0x7c8a3147, 0x9e68eaf0,
+ 0xd23dde87, 0xce08bdb7, 0x5f0c60b3, 0x4d1dabc7, 0xdac53f74, 0x5caf88d3,
+ 0xb0695f22, 0xe88a7cbe, 0xf90f1d40, 0x7fb11822, 0xf84887e4, 0x37be51a1,
+ 0x8be41e70, 0x2cfea460, 0xfbd036e9, 0xa1be62ab, 0xcfe543f8, 0xa28f7172,
+ 0x89f4dde6, 0x9bbcd4b1, 0x705f2255, 0x4ebe5457, 0x1936a39f, 0xaebee7fd,
+ 0xf8b1f195, 0x682ef910, 0xe5887ce2, 0x837f9106, 0xe22c187c, 0xa6f5887c,
+ 0x637856ef, 0x050b8bd9, 0x63bfdc5d, 0x224f86c9, 0x73acb7f6, 0xbe5e0685,
+ 0x910de1eb, 0xe3f751f9, 0xbf08303f, 0xed7e519e, 0x2f9db152, 0x2bcbff4f,
+ 0x48cd0ccd, 0xcf2807df, 0x319c1596, 0x5ea77bf2, 0x42eb9e23, 0xcc99ff61,
+ 0x2fd1f2b3, 0xf2e211db, 0x37889d6c, 0x33155b34, 0x3b9981c6, 0x50c71355,
+ 0x4b4d11e3, 0xd854b65c, 0x7c7f7247, 0x7ca56bc1, 0x14f9e1dc, 0xf1aa48df,
+ 0x32c6cedc, 0x9c6453d6, 0xdd62066b, 0xc056c18e, 0xd957f9e9, 0xc0c74133,
+ 0xf8174dbe, 0xb0fdc97b, 0x8f2467ec, 0xea68e42e, 0xa39c44db, 0x0b2dbf9f,
+ 0x8b3e70aa, 0xb0fb49db, 0x1e1aff31, 0xd1c6d417, 0xe73de24c, 0x343be3c1,
+ 0x7e226df5, 0xb5f1e572, 0x85d33971, 0x2fc621bc, 0x1adf1a8c, 0x7181fc73,
+ 0xabbdf1b5, 0x714f37b8, 0x2e3a184f, 0xe9cdd236, 0xdfdd9d69, 0x83317185,
+ 0x06667fe0, 0xf288993a, 0xe3e9ff80, 0xc1ae7e79, 0x198f8da1, 0xfa0baf30,
+ 0x98b8973f, 0x3efa8ae4, 0x0599fdb5, 0x27cbca12, 0xa4e8fdf0, 0x5a24f2c1,
+ 0xde44d88e, 0x811cb47c, 0xd37034f9, 0x36cf5cc3, 0xe50f8a4b, 0xfe7ef473,
+ 0x7587f17f, 0xc8bbe389, 0x778eceae, 0x0f632e9a, 0x638205b7, 0xf175b9f1,
+ 0x0778c5fe, 0x918ef77e, 0xe3944f69, 0xf88ceb7b, 0x298ec56c, 0xb60f3173,
+ 0x13ebf04d, 0xa7a23a69, 0xb7d3dbf4, 0x29e823ea, 0xa173e8dd, 0x13ae9c3d,
+ 0x87f85ff9, 0xd227b471, 0x318c6db7, 0xa9d76abf, 0xd601adb0, 0x6d8e7111,
+ 0x9fee9ec2, 0xadcc8eef, 0xd27188fa, 0x34b1be4d, 0xa3fe7f5f, 0x87e5af98,
+ 0xc459b7cd, 0x6cf9d4c3, 0x67f76a77, 0x7f69fa33, 0xd487a136, 0xfee336f9,
+ 0x15d5f062, 0x75fe13e7, 0x69777cff, 0xf93367f7, 0xf5367f69, 0x7cea1b3b,
+ 0x3e6c3f2d, 0x76cfe0bb, 0x3d97def1, 0x64377f9e, 0x9a23f7a8, 0xbdccf3fb,
+ 0xed2f9466, 0xe850bc6a, 0xfa5173bb, 0x3be849ae, 0x6973f9f5, 0x3dff14b9,
+ 0x7326f877, 0xfa873d2c, 0x933b098d, 0x09933b09, 0xd9e1133b, 0x0d57a735,
+ 0xbbfc7a07, 0x95cf371d, 0xbecfaf41, 0x1cf8f4ff, 0xf1d9df80, 0xe832b98b,
+ 0x9eafd9a9, 0x1e0b337e, 0xfbdbfe29, 0xe9f4fc38, 0x5bb4073e, 0xadcccf82,
+ 0x18693805, 0xbaeacfd7, 0xb97779d5, 0x7cb95db9, 0x6f8f1e75, 0x3d459c82,
+ 0x67e39cd6, 0xcafc7f18, 0x1f349bd1, 0xeecf2ffa, 0x03105f4d, 0x7cb96a2f,
+ 0x1e7f2175, 0x9889c0ad, 0xaf48c6cf, 0xc7bea8dd, 0x8f7da752, 0x23692925,
+ 0x2c7187d9, 0x96394564, 0xfbd0f660, 0x7316d797, 0x533370bd, 0xe15fb81a,
+ 0x1c79102c, 0x4dcbdef4, 0x6b5c62e5, 0xfdb12fe5, 0x09e79d66, 0x79ff77f4,
+ 0x68e1bcd2, 0x7379ab3e, 0x3bde06a3, 0xde7dfedd, 0xb1fd9e4f, 0x64e56dc4,
+ 0x36998f1e, 0x7bdfc9ca, 0xa22b888b, 0x3e143c5d, 0xff73753f, 0x1e9f007e,
+ 0x0f54cf8e, 0x37b5a7c7, 0xff9c0d69, 0xf4de94f2, 0xc34f89c7, 0x0835f131,
+ 0xfbf851af, 0x7ea99b93, 0x88ed1ea0, 0xc55be12b, 0xd85f9aab, 0xc80b392c,
+ 0x9a19675e, 0x14c660fc, 0x1e7bac67, 0x3d48cfa4, 0x197bb46b, 0x3486a3da,
+ 0xeff98dc5, 0xc7d17fcd, 0x1573dbcc, 0x525ef88b, 0x367de53c, 0x1fc91927,
+ 0x93349fdf, 0xb659fc61, 0xd4bc234c, 0x3e51d526, 0xeb187ea6, 0x3a357f44,
+ 0x7c9f5d0f, 0xe909e53b, 0x4061e86d, 0xecc79fd9, 0xe95f2331, 0x5d92563f,
+ 0x99570048, 0x295f2e87, 0x26753d0f, 0x324f43cf, 0xd85e313a, 0x998c689e,
+ 0x9badfe87, 0x71fb5dfb, 0x1fb8697f, 0x886eff23, 0xe56c97d8, 0x9f58eef7,
+ 0xab46f500, 0x5dfc518f, 0x615bffec, 0x4dfda907, 0xf9433f56, 0x4e2a37a0,
+ 0xa9f45fb4, 0x77e07f5c, 0xe231dc5b, 0x0dbb5f28, 0xa3fdfcf4, 0x99cf5cac,
+ 0xfb3eddb9, 0x27dfb137, 0x44962b28, 0xdd3624bc, 0x3737450d, 0x9dde78ea,
+ 0x2d7397ca, 0x9c07ca46, 0xf7d3b16b, 0x2102e66c, 0xf446a4f6, 0xfe56eebf,
+ 0xd8acb53e, 0x7b7e9e91, 0xfe5f94ed, 0x00b5e196, 0x66a7db97, 0xc2bde818,
+ 0x28f31253, 0x5df383a9, 0xa994debd, 0xea1bccb8, 0x7645af4f, 0xc8c3182c,
+ 0xc1757a4e, 0x4e95ad43, 0x8aea8ff2, 0x737d9e91, 0x770fa2a6, 0x77d8c363,
+ 0x04f2ffb1, 0xfbd5cf2e, 0xfc09e5a5, 0x646bde7d, 0xffec6cdf, 0x4917c555,
+ 0x725f48d5, 0x2bae0e6f, 0x33dd3fa2, 0x5b9ff445, 0xcffa813c, 0xf5ddafe6,
+ 0xce3977d2, 0xc8f99da5, 0xec7ce8c7, 0xf429ecb1, 0xbde458b7, 0xe81f9086,
+ 0xa3d64577, 0xce22c5bf, 0x6e505a53, 0x4f218eeb, 0x3ec332d4, 0xa042e46e,
+ 0xb18c8cd7, 0xcff5aa54, 0xa175f47a, 0x90fce718, 0xec1fe738, 0x6ac3b4f7,
+ 0x3df80e27, 0x843cefe0, 0xe172f8f8, 0xb0f1f4a9, 0xbf6a07a5, 0x6ec7bf26,
+ 0x16ceffec, 0xb00371f9, 0x2db3bef6, 0xdf8c5bd0, 0x87886019, 0x8bf91189,
+ 0x25f6bf62, 0xefd0526b, 0x20f4b381, 0xbc0476dd, 0x030d6b23, 0xe42cbfcf,
+ 0xd2160b08, 0x2eb106f3, 0x0ceb5a47, 0x2c38bb8c, 0x6073ca3a, 0x6791aacc,
+ 0xa6536a73, 0xbb0ba1a6, 0x2716299c, 0xe45df7fa, 0xfbe06417, 0x7c9f180d,
+ 0xf78636e7, 0x9d69595f, 0xfd75da12, 0xc6f788f3, 0xe17b8957, 0xed2d5f3e,
+ 0xefd6c327, 0x5ff23197, 0x507382d3, 0xc33df56e, 0x92f19457, 0xc691ddb6,
+ 0x5dee1ff3, 0x02721f18, 0xed2d67bd, 0xb04f4fc2, 0x30f8700c, 0xa9719fa6,
+ 0x7282d5d9, 0x140957e6, 0xe7b7d677, 0xfbc820b3, 0x1bfbecb0, 0xf9c877c2,
+ 0x6c4f2e90, 0xb65b9e16, 0xb9ec9e28, 0x0675a976, 0xe8f731f9, 0xd178ac58,
+ 0xa7ee62ce, 0x2b628ffc, 0x4fb5cfbf, 0x1f63f4e4, 0xb8e1723f, 0x77ffe7ab,
+ 0x49f99e84, 0x7fde93b2, 0x4da3ed52, 0x8e47f843, 0x5f213a91, 0xf8115e84,
+ 0x199f3333, 0x792f45f9, 0xc774b079, 0x96bdaf6b, 0x5b53e8ce, 0x841b4748,
+ 0x138ea3fd, 0xc6a21f9f, 0xf243c578, 0xb87ab252, 0xedfab0be, 0x75af3841,
+ 0xce63e9df, 0xfba085ff, 0xd90fd935, 0xd3ad7fb1, 0xfa32c6e7, 0x9c96983d,
+ 0x3e78dd7b, 0xe9fb332d, 0x96baec95, 0x61dfce33, 0x28f0563e, 0x9fd837cf,
+ 0xefc3685d, 0x1b0e5941, 0xe265d364, 0x27d046f1, 0x19d8cbce, 0xdeaf9146,
+ 0x99e78072, 0xbaca58b6, 0xc5a1af30, 0x6a465692, 0x56f3c2d8, 0xcb16fed5,
+ 0x1607d221, 0x5adfdf85, 0xb8487f50, 0x0947c04c, 0xe110ebae, 0x5077ed43,
+ 0x128b5dc8, 0x5a5ef866, 0xfd4ad29c, 0x83d7b2cc, 0x34e6ca79, 0x6644f746,
+ 0xe217f02b, 0xccc75f35, 0xbec9f431, 0x5a4fae62, 0xaabaca4a, 0x7e327d69,
+ 0xd8b58eb9, 0xe7a4eccb, 0x7cf0ef11, 0xcf968673, 0x577813bf, 0xf91669c7,
+ 0x4eae77b4, 0xc38ed609, 0x1bf79338, 0xcb16e7a4, 0xf5107302, 0xcbf8e25a,
+ 0x391a678e, 0xd7fb78d4, 0x43bef18a, 0x2c4fae79, 0x0678e2b3, 0x8d15f7c6,
+ 0x9c62e1f7, 0x7bfbd5ff, 0x47bd2cc0, 0x581d304d, 0x7deb1ed8, 0x13f3feac,
+ 0xcfd1f2f7, 0xbc7960fd, 0x02871b56, 0x091eec79, 0x72565afb, 0xd53550e6,
+ 0x0bd3f8f0, 0xfd519fc2, 0xf6317492, 0xbf7f120b, 0x2bc5283f, 0xe10c5df4,
+ 0x69c7a4a7, 0x3ef030f1, 0x6f873f2d, 0xde1e781a, 0x7c4c6937, 0xd7cb4e87,
+ 0x38ff1cdf, 0x059f9345, 0x7131ec7c, 0xde23c63f, 0x3888f5a7, 0x6f18c21d,
+ 0x049d17a0, 0x89c7f7ff, 0xc33f9c1b, 0x4099acef, 0x5c60eb8e, 0xfa27e1c9,
+ 0x5dba3936, 0xe239efc8, 0x78d10ffb, 0x2e48c9fe, 0x7a47a5af, 0x51af785c,
+ 0x119bd69b, 0x7c5fdf8b, 0xee0642f8, 0xfd19c5e7, 0xdf743b79, 0xe769e2f4,
+ 0xcbc402e6, 0x6ffbed11, 0x474df8ea, 0x22f8a7ce, 0xe5c0a5fd, 0x3a4b2fdf,
+ 0xd92571b3, 0xddb80b8d, 0x7dfa7ff8, 0x73e617b3, 0xa497753b, 0x084fcf95,
+ 0xfc141cb9, 0xd320bb60, 0x2aee43f7, 0x3a40adf2, 0x0bac936a, 0x3ce72e50,
+ 0x9af2f3cc, 0xb3d55b1e, 0xb47f0628, 0xd5fdf28c, 0xbabf08c8, 0xe491bd7c,
+ 0x3725b35e, 0x28f772f9, 0x9fbb9f43, 0xde7a94e4, 0x79988f55, 0xdb8f8abe,
+ 0x7bbee9d1, 0x3a260f29, 0x7ea8653f, 0x449d23d5, 0x137f6a0f, 0xc5f28f8e,
+ 0x15c52372, 0x818fa1ce, 0xb72b3b71, 0x59d7a233, 0xc098c889, 0x7d0663f1,
+ 0x49607499, 0x106b8e1c, 0x6a0bdcfe, 0xcca1a45c, 0xde7889ec, 0xb9995b70,
+ 0x9a4e823a, 0x8e0fcf19, 0x2337ff1e, 0xac22fb55, 0xa80c63b1, 0x94c6317f,
+ 0x97ed9f26, 0xf278643b, 0x0395b4fc, 0x0ee3cc7c, 0xc5a3e743, 0x232dbe71,
+ 0xf30dac7b, 0x5e0ec0d2, 0x0460b0d3, 0xf64db7e2, 0x3c0368bd, 0xa2687ef4,
+ 0x0bdfea3c, 0x7c16ed3e, 0x05f9d43a, 0xd23001d9, 0x1d9c7b18, 0x80e297c4,
+ 0x2327c64e, 0xebe7345f, 0xf63142ea, 0xf3ec5c79, 0x7878f632, 0xc7b3f7e4,
+ 0x1afe890f, 0x6ded1c7b, 0x46fdd44f, 0xb6768c24, 0x7e3d8627, 0x05f11242,
+ 0xc2742791, 0x0dd5dce0, 0x39313978, 0x5697be99, 0x5defc090, 0x527fa04e,
+ 0xabc87e06, 0x7ed1f3a7, 0x7ff52d99, 0x43f84917, 0x47f0608c, 0x62f905fe,
+ 0xb6bff30e, 0xe23e2248, 0x1b7835f7, 0x73e57e9f, 0xd19236de, 0xf9c036ba,
+ 0xdb46fde1, 0x6233f9c5, 0x8ea467dd, 0x5037fd52, 0x13ef1165, 0x889d3c33,
+ 0xf741acfb, 0x72f75174, 0x9fd36d78, 0xdc1fac77, 0xed7286ff, 0x8b86d9bd,
+ 0x5a622e3c, 0x4b8f42c2, 0x6daa9798, 0x10cea9bf, 0xb9a82f7d, 0x6bd9bb4f,
+ 0x7d0f5e88, 0xd621d417, 0x1f71dd9b, 0xcd4fbfdd, 0xa644f9e6, 0x04e28c65,
+ 0xa66df7d1, 0x3d1e5db1, 0x8c0dcfda, 0x38e8fdec, 0x52a9e639, 0xb181b0fc,
+ 0x79e5122d, 0x7973df6b, 0xfe73fea6, 0x3ad6947d, 0x760ec79c, 0xd1d3da10,
+ 0xf7a849ef, 0x51f7ea5a, 0xdfab3c55, 0x4dbf4a8f, 0xc163eb47, 0xc6aed429,
+ 0xb87bf1fd, 0xf911e955, 0x7f582be4, 0x2b7f7a7f, 0x9bdf7b18, 0xcf29eadb,
+ 0x7fbc7320, 0xb29a186c, 0xc8784614, 0x6fc8c85a, 0xf2683c00, 0xdbd94c09,
+ 0x16e79f69, 0x224c3633, 0x33da683c, 0xfdd3d340, 0x7e6d42c0, 0x0353ec01,
+ 0x57abfb47, 0xd94d53f2, 0xf39597f9, 0x9a638a57, 0x94e4bdc4, 0x97fbe251,
+ 0xed14aca5, 0x9edbf4a2, 0x0738f3a1, 0x5f7181e7, 0xdd629c74, 0xf1826e3b,
+ 0x77fc8fd1, 0xe2cd2fc1, 0xaefd5b6e, 0xf4c8f30f, 0xce549b1e, 0xf30d2cd7,
+ 0x12e97bf2, 0x8a6e7c46, 0x8fcc6667, 0x1e4c2a97, 0x04c9bbc4, 0x32596c30,
+ 0xd4067332, 0x7b3c45eb, 0x8464c48d, 0xf3315599, 0x5dfaa3f8, 0x577d10a1,
+ 0xd479a868, 0x20b22bef, 0x679d4e7f, 0x2ef577d0, 0x7bf93cf3, 0x6be7e8d6,
+ 0xcea99e29, 0x87fe143f, 0xbfde8efa, 0x8137bcd5, 0x441d53c7, 0xf4038daf,
+ 0x417cf04a, 0xca3cf88f, 0x66d5bb85, 0xfa29577b, 0x4c1e670f, 0x114a3650,
+ 0xd2ce08fb, 0x7e03eff3, 0xd7faf1bf, 0xbc927761, 0x1897dfef, 0x8beefbef,
+ 0xdae422fe, 0x09597c3a, 0x191a5ef3, 0xfba431e5, 0x29973faa, 0xa0f600ff,
+ 0xdf111391, 0xd6f18049, 0x1fefce3d, 0x3e77e336, 0xc0e7fef0, 0x13edfe40,
+ 0xd1f76c16, 0xbcd43677, 0x5da3cc5c, 0x3ef0325b, 0x837df472, 0x89c611bd,
+ 0x99b26f98, 0x9f401305, 0x0531f4a4, 0xb9ecf3bf, 0x03a65468, 0xa07d6c7e,
+ 0x93bf0150, 0xa5ee8999, 0x337ead2a, 0x0ae10eff, 0xef676916, 0xefa56e97,
+ 0x64bf86bd, 0x3e14bf94, 0xc3ee88cf, 0x70c4c39f, 0xddf8ff2e, 0xcbe47afb,
+ 0x7a5d7da9, 0xfb93f3d4, 0xf67fa4fc, 0xed3d4fd9, 0x9962e7e2, 0x751f9111,
+ 0xcf545b1d, 0x979f8ae9, 0x5f27ea2c, 0xfdf86a30, 0x46a35eda, 0x5b17c81e,
+ 0x65fd46be, 0x67aa89ea, 0xe3e33fd3, 0x2dde28f9, 0x53edb5db, 0xdbd03e44,
+ 0xc35fdf2a, 0xbc73a1ae, 0xcf331698, 0xd5dce06e, 0x71e26e73, 0x79c7c674,
+ 0x9ff7946e, 0xff404d46, 0xe87147c0, 0xd82fc464, 0xdd952917, 0x58798ecc,
+ 0x8e994ce5, 0xf3b2bd72, 0xe487a41d, 0x3c0f3cb3, 0x5ffdfc7a, 0x7e8595be,
+ 0x9dc99ec3, 0xed2f6859, 0x3d15f2f9, 0xd3d5578e, 0x193eb0cb, 0x58a41e4a,
+ 0x10aa784c, 0xcf5033b4, 0xf59144e3, 0xe74a9eb4, 0xcfe4e565, 0x871a4e50,
+ 0xd933df6e, 0x87e4c2c2, 0x3da02675, 0xfe7c7cc7, 0x57cab364, 0x70972fec,
+ 0x9f81845e, 0x52ea54f6, 0x7b9f616a, 0x6c15919e, 0x46f3d3dc, 0xe7bfce02,
+ 0x7acd39ec, 0xf322fe98, 0x5afbac45, 0x2b53ee71, 0x7efec97b, 0xf92bac4a,
+ 0xa1c52f6c, 0x30de9553, 0xc3d4dbea, 0x37fefa7a, 0xc8bcf0b3, 0x38a14c61,
+ 0xfc5eba9a, 0xd73e2a6e, 0x88de7282, 0x5632b3fb, 0x287eec28, 0x55832a33,
+ 0xcc9a8f98, 0x6b484a76, 0x417d2b53, 0xa5e4e7a4, 0xad939e9c, 0xbf18c3fe,
+ 0xa3af5e4f, 0x59f24538, 0xcbf406df, 0x0565cb92, 0xf84ae4c9, 0xb7f310ec,
+ 0xf9d4f98a, 0xa88cf5d5, 0x7ee84bf4, 0x62e3b324, 0x132aaefe, 0xcc5abf8e,
+ 0x59eb14ef, 0x2c3be8c5, 0x55ad67c9, 0x83272fe8, 0x33df419d, 0x9a79e2b8,
+ 0xb745f335, 0x99d94f27, 0xb1e0e745, 0xe30ad91e, 0x365b64a5, 0xceb94154,
+ 0x32ff23a1, 0x3c5187a9, 0x9d27a93d, 0x4f527de4, 0x8a2728a1, 0x0f4269fa,
+ 0xd4933970, 0xaf2d50f3, 0xa4d2a16f, 0x3f8717ca, 0xda98fb8c, 0x717cb8cb,
+ 0x98be4978, 0x517cb8d2, 0x9556b8e9, 0x325acc2b, 0x0ff7ea1f, 0x06b5acff,
+ 0x73f77b9e, 0xbbe5fefe, 0xbcbe5cd9, 0xfbf725fb, 0xd3bf694d, 0x42aa5ca3,
+ 0x4dfa05c3, 0x33edc0bb, 0xbaab1f95, 0x48113625, 0xe7839a63, 0xc8ba1f87,
+ 0xd9843b9f, 0x63af00d5, 0x9529c912, 0xdd056b6e, 0x83eab3ae, 0x81fed849,
+ 0x3477de89, 0x98e5ce39, 0x83fe1ec1, 0x7c41f7ae, 0x33f7f8ef, 0x415def7a,
+ 0x437e82f5, 0x9a2e494b, 0xe4396c84, 0x3e416058, 0xae487984, 0xe918721e,
+ 0x3a080ebc, 0xe9af673e, 0x5b3fc308, 0x69fcdfcc, 0xc1ffd43e, 0x9340eb9e,
+ 0x1e973d4c, 0x885f2f41, 0xe82b3bf3, 0x7bdd29a6, 0xfc04c953, 0xcd1e62fe,
+ 0x0dfece7b, 0xdcb27fbd, 0xc69f1ff6, 0x3aa72efa, 0x4f7cfa8e, 0xcf19a568,
+ 0x1f9bd0f5, 0xabb4409f, 0x7b235fe3, 0x7ee3e4ef, 0xd0f89a33, 0x78cf3b12,
+ 0xadf3fc90, 0x8b7f9688, 0xc80f864a, 0x91667abf, 0xe7121e79, 0x1e4259eb,
+ 0xddb8554d, 0xe7e56f5e, 0x5fb25f55, 0x8b8afea6, 0xd2af55f6, 0x5ae4f28d,
+ 0xf29b7fe4, 0x7d4bd124, 0xbd97a73e, 0x0a0f9e82, 0x63ecce7c, 0xed97e89d,
+ 0x196e982f, 0xe23ef80b, 0x1cff13d2, 0x52c6bb19, 0x291dcf06, 0x024bf095,
+ 0xd6c97a6c, 0xcf00a9b5, 0xa7a22452, 0x1dad92fa, 0x967fd04d, 0x03a94135,
+ 0xb3f9e8f8, 0x0eaf3416, 0x9784bc05, 0xe3f872e9, 0x1b9e1754, 0xcaccd3c7,
+ 0x4ffe8cb0, 0x8cbf63bd, 0xc46df6fa, 0x2ee311ab, 0x7567c11e, 0x6a571f04,
+ 0x238fb82c, 0x2f2126a5, 0x5e51e33d, 0xd537cace, 0x7c75a18f, 0x1a4c6c7d,
+ 0x506f77be, 0xa73c95f8, 0x7e82c9ff, 0x6b27ccea, 0xccdfa053, 0xd7196692,
+ 0x912cd47b, 0xd7da3cfc, 0xc793f944, 0xd2ac393b, 0x74073d2d, 0x5b6fbc79,
+ 0x6fb61273, 0xd53e4897, 0xe21d2f2b, 0xa7d38fea, 0x0b0f7e3a, 0x3077e1b6,
+ 0xb7af29cf, 0xb1f53e60, 0xcccf05be, 0x7f1c3c01, 0xb8c43f53, 0xc0ad1f4d,
+ 0x244cdf71, 0x356d9e3a, 0x8cb1f469, 0x5e84694e, 0xd36f1ead, 0x0d4af5c0,
+ 0x29cfd3c5, 0x7806e592, 0xad5df3de, 0xd191397b, 0xbd77da52, 0xe14c7be8,
+ 0xa1cc797c, 0xd63cbe23, 0x8a9cb8f7, 0xfb4659f0, 0xde769991, 0xb21a92fa,
+ 0x5b29ceaf, 0x826744f5, 0x54f1d50f, 0x4f8a3e3a, 0x9ced1e23, 0x6df68fff,
+ 0x1dbd20b3, 0xe323bf75, 0x89675d39, 0xa1d0571a, 0x5df0dfaa, 0xda9fa471,
+ 0x7ef3fb51, 0x3851eb86, 0xd7946bfe, 0xd57d238f, 0xa7a2643b, 0x9afecaa3,
+ 0x27bf8614, 0xffecd262, 0x9ac91dfe, 0xda7597f1, 0x5db47034, 0xdbfdcfb5,
+ 0x0ec4cba7, 0xd847a466, 0x3ec2f947, 0xe0771fd2, 0x1768aefa, 0xf7e8eb29,
+ 0x45d90649, 0x8a2edcf9, 0xbe5487b6, 0xb889d66e, 0x65c78eac, 0x58dff9a3,
+ 0xf1eec3fa, 0x8e492ad8, 0xc65bbfbc, 0xbe9073ba, 0x8612a3e6, 0x75d01ef1,
+ 0x15fc23a7, 0x078b6deb, 0xccad7c39, 0xbfbf6976, 0x3f37bfca, 0x1e77d4be,
+ 0x367495e5, 0x6561df4c, 0x07e518ab, 0x9e786be8, 0xad665e11, 0x258bd488,
+ 0x8d2df1fd, 0xd84ba45d, 0xac78859b, 0xf1e46b38, 0x38e89e8f, 0x851fea97,
+ 0xae2bf225, 0x93ea2e52, 0xe67bb8f9, 0x7f6778f0, 0x938f3379, 0xe5fc0915,
+ 0x5d691a94, 0xdcf7808a, 0xb59efb16, 0x41fa54a4, 0x07dfa2f9, 0xef8029df,
+ 0x61e690af, 0xb1553d9e, 0xca5291d7, 0x9777b5e3, 0xa14af278, 0x15f12a2c,
+ 0x3d5e2296, 0x77d35f60, 0x9f643dc5, 0x33bce3a9, 0xfd16e3ca, 0xbcc96146,
+ 0xee8f0edc, 0x6863ed07, 0xe3d8869c, 0x7a38fb40, 0xf6ec6e7e, 0xfc39b843,
+ 0x30fb237d, 0x0c0643d2, 0x52f2a664, 0x16e5e32a, 0x8846aefa, 0x1e0de7fb,
+ 0x9146f3d2, 0x103788af, 0xf4c7fc91, 0x1cbe34f5, 0x58f7419e, 0x8325d82d,
+ 0x7691f9fb, 0x6a84ac94, 0x6aade322, 0xdf94a8b9, 0x1528ce73, 0x604cf3ef,
+ 0xa8afc813, 0xea3cfcbc, 0xc3cd43f3, 0xc85765ec, 0x63f35e7b, 0xc3fa49d3,
+ 0xa55f27e4, 0x4a0e607d, 0x1f39df91, 0x4a89bf6a, 0xc28a1c94, 0x5cf350d3,
+ 0x22dc79ed, 0xd76af6e8, 0xcc7a655d, 0x2ed1f94e, 0x056b07ce, 0xd5dbf57d,
+ 0xbe3f1e3f, 0xfe861f3f, 0xfefbd9ca, 0x4a7ef893, 0x37a56842, 0x145e7ec6,
+ 0xe531f9fb, 0xce70d3c1, 0xfba18c1b, 0x0799ded1, 0xd20263a7, 0xf1f2c77b,
+ 0x9eb005f0, 0x2dfcc537, 0x6feb9596, 0x1c5b4785, 0x1ef998ba, 0x7a78fe6f,
+ 0xd93f0da2, 0xdce395ff, 0xa7206dfb, 0xd07d1e5b, 0x7581b0ac, 0x15d96b30,
+ 0xe347f9ce, 0x6d5d7513, 0x625e305b, 0xf7aabd4d, 0xaf5c5a14, 0x697de024,
+ 0x764de7ed, 0xb4460efc, 0x43c6a03d, 0xc6a5bd54, 0xa4bb544d, 0x1fe3c1c2,
+ 0x7bfced33, 0x69f6153d, 0xb20fdfa4, 0xaff21aae, 0x226d3b30, 0x19fd0ab1,
+ 0xe4fb5add, 0x4657bf3a, 0x9eda2a3b, 0x45334da8, 0x7abd07d9, 0x1715df94,
+ 0xfe54fdb5, 0xc454acf8, 0x17795451, 0xcf9a4765, 0xbb40499f, 0x670bedeb,
+ 0x8d142e28, 0x5c2eeb9f, 0xaebd9fde, 0x83f74f5d, 0xb7ad71d1, 0xfdd2e42f,
+ 0x1baf11a0, 0xcccad4c1, 0x808cc43f, 0x6b7b4c97, 0x18ec1195, 0xf82983a3,
+ 0x58fc36dd, 0x8d0dc633, 0x7c9c7817, 0xd7fb9d84, 0x2fc18b89, 0x95335185,
+ 0x78c17da0, 0xef48ce7c, 0xef5d99d3, 0x09bdbd91, 0x9e2186ea, 0xa6199ec7,
+ 0x5307118b, 0xc08a63cf, 0xb7e66eef, 0x4d81efe3, 0xf7f78bb1, 0x59db462e,
+ 0xa22d3cfc, 0x2d62e27f, 0x3ce22d3e, 0x435b8327, 0xd3ec79df, 0xe7116f3e,
+ 0xfb1a596b, 0x63a3ec1c, 0x7aa2439f, 0xc5b6130e, 0x596c39e1, 0x758a4dbc,
+ 0x2f8b990e, 0x845b0e7f, 0xefd2a95f, 0xb204acb4, 0xe8a6f7af, 0x7b41fbe8,
+ 0xcb59c313, 0xb2fdfe31, 0xaccfde99, 0xb4367110, 0x6b9f10a4, 0x84bf97b7,
+ 0xa371db71, 0x7b8e74f5, 0xbcffd125, 0x60feff8e, 0x1fea78cf, 0xf883b327,
+ 0xfb0780bb, 0x1bbbe9aa, 0xd3bbfcd1, 0x33dd007a, 0x3db9ceb6, 0x839c016b,
+ 0x9980fb25, 0xcf839bfb, 0x4a3fef07, 0x7b4bbe05, 0xa654b9f8, 0xbda3d49d,
+ 0xec66f25e, 0x8fe351f3, 0x3a9da47b, 0xaa362b20, 0x98fc8baf, 0xeca33b91,
+ 0x642db3e9, 0x47c65b67, 0x39c0f7d5, 0x9f8ebdd1, 0xa1d916ec, 0x87ebaf3d,
+ 0x114aa738, 0x7d7f3087, 0xfb65e28a, 0x7e714efa, 0x25c6d1e9, 0xfe5df727,
+ 0xe7135e9c, 0xa1c453b4, 0x00e22e7e, 0x7e7fc29d, 0xf2a4e023, 0xea9b80cd,
+ 0x04280adf, 0x0b940aef, 0x77cfc161, 0x47cb3e56, 0x84aaaf17, 0xcf47edfb,
+ 0x7f7dbf73, 0xbe83a862, 0x42de74ef, 0xbda417df, 0xdbbf144d, 0x2c727c07,
+ 0x1fbf49ce, 0x4cdb3478, 0xa5a3b3f1, 0x8a7bfbbf, 0xd16b7cbb, 0xc70bb8f1,
+ 0xeb4e7ab3, 0x6f184e70, 0xee8b855d, 0x47e036a5, 0xeeffa114, 0xffbe8932,
+ 0x040e1b34, 0x3a5445ef, 0xf169f537, 0x65ff0f59, 0x1ddff195, 0x617f42c8,
+ 0xa4e88b8c, 0x2273ef42, 0x4fba373e, 0x571e5f91, 0x871beed8, 0x7af18071,
+ 0x14fbbe26, 0x3bac4534, 0xe0426f0e, 0x44895379, 0x0a1a73df, 0x86e5d1bf,
+ 0xa32fae54, 0x3475ffeb, 0xdd1b83d7, 0x773ce8db, 0x50b2ba3b, 0xf913efaf,
+ 0x2964b310, 0x285fbf48, 0x1cb1dd77, 0x65915bf6, 0xc011bb1f, 0x6853a32d,
+ 0x4f4afbfd, 0xd8f81c53, 0x21c65785, 0x76b31dfd, 0x79ce305a, 0x53dfc9cc,
+ 0xf9951387, 0xf29db77b, 0xa4f2312d, 0xe958f2d5, 0x95fdfa22, 0xef7cfc7f,
+ 0xdf7cd1da, 0x0af5524c, 0xfb815b8c, 0xdef9424d, 0xc3f902b2, 0xfc83b998,
+ 0xaa73e8cc, 0x88b35f70, 0xfc64f3de, 0xb6bf4f7b, 0x3f782c86, 0x0267ed1c,
+ 0xff426c7d, 0x3d04f778, 0x5eadaf7d, 0xe782e7e6, 0x1fa4e788, 0x997e13a3,
+ 0x65667c76, 0xc0fa633e, 0xde1d6079, 0xf13ad0d7, 0xadefaa3e, 0xf86292bf,
+ 0xc9d683b5, 0xf9589efc, 0xcdcfd1b0, 0x9a20b276, 0x1615b386, 0x709fa176,
+ 0x99c69f30, 0xcce3e56d, 0x9b7c7112, 0x1759ffa0, 0x81df9475, 0xcf80d6f4,
+ 0x7927cc95, 0x50f5cc72, 0xb7ac1d57, 0x41c6ce1e, 0x569346fe, 0x5b39090e,
+ 0xf745525f, 0x07dcc7bd, 0xbfbea3c6, 0xe1e574be, 0x9fc22732, 0xb74154d4,
+ 0xd52fa529, 0x945a5d20, 0x4c2f8a2e, 0x5d74cb76, 0x36b97d78, 0x17afd14e,
+ 0xb44bf4a3, 0x928fa8be, 0x54f7113b, 0xf9c4434e, 0x4b9f72cf, 0xab83a488,
+ 0x2f1ccbc7, 0xd67baf7e, 0x1da71e05, 0xe9f7978c, 0x7803a573, 0xd8ef3e89,
+ 0xa73e8978, 0xeaad3c01, 0x8c1dcbaa, 0xbf6f155f, 0x1ac9792e, 0x8d1be799,
+ 0xaf8a1fb7, 0x4156d1e6, 0x579e5caf, 0x3b7dbe08, 0xb771443b, 0xeff94bb7,
+ 0xff731d4b, 0xb3bfe296, 0x0d63a858, 0xcbe045ca, 0xe8f94239, 0x344ce423,
+ 0xf4f8061e, 0xbf2e283f, 0x28b7f3fb, 0x21caaa2e, 0xea25f213, 0xea1fc113,
+ 0x1f9099b9, 0xf02f6f91, 0x2d5e87ef, 0x457ca87f, 0x383f21eb, 0x1fcc8fa4,
+ 0x5fc5dffc, 0x18cd717b, 0x52167617, 0xd1cab83c, 0xac7bc7a5, 0x3dd250c9,
+ 0xd27f8892, 0xf5919c3a, 0x591c6e3c, 0xa12f714f, 0xa6b8d4f7, 0xbb3ebeda,
+ 0x5518412b, 0xc24d47a4, 0xc4fd51de, 0x64538e7d, 0x54faaa7f, 0x57fef716,
+ 0x08f74fab, 0xfb543a7d, 0x79bb73de, 0x43cbe7dc, 0x1c800f3d, 0xa46f9c9f,
+ 0x0e4cb8ef, 0xa3dfcc3f, 0xfe498470, 0x9137746f, 0x69fb0c1f, 0xe604a346,
+ 0xf3e64475, 0xf3bee5a9, 0xefd60a6d, 0x0af4bb95, 0x16ff07f5, 0x568603e0,
+ 0x0d869dfa, 0x137d738f, 0xd651f457, 0xba83dee5, 0xe6994fb3, 0x61efc24a,
+ 0xdf835f6f, 0x8c2a0b01, 0xb598ebbe, 0xee458bb4, 0xdc31a5f7, 0xff9c9daf,
+ 0x68071dd6, 0x69ea1fdd, 0x035768dd, 0x9d964f9d, 0xcfe7050e, 0xfd23dbf6,
+ 0xf7d97dec, 0xb7009dda, 0x086c697c, 0xa3c37ad1, 0xecf3017e, 0x078d5733,
+ 0x73ed8d4b, 0x0bf5181f, 0x7346c7c0, 0xa3cc04d5, 0xdbdfb6ac, 0xdae51f3e,
+ 0x60265bd9, 0xbcec1bfc, 0x83b7d456, 0xcdb7dff6, 0x5d3bbf8c, 0xd69f78ed,
+ 0xabafa231, 0x5abfbf06, 0x48f7e0ed, 0x87bed1be, 0x7b404cc6, 0x73c1ec39,
+ 0x0c9f344f, 0x164cdd22, 0x2f1765eb, 0xbd41fc51, 0x9e73d997, 0xf8ff47d3,
+ 0x8fb80f40, 0x455cbf6b, 0x7db922f7, 0xa026f9ba, 0x3c7d75d5, 0xf1db0c7f,
+ 0xbf58e07b, 0x001d8628, 0x4be75cf3, 0xcaebf3c6, 0xde8637ba, 0x36fbedcd,
+ 0xf6e783e0, 0x44bc7064, 0xc31e6fb7, 0xafb882ed, 0x9272cfde, 0x7ff5c03d,
+ 0xf312c0b0, 0xa9b7553b, 0x3b1ad2fa, 0x552d450f, 0x23daa579, 0x21b35f80,
+ 0xc69bbf02, 0x7cfdff70, 0xf103a7a9, 0x7fe77df7, 0xe50b710a, 0xf6cf52f1,
+ 0xae91c331, 0x97ad5f04, 0xee01c663, 0xc5a3f31c, 0x13416e2b, 0x73beabef,
+ 0x86e96fe9, 0x7441dba6, 0xf8e95065, 0xffe3a221, 0xe27bf48b, 0x20efd0fb,
+ 0x14fe7479, 0xd347c3dd, 0x03bf4ab1, 0x9be6c874, 0x79e80692, 0x7ec1ba28,
+ 0xe806928b, 0xfb7ea87a, 0x931fbfce, 0xe9c607de, 0xabdd2cbd, 0xd059b7f4,
+ 0x540f7a91, 0xfd79ce29, 0xfeec8cd7, 0xf5463da3, 0x7e35c677, 0xca3fe811,
+ 0x72b0aea3, 0x37b47fb9, 0x3d19fb97, 0x9a9fba66, 0xbe295ee9, 0x235d0dbb,
+ 0xf211adc6, 0x75dba67e, 0xeaaf3959, 0xfddf550b, 0x43777c4f, 0x00800098,
+ 0x00000000, 0x00088b1f, 0x00000000, 0x7dedff00, 0xc754740b, 0xeebd6095,
+ 0x91a93fd7, 0x16883e9e, 0xc085a092, 0xeb404616, 0x7d3d05ff, 0xa71f3210,
+ 0x900b18c1, 0x04e08b4c, 0x60dd491b, 0x9e3d90e2, 0x123231a1, 0x1f62cd9f,
+ 0xbd6678cc, 0x8c030d39, 0xc077b19d, 0x0b611c56, 0x3837e2dc, 0x71c6ec4b,
+ 0x3c4c9c18, 0x6c0843c2, 0xc718d36c, 0xbc4ab243, 0x0f7adef7, 0x0b756bf5,
+ 0xcceb43db, 0x40e75764, 0xaabd5ea9, 0xfeeb75ba, 0x7ad3d56f, 0xcecc6333,
+ 0x53f817d8, 0x08acbc3d, 0x65cb191a, 0xfc05f3f4, 0xebf2e2db, 0xdf632b25,
+ 0xb4cbeeb9, 0x2c93f943, 0x1e670adf, 0x355faf63, 0xb188acca, 0xf6e3a9ae,
+ 0xfa87b3ea, 0x8c08758f, 0x127b4315, 0xef768674, 0x0077c154, 0x27d1311e,
+ 0x7d1e9d2e, 0xfd4c9fde, 0x8795cdae, 0x9d32fab3, 0xaf7a6863, 0x59b18d3e,
+ 0xca0e9bf8, 0x332d9320, 0x5aedcca0, 0xcca012c7, 0x9636f92c, 0xb12e624c,
+ 0xf2933184, 0x6bcae99e, 0x39f015df, 0xfe831993, 0x56f595eb, 0x0d5d7f30,
+ 0xcccf31c0, 0x3889f1bc, 0xc9c9d37a, 0x97cd5ed0, 0xd769e30a, 0xfe9fde1d,
+ 0xe4f329a5, 0x572e3630, 0xfbcdf5a0, 0xf04cf98c, 0xeb6e756b, 0xe7033602,
+ 0xd1cc7187, 0x1e60a9c7, 0x1d01e999, 0x2adb5ee5, 0xaa6b3fe8, 0xafe5e1c9,
+ 0x6cdef84b, 0x3e1bdfc6, 0x4ac67ace, 0xe2d9c686, 0x54fac809, 0x4c498ec6,
+ 0x6f5b2fe9, 0xf8e767c1, 0xb2857ac3, 0xcd6e533e, 0xebcbc455, 0x07e1c792,
+ 0x860f6778, 0xcb1d6f8d, 0x55633a58, 0x8b9f699f, 0x387d6d0e, 0x58fb305c,
+ 0x5f4fe5fa, 0x33467cc0, 0x5d398fc7, 0x5d79f847, 0x3e90fa32, 0xeed4ae2a,
+ 0x4b189362, 0xfc87ec96, 0x992adcf0, 0x36053e1d, 0x7e53f633, 0x0402b8af,
+ 0xc29fed04, 0x738014bf, 0x5aef6e9b, 0x16ddd027, 0xa21f4c6c, 0x4c0b2597,
+ 0x2e96381a, 0x9bd4d449, 0xea69c79a, 0xd44f57cb, 0xdb736fec, 0x43fa9add,
+ 0xea6a661b, 0x354a27ae, 0xd59d55f5, 0xef56f19a, 0xff69ab9c, 0x686feed6,
+ 0x7f9e6bea, 0x747f5350, 0xe911caff, 0x885f1a22, 0x89e991b6, 0xd23b0579,
+ 0x3a4d88bf, 0x9cc5cffc, 0xf7f7a3d3, 0x7ec27f21, 0xb7af6ebd, 0xd5fe82ad,
+ 0xe78d3f57, 0xc5f4b4fd, 0xf90072bc, 0x17d956a3, 0x402bc798, 0xad528d7b,
+ 0xf445be95, 0x4536635e, 0xee951be4, 0x11560ab6, 0xda66afc7, 0x6db0aafd,
+ 0x7e47aebd, 0xebd01a2e, 0x3759be61, 0x2157fcb5, 0xc706fc35, 0xc7afcc67,
+ 0xa5cb84f5, 0x9318eeff, 0x609e397a, 0xfc017fb5, 0x8cc9acc4, 0xa3c74795,
+ 0x5db7a74a, 0x6f5f6337, 0xeafccadd, 0xa0582b7a, 0xda3ee90e, 0xfc3b67ba,
+ 0x516b927a, 0x5ebe1dd6, 0x6feffe15, 0xef815f86, 0xf323ff5f, 0xdb1013ed,
+ 0xe6fc88b2, 0xcfeb5ddf, 0x02402bb5, 0x7a1527bc, 0x278291a8, 0x0e908b12,
+ 0x83650398, 0x51f99071, 0xc133d40e, 0x9652846f, 0x38af041c, 0x3034ef68,
+ 0x7e71eb2a, 0xa6861071, 0x35eb45d2, 0x288dca0e, 0xa92c456f, 0xebc79cee,
+ 0x875e068e, 0xd52ea8f7, 0x3ee7baf2, 0xea92875e, 0x43af275e, 0x5aefaa3f,
+ 0xb8cef58c, 0x014489c0, 0x5825beeb, 0x5a1e0e37, 0x05ff4bca, 0xe4994a81,
+ 0x5de83896, 0xec7ea7a7, 0x3707af22, 0xf2d0fa71, 0xf65e3183, 0x5f19b3f9,
+ 0x813f3c3d, 0xfdc24dbf, 0x006fd75c, 0x828ad43c, 0xd5ef0ec3, 0x3f87320c,
+ 0xe4d5f715, 0xe097d990, 0x3133a033, 0x8ccf886d, 0x4ab1982c, 0x0f793e20,
+ 0xedcaadf1, 0xe968e3e1, 0x5af51eab, 0xfc3bec01, 0xe51931be, 0xfaa7a730,
+ 0x2c12e0b2, 0xd013f9f1, 0xfc327b3e, 0x1f4e1e4b, 0x32a25c2a, 0x5fb5a55f,
+ 0x32b6aa8f, 0x59b72618, 0x8559d117, 0xd92c9d79, 0x716dcb87, 0x2e2fe550,
+ 0x56e1c22f, 0x1f39ade5, 0xfb1a6cf8, 0xb9967c3a, 0xaeb36a0a, 0xd9f0abbe,
+ 0x933e30ba, 0x8496f7ad, 0x321019f0, 0xb7d9f0d3, 0x276e9e89, 0x83094e5f,
+ 0x4f182675, 0x23e80cf6, 0xc05499ca, 0x3e244243, 0xb21bfb9b, 0x97c8a21f,
+ 0x5817f037, 0x987e6e67, 0x5cf4519c, 0xfee7aab5, 0xdda2b3a8, 0x117a67e2,
+ 0xc87c70cb, 0xd2313b2c, 0xbe3cb573, 0x6bba0609, 0x90f80ea8, 0x63be810f,
+ 0x06dc151f, 0xcec99bcf, 0x805ab862, 0x31e2aac7, 0x71ad6e8c, 0xec909d2f,
+ 0xecf505bc, 0x4e6e8518, 0xdf11a766, 0xc7bd76c3, 0xb59de442, 0x01f1cbe8,
+ 0xc70937cd, 0xbf226673, 0xc6db40d5, 0x33fde182, 0x99f00fb1, 0x3e7cc835,
+ 0x08eacf78, 0x46af5808, 0xf48d9efd, 0xfe51eacf, 0xe8095f57, 0xe5a5ea25,
+ 0x00745b97, 0xa4013fbf, 0x517c8b57, 0x642e9c30, 0x7ee3d3e6, 0xaffdd57c,
+ 0x90341fb6, 0xffdb0ebc, 0xcfb0419a, 0xd5394e00, 0x1afa20e4, 0xc8cf6464,
+ 0x48c7c14e, 0xbc21acbe, 0xade3f6a8, 0x176826f6, 0x622e91e8, 0xf640b37b,
+ 0xb36ca7d0, 0xf305f381, 0x867a55fa, 0x30afcbe7, 0x34ed1139, 0x7ed4f3cb,
+ 0xfa23136c, 0x3c97b6a8, 0xb8476755, 0x44cc7606, 0x0abd24b8, 0xc7153f97,
+ 0x70e260bd, 0x7f08daf9, 0xe4fe0ad5, 0x43331d41, 0x694fbfbb, 0xff5fa30f,
+ 0xfcd3b720, 0x702bc44f, 0x43f0c8dd, 0x4ed007bf, 0xe5689306, 0x43ff03dd,
+ 0x69dcf784, 0x01df3f77, 0xf028ae5d, 0x6e856ffc, 0x5124da3f, 0xf5cd3eb9,
+ 0xc7a07cfd, 0x7c6e917f, 0x0fc866e2, 0xd5f74439, 0x9027cff6, 0xd9f1521e,
+ 0x10f48637, 0xe8f84dc2, 0xdb8344b3, 0x387510aa, 0xe5bf0abc, 0x2a57c88c,
+ 0x577c2a9c, 0x0bab7a7c, 0xe7b37bc6, 0xf61c135f, 0x454bf821, 0xfb847ee7,
+ 0x674fc1cd, 0x92ef88b8, 0x34667635, 0xfc5266f9, 0x964ca488, 0x3ea2a62b,
+ 0x85cc7388, 0x74cb8c75, 0x364cbad1, 0x02fd1da3, 0xf393274b, 0x82734860,
+ 0xf7f08ccf, 0xd2ec37a7, 0xa9d6fb43, 0xfbc13322, 0x36bcb35b, 0x09fea75a,
+ 0x9399eb86, 0xd60361e9, 0x6577f3e8, 0x9c11293e, 0xbf475083, 0xa2f1c6c7,
+ 0xf8f4689f, 0xc75fb9e0, 0xc10a1cd6, 0xee02c1cb, 0xe7cd9d8f, 0x1e17dae5,
+ 0x842976d9, 0xad0fda3f, 0xbdddd4d3, 0x2976dbdf, 0x106ede54, 0x3697dc44,
+ 0xd9db8e85, 0x5ff404c0, 0xe13b455a, 0x903743a1, 0x2c6bf586, 0xae0a7e78,
+ 0x008fe70f, 0x5be73fff, 0xd2ff3d62, 0x8ff650a9, 0xff69fee1, 0x0df91f24,
+ 0x2b1ffcea, 0x5f38ffeb, 0xa6387317, 0xb3ba1e01, 0x9f70c5bf, 0x3f7c6c6a,
+ 0x7a72504d, 0xf54372e6, 0x739e8677, 0x3ea55179, 0x73de3a0f, 0x1ce91d12,
+ 0x994c76a8, 0x7de911f6, 0x71bbd227, 0x48b5bea8, 0xf08be8d7, 0x220573fe,
+ 0x16c07bc1, 0xa15b3db9, 0x5c139d97, 0xdfe8d9dd, 0x6c73ab3f, 0xcbce2586,
+ 0xe51e3adc, 0x7adb56fd, 0xe2e653a2, 0x38c058eb, 0xf4cbcebf, 0xd1e81978,
+ 0x82b7fe79, 0x8dd62a42, 0xf886c2cc, 0xe70bf557, 0x01d13e89, 0xd7f2bbfd,
+ 0x5ddd7199, 0x1c66f5b6, 0x82d684cf, 0xea3c386e, 0xe6ec0fba, 0xf4cbcef3,
+ 0xb2e9e089, 0xc57bb9b9, 0xa33fa801, 0xee5e7bac, 0x6aaf6a3a, 0x09149ff4,
+ 0x4367e07f, 0xf568e8dd, 0x87263ce2, 0x3ac246bd, 0xb2c66c73, 0xec89784f,
+ 0x0dbf5513, 0x9dad4fe9, 0x91bafa72, 0x15d763e4, 0xf244cf9d, 0x07305e53,
+ 0xbcaf9fde, 0x7b720d6d, 0xa3bf6bbe, 0x1cf7c45f, 0xf3e3f902, 0x764dbf73,
+ 0x2e77359d, 0x56b3e7b7, 0x98549179, 0x3fa1f04f, 0x5bc54f31, 0x195f569e,
+ 0xa0b7171d, 0xd4de30fa, 0x2c59d1ea, 0x2abe90c0, 0x70f3fcc2, 0x40bb3b7d,
+ 0x5972d7b1, 0x2d2bda31, 0xc863df26, 0x420d960f, 0xe2a1c23a, 0x8e814575,
+ 0x7c8620e8, 0x942667b0, 0xb465d95d, 0xd3ccfaaf, 0x5f980417, 0x4366df17,
+ 0x8cdbd0be, 0xb31bc47e, 0xa80d1f8a, 0xffc24df3, 0xb7b22533, 0x2f848eb0,
+ 0xfc79397d, 0x86c7966e, 0xb032eceb, 0xa7f248a6, 0xfdf380b6, 0x927e5907,
+ 0x8ddad10f, 0x7bd2041b, 0x66377caa, 0xc237d932, 0x5c8cdb78, 0xd25f80ce,
+ 0x3ebf402b, 0xffa017a4, 0xf7b35a17, 0x7ba205e9, 0xadf1e519, 0x12efb152,
+ 0xfe1fb90b, 0xca898166, 0x547eca93, 0xc336717f, 0xaffc8235, 0x8430f2aa,
+ 0xc7ca94df, 0xf1f26533, 0x732f224c, 0x2e3f7195, 0x5cdc7ce2, 0x5fb97b14,
+ 0xfb7a339a, 0x8d7a4b1c, 0x90285287, 0x98dd79e8, 0xc52e4987, 0xa3396f12,
+ 0x5da33788, 0xa7073fa1, 0x73fdb513, 0xaaffde45, 0xb274e620, 0xe51472b4,
+ 0xa4e92c41, 0xde83cfe2, 0x79ff97cf, 0x68da47ec, 0x99a3e3ae, 0xe042d4f2,
+ 0x2e9cbf93, 0x96e583df, 0xbbdb23d7, 0x772f63f3, 0x72801ed3, 0x37df04f1,
+ 0x79b3e923, 0xfb97b185, 0x48bed14b, 0xf845f6e1, 0x3d15cbfc, 0xd2794b14,
+ 0x11b36504, 0xff011fd6, 0xfcc28e8f, 0xef5073cb, 0xe5817b72, 0x0fa4b99e,
+ 0x67e1dfb1, 0x3ec42eb2, 0x1c147b06, 0x0543b441, 0xeddd9239, 0x2d7efd8d,
+ 0x643f487d, 0x5c61ccaf, 0x2ff3a81f, 0x7af8e12c, 0xb0e0147a, 0x25eade00,
+ 0xc29baf6e, 0xbfcb50e0, 0x7dbd8c2d, 0xe043e92a, 0x1fbb0548, 0x444205cb,
+ 0xd0a7af7b, 0x1a7e7318, 0xe2d9780b, 0xe4918d60, 0xefd8c9c9, 0xca0d9a4b,
+ 0xd3cee9aa, 0x4b96d728, 0x5c60e787, 0x1ff8fbf9, 0x79d21be6, 0xc1a561be,
+ 0xaeff45e5, 0xbc3bb24b, 0xac478c76, 0x7ccafaa2, 0x52af43bb, 0x94dfb63e,
+ 0x6c05db7c, 0xe57d51d7, 0xda1f24ef, 0xd617dfc3, 0xf1c6c99d, 0xfb1deb36,
+ 0x959dc618, 0xe78d837c, 0x9e36ac1b, 0x3c6d109f, 0x29b560ef, 0xcf1b0779,
+ 0x4a6d583b, 0xf3c6c1de, 0x929b560e, 0xbcf1b077, 0xe4a6d583, 0xef3c6c1d,
+ 0x7929b560, 0x3bcf1b07, 0xde6a6d58, 0x1538d3c1, 0x9e3691e3, 0x78dab077,
+ 0xe36ac1de, 0x97980779, 0x3c6c1de7, 0xf17000ef, 0x722d83bc, 0x943ac1de,
+ 0xf1ff2077, 0x67a49618, 0x547f5fb8, 0x7b06cfa9, 0x786334dd, 0xe76ab55e,
+ 0x17182dfe, 0xfc7209ab, 0x5e783955, 0x77b414d9, 0x457e300a, 0x04dfb066,
+ 0x114565fe, 0xb0d5f0c3, 0x13f3c3f9, 0xbde7d9dd, 0xb0a3fa02, 0x03bc2997,
+ 0x18ea29e5, 0xfe7c3f7f, 0x3b577161, 0x65d6e78f, 0x3bf08b7e, 0x78482cbb,
+ 0x8718e7c3, 0x13f253ad, 0xffad56b5, 0xb2e67f2a, 0x995f71f9, 0xf80899d4,
+ 0xbb6d4590, 0x8c2ff988, 0xd7f15ebb, 0x6ab7dc61, 0x15771b50, 0xb8d41b33,
+ 0x844bcf3c, 0xe1df39c1, 0x6b045f1c, 0x2a7f016a, 0xc1cfe601, 0x53ae15a4,
+ 0xa45e7c12, 0x881bddb7, 0x453bbcbe, 0xaa6814c7, 0x9e606404, 0x6a2012a5,
+ 0xc654d286, 0xf24cd2ac, 0xfe9d389b, 0xf1bdd4d7, 0x030f28d9, 0x6c04467a,
+ 0xf9a83c23, 0xbf580485, 0x2bfc8334, 0x332aeff2, 0x3a47bffd, 0xcc82eb50,
+ 0x5d8238f3, 0x2f80cd62, 0x5c266ef9, 0xceab9336, 0x45eb6f90, 0x73c335e6,
+ 0x9b37e941, 0x2d4e2905, 0x76f28933, 0x6541ccb5, 0x695774d1, 0xcea3f011,
+ 0x7ae175ec, 0x0966ecaa, 0xee3d85f9, 0xf148db3c, 0x32e97ae4, 0xf60049e0,
+ 0x48da62f8, 0x2ec88a76, 0x451cf8ab, 0x2f1f48bb, 0xadc92278, 0x61ebd88a,
+ 0x0a2a83b2, 0x2dc7c919, 0x7cfcb22c, 0xcfcb84ac, 0xdf5d4b37, 0xfbd73c44,
+ 0x878fd516, 0xd0be8f2e, 0x6d9b794a, 0x5bc2f161, 0x6f628afd, 0x90e72447,
+ 0xe901b93d, 0x8f04f17a, 0x1688e10d, 0xf62a78c7, 0x1b49ecf0, 0x767baec1,
+ 0xd45aec14, 0x2aecb743, 0xfa9399fb, 0xb1ca3b50, 0xd0ba4f0e, 0x9092baef,
+ 0xc3ddaa38, 0x8d67143c, 0x6979af1c, 0x9920e214, 0xfe13bfa8, 0xea639d0b,
+ 0x87fb023a, 0x54bcfbe5, 0x428ef8e1, 0x634be387, 0xa0d317cf, 0x613e27d4,
+ 0x771b8d0b, 0x970e0459, 0xf5c0d041, 0xfdff62b9, 0x78f624a0, 0x7d72812a,
+ 0xf22efca9, 0xf974d561, 0x7caa5867, 0xbae1df3b, 0x2d29fc40, 0xf9024faa,
+ 0x767f66bc, 0x0689ea01, 0x2ae35edb, 0x52d5f780, 0x3a22fdf9, 0x5b1ff46f,
+ 0x1eb16e1e, 0xf7bc478f, 0xa3cb22b9, 0xc50911bb, 0x28de4fe4, 0x67e4fee2,
+ 0xfe288784, 0x638bafe4, 0xea7b2fbe, 0xc9fc8673, 0x5b1ffe70, 0x639de3cc,
+ 0x068e0147, 0xf1465728, 0xc28ca6eb, 0xbf5a8dfc, 0x443ebf6e, 0x854110ce,
+ 0xdc6c69e6, 0xfc1163af, 0xba35973d, 0x147b37bf, 0xf310b1d6, 0xf591b571,
+ 0x31c57dda, 0x7e96aff7, 0x3307ca03, 0xd0a9fd5b, 0x6f30bcc4, 0xb2be50da,
+ 0x0fafd5c9, 0x383f738d, 0xe537e0e1, 0xb37e7008, 0xf272e638, 0xf91e9c7c,
+ 0xe119bd75, 0x7e066ae9, 0x255fb08d, 0x9bffdc25, 0x9611e13b, 0x3a637688,
+ 0xe411f743, 0x3637cf09, 0x83637e29, 0x2a767fa2, 0x2c53d472, 0xe52ce952,
+ 0xe851b9f5, 0xfbcad7fa, 0xb69c4a8d, 0x2bf26251, 0xec7ff491, 0x38fce6e9,
+ 0x71c6e728, 0xf30def38, 0xf453dfcf, 0xd3d89ec4, 0xa00c9ecf, 0x91b5b993,
+ 0xf63075f1, 0x0274b174, 0xf6d4bfcc, 0xf8901cf4, 0x0d9b2fb0, 0x2e9c5f94,
+ 0xef0c58bf, 0x57c28b6d, 0x69782b9f, 0xb03a3e86, 0x34a05bfb, 0x9010f942,
+ 0xfa405481, 0x6fec55ed, 0x14308e01, 0xf1de0420, 0x3af4e7e8, 0xce7c1ee4,
+ 0x7fe46d5c, 0xca1bc884, 0x3999569f, 0x83a774df, 0x0efe88ff, 0x9339d333,
+ 0x9fcf20ae, 0xfcf26576, 0x6a3c3868, 0x456ff4fe, 0x71cf198f, 0xc4166577,
+ 0xebddf285, 0x6f26989b, 0xe78575dc, 0x8a4fc185, 0xc949fad3, 0x8f8527e4,
+ 0x74b9909f, 0x247fa85e, 0x021fdcc8, 0x5c50267f, 0xa917e43c, 0x7c98cffe,
+ 0x7ff15cf9, 0xcd1dfd02, 0x4947119f, 0x07308b0f, 0x74ddff3e, 0x8f10dff9,
+ 0x1fd3d023, 0x9fd3d0a3, 0x347fdfb0, 0x11cc627a, 0xf0cc68b7, 0x1eb2bb71,
+ 0x708eb5b7, 0xd321203f, 0x54ce9119, 0x9b7a02fa, 0xe8763250, 0xb4f3217d,
+ 0x4b136f4a, 0xbd3ebf8a, 0xf0bec05d, 0xafe1acef, 0xd149d6ec, 0x7ab59dfb,
+ 0xfa0f28cc, 0xf19bd732, 0x99d4c49e, 0x6bce072e, 0x006c9911, 0x3e5cbb38,
+ 0x007b9e33, 0x64bf2f3b, 0xcdc1bc84, 0x7e3f2e22, 0xdcffecad, 0x2aff9c09,
+ 0x7dbe0b96, 0x6c4d7fc0, 0x4df70197, 0x4958ff7d, 0x7b88fdec, 0x35ee4872,
+ 0xf7208c96, 0xe2f8565e, 0x2b5f0573, 0xe729d6da, 0xfb445899, 0xfdec5567,
+ 0x942b348c, 0x45d75273, 0x745be3a4, 0x2285e787, 0xe21467ac, 0xe4c7e7e0,
+ 0xcd4c3ce0, 0xfc406d2b, 0xf1c4563e, 0x7dfecd17, 0xb3fc146a, 0x4ad70089,
+ 0xfd0199f6, 0xc7ff5969, 0x11e748ac, 0x39d9158e, 0x0390069c, 0x5995df80,
+ 0xfc31b7ba, 0xb5a495d9, 0x67f7d487, 0x67aefe2b, 0x5267e414, 0xf1c3ce0e,
+ 0x4c0e7e1a, 0x3ec5cf2d, 0x88b4b01e, 0x80ffb9fb, 0x73fc0efc, 0xe358a4a8,
+ 0x64a8fee7, 0xb5f73f64, 0x1adc8f7f, 0xcba8e850, 0x7d9ed911, 0x40fbf621,
+ 0xdd60e0e7, 0xb9157cef, 0xaa6f6e11, 0xdbd89ee5, 0x7a59697b, 0xd1c3879c,
+ 0x24e7b4c8, 0x28dff16e, 0x8f5d2de0, 0x77e968f3, 0x5ffae325, 0x1a58c385,
+ 0xe78c73f3, 0xff31e867, 0x7d79f9c3, 0x94be2ba9, 0x198f36ec, 0x07d837f5,
+ 0xb95f6714, 0xcd1f2539, 0x6b67d82a, 0x93be96a9, 0xefa6474a, 0x403bd2e4,
+ 0xfc9caadf, 0x534c6117, 0xa899bca8, 0xa5699bc8, 0x29afdfb1, 0x8e48af18,
+ 0x632baf2c, 0x73dbe71f, 0x79744e77, 0xfb379eac, 0x4f1b4147, 0x8f25bd6e,
+ 0x69474e63, 0x7921faa9, 0x7087eaac, 0x5e868d3c, 0x0bd10c48, 0xcce4510d,
+ 0x3631c068, 0x9db51f04, 0x98afe502, 0xc0a6f98d, 0x39d89daf, 0x96c7dee4,
+ 0x4f138851, 0xc87f8d0f, 0xa047af60, 0xb1a5dde3, 0xbca37fcf, 0xdb7c37e9,
+ 0x47f9d236, 0x28c5d5a3, 0x3173623f, 0xb19fec3b, 0xf6f295b3, 0x94ad05c6,
+ 0x029d6687, 0xf498fde5, 0xab79f92e, 0x30a7de6c, 0x9e5c367d, 0x5e398d6c,
+ 0x97d8728b, 0x28c537f6, 0xf8ebcd7e, 0x37f93a4a, 0x153ca3af, 0xb347ee24,
+ 0xf74ecc0d, 0xb97cafa4, 0x202f58fb, 0x9a2f3012, 0x763ee8c4, 0x7ac7e1a7,
+ 0x051b47cc, 0xe65cfe3e, 0x974ff9e7, 0xf0a3fc77, 0x31a0e59e, 0x7f543b7f,
+ 0xfb4d9a51, 0xcfe569de, 0xf39bf6bb, 0x9ea5849f, 0xc19e15b6, 0xa753e1f3,
+ 0xec1c5327, 0x6b8f03c5, 0xbc5aecec, 0xdf7e80c7, 0x7e861e0b, 0x35d329a2,
+ 0x9c3b2471, 0xae927f31, 0xa89a508c, 0xfa5e7a94, 0xf86d9d05, 0xf7f73bfb,
+ 0xbd67e848, 0x724cc078, 0x9e81ea7f, 0xe32155f8, 0x3e719627, 0xfe3d06b6,
+ 0x35af0019, 0x093273d3, 0xf92b1def, 0xce799173, 0x632bc2d4, 0x0f9d00a4,
+ 0x6b5791df, 0x2ebba50e, 0x794cd6a9, 0x639d5ce4, 0xfceb1d8a, 0xf4fc431c,
+ 0x4082fdda, 0x112edd7e, 0xe19aef50, 0xec7a86ba, 0xc3eb890d, 0x496b53a9,
+ 0xe72a75ab, 0x2de4761e, 0xc7ef8039, 0xf1a7af4f, 0x7b64593b, 0xe5c658cc,
+ 0x99068bf0, 0x80f17de6, 0x55c8e748, 0x7c69debc, 0x0f30cbd6, 0xa6dea3e0,
+ 0xa7d87ba7, 0xe5114e8d, 0x8134e9d0, 0xdf2d82ed, 0xee8578e9, 0x0288ec99,
+ 0xb94a2fef, 0xa96cca9f, 0xf7a77f44, 0x748f2e77, 0xbfa55f7e, 0xa96433c9,
+ 0x49c0ed0c, 0xff94269e, 0x36e4b6cc, 0xdf24f17c, 0xe68743bf, 0xcffc03cf,
+ 0x227fc17d, 0x6b21f70e, 0xf75c78cf, 0x6a76a507, 0x1f0f45bf, 0xb0f442bd,
+ 0xe3efc8c5, 0x8e717578, 0x858eb003, 0xcf1101d6, 0x8352184f, 0x2a6de794,
+ 0x8b74f2e3, 0x81630fca, 0x7d3de01f, 0xc507bf06, 0xcea9da26, 0x84270726,
+ 0x559ea3de, 0x0597aca6, 0xc2f9f132, 0xd83777f8, 0xf6158c1d, 0xb08b37a6,
+ 0xef8985fe, 0x7a86c86e, 0x5e78ef49, 0xb3f778cf, 0xb2b1896c, 0x9f5e0cde,
+ 0x9367eef6, 0x9bd15ea0, 0x3095ebc9, 0x9bb078d4, 0xbd9ab37a, 0xa4be3879,
+ 0x0f15bf19, 0xfd7f1472, 0x45d26f52, 0x28355f8c, 0x031f87eb, 0xfbece3ce,
+ 0xe2ef3a47, 0x78fd5b34, 0x86c9832e, 0x3419f8b0, 0x6077dc85, 0xff2409a9,
+ 0xf30bfbd4, 0xf63f7f45, 0x84fd99d7, 0x2759bbdf, 0xad8073d9, 0x7e145fdd,
+ 0x5c2e7b79, 0xc8d96dee, 0x8c4e785c, 0xef0966b1, 0xd64c0833, 0x78e3c17d,
+ 0x855f9c4e, 0x187f9d47, 0xc8b5b05c, 0x3d70439f, 0x70a8e34f, 0x7937cb5d,
+ 0x6b7ade51, 0x0427ae59, 0xe084d74f, 0x456c180f, 0x0f1dacda, 0x1b5d3ee1,
+ 0x40209c13, 0x1b7cb93d, 0xb1b5dbed, 0x8e081fc1, 0xef81ba90, 0x096f5b63,
+ 0x289763ed, 0x9b9d21b7, 0x216ed68c, 0xb8eeb191, 0xe60c1984, 0xe5d631d9,
+ 0x406e7bc5, 0xd8ef7477, 0x1c74659b, 0x8beb3800, 0xc7a1f9b4, 0x83fb3a15,
+ 0x98e60f22, 0x01ce7976, 0x047bba5d, 0xdc70f786, 0xa88c3783, 0x5df616ff,
+ 0xa4be6234, 0x11a2e7a3, 0xeb03bee9, 0xf3c74e30, 0x6ff988c6, 0xbd5eb963,
+ 0x91e74a2f, 0x4f1c4bd6, 0x7aeeb2a7, 0xe9e0152a, 0xbdd02d58, 0x9247f5bc,
+ 0x7d7d60e6, 0xb192ae2b, 0xe78755e5, 0x38b4b920, 0x72c29ffb, 0x95381b25,
+ 0xccb4240a, 0x10f667a5, 0x4d62b93d, 0xe887b33c, 0x8a4f16c9, 0x1772bea6,
+ 0x280cceec, 0xfa686637, 0xeafee531, 0x83f43632, 0x949a98e7, 0xdb665c7d,
+ 0xeeb8c019, 0x3bc19732, 0xc2de3210, 0x3262cdbe, 0x1c11edc2, 0xcbd28d74,
+ 0xe0ad3fcf, 0x1c52842b, 0xf7cf1f7a, 0xefc40af4, 0xba7a6d1d, 0xcbdcd3c7,
+ 0x35e6aeed, 0x202ecf82, 0x0dbdf81e, 0xed40af77, 0xeba7deee, 0x1bef1193,
+ 0x47000f00, 0x7d84f8da, 0x9347112c, 0x4ad5dce9, 0xdf775605, 0xb38e0339,
+ 0xdd023be2, 0x9bbf5567, 0xb2bfc2a0, 0x91ce91a9, 0xa45e7c01, 0x4d9d754f,
+ 0x5ce947f6, 0x9789cad5, 0x6187a80d, 0x3406977d, 0x5bd6d4f8, 0xcafada3c,
+ 0xd1fada8d, 0xf29ee532, 0xf90d3634, 0x209978e9, 0xb52439e2, 0xf9d651fe,
+ 0xe75ef1b7, 0x0a79d16e, 0xe8cdb3e9, 0x7efa819f, 0xbaa2e8b7, 0x3bcf0eda,
+ 0xf89df118, 0xb1f100e1, 0xc5b9fc40, 0xf8354b20, 0x8176973d, 0xb60576e8,
+ 0x0f67f3ab, 0xfd754fbd, 0x554dfaf0, 0x1b9c5aee, 0x4730bbe8, 0x90ed0905,
+ 0x9316517a, 0x222f88f3, 0xbdf9779e, 0xa36f07c2, 0xeeb803f6, 0x7d852242,
+ 0x44feebba, 0xbde6179f, 0x3a56cdeb, 0x215776e7, 0xf91d81d0, 0xd6e7475e,
+ 0x2f79e3e6, 0x7903ef28, 0x2ef28168, 0x9226a1fd, 0x128d33ef, 0x9ce577c9,
+ 0xe42f2a97, 0xb6e7b517, 0x219e67e6, 0xe7beeb3b, 0xb579d276, 0xc17239c9,
+ 0x2d0fa8d3, 0x471dfe7c, 0x1866df04, 0x34ef23a7, 0x3271cfc9, 0x61d72f3f,
+ 0x2f68e453, 0xfd7551c8, 0x50e3bfb0, 0x692261ae, 0x9bcd1e41, 0x5da9566e,
+ 0xf8283926, 0xffe8756b, 0xdde6538e, 0x75a76d5f, 0x487a3da7, 0x316775c0,
+ 0xe60166ef, 0x7c3a82bb, 0x55f950ec, 0xf8b5d7ed, 0x565de80b, 0x5b63b5af,
+ 0x65e3d745, 0x6dbb5f30, 0x2dcfc8c0, 0x1fa88d06, 0xdef8e0ee, 0xf2c3e348,
+ 0x50ee7475, 0x4730fbe2, 0x7680983f, 0x39a3face, 0xf608d8e3, 0xd3acde8d,
+ 0x148311c8, 0xf33791a7, 0x67f2b573, 0x772b43a1, 0xa39651be, 0x4f245f69,
+ 0xdfdfb4d3, 0x3fa9a858, 0xbcd4ace0, 0x9d5360ff, 0xcdb26ea6, 0xb16fbcd3,
+ 0xe3d4d62f, 0xde6b9773, 0xa558e31f, 0xf5bd3769, 0xed0126a3, 0xc077b371,
+ 0x06e87805, 0x1e4b28de, 0x12d323d2, 0xe32865e0, 0x2c562d0a, 0x744df3bb,
+ 0x3c7bb64e, 0xec4497e8, 0x773a1dff, 0xc97c4e69, 0xdfe5035c, 0xfc5abe0b,
+ 0xc9a00e7e, 0x3ddbf685, 0xf0e3684f, 0x5f38abc7, 0xb94365a9, 0x280ac1eb,
+ 0x67b05ef3, 0x81e97bf0, 0xcc7f707b, 0x45db8c71, 0x2ec999af, 0x5376899a,
+ 0xb071bf88, 0x397e66ba, 0xbe427bf6, 0xf582f917, 0xbc0a6932, 0x3b08cfb7,
+ 0x35ee7a8b, 0xebcbf523, 0xe685d01d, 0xce597ff7, 0xceb3c1e5, 0xfc717bda,
+ 0xb2d03e8e, 0x7dcf4fc8, 0xaebf4468, 0x013fafa3, 0xe70cd9f5, 0xcfb44687,
+ 0x7a2b9e87, 0x61c60c4e, 0x0e1fe39c, 0x63de23e9, 0xa46e5edd, 0x722b4ff1,
+ 0x7a3be5bd, 0xf78b4f3a, 0x864a6b37, 0xe1cb73e4, 0x63ef1fa0, 0x7bf3b4b7,
+ 0x368e789b, 0xf9069c92, 0xbca861fc, 0xf41d367d, 0x4f1a4cc1, 0x97960fa3,
+ 0x3edee9f9, 0xfbcd6fc8, 0x5c34972b, 0xc8257cc5, 0x4cf3ed71, 0xb1961e7e,
+ 0x73fa0301, 0xed35d720, 0xfb95cb1b, 0xde58d39c, 0x2e072017, 0xdbdf2338,
+ 0x9f8abb7d, 0xaae0b833, 0x16787da3, 0x47e789f0, 0x3f861d9f, 0xe1dbd78e,
+ 0x81a465ed, 0x661bfd90, 0xff7157ff, 0x7228e5ea, 0xbfb2a2fb, 0x014084fb,
+ 0x33b7550a, 0x8577e88e, 0xa5ed75b9, 0xcf97dc42, 0xdebfa2b7, 0xee8123f2,
+ 0xffb2ffc1, 0xac3b34ad, 0x54f878df, 0x7697de1a, 0x86953a1f, 0x0cdb89f7,
+ 0xcf68cdf6, 0x3dd07d03, 0x3f5e8ee4, 0xa87edfc1, 0xb79f1fb0, 0x140e0af7,
+ 0xeb9eeec9, 0x364eb40d, 0xa3fd15b0, 0x3ae0517d, 0xabedce58, 0x2a76e5c3,
+ 0x13982edd, 0xc98f7ef5, 0x1e9013e7, 0x5c213e40, 0x820fc047, 0xe66dbefa,
+ 0xd4f648a6, 0x27df0565, 0xde1919b7, 0xfe836dfb, 0x59d38eb8, 0xbdf88da7,
+ 0xb0c39685, 0x71d7012e, 0x1c7881ee, 0xa181837f, 0xf7c2a19d, 0x03e05671,
+ 0xabfbff5c, 0x2dcf0c0d, 0x27ad596f, 0x81bfbf7c, 0x87fa27db, 0x0335bd7f,
+ 0x2e80cbea, 0x270f3bf1, 0x9d38df56, 0xbfbee301, 0x7569db86, 0x2f881b0f,
+ 0x6e13ad97, 0xa50e4bdd, 0xff6e956b, 0x70d3a146, 0xdba70dfa, 0xe6baf461,
+ 0xdbebd1eb, 0x90ecb7e5, 0x61f7a819, 0x438ce7ff, 0x731efa3a, 0x1a7e401c,
+ 0x0718613c, 0x2ada4f70, 0x63c3c039, 0xa7bef5d3, 0x9c6e50d2, 0x6df9ede0,
+ 0x7f2e057b, 0x7d71cbec, 0x8646dd19, 0x2a2e08f7, 0xd95176fb, 0x0a0b3b37,
+ 0x62cfc8f1, 0xa9ca1260, 0xf9ce256c, 0x1d35818a, 0xe452ff46, 0x8ffa67f2,
+ 0x87b77b6d, 0x2b7fefd0, 0xcaab74e7, 0xe64669c5, 0xf7c56c3a, 0x045f8d0f,
+ 0xe06cbce3, 0x282735e7, 0x09c94de3, 0x52822c36, 0xe4e5c157, 0xd438156f,
+ 0x3e149ffa, 0x437f2760, 0xe6685cf8, 0xd1b79ff8, 0xf8eb8cdf, 0xbd75c999,
+ 0x305fde1c, 0xea1b7ce1, 0x3f49eebd, 0xb9dfe3c9, 0xee1d9073, 0xa27ff056,
+ 0x63cf37fc, 0x3532cfee, 0x72d7f68e, 0xe90969f4, 0x68a532d9, 0x30f148dc,
+ 0xe66ccdf7, 0xbaba014a, 0x5aa54399, 0xaafc745f, 0x82fc8071, 0x2fc40deb,
+ 0xb9e9d337, 0x0553efda, 0x8e46e9ee, 0x4a97d607, 0xb6e41b7a, 0x67921658,
+ 0xfaa0f150, 0xfb2996e3, 0x5b1ebf69, 0xcfee28c7, 0x8f84d3d8, 0x84e76d15,
+ 0x41e71856, 0x02b06c83, 0x3627cfbe, 0x8534bdad, 0x626c9fb1, 0x3a0b05cc,
+ 0x5cccc9bb, 0x6c7d0377, 0xd81ea892, 0xbbfaa364, 0x5e54ec9b, 0xa2c738b6,
+ 0xa4e079fe, 0xede20a67, 0x671ed644, 0xed73cc2d, 0x41f081ac, 0xfdf4063b,
+ 0x376b4298, 0x0cccf4fa, 0x947a37ed, 0xf028adef, 0x8333743f, 0xfcbe40b9,
+ 0x8e83e702, 0x467f1bed, 0xe6b1cf72, 0x49fa037a, 0xb7176df9, 0xf1bddd62,
+ 0x5f680d77, 0x04fa007c, 0x7eec0ce9, 0x9e501366, 0x81da339c, 0xa66f9a0e,
+ 0xeb2f38d0, 0x77c80d82, 0x430263de, 0xf7a0fcfa, 0xd71c71ba, 0xe12d7457,
+ 0xe6744df9, 0x48ad2d9f, 0xfbb8fc22, 0x7f7c75f2, 0xf7a1748b, 0xf9effa29,
+ 0x87ee0243, 0x9dfda379, 0x467fec4a, 0xb7af90cf, 0xa41306d7, 0x02f87208,
+ 0xa3978b8c, 0x86581d70, 0xbd1937b7, 0x413cf053, 0xe1c74293, 0xfa158bed,
+ 0x941b4c04, 0x213229ef, 0xc1239f8d, 0x5258169f, 0x41f93262, 0xe7e038fe,
+ 0xabbabe96, 0x811e9622, 0xcff5a87d, 0x762187d8, 0xfc3a347c, 0x437e25b2,
+ 0x4329c3e6, 0x4323f475, 0x1fa07fef, 0x82fbe919, 0xe3c9aca6, 0xb9778a46,
+ 0x83bec007, 0xc300eafd, 0xf4829ec9, 0x4fca8d3e, 0x91d9748e, 0xc171cc7f,
+ 0xd82fa83d, 0x3bf23a5d, 0x7b5abdda, 0x87e141a8, 0x7a1ec506, 0x3feb42b4,
+ 0x5ed49f81, 0x84a4fdc1, 0x3fe34ce3, 0xff273f85, 0x057c8cc9, 0xfd834ef3,
+ 0xfed22579, 0xc7aed554, 0x2ed8137e, 0x740673a2, 0xbe15f48e, 0xe0a8bfce,
+ 0xebe5547a, 0x48d7c865, 0xaf9cbdbf, 0xa96dc7c3, 0x1c0bf9aa, 0x7b945b77,
+ 0xf157f710, 0x139fdaf1, 0xe7ee5f08, 0x1f4f0852, 0xb59ce7b3, 0x031f9740,
+ 0x2e80fb1c, 0xf19d39af, 0x9affd049, 0x6c9f19cb, 0x1d03921d, 0xbf53c5cf,
+ 0xa717936d, 0x19fd42b4, 0xef187ba4, 0x8a3ade93, 0x1cf43e6f, 0xbe753fe7,
+ 0x52cbfc0f, 0x0d8a9f90, 0xda03a341, 0x262efb33, 0x7c581da0, 0xe414fee4,
+ 0x6e7068c3, 0xdce054ad, 0x4bdad8f8, 0xf01e9c29, 0x455aee1c, 0xf49fb9bf,
+ 0x6bff111b, 0xdfa23237, 0xd97ed7fe, 0x49fc7c81, 0xfa84bc5f, 0xf1a3e3f0,
+ 0xd7ff945e, 0x3a7c998e, 0x6f10fc81, 0x8fb5c822, 0x91f7030d, 0x2f4479bd,
+ 0x3ee8ffa1, 0xc83ddbf6, 0x4cd7ee8f, 0xb5b1f968, 0x51d75d7d, 0xddf5b5ef,
+ 0xf2c4557b, 0x87e5d1a5, 0xd38f8df6, 0x6ffad57a, 0x28ed9937, 0xb9113f47,
+ 0xfbdb589c, 0x6bbfd92a, 0xc0cc6f07, 0x47c7ea38, 0xca094fff, 0x379bf735,
+ 0xb99e504a, 0x8251b8df, 0xc71feeed, 0x2dd9227b, 0x84f4b371, 0x665f5557,
+ 0xe26a27bf, 0xfa141b45, 0xd5dceec8, 0x57f00938, 0x03896e7c, 0x7b6ab6f3,
+ 0x139d14f1, 0x79fe2fdf, 0x21c3ca7d, 0x22033afd, 0xce8a8de5, 0x0eafc7d5,
+ 0xaa47cba1, 0x94ef9a0c, 0x0f38d57d, 0x2df7e2b6, 0x0275c56f, 0xec0efa3a,
+ 0xbfc880b6, 0xf046bb2f, 0xf601bfa1, 0xb23f784b, 0x923daea7, 0x9910f742,
+ 0xbd3f9ce8, 0x1c53eb08, 0x5628eddb, 0x8726a7cc, 0x02cb4bd8, 0xe809bf3a,
+ 0xe4cfa9a8, 0x203f7b27, 0x62baa45e, 0xfd743d47, 0x85b26337, 0xdc9a7108,
+ 0x1ca0e777, 0xc0d78f0f, 0x5b8418cf, 0xa7ceafb5, 0xa651f8f3, 0x042dd247,
+ 0x993b9ab8, 0x161d7884, 0x4b9a69d7, 0xf8f0a2f1, 0xdbb03d8e, 0x93ecfd8c,
+ 0xabc21275, 0x8fb8a5da, 0xc0e4113d, 0x7972565f, 0x6757f2a6, 0x3af5e780,
+ 0xc9e6b503, 0x69577e50, 0xcc7491ef, 0xece9780b, 0xc600ffbb, 0x1f073a17,
+ 0xf30e9f8c, 0x98b7be74, 0x9ae79e61, 0x829e6b54, 0x9ae706fd, 0xa21bc81f,
+ 0x1af9f09b, 0x345db92a, 0xd6442f64, 0x5f0aa57f, 0x2c1e968f, 0xd0f3fcac,
+ 0x579fe083, 0x7cff7254, 0x709f8f05, 0x7f5c3cff, 0x1d5972a8, 0xef82ad77,
+ 0x2af972e1, 0x47e039d9, 0x5b5e5c93, 0x32f7a769, 0x90a516fb, 0x92defd7f,
+ 0xf875bb14, 0x43a239f8, 0x7c379c97, 0x739ed57c, 0x6653e57b, 0x3d647bf4,
+ 0x897ba7f1, 0x97fcc3e0, 0x9db9ff6a, 0xeee5d902, 0xdf0f8366, 0x2c0ae153,
+ 0x07d8f1e1, 0x22cf8364, 0xaa89d90c, 0xddab791d, 0x6abb5021, 0x63f6aa57,
+ 0xbbe3c9c0, 0xfb788a4b, 0x556b8b65, 0xa75c58e5, 0x97179e85, 0x398ce7f3,
+ 0xf55fa14f, 0x918152e0, 0x4aec501c, 0xedc34e95, 0x72fb4fce, 0x438a4712,
+ 0xa7d0af3d, 0xc21367ca, 0x63d543f8, 0x7e7054cf, 0x5e3d40eb, 0xf7fc7a88,
+ 0x7c3cfb1a, 0x8fe3d05c, 0x463f5257, 0x2e7e8bfd, 0xebf9233a, 0xadfc6566,
+ 0x4e05feea, 0x59bc20d6, 0xfd19b02c, 0xf5fa68cc, 0x139d8a7b, 0xc519fdad,
+ 0x3f1dbc7e, 0xc8e4561f, 0xcbf3f168, 0x70f2b795, 0xf9f9a9ff, 0x8c687d96,
+ 0xd557bf62, 0x1ffb86bc, 0x6a04f7a7, 0x97feff90, 0xe1eee281, 0xfaa53def,
+ 0xecd3229f, 0xa32ca9cf, 0xf723fd0e, 0xe83f1e1a, 0x43bfb24e, 0x7a5bcc7e,
+ 0x05ace386, 0xb8ed107f, 0x51266f47, 0x32f686d9, 0x385e2b94, 0x1588f947,
+ 0x77f0b46b, 0xfb174c63, 0xf3a6cbaf, 0x9eac2d03, 0x7d2d4ce2, 0x5016d249,
+ 0x0f63dd0a, 0xf2be469d, 0x0fdbd01e, 0x88ffbe84, 0xc799befa, 0xfba636e1,
+ 0x661af728, 0xc278b40f, 0x7dad7eed, 0x8dc4a950, 0x6f09d9a2, 0x5cb85bf4,
+ 0x3e27a339, 0xd378c0ef, 0x7d8cc64c, 0x37b82e5c, 0x474938f2, 0xfc04e6df,
+ 0xd2bb6a08, 0x500c457e, 0x6bf28a1c, 0xbed5eaf0, 0x3ee8d3a7, 0x27cdac97,
+ 0x39ffefb5, 0xbcf0cbc9, 0x970f7252, 0xbd36ee4b, 0xa12a4792, 0x83b797ef,
+ 0xed0e393f, 0x1bfdbb4b, 0x8b807788, 0xc8de48f9, 0x3ecbb89a, 0xe9f4af25,
+ 0x3f257f99, 0x2891c574, 0x79eea479, 0x7ca48f3c, 0x1e787727, 0x0ca9f4e9,
+ 0x48f3edfb, 0xe8e7bd1d, 0xf2edcb1e, 0x5baaa649, 0x3b8a1c71, 0x7c79144e,
+ 0x209f6277, 0x626abc61, 0xe9775f1f, 0xafb238b6, 0x3ab57e1b, 0xba81e505,
+ 0xe22c9f4f, 0xfde4fdf8, 0x5fb06acf, 0xc944afc9, 0xe37aeb02, 0xcb3f0dfd,
+ 0xd9bb75e0, 0xc436fd8e, 0xc9f33fa3, 0x23c7d6af, 0x1280df7e, 0x17c7e7f7,
+ 0xc9f1c8c4, 0x667578a1, 0x959dc515, 0xfa08b578, 0x5c50cc70, 0x8bdfbc27,
+ 0x746e5c55, 0x7142bb83, 0xef3c23cd, 0x9aee9ddf, 0x9ebff547, 0x29dff8c4,
+ 0xfd1e2990, 0xc635d02a, 0x62c1a68d, 0x3ffd2f31, 0xe62758e3, 0xbac7ba91,
+ 0xf47c427e, 0xf23b3ad7, 0xfca7f411, 0x9db0f793, 0x6a8623f4, 0x0333cf31,
+ 0xf7405b3f, 0xdf295231, 0x8fb28f73, 0xa2cfe0e9, 0x2cd0095f, 0x34f43cc1,
+ 0x2333df25, 0xfe38898e, 0xfb6b830e, 0xf52fcc54, 0xc4cd8e8b, 0x3c148e04,
+ 0x779e196f, 0x2f9e6412, 0x6a4ff357, 0xfe5a3cde, 0x9479c049, 0xf3f056ef,
+ 0xf980b296, 0xc4cf3574, 0xf9293a96, 0x43cca5b5, 0x807c42f7, 0xde73afb3,
+ 0xcffc846b, 0xf21115c3, 0x982beb3f, 0xf3699f62, 0x5f73db8d, 0xaafd3a21,
+ 0x78c3c679, 0xe68ee2ae, 0x0fdcecc5, 0x28bb830d, 0xf234d3e9, 0x6ff8febb,
+ 0xfb67a409, 0xbc3e906e, 0x00b13416, 0x78071fc5, 0x40cfbddc, 0xe06b8671,
+ 0xd10d8dbf, 0xf054efb3, 0xd5f78f71, 0x04f7fd11, 0xfdf1e3ea, 0xb7cf2bdf,
+ 0x7ee4b7bd, 0x01bdf7b4, 0xc60b1dfe, 0x13d63fb8, 0x6ed18b10, 0xf2fb83b9,
+ 0xf5846564, 0x7eb8e399, 0x52a3e70a, 0xab4aff85, 0xdeeb9e38, 0x7b987ee7,
+ 0x48afcf03, 0x7b705c8a, 0x74fd5e78, 0xc6a09a56, 0xca45c7d3, 0x92091cbf,
+ 0x447968de, 0x7cc9efa0, 0x33cbfcd9, 0xf1f391e9, 0x462f7a2b, 0x3634bfce,
+ 0x168cfc90, 0x638f0ecf, 0xff2a9dff, 0x7638f3a6, 0xeb44957a, 0xd7e4f64e,
+ 0xeb43638c, 0xb0fb83bf, 0x7d845674, 0x6fe383b8, 0xf1db1d9c, 0x3b63caeb,
+ 0x1e3113fe, 0xc78c7b7f, 0x6c7961ff, 0x8abaebf3, 0xdbffc2d8, 0x1fdfc318,
+ 0x57fffe09, 0xe78407cf, 0x0bcfc3ff, 0x30039f84, 0x17b0f5bd, 0x9d84badb,
+ 0xefc33f41, 0x24d6bf8d, 0x93141c80, 0xce7dd3f6, 0x1f3ce505, 0xecdeadb6,
+ 0x9d0c2bdb, 0xf5f1501b, 0x23f73568, 0x5eebbca5, 0x04d45efc, 0x829f5039,
+ 0xfe72b2f1, 0x59ae4377, 0x898c5e78, 0xc9e63a52, 0xc5f4cde0, 0x5b749760,
+ 0x5359e722, 0xe9a2f195, 0x35d58391, 0xe315678b, 0x7c8a3d1f, 0x4a87ff0e,
+ 0xe5ea521c, 0x6899e9f7, 0xf34c5f4f, 0x1ed1d3da, 0x9fc93c4a, 0xbc99f827,
+ 0x67b2e097, 0xdc7fe62f, 0x7be11b20, 0x26ffc946, 0x1b2bbbcf, 0x60c9d2e3,
+ 0xf05e6217, 0x920fcc69, 0x7bd12b3f, 0x66977cea, 0x19ea3f71, 0x9f301303,
+ 0xcfca9deb, 0xdf9eb139, 0xe6a6fd91, 0xfc1acef5, 0xca055a97, 0xfc23b5eb,
+ 0xf3f9d53f, 0x442b65f6, 0xebcdf80c, 0xf8df2891, 0xe5dff976, 0x9e1e68ba,
+ 0xe24c7be7, 0xbf409caf, 0xec78e019, 0xefd12168, 0xffe5e38a, 0xc7fe8cd4,
+ 0x3cf09164, 0xe254afcc, 0x78941705, 0x502f1a87, 0xacff5bf3, 0xc03e49c4,
+ 0x03940bf8, 0x72810f18, 0x9ddd2cfb, 0x67db4fd6, 0x67ffe045, 0xf21f1e04,
+ 0x87c794fe, 0x9c8e8d0a, 0x7f94f3d0, 0x63ef8b35, 0x2fe79fab, 0x0fcf78d4,
+ 0x7e14f595, 0xefc7ef4f, 0x9d6e15a1, 0x5f3d446e, 0x0e2b35b8, 0x4fb219cb,
+ 0x5ef80697, 0x4eb0fab6, 0x7448bfdd, 0xe75957b4, 0xca4133b6, 0x961abdef,
+ 0x8b34bff7, 0xa968679f, 0x097bfbe6, 0xd418a0ff, 0x6e229b1f, 0xb131f341,
+ 0xca47d24a, 0x5f80b52b, 0x76b6708c, 0x7c55b873, 0x75edf8b7, 0x53c5cf38,
+ 0x1658adc1, 0xa3aec9ac, 0xf5db7bb8, 0xb9bf68ad, 0xae9c6f07, 0xd19978a6,
+ 0x43c4fe8e, 0xdbb8da03, 0xfe3cd513, 0xe01a2afe, 0x457bb788, 0xef0b8ff2,
+ 0x927e8915, 0xbfe42c5b, 0xde981b26, 0xdc45f58a, 0x4c682a2e, 0x5b3ac3ad,
+ 0x60f64492, 0xd27b19c1, 0x714379c3, 0x377be4b0, 0xdd3c458c, 0xc6aacf2e,
+ 0xe45b2ed3, 0x5f9fb8e3, 0x7edacf35, 0x6f3a3df6, 0xc54baeaa, 0x8d2f9a8b,
+ 0xcf556796, 0x3f1bb83d, 0x70d39cd3, 0x8c06c18b, 0xbd1e163f, 0x5fce5468,
+ 0xa1ecb64a, 0x91e16c3c, 0x557f94eb, 0xcf6eadf3, 0xa1abb275, 0xf7fb119f,
+ 0xd7f9e26c, 0x2c0e00d7, 0xb2dd617b, 0xdba1ef09, 0x7583eca8, 0x9b63f3e3,
+ 0x6ff4a972, 0x7c795072, 0xf8951953, 0x64f4c999, 0xa75edbcc, 0x59d5edbc,
+ 0x524dcec3, 0xe8b76f5e, 0x15f108fc, 0x7aa3f792, 0x1f4fde78, 0xee35e3c7,
+ 0xbefa0633, 0x99acfba1, 0x5f4d77e4, 0x0ff444eb, 0x9ae73f3e, 0x60777088,
+ 0x2e842dde, 0x961d913e, 0x9d83f424, 0xdbe60b0e, 0x1aaffb0a, 0x874c3cf1,
+ 0x3c623018, 0xc0cf200c, 0x9eee8b23, 0x6fdcfceb, 0xf1058d5f, 0x58fcdb7b,
+ 0x8fcfffef, 0x58fc957d, 0x273f3577, 0x0291caad, 0x8bde4ea7, 0xf2d919e5,
+ 0xd89c8870, 0x94f9e4e6, 0x1127936d, 0x4e76ee1f, 0x321d5a4a, 0x8f23675e,
+ 0x3bdf245f, 0xfcfa12d9, 0x1f3cd597, 0x67302c96, 0x33567924, 0xc7ddebfb,
+ 0xd76e411b, 0x3ffbb244, 0xe5d029f9, 0x238ba04c, 0x90389edf, 0x343f19c7,
+ 0x71adb71e, 0x2831c4f5, 0xd8982e9f, 0xd3af1e14, 0x5858e3c4, 0x5c5a2e5e,
+ 0x4ea3456e, 0xa179d0b6, 0xdbd404e0, 0x2633f1e1, 0xbd702706, 0xbde0672e,
+ 0x83319814, 0xf961b195, 0xdf305fb9, 0xfbc327cf, 0xa4751acb, 0x5d3cd42f,
+ 0x36c8a341, 0x6c167d01, 0x3f28f834, 0xa45e28d7, 0xec6fc576, 0x90320a94,
+ 0x6b383fce, 0x16ae3094, 0x34731f1e, 0x049eefee, 0x026d1dfd, 0x5dba0bdd,
+ 0x073d4f1e, 0x3fdbd2de, 0xf96de307, 0x3d77576c, 0xac9fcff4, 0xf4fcf093,
+ 0x3f1e7cf0, 0xd8a05dff, 0x3671e139, 0x4bb433a4, 0x1bf0e3c2, 0x38d83a15,
+ 0xd7adeb9b, 0x1d537f14, 0x4e17ed47, 0xcd9d3f3f, 0xb8b46df5, 0xbc6551fe,
+ 0x6d82c6ce, 0x177f7193, 0x93ea18e8, 0xf35ac6ce, 0x76f190e4, 0xdbe7e6cc,
+ 0x60fcc19e, 0x907e686a, 0xf3c301e7, 0x2b9caa82, 0x037dffec, 0xc8377be2,
+ 0x6e63d46b, 0x141fcf1b, 0x8339ab1e, 0x4e086372, 0xc377b7ae, 0xbec8079e,
+ 0xbe312473, 0x457bfa2e, 0xc502a3de, 0x7c160ae7, 0xea1e3c76, 0xf74499cc,
+ 0x2767dcb0, 0x3ca2b16f, 0xe316205a, 0x53b71ebd, 0xc26795b8, 0xeffdd27c,
+ 0xbcefa1ac, 0x7f903e16, 0x81e5f70e, 0x0f9d0366, 0xfddef554, 0xf03534ef,
+ 0xc64fbdf6, 0xe0ae7b61, 0x79f1d8b0, 0x763f7d23, 0xfa7e4bfe, 0x110b58bb,
+ 0x81e7903a, 0xe44497b3, 0xd716cb9b, 0x151f23df, 0x4cf2522e, 0x3f4f5ccd,
+ 0xc0c8b7d0, 0xead3cec8, 0x9f5913cd, 0x46e83c53, 0x8fe5215f, 0x43fcf052,
+ 0x29be90de, 0x6c7a0a3c, 0x63d39dcc, 0x112d9d3f, 0x1e82673e, 0x17927843,
+ 0xf87d3cf1, 0xf650effe, 0x8a5e9a3f, 0xff518726, 0xde63fbf0, 0x5c36c10c,
+ 0xee31db8f, 0x3af68a53, 0xd3a2e394, 0x71661fdf, 0x628a4eba, 0xa149fdcf,
+ 0xa7e7a8df, 0xcf27477a, 0x7fd987f4, 0xd563791e, 0x4df352ff, 0xa0f6bfaa,
+ 0x65ab0f62, 0xbbfe5293, 0x72a037ef, 0x21bf788d, 0x86fdf239, 0x68090e87,
+ 0x1bf7a8a7, 0xcd59194e, 0x4f3c54e1, 0xf277dcab, 0xe93b222d, 0x62fcdfd4,
+ 0x78a98beb, 0x509049df, 0x3a1fb51d, 0x1dbe7a47, 0xa7b223ec, 0xe3cb7efa,
+ 0xf9f887ad, 0xc8def6f0, 0xaddbdddf, 0x32f5dfd8, 0xaed1b923, 0xe86db79c,
+ 0xb744f251, 0x8b8f96e2, 0xb74b71a1, 0x3d56303d, 0x7f23ebc7, 0x8cc71b4f,
+ 0x60ecb716, 0xdbb73a41, 0xa07046b1, 0x39ddb87e, 0x79ca5ddc, 0x4c71a8dd,
+ 0xb973e479, 0xb94c71e1, 0xb9c79b5a, 0xf7c4966f, 0x680825db, 0xce759aef,
+ 0x7fb73a36, 0x9d22904c, 0xcd5a5ef3, 0x257cf4e5, 0xc8d0720f, 0x8560e3e9,
+ 0xf06ff740, 0xfbee1e1e, 0x1efc63c1, 0x7e02c1ce, 0x7bcd470f, 0xa66bf7a8,
+ 0xe83de50e, 0x2f7a9dfe, 0xc367bd47, 0x5ae08f98, 0x7d1c5cf4, 0xe1876bc7,
+ 0xbddb8d90, 0x1a3f7e5e, 0x43e61065, 0x8913cc4d, 0x6bab6b5f, 0xef7a6ac4,
+ 0x8f4fdb8e, 0x7bf04754, 0xe91f8a7d, 0x2fea8eae, 0xfad6afac, 0xf70f540b,
+ 0xde54ee17, 0xecd98be3, 0x87fbfb4e, 0x9e8f1c63, 0xf1b63b32, 0xfb48ecc4,
+ 0xfda2c5b6, 0x5e5aaf1e, 0xb0dfe456, 0xbb0dc5ef, 0x7af5c92f, 0xa7ff60b7,
+ 0x1ba7ca4a, 0xcaae9f28, 0x7c31eed5, 0xe3291ffc, 0x294065a9, 0xd77ca3bb,
+ 0xbc4a97f9, 0x7b944bac, 0x2f69ee10, 0xd397e368, 0x97e3690f, 0x35937b33,
+ 0x78ff7cf5, 0x6785fbcd, 0x8bda6926, 0xda68f703, 0x68142f4b, 0x1503e5ea,
+ 0xaf2bf79a, 0xb3ea6ad4, 0x65f8da82, 0x61c5cdf5, 0xb47d38f7, 0xdca01abe,
+ 0xe6757ed0, 0xcbde6a6f, 0x575da358, 0xaebb4796, 0xebb51b89, 0xf6cdc752,
+ 0xd397d76a, 0x325f5dad, 0xbef2e3e6, 0x7f2e3e7e, 0xc7c95db6, 0xdfb058e5,
+ 0x2d938d33, 0xf7a9b768, 0xfef7d5a9, 0x5866372f, 0x007f40df, 0x00000000
};
static const u32 csem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0xe24bff00, 0x51f86062, 0x38cfc10f, 0x90981819,
- 0x770143f8, 0x01684331, 0x21060616, 0x62636620, 0x22676060, 0x072bbf5e,
- 0x9d877d82, 0x1038e181, 0x781f67df, 0x5e240d7f, 0xbb3f4dcd, 0x2ed1d37e,
- 0x7e27f062, 0x02af8606, 0x058b0c0c, 0x210b7c21, 0xfccff954, 0x18a47608,
- 0x02a57665, 0x150003f5, 0x8051b77b, 0x008051b7
+ 0x00088b1f, 0x00000000, 0xe4b3ff00, 0x51f86066, 0xb97bc10f, 0x726e1818,
+ 0x0143f821, 0xd08667cf, 0x0c0c2c6a, 0xc6cc401a, 0xcec0c0c4, 0x717ebc44,
+ 0x1d7b044e, 0x4cc30307, 0x31c8de20, 0x481afef0, 0x7e879d7c, 0x42f3a976,
+ 0x81c15968, 0x570837f7, 0xb430310a, 0xc430330a, 0x0cf84088, 0x55f2a8a2,
+ 0xa9b60842, 0x39766524, 0x0003f502, 0x3471cc24, 0x00000380
};
static const u32 csem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7dddff00, 0x45547c79, 0xbedd70b6, 0x97a7774b,
- 0x42c84274, 0x4010dc20, 0x804d8854, 0x024de3b0, 0x10602a31, 0x66b71c11,
- 0x04484b0f, 0xd3ce7cde, 0x0831baf9, 0x544e38e8, 0x387c0666, 0xa8d041af,
- 0x1a0c1a51, 0x166bc3b0, 0x26665419, 0xb8c38e3a, 0x6c8a89bc, 0xfd011242,
- 0x5f283798, 0x3b75539d, 0x4dba6f7d, 0xe3fbe65c, 0x45a7efcb, 0xeab7badd,
- 0x9cead9d4, 0x25aaa753, 0xd7a92059, 0xfe197212, 0x48a6f968, 0x51d11908,
- 0x1fb715b6, 0x04846927, 0x6dd5915e, 0x7fc22102, 0x0ed722b9, 0x16c8e427,
- 0xf5a56821, 0x21075ec8, 0xd3767eb4, 0x9735a0b4, 0x0e057d90, 0xbb3fde0d,
- 0x25eb08b5, 0x96e2febb, 0x2ee57b68, 0x65ba8251, 0x8b7729ef, 0x6b2a9093,
- 0xe963a3f3, 0x225df6f3, 0x228742d9, 0x490b1281, 0x8db8e427, 0xac8bbfb0,
- 0xaacec0be, 0xddf79b95, 0x3456fd05, 0xf69d895a, 0xe17bb953, 0xbeb4b1d4,
- 0xe04cb0f0, 0xab6dca95, 0xbeb45e94, 0xa0842828, 0x0fdec0fe, 0x62b69c70,
- 0x4c1a1152, 0x8dbf69c8, 0xbad057a8, 0x067d39bb, 0xb838be7d, 0x5fde14a3,
- 0x2d782f5c, 0x9bc5fdf4, 0xfe819df6, 0xfdc83717, 0x92ffda45, 0x0751073a,
- 0x132fb1b1, 0xa9fcc798, 0x1be56f00, 0x7ad2b132, 0x0a15a5c5, 0xb5491c01,
- 0xc60bb94a, 0x5d514c7f, 0x1c61ce30, 0xe567c747, 0xfa1c7473, 0x0497b2dd,
- 0x996d4c2f, 0x9e00f885, 0x59f6ddd6, 0x5e613b4f, 0xf08194ab, 0x0ab5eefd,
- 0x3830b7bc, 0x0abb15fb, 0x4a566df0, 0x9b4dce01, 0x3b830595, 0xf7525bfa,
- 0xe3ae0196, 0x7c32f21b, 0xf2e6ed31, 0xd5109fb4, 0x4c5f51da, 0x02721688,
- 0xda6541dc, 0x17e78e90, 0xf7a41484, 0xa8913a92, 0x29fe8eb6, 0x49e90861,
- 0xfa17ffff, 0x2683e04f, 0x6e5b7057, 0x7b96bd07, 0x0ed5bfe8, 0x70f39d7a,
- 0x85ed49fa, 0xe5ebfdb1, 0x0a0740a3, 0x83dfad4f, 0x4cfee3e5, 0x55fbd72c,
- 0xfc6fdbc4, 0xe0dcb083, 0x27f3e2f7, 0xdcb0a3fd, 0xfcb0d7e4, 0xcb0cbf9d,
- 0xdf1cbfa0, 0x859fe2db, 0x0fbf56e5, 0xafe33f9f, 0x5fceb2c0, 0xf79fcf8d,
- 0xbd658bdf, 0x5fcf803f, 0x32c3aff2, 0x72c5afe4, 0x96037fa7, 0xbe20fe0d,
- 0x0ebf8af7, 0x087f46cb, 0x37f1ef9f, 0x47f61962, 0xf40bdcb0, 0xdfc465a5,
- 0xff7ee58c, 0xfa0f2c51, 0x43bbf05b, 0x3e5893fe, 0x1eeef1c2, 0x8a248a47,
- 0x3c46b737, 0xea485c54, 0xa648ad64, 0x5672d4f5, 0x5023bf4f, 0xba7ad0a4,
- 0x1e29d68f, 0x148d2d7b, 0x57bd6959, 0xb9cf6b35, 0x68db149f, 0xdac0273d,
- 0x15a23dfb, 0x5fbd69db, 0xb81f6b2d, 0x449c5029, 0xac8303eb, 0x48faaafd,
- 0xafd683b1, 0xfcf6b10a, 0xd2712930, 0xd5847e7a, 0x25688e0b, 0x682f5a2e,
- 0x0fc2f566, 0x5a6e2503, 0xdf616c2f, 0x2913398f, 0x31f5a649, 0xc27daced,
- 0x43d13225, 0x808813eb, 0xd16762f5, 0x2f5a14c4, 0x697ab0f6, 0x1a92d9ef,
- 0xcaf6ff87, 0xe509732d, 0x4dc0ba85, 0xeb45949a, 0xe20acb4a, 0xcc0cf8a5,
- 0x26447ac2, 0x48fda0f3, 0x8d26b660, 0xac8575a6, 0x0efff684, 0xfdf6c62c,
- 0xeded8ab2, 0xbed81581, 0xddb1515f, 0xac7eeab2, 0x6c35941f, 0x20f55b4f,
- 0xd1507fbe, 0xaae07db0, 0x487eb147, 0xa8fb61f6, 0xf7c5bf55, 0x6c3e290f,
- 0x50757c7f, 0xffeb489b, 0x00b6f821, 0xbe08d75f, 0xfc07920a, 0xa72cca1a,
- 0x2046bafc, 0x1e3e40b3, 0xf2a6a606, 0xd14b26b0, 0xfdedbf40, 0x5169f0ba,
- 0x069dbce0, 0x3ccf05f5, 0xbcfd8b9c, 0xb4c8fd80, 0x7eebb11f, 0xca337c26,
- 0x6f84cfd0, 0x1a7ef42a, 0x7b1abde0, 0xfbd9faf7, 0x3c2318cd, 0xfbd62cdf,
- 0x5c7ec269, 0x84d79bdd, 0xf08ce3cb, 0xf7aa5e5c, 0x49fb0873, 0x113c1ee9,
- 0x9fa1a479, 0xef50bc88, 0x4fd84fe7, 0xa3c1eecf, 0xfd0da329, 0xbd22ca68,
- 0x4fd8a39f, 0x89faf756, 0xf08d6328, 0x7ef44b28, 0xfa7ec63e, 0x9a5e6f74,
- 0x1e11bc75, 0xcfdea56b, 0x6e7ba469, 0xefd9faf7, 0xbf67e232, 0xf39f8a2b,
- 0xee80cf08, 0x6dd8abcd, 0x3bb14fc4, 0xd84b9f8a, 0xebdd95cf, 0x88dbbf67,
- 0x28eefd9f, 0xe601647e, 0xf37ba435, 0xe2364e2a, 0x8a3938a7, 0xf000b71f,
- 0x3c1eed0c, 0xf11a7b07, 0x1467b073, 0xcf08193f, 0x33c1ee88, 0x9f88dd31,
- 0xfc51e989, 0xe8cf08a8, 0x3073f5ee, 0x839f88dd, 0x5cfc51e9, 0xef8cfd89,
- 0x6626bcde, 0x3133f118, 0x029f8a23, 0x57c8a7ec, 0xda10f087, 0x3f712b8f,
- 0xf118fa87, 0x144fa873, 0x9fb1633f, 0xbc9fb449, 0xcd29fbae, 0x34a7e231,
- 0x899f8a27, 0xbbebe788, 0x1ca1cfd7, 0xe50e7e23, 0x0533f144, 0xbdd299fb,
- 0x35f69579, 0x2fb4a7e2, 0xd2b5cfc3, 0xe8675c50, 0xe915e9da, 0x2ef5d727,
- 0xbefa04d2, 0xd17561e8, 0xf76025e3, 0x433dba88, 0xbe91359a, 0x294facef,
- 0xdac49878, 0x0277c535, 0xcad45c7e, 0x926bb58b, 0xec192547, 0xd52d14a8,
- 0xd651ef50, 0xcf7ef0cb, 0xf6867ef2, 0x1957598c, 0x057cb3da, 0xc5767a86,
- 0x7dfbc318, 0xf50d8baa, 0x60def7be, 0x70373f78, 0xb79ea1b3, 0xf78627ee,
- 0x31ced407, 0x61b15fb4, 0xcafda1b1, 0xfd4372e0, 0x377fbaea, 0xf4243fbc,
- 0x9afda180, 0xed0d87c6, 0x1b8f2343, 0x3f0ec3ea, 0x447f7869, 0xfb4316f3,
- 0x1bcfa3c8, 0xecb747da, 0x9ec7d434, 0x7f7863dc, 0x437efb7c, 0x6f8bdafd,
- 0x222fde1a, 0xdbda367f, 0xef0c0fb6, 0x6a7cf24f, 0xf32ebf68, 0xea9d9373,
- 0x9abf1cf4, 0x2b9045d7, 0x20497e82, 0x357b414b, 0xaeb052e2, 0x3f3272f4,
- 0x3d40b5c5, 0xd947f946, 0x434d573f, 0xd47fa4be, 0x55ea286e, 0x7d0b4571,
- 0xbe31d3fe, 0xf9f43c2b, 0x35df154f, 0x0df6389e, 0x648137e5, 0xa05aa942,
- 0x95afb734, 0x6717bf19, 0x31f81a5f, 0xd2cabefd, 0xd685303e, 0x2145897b,
- 0x04578f90, 0x49d5da0b, 0xf786a922, 0xfd04ac92, 0x85b9b5a6, 0xe462074f,
- 0x6a1f5d61, 0xfd1d0867, 0x997d93ae, 0xfaad4768, 0xce760028, 0x5e743e9a,
- 0x4d7908bd, 0xe81228f8, 0xb3efbf4f, 0xfb47d320, 0xcfd42ab3, 0xa15f1d88,
- 0xf1c60fe3, 0x870f2023, 0x9d11fc60, 0x1bf6b7c7, 0x96df1865, 0xdf186153,
- 0x3df1d0a6, 0xf55c3fd4, 0x129f1f19, 0x6f210c61, 0xf8e19f09, 0x1c0a9cd6,
- 0xfd42ad7f, 0x93f1d8ae, 0xc337e3a2, 0x344bdffc, 0x8c637eff, 0x6c59cff3,
- 0xe6c2bf9c, 0xb3aafeff, 0x9c24fc7c, 0x59c207ff, 0xc59cff36, 0xd656fe6c,
- 0x777c746f, 0x302dff14, 0xe304f1fe, 0x19c6f35b, 0xa977dfe7, 0x3656fe71,
- 0x5f55e9fe, 0x389df1f2, 0x97c2e7fe, 0x977dfe6c, 0xd58af8e2, 0x51fe05e7,
- 0x83aa93b2, 0x9bd27c74, 0x600cbe2a, 0x940e3a17, 0xd0a95283, 0xe84db210,
- 0x34fc7087, 0x57dbf189, 0x50df9449, 0x39f0059f, 0x59cd5209, 0xce46fd48,
- 0x8bea4beb, 0xd87bd014, 0xf9adfd4e, 0x8d79d41c, 0x5937f222, 0xa00e0d6f,
- 0x8a36b6f0, 0x5bcfa801, 0xfa083e3f, 0xee4acab5, 0x24ef872e, 0x9fe78112,
- 0x96c87afd, 0xcb9979d8, 0xf1f2b5f9, 0x8b791896, 0x64c581fa, 0x6f853550,
- 0x88c13012, 0xd427fa8e, 0xf8c7038f, 0x10f7ea43, 0x2a7cffea, 0x9bfef1b3,
- 0x6f507bfa, 0x3a1efea1, 0x7e1564ce, 0x377bbb47, 0xce5fc293, 0x6244ffe1,
- 0x1dc9faf2, 0xe5403042, 0x0d9fabf3, 0xeefaff45, 0xe9141d7b, 0x0ecc701d,
- 0xe9d430f4, 0xa74002bc, 0xe0d6ddf6, 0xabf10116, 0xa1a6be02, 0x77321268,
- 0x75c5365d, 0xdd7ffbc7, 0xe090e53b, 0xa256e426, 0xfdf419c9, 0x7d0a573b,
- 0x19dc743c, 0xad80b59a, 0x05b65a43, 0x5b649ae5, 0x73721146, 0xf69950c3,
- 0xf269a640, 0xe3312d27, 0xd6332f4e, 0xeb1b9467, 0x5b26b2ad, 0xd3ad5c28,
- 0xf699b204, 0xb196733b, 0xbfa71f5d, 0x99d19525, 0x714e578f, 0xcd1f4592,
- 0x1e00b284, 0xb3ce907b, 0x1d5bec3c, 0x32b9aa9e, 0x1f1fa089, 0xae8049e8,
- 0xef7c3481, 0x6f361e27, 0x64b3bc33, 0xe74e569b, 0x18b66b39, 0xc336fe04,
- 0x875efeff, 0xe5a7c966, 0x626427ba, 0x331f3ce9, 0xccf9b7fc, 0xb0c909f3,
- 0x615edfce, 0xe6f8ce7e, 0x27ffa738, 0x3cb41fc0, 0xe141fc01, 0xa3f9c63f,
- 0xfe32af43, 0xa6fab2a8, 0x6fb43f02, 0x95d20914, 0x9cadcbf3, 0x1ad7e65f,
- 0x9f1082f9, 0x385c740c, 0x3878284b, 0x72660f86, 0xc1b8583e, 0x927737c8,
- 0x87159c80, 0xdfadb72e, 0xdaa660fc, 0x711f7e79, 0x91fdb9be, 0xce9f887d,
- 0xba7464f3, 0xcee9d38b, 0xadfb636a, 0x7277ae9c, 0xf0daceba, 0x7d54ebd8,
- 0x41a89f90, 0xeabde419, 0x2d9e9d3e, 0x38fa7a06, 0xde70cd3d, 0xd779e9c5,
- 0xcd3d18cf, 0x7a70b6f0, 0x2f386cb6, 0xe19d7e93, 0xf777c335, 0x83e69dbd,
- 0x81d9ad71, 0x6aacf4f8, 0x2c715a2c, 0xe86579e6, 0x62c715fa, 0xdd496ce4,
- 0x517d4334, 0xfbc336f0, 0x36cc370b, 0x5dafcfb4, 0xbb9f6864, 0x7d431eee,
- 0x8667e076, 0x77beeff7, 0xcefda195, 0xed0c87ea, 0x663c57b7, 0xdbe6dfa8,
- 0xe67f7868, 0xf686cdac, 0x19cfe519, 0xed97a7da, 0x69a7d430, 0x0bef0dbb,
- 0x6df5177b, 0xf7d575c1, 0xef10199f, 0xf9159bfc, 0x74efacd4, 0xafcc78bd,
- 0xfee3f3e2, 0xf49e5841, 0x69f9f17b, 0x572c28ff, 0xeba6fe81, 0x2b376582,
- 0xdd9f1eab, 0x9742f817, 0x6f654f8b, 0xaed9e80e, 0xbefea1f4, 0xbfd1ef59,
- 0x8a7678ec, 0x48152e5e, 0x6d83ac39, 0x9fd74edc, 0x4ecc2ddb, 0x2c01e420,
- 0x6e4c2a97, 0x2accee97, 0x47a86e26, 0x133b5606, 0x02424bf7, 0x6d7e67ce,
- 0x85ce019e, 0xc136ae1b, 0x6af905b7, 0xe1987051, 0xb1ba92f9, 0xecceef86,
- 0x65be1113, 0x61a3e320, 0xdf7f2b39, 0x7233fa02, 0x10fa6720, 0x00fb5780,
- 0xd13d8deb, 0x2fe33b9e, 0x006c715b, 0xcb1cb9e0, 0x5859fe93, 0xb0fbf71e,
- 0xc0afe63c, 0x357f13f2, 0x7bfe2d96, 0x7f6ffcb1, 0xfd0fcb00, 0xdf7cb0eb,
- 0x51e58b5f, 0xdf2c06ff, 0x7cb107f3, 0xe5875fd7, 0x9610fe3b, 0x2c46fecd,
- 0x961afd5b, 0xf0c4bcba, 0x18acdf4b, 0x9ff5d17e, 0x724f1fae, 0xfc0d397e,
- 0xb62f8f12, 0x84e2f918, 0x617c8d5c, 0x3a6687d6, 0xf7dff598, 0x3f2987e5,
- 0xd0743f12, 0xef44db3b, 0x9de8aebc, 0x7bd0c629, 0xe0c3c58a, 0x05fef4e1,
- 0x5ec71bc0, 0xfb8b049f, 0x483b1888, 0xfac0b22b, 0x2fef9cb0, 0x3f5807d0,
- 0xa1aec7c7, 0xbda335dd, 0xfa041c14, 0xffa0dcf8, 0xf9f10819, 0x51294773,
- 0xcfcf1372, 0x7884bf4c, 0xabe8f180, 0x2e94820b, 0xdbb73a3d, 0xed5e1893,
- 0xe8465216, 0x80d0f17a, 0x0673bc67, 0xa9225d63, 0x3bd07df0, 0x5fa715cd,
- 0x7e02836a, 0x8d6bc2bb, 0xe87cabeb, 0xff93f8ef, 0x8a72842c, 0x49a1d985,
- 0x87b44407, 0x2f69e449, 0xefaa37e0, 0x884cdead, 0x500fb763, 0x931eb83c,
- 0x02fe2312, 0x3dfc06c5, 0x8cd47144, 0x266d59eb, 0x57ffafe2, 0x81bab303,
- 0x64f4aebf, 0x039cf857, 0xe017fef3, 0xd5fd2bb3, 0x9a22de95, 0x9d2352fa,
- 0x21dedb7f, 0x30ab0f05, 0x5be3b7ee, 0xc332b7df, 0x7c8ef813, 0xf3ae96dc,
- 0xa10e7371, 0xf2e59ce3, 0x8ae1ae72, 0xb44ba064, 0x29e82e9f, 0x3947d7fc,
- 0xe6cebfa0, 0x6b5bfb1a, 0x21592fee, 0x5c7435c2, 0x6490a297, 0xbe885642,
- 0x06fd115a, 0xfc004b6f, 0x6f0ebdf1, 0xd8fe0a8d, 0x54463fe9, 0xb7e8d9e8,
- 0xb4fc3b9f, 0xe59bfc1b, 0xb1f56299, 0xcbd47438, 0xb56e50ca, 0x680fd633,
- 0xd5cfd634, 0x9c21650a, 0xcb7c9a97, 0x3c075810, 0xd064c7d5, 0xea5899cb,
- 0x54cf2cfd, 0x7f4a1c70, 0x53ea47a6, 0xf69ccf50, 0x1fbdf0db, 0xfd448e1b,
- 0x40d1c074, 0x83dfa53e, 0x4bce5d88, 0x39427efc, 0x10282e90, 0xf961248f,
- 0xecdff02b, 0xfdcbbff4, 0xeb095fa0, 0x2155bf7a, 0x06bd6031, 0xc61bd79e,
- 0xfaa9dfa3, 0x977c2c1e, 0x7224de58, 0x4a77e75c, 0x7ef837b7, 0x7b3a92f1,
- 0x4c2ed1b5, 0x1aabd431, 0x760daab3, 0x0c03fc22, 0x02410ae1, 0x6729777b,
- 0xb9c936bf, 0x2b68f80e, 0xdf80fb04, 0xa55ef605, 0xa9f145ad, 0xc0cd2628,
- 0xe946739f, 0xfcceaf7c, 0x53a7ea80, 0xe404c96f, 0x50a25c8b, 0x47f47615,
- 0xa1625057, 0x36bcb9f5, 0x64c961a7, 0xbd4eaf58, 0xf5da2372, 0x1bb948f3,
- 0x520acdfc, 0xcff1085b, 0x0652c4b3, 0xbc967972, 0x23161ee3, 0x0545e787,
- 0xcebb99e1, 0x7f531768, 0xb85f50d9, 0x405f58c1, 0x7d874e6e, 0x65eb05f0,
- 0x5f401412, 0x153fdb18, 0x242d1c99, 0x7d606bd5, 0x75b32f5f, 0x48878e6c,
- 0x555f54d9, 0xe154fabe, 0x1fff5a6c, 0xf42dc591, 0xa945dd7d, 0x1c589fcc,
- 0xb468acda, 0x6186d3fd, 0x43cd52b7, 0x81ae0fbf, 0x4bb02af5, 0x3b536ef0,
- 0xc2bbefd3, 0x5f57866f, 0x2fed3bff, 0xeb2a3873, 0xc7182d04, 0x0249b00e,
- 0x580377f7, 0x863c960e, 0x5328c2b8, 0x53f37bfd, 0xd3f0311a, 0x4aa7d156,
- 0x80ff193d, 0xed48253f, 0xf487ef8a, 0xffa9d99f, 0xff6a3fc1, 0x85ff69bd,
- 0xfd47fe86, 0xeff7fda8, 0x6944ff04, 0x2bfee744, 0x95f17d5f, 0x8b27d500,
- 0x4ddaffb7, 0x4a78fae8, 0x52f74daa, 0xf6dd2efa, 0x7ce81ba0, 0x81b80a52,
- 0xc5054f5f, 0xf59c60b2, 0xe0493eea, 0x14e6a2f6, 0xff058e20, 0x7e9ffda4,
- 0xdfe817fe, 0xf64db57f, 0xceaa7c60, 0x3952b11a, 0x68b0d65c, 0xfac7c932,
- 0xf6beacc7, 0x8dea110b, 0xfc5bfe46, 0x21d3afec, 0x0a7282df, 0xd044d78f,
- 0xf5b65d9e, 0x975852b3, 0xca3b48aa, 0x183bf991, 0xea2a62ff, 0x724ad9bf,
- 0x270a76e7, 0x1c55ddfa, 0xbf0d552f, 0x437442f8, 0xd009fd79, 0x4043d417,
- 0x5dfcd8bf, 0x974fb705, 0xe3b4ae4a, 0x232714d4, 0x8bd048c9, 0x90485e3a,
- 0xabe2a7d9, 0x3c43e54f, 0xb7d6ccf2, 0xbe0c42dc, 0x173a7974, 0x7b9ffb9a,
- 0xb77ac4d4, 0xac5bca95, 0x5bafa41d, 0xabb7236a, 0x2a5cacc3, 0x1f90dc47,
- 0xecb374b3, 0x4bc7d00d, 0x99fa7c5f, 0xf83e2127, 0x0077ab37, 0x8bc97fed,
- 0x8637bfaf, 0x90ec97d6, 0x69b326d3, 0x0ef48538, 0xffd154fa, 0xa0e82dee,
- 0x5f97e2c7, 0xec21d457, 0x1da9fdf9, 0x63b25974, 0x7486429f, 0x684947c6,
- 0x8ce2d29f, 0xc7d09f43, 0x882760a5, 0x00ad7eaf, 0x15ed4ffd, 0x1c6e4648,
- 0x1d7e6e7c, 0x13c000ed, 0x2bd393d2, 0xfbd33f4a, 0xa02e9455, 0x32f4cdb7,
- 0xf40537bf, 0x2fd608cb, 0xfe502de4, 0xe40f697e, 0xf56fbd15, 0x5e2a1e02,
- 0xf986e15a, 0x19aa909c, 0x60f53f9f, 0xafc746ba, 0x1ee90390, 0x8af3d92c,
- 0xf21bfddf, 0xffb7c2df, 0x35e31d2d, 0xe0b2cb44, 0x82c8145a, 0x34dfce79,
- 0x80b9e703, 0x2b0f90f8, 0x41cb129e, 0x91297e1f, 0xe4711db2, 0x93973ce4,
- 0x71285b13, 0xd04f3ce9, 0x6df30665, 0xdb8311de, 0x87beded0, 0x37f83e80,
- 0x316a173e, 0x1b4bfd60, 0x921bd7a3, 0xab5197ee, 0xb77f9633, 0x3a066dae,
- 0x65a3ee9d, 0x15463ec0, 0x1f1c0291, 0xafda65c2, 0x0ca4f6f8, 0x4aa22746,
- 0xba3bfc85, 0x73c097ee, 0xd659bf78, 0xef86f9ec, 0x8edce5c8, 0xf1f257f1,
- 0xb049dc29, 0x8f489f5e, 0xb2aab76f, 0xbae807ae, 0x3167c31d, 0x7fe4cef2,
- 0xde4c43eb, 0x4e0ff975, 0x0bf6832b, 0x823932ef, 0xa43d60ef, 0xb0324570,
- 0x022ddf7d, 0x892b07ea, 0xadf393c4, 0x63739732, 0x285f99bb, 0x1c9092fc,
- 0x4e3037c3, 0xf701d22a, 0xa7ac1631, 0xd1e8c7df, 0xddd7182a, 0x8e5d5fb9,
- 0xd07d7217, 0x6407d26a, 0x8903d313, 0xae00aaed, 0xe0e54b7f, 0xfc824f33,
- 0xa80d7952, 0x3972bf20, 0xfaf3ffcc, 0x84fdef03, 0x21e7cdca, 0x7a8d6e5d,
- 0x15b72cd5, 0x7890473b, 0xd3b9fb72, 0x2dcae24b, 0x6e571e7d, 0xcfc82d9d,
- 0xaaf5afff, 0x990cc78e, 0x0eeaf1e2, 0x327aea3c, 0x7acd3e11, 0xc6a4a772,
- 0xeff493d5, 0x99d8525d, 0xd43e751f, 0x0bf16ff9, 0x1f417d95, 0xe754f945,
- 0xea9f28c3, 0x5e29d87c, 0xb9a3c06a, 0xefb0effd, 0xdb62fc01, 0x7518f538,
- 0x015e6d21, 0x338afee5, 0xb4afcc16, 0x5f70170d, 0x0906d064, 0x3c5b6feb,
- 0x9d4ec023, 0xcfd5f63a, 0xbbbe467f, 0xcb7df07f, 0x3f3e2957, 0x6ec84019,
- 0x5f046528, 0xc8e7a58a, 0xeab38330, 0x43f60908, 0xe589a0fd, 0xcff4fe31,
- 0xbdf76665, 0x61cee1fa, 0xb6a2c780, 0xa82dc9c1, 0x9fa20737, 0xc8f5c559,
- 0x0c9a80b9, 0x385cf5fa, 0x73c9fd0f, 0xbc574587, 0x38e7c6fc, 0xf8805f7d,
- 0xb6db2d19, 0xf2915a92, 0x47691b5d, 0xd5b022bb, 0xd9c5b646, 0x9990aadf,
- 0xf8a1fc9e, 0x3e03fa00, 0x94b7b39e, 0x73b1c796, 0xbbeb9dff, 0x81fffba9,
- 0xe155e6eb, 0xa7b016cd, 0x316adaae, 0xeb9605c4, 0x0a405d7c, 0xeea7af80,
- 0x0386bbb7, 0x5e8b0f1e, 0x0aad03c8, 0xe2f8a17f, 0xf9e68df8, 0x8f60ff43,
- 0x707b2b3d, 0xd0e4d7dc, 0x6bc3c05c, 0xf6046d67, 0xb52b76d3, 0xf9c1e24b,
- 0xb9c1852b, 0xcba318fb, 0xa297858f, 0x18a46736, 0x095b3de2, 0x3a676df2,
- 0x73f3e413, 0x2ab82475, 0xb22de817, 0x68353d7a, 0x9414fbe8, 0xef838e5f,
- 0x635ed12e, 0xc68af3e4, 0xf4082f1d, 0xc16165bd, 0xcbeda163, 0xf80516a4,
- 0x4531aaa5, 0x54367d04, 0x3d5bf3d5, 0xe1896e43, 0x096567bf, 0xcc6079e7,
- 0x5e03b76b, 0x08519fce, 0x076801e4, 0xf84f31db, 0xf218787c, 0xbd79a25b,
- 0x275327ec, 0x410fd0ca, 0x71d3363e, 0xa1927d70, 0xd7c4b63e, 0x6a9ae00b,
- 0x8de9596d, 0x1c01f783, 0x7c963fef, 0x5b765576, 0xe5d5df7e, 0xc79627d7,
- 0x9d57ddf0, 0x9e2337e5, 0xa55f2efc, 0x97bcc066, 0x0065e537, 0x21bf973e,
- 0x57c78cf7, 0xdf99fa2f, 0x03e79db8, 0xf95035b7, 0x7e4626bd, 0xc6fca81b,
- 0xfcb61389, 0x22fbf2c8, 0x7b3c6fc8, 0x9757cf8c, 0xc7f0fcdf, 0x0df9bf28,
- 0xca1e4316, 0xefaf9969, 0xe857e509, 0xd41a4b79, 0x8e23af65, 0x403c06be,
- 0xdf3b739c, 0x40718007, 0xbbe5558e, 0xfc7ff1c9, 0xf978e58b, 0x3379822e,
- 0xe4cde99d, 0x2a6ef978, 0x9dd002c7, 0x26f2f1c9, 0x9db9c72a, 0x275077e5,
- 0x2fdf65f9, 0xabefb08b, 0x7b7f731a, 0x40af1d07, 0xfa36bd93, 0x3c87417e,
- 0x6795888f, 0xcf204955, 0xcf27bb87, 0x533cb8bb, 0x8de7ed39, 0xd86f5743,
- 0xdaf61f98, 0x2ff513e8, 0x41fe5f03, 0x6de9ff44, 0xff73b30b, 0x70c4fa38,
- 0x00db8be0, 0x632fca1e, 0xfd5a1d39, 0x74bfec01, 0x9074c6cc, 0xb5839293,
- 0xec3c81bf, 0x0132adca, 0xe1acb87d, 0xcd53f463, 0xbedd1771, 0x745fc732,
- 0xc38e623d, 0xbd33a92c, 0x9dbe30a7, 0xbc20b626, 0x77a24fe4, 0xd3be1c5b,
- 0xe704ebdf, 0x9cf7dae1, 0xece03bc3, 0xcfa42e2a, 0xf4b82ba3, 0x7c2b9579,
- 0x864a1bbd, 0xe291bc41, 0xf025e511, 0xaa7188a6, 0x8601a2f2, 0x72b70cf3,
- 0x16d58738, 0x62d84095, 0x80ebe41a, 0x9ee1b55f, 0x368fb043, 0x005aa8e2,
- 0x31d8f566, 0x57f81f56, 0x51dbd9cf, 0x3cba759e, 0x3964f9c4, 0x5eb5e7ef,
- 0x6fc0c5d5, 0x07828d55, 0xc8aa9dd6, 0xc6dcf03f, 0x955f8d81, 0x6a2d1f02,
- 0xe4563c12, 0xf0142fc3, 0xfae94afb, 0x2c34fc0b, 0xbfda05fc, 0x448a9a8b,
- 0x6ed17ef8, 0xbbe41301, 0xe9774fc2, 0xf7c396b6, 0x04efc022, 0xbad9db38,
- 0xdbd3e1c6, 0x0180a4ab, 0x2f2792fe, 0x7066c9ae, 0x03b556ab, 0x785111de,
- 0xaf388b67, 0xe3abc26e, 0x1f782bbd, 0xe3deb852, 0xb8d3fc74, 0x222f18f3,
- 0xf96e94e1, 0x6e35df37, 0xd19a4555, 0x57e3d35f, 0x2adf455b, 0x6588e219,
- 0xf38c6482, 0xfbfc63b6, 0x7fffe847, 0xf07fadbe, 0xdd74222f, 0xd3fd7dfa,
- 0xcfb3ef88, 0xe8153c7f, 0x9135e4b2, 0x5a5d28d8, 0x82245deb, 0x054124fb,
- 0x41b8b0e8, 0x240e30d4, 0xbba70a45, 0xc351f162, 0x85ddb1f0, 0x4ef1707a,
- 0xfd32706b, 0x9f2bf17e, 0xd33d83e6, 0xa1fb40fa, 0x3c03886c, 0x931ca02f,
- 0xec3e4b40, 0xd8962d13, 0xbf198dbe, 0x87c58511, 0xcc76eccf, 0xea107902,
- 0xc5a9b9d8, 0x35b299a1, 0x557e1ec6, 0x641c5991, 0x15af3b37, 0xbcc04e78,
- 0xf62f8031, 0x8f9e8edc, 0xe639e673, 0x946e2c97, 0x6afe7083, 0x568edd71,
- 0x3e2c9b88, 0xad75c56a, 0x8c0beeaa, 0x7f6c96fb, 0x6aef9d91, 0x72fe0d14,
- 0x4eb53f27, 0xbfc1588c, 0x38c4a86a, 0x8c7fad3c, 0x0bf710f5, 0xb51fa3bf,
- 0x2bd37b64, 0x25c28a01, 0xc6eb3f2f, 0xdbcd5873, 0xd6afe8dc, 0xa8dc7b7d,
- 0x7a1a5f93, 0x53a5fb88, 0x97df804e, 0xcd3d2fc8, 0x62b4e4f9, 0x7aebeff2,
- 0xe14abfa0, 0x638f2c2c, 0xfff947b7, 0x077f2fc5, 0x3b33d571, 0xc01dff3f,
- 0xf39bf4bd, 0xe28fbbbf, 0x7bb5ec93, 0x3d560f40, 0x438c17ff, 0x5649dfe9,
- 0x7b9fafae, 0xad78e316, 0xa17ab37f, 0x13a6d6b7, 0x6ac71039, 0x748ff1dd,
- 0x365653b0, 0x6bbb424d, 0x0c92aee5, 0xd04ec712, 0x60dfe04b, 0x6688e237,
- 0x38681dba, 0x9e700390, 0x748774a5, 0x21bc68be, 0x38e2c954, 0xd4338f2a,
- 0x76db8fc7, 0x4c342b8a, 0x70fc69bf, 0x4aaf6528, 0x785f11ba, 0x9af3d297,
- 0x9eb1d06e, 0x534291c7, 0x70be35be, 0xe941fe16, 0xc6356795, 0x986cbe17,
- 0x424f9fff, 0x848f435b, 0x374885f1, 0x85c7a7f0, 0xdf2d14db, 0xf3b9720a,
- 0x00eb8c05, 0x09d326fd, 0x65f8beb7, 0x4fd5c40e, 0x6177edca, 0x15935bbe,
- 0x3717d7f7, 0xa9e515fd, 0x68dbd775, 0x9f1e127f, 0x3fd1256d, 0xb9e34716,
- 0x5d5b55aa, 0xe9c12e2c, 0xd50b7100, 0x7c79cf8d, 0x1eb5f182, 0xaf1448b7,
- 0xc7ed6058, 0x5c594ef3, 0x07eb72a5, 0x83c5310a, 0xeb1d5184, 0xe97a227e,
- 0x1e00f078, 0xe3c6c646, 0xa287c7e2, 0xdd1338f1, 0x87109e80, 0x68dbc68b,
- 0x5dc437bd, 0xe35fc282, 0x375b77c5, 0xab5e38b3, 0xe95bcc6c, 0xcf8b13a0,
- 0x5bd136cd, 0xeb576f9f, 0xf8f35756, 0x069a78ae, 0xcecf768b, 0x29733af8,
- 0x6d5f7ebe, 0x3ed87e15, 0xbcc13ceb, 0x7c0353ef, 0xb1f0d959, 0xfa8d7902,
- 0xf7cfa6fa, 0xcfcfb70c, 0x5e622f3c, 0x01d09aee, 0xfd66efd4, 0x61ce0cb1,
- 0x37f781c4, 0x8d65de1c, 0xb338fd6c, 0xd27415d3, 0xdfecce7e, 0xacbd7c8d,
- 0x402563fe, 0xf7543bfb, 0x49fcc2b2, 0x7eb04726, 0x3fe06304, 0x7cbed2f3,
- 0xfe647f16, 0xad9c7980, 0x85563f5c, 0x55538fe3, 0x9c6185ff, 0xc2908125,
- 0x7dbfacf2, 0x3692d3bc, 0xdd3bfa13, 0xb3c8132c, 0xcb121d3c, 0xae6bede2,
- 0x5f7ccab5, 0xb9c596b3, 0xe78a3ae9, 0x9cec5c5e, 0x60aa988b, 0x6ba5641c,
- 0x5f3851d4, 0xa8a5d2b9, 0xacd51fe0, 0x35bcfb62, 0x0266f73f, 0x6e526bbd,
- 0xad6d78c5, 0x349ebf09, 0x7f9c114f, 0x1f2c4cf1, 0xd66aec0e, 0xc59a293b,
- 0x574aff00, 0xe14a8659, 0x81fb4d5c, 0xf244a8f3, 0xd11c39e2, 0xf3065a5d,
- 0x8f163d11, 0x4c7c4e3d, 0x5f139676, 0x8f645e0c, 0xb90cdcf1, 0x7e854c34,
- 0xa5d9fdf4, 0xd843e6b6, 0xe004d1e8, 0xc7ef892b, 0xc1e2dd17, 0x0bd5b779,
- 0xaa71605e, 0x3a4f559e, 0x758033cb, 0x72676da4, 0x3f06b93e, 0x5f5d1a24,
- 0x50b9fc1c, 0xe81f6fbf, 0xa26ed5a5, 0xa33950a5, 0x3cc55558, 0xd4343f38,
- 0x9f01e426, 0xd7c7f17e, 0xb0f6bf68, 0xa0352048, 0x19e7a9cd, 0x67202969,
- 0xe608f20e, 0x5f2b0093, 0xa701d1ee, 0xc084cf39, 0x97e7312b, 0x8c4e8927,
- 0x24db9c7f, 0x922b9fa2, 0x8e3b7eab, 0x0824edf9, 0x65f5f3f0, 0x1cf38709,
- 0xf0231175, 0xe30bbd7e, 0x98df0bf3, 0x7403f28b, 0x8f57c588, 0xb91fa332,
- 0x87ceeec1, 0x768d9dfd, 0x492816f7, 0xbc866b40, 0xdfbc79e6, 0x73c6e59e,
- 0x030c5448, 0xe7ce7f60, 0x82f9faf2, 0xaf98c3d2, 0x7a805be0, 0xf196633e,
- 0xbed9929c, 0x1fb50897, 0x0a0d7d61, 0xb38908de, 0x19b8dfaf, 0xdecaeee1,
- 0xb0e8f1d7, 0x3909bd51, 0x04e24e42, 0x97d6263c, 0x65b7e05d, 0x0dc76fe0,
- 0xb5f8eeff, 0x6bf11a66, 0x75f88d57, 0xcfe3320c, 0xd7975f88, 0xe6ca2f88,
- 0x6fc36fc1, 0xb9e328f2, 0x7e157faf, 0x1db8d987, 0xff4af1c9, 0x4ce96dca,
- 0x59dc0365, 0xc2e50452, 0xced9472c, 0xeeff0088, 0x855c1693, 0xe85d795f,
- 0xf9f264af, 0x77d8f308, 0x1123900e, 0x1ca2f5e0, 0xd00bc9c1, 0xa1f20ef3,
- 0x2169e807, 0x57cb929f, 0x8ae7a627, 0x9e3f0769, 0x04dabf43, 0xf20d7bfc,
- 0x955f3b03, 0xb935824a, 0x0f5ea720, 0xbf21dfac, 0x864f3bcd, 0x3bc4f673,
- 0xaf9c006f, 0x68f960f7, 0x6dbf7b01, 0x1a73c130, 0x7485c8a1, 0xf3554fd0,
- 0xbfe83949, 0xa9f69547, 0x6cbef7e0, 0x1bbdf167, 0xd3ea0aec, 0xae16eda7,
- 0x71be2757, 0xb6c7952d, 0xf9c2acb0, 0x36f0b6c0, 0x37a800db, 0xbd6e788a,
- 0x4af6a52a, 0x2c35bf18, 0xd9e6b833, 0xbfc00382, 0x3d71926f, 0x0e379d68,
- 0xed44c1cf, 0x4fdb30b7, 0xea7f0b6c, 0xcfa31b9e, 0xb89f1b5b, 0x1b0fe212,
- 0x31f7f12d, 0xdf2cd857, 0xae8d7fcb, 0xf29d0dbf, 0x58d8562e, 0xfda3c75e,
- 0x4d963ce8, 0x61d7c73b, 0x39630f26, 0xb82e0f9d, 0x2bbfe701, 0x3a7cfd4c,
- 0x8ef1528f, 0x79d0871b, 0xc48bfe8e, 0x26d12bf4, 0x47674ecf, 0x1afde080,
- 0x5fa82fd0, 0x0e2cff6b, 0x44a0b887, 0xf0c45ce0, 0x6fe805ea, 0x7ca6e6bd,
- 0x50a2f94e, 0xbe030d0b, 0xc14e189d, 0x3eaa0a7b, 0x8fd76824, 0xfc0c9668,
- 0xd5d7c859, 0x9f1616c2, 0xd8d4791f, 0x3245ba3e, 0x8c4141d9, 0x693d8f1f,
- 0xf3ab5e7c, 0x03a49bb9, 0x24bfaf9f, 0xd517900a, 0x0fbc4ed6, 0xe6dbb850,
- 0xda3842f5, 0x2b29c02e, 0xcb125e5a, 0x9bf7ade2, 0x6b0f2c6d, 0x9d7042a3,
- 0x89c0b8d9, 0x17fb08fb, 0xeb3cc62c, 0xebe67eaf, 0x5edcef1b, 0x664a7e8c,
- 0x325af5fb, 0xbdfc0519, 0xaf78605a, 0xb7dd8acd, 0x9f9d4bd2, 0xf9d6fe75,
- 0x92416b3a, 0xcbde5e2f, 0x7bb33b60, 0x120c178a, 0xf6d7f014, 0xa9fc780a,
- 0x219f01f5, 0x065cdb7f, 0x00d903c8, 0x79e3554f, 0xe16dbbb4, 0xfb5479f8,
- 0x0fe66e6d, 0x0558103e, 0xa53f1e79, 0x327a09c2, 0xd1ebbf71, 0xa083aadf,
- 0xab677c2a, 0xa6e78d9d, 0x16c8dbe6, 0xb54ad388, 0x80bb3759, 0x5fae4bff,
- 0xb27de143, 0xebeb82dc, 0xf08bd946, 0xc1092a07, 0xa73f03f8, 0xd92a7bd5,
- 0xec7e7b1c, 0xa8e8ad88, 0xa8f7ce8d, 0xeef383cd, 0x000af3e1, 0xffebf7bf,
- 0xa6bb06e3, 0xe915a2ed, 0x43fb8bd8, 0x6de777fa, 0xd80f4f0c, 0x7be077b5,
- 0x72869152, 0xbdb9f5e2, 0x39c186f3, 0x18f78a55, 0x5fa0ea39, 0xea91e700,
- 0xc28e3aa3, 0x20b4ea93, 0x534d125f, 0x031e7a3d, 0xc8c5efe1, 0x04088905,
- 0xbd741cf2, 0x8885842a, 0x70c1ca8b, 0x7e02339b, 0x9d056a47, 0x4ec10537,
- 0x66bfac6c, 0x1cf44ce9, 0x5251e61c, 0xe4842cbe, 0x12798279, 0xfd05a890,
- 0xd756faeb, 0x0853abd3, 0xc7eacbca, 0xed0d60a4, 0x62d49367, 0xae4af887,
- 0x56c316a6, 0xe2a4aa74, 0x153ebcf9, 0x1c73f304, 0x44a54f79, 0xf42a16ed,
- 0xef11bf43, 0x1fe7178e, 0xe5f1d76a, 0x2be027fb, 0x7efb70ff, 0x76bc6f30,
- 0x75f79e36, 0x51e9da1b, 0xb1edc1fd, 0x8efebe52, 0x2bed8cfe, 0x24b5c893,
- 0xd66f8e36, 0x327dba1f, 0x03cb7c7a, 0x6feef80e, 0xadda4e0c, 0xe08ddf06,
- 0x13ea8df3, 0x0c8e6ebe, 0xbf427d53, 0x3b0f082f, 0x82eef100, 0x771c990f,
- 0x038727d2, 0xfbefe022, 0x5f3311ea, 0xb9508d0c, 0x5583ede4, 0x89ecbf38,
- 0xafbda1d6, 0xd277a8dd, 0x40cf0da6, 0x9bf3973b, 0x7cbacf19, 0xe0bee59b,
- 0x2b01ef5e, 0x60910b83, 0x1d08871e, 0xa079a870, 0x60888e97, 0x5115b7ef,
- 0x0eb8503c, 0xb94bf972, 0xe61ebc10, 0x9d7c3ebf, 0x7be4e41d, 0xfa1127af,
- 0xf27c4c75, 0xde37d171, 0xdcf8f2ce, 0xfb658780, 0x24f5f02e, 0xca8ef482,
- 0xd8939501, 0xffce8978, 0xe5d77e66, 0x3a0e06a3, 0x0bf9e1e7, 0x28aceb02,
- 0xbdf0f084, 0x00f26c95, 0xbb7b755e, 0x24b7db86, 0xdff68590, 0xebe10f4a,
- 0xf8104e51, 0xedd646a4, 0x362daf75, 0x55d2b53e, 0xfb6df19c, 0xa9175535,
- 0x8793167f, 0xa3b5255d, 0x517556ff, 0x1bdfe7c1, 0x450a617f, 0xf37f01ba,
- 0xe33b3ded, 0x57c83c6f, 0xe62fffcf, 0xbf3ccab7, 0xfcc76ab5, 0x6bdf12c6,
- 0x147f542d, 0xe35758ae, 0x7793f150, 0xeb3b0b33, 0x657cfd05, 0x96603d22,
- 0x6b4b91f7, 0xb498600f, 0x72af790b, 0x3212fc70, 0x98d9f41d, 0x725bb508,
- 0x05ffcb3b, 0x072abf3e, 0xaddb7bc3, 0x9e4103ed, 0xdfbe8856, 0x16a811d9,
- 0x8aec058b, 0x1eed04dd, 0x6e63beef, 0x1ee6f794, 0xb3a7f586, 0xf660105d,
- 0xf4475f26, 0x48d0a7b8, 0x738e80e5, 0x0e7beec4, 0x30f1affa, 0x340e14bf,
- 0x623a7e81, 0x5e03d5f3, 0x24c6141d, 0x28324f38, 0x28e2cb92, 0x25dc8311,
- 0x49873392, 0xde74428e, 0xe805aeb0, 0x484036ba, 0x7b02cf0c, 0xd502230a,
- 0xf4b7602e, 0xb06c242e, 0x06f30465, 0x7bb3e77b, 0xb0177a00, 0xb4dec77b,
- 0x5bc938b3, 0xcbd11d7c, 0x03f2b623, 0x912cbf00, 0xfbe0b580, 0x42a00dc3,
- 0x5d88f17c, 0xb27807db, 0x8f386995, 0x0af10f6c, 0x52d98e94, 0xad7d8048,
- 0xc0aaa5d4, 0xad848ae2, 0xfed25043, 0x45ab27b2, 0xfeecf740, 0x6509cf04,
- 0x4713fd83, 0xe5d98e6e, 0x6b07161f, 0x1f8764ec, 0x487172e3, 0x31edf3a1,
- 0x473fe599, 0x7c1439e3, 0xebab6fc0, 0xeb6c9c56, 0x225f2c97, 0x6cf0c290,
- 0x6080cbf6, 0xd7892f30, 0x6488541f, 0x29bf454f, 0xb0197c00, 0x726fd0d8,
- 0xef086f10, 0xc7ea4949, 0xbc1145ee, 0x2bfea0eb, 0xf706dda9, 0xa0f2e825,
- 0xe3a3f9f3, 0xf44af66e, 0x73f8f755, 0x52d3e0f9, 0xe027ff7e, 0xb9dc75b9,
- 0x2671ab81, 0xef8c39ed, 0x6790d134, 0x51afd3a9, 0x0ecfd036, 0xfd5892f1,
- 0x810652ed, 0x242ade3d, 0x6a5fc179, 0x7830245d, 0x43cf1b05, 0xccf30c95,
- 0xa33f3074, 0xfec5eb8d, 0x0f38b949, 0xf3a09d7d, 0x5d71875b, 0xe7a23cd3,
- 0x8ce74c8e, 0x3290e7cc, 0x9df1a2f3, 0x2b07cc2c, 0x184ee057, 0x40ec2e72,
- 0xddcaacfb, 0x9ce2439e, 0xb168c993, 0xa6073dc7, 0xfd6f1497, 0x5e427a92,
- 0xe80a7561, 0x993b8cd9, 0xa3e3307e, 0x3d0c084d, 0x7f63fb04, 0xa3eee390,
- 0xe66665eb, 0xe8f3298d, 0xd75999fb, 0xdf3fa963, 0xc6e294e0, 0x0925c70b,
- 0x0c8fcc3f, 0x18df3cb2, 0xf3071dfe, 0xe77beb39, 0xbfc50d3d, 0x1be9e31d,
- 0x37de1892, 0x6fbc3124, 0xaa7c7450, 0x1d7f20c9, 0x5f21af75, 0x96dfbd62,
- 0x509e4122, 0x73e50b20, 0xbbd187be, 0xed0d7de3, 0xbb449e96, 0x125036fe,
- 0x0db265eb, 0x7dc59ef9, 0xdfe0bcf4, 0x994b9ff8, 0xdba7ed48, 0x8d505f38,
- 0xc29be8c0, 0x7eb0bee0, 0x4e9b8e12, 0x1481da2d, 0x2dca0bcf, 0x9d07885e,
- 0x1bbef39d, 0xc9cdc88e, 0x78242e6e, 0x0d7ab5f4, 0x157f73f8, 0xd125b77d,
- 0x5036d27e, 0xf183d545, 0xa525c805, 0x8fb8f5d3, 0x3712db39, 0xc497cfef,
- 0x925776fc, 0xccc8e107, 0xea748a9c, 0x014e4fa8, 0xa7ccc37f, 0xe6b35e54,
- 0xb738ef0d, 0x1166f946, 0x6f2cd9e0, 0x1469326d, 0x208add70, 0x7674d2be,
- 0x975b7ae6, 0x43903497, 0xa72a8fd8, 0x73a7547a, 0x3a6afe3f, 0x4ff13bc6,
- 0x1ffeff08, 0xc7b847e0, 0xd45ea317, 0x620c88e5, 0x7a0ede7a, 0xd9ce2637,
- 0x3ed7f4d6, 0xd1f89fb0, 0x60bbcfcf, 0x52efe93f, 0xecf40bbb, 0xecfffbc9,
- 0x8f863c82, 0x8ef167ee, 0xd7fe4cbb, 0xff4c4923, 0x5e54947f, 0xdbbaf303,
- 0x2fa175ff, 0xbdc95f86, 0x51645f6c, 0x6f9d3450, 0xae379e34, 0x17cf990c,
- 0x95df1007, 0xfd78fc52, 0xe71624fe, 0x59bf5459, 0x7c6156c9, 0xae81afdf,
- 0x797fb927, 0x03dd81b2, 0xa733c3a2, 0x3e02a87e, 0x56c3dfd7, 0x2cdeafbe,
- 0x9b43f5b3, 0x3e62fb0c, 0x9c33378e, 0xa4fdf887, 0xa22d7ff3, 0x8e9b33df,
- 0xc3d52f75, 0xf3cb30be, 0xfe63cf35, 0x9c296a47, 0x90ff9fe7, 0xbc34fe80,
- 0xcf5d3f7f, 0xc5aef77c, 0x3cf333fd, 0xa08fdf3b, 0x90b5dfa1, 0xce7cdbd3,
- 0xed98616a, 0x3e23cf6f, 0xf94ecf94, 0x0f966118, 0x9e238e6d, 0x00e79c3b,
- 0xf126343c, 0x3242ab7d, 0x762ef212, 0xfc97ee1e, 0x675ef96d, 0xd3f2b9f8,
- 0xa4f44f3c, 0x9359609f, 0xdbf3b2a4, 0x814bb7e1, 0xee3596bf, 0xbe657bc0,
- 0x0caa3eab, 0x84ff729f, 0x6a25e874, 0xe811fe5f, 0xc1827c48, 0xf9b65cee,
- 0x65fcc2bc, 0xf83b9f86, 0x1f003bf3, 0xeececfb8, 0xa963b90f, 0xdef6217c,
- 0x8c92f799, 0xa267ebfb, 0x3cd9e4e7, 0x93bef92a, 0x5f333f3e, 0x9b3e70d7,
- 0x9ada75b7, 0x35ca745e, 0xf872274d, 0xfbcc0779, 0x2166f9d6, 0x8acd2f29,
- 0xbd3a1fc3, 0xfe107ca2, 0xd3abc225, 0x6ced5e69, 0x2640af3e, 0x84cbf7df,
- 0x2f9992b8, 0xd76f3aba, 0x80e4b72a, 0xdee99abc, 0xfb3ce09a, 0x3ed893df,
- 0x2b553ced, 0x9f38bd05, 0xc4f1af94, 0xa5272bd8, 0x81f743da, 0x7c656d1c,
- 0xe06bd51c, 0x7ebe82bc, 0x7cf5c64b, 0x80cd4bb9, 0x1e90917b, 0x87615e70,
- 0xe9ef0035, 0x6bf71ce3, 0xf0197f5a, 0x69e5865d, 0x7fd6b97f, 0x82fb4740,
- 0x10dde78d, 0x441b6dc7, 0xead3be30, 0x71ebc232, 0xc78f0888, 0xa5bbd6c1,
- 0x1f37f352, 0xdada0e80, 0xc711f98c, 0xd0f8f12f, 0xbc596b25, 0x10ed5e79,
- 0xdd05f70c, 0xf74ae5c5, 0xf4e6ee3f, 0xf6cc2bbb, 0x9a6ce7bd, 0xdf30f486,
- 0xfb847267, 0x041bb32d, 0xfa6623d4, 0x775ef7cc, 0xdcedf40a, 0xdf7e1160,
- 0x11e45e89, 0x6e99bba4, 0x761e1deb, 0xad548dbf, 0xc73f7dc0, 0x4fb80937,
- 0xde8124b8, 0x8f0777fb, 0x3e737767, 0x822479e6, 0x55d6e17f, 0x98117a6b,
- 0xf80550ff, 0x3ebf0cdc, 0x6344f9ff, 0x37cf877a, 0xcb48bcd1, 0x829f2cb5,
- 0xc28be3af, 0x65a97eec, 0xaf2c888f, 0x748bc793, 0xcd7875f8, 0x971528f3,
- 0xdb6f3e62, 0x09f31106, 0xd7040aef, 0x77cbbdc0, 0x3d7016ad, 0x5d27444d,
- 0x32fbe84f, 0x63671acb, 0xf68f957e, 0xdb697603, 0xd9170487, 0xde0275b6,
- 0x9e90937f, 0x94579661, 0x30849e88, 0x74a3cdba, 0x7e6e387b, 0x3fd6915c,
- 0x78273f76, 0x763fd6bd, 0x3084897f, 0xdd4964af, 0x4af3c334, 0x774f5187,
- 0x3aa47f25, 0x2e9cde7e, 0xe9fcba6f, 0x9c1eb8f2, 0xa51fb073, 0x5ceca1e0,
- 0xe863cfc0, 0xfbfd50af, 0xff8b0773, 0x7d1b7a3c, 0xf3c6d965, 0xf984fd86,
- 0xe6bd18a3, 0x79f1938b, 0xe28375a2, 0xd787a0c1, 0xf87a8c3a, 0x9f47ce87,
- 0xfa272e87, 0x6272ccfc, 0x0f4cdefe, 0xa6670e3d, 0x001e998b, 0x470df827,
- 0x07c11c9a, 0x04479c28, 0xc9a07706, 0x66b7708e, 0xfe706896, 0xedd65966,
- 0x0f811e58, 0x57bd8347, 0xed038cfe, 0x7957ee56, 0x4503e7e3, 0xf76e25ed,
- 0x41961988, 0x93111e30, 0x2ec790bc, 0x77aa5b66, 0x7d8a79d2, 0xd2183969,
- 0x9c22bd99, 0x992daee7, 0x143dc220, 0x77bcfc35, 0x379d858d, 0xc3dbfbd3,
- 0xed97a0f1, 0x8046f28e, 0x9a9fece7, 0xfe2c1d0b, 0xce0afe8c, 0x143dee13,
- 0x760dbfa8, 0xf304ebf0, 0xc8d20b69, 0x83b7a001, 0xee40a368, 0x72a4743f,
- 0xffed9c3b, 0x286cbfd1, 0xcbcb56bd, 0x3f9097aa, 0x49b3e2fc, 0x37b25f70,
- 0x9722b2d9, 0x38e2ffd6, 0xb9ee093d, 0xce5b66f3, 0xfda87ae7, 0xd59cf8ed,
- 0xef9cb6af, 0x737feb47, 0xd875619c, 0xf87b82a8, 0x0527671c, 0x1e38c306,
- 0xb5eae7a6, 0x243e41ab, 0xa597f30b, 0xc3c60afd, 0xd5fdfdf5, 0x17e0e694,
- 0x79f9c87f, 0x17e2aacd, 0x2c67101c, 0x6fd854d6, 0x71be0ade, 0xea5fefcf,
- 0x161d1578, 0x4a0367bc, 0x1ca7ffc0, 0x485d3a9f, 0xe4357683, 0x7690923d,
- 0xb483ec35, 0x1dc77c3b, 0x91d87db4, 0x572009e6, 0x5fbcef0d, 0xf68df788,
- 0xa30cfd65, 0xf3a6e20c, 0x9f6afb39, 0x8afbb1cd, 0xcfa28eed, 0x0c943e81,
- 0xaa084768, 0xed41dc87, 0xa88d1a86, 0x31f81e4a, 0x81bdbb46, 0x49d7d9f3,
- 0xcf91e7e5, 0x9f50477a, 0x7df0e53c, 0xfd9be305, 0xda9cd211, 0xf253fe2d,
- 0x7af8c5ef, 0xd1e3766a, 0xff9f2039, 0x0afdcec5, 0x7af9869a, 0x9ef7a3db,
- 0x1df7f410, 0x710bc924, 0x9925e236, 0xb71e7481, 0x4abe30b0, 0x4bf18c2b,
- 0xf7e87cf8, 0x951ee113, 0x1fb60e91, 0x8227e74c, 0xa894369f, 0xf8830e58,
- 0x9ab01e43, 0x487beb0f, 0xb47de8e8, 0xccedc7ff, 0x11d5b7ef, 0x84675c43,
- 0x7707d993, 0x275c58b9, 0x0cdd0e49, 0x0be93dfa, 0xdefd01e2, 0xe12294f6,
- 0xb9e4a67e, 0x0e39f711, 0xf82e3059, 0x40f41cac, 0x4afdbd7c, 0x3a42dd49,
- 0x74e36bfa, 0x5c7dfbd7, 0x7884af51, 0xb3175cca, 0x222d9e27, 0x7edaf798,
- 0xfec2094a, 0xadb66a57, 0xcf4fd63a, 0x4faddfe7, 0xa4e41e2e, 0x8929a865,
- 0xf723f8c0, 0xd2928352, 0x02fa85e3, 0x76c5f03b, 0x43c511c0, 0x0f73d5aa,
- 0x9e7a97f4, 0xcf8b9bc2, 0xa4afc435, 0xf8a64d0e, 0x5383731d, 0x9e297b85,
- 0xc06e87b5, 0x2d17bf3c, 0x76d3ff78, 0xea0d3bc5, 0x1ea9cfdb, 0x9b3d0788,
- 0xf9c24a1b, 0xf9c168bc, 0xbf6a4f6c, 0xfb85396a, 0x8e2c41e1, 0x64883920,
- 0x2a79054b, 0xcfa1ef56, 0x7d993bc7, 0xe4c2dabb, 0x62a9daa9, 0x8e8171fd,
- 0x15ef005f, 0xf9e91ca1, 0xeced6d17, 0x5bcf471c, 0xe7e0459a, 0x3fba69a4,
- 0x0fc1111f, 0x704e571f, 0x94e71d5d, 0xad3a2a83, 0x2176739a, 0xd6ceffdc,
- 0x2e1f098d, 0x29f2cc9d, 0xefc2efbd, 0xf2701c21, 0xbef836fb, 0x4f9cb5d0,
- 0xd11693c6, 0x5fc7db46, 0x2e48de24, 0x8c6af7dc, 0x5a633edf, 0xfef127e7,
- 0x44cf76b5, 0x8c445c78, 0x0da4f0eb, 0xae20a7a5, 0x09344c5c, 0x66c4a9f8,
- 0xdcf5876a, 0x9ac4f70d, 0xf273c9ee, 0xe4872b75, 0xe8fde6c4, 0xe249fb71,
- 0x47688de0, 0xc05e2994, 0xf6a70ecb, 0x0d4fd857, 0xdbf2f750, 0xf8cf3de2,
- 0xa0d67e59, 0x57020e8b, 0x74fe50ff, 0xdaae7cc2, 0xd3b01b50, 0x9fd55f79,
- 0x087c0ff5, 0xa78ae5fa, 0xbe807ad2, 0xe97a7377, 0xc077cea5, 0xc6649e5f,
- 0x3a6b9e5f, 0x273ef3e4, 0xf2e89b8b, 0xfd077c06, 0xb78391ec, 0xa41fdbc7,
- 0xf01f7afc, 0x41270eeb, 0x5917fa7b, 0x672059b6, 0x9dfb38fa, 0xe5cdff8c,
- 0xf7cb559a, 0x0412efc1, 0xc6eb64be, 0x31175ec4, 0x6eba2e4f, 0xab783327,
- 0x53e9dad4, 0x29c76f21, 0x3a4e5e63, 0xcb16373f, 0xfc31592f, 0xab5df3a2,
- 0x3adff993, 0xfeec94ff, 0x284b9e33, 0x06fa92f9, 0x376a24b9, 0x2133fcea,
- 0xb37dc110, 0x89d98409, 0x99d9fe66, 0x2e8a7f80, 0xade812a8, 0x9873fc4e,
- 0xbe224ff1, 0xb048fda1, 0xe7f99a0e, 0xe3b72719, 0x25cff212, 0x6569e037,
- 0xeeb7c953, 0x8dfa34ef, 0x72e67cf9, 0xbe7e23b4, 0xef1c67e7, 0x1bda95bb,
- 0x4c6f41f3, 0x2f4178b1, 0xbec8ee50, 0x3bbbc299, 0xb5d7bf49, 0x3bea0f3a,
- 0x7687a624, 0x87a8ad84, 0x3e7d3876, 0xb2658b8c, 0xf24474f3, 0xb6fe40b5,
- 0x8d4d97b7, 0x7efb27bd, 0x39218fce, 0xd804fa32, 0x3e306f45, 0x00a53518,
- 0x5921bc6e, 0x185e98f3, 0x0cd9527e, 0xd0b28fbf, 0x9386f455, 0x74067fbe,
- 0xc753ac07, 0x60b7bc14, 0xf50531d9, 0xdf7babe3, 0x93b8852e, 0x723a179e,
- 0xc5a5dbcf, 0xc67de183, 0xfd736f6f, 0x6531d7aa, 0xe9a5f41e, 0x84d1d85e,
- 0xbdf331e9, 0x47c0e5ae, 0xe6ed1df9, 0x49434efb, 0x933d2e2c, 0x0e9bb2a8,
- 0xf958fd31, 0x885d7083, 0x99d3def9, 0x4fd01b91, 0x5f5de5b8, 0x394f7bfc,
- 0xdfef987f, 0x77c93afc, 0xf95fe61a, 0x985ef342, 0xbad95102, 0xafaa521d,
- 0x579ef766, 0xe93f01e7, 0x147f8872, 0x068fa17f, 0xf5ddee19, 0x11e8f5f2,
- 0x7beec4af, 0xbf705168, 0x7d8497e7, 0x98ebe217, 0x40f4c5cd, 0x6e97cac1,
- 0x55873807, 0x2e800768, 0xf9993bff, 0x1122bfd7, 0xcdd01e5b, 0x3a9c612b,
- 0x2725ab24, 0x88f78e84, 0xce083e54, 0x99e9ed75, 0x5fc60c34, 0x5c39f2e8,
- 0xed486f60, 0x91bbe187, 0x81860a63, 0x5d0e771e, 0x35d603dd, 0x570a6e1d,
- 0x076736d9, 0x175c3a1c, 0x742cbf39, 0x7ab876cd, 0x2f40efb2, 0xdc7c7e35,
- 0xfcebdf06, 0x82fa6a10, 0x5f0c41f1, 0xf0741f00, 0xd4377085, 0xf1a43c75,
- 0xd8ffaf52, 0x97fba17c, 0xf805f25d, 0xc5efee8f, 0x715c4317, 0x73da82f8,
- 0xd9b9e1c3, 0x2c290b9e, 0xfcfccccf, 0xbe114729, 0xe60855ef, 0x76bd9089,
- 0xbe3bbbf6, 0xbf2f8c14, 0xb66361ec, 0x073c747d, 0x5ceb957c, 0xf90e4ca9,
- 0x2343df3d, 0x439fda02, 0x03b8a2a9, 0xa8debced, 0x7f1cbd27, 0xc020b8e4,
- 0x4b985dfd, 0x68760d9c, 0x6bd807a4, 0x2393ad43, 0x1d3b0f20, 0x7ec1b213,
- 0xcb8c702c, 0x32bff983, 0xb05be568, 0xabd2bda4, 0x6aade5e2, 0xeba57d87,
- 0x5bbc03c3, 0x5d5bfc7d, 0xd5ae3f8c, 0xd010f9d8, 0xe870b1eb, 0x099003eb,
- 0x332210e0, 0xa81d972d, 0x142dc3c7, 0x1c02d76f, 0x04fb0f14, 0x43f600d2,
- 0x2b4b4591, 0x67b03b01, 0xdb380244, 0x0391fe9a, 0xe1c9a771, 0x78051fdf,
- 0x5bfbeb27, 0x96fee35e, 0xedd6ded9, 0xd0ffdd21, 0x228925ed, 0xa0abb742,
- 0xa73c047d, 0xbdc0f4f8, 0x45beb0e0, 0xf53e786c, 0x95ea73f1, 0x8967971a,
- 0x9f3263ce, 0x19a44dc7, 0x2e9722e1, 0xe9471e5f, 0x63e39533, 0x491261f2,
- 0x427687ca, 0xfdc014a6, 0x4c902433, 0x15e299c7, 0x7c3127c8, 0x6328d373,
- 0xa426fe1d, 0xd5d3f477, 0x6375e6fb, 0xffce29ac, 0x7ec3cb43, 0x4dfc6e76,
- 0x3c173b3f, 0x90189fa6, 0x951dfd60, 0x7b03cecb, 0x2b0e1e18, 0x23b1d7f1,
- 0x58c79e5c, 0x3ce1f25a, 0xff3dbee4, 0xff7375c4, 0x07be7f9e, 0x53e8e476,
- 0xc63c8112, 0x2786a731, 0x28ebbee3, 0xef4af915, 0x06b3eab7, 0x49cf6107,
- 0x87e87dec, 0x15da3c28, 0xcb0d9f00, 0xfe3cced7, 0xe177f404, 0xf3624498,
- 0x5f154be4, 0x968f887f, 0x0ff17bf2, 0xd29ecc09, 0xfbf10fdb, 0x78b977a8,
- 0x93d28e7c, 0x1ac4c7fb, 0x5429e743, 0x74172513, 0xc9ca75d0, 0x7e5253b2,
- 0xdfc0fa67, 0x7e1f3a27, 0x57749e4b, 0xfb0e7ea5, 0x5eb62ef7, 0xc37f0392,
- 0x35d70cf3, 0xfd8123dc, 0x48a65d7e, 0xaf7198b4, 0x1fa7a957, 0xebd8f713,
- 0x07bfd932, 0x2a627b9e, 0x111e79e4, 0x2aac6531, 0x7cade3bc, 0x718b37a8,
- 0xf19ba7cf, 0x1ef85d7b, 0x887ff809, 0x574dc99b, 0x8ab98fe3, 0x4035c9f2,
- 0xc0ecc277, 0xc8e50142, 0x7bfddf4c, 0xcb47a3fe, 0x4ef8c4e0, 0x1d337f44,
- 0x8c533b5e, 0xd15d21fb, 0x7bb7ccc3, 0x57033ce9, 0xd97aefc0, 0xd77f0048,
- 0x83f583cb, 0xebac4cfe, 0xf4d55afc, 0xf3b00f74, 0xd49d3e74, 0xe8cdf183,
- 0x20f44fdd, 0x997a0ece, 0x19b826f1, 0x75d976fd, 0x633bc4bb, 0x67f47d2a,
- 0xa3210eba, 0xe4334806, 0x587394d9, 0x8a5bbe67, 0xf9e10976, 0x6df5e6ff,
- 0x24c778a6, 0xdd5da750, 0x3a8b7f4b, 0xb9f75bbb, 0x95a91d97, 0x952c1d60,
- 0xc63d3256, 0x1e1d78ed, 0x42ff9d33, 0x44fe11ca, 0xc0f999f0, 0x68aee70c,
- 0xeb86b27e, 0xfb4f7e81, 0x72b9fef4, 0xe8799c6a, 0xd085b8f8, 0xfbaf38f5,
- 0xdb8e71eb, 0x4fe7ffc8, 0xa013fc4e, 0x99bc9135, 0xd76e66e9, 0x0c2947f5,
- 0x00658050, 0xee2193ec, 0xd2879474, 0x60d10a8b, 0x9db7ba5f, 0x379b1a7c,
- 0xe40af93a, 0xf61e15b7, 0x2dbf112c, 0xdf1228bb, 0x93be0eb0, 0x00731f1b,
- 0x6a96eddf, 0xf7f45e1d, 0x5324d5a7, 0xacfc4d3c, 0x073c16f8, 0x102162de,
- 0xfe149b5a, 0x19c400e2, 0xcc128eaa, 0xef0e2f07, 0x3d3e012b, 0x9fa33528,
- 0x908176d5, 0xceec62c7, 0x038d70c6, 0x34c6b2ec, 0x50e99e76, 0x9be4310a,
- 0x7d33711e, 0xdcec78dd, 0xbb4e2d54, 0x79f8cc98, 0xf2d2d13a, 0xd74b3fe9,
- 0x3f00fe51, 0xe30ba7b8, 0xef051324, 0xb76069eb, 0x9feec6dc, 0xf91a6b6c,
- 0xb7851a7a, 0xd414cef5, 0xd71a9333, 0x84a1e3de, 0x0c3d7d08, 0x16cfb79f,
- 0x7be85bbc, 0xeb17aaa5, 0xd172f3a5, 0x4df91bef, 0xa193e98f, 0xfd197afd,
- 0x52e2499e, 0x6755e209, 0xf0028533, 0x2d08f727, 0xf2f7e0ab, 0x38d8d302,
- 0x01e813c4, 0x933be9fe, 0xdfc50c7b, 0xfaf55174, 0x205dfc00, 0x56dff262,
- 0xcfbf3aee, 0xce57db4a, 0x733f3010, 0x049b2792, 0x74a7f862, 0xbaf3829d,
- 0x0c519c39, 0xccbd3d7c, 0xc22c4e78, 0xe519c9ed, 0xdd8c120e, 0x283c1527,
- 0xedec87d7, 0x5cefe2b7, 0xe604c936, 0x0df9cba7, 0xce67df9c, 0x6ef861ea,
- 0xa776611a, 0x7237572e, 0xfb81bbf9, 0xb2f9b7cd, 0x1397e30d, 0x81fd0f66,
- 0x92044fb4, 0x3cb32794, 0xcdeda9a2, 0x2f0edeef, 0x8047bd89, 0x9071bc3e,
- 0x9715efc9, 0xc8be46ae, 0xc780bc14, 0xfb635e29, 0xe74ca34d, 0x6bf24d14,
- 0x20330fd6, 0xacec4a3b, 0x307d7427, 0x219449a3, 0x88a3341e, 0x62ed19e2,
- 0x95dedda3, 0x949918be, 0x525c5f40, 0xa433041f, 0xb0f8be93, 0x8be97bec,
- 0x32dba957, 0x36f5ca8a, 0x21f46f5d, 0x4c6f407d, 0x009feb12, 0xeba36a3e,
- 0x1f0e35a6, 0x1e8eebe9, 0x72a52807, 0x0ce07a8c, 0x749e2fcb, 0x86048b31,
- 0xa201c475, 0x25da847a, 0xd2f638de, 0x619e777e, 0x57aa23ff, 0xb912ec62,
- 0x25db87f0, 0xaa3da893, 0xbd7c0014, 0xc252be11, 0x90a596e2, 0xc3f102c8,
- 0x0e302fcc, 0x7f512554, 0xa7e7d716, 0xffa39e99, 0xe43b5212, 0xe8af6cc3,
- 0x3c09e871, 0x97e6617e, 0x16f23c68, 0x3a42e319, 0x3e02949f, 0x116ffe41,
- 0x2ba09f71, 0x37c7d1be, 0x14c44bf3, 0x5f92ea1f, 0x577ddcb8, 0xe6ed397e,
- 0xa4fea1f1, 0x44f8777f, 0x5f9d0fe7, 0x9bcdebcc, 0xa25138a6, 0xb09fe6f5,
- 0xbc4cf4de, 0x483ebcde, 0x95debd46, 0x992e735d, 0x6e89f9e9, 0x75773b0f,
- 0xd8270ce5, 0x59921335, 0x6ebe817e, 0x1b5de345, 0xdebc9f18, 0x7d824732,
- 0x1fd02aa6, 0xd0741db9, 0x5f3ac5e3, 0x60275b2e, 0xd732747c, 0x2c4dad5f,
- 0x5135585e, 0x8fd1c20c, 0x4f63f092, 0x6fbb3ab0, 0x14efa746, 0xd24527ce,
- 0xff7e093e, 0xe0af26f4, 0xc693b885, 0x35538de3, 0x668de301, 0x44d7b5bd,
- 0x1fbce9f7, 0xbbe0bff0, 0x2084ca9b, 0xfd6693f8, 0xb322fd36, 0x53d93a2f,
- 0xccd89f7c, 0x7326572f, 0xf497d0fd, 0x15da57fd, 0xddbf92a3, 0xefbfd0ae,
- 0xb065ce8a, 0xc0ffa0a6, 0x3b0193ee, 0xdd7ce81e, 0x2dfb0945, 0x49da3649,
- 0xfc14ce17, 0xfe4f7d0a, 0x3a1ef9be, 0x1aba7cf3, 0x17f750bf, 0x8fa0ffb8,
- 0xcec4837b, 0xa7d79bf7, 0xfe23d72e, 0x775e999d, 0xb5e31b24, 0x3d745d3a,
- 0x5cef09dc, 0x5ba2274f, 0xd75a7a57, 0x3d6aff87, 0xafaff7ad, 0x66b8fa23,
- 0x7fc89dfd, 0x9af1f5d4, 0xdb8c16cd, 0xfa7ee78c, 0xfe3f1e78, 0x7ee7b705,
- 0xdffccc99, 0x166d2fb6, 0x32436f58, 0xec0b27db, 0x69fc6273, 0x07665efb,
- 0xbe2a5cd9, 0x6220a0f7, 0x11c1e47c, 0xd4d7d416, 0xf3061a07, 0x19098a96,
- 0xbdbdfb04, 0xbd6f7ed8, 0x7d472914, 0x9c0895ef, 0x8c5d13d3, 0x1fdc1e1f,
- 0x7ffa1db8, 0x968193f0, 0x474f8c1a, 0x1a5ec19a, 0x7ee12059, 0xc5558a59,
- 0x936b7678, 0x6a3bef15, 0xf6bffddb, 0x97cfd0c9, 0xe52e0bc4, 0x746b26c1,
- 0xc7f40abf, 0x0888f124, 0xed6d1cf9, 0x1b03ef04, 0x02522b37, 0xd278d97e,
- 0xfffe035c, 0xc1e58518, 0x6cd4f19b, 0xfbcca75a, 0x2c4d255d, 0xc5c4a5ff,
- 0xed3a5ff3, 0xefe33457, 0x04904f26, 0xbce90d6f, 0xc992f15f, 0xefd8e9df,
- 0xd15fb04a, 0x77d1f4c8, 0x0318afdd, 0xde7ca034, 0xd701cba4, 0xbec1244f,
- 0xed8576c5, 0xcdbfb577, 0x6993d3ed, 0x5d46e371, 0xdeec5fed, 0x7dc1a49b,
- 0xeff9db23, 0xdbdeec6c, 0x13f3534b, 0xd2df9fbf, 0xd8d30c5e, 0x84b37f5e,
- 0xbe3c73f9, 0x9a0b8d1b, 0x90e9cbf1, 0x6b481f68, 0xf5041cf4, 0xe7df7095,
- 0xaae18a82, 0x5d4f8aef, 0x4f1fb66e, 0xb7ef80d2, 0x01a5ef1f, 0xdc79fb1c,
- 0xbcf56bd0, 0xeec2f605, 0x7092e763, 0x54d1583f, 0x53da4ff0, 0xae765e6c,
- 0x2841c992, 0xf610606b, 0xeff0f7ab, 0xbfb527b6, 0xec5a7579, 0xbfdb0e7e,
- 0xd7d9cfd1, 0x47f30428, 0x3f961602, 0x0cdfc662, 0x3b938f0f, 0x2274faf1,
- 0xbc62a9a7, 0x096f503c, 0x3f3057cb, 0xce4c3c97, 0xfdfe2fff, 0x80006684,
- 0x00008000, 0x00088b1f, 0x00000000, 0x5bbdff00, 0xd554780d, 0xdceefe99,
- 0xf26677b9, 0xfc999933, 0x4dc2fe10, 0x00908102, 0x7e100843, 0x502021d4,
- 0x4540647e, 0x043abaec, 0xa1bf9085, 0x56d3ebb1, 0x4126e1f7, 0x27d3e08a,
- 0x6796dd6d, 0x57067db5, 0x3b1254b6, 0x770704c1, 0x08a00ec2, 0x80a0db54,
- 0x11dae3c2, 0x2486a229, 0xec56bb0d, 0x3befdd6e, 0x6664dce7, 0xecfa5c18,
- 0xf8728376, 0x9cf739ee, 0xfbdf7cef, 0xb3739dfd, 0x330001d3, 0x68776e01,
- 0xdb00d900, 0x8c802f64, 0xde0820cf, 0x16e91bf4, 0xd305d609, 0x7ae77688,
- 0xa9dfe0a7, 0xce1a6ba6, 0x2cb0ef91, 0x7a448f35, 0x42d1e986, 0xc639e7a4,
- 0x699e7a72, 0xf806e286, 0xba5bc867, 0xcfc00e68, 0x03875e9c, 0xd257e9d7,
- 0x00194876, 0x65049366, 0x528ed859, 0xec373803, 0x65ac0152, 0x3c1daeb8,
- 0xaa40174e, 0xd21b7405, 0x54fb360d, 0x1e95f1a0, 0xd11a4b6d, 0x87c43d00,
- 0xa5039a39, 0xd336bed8, 0xbe00b304, 0xadc1fb4d, 0x1ef8aaa4, 0xc5a8ffbe,
- 0xfb81ce37, 0xec46b7ab, 0x1ff6015a, 0xa40473ba, 0x6c1d7ed1, 0xcf2f25bf,
- 0xc60285cb, 0x33ffe157, 0xf8c9655f, 0x75f0a6da, 0x2c940f7a, 0x64bf5c04,
- 0x1a5f8a1c, 0x59994fd6, 0x416dcf63, 0xf49f3d00, 0x9095c9e0, 0xeeaa716e,
- 0xce34f99d, 0xb6f267d0, 0x21fd4145, 0x69aa725f, 0xce51e90b, 0xc0e96d30,
- 0x89874ef6, 0xac58bfcd, 0xb7903003, 0x8e0df51a, 0x5335bc81, 0x96fa4d38,
- 0x4881b2e5, 0x9b7f5239, 0x871e7eee, 0x0f8198c2, 0xddfa471e, 0x3bdc4a07,
- 0xc290be91, 0x502eb1e5, 0x7a4512d0, 0x363025ba, 0x9d397c82, 0xf7c92f3e,
- 0x04c0969b, 0x2db4a786, 0xe4bf34e9, 0xca0ef801, 0x3d104243, 0xf16efb80,
- 0x0216a680, 0x1ce7808c, 0x90004b97, 0x332af82b, 0x2560bad9, 0x8737deb9,
- 0x1758d5cb, 0x1c856865, 0x3f82a7e4, 0xf5c0f837, 0xc1beb47d, 0x301f10cf,
- 0x153971c6, 0x4857cfd8, 0xd33cd1f7, 0x0a321e50, 0xfff3d705, 0xa0b014de,
- 0x3ff8fdfc, 0x325f2fd1, 0xc9897405, 0x2cfd6d3d, 0x33ad88f6, 0x9966ade7,
- 0x9fe3ab31, 0xecd44c59, 0xbb543ca7, 0xf748ec02, 0xad462f98, 0x37f61d62,
- 0x9cf91c6e, 0x7d9fde27, 0x8d30b7c2, 0xc7e2f7da, 0xffa783cd, 0x15fbe320,
- 0xe5019010, 0xd09a2732, 0x31fe5a1f, 0x4aef3fcd, 0x77bff3fc, 0x7db167a4,
- 0x5f51828d, 0x77227db1, 0x95a35eb8, 0x66f837af, 0xd3e10641, 0xa2d9466c,
- 0x864d55fc, 0xa2bf6c0a, 0x3a003b9f, 0x0b38e2b7, 0x56adc1c0, 0xe3394ed6,
- 0x84eb40d8, 0x269022b6, 0x35babc02, 0x1d86b597, 0x0f03394d, 0x7598d4c1,
- 0x390dde04, 0xe5c7be0e, 0xe93a3d38, 0x5691f3a7, 0xd010284e, 0x5730e586,
- 0x5d106bc8, 0xf079e906, 0x475b9a4a, 0xbbc9d67a, 0x4b4fb265, 0x98b409ae,
- 0x14b4d9fd, 0xd30d26d0, 0x715c93a9, 0xb8f42cb4, 0x9e7f66cd, 0xf4f742e1,
- 0x333ae2e4, 0xeee93ac4, 0x41f37151, 0xe8c4ff00, 0xe2d755f3, 0x67ee1213,
- 0x0af55a46, 0x454657da, 0xe5fcdc41, 0xbbcbc66f, 0x091ebc0c, 0x8fbf765f,
- 0xb3fbe3fc, 0xcc7f60ce, 0x2b488af8, 0xfbc547c3, 0x5ee7cff1, 0x6f3ba78a,
- 0xc99bb7a6, 0x74fea613, 0x2e5fd67e, 0x5e27a74f, 0xe34b999e, 0x8ded99e5,
- 0x7588e797, 0xe91af2f1, 0xe8c7978b, 0xfd71c9ea, 0xc594b763, 0x33bee3d1,
- 0xbe7c6e37, 0x1747195e, 0x371658ee, 0x9aeb427e, 0xeee27a38, 0x2f8dc66f,
- 0xf5c5540e, 0xf9abec97, 0x253ff48b, 0x9e3718d8, 0x1afa6cc4, 0x7d0b4ffd,
- 0xbfbd6e2f, 0x9dfffe96, 0xcf7e8ff4, 0x7a44bfd0, 0x42fa499f, 0x1c36593f,
- 0x06b89c9f, 0xf8674bf9, 0xda12eb8d, 0xe9a95ea5, 0x0cbebcc4, 0xf7d82ddc,
- 0xc895ec8c, 0x51468dbf, 0x6c6fd09b, 0xf9354133, 0x4c981ffd, 0x86d3790f,
- 0x94e4dced, 0xaacffcd8, 0x14b8a660, 0xe94d6e3b, 0x4da338f0, 0x78d89a77,
- 0xd37edfc3, 0xd144b5a2, 0xb9974e9f, 0x9b3f453f, 0x707f44ee, 0x21427a41,
- 0xe964a937, 0xc594af8a, 0xd8bc879d, 0x6a4b213a, 0xd86336c4, 0xa15f6bbf,
- 0x81a82e52, 0xfe213fbd, 0xbdeec94f, 0x486fffc8, 0x17492320, 0xef3f166e,
- 0xa696fc37, 0xf8633865, 0xe2334c1a, 0xf14196ad, 0x42e1f073, 0x3fced7e6,
- 0xf50b4e88, 0xfbe55e7f, 0x115fc631, 0xe153ed7e, 0x9fc97ad7, 0xabfb8659,
- 0x5d38fcf7, 0x4fce79c3, 0x18c1a582, 0x390b1539, 0x2c1c1981, 0x3ae3ccee,
- 0x4bb350bb, 0xdff388d9, 0xa16c2ef7, 0x13fbee75, 0x6f7d896c, 0xfe6153b6,
- 0x6653b671, 0x726c5aed, 0x316bce51, 0x18cb39a6, 0x5db0911d, 0xb2140275,
- 0x7cbed5cb, 0x0ef28485, 0xe176cfb8, 0xd1480b92, 0xe03ddef8, 0x9fffc855,
- 0x9d3eb07b, 0xf3cd0dc6, 0x117713c6, 0xa2a2d73e, 0xd7792f29, 0xe8392ba9,
- 0x936e060f, 0x75c49c58, 0xfbdcf4ac, 0x2927e8c0, 0xdf039cbe, 0xafa8b3d5,
- 0xf366e035, 0x7222f319, 0x05ccfce3, 0x38992215, 0x12c17e8f, 0x347c8bd8,
- 0xfa825e52, 0xc11eec69, 0xcd7f5fe2, 0x827fdb1f, 0x1d1a1ee3, 0xfaf14b1d,
- 0x8a9fcd42, 0xeff7cf48, 0x7d434196, 0x77c5377e, 0x90c0e117, 0xaf87f9c3,
- 0xc63f53a5, 0xd867a65d, 0x65ef716f, 0xdecfdbf2, 0x73adc633, 0xde9bb82e,
- 0xd0140a83, 0x67f11b9c, 0x496814b4, 0xe06a352e, 0x3e43dfe7, 0xe6c294e1,
- 0x59b2f033, 0x5f31a5e0, 0x978b111b, 0xbc21f4c6, 0x71ab7cb0, 0xa6ecccaf,
- 0x0016dbb1, 0x8159cb94, 0xebfeff3b, 0x234f7d2f, 0x1f3de782, 0xc4346e21,
- 0x3711efc9, 0x8fbdc61a, 0x3f443711, 0x886b7b2a, 0xfe9e8fdf, 0x79a3eec8,
- 0xbe35b9ef, 0x7381a5fb, 0x3df2437f, 0x083ef1c9, 0x5f98e783, 0x28d62cef,
- 0xf0785baf, 0xebca39fa, 0x9a2d3a1a, 0xceabe905, 0x6967f1e8, 0x680921fc,
- 0xc6c4437c, 0xa743559c, 0x7f61b014, 0xfb63a84d, 0xda6ba468, 0xd8539756,
- 0x7221dbf0, 0x901ff507, 0x7fd8cd02, 0x7b5eab79, 0xf0b87509, 0x6997ebd5,
- 0xf957bede, 0xeab657bc, 0x9013cc1b, 0x03feb03e, 0xd3aeaf9a, 0x6fd43602,
- 0x8ea2339f, 0xa43af5a6, 0x1d57ad20, 0xf34aa1fc, 0x7ab0bf57, 0xb539a53c,
- 0xc6aa9afb, 0xbebff8c7, 0x0d55a783, 0xf9dd54e5, 0x5c62c5c3, 0x015f0f39,
- 0xfec63766, 0x369a0737, 0x2ee36398, 0x7b275bfe, 0x2df77e12, 0xe175ff21,
- 0x271216c2, 0x67ae95fa, 0x7657e625, 0xb872bf33, 0x85fedffd, 0x8bf43bd6,
- 0x281b8409, 0x837935bf, 0xb1716757, 0x5703ac41, 0x9ea951de, 0x2e54e869,
- 0x7c65e7c7, 0x77a735fc, 0xf92673af, 0x85b49855, 0x79f13bd5, 0x25940ee2,
- 0x7e7ae1e5, 0x390fb30a, 0x8f5d406d, 0x069f7cfc, 0xc7663f20, 0xf4855a80,
- 0x5718970e, 0xcdec0d60, 0x3ebf91bf, 0x67ad99a7, 0xac5f002d, 0xcfda30df,
- 0x82b1ff44, 0xd528d54f, 0x9515da17, 0xf910db70, 0x7f90d544, 0xc5c3e87f,
- 0x7def249e, 0x6295fc22, 0x29ef56f2, 0x468fb61f, 0x714a39a9, 0x44d0f1aa,
- 0xd67a674d, 0x2ebf8ca3, 0x58fb469b, 0x5993f078, 0x3ef998d1, 0x578c7c43,
- 0x5f86e986, 0x2155387d, 0xe1fcbdb9, 0xcc7a7354, 0xaad2723e, 0xe0f94903,
- 0xbb49e2f1, 0x5bad0af7, 0x35a2d07f, 0xdcdb7c33, 0x3877c211, 0x44668dd5,
- 0xcb9b56f8, 0x3f7df163, 0x2c21bbe3, 0xd0e911bb, 0x6bed5a10, 0xddd3e362,
- 0xb43906a4, 0xc99c2740, 0x23c32f0e, 0x37ae27fc, 0xfe30e28b, 0x756a3fa0,
- 0x78477efa, 0x55e9a731, 0xdaf898e6, 0x35e68a60, 0x5f3fa44b, 0xfb1882eb,
- 0xad74d393, 0x99e48b39, 0x61b596e9, 0xae2629fd, 0x6a2d3e97, 0xdb1c5177,
- 0xbd91f38a, 0x93b13e44, 0x3687b7fc, 0x3beec958, 0x47ae0e9c, 0x481cd755,
- 0x877a09b7, 0xbb26adea, 0xc29391da, 0x2e31b5eb, 0x09ffef86, 0xaf647daf,
- 0x3e028eb8, 0x09f77f56, 0x058df5bc, 0xf7297fe6, 0x94c99c23, 0x199215ef,
- 0xce341cf9, 0xbdaa6a1f, 0x87976b14, 0x7f1373ee, 0x1f7f0a4a, 0x135e3872,
- 0x7175cdd7, 0xaa693d9c, 0x13105d6a, 0xe5c71387, 0xc399b8d0, 0xceb30072,
- 0x697001ce, 0xfefc324f, 0x776959c2, 0xde5dfe91, 0xcd87e449, 0x51e118c4,
- 0x81f29353, 0xd95cb3e3, 0x2e4de3c3, 0x554f5b07, 0xeb920e7c, 0xad39397f,
- 0x67265ea8, 0xec8d6c34, 0x057f6878, 0x9b3b526a, 0x91def82e, 0xc4f7af1f,
- 0x38c4d371, 0x56e7a4c5, 0x65879f11, 0xdafd3766, 0x31bfd300, 0x9d723fae,
- 0xed7c3feb, 0x79d90f2e, 0xcf865afe, 0x5c597f4f, 0xbbccc726, 0x853959ce,
- 0x12e793f6, 0x5cf45078, 0x2ba47be2, 0x733f1f7e, 0x62b8677a, 0x4c601fce,
- 0x04e12dd6, 0x16e07d44, 0x83eb0ef1, 0xb57c6649, 0xe4dc521f, 0x1e443bdf,
- 0xc32f066c, 0x35b82a49, 0xe07af756, 0x7f70f3d7, 0xb04c472d, 0x1d3b4913,
- 0xf3628c72, 0x04d8b079, 0x8a326cbb, 0x4b158f08, 0x323212bd, 0x9ae25fec,
- 0xc86d8df6, 0x65d021ef, 0xd7c73f5e, 0x3c91e0c1, 0xfbfd6c52, 0xd5adcd5a,
- 0x5af9cfbf, 0xeb13cec8, 0xd31139df, 0x16e3357a, 0x96d7e0ea, 0x1f83ad25,
- 0x53d7c574, 0xc634bb0f, 0xc712705c, 0x12923061, 0x3028e7e0, 0x845c7083,
- 0xedfa84e1, 0xa555bc39, 0x275649be, 0xf4d733c6, 0x418c76a7, 0xe5cf1b3b,
- 0xfd0b7440, 0x8df3ca3b, 0xb5fabaa1, 0x44ff2cc9, 0x7ab3247f, 0x497821d2,
- 0xe6395fd0, 0x7118bc49, 0x91e5d5c7, 0xc9da5fe3, 0xb4bbb6ff, 0x067e92df,
- 0x7940ca4e, 0x551ccd9c, 0xebec499d, 0x98b3e520, 0xe2e4bc8f, 0x921ad67e,
- 0xdf5c013c, 0xe28079aa, 0x98e1cdbc, 0x59d8c72e, 0x85c78b95, 0xf217e3fa,
- 0xaf23cc54, 0x97b4de9a, 0x5d75fce2, 0xcc74ec07, 0xedfe7b53, 0xb4147459,
- 0x4edbecc8, 0xb4a9fb76, 0xf94ac8a7, 0x54c08ee1, 0x52304f92, 0x77714190,
- 0x7374198a, 0xf8fc8dd9, 0x50a6e377, 0x33bb0d86, 0x3c253b59, 0xa7e51363,
- 0x2fdf08fe, 0x0ba0a1ad, 0x8c490e2c, 0xb8b50bee, 0xbfff3e68, 0x3f228f76,
- 0x9f9b3fb5, 0x45f8be2f, 0x0cdf7f09, 0xacff1a66, 0x1ef029cb, 0xd479d130,
- 0xd58e717e, 0xc6cc85f7, 0x094feb19, 0x881d902d, 0xeb48d283, 0x164e7651,
- 0xca7cb0b6, 0x797002f6, 0xa3cf3184, 0x4bc39cf3, 0xbf51e280, 0xf612dc13,
- 0xb00ca7b7, 0xdba067fc, 0x912f3da2, 0xec815adc, 0x75e55dbd, 0xf602314b,
- 0x73f0da40, 0xf85b3d63, 0x44e674a7, 0xfc50f0b8, 0xe15b99b3, 0x7958b4b6,
- 0x877933a7, 0xa6c80f29, 0x34a62275, 0x77d1cfca, 0x1af8cf3e, 0xbad813e6,
- 0xccc59f06, 0x03abb7cf, 0x62cf1f97, 0x0708397c, 0x84f9c0c5, 0xfc8d44f0,
- 0x61e1cd9c, 0x3439b0fb, 0xc8dd2eb7, 0x262a7f97, 0x3f3f6860, 0x7b218668,
- 0xa7f6fb26, 0xb456d30c, 0x8e02f685, 0x3c37d06b, 0x0c7e68b5, 0x62a68e4d,
- 0xaed3fdf8, 0x1b6d4f8d, 0x748dcec3, 0x8a9ff519, 0xf68bba6d, 0xbd0aedc9,
- 0x8cbb27a7, 0x728dc1cb, 0xfef2b54a, 0xf388f1a1, 0xf8d3a234, 0x91c5b738,
- 0xd99f2cba, 0x18bd900b, 0xa5b7d9f9, 0x503be5c8, 0xf43fbdb5, 0xbee29466,
- 0x1f474d7a, 0x9f71c36b, 0x45160fad, 0x7d50fea8, 0x5f3e13ef, 0xd76abf79,
- 0xedbbf214, 0xf9057b8a, 0x23fea89f, 0xa8bf0796, 0xec633b68, 0xe40cc60e,
- 0xd7137e10, 0xfe6f9ff1, 0xfdb9e511, 0xaacd2487, 0xc81dff91, 0xc21bbe23,
- 0xd7e4ab1f, 0x643e87fd, 0x9913ed79, 0x5eb42bbe, 0x2169a845, 0xb40e75c9,
- 0x2edf90b6, 0x3041f911, 0xc193fb97, 0x37cf4533, 0x9ec1e8c5, 0x0edc7129,
- 0x9c51c6f8, 0x3d7b0b0a, 0xb627f54c, 0x2fee475d, 0x44bbf9a4, 0xd7bc6c7d,
- 0x93474704, 0x35e19bdc, 0x9dc50ed6, 0xe1297980, 0xf59ce4ac, 0x78cc4f21,
- 0xbf3f266b, 0x02f58ab5, 0x133fbe99, 0x2e47b5bf, 0xe7da76aa, 0xd51e60a5,
- 0x93ac4195, 0xc8fc491d, 0xd826fd90, 0xa03cdf93, 0x15ff78d2, 0xf5057e60,
- 0xf5032dbd, 0x685cffb7, 0xde7c7af2, 0xa0c93a85, 0xaf3ce17c, 0xef14bb13,
- 0x74df1a68, 0xe4a9f3f6, 0xa82806c7, 0x779f7fe1, 0xb9238ed7, 0x532bfe21,
- 0x803acec8, 0x4ec335f9, 0xf14ec94b, 0x7fc252fd, 0xccc5d139, 0x3dabb72f,
- 0x765d98cb, 0x12ec8099, 0x01eccff1, 0xb8a0eff1, 0x7b40ea5c, 0x644fef60,
- 0x63dede76, 0x167cb0f2, 0x4604fafd, 0x744dde57, 0x0722cf7b, 0xe21373b3,
- 0x35ec8cb9, 0x13cd9472, 0xa634a004, 0xec6f025c, 0xcb954139, 0xf86cf0ce,
- 0x7ec22dcb, 0x0cb49383, 0x5523ee37, 0x23ece396, 0x5a725e26, 0x7fc7d3c4,
- 0x9ea793fc, 0xa78f4f99, 0x10e138f3, 0xce9b5271, 0x22a3fefc, 0x3ebe3556,
- 0xe51b5577, 0xacc96fe5, 0xa738b0ff, 0x1c9c0888, 0x1414e715, 0xcfd43437,
- 0x75fce26b, 0xf41ed226, 0x5b3cb3a3, 0x556e5216, 0x18f5b4b1, 0xc1bd73b5,
- 0xce329485, 0x4c73d75f, 0x425e66e1, 0xfa3cebf8, 0xf933128d, 0xcebcf3bd,
- 0xe072fceb, 0x0e511783, 0xf9461d8f, 0xb8538927, 0xcc3f861d, 0xee4346b3,
- 0x92fdfd8d, 0xf97e47e1, 0xfa43aa0d, 0x1a61e53a, 0x020363e3, 0x9955e89b,
- 0x474a78bf, 0xf4c83ec6, 0x7944c9ac, 0x35bed9ca, 0x9cef9499, 0xcc8732fe,
- 0x45ccebb2, 0xaa773f56, 0x4fc2129e, 0x9c960167, 0x7b7a7049, 0x51f4c2a6,
- 0x673f896e, 0x84c7da31, 0xb0e9141d, 0xb1f5624b, 0xfd5008ec, 0x547b29dc,
- 0x80ae83cc, 0xf91e76be, 0xf81e711b, 0x0f1f8808, 0x6cfd41fe, 0x9423e414,
- 0xdadc60b7, 0x77128cf8, 0x2de4673e, 0xb07bc675, 0xdaf844c5, 0x1fe09614,
- 0xcfd51651, 0xa3af8fc5, 0xd9e705bc, 0x7c73da1c, 0xe6b5ea34, 0xca7e8485,
- 0x79b9d85b, 0x75a3d590, 0xfe5c4a6d, 0x38a658f2, 0x42842c0f, 0x57105fca,
- 0x66284fcc, 0x1c416138, 0x6df6c84f, 0x6fdf3b20, 0xff42f2e2, 0x0373ecca,
- 0xb79f15e1, 0x34bf7257, 0xcc021570, 0x8f05f67e, 0xb9df91d9, 0x5a6ef96d,
- 0xf799ae63, 0xf3e50dcf, 0x40730d7b, 0xa90a8d5e, 0xb316f8f0, 0x9cf75afc,
- 0x54b945c9, 0x0e097f0b, 0x59b5fe7e, 0xe45abeec, 0x4a039b77, 0x2fcefcd2,
- 0x4081cdc6, 0x69bbad0b, 0x47cec49f, 0x8fc5f76b, 0xd5390bf7, 0x9c7d3eed,
- 0x83eafd8e, 0x4e42fd09, 0xf3fc50fe, 0x78727c03, 0x1e5390d6, 0xf373b1e4,
- 0x6756b713, 0x7cf0a67d, 0x8f316de3, 0x38161fd1, 0x906dc06a, 0x7202eb7e,
- 0x2d547080, 0xf79e76e9, 0xdc7ada42, 0x060306df, 0xb941fe1a, 0xb4e42c3c,
- 0xed87e041, 0x7fafdf1f, 0xbdd00a4e, 0xc74fc3d3, 0x5e035ff3, 0xdf3e3475,
- 0x952df9d8, 0xf112f5ce, 0xb0a6dd56, 0xc846b7fc, 0x355f1127, 0x5569f843,
- 0xe225be29, 0xdd27c1ab, 0xb79e7f84, 0x37f96fff, 0xa6235cf4, 0xec2255a9,
- 0x1ff6a89c, 0xddaeb724, 0xfb435f7c, 0x4bfbfb11, 0xd0de75f7, 0xcc9864f7,
- 0xf334bdf4, 0xf8a5eb16, 0xe543bb7c, 0xe6683376, 0x9e06cae7, 0x2c5fdf12,
- 0xbb25f5f2, 0x357ade79, 0xe74ecd74, 0x833dfdc4, 0x69ad6076, 0xa247c529,
- 0xa5f8c7c7, 0x5d79324f, 0xa3f73dbd, 0xbf3e501f, 0x637143a4, 0x637507a6,
- 0xf1c52f15, 0xe7afb1ba, 0x2bad8f8c, 0x1d25f8c5, 0xe8db348f, 0x9297e23c,
- 0x3fb2cc9b, 0x894777fc, 0xf724dbd6, 0x78ff7c04, 0xe66fe0cf, 0x53725e91,
- 0xfe7cd167, 0xda4b3bee, 0xfcfe3e91, 0xfd6c770c, 0xf7c5dc79, 0xc2ac64b7,
- 0xa8ef6ae2, 0x415a7fd4, 0x3d9e85e7, 0x5f7bbecc, 0xfb25597d, 0x20976fef,
- 0x9e3a1717, 0x1d25ec7b, 0xf07bdde5, 0xfac94ab4, 0x6ad3cec2, 0x85f26bf4,
- 0x458e58ab, 0xab6a79d8, 0xb78f754a, 0x946af7eb, 0x3e17a7f2, 0x3554e764,
- 0x3e53e794, 0xd01c9cf6, 0xbac79ff0, 0x4f09515f, 0x8c126d0d, 0x57ed8fc8,
- 0x41f93f58, 0xe36e3fa2, 0x69c0d4fe, 0x81a5c095, 0x55b70353, 0xd86cffc2,
- 0x86971c91, 0x9e08da9f, 0xbe70a3ed, 0xabd6da47, 0xd23d0794, 0x137e3f1a,
- 0x68d399d5, 0xa6e5c73c, 0x9bfdf1dd, 0x33a8f087, 0xefe89d3f, 0x1e04b24a,
- 0xf098a18b, 0x1aa91838, 0x7fdc4667, 0x1c66ba7e, 0x7947b924, 0x2377c453,
- 0xbe4cdebe, 0x2a6ba17d, 0x18ff45c5, 0xfe17d585, 0xc6a1ff31, 0x166665e2,
- 0xf0e2cbc7, 0x569e981f, 0xa22c8f84, 0xaf8256f5, 0x32bce48e, 0x7ca0ea9c,
- 0xdb944579, 0x25b0b2f1, 0x3f889010, 0x2b878b13, 0x708db821, 0xc2d87fd0,
- 0x955f29cf, 0xc204de58, 0x72126dbf, 0xbce424df, 0xd1b1eb09, 0xa883ddf4,
- 0xdd441bc7, 0x9ed279bd, 0x340254e3, 0x93bafe88, 0xe724ecc7, 0xcffdc065,
- 0x3ff720b2, 0x788cfe86, 0x18f76892, 0xfd241ea9, 0x402d86d7, 0x172c33df,
- 0x1b7967fe, 0x46e91ffa, 0x323fd03f, 0xef47e195, 0xc6277ce2, 0xf8ce86cf,
- 0x78b20bf1, 0xf2283a3e, 0x712caae0, 0xb6f4203e, 0x4b520062, 0x9a65be71,
- 0xb7b00eec, 0xfeb4cc7a, 0x4788a989, 0x5684ff9c, 0xa24be198, 0x8dfda34f,
- 0x7a0defc8, 0xe18b9d15, 0x35a3a0f8, 0x7f7eb62d, 0xebd78b2b, 0x9d647335,
- 0xef5310f4, 0x4fcb2aac, 0x377cef5a, 0x31bfc70b, 0xd3d3c366, 0xcf1deb63,
- 0xe3c2229e, 0xbc7f73f7, 0xf157be82, 0xd2ff71b7, 0x66f38157, 0x2c0efe50,
- 0x59b7f61f, 0xf8975402, 0x37544f11, 0x90bc212c, 0x3ba586bd, 0x2f582f09,
- 0xaff3493c, 0xdc3b2ba6, 0xc610eaff, 0xf57e9c69, 0xfc303fa2, 0xf7cf1c9d,
- 0x911b728d, 0xea307eac, 0x782f8686, 0x6f3c6a7e, 0xfd594730, 0x189610d0,
- 0x5e8f3b7e, 0x7e47cbcf, 0x98ffbbfb, 0x50db1eb7, 0x9db38f16, 0xf48bc195,
- 0xede7c91d, 0xe879a4d6, 0xb6971f90, 0x50697b31, 0x3f2c39a2, 0xe0f98439,
- 0xde37ac6c, 0x1bd594fe, 0x0f6d479d, 0xcab43cb1, 0x35f1ce37, 0x66826a7a,
- 0xc336cf96, 0x9e52d636, 0x6dff9b13, 0x52eff072, 0x48388a36, 0xeb8813f4,
- 0xf6f6388d, 0x83fd1bb2, 0x05ea6fe1, 0xbe8337ae, 0xa3749e7d, 0x7617a89f,
- 0x67ba5b53, 0x8968a53b, 0xb0bd5079, 0x59fccc27, 0x83cc4bdc, 0x6bc04ade,
- 0x2c29dbd3, 0x293fedcf, 0x184ce83b, 0x51f3fbe5, 0x7e61ef94, 0x1ce4905f,
- 0xcf8153f4, 0xd9ff715e, 0xf9332154, 0xd6f0e699, 0x8e509bc8, 0xa7fd370c,
- 0x275402d3, 0xa57e1c94, 0xbb507080, 0xdac5c70f, 0xc7d1ea1f, 0xf00a0fbe,
- 0x2a60a573, 0xfa31d3bb, 0x657e1ff7, 0xe9ade132, 0xb88b2fed, 0xa917ae7e,
- 0xcfe73759, 0xd7892568, 0xd78926bf, 0xa8e65dbf, 0xff2eea9d, 0x881bd921,
- 0xefa1abd1, 0xc08e040f, 0x8bfcebcc, 0x9ba31a59, 0xa61f1cc2, 0xfae2de6e,
- 0x8f39f96b, 0xa1bfd6c2, 0xf37112bf, 0x880ef135, 0x5f80c42f, 0xf3f86019,
- 0x7e31369f, 0x7307a7fc, 0x4ebee362, 0xff208ef3, 0xcc0754d7, 0xf902a49f,
- 0x3a67f45d, 0xdfcbcbd5, 0xea7cb1b3, 0x15aec178, 0xc8157fcc, 0xb1ebfe40,
- 0xc6266bb7, 0x598d8bc6, 0x254c3f32, 0x1652e439, 0x5f5f0cf3, 0xd619a1c8,
- 0x8e027388, 0xb9338fe7, 0xeafac15f, 0x89cf64cf, 0xe6add5f5, 0x16dd4dc5,
- 0xff6473a0, 0xcefb0b05, 0x4deef3e4, 0x2f877eac, 0xdfc9137c, 0x8d37cf80,
- 0x6f0ec7da, 0x3fcf489a, 0x1a79bc3f, 0x9a94f73b, 0x4e99e2e3, 0xbe52e5fc,
- 0xc3473674, 0xb3eefafe, 0xfab8bbec, 0x4ff1856e, 0xcb3c6c74, 0xefe7e6c8,
- 0xec6c47fd, 0x0282437c, 0x1f18038e, 0xe75d6f37, 0xa8bf2ceb, 0x589ec90b,
- 0x8def183c, 0xb171e6cb, 0x20e05b30, 0x9e987928, 0x175b783b, 0x53f1997a,
- 0x1e9904ab, 0xde14da9b, 0xcc5bcedf, 0x3a1f193b, 0xbfe274b8, 0xf9bfce83,
- 0xe73b08bd, 0x3ecc91c0, 0x07152706, 0x6bfd2276, 0x1d72847a, 0x3f80980c,
- 0xe4fbb0b7, 0x19851396, 0x13c1fb84, 0x8b25672f, 0x3dd26f1b, 0x54e5420a,
- 0x1243af3e, 0xf3652ffb, 0xe75387f3, 0xb53b3fb9, 0x993137c0, 0x92a1d35f,
- 0x9092e9d7, 0x34b2a777, 0x45dc7dd9, 0x31bedf31, 0x4fda29fa, 0xdd8d876f,
- 0xf93af5c7, 0x03c2ea79, 0x1499cd27, 0x99a53b7f, 0x276a4714, 0xbe88bbbd,
- 0x9cba4003, 0xe46d5afc, 0xac77bb10, 0xec58eb6f, 0x4747c249, 0x32dfc736,
- 0xe67df935, 0x3bff44b7, 0x7516cee0, 0xae132ed4, 0xc50acef7, 0x1de593b1,
- 0xe891b49e, 0x7e12ef87, 0x0a95eef8, 0x01de53cb, 0x16f7e14d, 0x95617efc,
- 0x0977b3f0, 0x22aabcff, 0x57be3fb9, 0x39fab3cc, 0x17ee9278, 0xc7e27b56,
- 0xbdf22bdd, 0xf361e035, 0xa134bddf, 0xf77de45f, 0xc1f2137a, 0x8b87e16c,
- 0x70fc88a0, 0xe903e310, 0xc6d8b1bd, 0x29f2ece2, 0x09e69213, 0xd2ffd1c7,
- 0xc42703f7, 0xfe860477, 0x65df8a9b, 0x91d4ebf1, 0x99392ff3, 0x4141b6ff,
- 0xe1b1fb92, 0xfdd865f8, 0xe2ef5c3d, 0xc1dea1be, 0x7ff43479, 0xd8a32b15,
- 0xff432d73, 0x7f73674f, 0xb6cfbb59, 0xb0bef625, 0xa38ce83e, 0x5b91a1fd,
- 0xfbf8c52e, 0x8c73815a, 0x73d8e601, 0xdf641790, 0xf4d9d9d3, 0xcb2f6b3d,
- 0x2c0771af, 0xf2bee17e, 0x2cf2bec4, 0xeae97131, 0x7149f5c8, 0x973fbc3c,
- 0x167ffdce, 0x5b148f6b, 0x07d5fd98, 0x6bdd00a5, 0x3db847d5, 0xb123dfd6,
- 0xcea2c273, 0x857bec23, 0xb7248bb5, 0x33b1bb87, 0xa3819fc4, 0xcf1e5655,
- 0xc90cbc0d, 0xfa88e04b, 0x25dfbe29, 0x9e227be2, 0x62cf4226, 0x8f3eff9a,
- 0xecefa6e4, 0x75a38a6e, 0x30a75fd3, 0x211c3374, 0x9bf2152e, 0x24fa7889,
- 0xf249d7db, 0xed71fac3, 0x54ff9c14, 0x8479c7f1, 0xd89b869f, 0x1d856fd1,
- 0x4fd34bed, 0x3baffc51, 0x0fd5ee20, 0x24a28714, 0xf2c01397, 0xcf675ec0,
- 0x1f9e46f6, 0xfaf57bb3, 0x0f7d8d88, 0x754e1f58, 0x6cee88db, 0x754c994a,
- 0xa7765864, 0xf3a2bd22, 0xdfaa22f4, 0xeff39457, 0x01d41a3c, 0x3ab68796,
- 0xbf89277d, 0xb8a6ee95, 0xcf8374fb, 0xd13de19b, 0xe1245dcf, 0xfcf5ff64,
- 0x972145cf, 0x72d793c6, 0x9d7e1326, 0x5365dfbe, 0x45fd793c, 0xfcf6ae95,
- 0x9c595f93, 0x8d38d1a9, 0x76d95b8d, 0xe31d1b64, 0xcf4ffc1a, 0x4efe3076,
- 0x2c318129, 0xb5bd2cbf, 0x0e9a4bef, 0xf29531bd, 0x2723bee9, 0x3831aaa7,
- 0x7f446def, 0x4d7f449d, 0x6bf61260, 0xad24ad66, 0xb70ef911, 0xb1f77f67,
- 0xe85f3a1c, 0xa52e3b25, 0xe29dacf6, 0x3bc77d64, 0x779409f6, 0x98d6f174,
- 0x66586aef, 0x2d1cc0e3, 0x963d37ba, 0x7f1927bf, 0x1e7c8357, 0xddd16880,
- 0x5bfb6253, 0x40fdaffe, 0x03f30e7a, 0x603f38d1, 0x7bab09c8, 0x8799d59d,
- 0x9e9eec2d, 0xbf625bee, 0xe1ce2acf, 0x1636697e, 0x73af643d, 0x90b99ee8,
- 0x3c333352, 0x2219b440, 0x07dd1766, 0xddfe6447, 0xe7e618da, 0x67f58967,
- 0xe847239b, 0xe239cdbb, 0xf42e727e, 0xc3b771b0, 0xe03d6b00, 0x095b5330,
- 0x5856d66e, 0x6ca9cb23, 0x65060d2f, 0xc7247fd2, 0xe56cbcec, 0x4c90f2bf,
- 0x3372c3df, 0x1e4365c3, 0xf163dd32, 0xf712ffef, 0xf1c39953, 0xfdc3db38,
- 0xf416a50f, 0x040566dd, 0x6df9fdd9, 0xe8f71510, 0x0f31f7c9, 0x37ba37eb,
- 0x99d30dbb, 0x008f2614, 0xf69f3f1b, 0x4fdb2723, 0x33533974, 0x7f10722c,
- 0xf4c72452, 0xefadea55, 0xd8073fa3, 0x030df6bc, 0x0f978f7d, 0xc3ba3bdf,
- 0xdf47bc6f, 0x0f1e4a99, 0x6dd50efb, 0x1d508b4d, 0x1de8da83, 0xe80563f2,
- 0x56aa7337, 0xfe1ccce6, 0xc07c1f9e, 0xfc48cfbe, 0x7bb69f9e, 0xbbf86725,
- 0xd27be32f, 0x9a35817d, 0x2eb1f109, 0x1196eacb, 0xbcd6651f, 0x657bec19,
- 0xe1256fa7, 0x36d482ea, 0x0e624d81, 0xa87964cc, 0x782a55c0, 0x92ff682a,
- 0x027df8c7, 0xc5d17860, 0x039eb7f9, 0x5238f7ec, 0x2bf7fc2d, 0xad0e2176,
- 0x8d7e862e, 0x27858fbe, 0xef946a16, 0xdd5a776e, 0x8859cf94, 0x7e61d4df,
- 0x3bfcac5b, 0x5e6b168a, 0xf1b8fc80, 0x3ca2585d, 0x3d16505b, 0x56dd0ecc,
- 0xfc272f96, 0xc59b47fe, 0xcf922df7, 0x472bd3b7, 0xf25c1e50, 0x2cb9f9ab,
- 0xcc79472f, 0xba61e437, 0x7028f7f1, 0xfda1dfff, 0x82fefe27, 0x04546fb1,
- 0xc8438f03, 0x838390d3, 0xc77144f4, 0xf4327a83, 0x9f2c305c, 0x0e5c295d,
- 0x52417d0a, 0xc8d5dec8, 0x6ff7135e, 0x01bfefec, 0x8f1a3ec3, 0x00003430
+ 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd554780b, 0x733ef0b5, 0x7993331e,
+ 0x0f20f264, 0x0084f102, 0x021842a2, 0x27088784, 0x01a8c421, 0x54bc8083,
+ 0x48433c26, 0xbfa81132, 0x2677bd6d, 0xb5ad1104, 0xbc1b6951, 0x14101de8,
+ 0xd1a07515, 0x40e81c06, 0xdbdab114, 0xd5a8f8a8, 0x40445076, 0x8bcbc248,
+ 0xaf7fd52d, 0xe649cfb5, 0xd4484c9c, 0xffffbff6, 0xdbf3f1fd, 0xd9cfb3ec,
+ 0xdaf5ed7b, 0xf6bdad6b, 0x9a32c11e, 0xe4224e24, 0x65a3f85b, 0xf4842784,
+ 0x0adb2ce9, 0x64918fda, 0x8b2ffc42, 0x108e36f2, 0xf08e77ee, 0xbc8451a4,
+ 0x980b99b5, 0xcfbc3d69, 0x9fad0846, 0x603d34de, 0xff6422ce, 0xef02b308,
+ 0x8f9ade9f, 0xbd2fc9f5, 0x7b6814e7, 0x00bc4bd5, 0x13bed375, 0x109d88ce,
+ 0xa1e5b9af, 0xf6f3e96b, 0x85b27897, 0x93fc450e, 0x9085244d, 0xfec21663,
+ 0x52fab22e, 0x6d56ab2b, 0xf4077fde, 0x2664de5b, 0xd54fda56, 0xaed365ee,
+ 0x8765f5a5, 0x54af0244, 0xfa95ab6d, 0x00f2fad2, 0x9afa8417, 0x71c67f7d,
+ 0x79480ada, 0x27212870, 0x5f22167d, 0x96ceeb49, 0x79f45994, 0x11676045,
+ 0x83b15fbc, 0xfbe89b73, 0x7ff69b15, 0x3457fd0c, 0xda79038a, 0x36ed8aff,
+ 0x63610f22, 0x1e604b7f, 0xbc01a64b, 0xc4886f55, 0x97e5eb4c, 0x70044956,
+ 0xa54bd424, 0x61ff180e, 0x38c07649, 0x0d1c7087, 0xd0cf559f, 0xd577e871,
+ 0x986e702f, 0x7889b55a, 0xddd69e00, 0xda4f39d6, 0xd2b55e61, 0xf77ef860,
+ 0xb7bc127d, 0xb2f6502c, 0x36f80655, 0xe700454b, 0xd2d2cda6, 0xadfd9da1,
+ 0x0ea6fed8, 0xd90d63ae, 0x76a89ea9, 0x47d27963, 0xacee6c88, 0x04a21057,
+ 0x407700ed, 0xf3ac3e9a, 0x812e79f9, 0x3fd0d190, 0x674b644f, 0xc83094ff,
+ 0xe8f7fe07, 0xf60f813f, 0xb2db023a, 0xd2b5e93a, 0x772dff45, 0x4bacebd2,
+ 0x9ed09fa5, 0x56bfdd17, 0xa074043e, 0x5cfbd4f0, 0x4be23e58, 0x4f8372c3,
+ 0xcafdbc46, 0x06cb0437, 0x3f9f1b9f, 0xe58b1be6, 0xe5829f26, 0x2c62be13,
+ 0x7c52be03, 0x0e6f8b6f, 0x1e7d5b96, 0xaf94fe7c, 0xbeedcb1c, 0xacfe7c1a,
+ 0x772c6eef, 0xfcf8fcf8, 0x2c7adf05, 0x2c7abe83, 0xb01af977, 0xf005f46c,
+ 0xdb7d97bd, 0x05f26cb1, 0x5f1ef9f1, 0x5f219613, 0x407dcb18, 0x7d865a5f,
+ 0xf01e582d, 0xabe5887d, 0x777e08be, 0xcb1c77d0, 0x3bbc5507, 0x817c9027,
+ 0x10a9cde2, 0x92171517, 0x8be4a258, 0xca589eb4, 0xf9b729ea, 0x4f5a25f3,
+ 0xc53ad0f1, 0x70cadf63, 0xfbd699be, 0xccf6b0d6, 0x8581487b, 0xacfd33d6,
+ 0x4a83c07d, 0x07d69581, 0xc1f6b3d4, 0x7105fc9b, 0xc0383eb4, 0x11deafda,
+ 0xfad1b02e, 0x9ed641d5, 0xed932213, 0x66139eb4, 0x94b7dcf5, 0xcf5a0ec9,
+ 0xbcf5616d, 0x9d93fd8f, 0x61179eb4, 0x153f8fdf, 0xeb4f1c9e, 0xfb59dbe3,
+ 0xd0a44bc4, 0x0913eb45, 0x7b02f587, 0xad02617e, 0xbd58b817, 0x20995fa8,
+ 0x7dbfe0c7, 0xa1116462, 0x7fddb0bc, 0xd3a422b3, 0x455914ba, 0xfe9f14dc,
+ 0x8b0f5839, 0xbfb43164, 0x84532fe5, 0x912eb471, 0x17fed0d5, 0x1fb6057f,
+ 0x6f6c6510, 0xf6c2aff7, 0xed8c9203, 0xb07bdaa6, 0x60a8aafe, 0xbded727b,
+ 0x92abfef8, 0x6b83ed82, 0x41fac21f, 0x63ed83d1, 0xef8d7f6b, 0xd83c941f,
+ 0x80dac8fe, 0xffeb4852, 0x00b679c1, 0x9e71d75f, 0xfc0d9272, 0xa52b4c1a,
+ 0x238ebafc, 0x1e3e4073, 0xf2a6a600, 0x525d2eb0, 0xfbedbf40, 0x3c93de47,
+ 0x3276f2a7, 0xf53e97d4, 0xf3f61640, 0xd223f61c, 0xfb9ef87e, 0x58cdf899,
+ 0xbf133f5d, 0x69fad729, 0xaceaf784, 0xdf67ebbd, 0xf0f5e337, 0xf5a1537c,
+ 0x71fb17b3, 0x135e6ef4, 0x87a09dbf, 0xad4adbe7, 0x4fd8839f, 0x09e0ef42,
+ 0xfd74638b, 0x5a65c584, 0x7ec47f3f, 0x1e0ef4fa, 0xeba71a45, 0x6b969147,
+ 0xfd887cfd, 0x9faef7a4, 0x1ead74b0, 0xd685691e, 0xa7ec11cf, 0xa5e6ef7f,
+ 0xc3d3af98, 0xfad2ae63, 0xcf748939, 0x073f5dea, 0x1cfc7a1c, 0xe7e07470,
+ 0xa833c21c, 0x702af377, 0xe053f1ea, 0x25cfc0ec, 0xdeaae7ec, 0xa9c073f5,
+ 0x6701cfc7, 0x0e447e07, 0x77ac35e6, 0xd7882af3, 0xbe20a7e3, 0x0e4e3f03,
+ 0x3bd119e0, 0xa3ed5e78, 0x7dabcfc7, 0x8a93f03a, 0x1dee8cf0, 0x7a29853c,
+ 0x74a614fc, 0x784647e0, 0x9faef5c6, 0xf8f45357, 0x03a53579, 0x3f61573f,
+ 0x5e6ef5d7, 0xfc7aa985, 0xe076a614, 0xc9fb1727, 0x78476cf7, 0xd1c7ed08,
+ 0xfb073f7d, 0xb073f1eb, 0xae7e077f, 0xd0a67ec5, 0xee7bb27e, 0x8f5328a7,
+ 0x0ecca29f, 0x9e2214fc, 0x3f5de86f, 0xf8f53307, 0x81d99839, 0xcfd8a99f,
+ 0xabcdded4, 0x7e3d0ae8, 0xf860ae8a, 0xc08c2499, 0x9dae8675, 0x727e9e6e,
+ 0x857cbf7d, 0x2ef3efa3, 0x6e5de756, 0xaf0f7602, 0x45a433d9, 0xf6fbe9e1,
+ 0x0fb9091d, 0xa6bb6890, 0x8fc076e0, 0xd1795a83, 0xd8fc4d76, 0x951d9d38,
+ 0xeaea24a0, 0x757dc549, 0x1d29f7ef, 0x9d4f6ba0, 0x3daeb573, 0xabab93dd,
+ 0xd78f9467, 0xa6bfdfbd, 0xe2bf5740, 0xef751bee, 0xd16ff967, 0xcfd7b3d5,
+ 0xa83fbdd3, 0xfdaea17e, 0x5d0a86ca, 0x958155fb, 0xdb35faba, 0x7f7ba27f,
+ 0xae8d7058, 0x03d3787d, 0xe111f6ba, 0x91f57447, 0xbdd31e87, 0x8b65ba3f,
+ 0x87cc7dae, 0xc7daeacf, 0xeae97645, 0xa3df1ed7, 0xf6baff7b, 0xa4faba03,
+ 0xbdd7bf8b, 0xd5de4f9f, 0x3f96dbdb, 0xe29fdeeb, 0x7ed74cfa, 0x0697da7d,
+ 0x3aeed53b, 0xe75a8d76, 0xfa08ae41, 0x0974fe25, 0x43b0d5ed, 0xd7d4bac2,
+ 0xc714fcce, 0xe528f952, 0x22c0e91f, 0x92f91939, 0x21bb51fe, 0x95f96fbf,
+ 0xaefcfa11, 0x5d2b9ef1, 0x925df9f4, 0x862bb867, 0x8df9437d, 0xca506923,
+ 0xed8d2826, 0xdf8c89f7, 0x0d2e320b, 0xf7bf423e, 0x2707da9a, 0x3e70fad0,
+ 0xf1f2083f, 0xbb426732, 0x35278e3a, 0x999c5ef0, 0x5f74dfa0, 0xfe93de56,
+ 0xdf587928, 0x5c19da9f, 0x45ebbf67, 0x51da1a4f, 0xc1f89fb5, 0x9fd759ce,
+ 0x212fabce, 0x849f70af, 0xf7e903fd, 0x79a697fd, 0x89667f68, 0xe3d119fa,
+ 0xa1fc744b, 0xe4187e38, 0x3f8c20e1, 0xe6f8ebba, 0xe3756301, 0x75cb325b,
+ 0x3a245be3, 0xdf908bbe, 0x8eae7ed7, 0x9e30894f, 0xcfb93790, 0x66737c71,
+ 0x9f7f8e39, 0xe8aefd44, 0xc63ae3f1, 0xbff9816f, 0x07fcdddf, 0x3fcfd78c,
+ 0x7f3f42b3, 0xa3ffcd89, 0xf8ead3da, 0x3fff3871, 0xfcd9a773, 0xfcd82b33,
+ 0x8edfaccd, 0xf81d9df1, 0xc7f8c08f, 0x9cdf19ba, 0xff3f413d, 0xf3f52a2b,
+ 0x4ff1b337, 0xc7505ed6, 0x5ff8e3b7, 0xfcd81772, 0xf1c4a8af, 0x0dc7b325,
+ 0xc46523fc, 0xf8e804d5, 0x7c551fa4, 0x742ec0a9, 0x2487281c, 0x6421a152,
+ 0xe100371b, 0xf18e2bb8, 0x947157db, 0xf99f50df, 0x500939f1, 0xfd4799cd,
+ 0x57d79546, 0x4097c8ec, 0xf53b61ef, 0xa0a896b7, 0x91e26e2e, 0x7306c9bf,
+ 0xb7851060, 0x43f789b5, 0xeb86f17d, 0xbd5fa002, 0x14a0b266, 0x184813be,
+ 0xcbfe7f9e, 0xe7a25b61, 0xd4972c65, 0x5122c78b, 0x07e1d6f2, 0x35219016,
+ 0xc029be14, 0xeb3ba304, 0x0e3f529f, 0xa98fe31c, 0xffa843df, 0xc6c899f3,
+ 0xf7f50bfb, 0xfea11ea0, 0xa4ce3a1e, 0xdda3bf16, 0xf0a34e1d, 0x7ff0aa97,
+ 0xfd79302a, 0xe02e36f4, 0xd5f9f2a7, 0x7fa0478f, 0x1b6ee0bd, 0x1c277a45,
+ 0x5d24fe65, 0x0fcbce9d, 0x6ddf6a74, 0x10e16c0e, 0x6be032bf, 0x21268a3a,
+ 0x5067d68b, 0xffbe775c, 0x07a9bec1, 0xb7212739, 0xa54c4512, 0x9abedfef,
+ 0xe3a2efeb, 0xb9cc52ce, 0x32521d6c, 0x24d7284c, 0x909634c3, 0x88471a5b,
+ 0x5d3207b4, 0x448d3f11, 0x58a33b8d, 0xaa559f5f, 0x8a8ab7af, 0xb570a268,
+ 0x66c8e74e, 0x39ecefda, 0x9c6d76fa, 0x4644a681, 0x52bc7567, 0xfa74938a,
+ 0xb9943668, 0x7485d8f0, 0xdf62e39e, 0x1778f06a, 0x7e8c2489, 0x010fbfbc,
+ 0xf193faba, 0x362e79bd, 0x73bc236f, 0x4a528b44, 0x8ca739e7, 0x1b7f000f,
+ 0x9f68ffe1, 0xd0e5314d, 0x22a3fd72, 0x8f9d7531, 0x1eb9fe11, 0x22827ce3,
+ 0xcbf3f3ac, 0xdf19cf8d, 0xffe9531c, 0x2d07f029, 0xa0fe00bf, 0xf9551ff0,
+ 0x32af53a3, 0x3d9af0fe, 0xda1f80d3, 0xe904f237, 0xadcbf2aa, 0xa92cbf2a,
+ 0x2105f3d7, 0xb8e8111e, 0xfb970e6c, 0xcc1f1440, 0x5960f956, 0x6e6f9e83,
+ 0x3d317e27, 0x6ee65d06, 0x9a6f7cd8, 0x9f7e75dc, 0xff337ca8, 0x9f88fdc1,
+ 0x7464f3ae, 0xd3a543ba, 0xf6fa35ed, 0xdeba555b, 0x4e75d2ae, 0x51afc3c3,
+ 0xc9e641f5, 0xdde41101, 0x9e8d53fb, 0x3d3d1d11, 0x708d3d2a, 0xf3d2a1de,
+ 0x7a331f8e, 0xa88de11a, 0x9c348cf4, 0xae80c913, 0x5be11af0, 0xf9977770,
+ 0xccab5c60, 0xde9e9b1f, 0x4755fca6, 0x05579ea3, 0x3475586f, 0x6c56ce4a,
+ 0x2fabae9f, 0xbdd5cc0f, 0x4ca1acbf, 0x7ea4bed7, 0xd17daeb9, 0xf5753bfa,
+ 0x758fff32, 0xbbb82fef, 0x7b7ed756, 0xf6bafdcd, 0xeb0fe5f9, 0x1b3d73ea,
+ 0x9ecfef75, 0x3ed759b3, 0x5d19f4ab, 0x9de28cfb, 0x6574faba, 0xd37deeb7,
+ 0x066eabbe, 0x3deb7cfe, 0x713d809e, 0xc605fdc1, 0x45b82f33, 0xd473bc37,
+ 0x1f5f2327, 0xf2c10df3, 0x7c8dcfb8, 0x1637d27f, 0x66a6d6cb, 0x7413ac3b,
+ 0x124a5c5d, 0xcd326908, 0x0fdf5dab, 0xeb8269d6, 0xa9e4c869, 0xb37ad3f5,
+ 0x28794649, 0x78489069, 0x2c1c2124, 0xed1c2a36, 0xa47b547c, 0xaa06f687,
+ 0xb6ba93f8, 0x3f624497, 0x76523ef7, 0x7765f005, 0xcbfd03eb, 0x4da7bb00,
+ 0xed8debb5, 0x8d291c95, 0x1ac84e7e, 0x626ac384, 0xc4a54776, 0x5772bfe4,
+ 0x4271017a, 0xe6b83c3d, 0x2905e372, 0x9f02a793, 0x78e4eb64, 0x3a35c359,
+ 0x9a204efd, 0x6df807dc, 0x8af9eea4, 0xbeead7ed, 0x479fb53b, 0x5741abb8,
+ 0xb165838c, 0xe81333f4, 0xe67370e1, 0xa700618c, 0x4deb1472, 0x3c2ed07d,
+ 0x755e2be5, 0xafd01074, 0xbee3cb14, 0xf31e5839, 0xea3cb079, 0x53f2c72b,
+ 0x11960d5f, 0xfe58dddf, 0xf2c7e7c5, 0x2c7adf63, 0x63d5f23f, 0x01afa1f9,
+ 0x017df7cb, 0xb6fb0f2c, 0x2f8ef963, 0xaf8b6588, 0x9f56cb09, 0x7726a582,
+ 0x71ddf13d, 0x093e1d75, 0xcf8317fc, 0xed7f3aa4, 0x7c9d09fa, 0x87dfc716,
+ 0xb9e1a67c, 0xf2acc1a4, 0x1f8e8a43, 0x4397c012, 0xbda1eb3e, 0xb0f95441,
+ 0xb763efbb, 0x6bfcb77b, 0x0fea6df8, 0x7e4eb7e4, 0x53f030ca, 0x34fc4f76,
+ 0xa7e28f8c, 0xb31726a9, 0xfa7e547b, 0x8623cc19, 0x8c0f315f, 0xf6513e90,
+ 0x826f929a, 0xbaa56c75, 0x601f420f, 0x763aacfd, 0x05b77d1d, 0x10c0baed,
+ 0x0ece3758, 0xd860dbf9, 0x21fb3847, 0xf7567e25, 0x49f233f3, 0xd05778f7,
+ 0xa01a59bf, 0xdaea4f44, 0x78638d6e, 0x31489ab5, 0xfddaeba1, 0x2f729e83,
+ 0x81758a1c, 0x01f7c224, 0x8c4774f7, 0x0cada97e, 0xaf09edf8, 0x72af8e75,
+ 0x8f63bfa0, 0xca0f3dfd, 0x2f6626a9, 0x68f335c7, 0x93f093b7, 0xc76fc06e,
+ 0xa77664ba, 0x7dbdbc41, 0xbb42e490, 0xe3d64c81, 0xc3a05fcf, 0x4714fddf,
+ 0xd6eeb82d, 0x06fe21a7, 0xbd38357e, 0x49ebf817, 0xcf84f7bf, 0x7fef3085,
+ 0xd27b3e01, 0x45e93d8f, 0x342fc8a2, 0xedb7f9d1, 0x80fb961b, 0x1e5ee30c,
+ 0x9afedadf, 0x7e5f9e11, 0x4b6e3e47, 0x25b8f8d1, 0xa41f8093, 0xc6d9cbca,
+ 0x2e81e32b, 0x40f4fd1d, 0x9f77ee4f, 0x7eff8264, 0xdfdf4b3a, 0xe2fec67d,
+ 0xa70dc225, 0x89243ae3, 0x92bf53c4, 0xd1e36cf7, 0xfc47719f, 0x67d83710,
+ 0xe0c9d773, 0xaffc9e37, 0xeb3d0cb0, 0x0f670be3, 0x3f04e93d, 0x5f1a656c,
+ 0x1d063473, 0x982ab2b5, 0xf68f6355, 0xf5f49a57, 0x715cf5b3, 0xc725e710,
+ 0xeb061ccf, 0xa8e6ab8c, 0x0d3f7a08, 0x959fad4b, 0x738e1269, 0x3c767b72,
+ 0x4c02fff3, 0x4048ec9f, 0x67d2737d, 0xd9fff7c1, 0x8fd774f0, 0x8d210f06,
+ 0xe80b33e4, 0xdd96da73, 0xcaddfbfd, 0x825e7083, 0x890929f8, 0x69bf815f,
+ 0x3b7fffa5, 0xb015fa00, 0x0debf5ae, 0x70f37ef2, 0x3743be78, 0xd64efd1e,
+ 0xbbe18cf6, 0x204ee5ee, 0xa7be34c7, 0xbaabfbf4, 0xbb62bdbf, 0xc76f46b5,
+ 0xdeeae826, 0x9d1af4a6, 0x00ff0b5d, 0x1386bdc3, 0x54ab0960, 0xb04db0d9,
+ 0xda7e07af, 0xf049c103, 0x5ef6385f, 0x79222595, 0x16971464, 0x6385d3e0,
+ 0x6797fe35, 0xa9ea99ff, 0x048a6f13, 0xa25c8ce4, 0xaea9e550, 0x899bf220,
+ 0x917d6898, 0xc6c2f6fa, 0x6eb02515, 0x26f9789d, 0x931643f4, 0xc7f82752,
+ 0x0f3ea4e5, 0x89a7b5e2, 0xf3e418a9, 0x39c77934, 0xad1e4a32, 0x2e9d8482,
+ 0xe3b7af5a, 0xabaf7fa9, 0xd7d06b2f, 0x525b9297, 0xe97edf60, 0x38049106,
+ 0xf6fa1bd0, 0xf61779af, 0xacd48cbb, 0x57fb7583, 0xa16bbc6a, 0x5419088b,
+ 0xf6fd556f, 0x0a32bcf1, 0x71604b87, 0x7a1f6d16, 0x7ff32279, 0x2406662a,
+ 0x59ffbe85, 0xa95bc8e3, 0x07dfa206, 0xbc7ec1d6, 0x6f713a7f, 0xf7e95d23,
+ 0xc237e15d, 0x5d03d9ab, 0x3855c3f6, 0x4a73b792, 0xcb1e8620, 0x67263814,
+ 0x102bbeaa, 0xc7b8ba5c, 0x7bfd4334, 0xd13253f3, 0xde1ed3f1, 0x668c2793,
+ 0xc0fc03fc, 0xe792ed09, 0xd69ff487, 0x7f82ffa5, 0x68fdff6a, 0xfeba79ff,
+ 0xfb53fda7, 0xfe05d81f, 0xaffab179, 0x2ff3edfa, 0xa93ea9fb, 0x4e97f178,
+ 0x13c9d742, 0x9b8a7d42, 0xdb72b5d2, 0x96854ebd, 0x13bf05c7, 0x8044f5f8,
+ 0xef458e2f, 0x154e0587, 0x41cec542, 0x49fe0ddc, 0xecf93ffb, 0xf11e30cf,
+ 0x85d136d5, 0xe6edb4f1, 0x61ca99b0, 0x12f2e375, 0x23f58392, 0x19df7eac,
+ 0x7a4dea1e, 0xfa78abfe, 0x1f902997, 0x8d453942, 0x9ed1852f, 0x79fadead,
+ 0x5e4fac11, 0x64728ed2, 0xbfc60efc, 0xaffa8898, 0xdaef8a4c, 0x38c4e14e,
+ 0x8bc55781, 0x6767f1b7, 0x37942778, 0x82fa017c, 0xc7e8227a, 0x572bbf1b,
+ 0x8235d4ed, 0x8d98f923, 0x190c7bfe, 0xc3517a03, 0x3b30090b, 0x5f99eeb5,
+ 0x70a11ce7, 0xa6fada9d, 0x97c28b93, 0x83674f26, 0x8f73fe8b, 0x6ddebddc,
+ 0x6d16f2a5, 0x96eb690f, 0xd7daa4dc, 0x8a565621, 0xf3e42761, 0xdd166e54,
+ 0xf2b8fa7e, 0x7a9f27f9, 0x7f99e20c, 0xd107bb32, 0xff3c57fe, 0x69e3fbda,
+ 0x314ec57d, 0xc34d84b9, 0xd274a5ce, 0xbfff4bc7, 0x1e93b73b, 0x4d79bf15,
+ 0xe7b18792, 0xd27624f7, 0xfdcec565, 0x15d61912, 0xfb83931f, 0x063d88a5,
+ 0x8a47827d, 0x7ba85ec0, 0x8825bfe6, 0xc7d89e33, 0x18acd491, 0x1afcdcf8,
+ 0x278003da, 0xaf4aa7a4, 0xde19fa0e, 0x80ba52f7, 0xcbd236de, 0x5522def8,
+ 0x90bf40bf, 0xfbf94167, 0x07903d85, 0x0dd991f5, 0x617f2878, 0xf3e61395,
+ 0xf8c35085, 0x537bf1fc, 0x8b959f40, 0x961714fe, 0x13f979ec, 0x5bfe423f,
+ 0x528ff6f6, 0x9444be30, 0x45ae1374, 0xe79874fe, 0x70b34d92, 0x07894b9e,
+ 0x71fcb0f9, 0xcb4034be, 0xde29020b, 0xac4e4319, 0x2f939322, 0xd2e250b6,
+ 0xfe017e79, 0x77efe824, 0xb436c0f8, 0xa024efbb, 0xcea47e0f, 0x580c5a85,
+ 0xf46160bf, 0x2ebaabfa, 0xa33eb010, 0x7deb77f9, 0x93a7402d, 0xd85495fd,
+ 0xc112f177, 0xfb83e2af, 0xbfcbf696, 0xd195253d, 0x9e42c889, 0xf75d1dfa,
+ 0x7873c327, 0xac5445bf, 0xc8efba39, 0xe39d59b7, 0xa7c756af, 0x7ac1c770,
+ 0x6c4a45fd, 0xd44f35fb, 0xb75d00f4, 0x4a2cf8a3, 0x6ffc99de, 0xbbc99fbd,
+ 0xe981ff26, 0xfe7ed0c5, 0xf8239330, 0x0a43d60e, 0xdb153857, 0x50e4cff7,
+ 0x3a3f503f, 0x156f9c96, 0xb7d73955, 0xc285f91b, 0x51f1702f, 0x24e3037c,
+ 0xdf701d22, 0xfa06e965, 0xf51e947d, 0xaeceb8c2, 0xbc726afd, 0x455bf34c,
+ 0x9b203ebd, 0xdee81e98, 0x9e23f2ae, 0x53c0c52a, 0x52fc818f, 0x20cbf579,
+ 0xcc2962bf, 0xcd1dcbff, 0x72a3cfef, 0x935065fb, 0x355ebd5b, 0xaef96dca,
+ 0xdc9624d1, 0x9377697e, 0x9f4b7298, 0x7b5b94c7, 0xfff9f904, 0xf0d55eb4,
+ 0x78f00c38, 0x351e274d, 0x3e1dd93d, 0x90f27a8d, 0x8d5e2320, 0x1dfe927a,
+ 0xf95d7926, 0x8d43e351, 0xab9e2aff, 0x51f402ba, 0x7c6a9f07, 0x1aa7c1d8,
+ 0xef89761f, 0x6c68f0ea, 0x34fb00bf, 0x96f9ae14, 0x528ed38d, 0x4ed2d257,
+ 0x7f26df70, 0xaafb8f26, 0xe584f396, 0xf3111081, 0xd5303f43, 0x753b068c,
+ 0x3d6fdfe2, 0x7785177d, 0x2c8bf13e, 0x445ea02f, 0xb7d2ffbb, 0xf3a04edf,
+ 0x79e2a799, 0x54fb453e, 0x0239974a, 0x70a38e17, 0x3f8815ce, 0xb7e2113e,
+ 0x0a34f91c, 0xfae5f98e, 0x4c4dfc3a, 0xa7a7ece9, 0x9fabbff7, 0xb7cb7df2,
+ 0x1d3f5d29, 0x50bbc844, 0x10bc388a, 0x81d357cd, 0xde7f14ae, 0x00605c51,
+ 0x5088a9ea, 0xbd77e51a, 0xf3fb3220, 0xa319c2ed, 0x9fc9bec1, 0xf19e2c3d,
+ 0x7bf460fb, 0x3b3eaabd, 0x41e397eb, 0x650d9fcf, 0xf67b7fa3, 0xac4722d0,
+ 0x9566d0bc, 0xf7535ecf, 0x5cecda5d, 0xbff94f3d, 0x7da3b48d, 0xc95bb7e3,
+ 0x82fb18b6, 0x5f4d451b, 0x7fa374ab, 0x8e7f1d3c, 0xe97387ca, 0x51b9f1a7,
+ 0xf5399b74, 0x4aece084, 0x34fbf807, 0xa1fb0fca, 0x06be05f8, 0x235b36fc,
+ 0xe231a545, 0xf8a9cf79, 0x6be0789b, 0x0c2dcfcc, 0xc7800be5, 0x8baf3b42,
+ 0xc9a93c83, 0x143250eb, 0x60789ae0, 0x5347cff9, 0xe21ef63e, 0xeb8f90dd,
+ 0x3c919d0d, 0x2361fc31, 0xb07fa13e, 0x2e888f33, 0x627bd7c4, 0xebc012e9,
+ 0x04acb37b, 0x95df35f6, 0xe0b155dc, 0xf5b3332c, 0xbd292e66, 0xbffb8a30,
+ 0xb3f9bf0f, 0x8a02e11d, 0x9676b38f, 0xff95ddf7, 0x759fdc98, 0x0e5a8171,
+ 0xf56790f8, 0x71002e64, 0xf9e222b4, 0xe50e04f9, 0xfeb4527d, 0xfe9a6fca,
+ 0x54f5e43c, 0x89973887, 0x110b57b6, 0xdbd8f809, 0xfb0053b4, 0x289926fd,
+ 0x6a108f18, 0x8a8ccd86, 0x05111d7b, 0xdff357c4, 0xf80edde6, 0x4cd3373d,
+ 0xe8652e00, 0x01d82719, 0x512342e7, 0xd79bba0e, 0x5a647c1f, 0x10fd08a1,
+ 0x3f230fe4, 0x74db2514, 0x499359f5, 0xdba5373f, 0x95647344, 0xeafd063b,
+ 0xbd67c624, 0xff966fd6, 0x04dbf4cf, 0x5f18dfaa, 0xedfad18b, 0x7df18926,
+ 0x8d4b7e94, 0xd656dfa5, 0x17c0a9ca, 0xa766f72b, 0xbe575d02, 0x2c4fa4b1,
+ 0x8fbaf6fd, 0xa86ff7f9, 0xfd6de679, 0x1e1b7ea8, 0x51fadfa5, 0xae2316fd,
+ 0xa5ea5a3b, 0xcffcb37e, 0xa0ebdfc8, 0xb7cc62df, 0xa69fc558, 0xb5438adf,
+ 0xfb8adfa8, 0xa97cbaf1, 0xfa4f5249, 0xb397ecad, 0x6dba2eb0, 0xf007f831,
+ 0x0dedfa0a, 0x38c1cf55, 0x5dfee7a0, 0x3d277d72, 0x3d5bd557, 0x67843ff7,
+ 0xecadcf4d, 0xd33da1cf, 0x9e990f95, 0xf4c5995b, 0x4cbdcadc, 0xc41cadcf,
+ 0xbf519cf4, 0x6fd17415, 0x21eafbec, 0x23f47bf4, 0x1b7d7eb3, 0x23992f6d,
+ 0xfdf42dba, 0x9f3b5912, 0x5a3a3351, 0xd4bbfddf, 0x9f73be8d, 0x3d2e73c1,
+ 0x823fbbe9, 0x7a841bbe, 0x91c8206c, 0x1c6e3f91, 0xd3e5d368, 0xb1f5f7bd,
+ 0x79045ee7, 0xfe8f03f9, 0xe62607f7, 0xfafbed27, 0xbb9048d8, 0xaa1e00f7,
+ 0xf9519eef, 0x47e7d5af, 0x28793a7d, 0x7baaf793, 0x1baafe18, 0xd5df3639,
+ 0x7586407c, 0xd1176fe0, 0x2f7dbe8f, 0x9b67a3f3, 0xc0d8fa5b, 0x225fffcf,
+ 0x2bfd25ca, 0x87e28b29, 0x302b1739, 0xce2bb9ee, 0xccfc05b9, 0x80b10239,
+ 0xd0e0bb1d, 0x7ec0278d, 0x3d71705d, 0xe00bbdda, 0xc8e92279, 0xa1db98fb,
+ 0xebf6f527, 0xaf9da6bc, 0xf9ae9065, 0x8ccd1310, 0x7157132e, 0x5d59cd81,
+ 0x5da823f3, 0xc62df986, 0xabdf893c, 0x47cd9ff3, 0x8fe45f10, 0xe5f8cc7c,
+ 0x72788def, 0xad54bc33, 0xaa78f5e6, 0x89e262e1, 0x2ca4ba52, 0xb72f13a5,
+ 0x975914bf, 0x39cbed01, 0xf38cb7f4, 0x9c66f0d6, 0xcd4786bf, 0xbea059bf,
+ 0x24743f3f, 0x86889e66, 0x22f92ee7, 0xf80dde1a, 0x33d34b78, 0x206190d7,
+ 0x3c981f97, 0x7c0d1f3f, 0x178a7bf4, 0x73ade70a, 0x2bcee907, 0x65e2a3bd,
+ 0x6148e7aa, 0x24780c8a, 0xf367c035, 0x96be77ca, 0xb377e742, 0x210b9592,
+ 0x937f59f5, 0x688f103c, 0x1ea3b6b6, 0x9470f8d4, 0x5985c999, 0xf5ef2bd5,
+ 0x7ae21575, 0x50b9c4d3, 0x3d06c2be, 0x7999e6a7, 0xd7f261ef, 0xbaf7fdcc,
+ 0x6788518c, 0x91482e58, 0x5d015eb6, 0x86a73fe8, 0x40bc5d18, 0x69cffa17,
+ 0xe020fda4, 0x73993abd, 0xa6fde187, 0x3f02f79d, 0xcfa56ebd, 0x39cbce41,
+ 0x0e8616f7, 0x65ca7a7b, 0xc58858f9, 0xc8cc18c7, 0x173f5ceb, 0x5d897bc0,
+ 0xe68993ed, 0x8e00f796, 0x366e5489, 0xfd00c3c3, 0x46fe8a2f, 0x07c8c5fb,
+ 0x7503e53d, 0x2ab9efc7, 0x3a075f9e, 0xeddf01d8, 0xde43d812, 0xb47f5b30,
+ 0x1720af76, 0x3a34de22, 0x65f5d134, 0x2983a314, 0xd66f9e06, 0xbd9e2aea,
+ 0xef844e21, 0x6ffea06f, 0x7ebb0712, 0xf8d41f5f, 0xc5772cdd, 0xd215c413,
+ 0xe806f4a3, 0xcd7de8b7, 0x11b7a6ea, 0xa6ae375f, 0x15dc99e6, 0x407d1a5f,
+ 0x6f0e5e0f, 0xd34fcadd, 0x61799891, 0x467e55df, 0xb3f2f599, 0xe6fedacf,
+ 0xedab8870, 0x90af50e5, 0x7e2e8250, 0xecccd330, 0x07ab6696, 0x0dfdbcf9,
+ 0xee45bdd1, 0xa8a67faa, 0x257f0174, 0x64e27cfa, 0x4de80898, 0xa67c9597,
+ 0xe3007bcd, 0xe0f5e8b7, 0xe907ab75, 0x33ff5dd7, 0xedfecccc, 0xead31ece,
+ 0x9078c3d7, 0xc7eb28d7, 0x5a47ae33, 0x79a7a95c, 0xbf71d479, 0x71b4bcef,
+ 0x84beebbe, 0x3c60b497, 0xd89fdb4e, 0x89767bc3, 0x73163f60, 0x0a107dba,
+ 0xfe6fee39, 0x59bffa13, 0xff7ddd1a, 0x530a3f10, 0xe3bebf3c, 0x9f638c49,
+ 0x34c8f67e, 0xaf159f90, 0xe542c4f0, 0x838775af, 0x889e5984, 0x45427604,
+ 0x5dfb8f23, 0xcde70844, 0xa833b288, 0xf1f0c327, 0x5ef503a2, 0xa0732ec5,
+ 0xf15f7e84, 0x103967f2, 0xc35d6b7f, 0x59ff9ff4, 0x91fd1f95, 0xa807c81c,
+ 0xbcfed810, 0xa88f3e91, 0xb76a79fc, 0x6fe80e6d, 0xc73b3b6e, 0x2d9c115b,
+ 0x0ce2a39a, 0x16459bf7, 0xc36ddee7, 0x33ff6c3c, 0x0331e61c, 0x48e7d17c,
+ 0x53d0fcb5, 0x5cbd30cf, 0xe00624d1, 0xf6c5703c, 0x1710ad9d, 0x8cd0f8af,
+ 0xfb77abf6, 0xd3ec0919, 0xcf3e2fc9, 0xf1371bce, 0x976878ba, 0x3e76e438,
+ 0x59f8866c, 0x01ea1563, 0xf5823f5a, 0xfbf71aa0, 0x15b2718e, 0xd97dee2f,
+ 0xe2b8514f, 0xf13b4f37, 0x36cb705c, 0xb723c627, 0xa05f7e5f, 0x7831dc4b,
+ 0x9c771abf, 0xf5c105fa, 0xf1dc7621, 0x2127caa4, 0x48ee3eb3, 0x3c6127b6,
+ 0x5799c292, 0xd17e231a, 0x5fcfffc1, 0xcdf60278, 0xf2faed4e, 0xf2bb8009,
+ 0xfc4f739b, 0x2a93e294, 0xdbac1720, 0xc3df67de, 0xbbed067d, 0xd27d55f7,
+ 0xb8d3ccfa, 0x27fad34f, 0x6b7a1bb3, 0x2645fbdd, 0xeeb453ec, 0xe2053afc,
+ 0x4ef7abb8, 0xf56d7f41, 0x4953934b, 0x2b407f0c, 0xbd037f81, 0xd23227d8,
+ 0x39b1b9ad, 0x4d3ce013, 0x77eb0ee9, 0x58393c47, 0xb2f4e2c5, 0x11de471a,
+ 0x4bae5f7b, 0xc671b8dc, 0x3ac1d7cd, 0x65ba28de, 0xf1f88bd2, 0xe1cf4a61,
+ 0x0ee3a0bd, 0x38209f75, 0xe3f1b2f5, 0x4a0ff0d3, 0x7d660baf, 0xe342fe1c,
+ 0x0c7cff92, 0xba931ada, 0x7b871f8d, 0xdf6d3f81, 0x2159bf6f, 0x5da39016,
+ 0x1edc61cf, 0x0f7d47e8, 0x85fcfad2, 0x1cbb884c, 0xc0efdb17, 0x66bdebfc,
+ 0xd8aaa3cc, 0x53ca01fb, 0xe36f4beb, 0xf7511abe, 0xc7495adf, 0x5127db1f,
+ 0x56ef3a7d, 0xab3b8b07, 0xb4b88074, 0x6ae7c4ec, 0xb5f199fc, 0x2eee9716,
+ 0x32d63d1e, 0xabbfed80, 0x5b5591fb, 0x43112cff, 0x0b1b9fbc, 0xd9723af4,
+ 0x0f0d547d, 0x98c3c02e, 0xd896fde8, 0xfd8efff1, 0x80dd0316, 0x758f609e,
+ 0x7ad0a7ec, 0x07ab883f, 0xed620fb8, 0x666eb5df, 0x62ad34fb, 0x6d45bcec,
+ 0xc5a465ff, 0xe812efb0, 0x4f4bbedd, 0x78aef8f3, 0xb42706ca, 0x9d7c574f,
+ 0xbf5b14ba, 0xd4e16adf, 0xe7be037b, 0x67257ebe, 0x05981bcc, 0x78d5597c,
+ 0x4a7b0244, 0xf9b4df5b, 0xe7fd529e, 0x78f2cf53, 0xb05d644e, 0x51bbf519,
+ 0x1613547f, 0x5bc23437, 0xab7a616e, 0x1fad89ba, 0x023976a7, 0xa9cfda76,
+ 0xaf91bb03, 0x911c77ab, 0x83bfb4fc, 0x45237fdb, 0x60acf2a2, 0xc14408fd,
+ 0xfd85ea7f, 0x897f6c39, 0x71c6ebf9, 0xf1c752ee, 0xe38f6286, 0x374671dd,
+ 0x507f0ace, 0x2e7ee762, 0x4149de3f, 0x9dfd0d99, 0xe409116c, 0xf20c9ffd,
+ 0xe31881c5, 0x5a88b5cf, 0x0fc98b3c, 0x1cf1475d, 0xbb9d83a6, 0xb42513e4,
+ 0xc63b57bb, 0xfde7087e, 0x19243b57, 0xb57517e2, 0xeeb52f2c, 0x4069dcdf,
+ 0x5b84baef, 0xdeae3f71, 0xb2575f80, 0x1ae21f2b, 0x51d2c2ae, 0xbd46aec0,
+ 0x7498a093, 0x1476aff0, 0xce14caa7, 0x469daab5, 0x0b9e3704, 0xc5459de5,
+ 0x65de1f30, 0xec635972, 0x52f6883b, 0x8bc289e2, 0xe39fd2e8, 0xca469724,
+ 0x7f968fd0, 0x39696953, 0x052e8d88, 0xb1858c53, 0x99fcddec, 0xdb779c2e,
+ 0x507fd50e, 0x614aec88, 0x8eb06479, 0xcf8aedb4, 0x43f1c321, 0xb47e50a2,
+ 0x1db9cfa9, 0x5e83f7fb, 0x4a24eb5a, 0x8a339502, 0x86cf9955, 0x2c23acf3,
+ 0xe9f0365c, 0x857aff99, 0xf10d6bf6, 0xd9b457e8, 0x25527cb5, 0x46cce401,
+ 0x41bcc41e, 0x936fe560, 0xe634e13a, 0x25781213, 0x298d3eea, 0xa1fd1dbc,
+ 0x7c589bb3, 0xff572780, 0xcf8b027a, 0xafc00091, 0x542b2fae, 0xe212cf38,
+ 0x3bfbc30e, 0x580f181c, 0x9422c6f6, 0x3443a01f, 0xf58a92be, 0xac1b5ee7,
+ 0x67f01cce, 0xbf555a36, 0xc0b4afc6, 0x6ac59b39, 0xf54a7dbf, 0x18a962e7,
+ 0x975e41fa, 0xe5faf2a8, 0x9843a2d2, 0x8a59e68f, 0x8e753e7a, 0x31acdcfe,
+ 0xaa204b4f, 0xfe601c9f, 0xadbc9773, 0xb708cda6, 0xc56b7f31, 0xc35d7d76,
+ 0x37a027e3, 0x127402af, 0x80e2e5fb, 0x3237e23d, 0x4613d7f8, 0x9afc777d,
+ 0xb5f8f4d3, 0xdafc7aca, 0xa7f11886, 0xadc3afc7, 0x97e697c7, 0xf8df8776,
+ 0xc873fab1, 0x8afc2aff, 0x548ed556, 0x4aff4af1, 0x654c292d, 0x42e9dc03,
+ 0x28c2e518, 0x30f61947, 0x9feeff07, 0xafc5a81c, 0xefd40edc, 0xb87cea69,
+ 0x1b3becc5, 0xf00f11c8, 0xe08e51ba, 0x79e82024, 0x75d8f91b, 0xfac40acc,
+ 0x4d7b7c8c, 0x355cf4f7, 0x0b23d5fd, 0x809b57e9, 0x3f23877f, 0x89bef3b0,
+ 0x05975024, 0xc176ea72, 0x59f41dfa, 0xb8458bdc, 0x17b885f7, 0x5efb820f,
+ 0xa43e585c, 0x0db4abe6, 0x306e7825, 0x029f3e18, 0xdca1e9fa, 0xf7a069f6,
+ 0x29484bbc, 0xc51fc1e8, 0x0f03f3b1, 0x38bf65a8, 0x85abd549, 0xef824c6f,
+ 0xe70ca243, 0xdb42dbd5, 0xdea0832c, 0x2a3de3c4, 0xabfa84de, 0x90d6fc60,
+ 0x6c5ae0c8, 0x38820c09, 0xc7115ec8, 0x013c5d6d, 0xd87665cf, 0x2f96216f,
+ 0xccfa16d2, 0x9f4a28b9, 0x7a3d36b7, 0x36b9c415, 0xa9e7629a, 0x7e9ab14c,
+ 0xec1bfad8, 0xc537b792, 0x1eeaf2ca, 0x51e7401a, 0xbaacfd3d, 0xb879330e,
+ 0xabf3a556, 0xf9c46f4b, 0x64e214bf, 0xf88a4758, 0x461a6edb, 0x3dee39e7,
+ 0xb0cf8d41, 0xf528e578, 0x2fd03afd, 0xdfeb5fa8, 0xddc3e9e5, 0xe7020547,
+ 0x2cd546f4, 0x15eb7f45, 0xca73e527, 0x704a7917, 0x616df024, 0xcdef0128,
+ 0xd04c7ef1, 0x22dd1fae, 0x4f33f8e8, 0x22f3575d, 0x44c05e54, 0x3edf50f9,
+ 0xec18222e, 0xfc0f00a0, 0xfd71ed75, 0xd55685f3, 0x149272ee, 0x970df3e0,
+ 0x5ef20e78, 0x7b89dadb, 0x6dbb850d, 0xa3845f71, 0xfa9c3ced, 0xbe25e5a5,
+ 0xbf7ad638, 0x62f8caca, 0x9d7044a3, 0x8ed4b8d9, 0x4b03c5f1, 0xf580ae2b,
+ 0x7b1fabfd, 0x8e7588ae, 0xc53f4a3c, 0x252c7cb3, 0xfe058c9e, 0xbc31cb5e,
+ 0xc697a7d7, 0xf8d7f7c8, 0x8d6fe359, 0xc697d3af, 0x35e56279, 0x7665637e,
+ 0x21d2c15a, 0xdafe049c, 0xe38f0e3e, 0x5cf1aeb6, 0x9f8ddcf6, 0x7800c9ac,
+ 0xd0e74dbc, 0x3884b6ee, 0xb1bd9625, 0xfec4eac1, 0x6bf8d75b, 0x2eef8f21,
+ 0x27a09c2a, 0x0377efbb, 0x813f5bfa, 0x677c2ca0, 0x73c32fa9, 0x642c4bbc,
+ 0x85bbc40b, 0x1c5bf4fa, 0x6f93ffc0, 0x7de14758, 0xeb84d4ac, 0x8dd146eb,
+ 0x08abfbf0, 0x1a83f8c1, 0x8d37edcf, 0xcf3e8e6c, 0xff3584fc, 0xc7a52b59,
+ 0xd21756b3, 0xe6e3c925, 0x3ff77e00, 0xf209dbfe, 0x8cd176dd, 0xfaabec74,
+ 0xaf77da43, 0x36dd9959, 0x0ad94e33, 0x64f293df, 0xc7b71394, 0x123c5ee9,
+ 0x78a04dee, 0x4ea3928f, 0xbbf1f9fa, 0x71d50f44, 0xbb449e14, 0x2892f909,
+ 0xc5d2ec8a, 0x4728fd29, 0x30905c9a, 0x4d8f2047, 0x885cabd3, 0x1ca83b0b,
+ 0xc3d8b28c, 0x962477e0, 0x105379d3, 0xfac2c4ac, 0x754e116b, 0x3cc6cb9c,
+ 0x7997ca79, 0x608a3870, 0x71121448, 0xdf4d7fa1, 0x6d7a7a6a, 0x59794102,
+ 0xa810b0fb, 0x126cfda3, 0xaf885622, 0x01722964, 0x0a251aa4, 0xef179e32,
+ 0xff304e5f, 0x78fd96d2, 0x42dd8742, 0x37c47e85, 0xfb5882fc, 0x869c7c79,
+ 0x401fcf2f, 0x6a1ce46f, 0x8de6003f, 0x73c6cadb, 0x3b4166bf, 0xa87f43bd,
+ 0xba9158f6, 0xdcfb8efe, 0xc209f2c4, 0x3ef44893, 0x687f519b, 0xebb8c9f6,
+ 0xbf606b22, 0x189fdc68, 0x055bb49c, 0xcead1bbe, 0xa89f43b7, 0x1098e6eb,
+ 0xfbf427d5, 0x66c8d0dc, 0xf72b07b8, 0x5dc72663, 0x3f21c9f4, 0xbefbf80f,
+ 0x17c8c47a, 0x2e54c223, 0x32a1f6d5, 0xeae1a7dc, 0x19fb43a8, 0x9e49de83,
+ 0xed152a3e, 0x8cdf955c, 0xdbe4d678, 0x77b9f728, 0x0ccd9bbb, 0x1a47e62e,
+ 0x275c21c6, 0xe836721c, 0xb078b7a5, 0x29f2dbf7, 0xbf5c281e, 0xf4a3f902,
+ 0xb81f384b, 0x21bfe601, 0xe415bd74, 0x27af7be4, 0x5475fa21, 0xbcd3f69e,
+ 0x0fae3e27, 0xc04e27ae, 0xf3fef543, 0x46127aea, 0x01c8777a, 0x78e89395,
+ 0x46ffc689, 0xa3e4d77e, 0xc8de2e0e, 0x047673c6, 0x0b9e59d6, 0x663065e2,
+ 0x7805c9b2, 0x3aedecd5, 0xfe25bed5, 0x56ffb474, 0x1eba88bb, 0x4f800665,
+ 0x5ecd44ea, 0xe3a25b77, 0x051dab53, 0x4fdb97a9, 0xfea45ef5, 0x1b39d459,
+ 0xfe8ed0af, 0x84a2f79b, 0xfe37bfcf, 0x7914289a, 0x898dfc3a, 0x7f15dd1b,
+ 0xb08471f1, 0x9ffec2fb, 0x230cdf9f, 0x7727dc7f, 0xe25aefce, 0xf5422579,
+ 0xf5aade47, 0x3f193675, 0xd7969c39, 0xfb682f55, 0x01e9dd9f, 0xa98fbca3,
+ 0x70c66fac, 0xeef20f4b, 0x25f8a9b5, 0xb3e80664, 0xb76a61f1, 0xff957564,
+ 0xbcfceaf3, 0xb6f78636, 0x8307db5b, 0x3de7ad3c, 0x2f687135, 0xb0264c46,
+ 0xb413762b, 0x8ffbdc7b, 0x5bde513a, 0x4feb7492, 0x8fc0bb57, 0xa7d9a9f2,
+ 0x7c6a5d9a, 0x552ec3af, 0x3e2d1bd7, 0x795135ca, 0x193cf0a1, 0x1c03f1e7,
+ 0xbfe62e75, 0xd05701c2, 0x3d584f63, 0x365fc075, 0xd838973a, 0xce12192f,
+ 0xb096f162, 0x93bb3e4e, 0xde419b47, 0xb03f1482, 0xfae9f9fe, 0x1eeb8837,
+ 0x0971b19e, 0x85aa5e0c, 0x97e9bec0, 0xd560d847, 0xfbc7f304, 0x6bfbb0e5,
+ 0xfbb2e5fa, 0x31c73732, 0xa18b65fb, 0xfa5ac27c, 0x144bcc18, 0xfb9cdf88,
+ 0x5006e1fd, 0x64f90e21, 0xf800d29c, 0x382b14b0, 0x71170c8f, 0x19de9473,
+ 0xbc839042, 0x994ac489, 0xd247f163, 0xfb48ffb9, 0xf39128cb, 0x06323f81,
+ 0x9a373c12, 0x9e7d8a11, 0xf13895e8, 0x8debd987, 0xbcc1ce5d, 0x41cfcaa2,
+ 0xa937ce89, 0xe9839d84, 0xf050fb88, 0x8eadbf01, 0xadb2715b, 0xab3ed817,
+ 0xd9e1813f, 0xc101bfe8, 0x5a825e60, 0x822257bf, 0x2bfd1135, 0xdfaff03f,
+ 0xcaff4164, 0xd041dc46, 0xb1c41fb7, 0xce3aecf8, 0xbfea1ebd, 0x702dda10,
+ 0x37268fcf, 0x343c3c9a, 0x40b716e1, 0x775e755f, 0x5f7c0736, 0x00ef172a,
+ 0x9c275b9e, 0x6716bc1d, 0xf8c99ed2, 0xf975e14e, 0x9afd1af6, 0xacfd1d44,
+ 0xd6895710, 0x08690ef3, 0x5cadedd8, 0xaafc1b9c, 0x831ce5d6, 0xe7a8b397,
+ 0x3cdd0411, 0x1fcc6cd3, 0xe7f55369, 0x90b2e3df, 0x84f5b51f, 0xc63d6fce,
+ 0xe8f30d7f, 0x386a8738, 0x973c6a77, 0x11dd969a, 0x7cc74a07, 0xee0952dc,
+ 0x43672332, 0xbce3b436, 0x124cf6ce, 0x6a64bce3, 0x5cf31ac4, 0xbc5256b0,
+ 0x4b780d7d, 0x40126b15, 0xcedea71f, 0x1f1188f4, 0xc47f9c6d, 0xfb47d841,
+ 0x1f331883, 0xd2d32b45, 0x4c584a6e, 0xbf4b4fdf, 0x79ed4b01, 0x19885d83,
+ 0x71b24c57, 0x64dcec3f, 0xfc18b103, 0xed1b24cd, 0x9de7b4ef, 0xff1415f7,
+ 0x37bb8c76, 0x37bc31c4, 0x37bc31c4, 0xe53e1a48, 0xcebf9078, 0xf7975bba,
+ 0x4967c1b4, 0xd10f2010, 0xb9f28e9f, 0xdde8c5c4, 0xf682bef9, 0xdca21f4d,
+ 0xc4941730, 0x436c9106, 0x21f167be, 0xafc87ced, 0x4024cf7c, 0x96db94be,
+ 0x16fbfaa5, 0x0604df46, 0x530df9f7, 0xb214dc70, 0xe2983ac6, 0xc9a96979,
+ 0xd3a3710d, 0xc2723f0b, 0x1985e991, 0x0f20792d, 0x1b8f79a7, 0x984a97e6,
+ 0x8e6cb85f, 0x2ed30814, 0xc2a81b93, 0x01ba7462, 0x4ccb3bf7, 0xc7aef331,
+ 0xe9fed8d8, 0x961738d1, 0x90d36969, 0x92f59d4e, 0x8c4bf004, 0x35e54a7c,
+ 0xcea8f17d, 0x6f94cc73, 0x790c5b14, 0x1349136b, 0x185beb87, 0xb1ac95f1,
+ 0x35b7aab3, 0x39064979, 0x52ab7d84, 0x3a3547aa, 0x4d5f500f, 0xfe28b8c1,
+ 0xbfd7a171, 0x79c37f06, 0x45ea015d, 0x10c88e4d, 0xa0ade7a6, 0xa1e2a377,
+ 0xe83f7b6d, 0x9f8efb0f, 0x0739dbfc, 0x55fd3bec, 0x9e807768, 0xbbcf7e3d,
+ 0xf4c7380e, 0x2e2c3dc9, 0x4fc18772, 0xfa63645b, 0x74ad8f7f, 0x8177e01e,
+ 0x9e791fef, 0x77257e28, 0xe593fdb3, 0xde70de01, 0x506f7f5d, 0x70c93055,
+ 0xf11f908f, 0x1fdea55a, 0x46c7a466, 0x2cb78b1b, 0xca59b1df, 0x4f7c6190,
+ 0x5c7f8c25, 0x378f43f5, 0xd1dfd03a, 0x63b859e0, 0xd9be0484, 0x7566435f,
+ 0x6445bdff, 0x025287eb, 0x151e67fb, 0x0f38466f, 0x2f6af7aa, 0x8fcb25f9,
+ 0xdd63a329, 0x27b0f54d, 0x187bcec4, 0x13e4b1e7, 0x129528b9, 0x1cfdc96f,
+ 0xfef0ddfa, 0xf33d743d, 0xee1f7ddc, 0xd9e719b3, 0x051f5ef5, 0x2a65b3fd,
+ 0x6de78dbd, 0x3ed88597, 0x41e262f8, 0xfe72ecf9, 0xc5cec436, 0x678de318,
+ 0x00db650f, 0xa9b0bf0f, 0x323cc4f1, 0xef6dce06, 0xfe20343a, 0x9f56f772,
+ 0x828bef52, 0x3ca1bb7b, 0xce5823ee, 0xe2902303, 0xf6f432bf, 0xd55fc05d,
+ 0x3ef13b4d, 0x8faaefb4, 0x9c2742aa, 0xe9ad4b90, 0x6e876a25, 0x8b20f903,
+ 0x5a7d9d39, 0xc49cf9bd, 0x9f866afc, 0xb7e7d4db, 0x20723e01, 0xd9fe5bdf,
+ 0xdbef4a04, 0xd1f3c52a, 0x6f3da5f7, 0xf7c3efd3, 0x3cdabe76, 0xed6b79b5,
+ 0x9c5e6a55, 0x0e4d3bf1, 0xb97ca9e6, 0x75f4eb78, 0xea8a297d, 0xa9917ef6,
+ 0xf3c3939e, 0x2d9f1a42, 0xe945a523, 0xa349f831, 0x84df076f, 0xd3f38e7e,
+ 0xbeb8bae8, 0x3f83c54c, 0x4c4fdd4d, 0x91957883, 0xa73a7a8f, 0x32462add,
+ 0x7c8dbe41, 0x7dcddad2, 0xb31b2128, 0x4acb162f, 0xa8cfc411, 0x15cebbf9,
+ 0x171cdf65, 0x14fe0fea, 0xe32b6ee4, 0x083d0efb, 0xf7e8314e, 0xff5c4537,
+ 0x54e43a57, 0xe90fffb8, 0x13f20e37, 0x4f787ecc, 0x4f98e71b, 0x808a0651,
+ 0x4f2c62ff, 0x81954afa, 0x97db3a83, 0x04e73c6e, 0x086dbbfb, 0xab51b8c1,
+ 0x69ef0f43, 0xe37a8f1b, 0x4a8f4ab4, 0x3f9be5a1, 0xdadace83, 0xc7177982,
+ 0xa771a92e, 0x58e2e64b, 0x39d8b4f3, 0x7778bddd, 0xf9a872a8, 0xfa540b35,
+ 0xfb6211dd, 0x4d370be9, 0xc9747a47, 0xa1fd54bf, 0xf50e46b2, 0x4b3e918e,
+ 0x3e63d7dc, 0x3e40a2da, 0x5e85df7e, 0xbba441e4, 0xda776e91, 0x371eec5d,
+ 0x7b8246a1, 0xe26d8eed, 0x8571ff70, 0x73ff7b10, 0x9df4ddb6, 0x479c63e6,
+ 0xdb2ff077, 0x2faebb5a, 0x908ff981, 0xf08dcf80, 0x425ff36b, 0xd4a7a614,
+ 0x2f3776f9, 0xf2c49912, 0x7f75d434, 0x815b9c39, 0x790793fd, 0xc6adcf96,
+ 0x35f834a1, 0x28f38d78, 0x7cf12be2, 0x8f035b41, 0xf877d979, 0x77067dd9,
+ 0xfd70e5ac, 0x9a4e8eed, 0x7bf6d15e, 0x30ca9baa, 0xfb43cb6f, 0xedb63b01,
+ 0x29f6c263, 0xcf7873d6, 0x0cf4b75b, 0xeea57cb1, 0xa30849e8, 0x374a62db,
+ 0xdebb3ff0, 0x0caf909f, 0x0a27de8c, 0x8c0ca0dc, 0x4122b7de, 0xb15957cc,
+ 0xf9eeba7d, 0x8e35768d, 0x9ef5eaa5, 0x24d48fe4, 0x696f8cc4, 0x9fc9a6f2,
+ 0xda778f26, 0x0a6f6665, 0x59198381, 0xd1879f80, 0x7afaa1bf, 0x3df99d9e,
+ 0xafa5cd0f, 0xa73c6f54, 0x3258a7db, 0x096bd196, 0xbbcf825f, 0x0f14bbd3,
+ 0xd8bdbd3a, 0xf8c3cfae, 0xe6d1f3a1, 0x3689c9a1, 0x189ca33f, 0x43d237bf,
+ 0xe919ef8b, 0xc007a462, 0x5bc67e09, 0x35816d7b, 0x38b7ce14, 0xaf7fb706,
+ 0x4d6ee115, 0xb9c0ac9b, 0xf9f4eacd, 0x3e01fe58, 0xb0fb074c, 0x768eceb4,
+ 0x8d87eaae, 0x225c5dea, 0x5ecbb557, 0xd9232ab2, 0x24d2a7b9, 0xb58993e0,
+ 0x17161991, 0x583e8f21, 0xa4f7045c, 0x32387c4e, 0xbff14203, 0x5646f07e,
+ 0xd77916df, 0xfcfb86e2, 0x690a8a4b, 0x2fd071fd, 0x95fa2fa0, 0x6efbe0db,
+ 0xf973c4eb, 0x1fdeccba, 0xcf9d2e65, 0xed66b1ee, 0xb33ed495, 0xf2aef5d0,
+ 0x4157e0f0, 0x4a5b2b7e, 0x542e218a, 0xba781109, 0xce2955de, 0xad872db0,
+ 0x7be9e3fb, 0x4f3cd91f, 0x76ee21d9, 0x8bae2d71, 0x94058795, 0xc588722f,
+ 0x573a0567, 0x6d6efd2b, 0x2993b51c, 0x5a26d77e, 0xd317e0dc, 0x97f07ee7,
+ 0xb22a26d7, 0xa35cf51c, 0x70077c1f, 0x7cb135ac, 0x0c6ffd82, 0xc65c8f8e,
+ 0x23efd82e, 0x34cfe025, 0x1a582cfb, 0x1725f3db, 0x37c8e79e, 0xb18978b1,
+ 0x76bb6dfd, 0x00ce49ae, 0x243ea8be, 0x1fc3fca1, 0x84559fd8, 0x613549c9,
+ 0x0eaad0e7, 0x53773c13, 0xcf08a87d, 0x84b9c0dd, 0xe07a754f, 0xa6ee735f,
+ 0x9e18af93, 0x44ae040a, 0xd0b71a88, 0xf9d5d56e, 0x9810d354, 0xdce3e10f,
+ 0xcf846e70, 0xa2ecd530, 0xa0afe7f3, 0xe087c525, 0xff70f372, 0x89e4fd4c,
+ 0x559fdc3c, 0x2d79aa27, 0xbe3e7626, 0xe557dd63, 0x39fb2b4f, 0xdd028f4a,
+ 0x25b1ff4f, 0x53f6c6cf, 0xe6d6afd0, 0x8429c75b, 0x35ed7f03, 0x7219e782,
+ 0xe0334993, 0xb19446cf, 0x47166fc0, 0x6c97caa2, 0x65fe9b3f, 0x9b36e940,
+ 0x7e53237e, 0x9fc1faff, 0xe3bbff22, 0x68b2ab4d, 0x59f8739d, 0x2e74c33d,
+ 0xef30b28b, 0x6bf565a8, 0xd006e74c, 0xc358e8ba, 0x4af1b0ea, 0xa3b33e17,
+ 0x143fc8ae, 0xba3171c6, 0x01ae50ee, 0x2c4c16fe, 0x901c23ae, 0xcb477f70,
+ 0x794b5957, 0xe2d1f806, 0x5d747a60, 0x3673c16d, 0x28179b88, 0xec4fe432,
+ 0xfa41ef51, 0x5786a5be, 0x7f4266de, 0x7fc04a09, 0x53e183bc, 0x54690ba3,
+ 0x5e3c81ae, 0x81ae5412, 0x0e7ebd7d, 0x7e83a24f, 0x96adf23f, 0x1bcfa089,
+ 0x0f28f9df, 0x82bf73ef, 0x2df233f5, 0xf9d243ea, 0xff6dfe9c, 0xe4fbd1cd,
+ 0xa9f91cfd, 0x03251df0, 0xec9cafda, 0x3951b722, 0x2c8853ac, 0xad9f8365,
+ 0x091b2ff7, 0xd91f4fd3, 0xa070af4a, 0x3ae3093e, 0x67bb13f6, 0x7e8dd400,
+ 0xec496933, 0x949dde55, 0x17ee3773, 0x7d346625, 0x85d610b8, 0x4a7bb1df,
+ 0xfcc14538, 0xee3b17d3, 0x9718236b, 0x373891b2, 0x9b898dc4, 0xd453f9a4,
+ 0xf1899af8, 0x945e7255, 0x87ceacff, 0x79085f7e, 0x2c6c63f2, 0x8fce81bf,
+ 0x823afd07, 0x848e58c8, 0xa0365938, 0x3df583d8, 0x4fe1f824, 0x588fff69,
+ 0xb2ca7c59, 0x8fe2e89d, 0xb7160e65, 0xe2c9c079, 0xf062718f, 0xe22bb016,
+ 0xd81710ce, 0x4b8f6d15, 0x0bcfee02, 0xdf709bae, 0xe309a0ee, 0x018b4fdc,
+ 0xb517ec17, 0x5bc8255f, 0x6d7f6748, 0x7eb5dd2a, 0xabe4911f, 0x0bf7ee20,
+ 0x9d3fab27, 0xbb8f304f, 0x801484fd, 0x0cc4dcfd, 0x3c744d4b, 0xd9839e69,
+ 0x1573bfbb, 0x043a04cc, 0x1811c6f7, 0x38becc7f, 0xb9e3d013, 0xe056b91d,
+ 0x4701178b, 0x66890f14, 0x5fd09dd7, 0x6f0a39e2, 0xf9673e16, 0x223c82fd,
+ 0xfc77e29e, 0xee19768d, 0x1ada7ad1, 0x56f311bc, 0xbde1379f, 0xee4a2fc1,
+ 0xf17f50e9, 0x3d02ecac, 0x305674fc, 0xbcf3e70e, 0x62f3e709, 0x2bd5fb5c,
+ 0x0c0fdc29, 0xc12ef161, 0xcfd00446, 0xbe40a982, 0xae5f3e93, 0xafa6b1f2,
+ 0xd11c8137, 0xc11c23fa, 0x29820c73, 0xcb48e51f, 0x276b6a27, 0x67d44f98,
+ 0xfc0f0b66, 0x8b5d371c, 0x8879853b, 0x25284d17, 0xb04dcf68, 0x05ce788b,
+ 0xbce199f2, 0x0f5544db, 0xb2b8fc4f, 0xbb07e584, 0x9ebdc30f, 0x7ef576cd,
+ 0x739f7530, 0xd727ca92, 0xa16f0891, 0x245dd7ed, 0x4d27886e, 0x8fdfa8ba,
+ 0x5f60ca78, 0x57fb514e, 0xf0855dda, 0xede89f38, 0x450d29bf, 0x2c3d6027,
+ 0xfc008a20, 0x6862d934, 0x09d23b07, 0x9febf0f7, 0xfd50e03f, 0x19924cdc,
+ 0xeda6c79d, 0x87e14d43, 0xb5fb446e, 0x5e037258, 0x0f95da76, 0xdfc03f20,
+ 0xc5cb9222, 0xb1f29f25, 0x1721c37c, 0x2cae046d, 0x8769fca4, 0x50dd5cf9,
+ 0x79d2b7ef, 0xf5903d5f, 0xfa087c0f, 0x93c7cae5, 0x8fdf4093, 0x95a5e957,
+ 0x7f01df1a, 0x7f19e2b9, 0xca7786b9, 0x2c8ed3e7, 0x37934f7c, 0x67e83be0,
+ 0x1f98188f, 0xf29bbf6b, 0xafc0d3eb, 0xfd04ed3b, 0x5ba59fb8, 0x699c80e6,
+ 0x7caab4e3, 0xd5d72c6d, 0xbf0fdcae, 0xc0bfe4fb, 0xbec28dd6, 0x75e8a517,
+ 0x83024fbf, 0xcfd72bd7, 0x68790698, 0xccf31176, 0x5173d452, 0x1e92fcd1,
+ 0xdf1a2fc5, 0x9c59dab5, 0xc99fe348, 0xe1e5dfbb, 0x840be4f9, 0x8748b2b8,
+ 0xcff1a2bf, 0xf7187f44, 0xe6122781, 0x67f9189f, 0x93fc3757, 0x40165e7f,
+ 0x9fe1756f, 0xba7f8c43, 0x0fda1be3, 0xe4616bde, 0xaa1c779f, 0xff2dddbd,
+ 0xfcf3c25c, 0xbe4ef7ab, 0x93657eec, 0x6a9f9f4f, 0x62d9c72c, 0x54bb2fe7,
+ 0xea96efbc, 0xbd01ca6f, 0xcec4d531, 0xe32409ef, 0xeeef0a16, 0xfcdeed38,
+ 0xefa86c9a, 0xda1e9814, 0x1ea33219, 0x78f769da, 0x669b7e30, 0x0557e761,
+ 0x23ce044f, 0xe45afbb8, 0xd921dfe8, 0x587660ee, 0xfb8f0c50, 0x37f1ec02,
+ 0x9d8c1f18, 0x2a43cb9a, 0xa662fa5a, 0x971d4617, 0xcfefc336, 0xbfccea3d,
+ 0x06967c00, 0x79dfa3b8, 0xcf784a8f, 0x0951f552, 0xf76fe3f5, 0xf1045dbd,
+ 0x79cf2d51, 0x8bb79ecc, 0xfbc2860a, 0xa1fedf8c, 0x8ead65ea, 0x5f404047,
+ 0x1fddee1a, 0x4b1e71d7, 0x297e6f7f, 0x674e51f0, 0xf93ef1bb, 0x3fdb1c60,
+ 0x11644d99, 0xb4719886, 0xdeb85ef4, 0xfcaf78cc, 0xff3b30ec, 0x27b0f336,
+ 0x2af2bdf6, 0x37ef187f, 0x8a77f6a7, 0xe7efec13, 0x6841f65a, 0xdd6cc884,
+ 0xd7354a0e, 0x26a33f30, 0x9349f81b, 0xf8a3fc43, 0x44327e0b, 0xb706bbf7,
+ 0xd07ff3a9, 0xa9fbb02d, 0x4bee1222, 0xefb09cfe, 0x363aea82, 0x40f4c9ca,
+ 0xe617eaee, 0xcb239c03, 0xcba06695, 0xd7162eb3, 0x5b0905f9, 0x6e6e81b2,
+ 0x8253f701, 0x0bf93ca2, 0x223df3ae, 0xd3b10e94, 0xe27d3df6, 0x8ff8c246,
+ 0x9c633d3a, 0xed099f60, 0x31bbe087, 0x824773e3, 0x588fb71e, 0x9aeb049b,
+ 0xab853706, 0x13bd9b78, 0x81ae0d0e, 0x8f97c64e, 0x00c6cb3a, 0xd03be01e,
+ 0x8e474d4b, 0x8d7be059, 0xcf7b821f, 0xe2883e30, 0x4e83e00b, 0x4016e0be,
+ 0xa283c35d, 0xfdb7cfae, 0x8b42f88b, 0x17c8f46b, 0x7e70b710, 0x0b98be2f,
+ 0x05f23578, 0xce3ce7b5, 0x505cf618, 0xc6937962, 0xe7b13fe7, 0x896efbe3,
+ 0xd913de60, 0x6bbf6567, 0x7dc049e8, 0xd8b8df90, 0x1c9f6d98, 0x28a6a4cb,
+ 0x7664e559, 0x2a3bf6bd, 0xda1cc223, 0xa2a8239f, 0xbced0db8, 0xdd27a87e,
+ 0x31c8fe2a, 0x46fb838e, 0x033e3731, 0x1270d0ec, 0xcc236bd8, 0x87906125,
+ 0x1989b65d, 0xdae63f60, 0xfcc36426, 0xfab21e5f, 0x5ed2584d, 0x9bfe5bee,
+ 0x7da772ad, 0x66c3e9a5, 0xfc6d5bb5, 0x4c7f2a35, 0x2779d852, 0x70d1ebd0,
+ 0x9003eb68, 0xc2e0e009, 0xdadf4db3, 0x22878f50, 0x00936f14, 0xfd878a0e,
+ 0xfb04691c, 0x24a4df21, 0xb03b064f, 0x3800584f, 0x9d7ef6db, 0x92cef109,
+ 0x021febd0, 0x3eda25bc, 0x0fbf5bac, 0x35b7b46b, 0x3ff3487b, 0xf3497b34,
+ 0x82aec17b, 0x1fd532f6, 0xbed99971, 0x05b084d8, 0xe47853ef, 0xa2957cac,
+ 0xe740b3ca, 0xe3cea251, 0x7082d266, 0x4ca9f769, 0x7251f153, 0x39abfa88,
+ 0x54c84ed0, 0xeaa9878a, 0xdd532a7d, 0x6e22fbfa, 0x3efb1b1e, 0x9e9fad15,
+ 0x1bae37de, 0xa3f61ad7, 0xc879687e, 0xf94feec7, 0xc3f98fbd, 0x7ef007e3,
+ 0xb1dfd601, 0x09feec59, 0x21c3c317, 0x763af629, 0xf1eb9551, 0x9c0e48a6,
+ 0xe7bfdec7, 0x1e6eb8ef, 0xf7f7f3d8, 0x771c8ec1, 0x97902042, 0xa8c4fe3b,
+ 0x180fcc78, 0x695f232b, 0x6f3f7afd, 0x9cf611b4, 0xccdeff44, 0x728f0a41,
+ 0xc167c025, 0x8f5395f2, 0x9dfd0a3c, 0xe8902a3f, 0x92451f73, 0xe5c42067,
+ 0x1ddfd48b, 0x7b31c83a, 0xa83f6b4a, 0x11c7defe, 0x21216f95, 0xc567bb43,
+ 0xa9e7451c, 0x1a1ffdea, 0x2f1ea75d, 0x74e4213e, 0xfdfc0fa5, 0x5a10e233,
+ 0xaa9ce1fc, 0x9ff3490f, 0xf5ce7cf0, 0x600a778d, 0xc69f5fbf, 0xdc6a2513,
+ 0xe9ea641b, 0x4e21c547, 0x6ff60d3a, 0x4e8f33f3, 0xb7e5bc83, 0xf4814c78,
+ 0x99be7686, 0x3e16f503, 0x462abde6, 0xba1f5efc, 0x9955ef13, 0xa3e4cf1b,
+ 0x5fc7f1a7, 0x3864f94d, 0x3b309dd0, 0x4bdd8f30, 0x81efa462, 0x1491ff3d,
+ 0xbe3dda19, 0x91bfa3bb, 0x2a9caf0e, 0x9eac7dc0, 0xdbe461e8, 0xfe9e747d,
+ 0x5377e12b, 0xbf8fc42d, 0xfac2ea9b, 0xac34beab, 0xddeafc6b, 0xd81264fb,
+ 0x4e9f1a79, 0x337c6249, 0x49a3f76e, 0x2f49dec4, 0xc586de23, 0xc97ffe33,
+ 0xee25d9aa, 0xa3e8d359, 0x843ae977, 0x2d27ea8c, 0xaa563790, 0x70fb3ac2,
+ 0x4425da11, 0x5c62cf3d, 0xb7f366df, 0xda75014d, 0xccfeefd3, 0xf57acb94,
+ 0x6fc5397b, 0x0eb00bd5, 0x99ab0916, 0x78ed531e, 0x9d231e0d, 0x08a523df,
+ 0x19f0777f, 0xe708c0f9, 0xf6f91d4b, 0xda07ae0a, 0x18cce0ef, 0xc6262598,
+ 0x8f868798, 0xc7ae8499, 0x8f5fbdd9, 0xdbd78c6f, 0x178ee7ef, 0xdad011fe,
+ 0xe919bc9d, 0xf4d76c66, 0x900c1147, 0xec1fa58b, 0x29f1b993, 0x8ba2df48,
+ 0x3ae85112, 0xcfe9fa43, 0x2b9293f5, 0xb956df91, 0xf8eeb3d8, 0x4f22faad,
+ 0xf93b233c, 0xd87a6c4e, 0x5bb77c06, 0x1c41b7a8, 0xf4fb3af5, 0xc2bd103a,
+ 0xe2660bcf, 0x131115fd, 0x94dad081, 0x886699d0, 0x243f7833, 0x20a1be78,
+ 0xf0327fb4, 0x0b42abe9, 0xe76d59fa, 0xca387909, 0xd50a6cee, 0x6b2ec0d9,
+ 0xf3e7664a, 0x5d10260e, 0x78c5f4fe, 0x8e9a6fa6, 0xc4a69d9e, 0x62ee1f68,
+ 0x28833cfc, 0x9ff439c9, 0x7f29eb45, 0xc7dc1f80, 0x42927181, 0x325afdce,
+ 0x39732dd8, 0xf6da23f4, 0x992d798e, 0x7b7adbc2, 0x2999ea02, 0xe9ddf74d,
+ 0xfe0884a2, 0x6f3e2463, 0xfef0e32f, 0x8dd92284, 0x59c5a2f5, 0xf98df7e8,
+ 0x09466926, 0xa220dfb4, 0xaf8533df, 0x755e2014, 0xabc38d3a, 0x9170f63c,
+ 0x623df85a, 0x0e3674ff, 0xc093f971, 0x24a77d3f, 0x66fe0469, 0x07d5ac9e,
+ 0x122eefe1, 0xfab6ff83, 0xcdfb73a5, 0x2cf57db4, 0xa78df30e, 0x3f8832b8,
+ 0xd68a7f8a, 0x5baf384b, 0xc005a942, 0xf58a33d7, 0xaac31ee7, 0xd4ab393d,
+ 0xfbd10246, 0xe50b9cf9, 0xfdb5a0fa, 0xf11dfc56, 0xf98122bd, 0xa37e7269,
+ 0xe7b3efca, 0x9bbee924, 0xa9dd984e, 0xaa4dd5c9, 0xfaa8ddfc, 0x193d73cd,
+ 0x094bf1ba, 0x40fe87b3, 0x64810bda, 0x7ed8b8f7, 0x96f6b4f4, 0x25e1f3c3,
+ 0xd068dfbe, 0x310d3787, 0xe57cbdf8, 0x348be45a, 0xc8f78dce, 0x37edf5b8,
+ 0x8dd7d58f, 0x0fd46bf2, 0x8f8b20b3, 0x3427aaef, 0x2f6b307d, 0x683c422f,
+ 0x33c53e56, 0xbb7ac5da, 0x317d27bd, 0x7d1bae26, 0x17be4971, 0xfa2e90cc,
+ 0xefe2e3e2, 0x4b7e2fa5, 0x54b196dd, 0x578edfae, 0xa4fecdd7, 0x298de83f,
+ 0x81478efc, 0xbae8da8f, 0x47c18e69, 0xc5a3bada, 0x1ca88a01, 0xc5381ea3,
+ 0x5ca663f6, 0x91fe274c, 0x0e80719d, 0x12ed423d, 0xa97b0c77, 0xe51b3e35,
+ 0x68ef43ab, 0x2eca257a, 0xb87ef311, 0xda85325d, 0xc02e52a3, 0x2be10fd7,
+ 0x2925ef52, 0x882b8482, 0xc19da61f, 0xa0579038, 0xcfae2cfe, 0x817f224f,
+ 0x3b12e3fe, 0xaf68c3e5, 0x0ae87168, 0xe94f6697, 0x1e23a5f9, 0xc3dd9339,
+ 0x1149f1aa, 0x7fe413e0, 0x04fb8f26, 0x7fd41bff, 0x8000b303, 0x00008000,
+ 0x00088b1f, 0x00000000, 0x7cc5ff00, 0x55547809, 0xf579f096, 0x55492d5e,
+ 0x146caa92, 0xb612f08b, 0x84582484, 0x5916ec80, 0xa014a358, 0x8168cb80,
+ 0x9a126b0b, 0x69ee9c71, 0x0242a6ff, 0x83b74343, 0xe8cedad2, 0x3ad857f4,
+ 0x08b41a83, 0xd09d0301, 0x584c5015, 0xf82e0834, 0x1a6d1ad9, 0x84490ed1,
+ 0xbfbb46d6, 0x739cffcf, 0x2aaa4bef, 0xffff4d85, 0xb49fdf3f, 0xdeefb97d,
+ 0x67b9ef77, 0x979ee73f, 0xb3559bdb, 0xf6e008ad, 0x14078a99, 0x77f1d000,
+ 0xe042c022, 0xadacc37f, 0xc78ef016, 0x69fcd7be, 0xe7f80d87, 0x9c2ffc3b,
+ 0xa42cfc90, 0x900bcf50, 0xce54b009, 0x7d57fc5f, 0x3c5e3d33, 0x52fe7a27,
+ 0x92b9fd98, 0xf81b700c, 0xf71c30cd, 0xff8ec5f3, 0xc7154bec, 0x7e8b2e97,
+ 0x4a4ce99e, 0xff8790bf, 0xbe230118, 0xd4ca0153, 0x22b79dba, 0x5527ddbc,
+ 0x334c558f, 0x390ffed1, 0x350ffec5, 0x7c800c97, 0x1674df80, 0x3db1f8a7,
+ 0x1c2111b6, 0xd1bad00d, 0xec71edc6, 0xefc5f107, 0x3c66e7e8, 0x21fc059f,
+ 0x52b4b607, 0x4801b721, 0xc4ed1805, 0xff602745, 0x0d3f9e2a, 0xc02486c7,
+ 0x5c2473ef, 0xe7af00d9, 0xf104e798, 0x5eb8c3bd, 0xe30dd700, 0xf75c01fa,
+ 0xf72746c8, 0xe6e8db5f, 0x442e0dfe, 0xfac0066a, 0x37af2714, 0x8776f72f,
+ 0xe35bdf1f, 0x50e7e6cc, 0xf844da3e, 0x7b2fe036, 0x1004086a, 0xac77afdf,
+ 0x807494d0, 0xb1e2b72a, 0x01d1f566, 0x8e58e34f, 0xbe25cbf3, 0x102ab72b,
+ 0x1fe5e7c4, 0xc4072bae, 0xee33575f, 0x2aa9f887, 0xfc368355, 0x63d34967,
+ 0x0cdf453b, 0xdefa08d6, 0x33028e22, 0x86cd16b5, 0x28f02cfb, 0xf1f7151e,
+ 0x6ff78936, 0x1d412af5, 0x278b79ff, 0x63871e9a, 0xae58bee8, 0x0ffe80b3,
+ 0x47305bdf, 0x9d718609, 0xdfa29305, 0xd6757c5b, 0xfed8cae7, 0xe898b47c,
+ 0xbf3fb63e, 0xb7744edc, 0xc1863fe3, 0x95fba230, 0x8d6fa58b, 0xc5ba3e85,
+ 0x8e74b1b6, 0x9d16bf1d, 0x673a27ef, 0xc6ce9b5c, 0xce8b7ffb, 0x904e110f,
+ 0x1bf470be, 0x30049e8b, 0x1a07e9bb, 0x55f679d1, 0x32add78d, 0x861433ce,
+ 0xd4fe79d2, 0xb76ff859, 0xaafcdf42, 0xfe2d2fa6, 0xe79f6b82, 0x22bfed6f,
+ 0x69fde745, 0xdf7e6f5f, 0x8034f3be, 0xf9ce78c1, 0x8df8d139, 0xbd2c6ba5,
+ 0x62f7ca16, 0xe635b5e9, 0xa05d061c, 0x60689913, 0x555fbc1c, 0xd16b8e19,
+ 0x162e97ad, 0x7e4f08ff, 0x5f8071ff, 0xd6fab9f3, 0x76827493, 0xe02057cd,
+ 0x03c84732, 0x052075f2, 0x0ade5be9, 0xec0444e1, 0x3e738b96, 0x28f5a8d7,
+ 0x39c469f0, 0x8353e7e8, 0xfadf6ace, 0xb2075765, 0x96fb19fc, 0x14b01069,
+ 0x972173d2, 0xd255f0b1, 0x7e69233a, 0xcb68f980, 0x10b2d32e, 0x05ba639e,
+ 0x9b51f5ee, 0x4e03da28, 0x9d1a07a1, 0xfbb75e26, 0x6e099b2b, 0xf0e57804,
+ 0xf8406280, 0x09e7563c, 0x33218bd2, 0xc945fbf0, 0x9cdfcf3a, 0xdc048104,
+ 0x9b76b41f, 0x2b44f90f, 0x3941c806, 0x825906d3, 0x9d64b835, 0xdc91f616,
+ 0xa8347b75, 0xd1bbb946, 0xe048ef78, 0x6c92402e, 0xa99474fe, 0x0fde8b26,
+ 0x79c54fb7, 0xfa6a1537, 0xb2e29c36, 0xf1a03fea, 0x93ab66ae, 0xf83eebde,
+ 0x5a662dcf, 0x20f02be7, 0x335af084, 0x4f8e1532, 0xa4839873, 0x93d4ca37,
+ 0xddfb09aa, 0x8fa4003d, 0x970b2da6, 0x3a6dd200, 0xb138d7b4, 0x8c74429d,
+ 0xd0bfbf43, 0xde843379, 0x9a74881a, 0x4334e921, 0x6692abea, 0x4946f595,
+ 0xac841a92, 0xb374fd3e, 0x408cd1a4, 0xee0a497b, 0x3c53433b, 0xf9bfd835,
+ 0x8fc516aa, 0xba3e932f, 0x951f4fb1, 0x3dbdf5c9, 0x019686ba, 0xff344266,
+ 0x3d0a3596, 0x798b6254, 0xbe0fed2e, 0xe6557cc9, 0x429f1e8c, 0xfbf913ba,
+ 0x825e8c62, 0xa653fb18, 0x03b935fe, 0xc58af0f1, 0x8454defb, 0x19b4e7bb,
+ 0x70e7c59e, 0xfb933b11, 0xc631a7e3, 0x07b6c51e, 0x757a270f, 0xe215eb84,
+ 0x07f50723, 0xd7b1f579, 0xa3b63f9e, 0xf18e98a7, 0x0d22dd4a, 0xcf2d99b2,
+ 0xf0fb33ba, 0x92bf0fde, 0xad78b10e, 0xdbde7a97, 0x8e8d7ce8, 0xad8f0fdb,
+ 0x979ed8b3, 0x48d749fc, 0xf8bdfdf5, 0x95e5e434, 0xe25e890b, 0x0c2e57ff,
+ 0x4afdb2f2, 0x0c3e59d2, 0xfe783879, 0x51e92272, 0x21aea7c4, 0x6cb8f49f,
+ 0x9f99679e, 0x06841c85, 0xc36e0a8e, 0xc12485fe, 0xf624aff7, 0xbc23cf1c,
+ 0x3cf262df, 0xeb68db4b, 0x202a2f87, 0xd175b9fd, 0xe2803379, 0x2887e505,
+ 0x84ee8a4f, 0xa00db1bb, 0x05ff113c, 0x72482152, 0xd0108662, 0x785e35be,
+ 0xd319da9a, 0xfbc214f4, 0xddb35c65, 0x29e9eb41, 0xd7f0f7c4, 0x057d132b,
+ 0xbf5ff1fd, 0xee1a7c11, 0xe6d1b0d3, 0x1c2f50d3, 0x7ee4e8d8, 0xb73746e3,
+ 0xdcea3687, 0xfc913a6e, 0xaa1ff243, 0x169f16bc, 0xa5e657a1, 0x0330fd0a,
+ 0x35c10ef5, 0x00609403, 0x23c66f79, 0x7288f2c0, 0x10a4dc10, 0x393cf0bd,
+ 0xfa44f87d, 0xe888ee5c, 0x3b56ad43, 0x82a59321, 0x67985ee9, 0x09d1f7e2,
+ 0xd59f3e08, 0x3fd23e7f, 0xfc8cbfaa, 0xefc38416, 0xb0b996f2, 0xb37c390d,
+ 0x7adf885d, 0x4bd1e965, 0xf4b9fdc0, 0x43b95ebc, 0x8feb84bd, 0x1f84cf0f,
+ 0x8f18bda2, 0xe2bc2184, 0xff045dcf, 0x100b1684, 0xb2b0d07d, 0xf21a167c,
+ 0x5ca2b5f9, 0x8448fdc0, 0xef8c1bbe, 0xc4c3cb59, 0x23a0074f, 0x645ef08d,
+ 0x7e49d9f3, 0x3f04b997, 0xdddb9578, 0x3937ae0a, 0x0951e2c3, 0xf1bee1b4,
+ 0x2d7f11eb, 0xce21b819, 0x1cc9696f, 0xb713e7a2, 0xc93ef1bd, 0x08e6d7b7,
+ 0xcc986cab, 0xf6111d9d, 0xe33c007c, 0x74927f24, 0x476877dc, 0x0e4e3f5a,
+ 0x6abb9eb0, 0x6b5e9209, 0x09ec933d, 0xafd33ee3, 0xacbfd8da, 0x6e5117a7,
+ 0x8f26270f, 0x42133d65, 0x63f2430d, 0x6d98e713, 0x3c23aff6, 0x7a3e65a0,
+ 0xedfbdf0a, 0xafd20065, 0x543fdbd3, 0x312d0fc9, 0x40e80ee5, 0xa32a8f38,
+ 0xf27da853, 0x6e7ce4e3, 0x127724cf, 0xec9b0e7e, 0xcefbed3a, 0x0474bd46,
+ 0x8da9cbf2, 0xf9023a50, 0x368dade3, 0x746f4f6e, 0xa3667b72, 0x38a3db9b,
+ 0x3af3fc4e, 0xbd7f138e, 0x6fd4e381, 0x4f6a71c3, 0x7ad43ae0, 0x489872df,
+ 0xe5bc677e, 0xbc2da8d0, 0xfadb892b, 0x742c933b, 0x50c9c38e, 0xfc4fec67,
+ 0x370c4e14, 0x2ee50780, 0xdb53fdd5, 0xad3f680d, 0x1c6502fe, 0xf754d4c0,
+ 0xae3a6d5c, 0x8fe87b3b, 0x19f1c2be, 0x6a7ec3a9, 0x3b6f7843, 0x893868e3,
+ 0xf5c7d2fd, 0x3f883a9f, 0x92a2244f, 0xb7643c24, 0xc7365179, 0xc418d293,
+ 0x24c2f768, 0xfd19a7ec, 0xc8a5b9ec, 0x3a4a4b0a, 0xb005c0f2, 0x73e1b1f3,
+ 0x25df886d, 0x513fff76, 0x9b6812df, 0xfa9d3a53, 0xbc927010, 0xcb20e62b,
+ 0x7d2510fb, 0xadbfda11, 0xd4c4ff0e, 0xabc07f08, 0xf48d21fc, 0x02af44c3,
+ 0x77a674ae, 0xf7d2a470, 0xd5b798dc, 0x15313651, 0x2ed7f7f9, 0xc269f995,
+ 0x741bc534, 0x635f97f4, 0x7af384de, 0xe26fd129, 0xd4b559c5, 0xe2e3982e,
+ 0x4dd96fbe, 0xa5ff24b5, 0x5fbd6b8e, 0x5c87efc2, 0xc547d666, 0x638bce1a,
+ 0xe3798d17, 0xffc8c991, 0x0c4b69ee, 0x7d7c4b3e, 0x84935fd6, 0x567732fd,
+ 0x34752aa1, 0x6bb5df70, 0xbf978d1b, 0xe572c0de, 0x59e8f249, 0xa5ed8ac4,
+ 0xd33e3869, 0x24c278a1, 0xa93ed32a, 0xa771a34d, 0xcdb421e2, 0x553b8ef4,
+ 0x5423e344, 0x9fea4ccf, 0xd89d4bd5, 0x4e66d19e, 0x66f384bd, 0x6c78a4e7,
+ 0xf099def8, 0xff10ae8f, 0xf249ccce, 0x1714e824, 0xa4ae9f04, 0xa9eac7be,
+ 0x8f1ce9d6, 0x3ad32495, 0x6131e2ba, 0x92d6febf, 0x147045ff, 0x514052fb,
+ 0x91a5dc68, 0xc7e4fb1f, 0xe275293f, 0x0aa1fabc, 0x099cfc90, 0xe091fee7,
+ 0xa89ad99f, 0xf5402027, 0xbd296716, 0x9c516f57, 0x2befb89b, 0x5181f9a1,
+ 0x5c79fd66, 0x769de4f7, 0x6fe507b6, 0x745fb3e5, 0x6cc1cef2, 0x9adfca17,
+ 0x49ed4c56, 0xcbdbf093, 0xc39f2adf, 0x930826e3, 0xebbf2952, 0x1dbdf81f,
+ 0x4d293f25, 0x0c4ff5c7, 0x416eb173, 0x116a953a, 0x83e70d7a, 0x55dfef42,
+ 0x945bf3c1, 0x8f3a3f01, 0xa7e4aff3, 0xff715a14, 0x5109e959, 0x710ce7f3,
+ 0x8de7f545, 0x45aa5818, 0xfcf2b1d8, 0xadfea8ac, 0x88e94a45, 0x69bef988,
+ 0x45fd5109, 0x11d2aea5, 0x2b6ff311, 0x5fd5181f, 0x54565b72, 0xb269a67f,
+ 0xa11b1fd0, 0x7dc854bc, 0x9bfb2979, 0x0a87acd9, 0x1bee629d, 0x8e3f7e38,
+ 0x7f09b617, 0xfe85d0aa, 0xb4a5d214, 0x80fd88ad, 0xc68f7c36, 0x8f52ec8b,
+ 0x3ddda005, 0xfc80ec91, 0xf62fe209, 0x6677658b, 0x6305fa3b, 0xb768ae89,
+ 0x752fe023, 0xfaf1db44, 0xcc27e144, 0x0bad7f01, 0x75a739e9, 0x6557fb1e,
+ 0x6145d5e9, 0xbf467c20, 0x2a370b1f, 0x13779dd1, 0xac6ab61f, 0x890ce737,
+ 0xd4adafd9, 0xf48c7ec1, 0xb7c8e6ef, 0xe0217d8c, 0xc6ff276d, 0xffb18738,
+ 0x4733ceb5, 0xe17ec69d, 0xacd73adf, 0xa9a5859c, 0xcf5fe171, 0x9c2c4cfe,
+ 0x4f32a979, 0xfb15fe81, 0xeca9ad85, 0x7a4fe22f, 0xf0c13f3c, 0xcf51ca7f,
+ 0x9cf522b9, 0x585f4943, 0x673d6d70, 0xff2d7bac, 0x78d758cf, 0xde54ea1f,
+ 0xf7bf78df, 0x7fc4aeb9, 0x27e71bbe, 0xae9e79c5, 0x5cfe7fc4, 0x9a19fcf4,
+ 0x7940e35e, 0x278a0e3e, 0xa93f7840, 0x959ae46b, 0x52d6f59c, 0x5fa1f65b,
+ 0xf670b723, 0xb52d40f9, 0x27833b53, 0xb9fe78ad, 0xf94eaa39, 0xea2fc307,
+ 0x0aa56717, 0x55f8e47f, 0x78e3aedd, 0x53b7407d, 0x88ff51dc, 0xaaf8a76e,
+ 0x28730bde, 0x370ef48e, 0xc438a7ad, 0xf62d879b, 0xfa154def, 0xdf7c857e,
+ 0xfea90f68, 0x857f0415, 0xf251e3ad, 0xe9bf2a49, 0x1c5f10b1, 0xbf2f7f27,
+ 0x5c77bfbf, 0xbf683a0b, 0x1d048fe3, 0x7e7d08be, 0x22defebd, 0xe20ca662,
+ 0xa917c553, 0x096c4a4f, 0x51fd48be, 0xf54574e6, 0x83ff93c7, 0x0f76cdef,
+ 0xae6f7a8c, 0x0f35159e, 0xf21cd8fd, 0x902c6a87, 0x353e91a3, 0xcfc87a25,
+ 0xefe3c58b, 0x0e3df9e5, 0x6051b927, 0x7f55d74e, 0x29e4fb1c, 0x7d8bf811,
+ 0xc4553dbe, 0x9ec88373, 0x52273ae3, 0x556b6e75, 0xd0e6709f, 0x887e267f,
+ 0xbaac63ed, 0x95c3d68c, 0x1e77c4dd, 0xba0ae9bb, 0xe3d2f0e0, 0x686ae7f3,
+ 0x4de33dff, 0xfb1c38ff, 0x215f1ec7, 0xfb4d53fa, 0xfadfb1b2, 0x7fa27df8,
+ 0xd9bc69a3, 0xb819ec83, 0xf9296e7f, 0x7fbee90b, 0x9b75fa27, 0xd4155b1d,
+ 0xa8099503, 0x4cd5b0d7, 0xf7a6140a, 0x2ddbc7c5, 0xc0915f68, 0x175e6cc8,
+ 0x156ec0d2, 0xc26574f1, 0x13d920d0, 0x13abd8ad, 0x0c132ade, 0x9264777a,
+ 0x09da879d, 0xdd9d7151, 0xfbe1ef82, 0x0bff3665, 0xc9c26f82, 0x87a5ea3a,
+ 0x200d960e, 0xea9138fe, 0xede43c64, 0x7d26ea9b, 0x21edf085, 0x01fffefb,
+ 0xf078e6be, 0x3ec59ad5, 0x2579f59d, 0x86f38f64, 0x3e947921, 0x3a6a15fa,
+ 0x21084f3f, 0xeebfb0ef, 0xb1fe5375, 0x90f165c6, 0xf2427eff, 0x35b6f5ef,
+ 0xdaa18f32, 0x29a91f05, 0xb17bf5a6, 0xcff25b7d, 0x6a2fb919, 0x910ba1be,
+ 0x33d9c03f, 0xe8815174, 0x6aa87f13, 0xe1f90f61, 0xe490ff3d, 0x83f9f8a1,
+ 0x183f8144, 0x8fd1f3d2, 0x777bf9f1, 0xf1b679e7, 0x65a78173, 0x0e9aecc1,
+ 0x06b38fec, 0xe3fca06f, 0x47ff34a1, 0xad3b8784, 0x87cc91c1, 0xb449f58e,
+ 0x8e05e28f, 0x0ff88c53, 0x32dd3ce3, 0x705c7fbc, 0x46c1fded, 0x64e96576,
+ 0x7f637781, 0xe88db1c4, 0xf124def1, 0xe10780dc, 0x303e26e8, 0x0785eae0,
+ 0x8f393886, 0xd4ff2200, 0x2e8be325, 0xa7ec8f5a, 0xdc7910ea, 0xff38983f,
+ 0x8ac24552, 0x4de77dfd, 0x791a0f1c, 0xfb1022e0, 0x49b53e4d, 0xf803e065,
+ 0x96a2513b, 0xcb5c695e, 0x7684fdf1, 0xf6fe262d, 0x2a9d3db2, 0xd5a9bfdf,
+ 0xf6a0e25f, 0x5379e8fd, 0x093f1c65, 0x59c52a82, 0xc6623b93, 0x467fe71b,
+ 0x18bd4feb, 0x4d293cfd, 0x3041c3da, 0xb24f3228, 0x974dc641, 0x10a7664f,
+ 0x2b186b1f, 0x8b0f48a8, 0xd4a4c2ae, 0xb0d33d3e, 0x4959e711, 0x2db8da9f,
+ 0x8fbceb38, 0x88dc69f6, 0xf49a3f0c, 0x435b9baa, 0xc2ce0aee, 0x623630bd,
+ 0x0617291f, 0x2fbf2f1e, 0x23ae38f0, 0xb0d397e7, 0x43356e6f, 0xc3c3ef50,
+ 0x0c2f8914, 0xbbfe38df, 0xf6c1d17c, 0x62db626b, 0xead9e495, 0x711e8136,
+ 0x113d04be, 0x6c7d08f4, 0xea8d49cf, 0xb59e92ab, 0xca7ed109, 0x924fb978,
+ 0x7ad45067, 0xd062bf86, 0xacea50f3, 0xc663f256, 0xdfb1563b, 0x3b293292,
+ 0x93a2fd6a, 0x042ef8d1, 0x63e2979f, 0x71c087cf, 0x5ab3c4c0, 0x29327f94,
+ 0x63f983bc, 0xcfd187d2, 0xee8f9ca7, 0xfcc9a697, 0xaedd2c56, 0xfb184f85,
+ 0x7fe969cb, 0xde5d3e3f, 0xcda67c68, 0x8667c689, 0x039f1a2f, 0x6be34596,
+ 0x1f1a3fa0, 0x898d5783, 0x7d61bf1a, 0xd87f5461, 0xcd44a70f, 0x198342cf,
+ 0x75be1fd9, 0x91fcd45e, 0xf545163b, 0x67753f47, 0xe0dcfcd4, 0xbcf1a88a,
+ 0x2efe6bdd, 0x368417fa, 0x3427cd44, 0xfe87be9b, 0x4bfe3637, 0x53ff7ed4,
+ 0xa18daff4, 0xe7d256ff, 0xa85e8813, 0xecfb0b37, 0xa425b919, 0x6f4d5d3f,
+ 0x9b79437c, 0xf9ceb140, 0xf03cc0aa, 0x2fd8e0d4, 0x7a429f54, 0xdaa2306e,
+ 0xd6a37a84, 0x1ec8ab04, 0x71326a3c, 0xf390d31e, 0x3f84d317, 0xc89a62f2,
+ 0x7b78197b, 0xd922ed1a, 0x43ea5541, 0x248efa73, 0x935453f2, 0xfec9da09,
+ 0x1fd61e69, 0xbe101ce7, 0x0755f719, 0x4ac5e701, 0x982d2792, 0xbea8fc88,
+ 0xa9fc72a9, 0x8e83f20e, 0xe4e6a4f6, 0x9f8453ce, 0x4e9b0e2b, 0xfaa6ab7c,
+ 0xf0df6403, 0xa1e7a19c, 0xdef39fbf, 0xf1495846, 0xe65fd196, 0xe699bf5e,
+ 0xe67bbb2f, 0x7b7f8a48, 0xacaddf9f, 0x43a08d2c, 0xc51739e4, 0xa40eabf1,
+ 0xd867fb09, 0xdc7ec313, 0x3a6bd569, 0x538c3ed0, 0xbb407d85, 0xf10d2071,
+ 0x88f281f1, 0x0169f859, 0xed1f9d33, 0xb827df2a, 0x80df21d0, 0xdd9f4a6d,
+ 0xe643bfd2, 0xda3b20fa, 0x00937d6f, 0xf74438a3, 0x1de33df0, 0x955dfe86,
+ 0xecbbf8cb, 0xf97f9e88, 0xaf02e1fe, 0x90f620f7, 0xe22ce70e, 0x17fc063c,
+ 0x42fe5ea5, 0xd24ee5ea, 0xebf911c7, 0x2676bb55, 0x2e7e7f91, 0xc6e3f847,
+ 0x3a49dff3, 0xe54d2eff, 0x9dddaff3, 0x047cfeb0, 0xae422ade, 0xe3557ea8,
+ 0xf991f5c0, 0x39c6b5cd, 0xe7468afc, 0xa8e52758, 0xf923b5a2, 0xfe7f604e,
+ 0xb75c34c3, 0x7b95d772, 0xa6fbd00e, 0x67614c9e, 0xd2dfbc03, 0x82e380f7,
+ 0x28817fa5, 0xcd33b6bf, 0xa67570cc, 0x09613889, 0xbbe44e36, 0xb803e825,
+ 0xda637da8, 0x7c3fe22c, 0xbfb0561e, 0xa4cc15a0, 0xb3fa16bf, 0x33f484cc,
+ 0x3f6779e0, 0x69cfed1e, 0x1b73ef3a, 0xfb7ef8f8, 0x922a7bdd, 0xd6340fd8,
+ 0x8141d633, 0x3def3f20, 0x499cc057, 0x0ae99f79, 0x9fb817fb, 0xeefb9e8d,
+ 0xec99bc1e, 0xbbdfb1b0, 0x0ef4bfe0, 0xf022c5f2, 0xfac6baf0, 0x1134d740,
+ 0x4b03f97a, 0x44ed1d2f, 0xa66d0dbf, 0x3685e530, 0xbdf2b39c, 0xcf75774a,
+ 0x9c230fcb, 0x66f9af1f, 0x7f7082bf, 0xbfe7bcb4, 0x3bf3e00e, 0x4741529e,
+ 0xfdd9f1be, 0xbc447a5a, 0x2bfeee79, 0xafe86f2c, 0x2924ff3c, 0x1eac97a5,
+ 0xd60f9392, 0x322a34bc, 0x9f4e485e, 0xf74e9099, 0xe2d2933b, 0xc6c46fde,
+ 0x3f886ba5, 0xf6757e59, 0x5cbe0d4b, 0xc372f92d, 0xf9f9a30b, 0xf3dea486,
+ 0x2af3fe88, 0x3436c1e7, 0xf1af395b, 0x3587e48e, 0x31337e2f, 0x8f57cf32,
+ 0xa95ba97c, 0xf74b7275, 0x09fa3aa6, 0x1e5e4efb, 0xeaab71cb, 0x1e73a2cf,
+ 0x3269fabe, 0xf9bdf7f5, 0x6e079f2d, 0xbbf83ebb, 0x78917911, 0x79ea4aae,
+ 0xc54af497, 0xf94eab01, 0xb90392ac, 0x7ec2ee27, 0x1fea2b65, 0x5725cf3c,
+ 0x29a7b1c7, 0x00a83b1e, 0xc32ab7e5, 0x2be4ac09, 0xe520941b, 0xee34d6c3,
+ 0xfb1832dd, 0x1616ea6b, 0x2556bb11, 0x59567d0b, 0xb13704af, 0xe9873e1f,
+ 0xa365285c, 0xbfee50e4, 0xd778e3e5, 0x85feb171, 0x3cf6b08d, 0xf55d9dc6,
+ 0x38205e5f, 0x395a35d6, 0x292176cf, 0xfb8c196c, 0x84abda5e, 0xdc9f7a02,
+ 0x1c44b976, 0x98f42ab6, 0xf55df685, 0xe411c2dc, 0x381d7636, 0xb93d216d,
+ 0x59b1e1aa, 0x309179f2, 0x8b9641ff, 0x9595bbb5, 0xd5ac7991, 0xa4420ee8,
+ 0x02f842fd, 0x40eafb13, 0x2cfa494e, 0x435e1a6b, 0xb6bd42e8, 0xf58569ff,
+ 0x97e242da, 0xf9ef0e0f, 0xdf686fdd, 0x923dff83, 0x7d745ff1, 0x805f07f8,
+ 0xb94a8bfd, 0x633c5c0f, 0xb2b2f8a1, 0xde217cc1, 0xba6352fd, 0xcfda1eef,
+ 0xfd638f88, 0x10162dee, 0x10d93ff7, 0x82ec9e7c, 0x1cb2c7a3, 0x9a57f9e1,
+ 0xce68f080, 0xec0acb1e, 0xc8ce48db, 0xc11db85e, 0xbef57178, 0x84f18d74,
+ 0x78fac4b1, 0x3921a0f7, 0x5877a25e, 0xe9579f28, 0x5f10b4ee, 0x173f8657,
+ 0x9f8dfff7, 0x89c6f2cc, 0x574e5fb7, 0x273f33a4, 0x6437de4a, 0x30b9618c,
+ 0x90c3daf7, 0x60bee58d, 0xa9d90f45, 0x3b91070d, 0xbfb7a214, 0xec0ee087,
+ 0x7ce9d04f, 0x9f3e0725, 0xcfb111d8, 0xf47ca51f, 0xf95e59e6, 0xf099ac64,
+ 0xb193efb9, 0xf3df525a, 0xaac74cae, 0x97997978, 0xdedd85d3, 0x18bbec9c,
+ 0x9e09072d, 0xd95bee30, 0x147be764, 0x2d2d8394, 0x70729145, 0xc45daac7,
+ 0x07aa4de7, 0x1b2a0225, 0x79abfa17, 0xc887927e, 0x0cce36a3, 0x4eaa1f10,
+ 0xfc27f31f, 0x289bf715, 0xff508fef, 0x3ff74dcd, 0x39ac724d, 0x1e646560,
+ 0xf1d4d2a4, 0xe88516ab, 0xa26bc3ba, 0xf5810afd, 0x75f0ea96, 0x94553c70,
+ 0x7bdc53a9, 0x202cc274, 0x59bcfd3c, 0x39afbce1, 0x8b35bfd5, 0xe55c7be8,
+ 0x2fa396f9, 0xbbbee804, 0x11141c6b, 0x7f79c67c, 0x2a0c2e3e, 0x00b9b3ae,
+ 0xe6edb43c, 0xc4dd4b83, 0x38cf3fbf, 0xdd867ec6, 0x2bd20213, 0x503fe835,
+ 0x1f9ec7de, 0x093ad30a, 0x1522be39, 0xee9359f7, 0x58b4be64, 0x27ca1efd,
+ 0x36fb203d, 0xe08ab7cd, 0x8a27a5b3, 0xf5c87bf8, 0x48baf9e5, 0x6f74cdfe,
+ 0x4b7ce7e9, 0x69f05997, 0x71c00dd7, 0x4cfcd722, 0xe32f21a6, 0xb83b06cd,
+ 0xd6546aad, 0x44d7da46, 0x79e8dbf0, 0x1ea5c1d7, 0x2d9cdf82, 0x91333df9,
+ 0xff7622e5, 0xa99f888f, 0x62b4c0ce, 0x99e1166b, 0x9ff7a6f0, 0x7be4a1f7,
+ 0xf9a01f03, 0x115e4873, 0xfcbc6f54, 0xf8bd3f92, 0x7375d12c, 0x95c72faa,
+ 0xc2bcd7cf, 0xc6277629, 0xff9c3b95, 0x31b7c901, 0x89f095bf, 0xfcd16fef,
+ 0x51efc236, 0xc5b35f89, 0xfe593ba7, 0xdfed3a7d, 0xf141be7b, 0x3c8df7cf,
+ 0xff6c96df, 0xcfef9ef7, 0x54e67cf2, 0x2f5a37e4, 0x399e7819, 0xfe201839,
+ 0xa2824dab, 0xa8f8f84d, 0xe49b966b, 0x6f91cb6e, 0xd7bc9286, 0x40dc7926,
+ 0x9be6b179, 0x6fdc9196, 0xf3277419, 0xe42f17ff, 0xfb11aa16, 0x7f17a724,
+ 0x2f3be745, 0xe2c5b1cf, 0x7c73a1cf, 0x9c69cf2c, 0xefba496b, 0xf911e92f,
+ 0x7e921826, 0xd7b3fc5d, 0x7194d7b8, 0x61da479e, 0x8f38f38c, 0x5c890dd8,
+ 0xfa57b67f, 0x98f81ae1, 0xd1e0ec7f, 0xc2f2bfd9, 0xa92baa09, 0x36c13169,
+ 0xb5253e3a, 0x92fdee22, 0x0c119355, 0xb2186d7a, 0x8d3435d3, 0x39d89f3b,
+ 0x3ee116af, 0xf8550108, 0x0cf9d169, 0x255e2af0, 0xdaf18f32, 0x63cbeb9a,
+ 0x21afe33c, 0x63cd8d79, 0x969b0e4c, 0x23ae525b, 0xbcdaf19f, 0xd18cf9b8,
+ 0x5171d119, 0xc0ce8641, 0x7f047285, 0x4189c286, 0xf1833791, 0x26eabf94,
+ 0x9fe3855b, 0xde5999e3, 0x9b1cae95, 0x13e0ed0b, 0x3adb6c4f, 0x8470e50d,
+ 0x6bf503c0, 0xf1f5c988, 0xe6f507ec, 0xc31b5e47, 0x3dea387e, 0x4e02f395,
+ 0x1d0c4b09, 0x137fd08b, 0x2a27a541, 0xf63e12bf, 0xdbf1326d, 0x2dfd549e,
+ 0x9b4f4fa2, 0x092875ca, 0x15c5875a, 0x900eee47, 0xe076807f, 0x3e84339f,
+ 0x7b8a35b7, 0x65ee9b4b, 0x74e0993d, 0xe423538e, 0xd8432f24, 0x1f638aa5,
+ 0x2ca0b50c, 0x4c9d325d, 0xd7f5c7ce, 0xa64fafed, 0x73dade34, 0xd2a44f6f,
+ 0xff353b9f, 0xff3c0c82, 0x51aeca17, 0xb75bf236, 0x7e12c706, 0xae6ce142,
+ 0x20d02ccf, 0x87f615a0, 0x3c29eaa7, 0x9504ba14, 0x5b71a54f, 0x257e34d0,
+ 0x58555ff1, 0x30f6979c, 0x6dcc8aa3, 0xd5dfb854, 0xeb4a9358, 0x79b6fd55,
+ 0x97afe910, 0xf39f8432, 0xf13cd5e2, 0xcd1a06be, 0x25c33fbf, 0xa2682a99,
+ 0x324be37c, 0x5575d94f, 0xfec679e5, 0x55338d05, 0x7e41f227, 0xce11c778,
+ 0x7559368b, 0x73c26fa2, 0x94d1f020, 0xd5687ec0, 0x7640d9e1, 0x1e05dbaf,
+ 0x24f7c705, 0xfc447cf6, 0xd56cd3d0, 0xc1373ee9, 0x715203b9, 0x1eb23dfd,
+ 0xb619172c, 0xdcf7d1de, 0xe9a12fd8, 0x24439497, 0xe57be0be, 0x4c076d04,
+ 0x3be24477, 0xc959d849, 0xc3127b57, 0xe967ba26, 0x59efdf41, 0x4e0fab86,
+ 0x380d7de0, 0xec0ed973, 0xf85cf4b1, 0xe5c33a71, 0x05c83e24, 0x8d342701,
+ 0x26af49d6, 0x8e7cbd38, 0x09eea704, 0xaae1fd28, 0x208e8b1a, 0xa4a3cfca,
+ 0xc9f4a6cc, 0x5f625577, 0xb0b286df, 0xfca41b27, 0x9d2b6eb7, 0x8547d916,
+ 0xfdefa933, 0xf8e278ff, 0x9c21dab6, 0x48a80bff, 0x49b63b7f, 0x214e74a9,
+ 0xde122857, 0x0781428c, 0xdbb40baa, 0x7cef78c4, 0x2a4773e4, 0xe79e7fdb,
+ 0xf3ed3ab1, 0xf85e58b2, 0x0ff0d17e, 0x17c2521f, 0x76d2466e, 0xc94be63e,
+ 0x9a7573c7, 0x875c3c8e, 0x3cb8fef3, 0xfd8c2a34, 0x79ffab16, 0x3f57cfe2,
+ 0x80bdb15c, 0xb31eeff4, 0x4ff49ca7, 0xf671e047, 0xeb345fcb, 0x0ee422db,
+ 0x7264f486, 0x3ecc61dd, 0x3d36e755, 0xf776fe4e, 0xfba74541, 0xcf736ef4,
+ 0xb2bb8250, 0xd50b33e9, 0xfc1d5663, 0xb2ebfd84, 0xda5eff4c, 0x3563526f,
+ 0x864dcfd7, 0x873f5c1d, 0x20eb917a, 0x4fa16e43, 0xf51d9f2e, 0x1d04756c,
+ 0x06f293de, 0x6461fe3d, 0xbca49abf, 0x1c38a61e, 0x772dfddb, 0xf7f5a70c,
+ 0xf180fccb, 0x191c355e, 0x04df784c, 0x3c6b71af, 0x5c6a0eef, 0xaef79cbf,
+ 0xc46f5eed, 0xfe52d3fc, 0x56fdcb4f, 0x20dffa67, 0x7cb6d778, 0xc2d2a16a,
+ 0xa1a1f3aa, 0x3486f714, 0x4719c53d, 0x6fcaf48f, 0x69553c8c, 0x5f9a163d,
+ 0xaf581175, 0x536bbd20, 0xbd2f7e90, 0x396638db, 0x348fdf3e, 0x8b3b2149,
+ 0xe3d92af1, 0x60df66fd, 0xcefd5f9a, 0x8f4963d7, 0xf020241d, 0xaf375f7f,
+ 0x4378461d, 0x244e2ffe, 0xac0bdb39, 0xcd390cd7, 0xf7c53927, 0x8bff89f3,
+ 0x7acb9fa8, 0x7da58f79, 0x7ee5cb1e, 0x225c9013, 0x203cb3ff, 0xdfc93bff,
+ 0x3ca277cb, 0x59a3fbf0, 0x9bb4f7ce, 0xa337ecbc, 0xfdc91f5e, 0xdfd4c5e2,
+ 0x64ea5ed3, 0x843aa739, 0xf0d79242, 0x04275e11, 0x45f2d740, 0xfd22f80a,
+ 0x648cbcff, 0xf1242f71, 0xd8433939, 0x9e8e5083, 0xd873c1e2, 0x3e4a3555,
+ 0xe8a5ec22, 0x9a5a7b4b, 0xbf6d97f9, 0x26524698, 0xda5384ed, 0xd678ff49,
+ 0x6d28fffb, 0xa7d786d5, 0x73c3a82c, 0xf2a5386e, 0xf71961f8, 0x1c9f2585,
+ 0xb21af991, 0xa89a7a1b, 0x13e7a61f, 0xe5f54fb0, 0x4bebbd13, 0x9a4d1cc8,
+ 0xb528e3b3, 0x12a17c53, 0x2da6db72, 0x166a3f6b, 0xfc479e62, 0x6e6470d7,
+ 0x75e3d51e, 0x0242b39f, 0x6df0d882, 0x222f47cf, 0x8c3e1e1e, 0xa7638ff8,
+ 0x7fcc38f0, 0x060d7fe8, 0x6ef1ff77, 0x4091ea45, 0xc7e27cd2, 0xafb506ae,
+ 0x2254808f, 0xfddf5363, 0x007b7da4, 0x677fe76d, 0x2267077a, 0xf00ccf3e,
+ 0xfa7ddb73, 0xcb124cdb, 0x5c4567fd, 0xe6f160df, 0x6434ff11, 0x871ba863,
+ 0x2299ad4f, 0x856453ef, 0x379cf7b8, 0x18390a67, 0x0aed8015, 0x33aaebc7,
+ 0xd4bf7488, 0xe82d7aa0, 0xc0845d2f, 0x6fa4a992, 0x01f75e64, 0xfc5e3f90,
+ 0x283cfa45, 0xdf900fbb, 0xc1eb7682, 0x11d6c45f, 0x316fd978, 0xeb0058f2,
+ 0x2b5fc44d, 0x0ff8149b, 0x67aac5c4, 0x93afe7a2, 0x1babf275, 0x8c1b1d77,
+ 0x5cf35d74, 0x2df938cc, 0xe211ff7c, 0x5d5d7878, 0xcdc33d74, 0x197fd299,
+ 0x7fc9c30e, 0x3d62be41, 0xd5a0d661, 0x60ac7c8a, 0xf6224314, 0x0be04992,
+ 0x67cb2bf5, 0x8a6f61be, 0xb9ea5e85, 0x94a75c04, 0x94743bbb, 0xd4a681ea,
+ 0x8f687965, 0x9f189a29, 0xee2598d2, 0x4aa0b4a7, 0xbc930c75, 0x77ec59fe,
+ 0xa967bc07, 0xd49564de, 0x5fc4e097, 0xd3c8fbca, 0xddfe92af, 0x9d6c60ea,
+ 0x9553c0a8, 0x8219379c, 0xcaefb435, 0x69dea2dd, 0xf9e8eeed, 0xeb4f1255,
+ 0x8c7d3a9e, 0xa11585d2, 0xa7897198, 0x3a98c6aa, 0xdc38b116, 0xadef299f,
+ 0xf5fb7d64, 0xd1fc5bd6, 0xb78dfc2c, 0xf8c63ae5, 0xef914ce6, 0x1063c4ad,
+ 0xd505d77d, 0x2ad1f120, 0xfc2c9025, 0xc72c705e, 0xb067ddf3, 0xbdcfac81,
+ 0x3ee9e25f, 0x7e7c3fc9, 0x19e2bf7c, 0xfdc57df1, 0x7f868b3f, 0x832cf80d,
+ 0x0d83f9f1, 0xde50b03f, 0x56df9631, 0xffd999d5, 0x13f1235d, 0x7a6b5fcb,
+ 0x858767f9, 0x7f2c5bec, 0x6b95fa55, 0xf6fc2fc0, 0x0df85bff, 0xcb91af3a,
+ 0x398735ac, 0x09f6b53f, 0xabf943c5, 0xf7ab9d6b, 0x7f7cf23c, 0x359eb9ef,
+ 0xc6063de8, 0xa4e7bd30, 0x63bd175d, 0x96bdedfd, 0xe726bcde, 0x66b72f05,
+ 0xe0dd3e73, 0x6675d8ab, 0xf67dbf49, 0xbd7fc253, 0x276258d4, 0xa4fba3ff,
+ 0x9ce8a3c9, 0xc02e4caf, 0x566f8ff3, 0xee91fc81, 0x033be1a6, 0xa9e17f08,
+ 0x5f94c5a2, 0xed0a7f1f, 0xb707dd13, 0x0257fd16, 0xd27b07df, 0xb667ee48,
+ 0xbdfb488d, 0xfb61d783, 0x70b27dde, 0xe9e93967, 0xb445a593, 0x54e382ae,
+ 0xed285e9f, 0x42c9f554, 0xbd84477b, 0xc8a64dfa, 0xff716fcf, 0x1b8a51fe,
+ 0x7b35ef66, 0xdb323f28, 0x8094dfec, 0xa0be15f0, 0xb771aa78, 0x9e47ed63,
+ 0xbe5175a4, 0xf38acd28, 0x8d08e9fe, 0x1851ed57, 0xb2a6eefe, 0x3f643dbc,
+ 0xec87aa83, 0x7dd37762, 0x1f920ff9, 0xfe40fcd4, 0x1dfb117d, 0x66fa154b,
+ 0xb6660df6, 0xec839dd7, 0xbca72ebf, 0xeb1777a8, 0xfb43ce8d, 0xc37dfc2c,
+ 0x78dc051e, 0xa3ee63ce, 0x3a1e132f, 0x50b69c0f, 0x70d25010, 0x4711d2da,
+ 0x25ed1b7f, 0x9cc2f30c, 0xe161ddaf, 0x7ffdcdfa, 0x2b79d0b0, 0xf384fb9f,
+ 0x7e286b6f, 0x19ef3f20, 0x3a77bf95, 0x85aafcda, 0x4eb2b4f8, 0x91590181,
+ 0x271e66e3, 0xcffd4afd, 0x369e84ea, 0xe4857ff8, 0x0dff8377, 0xf5215879,
+ 0xe35b7dda, 0xffa1bbf3, 0x96ef041e, 0x03deb841, 0x0eb9cb75, 0xd11d81e9,
+ 0xfc5257f3, 0x17cd237a, 0xa9f2befc, 0xbdd5f1e8, 0xfd601e7c, 0xbf47ab1f,
+ 0x2e7ff433, 0x5f9f12e4, 0xa618af0e, 0x7d7d3ca1, 0x8830cd7a, 0x293caf93,
+ 0x6ec306fd, 0xd89b0e5f, 0xebcec5ee, 0x2162bc6a, 0xfad55b7b, 0x6773f627,
+ 0xf4c97d35, 0xe16a6f28, 0xc05bd97a, 0x79f08ebf, 0x49dd934b, 0x877976fe,
+ 0x9af303d0, 0x42a0c1ac, 0xa25aa1e3, 0xf161f773, 0x90e049bd, 0x4816fec2,
+ 0xe252b8bd, 0xe3c4a575, 0x06e38c4a, 0x8c8c7d53, 0xbc652be3, 0xd7673abe,
+ 0xa9292a31, 0xdaebe394, 0x1e13268e, 0x5bd081e7, 0x6f4242f3, 0xec31f419,
+ 0x40beac50, 0xd10f770b, 0x95936d77, 0x4be7d6eb, 0x0ebf35bd, 0x5fd296f5,
+ 0xb40f747f, 0x7ef1fc8b, 0xddac7701, 0x9e886cad, 0xfc201aef, 0x7fd2cbd8,
+ 0x4d101c2e, 0xb01ef297, 0x9e7f7e53, 0xfc827aae, 0xfb46bb56, 0x7e458eb7,
+ 0xf55bf5c3, 0xeaf129e1, 0x4df68cb5, 0xfd181719, 0xc3679405, 0x0ee721f9,
+ 0xffdc6447, 0x7f84039f, 0x1ab266b3, 0xc446ba20, 0xb30a0b49, 0x7349c6e2,
+ 0x8637f409, 0x71b3f7dc, 0x77927191, 0xb7e228d7, 0x2cef757f, 0xaaa6baa7,
+ 0xba2fa13a, 0x29bae126, 0xfb03f7e4, 0xd67555d1, 0x5533c520, 0x7dfc2fc8,
+ 0xc909f11a, 0x46529363, 0xc671827c, 0x42feb4ed, 0xf3c4eaba, 0xfb446c2f,
+ 0x2c2fcb8e, 0xabf992fd, 0x3738846d, 0xbc406de2, 0x3788c3b8, 0xbf0aaf2a,
+ 0xa95e78d6, 0x51dc7075, 0xb5ea24d9, 0x337c8e1b, 0xede10b34, 0xd0f3fe6e,
+ 0x3e4f54e5, 0x86e7d840, 0x54a7d0e2, 0x1ef5f457, 0xb5ff5c5b, 0xb52bff57,
+ 0xe6950f2c, 0x6bf64c8e, 0x791fa20e, 0xb7d1ea13, 0xa538e0bf, 0xbdc248e1,
+ 0x5aebcf94, 0xfce61fe1, 0xc3553a1e, 0x3783f626, 0xe4b72d41, 0x8dfa451f,
+ 0x4ea29d2b, 0x3f6941e9, 0xf208ffa9, 0x773883f5, 0xf97f6146, 0x8549f437,
+ 0x10d5ebe4, 0xe95532d8, 0xa42a07af, 0xdfcdacdc, 0xf6ae85b5, 0x0aa7fd63,
+ 0x31184f29, 0xf58cbdb0, 0x8633fe9f, 0x4edfab5f, 0xbbb8ff64, 0xae52754d,
+ 0xabfbf119, 0x6227e441, 0x271d905c, 0xe485fb5f, 0x7f794ecf, 0x65493d5c,
+ 0x8b2699fc, 0x10b7f0d6, 0xdd37cc8f, 0xb2411da7, 0x5f87796f, 0x583e26cd,
+ 0xdefa3bbb, 0xe7e8e889, 0xc8a0b1ba, 0x7cec8547, 0xbf8c6517, 0x31d5f874,
+ 0x6fd56fc4, 0xd04a3b7f, 0x96519be7, 0x67c36bf4, 0xe2228ab4, 0xe2229366,
+ 0x475afde6, 0x556bc532, 0x645f5507, 0xef41bf3d, 0x813ca597, 0xf503f226,
+ 0xabe67403, 0x1fc126ea, 0xe2d166a6, 0x7e444bfe, 0xf7fbccc8, 0xbe462f1b,
+ 0x067b1ef9, 0x40f21704, 0xf987b995, 0x89b4eaaf, 0x7d3aa9e1, 0xc4447339,
+ 0x775a017b, 0xeabfe900, 0xc4fac075, 0xe76fa40e, 0xd891f7d3, 0x027eff9f,
+ 0xb2c761fb, 0xfb8b97b7, 0x7f48152f, 0x9af6fc3d, 0x60f691d1, 0x2f7100e2,
+ 0x3707840e, 0x10bf3f79, 0x6c3c4bfb, 0xbf324582, 0xaf79f820, 0x2e309b8c,
+ 0x9c40737b, 0xfd7aecb8, 0x2b66eae9, 0xeab9fe50, 0x19d72b03, 0x92bcdd7d,
+ 0xeab87ee3, 0x06fa4d1f, 0xa91bfefc, 0xcaf0f87d, 0xebfcf4d1, 0xe46fabc3,
+ 0x29b2a97c, 0x2011cf2a, 0x5fe4dcf8, 0x5deef57d, 0x69b67fe4, 0xb6149fec,
+ 0xee977d9d, 0x9835f769, 0x8ad1dbf9, 0x067613fd, 0x2aafc892, 0x11df4f9c,
+ 0x98d56bed, 0x32dfd0ff, 0xfb3b2bfc, 0xd88aa757, 0x7c75c2bf, 0x4e8b6e41,
+ 0xa7bad394, 0x9a688b8a, 0xd7a4e382, 0xe57f93c6, 0x0cb7f3e8, 0xf8933e78,
+ 0xe0496eec, 0xd9028bbc, 0x4460cf82, 0x1aebdc14, 0x64ff675e, 0xf51aa35d,
+ 0xdef188fd, 0x7b88065f, 0x3e0cef87, 0xe65e290b, 0x5da2bda3, 0x932fb8d7,
+ 0x1cd6b1ce, 0xaea93e62, 0x3df18b33, 0x07ba05a2, 0x411fc09a, 0x273f0807,
+ 0x65d211e8, 0x8438259e, 0xbdbdfafc, 0x2eb28af7, 0xf5ea2824, 0xf3875a6a,
+ 0x5b974c77, 0xb3c7a5f7, 0x9ee92743, 0xe3be1d07, 0x8a1e2259, 0x5badff1d,
+ 0x9f8e41e4, 0xf8f1fa13, 0x78e8ff4c, 0xc500327a, 0x48a05f22, 0xef8835fa,
+ 0x35e763ed, 0xfe787ad3, 0xc70243dd, 0xf73b8f89, 0x63fdf026, 0x75e44ba7,
+ 0x34dbea4b, 0x6d661efa, 0xec813283, 0xf79cdad2, 0xec197bf8, 0x5c9e9117,
+ 0xf7c83e1b, 0x7b7515af, 0xc0e37967, 0xec2dddb1, 0x9df93cc3, 0x7cf8ec72,
+ 0x3c067e39, 0xdb9e3219, 0x673ef74e, 0xf14ecdca, 0xeef89bdd, 0xd7a956f5,
+ 0x6662df17, 0xe80cea3f, 0x227f7166, 0x481639ee, 0xd4ab7dbd, 0x63dfb1f7,
+ 0x76fdfa1b, 0x67c2ceb9, 0x73dd3360, 0x7d9f7ec4, 0x170ff4bb, 0xefd79781,
+ 0xf4bd5df7, 0xfeff6313, 0xea5b8942, 0x8a3051f5, 0xed087af4, 0xe45bd70d,
+ 0x9eddb026, 0xae32305f, 0xa9df41df, 0x753bf2eb, 0x57fa0d6a, 0xf6c7bee7,
+ 0xb9cb78f0, 0x86fbf997, 0x1d900973, 0xcfad9ee7, 0xe47a1a1e, 0x79774136,
+ 0x14e151ef, 0xbff41a30, 0x645a1184, 0xffa0cd7e, 0xff0e9283, 0x394575c7,
+ 0x63e645a0, 0x07fea90e, 0x475419dd, 0x38fec9dd, 0x21ed809e, 0x3ca86b9e,
+ 0x846b50d7, 0x7034bb9d, 0xee3e5c79, 0x406a5f3b, 0x6e7493d8, 0xecad725b,
+ 0x14845637, 0x22b0eefe, 0x9b7fa20c, 0x51caf9c2, 0xbf5c2d0d, 0xf154a4b1,
+ 0x3c5a8578, 0x7c19f04b, 0xfc26c0b4, 0x7a5f8303, 0x88f925f1, 0xb85fc9c6,
+ 0xb10bfa55, 0xda1a34fc, 0x4bfad167, 0xea878abd, 0x47c9af36, 0x4ebdc6cb,
+ 0xf8b5eee1, 0x4cd2f908, 0x9f96317a, 0x1ffb735e, 0xb775fc25, 0x80525e5f,
+ 0xfdcf1feb, 0x4ff1286c, 0xe8e435e5, 0xddbf4945, 0xae71c08e, 0x7597a963,
+ 0x8db9f504, 0x5697841d, 0xd3b2bf60, 0x8365bed5, 0x8eb9b7f0, 0xc09c22a0,
+ 0x4d15a5f5, 0xad6efe76, 0x713aa1a2, 0x26e3e90c, 0x7ec763d5, 0x52e9c379,
+ 0x179423ca, 0x2a973a89, 0xabbba8bb, 0xbbba8bb2, 0xe7fee9b9, 0xeff813dc,
+ 0x11d74403, 0xb57e3a58, 0x3ef87be1, 0x9335df56, 0x7fe1370f, 0x4b350f4e,
+ 0xbb686cfc, 0xc4863992, 0x887fdd34, 0xfd7eeee0, 0x8a7d0b45, 0xd5e63551,
+ 0xd6825459, 0xde79d6ec, 0xb52d752d, 0xe0365694, 0x429dbbb7, 0x43839aef,
+ 0xbfcd6fd8, 0xea9b7abe, 0x258c6f83, 0xd2d5d5fb, 0xc112d636, 0x501b9def,
+ 0x63a1c76f, 0x1ca49835, 0xca2adc6b, 0x0947e922, 0x3e6aaeb9, 0x8bf9499a,
+ 0x7ce7924e, 0x1e49df6a, 0xdec56d81, 0xc923c933, 0x5a2fd99f, 0x4d4bbd63,
+ 0xad03cf2a, 0x49edd463, 0x666df091, 0xc4852ef8, 0xa31d003a, 0x8e441716,
+ 0xd6bffcd7, 0x3e851707, 0x07d288e8, 0x16429e06, 0x0388efe0, 0xa75cad87,
+ 0xae3ff740, 0x036a3a08, 0xc26efd05, 0x76e48a60, 0x0f7bdd32, 0x834f9727,
+ 0x41afa9bb, 0xfba54b58, 0xea2ab0e9, 0xbeb086fb, 0xbff7289f, 0x50b70b49,
+ 0x7964f03d, 0xda053a5f, 0xe80cde79, 0x4e0bd6e1, 0x18ba0efe, 0xb24edc3c,
+ 0x5a53e785, 0xe2143f2b, 0x99c27bef, 0x4d82eb9a, 0x871d6f7e, 0xd3787dde,
+ 0x0f8182e0, 0x44d5ee95, 0x79ec533d, 0xfc28186e, 0x42bc9bbc, 0x414b910f,
+ 0x2093c0f5, 0xd3f9f7c4, 0xebde43a1, 0x54c73fc7, 0x1ee90b8c, 0x31ba3a6f,
+ 0x208f8c89, 0xe7469fcf, 0xa79de351, 0x19933e63, 0x9f049d4a, 0x7d34ce12,
+ 0x73febf67, 0x28355374, 0xebefbde5, 0x5171fae9, 0xa7a83ddf, 0xa9f78de9,
+ 0x7af1597e, 0x43d9beb9, 0xfc538ddf, 0x7b3ad613, 0xc03659f5, 0x722b8198,
+ 0xfbe84e06, 0xc0fc046e, 0xdfb12475, 0x277c448d, 0xfe231702, 0xe751922e,
+ 0x48b83bbb, 0x65913aa7, 0x7bfe36e9, 0xa1b6853b, 0x79af29e3, 0x339fcd28,
+ 0x7dea8330, 0x62f246eb, 0xfb02705a, 0xecbf92b9, 0x78449de0, 0xf7c6bc50,
+ 0xd37cc02b, 0x320bf7fb, 0xb227bf81, 0x3e77c55b, 0x6d1f91db, 0x3a052ca9,
+ 0x23c35fd5, 0xd3f93a25, 0x0f365c5b, 0x256c477d, 0x707dedb8, 0x1d44d8d7,
+ 0xd44d8d48, 0x72f51879, 0xb1ad78b1, 0x8f4e7919, 0x98f1fd8d, 0x627e90ef,
+ 0x7842dff3, 0x98a9287a, 0xde530eff, 0x5cdcd32b, 0x7fbf250f, 0xf03049aa,
+ 0xe7e36c50, 0xec94f57d, 0x3d52d667, 0x9359c237, 0x78ff5c01, 0x0a546934,
+ 0xb4d565d5, 0x9aee7a89, 0x77eb008c, 0x7d615fb3, 0xd25ad35f, 0xb2e2f64a,
+ 0xdd75c2c3, 0x07512e35, 0xd080c81f, 0x3d347af3, 0xa0f419a6, 0x8f594bfb,
+ 0x5c65d064, 0x7bd0943a, 0x91dec2e3, 0xdb429384, 0xfdd037cb, 0x7470b8c2,
+ 0x69d2197d, 0xf7a9d135, 0xc9cd1e3b, 0x7d061ef5, 0xd9987190, 0x06ee929d,
+ 0xdfc69cbd, 0x516af023, 0xa0c08f7f, 0x4144f6e3, 0xe055332f, 0x7577e70c,
+ 0x4e96375a, 0x14e11bff, 0x4bb0bac1, 0x00004bb0
};
static const u32 xsem_int_table_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x277bff00, 0xa3f0c0cd, 0xa5fd811e, 0x79ba1818,
- 0x8968c550, 0x30327137, 0x303170b0, 0x06710268, 0x2036ded0, 0x17c40edd,
- 0x1022f880, 0x3033719b, 0x11710214, 0xf2032f10, 0x56dcd093, 0x50c0c4c1,
- 0x4035c405, 0x3ac4075c, 0xba0c0c8c, 0x1fdbc48c, 0xf0c0c42f, 0xd7c10c42,
- 0x48606710, 0xff9fa491, 0x54ee1b07, 0xc27dafa1, 0x860c0caa, 0x4662a8ba,
- 0x5d637c68, 0xa09866fc, 0xf1a29bc9, 0x17e8f0cd, 0x87e540b4, 0xe3f2a219,
- 0x7618198c, 0x3709a922, 0x7416efc4, 0xf7a802fc, 0x00031025, 0x22037beb,
- 0x00000368
+ 0x00088b1f, 0x00000000, 0x93cbff00, 0x51f86065, 0xd2f9c08f, 0xbcde0c0c,
+ 0xc4b462a8, 0x0c0c5c0c, 0x0e5c4041, 0x7b401ac4, 0xdbe9016f, 0xcdce1c40,
+ 0xc40110c0, 0x1ff881fb, 0x6207ff10, 0x04d6200d, 0x79405fe2, 0x5b1ba845,
+ 0xda181898, 0x8803b880, 0x875880bb, 0x97418191, 0x93fb7891, 0xde181984,
+ 0x7af82389, 0xcd0c0c12, 0xfff3f452, 0x5631c360, 0x29efb5f4, 0x174e3ed0,
+ 0x19c73f04, 0x505c2498, 0xe0bb70d5, 0x4d078337, 0xcf8d179e, 0x9e7f4787,
+ 0x5cbf2a21, 0x4d3f950b, 0x23e18187, 0x2d0a9a92, 0xc7416efc, 0x0c0c468a,
+ 0xabc4464a, 0xca8c60df, 0xd081300f, 0xb1adf900, 0x0003a809, 0x00000000
};
static const u32 xsem_pram_data_e1h[] = {
- 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c09, 0x73b9f8b9, 0xc999dee7,
- 0xac84992c, 0x5d86f12c, 0x48409c04, 0x5876c443, 0x0622b4a4, 0x30a20a97,
- 0x9037d96c, 0xff69f0fa, 0xa5ab0819, 0x68d06a1a, 0x68304ec1, 0x1a0741b0,
- 0x01c04830, 0x6a2be2d4, 0x6d8ad3ec, 0x2c3480c5, 0x0dc46486, 0x3ff2d3de,
- 0xcdce77df, 0x11337bdc, 0xbffbfb6c, 0x4f169fe5, 0xb7fb3dce, 0xe77cef9d,
- 0x92cc5f3b, 0x407e1240, 0xa1f865c8, 0x211318e9, 0x5d245c64, 0x88fdfd6c,
- 0xe5227d53, 0xacc8957f, 0x465a48e0, 0x46dbe42a, 0xb213be45, 0xb16feb12,
- 0x589346b9, 0xc402d348, 0x93df3f45, 0x84592268, 0xf826e7dc, 0x9bce25b3,
- 0x12126426, 0x6f7168de, 0x25dfa74d, 0xd02425c5, 0xb720fd74, 0x4a76805f,
- 0xebc3e412, 0x9a56f725, 0x165f5f27, 0xcad9bda1, 0x27e813da, 0xf87c9089,
- 0xd221107d, 0xe8f89145, 0x024ba4fc, 0x32245ba6, 0x4fce972f, 0x2646df72,
- 0x73f3223a, 0x9392e427, 0x994efbf4, 0x52efd396, 0x37d5ae42, 0x2d7e5232,
- 0xe4fe7011, 0x5fec4aeb, 0xfbb56f1d, 0xd717ab36, 0xdfb517eb, 0x5c17dcbb,
- 0xcb757df0, 0x2d0fd8ed, 0xc39675c1, 0x9e5a14fc, 0xa6265270, 0x3811ff48,
- 0x351c7005, 0x71d0b4af, 0xf08847bf, 0x84ed37ca, 0xb76abbae, 0x5c2858a4,
- 0x4296ef26, 0xd2f9a03f, 0x7900213a, 0x211b01d3, 0x9b9d6e14, 0x94e43e59,
- 0x7cff50bd, 0x2ed3cd3d, 0x8fad2dca, 0xdd7000dc, 0x38ad922d, 0xe609ae4c,
- 0xadc2aedb, 0x6cf3e599, 0x775a5b2c, 0x2fb42e70, 0x1b10b668, 0x6f74afed,
- 0x681b8cfe, 0x4488ff3e, 0xb6e94aa0, 0x9a5f7215, 0x41080c2f, 0x224d77c8,
- 0x8f7fbe38, 0xeb46d818, 0x935ab977, 0x3c70a4ee, 0xca256957, 0x676f3a30,
- 0x141dd26b, 0x9d81450e, 0x515da153, 0x1201e0a3, 0xdb7bbc9a, 0x5db4a9eb,
- 0x63c176e9, 0x6e2970a1, 0x386513b0, 0xfa65c39b, 0x0c49bdaf, 0x2f9680fd,
- 0xe924eba5, 0xa9ead780, 0x37f18444, 0x02338aca, 0xc39573a7, 0xe4896289,
- 0x71d3b74b, 0x17b2bb68, 0xb12c0f04, 0x407c44cc, 0x6d7b9d97, 0xc0719eb3,
- 0x43c856fa, 0xb5aeb09d, 0x0fcbd432, 0x5363dfcc, 0xf2757e60, 0xb45e5a54,
- 0xd3ce4eb9, 0xe1b8bfe0, 0x3558a23a, 0x941daaf3, 0x630fa5ac, 0x89928e7a,
- 0x84453e76, 0x200e8378, 0x533c8083, 0x857d17c3, 0x7177c438, 0x9feba883,
- 0x44909242, 0xe8f7dffa, 0xfe5e14af, 0xab844efd, 0x9ca5b78a, 0x5dbc548e,
- 0xcc43fce0, 0xff6d2ce1, 0xe008fa6a, 0xbaa7ce81, 0x2fe98dd2, 0xad30532b,
- 0x3f1054a9, 0x68fc038f, 0xdbcf81ba, 0x344c8135, 0x5e5d71d3, 0x8b3606e2,
- 0x289dee9f, 0x2e7c7cd1, 0xe3dd27cb, 0x596f9413, 0x2e3e9abf, 0x4f03e6f9,
- 0xbd53226e, 0x979a54e6, 0x87884b7d, 0xd5be6f8e, 0x213c653b, 0xa3df12af,
- 0xe4d17eb0, 0x12bc002b, 0xa5c94c12, 0x50235978, 0xb5e14239, 0xe1491616,
- 0xd29526b0, 0xe3d3c533, 0x233d66f7, 0x09ad7c0a, 0xf67bcf90, 0xa7ec74e1,
- 0x6991fb16, 0xdcae833f, 0x6cdcd24f, 0x73493f5d, 0xea7ed40b, 0xab989fb0,
- 0xb9f1e7eb, 0xccf9fa39, 0x79fb522d, 0xae89ea1e, 0xd2575bab, 0xf9fa09bc,
- 0x7ec12bcc, 0x10f1ef92, 0xaa2fad1f, 0xbd5a43f4, 0x34772d22, 0x98798dc6,
- 0xd268e968, 0x49cfe81e, 0x474b4ab9, 0x3a31d9b1, 0xc6f38a7e, 0xa67df2eb,
- 0x4fd5d5f5, 0x2ba81dcc, 0xc2359e4f, 0x770e9740, 0x0f3c75fb, 0x91597293,
- 0x32bee5ef, 0x7d899dca, 0xfbff38ad, 0xee503afb, 0x1be39fdc, 0x86f3a6e6,
- 0xff8a12b9, 0xf5df65fb, 0x437428ee, 0x149025d7, 0xa4131548, 0x12b5f2c6,
- 0x7ea4db83, 0x413d0f5f, 0xc29b97db, 0xfe68e343, 0x8ff13088, 0x80bfeeb0,
- 0x8b78a530, 0xd4054911, 0x9410b18b, 0xb3d36b7f, 0xe06bf19e, 0xa5006eba,
- 0xefd22117, 0x0297c93a, 0xafe6d8f4, 0xae7d03f0, 0x60532019, 0x54827212,
- 0x6983fc84, 0x297901fb, 0x4c8b7f00, 0x7c7687e5, 0x123f8e99, 0xf1876fc7,
- 0xdf197a3b, 0x375b3032, 0x40ad35be, 0xa655be37, 0x08fe53e3, 0xf1f397fb,
- 0x0872fc29, 0xc72c94f9, 0x05692df1, 0x995afe38, 0x8fc6e814, 0x4bff1ee9,
- 0x186bf718, 0xfaca313f, 0xd7e8e607, 0x5fa4569f, 0x4fd6ccbf, 0xf8f9f856,
- 0x417eb831, 0xa7f5b3f0, 0x5bf5b115, 0xe3ddbf58, 0x2fe1babb, 0x875c740b,
- 0x07facbd0, 0xffafd04d, 0xfafd129a, 0xf77c6c2d, 0x7c7c758a, 0x271f8e07,
- 0xbfeb63ac, 0x97c704a6, 0xd00f3e2d, 0xa62fdc91, 0x69fb0022, 0xc940ca7f,
- 0x98bd0328, 0x84278f0e, 0x93df93ca, 0xfb870881, 0x7ddd1863, 0xcde94319,
- 0x24a79111, 0xee903940, 0xa69c65c3, 0xca271b8b, 0xe3f67f6c, 0x4f98bebe,
- 0x88b35175, 0x2c6a4d74, 0xbe742181, 0x1fa2cd9d, 0x6e6a8bf2, 0x9fb8880c,
- 0x98823d32, 0xffbe0849, 0xada8d375, 0xd31975da, 0x7b52d5c5, 0xbaaf869b,
- 0x3224fbe5, 0xafce82bc, 0x5c608802, 0xe54edf24, 0xf872a134, 0x90c79524,
- 0x5e98969e, 0x71ca8a72, 0x37cb4c32, 0xe25e982b, 0xa70eef27, 0x9f09fff3,
- 0xc199bb7f, 0x10997dbb, 0xb97ff800, 0xf20c8971, 0x9db5716c, 0x8f323d02,
- 0xf0a78e72, 0xf5004b5e, 0x001dba29, 0x5642ee7c, 0x03c3e424, 0x502ebcb7,
- 0xb6bf2d3d, 0x3dddae8f, 0x853ab024, 0x61b85fd6, 0x5d3700fe, 0x96599cff,
- 0x4fec2231, 0x84cfdbc4, 0x99fa4c7c, 0xd59909b2, 0x47ea51b4, 0x92cd7733,
- 0xda69b64e, 0xf3e9f6cf, 0xf9f40a73, 0x9920294e, 0x14299f40, 0xf7ed1d48,
- 0xb97d0ade, 0x2134ce3a, 0x8f95e19e, 0x830a13f7, 0x5ee9fa54, 0x67c0c748,
- 0xae75e237, 0xe755b59b, 0x44a0fe53, 0xb71fb842, 0x7fc41225, 0xb9f3d622,
- 0xf38dbad9, 0xbd592b9d, 0x733e74b9, 0x9e11101f, 0x1db7f9c6, 0xa34d7bb0,
- 0x99fb5a69, 0x5c682404, 0xf3fe718f, 0xe3d71b96, 0x987f6196, 0x677e37ef,
- 0xa7a46274, 0x8f89e6f2, 0x53d0d29d, 0x8f47f069, 0x2bb4d29d, 0xcba9986e,
- 0xeb660617, 0xced7e7ea, 0xae2f95d7, 0x2f95d42e, 0x9744b75c, 0x407fef9f,
- 0xf2de7f57, 0x7bf2ba15, 0xcaebd62b, 0xd46c14e7, 0x9efb67e5, 0x6bbfd5d4,
- 0x5cae9d56, 0x4d785038, 0xdf55ca1b, 0xb7a0a935, 0x4021607e, 0xabbd2a8f,
- 0xea8670fc, 0xa39e902d, 0x2ba40b7a, 0xff294f80, 0xb4b2f69b, 0x6bfceb7c,
- 0xfebd1adc, 0x069154b4, 0x7ba464fc, 0xf48d3c23, 0x45fa7f4d, 0xb4d487db,
- 0x20b92044, 0x7ef8bae7, 0x5ebf7eae, 0x647a7130, 0x7e129de7, 0x95d9289e,
- 0x3bce093a, 0x68687225, 0x7ef7a385, 0x75c05049, 0x13d2d010, 0x5a946f01,
- 0x6e2b7035, 0x679ba418, 0xc71141c7, 0xa5de032f, 0xe4832ff2, 0x0f200b36,
- 0x6ed38742, 0xf1f3051f, 0x4cf905ee, 0xff71139a, 0xf69ca8ed, 0xe00929d8,
- 0x99e98b97, 0xb69859ca, 0x3d30fa57, 0xe9805955, 0x4c0acac9, 0x63972adb,
- 0x8fd2bc7a, 0xd72a5fe9, 0xcaa7fa61, 0x558f4c6a, 0xc7fa62d6, 0x9da600ca,
- 0x554c5e95, 0x9396edba, 0xe56f5cb9, 0x81fa0be7, 0x2d7cade9, 0x15bdfd22,
- 0x0293d1f9, 0xf1c178fc, 0xcbd050e5, 0x48a31c2f, 0x5e1def4e, 0x15e87a46,
- 0x7a8bc4ae, 0xe2805e45, 0x72cf4fb9, 0x93c30c5b, 0x11a644cd, 0x0fd6372a,
- 0x60b3d679, 0x24cde624, 0x3c07da1e, 0xfa519d33, 0xe0147ba5, 0x22784aeb,
- 0x3868f0de, 0xf53fb70f, 0xefd0599f, 0xb640c2f5, 0x71161e5f, 0x67a124bf,
- 0xefaf803c, 0x95e1370a, 0x6f80d30f, 0xf0aa27ce, 0x34234d6b, 0xb1b8225d,
- 0x164d0bff, 0xb6380662, 0x847003d8, 0x19e470bd, 0x4b77ec17, 0x53eac453,
- 0x57877b63, 0xdabd3069, 0x794f59a1, 0xa17f3eb3, 0xcec6985a, 0x1dec4af9,
- 0xdcae80a3, 0x0086a7d5, 0x553053fe, 0x229a59fb, 0xb9ea38e3, 0x21c63496,
- 0x2173d29d, 0xcf67fbd6, 0x227eb7a3, 0x1f2268f3, 0xbb01d853, 0xe5741e5c,
- 0x7c0f4bf3, 0x73973f9b, 0xd22d4f01, 0xc79fb097, 0x07977fd0, 0xcc66bf42,
- 0x0796fdab, 0x7ae5bf45, 0x1ba8def8, 0xd453b68f, 0xebb43733, 0xa4cd5e9d,
- 0x15275d5d, 0xdedc196d, 0xab60dc52, 0x38fdcbd6, 0x39bcbe5d, 0x0fb75ab5,
- 0xef942fc0, 0x06608149, 0x54e129ba, 0xac7665d4, 0x1cfce813, 0x2dfb0526,
- 0x52bd5817, 0x53ec9b6b, 0x415b0c90, 0xad90580f, 0xd7729dd2, 0x3e5ca99f,
- 0x3c897bfb, 0xeedce50c, 0x2547f6a2, 0xfcd13130, 0xd05b9e42, 0xe41d3c54,
- 0x373dd9dd, 0x88b0fea3, 0x10e0bae4, 0xb3aa4053, 0x4f390f40, 0xee80d34c,
- 0xb83f93cf, 0x03ce6ac6, 0xce324c73, 0xfd3ae167, 0x27f5483e, 0x56bf3e5d,
- 0xb723cf9f, 0xe79d0125, 0x202448d5, 0xcbea3f00, 0x7e31366f, 0x6b1527c8,
- 0xc5587f60, 0xdc0b13cf, 0xf28fdcc4, 0x5b4be97b, 0x79d3e6b2, 0xf931302c,
- 0x0bdf9ead, 0x511e99e3, 0xc193ac14, 0xd371f39e, 0x40dc9fd8, 0x0d607da0,
- 0xbbfc31d8, 0xa536cf05, 0xebbefe27, 0x55f38dfc, 0x761e8ff7, 0xd28f3e04,
- 0x881bc106, 0x98548fb2, 0xf8ffbe04, 0xeb097e99, 0x1b99e8d6, 0x435af90c,
- 0xff90debe, 0x812de9bb, 0x61cde8e8, 0x25306df2, 0xfd02fa32, 0x6587304a,
- 0x7fd23fdf, 0x6bfe8f4a, 0xf7fda9ff, 0xe967fda7, 0xa7ffaffa, 0xc7b83ff6,
- 0xfad183fc, 0xc7697d2f, 0x37953f1e, 0x726e2f45, 0x9cffba11, 0x79275735,
- 0xb64bfe28, 0xe2fb46ad, 0x05dfb319, 0x20367cf4, 0x39440b4e, 0x71369f57,
- 0x3af125bb, 0xc0f73804, 0x73ffb4af, 0x067cffcf, 0xdcbe5b9c, 0x3cf1b926,
- 0x590960d3, 0x35969f28, 0xa3274e15, 0xe5827f31, 0x422a7ed7, 0x9f4f59be,
- 0x4a6dcf45, 0xa51bfb02, 0x87efae14, 0xab2a5f50, 0xd854ebff, 0x1849ca7f,
- 0x0ed8ccf9, 0x8f18bfc6, 0x1cbe71f2, 0xce9cb3db, 0x72f0f513, 0xa6f2970e,
- 0xba2a7f9f, 0x69d1fd20, 0x369317b4, 0xed8d93d4, 0x73feb80a, 0x684ce4cc,
- 0xf91eaaa7, 0xc81ef91e, 0x242e154d, 0xf11ff4c0, 0xe1a32da5, 0xff51dafc,
- 0x81a0977b, 0x176fca97, 0xfd7f0b82, 0x5cbbd2b2, 0xb1e7e4ee, 0xb600bb48,
- 0xdeb99a53, 0x12d2c2d6, 0x7b02e429, 0xe49d4969, 0x25cfd3f1, 0xf6799e3b,
- 0x7e4f3829, 0xa10cf160, 0x78ef17fd, 0x34398fed, 0x4a53bc5f, 0x4049ce98,
- 0xa7e08a48, 0x3e5bfe9c, 0xa28f8226, 0x2b26bedf, 0x87f7d8a3, 0x297823e2,
- 0x265079de, 0x63c27aa3, 0xdca0f072, 0x9f8288e6, 0xa0a989e0, 0x7d2f895f,
- 0xcffe0323, 0x7248101e, 0xd678147a, 0x027a86bd, 0xc9f109c0, 0x3f8dd5f1,
- 0x8a72fd43, 0x46eb9017, 0xedeb197c, 0xfa05f2e5, 0xa521fb05, 0x065e17ef,
- 0x2c9ff33b, 0xc143801e, 0x60b9f70b, 0x15cda73d, 0xacb7ce8c, 0xf1d2f24e,
- 0x927f240b, 0xbdf6531b, 0x229fe9e0, 0xf3bfe5fd, 0x7e7624d3, 0x709aa6f3,
- 0xc2a7f2af, 0xbe6f173a, 0x4799d713, 0x0587487c, 0x905cc45b, 0xc9985f97,
- 0xf8519db4, 0xe4c89e64, 0x14ade9e6, 0xa79d74b9, 0x768436e9, 0x81883fd7,
- 0x58bf686d, 0xfc1e4042, 0x9397b554, 0xc2ff98a5, 0x4e35f0ca, 0xaa7ef554,
- 0xb7e969f5, 0xe02b6d7e, 0x6f00dce9, 0xcabdd832, 0xe1cfd989, 0xfda65c21,
- 0x94dcef8a, 0x1444f0cc, 0x476f1673, 0xf0c982f5, 0x4ab7ea1d, 0x5d68db5e,
- 0x3d39723b, 0x3e32fe32, 0x0c779d3e, 0x93a7e7ec, 0xca304148, 0xaa8836fa,
- 0xbafba01c, 0xfc34ce86, 0x7ebff8ce, 0x9577e33d, 0xa73303ff, 0xefe7f941,
- 0x76823e32, 0x79d25fb0, 0xfcb19285, 0xca021de0, 0x45090b07, 0x897af3e3,
- 0xdcbeb9f3, 0xfe742f48, 0x43562166, 0x3c4e3037, 0x5eed01e2, 0xbdb43579,
- 0xb8c2ae56, 0xaafd9eae, 0xe5cf9c7c, 0x9522ddc1, 0xe445d707, 0xe4ccd901,
- 0x977aef40, 0x2258f11f, 0x0a7d9e05, 0xabf297f8, 0x95fe015f, 0x9ffd6172,
- 0xe3fe1e34, 0x3e6f94dd, 0xab7caa09, 0xbe46ab97, 0x2e35d82d, 0xb27edf2a,
- 0xdf3a2321, 0xf951efd2, 0xdbe30376, 0x5572d7ff, 0xa8956385, 0x9caaab97,
- 0x469e0dec, 0x2a269939, 0x9ca35708, 0x92ef3fa4, 0xa8f49eac, 0x7f4aa1d2,
- 0xbd29bf45, 0x3751e406, 0xd874aa9d, 0x1d2aa74d, 0xe89fb0f6, 0xbf2c68e0,
- 0xd2826819, 0xf7deee4b, 0x78a3f6a6, 0xf761692d, 0xebddb450, 0xf2f0a790,
- 0xaa4736e2, 0xa097ef5f, 0xf90c07cd, 0xd7bea1a0, 0xd435cf90, 0x15f219f7,
- 0x6601fa86, 0x2c3e683f, 0x9087a413, 0x92b4beae, 0xb7609df8, 0xdda22fdb,
- 0x79ce8bae, 0xd5df6d0d, 0x53f01e98, 0xc6dab0f9, 0x44e18fce, 0xb3c80d79,
- 0x15d8772e, 0xd31b790f, 0xc372bb7b, 0xfe8d38ae, 0x4445a278, 0x2016dc79,
- 0x8cf6b4d3, 0x21545f08, 0x6f48dafe, 0xd90ecce5, 0x77eec315, 0x691d126f,
- 0x59dce1cb, 0x19287a2d, 0xee2b4590, 0xba898172, 0xadd065ab, 0xc5f7e8b3,
- 0x5aec886f, 0xa735efc4, 0x670dce6a, 0x09f1ff88, 0x6d97dc02, 0x6c2ffc40,
- 0x4588e761, 0x73d3a21b, 0xe7976f11, 0xdc832658, 0x49fffaa4, 0xed559dad,
- 0xe1b360a7, 0x9ccdcb7b, 0x3cf1abee, 0x2faf5457, 0xd0f3f1f7, 0x647e5549,
- 0x1f940c90, 0xf381d070, 0x37bb9738, 0x9d6f2389, 0x75d0f145, 0x37402444,
- 0xc4445a17, 0x764685c3, 0x89fc495f, 0x24653fc8, 0x854ef28c, 0xc7f00757,
- 0x50e5deb0, 0xb30feec7, 0x4a55a41e, 0xf479fcf6, 0xb1da68af, 0xfba183e7,
- 0xfbd2ff20, 0x3d267f69, 0x603e4feb, 0xd76e3b43, 0xbbde2701, 0x337fed74,
- 0xefc841ed, 0xbef078b5, 0xa357c0f9, 0x56ba8e81, 0x8e400a5a, 0xf7600d75,
- 0xbffb55f4, 0xfb86dd1a, 0x9fc42ae7, 0x5fceccd3, 0xf3fe5a17, 0x5fb3dc38,
- 0x02aba168, 0x1d80e0fd, 0x2fe5e1ed, 0xd08ed0db, 0x2cabffb5, 0xb79fe39f,
- 0xbf7e329e, 0xb324e5d2, 0xe2fcc176, 0x7cba5d98, 0x5667f8df, 0xd373fdc0,
- 0x2d217941, 0x37cafc9f, 0x763e41a3, 0x4f7a62ed, 0x34f6d4a7, 0xaca41fdc,
- 0xa242b4ba, 0xe604ee70, 0xf94f4be8, 0xf92672ab, 0xcb834647, 0xb91f6837,
- 0xff5c785a, 0x021e063f, 0xb49623de, 0x01560338, 0xf8e97dd6, 0x1c1e419f,
- 0xaa5d20b0, 0xb824fdeb, 0x2b91f502, 0xac067bad, 0xd37ff13b, 0xd5d085ba,
- 0xbff4bbac, 0xe33fbe39, 0x0f91a8fb, 0xfef9d27a, 0xc3bf31fb, 0x5ef9c1e9,
- 0xe2ffbd25, 0x77de1b7f, 0xaebbbc51, 0xffc6eebc, 0x1deeebe6, 0xe5cc6fef,
- 0xfdc37778, 0xdf2bf97b, 0xabbefce0, 0x3ffa3b9c, 0xbeaafd74, 0xf2933bfe,
- 0x3fad066e, 0x403b548d, 0xe951f8b1, 0x683237a1, 0x1ffaefe9, 0x4ef9838e,
- 0xc635f7e2, 0x66637df9, 0x7049bee7, 0x25c7436f, 0xef3f0271, 0x3f5273b1,
- 0x5bf45fae, 0x487a8796, 0x40bffebf, 0x9598827d, 0xfc0fb81a, 0x0f42da5d,
- 0x319036fa, 0x77907cc7, 0xfaf3c8df, 0x04afe2f3, 0xcaab85e2, 0x1f37697e,
- 0x7fb53d01, 0x58f5117f, 0xfafea29a, 0xfb1a6baa, 0xceeb225e, 0xf4523f33,
- 0x09a99be7, 0x14d073fa, 0x844ddfde, 0x8726ffcd, 0x38500810, 0x58f01a4c,
- 0x2743d802, 0x4088910d, 0x6f8953f3, 0xa61b9c15, 0x7dfdf438, 0xe3c4f700,
- 0xb7cc7022, 0x7f022dee, 0xc047ab3e, 0x987586fe, 0x33589e50, 0xe183a405,
- 0xbfcc66b5, 0x038f7263, 0xe1b8cf38, 0x201e4fa5, 0xcaf55760, 0x65cba14c,
- 0x2faff1f6, 0x05909e5f, 0x03f66fe7, 0x50b778fe, 0x66d17d7d, 0xeba18a12,
- 0xfe266c5d, 0x8bb078d8, 0xcea4e40a, 0xc3cfaa2e, 0x2293f7cf, 0x7ea95cfd,
- 0xcff8746f, 0x74a25f4e, 0x2108727f, 0xfbc5217b, 0x53cf662e, 0x6bdf57cf,
- 0x3f2af061, 0xd903024a, 0xab98b8bd, 0x2c5a3fb9, 0xe97bba31, 0xc2c6bb2f,
- 0xd76266b9, 0x8fc658c8, 0x904fcc99, 0x881797eb, 0x0071eb12, 0xc58a0e3f,
- 0xa223b17b, 0xd9df9a33, 0xfade7e76, 0xd297dc0d, 0x549eabb4, 0x93f7a08b,
- 0xfcf9da30, 0x2db256f5, 0xae427f8a, 0x382ddaa4, 0x988fe8de, 0x367af605,
- 0x34da62fe, 0x8eb78b56, 0xa3cd67e9, 0x7e01e27b, 0x2bee6a4e, 0xc2f851fe,
- 0xbbe00ef9, 0x3536d6dd, 0x2edf0a37, 0x633d9890, 0x784ba1c6, 0x52d11ebe,
- 0x1f3e0267, 0xddd26f51, 0x712dddbb, 0x190c7dfd, 0x719af303, 0x04cce6c8,
- 0x3d111cbc, 0xde57efe0, 0x8beca9f2, 0x84646f72, 0xf60ff427, 0x8dc95ad6,
- 0x8293eee3, 0xfbae010b, 0x9c095bce, 0xd5caf6b7, 0xe9e6d1c5, 0x2e79b0b0,
- 0x46fbc126, 0x83f7ffa7, 0x472ec4ef, 0x579c1268, 0x75f209ea, 0x4823fa4f,
- 0x481a17c7, 0x9c31e400, 0x5c2e406f, 0x1fb82468, 0x02fc9050, 0xdf946bce,
- 0xc73da07f, 0xf9de6b0f, 0xca47d81b, 0x9837045a, 0x6dcccba0, 0xcaedd832,
- 0x9044e39b, 0xea8a19db, 0x751ee90f, 0x6a2f8687, 0xebc23325, 0x39bece70,
- 0x1d67ee30, 0xcd7d8132, 0x05d86afb, 0x96b3ff72, 0xbd07c8b1, 0x95b7ebad,
- 0x048a68a4, 0x6ba410fd, 0x6c8c3d23, 0x6fe5d18c, 0x817d7d10, 0xda5866bf,
- 0xe0a27996, 0x7c66472f, 0x2df2d57a, 0x7c99fff0, 0x6f95577b, 0xc357313e,
- 0xd1992647, 0x25be46bd, 0x4b6f9347, 0xe0192505, 0xa0ff74be, 0xd2ebc064,
- 0x68c4a437, 0x25476df2, 0x917b07bb, 0x3576b1fb, 0xbd76f951, 0x5135be46,
- 0x4fc516f9, 0xf13243a0, 0xf20aedfd, 0xc35ff02d, 0xbe403b7f, 0xbe67a345,
- 0x6df2a83f, 0x9409cb74, 0x4c9ba36f, 0x2fccff3a, 0x84df28af, 0x9f403bc4,
- 0xec79223a, 0x0767e851, 0xe45edfd7, 0x0e30367e, 0xb271b9c8, 0x5abfc71b,
- 0xb5729739, 0x08bfee72, 0x5b9caace, 0x9fa09bba, 0x643a4f6a, 0x5ee96e72,
- 0xa004e72a, 0x96e72647, 0x8ecc27ee, 0xc36f9063, 0x8237c87b, 0xac42cbf5,
- 0xfa73797d, 0xfed0f713, 0x8f2578c6, 0x131fd695, 0xb4e37791, 0x6c9c6ef2,
- 0x90f73846, 0x4eae4777, 0xf2e6edde, 0x81b1ca8e, 0xf48d5f20, 0xfbd169e1,
- 0x7f1beeff, 0xc0b7f1ba, 0x788a6f2f, 0x898ef50f, 0x35bc17dd, 0xd02674fe,
- 0xc99906d7, 0x7b971f5f, 0xec7e959d, 0x6cabf27f, 0xec8da57d, 0x1359413d,
- 0xeacb0fd3, 0x7f4280c5, 0x09739a9d, 0xf70a93ef, 0xe699240b, 0x1faa5a67,
- 0xfd3e8077, 0x3eb8449c, 0x43433d3d, 0x8bb28b0f, 0x655bced1, 0x94256d73,
- 0x8999178f, 0xc5b9ec15, 0x4167a98e, 0x66ce2d9f, 0xfe62dff6, 0x544bf55d,
- 0xf78d33fd, 0x4bcd79e9, 0x7a47ef5e, 0xb0cfabde, 0x78cebc30, 0x1f800846,
- 0xf67bcf61, 0xe285ca00, 0x15f7fd06, 0xc533fd7c, 0x79178436, 0x8b6cf45b,
- 0x8c2b3fc2, 0xe1c23a70, 0x83a2e144, 0x0a884053, 0xe9e98a27, 0xb8114919,
- 0xb6d9be14, 0x85c0ec06, 0x6f780a4f, 0x0ab75c68, 0x55fae337, 0xd176aa38,
- 0x7e5fde62, 0x33be1d4b, 0x8545c231, 0xdd1e11b3, 0xa3c03770, 0xfff6e64a,
- 0xfc16320c, 0xa0dd2858, 0x9bfff19c, 0xb90ffe88, 0xdee88713, 0xf2e7ac43,
- 0xc4f56c7f, 0x3ddd70c9, 0xe182fc13, 0xc976ae3e, 0x37dfe0eb, 0x063298ee,
- 0x721bd3b6, 0x97b83e2c, 0xa30b6edb, 0xf0e9541c, 0xcd874e23, 0xfafbbe1c,
- 0x73c24c56, 0x06e0b361, 0x643ca43d, 0x5396b843, 0x2ad1b47a, 0x72fc9f87,
- 0x1bab872a, 0xf334bbdf, 0xc1e289fd, 0x751fe704, 0xf7b00abf, 0x185b6331,
- 0x181bca5e, 0x1849325e, 0xb565efed, 0xd7442782, 0x04bcd653, 0xf95582fd,
- 0x5a1c7f4c, 0x5fa1453c, 0x25fa3473, 0x8acc9c60, 0xbcc59bec, 0xf54b0cde,
- 0x3f9ec11f, 0x1d47f283, 0xdffd2192, 0x95f7d0b7, 0xf88c45fc, 0x6dc390fa,
- 0x01d5c007, 0xfd330bf0, 0xdf09742b, 0xe5e5a8cd, 0xae0ebf66, 0xc8ba9f93,
- 0xa0bf6fe8, 0x1ba51d80, 0xb4cf406e, 0x370a9c7c, 0x43c067a0, 0xf2117ccb,
- 0x7dde1479, 0x17ae7bd2, 0x7cb4c7ee, 0x04ffb85f, 0xe08b7feb, 0xfdd65121,
- 0x3bfbe99d, 0xfc6f75d2, 0xbe8191fe, 0x8f85b2df, 0xdefa058e, 0x93df202f,
- 0x3dfd3896, 0x4dcecc97, 0x0f946ddb, 0x0de61ee0, 0xe955b3c9, 0x1cc21f29,
- 0x509e70ce, 0x6b927634, 0x57e02161, 0xff4560d8, 0x40c79c30, 0xe56aafa6,
- 0x491b0ef5, 0xf7b323bc, 0xf9c6fffe, 0x497d37ac, 0xf1828fcd, 0xd3368e40,
- 0xc64786f1, 0xaa17ee33, 0xeb4ae01d, 0xb1fe5bb2, 0x7ce3a975, 0x7299ff57,
- 0x28f78ad2, 0xc38d1faa, 0xe0942be4, 0x304d3afc, 0xc2d1fdeb, 0x70ffcf1c,
- 0x2dfcb2ff, 0xab1493fd, 0x4de2fdee, 0x29f883a2, 0x4af33edc, 0xcb542fc8,
- 0xec026f78, 0x3ee8931f, 0x8ecf9348, 0x1eff7b8e, 0x5ef1172c, 0xfb37d6e6,
- 0xd5bdc294, 0x8a67ccad, 0xa0219adc, 0x740ef0fe, 0x70f41e36, 0xf85af12b,
- 0xfb3cb490, 0x7801717b, 0x5f519067, 0x7ca1593d, 0x5021a63d, 0x7267a905,
- 0xc02de138, 0x009144d7, 0x7dbd5abe, 0x7bfec326, 0x06495fdf, 0x9ea8ce98,
- 0x398cfd80, 0x5ea11242, 0x8f11378e, 0x3e9be333, 0x3a76f77f, 0x4547f1bf,
- 0xcdeb428f, 0x0070ec3c, 0x6cdf0d9f, 0x5c0d3e22, 0x0aa04872, 0x4fe347ec,
- 0x79076f79, 0x1ef54050, 0x682ff7f0, 0x4172aba9, 0xed80b37e, 0xa9befdcb,
- 0x1dbf3a2e, 0xbd4e9fb5, 0xad02e40e, 0x6f94dd07, 0xebcaf566, 0xb2b80f05,
- 0x946cb5e6, 0x0bd46e51, 0x476ca0f8, 0xd6562040, 0xfb4ac06f, 0xb699b1dd,
- 0x8bfd84cf, 0xeb7e87b6, 0x76f77d3f, 0x9e743b90, 0xdd91bed8, 0x76d1e6cf,
- 0xfd49f00a, 0x70afec12, 0x5de040b3, 0xdb234142, 0x4a8e0a9f, 0x3a6f281e,
- 0xbbee24f8, 0xa978e9d3, 0x851fb0e9, 0x8efbe0a6, 0xdf1b82b1, 0x43494dd5,
- 0x0b05d5b9, 0x01d60686, 0xe05cbeec, 0x51fe7e79, 0x2d37bff5, 0xcf377fcc,
- 0x43ee42b3, 0x3b2b79fb, 0xf484dd31, 0xfa0ca9f4, 0x6f0a29da, 0x3bf7851f,
- 0x70e17fdc, 0x9b72c7f6, 0x673c7f66, 0xbff48419, 0xfa2279a8, 0xb9262d4b,
- 0x633faf78, 0xdf3bd33c, 0x0016d1be, 0x52dbddbb, 0x3f7c3fb8, 0xbf05a37c,
- 0x7260ee77, 0x1b4073b8, 0x6f4f69da, 0x47bc0896, 0xa22cdaa8, 0x28dd389c,
- 0xb8b5fde1, 0x9db94245, 0x21e983bf, 0x7eb33787, 0xfd30374f, 0x3b96f26d,
- 0x9c3ec2a7, 0xefbd4dbf, 0x3d5a7266, 0x0bb9e687, 0x519bfb75, 0xb872aace,
- 0xa0a3c394, 0x5fef0eba, 0x54b7728d, 0xf20d0fdd, 0x65ee14b6, 0x8435fef1,
- 0x341a547c, 0x983913fa, 0x0d73863c, 0x12e843d0, 0x51d977d2, 0x46b9c089,
- 0x2a63b8f8, 0xec2ce7ac, 0x7c7cb4f7, 0xfb85e08b, 0x966382f0, 0x81e3ea00,
- 0x15fef3f9, 0x2c0f99f6, 0xbfc05044, 0xca83e29d, 0xf84b6ca9, 0xefd18f2f,
- 0x82b1df67, 0x9fa508a7, 0xd57f08f9, 0x1b73342f, 0x7cc8f3f3, 0xde0926a7,
- 0x7d29927f, 0xd7e40e50, 0x91a7c48a, 0xef05671b, 0xfdb377ed, 0xfff5adc1,
- 0xf3ab94cc, 0x6fed9f60, 0xd951f265, 0xddfbe126, 0x447cfcc3, 0xb7e80bcf,
- 0x6377b859, 0x87a1ac92, 0x931bfdc2, 0x6b20e8a8, 0x15447fb8, 0x285bf77f,
- 0x0f0a71b3, 0xcd3aee08, 0x6a3f6a38, 0xd65ef2bf, 0x967ed06e, 0x217fd6f6,
- 0xf9d70fcc, 0xc3720c85, 0xf18f4fd8, 0xfb27e97b, 0xc0d62fdf, 0xb7eced3b,
- 0xce6e7445, 0x20fa78fe, 0x9a80bded, 0x590c7eaa, 0x57889aef, 0xbfecbf03,
- 0x06af10c4, 0x28e34ddf, 0xddfc53ff, 0xb9f4ccd2, 0xe42771a6, 0xbbcc4cd2,
- 0xb8cbdf81, 0x0a6cba3d, 0xca69efbb, 0xf0156778, 0x014cf4ff, 0x7df881e9,
- 0xd4049f72, 0x4ff014df, 0xed64cfce, 0xe07b69f3, 0x1927a6cb, 0xa179529f,
- 0xdb293c80, 0xd62a71bc, 0xe81417af, 0x3e6ea9bf, 0xd90525ea, 0xfaf2c122,
- 0x1527a813, 0x00489f34, 0x5bfca67e, 0xd940fa03, 0xc41b8b04, 0x2a97cab1,
- 0xfdcdbf9f, 0x3dd58989, 0xcbf8fc0a, 0xf0a2a980, 0x709478b7, 0x65f195bd,
- 0xdbe33679, 0xb04877b7, 0x73e1abc2, 0x8f956be4, 0xcce3e045, 0xde1f1f08,
- 0xbe06593c, 0xd0101d3e, 0xc83262ef, 0xedf3e001, 0x31efb702, 0xf96af63d,
- 0x667a4afc, 0xd85fe529, 0x573e552f, 0xcfc8daf9, 0x3bb6e6ad, 0xddf71e60,
- 0x4c75c368, 0x3fdefefe, 0x15e4c7de, 0xfe4dd7de, 0x204903fe, 0xccccf31f,
- 0x6b8547af, 0x81f999a9, 0xcd5798f5, 0x6af5390a, 0xc79867e6, 0x5ede8b46,
- 0xc712d872, 0x25eb9dfc, 0xf12bfba4, 0xbb3e0f67, 0x5abcfe4a, 0x7f12babe,
- 0xfb8be3aa, 0x061cfdf5, 0xd9eb8e20, 0x6385275f, 0x77f1c288, 0x5fa0cf8d,
- 0x4fe7f9d9, 0x143c00cc, 0x0e74a3ef, 0x24e8d5f4, 0xe6739021, 0x455bee00,
- 0xfd17a24d, 0xaca1cd65, 0x3e5a9ddb, 0xc53ffe66, 0x9e913a2f, 0x0259768a,
- 0xa2fb69d3, 0x468f1f3d, 0x61958c3f, 0x3ff24ff4, 0x7f65f5cf, 0x83e068db,
- 0x43f33322, 0x9985ca32, 0x773fa656, 0x82cfb5ec, 0x2c0d09f5, 0xf05140de,
- 0xb9a2c92e, 0x956698a7, 0x2f787ad4, 0x0c74a7e8, 0x7e6131ef, 0xaaee77da,
- 0x76c751ff, 0x9a8a2726, 0x2dc400a5, 0xd9d86a28, 0x45a5fe09, 0xff682cc7,
- 0x14f86f2a, 0xbf27e7fd, 0x2bed03b8, 0xeea2cde5, 0x3f87ad3e, 0xb218835f,
- 0x535a1f80, 0xd1ffde29, 0x07cc09fc, 0x77dcffb9, 0x7e2b37f4, 0x3f1eff71,
- 0x6ff16105, 0x7c81739f, 0xcdbad739, 0x0d7d7e85, 0xdb5feedf, 0xb82f7fc3,
- 0xddeffb9e, 0xb9e09a72, 0xdeffba26, 0x3285f839, 0xbd5683ca, 0xe8691eff,
- 0x9d25fa83, 0x946e5667, 0xfd6e8ffb, 0x4f17c77c, 0xc779ff83, 0x869e4fae,
- 0xedfc9779, 0xafc1a7b3, 0xe1b01c88, 0xfcfe57be, 0xabafe87b, 0x6564dbb6,
- 0xfdb9da74, 0xee77f439, 0x81e2c0fc, 0x9ff73ade, 0xb2ff034e, 0x92979dce,
- 0x6cb99ec0, 0xef684dff, 0x727bb65d, 0x6fb28932, 0x6fd029a8, 0xadfc2ae0,
- 0xdc3b788d, 0x9ffd1874, 0x83bc53ce, 0xcbf6ec1c, 0x7f32960c, 0x63fb8557,
- 0x6ff74636, 0xd97fe1ef, 0x37adfb74, 0x626ffc82, 0xfd15e4fa, 0xf8a5df30,
- 0xf02afebc, 0x6dfdc8d8, 0xab7cb783, 0xf879e61f, 0xc9abe285, 0x9a2fc780,
- 0x29faff16, 0xd3ea6b28, 0xe8661fab, 0xfaa7e02a, 0xdeadfbcf, 0x6fc0ac57,
- 0xfe837ebb, 0xe9bf80af, 0x5f47ec0a, 0x83fbc1a4, 0x2e785233, 0xfde13fec,
- 0x52bf8c16, 0xe47dffb4, 0xefddcea7, 0x709a9da0, 0xd24ef63f, 0x8dfcc3fd,
- 0x7adebe05, 0xe4dff327, 0x4eff0078, 0xb9df85c5, 0x6ba3271f, 0x37b3bfd5,
- 0xacafcebf, 0xfd56ff4c, 0xffeb4bfa, 0x2324fdcc, 0x01b21378, 0xf5be275f,
- 0x070a823d, 0x11cb9737, 0x7ee8e5bf, 0xcb7eddb4, 0x3e01bc06, 0xf6ea9f61,
- 0xfef9a64b, 0xf24ed063, 0xf83f347e, 0xefe63ace, 0xdfe929dc, 0xc4f0468f,
- 0x0d5823df, 0xab81cbfe, 0xd2be5ff3, 0x9c2bbe3a, 0x3452824e, 0x3abc27ae,
- 0xdf2e8ebe, 0x3fc26d13, 0x916d5ef6, 0x931f7c60, 0x7f044b60, 0xcf681390,
- 0xf37f3eec, 0xfb7076f5, 0x22f3c77b, 0x09aebffa, 0x6ef9461e, 0x10651f94,
- 0x7cca2347, 0xbe98d987, 0xf6ccd65e, 0xce5d8e8f, 0xd3f68380, 0xd22f6871,
- 0x09e35975, 0x7bfb4fd9, 0x32b7e1bd, 0x7c62c7bb, 0x4047fb04, 0x178e9eb3,
- 0x7e668e0e, 0x6fdeccda, 0x1f1c671c, 0xfa25bca7, 0x9f8de538, 0xf629c6ea,
- 0xe3b76507, 0x339de3ca, 0xfe82ef7b, 0x3d32b5ce, 0x9c505cf1, 0x587ded16,
- 0xf7e24d8a, 0xa52cd561, 0x25c628fb, 0x2438b271, 0xf5062ba2, 0xecce65ce,
- 0x9009b163, 0x5407e8ca, 0x0dfb82b5, 0x0293ccfd, 0xfe72aef8, 0x577cc098,
- 0xf6357c03, 0x23edc91f, 0x294aafa0, 0x776099b9, 0x391dca30, 0x1a0244c1,
- 0x4e732f7c, 0x5ef0564b, 0xf01fd424, 0xb4e33c79, 0x647efd04, 0x647d5fb0,
- 0xe9926b26, 0x0bf23efc, 0x5fb4159e, 0x03c7f5f2, 0xfb3d9d72, 0x87bef357,
- 0xa9bd9d44, 0x0e3e12cc, 0x8af215e7, 0xc423ef0d, 0xe78c3603, 0x0db4fe50,
- 0xf7787bd7, 0xdea2cf57, 0x610b6bfd, 0x54f443f7, 0xdca47103, 0xbbd38fac,
- 0x3ffa7abf, 0xc686af41, 0xa7fcfc74, 0x4f387d69, 0xfcf1da34, 0x762bb5d3,
- 0xafcfea34, 0xe403383c, 0xd19dbe5a, 0xc98bfe63, 0x5fda2a81, 0xb7cb227b,
- 0xf18018ef, 0x39778a03, 0xf0f11fd1, 0x60ca97ee, 0xd17cea9f, 0xa4066e0e,
- 0xffae15f3, 0x3bc786ff, 0xad1495aa, 0x3121725f, 0x2077da2b, 0xe56790c5,
- 0x7f049ef8, 0x811f38b2, 0x1639ab1d, 0xbd508fdf, 0x79cfd758, 0x07bf7c29,
- 0x97dfd8e9, 0xf5099bbd, 0xac607905, 0x1fff96a7, 0xe5b7931b, 0x11ceda16,
- 0x872e5fa9, 0xbabe58f3, 0xad27932f, 0x2ae7ff58, 0x9ef2f39d, 0xebfab2fd,
- 0xf575036d, 0x3c65f6d4, 0x7e9188de, 0x16fde71f, 0x2c337c37, 0x288d3c5a,
- 0x3fefc7f3, 0x04df8815, 0x1b4ecb7a, 0x778251c6, 0xbf0fe0f8, 0x5ff76647,
- 0xc610ae25, 0xe5c7d933, 0x084c4971, 0xe5f4abe3, 0x90fa80f3, 0x17b6d627,
- 0x2fa5ef00, 0xe7c408d9, 0xe9c57d29, 0xee977c05, 0x57fdaaf9, 0x66efe099,
- 0xe95ebb47, 0x7482ff2b, 0xcd096a50, 0x3b6578c5, 0x99e2042d, 0x237cec75,
- 0x43b5f80d, 0x7fc5a50a, 0x695ebdcb, 0x478862d0, 0x52efe7e0, 0x7de18303,
- 0xb33efabd, 0xd33917a8, 0xdef76365, 0xbdde6cfb, 0x7d77e436, 0x95739edc,
- 0xefb483cd, 0xe8948bb4, 0x9b4df172, 0x69d977f4, 0xa3b8e5bb, 0x37c73bc7,
- 0x49e73e61, 0x2018126b, 0x0e3ea8cb, 0x21a8bcf2, 0x0fd83fbd, 0x77d4d90e,
- 0xec2c4aec, 0x05248747, 0x0687d9cf, 0xfbb5fd28, 0xab4a99cc, 0xaed09662,
- 0xdd576983, 0x097d79a7, 0x66da27f8, 0x1f7b9345, 0x8f08ecd9, 0x1bc5ab22,
- 0x07649ded, 0x02deafdf, 0x1b224063, 0x1d43f817, 0x401490f7, 0x4628bc39,
- 0x0ff4fd61, 0xb8bdf0c8, 0x2d20ef61, 0xd5cd0a1c, 0x29f28f58, 0xd490b3c2,
- 0xf91a99c8, 0xb8578ead, 0xf198a1dc, 0x3ff9ba3d, 0x8c55e9ba, 0xc88d19e0,
- 0x7472789a, 0xb33b45c7, 0x2cc0eefa, 0x7e015ae5, 0x9b75c932, 0x6a952045,
- 0x1218f7e4, 0xd541d4c4, 0xaabf162e, 0x3c9c8082, 0x83471dd3, 0xd7811a60,
- 0xfdf72803, 0x92190803, 0x1286fa0e, 0xefc0d6eb, 0xf385cd92, 0x082b98b1,
- 0xddd31793, 0x7e0a7fa0, 0xe94cb91f, 0x61b2aaa9, 0x40f78b10, 0x0d7ef0bc,
- 0x3f3a5855, 0x4bf5fb97, 0xd5f907a0, 0x27df70b8, 0x620a2a81, 0xbb453370,
- 0xe2c224eb, 0x463bad99, 0xb48fe7b4, 0xffaf8118, 0x0731ca20, 0x6984fc89,
- 0xc82ac41e, 0xbfd8aadb, 0x9cfdc365, 0xa0424dc3, 0x241dda1f, 0x63a9a764,
- 0x969cf9a4, 0x34995dff, 0xf74ba1af, 0x91b97d04, 0x335ca82f, 0xf8441b8c,
- 0x373f7ed1, 0xa1b9fbf4, 0xadbfcfdf, 0xe54e155f, 0x10e941d6, 0x65756087,
- 0x8d8dc390, 0xa370e567, 0x710e19f0, 0xc62988d7, 0x11cdefc3, 0x367c31ae,
- 0xf14fa816, 0x1d26273a, 0xd8f3f4e1, 0xaff06103, 0x04b50925, 0x04abc3ce,
- 0xc922fe35, 0x11da6875, 0x70f915b7, 0x4e671f3d, 0xf577a30c, 0xfacf7c1d,
- 0xe8efbc36, 0x5bd6df51, 0xf5e898fd, 0xc7cdbd9d, 0xdf3e751e, 0xbd94ce55,
- 0x705bfef2, 0x6f2ddb5f, 0xfa9414dc, 0x6273db77, 0x71a5bf68, 0xc36b7fed,
- 0xb46f4c2f, 0x2fe3d7f6, 0xd295e806, 0xfd60cc4f, 0x7bde2377, 0x7cf997a3,
- 0x48ef341d, 0x9bbaeba5, 0x9ea53f8f, 0xb3df77dd, 0xe8e3d98c, 0xf50bcff1,
- 0x77faf0e7, 0xaed1f35b, 0x87e62270, 0x9ee12718, 0xde17a65a, 0xf78890f3,
- 0x08e23dab, 0x7f942fc1, 0x042e5dee, 0xe2d1e942, 0xe3779122, 0xf8f3ff68,
- 0x4338c6f8, 0x5d4ca23e, 0x338b4627, 0x7d4ce8c4, 0x5f8c6587, 0xf2e488b0,
- 0xeffa51f8, 0x933736ed, 0x5c80e687, 0x2fb2323d, 0x3a5237f9, 0xd2927d06,
- 0x8967dc31, 0x712d3dfc, 0xfabfccc9, 0x3c9d788e, 0xb128a0bb, 0xc536bfb8,
- 0x2e1be2eb, 0xc724af1d, 0xf9b5e469, 0xbf175da2, 0xa4f24aa5, 0x2e92bc80,
- 0xca14475e, 0x3ec5f257, 0x5394d144, 0x1999143d, 0xee5136dc, 0x200398a4,
- 0x5ceecce7, 0x6c7a0f92, 0xb54fa31c, 0xa2309cbe, 0x9b7c6f5b, 0x262c7bfe,
- 0xe96cf911, 0xc6192512, 0xeb73da09, 0xcae893e1, 0x3d1cf8f6, 0x83bfc1e9,
- 0xd60abbad, 0x3d73de9d, 0x83c7b255, 0x774e73fa, 0xcc2b1bbc, 0xef28b44f,
- 0xdfbf302b, 0x2aec044b, 0x39e3e13d, 0xbbf0a013, 0x7e87e810, 0xf4ec6221,
- 0xc3afe8a1, 0x1075e4f5, 0xf5ca91cf, 0xe3be3c55, 0xf1cf1e2a, 0x737f1e61,
- 0xa8f38f0d, 0xa9eacfc2, 0xd68238c6, 0xab7facc1, 0xc127e39b, 0x43e3e1c4,
- 0x529ac97d, 0x3684f781, 0xe2084577, 0x74fe9171, 0xbb69809f, 0xb27e11ab,
- 0x927da09b, 0x05bcc7d6, 0x6a9534f2, 0xcc1e2247, 0x4f920aee, 0xfbb61fcb,
- 0xd9b802de, 0x41bc7d14, 0xc340ca4b, 0x9e01b0bd, 0xc93d3d2a, 0xa70262e4,
- 0x127c2327, 0x53df1664, 0xf4dea3a5, 0xcfee2aaa, 0x83d2a9bb, 0x2b8f1569,
- 0x84710555, 0x8f294e20, 0xcfc89423, 0x8e145589, 0xbe09fdf0, 0x6655566f,
- 0x9da67963, 0xa60953ed, 0xc012838a, 0xbb309e25, 0xf49f8267, 0x55cc22cf,
- 0xfc527e14, 0x7abc8144, 0xe7c3588f, 0x7441e9cd, 0xe1710d9b, 0x2f002794,
- 0x26486f35, 0x9715e7b8, 0xd63e4cdf, 0xcb38b3d0, 0x3476071b, 0x6013e1d1,
- 0xe039fbff, 0x2367ce95, 0x59c6179d, 0x9ab0f4e5, 0xa72d7de3, 0xde3cf587,
- 0x5d382fe7, 0x0fd74a3c, 0x7b0f2af9, 0x1a61b037, 0xc84b8bf3, 0x68b8f130,
- 0x3bf5a221, 0x8904f38b, 0x3c89d74c, 0x718a60aa, 0x0b31c8ef, 0x247d8bd2,
- 0x7e508af1, 0x8b0081ec, 0x0a9b9963, 0x1a9c66fb, 0x128272b7, 0xb61f1b37,
- 0x3e3ccc86, 0x1dcec89c, 0x3de351ad, 0x590e7956, 0xdbdefce1, 0xdcce0e7c,
- 0xf6bc6043, 0xd20e8851, 0x7b3b97c7, 0x6a3bcd31, 0x7f4dfea9, 0xda5f1eec,
- 0x5ae7a06a, 0x373f010b, 0xbe7f9d07, 0xf7b1af46, 0xd9080762, 0xa9d8a47f,
- 0x45074b3c, 0x97f7e283, 0x006c83b5, 0x05730a67, 0xa49b1dec, 0x039054dc,
- 0xdba2e29b, 0x4cec626d, 0x8e65765f, 0x8d75d1d0, 0xee76c5e4, 0xf4746309,
- 0x4fe5c35f, 0xdd1c94fc, 0x7cde5577, 0x0bfac31e, 0x30997dda, 0x998ba4af,
- 0xb709bfc8, 0x553f9745, 0x3887ec92, 0x98a35500, 0x94cff3bc, 0x43d59e99,
- 0x7539309e, 0xf8f08c81, 0x86467435, 0xbf07d413, 0xe2eb299c, 0x3e03ae19,
- 0x63710619, 0x02affd19, 0x38a9a07e, 0x89fa4658, 0xf3c26e9f, 0x5fce1aea,
- 0xda7e730f, 0x11e9f9c0, 0xc40b23e0, 0x677c659f, 0xb0e19e26, 0x58b9549f,
- 0xfe012ddc, 0xc5549b4f, 0x7187982c, 0x04598f8e, 0x32a89fb8, 0x4317537b,
- 0x59e2d6be, 0xe31e60a9, 0xed6bfb01, 0xdf7f344a, 0x2ce27d90, 0x6cd7853b,
- 0x6ac7bf8e, 0xacfe22c7, 0xac014f6e, 0xc188eccb, 0x50d57df3, 0x73b4416b,
- 0xb33b74c2, 0x2f78508f, 0x4cfa7e84, 0x873ee9cb, 0x66a19981, 0xfdc21666,
- 0x1d077831, 0xedca7e85, 0xfd218f4c, 0x46b064fd, 0x38f0d40e, 0x93f14471,
- 0xb0791ae1, 0x0254c872, 0x729e9e76, 0xb83917a0, 0x2ac1c98d, 0x062fef81,
- 0xf8f156bc, 0x341caadb, 0xc4a35e03, 0x4d7d5ad7, 0xbe7deeb6, 0xb1b8e5c4,
- 0x3b3b3ade, 0x9e21ad37, 0x59e84fb0, 0x0eb4e14e, 0x3fd914e0, 0xa0e3ba73,
- 0x3aca20fd, 0x0ceff28c, 0x532083ec, 0x338c3ecc, 0x9e5648b2, 0xe5720f18,
- 0x4cbf98df, 0x3a827a6f, 0x42c5fe5e, 0x2ef267dc, 0xbffdc78e, 0x213c76a0,
- 0x2b02ae70, 0xf69de6bd, 0x753fcde9, 0xd74ede01, 0xcdd3fbf2, 0x57fc0052,
- 0x2eaed74e, 0x4db57cc3, 0xfc4c9c01, 0x882e03e5, 0x69e8b2cb, 0xcf53ef11,
- 0xd0d3f8c4, 0xcbebefff, 0x7f8d4597, 0xb5ba8ac4, 0x169f2069, 0xef8b5d6d,
- 0x7bc4ceec, 0xf26ae687, 0xbd415324, 0x96d38d50, 0x0bc58cf7, 0xfb6f5dfa,
- 0xe8e6de52, 0xf82afde7, 0xca5af415, 0x1eb7a02f, 0x4384e574, 0x7e67ff14,
- 0xb27d4369, 0x4277f64a, 0x1dab6abe, 0xf8aa905a, 0x1e3ff1e8, 0x0bb4dfb6,
- 0x76c3c7e4, 0x89483eef, 0xed4bc583, 0xf8ea3e6d, 0x856b60ed, 0x78a7b77b,
- 0xa78a141c, 0x1bbb3a99, 0xe76b77bb, 0xed621476, 0x97863ca5, 0xbb94bd2b,
- 0x710c9f98, 0xe7572f47, 0x1f9f9673, 0x07b56d17, 0x03d14656, 0x84f7f116,
- 0x867df88b, 0xbb672f4a, 0x67462df5, 0x1725ff6a, 0x62f465af, 0xb9e14ba0,
- 0x9f874851, 0x7f70911d, 0x11bb9e11, 0x5d94b4e3, 0x12fd61b4, 0xf828f3d1,
- 0x45b79377, 0xdefbd3a4, 0x59f78718, 0x9078861d, 0x09e983a2, 0xb1779a6a,
- 0xe69fa758, 0xb0ca1605, 0x2c5de79f, 0xf60c7463, 0x93983867, 0x689b5e6f,
- 0x0396f4e6, 0xb4dd2fed, 0x6fcbd692, 0x264ef463, 0xbed0cbf8, 0x3cf76758,
- 0x8a0e451c, 0x3717450e, 0x84adbf34, 0x49f873b5, 0x7ffee682, 0x9e8b8f11,
- 0x45c5917f, 0x493f6e24, 0xf2e73a01, 0xfa9f4229, 0x261db5f8, 0x7ae32f86,
- 0x133af813, 0x437bd7ba, 0x3efdeb2f, 0x0fd72f5b, 0x1bc6dbf2, 0xf1abf5d6,
- 0x5915d6d1, 0x5fac04cf, 0x970de3c2, 0xd5de1898, 0x4c1d1bf2, 0x7b69ab0e,
- 0xa5e22ce5, 0x8f2151fb, 0xb81798ab, 0xcf3e064f, 0x2f171cdb, 0x5f99d668,
- 0xa7e7473b, 0x1f3b5792, 0x6fe570e3, 0xd02f2f9e, 0x9e3755f0, 0x6baf29fc,
- 0x86e374f1, 0x3a57533e, 0xbdca1f60, 0x3ee301d6, 0x65f73a5b, 0xbc32fd02,
- 0xa3fd919d, 0xdd0e502b, 0xcef68ae7, 0xdbc046e5, 0x387ced38, 0xc9fb06de,
- 0xa37bed48, 0x58e3d18b, 0xbe2b6fb6, 0xdbbbee1f, 0x4451649f, 0xd137977a,
- 0xe38469f1, 0x59bf0e2c, 0x8e1c70dd, 0x8657547e, 0x7f3a75e3, 0xc8e15ea9,
- 0x49c2aff1, 0xb0f54efd, 0x18448e99, 0x57f7b097, 0x0aafe3b5, 0x27f1917e,
- 0xa1defaf0, 0xa2fc824f, 0xf4f812f2, 0x1f3fb3ec, 0xb0f76dad, 0x30bde27d,
- 0xbabea90e, 0xd83fb57b, 0xdf50797d, 0x0473c93f, 0xadfe6bce, 0xae8aa7a2,
- 0xa9f630bb, 0x56ae10ce, 0xaeaddfbf, 0x760e186c, 0x20caaad6, 0x40bb54a6,
- 0x8a6a8bbd, 0x685fd01e, 0x78b46f15, 0xbc39eb54, 0x32b65757, 0x4fd5913b,
- 0x240f60dc, 0x99c92f8c, 0x333768b1, 0x837af43b, 0x60dcf92c, 0x7bf993a7,
- 0x5becc967, 0xe7099e97, 0xbf0c84e0, 0x1d6bbe06, 0x4362ffcc, 0xf83f52ca,
- 0x3ec159ed, 0x22ed0839, 0x81767417, 0x9c8bcd57, 0xf0d4ee94, 0xf58331a3,
- 0x904252e5, 0x246e1da0, 0x479daefd, 0x2eceab42, 0xd98b846a, 0x12fbc2ea,
- 0x2ef6e133, 0xeff50f0e, 0x72e5ac64, 0xcddb86b8, 0x197b071e, 0xbb4adf85,
- 0x35a3f70b, 0x39d898d7, 0xf3c66ac3, 0x40f1b835, 0x8fd6397d, 0x7ac1b0eb,
- 0x43f3d044, 0xe4427798, 0x7b43111a, 0x238f9009, 0x3ef9008a, 0xf406b424,
- 0x6d89aed6, 0xd9f7c3f7, 0xe01d5f36, 0xd6d4cbf7, 0x4fd802e3, 0x00c37d73,
- 0x3fa2b5ce, 0x7ff5a143, 0xa033862d, 0x3a2d1a5e, 0x6bd2cf16, 0xa7daafc0,
- 0xf16197b9, 0xb1792340, 0xe59afe67, 0xc53dc366, 0xe5b4c3d7, 0x2d946cfb,
- 0x7bfcf5c6, 0x0b1f0929, 0x74b6ef28, 0xf173c9db, 0x8e51d07d, 0xa00fa44f,
- 0xbf6c23af, 0x625660be, 0x4dfd99e3, 0x67675579, 0x6aaf2ab6, 0xf3f333c6,
- 0x57a53d50, 0x74aba7b0, 0x35ecd832, 0xa90d3d01, 0x74b5dfa6, 0x832f4511,
- 0x72f70671, 0x0fcea11f, 0x3c0007de, 0x6c598bc5, 0xc5d031bf, 0x25fb6ebe,
- 0xb32a7bfb, 0xaf33c255, 0xa238f962, 0xd1fc60fe, 0xe3edba0f, 0xcdde58ab,
- 0xd80be572, 0x05a1dc7d, 0xa6d7e8b1, 0xcb7663ce, 0xc3d056da, 0x2ea4b766,
- 0xd999fb84, 0x0afeebd6, 0x7c293ee9, 0xe2720ec8, 0xe79e2ca7, 0x2abdefdd,
- 0xfbba69d9, 0xdef8addd, 0xcfdf34fa, 0x04b092e6, 0xb711f7f8, 0x01ebeccc,
- 0xc405d3e4, 0x0941f3c3, 0x84f7bdce, 0x42de7702, 0x1abef773, 0x628e05b8,
- 0x5f848f73, 0x82f97403, 0xc368a9ee, 0x7b35db56, 0xd679675e, 0x66fd7bae,
- 0xb227ae2b, 0x5fae2b5e, 0xf6441f5d, 0xb8eef2c4, 0x912e2cc0, 0x0b498f0a,
- 0xdb67bad9, 0x7c98fce7, 0xdb39de8b, 0xccafea3a, 0xc7cd887f, 0xa1cf9f08,
- 0x4ec5ca88, 0xa4e4d787, 0xe1d0ffeb, 0x5eb49d15, 0x669c3589, 0x62fc881e,
- 0xe8997c81, 0xae8926bb, 0xdf00fcff, 0x438044b0, 0xd2ab9f6b, 0xf4e4df2f,
- 0xefa726fd, 0xe3bbd337, 0x1ea02718, 0xae024f7d, 0xb3a7066b, 0x47dfbb35,
- 0x6ff3cc3f, 0xa54b78b0, 0x83eb72a2, 0x49133768, 0x6aac38b4, 0xdfb726fa,
- 0x0e954e28, 0x0dce3c03, 0x4d1997e3, 0x9fbbf476, 0xf4ea2991, 0x029919f0,
- 0x1d6b87f7, 0x2f4e877d, 0xd2f5c55d, 0xff80fd9e, 0x859fb181, 0x39e327cb,
- 0x9eec8f6c, 0xffdff208, 0x85b3a334, 0x293c2853, 0x13ace5dd, 0xfc70def0,
- 0xf20236a9, 0x1c4d6170, 0x85f3fb81, 0x20fbfc0f, 0xd650c788, 0x81b734aa,
- 0x1e080c9c, 0x8b25bfb0, 0x467e324b, 0x10e9b5e7, 0xbf2187db, 0xf0e9e604,
- 0x3d8d0e2a, 0xc8aa43ba, 0xdf5d0370, 0x3c82f0eb, 0xf7877f98, 0x6fe78c03,
- 0x7b041d0e, 0xf99ebab7, 0x00d928f7, 0x9b41f9ff, 0x312b5317, 0x36b950c7,
- 0x90ac4cdf, 0x6cc4cb26, 0x73cb7c83, 0x1e4bb05f, 0x18e4eeb6, 0xdfdf6562,
- 0x72f404b8, 0x5bac835d, 0x3ea0a8f7, 0x3eb37d7f, 0xe7d2119f, 0xe7d11ec7,
- 0x431a83b7, 0xffc395f1, 0xfda1d4ce, 0x877f0216, 0x0b45f8a6, 0x0cbeb3fa,
- 0x05fa007b, 0x4dde50da, 0x82c96e2e, 0x5e4fd6fb, 0x9ce09a70, 0xdf9befbf,
- 0x786d7de2, 0xc9e31d87, 0x0c53fc1f, 0xc07f0189, 0xa15b6d17, 0x04e298bc,
- 0x2fc577ec, 0x0ec0eada, 0x7a8467b2, 0x5fa00d1e, 0x31bf9ec5, 0x76f0f9bf,
- 0x6fee004b, 0xdcfbd93f, 0x9f6f400b, 0xfa87ef6c, 0xdf82cbce, 0xd7f9fd04,
- 0xc4e67c33, 0x272d7db0, 0xde33d286, 0x75cfebbb, 0x1c993bf7, 0x1e6caf69,
- 0x4e59fb01, 0xb47fb33c, 0x011c1e57, 0x8f0e5cfb, 0x49eaae43, 0xbc7e3c39,
- 0x274fea9b, 0xe51439d9, 0x0fce70c2, 0xb2058179, 0xd5fa01d7, 0x5390188a,
- 0x79e5675d, 0xac358fe0, 0x15470f56, 0xf406d7cf, 0x7cf92bdf, 0xf7cd1016,
- 0x56f7b874, 0xbd00a4d6, 0xbea2433d, 0xf9c35c7b, 0x65e7f9e8, 0xf22fbcf5,
- 0xd14468f8, 0xc88acfbc, 0x1facb273, 0xbe0025f8, 0x17be4606, 0xfb55c61b,
- 0xfffbca9f, 0x92fccacc, 0xce1c3813, 0x7d411e55, 0xaddf5ba0, 0x68a77af4,
- 0x07b579f2, 0xfc23e693, 0xd02d260e, 0x1fb6f39e, 0xfe039a4e, 0xfc660d36,
- 0xb32553bb, 0x27247d9f, 0x418bbe01, 0x03942798, 0xaf823b1c, 0xd51ea0b9,
- 0xfd68c767, 0x6f6bf257, 0xecd14ef2, 0xce95dfd7, 0xbb65e3bb, 0xca5e5c19,
- 0x16fdbdce, 0xa2cdbba0, 0x0715aa07, 0x1479bcef, 0x84b37bc0, 0x764b72ef,
- 0xbdb7184a, 0xb406eebc, 0xbe371453, 0xffe31533, 0x03df393d, 0x9332caf3,
- 0x9a0c715c, 0xf480ee18, 0x8c6ecb4c, 0x61fc57af, 0x60566c8d, 0xa3ba7abe,
- 0xa3f08c74, 0x6dd6541a, 0x15de53c0, 0x7eab3fe8, 0x30b7e237, 0xc46f6fa0,
- 0x1ba72b53, 0x8b5c33fa, 0x3ebd636f, 0x8ef8fdd3, 0x953964b2, 0x543b1a63,
- 0xf46aa9c9, 0x038e33d7, 0xa344da37, 0x7703eca7, 0x1dafe01b, 0xfe836fcc,
- 0xee2cd608, 0xe5883ad7, 0xd0200e31, 0x047fac15, 0x3bc0a299, 0x34c8dbcc,
- 0xd1b95548, 0x0d1c1d91, 0xda165ff5, 0xf615fd9e, 0xed7e44e7, 0x2e308770,
- 0x3efe5f62, 0x796143b5, 0xa83aeff5, 0x362d45e5, 0xe4f8f3f4, 0x71f28cbc,
- 0x4197f805, 0x266c17fd, 0x3ebfdd13, 0x1267d9d9, 0x04762df8, 0x73dcbc59,
- 0xe4933ec1, 0x8d77d96f, 0x0fdd4172, 0x74afc04f, 0xe9c2fcdf, 0x4b7ec30d,
- 0xcebf3156, 0x19153ee4, 0xa4f05115, 0x2b904bb6, 0x123ce032, 0xd9e1d7be,
- 0xa7f2708a, 0xc1723ec3, 0x81f68297, 0x121edcf9, 0x06fdceef, 0xbad275fa,
- 0xfe2ffa5e, 0xe815b888, 0x73d163eb, 0xe4507bbf, 0xa6516f9e, 0x90f3df0f,
- 0xb45cec55, 0x66424cd0, 0x842eefaa, 0xe63463fd, 0xb85bbf71, 0xa6ff4059,
- 0xebf41b45, 0xdaad7881, 0x405087bf, 0x22dfb1aa, 0x60b4c412, 0x10bcbeb3,
- 0xf81723f6, 0xfc7bb067, 0xb97d7aa2, 0xa4a84efa, 0x1a25b2f1, 0xea20bedc,
- 0x2ec9bcfa, 0xb36e179a, 0xdbeefce2, 0x35eecb14, 0x7d85e264, 0x89c9bc30,
- 0xf898bc72, 0xbe3f3bd8, 0x303f960f, 0xd288bbdf, 0x85f2d767, 0x307d45de,
- 0x7d81077e, 0xf895b16f, 0x1e58635d, 0x0b2017e2, 0x38b29f21, 0xed4eb051,
- 0x29e2963b, 0x15c03424, 0x53ac2f59, 0x65de4e5b, 0x116e2cf8, 0xbd60a342,
- 0x64427ef0, 0x2bd6d5eb, 0x692870e1, 0x11ece8b4, 0x0a7fe0a5, 0x974d337e,
- 0xb97eba2d, 0x8fdd1f3f, 0x69e28d89, 0x0ddcb753, 0x4fcd1b5c, 0xd78738fe,
- 0x52f33ba6, 0x051f3f81, 0x072fb33d, 0x173d3668, 0x61cc9083, 0x71d2b780,
- 0xe776c662, 0x256b3cb1, 0x647d4fcb, 0x51e90fe0, 0x1bcefe1b, 0x142c6fde,
- 0xf7875f73, 0x7db9cf57, 0x71d1763f, 0x69bc9a16, 0xef53e466, 0x5cd7f450,
- 0xc4ffd6ce, 0x2b6b8a98, 0x557b9ca2, 0x042e3e7c, 0xbfd1bef1, 0xceabed97,
- 0x7da4b0cc, 0xc5c8b45f, 0xa1ec4fe4, 0x10777c36, 0xbbe02dde, 0x138527c7,
- 0xc9f02ef8, 0xce04291f, 0x6f1429e5, 0x149f1f20, 0xbf882ac8, 0x7334d995,
- 0xbf806bc9, 0xa3d418cc, 0x8a269b4a, 0x3f5c0ea5, 0x15eca3d3, 0x99ef7075,
- 0x18f86f3c, 0xeeba6ba0, 0xff01b779, 0x5b8414bb, 0x41d183aa, 0xfa7f4aca,
- 0x7e3091d2, 0x80d792ee, 0xe0c546ef, 0x0a64d93b, 0xa63c672b, 0x4a2f40eb,
- 0x41071921, 0x574ca78e, 0x772d80c6, 0x938d8b93, 0xcde71268, 0x0c6dfd04,
- 0x243fc7cb, 0x7122b778, 0x2575c46d, 0x369fd85b, 0x7fa0ef82, 0x804ec15a,
- 0xe78601e5, 0x301915c9, 0x9620f27e, 0xf421c826, 0x8dda3a53, 0xcdea1f77,
- 0xe504dccb, 0x134bb2f2, 0xfb69e393, 0xc0f41da3, 0xd1d5e54c, 0x1d9eaafe,
- 0x439e8072, 0xf5670f06, 0x2cb15eb9, 0x27e5f983, 0x10faa9a4, 0x7925d7ab,
- 0xfc82c763, 0xdbe9877c, 0xb1bc3b9f, 0x837737e0, 0xb80fdd1c, 0xfca9e386,
- 0x34049da2, 0xd67cbff2, 0xa4def897, 0xf74ba2fc, 0x69c9e21d, 0x0a4b49fd,
- 0xe3dc610e, 0x7e8ad252, 0xbd41a5c9, 0x310debff, 0xe955c7d1, 0x48a2fcbc,
- 0x95c751fc, 0xf62fdff5, 0xd13efe21, 0xbfe925ea, 0xf9f4145f, 0x3d78afe6,
- 0xd9277e33, 0xc7382e6d, 0x077d874d, 0xe4c049e4, 0xe08fae97, 0xa6ddd3a5,
- 0x153a6fdb, 0x71e2ef96, 0xb572d575, 0x3259ceff, 0xc6139f7f, 0xa92a3a71,
- 0x79f0a240, 0xb453e5aa, 0x1cb496a3, 0x74a8f844, 0x9d938111, 0x4a7035f8,
- 0x990d6aaa, 0xfeff8f28, 0x476b4591, 0x72514b5e, 0x3fb3f388, 0xf297ad6f,
- 0x2fc4126f, 0x3db7f0d7, 0x51df9bb3, 0x89326ccc, 0xbf99dedc, 0x4d04ca76,
- 0x6eefd79e, 0x21f82fef, 0x648e6794, 0xa47bdfed, 0x072b77f0, 0x5d13e447,
- 0x53ae5a47, 0xf21ab793, 0xa51f9a0e, 0xe50dbbc9, 0x14f28609, 0xab3fbe43,
- 0xa50ce1df, 0xda421e89, 0x21fd291e, 0x8eb95dfc, 0x885cd0d4, 0xac41b038,
- 0xddfc21f8, 0xf64cd2c9, 0x5acb1477, 0xb3730f04, 0xf32bf062, 0x87307bb0,
- 0x385e4da7, 0xfad0e012, 0x9283c83a, 0xfa0dc166, 0x33b823be, 0xa7687984,
- 0xd905da68, 0xe092ad3b, 0x6bd76c09, 0xc84dc3ff, 0x3f0f0fcf, 0xe4aef589,
- 0xeba644ef, 0xf37be0fd, 0x7c9874b3, 0x53df6117, 0xec770ce3, 0x77f23f7c,
- 0xcef7e8ed, 0x9461ef54, 0xaaf786a7, 0x471f30e5, 0x38545f84, 0x02fc3c3e,
- 0xf3fc5dc6, 0x40f796a8, 0xfb2fb00d, 0x95e80574, 0x1e9e961f, 0xc4167a07,
- 0xe3fd846e, 0x2d702171, 0x114f47ec, 0xee30b5df, 0x0e43a5bd, 0x39949fc2,
- 0x816db52e, 0x1ec31050, 0x3ff08f5d, 0x001b6cee, 0xdae8927f, 0x4f961ad8,
- 0x1008c36c, 0xfd37626b, 0x39fb4cd0, 0x806da03e, 0xc547e689, 0x43e5661e,
- 0xfe40b6da, 0xb0dfd8ce, 0x036d51f2, 0x1d1c3744, 0xdb7f111a, 0x3ef9d1dc,
- 0x1bc9962d, 0x06437e75, 0x4163537b, 0xfb612a8f, 0xb4873c0e, 0xb73ab952,
- 0x6d8edce8, 0xff731e14, 0x6ef28ed5, 0x3fedc75b, 0x3fb1fa66, 0x92a0fc17,
- 0x5f71bc39, 0x466ef944, 0xf61521bd, 0x3e08f8c2, 0x0aad699d, 0x2a231bee,
- 0x905e8276, 0xee24773c, 0xef4e9d1b, 0x9171d8da, 0x9a048bf4, 0x8dac79d2,
- 0x2ef93375, 0x5b3df09a, 0xd44e83f2, 0xf1e51e9f, 0x21df29ba, 0x5e38387d,
- 0x8cf5f2c6, 0xa1e7658d, 0xd84dd744, 0xaf5cddcf, 0xd81f59ad, 0xfff0a36e,
- 0xde0e7a93, 0x39e4f4c8, 0xc4ee5475, 0x37817f82, 0x1cc9e415, 0x8c8f07b0,
- 0xbfbd55e4, 0x1de68326, 0xcd58f391, 0x36aa6f4c, 0x1d4d782e, 0x55e5572b,
- 0xaf6b3a4d, 0x55c95bee, 0x8fc93e0c, 0xd615bb5e, 0xff333761, 0x86b3c581,
- 0x7a815d6e, 0x5f386dc0, 0xc2a6f5e2, 0xe154fcb9, 0xa3e81340, 0x0da67e2a,
- 0xeb82def6, 0x2a38f7e1, 0xd7f1d49e, 0x142f75f2, 0xf6011ea9, 0xe10fb774,
- 0xd18af549, 0xe99d72ec, 0x5ae96b15, 0x7c2a1f01, 0x1c6db989, 0x045fff7c,
- 0x0cffa5a7, 0x7eddfd38, 0xbc7bd3dc, 0xfd0359c7, 0xad3f2e97, 0xe1c38f7f,
- 0x9210b8fe, 0xf1353392, 0x3877e853, 0xf2eade77, 0x735622fd, 0xc1f735bf,
- 0xd53fd452, 0xe5ffd8f5, 0x917769a5, 0xd469fc9e, 0xc9ff8f0f, 0x02ec01ba,
- 0xca20e5c7, 0x263fe3e3, 0x38e42ef8, 0xeaa5678f, 0x5aff59b7, 0x6dce147c,
- 0x222b11ff, 0x7a54d87d, 0xe6777210, 0xa7aef851, 0x3bbc39db, 0xd464fd57,
- 0xc786bafd, 0xe079ada1, 0xd1af7c3a, 0x3cf0da45, 0x2826cfee, 0x67cbbb3f,
- 0x4a72c50f, 0xc81b7e27, 0x8c18c289, 0x41935fc7, 0xcd497df0, 0x0e5811ec,
- 0xc7f458e7, 0x71c56d99, 0x3a32666a, 0x478c29ac, 0x5dc8217b, 0x746f5b80,
- 0xecc55494, 0x1decc41f, 0x7f1fbdad, 0xf9f9962f, 0x76db33db, 0xed7a0fbf,
- 0xb5ea1b06, 0x57bc4280, 0xf1c64ea9, 0x8fec3d28, 0xcd97fdc5, 0xa963e163,
- 0x5c718781, 0xd603da0f, 0x51f3bd3a, 0xaeccfdce, 0xdb37fcc0, 0x18eb3ac8,
- 0x5590e638, 0x7cf92f28, 0xe813f548, 0xeb8f3157, 0x5c151f89, 0x721e8270,
- 0x1edbb634, 0xf9f385e0, 0x17cac202, 0x013f643c, 0x0f05abe7, 0x64b778b1,
- 0xfd5e4ddd, 0x6b9d093d, 0xf9d3d812, 0x09d86d4f, 0x3b41f070, 0x1ffff417,
- 0xe41f784e, 0xc3bd887b, 0x7eda7e25, 0x47fda478, 0x9760f7c0, 0x49fcd917,
- 0x16895da5, 0x58a3f4e7, 0xfd5397ee, 0x9e3b5784, 0x5fb18e3a, 0x036c8e7a,
- 0x0f70a37e, 0xf0a83bc1, 0x59dfd8cf, 0x4137ce30, 0x46c2ff0e, 0x8a56e7cb,
- 0x3c292b71, 0xb89dcb7d, 0xf3be755e, 0xa237c392, 0x7fd0c29d, 0x0b2cbdbb,
- 0x79eae7ec, 0x39a43c88, 0xe45c21ff, 0xf8845e48, 0x573c6101, 0xcfcef8f5,
- 0x2873c6cd, 0x68b37f21, 0x2bbf75eb, 0xfcc30450, 0x82295d39, 0xe3e6f019,
- 0x1cb2fef7, 0xeb720b9e, 0x50eb02ff, 0x8000589e, 0x00008000, 0x00088b1f,
- 0x00000000, 0x7dc5ff00, 0xd5547c0b, 0x73b9f899, 0x3332bcef, 0x49324cc9,
- 0x9b8f2126, 0x80402107, 0x52024c49, 0x1878431f, 0xa4076b35, 0x438b5b16,
- 0x921123c2, 0xb175b689, 0x5100cb65, 0x8d042208, 0x41380abc, 0xbb6bba50,
- 0x060222c1, 0xb6a2d11a, 0x6eb42fea, 0xfdfeed57, 0x58f88845, 0x16544649,
- 0xefffad5b, 0x99b9cefb, 0x514493b9, 0x67f4ddbb, 0x739ee72f, 0x77cef9cf,
- 0xcef9f7be, 0xe99a1619, 0xf4662deb, 0xfc3e79f7, 0x33577f87, 0x3034e896,
- 0x7cd8ca96, 0x96773599, 0xeb47df44, 0x6d67aa25, 0x34967d5b, 0x0bbc02c6,
- 0x66f536e6, 0x607da1fb, 0x694df9b9, 0xeb88bc22, 0x6330b19f, 0xb56d8c15,
- 0x993590b2, 0xf4126db1, 0xbbcf0e53, 0x7935e16c, 0x23580d8c, 0xc602b08f,
- 0x59afc782, 0x1bfbef80, 0x4d065412, 0x08589876, 0x8ee3a1cb, 0x576c3ef0,
- 0x64c45bd4, 0x7c1807a8, 0x24be786e, 0x0d248477, 0x5e9ac608, 0x87acf792,
- 0xae47fd76, 0xb2acfde5, 0x41ca0ca9, 0xb8c136a8, 0x575fd0c1, 0xa4c644b2,
- 0xff1a1639, 0x6c2921cc, 0x66c3fac6, 0x85e0d3e6, 0xbfe1faff, 0x2f1832fa,
- 0x2719086c, 0x102b13c1, 0x8236c38e, 0x40da6603, 0x813f7de3, 0x9bf187ad,
- 0x00cf920c, 0x8db74df5, 0xf0e1af0b, 0x67e01858, 0xc9ad0099, 0xe8245ac0,
- 0xb5e0532f, 0xe8ba70c9, 0xa75e128e, 0xf8a5bb40, 0x3dda950f, 0xcb9c012b,
- 0x647a1b2c, 0xe1399380, 0x0dbfa83f, 0xeba2f3eb, 0xbfe1b4d0, 0x3479c33f,
- 0x2db8041d, 0x3d97b851, 0x6dc79fa6, 0x27ad14cc, 0x7eb443b8, 0x2f8e72b6,
- 0x47858336, 0x510ebc03, 0x84f755b6, 0xf2c7c465, 0x65ccece9, 0xef44f4d0,
- 0xeb1dbf2c, 0x3c2d593b, 0x5f30ef83, 0xda9ee018, 0x28ccf1d5, 0xeeaaef68,
- 0x06e9c6c9, 0xa0b1ff97, 0x3ae8b2ef, 0xde5e706b, 0x766659b5, 0x03be8f1a,
- 0xec077c50, 0x9cec6ed4, 0xd5cfb109, 0x41aa5df4, 0xebc715be, 0x881957c5,
- 0x04865f1c, 0xc8696ce3, 0xdabae037, 0xb0057814, 0xb31b6a2e, 0xd9e11567,
- 0xc1c73457, 0xec8983d8, 0xd3e13f56, 0xfe87e95b, 0x2d56751e, 0xe97f4274,
- 0x9d5baaae, 0xbf1c7ca9, 0x029fa703, 0x6ba50d40, 0x47e1a9ed, 0xd05e976b,
- 0x1f6cda5c, 0xc4db9db9, 0x9ed916f1, 0xf083de14, 0x17951228, 0xb1d8deff,
- 0x8853e09e, 0x95d8ee6e, 0xebf84617, 0xe9099b59, 0x9b0b197c, 0x5b178e90,
- 0xe8112858, 0x4b343162, 0x6d92e782, 0xacc6a666, 0x5f58435f, 0xae1ced66,
- 0xd3f74a65, 0x4dd22252, 0x74b3f50f, 0xb2ddbebf, 0x01dbac19, 0xd6168df5,
- 0xa767c36d, 0x4589bebe, 0xe1e08e08, 0xfebacdcf, 0xc3ad1b59, 0xc8632b76,
- 0xbe6549a7, 0xfe01bbbc, 0xef460bc8, 0xb7cfa01e, 0x7868bac4, 0x35567648,
- 0x64139e20, 0xb233cd03, 0x03de16ca, 0xb033ecf3, 0x4de75c7a, 0x1ceb762e,
- 0x64aff678, 0xa12342be, 0x77ae2263, 0x1fd73e3c, 0x7d23d6b5, 0x13f9416c,
- 0x38373f43, 0x5ee7848d, 0xbe47ab13, 0xfd0d5ca9, 0xa6a5c8c5, 0xfc01ec9b,
- 0x9726976e, 0xc46f9d60, 0xa86b6675, 0x9e91ed8c, 0x4fe32e12, 0x83bdbbed,
- 0xa7f337ed, 0x4b7bf9c2, 0xae074243, 0x0cee9453, 0xc4aee88c, 0xf7c00a6f,
- 0x583c8547, 0x38fdf960, 0x40a3f7a4, 0xa1f7c808, 0x0b972b4e, 0x72fe738a,
- 0xa77d1f28, 0x455ebbc4, 0xe272e0fa, 0xd812f7e8, 0xf9f2186a, 0xdef5fef7,
- 0xfcfea197, 0x0cd5263b, 0x46910bf5, 0x4a8f3d60, 0x85e387cc, 0xf787309e,
- 0xc065bbc1, 0xb2cf08b6, 0x28c213e3, 0x02990edf, 0x38e117db, 0xfbbd1b8f,
- 0x8965bbe0, 0x423c5fe1, 0xa05e19f5, 0x9194f644, 0x88e861d3, 0x109f7f8d,
- 0xb95fb7fe, 0x1bdd3eb1, 0xac7bf682, 0x07c81381, 0x09356699, 0x97bf65fb,
- 0xbba71f19, 0x3bf805c8, 0x824af38d, 0x38495427, 0xfa83974e, 0x58cafe01,
- 0x699cfd04, 0x80f9a74d, 0x38e1f4dc, 0xf79a3667, 0x32dcdca0, 0xed44ae38,
- 0xb3fd1b4f, 0xfa7ca032, 0x2aef5289, 0x9bf01aa8, 0x7f404dba, 0x5f4b4dc1,
- 0xea17a064, 0xc46eea0c, 0xa36e3b0f, 0x11eb6879, 0x06a4b8dc, 0xadb783eb,
- 0xdae501b8, 0x7289fc48, 0xbbc8c59a, 0x41c9167e, 0x9f51dffa, 0xfa8dd9df,
- 0x57ac6ba0, 0x2c0f5aa6, 0x9387d03e, 0x7233edb7, 0x198e46fc, 0xb52f4f89,
- 0xa50ba47f, 0x1c0feb92, 0x94f20827, 0xf242fc69, 0x0f2ca634, 0x18ebe657,
- 0xfc4e9a3c, 0xdb3f5f1f, 0xf908f811, 0xfffee9a7, 0x8ab96379, 0x9e4845e3,
- 0xe254b6b1, 0xdbbb8033, 0x6df7df02, 0xe55f1077, 0xf70f50ae, 0x741ebae2,
- 0x335d3cd1, 0xcb03b27c, 0x3ca8f33b, 0x1c6dc855, 0xe2c6f516, 0xcaf48c29,
- 0x58b59962, 0xd17de8ca, 0xf67f6876, 0xcf5a6c89, 0xceb666c5, 0x36ce7c02,
- 0xdb3ffa70, 0xf00a7201, 0x25ee6753, 0x4dfecb39, 0xb518fb62, 0xcb76c16b,
- 0xb28c9060, 0xb94378a1, 0x385bc3a5, 0x7ffa0ca6, 0xe907676a, 0x8a720601,
- 0x9a05d8c5, 0xa4f9431c, 0xcdfd9efb, 0x4863c7ac, 0xc7c4b793, 0xd9f4a930,
- 0x28f2a213, 0x72cfe9d9, 0x30a16055, 0x5677f11d, 0x04e9dc0e, 0x8584b6f9,
- 0xb0363e48, 0xe36a7a6e, 0x72e5bc81, 0x2ee5c2d7, 0x412e133e, 0x3ac6defe,
- 0xa2366e49, 0xee4e1a44, 0x3bb900ae, 0xcbb96471, 0xe2297358, 0xdd8b7835,
- 0x221e788b, 0xd77c857f, 0xc4dd31d6, 0x15d4f0e5, 0x44959961, 0xe89a90f1,
- 0x115a969b, 0x57c1abd5, 0x1275162d, 0x1f2cfd96, 0xda63ade5, 0x7d41a7bf,
- 0x943e6150, 0xe61eb69b, 0xbbf780eb, 0xf3f5fd84, 0xf1fa9534, 0x185d3898,
- 0x852b3f15, 0x9eaacafa, 0x49f2036e, 0xbca2732a, 0xfef0f477, 0xbbe03977,
- 0xcb8efc32, 0x2defc1cd, 0xe62125ac, 0x56a3aafb, 0x470ba3a2, 0xe933611c,
- 0x0bae40c3, 0xb3fb4bfa, 0xfea4ec99, 0xf3920ea3, 0xaf3646fd, 0xd1bbda13,
- 0xbcf5a21e, 0xaefbfa87, 0x219e8f2b, 0x218a3556, 0x8dd74aed, 0xecd65642,
- 0x9ebcc683, 0x1edf489b, 0xc7c8ab30, 0x77bd5c17, 0x63c61962, 0xedbf2728,
- 0xf05da952, 0x9fd2f4e0, 0xdfa0fbc2, 0x0dd8e5ee, 0x98bd2294, 0x64dd1fe5,
- 0x259b7581, 0x05dc88af, 0xdb663670, 0x6787289d, 0x9fd7fee4, 0xbbf2866e,
- 0x8ccc8d07, 0xfa6fbeeb, 0xb23f963c, 0x1b08689c, 0xd0c6f74f, 0xfafdd2eb,
- 0xbea76372, 0x2fac3c1c, 0xb872e1df, 0xde278ecf, 0xf40e7ef4, 0xbf373664,
- 0x9af001d3, 0xdc93329f, 0xf815debc, 0x26e7a467, 0xe224e443, 0xfefb9cd1,
- 0x73ae00c4, 0x3e1207d7, 0x3d2640cd, 0xc8bf1c25, 0x0bac1757, 0xd8c39d72,
- 0x857b51eb, 0x47840c59, 0x513d06b0, 0x20e410f9, 0xdef95f01, 0xbfe61a7d,
- 0x73824e78, 0xd5f1bd35, 0xbda25454, 0xe0b23042, 0x45df6bb6, 0x35da1ebb,
- 0x0d989c90, 0xfaae00ed, 0x2f6e5c6d, 0xc8893d63, 0xd7604d0f, 0x7f096058,
- 0xb1f4e2e7, 0xd95225b4, 0x4f6cff0d, 0x708b1eae, 0x7e299f2a, 0xd8b5ff5c,
- 0xf61d8c6f, 0x1dfb8b90, 0xdb5bf74b, 0xa1f862fa, 0x2ba5d3b1, 0xb4670f07,
- 0x5de2c5f5, 0x25533ff0, 0xb6ded625, 0xb90f021b, 0x7b0f9152, 0xfc60d34d,
- 0x88fb3fab, 0xe592f7f4, 0x0a9d90cf, 0xedc058f3, 0x728aab36, 0x4f5dc975,
- 0x2fcd7bd3, 0x276d9b38, 0xed99e0bf, 0x99765e66, 0x17767ca8, 0x74965bf7,
- 0xa79c614a, 0xca62e734, 0xbba79434, 0x1b334e8c, 0x3c78d78a, 0x3ff3bdbe,
- 0xf54c1913, 0xfa3a426d, 0x1bb71213, 0x6489cd9c, 0x89cdaa9f, 0xb7051f68,
- 0xca2ef35d, 0x64bb25a9, 0x7635ea2f, 0xcd1de1cc, 0xec733cb0, 0xf3f63b22,
- 0x8034ca61, 0x4cf77da3, 0x65ef4ca7, 0x48f9187f, 0x0d5cf5f1, 0x93dd95ef,
- 0x67b7e455, 0x97f87177, 0x208f2cb8, 0x99fd5d1d, 0x62b2764c, 0xcfb40160,
- 0xb1be4dda, 0xceeab7c8, 0x7d70b37d, 0x699d9ede, 0x94bff6a0, 0xe2f11398,
- 0xef869e5a, 0x1f8a4897, 0x5b7eb4f9, 0x7eac4d43, 0x1325d5be, 0x5dcb4dbf,
- 0x276bd691, 0xf509babe, 0xe02ee355, 0xce7f1c23, 0xd9ba7feb, 0x692be51d,
- 0xa61bb6ce, 0x1a8fff62, 0x8377c8bd, 0x3fe7777a, 0x5fe17d11, 0x6dca2577,
- 0xca6faf8e, 0xc69b6667, 0x2845cd27, 0x6eac973f, 0x630e722e, 0xc9f20fcf,
- 0x6f97ce4e, 0xb7ee24b9, 0xeceb2566, 0x00fc91dd, 0x87c1b17b, 0x9978b7f8,
- 0xd33c1f6f, 0x7f430dc1, 0xa159212f, 0x136484fa, 0xe4f949e1, 0xa92ffd8e,
- 0x3e071768, 0x65ccfa44, 0x27d452be, 0x9559c46a, 0xec2b7484, 0xdb93b605,
- 0x907f6081, 0x9525b5bd, 0xc63eb23d, 0xfe8933ff, 0x8a7c4e40, 0xb5ffa272,
- 0x7e224f4f, 0x9fde729b, 0x783afa88, 0x0a9323f1, 0x4977b5f3, 0x5eedbf24,
- 0x09ba433f, 0x0b66cd76, 0x3772a24b, 0x217ae5e8, 0x26375e7e, 0x751cb91b,
- 0xab9fa847, 0xb73f3852, 0xd3d118bb, 0x6409e58e, 0x8770ee97, 0x57f408ad,
- 0x29f65be5, 0xe7587568, 0x675f0b06, 0xfb5fdecb, 0xb0f3a464, 0x658d1ce4,
- 0x40c7f395, 0x0cb0fcfd, 0xb7bbbce3, 0x83e54420, 0xd432bcd3, 0xbc3ef7d9,
- 0x74f11f2e, 0xf6c5e8d8, 0x226f6f76, 0xbdddefce, 0x7e711267, 0x9a657bf5,
- 0x83f87d77, 0x512545b4, 0x2917f139, 0x768c9050, 0xc7b25b82, 0xf7778bca,
- 0xd0b6987e, 0xd253fdce, 0xe3c3e597, 0xad35dd25, 0xfabfbf18, 0xef2ebe2a,
- 0x461cd2fd, 0x159ef839, 0xfc8c59f4, 0xf5c1cf7d, 0xcd64d4db, 0x41cce8cf,
- 0x565833fd, 0xfc701ac6, 0xfcf9391f, 0x1ccea6dd, 0x96ffcbe4, 0xb6dcfdf4,
- 0x9061664e, 0x24eb0d4b, 0xff990616, 0xcc9e2fde, 0xeefff941, 0x6a7327be,
- 0xff8be063, 0xd0ce7b4e, 0x9af113c6, 0xd78da65a, 0xd5e3859d, 0xa26fcd7a,
- 0x66eb619c, 0x26f906fa, 0xdb633f9f, 0x8a3e6db3, 0xd7000ca7, 0xdf6a1d22,
- 0xf827d40d, 0xcc2eb82c, 0x4e90c612, 0x6ddc976d, 0xbe7cfec6, 0xdfda3742,
- 0xfd71f7da, 0x927a0ab7, 0xa7e44b0e, 0x24224ada, 0xfcb6bf9f, 0x13d7e8f7,
- 0x4c98d9d6, 0x72723ff2, 0x30fa2314, 0x4d4cde21, 0x55f50576, 0x5f4e1ada,
- 0xc81b1f91, 0x2427701f, 0x3f60644e, 0x763d3299, 0x17576f94, 0x9218b425,
- 0x184e7df0, 0x166767db, 0x2aa177d3, 0x34a1ff4e, 0x0c9e7146, 0xff212cd6,
- 0x97b72732, 0xe730a6b3, 0x4fee287a, 0x878c76e6, 0x05c9b779, 0xc612feb4,
- 0x68bc3425, 0x08e901fa, 0x927be5e5, 0xea48e885, 0x947ec892, 0xb1f39d0d,
- 0xeae891df, 0x8ad75c6e, 0x960d5d28, 0xb57441ff, 0x086f1b49, 0xa254055d,
- 0x78658f2b, 0xf62552ba, 0x90b3da95, 0x74affd1f, 0x424daf81, 0x6c7e44fe,
- 0x4016f1e1, 0x46b7ce19, 0xb16357f4, 0x47a8cb77, 0x63f7c6bc, 0xc13b8fe3,
- 0x25ff45ee, 0x787ced03, 0x40b35a8e, 0x3d6375a5, 0xdaefe8bd, 0x5f485b26,
- 0xc9e86bde, 0x7d263b43, 0xa401f35c, 0x25f9f48f, 0x6fc86b65, 0x5ea172cb,
- 0x714b5d40, 0xfdd3e587, 0x7e808edc, 0x9b668e91, 0xba6b3fc8, 0xdb9f9a6b,
- 0x2fc4d511, 0x15560dc1, 0xaef4e0f5, 0xf76455bc, 0x335e60af, 0xf6c771d1,
- 0x9c2f18c5, 0xaca2f76b, 0x213c62b3, 0xe7afe705, 0x93a956bb, 0xb5d0f1ec,
- 0x5d728bcc, 0xbbb6478b, 0x14ff777a, 0x09437ff5, 0xf183f7f9, 0x7a4642c9,
- 0xcbe5dda3, 0x1ebc0648, 0xa78f1bfa, 0x194297b5, 0xf5894f9e, 0xcbed9f6c,
- 0x76b94170, 0xdef09583, 0x07ebc1de, 0x49a0801c, 0xfea4a714, 0xeb859258,
- 0x81f2a1a1, 0x53699be2, 0x0db7f698, 0xb95a99cb, 0x41d92b6d, 0xe7b7ff1a,
- 0x251c7871, 0xc8b43cfe, 0xf1dcdf2f, 0x47f0027c, 0xa68dc61a, 0xb42117d2,
- 0xc92e29f7, 0x7cb614cb, 0x648000d0, 0xeb27f162, 0x5b115c67, 0xdfa3ede6,
- 0x7ac7af5b, 0xf583bfd0, 0x65e83608, 0x02b3ecad, 0xd11d6b1c, 0x60ec057a,
- 0x7c4961cb, 0x3375e4ff, 0x92fe610b, 0x93f43f18, 0xafc61f56, 0x5e374cac,
- 0x5c4a7c2c, 0xdfe846ff, 0x77ed6aae, 0x0684cf56, 0xe569960f, 0xb2f9d78f,
- 0xbea33fa0, 0xf8a9423f, 0x78da0b1e, 0x63383dcf, 0xa8ac86fd, 0xc2f6007d,
- 0x34cf2827, 0xebed613b, 0x60936d35, 0x43f39b2c, 0x4d5fea13, 0x12dd07df,
- 0xfcf121d9, 0xbe914b6a, 0x085d7d99, 0xcea575f6, 0x70a5b6be, 0xb2167afb,
- 0x2425f824, 0xfc2b83bf, 0xb05bed0c, 0xbeb0924b, 0xcff7b5ff, 0xfdf50d3e,
- 0x7272fe73, 0x6eed8a94, 0x557e8f9f, 0xf242a2f0, 0x0e5fb837, 0x9637c04b,
- 0x83576e2e, 0xb478a73e, 0x39b73f46, 0x42b8fd05, 0xed6ce30c, 0xa40aa4c7,
- 0x73a3f077, 0xf96b03be, 0x665f14a3, 0x9fd4454a, 0x65f79f8c, 0x189e3c29,
- 0x5edaae2c, 0x95effd84, 0xeb0bda18, 0x2da74f8b, 0xcdea7f24, 0xdf3145b4,
- 0x907e1c35, 0xdfb0d9f0, 0x2f1e2c38, 0x8f09914b, 0xf09e474d, 0x2f78dca1,
- 0xa84c912c, 0x68adc257, 0x1bd7d6d7, 0xe56422d0, 0x533705e1, 0x899e7d7c,
- 0x65f9868d, 0xdc177d08, 0x2a68637f, 0x93fe1bce, 0xff0ed5e0, 0x3b139262,
- 0xb4ec59e6, 0x7b5c514f, 0x99c1e13b, 0xac3c43e0, 0xc0caae2f, 0xcf669a71,
- 0x1e5c5272, 0x6fac39ec, 0x147bebba, 0x5ae0d7a7, 0x8d58d87f, 0xd8254ef6,
- 0xb806bf75, 0xabaf93b3, 0x8f5f02f6, 0xfe940f92, 0x465bca10, 0xba2fe390,
- 0x48b45d39, 0xcbb7d0fe, 0x62c78e29, 0x87b972e3, 0x7d78fdb9, 0x69da898a,
- 0x514fafef, 0x8457af08, 0xb923a67a, 0x6d7a571c, 0x99075768, 0xabf403ef,
- 0xeeaedf99, 0xf2e275a3, 0xa552bdcb, 0xddc59378, 0xac24ef7b, 0x7f2142bf,
- 0x0fbd2986, 0xadfdb8e0, 0x267aef6e, 0x77cb00f8, 0xea1c5095, 0x1e604a68,
- 0xb0a56fae, 0x5c8ffb57, 0x125b5a53, 0xf75abfb5, 0x01abc239, 0xf50ead0f,
- 0x93946afe, 0x2724289f, 0x33d22599, 0xf869fa1d, 0xfbf5326b, 0x0ea05b07,
- 0x86b569fb, 0x420e915b, 0x73b5321d, 0x6374b1cf, 0xe23eef3f, 0xd33b40e8,
- 0x48636ee8, 0x50bee0c7, 0xf6e2c49c, 0xd3ca1533, 0x09140b43, 0x5d9c45f5,
- 0x49e31d33, 0x29b8b7e4, 0xf82558de, 0xc1503463, 0x42b10b59, 0x5129e7cb,
- 0x4ff9e73b, 0x52f82ae7, 0x160c7fb3, 0x319e1f1e, 0xf8e1812f, 0x49c89eec,
- 0xdd9bc603, 0xe1ed0c3d, 0xc6894ec6, 0xdc7e2c69, 0xd2cbfe84, 0x41dfce4e,
- 0xfe006fe1, 0x58aed072, 0x76136291, 0x77a70b66, 0x147273d6, 0xbe31f9e2,
- 0x3b418c9e, 0xb2dfac47, 0xfd69da8a, 0xbc9c4499, 0x4093c451, 0xdafd5213,
- 0x58cecd14, 0xc26d9e2d, 0x6ee3e0ce, 0x327c7a91, 0xd254b3e2, 0xe7b573c5,
- 0x9277216e, 0x2166444e, 0xbe8046ff, 0x5db4ae30, 0x6ffb7d9a, 0x2bdb7e61,
- 0x14d179c6, 0xc93900f3, 0x481ef865, 0x7e5ef011, 0x485983f8, 0x119aac37,
- 0x9e1d36bf, 0xfd8a3726, 0xd217b404, 0x581dcd6d, 0x316b7e9f, 0xef8c67e9,
- 0x5ec0bee3, 0x3b0cd781, 0x5679eb8f, 0x9f70f287, 0xff84e92d, 0xf8e2dff6,
- 0x1f681213, 0xc6d61d23, 0x75cf4c91, 0xb0f2d718, 0x3f51a7d2, 0x32d46a7b,
- 0x4fdb4784, 0xd9a8fdc2, 0xa9c72425, 0x7c95ec9c, 0xabf9e07b, 0x01e11714,
- 0x846abcfc, 0xed87df17, 0xf4adfdd1, 0x38a5cde9, 0xe11fee2e, 0x5ba33fb3,
- 0xeb3538a1, 0xfc8fbddd, 0xf113b37e, 0xb9f87355, 0xd6ff5157, 0xed275858,
- 0x2dd9c5f7, 0xf1bc4e3f, 0x03a39449, 0xbeeecee7, 0xcefae11b, 0xd6806f21,
- 0x5c8f6f47, 0xcfb7157d, 0x5367dbdf, 0x23dc8ed1, 0x8fd836e4, 0x5fa127c4,
- 0xde327f72, 0x45397c8e, 0x960c9fef, 0x2476eeff, 0xf0042f87, 0xef918bed,
- 0x0dffe141, 0x444f9fd4, 0x20faf5fd, 0x2bffa03c, 0xed5076a3, 0x2bed1b5e,
- 0x7117fa0f, 0x8ff3c8f6, 0x0f4842d8, 0x14ad3be7, 0xfec45477, 0xe44739cc,
- 0x8b52444e, 0x284de4eb, 0xbdb7836f, 0xf0032bf7, 0xf7c1d29f, 0xec49143b,
- 0x3320bc87, 0x73e37fbe, 0x294feec6, 0x5f1e59ae, 0x3e47ca09, 0x6e2265ef,
- 0x48b92cb4, 0x7c32fbe5, 0x62596a5f, 0x53da1177, 0xb43d094f, 0xabef812c,
- 0xdd4cb80c, 0xac7baeb8, 0xb429f381, 0x67bfc2ff, 0xb1ab31bf, 0x611d2ffb,
- 0x299dd76e, 0x609b7436, 0x1f681d9e, 0xe06dbae0, 0xfb8330fb, 0x1dcdc7d5,
- 0x51938266, 0xc455a079, 0x95fdb5eb, 0x571e3ce3, 0xce51f627, 0x10fc59cc,
- 0x48b5a96e, 0x9fe8d5cd, 0x8d3f585d, 0xde77d7e2, 0x759e9b3f, 0xf771f4eb,
- 0xde99acc5, 0x5a94fb6b, 0x7996bbbc, 0x8e5edc4d, 0x600d11c6, 0x94eba8bf,
- 0x7997d42a, 0xe51ab9cc, 0xd5821abf, 0x16cf0c9a, 0x2ed1a278, 0x73b42419,
- 0x02775694, 0x16daefae, 0x50a9e903, 0xed87c18b, 0xb8e73c34, 0xd2a91c79,
- 0xb01ae3cd, 0x471c6154, 0x4518b67b, 0xb7f45fdc, 0xf1ba198a, 0x73f89069,
- 0x1ea953ad, 0xfd6b5f4e, 0x2d9b18b5, 0x648ba718, 0x7dae281b, 0x479be4c1,
- 0x22e4e371, 0xb67c0216, 0x55d79a38, 0x9de27af3, 0x9f88d60b, 0xb854afea,
- 0x64d4c921, 0x376e9f94, 0xe3c6538f, 0xbe9b516d, 0xd21fbf1c, 0xeb97d610,
- 0x464c6058, 0x883fdf01, 0x7376ef7d, 0x7d6175f9, 0xd7b7c09e, 0x9b567284,
- 0x8e2caaff, 0x7f364337, 0xcd5767e6, 0x77c83a43, 0x203f2899, 0xabe3c5df,
- 0x3f821330, 0x44b74aff, 0x6f0711f4, 0x486d1a0b, 0xdf7cad5f, 0x1fc2abee,
- 0xee55f70f, 0x7c1fa134, 0xab67dc1e, 0xdf689a73, 0x24e352f4, 0x72f5bab7,
- 0xf7fcb068, 0x9fb967f7, 0x3c8b2ad4, 0xa1c9270e, 0xcb9f275a, 0x48fbc919,
- 0x83b7be37, 0x68f3809d, 0x6ed0cb95, 0x9da37e99, 0xdc74d1e6, 0xc6e0714a,
- 0xa839bd15, 0x7aaa9bc7, 0x203f308b, 0xad08bf1e, 0x682fc9a2, 0xff06eb57,
- 0xd884ed03, 0xc547e476, 0x7efa07ef, 0x3f454ee4, 0xe781cce7, 0xb01d5f50,
- 0x7f82be92, 0x38c66d3d, 0xb23c91cb, 0x023ac6a3, 0x305db02b, 0xa3f77ba1,
- 0x70b76879, 0xcbb1a9bb, 0x617681dc, 0x3ecc4b6d, 0x06dffe1b, 0x5b1bbefd,
- 0x77f14c97, 0x5f7faed6, 0xbbee33bf, 0x6d70fb21, 0x4c5bceb4, 0xefc8b181,
- 0x9f6877a0, 0x81835cfc, 0x64ebb7f6, 0xb79462ef, 0x7b7aace7, 0xaf839cfc,
- 0x9addcfd7, 0xc22de13d, 0x0f2c1e75, 0x116f6759, 0x819d73ae, 0x69fb6205,
- 0xf58675c4, 0xf9d6265d, 0x8b9313dc, 0x3fdf9d70, 0xd708b930, 0xcdb18b79,
- 0xa8f37c87, 0x1b90f033, 0xe99bedfa, 0xf70a7b27, 0x2e8f913d, 0xc40f1e95,
- 0xff81e3d1, 0xefa47a3d, 0xc787d246, 0xebd0e106, 0xcd49b743, 0x6b507942,
- 0x5ea17f31, 0xe361bfc4, 0xc5331678, 0xfa7f8e3b, 0x5047c6e1, 0x64c9740e,
- 0x1dfd688f, 0x68050257, 0xd57f1d0f, 0x23490de3, 0xed18bff7, 0x07da0aad,
- 0x455c610c, 0x7b3403f3, 0x9f1e5e32, 0xc779f312, 0x7b42abed, 0x8dc6ebfc,
- 0x4b3bc5eb, 0xe76e43f8, 0x3cbc95ee, 0x7149dc6e, 0x0b63a6e4, 0x7e27189c,
- 0xc6e3cc27, 0x52944f4d, 0xfc21b8dc, 0x2de6374c, 0x89c92eb1, 0xdec347fe,
- 0xdb171337, 0xf82e7ea3, 0x5f236fb5, 0x3f7e8b31, 0x99f09de9, 0xc13b3ac4,
- 0x71ea157d, 0x42623b9b, 0x7f026fba, 0x9ad4f30f, 0xec49c894, 0x28cdc9b7,
- 0xb0fca31f, 0xf2d3ffde, 0x4df876a2, 0x74777724, 0xd7946149, 0x5e40a669,
- 0x9635ea16, 0x8b6b3ce5, 0x6ec7d9f2, 0x77f71b9f, 0xbedbfba3, 0xe4c771ff,
- 0x4f6ef51b, 0x35edfa22, 0xe5139f32, 0x908776d9, 0xb7c90a67, 0xc2ba778f,
- 0xb788ff3c, 0xedcc38ff, 0xef2d0684, 0x0add6148, 0xb9e2d7ac, 0xbd70d7be,
- 0xc777de51, 0xb2d8fbc9, 0x14bd2fb6, 0xf6e3d1f7, 0x0ddb63bf, 0xecc7e7ee,
- 0x61faeb7f, 0xb96aa5cd, 0x5f5bff7e, 0x327ee21f, 0xb2f2c3f0, 0xeb6afd28,
- 0x936fd1a0, 0xeb074388, 0xf483df4f, 0x392c3c1b, 0xe65bbed1, 0x0cbbf4e5,
- 0xc4f32dfc, 0x3acefca1, 0x238979f5, 0xaa697ff1, 0xcb07ff9e, 0xeaf8a0ff,
- 0x9c9aa915, 0xcdaf7ce4, 0x0fdb8b5f, 0xe24bb3ce, 0xaf37197c, 0x3e353f78,
- 0x99f9aede, 0x6f0f2a97, 0xe387841c, 0x0ffcb063, 0xc6b78796, 0xfda465e1,
- 0x0f2caf8c, 0x35f797ff, 0x35b63a1e, 0xb40efd11, 0x594fd1e3, 0xf3c8cfb7,
- 0xb1fd0023, 0x64b3c5fb, 0x9fef8fbb, 0x7ebd5aca, 0x259d5e1f, 0x5f39e1f6,
- 0x4c84f33f, 0xf628d6eb, 0x398f1b89, 0xdeb4d8bc, 0x69f684be, 0x6f4ff7e3,
- 0xe1660763, 0xa3efc552, 0x2e7e432e, 0xd4fdf2f8, 0xbcc1d4d6, 0x5bcc3c85,
- 0xcbd2aca8, 0x1fec67f9, 0xd66204a6, 0x1c04aabd, 0xdbe86182, 0x725884a2,
- 0xa9adfbcc, 0x467eaedc, 0x4c78f7e4, 0xa5e61d6c, 0x7cd8726c, 0x0c78cfe8,
- 0x47e8ff3c, 0x28edfe29, 0xc0aa2d17, 0x32ef91eb, 0x21e5e003, 0x95c92763,
- 0x8bdda350, 0xdf8b5072, 0x2c7ffd68, 0x592ec1f6, 0xfbd1c7ff, 0x7a65ff81,
- 0x53cfc78f, 0x755f78da, 0xe01b6edf, 0x8c17c746, 0xdc45f8e8, 0x4a1bca5f,
- 0x33f523bf, 0x9cbf1d12, 0x95217fea, 0x226fa2e4, 0xa25c2be5, 0x4795b19c,
- 0x889c60ce, 0x18ab341d, 0x0938c4d7, 0x190dc7e9, 0x5bd26f22, 0x80f29b39,
- 0xbf9895bd, 0xf3fe06f5, 0xc8ed91f2, 0xe1f5c1be, 0x88df6476, 0xecf5f3eb,
- 0xfe9dbbc8, 0x7d6748b3, 0x6f947cd3, 0xf001d6be, 0x0bf87fa3, 0xd3b4779e,
- 0xa773e9ca, 0x2d92e9c4, 0x78a4b94f, 0x7471a7cb, 0x91ffe9f5, 0x8da4b51c,
- 0xbdfe5764, 0x125fe8e5, 0x723a7e31, 0xa79e213f, 0x7843d55b, 0xd8931c8b,
- 0x76b8989e, 0xe0cff310, 0xaf010cfb, 0xe123fef6, 0xf34c2c37, 0xfbc1a665,
- 0x58b35ff7, 0x3e981258, 0x362e5ce5, 0xafb4edf9, 0xf3c9d4d0, 0x30569a5f,
- 0x184de392, 0x78c12d37, 0x98b66ce2, 0x428189e2, 0xfb5b93cc, 0x27243dba,
- 0x0e7dbc61, 0xffaf3b43, 0xdebe5e35, 0xfec62815, 0x697a2b83, 0xce7da31f,
- 0x5587947b, 0xf787f9f9, 0xbc139754, 0x9b704f14, 0x6e25e7f5, 0x0efbe34c,
- 0xa69fd3da, 0xe28fbbad, 0xf3d7eff9, 0xdba0e2bc, 0x84b8c4e7, 0xa9b70f16,
- 0xd0afb43d, 0x6f1b9074, 0x0f9f3295, 0xd11669fb, 0x69c1d353, 0x653718a5,
- 0xb452d69d, 0x6cff2b77, 0xfdefbf27, 0x4f2932bb, 0xe04a68e2, 0x51d7846a,
- 0xed16be1e, 0x07185cd3, 0x0ff7deed, 0x708a5b5c, 0x0b6ff26b, 0xfda1cdc6,
- 0x1e3e8716, 0xdf3c2cce, 0x51d1e1bb, 0x1abcdc5a, 0xf045b3f1, 0x55b7b321,
- 0xef861ece, 0x974f7e35, 0xfa7fd40d, 0x3fb42df7, 0x2d83c9ae, 0x14b01646,
- 0x24c8e544, 0x74183f91, 0xaec5fc8b, 0x453f3cd9, 0xa9e2ed94, 0xf71df3e1,
- 0xaf3849cc, 0x37ca6949, 0x4a72c7db, 0xac7dd8f6, 0xea0148bf, 0xd0c4f317,
- 0xa515874f, 0x22ed8b78, 0x9df3a3b7, 0xc723a226, 0xa7f7c63a, 0x9ed08e80,
- 0x33d222bf, 0x59e6093d, 0x057dded8, 0x45f8f7e2, 0x3293ad03, 0x97da45fb,
- 0x78f89249, 0x5b7a1b05, 0xc61c60c7, 0xb895caf9, 0xb39b6a94, 0x36f8b70a,
- 0xa477fcb9, 0x1737df11, 0xff5578e3, 0x9379e461, 0x5f146cc7, 0x4659cf68,
- 0xaffd9379, 0x3ee7759b, 0xb6219fe2, 0xf324f29a, 0xf691ff0f, 0x25071c07,
- 0xe7b4de1d, 0xbe76697d, 0x99ea156f, 0x5735b945, 0x2abe49b8, 0x421cfec7,
- 0x5569437b, 0x16b0f250, 0x4560cfa3, 0x518ab5f9, 0xbb747f3c, 0x95eb80d3,
- 0x0662f22b, 0x6275ff8e, 0x6d15fc80, 0xf3cc203f, 0xf7bd8c9a, 0xaca61fa0,
- 0x842abdea, 0x65d071eb, 0xa9b8c268, 0xf144d231, 0x8a366396, 0x2e1ee6af,
- 0x282dfd58, 0xd273aee7, 0xd1c0d7fe, 0x6f94b9a5, 0x3d1cf30e, 0x4cef3ccc,
- 0xcd4879e3, 0x63945e82, 0x33ea0336, 0xe2f33365, 0x3e2d79e8, 0x7ef802e7,
- 0x3a2153b4, 0x0816985f, 0x9e0e7ae3, 0xc09e596f, 0x3c28b7cf, 0xfe58e23e,
- 0xdcf12ffa, 0xb7116ec8, 0xfc7c713d, 0xb5f38a1c, 0xfde2122a, 0x51e78b82,
- 0x3fa6963e, 0xf7c51087, 0xcd47ca09, 0xae47f63f, 0xf60da0bf, 0x7d3918af,
- 0x0eeead28, 0x3bf6278c, 0x7b7f9402, 0x4cb74b65, 0xbece63fb, 0x18d5aa07,
- 0xd71b66bf, 0xb9fb4d27, 0xc7ef1e1f, 0xf91e997c, 0xe13ca0ed, 0xfcb0647a,
- 0x7a4fb20f, 0x57c7f4e2, 0xde984ff6, 0x53b78baf, 0x21b8fde2, 0x7f5c7776,
- 0x5a2bd923, 0x745549be, 0x3b376e1c, 0xa4287b34, 0xb2a9c7cb, 0x166bf38b,
- 0x260fff7d, 0x22ff793b, 0x8d6d273f, 0x7d414aba, 0xe28c2ff5, 0x90fe5a73,
- 0xaa142f96, 0x213d79e2, 0xb7ce8583, 0xe51b5879, 0xdd628d09, 0xb4714492,
- 0xa7df865e, 0x7c10be63, 0xf2d2ffff, 0xcc5dffa9, 0x39264ebb, 0xbf084aa9,
- 0x524cf315, 0xf6f0ee10, 0x77de38c5, 0x159e34ec, 0xc8524cf3, 0xcdfe209f,
- 0xd4fcf3f4, 0x7f7cf5e9, 0x30f41321, 0x390b3396, 0x99e75a5d, 0xcb555f28,
- 0x4cf2d11f, 0x0954bc34, 0x598e677c, 0x5072879c, 0x92d947cb, 0xfb44ade0,
- 0x7b0255a7, 0x90d3e71a, 0x784bf220, 0xf90dedbf, 0xaff7a461, 0x8f127f9b,
- 0x650f2d67, 0x3d206272, 0x5e7a22bd, 0xd11fcb4e, 0x3d6626e8, 0xc71dae09,
- 0x555f3db8, 0x0c79a26f, 0x71475c34, 0x030681c9, 0xd55fbd43, 0x1874e665,
- 0x798ede37, 0xfd8dd626, 0xe52b612a, 0xf87a0bd7, 0xd6167b32, 0xbee318b7,
- 0x2fee5627, 0x7fde03e8, 0x3d276576, 0xa752ac07, 0x33ce893c, 0x950947ce,
- 0x5eb8e9e3, 0x6af31cb9, 0x90123922, 0x0fed84d0, 0x353950d7, 0xa79606f2,
- 0x51ae5e7a, 0x8c0c4f40, 0xa096ec8e, 0x2ddb7fbd, 0x99b48cbc, 0x7d3dfa09,
- 0xe4a84d76, 0x363be81b, 0x2aa36f24, 0x37e2953d, 0xbc50f4f7, 0x72bbe848,
- 0x0cd91f2e, 0xabc79873, 0x9d9b8a54, 0x3b23c8ca, 0x7f9c5ec0, 0xb3eb07b0,
- 0x836714cc, 0x53ffa27a, 0x7af1a7a3, 0xcb3faf95, 0x0dfcf072, 0xf9421bd6,
- 0x1a6f2a76, 0x911babc5, 0xb29ec03f, 0x7073023b, 0x3d49cf5d, 0x9c3f2277,
- 0x25cff99a, 0x0ee7e748, 0xe510b4fd, 0xb02635cf, 0x379187d3, 0xde5c1969,
- 0xebed180c, 0x65e7e824, 0xd8fbe07b, 0xf9b6abcf, 0x7cd530b3, 0x1334ca5e,
- 0xa1601d1e, 0xff28c85f, 0xb9fac552, 0xd1fb72e6, 0x612fc335, 0x2b1ae81e,
- 0xa0352387, 0x099ec8f8, 0x03be95cc, 0x09235ff3, 0x49a986fb, 0x6aa887e4,
- 0xcb21fa12, 0x5946b9c4, 0xf82cb7f0, 0x7b2b0ffb, 0xd830150a, 0x2cdcef2e,
- 0xdedfe70f, 0x686fe718, 0x5ce94dcf, 0xd591cf4e, 0x6e1f4809, 0xd7df91e3,
- 0x26c93ac0, 0xbdf1186f, 0xfb41db26, 0x2a3b4fb7, 0xafd0bd3d, 0xe52ffb94,
- 0x26bd5798, 0x71ca5ffb, 0xf64e4d9f, 0xe531fc7a, 0xf52ae94d, 0x21db0337,
- 0xe5cd6cfe, 0xbbfd7f18, 0xfd0497f5, 0xfefd7c95, 0x7331fb06, 0x225996b8,
- 0xddf00a39, 0x03c0d6cd, 0x16177eb8, 0xb3fb49bc, 0x7a9e6677, 0x4e2bf303,
- 0x88cf9919, 0x9c432472, 0x8ebd033f, 0x75cc9ee3, 0xce53f3f1, 0xb113d36d,
- 0xf2e9c05c, 0x7da6165a, 0xfcb99af5, 0xacf5e3bc, 0xda17a5a7, 0xaa31e35d,
- 0x71fc31bd, 0x5f2faaad, 0xd72fac5f, 0x7f8e3c88, 0xdfdfeaf2, 0xd20a22c0,
- 0x7ca7b7e9, 0xfdf62636, 0x2fdf5653, 0x929e8f90, 0xe867de78, 0xfb24e672,
- 0xd0852dd9, 0x64ff199e, 0xc9ff38a6, 0x55ff13f3, 0x4e4f5ff8, 0xb69f5461,
- 0x82c7b2df, 0x2d9e22f5, 0x1ef1fa8b, 0x264dc966, 0x30fa49b9, 0x473c8922,
- 0xb0f1ed37, 0x793bb743, 0x9ada175c, 0x0b439fa0, 0x9a4bc254, 0x42aec0dd,
- 0x10b72bfe, 0xbe7469ff, 0x0af40ac6, 0x651ca978, 0x5dfa4049, 0xc36ef463,
- 0xb304e4be, 0x5a6ffa8a, 0x96fa85a2, 0xfe90a67f, 0x33356558, 0xdc4f9427,
- 0x68654097, 0x44e07247, 0x718c2985, 0xee4235ee, 0x481bf7cb, 0xcc2a567f,
- 0xd01b798f, 0x9fdf1bae, 0x3b50b0c8, 0x7c5cd298, 0xf1a8ca7f, 0xf28534d5,
- 0x1aec0538, 0xf488c13f, 0x57e0ab7e, 0xb3cdf059, 0xfb8d0700, 0x7141dc82,
- 0x05bd5530, 0x632de7cb, 0x70511ce8, 0x629b9cf0, 0x9d8ac1c0, 0xf8bbdf82,
- 0x3f8d3339, 0xd2017935, 0x28b710ad, 0x6d0e3125, 0x3ea1a7af, 0x6b5f6466,
- 0x07edaafc, 0x76b45b66, 0xcffb0f8a, 0x3cd9df10, 0xdcb84279, 0x47fca668,
- 0x7aea5ef1, 0x1fa413ee, 0xaf77af8d, 0x3d7c40bd, 0x3fc5df14, 0x0e75f2a6,
- 0x98f7c727, 0x391fe42c, 0xea164c61, 0xaf2e359f, 0x17298fea, 0x4bcff903,
- 0x3b407c46, 0x7d58df28, 0x918950aa, 0xe70f36f3, 0x4be76857, 0xb09f7c01,
- 0x67c859aa, 0xc8db8cc3, 0x7dfdb5c7, 0xb8c0f5c7, 0x0384eed0, 0x7b7685c6,
- 0x436ee6ad, 0x4fe370e2, 0x2fbc7151, 0x6eb1971b, 0x04eb9e22, 0x420e815e,
- 0xe13a3718, 0x5e3d1030, 0x4f7bf227, 0x58f1f2a4, 0xa65f3eb1, 0x40d0e810,
- 0xfcfa58f9, 0x9da46b98, 0xb6efa82d, 0x20f7135a, 0xe8273ddd, 0x67eda4e2,
- 0x3cef6885, 0x59e8bf37, 0x92b3eb94, 0x9120b556, 0x893ac75c, 0x757935ef,
- 0x4acde321, 0x1adc832c, 0xbff581e7, 0x7cd4ff33, 0xd759fcec, 0x5fd442d6,
- 0x7bc60f20, 0xafc28752, 0x37069fd1, 0xfbd221d2, 0xc1c61d20, 0xbb11d1af,
- 0x0b1293a1, 0x88bd8177, 0x047ecd4f, 0x91e7884f, 0xf9d1d9ab, 0xb2cf1101,
- 0x3479f334, 0x6bee0884, 0x9e500f5c, 0x0199e5d9, 0x69d6079f, 0x720fa4de,
- 0x59ec6c14, 0x76e30630, 0xffb4ef00, 0xede3784b, 0xa7cb2fe5, 0xb58f891e,
- 0xfb39a5f1, 0x383a9f29, 0xd5f94ed7, 0x693e45d3, 0x7140deb0, 0xc8abf074,
- 0x96626f1e, 0xa9ddca30, 0xf2d5bec2, 0x3c4a8ffc, 0xc27a193e, 0xb18beeac,
- 0x59e68793, 0x1dc794ab, 0xb1f3c15a, 0x46e0ed07, 0x9060ec95, 0x0573badb,
- 0x765ca5ed, 0xd2aedfb7, 0x24a79979, 0x80b43ede, 0x7db3dc51, 0xe45fa8b6,
- 0x58f76b0c, 0x7cd16948, 0x460ef6f7, 0xc8eedff4, 0x594cfaa7, 0x16fdcb9c,
- 0x79ed37d7, 0xbf6c4fdc, 0xb7ea88b9, 0x52c78424, 0x87d88f5e, 0xf5fb81df,
- 0x7f1fb05f, 0xe3f3479f, 0xb0751c78, 0xa38a77fc, 0xb40cea3e, 0x2a2dfd21,
- 0x8118e5f1, 0x3c4cea5e, 0xbaf40a9e, 0x7a6187b3, 0xfa21735f, 0xe6b2d73b,
- 0x44050c57, 0x2e905baf, 0x7a078de7, 0xebd1d02d, 0x97054f56, 0x469708db,
- 0x5a7483af, 0x17379f1c, 0x76fb6308, 0x9b9fe757, 0x32e83fd0, 0x30de797b,
- 0x978c83cf, 0x2cf0310f, 0x6e3c3854, 0xf6782659, 0xc1c4ff13, 0x137c2973,
- 0x8ce9a74b, 0xfc48c7f3, 0x90b0ae93, 0x3fca2ca3, 0x4f03594f, 0x7c83b8e2,
- 0x0bf70f74, 0xdb2dc087, 0xba6e9e89, 0x0517ef99, 0xe3ef5c6d, 0x8c0651be,
- 0x7f8c5b3f, 0x867fab53, 0x96cddb0b, 0xe1ba1e38, 0x1cff007f, 0xabbb3f51,
- 0xe6c6f291, 0x8e9e30cc, 0x793473b5, 0xcd53eda9, 0x746fed13, 0x1e6236ce,
- 0xfd1adcf7, 0x5bbcd0fe, 0x4dd4fef8, 0xccfdf573, 0xa03e1b63, 0x6cd646fc,
- 0xbbcdfc44, 0x8aff5f45, 0x695f7067, 0x3d2bee0c, 0x0329e22b, 0x47c827c0,
- 0xb25d4dbf, 0xf3a076f3, 0x292f3f31, 0xcccf38c3, 0x9bbd86b4, 0x8ee8fca1,
- 0x6dfe5471, 0x747ff7da, 0x1777eb0a, 0x41867951, 0x90c7e7e2, 0x8acf810f,
- 0x2ebe6f2b, 0x89f5112f, 0x4676f7e8, 0x81093def, 0xced0d9f6, 0xf29f3133,
- 0xf888673e, 0x5e22c0c0, 0x0724fd7f, 0x55bded4f, 0x8ceaf8a5, 0xe47cc884,
- 0xff4b1783, 0x90f30cb3, 0x728be467, 0xb0e353d9, 0xc1f4acfc, 0xfd67d47c,
- 0xd705768d, 0xc79329a1, 0x4b17c7a5, 0xe22763dd, 0x7fd12c79, 0x4d579f23,
- 0x91322fd9, 0xf154664f, 0xa77bc67e, 0x3b6016b5, 0xf72a79c3, 0x11125a67,
- 0x19bf1aff, 0xd9a41f84, 0x27217e8d, 0xd9bdf49e, 0xfafd0292, 0xa717922d,
- 0x26f29fe8, 0x9d9817c5, 0xfbf3a79f, 0x6b8c14f2, 0x3cf1f74f, 0xd8ab6dd5,
- 0xb6f3b42a, 0xd653e95d, 0x0b74fd40, 0x7a04f5a3, 0xbd206537, 0x2720fe4f,
- 0xaecc8911, 0x9e8d77a7, 0x3e746b66, 0xc0cf4f43, 0xfefc76a7, 0x8eb5e4cb,
- 0x7a51ad9e, 0x09ce291e, 0xa0646570, 0x5e96f85c, 0x138e0d8f, 0xe3f18fc7,
- 0xf027248e, 0x46de562f, 0xbe24ebe1, 0xbfecc2cb, 0x36cbe402, 0xe1c72f8d,
- 0x1e864cfc, 0x2b943f3a, 0x01d1c779, 0x0b5e29dc, 0xfe38b9e9, 0xc6cbe0d4,
- 0x50d972d8, 0xd14ff0b8, 0xe7fe50ec, 0x9643f8c6, 0x7cef87a8, 0x170a392c,
- 0xf1153f8c, 0xf0e1eec0, 0xb99a92ec, 0x867e115c, 0xd268b716, 0x3f587be6,
- 0x7e04cadf, 0x7183df8e, 0x285bda26, 0xf708371d, 0x3683ac25, 0xdfd0a09f,
- 0x877e2d73, 0x1df6e609, 0xcfd11d57, 0xba834177, 0x811d5d70, 0x279c236f,
- 0xe863a10c, 0x3e622d8f, 0xfa065fda, 0x445467f0, 0x37834bd7, 0x234d4f1e,
- 0xf9f8d1c8, 0xba27e3c4, 0xf8193d6e, 0x0de7ced4, 0xe712f7ce, 0xb89f6f19,
- 0x5f78fa4d, 0x25cb88b2, 0xc570e347, 0x12c35f58, 0xf38714bc, 0xd5bfe44a,
- 0x7281bd80, 0x519aa6b9, 0x6ed9243c, 0x669c38a0, 0x27c48c77, 0x48c55f57,
- 0x632cd54e, 0x9f205ce2, 0xa63d3c5f, 0x931fdeb3, 0xb7516bff, 0xaf7e442f,
- 0xf0f2ebb7, 0x6e3cec6b, 0x1b935ebf, 0xf502b7ac, 0x887960fc, 0x40adef9e,
- 0xff7f13b9, 0x1e45cd57, 0x28be4e2f, 0xfbc6b3d1, 0xf9ea0566, 0x0adeeae4,
- 0x240f5f94, 0x75c5eef9, 0xe3c0c37d, 0xdcf8f1ea, 0xe2d0619a, 0xa74497c5,
- 0x78347cf1, 0xd811dace, 0xf168e381, 0x0f5273a4, 0x38a64f8f, 0x3c81ff45,
- 0x4ba067a4, 0x20669a23, 0x1cff3f27, 0x37fc519d, 0xf726ede0, 0x7b9c9aed,
- 0x18dce498, 0x5cfdd7a1, 0xbe9cf89e, 0x4e1c19bd, 0x021dcbc2, 0x9e85332f,
- 0x2653bf3d, 0xaf86643f, 0xa16e2b78, 0xb2379f04, 0x8fb1f130, 0x8f76a3f4,
- 0xa83079d7, 0x63fdb1ba, 0x4bb7d20e, 0xfda3a85e, 0x0cdb31a5, 0x97d18d4c,
- 0xba09c363, 0xefc641fb, 0x2795d64f, 0xdaea6674, 0xaf9c3a4f, 0x1eed2fab,
- 0xecbfaba7, 0xb95d32f9, 0xaeaa67a2, 0xab57e4fd, 0x7bcbe574, 0x7fb5d3af,
- 0xe03df504, 0xccef5bf5, 0xefffbdd1, 0xc79eb31d, 0x232bdcfd, 0x7f7dd3df,
- 0x5819c446, 0x0c53d7c8, 0xd1a85ff3, 0xdd5ac5ef, 0x74d660f7, 0x0728954b,
- 0x0dc2dff8, 0x1a7d4f3c, 0xbfb62c60, 0x7b7a6d45, 0x508b2662, 0x58535f7e,
- 0xcc3376f2, 0x37d7d353, 0xbc20ee1c, 0x013dd97e, 0x0c0bdc63, 0x197d0f48,
- 0x858c6760, 0x14b0a47f, 0x891bb3cc, 0xfd6cbfff, 0xd7e1588b, 0x47b37f5a,
- 0x5556febf, 0x62b6febf, 0xbc3bfafd, 0x9a4ff5fa, 0x977f5fa2, 0x29febf4f,
- 0x4ff5fad5, 0x3fd7ebf5, 0xfd7e9e7d, 0xf5fa0233, 0x5faf551f, 0xfd66ecf7,
- 0xd72ee77a, 0xe85e6baf, 0x36fdfd36, 0xd1a07471, 0x0b4f2693, 0x7711ddd6,
- 0x19818e1f, 0xa342e862, 0x7afe85b3, 0xdd1a5fca, 0x78dd13f6, 0x8631f4f1,
- 0x6fcbbc89, 0x99851f48, 0x7f981740, 0x3f92cc99, 0x1bef3d27, 0xd43a999d,
- 0x56e4d0be, 0xf58f3eac, 0x6792478f, 0xf094f443, 0x53d44797, 0xa35b2fe8,
- 0x7448f2fe, 0xfd031afa, 0xa06f834a, 0x4ecdd838, 0x0489c70e, 0x887fb76e,
- 0x3b439755, 0xe0053368, 0x03e70d7d, 0x3096bfe3, 0xdf1de29e, 0x1c469d63,
- 0x43d616f7, 0x422cf9cf, 0xea7300cf, 0x642c7dce, 0x7f88937e, 0x8159975c,
- 0x4ade9171, 0x1617a394, 0xf6837a9c, 0xb94c5eb3, 0x4e327ba4, 0x68c97ee3,
- 0xb90acec6, 0x26fb87d1, 0x8ab7ee50, 0xa98fa078, 0x9e7c18ee, 0xdacbf115,
- 0x57e912e9, 0x7e502726, 0x2577ed57, 0xffb54fd2, 0x99759fc3, 0xff1eae3c,
- 0xc35cb35c, 0x0bb09b6b, 0x5f707db8, 0xbbf54aa6, 0xb276aa60, 0x944ebd43,
- 0xdf1fd0ff, 0x44d878c7, 0xc2c7b9fe, 0xa29504e1, 0xe3a64c5c, 0xb8eeb474,
- 0xcbee78fe, 0x4df0e163, 0x22e59850, 0x02cf1fbc, 0x95de1764, 0xdffd4f99,
- 0xe38880ab, 0xfec38ffd, 0x15684a3d, 0xc07fd1c5, 0x5bf471f4, 0xa38a259a,
- 0x85e000ff, 0xf5e9c7a7, 0xcad61ea0, 0x33bc05ab, 0x4fbc1db0, 0x184b34f7,
- 0xfdbafaff, 0x78c3f60d, 0x7887f83f, 0x59a1e2d7, 0x58668740, 0x603fbdd7,
- 0x8f8bcf14, 0x41928e8b, 0x93fe63a2, 0xf7ab9f91, 0x9fb8db28, 0xd4ebd27a,
- 0xd1987dc5, 0xbf20e785, 0xbcc2decc, 0xe731b3e5, 0x87bd600c, 0xe9747fbd,
- 0xbf2fbe28, 0x31676566, 0x4fd88dd1, 0x7ee57bbc, 0x978acb2a, 0x3ef10af2,
- 0xf7cc572a, 0xc7d43726, 0x8762bbf0, 0x90e463ef, 0xcba7eed1, 0xd959ee57,
- 0x4678fb43, 0xdad66f71, 0x819c3bac, 0x2fc77898, 0x631d8533, 0x1a673109,
- 0xfc37a613, 0xe19d33bd, 0xe54ecafa, 0xcb5fac6c, 0x886c979e, 0xcf4146b7,
- 0xd7ba092f, 0x607b36e0, 0x5eb818bc, 0xe8def412, 0x3ce131ec, 0xe8b5825e,
- 0xd2b4b8c1, 0xd3fba6e3, 0x1c93716e, 0x83ac41ba, 0x8dd4a0f9, 0x0acc4ae7,
- 0x5ec5f99e, 0x832fda7a, 0x64bcf726, 0x76efb864, 0x2435c54f, 0xcdc94d4f,
- 0x8fa06ede, 0xc8b4be1f, 0xaf061819, 0x51ecd3da, 0xc5cac42e, 0x5f8532e7,
- 0xc64d993e, 0x1e061975, 0x743f93d2, 0x587e6ff2, 0x7e58f3c1, 0xf94603f8,
- 0xfc396ced, 0x94f14655, 0xf724bcca, 0x2f422c5c, 0x0604ac37, 0xe8f6031c,
- 0x980b0b4a, 0x66b21f41, 0x98d2d3b2, 0x4369e88f, 0x3ade8be9, 0xf65ecef8,
- 0xcff462bb, 0xaff8abef, 0x2a3b2c66, 0xf2c7af5f, 0x758fb1fa, 0x1d9a0e62,
- 0xde537161, 0xe0af1850, 0xaff7184c, 0x3b6357fb, 0x1f798f7c, 0xe01ef0d5,
- 0x574277b9, 0x26dbdb04, 0xeb077d1e, 0x96ddec13, 0xe12ef802, 0x0055e616,
- 0xf2dea95f, 0x74f00569, 0xb02f4395, 0xbdf136d4, 0x37ef0a6d, 0xdd26bf7e,
- 0x43df87be, 0xfb130573, 0x045efca2, 0xd5233f6d, 0x0aada7be, 0xbea156e5,
- 0x8f8141fe, 0xcfe3fb14, 0x303d63e7, 0xad1668dc, 0xbbd4407f, 0x54f78fec,
- 0xdd165cf1, 0xff459bf7, 0x97037649, 0xfb132a57, 0x937ebcb6, 0xf56ab7a8,
- 0x65f6261e, 0xa8ab7d79, 0xde79db37, 0xeeb7b012, 0xfc62b5fb, 0x2c0c5bb4,
- 0xeecf4310, 0x102c09b9, 0x35c91f43, 0xd1b2bac9, 0x3b25cfce, 0xbeea6467,
- 0x5bbdfad3, 0x45789b8c, 0x4b3beebe, 0xfb7d38e1, 0xcfa4c9b9, 0x367810ee,
- 0xeae99565, 0xacfef3b5, 0xf273b45d, 0xaa7b8a76, 0xaaf3dfae, 0xe072849a,
- 0xdd1ae5ec, 0xb7482d7a, 0xd3f23877, 0xbc21bf71, 0xa3353a12, 0xa788b13c,
- 0x683d3c53, 0xa553c05c, 0x7b889e72, 0x853959ae, 0x6e807bca, 0x95a1feb1,
- 0x82ef2a5e, 0x9fcf0ab2, 0xbc2a3f43, 0x60fd0edf, 0x83f42b79, 0x1fa107cf,
- 0xe3003e7c, 0xf866fd61, 0xa09bcb0e, 0xb7df2c3f, 0x7be547d2, 0xb9535657,
- 0xca9fa575, 0xa3ce576b, 0x032bdde7, 0xb2b35cf4, 0x8e67ea9e, 0x6bedfae2,
- 0xb39405e7, 0x9980bcf8, 0xe7a22aa3, 0x80bcb43a, 0xfef0d30e, 0xb8a3cddc,
- 0xfe65cc1c, 0xfe9c2da7, 0xecc89ee9, 0xa34f9d0d, 0xe7e29bdf, 0xa1b191eb,
- 0xd55dea99, 0x3bed1c7c, 0xacb10ee6, 0x158c7e4a, 0xea4bf5db, 0x1997ca6a,
- 0xcceae3cb, 0x256a6213, 0xfe974ebf, 0x13e90894, 0x5f2f58a5, 0xdfc3ccf3,
- 0xe3101d53, 0x3ecd85c8, 0x8a658e9c, 0xc4f31bbf, 0x9d00deed, 0x08bdcfef,
- 0x9b1f839d, 0xa62af174, 0xaee2e982, 0xc9d1dbd1, 0x7674ca33, 0x89b17caa,
- 0xbeb259da, 0x72676ba7, 0xd5daead7, 0xc7bbcd2e, 0xc518f883, 0xb0de61e7,
- 0xb8c0658a, 0xd337da8b, 0xbac5ebb8, 0xbdf97cc1, 0x3e2407d6, 0x3dbf615f,
- 0xb5f314ea, 0x3ab9206c, 0x458bc5c6, 0xca032149, 0x9d7ff7c3, 0xc8fafc44,
- 0x478a0643, 0x0361658e, 0x5078d7ae, 0x813f58d3, 0x127952f5, 0x9728574a,
- 0xf2c65532, 0x7e422c65, 0xab6fd82e, 0xe49b9d71, 0x285643c0, 0x3c0ecb9f,
- 0xba91f3ca, 0x8914af49, 0xecd228f5, 0x7c4a6dd8, 0x28dd6f7c, 0xe7f58ff2,
- 0x9bf7e295, 0xd32a3957, 0x1fe8fed1, 0xe6cc7f21, 0x42dcf339, 0xe32dbfc0,
- 0xef6a7a4d, 0xc30d55ef, 0x787de39e, 0xf2cdf494, 0xfbfac33e, 0x1fde81b8,
- 0x2b9c79c6, 0x5e6603f9, 0x08c2a6b1, 0x8c6b09f9, 0x93509c9a, 0xecb63d98,
- 0xf331624d, 0xabe56478, 0xec090a05, 0x764de100, 0xe7cc746a, 0xea527f2b,
- 0x22a63cc4, 0x7fb93791, 0x8ce14665, 0x7befd1d1, 0xb3141d04, 0xc5ff924e,
- 0xfc97836e, 0xe7539f48, 0xdb0b5a77, 0x445e787c, 0x98bcc71e, 0xb5963363,
- 0xf96b39d1, 0x23c9326f, 0x4cb5c4f9, 0xc123bb05, 0x7b216619, 0xfc265fb4,
- 0xf9091fd7, 0x067d91f9, 0x68e72fc1, 0xc8f9e1f7, 0xe9c8f9de, 0xd49e6275,
- 0xfa46ed47, 0xafad3e48, 0x5f7a762f, 0x2e9d000d, 0x22f3683e, 0x6dc50978,
- 0xbca03f74, 0x1259625b, 0x20f3c1c1, 0x6cbdb993, 0x42c956dc, 0x1b579eb0,
- 0xbf098702, 0x8321eabd, 0x5da1fca6, 0xee898a63, 0x78831f67, 0x6e5e23b1,
- 0x43819c2e, 0x1e131617, 0xbf798917, 0x26b1e625, 0x80bfc35b, 0x787cf987,
- 0x76e2e09f, 0xcfd6efcd, 0xaa92def3, 0x4b7d636f, 0xa0f94c8f, 0x973cf8f1,
- 0x44c4a7f8, 0xf1daf058, 0x70046e3c, 0xa0fc85be, 0x8829dc20, 0xb69fbe5f,
- 0xe30a69c4, 0xa97ee039, 0x30f29ab3, 0x7f281827, 0xdf2e9e35, 0xf368f617,
- 0x6d3d2728, 0xcf44b39e, 0x73df72d1, 0x7fc8530b, 0xaed67ae0, 0x9f16bcf0,
- 0xf78d8d4f, 0x28e2d7ad, 0x413f5f22, 0xdf783bc0, 0x479e38d8, 0xdb3d6768,
- 0x24664f30, 0x9590c6bf, 0xc0d7e717, 0x54fd20d2, 0x651f2858, 0xa4e796bd,
- 0x8f29529e, 0xe7989e1b, 0xba741164, 0xb9efc1d6, 0x3a37e6d0, 0xd1d1cb8b,
- 0x06ff9c59, 0x86de5a2c, 0x2634a6af, 0xabb6bfff, 0x6d75fc8e, 0xc4406a3f,
- 0xf4120649, 0x820d47fb, 0x6d9e0614, 0x7dc04aab, 0x1fbe3690, 0x3d75d0d5,
- 0xd8f2efbf, 0x285f7403, 0x3d22a9f4, 0x75f689d4, 0xfafef4eb, 0xe201fda2,
- 0x4078f8d7, 0x980fffbc, 0x1e5da133, 0x67e7ffef, 0xcbdf7f09, 0xe9bf714a,
- 0x938286cc, 0x29b70009, 0xd1b9d18f, 0x74e3f251, 0xa5583bef, 0x26cf786d,
- 0xcaf7e12b, 0x0fffafc4, 0x97844db2, 0xdf5f12fd, 0xf13b68d0, 0x2e0afec1,
- 0x7d3ff607, 0x28d186fe, 0x7d2572cf, 0x91ae713e, 0x818b77df, 0xc9df787e,
- 0xf970f558, 0x0cb23362, 0x5fcf4cdf, 0x8d7b97a1, 0xda4f7b87, 0xd37f9254,
- 0x4f3d70b3, 0x84b125fe, 0xf74228f8, 0x83b9a3e6, 0x78dc21e3, 0xe180e36e,
- 0xf4b1f983, 0x452cddf0, 0x66f86dc0, 0x1e8678f2, 0xaf2573ae, 0xe1c75da4,
- 0xf50b29ba, 0xb4e9f763, 0x0d7c7cd8, 0xc35503ae, 0xf86e2b9f, 0x029a78a6,
- 0x8b0e54f0, 0xc22ffaa7, 0xf0d301d3, 0xc04cfcf0, 0xf2cf6ff3, 0xd6862efb,
- 0x6dfb437f, 0x1efe1c67, 0xc509b9eb, 0x33fbc036, 0x2fa79fc2, 0x04c2f68d,
- 0x05cb3afe, 0xf90b967d, 0x895f25e3, 0x4c9f5f05, 0x0a9d64f9, 0x72c1a94b,
- 0x2aef42e5, 0x4a7f7a35, 0xfca010d0, 0x79baf67c, 0x4477f958, 0x990385c8,
- 0x3878b0d2, 0xf4f9e628, 0xa8b9b58b, 0xd57dee67, 0xb42e50cc, 0x5efdfb08,
- 0xef05a767, 0x88f0d59f, 0x067832e5, 0x5ec5914d, 0x647f972c, 0x8cc3ed51,
- 0x6de3e067, 0x6d1be38a, 0xabf9ed3c, 0x0fae62ac, 0xcc6567a5, 0xc574dfdb,
- 0xd42f742b, 0x648572a6, 0x7fc6d7ef, 0xce5e9ebb, 0x7692bf75, 0x5f97a703,
- 0x4934bd21, 0x1b7e256f, 0xf22941ca, 0xcbee0972, 0xff34029b, 0x43b1e020,
- 0xeda78a1a, 0xf9b45e82, 0xe0d7f369, 0x90b95c76, 0x9af1c1d6, 0x41c69499,
- 0x17d35ed1, 0xe1ff4249, 0x5c5f48bc, 0x0f73f0a1, 0xfbad0a15, 0xe95329a6,
- 0xb101ca5c, 0xdcb91e2f, 0xf83dec34, 0xf76f027d, 0x0f63fc5e, 0x2ea1b5fa,
- 0xc00bdd23, 0x8dcf5e94, 0x4bf12f78, 0x0c33dd0a, 0xf78d54f4, 0xe2fd3d1c,
- 0xf3b444f9, 0xf2e2ccde, 0x2e2ccdec, 0xca2e070f, 0xe45e74d5, 0x729c8fc5,
- 0xce9ffd0c, 0x4d3ec592, 0x039e0f4f, 0xf3c658d9, 0x1ec2eddf, 0x57d8bfb0,
- 0xa7dbf08f, 0xc52cc4fc, 0xb21fdbd0, 0x46d704cc, 0x0bcd2453, 0xc98f05fd,
- 0x82ec9bac, 0x6dafba5e, 0x939b9cf0, 0xfca9a1e3, 0x8ef68659, 0xe3df8bbd,
- 0xe54b3a76, 0x3ee01672, 0xc613ef04, 0xc3ace47e, 0x2f1872fa, 0xc3bdfa3f,
- 0xa133d7c9, 0xb2a3df82, 0x383f8ae9, 0x24b89ef1, 0xc7fdd189, 0xea36c83f,
- 0x57ada1ce, 0x2cec1cb9, 0x3b41e9ef, 0x2854e42e, 0xfbb3a72f, 0xfbda0b0e,
- 0xf2f85f1a, 0x8ad7bcf8, 0x4ed77cfb, 0x39e30e29, 0xd78e8d14, 0x202e0764,
- 0xbe046edf, 0xafec9c78, 0xc274ff1e, 0xf314b38f, 0x1eb0275c, 0x9586afba,
- 0x87c89c9b, 0x8e8306c5, 0xe6c9aedf, 0x413da374, 0xf3dd93fd, 0x9abb4163,
- 0x2c3b97de, 0x7db5cf0c, 0x1276717c, 0xb672a7da, 0x9d79ef66, 0xed8fc788,
- 0x7c4ec973, 0x0df6b7fb, 0xda0779b1, 0x73f02df3, 0xcb44c7bb, 0x59febc8b,
- 0x0b317ed8, 0xe97683dc, 0x775976e2, 0xc16dffde, 0xda2e8be7, 0x9d8c7758,
- 0xf7ca68bf, 0xa2d2bce8, 0xfef4898b, 0xf49f916d, 0x2a4bc8b6, 0x8af0f314,
- 0xdfd915e7, 0xc6f7fed0, 0xff5dcbc9, 0x972d48f9, 0xd0d98597, 0x6bd4a36f,
- 0xe36a7f42, 0xb9d0bfd4, 0x7fc0b791, 0xd17f36ef, 0x7758533c, 0xed83b8cc,
- 0x77595a2e, 0xa8baec4a, 0xbe747704, 0x6b7faa76, 0xf04be7a5, 0xc7874a38,
- 0x3a05ff68, 0xbfed0e3c, 0x5adfea88, 0xfd25fc59, 0xffa11f8f, 0xd1fc1d3c,
- 0x7de90b7e, 0x47da89ff, 0x272fc06d, 0x78ef57ba, 0x8eebf30a, 0x7cfee99b,
- 0x8ab3b876, 0x92fdafce, 0x3bc6b9d1, 0x06f27f8f, 0xb9ddcde6, 0x31c5e4c7,
- 0xf9918c06, 0x43f461de, 0xf0867321, 0x79ed291e, 0xcd017643, 0x45bdfe27,
- 0x0f313b09, 0x38ac52ce, 0x58593f51, 0xf135784f, 0x93e48583, 0xfad79716,
- 0x2672871d, 0xf76a3e46, 0xf62bbc85, 0x0b60ff8d, 0xc0aecc2c, 0x8157f732,
- 0x9c623773, 0xd961e1ad, 0x7421efc9, 0xc5a23f91, 0xf3f415bb, 0xe3d4300a,
- 0xe3fe7867, 0x4b03723f, 0x0e7e6e91, 0xdfe300e2, 0x01bd84f2, 0xff0a4f8a,
- 0x8f6b3eef, 0xf7231bc7, 0xdf2b6456, 0x8b6fdf4c, 0x7f1537d3, 0xeb9ba47a,
- 0x8f38159b, 0x57e7b946, 0x8e7879b5, 0x1bdc57a9, 0x5bdd92a5, 0xee927e5b,
- 0xfcd5ab97, 0xfbf175f9, 0xb42ed9ec, 0x7cf8b583, 0xa13fe622, 0xf3c8dfbe,
- 0xbc6cebef, 0x14fbf75c, 0x4789cf3a, 0xef104a45, 0xdf97b29d, 0xfc24e82b,
- 0x0f30179e, 0x20e63658, 0x9e04077e, 0x433d77cf, 0x5f9e18f7, 0xa0e89a37,
- 0xa53f37ee, 0x640ec97b, 0x63acfc8a, 0x7543d20e, 0xde256f66, 0x93207793,
- 0x4a9d9bdb, 0x8c596277, 0xab36b9fd, 0xfbebe48a, 0xd01b46eb, 0xbaf0d73e,
- 0x8d85c853, 0x89503c5a, 0x6dfde254, 0xbf7797ef, 0xa0f07a4c, 0xc6e77e95,
- 0x4a93e870, 0xa3714fba, 0xafa5ee99, 0xcb76343a, 0x2c6fa83c, 0xa8be5032,
- 0xe09590e1, 0xdf9eb739, 0xa2df84ef, 0x343c6ebe, 0xa80f7e8a, 0xbca116ce,
- 0x6f04c6ae, 0xd497ee11, 0xdd16fa1d, 0xbee67f27, 0x372839b1, 0x39aaa74f,
- 0x7dee7f74, 0xf7987480, 0xf86363e9, 0x74c9d6fb, 0xd1b1d25e, 0xae2e1816,
- 0xf893e9a1, 0x640ea3fb, 0x461ff696, 0x78b58cfc, 0x917940f7, 0xb8b03f76,
- 0xf9eeac0f, 0xf3151cc8, 0x557f85ac, 0x33ef7f67, 0xfdadf7ba, 0x3d385bcd,
- 0xcd027df3, 0xb71f8b3f, 0x039de84e, 0xfc7cc8a6, 0x35baa67d, 0x9e26ff02,
- 0x28675687, 0xd327dfa5, 0xee31bff0, 0x0457d57e, 0x99e7b5de, 0xb7ba1517,
- 0x1c81ec0e, 0x733a57dc, 0x76f44cdc, 0x3a78e366, 0x578dad2f, 0x0271b807,
- 0x564e9e9f, 0xfefae227, 0xbaafc859, 0xd4efdc35, 0x3619d7de, 0x477ae357,
- 0x6f94c98e, 0x248ce033, 0xd6887ee2, 0xce0f2b4e, 0xdfa64ba7, 0xf9903a19,
- 0xd03bad34, 0x32ba4315, 0xfa41c6fc, 0xfe1bf836, 0x97ef457b, 0xf50d90b3,
- 0xf266abf4, 0x331c4ed3, 0xf03c1d93, 0x3b773f1a, 0x7b2f1ee4, 0xadef0724,
- 0x1466fe0c, 0xec81b5c9, 0x376e6ec8, 0xb8dee95b, 0xc9815381, 0x432cff62,
- 0x81978bdc, 0x6385daf6, 0xd7b46ed6, 0x20fb49e0, 0x43d7b621, 0xe8db8fef,
- 0xd2780ffe, 0x1d260939, 0x9cefd0f4, 0x7df136b0, 0x677f7d0f, 0xca0c604e,
- 0xa00b3be9, 0xdf7e3b7f, 0xe42eed47, 0x19612607, 0x78c532fe, 0x766fd499,
- 0x4bde9720, 0xeff8791f, 0xfa89b47b, 0x9a0faa1e, 0x1e699303, 0x8eb0767f,
- 0x4df9e661, 0x2f7b7fef, 0x9be4853b, 0x99e03706, 0xbc78bfec, 0xe20c7278,
- 0x3e385df7, 0x7072e9e2, 0x3e04bf3d, 0x5f90a78c, 0x71d7c5d2, 0x971358fd,
- 0xc9e3ad27, 0x431ba5ce, 0x569af262, 0xe89b7b1d, 0xdbe8c072, 0x72297a8a,
- 0xbdf8c8ca, 0x6019606a, 0x6f0a619c, 0xfce36757, 0x9ef1c1a4, 0x686e6fc8,
- 0xef4f79e5, 0x9cede2fd, 0x273c7605, 0x9ceeb6fb, 0x83f716ac, 0xae31124e,
- 0x89aaf762, 0xdedc25b5, 0xfe2e0996, 0x8d1b4dfb, 0x554efd2a, 0x14b1bee8,
- 0x5263384f, 0x8ebdd10f, 0x901827eb, 0x5cbd5a9e, 0xf8da84f6, 0x9afbb4bc,
- 0xe2977bb4, 0x9cddf2f1, 0x38bbfe02, 0xde2b702c, 0xa99a7dd9, 0x8db36269,
- 0xc7ab9fee, 0xebca017f, 0x2b3e0d0b, 0xbd25bfcf, 0x379ef430, 0x8efc97d3,
- 0xf96dffd5, 0xe68cb907, 0x250dead9, 0xc77d5ea2, 0x583efdc9, 0xbbf4953d,
- 0x7749e7cc, 0xbea066e8, 0x939adff6, 0x0724f54a, 0x7d7891df, 0xf2699d3c,
- 0x903e086e, 0xfc5fb06e, 0x3dbefa0e, 0x48d5c787, 0x79bde058, 0x7ba2642c,
- 0x0abe8461, 0xcf018a4a, 0xd4b9f775, 0xbecba444, 0x55e482d6, 0x52e0a798,
- 0xe862cad3, 0xa32cf824, 0x9e2accf3, 0xbf8c984f, 0x889be273, 0xc903bcf1,
- 0x3c4238fa, 0xeb4f8f3c, 0xff5b1f9d, 0x772e1cd3, 0x1fb8735b, 0x261cebf8,
- 0x3c78feec, 0x22583a72, 0x1bd5a0e8, 0xcafc8ab8, 0xb64b76b8, 0x88fa0925,
- 0xd4f6df7b, 0xcabe533f, 0x85bdfd4e, 0xde3d6235, 0x9214de79, 0x8133e126,
- 0x37eb8df2, 0xff577973, 0x5dd14d42, 0xfce74cbc, 0x4ddc75a7, 0x70b30fbf,
- 0xc622cccf, 0x8bad17e5, 0x730b9f46, 0xdf68457c, 0x4ecbb645, 0x6dfa93e4,
- 0xaad3c132, 0xc3b659b4, 0x8cdbb3fb, 0x0bd5f764, 0x0566ce78, 0x14dd6912,
- 0xef0098a6, 0x22409567, 0xc5dbb5d9, 0xcdc4e0ef, 0xa2bdda03, 0x1f830d94,
- 0xc2675f0b, 0x7430c14f, 0xeb40ca70, 0x898130b4, 0xe89347df, 0xecd9c79c,
- 0xee58adc0, 0xee9e7f03, 0xa06b6e9f, 0xf1e2557b, 0x2012d67d, 0xe6225d7a,
- 0x7e33e1a3, 0x039f0d1c, 0x9fb44f88, 0xfa41df9e, 0x8ca0f82f, 0xee9ecc14,
- 0xecfc90fa, 0xbe66c769, 0xbf7c2df1, 0x1518ec19, 0xcbfe6df5, 0x077d47df,
- 0x98ed0a72, 0x690563da, 0xa36f4e2c, 0xd2fb593f, 0x8c4344dc, 0x976d6cbe,
- 0xb5a59f69, 0x22e24e70, 0x06fe7f6a, 0xaad3afa4, 0xa62cad37, 0x9a392bdd,
- 0xaf5fa93f, 0x4d7fcdba, 0x37ea71c4, 0xda5e6918, 0x4c000cba, 0x6cdb8724,
- 0x81ffa461, 0xabf508ac, 0x7d20d3ad, 0xf4683ae3, 0xcd3eed04, 0x78718a71,
- 0x2f2fb6bc, 0x861de950, 0x003f164e, 0xdb7f62e3, 0xe69f741c, 0xe1ab8ea5,
- 0x05bd7063, 0xd719535f, 0xc51e7771, 0x14a70dc7, 0xdd3f064a, 0xf20e4d76,
- 0x07d81d71, 0x93a88718, 0xbdd06f22, 0x74ccc7a6, 0xe6dd6fef, 0x78e2b7a5,
- 0x0d99af75, 0xfc77df58, 0x5704899a, 0x9e02badc, 0xf7a38672, 0x8e48bc81,
- 0x607f0637, 0x6b7f1057, 0x9b8189f3, 0x8b3f00e0, 0xc819c5ee, 0x918cf583,
- 0xe1cd7f03, 0xef681af1, 0xf37d1134, 0xe706997b, 0xaf9b8ceb, 0xafbe6e33,
- 0xe66fa230, 0x167cd00d, 0xe0366ebe, 0x5ff785fb, 0xb771845f, 0x69d3f5be,
- 0xbec97d5e, 0x7d5fc889, 0x30ffd039, 0xfde172f2, 0x2f92cf30, 0x959b6798,
- 0x79c46bd6, 0xb3764726, 0x27a7982f, 0xb7cf3f57, 0x7e913514, 0xcc88e34f,
- 0xcc128e30, 0x16fc6ff6, 0x97efd32f, 0x1e9c8d05, 0x746d9b82, 0x8bbfaa2e,
- 0xc9af8fdf, 0x12ef1801, 0xf440c1e9, 0x6ea557d0, 0x75f48299, 0xfdc4ec9f,
- 0x97f5be8a, 0x2fbf8cbd, 0x7651b7d7, 0x57d0dda2, 0xf207f1c5, 0x5f78f480,
- 0x2a06ff8e, 0xefd2371f, 0xfb699da4, 0x3ee89feb, 0xfa466382, 0x3c81e23d,
- 0x5879c6ff, 0xae517806, 0xe26e5e01, 0xe691ab76, 0xc1eebadf, 0xda1f5875,
- 0x6fce8936, 0x7ad7d50c, 0x906fd73c, 0x14c87c75, 0xde0bc695, 0x17ee8a3f,
- 0x120cf0d1, 0x23fd08b6, 0x9e581f0d, 0x978a213b, 0x8f7f38a0, 0x8fbf0276,
- 0xc433c84b, 0x13d73e4f, 0xe5058e78, 0x19a79e18, 0xcbc55f49, 0x7bbd789f,
- 0x4fb6ae63, 0x0dc797a9, 0x79afbf71, 0x69795c5b, 0x1658dc9c, 0x5718df57,
- 0x86f9fa0f, 0xcfd2e2e1, 0xa2cf8e0c, 0x1a21927e, 0x4fb81d1f, 0x56b4bf22,
- 0x07e84d51, 0xeb8d3e3d, 0x59853ae7, 0xe4be22ae, 0x156a73e7, 0xc32e62d6,
- 0xac535ef7, 0xb5fd04bf, 0x9ca19398, 0xb410e5c0, 0x94c536ab, 0xc1ab7935,
- 0xa3c04ab3, 0x9c76bf3d, 0x7dc466a0, 0x15b9558c, 0xca31f743, 0xbf5ffce4,
- 0x11d67e88, 0xe0ccfc99, 0xb0ff5c0b, 0xf2dc3f4f, 0x3bef1b98, 0x323ca02e,
- 0x78f1fe6d, 0x61fc381c, 0xe4defd22, 0x5f3a26f3, 0x5295db5e, 0x72587e45,
- 0x6fbc5864, 0x44fae5cd, 0xe95fafeb, 0x6b1d9c4d, 0xc4deb347, 0xadf7dfd8,
- 0x4ae1fc3d, 0x7f016bf4, 0x8e463921, 0x5a96399f, 0xdd65fe85, 0xf0ab32ef,
- 0x5cd1efbc, 0x3ea00e2d, 0xe6f901bc, 0x13e29988, 0x33cc2ffd, 0x2ffdf7e0,
- 0x9de78bd4, 0xff609f74, 0x7072675b, 0xfe8344fc, 0xcf7f89be, 0x9d54f6e5,
- 0x57ddcde1, 0x9a3ffca2, 0x2626b79e, 0x28675d0e, 0x31f8bf23, 0xc23e6463,
- 0x3aff760d, 0xfad503cc, 0x12ab9a39, 0xde47fd1c, 0xe1f28dde, 0x32ecc6cc,
- 0x47fd2b14, 0xdc1f90c6, 0x4565daff, 0xff6b5f78, 0x945e197d, 0xd5198f0b,
- 0xe2dfb93b, 0x8bc9eef0, 0xe0e387f6, 0x91ff63fe, 0x3f1895c9, 0xc38d7fe8,
- 0x278a650b, 0xe610bb40, 0x26fd6a5f, 0x984dd41a, 0x677ece8f, 0x8ee2bf24,
- 0xf1d20acf, 0xd344957e, 0xa050f7f0, 0xc3cfa11f, 0xd6f34d5e, 0xfde37df2,
- 0x37ff2d0c, 0xeed30fde, 0x17f78f8b, 0x3ddb59eb, 0xef1c9798, 0x6e618237,
- 0xdf89a509, 0x4ebfa733, 0xf74bf7d2, 0xdfd66e7f, 0xf6121d9f, 0x71e48580,
- 0x7ae3f02d, 0x79853f8a, 0x3c9d6fdc, 0xc5ec7eec, 0x6fa76e5c, 0x7e6dfdb5,
- 0x9ebacc6f, 0x03c53036, 0x626d3d78, 0x70d94f16, 0x9c85e3fe, 0xc37b925a,
- 0xb1758dfb, 0xa1b1d6f7, 0xaae9e47e, 0x9df9e530, 0xefd32f5e, 0xf5c3c459,
- 0xf8c8fd55, 0xebdfb5ef, 0xc4ed04f8, 0x00938c54, 0xe45fc9a4, 0xd5e1eb3f,
- 0xbf1569f0, 0x01fff2a3, 0x949113dd, 0x00008000, 0x00088b1f, 0x00000000,
- 0x7db5ff00, 0xc5547c0b, 0xbddcf8d5, 0xc3764cfb, 0x083c8426, 0x813bcd84,
- 0x44902c24, 0x8f2ed4ac, 0x0310f0c4, 0x5850822a, 0x89de4020, 0xc5b0fd60,
- 0x40802166, 0x151a86d1, 0x260dda2b, 0x22ec1208, 0x760d1201, 0x4a888941,
- 0xadb45503, 0x202a25f2, 0xd4109204, 0xeb6bfe8f, 0x73339cff, 0xd0820fb3,
- 0xcfe8fbf6, 0x99dee64e, 0x7de733b9, 0xfd999cce, 0xf7f87bfe, 0x17bec613,
- 0x62a2d9a5, 0xc963106c, 0x2d9990ff, 0x43b2b194, 0x891ae71a, 0xafdac0b1,
- 0xf50b999f, 0x398d16ee, 0xf958c2c6, 0x6726d921, 0x659ac630, 0x3e0c4267,
- 0x08a822ff, 0x8f3797de, 0x33cccb31, 0x9cb3795e, 0xac654ce7, 0xd86ae9ab,
- 0x671a54e2, 0xfd88c5ba, 0xa1dab69f, 0xc2acc834, 0x57b4f465, 0x4c8b58ca,
- 0x69de28f3, 0x9932fea8, 0xe1efbfd1, 0xb05752bf, 0x29bcbd4f, 0xbd4bfab2,
- 0x7f8c5ea7, 0x367fc244, 0x8c5967a6, 0xec57f095, 0x6187ea72, 0x5dde6053,
- 0x1912e7b5, 0xb2a8d12c, 0xa1325ac7, 0x169df89e, 0x67b58ceb, 0x7e6899e5,
- 0x67981641, 0x20dbf3b7, 0xb7d2f306, 0xbf9c36c8, 0x2c32fcff, 0xff32c65a,
- 0xc2e5f983, 0xf33cc2fc, 0x5864f983, 0x59e67906, 0xb2d1e966, 0x3e879858,
- 0xc48d9d28, 0xa369b616, 0xfc22fda0, 0x6a2fde13, 0x058d3c59, 0x79a93631,
- 0xe0031ac9, 0xb25abba1, 0x7e79e0ea, 0xf00dc00b, 0x764dbf90, 0x932f005a,
- 0x311d5692, 0xd3f17d40, 0xe6ba1ef0, 0xcf4ee3c8, 0x9ecbf686, 0xb87ea990,
- 0x1ad391f6, 0x0d36ebc4, 0x031e21d3, 0xef8bb682, 0xa15f9c31, 0xcb615f98,
- 0x7c120bd4, 0xd921d96f, 0xf5fec6ea, 0x5f3e2b26, 0x79f341bc, 0x96fad7bb,
- 0xde301fe0, 0xd392ad92, 0xa92de30d, 0x95df7df6, 0x38b2d0e9, 0xefd5bfe8,
- 0x99faed79, 0x54b14247, 0x51d60933, 0x8f7df4e8, 0xf986deff, 0x77bf8b94,
- 0x8c1e6c26, 0x3032e9f8, 0x61f806d6, 0x8630f6ea, 0x1a3dbba5, 0x7cd5d8f1,
- 0x58f11a36, 0x24fffafe, 0xa7f07eb2, 0x14c5ac94, 0xe0102e7a, 0xf7d89169,
- 0xabfba42a, 0x69faf3d3, 0xe7087a3f, 0xc71a9d8b, 0x3fbc2b60, 0x746dfb52,
- 0xb349d23b, 0x1fb9987d, 0x9f1bedfa, 0x08aa0c39, 0x8606dd2c, 0x3ccb8665,
- 0x4de4f905, 0xd213798d, 0x33f5f6c7, 0xf0dd43b7, 0x00660686, 0xf12304f5,
- 0x12c7f20b, 0x3e1571af, 0xd9b129d9, 0x99426654, 0x6892f38a, 0x930fdf5e,
- 0x1e771e88, 0xd09e9dee, 0x69867cdf, 0x21e8dda8, 0x347dda8c, 0xd2356f2c,
- 0x11ca805b, 0x3660f884, 0xe014259b, 0xaafa092b, 0xe121595a, 0x4d5608f3,
- 0xa2e610e5, 0xecc605f2, 0xaccf6c46, 0x63338466, 0x7e118343, 0x5eb4f3c4,
- 0xe6e90abb, 0x9b770267, 0x8e0f4e24, 0x87ace660, 0x3d5ae5bf, 0xa6300793,
- 0xd841ed65, 0xf33694c9, 0xbde0c3d7, 0x255943e6, 0x43c8bd01, 0xcd5a7c15,
- 0x8c6fdf88, 0xc6f00df7, 0x17f7e1df, 0xa578e2e5, 0x83a665fb, 0x6a372ef1,
- 0xed88db98, 0x9da05f81, 0xb5affde6, 0x5a972831, 0xeb009624, 0x3e3a8728,
- 0xb6a71f2f, 0x52e0bd39, 0x78f0e16f, 0xf04892da, 0x8edb52e8, 0x33fa434d,
- 0x2c3ad22f, 0x2e7e4e38, 0x11347183, 0xaf38b48b, 0xd04fefc3, 0x82de20c7,
- 0xeb37c4d5, 0xb6ef945b, 0x64fc7199, 0x78f329d5, 0xa993df78, 0xf1e1db66,
- 0xcdc6a3f9, 0xf7ca47c8, 0x3f1c2cba, 0x12812b67, 0x97cf3c92, 0x8397dc64,
- 0xfb3297fd, 0xa5a3a47a, 0x7b733235, 0x0d79fdd1, 0x6b92f7c7, 0xc63dcc81,
- 0x4cc45fab, 0x6b92d75a, 0xbcfcf441, 0x6f3bb781, 0x9ef174e2, 0xc7c5d385,
- 0x885fbbe2, 0xaf2dbffa, 0xeaf2beac, 0xef1f0bf2, 0xd6e5c458, 0xa547487b,
- 0x44ce7b52, 0x88fac4f8, 0xf5ca2d5e, 0xe66695b3, 0x3ad0fdd6, 0xd7b73207,
- 0x5ddafb77, 0x40f73033, 0x6859b86f, 0x1af59efe, 0xcad9fde9, 0x31c09b88,
- 0x9e8e07ca, 0xe07ce3f1, 0x89f8fd78, 0x656cfef4, 0x1fc64df2, 0x63f18371,
- 0x19efe67c, 0xaf9e9e37, 0x20b1554d, 0x9fb5aba0, 0x6cc49ce8, 0x74a7ae7a,
- 0xbad6ef82, 0xfd2de927, 0x4d83aff0, 0xe163628a, 0x8b9ca37d, 0xbcd97c74,
- 0xae7c8cc8, 0x74b90609, 0xd8d7f41b, 0x7180ef72, 0x0321c175, 0x5aaf7e91,
- 0xdf5d68e2, 0x1d105706, 0xb4743b7f, 0x8fc188ec, 0x7d61e454, 0x997c90ed,
- 0x59fab378, 0x7ae5f392, 0x21d37dfe, 0x9fe44a60, 0xaf42f5db, 0x18bcc9ff,
- 0xd43553be, 0xf4c98fae, 0xf994c7cc, 0xb33c4336, 0x9430fb26, 0x819b8f03,
- 0x801f896f, 0x5abd61af, 0x3bbbfec9, 0x9fd81f80, 0x8a1eac75, 0x24f60d6f,
- 0x471f17b3, 0x09fd70c4, 0x728510dc, 0xa86ac1d1, 0x4aba6f2c, 0xff00b670,
- 0xf794bae2, 0xe087ace5, 0xc2cd7c8e, 0x16d52691, 0x4f64df7a, 0xccf34bca,
- 0x78eecfa3, 0x0150e8c7, 0xfd0ee9ff, 0xd9e10823, 0x6e99eead, 0x22d5d285,
- 0x77c37a07, 0x8fe70c64, 0x4ebf4309, 0x65e7876f, 0xd3e40fd8, 0x27166f23,
- 0xd329fca1, 0xbce3a4f5, 0xf7f9bc8f, 0xdff79474, 0x861e2a1e, 0x7b4277cf,
- 0x3db413b2, 0xf1af5665, 0xa1d999e2, 0x9329eb1a, 0xef88e263, 0x3cef9ffc,
- 0xe7183554, 0x886200d1, 0x5677c085, 0xe5f717be, 0xdb072440, 0x18672853,
- 0x0b7a97c8, 0xcaf74dda, 0x3eca5728, 0xea04db02, 0xbf5ccd19, 0x4e650c67,
- 0x67da0c55, 0x7c46cd1f, 0xcd6a6595, 0xc04a582a, 0x1ae736a8, 0xa9901f78,
- 0x1d1ea337, 0x5f7f843e, 0x0e3cfa8b, 0x440f67fb, 0xe414fdbc, 0x0f247fec,
- 0x2becfcea, 0x06b2a9f7, 0xdca95ef8, 0x00e51d3e, 0x31e985c8, 0x07d97e30,
- 0xb5489f5f, 0x309e8b60, 0xd0b74fc4, 0xe3127f3f, 0x37931a3c, 0xfbaae913,
- 0xe3d777fe, 0xbb2437a3, 0x88e3d71d, 0x5f515bd4, 0xec6708b0, 0xcebc2f4c,
- 0xba09518d, 0xba01ee01, 0xb6e62e1d, 0x796bb067, 0x6725e930, 0xb943d208,
- 0x1e51d98a, 0xd40069b2, 0xf32e91db, 0xf5a666d2, 0xd0d79fa7, 0x6c62cb78,
- 0x4abe708b, 0xcd668ffb, 0xc3f7b34d, 0x04a94887, 0x21ebad4f, 0xa94f679c,
- 0xf01dbad1, 0x82be21f0, 0xd2cd2f7e, 0x93b065b9, 0x0dc635ba, 0x27d1d012,
- 0x075bf381, 0x184ffac1, 0xceb815ed, 0x5e4c0fd9, 0xc8e9758f, 0xa472cb40,
- 0x59ed85cb, 0x06399788, 0xbef8c3fb, 0x161f6f44, 0x3cbc4b06, 0x00349ed4,
- 0x40de6a95, 0x97966f0e, 0xfcefd796, 0x753c7cf9, 0x54b7fa46, 0x31b7a5c0,
- 0x49d9006e, 0x67480daf, 0x152e9f30, 0xd0fd402b, 0x15fbe625, 0x25e623e8,
- 0x279c0ba7, 0x7da10bb5, 0xed49dd61, 0x97f5af22, 0xeae08582, 0x3a7a2ec7,
- 0x1745db86, 0xdbfefdf7, 0x9d50c05f, 0x44481cdf, 0xba58b5bb, 0x76faeb44,
- 0x62f9c9d7, 0xbeb8d57d, 0xa27b7a47, 0x12aeb0b5, 0x972d61d7, 0xea7d621f,
- 0x5a1fc49e, 0x2daa975f, 0x80e2e887, 0xf18fae64, 0x3c6d2bf4, 0xf4051399,
- 0x3c17505e, 0x9674e65a, 0xe8567488, 0xd1788f84, 0x028e32b1, 0xde42e59f,
- 0xf014aef5, 0xb676e009, 0xfbe51f02, 0x33e0fc67, 0x8d93dd5f, 0x2abf98f3,
- 0xa9e5c558, 0x7947e893, 0xefa560bf, 0xfb14ab77, 0x49c931e7, 0x7ebc66f3,
- 0xdcec11d0, 0xea9d7504, 0xa2f787ea, 0xb2a690dd, 0x2db0dda2, 0x68c06400,
- 0xf028fec6, 0x07c802f3, 0xdf3d087d, 0x0223cf80, 0x6788ff78, 0xe82ace54,
- 0x99a1379f, 0x32a5f0e8, 0x6f8655a3, 0x98e0642d, 0x331614c0, 0x67d9d91b,
- 0x50fdffc7, 0x68f3ac3b, 0xf08ddd8c, 0x1550305f, 0xc3cd21fd, 0xda06623e,
- 0x1c38e36f, 0xfd17b3af, 0x99933fe0, 0xb1e46435, 0xfbe42acd, 0x94be6699,
- 0xe3e71225, 0x834d997b, 0xd99fbbdf, 0x2ea9dda9, 0x93fd0dad, 0xc15be853,
- 0x0e601fbc, 0x39873e7a, 0xdccb9ca9, 0xaca7fed4, 0x1f0aea9d, 0x082ffd00,
- 0x3e7ff4e5, 0xf9ba265c, 0x327de718, 0x4ae87d30, 0x678cc758, 0x5fc81293,
- 0xf04419ab, 0x67bcd9b9, 0x8f8e1c48, 0x71dbd8c6, 0x6fdcde9c, 0x7181ac5e,
- 0xd1377a54, 0x989c9f5f, 0xe1d04834, 0xb689cb0f, 0xcc7f3ede, 0xb8700918,
- 0x2ef4a04b, 0x63f9315b, 0x3991b2d9, 0xe36d3f00, 0x53fa2764, 0x43ab6cc7,
- 0x93aa6543, 0xcab36d5e, 0x59dff7a4, 0x50194ccd, 0xc694677f, 0x6b74455a,
- 0x5d3c3d23, 0xcd7d978c, 0x7800f6fe, 0x586e5d3e, 0xdcf50c1b, 0x790fe021,
- 0xd0e4d5d1, 0xb3e46abd, 0xcfbef129, 0xfafaa5a7, 0x6ab3774d, 0x3d3be119,
- 0x61ddb7c3, 0x95d00b84, 0x3ffb962a, 0xfe1b386c, 0x8fe1ecbd, 0x31f9147b,
- 0x1bb6aaed, 0xd62631e6, 0xf585886e, 0xecfbbf2f, 0x532efc7c, 0xa0c60fb3,
- 0xb3213a5e, 0x73fef04d, 0xd81b13e0, 0x82565f4b, 0x397e0306, 0xd61ff607,
- 0x0d3b02bf, 0x16958bcb, 0x5d812f2a, 0x2abbef85, 0x207f54ad, 0x16242f36,
- 0xc368bf40, 0xed1db515, 0xfa2ceafe, 0x5f410afe, 0x2ab72a6d, 0xbb67f910,
- 0xb87d4564, 0x2136d0c2, 0xa2b6e010, 0x180ac63e, 0xae4d4566, 0xbe7e9c56,
- 0xd1072f3b, 0x4558f4b8, 0xd7a5962b, 0xd2076624, 0x8bce417e, 0x3ebbf1c6,
- 0xddd67cfc, 0xe57cfcf0, 0x85fefa58, 0xbf7d1b4a, 0xca9732b3, 0x3c7b588a,
- 0x74b5b3b6, 0x20b40eb4, 0x7d10ae36, 0xa1d0dddc, 0xb67a828e, 0xdf21b24d,
- 0x4e6369dd, 0xab75e027, 0xada9eb86, 0x0f90a7a0, 0x7ccda7c7, 0x7a8661e1,
- 0xe38e9ec4, 0x30a53fdc, 0x3e99c71b, 0xdb1aa176, 0x631df03d, 0x743c6303,
- 0x65ba3376, 0xf2fc727e, 0xddd1129b, 0x1ee59565, 0xc71cabb4, 0x7a0fb265,
- 0x185530d5, 0xe193f7bf, 0x74e0074e, 0x70b8fef9, 0x35cb6794, 0x2f10f096,
- 0x27e9d639, 0xdcf73ac7, 0xdfade116, 0xdf5c433a, 0xd0e505fe, 0x810e5c67,
- 0xb7ee74a5, 0x118ca728, 0x976fc456, 0x520043f0, 0xcb8fa881, 0x406f82b4,
- 0x33bd608e, 0x83c82d80, 0x51abd67a, 0xf00f9013, 0x8f24967b, 0xf57c499c,
- 0x585fd8d9, 0xe9dbdf3c, 0xdf97f25a, 0x53b2fd42, 0x5e80d0e5, 0x5d5cccba,
- 0xeabae3af, 0x17b4568c, 0xc0752593, 0xefec10ca, 0x964bbe24, 0x2095ea2c,
- 0xfabd7647, 0x19e7e0c2, 0x8d8c09da, 0x6c6ff785, 0xf3392409, 0x667ac686,
- 0x817ff625, 0xc9f97ff7, 0xc26f3f47, 0xd1d289f2, 0x1059428f, 0xcd70421b,
- 0x70e14dff, 0x5111b3a4, 0x6f180680, 0x6dc941f7, 0xad2c6748, 0x489af0e6,
- 0x6dc8cf98, 0x50c1aa1d, 0xaa93aa8e, 0xca611cb0, 0xfbc3263d, 0xcd0b58b2,
- 0x8c434c63, 0x32ec851c, 0x9f97f9d8, 0x6be1bd90, 0x5cd6a487, 0x79983099,
- 0x92e191ec, 0xa5e222eb, 0x347a74ca, 0x4d563be9, 0xb96fece3, 0x69734ff7,
- 0xe0e9601d, 0xad6a17bc, 0x8e9c1fa4, 0xcbb3a45a, 0xd92b64f6, 0xe78e79e7,
- 0xed97bf10, 0x17d45661, 0xff5fc007, 0xa33fb611, 0xac1e75a6, 0xf184193b,
- 0x07e0019b, 0xe97de01b, 0x93d21ea8, 0x0c2d43a5, 0xc5f43bbf, 0x3e1172bb,
- 0x6bfb8d65, 0xbd129c69, 0x82d9fd15, 0x515b57fd, 0xccc9b26f, 0xd5f4809a,
- 0x9abfebc8, 0x1ea2b364, 0x86fda82d, 0xa8f2dbd7, 0x83de079e, 0xe62fdb1a,
- 0x42b3d976, 0x74f6b12f, 0xb2445b92, 0x7ebe0f16, 0xfdf1af05, 0x644718d6,
- 0xcfa3d185, 0x416d0f40, 0xf2d488fe, 0xe6136dfe, 0x6e5c1346, 0xe3290f51,
- 0x0e65ab3c, 0x2d45ea03, 0x20f597d7, 0x603e902f, 0x7c7117fc, 0xc9466f45,
- 0xac235a52, 0x1d59ea3b, 0xf8b7b397, 0xd603d99d, 0xec54de93, 0x1f6172b8,
- 0xe8136154, 0xbfb465df, 0x8970f282, 0x6d4cb3d0, 0xe3bb4549, 0x776da333,
- 0x6071d92c, 0x7f48a8e7, 0x65eb1efd, 0x7175d832, 0x319d765e, 0x17f496e4,
- 0xe3f6d933, 0x7db56e7a, 0x9fe798a8, 0x03433cc5, 0x1d2c9da2, 0x87f80afd,
- 0x7858e984, 0x587186d2, 0x447ef1f4, 0xc156eb24, 0xe11d073a, 0x8bb1e3f5,
- 0x1b05acb7, 0x77a47dfd, 0x3382470e, 0xfb430050, 0xca6e794c, 0x6210f4e0,
- 0x11dd93d7, 0x5462b03e, 0x337d1785, 0xc20c7bb5, 0x653fd363, 0xdb7684b7,
- 0xfc5233ff, 0x86de7fc7, 0xfd7fee38, 0x150e624c, 0x2d15d7d2, 0xb4d16bb5,
- 0xf43dfeef, 0xb54c296b, 0x007b3fa2, 0x71c7adf0, 0x8ec96a66, 0x05db416a,
- 0x09ccb7da, 0x86f7b923, 0xc741cb86, 0xdfde009c, 0xf7c10000, 0x689dc3ab,
- 0x55d60da7, 0xe38697bc, 0xdf120557, 0x1b9c68b4, 0xc7fc7162, 0xb2f8d206,
- 0xe8e1bdfe, 0xe4227d7f, 0x9ee49551, 0xc76df18b, 0xefc32d15, 0xa3bb04d5,
- 0x535ea1ca, 0x7fda9c38, 0xed192a02, 0x5b609ac4, 0x03d9ca24, 0xfe4994ff,
- 0xba828cd5, 0xc513e491, 0xd8666a61, 0xfea18322, 0x4d4bc0a0, 0x99feb3ad,
- 0x4c9e7c50, 0xb8c60ce3, 0xe18bb61e, 0xc345fce3, 0x07a7d9fb, 0x075ed1aa,
- 0xf089144d, 0x027e6dfb, 0xe3c2d2c5, 0x0871c826, 0xcfb7e15f, 0x19477216,
- 0xb3e83b1f, 0xffe30ed0, 0x37a92ce6, 0x5fdd7f20, 0x0d00e860, 0x58293ec2,
- 0xf5bf4263, 0xd6ecbb7e, 0xf7605c81, 0xecfadb65, 0xdf1c5882, 0xbd21c726,
- 0x937e2be5, 0xf5c2317b, 0xdb3d1ecd, 0xe0237644, 0xba7aed35, 0x1fdf80bb,
- 0xf8e3fe80, 0xc7fdbca7, 0x9fe71d42, 0x6887480b, 0x43da060f, 0x4de5fe70,
- 0xf6f29f93, 0x592ce72b, 0x40724417, 0xa552f77c, 0x132fa9ed, 0xa5c84ed0,
- 0xf2aef952, 0x7a99dcbd, 0xfe8a149b, 0x7189ce8d, 0x0ec205c0, 0x67b9d72d,
- 0x673e3f21, 0xefa30fb0, 0x474c5d14, 0x6674317b, 0x475c00f2, 0x0e60bbf7,
- 0x0233db41, 0x805067cf, 0x4c2b9e23, 0xd44c3744, 0x4818bfed, 0xdf04b9f6,
- 0x62fa3a41, 0xda3b698d, 0x2dad7673, 0xd1d20972, 0x47b240f2, 0xc1dc80ce,
- 0x0494cf71, 0xfbce1d13, 0xc8fbf175, 0xb4f2676f, 0x5a679f44, 0xe9f7bdb8,
- 0x85add94a, 0xbccd77f5, 0xf4224cf6, 0x45f55aeb, 0xdb2856d6, 0x1a35fcd7,
- 0x35bcd1f5, 0xdfb0d3a5, 0xd355a2bc, 0xe2374e11, 0x3a2579f3, 0x6e1cccc1,
- 0xb76ce353, 0x6742be23, 0x3941cb5e, 0xe4b8b83d, 0x17c18c39, 0xc4efd9c7,
- 0xdb6997f5, 0x651e10cb, 0x8d167c6f, 0xf37773f6, 0xa15b7bcb, 0x27d9336c,
- 0x35b2bf60, 0xc3acc577, 0x55ff84c1, 0x017c06a6, 0x671e7d1d, 0xe5f7c1cf,
- 0xd889dc93, 0x2da692ef, 0x56c6e107, 0x7ddd9add, 0x80fea5b1, 0x40607e84,
- 0xb295194b, 0xd1e71d33, 0xa483b929, 0xd8238438, 0x4beeb00f, 0x70507766,
- 0xc98d452a, 0xe9de289e, 0x5a9a3ebb, 0x403b8898, 0x6c9762bf, 0x32dd2033,
- 0xebe716a7, 0x9e18bedf, 0x7c5bbb53, 0xfc5cc45e, 0x93d37079, 0xab7d2077,
- 0x37f71b99, 0xd84aee2e, 0xbcbff88e, 0x6f44e5ff, 0xbcbfd83f, 0xfd7cbe7e,
- 0x00be9097, 0x89e0978e, 0x41abe906, 0x75ffe3e7, 0xfa248aed, 0xfd11ef82,
- 0x724aed74, 0x8f92f26e, 0x307e425d, 0x066b2bab, 0x95cdbdd2, 0x22967685,
- 0x95de982f, 0xb25bfe4e, 0x15fd1d2b, 0x3cb0de45, 0x773d2257, 0xfdb112ba,
- 0x8d67f401, 0xed16ef9e, 0xc4ddaa8e, 0x550e8ee3, 0x6c47d606, 0xee32bac7,
- 0xb497d6cd, 0x4f53eb55, 0x9fd6fa71, 0x95fcf210, 0x1f8ab457, 0x82bf0b2c,
- 0x5a3c1459, 0x7046fdb8, 0x8156b3f9, 0x5951c3cb, 0xbf803718, 0xdcde6962,
- 0xfb857e6f, 0xd94607cd, 0x2aae50a3, 0x6081f9fe, 0x5ea2a7a8, 0xea56f3e5,
- 0xe7fc1c0a, 0x4bcfe6bd, 0xf7be30a3, 0x1f8f1c46, 0xbcb81955, 0xb97032aa,
- 0x1594dab4, 0x34abef8e, 0xa2a6c760, 0xee2c72bf, 0x0e078d4b, 0x366d2ae7,
- 0xf57dc110, 0xe9475ba5, 0x6d976f91, 0xa6f7a51b, 0x639daa8f, 0xde60598e,
- 0xadaa7697, 0xb52a84b8, 0xd7b449f3, 0x2eca76aa, 0x7af7a307, 0x64bfb41b,
- 0xdb02723c, 0xe3c6dd2d, 0x65ff4a16, 0xf96db35b, 0xb11ef35e, 0x69be17d3,
- 0xc8fadf2e, 0x51fadf26, 0xfd0645b4, 0xb946fdeb, 0x8e63eb7d, 0x7fcfd6f9,
- 0x242cf0f8, 0xf1d902c3, 0xe3f68ca4, 0xa18e735f, 0xc0eaf93e, 0xf78a20c1,
- 0x8adf967c, 0xadb2f176, 0x3c0770be, 0x3827684a, 0x77a44876, 0xfcfe9d0b,
- 0x031f3fd2, 0x5f389446, 0x14dd37b2, 0x3aab4731, 0x9df6fae6, 0x86cb35cc,
- 0x7f95a571, 0x8c72fb8a, 0x5ddbdc67, 0x0fe8b45b, 0x46f77ff9, 0x368ccb7c,
- 0x1637c60b, 0x7eefe58e, 0xfb2272b4, 0x7cdbc702, 0x71e90732, 0xd224afe1,
- 0x25f70bc3, 0xd3748dbd, 0x14ce77b1, 0x12e5672a, 0xcbb8943c, 0x6dc916b2,
- 0x2c79ba82, 0x650fdbeb, 0x6b45ef30, 0xa1f13e75, 0xf3becdfc, 0xfbe35a58,
- 0xe1d3597e, 0x6bbee1bf, 0xda45fe81, 0xa6d82ea7, 0x396b8bf3, 0xbd3b42df,
- 0x7e462be8, 0xf7dd5178, 0x5ee2feba, 0x143ac44b, 0xee3990fb, 0x6e4eb864,
- 0x8edf8202, 0x3d7207ff, 0xc4d76cc4, 0x8dd8f20f, 0x95a9aa3f, 0xcca57e11,
- 0x8e3988fe, 0x207751fc, 0x0ea967cc, 0xa4d1b1ec, 0x577d6987, 0x78a00eb7,
- 0x06673c07, 0xb5957e78, 0xbe7ea165, 0xf2b268da, 0x965b5938, 0xa0cbea19,
- 0x602bf08e, 0x12a704d5, 0xa732cb94, 0xddb79b1b, 0xb3adf4e0, 0x97b76e6a,
- 0x1187dda8, 0x9dacc51e, 0xbd1e21fa, 0xbac095db, 0x3b41093e, 0xb33fafc4,
- 0xdcbc9c52, 0x95fc25a8, 0xf3af7d37, 0x0bf8af7e, 0xc4a2ff8a, 0xf4577ee1,
- 0xb7d20060, 0x3587d846, 0x5b7b9d1b, 0x94eb3d61, 0x0316deb8, 0x6b07a7c9,
- 0x7b07bcb9, 0x59d71130, 0xd68525b3, 0x8b64a0fd, 0xf6b68759, 0x7fd13d0c,
- 0xd3d8304d, 0x924764a1, 0x237600bd, 0x733dadd9, 0x12edceb4, 0x372e8fda,
- 0x4f35c1da, 0xca06f8f3, 0x9f6bb249, 0x527d9030, 0x27db8333, 0xa9c25b35,
- 0xca705fff, 0xf2576891, 0x913cd4f9, 0x995dedc6, 0x8ce163f7, 0x65f607e6,
- 0x5e6bdea2, 0xb2ff5d8a, 0xf1113ed9, 0x26b7acad, 0xfb84c7b8, 0xe060ac1d,
- 0x7af9e92d, 0x007abfa1, 0xff07180e, 0xc56bca52, 0xdda5097d, 0x1f5cf17d,
- 0xedb04d64, 0x5e28ed10, 0xb19aaf9e, 0xa79827e9, 0x52ca8cf0, 0x7f05e315,
- 0xd7112d9b, 0xc316e5ff, 0x99d3c468, 0x679e5c51, 0x05f1e04d, 0xdb6c5bf0,
- 0x5e22ff71, 0xfd7713e5, 0x614ef8a9, 0xf5e685bc, 0x2f8f3665, 0x28f2329a,
- 0xdab6038e, 0xf5f6fe82, 0xbef9e30b, 0xef36be68, 0x99fb8ff8, 0x3617028f,
- 0x5f17fb89, 0xbe91243e, 0x9a24f584, 0x1bf59ea1, 0xbe7fc503, 0xc1477a14,
- 0x2651d007, 0xc72161e9, 0xc67e90c2, 0x19e7e878, 0xa40e1741, 0xfd378b0b,
- 0x83c7d2f8, 0x09ecff02, 0x04d69f6e, 0x13cd7af3, 0x9fa03729, 0x650ffdfe,
- 0xfcb535bd, 0x01dfbfbd, 0xde36b074, 0x74fe9e0b, 0x4cced4c0, 0x7f35fdef,
- 0x8d96c83a, 0x57e728c9, 0xb4560148, 0xfe0857c7, 0x1184b158, 0x0ab1463d,
- 0x8235f909, 0x008f29b9, 0xc70181e4, 0xc00f71fb, 0x7f0f8bdc, 0xbccf4d72,
- 0x1678dff5, 0xa89f53ec, 0x9f69f48f, 0x79f18e6d, 0x8a44577f, 0x96c9fbcf,
- 0xa9f53e51, 0xb4fbb7c9, 0xde3adbbf, 0xd8cf7ea7, 0x67ed3ec9, 0xd4f866d8,
- 0xc6accc6d, 0xee54b7f9, 0xcde0fb24, 0x97dc574a, 0x65c3d709, 0x3ec8ee9c,
- 0xa6b1958b, 0xaa6707ba, 0x0dc61e81, 0x0622b238, 0xede387ea, 0xe4751ebc,
- 0xb1998c6a, 0xf217e2b7, 0x572388fa, 0x347ea163, 0xdfaf117e, 0x7f5fc8c1,
- 0x4cf17e27, 0x15c52a47, 0x667e218f, 0x8a38ab5d, 0xab47e16e, 0x41892e67,
- 0x24c92f1e, 0x67ecae39, 0x3f6313dc, 0xbcacfc84, 0x8d9fda57, 0xafbbfde7,
- 0x7ddff970, 0x2377cb85, 0xfe83291a, 0x32fc12fd, 0x0e04fefa, 0x6f413622,
- 0xa62ffda4, 0x8bea5cd7, 0x94fc8343, 0x3c618c6c, 0xf012a5af, 0xd370809d,
- 0x34aee953, 0x32a47953, 0x2bb7ca82, 0xe01f2c2d, 0x4c995ada, 0x2b4ab1e5,
- 0x395e3f3d, 0x2bf7ca96, 0xa89e546d, 0xadb2a5cc, 0x094a8f32, 0x2879a98c,
- 0x3758763f, 0x0e2e1068, 0xbd39f075, 0xc6e52f27, 0xcecd4c72, 0xc685f829,
- 0x5f6c186f, 0x31dd93c4, 0x71714cc4, 0xd35bbcf1, 0x73d222f3, 0xc16615d5,
- 0xa6c3b87c, 0x9fb416d3, 0x44f532ab, 0x9b4f52ef, 0xb8ebe505, 0xbaaf5e0c,
- 0x675166d2, 0xfdea3af0, 0x28d760ee, 0xa5550bd4, 0x189aeb46, 0x448eef7c,
- 0xa157197e, 0x387fa2b5, 0x3e67a7a9, 0xa338f1f2, 0xf47a82d6, 0x2df5a9b0,
- 0x73ca3df1, 0xdcc2bba9, 0x3457dc2a, 0xe2cc59b4, 0x7c0e383b, 0xc1f50637,
- 0xbbe187b8, 0xed056e34, 0x679b8d07, 0xe4aefbec, 0x0ffd5df7, 0xe4a2777f,
- 0x5ef8ddf5, 0xff3a6ef8, 0xbbe7c5ae, 0xe5ec996e, 0x0fb26e2b, 0x11ad83ba,
- 0xfa955f28, 0x4a9f7c24, 0x33d24271, 0x196e2ce3, 0xe887eff7, 0x070d3cb8,
- 0xa5e0d2f3, 0x6278956f, 0x675f2f5d, 0x08bba557, 0xb0926af9, 0x59692657,
- 0xa993c232, 0x98fe2802, 0x1ad77f2d, 0xcde5f505, 0x9dcc28d2, 0xdbcba498,
- 0x9aae7e46, 0xca161dcb, 0xb75332f5, 0xed0cbe15, 0x5945854e, 0x486adf31,
- 0x0f1601c4, 0x3cbb3872, 0xfaf51537, 0xd4df9129, 0x484f641c, 0x9bdc7980,
- 0x254a720a, 0xd9f71988, 0xde490372, 0xca4a1f77, 0xa67f7b44, 0x019fb2ce,
- 0x3c26a71f, 0x720d5333, 0x4b00e671, 0xfac664a6, 0xb70f5e36, 0xbde097ec,
- 0x73333d99, 0xc1ffedd2, 0x4934fafe, 0x381f97ed, 0xadf80136, 0xc8b2f734,
- 0xfb21ec57, 0xe498c7f6, 0x77e28834, 0x9ec7a46e, 0x03d226c9, 0x8e5b8f18,
- 0x92d53bf2, 0x35a2ed89, 0xff08413d, 0x94d4efee, 0x832d023f, 0xe38af3ee,
- 0xf3c2d8bc, 0xe3f9fc4a, 0xabd70272, 0x9f3cf1e5, 0xaf422ca9, 0x4ae5b2a7,
- 0x8f7ca30e, 0x3ff478bc, 0x57edeac1, 0x0277febf, 0x598e1fdf, 0x47f1e5af,
- 0x6530a114, 0xea53005b, 0xa96bcc0e, 0x3140247d, 0x4e006d46, 0x547ec5a6,
- 0x24cdfa6f, 0x1b7b4fb5, 0x67bcf7b6, 0xd29f0436, 0xcf7ea4bf, 0x8bc6d66f,
- 0x2cbd21ef, 0x825c4e65, 0x4da9febf, 0x0bfc510c, 0xa10bf3c2, 0xe38bf206,
- 0xa057a065, 0x1740a8cf, 0x0ceb33c5, 0xdcc17e9c, 0xc54eb2a0, 0xc0036bdf,
- 0x50fa85fe, 0x9a3ee3a8, 0x22bed13b, 0x67f51071, 0xef2fec66, 0x2291fea5,
- 0x1f794e6f, 0x1979518e, 0x0cdae9f3, 0x55938e58, 0x4e4dc2fd, 0xc46bff1c,
- 0x83a55777, 0x2fd2f59d, 0x2b41815d, 0x8654f1bd, 0xfdde8dfd, 0xa53f5026,
- 0xfdd8297f, 0x9c920767, 0x8d297a26, 0x2b3e5157, 0x4b6fcdf8, 0x36b0d768,
- 0xa561ea2d, 0xab9069df, 0x410fbdf8, 0x09f962ce, 0xc0b3d7c8, 0x9ca97f9b,
- 0x95a7e54d, 0xa67e7a76, 0xf6ca80b2, 0xfe7a0aca, 0x2a4ae579, 0x6535cd67,
- 0x37949f20, 0xbd6766ad, 0xa5d4bae8, 0x4bef7bb1, 0x3fdf1e9e, 0xe04aecbd,
- 0x98e9dd76, 0x95bbdffe, 0xbc7277f7, 0x817d8375, 0xdfd024f6, 0x8dc8735a,
- 0x136e8ced, 0x377abfdf, 0x7773d385, 0x25d7af24, 0x536ea868, 0xffd8adb1,
- 0xd12d14dd, 0xc6448aeb, 0x2c7889db, 0xdf8d1fd0, 0x3e54e707, 0x19ced28e,
- 0x2fedcaaf, 0xf225984f, 0xe89f4476, 0xc63d202f, 0x9967d178, 0x9fd3e885,
- 0x39136a2e, 0x38ebc4df, 0x2ea145dd, 0x708c7dc2, 0x0a731383, 0xdc36be60,
- 0x3893af57, 0x9f475e3d, 0x5d9fee2a, 0x0e309f47, 0x5ce809c1, 0x7ec7f282,
- 0xef94a3f4, 0x0b6fbe0a, 0xe08cfd33, 0xa331a2dc, 0x0cb1f8be, 0xaafec580,
- 0x0f9813de, 0xb266151e, 0xf6489ee0, 0xfe8ac6e3, 0x123fc7e4, 0x6ffd7db8,
- 0x1f8fbfaf, 0xdd7fd77d, 0xd07ec5ba, 0xe49baead, 0xa44bca09, 0xc3e47e9f,
- 0x3e4504a5, 0x1391fa70, 0x3f50e76d, 0x35064b74, 0x0dbbb3c6, 0x83ae2e9c,
- 0x4fa70a5b, 0x056a3e85, 0xbae1447d, 0xe9eb3ce2, 0xdf807f9b, 0xca3196fa,
- 0xa3c7f0eb, 0xd6bc5722, 0x2f04f7f5, 0xd818c279, 0x487fd017, 0x09f69189,
- 0x099a2457, 0xce83dd7e, 0x6f02dfcf, 0xe27a159f, 0xa7df1579, 0xdf76e450,
- 0x305e4973, 0x9e47d523, 0x7a33b433, 0xbf88e90e, 0xf0562adc, 0xf851fa1a,
- 0x70bf2f29, 0xef53c0ac, 0xee154cec, 0x6b7d75bf, 0xcd1e5074, 0x68339ee0,
- 0x056d7447, 0x7ffc8003, 0xf40934db, 0x878c12d9, 0xafbe3058, 0x8be8fda7,
- 0x24b20f60, 0x72bae768, 0xf298ed06, 0x07a664e7, 0x7dcfc9d0, 0x65e90b33,
- 0x998d21e9, 0x4fad9aec, 0x3b7a431d, 0x505928d7, 0xc23577df, 0xb39f71b2,
- 0x4034e4c6, 0x63a81cfb, 0x653b65fb, 0x03522527, 0x14fe907b, 0x286b3bdf,
- 0x777b458b, 0xa33f73e2, 0xb5a5f8fd, 0x71870b12, 0xa2badadf, 0xe7ea1235,
- 0xf9fcf1b6, 0x7fcf032a, 0x6b3791cf, 0xb47c6307, 0x312f3f96, 0x7bfe50e6,
- 0x75662ed1, 0xaf65bc63, 0xa5f3fc89, 0x1579be35, 0xeb7cdb05, 0x5cbe2285,
- 0xbcfbe754, 0x4f37c1a4, 0xc8a24c63, 0xa36148c3, 0x135a5e28, 0x22807642,
- 0x77e46f4f, 0x397396d9, 0x61d7d8c9, 0x0f95ef18, 0xb9fd137d, 0x8867d791,
- 0x2fd4077a, 0xa2f1c37f, 0xc94ca5c0, 0x1964882b, 0x23cc0cae, 0x3f719834,
- 0x8bf9acaa, 0x73f98620, 0x89d3ed01, 0x29975f3f, 0x93636adf, 0xa569fb4c,
- 0x3097862d, 0xff6cb0cf, 0x84c5ad49, 0xec887f70, 0x6398bb80, 0x6e8bfa3d,
- 0x6fe44a95, 0x8ddc51b7, 0x52967ad9, 0x60d9bb7c, 0xf65afd46, 0x73adc7fa,
- 0x625fbeb1, 0xd0e3c406, 0xa593a276, 0x5fb4c9cf, 0xc9f2d0cd, 0x8c89d0f2,
- 0xbb3c4578, 0xcf3ed006, 0xe23bc432, 0xe78ef019, 0x34e7e41b, 0xbba5f784,
- 0xb55f7a64, 0xed8b4ab5, 0x7e3939cf, 0xc8e7bc15, 0x45cf08ab, 0x4e7c702f,
- 0x99feae7c, 0x5d83a400, 0xdf73b21a, 0x79837e82, 0xd03a1f3f, 0x77e3e21e,
- 0xdf144bd5, 0x6683a3ea, 0xe01d1f5d, 0x07466f3c, 0x67a49fc0, 0x0607466f,
- 0x4fe41794, 0x8a1a3b8f, 0xf8cfedf6, 0x9db8947c, 0x1f9b9712, 0x10fa59d2,
- 0xd8884d34, 0x1b2cf647, 0x08955f60, 0xe4cce672, 0x74dc280f, 0x51eeca6a,
- 0xff034f94, 0xbf9461f4, 0xfb7cf047, 0x444b7fe7, 0x331dd079, 0x18c1db63,
- 0xae0767c2, 0x90383ba7, 0x923dd3eb, 0x3ae7a253, 0x93be0eb7, 0xf915720d,
- 0xa3a9bd92, 0xa0f743f8, 0x893e1e07, 0x184f68fb, 0xc92e88ad, 0xe2bafdc6,
- 0xc13e7796, 0xcc6b27f8, 0x7df8f9b6, 0x462b2fc2, 0x37df10bf, 0xb5e85f80,
- 0x3f9928df, 0x4bbf7ea0, 0xcb75a58c, 0xf256eb2a, 0x0598eadf, 0xe5eb95ed,
- 0xaff9233f, 0x686eafc4, 0x01e9f99f, 0x76e7fc8f, 0xf10c7319, 0xe5c0b73b,
- 0xf71132d3, 0x71c8fa3d, 0x675c40f5, 0x53373f1d, 0x297202d8, 0xf8a5ce94,
- 0xd13297c8, 0x19d23cfe, 0x472bf1c0, 0xec9501c5, 0x9d3e472d, 0xec94e384,
- 0x2194e3e2, 0x981c20fd, 0xdc0099fb, 0x28697027, 0x84c4591e, 0x5932695c,
- 0xe47e96dd, 0x7aed5d48, 0xe9fd7f34, 0x37ec18a7, 0x1d3f845c, 0xb6fa3595,
- 0x97ca03fb, 0xd25f2411, 0x077f47be, 0x23d32369, 0xd4e5b247, 0xf5afe801,
- 0xe400cb32, 0xb9e91be3, 0xdac0ada4, 0x38a6e35e, 0xb3ed4cf5, 0xa9f6615f,
- 0x7c22b9a7, 0xb26c8fda, 0xe51fbcf8, 0x3f79f64e, 0xa7d598e6, 0xd636d99e,
- 0x9f6dfda7, 0xb7ea7cd8, 0xb4fae7b7, 0x3cabe3bf, 0x2a6f7a9f, 0xf607e7ac,
- 0x908aeeef, 0xb64fda7c, 0x07c67c18, 0x99f04e0d, 0xf3ec1c9a, 0xe1c8d7bc,
- 0xef71a374, 0xab8efab6, 0x8cf7b9f8, 0x867f1df5, 0x5bdc77cd, 0xd00ec3c5,
- 0x4d106a9b, 0x628f413b, 0xc0254af9, 0x86f1ec1d, 0xbfaa08ca, 0xd2a1695a,
- 0xcf4c9955, 0x52b4ab5f, 0x2c72b1bd, 0x7d800fd5, 0xb026f58f, 0x1d7cb1f7,
- 0x7e7c7cec, 0x8ab57833, 0xdf131eef, 0xcbbe2e3d, 0x076e16d8, 0xef2e04dc,
- 0x4427fe8b, 0xafec36ff, 0x6961d0f1, 0x1aeaa66e, 0x90f8edf0, 0x2f8c5a0b,
- 0xe7b796d8, 0xf3df9fa0, 0x03b6ccae, 0xf3bb305f, 0xea286558, 0x1f3c81a9,
- 0x3de7af21, 0xed97178c, 0xfee3338f, 0x3fa6c6c7, 0x5df7c09d, 0x33c5328d,
- 0x117d348e, 0xba5ce384, 0x503ecc06, 0x97a837e8, 0xfaa24dfc, 0x798f7826,
- 0x82f793f8, 0xcb7a4b61, 0x52eb7a45, 0xd27752bc, 0x86bc8df9, 0xda76dabd,
- 0xef4bdc57, 0xf5be05df, 0xd6b3bf79, 0xdb19bde7, 0xdab67ee3, 0xc5f77e49,
- 0x373c6526, 0x97892fb5, 0xc5d23ce8, 0xc7ad6f9d, 0xbdd2be7c, 0x3ee2070b,
- 0xc9c37160, 0x003fc5b0, 0x7607cbff, 0x2f5ca2a7, 0xf9c5966d, 0x695e3e23,
- 0x891e72b3, 0x7e24bfcf, 0xca084e6f, 0x218906ed, 0x6ab12e7a, 0x6e2a8fca,
- 0x39412faa, 0x573c9c5a, 0x9721f143, 0x3c01e22c, 0xccc4b0df, 0xbae67db8,
- 0x35e7841a, 0x3a3ae0ff, 0xba85f31d, 0xc20ade5b, 0xf9e376ef, 0xdefc2f13,
- 0xdcedc493, 0xdfb8927b, 0x2df1a974, 0xd1b93f3a, 0xbb8716f5, 0x3feb4dda,
- 0x50ddea22, 0x649bbc12, 0x35e17f5a, 0x8ca0f099, 0x4c9260f7, 0x4a6e4de3,
- 0x4ebae130, 0xf2f7f8b9, 0x79fc2c93, 0x9c7cc2fc, 0x3988f1ff, 0x95d93299,
- 0x3ddf2e3c, 0xca3d6a7c, 0xe80fcc51, 0x047b0fcf, 0xb5f985c7, 0x77c63c8a,
- 0x0eb5f7e3, 0xcf1fb806, 0x748a381d, 0x274fe280, 0x473dfb71, 0x3d478f6b,
- 0xa168ca71, 0xdc9af838, 0xf7e21338, 0x3cf89608, 0x57da25f7, 0xdfe46a28,
- 0x0b6e653b, 0xd53bba42, 0x3b464638, 0x40af1946, 0xbe8fb77c, 0x20e6f0fb,
- 0x6b38153c, 0x078e388d, 0x7e79fc7f, 0x71e69992, 0x167279dc, 0x92a74bda,
- 0x68cec903, 0xfcfdf2d5, 0xef6e06e2, 0xaa896a9e, 0x5bf6bd95, 0xba3e05f2,
- 0xd7845593, 0x688d26ae, 0xf99eb737, 0x7c70d3b4, 0xc7cef9d5, 0x1278ecec,
- 0x1792eced, 0x54933a64, 0xc308a9a2, 0xe6df9ff5, 0x0102bf3b, 0x3b8d12e7,
- 0x5e8bcc2c, 0xf8fb9a4b, 0xde7448c6, 0x8589f0ac, 0xf1e0a9f0, 0xc73f3254,
- 0x9f822a72, 0x5bd92a83, 0xd1ed744f, 0x19ae3cf7, 0xbf3c5ff5, 0xae7e66f6,
- 0xf9780f62, 0x3cfd0c49, 0xa65c6e4d, 0xf7a3d62a, 0xbf6d137b, 0xfe841a4b,
- 0x85f91e53, 0x8a26ec40, 0x3c7da08b, 0xa7efe500, 0x7b77e0cf, 0xd879f91b,
- 0x11737d52, 0x5af5fbee, 0xbe604181, 0x4e34dbbd, 0xd118cfe1, 0xec2a5d4e,
- 0x7b16f3d4, 0xa3fb8c96, 0xaeb455ab, 0x89d90692, 0x425d98f9, 0x1bde5dde,
- 0x69d20f73, 0x8cd931c9, 0x5744cdfe, 0x65c7afcc, 0xfb26de90, 0xedc5ccae,
- 0x129db2dc, 0x7d8ab5d9, 0x8bec2a51, 0x3d8ec273, 0xdb87bab7, 0xf62487b7,
- 0xcec78c54, 0x45761528, 0x3d79bca9, 0x9ffb2be6, 0x396c2daf, 0xfd89e74c,
- 0xef16d5cf, 0xba97adf4, 0xbf8aeb7c, 0x9f524ef7, 0xfe82927f, 0x94a7d809,
- 0xc0a9f12f, 0xacafe2a7, 0x2386b348, 0x5b546fbf, 0x037128a6, 0xa1f95784,
- 0x6f38857d, 0x95804967, 0x6f9587fc, 0xbfbb5c10, 0x77497ee6, 0x77f5a304,
- 0xeedf0e33, 0xe5df4e26, 0xc7a9c91a, 0x7023a8fe, 0x5ce4bd3c, 0xa3a8768d,
- 0x12e48837, 0xf7c1e1e6, 0xfee1cf96, 0xa3630da7, 0x855a9530, 0x29fd140f,
- 0xa9decdce, 0xbd83976e, 0x2495c3e4, 0x124e776e, 0x4c2b48f9, 0x835fd256,
- 0xc1ebb9c5, 0x0f6f6e7a, 0x53573b56, 0x6631fe3c, 0xf2714359, 0x4e90a303,
- 0xf14eae30, 0x123d55ff, 0xeb1fc3c5, 0x063f9091, 0x7911ad9b, 0xf849f55e,
- 0x0763d53e, 0x48f6330c, 0xc7ba9df8, 0xd73af894, 0x66d433ef, 0x894fce0d,
- 0x87fb293b, 0x7394fcca, 0xf3e7ff08, 0x8cfcc333, 0xbe01f99e, 0xabff6007,
- 0x0fb25619, 0xe72867a2, 0x1e482afd, 0x04bcf028, 0x70093ef4, 0xa41d3185,
- 0x876d929b, 0x40fe7873, 0xcbdf9d1b, 0xc8ebe209, 0x39e3f911, 0x941cbc01,
- 0x2b35f1cc, 0x9e8bc799, 0x3722a510, 0x85b649df, 0x2fb94325, 0x39322f39,
- 0x62ce73d3, 0x9cfc07f9, 0x87bcbf85, 0x574f44e7, 0xee510f81, 0x3242b4fd,
- 0x63d8fbc7, 0xf9cabf9c, 0x2a3e3ea3, 0xe225e0fe, 0xb5b0e613, 0x9e618725,
- 0x05efe702, 0x78e60d2b, 0x1728be2f, 0xc5a6207e, 0x7297fee2, 0x5cc0be4e,
- 0xec40e748, 0xe8ccc32b, 0x97cb9597, 0xafff5e28, 0x93795df2, 0xe06ddd6f,
- 0x4936eff4, 0x9edcffe4, 0x13cf67dc, 0xfe0b463f, 0xb44bb5a8, 0x9dfb5c2f,
- 0xe6dbc79a, 0xbb5f1449, 0x7cf21e1f, 0x60aed17a, 0xdd9be53c, 0x37da550f,
- 0xfb1509ab, 0x9fb4a1d6, 0xf7589f77, 0xe2df22fd, 0x8315c6a8, 0xa5a3a0f1,
- 0x3f8e2b7a, 0x7f68b987, 0xa36b1e7d, 0xd96074f2, 0xee0d377e, 0xfcfe8a18,
- 0xc51d76c7, 0x6ed76aa1, 0x4f5ca137, 0xb8cd6b67, 0xd8a006cf, 0x5b98fdf9,
- 0xf2538fdf, 0x0e2ec189, 0xfc04fa47, 0x7ffc46cf, 0x1889b805, 0xe2ff7d7d,
- 0x3e53f68f, 0xfbc3e752, 0xd0c03d66, 0xff21eaaf, 0xb562a8a8, 0x1c4df686,
- 0xcb392dac, 0xef055783, 0xf0fade0a, 0x1f16616a, 0x869ac2bc, 0x4be49c20,
- 0xfd2e4833, 0x77a8664e, 0x0557866f, 0xf8113fee, 0xe5ccd659, 0x15be3f97,
- 0xe7803c3c, 0xdf48e2a3, 0x313c236e, 0x7f4bc91d, 0xbe19b87a, 0xe1e73080,
- 0x3aa189ab, 0x54a32ff2, 0x2d469e5c, 0x38be2895, 0xb50fd997, 0xf02b3943,
- 0xbbd10d53, 0x813cdbc0, 0xf3998fb7, 0xff98e4ee, 0x93bdbc3d, 0x3c9d579c,
- 0xf5be7ae8, 0xf11bd3e7, 0xfac58965, 0x3a5f4547, 0x1fa3f219, 0x6bf1fb3f,
- 0xf0ad1e1f, 0xda3c2f3f, 0x5f110657, 0x6e5be1f6, 0x88bd35b8, 0xaa1c607f,
- 0x716bdf89, 0x60957e53, 0x57cf8021, 0xa6f57d93, 0x2e053782, 0x9deb8a37,
- 0xc23b72d6, 0xfb4c88f1, 0xee499f98, 0x639466a3, 0xfce8a729, 0xb3fed29b,
- 0x1f436dd5, 0x1b3e7182, 0x5ad3cbcf, 0xd4a91f9e, 0x3e3c016d, 0xcea459f8,
- 0x4cfdeb81, 0xfa80994a, 0xbfe933e2, 0xb87af3a6, 0x39f582d6, 0x50cc13e1,
- 0xe251ad3f, 0x7c446b89, 0x67e549c0, 0x449b6e73, 0x36f624ed, 0x3f9f8ef3,
- 0x7cfc512a, 0x9c728801, 0x6784cc5f, 0xfeaf3173, 0x46e3cfcc, 0x72df3ed1,
- 0x1f50f1df, 0x921c50c7, 0x5e778bfb, 0xf42cd1eb, 0x7a7d3bd2, 0xfe15d270,
- 0xce933f3c, 0xd808161b, 0xb85242da, 0xe7e4ec7f, 0xd33d1536, 0xd19f6c7b,
- 0x417a4e3b, 0xeafb95c4, 0x7b444f29, 0x3bc3a9eb, 0xe388957e, 0xe91d6814,
- 0xabfb7e78, 0xd1a3e7da, 0xf1d8289e, 0xb7d92278, 0xa226363b, 0xfdb0529f,
- 0xaa368957, 0x4fc9da07, 0x7775f352, 0xa5fdb9ee, 0xe77a5e4d, 0x6fdce1d1,
- 0x9c3fa799, 0x94ee768d, 0x61d79711, 0xe7e13e3c, 0xf387dd12, 0x0eb6d653,
- 0x64fcdff5, 0x46acef4e, 0xe199724f, 0x73c02df9, 0x75ddca7d, 0x93c7a7c8,
- 0x43e4d0bf, 0x9a8a5d3b, 0x399f33e0, 0x7ee38737, 0x5cc906f6, 0x0fdbbccf,
- 0x85cafda5, 0x446d256b, 0xe0b7ea28, 0xea3fe851, 0x1e698252, 0x6a8c368b,
- 0x57f3e7c5, 0x7453e7f1, 0x3853c6ce, 0xca5ab3ce, 0x10f90237, 0xafc79deb,
- 0xf1e7e14b, 0xc8966c17, 0x93be57ae, 0xad584cf0, 0x29753af7, 0xd4672f42,
- 0xce51dc91, 0x755b4e09, 0x1808edf2, 0xbb6a9ff7, 0x39c60529, 0x78b9f4f1,
- 0x149f3c37, 0xfd152172, 0xfdad049b, 0xeeb885b7, 0x83ca3aed, 0x928f48cb,
- 0xe8fda1c3, 0x853fc787, 0x0b5582e5, 0xf2885b7f, 0x147eab71, 0xf3e6174f,
- 0x55592e5b, 0xaadf3f28, 0xc211607d, 0xf5a7abed, 0xaf2f9764, 0xfd670a4d,
- 0xbe528ff0, 0x8dc7f80c, 0x7a955d82, 0x9a57772a, 0x9eda3ce9, 0xffaa08ca,
- 0x2542d2be, 0x6be9cd9b, 0x8dcb99b9, 0xe6378d1b, 0x80b3205a, 0xc1b19abd,
- 0x70632cc0, 0x9c96ce5f, 0x18487002, 0xa37dba5e, 0xa56e1758, 0x4cc4728c,
- 0x6c643844, 0x4d15a87c, 0xee14d0da, 0x6a77bd67, 0xedf23443, 0x2f1d55b2,
- 0x537ae216, 0x7f6146f2, 0x142bb6fd, 0xf9ab7837, 0xef08f9f1, 0xbe3aed82,
- 0xafeeb13e, 0xff0c4e9e, 0x78ef8c2d, 0x7c7e4357, 0x178eb6f9, 0x78b94237,
- 0x6f5a43f3, 0xf5d5bf7a, 0xfbe14c8e, 0xabe3379d, 0x5fe1c11b, 0x455fabe7,
- 0x7f6cff13, 0xf9e1ee9c, 0x7caaf977, 0xdf826ad5, 0xd9bc94ba, 0x695f5f48,
- 0x4fc8d11c, 0x98fca55f, 0x4871dce8, 0xf22bf822, 0x4b3fe955, 0xe558bfc0,
- 0xc62e3cda, 0x61bf5f23, 0xc3df0419, 0xd113e7cd, 0x69a6fdae, 0xfbae0fce,
- 0xb7bf2540, 0xebe009a5, 0x52882f7d, 0x71ed6966, 0x965f5856, 0xffe0c738,
- 0x12a291de, 0x6fdf2cf6, 0x57927fc7, 0x17e8077e, 0x4f9800c7, 0x0ee48b49,
- 0xe9ae3f40, 0x20ea0bae, 0xfb1233d4, 0xc91e27dc, 0x7a5ee7d8, 0xbdf346f6,
- 0xe3865959, 0xeee47824, 0x7ca89f6d, 0xbdb963ee, 0x7ee7c03d, 0x03ff3e93,
- 0x3f69699e, 0x3956b227, 0x4c7980bf, 0x7429cd5d, 0x9682e25e, 0x00ebb1e3,
- 0x3e3c39d8, 0x7baf64c3, 0x77342e22, 0xf59ca3a6, 0xebd96f5f, 0x251f449d,
- 0x215f8f4d, 0xf269b63f, 0xcdfa7505, 0x47787fd7, 0x71dbdd27, 0x859ed341,
- 0xb69754fe, 0x50f11d3d, 0xe79706f6, 0x941c2aff, 0x601b85e7, 0x65e7c021,
- 0x24e89e92, 0x7144be5b, 0x3c63ae81, 0xfcd6502e, 0xded3c912, 0x29971e16,
- 0x84e5b557, 0xa2a31c63, 0x59e515a3, 0x93f7046f, 0x09bdc4ca, 0x1e84e2e3,
- 0xe344f754, 0xd8b70e79, 0x3bfc5627, 0xf90187bc, 0x2ae55cb5, 0xf4a5fca1,
- 0x2dfb8640, 0xe19f9117, 0x3195fcf9, 0xbfce91eb, 0x8d1a0e72, 0xf4bdf1f2,
- 0x1c5197bf, 0x66810fef, 0xd911ec99, 0x6fbc2f27, 0x27994e1d, 0xaec530c8,
- 0x8bc9f409, 0xee5ad72e, 0x38f67b21, 0x1f2b7fdf, 0xbd89f9ce, 0x74a9f9ce,
- 0x846d61ed, 0x820d78d7, 0x6efb149f, 0x4efe1fca, 0xd138797c, 0x92f91c76,
- 0x78e215ce, 0x929c0311, 0x7965da24, 0x2d8d1bf6, 0x95cfafc2, 0x93797de9,
- 0x8e5f70cc, 0x2f289845, 0x53559720, 0xe614e57e, 0x339b471a, 0xf127f6ea,
- 0x7fa99b5e, 0xfe60c790, 0xb441f816, 0x60139d7f, 0xa6fcc78f, 0xc0492ad3,
- 0xc33195d5, 0x87e99f4b, 0x4e353d73, 0xf58f4896, 0x9d920644, 0xe9767932,
- 0x69fb6f3c, 0x83b78ab4, 0x626ec871, 0xae7e1ece, 0xee93ddc6, 0xacc8ef7d,
- 0x9056043f, 0x8cae645e, 0x89df5e59, 0xe6f5ce1c, 0x06ffdc55, 0xfb17293a,
- 0x77f2d9ac, 0xbd3da0cf, 0x5fdf10fc, 0xf98aad3c, 0xe8b3f318, 0xe784b6dc,
- 0x7939f9a3, 0xbc366766, 0x6d2baf67, 0x2a079d10, 0xcc3123df, 0xd66b2b73,
- 0x5138c76d, 0x0c3da699, 0xd36379e9, 0xe7a45a47, 0x4d77dc72, 0x79abe7e3,
- 0x724f5cdc, 0x48ccdcbc, 0x2536957f, 0xbbf18c7d, 0x8b5c63d2, 0x924faa96,
- 0x1b728e7f, 0xb8dc57bf, 0x12f1fc97, 0xbc7f26e6, 0x6e97c1a4, 0x8ffa237a,
- 0xb70e47df, 0x3233dcf8, 0x8fe72b79, 0x325ee259, 0x93b0e226, 0xbd6bc223,
- 0x0a4531cf, 0xcee4d83c, 0x74c76875, 0xbc564ac7, 0xc03ba697, 0x23ed16b1,
- 0x6bb72247, 0x9ddcdfba, 0x8be494b1, 0x34dee333, 0xdb8757bc, 0x6c3793b1,
- 0xf35ecb51, 0xe3ee2c99, 0x05600eeb, 0xf6ef0807, 0x908f8821, 0xe1a8bca4,
- 0x9e3ee883, 0x7c607713, 0xf27b9c48, 0x446fc75f, 0x38b8e85c, 0x7bcca9bf,
- 0x9714546a, 0x7449cc67, 0x19ce2ad4, 0x4a367929, 0x1eb10aff, 0x3d077ec5,
- 0xfb43fe1d, 0x934fb825, 0xf269f62f, 0xbe4d3ec5, 0x17c9a7d8, 0x62f934fb,
- 0xec5f269f, 0x7d8be4d3, 0x4fb17c9a, 0x69f62f93, 0x0d3ec5f2, 0x54e2c3e5,
- 0x11cdff31, 0xd1ea34fb, 0xc1b5e456, 0x10e9fa9e, 0xdf60fabf, 0x2443a7f6,
- 0x8960fadf, 0x257c4fda, 0x118769f6, 0x2166a3e3, 0x547c789f, 0x2a79df39,
- 0xe1193ed0, 0xfce79cac, 0x03a9f72a, 0x42934fc8, 0xd9bf90e6, 0xca26fe0b,
- 0xf6e1caa3, 0xec776c3c, 0x2df8c4d8, 0x140d2724, 0xe0fd3ce7, 0x98739f08,
- 0xacc793e3, 0xc6307bc5, 0x7e71251b, 0x9e647abc, 0x38c1ffe2, 0x66165b13,
- 0x307cb9a8, 0x2d9cbda3, 0x77e3e497, 0xc61a4796, 0x24d61ca0, 0xf70ee7db,
- 0x8339db92, 0x5da3c597, 0x7cb1aad4, 0xc75af18c, 0xbf3a1a07, 0x94f5c4ab,
- 0x8d25ef76, 0x937ec42f, 0x8ed6e393, 0xfcf5f1c6, 0x969b38be, 0x6cfce035,
- 0xee8940aa, 0x3516616e, 0xe1c283ca, 0x58266e9c, 0xd6ec7db8, 0x1821d45a,
- 0x1f18098f, 0xad13798a, 0x04c7cf02, 0x3c0b8f9e, 0xa4d77ee3, 0x85dfbe04,
- 0x6177ee25, 0xd58de4a9, 0x1f2de4a5, 0x27b4f24e, 0xc4ace11a, 0xe728a6fd,
- 0xee8b98fc, 0xd0517c33, 0xbe70d26d, 0x7261f2cf, 0x09c3a3de, 0xb73a2e3f,
- 0x69e22c59, 0x437f629d, 0xcfd2a759, 0xfbf19fd3, 0x0732465c, 0x83b367ee,
- 0x08764f22, 0x9f5023d8, 0xe49c3079, 0x7a1e7290, 0x07ee18e6, 0xfce27db0,
- 0x13258462, 0xc44aa3f9, 0xfc9cbb53, 0x48696d1c, 0x239e225b, 0xa57c12e8,
- 0xd17395d4, 0x6ea1a3a5, 0x284b9cf4, 0x8896d99d, 0x24ba12e7, 0x0dce8a83,
- 0x4fefe76f, 0x8d2bbe09, 0xf729e315, 0xd15de84e, 0x43ee8788, 0xbcf1a307,
- 0x7ba326dd, 0x6efb9729, 0x2811de7e, 0x3a96f316, 0xcc19d725, 0xf7747dcf,
- 0x1e63f71b, 0xf5c6a77d, 0xdb1fd622, 0xcc7ee87d, 0xf694edcf, 0xbf7b319e,
- 0xc68ae41f, 0x7747ddfc, 0x83f7f0b7, 0x6c18bef6, 0x5e6baaf5, 0xb5ef833b,
- 0x8fdd0e6b, 0x7553bcf9, 0x489563ce, 0x74e7bf2f, 0xffb3d865, 0xb8adc21c,
- 0x13eddb99, 0xf4bfecf6, 0xfde5ea1a, 0x3fefda26, 0xe0863c38, 0xf2fcd55d,
- 0xaeb3a466, 0xbfde3cbd, 0x17a3e1a9, 0x74ed417f, 0x54dc0d74, 0xc1832b9d,
- 0x9eecd677, 0x1a9af34b, 0xeb1afae8, 0x46388d4f, 0x903a98f3, 0x11d6f3f3,
- 0xe78fddef, 0xeff6ba01, 0x6ef90479, 0x683000ea, 0xf9bb3e71, 0x7da2a0f9,
- 0xbfd09329, 0xcdb532ef, 0x5ecbf1c7, 0xf339d1d1, 0x74e17da2, 0xc3dbc72f,
- 0x9939f963, 0xa8d1d5e1, 0xefaf5567, 0x508bf1da, 0xfda0676c, 0x6e10f29e,
- 0xb5c915e7, 0xfe110f59, 0x3cf1da5e, 0x81977bce, 0x310b5ff6, 0xc2f502a6,
- 0xa714091d, 0x5f1fe37f, 0x643c47cc, 0x7ce8dbcb, 0x0675d7cf, 0x94e1c215,
- 0xcf0036d6, 0x694e38d3, 0x142cdfc8, 0xfcd3c2f5, 0x60517dbc, 0x2fe10e7b,
- 0xf51a3ab4, 0x47c0d16c, 0xa7bce3a7, 0xa22fd5ca, 0xe65ec3bf, 0xd85dc6f7,
- 0x7e837005, 0x9435ea17, 0xcbb5daad, 0x3be2e744, 0x78f9eaa5, 0x9ea3893f,
- 0x5434ebb7, 0xf51d3c13, 0xb4defc49, 0x48e8305d, 0xe7c5b76c, 0x97fa85f9,
- 0xbd1fd1d3, 0xf254caf8, 0x55fa154b, 0xcea8a5f8, 0x3f1d7cff, 0xfe245ab7,
- 0x33076666, 0x2e93c57a, 0xebae781e, 0xffd3ccb7, 0xce868362, 0xd8ea1779,
- 0x560fcc5a, 0xea28a1f8, 0x5f5c5cae, 0x1136aa91, 0x31c296ed, 0x2f91f3ed,
- 0x3e98182e, 0x27bdda02, 0xe35155f4, 0xff6819ea, 0xa63e68de, 0xbf8f9c11,
- 0xeb7ae089, 0xd383269b, 0xbfd1bf7b, 0x9992b4fc, 0xd4f04fdf, 0x7be15a7f,
- 0xad3df0de, 0xb4fd04ab, 0x3f2e10b2, 0xbc7b40ce, 0x7c502e93, 0xbf4ac167,
- 0x78239273, 0xb699645e, 0x9ef5113d, 0x863ffe32, 0xa85db99b, 0xb7fba76e,
- 0x454dfbfc, 0xc8e50473, 0xb79e7e6e, 0xa0ea51a8, 0x52082273, 0x8b667baf,
- 0xe6270ef4, 0x8787f509, 0x07812c88, 0x11b9eb18, 0xa28f3431, 0x079d0306,
- 0x0f680e2f, 0xc4a93b42, 0xf6841ed4, 0x32ebd74f, 0xe889c3dd, 0x8fc6550b,
- 0x894f7cf5, 0x34ba1613, 0xdf7f4336, 0x1c60e583, 0x0dfe1972, 0x047578a0,
- 0x682a27df, 0xcfe7e40a, 0x1e74edcd, 0x263cffdb, 0xc5ecd3ae, 0x2f4d5d8f,
- 0xe9fb7985, 0x797047a3, 0x10752dd0, 0xe3ff74df, 0x83a468f3, 0x8b5b1522,
- 0x251795fb, 0xea022e7e, 0xa2e21e74, 0xfa2cf7d8, 0xf48018d6, 0x129bf173,
- 0xa92ee3e2, 0xfb5ce49d, 0x7c933fee, 0x93b4d2e8, 0xc468fb9c, 0xe8fc937f,
- 0x8f9f6e0a, 0x447dab72, 0xd91f7f0f, 0x23cf1f3e, 0x7c7589bd, 0x81fff78f,
- 0xfddaeffe, 0xefa8fded, 0x8f3ccaa7, 0x31a4bd82, 0x8710f8f3, 0x270132f7,
- 0xae9c36c6, 0x6343ff24, 0x2dd0fd41, 0x166f03e8, 0x98fe5e64, 0xcc5d4fc2,
- 0xf911a7b2, 0xc7df80b3, 0xc3557603, 0xcdff686b, 0x84fba309, 0xeca6e1fc,
- 0xfc868633, 0x69e2296d, 0xc0fec986, 0x69538008, 0x17f93b6a, 0x87a4ed40,
- 0x91d4deca, 0xe9add99f, 0x2bf281d9, 0x8b9f64c5, 0x6db44aed, 0xbc2433eb,
- 0x15bda0a7, 0xca29fa4d, 0x3997c7f9, 0xbea575bd, 0x884dcfc4, 0x8162ca7d,
- 0xb25bbc07, 0xe243e916, 0x69ab7e78, 0x6f28fbdf, 0x48e2daba, 0xd3f3fb4e,
- 0xe8a7a685, 0x404f8a9e, 0xe2bc3baf, 0x7c2c9f00, 0x6601f299, 0xf1881e63,
- 0xbdbe73fa, 0xfe4bdddf, 0xf5ecdb20, 0xc6b1e91c, 0x170feeb7, 0x0fb74ba4,
- 0xde68381f, 0x00df903b, 0xda13c5fe, 0xbe877ee8, 0xcba84cfa, 0x7e23f55e,
- 0x78f6bf75, 0x0fda005f, 0x505d843b, 0x9a7dd432, 0x3c3df7fc, 0xf40ab76f,
- 0x07f7d51a, 0x6aa57e52, 0x50ade80f, 0x5f50b7ae, 0x51b50714, 0xbf6baadc,
- 0xd779f68e, 0xc68f9f34, 0x523d03f5, 0xf9b8a67c, 0x7ccbdd20, 0x4c87fd10,
- 0x94618fd2, 0x39bfb317, 0xe510fd0c, 0x95ca8979, 0xd3f5f228, 0xcf287e51,
- 0x2277654b, 0xda95f39d, 0x8388fee8, 0x2a25de62, 0x1758cba8, 0xdf3896f3,
- 0x2f7e66b3, 0x5ede3f96, 0x76edc119, 0x9f740f90, 0x79d79ae7, 0x079140dc,
- 0x1cae4285, 0x9ca9e7c1, 0x3ecacdff, 0x442d7411, 0x4e47efbe, 0x0b308f24,
- 0xe282b87f, 0x58463b3a, 0xa7f45d78, 0x89dc7971, 0xd1bd97de, 0x8a9b1e99,
- 0x3dca2cfd, 0x14791e5f, 0x282f91e7, 0x0e482207, 0xc184d1ac, 0x945e8aba,
- 0xc2a2fee8, 0xa073ab79, 0x7ea65b39, 0x2d49ee88, 0xe35bbcc0, 0xa7f2f3f5,
- 0x57b8f1a3, 0xec52f288, 0xe0ed1503, 0x351740fb, 0xe40d1f7c, 0x2ff5e50d,
- 0x073ab49b, 0x68496ff9, 0x4fdbd6a9, 0xd7f8d9be, 0x58af5b9d, 0x0fde139d,
- 0xdcad179f, 0x5d883ad2, 0xbda15e3f, 0x72cc2736, 0xde6573fd, 0x3cca0d17,
- 0x79066827, 0xeaf663c3, 0x734fbc1c, 0x85dffe99, 0xc5f75f07, 0xf51b9d66,
- 0xf697c02e, 0x56bcee83, 0xbd5f13e1, 0xcc8578d9, 0x371ffb49, 0x597fbf9a,
- 0x534fb922, 0x57f02d5e, 0xf9d9f13d, 0xa0fdef68, 0xf6be4229, 0x160a25c5,
- 0x407ba30e, 0x79870bec, 0x4bfc25c7, 0x55839410, 0xa0e23394, 0xbe70f812,
- 0x28781fb5, 0x0467ffed, 0x329a4fcf, 0xe0d5f382, 0xbdcfc5a9, 0xa39e28c6,
- 0xe3741d4e, 0x54a621f3, 0x7cb74fce, 0x2062643e, 0x60c8776f, 0xf74fb8c6,
- 0x5c51bfa1, 0x719d7bb8, 0x306fdf36, 0xdf7848b2, 0xddb6911a, 0x8afbfe3b,
- 0xe7814738, 0x7efce9be, 0xe387e6b2, 0xbea6a94a, 0x1bd912b8, 0xcfb481a9,
- 0x9574d5d2, 0x4b775bf4, 0x43f719a6, 0x469cdaba, 0x7ff2b7e4, 0xea184ffc,
- 0xb396aee1, 0xf5d69794, 0x57ca79dd, 0x06f228db, 0x7c89348f, 0x098b36af,
- 0x7ee7779f, 0x36ed8391, 0x5713d289, 0xa53171e0, 0x2565fc54, 0xff75e07e,
- 0x6b8428d1, 0x93e379bd, 0xa60f3019, 0x1ddfa6af, 0x0439ff00, 0xae2787f5,
- 0xa1ff0960, 0x2b8c4a3c, 0xb8f027c4, 0x57189602, 0xb8f0d788, 0xae31d602,
- 0x15c62580, 0x15c639f0, 0x05718eb0, 0x015c63ac, 0xc05718eb, 0xf80ae312,
- 0x8e716bfc, 0x378c1ba3, 0x9234f71e, 0xcf515ffc, 0x88576bf7, 0xd457a1fb,
- 0x85b7944a, 0x0f5038e7, 0xd3c7975e, 0x5c78f228, 0xb03f685b, 0x456cbf7c,
- 0x0f79e154, 0x79f30e87, 0x3c628e7a, 0x64af7ca8, 0xe7c16d5d, 0x1b1e69b3,
- 0x9e3f325b, 0x35ebcf87, 0xac97bc56, 0x309be5bb, 0xb515778c, 0x6adc53d4,
- 0x2d21f852, 0x6241b9e1, 0xa59d6f18, 0xa9727ee3, 0xd3474f0c, 0xd1d929be,
- 0xf236baa5, 0x4a778a5f, 0xddf3ef66, 0x90af63e5, 0x9bcbe89c, 0xf9cc1972,
- 0xc6d5fa3e, 0x4ff0aef3, 0x57d88fc4, 0xf49bca5e, 0x3d9159e5, 0x2d1f65e2,
- 0x7c64fdc5, 0xe7477f2e, 0xd1c14a4b, 0x93f5281d, 0xcfb7e587, 0x77b2d45c,
- 0xe29bde3d, 0x77dcdfbf, 0x9f6fcf5e, 0xd8aa6579, 0xcfc51e4f, 0x9d3ee489,
- 0x7c3f67bf, 0x475ab7af, 0x70e54af6, 0x266a657b, 0x28d86be6, 0x90f472ee,
- 0x2fadfc81, 0xc4f924b7, 0x21e5b25d, 0xae58f714, 0x6b8f4891, 0xb0ebed92,
- 0xc5dcc4df, 0x18996f14, 0x567e2261, 0xa4bdf0e8, 0xfdf1c7bc, 0xc50b34f2,
- 0xec75b2bb, 0xc89e3467, 0xf89282ef, 0xa24abb2d, 0x3217a97b, 0x597b9d2b,
- 0xf2f7e360, 0x2de8f729, 0x41cf3c60, 0x5be5aba1, 0x282bb224, 0xfb861100,
- 0x0b9e1c9d, 0x7ba1de5a, 0xc4eb164f, 0xbe2a7e3d, 0x89b51e1f, 0xc12cbfe7,
- 0xdef0a41b, 0x58abd010, 0xb37d9e82, 0x03db9e1d, 0x3b734487, 0xe38e12df,
- 0xa1ae3c2f, 0xf0ece13c, 0xa4ed13bb, 0x3e5127ef, 0xf6ef5e03, 0x921f88fd,
- 0x0cf9bea3, 0x43793547, 0x48addd70, 0xb1e714a7, 0xb2bc7953, 0x9e254a80,
- 0x762fe4a3, 0x17b83a1f, 0xce5d9fbf, 0xe1bde5ef, 0xfe80bd79, 0xe729adcf,
- 0xf9145e15, 0x53aa5175, 0x75fcf063, 0x2b46b7d4, 0xfc3b3fae, 0x8af79d10,
- 0x4e1fe313, 0xe5037bcc, 0x39882d8a, 0xcbee1fb0, 0x733c0354, 0xc6120170,
- 0x3c365dcd, 0x4873d337, 0xf51e5332, 0xcb73f275, 0x29efcc3a, 0xdee8978f,
- 0xea809cf0, 0x3f1830ec, 0x8ac63627, 0x89bcbbf2, 0xa0bb5dc7, 0xc3bf78e4,
- 0x3181f749, 0x14d73f7e, 0x2490b781, 0x4cd489fb, 0x82a9f3cf, 0xae5bba6f,
- 0x9be1fcf2, 0xe8eb65c7, 0xb06613be, 0x21b1f72a, 0x188ea7de, 0x8559f14a,
- 0xc21b7a6e, 0x7cdd23b7, 0xbcc3f42e, 0x68352779, 0x6c987c3f, 0x30e10cff,
- 0xbacaff3f, 0xff675a30, 0xcf2531f1, 0xa63e3fde, 0xabffedc8, 0x2bf7fafc,
- 0x513ca82b, 0xb6ca92b9, 0x07bd074a, 0xea75f0bd, 0xff55c5ad, 0x8ff5f08e,
- 0x65bd32ab, 0xe057e900, 0xf6c71e6f, 0x5f02a38b, 0x7af8bcab, 0xa2f04b62,
- 0xd47f680d, 0x4ffee968, 0x615e77cc, 0x49a03924, 0xaa9e37eb, 0xf148cdc0,
- 0x18665ed7, 0x909ff08d, 0xc156a71c, 0x926901fb, 0xf200fecf, 0xf90fae09,
- 0x13e44b04, 0xf3dc57b5, 0x70b02d05, 0x1c07b706, 0x08180f64, 0x8357ebaf,
- 0x1ef090fc, 0xfc8fb325, 0x3f27e4b8, 0x907971c0, 0xf0b57dce, 0xef2526fc,
- 0xd7140273, 0x4f23f746, 0x0c9e5c5c, 0xc2ed700d, 0x0b2d0cef, 0xa3e2bca0,
- 0x475f4e1a, 0xb9bcf237, 0xefc7967c, 0xae5eba6f, 0x163e2104, 0xf339ec0f,
- 0xfc5fb43c, 0x35d9232b, 0x669723eb, 0x257227fd, 0xc3c38d20, 0x63258131,
- 0xcacdf27e, 0xe045ee7e, 0x314e66f7, 0x2e5b9f91, 0x7cb2a0ec, 0x72a7f133,
- 0xed4cb43e, 0xed8f58ea, 0xff3c4d42, 0xbee8cd43, 0xc1aa5396, 0xc1599efc,
- 0xc4a6a767, 0x58605e51, 0xa887bf15, 0xee896ee7, 0xc8149e03, 0x56c857ef,
- 0x0cbc95e5, 0xb956dfef, 0x54c1efc5, 0x122bf8d3, 0x73d15c79, 0x6bdb951e,
- 0xba26b951, 0xbaf6413f, 0xc631a93f, 0x39f45eeb, 0x6ecfbefc, 0x4dff72a7,
- 0xa087bcde, 0x7e1ccd5f, 0xb33766cf, 0x03fb813c, 0x7100828e, 0xb5e8127f,
- 0x99fdcf0c, 0xedc9fe07, 0x15429ebc, 0x19ad539d, 0xeb8d5965, 0x42cc79aa,
- 0x27f73def, 0xe8dcf871, 0x82db9c3e, 0x8369f9ec, 0xe717bfae, 0xce6f2919,
- 0x669fec12, 0xe34ff7e4, 0xeed08de5, 0x4fe19ce8, 0x0e3840ec, 0x3da264b1,
- 0x706c68be, 0x11f40496, 0x06f306a5, 0xd4630fe8, 0x46d05f74, 0x71f313b5,
- 0x7dc5a887, 0xef216a01, 0xd180c861, 0x85a6ded4, 0x96a7c2fa, 0xabea1b31,
- 0xf3f74628, 0xfef9ebc6, 0x5863f438, 0x4646b862, 0x7c78c83d, 0x3e00e168,
- 0x4670c2fe, 0x45a5cfbf, 0x3bf25016, 0x2677f0b3, 0xb0bbc518, 0xea68d07f,
- 0xfef150ef, 0xc3943536, 0x523df8e2, 0xb474eb3d, 0xf1f0ba2f, 0xa71fa4a1,
- 0x773df04d, 0xe78d327f, 0xb8e5282d, 0x9f0f8b74, 0x429b5a2f, 0xd68b8bfb,
- 0x3b4529ce, 0x4810dec4, 0xef3b02e7, 0xef0ba97b, 0x9d962f71, 0xf5823f4b,
- 0x57b74ecc, 0x4a2f7c23, 0xa1fbf996, 0xdffba2c1, 0x8c9e62d2, 0xf2e335dd,
- 0x774e50eb, 0xf7813dec, 0x4fbf4de4, 0x19d3fea6, 0xad9a8fbf, 0xde6cf7e5,
- 0x8ea2b8ed, 0x1eeff180, 0xbcbc5127, 0x468e60c3, 0xc0a16efb, 0x5c69f3d7,
- 0x3f5c2f7e, 0xebfd1134, 0xbddf71bb, 0x5a733d1f, 0x0fde53b4, 0xfc7cc89b,
- 0xfbc54f9b, 0xfef8d34f, 0xfe38b0fc, 0xae837f3e, 0x4b082e23, 0x4a093b8d,
- 0x4ec2758d, 0x58b4cf5c, 0xe115b396, 0x378f28f8, 0x9b981876, 0x8d3eb1e8,
- 0x3d676ae0, 0x3ae38f1d, 0x3ad046ea, 0xa39bc63a, 0x710e5ee9, 0x3312eb7f,
- 0xe31d4f97, 0x98ce77f9, 0xa9214ddb, 0x1ef07f9c, 0xa502c5d7, 0x3d565767,
- 0x5bb41b79, 0xe74f4abc, 0x7d3c9735, 0x8b2bf92f, 0xa73a646b, 0xdefb36c9,
- 0xc4fa0ae3, 0xbff3f38d, 0xdeffd58f, 0xd239c455, 0x8966fe41, 0x955868e8,
- 0xf1fb8b55, 0x4ec05b3d, 0x46f9f780, 0x05da3c77, 0x758356f9, 0xbdcfd48d,
- 0xdc01dfac, 0x6b9ef0b2, 0xcf93f146, 0xe01fedd3, 0x2f561777, 0x03507ba4,
- 0x1714ed53, 0x217e061b, 0x48413fda, 0x69d7003f, 0x7fba5e00, 0x891edd42,
- 0x34facffe, 0x9cc43cf1, 0x34ba2468, 0x0ee7e430, 0xe711398d, 0xa0ceb1d7,
- 0x6d319942, 0xe04fa70d, 0x347abd1b, 0x0160339e, 0x4bbfbfc8, 0x6f3974e3,
- 0x16af3ab5, 0x6d4043ea, 0x6e90429b, 0x4e7d1146, 0x50ebdab6, 0x18f57daf,
- 0x73728b1b, 0x7c2de6f1, 0x4cff025e, 0x34e746dd, 0x198faabf, 0x0a06798d,
- 0x4eb64c3d, 0x4de69b38, 0x8449f707, 0x31cf587f, 0xeb1a37d4, 0x2f5c4ea2,
- 0xf48c3f3c, 0x9b826d31, 0xe5b212f2, 0xbcfdfa12, 0xf74608de, 0xce32f4f2,
- 0xd41bbdaf, 0x391467a4, 0xa003c8a1, 0xd39e1b07, 0x7ffdf055, 0xf2287f65,
- 0x7243e006, 0x8a1b9145, 0x4be8517c, 0x74fe3391, 0x7cc01f35, 0x4fea68e7,
- 0x63914cf2, 0x68d50eb8, 0xf0517c8f, 0x5e30d9ac, 0x81577145, 0xd2f96ce7,
- 0x8708839e, 0x2dd92302, 0xea31707d, 0x5ad12e09, 0xcff784d6, 0xb7943d56,
- 0xe3d22977, 0xd063732f, 0xe05b98fe, 0xa7f29e7b, 0x28e7be15, 0x3df4ac17,
- 0xe56f3947, 0xfc628e9f, 0x0fb00d89, 0x9cfc074b, 0x17b9e5f9, 0xefea863e,
- 0x8131797e, 0xea97d9fb, 0xaeefc59f, 0x68f3100a, 0xa55af3e7, 0x4c31bd25,
- 0x0ff881d8, 0x7188b2f1, 0x13185d3e, 0xdff5027c, 0x093f105f, 0xf1c1ffb8,
- 0x67e04673, 0xe80fc211, 0xae3ae17e, 0x121c3a97, 0xad1623c5, 0xc1ba7c15,
- 0xe7f47cf7, 0x303dac91, 0xfa8e73ce, 0xa312c7f3, 0x7395af91, 0xfc0df6d3,
- 0xf2b4b55c, 0x762fd918, 0x872d7ee5, 0x2b5afddf, 0xebf9f95b, 0xcd73df76,
- 0x2d361981, 0xf7182bc5, 0x1f2516a3, 0xd536f9e1, 0xbbf71992, 0xfcf3c5f3,
- 0xb9cf920d, 0x1e749cb9, 0xa698da17, 0xa3b63c26, 0xcaf1429d, 0x0a2fd26a,
- 0xa0dc829d, 0xd5f97c73, 0xbd4bb4a3, 0xf122e8e4, 0xcab2717c, 0x36d777e7,
- 0xebfdf1a6, 0x181a6476, 0xac725377, 0x3bc90976, 0x9547c50b, 0x47928bf6,
- 0xc1b8c7af, 0xebf8cda2, 0x33fe9e47, 0x367cf9d3, 0xdc94f98a, 0xe5f7ce40,
- 0xb79fe155, 0x9fc9bcd3, 0xf7757a2e, 0x033bf8ab, 0x91d57f45, 0x291a299e,
- 0x9d53d9f6, 0x3ed2f759, 0x55d73f32, 0x693df026, 0xe84167f7, 0xf2379427,
- 0xeca1b2fb, 0x556cb2c0, 0x65fbf901, 0x9087e056, 0xdfbff3eb, 0x41aff57e,
- 0x88ecbe3c, 0x47ffbf12, 0xd65563bf, 0x1fc505f8, 0x64772ed0, 0x4f9478d0,
- 0x5cbfdfee, 0xfb882efa, 0x9704edb1, 0x84df43ec, 0x5ff63cd1, 0xf979b8a5,
- 0xf66175a1, 0xdd7dd67e, 0xcf110139, 0x2af81728, 0xe0af9b67, 0xaaf95afe,
- 0xc82cf3dc, 0xbf7fbe33, 0xce22e975, 0x8dbb1b70, 0x4cd5d6f2, 0x5ccf7de5,
- 0x07e133af, 0xb7cb25f3, 0xbd9d73f2, 0xdc00cb6a, 0xe716eb97, 0x1ddbfcb4,
- 0xc37ee74f, 0x0c27e065, 0xc8377444, 0xddd3cfb4, 0x6578e3c0, 0xe2b54f0d,
- 0x7032d8f9, 0x959d919c, 0x8d654473, 0xeb7bd332, 0x1a47cc35, 0x1679e378,
- 0xfdd136ef, 0xc92e8534, 0xe9f30f56, 0x90697f05, 0x165e7cd7, 0x73ac5574,
- 0xcaf8e165, 0x72105ffc, 0xd857694c, 0xb79d14f2, 0x645d7685, 0x903efc9f,
- 0x9eb2fdf1, 0xcecf3813, 0x7f68636d, 0xb7b5d0ab, 0x0d8fe28c, 0x72b79481,
- 0x7e7be351, 0xdef89f7b, 0x676e74be, 0x24de6274, 0xa6557ff6, 0x13ce19b8,
- 0xe4a2f1f9, 0x2cd1cf9b, 0x73a735fa, 0x3a7e653b, 0x7da503e7, 0x2823aba1,
- 0x6f9fda1e, 0x6f9513fa, 0x6f7c7b61, 0xbd474b6c, 0x9031be79, 0x6f9ed3ce,
- 0x0de73e7c, 0xd765def8, 0x8bc950f8, 0xf3a74ebf, 0x6de5e5f8, 0x73b05ce2,
- 0xe26738a0, 0x3674f5a2, 0x5fe84944, 0xaffc8a96, 0x417dc6ce, 0xc75fe22a,
- 0x627bf67f, 0xefbbafb3, 0x264c77ac, 0xf76cbf9e, 0x7fecefb9, 0xf132fc6b,
- 0x13caa8dc, 0xb7bfe1df, 0x5ddf94ca, 0x4a76f331, 0x48fe763c, 0x0e7803cb,
- 0x7fc7bd97, 0xfeec0d97, 0x9a3fd167, 0xe481c7ff, 0xadefe27f, 0xf7ebfd60,
- 0xfcd9bef9, 0x44ae4231, 0x4cbe53b4, 0x1fb70c47, 0xcc48364a, 0x062b7006,
- 0x680072fa, 0xb3329c4b, 0x231dfde3, 0x2772fef9, 0x2476bfd0, 0x67ca0bc9,
- 0x1dfe0339, 0x6bc10efd, 0x24b93f7c, 0xe7889dd6, 0x5e453b03, 0x3b884941,
- 0x7b8c2071, 0xc949d049, 0xb7a2774c, 0xddb2537f, 0x9735794d, 0xbe1d3e44,
- 0xc95e78c7, 0x23aede68, 0xe745dcc6, 0x189bf638, 0x83aaabda, 0xd2c3a226,
- 0xbddb0d97, 0x4699d5cf, 0x92fffb72, 0xee1bdf96, 0x53e7c1d8, 0xe34d5418,
- 0x5df4125c, 0xf34d5018, 0x29ce233b, 0xbd796a17, 0xbee8c343, 0xfc5d9efe,
- 0x918ba13e, 0x3bf0076d, 0x50a57717, 0x8c4769de, 0xbd136973, 0x452679e7,
- 0x38dce8af, 0x4cbb0baf, 0xf7282e74, 0x9f695b97, 0x274eb7b1, 0xc2e1dc61,
- 0x1ee74620, 0x220fd42e, 0xb2417d7d, 0xc2f37c50, 0xbc6903bb, 0x7495caa2,
- 0xc408a5be, 0x509dda04, 0x76bda2e6, 0x68b9fea1, 0x6fa85fe4, 0x559dbac0,
- 0xf239ffcf, 0xbbfe4ee9, 0xf95f1710, 0xbef78a7b, 0xeffa528f, 0x54f8289f,
- 0xe48da7de, 0x923698fc, 0x91a8f3f3, 0x3bde7e66, 0x2c4cf5d0, 0x37f38fad,
- 0x02fc99c0, 0xafba27e0, 0x39ab8ce7, 0x8a71824c, 0xa86c9a0e, 0xee343bdf,
- 0x0e09e7c4, 0x7877e281, 0x1785f918, 0xbf240c76, 0x1a68ac1c, 0x348ec2e7,
- 0xf252d3ca, 0xada1a64d, 0x234c7846, 0xdbcb66f8, 0xe5fee9d2, 0xc7ca40ba,
- 0x36fc7a29, 0xc89fe515, 0x7a2eeedc, 0x5134f175, 0x4d7ee1b7, 0xa17fcfd1,
- 0x93e28bc0, 0x89695e4a, 0x8fa5a390, 0xf30031df, 0x651fd970, 0xaabb93ca,
- 0xfe8f79e6, 0x48e5f970, 0xbc0f4721, 0x025b7c40, 0xc3bf8e74, 0xc2f22c54,
- 0x71e15f8b, 0x77f5e296, 0xf1f24b3c, 0xde618684, 0x53d725ef, 0x2f70de41,
- 0x96e5c918, 0xda95bfa7, 0xde7b4317, 0x9a20bdff, 0xe50d0ecf, 0xebe3fb29,
- 0x22bffb96, 0x8bfd5bff, 0xf407605c, 0x957c1fb3, 0x57f23db5, 0x060d0394,
- 0xf29e83ab, 0x8d4ebdfc, 0xdf3f296b, 0xd0f92060, 0xaf7e2c19, 0x11e792b5,
- 0xfa9faf14, 0x3857ca6b, 0x699d2f75, 0x7fece65a, 0xa474aebf, 0x0f8bef86,
- 0x3e400eb4, 0xe07c052c, 0x3a1f8078, 0xa8fece5f, 0xebfefea1, 0xcb923a99,
- 0xdc3e3ef5, 0x3ba1f3c3, 0x74bc7307, 0x7a449abe, 0xd39823a7, 0xfc97cc35,
- 0x5e60ced4, 0xe604a252, 0x3d3998df, 0x91778e74, 0xed29ddff, 0xc343b2a5,
- 0x14ad15fb, 0xe6e22bbf, 0x482523f9, 0xff7871b3, 0xb436e6cf, 0x671e503b,
- 0xadd2a68d, 0x1efeb90b, 0xf263a076, 0x7e0a8eef, 0xe870f252, 0xae280177,
- 0x3ca2d2e9, 0xafbb0bb5, 0xdffae1a4, 0xefe7e08b, 0xae43ca25, 0xfb29291b,
- 0x540794ec, 0x2b3c25cc, 0x9fb44876, 0xa1f6bc5f, 0xe2fba442, 0x91732d8a,
- 0x1475941f, 0xfa2e59ab, 0x4c921d49, 0x7ebf01f3, 0xebd4ccc1, 0xf7c0a7bf,
- 0x197ccaf7, 0x3d27cfdf, 0x6fb6bc03, 0x53b145a4, 0x578c3559, 0x4cda56b2,
- 0xfc5189df, 0x053ebe4e, 0x83efb84e, 0x3c4a8cf9, 0x57eb46e0, 0xf9a379e6,
- 0x75e423bc, 0xd7e58c47, 0x1fdf10e3, 0xae4f24c8, 0x4066377e, 0x6dd80fc8,
- 0xcaa14bf4, 0x0fff3078, 0x38c11751, 0x56790acf, 0x79c3f30c, 0xfdf36e26,
- 0x3ae4807d, 0x06f0fadf, 0xa36a7adf, 0xc5bd3d6f, 0xdb7d6eb7, 0xdf82deb7,
- 0x09c0f4cd, 0x073c61fd, 0x879c53b1, 0xcf187f40, 0x8c3fa133, 0xb187f475,
- 0x9f187f44, 0x758c3fa3, 0x8eb187f4, 0x8925b0fe, 0xa258c3fb, 0x65cf8c3f,
- 0x4953872b, 0x023f8f2d, 0x2fb46c1e, 0x5df9473f, 0xd10bf00a, 0x421c2d1e,
- 0x7cc61d76, 0x7e9577e9, 0xd2296d79, 0xfd930cd1, 0xcc4cc8d2, 0x1f5b6ac7,
- 0xf2fded89, 0x1b464a94, 0x686f188c, 0x3d7e775f, 0x2629219a, 0xaf6c15fb,
- 0xae952fe4, 0x4f7e8b7c, 0xe5b57daf, 0x78e13f8f, 0xf287b8a2, 0x78454f7b,
- 0x714cbe4f, 0xf8a33d2e, 0xdfdf559e, 0xf9fedc3d, 0x679ab746, 0x5801fff4,
- 0x00db8bbb, 0x0000db8b, 0x00088b1f, 0x00000000, 0x7ccdff00, 0xd594740b,
- 0xe6feefbd, 0x49324995, 0x41e42126, 0x21e4cc20, 0x49389311, 0x47114bc8,
- 0xa8d53048, 0x684d43c3, 0x4092138c, 0xa3c30480, 0x7b96c4eb, 0xa4401833,
- 0x51b78d70, 0xa13a3951, 0xe85de94a, 0xb6950a09, 0x1006739c, 0x4e6d8ac5,
- 0xb6abad5b, 0xa9078838, 0x68349687, 0x69edec57, 0xdff7ffef, 0xbef997df,
- 0xbc7b5249, 0xacdd77ab, 0x7bfe7ba5, 0xfe3f6fef, 0xeffffdef, 0xfc42108d,
- 0xfb5bfe85, 0xdaf08c7c, 0x85fdff05, 0x442fdfff, 0x59cf10b9, 0x0e9d3247,
- 0xd77c2e21, 0x4f5c5bbe, 0x1868ac65, 0x06e6a42a, 0x09a449bb, 0xb8df11b1,
- 0x5335a884, 0xef0479a7, 0x28c7f651, 0xa4f34c42, 0x885d3108, 0x49f933d1,
- 0x05fffa82, 0x2c4f377f, 0xa8cac75b, 0xadde0eb3, 0x6ccf3098, 0x548af09b,
- 0x735dfb1a, 0x4f1a05f0, 0xa24d79d4, 0xea4d8842, 0x35ece71a, 0x59105109,
- 0x38c1b5ef, 0xbfeb7421, 0x018a60ee, 0x619a1a2e, 0xb1fd7fe8, 0x497b431c,
- 0xbda1ae68, 0x13d6f96d, 0x962144e6, 0xf4332eed, 0xbc116abb, 0xa7cfabcf,
- 0xea6e0307, 0xf0d1bbe7, 0x3aea109d, 0x936eb29d, 0xc3fce475, 0xd1d37fd4,
- 0xe3004f4c, 0x2f0b35ee, 0x8d03b7ed, 0x2b6442a5, 0x4f181d81, 0x179e2a0c,
- 0x6a56bc68, 0xe8bb53f7, 0x9d38f3b1, 0x2c3b7e2a, 0x2da4e022, 0x9bf3447d,
- 0xd1e77fa9, 0xc256e0f4, 0xc9c61f4b, 0xf0a776a4, 0x6b78d326, 0x87170ee6,
- 0x6f359c68, 0xd042bb7e, 0x83ccbb16, 0x215cced9, 0x03c12b36, 0x9f10b34e,
- 0xab4e1ca4, 0xd98776a6, 0xf443c8bf, 0xfca67cb9, 0xe78455c7, 0x1ecc87cb,
- 0x0d6d93cc, 0x291295a5, 0xab268385, 0x038cec06, 0xcdfb07fd, 0x63a24175,
- 0x9cc3ad16, 0xc18fe112, 0x797169fe, 0x35bec88e, 0x0b6d987e, 0x7d84dccd,
- 0x79eb1cbd, 0x0a3f8041, 0x9dbc62ef, 0x8fe02b31, 0x80945b8e, 0x3ec8faed,
- 0x77e53a37, 0xea3e7eda, 0x7c0632a5, 0xdb3e65e6, 0xbe5fb6ac, 0x8bb144f6,
- 0x7bd9d1f6, 0x2c4cdb2c, 0xe874ceb0, 0x01952640, 0xfb19bfbb, 0xffcc18e9,
- 0x679a7cc5, 0x61663bed, 0x3efffea6, 0x9ab128b0, 0x8bc9f7f6, 0xc13d4f56,
- 0xdb7ff70f, 0xac7da616, 0x1e6d04b5, 0x3bbe3b2a, 0x7952f368, 0xae41c1eb,
- 0x65b0755f, 0xb575f831, 0x7d81dee8, 0xbf12b25f, 0xb1d1f0eb, 0xa4e7d950,
- 0x31eebf75, 0xc4777f31, 0x6bda3f09, 0xa74ff3cd, 0x95077f62, 0xb97b2c12,
- 0x85adb0ef, 0x7ed47bea, 0x7a32f2d1, 0x74ed5976, 0xa43a3fea, 0x92a7de30,
- 0xd743bb8f, 0x1b2c7cb2, 0x7cb97373, 0x88213aec, 0xbe11df25, 0xa5744122,
- 0x3ef01ab5, 0xfcccd67a, 0x1cdc7a39, 0x8749f414, 0x0cba942d, 0x2b17f874,
- 0xf88ba1d3, 0xa4f88aa7, 0x40df7e8b, 0xd9be6fa5, 0xd40fbfc0, 0xbdf81bc4,
- 0x88e4e841, 0xcc47bbc6, 0xebcbc030, 0xeffd0d73, 0x945d7e5d, 0xda46943c,
- 0x0dfff8cd, 0xbb827691, 0x4a5c04b6, 0xc685a022, 0x30b72a7a, 0xf866dd9f,
- 0x8d2c4bbe, 0x3f9f03f4, 0x678c6fff, 0x4b6d8621, 0x26bf688b, 0xafd107a2,
- 0xad5e7fc1, 0x6d3d730f, 0xb39720c4, 0x98bf3d73, 0xf2317c4f, 0x47ec55b6,
- 0xdf089fc5, 0x7f46e815, 0x20e913b9, 0x9d5a1104, 0xb1d68937, 0xa9c908fe,
- 0x618a5f41, 0x06eb17d0, 0x74b6ba1d, 0x2a628bd4, 0xb4059be9, 0xb0c0ae8f,
- 0xf8c1dbad, 0x4a1164b7, 0xa22bf7d6, 0xdbfb8527, 0xbc2452b3, 0xac47f505,
- 0xf875861f, 0x686378c3, 0x816e633f, 0xafb744bc, 0xac0b7da7, 0x3dfeec47,
- 0x2dfad5f4, 0xde631f75, 0xea3cdaf5, 0xae9f1af8, 0xebdf4bde, 0x9e3d1dd6,
- 0x72c5c4a3, 0xe1e0f6bd, 0x7e1067d7, 0x4b92f996, 0x439d4720, 0x852dac4b,
- 0xd34df913, 0x9a0f57fb, 0xf06e3183, 0xb7e629df, 0x8f5683d1, 0xb2f01bf8,
- 0x0f182bde, 0x8ab87cd1, 0xf9a765f6, 0x3c511d57, 0x03f64541, 0xf146d67e,
- 0x9acdc627, 0xbe1a6f04, 0xd517f1c6, 0x683f1abe, 0x298fab9d, 0x09cbe841,
- 0xa7c68978, 0x3f2acf3a, 0x0aeb90fd, 0xc6a2baf2, 0xf2d15515, 0xfe86c9b8,
- 0xe114fba3, 0x1f18be54, 0x2c6cc74b, 0xe573b3df, 0x2a8e47fe, 0xddf4fd9e,
- 0xae16633d, 0x1f1fe71f, 0xf214ade1, 0x921f0137, 0x7e527c9f, 0xe34b1eee,
- 0x7c5efeef, 0x34fc45f5, 0xefdc573b, 0x7af44473, 0x621e9e44, 0x49294b3e,
- 0x5b48bd48, 0xace5dfa0, 0x3b3d541f, 0x4d243e95, 0xfc94facf, 0x71e7e603,
- 0xf894e3bb, 0xa57568dc, 0xeb4f8327, 0xd468f68c, 0xd64a4ae2, 0x642d21f9,
- 0xc0d35d67, 0xc2d333bf, 0x609f8e34, 0x4f4d57e8, 0x76f1d5fb, 0x0ecdcb6c,
- 0x6ff3beeb, 0xea09a6b7, 0x1a75bd9f, 0xceb12d97, 0x9691d834, 0xec1f66ad,
- 0xa48f87e3, 0x5f1155a7, 0x9addb87d, 0x7c434f5a, 0x6cbce0f8, 0x96b80451,
- 0xc58f0bcb, 0x131d0434, 0x625d55f7, 0xfd747c62, 0xaed8f7f7, 0x3674d6fd,
- 0xb77201b1, 0x156268fd, 0xfb6eb38d, 0x649c2acf, 0xfe4c87cf, 0xffda12ba,
- 0xdb20ca27, 0x2c1ce173, 0xfc4515f6, 0x6bdbb589, 0x3bf761d3, 0x59ea7cff,
- 0x56ff7dd8, 0xf8899a6b, 0x273f37e8, 0x3db0a87b, 0x52e23f63, 0x4be3e4ac,
- 0xfb07c42f, 0x292fff88, 0xf54b1bc2, 0x8a27cc6b, 0x7afb069d, 0xffcc1efc,
- 0xb79a76cf, 0x0f06f31c, 0x4f5e6064, 0xebcc1ae0, 0xe49f9adf, 0xddfe2bff,
- 0x7fa57b03, 0xe7b54077, 0xa0328857, 0x3b5ec1db, 0x97abffc3, 0x88473d10,
- 0x0c19bd43, 0xe2ebd4bf, 0x80b7a872, 0x3914d7eb, 0x46fbbd25, 0x3cd2364a,
- 0xa0a28581, 0xa3aded9b, 0xdfeb42c0, 0xe079c4a4, 0x3c526c4f, 0xfdd04ee9,
- 0xced2c9e7, 0x5e8bf4aa, 0xe4234dcf, 0xf3f8e983, 0x68bb31e6, 0x2deff1d3,
- 0x2f00d922, 0xfa1a67b2, 0x86dd3ad7, 0xae335bf6, 0xc57fb435, 0x6f806255,
- 0xf436a82f, 0x8b73c3bf, 0xeaabbe01, 0x4bfe862b, 0xf00c4bbc, 0x4346bab2,
- 0x2d7dbbff, 0x1b7bf686, 0x1bda18d6, 0xf00c1bfd, 0x341e3b57, 0x7bafbff4,
- 0x2bdda1ab, 0xbbd8169c, 0x171f44e3, 0x885ffde1, 0xbd37282e, 0xd3d0ef9d,
- 0x5322fe75, 0x7c24d0f7, 0xf48968fb, 0xea517e6f, 0x98fe05dd, 0x487c9265,
- 0xc3ae17a5, 0xd427b033, 0x0a42259e, 0x38622bfb, 0xdd137c13, 0x7e7dba2f,
- 0x2eabc9fc, 0xf4ada1a2, 0xe90b06c3, 0x2795f98d, 0xbe0972cb, 0x1b6be5f3,
- 0xe61fa42d, 0x2af278df, 0xb6951fe0, 0x32fb7235, 0xc345aec1, 0x04376fcb,
- 0x6ff39d68, 0x81edd9ce, 0xe913f3df, 0x9fc54cf7, 0xbe5b77d8, 0x10ca37dc,
- 0x93ca23f1, 0x5f288fc4, 0xb36c7e23, 0xfc47bf92, 0xaf4cf288, 0xd47feb87,
- 0xd9e5c55b, 0x3f972f5e, 0x72e3adee, 0xe5c7d7b8, 0xb81b7b4f, 0x9faf79fc,
- 0xb7b77bbf, 0x7af7cb83, 0x97feb9bb, 0xfe5c3dbd, 0xf5c037aa, 0x2c2896af,
- 0x0102b4ff, 0x037b05bd, 0x776f5dfe, 0x77a4cc84, 0xe5eb31c5, 0xf24abd71,
- 0xdda578ad, 0xa2a95c54, 0x6ebeca89, 0x5c878e11, 0x17c92d86, 0x39f8be89,
- 0x7a237ed9, 0xea2e22d4, 0xc61fadfc, 0xaf424f7a, 0xc9d33108, 0xffad58fa,
- 0x69ef52a7, 0x15ee5fae, 0x977a7d7a, 0xd023ffdb, 0xb2f71dfb, 0xec3332fc,
- 0x24e9f753, 0x24c77a6a, 0x93e3263a, 0x593e5467, 0xc62c4f60, 0x3d816ef9,
- 0xb27b083b, 0x83ee12c0, 0x4cfbea1e, 0x3d221eb8, 0xc6c12274, 0x11efa97a,
- 0xca13fb0b, 0x9be182a7, 0x7dc30552, 0xa19b0d9f, 0x3d381777, 0x54576c19,
- 0x022ecf38, 0xdd722949, 0x4a1e6758, 0xa7cd53c2, 0xf3b045e1, 0x2e6c3937,
- 0x5f9c09e8, 0xcf314a62, 0x02bcdabb, 0xd7bd52e3, 0xff3fdf46, 0x68990899,
- 0x5fa8b35d, 0x10a5f32c, 0x87d81728, 0x87923ecd, 0x276f5499, 0x9bd51678,
- 0x02d7bb65, 0x6c3a7c3a, 0x76a11d86, 0x03db2491, 0x7cc894a6, 0x2c133ada,
- 0xeca97e34, 0xe72a5897, 0x39c0bc01, 0x3ad0a254, 0x1e1cbafb, 0x02dd21e0,
- 0x5efee7de, 0x543f7f33, 0x3a1e04e2, 0xfb411e1d, 0xe2052c20, 0xaf1fb94a,
- 0xd722c133, 0x5fa9f353, 0x432fd178, 0x71d46278, 0x803db2ec, 0x0d4a6e71,
- 0x8f805a65, 0x20279b6e, 0x9d62f1c7, 0xfb2f17e8, 0xb93acc85, 0xad03fbcd,
- 0xacffec97, 0xf4376194, 0x4c43f12e, 0x2bd4f829, 0x539961f9, 0xa97083f2,
- 0x1a1fcab0, 0x4a752cbf, 0xedcafc92, 0x78d29677, 0xafe718be, 0x7fce49e3,
- 0x97e6e4aa, 0x512cdf10, 0x1fbff5fd, 0xfd2578bf, 0x7bbd5267, 0xf468df22,
- 0xe347f8d1, 0xd23e6883, 0xb7a340f8, 0x7f345df6, 0x3455f345, 0x4bb02d3f,
- 0x0f8e833a, 0x49f91329, 0x906874f9, 0x6769dfd7, 0x4fcd16bb, 0x35307cd1,
- 0x4e7dc93f, 0xfd08a3e4, 0xcf2f8f81, 0xde6ec347, 0xa4fb66c7, 0x8ff1a47c,
- 0x1f1a4fc6, 0x16223fdd, 0xcb535127, 0x9475eb98, 0xcffc727b, 0x8ab48f40,
- 0xab33165b, 0xbe45cd38, 0x9efd8984, 0x5bdfa298, 0x501fc4b1, 0x2f73c23c,
- 0x2e3381fc, 0x7ec5d8ab, 0x4251d7b6, 0xeaa45bf4, 0x9ba233d1, 0x8fb91ced,
- 0x46b5d001, 0xc2a2f125, 0xd77fecd5, 0x2c7e8c38, 0x88fc232c, 0x17efd4db,
- 0x0db7c9ff, 0x6a9c58eb, 0x536f6ff4, 0x455be3fd, 0x375f8f3f, 0xf0bdaa33,
- 0x6f9bf656, 0x6fd633cb, 0x5efd5528, 0xcf4370b7, 0x5c8f08d6, 0x7ecdd89f,
- 0x572a8d6b, 0x72fd2a59, 0x9f31665d, 0xfc2b58f0, 0xd7f72816, 0x62f3677e,
- 0x80455bdc, 0x2088afe1, 0x108bb797, 0x1907738f, 0x0977c002, 0x69dc0561,
- 0x91b6c91f, 0xfb37ad48, 0xf85f803f, 0x39fe59db, 0xc636c738, 0xcf20fbfa,
- 0x6cefe2a7, 0x5be6807a, 0x0f28b654, 0x71ac9ddf, 0xd2753fb1, 0x1dfecb9e,
- 0x129ac2e4, 0xc937cf91, 0xfd91e63e, 0x13f6453a, 0x9fb269e5, 0xdec76479,
- 0xf809fb20, 0x02ad82b6, 0x29762ddf, 0xb7dba2c2, 0xceedfdf6, 0x6d32c245,
- 0x7b74fb6a, 0xfa67f7f1, 0x4adf7f89, 0x1223539e, 0x60d65651, 0xa7256fbf,
- 0x6319649b, 0xd5e8b2e3, 0x4ffcc9bc, 0xf322ff8d, 0xa6f9e62d, 0xd786b3c2,
- 0x786a7c68, 0x7d7812fe, 0x3ebc3269, 0xced82253, 0x595fda8f, 0x5755b88f,
- 0xde6fd4bc, 0x06441357, 0xa3c6eff1, 0x1bfd1cf2, 0xe313312c, 0xf7b53c4b,
- 0xe42c28dc, 0x2bdc7f4a, 0xaaf3c002, 0x8fae6a9e, 0xf7898f8e, 0x6bf8616e,
- 0xd9572f2a, 0xdde821fd, 0x6ba1a5cb, 0x1f12c3c8, 0xbc4bebef, 0xedf9e681,
- 0xce0f664b, 0xd7669d27, 0xace20f6e, 0x2f3d996f, 0x9d3ffbe0, 0x724a5eca,
- 0x369f9e25, 0xd3ac39e9, 0x9da8f12e, 0xe39dbec3, 0xce14b963, 0x23c80cb2,
- 0x5f9829fd, 0x92665ff3, 0xfe27692f, 0xe59367dd, 0x454cfe54, 0x529fe91c,
- 0x50facfee, 0xc77d1fa3, 0x538d1670, 0xeb26fa41, 0xaf3e38d1, 0xf7de9d78,
- 0x08d50ed8, 0xc5afbf83, 0x25534623, 0x6b88171e, 0xb03c449e, 0x04558ce6,
- 0x82147da9, 0x250cf68f, 0x7a35bd08, 0xfa19aae6, 0x114136b6, 0x542f60d3,
- 0x6193127d, 0x3e9d2e12, 0x09c57588, 0xe38f8e97, 0x700c520b, 0xa1866782,
- 0x8e55527f, 0x3bd93da1, 0xad3ed0d7, 0x4f00d4ae, 0xe860ddf7, 0xd0b0de9f,
- 0x6ffa6700, 0xeacff433, 0x35806a58, 0xab25957d, 0x15eeacc4, 0xf767ef86,
- 0x77f434ac, 0xda1ad607, 0xfb8971cd, 0xbc068f59, 0x4e3405c3, 0xee4e3a9d,
- 0x7e868dce, 0xaa6dd082, 0xbfc89c80, 0xceeb1267, 0x3acf4428, 0xc87aaac7,
- 0xd7ff7e69, 0xd734eb8d, 0xbca9925b, 0x7fd465d5, 0x784619b5, 0x4284e391,
- 0x4e458b43, 0xeace1ea3, 0x8ce018b6, 0xd79bd232, 0x51628fd1, 0x2f82f1cc,
- 0xae7fbfa2, 0x78d1fe81, 0x84f07e22, 0x69ec9fd0, 0xb37aeb00, 0x8f7b02d5,
- 0x1f7e82fc, 0xf1e82fc8, 0x1e82fc80, 0xdf417e46, 0x7d05f91f, 0xfa0bf23b,
- 0x4633b2f6, 0x1b0f97fa, 0x9ef95fe9, 0x5f1afe91, 0xeaa7454e, 0x843f91b0,
- 0x7f2bf15f, 0x5e374e85, 0x344ff232, 0x37266e7d, 0xf4153927, 0xd7213c50,
- 0x9dd7a797, 0xfa22f451, 0xf7c04c04, 0x9f4904cc, 0xa04975d0, 0xb319ed57,
- 0x8ffc1208, 0xc77cfb51, 0x23286fe2, 0xab86f03d, 0xebfa0334, 0x147ae166,
- 0x9dc5db71, 0x86884f26, 0x7e35115d, 0x7dff0cf5, 0x1a17a465, 0xb6cd5da6,
- 0xfc463f81, 0xdc9e7073, 0xd9ddeaa5, 0xc0fc7271, 0x127cc142, 0xd839baf8,
- 0x339ee347, 0xcfd02bf5, 0xb7f44fdf, 0x0bfbfbe3, 0xd47f79bb, 0xcdf7c143,
- 0x0d931aff, 0xe0b679b8, 0x0c28b073, 0x88492f97, 0x2ce6c5e8, 0xd43b27aa,
- 0xe39ea655, 0xdf4ed43c, 0xb8c99775, 0x69c7824e, 0xa15178e3, 0x444e22f0,
- 0xe6ecafc7, 0x6ce3e022, 0x63e01cec, 0xde41e4c0, 0x25756c20, 0xde051f41,
- 0xbde40b34, 0x9fc217e0, 0x57faa59b, 0x29e46259, 0x5ece73ac, 0xd7abb061,
- 0x62c2ed06, 0x0d397fc8, 0x8650d170, 0xc7f5ffa1, 0x92f6865c, 0xbda18150,
- 0x00c78cec, 0x19570f97, 0xe7be57fa, 0xe1d5c035, 0x1bff433a, 0xf00cf92f,
- 0xef9e456c, 0x239653bf, 0x992e21f3, 0x387e6bdf, 0x6bfa5079, 0xf9afdcf2,
- 0x49ffa2d5, 0x38711daf, 0xbf357f95, 0x6da3f35c, 0xcfd04084, 0xf6c2d3b6,
- 0xfa5da660, 0xf62dfec9, 0x6827c8f3, 0x57e6bafe, 0x08a9fe6b, 0x76f57ad4,
- 0xf693be87, 0x35ebf545, 0x8bf359ff, 0x4c5d8b13, 0xb236eb3f, 0x4b07e0ab,
- 0xae761338, 0x1a4c4639, 0x4cb9790f, 0xd7a25b9e, 0x7a2badaf, 0xa762c4fe,
- 0xdc7517e4, 0x7ee2ec17, 0xccfe24df, 0xf57caabf, 0x63beb99f, 0xad67cfe0,
- 0xbb56f79e, 0xf4f3ebff, 0x1321fc25, 0xf5f352fe, 0x264dfd72, 0xc767c713,
- 0xd72e5fd7, 0x0bf595af, 0xd921dfc9, 0x37e2f359, 0x1fc83af7, 0xc2c7b678,
- 0xaf339671, 0xe40c6c5c, 0x5e121fc1, 0xfc9b338c, 0x3e07d07c, 0x0b07ce05,
- 0xdf3ccdcb, 0x772932a5, 0xcf2cbd11, 0xd242a365, 0xc6c7b47f, 0xe849d479,
- 0xeda07ccd, 0x8b43f107, 0x510dc655, 0xc9686e22, 0xc0437197, 0x44a21b88,
- 0x2ff510dc, 0x3e187af7, 0xf0c55bd2, 0x0cbd7af7, 0xe3adeb1f, 0x3ebd07f2,
- 0x26f8d7ae, 0x79da5f1a, 0xc43fa34b, 0x2f237610, 0x1feb1f8a, 0x6d72f492,
- 0xd3f6fab0, 0xa24deb16, 0xe08d294e, 0x8f151ef3, 0x3c49e633, 0x7fe41fa0,
- 0xe6b57eaa, 0x9bc424c2, 0xc92b8547, 0xaae257f9, 0x687c2f7f, 0x973f1f78,
- 0x949bcb8e, 0x52e4a987, 0xceeb3f3b, 0xd1772cab, 0xb72d18f2, 0x3fe778d1,
- 0xfc7bb9dd, 0x53c5ab5c, 0xe8d53954, 0x55b5c9a2, 0x5fa11b84, 0xce267982,
- 0x609c3f53, 0xf3c5a394, 0x077f7e24, 0xbcf2a239, 0x326699cb, 0xfdb2f847,
- 0x1017f271, 0x4869ef1f, 0x8059e0e4, 0x7dba8fce, 0xd2faf02e, 0x2b7ea06e,
- 0xd062ac07, 0xb0757d85, 0x44096d1d, 0xd8471b9f, 0xaddb6c9f, 0x3e469f38,
- 0xe7e4e77f, 0xd13fce4a, 0x6fc26d38, 0xfbdbbac3, 0xab56fd8d, 0xfce8cae7,
- 0xd53cd54a, 0x878479de, 0x7f351ffd, 0x19f6a1de, 0x6e609fe7, 0x60df1a92,
- 0x1432a479, 0xb9bf3ba3, 0x8b28ef90, 0xb8b784c0, 0x6dc3d802, 0x6bbe4f16,
- 0x7869bf22, 0x97e7989b, 0xf7c41bf7, 0xa0fcf962, 0x232ff9e5, 0x6afa0fcf,
- 0xffb514f9, 0x985980e5, 0x48e0df71, 0x7fa7e70c, 0x4f7b3a6b, 0x7f974b8e,
- 0x11b79099, 0x309fb889, 0x27ba687a, 0xb4bac930, 0x1b361fd2, 0x684c91ee,
- 0x11347adf, 0x17cec9e7, 0xf3a69e65, 0x796953c5, 0x3cd7bd3a, 0x1bfbc2cf,
- 0xe7dbf932, 0x9bdc8f4d, 0x60c7fb58, 0x357aca31, 0x9fbd127e, 0x5f36bd71,
- 0xa519fe61, 0xab5eb1fd, 0xa47f7853, 0x49e40517, 0x112fd7cb, 0x5a9454a1,
- 0xb3bfc43e, 0xe5a0e99a, 0xd5425a43, 0xfbbb8fbc, 0xa8e35b56, 0x2da9f84b,
- 0x48ae71b5, 0x4b3c249e, 0x2a99bfde, 0xac6cb25f, 0x3e5bc784, 0xb38f2376,
- 0xe65b9e6d, 0xd9edb64f, 0xee6fff00, 0x1e056141, 0x4e3956c2, 0x553e9e34,
- 0xdcb924e5, 0x6e37b7a8, 0x6f6f5855, 0xf796ad84, 0x6b6f587c, 0x157ed5f0,
- 0xa6f095ae, 0x5b0e12ed, 0x24953b1d, 0x05c45fb9, 0xd8944fb0, 0x87b1ce0f,
- 0xf60238d4, 0x40fb1281, 0x6015f43d, 0xd0c02be8, 0xafa18057, 0xa15f4250,
- 0x65f0a57e, 0xbc888e23, 0x4e4e8d4e, 0xd1a9d790, 0xebc81ff9, 0x75e461e8,
- 0xd791fdf4, 0xaf23b7d1, 0x5e476fa3, 0xaf230f47, 0xbc8fefa3, 0x5e461e8e,
- 0x791fdf47, 0xbc8c3d1d, 0xf23fbe8e, 0xe476fa3a, 0xc8edf475, 0xe461e8eb,
- 0x91fdf475, 0xdfb7d1d7, 0xf218a3df, 0x9a93f73e, 0xeeb5df06, 0x71fcc69d,
- 0x313bedda, 0x41fbe88f, 0x66bf9ffc, 0x8f9d01cd, 0x6edf01af, 0x48f38aec,
- 0x49d7f73a, 0xa4849bba, 0xd32348f3, 0xc24d8b79, 0xe7749eb5, 0xf20ffe24,
- 0x99563529, 0x7c89414f, 0x53e44a0a, 0x529f2250, 0x29f32f93, 0x414f9128,
- 0x2829f23d, 0x89414f91, 0xe44a0a7c, 0x9f225053, 0x14f91282, 0x0a7c877c,
- 0x5053e44a, 0x4a0a7c8f, 0x7f5053e4, 0xbc81d68e, 0xf82eb68a, 0xf38679cb,
- 0xe1a1f11c, 0xc034e73c, 0xfdf597f0, 0xdbeb2fe1, 0xdbeb2fe1, 0x61eb2fe1,
- 0xfefacbf8, 0xb0f597f0, 0xe58b9e69, 0xfeb37e0c, 0x7acdf83b, 0x703fa8b8,
- 0x3ba0b11a, 0x35eefdf6, 0xe504e194, 0xdf49c559, 0x15b7ff97, 0x638583c8,
- 0x0f64ec95, 0x0fadbfd9, 0xd821a8ad, 0x2ba7deaf, 0xd0262316, 0x44d8f39b,
- 0x04487f37, 0xe8a08f71, 0xd76e4cf3, 0x47fcaaf2, 0x22392f74, 0x535f0fd8,
- 0x7da5d724, 0x334e11ef, 0x047fad4a, 0xf45fbc9e, 0xd63f5afc, 0x9075ba97,
- 0xfdc12c9d, 0x8e2d9286, 0x4fc45dd2, 0xfb0a4c07, 0x9fc807a1, 0x5e893a5a,
- 0xa3fd50aa, 0x27c3a603, 0xa22f70e3, 0xa7ecf145, 0x88b1afa1, 0xe052d633,
- 0xfe14bba9, 0xb2797642, 0xdf75afea, 0xda3f7b80, 0x1db8b5ba, 0xf22f09e9,
- 0x8447f3ef, 0xb9e68dad, 0x6b6153e9, 0x9366df87, 0xc3be02fe, 0x80baedb9,
- 0xe3afdde2, 0x697282ef, 0x0d81fcff, 0xfd51b437, 0x6fba8775, 0x171f8768,
- 0xcefbbf27, 0xc78c8973, 0xfb29b73b, 0xf99fb4cd, 0x90778487, 0xcb9495fa,
- 0x8775dff3, 0x9e36b69c, 0xd76b69d7, 0x97d843df, 0x5ce1736d, 0x8835c228,
- 0x8a7989ff, 0xf0444178, 0x0d7bfb46, 0x4486bbfb, 0x75d7f105, 0x3ffb6307,
- 0xd751f1d2, 0x7e01b250, 0xff6658e0, 0x59fe3a47, 0x72441f87, 0xec206e41,
- 0xf24aa756, 0xc3bd6af5, 0x79c51be4, 0x623ecba2, 0x9a6efe03, 0x7b8b5c97,
- 0xf0b8e26c, 0xe6ef83e4, 0x4e9f6cb5, 0xbd07f2eb, 0xba03dc1e, 0xd3eed3e9,
- 0x63ef3f0c, 0x82a7d998, 0x70f6c7d7, 0xc509404e, 0x0cee2a13, 0x09529a0c,
- 0xd5b023be, 0x87fe869a, 0x00ee0784, 0xa0b12899, 0x42afb234, 0x558a6c31,
- 0xd4e22fc0, 0x91ff1d34, 0x7e0e58e6, 0x0558f129, 0xc58963f8, 0x89be8569,
- 0xefa237f6, 0x71ff907f, 0x6867bcaf, 0x6b1ec0b5, 0x538b51fe, 0x36eaf5ae,
- 0x2d1ffb2b, 0xd0ffc947, 0xfcd52bdd, 0x085eed0d, 0x109e1df9, 0xdb91f8ec,
- 0xb9d42e39, 0x7fbe1de1, 0x783b89f1, 0xfaf89920, 0xf7c39c93, 0xb7e1b954,
- 0xc94fac28, 0x272ce86f, 0x3f6cb63c, 0x55f3889d, 0xfb0af038, 0x3db7571b,
- 0x08e3289e, 0xa6d11f32, 0xcf8b49e2, 0x68f4abb4, 0x7d01ef53, 0x3bcb7a48,
- 0x086eed87, 0xbd6836f7, 0xfb4457ec, 0xb91f9a87, 0x384f1b4e, 0xa45c45df,
- 0x8bb7f683, 0x5bbbd5a0, 0x89886476, 0xd53ae3fe, 0xcdb35caf, 0x3a7ef7ca,
- 0xc2ed9044, 0x3f54609a, 0xbacfbef5, 0x9dfac683, 0xa7fe51e5, 0xeed22e7a,
- 0x7dbcb6e5, 0x7ff66eea, 0x6f9cadba, 0xfd2ada6b, 0x04587121, 0x8bc015f3,
- 0x3704b14c, 0x947af51d, 0x27e7f849, 0x1f545faa, 0x2ebc658e, 0x7d678b19,
- 0x8b2c74b2, 0x32c67be1, 0x4c77bcb9, 0x8a5c8bde, 0x3bd10c58, 0x9104ab5c,
- 0xea99fb4f, 0x7b8ddd0f, 0x2063a092, 0x9479f99d, 0x145319f8, 0xae6a7aab,
- 0x77053957, 0xdfeadeb3, 0xf5987b8e, 0xcbfd8283, 0xd137e03b, 0xa3f00df8,
- 0xdc1e41a6, 0xb73f7cb5, 0x6ef9114e, 0x9506c3c8, 0x041e49ff, 0xeb2f0feb,
- 0x41259ab5, 0xf069afdc, 0xee81361f, 0x03f81c9a, 0xef802de7, 0x57362808,
- 0xf8279f21, 0x79f1acbc, 0xc7343cb4, 0x8725f1ab, 0xfb8d1f8c, 0x9d2c58a7,
- 0xd7e045bb, 0xded4bc2b, 0x0ce0188c, 0xf7081195, 0xfdb28509, 0xaf5fd1e4,
- 0xd3c386d8, 0x343f8c97, 0xaf4c4c99, 0xf6f7f211, 0x70c56043, 0x65e43a6d,
- 0xcbba52b7, 0x53cf5915, 0x572f0b95, 0x2bc5cee8, 0xf922f955, 0x63f9c74b,
- 0xe9f923e3, 0x40ff1262, 0xcf095b2b, 0xa4e6b390, 0xa214d7f0, 0xc2e527cc,
- 0xdb0c435b, 0xe27dd428, 0x73ad0422, 0x7c670a85, 0x9dfdee2f, 0x861f8c85,
- 0x5e5f962f, 0xbffc2811, 0x8a4d87d0, 0xab57ef85, 0xfc9871f8, 0xefc3951f,
- 0x831787b7, 0x2385f1ae, 0x1a2dd036, 0x1eedf73f, 0xf08733da, 0xe9215190,
- 0xb7eb64d7, 0x045179f2, 0xb55f88ad, 0x22fb4a16, 0xafecae2c, 0xc5c43e72,
- 0xdf6d3e71, 0x89f7aa1f, 0xace1f1a3, 0x7e027690, 0xf48e6bb2, 0x4fc25193,
- 0xf81c7dc6, 0x27e180c9, 0x8c9f84a3, 0x80c9f87a, 0x860327e1, 0x7e180c9f,
- 0xc9f84a32, 0xe4c27fa8, 0xd130ff3d, 0xf05369f3, 0xa7c4abf0, 0x4dfaa59f,
- 0xa7feb415, 0xd79b8f71, 0x11fde7ef, 0x195eb0df, 0x5fc453d7, 0x1f088af6,
- 0x70b9ecad, 0xe11394d4, 0xbf9db6a7, 0xe205ea7f, 0x17e4958f, 0x3bfd9e42,
- 0xf14c5095, 0xdcf67cd4, 0x979638da, 0x636ebee7, 0x1b64dbfd, 0x47776d3e,
- 0xcf7ef9f0, 0x7d4ab4ff, 0xd177ca19, 0x63ba2bb8, 0x4fffd03d, 0xb1d2fa55,
- 0x0f42f8de, 0xad32e5d3, 0x251def89, 0xbf50b3fa, 0x9ebf0c52, 0xbf9afd41,
- 0xda3676f1, 0xb6ee381f, 0x1cb70f41, 0xe191d92b, 0x177ef7c2, 0xe1c5b5f8,
- 0x58cfc1b4, 0xed992dbf, 0x8cba736e, 0x73c712db, 0x47a34bde, 0xb78c8555,
- 0xb829527d, 0x979ea2bc, 0x25d64108, 0x6e927e86, 0xc5a6f2d1, 0x58e3a311,
- 0xf3ca7891, 0x0710733b, 0x3e9e1549, 0x217c44d7, 0x8d2b61ce, 0xe3a251c4,
- 0x6af2e31d, 0x9df88613, 0x50a9ae56, 0xdbcef70c, 0x85abcfc7, 0xd7e1d38b,
- 0x1138a63f, 0xb8736e6f, 0xb826adee, 0x37158ced, 0x8a7d4532, 0xf04996cb,
- 0x738a23c8, 0xb9bde83f, 0x1356f584, 0xf78a5268, 0xb72cd50b, 0xcb2a416d,
- 0xafef96a6, 0xd66a763e, 0x90afb1f7, 0xb67586d7, 0x14b6bd39, 0xdad3df9d,
- 0xf7f578af, 0xb1b83520, 0x9b0dc642, 0xfc0118e8, 0x6dd9b7dd, 0x2538895b,
- 0xffb83fb9, 0x13e546b7, 0xc7ea3bed, 0x73ea1ff7, 0xabe0ebc4, 0xf417da11,
- 0xd52be616, 0xe312bf8d, 0xfea7e6eb, 0x56b5b7ec, 0x2d78f024, 0x1bb7da4e,
- 0x49d793a5, 0x8d3c6078, 0x5cf1a1ec, 0xbde30f3c, 0x7ab41435, 0xbbdc1eb0,
- 0x33857820, 0x2b3cc568, 0x7c7095b7, 0xce5bbfdf, 0x6c99dfe3, 0x675f822b,
- 0xe966da71, 0x3be23dfd, 0x0e1365f0, 0x5ebca9f7, 0x08db87f6, 0x43f0294f,
- 0x75ffc853, 0x8b57c44c, 0xfeb6feba, 0xd8ffa364, 0xf41598ff, 0x4aed5469,
- 0x549e1d34, 0xb6e578f9, 0xd7786c5b, 0xf2f166d0, 0x8abf07bb, 0x10df7fef,
- 0x90f90bbb, 0xad2781c6, 0xae1f826e, 0x93f67e90, 0xeadf9215, 0xb8f94273,
- 0x21b231e7, 0x3721ef96, 0xbf79fb3a, 0x9c7ef8e3, 0xc4ff03f0, 0x137c63e9,
- 0x9f70049f, 0x48c06daf, 0x127ac8df, 0x81b6dc78, 0x55bf9616, 0xa9cdbf16,
- 0x13dec75f, 0xa5e10af9, 0x815ee491, 0xb3fa71fd, 0x1f173fc1, 0xf79b37bf,
- 0x7be4eb49, 0xe2d71e54, 0x37cc798c, 0xff1ad7cc, 0x79499734, 0xa97be6d6,
- 0xbdf3c2c2, 0xb4e525f4, 0xdf0b776d, 0x10cd6983, 0x62f9451e, 0x53e4d539,
- 0x3546d793, 0x7bbad92e, 0xf4ebf089, 0xeeefd90d, 0xcfc12797, 0x2b9d7565,
- 0x3e127a54, 0xb8ba135f, 0x3d2abbdd, 0x728c729b, 0xee30f18f, 0x9bee5529,
- 0x37f28616, 0x6bfa4614, 0xc8a536f3, 0xe0ffc0ef, 0xbd2a53b3, 0xf7237fd1,
- 0xeaa4f157, 0xbd71d68d, 0x1a7b6871, 0x8561c6f4, 0xf71b54f3, 0xe36ebf48,
- 0xe71c098b, 0xaf8d8ffa, 0xea1ef8fe, 0x8313c9f7, 0x13f7facd, 0x27a9216d,
- 0x829fc9da, 0xdaa558de, 0xff6286fd, 0x72742b4f, 0x17adf6dc, 0xac5c81af,
- 0xf8b92a18, 0x0efbc14b, 0xeafcdf41, 0x73be1fc5, 0x5f622b83, 0xdcac7db5,
- 0x16d66ff9, 0x726f1e87, 0x560abb9f, 0x493cef0a, 0x5ac39c2f, 0x1df229b7,
- 0xfd8d8f59, 0xd1de8d4f, 0xf242d07c, 0xf088eadb, 0xa9ff4681, 0x78db26fc,
- 0x5fd24e3e, 0x07c6b7a3, 0x3a35bd1a, 0x9d297bf1, 0xfbadafff, 0x2b5e9533,
- 0x531dfe54, 0x87456ee5, 0xe58ab6db, 0x056b6ddd, 0xb1fa6bdf, 0x4e3f58cd,
- 0x7eb8e727, 0xc0b901df, 0x69d022bb, 0xc655b774, 0xa04d0f23, 0xbeec3653,
- 0x6ad58eb6, 0x8d5db1dc, 0xfcd2ae1f, 0x4c7f62e0, 0xab4e8ea5, 0x6a74939f,
- 0x5fede97d, 0xfbc5c0ff, 0x4f6c7a93, 0x2b8bfb0c, 0xbd330e87, 0x663e771a,
- 0xf4bf5375, 0x5f41b74a, 0x389776b7, 0xb15f3711, 0xf90ad073, 0x4d74af4f,
- 0xea4defca, 0xaf0d60bd, 0xce8a3fb0, 0xa1fd69ee, 0x3cd30ef7, 0x26c4379b,
- 0x368d1ee2, 0xf252b78f, 0x72776b75, 0xed6be60a, 0x381ff96e, 0x3f7a68cf,
- 0xc42eee5a, 0x4958794a, 0x2f2e429f, 0xdec9e2dc, 0x3f313858, 0x959595a6,
- 0x10cf6e92, 0x256f717a, 0xbbe87e2b, 0x03d643c0, 0x93e41e71, 0x41c2f2f3,
- 0xc63e0bcc, 0x17a46dba, 0xaf25ff71, 0xac7bfc33, 0xbe745c83, 0x213282ef,
- 0xd23be645, 0x926fde08, 0xcc72b3ef, 0x52afbcb2, 0x0f6a3bda, 0x86a45da1,
- 0x68ffb1cb, 0x5f9535bd, 0x36a7f1a1, 0x9a9eb44e, 0x57777f6a, 0xa2fa794a,
- 0xab705dfd, 0x4f029371, 0x6de69db6, 0x078e747e, 0xda2fa471, 0xe64e2da7,
- 0x4bf7c697, 0x32955acc, 0xe4f37ec9, 0xfdea6839, 0x4da6d40e, 0x7909dfb2,
- 0xb44e555f, 0x79e3efbb, 0x27997e92, 0xdd90a0b9, 0x6c2eefa2, 0x65fbe588,
- 0x38b4beda, 0x5efadffd, 0x14cac1e1, 0x4e14fe35, 0x14d93f80, 0x487fcaa7,
- 0xa25fa8c2, 0xfdecd7ab, 0x21386739, 0x3f9fa745, 0xa1ed56ea, 0x3c81ef08,
- 0x815c9e8b, 0xfeb9c778, 0x42a6090b, 0x9f5ca7f0, 0xab66ddf6, 0xf40f5ce7,
- 0xbe18f6dc, 0xd37e4eef, 0xda93c40e, 0xa71cc903, 0xeca7afb9, 0xe71a5ee2,
- 0xfc596dbe, 0xf3f350de, 0x2ffaa957, 0x8ecb737e, 0xebdff44a, 0x6f8fc276,
- 0x886cf877, 0x2c0fc5c3, 0xdfb0e5b1, 0x5a01cf2b, 0x22b36ade, 0x0c9efc7c,
- 0x657211fa, 0x7b07913a, 0xf4af7ab3, 0x624debff, 0xb39bf227, 0x338b7cfb,
- 0x529e1fa1, 0xc527f03c, 0xdaa3d23e, 0xc7748c79, 0x6fbec587, 0xef68bf41,
- 0xc6c2e6ef, 0x219fb19a, 0x829dce2f, 0x07ec0bfc, 0xa65e01eb, 0x6e71fca9,
- 0xab827ce0, 0x2fcf8230, 0xe3481efb, 0xd67f2d0b, 0x194ff88e, 0x0d29a3f8,
- 0xe6a6d1fc, 0x2c0c76c9, 0x707db862, 0xe9fbbf19, 0x473a6743, 0xfb563db6,
- 0xef08a044, 0xda3e2578, 0x09dd16ba, 0x7f63a8bf, 0x35ce324c, 0xb640d6d9,
- 0x1b6d0fde, 0x01df987c, 0xe58c1a5d, 0xce354077, 0x67b83525, 0x7c9f6ab3,
- 0x3bf5a767, 0xb597eaa1, 0xef0c8b5d, 0x4c69da79, 0xd9ff8d27, 0x5fdf3c50,
- 0x04e9ded3, 0x95e3feec, 0x4ebdf2e5, 0xd3be4bb5, 0xaefee4c9, 0x5af4e349,
- 0xbe57b179, 0x3bbdd0fb, 0xbe91b3ba, 0x257aecef, 0x7bace311, 0x4e1567fc,
- 0xceb7c713, 0x77f1fc60, 0xbbe57b47, 0x27c7f6a3, 0xbe03ff7f, 0x1c767f06,
- 0xc6790c53, 0xec4982fb, 0xc243fa87, 0xdfb6fc86, 0xbdcfd829, 0xb03d1664,
- 0xa25f9aeb, 0xc552ffd5, 0xfea4a5c3, 0xcd7fd06c, 0x61b32781, 0x20937e37,
- 0xf703a6e1, 0xc87a08fe, 0xf48c7cff, 0xfd822dbf, 0xf480d6db, 0x64f7b597,
- 0x38ec7842, 0x19547f87, 0x46b9f2cf, 0xada4977d, 0xae0bfc8b, 0xd4458dff,
- 0x6f781d61, 0xdf7e7e04, 0x3d076a12, 0x147f27df, 0x2a138f79, 0x6fdfbdff,
- 0x87f7cc5e, 0x57e01048, 0x4affdfbc, 0x9a89f202, 0xfe6b561f, 0xb4ef1795,
- 0xef951e37, 0x870be381, 0xd4231cf9, 0xa77ac978, 0xdf8db7e4, 0x4ace2eb7,
- 0x6b8abf65, 0xdb212d3a, 0xab5af464, 0xf0e34dfa, 0x2e7cc391, 0xfd243ceb,
- 0xf3a1ce82, 0x7e6817ec, 0x70bef686, 0xecf3a1dd, 0xaddf6827, 0xd2f1223f,
- 0xb7d64475, 0x78b49814, 0xc3c9578b, 0x38615979, 0xb4d2c2bf, 0x9b9b00d5,
- 0x3a505ab6, 0x08c878d5, 0x0abbe5fb, 0x99e7ca7e, 0xb8ea6dae, 0xf3755b04,
- 0x974d56c5, 0x3ea8daef, 0xa5ef81d7, 0xbbdad73d, 0x50f3c88e, 0x276e2ba8,
- 0xef5d83df, 0xebeca0b0, 0xdf3db072, 0xc02a6dd7, 0x12af757d, 0x71dcfec7,
- 0xf4d6fef5, 0x22c6ef75, 0x4629904e, 0x7cdc994e, 0x15666b6f, 0x022e9b8d,
- 0x7b4b8f7c, 0x9fe5744f, 0xf8c32e3f, 0xafc2620b, 0x5b980220, 0x7909a335,
- 0xe1490593, 0xf73c6032, 0xd384ba58, 0x0e20afc3, 0x37240ce5, 0xa5f28f21,
- 0x8af54ae3, 0x30eece21, 0x0a07aff9, 0xdb2ec6ba, 0xc4635c64, 0x5799b906,
- 0xfa68f925, 0xe2473a49, 0x83b9f51c, 0xd3e981cf, 0x9b9df9ba, 0xa1970c28,
- 0x837c71df, 0x8c7f60fb, 0x420eff93, 0xf6f5979e, 0x027558c6, 0x3de99797,
- 0xa425aeaa, 0x9f0363e6, 0xf7f8829b, 0xa12b8e04, 0xbcfdeb6f, 0x4f292aee,
- 0x979918be, 0xceb14bbd, 0xe4fa27fa, 0x835fdb90, 0xcc72fa75, 0xb8b92545,
- 0x7def2b17, 0xb7f3515f, 0x50bcbf9a, 0x7a96769d, 0xc8cdb3ce, 0xb4fe4070,
- 0xd78a89fb, 0x1f52efcb, 0x8ad93c2a, 0xc4737f75, 0x1620efce, 0x73c9c48e,
- 0xb63a8cd5, 0xd9b17daf, 0x2e283fec, 0xfea2688b, 0x214d0b27, 0xa6ffdfdc,
- 0x599e73b0, 0x6dfca3d8, 0xc3df2c53, 0xf1bf8e56, 0x964dec39, 0x92a7f7f9,
- 0xff599f68, 0x8ba078a0, 0xfe2f479b, 0x6ca84fe3, 0x187fdb1a, 0xfe4911fb,
- 0xb9c3f066, 0x7ef3bad1, 0x9d37f542, 0xb48f7643, 0x8fbf4263, 0x9e7e0fe3,
- 0xac8a6298, 0xc5c8caef, 0x879d5f17, 0xe9f1ced2, 0x32cdc785, 0x9eb5159e,
- 0xbe2e192b, 0x98fd4e0f, 0xa61c573e, 0x0b87ce20, 0x0f7a9f8f, 0x7b885beb,
- 0xd83738ce, 0xf6f597ad, 0x2566b84e, 0x150e7e23, 0x88ac97fa, 0xb540783e,
- 0xae7d694b, 0x7b08dc9f, 0x2059a6f9, 0x651440ee, 0x07d6883e, 0x425f833f,
- 0xaa37c6fe, 0x07ed79e4, 0x546fbe39, 0x67065cb1, 0x9be72e41, 0xb69fbf27,
- 0xe3514aaf, 0xd1ae9259, 0x8ba68b74, 0xe7716f86, 0x8524e9f0, 0xa8f45cf1,
- 0xc62eefc4, 0xb767e7ef, 0x198a9893, 0xc636fbff, 0xf86ffff3, 0xca7de2fd,
- 0xfbe373f7, 0xd3ed3afc, 0x77e7d86d, 0x93ed1ffe, 0xbcdfc0f5, 0x3ee361cf,
- 0xb142fad3, 0x8f37c073, 0x8acfd89b, 0x0a2a37be, 0x66d1eb04, 0x53c71c73,
- 0xddf271fd, 0xd3cfe901, 0xde9a9fd0, 0x2e175d9c, 0x4e71bf82, 0xaeb16788,
- 0xeb8869b0, 0x30e5562f, 0xc314ccdf, 0xc27efc99, 0x3f872e12, 0x35bfb66b,
- 0x4bb223f7, 0x0f048f03, 0xf4e34abf, 0x56a7c129, 0xeddd5f41, 0x95dcfce0,
- 0xa56029a0, 0x45920679, 0x7f9a31f1, 0xce5ccd60, 0xaa115cb3, 0xb1b06a9e,
- 0xecf6a29e, 0xca37b41e, 0xf9fdeff6, 0xa3f81ec2, 0xf782f923, 0xae225033,
- 0xc0f04bd9, 0xff6e0292, 0xf6e7a6a1, 0x97efc824, 0x8193e608, 0xef7c2935,
- 0x83a7e9e4, 0x0e8ec2d7, 0x11337a0c, 0xf44cab57, 0x19c74187, 0x079f6966,
- 0xe54f54dc, 0xb1af8a13, 0xc914e31d, 0xe31b86f5, 0x43403a5e, 0x2a91e6c5,
- 0x3d73faa5, 0xd5cf9c09, 0x638b47e4, 0x7f9c0ecf, 0xded2780a, 0xf2a07f23,
- 0xc5778699, 0xa667df2b, 0xe8d678aa, 0x6a5bf1a0, 0xa6cf7c9c, 0x377c916c,
- 0xbd791f7e, 0x33c8fbe0, 0x27782969, 0x71e31cd7, 0x4adfdf01, 0xfd618ff2,
- 0x3e881b7d, 0xd243ec66, 0x5bde1ce1, 0x997fe24e, 0x7e5a4dab, 0x3463df9f,
- 0x9a5fa90b, 0x3d17f7b5, 0x2217f7c6, 0xef19333c, 0xe89f9891, 0x3edd67fb,
- 0x5fbe355b, 0xd2fb65ee, 0xd9def2ac, 0x7a4f34ff, 0x5aa9286f, 0x623b95da,
- 0x9dfc89fd, 0xf3450efa, 0x7c96cfc3, 0xe4f60b3c, 0xcc6f83dc, 0xa2577944,
- 0xf69ab92f, 0x1fe344f3, 0x7dc4c316, 0xf7e61990, 0xfe341f34, 0xe5c71671,
- 0xfcc1bcb7, 0x57aeb7ff, 0x01ffc75b, 0x0934e170, 0x000048d0
+ 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c09, 0xf37df0f5, 0x66499996,
+ 0x0d909326, 0x8a027108, 0x081380a8, 0xc3b44069, 0x8e22a222, 0x260dc55b,
+ 0x1037d902, 0xfdaff0fd, 0x2d361032, 0x4682d0d6, 0xa0c0748b, 0x0d0482c1,
+ 0x00e02418, 0xd52ff82e, 0x5b7bbfd8, 0x16c34a0c, 0x7e1b8092, 0xce7fe5b5,
+ 0xef25f7b9, 0x6d80264d, 0xfdfb5fbf, 0xe6f169bf, 0x5ddf7bbc, 0x3dcf76ce,
+ 0x14fbdcf7, 0xf89628db, 0xe0cec663, 0x2cabd20f, 0xdd51b18c, 0xa0db6ce9,
+ 0x74fa87a1, 0x6559ffe7, 0x4287ead3, 0x6ed0ab1e, 0x9cfdd61e, 0x7e5485b1,
+ 0x386b8c40, 0xf4d31cbb, 0x8f0e1b10, 0x9616c96d, 0x6e7dd8cc, 0x0901bf46,
+ 0x912974be, 0x5615ceb1, 0x780cbaf7, 0x085c7aae, 0x20c8f7df, 0xf7c25077,
+ 0x1652c93c, 0xbaa23fe4, 0xbecc01d7, 0x6cb3233f, 0xe0da66c6, 0xc3fc0f6f,
+ 0x7cbea07a, 0x63106cac, 0x059969ea, 0x77ea7fa0, 0x3403a512, 0x00efc336,
+ 0x6c2df978, 0xfeeed0dc, 0xecfd13b9, 0xe8b78073, 0x5b7e89f9, 0x097f90c0,
+ 0xecffa893, 0x5faa4afb, 0xf2f16f6f, 0x073e6c5b, 0x8d941636, 0x7f963bcf,
+ 0x8be7c2e9, 0x7aa16e9b, 0xd82c5318, 0xc8b772cf, 0x635cfc4f, 0xbbfaee96,
+ 0x76a214f1, 0x04d3d874, 0x3188feed, 0xb6bfb5e9, 0xd543c032, 0x0563d556,
+ 0xaad84cbc, 0x700c7f86, 0x84295ae9, 0x9d9765b0, 0xfb4bc031, 0x9d870e6a,
+ 0x9fcb0f9a, 0xaa1805a8, 0xff36b728, 0xdbc40afc, 0xa3ad9956, 0xf784fc66,
+ 0x3bc71b56, 0x9e70e46b, 0x6ba5839d, 0xf7c74f77, 0xccad1a0b, 0x6e95f50e,
+ 0x057a9fcf, 0x54fbf9c0, 0xd74a4586, 0x01fad02f, 0xea92185c, 0xcf18ee11,
+ 0x36e0fda8, 0xca1eb439, 0x939ab877, 0x1ff1836f, 0xcf31b4ab, 0x676fd0c5,
+ 0x80adf273, 0x96d0a287, 0xd15ef849, 0x2c8bc946, 0xfaeb6134, 0x7bc2fb37,
+ 0xaf241ba5, 0x5c52f015, 0x433ccb17, 0xc0ce1f78, 0x3906d6bf, 0x9fc863fc,
+ 0x1964e30b, 0x49ead748, 0x57f6c64c, 0x37671e68, 0x0e558e9e, 0x376b1e61,
+ 0xda01ba5c, 0x5ecaf781, 0xc438bc94, 0x200b0b32, 0xb76fb65f, 0x81d67b4f,
+ 0x0da05be3, 0x96b8e276, 0x3f2e586a, 0xeecdbb94, 0xd5adfec1, 0xd17e4126,
+ 0x9e5ab5ea, 0x75c5fe81, 0xcd8f3197, 0x419aafd0, 0x88fe4629, 0x9b018f4c,
+ 0xc453fb18, 0xf91eaf98, 0x37690944, 0x9fa2e419, 0x2ef44f14, 0xf54d93ae,
+ 0x4b192603, 0x007eff82, 0x82be027f, 0x57849d3b, 0x05736e9d, 0x3b74e91f,
+ 0x2987e425, 0xfac6d99d, 0x48e7f4f5, 0x754fe807, 0x5fd29ba5, 0xba52a654,
+ 0xf443d2b2, 0x07f10279, 0x6fd172e9, 0x4e3658d7, 0x3e5d7681, 0x4b3146e6,
+ 0xa71be298, 0xe7e09c02, 0x01ddf270, 0xf19673c9, 0x6a13e9eb, 0x72651720,
+ 0x53e49b15, 0x05ac02fa, 0xb42f30e6, 0x9be8dcaf, 0xd7b19a38, 0x1c71e059,
+ 0x502922ff, 0xac657480, 0x740fd53e, 0x1e812259, 0xc52d7c01, 0x961e0241,
+ 0x067e05f4, 0x4f713d3a, 0x24b2b3f6, 0x70889ac6, 0x668f73de, 0x54353d50,
+ 0x0cf50a8f, 0xc93d773a, 0xf54c73d3, 0xd02f4f24, 0xf54b59eb, 0x9eafcfd8,
+ 0x318fa627, 0x917a67f7, 0x580bcf5e, 0xfcf3916e, 0x633c95c6, 0x333fb9ac,
+ 0x949ea84a, 0x002cbdbb, 0x7f9d65e5, 0x864fb358, 0xf8c6c77c, 0x23328f11,
+ 0x86df8d1f, 0xaa4139f5, 0x97147c8c, 0xa7926313, 0x09825f78, 0x9fb933ee,
+ 0x7f927ca9, 0x653f29a0, 0x7c11a5da, 0x5eb770e9, 0x54e86026, 0xfea35e38,
+ 0xd234fd6a, 0xd9fae33b, 0x9fa07e08, 0x03cef483, 0xbb170263, 0x57d8dfa1,
+ 0x407ff406, 0x8eee5c0b, 0x2e3037c2, 0xea62a589, 0x991a60b1, 0x78e554bf,
+ 0xfbffdf1b, 0xfde107c1, 0xe0e74b72, 0x4bff8078, 0x8e21f71a, 0x4ca88ffb,
+ 0x32316e81, 0x3172c0ab, 0x6ffa4656, 0xb3f64669, 0x975e0341, 0x917e000d,
+ 0xa65debba, 0x1f915206, 0x4115825b, 0x3025cfe4, 0x8c7eb041, 0xe115641d,
+ 0xfef085e0, 0xc454bc80, 0xfd0355bf, 0x835f6c61, 0xfb5287f6, 0x5b7ed8ad,
+ 0x075bed2f, 0xb7da98e6, 0xda9817a5, 0x3ed069b7, 0x706747c8, 0xf01f68be,
+ 0x93b18637, 0x6fb53e6c, 0xf6a02f4d, 0xc0ac6a97, 0x574c7ed4, 0xbb60dffb,
+ 0x49fb63df, 0x703fc651, 0xe9fc798c, 0x6bf1e645, 0x416cfc7c, 0x431fb450,
+ 0x20a497e3, 0x117a7f1f, 0xd795bf1f, 0xabbed5db, 0x049aff0b, 0x5ea43aed,
+ 0xac683fc6, 0x9417fc79, 0xe56fc798, 0x2c17bbed, 0xa83bed13, 0x196978fd,
+ 0x2505ff1f, 0x0d66bed4, 0xb48f9178, 0x211531fe, 0x40d34f9c, 0x07485280,
+ 0x921d28fa, 0x93e818c0, 0x8481b2df, 0x38620787, 0x03137ddf, 0xd6e8e6fc,
+ 0x12042ca7, 0x9970f308, 0x8de2e9e0, 0x3f3e34e3, 0x9f5e6907, 0xab3aba2d,
+ 0x8cf9a651, 0x2e86b4ad, 0x37b6fe82, 0x678441ca, 0x2432bcad, 0x760a7cd3,
+ 0xb0a7be02, 0xf3ff3e30, 0x8ceb61aa, 0x674c8ae3, 0x2dadab57, 0xd2eab906,
+ 0x90d9e3ef, 0x055fe80a, 0x6ea8c132, 0x34f415b8, 0x39fc3d03, 0x0f4c63e8,
+ 0x392edcab, 0x5d9c7a04, 0x059b946c, 0xb2092edc, 0xff4087f7, 0xdffa227f,
+ 0xb77c70aa, 0x884293ce, 0xcc566fff, 0xcd9f50d1, 0xa4058eae, 0x5ca3f777,
+ 0xbb73a9d0, 0x14f64435, 0x9f88074c, 0x191449db, 0x1baed3fb, 0x305c94de,
+ 0x31f4d63f, 0x0b3777bd, 0xf2854e2d, 0x0ee79733, 0xeff8c370, 0x211d669a,
+ 0x7cc4fce3, 0xc7242dfd, 0x8725bfac, 0x2b0d69b1, 0xdc00fed4, 0xbcfd4d3e,
+ 0x1dfef0c5, 0x577c3301, 0x576e1981, 0xed05aa43, 0xad894299, 0xa9ef7a85,
+ 0xedebe730, 0x3812964c, 0x3f7b455d, 0x85f41c01, 0x3a60f747, 0x89bb1f02,
+ 0xfcddd3ae, 0xe53fbd5d, 0x4c2ca90f, 0x124b71f3, 0x5127fa23, 0x8f9b80b9,
+ 0xd3bfb23b, 0x0fcf9b55, 0xa0fe99fd, 0xec8cf84c, 0x58aecb7f, 0xd9ec059f,
+ 0x552f9a96, 0xf1c8c164, 0xc67ff644, 0xb8f1c8fc, 0x721f9c35, 0x39cf9183,
+ 0x53f2449f, 0x5fb8e379, 0x53f0321e, 0xbfb5fd69, 0xaf78643c, 0x1326eeb8,
+ 0xc3ba185c, 0x26bf3e54, 0xbb3f94d7, 0x3f94d0ba, 0x131cd973, 0xd07c1b9c,
+ 0xfcc67e54, 0x7bfca605, 0xe5311e2a, 0xc2b055df, 0x7811df04, 0xf6fe54ca,
+ 0xf94d6b69, 0xdc975d96, 0xf5547288, 0xde70cc81, 0xfad1daf8, 0xbf37b473,
+ 0xa45e2876, 0x57b011c7, 0x818e0e50, 0x7b6982bd, 0xabb248e3, 0x31e60f41,
+ 0x4b56a130, 0xc6cb83fb, 0xa4665ea2, 0xefd2433f, 0xc634c183, 0x843c979e,
+ 0x6346b93f, 0x89616061, 0x71f17425, 0x6fc86ca7, 0x0d7e4739, 0x9ec8fa08,
+ 0xf44b72f9, 0x72ebe5e7, 0xd3bd402f, 0x5f803e9b, 0x3ae79c7f, 0x99103d84,
+ 0xbf31225f, 0x7ebeb9f1, 0x7ae25cba, 0x53ac44be, 0x3bea5e4a, 0x0e10b99e,
+ 0x5b38ae0f, 0x5480f57b, 0xfd6893d4, 0x803f2127, 0x51e81814, 0x24c8375c,
+ 0x65bb6ddf, 0xea1957ea, 0x99abd004, 0x4257bfcc, 0x9bde133d, 0xec30cb7e,
+ 0xd475ef87, 0x8931acfb, 0xcab6f5e6, 0xa43cbfc9, 0x94fc7d22, 0x469ca91e,
+ 0x80656b69, 0x059543d2, 0x595e7e94, 0xe54b6941, 0x540f4a7c, 0x63fd2906,
+ 0x3f4a32e5, 0xf4a6acad, 0x4a1acae3, 0x510cac3f, 0xa3e95eda, 0x2e879754,
+ 0xf617ebfd, 0xc0b758b0, 0x8b0f6e03, 0xb2822cb1, 0xdee724cd, 0x53f39454,
+ 0xa3066f8e, 0x63ea7fbd, 0xde8ca260, 0x6fc915f1, 0x47d1d3bd, 0x085e4af6,
+ 0xcf4fa798, 0xa70c7b7c, 0x26c2dd93, 0x8f47d033, 0xf79cf45c, 0x2b04a1de,
+ 0xa9c032c8, 0x519c9bde, 0x0fb985ea, 0x3a2e75e9, 0x70e75f31, 0x3eb7675c,
+ 0xac6c97fd, 0x206972f7, 0xcaf7879f, 0xf0b30f34, 0xd7a45eb3, 0xf49bc50f,
+ 0x5bd29fda, 0x2e89dca0, 0x33a735fc, 0x6e48e748, 0x8354ffaa, 0xc7882995,
+ 0x2e10d8a6, 0x7bed4f8d, 0x38f285d6, 0x3eae5537, 0x7c77b234, 0x5467d695,
+ 0x29e30c3b, 0xa7c3346f, 0xdcc9a5aa, 0xbb89e07f, 0x95f21875, 0x45d0fabb,
+ 0x4a54ff48, 0xa6e67af5, 0xb1ced46a, 0x7c7141ba, 0x79f10efe, 0xf13c6370,
+ 0xa93bac2b, 0x3fbb3ffc, 0xf7a3d5bd, 0xf606b187, 0x01f50d85, 0xf73a0de4,
+ 0xdd07a8fa, 0x3f34af95, 0xfd49abd2, 0x1885ed06, 0x206677f8, 0xac10abd6,
+ 0x2f5e5bd7, 0xe397ad07, 0xf6a68df3, 0xbe8f3de0, 0x7af7c7a6, 0xb5855be7,
+ 0x7d04e3ea, 0xe7f0a575, 0xabd9d714, 0xbc4af3cd, 0xec6f2e09, 0x679a6d5b,
+ 0x7f900ff0, 0xc8292156, 0x9b82253f, 0x32c7143a, 0x6a97fa09, 0xe5bd50f1,
+ 0x6a572f12, 0x1e02d16b, 0xb466c762, 0xd1cdee33, 0xfb73cff9, 0x1fdf401f,
+ 0x1ecaadfd, 0xd7e17cc5, 0xb06cf551, 0xe7e82d6f, 0x0dbdd011, 0xef5053c5,
+ 0x3d76dd1d, 0x98b327d9, 0xa48b85df, 0x8d9d5602, 0x6609ce76, 0x7ffc8c99,
+ 0x35defd82, 0xc8deb0d2, 0x9fd468b7, 0xf3cccb99, 0x2667d82c, 0x0cc6bf38,
+ 0x939bb1e7, 0x56f3df91, 0xa0b730aa, 0x6ff39a5c, 0xbe49b8b7, 0x12c559f2,
+ 0x3f08ef5a, 0xa66ebdd8, 0x2fb907f4, 0xec99e57d, 0x87e8a1dc, 0xf75bfae0,
+ 0x7026140f, 0x3128a53b, 0xff20f9a4, 0x3f91868b, 0xfbe182b9, 0xa7a825a1,
+ 0x5de64e82, 0xefd27acf, 0xb23ff687, 0xd27cfabf, 0xfa214fc3, 0xbe49d721,
+ 0xda759450, 0xd84916c3, 0x974a415b, 0x76eb718b, 0x5c044d6b, 0x47d7011b,
+ 0xbf377fc0, 0xbf133225, 0x35025aa5, 0x5fce2496, 0x4a482f68, 0x47f816a7,
+ 0x51ed4fea, 0xb53fed7f, 0x3fa834fe, 0xfd7f54db, 0x0bfeb53f, 0x29bff47b,
+ 0xafa5fd5a, 0x0416da6c, 0x79b4537d, 0x3cc18b95, 0x4ea95474, 0x4bdd02f6,
+ 0x21762fd6, 0x82511c1f, 0xa3e7e42e, 0x34727921, 0x22d2f87e, 0xe7cca2fc,
+ 0x855d7090, 0xc7fd427f, 0x54d9f85e, 0x59bee7b4, 0xbd69baaf, 0x5b0d6754,
+ 0x1acb4e41, 0xdfa0a70a, 0x1c83e017, 0x46527a5e, 0x9fccd1b8, 0x4aafcf45,
+ 0x701eff46, 0x844f588a, 0xab2a5ec9, 0x9c24f3fd, 0x2759ca87, 0x7be459c9,
+ 0x04e9fed8, 0x5ab98fd2, 0xe87ccf5c, 0xe5f9d927, 0x0de52f02, 0xbb293b3f,
+ 0x30f6bd30, 0x4cb013ea, 0x7c8f0ec8, 0x41d840af, 0xc4ce2c87, 0xb1425856,
+ 0xa11fb11f, 0xc2f1d4de, 0xaa0edc42, 0xf0e4f0da, 0xb6afd083, 0x24badfda,
+ 0x7974be03, 0xf33f553b, 0x7a7aafd7, 0x62edcbd7, 0x5efdd7bd, 0x34f3de88,
+ 0x89adfb0a, 0xd86a25a7, 0xc971f685, 0x841bd55a, 0x9e9b25c7, 0x5c69ee7d,
+ 0xf5627eaf, 0x17f5045e, 0xc3e37a6f, 0x6f170031, 0xf0a71351, 0xe4a43861,
+ 0xc394fa6e, 0xba23f9bf, 0xf2f451e9, 0x18679a1b, 0x4270fe7f, 0xb78a5d37,
+ 0xb0d8d6ec, 0x5098f89e, 0x716b5bbf, 0xfd4fa144, 0x676849c1, 0x56f86d55,
+ 0xd1e575c3, 0xc94b125d, 0xb5cf8288, 0x80bd906f, 0x0a7a2278, 0x2fd1757a,
+ 0xd0397ca2, 0x247af505, 0xbdcb22bd, 0x1465fa81, 0x93fd17af, 0xbe2fdfc0,
+ 0x4fec7e8a, 0x43c45ead, 0xb9f78bc1, 0x95873c70, 0xcfe7ce0a, 0x3f464e2c,
+ 0x4c1a817d, 0x9fca5376, 0x9fb9ac17, 0xbdff2ff8, 0xfaf993fb, 0x42d7d7d0,
+ 0x2fb05573, 0xeaf6738e, 0x799c68db, 0x587c402c, 0x0fec8cf0, 0xc2b5fa41,
+ 0x22896f26, 0x9732c527, 0x80ebc393, 0xc3ce30b8, 0xbf414eb8, 0xd0e5efee,
+ 0xcc8ff27a, 0xee0fa861, 0x6cf1fdd7, 0x8b5fc12e, 0xb27184fd, 0xdae75f45,
+ 0xbb5bfc4c, 0x74e919b4, 0x052f806c, 0x4ce56afd, 0x487c0a09, 0xf95ea067,
+ 0x3853abbd, 0xc947989d, 0x5d81ef16, 0x639f0130, 0x67d566f9, 0x8f7a6e1f,
+ 0x6ee8c99d, 0x1f689e7f, 0xf3831dfa, 0x5664e1f9, 0x7c651f50, 0x07aeb235,
+ 0xf0375e60, 0xb9de4199, 0xc23ed7fc, 0xff975de5, 0x31934dd0, 0xb9f7abff,
+ 0x387be11c, 0xc2bf425f, 0xfbbf9429, 0x83f48956, 0xc9a38595, 0xe42aad79,
+ 0xc91f9cdc, 0x457fd02f, 0x0df0338a, 0x744093b6, 0xde5abf20, 0xa8df784a,
+ 0x575db157, 0x39757acf, 0x20fa17ce, 0x707d064f, 0x603eb759, 0xe81eb9ab,
+ 0xf20aeedd, 0x7a1a9bf5, 0x5f9469ee, 0x07a0d790, 0xe3f557e5, 0xdc6f8ff8,
+ 0x209de1fb, 0x75ebc7b7, 0xd5eb35b9, 0x782db948, 0x7c84bd69, 0xc7b7291a,
+ 0x894ac00b, 0x3cf0b726, 0xb416dcaa, 0xaaf44bfc, 0x65c7c78e, 0xf5d55eb3,
+ 0x8cf86f64, 0xca9793d4, 0x127aa89e, 0xecb3ef7e, 0xf3a8fc9e, 0x457fcea1,
+ 0x80bd29bf, 0x9f3a09fc, 0xc5d87cea, 0xf61f3aa7, 0xf098cff0, 0x3b7f9918,
+ 0xc10c04f2, 0x7f255dbf, 0xdf134962, 0xdef7838f, 0xf8459fec, 0xc734d1f2,
+ 0x9fecdfaa, 0x11438468, 0x79447d70, 0x8fec045f, 0x80881f28, 0x4be54c2b,
+ 0x8c6af71a, 0x2a6c20f8, 0x2bff9d67, 0x759445f6, 0x950f3eac, 0x82d49c37,
+ 0x9d691fc8, 0x753fea1a, 0xe8a89821, 0x9329dc3f, 0x7003b0ff, 0xe9da04bc,
+ 0x0a1198d8, 0x6c591e82, 0x0ecdebe7, 0x012ba777, 0x1cf1c5d2, 0x96d24cee,
+ 0x9fd41ea0, 0x1fb9da77, 0xe9dfc3a4, 0x31f8378a, 0xa4c9360e, 0x6c425bc7,
+ 0x093f3472, 0xdf8434cc, 0x3e5bd616, 0xe0768ff7, 0x87b633be, 0xcf40cefb,
+ 0xfa4765ab, 0x56bf5c7c, 0x23605ecb, 0xedc16b36, 0x77a1742e, 0x71ba0d34,
+ 0xfd9f3c1a, 0x6db7ccb6, 0xafa53e82, 0x8471dd61, 0x2b189f05, 0x72de7ee1,
+ 0x4d999fe2, 0x6b321d7c, 0x28797479, 0x39e5ef12, 0x77a869e6, 0xb9f0fd61,
+ 0xd7ac0fd1, 0xe23ab053, 0x42f5d379, 0x3d69aa6e, 0xce6b5458, 0xd4f5880f,
+ 0xc9feba37, 0x7fa49964, 0xeb84a170, 0xafb7a17a, 0x38de8796, 0xb1d3e80d,
+ 0xbfb8664f, 0x2649aa7a, 0xc8da9cfa, 0x305953f7, 0x8cafe489, 0xd4be9275,
+ 0xf286d6f1, 0x7aef7175, 0x9feb6dac, 0x3e421fb2, 0xe187f6da, 0x6db482bf,
+ 0x778327db, 0x47cafc20, 0x3d607fe9, 0x65d84fcb, 0xc7733f27, 0x7ff1272e,
+ 0xa5dfcec7, 0x76f0843f, 0x3af7f92b, 0x1c3b7d76, 0xa163b1f9, 0x60f500b5,
+ 0x7ebe00c7, 0xedf9daaa, 0x7f9a16f0, 0x331d1117, 0x7de88d14, 0x072fe9aa,
+ 0x54e02e30, 0xed0a8c13, 0x24b15d8b, 0xdaafe55f, 0xb1d11fc9, 0x80ecdbf3,
+ 0x9e379fe3, 0xd3ffb132, 0x5ed364e1, 0x73c5fec2, 0x8ef979bf, 0xc02ecfd1,
+ 0xdd86f1fd, 0x9fc84cda, 0x875fdaf0, 0x78ed7ea3, 0xed4ddb89, 0xdc1acb6a,
+ 0x48ba18df, 0xbd02a85e, 0xfac851da, 0xd16fb631, 0x4728f1c4, 0x57f2f13d,
+ 0x2f9cb3f2, 0x7c28263e, 0x8feffb3d, 0xf5c7c90f, 0x9364339f, 0x1ddfdc70,
+ 0x89ea03f8, 0x4be2565d, 0xebc7bc7d, 0x733d9017, 0xfbdf71ae, 0x52dc6e3f,
+ 0xbdc67cf8, 0xff9cdfe0, 0xfa878aad, 0x3d072917, 0x03e77cf9, 0x7a726f04,
+ 0xc9e7bfa9, 0xa7ff6bef, 0xa025fdd1, 0xe3dcebbb, 0x4b3fff0e, 0x0ba7b7f7,
+ 0x3e31bbba, 0xbfb5fca0, 0xa87eff52, 0x37f96b9e, 0xe36f7ba7, 0xb7fdedd7,
+ 0x33f79e2c, 0x5664fca1, 0xe2c340ed, 0x6f3dd2da, 0x5bee4267, 0xb1e37b69,
+ 0xf623e3bf, 0x5e34f47b, 0xf1b6fee5, 0xed03efb8, 0xac4978b2, 0xab3af917,
+ 0xfa2fb0bf, 0x3b23cbcf, 0x63da7fa4, 0xc5304f64, 0x2bf712b3, 0xe99f4adf,
+ 0x360bd8a5, 0xc200e3e2, 0x6c052bee, 0x4afe6f5e, 0x4adc3e62, 0xfd7e9fed,
+ 0xd373b43e, 0x83b264d2, 0xf7fb2521, 0xfe64d775, 0xad3344bc, 0x98f5ae87,
+ 0x129347d7, 0x89a8ebcd, 0x19abbea2, 0x0ed5ffef, 0x3c021429, 0xcbf01f8c,
+ 0x8ea7f444, 0x126548bf, 0x605893c0, 0x263bae11, 0x9df5cc3a, 0x836c7dc0,
+ 0xc5eff1bf, 0x3c2ec4e3, 0x47e95c0e, 0xc9900e3c, 0x3c4e7aaf, 0x6f09bf62,
+ 0xc78c2199, 0xe3978a61, 0x4bd4a131, 0x1eb16a7e, 0x1da26ec7, 0x349638a3,
+ 0xb82b3ca3, 0xa078e69e, 0x9ebeb875, 0x4cdf0dee, 0xd115cfac, 0x257f8ea4,
+ 0xcdd9f64d, 0x5cfad1f5, 0xa50fcba7, 0x7fc74e87, 0xaac92e94, 0x8e692e99,
+ 0xebca0a39, 0x8c3f5c64, 0x1c99f2c4, 0xb42a0b4e, 0x0fd624df, 0x28e678d7,
+ 0xa4278041, 0xaf482a65, 0x22f6db7c, 0x79b51f8c, 0xc5c7ea25, 0x1f9a166d,
+ 0xe112596c, 0x428d487d, 0xf7167bf0, 0xd4f7a428, 0xfe395e2b, 0xbb3f4320,
+ 0xba06e34f, 0x7c97ef9f, 0xd8cce67f, 0xf0c7f46c, 0xde7fc61f, 0x59b7eb00,
+ 0x063859ab, 0x615b34f0, 0xf404b8c1, 0x73ec4b93, 0x0cdc9f93, 0xe4aaefe3,
+ 0x55ce7aee, 0xf2bd37be, 0x015f4ecf, 0x45f9f63d, 0x94c76d8c, 0xc6288a6f,
+ 0x9a8ff6f5, 0xf7cabe38, 0x1e40d0b3, 0x0dfb2187, 0xab2f8afb, 0xcaf33fdc,
+ 0x891a5f1f, 0x1d71dceb, 0x7eb8e343, 0xa971e2cd, 0x8a70bd62, 0x0ebce279,
+ 0xe283afd4, 0x9f74bf68, 0xe7168cec, 0xbfac41b8, 0x28f1837f, 0xb2d47690,
+ 0x57d7196a, 0xbefc93ac, 0x5b1b5ac1, 0x661e251f, 0x7e116a8d, 0xf8374122,
+ 0x7fb8d9c9, 0x0d9fdbc3, 0xe919c6af, 0xa8e536d6, 0x1d27bc32, 0x61b9f7f0,
+ 0xc51feaff, 0x11f7ae2f, 0x2dec1bbf, 0xf451fc93, 0xdfc0bd47, 0x91df3dd4,
+ 0xa6d2f49f, 0xdfe416b5, 0xa62d6b4b, 0x553ad8fd, 0xb04631f8, 0xa9afd811,
+ 0x2cceec7b, 0xd93ecba4, 0xe5a5f18b, 0x40b5274d, 0x48c47d94, 0xe8fd627c,
+ 0xdd556f7f, 0xb50eeed4, 0x75e2267e, 0xc31b09c7, 0xad76f575, 0x3f5a38ba,
+ 0x7ef2b4ef, 0xf7f566ce, 0xf7f8cf0d, 0x0eb8efc3, 0xae3c7847, 0xf0996b3f,
+ 0x1ff24483, 0x553e3e23, 0xbf3842c7, 0xf5157ae2, 0x8c8da9c2, 0xc94077e6,
+ 0x06feb863, 0xd1b1ff79, 0xe37173af, 0x5da0df96, 0xb924d650, 0x4ca24b71,
+ 0x8fd0d169, 0x2f18de5b, 0xe99c3ce3, 0xdd6fe3d1, 0xc8356ec3, 0x10aaab45,
+ 0xd98ef6be, 0xfbb61771, 0xd0c69b65, 0xdebdf14e, 0xfc79c2e9, 0x2491a6cb,
+ 0xeb8dbd07, 0x34564ae5, 0x841ce311, 0x87e48c3e, 0x4c631ba1, 0xa07215f0,
+ 0x54d7ca1f, 0x6f3ccb6b, 0xd32dfa14, 0x788fb124, 0xf42dfa9e, 0x7b7e99ff,
+ 0x016fd75f, 0x23906fd9, 0x419bc0bf, 0xd344a5bf, 0x4f25736f, 0xee7de20a,
+ 0x482941ce, 0xab6fb9d7, 0xdbf4d149, 0x2fbe4aa6, 0x4dc459ba, 0x7e803477,
+ 0xdfa0dcbb, 0x45bf401a, 0xa3191f89, 0x73fa7ee9, 0xbfd0b7e8, 0xa136fe46,
+ 0xde328b7e, 0x74fe041b, 0xe9bc36fd, 0xe1b7e920, 0x3c53160d, 0xf84d44f0,
+ 0x6fd57a9b, 0x68add252, 0xbd53ef1f, 0x67f851b1, 0x37c7b093, 0x6c46388b,
+ 0x955cf507, 0x5cf4c3f6, 0xb9eaf9de, 0x759e117f, 0x2b77373d, 0x9ee8b8a3,
+ 0xdcf5c87c, 0xe7a0eddc, 0xae47e424, 0x64eee6e7, 0xa1172fdc, 0xd0f486df,
+ 0x97ca8c6f, 0xe5fbf985, 0xde4f198d, 0xf08df50d, 0x941b5ea9, 0xefadd11f,
+ 0x5df51946, 0xbe8bd695, 0xfa7e77db, 0x77d0ab6e, 0xa206c7a0, 0x0fe48d7e,
+ 0xde39936f, 0xc3e8c77c, 0x79465f1b, 0xfb4c9df9, 0xf859ef92, 0xa33bd1fe,
+ 0x7f21670f, 0xf3fa2a7d, 0xd9e9c6a2, 0xfaa4195e, 0xc7cebc27, 0xfb91ba57,
+ 0xb81acbcb, 0x2b56587d, 0xe7f03c87, 0x69df31a4, 0x9dc2ffd8, 0xf8014b12,
+ 0x13f56b26, 0x9febb40e, 0x1f589957, 0xf034c94d, 0x629cacc3, 0xd957fbf2,
+ 0xfcf0eb5d, 0xd9852cd1, 0xec5fbfd0, 0xed147498, 0xbe1ce2e0, 0x9e2c501f,
+ 0xb3b071eb, 0x4464f4bb, 0x9ce3483c, 0x9eb3fb37, 0xad531671, 0x9f53ae9c,
+ 0xb7184295, 0x22ee33da, 0xb8a17a44, 0x5dfcfcce, 0xc9377f21, 0xf62f842d,
+ 0xee351cae, 0x85d72f43, 0x4f027da7, 0x9e131780, 0x3c545242, 0x64a7a501,
+ 0xa5e37726, 0x4b2d77f0, 0xf0a05f70, 0x91f68929, 0xe3adc723, 0x3afc722d,
+ 0x773f751e, 0xbf2fa8b1, 0x6b9d2d69, 0x8e8bc48a, 0x747c48e7, 0x1f023de1,
+ 0x7e5d69ef, 0xd71891ed, 0x7a437c04, 0x809ff826, 0x3fc76817, 0xf9d322ee,
+ 0x5e048f9b, 0x9b8f5646, 0x370fe180, 0xe43a1c61, 0x79ccd5e7, 0x63e02fb3,
+ 0x119ec7d4, 0x315e9d38, 0x7dc01ac6, 0x4ef60dda, 0x1f3a83d2, 0x3e72b30e,
+ 0xd95e84d4, 0x3c62afd1, 0x251bf3ad, 0xe521da37, 0xb5e13b61, 0x0ed1f81c,
+ 0xf53ef645, 0x578124cd, 0x6aaf9d37, 0xd013f314, 0x26eb82c1, 0xf10abe7d,
+ 0x9b2358f3, 0xebca5d38, 0x58b25d38, 0x94c7ed27, 0x30de48d5, 0x71aca78c,
+ 0xeba1c50e, 0x0e7e19fa, 0xf0a29d23, 0x7f8d12af, 0xb39b3a19, 0x62cde7bb,
+ 0xb5aa6e51, 0xe7dc43fa, 0xb1f20a99, 0xfe10d896, 0x3efe1677, 0x2450fc57,
+ 0x78132ebd, 0x757884db, 0xb93afe20, 0x8efe15fd, 0xf9e969ce, 0x84d04ae5,
+ 0x9f4f09d7, 0x53b7fce6, 0xac5fa0f2, 0xcfc86f0b, 0xc74a3f90, 0xd233f21b,
+ 0x465729a1, 0xddf00f38, 0x78e7a327, 0x28d4bf71, 0x0f3b85f7, 0x919ffaf2,
+ 0xb8ca2cbc, 0xff7f307f, 0x4deebe40, 0xc55987de, 0xf7f0413a, 0xfdcef63b,
+ 0x77bf9123, 0xd12fdc4a, 0xf7da6f14, 0xd7cac1bc, 0x20ec1b4d, 0xf6dfb807,
+ 0xe75deab6, 0xae1fa9e9, 0xc03972b2, 0xe0c784f5, 0x0704baf7, 0x75a6f182,
+ 0xa4178a36, 0xf6e40c7e, 0x6f5f51aa, 0x5ba4b3b2, 0x7faf7ab3, 0x37bfa88a,
+ 0x8787497b, 0x47a87b61, 0x21bda11b, 0xce45eddd, 0xe0ffba17, 0x43bae35c,
+ 0x3bdfcff0, 0x1f9dbd2e, 0xce554f1a, 0x4c5f699a, 0xb54aab8f, 0xd1515e04,
+ 0x992c9bbe, 0xe7a0b7e2, 0x70ffce82, 0xa36ab7fd, 0xa59faf7a, 0xd08ec8da,
+ 0x2d5ecbcf, 0xf010583b, 0x254fa5f6, 0xe32b0179, 0x7f38b183, 0x1079878c,
+ 0x8ff72f92, 0xca6ee8fa, 0xed9f6997, 0x29f5dfc6, 0x1bc87dc5, 0xbb1d0c79,
+ 0xfb225331, 0x6cac3de1, 0x36e1da34, 0x268ab3e6, 0x47e73f21, 0xd73c21f1,
+ 0x3d5b5992, 0x3d7203c1, 0x85542ea2, 0x674277a9, 0xaf483be2, 0x7a433271,
+ 0x4cfafb35, 0xbef7f9c0, 0xdc4cb33f, 0x813b078a, 0x8fb119ea, 0x31b96125,
+ 0xce5a24be, 0xeaf86e8c, 0x7fa05bfd, 0x5ecbf7a3, 0x69bb940f, 0x7281c3af,
+ 0x85b56436, 0x19780c05, 0xe85542c3, 0xc87d1a77, 0x83ea0b77, 0xf07bb002,
+ 0xd341497c, 0xc2172ada, 0xbf7a25ab, 0xe498183c, 0xaa6dfe82, 0x32e93939,
+ 0x0e500bd4, 0xcd5f29ab, 0x4ad795cb, 0xce710c5e, 0xf1415a6b, 0x12b57948,
+ 0x14dc601d, 0xd78d9892, 0xbd41b21b, 0xfbc3569b, 0xc17f3859, 0xed6f58fb,
+ 0x416ff7c9, 0xa4fd03bd, 0xfdf237f7, 0xcf783cfa, 0x3b527283, 0x5c2bea87,
+ 0x073c312d, 0xcf91b053, 0x55fb054f, 0xec37e62f, 0xdde68a7e, 0xdf5ed029,
+ 0xc28f9c0c, 0xd13ce913, 0xe74dc948, 0x80be1f38, 0x0e0756f4, 0xa5f05f18,
+ 0x4909f8f3, 0xa3fd62c0, 0x6dfd7fdb, 0x9e535cfc, 0x07d68177, 0x272779ea,
+ 0xfc42c329, 0xe1f69274, 0x03be010f, 0x79379c56, 0x9cdecb3c, 0xc316b42f,
+ 0x1b6398fc, 0x6acfef44, 0x1e71471c, 0xe29f99b3, 0xe68ea63c, 0x57bbe776,
+ 0xefe843da, 0x4ced577b, 0xaf7be7c3, 0xf6f3d2b4, 0xb70f5c4d, 0xbf21680f,
+ 0x2ad5e1fb, 0x552ff3c3, 0x13d265ab, 0x74aa3787, 0x867e576e, 0x6fe437c7,
+ 0xdec876e2, 0xc3debcd5, 0x9b7edc75, 0x936dccf0, 0x5fce1e70, 0xeaf9cfcf,
+ 0x875f5a7a, 0x4d0bb9e6, 0x9ea45bf3, 0xa970f5d5, 0xf54147c0, 0x8f4fda5a,
+ 0xfaa5bbd4, 0x6fa1187c, 0x9d9f714b, 0x24c3d3f6, 0x91f5a547, 0x6e8e65f1,
+ 0x43f20dbf, 0xefe23bf8, 0xc32afdb2, 0x45f48d75, 0x678a24db, 0xf21ef9c3,
+ 0x3e493747, 0xf8287b8c, 0x7b221ad8, 0xe33b943c, 0xf99e703f, 0xc8f0cac4,
+ 0x03d22b48, 0xb58e54f4, 0x84bf8ff3, 0xb3df47e7, 0xf010e461, 0x5fe12e4f,
+ 0x5ace138f, 0xb27ee3cf, 0x8c995bde, 0xc4d98de7, 0xf207a43e, 0x3016646b,
+ 0x92a38de8, 0xf93b96ef, 0xfb46e0fc, 0x966ba747, 0xf3879d56, 0xeb8d916c,
+ 0x957acf47, 0x0bc78bce, 0x3e0bd618, 0xb70a77b4, 0x0cd648af, 0x73b850fc,
+ 0x0ea83245, 0xcbc444b6, 0xe6738954, 0xa76f1a85, 0x5ee49770, 0xaf47686b,
+ 0xdb57af47, 0xb41bdfce, 0xd5bda793, 0xa3fd885f, 0xa1ad7e71, 0xa7ac88de,
+ 0xd4bdfb47, 0xa75ff393, 0xffb9e257, 0x0a65779c, 0x62f9cf76, 0x3ee320ca,
+ 0x7eea9e8f, 0x2df7ece6, 0x5fc067cc, 0x98631fce, 0x86ef40cf, 0x40ff2051,
+ 0xb91a1bbf, 0xea30d73d, 0x459a56a0, 0xbde51bb0, 0xcba3f84c, 0xbbfdf226,
+ 0x16f7cc86, 0xc94ffca1, 0x581f8892, 0x49f5a030, 0x83cdfb24, 0x59f900fb,
+ 0x787cfdfc, 0xe1b2e51f, 0xa0a72e29, 0x4fa83c2f, 0x98af56ca, 0x256be544,
+ 0xb0dfd60f, 0x92ec9736, 0x51991c82, 0xb241ed7e, 0x0f1a0a93, 0x833ca226,
+ 0x7b44aefc, 0xd5ac6ca0, 0x9758ea8d, 0xdfce5d4b, 0x9961e715, 0xcf0c3dcd,
+ 0x5876e077, 0xf796f934, 0x72b76133, 0xe1cf2cb9, 0x26eefb72, 0x3e784715,
+ 0xad724e72, 0x728cb1cb, 0xc72dd59c, 0xd04f577b, 0x870fae50, 0x99a38a24,
+ 0xe5007a80, 0xe71e837c, 0xf3d8edc4, 0xd973f395, 0xbf20a599, 0x72ea5f38,
+ 0xa475cbae, 0x2d2b373c, 0xee3f62b7, 0xe34ed2bb, 0xf6d57098, 0xfae3ef0f,
+ 0x275ff68a, 0x3260f55c, 0x853cc7ea, 0x78e979c7, 0x5c78552d, 0xad7e8f60,
+ 0x3df5a05c, 0xf445fe9f, 0xd9ab33e3, 0x8b6f125f, 0xb5eff1e7, 0xb9fdf12a,
+ 0x9c87b3e4, 0x9e7ca79d, 0x4b9d5caf, 0xe5f6f53e, 0xe27ae69d, 0xf5476991,
+ 0xf01dafac, 0xbe3c0618, 0x8a59f1b5, 0xc2f13e0f, 0x8748a9c1, 0xe7c01de2,
+ 0x9d1b5fc8, 0x4e7a8c2c, 0x55bcd109, 0x39d320d4, 0xb384a603, 0xe51a716f,
+ 0x1575c798, 0x3f12766f, 0x0d64bd15, 0x8bf7814d, 0x9c317db6, 0x76166ae2,
+ 0xf05adc52, 0x072f6105, 0x1ca3865b, 0xbe3c2914, 0xfc2f522c, 0xe7edc6da,
+ 0xd3b1edb6, 0x1d527c70, 0xa8a2dfbf, 0x6ad576fe, 0xc278a7d8, 0x50bb52a6,
+ 0x8379f68e, 0xfe78c7c0, 0xbc67fb17, 0x2b8f4157, 0xf5c0db6b, 0x1aa35144,
+ 0x8a327bc2, 0x63b4b6ea, 0xc7d171bc, 0x957ff256, 0xf3a49dd7, 0x6f361314,
+ 0x794aff22, 0x8fda6ca3, 0x59df11eb, 0x18ad8727, 0x4a50d897, 0x1f0090fb,
+ 0xc45eb824, 0xf8c0fe53, 0x3bcde2c3, 0x850105b7, 0xef3f2fc5, 0xac72fd42,
+ 0xf10bbd79, 0x359ef50e, 0x3c47bade, 0x2223fd67, 0xc386f39e, 0x2f4b6f74,
+ 0xf0c79cf1, 0xb794100f, 0x4e78e66d, 0xec87d756, 0xb667e84b, 0x47feca3f,
+ 0xe9be7d97, 0x1e7835eb, 0xe3a5eda1, 0x25dfb06b, 0x0d72fb7f, 0x5db189c6,
+ 0xcaf79a76, 0xe280f85f, 0xbef7f5b7, 0xc87f09b0, 0xfe29e786, 0xab13fdbd,
+ 0xdf6b6b17, 0xe31d3879, 0x7cb7db06, 0xccfe8c97, 0x26af3b79, 0xadbcef7f,
+ 0x94585213, 0x914f4379, 0x11e7437f, 0xb7491f7f, 0x297b0dbd, 0xd004ed9e,
+ 0x5760f51d, 0x297d6e9c, 0x88f67f8f, 0xd18ddcf8, 0x88f43bcf, 0xe5b86dc7,
+ 0xff512bc6, 0xf27b7037, 0xefb9719c, 0x3f2f3d03, 0x146e3a0f, 0x37f5d7f1,
+ 0xf72e359c, 0xf401fe04, 0x74cdd8b2, 0xf661bafc, 0xbcc69faf, 0xc6bd3e86,
+ 0x03cf86e5, 0x8a79fa7f, 0xa73e6c77, 0xa5e8e51d, 0x343c50df, 0x078a6fd2,
+ 0xd3afa3e7, 0x11ca3cf1, 0xce3a73b5, 0xad3b9d3f, 0xd14fdf74, 0x9e488fce,
+ 0x47beb7da, 0xce266a7e, 0xaeb3b435, 0x973f8f1f, 0x9d6b78c4, 0xd0579e3c,
+ 0x3d7de301, 0xe22e7a2e, 0xeb5f397a, 0xc5bdbef1, 0x1f6d5ef9, 0xe00fee28,
+ 0xb5a5c8f1, 0xb3f1107f, 0x729374dd, 0xcf075e90, 0xe3ad471a, 0x72f42dc1,
+ 0xf47b1c77, 0x38aeeab8, 0x21ba08f6, 0xea9e713d, 0x3807538a, 0x49f9046d,
+ 0x2e768a3e, 0x8f2d7da2, 0xa3576f7f, 0xe3d6379f, 0xf4117dda, 0x9bdbc7d6,
+ 0x7b72e8bc, 0x50fc71ae, 0x4266d13c, 0xb57c4f52, 0xbf5d1f7d, 0x7f4bb4cf,
+ 0xebbefad7, 0x148954bc, 0x5eeb1e79, 0x86d2cbe4, 0xeccfe483, 0xf18b7f5a,
+ 0x7bff09b6, 0xc5320bdb, 0xdfa92f39, 0x523dfa4b, 0xbde1947f, 0x7bfa512d,
+ 0xe7d85dbf, 0x68fe7c8d, 0x7219c97b, 0x7b6d3d40, 0x975f13b6, 0x71483c6d,
+ 0xbdd66fd6, 0xe218b5ac, 0x08fe7027, 0xf6d3c619, 0xa4e1eee2, 0x30fdc5cf,
+ 0x8954ed91, 0xa29bca76, 0xf1be53b7, 0xe29da9a4, 0x76e6bd60, 0x63bdbb9c,
+ 0xac76ef8a, 0xb73358ef, 0xcbd58f13, 0xf6d14393, 0xd8aaec69, 0x29e6afef,
+ 0x0f74a3cc, 0x7bdf938e, 0xc862bb23, 0xcce79cee, 0x112e38f9, 0xbae28d53,
+ 0x388816aa, 0x537a9fb0, 0xce55de91, 0x77f618eb, 0xe0d7e231, 0x01dd51ff,
+ 0x9aaaf686, 0xbf42cfea, 0xd1dea443, 0x642c2d12, 0xe73cf7a0, 0xed0f14e4,
+ 0x90d3848b, 0x0f32079e, 0x67ef58ab, 0xcfabfe11, 0x0524b614, 0x5059f7fa,
+ 0x7a802ef2, 0x0c5ff7d9, 0xd67b3bf0, 0x8781c3af, 0xa9bf9365, 0x0079dacc,
+ 0x35ec2bd7, 0xc847ed3b, 0x7f74ecbb, 0x3b1af948, 0xd6ef778d, 0xbb239f6f,
+ 0xc656d7fb, 0x556087f7, 0xb996f783, 0xb7871d79, 0x2fe6bb7e, 0xcbe35768,
+ 0x1afe7ed0, 0x89eb8f28, 0xfeb4b18d, 0x8e2978e9, 0x7fcb51ee, 0xa8a9a1ed,
+ 0x3963f2d7, 0x4e6fe63f, 0x7d415509, 0x6e1c49ad, 0xee8034dd, 0xc97e28ab,
+ 0x7ba5f149, 0x8652beb7, 0xe6fb54f3, 0x60330c58, 0xfb09afed, 0x7ee237ff,
+ 0x63d51aad, 0x642f338c, 0x2e78c78a, 0x536118a8, 0x3f23135c, 0xfa11c906,
+ 0xe8e31ab1, 0xc5d8113c, 0xa84e7aa6, 0x89780f9d, 0xf8fd838f, 0x3f70aa39,
+ 0xe59107d4, 0x76fdfcf4, 0xdcbd8e7e, 0xba39ef0a, 0x9d6b97cb, 0xeeae1c79,
+ 0x3349f5c7, 0xe744ff95, 0xb3df9173, 0x23fe5e5e, 0x7aaedebd, 0xe265fbf8,
+ 0xfe489b7e, 0x57a5d43d, 0xb4717afe, 0xf4a25bfb, 0x2fdf9e9f, 0xed05a0b1,
+ 0xba762d96, 0x67ef0bb7, 0xdb0e73c0, 0x55ffbe34, 0xfdd30ae2, 0x3e843b39,
+ 0xd309892e, 0x44fd3e7d, 0xc23cb03f, 0x22f2d6cc, 0x15f4bdd2, 0xb3f8c33b,
+ 0x3e9cd7d2, 0xb6e977a4, 0x957f5b6f, 0xb18bf185, 0x7d2bd7e4, 0x1f117fed,
+ 0xd3c35a94, 0x2dbcfee9, 0xe7f78656, 0x3b796db5, 0x4db5e51d, 0x9c27a70d,
+ 0xb4af5f65, 0x57be6ade, 0x58e38c40, 0xbc42e865, 0xaf3f4177, 0x9e8bd45b,
+ 0xdb8632b9, 0x9f18f6d7, 0xdde48635, 0xb1d44f7c, 0xc641c6ca, 0x9e45fbf3,
+ 0x7fb17ae8, 0x9d8ffa8c, 0x38f47743, 0x263fdaf7, 0xe699ed09, 0x96407464,
+ 0xfa8e3d81, 0xe4eea8bc, 0x7c1ff430, 0x6fdfa316, 0xf9c389e0, 0x73ad33e8,
+ 0xcfbfea18, 0x19873bd2, 0x952399e7, 0x92a28f36, 0x8ed2875f, 0xfaf327b5,
+ 0xb5378c31, 0xf7a68b4f, 0x12c4c586, 0x8e1e8afe, 0x7a8e7a8d, 0xabe70c4c,
+ 0x531f6834, 0x43e5176c, 0x2d33f76f, 0x31b87a44, 0x49ebc3c6, 0xbcf8690b,
+ 0x20fb6eb8, 0x950a1e23, 0x72072a6a, 0x642cf84a, 0x832cb52b, 0x2bdbd6fe,
+ 0x28f0ef9c, 0xf2813f74, 0x55f8ba7f, 0x3933a6ee, 0x518e3191, 0x5c6614e0,
+ 0xe7eb33f2, 0x6fd51448, 0xcc69fc43, 0x646456ef, 0xf7926a95, 0xa94f5618,
+ 0x7e2ecc03, 0x43055a5f, 0xec44793d, 0x0c1fa3ef, 0x3d7c6ed3, 0x383f7a48,
+ 0x328bb180, 0x4f09bef0, 0xbf80db9c, 0x3eb3706b, 0x2b69e309, 0x5317d718,
+ 0x488f68dc, 0x033b00c1, 0x595554fc, 0x03df8837, 0x2f187cc2, 0xf42c2649,
+ 0xf37ee5cf, 0x8083b43b, 0x843df94f, 0x1550b157, 0x86c318a0, 0x9e3aefc9,
+ 0x96f3fbf1, 0xeb8ccc7d, 0x0741128f, 0x7a4ddc16, 0x7fbac1cc, 0x5aa3009d,
+ 0x155b7d45, 0xdc1cb7f7, 0x59b8739f, 0x58c3ed18, 0x42c70b07, 0x1caa18ea,
+ 0x2bbfca33, 0x5f03600b, 0xf39ac7ba, 0xf402e523, 0xf5bb445a, 0xf7a83f84,
+ 0xbf7a88ab, 0xabf7a88a, 0xe3abd5b3, 0x2836dca9, 0x58a5ef03, 0xf02f595c,
+ 0x09b3dbc6, 0x867e01bc, 0xcc7f3de0, 0xfb15e312, 0x18d784e6, 0x962b1bd1,
+ 0x8e6eba07, 0xfa7e20c9, 0x4eaedc59, 0x8966978c, 0xc3d70c35, 0xbefd248b,
+ 0x1877e64f, 0x1b6e63de, 0xa223e1c9, 0xcf02cd9d, 0x55bf748b, 0xb276f28f,
+ 0xb7947abf, 0x263e56f7, 0x6f67797a, 0xde8d89fd, 0xea5ef89f, 0x5a8d8eaf,
+ 0x4bd50fff, 0xf47daf65, 0x76efee0e, 0xa03727e9, 0x6e676cde, 0x1a54fd46,
+ 0x16b7fadf, 0x4cedc27a, 0xde999a5b, 0xc0dfc831, 0x9a17316f, 0x49f2479f,
+ 0xf472fe14, 0x29df7185, 0x61f3bbda, 0xe74d5e7e, 0xbe315c83, 0x9f7cb589,
+ 0xdc79eefc, 0x46cb078f, 0x25dfe61f, 0xe1aeeff2, 0x0fdde3f6, 0x1b0fb4cb,
+ 0xc1d5bf79, 0xe1efcdff, 0x801f07b8, 0x5f33ddbc, 0xa233850a, 0xdec5dbdd,
+ 0x677a878f, 0xde44fe88, 0x9e601583, 0x68e4cb49, 0xbe7160f7, 0x45e1cfd4,
+ 0x8b317fde, 0x66fdc5f9, 0x3159e7e6, 0x22dbe26e, 0x0f55a425, 0x82c79eed,
+ 0xd1ef802b, 0xc7be04fe, 0x9c592ffd, 0x8d2e66c7, 0x9adfd7c7, 0xa77fd260,
+ 0x70e27886, 0x8baf66be, 0x7cfe6ee7, 0x149eb5ee, 0xe54579e3, 0x1ee9ac74,
+ 0x9bd52aa0, 0x3d4dfa8a, 0x80f33d7d, 0x07a76a1c, 0x1f218f31, 0x7e1256ec,
+ 0x3d24f30c, 0x5084aa95, 0x3f6e2a2f, 0x37bb47cb, 0x5eb3f39e, 0xaebc4b5e,
+ 0x177ccecb, 0xe6461dfe, 0x5dcfff81, 0xdff3a1e1, 0xa7fc3957, 0x5d95fe71,
+ 0xa380de39, 0xb7043f27, 0xe15771f2, 0x8e7a33b8, 0x7af34aa7, 0x0ebedec9,
+ 0xcbf245e6, 0x3fd86d79, 0xc8f9ead9, 0xadfbfd83, 0xd30fd0ca, 0x23de3f13,
+ 0x153fc821, 0x24714fea, 0xc194dc72, 0xbc72fed8, 0xfff4146f, 0xe8bf7132,
+ 0x52264aa2, 0x08b7571e, 0x34a51fef, 0x913ea447, 0x8f72a64e, 0x974a7b8a,
+ 0xd5297a54, 0x56f36bf1, 0xb6983dd3, 0x36fb790b, 0xa25fa0b7, 0x402fe045,
+ 0xb52d97f6, 0xed1df682, 0xde308aee, 0x60d2c727, 0xb961c1de, 0x9abf09ab,
+ 0x13bf919b, 0x456c13ca, 0x66b55218, 0x7149d10a, 0xc87cb057, 0x0604754f,
+ 0xe37da2c7, 0x6987df31, 0xd6711d4d, 0xf8bb31fb, 0xfbc7136d, 0xb7e71263,
+ 0xa63fbc48, 0x6e307b36, 0xbb6bb1e2, 0xbc22abee, 0xe38872c3, 0x7ef93ffd,
+ 0x37bc4f6e, 0xc0699b4f, 0x327b33bb, 0x0267fde1, 0x5e054bcf, 0xaa1d04ab,
+ 0xc4ab3e04, 0xe255afbd, 0x812adcde, 0x3bc42adf, 0x7b888fa4, 0x3d23177b,
+ 0xef119520, 0xa1d6bfc0, 0x7b432641, 0x520f0f7c, 0xb75be087, 0xb2a4fc85,
+ 0xbc43efc3, 0xde39135b, 0x03a00e6d, 0xdde035f1, 0xc241f983, 0x78e0eaa7,
+ 0x0e9cf286, 0xef105602, 0xa739f123, 0xb6fde007, 0x87d424d8, 0xd6784c63,
+ 0x1f9fc712, 0xf3e29fde, 0xf390a25b, 0x6a25fc48, 0x5d605efc, 0x8fb37bbe,
+ 0x765c44ab, 0x1197b895, 0xcd7688f1, 0xbb0fc02a, 0x3f93e398, 0x2f60221f,
+ 0xfd6249a5, 0xc074055f, 0x3d8527fc, 0x74c67884, 0xb75f2c67, 0x762a5a24,
+ 0x04a788ab, 0x4b0fdf7e, 0x6cb4b20c, 0xf18043c6, 0x1e641a97, 0xe1fdf584,
+ 0xc8ff335a, 0x7ee2256e, 0xc893cf49, 0x56df2b6f, 0x2f7fb82d, 0x74debfcf,
+ 0xe69e5bae, 0xfe10f78b, 0x35da1203, 0xb872133f, 0xfa85f902, 0x8bc3d7c7,
+ 0x152c1f05, 0x223f06f7, 0x2131e7f8, 0x7ceb8fcf, 0x48e7e5e3, 0xf1e64f96,
+ 0x1699898e, 0x9862bf71, 0xe309e319, 0x834cf5bd, 0xc6dad17e, 0x9fdd2943,
+ 0x92b63ec9, 0x650ec6dc, 0xf8afe43e, 0xf10c1f8f, 0x7dfd70fb, 0xd78a1ed1,
+ 0xeb1dbfef, 0x0e83bf89, 0x711587b4, 0xd7cca4cf, 0xef51cd93, 0xeef2ad8d,
+ 0xa65fa1b1, 0xbeecfeb7, 0x73f11b69, 0x1e44e5de, 0xbfe027d6, 0x8ec03663,
+ 0xc157581a, 0xc81bd62f, 0xa57a8c5e, 0xebfc49c6, 0x1be7fe80, 0x17b624f8,
+ 0xc754ceff, 0x5f501bb5, 0x240680bc, 0x6a2fc130, 0xcf11d906, 0xfa0f7380,
+ 0xfea956b1, 0xac2f38be, 0x8fee8f8a, 0xdf2c65fb, 0x5d657087, 0xac2bf26a,
+ 0x9ef47d54, 0xef59ac7b, 0x44f314ac, 0x9cb344c2, 0x4fc2f3e8, 0x39577d45,
+ 0x5fb13b02, 0x9227a7c9, 0x1cde273c, 0x52a89e7d, 0xf7de20b5, 0xcb8c3551,
+ 0xe3573077, 0xfd0f73f6, 0xe49f68c3, 0x3af06054, 0x7ce983f4, 0x7d7190b6,
+ 0xaedc6417, 0x04f5c7d4, 0xe715bdf2, 0x3ff13703, 0xcb0807ce, 0xdefc6a17,
+ 0xe42dbbe3, 0xe4225887, 0x672151ed, 0xfd7c85cb, 0x8acbe51c, 0x297b58f7,
+ 0xab9085fd, 0x90872895, 0xe0cd8f1e, 0x3fb8bcf6, 0x2ccf5f4c, 0xfba08db4,
+ 0x161cab22, 0x4f94179a, 0xae0721ac, 0x768f760f, 0x7647ffa3, 0x4e03b966,
+ 0xfba2cfcc, 0x2cf8a5dc, 0x37cdf237, 0x9c1759ce, 0xc8161e2d, 0x2b16f74f,
+ 0xea4bf72a, 0x8957c8f7, 0xf75408fb, 0xd5fd0ccd, 0xd856264f, 0x9635de29,
+ 0xe4d787c7, 0x81de1366, 0x86b19d1e, 0xb4ca5a75, 0xfbeebaeb, 0xec9feac3,
+ 0xef835ee5, 0x6960de85, 0x41a17641, 0xfb88d44f, 0xc8279924, 0xc5f41886,
+ 0x31268bc2, 0xd4f5eff4, 0xcde8bd13, 0x2e6f5cf5, 0x4deba292, 0xf5d78edd,
+ 0xd17ea466, 0x4c17c5d3, 0x54bf9d36, 0x7a465e1d, 0x3f744867, 0xcac3b242,
+ 0xd7992ff7, 0x33d19b9b, 0xec95f01f, 0xed0be030, 0xf16fdd21, 0x89e328e3,
+ 0xae4793d4, 0x00d7e7d3, 0x4b343bdd, 0xfa393cf3, 0x79abf3ac, 0xfd3fc85e,
+ 0x794fcd08, 0x5a5347a7, 0xd92d7350, 0x69770c23, 0x1c2ef70c, 0x0bbf7d5e,
+ 0x46b87be9, 0x56af9fec, 0x74bf1843, 0x197166b8, 0x0f76d5c1, 0x2fdc66d2,
+ 0x3de1741e, 0xc8d6b34d, 0x247e9fb4, 0xf14e9826, 0x399fdf9f, 0x63e21b23,
+ 0x9a5dac16, 0x6b38fc8e, 0x373a52dd, 0x37c1247b, 0x59806fd8, 0x79ec8796,
+ 0xbcc6fefd, 0xb43ead67, 0xdbe37bc7, 0xfdd1d5bc, 0x27f8553d, 0x779853ae,
+ 0x7643ae08, 0x8674c6bb, 0xfc8e0f81, 0x82eb4ec2, 0x8ed82d2a, 0x58bad570,
+ 0x2555837c, 0x280fbf44, 0x0fb571d5, 0xf0ea94e9, 0x73298b5d, 0x4f7ed024,
+ 0xdbc472ef, 0x3b5f456f, 0x2d3ebbee, 0x3a0245ee, 0xbbf264dd, 0x56d77df2,
+ 0xb66347e1, 0x4463f25e, 0x7c97a7be, 0x62938f17, 0x7ff9e8ee, 0x6869ffb7,
+ 0x315df58f, 0xe6b4bf8e, 0xe84f92f8, 0xa11f7989, 0xcf8bc450, 0x5a1b175a,
+ 0x66ce4518, 0xb3c7f389, 0xce997ec4, 0xebd7858f, 0xe3e739f6, 0x5e973e48,
+ 0xfaf884b8, 0xcd2a7dcb, 0xafc0656b, 0x17a5efa8, 0x507dd346, 0xe2bb9e0b,
+ 0xfc0b8c71, 0xf94cbf6a, 0xc4eda725, 0xf53fedc7, 0xce8239d2, 0x9df4a9df,
+ 0x5df6af88, 0xda01e74d, 0x3ad3fdc5, 0x7c9cd29e, 0xc1c6bc3d, 0xe9de50f5,
+ 0x743c919f, 0xa66857f1, 0x779e7286, 0x5e5ce7fa, 0x31d9fef0, 0xdeebec38,
+ 0xe0a1771c, 0x2cd7806b, 0x2169349f, 0xc2df9bd4, 0x0d8d8ae5, 0x7b1f9196,
+ 0xd1f7ac6d, 0xc6bff228, 0xb5f931e1, 0xf3965bf2, 0x4caec0f7, 0xcc99c434,
+ 0xc87bdf12, 0x65efcd3f, 0x4b20ee65, 0xfa127945, 0xcc0e5bb0, 0xdbb772f7,
+ 0xd3d4e3cd, 0x79c6bb17, 0xd6fd6985, 0xe8abce3d, 0x53b09e79, 0x13465bf2,
+ 0x5f9e3ddc, 0x9e368e8d, 0xa58c71ee, 0xd1f1edf2, 0xb450ffdb, 0xc0595adf,
+ 0x8b4fa07c, 0x79bffdc4, 0xd434fba1, 0xe3ab791f, 0xb8c32413, 0x4d8a6bf2,
+ 0x35794ff1, 0x5fdf74b9, 0xed5ceafe, 0x76bc835e, 0x36cd85d1, 0x4743e5d1,
+ 0xd532e880, 0x40e3dfe1, 0xf0a17cb9, 0x583d4f81, 0x11d3a72f, 0x82bc382d,
+ 0xae7ddbf4, 0x3ea7e768, 0x8d53a48c, 0x1fac13a0, 0xd2740cb2, 0x7ef913e9,
+ 0x07d2faeb, 0x8bfdc53e, 0x45edf8a7, 0x08b1ebbd, 0xc74465fa, 0xf383a75f,
+ 0x0fd82b6b, 0xdfc2f381, 0xbbf8a665, 0xe827f15e, 0x7f47e3ad, 0x51dff60e,
+ 0x944efb94, 0x1f5851cd, 0xe17387e7, 0xc17dbbad, 0x8fa2e30f, 0xf3a9c527,
+ 0x04167cc3, 0x71aa3e01, 0xf1f7a3fb, 0xb682c43c, 0x974f18f3, 0xf1362e9c,
+ 0x01738a43, 0xff415397, 0x211e7ba3, 0xc50d6ebe, 0xbd19ed7a, 0xd9c5278f,
+ 0x185c1f0b, 0xffb34364, 0x11c1f1ef, 0x29f837cd, 0xde60479c, 0xf0bd79c2,
+ 0x1b86c7f9, 0x18ea97fb, 0x79c4e697, 0xf6fcfaa9, 0xbde383b7, 0x1e1d70fb,
+ 0xab7b275c, 0x8e254860, 0xbf7c60c0, 0x37f4f5c8, 0x145bdfe8, 0x68f0c4ff,
+ 0xcae2f476, 0xdfa0977d, 0x99b2aab5, 0xc5d85552, 0x0ce2ed0c, 0x688f5dfe,
+ 0x2b5e05f7, 0xcae2ebf4, 0xb5b7ee66, 0x70db9905, 0x323b00cf, 0x8ad8fc92,
+ 0x69cf6cc3, 0x7e8dc06a, 0x83dc4d73, 0x65812aa0, 0x67e85919, 0x1a0ccc4a,
+ 0x938d77f0, 0x4f2cd7ef, 0xfdc6e3dd, 0x8fd42b10, 0x9a5b33fe, 0x77e4ca72,
+ 0xe5995d7b, 0xd7e93a04, 0x7ab0c744, 0x1f91249f, 0x1f8454f2, 0x1fa994f2,
+ 0x7da6cd89, 0x28bc488a, 0x281dfe36, 0xb3ff0985, 0x9dfe87c0, 0x3e6ea5a4,
+ 0x8fc295ce, 0xaffa04fd, 0x363b022f, 0xc1f645d6, 0x7c2c0b92, 0xe853687d,
+ 0x3c6b2bbe, 0xf1c5af2f, 0xff71d871, 0x59f5c643, 0xde276098, 0xd5d32610,
+ 0xf1c2128b, 0xdc2123cc, 0xe0978587, 0x5c63a37a, 0xfcf803cb, 0xd7207b79,
+ 0xa6ff7809, 0x0901f36f, 0x81fc33f7, 0x35cf118b, 0x03d33072, 0x772d7fe5,
+ 0x74b96266, 0x8138fac8, 0x39e017a7, 0x9f618087, 0xdcd7df94, 0xe13dcb0d,
+ 0x112be60b, 0x5fdf86fb, 0xc7b7cc6c, 0x1fb02af8, 0x4acbdf91, 0xfda242fc,
+ 0x074cfc41, 0x34fdff9f, 0xf2772f3f, 0x07f10575, 0x6e3ed7f2, 0x3c529d3f,
+ 0x87efb871, 0xb4dd79d8, 0xbcf363ef, 0x114f686e, 0xe05ad8eb, 0x4fb0c557,
+ 0xb3e2a177, 0x545d3f20, 0xfd8dcf0d, 0x2727628d, 0xf2dae838, 0xdebd76a8,
+ 0x83af3c3f, 0x4f4f94f8, 0x92247b22, 0xed74762f, 0x69eff027, 0x9e33a1dd,
+ 0xf1c388b2, 0xfad1ff4c, 0xfdae93ee, 0x761c45aa, 0x5efca873, 0x69fe3fbe,
+ 0x99c51c6e, 0xa3b8fdea, 0xda336969, 0xf53477c5, 0xbcf8899d, 0x3fe2e0a3,
+ 0xed43ba63, 0xfa8b13dc, 0xce897ee2, 0xc1f9dd97, 0xa42c6aeb, 0x475fdf5b,
+ 0x2f3c1ff7, 0xeb3a71e4, 0x01fe9154, 0x7ef8d6e6, 0x47df8857, 0xae02bcc5,
+ 0x715fd157, 0xdb743877, 0xf3dd000d, 0x3406e87a, 0xebefa6f7, 0x43d5037c,
+ 0x893ddea0, 0xf7f494f6, 0x726fbd1a, 0x35d7bf98, 0xe346c57e, 0x8daf1ee9,
+ 0x0f8fafc6, 0xeff84a7a, 0xf7b88fc2, 0xf8c7c74d, 0x77dc7c99, 0x1d75dec4,
+ 0xe03acb3b, 0x3fb0db0e, 0xde3e78f3, 0x7cfc489f, 0x1fa05985, 0xf6fa745f,
+ 0xe33e3f20, 0xbd45edf4, 0x4ceb6257, 0xbc920657, 0xcbcf85bc, 0xc905c0e4,
+ 0x0313fe30, 0x21271702, 0x9cfb9a1e, 0xc07fbd97, 0x80fbf9ce, 0x81f7f39d,
+ 0x5baf9d0c, 0xecd7c89c, 0x538d2274, 0x92c77eff, 0xbb1f87ad, 0xc4fbf81d,
+ 0xbb3efcdb, 0xe373d952, 0x9697e443, 0x3e2e3199, 0xfc203d32, 0x7c5d2d0c,
+ 0x433bc7c8, 0xa332f2e1, 0xc1ce9621, 0x9b2f98cc, 0x319fdbee, 0x32c3c79f,
+ 0xadf879a5, 0x22c275a6, 0xb3d2d711, 0x4483f41e, 0xfe7333d6, 0x6517ba04,
+ 0x471ee69b, 0x9c35917e, 0xf44e66cf, 0x608e78c9, 0xf68932cc, 0xf21f47f1,
+ 0x3c00b634, 0x45ef1433, 0xe0f99d31, 0xfbc20d7f, 0xb99aca51, 0x9e45347f,
+ 0x4853f993, 0xf3e1ed57, 0x1073c23d, 0xc79f0e4f, 0x69cfd861, 0xdd322b53,
+ 0x38f7cfc8, 0x7207a87c, 0x827df56f, 0x22fdd574, 0x0afbbcfa, 0x171801d8,
+ 0x27b77b9a, 0xb724f907, 0xd4a3eede, 0xd01894c6, 0xb30ab96b, 0x31a29a61,
+ 0x0c698ec5, 0xbd9a61b3, 0x354fd850, 0xe0fd9137, 0x786bf1ca, 0xd36e79bf,
+ 0xfbe35ff3, 0xb7784af9, 0xdcabe064, 0xa3bfb7a6, 0x3f3e7673, 0x565efdc5,
+ 0x9fd699a7, 0xf0cdeac3, 0x38668de5, 0x47866c33, 0x65c333ee, 0x67683638,
+ 0xe11ef88c, 0x86569d9e, 0xde2b2bdf, 0xf438a56c, 0xa0ae7157, 0xe93b5e78,
+ 0x4dc509c5, 0x712718d9, 0x05a745fc, 0xfe3b95fd, 0x59c532fa, 0x658a6e74,
+ 0xfbb86718, 0x831618d3, 0xed9bbc71, 0x18bf30eb, 0xd9fe8768, 0xb5f6cde2,
+ 0xedb34f18, 0x434f9d52, 0xedb50f14, 0x4bbcfc6f, 0x086b06e7, 0x6f8e2ee3,
+ 0xe445fe7f, 0xfa1be3cb, 0xaaf61d93, 0x7d60b414, 0xdd3847c1, 0x3ebd08c7,
+ 0xe2f5e846, 0xfc7af33a, 0xaf6e970a, 0xfce287ba, 0xe3812637, 0x2fb2b5bb,
+ 0x2577c587, 0x8c6dfb74, 0x40dd67b0, 0x7687cfcf, 0xd08879d3, 0x7ba179cf,
+ 0x6bd11f35, 0xb3ea0c41, 0x0cdaa38e, 0x5c5d4bf4, 0xcea3c663, 0xcc8497df,
+ 0x24ba27cf, 0xcf0ce7a1, 0xc55e3033, 0xe71524b3, 0xdfa367ef, 0x8bbd7f53,
+ 0xbc2f19db, 0x20f2e9a0, 0x992a7b8b, 0xb2ae70c7, 0x79b3ef5b, 0x089e31fd,
+ 0xfbb035e9, 0xbb447179, 0x2eb1fd7a, 0xda5fcf2e, 0x448279f8, 0x95638781,
+ 0xe86ec8fb, 0x7d2b23b2, 0x380689be, 0x727766af, 0x776fe12e, 0xf986bdf2,
+ 0xdec364aa, 0x4e30bbe4, 0x8f414eae, 0xe3b92b36, 0x498f9fb9, 0x3d72e7c4,
+ 0x11f313f6, 0x6ff56d8f, 0xd81cb0b8, 0x718c23d9, 0x5735f967, 0xe41a26fb,
+ 0xb9f287fe, 0x3712b74e, 0x392bcbc7, 0x9cf093cd, 0xff0d7148, 0xfd71618e,
+ 0x80dcb76d, 0xcfcd5ef8, 0xcc2b67d3, 0x963c832f, 0xfaedb96c, 0xfcbcf061,
+ 0xec5e5199, 0x2b71540f, 0x78de2f3e, 0x3d15ce92, 0x8efee16a, 0x0504fa48,
+ 0x13fa3d9f, 0x39ea0147, 0xcb75efa8, 0x9f7f7a08, 0x239bec05, 0xdcef83e3,
+ 0xb38e4505, 0xa06f0ffa, 0x9f3330f8, 0x684bdf02, 0x97ae75bf, 0xe9e8ebbc,
+ 0xd19becc2, 0xa02df754, 0x8fc87978, 0x0c297eba, 0xa489eb99, 0x6fc16aef,
+ 0xe4621bf0, 0x7d72c893, 0xdce904a6, 0xd07cc974, 0x43ff0693, 0x8a6aa1c9,
+ 0x076c8dcf, 0xc1985823, 0xe181da0e, 0x9b972875, 0xfc169c78, 0x88b65b24,
+ 0x61c41f63, 0xf915c7ba, 0xf8a21811, 0x83d13652, 0x4d99bd78, 0x37d754c6,
+ 0xc3f5396d, 0x52abfcb1, 0xa2bf73cb, 0xe7249cfa, 0xdd30ee6d, 0x9c4fdb6f,
+ 0x70f36f47, 0x8feeff58, 0x64d45f9e, 0xe3aeb8a7, 0xbfd23427, 0x149e300b,
+ 0xb768bfcb, 0x3d68c058, 0x78cfa5be, 0xab6e538c, 0x1fa5f7e7, 0x5e33efab,
+ 0x1ebccb3b, 0xf9f44fa9, 0x39fe20f6, 0xbe7afd1a, 0x83ce1726, 0x771c788b,
+ 0xcc8a9f4a, 0xd274288a, 0x2ad44bdf, 0xd3fd7132, 0xbbc38f79, 0xcc14f08e,
+ 0x9fefc850, 0x5c9a7e4a, 0xe83a9fe1, 0x02edbff6, 0xaca139ba, 0xec25fe0f,
+ 0xdfa1d793, 0xfbd90bf3, 0xf7507b80, 0xacacfd3e, 0xa3df9d00, 0xfb40f40f,
+ 0x56161533, 0xe266df80, 0x609c353c, 0xae674f9a, 0x719e2896, 0x78f372d6,
+ 0xe36ebef0, 0xaac05afc, 0x5622dea9, 0x6ac1694f, 0xce217e73, 0x273c2e47,
+ 0x8a76e3c7, 0xfaf9cd6a, 0x8d92c0b9, 0xf0d1ac67, 0xc7d335f6, 0xc702fbe7,
+ 0xa36cdd27, 0x2ab7ddfe, 0x6977ef8e, 0x6df387cc, 0xe9272ae7, 0xa01662ff,
+ 0xe629dc7e, 0x7307f2fd, 0xed20b37d, 0x37d33f98, 0xcb9e0fab, 0x2d23f3e7,
+ 0xf99e4919, 0x13c57ebd, 0xbf007859, 0xbce187cf, 0x8524dc5b, 0x036c2187,
+ 0x9fc11d51, 0x3826bde3, 0x3679e37e, 0x6e38fc7d, 0x3ef673e3, 0x9e116fa7,
+ 0xb8f9929b, 0x0225f98d, 0xad1b251f, 0x98d17f26, 0x79d0528d, 0x6aaf9e39,
+ 0x1acaf7a1, 0xf54d58ce, 0xec1d798a, 0xba076601, 0x2b58298d, 0x755660e3,
+ 0x25d0f1e9, 0x1ccbced1, 0x755c7810, 0x945f5e5b, 0xbed1c7db, 0x9d1027ed,
+ 0xf84a7a43, 0x06d858a3, 0xec8cc5ed, 0x7b3f2982, 0xe2938721, 0x26a6bd1e,
+ 0x4a2fbe8d, 0x653361fb, 0x0e789bff, 0xd03e32b3, 0x99da0e37, 0x2ba5f169,
+ 0xc1bebf24, 0xcf9d6fe4, 0x88e4f0f1, 0xa22a4b8a, 0x3a75b7ac, 0x53d5213f,
+ 0x3b70409c, 0x599da79f, 0x20c06a9d, 0xb8e32317, 0xd3db8cbe, 0x3a8fe742,
+ 0xfe744ab7, 0x20e929f9, 0xea7e0f9d, 0xff430f5a, 0x09d02a40, 0x1253eff5,
+ 0xfcf7845b, 0x34dc3565, 0x73a40de7, 0xe3178c56, 0xc61b4a0f, 0x1a0ea5c9,
+ 0x62e3b73f, 0xbee2d62b, 0x218cca54, 0x61df9023, 0x866e33dc, 0x3ce3a3e7,
+ 0x075f5ed4, 0xc2ea7ba7, 0xa1dcc660, 0xce7fbed8, 0xc38f281b, 0x7cbce862,
+ 0x99cae00a, 0xb432e940, 0xe65952cf, 0x5333b46e, 0xa04678a7, 0x8b957f4f,
+ 0x916493b7, 0xf684dc67, 0x270e08e3, 0xd6f92c3c, 0xa0ae1311, 0xfcac5276,
+ 0x1cf87a93, 0xfa1b4ded, 0x7a061c27, 0xc4c8a84f, 0xf10653f6, 0xa70b5134,
+ 0xbbfb3d61, 0x75a01ee8, 0x23373cc8, 0xbbef3d7d, 0x2eb82971, 0x0b06dfdc,
+ 0xfb63d075, 0x97fdf4d3, 0xfbec83b0, 0xf2f0870b, 0x97994ec2, 0x24e7cfc9,
+ 0x15f6eba6, 0xfaa1d72f, 0x5ea246e2, 0xf9db8f7d, 0xe47c395f, 0xeb42bf07,
+ 0xa0803ce5, 0x58e9f953, 0x0bcc3216, 0x21bed3e5, 0xb4fcb3fb, 0xef1cf4cb,
+ 0x95c63509, 0xa1ec1497, 0xb2943bef, 0x509f3a66, 0x838e6f5a, 0x7a2622bf,
+ 0x979f3abb, 0x3059969f, 0xf99abb6a, 0x2c3ee9f9, 0xb95a27d8, 0xd3f3f364,
+ 0xfc6e1992, 0xe8539456, 0x7169cb39, 0x0a71fae1, 0x67a847ce, 0x7aa09642,
+ 0xda5d3779, 0x79a62ddd, 0xe1c3dda8, 0xa8bfb10e, 0xb7f5ebe7, 0x39c4d34f,
+ 0x7bcf7e3d, 0x2028255b, 0x4dd3cfc0, 0x5ddfc927, 0xf09bb4d2, 0x3745f3a3,
+ 0xd059629e, 0xaae4a780, 0x6405b0e6, 0xfdb8e9fc, 0x025e874b, 0xcba3d924,
+ 0x7d4b3bf3, 0xbf1f2163, 0xef90616b, 0x792eacd8, 0xcab37527, 0xf0fd0b22,
+ 0x6389d2ee, 0xdf2f308d, 0x35f37efd, 0xb2b78113, 0x6bf7f286, 0x6b7bdee3,
+ 0x7506c621, 0x4ce83b9d, 0xb00d3bf7, 0x0076022d, 0xbb00cc3c, 0x2313f223,
+ 0xe02353f2, 0xcdbe5e34, 0xbd974e19, 0xfb8e6d8c, 0xf4051ae0, 0xf0df5b5c,
+ 0x6479bc74, 0xd747d579, 0x4b8ef7e0, 0x7bf7f8b3, 0xaf249acb, 0x65a3d064,
+ 0xe4871e5e, 0x3368b6f0, 0x9a1e2287, 0x507d44df, 0x71b928d2, 0xdfa8e0fd,
+ 0xdf182612, 0xabde18f3, 0x92d3ebe7, 0x5ef483fa, 0xb10ff5af, 0x3a3f3c90,
+ 0x772a73e4, 0x362dfdae, 0xaf3dfcc5, 0x52bbf6de, 0x50b7812d, 0xc7f7eadf,
+ 0xa8f96db7, 0x20aa7bfb, 0x7d7ded7f, 0x469f497b, 0xc72f5b9c, 0xe5ba38fe,
+ 0xa3e3c745, 0x7dd14e43, 0xd6187fba, 0x079a01f4, 0x2e4ef3b1, 0xff75abc0,
+ 0x14787a54, 0x27785fda, 0x4f1fce2f, 0x704ba148, 0x059a7a5e, 0xef76c12e,
+ 0x3768bd29, 0x80ec6a7e, 0x5e0cf2da, 0xdc4df309, 0x01ffc249, 0xfc00cb67,
+ 0xc7e9dd64, 0xa4e1c2ff, 0xe609ba16, 0xafefeab6, 0x1ecdefc1, 0xc032d018,
+ 0x8ff7f002, 0xe0993a5f, 0x419e5a8b, 0x04eac2f8, 0x196b0f0e, 0x03fbc320,
+ 0x23267d83, 0xa3bbd6fd, 0xa109fdcb, 0xc5fef46f, 0x891df60e, 0x84aafb43,
+ 0x2c783bcf, 0x757a06da, 0x4db1d17a, 0xd31f01eb, 0xf49623ff, 0x5bb6fadd,
+ 0x1e13f3ae, 0x6f8c7e82, 0xa6f8114c, 0xbbf49179, 0x5f44f642, 0xba130b9c,
+ 0x6f4ce9e9, 0x71bcd0f6, 0xb416c569, 0x0fa6521f, 0x55e379a5, 0xee27ef97,
+ 0xe9e9dd51, 0xc4fe9e24, 0x5bfae6ed, 0x46bc50b6, 0xb24e43ca, 0xdf171eab,
+ 0x23b90067, 0xba0870fe, 0x3c7cdc58, 0x73190dff, 0x80001bd1, 0x00008000,
+ 0x00088b1f, 0x00000000, 0x7dddff00, 0xc594780d, 0xbbbcf0b5, 0x26effeef,
+ 0xb24d9bbb, 0xf379f909, 0x71100843, 0xa9189313, 0x18884dd6, 0x220bb531,
+ 0x49716b62, 0xc93049f8, 0x2d16ad46, 0x544859bd, 0x46d10882, 0xe1b80a04,
+ 0xfd2b6202, 0x1a8c4582, 0xf68882e8, 0x72dfbd2b, 0xbd3fadeb, 0x8a7e1bd7,
+ 0xb4564288, 0xeb6dea5c, 0x2666739d, 0x5c9377d9, 0x9f7b7aa8, 0xbe8f8be7,
+ 0xcef33bce, 0xfe73399c, 0xb3339ce6, 0x9086bb1a, 0x258e4264, 0x4ec730dc,
+ 0xe631df9f, 0x224c9d15, 0xf433bba4, 0xc84b499c, 0xc421127b, 0x09f04845,
+ 0x0e7b6853, 0xd1eddf21, 0xb4897504, 0x734de1de, 0x44b2d116, 0xc345bd7c,
+ 0xd57fbde5, 0xd2b3e5de, 0xd32d3172, 0x9912abe7, 0xbd33f58b, 0xfe5a0e69,
+ 0xa7aefe02, 0x9f561ee5, 0x58ad25ae, 0x7fbec39f, 0xe5dc84aa, 0x76d4cfa3,
+ 0x7d296e3a, 0xb5b89dae, 0x916b8e9d, 0x0bca1789, 0x5d6c16e7, 0x736a614e,
+ 0x897842cc, 0x51269bd7, 0xe6364ef8, 0x76d1566a, 0xc8afa7bf, 0x515c8435,
+ 0x97b0cde0, 0xff40f9d1, 0x44d21c74, 0x3c369527, 0x37981cfe, 0x7ad7afad,
+ 0xcf3a64b3, 0x39fe1ddb, 0xe35ebed0, 0xd0b4429d, 0x77c0b789, 0x8823b405,
+ 0x3b76399f, 0x40f227b6, 0xffffbc19, 0xb8954f08, 0x4f115fee, 0x7534ef77,
+ 0xf8242c9d, 0xb7fd05f7, 0x2aa1d7b9, 0xbad2fa07, 0xcb871a4e, 0xd0ffc377,
+ 0x24ad4871, 0x2c3a1493, 0x8d6e22ab, 0xbfe836ff, 0x7a07e979, 0x513781a2,
+ 0xf02ff43d, 0xeb0a4ebe, 0x82fce952, 0x76cf24fb, 0xb2cfdec2, 0xe8959211,
+ 0x21e613bf, 0xc3f79ee0, 0xd17f34e6, 0x3f2c7cf0, 0x76e6a978, 0xe4b79c5a,
+ 0xf4edaecc, 0x590f79fb, 0xdb865108, 0x9d711ed3, 0xb8cf7fdf, 0x9f495c9a,
+ 0x86b0defa, 0x19fdebe2, 0xb69cb3c4, 0x1a435f7b, 0x73efff00, 0x743f95bc,
+ 0x853211f7, 0xb5d95f90, 0xd0499df8, 0xbddbe483, 0x53b7e288, 0xd0234122,
+ 0xd23d4cc3, 0xd28860c3, 0xfeb095c3, 0xfbe87d74, 0x872707ee, 0x067d7482,
+ 0x619100c9, 0xbec4153e, 0xbfa9895d, 0x29eb00a3, 0xb44d049d, 0x0e68da3e,
+ 0x5e80956d, 0x50a5a028, 0x5feb093f, 0x07fad895, 0x38e230ef, 0x1d1933dd,
+ 0x433a3776, 0xb6001cc1, 0xc6de008b, 0x7694a3a2, 0x64487482, 0xb69994ef,
+ 0xe36c7c61, 0x3a52c172, 0xb4dbe2f0, 0xe4dab23f, 0xb01f4f19, 0xbb943284,
+ 0x4a3c7152, 0xbe91ab0f, 0xfd470664, 0xab42d38f, 0x394f5c70, 0x36a3cbac,
+ 0x1f787cef, 0x014591fd, 0xc89937f8, 0x7d09634a, 0xe8c3a44a, 0xe1c0eba4,
+ 0x134f5d21, 0x60bb83a0, 0x7f878a00, 0x536f386f, 0xd89ffbe8, 0x08038425,
+ 0x484e58cd, 0x75f5611d, 0xa4c72ccb, 0x86d4f029, 0xddf4090d, 0x03bc1bca,
+ 0xd972be82, 0xf3fb48d3, 0xeb22ba73, 0x83c036a3, 0x804bbe1f, 0x29b73ffe,
+ 0xefd32856, 0xd3f2c0a7, 0xbf870bef, 0x7df039ff, 0xe0c7c019, 0x65166d27,
+ 0x1f8c34bb, 0x80b9fcf1, 0x6f69ebaf, 0x9c6278ec, 0xd98f7ef8, 0xf007ffbd,
+ 0x4e1ef145, 0xb45e0174, 0xf0f1aeb8, 0xc7d1f4ba, 0x5e7eb44d, 0x82b1d69b,
+ 0xd4bfd3e2, 0xf015f386, 0xbd1a95de, 0xec8de48e, 0xa5a594ff, 0x2ff9865c,
+ 0x964f7465, 0x62e22819, 0x2e1fa2f1, 0x485dd253, 0xd23587a2, 0xf0e5ef28,
+ 0x517f8001, 0xf8f7cc77, 0x621abfdf, 0x21be09db, 0x3f07148a, 0x92452ba7,
+ 0x12fcdd61, 0x3ebd375b, 0x56e40f3a, 0x9f02dc3c, 0x8de5c6ff, 0x7c788ba0,
+ 0xbbe01bff, 0x5dbe246c, 0xe84c81fa, 0x80d4bfd7, 0x9fef8a78, 0xf77e1090,
+ 0x4d0489b4, 0x4bd6ee94, 0xfaebd212, 0x90212d07, 0xe8a6839b, 0x6067c00e,
+ 0xdeb88dff, 0x0acd1ae7, 0xea364da1, 0xf705bf19, 0x171f18db, 0xdc80140c,
+ 0xece7473b, 0xee73eba5, 0xa09eda37, 0xa4208024, 0xadda37e5, 0x5ee7ff40,
+ 0xb3f589be, 0x5a10a2dc, 0xe986000e, 0x7fe081b8, 0x578a11b6, 0xc7119669,
+ 0x0a57b13f, 0x8fbea019, 0x5e4639e2, 0x36ffa39e, 0x8dcb0c94, 0x3800a841,
+ 0x07082cfa, 0x8e23699d, 0x59335df7, 0xd16fc745, 0xad0d5e48, 0x2932596f,
+ 0x31e0ced4, 0x16d5cac6, 0x4a90e90d, 0x45bff986, 0xdee0bc73, 0xa7275622,
+ 0x60ac7970, 0x851243bb, 0x3ab8c9b3, 0x05fa05a2, 0x4bf5a03e, 0x78673ea0,
+ 0x7f565a1d, 0x479817f4, 0x7d351ecb, 0x9eaf3d34, 0xba5892c7, 0x17a619ca,
+ 0x17c3294b, 0xf1a126a9, 0x2f1b5e14, 0x21226a5b, 0xe963e02d, 0x2ae27234,
+ 0xc0e0f4da, 0x5b23a074, 0xa3a92f69, 0xe269c0cf, 0xa7b8510d, 0x36bcf7f6,
+ 0xd477b68e, 0xba613244, 0xcdbfa581, 0xf0d5793b, 0xaf380b3a, 0x4b427fe9,
+ 0x7e1e38ac, 0xeef14147, 0x89bb62b6, 0x7d88aeb3, 0x92efc0ae, 0x0f2f4c35,
+ 0x1fe02bc0, 0x75cde999, 0xfd526f5c, 0x617af28a, 0xafd404d7, 0xce40ffa0,
+ 0xf4c0953d, 0x903dc831, 0xaa8e6d33, 0x9e741cab, 0x14d56766, 0xc71b1947,
+ 0x27e98367, 0xa788fea1, 0x243d78eb, 0xb5e6a5da, 0xc75ab716, 0x0cf9476e,
+ 0x90dd16f1, 0x2c88e4c8, 0xafd17961, 0x10ab3d75, 0xe6e9193e, 0x2839cdde,
+ 0x97481b97, 0x89bce81e, 0xc740f484, 0x98248c8b, 0x1162e940, 0x9f48966d,
+ 0x881bd78b, 0x8d7eb312, 0x89b97521, 0x49bb85cb, 0x7bbfbf04, 0x357d5c67,
+ 0x7d68db09, 0x2d8491b3, 0xd755ecf0, 0x8e7d50b7, 0x85f7d67c, 0xe93df621,
+ 0x8bbdf366, 0x3aa3bbaf, 0x79d3f5a4, 0xdd51306f, 0x5d0684ea, 0x97533eb8,
+ 0x267ae0f5, 0x1e737896, 0x2bf2bd06, 0xa52b679d, 0xf5f03fdb, 0x6639f812,
+ 0xbc00aaaf, 0x9c1ab59b, 0x0361f47f, 0xd524e7e2, 0x6bfeb0e3, 0x59aee41d,
+ 0x8dae79f4, 0x8075f378, 0x2cd67b26, 0xaf3c48db, 0x00d4c57a, 0xd0e0d374,
+ 0xd32ae8a8, 0xf972c3a1, 0xe5ff8e0a, 0x1cd6d096, 0xa014f744, 0xa15cf2a7,
+ 0x9994c957, 0x474c7cb4, 0x6e5a3bed, 0x43f56399, 0x4f60037f, 0x0efdf2d0,
+ 0x77eecf26, 0x453d71e8, 0xd057cc59, 0xfb071d0d, 0x9ec55f33, 0x43658e02,
+ 0x74609fed, 0xbaf0f5c3, 0xea0f7346, 0xd5fa21e1, 0x22dfa410, 0xfaf01e9f,
+ 0xf32b970a, 0xf8a16ec1, 0x1412857e, 0x2f608fc8, 0x3e295fb3, 0xe5a52de6,
+ 0x79174e57, 0x67402956, 0xf2bcde4c, 0x4159331d, 0xccf37c87, 0x27fb1f4f,
+ 0xb4fe7f5a, 0xfad0315e, 0x746b4005, 0x88915efd, 0xbe0bc617, 0xbe810868,
+ 0x7b33d26c, 0x15ff69b4, 0xfbd19ecc, 0x71842c37, 0xc079d05e, 0x084a69de,
+ 0xeb03b73d, 0xa2943cd3, 0x863aabc9, 0x16cbe0cf, 0xf439bdf6, 0xa0bb9fb3,
+ 0xa413d53e, 0xff26a3ed, 0x74d75846, 0x7a889283, 0xc25ad7f9, 0x381709c6,
+ 0x878f5e28, 0x9c7ddd98, 0x4e304956, 0xa1fb0dbf, 0x90b69a7c, 0x33a273f6,
+ 0xe543e715, 0x2759da2f, 0x82b618d6, 0x34375dfc, 0x8fed84ae, 0xd3d37ceb,
+ 0x8bf8f968, 0xb4e59ec5, 0x0fa7d06a, 0x073d29eb, 0xafbb32d6, 0x016ca35e,
+ 0x16fd90fc, 0x8f58879c, 0xb5c59ac0, 0xb2581f50, 0x8f9016ec, 0xc839f163,
+ 0x3723127b, 0x166891cf, 0x86c6d3f0, 0xe830dedc, 0x1e89fe95, 0x4dc4af54,
+ 0x8dd29f17, 0xa93db59d, 0xee8df863, 0x5f3d21d3, 0x1740ff6e, 0x43d33972,
+ 0xca804e30, 0x0ff82265, 0x594c72e5, 0xad995a3b, 0x5495e063, 0xeba9df6e,
+ 0x47fc1253, 0x9e5a5d60, 0x97f78ffc, 0x145e302a, 0x4ae922e5, 0xa93cbe46,
+ 0xba03cef3, 0xf5875475, 0xfd7a3175, 0x99d983a4, 0x076e06f5, 0x963eb092,
+ 0x797d450f, 0xc5ee9a95, 0x7fa704f3, 0xf7c9845b, 0xce1af591, 0x401ab71f,
+ 0x20654d8f, 0x23d06c93, 0xc15fe856, 0x0e9ea7fe, 0x3969ebeb, 0xbf58597b,
+ 0x4f813f88, 0x46c3be28, 0x1b93ef3a, 0x29bf8c6c, 0x459fa01a, 0xe5f50415,
+ 0x63b52d22, 0xd2bde04b, 0xe5d74037, 0xa40e8bd4, 0x8a67f22f, 0xf9ef8a15,
+ 0x5033b784, 0xb1ca97bb, 0x30a43a97, 0xafe60bec, 0xe5356c37, 0xb57b5f00,
+ 0xcdcf5836, 0xf9b1ca12, 0x1b05951d, 0x9ec97968, 0x13fd702b, 0x2e5d182a,
+ 0x2f503909, 0xb1f2e54e, 0xa3d210de, 0x8933fe1d, 0xf6883ec0, 0x1374f68f,
+ 0x64ad28fd, 0xae401e24, 0x1421e8ab, 0xd1f6a653, 0x57265ed4, 0x24e79509,
+ 0xf2126ec6, 0x8938e41e, 0xf4d503b3, 0x88fa1411, 0xa4a23dc9, 0x7213dc82,
+ 0x97dd98f9, 0x3e3b44e8, 0x97d6153f, 0x9b9327ae, 0x6bc425bb, 0x7d456933,
+ 0xd0c0f422, 0x9c8f5cb8, 0xbe9906d2, 0xcf813c32, 0xae0e677c, 0x8bd212eb,
+ 0x95e844fa, 0xdf20e8b1, 0x88fbe1a9, 0xbc60e9d1, 0x9afec153, 0x75f0934e,
+ 0x65a6bc74, 0x853cdc24, 0x50536d3d, 0x693d323f, 0x9e127a64, 0x97d0cbe6,
+ 0x5e31faf1, 0xc1ebc61f, 0x77d33d54, 0x3d859d62, 0xd98d3a93, 0x85975301,
+ 0xfc08a4b4, 0x94eade35, 0x26bb61e4, 0xa8d18ef0, 0x1f65095c, 0x9ef905c9,
+ 0x2a62f950, 0xc4c80fad, 0xa1657c0b, 0xefa1e978, 0xb7fb7337, 0xd7cd9527,
+ 0xabf467ad, 0xd8a47d93, 0xc112eb0a, 0x99346f7d, 0x051e81d8, 0xe8db373e,
+ 0x1df02577, 0xefa1b7e3, 0x1cc3a48d, 0x2bd57df3, 0x173fd426, 0x0c85b65e,
+ 0xb3f88f68, 0x94bfb41d, 0x4ed01bdf, 0x0d8af73d, 0xae39e9f5, 0xefc25d0f,
+ 0x7e611e40, 0x41aebe16, 0x008e3552, 0xc6334bed, 0xf6140881, 0xd983b359,
+ 0x21ed2359, 0x99139f5e, 0x80cae8c3, 0x8e0bcdfb, 0x4ca00781, 0x7fa021e1,
+ 0x7e32716e, 0x5699ec0f, 0x3efa43fc, 0x187ab3e0, 0x40c5fdf6, 0xf7ed06af,
+ 0x7d2918e7, 0x8b2ed74d, 0xd1e7483e, 0x83b5699c, 0xfeceab7e, 0x41dddfd7,
+ 0xd1ee1fcb, 0xf3ac0311, 0x497369f6, 0xb7f2d8ee, 0x3e3ba431, 0x772fc310,
+ 0x9b9754ef, 0x40e5d57b, 0xbf7cba9f, 0x653ae6d3, 0xf9e1d941, 0xc1b5d282,
+ 0x87ba7ad0, 0xd5786bc2, 0x8668fa80, 0x1390ffd3, 0x7a26ade4, 0xc86cf018,
+ 0xf80a78fe, 0x9ffd023b, 0x5034f048, 0x31148a36, 0x5f5f03fc, 0xb6cfcd30,
+ 0x61b7828f, 0x06a311fc, 0x75ad4cf1, 0x173944f6, 0xd2e27ce0, 0x403c3f7b,
+ 0x9668bfe7, 0xdf02bed9, 0xcacb6b78, 0x18449ec1, 0x4dfd6049, 0x8bbec21f,
+ 0xf5846bb6, 0xb693353f, 0xac3570a3, 0x89b0fa67, 0x6f801244, 0x69dda85b,
+ 0x1bfc4ba4, 0x77776fce, 0xf4c3cb44, 0x359dbb7f, 0xf94e0113, 0xe80fb22f,
+ 0x37e851e3, 0xeade4ec6, 0x4bfc7264, 0x463299fb, 0x02b699f8, 0x038d9afe,
+ 0xfe3a4afa, 0x0cf97ff5, 0xa5e2fde5, 0x823ee1af, 0xb33e63ce, 0xc80a4dab,
+ 0x1e0fc5a7, 0xdf62f7c0, 0x8ad32a76, 0x36d7b6fb, 0xa1d95818, 0xcda9f2c7,
+ 0xb8b95f6c, 0x3cc10a57, 0x931759a5, 0x6c2f412a, 0x640dd9d6, 0xf1e35e24,
+ 0xb7a6c1f8, 0xf5efc013, 0xf61d2201, 0xc7b3127b, 0xb809adec, 0x135a507f,
+ 0xac0cbec0, 0x9043f1bf, 0x6b378b8f, 0x902f603d, 0xcff4367d, 0xc37cde2c,
+ 0xe85685c4, 0x4aa4d3e7, 0xb96d13f0, 0xd0543c01, 0x7e6217ce, 0xf4f5c89e,
+ 0x6ae5bcbd, 0xd0f1f805, 0x62ff0666, 0xd0077187, 0xd17ff5d1, 0x1ac97f22,
+ 0xb93b07e2, 0x089def5b, 0xda6cad7c, 0xe7d61d3e, 0x1ae99983, 0x224bbf6c,
+ 0x638bc076, 0x5fbc0a69, 0xe03ec92c, 0x8df586e3, 0x4f76b1b5, 0xc7f9939d,
+ 0xa597b32a, 0xaf91580c, 0x6d3e80e6, 0x08f94cde, 0xdef59fc6, 0x0d70eeef,
+ 0x6b3495f3, 0xa1532dfd, 0x1e7567ff, 0x7b21bbe0, 0x90b7d366, 0x4c2fe0be,
+ 0xe398b5f1, 0x99f2abeb, 0xa4f822c1, 0xeae400b5, 0x05ad15e2, 0x8cec51f6,
+ 0x44d93e21, 0x213272f9, 0xf9129da7, 0x1993fc02, 0x63bed54e, 0xb59a7dac,
+ 0xc67a8350, 0xedde21e8, 0xb74a99f4, 0xb71fb0c9, 0x6f58c925, 0x7d23d24b,
+ 0x77ba7fcb, 0xbce86fe7, 0x2ffa749e, 0x26ccbe80, 0x6bd062de, 0x455ed44a,
+ 0x35405acd, 0x136461da, 0xcc89afb3, 0x92eb85fc, 0x31558ec9, 0x125373fb,
+ 0x39504fdb, 0x73f405f1, 0x1f3fddee, 0x64b6fc06, 0xec053c7d, 0xcfc5c085,
+ 0xb35fe0f4, 0xdf284bf6, 0x011f1ead, 0xcff409ba, 0x868a0b24, 0xc3c072e5,
+ 0xbcfc46f4, 0x98e924e6, 0xb145751c, 0x82974a9f, 0x41076ee5, 0xd4b8da7a,
+ 0x46fef68c, 0x4004c857, 0x2b7cadff, 0xee46a7ec, 0xfb6e340f, 0x740b5785,
+ 0xe3ec921e, 0xfe30aca1, 0x17986c18, 0x3e71d2d2, 0xc41796dc, 0x8f4a9ef2,
+ 0xb759d696, 0x5ccae3fd, 0xce9f53c0, 0x9eaded03, 0xdf980481, 0x244edb87,
+ 0xb61afcc0, 0x0dde7169, 0x16524fa1, 0x09cb0d16, 0x905fc69d, 0x5d827604,
+ 0x42f8c2b2, 0xedb87c5e, 0x560594d3, 0x7d403fe6, 0x5e3a3a5a, 0xc9cacecc,
+ 0xdff5fdf0, 0x6672eb64, 0x72042197, 0xf9898cf0, 0x33bb45f7, 0xaeffa636,
+ 0xcdfe124b, 0x3fd02cde, 0xa2796543, 0xf7c4e406, 0x2efe6ced, 0xf0166f7d,
+ 0xba9247e5, 0xb52b259f, 0x52e54424, 0x84894ae3, 0xf33fcca8, 0x20594bdc,
+ 0xfedc3fff, 0x0c5d5652, 0x89dff17c, 0x6a498de7, 0xaff09a7f, 0x0ce1f4ba,
+ 0x63ceaf18, 0x31cc7e60, 0x3da2abfc, 0xa4fccf59, 0x816b9483, 0x8377c50e,
+ 0xd82f660d, 0x18c483bb, 0x5d5b9702, 0x7ad7f73f, 0xd82ef9bd, 0xe3ef88d7,
+ 0xf40d5ffa, 0xfa92e144, 0x5827f424, 0x9f28a28a, 0x77fcb4bf, 0x918cf5d1,
+ 0x8d9d74ff, 0xc6cd4eb0, 0x0471e1e8, 0x780f43e9, 0x6558b7d3, 0xed2957d0,
+ 0xf7a2be8c, 0xe59f706b, 0x814c2732, 0xdd3e80b8, 0x76f9056d, 0x43b9817d,
+ 0xb3ef0893, 0x333ed042, 0x0bbf10bd, 0x0ffa3156, 0xc3f410a6, 0x095691a5,
+ 0xe676b4fd, 0x20a8cfe7, 0xf8b455f6, 0xe76624b3, 0xbd6789b8, 0x5fd70f36,
+ 0xc70738c2, 0x400fd08b, 0xcf2f2047, 0x23a44648, 0x7b425fa9, 0x9de9ab54,
+ 0x458efd07, 0xbac52b57, 0x2a1aba72, 0xeae89dff, 0x23c74149, 0x20afcae8,
+ 0xa38db95d, 0x23f715d3, 0x127b765f, 0x36bec1f4, 0x2d6be395, 0xfbd13f97,
+ 0x2eafc28d, 0x796b7cc1, 0x6b46b57f, 0xc47a0b58, 0xd638fba3, 0xda89bc3f,
+ 0x4a7fb0c5, 0x3e9ebb03, 0x57cfb5c7, 0x6448dd70, 0x9608fc00, 0x2fa88dab,
+ 0x7244d31f, 0x9d498ec0, 0xe81bbad4, 0x515e7523, 0x0bee3b49, 0x17a01c33,
+ 0x7fa2d740, 0x1f34e974, 0x1c5823b3, 0x8f533a28, 0x07969cfb, 0x8ecc7d2b,
+ 0x097e41a8, 0xa02936ac, 0xe7f5a707, 0x08fa072c, 0x031e232c, 0x86cf71d2,
+ 0x9dcfe045, 0xac80f56d, 0xb225f113, 0x9d77cd52, 0x05538b12, 0x0f18226f,
+ 0x0d338e1b, 0xe821f96c, 0xf422c6ff, 0x8ff90c9b, 0x8dea09f3, 0xd6438dcb,
+ 0xde2136ad, 0xd068fc45, 0x25741146, 0x3fb191fa, 0x7a646892, 0x407ca468,
+ 0x054a73ff, 0xa1eb7f11, 0x3cca2e9c, 0x5ff823de, 0x456ca3c4, 0xc8b01cbe,
+ 0xbf399c2b, 0x049c4332, 0xb36c77fc, 0x00fd8416, 0x19598dfa, 0x694fcadd,
+ 0x50e92028, 0xaaab9ffb, 0xbcca6233, 0xc1f7d0fd, 0x5f573755, 0xa877fa8b,
+ 0x7aa6c01e, 0x26bd9459, 0xc355e205, 0x83b532f5, 0xff127d8d, 0x1be6e2be,
+ 0x941eaaa8, 0xee7ff8c4, 0xd11f82f4, 0xc5e35444, 0xf5c727c2, 0x5bfda3af,
+ 0x383ede15, 0xefe826ee, 0x7e5112a9, 0xe14bd3a0, 0xf753ab5b, 0xdfe52887,
+ 0xf78c4143, 0xaf0e537f, 0x6c319d5a, 0xe17b501f, 0xc36549cf, 0xefa3c276,
+ 0x495d76d5, 0x3fd8b2c7, 0x15fe83d5, 0x92e03efa, 0xe7890ed0, 0xf49704d7,
+ 0x656becd5, 0xe09d7d84, 0x74f5f662, 0x2fba4960, 0x581df941, 0xdf6023e6,
+ 0xe9c4bb52, 0xe3e4bb42, 0xfd680753, 0x1f9f59b9, 0xbb40a71e, 0xbec1e67b,
+ 0x4651702a, 0xa9d81bf9, 0x6f94490d, 0xaeccfd8c, 0xe31cfaa6, 0x967e8205,
+ 0x38fd39d8, 0x97fc0482, 0x32a4fbdd, 0x5a4277a0, 0x6ba36eb3, 0x379703f9,
+ 0xfbe1c713, 0x9779f8cd, 0x205f98bb, 0xa1b55850, 0x26dffa00, 0x5617b011,
+ 0x594f1e15, 0x63a9fb80, 0xbe630b29, 0x0a7bec6b, 0x53b8d9f1, 0xcb1e2a37,
+ 0x7804e1a9, 0x45f9796c, 0x338dc82f, 0x42650921, 0x04ea1c83, 0x41a1b6bb,
+ 0x29211603, 0x03bfcd0d, 0xf5731fe3, 0x5f9d3c64, 0x8177d706, 0xa706b79d,
+ 0xbfe9bcc2, 0xd1b57d12, 0xc4e508b7, 0x2b46b9c6, 0xeb0a91c6, 0xd83c41ee,
+ 0xc3c05ecd, 0x34aac2aa, 0xe665a718, 0x4dc63b74, 0xf5073da8, 0x077e0f2d,
+ 0xae0245fd, 0x1aba7d55, 0xa9ca77b0, 0x0a0bf75d, 0x4673a677, 0xf5f2878d,
+ 0xe2eeed38, 0x5710acfb, 0xff8e5d1f, 0x174664bf, 0xf82f921d, 0x8ff452ed,
+ 0x677f5892, 0x1fb31f76, 0x55e9716f, 0x5c5bf1fe, 0x36bdaecc, 0xe4069918,
+ 0xb01e5fb2, 0x201d5d80, 0x5f604fde, 0x65567c4d, 0x9313ae3b, 0x0536ae5f,
+ 0xd74666fd, 0x425763c0, 0xee32b5fd, 0xf03c8867, 0x5cf71863, 0x8ab3cba7,
+ 0xf2803e70, 0x90214583, 0xfe5cfbc7, 0x96fac2ef, 0xdcf57b73, 0x831637cb,
+ 0x5fd8517f, 0x5099cf9d, 0x94da766f, 0x4e406b27, 0x796649fe, 0x6468c603,
+ 0xc967ed1a, 0xb71c4ee7, 0x84ea14d3, 0x68f60ff5, 0xeac9beb1, 0xdbf4045f,
+ 0x29faeb78, 0x0d608798, 0xd51e8015, 0xd008bab9, 0xa0bedd31, 0xf2e8c51f,
+ 0x4f238811, 0x2597ce0b, 0x767117d0, 0x63f034cd, 0x85c5bee1, 0xce2adc7e,
+ 0x1529e31f, 0x2b22329c, 0x34917c74, 0xf9bce76c, 0xbc32d9e7, 0xc68ff614,
+ 0xd5eefcc8, 0xec04cd73, 0xf448f25c, 0xf8fc06b0, 0x7b0108ae, 0xc257b9b8,
+ 0x5f0b9a71, 0xe5fec3d0, 0xdfc65eee, 0xa0dfbe01, 0x78c2cbf8, 0xedc2cb94,
+ 0x67460e81, 0x1c787224, 0xb679f9e0, 0x76d0849e, 0x42577e31, 0xc0793396,
+ 0xf8f3d3fb, 0x37f73343, 0xf5884d51, 0xcec25cab, 0x5b8ea158, 0x49d771f0,
+ 0xf016af11, 0xfca92c5a, 0xc3d9e2e4, 0x183c4fbf, 0x1bfc0e9d, 0x7e05f4a5,
+ 0xccd20da7, 0xf3a75e7b, 0xc93650db, 0x9b98a603, 0x04b69392, 0xa45253de,
+ 0xfbed2f78, 0x0dd03a64, 0xafc821a9, 0xda957d2d, 0xeb8b2b66, 0xa58c5e60,
+ 0x53ea07b5, 0xfd442aef, 0x5993710c, 0x1cb3fdf4, 0xe65669af, 0x08af73c7,
+ 0x341c40e6, 0x9eefa0f1, 0x2bfc61d7, 0x4d87e8cc, 0x73636ba5, 0xf82573e2,
+ 0xf8a4dcbd, 0x7767e800, 0xf00252ad, 0xc41f7888, 0x0d16670b, 0x3d38e3e7,
+ 0x7d2b7792, 0x983976ee, 0x6a40cedf, 0x1f785e00, 0x1fc70eb2, 0xe3079fc1,
+ 0x9e0f7c42, 0x32c2d2e7, 0xc0c9fffa, 0xefb8ed96, 0x483e6037, 0xef1bdf6d,
+ 0x35adfe80, 0xc78c5e92, 0xd52dd9c6, 0x02beb789, 0xf6783ff4, 0x018796d4,
+ 0x7af6dbae, 0xce25ef30, 0x9bfeb91e, 0xb33f3ecc, 0x3f00a2dd, 0x9b72e56c,
+ 0x27c88fda, 0x3f6c5dc1, 0x1e476f19, 0x27f7a975, 0xddafe543, 0x05f0648e,
+ 0x0b3cb3b7, 0x7c03df21, 0x70d837ff, 0xd7f4013e, 0x13c10dbf, 0x8db20f97,
+ 0x8ff483e7, 0xe6f20f9e, 0xe8104b0e, 0x09af7ce1, 0x8f3292fd, 0x45b59d7b,
+ 0x7524001f, 0x01cf0e38, 0x72581b79, 0xca1ae7e6, 0x8b0f727f, 0x8f12c923,
+ 0x4b4afd33, 0x6bcc5c58, 0x808bff07, 0x774c765b, 0x3e408b7b, 0x713779b2,
+ 0xb39351bf, 0x2ef16140, 0x94d43796, 0x7b002e10, 0x87ae55ea, 0x5e2ccc9a,
+ 0x87d0e835, 0x26a35d61, 0x185d1fff, 0x93df62d7, 0xd8941a5f, 0x884f56b8,
+ 0x0a2775d9, 0x9d3d6135, 0x07d80f67, 0x59ab6eb0, 0x9f286b7c, 0xc7a1bf60,
+ 0x5890e2c0, 0x41ccec1e, 0xe22f5939, 0x3f99fb56, 0xa7c79eae, 0xf45acc4e,
+ 0x745ca40c, 0xb035ad48, 0xaab0bb3f, 0x0fe8fd12, 0x9f13393c, 0x7ed52bf5,
+ 0xa7e045ff, 0x238e1bcf, 0x1d7bff0b, 0xbd99e8f1, 0xd447ec3c, 0x5945fb50,
+ 0xbe815729, 0x15f621cc, 0x2095ff20, 0xe9abad5d, 0xc13e83b3, 0x12349768,
+ 0xa77239d8, 0xfbeb0ccb, 0xf5068768, 0xe343b054, 0xcf027685, 0x8fccc939,
+ 0xf3324d74, 0x0aa5d06b, 0xd9e238c1, 0x0771e3a1, 0xa272dfde, 0x2353c309,
+ 0x76a3e7b1, 0x7d3466b9, 0xd0ebfa2d, 0x4fc11ab5, 0xa0d4cd17, 0xde82fbdf,
+ 0xc6fd173b, 0x790202ce, 0xd6b61d54, 0x1eac3595, 0x2982e779, 0xebfac3ea,
+ 0x12486664, 0x33f209c5, 0xcbe79935, 0x616de1c5, 0x1f1cba97, 0xa90c698f,
+ 0x3fc4f5cb, 0xc58f2d21, 0xa7df620f, 0x75f93326, 0xc70e5561, 0xe3f307b7,
+ 0x6797fcc4, 0x3269bc30, 0xb33733d9, 0x41d02e6a, 0x7397c42e, 0xabfcc9e0,
+ 0x7f082674, 0x092e75ee, 0xde0e23e9, 0x80da300e, 0x3c593abe, 0x3f856ff4,
+ 0xe4caee1e, 0xbc1fae14, 0xd65f886e, 0x8f18f5db, 0x493f5cbe, 0x0e5ab25d,
+ 0xfebf950d, 0x27db2cfd, 0x9e796a75, 0x50e51d8d, 0xe5cd9d9d, 0x11d9e484,
+ 0x6a56f786, 0x3a3cc02f, 0x3f6025b5, 0x8ad5bb4c, 0x6fd968f3, 0xf3703f42,
+ 0xd02c81b2, 0x03552de3, 0x89b71005, 0x2b402fc7, 0xdb45f90b, 0xfee8b9d5,
+ 0xd884ec03, 0x4b5f3c76, 0xfef5671d, 0xf60cb920, 0xbf762739, 0xb76afa01,
+ 0xfd15f509, 0xf00603bf, 0x839cbcb3, 0x3687ccf6, 0x0bb41b7f, 0x9e5bc398,
+ 0x85bb01cd, 0xfdcd4dd9, 0x0bb01e86, 0xe2623aeb, 0xd59ff07c, 0x591fb8ea,
+ 0x3bff44e9, 0x6fbf56e9, 0xddf714d8, 0x17603888, 0xbd3af3ae, 0x3bf0227f,
+ 0x7f983bd5, 0x8351b670, 0x5af50379, 0xb79022cf, 0x7b6a4d67, 0xad8dacfc,
+ 0x75a196d7, 0xb5bda0f6, 0xf675cc65, 0xd73ac014, 0xb63f886b, 0x6758669f,
+ 0x7c4dbeba, 0x78becf9d, 0xf3ac0175, 0x2eafbbc7, 0xa75e7580, 0xdf02f2eb,
+ 0x5bfc39b4, 0x27bf6993, 0x3da1f06f, 0x2f58f225, 0x24f71e97, 0x432bfdab,
+ 0xff21ffe5, 0x30fa58ca, 0x5a87043c, 0x4af4ba1f, 0x3a83c806, 0xd5bfe1a3,
+ 0xaa37f08b, 0x4068cf1f, 0x3ffec77f, 0x0766ba7f, 0x2d7e81c8, 0xbfa223da,
+ 0x0f3fb2fd, 0xeffda1ec, 0x69413db8, 0xb91bfeec, 0x246dd85f, 0x88abf041,
+ 0x27b0807d, 0x5bf1e5e3, 0x251f3e7c, 0xbb006f7b, 0x8dfacbe6, 0x633bf81b,
+ 0xe76653e8, 0xcc3c936e, 0x7e8bdc6f, 0xf37d96e4, 0x3e27e0ed, 0xe37e621d,
+ 0xd18b1796, 0x7a18dc6f, 0x65790c2d, 0xc3b25fa4, 0xdb71a3fe, 0x07c804b1,
+ 0xba5cfb10, 0x8c933daf, 0xefdea8f4, 0x489d0e9e, 0x0a01fc80, 0x71e82577,
+ 0x07aa2b8b, 0xfba16fba, 0x6c23c83d, 0xa187a391, 0xc11716df, 0x3ed2973c,
+ 0xc44ffef5, 0xf4fa3779, 0xf6377728, 0xd790214b, 0x4e7f7a29, 0x9235e806,
+ 0x2078c761, 0xc98bb3e7, 0xb294d4de, 0xf7baf8d8, 0xe1e4e4f3, 0x0d81b07c,
+ 0x03bf4889, 0x83b5e23a, 0xe360db3c, 0xf9464cf2, 0x8e4dc7f6, 0x630fcb10,
+ 0x6218ffed, 0xc8a34276, 0x5849930b, 0x68b5eba6, 0x585df7b6, 0xe1f7906f,
+ 0x5b1f7938, 0xbbfb7116, 0x52f51849, 0xca181933, 0x176d8b0f, 0x7887d71f,
+ 0xd21faab8, 0x1f80ac5a, 0x07ab4eec, 0xb8f881e0, 0xf6c83eba, 0x961f94eb,
+ 0xafd30c96, 0xbf410758, 0x1d0fdc2d, 0x08fe3868, 0x4fa06fd0, 0xd77d83b2,
+ 0xdbf461e4, 0x905bf744, 0xefcf1b47, 0x379d57a4, 0x97ff163a, 0xd1f5a8a6,
+ 0xe4eff950, 0x453ebd5f, 0xfe62f7cd, 0x343f6fc2, 0xf1897ecf, 0xe2bcdc65,
+ 0xfef1a9f7, 0xbccfb176, 0x2738795c, 0x870f2d45, 0x79677fca, 0x2eb43758,
+ 0x1d50f2f1, 0xe59bf8cf, 0x5c70ffe1, 0x4f7d99e3, 0x03bec027, 0xa7d878ec,
+ 0x63aedcac, 0xfd1413f9, 0xe9e2f1b1, 0xc597ab5a, 0x5ea2b54f, 0xa657871d,
+ 0xe33c38f3, 0xd45ed7eb, 0xf335bae2, 0x3ef37138, 0x369a079b, 0x9c631758,
+ 0xba7e3e36, 0x0e9eec84, 0x471f154b, 0xce7e026d, 0x753c74bb, 0x8f8b0a75,
+ 0x20725852, 0x6f3e216f, 0xa7eb35eb, 0x7598fe49, 0x1ba22aaf, 0xdbe85182,
+ 0x33890728, 0x14c6fde6, 0xc6bf5766, 0x7adc8bf3, 0xad608e76, 0xfd85e2cd,
+ 0xf2c35b8c, 0xf2e07e9f, 0x18bc826d, 0xfaf1c2a3, 0x4344edf2, 0xae8cf2f1,
+ 0xb04ae517, 0x3901ead9, 0xa237fc28, 0x5e3c8bff, 0x3ffad971, 0xfcf7de8e,
+ 0x3c7bd30f, 0xf18bf67e, 0xddb8d6fe, 0x151b8a7a, 0xe3a4105f, 0xca5f1023,
+ 0x63bf4919, 0x1d1633f5, 0x1df14d1f, 0xfe766149, 0xb857cc14, 0x2963394c,
+ 0x3f009e8d, 0x5063d911, 0x7e09afc0, 0xab8fd412, 0xaa3e78d3, 0xe6267ca7,
+ 0x2573b369, 0x58ce1ce2, 0x4307e476, 0xc8ecc3eb, 0x9f5cc60f, 0xde47672f,
+ 0x087df0ee, 0xd2b27674, 0x1e01e78b, 0x61f851b5, 0x619cf87f, 0xe22e73d4,
+ 0xfca5c63c, 0xd1c45f2d, 0x4bff17d5, 0x3a92d472, 0x75f95d96, 0x13cfd1cb,
+ 0x763a7fc0, 0xff9e413f, 0x45bc4119, 0x6b6449f7, 0x103b5f8c, 0x197bf961,
+ 0xfef15e1c, 0xa1bef83f, 0x999bd521, 0xfc7fdf4a, 0x1248d1ae, 0x652e9ea9,
+ 0x67c5b172, 0x4b42b8c5, 0x697fcb2f, 0x8e504659, 0xb4df80b7, 0x3389fc08,
+ 0x4f7dd809, 0x2013fd3a, 0xf7d1ee8f, 0x226d41ac, 0x1167dbf8, 0xbdcef3b0,
+ 0x9c33cacb, 0x6798c9fe, 0xe3006cb7, 0xceb3dd18, 0xf9561e60, 0x523e9f17,
+ 0xa2f08a53, 0x5065c13f, 0x3db9679f, 0xf133c995, 0x6f843d9c, 0x3ff3fa2f,
+ 0xdaf9606e, 0x0ed79701, 0x0fe1097e, 0x8c1128b7, 0x61ecb42b, 0x96b95bc6,
+ 0x30fc87cd, 0x65a9e903, 0xf831654f, 0xa9af494d, 0xf2ddec18, 0xdf715bdf,
+ 0xe983f1f7, 0xcfb12798, 0x7c02afe5, 0x37434ad8, 0x4d9a7d81, 0xf7bb01c7,
+ 0x1537dde3, 0xfe42dc03, 0x39bf03ad, 0x4d9d7f1d, 0x462717ed, 0x64bf7796,
+ 0x33ee2647, 0x5afeac9b, 0x133aff98, 0x9db82383, 0xfee14f9f, 0x17fe78f2,
+ 0xd5aa9f7c, 0xdfa938e0, 0x5c9c6235, 0x3a7585c8, 0x0de637e2, 0x9e1293cb,
+ 0xf1701867, 0x99fec73c, 0x97854f2c, 0xbe752ead, 0x37c947e7, 0x253c0094,
+ 0x8b57f2a9, 0xe4475967, 0xb2a4940b, 0x5cea9678, 0xb322e5a2, 0x7aed73a7,
+ 0x4adb27a4, 0x9454e2c2, 0xbfaec09e, 0x06991a36, 0xbbf2bce7, 0x9e02d7c3,
+ 0x20d45ff7, 0x4799e49e, 0x28933e30, 0x56f2f1b1, 0x004e740f, 0xadfd8c7f,
+ 0x954960eb, 0xa0157b2e, 0xefa749f4, 0xffe45481, 0xaf1842d6, 0x2c745fea,
+ 0x059f72bf, 0x59dd0cfd, 0x795f984d, 0xea833dee, 0x33fc4e7c, 0x3e605648,
+ 0x6fdf6e65, 0xdb604e31, 0x279a8d23, 0x15aa44fb, 0x1825a6f9, 0x36398e99,
+ 0xce50bad7, 0x1f7efbca, 0xee43bb04, 0x91024194, 0x03579d0e, 0xcb82d3e7,
+ 0xc7f5fa09, 0xb035db77, 0x3f3cd95e, 0x7fff7066, 0xbee3f14e, 0x4205c445,
+ 0x3749bf2c, 0xc7ec08f0, 0xdf03e5e4, 0xec7ac20c, 0xc05a6871, 0xb68baa7f,
+ 0x9f65dfa0, 0xd9acfd05, 0xbe2b797d, 0x2bd9cb41, 0x1b0718ed, 0x6ceee57c,
+ 0xf3a7e7cc, 0x3cca3f1c, 0xf9654a1f, 0x8b3ef248, 0xfc99f406, 0xa8c0f104,
+ 0x0aa523b2, 0x968a7ee1, 0x07df3f69, 0x8e1e4a7a, 0x0a3f829b, 0xaa4354f4,
+ 0xcdd0077f, 0xa5a4b9d0, 0x892e7666, 0x2db5a79f, 0x9c176f7d, 0xfdc2d9f7,
+ 0x4ff707b9, 0xbffe859e, 0x7582594e, 0xf960e0b8, 0xb2a42f95, 0xfc48e278,
+ 0xd63cc41f, 0x65bf7ddc, 0x02e28d7a, 0x8c7597fa, 0x574ee45e, 0x5f19f80f,
+ 0xde63f049, 0x611d75ee, 0xeccdc62d, 0xa35c7f27, 0xd677ecc4, 0xb2d33d33,
+ 0xe3cfed93, 0xd29737f7, 0x921ebf2f, 0x0cbf4c33, 0x764eff95, 0xf4e2efcb,
+ 0x6fbcdfca, 0x5efdea21, 0xbf12fdbc, 0x8f611bbf, 0x9637f5c7, 0x50f2231d,
+ 0x61c786aa, 0xd84db4f6, 0x9e554149, 0x9f95954e, 0xfbaa343b, 0x47649f5f,
+ 0x3b79107a, 0x72caed29, 0xfe8fdbc8, 0x4edfa088, 0x3c8915e4, 0xcb1560a2,
+ 0x8c6a09f7, 0x4dd12e78, 0x687f30ba, 0x124b091c, 0xf006d7fa, 0xe42a6dfc,
+ 0x4fefd111, 0xff62e6a4, 0xa567899b, 0x22a6e516, 0xc826fc01, 0xb802493f,
+ 0xc1161b43, 0x7159b778, 0x9fe4133c, 0x033ee124, 0xc7dd39f9, 0x35a756f2,
+ 0x3a43b8b0, 0x4e50cfd5, 0x697467cf, 0x3cc7ab9a, 0x22579156, 0x5e044ff2,
+ 0xd3be38aa, 0x01ca2c27, 0x54f228b9, 0xe53d99d6, 0x39c11760, 0x1cbf3868,
+ 0xbcf3346c, 0x776fd613, 0x4f9e2e63, 0x2979b2fe, 0xf91678f1, 0x7f44fa29,
+ 0xe46cbba6, 0x37416739, 0x7089eb31, 0xecc7dc6d, 0x3d06aafc, 0x71b063ce,
+ 0x072bfa06, 0xec04351b, 0x037eaa81, 0xf1b8c3a3, 0x93d5ce36, 0x872bf430,
+ 0x054f204c, 0xceca5c3d, 0x085beba5, 0x6d83e0fe, 0x524ef33b, 0xd6d43fde,
+ 0x9341cf8b, 0x12bdabd4, 0x03cea1cf, 0xb48df5c9, 0x1af95afc, 0x6689b7c8,
+ 0x6a849449, 0x96faafd3, 0x60c4f54c, 0x287df472, 0x7be1bedf, 0xba3e3cac,
+ 0x9beda245, 0xed623ed3, 0xa9d33681, 0xefff5ed8, 0x57eb41b5, 0x267f7fd0,
+ 0x351cf9f1, 0xebf464ee, 0x3f41123c, 0xa57fd712, 0xadba3e4c, 0xdc9fb47a,
+ 0x54951f3c, 0x8854fcf3, 0x7b72d0f8, 0xefc6315a, 0x13d944ad, 0x030cfa81,
+ 0xe30827b3, 0xccf1f687, 0xf4e46d6f, 0xbf843240, 0xf208206a, 0x81c73dae,
+ 0xe7c90fdf, 0xf310863d, 0x8ff1b19b, 0x9e0578be, 0xb679124b, 0x6733d884,
+ 0x36f9815f, 0x135af2aa, 0xdb29a73f, 0x7bbce133, 0xc1db8ebb, 0xe6c47cbc,
+ 0x04f3885f, 0xddf6a4be, 0x507e1bd1, 0x7674fc04, 0x41f30fef, 0xa7a8ddce,
+ 0xe45184fb, 0x933a595a, 0xeb3a836b, 0xb77e894a, 0x016fe6c6, 0x32c77c3a,
+ 0x311c3a6f, 0xa9549b9a, 0xc1bc0077, 0xd780b4e7, 0x8e274e64, 0x473e0cd9,
+ 0x3c824fb5, 0x1b1376d4, 0x7b2fd937, 0x7f845cf1, 0x851b74b6, 0xf2625dbb,
+ 0x88947e9b, 0x92a15576, 0x26c87108, 0xcb55ee7e, 0xcb9688e5, 0x1b6e7f91,
+ 0xc1a997c8, 0x13ef4d78, 0x7fe7b05a, 0xbfe2e3cb, 0x9f9f51cd, 0xb83371e8,
+ 0x569673c5, 0xcfe802b9, 0x523aaba5, 0xab40e94b, 0xfd7084f7, 0x37186d32,
+ 0x772b603e, 0xa5efd00f, 0x42951fec, 0xe67b773e, 0xbe214a8f, 0xdc7a75a7,
+ 0x8f7298be, 0x357fd19b, 0x59bc03b4, 0xefc14b5a, 0x97f5b5fb, 0xfa2bfb48,
+ 0xf50dfdf2, 0x35706063, 0x7059a319, 0x9359fe6e, 0xffac3b7f, 0x30c7f985,
+ 0xfa40fc2e, 0xaf21f7d1, 0xd18ea8e3, 0xe793305d, 0x69ee93e3, 0x0eee9409,
+ 0x5e7839e7, 0x1ebf8b0a, 0xa8fcc09e, 0xfcb17e54, 0xe61289d1, 0x66ced621,
+ 0x266f62e7, 0xfa018e91, 0x68593a3d, 0x1c8af4fd, 0x796b7fb4, 0x77f4c89e,
+ 0x7eb0097c, 0xca8f6fd3, 0xb2c7f720, 0xeb746ee7, 0x3e188194, 0x975149be,
+ 0x97542e6f, 0x9751e5bf, 0x97f15dbf, 0x9365b109, 0xe8107bd9, 0xdf8955f5,
+ 0xb10d7147, 0xa4ba7f23, 0x935dd820, 0xe7e74a5f, 0xe53e5989, 0xf17ef94f,
+ 0xf5820aa5, 0x5b8d3b29, 0xfdcf508d, 0x3f5e5aef, 0xd98c4dd9, 0xea07c44e,
+ 0xf3c4a8e9, 0x93185d32, 0xb1ef7b22, 0x6d343f33, 0xecfda7ab, 0x1f20af9d,
+ 0xe43558a7, 0xa5ebc09b, 0x04c3b446, 0x289bb45f, 0x963c537d, 0x819a338f,
+ 0x9e75dbde, 0xd697d0f5, 0x2f40506c, 0xb1182657, 0xc83fed6f, 0x9b96d7a8,
+ 0xcb4ec40c, 0x63371f07, 0x3e265cb9, 0x20a123c8, 0x51e786ce, 0x0ad4279d,
+ 0x60eda5f3, 0x160eedbe, 0xeb96d757, 0x7ed3cf51, 0x3e0f5d71, 0x9c1109a1,
+ 0xf98ca57f, 0xc1661ca6, 0x7c247477, 0x6be734ff, 0x518486ad, 0x7bb3a58e,
+ 0xfed10e39, 0xbf83dfa1, 0xdfa0f6d2, 0x13b950ae, 0x271bcfea, 0xc0a8b9e0,
+ 0x592f79d0, 0xda15c003, 0x67e87cb9, 0x3f04f2e7, 0xa542f90b, 0x852bbe5e,
+ 0xf8149030, 0x053b050f, 0xfb8204ec, 0xccb71100, 0xd97a8a34, 0x0da6fd0b,
+ 0xe0e767b5, 0x56997852, 0x60253585, 0x27f1bca7, 0xe4b1c3a0, 0x931a6145,
+ 0xe429e213, 0xc3c316c5, 0x19af6a47, 0xef0a3d6d, 0x9b0cf2c7, 0x84c7ad9d,
+ 0xad4be00c, 0xe8064279, 0x478776cd, 0x0b94c5f1, 0xae6a76e9, 0xdb45f013,
+ 0x35adf2d1, 0x18e5f2c7, 0xc69854fd, 0xe76d00e4, 0x1ef0a24d, 0xc0192934,
+ 0xdb8ca3bf, 0x7cb5c6cc, 0xe9bae3bd, 0x41ddb4b8, 0xb6971d1b, 0x843266db,
+ 0x8da30935, 0x78c0a15f, 0xa2971a97, 0x833f911d, 0x93a503af, 0x0ec1f820,
+ 0xaf4834da, 0xf2be7833, 0x1e3664c1, 0xffe75429, 0xf8e99be4, 0xcea65f98,
+ 0xda51b9f7, 0xfa7a01d4, 0x56c25369, 0x3837cfa0, 0xfcb61cdd, 0x69d83e43,
+ 0x382bcc6f, 0x71267284, 0xd1100779, 0xf28bd20c, 0x0bc1c846, 0xa1cac769,
+ 0x8de1e54c, 0x0fde7469, 0x079d1ee4, 0x3c721f9d, 0xa5f68f9d, 0x56935bd9,
+ 0x417e1236, 0xa06e029f, 0x218be053, 0x5f838d3a, 0xa5b91bd0, 0x37251317,
+ 0x9e173b53, 0xa425eec2, 0x2bc5e595, 0xa3f3c399, 0xd8dd3e44, 0x18d1e6ca,
+ 0x746fb844, 0xe6f318fc, 0xffe718ee, 0xf735c01e, 0xbef04fca, 0x3f9ee222,
+ 0x1477f601, 0xc96979de, 0xc6f07bff, 0xca97f9db, 0xcf8b1f0f, 0xacd2f8c5,
+ 0x1e1f989d, 0x7cc56d98, 0x3f3c69f1, 0xc1a0d036, 0x0fdd00b8, 0x85a23ee2,
+ 0x97204318, 0x5cbb72a7, 0x45785b9c, 0xe0d6fe62, 0x7d45068b, 0xde7c513f,
+ 0xe97982b8, 0xbf2c65c1, 0x6f7ec87c, 0x1f7ed056, 0x9cfc73d2, 0x93317744,
+ 0x28f7dded, 0xe689fbea, 0x44fdf513, 0x7121ed0b, 0x32948a6f, 0xdddfbf9c,
+ 0xbbfe9043, 0x9f58b96d, 0x88fa65ae, 0xa3e9837c, 0xbaa21cee, 0x399d691f,
+ 0x94f31134, 0x46c15e78, 0x6ff83fc8, 0x9a7e0bf2, 0xc2fca926, 0xc9afe543,
+ 0xf0e6dc2f, 0x5b3a02ef, 0x92cde458, 0xebd63d28, 0xd2987f99, 0x8108a6eb,
+ 0x7cd6c574, 0x44dda7d8, 0xe4d2df5a, 0x02febd21, 0xa53275e9, 0xbd153cd7,
+ 0x15fc61ee, 0xe82d2144, 0x0b4e8875, 0xfd00f3e3, 0x6edc60fb, 0x5befef47,
+ 0x6fd35f60, 0x683cb0f0, 0x2f19d796, 0x59e0621f, 0x5c783320, 0xf3c22d5a,
+ 0x0f13f43a, 0x4df0e5cf, 0x12a69d2c, 0xf1631fc6, 0x824caa4f, 0xfe6192b6,
+ 0x6ffd9931, 0x7c43b8c1, 0xcfdb08f4, 0x6b5b808e, 0x739a7a45, 0x057f8b07,
+ 0x802ecc2c, 0x1d1a5838, 0x7f1f267f, 0xdaafa74e, 0x4a66ed01, 0xfa610f0c,
+ 0x167f850f, 0xdfd99faf, 0xb370798c, 0x63c775aa, 0x2f2120ed, 0x2e6ddc45,
+ 0x7dab7f6f, 0xd2f20ea6, 0xe3aad767, 0x64ef735d, 0xb339b6f1, 0x25ccfdd5,
+ 0x7cc13fab, 0x03aad24d, 0x53bdcdfc, 0xda49ff5d, 0x026c9c50, 0x710ec9c4,
+ 0xe520d03f, 0xd7a3e013, 0xba6f1793, 0x84f9d287, 0x8095149f, 0x9486f0df,
+ 0xd04f6dc6, 0x271bb3f2, 0x94f5f961, 0x28ff7eef, 0xc0296fd4, 0xe25c3572,
+ 0xe056fb04, 0x8567ca43, 0xc8cc77e5, 0xc27d0049, 0xe087bdfb, 0xdfd9b77b,
+ 0x73b6933d, 0x3cc5c94f, 0xd7ee6ad6, 0xeac85c18, 0xc6d2be6f, 0x52ef9552,
+ 0x6d5c5fd0, 0x1d35f766, 0x04bb7e29, 0x73abaaf2, 0xd5e4b979, 0x243e5049,
+ 0x3af7827d, 0xcab66b9c, 0xe92d0eb0, 0xb93ecfcc, 0xa44f0a50, 0xf276a978,
+ 0xbcd99bfe, 0x4b9e4b6a, 0xaea93e07, 0xf64cfd62, 0x41e67654, 0x2c79cd3b,
+ 0x26374b9f, 0xbf05fe00, 0x957df0e5, 0x5c7d2bb0, 0x3de4bc4e, 0xfb4491d6,
+ 0x0f2519f5, 0x7157d14c, 0x664bdd8c, 0x7d03e765, 0xfc191cde, 0x2cbcd3f4,
+ 0xb8cab6ef, 0xe1e40d3c, 0x297d7e2d, 0x2c6ecbcc, 0x1179043e, 0x65951589,
+ 0x246da798, 0xfe94beb8, 0x3f03a7c7, 0x5649fd5e, 0x559d1002, 0xbe82ff4d,
+ 0xafba0a66, 0xe537d356, 0x65e9c9db, 0x2adf9697, 0xd30d36fa, 0x3ef658f7,
+ 0xe102ab85, 0xaf5a86fa, 0xc7138d0d, 0x8ee3f19f, 0x2fe03725, 0xc30efe56,
+ 0x987c8bd7, 0x798dd901, 0x825da7c0, 0x38026f4f, 0x9e089af4, 0x3c96ca8f,
+ 0x7180f093, 0x7a88c785, 0x055f8e2f, 0x33e0997c, 0x1709192f, 0x6ec2c9fc,
+ 0xf02e7f65, 0x7af064a3, 0x38979dfa, 0xe3a2e187, 0x7a0e91df, 0xcf0611fc,
+ 0xc995a966, 0x112fbe19, 0x311697fe, 0x7cf53edf, 0x1eeccdcb, 0xcbf83703,
+ 0x3c527630, 0xcbee0869, 0x9f310758, 0xb3e7d700, 0x9e9b3e8d, 0x4736edce,
+ 0xedcfd23d, 0x283aa354, 0xff74c25e, 0xd41e700f, 0x7ec1f704, 0x62f1216f,
+ 0x47d29cfc, 0x6ec63d20, 0xe3c6f012, 0xb90c65a9, 0x789f3f1a, 0x5baf0cfc,
+ 0xe29e0d24, 0x7cd0e1fc, 0xf19e732f, 0xaf4b8af6, 0xb93a5bf6, 0xec39d17f,
+ 0xfa842c4f, 0xa0f6625a, 0xe123d13f, 0xda96af7e, 0x6ba7201f, 0x71fa086b,
+ 0xfa0d569c, 0x321d8513, 0xff5c9f16, 0x6ab7264d, 0xf73f089b, 0x4f17e6c8,
+ 0xe064a98f, 0x1ad6787e, 0x800b0d95, 0xaaac1bff, 0x56b50673, 0x4e788f16,
+ 0x503211c8, 0xa87f7a06, 0x0fef423c, 0x8a1c8194, 0xf6ae7fbf, 0x3b7bf322,
+ 0xacf84a2f, 0x032b1cf5, 0x19acefbd, 0x56790328, 0x14fef767, 0x13dc55d6,
+ 0xbdcf8f19, 0x97911ae9, 0x1a745972, 0x0e2247cf, 0x7fe6c47a, 0x3fc63d39,
+ 0xa08a5675, 0xcbb5759f, 0xcfe7e7ce, 0xd8767a01, 0xefc12a73, 0xaad8db34,
+ 0xd138bb03, 0xce903fe1, 0x5f17e8e4, 0x9a17e6c0, 0x56de3c52, 0x66587fed,
+ 0xee1e22c3, 0x81b878e5, 0x9bf3d9eb, 0xa90fb8b4, 0x0d3e16f6, 0x9bc0a0a1,
+ 0xbe42123a, 0x147ea2f5, 0xa79dc6f7, 0xda185506, 0x7d436f3f, 0xf557f8bb,
+ 0xb09b2718, 0x1894435e, 0x6431397d, 0x327fdd56, 0x5553a779, 0x5d37a2be,
+ 0xbecafed5, 0x717d555c, 0xfeaa9278, 0x544b37aa, 0x54c8b2e5, 0xdfabfb55,
+ 0xaf9552a9, 0x6aa19819, 0x3df403bf, 0x4e37e3c5, 0xffbd52cf, 0x37f4e368,
+ 0x5d7d3e21, 0xefaa3bf4, 0x043f704f, 0x85237a09, 0x040bfe74, 0x53ac5ebd,
+ 0x9acd4f7d, 0x7c0e54b0, 0xac16fecf, 0x95f77966, 0xfdb16314, 0xdb52ec2d,
+ 0x28903713, 0x84b62be6, 0x40984f24, 0xbeba9dde, 0xf107afb1, 0x0f7ba97a,
+ 0x6be6b826, 0xc69754c0, 0x22633b51, 0x0d5c8220, 0xf1638379, 0xbfd6a5fb,
+ 0xa97fe480, 0xd5b837f5, 0xd4526feb, 0x54296feb, 0xa3cdbfaf, 0x0ac4ff5e,
+ 0xbc3bfaf5, 0xaa4ff5ea, 0xb27faf51, 0xa9febd4f, 0x9febd573, 0xffaf57e6,
+ 0xbaf506b8, 0xd7aab667, 0x7aa97b3b, 0x4b82735d, 0x74f1f554, 0xc849e820,
+ 0xf795bccf, 0xa453dbaa, 0x42e86268, 0x5f02d9d0, 0x8d63e603, 0x35487aef,
+ 0x4c7d3c5e, 0xf48f3c20, 0xe547d22b, 0x727f6e38, 0xa97aa0ba, 0xda325c6a,
+ 0x73c03719, 0xff6e04ee, 0x33b746fb, 0xd58afc84, 0xe6fbb1eb, 0x08dae4b1,
+ 0xd1f7c57d, 0xd82bea63, 0xf7869b47, 0xefd163d1, 0x59ea84bb, 0xfa357c1c,
+ 0x33b0eecf, 0x999a0e38, 0x5429ff3d, 0xd1db435d, 0xde141536, 0x743e6177,
+ 0x93cd77fc, 0x1df20fd1, 0x7183abd2, 0x7c1124ef, 0x7c5123ce, 0x755d89fa,
+ 0xf10165be, 0x645fb9e9, 0xc9a9e009, 0x7a0e5038, 0xa3fcc2ff, 0xee7c63ef,
+ 0xdd65d248, 0xe21c7207, 0x3909e33f, 0x49c9e5c5, 0xf2d10388, 0x27f71339,
+ 0x8ae2897a, 0xee29e7c1, 0x269bacf7, 0x5a259ea1, 0xd5b1e633, 0x9ea12edd,
+ 0xf60ffbaa, 0xf4c71f6c, 0x52e788da, 0x6e2ed781, 0xa13b301f, 0x62dd0e0f,
+ 0xadf890fc, 0xec7a8f68, 0x3fb4deb0, 0x47f98716, 0xdbb17f76, 0x25dce0c8,
+ 0x89c2b911, 0xdd7106c7, 0x7ce1fd61, 0xe0c8db9b, 0x4623a5db, 0xe264efc0,
+ 0x31f0fb47, 0xd63c8a99, 0xefd624ef, 0x17f05cd1, 0x7e6fcd9a, 0xa9f21aab,
+ 0xf472e0e5, 0xa88f7fdf, 0xb677f7fd, 0xffbfe84a, 0x3e9b851e, 0x1b8f76dd,
+ 0xef28b2f4, 0x1e21b802, 0xfbe8ed00, 0x04ab7754, 0xadafb1fe, 0xb10f3dbf,
+ 0xbfb25f76, 0x83087ea1, 0x3d60fe0b, 0x83367f85, 0xd281b7d2, 0x11efb6cb,
+ 0xfbc61ff4, 0xa969c76b, 0x31fc8106, 0xc097bb1d, 0xfb67af2d, 0xbb1ec3e2,
+ 0x7444cfca, 0x7a47380e, 0xf20e7b29, 0x9cc54fbe, 0x3474a0d3, 0x1fbafdea,
+ 0xa47cb065, 0x44c8b6f6, 0xe39e4b88, 0xdb87d771, 0x56b2c4de, 0x265e60f6,
+ 0x88e5f7dc, 0xa2ef5ef9, 0x4e7231f5, 0x63efd2b6, 0xeace8de4, 0x1e6bcbc3,
+ 0xbc608b69, 0x25efc753, 0x5ee3347b, 0xbfc63fbb, 0x6e38cef2, 0xc4831927,
+ 0x69b8429e, 0x4f4eff4f, 0x5a3f4023, 0x762a7cbb, 0xd3706d1f, 0xeef562fe,
+ 0x1b1264c5, 0xf6d9587f, 0x88fdc20e, 0x6743f7e4, 0x36127c86, 0x641b7c51,
+ 0xdf4d0338, 0xe511b86f, 0xaf76deaf, 0x1aa1ee07, 0xb7067f0b, 0x7e56217c,
+ 0xdf8e387e, 0xe7e5c5cf, 0xc9d16d93, 0xdb7b4e30, 0x5d6f0a80, 0xfdf1176d,
+ 0xc452369a, 0x7ac43fea, 0xf4828d4d, 0x42d28a73, 0xf27ae204, 0xc1fc0d80,
+ 0x10263ed4, 0x8db9d67f, 0xb8306f18, 0xa2e4bc18, 0x9e63e90b, 0x3e00c19d,
+ 0x1f4a4cbf, 0xe1d52fef, 0x4cbefafe, 0xefbfb62b, 0x780fe337, 0x29eadf29,
+ 0xc37fb41a, 0x61c7867c, 0xf973d3f8, 0x0fbf6449, 0x5d3e80e4, 0xd38538c6,
+ 0xf1d70b3e, 0xf027f6cb, 0xcc1137ae, 0x5a67d647, 0x5cb85ed1, 0x6a19dd38,
+ 0x8fe3c7bc, 0xffe509e2, 0xf74f1c7d, 0x93fcc83d, 0xf04fddf7, 0x4a59053c,
+ 0xe987caff, 0x87971c6a, 0xcf87c4a9, 0x082a36ae, 0x465eb00d, 0xed409fe2,
+ 0x8d8bd211, 0x82a7e04d, 0x80ecaf7a, 0xaa2788d4, 0xb9e1335d, 0x1764e2a6,
+ 0x6bdae3b0, 0x13c08b3f, 0x2f801162, 0xc109037b, 0xab98bc55, 0xf877c740,
+ 0xd7813959, 0xe565cc27, 0xe89f5e44, 0xef4ce563, 0x0035520b, 0xcb471716,
+ 0xca6f3ab4, 0x80bc7907, 0xfcf173b0, 0x84cd8d7e, 0x73ab0bcb, 0xdfd43566,
+ 0x8b9cf049, 0xaf09ffa8, 0x5f1eb34f, 0x637a0799, 0x0dfbfab6, 0xd6a90f1c,
+ 0x30d35de3, 0x17aea6de, 0xeb64acf1, 0xfbf137f9, 0x53fd7522, 0xf59b7bfc,
+ 0xd41a647c, 0x7fc7abe7, 0xac5bd79c, 0xca8def2c, 0x037f767e, 0xd78c7faf,
+ 0xc61ea09b, 0x5af5642f, 0x6f09df71, 0x18e1c9d7, 0x431e33e2, 0xbf33260c,
+ 0x233696f2, 0xbf3c57f2, 0x73f707dd, 0x9bf30d95, 0xf519297d, 0x32fb86de,
+ 0x5049dc98, 0x51debc06, 0x77a8a2e4, 0x37cc65da, 0x48f5bad0, 0x972b064f,
+ 0x871f9c27, 0xead489e4, 0xe4c64461, 0x9ae8a5f4, 0x9005f012, 0x0ff4596b,
+ 0xfbe33ae8, 0x918fe21a, 0x664de973, 0x83e58fe2, 0x39554e05, 0x5574cee5,
+ 0x5cecd77b, 0x74b5bd55, 0xcc9eaa92, 0xdc9f2276, 0x5ccbe9cb, 0x17aaa254,
+ 0x6d9065f7, 0xb59d9dbc, 0x554fe5d3, 0xa85f3bb5, 0x9f8d0224, 0xa3dc49ba,
+ 0x7c8231e6, 0x9b96d7b8, 0xb3f8fc0a, 0x4e440ab6, 0xf627e53b, 0x1ba7f3b4,
+ 0x54fa598c, 0xcb10b978, 0x7e583bcf, 0x879b7b7f, 0x9e087395, 0xab6f6faf,
+ 0xca2ef2c1, 0x69fcf09f, 0xdb9f179b, 0xcfa15969, 0x2bfda47f, 0xda1e9fb4,
+ 0xa19f943f, 0x3373c3fd, 0x3f9e1fed, 0xfd43fda1, 0x942fda06, 0xc170a69f,
+ 0x0fda29f3, 0xed31ffbc, 0xb44fca1f, 0xb6bcb0f9, 0x1f962e6d, 0xf3e3f36f,
+ 0x7c06b6b1, 0x8ad6d9df, 0x96db47e5, 0xb6e1f3e2, 0xdbdb3e20, 0x2f7d6256,
+ 0xf9e793a7, 0x2be7dc79, 0xf103bdd9, 0x219fdfeb, 0x9d2fbb61, 0x154a539f,
+ 0x3f2ab97a, 0xfc033fa7, 0xfceabd02, 0xc21fc054, 0x8c786261, 0x0668e387,
+ 0x91270fb3, 0x930b72c8, 0x1f07181f, 0x6159e7df, 0xae35fca1, 0x4e7bad95,
+ 0xd3eb145f, 0x4778d81a, 0x5c409db9, 0xce519241, 0xbb439b8e, 0xcaa45273,
+ 0xd007f2c2, 0x14dc430f, 0x5aece53f, 0x21e64672, 0x5725c00d, 0x331e3d50,
+ 0x397c21af, 0xb7809c18, 0x57fde0d1, 0x696d378e, 0xa75fbb2f, 0x6c0c2ba6,
+ 0xe2b6f666, 0xb9c63afd, 0x9f4cb0be, 0xef1f9f2e, 0x717498e9, 0x5224dd3a,
+ 0x9bf176f9, 0x8ccfa144, 0x31fef526, 0x6a89417d, 0xb8bda67f, 0xd1572886,
+ 0xfbd48b7e, 0xbdfe733c, 0x198cefaa, 0xf5eaa90f, 0xfaaa15ae, 0x1e73bbba,
+ 0xc73e0371, 0x6199b8b1, 0x210272f5, 0x4fdd85e4, 0x4ce65c20, 0x92738f36,
+ 0x605f7ec2, 0x133dff37, 0xd6797fbe, 0x5c65f1ce, 0x09f2fb8d, 0x482c560e,
+ 0x0f406a0c, 0x448bfc7d, 0x9e3b7f94, 0x7e9fa0d1, 0x40690922, 0xe6a64cde,
+ 0x015fd424, 0xf16b8c37, 0x942d26aa, 0x85a2898b, 0x8a2455f2, 0x7fba3afb,
+ 0xf5d264d1, 0x9ffad16b, 0xd9f2d131, 0x2cb3ff4c, 0xfa8c30bf, 0x67af80ba,
+ 0xadc7d881, 0xdcfde397, 0x37f44cc6, 0x7625cfa9, 0x874bfdf0, 0x970df989,
+ 0xc153ca3b, 0x46373e0e, 0x7dcda83e, 0x14058de2, 0x63b4b6df, 0x1fef14f8,
+ 0x9ea33457, 0x94cbcfd7, 0xf75e5abe, 0xd44faa7a, 0xf307937c, 0xcffa5b38,
+ 0x6b76e029, 0xff228fc9, 0x3c84e874, 0x9e411253, 0x893d970d, 0x3b1e6624,
+ 0x93c9deda, 0x11fa2151, 0x375f326f, 0x4ff95f31, 0x4bc87695, 0xd179e02c,
+ 0xf2d2db3b, 0x7f0fc7ab, 0x5074e3ef, 0xa0352248, 0x348b0b5f, 0xe074109e,
+ 0x31fcabb5, 0x2f2efca6, 0x4b930b9c, 0xf2c40788, 0xf785d244, 0xd57fc829,
+ 0x7c9a3e62, 0x50a21af0, 0x0d6ad8fb, 0x70d16093, 0x75fb84bf, 0xfce5cfbe,
+ 0x9c6af667, 0xec259c8f, 0x74e80f26, 0x1bd599f2, 0xacfc3a01, 0xf4d8c75b,
+ 0xd0bebab8, 0x2def504a, 0x1487d42a, 0xebcbee09, 0xe5407bc2, 0xc8c9122d,
+ 0xb9a63801, 0xdf7e83e7, 0xb63a416b, 0x9fc72fac, 0xe359b830, 0x0efc40af,
+ 0xc2357b28, 0x9aeda2e8, 0x82b7eb27, 0xf001393d, 0xdcbc0562, 0x430d5f91,
+ 0x1e2217e7, 0x2f79f217, 0xc8e8f3e4, 0x833fc21c, 0x70bc7887, 0x6ea2ef1f,
+ 0xcf528fe1, 0xaad2f1f3, 0xa2bdc36f, 0xff2d11ed, 0x3e352299, 0x5322e957,
+ 0x70c34be6, 0x66173851, 0xb8015c82, 0xd80f82af, 0x919f9afc, 0x941cc6c8,
+ 0x6f68356b, 0x3f306994, 0x9b2e9e3d, 0x8fdc9932, 0x7dd9d866, 0x4853eee4,
+ 0x93e5c3cf, 0xc2482c6f, 0x5bb333fd, 0x8fcb326c, 0x58957af4, 0xe12af7bf,
+ 0x72e7e45f, 0xa1de1ccc, 0xb127057b, 0x892b60bc, 0xb4bc87ac, 0x2bf5f6b1,
+ 0xdc707332, 0xb53d7de1, 0xa53f205d, 0x5c7988cc, 0xa13e44ab, 0x69995472,
+ 0x57384f63, 0xfa74e465, 0xf79d4da8, 0x6fcf9db3, 0x418f5f3b, 0xf27bc8a3,
+ 0x9cc716d6, 0xafeba9f3, 0x88963f47, 0xff720ed3, 0x1d59a0e1, 0xa4e46d57,
+ 0xaba87830, 0xc1f10cca, 0x6da7162e, 0xdd99bfec, 0xc7efbb6b, 0xed302f78,
+ 0xa87a0153, 0x57ebede7, 0x0b58fdaa, 0x5f91fa77, 0xf164fde3, 0x398a317e,
+ 0xe31fec3d, 0x335b62fd, 0x43c27ef9, 0x7b0e218a, 0x61de7562, 0x7277ec33,
+ 0x1f0f9e08, 0xef017da7, 0x81bba6dd, 0x974fb82e, 0xa3fbb114, 0x54ffd7e2,
+ 0xb2f11e96, 0x78efac53, 0x3ba5da2b, 0xd81c98cb, 0x2dfce079, 0x2b3f69e3,
+ 0xf9d52473, 0x3a399580, 0x29b7a75c, 0x97b3c37d, 0xeed19a90, 0xa9943b29,
+ 0xef726af9, 0xc1eff55a, 0x1c0df734, 0xff2828b6, 0x1fba035e, 0x4279fc3c,
+ 0x1451f211, 0x08c4bf7f, 0xc19930c2, 0x76b3e70d, 0x17993e6b, 0x676f0f4b,
+ 0x36ff58ca, 0x0d2f8ba7, 0xae1ab557, 0xa56f45b3, 0xfd7060cc, 0xb9c6e40e,
+ 0x5894f1f0, 0xb5c0467b, 0x03df8c7b, 0xe2abf0f8, 0x1fad42a9, 0xfa74f062,
+ 0x6ed3c3bf, 0xfcf0e8fd, 0xb3f3c395, 0x9b5eec43, 0x515ff591, 0xe1ab759f,
+ 0x647cfb3d, 0x0a49880e, 0x7f115fef, 0x182993ee, 0xebf8e613, 0x59f4e52d,
+ 0x078fe5ca, 0xc09150cf, 0x1e63577b, 0x924caf66, 0xbe5ca16a, 0x2cf77f00,
+ 0x02c3ef93, 0xbf9e3f1a, 0x4619ef21, 0x64d77f95, 0x9ddeba31, 0x878a8d2e,
+ 0xcf362cd2, 0xb2ea4703, 0xd8f1bfc1, 0x7202063b, 0xbfcf3361, 0x6bdecc7e,
+ 0x05a67b84, 0x425ca11e, 0x747d019f, 0xc7bc2811, 0x2a333f4a, 0xd3c651d6,
+ 0xc6d6f1b0, 0x4f188df1, 0x1564a73c, 0x3a557b32, 0x387385a4, 0x0b7daf6b,
+ 0x5b5b7fef, 0xfdeca32a, 0x1d5ff8d2, 0x5bf0ff87, 0x7a30b729, 0xe1459299,
+ 0x90fe916b, 0x0e5a6df0, 0x2a7fd148, 0xbd157c82, 0xa01fe71f, 0x4691ec78,
+ 0x8b2d29e2, 0x9f988bd1, 0xdb80bf98, 0x5c02dd76, 0x06bbdb07, 0xbca51a54,
+ 0x8917d0bd, 0xbcc1ff5c, 0x2b5c5f50, 0x654c73b3, 0xdafbae32, 0xee78a98a,
+ 0x17cf376c, 0x1fa35e89, 0x164477f5, 0x763dbc70, 0xb811b7f1, 0xafd83947,
+ 0x883ffbc3, 0x15bee03c, 0x8dff1fee, 0x5389f78c, 0xfb81aa7a, 0x391c0ecc,
+ 0xebfb009f, 0x843a59f9, 0x87973e7b, 0x35b51783, 0xc8ec1e78, 0x0c6d7667,
+ 0x6965d7fd, 0x89127db9, 0x35af39c0, 0x8b3cec25, 0xd603db95, 0x001b2723,
+ 0x43c56b7e, 0xde862906, 0x10196566, 0x68fa35ae, 0x17f6878a, 0x6125a7d8,
+ 0x7bc1ffe6, 0xb3ce8719, 0x5a1e19da, 0xbda10f4a, 0xf767ed60, 0x2965d635,
+ 0xb852ce4c, 0xe6f7d2f7, 0xebd99f89, 0x8e94bea1, 0xbdfc3b97, 0xd3d6cecd,
+ 0x4beec65c, 0x3fed7b5a, 0xc83ee1db, 0x471df844, 0x79f2efd8, 0x7292b80a,
+ 0x48dfbc35, 0xcbf81724, 0x5abe632e, 0x235ef86f, 0x2f82fbd8, 0x62d5cade,
+ 0x39f947bb, 0x0a2b4789, 0x4cae7043, 0xdb35b1d0, 0xcc1640ff, 0x0bc5f28f,
+ 0x7c44ef68, 0xf63f10d3, 0xdf33c862, 0x32e64525, 0x076f443b, 0x68d42c3e,
+ 0xe116fc54, 0x549e26eb, 0x73dda3fd, 0xa15da73f, 0x46423bf7, 0xfe4de702,
+ 0x22667178, 0x191da7d8, 0x1af3dec2, 0x259b5f01, 0x8c0e625f, 0xdc5a2ff3,
+ 0x72381e0f, 0xedc601bc, 0xbe02f3a0, 0xeb75f87d, 0x3a53b06a, 0x53e45eec,
+ 0xd0ecbe31, 0xfd60f5f0, 0xdf7bd6ec, 0xd4647f04, 0x3acdeec1, 0x11867538,
+ 0xd3b69fe8, 0xa07f3f40, 0x04f0f7fb, 0xfd1aa7e8, 0xb3ed0b06, 0x8b77c3a6,
+ 0xb011ff88, 0x6b75176f, 0x3c83f755, 0xc2c5e5cc, 0x8e12168b, 0xac2c2fd9,
+ 0x6b9e0ef8, 0x0131785c, 0xcfcc3fdf, 0xcfcc3fed, 0xf8e2edbd, 0x5f3f9978,
+ 0xfb8afacf, 0xde9c4f6f, 0x8eddfe4a, 0xbbf7c63a, 0xa59afd60, 0xfaa83d01,
+ 0xc73f5335, 0x687f64f3, 0x21b093b3, 0xf311de06, 0x98e1224c, 0x5dda8771,
+ 0x52709134, 0xfa32faec, 0x15af9e1d, 0xe6d0ffeb, 0xdd8e3c46, 0x1e1538ff,
+ 0x53cffb87, 0xff6471e1, 0x87ff5805, 0xf44bc2b6, 0xfe8c793f, 0x0ff05473,
+ 0xef8f9bf7, 0x7bac1dcf, 0xeef942d6, 0xc6c57860, 0xf7e14b57, 0x7bf80cf7,
+ 0xb7afa41b, 0xeeb9cf0a, 0xfa0e7822, 0x7a7ffd81, 0x1f52f21f, 0xc0f7aad8,
+ 0xe8ba8318, 0x7a28cf3c, 0x83d89f26, 0x789cef70, 0x87959dbe, 0xdeff1ceb,
+ 0x90ec8728, 0x942c6a67, 0x8ce7a0ed, 0x015a1224, 0x235297fb, 0xdf1139ca,
+ 0x34fefd12, 0xb392ab53, 0x46a17ee2, 0x68d87f9e, 0x26aff161, 0xac2cffab,
+ 0x574d12ff, 0x1f68cfcb, 0xf03b0ba7, 0x0e213b7c, 0xf888d7dc, 0xc5fb0c8e,
+ 0xf97d703c, 0x9b0b9c08, 0x0cffe397, 0x1509fbbe, 0xd1ef102b, 0x0fcdb15e,
+ 0xf38f79f9, 0xa6e3e47d, 0x2313db88, 0xf2d9753f, 0xba1bb357, 0xecb7e8e2,
+ 0x8cc23b77, 0x40d9757e, 0xcfc8dabf, 0x7ce072eb, 0x67bf00e3, 0xb9fb414e,
+ 0xde30f4ae, 0xfc275947, 0xf3e32b02, 0x601d3256, 0x54788b4f, 0x8217e402,
+ 0xdd86b0dd, 0x616f5853, 0x275ffae5, 0xba17b9e1, 0x8114b21f, 0x65add99c,
+ 0x071e22fe, 0x1e61cf3b, 0x02c9ae34, 0x7cf20efc, 0xaffdf397, 0xe7a7bde1,
+ 0x3a478e57, 0x0fe5ffa8, 0xddc31ef1, 0x0d9f4ce9, 0x3ea1b3ee, 0xca7837ab,
+ 0xddcd5ee1, 0xed6ecce9, 0x2509c395, 0xa3ec7631, 0xa7285519, 0x5e395e3f,
+ 0x19271b13, 0xc2e4cd9f, 0x94ffe11a, 0xce70e5a3, 0xf0d2e3ea, 0xdd3ea13f,
+ 0x1bdfc263, 0x53fdecd3, 0xbabfde39, 0x63bf80c6, 0xe277b551, 0x5fb0b9ba,
+ 0x1f31904c, 0x84d7b35b, 0xc55d9cf0, 0x6f8383ee, 0xef35ee41, 0xcbbf871d,
+ 0x62896f56, 0xd9b364de, 0xc1f10053, 0xc0dfbdfa, 0xf1389fdf, 0x902cc4f8,
+ 0x9593c783, 0xfb6fbc2c, 0x3a748a71, 0x26fbe3ef, 0x579df7b0, 0xdb6ab9e3,
+ 0x347f8b1a, 0x4bd088ff, 0xedcdf7f1, 0xd73e2f4e, 0x6899f807, 0x5e1c80f4,
+ 0x675fe438, 0xbfd607f7, 0x24a59d19, 0xf306ffa0, 0xa7edea17, 0xeb1df7f0,
+ 0x49dd8fbb, 0x42e93e30, 0xbcfb15fa, 0xb9eb71f8, 0x8faddafe, 0xd5df83ce,
+ 0xf8e76fab, 0x59f7bfe7, 0xdfc629af, 0x5ff8149b, 0xf31f7713, 0xc5de38f7,
+ 0x1911c4f3, 0x76a4b9ef, 0x8ff81645, 0x2037ec4e, 0x33589dbd, 0x1057ef19,
+ 0x5853d5e3, 0x8f4f94ed, 0xb029953b, 0x15b20bbe, 0xb676ff36, 0xe9ef157f,
+ 0xbdf811f8, 0x2d3ee8ce, 0xda0dafe6, 0xc71009a3, 0x7944ed14, 0x5afd3e68,
+ 0xddb7bdfc, 0xdd7007e9, 0xa0115d29, 0x6d2fcd2b, 0xbf03b7a8, 0xf71bbf64,
+ 0x82092971, 0x8ef8349f, 0x077bf701, 0x9ed019f7, 0x9d977c1e, 0xef711fcf,
+ 0x059a359f, 0x7e06dcf7, 0xdae50e39, 0x0b746660, 0x784dbfb3, 0x51e0e4cf,
+ 0x5e3cd5ff, 0xd1efc69c, 0xefbb034c, 0x18533ec2, 0xc4fa3eec, 0x6c9043b8,
+ 0xfdfbe373, 0x882fbc16, 0x24f9d93e, 0x7f1b8f69, 0xf1748937, 0xfdf823ef,
+ 0x09fe5903, 0xc81fa720, 0xe15bfda3, 0xeed893fb, 0x4affae42, 0x9211598c,
+ 0xc74bc7ce, 0xd9fd337e, 0xccfa5ef8, 0xa80f7ecd, 0xb047d78b, 0x5ff0603e,
+ 0xbdf8f38d, 0x328cf48d, 0x5f7aafcf, 0x49d97de4, 0x6e028eb8, 0x23b4678a,
+ 0x93d2f1e3, 0x029ff6cd, 0x3974f11f, 0x80979eb4, 0x7832fc0f, 0xb63ec0bf,
+ 0xea26ab8e, 0x9ce93c99, 0xde32f68c, 0x27931430, 0x07df7cb8, 0x3a839748,
+ 0x97a0d3ef, 0x847547a2, 0x2d48c3dd, 0x5457f003, 0x16f576b0, 0x7010f7e6,
+ 0x07e7e19c, 0x1e593b1a, 0x3ee799e1, 0x856f9ac8, 0xa81ff3f3, 0xff0bcfce,
+ 0x0124ed21, 0x8f5633fc, 0xc4575092, 0xc22d76ec, 0x6e8f7ec5, 0xdfc14e8d,
+ 0x3e3e0c0b, 0x2712fd11, 0xbc5ecaf4, 0x15d57607, 0x6d27a01a, 0x4fbf9731,
+ 0xfb8979b0, 0x6d3dc4dd, 0xc81978f1, 0x99b2fa66, 0x3b82eff8, 0x25138ffe,
+ 0xf14b0785, 0xff744abe, 0x52cd206b, 0x7e589af6, 0x9185ea3b, 0x2fea42f7,
+ 0xff827bf1, 0xb053e5bb, 0x9f806556, 0xd5e80260, 0x7fb676d3, 0x40225bc4,
+ 0x3cd96bbf, 0xb803e03b, 0x4ef882ff, 0x5bc45e83, 0x4e1e2825, 0x9e3eac4b,
+ 0x1bbc84ce, 0x1ba00f81, 0xa3be17e8, 0x9d9e7f7d, 0x763ff6c3, 0x17943f27,
+ 0xaa5e43d4, 0x490157d0, 0x0f7dc0d6, 0x024a1d27, 0xcec9e5d0, 0xc872e73c,
+ 0x292871f7, 0xe076f6b1, 0x0e7bc110, 0x73ff3814, 0x922efc35, 0x05f80a77,
+ 0xfed53b77, 0x5e787888, 0xfd401ca8, 0xc6985ff3, 0x800053c5, 0x00008000,
+ 0x00088b1f, 0x00000000, 0x7db5ff00, 0xd554780b, 0x733effb5, 0x79332666,
+ 0x84841e4e, 0xe4249840, 0x09308401, 0x0741410f, 0x68151048, 0x85280978,
+ 0x42100793, 0x17b6881e, 0x240cdb5b, 0x41b45a20, 0x768bd151, 0xb4544140,
+ 0x03414141, 0x58a50077, 0x56d56351, 0x880dcb6d, 0xa8311fbc, 0xadadff97,
+ 0xfb5bf5ff, 0x90ce649c, 0xf9b7b5a8, 0x67d9d83e, 0x7b5ad7bf, 0x3bdaf5ed,
+ 0x3f437cdf, 0x756109d7, 0x10f4422b, 0x116dce22, 0xa3109862, 0x42f382dc,
+ 0x11c885d8, 0xca8df3fc, 0x5c3adb89, 0x8df88588, 0xdaf9aaaa, 0x2bc89eb5,
+ 0x1f5c2deb, 0x774675e3, 0xb5f1bdf1, 0x28f250ff, 0x084c21b3, 0x5d3dfe87,
+ 0x1e310f88, 0x90ea7b8d, 0x460ca7dd, 0x09ac2e1a, 0x75ac5442, 0xa51a45fa,
+ 0xbacc4e6f, 0x4285e653, 0x5c6cc775, 0xe34ad899, 0xca2a6f96, 0x1fb29112,
+ 0xd0aaf341, 0xea9e55e7, 0x0a8752cd, 0xeaa8f6d1, 0xebf684da, 0x6a8f9e55,
+ 0xa51eb8f3, 0xdbd627ef, 0x9fa9cb5c, 0x273e7d0a, 0xc5d16b7a, 0x0ab794b9,
+ 0xf280bdab, 0x45da2d56, 0x54782efd, 0xb177f62d, 0x81f7aa3e, 0xf80ba0b5,
+ 0x3a894d60, 0x1ea8327c, 0xe39469d6, 0x7268f7bf, 0xc2fcd157, 0x63cc77e9,
+ 0xd1f7e2a3, 0xd1f44efc, 0xfc7f21e6, 0x82b13093, 0x45daeaf2, 0x2bdceed1,
+ 0xa1c27de1, 0x01727b45, 0x031eb95f, 0x18e3a19e, 0x7808bcf0, 0xbabd20c6,
+ 0xabf04bc5, 0xa0f5487d, 0x4be6bece, 0x98df80d1, 0xae47453d, 0x61b5f7c1,
+ 0xecda8c22, 0xcefe9c3b, 0x8b8f34ad, 0x3d4155ab, 0x193dd28a, 0xdbc68289,
+ 0x2e7cf96e, 0x4dbf73e0, 0xd2917acc, 0x47a7b7d2, 0x46fd285b, 0x21f51fa7,
+ 0x6a352709, 0xae7cf47a, 0x98b93edf, 0x9edcc7f2, 0x7aa082c4, 0x2ce9d63f,
+ 0x6b655f14, 0x718d16ff, 0x78d8d62a, 0x2e5e065d, 0xbf341d62, 0xfe118d8b,
+ 0x8b9704e5, 0x5fb8dbbd, 0xbf464f03, 0x4183c015, 0xa56f544f, 0xe38fa5db,
+ 0x114717b3, 0xe1b4d35c, 0x64e82e9e, 0x2e3483c1, 0xe51f5bfa, 0xff7de675,
+ 0x74780d71, 0x25969be0, 0x8f03fc0c, 0xbc6da44f, 0xde59be97, 0x93d10ab3,
+ 0x7d78d0e0, 0xcbdf42aa, 0x850984f6, 0xda532bfa, 0x9c09288e, 0xac14fb77,
+ 0x8c3cf17f, 0x9871f657, 0xf7c7e505, 0xf3c79f5e, 0xc12bc10a, 0x7a2bb529,
+ 0x96d698bf, 0xdf8209ea, 0x736d3ec5, 0x7d06be79, 0xe79bce74, 0x4c37bb51,
+ 0x4c5c5f60, 0x76467c23, 0xf801b1c2, 0x5df5c619, 0x6f6fa676, 0xb1d7e01e,
+ 0x7ac8575e, 0xfdeb215d, 0x0b7d3040, 0x29ebc68f, 0x82cc24ff, 0xdc0fe5ef,
+ 0x71a6e594, 0x8e3bdf8e, 0xce3c75d7, 0x75fd879b, 0xcffa953c, 0xe59d72bd,
+ 0x733ad00f, 0x8d9d65bf, 0xb757c64e, 0x7b6b8ceb, 0x3acb7c42, 0x6874ea37,
+ 0xab33f3ac, 0xfa8ada3b, 0x9cb155bb, 0x14fb6a8a, 0xcc8d7fdf, 0xd0d056bb,
+ 0x0f4936b5, 0xfc236bb5, 0x6685d7c0, 0x6e7f04db, 0xf1a01f27, 0x583d27be,
+ 0x8f8e1e98, 0x023c3f75, 0xea9f75f4, 0x9701b9f2, 0x9cfcef21, 0x57efc7f2,
+ 0xb1f9025d, 0x0fc47e12, 0xc70fe02c, 0x73278b53, 0xb5cdaf7e, 0xb4f9fa82,
+ 0x047f6ff1, 0x63dc5cfd, 0x5f5e0b73, 0x90b3fdf1, 0xaf82f9a7, 0xc66e5c11,
+ 0xebce54b8, 0xd619ef57, 0xe8f17288, 0xbba65760, 0x0214be0b, 0xaa358ae7,
+ 0x01d21f69, 0x3ed5e3c1, 0x3ac6e290, 0x8713380c, 0xa83a9acd, 0x4fc81e13,
+ 0x9709d41f, 0x9ad0bb5a, 0xfb12fbf8, 0xfc414194, 0x9749f00c, 0x3cff44e7,
+ 0xa2d2c7c9, 0xc873f683, 0x8ff942fc, 0xff48cf51, 0xcc57c1d2, 0x705178fc,
+ 0x1950e09e, 0xc21c5f92, 0xca42aa37, 0xb7ca43ab, 0xf99cfaf7, 0x13f8e840,
+ 0x31bee4d3, 0xc3aa58e0, 0x9145bb71, 0xc53ee47c, 0x2d7e89bf, 0x4bedbab5,
+ 0x8e2ffe69, 0x4fd0f311, 0xae385599, 0xced97de5, 0x8ab52beb, 0x7c02b086,
+ 0x633d70f7, 0x435fd4dd, 0xc3e51c58, 0x7aa21f25, 0x7941ec13, 0xf31adf83,
+ 0xf0934f09, 0x5bc5d230, 0x83c78d9d, 0x14dd59e0, 0xeed7ca6b, 0xee3c6e4a,
+ 0xc62fcce8, 0x6ff4c92f, 0x387ead22, 0xaa7f22e0, 0x8c1eb577, 0xb249fa20,
+ 0xd469e168, 0xff83c5ef, 0x66eb9d1b, 0x262f0fbc, 0xe9a816fc, 0xf5a61d2f,
+ 0x3d56edb6, 0x9befd09b, 0x5f11fcf2, 0x1b787a5f, 0x9bd9af7d, 0x7775ee21,
+ 0x8e143fae, 0x8a5d7717, 0x17efa74e, 0x05c3d90e, 0xcda501c9, 0xd1ed63f1,
+ 0x84babfbc, 0xbb875bbb, 0x6b05dfd1, 0xa094f46b, 0x6b44177a, 0x7a20d4f4,
+ 0xa975dd29, 0xfc31e44e, 0x1f106a7c, 0x8f4f74ff, 0x2f7d2ab1, 0xb1af7dfb,
+ 0xe9c74a16, 0x736fdefd, 0xe686b93f, 0xe61ddbed, 0xbef34cd9, 0x0b2ce6f0,
+ 0xb3785fda, 0xea7f4f42, 0x4fb3f4e5, 0xb47e3153, 0x31bbd245, 0x293488de,
+ 0x8e59954f, 0xfc1a313e, 0x699ed5ff, 0xe59d69f5, 0x2c829665, 0xad9b79e0,
+ 0x7de62e6d, 0x95ab1141, 0xc67eceb8, 0xfdb9b9a5, 0x9f27dd85, 0xf4f87f00,
+ 0x60053efe, 0x6776172b, 0x7e5469e7, 0x5921e3e1, 0xc2f7ea2e, 0xf01ec97d,
+ 0xf7366d85, 0xeede994f, 0xdf60f289, 0x9c61fd1b, 0xf77fe825, 0xa435c355,
+ 0x52f9cb1f, 0xe3934f3e, 0xce8294fa, 0xee2da37e, 0xbf028f5f, 0xb3cdbdf8,
+ 0x7fa59299, 0x8b19e8cf, 0x773f61f5, 0xd5b28781, 0xe26dc261, 0xde782b27,
+ 0x8763c2a5, 0x1172841c, 0xa2e55f44, 0x6fcfbf98, 0x405f7f34, 0x17df027c,
+ 0xaf7f37ae, 0x5aab8d10, 0xfc8b7d69, 0xf682efe6, 0xfb112f8f, 0xe269f8da,
+ 0xd6f17ef3, 0xf54cc26f, 0x0fe74f84, 0xa5c7e60e, 0xc7c11fb4, 0xfefc579e,
+ 0x3defc015, 0x7433af2a, 0xd2d3cb5d, 0x448f1d78, 0x6b6e63fc, 0x598f5e10,
+ 0xe0893584, 0x1c2ecc7a, 0x47e80549, 0xbeab9c08, 0xcdfe613d, 0xfedee4d4,
+ 0x3296a55f, 0xe0b24bdf, 0x05c3b83c, 0xedfd47ce, 0x7e8a9939, 0x791756ca,
+ 0x77e6835b, 0xe47de6d1, 0xdf5790e7, 0xf54d7e23, 0x37f58d8e, 0x1d79a58e,
+ 0xd4f557bb, 0x33af3177, 0xe3f99f24, 0x28f71e09, 0xf2843fc2, 0x2d4c9ccf,
+ 0xde9cbc21, 0x34b5327c, 0x3115fe98, 0x8d1e982b, 0xebc26694, 0xf489ac82,
+ 0xeb05ad18, 0x89d7ad09, 0x0d7cf35f, 0xb1553a78, 0x787a2ba4, 0xe54f7414,
+ 0x05577f39, 0x3d9acee4, 0x33e83f36, 0x0f17e362, 0x6cfa0adf, 0xda40b9b6,
+ 0x2f547bb5, 0x5bb174e4, 0x1ce267f5, 0xba34fe6b, 0xeecce712, 0x68352e21,
+ 0x170e74dd, 0xb0b97ce3, 0x596252eb, 0x1933f72e, 0x9eed44f2, 0xdfa03c87,
+ 0x5cf1e6ee, 0xf1affa9a, 0xff99af3f, 0x20fdcf9d, 0x81f046f1, 0xc0b2278d,
+ 0x3e0f89df, 0x99fd8697, 0x791db5f5, 0x83875a21, 0x2c7e68fe, 0x7ff45fbf,
+ 0xa3a5f2c5, 0xbbfaf559, 0x349ec3c0, 0x07ffc33b, 0xcd026fcf, 0x7e73b12f,
+ 0xe03d9f34, 0x6b3cc6cb, 0x9c766ddc, 0xd11d17b3, 0xb4a7e079, 0x89f989a0,
+ 0x06e4f9fa, 0x289b2d7f, 0xee16bf88, 0x09c2bf9e, 0xf151a179, 0x6f280f40,
+ 0x2adcf956, 0xddfaa0df, 0xecc29784, 0x213bf6bb, 0xe5443e9f, 0x3abc74d4,
+ 0xa8b38fea, 0x54fbc2fe, 0xf8dbefce, 0x80da3fd3, 0x11360dd7, 0x47863c06,
+ 0x63c7d26f, 0x3e916879, 0x37cd45bf, 0xb7a0569d, 0x013d51ec, 0xe51cdfb4,
+ 0xd5b2f7c1, 0xf4c163b6, 0x50bf1f35, 0x2bd7f37f, 0xf81a40fe, 0xc2fcb984,
+ 0x27ce9f30, 0x5c6fbe42, 0x027f7535, 0x89eb2b52, 0x72e6fc8b, 0xf34ebcfc,
+ 0xdf7fd5a9, 0x17a6b99a, 0x29c173f0, 0xabf60b44, 0x1df595b5, 0x054d6811,
+ 0xfeec2f1e, 0xac78152c, 0xb27ff57d, 0xebf81744, 0x51cd4fd8, 0x84222709,
+ 0xc6e74b38, 0xfdd01637, 0x5dc5c9a5, 0x8fb17fd4, 0x6d5b17dc, 0x63905ebe,
+ 0x8afc6ff7, 0xddc5c1f9, 0x17575f5a, 0x5fb9dbf4, 0x124b4e7d, 0x205380d2,
+ 0xbae4da1d, 0xe484fb11, 0x1f417bc1, 0xdd4d569b, 0x6be77944, 0xa2424836,
+ 0xf7923336, 0xfcc7f60b, 0x7d8d7ea0, 0x017c15b2, 0x1fc930e9, 0xe523ec5e,
+ 0xbcbad584, 0xfb5f75b0, 0xe62ecce4, 0x26cd3ab3, 0x923edbcf, 0x2b4dcc6f,
+ 0x9c874f0e, 0x0345f161, 0x75ebc21f, 0x157c1027, 0x97eabe9d, 0x3df0512d,
+ 0xda723449, 0xfa71345b, 0x245a10b8, 0x0b8f0bea, 0x4fa21670, 0x7bc7e02c,
+ 0x31abd79e, 0x8e89fcdf, 0xd06af03b, 0xf8562f83, 0xeaefd337, 0x63508746,
+ 0x46b5ed20, 0xa0d451a3, 0x4beebfa9, 0x540fb6e5, 0x3ed49fd6, 0x2e3d3e06,
+ 0xc8cbf7e0, 0xf8c131e9, 0x74b877db, 0xdeabfa02, 0xf52e7a49, 0x4d877e77,
+ 0x5957a004, 0x3d50bf69, 0xec2fe1db, 0xcd4be069, 0x5cbc808a, 0xaf7c794b,
+ 0xfaf5651d, 0x9792e083, 0x9a91e12e, 0xbb70c59e, 0x9a1ef560, 0x9573fa08,
+ 0xdbd721da, 0xc04f970e, 0x2a4b6379, 0xfb5e63b5, 0xa4758f0e, 0x56b16f01,
+ 0x9aab37de, 0x5c5b718d, 0xf62a3fe8, 0x436f9e03, 0x534445ae, 0xc28f86bb,
+ 0x874c0cfc, 0x3a6143e4, 0x85021b5c, 0xf817770e, 0x14c289f1, 0x77ca8231,
+ 0xcf3013a8, 0x1752aef3, 0x958b68f0, 0x9b308776, 0x9af40277, 0x78b8d8b0,
+ 0x7a446fcc, 0xabffcf06, 0xcf3c25d8, 0x80bc48af, 0x7af241be, 0xbd0df231,
+ 0x7d8655cb, 0x8fbc23e3, 0xfc721d6b, 0x9f2a3da8, 0x43a462a3, 0xbbefdbe7,
+ 0xc89c68ca, 0xd024dabe, 0xa89f3183, 0xf00baf61, 0x858b1ce7, 0x3786b3e5,
+ 0x2f80d722, 0xd21be518, 0xf819bd25, 0x75609958, 0xae3c7f81, 0x574ae7d3,
+ 0x6820a3b1, 0x161eb69d, 0x0ec55e1d, 0xbdbb69c0, 0x97ce10f8, 0x738efa36,
+ 0x54d27f73, 0xaa14f407, 0x273f4167, 0x64c768ea, 0x0ee9dfa3, 0x424177c0,
+ 0x5bb478e9, 0xc2ac9628, 0x5eb85b7e, 0x3e208115, 0xe39360db, 0x211cb82e,
+ 0xc73a4302, 0xe3f8405d, 0xf9a397f6, 0xd653837b, 0xfb92886b, 0x2974cee7,
+ 0xd3d4ae2f, 0x83fa7ab5, 0xccc7baf9, 0xfec7cfd7, 0xe4a94b71, 0x53a677ef,
+ 0xeb4ad5bf, 0xab268878, 0x80edda92, 0x973a89ef, 0xcd058408, 0xc6758af7,
+ 0x38d0408b, 0x3b2ef51d, 0x183e2045, 0x47c66e1f, 0xb9237ae7, 0x125d44fc,
+ 0xfefbb1c3, 0xec704c53, 0x04c33fec, 0xcffb2bc7, 0x7513f2e2, 0xffd1df39,
+ 0x4ffa6ec0, 0xb3bfcd33, 0x5dfc7edf, 0x82fad2ec, 0x22eddcbf, 0xd374c07e,
+ 0xbb2676ca, 0x7606fda2, 0x9871f12f, 0x95f7dc80, 0x0576cb53, 0xe96d87f1,
+ 0x0b9f5d76, 0xfadf80a4, 0x6b4e3ac4, 0x8f1a5d77, 0x0be26ef6, 0xcbd0e76c,
+ 0xcf1b456b, 0xfa02fc13, 0xbab648bd, 0x96977cb9, 0x98c8bd0d, 0xf33c8747,
+ 0x859f48bb, 0x9ed841f6, 0x1f6347bf, 0x4db6b45f, 0xa9aa7d86, 0xde088d59,
+ 0xfdf407d7, 0x17cfb631, 0xd5d7b079, 0xbdf11da0, 0x9c5dee9f, 0x84d4f80d,
+ 0xde61e5b5, 0x2dfef7fb, 0x57c8e70f, 0xc5f7167b, 0x9f54adf7, 0x5b7b0fe5,
+ 0xbfa8278d, 0xb3e5c27e, 0x9b4ce88c, 0xfa1ffdf5, 0xfa9eeb7d, 0x36c7985e,
+ 0x2e483dd8, 0x56f659ac, 0xb078f1c6, 0xe083ef21, 0x16f8825f, 0xa6bb43eb,
+ 0xdf2063a9, 0x0f32487d, 0x96ee87e5, 0x3ed0c372, 0x83496fc2, 0x2ce1f7dc,
+ 0x619a89f0, 0xe1541776, 0x9616fcf0, 0x3987c3b7, 0x9f9f385c, 0xebc193ed,
+ 0xc84e43b3, 0x78a2fb40, 0xf154e7a6, 0x1b6dc9af, 0xe04ff642, 0x68db350f,
+ 0x75b56abc, 0xf78538f2, 0xa9f031d1, 0x78bfb79a, 0x135fd747, 0x8c5a9f81,
+ 0x5f78f04b, 0x432127ef, 0x9a7a893b, 0xabbef5a3, 0x9b8cdea8, 0x1fa15393,
+ 0x99fae895, 0x19404898, 0x1068fcc9, 0x9e5720ec, 0x7a0f52db, 0xc034d14d,
+ 0xf0ec97c1, 0x981afce0, 0x71c91c22, 0xf4fed0d8, 0x57ee34a9, 0x2ec316e9,
+ 0x03de60aa, 0xdf3d35f4, 0x2c6969ab, 0x38fe939f, 0x3b3fd1d0, 0xfbc325ae,
+ 0xa30bf077, 0xdf3787fe, 0xe2eb483a, 0x79e430dc, 0x36e9bdbb, 0x3aadb3cc,
+ 0x9847f592, 0xc9eed0f3, 0x2a02c39b, 0xc8b68aec, 0x3fe7d0d5, 0xb07b988a,
+ 0xfee3c107, 0x83222d28, 0x799acdda, 0x95e42ac3, 0xa5eef1fd, 0xd692e7a0,
+ 0xd3e7c0e1, 0x83262d4e, 0x6872afc6, 0x8969137d, 0xd968fbe7, 0x8be43831,
+ 0x449e25e3, 0x2ee2a0f1, 0x53e72fe7, 0x0ff1c8a2, 0xe8496947, 0xf2d2c4a7,
+ 0x66f855c4, 0x837b616d, 0xfdc1e868, 0x8a8bb79c, 0x037fe4ae, 0x75f4470e,
+ 0x6b89b3ec, 0xf6fad32f, 0xd4f18dad, 0xefcb7cd3, 0x96b7399e, 0xe296f9d2,
+ 0x9a6a80c4, 0x55d61677, 0x9be92be5, 0x79f3f24c, 0x65ef3e9b, 0xaeadbcfa,
+ 0x1cfde0ac, 0x437aef3a, 0xc285f95e, 0x50ff20fa, 0xac5f15fe, 0x87ca5eff,
+ 0x307d2e59, 0x20d6e70d, 0x3649db0b, 0x22ded384, 0x7d5df23d, 0xbed38f9e,
+ 0xf7f1c473, 0x149ef8d5, 0x3d27db2e, 0x7ec3f16c, 0x37763c50, 0x9ac9e9e3,
+ 0x634a8f48, 0x1db70895, 0xf0995072, 0xd9fc5cb2, 0x69edbf98, 0x661575a5,
+ 0x6e01d768, 0xa92de2f3, 0xb43cf01f, 0x6f205381, 0xf8eb928d, 0xd7937916,
+ 0x6cb85531, 0x3589942c, 0x531fc816, 0xf329725d, 0xa63fb915, 0xe30daf09,
+ 0xd71a10cd, 0xbb05c3fb, 0x1fc4fa17, 0xbcd10ba0, 0x7f1f0a67, 0x9cfc2d9f,
+ 0x5c022ade, 0x95a2c7ff, 0x89bc06f3, 0x4825e63e, 0x53d938fa, 0x8cdff865,
+ 0x9117bf79, 0xad1967d7, 0xd923ca63, 0xad5fac99, 0xf9f0c1eb, 0xd14f79ae,
+ 0xeff686e9, 0xfd83f43c, 0x99fa9d3b, 0xfec8637a, 0xe061ec2d, 0xf6dbf333,
+ 0x877b4b51, 0x4c9914fe, 0x475eb870, 0xc5def5e9, 0xa9153fac, 0xf847c291,
+ 0xfaa51969, 0xf21c7721, 0xa0484f2e, 0xb9fddc75, 0xb77e83d4, 0x843dbc5c,
+ 0x46377fca, 0xd2dcf515, 0x64d4f2cb, 0xbdc99fbd, 0x9d869fc7, 0x2408b0f5,
+ 0x17b9a50c, 0x8f5ed65d, 0x564ef9a1, 0x52c435b7, 0xa4de84f9, 0xbdf104c7,
+ 0x5bb6121b, 0xd8ddd7a1, 0x627dfccf, 0x99df59ae, 0xc0551a24, 0x7350f279,
+ 0x0f807dbd, 0x0c8ad7d1, 0x0188b7a9, 0xdfee8062, 0x47fbb963, 0x13ed1f7a,
+ 0x0be1d92f, 0xbb433579, 0x3a5c7007, 0x18b9b3e9, 0x7ae55857, 0xd951de6a,
+ 0xe48c779e, 0xdf9d2f2c, 0x84e8ebc7, 0x08f29308, 0x6e48a7f2, 0xcea67a40,
+ 0x3a39e9cd, 0xa17e51e7, 0x67eb23ce, 0x7d803f14, 0x73faba56, 0xb772f02b,
+ 0x6ef9c253, 0x761faa67, 0xc6a68ab5, 0xe55e98f1, 0x4883a6ae, 0xe3c503cb,
+ 0x382ecc71, 0xd220e4b4, 0xb6f43bbb, 0x5fdd0e25, 0x5dbff3c0, 0xa3dbd3a7,
+ 0x8834dea6, 0xbbedc9f6, 0xf6ebdfa5, 0x4da7533e, 0xc6de404a, 0xa8e8eef9,
+ 0x3422b2fa, 0xa8cf22da, 0xb758cdde, 0xc1e8f9b7, 0xc9e75a78, 0xff3c11ba,
+ 0x9e5e75d3, 0x09bad9ff, 0xa33dfe9c, 0x27ae39f8, 0x6c79673e, 0xd6a3b6d2,
+ 0xe45faa14, 0xb7d8bc55, 0xdf857ad7, 0xdeb1744f, 0xf581cf26, 0x1f600e74,
+ 0xf534198f, 0xe9303bf1, 0xda276d0c, 0x5171b8cf, 0x3c99c611, 0x7a8ac4a2,
+ 0x2216bf33, 0x4e93ad3e, 0x8dee8bbf, 0xf8eb57f5, 0x6157bf3b, 0x1bdf9e78,
+ 0xdf6cf0cb, 0xf9031191, 0x8ccee960, 0x6f89489e, 0x046f7a1a, 0xd97ed7e0,
+ 0xff6df3c2, 0x8ef59c28, 0x774bf6d0, 0x7a89ec0e, 0x22df0967, 0xfb3cde48,
+ 0x83b87ffc, 0x71b395cf, 0x027d5f4d, 0xc957f6fe, 0x39b248df, 0x5ff818f1,
+ 0xd01e5eef, 0xce5d05cb, 0x02233d26, 0x6e8d5fe7, 0x427f0457, 0xb4b86cfe,
+ 0x217f0ee7, 0x17f62c65, 0x9c1373c6, 0xb9191cc3, 0x7f7087c7, 0xfd467e47,
+ 0x9258fcbd, 0xb9effa07, 0x63a48fed, 0xf34dadfc, 0xfa8c793f, 0xf8b7ef3f,
+ 0x9d4e746c, 0x5e174d17, 0x2a7e1f05, 0x777bed92, 0x9c2f342b, 0x717b9bc3,
+ 0x86b1473e, 0x2c39c32f, 0x73cfbcfc, 0x1975b714, 0x17aaadf1, 0x7a05ed1f,
+ 0x30608d7c, 0x5b5fca82, 0xed7cc11b, 0xc8e79b35, 0xb8f7f432, 0xfbe9efec,
+ 0x0bb63cef, 0x05d57de9, 0x65fa5277, 0xa1e31c46, 0x034581fc, 0x79ce9ed0,
+ 0x3dfd4c91, 0x80128af7, 0xbad06abf, 0x69922b7d, 0x1c37837e, 0x34a2f4b5,
+ 0x1ea529ff, 0x373ec0e9, 0xf9fd821e, 0x6e6e196f, 0x9a5b643f, 0xd96d829a,
+ 0x75c9ffcb, 0xe59bfe7c, 0x9f75dc82, 0x3a25ed8f, 0x4a0183e5, 0x348d99d3,
+ 0x8fd4b0d7, 0x6386340a, 0x6767af23, 0x6ff7b4f3, 0x49075815, 0x8977981e,
+ 0x91e7c3dd, 0x7811b7df, 0x78e5af3e, 0xf62bbf58, 0x3b7a0a3d, 0x707a25af,
+ 0xfa4cbd3e, 0x7fa8d5fc, 0x7cebcac4, 0xa2f7a9e5, 0x2189df61, 0xbf09d93d,
+ 0x78db7e48, 0xe3eeafd4, 0xf587f016, 0x09fae279, 0x8ecd4f80, 0x9fb91b9d,
+ 0xfa07872a, 0x4bcec56e, 0x2f205307, 0x993c20de, 0x321dc7a0, 0xaf42abff,
+ 0x56a5a547, 0xe652fc6c, 0x5f398a5b, 0xfc27da4c, 0xca4ca2fe, 0xe7e88f49,
+ 0x63cd68a0, 0xee24c97e, 0xafd7c4ee, 0xebe518a8, 0xb0c97cd3, 0x27e71b6f,
+ 0xfda97b9d, 0xb2ec65b0, 0x5bd8cb7d, 0xdf2e1953, 0xebb3dcf3, 0xdfd197e7,
+ 0x73e17623, 0xdf303f52, 0xc1be9ec0, 0xcdebcf2e, 0x2f4067c4, 0xe34d79c6,
+ 0xed93f5e6, 0x29afe0bd, 0x076832aa, 0x91e523c1, 0xbe379630, 0x62b3f8ef,
+ 0x6df9f156, 0xe1b55bc8, 0xd9f22f92, 0x885fed41, 0x37eeaed2, 0x7932760c,
+ 0x3bab0bde, 0xe3c8f217, 0xfa6bde51, 0x96d5bcb1, 0x39d0358a, 0x53e61d7a,
+ 0x95fc92a3, 0x457f2411, 0x73af7dc6, 0x2de51034, 0x5beffb42, 0xcd046c7f,
+ 0xf1290633, 0x86a468ef, 0x485a45de, 0x7d39fc97, 0xf3f8135b, 0x3f926143,
+ 0xbe610d47, 0x7433ac64, 0x07c4039c, 0x6f3be234, 0x11a339d0, 0x3917183f,
+ 0x7d78cac6, 0x907552dd, 0x3922e5ce, 0x1ada0802, 0xdef3943b, 0x61638228,
+ 0x2eb42aa4, 0x252347f4, 0x3ac7cdbc, 0x984427c7, 0xc42515ea, 0xbf8fb1da,
+ 0x1d55faef, 0x3cb86a4f, 0x8370d4bf, 0x7413babf, 0xfac87dbf, 0x776f7ae5,
+ 0x3abe630e, 0xeb7ef956, 0xdf15b22e, 0x8b8f3c09, 0x7373e7cc, 0x2394e45c,
+ 0xd475e09a, 0x7ae87be1, 0x1c25d743, 0xfa8e4fdf, 0x167c2289, 0xedcfc7ec,
+ 0xb66b776c, 0x5bf73eb5, 0xa2f36b82, 0x47ec0f5c, 0x70bed32f, 0xb54e9f80,
+ 0x0cdb9cb3, 0x37ea92d9, 0x5c7170f7, 0xdfba6bcb, 0x6f5b37dc, 0xbe7c14ef,
+ 0xc5eecf34, 0x615ef47e, 0x48ec1034, 0xd26fd2f5, 0x16f25b6c, 0xe5e6ebce,
+ 0x819a1e29, 0x69efc150, 0x97e47ccb, 0x095ebcfc, 0x817f0adc, 0x40bb73ef,
+ 0xfeb175fd, 0x5f94e9d5, 0x9e0c8bf7, 0x8fa447cf, 0x8abc62d7, 0xeb5be670,
+ 0x71c9bd62, 0xff979f04, 0xb279f2a1, 0x91f29f2e, 0x6ed9d7cc, 0x378a6eb3,
+ 0x04ad7e19, 0x36eb6f1d, 0xb05ef2ca, 0x4d3ca293, 0x26c4ffb6, 0xd7a2dfeb,
+ 0xfbf1d04b, 0xb4a74eb1, 0x683f99ff, 0xa0ac2393, 0x95fb77ff, 0x46fbc6be,
+ 0x17e19378, 0x933cac7a, 0x54b7986d, 0xf4c690de, 0x66d3dba4, 0xe8dcfce9,
+ 0xc31c0d17, 0x9fcb4f21, 0x3b37f3d9, 0x2a33df41, 0x1f21479c, 0x22b1547e,
+ 0x0cfd7a0a, 0x21840d4d, 0x917a6abe, 0x4bae43b7, 0x395eb8c7, 0x1fa1b96e,
+ 0xdf00ca06, 0x710e6dbd, 0x81ffcb2f, 0x96fac121, 0xfa45e781, 0x1a6eadbe,
+ 0x7eb060f3, 0xfe27695d, 0x72e51833, 0x6a45573f, 0xd57d07bf, 0xc1e1baee,
+ 0x54fbbd60, 0xbc7943f9, 0xcf71f4ef, 0x3c1f79d5, 0x6f39099e, 0xb8c6a702,
+ 0xf011fa1d, 0xd5f6fd49, 0xefda73cf, 0xdaf00b3e, 0x92fa94e4, 0x85e3edb5,
+ 0x359faf94, 0x09f7cf80, 0xd85e1d53, 0x8477daf5, 0xadaf61f9, 0xc5ee159f,
+ 0x44f7eaba, 0x985761f9, 0xd21befa7, 0x6fbbf8bb, 0xade98dbb, 0x667feeca,
+ 0xdaabb50b, 0x89e99fdb, 0x96ed95e8, 0x642357be, 0x6d37b479, 0xf79450e5,
+ 0xcd79fa64, 0xf2e18ee6, 0xe5c15537, 0x58ac81e1, 0x539b7782, 0x1375853b,
+ 0xbcfdb2bd, 0x1fbf2eca, 0xfa12e9d1, 0x96fffb25, 0x42bf7144, 0x8f3f6bcf,
+ 0x584f7d67, 0x91f3c9bd, 0xaf207dbf, 0x7dcbb347, 0x7ea46a21, 0xe725c478,
+ 0x9e39a475, 0x8f4185f7, 0xdcb78a47, 0xef809593, 0xfcd2af24, 0x0d4cb2fe,
+ 0xd06e1fc0, 0xf2f5329f, 0xbb5157db, 0xd9555f4f, 0xd7e7336f, 0xfbe30f8b,
+ 0x13d5159c, 0x6bbcad39, 0xf5cb9f32, 0xa2eea71f, 0xa7a984f2, 0xe06bbfd8,
+ 0xd9954e7f, 0xe9989a9f, 0xdf813355, 0x83f6ff5c, 0xd9e1ff54, 0xaf001627,
+ 0x473533c3, 0xf6dbec26, 0x4cff97d6, 0xfe5d6df3, 0x36a3d627, 0xf8116b44,
+ 0xd3f7717e, 0xc566bf5c, 0x7e802cff, 0x74956350, 0xb5db9c63, 0x91bf3d3a,
+ 0xffa2c5a9, 0x63bf15aa, 0xb722223d, 0xbbd7f245, 0x3a3f1fbe, 0x65f9bcd3,
+ 0x0e2dda85, 0x54e1ae6f, 0xfce1e7f5, 0xa204ab3b, 0x2b860c95, 0x5ce775eb,
+ 0x47e06881, 0x72b948b3, 0xbf10d6f1, 0xa8925031, 0xdda88bdb, 0x8f5526e2,
+ 0x41dbf457, 0x17f5a1a7, 0xf7ae77d3, 0x8a57bf3d, 0x763df926, 0x30d7fdd7,
+ 0xfe0045fe, 0x64cf33ae, 0x9c3d026e, 0x5674f9df, 0x34369fb0, 0x72be72bd,
+ 0x7df4e7fd, 0xd8be8e73, 0xc2db6f40, 0x0b85f64c, 0xf4eb24cf, 0xc2e9e926,
+ 0xe7ecd933, 0xd9f7d44e, 0x0967c505, 0x085fbb47, 0x9e10678e, 0x971ce1a6,
+ 0x0e1a6de3, 0x9d61fbb9, 0x6f8e2e2f, 0x67be0e1a, 0x68e141f0, 0x41bb63ca,
+ 0xf41e534e, 0x8a7f8364, 0xfe2ca6e2, 0x42ca6fee, 0xd22d97fb, 0xa7cc630e,
+ 0x8e14b9f2, 0xf0b5a27b, 0x6e7caefe, 0x8de426e0, 0x929dea71, 0x253bd4ef,
+ 0xb75d097f, 0xe8ed2996, 0x1ee64fa4, 0x3ea4b3a7, 0x5c82f496, 0xde6593e4,
+ 0x370bf329, 0x6fe1d894, 0xbcc9b7af, 0xfd897d6b, 0x35f7e618, 0x4fc4b569,
+ 0xc5bf7473, 0xdda97f02, 0xfafefb0b, 0x3f1ce1e5, 0xcf3edb31, 0x7af6694b,
+ 0x035c69bb, 0xe6fdfd0f, 0xf9f48bef, 0x0b890df4, 0xedb6a5ea, 0xf639c30b,
+ 0x8e32e8a4, 0xb4a64960, 0x6cfb3ee3, 0xaa917c47, 0x6dc2dbeb, 0xea5ba1d0,
+ 0x8fd78c1b, 0xef5e06ed, 0x2ff9a148, 0x5ea5e3d6, 0xfab848b6, 0xe37c959e,
+ 0x052d7ce5, 0xc005d5e7, 0x2c5ce71d, 0xef2173e5, 0x7919bc49, 0xf0a15f03,
+ 0x82f1f15d, 0x9f95d814, 0xc7f694c8, 0x8f2c7c50, 0xe513de1a, 0xd4cf5c06,
+ 0xdc00ca1d, 0xa89d758d, 0x68e97af3, 0xafbfb4eb, 0x8c6877cf, 0x30477c8f,
+ 0x1d6fd77d, 0x20248872, 0xd5ab6e71, 0x5bd42583, 0xbf43f7fd, 0x36aadfa8,
+ 0x3b9704f9, 0x91739780, 0xbd41dffb, 0x0b621b05, 0xed180fa0, 0xf22fae17,
+ 0x7bcd0796, 0x5e3356e0, 0xf3993506, 0xf3997783, 0x0d06715b, 0xe5dbe7fb,
+ 0x21f9cc07, 0x93f9cc87, 0x3371dc1f, 0xea854fb6, 0xbe855fbb, 0x87f1e7f3,
+ 0x7a9f4e70, 0xe06895f9, 0xcb5ff16b, 0x0b8f420f, 0x3c21678d, 0x7c73d02a,
+ 0x97a6145b, 0xba5ae22b, 0xdc4643e1, 0x30627606, 0xdf0a54dd, 0x95da6b41,
+ 0xa68acff5, 0x6744bd9b, 0xcfdecb55, 0xecb37a90, 0x5ad36477, 0xd0cee43b,
+ 0x3be3bb71, 0xc6ebd222, 0x21192a3e, 0x365eaecb, 0xfe8a7c4e, 0x1e37bcd6,
+ 0x2bf258f4, 0x929be585, 0x075fb297, 0x3edd1cdd, 0x6f4e46fb, 0x30f0c09e,
+ 0x9b0b92ec, 0xe5144095, 0x8744235d, 0x8bf11f7f, 0xf1210da5, 0xe2426b9f,
+ 0xcb99d682, 0xf7daee17, 0x504710ff, 0xe38278e1, 0x678cae2e, 0x5e801ff4,
+ 0xb04a7959, 0xa9f2aa7d, 0xe5ccc26f, 0xf5f35d72, 0xade71875, 0xf1cb5df0,
+ 0xaacb577b, 0xa3fe38e2, 0x4ba8e973, 0xcb73853b, 0x5eaf7738, 0xf29551b7,
+ 0xfd84b7bc, 0x8e7691c8, 0x8876ac8b, 0xebcd0440, 0xebdd9450, 0xd697efa2,
+ 0xb2bcb147, 0xe85ce480, 0x270a948b, 0x627a4dc7, 0xbbc4eed0, 0xd565cb2a,
+ 0xd51e12f1, 0xb0fc51bf, 0xa8c3571d, 0x3293fc8b, 0xd80448bf, 0xf23a0bbe,
+ 0xf803ad06, 0x468bce0b, 0x59565fa9, 0x9f00fb03, 0xab68738e, 0xad155eb9,
+ 0xc838a3f3, 0x35efe67b, 0xd7eb8da2, 0x2c26faee, 0x3d907bf8, 0x435ef59a,
+ 0xf97556ff, 0x3865fd4a, 0x20744fcb, 0x6cbe8384, 0xeebedcba, 0x6823921e,
+ 0x7b0d2b7d, 0xdf295af8, 0x9e51b2dd, 0x679f2463, 0xd6eb4e01, 0xef867c92,
+ 0xce206fa4, 0xf70a2c44, 0xea5ef94b, 0x6766eb0b, 0xf2f45cb1, 0x400a5e3f,
+ 0x487b691f, 0xbad2bb61, 0xbaefd97c, 0x3973fafb, 0xe3c2a7f8, 0xb61cb184,
+ 0xde518a6e, 0x4f91f587, 0xc864c530, 0x1ef7faf9, 0x4bdefe6e, 0x3ec166f5,
+ 0xb2741e22, 0xfb90c47d, 0x2ebeb90d, 0x1ac9cb56, 0x75feb9d6, 0xf0516db1,
+ 0xf88a89bb, 0x6cb725ef, 0x36e3cfd6, 0x2afc3f5a, 0x83e295c7, 0xf5198ff0,
+ 0x73c96646, 0xef58f865, 0xfb1ebd16, 0x532dca5f, 0xe68ebdee, 0xc5b0fe55,
+ 0x81a17b0d, 0x66f5e107, 0xd7c70e01, 0x77400b3a, 0x7b4ac7c3, 0xc97c91d9,
+ 0x0a8623e7, 0xab1a378e, 0xcb363bf7, 0xc2934a62, 0x9fa91e89, 0x1ed245e3,
+ 0x98b4351f, 0x132496ed, 0x6e2aebcc, 0x4fdeb265, 0xf7f8bdb9, 0x4f98bba3,
+ 0x4a145d07, 0x6df8fbf9, 0x2f3926ca, 0x0e27c72f, 0xf6c9c07f, 0x39fae3ce,
+ 0xe881e064, 0x0fcb1868, 0x0d8b5f3a, 0xa0b59ba1, 0xa0879c07, 0x6e982507,
+ 0x8b7174cc, 0xee2be122, 0xbaf7f293, 0xe8379958, 0xf13ff482, 0x229ba0bf,
+ 0x4eeff0c1, 0xdbd6340f, 0x74481e9d, 0xd07408b0, 0x0e842f51, 0xec3fd584,
+ 0xa542fcdb, 0x2b876223, 0xab148284, 0x17ce21f0, 0xebc32467, 0xb11fab1e,
+ 0x12adbd78, 0x92ac7d2f, 0xf1b4e8ee, 0x7d701785, 0x4b7de22f, 0xbc285c1e,
+ 0x4524bf54, 0x1fad7db0, 0x713155c9, 0x45204edc, 0xbb0a8e58, 0x5f68a513,
+ 0x2ffb2312, 0xfe3829e9, 0x5af3fa8e, 0x36e674e2, 0xc15efe1c, 0x47da0572,
+ 0x9f7b7017, 0x5af7b645, 0x219bed29, 0x95b698f5, 0x5cbf1c61, 0x2c9f7772,
+ 0xb1c4c9d0, 0xa2393a66, 0xde9195d3, 0x8dd6ed94, 0xf0249e75, 0xfe86d283,
+ 0x3bd4de7c, 0x0277ab8b, 0xb047cf9f, 0xeab259fc, 0x618693c7, 0x7bc42f7e,
+ 0x9333c280, 0xa83fb3b7, 0x4ff661b4, 0xb4be843e, 0x2bdfc9d5, 0x59f5b5b2,
+ 0xf715ff90, 0xa1f49ddc, 0x7b01c674, 0x9ad7b512, 0x957f9ca6, 0xedbec9d2,
+ 0x989e40ef, 0xfae55d3c, 0x3fb48593, 0xce39068b, 0xd6e7df24, 0xd26fea24,
+ 0x69c38528, 0xa95d3a8e, 0xa40fc1b7, 0x2ca9f7e3, 0xe47f9745, 0x5592813d,
+ 0x73d2b27d, 0xc9213fe1, 0xfd390bb8, 0x18fea353, 0xa5e40365, 0xfee4e3be,
+ 0x1fa3ea33, 0x4b3a7bf4, 0xd5bf55ca, 0x09e462e1, 0x7cbf5cae, 0x8cd1d875,
+ 0x40b6a468, 0xfde9a536, 0x7584bec7, 0xe3174c4e, 0x77ee03d7, 0xcf1362aa,
+ 0xf984adb7, 0x1b965442, 0x4291abf4, 0xd6e3facd, 0x8f27ccfe, 0x7a3b698e,
+ 0x6e8fe537, 0x8ced241e, 0xbe617dba, 0x707cb04b, 0x77e48c74, 0x98239b6d,
+ 0x5ab88ffe, 0x3da4e2a3, 0x650ded8e, 0xb67c493a, 0xf87efeac, 0xed22cbb9,
+ 0xcc7e7147, 0xc71a687f, 0x53ad9427, 0x07b86103, 0x6f6cc6b0, 0xded48aa8,
+ 0xb5087ec6, 0x07da841b, 0xa3a03340, 0xd30a35f2, 0x8f7adf61, 0x9cf9993d,
+ 0xcafac2e2, 0x70fd0323, 0x9c7b940e, 0x857cc71c, 0x826be0fd, 0xb9d870fb,
+ 0xb5890705, 0x009f6b67, 0x258d254e, 0xe446efac, 0xfabfcc6a, 0xec1704aa,
+ 0x26fe9d17, 0xbe0b5ec2, 0xc64d6d64, 0x9655fcbe, 0x3130f19b, 0xc91595ce,
+ 0xfbe4ed74, 0xae6d4711, 0xe8efcc2c, 0xe705a74a, 0x9215c4ed, 0x39df69be,
+ 0x1ee18f70, 0x3f0708ab, 0xfb259ad8, 0x5adcb39d, 0xbdf291bc, 0x151ac21d,
+ 0x67cafa07, 0x5fd85efa, 0x75e62dfb, 0x046217ea, 0x35b289e4, 0x74bce56b,
+ 0x96d610fa, 0xe71a78c2, 0x02b4e6d4, 0xe43a01d8, 0xdb63fedb, 0xba0ec701,
+ 0x3d30ae98, 0xc10e7ad0, 0xbfde9c8e, 0xe9ca32f4, 0xcbd03efb, 0x7e81b1c4,
+ 0x522f1b88, 0xb6be38ab, 0xe078493d, 0x6d176c77, 0x93b48f2c, 0x67be023c,
+ 0x9f8319f0, 0x1d785d10, 0xdef89d89, 0x22534752, 0xceb5be1e, 0x75b3e9c1,
+ 0x7825612e, 0xe24bab6f, 0x6e750bfc, 0x72ea9b4e, 0x758bfbf8, 0xa8efce1e,
+ 0x97f9c11b, 0xdf9cbceb, 0xd3813755, 0xf98aeb57, 0x08afc1bb, 0x0c97cc3e,
+ 0x27f063be, 0x3e0cbe83, 0x73574a15, 0x17b8cc09, 0x1f99ed41, 0xeb107c1a,
+ 0xf27414b0, 0xe9cf0327, 0x092fb14a, 0xceb450fc, 0x5228ff06, 0x0aff3dcf,
+ 0x22bdb9c1, 0xed22ed92, 0xf6c1f242, 0x079f0748, 0x0bb176a9, 0xdbfa89f6,
+ 0x0eef47bc, 0xad6f873a, 0x88358450, 0xc4bc7f8e, 0x7441ac29, 0xac596f3c,
+ 0xd9673f29, 0xa4f46ffb, 0xd18ddffe, 0x1e69b372, 0xe2797e47, 0xf7d13ff1,
+ 0x4cf2fcdf, 0xf34ef026, 0xc608fcd8, 0x9f5c2bbd, 0xd79cab47, 0x9796765d,
+ 0x7d4b86fa, 0xd4b86fab, 0x08e3f0b7, 0xa23dcf8a, 0x2d24a3e3, 0xb1a79df6,
+ 0x9baeec6f, 0xb44ec047, 0xfa4bde52, 0xf2a3f804, 0x2bf8e8bf, 0x70c6165d,
+ 0xf7d06d2d, 0x36dc706b, 0xb258f5c1, 0xf14ef960, 0xd7bf010a, 0x03d85fb1,
+ 0x63882b24, 0x40afc38a, 0x6be52276, 0xab98ec0e, 0xe411f77f, 0x21d96576,
+ 0x4735b396, 0x087fc724, 0x705ced9f, 0x83b2ca7f, 0xf6b44f5c, 0x466fc536,
+ 0xc1daf50c, 0xc0e34037, 0x7ece695f, 0x1a2efd81, 0x547fbe15, 0x5f2f7fae,
+ 0xa2e298ad, 0xf2ab6467, 0x959645de, 0x4259f3d3, 0xf91a473f, 0x96e832bc,
+ 0x61c708f8, 0xdbe63796, 0xe7f10417, 0x597bfd52, 0xa714c58e, 0x9d967f79,
+ 0xcd8f39fb, 0x9bdefd49, 0xcf9f6e93, 0xf7cdcffc, 0xa5fa8c05, 0x60ab0539,
+ 0x835d2e4f, 0xf6cea6a8, 0x7d56d925, 0x7fa92e5e, 0x8b5ce839, 0x2ea2f8e2,
+ 0x9e4307cf, 0x475f8539, 0xef59fcf2, 0xb9e17caa, 0xac8fe017, 0x9f1873fc,
+ 0x75839553, 0x7fae4afb, 0x839634f8, 0x70ca91bc, 0xff12e1c8, 0x35fdcf85,
+ 0xb55d711a, 0x97bda43b, 0x6b48a3d2, 0xfb60aaee, 0xf6878d5e, 0xadf81c49,
+ 0xfaffefd9, 0xfbe67f0b, 0x14b0849d, 0xe3986e3d, 0x7c766ad4, 0xb06bf1ca,
+ 0x7286f9c7, 0x1d5f1c7f, 0xf956beda, 0x4257f59a, 0x68a7c32c, 0x3c8997cf,
+ 0x12979d8f, 0xf76ae7c1, 0x2aec4cac, 0x1fb4288e, 0xb0c1ce23, 0x358ad5ff,
+ 0x59cfc39f, 0x9384d77b, 0xff65de92, 0xca1eeda1, 0x31384a8e, 0xeec62050,
+ 0x5893b62a, 0x2c9fc705, 0xed38edd5, 0x63f64cfe, 0xd7772777, 0x2446a7ae,
+ 0xdd5bb592, 0xbeb38831, 0xae84c428, 0xb649f4f0, 0xd3cf6b94, 0xfb3f823e,
+ 0xe59536e2, 0xa2db8bca, 0x6cd43f78, 0xe220f07b, 0x529e6b04, 0x2d58edd8,
+ 0xafce385a, 0x1c2a8766, 0xec1de7c1, 0xcfddf147, 0x5173f173, 0x8b5f404b,
+ 0x66ef149a, 0xc3bb4f9a, 0x6823d31d, 0xbe80af3e, 0x87173488, 0xff470d35,
+ 0x079ffcc6, 0x37920b7f, 0xc83f3517, 0xef548df1, 0xbf37cb02, 0x3c38e08d,
+ 0xc1dec93a, 0x186ecf3c, 0x45f5fec2, 0x586bdb4d, 0xe116d83e, 0x8ce9e982,
+ 0xe40f7ccd, 0x81de3e80, 0x9c8f296c, 0x67d1edd5, 0x1f59505f, 0x2fb13cc2,
+ 0xb871e8cf, 0xf537bb46, 0x4b666f76, 0x5b26a7f9, 0xfea34fee, 0xd1a3a6a2,
+ 0xc9fea8fd, 0xfa73ef5d, 0x166fbebe, 0x3df0b645, 0x223b93cf, 0xc9e09ef8,
+ 0xfe39ff1d, 0x7cef1a35, 0x250498d3, 0xc89d9f68, 0xba7dc9b6, 0xf32fc641,
+ 0x13d61725, 0x673d789a, 0xac28a5b7, 0xa4de032f, 0xf1dd9fb7, 0x3643df12,
+ 0x1c1febe4, 0xb14b382f, 0x18a3dc86, 0x8d72083d, 0xd7bf55a3, 0x63dba6d1,
+ 0xaffa6ffe, 0x5927bfd1, 0xe471f58a, 0xc4610d3d, 0xbd64b86f, 0x27b73522,
+ 0xc1dcddf6, 0x97b899ee, 0x7192de2d, 0xfbb7a297, 0x737fe811, 0xbb678ddf,
+ 0xbb9b52cb, 0x1c5ff227, 0xe0958526, 0xce887733, 0x875a9257, 0x347bbec1,
+ 0x8615ca4d, 0xb56aad3f, 0xbf04bc22, 0x3e67445e, 0xd0aafde4, 0x49c90760,
+ 0x563d7c67, 0x71daf161, 0x99d9463e, 0x3bb7ea2e, 0x75bec137, 0xec7c2ec4,
+ 0x29d17b7f, 0xd2e927fd, 0xf618f20f, 0x7155a517, 0xd878ac81, 0xa9ba74f1,
+ 0x41e54a9a, 0x29b553f4, 0xea390590, 0x2bda5d9c, 0xa9fd0e51, 0xabd640aa,
+ 0xfd14e9d7, 0x69a3dfa0, 0xf72c0bae, 0xd0128cee, 0x44af2c3f, 0xd3c8bb49,
+ 0x41614dce, 0x1cbf76e7, 0xc777118b, 0x66df4afe, 0x0bcc3f39, 0x7b22fcf2,
+ 0x5de41663, 0xd145dc63, 0x39de3c8d, 0xe145bc7d, 0xa39fd28d, 0x3ea211c7,
+ 0xec136f8f, 0x267b6a77, 0x33e6e58c, 0x632f2dc9, 0xf4cf33fc, 0xa387b8e7,
+ 0xbb05fe69, 0xf1c9dcb8, 0x86cf95e7, 0xd3df3005, 0x5db144cf, 0xca4db4eb,
+ 0x12a3a763, 0x143b1e59, 0xf65cf0f5, 0xa6153d63, 0x5a742ec0, 0x9424f611,
+ 0xf2c1ee6f, 0x32dd6540, 0x1254d7f6, 0x4b1c817b, 0x7fc804e9, 0x67f737a7,
+ 0x37e9d17b, 0x415cbe55, 0xbbe357df, 0xfee71a26, 0x0880f58c, 0x799e23b6,
+ 0x83fd6ff6, 0x5a463bfd, 0x3ed994f9, 0x5183d066, 0xf923945e, 0xd48e5160,
+ 0x71c86e53, 0xd11d5a71, 0xaf3a70f4, 0xc207f253, 0xb481eb03, 0xef61131f,
+ 0x3bb4d23f, 0x9c048951, 0x09ff5903, 0xfa956fb8, 0x366d99d6, 0xbe5553f6,
+ 0x3b65e512, 0xf157ddd4, 0x554ac97d, 0x1695e3ca, 0xf950df79, 0xffb656e5,
+ 0x2ce33fd4, 0xde083c00, 0x6db6dfac, 0xe471f556, 0xf4b7a7b8, 0x808d7e91,
+ 0x10797f9e, 0xc62635fb, 0x59537989, 0x0790dace, 0x2a7a5eb8, 0x69fee382,
+ 0x34e22f1c, 0x73f67f2a, 0x0598cf09, 0xc1d027ac, 0x4ab9fccd, 0x77d5cfe7,
+ 0xfb83135f, 0x955de210, 0xb25c79ef, 0xff827a7a, 0xd1ebc286, 0xbf3f9d1c,
+ 0x83f338fc, 0x8837da2a, 0xfbac5b0f, 0xab3f1713, 0x78b95cb0, 0x308f35d5,
+ 0x26c77ddf, 0x5ce22f70, 0xc1d183d3, 0x91cfa8f8, 0xbdb3b0fc, 0xa62feb87,
+ 0x5bfdb2fa, 0x2d9f3cd1, 0x13e60f36, 0xddefc78a, 0x07f559fe, 0x226cafb5,
+ 0xcaef22f9, 0x2d125ff5, 0xf833fd3f, 0xfb2736cb, 0x7cff0951, 0xadacea3f,
+ 0x7fd60169, 0xf32779f6, 0x72b1b39d, 0xf3a49fdf, 0xf98d97d4, 0xb66bf4dc,
+ 0x9a61fccb, 0xd0b439c0, 0x98d7ee6f, 0x9b1cead7, 0x4f78b7a4, 0xd544fc0c,
+ 0x47f40f84, 0xb711f9f8, 0xedc6d77f, 0x40b3d743, 0x4fb1d76f, 0xba608f9f,
+ 0xe24bdb39, 0xd90bece5, 0x8d1d9e7c, 0xf34ef495, 0x74de854d, 0xb8a65636,
+ 0xa87a0499, 0x387a4974, 0xed89a63b, 0xed956702, 0xc9b51e9c, 0x74cb9576,
+ 0x5fd13b7f, 0xb407e812, 0x63aabb09, 0x19e40b4d, 0x05e1f9f0, 0x4f70069c,
+ 0x0e8ed43b, 0xd7f9c53a, 0xe333efaa, 0xebf6051d, 0x89a79fb0, 0xba6bc7ef,
+ 0xedb5593c, 0xf0257f4a, 0x614db554, 0x197fda7f, 0x13acd0fd, 0xd1003f0c,
+ 0xc29f62e5, 0x6e2c22ef, 0xfb116db8, 0xbdac96d3, 0xac6f7415, 0x6f7eb163,
+ 0xf2a2a8fc, 0x693a8e7c, 0x395ee4ff, 0xdfdf019e, 0xef1d28e7, 0xf38cb875,
+ 0x3bf0f68b, 0x47496e39, 0xfea46d94, 0x35941aaa, 0xa19a4e3c, 0x19f5cae7,
+ 0xd8b02270, 0xaa3be761, 0x6eeed3df, 0xbb3cc6fd, 0x9d31cf9b, 0x934d1fcf,
+ 0xdedb93f7, 0x2fccf796, 0x26243d7d, 0x41e45bee, 0xf46061be, 0xd063b887,
+ 0x22f3f520, 0x35f61cf8, 0xcf34ebec, 0xff660dac, 0xe653ce4e, 0xe66d80fc,
+ 0x730eee7c, 0x9cd9af3e, 0xce6ebcf7, 0x0ee309ff, 0xf41384eb, 0x4235c46f,
+ 0xfd0a46ff, 0xf5261ddb, 0x7fa1e46f, 0x8dfe8523, 0x91bfd0ef, 0x3c8dfe87,
+ 0xa1e46ff4, 0xfe85237f, 0xfeeeef8d, 0xba554e12, 0xe07814bd, 0x4eddbab8,
+ 0xf7813e23, 0x89d9c5cb, 0x558547cc, 0x1717a5ea, 0xd8fcb2e5, 0xe29a6f61,
+ 0x11937b60, 0xad18958f, 0x1c47f785, 0x2ab2d280, 0xb1db8d39, 0x55f6ba1d,
+ 0x2aae8769, 0xeec24670, 0xe4f2bad1, 0xa73d882a, 0xd418b4a3, 0xdb6b68bf,
+ 0x2f56f802, 0xff7ec03b, 0x77eee5d6, 0x63f893af, 0x5f118bfb, 0x0f738255,
+ 0x25f49b7c, 0x71ee7719, 0x4353db04, 0x4d6244fd, 0xd3f21e50, 0xd43e733a,
+ 0xe6be042f, 0x46abed35, 0x6c6fc7c6, 0xfbe0c96d, 0xe0e33e9f, 0xea9f69fb,
+ 0xcb313bf6, 0x2198f2c1, 0x1bce23cf, 0x9f7a5970, 0x95e709b2, 0xc31c7fa7,
+ 0xa650fdb9, 0x68617ee9, 0x0879765a, 0xf91df3cb, 0xe3058a35, 0xbe5f4f94,
+ 0xcd6af58f, 0xedd2e7cb, 0xd7b2dcfa, 0xeef34c5b, 0xd1370fef, 0x71adc0d1,
+ 0x5ecc7e21, 0x7783faa6, 0x31f887a5, 0xa7ca9807, 0xbe6219ad, 0x8d7c5f8f,
+ 0xbdafbca9, 0xa1cf6e23, 0xfce4b9fb, 0xa5ceb25c, 0x6f5e02c8, 0xc554bd68,
+ 0x6ff827f3, 0x4e52dbc5, 0xc673a72d, 0x2bbfaf1b, 0x9d7f0052, 0x57e03277,
+ 0x858b64d1, 0x3f4cad9d, 0xf332c487, 0x15615cb9, 0x275c573e, 0x84b855dd,
+ 0x7fda9637, 0x654c6d69, 0x47e5fa3a, 0x68812aa9, 0x3c9680d1, 0xde8bafe8,
+ 0xe838727c, 0x98dd5aaa, 0x3bf2a2ea, 0x5c16ff14, 0xb7133f20, 0x9524713d,
+ 0x495aa927, 0xaa73c27f, 0x1cff702d, 0x19edd1f0, 0x7ca4ef02, 0x68a5e6ba,
+ 0xe9d41f8e, 0x0ae6d52f, 0x6c6c1d07, 0x814f5954, 0xeb8d4cfd, 0x8d8d93a4,
+ 0x6bd0e1f1, 0x3e28c62a, 0x5c06c7c8, 0x8508fa0c, 0xefefc907, 0x97bd69ba,
+ 0x94f7c90e, 0x752e758c, 0x41a2fac9, 0x07de37b6, 0x5c7bd630, 0x372b47d7,
+ 0x3b7591be, 0x7fd73f7d, 0x7e1b9e5f, 0xbc5dbadc, 0x6d96c5ee, 0x7d29925b,
+ 0x85dda1c7, 0x7b7d2d75, 0x1a48f45c, 0x326dcbe7, 0x75b3fdae, 0x23e13e4f,
+ 0xe3777a7e, 0x0fe87693, 0x9dbf5695, 0x6679cddf, 0x0ef11da3, 0xc8dd6fd7,
+ 0x2d6c17df, 0x71807b61, 0x1194eecf, 0xa3c3ad97, 0xc1b2ac62, 0xde3ceb45,
+ 0x1585ca5f, 0xa69e32e1, 0x46f51d48, 0x55b5d602, 0xa6bac7c9, 0xe3b76f17,
+ 0xf58781fd, 0xa6fba17a, 0xa2b4f0fd, 0x357bb01e, 0xd4c71c29, 0x11993edd,
+ 0x64fbcfe8, 0x4e34e5da, 0xc81e5fa7, 0x8287de7a, 0x239c2fb4, 0xf5fa21b9,
+ 0xf5da5561, 0x4ef9559a, 0x30903d98, 0x5ec2f20d, 0x35456ef9, 0x0a23439d,
+ 0x710bb7a0, 0xa3c5a535, 0xd79d1354, 0xf6984616, 0xb4112cc1, 0x9bbfa8af,
+ 0x7e532f45, 0x530cc4fa, 0x07d399fd, 0x0b9df886, 0x7f99cb3a, 0x8f7a6d5d,
+ 0x9f2efaa6, 0xc7bb615b, 0x4a77f358, 0xbb3a62ef, 0x5abed4d1, 0x47bd354c,
+ 0xf7a9e8b3, 0x6544ce18, 0x54e1c476, 0x6658f7e8, 0xeff54769, 0x169dfcad,
+ 0x7dafda62, 0x927f3c33, 0xfd8da5e7, 0x7d3d8609, 0xe8cf7e16, 0xef0cbcea,
+ 0xbc451788, 0x9a1dec30, 0x61691e59, 0x3c48553d, 0xa8f6eb54, 0x8f691cea,
+ 0xd8b5f6aa, 0xf04d8f11, 0x4810a6b7, 0xb6151a6a, 0x477d5237, 0xdfcc9c4a,
+ 0xcc3bef85, 0xdfd052f7, 0x521f9465, 0x42bfb04b, 0xdd686bcb, 0x606a1738,
+ 0xd83b6247, 0x076c9384, 0xfbd1c633, 0xf434e837, 0xfed0807d, 0x33700c06,
+ 0xbadcaeff, 0x822f60fd, 0xd8e2b4cf, 0x549dc47c, 0x95b14d35, 0x6f495ee4,
+ 0x54bfff06, 0x7ebf6161, 0x4c03e1fb, 0x5615ed6f, 0xff4b8c8f, 0x78d4b876,
+ 0x9435dda5, 0xbad0170e, 0xb05e7fe0, 0x15f8f143, 0xe9f00f59, 0x810cfa05,
+ 0x70174a4f, 0x01d5e033, 0x7e7290bf, 0xe2286e3f, 0x0a7be426, 0x1425c057,
+ 0x0b38fa9e, 0x2772c134, 0xf3cfcbcd, 0x8c57e90a, 0xb78fdd08, 0xb0ffd9db,
+ 0xe52e1141, 0xf531e1bb, 0xf4e3b4b2, 0x6feb90cd, 0x2078a9db, 0xd97cdfbf,
+ 0xe83bdfca, 0xd9c658a7, 0xde689f4f, 0x54f41daf, 0x8ccff72c, 0xeedc89cb,
+ 0xdf5745df, 0xff864f45, 0xdd7e3426, 0x19e647b8, 0x1ab7dfa0, 0xf37d8626,
+ 0x1be1c44f, 0xe77741f2, 0xe439c74c, 0x9910f1d2, 0xbcf9e5de, 0xe39d2a34,
+ 0xbedd35cc, 0x4d69f068, 0x5b8c676f, 0x78eee542, 0x7e6f7bd0, 0x43557167,
+ 0xfbf06a46, 0x1b4ada37, 0x975381db, 0xe25a73c7, 0x7ce22574, 0xdf2e5929,
+ 0x4f763969, 0x29f844cf, 0x25b4ad8e, 0x8faea44c, 0x553439dd, 0x88be420c,
+ 0x86d74fd3, 0xcfb60acd, 0x032de91b, 0x9c61f9e4, 0x872de7ef, 0x3f6167a3,
+ 0x8d19dcae, 0x2bc5a190, 0xa2ee1fdf, 0xa2d9be73, 0xfec01a2d, 0xce7c8de0,
+ 0x3cc6d70b, 0x390ce7d8, 0x516572a3, 0x5503c84f, 0x04f038ff, 0xb96d01e4,
+ 0xea72112d, 0x81540fe9, 0xe73a1ad0, 0xe538be58, 0x6a7df494, 0xabdf0473,
+ 0x2f08a53c, 0xd48b51fc, 0xd32e797d, 0x337cdb79, 0xd2708fc6, 0xae30c3b8,
+ 0xc6124b7f, 0x30b2f8f5, 0x333cb6ae, 0x8bbb2ba6, 0x97aed691, 0xc316dff2,
+ 0xa3dbacce, 0x0f23f721, 0x4b645fb9, 0xc8791fb9, 0xf72148fd, 0xfc0d7be3,
+ 0xd71bf00e, 0x6f43e5b7, 0x39158df5, 0x8e1cf84b, 0x7f5c81cc, 0x01ee12bb,
+ 0xf15dba3f, 0x8478e4f4, 0xf9e5620f, 0x2357821b, 0xb246dd1d, 0x5edd1059,
+ 0x8221d977, 0x88c6ebe3, 0x9c7e5358, 0xbf54d923, 0x2a6695c8, 0xbfa93ebf,
+ 0x7706fca9, 0x537f29be, 0xfd5348ce, 0xa6319e49, 0xdc468ffc, 0xc53faa60,
+ 0x9f94c53b, 0xa9b66136, 0x12e28cfe, 0x59ccf953, 0xb3e54c8b, 0xf94cdbb5,
+ 0x34ee2b5b, 0x92f1ffd5, 0xaf72a6e5, 0x0e715970, 0x231f4336, 0x3e85efb8,
+ 0x6fede946, 0xe3064667, 0x4b38d475, 0x350cef97, 0x56fa900d, 0x39f7ae74,
+ 0x09ee25d0, 0xe8fb0e81, 0xe2f680f7, 0xbf06199c, 0xfa914065, 0xe8324b70,
+ 0x685eb426, 0xfd88a8f9, 0x6594f097, 0x9f6ee7ff, 0x313e2561, 0x43fdaaea,
+ 0xfb7f2832, 0x5619e6c0, 0xaea32fe2, 0x3a52ffd9, 0xdcf17fe5, 0xf07cb237,
+ 0x57284bfe, 0xfccbf772, 0xc822c134, 0x9bce06af, 0x8c75a3e1, 0x8d7d2eba,
+ 0xba53da47, 0x5235538c, 0x9d7101c0, 0x00d20380, 0xfdd227d1, 0x5f489f44,
+ 0xb72cfa27, 0xe8907109, 0xd221e913, 0xf7fdf14b, 0x3d2297a4, 0xd2297a4c,
+ 0x452f4877, 0x297a42da, 0xcdd43fd2, 0x3a83f4e2, 0xb1fddb8d, 0x8fd382ae,
+ 0xf7f096ea, 0x7196ea4f, 0x1f3a97fa, 0x8064ff7f, 0xb0087f61, 0x8bf0c69d,
+ 0x091fc0d5, 0xdb2ede7b, 0xb1bf60b9, 0xabe795e2, 0x5facc7e1, 0xb0235a22,
+ 0xb1ad5b4f, 0xfe9d1c27, 0xadf9eec9, 0x92089c55, 0xdee19ccb, 0xf8f006cf,
+ 0xb7cc5dbd, 0xc447eff5, 0x84053eb4, 0xb5d34fa7, 0x3307e0b3, 0xc656ca0a,
+ 0xeeb8ff10, 0xd03625eb, 0xae9687cb, 0xd5efa3ef, 0x03a7dbf9, 0xf7e86dbd,
+ 0xa65dfd5a, 0xae321d6b, 0x6b6b5af0, 0xbfdbdb3d, 0x03c46e14, 0xefec33ed,
+ 0x5ef958f7, 0xe085f2b1, 0xc104e8fc, 0x5b2ffaf9, 0x5af10e38, 0xcf892797,
+ 0xc46f3d1d, 0xfdf87505, 0xef1413f1, 0x8de1f863, 0x2fc29f78, 0x3e41c75a,
+ 0x77691d18, 0x0dc48587, 0x2fbedfc0, 0xbcc68fea, 0xc3277df8, 0x97d4ffbf,
+ 0xf2f78022, 0xb5fe3f0c, 0xd834968e, 0xe1df4615, 0x33c704f0, 0xe57afe19,
+ 0xe715168b, 0x64af1189, 0x3bcc638c, 0x15fd4aca, 0x5d23c674, 0x47ca6aeb,
+ 0x757d465c, 0x93d7f724, 0x49dde3be, 0xb955e7aa, 0xec3e535d, 0x22aba3c7,
+ 0x8ce9423d, 0xafa9e813, 0x3af1ea9b, 0x38d0bf0b, 0x1eb4624e, 0x1c7e8127,
+ 0x01df9cb2, 0x48109d1c, 0xa39ffbc6, 0xb03dd897, 0xb88e3e83, 0xb8ce82b3,
+ 0x088fd405, 0x2798c7da, 0x15f7edfa, 0xbcf217cd, 0x9df0cbd7, 0x29f492e6,
+ 0x3f5e7adc, 0x2c6385af, 0x3d54bbdb, 0xfae61c5f, 0xcfd1046b, 0x90da19ad,
+ 0x1fdfd481, 0x7ccc8c94, 0x7a3217d6, 0x094fdf60, 0x0bb04779, 0xf03119fa,
+ 0xbc7e84ff, 0x05bdef12, 0xe942e1db, 0x418fc0c8, 0xbbde064f, 0x0e832ba3,
+ 0x18d0e282, 0x65711def, 0xf4a17f7a, 0x199d1dd6, 0x43ad75f4, 0x8cf001d2,
+ 0xae8320f8, 0xf89a2f94, 0x2ae8eb1e, 0x067f9f07, 0xc5d2855d, 0xe9257495,
+ 0x0e27feb4, 0xba4aefee, 0xc007a4ea, 0x55d387e5, 0xf8f38a8b, 0x79a7a59f,
+ 0xee3c626d, 0x765c97ff, 0xabda441f, 0x7c17b69f, 0x198c4ca6, 0x2e13120f,
+ 0x62ec1075, 0xba32f5a1, 0x7f4a17a9, 0xbc6eeda1, 0x6e465da2, 0xfa71bb70,
+ 0xaeda1959, 0x047aed12, 0x71c21bb7, 0xf7e96f11, 0x1a72de08, 0x999e2d71,
+ 0xb90e5390, 0x2f2df26d, 0x27cc8de1, 0xf3a719ba, 0x096243f3, 0xee24bf9f,
+ 0x854f40fa, 0xcb8d693a, 0x42fac85d, 0x71d76461, 0xedea3705, 0xdc5d7fc7,
+ 0x4f8cf980, 0x37e3cb30, 0xf5fcf2ea, 0x0ffb91a2, 0xc6e1477d, 0xce59ebdc,
+ 0x61477d0f, 0xfe3d40f3, 0x81a44d20, 0x8f0a17df, 0x0efe9f9c, 0xcfbea146,
+ 0xc9ba7453, 0x5462ab70, 0x6a9bee1c, 0xaf321c56, 0x3c8c1de3, 0xfce3eb8c,
+ 0xe9cfc20d, 0xfdc0224d, 0x0903a24c, 0x61091ff9, 0xc85fef93, 0xaa35bafb,
+ 0x5790dff6, 0x4fba7b8d, 0xb057b53b, 0x4c440fcf, 0x4a77839e, 0xd7190dc6,
+ 0x17f6ed0f, 0xdbce59ba, 0xb960c8ef, 0x16d2fb13, 0xde27c9d7, 0x5fba73a4,
+ 0x8a37bca6, 0xfb46f714, 0x3bfa79d1, 0xbf91c73a, 0x40b96731, 0x736ef1bb,
+ 0xfed193bc, 0x6138d726, 0x9cfeef8d, 0x776f29bc, 0xdecdd86f, 0x042ecd8a,
+ 0xbd8adf7e, 0x7deb10aa, 0x45a7b62b, 0x4e7661a6, 0xafd2bd07, 0xa0d8b92b,
+ 0xc6f1cefb, 0xc1dd78f3, 0x286b80d9, 0xff380d3c, 0xeb1eb800, 0x077bae0a,
+ 0xaa379608, 0xad5f2423, 0xd57c908e, 0x58757380, 0x9ede7dc7, 0x5527f1c1,
+ 0xf9af090e, 0x5611aecb, 0x2c17f512, 0x93f9c91b, 0xb807c275, 0x6092c69f,
+ 0xf7b10f10, 0xce58eb09, 0x9ddcef1b, 0xe8bdf87d, 0x2ae79a24, 0x983ff687,
+ 0x4082b9df, 0xe2844916, 0xbe7a86e4, 0x05fe7f8f, 0xaa7d03d5, 0xf1af754a,
+ 0x96facec0, 0x7d71ef2a, 0xfe15207d, 0xd754f158, 0x0e55e8f1, 0x9f435f09,
+ 0x98afd21c, 0x5fb1adf7, 0x80befe85, 0x0ef55f21, 0xc6dcf193, 0xe4eef73d,
+ 0x92e1e1ad, 0x930ef5af, 0xebc0d8fc, 0xee7ebb06, 0x89c33f53, 0x3afca68f,
+ 0x98abf59c, 0x2e4c6f58, 0xc28583ec, 0x76189fa4, 0xf904f695, 0x22b5ca7e,
+ 0x945191eb, 0x13643c2f, 0x076f2a7e, 0x92794043, 0x1fb6b3f4, 0xef82a4ba,
+ 0xfc294517, 0x6f71863e, 0x22c92c29, 0xc27c41dc, 0xbd370ee9, 0x13911b4b,
+ 0x7947ca67, 0xc7ea997a, 0x9537488c, 0x98077ac7, 0x1427e3ca, 0x8a3df298,
+ 0xefd536af, 0x29ac6b39, 0x68ddac9f, 0x31529faa, 0xf83794d5, 0x24fc8a58,
+ 0xc5b92cfa, 0xb2efbed4, 0x34fd5352, 0x5ca9a55f, 0x319b3bc5, 0x25b7ab40,
+ 0x81cf1127, 0xd58c9fca, 0xe3de434b, 0xf0cb08b5, 0xfe6b77ce, 0xcbde5a33,
+ 0x80b91099, 0x6cc9afdf, 0x9e7999fc, 0x2c6b44ea, 0xcdbbd7a5, 0xc928b17c,
+ 0xb9171f9c, 0x71df814f, 0x9fcccb9c, 0x4d589653, 0xeae51ff9, 0xe44f34fc,
+ 0xbbe3ddb1, 0x300daff0, 0x4e143fe1, 0x7efc0f44, 0xef9d3b68, 0xcdebcc3e,
+ 0x070f7e32, 0x75e0937e, 0x0c126fc0, 0x824df807, 0x049bf0f3, 0x24df87d7,
+ 0x937e1cb8, 0x8721f2e0, 0xd61ff8cc, 0x55ffc662, 0x6ff1991f, 0x787765d0,
+ 0xa66ad91a, 0x9a29a10f, 0xba782df2, 0x7e9994e6, 0x1d73f142, 0x09b15b89,
+ 0x09e287c0, 0xbe387fb8, 0x8be08656, 0x37f7c3f0, 0x31477bdb, 0xd7d71e7e,
+ 0x20606d75, 0x3a2e97df, 0x6fbc0aa4, 0x71f3ac63, 0x6d3fdcfd, 0x89731ad5,
+ 0x5dcefccf, 0x763e0490, 0xdb7e909d, 0x4f1655f1, 0x207fba80, 0x29d99c64,
+ 0x3fa843da, 0xaa52fe2b, 0x26d2741d, 0x0e7bcfdf, 0x95d8797c, 0x123eb2f1,
+ 0xf6bef84f, 0x27be54cf, 0xa8d2c475, 0x8eaf8f80, 0x9f009ed1, 0x84bb9799,
+ 0x8a249bd7, 0x5c402fb7, 0xa5857fd4, 0xafb73f22, 0x722dc7bc, 0x89fef95b,
+ 0xa6e727c1, 0x2da9b8c8, 0xdd7fbab9, 0x9ea7e323, 0x777295c9, 0x71c5c794,
+ 0xf2b925de, 0x8ba90d7e, 0x010773a9, 0xd99d873e, 0x0b3acf80, 0x8ad9ebbf,
+ 0x9d09e47b, 0x0f21c8f7, 0xa3ecfe43, 0x1ff57fcb, 0x47581c3b, 0x3a617af6,
+ 0x1dfbfb7f, 0x81e2f8a6, 0xfca65d5b, 0x5324a6a0, 0xdcbbc1fd, 0x40fcf2a6,
+ 0xc87ca98e, 0x3f298f21, 0xa98465ac, 0x791f55fe, 0xad91f94d, 0xaff54c13,
+ 0xca6c5539, 0x47b688a7, 0x8abedf01, 0xcd1c53b4, 0xb9fa974d, 0xe4dc705b,
+ 0xe563bbdc, 0x7edd5f7d, 0x46fbc861, 0xd3a6b9dc, 0xd11ea875, 0xe8e52ed7,
+ 0xf52164fa, 0x1fae8746, 0xa13eb30a, 0x1de371e9, 0xe67c58f7, 0x5e2371b8,
+ 0xd0ef43bc, 0x7b8e8af5, 0xe2f19d34, 0xf178e0de, 0xbf5d61b9, 0xc75e7d1f,
+ 0xfbfce87b, 0xeb7ae5da, 0xbdf3b4ef, 0xa15e631d, 0x96c949f3, 0xd1d9bb74,
+ 0xbfaabdf5, 0x46fb4ae5, 0x25f1666b, 0x3613fdd0, 0x6dff2b4f, 0xf3c62b84,
+ 0xb75e22b4, 0xcf7617fe, 0x8f77f70a, 0x5cb07737, 0x658b1ccf, 0x8e5c94de,
+ 0xddfd338b, 0x92418884, 0x7583adbe, 0x78c84afb, 0xdc646373, 0xbbb1889a,
+ 0x8fddbf41, 0x6499e127, 0xff7c0d17, 0xf167bf4b, 0xf74d35e3, 0xbd8e68a1,
+ 0xce3f7f51, 0x4c3d036f, 0x59f24b1c, 0x5b13c93e, 0x49143d7a, 0xcb13ca72,
+ 0x8a9f6cac, 0x3757fe7b, 0xde75fafb, 0xfa4be99f, 0xb203e810, 0x07a8f40e,
+ 0xb72954f2, 0x2beb920c, 0xb8eebf52, 0x187ec0e7, 0x43f3f421, 0x174fbc70,
+ 0x6874c6f4, 0x75dfe3ac, 0xdba0c1ef, 0xfa193850, 0x3be3d0af, 0xd2f319fb,
+ 0x07ec67e1, 0xfdc67e03, 0xb66df713, 0x7c914de2, 0xe202658f, 0x6dfc0ce5,
+ 0xc6f693c9, 0x503c3a05, 0xbba8fc0f, 0x6e6a457a, 0xedf7ec0c, 0xeae31dc2,
+ 0xea3b0e82, 0x62e09bff, 0xfbbbbfc0, 0x87f1dd6d, 0x5df0be50, 0xa3baddf7,
+ 0xdef67fd3, 0x909f105b, 0x5e3a4bf1, 0x1c2cfdfc, 0x94777017, 0x323f3f79,
+ 0x9189f248, 0xe4fdf483, 0xccd6fd23, 0x0ffc042f, 0x9d552bf5, 0xbcf3c85f,
+ 0xdf98ad24, 0x8af9c6af, 0x37f35bfb, 0x8847f94a, 0x87abc4e2, 0xe36f8fc2,
+ 0x7ad7cbfb, 0x4a6ddb05, 0xde3f151b, 0x75f12af9, 0x9fb30fad, 0x0772cdcf,
+ 0x26c83bbf, 0x46576a4d, 0x5da5f6ed, 0xc2facef9, 0x60eef948, 0x0beafbe8,
+ 0x2f19bd75, 0x86df606a, 0x19eebdfa, 0x3cb1fba4, 0x9cf2c3c2, 0xa150d71e,
+ 0x37a0e9d7, 0x0e6f7cbf, 0x31f6327a, 0x671f1ca5, 0x3f0dcdc0, 0x3cce90d4,
+ 0x073c37c1, 0xb58379e7, 0x0ec5f8cb, 0xab7e1af8, 0x61ecbf0e, 0x1a1127be,
+ 0x77ce718f, 0x3f2bba20, 0xeb1fe198, 0xf8741f6e, 0xefc3bec7, 0x89691ed6,
+ 0x69f1dfc6, 0x67df26df, 0xfd5bf4e9, 0x22cbb865, 0xf03153fd, 0xfdeab53f,
+ 0x5d798d89, 0x96d50fdd, 0x9438e4ef, 0x73b68b66, 0x2cefad10, 0x7b778ff5,
+ 0x9fdc89ef, 0x26117788, 0x2ba976ea, 0xcdcbadd7, 0x8fe914a3, 0xef8ca9f6,
+ 0x5ef209f6, 0x8151f13d, 0x4fc4677d, 0x0481114c, 0x4a1f86a4, 0xe1923d5b,
+ 0x4aa1f86f, 0x9e792302, 0xda17ea33, 0xeb68e4f0, 0x851577a3, 0x53fd3bbb,
+ 0x5c647dad, 0xaa7e7754, 0xb9f39769, 0xaf97e9bf, 0x183e7ee1, 0xb6e52694,
+ 0x036efb86, 0x2ad80d9d, 0xab67586c, 0x4bbfebad, 0xabf3a851, 0x3d9ae812,
+ 0x96ade282, 0x962fbc2b, 0xbf88c22a, 0xe46f3e62, 0xf9ea352f, 0x7dbf9922,
+ 0xeab7cca5, 0xd16da7ef, 0x275820ed, 0x7a07ac52, 0x4edd36f9, 0xc5207582,
+ 0x7c1df03a, 0x35f0790d, 0x90d7c1e4, 0x0a435f07, 0xa5ef86be, 0x761538a2,
+ 0x0ad3f85b, 0xfc07f683, 0x72418569, 0xc169fc13, 0x82d3f879, 0x169fc3eb,
+ 0x5a7f0e5c, 0x69fc3970, 0xd3f879c1, 0x9fc3eb82, 0x3f879c16, 0xfc3eb82d,
+ 0xf879c169, 0xc3eb82d3, 0x0e5c169f, 0x39705a7f, 0x79c169fc, 0xeb82d3f8,
+ 0x5c169fc3, 0x62996f3e, 0xd3cdb7f2, 0x5b287fdf, 0x51f4cf1f, 0x9b1c5198,
+ 0xeffdf847, 0xc4fc7f88, 0x373c0e96, 0x2edd022f, 0x48f70ead, 0x904e373c,
+ 0x8908b778, 0x8cd9b6e7, 0x32ecbbe7, 0xb4e3245f, 0x7e07e943, 0xf49b42ab,
+ 0xdf85215b, 0x56fc290a, 0x2ab7e148, 0x2b7e94cc, 0xe15bf0a4, 0x4856fc3b,
+ 0x0a42b7e1, 0xf85215bf, 0x6fc290ad, 0x2b7e1485, 0x0adf83b4, 0xf856fc29,
+ 0x5215bf0e, 0xfdf0adf8, 0xfe03cd08, 0x905e632b, 0xf499fbf3, 0x9343a252,
+ 0xe532ea5e, 0xd707e721, 0x5c1f9c87, 0xb83f390e, 0x707e721c, 0x707e721e,
+ 0xc1f9c87d, 0xdc8349f9, 0xef20bfbc, 0xbc83b707, 0xd41f9c1f, 0xb6037be8,
+ 0x2e1b49ab, 0x35b48ebc, 0x7142794a, 0x2f353109, 0x8bfc2673, 0x35254ead,
+ 0x6d8423d6, 0x859980f9, 0x38f4d794, 0x66d13cc7, 0xae39be01, 0x05a6f080,
+ 0x0f65c704, 0x5cc97ffa, 0xf9b3f86e, 0xbf9ef087, 0x50deb043, 0x35afdfa3,
+ 0x4b847bda, 0xefd46a45, 0x2f5d77cc, 0x1ea37c74, 0x79a0cbf3, 0x8f996290,
+ 0xbbfc9378, 0xaf700b22, 0x91458b60, 0x642bb8f1, 0x5d28743c, 0xe793caad,
+ 0xf6cb16fb, 0x5388e1fd, 0xb83c5129, 0x156591ef, 0x80056c87, 0x7e0292d3,
+ 0x562f2af7, 0xab92d75f, 0xcc658711, 0x124bb0db, 0x867be09f, 0xbd84daa3,
+ 0xfd19c69c, 0xefe3b085, 0x4bb44c73, 0xa0ed0279, 0x29f40e6f, 0xf4414dde,
+ 0x9e4f2cbd, 0xb6ef9a7b, 0xfbe9cbab, 0xae4b6dc0, 0x89c5fdc6, 0xd3ddb2e1,
+ 0x386689bf, 0xf8506e4e, 0x6da8ce9e, 0xc9fb8bc2, 0x3a7e75cb, 0x5ecb9b70,
+ 0xf8bae3ce, 0x6fd1a3de, 0xbe5486c9, 0x5a2259a7, 0x450f710b, 0x3df8550c,
+ 0xb46e037c, 0xbeb1d7be, 0xb02ada2c, 0xfbe0ff2f, 0x7e2e244f, 0xa34ffb9f,
+ 0x2116c687, 0xcb3450ae, 0x0d2742f7, 0x83d9592d, 0xe5f9a5e6, 0xbfa3a17b,
+ 0xe706f258, 0x85ef929f, 0xe70cf932, 0x9879f1f9, 0xfdf853ed, 0x8dbec995,
+ 0xee370496, 0x25b72f65, 0xe136fea2, 0xf5055881, 0x8d8af708, 0x168ae575,
+ 0xbd01538b, 0x41f10388, 0x639c47f4, 0xdf25e83a, 0x59f7e363, 0x365d58a6,
+ 0xce431bf0, 0xb1c97129, 0x3151d48b, 0x4432cf7c, 0xd0d4b84e, 0x7e62e383,
+ 0x3b4e9c78, 0xba5fe7df, 0x8572c9d3, 0xbe615eb6, 0xc65f3e79, 0xf6dd56bb,
+ 0x7a4b70e1, 0x99ce9c67, 0xbc16ff34, 0x7d267b03, 0x8508f47b, 0x79bd88e5,
+ 0x0da3d704, 0xcd3df12f, 0xf06f9592, 0x0d4b943d, 0xfbcb450f, 0x52ffd26c,
+ 0xb0cdc3ae, 0xf1d7cd3b, 0x69c7ae53, 0xef93ab1d, 0xcc39d33a, 0x6a5caeef,
+ 0x119cb1b0, 0xf21a2f2a, 0x911ef1a7, 0xc23fae10, 0x60d153ce, 0x0bc03be3,
+ 0x4aac94d7, 0x91ca5712, 0x7339758b, 0xe38d8351, 0xf7f42ab2, 0x6eff42d4,
+ 0x1e3d62cf, 0xf356f16b, 0x42f24ff7, 0x7de350e4, 0xc94ebd4d, 0xb06607db,
+ 0xc6c4b43c, 0xcb39cdfe, 0xb6247ca5, 0x93ee3f0b, 0xce3e59cc, 0xe666f782,
+ 0x947af4ec, 0x5de9e82e, 0xd89a4e5d, 0x4ff864ea, 0xfcc11cb9, 0x14e5ea65,
+ 0x397cdfce, 0x9799d399, 0xee2adc65, 0x5a6e8122, 0x073be48b, 0xd1f2ebef,
+ 0xc6b1c40c, 0xc9eb3e43, 0xf44eddf4, 0x74f2218d, 0xabc035be, 0x3878801c,
+ 0x44ada6d1, 0x8dc4ec9c, 0x4d83ef82, 0xfd451c82, 0x155c82cf, 0x5691fd8f,
+ 0x2661f7c4, 0x68bf7c28, 0xf4dbd0d2, 0x43fb40fd, 0xf7e13f30, 0x29c2b457,
+ 0xcd39c47e, 0x805bb6d2, 0x685f637f, 0x5efca3be, 0x629f24ea, 0x9a923bc7,
+ 0x741b6fae, 0xe63fba1f, 0xb276e846, 0xeb076948, 0xb26193b0, 0xb7c92478,
+ 0xd3e4266a, 0xf66db0b9, 0x608109d2, 0xcb2b951f, 0xd576fc7b, 0x419206cc,
+ 0xc9fb55ff, 0xde458b1c, 0x9039233f, 0x96880bef, 0x2f949ea2, 0x4014a359,
+ 0xf5e6323f, 0x38ec67b9, 0x3a4eb0cf, 0xa7d8ed28, 0xd2e51ef2, 0x7e4d327b,
+ 0x8cb4d09b, 0x34fd8de0, 0x27f5a637, 0xf468610a, 0x1c2de160, 0x85ebf781,
+ 0x005428f1, 0xe8b798f1, 0x3bc1eaf9, 0x973ab4ff, 0x91f9c4e1, 0xa6687dbf,
+ 0xe05ff22f, 0x6b147393, 0x4b1bdff0, 0x0d5768b2, 0x50f7c1ee, 0x11bf03c7,
+ 0x9efc6db9, 0x4bb64a44, 0x7b10a9f2, 0x8960f54b, 0x4bbb50c7, 0x773cae59,
+ 0x7a9dd584, 0xdc7bfb2b, 0xd634b76c, 0xbe66cc7d, 0xf3a46be7, 0x5ee7eb07,
+ 0x9ee7bfdd, 0xf916c3ca, 0x1663c2fe, 0x8857f6ff, 0xd0f72f5e, 0x8fbd6066,
+ 0xe79ede21, 0x8cfaf1af, 0xf83a4cf7, 0x896efe95, 0x96474f41, 0x2afbe25d,
+ 0xb77691a5, 0xe54f441a, 0x0fbe15ab, 0xde4cba5a, 0x2b56d6e7, 0x6e845df2,
+ 0x99bf58ec, 0x9efcbffd, 0x117e6fd5, 0xf8750b2e, 0xbcb7b1ce, 0x84eb48e1,
+ 0x3d979fef, 0x347c9360, 0x0efb8990, 0xf2712cb7, 0x7b9fd9bb, 0x0f06ab8a,
+ 0x8c3c9e03, 0xe5d871a7, 0x8c4b7f54, 0x4bdf04b6, 0xd841cb45, 0xfcfee71d,
+ 0xba8f7e6d, 0xdf8d39b6, 0x95d92cbf, 0xd9ef0abf, 0x7ed1ee7c, 0x4497f582,
+ 0x4790ecba, 0xf9621a6a, 0x53db9e7c, 0xda2bcfbf, 0xe067cfd8, 0xd2c1bee7,
+ 0xbe7d778e, 0xaea2e71c, 0x6cc01157, 0xbaf54c53, 0xf61a63b6, 0x4b3b50d1,
+ 0xdf21bbe8, 0xdd815765, 0x5f641ec4, 0xb632ec35, 0x71b3639c, 0x77b1cfae,
+ 0xf73ef7fd, 0xf437f3ea, 0x7a1df9da, 0x9ef8ee6d, 0x2ad7ff90, 0xcbd3d82e,
+ 0x7133dd23, 0x90fca1bf, 0x62b4910d, 0xbe5b9c62, 0x7c8f731f, 0x8ef4a63f,
+ 0x7367e67c, 0xdc029380, 0xfbc9193b, 0xe94fdcb8, 0xfbf7ee90, 0xf40f6bad,
+ 0x0a7a0dd9, 0x821df978, 0x1ed79772, 0x951f2417, 0x77a62a35, 0x0bfc8c24,
+ 0x97c95583, 0xfc00dd48, 0x9a477c7e, 0xcd396f1d, 0xf1093121, 0x27417b99,
+ 0x51db3ac3, 0x993f8e3d, 0xca0e2e98, 0xfe14bdf7, 0x2f18e4bb, 0x955beff8,
+ 0xc3df9a36, 0xdf2cfaa0, 0xc51c1aed, 0x68b895fd, 0x5d4869dd, 0x03824f3c,
+ 0x3eeda9c3, 0xe3cdcfea, 0x02ca3e30, 0x07ec1b7e, 0x42f71073, 0x7e5c5bf9,
+ 0x6d29c61b, 0x68d4ef90, 0xda38e46b, 0x20fb58ea, 0x975607c8, 0x5cb04fbd,
+ 0xbddf20d8, 0xddffa39e, 0xcb2f9a11, 0x2704e5cd, 0xee33b3dc, 0xabc286dd,
+ 0x797f9f44, 0xce59ac63, 0x036b5c6c, 0xf377667e, 0xdd39c65e, 0x30da5d0e,
+ 0x2837df86, 0xbef97ab7, 0xfbc3a68a, 0xf79cdbb3, 0x7b325fc2, 0x34b623dd,
+ 0xb065ffca, 0xe9cf6b94, 0x7a6271fb, 0xa9df9320, 0xf1c9cdba, 0x8d5db3e3,
+ 0x780edebc, 0x81f0443f, 0x662ae2dc, 0xf89d1378, 0xbe596f10, 0xcedf8cce,
+ 0x77c944f9, 0xf095d7fc, 0xd5605bfe, 0x79e0aeec, 0x8997dfac, 0xb4d9a1f8,
+ 0x970ef1ef, 0x1f7c6970, 0x3343c4f6, 0x6205eff9, 0xe6cf1c9e, 0xbbc78f71,
+ 0x4c374453, 0x18fd06d7, 0xf18df3f7, 0xb4ab1eac, 0x6bbe7bc7, 0x420f7a9f,
+ 0x7c27af4e, 0xddd00fc3, 0x02e3b53e, 0x2f6b8d26, 0x5e07ef97, 0xfdf4efc1,
+ 0x6a01fffa, 0x00d36c91, 0x0000d36c, 0x00088b1f, 0x00000000, 0x7dedff00,
+ 0x65555c7b, 0xd6bbf0ba, 0xc0d857da, 0x51b08b66, 0x62020dc0, 0x10106d11,
+ 0x80a17515, 0x636a735b, 0x8dc42937, 0x910150b7, 0xf39fa8ac, 0xa96f0db1,
+ 0x962a2695, 0x8da6b675, 0xb2707595, 0xd99b1b46, 0x0f5d9a6a, 0x39d38d3a,
+ 0x32cdb653, 0x34d209bb, 0x99d37d9f, 0xde79e7be, 0x0daf60b5, 0xf9a675a4,
+ 0x3efcefce, 0x7df5e3fc, 0xee7d7bd7, 0x765ef3cf, 0xb24c6322, 0x98783631,
+ 0x8c81b183, 0x45931819, 0x77a13fc8, 0x6302edfb, 0xbeac7195, 0x28d2132d,
+ 0x0b6bff56, 0xdfe3df63, 0xa2749ef8, 0x8f2c6453, 0x5da0dbb1, 0x10af7c1b,
+ 0xd6ccabd9, 0x29d33df3, 0x148af7d0, 0xd41dd336, 0x7ec3fb1e, 0x13efd5e3,
+ 0x338b69fc, 0xe3abea7b, 0xbb78d856, 0x9a7ed0a9, 0xdd8beb05, 0x3ea81bf5,
+ 0x26e9b3cf, 0x3632c591, 0x87ff04db, 0x7b4894a5, 0x32e6c456, 0x7057b0d6,
+ 0xe1a8a11a, 0x18b18941, 0xf08b9f48, 0xbec664b1, 0x3bcdf868, 0xcfbd40b7,
+ 0x64af6f37, 0x35e67b43, 0x398a3fc7, 0xf7363046, 0x0c733652, 0xa5de6c60,
+ 0x0f569431, 0x073864f3, 0xf8dbd506, 0xc607ba5c, 0xfb2dadbf, 0x5a307fdc,
+ 0x30e59fb7, 0xbf73fef6, 0xe868e3fd, 0xde9f3197, 0x3acf4d7d, 0xa13ead66,
+ 0xc304b2af, 0x4d73af8d, 0x83155746, 0x18b6ce79, 0xcd14121c, 0x64c55e5e,
+ 0x33b32798, 0x13e41a67, 0x422bcc75, 0x16fd6cbf, 0xf3eb04d9, 0xb557fe30,
+ 0x5da9905c, 0x824fbe63, 0x7a860cf5, 0xdf5e1cc6, 0x58f7f00c, 0x4884670c,
+ 0x912de8a8, 0xcdbc1903, 0xf83d29f7, 0x21a90c1d, 0x89ef07a7, 0x5ecc1d0a,
+ 0x7b6d0657, 0x330305f0, 0x65eb0f96, 0xfceaae1c, 0xbff32aa7, 0xfb20bd6d,
+ 0x4e0ddea0, 0x2757cf07, 0x7ac1e61b, 0x364face7, 0x5cb486cc, 0x473e5ef9,
+ 0x2f8dde5b, 0xccaf8aab, 0x4f587695, 0x57c71b57, 0xe13d3ad7, 0x2f4f6bab,
+ 0xa931257c, 0x00771e67, 0x8e00d8be, 0xe382362f, 0x57c0530b, 0xa82f33a5,
+ 0x7c70bfde, 0xedfe7ecd, 0xd0765e0f, 0xceffa8fa, 0x1dbe8d07, 0xb6acffd0,
+ 0xf2b784bd, 0xc9f41bd5, 0x99ceaf50, 0xdb51704c, 0xb6cfaecf, 0x6de78032,
+ 0x1debb7ab, 0xe8eefc16, 0x9521ee93, 0x413f1059, 0x6790099e, 0x3bbc40ba,
+ 0x397ea7a2, 0x9c617ba4, 0x91cd8b25, 0x719edaec, 0x3cf428b6, 0x86da3ebb,
+ 0xafaecde3, 0x7165887a, 0xf66777fa, 0x66b3bfe6, 0xa0b317ce, 0xb3cfe43f,
+ 0xe424ce45, 0xd4510a8b, 0x3e9a9bf0, 0x79837884, 0x35e0063d, 0xdbc3fe23,
+ 0x0c38469e, 0x6ce6145e, 0xa9a94f86, 0x8b8e1f01, 0x36f38cf4, 0x826bcc88,
+ 0x8135a97a, 0x548f388b, 0x876c28a0, 0x528d8469, 0x1df90b16, 0x4802ed30,
+ 0xee9e2453, 0xc3f5f273, 0x677e3f77, 0x5c3c8131, 0xa1cf4abf, 0x3b606af4,
+ 0xfe00a757, 0xd9cc310d, 0x4fa1e8ec, 0x3e951fb5, 0x6fedfa55, 0x70ae7b7d,
+ 0x3993677d, 0x3386593c, 0x56e304c9, 0xb9cc3c3e, 0x3afcb846, 0x0f00610d,
+ 0x817ad05b, 0x7d6c0b58, 0x903537ac, 0x0fcd7657, 0x24a5b7ad, 0x86f58fb6,
+ 0x93e553ae, 0xc3ce2639, 0x015127c0, 0xfad77798, 0xf10c51a1, 0xca2f302d,
+ 0xcd8bb39d, 0x5d5bce22, 0x504d53d7, 0xbbb6e619, 0x33e944c9, 0xc368c04d,
+ 0x764d3e00, 0xe4df3fca, 0x29adb4a0, 0x9ddbca83, 0x633f9a36, 0x80698881,
+ 0x85308aa7, 0x8f3cfdff, 0xe54165e5, 0xee9c6d53, 0x11035b4e, 0xfd3920b6,
+ 0x0d79bd71, 0x0efa428b, 0xccfc883c, 0x5db2871a, 0xf5e9d430, 0x4cc42367,
+ 0x3f3e4fa4, 0x7d12ddb5, 0x163fc927, 0x02ec7061, 0x24b19b96, 0xe02374fb,
+ 0x38f2ee6b, 0x9b129027, 0xe49438d1, 0xb46f0cc2, 0x7eb00093, 0xcc78430b,
+ 0xf860e453, 0x2395aa92, 0xb26b7eb1, 0xe6718055, 0x5ae79c5a, 0xced5fda9,
+ 0x4b7bf1fb, 0x93252199, 0x9026caaa, 0x72287763, 0xdcc0896c, 0xa07787c8,
+ 0x12fe449c, 0xfea2a50f, 0xf055a3b9, 0x56cf291b, 0x21d7000b, 0x78d2eecd,
+ 0x055b1394, 0xbb6c0ee7, 0xa9a9e40d, 0x0d769e47, 0x7a817f73, 0xf4077d81,
+ 0x255ffd07, 0x5d710220, 0xca1c726d, 0x75824df1, 0xb979c317, 0x059f080d,
+ 0x6e9c9d0a, 0xc8e11339, 0xa3eb81ec, 0x65105ff8, 0x288b23cc, 0x3d141b6f,
+ 0x79406486, 0x310e4e45, 0xca41f870, 0x3a3f11da, 0xa0e909a7, 0xc51292cb,
+ 0x886f28fa, 0xf2c38948, 0xc912ad39, 0xaa9e9545, 0x7c2835d5, 0xa3be1733,
+ 0x2a912bde, 0x56be9162, 0x74a44cb6, 0xcd9286ce, 0x24e3a05e, 0x9a3b1dc1,
+ 0xb867a3d6, 0x13b5399e, 0x55bc47af, 0x9b4630ef, 0x7a496f00, 0x104e526f,
+ 0xbed9ce3f, 0xbb41892a, 0xd3cddbf3, 0x5b17fe51, 0xa1a38acb, 0xd16dbcfd,
+ 0x1e9052d9, 0x7ae6ca49, 0xc4ed4164, 0xacf00638, 0x2791fbf9, 0xe78fa0ac,
+ 0xe8569f42, 0x70b69bff, 0xd4aa179f, 0x924fed34, 0x31dee780, 0xa1b3e279,
+ 0xe0f142fe, 0x1f50a32d, 0xe2a7be08, 0xce23bea9, 0x503c87da, 0x0fc073d3,
+ 0xdaf7a00e, 0xf51ef5ff, 0xd6f895f3, 0xbed0e5f5, 0x4885f6a6, 0xa6e167ec,
+ 0xa15be43f, 0x49e8a0fc, 0x173ffec3, 0x45653fb6, 0x9edd6c02, 0xee7c7a85,
+ 0x4f28b4a6, 0xf917f21f, 0xbd51f100, 0xaaf8205f, 0x517c33e5, 0xc7bb8406,
+ 0x4c560ccf, 0xf480ccad, 0x8d625e7e, 0xf6a80f68, 0x323e5a8c, 0xf3adcb9b,
+ 0x9093eb51, 0xb53fe64e, 0xccf50925, 0x5f3c1167, 0x6fadd4f1, 0xecf2dca0,
+ 0xaf101a34, 0x38331d1e, 0x41799f51, 0x551d22bf, 0x93c6ff03, 0x04ae61dd,
+ 0x0eca2a7a, 0x6fceb827, 0x51fa411d, 0xa77c179d, 0xcc74cff2, 0xd218f385,
+ 0x748d99dc, 0x7f9d67ff, 0xcff3e22e, 0x17a766f5, 0xf5cd99f1, 0x4bd79fdb,
+ 0x05ee58a5, 0xe47b4186, 0x885febcf, 0xd8f4b548, 0xfbd2256f, 0xd67684b2,
+ 0xea36428b, 0x76ccf0ed, 0x1bb22cc3, 0x9d59d118, 0xc359d395, 0xe0e97d01,
+ 0xa8c7b218, 0x37e746a4, 0x05af85f4, 0x9dd5bd8a, 0x80d7b7df, 0x87b3527c,
+ 0x6d3511db, 0x508ec867, 0x855a92ed, 0x39ee179f, 0xda857643, 0x871f6eae,
+ 0x5e3eed4b, 0xc801955e, 0x80e5cd1d, 0x0aba4200, 0xfbf905f1, 0xd3d7f5fe,
+ 0x7bf26997, 0xb5df7f29, 0x750f2e56, 0xb7a8499d, 0x349c64d6, 0x976bfe20,
+ 0x5e42fd2b, 0xbcde341f, 0x2f0481ec, 0xc16a1f2c, 0xfd8d0ef6, 0x9a2fbb50,
+ 0xc36bfbda, 0x97bea356, 0x4c3a2ceb, 0xa42d6b9b, 0x8bd5b7ff, 0x9c5cba19,
+ 0xed13985c, 0x916183b9, 0x07472859, 0x06653c2e, 0x3b6a0248, 0xbe50888f,
+ 0x2f73ca3a, 0x031c67d2, 0x6f5090ae, 0x5fb405f8, 0x74f95e3b, 0x6e3ff604,
+ 0x066be048, 0xbf0bd753, 0xf20c5e9b, 0x2d981964, 0x06671f64, 0x0f1d2046,
+ 0xf4e5cc3c, 0x1ab67ae3, 0xb9d31bf5, 0xf72834d9, 0x3c42dca3, 0xdbe61b7f,
+ 0x1dffff05, 0xfec60ff3, 0x143fc999, 0xd0a4bddb, 0x5968dba7, 0xaebcc02d,
+ 0x8359ea1e, 0xd041be4b, 0x222d935f, 0xac34a40e, 0xdfe7a1d7, 0x82757b55,
+ 0xc113a722, 0xc8bb408e, 0x416ec830, 0xf3366e3a, 0xccb209f5, 0xf71e611a,
+ 0x8d9e1e67, 0xa76d7a7a, 0x9d611989, 0xc8c33a13, 0xe41c4d7e, 0x6cd6bd22,
+ 0x2dbd224e, 0x02ac7438, 0x14ce1fea, 0xcfac3afd, 0xcfac3e4c, 0xae76214c,
+ 0x9db19668, 0x6fb5f070, 0x960fbe51, 0x82891e2e, 0x47be0df5, 0x9d433670,
+ 0x8f73aeca, 0x15a41bff, 0xfdec7697, 0x2dff4857, 0xe113b3ca, 0x75cbba7a,
+ 0x5ba803c6, 0x39336d6b, 0xc160deb9, 0xef7838eb, 0xb13691b7, 0x9d1d7e67,
+ 0x4dfb9ee7, 0x2726a62e, 0x07099fea, 0xa11fd225, 0xc3b0e9f3, 0x3d5287c4,
+ 0x2c3b3bb2, 0xb0104fa2, 0x70f791fe, 0x164c137e, 0xbaf684bf, 0xb065ff49,
+ 0xc48e617e, 0x935773e8, 0x83df614a, 0x938b1091, 0xd1747d47, 0x38eb7642,
+ 0x3a550f85, 0xdb9b2b7b, 0x72296f8f, 0x73338555, 0xaf582cc8, 0xd66cf0a8,
+ 0x1022faab, 0xf87b32ce, 0xaf529176, 0x932892eb, 0xf46d5e1d, 0xebb2e831,
+ 0x33d250e0, 0x3fd9c9fd, 0xf601dda0, 0xf954f2c4, 0x5327845d, 0x0acdeef4,
+ 0x2dfd54fc, 0xacdffd29, 0x8b66f1c0, 0x5376e1c8, 0x7a14dc08, 0x1e97a50a,
+ 0xdb41887a, 0xeccf1ba3, 0x51a3f6be, 0x6bdf84c9, 0xfd78e61e, 0xedfaf090,
+ 0xcd802b5b, 0x4dbfa0d8, 0x0cfefc21, 0xb98bf578, 0xedaf023f, 0x9bf578a1,
+ 0x375e2187, 0xa0676489, 0xa376881d, 0xb5c0e507, 0x60f6e794, 0x51392306,
+ 0xd7398529, 0x8077e324, 0x87c91643, 0x541f28a3, 0x15c430b9, 0xe9f506b8,
+ 0x71e57069, 0x8db1017e, 0x10a4e797, 0xf6b0245d, 0xbc072c78, 0x277da1e7,
+ 0x7e668699, 0xe5b7720c, 0xdfdedf01, 0x82cd3f40, 0x983ceb6f, 0x8b66f78f,
+ 0x0eb7ed13, 0xc3d5e89f, 0x59a25a3c, 0xbf187ed6, 0x4e55fe65, 0x4533962f,
+ 0xf8374c6e, 0xef837ed0, 0xbdf88d49, 0xe97f7f9c, 0x441f67ef, 0x8d33acfb,
+ 0xb25abad1, 0x67da3a59, 0xf419652d, 0xdcaab7fd, 0xb7823079, 0xddf4e32f,
+ 0x43e6df32, 0xa3e8f43d, 0x27a8e1be, 0xf1cbb65a, 0x510d4836, 0x981cf89e,
+ 0xd38920ff, 0x94324b7d, 0x7059ba43, 0x7ec5cf97, 0x0df3e1ae, 0xff3d8794,
+ 0x4e657414, 0xe506d105, 0x76231ba7, 0xe9555ca0, 0x2e30f074, 0xcf7887df,
+ 0x7938456c, 0x7a8cb027, 0x8543ffe8, 0x0bf854de, 0x008d36c0, 0x3c1098f7,
+ 0xa31774a8, 0xca585fc0, 0x413bcfe9, 0xf31d4f59, 0x0091bfa1, 0x38070953,
+ 0xf0c11a57, 0xd5967483, 0x6ff38d93, 0x91f80c5e, 0x0f1c1d70, 0xdd5645a7,
+ 0x155f07d6, 0x0df128e6, 0xa6f90218, 0xa9be7192, 0x7a42ba44, 0x0aba046c,
+ 0x481647a2, 0xae173e88, 0x83ca15d0, 0x1cb8f708, 0xc257e758, 0xf0b1f21f,
+ 0xa694ffad, 0xa4ce35f7, 0x1e2f2e1c, 0x734a7b33, 0xd04def48, 0x656f9dd8,
+ 0xfa889a7f, 0xafbdf4e5, 0x149a6025, 0xeb8c9ee5, 0xd7fe5cd8, 0x1fff1452,
+ 0xb8f407c6, 0xffcb0f8e, 0x2dda224f, 0x235f4b95, 0x79d2bffa, 0x37989996,
+ 0x5d1ee01c, 0x00fd382c, 0x462d79bf, 0x16f824e7, 0x0c755c57, 0x6ad659e1,
+ 0x56911874, 0x1c8d62d8, 0x408f2b3b, 0xda1d8a37, 0x39ba246a, 0xf4894bf7,
+ 0x8b92b9c1, 0x0f800eaf, 0x4e0856e7, 0x32d657ac, 0x3790256c, 0xa816292b,
+ 0xa057995e, 0x1ca9657a, 0x051a275f, 0xaf4037a2, 0xde283b25, 0x8ef5a731,
+ 0x13df88a9, 0xa40f5fc5, 0x187ac1f8, 0x2e63e547, 0x959e48de, 0x56abf529,
+ 0xbb47911b, 0xacb597bf, 0x3ffc88ba, 0xde521bd3, 0xec53e93a, 0x5b51acb7,
+ 0x8235c6ee, 0x4e57771d, 0x07ca0c44, 0xefce64e6, 0x40f24811, 0x93fa0ff2,
+ 0x447140bb, 0xc20f30cf, 0x61bc89c3, 0x99eba47a, 0xdba05708, 0xdd7ca5e8,
+ 0xbe0aa733, 0x99ceb049, 0x1f67ce16, 0xfbbe0996, 0x09ff3e05, 0x5065ef40,
+ 0x5d740b1e, 0x38e4c316, 0xe626dd48, 0x2e79c70f, 0xca09f61d, 0xd438d3db,
+ 0x8fefaa28, 0xf75ca1b4, 0xb78911e8, 0xe5a52f32, 0xede947cc, 0x98f34fcc,
+ 0x74933ac1, 0xfc93af90, 0xf38e312b, 0x0367b32b, 0x8b5fd7d2, 0xe0169c4e,
+ 0x4239ddfb, 0x439428de, 0xdd68038d, 0x701f5b97, 0x067680a5, 0x5fac41aa,
+ 0x147ee396, 0x4ccab3fb, 0x74ab718f, 0x995a8e95, 0x17d61537, 0x9be2debb,
+ 0x6b8beb04, 0xf5c21cf5, 0x38374fa6, 0x1383ef10, 0x74133af8, 0x543f9fdc,
+ 0x81a3606e, 0x183f360e, 0xdb3a43e6, 0xda2035bc, 0x03e6fea1, 0x97cc0180,
+ 0xf0bc14af, 0x4e61eadd, 0x7559d38c, 0xfeed111e, 0x188f56a2, 0xe1a7e208,
+ 0x394441b2, 0x23d3be91, 0x5ab49ea2, 0x353d53d7, 0x4fd4ac5f, 0x59067937,
+ 0x4e9e4ec9, 0xa15c33f4, 0xd49fb51f, 0x045f8356, 0x4ac917b8, 0x57b7997d,
+ 0x9e8a61fb, 0x3961db56, 0xab7a67d2, 0x453f4fa3, 0x3f505b4d, 0x08f88f83,
+ 0x7bd205c6, 0xfd711fca, 0x1bf084da, 0x36abf378, 0x2103374c, 0x9d1c71f8,
+ 0x79e34cc7, 0x15d33cf8, 0xbfbf87da, 0x63e38f7f, 0xb9bbf01e, 0xe422fef5,
+ 0x1f00cda3, 0x9de6f3c4, 0xcfd4ccb3, 0x799a59f4, 0xf286a931, 0x4b070825,
+ 0xa23c75ef, 0xd53d2fcc, 0xbd695a23, 0xe76843ce, 0xe28ccba5, 0x763f6a01,
+ 0xf405741d, 0x857a776a, 0x90cbcc7a, 0x47b8945a, 0x4eb38e3a, 0x5d31ff40,
+ 0x6b4957c1, 0xf63361fd, 0x5f1466e3, 0xfe85cf4c, 0x8426fea1, 0xfc37a183,
+ 0x5e99e742, 0x4273e7cc, 0xf18edfa9, 0xe76c7494, 0x74431158, 0xd5d7e7c5,
+ 0x1c6214ea, 0xa08fb197, 0x7e90c9fd, 0x0cb8c29e, 0x7e4ecfa4, 0xb42e4a6d,
+ 0x97d1fe7f, 0x52d0b476, 0x0fb33e0e, 0xf5ab56e5, 0x9c709be6, 0xff9f2283,
+ 0x5de2724d, 0x206ddf98, 0x53be9a3d, 0x7944db4e, 0xebfd1393, 0x55df56ae,
+ 0x2cbd422f, 0xeb64c618, 0x0a138f3d, 0x3a15da9c, 0xcb793938, 0x53ef5c20,
+ 0x582c7745, 0x5f87ed02, 0x3b8d38f7, 0x94fcca7c, 0x9b0fc816, 0x30abcbf8,
+ 0xc78e5f7f, 0xfee4023c, 0xde5fd2b0, 0x6ae50fb6, 0x821cfce9, 0x4576c597,
+ 0xda39a9f2, 0xbf02f5e3, 0x52dc4737, 0xd2b8fc8e, 0x24487066, 0xfa19eb77,
+ 0x7711cd59, 0xe5bfb1db, 0x4c26f9d1, 0x36bfd60d, 0x6e3c9ca1, 0x1e2131c9,
+ 0x18132d9a, 0x0aaceb96, 0x4f1bbe9e, 0x885240fa, 0x73847772, 0xe5744cba,
+ 0x0c272864, 0xbcad0609, 0x2f7971d6, 0xb43e1dd9, 0xf5acba9f, 0x60cc8148,
+ 0x7ca05409, 0x69795493, 0x3c717a71, 0xa3b4e2c9, 0x9142b4bf, 0xaf862c37,
+ 0xf73960d3, 0x5eaf389f, 0x962e63fd, 0x867f4b50, 0x4128ccb0, 0x9bda3ff9,
+ 0x573e10c6, 0xbbc58353, 0x6844f518, 0x70205d7f, 0x4fa38e50, 0x7e337647,
+ 0x5eddee48, 0x7a341bb2, 0x7a5e5ba4, 0xf221f5a2, 0x7a811e52, 0x792058a2,
+ 0x0ceb61e9, 0x0c12feb8, 0x3c5c00b2, 0x545eb8db, 0xce267bf9, 0x49e5f005,
+ 0x5e5c9165, 0x2673e4e9, 0xd1efc60e, 0x452a5cae, 0x5e021e22, 0xc3e9e0c9,
+ 0x9378f79f, 0x9d1e507f, 0xa987fa41, 0x21fe9007, 0x0fe144fd, 0x6f078a8f,
+ 0x50a3f5d9, 0xd912cb5f, 0x85cb9503, 0xe2cfb436, 0x6947d1bc, 0x2edcc5be,
+ 0xa6bf9768, 0x892a1cf5, 0x7979444b, 0xc799d962, 0xbebd41ef, 0xfff49c29,
+ 0x5667a5a4, 0xa66e3c60, 0x211a7057, 0x7d1a59ef, 0x6f987bf7, 0x905d3a34,
+ 0x81f0ab3f, 0x914597fb, 0xb8084f68, 0x759e8cce, 0x83321656, 0xf139e29b,
+ 0x3b409633, 0x34e0a34f, 0xa1e07a3b, 0xef527ac7, 0x37bc05f5, 0xfad0fe46,
+ 0xa8d7bc3f, 0x3e7759c8, 0xc6a2d9ca, 0x700a87e4, 0x7cf5eb5d, 0xd7d18d9e,
+ 0x3927de53, 0x1cb97639, 0x3fd8a99e, 0x57b3a59e, 0xc0f7c3c6, 0xcef9416a,
+ 0xc8a956f1, 0x88e340e5, 0x0d3f1863, 0x3e48172c, 0xa252bc79, 0x5ccdda1f,
+ 0xef784d9e, 0x5d900a28, 0xb43de5d8, 0x722b5a92, 0x3674a3de, 0x94588c17,
+ 0xe3dfa76f, 0xfe479ffe, 0x9bb62563, 0x83b5a2d3, 0x0cfd0226, 0x67bcb840,
+ 0xf1e9fd26, 0xefbad196, 0xea6945f0, 0xd38ead55, 0x8bab3de4, 0xe7b0c7ae,
+ 0x52277bac, 0x3992af3c, 0x2ade9122, 0xc1376e65, 0xe61b259f, 0x4f9d5733,
+ 0x2ac7b731, 0xa27ec18b, 0xb07b5aef, 0x3389fec7, 0x78a8df20, 0x3a13f154,
+ 0x19765eef, 0xacd076e3, 0xdd7ada75, 0x16301076, 0xe5caba8a, 0x32bf76da,
+ 0xb9459fbb, 0xe038dee8, 0xaeabf21b, 0x80821e50, 0x266e7f21, 0xa61f71e3,
+ 0xced543e8, 0x517a592f, 0x6668728f, 0xc23d45e3, 0x1fd2e673, 0x385fa7e6,
+ 0xa1bef3b5, 0x3ebb4a20, 0xbf934e39, 0x534435d1, 0x30f766ff, 0xa75bf7cd,
+ 0x5ef9ab5f, 0xc9a919ee, 0x5e3d5edf, 0xfd467f53, 0x7a1cad24, 0xa3d69a37,
+ 0x79bfa7e2, 0xa3e8a5bf, 0x12ec4277, 0xe23a9d35, 0xbf91133f, 0xe4672c3f,
+ 0x33787cbf, 0x1d31f8d3, 0xe7822423, 0xf93d5c80, 0xc8e5f731, 0xbf208fef,
+ 0xa1f44fc9, 0x7343f3c2, 0xa228c9a1, 0x7ee4627f, 0x725fa879, 0x5e503990,
+ 0xfdb1d4ce, 0xff8f5442, 0x9cf30e67, 0xe3bafec7, 0xf10f4b0d, 0x1f884378,
+ 0xff78a573, 0xbfcc0670, 0x4d79790f, 0x16c3f72e, 0xffaf36ee, 0xb58e0838,
+ 0xfc9ad16d, 0xebf1fda2, 0x3bd60e3f, 0xae1d044b, 0x93e146b3, 0x7da0165a,
+ 0xa0e8bb52, 0x40c4eafe, 0x583be62c, 0xf4b46c67, 0x0a8b838f, 0x258f800f,
+ 0xa9de2837, 0x193fc3fa, 0x9e0a453e, 0x1a70b4cb, 0x90e3cb93, 0x29108f5f,
+ 0xc7239cdd, 0xf103fee7, 0xf49eb41c, 0xdc7fbcdc, 0xc847227a, 0x9f9f0859,
+ 0xe3dfaf1b, 0x17940f1e, 0x7f0b908e, 0xfe4cb826, 0x47a5c247, 0xd82f47cf,
+ 0x72a3fa0d, 0xfdfb819d, 0xbf5c33de, 0xfefd7237, 0xf68fb47c, 0x44f39b87,
+ 0xed070ee7, 0xe93ed297, 0x618d7ba1, 0x59df1819, 0x797d23a1, 0x8190997a,
+ 0x2126c2fe, 0x0f36fc8c, 0xc81648ab, 0xc878b9be, 0xaa31fd48, 0x3afded07,
+ 0x0551f390, 0xe4096b3e, 0x71e5ccdf, 0x716e35b1, 0xf5038a4a, 0x1eac1ff6,
+ 0xe27a8b8a, 0xfd9e1e11, 0x696be130, 0x2bee45df, 0x6bd0127e, 0x8512d1e5,
+ 0xd5cc5f8f, 0x2e1f3ad1, 0x949db914, 0x1f70ba2a, 0xa9d81563, 0x96065768,
+ 0x915f28eb, 0x6d59e9c7, 0x9d0a1ff7, 0x14dd94c7, 0xda88f386, 0x7d7dba24,
+ 0x2e51fb8c, 0x793d0f8f, 0xb3ed1857, 0x68742a01, 0xd6bddbef, 0xaf582e69,
+ 0x8d96d0bd, 0xdcdadfb6, 0x4d6fea68, 0xcf159746, 0x748cfca1, 0xfe8eca78,
+ 0x8cfac0a0, 0xe655cd33, 0x580feeab, 0xe936fe94, 0x9da2bf41, 0x1e289822,
+ 0xf91af161, 0xb16715f9, 0x1ccade26, 0xa76e0b02, 0xf428f3d6, 0x1b42c76a,
+ 0xeff697e1, 0x5db178d5, 0x1ba417a1, 0xcf4abbc4, 0x8983fda1, 0xe9cc8dec,
+ 0x15d9f389, 0xe51a8e52, 0x8f748dd9, 0x1f90eafd, 0x07fe5cbc, 0xe3c4be6e,
+ 0xded7de2c, 0xe18879c3, 0x0c9c525f, 0x5fce4aec, 0xbee2434b, 0x024f913f,
+ 0x40cf0e66, 0xde1e5684, 0xdac9d0ab, 0x48de827f, 0x3ebc02ba, 0x8fe5cb9c,
+ 0x36fdc0ab, 0xb2c73bca, 0xfba230d4, 0x96270b1f, 0x51384560, 0x3872ba5e,
+ 0x1f3df379, 0xcc749e10, 0x7f71b46f, 0x72e1f90b, 0x31c2a47c, 0xbe9e6449,
+ 0x3c88f2f4, 0xca1bfbe5, 0x6ab7ae7e, 0x61d90fc8, 0x02c57728, 0xcc2cd2c6,
+ 0xffb6bc61, 0x8f9c0e7a, 0x396ae885, 0x96aee5d2, 0xcfe43094, 0xcabc6564,
+ 0x0ca7d29b, 0x205fa077, 0x040ed018, 0xe3c0c3bf, 0x574edc3f, 0xb94f7ae5,
+ 0x72c47ed6, 0x1f8f664f, 0xeaf7daa6, 0x82973c77, 0x59f3aae3, 0xfd61d8a5,
+ 0x125577cd, 0xdca2724b, 0x808f765a, 0x5ab1dcf0, 0x717df8d4, 0x0325615e,
+ 0x7fce3e3f, 0x8efd13af, 0xcdafb038, 0xf575cf28, 0x5e083382, 0x0a817b81,
+ 0xf8871338, 0xe24fe02b, 0x8967bd3a, 0x57c7425e, 0x85abb1d7, 0x5de71b8f,
+ 0x9f90c82c, 0xa02f5154, 0x9956b7df, 0xa3055c7f, 0x3e9969ef, 0x9e21e301,
+ 0xe38a5616, 0x03335655, 0x332af5c6, 0xf2865399, 0x7443c6ca, 0x02b9edde,
+ 0x206f2539, 0x4f3a4fc9, 0xa4f02ae3, 0x4d1d01e7, 0x7643284d, 0x864bb867,
+ 0x167f89f1, 0x4cb5a71d, 0x59efa2f0, 0x843ce2d4, 0x11d001fe, 0x2d3c7dc5,
+ 0xe75f1a01, 0x5d7271e5, 0x80e9c18b, 0x658d4875, 0x5521ffb4, 0xd4329c1b,
+ 0xdf29b63b, 0x2d95f18f, 0x0ddfdc8d, 0xd67493f5, 0xd1c3d7fa, 0x9910ab5f,
+ 0x790a0144, 0x5659fa2a, 0x30562e85, 0xf7ee3b77, 0x41fe1933, 0xdca548bb,
+ 0x2a6f3d5a, 0xd0e52266, 0x13dc8378, 0x6b9e409f, 0xd3b240dc, 0x678daa94,
+ 0xc92b2d48, 0x7d6233af, 0x890faca8, 0xa5d54877, 0xac971714, 0xf35bf2da,
+ 0x8e086222, 0x9e1e3c59, 0x8d88ef73, 0x727cc2b7, 0x1fe3797f, 0x41873d30,
+ 0xfe5b8033, 0x4c073bb2, 0xac16ff87, 0xa62378d8, 0xe8cebc4f, 0xe08fc19c,
+ 0xfa8c6657, 0xe8fafcf1, 0xb2abf295, 0xb9d00f26, 0xd27dafc2, 0x094f1abf,
+ 0xfe954fe5, 0x4d4ef943, 0x7f865ed7, 0x120526d7, 0xdf4f0f91, 0xdb03323b,
+ 0x73de3657, 0x5f88c7c8, 0x77d00705, 0x117177a5, 0x5660ba23, 0x5e5bd097,
+ 0x490b3784, 0x1f37bfec, 0x3b7c863f, 0x13e7effe, 0x95df087f, 0x63ce8c09,
+ 0xf649fd81, 0xdfaa9a9c, 0x3eb9f223, 0x246790bd, 0xc1464ebc, 0x053bac0a,
+ 0xc7bee0da, 0x2b4e6078, 0xf02e7fa4, 0x4de38b3c, 0xef9e3c81, 0x6b40fd7b,
+ 0x4b37ae0c, 0xa78ef5c7, 0x76e68edb, 0xa8ffb748, 0x06590fd8, 0xdced0536,
+ 0x771126c0, 0xc0e0596e, 0xe2d63be7, 0xc9b96bbe, 0xcaeb0699, 0xf448dfba,
+ 0xf68a0484, 0xa7689651, 0xb6aee5b8, 0x9f69cb8f, 0xd2c0d1b1, 0x0ee06e28,
+ 0x006473c3, 0x4caab0cf, 0xacc357b2, 0x857aaf68, 0x1e88aaa4, 0x22f5087b,
+ 0xef2cb40a, 0x30ac53ad, 0xb042aefe, 0xec7b3347, 0x59fed51c, 0xeb4c9f9c,
+ 0x6820ed57, 0x8fddb0c7, 0x0b4aa7e5, 0x19bb224b, 0xf7fb83e6, 0x90264cb6,
+ 0xff5213ed, 0xd92332f4, 0x7baf76af, 0x5bb470ca, 0xa0e6a797, 0x9ae30add,
+ 0xfd7f6e24, 0xbb67ca3b, 0x285ef94e, 0x49b9e0e6, 0x05801f75, 0x8718d174,
+ 0xfeaaed53, 0xe763a5e7, 0x9505b954, 0x9f2f9b7f, 0x59ff7ec1, 0x5563dd72,
+ 0x634d4de8, 0xe9e079f8, 0xcf8dbd0a, 0x9e9a5337, 0x73dbb3ff, 0xfe93aea7,
+ 0x39feeb79, 0x9ffae1d7, 0xffd88eb1, 0x3cd8f821, 0x3ac67ff9, 0x4ff2996e,
+ 0x5f37875c, 0x43cfc86e, 0xe746d679, 0x7e2eec88, 0xdee41c2e, 0xcb9cbc3d,
+ 0x09938b39, 0x74ffc764, 0xfd84d779, 0x1c1f419d, 0x7778a1cf, 0x67183a08,
+ 0x88a1a588, 0x8ca5cdec, 0x2c8681f6, 0x4340fbe5, 0x224d3a96, 0x6e1603da,
+ 0xec520e27, 0xb94b41ce, 0x9ca719dd, 0x118b882b, 0x3fd4327d, 0xca5bcbf6,
+ 0xbee0c6e7, 0xd5ec9190, 0xf5dd36e6, 0x5e53d416, 0x868fce89, 0xd2d289da,
+ 0x5f9c4a95, 0xf6aa9f6b, 0x79e31a68, 0xb4b3b2fd, 0xa3daa74f, 0xb4f29443,
+ 0x603f7ca5, 0x1ed68b48, 0xdad6ab8d, 0x1082fa8f, 0xbaa9733b, 0xeb49d07f,
+ 0xe9d72dd3, 0xa87ffcf1, 0xb07b89dd, 0xab0714a8, 0xfeb4067a, 0xf630d74d,
+ 0xf9f77e74, 0x1fdc1c8c, 0xd05ab99a, 0xcf5539e8, 0x7e282402, 0x43e3e2a4,
+ 0x3f8873d4, 0x5fb534f7, 0xaf3e6fd2, 0x2e4c7048, 0x539cd74f, 0x1e7eec62,
+ 0x3a73712f, 0x11eaf5fa, 0xddaed16b, 0x37c6eeb7, 0xfd697d31, 0x04e5e19d,
+ 0x6f54f5af, 0xebc6cb7f, 0x7650ff30, 0xe6123dbb, 0x53a8d0f5, 0xefd009ef,
+ 0x85e33c6a, 0x2978b3eb, 0x9e14b68f, 0x7ab3d08b, 0xa4dbdfda, 0x0d9f4c0f,
+ 0x45122be5, 0x23be911c, 0x1832981d, 0x59309f9d, 0x35f57e78, 0x30e3ee8c,
+ 0x1a9f5ce5, 0xd73d0987, 0xc7c3cab7, 0xc4f00559, 0x18963573, 0x39a91f7e,
+ 0x08e9fee1, 0x818766ef, 0x8b3939e1, 0x624fee72, 0xa82aaed5, 0xbf7edc77,
+ 0x0bee167d, 0x7e881867, 0x26ce98a4, 0x9ed993c4, 0x71c2af63, 0xcd35e242,
+ 0x2037e929, 0xfbb5bc59, 0x20679ef0, 0xc9cf7b7d, 0x2a9d312f, 0xf3c3efb5,
+ 0x88465225, 0xbf6bd29f, 0x9bdc1198, 0x4a5f3387, 0x6e3b9632, 0x754e9110,
+ 0x869a6feb, 0x50c154fe, 0x4f581ae7, 0x1bf30258, 0xbd611e60, 0x7b7989f6,
+ 0xce9c20a9, 0xf59648d5, 0xdfd80d15, 0x7fba08a8, 0xae03bec0, 0x4df3a7cb,
+ 0x80f657f4, 0x0e3a47a8, 0xc38ff653, 0x1fed7b32, 0x30c2fcd3, 0x3b59e14d,
+ 0x7a15c3e4, 0xca7b635f, 0x6b77fb87, 0x106e5213, 0x69f53d1d, 0xbbd6195f,
+ 0xab1bbbf2, 0x26fd5f68, 0x9fcf1593, 0xcafb2985, 0xa574e3a1, 0x43675b3a,
+ 0x6418b46a, 0x55f11673, 0xe0725f0f, 0xe68353d8, 0x9cfaf501, 0x736e3aa7,
+ 0xda83c71e, 0x64c2d19f, 0xf74323b4, 0x81fb43ad, 0x56be7079, 0x31fda9ea,
+ 0x01e746d6, 0x518b8874, 0xa7abb57d, 0xe9df0db9, 0xff1fbb24, 0xcc82e382,
+ 0x35fc431a, 0xcedb55ac, 0x0dcfca9c, 0x2a18f4a8, 0xfdd0a52f, 0x6f7ad4f7,
+ 0x9f81e138, 0x1fad0827, 0xf6d0d70a, 0x5833b7f0, 0xe160ddde, 0xa95d88fb,
+ 0xac22b99d, 0x473da57b, 0xbf5a7f33, 0xef7fd3d0, 0xbe6d3cfd, 0xb9f6364c,
+ 0x7d07943e, 0x4e8277cd, 0x6c596fbb, 0x8d2fb6d1, 0x25777ed1, 0x4592f368,
+ 0x6d91dfe9, 0x8e1af3a2, 0xf79e137c, 0x18d8f953, 0x8af7efe2, 0x2efa2adf,
+ 0x1e74c991, 0x79de9375, 0xe3c4e50e, 0x01d24033, 0xf82c3c7d, 0x552e58cc,
+ 0x0f515bb4, 0x93d3adc6, 0xaefc7a9c, 0xbde0ce5b, 0x6ba016a0, 0xf771e584,
+ 0xc56e9b47, 0xf148b17c, 0x70fb9b0d, 0xcb51d239, 0x37bf5f77, 0x3a9fcf1b,
+ 0x5bce740d, 0x75b1b73d, 0x1e2b61ac, 0x94cb8a0b, 0xfdf069cd, 0x84e62aa1,
+ 0x6323b099, 0xfc712363, 0x15a2d12d, 0xd1f3ddf5, 0x718efff5, 0x8c19e694,
+ 0xe14219f6, 0x46d23757, 0x756e3672, 0x5bf780b6, 0x5f9b1e1e, 0x06317289,
+ 0xaf9465fc, 0xc57dca90, 0xf015c717, 0xc5b6c0f8, 0xbe23c52f, 0xdb0f5837,
+ 0xa2159e69, 0x52d8a713, 0x8b7fe5c1, 0x7b3ed185, 0x3752a8f3, 0x72ec4d1e,
+ 0x8b3c0ec9, 0x41dee2d8, 0x2d595ef3, 0x9cacd972, 0xc8580197, 0xbe9c3951,
+ 0xfd4a360c, 0xb3346e98, 0x972839f8, 0x7ce8c292, 0x81f67f50, 0x57cb84b4,
+ 0xe9cc6f6c, 0x1143debf, 0x5cc8f18d, 0x9fe467cb, 0x6dfd0b9f, 0xf299b19d,
+ 0x538d3caa, 0xdfbbbbe8, 0x1bba3d10, 0x36724bf0, 0x9e2ce41a, 0x878e63c7,
+ 0xf575b789, 0x3a20b4c2, 0x7c8055d5, 0x2ee7e2cd, 0xbebb7e30, 0x87e334a8,
+ 0x9b9d4cfc, 0x5518e5cb, 0x97ebbb1e, 0xda05dc61, 0x635f51fb, 0x0fce783f,
+ 0xb7d71952, 0x443fa851, 0x830cf37e, 0xe839ef03, 0x430e402a, 0x56825d7b,
+ 0xc9181c4f, 0xc1fb35f1, 0xa09eccbb, 0x728c4d38, 0xbea3661e, 0xeb069cde,
+ 0x744338d9, 0x6c78076e, 0xfa1068a9, 0x55c4c78a, 0x0d997e70, 0xde6fd1f5,
+ 0x1b139152, 0x8c669ebc, 0x36d0c073, 0xdb9f0fd7, 0xbfc885d3, 0xbc79235d,
+ 0x1cdd67bd, 0x3f4071be, 0x479a87a8, 0x6ae6ae97, 0x557241da, 0x6d6de567,
+ 0x073a7aae, 0xcfc155d9, 0xf813ad5d, 0xc4a4827e, 0xf28b9bcb, 0x4bf4bf49,
+ 0x492b152f, 0x57e2849f, 0xe5fd3f9d, 0x9911e907, 0x8719f1f1, 0x4cceb49b,
+ 0xda07e1fa, 0x4af9743b, 0x1e0bd47d, 0x62ba7f6d, 0xf8e33651, 0xaf105fa8,
+ 0x7bc5e63a, 0x95fda193, 0x3a16fc2a, 0xe069c91f, 0x8d9db1ed, 0xdbf48bf8,
+ 0xc8e00169, 0xa1ce82e9, 0x3c38f7b3, 0x7c3a24b7, 0x2e01f86b, 0xae7487d2,
+ 0x78f7a52b, 0x658e098f, 0x7de8efb8, 0xe7f3a25d, 0xcd4f7aa1, 0xb13070ab,
+ 0x3e9ce736, 0x0f9c4dec, 0xa76935ea, 0x01fa89d7, 0xed8a97d0, 0x094b2a36,
+ 0x5cd4b3bb, 0xd7ade8e0, 0xab6d5cba, 0x937282af, 0x03f69983, 0x99534c3c,
+ 0x79c0307f, 0x1ccf33ed, 0x3df58abf, 0xf803ae0e, 0xe6bce099, 0xe63347f9,
+ 0xedf37b40, 0xb9b426ad, 0xf5a1cf43, 0x76a4ef6e, 0x4cab4b71, 0x23c519d3,
+ 0x86b95465, 0xafd90b08, 0xe48674cc, 0xc6c934b3, 0x3d10a7ed, 0x50f80eb9,
+ 0x644af08f, 0x38d0af04, 0x49f8e871, 0xdefcc905, 0x1a52e2e4, 0xa7454377,
+ 0x5d90e31e, 0x4ec57aae, 0xefa9f4f2, 0x7bb1fb42, 0xff23a73a, 0xc81a1577,
+ 0xc1f87e1e, 0xcf119349, 0xc51265de, 0x7bd17ad1, 0x233dbac8, 0x1cae9cf5,
+ 0x7f28cd8b, 0xdbb9ccb7, 0xfec3e8ec, 0x8b3152d8, 0x965a2fce, 0xa5633b70,
+ 0x88e481bd, 0xe7b942a5, 0x71cbd8a2, 0xa213bfaa, 0x3754b727, 0x9bdef198,
+ 0x8590de7a, 0xed97dbd8, 0xbbbd1fbf, 0xf18bf961, 0x2aee4fa8, 0x79c78869,
+ 0x4ff0896f, 0xd5df1377, 0xf2029f93, 0xf1e51e38, 0x920e91a2, 0x7ff2dd2f,
+ 0x0e3b39c6, 0x5569181e, 0x43db8af8, 0x417fe25f, 0x928d66bf, 0x1c6014a7,
+ 0x8e44b52d, 0x74bc6076, 0x00d3bbdf, 0x7abd93ae, 0xfb8d63f2, 0x2fc1f481,
+ 0x49382632, 0x681e9e5f, 0xac9d22b0, 0x8f46fc6a, 0xe2ce6bf7, 0x7fe855e9,
+ 0x87b70255, 0x9818c556, 0xa1f342df, 0x2e754f45, 0xf5a7a866, 0x0137dc09,
+ 0x798fc5bf, 0xfd102316, 0xbaf18e4c, 0x298700ad, 0x30bbbe31, 0xd7ac4aad,
+ 0x129c60d9, 0xf080b447, 0xc563a29d, 0x9daf1e06, 0x115cf385, 0x59c511f3,
+ 0xd1c5a727, 0xc5a3547d, 0xc9fbc3ad, 0xf6d5677a, 0x8bce8cb5, 0xb015bc51,
+ 0x8ce1f74a, 0xb6bdc718, 0xeeab8e27, 0xdcf1a913, 0x04290575, 0xffc1212f,
+ 0xcb23e22d, 0x1ef1101a, 0x403e987e, 0x46aaf8f6, 0xcd41f913, 0x91da3b09,
+ 0xf823323d, 0x3e7aa43e, 0xb163e017, 0x0c567c02, 0x95d69bbc, 0x17bb1494,
+ 0x91faa5e7, 0x50af20f1, 0xcc2565de, 0x4beb8a9b, 0x4aedc37a, 0x0cc67a86,
+ 0x1660365d, 0xa2b9eae0, 0xc61eac78, 0xd8583c21, 0xabfb4c38, 0x40d122bf,
+ 0xf2d0d8f1, 0x5c780b27, 0x21050b32, 0x135eebae, 0x755dcfdd, 0xaaf7bee0,
+ 0x301e7e50, 0x6767c939, 0xffbc1481, 0x66771dde, 0xaeddff7c, 0xdbb5bf9c,
+ 0xa63f740d, 0xf8ccbe3b, 0xe71abcbe, 0xd9e51a88, 0x31f2788c, 0xc7f421c7,
+ 0x8f71abfe, 0x4fca461b, 0x6dac7f60, 0x63c515c0, 0x68eac6c2, 0x8529279f,
+ 0x05f78279, 0x5feb2956, 0x7a870dd5, 0x75f5ea3b, 0xf6079428, 0x378d870f,
+ 0x2226bbe7, 0x88ec46dd, 0x47dafd47, 0x171343bc, 0x79287bc1, 0xfa6204b1,
+ 0x9c79aa93, 0x3cea6624, 0x5348778a, 0x0ad93ef9, 0xdcfc6016, 0x7c84c0a0,
+ 0xfd4beaba, 0xe887700d, 0x927accd7, 0x90ae9193, 0x7f2f48b8, 0x6576e645,
+ 0xa2dbdc88, 0x02f1f9f0, 0xcf91ee25, 0x93e7bff2, 0x5228bb25, 0x1889f7d9,
+ 0xe8724295, 0xd90a5711, 0x411cc443, 0x9d9cbef0, 0x87b15073, 0x8f9ca77e,
+ 0x83e72bf7, 0x83e72b0f, 0x0b77c55f, 0x863f90c0, 0x7a4016ef, 0xe549c9bc,
+ 0x2815346f, 0x6fe399ca, 0x4892ee45, 0xf9941fb2, 0xadf994e9, 0x25734eb0,
+ 0x6d567e03, 0x5879d3d3, 0xe984c263, 0xaf32cf68, 0xdb119edc, 0x7587ef73,
+ 0x9efcbfc2, 0x095da773, 0x3a4f3a1e, 0x3ff7cac7, 0x542d7c55, 0xb612afea,
+ 0xc75f9019, 0x36e16a76, 0xc6a452fe, 0xda622cae, 0x4d1397f3, 0x4bf53443,
+ 0x97f3daac, 0x6ad7ec93, 0x68764fbe, 0x975e5fcf, 0x1f643e31, 0x0b574b56,
+ 0x806e8013, 0x7d33aa4e, 0xd685ff34, 0xcd7b8a52, 0x74c7b90d, 0x3f36ab47,
+ 0x2fcda7df, 0xabcdaddc, 0x46c3c9e7, 0x9230f429, 0xf131fc8d, 0x0cf7e44e,
+ 0x0107ef85, 0x3ab36fbf, 0xcfda1199, 0xf8bf7816, 0x1b00c61e, 0x76c94bed,
+ 0xe3ac238c, 0x5cb09ff7, 0xc3bdcbc7, 0xbe7af695, 0xdb8ec56f, 0x4b1dbee8,
+ 0x06ede1cc, 0xfc7eeff0, 0x72f1a48e, 0xfe87af0e, 0xa21bd612, 0xe5c353f4,
+ 0xfe459c93, 0x33ec9b82, 0x62b36b23, 0xc2fe016a, 0xe9399a34, 0xab0c759e,
+ 0x9075bf27, 0x51327f72, 0x43bca4e8, 0x3e6186b0, 0xf0a67045, 0xe48f85f8,
+ 0xfe4950c3, 0x89f12a75, 0xf447745b, 0xb90d97e6, 0xaaf007ba, 0x910286f8,
+ 0x5623e2e4, 0xd8f9ef46, 0xbf13f75c, 0xb016c36e, 0x8f6b336e, 0xf87a1549,
+ 0x61bcede7, 0x5c135fc4, 0xb52fda0e, 0x780b2415, 0x8588a52e, 0x4536cb9c,
+ 0xc4a3e869, 0x5f42171a, 0x4be84243, 0x9d7f7f4b, 0x3945d5ec, 0xe842ce90,
+ 0xe5be2ff0, 0xaf182c51, 0x05fa8f4c, 0x7689d58f, 0xca9e054a, 0x754f9602,
+ 0xee319b46, 0x73d18b67, 0x3fd8a579, 0xab9f4aa5, 0xb2eb59e4, 0x566bfbe1,
+ 0xf6e649d1, 0xf13d2dba, 0x96df1825, 0xea35f600, 0x5c919963, 0x1fd3b07d,
+ 0x7fd43576, 0x65fffc04, 0xeb1bfd0c, 0x65efbc64, 0x5f10e4b5, 0x7949623f,
+ 0xd05ef300, 0x437f58e8, 0xe5aff731, 0xef826ce8, 0x05bea151, 0xc23da5ef,
+ 0xc1a94cf2, 0xfebc2df5, 0x5164597a, 0x31189f90, 0x9dbfea82, 0xcef86667,
+ 0xd9a07781, 0x63ec7187, 0xdd77acf2, 0x7b7feb41, 0xaf07d714, 0xa8f11c19,
+ 0x7c991e0f, 0xd287a677, 0x685f8d74, 0xbee4104b, 0x8f8517ce, 0x92bd7236,
+ 0x78c7e25b, 0x34c2747c, 0xfd039957, 0xe90bb71d, 0xf112e742, 0xfd375be8,
+ 0xa87e2b44, 0x0fc106e4, 0x5d749b4b, 0xe3ff430e, 0x35770b11, 0xd59e291e,
+ 0x02f98652, 0xd903ee91, 0xd9ebe25c, 0x7e02aeb8, 0xe54af0fe, 0x181ea871,
+ 0xbfdb9a32, 0x3c448693, 0xdffa1430, 0xb15a2450, 0x2b7a0dff, 0x4ef1e7dd,
+ 0x1757e466, 0xe097eabb, 0x11096dbc, 0xda6fcf0c, 0xbe781a0a, 0x00ccc0d8,
+ 0xbd6b934f, 0x4a69f117, 0xf6c08cf5, 0x7a7e0747, 0x5b19ed1c, 0x703a4882,
+ 0xaef9cba2, 0x2817eb1b, 0x79e29df1, 0x9b3c70eb, 0x599ab445, 0xb9541c0f,
+ 0xcbc99ebe, 0x0ab2ffc9, 0x0accdef4, 0xce0d436b, 0x708491e7, 0xae6df3b2,
+ 0x79e20b06, 0xd13d40c3, 0x7f224941, 0xc2556a57, 0xffcc0ab4, 0x7191a062,
+ 0x1f2ff3be, 0x5381fe8a, 0x5b3575a0, 0xc75e681a, 0xc139892e, 0xa9a896ef,
+ 0xcf85a1d9, 0xf8f146ef, 0xf1e30990, 0xf5b79f80, 0x8b9a9ccc, 0x78a7a3f4,
+ 0x6b7c7f53, 0x7ece5d73, 0x2afe61fb, 0x110b0394, 0xc29785be, 0xfa404f98,
+ 0xfe61293d, 0x5b017f77, 0x60d9d680, 0x6e41fec1, 0xbfa2fabb, 0x7e9cd188,
+ 0x4b0e0b9b, 0xd7824ef8, 0x341f1021, 0x444e4e5b, 0xb528783e, 0xa1e8e88c,
+ 0x899a8f82, 0xfcf3862f, 0xeef779db, 0x137a3c41, 0xe77f69c3, 0x315982a1,
+ 0x60bef4c1, 0x32f44894, 0x4e616fee, 0x9463e23f, 0x91fbf881, 0x8c56c708,
+ 0xccf3794f, 0x824bbf64, 0x986cd975, 0x2862c4e7, 0x5da2fe87, 0x7ef13e62,
+ 0x0b8f0575, 0xd57e302b, 0xf8843b65, 0x31664a90, 0x3949ae7e, 0xef9114f7,
+ 0xb435435c, 0x25956ffa, 0xd8cfde97, 0x4270d092, 0xbb20b6d9, 0x5722906a,
+ 0x45889406, 0x5906df28, 0xeb655db8, 0xbb940594, 0xaa47fba1, 0xed29d7be,
+ 0xa65b328c, 0x371b54a3, 0x7d7015d2, 0xe97f6a1b, 0xc35edc2c, 0xae8fbc3f,
+ 0x893f35cf, 0x317438e7, 0x197f7ada, 0x0a739ca5, 0x3a54afb1, 0x7ae560df,
+ 0xd1ae4362, 0xa1bd7487, 0x2a59db98, 0x47f2ab1f, 0x872abf85, 0xef7e7bd4,
+ 0x5195f628, 0x87365e4e, 0xe599eae4, 0xd4076f78, 0xc317739e, 0xfa56897b,
+ 0x1f72aefe, 0x6f6294f1, 0x5bd8a7bd, 0x5bd8a1ff, 0x05bda3ef, 0x835186f9,
+ 0x1437bf08, 0x08dd762e, 0x20901af3, 0x3a14df11, 0xedc44c4e, 0x271971af,
+ 0x61d97d2c, 0x0ea2d111, 0x348f05e3, 0x36497bf2, 0x1598ed97, 0x95cf59f1,
+ 0x766b2cf9, 0xbcbb3469, 0x7ae3f27c, 0xe43ed1d2, 0xb9557beb, 0x994c794f,
+ 0xfe6571ff, 0x57f3286f, 0x43498fed, 0xbca132be, 0xefaf10df, 0xfc297e47,
+ 0xb9d0a729, 0xb57950a8, 0xe908c401, 0xfc9122eb, 0xe778209f, 0x25bde46a,
+ 0x4ef5f720, 0x1e68c959, 0x7660dbbf, 0x7c462c57, 0xa714664e, 0x27aae89d,
+ 0xb90365b9, 0xf8b37245, 0xca6ceb5c, 0xe5833847, 0x6381519e, 0x8e5acbb1,
+ 0x4638be72, 0x24571f4f, 0x5bbdd0a4, 0x1d0efed5, 0x0cf072f7, 0x82a66795,
+ 0xf3e25ef5, 0x6c7247ff, 0x8ee3e32c, 0xfd3a24bd, 0x4f1cde5c, 0x91237926,
+ 0x5fed0a7c, 0x636f3795, 0xbe2064cc, 0xfba1644f, 0x610a7700, 0x9de7844e,
+ 0x3f307c28, 0xff7dd197, 0x673d8ac1, 0x01d1de57, 0xceb8a14e, 0xf5b04ed8,
+ 0xfc7af883, 0x1bf75325, 0x8f8edc6c, 0x9a27e4d6, 0x4bf535e2, 0xef9ac9ac,
+ 0x35c3ec93, 0xb23b27df, 0x32ebf935, 0xffea6946, 0xc9a459c2, 0x593050df,
+ 0x2e4cbf53, 0x6665e4d3, 0x0e4877a5, 0xfa1eed36, 0xa7fd1eb1, 0xa71fa1b6,
+ 0xa14f86f5, 0x0e0bf0f1, 0xa3b5e160, 0x00e8678b, 0x87518546, 0xfc864cef,
+ 0x6793d1c6, 0x0aef80e8, 0x3afe1f07, 0xd3685819, 0x7f3c29e8, 0x53afe1f5,
+ 0xf465bf20, 0x863f3c75, 0x3adcf091, 0x2f0cea7a, 0xea1c59e0, 0xd0347479,
+ 0xea972df1, 0xf83da28f, 0xe6d365c7, 0x4ef84b26, 0x06625940, 0x8a6ce7cc,
+ 0x7efc61e7, 0x15acec73, 0xfc761178, 0x8f74f577, 0x79a337ed, 0xfc8b8ebb,
+ 0x8b8e8d5d, 0xbb0d1dfc, 0x53f6f1c8, 0xcbbef553, 0x7e9a0e04, 0x64115fdf,
+ 0xfd05af7e, 0xdc6939cd, 0xfd14c4df, 0xdfd14c4d, 0xcdfd14c4, 0x6fee7a39,
+ 0x26fe8a62, 0x89bfa396, 0x324d5be9, 0xb934efa5, 0x726f6d28, 0xbf7dda53,
+ 0x6ae729e0, 0xef380a3d, 0x985b8b4f, 0x1117e4c3, 0x4ae7a14e, 0x4f9df43a,
+ 0x45ca7ed0, 0x12fbc0e6, 0x394e2287, 0x39acbf70, 0x2e7444cf, 0x4c3bb674,
+ 0x9730bdf0, 0xb62f9be7, 0x617e503b, 0x8e9eed1e, 0x946cb6e8, 0x16b5cdbf,
+ 0x35bbee27, 0x23c7f45f, 0x1bd6149f, 0x714cdee8, 0xe9c52767, 0xbdfc2d0a,
+ 0xc7114384, 0x91e3288e, 0x9179da5c, 0x277c45f9, 0xb0eedcc7, 0x3f60e32a,
+ 0xea326e30, 0x3025c2b7, 0xbf5bf52e, 0xb0a9fa98, 0x842b8f74, 0xe1fa6b8c,
+ 0x410a2771, 0x3176a6e3, 0xc701177a, 0xf5c66875, 0xfc3f744b, 0x78c25fa2,
+ 0xd3b44761, 0x354d718e, 0x21df8c5f, 0xdfcf45bf, 0xf8742c5f, 0xb893d425,
+ 0x5bef89bd, 0x33d881c6, 0x1f0d79d3, 0x47a865c9, 0x5d9db971, 0x9a179d7c,
+ 0x9f900bfc, 0x6077958a, 0x7ba58cc0, 0x730c4c9b, 0x9128bea2, 0x38363bbe,
+ 0xe339df17, 0x1b15a0ef, 0x1f90dbdd, 0xde5c74eb, 0xdf3318b0, 0xcfb5d057,
+ 0x3bd415ff, 0xec983b19, 0x4bfb0495, 0xb404752c, 0x44cae45f, 0x5b24e3bb,
+ 0x7568724f, 0x8f7fe794, 0x31be7a06, 0xf4505eb3, 0x7763f527, 0xfdc0ef85,
+ 0x86578e88, 0x4d1f21e5, 0x645e3a33, 0x1f7fbfc0, 0x3cfc44dd, 0x8791ca2d,
+ 0x7dfdac2f, 0x8f9e0af4, 0x3788bc73, 0x69acad83, 0x8ffc7146, 0xf1452f3f,
+ 0xa79a740d, 0x7fb43a0a, 0x765373d4, 0x063613d1, 0xfaeb54e0, 0xd7e7c0ca,
+ 0x7078c069, 0xc10718d4, 0x4661e06f, 0x273a98e7, 0xe076f847, 0xfa80df7e,
+ 0xb2878c6c, 0xd61e474c, 0xd277d24b, 0xef8ef27d, 0xa827fdf8, 0x50537919,
+ 0x8389fefc, 0xf8afab92, 0xdc31c9e3, 0x6a945d4e, 0xa8788759, 0x944c9bb3,
+ 0xe748bc1e, 0x9dce9982, 0xd96bf18a, 0xa97bf7d0, 0xfae18eaf, 0x41a57921,
+ 0x74410231, 0x30e594c2, 0x0cbde6a6, 0xbbf6d0f4, 0x8bdfbac3, 0x43327003,
+ 0xdef3c89a, 0xeb178f1d, 0xac65f534, 0xe31dfddf, 0xbda7acf4, 0x8fcddbfc,
+ 0xc6554f2f, 0xc7997a43, 0xd50c7fc8, 0x6d0b6b3b, 0x843f3bea, 0xcc63c7e7,
+ 0x523de9db, 0x14877949, 0x4e315aea, 0x3de8ce11, 0x37bfc1ae, 0x9e819afb,
+ 0x3d399a76, 0xdd3c8aa7, 0xeafaf229, 0xbbeaa53b, 0x7a14cf6b, 0xa3cc2b6e,
+ 0x8fd4fc7e, 0xdf1b37b4, 0x6d6788cb, 0x6efabe34, 0x012f5a94, 0x2b0920f4,
+ 0xe23a675d, 0xfb1250ab, 0x63e7e784, 0x1d20e68a, 0xb2f2685c, 0xcdf4824f,
+ 0xc6c8f085, 0x49d5fc60, 0x3f5af7da, 0xda81331f, 0x1b6beda9, 0x284fb227,
+ 0x3a27e978, 0x69154daa, 0x624ebd1f, 0x9c3be2af, 0xa80d5920, 0xa776d597,
+ 0x78e2de40, 0xc5fc82ef, 0xbb903df4, 0x3ed1e89f, 0xfbe94e9d, 0x3f2a1e4d,
+ 0x694d54dd, 0xca9ea9a0, 0xa46a6a3f, 0x23db96f4, 0x167f9172, 0x3ec65fed,
+ 0xdaf7a209, 0x1027bd36, 0xd4553f94, 0x51ad1d37, 0x7254e8e8, 0x1c9fdfdf,
+ 0x53bbedc3, 0x3b3e38e3, 0xf7c0dec0, 0x972e80da, 0xdbfd6d5b, 0xfdca1d1d,
+ 0xf9e3a3ae, 0x3c4765fe, 0xc31f2fcf, 0x64596efd, 0xe8fed8ad, 0x3fef0378,
+ 0xefc6ac45, 0x7bf78db2, 0x77a45d2a, 0xb1357ea4, 0x5831fee8, 0x73ca163f,
+ 0xaea7f27a, 0x41e5dfe2, 0xaf9d5cbc, 0x42b6fdfa, 0x61eefaab, 0x8fcf7f3a,
+ 0x7a02f7df, 0xfad5fea7, 0x3e702663, 0x4befad0c, 0x43c9e7e5, 0xc2a9f1e1,
+ 0x6817c4b7, 0x241f2367, 0x9d45f107, 0xa542f883, 0xd6fe9543, 0xa7387216,
+ 0x0f3a151a, 0x07eee7e7, 0x76842ea3, 0xb4cce383, 0xbbe3208f, 0x9d9eb0cb,
+ 0xa12fc282, 0x63bca0fc, 0xca83f2ac, 0x0fbd2a07, 0xefe33e06, 0x8c75f334,
+ 0x5f79fa95, 0x7b475958, 0x845dc46c, 0x2b7a83d7, 0x12b1adea, 0xb0792f7f,
+ 0xedcef5d8, 0x11b19fc8, 0x96918c0e, 0xf7d4b2ac, 0xfe3ec725, 0x9543c2af,
+ 0xa3c0fd0b, 0xca0c1c17, 0x123fc3bb, 0x50e7240e, 0xf6fd238e, 0x8c4eb721,
+ 0x177629b1, 0xc7cfdfa7, 0x1d226fc8, 0x1d660875, 0x30e87bde, 0xf05f7df7,
+ 0x0ebe78e8, 0x16d68e95, 0xe3074a32, 0x96f6873a, 0xba7aea7b, 0x230779d7,
+ 0xc61a97f9, 0xacf143cb, 0xfe482bae, 0xa979c19d, 0xec0c64f0, 0xa127e81f,
+ 0xe8ef42c6, 0xe0e856dd, 0xd3f036fc, 0x67ac0dca, 0x3e8a35fd, 0xf8944c7b,
+ 0x7e8ac87b, 0xa4172ee9, 0x1a996599, 0xcf4743bd, 0xefe15f3a, 0x5645fb8a,
+ 0xa372ef8d, 0x171c1d6f, 0xe5c8521f, 0x3cf4d743, 0x2f13f711, 0xf742d5fc,
+ 0xea0c2f8b, 0xcef68d3c, 0x533d5685, 0x2a9b23de, 0x8b9dde80, 0xf90c133e,
+ 0xf39ef2a5, 0x0ef7e8e7, 0x176d7a83, 0xb5bda34f, 0x4cc4ab68, 0xeb609e78,
+ 0x3d20b737, 0x4f457bcd, 0x5b9a99e7, 0x7a471e37, 0xc04fb73c, 0x85d96fe7,
+ 0x31c5027d, 0x7c225b6b, 0x0a5fa866, 0xc77fac79, 0xe3c7c96e, 0x39c5328b,
+ 0x3ef1946a, 0xa0a5d731, 0xeb713e5d, 0xfb843a5d, 0x8b02edbc, 0xb48f7e83,
+ 0xdf0c79de, 0x8db7391d, 0x366b2fdf, 0xf9c0ee47, 0x0ceb4a97, 0xc17ca083,
+ 0x635e5e76, 0xf70cfd29, 0xcd3c1743, 0x60b3fe28, 0x8ff9046f, 0x1ff45af3,
+ 0x8eec8205, 0xfcda6dea, 0x4066d67c, 0x53b0583a, 0x07b35e5b, 0x79f241f2,
+ 0x2f12a150, 0x29b2ce19, 0xe3c2d25e, 0xef7caa07, 0xb97b5f6d, 0xde506d1c,
+ 0x897f66ff, 0x5f0ff7a5, 0x23e926f9, 0x2997cf0b, 0xff9033f9, 0x178e1bea,
+ 0xca752e15, 0xb3c55fd8, 0x675836dc, 0x2b662bdd, 0x0775edfa, 0x79e246ce,
+ 0x016145b0, 0xbd99177a, 0xded1592c, 0xe4bf607b, 0x1ed6f845, 0xfb893f34,
+ 0x9e2f7598, 0xa13c6030, 0xb262df74, 0xef312657, 0xfd9bf44a, 0x89dac8a2,
+ 0x7de9da8e, 0xce77265f, 0x1c2e7ec3, 0x0ed15b30, 0x4ff97ba8, 0xfcc76ec7,
+ 0xa7dd028b, 0x201890bc, 0x55b7993a, 0x0c437ba2, 0x1efcb42d, 0xaf10913a,
+ 0x28b6e788, 0x0ee58f7a, 0x19e23bc4, 0x4648eef0, 0xd071e13a, 0xf44b4f79,
+ 0xd9b5b9bd, 0xf9cff580, 0xbc557e38, 0x094b4a97, 0xe71e0bcf, 0x75b89cf8,
+ 0xa430e6d7, 0x64f5a783, 0x76811f8f, 0x0d3b7883, 0xe15e181d, 0xc5d85ffd,
+ 0xd37791cf, 0x376301c1, 0x2f3ce01d, 0xa7c00747, 0x472ff7a4, 0x97e89d07,
+ 0xddffbf92, 0x0ed0c7b9, 0x87e7e08f, 0xd51b77d5, 0x2e071a77, 0xdf14753c,
+ 0xbfb34ae7, 0xa5777640, 0xc5da8bed, 0x9d09de8c, 0x4be78853, 0x02bdbf26,
+ 0xca7277d1, 0x2f14d9b3, 0x6d7607d5, 0x744378c1, 0x3ac7c538, 0xe1b6cb92,
+ 0xb6c598fb, 0xc2f6936f, 0xcefd163a, 0xeb11e748, 0x3fc67e15, 0xbea2073c,
+ 0xa7780c4b, 0x07b519f3, 0xc65cfc8d, 0xe1fbed3e, 0xce9cf11d, 0x959d0c4b,
+ 0x804fd18b, 0x411c70fe, 0xc2e9fee6, 0x451dfc83, 0xa85c9fd5, 0x47b8a7be,
+ 0x60836efb, 0x3dea9b7d, 0x70429850, 0xd6371a18, 0x73797681, 0x0d84f339,
+ 0xc17d21fd, 0x5c7ca9df, 0xb5fa8bf1, 0x1bd1fb27, 0xbcc91daa, 0x15daf721,
+ 0x014775b9, 0xbbd1e39f, 0x7be1d0df, 0xf93b1d8c, 0x3fcc3bef, 0x062af208,
+ 0x1af519f7, 0xd4a753b9, 0x0fe914ff, 0x5bde76e0, 0x052892ff, 0x8bf797cb,
+ 0xa79a9fb1, 0x48753f79, 0xf5571457, 0xfe830e6f, 0x33d36cbe, 0x4c0597e4,
+ 0x23fb3791, 0x4bd46e28, 0xbedcecbe, 0x50f7cd12, 0x76085aba, 0x94222e26,
+ 0x69f6eabe, 0xa85d3deb, 0x670e7bec, 0xfff9e0d7, 0x90e031af, 0xba5f23d7,
+ 0x8e67e9df, 0x6eefe428, 0xef68287d, 0x056b0fef, 0x77ea0f96, 0x63c4cfb8,
+ 0xeafe4aa4, 0xfe4d56dd, 0xa6bb369a, 0x1dfbb5fe, 0xfed9ef9a, 0x11f7cd0c,
+ 0x7c9a9dc7, 0xa6817b5e, 0x64f7c8fe, 0xc0547e4d, 0xe63fa9a5, 0xef935bbc,
+ 0xf4f584ca, 0xe9a8cf61, 0xa9a0bb24, 0xd661d93f, 0x465d7ff4, 0x65df26b4,
+ 0xd8a3e051, 0xfbfdaa99, 0xff6e42a7, 0x7c2aa686, 0x8ed4e17f, 0x37edfaa3,
+ 0x2bc76814, 0x5de3b593, 0x1df05e29, 0xff9e9d41, 0xf8a6027e, 0x34ba09fb,
+ 0x9809fbfe, 0xc04fdfc7, 0x013f7f14, 0xe4dd7fcb, 0xa6befca4, 0x04bfca02,
+ 0xf7e6097e, 0xe9829f83, 0x609fe0cb, 0x77e0e5f9, 0xb8f7194c, 0xca1bee32,
+ 0x4e153fb8, 0xbdfd296f, 0xef87f4a3, 0x3df4ea0d, 0x795d6bdf, 0xe3e025e2,
+ 0x7467db22, 0x086e595f, 0xa31c6294, 0xe18975f3, 0xf1e667f9, 0x418a6f1d,
+ 0xa18036fd, 0x9ddcc49d, 0x6e3ee26f, 0xad438bdd, 0x81efae78, 0x07787ffd,
+ 0x27d85fbf, 0xf0e6bc51, 0xd891b3fe, 0xc29797cf, 0xe90a30e9, 0x7cd7c845,
+ 0x0d7e502b, 0x6773c77c, 0xca4af793, 0xa46d67bb, 0x554cbeef, 0x2fba3ef3,
+ 0xd7b3deed, 0xb85a7880, 0x7f7d2f7b, 0xf35af81d, 0xcd76f77d, 0x87d62b77,
+ 0x47cea174, 0xf7cf8571, 0xa9f9fdab, 0x7f2a4d7e, 0xddf3fe3f, 0x418e5647,
+ 0x6ab7bc7d, 0x17b5c600, 0x3b1139ee, 0xf1f007fb, 0x66cf4bd5, 0x3da81ea2,
+ 0xd1e72920, 0x07b57f78, 0xcf9e4af4, 0x6f7526bf, 0x63379e29, 0xb3ba047b,
+ 0x4f5b25f4, 0xee16c4e7, 0x728355df, 0xedc66176, 0xb57f8a7a, 0x83bc4a49,
+ 0x6350d3bf, 0x6baedc65, 0xdf123afb, 0xdb7dffa9, 0x1ef1ebd1, 0x23c1c774,
+ 0xc74c5ef4, 0x4fe3493e, 0xf1cb1d8d, 0xf72c763b, 0x77dcbeff, 0x09cf1224,
+ 0x8476d03e, 0xa7e75dc3, 0xf2561ff5, 0xbc12901d, 0xfeb44bf7, 0xcd2497f9,
+ 0xc0b801ef, 0xcdfba171, 0x7022d3fb, 0xf8db275d, 0x7d40d378, 0xd56a7950,
+ 0x1bff9c1c, 0xe53cf2f6, 0xddfa327d, 0xaeab8ea1, 0x767285db, 0xe7d49b61,
+ 0xd839f779, 0x98efcc2f, 0xebe9d39e, 0x1b1c2fa9, 0xc37f7004, 0x749b2035,
+ 0x62af5284, 0xa59bd72c, 0xea2a4f06, 0x47169391, 0xfdf9d204, 0x8811a1ae,
+ 0x6298c3df, 0xba49ebb9, 0x1f60be07, 0xb5a4ef1f, 0xeee9123d, 0x5211bee4,
+ 0x2dcbfef0, 0xe9ba7aca, 0x5e6f1bbb, 0x6fb553c2, 0xe9fb05bb, 0x9f2f1fc1,
+ 0xf54ad636, 0xb89df0df, 0x93aced05, 0xc0ddfc19, 0xfe460663, 0xdc3dc2f5,
+ 0x70793e4e, 0xfbe0f6f0, 0x7c14d359, 0x7df06474, 0xf5fb0bf5, 0x77dbbd4a,
+ 0x3d3d4d31, 0xed4ed7c7, 0x33beac7c, 0x5e7da10f, 0x6744b8f3, 0xf5f46a1d,
+ 0x4ffeb8b1, 0x57e769b7, 0x46b9c0ad, 0x0d8d8fef, 0x039ad7a2, 0x21637cdd,
+ 0xf2a03f3a, 0xa9f08389, 0x8664f1e2, 0xe765e7c4, 0xecd5f8ef, 0xdd7445dd,
+ 0xe3c4be3b, 0x31ef83b7, 0x74be2939, 0xb55a7f19, 0x2dfc821b, 0xbd23bdfa,
+ 0x989e686b, 0x9c1f63d2, 0x1a1f942e, 0x987e879b, 0x93ccfc9b, 0x185bec0c,
+ 0xebed16b3, 0x891dfa28, 0xd76e38cd, 0xffbd3d3e, 0xb03a6b5f, 0xef23df00,
+ 0xc0a30272, 0xe9b6bbbc, 0x4667dfbb, 0x629e773b, 0xf0ea7ee7, 0x7fa04be4,
+ 0xb489976b, 0x923d9abe, 0x5c17cf0f, 0x57dee450, 0x406f937b, 0x2e39ad7a,
+ 0x9a3fd159, 0x70fc96d8, 0x77e92e61, 0xdaeb57b2, 0xb75c9db8, 0x58bb205b,
+ 0x156a43b5, 0x629ce43b, 0xd65b9f07, 0x57e3edc9, 0xea11b604, 0x7b030dad,
+ 0x9b5de604, 0xdaec8539, 0xcadd695a, 0x473c0ec1, 0xe61bb5a5, 0xe7443c1f,
+ 0xd1cec0ae, 0xaddc2f94, 0x69b6d7cd, 0xf8bfaaf3, 0x3b6ed8d2, 0x37fa3863,
+ 0x1c615225, 0x0a9bc3f2, 0xe77f555e, 0xf49c6bce, 0xe80f27fb, 0xb8d4531c,
+ 0xd16bc204, 0xc7cc2f2b, 0xc26afb79, 0x347fe49c, 0xdae096fe, 0xd7ee17f1,
+ 0x1bdee074, 0xf0e333f2, 0xe9cfd8ed, 0xf05e917c, 0x2cbaefe1, 0xfd815d42,
+ 0x32df0499, 0xbb7b3b8c, 0x293e4922, 0xca1a08e7, 0x632affb9, 0xb2a6180c,
+ 0xe7f72c7e, 0x38eaf543, 0x0e8a405d, 0xb1811392, 0xd8af5429, 0xde57cfc0,
+ 0xfd24e119, 0xedc4c436, 0x6e2621f5, 0x75d10faf, 0x85dfa32e, 0x7df02418,
+ 0x6997ac8e, 0x9d6d60ff, 0x0417f685, 0xe10e957b, 0x955076b1, 0x887de90e,
+ 0xfd032db5, 0x8c5f353a, 0xec7b33df, 0x478b5283, 0x8cece387, 0x047d9417,
+ 0x74cb4fae, 0x90747d56, 0x996c657e, 0x3dea7e66, 0x7e7d9fcc, 0xa59f9856,
+ 0xef807e67, 0x75ff6c28, 0x86ec93ae, 0xf7f532a4, 0x2e49ea1a, 0x12fcf0a8,
+ 0x7018bde8, 0x816c7745, 0x1db66a6e, 0x96b2ff22, 0x76c4afb5, 0x1d7c91a5,
+ 0xbefe06a5, 0x4f186951, 0xfcb8e375, 0xa5d2512a, 0xc3f6b4e3, 0x7eb27191,
+ 0xc63ba41c, 0xf2e34db9, 0x79953f68, 0x6f0d7d61, 0x43d677f3, 0x13943ee5,
+ 0x7c0d7d3d, 0x466ff288, 0xd54d60bd, 0xbf9c69d8, 0x6ea2f116, 0xf6f85a3e,
+ 0xea27c493, 0xc66acc39, 0xa3667bf9, 0xc41a9ad9, 0xdf908b17, 0xc377ded0,
+ 0x138c7cbf, 0xeb6abff0, 0xe9973a7c, 0xa2b58c69, 0xfa48b75f, 0x7e25f692,
+ 0xda2ddf2c, 0xcdfbcdaf, 0x11fdfe9c, 0x1949f902, 0x0de3bae3, 0x0a498fc4,
+ 0x08f76c7f, 0xfb600e74, 0xcf1e3a77, 0x7e2810ab, 0x36143377, 0x624994da,
+ 0xba22eabd, 0xe333724f, 0x4b596347, 0x3dbbf28c, 0x796fb431, 0x9beeb293,
+ 0x2843fe75, 0xdbea8e57, 0x749e3192, 0xc4e4d6b4, 0x1b59cbfe, 0xc15a6fbd,
+ 0x153d29da, 0x9fa2f75e, 0x2226f73a, 0x63c9fddd, 0xf6d678a4, 0x50223be5,
+ 0xe5b167be, 0x044fdc56, 0xb7c6ec50, 0x73b3fb01, 0xd51df742, 0x2f60c4fb,
+ 0x027d21c7, 0x1d2127fe, 0xd8dc079c, 0x5fb77a73, 0x2317c7f8, 0x2c5f7f11,
+ 0x5b96e179, 0x9d5ffa19, 0xa82d47e4, 0x5df7465f, 0x33da9c81, 0xaaf07bf2,
+ 0x5bc55de2, 0xf01d5e37, 0xb0af182f, 0x938404a6, 0xc91965f4, 0xe8917fa5,
+ 0xf0e5d69c, 0xbc7dc2aa, 0x0e3b9f82, 0x8a15f970, 0xb70f156f, 0x43f5bbe2,
+ 0x236eef49, 0xc923313c, 0xb87a50cb, 0x3080be1c, 0xc4d93ce9, 0xa1f92318,
+ 0x4f2e4583, 0x2813cf07, 0xf33b795e, 0xf48012bc, 0xf5f7f096, 0xc70adefc,
+ 0xb782855b, 0x2fdf313f, 0x71ff9232, 0xce323b78, 0x606e34dd, 0xe50dbe6f,
+ 0xb2f8fed3, 0x37fce1c6, 0x18fa5f55, 0x3f0863f2, 0x376bf087, 0x2ff09d1e,
+ 0xc69e8f08, 0x6ecbe248, 0xae7b4b7c, 0x7fe22f4c, 0x5fb58e30, 0xaf93f9f0,
+ 0x46055f80, 0xf8f8bfbf, 0x54dead38, 0xa5c2a6f1, 0x07e0b8bf, 0x2ad47fcc,
+ 0xe70abed0, 0x748dbbe3, 0x57dd43ff, 0x5e4ff751, 0x5cf5c719, 0xd801fa68,
+ 0xb55fb84b, 0x40e4e326, 0x194f33b4, 0xfef87ed4, 0xdacb07ef, 0xb6f7f113,
+ 0xe9e2283e, 0xddff0329, 0x872f350f, 0x07e4b8f1, 0xc22f46f1, 0xf86103e9,
+ 0x1f33d404, 0xcf5cf708, 0x070671f3, 0x26e3cbe6, 0x53903de0, 0x798e357a,
+ 0xf07f12bf, 0x8f9479f1, 0x027aa62c, 0x074a5dff, 0xf61ddefe, 0x1736082b,
+ 0xbb83e7cc, 0x9d7de8d2, 0x718d7dee, 0x467f0edc, 0xdc774759, 0xe2815eff,
+ 0x355133fe, 0x84c4fee1, 0x877c2e2d, 0x437df4f3, 0xb4df69b3, 0xea3e3b41,
+ 0x978a64fd, 0xfee7e06e, 0xabea752e, 0xb75bf482, 0xc8be2dbe, 0xd1e4e7cb,
+ 0xbfa88cef, 0x86db2747, 0xc7dcff73, 0xd550df7f, 0x5fc75d67, 0x73c704b0,
+ 0xdfe2533f, 0x0fe1f9dd, 0xc3eb0526, 0x4dad4f43, 0x0daa7ec7, 0x05a72cde,
+ 0xb1ee877f, 0xaa5bb424, 0x4e955a9f, 0x0f53f4f6, 0x545fa3a4, 0xba6d63bd,
+ 0x0f70f94c, 0xbe3a65f9, 0x1b9e2fee, 0xd4f3e745, 0xdccaf6fe, 0x1d30a8af,
+ 0x3dbd412a, 0x56afeae5, 0xda41fee0, 0xffc5027d, 0x15f6b066, 0x332b67a8,
+ 0x16b15f38, 0xe87fc913, 0x776bf68f, 0x4ec5ff0d, 0x646f0794, 0x81cfd59c,
+ 0x203e127a, 0xd5df1035, 0xdfa3adf2, 0x7fcd5c09, 0x7ea7b027, 0x56ffed22,
+ 0x9de8172d, 0xfcf519ab, 0xf1a4f377, 0x59c704d1, 0xd18fb3ab, 0x794b57fb,
+ 0x6fa314f9, 0x67ec49df, 0x3fdf818b, 0xe094ee64, 0xb29270fb, 0x9d73385f,
+ 0xca717bf2, 0x639b6938, 0x53af07b7, 0x591df652, 0xdf2477ea, 0x32f0506e,
+ 0x5789e975, 0x54efd0ed, 0x1e3cc7bd, 0xe9b3bfbe, 0x619faa5c, 0x3a33f41c,
+ 0xf066985f, 0xd71f3a3c, 0x7148c3bd, 0xc1acdcd2, 0xcfd41c52, 0x11b45259,
+ 0xab4b99d3, 0x728f9d1e, 0xcd94d5b8, 0xf9f2358f, 0x114e0835, 0xed91f4e5,
+ 0xb842ceb7, 0x7fc4df9d, 0xfb61abff, 0xc2ddfa30, 0xafdee4fe, 0xf9eff89a,
+ 0xa264dd3d, 0x2b26d9f4, 0xcfeba3c3, 0xff29d935, 0x4a0e4daf, 0xcd3cf4d9,
+ 0xd7f4d8ef, 0xe14b88df, 0xb973bbf4, 0x3bf4cdab, 0x39460d88, 0x2bc03c75,
+ 0x1ddaaaed, 0xc2eb280f, 0xbdb2b8f7, 0x0e1113c9, 0x3e2c0fb9, 0x75b3a686,
+ 0x7d97df3c, 0x24eae4f3, 0x2c77d614, 0x7cc4f33d, 0x78fb7ef8, 0x270835f7,
+ 0x148bb6d3, 0x607238a7, 0xbbc22555, 0xaf91877a, 0xf9f7594f, 0x8f71e94d,
+ 0x75f97c62, 0x160dc53d, 0xc4f33b6d, 0x877f0c03, 0x9821b177, 0xbd74afde,
+ 0x7ee78f57, 0xaaf8e5e6, 0x78fc383f, 0x449b5abe, 0xf803b3fc, 0xf3a7f32a,
+ 0xcba5a2d5, 0xc6cb7e08, 0xb8426fbb, 0x937bd79d, 0x0fce9f90, 0xee744b1f,
+ 0xf820457d, 0xdbbc72ab, 0xbfe056af, 0x575b6c50, 0xc723dc98, 0x04b961bf,
+ 0x3e0743df, 0xf9fb474d, 0x3fe5fd9b, 0x6097eeb8, 0x1861fedd, 0x1a5133af,
+ 0xe0df3dfa, 0xf584ea19, 0x3ef3f7e5, 0x6af1d2e8, 0x539f9ffc, 0x36213fc0,
+ 0xe6219df8, 0xd4f9828d, 0x61fc141c, 0x26cfa859, 0xbf43a67d, 0x8fcffc11,
+ 0x198ce734, 0x9f4828fb, 0xcbdf37f7, 0x4fd875a5, 0x1ddc8f5a, 0xfcc89ef9,
+ 0x547b7a41, 0x83f98c20, 0x73f6edc6, 0xfb40cca0, 0x1724f14e, 0x2e786f10,
+ 0xe181c2ec, 0x99ff303b, 0xc2f1e381, 0xf14f604b, 0xf2931078, 0xd9f9d67b,
+ 0x50b22f81, 0xb7ae86ce, 0x882fe5ee, 0xaff66a3e, 0xfad028ba, 0xcba67f27,
+ 0x0ffafcba, 0x1645f53d, 0x7d33efe2, 0xb6fd1f20, 0x1640860b, 0xb7eea1e2,
+ 0x58ff9e5c, 0xf3e5a838, 0xf7e81b57, 0x1304eb3a, 0xf48949d1, 0x2e1fc525,
+ 0x87f1e71c, 0x924f03ba, 0xc83aed3c, 0xc48b40e3, 0x8c38d2f6, 0x399fd49b,
+ 0xcbacf286, 0xe831fdce, 0x2b71de9f, 0x41e8aa1c, 0xde12675d, 0x4dd83bf7,
+ 0x3c8fdc0f, 0x0c3bfc8f, 0xf3a369fb, 0x9c2b2cbd, 0x39f15da1, 0x7c30f3f2,
+ 0x257930bf, 0xdf79f9d2, 0x8f941cc0, 0xadfd666f, 0xbf86e28e, 0xb27ba70f,
+ 0xe6926db5, 0x3af7799c, 0x703f127c, 0x29fb54c4, 0xe7c1c99c, 0x1b8e0cb9,
+ 0x837e6ec8, 0xba2e13ef, 0x7b13f38a, 0xed53f399, 0x7b0643f2, 0x15bb7f50,
+ 0xc8ed527e, 0x1bffbf29, 0x85b3e5f1, 0xd504fd32, 0xffc7a54f, 0x4cf7fe9f,
+ 0x33412fff, 0x800063ec, 0x00008000, 0x00088b1f, 0x00000000, 0x5aa5ff00,
+ 0x5554700d, 0xbdef3e96, 0xdd2749fe, 0x12421349, 0x42068408, 0x03621a88,
+ 0xc4d67281, 0x206efce9, 0x6b01bb33, 0x8d08c42d, 0x749d2422, 0x6aece882,
+ 0x021a6eb9, 0x367564ac, 0x1d47598c, 0x809f9b47, 0x9476ec28, 0x0da0c040,
+ 0x6ba2cb0a, 0x3a26aa45, 0xab545b55, 0xa6e00eac, 0xd63b8223, 0x3be7b8e2,
+ 0x1dddb5ef, 0xa6ed4fe2, 0xee7dba8a, 0x9ee7b9cf, 0xce77ce7b, 0x52b48f3d,
+ 0x6a22ca22, 0x2a08cdcf, 0x6ea6ff0a, 0x6d4445a2, 0xf67f2429, 0xaf1f4541,
+ 0x7dbc64d3, 0x58c9a340, 0xce08eb93, 0x4754419e, 0x459a26dd, 0x654284b4,
+ 0x29bf71a4, 0x795bcbf2, 0x6d0dfebc, 0x61931741, 0xb06aad1b, 0x7aa6d513,
+ 0x1314360b, 0xaacaab0d, 0x0bcc6286, 0x4b9d2e95, 0x7efe0df4, 0x879b744a,
+ 0x2a224f99, 0xf60f14d3, 0x169c9d1b, 0x8b5dc9dc, 0x491bfb97, 0xeaa7984d,
+ 0x534f98f3, 0xa3827c08, 0xd81d4b25, 0x9964b468, 0x8eef3e23, 0x07d6d237,
+ 0xd2a14e31, 0xf9f6123b, 0x68858f4b, 0xcb17d121, 0x650faa17, 0xdaae79f2,
+ 0x51337403, 0x29ed768d, 0x70ddf785, 0x05564ccc, 0xafbc67fc, 0x670239f2,
+ 0xfa65ea34, 0x790a4752, 0x4bceccac, 0x1bcf0f1e, 0xd8293b99, 0x3f6fe7c5,
+ 0xe78990a0, 0xeeb11db5, 0x6d79e14c, 0x9bb648e6, 0xf036ddf7, 0xdb878b3b,
+ 0x2cf7fef6, 0xcf58b9ae, 0x9e433647, 0x6dfa1514, 0x174ff277, 0xce607f91,
+ 0x3f3177fb, 0xf44d69ff, 0x67bd37ed, 0x05d7d621, 0x5afd8f9e, 0x82d5f60e,
+ 0x56f0a56e, 0x3cfdda27, 0x9bbf48af, 0xe5dff86f, 0xb386575c, 0xf8be7e38,
+ 0xa7a25d39, 0x69f8bd18, 0xd602f73e, 0x43eb468b, 0x21ee5976, 0x6e717b96,
+ 0x252e8ece, 0x5fae9d71, 0x4b69768f, 0x9d15cb0e, 0x6615b8a9, 0x6c0d4d15,
+ 0x851f4276, 0x1797b38a, 0xb97f5f47, 0x9bf42d74, 0x9dbd2c12, 0x90b517cf,
+ 0xc7e2c7dc, 0x04b49bb6, 0x6a0f1679, 0x3443dc1e, 0xc90e9a95, 0xe2a77bbd,
+ 0x61bca83e, 0xd61267a9, 0x2b7bbe8d, 0x7955196f, 0x73fafdbd, 0x7975ca04,
+ 0xc9a9b0ce, 0xd7721b7d, 0x80ede5e7, 0xc400d9fe, 0xfaa94e8e, 0xc7951efe,
+ 0xbfd7c7e7, 0x46a79c68, 0xf089ce2b, 0x9dc506f8, 0x9f671ce3, 0xf587bb58,
+ 0xe9ef86be, 0xb46fbe45, 0x6938752f, 0xfda26ccd, 0xff42b91d, 0xda4b8773,
+ 0xf4914750, 0x16e1d2bf, 0x2dc760fa, 0xf0ea1f42, 0x51d03d08, 0x8ed1ed27,
+ 0x033fe906, 0x708cff51, 0xe2ec20a0, 0x4a6d7c14, 0x1cce1e9c, 0x9e494f43,
+ 0x24a99c3f, 0x991453d3, 0x3cb870ff, 0xa5fa6018, 0x939ca732, 0xc0d1ca8d,
+ 0x4b4e68fa, 0xb40ca12f, 0x674a41f9, 0x037bb1bb, 0x3ffbb61e, 0x43daedd4,
+ 0x4bcfc533, 0xf33aaf30, 0xdbf846ce, 0x692b2ce5, 0x1ec3cfac, 0xde63dfef,
+ 0x0555d3e9, 0x683fd1db, 0xfef95b73, 0x94dc5787, 0xff47bd01, 0xb78d234d,
+ 0xb05a28ae, 0x0ae994b9, 0xcc7622bb, 0xc86e6efc, 0x4fc6bb66, 0xb83553e6,
+ 0xe3a4d4ba, 0x02b67384, 0xc1aeb7fd, 0xdb261b3e, 0xfc795816, 0x57f7b94a,
+ 0xf7a627d8, 0x0aeb29da, 0xd98bd0bc, 0xf3cabef5, 0xa66eff02, 0x80f79e5e,
+ 0xdf649dc3, 0x822bcb47, 0x45c59bb0, 0x07cf36b3, 0xd9ba767f, 0xf5bb3fbc,
+ 0x51e7c87e, 0xc14e94d3, 0xb8099731, 0xf3fdc410, 0x452e953e, 0x716c30ec,
+ 0x7f993299, 0x2b22b538, 0x194eebc0, 0xb8da7df7, 0x7dc633ef, 0xd5fdc3bf,
+ 0xfdcbbedc, 0x1fb88768, 0x9e988aed, 0xd085a34d, 0x0da7f05f, 0xef44792f,
+ 0xa3a0f9a3, 0x3b0e5a66, 0xd33f025c, 0x81bf27f1, 0x5ca278e5, 0x036ee397,
+ 0x6b6e867f, 0x85d7d3e8, 0x858b4f84, 0x4bffb0bc, 0x9f609f58, 0xf5f175b1,
+ 0x9bb2ed24, 0xe7c29029, 0x20b6c3a0, 0x895344f4, 0x0ecb5f80, 0x692e08e7,
+ 0xcf8ab329, 0x017a644f, 0xabd29e09, 0xae5e7d56, 0x85fc216b, 0x8cfb2475,
+ 0x9980d504, 0x399fc4ed, 0xf2c99854, 0x167e188e, 0x49fd0fa3, 0xcff6fc13,
+ 0xd7db9a67, 0xfe7cfd14, 0x13854365, 0xa9b15eb0, 0x4eff33b0, 0xe1acfc7d,
+ 0x0699fe87, 0x943ce33f, 0x7dc7ca12, 0xce1d8f44, 0x2ee987bf, 0x1ead787b,
+ 0x8285c207, 0x5c2e14df, 0x42549c06, 0xd44dc8e7, 0xaf7dfc77, 0x47d027e9,
+ 0xfdd079e8, 0xd3af7fc7, 0x6739df4a, 0x50a4f8e2, 0xfd04e2be, 0x3df74181,
+ 0x409dc13f, 0x87395f9b, 0xdfa6cb71, 0x3327ab7b, 0xa783586e, 0xff37603b,
+ 0xed97dba2, 0xd027ff40, 0x2b11cb5b, 0x0f2b2ec1, 0x0af67ff4, 0x3bf4b78f,
+ 0xa8fb80dc, 0xbbe88667, 0xc7dec8f3, 0x7d236f61, 0xae87f166, 0xfe7bbffd,
+ 0x25679911, 0x35bd5b98, 0xcfbc4a54, 0xe37fe3d1, 0xb49f6135, 0x6fd015d0,
+ 0x39179c57, 0xfeea27ea, 0xa9f1543d, 0xf5bd0037, 0xc46bf81f, 0x0a0cfab5,
+ 0x65e96ec0, 0xe46647be, 0x6a86f57b, 0xc771e12a, 0x6ff04ad0, 0x86eac97b,
+ 0xcd5efa9d, 0x5f1f84a9, 0xfb14ccf3, 0x3bb1be6b, 0x3d57711f, 0x23cf6fba,
+ 0x23679859, 0xc99edbc8, 0xf57ac476, 0xdd163b69, 0x6bb7f72f, 0xf7206fcf,
+ 0x64ed1b3e, 0x03cccd3e, 0x99ef35fb, 0xd1f00c1d, 0xe3fafb5e, 0x1a87b895,
+ 0xe83db9ed, 0xa6dbb2bf, 0x2d670f42, 0xf8728c9e, 0xbbb359e1, 0xba0ceb17,
+ 0x2ea27879, 0x56a45a4f, 0x3bab2fee, 0x37d7711f, 0x80bfe1f1, 0xf75af5dc,
+ 0x3ce2cff3, 0x3884ad7b, 0xeb1f6171, 0xe85dd78d, 0x2dc7cf35, 0x9873ec8f,
+ 0x94972f60, 0x82cf95ee, 0xef3eaf7f, 0xf45bad92, 0x439de819, 0x11e78fd8,
+ 0x6525f2e2, 0x85ff527b, 0x5e25bdde, 0x97c5dfd6, 0x09bd8bea, 0x17f31bf6,
+ 0x526b6edf, 0x6024147c, 0xbf19f25c, 0x3b2019c9, 0x8366dfc7, 0x99e878bc,
+ 0xbe296791, 0x737ee2fe, 0x6a3ac2d8, 0x94e6d2b6, 0xf83fb8cc, 0x0ebcfef2,
+ 0x3ba9f3e7, 0x34c7910a, 0x84ac882f, 0x51b05c5f, 0x7bcf2e4a, 0xbe5f88db,
+ 0x2a971b83, 0x4f2ddf25, 0xc7ee854d, 0x38f57357, 0x16c07576, 0x1ddf280c,
+ 0x83a3fe8f, 0x8eccef9c, 0x67af77d3, 0x7e71297e, 0xad425b6f, 0x2db7de6e,
+ 0x738fc753, 0xe33f7f3c, 0xcfb19558, 0xe79287aa, 0x299152df, 0x8966d3f6,
+ 0xc60e2214, 0x88ac2ff8, 0x10a45ae1, 0x5d763578, 0xe013d23d, 0xe08acbc8,
+ 0xf2a0ef88, 0xa86e96a1, 0x4fae3b34, 0xa8204a5f, 0x0f7f8c95, 0x7b8c8bb9,
+ 0x55ef5e60, 0xdbe57ee8, 0x98d8f36f, 0x246a4b4f, 0xab53791d, 0x7c8e9223,
+ 0x46a8e468, 0xcbeb8d3b, 0x199ff18a, 0x4649afdf, 0xf6643fb8, 0x8fdbc6d8,
+ 0x6f3c438f, 0x2ab37e1d, 0xfdd0a93e, 0x4d2069a6, 0x646723f6, 0xe9b6ec11,
+ 0x3875e4b9, 0x1fc133a7, 0x65760647, 0x8fe2137b, 0xaa3b90cf, 0x137e287c,
+ 0x7ca3fafd, 0xa54f81d8, 0xf6ab0acd, 0x65b1af22, 0x3a294d0a, 0xe5b1b01d,
+ 0xa7b4befb, 0x5e2e7ec2, 0x1e3f156d, 0x73822251, 0x0aae27b9, 0x23988c3e,
+ 0xca8e7382, 0x18fc11ff, 0x09591099, 0xb4adcadc, 0xc9f196af, 0x1e2e9591,
+ 0xa0c2b2ff, 0x03e491a7, 0x57322785, 0xb5ea4f03, 0x3711b7d1, 0x09d99769,
+ 0x7be9893f, 0xa227a19d, 0x783b86c7, 0xb3410ffc, 0x4e61f10b, 0x0be462a5,
+ 0xb5f9f896, 0x908d3fb8, 0xf841c0eb, 0xdddd9367, 0xfdc1a32b, 0xbc1f20af,
+ 0xe5dddb33, 0x326f5eba, 0xcacae587, 0xee2d6afc, 0xfbdd3b29, 0xdfcc158f,
+ 0x07c91c5f, 0x4bb5b1ce, 0xdd7b6a1c, 0x47fb13ba, 0x807ba3cd, 0xde1c175f,
+ 0x9f582b27, 0xada196ad, 0x67d22ca5, 0xa429c8e6, 0x6f604bf8, 0xbdba2382,
+ 0xb2ef148d, 0x561e9f08, 0x9767eb2a, 0x4b940f71, 0xa1f603b4, 0xe6fcf7e8,
+ 0x00efabc0, 0x6686466f, 0xf58f4e09, 0x4f030ba7, 0x3e3703a6, 0x981ef8e0,
+ 0x60ffef13, 0xfa0b5ef5, 0xc3b8bf97, 0x9ef6e112, 0xbbe7c9cd, 0x0cf6ed7c,
+ 0x9e3d0bf8, 0xec7b0fd0, 0xeac7a649, 0x4e197605, 0xe88083f2, 0x29c79cfd,
+ 0x0e54b7f2, 0xdf0f41b5, 0xd698cbd2, 0x6313e812, 0xa9f331e8, 0xce1fcf41,
+ 0xb6f84879, 0x430f0b4e, 0xcc07236f, 0xe4ef7c04, 0x7f7426b8, 0x1aef105a,
+ 0xadc700f5, 0x216e3d2c, 0x0fa4b45e, 0x8cbdc4ad, 0x989d5bf4, 0xa7c8e9bf,
+ 0xdb3f38f9, 0xdbce3e63, 0x3670e472, 0xf78dcec1, 0x6cc7c704, 0x1ff4b78c,
+ 0x24bbc6c9, 0x86aadfd6, 0x4717210a, 0x47e012b8, 0x85afdfac, 0x8b7f210b,
+ 0xf1825432, 0xf996e428, 0x49a06b4c, 0xe8aad1ce, 0x34474f7e, 0xf7b1f9c1,
+ 0x6e8551f6, 0x250f8caf, 0x1d3707c8, 0xb11254bd, 0xd9a0f1c7, 0xe81395c0,
+ 0xdffdd62f, 0x09c0c8b9, 0xbf0cda5e, 0xbc27071f, 0xf5a3dc31, 0xae7dc816,
+ 0xb63b9742, 0x3bcaf85e, 0x6de32023, 0x992a5daf, 0xc6758c59, 0xa3c04a3c,
+ 0x017c7159, 0x0e0ae40e, 0xf367326c, 0x2bcf7cb9, 0xd25e4eee, 0x96b1b8dc,
+ 0xd33ad3a7, 0x6bd0b5fd, 0x5de40513, 0xb1ae5637, 0x8570f476, 0x553ebf7e,
+ 0xf6fb8f7f, 0x964ec128, 0x7d6322eb, 0x9bc17cee, 0x5d67f030, 0xf85ac6f5,
+ 0x7e597ddf, 0xf9bbe24b, 0xedaff887, 0xadd7a649, 0x339b58df, 0x1efb9f8e,
+ 0x126a7eda, 0xd9afcf5d, 0xdb36a3bb, 0x4c7f7d75, 0x98b68bee, 0x49e6959c,
+ 0xbe58fa89, 0xb71276b1, 0xaffe52eb, 0x7dcfd0fa, 0x8c3588f1, 0xb5facbb8,
+ 0xfdb7fce0, 0x0925bd71, 0x5f807fb7, 0x9d6b0533, 0xfe5bbe33, 0x12ab6db1,
+ 0x4f80561e, 0xe2bd5fec, 0x0937ec67, 0x18aa6dfb, 0x5a68a753, 0x37791d3d,
+ 0x4f4f5779, 0x6d8c53ac, 0xa8a72819, 0x49bd88b7, 0xd2b87ecb, 0x623e8e3d,
+ 0xd4ae6ff3, 0x864d9f64, 0x6fa94f1d, 0x1e15e679, 0x53ccb97f, 0x557ec956,
+ 0xbf92a9ae, 0xa6a7dd8f, 0x860fcf52, 0x80bf1db2, 0xcd07453d, 0xb949f84e,
+ 0x4f33eba6, 0xfc2efcbd, 0xe1db2f31, 0x357e64ea, 0xbcfa6955, 0xea273663,
+ 0x5f63d140, 0xffe07be5, 0xa5cbec5b, 0xd3b262ce, 0x953f1e64, 0x3df0573b,
+ 0xc6c7cfb6, 0x7aa5693e, 0x645ed3be, 0x533afefe, 0x3adbe3b1, 0xc51be493,
+ 0x12d9c169, 0xf890bf87, 0xe85c1d16, 0xf7c05cd4, 0xd6fe1da0, 0x677ff5fe,
+ 0x0c8f0e23, 0x0bba67fe, 0xd3ed75b8, 0xb6cfd874, 0x81d38f81, 0x6606270f,
+ 0x1d9ed039, 0x1fd03972, 0x16b8fbad, 0x368cbaf3, 0x8b30675e, 0xf636b19c,
+ 0x13d58e7e, 0xcdd1de12, 0x73af6bd0, 0x614b2fdb, 0x82dda9ef, 0xce8efc63,
+ 0xd788fc44, 0xe3395c19, 0xeb1265d5, 0xf5b3050c, 0xd45a033a, 0x7acc0a19,
+ 0xea34019d, 0x6751680c, 0x0cea3f40, 0x006751a0, 0x68033a8d, 0xa2d019d4,
+ 0x2bfe80ce, 0xbcb16ba8, 0x50de4e51, 0xecd1aadf, 0xf40fff82, 0xf5e4416a,
+ 0x74d31c0f, 0xc412877a, 0xfbc67f7d, 0xaf460e23, 0x28b075e8, 0xe77953c7,
+ 0xfbcb341f, 0x5eda1a20, 0xd6f71337, 0x5571b9af, 0xd9371117, 0xa3cddb14,
+ 0x6a1f5127, 0x1bdc53ef, 0x2e5fe85d, 0x5c1b6c72, 0xfa237ef8, 0xd56ecd7b,
+ 0x9abafb85, 0x6f97fa8d, 0x58ea57b0, 0x2cc739d5, 0x15fbcf72, 0xeffde1ca,
+ 0x64efeab0, 0x2cbdc6bf, 0x9545b0f7, 0x1d6fda3c, 0xcb4bf792, 0x4d738a8b,
+ 0x7eda1e42, 0x1382e7cb, 0x9df4b69d, 0xb21fd790, 0xc524d739, 0x7de48f57,
+ 0xc174fc7e, 0x45433c8d, 0xa7d5af4c, 0x7b5edf90, 0xf9213801, 0xb47e4248,
+ 0x33fcd9d6, 0x5da467e4, 0x7efce133, 0x644ee87e, 0x6d3dd6f9, 0xb09228fe,
+ 0x9930737f, 0x6df60df6, 0x99c823cd, 0x034a8fdc, 0x943fb2e2, 0x74aa1fdc,
+ 0xc6927d64, 0x3cd1e63f, 0xff755be4, 0x3f40e6b4, 0xdbb977ef, 0x61caf92a,
+ 0x2570f78f, 0xb349f1fb, 0x272fea47, 0xbde4d98f, 0x9cfb7e75, 0x8d4bfaa4,
+ 0x1fea5536, 0xc48acc1b, 0xdee52bf1, 0xaacbb063, 0xeea57bba, 0x10eb9552,
+ 0xe1d98e7f, 0x3786f2d1, 0x5cc377c0, 0x6abfd497, 0xe10bf4ac, 0xf72f7ec7,
+ 0x7f16683c, 0x8254e9ab, 0xc9abd32a, 0xad7f816d, 0x3d8a7562, 0x298fed99,
+ 0x78ab0fec, 0xbb04c6af, 0x915db0da, 0x100a42bc, 0x8695e7ac, 0xfe0d573e,
+ 0xfb0a57eb, 0x3d56bdcb, 0x5553ce0f, 0xc5d79fe1, 0xdfe78b71, 0xfc0b5e47,
+ 0x55c71d66, 0x5f671cb4, 0x37bf708f, 0x9ebe6a6d, 0xc072bbe7, 0x3319f57f,
+ 0x726a4f01, 0x95e85e7e, 0xfced5f78, 0x095bef84, 0x737da5df, 0xa8e1f7d3,
+ 0xc8493e89, 0x759a4f6b, 0xca7d61fc, 0xec14eb7b, 0x5e3eea55, 0x3474cf69,
+ 0x8ca2bb49, 0x340bffc4, 0xe02f6f3d, 0x4a6672bb, 0xeb0fa2dd, 0x6eedda6b,
+ 0x0b863fe8, 0xbefc8dbb, 0xe796e540, 0x5bd54eed, 0xdc29d30b, 0xca5b8d3f,
+ 0xe7617e14, 0x5c71d47c, 0x3d4f3fc2, 0x7d05c0bb, 0x4377697c, 0xc739351f,
+ 0x31dde1e6, 0x72ffe0cb, 0xdc55c359, 0x029d2797, 0x438f9fd8, 0x5adfacdd,
+ 0x5d41481c, 0x50d1e43d, 0x38a63f27, 0x1ebfaef1, 0x716fb74f, 0x140acfc2,
+ 0xb5b7ea27, 0xd935dda9, 0xe676bfcc, 0x9cf0370c, 0x61ea55f1, 0x76eadc23,
+ 0x53506b70, 0x6ca6b5f4, 0xff0df3d4, 0x54a6f729, 0xd7f78a4d, 0x1d147e1b,
+ 0xf11d22fc, 0x6dd447f5, 0x807f8377, 0x835eee6c, 0xfea0ec3f, 0xbf5269a6,
+ 0xe5d1d98d, 0x613b39fd, 0xf4ab5347, 0xef8d8d75, 0x0c4f9199, 0xc1cde6dd,
+ 0x7cd72bfe, 0xce5b25be, 0x8cbd7e39, 0xb8033771, 0x165eb63b, 0x463df1c3,
+ 0x6b781dfd, 0x26baea32, 0x326baea3, 0xa326baea, 0xea326bae, 0xaea326ba,
+ 0xbaea326b, 0x6baea326, 0x26baea32, 0x97ae13a9, 0x878eddf6, 0x08ea1da4,
+ 0xbc4278c8, 0xc7eab9b8, 0x55175dd5, 0xa577538d, 0xc4865714, 0xbd7bf65d,
+ 0xcea63dde, 0x26aefeca, 0xe0d57bf8, 0x431e7b84, 0x7163d25e, 0x6b5438b3,
+ 0x603c16f1, 0x54f07c17, 0x8d6f5b8d, 0xf52ecfe9, 0x9b64cbd9, 0x2ca87b8f,
+ 0x5152659a, 0x23ee34c7, 0xdf84ef56, 0x1bf09ce0, 0xd31bf0b4, 0xfcdfb8ec,
+ 0x5daec2d6, 0x0109e7aa, 0x726c13c9, 0x32375bbf, 0x2f7d30ae, 0xe5709339,
+ 0xc2b831b3, 0x90159a0f, 0x95a0ed63, 0x233f74ba, 0x37254ff8, 0x0e3f9c7f,
+ 0x9c7484ce, 0xda1a9699, 0xb5a67d87, 0x1791baa5, 0x9d8bbfb3, 0x88a6dc9d,
+ 0x06a1afbf, 0xbc1c77d9, 0x7c9e4749, 0x73d1c4ef, 0xf7f9e1bf, 0xf25d83fe,
+ 0xd793ad9d, 0xe0fffa2e, 0xae954d4d, 0x84775f8f, 0x9659e77d, 0x43b654ea,
+ 0x16d5578e, 0xb8ba922a, 0x50fe2a9a, 0x58ae3da3, 0xd377a380, 0xb577dc3c,
+ 0xc839e1b5, 0x2efec399, 0xa32cdfef, 0x6a1a6bbe, 0xd9f4cbde, 0xbe373cec,
+ 0x3dcd4dab, 0x800b0544, 0xb0c57547, 0xadd4b3ab, 0x1963dd60, 0xbf83bfde,
+ 0xa7cc5edc, 0x96fee356, 0xb3b69753, 0xce63ee4b, 0x32fbdc42, 0xf51fabab,
+ 0x9e6f2d86, 0xb2c27a90, 0xd442d70c, 0x79bcb61b, 0x5c73a75a, 0xe51b8afd,
+ 0xabab13b2, 0x66f8827f, 0x109f3eeb, 0x09a1fd67, 0xc0fb7449, 0x09f3eee4,
+ 0x3f05ae71, 0x3f4e9df8, 0xafb84c53, 0x5c944356, 0xf21dbbd5, 0x4bfeebf9,
+ 0xa8d3cf7f, 0xaaa7c9c4, 0x749c5c74, 0xe7b0c282, 0xf90ec5d1, 0x713397fe,
+ 0xdbd43cfd, 0x10b5d8a8, 0xfdaf38f3, 0xe2f8ec35, 0xc1a79ead, 0x7738cf27,
+ 0x3579f10e, 0x0d90c758, 0xbbe319ed, 0xdbd529e4, 0x3d36b688, 0x357e9260,
+ 0x6df68a58, 0xfa20f435, 0x81762fd9, 0xf393ed4f, 0x3a622c6e, 0xb79a1acf,
+ 0xe9788ede, 0x73fe8dd9, 0xec5e9e65, 0xdfeeb637, 0xe58f9c69, 0xc37987d9,
+ 0xf9e4aa85, 0x6dea37c3, 0x55c22ecc, 0x371d0e3a, 0x93aca8fc, 0x58e7fbe4,
+ 0xa55e39fb, 0xfdf9781a, 0x47bcb372, 0x7e4c4f20, 0x0a5d5eea, 0xa3de5879,
+ 0x61afbc86, 0x5299ec9c, 0x7b6ef98f, 0xc77ec80d, 0x7c653b0d, 0xe3af396c,
+ 0xa685b4a3, 0x0de404e0, 0x4e0d1e53, 0x7653bc80, 0xdc5cda8c, 0xb51810be,
+ 0xe1787f21, 0xe86d476f, 0x7543c17f, 0x56bfe1e3, 0xc2df09ad, 0x3f5951b2,
+ 0x921af79d, 0x04e8c277, 0x4d856fe4, 0x6c02596f, 0xe69e73b7, 0xb7f2937d,
+ 0xd3638922, 0xfe9a5b0d, 0x87b04aa8, 0xe490cfe9, 0x259d54ab, 0xdd14bee3,
+ 0x3e8f7dff, 0x6e8ec2a8, 0x09dcb208, 0x69e737f6, 0x1248e5d3, 0x6bacb0df,
+ 0xf3837031, 0x3f71a4b5, 0x3cbe4733, 0xe423c0c5, 0x378c8d8f, 0xbeb7a6fe,
+ 0x79c8be42, 0x8c7e18dc, 0x261c314d, 0xebef5dc4, 0x20fc1711, 0xbbdade79,
+ 0xf78ad91e, 0x76e3536d, 0xd78fbc8b, 0xdb456df4, 0x259efada, 0x4cbf2487,
+ 0x65f9cf9a, 0x9c9d7d12, 0x7b68e463, 0x39adf3f0, 0x76cbece3, 0x0ed12d70,
+ 0x37439a4e, 0xd27abde0, 0x480eea9f, 0x0fdd091c, 0x6ad9d97c, 0xecae2377,
+ 0xd8a555fa, 0xa9f5b7d7, 0xfaa98f32, 0xa751d947, 0x52540fcc, 0x87e6fc11,
+ 0xe1e011da, 0x0c3c24ec, 0x8972dd48, 0xddae7043, 0xadb60778, 0x123e4a71,
+ 0x5336ebf3, 0x98adc3e8, 0xef90e597, 0x45b70c11, 0x6f7c2ca6, 0x4aeee29a,
+ 0x2ece2bc8, 0x9d041599, 0x830a19dd, 0x15cfe8ef, 0xd5c8ea37, 0xd6ae3a69,
+ 0x7bad0da8, 0x352dfc79, 0x5bf1b82c, 0x6ff307e0, 0x7697acb7, 0xb14cd945,
+ 0x290a5cdb, 0x7067fffa, 0x3d7bc42d, 0x67ad3df6, 0x20efb05b, 0xf04afbde,
+ 0x8fa8b599, 0xe45d95fe, 0x80d50689, 0x33d3cf99, 0x7bb70481, 0xb8942cee,
+ 0xc686a513, 0x2cff91fb, 0x6a3a954f, 0x13d704cf, 0xd3da6ef8, 0xf5e4a37c,
+ 0xc7a4fe87, 0x29a5d1fb, 0x3d71e46e, 0x711b5cf3, 0x5d479eae, 0xa29afe32,
+ 0xa13c0bf3, 0xa967a7eb, 0xe69ece7e, 0xc59f794c, 0x8767a1ee, 0xbfbe3267,
+ 0xe5bc3259, 0x1803a8d5, 0x667b1fdf, 0x4fb73f70, 0xde770d29, 0x75733e07,
+ 0xb9945779, 0xde4edee4, 0x7b13e379, 0xf1867d74, 0x897dac1d, 0xfefde923,
+ 0xcb80febf, 0x002220b3, 0x00000000
};
#endif /*__BNX2X_INIT_VALUES_H__*/
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c
index aea26b4dc453..ed648acef7cf 100644
--- a/drivers/net/bnx2x_link.c
+++ b/drivers/net/bnx2x_link.c
@@ -22,14 +22,9 @@
#include <linux/ethtool.h>
#include <linux/mutex.h>
-#include "bnx2x_reg.h"
-#include "bnx2x_fw_defs.h"
-#include "bnx2x_hsi.h"
-#include "bnx2x_link.h"
#include "bnx2x.h"
/********************************************************/
-#define SUPPORT_CL73 0 /* Currently no */
#define ETH_HLEN 14
#define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
#define ETH_MIN_PACKET_SIZE 60
@@ -139,6 +134,26 @@
#define PHY_SGMII_FLAG 0x2
#define PHY_SERDES_FLAG 0x4
+/* */
+#define SFP_EEPROM_CON_TYPE_ADDR 0x2
+ #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
+ #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
+
+#define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
+ #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
+ #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
+#define SFP_EEPROM_VENDOR_NAME_ADDR 0x14
+#define SFP_EEPROM_VENDOR_NAME_SIZE 16
+#define SFP_EEPROM_OPTIONS_ADDR 0x40
+ #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
+#define SFP_EEPROM_OPTIONS_SIZE 2
+
+#define SFP_MODULE_TYPE_UNKNOWN 0x0
+#define SFP_MODULE_TYPE_LC 0x1
+#define SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE 0x2
+#define SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE 0x3
+
+#define SFP_LIMITING_MODE_VALUE 0x0044
/**********************************************************/
/* INTERFACE */
/**********************************************************/
@@ -154,13 +169,34 @@
(_bank + (_addr & 0xf)), \
_val)
-static void bnx2x_set_phy_mdio(struct link_params *params)
+static void bnx2x_set_serdes_access(struct link_params *params)
{
struct bnx2x *bp = params->bp;
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
- params->port*0x18, 0);
- REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
- DEFAULT_PHY_DEV_ADDR);
+ u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+ /* Set Clause 22 */
+ REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
+ udelay(500);
+ REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
+ udelay(500);
+ /* Set Clause 45 */
+ REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0);
+}
+static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
+{
+ struct bnx2x *bp = params->bp;
+ if (phy_flags & PHY_XGXS_FLAG) {
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
+ params->port*0x18, 0);
+ REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
+ DEFAULT_PHY_DEV_ADDR);
+ } else {
+ bnx2x_set_serdes_access(params);
+
+ REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
+ params->port*0x10,
+ DEFAULT_PHY_DEV_ADDR);
+ }
}
static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
@@ -277,8 +313,10 @@ static u8 bnx2x_emac_enable(struct link_params *params,
port*4, 0);
}
- /* enable emac */
- REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
+ bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
+ EMAC_RX_MODE_RESET);
+ bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
+ EMAC_TX_MODE_RESET);
if (CHIP_REV_IS_SLOW(bp)) {
/* config GMII mode */
@@ -498,7 +536,7 @@ static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
udelay(500);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
val);
- bnx2x_set_phy_mdio(params);
+ bnx2x_set_phy_mdio(params, phy_flags);
}
void bnx2x_link_status_update(struct link_params *params,
@@ -749,12 +787,17 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
return 0;
}
-static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
+static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
{
u32 emac_base;
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- emac_base = GRCBASE_EMAC0;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ /* All MDC/MDIO is directed through single EMAC */
+ if (REG_RD(bp, NIG_REG_PORT_SWAP))
+ emac_base = GRCBASE_EMAC0;
+ else
+ emac_base = GRCBASE_EMAC1;
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
@@ -772,11 +815,12 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
{
u32 tmp, saved_mode;
u8 i, rc = 0;
- u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
+ u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
/* set clause 45 mode, slow down the MDIO clock to 2.5MHz
* (a value of 49==0x31) and make sure that the AUTO poll is off
*/
+
saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
EMAC_MDIO_MODE_CLOCK_CNT);
@@ -841,10 +885,11 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
u16 i;
u8 rc = 0;
- u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
+ u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
/* set clause 45 mode, slow down the MDIO clock to 2.5MHz
* (a value of 49==0x31) and make sure that the AUTO poll is off
*/
+
saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
EMAC_MDIO_MODE_CLOCK_CNT));
@@ -967,6 +1012,8 @@ static u8 bnx2x_reset_unicore(struct link_params *params)
(mii_control |
MDIO_COMBO_IEEO_MII_CONTROL_RESET));
+ bnx2x_set_serdes_access(params);
+
/* wait for the reset to self clear */
for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
udelay(5);
@@ -1156,62 +1203,9 @@ static void bnx2x_set_autoneg(struct link_params *params,
MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
reg_val);
- /* Enable Clause 73 Aneg */
- if ((vars->line_speed == SPEED_AUTO_NEG) &&
- (SUPPORT_CL73)) {
- /* Enable BAM Station Manager */
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_USERB0,
- MDIO_CL73_USERB0_CL73_BAM_CTRL1,
- (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
- MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
- MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
-
- /* Merge CL73 and CL37 aneg resolution */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_USERB0,
- MDIO_CL73_USERB0_CL73_BAM_CTRL3,
- &reg_val);
-
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_USERB0,
- MDIO_CL73_USERB0_CL73_BAM_CTRL3,
- (reg_val |
- MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
+ /* CL73 Autoneg Disabled */
+ reg_val = 0;
- /* Set the CL73 AN speed */
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_IEEEB1,
- MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
- /* In the SerDes we support only the 1G.
- In the XGXS we support the 10G KX4
- but we currently do not support the KR */
- if (vars->phy_flags & PHY_XGXS_FLAG) {
- DP(NETIF_MSG_LINK, "XGXS\n");
- /* 10G KX4 */
- reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
- } else {
- DP(NETIF_MSG_LINK, "SerDes\n");
- /* 1000M KX */
- reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
- }
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_IEEEB1,
- MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
-
- /* CL73 Autoneg Enabled */
- reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
- } else {
- /* CL73 Autoneg Disabled */
- reg_val = 0;
- }
CL45_WR_OVER_CL22(bp, params->port,
params->phy_addr,
MDIO_REG_BANK_CL73_IEEEB0,
@@ -1344,44 +1338,25 @@ static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
static void bnx2x_restart_autoneg(struct link_params *params)
{
struct bnx2x *bp = params->bp;
+ u16 mii_control;
DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
- if (SUPPORT_CL73) {
- /* enable and restart clause 73 aneg */
- u16 an_ctrl;
-
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_IEEEB0,
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
- &an_ctrl);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_CL73_IEEEB0,
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
- (an_ctrl |
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
- MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
-
- } else {
- /* Enable and restart BAM/CL37 aneg */
- u16 mii_control;
+ /* Enable and restart BAM/CL37 aneg */
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- &mii_control);
- DP(NETIF_MSG_LINK,
- "bnx2x_restart_autoneg mii_control before = 0x%x\n",
- mii_control);
- CL45_WR_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_COMBO_IEEE0,
- MDIO_COMBO_IEEE0_MII_CONTROL,
- (mii_control |
- MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
- MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
- }
+ CL45_RD_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL,
+ &mii_control);
+ DP(NETIF_MSG_LINK,
+ "bnx2x_restart_autoneg mii_control before = 0x%x\n",
+ mii_control);
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ MDIO_REG_BANK_COMBO_IEEE0,
+ MDIO_COMBO_IEEE0_MII_CONTROL,
+ (mii_control |
+ MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
+ MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
}
static void bnx2x_initialize_sgmii_process(struct link_params *params,
@@ -1726,7 +1701,11 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
(XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
+ (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
+ (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481))) {
vars->autoneg = AUTO_NEG_ENABLED;
if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
@@ -1770,38 +1749,44 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
return rc;
}
-static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
+static void bnx2x_set_gmii_tx_driver(struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 lp_up2;
u16 tx_driver;
+ u16 bank;
/* read precomp */
-
CL45_RD_OVER_CL22(bp, params->port,
params->phy_addr,
MDIO_REG_BANK_OVER_1G,
MDIO_OVER_1G_LP_UP2, &lp_up2);
- CL45_RD_OVER_CL22(bp, params->port,
- params->phy_addr,
- MDIO_REG_BANK_TX0,
- MDIO_TX0_TX_DRIVER, &tx_driver);
-
/* bits [10:7] at lp_up2, positioned at [15:12] */
lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
- if ((lp_up2 != 0) &&
- (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
- /* replace tx_driver bits [15:12] */
- tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
- tx_driver |= lp_up2;
- CL45_WR_OVER_CL22(bp, params->port,
+ if (lp_up2 == 0)
+ return;
+
+ for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
+ bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
+ CL45_RD_OVER_CL22(bp, params->port,
params->phy_addr,
- MDIO_REG_BANK_TX0,
- MDIO_TX0_TX_DRIVER, tx_driver);
+ bank,
+ MDIO_TX0_TX_DRIVER, &tx_driver);
+
+ /* replace tx_driver bits [15:12] */
+ if (lp_up2 !=
+ (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
+ tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
+ tx_driver |= lp_up2;
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ bank,
+ MDIO_TX0_TX_DRIVER, tx_driver);
+ }
}
}
@@ -1902,6 +1887,25 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL, 0xa040);
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH,
+ params->port);
+
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH,
+ params->port);
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL,
+ 1<<15);
+
+ break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
/* Unset Low Power Mode and SW reset */
/* Restore normal power mode*/
@@ -1919,9 +1923,6 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
{
- u16 emac_base;
- emac_base = (params->port) ? GRCBASE_EMAC0 :
- GRCBASE_EMAC1;
/* Restore normal power mode*/
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
@@ -1949,6 +1950,23 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+
+ /* Restore normal power mode*/
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_HIGH,
+ params->port);
+
+ /* HW reset */
+ bnx2x_hw_reset(bp, params->port);
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL,
+ 1<<15);
+ break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
break;
@@ -1980,6 +1998,31 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
}
}
+
+static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
+ u32 shmem_base, u32 spirom_ver)
+{
+ DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n",
+ (u16)(spirom_ver>>16), (u16)spirom_ver);
+ REG_WR(bp, shmem_base +
+ offsetof(struct shmem_region,
+ port_mb[port].ext_phy_fw_version),
+ spirom_ver);
+}
+
+static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
+ u32 ext_phy_type, u8 ext_phy_addr,
+ u32 shmem_base)
+{
+ u16 fw_ver1, fw_ver2;
+ bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER1, &fw_ver1);
+ bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER2, &fw_ver2);
+ bnx2x_save_spirom_version(bp, port, shmem_base,
+ (u32)(fw_ver1<<16 | fw_ver2));
+}
+
static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
{
struct bnx2x *bp = params->bp;
@@ -1988,7 +2031,6 @@ static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- u16 fw_ver1, fw_ver2;
/* Need to wait 200ms after reset */
msleep(200);
@@ -2024,14 +2066,10 @@ static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
/* Wait 100ms */
msleep(100);
- /* Print the PHY FW version */
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &fw_ver1);
- bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2, &fw_ver2);
- DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
+ bnx2x_save_bcm_spirom_ver(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ params->shmem_base);
}
static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
@@ -2049,7 +2087,7 @@ static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xc801, &val);
+ MDIO_PMA_REG_8073_CHIP_REV, &val);
if (val != 1) {
/* No need to workaround in 8073 A1 */
@@ -2081,7 +2119,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xc801, &val);
+ MDIO_PMA_REG_8073_CHIP_REV, &val);
if (val > 0) {
/* No need to workaround in 8073 A1 */
@@ -2097,7 +2135,8 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xc820, &val);
+ MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
+ &val);
/* If bit [14] = 0 or bit [13] = 0, continue on with
system initialization (XAUI work-around not required,
as these bits indicate 2.5G or 1G link up). */
@@ -2115,7 +2154,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xc841, &val);
+ MDIO_PMA_REG_8073_XAUI_WA, &val);
if (val & (1<<15)) {
DP(NETIF_MSG_LINK,
"XAUI workaround has completed\n");
@@ -2133,9 +2172,8 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
}
static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
- u8 ext_phy_addr)
+ u8 ext_phy_addr, u32 shmem_base)
{
- u16 fw_ver1, fw_ver2;
/* Boot port from external ROM */
/* EDC grst */
bnx2x_cl45_write(bp, port,
@@ -2185,17 +2223,496 @@ static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_MISC_CTRL1, 0x0000);
- bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ bnx2x_save_bcm_spirom_ver(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ ext_phy_addr,
+ shmem_base);
+}
+
+static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
+ /* Need to wait 100ms after reset */
+ msleep(100);
+
+ /* Set serial boot control for external load */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0001);
+
+ /* Micro controller re-boot */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+
+ /* Set soft reset */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
+
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL2,
+ 0x73A0);
+
+ /* Clear soft reset.
+ Will automatically reset micro-controller re-boot */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL,
+ MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
+
+ /* wait for 150ms for microcode load */
+ msleep(150);
+
+ /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
+ bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL1, 0x0000);
+
+ msleep(200);
+ bnx2x_save_bcm_spirom_ver(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ params->shmem_base);
+}
+
+static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
+ u8 ext_phy_addr, u8 tx_en)
+{
+ u16 val;
+ DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
+ tx_en, port);
+ /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
+ bnx2x_cl45_read(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
ext_phy_addr,
MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &fw_ver1);
+ MDIO_PMA_REG_PHY_IDENTIFIER,
+ &val);
+
+ if (tx_en)
+ val &= ~(1<<15);
+ else
+ val |= (1<<15);
+
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_PHY_IDENTIFIER,
+ val);
+}
+
+
+static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
+ u8 byte_cnt, u8 *o_buf) {
+ struct bnx2x *bp = params->bp;
+ u16 val, i;
+ u8 port = params->port;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+ if (byte_cnt > 16) {
+ DP(NETIF_MSG_LINK, "Reading from eeprom is"
+ " is limited to 0xf\n");
+ return -EINVAL;
+ }
+ /* Set the read command byte count */
+ bnx2x_cl45_write(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
+ (byte_cnt | 0xa000));
+
+ /* Set the read command address */
+ bnx2x_cl45_write(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
+ addr);
+
+ /* Activate read command */
+ bnx2x_cl45_write(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
+ 0x2c0f);
+
+ /* Wait up to 500us for command complete status */
+ for (i = 0; i < 100; i++) {
+ bnx2x_cl45_read(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
+ if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
+ MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
+ break;
+ udelay(5);
+ }
+
+ if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
+ MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
+ DP(NETIF_MSG_LINK,
+ "Got bad status 0x%x when reading from SFP+ EEPROM\n",
+ (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
+ return -EINVAL;
+ }
+
+ /* Read the buffer */
+ for (i = 0; i < byte_cnt; i++) {
+ bnx2x_cl45_read(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
+ o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
+ }
+
+ for (i = 0; i < 100; i++) {
+ bnx2x_cl45_read(bp, port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
+ if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
+ MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
+ return 0;;
+ msleep(1);
+ }
+ return -EINVAL;
+}
+
+
+static u8 bnx2x_get_sfp_module_type(struct link_params *params,
+ u8 *module_type)
+{
+ struct bnx2x *bp = params->bp;
+ u8 val;
+ *module_type = SFP_MODULE_TYPE_UNKNOWN;
+
+ /* First check for copper cable */
+ if (bnx2x_read_sfp_module_eeprom(params,
+ SFP_EEPROM_CON_TYPE_ADDR,
+ 1,
+ &val) != 0) {
+ DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
+ return -EINVAL;
+ }
+
+ switch (val) {
+ case SFP_EEPROM_CON_TYPE_VAL_COPPER:
+ {
+ u8 copper_module_type;
+ /* Check if its active cable( includes SFP+ module)
+ of passive cable*/
+ if (bnx2x_read_sfp_module_eeprom(params,
+ SFP_EEPROM_FC_TX_TECH_ADDR,
+ 1,
+ &copper_module_type) !=
+ 0) {
+ DP(NETIF_MSG_LINK,
+ "Failed to read copper-cable-type"
+ " from SFP+ EEPROM\n");
+ return -EINVAL;
+ }
+
+ if (copper_module_type &
+ SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
+ DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
+ *module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
+ } else if (copper_module_type &
+ SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
+ DP(NETIF_MSG_LINK, "Passive Copper"
+ " cable detected\n");
+ *module_type =
+ SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
+ } else {
+ DP(NETIF_MSG_LINK, "Unknown copper-cable-"
+ "type 0x%x !!!\n", copper_module_type);
+ return -EINVAL;
+ }
+ break;
+ }
+ case SFP_EEPROM_CON_TYPE_VAL_LC:
+ DP(NETIF_MSG_LINK, "Optic module detected\n");
+ *module_type = SFP_MODULE_TYPE_LC;
+ break;
+
+ default:
+ DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
+ val);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+
+/* This function read the relevant field from the module ( SFP+ ),
+ and verify it is compliant with this board */
+static u8 bnx2x_verify_sfp_module(struct link_params *params,
+ u8 module_type)
+{
+ struct bnx2x *bp = params->bp;
+ u8 *str_p, *tmp_buf;
+ u16 i;
+
+#define COMPLIANCE_STR_CNT 6
+ u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
+ "FINISAR CORP. ", "Amphenol"};
+ u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
+ /* Passive Copper cables are allowed to participate,
+ since the module is hardwired to the copper cable */
+
+ if (!(params->feature_config_flags &
+ FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
+ DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
+ return 0;
+ }
+
+ if (module_type != SFP_MODULE_TYPE_LC) {
+ DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
+ return 0;
+ }
+
+ /* In case of non copper cable or Active copper cable,
+ verify that the SFP+ module is compliant with this board*/
+ if (bnx2x_read_sfp_module_eeprom(params,
+ SFP_EEPROM_VENDOR_NAME_ADDR,
+ SFP_EEPROM_VENDOR_NAME_SIZE,
+ buf) != 0) {
+ DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
+ " module EEPROM\n");
+ return -EINVAL;
+ }
+ for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
+ str_p = compliance_str[i];
+ tmp_buf = buf;
+ while (*str_p) {
+ if ((u8)(*tmp_buf) != (u8)(*str_p))
+ break;
+ str_p++;
+ tmp_buf++;
+ }
+
+ if (!(*str_p)) {
+ DP(NETIF_MSG_LINK, "SFP+ Module verified, "
+ "index=%x\n", i);
+ return 0;
+ }
+ }
+ DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
+ return -EINVAL;
+}
+
+
+static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
+ u8 module_type)
+{
+ struct bnx2x *bp = params->bp;
+ u8 port = params->port;
+ u8 options[SFP_EEPROM_OPTIONS_SIZE];
+ u8 limiting_mode;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u16 cur_limiting_mode;
+ if (bnx2x_read_sfp_module_eeprom(params,
+ SFP_EEPROM_OPTIONS_ADDR,
+ SFP_EEPROM_OPTIONS_SIZE,
+ options) != 0) {
+ DP(NETIF_MSG_LINK, "Failed to read Option field from"
+ " module EEPROM\n");
+ return -EINVAL;
+ }
+ limiting_mode = !(options[0] &
+ SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
+
bnx2x_cl45_read(bp, port,
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
ext_phy_addr,
MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2, &fw_ver2);
- DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
+ MDIO_PMA_REG_ROM_VER2,
+ &cur_limiting_mode);
+ DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
+ cur_limiting_mode);
+ if (limiting_mode &&
+ (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
+ DP(NETIF_MSG_LINK,
+ "Module options = 0x%x.Setting LIMITING MODE\n",
+ options[0]);
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER2,
+ SFP_LIMITING_MODE_VALUE);
+ } else { /* LRM mode ( default )*/
+
+ DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
+ options[0]);
+
+ /* Changing to LRM mode takes quite few seconds.
+ So do it only if current mode is limiting
+ ( default is LRM )*/
+ if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
+ return 0;
+
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LRM_MODE,
+ 0);
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER2,
+ 0x128);
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_MISC_CTRL0,
+ 0x4008);
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LRM_MODE,
+ 0xaaaa);
+ }
+ return 0;
+}
+
+static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
+{
+ u8 val;
+ struct bnx2x *bp = params->bp;
+ u16 timeout;
+ /* Initialization time after hot-plug may take up to 300ms for some
+ phys type ( e.g. JDSU ) */
+ for (timeout = 0; timeout < 60; timeout++) {
+ if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
+ == 0) {
+ DP(NETIF_MSG_LINK, "SFP+ module initialization "
+ "took %d ms\n", timeout * 5);
+ return 0;
+ }
+ msleep(5);
+ }
+ return -EINVAL;
+}
+
+static u8 bnx2x_sfp_module_detection(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u8 module_type;
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
+ if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
+ DP(NETIF_MSG_LINK, "Module detection is not required "
+ "for this phy\n");
+ return 0;
+ }
+
+ DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
+ params->port);
+
+ if (bnx2x_get_sfp_module_type(params,
+ &module_type) != 0) {
+ DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
+ if (!(params->feature_config_flags &
+ FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
+ /* In case module detection is disabled, it trys to
+ link up. The issue that can happen here is LRM /
+ LIMITING mode which set according to the module-type*/
+ DP(NETIF_MSG_LINK, "Unable to read module-type."
+ "Probably due to Bit Stretching."
+ " Proceeding...\n");
+ } else {
+ return -EINVAL;
+ }
+ } else if (bnx2x_verify_sfp_module(params, module_type) !=
+ 0) {
+ /* check SFP+ module compatibility */
+ DP(NETIF_MSG_LINK, "Module verification failed!!\n");
+ /* Turn on fault module-detected led */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+ MISC_REGISTERS_GPIO_HIGH,
+ params->port);
+ return -EINVAL;
+ }
+
+ /* Turn off fault module-detected led */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+ MISC_REGISTERS_GPIO_LOW,
+ params->port);
+
+ /* Check and set limiting mode / LRM mode */
+ bnx2x_bcm8726_set_limiting_mode(params, module_type);
+
+ /* Enable transmit for this module */
+ bnx2x_bcm8726_set_transmitter(bp, params->port,
+ ext_phy_addr, 1);
+ return 0;
+}
+
+void bnx2x_handle_module_detect_int(struct link_params *params)
+{
+ struct bnx2x *bp = params->bp;
+ u32 gpio_val;
+ u8 port = params->port;
+ /* Set valid module led off */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+ MISC_REGISTERS_GPIO_HIGH,
+ params->port);
+
+ /* Get current gpio val refelecting module plugged in / out*/
+ gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
+
+ /* Call the handling function in case module is detected */
+ if (gpio_val == 0) {
+
+ bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
+ MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
+ port);
+
+ if (bnx2x_wait_for_sfp_module_initialized(params)
+ == 0)
+ bnx2x_sfp_module_detection(params);
+ else
+ DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
+ } else {
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
+ MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
+ port);
+ /* Module was plugged out. */
+ /* Disable transmit for this module */
+ bnx2x_bcm8726_set_transmitter(bp, params->port,
+ ext_phy_addr, 0);
+ }
}
static void bnx2x_bcm807x_force_10G(struct link_params *params)
@@ -2239,7 +2756,7 @@ static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xc801, &val);
+ MDIO_PMA_REG_8073_CHIP_REV, &val);
if (val == 0) {
/* Mustn't set low power mode in 8073 A0 */
@@ -2377,31 +2894,40 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params,
MDIO_AN_DEVAD,
MDIO_AN_REG_ADV_PAUSE, val);
}
+static void bnx2x_set_preemphasis(struct link_params *params)
+{
+ u16 bank, i = 0;
+ struct bnx2x *bp = params->bp;
+ for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
+ bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ bank,
+ MDIO_RX0_RX_EQ_BOOST,
+ params->xgxs_config_rx[i]);
+ }
+
+ for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
+ bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
+ CL45_WR_OVER_CL22(bp, params->port,
+ params->phy_addr,
+ bank,
+ MDIO_TX0_TX_DRIVER,
+ params->xgxs_config_tx[i]);
+ }
+}
static void bnx2x_init_internal_phy(struct link_params *params,
struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
- u8 port = params->port;
if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
- u16 bank, rx_eq;
-
- rx_eq = ((params->serdes_config &
- PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
- PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
-
- DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
- for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
- bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
- CL45_WR_OVER_CL22(bp, port,
- params->phy_addr,
- bank ,
- MDIO_RX0_RX_EQ_BOOST,
- ((rx_eq &
- MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
- MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
- }
+ if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
+ (params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
+ bnx2x_set_preemphasis(params);
/* forced speed requested? */
if (vars->line_speed != SPEED_AUTO_NEG) {
@@ -2506,12 +3032,53 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
ext_phy_addr,
MDIO_WIS_DEVAD,
MDIO_WIS_REG_LASI_CNTL, 0x1);
+
+ /* BCM8705 doesn't have microcode, hence the 0 */
+ bnx2x_save_spirom_version(bp, params->port,
+ params->shmem_base, 0);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8706\n");
-
- msleep(10);
+ /* Wait until fw is loaded */
+ for (cnt = 0; cnt < 100; cnt++) {
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_ROM_VER1, &val);
+ if (val)
+ break;
+ msleep(10);
+ }
+ DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
+ "after %d ms\n", cnt);
+ if ((params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
+ u8 i;
+ u16 reg;
+ for (i = 0; i < 4; i++) {
+ reg = MDIO_XS_8706_REG_BANK_RX0 +
+ i*(MDIO_XS_8706_REG_BANK_RX1 -
+ MDIO_XS_8706_REG_BANK_RX0);
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_XS_DEVAD,
+ reg, &val);
+ /* Clear first 3 bits of the control */
+ val &= ~0x7;
+ /* Set control bits according to
+ configuation */
+ val |= (params->xgxs_config_rx[i] &
+ 0x7);
+ DP(NETIF_MSG_LINK, "Setting RX"
+ "Equalizer to BCM8706 reg 0x%x"
+ " <-- val 0x%x\n", reg, val);
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_XS_DEVAD,
+ reg, val);
+ }
+ }
/* Force speed */
/* First enable LASI */
bnx2x_cl45_write(bp, params->port,
@@ -2578,9 +3145,95 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
0x1200);
}
-
+ bnx2x_save_bcm_spirom_ver(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ params->shmem_base);
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
+ bnx2x_bcm8726_external_rom_boot(params);
+
+ /* Need to call module detected on initialization since
+ the module detection triggered by actual module
+ insertion might occur before driver is loaded, and when
+ driver is loaded, it reset all registers, including the
+ transmitter */
+ bnx2x_sfp_module_detection(params);
+ if (params->req_line_speed == SPEED_1000) {
+ DP(NETIF_MSG_LINK, "Setting 1G force\n");
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL, 0x40);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_10G_CTRL2, 0xD);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_CTRL, 0x5);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM_CTRL,
+ 0x400);
+ } else if ((params->req_line_speed ==
+ SPEED_AUTO_NEG) &&
+ ((params->speed_cap_mask &
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
+ DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_AN_DEVAD,
+ MDIO_AN_REG_ADV, 0x20);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_CL73, 0x040c);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_FC_LD, 0x0020);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_AN_DEVAD,
+ MDIO_AN_REG_CL37_AN, 0x1000);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_AN_DEVAD,
+ MDIO_AN_REG_CTRL, 0x1200);
+
+ /* Enable RX-ALARM control to receive
+ interrupt for 1G speed change */
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_CTRL, 0x4);
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_RX_ALARM_CTRL,
+ 0x400);
+
+ } else { /* Default 10G. Set only LASI control */
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_CTRL, 1);
+ }
+
+ /* Set TX PreEmphasis if needed */
+ if ((params->feature_config_flags &
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
+ DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
+ "TX_CTRL2 0x%x\n",
+ params->xgxs_config_tx[0],
+ params->xgxs_config_tx[1]);
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TX_CTRL1,
+ params->xgxs_config_tx[0]);
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8726_TX_CTRL2,
+ params->xgxs_config_tx[1]);
+ }
+ break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
{
@@ -2627,7 +3280,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
ext_phy_type,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xca13,
+ MDIO_PMA_REG_M8051_MSGOUT_REG,
&tmp1);
bnx2x_cl45_read(bp, params->port,
@@ -2694,7 +3347,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
ext_phy_type,
ext_phy_addr,
MDIO_AN_DEVAD,
- 0x8329, &tmp1);
+ MDIO_AN_REG_8073_2_5G, &tmp1);
if (((params->speed_cap_mask &
PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
@@ -2708,7 +3361,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xc801, &phy_ver);
+ MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
DP(NETIF_MSG_LINK, "Add 2.5G\n");
if (phy_ver > 0)
tmp1 |= 1;
@@ -2723,7 +3376,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
ext_phy_type,
ext_phy_addr,
MDIO_AN_DEVAD,
- 0x8329, tmp1);
+ MDIO_AN_REG_8073_2_5G, tmp1);
}
/* Add support for CL37 (passive mode) II */
@@ -2798,6 +3451,8 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
break;
}
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ {
+ u16 fw_ver1, fw_ver2;
DP(NETIF_MSG_LINK,
"Setting the SFX7101 LASI indication\n");
@@ -2827,6 +3482,50 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
ext_phy_addr,
MDIO_AN_DEVAD,
MDIO_AN_REG_CTRL, val);
+
+ /* Save spirom version */
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_VER1, &fw_ver1);
+
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr, MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_7101_VER2, &fw_ver2);
+
+ bnx2x_save_spirom_version(params->bp, params->port,
+ params->shmem_base,
+ (u32)(fw_ver1<<16 | fw_ver2));
+
+ break;
+ }
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+ DP(NETIF_MSG_LINK,
+ "Setting the BCM8481 LASI control\n");
+
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_CTRL, 0x1);
+
+ /* Restart autoneg */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CTRL, &val);
+ val |= 0x200;
+ bnx2x_cl45_write(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_CTRL, val);
+
+ bnx2x_save_bcm_spirom_ver(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ params->shmem_base);
+
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
DP(NETIF_MSG_LINK,
@@ -2910,38 +3609,43 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- DP(NETIF_MSG_LINK, "XGXS 8706\n");
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
+ /* Clear RX Alarm*/
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
-
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
+ &val2);
+ /* clear LASI indication*/
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_LASI_STATUS, &val1);
- DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
+ &val1);
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
+ &val2);
+ DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
+ "0x%x\n", val1, val2);
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_SD, &rx_sd);
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
+ &rx_sd);
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr,
- MDIO_PCS_DEVAD,
- MDIO_PCS_REG_STATUS, &pcs_status);
-
+ MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
+ &pcs_status);
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS, &val2);
+ MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
+ &val2);
bnx2x_cl45_read(bp, params->port, ext_phy_type,
ext_phy_addr,
- MDIO_AN_DEVAD,
- MDIO_AN_REG_LINK_STATUS, &val2);
+ MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
+ &val2);
- DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
+ DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
" pcs_status 0x%x 1Gbps link_status 0x%x\n",
rx_sd, pcs_status, val2);
/* link is up if both bit 0 of pmd_rx_sd and
@@ -2951,19 +3655,31 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
(val2 & (1<<1)));
if (ext_phy_link_up) {
+ if (ext_phy_type ==
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
+ /* If transmitter is disabled,
+ ignore false link up indication */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_PHY_IDENTIFIER,
+ &val1);
+ if (val1 & (1<<15)) {
+ DP(NETIF_MSG_LINK, "Tx is "
+ "disabled\n");
+ ext_phy_link_up = 0;
+ break;
+ }
+ }
+
if (val2 & (1<<1))
vars->line_speed = SPEED_1000;
else
vars->line_speed = SPEED_10000;
}
- /* clear LASI indication*/
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_RX_ALARM, &val2);
break;
-
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
{
@@ -3018,7 +3734,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
ext_phy_type,
ext_phy_addr,
MDIO_PMA_DEVAD,
- 0xca13,
+ MDIO_PMA_REG_M8051_MSGOUT_REG,
&val1);
/* Check the LASI */
@@ -3063,17 +3779,17 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
}
}
bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8304,
- &an1000_status);
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_LINK_STATUS,
+ &an1000_status);
bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8304,
- &an1000_status);
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_LINK_STATUS,
+ &an1000_status);
/* Check the link status on 1.1.2 */
bnx2x_cl45_read(bp, params->port,
@@ -3090,7 +3806,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
"an_link_status=0x%x\n",
val2, val1, an1000_status);
- ext_phy_link_up = (((val1 & 4) == 4) ||
+ ext_phy_link_up = (((val1 & 4) == 4) ||
(an1000_status & (1<<1)));
if (ext_phy_link_up &&
bnx2x_8073_is_snr_needed(params)) {
@@ -3118,11 +3834,11 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
}
bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- 0xc820,
- &link_status);
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
+ &link_status);
/* Bits 0..2 --> speed detected,
bits 13..15--> link is down */
@@ -3156,17 +3872,17 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
} else {
/* See if 1G link is up for the 8072 */
bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8304,
- &an1000_status);
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_LINK_STATUS,
+ &an1000_status);
bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_AN_DEVAD,
- 0x8304,
- &an1000_status);
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD,
+ MDIO_AN_REG_LINK_STATUS,
+ &an1000_status);
if (an1000_status & (1<<1)) {
ext_phy_link_up = 1;
vars->line_speed = SPEED_1000;
@@ -3226,7 +3942,53 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
(val2 & (1<<14)));
}
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+ /* Clear LASI interrupt */
+ bnx2x_cl45_read(bp, params->port,
+ ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_LASI_STATUS, &val1);
+ DP(NETIF_MSG_LINK, "8481 LASI status reg = 0x%x\n",
+ val1);
+ /* Check 10G-BaseT link status */
+ /* Check Global PMD signal ok */
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
+ &rx_sd);
+ /* Check PCS block lock */
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
+ &pcs_status);
+ DP(NETIF_MSG_LINK, "8481 1.a = 0x%x, 1.20 = 0x%x\n",
+ rx_sd, pcs_status);
+ if (rx_sd & pcs_status & 0x1) {
+ vars->line_speed = SPEED_10000;
+ ext_phy_link_up = 1;
+ } else {
+
+ /* Check 1000-BaseT link status */
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD, 0xFFE1,
+ &val1);
+
+ bnx2x_cl45_read(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_AN_DEVAD, 0xFFE1,
+ &val2);
+ DP(NETIF_MSG_LINK, "8481 7.FFE1 ="
+ "0x%x-->0x%x\n", val1, val2);
+ if (val2 & (1<<2)) {
+ vars->line_speed = SPEED_1000;
+ ext_phy_link_up = 1;
+ }
+ }
+
+ break;
default:
DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
params->ext_phy_config);
@@ -3426,7 +4188,7 @@ static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
ext_phy_addr,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_CTRL,
- &ctrl);
+ &ctrl);
if (!(ctrl & (1<<15))) {
DP(NETIF_MSG_LINK, "Reset completed\n\n");
break;
@@ -3452,91 +4214,39 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
{
struct bnx2x *bp = params->bp;
u32 ext_phy_type = 0;
- u16 val = 0;
- u8 ext_phy_addr = 0 ;
+ u32 spirom_ver = 0;
u8 status = 0 ;
- u32 ver_num;
if (version == NULL || params == NULL)
return -EINVAL;
+ spirom_ver = REG_RD(bp, params->shmem_base +
+ offsetof(struct shmem_region,
+ port_mb[params->port].ext_phy_fw_version));
+
/* reset the returned value to zero */
ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
- ext_phy_addr = ((params->ext_phy_config &
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
- PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
if (len < 5)
return -EINVAL;
- /* Take ext phy out of reset */
- if (!driver_loaded)
- bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
- ext_phy_type);
-
- /* wait for 1ms */
- msleep(1);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_7101_VER1, &val);
- version[2] = (val & 0xFF);
- version[3] = ((val & 0xFF00)>>8);
-
- bnx2x_cl45_read(bp, params->port,
- ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
- &val);
- version[0] = (val & 0xFF);
- version[1] = ((val & 0xFF00)>>8);
+ version[0] = (spirom_ver & 0xFF);
+ version[1] = (spirom_ver & 0xFF00) >> 8;
+ version[2] = (spirom_ver & 0xFF0000) >> 16;
+ version[3] = (spirom_ver & 0xFF000000) >> 24;
version[4] = '\0';
- if (!driver_loaded)
- bnx2x_turn_off_sf(bp, params->port);
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- {
- /* Take ext phy out of reset */
- if (!driver_loaded)
- bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
- ext_phy_type);
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &val);
- ver_num = val<<16;
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2, &val);
- ver_num |= val;
- status = bnx2x_format_ver(ver_num, version, len);
- break;
- }
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
-
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER1, &val);
- ver_num = val<<16;
- bnx2x_cl45_read(bp, params->port, ext_phy_type,
- ext_phy_addr,
- MDIO_PMA_DEVAD,
- MDIO_PMA_REG_ROM_VER2, &val);
- ver_num |= val;
- status = bnx2x_format_ver(ver_num, version, len);
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+ status = bnx2x_format_ver(spirom_ver, version, len);
break;
-
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
break;
@@ -3636,6 +4346,14 @@ static void bnx2x_ext_phy_loopback(struct link_params *params)
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
+ bnx2x_cl45_write(bp, params->port, ext_phy_type,
+ ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_CTRL,
+ 0x0001);
+ break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
/* SFX7101_XGXS_TEST1 */
bnx2x_cl45_write(bp, params->port, ext_phy_type,
@@ -3906,11 +4624,13 @@ static u8 bnx2x_link_initialize(struct link_params *params,
/* init ext phy and enable link state int */
non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
- (params->loopback_mode == LOOPBACK_XGXS_10) ||
- (params->loopback_mode == LOOPBACK_EXT_PHY));
+ (params->loopback_mode == LOOPBACK_XGXS_10));
if (non_ext_phy ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
+ (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
+ (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
+ (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
+ (params->loopback_mode == LOOPBACK_EXT_PHY)) {
if (params->req_line_speed == SPEED_AUTO_NEG)
bnx2x_set_parallel_detection(params, vars->phy_flags);
bnx2x_init_internal_phy(params, vars);
@@ -4104,6 +4824,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
return -EINVAL;
break;
}
+ DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
bnx2x_link_initialize(params, vars);
msleep(30);
@@ -4112,7 +4833,23 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
return 0;
}
-u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
+static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
+{
+ DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
+
+ /* Set serial boot control for external load */
+ bnx2x_cl45_write(bp, port,
+ PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
+ MDIO_PMA_DEVAD,
+ MDIO_PMA_REG_GEN_CTRL, 0x0001);
+
+ /* Disable Transmitter */
+ bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
+
+}
+
+u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
+ u8 reset_ext_phy)
{
struct bnx2x *bp = params->bp;
@@ -4150,28 +4887,37 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
*/
/* clear link led */
bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
- if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
- if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
- (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
+ if (reset_ext_phy) {
+ switch (ext_phy_type) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
+ "low power mode\n",
+ port);
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+ MISC_REGISTERS_GPIO_OUTPUT_LOW,
+ port);
+ break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ {
+ u8 ext_phy_addr = ((params->ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ /* Set soft reset */
+ bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
+ break;
+ }
+ default:
/* HW reset */
-
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
MISC_REGISTERS_GPIO_OUTPUT_LOW,
port);
-
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
MISC_REGISTERS_GPIO_OUTPUT_LOW,
port);
-
DP(NETIF_MSG_LINK, "reset external PHY\n");
- } else if (ext_phy_type ==
- PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
- DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
- "low power mode\n",
- port);
- bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
- MISC_REGISTERS_GPIO_OUTPUT_LOW,
- port);
}
}
/* reset the SerDes/XGXS */
@@ -4248,7 +4994,7 @@ static u8 bnx2x_update_link_up(struct link_params *params,
if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
if (!(vars->phy_flags &
PHY_SGMII_FLAG))
- bnx2x_set_sgmii_tx_driver(params);
+ bnx2x_set_gmii_tx_driver(params);
}
}
@@ -4337,6 +5083,7 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
(ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
+ (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
(ext_phy_link_up && !vars->phy_link_up))
bnx2x_init_internal_phy(params, vars);
@@ -4398,7 +5145,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
u16 fw_ver1;
bnx2x_bcm8073_external_rom_boot(bp, port,
- ext_phy_addr[port]);
+ ext_phy_addr[port], shmem_base);
bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
ext_phy_addr[port],
@@ -4434,7 +5181,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
/* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
for (port = PORT_MAX - 1; port >= PORT_0; port--) {
- /* Phase2 of POWER_DOWN_RESET*/
+ /* Phase2 of POWER_DOWN_RESET */
/* Release bit 10 (Release Tx power down) */
bnx2x_cl45_read(bp, port,
PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
@@ -4469,12 +5216,51 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
}
+
+static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
+{
+ u8 ext_phy_addr;
+ u32 val;
+ s8 port;
+ /* Use port1 because of the static port-swap */
+ /* Enable the module detection interrupt */
+ val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
+ val |= ((1<<MISC_REGISTERS_GPIO_3)|
+ (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
+ REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
+
+ bnx2x_hw_reset(bp, 1);
+ msleep(5);
+ for (port = 0; port < PORT_MAX; port++) {
+ /* Extract the ext phy address for the port */
+ u32 ext_phy_config = REG_RD(bp, shmem_base +
+ offsetof(struct shmem_region,
+ dev_info.port_hw_config[port].external_phy_config));
+
+ ext_phy_addr =
+ ((ext_phy_config &
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+ PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+ DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
+ ext_phy_addr);
+
+ bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
+
+ /* Set fault module detected LED on */
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+ MISC_REGISTERS_GPIO_HIGH,
+ port);
+ }
+
+ return 0;
+}
+
u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
{
u8 rc = 0;
u32 ext_phy_type;
- DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
+ DP(NETIF_MSG_LINK, "Begin common phy init\n");
/* Read the ext_phy_type for arbitrary port(0) */
ext_phy_type = XGXS_EXT_PHY_TYPE(
@@ -4488,6 +5274,12 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
rc = bnx2x_8073_common_init_phy(bp, shmem_base);
break;
}
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ /* GPIO1 affects both ports, so there's need to pull
+ it for single port alone */
+ rc = bnx2x_8726_common_init_phy(bp, shmem_base);
+
+ break;
default:
DP(NETIF_MSG_LINK,
"bnx2x_common_init_phy: ext_phy 0x%x not required\n",
diff --git a/drivers/net/bnx2x_link.h b/drivers/net/bnx2x_link.h
index 47cb585f4278..19a866dc10eb 100644
--- a/drivers/net/bnx2x_link.h
+++ b/drivers/net/bnx2x_link.h
@@ -1,4 +1,4 @@
-/* Copyright 2008 Broadcom Corporation
+/* Copyright 2008-2009 Broadcom Corporation
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
@@ -66,8 +66,6 @@ struct link_params {
/* Device parameters */
u8 mac_addr[6];
-
-
/* shmem parameters */
u32 shmem_base;
u32 speed_cap_mask;
@@ -77,7 +75,6 @@ struct link_params {
#define SWITCH_CFG_AUTO_DETECT PORT_FEATURE_CON_SWITCH_AUTO_DETECT
u16 hw_led_mode; /* part of the hw_config read from the shmem */
- u32 serdes_config;
u32 lane_config;
u32 ext_phy_config;
#define XGXS_EXT_PHY_TYPE(ext_phy_config) (ext_phy_config & \
@@ -89,6 +86,12 @@ struct link_params {
/* phy_addr populated by the CLC */
u8 phy_addr;
+ u16 xgxs_config_rx[4]; /* preemphasis values for the rx side */
+
+ u16 xgxs_config_tx[4]; /* preemphasis values for the tx side */
+ u32 feature_config_flags;
+#define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0)
+#define FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED (2<<0)
/* Device pointer passed to all callback functions */
struct bnx2x *bp;
};
@@ -125,8 +128,11 @@ struct link_vars {
/* Initialize the phy */
u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output);
-/* Reset the link. Should be called when driver or interface goes down */
-u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars);
+/* Reset the link. Should be called when driver or interface goes down
+ Before calling phy firmware upgrade, the reset_ext_phy should be set
+ to 0 */
+u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
+ u8 reset_ext_phy);
/* bnx2x_link_update should be called upon link interrupt */
u8 bnx2x_link_update(struct link_params *input, struct link_vars *output);
@@ -163,6 +169,10 @@ u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, u32 led_idx, u32 value);
u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
u8 driver_loaded, char data[], u32 size);
+/* bnx2x_handle_module_detect_int should be called upon module detection
+ interrupt */
+void bnx2x_handle_module_detect_int(struct link_params *params);
+
/* Get the actual link status. In case it returns 0, link is up,
otherwise link is down*/
u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
@@ -170,4 +180,5 @@ u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
/* One-time initialization for external phy after power up */
u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base);
+
#endif /* BNX2X_LINK_H */
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 2e346a5e98cf..00a78e8677b0 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -50,15 +50,13 @@
#include <linux/zlib.h>
#include <linux/io.h>
-#include "bnx2x_reg.h"
-#include "bnx2x_fw_defs.h"
-#include "bnx2x_hsi.h"
-#include "bnx2x_link.h"
+
#include "bnx2x.h"
#include "bnx2x_init.h"
+#include "bnx2x_dump.h"
-#define DRV_MODULE_VERSION "1.45.27"
-#define DRV_MODULE_RELDATE "2009/01/26"
+#define DRV_MODULE_VERSION "1.48.105"
+#define DRV_MODULE_RELDATE "2009/03/02"
#define BNX2X_BC_VER 0x040200
/* Time in jiffies before concluding the transmitter is hung */
@@ -73,26 +71,32 @@ MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710/57711/57711E Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_MODULE_VERSION);
+static int multi_mode = 1;
+module_param(multi_mode, int, 0);
+MODULE_PARM_DESC(multi_mode, " Use per-CPU queues");
+
static int disable_tpa;
-static int use_inta;
+module_param(disable_tpa, int, 0);
+MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature");
+
+static int int_mode;
+module_param(int_mode, int, 0);
+MODULE_PARM_DESC(int_mode, " Force interrupt mode (1 INT#x; 2 MSI)");
+
static int poll;
+module_param(poll, int, 0);
+MODULE_PARM_DESC(poll, " Use polling (for debug)");
+
+static int mrrs = -1;
+module_param(mrrs, int, 0);
+MODULE_PARM_DESC(mrrs, " Force Max Read Req Size (0..3) (for debug)");
+
static int debug;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, " Default debug msglevel");
+
static int load_count[3]; /* 0-common, 1-port0, 2-port1 */
-static int use_multi;
-module_param(disable_tpa, int, 0);
-module_param(use_inta, int, 0);
-module_param(poll, int, 0);
-module_param(debug, int, 0);
-MODULE_PARM_DESC(disable_tpa, "disable the TPA (LRO) feature");
-MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X");
-MODULE_PARM_DESC(poll, "use polling (for debug)");
-MODULE_PARM_DESC(debug, "default debug msglevel");
-
-#ifdef BNX2X_MULTI
-module_param(use_multi, int, 0);
-MODULE_PARM_DESC(use_multi, "use per-CPU queues");
-#endif
static struct workqueue_struct *bnx2x_wq;
enum bnx2x_board_type {
@@ -213,7 +217,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
dmae->comp_val = DMAE_COMP_VAL;
- DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
+ DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n"
DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
"dst_addr [%x:%08x (%08x)]\n"
DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
@@ -234,7 +238,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp);
if (!cnt) {
- BNX2X_ERR("dmae timeout!\n");
+ BNX2X_ERR("DMAE timeout!\n");
break;
}
cnt--;
@@ -289,7 +293,7 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
dmae->comp_val = DMAE_COMP_VAL;
- DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
+ DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n"
DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
"dst_addr [%x:%08x (%08x)]\n"
DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
@@ -306,7 +310,7 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
while (*wb_comp != DMAE_COMP_VAL) {
if (!cnt) {
- BNX2X_ERR("dmae timeout!\n");
+ BNX2X_ERR("DMAE timeout!\n");
break;
}
cnt--;
@@ -468,7 +472,7 @@ static int bnx2x_mc_assert(struct bnx2x *bp)
static void bnx2x_fw_dump(struct bnx2x *bp)
{
u32 mark, offset;
- u32 data[9];
+ __be32 data[9];
int word;
mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104);
@@ -502,82 +506,103 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
BNX2X_ERR("begin crash dump -----------------\n");
- for_each_queue(bp, i) {
+ /* Indices */
+ /* Common */
+ BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_x_idx(%u)"
+ " def_t_idx(%u) def_att_idx(%u) attn_state(%u)"
+ " spq_prod_idx(%u)\n",
+ bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
+ bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
+
+ /* Rx */
+ for_each_rx_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
- struct eth_tx_db_data *hw_prods = fp->hw_tx_prods;
- BNX2X_ERR("queue[%d]: tx_pkt_prod(%x) tx_pkt_cons(%x)"
- " tx_bd_prod(%x) tx_bd_cons(%x) *tx_cons_sb(%x)\n",
- i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
- fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
- BNX2X_ERR(" rx_bd_prod(%x) rx_bd_cons(%x)"
+ BNX2X_ERR("fp%d: rx_bd_prod(%x) rx_bd_cons(%x)"
" *rx_bd_cons_sb(%x) rx_comp_prod(%x)"
" rx_comp_cons(%x) *rx_cons_sb(%x)\n",
- fp->rx_bd_prod, fp->rx_bd_cons,
+ i, fp->rx_bd_prod, fp->rx_bd_cons,
le16_to_cpu(*fp->rx_bd_cons_sb), fp->rx_comp_prod,
fp->rx_comp_cons, le16_to_cpu(*fp->rx_cons_sb));
- BNX2X_ERR(" rx_sge_prod(%x) last_max_sge(%x)"
- " fp_c_idx(%x) *sb_c_idx(%x) fp_u_idx(%x)"
- " *sb_u_idx(%x) bd data(%x,%x)\n",
- fp->rx_sge_prod, fp->last_max_sge, fp->fp_c_idx,
- fp->status_blk->c_status_block.status_block_index,
- fp->fp_u_idx,
- fp->status_blk->u_status_block.status_block_index,
- hw_prods->packets_prod, hw_prods->bds_prod);
-
- start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
- end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245);
- for (j = start; j < end; j++) {
- struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j];
+ BNX2X_ERR(" rx_sge_prod(%x) last_max_sge(%x)"
+ " fp_u_idx(%x) *sb_u_idx(%x)\n",
+ fp->rx_sge_prod, fp->last_max_sge,
+ le16_to_cpu(fp->fp_u_idx),
+ fp->status_blk->u_status_block.status_block_index);
+ }
- BNX2X_ERR("packet[%x]=[%p,%x]\n", j,
- sw_bd->skb, sw_bd->first_bd);
- }
+ /* Tx */
+ for_each_tx_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+ struct eth_tx_db_data *hw_prods = fp->hw_tx_prods;
- start = TX_BD(fp->tx_bd_cons - 10);
- end = TX_BD(fp->tx_bd_cons + 254);
- for (j = start; j < end; j++) {
- u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j];
+ BNX2X_ERR("fp%d: tx_pkt_prod(%x) tx_pkt_cons(%x)"
+ " tx_bd_prod(%x) tx_bd_cons(%x) *tx_cons_sb(%x)\n",
+ i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
+ fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
+ BNX2X_ERR(" fp_c_idx(%x) *sb_c_idx(%x)"
+ " bd data(%x,%x)\n", le16_to_cpu(fp->fp_c_idx),
+ fp->status_blk->c_status_block.status_block_index,
+ hw_prods->packets_prod, hw_prods->bds_prod);
+ }
- BNX2X_ERR("tx_bd[%x]=[%x:%x:%x:%x]\n",
- j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]);
- }
+ /* Rings */
+ /* Rx */
+ for_each_rx_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10);
end = RX_BD(le16_to_cpu(*fp->rx_cons_sb) + 503);
- for (j = start; j < end; j++) {
+ for (j = start; j != end; j = RX_BD(j + 1)) {
u32 *rx_bd = (u32 *)&fp->rx_desc_ring[j];
struct sw_rx_bd *sw_bd = &fp->rx_buf_ring[j];
- BNX2X_ERR("rx_bd[%x]=[%x:%x] sw_bd=[%p]\n",
- j, rx_bd[1], rx_bd[0], sw_bd->skb);
+ BNX2X_ERR("fp%d: rx_bd[%x]=[%x:%x] sw_bd=[%p]\n",
+ i, j, rx_bd[1], rx_bd[0], sw_bd->skb);
}
start = RX_SGE(fp->rx_sge_prod);
end = RX_SGE(fp->last_max_sge);
- for (j = start; j < end; j++) {
+ for (j = start; j != end; j = RX_SGE(j + 1)) {
u32 *rx_sge = (u32 *)&fp->rx_sge_ring[j];
struct sw_rx_page *sw_page = &fp->rx_page_ring[j];
- BNX2X_ERR("rx_sge[%x]=[%x:%x] sw_page=[%p]\n",
- j, rx_sge[1], rx_sge[0], sw_page->page);
+ BNX2X_ERR("fp%d: rx_sge[%x]=[%x:%x] sw_page=[%p]\n",
+ i, j, rx_sge[1], rx_sge[0], sw_page->page);
}
start = RCQ_BD(fp->rx_comp_cons - 10);
end = RCQ_BD(fp->rx_comp_cons + 503);
- for (j = start; j < end; j++) {
+ for (j = start; j != end; j = RCQ_BD(j + 1)) {
u32 *cqe = (u32 *)&fp->rx_comp_ring[j];
- BNX2X_ERR("cqe[%x]=[%x:%x:%x:%x]\n",
- j, cqe[0], cqe[1], cqe[2], cqe[3]);
+ BNX2X_ERR("fp%d: cqe[%x]=[%x:%x:%x:%x]\n",
+ i, j, cqe[0], cqe[1], cqe[2], cqe[3]);
}
}
- BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_x_idx(%u)"
- " def_t_idx(%u) def_att_idx(%u) attn_state(%u)"
- " spq_prod_idx(%u)\n",
- bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx,
- bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
+ /* Tx */
+ for_each_tx_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
+ end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245);
+ for (j = start; j != end; j = TX_BD(j + 1)) {
+ struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j];
+
+ BNX2X_ERR("fp%d: packet[%x]=[%p,%x]\n",
+ i, j, sw_bd->skb, sw_bd->first_bd);
+ }
+
+ start = TX_BD(fp->tx_bd_cons - 10);
+ end = TX_BD(fp->tx_bd_cons + 254);
+ for (j = start; j != end; j = TX_BD(j + 1)) {
+ u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j];
+
+ BNX2X_ERR("fp%d: tx_bd[%x]=[%x:%x:%x:%x]\n",
+ i, j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]);
+ }
+ }
bnx2x_fw_dump(bp);
bnx2x_mc_assert(bp);
@@ -590,37 +615,44 @@ static void bnx2x_int_enable(struct bnx2x *bp)
u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
u32 val = REG_RD(bp, addr);
int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
+ int msi = (bp->flags & USING_MSI_FLAG) ? 1 : 0;
if (msix) {
- val &= ~HC_CONFIG_0_REG_SINGLE_ISR_EN_0;
+ val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+ HC_CONFIG_0_REG_INT_LINE_EN_0);
val |= (HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+ } else if (msi) {
+ val &= ~HC_CONFIG_0_REG_INT_LINE_EN_0;
+ val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+ HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
+ HC_CONFIG_0_REG_ATTN_BIT_EN_0);
} else {
val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
HC_CONFIG_0_REG_INT_LINE_EN_0 |
HC_CONFIG_0_REG_ATTN_BIT_EN_0);
- DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
- val, port, addr, msix);
+ DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n",
+ val, port, addr);
REG_WR(bp, addr, val);
val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0;
}
- DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) MSI-X %d\n",
- val, port, addr, msix);
+ DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) mode %s\n",
+ val, port, addr, (msix ? "MSI-X" : (msi ? "MSI" : "INTx")));
REG_WR(bp, addr, val);
if (CHIP_IS_E1H(bp)) {
/* init leading/trailing edge */
if (IS_E1HMF(bp)) {
- val = (0xfe0f | (1 << (BP_E1HVN(bp) + 4)));
+ val = (0xee0f | (1 << (BP_E1HVN(bp) + 4)));
if (bp->port.pmf)
- /* enable nig attention */
- val |= 0x0100;
+ /* enable nig and gpio3 attention */
+ val |= 0x1100;
} else
val = 0xffff;
@@ -643,15 +675,19 @@ static void bnx2x_int_disable(struct bnx2x *bp)
DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n",
val, port, addr);
+ /* flush all outstanding writes */
+ mmiowb();
+
REG_WR(bp, addr, val);
if (REG_RD(bp, addr) != val)
BNX2X_ERR("BUG! proper val not read from IGU!\n");
+
}
static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw)
{
int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
- int i;
+ int i, offset;
/* disable interrupt handling */
atomic_inc(&bp->intr_sem);
@@ -661,11 +697,10 @@ static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw)
/* make sure all ISRs are done */
if (msix) {
+ synchronize_irq(bp->msix_table[0].vector);
+ offset = 1;
for_each_queue(bp, i)
- synchronize_irq(bp->msix_table[i].vector);
-
- /* one more for the Slow Path IRQ */
- synchronize_irq(bp->msix_table[i].vector);
+ synchronize_irq(bp->msix_table[i + offset].vector);
} else
synchronize_irq(bp->pdev->irq);
@@ -748,7 +783,6 @@ static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp)
/* Tell compiler that consumer and producer can change */
barrier();
return (fp->tx_pkt_prod != fp->tx_pkt_cons);
-
}
/* free skb in the packet ring at pos idx
@@ -842,9 +876,10 @@ static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
return (s16)(fp->bp->tx_ring_size) - used;
}
-static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
+static void bnx2x_tx_int(struct bnx2x_fastpath *fp)
{
struct bnx2x *bp = fp->bp;
+ struct netdev_queue *txq;
u16 hw_cons, sw_cons, bd_cons = fp->tx_bd_cons;
int done = 0;
@@ -853,6 +888,7 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
return;
#endif
+ txq = netdev_get_tx_queue(bp->dev, fp->index);
hw_cons = le16_to_cpu(*fp->tx_cons_sb);
sw_cons = fp->tx_pkt_cons;
@@ -874,32 +910,30 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons);
sw_cons++;
done++;
-
- if (done == work)
- break;
}
fp->tx_pkt_cons = sw_cons;
fp->tx_bd_cons = bd_cons;
- /* Need to make the tx_cons update visible to start_xmit()
- * before checking for netif_queue_stopped(). Without the
- * memory barrier, there is a small possibility that start_xmit()
- * will miss it and cause the queue to be stopped forever.
- */
- smp_mb();
-
/* TBD need a thresh? */
- if (unlikely(netif_queue_stopped(bp->dev))) {
+ if (unlikely(netif_tx_queue_stopped(txq))) {
- netif_tx_lock(bp->dev);
+ __netif_tx_lock(txq, smp_processor_id());
- if (netif_queue_stopped(bp->dev) &&
+ /* Need to make the tx_bd_cons update visible to start_xmit()
+ * before checking for netif_tx_queue_stopped(). Without the
+ * memory barrier, there is a small possibility that
+ * start_xmit() will miss it and cause the queue to be stopped
+ * forever.
+ */
+ smp_mb();
+
+ if ((netif_tx_queue_stopped(txq)) &&
(bp->state == BNX2X_STATE_OPEN) &&
(bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
- netif_wake_queue(bp->dev);
+ netif_tx_wake_queue(txq);
- netif_tx_unlock(bp->dev);
+ __netif_tx_unlock(txq);
}
}
@@ -913,12 +947,12 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
DP(BNX2X_MSG_SP,
"fp %d cid %d got ramrod #%d state is %x type is %d\n",
- FP_IDX(fp), cid, command, bp->state,
+ fp->index, cid, command, bp->state,
rr_cqe->ramrod_cqe.ramrod_type);
bp->spq_left++;
- if (FP_IDX(fp)) {
+ if (fp->index) {
switch (command | fp->state) {
case (RAMROD_CMD_ID_ETH_CLIENT_SETUP |
BNX2X_FP_STATE_OPENING):
@@ -1078,8 +1112,7 @@ static void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp,
pci_dma_sync_single_for_device(bp->pdev,
pci_unmap_addr(cons_rx_buf, mapping),
- bp->rx_offset + RX_COPY_THRESH,
- PCI_DMA_FROMDEVICE);
+ RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
prod_rx_buf->skb = cons_rx_buf->skb;
pci_unmap_addr_set(prod_rx_buf, mapping,
@@ -1260,7 +1293,7 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp,
where we are and drop the whole packet */
err = bnx2x_alloc_rx_sge(bp, fp, sge_idx);
if (unlikely(err)) {
- bp->eth_stats.rx_skb_alloc_failed++;
+ fp->eth_q_stats.rx_skb_alloc_failed++;
return err;
}
@@ -1365,7 +1398,7 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
/* else drop the packet and keep the buffer in the bin */
DP(NETIF_MSG_RX_STATUS,
"Failed to allocate new skb - dropping packet!\n");
- bp->eth_stats.rx_skb_alloc_failed++;
+ fp->eth_q_stats.rx_skb_alloc_failed++;
}
fp->tpa_state[queue] = BNX2X_TPA_STOP;
@@ -1376,7 +1409,7 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
u16 bd_prod, u16 rx_comp_prod,
u16 rx_sge_prod)
{
- struct tstorm_eth_rx_producers rx_prods = {0};
+ struct ustorm_eth_rx_producers rx_prods = {0};
int i;
/* Update producers */
@@ -1394,16 +1427,16 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
*/
wmb();
- for (i = 0; i < sizeof(struct tstorm_eth_rx_producers)/4; i++)
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_RX_PRODS_OFFSET(BP_PORT(bp), FP_CL_ID(fp)) + i*4,
+ for (i = 0; i < sizeof(struct ustorm_eth_rx_producers)/4; i++)
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_RX_PRODS_OFFSET(BP_PORT(bp), fp->cl_id) + i*4,
((u32 *)&rx_prods)[i]);
mmiowb(); /* keep prod updates ordered */
DP(NETIF_MSG_RX_STATUS,
- "Wrote: bd_prod %u cqe_prod %u sge_prod %u\n",
- bd_prod, rx_comp_prod, rx_sge_prod);
+ "queue[%d]: wrote bd_prod %u cqe_prod %u sge_prod %u\n",
+ fp->index, bd_prod, rx_comp_prod, rx_sge_prod);
}
static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
@@ -1437,7 +1470,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
DP(NETIF_MSG_RX_STATUS,
"queue[%d]: hw_comp_cons %u sw_comp_cons %u\n",
- FP_IDX(fp), hw_comp_cons, sw_comp_cons);
+ fp->index, hw_comp_cons, sw_comp_cons);
while (sw_comp_cons != hw_comp_cons) {
struct sw_rx_bd *rx_buf = NULL;
@@ -1527,7 +1560,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
DP(NETIF_MSG_RX_ERR,
"ERROR flags %x rx packet %u\n",
cqe_fp_flags, sw_comp_cons);
- bp->eth_stats.rx_err_discard_pkt++;
+ fp->eth_q_stats.rx_err_discard_pkt++;
goto reuse_rx;
}
@@ -1544,7 +1577,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
DP(NETIF_MSG_RX_ERR,
"ERROR packet dropped "
"because of alloc failure\n");
- bp->eth_stats.rx_skb_alloc_failed++;
+ fp->eth_q_stats.rx_skb_alloc_failed++;
goto reuse_rx;
}
@@ -1570,7 +1603,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
DP(NETIF_MSG_RX_ERR,
"ERROR packet dropped because "
"of alloc failure\n");
- bp->eth_stats.rx_skb_alloc_failed++;
+ fp->eth_q_stats.rx_skb_alloc_failed++;
reuse_rx:
bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
goto next_rx;
@@ -1583,10 +1616,11 @@ reuse_rx:
if (likely(BNX2X_RX_CSUM_OK(cqe)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
- bp->eth_stats.hw_csum_err++;
+ fp->eth_q_stats.hw_csum_err++;
}
}
+ skb_record_rx_queue(skb, fp->index);
#ifdef BCM_VLAN
if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
(le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
@@ -1632,7 +1666,7 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
{
struct bnx2x_fastpath *fp = fp_cookie;
struct bnx2x *bp = fp->bp;
- int index = FP_IDX(fp);
+ int index = fp->index;
/* Return here if interrupt is disabled */
if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
@@ -1641,8 +1675,8 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
}
DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n",
- index, FP_SB_ID(fp));
- bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID, 0, IGU_INT_DISABLE, 0);
+ index, fp->sb_id);
+ bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0);
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
@@ -1654,15 +1688,14 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
prefetch(&fp->status_blk->c_status_block.status_block_index);
prefetch(&fp->status_blk->u_status_block.status_block_index);
- netif_rx_schedule(&bnx2x_fp(bp, index, napi));
+ napi_schedule(&bnx2x_fp(bp, index, napi));
return IRQ_HANDLED;
}
static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
{
- struct net_device *dev = dev_instance;
- struct bnx2x *bp = netdev_priv(dev);
+ struct bnx2x *bp = netdev_priv(dev_instance);
u16 status = bnx2x_ack_int(bp);
u16 mask;
@@ -1671,7 +1704,7 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
DP(NETIF_MSG_INTR, "not our interrupt!\n");
return IRQ_NONE;
}
- DP(NETIF_MSG_INTR, "got an interrupt status %u\n", status);
+ DP(NETIF_MSG_INTR, "got an interrupt status 0x%x\n", status);
/* Return here if interrupt is disabled */
if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
@@ -1693,7 +1726,7 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
prefetch(&fp->status_blk->c_status_block.status_block_index);
prefetch(&fp->status_blk->u_status_block.status_block_index);
- netif_rx_schedule(&bnx2x_fp(bp, 0, napi));
+ napi_schedule(&bnx2x_fp(bp, 0, napi));
status &= ~mask;
}
@@ -1806,26 +1839,50 @@ static int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource)
/* HW Lock for shared dual port PHYs */
static void bnx2x_acquire_phy_lock(struct bnx2x *bp)
{
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
-
mutex_lock(&bp->port.phy_mutex);
- if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
- bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ if (bp->port.need_hw_lock)
+ bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_MDIO);
}
static void bnx2x_release_phy_lock(struct bnx2x *bp)
{
- u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
-
- if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) ||
- (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073))
- bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_8072_MDIO);
+ if (bp->port.need_hw_lock)
+ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_MDIO);
mutex_unlock(&bp->port.phy_mutex);
}
+int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port)
+{
+ /* The GPIO should be swapped if swap register is set and active */
+ int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
+ REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port;
+ int gpio_shift = gpio_num +
+ (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
+ u32 gpio_mask = (1 << gpio_shift);
+ u32 gpio_reg;
+ int value;
+
+ if (gpio_num > MISC_REGISTERS_GPIO_3) {
+ BNX2X_ERR("Invalid GPIO %d\n", gpio_num);
+ return -EINVAL;
+ }
+
+ /* read GPIO value */
+ gpio_reg = REG_RD(bp, MISC_REG_GPIO);
+
+ /* get the requested pin value */
+ if ((gpio_reg & gpio_mask) == gpio_mask)
+ value = 1;
+ else
+ value = 0;
+
+ DP(NETIF_MSG_LINK, "pin %d value 0x%x\n", gpio_num, value);
+
+ return value;
+}
+
int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port)
{
/* The GPIO should be swapped if swap register is set and active */
@@ -1879,6 +1936,52 @@ int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port)
return 0;
}
+int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port)
+{
+ /* The GPIO should be swapped if swap register is set and active */
+ int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) &&
+ REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port;
+ int gpio_shift = gpio_num +
+ (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0);
+ u32 gpio_mask = (1 << gpio_shift);
+ u32 gpio_reg;
+
+ if (gpio_num > MISC_REGISTERS_GPIO_3) {
+ BNX2X_ERR("Invalid GPIO %d\n", gpio_num);
+ return -EINVAL;
+ }
+
+ bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
+ /* read GPIO int */
+ gpio_reg = REG_RD(bp, MISC_REG_GPIO_INT);
+
+ switch (mode) {
+ case MISC_REGISTERS_GPIO_INT_OUTPUT_CLR:
+ DP(NETIF_MSG_LINK, "Clear GPIO INT %d (shift %d) -> "
+ "output low\n", gpio_num, gpio_shift);
+ /* clear SET and set CLR */
+ gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS);
+ gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS);
+ break;
+
+ case MISC_REGISTERS_GPIO_INT_OUTPUT_SET:
+ DP(NETIF_MSG_LINK, "Set GPIO INT %d (shift %d) -> "
+ "output high\n", gpio_num, gpio_shift);
+ /* clear CLR and set SET */
+ gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS);
+ gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS);
+ break;
+
+ default:
+ break;
+ }
+
+ REG_WR(bp, MISC_REG_GPIO_INT, gpio_reg);
+ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_GPIO);
+
+ return 0;
+}
+
static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
{
u32 spio_mask = (1 << spio_num);
@@ -1933,13 +2036,16 @@ static void bnx2x_calc_fc_adv(struct bnx2x *bp)
bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
ADVERTISED_Pause);
break;
+
case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH:
bp->port.advertising |= (ADVERTISED_Asym_Pause |
ADVERTISED_Pause);
break;
+
case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC:
bp->port.advertising |= ADVERTISED_Asym_Pause;
break;
+
default:
bp->port.advertising &= ~(ADVERTISED_Asym_Pause |
ADVERTISED_Pause);
@@ -1964,7 +2070,8 @@ static void bnx2x_link_report(struct bnx2x *bp)
if (bp->link_vars.flow_ctrl != BNX2X_FLOW_CTRL_NONE) {
if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) {
printk(", receive ");
- if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ if (bp->link_vars.flow_ctrl &
+ BNX2X_FLOW_CTRL_TX)
printk("& transmit ");
} else {
printk(", transmit ");
@@ -1979,7 +2086,7 @@ static void bnx2x_link_report(struct bnx2x *bp)
}
}
-static u8 bnx2x_initial_phy_init(struct bnx2x *bp)
+static u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
{
if (!BP_NOMCP(bp)) {
u8 rc;
@@ -1995,18 +2102,24 @@ static u8 bnx2x_initial_phy_init(struct bnx2x *bp)
bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH;
bnx2x_acquire_phy_lock(bp);
+
+ if (load_mode == LOAD_DIAG)
+ bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
+
rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars);
+
bnx2x_release_phy_lock(bp);
bnx2x_calc_fc_adv(bp);
- if (bp->link_vars.link_up)
+ if (CHIP_REV_IS_SLOW(bp) && bp->link_vars.link_up) {
+ bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
bnx2x_link_report(bp);
-
+ }
return rc;
}
- BNX2X_ERR("Bootcode is missing -not initializing link\n");
+ BNX2X_ERR("Bootcode is missing - can not initialize link\n");
return -EINVAL;
}
@@ -2019,17 +2132,17 @@ static void bnx2x_link_set(struct bnx2x *bp)
bnx2x_calc_fc_adv(bp);
} else
- BNX2X_ERR("Bootcode is missing -not setting link\n");
+ BNX2X_ERR("Bootcode is missing - can not set link\n");
}
static void bnx2x__link_reset(struct bnx2x *bp)
{
if (!BP_NOMCP(bp)) {
bnx2x_acquire_phy_lock(bp);
- bnx2x_link_reset(&bp->link_params, &bp->link_vars);
+ bnx2x_link_reset(&bp->link_params, &bp->link_vars, 1);
bnx2x_release_phy_lock(bp);
} else
- BNX2X_ERR("Bootcode is missing -not resetting link\n");
+ BNX2X_ERR("Bootcode is missing - can not reset link\n");
}
static u8 bnx2x_link_test(struct bnx2x *bp)
@@ -2043,119 +2156,42 @@ static u8 bnx2x_link_test(struct bnx2x *bp)
return rc;
}
-/* Calculates the sum of vn_min_rates.
- It's needed for further normalizing of the min_rates.
-
- Returns:
- sum of vn_min_rates
- or
- 0 - if all the min_rates are 0.
- In the later case fairness algorithm should be deactivated.
- If not all min_rates are zero then those that are zeroes will
- be set to 1.
- */
-static u32 bnx2x_calc_vn_wsum(struct bnx2x *bp)
+static void bnx2x_init_port_minmax(struct bnx2x *bp)
{
- int i, port = BP_PORT(bp);
- u32 wsum = 0;
- int all_zero = 1;
+ u32 r_param = bp->link_vars.line_speed / 8;
+ u32 fair_periodic_timeout_usec;
+ u32 t_fair;
- for (i = 0; i < E1HVN_MAX; i++) {
- u32 vn_cfg =
- SHMEM_RD(bp, mf_cfg.func_mf_config[2*i + port].config);
- u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
- FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
- if (!(vn_cfg & FUNC_MF_CFG_FUNC_HIDE)) {
- /* If min rate is zero - set it to 1 */
- if (!vn_min_rate)
- vn_min_rate = DEF_MIN_RATE;
- else
- all_zero = 0;
-
- wsum += vn_min_rate;
- }
- }
-
- /* ... only if all min rates are zeros - disable FAIRNESS */
- if (all_zero)
- return 0;
-
- return wsum;
-}
-
-static void bnx2x_init_port_minmax(struct bnx2x *bp,
- int en_fness,
- u16 port_rate,
- struct cmng_struct_per_port *m_cmng_port)
-{
- u32 r_param = port_rate / 8;
- int port = BP_PORT(bp);
- int i;
-
- memset(m_cmng_port, 0, sizeof(struct cmng_struct_per_port));
-
- /* Enable minmax only if we are in e1hmf mode */
- if (IS_E1HMF(bp)) {
- u32 fair_periodic_timeout_usec;
- u32 t_fair;
-
- /* Enable rate shaping and fairness */
- m_cmng_port->flags.cmng_vn_enable = 1;
- m_cmng_port->flags.fairness_enable = en_fness ? 1 : 0;
- m_cmng_port->flags.rate_shaping_enable = 1;
-
- if (!en_fness)
- DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
- " fairness will be disabled\n");
+ memset(&(bp->cmng.rs_vars), 0,
+ sizeof(struct rate_shaping_vars_per_port));
+ memset(&(bp->cmng.fair_vars), 0, sizeof(struct fairness_vars_per_port));
- /* 100 usec in SDM ticks = 25 since each tick is 4 usec */
- m_cmng_port->rs_vars.rs_periodic_timeout =
- RS_PERIODIC_TIMEOUT_USEC / 4;
+ /* 100 usec in SDM ticks = 25 since each tick is 4 usec */
+ bp->cmng.rs_vars.rs_periodic_timeout = RS_PERIODIC_TIMEOUT_USEC / 4;
- /* this is the threshold below which no timer arming will occur
- 1.25 coefficient is for the threshold to be a little bigger
- than the real time, to compensate for timer in-accuracy */
- m_cmng_port->rs_vars.rs_threshold =
+ /* this is the threshold below which no timer arming will occur
+ 1.25 coefficient is for the threshold to be a little bigger
+ than the real time, to compensate for timer in-accuracy */
+ bp->cmng.rs_vars.rs_threshold =
(RS_PERIODIC_TIMEOUT_USEC * r_param * 5) / 4;
- /* resolution of fairness timer */
- fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
- /* for 10G it is 1000usec. for 1G it is 10000usec. */
- t_fair = T_FAIR_COEF / port_rate;
+ /* resolution of fairness timer */
+ fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
+ /* for 10G it is 1000usec. for 1G it is 10000usec. */
+ t_fair = T_FAIR_COEF / bp->link_vars.line_speed;
- /* this is the threshold below which we won't arm
- the timer anymore */
- m_cmng_port->fair_vars.fair_threshold = QM_ARB_BYTES;
+ /* this is the threshold below which we won't arm the timer anymore */
+ bp->cmng.fair_vars.fair_threshold = QM_ARB_BYTES;
- /* we multiply by 1e3/8 to get bytes/msec.
- We don't want the credits to pass a credit
- of the T_FAIR*FAIR_MEM (algorithm resolution) */
- m_cmng_port->fair_vars.upper_bound =
- r_param * t_fair * FAIR_MEM;
- /* since each tick is 4 usec */
- m_cmng_port->fair_vars.fairness_timeout =
- fair_periodic_timeout_usec / 4;
-
- } else {
- /* Disable rate shaping and fairness */
- m_cmng_port->flags.cmng_vn_enable = 0;
- m_cmng_port->flags.fairness_enable = 0;
- m_cmng_port->flags.rate_shaping_enable = 0;
-
- DP(NETIF_MSG_IFUP,
- "Single function mode minmax will be disabled\n");
- }
-
- /* Store it to internal memory */
- for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4,
- ((u32 *)(m_cmng_port))[i]);
+ /* we multiply by 1e3/8 to get bytes/msec.
+ We don't want the credits to pass a credit
+ of the t_fair*FAIR_MEM (algorithm resolution) */
+ bp->cmng.fair_vars.upper_bound = r_param * t_fair * FAIR_MEM;
+ /* since each tick is 4 usec */
+ bp->cmng.fair_vars.fairness_timeout = fair_periodic_timeout_usec / 4;
}
-static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
- u32 wsum, u16 port_rate,
- struct cmng_struct_per_port *m_cmng_port)
+static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func)
{
struct rate_shaping_vars_per_vn m_rs_vn;
struct fairness_vars_per_vn m_fair_vn;
@@ -2171,17 +2207,18 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
} else {
vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
- /* If FAIRNESS is enabled (not all min rates are zeroes) and
+ /* If fairness is enabled (not all min rates are zeroes) and
if current min rate is zero - set it to 1.
This is a requirement of the algorithm. */
- if ((vn_min_rate == 0) && wsum)
+ if (bp->vn_weight_sum && (vn_min_rate == 0))
vn_min_rate = DEF_MIN_RATE;
vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
}
- DP(NETIF_MSG_IFUP, "func %d: vn_min_rate=%d vn_max_rate=%d "
- "wsum=%d\n", func, vn_min_rate, vn_max_rate, wsum);
+ DP(NETIF_MSG_IFUP,
+ "func %d: vn_min_rate=%d vn_max_rate=%d vn_weight_sum=%d\n",
+ func, vn_min_rate, vn_max_rate, bp->vn_weight_sum);
memset(&m_rs_vn, 0, sizeof(struct rate_shaping_vars_per_vn));
memset(&m_fair_vn, 0, sizeof(struct fairness_vars_per_vn));
@@ -2193,55 +2230,20 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
m_rs_vn.vn_counter.quota =
(vn_max_rate * RS_PERIODIC_TIMEOUT_USEC) / 8;
-#ifdef BNX2X_PER_PROT_QOS
- /* per protocol counter */
- for (protocol = 0; protocol < NUM_OF_PROTOCOLS; protocol++) {
- /* maximal Mbps for this protocol */
- m_rs_vn.protocol_counters[protocol].rate =
- protocol_max_rate[protocol];
- /* the quota in each timer period -
- number of bytes transmitted in this period */
- m_rs_vn.protocol_counters[protocol].quota =
- (u32)(rs_periodic_timeout_usec *
- ((double)m_rs_vn.
- protocol_counters[protocol].rate/8));
- }
-#endif
-
- if (wsum) {
+ if (bp->vn_weight_sum) {
/* credit for each period of the fairness algorithm:
number of bytes in T_FAIR (the vn share the port rate).
- wsum should not be larger than 10000, thus
- T_FAIR_COEF / (8 * wsum) will always be grater than zero */
+ vn_weight_sum should not be larger than 10000, thus
+ T_FAIR_COEF / (8 * vn_weight_sum) will always be greater
+ than zero */
m_fair_vn.vn_credit_delta =
- max((u64)(vn_min_rate * (T_FAIR_COEF / (8 * wsum))),
- (u64)(m_cmng_port->fair_vars.fair_threshold * 2));
+ max((u32)(vn_min_rate * (T_FAIR_COEF /
+ (8 * bp->vn_weight_sum))),
+ (u32)(bp->cmng.fair_vars.fair_threshold * 2));
DP(NETIF_MSG_IFUP, "m_fair_vn.vn_credit_delta=%d\n",
m_fair_vn.vn_credit_delta);
}
-#ifdef BNX2X_PER_PROT_QOS
- do {
- u32 protocolWeightSum = 0;
-
- for (protocol = 0; protocol < NUM_OF_PROTOCOLS; protocol++)
- protocolWeightSum +=
- drvInit.protocol_min_rate[protocol];
- /* per protocol counter -
- NOT NEEDED IF NO PER-PROTOCOL CONGESTION MANAGEMENT */
- if (protocolWeightSum > 0) {
- for (protocol = 0;
- protocol < NUM_OF_PROTOCOLS; protocol++)
- /* credit for each period of the
- fairness algorithm - number of bytes in
- T_FAIR (the protocol share the vn rate) */
- m_fair_vn.protocol_credit_delta[protocol] =
- (u32)((vn_min_rate / 8) * t_fair *
- protocol_min_rate / protocolWeightSum);
- }
- } while (0);
-#endif
-
/* Store it to internal memory */
for (i = 0; i < sizeof(struct rate_shaping_vars_per_vn)/4; i++)
REG_WR(bp, BAR_XSTRORM_INTMEM +
@@ -2254,11 +2256,10 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func,
((u32 *)(&m_fair_vn))[i]);
}
+
/* This function is called upon link interrupt */
static void bnx2x_link_attn(struct bnx2x *bp)
{
- int vn;
-
/* Make sure that we are synced with the current statistics */
bnx2x_stats_handle(bp, STATS_EVENT_STOP);
@@ -2266,6 +2267,19 @@ static void bnx2x_link_attn(struct bnx2x *bp)
if (bp->link_vars.link_up) {
+ /* dropless flow control */
+ if (CHIP_IS_E1H(bp)) {
+ int port = BP_PORT(bp);
+ u32 pause_enabled = 0;
+
+ if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
+ pause_enabled = 1;
+
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_PAUSE_ENABLED_OFFSET(port),
+ pause_enabled);
+ }
+
if (bp->link_vars.mac_type == MAC_TYPE_BMAC) {
struct host_port_stats *pstats;
@@ -2283,36 +2297,38 @@ static void bnx2x_link_attn(struct bnx2x *bp)
bnx2x_link_report(bp);
if (IS_E1HMF(bp)) {
+ int port = BP_PORT(bp);
int func;
+ int vn;
for (vn = VN_0; vn < E1HVN_MAX; vn++) {
if (vn == BP_E1HVN(bp))
continue;
- func = ((vn << 1) | BP_PORT(bp));
+ func = ((vn << 1) | port);
/* Set the attention towards other drivers
on the same port */
REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
(LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
}
- }
- if (CHIP_IS_E1H(bp) && (bp->link_vars.line_speed > 0)) {
- struct cmng_struct_per_port m_cmng_port;
- u32 wsum;
- int port = BP_PORT(bp);
+ if (bp->link_vars.link_up) {
+ int i;
+
+ /* Init rate shaping and fairness contexts */
+ bnx2x_init_port_minmax(bp);
- /* Init RATE SHAPING and FAIRNESS contexts */
- wsum = bnx2x_calc_vn_wsum(bp);
- bnx2x_init_port_minmax(bp, (int)wsum,
- bp->link_vars.line_speed,
- &m_cmng_port);
- if (IS_E1HMF(bp))
for (vn = VN_0; vn < E1HVN_MAX; vn++)
- bnx2x_init_vn_minmax(bp, 2*vn + port,
- wsum, bp->link_vars.line_speed,
- &m_cmng_port);
+ bnx2x_init_vn_minmax(bp, 2*vn + port);
+
+ /* Store it to internal memory */
+ for (i = 0;
+ i < sizeof(struct cmng_struct_per_port) / 4; i++)
+ REG_WR(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4,
+ ((u32 *)(&bp->cmng))[i]);
+ }
}
}
@@ -2489,6 +2505,7 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
NIG_REG_MASK_INTERRUPT_PORT0;
u32 aeu_mask;
+ u32 nig_mask = 0;
if (bp->attn_state & asserted)
BNX2X_ERR("IGU ERROR\n");
@@ -2514,7 +2531,7 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
bnx2x_acquire_phy_lock(bp);
/* save nig interrupt mask */
- bp->nig_mask = REG_RD(bp, nig_int_mask_addr);
+ nig_mask = REG_RD(bp, nig_int_mask_addr);
REG_WR(bp, nig_int_mask_addr, 0);
bnx2x_link_attn(bp);
@@ -2569,7 +2586,7 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
/* now set back the mask */
if (asserted & ATTN_NIG_FOR_FUNC) {
- REG_WR(bp, nig_int_mask_addr, bp->nig_mask);
+ REG_WR(bp, nig_int_mask_addr, nig_mask);
bnx2x_release_phy_lock(bp);
}
}
@@ -2591,9 +2608,8 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
BNX2X_ERR("SPIO5 hw attention\n");
- switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G:
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
/* Fan failure attention */
/* The PHY reset is controlled by GPIO 1 */
@@ -2624,6 +2640,13 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
}
}
+ if (attn & (AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 |
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1)) {
+ bnx2x_acquire_phy_lock(bp);
+ bnx2x_handle_module_detect_int(&bp->link_params);
+ bnx2x_release_phy_lock(bp);
+ }
+
if (attn & HW_INTERRUT_ASSERT_SET_0) {
val = REG_RD(bp, reg_offset);
@@ -2640,7 +2663,7 @@ static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn)
{
u32 val;
- if (attn & BNX2X_DOORQ_ASSERT) {
+ if (attn & AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT) {
val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
BNX2X_ERR("DB hw attention 0x%x\n", val);
@@ -2886,10 +2909,6 @@ static void bnx2x_sp_task(struct work_struct *work)
if (status & 0x1)
bnx2x_attn_int(bp);
- /* CStorm events: query_stats, port delete ramrod */
- if (status & 0x2)
- bp->stats_pending = 0;
-
bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, le16_to_cpu(bp->def_att_idx),
IGU_INT_NOP, 1);
bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx),
@@ -2914,7 +2933,7 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
return IRQ_HANDLED;
}
- bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, 0, IGU_INT_DISABLE, 0);
+ bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, 0, IGU_INT_DISABLE, 0);
#ifdef BNX2X_STOP_ON_ERROR
if (unlikely(bp->panic))
@@ -3003,16 +3022,41 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
#define UPDATE_EXTEND_TSTAT(s, t) \
do { \
- diff = le32_to_cpu(tclient->s) - old_tclient->s; \
- old_tclient->s = le32_to_cpu(tclient->s); \
- ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
+ diff = le32_to_cpu(tclient->s) - le32_to_cpu(old_tclient->s); \
+ old_tclient->s = tclient->s; \
+ ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
+ } while (0)
+
+#define UPDATE_EXTEND_USTAT(s, t) \
+ do { \
+ diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \
+ old_uclient->s = uclient->s; \
+ ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
} while (0)
#define UPDATE_EXTEND_XSTAT(s, t) \
do { \
- diff = le32_to_cpu(xclient->s) - old_xclient->s; \
- old_xclient->s = le32_to_cpu(xclient->s); \
- ADD_EXTEND_64(fstats->t##_hi, fstats->t##_lo, diff); \
+ diff = le32_to_cpu(xclient->s) - le32_to_cpu(old_xclient->s); \
+ old_xclient->s = xclient->s; \
+ ADD_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
+ } while (0)
+
+/* minuend -= subtrahend */
+#define SUB_64(m_hi, s_hi, m_lo, s_lo) \
+ do { \
+ DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \
+ } while (0)
+
+/* minuend[hi:lo] -= subtrahend */
+#define SUB_EXTEND_64(m_hi, m_lo, s) \
+ do { \
+ SUB_64(m_hi, 0, m_lo, s); \
+ } while (0)
+
+#define SUB_EXTEND_USTAT(s, t) \
+ do { \
+ diff = le32_to_cpu(uclient->s) - le32_to_cpu(old_uclient->s); \
+ SUB_EXTEND_64(qstats->t##_hi, qstats->t##_lo, diff); \
} while (0)
/*
@@ -3039,11 +3083,12 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp)
{
if (!bp->stats_pending) {
struct eth_query_ramrod_data ramrod_data = {0};
- int rc;
+ int i, rc;
ramrod_data.drv_counter = bp->stats_counter++;
- ramrod_data.collect_port_1b = bp->port.pmf ? 1 : 0;
- ramrod_data.ctr_id_vector = (1 << BP_CL_ID(bp));
+ ramrod_data.collect_port = bp->port.pmf ? 1 : 0;
+ for_each_queue(bp, i)
+ ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id);
rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0,
((u32 *)&ramrod_data)[1],
@@ -3059,7 +3104,9 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp)
static void bnx2x_stats_init(struct bnx2x *bp)
{
int port = BP_PORT(bp);
+ int i;
+ bp->stats_pending = 0;
bp->executer_idx = 0;
bp->stats_counter = 0;
@@ -3081,9 +3128,19 @@ static void bnx2x_stats_init(struct bnx2x *bp)
&(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2);
/* function stats */
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ memset(&fp->old_tclient, 0,
+ sizeof(struct tstorm_per_client_stats));
+ memset(&fp->old_uclient, 0,
+ sizeof(struct ustorm_per_client_stats));
+ memset(&fp->old_xclient, 0,
+ sizeof(struct xstorm_per_client_stats));
+ memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats));
+ }
+
memset(&bp->dev->stats, 0, sizeof(struct net_device_stats));
- memset(&bp->old_tclient, 0, sizeof(struct tstorm_per_client_stats));
- memset(&bp->old_xclient, 0, sizeof(struct xstorm_per_client_stats));
memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats));
bp->stats_state = STATS_STATE_DISABLED;
@@ -3097,6 +3154,8 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp)
u32 *stats_comp = bnx2x_sp(bp, stats_comp);
*stats_comp = DMAE_COMP_VAL;
+ if (CHIP_REV_IS_SLOW(bp))
+ return;
/* loader */
if (bp->executer_idx) {
@@ -3486,7 +3545,11 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp)
{
struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats);
struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
- struct regpair diff;
+ struct bnx2x_eth_stats *estats = &bp->eth_stats;
+ struct {
+ u32 lo;
+ u32 hi;
+ } diff;
UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets);
UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors);
@@ -3496,7 +3559,7 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp)
UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers);
UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived);
UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered);
- UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffpauseframesreceived);
+ UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf);
UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent);
UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone);
UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets);
@@ -3517,12 +3580,23 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp)
UPDATE_STAT64(tx_stat_gterr,
tx_stat_dot3statsinternalmactransmiterrors);
UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl);
+
+ estats->pause_frames_received_hi =
+ pstats->mac_stx[1].rx_stat_bmac_xpf_hi;
+ estats->pause_frames_received_lo =
+ pstats->mac_stx[1].rx_stat_bmac_xpf_lo;
+
+ estats->pause_frames_sent_hi =
+ pstats->mac_stx[1].tx_stat_outxoffsent_hi;
+ estats->pause_frames_sent_lo =
+ pstats->mac_stx[1].tx_stat_outxoffsent_lo;
}
static void bnx2x_emac_stats_update(struct bnx2x *bp)
{
struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac_stats);
struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
+ struct bnx2x_eth_stats *estats = &bp->eth_stats;
UPDATE_EXTEND_STAT(rx_stat_ifhcinbadoctets);
UPDATE_EXTEND_STAT(tx_stat_ifhcoutbadoctets);
@@ -3555,6 +3629,24 @@ static void bnx2x_emac_stats_update(struct bnx2x *bp)
UPDATE_EXTEND_STAT(tx_stat_etherstatspkts1024octetsto1522octets);
UPDATE_EXTEND_STAT(tx_stat_etherstatspktsover1522octets);
UPDATE_EXTEND_STAT(tx_stat_dot3statsinternalmactransmiterrors);
+
+ estats->pause_frames_received_hi =
+ pstats->mac_stx[1].rx_stat_xonpauseframesreceived_hi;
+ estats->pause_frames_received_lo =
+ pstats->mac_stx[1].rx_stat_xonpauseframesreceived_lo;
+ ADD_64(estats->pause_frames_received_hi,
+ pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_hi,
+ estats->pause_frames_received_lo,
+ pstats->mac_stx[1].rx_stat_xoffpauseframesreceived_lo);
+
+ estats->pause_frames_sent_hi =
+ pstats->mac_stx[1].tx_stat_outxonsent_hi;
+ estats->pause_frames_sent_lo =
+ pstats->mac_stx[1].tx_stat_outxonsent_lo;
+ ADD_64(estats->pause_frames_sent_hi,
+ pstats->mac_stx[1].tx_stat_outxoffsent_hi,
+ estats->pause_frames_sent_lo,
+ pstats->mac_stx[1].tx_stat_outxoffsent_lo);
}
static int bnx2x_hw_stats_update(struct bnx2x *bp)
@@ -3563,7 +3655,11 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp)
struct nig_stats *old = &(bp->port.old_nig_stats);
struct host_port_stats *pstats = bnx2x_sp(bp, port_stats);
struct bnx2x_eth_stats *estats = &bp->eth_stats;
- struct regpair diff;
+ struct {
+ u32 lo;
+ u32 hi;
+ } diff;
+ u32 nig_timer_max;
if (bp->link_vars.mac_type == MAC_TYPE_BMAC)
bnx2x_bmac_stats_update(bp);
@@ -3572,7 +3668,7 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp)
bnx2x_emac_stats_update(bp);
else { /* unreached */
- BNX2X_ERR("stats updated by dmae but no MAC active\n");
+ BNX2X_ERR("stats updated by DMAE but no MAC active\n");
return -1;
}
@@ -3594,134 +3690,211 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp)
pstats->host_port_stats_start = ++pstats->host_port_stats_end;
+ nig_timer_max = SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer);
+ if (nig_timer_max != estats->nig_timer_max) {
+ estats->nig_timer_max = nig_timer_max;
+ BNX2X_ERR("NIG timer max (%u)\n", estats->nig_timer_max);
+ }
+
return 0;
}
static int bnx2x_storm_stats_update(struct bnx2x *bp)
{
struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats);
- int cl_id = BP_CL_ID(bp);
struct tstorm_per_port_stats *tport =
- &stats->tstorm_common.port_statistics;
- struct tstorm_per_client_stats *tclient =
- &stats->tstorm_common.client_statistics[cl_id];
- struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
- struct xstorm_per_client_stats *xclient =
- &stats->xstorm_common.client_statistics[cl_id];
- struct xstorm_per_client_stats *old_xclient = &bp->old_xclient;
+ &stats->tstorm_common.port_statistics;
struct host_func_stats *fstats = bnx2x_sp(bp, func_stats);
struct bnx2x_eth_stats *estats = &bp->eth_stats;
- u32 diff;
+ int i;
- /* are storm stats valid? */
- if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) !=
+ memset(&(fstats->total_bytes_received_hi), 0,
+ sizeof(struct host_func_stats) - 2*sizeof(u32));
+ estats->error_bytes_received_hi = 0;
+ estats->error_bytes_received_lo = 0;
+ estats->etherstatsoverrsizepkts_hi = 0;
+ estats->etherstatsoverrsizepkts_lo = 0;
+ estats->no_buff_discard_hi = 0;
+ estats->no_buff_discard_lo = 0;
+
+ for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+ int cl_id = fp->cl_id;
+ struct tstorm_per_client_stats *tclient =
+ &stats->tstorm_common.client_statistics[cl_id];
+ struct tstorm_per_client_stats *old_tclient = &fp->old_tclient;
+ struct ustorm_per_client_stats *uclient =
+ &stats->ustorm_common.client_statistics[cl_id];
+ struct ustorm_per_client_stats *old_uclient = &fp->old_uclient;
+ struct xstorm_per_client_stats *xclient =
+ &stats->xstorm_common.client_statistics[cl_id];
+ struct xstorm_per_client_stats *old_xclient = &fp->old_xclient;
+ struct bnx2x_eth_q_stats *qstats = &fp->eth_q_stats;
+ u32 diff;
+
+ /* are storm stats valid? */
+ if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) !=
bp->stats_counter) {
- DP(BNX2X_MSG_STATS, "stats not updated by tstorm"
- " tstorm counter (%d) != stats_counter (%d)\n",
- tclient->stats_counter, bp->stats_counter);
- return -1;
- }
- if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) !=
+ DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm"
+ " xstorm counter (%d) != stats_counter (%d)\n",
+ i, xclient->stats_counter, bp->stats_counter);
+ return -1;
+ }
+ if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) !=
bp->stats_counter) {
- DP(BNX2X_MSG_STATS, "stats not updated by xstorm"
- " xstorm counter (%d) != stats_counter (%d)\n",
- xclient->stats_counter, bp->stats_counter);
- return -2;
- }
+ DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm"
+ " tstorm counter (%d) != stats_counter (%d)\n",
+ i, tclient->stats_counter, bp->stats_counter);
+ return -2;
+ }
+ if ((u16)(le16_to_cpu(uclient->stats_counter) + 1) !=
+ bp->stats_counter) {
+ DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm"
+ " ustorm counter (%d) != stats_counter (%d)\n",
+ i, uclient->stats_counter, bp->stats_counter);
+ return -4;
+ }
- fstats->total_bytes_received_hi =
- fstats->valid_bytes_received_hi =
+ qstats->total_bytes_received_hi =
+ qstats->valid_bytes_received_hi =
le32_to_cpu(tclient->total_rcv_bytes.hi);
- fstats->total_bytes_received_lo =
- fstats->valid_bytes_received_lo =
+ qstats->total_bytes_received_lo =
+ qstats->valid_bytes_received_lo =
le32_to_cpu(tclient->total_rcv_bytes.lo);
- estats->error_bytes_received_hi =
+ qstats->error_bytes_received_hi =
le32_to_cpu(tclient->rcv_error_bytes.hi);
- estats->error_bytes_received_lo =
+ qstats->error_bytes_received_lo =
le32_to_cpu(tclient->rcv_error_bytes.lo);
- ADD_64(estats->error_bytes_received_hi,
- estats->rx_stat_ifhcinbadoctets_hi,
- estats->error_bytes_received_lo,
- estats->rx_stat_ifhcinbadoctets_lo);
- ADD_64(fstats->total_bytes_received_hi,
- estats->error_bytes_received_hi,
- fstats->total_bytes_received_lo,
- estats->error_bytes_received_lo);
-
- UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, total_unicast_packets_received);
- UPDATE_EXTEND_TSTAT(rcv_multicast_pkts,
- total_multicast_packets_received);
- UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts,
- total_broadcast_packets_received);
-
- fstats->total_bytes_transmitted_hi =
+ ADD_64(qstats->total_bytes_received_hi,
+ qstats->error_bytes_received_hi,
+ qstats->total_bytes_received_lo,
+ qstats->error_bytes_received_lo);
+
+ UPDATE_EXTEND_TSTAT(rcv_unicast_pkts,
+ total_unicast_packets_received);
+ UPDATE_EXTEND_TSTAT(rcv_multicast_pkts,
+ total_multicast_packets_received);
+ UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts,
+ total_broadcast_packets_received);
+ UPDATE_EXTEND_TSTAT(packets_too_big_discard,
+ etherstatsoverrsizepkts);
+ UPDATE_EXTEND_TSTAT(no_buff_discard, no_buff_discard);
+
+ SUB_EXTEND_USTAT(ucast_no_buff_pkts,
+ total_unicast_packets_received);
+ SUB_EXTEND_USTAT(mcast_no_buff_pkts,
+ total_multicast_packets_received);
+ SUB_EXTEND_USTAT(bcast_no_buff_pkts,
+ total_broadcast_packets_received);
+ UPDATE_EXTEND_USTAT(ucast_no_buff_pkts, no_buff_discard);
+ UPDATE_EXTEND_USTAT(mcast_no_buff_pkts, no_buff_discard);
+ UPDATE_EXTEND_USTAT(bcast_no_buff_pkts, no_buff_discard);
+
+ qstats->total_bytes_transmitted_hi =
le32_to_cpu(xclient->total_sent_bytes.hi);
- fstats->total_bytes_transmitted_lo =
+ qstats->total_bytes_transmitted_lo =
le32_to_cpu(xclient->total_sent_bytes.lo);
- UPDATE_EXTEND_XSTAT(unicast_pkts_sent,
- total_unicast_packets_transmitted);
- UPDATE_EXTEND_XSTAT(multicast_pkts_sent,
- total_multicast_packets_transmitted);
- UPDATE_EXTEND_XSTAT(broadcast_pkts_sent,
- total_broadcast_packets_transmitted);
+ UPDATE_EXTEND_XSTAT(unicast_pkts_sent,
+ total_unicast_packets_transmitted);
+ UPDATE_EXTEND_XSTAT(multicast_pkts_sent,
+ total_multicast_packets_transmitted);
+ UPDATE_EXTEND_XSTAT(broadcast_pkts_sent,
+ total_broadcast_packets_transmitted);
+
+ old_tclient->checksum_discard = tclient->checksum_discard;
+ old_tclient->ttl0_discard = tclient->ttl0_discard;
+
+ ADD_64(fstats->total_bytes_received_hi,
+ qstats->total_bytes_received_hi,
+ fstats->total_bytes_received_lo,
+ qstats->total_bytes_received_lo);
+ ADD_64(fstats->total_bytes_transmitted_hi,
+ qstats->total_bytes_transmitted_hi,
+ fstats->total_bytes_transmitted_lo,
+ qstats->total_bytes_transmitted_lo);
+ ADD_64(fstats->total_unicast_packets_received_hi,
+ qstats->total_unicast_packets_received_hi,
+ fstats->total_unicast_packets_received_lo,
+ qstats->total_unicast_packets_received_lo);
+ ADD_64(fstats->total_multicast_packets_received_hi,
+ qstats->total_multicast_packets_received_hi,
+ fstats->total_multicast_packets_received_lo,
+ qstats->total_multicast_packets_received_lo);
+ ADD_64(fstats->total_broadcast_packets_received_hi,
+ qstats->total_broadcast_packets_received_hi,
+ fstats->total_broadcast_packets_received_lo,
+ qstats->total_broadcast_packets_received_lo);
+ ADD_64(fstats->total_unicast_packets_transmitted_hi,
+ qstats->total_unicast_packets_transmitted_hi,
+ fstats->total_unicast_packets_transmitted_lo,
+ qstats->total_unicast_packets_transmitted_lo);
+ ADD_64(fstats->total_multicast_packets_transmitted_hi,
+ qstats->total_multicast_packets_transmitted_hi,
+ fstats->total_multicast_packets_transmitted_lo,
+ qstats->total_multicast_packets_transmitted_lo);
+ ADD_64(fstats->total_broadcast_packets_transmitted_hi,
+ qstats->total_broadcast_packets_transmitted_hi,
+ fstats->total_broadcast_packets_transmitted_lo,
+ qstats->total_broadcast_packets_transmitted_lo);
+ ADD_64(fstats->valid_bytes_received_hi,
+ qstats->valid_bytes_received_hi,
+ fstats->valid_bytes_received_lo,
+ qstats->valid_bytes_received_lo);
+
+ ADD_64(estats->error_bytes_received_hi,
+ qstats->error_bytes_received_hi,
+ estats->error_bytes_received_lo,
+ qstats->error_bytes_received_lo);
+ ADD_64(estats->etherstatsoverrsizepkts_hi,
+ qstats->etherstatsoverrsizepkts_hi,
+ estats->etherstatsoverrsizepkts_lo,
+ qstats->etherstatsoverrsizepkts_lo);
+ ADD_64(estats->no_buff_discard_hi, qstats->no_buff_discard_hi,
+ estats->no_buff_discard_lo, qstats->no_buff_discard_lo);
+ }
+
+ ADD_64(fstats->total_bytes_received_hi,
+ estats->rx_stat_ifhcinbadoctets_hi,
+ fstats->total_bytes_received_lo,
+ estats->rx_stat_ifhcinbadoctets_lo);
memcpy(estats, &(fstats->total_bytes_received_hi),
sizeof(struct host_func_stats) - 2*sizeof(u32));
- estats->mac_filter_discard = le32_to_cpu(tport->mac_filter_discard);
- estats->xxoverflow_discard = le32_to_cpu(tport->xxoverflow_discard);
- estats->brb_truncate_discard =
+ ADD_64(estats->etherstatsoverrsizepkts_hi,
+ estats->rx_stat_dot3statsframestoolong_hi,
+ estats->etherstatsoverrsizepkts_lo,
+ estats->rx_stat_dot3statsframestoolong_lo);
+ ADD_64(estats->error_bytes_received_hi,
+ estats->rx_stat_ifhcinbadoctets_hi,
+ estats->error_bytes_received_lo,
+ estats->rx_stat_ifhcinbadoctets_lo);
+
+ if (bp->port.pmf) {
+ estats->mac_filter_discard =
+ le32_to_cpu(tport->mac_filter_discard);
+ estats->xxoverflow_discard =
+ le32_to_cpu(tport->xxoverflow_discard);
+ estats->brb_truncate_discard =
le32_to_cpu(tport->brb_truncate_discard);
- estats->mac_discard = le32_to_cpu(tport->mac_discard);
-
- old_tclient->rcv_unicast_bytes.hi =
- le32_to_cpu(tclient->rcv_unicast_bytes.hi);
- old_tclient->rcv_unicast_bytes.lo =
- le32_to_cpu(tclient->rcv_unicast_bytes.lo);
- old_tclient->rcv_broadcast_bytes.hi =
- le32_to_cpu(tclient->rcv_broadcast_bytes.hi);
- old_tclient->rcv_broadcast_bytes.lo =
- le32_to_cpu(tclient->rcv_broadcast_bytes.lo);
- old_tclient->rcv_multicast_bytes.hi =
- le32_to_cpu(tclient->rcv_multicast_bytes.hi);
- old_tclient->rcv_multicast_bytes.lo =
- le32_to_cpu(tclient->rcv_multicast_bytes.lo);
- old_tclient->total_rcv_pkts = le32_to_cpu(tclient->total_rcv_pkts);
-
- old_tclient->checksum_discard = le32_to_cpu(tclient->checksum_discard);
- old_tclient->packets_too_big_discard =
- le32_to_cpu(tclient->packets_too_big_discard);
- estats->no_buff_discard =
- old_tclient->no_buff_discard = le32_to_cpu(tclient->no_buff_discard);
- old_tclient->ttl0_discard = le32_to_cpu(tclient->ttl0_discard);
-
- old_xclient->total_sent_pkts = le32_to_cpu(xclient->total_sent_pkts);
- old_xclient->unicast_bytes_sent.hi =
- le32_to_cpu(xclient->unicast_bytes_sent.hi);
- old_xclient->unicast_bytes_sent.lo =
- le32_to_cpu(xclient->unicast_bytes_sent.lo);
- old_xclient->multicast_bytes_sent.hi =
- le32_to_cpu(xclient->multicast_bytes_sent.hi);
- old_xclient->multicast_bytes_sent.lo =
- le32_to_cpu(xclient->multicast_bytes_sent.lo);
- old_xclient->broadcast_bytes_sent.hi =
- le32_to_cpu(xclient->broadcast_bytes_sent.hi);
- old_xclient->broadcast_bytes_sent.lo =
- le32_to_cpu(xclient->broadcast_bytes_sent.lo);
+ estats->mac_discard = le32_to_cpu(tport->mac_discard);
+ }
fstats->host_func_stats_start = ++fstats->host_func_stats_end;
+ bp->stats_pending = 0;
+
return 0;
}
static void bnx2x_net_stats_update(struct bnx2x *bp)
{
- struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
struct bnx2x_eth_stats *estats = &bp->eth_stats;
struct net_device_stats *nstats = &bp->dev->stats;
+ int i;
nstats->rx_packets =
bnx2x_hilo(&estats->total_unicast_packets_received_hi) +
@@ -3733,34 +3906,33 @@ static void bnx2x_net_stats_update(struct bnx2x *bp)
bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) +
bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi);
- nstats->rx_bytes = bnx2x_hilo(&estats->valid_bytes_received_hi);
+ nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi);
nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
- nstats->rx_dropped = old_tclient->checksum_discard +
- estats->mac_discard;
+ nstats->rx_dropped = estats->mac_discard;
+ for_each_queue(bp, i)
+ nstats->rx_dropped +=
+ le32_to_cpu(bp->fp[i].old_tclient.checksum_discard);
+
nstats->tx_dropped = 0;
nstats->multicast =
- bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi);
+ bnx2x_hilo(&estats->total_multicast_packets_received_hi);
nstats->collisions =
- estats->tx_stat_dot3statssinglecollisionframes_lo +
- estats->tx_stat_dot3statsmultiplecollisionframes_lo +
- estats->tx_stat_dot3statslatecollisions_lo +
- estats->tx_stat_dot3statsexcessivecollisions_lo;
-
- estats->jabber_packets_received =
- old_tclient->packets_too_big_discard +
- estats->rx_stat_dot3statsframestoolong_lo;
+ bnx2x_hilo(&estats->tx_stat_etherstatscollisions_hi);
nstats->rx_length_errors =
- estats->rx_stat_etherstatsundersizepkts_lo +
- estats->jabber_packets_received;
- nstats->rx_over_errors = estats->brb_drop_lo + estats->brb_truncate_lo;
- nstats->rx_crc_errors = estats->rx_stat_dot3statsfcserrors_lo;
- nstats->rx_frame_errors = estats->rx_stat_dot3statsalignmenterrors_lo;
- nstats->rx_fifo_errors = old_tclient->no_buff_discard;
+ bnx2x_hilo(&estats->rx_stat_etherstatsundersizepkts_hi) +
+ bnx2x_hilo(&estats->etherstatsoverrsizepkts_hi);
+ nstats->rx_over_errors = bnx2x_hilo(&estats->brb_drop_hi) +
+ bnx2x_hilo(&estats->brb_truncate_hi);
+ nstats->rx_crc_errors =
+ bnx2x_hilo(&estats->rx_stat_dot3statsfcserrors_hi);
+ nstats->rx_frame_errors =
+ bnx2x_hilo(&estats->rx_stat_dot3statsalignmenterrors_hi);
+ nstats->rx_fifo_errors = bnx2x_hilo(&estats->no_buff_discard_hi);
nstats->rx_missed_errors = estats->xxoverflow_discard;
nstats->rx_errors = nstats->rx_length_errors +
@@ -3771,46 +3943,61 @@ static void bnx2x_net_stats_update(struct bnx2x *bp)
nstats->rx_missed_errors;
nstats->tx_aborted_errors =
- estats->tx_stat_dot3statslatecollisions_lo +
- estats->tx_stat_dot3statsexcessivecollisions_lo;
- nstats->tx_carrier_errors = estats->rx_stat_falsecarriererrors_lo;
+ bnx2x_hilo(&estats->tx_stat_dot3statslatecollisions_hi) +
+ bnx2x_hilo(&estats->tx_stat_dot3statsexcessivecollisions_hi);
+ nstats->tx_carrier_errors =
+ bnx2x_hilo(&estats->rx_stat_dot3statscarriersenseerrors_hi);
nstats->tx_fifo_errors = 0;
nstats->tx_heartbeat_errors = 0;
nstats->tx_window_errors = 0;
nstats->tx_errors = nstats->tx_aborted_errors +
- nstats->tx_carrier_errors;
+ nstats->tx_carrier_errors +
+ bnx2x_hilo(&estats->tx_stat_dot3statsinternalmactransmiterrors_hi);
+}
+
+static void bnx2x_drv_stats_update(struct bnx2x *bp)
+{
+ struct bnx2x_eth_stats *estats = &bp->eth_stats;
+ int i;
+
+ estats->driver_xoff = 0;
+ estats->rx_err_discard_pkt = 0;
+ estats->rx_skb_alloc_failed = 0;
+ estats->hw_csum_err = 0;
+ for_each_queue(bp, i) {
+ struct bnx2x_eth_q_stats *qstats = &bp->fp[i].eth_q_stats;
+
+ estats->driver_xoff += qstats->driver_xoff;
+ estats->rx_err_discard_pkt += qstats->rx_err_discard_pkt;
+ estats->rx_skb_alloc_failed += qstats->rx_skb_alloc_failed;
+ estats->hw_csum_err += qstats->hw_csum_err;
+ }
}
static void bnx2x_stats_update(struct bnx2x *bp)
{
u32 *stats_comp = bnx2x_sp(bp, stats_comp);
- int update = 0;
if (*stats_comp != DMAE_COMP_VAL)
return;
if (bp->port.pmf)
- update = (bnx2x_hw_stats_update(bp) == 0);
-
- update |= (bnx2x_storm_stats_update(bp) == 0);
-
- if (update)
- bnx2x_net_stats_update(bp);
+ bnx2x_hw_stats_update(bp);
- else {
- if (bp->stats_pending) {
- bp->stats_pending++;
- if (bp->stats_pending == 3) {
- BNX2X_ERR("stats not updated for 3 times\n");
- bnx2x_panic();
- return;
- }
- }
+ if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) {
+ BNX2X_ERR("storm stats were not updated for 3 times\n");
+ bnx2x_panic();
+ return;
}
+ bnx2x_net_stats_update(bp);
+ bnx2x_drv_stats_update(bp);
+
if (bp->msglevel & NETIF_MSG_TIMER) {
- struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
+ struct tstorm_per_client_stats *old_tclient =
+ &bp->fp->old_tclient;
+ struct bnx2x_eth_q_stats *qstats = &bp->fp->eth_q_stats;
struct bnx2x_eth_stats *estats = &bp->eth_stats;
struct net_device_stats *nstats = &bp->dev->stats;
int i;
@@ -3825,20 +4012,22 @@ static void bnx2x_stats_update(struct bnx2x *bp)
(u16)(le16_to_cpu(*bp->fp->rx_cons_sb) -
bp->fp->rx_comp_cons),
le16_to_cpu(*bp->fp->rx_cons_sb), nstats->rx_packets);
- printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u\n",
- netif_queue_stopped(bp->dev) ? "Xoff" : "Xon",
- estats->driver_xoff, estats->brb_drop_lo);
+ printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u "
+ "brb truncate %u\n",
+ (netif_queue_stopped(bp->dev) ? "Xoff" : "Xon"),
+ qstats->driver_xoff,
+ estats->brb_drop_lo, estats->brb_truncate_lo);
printk(KERN_DEBUG "tstats: checksum_discard %u "
- "packets_too_big_discard %u no_buff_discard %u "
+ "packets_too_big_discard %lu no_buff_discard %lu "
"mac_discard %u mac_filter_discard %u "
"xxovrflow_discard %u brb_truncate_discard %u "
"ttl0_discard %u\n",
- old_tclient->checksum_discard,
- old_tclient->packets_too_big_discard,
- old_tclient->no_buff_discard, estats->mac_discard,
- estats->mac_filter_discard, estats->xxoverflow_discard,
- estats->brb_truncate_discard,
- old_tclient->ttl0_discard);
+ le32_to_cpu(old_tclient->checksum_discard),
+ bnx2x_hilo(&qstats->etherstatsoverrsizepkts_hi),
+ bnx2x_hilo(&qstats->no_buff_discard_hi),
+ estats->mac_discard, estats->mac_filter_discard,
+ estats->xxoverflow_discard, estats->brb_truncate_discard,
+ le32_to_cpu(old_tclient->ttl0_discard));
for_each_queue(bp, i) {
printk(KERN_DEBUG "[%d]: %lu\t%lu\t%lu\n", i,
@@ -3987,7 +4176,7 @@ static void bnx2x_timer(unsigned long data)
struct bnx2x_fastpath *fp = &bp->fp[0];
int rc;
- bnx2x_tx_int(fp, 1000);
+ bnx2x_tx_int(fp);
rc = bnx2x_rx_int(fp, 1000);
}
@@ -4239,10 +4428,6 @@ static void bnx2x_update_coalesce(struct bnx2x *bp)
USTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
U_SB_ETH_RX_CQ_INDEX),
bp->rx_ticks ? 0 : 1);
- REG_WR16(bp, BAR_USTRORM_INTMEM +
- USTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
- U_SB_ETH_RX_BD_INDEX),
- bp->rx_ticks ? 0 : 1);
/* HC_INDEX_C_ETH_TX_CQ_CONS */
REG_WR8(bp, BAR_CSTRORM_INTMEM +
@@ -4273,8 +4458,7 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp,
if (fp->tpa_state[i] == BNX2X_TPA_START)
pci_unmap_single(bp->pdev,
pci_unmap_addr(rx_buf, mapping),
- bp->rx_buf_size,
- PCI_DMA_FROMDEVICE);
+ bp->rx_buf_size, PCI_DMA_FROMDEVICE);
dev_kfree_skb(skb);
rx_buf->skb = NULL;
@@ -4289,16 +4473,13 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp)
u16 ring_prod, cqe_ring_prod;
int i, j;
- bp->rx_buf_size = bp->dev->mtu;
- bp->rx_buf_size += bp->rx_offset + ETH_OVREHEAD +
- BCM_RX_ETH_PAYLOAD_ALIGN;
+ bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN;
+ DP(NETIF_MSG_IFUP,
+ "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size);
if (bp->flags & TPA_ENABLE_FLAG) {
- DP(NETIF_MSG_IFUP,
- "rx_buf_size %d effective_mtu %d\n",
- bp->rx_buf_size, bp->dev->mtu + ETH_OVREHEAD);
- for_each_queue(bp, j) {
+ for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
for (i = 0; i < max_agg_queues; i++) {
@@ -4321,7 +4502,7 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp)
}
}
- for_each_queue(bp, j) {
+ for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
fp->rx_bd_cons = 0;
@@ -4396,8 +4577,8 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp)
for (i = 0; i < bp->rx_ring_size; i++) {
if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
BNX2X_ERR("was only able to allocate "
- "%d rx skbs\n", i);
- bp->eth_stats.rx_skb_alloc_failed++;
+ "%d rx skbs on queue[%d]\n", i, j);
+ fp->eth_q_stats.rx_skb_alloc_failed++;
break;
}
ring_prod = NEXT_RX_IDX(ring_prod);
@@ -4433,7 +4614,7 @@ static void bnx2x_init_tx_ring(struct bnx2x *bp)
{
int i, j;
- for_each_queue(bp, j) {
+ for_each_tx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
for (i = 1; i <= NUM_TX_RINGS; i++) {
@@ -4486,27 +4667,20 @@ static void bnx2x_init_context(struct bnx2x *bp)
for_each_queue(bp, i) {
struct eth_context *context = bnx2x_sp(bp, context[i].eth);
struct bnx2x_fastpath *fp = &bp->fp[i];
- u8 sb_id = FP_SB_ID(fp);
-
- context->xstorm_st_context.tx_bd_page_base_hi =
- U64_HI(fp->tx_desc_mapping);
- context->xstorm_st_context.tx_bd_page_base_lo =
- U64_LO(fp->tx_desc_mapping);
- context->xstorm_st_context.db_data_addr_hi =
- U64_HI(fp->tx_prods_mapping);
- context->xstorm_st_context.db_data_addr_lo =
- U64_LO(fp->tx_prods_mapping);
- context->xstorm_st_context.statistics_data = (BP_CL_ID(bp) |
- XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE);
+ u8 cl_id = fp->cl_id;
+ u8 sb_id = fp->sb_id;
context->ustorm_st_context.common.sb_index_numbers =
BNX2X_RX_SB_INDEX_NUM;
- context->ustorm_st_context.common.clientId = FP_CL_ID(fp);
+ context->ustorm_st_context.common.clientId = cl_id;
context->ustorm_st_context.common.status_block_id = sb_id;
context->ustorm_st_context.common.flags =
- USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT;
- context->ustorm_st_context.common.mc_alignment_size =
- BCM_RX_ETH_PAYLOAD_ALIGN;
+ (USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT |
+ USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS);
+ context->ustorm_st_context.common.statistics_counter_id =
+ cl_id;
+ context->ustorm_st_context.common.mc_alignment_log_size =
+ BNX2X_RX_ALIGN_SHIFT;
context->ustorm_st_context.common.bd_buff_size =
bp->rx_buf_size;
context->ustorm_st_context.common.bd_page_base_hi =
@@ -4526,6 +4700,21 @@ static void bnx2x_init_context(struct bnx2x *bp)
U64_LO(fp->rx_sge_mapping);
}
+ context->ustorm_ag_context.cdu_usage =
+ CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
+ CDU_REGION_NUMBER_UCM_AG,
+ ETH_CONNECTION_TYPE);
+
+ context->xstorm_st_context.tx_bd_page_base_hi =
+ U64_HI(fp->tx_desc_mapping);
+ context->xstorm_st_context.tx_bd_page_base_lo =
+ U64_LO(fp->tx_desc_mapping);
+ context->xstorm_st_context.db_data_addr_hi =
+ U64_HI(fp->tx_prods_mapping);
+ context->xstorm_st_context.db_data_addr_lo =
+ U64_LO(fp->tx_prods_mapping);
+ context->xstorm_st_context.statistics_data = (cl_id |
+ XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE);
context->cstorm_st_context.sb_index_number =
C_SB_ETH_TX_CQ_INDEX;
context->cstorm_st_context.status_block_id = sb_id;
@@ -4534,10 +4723,6 @@ static void bnx2x_init_context(struct bnx2x *bp)
CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
CDU_REGION_NUMBER_XCM_AG,
ETH_CONNECTION_TYPE);
- context->ustorm_ag_context.cdu_usage =
- CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
- CDU_REGION_NUMBER_UCM_AG,
- ETH_CONNECTION_TYPE);
}
}
@@ -4546,14 +4731,15 @@ static void bnx2x_init_ind_table(struct bnx2x *bp)
int func = BP_FUNC(bp);
int i;
- if (!is_multi(bp))
+ if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
return;
- DP(NETIF_MSG_IFUP, "Initializing indirection table\n");
+ DP(NETIF_MSG_IFUP,
+ "Initializing indirection table multi_mode %d\n", bp->multi_mode);
for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
REG_WR8(bp, BAR_TSTRORM_INTMEM +
TSTORM_INDIRECTION_TABLE_OFFSET(func) + i,
- BP_CL_ID(bp) + (i % bp->num_queues));
+ bp->fp->cl_id + (i % bp->num_rx_queues));
}
static void bnx2x_set_client_config(struct bnx2x *bp)
@@ -4563,13 +4749,13 @@ static void bnx2x_set_client_config(struct bnx2x *bp)
int i;
tstorm_client.mtu = bp->dev->mtu;
- tstorm_client.statistics_counter_id = BP_CL_ID(bp);
tstorm_client.config_flags =
- TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
+ (TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE |
+ TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE);
#ifdef BCM_VLAN
if (bp->rx_mode && bp->vlgrp && (bp->flags & HW_VLAN_RX_FLAG)) {
tstorm_client.config_flags |=
- TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
+ TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE;
DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
}
#endif
@@ -4587,6 +4773,8 @@ static void bnx2x_set_client_config(struct bnx2x *bp)
}
for_each_queue(bp, i) {
+ tstorm_client.statistics_counter_id = bp->fp[i].cl_id;
+
REG_WR(bp, BAR_TSTRORM_INTMEM +
TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id),
((u32 *)&tstorm_client)[0]);
@@ -4615,18 +4803,22 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
tstorm_mac_filter.mcast_drop_all = mask;
tstorm_mac_filter.bcast_drop_all = mask;
break;
+
case BNX2X_RX_MODE_NORMAL:
tstorm_mac_filter.bcast_accept_all = mask;
break;
+
case BNX2X_RX_MODE_ALLMULTI:
tstorm_mac_filter.mcast_accept_all = mask;
tstorm_mac_filter.bcast_accept_all = mask;
break;
+
case BNX2X_RX_MODE_PROMISC:
tstorm_mac_filter.ucast_accept_all = mask;
tstorm_mac_filter.mcast_accept_all = mask;
tstorm_mac_filter.bcast_accept_all = mask;
break;
+
default:
BNX2X_ERR("BAD rx mode (%d)\n", mode);
break;
@@ -4677,19 +4869,64 @@ static void bnx2x_init_internal_port(struct bnx2x *bp)
REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
}
+/* Calculates the sum of vn_min_rates.
+ It's needed for further normalizing of the min_rates.
+ Returns:
+ sum of vn_min_rates.
+ or
+ 0 - if all the min_rates are 0.
+ In the later case fainess algorithm should be deactivated.
+ If not all min_rates are zero then those that are zeroes will be set to 1.
+ */
+static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
+{
+ int all_zero = 1;
+ int port = BP_PORT(bp);
+ int vn;
+
+ bp->vn_weight_sum = 0;
+ for (vn = VN_0; vn < E1HVN_MAX; vn++) {
+ int func = 2*vn + port;
+ u32 vn_cfg =
+ SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
+ u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
+ FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
+
+ /* Skip hidden vns */
+ if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE)
+ continue;
+
+ /* If min rate is zero - set it to 1 */
+ if (!vn_min_rate)
+ vn_min_rate = DEF_MIN_RATE;
+ else
+ all_zero = 0;
+
+ bp->vn_weight_sum += vn_min_rate;
+ }
+
+ /* ... only if all min rates are zeros - disable fairness */
+ if (all_zero)
+ bp->vn_weight_sum = 0;
+}
+
static void bnx2x_init_internal_func(struct bnx2x *bp)
{
struct tstorm_eth_function_common_config tstorm_config = {0};
struct stats_indication_flags stats_flags = {0};
int port = BP_PORT(bp);
int func = BP_FUNC(bp);
- int i;
+ int i, j;
+ u32 offset;
u16 max_agg_size;
if (is_multi(bp)) {
- tstorm_config.config_flags = MULTI_FLAGS;
+ tstorm_config.config_flags = MULTI_FLAGS(bp);
tstorm_config.rss_result_mask = MULTI_MASK;
}
+ if (IS_E1HMF(bp))
+ tstorm_config.config_flags |=
+ TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM;
tstorm_config.leading_client_id = BP_L_ID(bp);
@@ -4700,17 +4937,29 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */
bnx2x_set_storm_rx_mode(bp);
- /* reset xstorm per client statistics */
- for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++) {
- REG_WR(bp, BAR_XSTRORM_INTMEM +
- XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, BP_CL_ID(bp)) +
- i*4, 0);
- }
- /* reset tstorm per client statistics */
- for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++) {
- REG_WR(bp, BAR_TSTRORM_INTMEM +
- TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, BP_CL_ID(bp)) +
- i*4, 0);
+ for_each_queue(bp, i) {
+ u8 cl_id = bp->fp[i].cl_id;
+
+ /* reset xstorm per client statistics */
+ offset = BAR_XSTRORM_INTMEM +
+ XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id);
+ for (j = 0;
+ j < sizeof(struct xstorm_per_client_stats) / 4; j++)
+ REG_WR(bp, offset + j*4, 0);
+
+ /* reset tstorm per client statistics */
+ offset = BAR_TSTRORM_INTMEM +
+ TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id);
+ for (j = 0;
+ j < sizeof(struct tstorm_per_client_stats) / 4; j++)
+ REG_WR(bp, offset + j*4, 0);
+
+ /* reset ustorm per client statistics */
+ offset = BAR_USTRORM_INTMEM +
+ USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id);
+ for (j = 0;
+ j < sizeof(struct ustorm_per_client_stats) / 4; j++)
+ REG_WR(bp, offset + j*4, 0);
}
/* Init statistics related context */
@@ -4726,6 +4975,11 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func) + 4,
((u32 *)&stats_flags)[1]);
+ REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func),
+ ((u32 *)&stats_flags)[0]);
+ REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func) + 4,
+ ((u32 *)&stats_flags)[1]);
+
REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func),
((u32 *)&stats_flags)[0]);
REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func) + 4,
@@ -4745,6 +4999,13 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func),
+ U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
+ REG_WR(bp, BAR_USTRORM_INTMEM +
+ USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4,
+ U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
+
if (CHIP_IS_E1H(bp)) {
REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET,
IS_E1HMF(bp));
@@ -4764,20 +5025,91 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
min((u32)(min((u32)8, (u32)MAX_SKB_FRAGS) *
SGE_PAGE_SIZE * PAGES_PER_SGE),
(u32)0xffff);
- for_each_queue(bp, i) {
+ for_each_rx_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)),
+ USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id),
U64_LO(fp->rx_comp_mapping));
REG_WR(bp, BAR_USTRORM_INTMEM +
- USTORM_CQE_PAGE_BASE_OFFSET(port, FP_CL_ID(fp)) + 4,
+ USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id) + 4,
U64_HI(fp->rx_comp_mapping));
REG_WR16(bp, BAR_USTRORM_INTMEM +
- USTORM_MAX_AGG_SIZE_OFFSET(port, FP_CL_ID(fp)),
+ USTORM_MAX_AGG_SIZE_OFFSET(port, fp->cl_id),
max_agg_size);
}
+
+ /* dropless flow control */
+ if (CHIP_IS_E1H(bp)) {
+ struct ustorm_eth_rx_pause_data_e1h rx_pause = {0};
+
+ rx_pause.bd_thr_low = 250;
+ rx_pause.cqe_thr_low = 250;
+ rx_pause.cos = 1;
+ rx_pause.sge_thr_low = 0;
+ rx_pause.bd_thr_high = 350;
+ rx_pause.cqe_thr_high = 350;
+ rx_pause.sge_thr_high = 0;
+
+ for_each_rx_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ if (!fp->disable_tpa) {
+ rx_pause.sge_thr_low = 150;
+ rx_pause.sge_thr_high = 250;
+ }
+
+
+ offset = BAR_USTRORM_INTMEM +
+ USTORM_ETH_RING_PAUSE_DATA_OFFSET(port,
+ fp->cl_id);
+ for (j = 0;
+ j < sizeof(struct ustorm_eth_rx_pause_data_e1h)/4;
+ j++)
+ REG_WR(bp, offset + j*4,
+ ((u32 *)&rx_pause)[j]);
+ }
+ }
+
+ memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port));
+
+ /* Init rate shaping and fairness contexts */
+ if (IS_E1HMF(bp)) {
+ int vn;
+
+ /* During init there is no active link
+ Until link is up, set link rate to 10Gbps */
+ bp->link_vars.line_speed = SPEED_10000;
+ bnx2x_init_port_minmax(bp);
+
+ bnx2x_calc_vn_weight_sum(bp);
+
+ for (vn = VN_0; vn < E1HVN_MAX; vn++)
+ bnx2x_init_vn_minmax(bp, 2*vn + port);
+
+ /* Enable rate shaping and fairness */
+ bp->cmng.flags.cmng_enables =
+ CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN;
+ if (bp->vn_weight_sum)
+ bp->cmng.flags.cmng_enables |=
+ CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
+ else
+ DP(NETIF_MSG_IFUP, "All MIN values are zeroes"
+ " fairness will be disabled\n");
+ } else {
+ /* rate shaping and fairness are disabled */
+ DP(NETIF_MSG_IFUP,
+ "single function mode minmax will be disabled\n");
+ }
+
+
+ /* Store it to internal memory */
+ if (bp->port.pmf)
+ for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
+ REG_WR(bp, BAR_XSTRORM_INTMEM +
+ XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4,
+ ((u32 *)(&bp->cmng))[i]);
}
static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code)
@@ -4814,13 +5146,17 @@ static void bnx2x_nic_init(struct bnx2x *bp, u32 load_code)
fp->cl_id = BP_L_ID(bp) + i;
fp->sb_id = fp->cl_id;
DP(NETIF_MSG_IFUP,
- "bnx2x_init_sb(%p,%p) index %d cl_id %d sb %d\n",
- bp, fp->status_blk, i, FP_CL_ID(fp), FP_SB_ID(fp));
+ "queue[%d]: bnx2x_init_sb(%p,%p) cl_id %d sb %d\n",
+ i, bp, fp->status_blk, fp->cl_id, fp->sb_id);
bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping,
- FP_SB_ID(fp));
+ fp->sb_id);
bnx2x_update_fpsb_idx(fp);
}
+ /* ensure status block indices were read */
+ rmb();
+
+
bnx2x_init_def_sb(bp, bp->def_status_blk, bp->def_status_blk_mapping,
DEF_SB_ID);
bnx2x_update_dsb_idx(bp);
@@ -5198,6 +5534,8 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1);
REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1);
REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1);
+ /* make sure this value is 0 */
+ REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 0);
/* REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */
REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1);
@@ -5266,14 +5604,6 @@ static int bnx2x_init_common(struct bnx2x *bp)
}
bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
- if (CHIP_REV_IS_SLOW(bp)) {
- /* fix for emulation and FPGA for no pause */
- REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 513);
- REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 513);
- REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0);
- REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0);
- }
-
bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
/* set NIC mode */
@@ -5286,37 +5616,10 @@ static int bnx2x_init_common(struct bnx2x *bp)
bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END);
bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END);
- if (CHIP_IS_E1H(bp)) {
- bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp,
- TSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
- 0, STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp,
- CSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
- 0, STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp,
- XSTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
- 0, STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1H/2);
- bnx2x_init_fill(bp,
- USTORM_INTMEM_ADDR + STORM_INTMEM_SIZE_E1H/2,
- 0, STORM_INTMEM_SIZE_E1H/2);
- } else { /* E1 */
- bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1);
- bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1);
- bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1);
- bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0,
- STORM_INTMEM_SIZE_E1);
- }
+ bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
+ bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
+ bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
+ bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END);
bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END);
@@ -5338,8 +5641,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
REG_WR(bp, i, 0xc0cac01a);
/* TODO: replace with something meaningful */
}
- if (CHIP_IS_E1H(bp))
- bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END);
+ bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END);
REG_WR(bp, SRC_REG_SOFT_RST, 0);
if (sizeof(union cdu_context) != 1024)
@@ -5358,6 +5660,11 @@ static int bnx2x_init_common(struct bnx2x *bp)
bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END);
REG_WR(bp, CFC_REG_INIT_REG, 0x7FF);
+ /* enable context validation interrupt from CFC */
+ REG_WR(bp, CFC_REG_CFC_INT_MASK, 0);
+
+ /* set the thresholds to prevent CFC/CDU race */
+ REG_WR(bp, CFC_REG_DEBUG0, 0x20020000);
bnx2x_init_block(bp, HC_COMMON_START, HC_COMMON_END);
bnx2x_init_block(bp, MISC_AEU_COMMON_START, MISC_AEU_COMMON_END);
@@ -5410,9 +5717,14 @@ static int bnx2x_init_common(struct bnx2x *bp)
return -EBUSY;
}
- switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G:
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ bp->port.need_hw_lock = 1;
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
/* Fan failure is indicated by SPIO 5 */
bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5,
MISC_REGISTERS_SPIO_INPUT_HI_Z);
@@ -5451,6 +5763,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
static int bnx2x_init_port(struct bnx2x *bp)
{
int port = BP_PORT(bp);
+ u32 low, high;
u32 val;
DP(BNX2X_MSG_MCP, "starting port init port %x\n", port);
@@ -5485,6 +5798,8 @@ static int bnx2x_init_port(struct bnx2x *bp)
REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
#endif
/* Port CMs come here */
+ bnx2x_init_block(bp, (port ? XCM_PORT1_START : XCM_PORT0_START),
+ (port ? XCM_PORT1_END : XCM_PORT0_END));
/* Port QM comes here */
#ifdef BCM_ISCSI
@@ -5495,12 +5810,38 @@ static int bnx2x_init_port(struct bnx2x *bp)
func ? TIMERS_PORT1_END : TIMERS_PORT0_END);
#endif
/* Port DQ comes here */
- /* Port BRB1 comes here */
+
+ bnx2x_init_block(bp, (port ? BRB1_PORT1_START : BRB1_PORT0_START),
+ (port ? BRB1_PORT1_END : BRB1_PORT0_END));
+ if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) {
+ /* no pause for emulation and FPGA */
+ low = 0;
+ high = 513;
+ } else {
+ if (IS_E1HMF(bp))
+ low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246);
+ else if (bp->dev->mtu > 4096) {
+ if (bp->flags & ONE_PORT_FLAG)
+ low = 160;
+ else {
+ val = bp->dev->mtu;
+ /* (24*1024 + val*4)/256 */
+ low = 96 + (val/64) + ((val % 64) ? 1 : 0);
+ }
+ } else
+ low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160);
+ high = low + 56; /* 14*1024/256 */
+ }
+ REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low);
+ REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high);
+
+
/* Port PRS comes here */
/* Port TSDM comes here */
/* Port CSDM comes here */
/* Port USDM comes here */
/* Port XSDM comes here */
+
bnx2x_init_block(bp, port ? TSEM_PORT1_START : TSEM_PORT0_START,
port ? TSEM_PORT1_END : TSEM_PORT0_END);
bnx2x_init_block(bp, port ? USEM_PORT1_START : USEM_PORT0_START,
@@ -5509,6 +5850,7 @@ static int bnx2x_init_port(struct bnx2x *bp)
port ? CSEM_PORT1_END : CSEM_PORT0_END);
bnx2x_init_block(bp, port ? XSEM_PORT1_START : XSEM_PORT0_START,
port ? XSEM_PORT1_END : XSEM_PORT0_END);
+
/* Port UPB comes here */
/* Port XPB comes here */
@@ -5567,36 +5909,63 @@ static int bnx2x_init_port(struct bnx2x *bp)
/* Port EMAC1 comes here */
/* Port DBU comes here */
/* Port DBG comes here */
+
bnx2x_init_block(bp, port ? NIG_PORT1_START : NIG_PORT0_START,
port ? NIG_PORT1_END : NIG_PORT0_END);
REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
if (CHIP_IS_E1H(bp)) {
- u32 wsum;
- struct cmng_struct_per_port m_cmng_port;
- int vn;
-
/* 0x2 disable e1hov, 0x1 enable */
REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4,
(IS_E1HMF(bp) ? 0x1 : 0x2));
- /* Init RATE SHAPING and FAIRNESS contexts.
- Initialize as if there is 10G link. */
- wsum = bnx2x_calc_vn_wsum(bp);
- bnx2x_init_port_minmax(bp, (int)wsum, 10000, &m_cmng_port);
- if (IS_E1HMF(bp))
- for (vn = VN_0; vn < E1HVN_MAX; vn++)
- bnx2x_init_vn_minmax(bp, 2*vn + port,
- wsum, 10000, &m_cmng_port);
+ /* support pause requests from USDM, TSDM and BRB */
+ REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0 + port*4, 0x7);
+
+ {
+ REG_WR(bp, NIG_REG_LLFC_ENABLE_0 + port*4, 0);
+ REG_WR(bp, NIG_REG_LLFC_OUT_EN_0 + port*4, 0);
+ REG_WR(bp, NIG_REG_PAUSE_ENABLE_0 + port*4, 1);
+ }
}
/* Port MCP comes here */
/* Port DMAE comes here */
- switch (bp->common.board & SHARED_HW_CFG_BOARD_TYPE_MASK) {
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1021G:
- case SHARED_HW_CFG_BOARD_TYPE_BCM957710A1022G:
+ switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ {
+ u32 swap_val, swap_override, aeu_gpio_mask, offset;
+
+ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
+ MISC_REGISTERS_GPIO_INPUT_HI_Z, port);
+
+ /* The GPIO should be swapped if the swap register is
+ set and active */
+ swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
+ swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
+
+ /* Select function upon port-swap configuration */
+ if (port == 0) {
+ offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
+ aeu_gpio_mask = (swap_val && swap_override) ?
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
+ } else {
+ offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
+ aeu_gpio_mask = (swap_val && swap_override) ?
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
+ AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
+ }
+ val = REG_RD(bp, offset);
+ /* add GPIO3 to group */
+ val |= aeu_gpio_mask;
+ REG_WR(bp, offset, val);
+ }
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
/* add SPIO 5 to group 0 */
val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
val |= AEU_INPUTS_ATTN_BITS_SPIO5;
@@ -5642,10 +6011,17 @@ static int bnx2x_init_func(struct bnx2x *bp)
{
int port = BP_PORT(bp);
int func = BP_FUNC(bp);
+ u32 addr, val;
int i;
DP(BNX2X_MSG_MCP, "starting func init func %x\n", func);
+ /* set MSI reconfigure capability */
+ addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0);
+ val = REG_RD(bp, addr);
+ val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0;
+ REG_WR(bp, addr, val);
+
i = FUNC_ILT_BASE(func);
bnx2x_ilt_wr(bp, i, bnx2x_sp_mapping(bp, context));
@@ -5675,9 +6051,6 @@ static int bnx2x_init_func(struct bnx2x *bp)
}
bnx2x_init_block(bp, hc_limits[func][0], hc_limits[func][1]);
- if (CHIP_IS_E1H(bp))
- REG_WR(bp, HC_REG_FUNC_NUM_P0 + port*4, func);
-
/* Reset PCIE errors for debug */
REG_WR(bp, 0x2114, 0xffffffff);
REG_WR(bp, 0x2120, 0xffffffff);
@@ -5806,20 +6179,19 @@ static void bnx2x_free_mem(struct bnx2x *bp)
int i;
/* fastpath */
+ /* Common */
for_each_queue(bp, i) {
- /* Status blocks */
+ /* status blocks */
BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk),
bnx2x_fp(bp, i, status_blk_mapping),
sizeof(struct host_status_block) +
sizeof(struct eth_tx_db_data));
+ }
+ /* Rx */
+ for_each_rx_queue(bp, i) {
- /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
- BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
- BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring),
- bnx2x_fp(bp, i, tx_desc_mapping),
- sizeof(struct eth_tx_bd) * NUM_TX_BD);
-
+ /* fastpath rx rings: rx_buf rx_desc rx_comp */
BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring));
BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_desc_ring),
bnx2x_fp(bp, i, rx_desc_mapping),
@@ -5836,6 +6208,15 @@ static void bnx2x_free_mem(struct bnx2x *bp)
bnx2x_fp(bp, i, rx_sge_mapping),
BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
}
+ /* Tx */
+ for_each_tx_queue(bp, i) {
+
+ /* fastpath tx rings: tx_buf tx_desc */
+ BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
+ BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring),
+ bnx2x_fp(bp, i, tx_desc_mapping),
+ sizeof(struct eth_tx_bd) * NUM_TX_BD);
+ }
/* end of fastpath */
BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping,
@@ -5878,29 +6259,20 @@ static int bnx2x_alloc_mem(struct bnx2x *bp)
int i;
/* fastpath */
+ /* Common */
for_each_queue(bp, i) {
bnx2x_fp(bp, i, bp) = bp;
- /* Status blocks */
+ /* status blocks */
BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk),
&bnx2x_fp(bp, i, status_blk_mapping),
sizeof(struct host_status_block) +
sizeof(struct eth_tx_db_data));
+ }
+ /* Rx */
+ for_each_rx_queue(bp, i) {
- bnx2x_fp(bp, i, hw_tx_prods) =
- (void *)(bnx2x_fp(bp, i, status_blk) + 1);
-
- bnx2x_fp(bp, i, tx_prods_mapping) =
- bnx2x_fp(bp, i, status_blk_mapping) +
- sizeof(struct host_status_block);
-
- /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
- BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
- sizeof(struct sw_tx_bd) * NUM_TX_BD);
- BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring),
- &bnx2x_fp(bp, i, tx_desc_mapping),
- sizeof(struct eth_tx_bd) * NUM_TX_BD);
-
+ /* fastpath rx rings: rx_buf rx_desc rx_comp */
BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring),
sizeof(struct sw_rx_bd) * NUM_RX_BD);
BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_desc_ring),
@@ -5919,6 +6291,23 @@ static int bnx2x_alloc_mem(struct bnx2x *bp)
&bnx2x_fp(bp, i, rx_sge_mapping),
BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
}
+ /* Tx */
+ for_each_tx_queue(bp, i) {
+
+ bnx2x_fp(bp, i, hw_tx_prods) =
+ (void *)(bnx2x_fp(bp, i, status_blk) + 1);
+
+ bnx2x_fp(bp, i, tx_prods_mapping) =
+ bnx2x_fp(bp, i, status_blk_mapping) +
+ sizeof(struct host_status_block);
+
+ /* fastpath tx rings: tx_buf tx_desc */
+ BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
+ sizeof(struct sw_tx_bd) * NUM_TX_BD);
+ BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring),
+ &bnx2x_fp(bp, i, tx_desc_mapping),
+ sizeof(struct eth_tx_bd) * NUM_TX_BD);
+ }
/* end of fastpath */
BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping,
@@ -5972,7 +6361,7 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp)
{
int i;
- for_each_queue(bp, i) {
+ for_each_tx_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
u16 bd_cons = fp->tx_bd_cons;
@@ -5990,7 +6379,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp)
{
int i, j;
- for_each_queue(bp, j) {
+ for_each_rx_queue(bp, j) {
struct bnx2x_fastpath *fp = &bp->fp[j];
for (i = 0; i < NUM_RX_BD; i++) {
@@ -6002,8 +6391,7 @@ static void bnx2x_free_rx_skbs(struct bnx2x *bp)
pci_unmap_single(bp->pdev,
pci_unmap_addr(rx_buf, mapping),
- bp->rx_buf_size,
- PCI_DMA_FROMDEVICE);
+ bp->rx_buf_size, PCI_DMA_FROMDEVICE);
rx_buf->skb = NULL;
dev_kfree_skb(skb);
@@ -6034,10 +6422,6 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp)
"state %x\n", i, bp->msix_table[i + offset].vector,
bnx2x_fp(bp, i, state));
- if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED)
- BNX2X_ERR("IRQ of fp #%d being freed while "
- "state != closed\n", i);
-
free_irq(bp->msix_table[i + offset].vector, &bp->fp[i]);
}
}
@@ -6049,32 +6433,37 @@ static void bnx2x_free_irq(struct bnx2x *bp)
pci_disable_msix(bp->pdev);
bp->flags &= ~USING_MSIX_FLAG;
+ } else if (bp->flags & USING_MSI_FLAG) {
+ free_irq(bp->pdev->irq, bp->dev);
+ pci_disable_msi(bp->pdev);
+ bp->flags &= ~USING_MSI_FLAG;
+
} else
free_irq(bp->pdev->irq, bp->dev);
}
static int bnx2x_enable_msix(struct bnx2x *bp)
{
- int i, rc, offset;
+ int i, rc, offset = 1;
+ int igu_vec = 0;
- bp->msix_table[0].entry = 0;
- offset = 1;
- DP(NETIF_MSG_IFUP, "msix_table[0].entry = 0 (slowpath)\n");
+ bp->msix_table[0].entry = igu_vec;
+ DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n", igu_vec);
for_each_queue(bp, i) {
- int igu_vec = offset + i + BP_L_ID(bp);
-
+ igu_vec = BP_L_ID(bp) + offset + i;
bp->msix_table[i + offset].entry = igu_vec;
DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d "
"(fastpath #%u)\n", i + offset, igu_vec, i);
}
rc = pci_enable_msix(bp->pdev, &bp->msix_table[0],
- bp->num_queues + offset);
+ BNX2X_NUM_QUEUES(bp) + offset);
if (rc) {
- DP(NETIF_MSG_IFUP, "MSI-X is not attainable\n");
- return -1;
+ DP(NETIF_MSG_IFUP, "MSI-X is not attainable rc %d\n", rc);
+ return rc;
}
+
bp->flags |= USING_MSIX_FLAG;
return 0;
@@ -6092,27 +6481,60 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
}
for_each_queue(bp, i) {
+ struct bnx2x_fastpath *fp = &bp->fp[i];
+
+ sprintf(fp->name, "%s.fp%d", bp->dev->name, i);
rc = request_irq(bp->msix_table[i + offset].vector,
- bnx2x_msix_fp_int, 0,
- bp->dev->name, &bp->fp[i]);
+ bnx2x_msix_fp_int, 0, fp->name, fp);
if (rc) {
- BNX2X_ERR("request fp #%d irq failed rc -%d\n",
- i + offset, -rc);
+ BNX2X_ERR("request fp #%d irq failed rc %d\n", i, rc);
bnx2x_free_msix_irqs(bp);
return -EBUSY;
}
- bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_IRQ;
+ fp->state = BNX2X_FP_STATE_IRQ;
}
+ i = BNX2X_NUM_QUEUES(bp);
+ if (is_multi(bp))
+ printk(KERN_INFO PFX
+ "%s: using MSI-X IRQs: sp %d fp %d - %d\n",
+ bp->dev->name, bp->msix_table[0].vector,
+ bp->msix_table[offset].vector,
+ bp->msix_table[offset + i - 1].vector);
+ else
+ printk(KERN_INFO PFX "%s: using MSI-X IRQs: sp %d fp %d\n",
+ bp->dev->name, bp->msix_table[0].vector,
+ bp->msix_table[offset + i - 1].vector);
+
+ return 0;
+}
+
+static int bnx2x_enable_msi(struct bnx2x *bp)
+{
+ int rc;
+
+ rc = pci_enable_msi(bp->pdev);
+ if (rc) {
+ DP(NETIF_MSG_IFUP, "MSI is not attainable\n");
+ return -1;
+ }
+ bp->flags |= USING_MSI_FLAG;
+
return 0;
}
static int bnx2x_req_irq(struct bnx2x *bp)
{
+ unsigned long flags;
int rc;
- rc = request_irq(bp->pdev->irq, bnx2x_interrupt, IRQF_SHARED,
+ if (bp->flags & USING_MSI_FLAG)
+ flags = 0;
+ else
+ flags = IRQF_SHARED;
+
+ rc = request_irq(bp->pdev->irq, bnx2x_interrupt, flags,
bp->dev->name, bp->dev);
if (!rc)
bnx2x_fp(bp, 0, state) = BNX2X_FP_STATE_IRQ;
@@ -6124,7 +6546,7 @@ static void bnx2x_napi_enable(struct bnx2x *bp)
{
int i;
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
napi_enable(&bnx2x_fp(bp, i, napi));
}
@@ -6132,7 +6554,7 @@ static void bnx2x_napi_disable(struct bnx2x *bp)
{
int i;
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
napi_disable(&bnx2x_fp(bp, i, napi));
}
@@ -6140,10 +6562,10 @@ static void bnx2x_netif_start(struct bnx2x *bp)
{
if (atomic_dec_and_test(&bp->intr_sem)) {
if (netif_running(bp->dev)) {
- if (bp->state == BNX2X_STATE_OPEN)
- netif_wake_queue(bp->dev);
bnx2x_napi_enable(bp);
bnx2x_int_enable(bp);
+ if (bp->state == BNX2X_STATE_OPEN)
+ netif_tx_wake_all_queues(bp->dev);
}
}
}
@@ -6152,10 +6574,8 @@ static void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
{
bnx2x_int_disable_sync(bp, disable_hw);
bnx2x_napi_disable(bp);
- if (netif_running(bp->dev)) {
- netif_tx_disable(bp->dev);
- bp->dev->trans_start = jiffies; /* prevent tx timeout */
- }
+ netif_tx_disable(bp->dev);
+ bp->dev->trans_start = jiffies; /* prevent tx timeout */
}
/*
@@ -6171,9 +6591,9 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
* unicasts 0-31:port0 32-63:port1
* multicast 64-127:port0 128-191:port1
*/
- config->hdr.length_6b = 2;
+ config->hdr.length = 2;
config->hdr.offset = port ? 32 : 0;
- config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
/* primary MAC */
@@ -6198,9 +6618,9 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
config->config_table[0].cam_entry.lsb_mac_addr);
/* broadcast */
- config->config_table[1].cam_entry.msb_mac_addr = 0xffff;
- config->config_table[1].cam_entry.middle_mac_addr = 0xffff;
- config->config_table[1].cam_entry.lsb_mac_addr = 0xffff;
+ config->config_table[1].cam_entry.msb_mac_addr = cpu_to_le16(0xffff);
+ config->config_table[1].cam_entry.middle_mac_addr = cpu_to_le16(0xffff);
+ config->config_table[1].cam_entry.lsb_mac_addr = cpu_to_le16(0xffff);
config->config_table[1].cam_entry.flags = cpu_to_le16(port);
if (set)
config->config_table[1].target_table_entry.flags =
@@ -6229,9 +6649,9 @@ static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp, int set)
* unicasts: by func number
* multicast: 20+FUNC*20, 20 each
*/
- config->hdr.length_6b = 1;
+ config->hdr.length = 1;
config->hdr.offset = BP_FUNC(bp);
- config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
/* primary MAC */
@@ -6265,7 +6685,7 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
int *state_p, int poll)
{
/* can take a while if any port is running */
- int cnt = 500;
+ int cnt = 5000;
DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n",
poll ? "polling" : "waiting", state, idx);
@@ -6283,8 +6703,12 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
}
mb(); /* state is changed by bnx2x_sp_event() */
- if (*state_p == state)
+ if (*state_p == state) {
+#ifdef BNX2X_STOP_ON_ERROR
+ DP(NETIF_MSG_IFUP, "exit (cnt %d)\n", 5000 - cnt);
+#endif
return 0;
+ }
msleep(1);
}
@@ -6317,19 +6741,68 @@ static int bnx2x_setup_leading(struct bnx2x *bp)
static int bnx2x_setup_multi(struct bnx2x *bp, int index)
{
+ struct bnx2x_fastpath *fp = &bp->fp[index];
+
/* reset IGU state */
- bnx2x_ack_sb(bp, bp->fp[index].sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+ bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
/* SETUP ramrod */
- bp->fp[index].state = BNX2X_FP_STATE_OPENING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, index, 0);
+ fp->state = BNX2X_FP_STATE_OPENING;
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0,
+ fp->cl_id, 0);
/* Wait for completion */
return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index,
- &(bp->fp[index].state), 0);
+ &(fp->state), 0);
}
static int bnx2x_poll(struct napi_struct *napi, int budget);
+
+static void bnx2x_set_int_mode(struct bnx2x *bp)
+{
+ int num_queues;
+
+ switch (int_mode) {
+ case INT_MODE_INTx:
+ case INT_MODE_MSI:
+ num_queues = 1;
+ bp->num_rx_queues = num_queues;
+ bp->num_tx_queues = num_queues;
+ DP(NETIF_MSG_IFUP,
+ "set number of queues to %d\n", num_queues);
+ break;
+
+ case INT_MODE_MSIX:
+ default:
+ if (bp->multi_mode == ETH_RSS_MODE_REGULAR)
+ num_queues = min_t(u32, num_online_cpus(),
+ BNX2X_MAX_QUEUES(bp));
+ else
+ num_queues = 1;
+ bp->num_rx_queues = num_queues;
+ bp->num_tx_queues = num_queues;
+ DP(NETIF_MSG_IFUP, "set number of rx queues to %d"
+ " number of tx queues to %d\n",
+ bp->num_rx_queues, bp->num_tx_queues);
+ /* if we can't use MSI-X we only need one fp,
+ * so try to enable MSI-X with the requested number of fp's
+ * and fallback to MSI or legacy INTx with one fp
+ */
+ if (bnx2x_enable_msix(bp)) {
+ /* failed to enable MSI-X */
+ num_queues = 1;
+ bp->num_rx_queues = num_queues;
+ bp->num_tx_queues = num_queues;
+ if (bp->multi_mode)
+ BNX2X_ERR("Multi requested but failed to "
+ "enable MSI-X set number of "
+ "queues to %d\n", num_queues);
+ }
+ break;
+ }
+ bp->dev->real_num_tx_queues = bp->num_tx_queues;
+}
+
static void bnx2x_set_rx_mode(struct net_device *dev);
/* must be called with rtnl_lock */
@@ -6338,56 +6811,28 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
u32 load_code;
int i, rc = 0;
#ifdef BNX2X_STOP_ON_ERROR
+ DP(NETIF_MSG_IFUP, "enter load_mode %d\n", load_mode);
if (unlikely(bp->panic))
return -EPERM;
#endif
bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
- if (use_inta) {
- bp->num_queues = 1;
-
- } else {
- if ((use_multi > 1) && (use_multi <= BP_MAX_QUEUES(bp)))
- /* user requested number */
- bp->num_queues = use_multi;
-
- else if (use_multi)
- bp->num_queues = min_t(u32, num_online_cpus(),
- BP_MAX_QUEUES(bp));
- else
- bp->num_queues = 1;
-
- DP(NETIF_MSG_IFUP,
- "set number of queues to %d\n", bp->num_queues);
-
- /* if we can't use MSI-X we only need one fp,
- * so try to enable MSI-X with the requested number of fp's
- * and fallback to MSI or legacy INTx with one fp
- */
- rc = bnx2x_enable_msix(bp);
- if (rc) {
- /* failed to enable MSI-X */
- bp->num_queues = 1;
- if (use_multi)
- BNX2X_ERR("Multi requested but failed"
- " to enable MSI-X\n");
- }
- }
+ bnx2x_set_int_mode(bp);
if (bnx2x_alloc_mem(bp))
return -ENOMEM;
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
bnx2x_fp(bp, i, disable_tpa) =
((bp->flags & TPA_ENABLE_FLAG) == 0);
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
bnx2x_poll, 128);
#ifdef BNX2X_STOP_ON_ERROR
- for_each_queue(bp, i) {
+ for_each_rx_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
fp->poll_no_work = 0;
@@ -6405,14 +6850,22 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
pci_disable_msix(bp->pdev);
goto load_error1;
}
- printk(KERN_INFO PFX "%s: using MSI-X\n", bp->dev->name);
} else {
+ if ((rc != -ENOMEM) && (int_mode != INT_MODE_INTx))
+ bnx2x_enable_msi(bp);
bnx2x_ack_int(bp);
rc = bnx2x_req_irq(bp);
if (rc) {
BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc);
+ if (bp->flags & USING_MSI_FLAG)
+ pci_disable_msi(bp->pdev);
goto load_error1;
}
+ if (bp->flags & USING_MSI_FLAG) {
+ bp->dev->irq = bp->pdev->irq;
+ printk(KERN_INFO PFX "%s: using MSI IRQ %d\n",
+ bp->dev->name, bp->pdev->irq);
+ }
}
/* Send LOAD_REQUEST command to MCP
@@ -6435,11 +6888,11 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
} else {
int port = BP_PORT(bp);
- DP(NETIF_MSG_IFUP, "NO MCP load counts before us %d, %d, %d\n",
+ DP(NETIF_MSG_IFUP, "NO MCP - load counts %d, %d, %d\n",
load_count[0], load_count[1], load_count[2]);
load_count[0]++;
load_count[1 + port]++;
- DP(NETIF_MSG_IFUP, "NO MCP new load counts %d, %d, %d\n",
+ DP(NETIF_MSG_IFUP, "NO MCP - new load counts %d, %d, %d\n",
load_count[0], load_count[1], load_count[2]);
if (load_count[0] == 1)
load_code = FW_MSG_CODE_DRV_LOAD_COMMON;
@@ -6486,7 +6939,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
if (CHIP_IS_E1H(bp))
if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
- BNX2X_ERR("!!! mf_cfg function disabled\n");
+ DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n");
bp->state = BNX2X_STATE_DISABLED;
}
@@ -6503,19 +6956,19 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bnx2x_set_mac_addr_e1h(bp, 1);
if (bp->port.pmf)
- bnx2x_initial_phy_init(bp);
+ bnx2x_initial_phy_init(bp, load_mode);
/* Start fast path */
switch (load_mode) {
case LOAD_NORMAL:
/* Tx queue should be only reenabled */
- netif_wake_queue(bp->dev);
+ netif_tx_wake_all_queues(bp->dev);
/* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
break;
case LOAD_OPEN:
- netif_start_queue(bp->dev);
+ netif_tx_start_all_queues(bp->dev);
/* Initialize the receive filter. */
bnx2x_set_rx_mode(bp->dev);
break;
@@ -6548,33 +7001,32 @@ load_error3:
bp->port.pmf = 0;
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
load_error2:
/* Release IRQs */
bnx2x_free_irq(bp);
load_error1:
bnx2x_napi_disable(bp);
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
netif_napi_del(&bnx2x_fp(bp, i, napi));
bnx2x_free_mem(bp);
- /* TBD we really need to reset the chip
- if we want to recover from this */
return rc;
}
static int bnx2x_stop_multi(struct bnx2x *bp, int index)
{
+ struct bnx2x_fastpath *fp = &bp->fp[index];
int rc;
/* halt the connection */
- bp->fp[index].state = BNX2X_FP_STATE_HALTING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, index, 0);
+ fp->state = BNX2X_FP_STATE_HALTING;
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, fp->cl_id, 0);
/* Wait for completion */
rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index,
- &(bp->fp[index].state), 1);
+ &(fp->state), 1);
if (rc) /* timeout */
return rc;
@@ -6583,13 +7035,13 @@ static int bnx2x_stop_multi(struct bnx2x *bp, int index)
/* Wait for completion */
rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index,
- &(bp->fp[index].state), 1);
+ &(fp->state), 1);
return rc;
}
static int bnx2x_stop_leading(struct bnx2x *bp)
{
- u16 dsb_sp_prod_idx;
+ __le16 dsb_sp_prod_idx;
/* if the other port is handling traffic,
this can take a lot of time */
int cnt = 500;
@@ -6599,7 +7051,7 @@ static int bnx2x_stop_leading(struct bnx2x *bp)
/* Send HALT ramrod */
bp->fp[0].state = BNX2X_FP_STATE_HALTING;
- bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, BP_CL_ID(bp), 0);
+ bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, bp->fp->cl_id, 0);
/* Wait for completion */
rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0,
@@ -6623,9 +7075,8 @@ static int bnx2x_stop_leading(struct bnx2x *bp)
*bp->dsb_sp_prod, dsb_sp_prod_idx);
#ifdef BNX2X_STOP_ON_ERROR
bnx2x_panic();
-#else
- rc = -EBUSY;
#endif
+ rc = -EBUSY;
break;
}
cnt--;
@@ -6648,8 +7099,6 @@ static void bnx2x_reset_func(struct bnx2x *bp)
REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
- REG_WR(bp, HC_REG_CONFIG_0 + port*4, 0x1000);
-
/* Clear ILT */
base = FUNC_ILT_BASE(func);
for (i = base; i < base + ILT_PER_FUNC; i++)
@@ -6731,15 +7180,14 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
/* Release IRQs */
bnx2x_free_irq(bp);
- /* Wait until tx fast path tasks complete */
- for_each_queue(bp, i) {
+ /* Wait until tx fastpath tasks complete */
+ for_each_tx_queue(bp, i) {
struct bnx2x_fastpath *fp = &bp->fp[i];
cnt = 1000;
- smp_rmb();
while (bnx2x_has_tx_work_unload(fp)) {
- bnx2x_tx_int(fp, 1000);
+ bnx2x_tx_int(fp);
if (!cnt) {
BNX2X_ERR("timeout waiting for queue[%d]\n",
i);
@@ -6752,7 +7200,6 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
}
cnt--;
msleep(1);
- smp_rmb();
}
}
/* Give HW time to discard old tx messages */
@@ -6764,15 +7211,15 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
bnx2x_set_mac_addr_e1(bp, 0);
- for (i = 0; i < config->hdr.length_6b; i++)
+ for (i = 0; i < config->hdr.length; i++)
CAM_INVALIDATE(config->config_table[i]);
- config->hdr.length_6b = i;
+ config->hdr.length = i;
if (CHIP_REV_IS_SLOW(bp))
config->hdr.offset = BNX2X_MAX_EMUL_MULTI*(1 + port);
else
config->hdr.offset = BNX2X_MAX_MULTICAST*(1 + port);
- config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
@@ -6836,11 +7283,11 @@ unload_error:
if (!BP_NOMCP(bp))
reset_code = bnx2x_fw_command(bp, reset_code);
else {
- DP(NETIF_MSG_IFDOWN, "NO MCP load counts %d, %d, %d\n",
+ DP(NETIF_MSG_IFDOWN, "NO MCP - load counts %d, %d, %d\n",
load_count[0], load_count[1], load_count[2]);
load_count[0]--;
load_count[1 + port]--;
- DP(NETIF_MSG_IFDOWN, "NO MCP new load counts %d, %d, %d\n",
+ DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts %d, %d, %d\n",
load_count[0], load_count[1], load_count[2]);
if (load_count[0] == 0)
reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON;
@@ -6860,13 +7307,14 @@ unload_error:
/* Report UNLOAD_DONE to MCP */
if (!BP_NOMCP(bp))
bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+
bp->port.pmf = 0;
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
netif_napi_del(&bnx2x_fp(bp, i, napi));
bnx2x_free_mem(bp);
@@ -6908,6 +7356,64 @@ reset_task_exit:
* Init service functions
*/
+static inline u32 bnx2x_get_pretend_reg(struct bnx2x *bp, int func)
+{
+ switch (func) {
+ case 0: return PXP2_REG_PGL_PRETEND_FUNC_F0;
+ case 1: return PXP2_REG_PGL_PRETEND_FUNC_F1;
+ case 2: return PXP2_REG_PGL_PRETEND_FUNC_F2;
+ case 3: return PXP2_REG_PGL_PRETEND_FUNC_F3;
+ case 4: return PXP2_REG_PGL_PRETEND_FUNC_F4;
+ case 5: return PXP2_REG_PGL_PRETEND_FUNC_F5;
+ case 6: return PXP2_REG_PGL_PRETEND_FUNC_F6;
+ case 7: return PXP2_REG_PGL_PRETEND_FUNC_F7;
+ default:
+ BNX2X_ERR("Unsupported function index: %d\n", func);
+ return (u32)(-1);
+ }
+}
+
+static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp, int orig_func)
+{
+ u32 reg = bnx2x_get_pretend_reg(bp, orig_func), new_val;
+
+ /* Flush all outstanding writes */
+ mmiowb();
+
+ /* Pretend to be function 0 */
+ REG_WR(bp, reg, 0);
+ /* Flush the GRC transaction (in the chip) */
+ new_val = REG_RD(bp, reg);
+ if (new_val != 0) {
+ BNX2X_ERR("Hmmm... Pretend register wasn't updated: (0,%d)!\n",
+ new_val);
+ BUG();
+ }
+
+ /* From now we are in the "like-E1" mode */
+ bnx2x_int_disable(bp);
+
+ /* Flush all outstanding writes */
+ mmiowb();
+
+ /* Restore the original funtion settings */
+ REG_WR(bp, reg, orig_func);
+ new_val = REG_RD(bp, reg);
+ if (new_val != orig_func) {
+ BNX2X_ERR("Hmmm... Pretend register wasn't updated: (%d,%d)!\n",
+ orig_func, new_val);
+ BUG();
+ }
+}
+
+static inline void bnx2x_undi_int_disable(struct bnx2x *bp, int func)
+{
+ if (CHIP_IS_E1H(bp))
+ bnx2x_undi_int_disable_e1h(bp, func);
+ else
+ bnx2x_int_disable(bp);
+}
+
static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
{
u32 val;
@@ -6958,8 +7464,7 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
/* now it's safe to release the lock */
bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI);
- REG_WR(bp, (BP_PORT(bp) ? HC_REG_CONFIG_1 :
- HC_REG_CONFIG_0), 0x1000);
+ bnx2x_undi_int_disable(bp, func);
/* close input traffic and wait for it */
/* Do not rcv packets to BRB */
@@ -7027,6 +7532,13 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
bp->link_params.chip_id = bp->common.chip_id;
BNX2X_DEV_INFO("chip ID is 0x%x\n", id);
+ val = (REG_RD(bp, 0x2874) & 0x55);
+ if ((bp->common.chip_id & 0x1) ||
+ (CHIP_IS_E1(bp) && val) || (CHIP_IS_E1H(bp) && (val == 0x55))) {
+ bp->flags |= ONE_PORT_FLAG;
+ BNX2X_DEV_INFO("single port device\n");
+ }
+
val = REG_RD(bp, MCP_REG_MCPR_NVM_CFG4);
bp->common.flash_size = (NVRAM_1MB_SIZE <<
(val & MCPR_NVM_CFG4_FLASH_SIZE));
@@ -7051,15 +7563,21 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
BNX2X_ERR("BAD MCP validity signature\n");
bp->common.hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config);
- bp->common.board = SHMEM_RD(bp, dev_info.shared_hw_config.board);
-
- BNX2X_DEV_INFO("hw_config 0x%08x board 0x%08x\n",
- bp->common.hw_config, bp->common.board);
+ BNX2X_DEV_INFO("hw_config 0x%08x\n", bp->common.hw_config);
bp->link_params.hw_led_mode = ((bp->common.hw_config &
SHARED_HW_CFG_LED_MODE_MASK) >>
SHARED_HW_CFG_LED_MODE_SHIFT);
+ bp->link_params.feature_config_flags = 0;
+ val = SHMEM_RD(bp, dev_info.shared_feature_config.config);
+ if (val & SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED)
+ bp->link_params.feature_config_flags |=
+ FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED;
+ else
+ bp->link_params.feature_config_flags &=
+ ~FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED;
+
val = SHMEM_RD(bp, dev_info.bc_rev) >> 8;
bp->common.bc_ver = val;
BNX2X_DEV_INFO("bc_ver %X\n", val);
@@ -7078,7 +7596,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
bp->flags |= NO_WOL_FLAG;
}
BNX2X_DEV_INFO("%sWoL capable\n",
- (bp->flags & NO_WOL_FLAG) ? "Not " : "");
+ (bp->flags & NO_WOL_FLAG) ? "not " : "");
val = SHMEM_RD(bp, dev_info.shared_hw_config.part_num);
val2 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[4]);
@@ -7171,48 +7689,60 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
SUPPORTED_Asym_Pause);
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
SUPPORTED_Pause |
SUPPORTED_Asym_Pause);
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n",
ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_2500baseX_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
+ SUPPORTED_Autoneg |
SUPPORTED_Pause |
SUPPORTED_Asym_Pause);
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
- SUPPORTED_Autoneg |
SUPPORTED_Pause |
SUPPORTED_Asym_Pause);
break;
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
- BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n",
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
ext_phy_type);
bp->port.supported |= (SUPPORTED_10000baseT_Full |
- SUPPORTED_2500baseX_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_FIBRE |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (8726)\n",
+ ext_phy_type);
+
+ bp->port.supported |= (SUPPORTED_10000baseT_Full |
+ SUPPORTED_1000baseT_Full |
SUPPORTED_Autoneg |
+ SUPPORTED_FIBRE |
SUPPORTED_Pause |
SUPPORTED_Asym_Pause);
break;
@@ -7228,6 +7758,22 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
SUPPORTED_Asym_Pause);
break;
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+ BNX2X_DEV_INFO("ext_phy_type 0x%x (BCM8481)\n",
+ ext_phy_type);
+
+ bp->port.supported |= (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full |
+ SUPPORTED_10000baseT_Full |
+ SUPPORTED_TP |
+ SUPPORTED_Autoneg |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+ break;
+
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
BNX2X_ERR("XGXS PHY Failure detected 0x%x\n",
bp->link_params.ext_phy_config);
@@ -7453,12 +7999,12 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
{
int port = BP_PORT(bp);
u32 val, val2;
+ u32 config;
+ u16 i;
bp->link_params.bp = bp;
bp->link_params.port = port;
- bp->link_params.serdes_config =
- SHMEM_RD(bp, dev_info.port_hw_config[port].serdes_config);
bp->link_params.lane_config =
SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
bp->link_params.ext_phy_config =
@@ -7471,10 +8017,35 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
bp->port.link_config =
SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
- BNX2X_DEV_INFO("serdes_config 0x%08x lane_config 0x%08x\n"
- KERN_INFO " ext_phy_config 0x%08x speed_cap_mask 0x%08x"
- " link_config 0x%08x\n",
- bp->link_params.serdes_config,
+ /* Get the 4 lanes xgxs config rx and tx */
+ for (i = 0; i < 2; i++) {
+ val = SHMEM_RD(bp,
+ dev_info.port_hw_config[port].xgxs_config_rx[i<<1]);
+ bp->link_params.xgxs_config_rx[i << 1] = ((val>>16) & 0xffff);
+ bp->link_params.xgxs_config_rx[(i << 1) + 1] = (val & 0xffff);
+
+ val = SHMEM_RD(bp,
+ dev_info.port_hw_config[port].xgxs_config_tx[i<<1]);
+ bp->link_params.xgxs_config_tx[i << 1] = ((val>>16) & 0xffff);
+ bp->link_params.xgxs_config_tx[(i << 1) + 1] = (val & 0xffff);
+ }
+
+ config = SHMEM_RD(bp, dev_info.port_feature_config[port].config);
+ if (config & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_ENABLED)
+ bp->link_params.feature_config_flags |=
+ FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED;
+ else
+ bp->link_params.feature_config_flags &=
+ ~FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED;
+
+ /* If the device is capable of WoL, set the default state according
+ * to the HW
+ */
+ bp->wol = (!(bp->flags & NO_WOL_FLAG) &&
+ (config & PORT_FEATURE_WOL_ENABLED));
+
+ BNX2X_DEV_INFO("lane_config 0x%08x ext_phy_config 0x%08x"
+ " speed_cap_mask 0x%08x link_config 0x%08x\n",
bp->link_params.lane_config,
bp->link_params.ext_phy_config,
bp->link_params.speed_cap_mask, bp->port.link_config);
@@ -7521,7 +8092,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
"(0x%04x)\n",
func, bp->e1hov, bp->e1hov);
} else {
- BNX2X_DEV_INFO("Single function mode\n");
+ BNX2X_DEV_INFO("single function mode\n");
if (BP_E1HVN(bp)) {
BNX2X_ERR("!!! No valid E1HOV for func %d,"
" aborting\n", func);
@@ -7571,6 +8142,7 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
static int __devinit bnx2x_init_bp(struct bnx2x *bp)
{
int func = BP_FUNC(bp);
+ int timer_interval;
int rc;
/* Disable interrupt handling until HW is initialized */
@@ -7594,6 +8166,16 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
printk(KERN_ERR PFX
"MCP disabled, must load devices in order!\n");
+ /* Set multi queue mode */
+ if ((multi_mode != ETH_RSS_MODE_DISABLED) &&
+ ((int_mode == INT_MODE_INTx) || (int_mode == INT_MODE_MSI))) {
+ printk(KERN_ERR PFX
+ "Multi disabled since int_mode requested is not MSI-X\n");
+ multi_mode = ETH_RSS_MODE_DISABLED;
+ }
+ bp->multi_mode = multi_mode;
+
+
/* Set TPA flags */
if (disable_tpa) {
bp->flags &= ~TPA_ENABLE_FLAG;
@@ -7603,18 +8185,18 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
bp->dev->features |= NETIF_F_LRO;
}
+ bp->mrrs = mrrs;
bp->tx_ring_size = MAX_TX_AVAIL;
bp->rx_ring_size = MAX_RX_AVAIL;
bp->rx_csum = 1;
- bp->rx_offset = 0;
bp->tx_ticks = 50;
bp->rx_ticks = 25;
- bp->timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ);
- bp->current_interval = (poll ? poll : bp->timer_interval);
+ timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ);
+ bp->current_interval = (poll ? poll : timer_interval);
init_timer(&bp->timer);
bp->timer.expires = jiffies + bp->current_interval;
@@ -7659,14 +8241,16 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
switch (ext_phy_type) {
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
- case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
cmd->port = PORT_FIBRE;
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+ case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
cmd->port = PORT_TP;
break;
@@ -7888,6 +8472,84 @@ static void bnx2x_get_drvinfo(struct net_device *dev,
info->regdump_len = 0;
}
+#define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE)
+#define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE)
+
+static int bnx2x_get_regs_len(struct net_device *dev)
+{
+ static u32 regdump_len;
+ struct bnx2x *bp = netdev_priv(dev);
+ int i;
+
+ if (regdump_len)
+ return regdump_len;
+
+ if (CHIP_IS_E1(bp)) {
+ for (i = 0; i < REGS_COUNT; i++)
+ if (IS_E1_ONLINE(reg_addrs[i].info))
+ regdump_len += reg_addrs[i].size;
+
+ for (i = 0; i < WREGS_COUNT_E1; i++)
+ if (IS_E1_ONLINE(wreg_addrs_e1[i].info))
+ regdump_len += wreg_addrs_e1[i].size *
+ (1 + wreg_addrs_e1[i].read_regs_count);
+
+ } else { /* E1H */
+ for (i = 0; i < REGS_COUNT; i++)
+ if (IS_E1H_ONLINE(reg_addrs[i].info))
+ regdump_len += reg_addrs[i].size;
+
+ for (i = 0; i < WREGS_COUNT_E1H; i++)
+ if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info))
+ regdump_len += wreg_addrs_e1h[i].size *
+ (1 + wreg_addrs_e1h[i].read_regs_count);
+ }
+ regdump_len *= 4;
+ regdump_len += sizeof(struct dump_hdr);
+
+ return regdump_len;
+}
+
+static void bnx2x_get_regs(struct net_device *dev,
+ struct ethtool_regs *regs, void *_p)
+{
+ u32 *p = _p, i, j;
+ struct bnx2x *bp = netdev_priv(dev);
+ struct dump_hdr dump_hdr = {0};
+
+ regs->version = 0;
+ memset(p, 0, regs->len);
+
+ if (!netif_running(bp->dev))
+ return;
+
+ dump_hdr.hdr_size = (sizeof(struct dump_hdr) / 4) - 1;
+ dump_hdr.dump_sign = dump_sign_all;
+ dump_hdr.xstorm_waitp = REG_RD(bp, XSTORM_WAITP_ADDR);
+ dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR);
+ dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR);
+ dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR);
+ dump_hdr.info = CHIP_IS_E1(bp) ? RI_E1_ONLINE : RI_E1H_ONLINE;
+
+ memcpy(p, &dump_hdr, sizeof(struct dump_hdr));
+ p += dump_hdr.hdr_size + 1;
+
+ if (CHIP_IS_E1(bp)) {
+ for (i = 0; i < REGS_COUNT; i++)
+ if (IS_E1_ONLINE(reg_addrs[i].info))
+ for (j = 0; j < reg_addrs[i].size; j++)
+ *p++ = REG_RD(bp,
+ reg_addrs[i].addr + j*4);
+
+ } else { /* E1H */
+ for (i = 0; i < REGS_COUNT; i++)
+ if (IS_E1H_ONLINE(reg_addrs[i].info))
+ for (j = 0; j < reg_addrs[i].size; j++)
+ *p++ = REG_RD(bp,
+ reg_addrs[i].addr + j*4);
+ }
+}
+
static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct bnx2x *bp = netdev_priv(dev);
@@ -8046,7 +8708,7 @@ static void bnx2x_disable_nvram_access(struct bnx2x *bp)
MCPR_NVM_ACCESS_ENABLE_WR_EN)));
}
-static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
+static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, __be32 *ret_val,
u32 cmd_flags)
{
int count, i, rc;
@@ -8082,8 +8744,7 @@ static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
/* we read nvram data in cpu order
* but ethtool sees it as an array of bytes
* converting to big-endian will do the work */
- val = cpu_to_be32(val);
- *ret_val = val;
+ *ret_val = cpu_to_be32(val);
rc = 0;
break;
}
@@ -8097,7 +8758,7 @@ static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
{
int rc;
u32 cmd_flags;
- u32 val;
+ __be32 val;
if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
DP(BNX2X_MSG_NVM,
@@ -8216,7 +8877,7 @@ static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
int rc;
u32 cmd_flags;
u32 align_offset;
- u32 val;
+ __be32 val;
if (offset + buf_size > bp->common.flash_size) {
DP(BNX2X_MSG_NVM, "Invalid parameter: offset (0x%x) +"
@@ -8345,7 +9006,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
if ((bp->state == BNX2X_STATE_OPEN) ||
(bp->state == BNX2X_STATE_DISABLED)) {
rc |= bnx2x_link_reset(&bp->link_params,
- &bp->link_vars);
+ &bp->link_vars, 1);
rc |= bnx2x_phy_init(&bp->link_params,
&bp->link_vars);
}
@@ -8435,7 +9096,8 @@ static void bnx2x_get_pauseparam(struct net_device *dev,
{
struct bnx2x *bp = netdev_priv(dev);
- epause->autoneg = (bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
+ epause->autoneg = (bp->link_params.req_flow_ctrl ==
+ BNX2X_FLOW_CTRL_AUTO) &&
(bp->link_params.req_line_speed == SPEED_AUTO_NEG);
epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) ==
@@ -8567,8 +9229,7 @@ static const struct {
{ "nvram_test (online)" },
{ "interrupt_test (online)" },
{ "link_test (online)" },
- { "idle check (online)" },
- { "MC errors (online)" }
+ { "idle check (online)" }
};
static int bnx2x_self_test_count(struct net_device *dev)
@@ -8756,23 +9417,23 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
u16 len;
int rc = -ENODEV;
- if (loopback_mode == BNX2X_MAC_LOOPBACK) {
+ /* check the loopback mode */
+ switch (loopback_mode) {
+ case BNX2X_PHY_LOOPBACK:
+ if (bp->link_params.loopback_mode != LOOPBACK_XGXS_10)
+ return -EINVAL;
+ break;
+ case BNX2X_MAC_LOOPBACK:
bp->link_params.loopback_mode = LOOPBACK_BMAC;
bnx2x_phy_init(&bp->link_params, &bp->link_vars);
-
- } else if (loopback_mode == BNX2X_PHY_LOOPBACK) {
- u16 cnt = 1000;
- bp->link_params.loopback_mode = LOOPBACK_XGXS_10;
- bnx2x_phy_init(&bp->link_params, &bp->link_vars);
- /* wait until link state is restored */
- if (link_up)
- while (cnt-- && bnx2x_test_link(&bp->link_params,
- &bp->link_vars))
- msleep(10);
- } else
+ break;
+ default:
return -EINVAL;
+ }
- pkt_size = 1514;
+ /* prepare the loopback packet */
+ pkt_size = (((bp->dev->mtu < ETH_MAX_PACKET_SIZE) ?
+ bp->dev->mtu : ETH_MAX_PACKET_SIZE) + ETH_HLEN);
skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
if (!skb) {
rc = -ENOMEM;
@@ -8784,6 +9445,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
for (i = ETH_HLEN; i < pkt_size; i++)
packet[i] = (unsigned char) (i & 0xff);
+ /* send the loopback packet */
num_pkts = 0;
tx_start_idx = le16_to_cpu(*fp->tx_cons_sb);
rx_start_idx = le16_to_cpu(*fp->rx_cons_sb);
@@ -8808,12 +9470,10 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
wmb();
- fp->hw_tx_prods->bds_prod =
- cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + 1);
+ le16_add_cpu(&fp->hw_tx_prods->bds_prod, 1);
mb(); /* FW restriction: must not reorder writing nbd and packets */
- fp->hw_tx_prods->packets_prod =
- cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
- DOORBELL(bp, FP_IDX(fp), 0);
+ le32_add_cpu(&fp->hw_tx_prods->packets_prod, 1);
+ DOORBELL(bp, fp->index, 0);
mmiowb();
@@ -8868,7 +9528,7 @@ test_loopback_exit:
static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
{
- int rc = 0;
+ int rc = 0, res;
if (!netif_running(bp->dev))
return BNX2X_LOOPBACK_FAILED;
@@ -8876,14 +9536,16 @@ static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
bnx2x_netif_stop(bp, 1);
bnx2x_acquire_phy_lock(bp);
- if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) {
- DP(NETIF_MSG_PROBE, "MAC loopback failed\n");
- rc |= BNX2X_MAC_LOOPBACK_FAILED;
+ res = bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up);
+ if (res) {
+ DP(NETIF_MSG_PROBE, " PHY loopback failed (res %d)\n", res);
+ rc |= BNX2X_PHY_LOOPBACK_FAILED;
}
- if (bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up)) {
- DP(NETIF_MSG_PROBE, "PHY loopback failed\n");
- rc |= BNX2X_PHY_LOOPBACK_FAILED;
+ res = bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up);
+ if (res) {
+ DP(NETIF_MSG_PROBE, " MAC loopback failed (res %d)\n", res);
+ rc |= BNX2X_MAC_LOOPBACK_FAILED;
}
bnx2x_release_phy_lock(bp);
@@ -8910,14 +9572,14 @@ static int bnx2x_test_nvram(struct bnx2x *bp)
{ 0x778, 0x70 },
{ 0, 0 }
};
- u32 buf[0x350 / 4];
+ __be32 buf[0x350 / 4];
u8 *data = (u8 *)buf;
int i, rc;
u32 magic, csum;
rc = bnx2x_nvram_read(bp, 0, data, 4);
if (rc) {
- DP(NETIF_MSG_PROBE, "magic value read (rc -%d)\n", -rc);
+ DP(NETIF_MSG_PROBE, "magic value read (rc %d)\n", rc);
goto test_nvram_exit;
}
@@ -8934,7 +9596,7 @@ static int bnx2x_test_nvram(struct bnx2x *bp)
nvram_tbl[i].size);
if (rc) {
DP(NETIF_MSG_PROBE,
- "nvram_tbl[%d] read data (rc -%d)\n", i, -rc);
+ "nvram_tbl[%d] read data (rc %d)\n", i, rc);
goto test_nvram_exit;
}
@@ -8959,12 +9621,12 @@ static int bnx2x_test_intr(struct bnx2x *bp)
if (!netif_running(bp->dev))
return -ENODEV;
- config->hdr.length_6b = 0;
+ config->hdr.length = 0;
if (CHIP_IS_E1(bp))
config->hdr.offset = (BP_PORT(bp) ? 32 : 0);
else
config->hdr.offset = BP_FUNC(bp);
- config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
@@ -9037,9 +9699,6 @@ static void bnx2x_self_test(struct net_device *dev,
buf[5] = 1;
etest->flags |= ETH_TEST_FL_FAILED;
}
- buf[7] = bnx2x_mc_assert(bp);
- if (buf[7] != 0)
- etest->flags |= ETH_TEST_FL_FAILED;
#ifdef BNX2X_EXTRA_DEBUG
bnx2x_panic_dump(bp);
@@ -9049,40 +9708,98 @@ static void bnx2x_self_test(struct net_device *dev,
static const struct {
long offset;
int size;
+ u8 string[ETH_GSTRING_LEN];
+} bnx2x_q_stats_arr[BNX2X_NUM_Q_STATS] = {
+/* 1 */ { Q_STATS_OFFSET32(total_bytes_received_hi), 8, "[%d]: rx_bytes" },
+ { Q_STATS_OFFSET32(error_bytes_received_hi),
+ 8, "[%d]: rx_error_bytes" },
+ { Q_STATS_OFFSET32(total_unicast_packets_received_hi),
+ 8, "[%d]: rx_ucast_packets" },
+ { Q_STATS_OFFSET32(total_multicast_packets_received_hi),
+ 8, "[%d]: rx_mcast_packets" },
+ { Q_STATS_OFFSET32(total_broadcast_packets_received_hi),
+ 8, "[%d]: rx_bcast_packets" },
+ { Q_STATS_OFFSET32(no_buff_discard_hi), 8, "[%d]: rx_discards" },
+ { Q_STATS_OFFSET32(rx_err_discard_pkt),
+ 4, "[%d]: rx_phy_ip_err_discards"},
+ { Q_STATS_OFFSET32(rx_skb_alloc_failed),
+ 4, "[%d]: rx_skb_alloc_discard" },
+ { Q_STATS_OFFSET32(hw_csum_err), 4, "[%d]: rx_csum_offload_errors" },
+
+/* 10 */{ Q_STATS_OFFSET32(total_bytes_transmitted_hi), 8, "[%d]: tx_bytes" },
+ { Q_STATS_OFFSET32(total_unicast_packets_transmitted_hi),
+ 8, "[%d]: tx_packets" }
+};
+
+static const struct {
+ long offset;
+ int size;
u32 flags;
#define STATS_FLAGS_PORT 1
#define STATS_FLAGS_FUNC 2
+#define STATS_FLAGS_BOTH (STATS_FLAGS_FUNC | STATS_FLAGS_PORT)
u8 string[ETH_GSTRING_LEN];
} bnx2x_stats_arr[BNX2X_NUM_STATS] = {
-/* 1 */ { STATS_OFFSET32(valid_bytes_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_bytes" },
+/* 1 */ { STATS_OFFSET32(total_bytes_received_hi),
+ 8, STATS_FLAGS_BOTH, "rx_bytes" },
{ STATS_OFFSET32(error_bytes_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_error_bytes" },
- { STATS_OFFSET32(total_bytes_transmitted_hi),
- 8, STATS_FLAGS_FUNC, "tx_bytes" },
- { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi),
- 8, STATS_FLAGS_PORT, "tx_error_bytes" },
+ 8, STATS_FLAGS_BOTH, "rx_error_bytes" },
{ STATS_OFFSET32(total_unicast_packets_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_ucast_packets" },
+ 8, STATS_FLAGS_BOTH, "rx_ucast_packets" },
{ STATS_OFFSET32(total_multicast_packets_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_mcast_packets" },
+ 8, STATS_FLAGS_BOTH, "rx_mcast_packets" },
{ STATS_OFFSET32(total_broadcast_packets_received_hi),
- 8, STATS_FLAGS_FUNC, "rx_bcast_packets" },
- { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
- 8, STATS_FLAGS_FUNC, "tx_packets" },
- { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
- 8, STATS_FLAGS_PORT, "tx_mac_errors" },
-/* 10 */{ STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
- 8, STATS_FLAGS_PORT, "tx_carrier_errors" },
+ 8, STATS_FLAGS_BOTH, "rx_bcast_packets" },
{ STATS_OFFSET32(rx_stat_dot3statsfcserrors_hi),
8, STATS_FLAGS_PORT, "rx_crc_errors" },
{ STATS_OFFSET32(rx_stat_dot3statsalignmenterrors_hi),
8, STATS_FLAGS_PORT, "rx_align_errors" },
+ { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
+ 8, STATS_FLAGS_PORT, "rx_undersize_packets" },
+ { STATS_OFFSET32(etherstatsoverrsizepkts_hi),
+ 8, STATS_FLAGS_PORT, "rx_oversize_packets" },
+/* 10 */{ STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
+ 8, STATS_FLAGS_PORT, "rx_fragments" },
+ { STATS_OFFSET32(rx_stat_etherstatsjabbers_hi),
+ 8, STATS_FLAGS_PORT, "rx_jabbers" },
+ { STATS_OFFSET32(no_buff_discard_hi),
+ 8, STATS_FLAGS_BOTH, "rx_discards" },
+ { STATS_OFFSET32(mac_filter_discard),
+ 4, STATS_FLAGS_PORT, "rx_filtered_packets" },
+ { STATS_OFFSET32(xxoverflow_discard),
+ 4, STATS_FLAGS_PORT, "rx_fw_discards" },
+ { STATS_OFFSET32(brb_drop_hi),
+ 8, STATS_FLAGS_PORT, "rx_brb_discard" },
+ { STATS_OFFSET32(brb_truncate_hi),
+ 8, STATS_FLAGS_PORT, "rx_brb_truncate" },
+ { STATS_OFFSET32(pause_frames_received_hi),
+ 8, STATS_FLAGS_PORT, "rx_pause_frames" },
+ { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
+ 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" },
+ { STATS_OFFSET32(nig_timer_max),
+ 4, STATS_FLAGS_PORT, "rx_constant_pause_events" },
+/* 20 */{ STATS_OFFSET32(rx_err_discard_pkt),
+ 4, STATS_FLAGS_BOTH, "rx_phy_ip_err_discards"},
+ { STATS_OFFSET32(rx_skb_alloc_failed),
+ 4, STATS_FLAGS_BOTH, "rx_skb_alloc_discard" },
+ { STATS_OFFSET32(hw_csum_err),
+ 4, STATS_FLAGS_BOTH, "rx_csum_offload_errors" },
+
+ { STATS_OFFSET32(total_bytes_transmitted_hi),
+ 8, STATS_FLAGS_BOTH, "tx_bytes" },
+ { STATS_OFFSET32(tx_stat_ifhcoutbadoctets_hi),
+ 8, STATS_FLAGS_PORT, "tx_error_bytes" },
+ { STATS_OFFSET32(total_unicast_packets_transmitted_hi),
+ 8, STATS_FLAGS_BOTH, "tx_packets" },
+ { STATS_OFFSET32(tx_stat_dot3statsinternalmactransmiterrors_hi),
+ 8, STATS_FLAGS_PORT, "tx_mac_errors" },
+ { STATS_OFFSET32(rx_stat_dot3statscarriersenseerrors_hi),
+ 8, STATS_FLAGS_PORT, "tx_carrier_errors" },
{ STATS_OFFSET32(tx_stat_dot3statssinglecollisionframes_hi),
8, STATS_FLAGS_PORT, "tx_single_collisions" },
{ STATS_OFFSET32(tx_stat_dot3statsmultiplecollisionframes_hi),
8, STATS_FLAGS_PORT, "tx_multi_collisions" },
- { STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
+/* 30 */{ STATS_OFFSET32(tx_stat_dot3statsdeferredtransmissions_hi),
8, STATS_FLAGS_PORT, "tx_deferred" },
{ STATS_OFFSET32(tx_stat_dot3statsexcessivecollisions_hi),
8, STATS_FLAGS_PORT, "tx_excess_collisions" },
@@ -9090,14 +9807,6 @@ static const struct {
8, STATS_FLAGS_PORT, "tx_late_collisions" },
{ STATS_OFFSET32(tx_stat_etherstatscollisions_hi),
8, STATS_FLAGS_PORT, "tx_total_collisions" },
- { STATS_OFFSET32(rx_stat_etherstatsfragments_hi),
- 8, STATS_FLAGS_PORT, "rx_fragments" },
-/* 20 */{ STATS_OFFSET32(rx_stat_etherstatsjabbers_hi),
- 8, STATS_FLAGS_PORT, "rx_jabbers" },
- { STATS_OFFSET32(rx_stat_etherstatsundersizepkts_hi),
- 8, STATS_FLAGS_PORT, "rx_undersize_packets" },
- { STATS_OFFSET32(jabber_packets_received),
- 4, STATS_FLAGS_FUNC, "rx_oversize_packets" },
{ STATS_OFFSET32(tx_stat_etherstatspkts64octets_hi),
8, STATS_FLAGS_PORT, "tx_64_byte_packets" },
{ STATS_OFFSET32(tx_stat_etherstatspkts65octetsto127octets_hi),
@@ -9110,52 +9819,46 @@ static const struct {
8, STATS_FLAGS_PORT, "tx_512_to_1023_byte_packets" },
{ STATS_OFFSET32(etherstatspkts1024octetsto1522octets_hi),
8, STATS_FLAGS_PORT, "tx_1024_to_1522_byte_packets" },
- { STATS_OFFSET32(etherstatspktsover1522octets_hi),
+/* 40 */{ STATS_OFFSET32(etherstatspktsover1522octets_hi),
8, STATS_FLAGS_PORT, "tx_1523_to_9022_byte_packets" },
-/* 30 */{ STATS_OFFSET32(rx_stat_xonpauseframesreceived_hi),
- 8, STATS_FLAGS_PORT, "rx_xon_frames" },
- { STATS_OFFSET32(rx_stat_xoffpauseframesreceived_hi),
- 8, STATS_FLAGS_PORT, "rx_xoff_frames" },
- { STATS_OFFSET32(tx_stat_outxonsent_hi),
- 8, STATS_FLAGS_PORT, "tx_xon_frames" },
- { STATS_OFFSET32(tx_stat_outxoffsent_hi),
- 8, STATS_FLAGS_PORT, "tx_xoff_frames" },
- { STATS_OFFSET32(rx_stat_maccontrolframesreceived_hi),
- 8, STATS_FLAGS_PORT, "rx_mac_ctrl_frames" },
- { STATS_OFFSET32(mac_filter_discard),
- 4, STATS_FLAGS_PORT, "rx_filtered_packets" },
- { STATS_OFFSET32(no_buff_discard),
- 4, STATS_FLAGS_FUNC, "rx_discards" },
- { STATS_OFFSET32(xxoverflow_discard),
- 4, STATS_FLAGS_PORT, "rx_fw_discards" },
- { STATS_OFFSET32(brb_drop_hi),
- 8, STATS_FLAGS_PORT, "brb_discard" },
- { STATS_OFFSET32(brb_truncate_hi),
- 8, STATS_FLAGS_PORT, "brb_truncate" },
-/* 40 */{ STATS_OFFSET32(rx_err_discard_pkt),
- 4, STATS_FLAGS_FUNC, "rx_phy_ip_err_discards"},
- { STATS_OFFSET32(rx_skb_alloc_failed),
- 4, STATS_FLAGS_FUNC, "rx_skb_alloc_discard" },
-/* 42 */{ STATS_OFFSET32(hw_csum_err),
- 4, STATS_FLAGS_FUNC, "rx_csum_offload_errors" }
+ { STATS_OFFSET32(pause_frames_sent_hi),
+ 8, STATS_FLAGS_PORT, "tx_pause_frames" }
};
-#define IS_NOT_E1HMF_STAT(bp, i) \
- (IS_E1HMF(bp) && (bnx2x_stats_arr[i].flags & STATS_FLAGS_PORT))
+#define IS_PORT_STAT(i) \
+ ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT)
+#define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC)
+#define IS_E1HMF_MODE_STAT(bp) \
+ (IS_E1HMF(bp) && !(bp->msglevel & BNX2X_MSG_STATS))
static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
{
struct bnx2x *bp = netdev_priv(dev);
- int i, j;
+ int i, j, k;
switch (stringset) {
case ETH_SS_STATS:
- for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_NOT_E1HMF_STAT(bp, i))
- continue;
- strcpy(buf + j*ETH_GSTRING_LEN,
- bnx2x_stats_arr[i].string);
- j++;
+ if (is_multi(bp)) {
+ k = 0;
+ for_each_queue(bp, i) {
+ for (j = 0; j < BNX2X_NUM_Q_STATS; j++)
+ sprintf(buf + (k + j)*ETH_GSTRING_LEN,
+ bnx2x_q_stats_arr[j].string, i);
+ k += BNX2X_NUM_Q_STATS;
+ }
+ if (IS_E1HMF_MODE_STAT(bp))
+ break;
+ for (j = 0; j < BNX2X_NUM_STATS; j++)
+ strcpy(buf + (k + j)*ETH_GSTRING_LEN,
+ bnx2x_stats_arr[j].string);
+ } else {
+ for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+ if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i))
+ continue;
+ strcpy(buf + j*ETH_GSTRING_LEN,
+ bnx2x_stats_arr[i].string);
+ j++;
+ }
}
break;
@@ -9168,13 +9871,22 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
static int bnx2x_get_stats_count(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
- int i, num_stats = 0;
+ int i, num_stats;
- for (i = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_NOT_E1HMF_STAT(bp, i))
- continue;
- num_stats++;
+ if (is_multi(bp)) {
+ num_stats = BNX2X_NUM_Q_STATS * BNX2X_NUM_QUEUES(bp);
+ if (!IS_E1HMF_MODE_STAT(bp))
+ num_stats += BNX2X_NUM_STATS;
+ } else {
+ if (IS_E1HMF_MODE_STAT(bp)) {
+ num_stats = 0;
+ for (i = 0; i < BNX2X_NUM_STATS; i++)
+ if (IS_FUNC_STAT(i))
+ num_stats++;
+ } else
+ num_stats = BNX2X_NUM_STATS;
}
+
return num_stats;
}
@@ -9182,29 +9894,71 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *buf)
{
struct bnx2x *bp = netdev_priv(dev);
- u32 *hw_stats = (u32 *)&bp->eth_stats;
- int i, j;
+ u32 *hw_stats, *offset;
+ int i, j, k;
- for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
- if (IS_NOT_E1HMF_STAT(bp, i))
- continue;
-
- if (bnx2x_stats_arr[i].size == 0) {
- /* skip this counter */
- buf[j] = 0;
- j++;
- continue;
+ if (is_multi(bp)) {
+ k = 0;
+ for_each_queue(bp, i) {
+ hw_stats = (u32 *)&bp->fp[i].eth_q_stats;
+ for (j = 0; j < BNX2X_NUM_Q_STATS; j++) {
+ if (bnx2x_q_stats_arr[j].size == 0) {
+ /* skip this counter */
+ buf[k + j] = 0;
+ continue;
+ }
+ offset = (hw_stats +
+ bnx2x_q_stats_arr[j].offset);
+ if (bnx2x_q_stats_arr[j].size == 4) {
+ /* 4-byte counter */
+ buf[k + j] = (u64) *offset;
+ continue;
+ }
+ /* 8-byte counter */
+ buf[k + j] = HILO_U64(*offset, *(offset + 1));
+ }
+ k += BNX2X_NUM_Q_STATS;
}
- if (bnx2x_stats_arr[i].size == 4) {
- /* 4-byte counter */
- buf[j] = (u64) *(hw_stats + bnx2x_stats_arr[i].offset);
+ if (IS_E1HMF_MODE_STAT(bp))
+ return;
+ hw_stats = (u32 *)&bp->eth_stats;
+ for (j = 0; j < BNX2X_NUM_STATS; j++) {
+ if (bnx2x_stats_arr[j].size == 0) {
+ /* skip this counter */
+ buf[k + j] = 0;
+ continue;
+ }
+ offset = (hw_stats + bnx2x_stats_arr[j].offset);
+ if (bnx2x_stats_arr[j].size == 4) {
+ /* 4-byte counter */
+ buf[k + j] = (u64) *offset;
+ continue;
+ }
+ /* 8-byte counter */
+ buf[k + j] = HILO_U64(*offset, *(offset + 1));
+ }
+ } else {
+ hw_stats = (u32 *)&bp->eth_stats;
+ for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) {
+ if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i))
+ continue;
+ if (bnx2x_stats_arr[i].size == 0) {
+ /* skip this counter */
+ buf[j] = 0;
+ j++;
+ continue;
+ }
+ offset = (hw_stats + bnx2x_stats_arr[i].offset);
+ if (bnx2x_stats_arr[i].size == 4) {
+ /* 4-byte counter */
+ buf[j] = (u64) *offset;
+ j++;
+ continue;
+ }
+ /* 8-byte counter */
+ buf[j] = HILO_U64(*offset, *(offset + 1));
j++;
- continue;
}
- /* 8-byte counter */
- buf[j] = HILO_U64(*(hw_stats + bnx2x_stats_arr[i].offset),
- *(hw_stats + bnx2x_stats_arr[i].offset + 1));
- j++;
}
}
@@ -9251,6 +10005,8 @@ static struct ethtool_ops bnx2x_ethtool_ops = {
.get_settings = bnx2x_get_settings,
.set_settings = bnx2x_set_settings,
.get_drvinfo = bnx2x_get_drvinfo,
+ .get_regs_len = bnx2x_get_regs_len,
+ .get_regs = bnx2x_get_regs,
.get_wol = bnx2x_get_wol,
.set_wol = bnx2x_set_wol,
.get_msglevel = bnx2x_get_msglevel,
@@ -9363,25 +10119,41 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
bnx2x_update_fpsb_idx(fp);
if (bnx2x_has_tx_work(fp))
- bnx2x_tx_int(fp, budget);
+ bnx2x_tx_int(fp);
- if (bnx2x_has_rx_work(fp))
+ if (bnx2x_has_rx_work(fp)) {
work_done = bnx2x_rx_int(fp, budget);
- rmb(); /* BNX2X_HAS_WORK() reads the status block */
- /* must not complete if we consumed full budget */
- if ((work_done < budget) && !BNX2X_HAS_WORK(fp)) {
+ /* must not complete if we consumed full budget */
+ if (work_done >= budget)
+ goto poll_again;
+ }
+
+ /* BNX2X_HAS_WORK() reads the status block, thus we need to
+ * ensure that status block indices have been actually read
+ * (bnx2x_update_fpsb_idx) prior to this check (BNX2X_HAS_WORK)
+ * so that we won't write the "newer" value of the status block to IGU
+ * (if there was a DMA right after BNX2X_HAS_WORK and
+ * if there is no rmb, the memory reading (bnx2x_update_fpsb_idx)
+ * may be postponed to right before bnx2x_ack_sb). In this case
+ * there will never be another interrupt until there is another update
+ * of the status block, while there is still unhandled work.
+ */
+ rmb();
+ if (!BNX2X_HAS_WORK(fp)) {
#ifdef BNX2X_STOP_ON_ERROR
poll_panic:
#endif
- netif_rx_complete(napi);
+ napi_complete(napi);
- bnx2x_ack_sb(bp, FP_SB_ID(fp), USTORM_ID,
+ bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID,
le16_to_cpu(fp->fp_u_idx), IGU_INT_NOP, 1);
- bnx2x_ack_sb(bp, FP_SB_ID(fp), CSTORM_ID,
+ bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID,
le16_to_cpu(fp->fp_c_idx), IGU_INT_ENABLE, 1);
}
+
+poll_again:
return work_done;
}
@@ -9457,7 +10229,7 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
rc = XMIT_PLAIN;
else {
- if (skb->protocol == ntohs(ETH_P_IPV6)) {
+ if (skb->protocol == htons(ETH_P_IPV6)) {
rc = XMIT_CSUM_V6;
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
rc |= XMIT_CSUM_TCP;
@@ -9479,7 +10251,9 @@ static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
}
#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
-/* check if packet requires linearization (packet is too fragmented) */
+/* check if packet requires linearization (packet is too fragmented)
+ no need to check fragmentation if page size > 8K (there will be no
+ violation to FW restrictions) */
static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
u32 xmit_type)
{
@@ -9538,7 +10312,6 @@ static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb,
wnd_sum -=
skb_shinfo(skb)->frags[wnd_idx].size;
}
-
} else {
/* in non-LSO too fragmented packet should always
be linearized */
@@ -9566,6 +10339,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
struct bnx2x_fastpath *fp;
+ struct netdev_queue *txq;
struct sw_tx_bd *tx_buf;
struct eth_tx_bd *tx_bd;
struct eth_tx_parse_bd *pbd = NULL;
@@ -9582,12 +10356,14 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_BUSY;
#endif
- fp_index = (smp_processor_id() % bp->num_queues);
+ fp_index = skb_get_queue_mapping(skb);
+ txq = netdev_get_tx_queue(dev, fp_index);
+
fp = &bp->fp[fp_index];
if (unlikely(bnx2x_tx_avail(fp) < (skb_shinfo(skb)->nr_frags + 3))) {
- bp->eth_stats.driver_xoff++,
- netif_stop_queue(dev);
+ fp->eth_q_stats.driver_xoff++,
+ netif_tx_stop_queue(txq);
BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
return NETDEV_TX_BUSY;
}
@@ -9598,8 +10374,9 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type);
#if (MAX_SKB_FRAGS >= MAX_FETCH_BD - 3)
- /* First, check if we need to linearize the skb
- (due to FW restrictions) */
+ /* First, check if we need to linearize the skb (due to FW
+ restrictions). No need to check fragmentation if page size > 8K
+ (there will be no violation to FW restrictions) */
if (bnx2x_pkt_req_lin(bp, skb, xmit_type)) {
/* Statistics of linearization */
bp->lin_cnt++;
@@ -9664,9 +10441,9 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
hlen = (skb_network_header(skb) - skb->data + vlan_off) / 2;
/* for now NS flag is not used in Linux */
- pbd->global_data = (hlen |
- ((skb->protocol == ntohs(ETH_P_8021Q)) <<
- ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
+ pbd->global_data =
+ (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) <<
+ ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
pbd->ip_hlen = (skb_transport_header(skb) -
skb_network_header(skb)) / 2;
@@ -9810,12 +10587,10 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/
wmb();
- fp->hw_tx_prods->bds_prod =
- cpu_to_le16(le16_to_cpu(fp->hw_tx_prods->bds_prod) + nbd);
+ le16_add_cpu(&fp->hw_tx_prods->bds_prod, nbd);
mb(); /* FW restriction: must not reorder writing nbd and packets */
- fp->hw_tx_prods->packets_prod =
- cpu_to_le32(le32_to_cpu(fp->hw_tx_prods->packets_prod) + 1);
- DOORBELL(bp, FP_IDX(fp), 0);
+ le32_add_cpu(&fp->hw_tx_prods->packets_prod, 1);
+ DOORBELL(bp, fp->index, 0);
mmiowb();
@@ -9826,10 +10601,10 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* We want bnx2x_tx_int to "see" the updated tx_bd_prod
if we put Tx into XOFF state. */
smp_mb();
- netif_stop_queue(dev);
- bp->eth_stats.driver_xoff++;
+ netif_tx_stop_queue(txq);
+ fp->eth_q_stats.driver_xoff++;
if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
- netif_wake_queue(dev);
+ netif_tx_wake_queue(txq);
}
fp->tx_pkt++;
@@ -9862,7 +10637,7 @@ static int bnx2x_close(struct net_device *dev)
return 0;
}
-/* called with netif_tx_lock from set_multicast */
+/* called with netif_tx_lock from dev_mcast.c */
static void bnx2x_set_rx_mode(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
@@ -9921,7 +10696,7 @@ static void bnx2x_set_rx_mode(struct net_device *dev)
config->config_table[i].
cam_entry.lsb_mac_addr);
}
- old = config->hdr.length_6b;
+ old = config->hdr.length;
if (old > i) {
for (; i < old; i++) {
if (CAM_IS_INVALID(config->
@@ -9940,9 +10715,9 @@ static void bnx2x_set_rx_mode(struct net_device *dev)
else
offset = BNX2X_MAX_MULTICAST*(1 + port);
- config->hdr.length_6b = i;
+ config->hdr.length = i;
config->hdr.offset = offset;
- config->hdr.client_id = BP_CL_ID(bp);
+ config->hdr.client_id = bp->fp->cl_id;
config->hdr.reserved1 = 0;
bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
@@ -10128,7 +10903,7 @@ static const struct net_device_ops bnx2x_netdev_ops = {
.ndo_open = bnx2x_open,
.ndo_stop = bnx2x_close,
.ndo_start_xmit = bnx2x_start_xmit,
- .ndo_set_multicast_list = bnx2x_set_rx_mode,
+ .ndo_set_multicast_list = bnx2x_set_rx_mode,
.ndo_set_mac_address = bnx2x_change_mac_addr,
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = bnx2x_ioctl,
@@ -10142,7 +10917,6 @@ static const struct net_device_ops bnx2x_netdev_ops = {
#endif
};
-
static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
struct net_device *dev)
{
@@ -10321,7 +11095,7 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
printk(KERN_INFO "%s", version);
/* dev zeroed in init_etherdev */
- dev = alloc_etherdev(sizeof(*bp));
+ dev = alloc_etherdev_mq(sizeof(*bp), MAX_CONTEXT);
if (!dev) {
printk(KERN_ERR PFX "Cannot allocate net device\n");
return -ENOMEM;
@@ -10348,14 +11122,14 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
goto init_one_exit;
}
- bp->common.name = board_info[ent->driver_data].name;
printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
- " IRQ %d, ", dev->name, bp->common.name,
+ " IRQ %d, ", dev->name, board_info[ent->driver_data].name,
(CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
bnx2x_get_pcie_width(bp),
(bnx2x_get_pcie_speed(bp) == 2) ? "5GHz (Gen2)" : "2.5GHz",
dev->base_addr, bp->pdev->irq);
printk(KERN_CONT "node addr %pM\n", dev->dev_addr);
+
return 0;
init_one_exit:
@@ -10487,15 +11261,15 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
struct mac_configuration_cmd *config =
bnx2x_sp(bp, mcast_config);
- for (i = 0; i < config->hdr.length_6b; i++)
+ for (i = 0; i < config->hdr.length; i++)
CAM_INVALIDATE(config->config_table[i]);
}
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
- for_each_queue(bp, i)
+ for_each_rx_queue(bp, i)
netif_napi_del(&bnx2x_fp(bp, i, napi));
bnx2x_free_mem(bp);
@@ -10622,8 +11396,8 @@ static void bnx2x_io_resume(struct pci_dev *pdev)
static struct pci_error_handlers bnx2x_err_handler = {
.error_detected = bnx2x_io_error_detected,
- .slot_reset = bnx2x_io_slot_reset,
- .resume = bnx2x_io_resume,
+ .slot_reset = bnx2x_io_slot_reset,
+ .resume = bnx2x_io_resume,
};
static struct pci_driver bnx2x_pci_driver = {
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index d084e5fc4b51..b8ce6fc927a0 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -30,8 +30,20 @@
address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address
BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. */
#define BRB1_REG_FREE_LIST_PRS_CRDT 0x60200
+/* [RW 10] The number of free blocks above which the High_llfc signal to
+ interface #n is de-asserted. */
+#define BRB1_REG_HIGH_LLFC_HIGH_THRESHOLD_0 0x6014c
+/* [RW 10] The number of free blocks below which the High_llfc signal to
+ interface #n is asserted. */
+#define BRB1_REG_HIGH_LLFC_LOW_THRESHOLD_0 0x6013c
/* [RW 23] LL RAM data. */
#define BRB1_REG_LL_RAM 0x61000
+/* [RW 10] The number of free blocks above which the Low_llfc signal to
+ interface #n is de-asserted. */
+#define BRB1_REG_LOW_LLFC_HIGH_THRESHOLD_0 0x6016c
+/* [RW 10] The number of free blocks below which the Low_llfc signal to
+ interface #n is asserted. */
+#define BRB1_REG_LOW_LLFC_LOW_THRESHOLD_0 0x6015c
/* [R 24] The number of full blocks. */
#define BRB1_REG_NUM_OF_FULL_BLOCKS 0x60090
/* [ST 32] The number of cycles that the write_full signal towards MAC #0
@@ -125,6 +137,10 @@
stands for weight 8 (the most prioritised); 1 stands for weight 1(least
prioritised); 2 stands for weight 2; tc. */
#define CCM_REG_CQM_P_WEIGHT 0xd00b8
+/* [RW 3] The weight of the QM (secondary) input in the WRR mechanism. 0
+ stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define CCM_REG_CQM_S_WEIGHT 0xd00bc
/* [RW 1] Input SDM Interface enable. If 0 - the valid input is disregarded;
acknowledge output is deasserted; all other signals are treated as usual;
if 1 - normal activity. */
@@ -132,6 +148,10 @@
/* [RC 1] Set when the message length mismatch (relative to last indication)
at the SDM interface is detected. */
#define CCM_REG_CSDM_LENGTH_MIS 0xd0170
+/* [RW 3] The weight of the SDM input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define CCM_REG_CSDM_WEIGHT 0xd00b4
/* [RW 28] The CM header for QM formatting in case of an error in the QM
inputs. */
#define CCM_REG_ERR_CCM_HDR 0xd0094
@@ -211,6 +231,11 @@
/* [RC 1] Set when the message length mismatch (relative to last indication)
at the STORM interface is detected. */
#define CCM_REG_STORM_LENGTH_MIS 0xd016c
+/* [RW 3] The weight of the STORM input in the WRR (Weighted Round robin)
+ mechanism. 0 stands for weight 8 (the most prioritised); 1 stands for
+ weight 1(least prioritised); 2 stands for weight 2 (more prioritised);
+ tc. */
+#define CCM_REG_STORM_WEIGHT 0xd009c
/* [RW 1] Input tsem Interface enable. If 0 - the valid input is
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
@@ -323,7 +348,11 @@
set one of these bits. the bit description can be found in CFC
specifications */
#define CFC_REG_ERROR_VECTOR 0x10403c
+/* [WB 93] LCID info ram access */
+#define CFC_REG_INFO_RAM 0x105000
+#define CFC_REG_INFO_RAM_SIZE 1024
#define CFC_REG_INIT_REG 0x10404c
+#define CFC_REG_INTERFACES 0x104058
/* [RW 24] {weight_load_client7[2:0] to weight_load_client0[2:0]}. this
field allows changing the priorities of the weighted-round-robin arbiter
which selects which CFC load client should be served next */
@@ -337,8 +366,6 @@
#define CFC_REG_NUM_LCIDS_ALLOC 0x104020
/* [R 9] Number of Arriving LCIDs in Link List Block */
#define CFC_REG_NUM_LCIDS_ARRIVING 0x104004
-/* [R 9] Number of Inside LCIDs in Link List Block */
-#define CFC_REG_NUM_LCIDS_INSIDE 0x104008
/* [R 9] Number of Leaving LCIDs in Link List Block */
#define CFC_REG_NUM_LCIDS_LEAVING 0x104018
/* [RW 8] The event id for aggregated interrupt 0 */
@@ -730,6 +757,7 @@
#define DORQ_REG_SHRT_CMHEAD 0x170054
#define HC_CONFIG_0_REG_ATTN_BIT_EN_0 (0x1<<4)
#define HC_CONFIG_0_REG_INT_LINE_EN_0 (0x1<<3)
+#define HC_CONFIG_0_REG_MSI_ATTN_EN_0 (0x1<<7)
#define HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 (0x1<<2)
#define HC_CONFIG_0_REG_SINGLE_ISR_EN_0 (0x1<<1)
#define HC_REG_AGG_INT_0 0x108050
@@ -1410,6 +1438,29 @@
This is the result value of the pin; not the drive value. Writing these
bits will have not effect. */
#define MISC_REG_GPIO 0xa490
+/* [RW 8] These bits enable the GPIO_INTs to signals event to the
+ IGU/MCP.according to the following map: [0] p0_gpio_0; [1] p0_gpio_1; [2]
+ p0_gpio_2; [3] p0_gpio_3; [4] p1_gpio_0; [5] p1_gpio_1; [6] p1_gpio_2;
+ [7] p1_gpio_3; */
+#define MISC_REG_GPIO_EVENT_EN 0xa2bc
+/* [RW 32] GPIO INT. [31-28] OLD_CLR port1; [27-24] OLD_CLR port0; Writing a
+ '1' to these bit clears the corresponding bit in the #OLD_VALUE register.
+ This will acknowledge an interrupt on the falling edge of corresponding
+ GPIO input (reset value 0). [23-16] OLD_SET [23-16] port1; OLD_SET port0;
+ Writing a '1' to these bit sets the corresponding bit in the #OLD_VALUE
+ register. This will acknowledge an interrupt on the rising edge of
+ corresponding SPIO input (reset value 0). [15-12] OLD_VALUE [11-8] port1;
+ OLD_VALUE port0; RO; These bits indicate the old value of the GPIO input
+ value. When the ~INT_STATE bit is set; this bit indicates the OLD value
+ of the pin such that if ~INT_STATE is set and this bit is '0'; then the
+ interrupt is due to a low to high edge. If ~INT_STATE is set and this bit
+ is '1'; then the interrupt is due to a high to low edge (reset value 0).
+ [7-4] INT_STATE port1; [3-0] INT_STATE RO port0; These bits indicate the
+ current GPIO interrupt state for each GPIO pin. This bit is cleared when
+ the appropriate #OLD_SET or #OLD_CLR command bit is written. This bit is
+ set when the GPIO input does not match the current value in #OLD_VALUE
+ (reset value 0). */
+#define MISC_REG_GPIO_INT 0xa494
/* [R 28] this field hold the last information that caused reserved
attention. bits [19:0] - address; [22:20] function; [23] reserved;
[27:24] the master that caused the attention - according to the following
@@ -1554,6 +1605,14 @@
command bit is written. This bit is set when the SPIO input does not
match the current value in #OLD_VALUE (reset value 0). */
#define MISC_REG_SPIO_INT 0xa500
+/* [RW 32] reload value for counter 4 if reload; the value will be reload if
+ the counter reached zero and the reload bit
+ (~misc_registers_sw_timer_cfg_4.sw_timer_cfg_4[1] ) is set */
+#define MISC_REG_SW_TIMER_RELOAD_VAL_4 0xa2fc
+/* [RW 32] the value of the counter for sw timers1-8. there are 8 addresses
+ in this register. addres 0 - timer 1; address - timer 2�address 7 -
+ timer 8 */
+#define MISC_REG_SW_TIMER_VAL 0xa5c0
/* [RW 1] Set by the MCP to remember if one or more of the drivers is/are
loaded; 0-prepare; -unprepare */
#define MISC_REG_UNPREPARED 0xa424
@@ -1660,6 +1719,19 @@
/* [RW 4] led mode for port0: 0 MAC; 1-3 PHY1; 4 MAC2; 5-7 PHY4; 8-MAC3;
9-11PHY7; 12 MAC4; 13-15 PHY10; */
#define NIG_REG_LED_MODE_P0 0x102f0
+/* [RW 3] for port0 enable for llfc ppp and pause. b0 - brb1 enable; b1-
+ tsdm enable; b2- usdm enable */
+#define NIG_REG_LLFC_EGRESS_SRC_ENABLE_0 0x16070
+/* [RW 1] SAFC enable for port0. This register may get 1 only when
+ ~ppp_enable.ppp_enable = 0 and pause_enable.pause_enable =0 for the same
+ port */
+#define NIG_REG_LLFC_ENABLE_0 0x16208
+/* [RW 16] classes are high-priority for port0 */
+#define NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0 0x16058
+/* [RW 16] classes are low-priority for port0 */
+#define NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0 0x16060
+/* [RW 1] Output enable of message to LLFC BMAC IF for port0 */
+#define NIG_REG_LLFC_OUT_EN_0 0x160c8
#define NIG_REG_LLH0_ACPI_PAT_0_CRC 0x1015c
#define NIG_REG_LLH0_ACPI_PAT_6_LEN 0x10154
#define NIG_REG_LLH0_BRB1_DRV_MASK 0x10244
@@ -1730,6 +1802,10 @@
#define NIG_REG_NIG_INT_STS_1 0x103c0
/* [R 32] Parity register #0 read */
#define NIG_REG_NIG_PRTY_STS 0x103d0
+/* [RW 1] Pause enable for port0. This register may get 1 only when
+ ~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same
+ port */
+#define NIG_REG_PAUSE_ENABLE_0 0x160c0
/* [RW 1] Input enable for RX PBF LP IF */
#define NIG_REG_PBF_LB_IN_EN 0x100b4
/* [RW 1] Value of this register will be transmitted to port swap when
@@ -1739,6 +1815,10 @@
#define NIG_REG_PRS_EOP_OUT_EN 0x10104
/* [RW 1] Input enable for RX parser request IF */
#define NIG_REG_PRS_REQ_IN_EN 0x100b8
+/* [RW 5] control to serdes - CL45 DEVAD */
+#define NIG_REG_SERDES0_CTRL_MD_DEVAD 0x10370
+/* [RW 1] control to serdes; 0 - clause 45; 1 - clause 22 */
+#define NIG_REG_SERDES0_CTRL_MD_ST 0x1036c
/* [RW 5] control to serdes - CL22 PHY_ADD and CL45 PRTAD */
#define NIG_REG_SERDES0_CTRL_PHY_ADDR 0x10374
/* [R 1] status from serdes0 that inputs to interrupt logic of link status */
@@ -1885,6 +1965,7 @@
#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_2 0x400e4
#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_3 0x400e8
#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4 0x400ec
+#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_5 0x400f0
/* [RW 32] The CM header for flush message where 'load existed' bit in CFC
load response is set and packet type is 0. Used in packet start message
to TCM. */
@@ -1893,6 +1974,7 @@
#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2 0x400c4
#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3 0x400c8
#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4 0x400cc
+#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_5 0x400d0
/* [RW 32] The CM header for a match and packet type 1 for loopback port.
Used in packet start message to TCM. */
#define PRS_REG_CM_HDR_LOOPBACK_TYPE_1 0x4009c
@@ -2035,6 +2117,19 @@
#define PXP2_REG_PGL_INT_XSDM_5 0x1204e8
#define PXP2_REG_PGL_INT_XSDM_6 0x1204ec
#define PXP2_REG_PGL_INT_XSDM_7 0x1204f0
+/* [RW 3] this field allows one function to pretend being another function
+ when accessing any BAR mapped resource within the device. the value of
+ the field is the number of the function that will be accessed
+ effectively. after software write to this bit it must read it in order to
+ know that the new value is updated */
+#define PXP2_REG_PGL_PRETEND_FUNC_F0 0x120674
+#define PXP2_REG_PGL_PRETEND_FUNC_F1 0x120678
+#define PXP2_REG_PGL_PRETEND_FUNC_F2 0x12067c
+#define PXP2_REG_PGL_PRETEND_FUNC_F3 0x120680
+#define PXP2_REG_PGL_PRETEND_FUNC_F4 0x120684
+#define PXP2_REG_PGL_PRETEND_FUNC_F5 0x120688
+#define PXP2_REG_PGL_PRETEND_FUNC_F6 0x12068c
+#define PXP2_REG_PGL_PRETEND_FUNC_F7 0x120690
/* [R 1] this bit indicates that a read request was blocked because of
bus_master_en was deasserted */
#define PXP2_REG_PGL_READ_BLOCKED 0x120568
@@ -2498,6 +2593,11 @@
considered zero so practically there are only 20 bits in this register;
queues 63-0 */
#define QM_REG_BASEADDR 0x168900
+/* [RW 32] The base logical address (in bytes) of each physical queue. The
+ index I represents the physical queue number. The 12 lsbs are ignore and
+ considered zero so practically there are only 20 bits in this register;
+ queues 127-64 */
+#define QM_REG_BASEADDR_EXT_A 0x16e100
/* [RW 16] The byte credit cost for each task. This value is for both ports */
#define QM_REG_BYTECRDCOST 0x168234
/* [RW 16] The initial byte credit value for both ports. */
@@ -3438,6 +3538,16 @@
#define SRC_REG_KEYRSS0_0 0x40408
#define SRC_REG_KEYRSS0_7 0x40424
#define SRC_REG_KEYRSS1_9 0x40454
+#define SRC_REG_KEYSEARCH_0 0x40458
+#define SRC_REG_KEYSEARCH_1 0x4045c
+#define SRC_REG_KEYSEARCH_2 0x40460
+#define SRC_REG_KEYSEARCH_3 0x40464
+#define SRC_REG_KEYSEARCH_4 0x40468
+#define SRC_REG_KEYSEARCH_5 0x4046c
+#define SRC_REG_KEYSEARCH_6 0x40470
+#define SRC_REG_KEYSEARCH_7 0x40474
+#define SRC_REG_KEYSEARCH_8 0x40478
+#define SRC_REG_KEYSEARCH_9 0x4047c
#define SRC_REG_LASTFREE0 0x40530
#define SRC_REG_NUMBER_HASH_BITS0 0x40400
/* [RW 1] Reset internal state machines. */
@@ -3481,6 +3591,10 @@
/* [RC 1] Message length mismatch (relative to last indication) at the In#9
interface. */
#define TCM_REG_CSEM_LENGTH_MIS 0x50174
+/* [RW 3] The weight of the input csem in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_CSEM_WEIGHT 0x500bc
/* [RW 8] The Event ID in case of ErrorFlg is set in the input message. */
#define TCM_REG_ERR_EVNT_ID 0x500a0
/* [RW 28] The CM erroneous header for QM and Timers formatting. */
@@ -3524,6 +3638,7 @@
#define TCM_REG_N_SM_CTX_LD_2 0x50058
#define TCM_REG_N_SM_CTX_LD_3 0x5005c
#define TCM_REG_N_SM_CTX_LD_4 0x50060
+#define TCM_REG_N_SM_CTX_LD_5 0x50064
/* [RW 1] Input pbf Interface enable. If 0 - the valid input is disregarded;
acknowledge output is deasserted; all other signals are treated as usual;
if 1 - normal activity. */
@@ -3563,6 +3678,10 @@
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
#define TCM_REG_STORM_TCM_IFEN 0x50010
+/* [RW 3] The weight of the STORM input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_STORM_WEIGHT 0x500ac
/* [RW 1] CM - CFC Interface enable. If 0 - the valid input is disregarded;
acknowledge output is deasserted; all other signals are treated as usual;
if 1 - normal activity. */
@@ -3598,10 +3717,22 @@
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
#define TCM_REG_TM_TCM_IFEN 0x5001c
+/* [RW 3] The weight of the Timers input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_TM_WEIGHT 0x500d0
/* [RW 6] QM output initial credit. Max credit available - 32.Write writes
the initial credit value; read returns the current value of the credit
counter. Must be initialized to 32 at start-up. */
#define TCM_REG_TQM_INIT_CRD 0x5021c
+/* [RW 3] The weight of the QM (primary) input in the WRR mechanism. 0
+ stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_TQM_P_WEIGHT 0x500c8
+/* [RW 3] The weight of the QM (secondary) input in the WRR mechanism. 0
+ stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_TQM_S_WEIGHT 0x500cc
/* [RW 28] The CM header value for QM request (primary). */
#define TCM_REG_TQM_TCM_HDR_P 0x50090
/* [RW 28] The CM header value for QM request (secondary). */
@@ -3628,6 +3759,10 @@
/* [RC 1] Message length mismatch (relative to last indication) at the In#8
interface. */
#define TCM_REG_USEM_LENGTH_MIS 0x50170
+/* [RW 3] The weight of the input usem in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_USEM_WEIGHT 0x500b8
/* [RW 21] Indirect access to the descriptor table of the XX protection
mechanism. The fields are: [5:0] - length of the message; 15:6] - message
pointer; 20:16] - next pointer. */
@@ -3677,6 +3812,7 @@
#define TM_REG_EN_CL1_INPUT 0x16400c
/* [RW 1] Enable client2 input. */
#define TM_REG_EN_CL2_INPUT 0x164010
+#define TM_REG_EN_LINEAR0_TIMER 0x164014
/* [RW 1] Enable real time counter. */
#define TM_REG_EN_REAL_TIME_CNT 0x1640d8
/* [RW 1] Enable for Timers state machines. */
@@ -3684,14 +3820,22 @@
/* [RW 4] Load value for expiration credit cnt. CFC max number of
outstanding load requests for timers (expiration) context loading. */
#define TM_REG_EXP_CRDCNT_VAL 0x164238
+/* [RW 32] Linear0 logic address. */
+#define TM_REG_LIN0_LOGIC_ADDR 0x164240
/* [RW 18] Linear0 Max active cid (in banks of 32 entries). */
#define TM_REG_LIN0_MAX_ACTIVE_CID 0x164048
/* [WB 64] Linear0 phy address. */
#define TM_REG_LIN0_PHY_ADDR 0x164270
+/* [RW 1] Linear0 physical address valid. */
+#define TM_REG_LIN0_PHY_ADDR_VALID 0x164248
/* [RW 24] Linear0 array scan timeout. */
#define TM_REG_LIN0_SCAN_TIME 0x16403c
+/* [RW 32] Linear1 logic address. */
+#define TM_REG_LIN1_LOGIC_ADDR 0x164250
/* [WB 64] Linear1 phy address. */
#define TM_REG_LIN1_PHY_ADDR 0x164280
+/* [RW 1] Linear1 physical address valid. */
+#define TM_REG_LIN1_PHY_ADDR_VALID 0x164258
/* [RW 6] Linear timer set_clear fifo threshold. */
#define TM_REG_LIN_SETCLR_FIFO_ALFULL_THR 0x164070
/* [RW 2] Load value for pci arbiter credit cnt. */
@@ -3708,6 +3852,17 @@
#define TM_REG_TM_INT_STS 0x1640f0
/* [RW 8] The event id for aggregated interrupt 0 */
#define TSDM_REG_AGG_INT_EVENT_0 0x42038
+#define TSDM_REG_AGG_INT_EVENT_1 0x4203c
+#define TSDM_REG_AGG_INT_EVENT_10 0x42060
+#define TSDM_REG_AGG_INT_EVENT_11 0x42064
+#define TSDM_REG_AGG_INT_EVENT_12 0x42068
+#define TSDM_REG_AGG_INT_EVENT_13 0x4206c
+#define TSDM_REG_AGG_INT_EVENT_14 0x42070
+#define TSDM_REG_AGG_INT_EVENT_15 0x42074
+#define TSDM_REG_AGG_INT_EVENT_16 0x42078
+#define TSDM_REG_AGG_INT_EVENT_17 0x4207c
+#define TSDM_REG_AGG_INT_EVENT_18 0x42080
+#define TSDM_REG_AGG_INT_EVENT_19 0x42084
#define TSDM_REG_AGG_INT_EVENT_2 0x42040
#define TSDM_REG_AGG_INT_EVENT_20 0x42088
#define TSDM_REG_AGG_INT_EVENT_21 0x4208c
@@ -3723,6 +3878,19 @@
#define TSDM_REG_AGG_INT_EVENT_30 0x420b0
#define TSDM_REG_AGG_INT_EVENT_31 0x420b4
#define TSDM_REG_AGG_INT_EVENT_4 0x42048
+/* [RW 1] The T bit for aggregated interrupt 0 */
+#define TSDM_REG_AGG_INT_T_0 0x420b8
+#define TSDM_REG_AGG_INT_T_1 0x420bc
+#define TSDM_REG_AGG_INT_T_10 0x420e0
+#define TSDM_REG_AGG_INT_T_11 0x420e4
+#define TSDM_REG_AGG_INT_T_12 0x420e8
+#define TSDM_REG_AGG_INT_T_13 0x420ec
+#define TSDM_REG_AGG_INT_T_14 0x420f0
+#define TSDM_REG_AGG_INT_T_15 0x420f4
+#define TSDM_REG_AGG_INT_T_16 0x420f8
+#define TSDM_REG_AGG_INT_T_17 0x420fc
+#define TSDM_REG_AGG_INT_T_18 0x42100
+#define TSDM_REG_AGG_INT_T_19 0x42104
/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
#define TSDM_REG_CFC_RSP_START_ADDR 0x42008
/* [RW 16] The maximum value of the competion counter #0 */
@@ -3967,6 +4135,10 @@
/* [RC 1] Set when the message length mismatch (relative to last indication)
at the dorq interface is detected. */
#define UCM_REG_DORQ_LENGTH_MIS 0xe0168
+/* [RW 3] The weight of the input dorq in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_DORQ_WEIGHT 0xe00c0
/* [RW 8] The Event ID in case ErrorFlg input message bit is set. */
#define UCM_REG_ERR_EVNT_ID 0xe00a4
/* [RW 28] The CM erroneous header for QM and Timers formatting. */
@@ -4030,6 +4202,10 @@
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
#define UCM_REG_STORM_UCM_IFEN 0xe0010
+/* [RW 3] The weight of the STORM input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_STORM_WEIGHT 0xe00b0
/* [RW 4] Timers output initial credit. Max credit available - 15.Write
writes the initial credit value; read returns the current value of the
credit counter. Must be initialized to 4 at start-up. */
@@ -4040,6 +4216,10 @@
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
#define UCM_REG_TM_UCM_IFEN 0xe001c
+/* [RW 3] The weight of the Timers input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_TM_WEIGHT 0xe00d4
/* [RW 1] Input tsem Interface enable. If 0 - the valid input is
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
@@ -4092,6 +4272,10 @@
stands for weight 8 (the most prioritised); 1 stands for weight 1(least
prioritised); 2 stands for weight 2; tc. */
#define UCM_REG_UQM_P_WEIGHT 0xe00cc
+/* [RW 3] The weight of the QM (secondary) input in the WRR mechanism. 0
+ stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_UQM_S_WEIGHT 0xe00d0
/* [RW 28] The CM header value for QM request (primary). */
#define UCM_REG_UQM_UCM_HDR_P 0xe0094
/* [RW 28] The CM header value for QM request (secondary). */
@@ -4107,6 +4291,10 @@
/* [RC 1] Set when the message length mismatch (relative to last indication)
at the SDM interface is detected. */
#define UCM_REG_USDM_LENGTH_MIS 0xe0158
+/* [RW 3] The weight of the SDM input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_USDM_WEIGHT 0xe00c8
/* [RW 1] Input xsem Interface enable. If 0 - the valid input is
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
@@ -4114,6 +4302,10 @@
/* [RC 1] Set when the message length mismatch (relative to last indication)
at the xsem interface isdetected. */
#define UCM_REG_XSEM_LENGTH_MIS 0xe0164
+/* [RW 3] The weight of the input xsem in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_XSEM_WEIGHT 0xe00bc
/* [RW 20] Indirect access to the descriptor table of the XX protection
mechanism. The fields are:[5:0] - message length; 14:6] - message
pointer; 19:15] - next pointer. */
@@ -4163,6 +4355,7 @@
#define USDM_REG_AGG_INT_EVENT_30 0xc40b0
#define USDM_REG_AGG_INT_EVENT_31 0xc40b4
#define USDM_REG_AGG_INT_EVENT_4 0xc4048
+#define USDM_REG_AGG_INT_EVENT_5 0xc404c
/* [RW 1] For each aggregated interrupt index whether the mode is normal (0)
or auto-mask-mode (1) */
#define USDM_REG_AGG_INT_MODE_0 0xc41b8
@@ -4177,6 +4370,8 @@
#define USDM_REG_AGG_INT_MODE_17 0xc41fc
#define USDM_REG_AGG_INT_MODE_18 0xc4200
#define USDM_REG_AGG_INT_MODE_19 0xc4204
+#define USDM_REG_AGG_INT_MODE_4 0xc41c8
+#define USDM_REG_AGG_INT_MODE_5 0xc41cc
/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
#define USDM_REG_CFC_RSP_START_ADDR 0xc4008
/* [RW 16] The maximum value of the competion counter #0 */
@@ -4427,6 +4622,10 @@
/* [RC 1] Set at message length mismatch (relative to last indication) at
the dorq interface. */
#define XCM_REG_DORQ_LENGTH_MIS 0x20230
+/* [RW 3] The weight of the input dorq in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_DORQ_WEIGHT 0x200cc
/* [RW 8] The Event ID in case the ErrorFlg input message bit is set. */
#define XCM_REG_ERR_EVNT_ID 0x200b0
/* [RW 28] The CM erroneous header for QM and Timers formatting. */
@@ -4465,6 +4664,10 @@
/* [RC 1] Set at message length mismatch (relative to last indication) at
the nig0 interface. */
#define XCM_REG_NIG0_LENGTH_MIS 0x20238
+/* [RW 3] The weight of the input nig0 in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_NIG0_WEIGHT 0x200d4
/* [RW 1] Input nig1 Interface enable. If 0 - the valid input is
disregarded; acknowledge output is deasserted; all other signals are
treated as usual; if 1 - normal activity. */
@@ -4523,6 +4726,10 @@
writes the initial credit value; read returns the current value of the
credit counter. Must be initialized to 4 at start-up. */
#define XCM_REG_TM_INIT_CRD 0x2041c
+/* [RW 3] The weight of the Timers input in the WRR mechanism. 0 stands for
+ weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_TM_WEIGHT 0x200ec
/* [RW 28] The CM header for Timers expiration command. */
#define XCM_REG_TM_XCM_HDR 0x200a8
/* [RW 1] Timers - CM Interface enable. If 0 - the valid input is
@@ -4608,6 +4815,10 @@
stands for weight 8 (the most prioritised); 1 stands for weight 1(least
prioritised); 2 stands for weight 2; tc. */
#define XCM_REG_XQM_P_WEIGHT 0x200e4
+/* [RW 3] The weight of the QM (secondary) input in the WRR mechanism. 0
+ stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+ prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_XQM_S_WEIGHT 0x200e8
/* [RW 28] The CM header value for QM request (primary). */
#define XCM_REG_XQM_XCM_HDR_P 0x200a0
/* [RW 28] The CM header value for QM request (secondary). */
@@ -4665,6 +4876,8 @@
#define XSDM_REG_AGG_INT_EVENT_10 0x166060
#define XSDM_REG_AGG_INT_EVENT_11 0x166064
#define XSDM_REG_AGG_INT_EVENT_12 0x166068
+#define XSDM_REG_AGG_INT_EVENT_13 0x16606c
+#define XSDM_REG_AGG_INT_EVENT_14 0x166070
#define XSDM_REG_AGG_INT_EVENT_2 0x166040
#define XSDM_REG_AGG_INT_EVENT_20 0x166088
#define XSDM_REG_AGG_INT_EVENT_21 0x16608c
@@ -4964,9 +5177,11 @@
#define EMAC_RX_MODE_FLOW_EN (1L<<2)
#define EMAC_RX_MODE_KEEP_VLAN_TAG (1L<<10)
#define EMAC_RX_MODE_PROMISCUOUS (1L<<8)
+#define EMAC_RX_MODE_RESET (1L<<0)
#define EMAC_RX_MTU_SIZE_JUMBO_ENA (1L<<31)
#define EMAC_TX_MODE_EXT_PAUSE_EN (1L<<3)
#define EMAC_TX_MODE_FLOW_EN (1L<<4)
+#define EMAC_TX_MODE_RESET (1L<<0)
#define MISC_REGISTERS_GPIO_0 0
#define MISC_REGISTERS_GPIO_1 1
#define MISC_REGISTERS_GPIO_2 2
@@ -4976,6 +5191,10 @@
#define MISC_REGISTERS_GPIO_FLOAT_POS 24
#define MISC_REGISTERS_GPIO_HIGH 1
#define MISC_REGISTERS_GPIO_INPUT_HI_Z 2
+#define MISC_REGISTERS_GPIO_INT_CLR_POS 24
+#define MISC_REGISTERS_GPIO_INT_OUTPUT_CLR 0
+#define MISC_REGISTERS_GPIO_INT_OUTPUT_SET 1
+#define MISC_REGISTERS_GPIO_INT_SET_POS 16
#define MISC_REGISTERS_GPIO_LOW 0
#define MISC_REGISTERS_GPIO_OUTPUT_HIGH 1
#define MISC_REGISTERS_GPIO_OUTPUT_LOW 0
@@ -5015,11 +5234,12 @@
#define MISC_REGISTERS_SPIO_OUTPUT_LOW 0
#define MISC_REGISTERS_SPIO_SET_POS 8
#define HW_LOCK_MAX_RESOURCE_VALUE 31
-#define HW_LOCK_RESOURCE_8072_MDIO 0
#define HW_LOCK_RESOURCE_GPIO 1
+#define HW_LOCK_RESOURCE_MDIO 0
#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3
#define HW_LOCK_RESOURCE_SPIO 2
#define HW_LOCK_RESOURCE_UNDI 5
+#define PRS_FLAG_OVERETH_IPV4 1
#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18)
#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31)
#define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9)
@@ -5034,6 +5254,8 @@
#define AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT (1<<11)
#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT (1<<13)
#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR (1<<12)
+#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 (1<<5)
+#define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 (1<<9)
#define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR (1<<12)
#define AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT (1<<15)
#define AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR (1<<14)
@@ -5188,7 +5410,7 @@
#define PCICFG_COMMAND_INT_DISABLE (1<<10)
#define PCICFG_COMMAND_RESERVED (0x1f<<11)
#define PCICFG_STATUS_OFFSET 0x06
-#define PCICFG_REVESION_ID 0x08
+#define PCICFG_REVESION_ID_OFFSET 0x08
#define PCICFG_CACHE_LINE_SIZE 0x0c
#define PCICFG_LATENCY_TIMER 0x0d
#define PCICFG_BAR_1_LOW 0x10
@@ -5216,9 +5438,28 @@
#define PCICFG_PM_CSR_STATE (0x3<<0)
#define PCICFG_PM_CSR_PME_ENABLE (1<<8)
#define PCICFG_PM_CSR_PME_STATUS (1<<15)
+#define PCICFG_MSI_CAP_ID_OFFSET 0x58
+#define PCICFG_MSI_CONTROL_ENABLE (0x1<<16)
+#define PCICFG_MSI_CONTROL_MCAP (0x7<<17)
+#define PCICFG_MSI_CONTROL_MENA (0x7<<20)
+#define PCICFG_MSI_CONTROL_64_BIT_ADDR_CAP (0x1<<23)
+#define PCICFG_MSI_CONTROL_MSI_PVMASK_CAPABLE (0x1<<24)
#define PCICFG_GRC_ADDRESS 0x78
#define PCICFG_GRC_DATA 0x80
+#define PCICFG_MSIX_CAP_ID_OFFSET 0xa0
+#define PCICFG_MSIX_CONTROL_TABLE_SIZE (0x7ff<<16)
+#define PCICFG_MSIX_CONTROL_RESERVED (0x7<<27)
+#define PCICFG_MSIX_CONTROL_FUNC_MASK (0x1<<30)
+#define PCICFG_MSIX_CONTROL_MSIX_ENABLE (0x1<<31)
+
#define PCICFG_DEVICE_CONTROL 0xb4
+#define PCICFG_DEVICE_STATUS 0xb6
+#define PCICFG_DEVICE_STATUS_CORR_ERR_DET (1<<0)
+#define PCICFG_DEVICE_STATUS_NON_FATAL_ERR_DET (1<<1)
+#define PCICFG_DEVICE_STATUS_FATAL_ERR_DET (1<<2)
+#define PCICFG_DEVICE_STATUS_UNSUP_REQ_DET (1<<3)
+#define PCICFG_DEVICE_STATUS_AUX_PWR_DET (1<<4)
+#define PCICFG_DEVICE_STATUS_NO_PEND (1<<5)
#define PCICFG_LINK_CONTROL 0xbc
@@ -5363,6 +5604,42 @@
#define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT 1
#define MDIO_TX0_TX_DRIVER_ICBUF1T 1
+#define MDIO_REG_BANK_TX1 0x8070
+#define MDIO_TX1_TX_DRIVER 0x17
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK 0xf000
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT 12
+#define MDIO_TX0_TX_DRIVER_IDRIVER_MASK 0x0f00
+#define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT 8
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK 0x00f0
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT 4
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK 0x000e
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT 1
+#define MDIO_TX0_TX_DRIVER_ICBUF1T 1
+
+#define MDIO_REG_BANK_TX2 0x8080
+#define MDIO_TX2_TX_DRIVER 0x17
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK 0xf000
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT 12
+#define MDIO_TX0_TX_DRIVER_IDRIVER_MASK 0x0f00
+#define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT 8
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK 0x00f0
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT 4
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK 0x000e
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT 1
+#define MDIO_TX0_TX_DRIVER_ICBUF1T 1
+
+#define MDIO_REG_BANK_TX3 0x8090
+#define MDIO_TX3_TX_DRIVER 0x17
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK 0xf000
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT 12
+#define MDIO_TX0_TX_DRIVER_IDRIVER_MASK 0x0f00
+#define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT 8
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK 0x00f0
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT 4
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK 0x000e
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT 1
+#define MDIO_TX0_TX_DRIVER_ICBUF1T 1
+
#define MDIO_REG_BANK_XGXS_BLOCK0 0x8000
#define MDIO_BLOCK0_XGXS_CONTROL 0x10
@@ -5566,9 +5843,30 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_PMA_REG_ROM_VER2 0xca1a
#define MDIO_PMA_REG_EDC_FFE_MAIN 0xca1b
#define MDIO_PMA_REG_PLL_BANDWIDTH 0xca1d
+#define MDIO_PMA_REG_GEN_CTRL2 0xca1e
+#define MDIO_PMA_REG_MISC_CTRL0 0xca23
+#define MDIO_PMA_REG_LRM_MODE 0xca3f
#define MDIO_PMA_REG_CDR_BANDWIDTH 0xca46
#define MDIO_PMA_REG_MISC_CTRL1 0xca85
+#define MDIO_PMA_REG_8726_TWO_WIRE_CTRL 0x8000
+#define MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK 0x000c
+#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE 0x0000
+#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE 0x0004
+#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IN_PROGRESS 0x0008
+#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_FAILED 0x000c
+#define MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT 0x8002
+#define MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR 0x8003
+#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF 0xc820
+#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK 0xff
+#define MDIO_PMA_REG_8726_TX_CTRL1 0xca01
+#define MDIO_PMA_REG_8726_TX_CTRL2 0xca05
+
+
+#define MDIO_PMA_REG_8073_CHIP_REV 0xc801
+#define MDIO_PMA_REG_8073_SPEED_LINK_STATUS 0xc820
+#define MDIO_PMA_REG_8073_XAUI_WA 0xc841
+
#define MDIO_PMA_REG_7101_RESET 0xc000
#define MDIO_PMA_REG_7107_LED_CNTL 0xc007
#define MDIO_PMA_REG_7101_VER1 0xc026
@@ -5598,6 +5896,12 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_XS_PLL_SEQUENCER 0x8000
#define MDIO_XS_SFX7101_XGXS_TEST1 0xc00a
+#define MDIO_XS_8706_REG_BANK_RX0 0x80bc
+#define MDIO_XS_8706_REG_BANK_RX1 0x80cc
+#define MDIO_XS_8706_REG_BANK_RX2 0x80dc
+#define MDIO_XS_8706_REG_BANK_RX3 0x80ec
+#define MDIO_XS_8706_REG_BANK_RXA 0x80fc
+
#define MDIO_AN_DEVAD 0x7
/*ieee*/
#define MDIO_AN_REG_CTRL 0x0000
@@ -5619,6 +5923,8 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_AN_REG_CL37_FC_LD 0xffe4
#define MDIO_AN_REG_CL37_FC_LP 0xffe5
+#define MDIO_AN_REG_8073_2_5G 0x8329
+
#define IGU_FUNC_BASE 0x0400
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index 8a83eb283c21..a306230381c8 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -29,7 +29,7 @@
// General definitions
#define BOND_ETH_P_LACPDU 0x8809
-#define PKT_TYPE_LACPDU __constant_htons(BOND_ETH_P_LACPDU)
+#define PKT_TYPE_LACPDU cpu_to_be16(BOND_ETH_P_LACPDU)
#define AD_TIMER_INTERVAL 100 /*msec*/
#define MULTICAST_LACPDU_ADDR {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02}
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 27fb7f5c21cf..8dc6fbb9a41e 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -822,7 +822,7 @@ static int rlb_initialize(struct bonding *bond)
_unlock_rx_hashtbl(bond);
/*initialize packet type*/
- pk_type->type = __constant_htons(ETH_P_ARP);
+ pk_type->type = cpu_to_be16(ETH_P_ARP);
pk_type->dev = NULL;
pk_type->func = rlb_arp_recv;
@@ -892,7 +892,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
memset(&pkt, 0, size);
memcpy(pkt.mac_dst, mac_addr, ETH_ALEN);
memcpy(pkt.mac_src, mac_addr, ETH_ALEN);
- pkt.type = __constant_htons(ETH_P_LOOP);
+ pkt.type = cpu_to_be16(ETH_P_LOOP);
for (i = 0; i < MAX_LP_BURST; i++) {
struct sk_buff *skb;
@@ -1628,6 +1628,10 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char
* no other locks may be held.
*/
void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave)
+ __releases(&bond->curr_slave_lock)
+ __releases(&bond->lock)
+ __acquires(&bond->lock)
+ __acquires(&bond->curr_slave_lock)
{
struct slave *swap_slave;
int i;
@@ -1704,6 +1708,10 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
* Called with RTNL
*/
int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
+ __releases(&bond->curr_slave_lock)
+ __releases(&bond->lock)
+ __acquires(&bond->lock)
+ __acquires(&bond->curr_slave_lock)
{
struct bonding *bond = netdev_priv(bond_dev);
struct sockaddr *sa = addr;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index e0578fe8c0db..99610f358c40 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1002,6 +1002,10 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct
static void bond_do_fail_over_mac(struct bonding *bond,
struct slave *new_active,
struct slave *old_active)
+ __releases(&bond->curr_slave_lock)
+ __releases(&bond->lock)
+ __acquires(&bond->lock)
+ __acquires(&bond->curr_slave_lock)
{
u8 tmp_mac[ETH_ALEN];
struct sockaddr saddr;
@@ -1710,6 +1714,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
case BOND_MODE_ALB:
new_slave->state = BOND_STATE_ACTIVE;
bond_set_slave_inactive_flags(new_slave);
+ bond_select_active_slave(bond);
break;
default:
pr_debug("This slave is always active in trunk mode\n");
@@ -3193,6 +3198,8 @@ out:
#ifdef CONFIG_PROC_FS
static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(&dev_base_lock)
+ __acquires(&bond->lock)
{
struct bonding *bond = seq->private;
loff_t off = 0;
@@ -3232,6 +3239,8 @@ static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void bond_info_seq_stop(struct seq_file *seq, void *v)
+ __releases(&bond->lock)
+ __releases(&dev_base_lock)
{
struct bonding *bond = seq->private;
@@ -3369,7 +3378,7 @@ static int bond_info_seq_show(struct seq_file *seq, void *v)
return 0;
}
-static struct seq_operations bond_info_seq_ops = {
+static const struct seq_operations bond_info_seq_ops = {
.start = bond_info_seq_start,
.next = bond_info_seq_next,
.stop = bond_info_seq_stop,
@@ -3435,25 +3444,12 @@ static void bond_remove_proc_entry(struct bonding *bond)
*/
static void bond_create_proc_dir(void)
{
- int len = strlen(DRV_NAME);
-
- for (bond_proc_dir = init_net.proc_net->subdir; bond_proc_dir;
- bond_proc_dir = bond_proc_dir->next) {
- if ((bond_proc_dir->namelen == len) &&
- !memcmp(bond_proc_dir->name, DRV_NAME, len)) {
- break;
- }
- }
-
if (!bond_proc_dir) {
bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net);
- if (bond_proc_dir) {
- bond_proc_dir->owner = THIS_MODULE;
- } else {
+ if (!bond_proc_dir)
printk(KERN_WARNING DRV_NAME
": Warning: cannot create /proc/net/%s\n",
DRV_NAME);
- }
}
}
@@ -3462,25 +3458,7 @@ static void bond_create_proc_dir(void)
*/
static void bond_destroy_proc_dir(void)
{
- struct proc_dir_entry *de;
-
- if (!bond_proc_dir) {
- return;
- }
-
- /* verify that the /proc dir is empty */
- for (de = bond_proc_dir->subdir; de; de = de->next) {
- /* ignore . and .. */
- if (*(de->name) != '.') {
- break;
- }
- }
-
- if (de) {
- if (bond_proc_dir->owner == THIS_MODULE) {
- bond_proc_dir->owner = NULL;
- }
- } else {
+ if (bond_proc_dir) {
remove_proc_entry(DRV_NAME, init_net.proc_net);
bond_proc_dir = NULL;
}
@@ -3537,11 +3515,26 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
}
break;
case NETDEV_CHANGE:
- /*
- * TODO: is this what we get if somebody
- * sets up a hierarchical bond, then rmmod's
- * one of the slave bonding devices?
- */
+ if (bond->params.mode == BOND_MODE_8023AD || bond_is_lb(bond)) {
+ struct slave *slave;
+
+ slave = bond_get_slave_by_dev(bond, slave_dev);
+ if (slave) {
+ u16 old_speed = slave->speed;
+ u16 old_duplex = slave->duplex;
+
+ bond_update_speed_duplex(slave);
+
+ if (bond_is_lb(bond))
+ break;
+
+ if (old_speed != slave->speed)
+ bond_3ad_adapter_speed_changed(slave);
+ if (old_duplex != slave->duplex)
+ bond_3ad_adapter_duplex_changed(slave);
+ }
+ }
+
break;
case NETDEV_DOWN:
/*
@@ -4724,7 +4717,7 @@ static void bond_free_all(void)
*/
int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
{
- int mode = -1, i, rv;
+ int modeint = -1, i, rv;
char *p, modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };
for (p = (char *)buf; *p; p++)
@@ -4734,13 +4727,13 @@ int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
if (*p)
rv = sscanf(buf, "%20s", modestr);
else
- rv = sscanf(buf, "%d", &mode);
+ rv = sscanf(buf, "%d", &modeint);
if (!rv)
return -1;
for (i = 0; tbl[i].modename; i++) {
- if (mode == tbl[i].mode)
+ if (modeint == tbl[i].mode)
return tbl[i].mode;
if (strcmp(modestr, tbl[i].modename) == 0)
return tbl[i].mode;
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index bbbc3bb08aa5..0effefa1b882 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -2506,7 +2506,7 @@ static irqreturn_t cas_interruptN(int irq, void *dev_id)
if (status & INTR_RX_DONE_ALT) { /* handle rx separately */
#ifdef USE_NAPI
cas_mask_intr(cp);
- netif_rx_schedule(&cp->napi);
+ napi_schedule(&cp->napi);
#else
cas_rx_ringN(cp, ring, 0);
#endif
@@ -2557,7 +2557,7 @@ static irqreturn_t cas_interrupt1(int irq, void *dev_id)
if (status & INTR_RX_DONE_ALT) { /* handle rx separately */
#ifdef USE_NAPI
cas_mask_intr(cp);
- netif_rx_schedule(&cp->napi);
+ napi_schedule(&cp->napi);
#else
cas_rx_ringN(cp, 1, 0);
#endif
@@ -2613,7 +2613,7 @@ static irqreturn_t cas_interrupt(int irq, void *dev_id)
if (status & INTR_RX_DONE) {
#ifdef USE_NAPI
cas_mask_intr(cp);
- netif_rx_schedule(&cp->napi);
+ napi_schedule(&cp->napi);
#else
cas_rx_ringN(cp, 0, 0);
#endif
@@ -2691,7 +2691,7 @@ rx_comp:
#endif
spin_unlock_irqrestore(&cp->lock, flags);
if (enable_intr) {
- netif_rx_complete(napi);
+ napi_complete(napi);
cas_unmask_intr(cp);
}
return credits;
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index d984b7995763..58f6fc055f6a 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -1612,7 +1612,7 @@ int t1_poll(struct napi_struct *napi, int budget)
int work_done = process_responses(adapter, budget);
if (likely(work_done < budget)) {
- netif_rx_complete(napi);
+ napi_complete(napi);
writel(adapter->sge->respQ.cidx,
adapter->regs + A_SG_SLEEPING);
}
@@ -1630,7 +1630,7 @@ irqreturn_t t1_interrupt(int irq, void *data)
if (napi_schedule_prep(&adapter->napi)) {
if (process_pure_responses(adapter))
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
else {
/* no data, no NAPI needed */
writel(sge->respQ.cidx, adapter->regs + A_SG_SLEEPING);
@@ -1967,8 +1967,7 @@ void t1_sge_stop(struct sge *sge)
tx_sched_stop(sge);
for (i = 0; i < MAX_NPORTS; i++)
- if (sge->espibug_skb[i])
- kfree_skb(sge->espibug_skb[i]);
+ kfree_skb(sge->espibug_skb[i]);
}
/*
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index f66548751c38..3f476c7c0736 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -428,7 +428,7 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
printk(KERN_WARNING "%s: rx: polling, but no queue\n",
priv->dev->name);
spin_unlock(&priv->rx_lock);
- netif_rx_complete(napi);
+ napi_complete(napi);
return 0;
}
@@ -514,7 +514,7 @@ static int cpmac_poll(struct napi_struct *napi, int budget)
if (processed == 0) {
/* we ran out of packets to read,
* revert to interrupt-driven mode */
- netif_rx_complete(napi);
+ napi_complete(napi);
cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1);
return 0;
}
@@ -536,7 +536,7 @@ fatal_error:
}
spin_unlock(&priv->rx_lock);
- netif_rx_complete(napi);
+ napi_complete(napi);
netif_tx_stop_all_queues(priv->dev);
napi_disable(&priv->napi);
@@ -802,9 +802,9 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
if (status & MAC_INT_RX) {
queue = (status >> 8) & 7;
- if (netif_rx_schedule_prep(&priv->napi)) {
+ if (napi_schedule_prep(&priv->napi)) {
cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 1 << queue);
- __netif_rx_schedule(&priv->napi);
+ __napi_schedule(&priv->napi);
}
}
@@ -1161,7 +1161,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
priv->msg_enable = netif_msg_init(debug_level, 0xff);
memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
- priv->phy = phy_connect(dev, cpmac_mii->phy_map[phy_id]->dev.bus_id,
+ priv->phy = phy_connect(dev, dev_name(&cpmac_mii->phy_map[phy_id]->dev),
&cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(priv->phy)) {
if (netif_msg_drv(priv))
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index ff6497658a45..7433b88eed7e 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -501,6 +501,21 @@ static void net_poll_controller(struct net_device *dev)
}
#endif
+static const struct net_device_ops net_ops = {
+ .ndo_open = net_open,
+ .ndo_stop = net_close,
+ .ndo_tx_timeout = net_timeout,
+ .ndo_start_xmit = net_send_packet,
+ .ndo_get_stats = net_get_stats,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_set_mac_address = set_mac_address,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = net_poll_controller,
+#endif
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/* This is the real probe routine. Linux has a history of friendly device
probes on the ISA bus. A good device probes avoids doing writes, and
verifies that the correct device exists and functions.
@@ -843,17 +858,8 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
/* print the ethernet address. */
printk(", MAC %pM", dev->dev_addr);
- dev->open = net_open;
- dev->stop = net_close;
- dev->tx_timeout = net_timeout;
- dev->watchdog_timeo = HZ;
- dev->hard_start_xmit = net_send_packet;
- dev->get_stats = net_get_stats;
- dev->set_multicast_list = set_multicast_list;
- dev->set_mac_address = set_mac_address;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = net_poll_controller;
-#endif
+ dev->netdev_ops = &net_ops;
+ dev->watchdog_timeo = HZ;
printk("\n");
if (net_debug)
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index a89d8cc51205..714df2b675e6 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -42,7 +42,6 @@
#include <linux/cache.h>
#include <linux/mutex.h>
#include <linux/bitops.h>
-#include <linux/inet_lro.h>
#include "t3cdev.h"
#include <asm/io.h>
@@ -69,6 +68,8 @@ struct port_info {
struct net_device_stats netstats;
int activity;
__be32 iscsi_ipv4addr;
+
+ int link_fault; /* link fault was detected */
};
enum { /* adapter flags */
@@ -84,6 +85,8 @@ struct fl_pg_chunk {
struct page *page;
void *va;
unsigned int offset;
+ u64 *p_cnt;
+ DECLARE_PCI_UNMAP_ADDR(mapping);
};
struct rx_desc;
@@ -92,6 +95,7 @@ struct rx_sw_desc;
struct sge_fl { /* SGE per free-buffer list state */
unsigned int buf_size; /* size of each Rx buffer */
unsigned int credits; /* # of available Rx buffers */
+ unsigned int pend_cred; /* new buffers since last FL DB ring */
unsigned int size; /* capacity of free list */
unsigned int cidx; /* consumer index */
unsigned int pidx; /* producer index */
@@ -99,6 +103,7 @@ struct sge_fl { /* SGE per free-buffer list state */
struct fl_pg_chunk pg_chunk;/* page chunk cache */
unsigned int use_pages; /* whether FL uses pages or sk_buffs */
unsigned int order; /* order of page allocations */
+ unsigned int alloc_size; /* size of allocated buffer */
struct rx_desc *desc; /* address of HW Rx descriptor ring */
struct rx_sw_desc *sdesc; /* address of SW Rx descriptor ring */
dma_addr_t phys_addr; /* physical address of HW ring start */
@@ -178,15 +183,11 @@ enum { /* per port SGE statistics */
SGE_PSTAT_TX_CSUM, /* # of TX checksum offloads */
SGE_PSTAT_VLANEX, /* # of VLAN tag extractions */
SGE_PSTAT_VLANINS, /* # of VLAN tag insertions */
- SGE_PSTAT_LRO_AGGR, /* # of page chunks added to LRO sessions */
- SGE_PSTAT_LRO_FLUSHED, /* # of flushed LRO sessions */
- SGE_PSTAT_LRO_NO_DESC, /* # of overflown LRO sessions */
SGE_PSTAT_MAX /* must be last */
};
-#define T3_MAX_LRO_SES 8
-#define T3_MAX_LRO_MAX_PKTS 64
+struct napi_gro_fraginfo;
struct sge_qset { /* an SGE queue set */
struct adapter *adap;
@@ -194,17 +195,14 @@ struct sge_qset { /* an SGE queue set */
struct sge_rspq rspq;
struct sge_fl fl[SGE_RXQ_PER_SET];
struct sge_txq txq[SGE_TXQ_PER_SET];
- struct net_lro_mgr lro_mgr;
- struct net_lro_desc lro_desc[T3_MAX_LRO_SES];
- struct skb_frag_struct *lro_frag_tbl;
- int lro_nfrags;
+ struct napi_gro_fraginfo lro_frag_tbl;
int lro_enabled;
- int lro_frag_len;
void *lro_va;
struct net_device *netdev;
struct netdev_queue *tx_q; /* associated netdev TX queue */
unsigned long txq_stopped; /* which Tx queues are stopped */
struct timer_list tx_reclaim_timer; /* reclaims TX buffers */
+ struct timer_list rx_reclaim_timer; /* reclaims RX buffers */
unsigned long port_stats[SGE_PSTAT_MAX];
} ____cacheline_aligned;
@@ -230,6 +228,7 @@ struct adapter {
unsigned int slow_intr_mask;
unsigned long irq_stats[IRQ_NUM_STATS];
+ int msix_nvectors;
struct {
unsigned short vec;
char desc[22];
@@ -247,6 +246,7 @@ struct adapter {
struct delayed_work adap_check_task;
struct work_struct ext_intr_handler_task;
struct work_struct fatal_error_handler_task;
+ struct work_struct link_fault_handler_task;
struct dentry *debugfs_root;
@@ -289,9 +289,12 @@ void t3_os_ext_intr_handler(struct adapter *adapter);
void t3_os_link_changed(struct adapter *adapter, int port_id, int link_status,
int speed, int duplex, int fc);
void t3_os_phymod_changed(struct adapter *adap, int port_id);
+void t3_os_link_fault(struct adapter *adapter, int port_id, int state);
+void t3_os_link_fault_handler(struct adapter *adapter, int port_id);
void t3_sge_start(struct adapter *adap);
void t3_sge_stop(struct adapter *adap);
+void t3_start_sge_timers(struct adapter *adap);
void t3_stop_sge_timers(struct adapter *adap);
void t3_free_sge_resources(struct adapter *adap);
void t3_sge_err_intr_handler(struct adapter *adapter);
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
index 5c3c05da4d96..e1b22490ff59 100644
--- a/drivers/net/cxgb3/ael1002.c
+++ b/drivers/net/cxgb3/ael1002.c
@@ -1005,7 +1005,8 @@ static int ael2005_reset(struct cphy *phy, int wait)
{ 0, 0, 0, 0 }
};
- int err, lasi_ctrl;
+ int err;
+ unsigned int lasi_ctrl;
err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
if (err)
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index db4f4f575b6a..e508dc32f3ec 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -191,7 +191,8 @@ struct mdio_ops {
};
struct adapter_info {
- unsigned char nports; /* # of ports */
+ unsigned char nports0; /* # of ports on channel 0 */
+ unsigned char nports1; /* # of ports on channel 1 */
unsigned char phy_base_addr; /* MDIO PHY base address */
unsigned int gpio_out; /* GPIO output settings */
unsigned char gpio_intr[MAX_NPORTS]; /* GPIO PHY IRQ pins */
@@ -280,6 +281,7 @@ struct mac_stats {
unsigned long num_toggled; /* # times toggled TxEn due to stuck TX */
unsigned long num_resets; /* # times reset due to stuck TX */
+ unsigned long link_faults; /* # detected link faults */
};
struct tp_mib_stats {
@@ -421,6 +423,7 @@ struct adapter_params {
unsigned short b_wnd[NCCTRL_WIN];
unsigned int nports; /* # of ethernet ports */
+ unsigned int chan_map; /* bitmap of in-use Tx channels */
unsigned int stats_update_period; /* MAC stats accumulation period */
unsigned int linkpoll_period; /* link poll period in 0.1s */
unsigned int rev; /* chip revision */
@@ -701,6 +704,8 @@ int t3_phy_lasi_intr_handler(struct cphy *phy);
void t3_intr_enable(struct adapter *adapter);
void t3_intr_disable(struct adapter *adapter);
void t3_intr_clear(struct adapter *adapter);
+void t3_xgm_intr_enable(struct adapter *adapter, int idx);
+void t3_xgm_intr_disable(struct adapter *adapter, int idx);
void t3_port_intr_enable(struct adapter *adapter, int idx);
void t3_port_intr_disable(struct adapter *adapter, int idx);
void t3_port_intr_clear(struct adapter *adapter, int idx);
@@ -708,6 +713,7 @@ int t3_slow_intr_handler(struct adapter *adapter);
int t3_phy_intr_handler(struct adapter *adapter);
void t3_link_changed(struct adapter *adapter, int port_id);
+void t3_link_fault(struct adapter *adapter, int port_id);
int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc);
const struct adapter_info *t3_get_adapter_info(unsigned int board_id);
int t3_seeprom_read(struct adapter *adapter, u32 addr, __le32 *data);
@@ -744,6 +750,8 @@ int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n,
int t3_mac_reset(struct cmac *mac);
void t3b_pcs_reset(struct cmac *mac);
+void t3_mac_disable_exact_filters(struct cmac *mac);
+void t3_mac_enable_exact_filters(struct cmac *mac);
int t3_mac_enable(struct cmac *mac, int which);
int t3_mac_disable(struct cmac *mac, int which);
int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu);
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index bab8a934c33d..2c2aaa741450 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -170,6 +170,40 @@ static void link_report(struct net_device *dev)
}
}
+void t3_os_link_fault(struct adapter *adap, int port_id, int state)
+{
+ struct net_device *dev = adap->port[port_id];
+ struct port_info *pi = netdev_priv(dev);
+
+ if (state == netif_carrier_ok(dev))
+ return;
+
+ if (state) {
+ struct cmac *mac = &pi->mac;
+
+ netif_carrier_on(dev);
+
+ /* Clear local faults */
+ t3_xgm_intr_disable(adap, pi->port_id);
+ t3_read_reg(adap, A_XGM_INT_STATUS +
+ pi->mac.offset);
+ t3_write_reg(adap,
+ A_XGM_INT_CAUSE + pi->mac.offset,
+ F_XGM_INT);
+
+ t3_set_reg_field(adap,
+ A_XGM_INT_ENABLE +
+ pi->mac.offset,
+ F_XGM_INT, F_XGM_INT);
+ t3_xgm_intr_enable(adap, pi->port_id);
+
+ t3_mac_enable(mac, MAC_DIRECTION_TX);
+ } else
+ netif_carrier_off(dev);
+
+ link_report(dev);
+}
+
/**
* t3_os_link_changed - handle link status changes
* @adapter: the adapter associated with the link change
@@ -197,10 +231,34 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat,
if (link_stat != netif_carrier_ok(dev)) {
if (link_stat) {
t3_mac_enable(mac, MAC_DIRECTION_RX);
+
+ /* Clear local faults */
+ t3_xgm_intr_disable(adapter, pi->port_id);
+ t3_read_reg(adapter, A_XGM_INT_STATUS +
+ pi->mac.offset);
+ t3_write_reg(adapter,
+ A_XGM_INT_CAUSE + pi->mac.offset,
+ F_XGM_INT);
+
+ t3_set_reg_field(adapter,
+ A_XGM_INT_ENABLE + pi->mac.offset,
+ F_XGM_INT, F_XGM_INT);
+ t3_xgm_intr_enable(adapter, pi->port_id);
+
netif_carrier_on(dev);
} else {
netif_carrier_off(dev);
- pi->phy.ops->power_down(&pi->phy, 1);
+
+ t3_xgm_intr_disable(adapter, pi->port_id);
+ t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
+ t3_set_reg_field(adapter,
+ A_XGM_INT_ENABLE + pi->mac.offset,
+ F_XGM_INT, 0);
+
+ if (is_10G(adapter))
+ pi->phy.ops->power_down(&pi->phy, 1);
+
+ t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
t3_mac_disable(mac, MAC_DIRECTION_RX);
t3_link_start(&pi->phy, mac, &pi->link_config);
}
@@ -339,7 +397,7 @@ static void free_irq_resources(struct adapter *adapter)
free_irq(adapter->msix_info[0].vec, adapter);
for_each_port(adapter, i)
- n += adap2pinfo(adapter, i)->nqsets;
+ n += adap2pinfo(adapter, i)->nqsets;
for (i = 0; i < n; ++i)
free_irq(adapter->msix_info[i + 1].vec,
@@ -509,19 +567,9 @@ static void set_qset_lro(struct net_device *dev, int qset_idx, int val)
{
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
- int i, lro_on = 1;
adapter->params.sge.qset[qset_idx].lro = !!val;
adapter->sge.qs[qset_idx].lro_enabled = !!val;
-
- /* let ethtool report LRO on only if all queues are LRO enabled */
- for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; ++i)
- lro_on &= adapter->params.sge.qset[i].lro;
-
- if (lro_on)
- dev->features |= NETIF_F_LRO;
- else
- dev->features &= ~NETIF_F_LRO;
}
/**
@@ -554,7 +602,6 @@ static int setup_sge_qsets(struct adapter *adap)
&adap->params.sge.qset[qset_idx], ntxq, dev,
netdev_get_tx_queue(dev, j));
if (err) {
- t3_stop_sge_timers(adap);
t3_free_sge_resources(adap);
return err;
}
@@ -998,6 +1045,8 @@ static int cxgb_up(struct adapter *adap)
setup_rss(adap);
if (!(adap->flags & NAPI_INIT))
init_napi(adap);
+
+ t3_start_sge_timers(adap);
adap->flags |= FULL_INIT_DONE;
}
@@ -1183,6 +1232,10 @@ static int cxgb_close(struct net_device *dev)
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
+ /* Stop link fault interrupts */
+ t3_xgm_intr_disable(adapter, pi->port_id);
+ t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
+
t3_port_intr_disable(adapter, pi->port_id);
netif_tx_stop_all_queues(dev);
pi->phy.ops->power_down(&pi->phy, 1);
@@ -1309,6 +1362,7 @@ static char stats_strings[][ETH_GSTRING_LEN] = {
"CheckTXEnToggled ",
"CheckResets ",
+ "LinkFaults ",
};
static int get_sset_count(struct net_device *dev, int sset)
@@ -1434,13 +1488,15 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_VLANINS);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM);
*data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD);
- *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_AGGR);
- *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_FLUSHED);
- *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_LRO_NO_DESC);
+ *data++ = 0;
+ *data++ = 0;
+ *data++ = 0;
*data++ = s->rx_cong_drops;
*data++ = s->num_toggled;
*data++ = s->num_resets;
+
+ *data++ = s->link_faults;
}
static inline void reg_block_dump(struct adapter *ap, void *buf,
@@ -1576,7 +1632,6 @@ static int speed_duplex_to_caps(int speed, int duplex)
static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- int cap;
struct port_info *p = netdev_priv(dev);
struct link_config *lc = &p->link_config;
@@ -1586,7 +1641,7 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
* being requested.
*/
if (cmd->autoneg == AUTONEG_DISABLE) {
- cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
+ int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
if (lc->supported & cap)
return 0;
}
@@ -1827,28 +1882,6 @@ static void get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
memset(&wol->sopass, 0, sizeof(wol->sopass));
}
-static int cxgb3_set_flags(struct net_device *dev, u32 data)
-{
- struct port_info *pi = netdev_priv(dev);
- int i;
-
- if (data & ETH_FLAG_LRO) {
- if (!(pi->rx_offload & T3_RX_CSUM))
- return -EINVAL;
-
- pi->rx_offload |= T3_LRO;
- for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++)
- set_qset_lro(dev, i, 1);
-
- } else {
- pi->rx_offload &= ~T3_LRO;
- for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++)
- set_qset_lro(dev, i, 0);
- }
-
- return 0;
-}
-
static const struct ethtool_ops cxgb_ethtool_ops = {
.get_settings = get_settings,
.set_settings = set_settings,
@@ -1878,8 +1911,6 @@ static const struct ethtool_ops cxgb_ethtool_ops = {
.get_regs = get_regs,
.get_wol = get_wol,
.set_tso = ethtool_op_set_tso,
- .get_flags = ethtool_op_get_flags,
- .set_flags = cxgb3_set_flags,
};
static int in_range(int val, int lo, int hi)
@@ -2460,8 +2491,20 @@ static void check_link_status(struct adapter *adapter)
struct net_device *dev = adapter->port[i];
struct port_info *p = netdev_priv(dev);
- if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev))
+ spin_lock_irq(&adapter->work_lock);
+ if (p->link_fault) {
+ spin_unlock_irq(&adapter->work_lock);
+ continue;
+ }
+ spin_unlock_irq(&adapter->work_lock);
+
+ if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev)) {
+ t3_xgm_intr_disable(adapter, i);
+ t3_read_reg(adapter, A_XGM_INT_STATUS + p->mac.offset);
+
t3_link_changed(adapter, i);
+ t3_xgm_intr_enable(adapter, i);
+ }
}
}
@@ -2506,6 +2549,8 @@ static void t3_adap_check_task(struct work_struct *work)
struct adapter *adapter = container_of(work, struct adapter,
adap_check_task.work);
const struct adapter_params *p = &adapter->params;
+ int port;
+ unsigned int v, status, reset;
adapter->check_task_cnt++;
@@ -2524,6 +2569,54 @@ static void t3_adap_check_task(struct work_struct *work)
if (p->rev == T3_REV_B2)
check_t3b2_mac(adapter);
+ /*
+ * Scan the XGMAC's to check for various conditions which we want to
+ * monitor in a periodic polling manner rather than via an interrupt
+ * condition. This is used for conditions which would otherwise flood
+ * the system with interrupts and we only really need to know that the
+ * conditions are "happening" ... For each condition we count the
+ * detection of the condition and reset it for the next polling loop.
+ */
+ for_each_port(adapter, port) {
+ struct cmac *mac = &adap2pinfo(adapter, port)->mac;
+ u32 cause;
+
+ cause = t3_read_reg(adapter, A_XGM_INT_CAUSE + mac->offset);
+ reset = 0;
+ if (cause & F_RXFIFO_OVERFLOW) {
+ mac->stats.rx_fifo_ovfl++;
+ reset |= F_RXFIFO_OVERFLOW;
+ }
+
+ t3_write_reg(adapter, A_XGM_INT_CAUSE + mac->offset, reset);
+ }
+
+ /*
+ * We do the same as above for FL_EMPTY interrupts.
+ */
+ status = t3_read_reg(adapter, A_SG_INT_CAUSE);
+ reset = 0;
+
+ if (status & F_FLEMPTY) {
+ struct sge_qset *qs = &adapter->sge.qs[0];
+ int i = 0;
+
+ reset |= F_FLEMPTY;
+
+ v = (t3_read_reg(adapter, A_SG_RSPQ_FL_STATUS) >> S_FL0EMPTY) &
+ 0xffff;
+
+ while (v) {
+ qs->fl[i].empty += (v & 1);
+ if (i)
+ qs++;
+ i ^= 1;
+ v >>= 1;
+ }
+ }
+
+ t3_write_reg(adapter, A_SG_INT_CAUSE, reset);
+
/* Schedule the next check update if any port is active. */
spin_lock_irq(&adapter->work_lock);
if (adapter->open_device_map & PORT_MASK)
@@ -2538,9 +2631,23 @@ static void ext_intr_task(struct work_struct *work)
{
struct adapter *adapter = container_of(work, struct adapter,
ext_intr_handler_task);
+ int i;
+ /* Disable link fault interrupts */
+ for_each_port(adapter, i) {
+ struct net_device *dev = adapter->port[i];
+ struct port_info *p = netdev_priv(dev);
+
+ t3_xgm_intr_disable(adapter, i);
+ t3_read_reg(adapter, A_XGM_INT_STATUS + p->mac.offset);
+ }
+
+ /* Re-enable link fault interrupts */
t3_phy_intr_handler(adapter);
+ for_each_port(adapter, i)
+ t3_xgm_intr_enable(adapter, i);
+
/* Now reenable external interrupts */
spin_lock_irq(&adapter->work_lock);
if (adapter->slow_intr_mask) {
@@ -2573,10 +2680,42 @@ void t3_os_ext_intr_handler(struct adapter *adapter)
spin_unlock(&adapter->work_lock);
}
+static void link_fault_task(struct work_struct *work)
+{
+ struct adapter *adapter = container_of(work, struct adapter,
+ link_fault_handler_task);
+ int i;
+
+ for_each_port(adapter, i) {
+ struct net_device *netdev = adapter->port[i];
+ struct port_info *pi = netdev_priv(netdev);
+
+ if (pi->link_fault)
+ t3_link_fault(adapter, i);
+ }
+}
+
+void t3_os_link_fault_handler(struct adapter *adapter, int port_id)
+{
+ struct net_device *netdev = adapter->port[port_id];
+ struct port_info *pi = netdev_priv(netdev);
+
+ spin_lock(&adapter->work_lock);
+ pi->link_fault = 1;
+ queue_work(cxgb3_wq, &adapter->link_fault_handler_task);
+ spin_unlock(&adapter->work_lock);
+}
+
static int t3_adapter_error(struct adapter *adapter, int reset)
{
int i, ret = 0;
+ if (is_offload(adapter) &&
+ test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) {
+ cxgb3_err_notify(&adapter->tdev, OFFLOAD_STATUS_DOWN, 0);
+ offload_close(&adapter->tdev);
+ }
+
/* Stop all ports */
for_each_port(adapter, i) {
struct net_device *netdev = adapter->port[i];
@@ -2585,10 +2724,6 @@ static int t3_adapter_error(struct adapter *adapter, int reset)
cxgb_close(netdev);
}
- if (is_offload(adapter) &&
- test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
- offload_close(&adapter->tdev);
-
/* Stop SGE timers */
t3_stop_sge_timers(adapter);
@@ -2640,6 +2775,9 @@ static void t3_resume_ports(struct adapter *adapter)
}
}
}
+
+ if (is_offload(adapter) && !ofld_disable)
+ cxgb3_err_notify(&adapter->tdev, OFFLOAD_STATUS_UP, 0);
}
/*
@@ -2684,7 +2822,6 @@ void t3_fatal_err(struct adapter *adapter)
CH_ALERT(adapter, "FW status: 0x%x, 0x%x, 0x%x, 0x%x\n",
fw_status[0], fw_status[1],
fw_status[2], fw_status[3]);
-
}
/**
@@ -2734,6 +2871,9 @@ static void t3_io_resume(struct pci_dev *pdev)
{
struct adapter *adapter = pci_get_drvdata(pdev);
+ CH_ALERT(adapter, "adapter recovering, PEX ERR 0x%x\n",
+ t3_read_reg(adapter, A_PCIE_PEX_ERR));
+
t3_resume_ports(adapter);
}
@@ -2753,7 +2893,7 @@ static void set_nqsets(struct adapter *adap)
int i, j = 0;
int num_cpus = num_online_cpus();
int hwports = adap->params.nports;
- int nqsets = SGE_QSETS;
+ int nqsets = adap->msix_nvectors - 1;
if (adap->params.rev > 0 && adap->flags & USING_MSIX) {
if (hwports == 2 &&
@@ -2782,18 +2922,25 @@ static void set_nqsets(struct adapter *adap)
static int __devinit cxgb_enable_msix(struct adapter *adap)
{
struct msix_entry entries[SGE_QSETS + 1];
+ int vectors;
int i, err;
- for (i = 0; i < ARRAY_SIZE(entries); ++i)
+ vectors = ARRAY_SIZE(entries);
+ for (i = 0; i < vectors; ++i)
entries[i].entry = i;
- err = pci_enable_msix(adap->pdev, entries, ARRAY_SIZE(entries));
+ while ((err = pci_enable_msix(adap->pdev, entries, vectors)) > 0)
+ vectors = err;
+
+ if (!err && vectors < (adap->params.nports + 1))
+ err = -1;
+
if (!err) {
- for (i = 0; i < ARRAY_SIZE(entries); ++i)
+ for (i = 0; i < vectors; ++i)
adap->msix_info[i].vec = entries[i].vector;
- } else if (err > 0)
- dev_info(&adap->pdev->dev,
- "only %d MSI-X vectors left, not using MSI-X\n", err);
+ adap->msix_nvectors = vectors;
+ }
+
return err;
}
@@ -2859,7 +3006,7 @@ static int __devinit init_one(struct pci_dev *pdev,
static int version_printed;
int i, err, pci_using_dac = 0;
- unsigned long mmio_start, mmio_len;
+ resource_size_t mmio_start, mmio_len;
const struct adapter_info *ai;
struct adapter *adapter = NULL;
struct port_info *pi;
@@ -2935,10 +3082,11 @@ static int __devinit init_one(struct pci_dev *pdev,
INIT_LIST_HEAD(&adapter->adapter_list);
INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task);
+ INIT_WORK(&adapter->link_fault_handler_task, link_fault_task);
INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task);
INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task);
- for (i = 0; i < ai->nports; ++i) {
+ for (i = 0; i < ai->nports0 + ai->nports1; ++i) {
struct net_device *netdev;
netdev = alloc_etherdev_mq(sizeof(struct port_info), SGE_QSETS);
@@ -2961,7 +3109,7 @@ static int __devinit init_one(struct pci_dev *pdev,
netdev->mem_end = mmio_start + mmio_len - 1;
netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
netdev->features |= NETIF_F_LLTX;
- netdev->features |= NETIF_F_LRO;
+ netdev->features |= NETIF_F_GRO;
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
@@ -3028,7 +3176,7 @@ static int __devinit init_one(struct pci_dev *pdev,
out_free_dev:
iounmap(adapter->regs);
- for (i = ai->nports - 1; i >= 0; --i)
+ for (i = ai->nports0 + ai->nports1 - 1; i >= 0; --i)
if (adapter->port[i])
free_netdev(adapter->port[i]);
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index 2d7f69aff1d9..620d80be6aac 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -153,6 +153,18 @@ void cxgb3_remove_clients(struct t3cdev *tdev)
mutex_unlock(&cxgb3_db_lock);
}
+void cxgb3_err_notify(struct t3cdev *tdev, u32 status, u32 error)
+{
+ struct cxgb3_client *client;
+
+ mutex_lock(&cxgb3_db_lock);
+ list_for_each_entry(client, &client_list, client_list) {
+ if (client->err_handler)
+ client->err_handler(tdev, status, error);
+ }
+ mutex_unlock(&cxgb3_db_lock);
+}
+
static struct net_device *get_iff_from_mac(struct adapter *adapter,
const unsigned char *mac,
unsigned int vlan)
diff --git a/drivers/net/cxgb3/cxgb3_offload.h b/drivers/net/cxgb3/cxgb3_offload.h
index d514e5019dfc..a8e8e5fcdf84 100644
--- a/drivers/net/cxgb3/cxgb3_offload.h
+++ b/drivers/net/cxgb3/cxgb3_offload.h
@@ -64,10 +64,16 @@ void cxgb3_register_client(struct cxgb3_client *client);
void cxgb3_unregister_client(struct cxgb3_client *client);
void cxgb3_add_clients(struct t3cdev *tdev);
void cxgb3_remove_clients(struct t3cdev *tdev);
+void cxgb3_err_notify(struct t3cdev *tdev, u32 status, u32 error);
typedef int (*cxgb3_cpl_handler_func)(struct t3cdev *dev,
struct sk_buff *skb, void *ctx);
+enum {
+ OFFLOAD_STATUS_UP,
+ OFFLOAD_STATUS_DOWN
+};
+
struct cxgb3_client {
char *name;
void (*add) (struct t3cdev *);
@@ -76,6 +82,7 @@ struct cxgb3_client {
int (*redirect)(void *ctx, struct dst_entry *old,
struct dst_entry *new, struct l2t_entry *l2t);
struct list_head client_list;
+ void (*err_handler)(struct t3cdev *tdev, u32 status, u32 error);
};
/*
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index a035d5c24442..1b5327b5a965 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -170,6 +170,10 @@
#define S_RSPQ0DISABLED 8
+#define S_FL0EMPTY 16
+#define V_FL0EMPTY(x) ((x) << S_FL0EMPTY)
+#define F_FL0EMPTY V_FL0EMPTY(1U)
+
#define A_SG_EGR_RCQ_DRB_THRSH 0x54
#define S_HIRCQDRBTHRSH 16
@@ -258,6 +262,10 @@
#define V_RSPQCREDITOVERFOW(x) ((x) << S_RSPQCREDITOVERFOW)
#define F_RSPQCREDITOVERFOW V_RSPQCREDITOVERFOW(1U)
+#define S_FLEMPTY 1
+#define V_FLEMPTY(x) ((x) << S_FLEMPTY)
+#define F_FLEMPTY V_FLEMPTY(1U)
+
#define A_SG_INT_ENABLE 0x60
#define A_SG_CMDQ_CREDIT_TH 0x64
@@ -2207,6 +2215,15 @@
#define A_XGM_RX_EXACT_MATCH_LOW_8 0x854
+#define A_XGM_INT_STATUS 0x86c
+
+#define S_LINKFAULTCHANGE 9
+#define V_LINKFAULTCHANGE(x) ((x) << S_LINKFAULTCHANGE)
+#define F_LINKFAULTCHANGE V_LINKFAULTCHANGE(1U)
+
+#define A_XGM_XGM_INT_ENABLE 0x874
+#define A_XGM_XGM_INT_DISABLE 0x878
+
#define A_XGM_STAT_CTRL 0x880
#define S_CLRSTATS 2
@@ -2405,6 +2422,10 @@
#define V_XAUIPCSALIGNCHANGE(x) ((x) << S_XAUIPCSALIGNCHANGE)
#define F_XAUIPCSALIGNCHANGE V_XAUIPCSALIGNCHANGE(1U)
+#define S_XGM_INT 0
+#define V_XGM_INT(x) ((x) << S_XGM_INT)
+#define F_XGM_INT V_XGM_INT(1U)
+
#define A_XGM_INT_CAUSE 0x8d8
#define A_XGM_XAUI_ACT_CTRL 0x8dc
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index d31791f60292..26d3587f3399 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -50,6 +50,7 @@
#define SGE_RX_COPY_THRES 256
#define SGE_RX_PULL_LEN 128
+#define SGE_PG_RSVD SMP_CACHE_BYTES
/*
* Page chunk size for FL0 buffers if FL0 is to be populated with page chunks.
* It must be a divisor of PAGE_SIZE. If set to 0 FL0 will use sk_buffs
@@ -57,16 +58,25 @@
*/
#define FL0_PG_CHUNK_SIZE 2048
#define FL0_PG_ORDER 0
+#define FL0_PG_ALLOC_SIZE (PAGE_SIZE << FL0_PG_ORDER)
#define FL1_PG_CHUNK_SIZE (PAGE_SIZE > 8192 ? 16384 : 8192)
#define FL1_PG_ORDER (PAGE_SIZE > 8192 ? 0 : 1)
+#define FL1_PG_ALLOC_SIZE (PAGE_SIZE << FL1_PG_ORDER)
#define SGE_RX_DROP_THRES 16
+#define RX_RECLAIM_PERIOD (HZ/4)
/*
+ * Max number of Rx buffers we replenish at a time.
+ */
+#define MAX_RX_REFILL 16U
+/*
* Period of the Tx buffer reclaim timer. This timer does not need to run
* frequently as Tx buffers are usually reclaimed by new Tx packets.
*/
#define TX_RECLAIM_PERIOD (HZ / 4)
+#define TX_RECLAIM_TIMER_CHUNK 64U
+#define TX_RECLAIM_CHUNK 16U
/* WR size in bytes */
#define WR_LEN (WR_FLITS * 8)
@@ -304,21 +314,25 @@ static void free_tx_desc(struct adapter *adapter, struct sge_txq *q,
* reclaim_completed_tx - reclaims completed Tx descriptors
* @adapter: the adapter
* @q: the Tx queue to reclaim completed descriptors from
+ * @chunk: maximum number of descriptors to reclaim
*
* Reclaims Tx descriptors that the SGE has indicated it has processed,
* and frees the associated buffers if possible. Called with the Tx
* queue's lock held.
*/
-static inline void reclaim_completed_tx(struct adapter *adapter,
- struct sge_txq *q)
+static inline unsigned int reclaim_completed_tx(struct adapter *adapter,
+ struct sge_txq *q,
+ unsigned int chunk)
{
unsigned int reclaim = q->processed - q->cleaned;
+ reclaim = min(chunk, reclaim);
if (reclaim) {
free_tx_desc(adapter, q, reclaim);
q->cleaned += reclaim;
q->in_use -= reclaim;
}
+ return q->processed - q->cleaned;
}
/**
@@ -334,6 +348,26 @@ static inline int should_restart_tx(const struct sge_txq *q)
return q->in_use - r < (q->size >> 1);
}
+static void clear_rx_desc(struct pci_dev *pdev, const struct sge_fl *q,
+ struct rx_sw_desc *d)
+{
+ if (q->use_pages && d->pg_chunk.page) {
+ (*d->pg_chunk.p_cnt)--;
+ if (!*d->pg_chunk.p_cnt)
+ pci_unmap_page(pdev,
+ pci_unmap_addr(&d->pg_chunk, mapping),
+ q->alloc_size, PCI_DMA_FROMDEVICE);
+
+ put_page(d->pg_chunk.page);
+ d->pg_chunk.page = NULL;
+ } else {
+ pci_unmap_single(pdev, pci_unmap_addr(d, dma_addr),
+ q->buf_size, PCI_DMA_FROMDEVICE);
+ kfree_skb(d->skb);
+ d->skb = NULL;
+ }
+}
+
/**
* free_rx_bufs - free the Rx buffers on an SGE free list
* @pdev: the PCI device associated with the adapter
@@ -349,16 +383,8 @@ static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q)
while (q->credits--) {
struct rx_sw_desc *d = &q->sdesc[cidx];
- pci_unmap_single(pdev, pci_unmap_addr(d, dma_addr),
- q->buf_size, PCI_DMA_FROMDEVICE);
- if (q->use_pages) {
- if (d->pg_chunk.page)
- put_page(d->pg_chunk.page);
- d->pg_chunk.page = NULL;
- } else {
- kfree_skb(d->skb);
- d->skb = NULL;
- }
+
+ clear_rx_desc(pdev, q, d);
if (++cidx == q->size)
cidx = 0;
}
@@ -401,18 +427,39 @@ static inline int add_one_rx_buf(void *va, unsigned int len,
return 0;
}
-static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp,
+static inline int add_one_rx_chunk(dma_addr_t mapping, struct rx_desc *d,
+ unsigned int gen)
+{
+ d->addr_lo = cpu_to_be32(mapping);
+ d->addr_hi = cpu_to_be32((u64) mapping >> 32);
+ wmb();
+ d->len_gen = cpu_to_be32(V_FLD_GEN1(gen));
+ d->gen2 = cpu_to_be32(V_FLD_GEN2(gen));
+ return 0;
+}
+
+static int alloc_pg_chunk(struct adapter *adapter, struct sge_fl *q,
+ struct rx_sw_desc *sd, gfp_t gfp,
unsigned int order)
{
if (!q->pg_chunk.page) {
+ dma_addr_t mapping;
+
q->pg_chunk.page = alloc_pages(gfp, order);
if (unlikely(!q->pg_chunk.page))
return -ENOMEM;
q->pg_chunk.va = page_address(q->pg_chunk.page);
+ q->pg_chunk.p_cnt = q->pg_chunk.va + (PAGE_SIZE << order) -
+ SGE_PG_RSVD;
q->pg_chunk.offset = 0;
+ mapping = pci_map_page(adapter->pdev, q->pg_chunk.page,
+ 0, q->alloc_size, PCI_DMA_FROMDEVICE);
+ pci_unmap_addr_set(&q->pg_chunk, mapping, mapping);
}
sd->pg_chunk = q->pg_chunk;
+ prefetch(sd->pg_chunk.p_cnt);
+
q->pg_chunk.offset += q->buf_size;
if (q->pg_chunk.offset == (PAGE_SIZE << order))
q->pg_chunk.page = NULL;
@@ -420,9 +467,23 @@ static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp,
q->pg_chunk.va += q->buf_size;
get_page(q->pg_chunk.page);
}
+
+ if (sd->pg_chunk.offset == 0)
+ *sd->pg_chunk.p_cnt = 1;
+ else
+ *sd->pg_chunk.p_cnt += 1;
+
return 0;
}
+static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
+{
+ if (q->pend_cred >= q->credits / 4) {
+ q->pend_cred = 0;
+ t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
+ }
+}
+
/**
* refill_fl - refill an SGE free-buffer list
* @adapter: the adapter
@@ -436,38 +497,43 @@ static int alloc_pg_chunk(struct sge_fl *q, struct rx_sw_desc *sd, gfp_t gfp,
*/
static int refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp)
{
- void *buf_start;
struct rx_sw_desc *sd = &q->sdesc[q->pidx];
struct rx_desc *d = &q->desc[q->pidx];
unsigned int count = 0;
while (n--) {
+ dma_addr_t mapping;
int err;
if (q->use_pages) {
- if (unlikely(alloc_pg_chunk(q, sd, gfp, q->order))) {
+ if (unlikely(alloc_pg_chunk(adap, q, sd, gfp,
+ q->order))) {
nomem: q->alloc_failed++;
break;
}
- buf_start = sd->pg_chunk.va;
+ mapping = pci_unmap_addr(&sd->pg_chunk, mapping) +
+ sd->pg_chunk.offset;
+ pci_unmap_addr_set(sd, dma_addr, mapping);
+
+ add_one_rx_chunk(mapping, d, q->gen);
+ pci_dma_sync_single_for_device(adap->pdev, mapping,
+ q->buf_size - SGE_PG_RSVD,
+ PCI_DMA_FROMDEVICE);
} else {
- struct sk_buff *skb = alloc_skb(q->buf_size, gfp);
+ void *buf_start;
+ struct sk_buff *skb = alloc_skb(q->buf_size, gfp);
if (!skb)
goto nomem;
sd->skb = skb;
buf_start = skb->data;
- }
-
- err = add_one_rx_buf(buf_start, q->buf_size, d, sd, q->gen,
- adap->pdev);
- if (unlikely(err)) {
- if (!q->use_pages) {
- kfree_skb(sd->skb);
- sd->skb = NULL;
+ err = add_one_rx_buf(buf_start, q->buf_size, d, sd,
+ q->gen, adap->pdev);
+ if (unlikely(err)) {
+ clear_rx_desc(adap->pdev, q, sd);
+ break;
}
- break;
}
d++;
@@ -478,19 +544,19 @@ nomem: q->alloc_failed++;
sd = q->sdesc;
d = q->desc;
}
- q->credits++;
count++;
}
- wmb();
- if (likely(count))
- t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
+
+ q->credits += count;
+ q->pend_cred += count;
+ ring_fl_db(adap, q);
return count;
}
static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
{
- refill_fl(adap, fl, min(16U, fl->size - fl->credits),
+ refill_fl(adap, fl, min(MAX_RX_REFILL, fl->size - fl->credits),
GFP_ATOMIC | __GFP_COMP);
}
@@ -515,13 +581,15 @@ static void recycle_rx_buf(struct adapter *adap, struct sge_fl *q,
wmb();
to->len_gen = cpu_to_be32(V_FLD_GEN1(q->gen));
to->gen2 = cpu_to_be32(V_FLD_GEN2(q->gen));
- q->credits++;
if (++q->pidx == q->size) {
q->pidx = 0;
q->gen ^= 1;
}
- t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
+
+ q->credits++;
+ q->pend_cred++;
+ ring_fl_db(adap, q);
}
/**
@@ -585,8 +653,8 @@ static void t3_reset_qset(struct sge_qset *q)
memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET);
q->txq_stopped = 0;
q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
- kfree(q->lro_frag_tbl);
- q->lro_nfrags = q->lro_frag_len = 0;
+ q->rx_reclaim_timer.function = NULL;
+ q->lro_frag_tbl.nr_frags = q->lro_frag_tbl.len = 0;
}
@@ -733,7 +801,9 @@ recycle:
return skb;
}
- if (unlikely(fl->credits < drop_thres))
+ if (unlikely(fl->credits < drop_thres) &&
+ refill_fl(adap, fl, min(MAX_RX_REFILL, fl->size - fl->credits - 1),
+ GFP_ATOMIC | __GFP_COMP) == 0)
goto recycle;
use_orig_buf:
@@ -770,19 +840,19 @@ static struct sk_buff *get_packet_pg(struct adapter *adap, struct sge_fl *fl,
struct sk_buff *newskb, *skb;
struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
- newskb = skb = q->pg_skb;
+ dma_addr_t dma_addr = pci_unmap_addr(sd, dma_addr);
+ newskb = skb = q->pg_skb;
if (!skb && (len <= SGE_RX_COPY_THRES)) {
newskb = alloc_skb(len, GFP_ATOMIC);
if (likely(newskb != NULL)) {
__skb_put(newskb, len);
- pci_dma_sync_single_for_cpu(adap->pdev,
- pci_unmap_addr(sd, dma_addr), len,
+ pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len,
PCI_DMA_FROMDEVICE);
memcpy(newskb->data, sd->pg_chunk.va, len);
- pci_dma_sync_single_for_device(adap->pdev,
- pci_unmap_addr(sd, dma_addr), len,
- PCI_DMA_FROMDEVICE);
+ pci_dma_sync_single_for_device(adap->pdev, dma_addr,
+ len,
+ PCI_DMA_FROMDEVICE);
} else if (!drop_thres)
return NULL;
recycle:
@@ -795,16 +865,25 @@ recycle:
if (unlikely(q->rx_recycle_buf || (!skb && fl->credits <= drop_thres)))
goto recycle;
+ prefetch(sd->pg_chunk.p_cnt);
+
if (!skb)
newskb = alloc_skb(SGE_RX_PULL_LEN, GFP_ATOMIC);
+
if (unlikely(!newskb)) {
if (!drop_thres)
return NULL;
goto recycle;
}
- pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
- fl->buf_size, PCI_DMA_FROMDEVICE);
+ pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len,
+ PCI_DMA_FROMDEVICE);
+ (*sd->pg_chunk.p_cnt)--;
+ if (!*sd->pg_chunk.p_cnt)
+ pci_unmap_page(adap->pdev,
+ pci_unmap_addr(&sd->pg_chunk, mapping),
+ fl->alloc_size,
+ PCI_DMA_FROMDEVICE);
if (!skb) {
__skb_put(newskb, SGE_RX_PULL_LEN);
memcpy(newskb->data, sd->pg_chunk.va, SGE_RX_PULL_LEN);
@@ -813,14 +892,15 @@ recycle:
len - SGE_RX_PULL_LEN);
newskb->len = len;
newskb->data_len = len - SGE_RX_PULL_LEN;
+ newskb->truesize += newskb->data_len;
} else {
skb_fill_page_desc(newskb, skb_shinfo(newskb)->nr_frags,
sd->pg_chunk.page,
sd->pg_chunk.offset, len);
newskb->len += len;
newskb->data_len += len;
+ newskb->truesize += len;
}
- newskb->truesize += newskb->data_len;
fl->credits--;
/*
@@ -1063,7 +1143,7 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb,
struct tx_desc *d = &q->desc[pidx];
struct cpl_tx_pkt *cpl = (struct cpl_tx_pkt *)d;
- cpl->len = htonl(skb->len | 0x80000000);
+ cpl->len = htonl(skb->len);
cntrl = V_TXPKT_INTF(pi->port_id);
if (vlan_tx_tag_present(skb) && pi->vlan_grp)
@@ -1161,7 +1241,7 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
txq = netdev_get_tx_queue(dev, qidx);
spin_lock(&q->lock);
- reclaim_completed_tx(adap, q);
+ reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);
credits = q->size - q->in_use;
ndesc = calc_tx_descs(skb);
@@ -1570,7 +1650,7 @@ static int ofld_xmit(struct adapter *adap, struct sge_txq *q,
unsigned int ndesc = calc_tx_descs_ofld(skb), pidx, gen;
spin_lock(&q->lock);
- again:reclaim_completed_tx(adap, q);
+again: reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);
ret = check_desc_avail(adap, q, skb, ndesc, TXQ_OFLD);
if (unlikely(ret)) {
@@ -1612,7 +1692,7 @@ static void restart_offloadq(unsigned long data)
struct adapter *adap = pi->adapter;
spin_lock(&q->lock);
- again:reclaim_completed_tx(adap, q);
+again: reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);
while ((skb = skb_peek(&q->sendq)) != NULL) {
unsigned int gen, pidx;
@@ -1932,12 +2012,13 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
skb_pull(skb, sizeof(*p) + pad);
skb->protocol = eth_type_trans(skb, adap->port[p->iff]);
pi = netdev_priv(skb->dev);
- if ((pi->rx_offload & T3_RX_CSUM) && p->csum_valid && p->csum == htons(0xffff) &&
- !p->fragment) {
+ if ((pi->rx_offload & T3_RX_CSUM) && p->csum_valid &&
+ p->csum == htons(0xffff) && !p->fragment) {
qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else
skb->ip_summed = CHECKSUM_NONE;
+ skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
if (unlikely(p->vlan_valid)) {
struct vlan_group *grp = pi->vlan_grp;
@@ -1945,10 +2026,8 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
qs->port_stats[SGE_PSTAT_VLANEX]++;
if (likely(grp))
if (lro)
- lro_vlan_hwaccel_receive_skb(&qs->lro_mgr, skb,
- grp,
- ntohs(p->vlan),
- p);
+ vlan_gro_receive(&qs->napi, grp,
+ ntohs(p->vlan), skb);
else {
if (unlikely(pi->iscsi_ipv4addr &&
is_arp(skb))) {
@@ -1965,7 +2044,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
dev_kfree_skb_any(skb);
} else if (rq->polling) {
if (lro)
- lro_receive_skb(&qs->lro_mgr, skb, p);
+ napi_gro_receive(&qs->napi, skb);
else {
if (unlikely(pi->iscsi_ipv4addr && is_arp(skb)))
cxgb3_arp_process(adap, skb);
@@ -1981,59 +2060,6 @@ static inline int is_eth_tcp(u32 rss)
}
/**
- * lro_frame_ok - check if an ingress packet is eligible for LRO
- * @p: the CPL header of the packet
- *
- * Returns true if a received packet is eligible for LRO.
- * The following conditions must be true:
- * - packet is TCP/IP Ethernet II (checked elsewhere)
- * - not an IP fragment
- * - no IP options
- * - TCP/IP checksums are correct
- * - the packet is for this host
- */
-static inline int lro_frame_ok(const struct cpl_rx_pkt *p)
-{
- const struct ethhdr *eh = (struct ethhdr *)(p + 1);
- const struct iphdr *ih = (struct iphdr *)(eh + 1);
-
- return (*((u8 *)p + 1) & 0x90) == 0x10 && p->csum == htons(0xffff) &&
- eh->h_proto == htons(ETH_P_IP) && ih->ihl == (sizeof(*ih) >> 2);
-}
-
-static int t3_get_lro_header(void **eh, void **iph, void **tcph,
- u64 *hdr_flags, void *priv)
-{
- const struct cpl_rx_pkt *cpl = priv;
-
- if (!lro_frame_ok(cpl))
- return -1;
-
- *eh = (struct ethhdr *)(cpl + 1);
- *iph = (struct iphdr *)((struct ethhdr *)*eh + 1);
- *tcph = (struct tcphdr *)((struct iphdr *)*iph + 1);
-
- *hdr_flags = LRO_IPV4 | LRO_TCP;
- return 0;
-}
-
-static int t3_get_skb_header(struct sk_buff *skb,
- void **iph, void **tcph, u64 *hdr_flags,
- void *priv)
-{
- void *eh;
-
- return t3_get_lro_header(&eh, iph, tcph, hdr_flags, priv);
-}
-
-static int t3_get_frag_header(struct skb_frag_struct *frag, void **eh,
- void **iph, void **tcph, u64 *hdr_flags,
- void *priv)
-{
- return t3_get_lro_header(eh, iph, tcph, hdr_flags, priv);
-}
-
-/**
* lro_add_page - add a page chunk to an LRO session
* @adap: the adapter
* @qs: the associated queue set
@@ -2049,8 +2075,9 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
{
struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
struct cpl_rx_pkt *cpl;
- struct skb_frag_struct *rx_frag = qs->lro_frag_tbl;
- int nr_frags = qs->lro_nfrags, frag_len = qs->lro_frag_len;
+ struct skb_frag_struct *rx_frag = qs->lro_frag_tbl.frags;
+ int nr_frags = qs->lro_frag_tbl.nr_frags;
+ int frag_len = qs->lro_frag_tbl.len;
int offset = 0;
if (!nr_frags) {
@@ -2061,21 +2088,33 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
fl->credits--;
len -= offset;
- pci_unmap_single(adap->pdev, pci_unmap_addr(sd, dma_addr),
- fl->buf_size, PCI_DMA_FROMDEVICE);
+ pci_dma_sync_single_for_cpu(adap->pdev,
+ pci_unmap_addr(sd, dma_addr),
+ fl->buf_size - SGE_PG_RSVD,
+ PCI_DMA_FROMDEVICE);
+
+ (*sd->pg_chunk.p_cnt)--;
+ if (!*sd->pg_chunk.p_cnt)
+ pci_unmap_page(adap->pdev,
+ pci_unmap_addr(&sd->pg_chunk, mapping),
+ fl->alloc_size,
+ PCI_DMA_FROMDEVICE);
+
+ prefetch(qs->lro_va);
rx_frag += nr_frags;
rx_frag->page = sd->pg_chunk.page;
rx_frag->page_offset = sd->pg_chunk.offset + offset;
rx_frag->size = len;
frag_len += len;
- qs->lro_nfrags++;
- qs->lro_frag_len = frag_len;
+ qs->lro_frag_tbl.nr_frags++;
+ qs->lro_frag_tbl.len = frag_len;
+
if (!complete)
return;
- qs->lro_nfrags = qs->lro_frag_len = 0;
+ qs->lro_frag_tbl.ip_summed = CHECKSUM_UNNECESSARY;
cpl = qs->lro_va;
if (unlikely(cpl->vlan_valid)) {
@@ -2084,36 +2123,15 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
struct vlan_group *grp = pi->vlan_grp;
if (likely(grp != NULL)) {
- lro_vlan_hwaccel_receive_frags(&qs->lro_mgr,
- qs->lro_frag_tbl,
- frag_len, frag_len,
- grp, ntohs(cpl->vlan),
- cpl, 0);
- return;
+ vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan),
+ &qs->lro_frag_tbl);
+ goto out;
}
}
- lro_receive_frags(&qs->lro_mgr, qs->lro_frag_tbl,
- frag_len, frag_len, cpl, 0);
-}
+ napi_gro_frags(&qs->napi, &qs->lro_frag_tbl);
-/**
- * init_lro_mgr - initialize a LRO manager object
- * @lro_mgr: the LRO manager object
- */
-static void init_lro_mgr(struct sge_qset *qs, struct net_lro_mgr *lro_mgr)
-{
- lro_mgr->dev = qs->netdev;
- lro_mgr->features = LRO_F_NAPI;
- lro_mgr->frag_align_pad = NET_IP_ALIGN;
- lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
- lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
- lro_mgr->max_desc = T3_MAX_LRO_SES;
- lro_mgr->lro_arr = qs->lro_desc;
- lro_mgr->get_frag_header = t3_get_frag_header;
- lro_mgr->get_skb_header = t3_get_skb_header;
- lro_mgr->max_aggr = T3_MAX_LRO_MAX_PKTS;
- if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
- lro_mgr->max_aggr = MAX_SKB_FRAGS;
+out:
+ qs->lro_frag_tbl.nr_frags = qs->lro_frag_tbl.len = 0;
}
/**
@@ -2282,6 +2300,8 @@ no_mem:
if (fl->use_pages) {
void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
+ prefetch(&qs->lro_frag_tbl);
+
prefetch(addr);
#if L1_CACHE_BYTES < 128
prefetch(addr + L1_CACHE_BYTES);
@@ -2356,10 +2376,6 @@ next_fl:
}
deliver_partial_bundle(&adap->tdev, q, offload_skbs, ngathered);
- lro_flush_all(&qs->lro_mgr);
- qs->port_stats[SGE_PSTAT_LRO_AGGR] = qs->lro_mgr.stats.aggregated;
- qs->port_stats[SGE_PSTAT_LRO_FLUSHED] = qs->lro_mgr.stats.flushed;
- qs->port_stats[SGE_PSTAT_LRO_NO_DESC] = qs->lro_mgr.stats.no_desc;
if (sleeping)
check_ring_db(adap, qs, sleeping);
@@ -2775,7 +2791,8 @@ irq_handler_t t3_intr_handler(struct adapter *adap, int polling)
*/
void t3_sge_err_intr_handler(struct adapter *adapter)
{
- unsigned int v, status = t3_read_reg(adapter, A_SG_INT_CAUSE);
+ unsigned int v, status = t3_read_reg(adapter, A_SG_INT_CAUSE) &
+ ~F_FLEMPTY;
if (status & SGE_PARERR)
CH_ALERT(adapter, "SGE parity error (0x%x)\n",
@@ -2805,13 +2822,13 @@ void t3_sge_err_intr_handler(struct adapter *adapter)
}
/**
- * sge_timer_cb - perform periodic maintenance of an SGE qset
+ * sge_timer_tx - perform periodic maintenance of an SGE qset
* @data: the SGE queue set to maintain
*
* Runs periodically from a timer to perform maintenance of an SGE queue
* set. It performs two tasks:
*
- * a) Cleans up any completed Tx descriptors that may still be pending.
+ * Cleans up any completed Tx descriptors that may still be pending.
* Normal descriptor cleanup happens when new packets are added to a Tx
* queue so this timer is relatively infrequent and does any cleanup only
* if the Tx queue has not seen any new packets in a while. We make a
@@ -2821,51 +2838,87 @@ void t3_sge_err_intr_handler(struct adapter *adapter)
* up). Since control queues use immediate data exclusively we don't
* bother cleaning them up here.
*
- * b) Replenishes Rx queues that have run out due to memory shortage.
- * Normally new Rx buffers are added when existing ones are consumed but
- * when out of memory a queue can become empty. We try to add only a few
- * buffers here, the queue will be replenished fully as these new buffers
- * are used up if memory shortage has subsided.
*/
-static void sge_timer_cb(unsigned long data)
+static void sge_timer_tx(unsigned long data)
{
- spinlock_t *lock;
struct sge_qset *qs = (struct sge_qset *)data;
- struct adapter *adap = qs->adap;
+ struct port_info *pi = netdev_priv(qs->netdev);
+ struct adapter *adap = pi->adapter;
+ unsigned int tbd[SGE_TXQ_PER_SET] = {0, 0};
+ unsigned long next_period;
if (spin_trylock(&qs->txq[TXQ_ETH].lock)) {
- reclaim_completed_tx(adap, &qs->txq[TXQ_ETH]);
+ tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH],
+ TX_RECLAIM_TIMER_CHUNK);
spin_unlock(&qs->txq[TXQ_ETH].lock);
}
if (spin_trylock(&qs->txq[TXQ_OFLD].lock)) {
- reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD]);
+ tbd[TXQ_OFLD] = reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD],
+ TX_RECLAIM_TIMER_CHUNK);
spin_unlock(&qs->txq[TXQ_OFLD].lock);
}
- lock = (adap->flags & USING_MSIX) ? &qs->rspq.lock :
- &adap->sge.qs[0].rspq.lock;
- if (spin_trylock_irq(lock)) {
- if (!napi_is_scheduled(&qs->napi)) {
- u32 status = t3_read_reg(adap, A_SG_RSPQ_FL_STATUS);
-
- if (qs->fl[0].credits < qs->fl[0].size)
- __refill_fl(adap, &qs->fl[0]);
- if (qs->fl[1].credits < qs->fl[1].size)
- __refill_fl(adap, &qs->fl[1]);
-
- if (status & (1 << qs->rspq.cntxt_id)) {
- qs->rspq.starved++;
- if (qs->rspq.credits) {
- refill_rspq(adap, &qs->rspq, 1);
- qs->rspq.credits--;
- qs->rspq.restarted++;
- t3_write_reg(adap, A_SG_RSPQ_FL_STATUS,
- 1 << qs->rspq.cntxt_id);
- }
+
+ next_period = TX_RECLAIM_PERIOD >>
+ (max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) /
+ TX_RECLAIM_TIMER_CHUNK);
+ mod_timer(&qs->tx_reclaim_timer, jiffies + next_period);
+}
+
+/*
+ * sge_timer_rx - perform periodic maintenance of an SGE qset
+ * @data: the SGE queue set to maintain
+ *
+ * a) Replenishes Rx queues that have run out due to memory shortage.
+ * Normally new Rx buffers are added when existing ones are consumed but
+ * when out of memory a queue can become empty. We try to add only a few
+ * buffers here, the queue will be replenished fully as these new buffers
+ * are used up if memory shortage has subsided.
+ *
+ * b) Return coalesced response queue credits in case a response queue is
+ * starved.
+ *
+ */
+static void sge_timer_rx(unsigned long data)
+{
+ spinlock_t *lock;
+ struct sge_qset *qs = (struct sge_qset *)data;
+ struct port_info *pi = netdev_priv(qs->netdev);
+ struct adapter *adap = pi->adapter;
+ u32 status;
+
+ lock = adap->params.rev > 0 ?
+ &qs->rspq.lock : &adap->sge.qs[0].rspq.lock;
+
+ if (!spin_trylock_irq(lock))
+ goto out;
+
+ if (napi_is_scheduled(&qs->napi))
+ goto unlock;
+
+ if (adap->params.rev < 4) {
+ status = t3_read_reg(adap, A_SG_RSPQ_FL_STATUS);
+
+ if (status & (1 << qs->rspq.cntxt_id)) {
+ qs->rspq.starved++;
+ if (qs->rspq.credits) {
+ qs->rspq.credits--;
+ refill_rspq(adap, &qs->rspq, 1);
+ qs->rspq.restarted++;
+ t3_write_reg(adap, A_SG_RSPQ_FL_STATUS,
+ 1 << qs->rspq.cntxt_id);
}
}
- spin_unlock_irq(lock);
}
- mod_timer(&qs->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);
+
+ if (qs->fl[0].credits < qs->fl[0].size)
+ __refill_fl(adap, &qs->fl[0]);
+ if (qs->fl[1].credits < qs->fl[1].size)
+ __refill_fl(adap, &qs->fl[1]);
+
+unlock:
+ spin_unlock_irq(lock);
+out:
+ mod_timer(&qs->rx_reclaim_timer, jiffies + RX_RECLAIM_PERIOD);
}
/**
@@ -2906,10 +2959,10 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
{
int i, avail, ret = -ENOMEM;
struct sge_qset *q = &adapter->sge.qs[id];
- struct net_lro_mgr *lro_mgr = &q->lro_mgr;
init_qset_cntxt(q, id);
- setup_timer(&q->tx_reclaim_timer, sge_timer_cb, (unsigned long)q);
+ setup_timer(&q->tx_reclaim_timer, sge_timer_tx, (unsigned long)q);
+ setup_timer(&q->rx_reclaim_timer, sge_timer_rx, (unsigned long)q);
q->fl[0].desc = alloc_ring(adapter->pdev, p->fl_size,
sizeof(struct rx_desc),
@@ -2985,25 +3038,23 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
q->fl[1].use_pages = FL1_PG_CHUNK_SIZE > 0;
q->fl[0].order = FL0_PG_ORDER;
q->fl[1].order = FL1_PG_ORDER;
+ q->fl[0].alloc_size = FL0_PG_ALLOC_SIZE;
+ q->fl[1].alloc_size = FL1_PG_ALLOC_SIZE;
- q->lro_frag_tbl = kcalloc(MAX_FRAME_SIZE / FL1_PG_CHUNK_SIZE + 1,
- sizeof(struct skb_frag_struct),
- GFP_KERNEL);
- q->lro_nfrags = q->lro_frag_len = 0;
spin_lock_irq(&adapter->sge.reg_lock);
/* FL threshold comparison uses < */
ret = t3_sge_init_rspcntxt(adapter, q->rspq.cntxt_id, irq_vec_idx,
q->rspq.phys_addr, q->rspq.size,
- q->fl[0].buf_size, 1, 0);
+ q->fl[0].buf_size - SGE_PG_RSVD, 1, 0);
if (ret)
goto err_unlock;
for (i = 0; i < SGE_RXQ_PER_SET; ++i) {
ret = t3_sge_init_flcntxt(adapter, q->fl[i].cntxt_id, 0,
q->fl[i].phys_addr, q->fl[i].size,
- q->fl[i].buf_size, p->cong_thres, 1,
- 0);
+ q->fl[i].buf_size - SGE_PG_RSVD,
+ p->cong_thres, 1, 0);
if (ret)
goto err_unlock;
}
@@ -3041,8 +3092,6 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
q->tx_q = netdevq;
t3_update_qset_coalesce(q, p);
- init_lro_mgr(q, lro_mgr);
-
avail = refill_fl(adapter, &q->fl[0], q->fl[0].size,
GFP_KERNEL | __GFP_COMP);
if (!avail) {
@@ -3063,7 +3112,6 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
t3_write_reg(adapter, A_SG_GTS, V_RSPQ(q->rspq.cntxt_id) |
V_NEWTIMER(q->rspq.holdoff_tmr));
- mod_timer(&q->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);
return 0;
err_unlock:
@@ -3074,6 +3122,27 @@ err:
}
/**
+ * t3_start_sge_timers - start SGE timer call backs
+ * @adap: the adapter
+ *
+ * Starts each SGE queue set's timer call back
+ */
+void t3_start_sge_timers(struct adapter *adap)
+{
+ int i;
+
+ for (i = 0; i < SGE_QSETS; ++i) {
+ struct sge_qset *q = &adap->sge.qs[i];
+
+ if (q->tx_reclaim_timer.function)
+ mod_timer(&q->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD);
+
+ if (q->rx_reclaim_timer.function)
+ mod_timer(&q->rx_reclaim_timer, jiffies + RX_RECLAIM_PERIOD);
+ }
+}
+
+/**
* t3_stop_sge_timers - stop SGE timer call backs
* @adap: the adapter
*
@@ -3088,6 +3157,8 @@ void t3_stop_sge_timers(struct adapter *adap)
if (q->tx_reclaim_timer.function)
del_timer_sync(&q->tx_reclaim_timer);
+ if (q->rx_reclaim_timer.function)
+ del_timer_sync(&q->rx_reclaim_timer);
}
}
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index ac2a974dfe37..31ed31a3428b 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -493,20 +493,20 @@ int t3_phy_lasi_intr_handler(struct cphy *phy)
}
static const struct adapter_info t3_adap_info[] = {
- {2, 0,
+ {1, 1, 0,
F_GPIO2_OEN | F_GPIO4_OEN |
F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, { S_GPIO3, S_GPIO5 }, 0,
&mi1_mdio_ops, "Chelsio PE9000"},
- {2, 0,
+ {1, 1, 0,
F_GPIO2_OEN | F_GPIO4_OEN |
F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, { S_GPIO3, S_GPIO5 }, 0,
&mi1_mdio_ops, "Chelsio T302"},
- {1, 0,
+ {1, 0, 0,
F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN |
F_GPIO11_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
{ 0 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
&mi1_mdio_ext_ops, "Chelsio T310"},
- {2, 0,
+ {1, 1, 0,
F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN |
F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO11_OEN | F_GPIO1_OUT_VAL |
F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
@@ -514,7 +514,7 @@ static const struct adapter_info t3_adap_info[] = {
&mi1_mdio_ext_ops, "Chelsio T320"},
{},
{},
- {1, 0,
+ {1, 0, 0,
F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO6_OEN | F_GPIO7_OEN |
F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
{ S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
@@ -1153,6 +1153,38 @@ int t3_cim_ctl_blk_read(struct adapter *adap, unsigned int addr,
return ret;
}
+static void t3_gate_rx_traffic(struct cmac *mac, u32 *rx_cfg,
+ u32 *rx_hash_high, u32 *rx_hash_low)
+{
+ /* stop Rx unicast traffic */
+ t3_mac_disable_exact_filters(mac);
+
+ /* stop broadcast, multicast, promiscuous mode traffic */
+ *rx_cfg = t3_read_reg(mac->adapter, A_XGM_RX_CFG);
+ t3_set_reg_field(mac->adapter, A_XGM_RX_CFG,
+ F_ENHASHMCAST | F_DISBCAST | F_COPYALLFRAMES,
+ F_DISBCAST);
+
+ *rx_hash_high = t3_read_reg(mac->adapter, A_XGM_RX_HASH_HIGH);
+ t3_write_reg(mac->adapter, A_XGM_RX_HASH_HIGH, 0);
+
+ *rx_hash_low = t3_read_reg(mac->adapter, A_XGM_RX_HASH_LOW);
+ t3_write_reg(mac->adapter, A_XGM_RX_HASH_LOW, 0);
+
+ /* Leave time to drain max RX fifo */
+ msleep(1);
+}
+
+static void t3_open_rx_traffic(struct cmac *mac, u32 rx_cfg,
+ u32 rx_hash_high, u32 rx_hash_low)
+{
+ t3_mac_enable_exact_filters(mac);
+ t3_set_reg_field(mac->adapter, A_XGM_RX_CFG,
+ F_ENHASHMCAST | F_DISBCAST | F_COPYALLFRAMES,
+ rx_cfg);
+ t3_write_reg(mac->adapter, A_XGM_RX_HASH_HIGH, rx_hash_high);
+ t3_write_reg(mac->adapter, A_XGM_RX_HASH_LOW, rx_hash_low);
+}
/**
* t3_link_changed - handle interface link changes
@@ -1170,9 +1202,32 @@ void t3_link_changed(struct adapter *adapter, int port_id)
struct cphy *phy = &pi->phy;
struct cmac *mac = &pi->mac;
struct link_config *lc = &pi->link_config;
+ int force_link_down = 0;
phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
+ if (!lc->link_ok && link_ok) {
+ u32 rx_cfg, rx_hash_high, rx_hash_low;
+ u32 status;
+
+ t3_xgm_intr_enable(adapter, port_id);
+ t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low);
+ t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0);
+ t3_mac_enable(mac, MAC_DIRECTION_RX);
+
+ status = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset);
+ if (status & F_LINKFAULTCHANGE) {
+ mac->stats.link_faults++;
+ force_link_down = 1;
+ }
+ t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low);
+
+ if (force_link_down) {
+ t3_os_link_fault_handler(adapter, port_id);
+ return;
+ }
+ }
+
if (lc->requested_fc & PAUSE_AUTONEG)
fc &= lc->requested_fc;
else
@@ -1202,6 +1257,57 @@ void t3_link_changed(struct adapter *adapter, int port_id)
t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc);
}
+void t3_link_fault(struct adapter *adapter, int port_id)
+{
+ struct port_info *pi = adap2pinfo(adapter, port_id);
+ struct cmac *mac = &pi->mac;
+ struct cphy *phy = &pi->phy;
+ struct link_config *lc = &pi->link_config;
+ int link_ok, speed, duplex, fc, link_fault;
+ u32 rx_cfg, rx_hash_high, rx_hash_low;
+
+ t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low);
+
+ if (adapter->params.rev > 0 && uses_xaui(adapter))
+ t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, 0);
+
+ t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0);
+ t3_mac_enable(mac, MAC_DIRECTION_RX);
+
+ t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low);
+
+ link_fault = t3_read_reg(adapter,
+ A_XGM_INT_STATUS + mac->offset);
+ link_fault &= F_LINKFAULTCHANGE;
+
+ phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
+
+ if (link_fault) {
+ lc->link_ok = 0;
+ lc->speed = SPEED_INVALID;
+ lc->duplex = DUPLEX_INVALID;
+
+ t3_os_link_fault(adapter, port_id, 0);
+
+ /* Account link faults only when the phy reports a link up */
+ if (link_ok)
+ mac->stats.link_faults++;
+
+ msleep(1000);
+ t3_os_link_fault_handler(adapter, port_id);
+ } else {
+ if (link_ok)
+ t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset,
+ F_TXACTENABLE | F_RXEN);
+
+ pi->link_fault = 0;
+ lc->link_ok = (unsigned char)link_ok;
+ lc->speed = speed < 0 ? SPEED_INVALID : speed;
+ lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex;
+ t3_os_link_fault(adapter, port_id, link_ok);
+ }
+}
+
/**
* t3_link_start - apply link configuration to MAC/PHY
* @phy: the PHY to setup
@@ -1323,7 +1429,7 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg,
#define MC7_INTR_MASK (F_AE | F_UE | F_CE | V_PE(M_PE))
#define XGM_INTR_MASK (V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR) | \
V_RXFIFO_PRTY_ERR(M_RXFIFO_PRTY_ERR) | \
- F_TXFIFO_UNDERRUN | F_RXFIFO_OVERFLOW)
+ F_TXFIFO_UNDERRUN)
#define PCIX_INTR_MASK (F_MSTDETPARERR | F_SIGTARABT | F_RCVTARABT | \
F_RCVMSTABT | F_SIGSYSERR | F_DETPARERR | \
F_SPLCMPDIS | F_UNXSPLCMP | F_RCVSPLCMPERR | \
@@ -1360,11 +1466,11 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg,
V_TX1TPPARERRENB(M_TX1TPPARERRENB) | \
V_RXTPPARERRENB(M_RXTPPARERRENB) | \
V_MCAPARERRENB(M_MCAPARERRENB))
+#define XGM_EXTRA_INTR_MASK (F_LINKFAULTCHANGE)
#define PL_INTR_MASK (F_T3DBG | F_XGMAC0_0 | F_XGMAC0_1 | F_MC5A | F_PM1_TX | \
F_PM1_RX | F_ULP2_TX | F_ULP2_RX | F_TP1 | F_CIM | \
F_MC7_CM | F_MC7_PMTX | F_MC7_PMRX | F_SGE3 | F_PCIM0 | \
F_MPS0 | F_CPL_SWITCH)
-
/*
* Interrupt handler for the PCIX1 module.
*/
@@ -1695,7 +1801,14 @@ static void mc7_intr_handler(struct mc7 *mc7)
static int mac_intr_handler(struct adapter *adap, unsigned int idx)
{
struct cmac *mac = &adap2pinfo(adap, idx)->mac;
- u32 cause = t3_read_reg(adap, A_XGM_INT_CAUSE + mac->offset);
+ /*
+ * We mask out interrupt causes for which we're not taking interrupts.
+ * This allows us to use polling logic to monitor some of the other
+ * conditions when taking interrupts would impose too much load on the
+ * system.
+ */
+ u32 cause = t3_read_reg(adap, A_XGM_INT_CAUSE + mac->offset) &
+ ~F_RXFIFO_OVERFLOW;
if (cause & V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR)) {
mac->stats.tx_fifo_parity_err++;
@@ -1715,10 +1828,20 @@ static int mac_intr_handler(struct adapter *adap, unsigned int idx)
mac->stats.xaui_pcs_ctc_err++;
if (cause & F_XAUIPCSALIGNCHANGE)
mac->stats.xaui_pcs_align_change++;
+ if (cause & F_XGM_INT) {
+ t3_set_reg_field(adap,
+ A_XGM_INT_ENABLE + mac->offset,
+ F_XGM_INT, 0);
+ mac->stats.link_faults++;
+
+ t3_os_link_fault_handler(adap, idx);
+ }
t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause);
+
if (cause & XGM_INTR_FATAL)
t3_fatal_err(adap);
+
return cause != 0;
}
@@ -1924,6 +2047,22 @@ void t3_intr_clear(struct adapter *adapter)
t3_read_reg(adapter, A_PL_INT_CAUSE0); /* flush */
}
+void t3_xgm_intr_enable(struct adapter *adapter, int idx)
+{
+ struct port_info *pi = adap2pinfo(adapter, idx);
+
+ t3_write_reg(adapter, A_XGM_XGM_INT_ENABLE + pi->mac.offset,
+ XGM_EXTRA_INTR_MASK);
+}
+
+void t3_xgm_intr_disable(struct adapter *adapter, int idx)
+{
+ struct port_info *pi = adap2pinfo(adapter, idx);
+
+ t3_write_reg(adapter, A_XGM_XGM_INT_DISABLE + pi->mac.offset,
+ 0x7ff);
+}
+
/**
* t3_port_intr_enable - enable port-specific interrupts
* @adapter: associated adapter
@@ -1989,16 +2128,40 @@ void t3_port_intr_clear(struct adapter *adapter, int idx)
static int t3_sge_write_context(struct adapter *adapter, unsigned int id,
unsigned int type)
{
- t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0xffffffff);
- t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0xffffffff);
- t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0xffffffff);
- t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0xffffffff);
+ if (type == F_RESPONSEQ) {
+ /*
+ * Can't write the Response Queue Context bits for
+ * Interrupt Armed or the Reserve bits after the chip
+ * has been initialized out of reset. Writing to these
+ * bits can confuse the hardware.
+ */
+ t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0xffffffff);
+ t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0xffffffff);
+ t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0x17ffffff);
+ t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0xffffffff);
+ } else {
+ t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0xffffffff);
+ t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0xffffffff);
+ t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0xffffffff);
+ t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0xffffffff);
+ }
t3_write_reg(adapter, A_SG_CONTEXT_CMD,
V_CONTEXT_CMD_OPCODE(1) | type | V_CONTEXT(id));
return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
0, SG_CONTEXT_CMD_ATTEMPTS, 1);
}
+/**
+ * clear_sge_ctxt - completely clear an SGE context
+ * @adapter: the adapter
+ * @id: the context id
+ * @type: the context type
+ *
+ * Completely clear an SGE context. Used predominantly at post-reset
+ * initialization. Note in particular that we don't skip writing to any
+ * "sensitive bits" in the contexts the way that t3_sge_write_context()
+ * does ...
+ */
static int clear_sge_ctxt(struct adapter *adap, unsigned int id,
unsigned int type)
{
@@ -2006,7 +2169,14 @@ static int clear_sge_ctxt(struct adapter *adap, unsigned int id,
t3_write_reg(adap, A_SG_CONTEXT_DATA1, 0);
t3_write_reg(adap, A_SG_CONTEXT_DATA2, 0);
t3_write_reg(adap, A_SG_CONTEXT_DATA3, 0);
- return t3_sge_write_context(adap, id, type);
+ t3_write_reg(adap, A_SG_CONTEXT_MASK0, 0xffffffff);
+ t3_write_reg(adap, A_SG_CONTEXT_MASK1, 0xffffffff);
+ t3_write_reg(adap, A_SG_CONTEXT_MASK2, 0xffffffff);
+ t3_write_reg(adap, A_SG_CONTEXT_MASK3, 0xffffffff);
+ t3_write_reg(adap, A_SG_CONTEXT_CMD,
+ V_CONTEXT_CMD_OPCODE(1) | type | V_CONTEXT(id));
+ return t3_wait_op_done(adap, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
+ 0, SG_CONTEXT_CMD_ATTEMPTS, 1);
}
/**
@@ -2590,10 +2760,10 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
F_TCPCHECKSUMOFFLOAD | V_IPTTL(64));
t3_write_reg(adap, A_TP_TCP_OPTIONS, V_MTUDEFAULT(576) |
F_MTUENABLE | V_WINDOWSCALEMODE(1) |
- V_TIMESTAMPSMODE(0) | V_SACKMODE(1) | V_SACKRX(1));
+ V_TIMESTAMPSMODE(1) | V_SACKMODE(1) | V_SACKRX(1));
t3_write_reg(adap, A_TP_DACK_CONFIG, V_AUTOSTATE3(1) |
V_AUTOSTATE2(1) | V_AUTOSTATE1(0) |
- V_BYTETHRESHOLD(16384) | V_MSSTHRESHOLD(2) |
+ V_BYTETHRESHOLD(26880) | V_MSSTHRESHOLD(2) |
F_AUTOCAREFUL | F_AUTOENABLE | V_DACK_MODE(1));
t3_set_reg_field(adap, A_TP_IN_CONFIG, F_RXFBARBPRIO | F_TXFBARBPRIO,
F_IPV6ENABLE | F_NICMODE);
@@ -3057,20 +3227,22 @@ int t3_mps_set_active_ports(struct adapter *adap, unsigned int port_mask)
}
/*
- * Perform the bits of HW initialization that are dependent on the number
- * of available ports.
+ * Perform the bits of HW initialization that are dependent on the Tx
+ * channels being used.
*/
-static void init_hw_for_avail_ports(struct adapter *adap, int nports)
+static void chan_init_hw(struct adapter *adap, unsigned int chan_map)
{
int i;
- if (nports == 1) {
+ if (chan_map != 3) { /* one channel */
t3_set_reg_field(adap, A_ULPRX_CTL, F_ROUND_ROBIN, 0);
t3_set_reg_field(adap, A_ULPTX_CONFIG, F_CFG_RR_ARB, 0);
- t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_TPTXPORT0EN |
- F_PORT0ACTIVE | F_ENFORCEPKT);
- t3_write_reg(adap, A_PM1_TX_CFG, 0xffffffff);
- } else {
+ t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_ENFORCEPKT |
+ (chan_map == 1 ? F_TPTXPORT0EN | F_PORT0ACTIVE :
+ F_TPTXPORT1EN | F_PORT1ACTIVE));
+ t3_write_reg(adap, A_PM1_TX_CFG,
+ chan_map == 1 ? 0xffffffff : 0);
+ } else { /* two channels */
t3_set_reg_field(adap, A_ULPRX_CTL, 0, F_ROUND_ROBIN);
t3_set_reg_field(adap, A_ULPTX_CONFIG, 0, F_CFG_RR_ARB);
t3_write_reg(adap, A_ULPTX_DMA_WEIGHT,
@@ -3378,7 +3550,7 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
t3_write_reg(adapter, A_PM1_RX_CFG, 0xffffffff);
t3_write_reg(adapter, A_PM1_RX_MODE, 0);
t3_write_reg(adapter, A_PM1_TX_MODE, 0);
- init_hw_for_avail_ports(adapter, adapter->params.nports);
+ chan_init_hw(adapter, adapter->params.chan_map);
t3_sge_init(adapter, &adapter->params.sge);
t3_write_reg(adapter, A_T3DBG_GPIO_ACT_LOW, calc_gpio_intr(adapter));
@@ -3615,9 +3787,18 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
get_pci_mode(adapter, &adapter->params.pci);
adapter->params.info = ai;
- adapter->params.nports = ai->nports;
+ adapter->params.nports = ai->nports0 + ai->nports1;
+ adapter->params.chan_map = !!ai->nports0 | (!!ai->nports1 << 1);
adapter->params.rev = t3_read_reg(adapter, A_PL_REV);
- adapter->params.linkpoll_period = 0;
+ /*
+ * We used to only run the "adapter check task" once a second if
+ * we had PHYs which didn't support interrupts (we would check
+ * their link status once a second). Now we check other conditions
+ * in that routine which could potentially impose a very high
+ * interrupt load on the system. As such, we now always scan the
+ * adapter state once a second ...
+ */
+ adapter->params.linkpoll_period = 10;
adapter->params.stats_update_period = is_10G(adapter) ?
MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10);
adapter->params.pci.vpd_cap_addr =
@@ -3638,7 +3819,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
mc7_prep(adapter, &adapter->pmtx, MC7_PMTX_BASE_ADDR, "PMTX");
mc7_prep(adapter, &adapter->cm, MC7_CM_BASE_ADDR, "CM");
- p->nchan = ai->nports;
+ p->nchan = adapter->params.chan_map == 3 ? 2 : 1;
p->pmrx_size = t3_mc7_size(&adapter->pmrx);
p->pmtx_size = t3_mc7_size(&adapter->pmtx);
p->cm_size = t3_mc7_size(&adapter->cm);
@@ -3707,7 +3888,14 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
ETH_ALEN);
init_link_config(&p->link_config, p->phy.caps);
p->phy.ops->power_down(&p->phy, 1);
- if (!(p->phy.caps & SUPPORTED_IRQ))
+
+ /*
+ * If the PHY doesn't support interrupts for link status
+ * changes, schedule a scan of the adapter links at least
+ * once a second.
+ */
+ if (!(p->phy.caps & SUPPORTED_IRQ) &&
+ adapter->params.linkpoll_period > 10)
adapter->params.linkpoll_period = 10;
}
diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h
index b1b25c37aa10..7bf963ec5548 100644
--- a/drivers/net/cxgb3/version.h
+++ b/drivers/net/cxgb3/version.h
@@ -35,10 +35,10 @@
#define DRV_DESC "Chelsio T3 Network Driver"
#define DRV_NAME "cxgb3"
/* Driver version */
-#define DRV_VERSION "1.1.1-ko"
+#define DRV_VERSION "1.1.2-ko"
/* Firmware version */
#define FW_VERSION_MAJOR 7
-#define FW_VERSION_MINOR 0
+#define FW_VERSION_MINOR 1
#define FW_VERSION_MICRO 0
#endif /* __CHELSIO_VERSION_H */
diff --git a/drivers/net/cxgb3/xgmac.c b/drivers/net/cxgb3/xgmac.c
index 9d7786937aad..f87f9435049f 100644
--- a/drivers/net/cxgb3/xgmac.c
+++ b/drivers/net/cxgb3/xgmac.c
@@ -150,7 +150,8 @@ int t3_mac_reset(struct cmac *mac)
static int t3b2_mac_reset(struct cmac *mac)
{
struct adapter *adap = mac->adapter;
- unsigned int oft = mac->offset;
+ unsigned int oft = mac->offset, store;
+ int idx = macidx(mac);
u32 val;
if (!macidx(mac))
@@ -158,14 +159,28 @@ static int t3b2_mac_reset(struct cmac *mac)
else
t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE, 0);
+ /* Stop NIC traffic to reduce the number of TXTOGGLES */
+ t3_set_reg_field(adap, A_MPS_CFG, F_ENFORCEPKT, 0);
+ /* Ensure TX drains */
+ t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN, 0);
+
t3_write_reg(adap, A_XGM_RESET_CTRL + oft, F_MAC_RESET_);
t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */
+ /* Store A_TP_TX_DROP_CFG_CH0 */
+ t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
+ store = t3_read_reg(adap, A_TP_TX_DROP_CFG_CH0 + idx);
+
msleep(10);
+ /* Change DROP_CFG to 0xc0000011 */
+ t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
+ t3_write_reg(adap, A_TP_PIO_DATA, 0xc0000011);
+
/* Check for xgm Rx fifo empty */
+ /* Increased loop count to 1000 from 5 cover 1G and 100Mbps case */
if (t3_wait_op_done(adap, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT + oft,
- 0x80000000, 1, 5, 2)) {
+ 0x80000000, 1, 1000, 2)) {
CH_ERR(adap, "MAC %d Rx fifo drain failed\n",
macidx(mac));
return -1;
@@ -191,11 +206,21 @@ static int t3b2_mac_reset(struct cmac *mac)
F_DISPAUSEFRAMES | F_EN1536BFRAMES |
F_RMFCS | F_ENJUMBO | F_ENHASHMCAST);
- if (!macidx(mac))
+ /* Restore the DROP_CFG */
+ t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
+ t3_write_reg(adap, A_TP_PIO_DATA, store);
+
+ if (!idx)
t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT0ACTIVE);
else
t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT1ACTIVE);
+ /* re-enable nic traffic */
+ t3_set_reg_field(adap, A_MPS_CFG, F_ENFORCEPKT, 1);
+
+ /* Set: re-enable NIC traffic */
+ t3_set_reg_field(adap, A_MPS_CFG, F_ENFORCEPKT, 1);
+
return 0;
}
@@ -236,7 +261,7 @@ int t3_mac_set_num_ucast(struct cmac *mac, int n)
return 0;
}
-static void disable_exact_filters(struct cmac *mac)
+void t3_mac_disable_exact_filters(struct cmac *mac)
{
unsigned int i, reg = mac->offset + A_XGM_RX_EXACT_MATCH_LOW_1;
@@ -247,7 +272,7 @@ static void disable_exact_filters(struct cmac *mac)
t3_read_reg(mac->adapter, A_XGM_RX_EXACT_MATCH_LOW_1); /* flush */
}
-static void enable_exact_filters(struct cmac *mac)
+void t3_mac_enable_exact_filters(struct cmac *mac)
{
unsigned int i, reg = mac->offset + A_XGM_RX_EXACT_MATCH_HIGH_1;
@@ -332,18 +357,9 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
return -EINVAL;
t3_write_reg(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset, mtu);
- /*
- * Adjust the PAUSE frame watermarks. We always set the LWM, and the
- * HWM only if flow-control is enabled.
- */
- hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu,
- MAC_RXFIFO_SIZE * 38 / 100);
- hwm = min(hwm, MAC_RXFIFO_SIZE - 8192);
- lwm = min(3 * (int)mtu, MAC_RXFIFO_SIZE / 4);
-
if (adap->params.rev >= T3_REV_B2 &&
(t3_read_reg(adap, A_XGM_RX_CTRL + mac->offset) & F_RXEN)) {
- disable_exact_filters(mac);
+ t3_mac_disable_exact_filters(mac);
v = t3_read_reg(adap, A_XGM_RX_CFG + mac->offset);
t3_set_reg_field(adap, A_XGM_RX_CFG + mac->offset,
F_ENHASHMCAST | F_COPYALLFRAMES, F_DISBCAST);
@@ -355,14 +371,14 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
if (t3_wait_op_done(adap, reg + mac->offset,
F_RXFIFO_EMPTY, 1, 20, 5)) {
t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
- enable_exact_filters(mac);
+ t3_mac_enable_exact_filters(mac);
return -EIO;
}
t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
V_RXMAXPKTSIZE(mtu));
t3_write_reg(adap, A_XGM_RX_CFG + mac->offset, v);
- enable_exact_filters(mac);
+ t3_mac_enable_exact_filters(mac);
} else
t3_set_reg_field(adap, A_XGM_RX_MAX_PKT_SIZE + mac->offset,
V_RXMAXPKTSIZE(M_RXMAXPKTSIZE),
@@ -452,9 +468,12 @@ int t3_mac_enable(struct cmac *mac, int which)
if (which & MAC_DIRECTION_TX) {
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
- t3_write_reg(adap, A_TP_PIO_DATA, 0xc0ede401);
+ t3_write_reg(adap, A_TP_PIO_DATA,
+ adap->params.rev == T3_REV_C ?
+ 0xc4ffff01 : 0xc0ede401);
t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE);
- t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
+ t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx,
+ adap->params.rev == T3_REV_C ? 0 : 1 << idx);
t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
@@ -510,15 +529,12 @@ int t3b2_mac_watchdog_task(struct cmac *mac)
struct adapter *adap = mac->adapter;
struct mac_stats *s = &mac->stats;
unsigned int tx_tcnt, tx_xcnt;
- unsigned int tx_mcnt = s->tx_frames;
- unsigned int rx_mcnt = s->rx_frames;
- unsigned int rx_xcnt;
+ u64 tx_mcnt = s->tx_frames;
int status;
status = 0;
tx_xcnt = 1; /* By default tx_xcnt is making progress */
tx_tcnt = mac->tx_tcnt; /* If tx_mcnt is progressing ignore tx_tcnt */
- rx_xcnt = 1; /* By default rx_xcnt is making progress */
if (tx_mcnt == mac->tx_mcnt && mac->rx_pause == s->rx_pause) {
tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
A_XGM_TX_SPI4_SOP_EOP_CNT +
@@ -529,11 +545,11 @@ int t3b2_mac_watchdog_task(struct cmac *mac)
tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
A_TP_PIO_DATA)));
} else {
- goto rxcheck;
+ goto out;
}
} else {
mac->toggle_cnt = 0;
- goto rxcheck;
+ goto out;
}
if ((tx_tcnt != mac->tx_tcnt) && (mac->tx_xcnt == 0)) {
@@ -546,23 +562,6 @@ int t3b2_mac_watchdog_task(struct cmac *mac)
}
} else {
mac->toggle_cnt = 0;
- goto rxcheck;
- }
-
-rxcheck:
- if (rx_mcnt != mac->rx_mcnt) {
- rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
- A_XGM_RX_SPI4_SOP_EOP_CNT +
- mac->offset))) +
- (s->rx_fifo_ovfl -
- mac->rx_ocnt);
- mac->rx_ocnt = s->rx_fifo_ovfl;
- } else
- goto out;
-
- if (mac->rx_mcnt != s->rx_frames && rx_xcnt == 0 &&
- mac->rx_xcnt == 0) {
- status = 2;
goto out;
}
@@ -570,8 +569,6 @@ out:
mac->tx_tcnt = tx_tcnt;
mac->tx_xcnt = tx_xcnt;
mac->tx_mcnt = s->tx_frames;
- mac->rx_xcnt = rx_xcnt;
- mac->rx_mcnt = s->rx_frames;
mac->rx_pause = s->rx_pause;
if (status == 1) {
t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 7ce3053530f9..861c867fca87 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -1027,7 +1027,7 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
printk(version);
if (bdev)
- snprintf(name, sizeof(name), "%s", bdev->bus_id);
+ snprintf(name, sizeof(name), "%s", dev_name(bdev));
else {
i = 0;
dev = root_lance_dev;
@@ -1105,10 +1105,10 @@ static int __init dec_lance_probe(struct device *bdev, const int type)
start = to_tc_dev(bdev)->resource.start;
len = to_tc_dev(bdev)->resource.end - start + 1;
- if (!request_mem_region(start, len, bdev->bus_id)) {
+ if (!request_mem_region(start, len, dev_name(bdev))) {
printk(KERN_ERR
"%s: Unable to reserve MMIO resource\n",
- bdev->bus_id);
+ dev_name(bdev));
ret = -EBUSY;
goto err_out_dev;
}
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index 6445cedd5868..4ec055dc7174 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -2937,7 +2937,7 @@ static int dfx_rcv_init(DFX_board_t *bp, int get_buffers)
for (i = 0; i < (int)(bp->rcv_bufs_to_post); i++)
for (j = 0; (i + j) < (int)PI_RCV_DATA_K_NUM_ENTRIES; j += bp->rcv_bufs_to_post)
{
- struct sk_buff *newskb = __dev_alloc_skb(NEW_SKB_SIZE, GFP_NOIO);
+ struct sk_buff *newskb = __netdev_alloc_skb(bp->dev, NEW_SKB_SIZE, GFP_NOIO);
if (!newskb)
return -ENOMEM;
bp->descr_block_virt->rcv_data[i+j].long_0 = (u32) (PI_RCV_DESCR_M_SOP |
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index e4cef491dc73..357f565851ed 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -566,6 +566,18 @@ MODULE_LICENSE("GPL");
outw(CSR0, DEPCA_ADDR);\
outw(STOP, DEPCA_DATA)
+static const struct net_device_ops depca_netdev_ops = {
+ .ndo_open = depca_open,
+ .ndo_start_xmit = depca_start_xmit,
+ .ndo_stop = depca_close,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_do_ioctl = depca_ioctl,
+ .ndo_tx_timeout = depca_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init depca_hw_init (struct net_device *dev, struct device *device)
{
struct depca_private *lp;
@@ -606,8 +618,8 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
if (!mem_start || lp->adapter < DEPCA || lp->adapter >=unknown)
return -ENXIO;
- printk ("%s: %s at 0x%04lx",
- device->bus_id, depca_signature[lp->adapter], ioaddr);
+ printk("%s: %s at 0x%04lx",
+ dev_name(device), depca_signature[lp->adapter], ioaddr);
switch (lp->depca_bus) {
#ifdef CONFIG_MCA
@@ -669,7 +681,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
spin_lock_init(&lp->lock);
sprintf(lp->adapter_name, "%s (%s)",
- depca_signature[lp->adapter], device->bus_id);
+ depca_signature[lp->adapter], dev_name(device));
status = -EBUSY;
/* Initialisation Block */
@@ -793,12 +805,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
}
/* The DEPCA-specific entries in the device structure. */
- dev->open = &depca_open;
- dev->hard_start_xmit = &depca_start_xmit;
- dev->stop = &depca_close;
- dev->set_multicast_list = &set_multicast_list;
- dev->do_ioctl = &depca_ioctl;
- dev->tx_timeout = depca_tx_timeout;
+ dev->netdev_ops = &depca_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
dev->mem_start = 0;
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index bcf92917bbf3..d8350860c0f8 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -559,7 +559,7 @@ static void dm9000_show_carrier(board_info_t *db,
static void
dm9000_poll_work(struct work_struct *w)
{
- struct delayed_work *dw = container_of(w, struct delayed_work, work);
+ struct delayed_work *dw = to_delayed_work(w);
board_info_t *db = container_of(dw, board_info_t, phy_poll);
struct net_device *ndev = db->ndev;
@@ -930,13 +930,15 @@ static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
struct net_device *dev = dev_id;
board_info_t *db = netdev_priv(dev);
int int_status;
+ unsigned long flags;
u8 reg_save;
dm9000_dbg(db, 3, "entering %s\n", __func__);
/* A real interrupt coming */
- spin_lock(&db->lock);
+ /* holders of db->lock must always block IRQs */
+ spin_lock_irqsave(&db->lock, flags);
/* Save previous register address */
reg_save = readb(db->io_addr);
@@ -972,7 +974,7 @@ static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
/* Restore previous register address */
writeb(reg_save, db->io_addr);
- spin_unlock(&db->lock);
+ spin_unlock_irqrestore(&db->lock, flags);
return IRQ_HANDLED;
}
diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c
index 5c347f70cb67..33fa9eee4cac 100644
--- a/drivers/net/dnet.c
+++ b/drivers/net/dnet.c
@@ -8,7 +8,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#include <linux/version.h>
+#include <linux/io.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -21,7 +21,6 @@
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/phy.h>
-#include <linux/platform_device.h>
#include "dnet.h"
@@ -280,11 +279,11 @@ static int dnet_mii_probe(struct net_device *dev)
/* attach the mac to the phy */
if (bp->capabilities & DNET_HAS_RMII) {
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&dnet_handle_link_change, 0,
PHY_INTERFACE_MODE_RMII);
} else {
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&dnet_handle_link_change, 0,
PHY_INTERFACE_MODE_MII);
}
@@ -927,7 +926,7 @@ static int __devinit dnet_probe(struct platform_device *pdev)
phydev = bp->phy_dev;
dev_info(&pdev->dev, "attached PHY driver [%s] "
"(mii_bus:phy_addr=%s, irq=%d)\n",
- phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
return 0;
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 86bb876fb123..0504db9ad643 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -167,7 +167,7 @@
#define DRV_NAME "e100"
#define DRV_EXT "-NAPI"
-#define DRV_VERSION "3.5.23-k6"DRV_EXT
+#define DRV_VERSION "3.5.24-k2"DRV_EXT
#define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver"
#define DRV_COPYRIGHT "Copyright(c) 1999-2006 Intel Corporation"
#define PFX DRV_NAME ": "
@@ -240,6 +240,7 @@ static struct pci_device_id e100_id_table[] = {
INTEL_8255X_ETHERNET_DEVICE(0x1093, 7),
INTEL_8255X_ETHERNET_DEVICE(0x1094, 7),
INTEL_8255X_ETHERNET_DEVICE(0x1095, 7),
+ INTEL_8255X_ETHERNET_DEVICE(0x10fe, 7),
INTEL_8255X_ETHERNET_DEVICE(0x1209, 0),
INTEL_8255X_ETHERNET_DEVICE(0x1229, 0),
INTEL_8255X_ETHERNET_DEVICE(0x2449, 2),
@@ -275,6 +276,7 @@ enum phy {
phy_82562_em = 0x032002A8,
phy_82562_ek = 0x031002A8,
phy_82562_eh = 0x017002A8,
+ phy_82552_v = 0xd061004d,
phy_unknown = 0xFFFFFFFF,
};
@@ -943,6 +945,22 @@ static int mdio_read(struct net_device *netdev, int addr, int reg)
static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
{
+ struct nic *nic = netdev_priv(netdev);
+
+ if ((nic->phy == phy_82552_v) && (reg == MII_BMCR) &&
+ (data & (BMCR_ANRESTART | BMCR_ANENABLE))) {
+ u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
+
+ /*
+ * Workaround Si issue where sometimes the part will not
+ * autoneg to 100Mbps even when advertised.
+ */
+ if (advert & ADVERTISE_100FULL)
+ data |= BMCR_SPEED100 | BMCR_FULLDPLX;
+ else if (advert & ADVERTISE_100HALF)
+ data |= BMCR_SPEED100;
+ }
+
mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);
}
@@ -1276,16 +1294,12 @@ static int e100_phy_init(struct nic *nic)
if (addr == 32)
return -EAGAIN;
- /* Selected the phy and isolate the rest */
- for (addr = 0; addr < 32; addr++) {
- if (addr != nic->mii.phy_id) {
- mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
- } else {
- bmcr = mdio_read(netdev, addr, MII_BMCR);
- mdio_write(netdev, addr, MII_BMCR,
- bmcr & ~BMCR_ISOLATE);
- }
- }
+ /* Isolate all the PHY ids */
+ for (addr = 0; addr < 32; addr++)
+ mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
+ /* Select the discovered PHY */
+ bmcr &= ~BMCR_ISOLATE;
+ mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
/* Get phy ID */
id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1);
@@ -1303,7 +1317,18 @@ static int e100_phy_init(struct nic *nic)
mdio_write(netdev, nic->mii.phy_id, MII_NSC_CONG, cong);
}
- if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
+ if (nic->phy == phy_82552_v) {
+ u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
+
+ /* Workaround Si not advertising flow-control during autoneg */
+ advert |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+ mdio_write(netdev, nic->mii.phy_id, MII_ADVERTISE, advert);
+
+ /* Reset for the above changes to take effect */
+ bmcr = mdio_read(netdev, nic->mii.phy_id, MII_BMCR);
+ bmcr |= BMCR_RESET;
+ mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
+ } else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) &&
(mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) &&
!(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) {
/* enable/disable MDI/MDI-X auto-switching. */
@@ -1944,9 +1969,9 @@ static irqreturn_t e100_intr(int irq, void *dev_id)
if (stat_ack & stat_ack_rnr)
nic->ru_running = RU_SUSPENDED;
- if (likely(netif_rx_schedule_prep(&nic->napi))) {
+ if (likely(napi_schedule_prep(&nic->napi))) {
e100_disable_irq(nic);
- __netif_rx_schedule(&nic->napi);
+ __napi_schedule(&nic->napi);
}
return IRQ_HANDLED;
@@ -1962,7 +1987,7 @@ static int e100_poll(struct napi_struct *napi, int budget)
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
e100_enable_irq(nic);
}
@@ -2134,6 +2159,9 @@ err_clean_rx:
}
#define MII_LED_CONTROL 0x1B
+#define E100_82552_LED_OVERRIDE 0x19
+#define E100_82552_LED_ON 0x000F /* LEDTX and LED_RX both on */
+#define E100_82552_LED_OFF 0x000A /* LEDTX and LED_RX both off */
static void e100_blink_led(unsigned long data)
{
struct nic *nic = (struct nic *)data;
@@ -2143,10 +2171,19 @@ static void e100_blink_led(unsigned long data)
led_on_559 = 0x05,
led_on_557 = 0x07,
};
+ u16 led_reg = MII_LED_CONTROL;
+
+ if (nic->phy == phy_82552_v) {
+ led_reg = E100_82552_LED_OVERRIDE;
- nic->leds = (nic->leds & led_on) ? led_off :
- (nic->mac < mac_82559_D101M) ? led_on_557 : led_on_559;
- mdio_write(nic->netdev, nic->mii.phy_id, MII_LED_CONTROL, nic->leds);
+ nic->leds = (nic->leds == E100_82552_LED_ON) ?
+ E100_82552_LED_OFF : E100_82552_LED_ON;
+ } else {
+ nic->leds = (nic->leds & led_on) ? led_off :
+ (nic->mac < mac_82559_D101M) ? led_on_557 :
+ led_on_559;
+ }
+ mdio_write(nic->netdev, nic->mii.phy_id, led_reg, nic->leds);
mod_timer(&nic->blink_timer, jiffies + HZ / 4);
}
@@ -2375,13 +2412,15 @@ static void e100_diag_test(struct net_device *netdev,
static int e100_phys_id(struct net_device *netdev, u32 data)
{
struct nic *nic = netdev_priv(netdev);
+ u16 led_reg = (nic->phy == phy_82552_v) ? E100_82552_LED_OVERRIDE :
+ MII_LED_CONTROL;
if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
mod_timer(&nic->blink_timer, jiffies);
msleep_interruptible(data * 1000);
del_timer_sync(&nic->blink_timer);
- mdio_write(netdev, nic->mii.phy_id, MII_LED_CONTROL, 0);
+ mdio_write(netdev, nic->mii.phy_id, led_reg, 0);
return 0;
}
@@ -2686,6 +2725,9 @@ static void __devexit e100_remove(struct pci_dev *pdev)
}
}
+#define E100_82552_SMARTSPEED 0x14 /* SmartSpeed Ctrl register */
+#define E100_82552_REV_ANEG 0x0200 /* Reverse auto-negotiation */
+#define E100_82552_ANEG_NOW 0x0400 /* Auto-negotiate now */
static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
@@ -2698,6 +2740,15 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
pci_save_state(pdev);
if ((nic->flags & wol_magic) | e100_asf(nic)) {
+ /* enable reverse auto-negotiation */
+ if (nic->phy == phy_82552_v) {
+ u16 smartspeed = mdio_read(netdev, nic->mii.phy_id,
+ E100_82552_SMARTSPEED);
+
+ mdio_write(netdev, nic->mii.phy_id,
+ E100_82552_SMARTSPEED, smartspeed |
+ E100_82552_REV_ANEG | E100_82552_ANEG_NOW);
+ }
if (pci_enable_wake(pdev, PCI_D3cold, true))
pci_enable_wake(pdev, PCI_D3hot, true);
} else {
@@ -2721,6 +2772,16 @@ static int e100_resume(struct pci_dev *pdev)
/* ack any pending wake events, disable PME */
pci_enable_wake(pdev, 0, 0);
+ /* disbale reverse auto-negotiation */
+ if (nic->phy == phy_82552_v) {
+ u16 smartspeed = mdio_read(netdev, nic->mii.phy_id,
+ E100_82552_SMARTSPEED);
+
+ mdio_write(netdev, nic->mii.phy_id,
+ E100_82552_SMARTSPEED,
+ smartspeed & ~(E100_82552_REV_ANEG));
+ }
+
netif_device_attach(netdev);
if (netif_running(netdev))
e100_up(nic);
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index f5581de04757..e9a416f40162 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -182,7 +182,6 @@ struct e1000_tx_ring {
/* array of buffer information structs */
struct e1000_buffer *buffer_info;
- spinlock_t tx_lock;
u16 tdh;
u16 tdt;
bool last_tx_tso;
@@ -238,7 +237,6 @@ struct e1000_adapter {
u16 link_speed;
u16 link_duplex;
spinlock_t stats_lock;
- spinlock_t tx_queue_lock;
unsigned int total_tx_bytes;
unsigned int total_tx_packets;
unsigned int total_rx_bytes;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 6bd63cc67b3e..93b861d032b5 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -577,12 +577,30 @@ out:
void e1000_down(struct e1000_adapter *adapter)
{
+ struct e1000_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
+ u32 rctl, tctl;
/* signal that we're down so the interrupt handler does not
* reschedule our watchdog timer */
set_bit(__E1000_DOWN, &adapter->flags);
+ /* disable receives in the hardware */
+ rctl = er32(RCTL);
+ ew32(RCTL, rctl & ~E1000_RCTL_EN);
+ /* flush and sleep below */
+
+ /* can be netif_tx_disable when NETIF_F_LLTX is removed */
+ netif_stop_queue(netdev);
+
+ /* disable transmits in the hardware */
+ tctl = er32(TCTL);
+ tctl &= ~E1000_TCTL_EN;
+ ew32(TCTL, tctl);
+ /* flush both disables and wait for them to finish */
+ E1000_WRITE_FLUSH();
+ msleep(10);
+
napi_disable(&adapter->napi);
e1000_irq_disable(adapter);
@@ -595,7 +613,6 @@ void e1000_down(struct e1000_adapter *adapter)
adapter->link_speed = 0;
adapter->link_duplex = 0;
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
e1000_reset(adapter);
e1000_clean_all_tx_rings(adapter);
@@ -1048,8 +1065,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
- netdev->features |= NETIF_F_LLTX;
-
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_TSO6;
netdev->vlan_features |= NETIF_F_HW_CSUM;
@@ -1368,8 +1383,6 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
return -ENOMEM;
}
- spin_lock_init(&adapter->tx_queue_lock);
-
/* Explicitly disable IRQ since the NIC can be in any state. */
e1000_irq_disable(adapter);
@@ -1624,7 +1637,6 @@ setup_tx_desc_die:
txdr->next_to_use = 0;
txdr->next_to_clean = 0;
- spin_lock_init(&txdr->tx_lock);
return 0;
}
@@ -1882,8 +1894,6 @@ int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
* e1000_setup_rctl - configure the receive control registers
* @adapter: Board private structure
**/
-#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
- (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
static void e1000_setup_rctl(struct e1000_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
@@ -2056,17 +2066,14 @@ void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
struct e1000_buffer *buffer_info)
{
- if (buffer_info->dma) {
- pci_unmap_page(adapter->pdev,
- buffer_info->dma,
- buffer_info->length,
- PCI_DMA_TODEVICE);
- buffer_info->dma = 0;
- }
+ buffer_info->dma = 0;
if (buffer_info->skb) {
+ skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
+ DMA_TO_DEVICE);
dev_kfree_skb_any(buffer_info->skb);
buffer_info->skb = NULL;
}
+ buffer_info->time_stamp = 0;
/* buffer_info must be completely set up in the transmit path */
}
@@ -2865,11 +2872,11 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter,
return false;
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case cpu_to_be16(ETH_P_IP):
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
cmd_len |= E1000_TXD_CMD_TCP;
break;
- case __constant_htons(ETH_P_IPV6):
+ case cpu_to_be16(ETH_P_IPV6):
/* XXX not handling all IPV6 headers */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
cmd_len |= E1000_TXD_CMD_TCP;
@@ -2915,13 +2922,21 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
{
struct e1000_hw *hw = &adapter->hw;
struct e1000_buffer *buffer_info;
- unsigned int len = skb->len;
- unsigned int offset = 0, size, count = 0, i;
+ unsigned int len = skb_headlen(skb);
+ unsigned int offset, size, count = 0, i;
unsigned int f;
- len -= skb->data_len;
+ dma_addr_t *map;
i = tx_ring->next_to_use;
+ if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+ return 0;
+ }
+
+ map = skb_shinfo(skb)->dma_maps;
+ offset = 0;
+
while (len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, max_per_txd);
@@ -2956,18 +2971,18 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
size -= 4;
buffer_info->length = size;
- buffer_info->dma =
- pci_map_single(adapter->pdev,
- skb->data + offset,
- size,
- PCI_DMA_TODEVICE);
+ buffer_info->dma = map[0] + offset;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
len -= size;
offset += size;
count++;
- if (unlikely(++i == tx_ring->count)) i = 0;
+ if (len) {
+ i++;
+ if (unlikely(i == tx_ring->count))
+ i = 0;
+ }
}
for (f = 0; f < nr_frags; f++) {
@@ -2975,9 +2990,13 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
frag = &skb_shinfo(skb)->frags[f];
len = frag->size;
- offset = frag->page_offset;
+ offset = 0;
while (len) {
+ i++;
+ if (unlikely(i == tx_ring->count))
+ i = 0;
+
buffer_info = &tx_ring->buffer_info[i];
size = min(len, max_per_txd);
/* Workaround for premature desc write-backs
@@ -2993,23 +3012,16 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
size -= 4;
buffer_info->length = size;
- buffer_info->dma =
- pci_map_page(adapter->pdev,
- frag->page,
- offset,
- size,
- PCI_DMA_TODEVICE);
+ buffer_info->dma = map[f + 1] + offset;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
len -= size;
offset += size;
count++;
- if (unlikely(++i == tx_ring->count)) i = 0;
}
}
- i = (i == 0) ? tx_ring->count - 1 : i - 1;
tx_ring->buffer_info[i].skb = skb;
tx_ring->buffer_info[first].next_to_watch = i;
@@ -3185,7 +3197,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
unsigned int tx_flags = 0;
unsigned int len = skb->len - skb->data_len;
- unsigned long flags;
unsigned int nr_frags;
unsigned int mss;
int count = 0;
@@ -3290,22 +3301,15 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
(hw->mac_type == e1000_82573))
e1000_transfer_dhcp_info(adapter, skb);
- if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags))
- /* Collision - tell upper layer to requeue */
- return NETDEV_TX_LOCKED;
-
/* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time */
- if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+ if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
return NETDEV_TX_BUSY;
- }
if (unlikely(hw->mac_type == e1000_82547)) {
if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
netif_stop_queue(netdev);
mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_BUSY;
}
}
@@ -3320,7 +3324,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tso = e1000_tso(adapter, tx_ring, skb);
if (tso < 0) {
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
}
@@ -3336,16 +3339,21 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (likely(skb->protocol == htons(ETH_P_IP)))
tx_flags |= E1000_TX_FLAGS_IPV4;
- e1000_tx_queue(adapter, tx_ring, tx_flags,
- e1000_tx_map(adapter, tx_ring, skb, first,
- max_per_txd, nr_frags, mss));
+ count = e1000_tx_map(adapter, tx_ring, skb, first, max_per_txd,
+ nr_frags, mss);
- netdev->trans_start = jiffies;
+ if (count) {
+ e1000_tx_queue(adapter, tx_ring, tx_flags, count);
+ netdev->trans_start = jiffies;
+ /* Make sure there is space in the ring for the next send. */
+ e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
- /* Make sure there is space in the ring for the next send. */
- e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
+ } else {
+ dev_kfree_skb_any(skb);
+ tx_ring->buffer_info[first].time_stamp = 0;
+ tx_ring->next_to_use = first;
+ }
- spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
return NETDEV_TX_OK;
}
@@ -3687,12 +3695,12 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- if (likely(netif_rx_schedule_prep(&adapter->napi))) {
+ if (likely(napi_schedule_prep(&adapter->napi))) {
adapter->total_tx_bytes = 0;
adapter->total_tx_packets = 0;
adapter->total_rx_bytes = 0;
adapter->total_rx_packets = 0;
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
} else
e1000_irq_enable(adapter);
@@ -3747,16 +3755,18 @@ static irqreturn_t e1000_intr(int irq, void *data)
ew32(IMC, ~0);
E1000_WRITE_FLUSH();
}
- if (likely(netif_rx_schedule_prep(&adapter->napi))) {
+ if (likely(napi_schedule_prep(&adapter->napi))) {
adapter->total_tx_bytes = 0;
adapter->total_tx_packets = 0;
adapter->total_rx_bytes = 0;
adapter->total_rx_packets = 0;
- __netif_rx_schedule(&adapter->napi);
- } else
+ __napi_schedule(&adapter->napi);
+ } else {
/* this really should not happen! if it does it is basically a
* bug, but not a hard error, so enable ints and continue */
- e1000_irq_enable(adapter);
+ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ e1000_irq_enable(adapter);
+ }
return IRQ_HANDLED;
}
@@ -3773,28 +3783,21 @@ static int e1000_clean(struct napi_struct *napi, int budget)
adapter = netdev_priv(poll_dev);
- /* e1000_clean is called per-cpu. This lock protects
- * tx_ring[0] from being cleaned by multiple cpus
- * simultaneously. A failure obtaining the lock means
- * tx_ring[0] is currently being cleaned anyway. */
- if (spin_trylock(&adapter->tx_queue_lock)) {
- tx_cleaned = e1000_clean_tx_irq(adapter,
- &adapter->tx_ring[0]);
- spin_unlock(&adapter->tx_queue_lock);
- }
+ tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[0]);
adapter->clean_rx(adapter, &adapter->rx_ring[0],
&work_done, budget);
- if (tx_cleaned)
+ if (!tx_cleaned)
work_done = budget;
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
if (likely(adapter->itr_setting & 3))
e1000_set_itr(adapter);
- netif_rx_complete(napi);
- e1000_irq_enable(adapter);
+ napi_complete(napi);
+ if (!test_bit(__E1000_DOWN, &adapter->flags))
+ e1000_irq_enable(adapter);
}
return work_done;
@@ -3813,15 +3816,16 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
struct e1000_buffer *buffer_info;
unsigned int i, eop;
unsigned int count = 0;
- bool cleaned = false;
+ bool cleaned;
unsigned int total_tx_bytes=0, total_tx_packets=0;
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
- while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
- for (cleaned = false; !cleaned; ) {
+ while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+ (count < tx_ring->count)) {
+ for (cleaned = false; !cleaned; count++) {
tx_desc = E1000_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
cleaned = (i == eop);
@@ -3844,10 +3848,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
-#define E1000_TX_WEIGHT 64
- /* weight of a sort for tx, to avoid endless transmit cleanup */
- if (count++ == E1000_TX_WEIGHT)
- break;
}
tx_ring->next_to_clean = i;
@@ -3869,8 +3869,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
/* Detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i */
adapter->detect_tx_hung = false;
- if (tx_ring->buffer_info[eop].dma &&
- time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
+ if (tx_ring->buffer_info[i].time_stamp &&
+ time_after(jiffies, tx_ring->buffer_info[i].time_stamp +
(adapter->tx_timeout_factor * HZ))
&& !(er32(STATUS) & E1000_STATUS_TXOFF)) {
@@ -3892,7 +3892,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
readl(hw->hw_addr + tx_ring->tdt),
tx_ring->next_to_use,
tx_ring->next_to_clean,
- tx_ring->buffer_info[eop].time_stamp,
+ tx_ring->buffer_info[i].time_stamp,
eop,
jiffies,
eop_desc->upper.fields.status);
@@ -3903,7 +3903,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
adapter->total_tx_packets += total_tx_packets;
adapter->net_stats.tx_bytes += total_tx_bytes;
adapter->net_stats.tx_packets += total_tx_packets;
- return cleaned;
+ return (count < tx_ring->count);
}
/**
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 0890162953e9..6c01a2072c87 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -40,6 +40,7 @@
* 82573E Gigabit Ethernet Controller (Copper)
* 82573L Gigabit Ethernet Controller
* 82574L Gigabit Network Connection
+ * 82583V Gigabit Network Connection
*/
#include <linux/netdevice.h>
@@ -61,6 +62,7 @@
static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw);
static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw);
+static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw);
static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
@@ -99,6 +101,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
phy->type = e1000_phy_m88;
break;
case e1000_82574:
+ case e1000_82583:
phy->type = e1000_phy_bm;
break;
default:
@@ -121,6 +124,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
return -E1000_ERR_PHY;
break;
case e1000_82574:
+ case e1000_82583:
if (phy->id != BME1000_E_PHY_ID_R2)
return -E1000_ERR_PHY;
break;
@@ -164,6 +168,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
switch (hw->mac.type) {
case e1000_82573:
case e1000_82574:
+ case e1000_82583:
if (((eecd >> 15) & 0x3) == 0x3) {
nvm->type = e1000_nvm_flash_hw;
nvm->word_size = 2048;
@@ -250,7 +255,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
case e1000_media_type_internal_serdes:
func->setup_physical_interface =
e1000_setup_fiber_serdes_link_82571;
- func->check_for_link = e1000e_check_for_serdes_link;
+ func->check_for_link = e1000_check_for_serdes_link_82571;
func->get_link_up_info =
e1000e_get_speed_and_duplex_fiber_serdes;
break;
@@ -261,6 +266,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
switch (hw->mac.type) {
case e1000_82574:
+ case e1000_82583:
func->check_mng_mode = e1000_check_mng_mode_82574;
func->led_on = e1000_led_on_82574;
break;
@@ -374,6 +380,7 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
return e1000e_get_phy_id(hw);
break;
case e1000_82574:
+ case e1000_82583:
ret_val = e1e_rphy(hw, PHY_ID1, &phy_id);
if (ret_val)
return ret_val;
@@ -463,8 +470,15 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
if (ret_val)
return ret_val;
- if (hw->mac.type != e1000_82573 && hw->mac.type != e1000_82574)
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
+ break;
+ default:
ret_val = e1000e_acquire_nvm(hw);
+ break;
+ }
if (ret_val)
e1000_put_hw_semaphore_82571(hw);
@@ -504,6 +518,7 @@ static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
switch (hw->mac.type) {
case e1000_82573:
case e1000_82574:
+ case e1000_82583:
ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data);
break;
case e1000_82571:
@@ -778,7 +793,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
* Must acquire the MDIO ownership before MAC reset.
* Ownership defaults to firmware after a reset.
*/
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
extcnf_ctrl = er32(EXTCNF_CTRL);
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
@@ -794,6 +812,9 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
msleep(2);
i++;
} while (i < MDIO_OWNERSHIP_TIMEOUT);
+ break;
+ default:
+ break;
}
ctrl = er32(CTRL);
@@ -819,8 +840,16 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
* Need to wait for Phy configuration completion before accessing
* NVM and Phy.
*/
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574)
+
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
msleep(25);
+ break;
+ default:
+ break;
+ }
/* Clear any pending interrupt events. */
ew32(IMC, 0xffffffff);
@@ -830,6 +859,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
hw->dev_spec.e82571.alt_mac_addr_is_present)
e1000e_set_laa_state_82571(hw, true);
+ /* Reinitialize the 82571 serdes link state machine */
+ if (hw->phy.media_type == e1000_media_type_internal_serdes)
+ hw->mac.serdes_link_state = e1000_serdes_link_down;
+
return 0;
}
@@ -886,17 +919,22 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
ew32(TXDCTL(0), reg_data);
/* ...for both queues. */
- if (mac->type != e1000_82573 && mac->type != e1000_82574) {
+ switch (mac->type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
+ e1000e_enable_tx_pkt_filtering(hw);
+ reg_data = er32(GCR);
+ reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
+ ew32(GCR, reg_data);
+ break;
+ default:
reg_data = er32(TXDCTL(1));
reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
E1000_TXDCTL_FULL_TX_DESC_WB |
E1000_TXDCTL_COUNT_DESC;
ew32(TXDCTL(1), reg_data);
- } else {
- e1000e_enable_tx_pkt_filtering(hw);
- reg_data = er32(GCR);
- reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
- ew32(GCR, reg_data);
+ break;
}
/*
@@ -961,18 +999,30 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
}
/* Device Control */
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
reg = er32(CTRL);
reg &= ~(1 << 29);
ew32(CTRL, reg);
+ break;
+ default:
+ break;
}
/* Extended Device Control */
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
reg = er32(CTRL_EXT);
reg &= ~(1 << 23);
reg |= (1 << 22);
ew32(CTRL_EXT, reg);
+ break;
+ default:
+ break;
}
if (hw->mac.type == e1000_82571) {
@@ -980,9 +1030,23 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
reg |= E1000_PBA_ECC_CORR_EN;
ew32(PBA_ECC, reg);
}
+ /*
+ * Workaround for hardware errata.
+ * Ensure that DMA Dynamic Clock gating is disabled on 82571 and 82572
+ */
+
+ if ((hw->mac.type == e1000_82571) ||
+ (hw->mac.type == e1000_82572)) {
+ reg = er32(CTRL_EXT);
+ reg &= ~E1000_CTRL_EXT_DMA_DYN_CLK_EN;
+ ew32(CTRL_EXT, reg);
+ }
+
/* PCI-Ex Control Registers */
- if (hw->mac.type == e1000_82574) {
+ switch (hw->mac.type) {
+ case e1000_82574:
+ case e1000_82583:
reg = er32(GCR);
reg |= (1 << 22);
ew32(GCR, reg);
@@ -990,6 +1054,9 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
reg = er32(GCR2);
reg |= 1;
ew32(GCR2, reg);
+ break;
+ default:
+ break;
}
return;
@@ -1009,7 +1076,10 @@ void e1000e_clear_vfta(struct e1000_hw *hw)
u32 vfta_offset = 0;
u32 vfta_bit_in_reg = 0;
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
if (hw->mng_cookie.vlan_id != 0) {
/*
* The VFTA is a 4096b bit-field, each identifying
@@ -1024,6 +1094,9 @@ void e1000e_clear_vfta(struct e1000_hw *hw)
vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id &
E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
}
+ break;
+ default:
+ break;
}
for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
/*
@@ -1122,9 +1195,16 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw)
* the default flow control setting, so we explicitly
* set it to full.
*/
- if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) &&
- hw->fc.requested_mode == e1000_fc_default)
- hw->fc.requested_mode = e1000_fc_full;
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
+ if (hw->fc.requested_mode == e1000_fc_default)
+ hw->fc.requested_mode = e1000_fc_full;
+ break;
+ default:
+ break;
+ }
return e1000e_setup_link(hw);
}
@@ -1203,6 +1283,131 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
}
/**
+ * e1000_check_for_serdes_link_82571 - Check for link (Serdes)
+ * @hw: pointer to the HW structure
+ *
+ * Checks for link up on the hardware. If link is not up and we have
+ * a signal, then we need to force link up.
+ **/
+static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
+{
+ struct e1000_mac_info *mac = &hw->mac;
+ u32 rxcw;
+ u32 ctrl;
+ u32 status;
+ s32 ret_val = 0;
+
+ ctrl = er32(CTRL);
+ status = er32(STATUS);
+ rxcw = er32(RXCW);
+
+ if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) {
+
+ /* Receiver is synchronized with no invalid bits. */
+ switch (mac->serdes_link_state) {
+ case e1000_serdes_link_autoneg_complete:
+ if (!(status & E1000_STATUS_LU)) {
+ /*
+ * We have lost link, retry autoneg before
+ * reporting link failure
+ */
+ mac->serdes_link_state =
+ e1000_serdes_link_autoneg_progress;
+ hw_dbg(hw, "AN_UP -> AN_PROG\n");
+ }
+ break;
+
+ case e1000_serdes_link_forced_up:
+ /*
+ * If we are receiving /C/ ordered sets, re-enable
+ * auto-negotiation in the TXCW register and disable
+ * forced link in the Device Control register in an
+ * attempt to auto-negotiate with our link partner.
+ */
+ if (rxcw & E1000_RXCW_C) {
+ /* Enable autoneg, and unforce link up */
+ ew32(TXCW, mac->txcw);
+ ew32(CTRL,
+ (ctrl & ~E1000_CTRL_SLU));
+ mac->serdes_link_state =
+ e1000_serdes_link_autoneg_progress;
+ hw_dbg(hw, "FORCED_UP -> AN_PROG\n");
+ }
+ break;
+
+ case e1000_serdes_link_autoneg_progress:
+ /*
+ * If the LU bit is set in the STATUS register,
+ * autoneg has completed sucessfully. If not,
+ * try foring the link because the far end may be
+ * available but not capable of autonegotiation.
+ */
+ if (status & E1000_STATUS_LU) {
+ mac->serdes_link_state =
+ e1000_serdes_link_autoneg_complete;
+ hw_dbg(hw, "AN_PROG -> AN_UP\n");
+ } else {
+ /*
+ * Disable autoneg, force link up and
+ * full duplex, and change state to forced
+ */
+ ew32(TXCW,
+ (mac->txcw & ~E1000_TXCW_ANE));
+ ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
+ ew32(CTRL, ctrl);
+
+ /* Configure Flow Control after link up. */
+ ret_val =
+ e1000e_config_fc_after_link_up(hw);
+ if (ret_val) {
+ hw_dbg(hw, "Error config flow control\n");
+ break;
+ }
+ mac->serdes_link_state =
+ e1000_serdes_link_forced_up;
+ hw_dbg(hw, "AN_PROG -> FORCED_UP\n");
+ }
+ mac->serdes_has_link = true;
+ break;
+
+ case e1000_serdes_link_down:
+ default:
+ /* The link was down but the receiver has now gained
+ * valid sync, so lets see if we can bring the link
+ * up. */
+ ew32(TXCW, mac->txcw);
+ ew32(CTRL,
+ (ctrl & ~E1000_CTRL_SLU));
+ mac->serdes_link_state =
+ e1000_serdes_link_autoneg_progress;
+ hw_dbg(hw, "DOWN -> AN_PROG\n");
+ break;
+ }
+ } else {
+ if (!(rxcw & E1000_RXCW_SYNCH)) {
+ mac->serdes_has_link = false;
+ mac->serdes_link_state = e1000_serdes_link_down;
+ hw_dbg(hw, "ANYSTATE -> DOWN\n");
+ } else {
+ /*
+ * We have sync, and can tolerate one
+ * invalid (IV) codeword before declaring
+ * link down, so reread to look again
+ */
+ udelay(10);
+ rxcw = er32(RXCW);
+ if (rxcw & E1000_RXCW_IV) {
+ mac->serdes_link_state = e1000_serdes_link_down;
+ mac->serdes_has_link = false;
+ hw_dbg(hw, "ANYSTATE -> DOWN\n");
+ }
+ }
+ }
+
+ return ret_val;
+}
+
+/**
* e1000_valid_led_default_82571 - Verify a valid default LED config
* @hw: pointer to the HW structure
* @data: pointer to the NVM (EEPROM)
@@ -1220,11 +1425,19 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data)
return ret_val;
}
- if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) &&
- *data == ID_LED_RESERVED_F746)
- *data = ID_LED_DEFAULT_82573;
- else if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
- *data = ID_LED_DEFAULT;
+ switch (hw->mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
+ if (*data == ID_LED_RESERVED_F746)
+ *data = ID_LED_DEFAULT_82573;
+ break;
+ default:
+ if (*data == ID_LED_RESERVED_0000 ||
+ *data == ID_LED_RESERVED_FFFF)
+ *data = ID_LED_DEFAULT;
+ break;
+ }
return 0;
}
@@ -1517,3 +1730,19 @@ struct e1000_info e1000_82574_info = {
.nvm_ops = &e82571_nvm_ops,
};
+struct e1000_info e1000_82583_info = {
+ .mac = e1000_82583,
+ .flags = FLAG_HAS_HW_VLAN_FILTER
+ | FLAG_HAS_WOL
+ | FLAG_APME_IN_CTRL3
+ | FLAG_RX_CSUM_ENABLED
+ | FLAG_HAS_SMART_POWER_DOWN
+ | FLAG_HAS_AMT
+ | FLAG_HAS_CTRLEXT_ON_LOAD,
+ .pba = 20,
+ .get_variants = e1000_get_variants_82571,
+ .mac_ops = &e82571_mac_ops,
+ .phy_ops = &e82_phy_ops_bm,
+ .nvm_ops = &e82571_nvm_ops,
+};
+
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index e6caf29d4252..243aa499fe90 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -69,6 +69,7 @@
#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
+#define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
#define E1000_CTRL_EXT_EIAME 0x01000000
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 37bcb190eef8..f37360aa12a8 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -101,6 +101,7 @@ enum e1000_boards {
board_82572,
board_82573,
board_82574,
+ board_82583,
board_80003es2lan,
board_ich8lan,
board_ich9lan,
@@ -195,8 +196,6 @@ struct e1000_adapter {
u16 link_duplex;
u16 eeprom_vers;
- spinlock_t tx_queue_lock; /* prevent concurrent tail updates */
-
/* track device up/down/testing state */
unsigned long state;
@@ -401,6 +400,7 @@ extern struct e1000_info e1000_82571_info;
extern struct e1000_info e1000_82572_info;
extern struct e1000_info e1000_82573_info;
extern struct e1000_info e1000_82574_info;
+extern struct e1000_info e1000_82583_info;
extern struct e1000_info e1000_ich8_info;
extern struct e1000_info e1000_ich9_info;
extern struct e1000_info e1000_ich10_info;
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index e48956d924b0..4d25ede88369 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -790,6 +790,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
break;
case e1000_82573:
case e1000_82574:
+ case e1000_82583:
case e1000_ich8lan:
case e1000_ich9lan:
case e1000_ich10lan:
@@ -1589,7 +1590,7 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data)
*data = 0;
if (hw->phy.media_type == e1000_media_type_internal_serdes) {
int i = 0;
- hw->mac.serdes_has_link = 0;
+ hw->mac.serdes_has_link = false;
/*
* On some blade server designs, link establishment
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 2d4ce0492df0..d8b82296f41e 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -339,6 +339,8 @@ enum e1e_registers {
#define E1000_DEV_ID_82573E_IAMT 0x108C
#define E1000_DEV_ID_82573L 0x109A
#define E1000_DEV_ID_82574L 0x10D3
+#define E1000_DEV_ID_82574LA 0x10F6
+#define E1000_DEV_ID_82583V 0x150C
#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
@@ -376,6 +378,7 @@ enum e1000_mac_type {
e1000_82572,
e1000_82573,
e1000_82574,
+ e1000_82583,
e1000_80003es2lan,
e1000_ich8lan,
e1000_ich9lan,
@@ -459,6 +462,13 @@ enum e1000_smart_speed {
e1000_smart_speed_off
};
+enum e1000_serdes_link_state {
+ e1000_serdes_link_down = 0,
+ e1000_serdes_link_autoneg_progress,
+ e1000_serdes_link_autoneg_complete,
+ e1000_serdes_link_forced_up
+};
+
/* Receive Descriptor */
struct e1000_rx_desc {
__le64 buffer_addr; /* Address of the descriptor's data buffer */
@@ -787,6 +797,7 @@ struct e1000_mac_info {
bool in_ifs_mode;
bool serdes_has_link;
bool tx_pkt_filtering;
+ enum e1000_serdes_link_state serdes_link_state;
};
struct e1000_phy_info {
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index e415e81ecd3e..6d1aab6316ba 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -390,8 +390,6 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
}
static DEFINE_MUTEX(nvm_mutex);
-static pid_t nvm_owner_pid = -1;
-static char nvm_owner_name[TASK_COMM_LEN] = "";
/**
* e1000_acquire_swflag_ich8lan - Acquire software control flag
@@ -408,16 +406,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
might_sleep();
- if (!mutex_trylock(&nvm_mutex)) {
- WARN(1, KERN_ERR "e1000e mutex contention. Owned by process "
- "%s (pid %d), required by process %s (pid %d)\n",
- nvm_owner_name, nvm_owner_pid,
- current->comm, current->pid);
-
- mutex_lock(&nvm_mutex);
- }
- nvm_owner_pid = current->pid;
- strncpy(nvm_owner_name, current->comm, TASK_COMM_LEN);
+ mutex_lock(&nvm_mutex);
while (timeout) {
extcnf_ctrl = er32(EXTCNF_CTRL);
@@ -435,8 +424,6 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
hw_dbg(hw, "FW or HW has locked the resource for too long.\n");
extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
ew32(EXTCNF_CTRL, extcnf_ctrl);
- nvm_owner_pid = -1;
- strcpy(nvm_owner_name, "");
mutex_unlock(&nvm_mutex);
return -E1000_ERR_CONFIG;
}
@@ -460,8 +447,6 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
ew32(EXTCNF_CTRL, extcnf_ctrl);
- nvm_owner_pid = -1;
- strcpy(nvm_owner_name, "");
mutex_unlock(&nvm_mutex);
}
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 66741104ffd1..18a4f5902f3b 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -159,41 +159,6 @@ void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
}
/**
- * e1000_mta_set - Set multicast filter table address
- * @hw: pointer to the HW structure
- * @hash_value: determines the MTA register and bit to set
- *
- * The multicast table address is a register array of 32-bit registers.
- * The hash_value is used to determine what register the bit is in, the
- * current value is read, the new bit is OR'd in and the new value is
- * written back into the register.
- **/
-static void e1000_mta_set(struct e1000_hw *hw, u32 hash_value)
-{
- u32 hash_bit, hash_reg, mta;
-
- /*
- * The MTA is a register array of 32-bit registers. It is
- * treated like an array of (32*mta_reg_count) bits. We want to
- * set bit BitArray[hash_value]. So we figure out what register
- * the bit is in, read it, OR in the new bit, then write
- * back the new value. The (hw->mac.mta_reg_count - 1) serves as a
- * mask to bits 31:5 of the hash value which gives us the
- * register we're modifying. The hash bit within that register
- * is determined by the lower 5 bits of the hash value.
- */
- hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
- hash_bit = hash_value & 0x1F;
-
- mta = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg);
-
- mta |= (1 << hash_bit);
-
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg, mta);
- e1e_flush();
-}
-
-/**
* e1000_hash_mc_addr - Generate a multicast hash value
* @hw: pointer to the HW structure
* @mc_addr: pointer to a multicast address
@@ -281,8 +246,13 @@ void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count)
{
- u32 hash_value;
u32 i;
+ u32 *mcarray = kzalloc(hw->mac.mta_reg_count * sizeof(u32), GFP_ATOMIC);
+
+ if (!mcarray) {
+ printk(KERN_ERR "multicast array memory allocation failed\n");
+ return;
+ }
/*
* Load the first set of multicast addresses into the exact
@@ -302,20 +272,24 @@ void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
}
}
- /* Clear the old settings from the MTA */
- hw_dbg(hw, "Clearing MTA\n");
- for (i = 0; i < hw->mac.mta_reg_count; i++) {
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
- e1e_flush();
- }
-
/* Load any remaining multicast addresses into the hash table. */
for (; mc_addr_count > 0; mc_addr_count--) {
+ u32 hash_value, hash_reg, hash_bit, mta;
hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
hw_dbg(hw, "Hash value = 0x%03X\n", hash_value);
- e1000_mta_set(hw, hash_value);
+ hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
+ hash_bit = hash_value & 0x1F;
+ mta = (1 << hash_bit);
+ mcarray[hash_reg] |= mta;
mc_addr_list += ETH_ALEN;
}
+
+ /* write the hash table completely */
+ for (i = 0; i < hw->mac.mta_reg_count; i++)
+ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, mcarray[i]);
+
+ e1e_flush();
+ kfree(mcarray);
}
/**
@@ -501,7 +475,7 @@ s32 e1000e_check_for_fiber_link(struct e1000_hw *hw)
ew32(TXCW, mac->txcw);
ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
- mac->serdes_has_link = 1;
+ mac->serdes_has_link = true;
}
return 0;
@@ -566,7 +540,7 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
ew32(TXCW, mac->txcw);
ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
- mac->serdes_has_link = 1;
+ mac->serdes_has_link = true;
} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
/*
* If we force link for non-auto-negotiation switch, check
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 91817d0afcaf..bfb2d6c85c54 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -44,10 +44,11 @@
#include <linux/cpu.h>
#include <linux/smp.h>
#include <linux/pm_qos_params.h>
+#include <linux/aer.h>
#include "e1000.h"
-#define DRV_VERSION "0.3.3.3-k6"
+#define DRV_VERSION "0.3.3.4-k4"
char e1000e_driver_name[] = "e1000e";
const char e1000e_driver_version[] = DRV_VERSION;
@@ -56,6 +57,7 @@ static const struct e1000_info *e1000_info_tbl[] = {
[board_82572] = &e1000_82572_info,
[board_82573] = &e1000_82573_info,
[board_82574] = &e1000_82574_info,
+ [board_82583] = &e1000_82583_info,
[board_80003es2lan] = &e1000_es2_info,
[board_ich8lan] = &e1000_ich8_info,
[board_ich9lan] = &e1000_ich9_info,
@@ -99,8 +101,8 @@ static void e1000_receive_skb(struct e1000_adapter *adapter,
skb->protocol = eth_type_trans(skb, netdev);
if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- le16_to_cpu(vlan));
+ vlan_gro_receive(&adapter->napi, adapter->vlgrp,
+ le16_to_cpu(vlan), skb);
else
napi_gro_receive(&adapter->napi, skb);
}
@@ -565,15 +567,14 @@ next_desc:
static void e1000_put_txbuf(struct e1000_adapter *adapter,
struct e1000_buffer *buffer_info)
{
- if (buffer_info->dma) {
- pci_unmap_page(adapter->pdev, buffer_info->dma,
- buffer_info->length, PCI_DMA_TODEVICE);
- buffer_info->dma = 0;
- }
+ buffer_info->dma = 0;
if (buffer_info->skb) {
+ skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
+ DMA_TO_DEVICE);
dev_kfree_skb_any(buffer_info->skb);
buffer_info->skb = NULL;
}
+ buffer_info->time_stamp = 0;
}
static void e1000_print_tx_hang(struct e1000_adapter *adapter)
@@ -620,15 +621,16 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
struct e1000_buffer *buffer_info;
unsigned int i, eop;
unsigned int count = 0;
- bool cleaned = 0;
+ bool cleaned;
unsigned int total_tx_bytes = 0, total_tx_packets = 0;
i = tx_ring->next_to_clean;
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
- while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
- for (cleaned = 0; !cleaned; ) {
+ while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+ (count < tx_ring->count)) {
+ for (cleaned = 0; !cleaned; count++) {
tx_desc = E1000_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
cleaned = (i == eop);
@@ -654,10 +656,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC(*tx_ring, eop);
-#define E1000_TX_WEIGHT 64
- /* weight of a sort for tx, to avoid endless transmit cleanup */
- if (count++ == E1000_TX_WEIGHT)
- break;
}
tx_ring->next_to_clean = i;
@@ -678,13 +676,11 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
}
if (adapter->detect_tx_hung) {
- /*
- * Detect a transmit hang in hardware, this serializes the
- * check with the clearing of time_stamp and movement of i
- */
+ /* Detect a transmit hang in hardware, this serializes the
+ * check with the clearing of time_stamp and movement of i */
adapter->detect_tx_hung = 0;
- if (tx_ring->buffer_info[eop].dma &&
- time_after(jiffies, tx_ring->buffer_info[eop].time_stamp
+ if (tx_ring->buffer_info[i].time_stamp &&
+ time_after(jiffies, tx_ring->buffer_info[i].time_stamp
+ (adapter->tx_timeout_factor * HZ))
&& !(er32(STATUS) & E1000_STATUS_TXOFF)) {
e1000_print_tx_hang(adapter);
@@ -695,7 +691,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
adapter->total_tx_packets += total_tx_packets;
adapter->net_stats.tx_bytes += total_tx_bytes;
adapter->net_stats.tx_packets += total_tx_packets;
- return cleaned;
+ return (count < tx_ring->count);
}
/**
@@ -1152,7 +1148,7 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
* read ICR disables interrupts using IAM
*/
- if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+ if (icr & E1000_ICR_LSC) {
hw->mac.get_link_status = 1;
/*
* ICH8 workaround-- Call gig speed drop workaround on cable
@@ -1179,12 +1175,12 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- if (netif_rx_schedule_prep(&adapter->napi)) {
+ if (napi_schedule_prep(&adapter->napi)) {
adapter->total_tx_bytes = 0;
adapter->total_tx_packets = 0;
adapter->total_rx_bytes = 0;
adapter->total_rx_packets = 0;
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
}
return IRQ_HANDLED;
@@ -1218,7 +1214,7 @@ static irqreturn_t e1000_intr(int irq, void *data)
* IMC write
*/
- if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+ if (icr & E1000_ICR_LSC) {
hw->mac.get_link_status = 1;
/*
* ICH8 workaround-- Call gig speed drop workaround on cable
@@ -1246,12 +1242,12 @@ static irqreturn_t e1000_intr(int irq, void *data)
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- if (netif_rx_schedule_prep(&adapter->napi)) {
+ if (napi_schedule_prep(&adapter->napi)) {
adapter->total_tx_bytes = 0;
adapter->total_tx_packets = 0;
adapter->total_rx_bytes = 0;
adapter->total_rx_packets = 0;
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
}
return IRQ_HANDLED;
@@ -1265,7 +1261,8 @@ static irqreturn_t e1000_msix_other(int irq, void *data)
u32 icr = er32(ICR);
if (!(icr & E1000_ICR_INT_ASSERTED)) {
- ew32(IMS, E1000_IMS_OTHER);
+ if (!test_bit(__E1000_DOWN, &adapter->state))
+ ew32(IMS, E1000_IMS_OTHER);
return IRQ_NONE;
}
@@ -1282,7 +1279,8 @@ static irqreturn_t e1000_msix_other(int irq, void *data)
}
no_link_interrupt:
- ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
+ if (!test_bit(__E1000_DOWN, &adapter->state))
+ ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
return IRQ_HANDLED;
}
@@ -1320,10 +1318,10 @@ static irqreturn_t e1000_intr_msix_rx(int irq, void *data)
adapter->rx_ring->set_itr = 0;
}
- if (netif_rx_schedule_prep(&adapter->napi)) {
+ if (napi_schedule_prep(&adapter->napi)) {
adapter->total_rx_bytes = 0;
adapter->total_rx_packets = 0;
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
}
return IRQ_HANDLED;
}
@@ -1698,7 +1696,6 @@ int e1000e_setup_tx_resources(struct e1000_adapter *adapter)
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
- spin_lock_init(&adapter->tx_queue_lock);
return 0;
err:
@@ -2007,32 +2004,25 @@ static int e1000_clean(struct napi_struct *napi, int budget)
!(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
goto clean_rx;
- /*
- * e1000_clean is called per-cpu. This lock protects
- * tx_ring from being cleaned by multiple cpus
- * simultaneously. A failure obtaining the lock means
- * tx_ring is currently being cleaned anyway.
- */
- if (spin_trylock(&adapter->tx_queue_lock)) {
- tx_cleaned = e1000_clean_tx_irq(adapter);
- spin_unlock(&adapter->tx_queue_lock);
- }
+ tx_cleaned = e1000_clean_tx_irq(adapter);
clean_rx:
adapter->clean_rx(adapter, &work_done, budget);
- if (tx_cleaned)
+ if (!tx_cleaned)
work_done = budget;
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
if (adapter->itr_setting & 3)
e1000_set_itr(adapter);
- netif_rx_complete(napi);
- if (adapter->msix_entries)
- ew32(IMS, adapter->rx_ring->ims_val);
- else
- e1000_irq_enable(adapter);
+ napi_complete(napi);
+ if (!test_bit(__E1000_DOWN, &adapter->state)) {
+ if (adapter->msix_entries)
+ ew32(IMS, adapter->rx_ring->ims_val);
+ else
+ e1000_irq_enable(adapter);
+ }
}
return work_done;
@@ -2922,8 +2912,6 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
if (e1000_alloc_queues(adapter))
return -ENOMEM;
- spin_lock_init(&adapter->tx_queue_lock);
-
/* Explicitly disable IRQ since the NIC can be in any state. */
e1000_irq_disable(adapter);
@@ -3320,7 +3308,7 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
adapter->stats.algnerrc += er32(ALGNERRC);
adapter->stats.rxerrc += er32(RXERRC);
- if (hw->mac.type != e1000_82574)
+ if ((hw->mac.type != e1000_82574) && (hw->mac.type != e1000_82583))
adapter->stats.tncrs += er32(TNCRS);
adapter->stats.cexterr += er32(CEXTERR);
adapter->stats.tsctc += er32(TSCTC);
@@ -3777,23 +3765,30 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
unsigned int i;
u8 css;
u32 cmd_len = E1000_TXD_CMD_DEXT;
+ __be16 protocol;
if (skb->ip_summed != CHECKSUM_PARTIAL)
return 0;
- switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
+ protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+ else
+ protocol = skb->protocol;
+
+ switch (protocol) {
+ case cpu_to_be16(ETH_P_IP):
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
cmd_len |= E1000_TXD_CMD_TCP;
break;
- case __constant_htons(ETH_P_IPV6):
+ case cpu_to_be16(ETH_P_IPV6):
/* XXX not handling all IPV6 headers */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
cmd_len |= E1000_TXD_CMD_TCP;
break;
default:
if (unlikely(net_ratelimit()))
- e_warn("checksum_partial proto=%x!\n", skb->protocol);
+ e_warn("checksum_partial proto=%x!\n",
+ be16_to_cpu(protocol));
break;
}
@@ -3832,42 +3827,40 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
{
struct e1000_ring *tx_ring = adapter->tx_ring;
struct e1000_buffer *buffer_info;
- unsigned int len = skb->len - skb->data_len;
- unsigned int offset = 0, size, count = 0, i;
+ unsigned int len = skb_headlen(skb);
+ unsigned int offset, size, count = 0, i;
unsigned int f;
+ dma_addr_t *map;
i = tx_ring->next_to_use;
+ if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+ adapter->tx_dma_failed++;
+ return 0;
+ }
+
+ map = skb_shinfo(skb)->dma_maps;
+ offset = 0;
+
while (len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, max_per_txd);
- /* Workaround for premature desc write-backs
- * in TSO mode. Append 4-byte sentinel desc */
- if (mss && !nr_frags && size == len && size > 8)
- size -= 4;
-
buffer_info->length = size;
- /* set time_stamp *before* dma to help avoid a possible race */
buffer_info->time_stamp = jiffies;
- buffer_info->dma =
- pci_map_single(adapter->pdev,
- skb->data + offset,
- size,
- PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(adapter->pdev, buffer_info->dma)) {
- dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
- adapter->tx_dma_failed++;
- return -1;
- }
buffer_info->next_to_watch = i;
+ buffer_info->dma = map[0] + offset;
+ count++;
len -= size;
offset += size;
- count++;
- i++;
- if (i == tx_ring->count)
- i = 0;
+
+ if (len) {
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+ }
}
for (f = 0; f < nr_frags; f++) {
@@ -3875,49 +3868,27 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
frag = &skb_shinfo(skb)->frags[f];
len = frag->size;
- offset = frag->page_offset;
+ offset = 0;
while (len) {
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+
buffer_info = &tx_ring->buffer_info[i];
size = min(len, max_per_txd);
- /* Workaround for premature desc write-backs
- * in TSO mode. Append 4-byte sentinel desc */
- if (mss && f == (nr_frags-1) && size == len && size > 8)
- size -= 4;
buffer_info->length = size;
buffer_info->time_stamp = jiffies;
- buffer_info->dma =
- pci_map_page(adapter->pdev,
- frag->page,
- offset,
- size,
- PCI_DMA_TODEVICE);
- if (pci_dma_mapping_error(adapter->pdev,
- buffer_info->dma)) {
- dev_err(&adapter->pdev->dev,
- "TX DMA page map failed\n");
- adapter->tx_dma_failed++;
- return -1;
- }
-
buffer_info->next_to_watch = i;
+ buffer_info->dma = map[f + 1] + offset;
len -= size;
offset += size;
count++;
-
- i++;
- if (i == tx_ring->count)
- i = 0;
}
}
- if (i == 0)
- i = tx_ring->count - 1;
- else
- i--;
-
tx_ring->buffer_info[i].skb = skb;
tx_ring->buffer_info[first].next_to_watch = i;
@@ -4069,7 +4040,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
unsigned int tx_flags = 0;
unsigned int len = skb->len - skb->data_len;
- unsigned long irq_flags;
unsigned int nr_frags;
unsigned int mss;
int count = 0;
@@ -4138,18 +4108,12 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (adapter->hw.mac.tx_pkt_filtering)
e1000_transfer_dhcp_info(adapter, skb);
- if (!spin_trylock_irqsave(&adapter->tx_queue_lock, irq_flags))
- /* Collision - tell upper layer to requeue */
- return NETDEV_TX_LOCKED;
-
/*
* need: count + 2 desc gap to keep tail from touching
* head, otherwise try next time
*/
- if (e1000_maybe_stop_tx(netdev, count + 2)) {
- spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
+ if (e1000_maybe_stop_tx(netdev, count + 2))
return NETDEV_TX_BUSY;
- }
if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
tx_flags |= E1000_TX_FLAGS_VLAN;
@@ -4161,7 +4125,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tso = e1000_tso(adapter, skb);
if (tso < 0) {
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
return NETDEV_TX_OK;
}
@@ -4178,22 +4141,20 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if (skb->protocol == htons(ETH_P_IP))
tx_flags |= E1000_TX_FLAGS_IPV4;
+ /* if count is 0 then mapping error has occured */
count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
- if (count < 0) {
- /* handle pci_map_single() error in e1000_tx_map */
+ if (count) {
+ e1000_tx_queue(adapter, tx_flags, count);
+ netdev->trans_start = jiffies;
+ /* Make sure there is space in the ring for the next send. */
+ e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
+
+ } else {
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
- return NETDEV_TX_OK;
+ tx_ring->buffer_info[first].time_stamp = 0;
+ tx_ring->next_to_use = first;
}
- e1000_tx_queue(adapter, tx_flags, count);
-
- netdev->trans_start = jiffies;
-
- /* Make sure there is space in the ring for the next send. */
- e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
-
- spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
return NETDEV_TX_OK;
}
@@ -4543,6 +4504,14 @@ static int e1000_resume(struct pci_dev *pdev)
return err;
}
+ /* AER (Advanced Error Reporting) hooks */
+ err = pci_enable_pcie_error_reporting(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
+ "0x%x\n", err);
+ /* non-fatal, continue */
+ }
+
pci_set_master(pdev);
pci_enable_wake(pdev, PCI_D3hot, 0);
@@ -4637,24 +4606,29 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
int err;
+ pci_ers_result_t result;
e1000e_disable_l1aspm(pdev);
err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
- return PCI_ERS_RESULT_DISCONNECT;
- }
- pci_set_master(pdev);
- pci_restore_state(pdev);
+ result = PCI_ERS_RESULT_DISCONNECT;
+ } else {
+ pci_set_master(pdev);
+ pci_restore_state(pdev);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
- e1000e_reset(adapter);
- ew32(WUS, ~0);
+ e1000e_reset(adapter);
+ ew32(WUS, ~0);
+ result = PCI_ERS_RESULT_RECOVERED;
+ }
+
+ pci_cleanup_aer_uncorrect_error_status(pdev);
- return PCI_ERS_RESULT_RECOVERED;
+ return result;
}
/**
@@ -4922,12 +4896,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
- /*
- * We should not be using LLTX anymore, but we are still Tx faster with
- * it.
- */
- netdev->features |= NETIF_F_LLTX;
-
if (e1000e_enable_mng_pass_thru(&adapter->hw))
adapter->flags |= FLAG_MNG_PT_ENABLED;
@@ -5091,6 +5059,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
+ int err;
/*
* flush_scheduled work may reschedule our watchdog task, so
@@ -5125,6 +5094,12 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
free_netdev(netdev);
+ /* AER disable */
+ err = pci_disable_pcie_error_reporting(pdev);
+ if (err)
+ dev_err(&pdev->dev,
+ "pci_disable_pcie_error_reporting failed 0x%x\n", err);
+
pci_disable_device(pdev);
}
@@ -5156,6 +5131,8 @@ static struct pci_device_id e1000_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82574LA), board_82574 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82583V), board_82583 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
board_80003es2lan },
diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c
index b07ba1924de0..d2f6ee1a6290 100644
--- a/drivers/net/e2100.c
+++ b/drivers/net/e2100.c
@@ -216,13 +216,13 @@ static int __init e21_probe1(struct net_device *dev, int ioaddr)
printk(" %02X", station_addr[i]);
if (dev->irq < 2) {
- int irqlist[] = {15,11,10,12,5,9,3,4}, i;
- for (i = 0; i < 8; i++)
+ int irqlist[] = {15, 11, 10, 12, 5, 9, 3, 4};
+ for (i = 0; i < ARRAY_SIZE(irqlist); i++)
if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) {
dev->irq = irqlist[i];
break;
}
- if (i >= 8) {
+ if (i >= ARRAY_SIZE(irqlist)) {
printk(" unable to get IRQ %d.\n", dev->irq);
retval = -EAGAIN;
goto out;
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index e187c88ae145..cc2ab6412c73 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -739,6 +739,17 @@ static void __init eepro_print_info (struct net_device *dev)
static const struct ethtool_ops eepro_ethtool_ops;
+static const struct net_device_ops eepro_netdev_ops = {
+ .ndo_open = eepro_open,
+ .ndo_stop = eepro_close,
+ .ndo_start_xmit = eepro_send_packet,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_tx_timeout = eepro_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/* This is the real probe routine. Linux has a history of friendly device
probes on the ISA bus. A good device probe avoids doing writes, and
verifies that the correct device exists and functions. */
@@ -851,11 +862,7 @@ static int __init eepro_probe1(struct net_device *dev, int autoprobe)
}
}
- dev->open = eepro_open;
- dev->stop = eepro_close;
- dev->hard_start_xmit = eepro_send_packet;
- dev->set_multicast_list = &set_multicast_list;
- dev->tx_timeout = eepro_tx_timeout;
+ dev->netdev_ops = &eepro_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
dev->ethtool_ops = &eepro_ethtool_ops;
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index 9ff3f2f5e382..1686dca28748 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -1043,6 +1043,17 @@ static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf,
lp->last_tx = jiffies;
}
+static const struct net_device_ops eexp_netdev_ops = {
+ .ndo_open = eexp_open,
+ .ndo_stop = eexp_close,
+ .ndo_start_xmit = eexp_xmit,
+ .ndo_set_multicast_list = eexp_set_multicast,
+ .ndo_tx_timeout = eexp_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*
* Sanity check the suspected EtherExpress card
* Read hardware address, reset card, size memory and initialize buffer
@@ -1163,11 +1174,7 @@ static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr)
lp->rx_buf_start = TX_BUF_START + (lp->num_tx_bufs*TX_BUF_SIZE);
lp->width = buswidth;
- dev->open = eexp_open;
- dev->stop = eexp_close;
- dev->hard_start_xmit = eexp_xmit;
- dev->set_multicast_list = &eexp_set_multicast;
- dev->tx_timeout = eexp_timeout;
+ dev->netdev_ops = &eexp_netdev_ops;
dev->watchdog_timeo = 2*HZ;
return register_netdev(dev);
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 6271b9411ccf..6e317caf429c 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,7 +40,7 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0096"
+#define DRV_VERSION "EHEA_0100"
/* eHEA capability flags */
#define DLPAR_PORT_ADD_REM 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index dfe92264e825..ac0c5b438e0a 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -155,6 +155,8 @@ static void ehea_update_firmware_handles(void)
int num_fw_handles, k, l;
/* Determine number of handles */
+ mutex_lock(&ehea_fw_handles.lock);
+
list_for_each_entry(adapter, &adapter_list, list) {
num_adapters++;
@@ -176,15 +178,19 @@ static void ehea_update_firmware_handles(void)
if (num_fw_handles) {
arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL);
if (!arr)
- return; /* Keep the existing array */
+ goto out; /* Keep the existing array */
} else
goto out_update;
list_for_each_entry(adapter, &adapter_list, list) {
+ if (num_adapters == 0)
+ break;
+
for (k = 0; k < EHEA_MAX_PORTS; k++) {
struct ehea_port *port = adapter->port[k];
- if (!port || (port->state != EHEA_PORT_UP))
+ if (!port || (port->state != EHEA_PORT_UP)
+ || (num_ports == 0))
continue;
for (l = 0;
@@ -207,6 +213,7 @@ static void ehea_update_firmware_handles(void)
}
arr[i].adh = adapter->handle;
arr[i++].fwh = port->qp_eq->fw_handle;
+ num_ports--;
}
arr[i].adh = adapter->handle;
@@ -216,16 +223,20 @@ static void ehea_update_firmware_handles(void)
arr[i].adh = adapter->handle;
arr[i++].fwh = adapter->mr.handle;
}
+ num_adapters--;
}
out_update:
kfree(ehea_fw_handles.arr);
ehea_fw_handles.arr = arr;
ehea_fw_handles.num_entries = i;
+out:
+ mutex_unlock(&ehea_fw_handles.lock);
}
static void ehea_update_bcmc_registrations(void)
{
+ unsigned long flags;
struct ehea_bcmc_reg_entry *arr = NULL;
struct ehea_adapter *adapter;
struct ehea_mc_list *mc_entry;
@@ -233,6 +244,8 @@ static void ehea_update_bcmc_registrations(void)
int i = 0;
int k;
+ spin_lock_irqsave(&ehea_bcmc_regs.lock, flags);
+
/* Determine number of registrations */
list_for_each_entry(adapter, &adapter_list, list)
for (k = 0; k < EHEA_MAX_PORTS; k++) {
@@ -250,7 +263,7 @@ static void ehea_update_bcmc_registrations(void)
if (num_registrations) {
arr = kzalloc(num_registrations * sizeof(*arr), GFP_ATOMIC);
if (!arr)
- return; /* Keep the existing array */
+ goto out; /* Keep the existing array */
} else
goto out_update;
@@ -261,6 +274,9 @@ static void ehea_update_bcmc_registrations(void)
if (!port || (port->state != EHEA_PORT_UP))
continue;
+ if (num_registrations == 0)
+ goto out_update;
+
arr[i].adh = adapter->handle;
arr[i].port_id = port->logical_port_id;
arr[i].reg_type = EHEA_BCMC_BROADCAST |
@@ -272,9 +288,13 @@ static void ehea_update_bcmc_registrations(void)
arr[i].reg_type = EHEA_BCMC_BROADCAST |
EHEA_BCMC_VLANID_ALL;
arr[i++].macaddr = port->mac_addr;
+ num_registrations -= 2;
list_for_each_entry(mc_entry,
&port->mc_list->list, list) {
+ if (num_registrations == 0)
+ goto out_update;
+
arr[i].adh = adapter->handle;
arr[i].port_id = port->logical_port_id;
arr[i].reg_type = EHEA_BCMC_SCOPE_ALL |
@@ -288,6 +308,7 @@ static void ehea_update_bcmc_registrations(void)
EHEA_BCMC_MULTICAST |
EHEA_BCMC_VLANID_ALL;
arr[i++].macaddr = mc_entry->macaddr;
+ num_registrations -= 2;
}
}
}
@@ -296,6 +317,8 @@ out_update:
kfree(ehea_bcmc_regs.arr);
ehea_bcmc_regs.arr = arr;
ehea_bcmc_regs.num_entries = i;
+out:
+ spin_unlock_irqrestore(&ehea_bcmc_regs.lock, flags);
}
static struct net_device_stats *ehea_get_stats(struct net_device *dev)
@@ -308,7 +331,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev)
memset(stats, 0, sizeof(*stats));
- cb2 = kzalloc(PAGE_SIZE, GFP_ATOMIC);
+ cb2 = (void *)get_zeroed_page(GFP_ATOMIC);
if (!cb2) {
ehea_error("no mem for cb2");
goto out;
@@ -341,7 +364,7 @@ static struct net_device_stats *ehea_get_stats(struct net_device *dev)
stats->rx_packets = rx_packets;
out_herr:
- kfree(cb2);
+ free_page((unsigned long)cb2);
out:
return stats;
}
@@ -370,8 +393,6 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
EHEA_L_PKT_SIZE);
if (!skb_arr_rq1[index]) {
pr->rq1_skba.os_skbs = fill_wqes - i;
- ehea_error("%s: no mem for skb/%d wqes filled",
- dev->name, i);
break;
}
}
@@ -387,26 +408,19 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
ehea_update_rq1a(pr->qp, adder);
}
-static int ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a)
+static void ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a)
{
- int ret = 0;
struct sk_buff **skb_arr_rq1 = pr->rq1_skba.arr;
struct net_device *dev = pr->port->netdev;
int i;
for (i = 0; i < pr->rq1_skba.len; i++) {
skb_arr_rq1[i] = netdev_alloc_skb(dev, EHEA_L_PKT_SIZE);
- if (!skb_arr_rq1[i]) {
- ehea_error("%s: no mem for skb/%d wqes filled",
- dev->name, i);
- ret = -ENOMEM;
- goto out;
- }
+ if (!skb_arr_rq1[i])
+ break;
}
/* Ring doorbell */
ehea_update_rq1a(pr->qp, nr_rq1a);
-out:
- return ret;
}
static int ehea_refill_rq_def(struct ehea_port_res *pr,
@@ -435,10 +449,12 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr,
u64 tmp_addr;
struct sk_buff *skb = netdev_alloc_skb(dev, packet_size);
if (!skb) {
- ehea_error("%s: no mem for skb/%d wqes filled",
- pr->port->netdev->name, i);
q_skba->os_skbs = fill_wqes - i;
- ret = -ENOMEM;
+ if (q_skba->os_skbs == q_skba->len - 2) {
+ ehea_info("%s: rq%i ran dry - no mem for skb",
+ pr->port->netdev->name, rq_nr);
+ ret = -ENOMEM;
+ }
break;
}
skb_reserve(skb, NET_IP_ALIGN);
@@ -830,7 +846,7 @@ static int ehea_poll(struct napi_struct *napi, int budget)
while ((rx != budget) || force_irq) {
pr->poll_counter = 0;
force_irq = 0;
- netif_rx_complete(napi);
+ napi_complete(napi);
ehea_reset_cq_ep(pr->recv_cq);
ehea_reset_cq_ep(pr->send_cq);
ehea_reset_cq_n1(pr->recv_cq);
@@ -841,7 +857,7 @@ static int ehea_poll(struct napi_struct *napi, int budget)
if (!cqe && !cqe_skb)
return rx;
- if (!netif_rx_reschedule(napi))
+ if (!napi_reschedule(napi))
return rx;
cqe_skb = ehea_proc_cqes(pr, EHEA_POLL_MAX_CQES);
@@ -859,7 +875,7 @@ static void ehea_netpoll(struct net_device *dev)
int i;
for (i = 0; i < port->num_def_qps; i++)
- netif_rx_schedule(&port->port_res[i].napi);
+ napi_schedule(&port->port_res[i].napi);
}
#endif
@@ -867,7 +883,7 @@ static irqreturn_t ehea_recv_irq_handler(int irq, void *param)
{
struct ehea_port_res *pr = param;
- netif_rx_schedule(&pr->napi);
+ napi_schedule(&pr->napi);
return IRQ_HANDLED;
}
@@ -915,7 +931,7 @@ int ehea_sense_port_attr(struct ehea_port *port)
struct hcp_ehea_port_cb0 *cb0;
/* may be called via ehea_neq_tasklet() */
- cb0 = kzalloc(PAGE_SIZE, GFP_ATOMIC);
+ cb0 = (void *)get_zeroed_page(GFP_ATOMIC);
if (!cb0) {
ehea_error("no mem for cb0");
ret = -ENOMEM;
@@ -996,7 +1012,7 @@ int ehea_sense_port_attr(struct ehea_port *port)
out_free:
if (ret || netif_msg_probe(port))
ehea_dump(cb0, sizeof(*cb0), "ehea_sense_port_attr");
- kfree(cb0);
+ free_page((unsigned long)cb0);
out:
return ret;
}
@@ -1007,7 +1023,7 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed)
u64 hret;
int ret = 0;
- cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb4 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb4) {
ehea_error("no mem for cb4");
ret = -ENOMEM;
@@ -1075,7 +1091,7 @@ int ehea_set_portspeed(struct ehea_port *port, u32 port_speed)
if (!prop_carrier_state || (port->phy_link == EHEA_PHY_LINK_UP))
netif_carrier_on(port->netdev);
- kfree(cb4);
+ free_page((unsigned long)cb4);
out:
return ret;
}
@@ -1201,11 +1217,11 @@ static int ehea_fill_port_res(struct ehea_port_res *pr)
int ret;
struct ehea_qp_init_attr *init_attr = &pr->qp->init_attr;
- ret = ehea_init_fill_rq1(pr, init_attr->act_nr_rwqes_rq1
- - init_attr->act_nr_rwqes_rq2
- - init_attr->act_nr_rwqes_rq3 - 1);
+ ehea_init_fill_rq1(pr, init_attr->act_nr_rwqes_rq1
+ - init_attr->act_nr_rwqes_rq2
+ - init_attr->act_nr_rwqes_rq3 - 1);
- ret |= ehea_refill_rq2(pr, init_attr->act_nr_rwqes_rq2 - 1);
+ ret = ehea_refill_rq2(pr, init_attr->act_nr_rwqes_rq2 - 1);
ret |= ehea_refill_rq3(pr, init_attr->act_nr_rwqes_rq3 - 1);
@@ -1302,7 +1318,7 @@ static int ehea_configure_port(struct ehea_port *port)
struct hcp_ehea_port_cb0 *cb0;
ret = -ENOMEM;
- cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb0 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb0)
goto out;
@@ -1338,7 +1354,7 @@ static int ehea_configure_port(struct ehea_port *port)
ret = 0;
out_free:
- kfree(cb0);
+ free_page((unsigned long)cb0);
out:
return ret;
}
@@ -1748,7 +1764,7 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
goto out;
}
- cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb0 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb0) {
ehea_error("no mem for cb0");
ret = -ENOMEM;
@@ -1769,8 +1785,6 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
- spin_lock(&ehea_bcmc_regs.lock);
-
/* Deregister old MAC in pHYP */
if (port->state == EHEA_PORT_UP) {
ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
@@ -1791,9 +1805,8 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
out_upregs:
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
out_free:
- kfree(cb0);
+ free_page((unsigned long)cb0);
out:
return ret;
}
@@ -1817,7 +1830,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable)
if ((enable && port->promisc) || (!enable && !port->promisc))
return;
- cb7 = kzalloc(PAGE_SIZE, GFP_ATOMIC);
+ cb7 = (void *)get_zeroed_page(GFP_ATOMIC);
if (!cb7) {
ehea_error("no mem for cb7");
goto out;
@@ -1836,7 +1849,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable)
port->promisc = enable;
out:
- kfree(cb7);
+ free_page((unsigned long)cb7);
return;
}
@@ -1953,8 +1966,6 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
ehea_promiscuous(dev, 0);
- spin_lock(&ehea_bcmc_regs.lock);
-
if (dev->flags & IFF_ALLMULTI) {
ehea_allmulti(dev, 1);
goto out;
@@ -1984,7 +1995,6 @@ static void ehea_set_multicast_list(struct net_device *dev)
}
out:
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
return;
}
@@ -2217,7 +2227,7 @@ static void ehea_vlan_rx_register(struct net_device *dev,
port->vgrp = grp;
- cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb1 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb1) {
ehea_error("no mem for cb1");
goto out;
@@ -2228,7 +2238,7 @@ static void ehea_vlan_rx_register(struct net_device *dev,
if (hret != H_SUCCESS)
ehea_error("modify_ehea_port failed");
- kfree(cb1);
+ free_page((unsigned long)cb1);
out:
return;
}
@@ -2241,7 +2251,7 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
int index;
u64 hret;
- cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb1 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb1) {
ehea_error("no mem for cb1");
goto out;
@@ -2262,7 +2272,7 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
if (hret != H_SUCCESS)
ehea_error("modify_ehea_port failed");
out:
- kfree(cb1);
+ free_page((unsigned long)cb1);
return;
}
@@ -2276,7 +2286,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
vlan_group_set_device(port->vgrp, vid, NULL);
- cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb1 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb1) {
ehea_error("no mem for cb1");
goto out;
@@ -2297,7 +2307,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
if (hret != H_SUCCESS)
ehea_error("modify_ehea_port failed");
out:
- kfree(cb1);
+ free_page((unsigned long)cb1);
return;
}
@@ -2309,7 +2319,7 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp)
u64 dummy64 = 0;
struct hcp_modify_qp_cb0 *cb0;
- cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb0 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb0) {
ret = -ENOMEM;
goto out;
@@ -2372,7 +2382,7 @@ int ehea_activate_qp(struct ehea_adapter *adapter, struct ehea_qp *qp)
ret = 0;
out:
- kfree(cb0);
+ free_page((unsigned long)cb0);
return ret;
}
@@ -2465,8 +2475,6 @@ static int ehea_up(struct net_device *dev)
if (port->state == EHEA_PORT_UP)
return 0;
- mutex_lock(&ehea_fw_handles.lock);
-
ret = ehea_port_res_setup(port, port->num_def_qps,
port->num_add_tx_qps);
if (ret) {
@@ -2503,8 +2511,6 @@ static int ehea_up(struct net_device *dev)
}
}
- spin_lock(&ehea_bcmc_regs.lock);
-
ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
if (ret) {
ret = -EIO;
@@ -2526,10 +2532,7 @@ out:
ehea_info("Failed starting %s. ret=%i", dev->name, ret);
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
-
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return ret;
}
@@ -2579,9 +2582,6 @@ static int ehea_down(struct net_device *dev)
if (port->state == EHEA_PORT_DOWN)
return 0;
- mutex_lock(&ehea_fw_handles.lock);
-
- spin_lock(&ehea_bcmc_regs.lock);
ehea_drop_multicast_list(dev);
ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
@@ -2590,7 +2590,6 @@ static int ehea_down(struct net_device *dev)
port->state = EHEA_PORT_DOWN;
ehea_update_bcmc_registrations();
- spin_unlock(&ehea_bcmc_regs.lock);
ret = ehea_clean_all_portres(port);
if (ret)
@@ -2598,7 +2597,6 @@ static int ehea_down(struct net_device *dev)
dev->name, ret);
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return ret;
}
@@ -2664,7 +2662,7 @@ int ehea_stop_qps(struct net_device *dev)
u64 dummy64 = 0;
u16 dummy16 = 0;
- cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb0 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb0) {
ret = -ENOMEM;
goto out;
@@ -2716,7 +2714,7 @@ int ehea_stop_qps(struct net_device *dev)
ret = 0;
out:
- kfree(cb0);
+ free_page((unsigned long)cb0);
return ret;
}
@@ -2766,7 +2764,7 @@ int ehea_restart_qps(struct net_device *dev)
u64 dummy64 = 0;
u16 dummy16 = 0;
- cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb0 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb0) {
ret = -ENOMEM;
goto out;
@@ -2819,7 +2817,7 @@ int ehea_restart_qps(struct net_device *dev)
ehea_refill_rq3(pr, 0);
}
out:
- kfree(cb0);
+ free_page((unsigned long)cb0);
return ret;
}
@@ -2950,7 +2948,7 @@ int ehea_sense_adapter_attr(struct ehea_adapter *adapter)
u64 hret;
int ret;
- cb = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb) {
ret = -ENOMEM;
goto out;
@@ -2967,7 +2965,7 @@ int ehea_sense_adapter_attr(struct ehea_adapter *adapter)
ret = 0;
out_herr:
- kfree(cb);
+ free_page((unsigned long)cb);
out:
return ret;
}
@@ -2981,7 +2979,7 @@ int ehea_get_jumboframe_status(struct ehea_port *port, int *jumbo)
*jumbo = 0;
/* (Try to) enable *jumbo frames */
- cb4 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ cb4 = (void *)get_zeroed_page(GFP_KERNEL);
if (!cb4) {
ehea_error("no mem for cb4");
ret = -ENOMEM;
@@ -3009,7 +3007,7 @@ int ehea_get_jumboframe_status(struct ehea_port *port, int *jumbo)
} else
ret = -EINVAL;
- kfree(cb4);
+ free_page((unsigned long)cb4);
}
out:
return ret;
@@ -3040,7 +3038,7 @@ static struct device *ehea_register_port(struct ehea_port *port,
port->ofdev.dev.parent = &port->adapter->ofdev->dev;
port->ofdev.dev.bus = &ibmebus_bus_type;
- sprintf(port->ofdev.dev.bus_id, "port%d", port_name_cnt++);
+ dev_set_name(&port->ofdev.dev, "port%d", port_name_cnt++);
port->ofdev.dev.release = logical_port_release;
ret = of_device_register(&port->ofdev);
@@ -3069,6 +3067,22 @@ static void ehea_unregister_port(struct ehea_port *port)
of_device_unregister(&port->ofdev);
}
+static const struct net_device_ops ehea_netdev_ops = {
+ .ndo_open = ehea_open,
+ .ndo_stop = ehea_stop,
+ .ndo_start_xmit = ehea_start_xmit,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ehea_netpoll,
+#endif
+ .ndo_get_stats = ehea_get_stats,
+ .ndo_set_mac_address = ehea_set_mac_addr,
+ .ndo_set_multicast_list = ehea_set_multicast_list,
+ .ndo_change_mtu = ehea_change_mtu,
+ .ndo_vlan_rx_register = ehea_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = ehea_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = ehea_vlan_rx_kill_vid
+};
+
struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
u32 logical_port_id,
struct device_node *dn)
@@ -3121,19 +3135,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
/* initialize net_device structure */
memcpy(dev->dev_addr, &port->mac_addr, ETH_ALEN);
- dev->open = ehea_open;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ehea_netpoll;
-#endif
- dev->stop = ehea_stop;
- dev->hard_start_xmit = ehea_start_xmit;
- dev->get_stats = ehea_get_stats;
- dev->set_multicast_list = ehea_set_multicast_list;
- dev->set_mac_address = ehea_set_mac_addr;
- dev->change_mtu = ehea_change_mtu;
- dev->vlan_rx_register = ehea_vlan_rx_register;
- dev->vlan_rx_add_vid = ehea_vlan_rx_add_vid;
- dev->vlan_rx_kill_vid = ehea_vlan_rx_kill_vid;
+ dev->netdev_ops = &ehea_netdev_ops;
+ ehea_set_ethtool_ops(dev);
+
dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO
| NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX
| NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER
@@ -3142,7 +3146,6 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
INIT_WORK(&port->reset_task, ehea_reset_port);
- ehea_set_ethtool_ops(dev);
ret = register_netdev(dev);
if (ret) {
@@ -3370,7 +3373,6 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
ehea_error("Invalid ibmebus device probed");
return -EINVAL;
}
- mutex_lock(&ehea_fw_handles.lock);
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
if (!adapter) {
@@ -3450,11 +3452,12 @@ out_kill_eq:
ehea_destroy_eq(adapter->neq);
out_free_ad:
+ list_del(&adapter->list);
kfree(adapter);
out:
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
+
return ret;
}
@@ -3473,8 +3476,6 @@ static int __devexit ehea_remove(struct of_device *dev)
flush_scheduled_work();
- mutex_lock(&ehea_fw_handles.lock);
-
ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
tasklet_kill(&adapter->neq_tasklet);
@@ -3484,7 +3485,6 @@ static int __devexit ehea_remove(struct of_device *dev)
kfree(adapter);
ehea_update_firmware_handles();
- mutex_unlock(&ehea_fw_handles.lock);
return 0;
}
@@ -3518,12 +3518,14 @@ static int ehea_mem_notifier(struct notifier_block *nb,
/* Readd canceled memory block */
case MEM_ONLINE:
ehea_info("memory is going online");
+ set_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages))
return NOTIFY_BAD;
ehea_rereg_mrs(NULL);
break;
case MEM_GOING_OFFLINE:
ehea_info("memory is going offline");
+ set_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages))
return NOTIFY_BAD;
ehea_rereg_mrs(NULL);
@@ -3531,6 +3533,9 @@ static int ehea_mem_notifier(struct notifier_block *nb,
default:
break;
}
+
+ ehea_update_firmware_handles();
+
return NOTIFY_OK;
}
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 49d766ebbcf4..3747457f5e69 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -1005,7 +1005,7 @@ void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle)
unsigned long ret;
u64 *rblock;
- rblock = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ rblock = (void *)get_zeroed_page(GFP_KERNEL);
if (!rblock) {
ehea_error("Cannot allocate rblock memory.");
return;
@@ -1022,5 +1022,5 @@ void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle)
else
ehea_error("Error data could not be fetched: %llX", res_handle);
- kfree(rblock);
+ free_page((unsigned long)rblock);
}
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index a832cc5d6a1e..c26cea0b300e 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -33,7 +33,7 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco 10G Ethernet Driver"
-#define DRV_VERSION "1.0.0.648"
+#define DRV_VERSION "1.0.0.933"
#define DRV_COPYRIGHT "Copyright 2008 Cisco Systems, Inc"
#define PFX DRV_NAME ": "
@@ -97,6 +97,7 @@ struct enic {
____cacheline_aligned struct vnic_rq rq[1];
unsigned int rq_count;
int (*rq_alloc_buf)(struct vnic_rq *rq);
+ u64 rq_bad_fcs;
struct napi_struct napi;
struct net_lro_mgr lro_mgr;
struct net_lro_desc lro_desc[ENIC_LRO_MAX_DESC];
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 7d60551d538f..03403a51f7ea 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -400,10 +400,13 @@ static irqreturn_t enic_isr_legacy(int irq, void *data)
return IRQ_NONE; /* not our interrupt */
}
- if (ENIC_TEST_INTR(pba, ENIC_INTX_NOTIFY))
+ if (ENIC_TEST_INTR(pba, ENIC_INTX_NOTIFY)) {
+ vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_NOTIFY]);
enic_notify_check(enic);
+ }
if (ENIC_TEST_INTR(pba, ENIC_INTX_ERR)) {
+ vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_ERR]);
enic_log_q_error(enic);
/* schedule recovery from WQ/RQ error */
schedule_work(&enic->reset);
@@ -411,8 +414,8 @@ static irqreturn_t enic_isr_legacy(int irq, void *data)
}
if (ENIC_TEST_INTR(pba, ENIC_INTX_WQ_RQ)) {
- if (netif_rx_schedule_prep(&enic->napi))
- __netif_rx_schedule(&enic->napi);
+ if (napi_schedule_prep(&enic->napi))
+ __napi_schedule(&enic->napi);
} else {
vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
}
@@ -440,7 +443,7 @@ static irqreturn_t enic_isr_msi(int irq, void *data)
* writes).
*/
- netif_rx_schedule(&enic->napi);
+ napi_schedule(&enic->napi);
return IRQ_HANDLED;
}
@@ -450,7 +453,7 @@ static irqreturn_t enic_isr_msix_rq(int irq, void *data)
struct enic *enic = data;
/* schedule NAPI polling for RQ cleanup */
- netif_rx_schedule(&enic->napi);
+ napi_schedule(&enic->napi);
return IRQ_HANDLED;
}
@@ -476,6 +479,8 @@ static irqreturn_t enic_isr_msix_err(int irq, void *data)
{
struct enic *enic = data;
+ vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_ERR]);
+
enic_log_q_error(enic);
/* schedule recovery from WQ/RQ error */
@@ -488,8 +493,8 @@ static irqreturn_t enic_isr_msix_notify(int irq, void *data)
{
struct enic *enic = data;
+ vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_NOTIFY]);
enic_notify_check(enic);
- vnic_intr_unmask(&enic->intr[ENIC_MSIX_NOTIFY]);
return IRQ_HANDLED;
}
@@ -570,11 +575,11 @@ static inline void enic_queue_wq_skb_tso(struct enic *enic,
* to each TCP segment resulting from the TSO.
*/
- if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ if (skb->protocol == cpu_to_be16(ETH_P_IP)) {
ip_hdr(skb)->check = 0;
tcp_hdr(skb)->check = ~csum_tcpudp_magic(ip_hdr(skb)->saddr,
ip_hdr(skb)->daddr, 0, IPPROTO_TCP, 0);
- } else if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
+ } else if (skb->protocol == cpu_to_be16(ETH_P_IPV6)) {
tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
&ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0);
}
@@ -616,7 +621,7 @@ static inline void enic_queue_wq_skb(struct enic *enic,
vlan_tag_insert, vlan_tag);
}
-/* netif_tx_lock held, process context with BHs disabled */
+/* netif_tx_lock held, process context with BHs disabled, or BH */
static int enic_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct enic *enic = netdev_priv(netdev);
@@ -683,7 +688,7 @@ static struct net_device_stats *enic_get_stats(struct net_device *netdev)
net_stats->rx_bytes = stats->rx.rx_bytes_ok;
net_stats->rx_errors = stats->rx.rx_errors;
net_stats->multicast = stats->rx.rx_multicast_frames_ok;
- net_stats->rx_crc_errors = stats->rx.rx_crc_errors;
+ net_stats->rx_crc_errors = enic->rq_bad_fcs;
net_stats->rx_dropped = stats->rx.rx_no_bufs;
return net_stats;
@@ -928,12 +933,8 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
if (packet_error) {
- if (bytes_written > 0 && !fcs_ok) {
- if (net_ratelimit())
- printk(KERN_ERR PFX
- "%s: packet error: bad FCS\n",
- netdev->name);
- }
+ if (bytes_written > 0 && !fcs_ok)
+ enic->rq_bad_fcs++;
dev_kfree_skb_any(skb);
@@ -1068,8 +1069,8 @@ static int enic_poll(struct napi_struct *napi, int budget)
if (netdev->features & NETIF_F_LRO)
lro_flush_all(&enic->lro_mgr);
- netif_rx_complete(napi);
- vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]);
+ napi_complete(napi);
+ vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
}
return rq_work_done;
@@ -1095,9 +1096,9 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf);
- /* Accumulate intr event credits for this polling
+ /* Return intr event credits for this polling
* cycle. An intr event is the completion of a
- * a WQ or RQ packet.
+ * RQ packet.
*/
vnic_intr_return_credits(&enic->intr[ENIC_MSIX_RQ],
@@ -1112,7 +1113,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
if (netdev->features & NETIF_F_LRO)
lro_flush_all(&enic->lro_mgr);
- netif_rx_complete(napi);
+ napi_complete(napi);
vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]);
}
@@ -1461,6 +1462,26 @@ static int enic_dev_soft_reset(struct enic *enic)
return err;
}
+static int enic_set_niccfg(struct enic *enic)
+{
+ const u8 rss_default_cpu = 0;
+ const u8 rss_hash_type = 0;
+ const u8 rss_hash_bits = 0;
+ const u8 rss_base_cpu = 0;
+ const u8 rss_enable = 0;
+ const u8 tso_ipid_split_en = 0;
+ const u8 ig_vlan_strip_en = 1;
+
+ /* Enable VLAN tag stripping. RSS not enabled (yet).
+ */
+
+ return enic_set_nic_cfg(enic,
+ rss_default_cpu, rss_hash_type,
+ rss_hash_bits, rss_base_cpu,
+ rss_enable, tso_ipid_split_en,
+ ig_vlan_strip_en);
+}
+
static void enic_reset(struct work_struct *work)
{
struct enic *enic = container_of(work, struct enic, reset);
@@ -1476,8 +1497,10 @@ static void enic_reset(struct work_struct *work)
enic_stop(enic->netdev);
enic_dev_soft_reset(enic);
+ vnic_dev_init(enic->vdev, 0);
enic_reset_mcaddrs(enic);
enic_init_vnic_resources(enic);
+ enic_set_niccfg(enic);
enic_open(enic->netdev);
rtnl_unlock();
@@ -1620,14 +1643,6 @@ static int __devinit enic_probe(struct pci_dev *pdev,
unsigned int i;
int err;
- const u8 rss_default_cpu = 0;
- const u8 rss_hash_type = 0;
- const u8 rss_hash_bits = 0;
- const u8 rss_base_cpu = 0;
- const u8 rss_enable = 0;
- const u8 tso_ipid_split_en = 0;
- const u8 ig_vlan_strip_en = 1;
-
/* Allocate net device structure and initialize. Private
* instance data is initialized to zero.
*/
@@ -1793,14 +1808,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
enic_init_vnic_resources(enic);
- /* Enable VLAN tag stripping. RSS not enabled (yet).
- */
-
- err = enic_set_nic_cfg(enic,
- rss_default_cpu, rss_hash_type,
- rss_hash_bits, rss_base_cpu,
- rss_enable, tso_ipid_split_en,
- ig_vlan_strip_en);
+ err = enic_set_niccfg(enic);
if (err) {
printk(KERN_ERR PFX
"Failed to config nic, aborting.\n");
@@ -1858,7 +1866,6 @@ static int __devinit enic_probe(struct pci_dev *pdev,
if (using_dac)
netdev->features |= NETIF_F_HIGHDMA;
-
enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM);
enic->lro_mgr.max_aggr = ENIC_LRO_MAX_AGGR;
@@ -1870,7 +1877,6 @@ static int __devinit enic_probe(struct pci_dev *pdev,
enic->lro_mgr.ip_summed = CHECKSUM_COMPLETE;
enic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
-
err = register_netdev(netdev);
if (err) {
printk(KERN_ERR PFX
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 11708579b6ce..e21b9d636aec 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -34,6 +34,9 @@ struct vnic_res {
unsigned int count;
};
+#define VNIC_DEV_CAP_INIT 0x0001
+#define VNIC_DEV_CAP_PERBI 0x0002
+
struct vnic_dev {
void *priv;
struct pci_dev *pdev;
@@ -50,6 +53,7 @@ struct vnic_dev {
dma_addr_t stats_pa;
struct vnic_devcmd_fw_info *fw_info;
dma_addr_t fw_info_pa;
+ u32 cap_flags;
};
#define VNIC_MAX_RES_HDR_SIZE \
@@ -575,9 +579,9 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg)
{
u64 a0 = (u32)arg, a1 = 0;
int wait = 1000;
- int r = 0;
+ int r = 0;
- if (vnic_dev_capable(vdev, CMD_INIT))
+ if (vdev->cap_flags & VNIC_DEV_CAP_INIT)
r = vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait);
else {
vnic_dev_cmd(vdev, CMD_INIT_v1, &a0, &a1, wait);
@@ -587,8 +591,8 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg)
vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
}
- }
- return r;
+ }
+ return r;
}
int vnic_dev_link_status(struct vnic_dev *vdev)
@@ -626,6 +630,22 @@ u32 vnic_dev_mtu(struct vnic_dev *vdev)
return vdev->notify_copy.mtu;
}
+u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev)
+{
+ if (!vnic_dev_notify_ready(vdev))
+ return 0;
+
+ return vdev->notify_copy.link_down_cnt;
+}
+
+u32 vnic_dev_notify_status(struct vnic_dev *vdev)
+{
+ if (!vnic_dev_notify_ready(vdev))
+ return 0;
+
+ return vdev->notify_copy.status;
+}
+
void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
enum vnic_dev_intr_mode intr_mode)
{
@@ -682,6 +702,11 @@ struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
if (!vdev->devcmd)
goto err_out;
+ vdev->cap_flags = 0;
+
+ if (vnic_dev_capable(vdev, CMD_INIT))
+ vdev->cap_flags |= VNIC_DEV_CAP_INIT;
+
return vdev;
err_out:
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index b9dc1821c805..8aa8db2fd03f 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -102,6 +102,8 @@ int vnic_dev_link_status(struct vnic_dev *vdev);
u32 vnic_dev_port_speed(struct vnic_dev *vdev);
u32 vnic_dev_msg_lvl(struct vnic_dev *vdev);
u32 vnic_dev_mtu(struct vnic_dev *vdev);
+u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev);
+u32 vnic_dev_notify_status(struct vnic_dev *vdev);
int vnic_dev_close(struct vnic_dev *vdev);
int vnic_dev_enable(struct vnic_dev *vdev);
int vnic_dev_disable(struct vnic_dev *vdev);
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h
index 8062c75154e6..2587f34fbfbd 100644
--- a/drivers/net/enic/vnic_devcmd.h
+++ b/drivers/net/enic/vnic_devcmd.h
@@ -191,7 +191,7 @@ enum vnic_devcmd_cmd {
CMD_INIT_STATUS = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 31),
/* INT13 API: (u64)a0=paddr to vnic_int13_params struct
- * (u8)a1=INT13_CMD_xxx */
+ * (u32)a1=INT13_CMD_xxx */
CMD_INT13 = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_FC, 32),
/* logical uplink enable/disable: (u64)a0: 0/1=disable/enable */
@@ -207,6 +207,11 @@ enum vnic_devcmd_cmd {
* in: (u32)a0=cmd
* out: (u32)a0=errno, 0:valid cmd, a1=supported VNIC_STF_* bits */
CMD_CAPABILITY = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 36),
+
+ /* persistent binding info
+ * in: (u64)a0=paddr of arg
+ * (u32)a1=CMD_PERBI_XXX */
+ CMD_PERBI = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_FC, 37),
};
/* flags for CMD_OPEN */
@@ -259,6 +264,7 @@ struct vnic_devcmd_notify {
u32 status; /* status bits (see VNIC_STF_*) */
u32 error; /* error code (see ERR_*) for first ERR */
u32 link_down_cnt; /* running count of link down transitions */
+ u32 perbi_rebuild_cnt; /* running count of perbi rebuilds */
};
#define VNIC_STF_FATAL_ERR 0x0001 /* fatal fw error */
#define VNIC_STF_STD_PAUSE 0x0002 /* standard link-level pause on */
diff --git a/drivers/net/enic/vnic_intr.h b/drivers/net/enic/vnic_intr.h
index ce633a5a7e3c..9a53604edce6 100644
--- a/drivers/net/enic/vnic_intr.h
+++ b/drivers/net/enic/vnic_intr.h
@@ -76,6 +76,20 @@ static inline void vnic_intr_return_credits(struct vnic_intr *intr,
iowrite32(int_credit_return, &intr->ctrl->int_credit_return);
}
+static inline unsigned int vnic_intr_credits(struct vnic_intr *intr)
+{
+ return ioread32(&intr->ctrl->int_credits);
+}
+
+static inline void vnic_intr_return_all_credits(struct vnic_intr *intr)
+{
+ unsigned int credits = vnic_intr_credits(intr);
+ int unmask = 1;
+ int reset_timer = 1;
+
+ vnic_intr_return_credits(intr, credits, unmask, reset_timer);
+}
+
static inline u32 vnic_intr_legacy_pba(u32 __iomem *legacy_pba)
{
/* read PBA without clearing */
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index a539bc3163cf..b60e27dfcfa7 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -1114,9 +1114,9 @@ static irqreturn_t epic_interrupt(int irq, void *dev_instance)
if ((status & EpicNapiEvent) && !ep->reschedule_in_poll) {
spin_lock(&ep->napi_lock);
- if (netif_rx_schedule_prep(&ep->napi)) {
+ if (napi_schedule_prep(&ep->napi)) {
epic_napi_irq_off(dev, ep);
- __netif_rx_schedule(&ep->napi);
+ __napi_schedule(&ep->napi);
} else
ep->reschedule_in_poll++;
spin_unlock(&ep->napi_lock);
@@ -1293,7 +1293,7 @@ rx_action:
more = ep->reschedule_in_poll;
if (!more) {
- __netif_rx_complete(napi);
+ __napi_complete(napi);
outl(EpicNapiEvent, ioaddr + INTSTAT);
epic_napi_irq_on(dev, ep);
} else
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
index 40125694bd9f..51ead7941f83 100644
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -159,7 +159,7 @@ static void eql_timer(unsigned long param)
add_timer(&eql->timer);
}
-static char version[] __initdata =
+static const char version[] __initconst =
"Equalizer2002: Simon Janes (simon@ncm.com) and David S. Miller (davem@redhat.com)\n";
static const struct net_device_ops eql_netdev_ops = {
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
index 5c048f2fd74f..0d8b6da046f2 100644
--- a/drivers/net/eth16i.c
+++ b/drivers/net/eth16i.c
@@ -475,6 +475,17 @@ out:
}
#endif
+static const struct net_device_ops eth16i_netdev_ops = {
+ .ndo_open = eth16i_open,
+ .ndo_stop = eth16i_close,
+ .ndo_start_xmit = eth16i_tx,
+ .ndo_set_multicast_list = eth16i_multicast,
+ .ndo_tx_timeout = eth16i_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
{
struct eth16i_local *lp = netdev_priv(dev);
@@ -549,12 +560,7 @@ static int __init eth16i_probe1(struct net_device *dev, int ioaddr)
BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
/* Initialize the device structure */
- memset(lp, 0, sizeof(struct eth16i_local));
- dev->open = eth16i_open;
- dev->stop = eth16i_close;
- dev->hard_start_xmit = eth16i_tx;
- dev->set_multicast_list = eth16i_multicast;
- dev->tx_timeout = eth16i_timeout;
+ dev->netdev_ops = &eth16i_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
spin_lock_init(&lp->lock);
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
new file mode 100644
index 000000000000..91a9b1a33764
--- /dev/null
+++ b/drivers/net/ethoc.c
@@ -0,0 +1,1112 @@
+/*
+ * linux/drivers/net/ethoc.c
+ *
+ * Copyright (C) 2007-2008 Avionic Design Development GmbH
+ * Copyright (C) 2008-2009 Avionic Design GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Written by Thierry Reding <thierry.reding@avionic-design.de>
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/crc32.h>
+#include <linux/io.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <net/ethoc.h>
+
+/* register offsets */
+#define MODER 0x00
+#define INT_SOURCE 0x04
+#define INT_MASK 0x08
+#define IPGT 0x0c
+#define IPGR1 0x10
+#define IPGR2 0x14
+#define PACKETLEN 0x18
+#define COLLCONF 0x1c
+#define TX_BD_NUM 0x20
+#define CTRLMODER 0x24
+#define MIIMODER 0x28
+#define MIICOMMAND 0x2c
+#define MIIADDRESS 0x30
+#define MIITX_DATA 0x34
+#define MIIRX_DATA 0x38
+#define MIISTATUS 0x3c
+#define MAC_ADDR0 0x40
+#define MAC_ADDR1 0x44
+#define ETH_HASH0 0x48
+#define ETH_HASH1 0x4c
+#define ETH_TXCTRL 0x50
+
+/* mode register */
+#define MODER_RXEN (1 << 0) /* receive enable */
+#define MODER_TXEN (1 << 1) /* transmit enable */
+#define MODER_NOPRE (1 << 2) /* no preamble */
+#define MODER_BRO (1 << 3) /* broadcast address */
+#define MODER_IAM (1 << 4) /* individual address mode */
+#define MODER_PRO (1 << 5) /* promiscuous mode */
+#define MODER_IFG (1 << 6) /* interframe gap for incoming frames */
+#define MODER_LOOP (1 << 7) /* loopback */
+#define MODER_NBO (1 << 8) /* no back-off */
+#define MODER_EDE (1 << 9) /* excess defer enable */
+#define MODER_FULLD (1 << 10) /* full duplex */
+#define MODER_RESET (1 << 11) /* FIXME: reset (undocumented) */
+#define MODER_DCRC (1 << 12) /* delayed CRC enable */
+#define MODER_CRC (1 << 13) /* CRC enable */
+#define MODER_HUGE (1 << 14) /* huge packets enable */
+#define MODER_PAD (1 << 15) /* padding enabled */
+#define MODER_RSM (1 << 16) /* receive small packets */
+
+/* interrupt source and mask registers */
+#define INT_MASK_TXF (1 << 0) /* transmit frame */
+#define INT_MASK_TXE (1 << 1) /* transmit error */
+#define INT_MASK_RXF (1 << 2) /* receive frame */
+#define INT_MASK_RXE (1 << 3) /* receive error */
+#define INT_MASK_BUSY (1 << 4)
+#define INT_MASK_TXC (1 << 5) /* transmit control frame */
+#define INT_MASK_RXC (1 << 6) /* receive control frame */
+
+#define INT_MASK_TX (INT_MASK_TXF | INT_MASK_TXE)
+#define INT_MASK_RX (INT_MASK_RXF | INT_MASK_RXE)
+
+#define INT_MASK_ALL ( \
+ INT_MASK_TXF | INT_MASK_TXE | \
+ INT_MASK_RXF | INT_MASK_RXE | \
+ INT_MASK_TXC | INT_MASK_RXC | \
+ INT_MASK_BUSY \
+ )
+
+/* packet length register */
+#define PACKETLEN_MIN(min) (((min) & 0xffff) << 16)
+#define PACKETLEN_MAX(max) (((max) & 0xffff) << 0)
+#define PACKETLEN_MIN_MAX(min, max) (PACKETLEN_MIN(min) | \
+ PACKETLEN_MAX(max))
+
+/* transmit buffer number register */
+#define TX_BD_NUM_VAL(x) (((x) <= 0x80) ? (x) : 0x80)
+
+/* control module mode register */
+#define CTRLMODER_PASSALL (1 << 0) /* pass all receive frames */
+#define CTRLMODER_RXFLOW (1 << 1) /* receive control flow */
+#define CTRLMODER_TXFLOW (1 << 2) /* transmit control flow */
+
+/* MII mode register */
+#define MIIMODER_CLKDIV(x) ((x) & 0xfe) /* needs to be an even number */
+#define MIIMODER_NOPRE (1 << 8) /* no preamble */
+
+/* MII command register */
+#define MIICOMMAND_SCAN (1 << 0) /* scan status */
+#define MIICOMMAND_READ (1 << 1) /* read status */
+#define MIICOMMAND_WRITE (1 << 2) /* write control data */
+
+/* MII address register */
+#define MIIADDRESS_FIAD(x) (((x) & 0x1f) << 0)
+#define MIIADDRESS_RGAD(x) (((x) & 0x1f) << 8)
+#define MIIADDRESS_ADDR(phy, reg) (MIIADDRESS_FIAD(phy) | \
+ MIIADDRESS_RGAD(reg))
+
+/* MII transmit data register */
+#define MIITX_DATA_VAL(x) ((x) & 0xffff)
+
+/* MII receive data register */
+#define MIIRX_DATA_VAL(x) ((x) & 0xffff)
+
+/* MII status register */
+#define MIISTATUS_LINKFAIL (1 << 0)
+#define MIISTATUS_BUSY (1 << 1)
+#define MIISTATUS_INVALID (1 << 2)
+
+/* TX buffer descriptor */
+#define TX_BD_CS (1 << 0) /* carrier sense lost */
+#define TX_BD_DF (1 << 1) /* defer indication */
+#define TX_BD_LC (1 << 2) /* late collision */
+#define TX_BD_RL (1 << 3) /* retransmission limit */
+#define TX_BD_RETRY_MASK (0x00f0)
+#define TX_BD_RETRY(x) (((x) & 0x00f0) >> 4)
+#define TX_BD_UR (1 << 8) /* transmitter underrun */
+#define TX_BD_CRC (1 << 11) /* TX CRC enable */
+#define TX_BD_PAD (1 << 12) /* pad enable for short packets */
+#define TX_BD_WRAP (1 << 13)
+#define TX_BD_IRQ (1 << 14) /* interrupt request enable */
+#define TX_BD_READY (1 << 15) /* TX buffer ready */
+#define TX_BD_LEN(x) (((x) & 0xffff) << 16)
+#define TX_BD_LEN_MASK (0xffff << 16)
+
+#define TX_BD_STATS (TX_BD_CS | TX_BD_DF | TX_BD_LC | \
+ TX_BD_RL | TX_BD_RETRY_MASK | TX_BD_UR)
+
+/* RX buffer descriptor */
+#define RX_BD_LC (1 << 0) /* late collision */
+#define RX_BD_CRC (1 << 1) /* RX CRC error */
+#define RX_BD_SF (1 << 2) /* short frame */
+#define RX_BD_TL (1 << 3) /* too long */
+#define RX_BD_DN (1 << 4) /* dribble nibble */
+#define RX_BD_IS (1 << 5) /* invalid symbol */
+#define RX_BD_OR (1 << 6) /* receiver overrun */
+#define RX_BD_MISS (1 << 7)
+#define RX_BD_CF (1 << 8) /* control frame */
+#define RX_BD_WRAP (1 << 13)
+#define RX_BD_IRQ (1 << 14) /* interrupt request enable */
+#define RX_BD_EMPTY (1 << 15)
+#define RX_BD_LEN(x) (((x) & 0xffff) << 16)
+
+#define RX_BD_STATS (RX_BD_LC | RX_BD_CRC | RX_BD_SF | RX_BD_TL | \
+ RX_BD_DN | RX_BD_IS | RX_BD_OR | RX_BD_MISS)
+
+#define ETHOC_BUFSIZ 1536
+#define ETHOC_ZLEN 64
+#define ETHOC_BD_BASE 0x400
+#define ETHOC_TIMEOUT (HZ / 2)
+#define ETHOC_MII_TIMEOUT (1 + (HZ / 5))
+
+/**
+ * struct ethoc - driver-private device structure
+ * @iobase: pointer to I/O memory region
+ * @membase: pointer to buffer memory region
+ * @num_tx: number of send buffers
+ * @cur_tx: last send buffer written
+ * @dty_tx: last buffer actually sent
+ * @num_rx: number of receive buffers
+ * @cur_rx: current receive buffer
+ * @netdev: pointer to network device structure
+ * @napi: NAPI structure
+ * @stats: network device statistics
+ * @msg_enable: device state flags
+ * @rx_lock: receive lock
+ * @lock: device lock
+ * @phy: attached PHY
+ * @mdio: MDIO bus for PHY access
+ * @phy_id: address of attached PHY
+ */
+struct ethoc {
+ void __iomem *iobase;
+ void __iomem *membase;
+
+ unsigned int num_tx;
+ unsigned int cur_tx;
+ unsigned int dty_tx;
+
+ unsigned int num_rx;
+ unsigned int cur_rx;
+
+ struct net_device *netdev;
+ struct napi_struct napi;
+ struct net_device_stats stats;
+ u32 msg_enable;
+
+ spinlock_t rx_lock;
+ spinlock_t lock;
+
+ struct phy_device *phy;
+ struct mii_bus *mdio;
+ s8 phy_id;
+};
+
+/**
+ * struct ethoc_bd - buffer descriptor
+ * @stat: buffer statistics
+ * @addr: physical memory address
+ */
+struct ethoc_bd {
+ u32 stat;
+ u32 addr;
+};
+
+static u32 ethoc_read(struct ethoc *dev, loff_t offset)
+{
+ return ioread32(dev->iobase + offset);
+}
+
+static void ethoc_write(struct ethoc *dev, loff_t offset, u32 data)
+{
+ iowrite32(data, dev->iobase + offset);
+}
+
+static void ethoc_read_bd(struct ethoc *dev, int index, struct ethoc_bd *bd)
+{
+ loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
+ bd->stat = ethoc_read(dev, offset + 0);
+ bd->addr = ethoc_read(dev, offset + 4);
+}
+
+static void ethoc_write_bd(struct ethoc *dev, int index,
+ const struct ethoc_bd *bd)
+{
+ loff_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
+ ethoc_write(dev, offset + 0, bd->stat);
+ ethoc_write(dev, offset + 4, bd->addr);
+}
+
+static void ethoc_enable_irq(struct ethoc *dev, u32 mask)
+{
+ u32 imask = ethoc_read(dev, INT_MASK);
+ imask |= mask;
+ ethoc_write(dev, INT_MASK, imask);
+}
+
+static void ethoc_disable_irq(struct ethoc *dev, u32 mask)
+{
+ u32 imask = ethoc_read(dev, INT_MASK);
+ imask &= ~mask;
+ ethoc_write(dev, INT_MASK, imask);
+}
+
+static void ethoc_ack_irq(struct ethoc *dev, u32 mask)
+{
+ ethoc_write(dev, INT_SOURCE, mask);
+}
+
+static void ethoc_enable_rx_and_tx(struct ethoc *dev)
+{
+ u32 mode = ethoc_read(dev, MODER);
+ mode |= MODER_RXEN | MODER_TXEN;
+ ethoc_write(dev, MODER, mode);
+}
+
+static void ethoc_disable_rx_and_tx(struct ethoc *dev)
+{
+ u32 mode = ethoc_read(dev, MODER);
+ mode &= ~(MODER_RXEN | MODER_TXEN);
+ ethoc_write(dev, MODER, mode);
+}
+
+static int ethoc_init_ring(struct ethoc *dev)
+{
+ struct ethoc_bd bd;
+ int i;
+
+ dev->cur_tx = 0;
+ dev->dty_tx = 0;
+ dev->cur_rx = 0;
+
+ /* setup transmission buffers */
+ bd.addr = 0;
+ bd.stat = TX_BD_IRQ | TX_BD_CRC;
+
+ for (i = 0; i < dev->num_tx; i++) {
+ if (i == dev->num_tx - 1)
+ bd.stat |= TX_BD_WRAP;
+
+ ethoc_write_bd(dev, i, &bd);
+ bd.addr += ETHOC_BUFSIZ;
+ }
+
+ bd.addr = dev->num_tx * ETHOC_BUFSIZ;
+ bd.stat = RX_BD_EMPTY | RX_BD_IRQ;
+
+ for (i = 0; i < dev->num_rx; i++) {
+ if (i == dev->num_rx - 1)
+ bd.stat |= RX_BD_WRAP;
+
+ ethoc_write_bd(dev, dev->num_tx + i, &bd);
+ bd.addr += ETHOC_BUFSIZ;
+ }
+
+ return 0;
+}
+
+static int ethoc_reset(struct ethoc *dev)
+{
+ u32 mode;
+
+ /* TODO: reset controller? */
+
+ ethoc_disable_rx_and_tx(dev);
+
+ /* TODO: setup registers */
+
+ /* enable FCS generation and automatic padding */
+ mode = ethoc_read(dev, MODER);
+ mode |= MODER_CRC | MODER_PAD;
+ ethoc_write(dev, MODER, mode);
+
+ /* set full-duplex mode */
+ mode = ethoc_read(dev, MODER);
+ mode |= MODER_FULLD;
+ ethoc_write(dev, MODER, mode);
+ ethoc_write(dev, IPGT, 0x15);
+
+ ethoc_ack_irq(dev, INT_MASK_ALL);
+ ethoc_enable_irq(dev, INT_MASK_ALL);
+ ethoc_enable_rx_and_tx(dev);
+ return 0;
+}
+
+static unsigned int ethoc_update_rx_stats(struct ethoc *dev,
+ struct ethoc_bd *bd)
+{
+ struct net_device *netdev = dev->netdev;
+ unsigned int ret = 0;
+
+ if (bd->stat & RX_BD_TL) {
+ dev_err(&netdev->dev, "RX: frame too long\n");
+ dev->stats.rx_length_errors++;
+ ret++;
+ }
+
+ if (bd->stat & RX_BD_SF) {
+ dev_err(&netdev->dev, "RX: frame too short\n");
+ dev->stats.rx_length_errors++;
+ ret++;
+ }
+
+ if (bd->stat & RX_BD_DN) {
+ dev_err(&netdev->dev, "RX: dribble nibble\n");
+ dev->stats.rx_frame_errors++;
+ }
+
+ if (bd->stat & RX_BD_CRC) {
+ dev_err(&netdev->dev, "RX: wrong CRC\n");
+ dev->stats.rx_crc_errors++;
+ ret++;
+ }
+
+ if (bd->stat & RX_BD_OR) {
+ dev_err(&netdev->dev, "RX: overrun\n");
+ dev->stats.rx_over_errors++;
+ ret++;
+ }
+
+ if (bd->stat & RX_BD_MISS)
+ dev->stats.rx_missed_errors++;
+
+ if (bd->stat & RX_BD_LC) {
+ dev_err(&netdev->dev, "RX: late collision\n");
+ dev->stats.collisions++;
+ ret++;
+ }
+
+ return ret;
+}
+
+static int ethoc_rx(struct net_device *dev, int limit)
+{
+ struct ethoc *priv = netdev_priv(dev);
+ int count;
+
+ for (count = 0; count < limit; ++count) {
+ unsigned int entry;
+ struct ethoc_bd bd;
+
+ entry = priv->num_tx + (priv->cur_rx % priv->num_rx);
+ ethoc_read_bd(priv, entry, &bd);
+ if (bd.stat & RX_BD_EMPTY)
+ break;
+
+ if (ethoc_update_rx_stats(priv, &bd) == 0) {
+ int size = bd.stat >> 16;
+ struct sk_buff *skb = netdev_alloc_skb(dev, size);
+ if (likely(skb)) {
+ void *src = priv->membase + bd.addr;
+ memcpy_fromio(skb_put(skb, size), src, size);
+ skb->protocol = eth_type_trans(skb, dev);
+ dev->last_rx = jiffies;
+ priv->stats.rx_packets++;
+ priv->stats.rx_bytes += size;
+ netif_receive_skb(skb);
+ } else {
+ if (net_ratelimit())
+ dev_warn(&dev->dev, "low on memory - "
+ "packet dropped\n");
+
+ priv->stats.rx_dropped++;
+ break;
+ }
+ }
+
+ /* clear the buffer descriptor so it can be reused */
+ bd.stat &= ~RX_BD_STATS;
+ bd.stat |= RX_BD_EMPTY;
+ ethoc_write_bd(priv, entry, &bd);
+ priv->cur_rx++;
+ }
+
+ return count;
+}
+
+static int ethoc_update_tx_stats(struct ethoc *dev, struct ethoc_bd *bd)
+{
+ struct net_device *netdev = dev->netdev;
+
+ if (bd->stat & TX_BD_LC) {
+ dev_err(&netdev->dev, "TX: late collision\n");
+ dev->stats.tx_window_errors++;
+ }
+
+ if (bd->stat & TX_BD_RL) {
+ dev_err(&netdev->dev, "TX: retransmit limit\n");
+ dev->stats.tx_aborted_errors++;
+ }
+
+ if (bd->stat & TX_BD_UR) {
+ dev_err(&netdev->dev, "TX: underrun\n");
+ dev->stats.tx_fifo_errors++;
+ }
+
+ if (bd->stat & TX_BD_CS) {
+ dev_err(&netdev->dev, "TX: carrier sense lost\n");
+ dev->stats.tx_carrier_errors++;
+ }
+
+ if (bd->stat & TX_BD_STATS)
+ dev->stats.tx_errors++;
+
+ dev->stats.collisions += (bd->stat >> 4) & 0xf;
+ dev->stats.tx_bytes += bd->stat >> 16;
+ dev->stats.tx_packets++;
+ return 0;
+}
+
+static void ethoc_tx(struct net_device *dev)
+{
+ struct ethoc *priv = netdev_priv(dev);
+
+ spin_lock(&priv->lock);
+
+ while (priv->dty_tx != priv->cur_tx) {
+ unsigned int entry = priv->dty_tx % priv->num_tx;
+ struct ethoc_bd bd;
+
+ ethoc_read_bd(priv, entry, &bd);
+ if (bd.stat & TX_BD_READY)
+ break;
+
+ entry = (++priv->dty_tx) % priv->num_tx;
+ (void)ethoc_update_tx_stats(priv, &bd);
+ }
+
+ if ((priv->cur_tx - priv->dty_tx) <= (priv->num_tx / 2))
+ netif_wake_queue(dev);
+
+ ethoc_ack_irq(priv, INT_MASK_TX);
+ spin_unlock(&priv->lock);
+}
+
+static irqreturn_t ethoc_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct ethoc *priv = netdev_priv(dev);
+ u32 pending;
+
+ ethoc_disable_irq(priv, INT_MASK_ALL);
+ pending = ethoc_read(priv, INT_SOURCE);
+ if (unlikely(pending == 0)) {
+ ethoc_enable_irq(priv, INT_MASK_ALL);
+ return IRQ_NONE;
+ }
+
+ ethoc_ack_irq(priv, INT_MASK_ALL);
+
+ if (pending & INT_MASK_BUSY) {
+ dev_err(&dev->dev, "packet dropped\n");
+ priv->stats.rx_dropped++;
+ }
+
+ if (pending & INT_MASK_RX) {
+ if (napi_schedule_prep(&priv->napi))
+ __napi_schedule(&priv->napi);
+ } else {
+ ethoc_enable_irq(priv, INT_MASK_RX);
+ }
+
+ if (pending & INT_MASK_TX)
+ ethoc_tx(dev);
+
+ ethoc_enable_irq(priv, INT_MASK_ALL & ~INT_MASK_RX);
+ return IRQ_HANDLED;
+}
+
+static int ethoc_get_mac_address(struct net_device *dev, void *addr)
+{
+ struct ethoc *priv = netdev_priv(dev);
+ u8 *mac = (u8 *)addr;
+ u32 reg;
+
+ reg = ethoc_read(priv, MAC_ADDR0);
+ mac[2] = (reg >> 24) & 0xff;
+ mac[3] = (reg >> 16) & 0xff;
+ mac[4] = (reg >> 8) & 0xff;
+ mac[5] = (reg >> 0) & 0xff;
+
+ reg = ethoc_read(priv, MAC_ADDR1);
+ mac[0] = (reg >> 8) & 0xff;
+ mac[1] = (reg >> 0) & 0xff;
+
+ return 0;
+}
+
+static int ethoc_poll(struct napi_struct *napi, int budget)
+{
+ struct ethoc *priv = container_of(napi, struct ethoc, napi);
+ int work_done = 0;
+
+ work_done = ethoc_rx(priv->netdev, budget);
+ if (work_done < budget) {
+ ethoc_enable_irq(priv, INT_MASK_RX);
+ napi_complete(napi);
+ }
+
+ return work_done;
+}
+
+static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg)
+{
+ unsigned long timeout = jiffies + ETHOC_MII_TIMEOUT;
+ struct ethoc *priv = bus->priv;
+
+ ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg));
+ ethoc_write(priv, MIICOMMAND, MIICOMMAND_READ);
+
+ while (time_before(jiffies, timeout)) {
+ u32 status = ethoc_read(priv, MIISTATUS);
+ if (!(status & MIISTATUS_BUSY)) {
+ u32 data = ethoc_read(priv, MIIRX_DATA);
+ /* reset MII command register */
+ ethoc_write(priv, MIICOMMAND, 0);
+ return data;
+ }
+
+ schedule();
+ }
+
+ return -EBUSY;
+}
+
+static int ethoc_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
+{
+ unsigned long timeout = jiffies + ETHOC_MII_TIMEOUT;
+ struct ethoc *priv = bus->priv;
+
+ ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg));
+ ethoc_write(priv, MIITX_DATA, val);
+ ethoc_write(priv, MIICOMMAND, MIICOMMAND_WRITE);
+
+ while (time_before(jiffies, timeout)) {
+ u32 stat = ethoc_read(priv, MIISTATUS);
+ if (!(stat & MIISTATUS_BUSY))
+ return 0;
+
+ schedule();
+ }
+
+ return -EBUSY;
+}
+
+static int ethoc_mdio_reset(struct mii_bus *bus)
+{
+ return 0;
+}
+
+static void ethoc_mdio_poll(struct net_device *dev)
+{
+}
+
+static int ethoc_mdio_probe(struct net_device *dev)
+{
+ struct ethoc *priv = netdev_priv(dev);
+ struct phy_device *phy;
+ int i;
+
+ for (i = 0; i < PHY_MAX_ADDR; i++) {
+ phy = priv->mdio->phy_map[i];
+ if (phy) {
+ if (priv->phy_id != -1) {
+ /* attach to specified PHY */
+ if (priv->phy_id == phy->addr)
+ break;
+ } else {
+ /* autoselect PHY if none was specified */
+ if (phy->addr != 0)
+ break;
+ }
+ }
+ }
+
+ if (!phy) {
+ dev_err(&dev->dev, "no PHY found\n");
+ return -ENXIO;
+ }
+
+ phy = phy_connect(dev, dev_name(&phy->dev), &ethoc_mdio_poll, 0,
+ PHY_INTERFACE_MODE_GMII);
+ if (IS_ERR(phy)) {
+ dev_err(&dev->dev, "could not attach to PHY\n");
+ return PTR_ERR(phy);
+ }
+
+ priv->phy = phy;
+ return 0;
+}
+
+static int ethoc_open(struct net_device *dev)
+{
+ struct ethoc *priv = netdev_priv(dev);
+ unsigned int min_tx = 2;
+ unsigned int num_bd;
+ int ret;
+
+ ret = request_irq(dev->irq, ethoc_interrupt, IRQF_SHARED,
+ dev->name, dev);
+ if (ret)
+ return ret;
+
+ /* calculate the number of TX/RX buffers */
+ num_bd = (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ;
+ priv->num_tx = min(min_tx, num_bd / 4);
+ priv->num_rx = num_bd - priv->num_tx;
+ ethoc_write(priv, TX_BD_NUM, priv->num_tx);
+
+ ethoc_init_ring(priv);
+ ethoc_reset(priv);
+
+ if (netif_queue_stopped(dev)) {
+ dev_dbg(&dev->dev, " resuming queue\n");
+ netif_wake_queue(dev);
+ } else {
+ dev_dbg(&dev->dev, " starting queue\n");
+ netif_start_queue(dev);
+ }
+
+ phy_start(priv->phy);
+ napi_enable(&priv->napi);
+
+ if (netif_msg_ifup(priv)) {
+ dev_info(&dev->dev, "I/O: %08lx Memory: %08lx-%08lx\n",
+ dev->base_addr, dev->mem_start, dev->mem_end);
+ }
+
+ return 0;
+}
+
+static int ethoc_stop(struct net_device *dev)
+{
+ struct ethoc *priv = netdev_priv(dev);
+
+ napi_disable(&priv->napi);
+
+ if (priv->phy)
+ phy_stop(priv->phy);
+
+ ethoc_disable_rx_and_tx(priv);
+ free_irq(dev->irq, dev);
+
+ if (!netif_queue_stopped(dev))
+ netif_stop_queue(dev);
+
+ return 0;
+}
+
+static int ethoc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ struct ethoc *priv = netdev_priv(dev);
+ struct mii_ioctl_data *mdio = if_mii(ifr);
+ struct phy_device *phy = NULL;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (cmd != SIOCGMIIPHY) {
+ if (mdio->phy_id >= PHY_MAX_ADDR)
+ return -ERANGE;
+
+ phy = priv->mdio->phy_map[mdio->phy_id];
+ if (!phy)
+ return -ENODEV;
+ } else {
+ phy = priv->phy;
+ }
+
+ return phy_mii_ioctl(phy, mdio, cmd);
+}
+
+static int ethoc_config(struct net_device *dev, struct ifmap *map)
+{
+ return -ENOSYS;
+}
+
+static int ethoc_set_mac_address(struct net_device *dev, void *addr)
+{
+ struct ethoc *priv = netdev_priv(dev);
+ u8 *mac = (u8 *)addr;
+
+ ethoc_write(priv, MAC_ADDR0, (mac[2] << 24) | (mac[3] << 16) |
+ (mac[4] << 8) | (mac[5] << 0));
+ ethoc_write(priv, MAC_ADDR1, (mac[0] << 8) | (mac[1] << 0));
+
+ return 0;
+}
+
+static void ethoc_set_multicast_list(struct net_device *dev)
+{
+ struct ethoc *priv = netdev_priv(dev);
+ u32 mode = ethoc_read(priv, MODER);
+ struct dev_mc_list *mc = NULL;
+ u32 hash[2] = { 0, 0 };
+
+ /* set loopback mode if requested */
+ if (dev->flags & IFF_LOOPBACK)
+ mode |= MODER_LOOP;
+ else
+ mode &= ~MODER_LOOP;
+
+ /* receive broadcast frames if requested */
+ if (dev->flags & IFF_BROADCAST)
+ mode &= ~MODER_BRO;
+ else
+ mode |= MODER_BRO;
+
+ /* enable promiscuous mode if requested */
+ if (dev->flags & IFF_PROMISC)
+ mode |= MODER_PRO;
+ else
+ mode &= ~MODER_PRO;
+
+ ethoc_write(priv, MODER, mode);
+
+ /* receive multicast frames */
+ if (dev->flags & IFF_ALLMULTI) {
+ hash[0] = 0xffffffff;
+ hash[1] = 0xffffffff;
+ } else {
+ for (mc = dev->mc_list; mc; mc = mc->next) {
+ u32 crc = ether_crc(mc->dmi_addrlen, mc->dmi_addr);
+ int bit = (crc >> 26) & 0x3f;
+ hash[bit >> 5] |= 1 << (bit & 0x1f);
+ }
+ }
+
+ ethoc_write(priv, ETH_HASH0, hash[0]);
+ ethoc_write(priv, ETH_HASH1, hash[1]);
+}
+
+static int ethoc_change_mtu(struct net_device *dev, int new_mtu)
+{
+ return -ENOSYS;
+}
+
+static void ethoc_tx_timeout(struct net_device *dev)
+{
+ struct ethoc *priv = netdev_priv(dev);
+ u32 pending = ethoc_read(priv, INT_SOURCE);
+ if (likely(pending))
+ ethoc_interrupt(dev->irq, dev);
+}
+
+static struct net_device_stats *ethoc_stats(struct net_device *dev)
+{
+ struct ethoc *priv = netdev_priv(dev);
+ return &priv->stats;
+}
+
+static int ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct ethoc *priv = netdev_priv(dev);
+ struct ethoc_bd bd;
+ unsigned int entry;
+ void *dest;
+
+ if (unlikely(skb->len > ETHOC_BUFSIZ)) {
+ priv->stats.tx_errors++;
+ return -EMSGSIZE;
+ }
+
+ entry = priv->cur_tx % priv->num_tx;
+ spin_lock_irq(&priv->lock);
+ priv->cur_tx++;
+
+ ethoc_read_bd(priv, entry, &bd);
+ if (unlikely(skb->len < ETHOC_ZLEN))
+ bd.stat |= TX_BD_PAD;
+ else
+ bd.stat &= ~TX_BD_PAD;
+
+ dest = priv->membase + bd.addr;
+ memcpy_toio(dest, skb->data, skb->len);
+
+ bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK);
+ bd.stat |= TX_BD_LEN(skb->len);
+ ethoc_write_bd(priv, entry, &bd);
+
+ bd.stat |= TX_BD_READY;
+ ethoc_write_bd(priv, entry, &bd);
+
+ if (priv->cur_tx == (priv->dty_tx + priv->num_tx)) {
+ dev_dbg(&dev->dev, "stopping queue\n");
+ netif_stop_queue(dev);
+ }
+
+ dev->trans_start = jiffies;
+ dev_kfree_skb(skb);
+
+ spin_unlock_irq(&priv->lock);
+ return NETDEV_TX_OK;
+}
+
+static const struct net_device_ops ethoc_netdev_ops = {
+ .ndo_open = ethoc_open,
+ .ndo_stop = ethoc_stop,
+ .ndo_do_ioctl = ethoc_ioctl,
+ .ndo_set_config = ethoc_config,
+ .ndo_set_mac_address = ethoc_set_mac_address,
+ .ndo_set_multicast_list = ethoc_set_multicast_list,
+ .ndo_change_mtu = ethoc_change_mtu,
+ .ndo_tx_timeout = ethoc_tx_timeout,
+ .ndo_get_stats = ethoc_stats,
+ .ndo_start_xmit = ethoc_start_xmit,
+};
+
+/**
+ * ethoc_probe() - initialize OpenCores ethernet MAC
+ * pdev: platform device
+ */
+static int ethoc_probe(struct platform_device *pdev)
+{
+ struct net_device *netdev = NULL;
+ struct resource *res = NULL;
+ struct resource *mmio = NULL;
+ struct resource *mem = NULL;
+ struct ethoc *priv = NULL;
+ unsigned int phy;
+ int ret = 0;
+
+ /* allocate networking device */
+ netdev = alloc_etherdev(sizeof(struct ethoc));
+ if (!netdev) {
+ dev_err(&pdev->dev, "cannot allocate network device\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+ platform_set_drvdata(pdev, netdev);
+
+ /* obtain I/O memory space */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "cannot obtain I/O memory space\n");
+ ret = -ENXIO;
+ goto free;
+ }
+
+ mmio = devm_request_mem_region(&pdev->dev, res->start,
+ res->end - res->start + 1, res->name);
+ if (!res) {
+ dev_err(&pdev->dev, "cannot request I/O memory space\n");
+ ret = -ENXIO;
+ goto free;
+ }
+
+ netdev->base_addr = mmio->start;
+
+ /* obtain buffer memory space */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "cannot obtain memory space\n");
+ ret = -ENXIO;
+ goto free;
+ }
+
+ mem = devm_request_mem_region(&pdev->dev, res->start,
+ res->end - res->start + 1, res->name);
+ if (!mem) {
+ dev_err(&pdev->dev, "cannot request memory space\n");
+ ret = -ENXIO;
+ goto free;
+ }
+
+ netdev->mem_start = mem->start;
+ netdev->mem_end = mem->end;
+
+ /* obtain device IRQ number */
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "cannot obtain IRQ\n");
+ ret = -ENXIO;
+ goto free;
+ }
+
+ netdev->irq = res->start;
+
+ /* setup driver-private data */
+ priv = netdev_priv(netdev);
+ priv->netdev = netdev;
+
+ priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr,
+ mmio->end - mmio->start + 1);
+ if (!priv->iobase) {
+ dev_err(&pdev->dev, "cannot remap I/O memory space\n");
+ ret = -ENXIO;
+ goto error;
+ }
+
+ priv->membase = devm_ioremap_nocache(&pdev->dev, netdev->mem_start,
+ mem->end - mem->start + 1);
+ if (!priv->membase) {
+ dev_err(&pdev->dev, "cannot remap memory space\n");
+ ret = -ENXIO;
+ goto error;
+ }
+
+ /* Allow the platform setup code to pass in a MAC address. */
+ if (pdev->dev.platform_data) {
+ struct ethoc_platform_data *pdata =
+ (struct ethoc_platform_data *)pdev->dev.platform_data;
+ memcpy(netdev->dev_addr, pdata->hwaddr, IFHWADDRLEN);
+ priv->phy_id = pdata->phy_id;
+ }
+
+ /* Check that the given MAC address is valid. If it isn't, read the
+ * current MAC from the controller. */
+ if (!is_valid_ether_addr(netdev->dev_addr))
+ ethoc_get_mac_address(netdev, netdev->dev_addr);
+
+ /* Check the MAC again for validity, if it still isn't choose and
+ * program a random one. */
+ if (!is_valid_ether_addr(netdev->dev_addr))
+ random_ether_addr(netdev->dev_addr);
+
+ ethoc_set_mac_address(netdev, netdev->dev_addr);
+
+ /* register MII bus */
+ priv->mdio = mdiobus_alloc();
+ if (!priv->mdio) {
+ ret = -ENOMEM;
+ goto free;
+ }
+
+ priv->mdio->name = "ethoc-mdio";
+ snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "%s-%d",
+ priv->mdio->name, pdev->id);
+ priv->mdio->read = ethoc_mdio_read;
+ priv->mdio->write = ethoc_mdio_write;
+ priv->mdio->reset = ethoc_mdio_reset;
+ priv->mdio->priv = priv;
+
+ priv->mdio->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+ if (!priv->mdio->irq) {
+ ret = -ENOMEM;
+ goto free_mdio;
+ }
+
+ for (phy = 0; phy < PHY_MAX_ADDR; phy++)
+ priv->mdio->irq[phy] = PHY_POLL;
+
+ ret = mdiobus_register(priv->mdio);
+ if (ret) {
+ dev_err(&netdev->dev, "failed to register MDIO bus\n");
+ goto free_mdio;
+ }
+
+ ret = ethoc_mdio_probe(netdev);
+ if (ret) {
+ dev_err(&netdev->dev, "failed to probe MDIO bus\n");
+ goto error;
+ }
+
+ ether_setup(netdev);
+
+ /* setup the net_device structure */
+ netdev->netdev_ops = &ethoc_netdev_ops;
+ netdev->watchdog_timeo = ETHOC_TIMEOUT;
+ netdev->features |= 0;
+
+ /* setup NAPI */
+ memset(&priv->napi, 0, sizeof(priv->napi));
+ netif_napi_add(netdev, &priv->napi, ethoc_poll, 64);
+
+ spin_lock_init(&priv->rx_lock);
+ spin_lock_init(&priv->lock);
+
+ ret = register_netdev(netdev);
+ if (ret < 0) {
+ dev_err(&netdev->dev, "failed to register interface\n");
+ goto error;
+ }
+
+ goto out;
+
+error:
+ mdiobus_unregister(priv->mdio);
+free_mdio:
+ kfree(priv->mdio->irq);
+ mdiobus_free(priv->mdio);
+free:
+ free_netdev(netdev);
+out:
+ return ret;
+}
+
+/**
+ * ethoc_remove() - shutdown OpenCores ethernet MAC
+ * @pdev: platform device
+ */
+static int ethoc_remove(struct platform_device *pdev)
+{
+ struct net_device *netdev = platform_get_drvdata(pdev);
+ struct ethoc *priv = netdev_priv(netdev);
+
+ platform_set_drvdata(pdev, NULL);
+
+ if (netdev) {
+ phy_disconnect(priv->phy);
+ priv->phy = NULL;
+
+ if (priv->mdio) {
+ mdiobus_unregister(priv->mdio);
+ kfree(priv->mdio->irq);
+ mdiobus_free(priv->mdio);
+ }
+
+ unregister_netdev(netdev);
+ free_netdev(netdev);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ethoc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ return -ENOSYS;
+}
+
+static int ethoc_resume(struct platform_device *pdev)
+{
+ return -ENOSYS;
+}
+#else
+# define ethoc_suspend NULL
+# define ethoc_resume NULL
+#endif
+
+static struct platform_driver ethoc_driver = {
+ .probe = ethoc_probe,
+ .remove = ethoc_remove,
+ .suspend = ethoc_suspend,
+ .resume = ethoc_resume,
+ .driver = {
+ .name = "ethoc",
+ },
+};
+
+static int __init ethoc_init(void)
+{
+ return platform_driver_register(&ethoc_driver);
+}
+
+static void __exit ethoc_exit(void)
+{
+ platform_driver_unregister(&ethoc_driver);
+}
+
+module_init(ethoc_init);
+module_exit(ethoc_exit);
+
+MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
+MODULE_DESCRIPTION("OpenCores Ethernet MAC driver");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
index b852303c9362..1a685a04d4b2 100644
--- a/drivers/net/ewrk3.c
+++ b/drivers/net/ewrk3.c
@@ -388,6 +388,18 @@ static int __init ewrk3_probe1(struct net_device *dev, u_long iobase, int irq)
return err;
}
+static const struct net_device_ops ewrk3_netdev_ops = {
+ .ndo_open = ewrk3_open,
+ .ndo_start_xmit = ewrk3_queue_pkt,
+ .ndo_stop = ewrk3_close,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_do_ioctl = ewrk3_ioctl,
+ .ndo_tx_timeout = ewrk3_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init
ewrk3_hw_init(struct net_device *dev, u_long iobase)
{
@@ -603,16 +615,11 @@ ewrk3_hw_init(struct net_device *dev, u_long iobase)
printk(version);
}
/* The EWRK3-specific entries in the device structure. */
- dev->open = ewrk3_open;
- dev->hard_start_xmit = ewrk3_queue_pkt;
- dev->stop = ewrk3_close;
- dev->set_multicast_list = set_multicast_list;
- dev->do_ioctl = ewrk3_ioctl;
+ dev->netdev_ops = &ewrk3_netdev_ops;
if (lp->adapter_name[4] == '3')
SET_ETHTOOL_OPS(dev, &ethtool_ops_203);
else
SET_ETHTOOL_OPS(dev, &ethtool_ops);
- dev->tx_timeout = ewrk3_timeout;
dev->watchdog_timeo = QUEUE_PKT_TIMEOUT;
dev->mem_start = 0;
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index daf7272c3352..891be28a7d4f 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -93,8 +93,8 @@ static int full_duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
#include <asm/byteorder.h>
/* These identify the driver base version and may not be removed. */
-static char version[] =
-KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "\n";
+static const char version[] __devinitconst =
+ KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "\n";
/* This driver was written to use PCI memory space, however some x86 systems
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 2769083bfe83..a515acccc61f 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -36,46 +36,32 @@
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/cacheflush.h>
+#ifndef CONFIG_ARCH_MXC
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
+#endif
+
#include "fec.h"
-#if defined(CONFIG_FEC2)
-#define FEC_MAX_PORTS 2
+#ifdef CONFIG_ARCH_MXC
+#include <mach/hardware.h>
+#define FEC_ALIGNMENT 0xf
#else
-#define FEC_MAX_PORTS 1
-#endif
-
-#if defined(CONFIG_M5272)
-#define HAVE_mii_link_interrupt
+#define FEC_ALIGNMENT 0x3
#endif
/*
* Define the fixed address of the FEC hardware.
*/
-static unsigned int fec_hw[] = {
#if defined(CONFIG_M5272)
- (MCF_MBAR + 0x840),
-#elif defined(CONFIG_M527x)
- (MCF_MBAR + 0x1000),
- (MCF_MBAR + 0x1800),
-#elif defined(CONFIG_M523x) || defined(CONFIG_M528x)
- (MCF_MBAR + 0x1000),
-#elif defined(CONFIG_M520x)
- (MCF_MBAR+0x30000),
-#elif defined(CONFIG_M532x)
- (MCF_MBAR+0xfc030000),
-#else
- &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec),
-#endif
-};
+#define HAVE_mii_link_interrupt
static unsigned char fec_mac_default[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -98,6 +84,7 @@ static unsigned char fec_mac_default[] = {
#else
#define FEC_FLASHMAC 0
#endif
+#endif /* CONFIG_M5272 */
/* Forward declarations of some structures to support different PHYs
*/
@@ -162,7 +149,7 @@ typedef struct {
* account when setting it.
*/
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M520x) || defined(CONFIG_M532x)
+ defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
#else
#define OPT_FRAME_SIZE 0
@@ -182,6 +169,8 @@ struct fec_enet_private {
struct net_device *netdev;
+ struct clk *clk;
+
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
unsigned char *tx_bounce[TX_RING_SIZE];
struct sk_buff* tx_skbuff[TX_RING_SIZE];
@@ -190,6 +179,7 @@ struct fec_enet_private {
/* CPM dual port RAM relative addresses.
*/
+ dma_addr_t bd_dma;
cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */
cbd_t *tx_bd_base;
cbd_t *cur_rx, *cur_tx; /* The next free ring entry */
@@ -342,10 +332,10 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
* 4-byte boundaries. Use bounce buffers to copy data
* and get it aligned. Ugh.
*/
- if (bdp->cbd_bufaddr & 0x3) {
+ if (bdp->cbd_bufaddr & FEC_ALIGNMENT) {
unsigned int index;
index = bdp - fep->tx_bd_base;
- memcpy(fep->tx_bounce[index], (void *) bdp->cbd_bufaddr, bdp->cbd_datlen);
+ memcpy(fep->tx_bounce[index], (void *)skb->data, skb->len);
bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]);
}
@@ -359,8 +349,8 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Push the data cache so the CPM does not get stale memory
* data.
*/
- flush_dcache_range((unsigned long)skb->data,
- (unsigned long)skb->data + skb->len);
+ dma_sync_single(NULL, bdp->cbd_bufaddr,
+ bdp->cbd_datlen, DMA_TO_DEVICE);
/* Send it on its way. Tell FEC it's ready, interrupt when done,
* it's the last BD of the frame, and to put the CRC on the end.
@@ -633,6 +623,9 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
dev->stats.rx_bytes += pkt_len;
data = (__u8*)__va(bdp->cbd_bufaddr);
+ dma_sync_single(NULL, (unsigned long)__pa(data),
+ pkt_len - 4, DMA_FROM_DEVICE);
+
/* This does 16 byte alignment, exactly what we need.
* The packet length includes FCS, but we don't want to
* include that when passing upstream as it messes up
@@ -1114,7 +1107,7 @@ static phy_info_t const phy_info_am79c874 = {
/* register definitions for the 8721 */
#define MII_KS8721BL_RXERCR 21
-#define MII_KS8721BL_ICSR 22
+#define MII_KS8721BL_ICSR 27
#define MII_KS8721BL_PHYCR 31
static phy_cmd_t const phy_cmd_ks8721bl_config[] = {
@@ -1223,93 +1216,14 @@ static phy_info_t const * const phy_info[] = {
#ifdef HAVE_mii_link_interrupt
static irqreturn_t
mii_link_interrupt(int irq, void * dev_id);
-#endif
-#if defined(CONFIG_M5272)
/*
- * Code specific to Coldfire 5272 setup.
+ * This is specific to the MII interrupt setup of the M5272EVB.
*/
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
- volatile unsigned long *icrp;
- static const struct idesc {
- char *name;
- unsigned short irq;
- irq_handler_t handler;
- } *idp, id[] = {
- { "fec(RX)", 86, fec_enet_interrupt },
- { "fec(TX)", 87, fec_enet_interrupt },
- { "fec(OTHER)", 88, fec_enet_interrupt },
- { "fec(MII)", 66, mii_link_interrupt },
- { NULL },
- };
-
- /* Setup interrupt handlers. */
- for (idp = id; idp->name; idp++) {
- if (request_irq(idp->irq, idp->handler, IRQF_DISABLED, idp->name, dev) != 0)
- printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, idp->irq);
- }
-
- /* Unmask interrupt at ColdFire 5272 SIM */
- icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR3);
- *icrp = 0x00000ddd;
- icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
- *icrp = 0x0d000000;
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
- fecp->fec_x_cntrl = 0x00;
-
- /*
- * Set MII speed to 2.5 MHz
- * See 5272 manual section 11.5.8: MSCR
- */
- fep->phy_speed = ((((MCF_CLK / 4) / (2500000 / 10)) + 5) / 10) * 2;
- fecp->fec_mii_speed = fep->phy_speed;
-
- fec_restart(dev, 0);
-}
-
-static void __inline__ fec_get_mac(struct net_device *dev)
-{
- struct fec_enet_private *fep = netdev_priv(dev);
- volatile fec_t *fecp;
- unsigned char *iap, tmpaddr[ETH_ALEN];
-
- fecp = fep->hwp;
-
- if (FEC_FLASHMAC) {
- /*
- * Get MAC address from FLASH.
- * If it is all 1's or 0's, use the default.
- */
- iap = (unsigned char *)FEC_FLASHMAC;
- if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
- (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
- iap = fec_mac_default;
- if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
- (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
- iap = fec_mac_default;
- } else {
- *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
- *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
- iap = &tmpaddr[0];
- }
-
- memcpy(dev->dev_addr, iap, ETH_ALEN);
-
- /* Adjust MAC if using default MAC address */
- if (iap == fec_mac_default)
- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
+static void __inline__ fec_request_mii_intr(struct net_device *dev)
{
+ if (request_irq(66, mii_link_interrupt, IRQF_DISABLED, "fec(MII)", dev) != 0)
+ printk("FEC: Could not allocate fec(MII) IRQ(66)!\n");
}
static void __inline__ fec_disable_phy_intr(void)
@@ -1327,244 +1241,7 @@ static void __inline__ fec_phy_ack_intr(void)
*icrp = 0x0d000000;
}
-static void __inline__ fec_localhw_setup(void)
-{
-}
-
-/*
- * Do not need to make region uncached on 5272.
- */
-static void __inline__ fec_uncache(unsigned long addr)
-{
-}
-
-/* ------------------------------------------------------------------------- */
-
-#elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
-
-/*
- * Code specific to Coldfire 5230/5231/5232/5234/5235,
- * the 5270/5271/5274/5275 and 5280/5282 setups.
- */
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
- struct fec_enet_private *fep;
- int b;
- static const struct idesc {
- char *name;
- unsigned short irq;
- } *idp, id[] = {
- { "fec(TXF)", 23 },
- { "fec(RXF)", 27 },
- { "fec(MII)", 29 },
- { NULL },
- };
-
- fep = netdev_priv(dev);
- b = (fep->index) ? 128 : 64;
-
- /* Setup interrupt handlers. */
- for (idp = id; idp->name; idp++) {
- if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name, dev) != 0)
- printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
- }
-
- /* Unmask interrupts at ColdFire 5280/5282 interrupt controller */
- {
- volatile unsigned char *icrp;
- volatile unsigned long *imrp;
- int i, ilip;
-
- b = (fep->index) ? MCFICM_INTC1 : MCFICM_INTC0;
- icrp = (volatile unsigned char *) (MCF_IPSBAR + b +
- MCFINTC_ICR0);
- for (i = 23, ilip = 0x28; (i < 36); i++)
- icrp[i] = ilip--;
-
- imrp = (volatile unsigned long *) (MCF_IPSBAR + b +
- MCFINTC_IMRH);
- *imrp &= ~0x0000000f;
- imrp = (volatile unsigned long *) (MCF_IPSBAR + b +
- MCFINTC_IMRL);
- *imrp &= ~0xff800001;
- }
-
-#if defined(CONFIG_M528x)
- /* Set up gpio outputs for MII lines */
- {
- volatile u16 *gpio_paspar;
- volatile u8 *gpio_pehlpar;
-
- gpio_paspar = (volatile u16 *) (MCF_IPSBAR + 0x100056);
- gpio_pehlpar = (volatile u16 *) (MCF_IPSBAR + 0x100058);
- *gpio_paspar |= 0x0f00;
- *gpio_pehlpar = 0xc0;
- }
-#endif
-
-#if defined(CONFIG_M527x)
- /* Set up gpio outputs for MII lines */
- {
- volatile u8 *gpio_par_fec;
- volatile u16 *gpio_par_feci2c;
-
- gpio_par_feci2c = (volatile u16 *)(MCF_IPSBAR + 0x100082);
- /* Set up gpio outputs for FEC0 MII lines */
- gpio_par_fec = (volatile u8 *)(MCF_IPSBAR + 0x100078);
-
- *gpio_par_feci2c |= 0x0f00;
- *gpio_par_fec |= 0xc0;
-
-#if defined(CONFIG_FEC2)
- /* Set up gpio outputs for FEC1 MII lines */
- gpio_par_fec = (volatile u8 *)(MCF_IPSBAR + 0x100079);
-
- *gpio_par_feci2c |= 0x00a0;
- *gpio_par_fec |= 0xc0;
-#endif /* CONFIG_FEC2 */
- }
-#endif /* CONFIG_M527x */
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
- fecp->fec_x_cntrl = 0x00;
-
- /*
- * Set MII speed to 2.5 MHz
- * See 5282 manual section 17.5.4.7: MSCR
- */
- fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
- fecp->fec_mii_speed = fep->phy_speed;
-
- fec_restart(dev, 0);
-}
-
-static void __inline__ fec_get_mac(struct net_device *dev)
-{
- struct fec_enet_private *fep = netdev_priv(dev);
- volatile fec_t *fecp;
- unsigned char *iap, tmpaddr[ETH_ALEN];
-
- fecp = fep->hwp;
-
- if (FEC_FLASHMAC) {
- /*
- * Get MAC address from FLASH.
- * If it is all 1's or 0's, use the default.
- */
- iap = FEC_FLASHMAC;
- if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
- (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
- iap = fec_mac_default;
- if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
- (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
- iap = fec_mac_default;
- } else {
- *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
- *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
- iap = &tmpaddr[0];
- }
-
- memcpy(dev->dev_addr, iap, ETH_ALEN);
-
- /* Adjust MAC if using default MAC address */
- if (iap == fec_mac_default)
- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_disable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-}
-
-static void __inline__ fec_localhw_setup(void)
-{
-}
-
-/*
- * Do not need to make region uncached on 5272.
- */
-static void __inline__ fec_uncache(unsigned long addr)
-{
-}
-
-/* ------------------------------------------------------------------------- */
-
-#elif defined(CONFIG_M520x)
-
-/*
- * Code specific to Coldfire 520x
- */
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
- struct fec_enet_private *fep;
- int b;
- static const struct idesc {
- char *name;
- unsigned short irq;
- } *idp, id[] = {
- { "fec(TXF)", 23 },
- { "fec(RXF)", 27 },
- { "fec(MII)", 29 },
- { NULL },
- };
-
- fep = netdev_priv(dev);
- b = 64 + 13;
-
- /* Setup interrupt handlers. */
- for (idp = id; idp->name; idp++) {
- if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name,dev) != 0)
- printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
- }
-
- /* Unmask interrupts at ColdFire interrupt controller */
- {
- volatile unsigned char *icrp;
- volatile unsigned long *imrp;
-
- icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
- MCFINTC_ICR0);
- for (b = 36; (b < 49); b++)
- icrp[b] = 0x04;
- imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 +
- MCFINTC_IMRH);
- *imrp &= ~0x0001FFF0;
- }
- *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FEC) |= 0xf0;
- *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C) |= 0x0f;
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
- fecp->fec_x_cntrl = 0x00;
-
- /*
- * Set MII speed to 2.5 MHz
- * See 5282 manual section 17.5.4.7: MSCR
- */
- fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
- fecp->fec_mii_speed = fep->phy_speed;
-
- fec_restart(dev, 0);
-}
-
+#ifdef CONFIG_M5272
static void __inline__ fec_get_mac(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
@@ -1578,146 +1255,7 @@ static void __inline__ fec_get_mac(struct net_device *dev)
* Get MAC address from FLASH.
* If it is all 1's or 0's, use the default.
*/
- iap = FEC_FLASHMAC;
- if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
- (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
- iap = fec_mac_default;
- if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
- (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
- iap = fec_mac_default;
- } else {
- *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
- *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
- iap = &tmpaddr[0];
- }
-
- memcpy(dev->dev_addr, iap, ETH_ALEN);
-
- /* Adjust MAC if using default MAC address */
- if (iap == fec_mac_default)
- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_disable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-}
-
-static void __inline__ fec_localhw_setup(void)
-{
-}
-
-static void __inline__ fec_uncache(unsigned long addr)
-{
-}
-
-/* ------------------------------------------------------------------------- */
-
-#elif defined(CONFIG_M532x)
-/*
- * Code specific for M532x
- */
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
- struct fec_enet_private *fep;
- int b;
- static const struct idesc {
- char *name;
- unsigned short irq;
- } *idp, id[] = {
- { "fec(TXF)", 36 },
- { "fec(RXF)", 40 },
- { "fec(MII)", 42 },
- { NULL },
- };
-
- fep = netdev_priv(dev);
- b = (fep->index) ? 128 : 64;
-
- /* Setup interrupt handlers. */
- for (idp = id; idp->name; idp++) {
- if (request_irq(b+idp->irq, fec_enet_interrupt, IRQF_DISABLED, idp->name,dev) != 0)
- printk("FEC: Could not allocate %s IRQ(%d)!\n",
- idp->name, b+idp->irq);
- }
-
- /* Unmask interrupts */
- MCF_INTC0_ICR36 = 0x2;
- MCF_INTC0_ICR37 = 0x2;
- MCF_INTC0_ICR38 = 0x2;
- MCF_INTC0_ICR39 = 0x2;
- MCF_INTC0_ICR40 = 0x2;
- MCF_INTC0_ICR41 = 0x2;
- MCF_INTC0_ICR42 = 0x2;
- MCF_INTC0_ICR43 = 0x2;
- MCF_INTC0_ICR44 = 0x2;
- MCF_INTC0_ICR45 = 0x2;
- MCF_INTC0_ICR46 = 0x2;
- MCF_INTC0_ICR47 = 0x2;
- MCF_INTC0_ICR48 = 0x2;
-
- MCF_INTC0_IMRH &= ~(
- MCF_INTC_IMRH_INT_MASK36 |
- MCF_INTC_IMRH_INT_MASK37 |
- MCF_INTC_IMRH_INT_MASK38 |
- MCF_INTC_IMRH_INT_MASK39 |
- MCF_INTC_IMRH_INT_MASK40 |
- MCF_INTC_IMRH_INT_MASK41 |
- MCF_INTC_IMRH_INT_MASK42 |
- MCF_INTC_IMRH_INT_MASK43 |
- MCF_INTC_IMRH_INT_MASK44 |
- MCF_INTC_IMRH_INT_MASK45 |
- MCF_INTC_IMRH_INT_MASK46 |
- MCF_INTC_IMRH_INT_MASK47 |
- MCF_INTC_IMRH_INT_MASK48 );
-
- /* Set up gpio outputs for MII lines */
- MCF_GPIO_PAR_FECI2C |= (0 |
- MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
- MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
- MCF_GPIO_PAR_FEC = (0 |
- MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC |
- MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC);
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
- fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
- fecp->fec_x_cntrl = 0x00;
-
- /*
- * Set MII speed to 2.5 MHz
- */
- fep->phy_speed = (MCF_CLK / 3) / (2500000 * 2 ) * 2;
- fecp->fec_mii_speed = fep->phy_speed;
-
- fec_restart(dev, 0);
-}
-
-static void __inline__ fec_get_mac(struct net_device *dev)
-{
- struct fec_enet_private *fep = netdev_priv(dev);
- volatile fec_t *fecp;
- unsigned char *iap, tmpaddr[ETH_ALEN];
-
- fecp = fep->hwp;
-
- if (FEC_FLASHMAC) {
- /*
- * Get MAC address from FLASH.
- * If it is all 1's or 0's, use the default.
- */
- iap = FEC_FLASHMAC;
+ iap = (unsigned char *)FEC_FLASHMAC;
if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
(iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
iap = fec_mac_default;
@@ -1734,122 +1272,8 @@ static void __inline__ fec_get_mac(struct net_device *dev)
/* Adjust MAC if using default MAC address */
if (iap == fec_mac_default)
- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_disable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-}
-
-static void __inline__ fec_localhw_setup(void)
-{
-}
-
-/*
- * Do not need to make region uncached on 532x.
- */
-static void __inline__ fec_uncache(unsigned long addr)
-{
-}
-
-/* ------------------------------------------------------------------------- */
-
-
-#else
-
-/*
- * Code specific to the MPC860T setup.
- */
-static void __inline__ fec_request_intrs(struct net_device *dev)
-{
- volatile immap_t *immap;
-
- immap = (immap_t *)IMAP_ADDR; /* pointer to internal registers */
-
- if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0)
- panic("Could not allocate FEC IRQ!");
-}
-
-static void __inline__ fec_get_mac(struct net_device *dev)
-{
- bd_t *bd;
-
- bd = (bd_t *)__res;
- memcpy(dev->dev_addr, bd->bi_enetaddr, ETH_ALEN);
-}
-
-static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
-{
- extern uint _get_IMMR(void);
- volatile immap_t *immap;
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
- immap = (immap_t *)IMAP_ADDR; /* pointer to internal registers */
-
- /* Configure all of port D for MII.
- */
- immap->im_ioport.iop_pdpar = 0x1fff;
-
- /* Bits moved from Rev. D onward.
- */
- if ((_get_IMMR() & 0xffff) < 0x0501)
- immap->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */
- else
- immap->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */
-
- /* Set MII speed to 2.5 MHz
- */
- fecp->fec_mii_speed = fep->phy_speed =
- ((bd->bi_busfreq * 1000000) / 2500000) & 0x7e;
-}
-
-static void __inline__ fec_enable_phy_intr(void)
-{
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
-
- /* Enable MII command finished interrupt
- */
- fecp->fec_ivec = (FEC_INTERRUPT/2) << 29;
-}
-
-static void __inline__ fec_disable_phy_intr(void)
-{
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-}
-
-static void __inline__ fec_localhw_setup(void)
-{
- volatile fec_t *fecp;
-
- fecp = fep->hwp;
- fecp->fec_r_hash = PKT_MAXBUF_SIZE;
- /* Enable big endian and don't care about SDMA FC.
- */
- fecp->fec_fun_code = 0x78000000;
-}
-
-static void __inline__ fec_uncache(unsigned long addr)
-{
- pte_t *pte;
- pte = va_to_pte(mem_addr);
- pte_val(*pte) |= _PAGE_NO_CACHE;
- flush_tlb_page(init_mm.mmap, mem_addr);
+ dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
}
-
#endif
/* ------------------------------------------------------------------------- */
@@ -2055,7 +1479,9 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
printk("FEC: No PHY device found.\n");
/* Disable external MII interface */
fecp->fec_mii_speed = fep->phy_speed = 0;
+#ifdef HAVE_mii_link_interrupt
fec_disable_phy_intr();
+#endif
}
}
@@ -2237,12 +1663,12 @@ fec_set_mac_address(struct net_device *dev)
}
-/* Initialize the FEC Ethernet on 860T (or ColdFire 5272).
- */
/*
* XXX: We need to clean up on failure exits here.
+ *
+ * index is only used in legacy code
*/
-int __init fec_enet_init(struct net_device *dev)
+int __init fec_enet_init(struct net_device *dev, int index)
{
struct fec_enet_private *fep = netdev_priv(dev);
unsigned long mem_addr;
@@ -2250,15 +1676,11 @@ int __init fec_enet_init(struct net_device *dev)
cbd_t *cbd_base;
volatile fec_t *fecp;
int i, j;
- static int index = 0;
-
- /* Only allow us to be probed once. */
- if (index >= FEC_MAX_PORTS)
- return -ENXIO;
/* Allocate memory for buffer descriptors.
*/
- mem_addr = __get_free_page(GFP_KERNEL);
+ mem_addr = (unsigned long)dma_alloc_coherent(NULL, PAGE_SIZE,
+ &fep->bd_dma, GFP_KERNEL);
if (mem_addr == 0) {
printk("FEC: allocate descriptor memory failed?\n");
return -ENOMEM;
@@ -2269,7 +1691,7 @@ int __init fec_enet_init(struct net_device *dev)
/* Create an Ethernet device instance.
*/
- fecp = (volatile fec_t *) fec_hw[index];
+ fecp = (volatile fec_t *)dev->base_addr;
fep->index = index;
fep->hwp = fecp;
@@ -2280,18 +1702,24 @@ int __init fec_enet_init(struct net_device *dev)
fecp->fec_ecntrl = 1;
udelay(10);
- /* Set the Ethernet address. If using multiple Enets on the 8xx,
- * this needs some work to get unique addresses.
- *
- * This is our default MAC address unless the user changes
- * it via eth_mac_addr (our dev->set_mac_addr handler).
- */
+ /* Set the Ethernet address */
+#ifdef CONFIG_M5272
fec_get_mac(dev);
+#else
+ {
+ unsigned long l;
+ l = fecp->fec_addr_low;
+ dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
+ dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
+ dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
+ dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
+ l = fecp->fec_addr_high;
+ dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
+ dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
+ }
+#endif
cbd_base = (cbd_t *)mem_addr;
- /* XXX: missing check for allocation failure */
-
- fec_uncache(mem_addr);
/* Set receive and transmit descriptor base.
*/
@@ -2313,8 +1741,6 @@ int __init fec_enet_init(struct net_device *dev)
mem_addr = __get_free_page(GFP_KERNEL);
/* XXX: missing check for allocation failure */
- fec_uncache(mem_addr);
-
/* Initialize the BD for every fragment in the page.
*/
for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
@@ -2357,13 +1783,13 @@ int __init fec_enet_init(struct net_device *dev)
/* Set receive and transmit descriptor base.
*/
- fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
- fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
+ fecp->fec_r_des_start = fep->bd_dma;
+ fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
+ * RX_RING_SIZE;
- /* Install our interrupt handlers. This varies depending on
- * the architecture.
- */
- fec_request_intrs(dev);
+#ifdef HAVE_mii_link_interrupt
+ fec_request_mii_intr(dev);
+#endif
fecp->fec_grp_hash_table_high = 0;
fecp->fec_grp_hash_table_low = 0;
@@ -2375,8 +1801,6 @@ int __init fec_enet_init(struct net_device *dev)
fecp->fec_hash_table_low = 0;
#endif
- dev->base_addr = (unsigned long)fecp;
-
/* The FEC Ethernet specific entries in the device structure. */
dev->open = fec_enet_open;
dev->hard_start_xmit = fec_enet_start_xmit;
@@ -2390,7 +1814,16 @@ int __init fec_enet_init(struct net_device *dev)
mii_free = mii_cmds;
/* setup MII interface */
- fec_set_mii(dev, fep);
+ fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
+ fecp->fec_x_cntrl = 0x00;
+
+ /*
+ * Set MII speed to 2.5 MHz
+ */
+ fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
+ / 2500000) / 2) & 0x3F) << 1;
+ fecp->fec_mii_speed = fep->phy_speed;
+ fec_restart(dev, 0);
/* Clear and enable interrupts */
fecp->fec_ievent = 0xffc00000;
@@ -2403,7 +1836,6 @@ int __init fec_enet_init(struct net_device *dev)
fep->phy_addr = 0;
mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy);
- index++;
return 0;
}
@@ -2430,7 +1862,6 @@ fec_restart(struct net_device *dev, int duplex)
/* Clear any outstanding interrupt.
*/
fecp->fec_ievent = 0xffc00000;
- fec_enable_phy_intr();
/* Set station address.
*/
@@ -2445,12 +1876,11 @@ fec_restart(struct net_device *dev, int duplex)
*/
fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
- fec_localhw_setup();
-
/* Set receive and transmit descriptor base.
*/
- fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
- fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
+ fecp->fec_r_des_start = fep->bd_dma;
+ fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
+ * RX_RING_SIZE;
fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
fep->cur_rx = fep->rx_bd_base;
@@ -2552,39 +1982,171 @@ fec_stop(struct net_device *dev)
/* Clear outstanding MII command interrupts.
*/
fecp->fec_ievent = FEC_ENET_MII;
- fec_enable_phy_intr();
fecp->fec_imask = FEC_ENET_MII;
fecp->fec_mii_speed = fep->phy_speed;
}
-static int __init fec_enet_module_init(void)
+static int __devinit
+fec_probe(struct platform_device *pdev)
{
- struct net_device *dev;
- int i, err;
-
- printk("FEC ENET Version 0.2\n");
-
- for (i = 0; (i < FEC_MAX_PORTS); i++) {
- dev = alloc_etherdev(sizeof(struct fec_enet_private));
- if (!dev)
- return -ENOMEM;
- err = fec_enet_init(dev);
- if (err) {
- free_netdev(dev);
- continue;
+ struct fec_enet_private *fep;
+ struct net_device *ndev;
+ int i, irq, ret = 0;
+ struct resource *r;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r)
+ return -ENXIO;
+
+ r = request_mem_region(r->start, resource_size(r), pdev->name);
+ if (!r)
+ return -EBUSY;
+
+ /* Init network device */
+ ndev = alloc_etherdev(sizeof(struct fec_enet_private));
+ if (!ndev)
+ return -ENOMEM;
+
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ /* setup board info structure */
+ fep = netdev_priv(ndev);
+ memset(fep, 0, sizeof(*fep));
+
+ ndev->base_addr = (unsigned long)ioremap(r->start, resource_size(r));
+
+ if (!ndev->base_addr) {
+ ret = -ENOMEM;
+ goto failed_ioremap;
+ }
+
+ platform_set_drvdata(pdev, ndev);
+
+ /* This device has up to three irqs on some platforms */
+ for (i = 0; i < 3; i++) {
+ irq = platform_get_irq(pdev, i);
+ if (i && irq < 0)
+ break;
+ ret = request_irq(irq, fec_enet_interrupt, IRQF_DISABLED, pdev->name, ndev);
+ if (ret) {
+ while (i >= 0) {
+ irq = platform_get_irq(pdev, i);
+ free_irq(irq, ndev);
+ i--;
+ }
+ goto failed_irq;
}
- if (register_netdev(dev) != 0) {
- /* XXX: missing cleanup here */
- free_netdev(dev);
- return -EIO;
+ }
+
+ fep->clk = clk_get(&pdev->dev, "fec_clk");
+ if (IS_ERR(fep->clk)) {
+ ret = PTR_ERR(fep->clk);
+ goto failed_clk;
+ }
+ clk_enable(fep->clk);
+
+ ret = fec_enet_init(ndev, 0);
+ if (ret)
+ goto failed_init;
+
+ ret = register_netdev(ndev);
+ if (ret)
+ goto failed_register;
+
+ return 0;
+
+failed_register:
+failed_init:
+ clk_disable(fep->clk);
+ clk_put(fep->clk);
+failed_clk:
+ for (i = 0; i < 3; i++) {
+ irq = platform_get_irq(pdev, i);
+ if (irq > 0)
+ free_irq(irq, ndev);
+ }
+failed_irq:
+ iounmap((void __iomem *)ndev->base_addr);
+failed_ioremap:
+ free_netdev(ndev);
+
+ return ret;
+}
+
+static int __devexit
+fec_drv_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct fec_enet_private *fep = netdev_priv(ndev);
+
+ platform_set_drvdata(pdev, NULL);
+
+ fec_stop(ndev);
+ clk_disable(fep->clk);
+ clk_put(fep->clk);
+ iounmap((void __iomem *)ndev->base_addr);
+ unregister_netdev(ndev);
+ free_netdev(ndev);
+ return 0;
+}
+
+static int
+fec_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct net_device *ndev = platform_get_drvdata(dev);
+ struct fec_enet_private *fep;
+
+ if (ndev) {
+ fep = netdev_priv(ndev);
+ if (netif_running(ndev)) {
+ netif_device_detach(ndev);
+ fec_stop(ndev);
}
+ }
+ return 0;
+}
- printk("%s: ethernet %pM\n", dev->name, dev->dev_addr);
+static int
+fec_resume(struct platform_device *dev)
+{
+ struct net_device *ndev = platform_get_drvdata(dev);
+
+ if (ndev) {
+ if (netif_running(ndev)) {
+ fec_enet_init(ndev, 0);
+ netif_device_attach(ndev);
+ }
}
return 0;
}
+static struct platform_driver fec_driver = {
+ .driver = {
+ .name = "fec",
+ .owner = THIS_MODULE,
+ },
+ .probe = fec_probe,
+ .remove = __devexit_p(fec_drv_remove),
+ .suspend = fec_suspend,
+ .resume = fec_resume,
+};
+
+static int __init
+fec_enet_module_init(void)
+{
+ printk(KERN_INFO "FEC Ethernet Driver\n");
+
+ return platform_driver_register(&fec_driver);
+}
+
+static void __exit
+fec_enet_cleanup(void)
+{
+ platform_driver_unregister(&fec_driver);
+}
+
+module_exit(fec_enet_cleanup);
module_init(fec_enet_module_init);
MODULE_LICENSE("GPL");
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 292719daceff..76c64c92e190 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -14,7 +14,7 @@
/****************************************************************************/
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M520x) || defined(CONFIG_M532x)
+ defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
/*
* Just figures, Motorola would have to change the offsets for
* registers in the same peripheral device on different models
@@ -103,12 +103,19 @@ typedef struct fec {
/*
* Define the buffer descriptor structure.
*/
+#ifdef CONFIG_ARCH_MXC
+typedef struct bufdesc {
+ unsigned short cbd_datlen; /* Data length */
+ unsigned short cbd_sc; /* Control and status info */
+ unsigned long cbd_bufaddr; /* Buffer address */
+} cbd_t;
+#else
typedef struct bufdesc {
unsigned short cbd_sc; /* Control and status info */
unsigned short cbd_datlen; /* Data length */
unsigned long cbd_bufaddr; /* Buffer address */
} cbd_t;
-
+#endif
/*
* The following definitions courtesy of commproc.h, which where
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index cd8e98b45ec5..8bbe7f617994 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -129,7 +129,8 @@ static void mpc52xx_fec_free_rx_buffers(struct net_device *dev, struct bcom_task
struct sk_buff *skb;
skb = bcom_retrieve_buffer(s, NULL, (struct bcom_bd **)&bd);
- dma_unmap_single(&dev->dev, bd->skb_pa, skb->len, DMA_FROM_DEVICE);
+ dma_unmap_single(dev->dev.parent, bd->skb_pa, skb->len,
+ DMA_FROM_DEVICE);
kfree_skb(skb);
}
}
@@ -150,7 +151,7 @@ static int mpc52xx_fec_alloc_rx_buffers(struct net_device *dev, struct bcom_task
bd = (struct bcom_fec_bd *)bcom_prepare_next_buffer(rxtsk);
bd->status = FEC_RX_BUFFER_SIZE;
- bd->skb_pa = dma_map_single(&dev->dev, skb->data,
+ bd->skb_pa = dma_map_single(dev->dev.parent, skb->data,
FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
bcom_submit_next_buffer(rxtsk, skb);
@@ -270,15 +271,6 @@ static void mpc52xx_fec_phy_stop(struct net_device *dev)
phy_write(priv->phydev, MII_BMCR, BMCR_PDOWN);
}
-static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv,
- struct mii_ioctl_data *mii_data, int cmd)
-{
- if (!priv->phydev)
- return -ENOTSUPP;
-
- return phy_mii_ioctl(priv->phydev, mii_data, cmd);
-}
-
static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv)
{
struct mpc52xx_fec __iomem *fec = priv->fec;
@@ -370,7 +362,7 @@ static int mpc52xx_fec_close(struct net_device *dev)
* invariant will hold if you make sure that the netif_*_queue()
* calls are done at the proper times.
*/
-static int mpc52xx_fec_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct mpc52xx_fec_priv *priv = netdev_priv(dev);
struct bcom_fec_bd *bd;
@@ -378,7 +370,7 @@ static int mpc52xx_fec_hard_start_xmit(struct sk_buff *skb, struct net_device *d
if (bcom_queue_full(priv->tx_dmatsk)) {
if (net_ratelimit())
dev_err(&dev->dev, "transmit queue overrun\n");
- return 1;
+ return NETDEV_TX_BUSY;
}
spin_lock_irq(&priv->lock);
@@ -388,7 +380,8 @@ static int mpc52xx_fec_hard_start_xmit(struct sk_buff *skb, struct net_device *d
bcom_prepare_next_buffer(priv->tx_dmatsk);
bd->status = skb->len | BCOM_FEC_TX_BD_TFD | BCOM_FEC_TX_BD_TC;
- bd->skb_pa = dma_map_single(&dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
+ bd->skb_pa = dma_map_single(dev->dev.parent, skb->data, skb->len,
+ DMA_TO_DEVICE);
bcom_submit_next_buffer(priv->tx_dmatsk, skb);
@@ -398,7 +391,7 @@ static int mpc52xx_fec_hard_start_xmit(struct sk_buff *skb, struct net_device *d
spin_unlock_irq(&priv->lock);
- return 0;
+ return NETDEV_TX_OK;
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -430,7 +423,8 @@ static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id)
struct bcom_fec_bd *bd;
skb = bcom_retrieve_buffer(priv->tx_dmatsk, NULL,
(struct bcom_bd **)&bd);
- dma_unmap_single(&dev->dev, bd->skb_pa, skb->len, DMA_TO_DEVICE);
+ dma_unmap_single(dev->dev.parent, bd->skb_pa, skb->len,
+ DMA_TO_DEVICE);
dev_kfree_skb_irq(skb);
}
@@ -455,7 +449,8 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id)
rskb = bcom_retrieve_buffer(priv->rx_dmatsk, &status,
(struct bcom_bd **)&bd);
- dma_unmap_single(&dev->dev, bd->skb_pa, rskb->len, DMA_FROM_DEVICE);
+ dma_unmap_single(dev->dev.parent, bd->skb_pa, rskb->len,
+ DMA_FROM_DEVICE);
/* Test for errors in received frame */
if (status & BCOM_FEC_RX_BD_ERRORS) {
@@ -464,7 +459,8 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id)
bcom_prepare_next_buffer(priv->rx_dmatsk);
bd->status = FEC_RX_BUFFER_SIZE;
- bd->skb_pa = dma_map_single(&dev->dev, rskb->data,
+ bd->skb_pa = dma_map_single(dev->dev.parent,
+ rskb->data,
FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
bcom_submit_next_buffer(priv->rx_dmatsk, rskb);
@@ -499,7 +495,7 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id)
bcom_prepare_next_buffer(priv->rx_dmatsk);
bd->status = FEC_RX_BUFFER_SIZE;
- bd->skb_pa = dma_map_single(&dev->dev, skb->data,
+ bd->skb_pa = dma_map_single(dev->dev.parent, skb->data,
FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
bcom_submit_next_buffer(priv->rx_dmatsk, skb);
@@ -847,12 +843,20 @@ static void mpc52xx_fec_get_drvinfo(struct net_device *dev,
static int mpc52xx_fec_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+
+ if (!priv->phydev)
+ return -ENODEV;
+
return phy_ethtool_gset(priv->phydev, cmd);
}
static int mpc52xx_fec_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+
+ if (!priv->phydev)
+ return -ENODEV;
+
return phy_ethtool_sset(priv->phydev, cmd);
}
@@ -882,9 +886,28 @@ static int mpc52xx_fec_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct mpc52xx_fec_priv *priv = netdev_priv(dev);
- return mpc52xx_fec_phy_mii_ioctl(priv, if_mii(rq), cmd);
+ if (!priv->phydev)
+ return -ENOTSUPP;
+
+ return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
}
+static const struct net_device_ops mpc52xx_fec_netdev_ops = {
+ .ndo_open = mpc52xx_fec_open,
+ .ndo_stop = mpc52xx_fec_close,
+ .ndo_start_xmit = mpc52xx_fec_start_xmit,
+ .ndo_set_multicast_list = mpc52xx_fec_set_multicast_list,
+ .ndo_set_mac_address = mpc52xx_fec_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = mpc52xx_fec_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_tx_timeout = mpc52xx_fec_tx_timeout,
+ .ndo_get_stats = mpc52xx_fec_get_stats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = mpc52xx_fec_poll_controller,
+#endif
+};
+
/* ======================================================================== */
/* OF Driver */
/* ======================================================================== */
@@ -929,22 +952,10 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
return -EBUSY;
/* Init ether ndev with what we have */
- ndev->open = mpc52xx_fec_open;
- ndev->stop = mpc52xx_fec_close;
- ndev->hard_start_xmit = mpc52xx_fec_hard_start_xmit;
- ndev->do_ioctl = mpc52xx_fec_ioctl;
+ ndev->netdev_ops = &mpc52xx_fec_netdev_ops;
ndev->ethtool_ops = &mpc52xx_fec_ethtool_ops;
- ndev->get_stats = mpc52xx_fec_get_stats;
- ndev->set_mac_address = mpc52xx_fec_set_mac_address;
- ndev->set_multicast_list = mpc52xx_fec_set_multicast_list;
- ndev->tx_timeout = mpc52xx_fec_tx_timeout;
ndev->watchdog_timeo = FEC_WATCHDOG_TIMEOUT;
ndev->base_addr = mem.start;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- ndev->poll_controller = mpc52xx_fec_poll_controller;
-#endif
-
- priv->t_irq = priv->r_irq = ndev->irq = NO_IRQ; /* IRQ are free for now */
spin_lock_init(&priv->lock);
@@ -1123,9 +1134,9 @@ static int mpc52xx_fec_of_resume(struct of_device *op)
#endif
static struct of_device_id mpc52xx_fec_match[] = {
- { .type = "network", .compatible = "fsl,mpc5200b-fec", },
- { .type = "network", .compatible = "fsl,mpc5200-fec", },
- { .type = "network", .compatible = "mpc5200-fec", },
+ { .compatible = "fsl,mpc5200b-fec", },
+ { .compatible = "fsl,mpc5200-fec", },
+ { .compatible = "mpc5200-fec", },
{ }
};
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index b8251e827059..a858c6ff80dd 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -39,7 +39,7 @@
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* superfluous timer interrupts from the nic.
*/
-#define FORCEDETH_VERSION "0.62"
+#define FORCEDETH_VERSION "0.64"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
@@ -87,8 +87,8 @@
#define DEV_HAS_MSI_X 0x000080 /* device supports MSI-X */
#define DEV_HAS_POWER_CNTRL 0x000100 /* device supports power savings */
#define DEV_HAS_STATISTICS_V1 0x000200 /* device supports hw statistics version 1 */
-#define DEV_HAS_STATISTICS_V2 0x000400 /* device supports hw statistics version 2 */
-#define DEV_HAS_STATISTICS_V3 0x000800 /* device supports hw statistics version 3 */
+#define DEV_HAS_STATISTICS_V2 0x000600 /* device supports hw statistics version 2 */
+#define DEV_HAS_STATISTICS_V3 0x000e00 /* device supports hw statistics version 3 */
#define DEV_HAS_TEST_EXTENDED 0x001000 /* device supports extended diagnostic test */
#define DEV_HAS_MGMT_UNIT 0x002000 /* device supports management unit */
#define DEV_HAS_CORRECT_MACADDR 0x004000 /* device supports correct mac address order */
@@ -102,7 +102,7 @@
enum {
NvRegIrqStatus = 0x000,
#define NVREG_IRQSTAT_MIIEVENT 0x040
-#define NVREG_IRQSTAT_MASK 0x81ff
+#define NVREG_IRQSTAT_MASK 0x83ff
NvRegIrqMask = 0x004,
#define NVREG_IRQ_RX_ERROR 0x0001
#define NVREG_IRQ_RX 0x0002
@@ -113,17 +113,13 @@ enum {
#define NVREG_IRQ_LINK 0x0040
#define NVREG_IRQ_RX_FORCED 0x0080
#define NVREG_IRQ_TX_FORCED 0x0100
-#define NVREG_IRQ_RECOVER_ERROR 0x8000
+#define NVREG_IRQ_RECOVER_ERROR 0x8200
#define NVREG_IRQMASK_THROUGHPUT 0x00df
#define NVREG_IRQMASK_CPU 0x0060
#define NVREG_IRQ_TX_ALL (NVREG_IRQ_TX_ERR|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_FORCED)
#define NVREG_IRQ_RX_ALL (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_RX_FORCED)
#define NVREG_IRQ_OTHER (NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RECOVER_ERROR)
-#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR| \
- NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RX_FORCED| \
- NVREG_IRQ_TX_FORCED|NVREG_IRQ_RECOVER_ERROR))
-
NvRegUnknownSetupReg6 = 0x008,
#define NVREG_UNKSETUP6_VAL 3
@@ -132,7 +128,7 @@ enum {
* NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
*/
NvRegPollingInterval = 0x00c,
-#define NVREG_POLL_DEFAULT_THROUGHPUT 970 /* backup tx cleanup if loop max reached */
+#define NVREG_POLL_DEFAULT_THROUGHPUT 65535 /* backup tx cleanup if loop max reached */
#define NVREG_POLL_DEFAULT_CPU 13
NvRegMSIMap0 = 0x020,
NvRegMSIMap1 = 0x024,
@@ -157,6 +153,9 @@ enum {
#define NVREG_XMITCTL_HOST_SEMA_ACQ 0x0000f000
#define NVREG_XMITCTL_HOST_LOADED 0x00004000
#define NVREG_XMITCTL_TX_PATH_EN 0x01000000
+#define NVREG_XMITCTL_DATA_START 0x00100000
+#define NVREG_XMITCTL_DATA_READY 0x00010000
+#define NVREG_XMITCTL_DATA_ERROR 0x00020000
NvRegTransmitterStatus = 0x088,
#define NVREG_XMITSTAT_BUSY 0x01
@@ -289,8 +288,10 @@ enum {
#define NVREG_WAKEUPFLAGS_ACCEPT_LINKCHANGE 0x04
#define NVREG_WAKEUPFLAGS_ENABLE 0x1111
- NvRegPatternCRC = 0x204,
- NvRegPatternMask = 0x208,
+ NvRegMgmtUnitGetVersion = 0x204,
+#define NVREG_MGMTUNITGETVERSION 0x01
+ NvRegMgmtUnitVersion = 0x208,
+#define NVREG_MGMTUNITVERSION 0x08
NvRegPowerCap = 0x268,
#define NVREG_POWERCAP_D3SUPP (1<<30)
#define NVREG_POWERCAP_D2SUPP (1<<26)
@@ -303,6 +304,8 @@ enum {
#define NVREG_POWERSTATE_D1 0x0001
#define NVREG_POWERSTATE_D2 0x0002
#define NVREG_POWERSTATE_D3 0x0003
+ NvRegMgmtUnitControl = 0x278,
+#define NVREG_MGMTUNITCONTROL_INUSE 0x20000
NvRegTxCnt = 0x280,
NvRegTxZeroReXmt = 0x284,
NvRegTxOneReXmt = 0x288,
@@ -460,7 +463,7 @@ union ring_type {
/* General driver defaults */
#define NV_WATCHDOG_TIMEO (5*HZ)
-#define RX_RING_DEFAULT 128
+#define RX_RING_DEFAULT 512
#define TX_RING_DEFAULT 256
#define RX_RING_MIN 128
#define TX_RING_MIN 64
@@ -582,11 +585,17 @@ union ring_type {
#define NV_MSI_X_VECTOR_TX 0x1
#define NV_MSI_X_VECTOR_OTHER 0x2
+#define NV_MSI_PRIV_OFFSET 0x68
+#define NV_MSI_PRIV_VALUE 0xffffffff
+
#define NV_RESTART_TX 0x1
#define NV_RESTART_RX 0x2
#define NV_TX_LIMIT_COUNT 16
+#define NV_DYNAMIC_THRESHOLD 4
+#define NV_DYNAMIC_MAX_QUIET_COUNT 2048
+
/* statistics */
struct nv_ethtool_str {
char name[ETH_GSTRING_LEN];
@@ -744,11 +753,13 @@ struct fe_priv {
u16 gigabit;
int intr_test;
int recover_error;
+ int quiet_count;
/* General data: RO fields */
dma_addr_t ring_addr;
struct pci_dev *pci_dev;
u32 orig_mac[2];
+ u32 events;
u32 irqmask;
u32 desc_ver;
u32 txrxctl_bits;
@@ -758,6 +769,8 @@ struct fe_priv {
u32 register_size;
int rx_csum;
u32 mac_in_use;
+ int mgmt_version;
+ int mgmt_sema;
void __iomem *base;
@@ -812,13 +825,18 @@ struct fe_priv {
/* power saved state */
u32 saved_config_space[NV_PCI_REGSZ_MAX/4];
+
+ /* for different msi-x irq type */
+ char name_rx[IFNAMSIZ + 3]; /* -rx */
+ char name_tx[IFNAMSIZ + 3]; /* -tx */
+ char name_other[IFNAMSIZ + 6]; /* -other */
};
/*
* Maximum number of loops until we assume that a bit in the irq mask
* is stuck. Overridable with module param.
*/
-static int max_interrupt_work = 15;
+static int max_interrupt_work = 4;
/*
* Optimization can be either throuput mode or cpu mode
@@ -828,9 +846,10 @@ static int max_interrupt_work = 15;
*/
enum {
NV_OPTIMIZATION_MODE_THROUGHPUT,
- NV_OPTIMIZATION_MODE_CPU
+ NV_OPTIMIZATION_MODE_CPU,
+ NV_OPTIMIZATION_MODE_DYNAMIC
};
-static int optimization_mode = NV_OPTIMIZATION_MODE_THROUGHPUT;
+static int optimization_mode = NV_OPTIMIZATION_MODE_DYNAMIC;
/*
* Poll interval for timer irq
@@ -857,7 +876,7 @@ enum {
NV_MSIX_INT_DISABLED,
NV_MSIX_INT_ENABLED
};
-static int msix = NV_MSIX_INT_DISABLED;
+static int msix = NV_MSIX_INT_ENABLED;
/*
* DMA 64bit
@@ -923,7 +942,7 @@ static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target,
delaymax -= delay;
if (delaymax < 0) {
if (msg)
- printk(msg);
+ printk("%s", msg);
return 1;
}
} while ((readl(base + offset) & mask) != target);
@@ -1052,6 +1071,24 @@ static void nv_disable_hw_interrupts(struct net_device *dev, u32 mask)
}
}
+static void nv_napi_enable(struct net_device *dev)
+{
+#ifdef CONFIG_FORCEDETH_NAPI
+ struct fe_priv *np = get_nvpriv(dev);
+
+ napi_enable(&np->napi);
+#endif
+}
+
+static void nv_napi_disable(struct net_device *dev)
+{
+#ifdef CONFIG_FORCEDETH_NAPI
+ struct fe_priv *np = get_nvpriv(dev);
+
+ napi_disable(&np->napi);
+#endif
+}
+
#define MII_READ (-1)
/* mii_rw: read/write a register on the PHY.
*
@@ -1760,7 +1797,7 @@ static void nv_do_rx_refill(unsigned long data)
struct fe_priv *np = netdev_priv(dev);
/* Just reschedule NAPI rx processing */
- netif_rx_schedule(&np->napi);
+ napi_schedule(&np->napi);
}
#else
static void nv_do_rx_refill(unsigned long data)
@@ -2365,14 +2402,16 @@ static inline void nv_tx_flip_ownership(struct net_device *dev)
*
* Caller must own np->lock.
*/
-static void nv_tx_done(struct net_device *dev)
+static int nv_tx_done(struct net_device *dev, int limit)
{
struct fe_priv *np = netdev_priv(dev);
u32 flags;
+ int tx_work = 0;
struct ring_desc* orig_get_tx = np->get_tx.orig;
while ((np->get_tx.orig != np->put_tx.orig) &&
- !((flags = le32_to_cpu(np->get_tx.orig->flaglen)) & NV_TX_VALID)) {
+ !((flags = le32_to_cpu(np->get_tx.orig->flaglen)) & NV_TX_VALID) &&
+ (tx_work < limit)) {
dprintk(KERN_DEBUG "%s: nv_tx_done: flags 0x%x.\n",
dev->name, flags);
@@ -2398,6 +2437,7 @@ static void nv_tx_done(struct net_device *dev)
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
+ tx_work++;
}
} else {
if (flags & NV_TX2_LASTPACKET) {
@@ -2415,6 +2455,7 @@ static void nv_tx_done(struct net_device *dev)
}
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
+ tx_work++;
}
}
if (unlikely(np->get_tx.orig++ == np->last_tx.orig))
@@ -2426,17 +2467,19 @@ static void nv_tx_done(struct net_device *dev)
np->tx_stop = 0;
netif_wake_queue(dev);
}
+ return tx_work;
}
-static void nv_tx_done_optimized(struct net_device *dev, int limit)
+static int nv_tx_done_optimized(struct net_device *dev, int limit)
{
struct fe_priv *np = netdev_priv(dev);
u32 flags;
+ int tx_work = 0;
struct ring_desc_ex* orig_get_tx = np->get_tx.ex;
while ((np->get_tx.ex != np->put_tx.ex) &&
!((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX_VALID) &&
- (limit-- > 0)) {
+ (tx_work < limit)) {
dprintk(KERN_DEBUG "%s: nv_tx_done_optimized: flags 0x%x.\n",
dev->name, flags);
@@ -2460,6 +2503,7 @@ static void nv_tx_done_optimized(struct net_device *dev, int limit)
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
+ tx_work++;
if (np->tx_limit) {
nv_tx_flip_ownership(dev);
@@ -2474,6 +2518,7 @@ static void nv_tx_done_optimized(struct net_device *dev, int limit)
np->tx_stop = 0;
netif_wake_queue(dev);
}
+ return tx_work;
}
/*
@@ -2546,7 +2591,7 @@ static void nv_tx_timeout(struct net_device *dev)
/* 2) check that the packets were not sent already: */
if (!nv_optimized(np))
- nv_tx_done(dev);
+ nv_tx_done(dev, np->tx_ring_size);
else
nv_tx_done_optimized(dev, np->tx_ring_size);
@@ -2907,6 +2952,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
* Changing the MTU is a rare event, it shouldn't matter.
*/
nv_disable_irq(dev);
+ nv_napi_disable(dev);
netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock(&np->lock);
@@ -2935,6 +2981,7 @@ static int nv_change_mtu(struct net_device *dev, int new_mtu)
spin_unlock(&np->lock);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
+ nv_napi_enable(dev);
nv_enable_irq(dev);
}
return 0;
@@ -3375,50 +3422,71 @@ static void nv_msi_workaround(struct fe_priv *np)
}
}
+static inline int nv_change_interrupt_mode(struct net_device *dev, int total_work)
+{
+ struct fe_priv *np = netdev_priv(dev);
+
+ if (optimization_mode == NV_OPTIMIZATION_MODE_DYNAMIC) {
+ if (total_work > NV_DYNAMIC_THRESHOLD) {
+ /* transition to poll based interrupts */
+ np->quiet_count = 0;
+ if (np->irqmask != NVREG_IRQMASK_CPU) {
+ np->irqmask = NVREG_IRQMASK_CPU;
+ return 1;
+ }
+ } else {
+ if (np->quiet_count < NV_DYNAMIC_MAX_QUIET_COUNT) {
+ np->quiet_count++;
+ } else {
+ /* reached a period of low activity, switch
+ to per tx/rx packet interrupts */
+ if (np->irqmask != NVREG_IRQMASK_THROUGHPUT) {
+ np->irqmask = NVREG_IRQMASK_THROUGHPUT;
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
static irqreturn_t nv_nic_irq(int foo, void *data)
{
struct net_device *dev = (struct net_device *) data;
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
- u32 events;
- int i;
+#ifndef CONFIG_FORCEDETH_NAPI
+ int total_work = 0;
+ int loop_count = 0;
+#endif
dprintk(KERN_DEBUG "%s: nv_nic_irq\n", dev->name);
- for (i=0; ; i++) {
- if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
- events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK;
- writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
- } else {
- events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK;
- writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
- }
- dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events);
- if (!(events & np->irqmask))
- break;
-
- nv_msi_workaround(np);
+ if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
+ np->events = readl(base + NvRegIrqStatus);
+ writel(np->events, base + NvRegIrqStatus);
+ } else {
+ np->events = readl(base + NvRegMSIXIrqStatus);
+ writel(np->events, base + NvRegMSIXIrqStatus);
+ }
+ dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
+ if (!(np->events & np->irqmask))
+ return IRQ_NONE;
- spin_lock(&np->lock);
- nv_tx_done(dev);
- spin_unlock(&np->lock);
+ nv_msi_workaround(np);
#ifdef CONFIG_FORCEDETH_NAPI
- if (events & NVREG_IRQ_RX_ALL) {
- spin_lock(&np->lock);
- netif_rx_schedule(&np->napi);
+ napi_schedule(&np->napi);
- /* Disable furthur receive irq's */
- np->irqmask &= ~NVREG_IRQ_RX_ALL;
+ /* Disable furthur irq's
+ (msix not enabled with napi) */
+ writel(0, base + NvRegIrqMask);
- if (np->msi_flags & NV_MSI_X_ENABLED)
- writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
- spin_unlock(&np->lock);
- }
#else
- if (nv_rx_process(dev, RX_WORK_PER_LOOP)) {
+ do
+ {
+ int work = 0;
+ if ((work = nv_rx_process(dev, RX_WORK_PER_LOOP))) {
if (unlikely(nv_alloc_rx(dev))) {
spin_lock(&np->lock);
if (!np->in_shutdown)
@@ -3426,65 +3494,56 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
spin_unlock(&np->lock);
}
}
-#endif
- if (unlikely(events & NVREG_IRQ_LINK)) {
- spin_lock(&np->lock);
- nv_link_irq(dev);
- spin_unlock(&np->lock);
- }
- if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
- spin_lock(&np->lock);
- nv_linkchange(dev);
- spin_unlock(&np->lock);
- np->link_timeout = jiffies + LINK_TIMEOUT;
- }
- if (unlikely(events & (NVREG_IRQ_TX_ERR))) {
- dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
- dev->name, events);
- }
- if (unlikely(events & (NVREG_IRQ_UNKNOWN))) {
- printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n",
- dev->name, events);
- }
- if (unlikely(events & NVREG_IRQ_RECOVER_ERROR)) {
- spin_lock(&np->lock);
- /* disable interrupts on the nic */
- if (!(np->msi_flags & NV_MSI_X_ENABLED))
- writel(0, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
- pci_push(base);
- if (!np->in_shutdown) {
- np->nic_poll_irq = np->irqmask;
- np->recover_error = 1;
- mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
- }
- spin_unlock(&np->lock);
- break;
- }
- if (unlikely(i > max_interrupt_work)) {
- spin_lock(&np->lock);
- /* disable interrupts on the nic */
- if (!(np->msi_flags & NV_MSI_X_ENABLED))
- writel(0, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
- pci_push(base);
+ spin_lock(&np->lock);
+ work += nv_tx_done(dev, TX_WORK_PER_LOOP);
+ spin_unlock(&np->lock);
- if (!np->in_shutdown) {
- np->nic_poll_irq = np->irqmask;
- mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
- }
- spin_unlock(&np->lock);
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
+ if (!work)
break;
- }
+ total_work += work;
+
+ loop_count++;
+ }
+ while (loop_count < max_interrupt_work);
+
+ if (nv_change_interrupt_mode(dev, total_work)) {
+ /* setup new irq mask */
+ writel(np->irqmask, base + NvRegIrqMask);
+ }
+
+ if (unlikely(np->events & NVREG_IRQ_LINK)) {
+ spin_lock(&np->lock);
+ nv_link_irq(dev);
+ spin_unlock(&np->lock);
+ }
+ if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
+ spin_lock(&np->lock);
+ nv_linkchange(dev);
+ spin_unlock(&np->lock);
+ np->link_timeout = jiffies + LINK_TIMEOUT;
+ }
+ if (unlikely(np->events & NVREG_IRQ_RECOVER_ERROR)) {
+ spin_lock(&np->lock);
+ /* disable interrupts on the nic */
+ if (!(np->msi_flags & NV_MSI_X_ENABLED))
+ writel(0, base + NvRegIrqMask);
+ else
+ writel(np->irqmask, base + NvRegIrqMask);
+ pci_push(base);
+
+ if (!np->in_shutdown) {
+ np->nic_poll_irq = np->irqmask;
+ np->recover_error = 1;
+ mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ }
+ spin_unlock(&np->lock);
}
+#endif
dprintk(KERN_DEBUG "%s: nv_nic_irq completed\n", dev->name);
- return IRQ_RETVAL(i);
+ return IRQ_HANDLED;
}
/**
@@ -3497,45 +3556,38 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
struct net_device *dev = (struct net_device *) data;
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
- u32 events;
- int i;
+#ifndef CONFIG_FORCEDETH_NAPI
+ int total_work = 0;
+ int loop_count = 0;
+#endif
dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized\n", dev->name);
- for (i=0; ; i++) {
- if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
- events = readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK;
- writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
- } else {
- events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQSTAT_MASK;
- writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
- }
- dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events);
- if (!(events & np->irqmask))
- break;
-
- nv_msi_workaround(np);
+ if (!(np->msi_flags & NV_MSI_X_ENABLED)) {
+ np->events = readl(base + NvRegIrqStatus);
+ writel(np->events, base + NvRegIrqStatus);
+ } else {
+ np->events = readl(base + NvRegMSIXIrqStatus);
+ writel(np->events, base + NvRegMSIXIrqStatus);
+ }
+ dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, np->events);
+ if (!(np->events & np->irqmask))
+ return IRQ_NONE;
- spin_lock(&np->lock);
- nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
- spin_unlock(&np->lock);
+ nv_msi_workaround(np);
#ifdef CONFIG_FORCEDETH_NAPI
- if (events & NVREG_IRQ_RX_ALL) {
- spin_lock(&np->lock);
- netif_rx_schedule(&np->napi);
+ napi_schedule(&np->napi);
- /* Disable furthur receive irq's */
- np->irqmask &= ~NVREG_IRQ_RX_ALL;
+ /* Disable furthur irq's
+ (msix not enabled with napi) */
+ writel(0, base + NvRegIrqMask);
- if (np->msi_flags & NV_MSI_X_ENABLED)
- writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
- spin_unlock(&np->lock);
- }
#else
- if (nv_rx_process_optimized(dev, RX_WORK_PER_LOOP)) {
+ do
+ {
+ int work = 0;
+ if ((work = nv_rx_process_optimized(dev, RX_WORK_PER_LOOP))) {
if (unlikely(nv_alloc_rx_optimized(dev))) {
spin_lock(&np->lock);
if (!np->in_shutdown)
@@ -3543,66 +3595,57 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
spin_unlock(&np->lock);
}
}
-#endif
- if (unlikely(events & NVREG_IRQ_LINK)) {
- spin_lock(&np->lock);
- nv_link_irq(dev);
- spin_unlock(&np->lock);
- }
- if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
- spin_lock(&np->lock);
- nv_linkchange(dev);
- spin_unlock(&np->lock);
- np->link_timeout = jiffies + LINK_TIMEOUT;
- }
- if (unlikely(events & (NVREG_IRQ_TX_ERR))) {
- dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
- dev->name, events);
- }
- if (unlikely(events & (NVREG_IRQ_UNKNOWN))) {
- printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n",
- dev->name, events);
- }
- if (unlikely(events & NVREG_IRQ_RECOVER_ERROR)) {
- spin_lock(&np->lock);
- /* disable interrupts on the nic */
- if (!(np->msi_flags & NV_MSI_X_ENABLED))
- writel(0, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
- pci_push(base);
- if (!np->in_shutdown) {
- np->nic_poll_irq = np->irqmask;
- np->recover_error = 1;
- mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
- }
- spin_unlock(&np->lock);
+ spin_lock(&np->lock);
+ work += nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
+ spin_unlock(&np->lock);
+
+ if (!work)
break;
- }
- if (unlikely(i > max_interrupt_work)) {
- spin_lock(&np->lock);
- /* disable interrupts on the nic */
- if (!(np->msi_flags & NV_MSI_X_ENABLED))
- writel(0, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
- pci_push(base);
+ total_work += work;
- if (!np->in_shutdown) {
- np->nic_poll_irq = np->irqmask;
- mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
- }
- spin_unlock(&np->lock);
- printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
- break;
- }
+ loop_count++;
+ }
+ while (loop_count < max_interrupt_work);
+ if (nv_change_interrupt_mode(dev, total_work)) {
+ /* setup new irq mask */
+ writel(np->irqmask, base + NvRegIrqMask);
}
+
+ if (unlikely(np->events & NVREG_IRQ_LINK)) {
+ spin_lock(&np->lock);
+ nv_link_irq(dev);
+ spin_unlock(&np->lock);
+ }
+ if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
+ spin_lock(&np->lock);
+ nv_linkchange(dev);
+ spin_unlock(&np->lock);
+ np->link_timeout = jiffies + LINK_TIMEOUT;
+ }
+ if (unlikely(np->events & NVREG_IRQ_RECOVER_ERROR)) {
+ spin_lock(&np->lock);
+ /* disable interrupts on the nic */
+ if (!(np->msi_flags & NV_MSI_X_ENABLED))
+ writel(0, base + NvRegIrqMask);
+ else
+ writel(np->irqmask, base + NvRegIrqMask);
+ pci_push(base);
+
+ if (!np->in_shutdown) {
+ np->nic_poll_irq = np->irqmask;
+ np->recover_error = 1;
+ mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ }
+ spin_unlock(&np->lock);
+ }
+
+#endif
dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized completed\n", dev->name);
- return IRQ_RETVAL(i);
+ return IRQ_HANDLED;
}
static irqreturn_t nv_nic_irq_tx(int foo, void *data)
@@ -3627,10 +3670,6 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data)
nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
spin_unlock_irqrestore(&np->lock, flags);
- if (unlikely(events & (NVREG_IRQ_TX_ERR))) {
- dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
- dev->name, events);
- }
if (unlikely(i > max_interrupt_work)) {
spin_lock_irqsave(&np->lock, flags);
/* disable interrupts on the nic */
@@ -3659,13 +3698,22 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
struct net_device *dev = np->dev;
u8 __iomem *base = get_hwbase(dev);
unsigned long flags;
- int pkts, retcode;
+ int retcode;
+ int tx_work, rx_work;
if (!nv_optimized(np)) {
- pkts = nv_rx_process(dev, budget);
+ spin_lock_irqsave(&np->lock, flags);
+ tx_work = nv_tx_done(dev, np->tx_ring_size);
+ spin_unlock_irqrestore(&np->lock, flags);
+
+ rx_work = nv_rx_process(dev, budget);
retcode = nv_alloc_rx(dev);
} else {
- pkts = nv_rx_process_optimized(dev, budget);
+ spin_lock_irqsave(&np->lock, flags);
+ tx_work = nv_tx_done_optimized(dev, np->tx_ring_size);
+ spin_unlock_irqrestore(&np->lock, flags);
+
+ rx_work = nv_rx_process_optimized(dev, budget);
retcode = nv_alloc_rx_optimized(dev);
}
@@ -3676,44 +3724,42 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
spin_unlock_irqrestore(&np->lock, flags);
}
- if (pkts < budget) {
- /* re-enable receive interrupts */
- spin_lock_irqsave(&np->lock, flags);
-
- __netif_rx_complete(napi);
-
- np->irqmask |= NVREG_IRQ_RX_ALL;
- if (np->msi_flags & NV_MSI_X_ENABLED)
- writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
+ nv_change_interrupt_mode(dev, tx_work + rx_work);
+ if (unlikely(np->events & NVREG_IRQ_LINK)) {
+ spin_lock_irqsave(&np->lock, flags);
+ nv_link_irq(dev);
spin_unlock_irqrestore(&np->lock, flags);
}
- return pkts;
-}
-#endif
-
-#ifdef CONFIG_FORCEDETH_NAPI
-static irqreturn_t nv_nic_irq_rx(int foo, void *data)
-{
- struct net_device *dev = (struct net_device *) data;
- struct fe_priv *np = netdev_priv(dev);
- u8 __iomem *base = get_hwbase(dev);
- u32 events;
+ if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
+ spin_lock_irqsave(&np->lock, flags);
+ nv_linkchange(dev);
+ spin_unlock_irqrestore(&np->lock, flags);
+ np->link_timeout = jiffies + LINK_TIMEOUT;
+ }
+ if (unlikely(np->events & NVREG_IRQ_RECOVER_ERROR)) {
+ spin_lock_irqsave(&np->lock, flags);
+ if (!np->in_shutdown) {
+ np->nic_poll_irq = np->irqmask;
+ np->recover_error = 1;
+ mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ }
+ spin_unlock_irqrestore(&np->lock, flags);
+ __napi_complete(napi);
+ return rx_work;
+ }
- events = readl(base + NvRegMSIXIrqStatus) & NVREG_IRQ_RX_ALL;
- writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus);
+ if (rx_work < budget) {
+ /* re-enable interrupts
+ (msix not enabled in napi) */
+ __napi_complete(napi);
- if (events) {
- netif_rx_schedule(&np->napi);
- /* disable receive interrupts on the nic */
- writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
- pci_push(base);
+ writel(np->irqmask, base + NvRegIrqMask);
}
- return IRQ_HANDLED;
+ return rx_work;
}
-#else
+#endif
+
static irqreturn_t nv_nic_irq_rx(int foo, void *data)
{
struct net_device *dev = (struct net_device *) data;
@@ -3760,7 +3806,6 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data)
return IRQ_RETVAL(i);
}
-#endif
static irqreturn_t nv_nic_irq_other(int foo, void *data)
{
@@ -3810,10 +3855,6 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data)
spin_unlock_irq(&np->lock);
break;
}
- if (events & (NVREG_IRQ_UNKNOWN)) {
- printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n",
- dev->name, events);
- }
if (unlikely(i > max_interrupt_work)) {
spin_lock_irqsave(&np->lock, flags);
/* disable interrupts on the nic */
@@ -3918,21 +3959,27 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
np->msi_flags |= NV_MSI_X_ENABLED;
if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT && !intr_test) {
/* Request irq for rx handling */
- if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, IRQF_SHARED, dev->name, dev) != 0) {
+ sprintf(np->name_rx, "%s-rx", dev->name);
+ if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector,
+ &nv_nic_irq_rx, IRQF_SHARED, np->name_rx, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
goto out_err;
}
/* Request irq for tx handling */
- if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, &nv_nic_irq_tx, IRQF_SHARED, dev->name, dev) != 0) {
+ sprintf(np->name_tx, "%s-tx", dev->name);
+ if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector,
+ &nv_nic_irq_tx, IRQF_SHARED, np->name_tx, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
goto out_free_rx;
}
/* Request irq for link and timer handling */
- if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, &nv_nic_irq_other, IRQF_SHARED, dev->name, dev) != 0) {
+ sprintf(np->name_other, "%s-other", dev->name);
+ if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector,
+ &nv_nic_irq_other, IRQF_SHARED, np->name_other, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret);
pci_disable_msix(np->pci_dev);
np->msi_flags &= ~NV_MSI_X_ENABLED;
@@ -4046,19 +4093,19 @@ static void nv_do_nic_poll(unsigned long data)
mask |= NVREG_IRQ_OTHER;
}
}
- np->nic_poll_irq = 0;
-
/* disable_irq() contains synchronize_irq, thus no irq handler can run now */
if (np->recover_error) {
np->recover_error = 0;
- printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
+ printk(KERN_INFO "%s: MAC in recoverable error state\n", dev->name);
if (netif_running(dev)) {
netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock(&np->lock);
/* stop engines */
nv_stop_rxtx(dev);
+ if (np->driver_data & DEV_HAS_POWER_CNTRL)
+ nv_mac_reset(dev);
nv_txrx_reset(dev);
/* drain rx queue */
nv_drain_rxtx(dev);
@@ -4076,6 +4123,11 @@ static void nv_do_nic_poll(unsigned long data)
pci_push(base);
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
pci_push(base);
+ /* clear interrupts */
+ if (!(np->msi_flags & NV_MSI_X_ENABLED))
+ writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
+ else
+ writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
/* restart rx engine */
nv_start_rxtx(dev);
@@ -4085,11 +4137,11 @@ static void nv_do_nic_poll(unsigned long data)
}
}
-
writel(mask, base + NvRegIrqMask);
pci_push(base);
if (!using_multi_irqs(dev)) {
+ np->nic_poll_irq = 0;
if (nv_optimized(np))
nv_nic_irq_optimized(0, dev);
else
@@ -4100,18 +4152,22 @@ static void nv_do_nic_poll(unsigned long data)
enable_irq_lockdep(np->pci_dev->irq);
} else {
if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
+ np->nic_poll_irq &= ~NVREG_IRQ_RX_ALL;
nv_nic_irq_rx(0, dev);
enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
}
if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) {
+ np->nic_poll_irq &= ~NVREG_IRQ_TX_ALL;
nv_nic_irq_tx(0, dev);
enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
}
if (np->nic_poll_irq & NVREG_IRQ_OTHER) {
+ np->nic_poll_irq &= ~NVREG_IRQ_OTHER;
nv_nic_irq_other(0, dev);
enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector);
}
}
+
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -4560,6 +4616,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
if (netif_running(dev)) {
nv_disable_irq(dev);
+ nv_napi_disable(dev);
netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock(&np->lock);
@@ -4612,6 +4669,7 @@ static int nv_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ri
spin_unlock(&np->lock);
netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
+ nv_napi_enable(dev);
nv_enable_irq(dev);
}
return 0;
@@ -4738,7 +4796,7 @@ static int nv_set_tx_csum(struct net_device *dev, u32 data)
struct fe_priv *np = netdev_priv(dev);
if (np->driver_data & DEV_HAS_CHECKSUM)
- return ethtool_op_set_tx_hw_csum(dev, data);
+ return ethtool_op_set_tx_csum(dev, data);
else
return -EOPNOTSUPP;
}
@@ -4764,12 +4822,12 @@ static int nv_get_sset_count(struct net_device *dev, int sset)
else
return NV_TEST_COUNT_BASE;
case ETH_SS_STATS:
- if (np->driver_data & DEV_HAS_STATISTICS_V1)
- return NV_DEV_STATISTICS_V1_COUNT;
+ if (np->driver_data & DEV_HAS_STATISTICS_V3)
+ return NV_DEV_STATISTICS_V3_COUNT;
else if (np->driver_data & DEV_HAS_STATISTICS_V2)
return NV_DEV_STATISTICS_V2_COUNT;
- else if (np->driver_data & DEV_HAS_STATISTICS_V3)
- return NV_DEV_STATISTICS_V3_COUNT;
+ else if (np->driver_data & DEV_HAS_STATISTICS_V1)
+ return NV_DEV_STATISTICS_V1_COUNT;
else
return 0;
default:
@@ -5038,9 +5096,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
if (test->flags & ETH_TEST_FL_OFFLINE) {
if (netif_running(dev)) {
netif_stop_queue(dev);
-#ifdef CONFIG_FORCEDETH_NAPI
- napi_disable(&np->napi);
-#endif
+ nv_napi_disable(dev);
netif_tx_lock_bh(dev);
netif_addr_lock(dev);
spin_lock_irq(&np->lock);
@@ -5098,9 +5154,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
/* restart rx engine */
nv_start_rxtx(dev);
netif_start_queue(dev);
-#ifdef CONFIG_FORCEDETH_NAPI
- napi_enable(&np->napi);
-#endif
+ nv_napi_enable(dev);
nv_enable_hw_interrupts(dev, np->irqmask);
}
}
@@ -5169,6 +5223,7 @@ static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
/* The mgmt unit and driver use a semaphore to access the phy during init */
static int nv_mgmt_acquire_sema(struct net_device *dev)
{
+ struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
int i;
u32 tx_ctrl, mgmt_sema;
@@ -5191,8 +5246,10 @@ static int nv_mgmt_acquire_sema(struct net_device *dev)
/* verify that semaphore was acquired */
tx_ctrl = readl(base + NvRegTransmitterControl);
if (((tx_ctrl & NVREG_XMITCTL_HOST_SEMA_MASK) == NVREG_XMITCTL_HOST_SEMA_ACQ) &&
- ((tx_ctrl & NVREG_XMITCTL_MGMT_SEMA_MASK) == NVREG_XMITCTL_MGMT_SEMA_FREE))
+ ((tx_ctrl & NVREG_XMITCTL_MGMT_SEMA_MASK) == NVREG_XMITCTL_MGMT_SEMA_FREE)) {
+ np->mgmt_sema = 1;
return 1;
+ }
else
udelay(50);
}
@@ -5200,6 +5257,51 @@ static int nv_mgmt_acquire_sema(struct net_device *dev)
return 0;
}
+static void nv_mgmt_release_sema(struct net_device *dev)
+{
+ struct fe_priv *np = netdev_priv(dev);
+ u8 __iomem *base = get_hwbase(dev);
+ u32 tx_ctrl;
+
+ if (np->driver_data & DEV_HAS_MGMT_UNIT) {
+ if (np->mgmt_sema) {
+ tx_ctrl = readl(base + NvRegTransmitterControl);
+ tx_ctrl &= ~NVREG_XMITCTL_HOST_SEMA_ACQ;
+ writel(tx_ctrl, base + NvRegTransmitterControl);
+ }
+ }
+}
+
+
+static int nv_mgmt_get_version(struct net_device *dev)
+{
+ struct fe_priv *np = netdev_priv(dev);
+ u8 __iomem *base = get_hwbase(dev);
+ u32 data_ready = readl(base + NvRegTransmitterControl);
+ u32 data_ready2 = 0;
+ unsigned long start;
+ int ready = 0;
+
+ writel(NVREG_MGMTUNITGETVERSION, base + NvRegMgmtUnitGetVersion);
+ writel(data_ready ^ NVREG_XMITCTL_DATA_START, base + NvRegTransmitterControl);
+ start = jiffies;
+ while (time_before(jiffies, start + 5*HZ)) {
+ data_ready2 = readl(base + NvRegTransmitterControl);
+ if ((data_ready & NVREG_XMITCTL_DATA_READY) != (data_ready2 & NVREG_XMITCTL_DATA_READY)) {
+ ready = 1;
+ break;
+ }
+ schedule_timeout_uninterruptible(1);
+ }
+
+ if (!ready || (data_ready2 & NVREG_XMITCTL_DATA_ERROR))
+ return 0;
+
+ np->mgmt_version = readl(base + NvRegMgmtUnitVersion) & NVREG_MGMTUNITVERSION;
+
+ return 1;
+}
+
static int nv_open(struct net_device *dev)
{
struct fe_priv *np = netdev_priv(dev);
@@ -5344,9 +5446,7 @@ static int nv_open(struct net_device *dev)
ret = nv_update_linkspeed(dev);
nv_start_rxtx(dev);
netif_start_queue(dev);
-#ifdef CONFIG_FORCEDETH_NAPI
- napi_enable(&np->napi);
-#endif
+ nv_napi_enable(dev);
if (ret) {
netif_carrier_on(dev);
@@ -5378,9 +5478,7 @@ static int nv_close(struct net_device *dev)
spin_lock_irq(&np->lock);
np->in_shutdown = 1;
spin_unlock_irq(&np->lock);
-#ifdef CONFIG_FORCEDETH_NAPI
- napi_disable(&np->napi);
-#endif
+ nv_napi_disable(dev);
synchronize_irq(np->pci_dev->irq);
del_timer_sync(&np->oom_kick);
@@ -5571,14 +5669,6 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX;
}
- np->msi_flags = 0;
- if ((id->driver_data & DEV_HAS_MSI) && msi) {
- np->msi_flags |= NV_MSI_CAPABLE;
- }
- if ((id->driver_data & DEV_HAS_MSI_X) && msix) {
- np->msi_flags |= NV_MSI_X_CAPABLE;
- }
-
np->pause_flags = NV_PAUSEFRAME_RX_CAPABLE | NV_PAUSEFRAME_RX_REQ | NV_PAUSEFRAME_AUTONEG;
if ((id->driver_data & DEV_HAS_PAUSEFRAME_TX_V1) ||
(id->driver_data & DEV_HAS_PAUSEFRAME_TX_V2) ||
@@ -5723,14 +5813,35 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
} else {
np->tx_flags = NV_TX2_VALID;
}
- if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT) {
- np->irqmask = NVREG_IRQMASK_THROUGHPUT;
- if (np->msi_flags & NV_MSI_X_CAPABLE) /* set number of vectors */
- np->msi_flags |= 0x0003;
- } else {
+
+ np->msi_flags = 0;
+ if ((id->driver_data & DEV_HAS_MSI) && msi) {
+ np->msi_flags |= NV_MSI_CAPABLE;
+ }
+ if ((id->driver_data & DEV_HAS_MSI_X) && msix) {
+ /* msix has had reported issues when modifying irqmask
+ as in the case of napi, therefore, disable for now
+ */
+#ifndef CONFIG_FORCEDETH_NAPI
+ np->msi_flags |= NV_MSI_X_CAPABLE;
+#endif
+ }
+
+ if (optimization_mode == NV_OPTIMIZATION_MODE_CPU) {
np->irqmask = NVREG_IRQMASK_CPU;
if (np->msi_flags & NV_MSI_X_CAPABLE) /* set number of vectors */
np->msi_flags |= 0x0001;
+ } else if (optimization_mode == NV_OPTIMIZATION_MODE_DYNAMIC &&
+ !(id->driver_data & DEV_NEED_TIMERIRQ)) {
+ /* start off in throughput mode */
+ np->irqmask = NVREG_IRQMASK_THROUGHPUT;
+ /* remove support for msix mode */
+ np->msi_flags &= ~NV_MSI_X_CAPABLE;
+ } else {
+ optimization_mode = NV_OPTIMIZATION_MODE_THROUGHPUT;
+ np->irqmask = NVREG_IRQMASK_THROUGHPUT;
+ if (np->msi_flags & NV_MSI_X_CAPABLE) /* set number of vectors */
+ np->msi_flags |= 0x0003;
}
if (id->driver_data & DEV_NEED_TIMERIRQ)
@@ -5771,19 +5882,26 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
if (id->driver_data & DEV_HAS_MGMT_UNIT) {
/* management unit running on the mac? */
- if (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_PHY_INIT) {
- np->mac_in_use = readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_MGMT_ST;
- dprintk(KERN_INFO "%s: mgmt unit is running. mac in use %x.\n", pci_name(pci_dev), np->mac_in_use);
- if (nv_mgmt_acquire_sema(dev)) {
- /* management unit setup the phy already? */
- if ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
- NVREG_XMITCTL_SYNC_PHY_INIT) {
- /* phy is inited by mgmt unit */
- phyinitialized = 1;
- dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n", pci_name(pci_dev));
- } else {
- /* we need to init the phy */
- }
+ if ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_MGMT_ST) &&
+ (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_PHY_INIT) &&
+ nv_mgmt_acquire_sema(dev) &&
+ nv_mgmt_get_version(dev)) {
+ np->mac_in_use = 1;
+ if (np->mgmt_version > 0) {
+ np->mac_in_use = readl(base + NvRegMgmtUnitControl) & NVREG_MGMTUNITCONTROL_INUSE;
+ }
+ dprintk(KERN_INFO "%s: mgmt unit is running. mac in use %x.\n",
+ pci_name(pci_dev), np->mac_in_use);
+ /* management unit setup the phy already? */
+ if (np->mac_in_use &&
+ ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
+ NVREG_XMITCTL_SYNC_PHY_INIT)) {
+ /* phy is inited by mgmt unit */
+ phyinitialized = 1;
+ dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n",
+ pci_name(pci_dev));
+ } else {
+ /* we need to init the phy */
}
}
}
@@ -5945,6 +6063,8 @@ static void __devexit nv_remove(struct pci_dev *pci_dev)
/* restore any phy related changes */
nv_restore_phy(dev);
+ nv_mgmt_release_sema(dev);
+
/* free all structures */
free_rings(dev);
iounmap(get_hwbase(dev));
@@ -5995,6 +6115,8 @@ static int nv_resume(struct pci_dev *pdev)
for (i = 0;i <= np->register_size/sizeof(u32); i++)
writel(np->saved_config_space[i], base+i*sizeof(u32));
+ pci_write_config_dword(pdev, NV_MSI_PRIV_OFFSET, NV_MSI_PRIV_VALUE);
+
netif_device_attach(dev);
if (netif_running(dev)) {
rc = nv_open(dev);
@@ -6068,115 +6190,115 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* CK804 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
},
{ /* CK804 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
},
{ /* MCP04 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
},
{ /* MCP04 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
},
{ /* MCP51 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
},
{ /* MCP51 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
},
{ /* MCP55 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{ /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
},
{ /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
},
{ /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{ /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
@@ -6184,15 +6306,15 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{0,},
};
@@ -6220,7 +6342,7 @@ static void __exit exit_nic(void)
module_param(max_interrupt_work, int, 0);
MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt");
module_param(optimization_mode, int, 0);
-MODULE_PARM_DESC(optimization_mode, "In throughput mode (0), every tx & rx packet will generate an interrupt. In CPU mode (1), interrupts are controlled by a timer.");
+MODULE_PARM_DESC(optimization_mode, "In throughput mode (0), every tx & rx packet will generate an interrupt. In CPU mode (1), interrupts are controlled by a timer. In dynamic mode (2), the mode toggles between throughput and CPU mode based on network load.");
module_param(poll_interval, int, 0);
MODULE_PARM_DESC(poll_interval, "Interval determines how frequent timer interrupt is generated by [(time_in_micro_secs * 100) / (2^10)]. Min is 0 and Max is 65535.");
module_param(msi, int, 0);
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index ce900e54d8d1..b037ce9857bf 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -209,7 +209,7 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
if (received < budget) {
/* done */
- netif_rx_complete(napi);
+ napi_complete(napi);
(*fep->ops->napi_enable_rx)(dev);
}
return received;
@@ -478,7 +478,7 @@ fs_enet_interrupt(int irq, void *dev_id)
/* NOTE: it is possible for FCCs in NAPI mode */
/* to submit a spurious interrupt while in poll */
if (napi_ok)
- __netif_rx_schedule(&fep->napi);
+ __napi_schedule(&fep->napi);
}
}
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/fsl_pq_mdio.c
index f49a426ad681..aa1eb88c21fc 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/fsl_pq_mdio.c
@@ -1,13 +1,12 @@
/*
- * drivers/net/gianfar_mii.c
- *
- * Gianfar Ethernet Driver -- MIIM bus implementation
+ * Freescale PowerQUICC Ethernet Driver -- MIIM bus implementation
* Provides Bus interface for MIIM regs
*
- * Author: Andy Fleming
- * Maintainer: Kumar Gala
+ * Author: Andy Fleming <afleming@freescale.com>
+ *
+ * Copyright (c) 2002-2004,2008 Freescale Semiconductor, Inc.
*
- * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
+ * Based on gianfar_mii.c and ucc_geth_mii.c (Li Yang, Kim Phillips)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -40,9 +39,10 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
+#include <asm/ucc.h>
#include "gianfar.h"
-#include "gianfar_mii.h"
+#include "fsl_pq_mdio.h"
/*
* Write value to the PHY at mii_id at register regnum,
@@ -53,17 +53,17 @@
* the local mdio pins, which may not be the same as system mdio bus, used for
* controlling the external PHYs, for example.
*/
-int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
- int regnum, u16 value)
+int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
+ int regnum, u16 value)
{
/* Set the PHY address and the register address we want to write */
- gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
+ out_be32(&regs->miimadd, (mii_id << 8) | regnum);
/* Write out the value we want */
- gfar_write(&regs->miimcon, value);
+ out_be32(&regs->miimcon, value);
/* Wait for the transaction to finish */
- while (gfar_read(&regs->miimind) & MIIMIND_BUSY)
+ while (in_be32(&regs->miimind) & MIIMIND_BUSY)
cpu_relax();
return 0;
@@ -75,75 +75,77 @@ int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
* done on the bus attached to the local interface,
* which may be different from the generic mdio bus
* This is helpful in programming interfaces like
- * the TBI which, inturn, control interfaces like onchip SERDES
+ * the TBI which, in turn, control interfaces like onchip SERDES
* and are always tied to the local mdio pins, which may not be the
* same as system mdio bus, used for controlling the external PHYs, for eg.
*/
-int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum)
+int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs,
+ int mii_id, int regnum)
{
u16 value;
/* Set the PHY address and the register address we want to read */
- gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
+ out_be32(&regs->miimadd, (mii_id << 8) | regnum);
/* Clear miimcom, and then initiate a read */
- gfar_write(&regs->miimcom, 0);
- gfar_write(&regs->miimcom, MII_READ_COMMAND);
+ out_be32(&regs->miimcom, 0);
+ out_be32(&regs->miimcom, MII_READ_COMMAND);
/* Wait for the transaction to finish */
- while (gfar_read(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
+ while (in_be32(&regs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
cpu_relax();
/* Grab the value of the register from miimstat */
- value = gfar_read(&regs->miimstat);
+ value = in_be32(&regs->miimstat);
return value;
}
-/* Write value to the PHY at mii_id at register regnum,
+/*
+ * Write value to the PHY at mii_id at register regnum,
* on the bus, waiting until the write is done before returning.
- * All PHY configuration is done through the TSEC1 MIIM regs */
-int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
+ */
+int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
{
- struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
+ struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv;
/* Write to the local MII regs */
- return(gfar_local_mdio_write(regs, mii_id, regnum, value));
+ return(fsl_pq_local_mdio_write(regs, mii_id, regnum, value));
}
-/* Read the bus for PHY at addr mii_id, register regnum, and
- * return the value. Clears miimcom first. All PHY
- * configuration has to be done through the TSEC1 MIIM regs */
-int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+/*
+ * Read the bus for PHY at addr mii_id, register regnum, and
+ * return the value. Clears miimcom first.
+ */
+int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
{
- struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
+ struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv;
/* Read the local MII regs */
- return(gfar_local_mdio_read(regs, mii_id, regnum));
+ return(fsl_pq_local_mdio_read(regs, mii_id, regnum));
}
/* Reset the MIIM registers, and wait for the bus to free */
-static int gfar_mdio_reset(struct mii_bus *bus)
+static int fsl_pq_mdio_reset(struct mii_bus *bus)
{
- struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
- unsigned int timeout = PHY_INIT_TIMEOUT;
+ struct fsl_pq_mdio __iomem *regs = (void __iomem *)bus->priv;
+ int timeout = PHY_INIT_TIMEOUT;
mutex_lock(&bus->mdio_lock);
/* Reset the management interface */
- gfar_write(&regs->miimcfg, MIIMCFG_RESET);
+ out_be32(&regs->miimcfg, MIIMCFG_RESET);
/* Setup the MII Mgmt clock speed */
- gfar_write(&regs->miimcfg, MIIMCFG_INIT_VALUE);
+ out_be32(&regs->miimcfg, MIIMCFG_INIT_VALUE);
/* Wait until the bus is free */
- while ((gfar_read(&regs->miimind) & MIIMIND_BUSY) &&
- --timeout)
+ while ((in_be32(&regs->miimind) & MIIMIND_BUSY) && timeout--)
cpu_relax();
mutex_unlock(&bus->mdio_lock);
- if(timeout == 0) {
+ if (timeout < 0) {
printk(KERN_ERR "%s: The MII Bus is stuck!\n",
bus->name);
return -EBUSY;
@@ -190,18 +192,22 @@ static int *create_irq_map(struct device_node *np)
return irqs;
}
-
-void gfar_mdio_bus_name(char *name, struct device_node *np)
+void fsl_pq_mdio_bus_name(char *name, struct device_node *np)
{
- const u32 *reg;
+ const u32 *addr;
+ u64 taddr = OF_BAD_ADDR;
- reg = of_get_property(np, "reg", NULL);
+ addr = of_get_address(np, 0, NULL, NULL);
+ if (addr)
+ taddr = of_translate_address(np, addr);
- snprintf(name, MII_BUS_ID_SIZE, "%s@%x", np->name, reg ? *reg : 0);
+ snprintf(name, MII_BUS_ID_SIZE, "%s@%llx", np->name,
+ (unsigned long long)taddr);
}
+EXPORT_SYMBOL_GPL(fsl_pq_mdio_bus_name);
/* Scan the bus in reverse, looking for an empty spot */
-static int gfar_mdio_find_free(struct mii_bus *new_bus)
+static int fsl_pq_mdio_find_free(struct mii_bus *new_bus)
{
int i;
@@ -218,29 +224,85 @@ static int gfar_mdio_find_free(struct mii_bus *new_bus)
return i;
}
-static int gfar_mdio_probe(struct of_device *ofdev,
- const struct of_device_id *match)
+
+#ifdef CONFIG_GIANFAR
+static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs)
{
- struct gfar_mii __iomem *regs;
struct gfar __iomem *enet_regs;
- struct mii_bus *new_bus;
+
+ /*
+ * This is mildly evil, but so is our hardware for doing this.
+ * Also, we have to cast back to struct gfar because of
+ * definition weirdness done in gianfar.h.
+ */
+ enet_regs = (struct gfar __iomem *)
+ ((char __iomem *)regs - offsetof(struct gfar, gfar_mii_regs));
+
+ return &enet_regs->tbipa;
+}
+#endif
+
+
+#ifdef CONFIG_UCC_GETH
+static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id)
+{
+ struct device_node *np = NULL;
int err = 0;
- u64 addr, size;
+
+ for_each_compatible_node(np, NULL, "ucc_geth") {
+ struct resource tempres;
+
+ err = of_address_to_resource(np, 0, &tempres);
+ if (err)
+ continue;
+
+ /* if our mdio regs fall within this UCC regs range */
+ if ((start >= tempres.start) && (end <= tempres.end)) {
+ /* Find the id of the UCC */
+ const u32 *id;
+
+ id = of_get_property(np, "cell-index", NULL);
+ if (!id) {
+ id = of_get_property(np, "device-id", NULL);
+ if (!id)
+ continue;
+ }
+
+ *ucc_id = *id;
+
+ return 0;
+ }
+ }
+
+ if (err)
+ return err;
+ else
+ return -EINVAL;
+}
+#endif
+
+
+static int fsl_pq_mdio_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
struct device_node *np = ofdev->node;
struct device_node *tbi;
+ struct fsl_pq_mdio __iomem *regs;
+ u32 __iomem *tbipa;
+ struct mii_bus *new_bus;
int tbiaddr = -1;
+ u64 addr, size;
+ int err = 0;
new_bus = mdiobus_alloc();
if (NULL == new_bus)
return -ENOMEM;
- device_init_wakeup(&ofdev->dev, 1);
-
- new_bus->name = "Gianfar MII Bus",
- new_bus->read = &gfar_mdio_read,
- new_bus->write = &gfar_mdio_write,
- new_bus->reset = &gfar_mdio_reset,
- gfar_mdio_bus_name(new_bus->id, np);
+ new_bus->name = "Freescale PowerQUICC MII Bus",
+ new_bus->read = &fsl_pq_mdio_read,
+ new_bus->write = &fsl_pq_mdio_write,
+ new_bus->reset = &fsl_pq_mdio_reset,
+ fsl_pq_mdio_bus_name(new_bus->id, np);
/* Set the PHY base address */
addr = of_translate_address(np, of_get_address(np, 0, &size, NULL));
@@ -255,7 +317,7 @@ static int gfar_mdio_probe(struct of_device *ofdev,
new_bus->irq = create_irq_map(np);
- if (new_bus->irq == NULL) {
+ if (NULL == new_bus->irq) {
err = -ENOMEM;
goto err_unmap_regs;
}
@@ -263,13 +325,34 @@ static int gfar_mdio_probe(struct of_device *ofdev,
new_bus->parent = &ofdev->dev;
dev_set_drvdata(&ofdev->dev, new_bus);
- /*
- * This is mildly evil, but so is our hardware for doing this.
- * Also, we have to cast back to struct gfar_mii because of
- * definition weirdness done in gianfar.h.
- */
- enet_regs = (struct gfar __iomem *)
- ((char *)regs - offsetof(struct gfar, gfar_mii_regs));
+ if (of_device_is_compatible(np, "fsl,gianfar-mdio") ||
+ of_device_is_compatible(np, "fsl,gianfar-tbi") ||
+ of_device_is_compatible(np, "gianfar")) {
+#ifdef CONFIG_GIANFAR
+ tbipa = get_gfar_tbipa(regs);
+#else
+ err = -ENODEV;
+ goto err_free_irqs;
+#endif
+ } else if (of_device_is_compatible(np, "fsl,ucc-mdio") ||
+ of_device_is_compatible(np, "ucc_geth_phy")) {
+#ifdef CONFIG_UCC_GETH
+ u32 id;
+
+ tbipa = &regs->utbipar;
+
+ if ((err = get_ucc_id_for_range(addr, addr + size, &id)))
+ goto err_free_irqs;
+
+ ucc_set_qe_mux_mii_mng(id - 1);
+#else
+ err = -ENODEV;
+ goto err_free_irqs;
+#endif
+ } else {
+ err = -ENODEV;
+ goto err_free_irqs;
+ }
for_each_child_of_node(np, tbi) {
if (!strncmp(tbi->type, "tbi-phy", 8))
@@ -284,9 +367,9 @@ static int gfar_mdio_probe(struct of_device *ofdev,
}
if (tbiaddr == -1) {
- gfar_write(&enet_regs->tbipa, 0);
+ out_be32(tbipa, 0);
- tbiaddr = gfar_mdio_find_free(new_bus);
+ tbiaddr = fsl_pq_mdio_find_free(new_bus);
}
/*
@@ -299,18 +382,18 @@ static int gfar_mdio_probe(struct of_device *ofdev,
goto err_free_irqs;
}
- gfar_write(&enet_regs->tbipa, tbiaddr);
+ out_be32(tbipa, tbiaddr);
/*
* The TBIPHY-only buses will find PHYs at every address,
* so we mask them all but the TBI
*/
- if (!of_device_is_compatible(np, "fsl,gianfar-mdio"))
+ if (of_device_is_compatible(np, "fsl,gianfar-tbi"))
new_bus->phy_mask = ~(1 << tbiaddr);
err = mdiobus_register(new_bus);
- if (err != 0) {
+ if (err) {
printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
new_bus->name);
goto err_free_irqs;
@@ -323,57 +406,64 @@ err_free_irqs:
err_unmap_regs:
iounmap(regs);
err_free_bus:
- mdiobus_free(new_bus);
+ kfree(new_bus);
return err;
}
-static int gfar_mdio_remove(struct of_device *ofdev)
+static int fsl_pq_mdio_remove(struct of_device *ofdev)
{
- struct mii_bus *bus = dev_get_drvdata(&ofdev->dev);
+ struct device *device = &ofdev->dev;
+ struct mii_bus *bus = dev_get_drvdata(device);
mdiobus_unregister(bus);
- dev_set_drvdata(&ofdev->dev, NULL);
+ dev_set_drvdata(device, NULL);
iounmap((void __iomem *)bus->priv);
bus->priv = NULL;
- kfree(bus->irq);
mdiobus_free(bus);
return 0;
}
-static struct of_device_id gfar_mdio_match[] =
-{
+static struct of_device_id fsl_pq_mdio_match[] = {
{
- .compatible = "fsl,gianfar-mdio",
+ .type = "mdio",
+ .compatible = "ucc_geth_phy",
+ },
+ {
+ .type = "mdio",
+ .compatible = "gianfar",
+ },
+ {
+ .compatible = "fsl,ucc-mdio",
},
{
.compatible = "fsl,gianfar-tbi",
},
{
- .type = "mdio",
- .compatible = "gianfar",
+ .compatible = "fsl,gianfar-mdio",
},
{},
};
-static struct of_platform_driver gianfar_mdio_driver = {
- .name = "fsl-gianfar_mdio",
- .match_table = gfar_mdio_match,
-
- .probe = gfar_mdio_probe,
- .remove = gfar_mdio_remove,
+static struct of_platform_driver fsl_pq_mdio_driver = {
+ .name = "fsl-pq_mdio",
+ .probe = fsl_pq_mdio_probe,
+ .remove = fsl_pq_mdio_remove,
+ .match_table = fsl_pq_mdio_match,
};
-int __init gfar_mdio_init(void)
+int __init fsl_pq_mdio_init(void)
{
- return of_register_platform_driver(&gianfar_mdio_driver);
+ return of_register_platform_driver(&fsl_pq_mdio_driver);
}
-void gfar_mdio_exit(void)
+void fsl_pq_mdio_exit(void)
{
- of_unregister_platform_driver(&gianfar_mdio_driver);
+ of_unregister_platform_driver(&fsl_pq_mdio_driver);
}
+subsys_initcall_sync(fsl_pq_mdio_init);
+module_exit(fsl_pq_mdio_exit);
diff --git a/drivers/net/fsl_pq_mdio.h b/drivers/net/fsl_pq_mdio.h
new file mode 100644
index 000000000000..36dad527410b
--- /dev/null
+++ b/drivers/net/fsl_pq_mdio.h
@@ -0,0 +1,45 @@
+/*
+ * Freescale PowerQUICC MDIO Driver -- MII Management Bus Implementation
+ * Driver for the MDIO bus controller on Freescale PowerQUICC processors
+ *
+ * Author: Andy Fleming
+ *
+ * Copyright (c) 2002-2004,2008 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+#ifndef __FSL_PQ_MDIO_H
+#define __FSL_PQ_MDIO_H
+
+#define MIIMIND_BUSY 0x00000001
+#define MIIMIND_NOTVALID 0x00000004
+#define MIIMCFG_INIT_VALUE 0x00000007
+#define MIIMCFG_RESET 0x80000000
+
+#define MII_READ_COMMAND 0x00000001
+
+struct fsl_pq_mdio {
+ u32 miimcfg; /* MII management configuration reg */
+ u32 miimcom; /* MII management command reg */
+ u32 miimadd; /* MII management address reg */
+ u32 miimcon; /* MII management control reg */
+ u32 miimstat; /* MII management status reg */
+ u32 miimind; /* MII management indication reg */
+ u8 reserved[28]; /* Space holder */
+ u32 utbipar; /* TBI phy address reg (only on UCC) */
+} __attribute__ ((packed));
+
+
+int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
+int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
+int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
+ int regnum, u16 value);
+int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, int mii_id, int regnum);
+int __init fsl_pq_mdio_init(void);
+void fsl_pq_mdio_exit(void);
+void fsl_pq_mdio_bus_name(char *name, struct device_node *np);
+#endif /* FSL_PQ_MDIO_H */
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 9831b3f408aa..65f55877be95 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -93,7 +93,7 @@
#include <linux/of.h>
#include "gianfar.h"
-#include "gianfar_mii.h"
+#include "fsl_pq_mdio.h"
#define TX_TIMEOUT (1*HZ)
#undef BRIEF_GFAR_ERRORS
@@ -140,13 +140,26 @@ static void gfar_halt_nodisable(struct net_device *dev);
void gfar_start(struct net_device *dev);
static void gfar_clear_exact_match(struct net_device *dev);
static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
-
-extern const struct ethtool_ops gfar_ethtool_ops;
+static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
MODULE_AUTHOR("Freescale Semiconductor, Inc");
MODULE_DESCRIPTION("Gianfar Ethernet Driver");
MODULE_LICENSE("GPL");
+static const struct net_device_ops gfar_netdev_ops = {
+ .ndo_open = gfar_enet_open,
+ .ndo_start_xmit = gfar_start_xmit,
+ .ndo_stop = gfar_close,
+ .ndo_change_mtu = gfar_change_mtu,
+ .ndo_set_multicast_list = gfar_set_multi,
+ .ndo_tx_timeout = gfar_timeout,
+ .ndo_do_ioctl = gfar_ioctl,
+ .ndo_vlan_rx_register = gfar_vlan_rx_register,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = gfar_netpoll,
+#endif
+};
+
/* Returns 1 if incoming frames use an FCB */
static inline int gfar_uses_fcb(struct gfar_private *priv)
{
@@ -166,6 +179,9 @@ static int gfar_of_init(struct net_device *dev)
struct gfar_private *priv = netdev_priv(dev);
struct device_node *np = priv->node;
char bus_name[MII_BUS_ID_SIZE];
+ const u32 *stash;
+ const u32 *stash_len;
+ const u32 *stash_idx;
if (!np || !of_device_is_available(np))
return -ENODEV;
@@ -195,6 +211,26 @@ static int gfar_of_init(struct net_device *dev)
}
}
+ stash = of_get_property(np, "bd-stash", NULL);
+
+ if(stash) {
+ priv->device_flags |= FSL_GIANFAR_DEV_HAS_BD_STASHING;
+ priv->bd_stash_en = 1;
+ }
+
+ stash_len = of_get_property(np, "rx-stash-len", NULL);
+
+ if (stash_len)
+ priv->rx_stash_size = *stash_len;
+
+ stash_idx = of_get_property(np, "rx-stash-idx", NULL);
+
+ if (stash_idx)
+ priv->rx_stash_index = *stash_idx;
+
+ if (stash_len || stash_idx)
+ priv->device_flags |= FSL_GIANFAR_DEV_HAS_BUF_STASHING;
+
mac_addr = of_get_mac_address(np);
if (mac_addr)
memcpy(dev->dev_addr, mac_addr, MAC_ADDR_LEN);
@@ -253,9 +289,9 @@ static int gfar_of_init(struct net_device *dev)
id = of_get_property(phy, "reg", NULL);
of_node_put(phy);
- of_node_put(mdio);
- gfar_mdio_bus_name(bus_name, mdio);
+ fsl_pq_mdio_bus_name(bus_name, mdio);
+ of_node_put(mdio);
snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x",
bus_name, *id);
}
@@ -329,8 +365,10 @@ static int gfar_probe(struct of_device *ofdev,
return -ENOMEM;
priv = netdev_priv(dev);
- priv->dev = dev;
+ priv->ndev = dev;
+ priv->ofdev = ofdev;
priv->node = ofdev->node;
+ SET_NETDEV_DEV(dev, &ofdev->dev);
err = gfar_of_init(dev);
@@ -369,21 +407,12 @@ static int gfar_probe(struct of_device *ofdev,
SET_NETDEV_DEV(dev, &ofdev->dev);
/* Fill in the dev structure */
- dev->open = gfar_enet_open;
- dev->hard_start_xmit = gfar_start_xmit;
- dev->tx_timeout = gfar_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
netif_napi_add(dev, &priv->napi, gfar_poll, GFAR_DEV_WEIGHT);
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = gfar_netpoll;
-#endif
- dev->stop = gfar_close;
- dev->change_mtu = gfar_change_mtu;
dev->mtu = 1500;
- dev->set_multicast_list = gfar_set_multi;
+ dev->netdev_ops = &gfar_netdev_ops;
dev->ethtool_ops = &gfar_ethtool_ops;
- dev->do_ioctl = gfar_ioctl;
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
priv->rx_csum_enable = 1;
@@ -393,11 +422,8 @@ static int gfar_probe(struct of_device *ofdev,
priv->vlgrp = NULL;
- if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
- dev->vlan_rx_register = gfar_vlan_rx_register;
-
+ if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN)
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
- }
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) {
priv->extended_hash = 1;
@@ -425,7 +451,7 @@ static int gfar_probe(struct of_device *ofdev,
priv->hash_width = 8;
priv->hash_regs[0] = &priv->regs->gaddr0;
- priv->hash_regs[1] = &priv->regs->gaddr1;
+ priv->hash_regs[1] = &priv->regs->gaddr1;
priv->hash_regs[2] = &priv->regs->gaddr2;
priv->hash_regs[3] = &priv->regs->gaddr3;
priv->hash_regs[4] = &priv->regs->gaddr4;
@@ -466,6 +492,9 @@ static int gfar_probe(struct of_device *ofdev,
goto register_fail;
}
+ device_init_wakeup(&dev->dev,
+ priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+
/* fill out IRQ number and name fields */
len_devname = strlen(dev->name);
strncpy(&priv->int_name_tx[0], dev->name, len_devname);
@@ -511,7 +540,7 @@ static int gfar_remove(struct of_device *ofdev)
dev_set_drvdata(&ofdev->dev, NULL);
iounmap(priv->regs);
- free_netdev(priv->dev);
+ free_netdev(priv->ndev);
return 0;
}
@@ -520,7 +549,7 @@ static int gfar_remove(struct of_device *ofdev)
static int gfar_suspend(struct of_device *ofdev, pm_message_t state)
{
struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
- struct net_device *dev = priv->dev;
+ struct net_device *dev = priv->ndev;
unsigned long flags;
u32 tempval;
@@ -569,7 +598,7 @@ static int gfar_suspend(struct of_device *ofdev, pm_message_t state)
static int gfar_resume(struct of_device *ofdev)
{
struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
- struct net_device *dev = priv->dev;
+ struct net_device *dev = priv->ndev;
unsigned long flags;
u32 tempval;
int magic_packet = priv->wol_en &&
@@ -838,12 +867,12 @@ void stop_gfar(struct net_device *dev)
free_irq(priv->interruptTransmit, dev);
free_irq(priv->interruptReceive, dev);
} else {
- free_irq(priv->interruptTransmit, dev);
+ free_irq(priv->interruptTransmit, dev);
}
free_skb_resources(priv);
- dma_free_coherent(&dev->dev,
+ dma_free_coherent(&priv->ofdev->dev,
sizeof(struct txbd8)*priv->tx_ring_size
+ sizeof(struct rxbd8)*priv->rx_ring_size,
priv->tx_bd_base,
@@ -865,12 +894,12 @@ static void free_skb_resources(struct gfar_private *priv)
if (!priv->tx_skbuff[i])
continue;
- dma_unmap_single(&priv->dev->dev, txbdp->bufPtr,
+ dma_unmap_single(&priv->ofdev->dev, txbdp->bufPtr,
txbdp->length, DMA_TO_DEVICE);
txbdp->lstatus = 0;
for (j = 0; j < skb_shinfo(priv->tx_skbuff[i])->nr_frags; j++) {
txbdp++;
- dma_unmap_page(&priv->dev->dev, txbdp->bufPtr,
+ dma_unmap_page(&priv->ofdev->dev, txbdp->bufPtr,
txbdp->length, DMA_TO_DEVICE);
}
txbdp++;
@@ -887,7 +916,7 @@ static void free_skb_resources(struct gfar_private *priv)
if(priv->rx_skbuff != NULL) {
for (i = 0; i < priv->rx_ring_size; i++) {
if (priv->rx_skbuff[i]) {
- dma_unmap_single(&priv->dev->dev, rxbdp->bufPtr,
+ dma_unmap_single(&priv->ofdev->dev, rxbdp->bufPtr,
priv->rx_buffer_size,
DMA_FROM_DEVICE);
@@ -953,7 +982,7 @@ int startup_gfar(struct net_device *dev)
gfar_write(&regs->imask, IMASK_INIT_CLEAR);
/* Allocate memory for the buffer descriptors */
- vaddr = (unsigned long) dma_alloc_coherent(&dev->dev,
+ vaddr = (unsigned long) dma_alloc_coherent(&priv->ofdev->dev,
sizeof (struct txbd8) * priv->tx_ring_size +
sizeof (struct rxbd8) * priv->rx_ring_size,
&addr, GFP_KERNEL);
@@ -1165,7 +1194,7 @@ err_rxalloc_fail:
rx_skb_fail:
free_skb_resources(priv);
tx_skb_fail:
- dma_free_coherent(&dev->dev,
+ dma_free_coherent(&priv->ofdev->dev,
sizeof(struct txbd8)*priv->tx_ring_size
+ sizeof(struct rxbd8)*priv->rx_ring_size,
priv->tx_bd_base,
@@ -1183,6 +1212,8 @@ static int gfar_enet_open(struct net_device *dev)
napi_enable(&priv->napi);
+ skb_queue_head_init(&priv->rx_recycle);
+
/* Initialize a bunch of registers */
init_registers(dev);
@@ -1203,13 +1234,14 @@ static int gfar_enet_open(struct net_device *dev)
netif_start_queue(dev);
+ device_set_wakeup_enable(&dev->dev, priv->wol_en);
+
return err;
}
static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb)
{
- struct txfcb *fcb = (struct txfcb *)skb_push (skb, GMAC_FCB_LEN);
-
+ struct txfcb *fcb = (struct txfcb *)skb_push(skb, GMAC_FCB_LEN);
cacheable_memzero(fcb, GMAC_FCB_LEN);
return fcb;
@@ -1278,6 +1310,22 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
base = priv->tx_bd_base;
+ /* make space for additional header when fcb is needed */
+ if (((skb->ip_summed == CHECKSUM_PARTIAL) ||
+ (priv->vlgrp && vlan_tx_tag_present(skb))) &&
+ (skb_headroom(skb) < GMAC_FCB_LEN)) {
+ struct sk_buff *skb_new;
+
+ skb_new = skb_realloc_headroom(skb, GMAC_FCB_LEN);
+ if (!skb_new) {
+ dev->stats.tx_errors++;
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+ kfree_skb(skb);
+ skb = skb_new;
+ }
+
/* total number of fragments in the SKB */
nr_frags = skb_shinfo(skb)->nr_frags;
@@ -1314,7 +1362,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (i == nr_frags - 1)
lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
- bufaddr = dma_map_page(&dev->dev,
+ bufaddr = dma_map_page(&priv->ofdev->dev,
skb_shinfo(skb)->frags[i].page,
skb_shinfo(skb)->frags[i].page_offset,
length,
@@ -1346,7 +1394,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* setup the TxBD length and buffer pointer for the first BD */
priv->tx_skbuff[priv->skb_curtx] = skb;
- txbdp_start->bufPtr = dma_map_single(&dev->dev, skb->data,
+ txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
skb_headlen(skb), DMA_TO_DEVICE);
lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);
@@ -1389,7 +1437,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Unlock priv */
spin_unlock_irqrestore(&priv->txlock, flags);
- return 0;
+ return NETDEV_TX_OK;
}
/* Stops the kernel queue, and halts the controller */
@@ -1399,6 +1447,7 @@ static int gfar_close(struct net_device *dev)
napi_disable(&priv->napi);
+ skb_queue_purge(&priv->rx_recycle);
cancel_work_sync(&priv->reset_task);
stop_gfar(dev);
@@ -1531,7 +1580,7 @@ static void gfar_reset_task(struct work_struct *work)
{
struct gfar_private *priv = container_of(work, struct gfar_private,
reset_task);
- struct net_device *dev = priv->dev;
+ struct net_device *dev = priv->ndev;
if (dev->flags & IFF_UP) {
stop_gfar(dev);
@@ -1578,7 +1627,7 @@ static int gfar_clean_tx_ring(struct net_device *dev)
(lstatus & BD_LENGTH_MASK))
break;
- dma_unmap_single(&dev->dev,
+ dma_unmap_single(&priv->ofdev->dev,
bdp->bufPtr,
bdp->length,
DMA_TO_DEVICE);
@@ -1587,7 +1636,7 @@ static int gfar_clean_tx_ring(struct net_device *dev)
bdp = next_txbd(bdp, base, tx_ring_size);
for (i = 0; i < frags; i++) {
- dma_unmap_page(&dev->dev,
+ dma_unmap_page(&priv->ofdev->dev,
bdp->bufPtr,
bdp->length,
DMA_TO_DEVICE);
@@ -1595,7 +1644,17 @@ static int gfar_clean_tx_ring(struct net_device *dev)
bdp = next_txbd(bdp, base, tx_ring_size);
}
- dev_kfree_skb_any(skb);
+ /*
+ * If there's room in the queue (limit it to rx_buffer_size)
+ * we add this skb back into the pool, if it's the right size
+ */
+ if (skb_queue_len(&priv->rx_recycle) < priv->rx_ring_size &&
+ skb_recycle_check(skb, priv->rx_buffer_size +
+ RXBUF_ALIGNMENT))
+ __skb_queue_head(&priv->rx_recycle, skb);
+ else
+ dev_kfree_skb_any(skb);
+
priv->tx_skbuff[skb_dirtytx] = NULL;
skb_dirtytx = (skb_dirtytx + 1) &
@@ -1626,9 +1685,9 @@ static void gfar_schedule_cleanup(struct net_device *dev)
spin_lock_irqsave(&priv->txlock, flags);
spin_lock(&priv->rxlock);
- if (netif_rx_schedule_prep(&priv->napi)) {
+ if (napi_schedule_prep(&priv->napi)) {
gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED);
- __netif_rx_schedule(&priv->napi);
+ __napi_schedule(&priv->napi);
} else {
/*
* Clear IEVENT, so interrupts aren't called again
@@ -1654,7 +1713,7 @@ static void gfar_new_rxbdp(struct net_device *dev, struct rxbd8 *bdp,
struct gfar_private *priv = netdev_priv(dev);
u32 lstatus;
- bdp->bufPtr = dma_map_single(&dev->dev, skb->data,
+ bdp->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
priv->rx_buffer_size, DMA_FROM_DEVICE);
lstatus = BD_LFLAG(RXBD_EMPTY | RXBD_INTERRUPT);
@@ -1674,8 +1733,10 @@ struct sk_buff * gfar_new_skb(struct net_device *dev)
struct gfar_private *priv = netdev_priv(dev);
struct sk_buff *skb = NULL;
- /* We have to allocate the skb, so keep trying till we succeed */
- skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT);
+ skb = __skb_dequeue(&priv->rx_recycle);
+ if (!skb)
+ skb = netdev_alloc_skb(dev,
+ priv->rx_buffer_size + RXBUF_ALIGNMENT);
if (!skb)
return NULL;
@@ -1812,7 +1873,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
skb = priv->rx_skbuff[priv->skb_currx];
- dma_unmap_single(&priv->dev->dev, bdp->bufPtr,
+ dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr,
priv->rx_buffer_size, DMA_FROM_DEVICE);
/* We drop the frame if we failed to allocate a new buffer */
@@ -1823,7 +1884,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
if (unlikely(!newskb))
newskb = skb;
else if (skb)
- dev_kfree_skb_any(skb);
+ __skb_queue_head(&priv->rx_recycle, skb);
} else {
/* Increment the number of packets */
dev->stats.rx_packets++;
@@ -1835,6 +1896,8 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
skb_put(skb, pkt_len);
dev->stats.rx_bytes += pkt_len;
+ if (in_irq() || irqs_disabled())
+ printk("Interrupt problem!\n");
gfar_process_frame(dev, skb, amount_pull);
} else {
@@ -1870,7 +1933,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
static int gfar_poll(struct napi_struct *napi, int budget)
{
struct gfar_private *priv = container_of(napi, struct gfar_private, napi);
- struct net_device *dev = priv->dev;
+ struct net_device *dev = priv->ndev;
int tx_cleaned = 0;
int rx_cleaned = 0;
unsigned long flags;
@@ -1891,7 +1954,7 @@ static int gfar_poll(struct napi_struct *napi, int budget)
return budget;
if (rx_cleaned < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
/* Clear the halt bit in RSTAT */
gfar_write(&priv->regs->rstat, RSTAT_CLEAR_RHALT);
@@ -2308,23 +2371,12 @@ static struct of_platform_driver gfar_driver = {
static int __init gfar_init(void)
{
- int err = gfar_mdio_init();
-
- if (err)
- return err;
-
- err = of_register_platform_driver(&gfar_driver);
-
- if (err)
- gfar_mdio_exit();
-
- return err;
+ return of_register_platform_driver(&gfar_driver);
}
static void __exit gfar_exit(void)
{
of_unregister_platform_driver(&gfar_driver);
- gfar_mdio_exit();
}
module_init(gfar_init);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index eaa86897f5c3..0642d52aef5c 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -45,8 +45,6 @@
#include <linux/crc32.h>
#include <linux/workqueue.h>
#include <linux/ethtool.h>
-#include <linux/fsl_devices.h>
-#include "gianfar_mii.h"
/* The maximum number of packets to be handled in one call of gfar_poll */
#define GFAR_DEV_WEIGHT 64
@@ -126,9 +124,12 @@ extern const char gfar_driver_version[];
#define DEFAULT_RX_COALESCE 0
#define DEFAULT_RXCOUNT 0
-#define MIIMCFG_INIT_VALUE 0x00000007
-#define MIIMCFG_RESET 0x80000000
-#define MIIMIND_BUSY 0x00000001
+#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
+ | SUPPORTED_10baseT_Full \
+ | SUPPORTED_100baseT_Half \
+ | SUPPORTED_100baseT_Full \
+ | SUPPORTED_Autoneg \
+ | SUPPORTED_MII)
/* TBI register addresses */
#define MII_TBICON 0x11
@@ -736,7 +737,8 @@ struct gfar_private {
spinlock_t rxlock;
struct device_node *node;
- struct net_device *dev;
+ struct net_device *ndev;
+ struct of_device *ofdev;
struct napi_struct napi;
/* skb array and index */
@@ -756,6 +758,8 @@ struct gfar_private {
unsigned int rx_stash_size;
unsigned int rx_stash_index;
+ struct sk_buff_head rx_recycle;
+
struct vlan_group *vlgrp;
/* Unprotected fields */
@@ -826,8 +830,7 @@ extern void gfar_halt(struct net_device *dev);
extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
int enable, u32 regnum, u32 read);
void gfar_init_sysfs(struct net_device *dev);
-int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
- int regnum, u16 value);
-int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
+
+extern const struct ethtool_ops gfar_ethtool_ops;
#endif /* __GIANFAR_H */
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 59b3b5d98efe..dbf06e9313cc 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -600,6 +600,7 @@ static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
spin_lock_irqsave(&priv->bflock, flags);
priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0;
+ device_set_wakeup_enable(&dev->dev, priv->wol_en);
spin_unlock_irqrestore(&priv->bflock, flags);
return 0;
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h
deleted file mode 100644
index 65c242cd468a..000000000000
--- a/drivers/net/gianfar_mii.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * drivers/net/gianfar_mii.h
- *
- * Gianfar Ethernet Driver -- MII Management Bus Implementation
- * Driver for the MDIO bus controller in the Gianfar register space
- *
- * Author: Andy Fleming
- * Maintainer: Kumar Gala
- *
- * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-#ifndef __GIANFAR_MII_H
-#define __GIANFAR_MII_H
-
-struct gfar_private; /* forward ref */
-
-#define MIIMIND_BUSY 0x00000001
-#define MIIMIND_NOTVALID 0x00000004
-
-#define MII_READ_COMMAND 0x00000001
-
-#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
- | SUPPORTED_10baseT_Full \
- | SUPPORTED_100baseT_Half \
- | SUPPORTED_100baseT_Full \
- | SUPPORTED_Autoneg \
- | SUPPORTED_MII)
-
-struct gfar_mii {
- u32 miimcfg; /* 0x.520 - MII Management Config Register */
- u32 miimcom; /* 0x.524 - MII Management Command Register */
- u32 miimadd; /* 0x.528 - MII Management Address Register */
- u32 miimcon; /* 0x.52c - MII Management Control Register */
- u32 miimstat; /* 0x.530 - MII Management Status Register */
- u32 miimind; /* 0x.534 - MII Management Indicator Register */
-};
-
-int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
-int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
-int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
- int regnum, u16 value);
-int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
-struct mii_bus *gfar_get_miibus(const struct gfar_private *priv);
-int __init gfar_mdio_init(void);
-void gfar_mdio_exit(void);
-
-void gfar_mdio_bus_name(char *name, struct device_node *np);
-#endif /* GIANFAR_PHY_H */
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
index 782c20170082..dd26da74f27a 100644
--- a/drivers/net/gianfar_sysfs.c
+++ b/drivers/net/gianfar_sysfs.c
@@ -53,6 +53,9 @@ static ssize_t gfar_set_bd_stash(struct device *dev,
u32 temp;
unsigned long flags;
+ if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BD_STASHING))
+ return count;
+
/* Find out the new setting */
if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
new_setting = 1;
@@ -81,7 +84,7 @@ static ssize_t gfar_set_bd_stash(struct device *dev,
return count;
}
-DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash);
+static DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash);
static ssize_t gfar_show_rx_stash_size(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -100,6 +103,9 @@ static ssize_t gfar_set_rx_stash_size(struct device *dev,
u32 temp;
unsigned long flags;
+ if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
+ return count;
+
spin_lock_irqsave(&priv->rxlock, flags);
if (length > priv->rx_buffer_size)
goto out;
@@ -130,8 +136,8 @@ out:
return count;
}
-DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size,
- gfar_set_rx_stash_size);
+static DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size,
+ gfar_set_rx_stash_size);
/* Stashing will only be enabled when rx_stash_size != 0 */
static ssize_t gfar_show_rx_stash_index(struct device *dev,
@@ -152,6 +158,9 @@ static ssize_t gfar_set_rx_stash_index(struct device *dev,
u32 temp;
unsigned long flags;
+ if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING))
+ return count;
+
spin_lock_irqsave(&priv->rxlock, flags);
if (index > priv->rx_stash_size)
goto out;
@@ -172,8 +181,8 @@ out:
return count;
}
-DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index,
- gfar_set_rx_stash_index);
+static DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index,
+ gfar_set_rx_stash_index);
static ssize_t gfar_show_fifo_threshold(struct device *dev,
struct device_attribute *attr,
@@ -210,8 +219,8 @@ static ssize_t gfar_set_fifo_threshold(struct device *dev,
return count;
}
-DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold,
- gfar_set_fifo_threshold);
+static DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold,
+ gfar_set_fifo_threshold);
static ssize_t gfar_show_fifo_starve(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -247,7 +256,8 @@ static ssize_t gfar_set_fifo_starve(struct device *dev,
return count;
}
-DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve, gfar_set_fifo_starve);
+static DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve,
+ gfar_set_fifo_starve);
static ssize_t gfar_show_fifo_starve_off(struct device *dev,
struct device_attribute *attr,
@@ -284,8 +294,8 @@ static ssize_t gfar_set_fifo_starve_off(struct device *dev,
return count;
}
-DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off,
- gfar_set_fifo_starve_off);
+static DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off,
+ gfar_set_fifo_starve_off);
void gfar_init_sysfs(struct net_device *dev)
{
@@ -293,12 +303,9 @@ void gfar_init_sysfs(struct net_device *dev)
int rc;
/* Initialize the default values */
- priv->rx_stash_size = DEFAULT_STASH_LENGTH;
- priv->rx_stash_index = DEFAULT_STASH_INDEX;
priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
- priv->bd_stash_en = DEFAULT_BD_STASH;
/* Create our sysfs files */
rc = device_create_file(&dev->dev, &dev_attr_bd_stash);
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 7e8b3c59a7d6..310ee035067c 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -171,7 +171,7 @@ static int tx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
#include <asm/unaligned.h>
#include <asm/cache.h>
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n"
KERN_INFO " Some modifications by Eric kasten <kasten@nscl.msu.edu>\n"
KERN_INFO " Further modifications by Keith Underwood <keithu@parl.clemson.edu>\n";
@@ -1244,7 +1244,7 @@ do { \
csum_add(sum, (ih)->saddr & 0xffff); \
csum_add(sum, (ih)->daddr >> 16); \
csum_add(sum, (ih)->daddr & 0xffff); \
- csum_add(sum, __constant_htons(IPPROTO_UDP)); \
+ csum_add(sum, cpu_to_be16(IPPROTO_UDP)); \
csum_add(sum, (uh)->len); \
} while (0)
@@ -1255,7 +1255,7 @@ do { \
csum_add(sum, (ih)->saddr & 0xffff); \
csum_add(sum, (ih)->daddr >> 16); \
csum_add(sum, (ih)->daddr & 0xffff); \
- csum_add(sum, __constant_htons(IPPROTO_TCP)); \
+ csum_add(sum, cpu_to_be16(IPPROTO_TCP)); \
csum_add(sum, htons(len)); \
} while (0)
#endif
@@ -1296,7 +1296,7 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* tack on checksum tag */
u32 tagval = 0;
struct ethhdr *eh = (struct ethhdr *)skb->data;
- if (eh->h_proto == __constant_htons(ETH_P_IP)) {
+ if (eh->h_proto == cpu_to_be16(ETH_P_IP)) {
struct iphdr *ih = (struct iphdr *)((char *)eh + ETH_HLEN);
if (ih->protocol == IPPROTO_UDP) {
struct udphdr *uh
@@ -1605,7 +1605,7 @@ static int hamachi_rx(struct net_device *dev)
*/
if (ntohs(ih->tot_len) >= 46){
/* don't worry about frags */
- if (!(ih->frag_off & __constant_htons(IP_MF|IP_OFFSET))) {
+ if (!(ih->frag_off & cpu_to_be16(IP_MF|IP_OFFSET))) {
u32 inv = *(u32 *) &buf_addr[data_size - 16];
u32 *p = (u32 *) &buf_addr[data_size - 20];
register u32 crc, p_r, p_r1;
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 2d4089894ec7..155160052c8b 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -322,23 +322,25 @@ static const struct header_ops sp_header_ops = {
.rebuild = sp_rebuild_header,
};
+static const struct net_device_ops sp_netdev_ops = {
+ .ndo_open = sp_open_dev,
+ .ndo_stop = sp_close,
+ .ndo_start_xmit = sp_xmit,
+ .ndo_set_mac_address = sp_set_mac_address,
+};
+
static void sp_setup(struct net_device *dev)
{
/* Finish setting up the DEVICE info. */
- dev->mtu = SIXP_MTU;
- dev->hard_start_xmit = sp_xmit;
- dev->open = sp_open_dev;
+ dev->netdev_ops = &sp_netdev_ops;
dev->destructor = free_netdev;
- dev->stop = sp_close;
-
- dev->set_mac_address = sp_set_mac_address;
+ dev->mtu = SIXP_MTU;
dev->hard_header_len = AX25_MAX_HEADER_LEN;
dev->header_ops = &sp_header_ops;
dev->addr_len = AX25_ADDR_LEN;
dev->type = ARPHRD_AX25;
dev->tx_queue_len = 10;
- dev->tx_timeout = NULL;
/* Only activated in AX.25 mode */
memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
@@ -788,9 +790,9 @@ static struct tty_ldisc_ops sp_ldisc = {
/* Initialize 6pack control device -- register 6pack line discipline */
-static char msg_banner[] __initdata = KERN_INFO \
+static const char msg_banner[] __initdata = KERN_INFO \
"AX.25: 6pack driver, " SIXPACK_VERSION "\n";
-static char msg_regfail[] __initdata = KERN_ERR \
+static const char msg_regfail[] __initdata = KERN_ERR \
"6pack: can't register line discipline (err = %d)\n";
static int __init sixpack_init_driver(void)
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 81a65e3a1c05..bb78c11559cd 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -203,7 +203,6 @@ struct baycom_state {
unsigned char buf[TXBUFFER_SIZE];
} hdlctx;
- struct net_device_stats stats;
unsigned int ptt_keyed;
struct sk_buff *skb; /* next transmit packet */
@@ -423,7 +422,7 @@ static void encode_hdlc(struct baycom_state *bc)
bc->hdlctx.bufptr = bc->hdlctx.buf;
bc->hdlctx.bufcnt = wp - bc->hdlctx.buf;
dev_kfree_skb(skb);
- bc->stats.tx_packets++;
+ bc->dev->stats.tx_packets++;
}
/* ---------------------------------------------------------------------- */
@@ -547,7 +546,7 @@ static void do_rxpacket(struct net_device *dev)
pktlen = bc->hdlcrx.bufcnt-2+1; /* KISS kludge */
if (!(skb = dev_alloc_skb(pktlen))) {
printk("%s: memory squeeze, dropping packet\n", dev->name);
- bc->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
cp = skb_put(skb, pktlen);
@@ -555,7 +554,7 @@ static void do_rxpacket(struct net_device *dev)
memcpy(cp, bc->hdlcrx.buf, pktlen - 1);
skb->protocol = ax25_type_trans(skb, dev);
netif_rx(skb);
- bc->stats.rx_packets++;
+ dev->stats.rx_packets++;
}
static int receive(struct net_device *dev, int cnt)
@@ -802,19 +801,6 @@ static int baycom_set_mac_address(struct net_device *dev, void *addr)
/* --------------------------------------------------------------------- */
-static struct net_device_stats *baycom_get_stats(struct net_device *dev)
-{
- struct baycom_state *bc = netdev_priv(dev);
-
- /*
- * Get the current statistics. This may be called with the
- * card open or closed.
- */
- return &bc->stats;
-}
-
-/* --------------------------------------------------------------------- */
-
static void epp_wakeup(void *handle)
{
struct net_device *dev = (struct net_device *)handle;
@@ -1065,10 +1051,10 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
hi.data.cs.ptt = !!(bc->stat & EPP_PTTBIT);
hi.data.cs.dcd = !(bc->stat & EPP_DCDBIT);
hi.data.cs.ptt_keyed = bc->ptt_keyed;
- hi.data.cs.tx_packets = bc->stats.tx_packets;
- hi.data.cs.tx_errors = bc->stats.tx_errors;
- hi.data.cs.rx_packets = bc->stats.rx_packets;
- hi.data.cs.rx_errors = bc->stats.rx_errors;
+ hi.data.cs.tx_packets = dev->stats.tx_packets;
+ hi.data.cs.tx_errors = dev->stats.tx_errors;
+ hi.data.cs.rx_packets = dev->stats.rx_packets;
+ hi.data.cs.rx_errors = dev->stats.rx_errors;
break;
case HDLCDRVCTL_OLDGETSTAT:
@@ -1116,6 +1102,14 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
/* --------------------------------------------------------------------- */
+static const struct net_device_ops baycom_netdev_ops = {
+ .ndo_open = epp_open,
+ .ndo_stop = epp_close,
+ .ndo_do_ioctl = baycom_ioctl,
+ .ndo_start_xmit = baycom_send_packet,
+ .ndo_set_mac_address = baycom_set_mac_address,
+};
+
/*
* Check for a network adaptor of this type, and return '0' if one exists.
* If dev->base_addr == 0, probe all likely locations.
@@ -1143,17 +1137,12 @@ static void baycom_probe(struct net_device *dev)
/*
* initialize the device struct
*/
- dev->open = epp_open;
- dev->stop = epp_close;
- dev->do_ioctl = baycom_ioctl;
- dev->hard_start_xmit = baycom_send_packet;
- dev->get_stats = baycom_get_stats;
/* Fill in the fields of the device structure */
bc->skb = NULL;
+ dev->netdev_ops = &baycom_netdev_ops;
dev->header_ops = &ax25_header_ops;
- dev->set_mac_address = baycom_set_mac_address;
dev->type = ARPHRD_AX25; /* AF_AX25 device */
dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 46f8f3390e7d..d509b371a562 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -87,7 +87,8 @@
#include <linux/bpqether.h>
-static char banner[] __initdata = KERN_INFO "AX.25: bpqether driver version 004\n";
+static const char banner[] __initdata = KERN_INFO \
+ "AX.25: bpqether driver version 004\n";
static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
@@ -96,8 +97,8 @@ static char bpq_eth_addr[6];
static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
static int bpq_device_event(struct notifier_block *, unsigned long, void *);
-static struct packet_type bpq_packet_type = {
- .type = __constant_htons(ETH_P_BPQ),
+static struct packet_type bpq_packet_type __read_mostly = {
+ .type = cpu_to_be16(ETH_P_BPQ),
.func = bpq_rcv,
};
@@ -110,7 +111,6 @@ struct bpqdev {
struct list_head bpq_list; /* list of bpq devices chain */
struct net_device *ethdev; /* link to ethernet device */
struct net_device *axdev; /* bpq device (bpq#) */
- struct net_device_stats stats; /* some statistics */
char dest_addr[6]; /* ether destination address */
char acpt_addr[6]; /* accept ether frames from this address only */
};
@@ -222,8 +222,8 @@ static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty
skb_pull(skb, 2); /* Remove the length bytes */
skb_trim(skb, len); /* Set the length of the data */
- bpq->stats.rx_packets++;
- bpq->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
ptr = skb_push(skb, 1);
*ptr = 0;
@@ -292,7 +292,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
bpq = netdev_priv(dev);
if ((dev = bpq_get_ether_dev(dev)) == NULL) {
- bpq->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
kfree_skb(skb);
return -ENODEV;
}
@@ -300,8 +300,8 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
skb->protocol = ax25_type_trans(skb, dev);
skb_reset_network_header(skb);
dev_hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
- bpq->stats.tx_packets++;
- bpq->stats.tx_bytes+=skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes+=skb->len;
dev_queue_xmit(skb);
netif_wake_queue(dev);
@@ -309,16 +309,6 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
}
/*
- * Statistics
- */
-static struct net_device_stats *bpq_get_stats(struct net_device *dev)
-{
- struct bpqdev *bpq = netdev_priv(dev);
-
- return &bpq->stats;
-}
-
-/*
* Set AX.25 callsign
*/
static int bpq_set_mac_address(struct net_device *dev, void *addr)
@@ -396,6 +386,7 @@ static int bpq_close(struct net_device *dev)
* Proc filesystem
*/
static void *bpq_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
int i = 1;
struct bpqdev *bpqdev;
@@ -428,6 +419,7 @@ static void *bpq_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void bpq_seq_stop(struct seq_file *seq, void *v)
+ __releases(RCU)
{
rcu_read_unlock();
}
@@ -454,7 +446,7 @@ static int bpq_seq_show(struct seq_file *seq, void *v)
return 0;
}
-static struct seq_operations bpq_seqops = {
+static const struct seq_operations bpq_seqops = {
.start = bpq_seq_start,
.next = bpq_seq_next,
.stop = bpq_seq_stop,
@@ -477,16 +469,17 @@ static const struct file_operations bpq_info_fops = {
/* ------------------------------------------------------------------------ */
+static const struct net_device_ops bpq_netdev_ops = {
+ .ndo_open = bpq_open,
+ .ndo_stop = bpq_close,
+ .ndo_start_xmit = bpq_xmit,
+ .ndo_set_mac_address = bpq_set_mac_address,
+ .ndo_do_ioctl = bpq_ioctl,
+};
static void bpq_setup(struct net_device *dev)
{
-
- dev->hard_start_xmit = bpq_xmit;
- dev->open = bpq_open;
- dev->stop = bpq_close;
- dev->set_mac_address = bpq_set_mac_address;
- dev->get_stats = bpq_get_stats;
- dev->do_ioctl = bpq_ioctl;
+ dev->netdev_ops = &bpq_netdev_ops;
dev->destructor = free_netdev;
memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index e67103396ed7..7459b3ac77a9 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -195,7 +195,7 @@ struct scc_priv {
int chip;
struct net_device *dev;
struct scc_info *info;
- struct net_device_stats stats;
+
int channel;
int card_base, scc_cmd, scc_data;
int tmr_cnt, tmr_ctrl, tmr_mode;
@@ -239,7 +239,6 @@ static int scc_open(struct net_device *dev);
static int scc_close(struct net_device *dev);
static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
static int scc_send_packet(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *scc_get_stats(struct net_device *dev);
static int scc_set_mac_address(struct net_device *dev, void *sa);
static inline void tx_on(struct scc_priv *priv);
@@ -441,6 +440,14 @@ static void __init dev_setup(struct net_device *dev)
memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN);
}
+static const struct net_device_ops scc_netdev_ops = {
+ .ndo_open = scc_open,
+ .ndo_stop = scc_close,
+ .ndo_start_xmit = scc_send_packet,
+ .ndo_do_ioctl = scc_ioctl,
+ .ndo_set_mac_address = scc_set_mac_address,
+};
+
static int __init setup_adapter(int card_base, int type, int n)
{
int i, irq, chip;
@@ -576,13 +583,8 @@ static int __init setup_adapter(int card_base, int type, int n)
sprintf(dev->name, "dmascc%i", 2 * n + i);
dev->base_addr = card_base;
dev->irq = irq;
- dev->open = scc_open;
- dev->stop = scc_close;
- dev->do_ioctl = scc_ioctl;
- dev->hard_start_xmit = scc_send_packet;
- dev->get_stats = scc_get_stats;
+ dev->netdev_ops = &scc_netdev_ops;
dev->header_ops = &ax25_header_ops;
- dev->set_mac_address = scc_set_mac_address;
}
if (register_netdev(info->dev[0])) {
printk(KERN_ERR "dmascc: could not register %s\n",
@@ -961,14 +963,6 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev)
}
-static struct net_device_stats *scc_get_stats(struct net_device *dev)
-{
- struct scc_priv *priv = dev->ml_priv;
-
- return &priv->stats;
-}
-
-
static int scc_set_mac_address(struct net_device *dev, void *sa)
{
memcpy(dev->dev_addr, ((struct sockaddr *) sa)->sa_data,
@@ -1216,17 +1210,17 @@ static void special_condition(struct scc_priv *priv, int rc)
}
if (priv->rx_over) {
/* We had an overrun */
- priv->stats.rx_errors++;
+ priv->dev->stats.rx_errors++;
if (priv->rx_over == 2)
- priv->stats.rx_length_errors++;
+ priv->dev->stats.rx_length_errors++;
else
- priv->stats.rx_fifo_errors++;
+ priv->dev->stats.rx_fifo_errors++;
priv->rx_over = 0;
} else if (rc & CRC_ERR) {
/* Count invalid CRC only if packet length >= minimum */
if (cb >= 15) {
- priv->stats.rx_errors++;
- priv->stats.rx_crc_errors++;
+ priv->dev->stats.rx_errors++;
+ priv->dev->stats.rx_crc_errors++;
}
} else {
if (cb >= 15) {
@@ -1239,8 +1233,8 @@ static void special_condition(struct scc_priv *priv, int rc)
priv->rx_count++;
schedule_work(&priv->rx_work);
} else {
- priv->stats.rx_errors++;
- priv->stats.rx_over_errors++;
+ priv->dev->stats.rx_errors++;
+ priv->dev->stats.rx_over_errors++;
}
}
}
@@ -1275,7 +1269,7 @@ static void rx_bh(struct work_struct *ugli_api)
skb = dev_alloc_skb(cb + 1);
if (skb == NULL) {
/* Drop packet */
- priv->stats.rx_dropped++;
+ priv->dev->stats.rx_dropped++;
} else {
/* Fill buffer */
data = skb_put(skb, cb + 1);
@@ -1283,8 +1277,8 @@ static void rx_bh(struct work_struct *ugli_api)
memcpy(&data[1], priv->rx_buf[i], cb);
skb->protocol = ax25_type_trans(skb, priv->dev);
netif_rx(skb);
- priv->stats.rx_packets++;
- priv->stats.rx_bytes += cb;
+ priv->dev->stats.rx_packets++;
+ priv->dev->stats.rx_bytes += cb;
}
spin_lock_irqsave(&priv->ring_lock, flags);
/* Move tail */
@@ -1351,15 +1345,15 @@ static void es_isr(struct scc_priv *priv)
write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN);
if (res) {
/* Update packet statistics */
- priv->stats.tx_errors++;
- priv->stats.tx_fifo_errors++;
+ priv->dev->stats.tx_errors++;
+ priv->dev->stats.tx_fifo_errors++;
/* Other underrun interrupts may already be waiting */
write_scc(priv, R0, RES_EXT_INT);
write_scc(priv, R0, RES_EXT_INT);
} else {
/* Update packet statistics */
- priv->stats.tx_packets++;
- priv->stats.tx_bytes += priv->tx_len[i];
+ priv->dev->stats.tx_packets++;
+ priv->dev->stats.tx_bytes += priv->tx_len[i];
/* Remove frame from FIFO */
priv->tx_tail = (i + 1) % NUM_TX_BUF;
priv->tx_count--;
@@ -1425,7 +1419,7 @@ static void tm_isr(struct scc_priv *priv)
write_scc(priv, R15, DCDIE);
priv->rr0 = read_scc(priv, R0);
if (priv->rr0 & DCD) {
- priv->stats.collisions++;
+ priv->dev->stats.collisions++;
rx_on(priv);
priv->state = RX_ON;
} else {
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index 8eba61a1d4ab..61de56e45eed 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -154,7 +154,7 @@ static void hdlc_rx_flag(struct net_device *dev, struct hdlcdrv_state *s)
pkt_len = s->hdlcrx.len - 2 + 1; /* KISS kludge */
if (!(skb = dev_alloc_skb(pkt_len))) {
printk("%s: memory squeeze, dropping packet\n", dev->name);
- s->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
cp = skb_put(skb, pkt_len);
@@ -162,7 +162,7 @@ static void hdlc_rx_flag(struct net_device *dev, struct hdlcdrv_state *s)
memcpy(cp, s->hdlcrx.buffer, pkt_len - 1);
skb->protocol = ax25_type_trans(skb, dev);
netif_rx(skb);
- s->stats.rx_packets++;
+ dev->stats.rx_packets++;
}
void hdlcdrv_receiver(struct net_device *dev, struct hdlcdrv_state *s)
@@ -326,7 +326,7 @@ void hdlcdrv_transmitter(struct net_device *dev, struct hdlcdrv_state *s)
s->hdlctx.len = pkt_len+2; /* the appended CRC */
s->hdlctx.tx_state = 2;
s->hdlctx.bitstream = 0;
- s->stats.tx_packets++;
+ dev->stats.tx_packets++;
break;
case 2:
if (!s->hdlctx.len) {
@@ -427,19 +427,6 @@ static int hdlcdrv_set_mac_address(struct net_device *dev, void *addr)
}
/* --------------------------------------------------------------------- */
-
-static struct net_device_stats *hdlcdrv_get_stats(struct net_device *dev)
-{
- struct hdlcdrv_state *sm = netdev_priv(dev);
-
- /*
- * Get the current statistics. This may be called with the
- * card open or closed.
- */
- return &sm->stats;
-}
-
-/* --------------------------------------------------------------------- */
/*
* Open/initialize the board. This is called (in the current kernel)
* sometime after booting when the 'ifconfig' program is run.
@@ -568,10 +555,10 @@ static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
bi.data.cs.ptt = hdlcdrv_ptt(s);
bi.data.cs.dcd = s->hdlcrx.dcd;
bi.data.cs.ptt_keyed = s->ptt_keyed;
- bi.data.cs.tx_packets = s->stats.tx_packets;
- bi.data.cs.tx_errors = s->stats.tx_errors;
- bi.data.cs.rx_packets = s->stats.rx_packets;
- bi.data.cs.rx_errors = s->stats.rx_errors;
+ bi.data.cs.tx_packets = dev->stats.tx_packets;
+ bi.data.cs.tx_errors = dev->stats.tx_errors;
+ bi.data.cs.rx_packets = dev->stats.rx_packets;
+ bi.data.cs.rx_errors = dev->stats.rx_errors;
break;
case HDLCDRVCTL_OLDGETSTAT:
@@ -630,6 +617,14 @@ static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
/* --------------------------------------------------------------------- */
+static const struct net_device_ops hdlcdrv_netdev = {
+ .ndo_open = hdlcdrv_open,
+ .ndo_stop = hdlcdrv_close,
+ .ndo_start_xmit = hdlcdrv_send_packet,
+ .ndo_do_ioctl = hdlcdrv_ioctl,
+ .ndo_set_mac_address = hdlcdrv_set_mac_address,
+};
+
/*
* Initialize fields in hdlcdrv
*/
@@ -669,21 +664,13 @@ static void hdlcdrv_setup(struct net_device *dev)
s->bitbuf_hdlc.shreg = 0x80;
#endif /* HDLCDRV_DEBUG */
- /*
- * initialize the device struct
- */
- dev->open = hdlcdrv_open;
- dev->stop = hdlcdrv_close;
- dev->do_ioctl = hdlcdrv_ioctl;
- dev->hard_start_xmit = hdlcdrv_send_packet;
- dev->get_stats = hdlcdrv_get_stats;
/* Fill in the fields of the device structure */
s->skb = NULL;
+ dev->netdev_ops = &hdlcdrv_netdev;
dev->header_ops = &ax25_header_ops;
- dev->set_mac_address = hdlcdrv_set_mac_address;
dev->type = ARPHRD_AX25; /* AF_AX25 device */
dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index bbdb311b8420..032c0db4c410 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -59,8 +59,6 @@ struct mkiss {
unsigned char *xhead; /* pointer to next byte to XMIT */
int xleft; /* bytes left in XMIT queue */
- struct net_device_stats stats;
-
/* Detailed SLIP statistics. */
int mtu; /* Our mtu (to spot changes!) */
int buffsize; /* Max buffers sizes */
@@ -253,7 +251,7 @@ static void ax_bump(struct mkiss *ax)
if (ax->rbuff[0] > 0x0f) {
if (ax->rbuff[0] & 0x80) {
if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
- ax->stats.rx_errors++;
+ ax->dev->stats.rx_errors++;
spin_unlock_bh(&ax->buflock);
return;
@@ -268,7 +266,7 @@ static void ax_bump(struct mkiss *ax)
*ax->rbuff &= ~0x80;
} else if (ax->rbuff[0] & 0x20) {
if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
- ax->stats.rx_errors++;
+ ax->dev->stats.rx_errors++;
spin_unlock_bh(&ax->buflock);
return;
}
@@ -295,7 +293,7 @@ static void ax_bump(struct mkiss *ax)
if ((skb = dev_alloc_skb(count)) == NULL) {
printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n",
ax->dev->name);
- ax->stats.rx_dropped++;
+ ax->dev->stats.rx_dropped++;
spin_unlock_bh(&ax->buflock);
return;
}
@@ -303,8 +301,8 @@ static void ax_bump(struct mkiss *ax)
memcpy(skb_put(skb,count), ax->rbuff, count);
skb->protocol = ax25_type_trans(skb, ax->dev);
netif_rx(skb);
- ax->stats.rx_packets++;
- ax->stats.rx_bytes += count;
+ ax->dev->stats.rx_packets++;
+ ax->dev->stats.rx_bytes += count;
spin_unlock_bh(&ax->buflock);
}
@@ -344,7 +342,7 @@ static void kiss_unesc(struct mkiss *ax, unsigned char s)
return;
}
- ax->stats.rx_over_errors++;
+ ax->dev->stats.rx_over_errors++;
set_bit(AXF_ERROR, &ax->flags);
}
spin_unlock_bh(&ax->buflock);
@@ -406,7 +404,7 @@ static void ax_changedmtu(struct mkiss *ax)
memcpy(ax->xbuff, ax->xhead, ax->xleft);
} else {
ax->xleft = 0;
- ax->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
}
}
@@ -417,7 +415,7 @@ static void ax_changedmtu(struct mkiss *ax)
memcpy(ax->rbuff, orbuff, ax->rcount);
} else {
ax->rcount = 0;
- ax->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
set_bit(AXF_ERROR, &ax->flags);
}
}
@@ -444,7 +442,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
if (len > ax->mtu) { /* Sigh, shouldn't occur BUT ... */
len = ax->mtu;
printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name);
- ax->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
netif_start_queue(dev);
return;
}
@@ -518,8 +516,8 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
actual = ax->tty->ops->write(ax->tty, ax->xbuff, count);
- ax->stats.tx_packets++;
- ax->stats.tx_bytes += actual;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += actual;
ax->dev->trans_start = jiffies;
ax->xleft = count - actual;
@@ -664,32 +662,28 @@ static int ax_close(struct net_device *dev)
return 0;
}
-static struct net_device_stats *ax_get_stats(struct net_device *dev)
-{
- struct mkiss *ax = netdev_priv(dev);
-
- return &ax->stats;
-}
-
static const struct header_ops ax_header_ops = {
.create = ax_header,
.rebuild = ax_rebuild_header,
};
+static const struct net_device_ops ax_netdev_ops = {
+ .ndo_open = ax_open_dev,
+ .ndo_stop = ax_close,
+ .ndo_start_xmit = ax_xmit,
+ .ndo_set_mac_address = ax_set_mac_address,
+};
+
static void ax_setup(struct net_device *dev)
{
/* Finish setting up the DEVICE info. */
dev->mtu = AX_MTU;
- dev->hard_start_xmit = ax_xmit;
- dev->open = ax_open_dev;
- dev->stop = ax_close;
- dev->get_stats = ax_get_stats;
- dev->set_mac_address = ax_set_mac_address;
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->type = ARPHRD_AX25;
dev->tx_queue_len = 10;
dev->header_ops = &ax_header_ops;
+ dev->netdev_ops = &ax_netdev_ops;
memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
@@ -929,7 +923,7 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
while (count--) {
if (fp != NULL && *fp++) {
if (!test_and_set_bit(AXF_ERROR, &ax->flags))
- ax->stats.rx_errors++;
+ ax->dev->stats.rx_errors++;
cp++;
continue;
}
@@ -982,9 +976,9 @@ static struct tty_ldisc_ops ax_ldisc = {
.write_wakeup = mkiss_write_wakeup
};
-static char banner[] __initdata = KERN_INFO \
+static const char banner[] __initdata = KERN_INFO \
"mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
-static char msg_regfail[] __initdata = KERN_ERR \
+static const char msg_regfail[] __initdata = KERN_ERR \
"mkiss: can't register line discipline (err = %d)\n";
static int __init mkiss_init_driver(void)
@@ -993,8 +987,9 @@ static int __init mkiss_init_driver(void)
printk(banner);
- if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0)
- printk(msg_regfail);
+ status = tty_register_ldisc(N_AX25, &ax_ldisc);
+ if (status != 0)
+ printk(msg_regfail, status);
return status;
}
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index c011af7088ea..d712e7af780c 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -184,7 +184,8 @@
#include "z8530.h"
-static char banner[] __initdata = KERN_INFO "AX.25: Z8530 SCC driver version "VERSION".dl1bke\n";
+static const char banner[] __initdata = KERN_INFO \
+ "AX.25: Z8530 SCC driver version "VERSION".dl1bke\n";
static void t_dwait(unsigned long);
static void t_txdelay(unsigned long);
@@ -1542,23 +1543,24 @@ static int scc_net_alloc(const char *name, struct scc_channel *scc)
/* * Network driver methods * */
/* ******************************************************************** */
+static const struct net_device_ops scc_netdev_ops = {
+ .ndo_open = scc_net_open,
+ .ndo_stop = scc_net_close,
+ .ndo_start_xmit = scc_net_tx,
+ .ndo_set_mac_address = scc_net_set_mac_address,
+ .ndo_get_stats = scc_net_get_stats,
+ .ndo_do_ioctl = scc_net_ioctl,
+};
+
/* ----> Initialize device <----- */
static void scc_net_setup(struct net_device *dev)
{
dev->tx_queue_len = 16; /* should be enough... */
- dev->open = scc_net_open;
- dev->stop = scc_net_close;
-
- dev->hard_start_xmit = scc_net_tx;
+ dev->netdev_ops = &scc_netdev_ops;
dev->header_ops = &ax25_header_ops;
- dev->set_mac_address = scc_net_set_mac_address;
- dev->get_stats = scc_net_get_stats;
- dev->do_ioctl = scc_net_ioctl;
- dev->tx_timeout = NULL;
-
memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
memcpy(dev->dev_addr, &ax25_defaddr, AX25_ADDR_LEN);
@@ -2073,7 +2075,7 @@ static int scc_net_seq_show(struct seq_file *seq, void *v)
return 0;
}
-static struct seq_operations scc_net_seq_ops = {
+static const struct seq_operations scc_net_seq_ops = {
.start = scc_net_seq_start,
.next = scc_net_seq_next,
.stop = scc_net_seq_stop,
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 5407f7486c9c..b06691937ce9 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -55,6 +55,8 @@
#include <asm/system.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
@@ -71,16 +73,18 @@
#include <linux/init.h>
#include <linux/yam.h>
-#include "yam9600.h"
-#include "yam1200.h"
/* --------------------------------------------------------------------- */
static const char yam_drvname[] = "yam";
-static char yam_drvinfo[] __initdata = KERN_INFO "YAM driver version 0.8 by F1OAT/F6FBB\n";
+static const char yam_drvinfo[] __initdata = KERN_INFO \
+ "YAM driver version 0.8 by F1OAT/F6FBB\n";
/* --------------------------------------------------------------------- */
+#define FIRMWARE_9600 "yam/9600.bin"
+#define FIRMWARE_1200 "yam/1200.bin"
+
#define YAM_9600 1
#define YAM_1200 2
@@ -115,10 +119,6 @@ struct yam_port {
struct net_device *dev;
- /* Stats section */
-
- struct net_device_stats stats;
-
int nb_rxint;
int nb_mdint;
@@ -345,9 +345,51 @@ static int fpga_write(int iobase, unsigned char wrd)
return 0;
}
-static unsigned char *add_mcs(unsigned char *bits, int bitrate)
+/*
+ * predef should be 0 for loading user defined mcs
+ * predef should be YAM_1200 for loading predef 1200 mcs
+ * predef should be YAM_9600 for loading predef 9600 mcs
+ */
+static unsigned char *add_mcs(unsigned char *bits, int bitrate,
+ unsigned int predef)
{
+ const char *fw_name[2] = {FIRMWARE_9600, FIRMWARE_1200};
+ const struct firmware *fw;
+ struct platform_device *pdev;
struct yam_mcs *p;
+ int err;
+
+ switch (predef) {
+ case 0:
+ fw = NULL;
+ break;
+ case YAM_1200:
+ case YAM_9600:
+ predef--;
+ pdev = platform_device_register_simple("yam", 0, NULL, 0);
+ if (IS_ERR(pdev)) {
+ printk(KERN_ERR "yam: Failed to register firmware\n");
+ return NULL;
+ }
+ err = request_firmware(&fw, fw_name[predef], &pdev->dev);
+ platform_device_unregister(pdev);
+ if (err) {
+ printk(KERN_ERR "Failed to load firmware \"%s\"\n",
+ fw_name[predef]);
+ return NULL;
+ }
+ if (fw->size != YAM_FPGA_SIZE) {
+ printk(KERN_ERR "Bogus length %zu in firmware \"%s\"\n",
+ fw->size, fw_name[predef]);
+ release_firmware(fw);
+ return NULL;
+ }
+ bits = (unsigned char *)fw->data;
+ break;
+ default:
+ printk(KERN_ERR "yam: Invalid predef number %u\n", predef);
+ return NULL;
+ }
/* If it already exists, replace the bit data */
p = yam_data;
@@ -362,6 +404,7 @@ static unsigned char *add_mcs(unsigned char *bits, int bitrate)
/* Allocate a new mcs */
if ((p = kmalloc(sizeof(struct yam_mcs), GFP_KERNEL)) == NULL) {
printk(KERN_WARNING "YAM: no memory to allocate mcs\n");
+ release_firmware(fw);
return NULL;
}
memcpy(p->bits, bits, YAM_FPGA_SIZE);
@@ -369,6 +412,7 @@ static unsigned char *add_mcs(unsigned char *bits, int bitrate)
p->next = yam_data;
yam_data = p;
+ release_firmware(fw);
return p->bits;
}
@@ -386,9 +430,11 @@ static unsigned char *get_mcs(int bitrate)
/* Load predefined mcs data */
switch (bitrate) {
case 1200:
- return add_mcs(bits_1200, bitrate);
+ /* setting predef as YAM_1200 for loading predef 1200 mcs */
+ return add_mcs(NULL, bitrate, YAM_1200);
default:
- return add_mcs(bits_9600, bitrate);
+ /* setting predef as YAM_9600 for loading predef 9600 mcs */
+ return add_mcs(NULL, bitrate, YAM_9600);
}
}
@@ -507,7 +553,7 @@ static inline void yam_rx_flag(struct net_device *dev, struct yam_port *yp)
} else {
if (!(skb = dev_alloc_skb(pkt_len))) {
printk(KERN_WARNING "%s: memory squeeze, dropping packet\n", dev->name);
- ++yp->stats.rx_dropped;
+ ++dev->stats.rx_dropped;
} else {
unsigned char *cp;
cp = skb_put(skb, pkt_len);
@@ -515,7 +561,7 @@ static inline void yam_rx_flag(struct net_device *dev, struct yam_port *yp)
memcpy(cp, yp->rx_buf, pkt_len - 1);
skb->protocol = ax25_type_trans(skb, dev);
netif_rx(skb);
- ++yp->stats.rx_packets;
+ ++dev->stats.rx_packets;
}
}
}
@@ -677,7 +723,7 @@ static void yam_tx_byte(struct net_device *dev, struct yam_port *yp)
yp->tx_count = 1;
yp->tx_state = TX_HEAD;
}
- ++yp->stats.tx_packets;
+ ++dev->stats.tx_packets;
break;
case TX_TAIL:
if (--yp->tx_count <= 0) {
@@ -716,7 +762,7 @@ static irqreturn_t yam_interrupt(int irq, void *dev_id)
handled = 1;
if (lsr & LSR_OE)
- ++yp->stats.rx_fifo_errors;
+ ++dev->stats.rx_fifo_errors;
yp->dcd = (msr & RX_DCD) ? 1 : 0;
@@ -778,16 +824,16 @@ static int yam_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, " TxTail %u\n", yp->txtail);
seq_printf(seq, " SlotTime %u\n", yp->slot);
seq_printf(seq, " Persist %u\n", yp->pers);
- seq_printf(seq, " TxFrames %lu\n", yp->stats.tx_packets);
- seq_printf(seq, " RxFrames %lu\n", yp->stats.rx_packets);
+ seq_printf(seq, " TxFrames %lu\n", dev->stats.tx_packets);
+ seq_printf(seq, " RxFrames %lu\n", dev->stats.rx_packets);
seq_printf(seq, " TxInt %u\n", yp->nb_mdint);
seq_printf(seq, " RxInt %u\n", yp->nb_rxint);
- seq_printf(seq, " RxOver %lu\n", yp->stats.rx_fifo_errors);
+ seq_printf(seq, " RxOver %lu\n", dev->stats.rx_fifo_errors);
seq_printf(seq, "\n");
return 0;
}
-static struct seq_operations yam_seqops = {
+static const struct seq_operations yam_seqops = {
.start = yam_seq_start,
.next = yam_seq_next,
.stop = yam_seq_stop,
@@ -812,26 +858,6 @@ static const struct file_operations yam_info_fops = {
/* --------------------------------------------------------------------- */
-static struct net_device_stats *yam_get_stats(struct net_device *dev)
-{
- struct yam_port *yp;
-
- if (!dev)
- return NULL;
-
- yp = netdev_priv(dev);
- if (yp->magic != YAM_MAGIC)
- return NULL;
-
- /*
- * Get the current statistics. This may be called with the
- * card open or closed.
- */
- return &yp->stats;
-}
-
-/* --------------------------------------------------------------------- */
-
static int yam_open(struct net_device *dev)
{
struct yam_port *yp = netdev_priv(dev);
@@ -877,10 +903,10 @@ static int yam_open(struct net_device *dev)
/* Reset overruns for all ports - FPGA programming makes overruns */
for (i = 0; i < NR_PORTS; i++) {
- struct net_device *dev = yam_devs[i];
- struct yam_port *yp = netdev_priv(dev);
- inb(LSR(dev->base_addr));
- yp->stats.rx_fifo_errors = 0;
+ struct net_device *yam_dev = yam_devs[i];
+
+ inb(LSR(yam_dev->base_addr));
+ yam_dev->stats.rx_fifo_errors = 0;
}
printk(KERN_INFO "%s at iobase 0x%lx irq %u uart %s\n", dev->name, dev->base_addr, dev->irq,
@@ -959,7 +985,8 @@ static int yam_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
kfree(ym);
return -EINVAL;
}
- add_mcs(ym->bits, ym->bitrate);
+ /* setting predef as 0 for loading userdefined mcs data */
+ add_mcs(ym->bits, ym->bitrate, 0);
kfree(ym);
break;
@@ -1068,6 +1095,14 @@ static int yam_set_mac_address(struct net_device *dev, void *addr)
/* --------------------------------------------------------------------- */
+static const struct net_device_ops yam_netdev_ops = {
+ .ndo_open = yam_open,
+ .ndo_stop = yam_close,
+ .ndo_start_xmit = yam_send_packet,
+ .ndo_do_ioctl = yam_ioctl,
+ .ndo_set_mac_address = yam_set_mac_address,
+};
+
static void yam_setup(struct net_device *dev)
{
struct yam_port *yp = netdev_priv(dev);
@@ -1088,18 +1123,11 @@ static void yam_setup(struct net_device *dev)
dev->base_addr = yp->iobase;
dev->irq = yp->irq;
- dev->open = yam_open;
- dev->stop = yam_close;
- dev->do_ioctl = yam_ioctl;
- dev->hard_start_xmit = yam_send_packet;
- dev->get_stats = yam_get_stats;
-
skb_queue_head_init(&yp->send_queue);
+ dev->netdev_ops = &yam_netdev_ops;
dev->header_ops = &ax25_header_ops;
- dev->set_mac_address = yam_set_mac_address;
-
dev->type = ARPHRD_AX25;
dev->hard_header_len = AX25_MAX_HEADER_LEN;
dev->mtu = AX25_MTU;
@@ -1181,6 +1209,8 @@ static void __exit yam_cleanup_driver(void)
MODULE_AUTHOR("Frederic Rible F1OAT frible@teaser.fr");
MODULE_DESCRIPTION("Yam amateur radio modem driver");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FIRMWARE_1200);
+MODULE_FIRMWARE(FIRMWARE_9600);
module_init(yam_init_driver);
module_exit(yam_cleanup_driver);
diff --git a/drivers/net/hamradio/yam1200.h b/drivers/net/hamradio/yam1200.h
deleted file mode 100644
index 53ca8a3903a7..000000000000
--- a/drivers/net/hamradio/yam1200.h
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- *
- * File yam1k2b5.mcs converted to h format by mcs2h
- *
- * (C) F6FBB 1998
- *
- * Tue Aug 25 20:24:08 1998
- *
- */
-
-static unsigned char bits_1200[]= {
-0xff,0xf2,0x00,0xa5,0xad,0xff,0xfe,0x9f,0xff,0xef,0xf3,0xcb,0xff,0xdb,0xfc,0xf2,
-0xff,0xf6,0xff,0x3c,0xbf,0xfd,0xbf,0xdf,0x6e,0x3f,0x6f,0xf1,0x7d,0xb4,0xfd,0xbf,
-0xdf,0x6f,0x3f,0x6f,0xf7,0x0b,0xff,0xdb,0xfd,0xf2,0xff,0xf6,0xff,0xff,0xff,0xff,
-0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xdf,0xff,0xff,0xff,0xef,0xff,0xff,0xff,
-0xfd,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xbf,
-0xff,0xff,0xf7,0xff,0xff,0xfb,0xff,0xff,0xff,0xfc,0xff,0xfe,0xff,0xff,0xff,0xf0,
-0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xf1,0xff,0xff,0xfe,0x7f,0xbf,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xfb,0xff,0xff,0xff,0xf0,0x9f,
-0xff,0xff,0xff,0xfe,0xff,0xfd,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xf7,0xff,
-0xff,0xff,0xfb,0xff,0xfb,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xf7,0xff,0xff,0xfb,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xef,0xff,0xf0,0x5f,0xff,
-0xff,0xff,0xfe,0xff,0xff,0xef,0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xbf,0xff,0xff,0xdf,0xf7,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xfb,0xfe,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,
-0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xeb,
-0xff,0xff,0xff,0xfd,0xff,0xbf,0xf1,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xfb,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x6f,0xff,0xff,0xff,
-0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xf7,0xff,0xff,0xf1,0xff,0xff,0xf7,0xbf,0xe7,0xff,0xff,0xff,0xff,0xfb,
-0xff,0xff,0xff,0xff,0xff,0xff,0x77,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xdb,
-0xff,0xff,0xf5,0xa5,0xfd,0x4b,0x6e,0xef,0x33,0x32,0xdd,0xd3,0x4a,0xd6,0x92,0xfe,
-0xb3,0x3f,0xbd,0xf1,0xfa,0xdb,0xfe,0xf7,0xf6,0x96,0xbd,0xbd,0xff,0xbd,0xff,0xed,
-0x7f,0x6b,0x7f,0xfb,0xdf,0xfe,0xfb,0xfe,0x90,0xcf,0xff,0xff,0xff,0xfe,0xbe,0xef,
-0xff,0xff,0xdb,0x5f,0xf6,0xff,0xf6,0x8f,0xfd,0xa5,0xdd,0xff,0xff,0xff,0xff,0x6f,
-0x7f,0xdb,0xf1,0xfc,0xbf,0xff,0x6f,0xff,0xef,0xfc,0x5b,0x5d,0xda,0xdf,0xf4,0xff,
-0xf2,0xff,0xfd,0xbf,0xff,0xff,0xff,0xd0,0x1f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
-0xff,0xfb,0xef,0xb7,0xfc,0x33,0xff,0xfb,0xff,0x04,0x6a,0xf3,0x3c,0x36,0xff,0xf0,
-0x0f,0xf1,0x0f,0xff,0xff,0xff,0xf3,0x15,0x72,0x0f,0xf1,0x6f,0xff,0xfe,0x94,0x3f,
-0xff,0xff,0xff,0x7b,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf0,
-0xf7,0xef,0xb7,0xfc,0x33,0xff,0xff,0xff,0x04,0x6a,0xf3,0x3c,0x36,0xff,0xf0,0x0f,
-0xf1,0x0f,0xff,0xff,0xff,0xf3,0x15,0x73,0x8f,0xf2,0x6f,0xff,0xfe,0x94,0x3f,0xff,
-0xff,0xff,0x7d,0x9f,0xff,0xf0,0x0f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x9e,
-0xff,0xfc,0xef,0xd3,0xfb,0xff,0x7f,0xf5,0x5f,0xfe,0x59,0xff,0xff,0xff,0xfc,0xf1,
-0xfe,0x7f,0xff,0xff,0xfa,0x17,0xff,0xe7,0xef,0xef,0xff,0xff,0x3f,0xf1,0xff,0xff,
-0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xf5,0xff,0xbf,0xff,0xfc,0xea,
-0xff,0xf0,0xff,0xff,0xbf,0xf9,0x3f,0xb1,0xef,0xff,0xd7,0xff,0xfb,0xff,0xf0,0xff,
-0xff,0xf3,0xff,0xdf,0xff,0x7b,0xff,0xfd,0xff,0xf6,0xff,0xbf,0xff,0xff,0xbf,0xff,
-0xff,0xff,0xda,0xf0,0xff,0xff,0xff,0xff,0xfe,0xf2,0xc0,0x01,0x00,0x00,0x02,0x02,
-0x02,0x02,0x00,0x40,0x40,0x40,0x10,0x00,0x00,0x00,0x20,0x00,0x00,0x01,0x00,0x00,
-0x00,0x00,0x00,0x00,0x19,0x00,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,
-0x00,0x3c,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xfb,0xff,0xfd,0xff,
-0xff,0x7f,0xff,0xff,0xbf,0xff,0xef,0xff,0xff,0xfd,0xff,0xff,0xf1,0xff,0xdf,0xff,
-0xff,0xff,0xff,0xff,0xff,0xbf,0xfe,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xdf,
-0xdb,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xf0,0xbf,0xdf,0xff,0x7f,0xff,0xff,0xff,0xff,
-0xdf,0xdf,0xff,0xef,0xff,0x9e,0xef,0xff,0xff,0x7f,0xff,0xf1,0xef,0xff,0xff,0xff,
-0xf7,0xfa,0xbf,0xff,0xff,0xfe,0x47,0xef,0xff,0xbd,0xf6,0xff,0xff,0xdf,0xf5,0xf0,
-0xf0,0xef,0xff,0xff,0xff,0xfe,0xf8,0x30,0x00,0x00,0x00,0x04,0x00,0x01,0x02,0x08,
-0x16,0x00,0x00,0x00,0x80,0x00,0x01,0x02,0x00,0x80,0x01,0x0c,0x02,0x00,0x00,0x01,
-0x00,0x00,0x20,0x00,0x00,0x06,0x00,0x20,0x00,0x10,0x00,0x14,0x00,0x04,0xc1,0xf0,
-0x2f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xff,0x7f,
-0xec,0xff,0xff,0xfa,0xff,0xbf,0xff,0x6f,0xff,0xe1,0xff,0xff,0xff,0xff,0xbd,0xfe,
-0x46,0xff,0xef,0x7f,0xcd,0xdf,0xff,0xff,0xfd,0xff,0xbd,0xff,0x7f,0x7f,0xf0,0x4f,
-0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x0f,0xff,
-0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0xa4,0xbc,0xcd,0x6d,0x6b,0x6f,0x5b,0xdc,0x33,
-0x5a,0xf6,0xf7,0xf6,0xb3,0x3f,0xbd,0xc1,0xfa,0x5a,0xf6,0xf6,0xb6,0xf7,0xff,0xbd,
-0xbb,0x3c,0xce,0xcf,0x34,0xef,0x33,0xbb,0xcc,0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,
-0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,0xf6,0xd6,0xff,0xfd,0xfd,0xbf,0xff,0xad,
-0xbf,0xf9,0x7f,0x6f,0xfc,0xdb,0xf1,0xfd,0xbf,0xff,0x6f,0xff,0xff,0xda,0xdb,0xfc,
-0xdb,0xff,0x76,0x8f,0xf6,0xff,0xcd,0xab,0xfe,0xfb,0xff,0xd0,0xff,0xff,0xff,0xff,
-0xfe,0xff,0x9f,0xff,0xf4,0x20,0xaf,0x6d,0x0b,0xc1,0x7b,0xff,0xff,0xff,0xcb,0xff,
-0x3f,0xf0,0xef,0x7f,0x0f,0xf1,0xc3,0x3c,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x0b,
-0x1d,0x6a,0x64,0x05,0x6b,0x99,0x01,0xff,0xfd,0xef,0xf0,0x2f,0xff,0xff,0xff,0xfe,
-0xff,0xff,0xff,0xf4,0x00,0x2f,0xcc,0x0b,0xc3,0x7f,0xff,0xff,0xff,0x0a,0xdf,0xbf,
-0xfd,0x7f,0xff,0xff,0xf1,0xc3,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x4a,0x0e,
-0x96,0x64,0x02,0x97,0x99,0x10,0xff,0xff,0xff,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,
-0xff,0xff,0xfe,0x84,0xf9,0xd5,0x27,0xf1,0x7f,0xff,0xf8,0xeb,0xdf,0xf3,0xcf,0x3f,
-0x1f,0xff,0xf7,0x11,0xff,0xcf,0xff,0xfe,0x67,0xff,0xff,0xff,0xff,0xc4,0xff,0xff,
-0xb3,0xa1,0xff,0xf9,0xe0,0xff,0xff,0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xf5,0xff,
-0xff,0xfb,0x7f,0xe0,0xff,0xc7,0xfe,0x7f,0x3f,0xff,0xfd,0x77,0x8d,0x7f,0x0f,0xff,
-0xc3,0xff,0xf1,0xbf,0x8f,0xcf,0xff,0xff,0xdd,0x7b,0xff,0xf6,0xfa,0xf7,0xff,0x40,
-0x9f,0xf9,0x7f,0xd8,0xff,0xff,0xfa,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xf1,0xc0,0x00,
-0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x10,0x00,0x00,0x10,
-0x00,0x01,0x00,0x10,0x20,0x20,0x00,0x00,0x10,0x00,0x04,0x01,0x05,0x00,0x00,0x00,
-0x00,0x40,0x40,0x00,0x00,0x3c,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,
-0xff,0xff,0xfe,0x7f,0x7f,0xff,0xef,0xff,0xff,0xdf,0xff,0xff,0xdf,0xff,0xef,0xf7,
-0xf1,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xf7,0xff,0xff,0xff,0xfc,0xfd,0xff,0x7f,
-0x7e,0xff,0xff,0xff,0xdb,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xf0,0xbb,0xff,0xff,0xff,
-0xff,0xff,0xfe,0xeb,0xfd,0x6f,0xff,0xf7,0xfe,0xf5,0x7f,0xff,0xff,0x7f,0xbf,0xb1,
-0xff,0xff,0x9f,0xbf,0xfb,0xff,0xfe,0xff,0xfe,0xff,0xf7,0xeb,0xdf,0xbf,0x5f,0xdd,
-0xff,0xdb,0xfd,0xd0,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xf8,0x30,0x20,0x00,0x42,0x00,
-0x00,0x00,0x30,0x18,0x04,0x08,0x09,0x21,0x82,0x80,0x02,0x00,0x08,0x00,0x01,0x00,
-0x00,0x00,0x0c,0x20,0x10,0x00,0x11,0x00,0x44,0x84,0x00,0x20,0x20,0x84,0x80,0x00,
-0x00,0x00,0xc1,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xf7,0xff,0xfb,0xdd,0xf9,0xff,
-0xda,0xff,0xdc,0xdd,0xfc,0xfb,0xff,0xbf,0xfb,0x3e,0xd7,0x96,0xfe,0x61,0xf7,0xff,
-0x7f,0xff,0x3f,0xfd,0xff,0xdf,0xcf,0xf7,0xdf,0xf7,0xbf,0xfd,0xff,0xfe,0xef,0xef,
-0xfe,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf3,0xbd,0xfd,0x4b,0x74,0xcf,
-0x73,0x5b,0xcb,0x3b,0xdf,0xfe,0xf7,0xfe,0xd3,0x75,0xac,0xa1,0xfb,0xdf,0xfe,0xf7,
-0x76,0x96,0xb5,0x24,0xbd,0xa5,0xad,0x49,0x2f,0x69,0x2b,0x52,0x5b,0xbd,0xff,0xff,
-0xf0,0xcf,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,0xf6,0xfe,0xff,0xcc,
-0xa7,0xfb,0xad,0xff,0x7f,0x6f,0xff,0x6d,0x7f,0xdb,0xf1,0xfd,0xbf,0xff,0x6f,0xff,
-0x6f,0xff,0xdb,0xff,0xdb,0xff,0xf6,0x97,0xf6,0xff,0xb5,0xb5,0xff,0xff,0xff,0xd0,
-0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0xa5,0xbc,0x43,0xfc,0x7c,0x03,0xe7,
-0xff,0xff,0x20,0xff,0xff,0xff,0xcc,0xfd,0x7d,0xf1,0xff,0xff,0xff,0xff,0xd5,0x59,
-0xba,0x56,0x66,0x6a,0xad,0x9a,0xa9,0x9a,0x97,0xa5,0xaa,0xbb,0xff,0xff,0xf0,0x0f,
-0xff,0xff,0xff,0xfe,0xfe,0xfb,0xff,0xfd,0xf7,0xfd,0x43,0xff,0xfd,0x6b,0xe7,0xff,
-0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0x3f,0xf1,0xff,0xff,0xff,0xff,0xd5,0x59,0xb5,
-0xa6,0x66,0x6a,0xad,0x9a,0xa9,0x99,0x6b,0x5a,0xaa,0xff,0xff,0xb7,0xf0,0x3f,0xff,
-0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0x9c,0xf7,0xfd,0xd2,0x41,0xff,0xff,0xf2,0x7f,
-0x8f,0xff,0xff,0x3d,0xf3,0xff,0x17,0xf1,0xff,0xff,0xff,0xff,0xff,0x7f,0xdf,0xfc,
-0x8f,0x38,0xff,0xef,0x23,0xff,0xfb,0xf7,0xc8,0xff,0xff,0xff,0xf0,0x9f,0xff,0xff,
-0xff,0xfe,0xf5,0x7f,0xff,0xfd,0xff,0xe4,0xff,0xeb,0xff,0xcf,0xbf,0xfa,0xff,0xab,
-0xef,0xff,0xfb,0xff,0xf3,0xfd,0x61,0xff,0xff,0xff,0xff,0xfa,0xff,0xfb,0xfd,0x0d,
-0xff,0xfe,0xff,0x43,0x7f,0xfe,0xbf,0xd0,0xfd,0xff,0xfa,0xf0,0x3f,0xff,0xff,0xff,
-0xfe,0xf3,0xc0,0x00,0x00,0x00,0x02,0x00,0x02,0x01,0x00,0x60,0xc0,0x40,0x00,0x00,
-0x00,0x00,0x34,0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x88,0x00,
-0x00,0x03,0x00,0x00,0x40,0x00,0x40,0x00,0x00,0x3c,0xf0,0x3f,0xff,0xff,0xff,0xfe,
-0xfd,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x7f,0xbf,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xf7,0xf1,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xfd,0xff,
-0xff,0xff,0xff,0xfe,0xfe,0x5f,0xff,0xff,0xcb,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xf0,
-0xff,0xff,0xfd,0xff,0xef,0xe3,0xde,0xee,0xd9,0xc5,0x93,0xff,0xff,0xfe,0xfe,0xff,
-0xfb,0xee,0xfe,0xf1,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xbf,0xf7,0xff,0xff,0x7f,
-0xaf,0xbd,0xdf,0xdf,0xfb,0xf3,0xf3,0xf0,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xf8,0x34,
-0x00,0x06,0x61,0x00,0x18,0x01,0xa0,0x05,0x17,0x00,0x20,0x05,0x28,0x20,0x00,0x00,
-0x05,0x00,0x41,0x00,0x00,0x40,0x00,0x09,0x00,0x01,0x20,0x86,0x82,0x08,0x40,0x03,
-0x80,0x30,0x70,0x08,0x14,0x02,0xc1,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
-0xff,0xff,0xbd,0xef,0xfb,0xff,0xff,0xfb,0x9c,0x7f,0xef,0xdf,0xff,0xbf,0xeb,0xde,
-0xff,0xc1,0x7f,0xff,0xfb,0x7f,0xff,0xff,0xff,0x5f,0xff,0xff,0xff,0xdf,0xbf,0xef,
-0x3f,0xf7,0x8f,0xef,0x7f,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xbd,
-0xdf,0xef,0x7d,0x6d,0x2b,0x5a,0x5d,0xd2,0xdf,0xf6,0x92,0xb6,0xb2,0xb3,0xac,0xa1,
-0xfb,0xdf,0xfe,0xf1,0xee,0xf5,0xf6,0xbc,0x6b,0xbd,0x7d,0xaf,0x1a,0xef,0x5f,0x6b,
-0xc6,0xff,0xff,0xff,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,
-0xf6,0xff,0xf6,0xb7,0xfd,0xad,0xfd,0xbf,0xf3,0x6f,0xff,0x6f,0xff,0xdb,0xd1,0xfd,
-0xbf,0xff,0x6f,0xf5,0x6b,0xbc,0x5b,0x3c,0xda,0xef,0x16,0xaf,0x16,0xff,0xcd,0xab,
-0xff,0x6f,0xff,0xd0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfc,0xbf,0xff,0xff,
-0xff,0x6c,0x03,0x10,0xc1,0xf3,0xff,0xf3,0x3a,0xf3,0xca,0xff,0xaf,0xf1,0xff,0xff,
-0xff,0xff,0xd9,0x96,0xa6,0x65,0xa6,0x66,0x6a,0x95,0x69,0x69,0x6a,0x5a,0x5a,0xff,
-0xff,0x5f,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,
-0xea,0x0f,0x50,0xc3,0xf3,0x7f,0xff,0xf3,0xf3,0xc3,0xff,0xaf,0xf1,0xff,0xff,0xff,
-0xff,0xd9,0x96,0xa6,0x65,0xa6,0x66,0x6a,0x95,0x69,0x69,0x6a,0x5a,0x5a,0xff,0xff,
-0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xd7,0xff,0xff,0x5f,0xc1,
-0x3f,0xf7,0x5e,0xf5,0xce,0x9e,0x5f,0x3f,0x17,0xff,0xf3,0xe1,0xff,0xff,0xff,0xff,
-0xd8,0xff,0xfa,0xfe,0x67,0xff,0xfe,0xbf,0x5a,0xff,0xff,0xaf,0xf5,0xff,0xff,0xff,
-0xf0,0x2f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xfd,0xff,0xf7,0xff,0xfd,0x4e,0x3d,
-0x3f,0xe7,0x0b,0xbf,0x8f,0xf9,0xff,0xeb,0xe3,0xff,0xe1,0xff,0xff,0xfc,0xff,0xc7,
-0x9f,0xff,0x3e,0x39,0xe5,0xff,0xcf,0x9b,0xf9,0xff,0xff,0xc5,0xff,0xff,0xfa,0xf0,
-0x5f,0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,
-0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x20,0x00,0x20,
-0x00,0x01,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0xf0,0x4f,
-0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xbf,
-0x3f,0xff,0xff,0xbf,0xff,0xff,0xff,0xfb,0xf1,0xff,0xff,0xff,0xff,0xf7,0xff,0xf7,
-0xff,0xed,0xff,0xfb,0xfe,0xff,0x7f,0xff,0x7f,0xdf,0xff,0xff,0xdd,0xf0,0x3f,0xff,
-0xff,0xff,0xfe,0xf0,0xff,0xff,0xf3,0xff,0xf7,0xff,0xfe,0x5f,0xff,0xf7,0xff,0xff,
-0xdf,0xff,0xff,0xff,0xf7,0xfe,0x7b,0xf1,0xff,0xfd,0xfd,0xff,0xdf,0xdf,0xff,0x7d,
-0x73,0xf9,0xff,0xc3,0x7e,0xfe,0xff,0xef,0xd7,0xff,0xcf,0xd0,0xf0,0x6f,0xff,0xff,
-0xff,0xfe,0xf8,0x30,0x00,0x00,0x40,0x04,0x00,0x01,0x41,0x20,0x00,0x04,0x00,0x02,
-0xd5,0x09,0x00,0x02,0x80,0x02,0x01,0x00,0x00,0x00,0x0a,0x04,0x00,0x07,0x00,0x01,
-0x50,0x01,0x80,0x02,0x61,0x40,0x41,0x0c,0x14,0x08,0xc1,0xf0,0x9f,0xff,0xff,0xff,
-0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0xdf,0xcb,0x5f,0xfe,0xef,0xff,0xfe,
-0xff,0x3f,0xff,0x7f,0xfd,0xc1,0xff,0xff,0x7f,0xff,0xdf,0xfd,0xfc,0xfd,0xf7,0xee,
-0xff,0xff,0x4e,0xff,0xdf,0xcf,0xdb,0xeb,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff,0xfe,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff,0xfe,0x7f,
-0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,
-0xf7,0xfb,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0x7f,0xff,0xff,0xff,0x7f,0xff,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xdd,0xff,
-0xff,0xff,0xa5,0xff,0x6f,0x6b,0xe9,0x6f,0xda,0xca,0xfb,0xdd,0xee,0xf7,0xf6,0xb2,
-0xb3,0xa4,0xa1,0x5b,0x5b,0xf6,0xd7,0xf4,0xf7,0x7b,0xbd,0xbd,0xad,0xcf,0xef,0x7f,
-0x6b,0x7f,0x3b,0xdf,0xdb,0xff,0xff,0x30,0xcf,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,
-0xff,0xff,0xff,0xf6,0xfe,0x96,0xff,0xfd,0xb5,0xfd,0xbf,0xad,0x7f,0xff,0x6f,0xff,
-0xde,0xd1,0xad,0xad,0xe9,0xff,0xf1,0xec,0xef,0xde,0x3f,0xcb,0xff,0xf6,0xff,0x32,
-0xff,0xc5,0xbd,0xff,0xff,0xff,0xd0,0xbf,0xff,0xff,0xff,0xfe,0xfe,0xfb,0xff,0xf4,
-0x28,0xbf,0xff,0xfd,0xfb,0xd3,0xff,0xff,0x42,0xff,0xff,0xff,0xea,0xb3,0xfc,0xc3,
-0xc1,0xff,0x33,0xff,0xc0,0x15,0x6b,0x70,0xff,0xf0,0xf2,0x4f,0xff,0xfc,0x3e,0x97,
-0x3c,0xff,0xff,0xfd,0xef,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0x78,
-0xbf,0xff,0xfd,0xf3,0xef,0x55,0xff,0x7e,0xff,0xff,0xff,0xea,0xb3,0xfc,0xc3,0xc1,
-0xff,0x33,0xff,0xc0,0x15,0x6f,0xff,0x0f,0xf0,0xf0,0x0f,0xff,0xfc,0x3d,0x6b,0xc3,
-0xff,0xff,0xfe,0xf7,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfc,0xff,
-0xff,0x23,0xf8,0x7f,0xff,0x4e,0xff,0xff,0xff,0xfb,0xf9,0x17,0xff,0xf6,0xf1,0xff,
-0xcf,0xef,0xff,0xff,0x13,0xdf,0xe6,0x2f,0xc7,0xff,0xff,0xe7,0xc1,0xfd,0xff,0xfe,
-0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xff,0xfe,0xae,0xff,
-0xff,0x7f,0x3b,0x3f,0xfc,0x7f,0xfc,0xef,0xff,0xfc,0xe2,0x7b,0xff,0xf1,0xfd,0xed,
-0xef,0xff,0xff,0x35,0x73,0xff,0xff,0xfe,0xfa,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,
-0xff,0xfa,0xf0,0x8f,0xff,0xff,0xff,0xfe,0xf1,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x80,0x00,0x00,0x40,0x00,0x00,0x00,0x0c,0x04,0x01,0x40,0x40,0x00,
-0x00,0x30,0x28,0x04,0x00,0x08,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,
-0x38,0xf0,0x0f,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xfb,0xff,0x7f,
-0xff,0xff,0x9f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xdf,0xdf,0xff,
-0xff,0xff,0xff,0xed,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xbf,0xbf,0xff,0xff,0xc3,
-0xf0,0x3f,0xff,0xff,0xff,0xfe,0xf0,0xbf,0xfd,0xff,0xbf,0xff,0xff,0xfd,0xff,0xff,
-0xff,0xff,0xff,0xfd,0x7b,0xff,0x7f,0xff,0xbd,0xff,0xf1,0xef,0xff,0xff,0xfd,0xdf,
-0xfd,0xfb,0xff,0xff,0xbf,0xbe,0xff,0xcd,0x7f,0xfc,0xf7,0xf7,0x6f,0xbf,0xd8,0xf0,
-0xef,0xff,0xff,0xff,0xfe,0xf8,0x30,0x00,0x00,0x00,0x04,0x00,0x00,0xa0,0x00,0x00,
-0xc0,0x00,0x00,0x20,0x34,0x00,0x00,0x00,0x0c,0x81,0x00,0x20,0xa4,0x20,0x00,0x10,
-0x08,0x04,0x48,0x08,0x00,0x40,0x93,0x00,0x10,0x00,0x38,0x18,0x20,0xc1,0xf0,0x3f,
-0xff,0xff,0xff,0xfe,0xff,0xfb,0xff,0xff,0xb9,0xdf,0xfe,0xb3,0xff,0xff,0xe7,0xfd,
-0xff,0xff,0x3b,0xff,0x7f,0xff,0xbf,0xff,0xc1,0xff,0xfc,0xff,0xff,0x3f,0x77,0xfe,
-0xfe,0xcf,0xff,0xbf,0xfd,0xbf,0xff,0xfe,0xed,0xf2,0xfd,0xf7,0xff,0xf0,0x2f,0xff,
-0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xbf,0xff,0xff,
-0xff,0xfe,0xff,0xff,0xff,0xf3,0xad,0xcf,0xef,0x70,0xc9,0x73,0x3b,0xdf,0x5b,0x4a,
-0xf6,0xb7,0xfe,0xd7,0xf5,0xbc,0xc1,0x33,0xca,0xd6,0xb7,0x6e,0xf7,0xfb,0xbd,0xc5,
-0x24,0xcf,0x6f,0x2f,0x4d,0x2b,0xba,0x5a,0xff,0xff,0xff,0xf0,0xaf,0xff,0xff,0xff,
-0xfe,0xbf,0xff,0xff,0xff,0xff,0xf6,0xf6,0xd7,0xff,0xff,0xad,0xbd,0xff,0xff,0xff,
-0xef,0xf7,0x7f,0xfc,0x5b,0xb1,0xfd,0xbd,0x75,0x6f,0xef,0x6a,0xfd,0x5b,0xfb,0xdb,
-0x3a,0xbf,0x8e,0x9f,0xff,0xbf,0xfd,0xff,0x6f,0xff,0xd0,0x6f,0xff,0xff,0xff,0xfe,
-0xff,0xbb,0xff,0xf0,0x3f,0xff,0xff,0xfd,0xfb,0x7f,0xde,0xff,0xff,0x5a,0xd6,0xbf,
-0xd8,0x2a,0xbf,0xbf,0xf1,0xe5,0xff,0xcc,0xc0,0xa9,0x70,0xff,0xf3,0x3c,0x3c,0xfd,
-0x57,0xfd,0x98,0x03,0x00,0xc3,0xff,0xff,0xff,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xff,
-0xff,0xff,0xff,0x3d,0xbf,0xff,0xfd,0xfb,0xff,0xdb,0xff,0xff,0x0f,0xfc,0x3f,0xd8,
-0x2a,0xbf,0xbf,0xf1,0xef,0xff,0xcc,0xc0,0x96,0xbe,0xff,0xf3,0x3f,0xff,0xfd,0x57,
-0xfd,0x99,0x0f,0xff,0xc3,0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xff,0xff,
-0xff,0xf1,0xe7,0xff,0xff,0xf3,0x8e,0x7b,0xff,0xa8,0xff,0xdf,0x7f,0x8e,0x78,0x73,
-0xff,0xf1,0x51,0x62,0xff,0xfc,0x4b,0xff,0xf3,0xff,0x7e,0xcf,0xf9,0xff,0xfd,0xff,
-0xff,0x7f,0xff,0xe0,0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,
-0xfb,0xfd,0xae,0xff,0xfc,0xfe,0x6f,0x3f,0xf8,0xfd,0x77,0xaf,0xfe,0x37,0xfe,0x7b,
-0xff,0xb1,0x8c,0xff,0xef,0xfd,0xf8,0xe7,0xbf,0xff,0xf1,0xfe,0x3e,0xf7,0xfe,0x95,
-0x3e,0xbf,0xff,0xff,0xff,0xfa,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xf1,0xc0,0x00,0x00,
-0x01,0x04,0x00,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x08,
-0x41,0x80,0x10,0x00,0x00,0x08,0x10,0x84,0x00,0x0c,0x04,0x02,0x61,0x00,0x00,0x81,
-0x00,0x00,0x00,0x00,0x3d,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,
-0xff,0xff,0x7f,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,
-0x7f,0xbf,0xf7,0x7f,0xef,0xff,0xef,0xff,0xf7,0xfd,0xff,0xff,0xfd,0x7f,0xff,0xbe,
-0xdf,0xff,0xff,0xd9,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xf0,0xbb,0xff,0x7f,0xfb,0xff,
-0xfb,0xff,0xbf,0xff,0xf3,0x7f,0xfb,0xfd,0xeb,0x7f,0xdf,0xfa,0xff,0xde,0xf0,0xed,
-0xff,0xb1,0xf7,0xf9,0x1f,0xb5,0x5b,0xfe,0x7e,0xf7,0xbe,0xfd,0x7f,0x5f,0xb5,0xf7,
-0xff,0xff,0xd0,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf8,0x30,0x01,0x00,0x07,0x42,0x01,
-0x00,0x6a,0x18,0x50,0x80,0x00,0x00,0x02,0x40,0x01,0x01,0x20,0x01,0x01,0x24,0x14,
-0x21,0x10,0x02,0x08,0x07,0x08,0x00,0x40,0x10,0x80,0x58,0x00,0x84,0x80,0x18,0x10,
-0x40,0xc1,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf7,0xff,0xdb,0xb7,0xf3,
-0xdf,0x7c,0xf8,0x74,0xff,0xff,0x6f,0x7d,0x3f,0x7e,0xec,0x7f,0xc1,0xf5,0xff,0xcf,
-0x6f,0x9f,0xf9,0xdf,0xbe,0xe5,0xe7,0xff,0xd7,0xf3,0xdd,0xfb,0xff,0xfc,0xff,0xbf,
-0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xf0,0x2f,0xff,0xff,0xff,0xfe,0xd7,0xff,0xff,0xff,0xb4,0xcf,0xef,0x77,0x6f,0x73,
-0x3a,0x4a,0x3a,0xcb,0xd4,0xf7,0x2e,0xd6,0xbd,0xbd,0xa1,0x3b,0xdf,0xd6,0xf7,0xee,
-0xd3,0x35,0xbd,0xfb,0xbd,0xce,0xeb,0x2b,0x4d,0x2f,0xbb,0xda,0xff,0xff,0xfe,0xb0,
-0x5f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdf,0x5f,0x36,0xaf,0x3f,0xed,0xb7,
-0xf5,0xfd,0xf3,0x2b,0xef,0x77,0xff,0xfb,0xda,0xb1,0xbd,0xa3,0x77,0x69,0x7f,0x4f,
-0xff,0xdb,0xfa,0x5b,0xff,0xf2,0xfe,0xff,0x96,0xff,0xff,0xfe,0xdf,0xff,0xd0,0xaf,
-0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0x8f,0xfd,0x40,0x6f,0x9e,0x83,0x5a,0x0f,
-0xfa,0xc3,0xff,0xff,0xfc,0xe9,0x7f,0xf3,0x01,0xd0,0x00,0xfe,0xbf,0xcd,0x3f,0xf0,
-0xef,0xfc,0xc5,0x0c,0x3f,0xfd,0x68,0x0b,0xff,0xff,0xff,0xfe,0xdf,0xf0,0xff,0xff,
-0xff,0xff,0xfe,0xff,0xbb,0xff,0xfd,0x85,0xff,0xd4,0x6f,0x9f,0xc3,0x5a,0x0f,0xff,
-0xff,0xff,0xff,0xfc,0xe9,0x7f,0xf3,0x01,0xf0,0xfb,0xc2,0xbf,0xfc,0x00,0x37,0xef,
-0xfc,0xcd,0xbc,0x3f,0xff,0x0c,0xbf,0xff,0xff,0xff,0xff,0xff,0xf0,0x5f,0xff,0xff,
-0xff,0xfe,0xff,0xff,0xff,0xff,0xd9,0xf7,0xd1,0xb7,0x7e,0x7f,0xf1,0xe4,0xfd,0xff,
-0xfb,0xfb,0xff,0x5f,0xff,0x7f,0xb1,0xbc,0x0f,0x67,0xeb,0xb8,0x3f,0xff,0xe2,0xff,
-0xe9,0xff,0xfd,0xe3,0xff,0x3f,0x9f,0xc2,0xff,0xff,0xff,0xf0,0x9f,0xff,0xff,0xff,
-0xfe,0xf5,0x7f,0xff,0xf0,0x3f,0xbc,0xff,0xd5,0xf5,0xce,0x3f,0xfe,0xff,0xfe,0x6d,
-0xff,0xf1,0xbf,0x7b,0xff,0xf1,0xfd,0xff,0x4f,0xff,0x87,0xff,0xae,0xff,0xb1,0xf8,
-0xfe,0xff,0xff,0x78,0x01,0xb9,0xff,0xff,0xff,0xfa,0xf0,0x2f,0xff,0xff,0xff,0xfe,
-0xf3,0xc0,0x00,0x00,0x00,0x04,0x02,0x13,0x02,0x00,0x80,0x40,0x00,0x90,0x10,0x00,
-0x10,0x00,0x02,0x00,0x01,0x20,0x80,0x12,0x10,0x00,0x40,0x08,0x00,0x04,0x00,0x00,
-0x02,0x00,0x01,0x40,0x00,0x80,0x00,0x00,0x3c,0xf0,0xef,0xff,0xff,0xff,0xfe,0xfd,
-0x1f,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0x7f,0xff,0x7f,0xf7,0xdf,0xf7,0xff,
-0xf7,0xfb,0xeb,0xd1,0xff,0xff,0xff,0xff,0xef,0xf7,0xff,0xff,0xfb,0xff,0xfe,0xff,
-0xff,0x7e,0xff,0xfb,0xff,0xff,0xff,0xdb,0xf0,0xff,0xff,0xff,0xff,0xfe,0xf0,0xff,
-0xff,0xb7,0xeb,0xf7,0xdf,0xff,0xfe,0xf5,0x6b,0xe7,0xed,0xf7,0x3e,0xec,0xff,0x54,
-0xef,0x6f,0xf1,0xf5,0xaf,0x6f,0xf6,0xfd,0xff,0xdd,0x7b,0xff,0xef,0xbf,0x7f,0xff,
-0xff,0xf7,0xff,0xf3,0x5f,0xf7,0xd0,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xf8,0x30,0x00,
-0x80,0x40,0x04,0x00,0x81,0x2c,0x04,0x24,0x00,0x02,0x01,0xc8,0x02,0x00,0x02,0x24,
-0x00,0x01,0xb4,0x42,0xdc,0x44,0x02,0x15,0x90,0x02,0x03,0x48,0x39,0x10,0x02,0x24,
-0xa0,0xba,0x00,0x00,0x40,0xc1,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
-0xfe,0xfc,0xf7,0xf0,0xee,0xb6,0x5d,0xfd,0xf5,0xff,0xdb,0xf7,0x7f,0x7f,0xbe,0xff,
-0xc1,0xfe,0xbf,0xfa,0xfa,0x5f,0xff,0xad,0xff,0xef,0xff,0x7f,0xdf,0x7f,0xfe,0xbf,
-0xb7,0x94,0xbf,0xff,0xff,0xf0,0x9f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xf0,0x8f,0xff,0xff,0xff,0xfe,0xd7,0xff,0xff,0xfb,0xb5,0xff,
-0xef,0x7c,0xeb,0x2b,0x52,0x5b,0x3b,0xda,0xd4,0xf3,0x36,0x96,0xb5,0xbd,0xf1,0xfb,
-0xda,0xee,0xf6,0xfe,0xd3,0x35,0xbd,0xdf,0xad,0xcf,0xef,0x7e,0xcd,0x6b,0xbb,0xdf,
-0xff,0xff,0xfd,0xb0,0xef,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xd3,0x5f,0xf6,
-0xff,0xf6,0xff,0xfd,0xad,0xfd,0xff,0x7f,0xef,0xff,0x6f,0x7f,0xdb,0xf1,0xa5,0xa3,
-0x7f,0x6f,0x6b,0x4f,0xff,0xdb,0xfb,0xcb,0xff,0xf6,0xff,0xf4,0xd7,0xfd,0xbf,0xfe,
-0xdf,0xff,0xd0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf7,0xdf,0xff,0xff,0xff,
-0x3f,0x7f,0xfc,0xe5,0xff,0x20,0xfe,0xff,0xff,0xdf,0x7f,0xff,0xf1,0x7f,0xff,0xfe,
-0xff,0xf0,0x7c,0x3d,0x4f,0xf3,0xc3,0x3f,0xff,0xff,0x6f,0xc3,0xff,0x0f,0xff,0xff,
-0xaf,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xff,0xff,0xfb,0xb7,0xe0,0x0f,0xff,0xff,0x2b,
-0xff,0x7d,0xbf,0xff,0xdf,0xff,0xff,0xf8,0x9f,0x7f,0xff,0xf1,0x55,0xff,0xff,0xff,
-0xfd,0x7c,0x3c,0xff,0xf3,0xc3,0x3f,0xff,0xff,0xef,0xc3,0xff,0xdf,0xff,0xff,0xff,
-0xf0,0x9f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xef,0xff,0xff,0x9f,0xbf,0x7f,
-0xf9,0x19,0x47,0x8e,0xe7,0x9f,0x3f,0x17,0xff,0xfc,0x81,0xc1,0x7e,0xf3,0xd9,0xf9,
-0x73,0xdf,0xf4,0x7f,0xfa,0xff,0xff,0xff,0xfb,0x7f,0x77,0xc7,0xff,0xff,0xff,0xf0,
-0x2f,0xff,0xff,0xff,0xfe,0xf5,0xf7,0xff,0xfb,0xff,0xf7,0x3f,0xfc,0xbf,0x3e,0x3f,
-0xec,0xff,0x81,0xaf,0xfe,0x4f,0xf3,0xbb,0xff,0xf0,0x7e,0xff,0x6f,0xff,0x87,0xff,
-0xbb,0xff,0xd5,0xfc,0xff,0x7f,0xfc,0x6f,0xff,0xef,0xe7,0xff,0xff,0xfa,0xf0,0x3f,
-0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
-0x00,0x30,0x10,0x60,0x20,0x00,0x08,0x00,0x01,0x20,0x80,0x00,0x10,0x00,0x04,0x00,
-0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x80,0x40,0x00,0x08,0x20,0x3c,0xf0,0x6f,0xff,
-0xff,0xff,0xfe,0xf5,0xbf,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x7f,0xfe,0x3f,0xff,
-0xff,0xff,0xff,0xff,0xef,0xff,0xff,0xf1,0xdf,0xdf,0xff,0xff,0xff,0x7f,0xdf,0xff,
-0xfd,0xbd,0xff,0xff,0xff,0xfb,0xdf,0xff,0xff,0xff,0xff,0x5b,0xf0,0xff,0xff,0xff,
-0xff,0xfe,0xf0,0xbf,0xbf,0xbf,0xff,0xf7,0xfb,0xff,0xfe,0xee,0xfa,0xff,0xff,0xff,
-0x3d,0x3b,0xff,0xff,0xfe,0xfb,0xf1,0xff,0xbf,0x7b,0xff,0xff,0xef,0xff,0xbf,0xff,
-0xff,0xff,0xff,0xff,0xfe,0xff,0xf7,0xef,0xff,0xfb,0xd0,0xf0,0xdf,0xff,0xff,0xff,
-0xfe,0xf8,0x30,0x00,0x00,0x00,0x00,0x00,0x0b,0x10,0x05,0x01,0x00,0x08,0x00,0x02,
-0x01,0x01,0x00,0x00,0x10,0x01,0xc8,0x08,0x00,0x00,0x00,0x00,0x42,0x02,0x00,0x00,
-0x00,0x80,0x02,0x00,0x00,0x40,0x24,0x80,0x00,0xc1,0xf0,0x3f,0xff,0xff,0xff,0xfe,
-0xff,0xff,0xff,0xff,0xf7,0xfd,0xf7,0xfa,0xef,0xee,0xf9,0xfd,0xff,0xf7,0xfe,0xbf,
-0x1f,0xfd,0x9e,0xfd,0xd1,0xef,0xff,0xf7,0x7f,0x9f,0xff,0xef,0xff,0xf6,0xff,0xfe,
-0xfe,0x7b,0xff,0xbd,0xff,0x7e,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xff,0xff,
-0xff,0xf7,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xdf,0xfd,0xff,0xff,0xdf,0xff,
-0xff,0x5f,0xf1,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xef,0xff,
-0xf7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xfb,0xff,0xff,0xef,0xfb,0xfd,
-0xff,0xf1,0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xf7,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xe7,0xff,
-0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcf,0xff,0xfb,0xff,0xfb,0xf1,
-0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7b,0xff,0xff,0xff,0x7f,0xff,0xf1,0xff,
-0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xef,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x57,0xff,0xfe,0xbf,0xfb,0xf1,0xff,0xff,
-0xfd,0xf7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xd7,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf7,0xdb,0xff,0xdb,0xfd,
-0xf6,0xff,0xf6,0xff,0x3c,0xbc,0xbc,0xbf,0xdf,0x6f,0xef,0x2f,0xf1,0x3c,0xbf,0xbc,
-0xbf,0xdf,0x6f,0xff,0x6f,0xf7,0xdb,0xff,0xdb,0xfd,0xf6,0xff,0xf6,0xff,0xff,0xff,
-0x01,0xe2,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff };
diff --git a/drivers/net/hamradio/yam9600.h b/drivers/net/hamradio/yam9600.h
deleted file mode 100644
index 5ed1fe6ff43e..000000000000
--- a/drivers/net/hamradio/yam9600.h
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- *
- * File yam111.mcs converted to h format by mcs2h
- *
- * (C) F6FBB 1998
- *
- * Tue Aug 25 20:23:03 1998
- *
- */
-
-static unsigned char bits_9600[]= {
-0xff,0xf2,0x00,0xa5,0xad,0xff,0xfe,0x9f,0xff,0xef,0xfb,0xcb,0xff,0xdb,0xfe,0xf2,
-0xff,0xf6,0xff,0x9c,0xbf,0xfd,0xbf,0xef,0x2e,0x3f,0x6f,0xf1,0xfd,0xb4,0xfd,0xbf,
-0xff,0x6f,0xff,0x6f,0xff,0x0b,0xff,0xdb,0xff,0xf2,0xff,0xf6,0xff,0xff,0xff,0xff,
-0xf0,0x6f,0xff,0xff,0xff,0xfe,0xff,0xfd,0xdf,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,
-0xfb,0xff,0xff,0xf7,0xff,0xff,0xff,0xfe,0xff,0x7f,0xf1,0xff,0xfe,0xff,0xbf,0xbf,
-0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0xf0,
-0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,0xf7,
-0xff,0xff,0xf7,0xef,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0x7e,0xff,0xff,
-0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xf0,0xdf,
-0xff,0xff,0xff,0xfe,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xef,0xff,0xf3,0xfb,0xfe,0xff,0xf1,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xdf,0xff,0xf0,0x7f,0xff,
-0xff,0xff,0xfe,0xff,0xff,0xef,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xdf,0xff,0xff,0xff,0xf7,0xf1,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xf0,0x0f,0xff,0xff,
-0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf5,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff,
-0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xef,0xff,0x7f,0xff,0xef,
-0xff,0xef,0xff,0x7f,0xef,0xf1,0xff,0xef,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xf0,0x9f,0xff,0xff,0xff,0xfe,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xff,
-0xff,0xff,0xff,0xbd,0xff,0xef,0x7f,0xef,0x7f,0xfb,0xdf,0xd3,0x5a,0xfe,0xd7,0xd6,
-0xf7,0x7f,0xbd,0xf1,0xbb,0x5d,0xd6,0xf7,0xfe,0x96,0xff,0xbd,0xaf,0xad,0xbf,0xef,
-0x7f,0x6b,0x7f,0xfb,0xd6,0xfe,0xf7,0xff,0x10,0xef,0xff,0xff,0xff,0xfe,0xbe,0xef,
-0xff,0xff,0xdb,0xff,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xfd,0xbf,0xff,0x7f,0xff,0x7f,
-0xdf,0xdb,0xf1,0xfd,0x35,0xff,0x6f,0xff,0x6f,0xff,0xdb,0xff,0xcb,0xff,0xf6,0xff,
-0xf2,0xfd,0xfd,0xbf,0xff,0xff,0xff,0xd0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0xff,0xcc,0xc0,0x3f,0xff,
-0xff,0xf1,0x24,0xf0,0xff,0xff,0xcf,0xef,0x3f,0xff,0xf0,0xff,0xff,0xff,0xfc,0x3f,
-0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0xff,0xcc,0xc0,0x3f,0xff,0xff,
-0xf1,0x00,0xf0,0xff,0xff,0xcf,0xdf,0xff,0xff,0xf0,0xff,0xff,0xff,0xfc,0x3f,0xff,
-0xff,0xff,0x7d,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xfe,0x7f,0xdf,0xff,0xff,0xff,0xf1,
-0xff,0xcf,0xff,0xf3,0xff,0x97,0xff,0xff,0x8f,0xe7,0xff,0xff,0xfc,0x71,0xff,0xff,
-0xff,0xff,0xff,0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xf5,0xff,0xbf,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xe3,0xf7,0xef,0xff,0xff,0xfc,0x7b,0xff,0xf1,0x3f,
-0xff,0xef,0xff,0xcf,0xe3,0xe3,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xbf,0xff,
-0xbf,0xff,0xda,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xf2,0xc0,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
-0x01,0x3c,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xdb,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0x9f,0xff,
-0xff,0xff,0xf7,0xff,0xef,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xdb,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xf0,0xbb,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xfb,0xdf,0xbf,0xf1,0xfe,0xfd,0xf7,0xff,
-0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x77,0xfd,0xf2,
-0xf0,0x1f,0xff,0xff,0xff,0xfe,0xf8,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,
-0x00,0x00,0x00,0x02,0x00,0x90,0x00,0x00,0x00,0x0c,0x01,0x00,0x00,0x04,0x24,0x00,
-0x40,0x01,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x01,0xc0,0xf0,
-0x4f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xbf,0xff,0xff,0x6f,0xff,0xdf,0xff,0xd1,0xff,0xfe,0xff,0xff,0xff,0xff,
-0xff,0xff,0xdf,0xff,0xfb,0xff,0xfb,0xef,0xff,0xff,0xee,0xff,0xff,0x7f,0xf0,0xdf,
-0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x8f,0xff,
-0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,0xad,0xff,0x69,0x2a,0xed,0x6b,0xfb,0xdf,0x3a,
-0xdc,0xf4,0x96,0xee,0xb3,0x3d,0x35,0xc1,0xbb,0xdd,0xfe,0xf6,0xfe,0xd6,0xb5,0xad,
-0xbf,0xa5,0xad,0x49,0x2f,0x4f,0x2b,0xda,0x5f,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,
-0xff,0xfe,0xbf,0xff,0xff,0xfb,0x5b,0xf7,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xfd,0xa5,
-0xf3,0x6f,0xf3,0x6e,0xfa,0x7b,0xd1,0xfd,0xb5,0x77,0x6f,0xe9,0x6f,0xff,0xdb,0xfb,
-0xdb,0xdf,0xf6,0xff,0xf6,0xff,0xfd,0x3f,0xfe,0xf7,0xff,0xd0,0x4f,0xff,0xff,0xff,
-0xfe,0xff,0x9f,0xff,0xff,0x0f,0xff,0xc0,0x3f,0x9c,0x03,0xff,0xff,0x8b,0xa5,0xfe,
-0x80,0x3e,0xc2,0xbf,0xac,0xb1,0x24,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xff,0xa3,
-0xff,0xfd,0x6b,0xff,0xff,0xf0,0xa5,0xff,0xff,0xff,0xf0,0xaf,0xff,0xff,0xff,0xfe,
-0xff,0xff,0xff,0xff,0x0f,0xff,0xc0,0x3f,0xd4,0x6b,0xff,0xff,0xdb,0xff,0xfe,0x86,
-0xbf,0xc2,0xbf,0x30,0xa1,0x24,0xff,0xff,0xff,0xff,0xcc,0xff,0x0f,0xff,0xa3,0xff,
-0x05,0x6b,0xff,0xff,0xf0,0xa5,0xff,0xff,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,
-0xff,0xff,0xfb,0xc7,0xff,0xc4,0xff,0xff,0x7f,0xff,0xec,0xfe,0x7f,0xdf,0xd8,0xb9,
-0x47,0xfc,0x36,0xc1,0xdf,0xff,0xff,0xf9,0xff,0xf3,0xff,0xf7,0xff,0xfc,0xff,0xfd,
-0x3f,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xf5,0xff,
-0xff,0xff,0xff,0xfe,0xff,0xff,0x7e,0xbd,0x3f,0xff,0x2b,0xfe,0x2f,0xf5,0xa3,0xfc,
-0x5b,0xfe,0x61,0x9f,0x7f,0xef,0xff,0xff,0xa7,0xfb,0xff,0xff,0xfa,0xfe,0xff,0x33,
-0xf1,0xff,0xbf,0xff,0xff,0xff,0xfa,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xf1,0xc0,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x30,0x24,0x04,
-0x00,0x01,0x00,0x80,0x40,0x00,0x08,0x00,0x00,0x00,0x02,0x01,0x01,0x00,0x02,0x00,
-0x00,0x00,0x00,0x00,0x01,0x3d,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xfd,0xbd,0xff,0xfd,
-0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xff,0x7f,0xf6,0xef,0xbf,0xf7,0xff,0x73,0xeb,
-0xf1,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xf9,0xff,0xfd,0xfe,0xff,0xff,
-0xff,0xff,0xff,0xff,0xd9,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xf0,0xbf,0x7f,0xff,0xff,
-0xff,0x7f,0xff,0xff,0xde,0xff,0xff,0xef,0xdd,0xde,0x77,0xf2,0xfb,0xed,0xe7,0xf1,
-0x73,0xfd,0xfd,0xdf,0xff,0x7d,0xbe,0xdf,0xff,0xfb,0xff,0xef,0xff,0xef,0xff,0xff,
-0xff,0xff,0xff,0xd0,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xf8,0x30,0x20,0x02,0x00,0x22,
-0x40,0xc0,0x00,0x00,0x00,0x08,0x00,0x02,0x41,0x02,0x12,0x00,0x21,0x87,0x81,0x00,
-0x00,0x80,0x04,0x0b,0x28,0x01,0xb0,0x00,0x82,0x00,0x40,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0xc1,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,
-0xf7,0xff,0xfe,0x7f,0xed,0x79,0xff,0xde,0xeb,0x7f,0x74,0xf7,0xf7,0xe1,0xf9,0xff,
-0xf6,0x5f,0x7f,0xff,0xff,0xff,0xd7,0xdb,0xef,0xff,0xbb,0xff,0xff,0xff,0xcc,0xff,
-0xff,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xf0,0x0f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0x3d,0xcd,0x49,0x7f,0x6f,
-0x2b,0xba,0x5c,0xd2,0xda,0xf6,0xf3,0x3e,0xf7,0xff,0xbd,0xf1,0xfa,0xdf,0xfe,0xf7,
-0xcc,0xf6,0xbb,0xa5,0xb3,0xad,0xbf,0x6f,0x7d,0x6f,0x6b,0xdb,0xdf,0xbd,0xff,0xfe,
-0xb0,0x5f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xfb,0xdb,0x57,0xf6,0xfe,0x9f,0xd5,
-0xb7,0xff,0xaf,0xe5,0x3f,0xff,0xff,0x6f,0xff,0xdb,0xf1,0xfd,0xbf,0xff,0x6f,0x69,
-0x6c,0xdf,0xda,0xdf,0xcb,0xff,0xf6,0xff,0x76,0xfd,0xfd,0xbf,0xff,0xff,0xff,0xd0,
-0x3f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfd,0xbd,0x08,0x03,0x89,0x4f,0x5a,
-0x0f,0xf0,0xff,0xf8,0xbf,0xff,0xff,0xff,0xff,0xf1,0x5a,0xff,0xff,0xff,0xff,0xf3,
-0xfa,0xa0,0xf0,0xf2,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,
-0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfc,0xfd,0x00,0x6b,0xff,0xff,0x5a,0x0f,
-0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0x5a,0xff,0xff,0xff,0xff,0xb3,0xf5,
-0x50,0xf0,0xf0,0xff,0xff,0xff,0xd7,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x7f,0xff,
-0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0xbc,0xff,0xe4,0xe7,0x71,0xff,0xf9,0xc4,0xf4,
-0x7f,0x7f,0xcf,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xfb,0xf7,0x73,0xbf,0x14,
-0xff,0xe6,0xff,0xff,0xe1,0x7d,0xff,0xff,0xe7,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,
-0xff,0xfe,0xf5,0xff,0xff,0xfe,0xd2,0xfa,0xff,0xc4,0xf4,0x5c,0xbf,0xfa,0xff,0xff,
-0xec,0x7e,0xbf,0xff,0xff,0xff,0xf1,0xff,0xff,0xef,0xff,0xff,0x6b,0xdb,0xff,0xdf,
-0xf9,0xfb,0xbf,0xff,0xf1,0xff,0xbf,0xff,0xff,0xff,0xfb,0xf0,0xbf,0xff,0xff,0xff,
-0xfe,0xf3,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x82,0x00,0x00,0x00,0x00,0x80,0x00,
-0x00,0x00,0x00,0x40,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x20,0x00,0x00,0x00,0x00,
-0x01,0x00,0x01,0x00,0x00,0x80,0x02,0x00,0x01,0x3c,0xf0,0x5f,0xff,0xff,0xff,0xfe,
-0xfd,0xbf,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0x7f,0xff,0xdf,0xff,0xef,0xff,
-0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xfb,0xff,0xfd,0xff,
-0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xc3,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xf0,
-0xff,0xdf,0xff,0xff,0xf7,0x23,0xff,0xff,0xfd,0xff,0xef,0xff,0xfe,0x7f,0x7d,0xf7,
-0xfe,0xff,0x7f,0x71,0xff,0xfb,0x7f,0xff,0xff,0xff,0x6e,0xfd,0xf7,0xfd,0xff,0xbf,
-0xff,0xbf,0xf9,0xfd,0xff,0xdf,0xef,0xf0,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xf8,0x30,
-0x40,0x01,0x00,0x83,0x00,0x00,0x00,0x0c,0x06,0x08,0x04,0x26,0x26,0x00,0x00,0x06,
-0x03,0x00,0x01,0x00,0x00,0x00,0x00,0x04,0x00,0x70,0x08,0x80,0x00,0x20,0x01,0x20,
-0x00,0x02,0x00,0x30,0x00,0x00,0xc1,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
-0xff,0xff,0x7b,0x3f,0xf7,0xff,0xd7,0xfe,0xfe,0xfb,0xfe,0x3b,0xfe,0xbd,0xff,0x2f,
-0xff,0x71,0xff,0xfb,0x7f,0xe7,0xff,0xf9,0xef,0xff,0xd7,0xfa,0xff,0xb7,0xbb,0xfe,
-0xff,0xff,0x74,0xff,0xf7,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xf0,0x8f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xb5,
-0xbd,0x6f,0x7c,0xeb,0x7f,0xfb,0xdb,0xd3,0x4b,0xee,0xd6,0xf6,0xb7,0xfd,0xac,0xa1,
-0xfb,0xdf,0xfe,0xf7,0xf4,0x96,0xbd,0xb4,0xc5,0xa5,0xaf,0x6f,0x69,0x4f,0x7f,0xba,
-0xdb,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,
-0xf6,0xff,0xf6,0xff,0xbd,0xbf,0xa5,0xbf,0xff,0x7d,0x7f,0xef,0xff,0xfb,0xf1,0xfd,
-0xbf,0xff,0x6f,0xff,0x6b,0x7a,0xdb,0xff,0xdb,0xdf,0xf6,0xfe,0xb6,0xfd,0xfd,0xbf,
-0xfe,0xf7,0xff,0xd0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xf4,0x2f,0xff,
-0xfc,0x43,0x6b,0xff,0xff,0xff,0x0d,0xff,0xfc,0x33,0x3f,0xf0,0x5f,0xf1,0xff,0xff,
-0xff,0xff,0xf9,0xde,0xf0,0x4c,0xfe,0x77,0xaf,0xff,0xff,0xef,0xff,0xf0,0xff,0xdb,
-0xff,0x5f,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,0xfe,0xf7,0xff,0xf0,0x2f,0xff,0xfd,
-0x43,0x7f,0xff,0xff,0xf1,0x0f,0xff,0xfc,0x33,0x3f,0xff,0xaf,0xf1,0xff,0xff,0xff,
-0xff,0xf6,0xd7,0xff,0xbc,0xfd,0xbd,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,
-0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfc,0xff,0xff,0xfb,0xf1,
-0xbf,0xff,0xf9,0xfd,0xcf,0xf2,0x70,0xff,0x1f,0x9f,0xf3,0xf1,0xff,0xff,0xff,0xff,
-0xfc,0xf7,0xff,0x13,0x9f,0xfc,0xff,0xff,0x84,0xf7,0xff,0xff,0x47,0xff,0xff,0xff,
-0xf0,0xbf,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xff,0xf1,0xfc,0xff,0xfe,0xfe,0x79,
-0x3f,0xff,0x1d,0x46,0xcf,0xff,0xcf,0xfc,0x7b,0xff,0xf1,0xff,0xff,0xff,0xff,0xed,
-0xf3,0xab,0xff,0xcb,0xff,0xf8,0xff,0xfc,0xf5,0xff,0xbf,0xff,0xff,0xff,0xfa,0xf0,
-0x8f,0xff,0xff,0xff,0xfe,0xf3,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
-0x00,0x00,0x20,0x00,0x20,0x00,0x00,0x04,0x08,0x01,0x00,0x00,0x00,0x00,0x00,0x20,
-0x0c,0x00,0x00,0x04,0x01,0x00,0x01,0x00,0x00,0x80,0x00,0x00,0x01,0x3c,0xf0,0x7f,
-0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xfd,0xfe,0xff,0xff,0xff,0xff,0xfe,0xff,
-0xdf,0xff,0xff,0xf7,0xff,0xff,0xff,0xef,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xeb,
-0xff,0xdf,0xff,0xff,0xfb,0xf7,0x7f,0xff,0xfe,0xff,0xff,0xbf,0xdb,0xf0,0xff,0xff,
-0xff,0xff,0xfe,0xf0,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0x7f,0xf7,0xff,
-0xbf,0xbf,0xcf,0xff,0xff,0xff,0x3e,0xf1,0x7f,0xff,0xff,0xef,0xff,0xff,0xff,0xfe,
-0xff,0xfd,0xff,0xbf,0xbd,0xfe,0xff,0xfb,0xf7,0xdf,0xfb,0xd0,0xf0,0x9f,0xff,0xff,
-0xff,0xfe,0xf8,0x30,0x20,0x00,0x40,0x01,0x80,0xc0,0x30,0x00,0x00,0x20,0x00,0x10,
-0x50,0x88,0x20,0x00,0x00,0x13,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,
-0x00,0x00,0x01,0x80,0x08,0x00,0x00,0xa0,0x00,0x10,0xc1,0xf0,0xef,0xff,0xff,0xff,
-0xfe,0xfd,0xef,0x7f,0xff,0xff,0xbf,0xff,0xf7,0xff,0xef,0xfb,0xfd,0x77,0xef,0xbf,
-0xf7,0x7f,0xff,0xff,0xbf,0xd1,0x7f,0xff,0xff,0xf7,0xff,0xff,0xff,0xff,0xaf,0xff,
-0xdf,0xf7,0xfb,0xff,0xfd,0xff,0xfc,0xff,0xfd,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,
-0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x3f,0xff,0xff,0xff,0xfe,0xdd,0xff,
-0xff,0xff,0xa5,0xfd,0x6f,0x7d,0x6d,0x7f,0x52,0xdf,0x5a,0x4b,0xee,0xb6,0xee,0xf2,
-0xbb,0xac,0xa1,0x5b,0x4d,0xd6,0xf7,0xfe,0xb2,0xbd,0x35,0xb5,0xb5,0xdd,0x6f,0x7f,
-0xe9,0x5f,0x52,0xdf,0xbd,0xff,0xff,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,
-0xff,0xdb,0xfe,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xfd,0xb5,0xbf,0xf9,0x7f,0x6f,0xff,
-0xdb,0xf1,0xfd,0xbf,0xff,0x6f,0xff,0x69,0x7f,0xdb,0xff,0xd3,0xff,0xf6,0xfe,0xf2,
-0xff,0xad,0xbf,0xff,0xff,0xff,0xd0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,
-0x30,0x0f,0xff,0xff,0xfd,0x6b,0xca,0xff,0xf0,0x0f,0xd6,0xbf,0xcf,0x3f,0xff,0xff,
-0xf1,0xff,0xff,0xff,0xca,0xfe,0xbf,0xff,0xf0,0x05,0xaf,0x0f,0xff,0xfc,0xf0,0xcf,
-0xf0,0xff,0xff,0xff,0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,0x30,
-0x0f,0xff,0xff,0xfc,0x3f,0xca,0xff,0x0f,0x0f,0xd6,0xbf,0xff,0xff,0xf5,0x5f,0xf1,
-0xff,0x8b,0xff,0xc3,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xff,0xfc,0xf0,0xcf,0xf0,
-0xff,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xcf,0xff,
-0xff,0xbf,0x9f,0x3f,0xfe,0xfc,0xff,0x4f,0xff,0xff,0xff,0xff,0xff,0xf7,0xf1,0xff,
-0xdf,0xfe,0x7e,0x3f,0x9f,0xf4,0xfc,0x7f,0xfc,0xff,0xff,0x3f,0xff,0x3f,0xfe,0x3f,
-0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xfb,0xff,0xfe,0xff,
-0xff,0xff,0xff,0xbf,0xfb,0xff,0xf8,0xed,0xff,0x8f,0xff,0xbb,0xff,0xb1,0xf3,0xef,
-0x8f,0xf7,0xff,0xff,0xdb,0xff,0xff,0xff,0xef,0xbf,0xfd,0x79,0xbf,0xbf,0xff,0xff,
-0xff,0xfb,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,0x00,0x04,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x04,0x08,0x08,0x01,0x01,0x00,0x90,
-0x00,0x00,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x00,0x01,
-0x3c,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0x9f,0xff,0xaf,0xdf,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,
-0xbf,0xef,0xff,0xff,0xff,0xed,0xff,0xff,0xff,0xef,0xff,0xbf,0xff,0xff,0xff,0xc3,
-0xf0,0x3f,0xff,0xff,0xff,0xfe,0xf0,0xff,0xfd,0xff,0xff,0xff,0xfb,0xff,0xbb,0xff,
-0xff,0xff,0x7f,0xf6,0xff,0x7f,0xfb,0xfd,0xed,0xff,0xf1,0xff,0xfe,0x7f,0xff,0xff,
-0xff,0x5f,0xff,0xf7,0xff,0x7e,0xff,0xfd,0xff,0xef,0xff,0xff,0xff,0xef,0xf0,0xf0,
-0x8f,0xff,0xff,0xff,0xfe,0xf8,0x30,0x80,0x00,0x04,0x00,0x00,0x40,0x02,0x00,0x03,
-0x00,0x05,0x04,0x20,0x00,0x00,0x01,0xd0,0x00,0x81,0x00,0x20,0x04,0x04,0x00,0x00,
-0x81,0x04,0x08,0x80,0x10,0x00,0xc0,0x00,0x00,0x00,0x20,0x00,0x08,0xc1,0xf0,0x6f,
-0xff,0xff,0xff,0xfe,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xf3,0xfd,0xff,0xed,0xfc,
-0xff,0xff,0x9f,0xfb,0xfd,0xff,0xff,0xff,0xf1,0xff,0xff,0x7f,0xfb,0x3e,0xff,0x9f,
-0xff,0xff,0xff,0xff,0xfd,0xf9,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xf0,0x6f,0xff,
-0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xcf,0xff,0xff,
-0xff,0xfe,0xff,0xff,0xff,0xfd,0xbd,0xff,0xef,0x7c,0xeb,0x7f,0xfb,0xdb,0xfa,0xdc,
-0xee,0xf7,0xf6,0xd7,0xf5,0x2d,0xa1,0xbb,0xdd,0xee,0xf7,0x54,0xf7,0xfb,0x2c,0xb5,
-0xb4,0xbd,0x6b,0x6f,0xef,0x6f,0xbb,0xdf,0xff,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff,
-0xfe,0xbf,0xff,0xff,0xff,0xfb,0xff,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xff,0xbf,0xef,
-0x6f,0xff,0x6f,0xfa,0xdb,0xf1,0xc5,0xbd,0xf5,0x6f,0xff,0x6f,0xca,0xdb,0xff,0xdb,
-0xfb,0xf6,0x97,0xf6,0xff,0xfd,0xbf,0xfe,0xf7,0xff,0xd0,0x9f,0xff,0xff,0xff,0xfe,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8b,0x7f,0xff,0xff,0xe7,0x63,0xff,0xff,
-0xff,0xfc,0x77,0xdf,0xf1,0xdb,0xff,0xd6,0xa8,0x3f,0xff,0xff,0x08,0x2f,0xf0,0xff,
-0xc3,0xff,0xeb,0xff,0xff,0xff,0xff,0xff,0x5f,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xfc,0xff,0xcf,0xf1,0xdb,0xff,0xd6,0xa8,0x3f,0xff,0xff,0x08,0x2f,0xf0,0xff,0xc3,
-0xff,0xeb,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0xbf,0xff,0xca,0xff,0x9f,0xff,0xfa,0xb9,0xe7,
-0x9f,0xf3,0x81,0xff,0xff,0xfc,0x73,0xd7,0xff,0xff,0x77,0xff,0xfd,0xff,0xfc,0xff,
-0xff,0xff,0xff,0xcf,0xff,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,
-0xff,0xf7,0xde,0xff,0xfe,0x7e,0xff,0xbf,0xff,0xbf,0xf1,0xb3,0xff,0xff,0xe3,0xfb,
-0xff,0xe1,0x1f,0x7f,0xff,0xf8,0x78,0xff,0xfb,0x1e,0xff,0xf7,0xfe,0xe7,0xff,0xff,
-0xff,0xbf,0xff,0xff,0xff,0xfa,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x04,0x00,
-0x01,0x80,0x40,0x40,0x20,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
-0x80,0x00,0x00,0x01,0x3c,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xfb,0xff,
-0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xf7,0xf1,
-0xfd,0xff,0xff,0xff,0xdf,0xff,0xef,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,
-0xff,0xff,0xff,0xdb,0xf0,0x8f,0xff,0xff,0xff,0xfe,0xf0,0xff,0xdf,0xff,0xff,0x7f,
-0xff,0xff,0xff,0xbe,0xd7,0xff,0xed,0xbd,0x7e,0xbf,0xfe,0xf6,0x7f,0xbf,0x71,0xff,
-0xff,0xda,0xff,0xf9,0xff,0xbf,0x7f,0xfe,0xff,0x6f,0x7f,0xff,0xff,0xff,0xff,0xff,
-0x7f,0xff,0xd0,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xf8,0x30,0x42,0x00,0x00,0x00,0x00,
-0x80,0xc1,0x00,0x00,0x90,0x00,0xc4,0x00,0x00,0x12,0x20,0x43,0x22,0x81,0x84,0x00,
-0x00,0x14,0x00,0x01,0x00,0x08,0x80,0x00,0x02,0x00,0x02,0x00,0x04,0x02,0x00,0x00,
-0x10,0xc1,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xff,0xff,0xfd,0xff,0xff,0xdd,0xfe,0xff,
-0xb6,0x76,0xe5,0xbc,0xf9,0xf7,0xaf,0x5f,0xbf,0xfc,0xdf,0xcf,0xf1,0xff,0xef,0x79,
-0xff,0xbd,0xff,0xef,0xff,0xff,0xf7,0x6f,0x5f,0xff,0xff,0xfd,0xef,0xef,0xbf,0xff,
-0xff,0xf0,0x9f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xf0,0xff,0xff,0xff,0xff,0xfe,0xdb,0xff,0xff,0xfd,0x2d,0xff,0x69,0x2a,0xef,0x77,
-0xbb,0xdd,0x5a,0xdf,0xf6,0xf6,0xd6,0xf7,0x7d,0xbd,0xd1,0xb2,0x4a,0xd6,0xb2,0xbe,
-0x97,0xf5,0xbd,0xb3,0xad,0xff,0xef,0x7f,0x69,0x6b,0xfb,0xdf,0xff,0xff,0xff,0xf0,
-0x2f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,0xf6,0xfe,0x9f,0xd4,0xbf,
-0xed,0xaf,0xff,0x6b,0x6f,0xf7,0xff,0xdd,0xdb,0x31,0xfd,0xbf,0xff,0x6f,0x7f,0xff,
-0xff,0xdb,0xff,0xcb,0xdf,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xfe,0xf7,0xff,0xd0,0x8f,
-0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0x1f,0xff,0x46,0x2f,0x9f,0xff,0xff,0xff,
-0xa5,0xff,0xff,0xff,0xdf,0xb7,0xff,0xff,0xf1,0xff,0xff,0xff,0xf7,0xe9,0x6a,0xbf,
-0xff,0xff,0xfd,0xff,0xff,0xfd,0x55,0x57,0xff,0xff,0xff,0xff,0xaf,0xf0,0x4f,0xff,
-0xff,0xff,0xfe,0xfe,0xdf,0xff,0xfd,0x1f,0xff,0x46,0x2f,0x9f,0xff,0xff,0xff,0xa5,
-0xff,0xff,0xff,0xc0,0x37,0xff,0xff,0xf1,0x99,0x8e,0xdc,0x7f,0xe9,0x6a,0xbf,0xff,
-0xf0,0x0f,0xff,0xff,0xfd,0x55,0x57,0xff,0xff,0xff,0xff,0xff,0xf0,0x0f,0xff,0xff,
-0xff,0xfe,0xff,0xff,0xff,0xff,0x07,0xff,0xc0,0xbe,0xff,0xff,0xcf,0xef,0x9f,0xff,
-0xff,0xfb,0xff,0xe7,0xff,0xff,0xa1,0xe3,0xce,0x3c,0x58,0x3f,0xf3,0xff,0xfd,0xef,
-0xf9,0xff,0xff,0xf7,0xf1,0x7f,0xff,0xcb,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff,
-0xfe,0xf5,0x7f,0xff,0xf0,0xff,0xfe,0xff,0xc4,0x75,0xe7,0xb9,0xff,0xff,0xff,0xef,
-0xff,0xc7,0x37,0x3b,0xff,0xf0,0x13,0x9e,0x0f,0xf4,0xff,0xfe,0xfb,0xff,0xff,0xf9,
-0xfc,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,0xfa,0xf0,0xef,0xff,0xff,0xff,0xfe,
-0xf3,0xc0,0x01,0x00,0x00,0x02,0x00,0x02,0x22,0x00,0x00,0xc0,0x40,0x00,0x40,0x00,
-0x04,0x08,0x04,0x0a,0x01,0x01,0x10,0x20,0x20,0x00,0x00,0x04,0x08,0x08,0x04,0x00,
-0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x3c,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xfd,
-0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0xcf,0x9d,0xff,
-0xff,0xf7,0xfd,0xf1,0xff,0xff,0xff,0xee,0xbf,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xf0,0xff,
-0xff,0xff,0xf7,0xf7,0xff,0xff,0xfe,0xbf,0xf7,0xff,0xff,0x5b,0xff,0xbf,0xf7,0xff,
-0xfd,0x7f,0x71,0xfd,0xff,0xed,0xf7,0xfe,0xef,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,
-0xff,0xff,0xef,0xff,0x7f,0xff,0xd0,0xf0,0xff,0xff,0xff,0xff,0xfe,0xf8,0x30,0x11,
-0x00,0x48,0x60,0x40,0x82,0x60,0x24,0x60,0x00,0xcc,0x00,0x80,0x04,0x01,0x00,0x00,
-0x14,0x01,0x0c,0x04,0x00,0x30,0x00,0x00,0x00,0x08,0x08,0x00,0x01,0x00,0xc2,0x00,
-0x00,0x02,0x00,0x80,0x00,0xc1,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
-0xf7,0x7b,0xff,0xf3,0xeb,0xbf,0xff,0xf7,0xff,0xff,0xff,0xe7,0x5d,0x3f,0xff,0xf6,
-0xd1,0xfd,0xff,0xeb,0xf7,0x3d,0xff,0xff,0xff,0x5f,0xff,0x7f,0x7f,0xf3,0xff,0xff,
-0xef,0xfd,0xbf,0xff,0xff,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,0xb5,0xdf,
-0x6f,0x7d,0x69,0x7f,0xfb,0xdf,0x52,0x5f,0xf6,0xf7,0xfe,0xf6,0xf3,0xbd,0xb1,0xda,
-0xcd,0xfe,0xf6,0xee,0xd2,0xbd,0xa5,0xaf,0xbd,0xff,0x6f,0x7c,0xeb,0x2b,0xfa,0xda,
-0xff,0xfe,0xdf,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,0xf6,
-0xff,0xf6,0xff,0xbd,0xbf,0xcd,0xbf,0xeb,0x6f,0xf7,0x6f,0xdf,0xdb,0x51,0xfd,0xbd,
-0xff,0x6f,0xff,0x6f,0xfb,0x5b,0xff,0xdb,0xff,0xf6,0xfe,0xf6,0xfd,0xfd,0xbf,0xfe,
-0xf7,0xff,0xd0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfa,0x50,0xff,0xff,0xff,
-0xf0,0x6f,0xff,0xff,0xf0,0x96,0xff,0xff,0xc6,0x2b,0xff,0xff,0xf1,0xfc,0xff,0xff,
-0xf7,0xdb,0xc3,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xc1,0x4f,0xc3,0xff,0xff,0xff,
-0xaf,0xf0,0x9f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,0xa0,0xff,0xff,0xff,0xf0,
-0x6f,0xff,0xff,0xf0,0x96,0xff,0xff,0xc6,0x2b,0xff,0xff,0xf1,0x5a,0xff,0xff,0xff,
-0xf3,0xc3,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xc1,0x4f,0xc3,0xff,0xff,0xff,0xff,
-0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfc,0xff,0xff,0x9f,0xf0,0x7f,
-0xff,0xf9,0xfc,0x4f,0xf3,0xff,0x27,0xeb,0xff,0xfc,0x81,0xfc,0x7f,0xfe,0x7b,0xff,
-0xf7,0xff,0x12,0x7f,0xff,0xff,0xff,0xff,0x18,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,
-0x7f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xff,0xdf,0xfe,0xff,0xfc,0x7e,0x7f,0xbf,
-0xff,0xff,0xaf,0xef,0xff,0xdf,0xdf,0xfb,0xff,0xf1,0xc3,0xfe,0x6f,0xf1,0xcf,0x3f,
-0xfb,0xff,0xff,0xcf,0xfe,0xff,0xff,0xfe,0x7f,0xbf,0xff,0xff,0xbf,0xfa,0xf0,0xdf,
-0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
-0x20,0x00,0x01,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x02,0x00,0x00,0x80,0x00,0x02,0x80,0x00,0x02,0x3c,0xf0,0x2f,0xff,
-0xff,0xff,0xfe,0xfd,0xbf,0xff,0xfb,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0xf1,0xff,0x7f,0xff,0xff,0xff,0xff,0xef,0xff,
-0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xf0,0x2f,0xff,0xff,
-0xff,0xfe,0xf0,0xff,0xff,0xff,0xfb,0xff,0xbf,0xff,0xff,0xff,0xff,0xf7,0xbf,0xfb,
-0xff,0xff,0xff,0xdf,0xf7,0xff,0xf1,0xf7,0xbf,0xfb,0xff,0xff,0xff,0x7f,0xde,0xff,
-0xff,0xff,0xff,0xff,0xff,0xed,0xf7,0xff,0xff,0x7f,0xd0,0xf0,0x3f,0xff,0xff,0xff,
-0xfe,0xf8,0x30,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x80,
-0x20,0x01,0x01,0x92,0x00,0x01,0x01,0x00,0xe0,0x1c,0x60,0x20,0x30,0x08,0x08,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xc1,0xf0,0x6f,0xff,0xff,0xff,0xfe,
-0xff,0xff,0xff,0xff,0xff,0xdb,0xfe,0xff,0xff,0xdf,0xff,0xfc,0x7f,0xfb,0xbf,0xff,
-0xff,0xff,0xff,0xff,0xf1,0xf6,0xff,0xf7,0x7e,0x3f,0xff,0x7f,0xff,0xff,0xff,0xf7,
-0xff,0xff,0xff,0xed,0xff,0xdf,0xff,0xb7,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,
-0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xbf,0xff,0xdf,
-0x57,0xef,0xf1,0xfd,0xfe,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xfb,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
-0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xdf,0xff,
-0xff,0xf1,0xfd,0xff,0x7f,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xfe,0xff,0xff,0xff,0xff,0xf0,0x9f,0xff,0xff,0xff,0xfe,0xf7,0xfd,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,0xff,0xff,
-0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,
-0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xfb,0xff,0xff,0xff,0xfe,0xff,0xff,0xfb,0x6f,0xff,0xfe,0xbf,0xff,0xf1,0xff,
-0xf7,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,
-0xff,0xff,0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xfb,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0x57,0xff,0xfd,0xbf,0xff,0xf1,0xff,0xef,
-0xfe,0xff,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,
-0xde,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf7,0xdb,0xff,0xdb,0xfd,
-0xf6,0xff,0xf6,0xff,0x3c,0xbc,0xbc,0xbf,0xdf,0x6f,0xe7,0x2f,0xf1,0x3c,0xbf,0xfd,
-0xbf,0xdf,0x6f,0xff,0x6f,0xf7,0xdb,0xff,0xdb,0xfd,0xf6,0xff,0xf6,0xff,0xff,0xff,
-0x02,0x01,0xdf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff };
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 6fd7aa61736e..a815e17a0ab4 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -134,7 +134,7 @@ static inline void emac_report_timeout_error(struct emac_instance *dev,
EMAC_FTR_440EP_PHY_CLK_FIX))
DBG(dev, "%s" NL, error);
else if (net_ratelimit())
- printk(KERN_ERR "%s: %s\n", dev->ndev->name, error);
+ printk(KERN_ERR "%s: %s\n", dev->ofdev->node->full_name, error);
}
/* EMAC PHY clock workaround:
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
index 5b5bf9f9861a..c25bc0bc0b25 100644
--- a/drivers/net/ibmlana.c
+++ b/drivers/net/ibmlana.c
@@ -905,6 +905,17 @@ static char *ibmlana_adapter_names[] __devinitdata = {
NULL
};
+
+static const struct net_device_ops ibmlana_netdev_ops = {
+ .ndo_open = ibmlana_open,
+ .ndo_stop = ibmlana_close,
+ .ndo_start_xmit = ibmlana_tx,
+ .ndo_set_multicast_list = ibmlana_set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __devinit ibmlana_init_one(struct device *kdev)
{
struct mca_device *mdev = to_mca_device(kdev);
@@ -973,11 +984,7 @@ static int __devinit ibmlana_init_one(struct device *kdev)
mca_device_set_claim(mdev, 1);
/* set methods */
-
- dev->open = ibmlana_open;
- dev->stop = ibmlana_close;
- dev->hard_start_xmit = ibmlana_tx;
- dev->set_multicast_list = ibmlana_set_multicast_list;
+ dev->netdev_ops = &ibmlana_netdev_ops;
dev->flags |= IFF_MULTICAST;
/* copy out MAC address */
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index dfa6348ac1dc..5c6315df86b9 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -1028,10 +1028,10 @@ static int ibmveth_poll(struct napi_struct *napi, int budget)
ibmveth_assert(lpar_rc == H_SUCCESS);
- netif_rx_complete(napi);
+ napi_complete(napi);
if (ibmveth_rxq_pending_buffer(adapter) &&
- netif_rx_reschedule(napi)) {
+ napi_reschedule(napi)) {
lpar_rc = h_vio_signal(adapter->vdev->unit_address,
VIO_IRQ_DISABLE);
goto restart_poll;
@@ -1047,11 +1047,11 @@ static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance)
struct ibmveth_adapter *adapter = netdev_priv(netdev);
unsigned long lpar_rc;
- if (netif_rx_schedule_prep(&adapter->napi)) {
+ if (napi_schedule_prep(&adapter->napi)) {
lpar_rc = h_vio_signal(adapter->vdev->unit_address,
VIO_IRQ_DISABLE);
ibmveth_assert(lpar_rc == H_SUCCESS);
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
}
return IRQ_HANDLED;
}
diff --git a/drivers/net/igb/Makefile b/drivers/net/igb/Makefile
index 1927b3fd6f05..8372cb9a8c1a 100644
--- a/drivers/net/igb/Makefile
+++ b/drivers/net/igb/Makefile
@@ -1,7 +1,7 @@
################################################################################
#
# Intel 82575 PCI-Express Ethernet Linux driver
-# Copyright(c) 1999 - 2007 Intel Corporation.
+# Copyright(c) 1999 - 2009 Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
@@ -33,5 +33,5 @@
obj-$(CONFIG_IGB) += igb.o
igb-objs := igb_main.o igb_ethtool.o e1000_82575.o \
- e1000_mac.o e1000_nvm.o e1000_phy.o
+ e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 13ca73f96ec6..efd9be214885 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 - 2008 Intel Corporation.
+ Copyright(c) 2007-2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -62,17 +62,12 @@ static bool igb_sgmii_active_82575(struct e1000_hw *);
static s32 igb_reset_init_script_82575(struct e1000_hw *);
static s32 igb_read_mac_addr_82575(struct e1000_hw *);
-
-struct e1000_dev_spec_82575 {
- bool sgmii_active;
-};
-
static s32 igb_get_invariants_82575(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
struct e1000_nvm_info *nvm = &hw->nvm;
struct e1000_mac_info *mac = &hw->mac;
- struct e1000_dev_spec_82575 *dev_spec;
+ struct e1000_dev_spec_82575 * dev_spec = &hw->dev_spec._82575;
u32 eecd;
s32 ret_val;
u16 size;
@@ -85,8 +80,10 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
mac->type = e1000_82575;
break;
case E1000_DEV_ID_82576:
+ case E1000_DEV_ID_82576_NS:
case E1000_DEV_ID_82576_FIBER:
case E1000_DEV_ID_82576_SERDES:
+ case E1000_DEV_ID_82576_QUAD_COPPER:
mac->type = e1000_82576;
break;
default:
@@ -94,17 +91,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
break;
}
- /* MAC initialization */
- hw->dev_spec_size = sizeof(struct e1000_dev_spec_82575);
-
- /* Device-specific structure allocation */
- hw->dev_spec = kzalloc(hw->dev_spec_size, GFP_KERNEL);
-
- if (!hw->dev_spec)
- return -ENOMEM;
-
- dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
-
/* Set media type */
/*
* The 82575 uses bits 22:23 for link mode. The mode can be changed
@@ -195,13 +181,13 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
/* PHY function pointers */
if (igb_sgmii_active_82575(hw)) {
- phy->ops.reset_phy = igb_phy_hw_reset_sgmii_82575;
- phy->ops.read_phy_reg = igb_read_phy_reg_sgmii_82575;
- phy->ops.write_phy_reg = igb_write_phy_reg_sgmii_82575;
+ phy->ops.reset = igb_phy_hw_reset_sgmii_82575;
+ phy->ops.read_reg = igb_read_phy_reg_sgmii_82575;
+ phy->ops.write_reg = igb_write_phy_reg_sgmii_82575;
} else {
- phy->ops.reset_phy = igb_phy_hw_reset;
- phy->ops.read_phy_reg = igb_read_phy_reg_igp;
- phy->ops.write_phy_reg = igb_write_phy_reg_igp;
+ phy->ops.reset = igb_phy_hw_reset;
+ phy->ops.read_reg = igb_read_phy_reg_igp;
+ phy->ops.write_reg = igb_write_phy_reg_igp;
}
/* Set phy->phy_addr and phy->id. */
@@ -229,6 +215,10 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
return -E1000_ERR_PHY;
}
+ /* if 82576 then initialize mailbox parameters */
+ if (mac->type == e1000_82576)
+ igb_init_mbx_params_pf(hw);
+
return 0;
}
@@ -451,7 +441,7 @@ static s32 igb_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
* SFP documentation requires the following to configure the SPF module
* to work on SGMII. No further documentation is given.
*/
- ret_val = hw->phy.ops.write_phy_reg(hw, 0x1B, 0x8084);
+ ret_val = hw->phy.ops.write_reg(hw, 0x1B, 0x8084);
if (ret_val)
goto out;
@@ -480,28 +470,28 @@ static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
s32 ret_val;
u16 data;
- ret_val = phy->ops.read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
+ ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
if (ret_val)
goto out;
if (active) {
data |= IGP02E1000_PM_D0_LPLU;
- ret_val = phy->ops.write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+ ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data);
if (ret_val)
goto out;
/* When LPLU is enabled, we should disable SmartSpeed */
- ret_val = phy->ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&data);
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = phy->ops.write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
+ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
goto out;
} else {
data &= ~IGP02E1000_PM_D0_LPLU;
- ret_val = phy->ops.write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+ ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data);
/*
* LPLU and SmartSpeed are mutually exclusive. LPLU is used
@@ -510,24 +500,24 @@ static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
* SmartSpeed, so performance is maintained.
*/
if (phy->smart_speed == e1000_smart_speed_on) {
- ret_val = phy->ops.read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG, &data);
if (ret_val)
goto out;
data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = phy->ops.write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG, data);
if (ret_val)
goto out;
} else if (phy->smart_speed == e1000_smart_speed_off) {
- ret_val = phy->ops.read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG, &data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = phy->ops.write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG, data);
if (ret_val)
goto out;
@@ -803,7 +793,7 @@ static void igb_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
}
/**
- * igb_update_mc_addr_list_82575 - Update Multicast addresses
+ * igb_update_mc_addr_list - Update Multicast addresses
* @hw: pointer to the HW structure
* @mc_addr_list: array of multicast addresses to program
* @mc_addr_count: number of multicast addresses to program
@@ -815,9 +805,9 @@ static void igb_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
* The parameter rar_count will usually be hw->mac.rar_entry_count
* unless there are workarounds that change this.
**/
-void igb_update_mc_addr_list_82575(struct e1000_hw *hw,
- u8 *mc_addr_list, u32 mc_addr_count,
- u32 rar_used_count, u32 rar_count)
+void igb_update_mc_addr_list(struct e1000_hw *hw,
+ u8 *mc_addr_list, u32 mc_addr_count,
+ u32 rar_used_count, u32 rar_count)
{
u32 hash_value;
u32 i;
@@ -1051,7 +1041,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
* depending on user settings.
*/
hw_dbg("Forcing Speed and Duplex\n");
- ret_val = igb_phy_force_speed_duplex(hw);
+ ret_val = hw->phy.ops.force_speed_duplex(hw);
if (ret_val) {
hw_dbg("Error Forcing Speed and Duplex\n");
goto out;
@@ -1110,6 +1100,13 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
E1000_CTRL_SWDPIN1;
wr32(E1000_CTRL, reg);
+ /* Power on phy for 82576 fiber adapters */
+ if (hw->mac.type == e1000_82576) {
+ reg = rd32(E1000_CTRL_EXT);
+ reg &= ~E1000_CTRL_EXT_SDP7_DATA;
+ wr32(E1000_CTRL_EXT, reg);
+ }
+
/* Set switch control to serdes energy detect */
reg = rd32(E1000_CONNSW);
reg |= E1000_CONNSW_ENRGSRC;
@@ -1227,20 +1224,12 @@ out:
**/
static bool igb_sgmii_active_82575(struct e1000_hw *hw)
{
- struct e1000_dev_spec_82575 *dev_spec;
- bool ret_val;
-
- if (hw->mac.type != e1000_82575) {
- ret_val = false;
- goto out;
- }
-
- dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
+ struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
- ret_val = dev_spec->sgmii_active;
+ if (hw->mac.type != e1000_82575 && hw->mac.type != e1000_82576)
+ return false;
-out:
- return ret_val;
+ return dev_spec->sgmii_active;
}
/**
@@ -1430,6 +1419,44 @@ void igb_rx_fifo_flush_82575(struct e1000_hw *hw)
rd32(E1000_MPC);
}
+/**
+ * igb_vmdq_set_loopback_pf - enable or disable vmdq loopback
+ * @hw: pointer to the hardware struct
+ * @enable: state to enter, either enabled or disabled
+ *
+ * enables/disables L2 switch loopback functionality.
+ **/
+void igb_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
+{
+ u32 dtxswc = rd32(E1000_DTXSWC);
+
+ if (enable)
+ dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
+ else
+ dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
+
+ wr32(E1000_DTXSWC, dtxswc);
+}
+
+/**
+ * igb_vmdq_set_replication_pf - enable or disable vmdq replication
+ * @hw: pointer to the hardware struct
+ * @enable: state to enter, either enabled or disabled
+ *
+ * enables/disables replication of packets across multiple pools.
+ **/
+void igb_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
+{
+ u32 vt_ctl = rd32(E1000_VT_CTL);
+
+ if (enable)
+ vt_ctl |= E1000_VT_CTL_VM_REPL_EN;
+ else
+ vt_ctl &= ~E1000_VT_CTL_VM_REPL_EN;
+
+ wr32(E1000_VT_CTL, vt_ctl);
+}
+
static struct e1000_mac_operations e1000_mac_ops_82575 = {
.reset_hw = igb_reset_hw_82575,
.init_hw = igb_init_hw_82575,
@@ -1440,16 +1467,16 @@ static struct e1000_mac_operations e1000_mac_ops_82575 = {
};
static struct e1000_phy_operations e1000_phy_ops_82575 = {
- .acquire_phy = igb_acquire_phy_82575,
+ .acquire = igb_acquire_phy_82575,
.get_cfg_done = igb_get_cfg_done_82575,
- .release_phy = igb_release_phy_82575,
+ .release = igb_release_phy_82575,
};
static struct e1000_nvm_operations e1000_nvm_ops_82575 = {
- .acquire_nvm = igb_acquire_nvm_82575,
- .read_nvm = igb_read_nvm_eerd,
- .release_nvm = igb_release_nvm_82575,
- .write_nvm = igb_write_nvm_spi,
+ .acquire = igb_acquire_nvm_82575,
+ .read = igb_read_nvm_eerd,
+ .release = igb_release_nvm_82575,
+ .write = igb_write_nvm_spi,
};
const struct e1000_info e1000_82575_info = {
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index c1928b5efe1f..eaf977050368 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 - 2008 Intel Corporation.
+ Copyright(c) 2007-2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -28,7 +28,7 @@
#ifndef _E1000_82575_H_
#define _E1000_82575_H_
-void igb_update_mc_addr_list_82575(struct e1000_hw*, u8*, u32, u32, u32);
+void igb_update_mc_addr_list(struct e1000_hw*, u8*, u32, u32, u32);
extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
@@ -40,8 +40,11 @@ extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
+#define E1000_SRRCTL_DROP_EN 0x80000000
#define E1000_MRQC_ENABLE_RSS_4Q 0x00000002
+#define E1000_MRQC_ENABLE_VMDQ 0x00000003
+#define E1000_MRQC_ENABLE_VMDQ_RSS_2Q 0x00000005
#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
@@ -58,9 +61,6 @@ extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
E1000_EICR_RX_QUEUE2 | \
E1000_EICR_RX_QUEUE3)
-#define E1000_EIMS_RX_QUEUE E1000_EICR_RX_QUEUE
-#define E1000_EIMS_TX_QUEUE E1000_EICR_TX_QUEUE
-
/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
/* Receive Descriptor - Advanced */
@@ -95,12 +95,6 @@ union e1000_adv_rx_desc {
#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0
#define E1000_RXDADV_HDRBUFLEN_SHIFT 5
-/* RSS Hash results */
-
-/* RSS Packet Types as indicated in the receive descriptor */
-#define E1000_RXDADV_PKTTYPE_IPV4 0x00000010 /* IPV4 hdr present */
-#define E1000_RXDADV_PKTTYPE_TCP 0x00000100 /* TCP hdr present */
-
/* Transmit Descriptor - Advanced */
union e1000_adv_tx_desc {
struct {
@@ -116,6 +110,7 @@ union e1000_adv_tx_desc {
};
/* Adv Transmit Descriptor Config Masks */
+#define E1000_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp packet */
#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
@@ -149,11 +144,8 @@ struct e1000_adv_tx_context_desc {
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
/* Direct Cache Access (DCA) definitions */
-#define E1000_DCA_CTRL_DCA_ENABLE 0x00000000 /* DCA Enable */
-#define E1000_DCA_CTRL_DCA_DISABLE 0x00000001 /* DCA Disable */
-
-#define E1000_DCA_CTRL_DCA_MODE_CB1 0x00 /* DCA Mode CB1 */
-#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
+#define E1000_DCA_CTRL_DCA_MODE_DISABLE 0x01 /* DCA Disable */
+#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
#define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
#define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
@@ -170,4 +162,44 @@ struct e1000_adv_tx_context_desc {
#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */
+#define MAX_NUM_VFS 8
+
+#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */
+
+/* Easy defines for setting default pool, would normally be left a zero */
+#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7
+#define E1000_VT_CTL_DEFAULT_POOL_MASK (0x7 << E1000_VT_CTL_DEFAULT_POOL_SHIFT)
+
+/* Other useful VMD_CTL register defines */
+#define E1000_VT_CTL_IGNORE_MAC (1 << 28)
+#define E1000_VT_CTL_DISABLE_DEF_POOL (1 << 29)
+#define E1000_VT_CTL_VM_REPL_EN (1 << 30)
+
+/* Per VM Offload register setup */
+#define E1000_VMOLR_RLPML_MASK 0x00003FFF /* Long Packet Maximum Length mask */
+#define E1000_VMOLR_LPE 0x00010000 /* Accept Long packet */
+#define E1000_VMOLR_RSSE 0x00020000 /* Enable RSS */
+#define E1000_VMOLR_AUPE 0x01000000 /* Accept untagged packets */
+#define E1000_VMOLR_ROMPE 0x02000000 /* Accept overflow multicast */
+#define E1000_VMOLR_ROPE 0x04000000 /* Accept overflow unicast */
+#define E1000_VMOLR_BAM 0x08000000 /* Accept Broadcast packets */
+#define E1000_VMOLR_MPME 0x10000000 /* Multicast promiscuous mode */
+#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
+#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */
+
+#define E1000_VLVF_ARRAY_SIZE 32
+#define E1000_VLVF_VLANID_MASK 0x00000FFF
+#define E1000_VLVF_POOLSEL_SHIFT 12
+#define E1000_VLVF_POOLSEL_MASK (0xFF << E1000_VLVF_POOLSEL_SHIFT)
+#define E1000_VLVF_LVLAN 0x00100000
+#define E1000_VLVF_VLANID_ENABLE 0x80000000
+
+#define E1000_IOVCTL 0x05BBC
+#define E1000_IOVCTL_REUSE_VFQ 0x00000001
+
+#define ALL_QUEUES 0xFFFF
+
+void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool);
+void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
+
#endif
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index 40d03426c122..ad2d319d0f8b 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 - 2008 Intel Corporation.
+ Copyright(c) 2007-2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -42,33 +42,11 @@
#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */
#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
-#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
-#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
-#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
-#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
-#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
-#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
-#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
-#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
-
-/* Wake Up Status */
-
-/* Wake Up Packet Length */
-
-/* Four Flexible Filters are supported */
-#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
-
-/* Each Flexible Filter is at most 128 (0x80) bytes in length */
-#define E1000_FLEXIBLE_FILTER_SIZE_MAX 128
-
/* Extended Device Control */
-#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */
-#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Defineable Pin 4 */
-#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Defineable Pin 5 */
#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
-#define E1000_CTRL_EXT_SDP4_DIR 0x00000100 /* Direction of SDP4 0=in 1=out */
-#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
+/* Physical Func Reset Done Indication */
+#define E1000_CTRL_EXT_PFRSTD 0x00004000
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
@@ -103,13 +81,7 @@
#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
-#define E1000_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */
-#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
-#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
-#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
-#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */
-#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
-#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
+#define E1000_RXD_STAT_TS 0x10000 /* Pkt was time stamped */
#define E1000_RXDEXT_STATERR_CE 0x01000000
#define E1000_RXDEXT_STATERR_SE 0x02000000
@@ -119,14 +91,6 @@
#define E1000_RXDEXT_STATERR_IPE 0x40000000
#define E1000_RXDEXT_STATERR_RXE 0x80000000
-/* mask to determine if packets should be dropped due to frame errors */
-#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
- E1000_RXD_ERR_CE | \
- E1000_RXD_ERR_SE | \
- E1000_RXD_ERR_SEQ | \
- E1000_RXD_ERR_CXE | \
- E1000_RXD_ERR_RXE)
-
/* Same mask, but for extended and packet split descriptors */
#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
E1000_RXDEXT_STATERR_CE | \
@@ -145,16 +109,11 @@
/* Management Control */
#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
-#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
/* Enable Neighbor Discovery Filtering */
#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
/* Enable MAC address filtering */
#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000
-/* Enable MNG packets to host memory */
-#define E1000_MANC_EN_MNG2HOST 0x00200000
-/* Enable IP address filtering */
-
/* Receive Control */
#define E1000_RCTL_EN 0x00000002 /* enable */
@@ -162,14 +121,11 @@
#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
-#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
-#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */
-#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */
#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */
#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */
#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
@@ -226,11 +182,7 @@
/* enable link status from external LINK_0 and LINK_1 pins */
#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
-#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
-#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */
#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
-#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */
-#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */
#define E1000_CTRL_RST 0x04000000 /* Global reset */
#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
@@ -308,9 +260,7 @@
#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX
/* LED Control */
-#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
#define E1000_LEDCTL_LED0_MODE_SHIFT 0
-#define E1000_LEDCTL_LED0_IVRT 0x00000040
#define E1000_LEDCTL_LED0_BLINK 0x00000080
#define E1000_LEDCTL_MODE_LED_ON 0xE
@@ -357,12 +307,7 @@
#define MAX_JUMBO_FRAME_SIZE 0x3F00
-/* Extended Configuration Control and Size */
-#define E1000_PHY_CTRL_GBE_DISABLE 0x00000040
-
/* PBA constants */
-#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
-#define E1000_PBA_24K 0x0018
#define E1000_PBA_34K 0x0022
#define E1000_PBA_64K 0x0040 /* 64KB */
@@ -378,41 +323,15 @@
/* Interrupt Cause Read */
#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
-#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */
#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
-#define E1000_ICR_RXO 0x00000040 /* rx overrun */
#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
-#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
-#define E1000_ICR_RXCFG 0x00000400 /* Rx /c/ ordered set */
-#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
-#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
-#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
-#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
-#define E1000_ICR_TXD_LOW 0x00008000
-#define E1000_ICR_SRPD 0x00010000
-#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */
-#define E1000_ICR_MNG 0x00040000 /* Manageability event */
-#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */
+#define E1000_ICR_VMMB 0x00000100 /* VM MB event */
/* If this bit asserted, the driver should claim the interrupt */
#define E1000_ICR_INT_ASSERTED 0x80000000
-/* queue 0 Rx descriptor FIFO parity error */
-#define E1000_ICR_RXD_FIFO_PAR0 0x00100000
-/* queue 0 Tx descriptor FIFO parity error */
-#define E1000_ICR_TXD_FIFO_PAR0 0x00200000
-/* host arb read buffer parity error */
-#define E1000_ICR_HOST_ARB_PAR 0x00400000
-#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */
-/* queue 1 Rx descriptor FIFO parity error */
-#define E1000_ICR_RXD_FIFO_PAR1 0x01000000
-/* queue 1 Tx descriptor FIFO parity error */
-#define E1000_ICR_TXD_FIFO_PAR1 0x02000000
-/* FW changed the status of DISSW bit in the FWSM */
-#define E1000_ICR_DSW 0x00000020
/* LAN connected device generates an interrupt */
-#define E1000_ICR_PHYINT 0x00001000
-#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */
+#define E1000_ICR_DOUTSYNC 0x10000000 /* NIC DMA out of sync */
/* Extended Interrupt Cause Read */
#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */
@@ -423,7 +342,6 @@
#define E1000_EICR_TX_QUEUE1 0x00000200 /* Tx Queue 1 Interrupt */
#define E1000_EICR_TX_QUEUE2 0x00000400 /* Tx Queue 2 Interrupt */
#define E1000_EICR_TX_QUEUE3 0x00000800 /* Tx Queue 3 Interrupt */
-#define E1000_EICR_TCP_TIMER 0x40000000 /* TCP Timer */
#define E1000_EICR_OTHER 0x80000000 /* Interrupt Cause Active */
/* TCP Timer */
@@ -441,17 +359,19 @@
E1000_IMS_TXDW | \
E1000_IMS_RXDMT0 | \
E1000_IMS_RXSEQ | \
- E1000_IMS_LSC)
+ E1000_IMS_LSC | \
+ E1000_IMS_DOUTSYNC)
/* Interrupt Mask Set */
#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
+#define E1000_IMS_VMMB E1000_ICR_VMMB /* Mail box activity */
#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
+#define E1000_IMS_DOUTSYNC E1000_ICR_DOUTSYNC /* NIC DMA out of sync */
/* Extended Interrupt Mask Set */
-#define E1000_EIMS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */
#define E1000_EIMS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */
/* Interrupt Cause Set */
@@ -481,6 +401,10 @@
* manageability enabled, allowing us room for 15 multicast addresses.
*/
#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
+#define E1000_RAL_MAC_ADDR_LEN 4
+#define E1000_RAH_MAC_ADDR_LEN 2
+#define E1000_RAH_POOL_MASK 0x03FC0000
+#define E1000_RAH_POOL_1 0x00040000
/* Error Codes */
#define E1000_ERR_NVM 1
@@ -490,10 +414,10 @@
#define E1000_ERR_MAC_INIT 5
#define E1000_ERR_RESET 9
#define E1000_ERR_MASTER_REQUESTS_PENDING 10
-#define E1000_ERR_HOST_INTERFACE_COMMAND 11
#define E1000_BLK_PHY_RESET 12
#define E1000_ERR_SWFW_SYNC 13
#define E1000_NOT_IMPLEMENTED 14
+#define E1000_ERR_MBX 15
/* Loop limit on how long we wait for auto-negotiation to complete */
#define COPPER_LINK_UP_LIMIT 10
@@ -510,30 +434,9 @@
/* Flow Control */
#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
-/* Transmit Configuration Word */
-#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */
-
-/* Receive Configuration Word */
-
-/* PCI Express Control */
-#define E1000_GCR_RXD_NO_SNOOP 0x00000001
-#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002
-#define E1000_GCR_RXDSCR_NO_SNOOP 0x00000004
-#define E1000_GCR_TXD_NO_SNOOP 0x00000008
-#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010
-#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020
-
-#define PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \
- E1000_GCR_RXDSCW_NO_SNOOP | \
- E1000_GCR_RXDSCR_NO_SNOOP | \
- E1000_GCR_TXD_NO_SNOOP | \
- E1000_GCR_TXDSCW_NO_SNOOP | \
- E1000_GCR_TXDSCR_NO_SNOOP)
-
/* PHY Control Register */
#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
-#define MII_CR_POWER_DOWN 0x0800 /* Power down */
#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
@@ -609,6 +512,7 @@
#define NVM_ID_LED_SETTINGS 0x0004
/* For SERDES output amplitude adjustment. */
#define NVM_INIT_CONTROL2_REG 0x000F
+#define NVM_INIT_CONTROL3_PORT_B 0x0014
#define NVM_INIT_CONTROL3_PORT_A 0x0024
#define NVM_ALT_MAC_ADDR_PTR 0x0037
#define NVM_CHECKSUM_REG 0x003F
@@ -663,10 +567,8 @@
#define IGP_LED3_MODE 0x07000000
/* PCI/PCI-X/PCI-EX Config space */
-#define PCI_HEADER_TYPE_REGISTER 0x0E
#define PCIE_LINK_STATUS 0x12
-#define PCI_HEADER_TYPE_MULTIFUNC 0x80
#define PCIE_LINK_WIDTH_MASK 0x3F0
#define PCIE_LINK_WIDTH_SHIFT 4
@@ -763,4 +665,8 @@
#define E1000_GEN_CTL_ADDRESS_SHIFT 8
#define E1000_GEN_POLL_TIMEOUT 640
+#define E1000_VFTA_ENTRY_SHIFT 5
+#define E1000_VFTA_ENTRY_MASK 0x7F
+#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
+
#endif
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 99504a600a80..68aac20c31ca 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -32,7 +32,6 @@
#include <linux/delay.h>
#include <linux/io.h>
-#include "e1000_mac.h"
#include "e1000_regs.h"
#include "e1000_defines.h"
@@ -41,6 +40,8 @@ struct e1000_hw;
#define E1000_DEV_ID_82576 0x10C9
#define E1000_DEV_ID_82576_FIBER 0x10E6
#define E1000_DEV_ID_82576_SERDES 0x10E7
+#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
+#define E1000_DEV_ID_82576_NS 0x150A
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
@@ -144,144 +145,6 @@ enum e1000_fc_type {
e1000_fc_default = 0xFF
};
-
-/* Receive Descriptor */
-struct e1000_rx_desc {
- __le64 buffer_addr; /* Address of the descriptor's data buffer */
- __le16 length; /* Length of data DMAed into data buffer */
- __le16 csum; /* Packet checksum */
- u8 status; /* Descriptor status */
- u8 errors; /* Descriptor Errors */
- __le16 special;
-};
-
-/* Receive Descriptor - Extended */
-union e1000_rx_desc_extended {
- struct {
- __le64 buffer_addr;
- __le64 reserved;
- } read;
- struct {
- struct {
- __le32 mrq; /* Multiple Rx Queues */
- union {
- __le32 rss; /* RSS Hash */
- struct {
- __le16 ip_id; /* IP id */
- __le16 csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- __le32 status_error; /* ext status/error */
- __le16 length;
- __le16 vlan; /* VLAN tag */
- } upper;
- } wb; /* writeback */
-};
-
-#define MAX_PS_BUFFERS 4
-/* Receive Descriptor - Packet Split */
-union e1000_rx_desc_packet_split {
- struct {
- /* one buffer for protocol header(s), three data buffers */
- __le64 buffer_addr[MAX_PS_BUFFERS];
- } read;
- struct {
- struct {
- __le32 mrq; /* Multiple Rx Queues */
- union {
- __le32 rss; /* RSS Hash */
- struct {
- __le16 ip_id; /* IP id */
- __le16 csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- __le32 status_error; /* ext status/error */
- __le16 length0; /* length of buffer 0 */
- __le16 vlan; /* VLAN tag */
- } middle;
- struct {
- __le16 header_status;
- __le16 length[3]; /* length of buffers 1-3 */
- } upper;
- __le64 reserved;
- } wb; /* writeback */
-};
-
-/* Transmit Descriptor */
-struct e1000_tx_desc {
- __le64 buffer_addr; /* Address of the descriptor's data buffer */
- union {
- __le32 data;
- struct {
- __le16 length; /* Data buffer length */
- u8 cso; /* Checksum offset */
- u8 cmd; /* Descriptor control */
- } flags;
- } lower;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 css; /* Checksum start */
- __le16 special;
- } fields;
- } upper;
-};
-
-/* Offload Context Descriptor */
-struct e1000_context_desc {
- union {
- __le32 ip_config;
- struct {
- u8 ipcss; /* IP checksum start */
- u8 ipcso; /* IP checksum offset */
- __le16 ipcse; /* IP checksum end */
- } ip_fields;
- } lower_setup;
- union {
- __le32 tcp_config;
- struct {
- u8 tucss; /* TCP checksum start */
- u8 tucso; /* TCP checksum offset */
- __le16 tucse; /* TCP checksum end */
- } tcp_fields;
- } upper_setup;
- __le32 cmd_and_length;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 hdr_len; /* Header length */
- __le16 mss; /* Maximum segment size */
- } fields;
- } tcp_seg_setup;
-};
-
-/* Offload data descriptor */
-struct e1000_data_desc {
- __le64 buffer_addr; /* Address of the descriptor's buffer address */
- union {
- __le32 data;
- struct {
- __le16 length; /* Data buffer length */
- u8 typ_len_ext;
- u8 cmd;
- } flags;
- } lower;
- union {
- __le32 data;
- struct {
- u8 status; /* Descriptor status */
- u8 popts; /* Packet Options */
- __le16 special;
- } fields;
- } upper;
-};
-
/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
u64 crcerrs;
@@ -359,6 +222,7 @@ struct e1000_hw_stats {
u64 lenerrs;
u64 scvpc;
u64 hrmpc;
+ u64 doosync;
};
struct e1000_phy_stats {
@@ -409,6 +273,7 @@ struct e1000_host_mng_command_info {
#include "e1000_mac.h"
#include "e1000_phy.h"
#include "e1000_nvm.h"
+#include "e1000_mbx.h"
struct e1000_mac_operations {
s32 (*check_for_link)(struct e1000_hw *);
@@ -422,25 +287,25 @@ struct e1000_mac_operations {
};
struct e1000_phy_operations {
- s32 (*acquire_phy)(struct e1000_hw *);
+ s32 (*acquire)(struct e1000_hw *);
s32 (*check_reset_block)(struct e1000_hw *);
s32 (*force_speed_duplex)(struct e1000_hw *);
s32 (*get_cfg_done)(struct e1000_hw *hw);
s32 (*get_cable_length)(struct e1000_hw *);
s32 (*get_phy_info)(struct e1000_hw *);
- s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *);
- void (*release_phy)(struct e1000_hw *);
- s32 (*reset_phy)(struct e1000_hw *);
+ s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
+ void (*release)(struct e1000_hw *);
+ s32 (*reset)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
- s32 (*write_phy_reg)(struct e1000_hw *, u32, u16);
+ s32 (*write_reg)(struct e1000_hw *, u32, u16);
};
struct e1000_nvm_operations {
- s32 (*acquire_nvm)(struct e1000_hw *);
- s32 (*read_nvm)(struct e1000_hw *, u16, u16, u16 *);
- void (*release_nvm)(struct e1000_hw *);
- s32 (*write_nvm)(struct e1000_hw *, u16, u16, u16 *);
+ s32 (*acquire)(struct e1000_hw *);
+ s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
+ void (*release)(struct e1000_hw *);
+ s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
};
struct e1000_info {
@@ -483,7 +348,6 @@ struct e1000_mac_info {
bool asf_firmware_present;
bool autoneg;
bool autoneg_failed;
- bool disable_av;
bool disable_hw_init_bits;
bool get_link_status;
bool ifs_params_forced;
@@ -565,9 +429,40 @@ struct e1000_fc_info {
enum e1000_fc_type original_type;
};
+struct e1000_mbx_operations {
+ s32 (*init_params)(struct e1000_hw *hw);
+ s32 (*read)(struct e1000_hw *, u32 *, u16, u16);
+ s32 (*write)(struct e1000_hw *, u32 *, u16, u16);
+ s32 (*read_posted)(struct e1000_hw *, u32 *, u16, u16);
+ s32 (*write_posted)(struct e1000_hw *, u32 *, u16, u16);
+ s32 (*check_for_msg)(struct e1000_hw *, u16);
+ s32 (*check_for_ack)(struct e1000_hw *, u16);
+ s32 (*check_for_rst)(struct e1000_hw *, u16);
+};
+
+struct e1000_mbx_stats {
+ u32 msgs_tx;
+ u32 msgs_rx;
+
+ u32 acks;
+ u32 reqs;
+ u32 rsts;
+};
+
+struct e1000_mbx_info {
+ struct e1000_mbx_operations ops;
+ struct e1000_mbx_stats stats;
+ u32 timeout;
+ u32 usec_delay;
+ u16 size;
+};
+
+struct e1000_dev_spec_82575 {
+ bool sgmii_active;
+};
+
struct e1000_hw {
void *back;
- void *dev_spec;
u8 __iomem *hw_addr;
u8 __iomem *flash_address;
@@ -578,9 +473,12 @@ struct e1000_hw {
struct e1000_phy_info phy;
struct e1000_nvm_info nvm;
struct e1000_bus_info bus;
+ struct e1000_mbx_info mbx;
struct e1000_host_mng_dhcp_cookie mng_cookie;
- u32 dev_spec_size;
+ union {
+ struct e1000_dev_spec_82575 _82575;
+ } dev_spec;
u16 device_id;
u16 subsystem_vendor_id;
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 97f0049a5d6b..f4c315b5a900 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -37,19 +37,6 @@
static s32 igb_set_default_fc(struct e1000_hw *hw);
static s32 igb_set_fc_watermarks(struct e1000_hw *hw);
-/**
- * igb_remove_device - Free device specific structure
- * @hw: pointer to the HW structure
- *
- * If a device specific structure was allocated, this function will
- * free it.
- **/
-void igb_remove_device(struct e1000_hw *hw)
-{
- /* Freeing the dev_spec member of e1000_hw structure */
- kfree(hw->dev_spec);
-}
-
static s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
{
struct igb_adapter *adapter = hw->back;
@@ -131,6 +118,37 @@ void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
}
/**
+ * igb_vfta_set - enable or disable vlan in VLAN filter table
+ * @hw: pointer to the HW structure
+ * @vid: VLAN id to add or remove
+ * @add: if true add filter, if false remove
+ *
+ * Sets or clears a bit in the VLAN filter table array based on VLAN id
+ * and if we are adding or removing the filter
+ **/
+s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add)
+{
+ u32 index = (vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK;
+ u32 mask = 1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
+ u32 vfta = array_rd32(E1000_VFTA, index);
+ s32 ret_val = 0;
+
+ /* bit was set/cleared before we started */
+ if ((!!(vfta & mask)) == add) {
+ ret_val = -E1000_ERR_CONFIG;
+ } else {
+ if (add)
+ vfta |= mask;
+ else
+ vfta &= ~mask;
+ }
+
+ igb_write_vfta(hw, index, vfta);
+
+ return ret_val;
+}
+
+/**
* igb_check_alt_mac_addr - Check for alternate MAC addr
* @hw: pointer to the HW structure
*
@@ -148,7 +166,7 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw)
u16 offset, nvm_alt_mac_addr_offset, nvm_data;
u8 alt_mac_addr[ETH_ALEN];
- ret_val = hw->nvm.ops.read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
+ ret_val = hw->nvm.ops.read(hw, NVM_ALT_MAC_ADDR_PTR, 1,
&nvm_alt_mac_addr_offset);
if (ret_val) {
hw_dbg("NVM Read Error\n");
@@ -165,7 +183,7 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw)
for (i = 0; i < ETH_ALEN; i += 2) {
offset = nvm_alt_mac_addr_offset + (i >> 1);
- ret_val = hw->nvm.ops.read_nvm(hw, offset, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
@@ -213,7 +231,8 @@ void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
- if (!hw->mac.disable_av)
+ /* If MAC address zero, no need to set the AV bit */
+ if (rar_low || rar_high)
rar_high |= E1000_RAH_AV;
wr32(E1000_RAL(index), rar_low);
@@ -588,8 +607,7 @@ static s32 igb_set_default_fc(struct e1000_hw *hw)
* control setting, then the variable hw->fc will
* be initialized based on a value in the EEPROM.
*/
- ret_val = hw->nvm.ops.read_nvm(hw, NVM_INIT_CONTROL2_REG, 1,
- &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
@@ -720,11 +738,11 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
* has completed. We read this twice because this reg has
* some "sticky" (latched) bits.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS,
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
&mii_status_reg);
if (ret_val)
goto out;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS,
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
&mii_status_reg);
if (ret_val)
goto out;
@@ -742,11 +760,11 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
* Page Ability Register (Address 5) to determine how
* flow control was negotiated.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_AUTONEG_ADV,
+ ret_val = hw->phy.ops.read_reg(hw, PHY_AUTONEG_ADV,
&mii_nway_adv_reg);
if (ret_val)
goto out;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_LP_ABILITY,
+ ret_val = hw->phy.ops.read_reg(hw, PHY_LP_ABILITY,
&mii_nway_lp_ability_reg);
if (ret_val)
goto out;
@@ -1041,7 +1059,7 @@ static s32 igb_valid_led_default(struct e1000_hw *hw, u16 *data)
{
s32 ret_val;
- ret_val = hw->nvm.ops.read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
+ ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h
index cbee6af7d912..a34de5269637 100644
--- a/drivers/net/igb/e1000_mac.h
+++ b/drivers/net/igb/e1000_mac.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -58,12 +58,12 @@ s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
void igb_clear_vfta(struct e1000_hw *hw);
+s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add);
void igb_config_collision_dist(struct e1000_hw *hw);
void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
void igb_put_hw_semaphore(struct e1000_hw *hw);
void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
s32 igb_check_alt_mac_addr(struct e1000_hw *hw);
-void igb_remove_device(struct e1000_hw *hw);
void igb_reset_adaptive(struct e1000_hw *hw);
void igb_update_adaptive(struct e1000_hw *hw);
void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
@@ -83,13 +83,8 @@ enum e1000_mng_mode {
#define E1000_FWSM_MODE_MASK 0xE
#define E1000_FWSM_MODE_SHIFT 1
-#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
-#define E1000_HICR_EN 0x01 /* Enable bit - RO */
-/* Driver sets this bit when done to put command in RAM */
-#define E1000_HICR_C 0x02
-
extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
extern u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
diff --git a/drivers/net/igb/e1000_mbx.c b/drivers/net/igb/e1000_mbx.c
new file mode 100644
index 000000000000..fe71c7ddaa05
--- /dev/null
+++ b/drivers/net/igb/e1000_mbx.c
@@ -0,0 +1,447 @@
+/*******************************************************************************
+
+ Intel(R) Gigabit Ethernet Linux driver
+ Copyright(c) 2007-2009 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include "e1000_mbx.h"
+
+/**
+ * igb_read_mbx - Reads a message from the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to read
+ *
+ * returns SUCCESS if it successfuly read message from buffer
+ **/
+s32 igb_read_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = -E1000_ERR_MBX;
+
+ /* limit read to size of mailbox */
+ if (size > mbx->size)
+ size = mbx->size;
+
+ if (mbx->ops.read)
+ ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+
+ return ret_val;
+}
+
+/**
+ * igb_write_mbx - Write a message to the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully copied message into the buffer
+ **/
+s32 igb_write_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = 0;
+
+ if (size > mbx->size)
+ ret_val = -E1000_ERR_MBX;
+
+ else if (mbx->ops.write)
+ ret_val = mbx->ops.write(hw, msg, size, mbx_id);
+
+ return ret_val;
+}
+
+/**
+ * igb_check_for_msg - checks to see if someone sent us mail
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to check
+ *
+ * returns SUCCESS if the Status bit was found or else ERR_MBX
+ **/
+s32 igb_check_for_msg(struct e1000_hw *hw, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (mbx->ops.check_for_msg)
+ ret_val = mbx->ops.check_for_msg(hw, mbx_id);
+
+ return ret_val;
+}
+
+/**
+ * igb_check_for_ack - checks to see if someone sent us ACK
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to check
+ *
+ * returns SUCCESS if the Status bit was found or else ERR_MBX
+ **/
+s32 igb_check_for_ack(struct e1000_hw *hw, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (mbx->ops.check_for_ack)
+ ret_val = mbx->ops.check_for_ack(hw, mbx_id);
+
+ return ret_val;
+}
+
+/**
+ * igb_check_for_rst - checks to see if other side has reset
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to check
+ *
+ * returns SUCCESS if the Status bit was found or else ERR_MBX
+ **/
+s32 igb_check_for_rst(struct e1000_hw *hw, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (mbx->ops.check_for_rst)
+ ret_val = mbx->ops.check_for_rst(hw, mbx_id);
+
+ return ret_val;
+}
+
+/**
+ * igb_poll_for_msg - Wait for message notification
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully received a message notification
+ **/
+static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ int countdown = mbx->timeout;
+
+ if (!mbx->ops.check_for_msg)
+ goto out;
+
+ while (mbx->ops.check_for_msg(hw, mbx_id)) {
+ if (!countdown)
+ break;
+ countdown--;
+ udelay(mbx->usec_delay);
+ }
+out:
+ return countdown ? 0 : -E1000_ERR_MBX;
+}
+
+/**
+ * igb_poll_for_ack - Wait for message acknowledgement
+ * @hw: pointer to the HW structure
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully received a message acknowledgement
+ **/
+static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ int countdown = mbx->timeout;
+
+ if (!mbx->ops.check_for_ack)
+ goto out;
+
+ while (mbx->ops.check_for_ack(hw, mbx_id)) {
+ if (!countdown)
+ break;
+ countdown--;
+ udelay(mbx->usec_delay);
+ }
+out:
+ return countdown ? 0 : -E1000_ERR_MBX;
+}
+
+/**
+ * igb_read_posted_mbx - Wait for message notification and receive message
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully received a message notification and
+ * copied it into the receive buffer.
+ **/
+s32 igb_read_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (!mbx->ops.read)
+ goto out;
+
+ ret_val = igb_poll_for_msg(hw, mbx_id);
+
+ if (!ret_val)
+ ret_val = mbx->ops.read(hw, msg, size, mbx_id);
+out:
+ return ret_val;
+}
+
+/**
+ * igb_write_posted_mbx - Write a message to the mailbox, wait for ack
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @mbx_id: id of mailbox to write
+ *
+ * returns SUCCESS if it successfully copied message into the buffer and
+ * received an ack to that message within delay * timeout period
+ **/
+s32 igb_write_posted_mbx(struct e1000_hw *hw, u32 *msg, u16 size, u16 mbx_id)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ s32 ret_val = 0;
+
+ if (!mbx->ops.write)
+ goto out;
+
+ /* send msg*/
+ ret_val = mbx->ops.write(hw, msg, size, mbx_id);
+
+ /* if msg sent wait until we receive an ack */
+ if (!ret_val)
+ ret_val = igb_poll_for_ack(hw, mbx_id);
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_init_mbx_ops_generic - Initialize NVM function pointers
+ * @hw: pointer to the HW structure
+ *
+ * Setups up the function pointers to no-op functions
+ **/
+void e1000_init_mbx_ops_generic(struct e1000_hw *hw)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+ mbx->ops.read_posted = igb_read_posted_mbx;
+ mbx->ops.write_posted = igb_write_posted_mbx;
+}
+
+static s32 igb_check_for_bit_pf(struct e1000_hw *hw, u32 mask)
+{
+ u32 mbvficr = rd32(E1000_MBVFICR);
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (mbvficr & mask) {
+ ret_val = 0;
+ wr32(E1000_MBVFICR, mask);
+ }
+
+ return ret_val;
+}
+
+/**
+ * igb_check_for_msg_pf - checks to see if the VF has sent mail
+ * @hw: pointer to the HW structure
+ * @vf_number: the VF index
+ *
+ * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+ **/
+static s32 igb_check_for_msg_pf(struct e1000_hw *hw, u16 vf_number)
+{
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFREQ_VF1 << vf_number)) {
+ ret_val = 0;
+ hw->mbx.stats.reqs++;
+ }
+
+ return ret_val;
+}
+
+/**
+ * igb_check_for_ack_pf - checks to see if the VF has ACKed
+ * @hw: pointer to the HW structure
+ * @vf_number: the VF index
+ *
+ * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+ **/
+static s32 igb_check_for_ack_pf(struct e1000_hw *hw, u16 vf_number)
+{
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (!igb_check_for_bit_pf(hw, E1000_MBVFICR_VFACK_VF1 << vf_number)) {
+ ret_val = 0;
+ hw->mbx.stats.acks++;
+ }
+
+ return ret_val;
+}
+
+/**
+ * igb_check_for_rst_pf - checks to see if the VF has reset
+ * @hw: pointer to the HW structure
+ * @vf_number: the VF index
+ *
+ * returns SUCCESS if the VF has set the Status bit or else ERR_MBX
+ **/
+static s32 igb_check_for_rst_pf(struct e1000_hw *hw, u16 vf_number)
+{
+ u32 vflre = rd32(E1000_VFLRE);
+ s32 ret_val = -E1000_ERR_MBX;
+
+ if (vflre & (1 << vf_number)) {
+ ret_val = 0;
+ wr32(E1000_VFLRE, (1 << vf_number));
+ hw->mbx.stats.rsts++;
+ }
+
+ return ret_val;
+}
+
+/**
+ * igb_write_mbx_pf - Places a message in the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @vf_number: the VF index
+ *
+ * returns SUCCESS if it successfully copied message into the buffer
+ **/
+static s32 igb_write_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
+ u16 vf_number)
+{
+ u32 p2v_mailbox;
+ s32 ret_val = 0;
+ u16 i;
+
+ /* Take ownership of the buffer */
+ wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
+
+ /* Make sure we have ownership now... */
+ p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
+ if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) {
+ /* failed to grab ownership */
+ ret_val = -E1000_ERR_MBX;
+ goto out_no_write;
+ }
+
+ /*
+ * flush any ack or msg which may already be in the queue
+ * as they are likely the result of an error
+ */
+ igb_check_for_ack_pf(hw, vf_number);
+ igb_check_for_msg_pf(hw, vf_number);
+
+ /* copy the caller specified message to the mailbox memory buffer */
+ for (i = 0; i < size; i++)
+ array_wr32(E1000_VMBMEM(vf_number), i, msg[i]);
+
+ /* Interrupt VF to tell it a message has been sent and release buffer*/
+ wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_STS);
+
+ /* update stats */
+ hw->mbx.stats.msgs_tx++;
+
+out_no_write:
+ return ret_val;
+
+}
+
+/**
+ * igb_read_mbx_pf - Read a message from the mailbox
+ * @hw: pointer to the HW structure
+ * @msg: The message buffer
+ * @size: Length of buffer
+ * @vf_number: the VF index
+ *
+ * This function copies a message from the mailbox buffer to the caller's
+ * memory buffer. The presumption is that the caller knows that there was
+ * a message due to a VF request so no polling for message is needed.
+ **/
+static s32 igb_read_mbx_pf(struct e1000_hw *hw, u32 *msg, u16 size,
+ u16 vf_number)
+{
+ u32 p2v_mailbox;
+ s32 ret_val = 0;
+ u16 i;
+
+ /* Take ownership of the buffer */
+ wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_PFU);
+
+ /* Make sure we have ownership now... */
+ p2v_mailbox = rd32(E1000_P2VMAILBOX(vf_number));
+ if (!(p2v_mailbox & E1000_P2VMAILBOX_PFU)) {
+ /* failed to grab ownership */
+ ret_val = -E1000_ERR_MBX;
+ goto out_no_read;
+ }
+
+ /* copy the message to the mailbox memory buffer */
+ for (i = 0; i < size; i++)
+ msg[i] = array_rd32(E1000_VMBMEM(vf_number), i);
+
+ /* Acknowledge the message and release buffer */
+ wr32(E1000_P2VMAILBOX(vf_number), E1000_P2VMAILBOX_ACK);
+
+ /* update stats */
+ hw->mbx.stats.msgs_rx++;
+
+ ret_val = 0;
+
+out_no_read:
+ return ret_val;
+}
+
+/**
+ * e1000_init_mbx_params_pf - set initial values for pf mailbox
+ * @hw: pointer to the HW structure
+ *
+ * Initializes the hw->mbx struct to correct values for pf mailbox
+ */
+s32 igb_init_mbx_params_pf(struct e1000_hw *hw)
+{
+ struct e1000_mbx_info *mbx = &hw->mbx;
+
+ if (hw->mac.type == e1000_82576) {
+ mbx->timeout = 0;
+ mbx->usec_delay = 0;
+
+ mbx->size = E1000_VFMAILBOX_SIZE;
+
+ mbx->ops.read = igb_read_mbx_pf;
+ mbx->ops.write = igb_write_mbx_pf;
+ mbx->ops.read_posted = igb_read_posted_mbx;
+ mbx->ops.write_posted = igb_write_posted_mbx;
+ mbx->ops.check_for_msg = igb_check_for_msg_pf;
+ mbx->ops.check_for_ack = igb_check_for_ack_pf;
+ mbx->ops.check_for_rst = igb_check_for_rst_pf;
+
+ mbx->stats.msgs_tx = 0;
+ mbx->stats.msgs_rx = 0;
+ mbx->stats.reqs = 0;
+ mbx->stats.acks = 0;
+ mbx->stats.rsts = 0;
+ }
+
+ return 0;
+}
+
diff --git a/drivers/net/igb/e1000_mbx.h b/drivers/net/igb/e1000_mbx.h
new file mode 100644
index 000000000000..6ec9890a8f7a
--- /dev/null
+++ b/drivers/net/igb/e1000_mbx.h
@@ -0,0 +1,77 @@
+/*******************************************************************************
+
+ Intel(R) Gigabit Ethernet Linux driver
+ Copyright(c) 2007-2009 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _E1000_MBX_H_
+#define _E1000_MBX_H_
+
+#include "e1000_hw.h"
+
+#define E1000_P2VMAILBOX_STS 0x00000001 /* Initiate message send to VF */
+#define E1000_P2VMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */
+#define E1000_P2VMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
+#define E1000_P2VMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
+#define E1000_P2VMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck */
+
+#define E1000_MBVFICR_VFREQ_MASK 0x000000FF /* bits for VF messages */
+#define E1000_MBVFICR_VFREQ_VF1 0x00000001 /* bit for VF 1 message */
+#define E1000_MBVFICR_VFACK_MASK 0x00FF0000 /* bits for VF acks */
+#define E1000_MBVFICR_VFACK_VF1 0x00010000 /* bit for VF 1 ack */
+
+#define E1000_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */
+
+/* If it's a E1000_VF_* msg then it originates in the VF and is sent to the
+ * PF. The reverse is true if it is E1000_PF_*.
+ * Message ACK's are the value or'd with 0xF0000000
+ */
+#define E1000_VT_MSGTYPE_ACK 0x80000000 /* Messages below or'd with
+ * this are the ACK */
+#define E1000_VT_MSGTYPE_NACK 0x40000000 /* Messages below or'd with
+ * this are the NACK */
+#define E1000_VT_MSGTYPE_CTS 0x20000000 /* Indicates that VF is still
+ clear to send requests */
+#define E1000_VT_MSGINFO_SHIFT 16
+/* bits 23:16 are used for exra info for certain messages */
+#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT)
+
+#define E1000_VF_RESET 0x01 /* VF requests reset */
+#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */
+#define E1000_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
+#define E1000_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
+#define E1000_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
+
+#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */
+
+s32 igb_read_mbx(struct e1000_hw *, u32 *, u16, u16);
+s32 igb_write_mbx(struct e1000_hw *, u32 *, u16, u16);
+s32 igb_read_posted_mbx(struct e1000_hw *, u32 *, u16, u16);
+s32 igb_write_posted_mbx(struct e1000_hw *, u32 *, u16, u16);
+s32 igb_check_for_msg(struct e1000_hw *, u16);
+s32 igb_check_for_ack(struct e1000_hw *, u16);
+s32 igb_check_for_rst(struct e1000_hw *, u16);
+s32 igb_init_mbx_params_pf(struct e1000_hw *);
+
+#endif /* _E1000_MBX_H_ */
diff --git a/drivers/net/igb/e1000_nvm.c b/drivers/net/igb/e1000_nvm.c
index a84e4e429fa7..a88bfe2f1e8f 100644
--- a/drivers/net/igb/e1000_nvm.c
+++ b/drivers/net/igb/e1000_nvm.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -419,7 +419,7 @@ s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
goto out;
}
- ret_val = hw->nvm.ops.acquire_nvm(hw);
+ ret_val = hw->nvm.ops.acquire(hw);
if (ret_val)
goto out;
@@ -468,7 +468,7 @@ s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
msleep(10);
release:
- hw->nvm.ops.release_nvm(hw);
+ hw->nvm.ops.release(hw);
out:
return ret_val;
@@ -487,14 +487,14 @@ s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num)
s32 ret_val;
u16 nvm_data;
- ret_val = hw->nvm.ops.read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
}
*part_num = (u32)(nvm_data << 16);
- ret_val = hw->nvm.ops.read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
@@ -515,29 +515,23 @@ out:
**/
s32 igb_read_mac_addr(struct e1000_hw *hw)
{
- s32 ret_val = 0;
- u16 offset, nvm_data, i;
+ u32 rar_high;
+ u32 rar_low;
+ u16 i;
- for (i = 0; i < ETH_ALEN; i += 2) {
- offset = i >> 1;
- ret_val = hw->nvm.ops.read_nvm(hw, offset, 1, &nvm_data);
- if (ret_val) {
- hw_dbg("NVM Read Error\n");
- goto out;
- }
- hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
- hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
- }
+ rar_high = rd32(E1000_RAH(0));
+ rar_low = rd32(E1000_RAL(0));
+
+ for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
+ hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
- /* Flip last bit of mac address if we're on second port */
- if (hw->bus.func == E1000_FUNC_1)
- hw->mac.perm_addr[5] ^= 1;
+ for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
+ hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
for (i = 0; i < ETH_ALEN; i++)
hw->mac.addr[i] = hw->mac.perm_addr[i];
-out:
- return ret_val;
+ return 0;
}
/**
@@ -554,7 +548,7 @@ s32 igb_validate_nvm_checksum(struct e1000_hw *hw)
u16 i, nvm_data;
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
- ret_val = hw->nvm.ops.read_nvm(hw, i, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error\n");
goto out;
@@ -587,7 +581,7 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw)
u16 i, nvm_data;
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
- ret_val = hw->nvm.ops.read_nvm(hw, i, 1, &nvm_data);
+ ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) {
hw_dbg("NVM Read Error while updating checksum.\n");
goto out;
@@ -595,7 +589,7 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw)
checksum += nvm_data;
}
checksum = (u16) NVM_SUM - checksum;
- ret_val = hw->nvm.ops.write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
+ ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
if (ret_val)
hw_dbg("NVM Write Error while updating checksum.\n");
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index 17fddb91c9f5..f50fac25be40 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -31,10 +31,6 @@
#include "e1000_mac.h"
#include "e1000_phy.h"
-static s32 igb_get_phy_cfg_done(struct e1000_hw *hw);
-static void igb_release_phy(struct e1000_hw *hw);
-static s32 igb_acquire_phy(struct e1000_hw *hw);
-static s32 igb_phy_reset_dsp(struct e1000_hw *hw);
static s32 igb_phy_setup_autoneg(struct e1000_hw *hw);
static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
u16 *phy_ctrl);
@@ -43,9 +39,6 @@ static s32 igb_wait_autoneg(struct e1000_hw *hw);
/* Cable length tables */
static const u16 e1000_m88_cable_length_table[] =
{ 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
-#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
- (sizeof(e1000_m88_cable_length_table) / \
- sizeof(e1000_m88_cable_length_table[0]))
static const u16 e1000_igp_2_cable_length_table[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
@@ -91,13 +84,13 @@ s32 igb_get_phy_id(struct e1000_hw *hw)
s32 ret_val = 0;
u16 phy_id;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_ID1, &phy_id);
+ ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
if (ret_val)
goto out;
phy->id = (u32)(phy_id << 16);
udelay(20);
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_ID2, &phy_id);
+ ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
if (ret_val)
goto out;
@@ -118,11 +111,11 @@ static s32 igb_phy_reset_dsp(struct e1000_hw *hw)
{
s32 ret_val;
- ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
+ ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
if (ret_val)
goto out;
- ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0);
+ ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0);
out:
return ret_val;
@@ -257,9 +250,12 @@ out:
**/
s32 igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
{
- s32 ret_val;
+ s32 ret_val = 0;
+
+ if (!(hw->phy.ops.acquire))
+ goto out;
- ret_val = igb_acquire_phy(hw);
+ ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;
@@ -268,16 +264,15 @@ s32 igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
IGP01E1000_PHY_PAGE_SELECT,
(u16)offset);
if (ret_val) {
- igb_release_phy(hw);
+ hw->phy.ops.release(hw);
goto out;
}
}
- ret_val = igb_read_phy_reg_mdic(hw,
- MAX_PHY_REG_ADDRESS & offset,
- data);
+ ret_val = igb_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+ data);
- igb_release_phy(hw);
+ hw->phy.ops.release(hw);
out:
return ret_val;
@@ -294,9 +289,12 @@ out:
**/
s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
{
- s32 ret_val;
+ s32 ret_val = 0;
- ret_val = igb_acquire_phy(hw);
+ if (!(hw->phy.ops.acquire))
+ goto out;
+
+ ret_val = hw->phy.ops.acquire(hw);
if (ret_val)
goto out;
@@ -305,16 +303,15 @@ s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
IGP01E1000_PHY_PAGE_SELECT,
(u16)offset);
if (ret_val) {
- igb_release_phy(hw);
+ hw->phy.ops.release(hw);
goto out;
}
}
- ret_val = igb_write_phy_reg_mdic(hw,
- MAX_PHY_REG_ADDRESS & offset,
+ ret_val = igb_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
data);
- igb_release_phy(hw);
+ hw->phy.ops.release(hw);
out:
return ret_val;
@@ -339,8 +336,7 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw)
}
/* Enable CRS on TX. This must be set for half-duplex operation. */
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
@@ -383,8 +379,7 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw)
if (phy->disable_polarity_correction == 1)
phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
- ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- phy_data);
+ ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
if (ret_val)
goto out;
@@ -393,8 +388,7 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw)
* Force TX_CLK in the Extended PHY Specific Control Register
* to 25MHz clock.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw,
- M88E1000_EXT_PHY_SPEC_CTRL,
+ ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
&phy_data);
if (ret_val)
goto out;
@@ -413,8 +407,7 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw)
phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
}
- ret_val = hw->phy.ops.write_phy_reg(hw,
- M88E1000_EXT_PHY_SPEC_CTRL,
+ ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
phy_data);
if (ret_val)
goto out;
@@ -449,14 +442,17 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
goto out;
}
- ret_val = hw->phy.ops.reset_phy(hw);
+ ret_val = phy->ops.reset(hw);
if (ret_val) {
hw_dbg("Error resetting the PHY.\n");
goto out;
}
- /* Wait 15ms for MAC to configure PHY from NVM settings. */
- msleep(15);
+ /*
+ * Wait 100ms for MAC to configure PHY from NVM settings, to avoid
+ * timeout issues when LFS is enabled.
+ */
+ msleep(100);
/*
* The NVM settings will configure LPLU in D3 for
@@ -464,8 +460,8 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
*/
if (phy->type == e1000_phy_igp) {
/* disable lplu d3 during driver init */
- if (hw->phy.ops.set_d3_lplu_state)
- ret_val = hw->phy.ops.set_d3_lplu_state(hw, false);
+ if (phy->ops.set_d3_lplu_state)
+ ret_val = phy->ops.set_d3_lplu_state(hw, false);
if (ret_val) {
hw_dbg("Error Disabling LPLU D3\n");
goto out;
@@ -473,13 +469,13 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
}
/* disable lplu d0 during driver init */
- ret_val = hw->phy.ops.set_d0_lplu_state(hw, false);
+ ret_val = phy->ops.set_d0_lplu_state(hw, false);
if (ret_val) {
hw_dbg("Error Disabling LPLU D0\n");
goto out;
}
/* Configure mdi-mdix settings */
- ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data);
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data);
if (ret_val)
goto out;
@@ -497,7 +493,7 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
data |= IGP01E1000_PSCR_AUTO_MDIX;
break;
}
- ret_val = hw->phy.ops.write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, data);
+ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, data);
if (ret_val)
goto out;
@@ -510,33 +506,31 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
*/
if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
/* Disable SmartSpeed */
- ret_val = hw->phy.ops.read_phy_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
- &data);
+ ret_val = phy->ops.read_reg(hw,
+ IGP01E1000_PHY_PORT_CONFIG,
+ &data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = hw->phy.ops.write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
goto out;
/* Set auto Master/Slave resolution process */
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_CTRL,
- &data);
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data);
if (ret_val)
goto out;
data &= ~CR_1000T_MS_ENABLE;
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_1000T_CTRL,
- data);
+ ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data);
if (ret_val)
goto out;
}
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_CTRL, &data);
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data);
if (ret_val)
goto out;
@@ -560,7 +554,7 @@ s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
default:
break;
}
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_1000T_CTRL, data);
+ ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data);
if (ret_val)
goto out;
}
@@ -609,12 +603,12 @@ s32 igb_copper_link_autoneg(struct e1000_hw *hw)
* Restart auto-negotiation by setting the Auto Neg Enable bit and
* the Auto Neg Restart bit in the PHY control register.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_ctrl);
+ ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
if (ret_val)
goto out;
phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_ctrl);
+ ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
if (ret_val)
goto out;
@@ -656,15 +650,13 @@ static s32 igb_phy_setup_autoneg(struct e1000_hw *hw)
phy->autoneg_advertised &= phy->autoneg_mask;
/* Read the MII Auto-Neg Advertisement Register (Address 4). */
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_AUTONEG_ADV,
- &mii_autoneg_adv_reg);
+ ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
if (ret_val)
goto out;
if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
/* Read the MII 1000Base-T Control Register (Address 9). */
- ret_val = hw->phy.ops.read_phy_reg(hw,
- PHY_1000T_CTRL,
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL,
&mii_1000t_ctrl_reg);
if (ret_val)
goto out;
@@ -785,17 +777,16 @@ static s32 igb_phy_setup_autoneg(struct e1000_hw *hw)
goto out;
}
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_AUTONEG_ADV,
- mii_autoneg_adv_reg);
+ ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
if (ret_val)
goto out;
hw_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
- ret_val = hw->phy.ops.write_phy_reg(hw,
- PHY_1000T_CTRL,
- mii_1000t_ctrl_reg);
+ ret_val = phy->ops.write_reg(hw,
+ PHY_1000T_CTRL,
+ mii_1000t_ctrl_reg);
if (ret_val)
goto out;
}
@@ -819,13 +810,13 @@ s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw)
u16 phy_data;
bool link;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_data);
+ ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
if (ret_val)
goto out;
igb_phy_force_speed_duplex_setup(hw, &phy_data);
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_data);
+ ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
if (ret_val)
goto out;
@@ -833,16 +824,14 @@ s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw)
* Clear Auto-Crossover to force MDI manually. IGP requires MDI
* forced whenever speed and duplex are forced.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
if (ret_val)
goto out;
phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
- ret_val = hw->phy.ops.write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
- phy_data);
+ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
if (ret_val)
goto out;
@@ -897,20 +886,18 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
* forced whenever speed and duplex are forced.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
- ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- phy_data);
+ ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
if (ret_val)
goto out;
hw_dbg("M88E1000 PSCR: %X\n", phy_data);
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_data);
+ ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
if (ret_val)
goto out;
@@ -919,7 +906,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
/* Reset the phy to commit changes. */
phy_data |= MII_CR_RESET;
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_data);
+ ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
if (ret_val)
goto out;
@@ -940,7 +927,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* We didn't get link.
* Reset the DSP and cross our fingers.
*/
- ret_val = hw->phy.ops.write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
M88E1000_PHY_PAGE_SELECT,
0x001d);
if (ret_val)
@@ -957,8 +944,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
goto out;
}
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
@@ -968,8 +954,7 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* the reset value of 2.5MHz.
*/
phy_data |= M88E1000_EPSCR_TX_CLK_25;
- ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
- phy_data);
+ ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
if (ret_val)
goto out;
@@ -977,14 +962,12 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
* In addition, we must re-enable CRS on Tx for both half and full
* duplex.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
- ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- phy_data);
+ ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
out:
return ret_val;
@@ -1071,15 +1054,13 @@ s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active)
s32 ret_val;
u16 data;
- ret_val = hw->phy.ops.read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
- &data);
+ ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
if (ret_val)
goto out;
if (!active) {
data &= ~IGP02E1000_PM_D3_LPLU;
- ret_val = hw->phy.ops.write_phy_reg(hw,
- IGP02E1000_PHY_POWER_MGMT,
+ ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data);
if (ret_val)
goto out;
@@ -1090,27 +1071,27 @@ s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active)
* SmartSpeed, so performance is maintained.
*/
if (phy->smart_speed == e1000_smart_speed_on) {
- ret_val = hw->phy.ops.read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
if (ret_val)
goto out;
data |= IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = hw->phy.ops.write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
goto out;
} else if (phy->smart_speed == e1000_smart_speed_off) {
- ret_val = hw->phy.ops.read_phy_reg(hw,
+ ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
&data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = hw->phy.ops.write_phy_reg(hw,
+ ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG,
data);
if (ret_val)
@@ -1120,22 +1101,19 @@ s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active)
(phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
(phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
data |= IGP02E1000_PM_D3_LPLU;
- ret_val = hw->phy.ops.write_phy_reg(hw,
- IGP02E1000_PHY_POWER_MGMT,
+ ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data);
if (ret_val)
goto out;
/* When LPLU is enabled, we should disable SmartSpeed */
- ret_val = hw->phy.ops.read_phy_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&data);
if (ret_val)
goto out;
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = hw->phy.ops.write_phy_reg(hw,
- IGP01E1000_PHY_PORT_CONFIG,
+ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
data);
}
@@ -1176,7 +1154,7 @@ s32 igb_check_downshift(struct e1000_hw *hw)
goto out;
}
- ret_val = hw->phy.ops.read_phy_reg(hw, offset, &phy_data);
+ ret_val = phy->ops.read_reg(hw, offset, &phy_data);
if (!ret_val)
phy->speed_downgraded = (phy_data & mask) ? true : false;
@@ -1199,7 +1177,7 @@ static s32 igb_check_polarity_m88(struct e1000_hw *hw)
s32 ret_val;
u16 data;
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
if (!ret_val)
phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY)
@@ -1228,8 +1206,7 @@ static s32 igb_check_polarity_igp(struct e1000_hw *hw)
* Polarity is determined based on the speed of
* our connection.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
- &data);
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
if (ret_val)
goto out;
@@ -1246,7 +1223,7 @@ static s32 igb_check_polarity_igp(struct e1000_hw *hw)
mask = IGP01E1000_PSSR_POLARITY_REVERSED;
}
- ret_val = hw->phy.ops.read_phy_reg(hw, offset, &data);
+ ret_val = phy->ops.read_reg(hw, offset, &data);
if (!ret_val)
phy->cable_polarity = (data & mask)
@@ -1271,10 +1248,10 @@ static s32 igb_wait_autoneg(struct e1000_hw *hw)
/* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
if (phy_status & MII_SR_AUTONEG_COMPLETE)
@@ -1310,10 +1287,10 @@ s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
* twice due to the link bit being sticky. No harm doing
* it across the board.
*/
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val)
break;
if (phy_status & MII_SR_LINK_STATUS)
@@ -1350,8 +1327,7 @@ s32 igb_get_cable_length_m88(struct e1000_hw *hw)
s32 ret_val;
u16 phy_data, index;
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
if (ret_val)
goto out;
@@ -1372,8 +1348,8 @@ out:
*
* The automatic gain control (agc) normalizes the amplitude of the
* received signal, adjusting for the attenuation produced by the
- * cable. By reading the AGC registers, which reperesent the
- * cobination of course and fine gain value, the value can be put
+ * cable. By reading the AGC registers, which represent the
+ * combination of coarse and fine gain value, the value can be put
* into a lookup table to obtain the approximate cable length
* for each channel.
**/
@@ -1392,14 +1368,13 @@ s32 igb_get_cable_length_igp_2(struct e1000_hw *hw)
/* Read the AGC registers for all channels */
for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
- ret_val = hw->phy.ops.read_phy_reg(hw, agc_reg_array[i],
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, agc_reg_array[i], &phy_data);
if (ret_val)
goto out;
/*
* Getting bits 15:9, which represent the combination of
- * course and fine gain values. The result is a number
+ * coarse and fine gain values. The result is a number
* that can be put into the lookup table to obtain the
* approximate cable length.
*/
@@ -1456,7 +1431,7 @@ s32 igb_get_phy_info_m88(struct e1000_hw *hw)
u16 phy_data;
bool link;
- if (hw->phy.media_type != e1000_media_type_copper) {
+ if (phy->media_type != e1000_media_type_copper) {
hw_dbg("Phy info is only valid for copper media\n");
ret_val = -E1000_ERR_CONFIG;
goto out;
@@ -1472,33 +1447,29 @@ s32 igb_get_phy_info_m88(struct e1000_hw *hw)
goto out;
}
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
phy->polarity_correction = (phy_data & M88E1000_PSCR_POLARITY_REVERSAL)
- ? true
- : false;
+ ? true : false;
ret_val = igb_check_polarity_m88(hw);
if (ret_val)
goto out;
- ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
if (ret_val)
goto out;
phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX) ? true : false;
if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
- ret_val = hw->phy.ops.get_cable_length(hw);
+ ret_val = phy->ops.get_cable_length(hw);
if (ret_val)
goto out;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_STATUS,
- &phy_data);
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &phy_data);
if (ret_val)
goto out;
@@ -1552,8 +1523,7 @@ s32 igb_get_phy_info_igp(struct e1000_hw *hw)
if (ret_val)
goto out;
- ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
- &data);
+ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
if (ret_val)
goto out;
@@ -1561,12 +1531,11 @@ s32 igb_get_phy_info_igp(struct e1000_hw *hw)
if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
IGP01E1000_PSSR_SPEED_1000MBPS) {
- ret_val = hw->phy.ops.get_cable_length(hw);
+ ret_val = phy->ops.get_cable_length(hw);
if (ret_val)
goto out;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_STATUS,
- &data);
+ ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
if (ret_val)
goto out;
@@ -1599,12 +1568,12 @@ s32 igb_phy_sw_reset(struct e1000_hw *hw)
s32 ret_val;
u16 phy_ctrl;
- ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_ctrl);
+ ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
if (ret_val)
goto out;
phy_ctrl |= MII_CR_RESET;
- ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_ctrl);
+ ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
if (ret_val)
goto out;
@@ -1635,7 +1604,7 @@ s32 igb_phy_hw_reset(struct e1000_hw *hw)
goto out;
}
- ret_val = igb_acquire_phy(hw);
+ ret_val = phy->ops.acquire(hw);
if (ret_val)
goto out;
@@ -1650,74 +1619,14 @@ s32 igb_phy_hw_reset(struct e1000_hw *hw)
udelay(150);
- igb_release_phy(hw);
+ phy->ops.release(hw);
- ret_val = igb_get_phy_cfg_done(hw);
+ ret_val = phy->ops.get_cfg_done(hw);
out:
return ret_val;
}
-/* Internal function pointers */
-
-/**
- * igb_get_phy_cfg_done - Generic PHY configuration done
- * @hw: pointer to the HW structure
- *
- * Return success if silicon family did not implement a family specific
- * get_cfg_done function.
- **/
-static s32 igb_get_phy_cfg_done(struct e1000_hw *hw)
-{
- if (hw->phy.ops.get_cfg_done)
- return hw->phy.ops.get_cfg_done(hw);
-
- return 0;
-}
-
-/**
- * igb_release_phy - Generic release PHY
- * @hw: pointer to the HW structure
- *
- * Return if silicon family does not require a semaphore when accessing the
- * PHY.
- **/
-static void igb_release_phy(struct e1000_hw *hw)
-{
- if (hw->phy.ops.release_phy)
- hw->phy.ops.release_phy(hw);
-}
-
-/**
- * igb_acquire_phy - Generic acquire PHY
- * @hw: pointer to the HW structure
- *
- * Return success if silicon family does not require a semaphore when
- * accessing the PHY.
- **/
-static s32 igb_acquire_phy(struct e1000_hw *hw)
-{
- if (hw->phy.ops.acquire_phy)
- return hw->phy.ops.acquire_phy(hw);
-
- return 0;
-}
-
-/**
- * igb_phy_force_speed_duplex - Generic force PHY speed/duplex
- * @hw: pointer to the HW structure
- *
- * When the silicon family has not implemented a forced speed/duplex
- * function for the PHY, simply return 0.
- **/
-s32 igb_phy_force_speed_duplex(struct e1000_hw *hw)
-{
- if (hw->phy.ops.force_speed_duplex)
- return hw->phy.ops.force_speed_duplex(hw);
-
- return 0;
-}
-
/**
* igb_phy_init_script_igp3 - Inits the IGP3 PHY
* @hw: pointer to the HW structure
@@ -1730,75 +1639,75 @@ s32 igb_phy_init_script_igp3(struct e1000_hw *hw)
/* PHY init IGP 3 */
/* Enable rise/fall, 10-mode work in class-A */
- hw->phy.ops.write_phy_reg(hw, 0x2F5B, 0x9018);
+ hw->phy.ops.write_reg(hw, 0x2F5B, 0x9018);
/* Remove all caps from Replica path filter */
- hw->phy.ops.write_phy_reg(hw, 0x2F52, 0x0000);
+ hw->phy.ops.write_reg(hw, 0x2F52, 0x0000);
/* Bias trimming for ADC, AFE and Driver (Default) */
- hw->phy.ops.write_phy_reg(hw, 0x2FB1, 0x8B24);
+ hw->phy.ops.write_reg(hw, 0x2FB1, 0x8B24);
/* Increase Hybrid poly bias */
- hw->phy.ops.write_phy_reg(hw, 0x2FB2, 0xF8F0);
+ hw->phy.ops.write_reg(hw, 0x2FB2, 0xF8F0);
/* Add 4% to TX amplitude in Giga mode */
- hw->phy.ops.write_phy_reg(hw, 0x2010, 0x10B0);
+ hw->phy.ops.write_reg(hw, 0x2010, 0x10B0);
/* Disable trimming (TTT) */
- hw->phy.ops.write_phy_reg(hw, 0x2011, 0x0000);
+ hw->phy.ops.write_reg(hw, 0x2011, 0x0000);
/* Poly DC correction to 94.6% + 2% for all channels */
- hw->phy.ops.write_phy_reg(hw, 0x20DD, 0x249A);
+ hw->phy.ops.write_reg(hw, 0x20DD, 0x249A);
/* ABS DC correction to 95.9% */
- hw->phy.ops.write_phy_reg(hw, 0x20DE, 0x00D3);
+ hw->phy.ops.write_reg(hw, 0x20DE, 0x00D3);
/* BG temp curve trim */
- hw->phy.ops.write_phy_reg(hw, 0x28B4, 0x04CE);
+ hw->phy.ops.write_reg(hw, 0x28B4, 0x04CE);
/* Increasing ADC OPAMP stage 1 currents to max */
- hw->phy.ops.write_phy_reg(hw, 0x2F70, 0x29E4);
+ hw->phy.ops.write_reg(hw, 0x2F70, 0x29E4);
/* Force 1000 ( required for enabling PHY regs configuration) */
- hw->phy.ops.write_phy_reg(hw, 0x0000, 0x0140);
+ hw->phy.ops.write_reg(hw, 0x0000, 0x0140);
/* Set upd_freq to 6 */
- hw->phy.ops.write_phy_reg(hw, 0x1F30, 0x1606);
+ hw->phy.ops.write_reg(hw, 0x1F30, 0x1606);
/* Disable NPDFE */
- hw->phy.ops.write_phy_reg(hw, 0x1F31, 0xB814);
+ hw->phy.ops.write_reg(hw, 0x1F31, 0xB814);
/* Disable adaptive fixed FFE (Default) */
- hw->phy.ops.write_phy_reg(hw, 0x1F35, 0x002A);
+ hw->phy.ops.write_reg(hw, 0x1F35, 0x002A);
/* Enable FFE hysteresis */
- hw->phy.ops.write_phy_reg(hw, 0x1F3E, 0x0067);
+ hw->phy.ops.write_reg(hw, 0x1F3E, 0x0067);
/* Fixed FFE for short cable lengths */
- hw->phy.ops.write_phy_reg(hw, 0x1F54, 0x0065);
+ hw->phy.ops.write_reg(hw, 0x1F54, 0x0065);
/* Fixed FFE for medium cable lengths */
- hw->phy.ops.write_phy_reg(hw, 0x1F55, 0x002A);
+ hw->phy.ops.write_reg(hw, 0x1F55, 0x002A);
/* Fixed FFE for long cable lengths */
- hw->phy.ops.write_phy_reg(hw, 0x1F56, 0x002A);
+ hw->phy.ops.write_reg(hw, 0x1F56, 0x002A);
/* Enable Adaptive Clip Threshold */
- hw->phy.ops.write_phy_reg(hw, 0x1F72, 0x3FB0);
+ hw->phy.ops.write_reg(hw, 0x1F72, 0x3FB0);
/* AHT reset limit to 1 */
- hw->phy.ops.write_phy_reg(hw, 0x1F76, 0xC0FF);
+ hw->phy.ops.write_reg(hw, 0x1F76, 0xC0FF);
/* Set AHT master delay to 127 msec */
- hw->phy.ops.write_phy_reg(hw, 0x1F77, 0x1DEC);
+ hw->phy.ops.write_reg(hw, 0x1F77, 0x1DEC);
/* Set scan bits for AHT */
- hw->phy.ops.write_phy_reg(hw, 0x1F78, 0xF9EF);
+ hw->phy.ops.write_reg(hw, 0x1F78, 0xF9EF);
/* Set AHT Preset bits */
- hw->phy.ops.write_phy_reg(hw, 0x1F79, 0x0210);
+ hw->phy.ops.write_reg(hw, 0x1F79, 0x0210);
/* Change integ_factor of channel A to 3 */
- hw->phy.ops.write_phy_reg(hw, 0x1895, 0x0003);
+ hw->phy.ops.write_reg(hw, 0x1895, 0x0003);
/* Change prop_factor of channels BCD to 8 */
- hw->phy.ops.write_phy_reg(hw, 0x1796, 0x0008);
+ hw->phy.ops.write_reg(hw, 0x1796, 0x0008);
/* Change cg_icount + enable integbp for channels BCD */
- hw->phy.ops.write_phy_reg(hw, 0x1798, 0xD008);
+ hw->phy.ops.write_reg(hw, 0x1798, 0xD008);
/*
* Change cg_icount + enable integbp + change prop_factor_master
* to 8 for channel A
*/
- hw->phy.ops.write_phy_reg(hw, 0x1898, 0xD918);
+ hw->phy.ops.write_reg(hw, 0x1898, 0xD918);
/* Disable AHT in Slave mode on channel A */
- hw->phy.ops.write_phy_reg(hw, 0x187A, 0x0800);
+ hw->phy.ops.write_reg(hw, 0x187A, 0x0800);
/*
* Enable LPLU and disable AN to 1000 in non-D0a states,
* Enable SPD+B2B
*/
- hw->phy.ops.write_phy_reg(hw, 0x0019, 0x008D);
+ hw->phy.ops.write_reg(hw, 0x0019, 0x008D);
/* Enable restart AN on an1000_dis change */
- hw->phy.ops.write_phy_reg(hw, 0x001B, 0x2080);
+ hw->phy.ops.write_reg(hw, 0x001B, 0x2080);
/* Enable wh_fifo read clock in 10/100 modes */
- hw->phy.ops.write_phy_reg(hw, 0x0014, 0x0045);
+ hw->phy.ops.write_reg(hw, 0x0014, 0x0045);
/* Restart AN, Speed selection is 1000 */
- hw->phy.ops.write_phy_reg(hw, 0x0000, 0x1340);
+ hw->phy.ops.write_reg(hw, 0x0000, 0x1340);
return 0;
}
diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h
index 8f8fe0a780d1..3228a862031f 100644
--- a/drivers/net/igb/e1000_phy.h
+++ b/drivers/net/igb/e1000_phy.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -44,7 +44,6 @@ enum e1000_smart_speed {
s32 igb_check_downshift(struct e1000_hw *hw);
s32 igb_check_reset_block(struct e1000_hw *hw);
s32 igb_copper_link_autoneg(struct e1000_hw *hw);
-s32 igb_phy_force_speed_duplex(struct e1000_hw *hw);
s32 igb_copper_link_setup_igp(struct e1000_hw *hw);
s32 igb_copper_link_setup_m88(struct e1000_hw *hw);
s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw);
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index bdf5d839c4bf..0bd7728fe469 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -73,8 +73,75 @@
#define E1000_TCPTIMER 0x0104C /* TCP Timer - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
-#define E1000_RDFPCQ(_n) (0x02430 + (0x4 * (_n)))
#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
+
+/* IEEE 1588 TIMESYNCH */
+#define E1000_TSYNCTXCTL 0x0B614
+#define E1000_TSYNCTXCTL_VALID (1<<0)
+#define E1000_TSYNCTXCTL_ENABLED (1<<4)
+#define E1000_TSYNCRXCTL 0x0B620
+#define E1000_TSYNCRXCTL_VALID (1<<0)
+#define E1000_TSYNCRXCTL_ENABLED (1<<4)
+enum {
+ E1000_TSYNCRXCTL_TYPE_L2_V2 = 0,
+ E1000_TSYNCRXCTL_TYPE_L4_V1 = (1<<1),
+ E1000_TSYNCRXCTL_TYPE_L2_L4_V2 = (1<<2),
+ E1000_TSYNCRXCTL_TYPE_ALL = (1<<3),
+ E1000_TSYNCRXCTL_TYPE_EVENT_V2 = (1<<3) | (1<<1),
+};
+#define E1000_TSYNCRXCFG 0x05F50
+enum {
+ E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE = 0<<0,
+ E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE = 1<<0,
+ E1000_TSYNCRXCFG_PTP_V1_FOLLOWUP_MESSAGE = 2<<0,
+ E1000_TSYNCRXCFG_PTP_V1_DELAY_RESP_MESSAGE = 3<<0,
+ E1000_TSYNCRXCFG_PTP_V1_MANAGEMENT_MESSAGE = 4<<0,
+
+ E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE = 0<<8,
+ E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE = 1<<8,
+ E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_REQ_MESSAGE = 2<<8,
+ E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_RESP_MESSAGE = 3<<8,
+ E1000_TSYNCRXCFG_PTP_V2_FOLLOWUP_MESSAGE = 8<<8,
+ E1000_TSYNCRXCFG_PTP_V2_DELAY_RESP_MESSAGE = 9<<8,
+ E1000_TSYNCRXCFG_PTP_V2_PATH_DELAY_FOLLOWUP_MESSAGE = 0xA<<8,
+ E1000_TSYNCRXCFG_PTP_V2_ANNOUNCE_MESSAGE = 0xB<<8,
+ E1000_TSYNCRXCFG_PTP_V2_SIGNALLING_MESSAGE = 0xC<<8,
+ E1000_TSYNCRXCFG_PTP_V2_MANAGEMENT_MESSAGE = 0xD<<8,
+};
+#define E1000_SYSTIML 0x0B600
+#define E1000_SYSTIMH 0x0B604
+#define E1000_TIMINCA 0x0B608
+
+#define E1000_RXMTRL 0x0B634
+#define E1000_RXSTMPL 0x0B624
+#define E1000_RXSTMPH 0x0B628
+#define E1000_RXSATRL 0x0B62C
+#define E1000_RXSATRH 0x0B630
+
+#define E1000_TXSTMPL 0x0B618
+#define E1000_TXSTMPH 0x0B61C
+
+#define E1000_ETQF0 0x05CB0
+#define E1000_ETQF1 0x05CB4
+#define E1000_ETQF2 0x05CB8
+#define E1000_ETQF3 0x05CBC
+#define E1000_ETQF4 0x05CC0
+#define E1000_ETQF5 0x05CC4
+#define E1000_ETQF6 0x05CC8
+#define E1000_ETQF7 0x05CCC
+
+/* Filtering Registers */
+#define E1000_SAQF(_n) (0x5980 + 4 * (_n))
+#define E1000_DAQF(_n) (0x59A0 + 4 * (_n))
+#define E1000_SPQF(_n) (0x59C0 + 4 * (_n))
+#define E1000_FTQF(_n) (0x59E0 + 4 * (_n))
+#define E1000_SAQF0 E1000_SAQF(0)
+#define E1000_DAQF0 E1000_DAQF(0)
+#define E1000_SPQF0 E1000_SPQF(0)
+#define E1000_FTQF0 E1000_FTQF(0)
+#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
+#define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
+
/* Split and Replication RX Control - RW */
/*
* Convenience macros
@@ -110,7 +177,6 @@
: (0x0E018 + ((_n) * 0x40)))
#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \
: (0x0E028 + ((_n) * 0x40)))
-#define E1000_TARC(_n) (0x03840 + (_n << 8))
#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8))
#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
#define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \
@@ -226,16 +292,14 @@
#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
(0x054E4 + ((_i - 16) * 8)))
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
-#define E1000_VMD_CTL 0x0581C /* VMDq Control - RW */
+#define E1000_VT_CTL 0x0581C /* VMDq Control - RW */
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
#define E1000_WUS 0x05810 /* Wakeup Status - RO */
#define E1000_MANC 0x05820 /* Management Control - RW */
#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
-#define E1000_HOST_IF 0x08800 /* Host Interface */
-#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
@@ -243,9 +307,7 @@
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
-#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
-#define E1000_HICR 0x08F00 /* Host Inteface Control */
/* RSS registers */
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
@@ -254,18 +316,27 @@
#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt RX VLAN Priority - RW */
/* MSI-X Allocation Register (_i) - RW */
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4))
-/* MSI-X Table entry addr low reg 0 - RW */
-#define E1000_MSIXTADD(_i) (0x0C000 + ((_i) * 0x10))
-/* MSI-X Table entry addr upper reg 0 - RW */
-#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10))
-/* MSI-X Table entry message reg 0 - RW */
-#define E1000_MSIXTMSG(_i) (0x0C008 + ((_i) * 0x10))
-/* MSI-X Table entry vector ctrl reg 0 - RW */
-#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10))
/* Redirection Table - RW Array */
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4))
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */
+/* VT Registers */
+#define E1000_MBVFICR 0x00C80 /* Mailbox VF Cause - RWC */
+#define E1000_MBVFIMR 0x00C84 /* Mailbox VF int Mask - RW */
+#define E1000_VFLRE 0x00C88 /* VF Register Events - RWC */
+#define E1000_VFRE 0x00C8C /* VF Receive Enables */
+#define E1000_VFTE 0x00C90 /* VF Transmit Enables */
+#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */
+#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */
+#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */
+#define E1000_IOVTCL 0x05BBC /* IOV Control Register */
+/* These act per VF so an array friendly macro is used */
+#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n)))
+#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
+#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n)))
+#define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine
+ * Filter - RW */
+
#define wr32(reg, value) (writel(value, hw->hw_addr + reg))
#define rd32(reg) (readl(hw->hw_addr + reg))
#define wrfl() ((void)rd32(E1000_STATUS))
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index aebef8e48e76..4e8464b9df2e 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -34,25 +34,15 @@
#include "e1000_mac.h"
#include "e1000_82575.h"
-struct igb_adapter;
-
-#ifdef CONFIG_IGB_LRO
-#include <linux/inet_lro.h>
-#define MAX_LRO_AGGR 32
-#define MAX_LRO_DESCRIPTORS 8
-#endif
+#include <linux/clocksource.h>
+#include <linux/timecompare.h>
+#include <linux/net_tstamp.h>
-/* Interrupt defines */
-#define IGB_MIN_DYN_ITR 3000
-#define IGB_MAX_DYN_ITR 96000
+struct igb_adapter;
/* ((1000000000ns / (6000ints/s * 1024ns)) << 2 = 648 */
#define IGB_START_ITR 648
-#define IGB_DYN_ITR_PACKET_THRESHOLD 2
-#define IGB_DYN_ITR_LENGTH_LOW 200
-#define IGB_DYN_ITR_LENGTH_HIGH 1000
-
/* TX/RX descriptor defines */
#define IGB_DEFAULT_TXD 256
#define IGB_MIN_TXD 80
@@ -67,8 +57,21 @@ struct igb_adapter;
#define IGB_MIN_ITR_USECS 10
/* Transmit and receive queues */
-#define IGB_MAX_RX_QUEUES 4
-#define IGB_MAX_TX_QUEUES 4
+#define IGB_MAX_RX_QUEUES (adapter->vfs_allocated_count ? \
+ (adapter->vfs_allocated_count > 6 ? 1 : 2) : 4)
+#define IGB_MAX_TX_QUEUES IGB_MAX_RX_QUEUES
+#define IGB_ABS_MAX_TX_QUEUES 4
+
+#define IGB_MAX_VF_MC_ENTRIES 30
+#define IGB_MAX_VF_FUNCTIONS 8
+#define IGB_MAX_VFTA_ENTRIES 128
+
+struct vf_data_storage {
+ unsigned char vf_mac_addresses[ETH_ALEN];
+ u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES];
+ u16 num_vf_mc_hashes;
+ bool clear_to_send;
+};
/* RX descriptor control thresholds.
* PTHRESH - MAC will consider prefetch if it has fewer than this number of
@@ -94,12 +97,9 @@ struct igb_adapter;
#define IGB_RXBUFFER_512 512
#define IGB_RXBUFFER_1024 1024
#define IGB_RXBUFFER_2048 2048
-#define IGB_RXBUFFER_4096 4096
-#define IGB_RXBUFFER_8192 8192
#define IGB_RXBUFFER_16384 16384
-/* Packet Buffer allocations */
-
+#define MAX_STD_JUMBO_FRAME_SIZE 9234
/* How many Tx Descriptors do we need to call netif_wake_queue ? */
#define IGB_TX_QUEUE_WAKE 16
@@ -176,29 +176,18 @@ struct igb_ring {
struct napi_struct napi;
int set_itr;
struct igb_ring *buddy;
-#ifdef CONFIG_IGB_LRO
- struct net_lro_mgr lro_mgr;
- bool lro_used;
-#endif
};
};
char name[IFNAMSIZ + 5];
};
-#define IGB_DESC_UNUSED(R) \
- ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
- (R)->next_to_clean - (R)->next_to_use - 1)
-
#define E1000_RX_DESC_ADV(R, i) \
(&(((union e1000_adv_rx_desc *)((R).desc))[i]))
#define E1000_TX_DESC_ADV(R, i) \
(&(((union e1000_adv_tx_desc *)((R).desc))[i]))
#define E1000_TX_CTXTDESC_ADV(R, i) \
(&(((struct e1000_adv_tx_context_desc *)((R).desc))[i]))
-#define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
-#define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc)
-#define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc)
/* board specific private data structure */
@@ -248,7 +237,6 @@ struct igb_adapter {
u64 hw_csum_err;
u64 hw_csum_good;
- u64 rx_hdr_split;
u32 alloc_rx_buff_failed;
bool rx_csum;
u32 gorc;
@@ -262,6 +250,10 @@ struct igb_adapter {
struct napi_struct napi;
struct pci_dev *pdev;
struct net_device_stats net_stats;
+ struct cyclecounter cycles;
+ struct timecounter clock;
+ struct timecompare compare;
+ struct hwtstamp_config hwtstamp_config;
/* structs defined in e1000_hw.h */
struct e1000_hw hw;
@@ -283,27 +275,17 @@ struct igb_adapter {
unsigned int flags;
u32 eeprom_wol;
- /* for ioport free */
- int bars;
- int need_ioport;
-
- struct igb_ring *multi_tx_table[IGB_MAX_TX_QUEUES];
-#ifdef CONFIG_IGB_LRO
- unsigned int lro_max_aggr;
- unsigned int lro_aggregated;
- unsigned int lro_flushed;
- unsigned int lro_no_desc;
-#endif
+ struct igb_ring *multi_tx_table[IGB_ABS_MAX_TX_QUEUES];
unsigned int tx_ring_count;
unsigned int rx_ring_count;
+ unsigned int vfs_allocated_count;
+ struct vf_data_storage *vf_data;
};
#define IGB_FLAG_HAS_MSI (1 << 0)
-#define IGB_FLAG_MSI_ENABLE (1 << 1)
-#define IGB_FLAG_DCA_ENABLED (1 << 2)
-#define IGB_FLAG_IN_NETPOLL (1 << 3)
-#define IGB_FLAG_QUAD_PORT_A (1 << 4)
-#define IGB_FLAG_NEED_CTX_IDX (1 << 5)
+#define IGB_FLAG_DCA_ENABLED (1 << 1)
+#define IGB_FLAG_QUAD_PORT_A (1 << 2)
+#define IGB_FLAG_NEED_CTX_IDX (1 << 3)
enum e1000_state_t {
__IGB_TESTING,
@@ -333,24 +315,24 @@ extern void igb_set_ethtool_ops(struct net_device *);
static inline s32 igb_reset_phy(struct e1000_hw *hw)
{
- if (hw->phy.ops.reset_phy)
- return hw->phy.ops.reset_phy(hw);
+ if (hw->phy.ops.reset)
+ return hw->phy.ops.reset(hw);
return 0;
}
static inline s32 igb_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data)
{
- if (hw->phy.ops.read_phy_reg)
- return hw->phy.ops.read_phy_reg(hw, offset, data);
+ if (hw->phy.ops.read_reg)
+ return hw->phy.ops.read_reg(hw, offset, data);
return 0;
}
static inline s32 igb_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data)
{
- if (hw->phy.ops.write_phy_reg)
- return hw->phy.ops.write_phy_reg(hw, offset, data);
+ if (hw->phy.ops.write_reg)
+ return hw->phy.ops.write_reg(hw, offset, data);
return 0;
}
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 3c831f1472ad..27eae49e79c2 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -88,16 +88,11 @@ static const struct igb_stats igb_gstrings_stats[] = {
{ "rx_long_byte_count", IGB_STAT(stats.gorc) },
{ "rx_csum_offload_good", IGB_STAT(hw_csum_good) },
{ "rx_csum_offload_errors", IGB_STAT(hw_csum_err) },
- { "rx_header_split", IGB_STAT(rx_hdr_split) },
+ { "tx_dma_out_of_sync", IGB_STAT(stats.doosync) },
{ "alloc_rx_buff_failed", IGB_STAT(alloc_rx_buff_failed) },
{ "tx_smbus", IGB_STAT(stats.mgptc) },
{ "rx_smbus", IGB_STAT(stats.mgprc) },
{ "dropped_smbus", IGB_STAT(stats.mgpdc) },
-#ifdef CONFIG_IGB_LRO
- { "lro_aggregated", IGB_STAT(lro_aggregated) },
- { "lro_flushed", IGB_STAT(lro_flushed) },
- { "lro_no_desc", IGB_STAT(lro_no_desc) },
-#endif
};
#define IGB_QUEUE_STATS_LEN \
@@ -293,15 +288,15 @@ static int igb_set_rx_csum(struct net_device *netdev, u32 data)
static u32 igb_get_tx_csum(struct net_device *netdev)
{
- return (netdev->features & NETIF_F_HW_CSUM) != 0;
+ return (netdev->features & NETIF_F_IP_CSUM) != 0;
}
static int igb_set_tx_csum(struct net_device *netdev, u32 data)
{
if (data)
- netdev->features |= NETIF_F_HW_CSUM;
+ netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
else
- netdev->features &= ~NETIF_F_HW_CSUM;
+ netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
return 0;
}
@@ -310,15 +305,13 @@ static int igb_set_tso(struct net_device *netdev, u32 data)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- if (data)
+ if (data) {
netdev->features |= NETIF_F_TSO;
- else
- netdev->features &= ~NETIF_F_TSO;
-
- if (data)
netdev->features |= NETIF_F_TSO6;
- else
+ } else {
+ netdev->features &= ~NETIF_F_TSO;
netdev->features &= ~NETIF_F_TSO6;
+ }
dev_info(&adapter->pdev->dev, "TSO is %s\n",
data ? "Enabled" : "Disabled");
@@ -405,7 +398,7 @@ static void igb_get_regs(struct net_device *netdev,
regs_buff[34] = rd32(E1000_RLPML);
regs_buff[35] = rd32(E1000_RFCTL);
regs_buff[36] = rd32(E1000_MRQC);
- regs_buff[37] = rd32(E1000_VMD_CTL);
+ regs_buff[37] = rd32(E1000_VT_CTL);
/* Transmit */
regs_buff[38] = rd32(E1000_TCTL);
@@ -598,12 +591,12 @@ static int igb_get_eeprom(struct net_device *netdev,
return -ENOMEM;
if (hw->nvm.type == e1000_nvm_eeprom_spi)
- ret_val = hw->nvm.ops.read_nvm(hw, first_word,
+ ret_val = hw->nvm.ops.read(hw, first_word,
last_word - first_word + 1,
eeprom_buff);
else {
for (i = 0; i < last_word - first_word + 1; i++) {
- ret_val = hw->nvm.ops.read_nvm(hw, first_word + i, 1,
+ ret_val = hw->nvm.ops.read(hw, first_word + i, 1,
&eeprom_buff[i]);
if (ret_val)
break;
@@ -650,14 +643,14 @@ static int igb_set_eeprom(struct net_device *netdev,
if (eeprom->offset & 1) {
/* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */
- ret_val = hw->nvm.ops.read_nvm(hw, first_word, 1,
+ ret_val = hw->nvm.ops.read(hw, first_word, 1,
&eeprom_buff[0]);
ptr++;
}
if (((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
/* need read/modify/write of last changed EEPROM word */
/* only the first byte of the word is being modified */
- ret_val = hw->nvm.ops.read_nvm(hw, last_word, 1,
+ ret_val = hw->nvm.ops.read(hw, last_word, 1,
&eeprom_buff[last_word - first_word]);
}
@@ -670,7 +663,7 @@ static int igb_set_eeprom(struct net_device *netdev,
for (i = 0; i < last_word - first_word + 1; i++)
eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]);
- ret_val = hw->nvm.ops.write_nvm(hw, first_word,
+ ret_val = hw->nvm.ops.write(hw, first_word,
last_word - first_word + 1, eeprom_buff);
/* Update the checksum over the first part of the EEPROM if needed
@@ -694,7 +687,7 @@ static void igb_get_drvinfo(struct net_device *netdev,
/* EEPROM image version # is reported as firmware version # for
* 82575 controllers */
- adapter->hw.nvm.ops.read_nvm(&adapter->hw, 5, 1, &eeprom_data);
+ adapter->hw.nvm.ops.read(&adapter->hw, 5, 1, &eeprom_data);
sprintf(firmware_version, "%d.%d-%d",
(eeprom_data & 0xF000) >> 12,
(eeprom_data & 0x0FF0) >> 4,
@@ -863,23 +856,26 @@ static struct igb_reg_test reg_test_82576[] = {
{ E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- { E1000_RDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_RDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_RDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- /* Enable all four RX queues before testing. */
- { E1000_RXDCTL(0), 0x100, 1, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
+ { E1000_RDBAL(4), 0x40, 12, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { E1000_RDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_RDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+ /* Enable all RX queues before testing. */
+ { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
+ { E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
/* RDH is read-only for 82576, only test RDT. */
{ E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+ { E1000_RDT(4), 0x40, 12, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
+ { E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0, 0 },
{ E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
{ E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
{ E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
{ E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
- { E1000_TDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
- { E1000_TDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
- { E1000_TDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
+ { E1000_TDBAL(4), 0x40, 12, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+ { E1000_TDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_TDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
@@ -926,12 +922,13 @@ static struct igb_reg_test reg_test_82575[] = {
static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
int reg, u32 mask, u32 write)
{
+ struct e1000_hw *hw = &adapter->hw;
u32 pat, val;
u32 _test[] =
{0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {
- writel((_test[pat] & write), (adapter->hw.hw_addr + reg));
- val = readl(adapter->hw.hw_addr + reg);
+ wr32(reg, (_test[pat] & write));
+ val = rd32(reg);
if (val != (_test[pat] & write & mask)) {
dev_err(&adapter->pdev->dev, "pattern test reg %04X "
"failed: got 0x%08X expected 0x%08X\n",
@@ -946,9 +943,10 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data,
int reg, u32 mask, u32 write)
{
+ struct e1000_hw *hw = &adapter->hw;
u32 val;
- writel((write & mask), (adapter->hw.hw_addr + reg));
- val = readl(adapter->hw.hw_addr + reg);
+ wr32(reg, write & mask);
+ val = rd32(reg);
if ((write & mask) != (val & mask)) {
dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:"
" got 0x%08X expected 0x%08X\n", reg,
@@ -1014,12 +1012,14 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
for (i = 0; i < test->array_len; i++) {
switch (test->test_type) {
case PATTERN_TEST:
- REG_PATTERN_TEST(test->reg + (i * test->reg_offset),
+ REG_PATTERN_TEST(test->reg +
+ (i * test->reg_offset),
test->mask,
test->write);
break;
case SET_READ_TEST:
- REG_SET_AND_CHECK(test->reg + (i * test->reg_offset),
+ REG_SET_AND_CHECK(test->reg +
+ (i * test->reg_offset),
test->mask,
test->write);
break;
@@ -1061,7 +1061,7 @@ static int igb_eeprom_test(struct igb_adapter *adapter, u64 *data)
*data = 0;
/* Read and add up the contents of the EEPROM */
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
- if ((adapter->hw.nvm.ops.read_nvm(&adapter->hw, i, 1, &temp))
+ if ((adapter->hw.nvm.ops.read(&adapter->hw, i, 1, &temp))
< 0) {
*data = 1;
break;
@@ -1091,16 +1091,17 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
{
struct e1000_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
- u32 mask, i = 0, shared_int = true;
+ u32 mask, ics_mask, i = 0, shared_int = true;
u32 irq = adapter->pdev->irq;
*data = 0;
/* Hook up test interrupt handler just for this test */
- if (adapter->msix_entries) {
+ if (adapter->msix_entries)
/* NOTE: we don't test MSI-X interrupts here, yet */
return 0;
- } else if (adapter->flags & IGB_FLAG_HAS_MSI) {
+
+ if (adapter->flags & IGB_FLAG_HAS_MSI) {
shared_int = false;
if (request_irq(irq, &igb_test_intr, 0, netdev->name, netdev)) {
*data = 1;
@@ -1116,16 +1117,31 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
}
dev_info(&adapter->pdev->dev, "testing %s interrupt\n",
(shared_int ? "shared" : "unshared"));
-
/* Disable all the interrupts */
wr32(E1000_IMC, 0xFFFFFFFF);
msleep(10);
+ /* Define all writable bits for ICS */
+ switch(hw->mac.type) {
+ case e1000_82575:
+ ics_mask = 0x37F47EDD;
+ break;
+ case e1000_82576:
+ ics_mask = 0x77D4FBFD;
+ break;
+ default:
+ ics_mask = 0x7FFFFFFF;
+ break;
+ }
+
/* Test each interrupt */
- for (; i < 10; i++) {
+ for (; i < 31; i++) {
/* Interrupt to test */
mask = 1 << i;
+ if (!(mask & ics_mask))
+ continue;
+
if (!shared_int) {
/* Disable the interrupt to be reported in
* the cause register and then force the same
@@ -1134,8 +1150,12 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
* test failed.
*/
adapter->test_icr = 0;
- wr32(E1000_IMC, ~mask & 0x00007FFF);
- wr32(E1000_ICS, ~mask & 0x00007FFF);
+
+ /* Flush any pending interrupts */
+ wr32(E1000_ICR, ~0);
+
+ wr32(E1000_IMC, mask);
+ wr32(E1000_ICS, mask);
msleep(10);
if (adapter->test_icr & mask) {
@@ -1151,6 +1171,10 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
* test failed.
*/
adapter->test_icr = 0;
+
+ /* Flush any pending interrupts */
+ wr32(E1000_ICR, ~0);
+
wr32(E1000_IMS, mask);
wr32(E1000_ICS, mask);
msleep(10);
@@ -1168,11 +1192,15 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
* test failed.
*/
adapter->test_icr = 0;
- wr32(E1000_IMC, ~mask & 0x00007FFF);
- wr32(E1000_ICS, ~mask & 0x00007FFF);
+
+ /* Flush any pending interrupts */
+ wr32(E1000_ICR, ~0);
+
+ wr32(E1000_IMC, ~mask);
+ wr32(E1000_ICS, ~mask);
msleep(10);
- if (adapter->test_icr) {
+ if (adapter->test_icr & mask) {
*data = 5;
break;
}
@@ -1180,7 +1208,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
}
/* Disable all the interrupts */
- wr32(E1000_IMC, 0xFFFFFFFF);
+ wr32(E1000_IMC, ~0);
msleep(10);
/* Unhook test interrupt handler */
@@ -1244,6 +1272,7 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
struct igb_ring *tx_ring = &adapter->test_tx_ring;
struct igb_ring *rx_ring = &adapter->test_rx_ring;
struct pci_dev *pdev = adapter->pdev;
+ struct igb_buffer *buffer_info;
u32 rctl;
int i, ret_val;
@@ -1260,7 +1289,7 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
goto err_nomem;
}
- tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
+ tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
tx_ring->size = ALIGN(tx_ring->size, 4096);
tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
&tx_ring->dma);
@@ -1274,7 +1303,7 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
((u64) tx_ring->dma & 0x00000000FFFFFFFF));
wr32(E1000_TDBAH(0), ((u64) tx_ring->dma >> 32));
wr32(E1000_TDLEN(0),
- tx_ring->count * sizeof(struct e1000_tx_desc));
+ tx_ring->count * sizeof(union e1000_adv_tx_desc));
wr32(E1000_TDH(0), 0);
wr32(E1000_TDT(0), 0);
wr32(E1000_TCTL,
@@ -1283,27 +1312,31 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT);
for (i = 0; i < tx_ring->count; i++) {
- struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i);
+ union e1000_adv_tx_desc *tx_desc;
struct sk_buff *skb;
unsigned int size = 1024;
+ tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
skb = alloc_skb(size, GFP_KERNEL);
if (!skb) {
ret_val = 3;
goto err_nomem;
}
skb_put(skb, size);
- tx_ring->buffer_info[i].skb = skb;
- tx_ring->buffer_info[i].length = skb->len;
- tx_ring->buffer_info[i].dma =
- pci_map_single(pdev, skb->data, skb->len,
- PCI_DMA_TODEVICE);
- tx_desc->buffer_addr = cpu_to_le64(tx_ring->buffer_info[i].dma);
- tx_desc->lower.data = cpu_to_le32(skb->len);
- tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP |
- E1000_TXD_CMD_IFCS |
- E1000_TXD_CMD_RS);
- tx_desc->upper.data = 0;
+ buffer_info = &tx_ring->buffer_info[i];
+ buffer_info->skb = skb;
+ buffer_info->length = skb->len;
+ buffer_info->dma = pci_map_single(pdev, skb->data, skb->len,
+ PCI_DMA_TODEVICE);
+ tx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
+ tx_desc->read.olinfo_status = cpu_to_le32(skb->len) <<
+ E1000_ADVTXD_PAYLEN_SHIFT;
+ tx_desc->read.cmd_type_len = cpu_to_le32(skb->len);
+ tx_desc->read.cmd_type_len |= cpu_to_le32(E1000_TXD_CMD_EOP |
+ E1000_TXD_CMD_IFCS |
+ E1000_TXD_CMD_RS |
+ E1000_ADVTXD_DTYP_DATA |
+ E1000_ADVTXD_DCMD_DEXT);
}
/* Setup Rx descriptor ring and Rx buffers */
@@ -1319,7 +1352,7 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
goto err_nomem;
}
- rx_ring->size = rx_ring->count * sizeof(struct e1000_rx_desc);
+ rx_ring->size = rx_ring->count * sizeof(union e1000_adv_rx_desc);
rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size,
&rx_ring->dma);
if (!rx_ring->desc) {
@@ -1338,16 +1371,17 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
wr32(E1000_RDH(0), 0);
wr32(E1000_RDT(0), 0);
rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
- rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 |
- E1000_RCTL_RDMTS_HALF |
+ rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_RDMTS_HALF |
(adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
wr32(E1000_RCTL, rctl);
- wr32(E1000_SRRCTL(0), 0);
+ wr32(E1000_SRRCTL(0), E1000_SRRCTL_DESCTYPE_ADV_ONEBUF);
for (i = 0; i < rx_ring->count; i++) {
- struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i);
+ union e1000_adv_rx_desc *rx_desc;
struct sk_buff *skb;
+ buffer_info = &rx_ring->buffer_info[i];
+ rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
skb = alloc_skb(IGB_RXBUFFER_2048 + NET_IP_ALIGN,
GFP_KERNEL);
if (!skb) {
@@ -1355,11 +1389,11 @@ static int igb_setup_desc_rings(struct igb_adapter *adapter)
goto err_nomem;
}
skb_reserve(skb, NET_IP_ALIGN);
- rx_ring->buffer_info[i].skb = skb;
- rx_ring->buffer_info[i].dma =
- pci_map_single(pdev, skb->data, IGB_RXBUFFER_2048,
- PCI_DMA_FROMDEVICE);
- rx_desc->buffer_addr = cpu_to_le64(rx_ring->buffer_info[i].dma);
+ buffer_info->skb = skb;
+ buffer_info->dma = pci_map_single(pdev, skb->data,
+ IGB_RXBUFFER_2048,
+ PCI_DMA_FROMDEVICE);
+ rx_desc->read.pkt_addr = cpu_to_le64(buffer_info->dma);
memset(skb->data, 0x00, skb->len);
}
@@ -1385,7 +1419,6 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
u32 ctrl_reg = 0;
- u32 stat_reg = 0;
hw->mac.autoneg = false;
@@ -1409,18 +1442,11 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter)
ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
- E1000_CTRL_FD); /* Force Duplex to FULL */
+ E1000_CTRL_FD | /* Force Duplex to FULL */
+ E1000_CTRL_SLU); /* Set link up enable bit */
- if (hw->phy.media_type == e1000_media_type_copper &&
- hw->phy.type == e1000_phy_m88)
+ if (hw->phy.type == e1000_phy_m88)
ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */
- else {
- /* Set the ILOS bit on the fiber Nic if half duplex link is
- * detected. */
- stat_reg = rd32(E1000_STATUS);
- if ((stat_reg & E1000_STATUS_FD) == 0)
- ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU);
- }
wr32(E1000_CTRL, ctrl_reg);
@@ -1458,7 +1484,7 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter)
E1000_CTRL_TFCE |
E1000_CTRL_LRST);
reg |= E1000_CTRL_SLU |
- E1000_CTRL_FD;
+ E1000_CTRL_FD;
wr32(E1000_CTRL, reg);
/* Unset switch control to serdes energy detect */
@@ -1745,6 +1771,15 @@ static int igb_wol_exclusion(struct igb_adapter *adapter,
/* return success for non excluded adapter ports */
retval = 0;
break;
+ case E1000_DEV_ID_82576_QUAD_COPPER:
+ /* quad port adapters only support WoL on port A */
+ if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) {
+ wol->supported = 0;
+ break;
+ }
+ /* return success for non excluded adapter ports */
+ retval = 0;
+ break;
default:
/* dual port cards only support WoL on port A from now on
* unless it was enabled in the eeprom for port B
@@ -1827,9 +1862,6 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
return 0;
}
-/* toggle LED 4 times per second = 2 "blinks" per second */
-#define IGB_ID_INTERVAL (HZ/4)
-
/* bit defines for adapter->led_status */
#define IGB_LED_ON 0
@@ -1921,18 +1953,6 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
int stat_count = sizeof(struct igb_queue_stats) / sizeof(u64);
int j;
int i;
-#ifdef CONFIG_IGB_LRO
- int aggregated = 0, flushed = 0, no_desc = 0;
-
- for (i = 0; i < adapter->num_rx_queues; i++) {
- aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated;
- flushed += adapter->rx_ring[i].lro_mgr.stats.flushed;
- no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc;
- }
- adapter->lro_aggregated = aggregated;
- adapter->lro_flushed = flushed;
- adapter->lro_no_desc = no_desc;
-#endif
igb_update_stats(adapter);
for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 9dd13ad12ce4..03aa9593dd9e 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007 Intel Corporation.
+ Copyright(c) 2007-2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -34,6 +34,7 @@
#include <linux/ipv6.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
+#include <linux/net_tstamp.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
@@ -48,12 +49,12 @@
#endif
#include "igb.h"
-#define DRV_VERSION "1.2.45-k2"
+#define DRV_VERSION "1.3.16-k2"
char igb_driver_name[] = "igb";
char igb_driver_version[] = DRV_VERSION;
static const char igb_driver_string[] =
"Intel(R) Gigabit Ethernet Network Driver";
-static const char igb_copyright[] = "Copyright (c) 2008 Intel Corporation.";
+static const char igb_copyright[] = "Copyright (c) 2007-2009 Intel Corporation.";
static const struct e1000_info *igb_info_tbl[] = {
[board_82575] = &e1000_82575_info,
@@ -61,8 +62,10 @@ static const struct e1000_info *igb_info_tbl[] = {
static struct pci_device_id igb_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575GB_QUAD_COPPER), board_82575 },
@@ -105,7 +108,6 @@ static irqreturn_t igb_intr_msi(int irq, void *);
static irqreturn_t igb_msix_other(int irq, void *);
static irqreturn_t igb_msix_rx(int irq, void *);
static irqreturn_t igb_msix_tx(int irq, void *);
-static int igb_clean_rx_ring_msix(struct napi_struct *, int);
#ifdef CONFIG_IGB_DCA
static void igb_update_rx_dca(struct igb_ring *);
static void igb_update_tx_dca(struct igb_ring *);
@@ -115,9 +117,6 @@ static bool igb_clean_tx_irq(struct igb_ring *);
static int igb_poll(struct napi_struct *, int);
static bool igb_clean_rx_irq_adv(struct igb_ring *, int *, int);
static void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
-#ifdef CONFIG_IGB_LRO
-static int igb_get_skb_hdr(struct sk_buff *skb, void **, void **, u64 *, void *);
-#endif
static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
static void igb_tx_timeout(struct net_device *);
static void igb_reset_task(struct work_struct *);
@@ -125,9 +124,19 @@ static void igb_vlan_rx_register(struct net_device *, struct vlan_group *);
static void igb_vlan_rx_add_vid(struct net_device *, u16);
static void igb_vlan_rx_kill_vid(struct net_device *, u16);
static void igb_restore_vlan(struct igb_adapter *);
+static void igb_ping_all_vfs(struct igb_adapter *);
+static void igb_msg_task(struct igb_adapter *);
+static int igb_rcv_msg_from_vf(struct igb_adapter *, u32);
+static inline void igb_set_rah_pool(struct e1000_hw *, int , int);
+static void igb_set_mc_list_pools(struct igb_adapter *, int, u16);
+static void igb_vmm_control(struct igb_adapter *);
+static inline void igb_set_vmolr(struct e1000_hw *, int);
+static inline int igb_set_vf_rlpml(struct igb_adapter *, int, int);
+static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *);
+static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
-static int igb_suspend(struct pci_dev *, pm_message_t);
#ifdef CONFIG_PM
+static int igb_suspend(struct pci_dev *, pm_message_t);
static int igb_resume(struct pci_dev *);
#endif
static void igb_shutdown(struct pci_dev *);
@@ -139,12 +148,18 @@ static struct notifier_block dca_notifier = {
.priority = 0
};
#endif
-
#ifdef CONFIG_NET_POLL_CONTROLLER
/* for netdump / net console */
static void igb_netpoll(struct net_device *);
#endif
+#ifdef CONFIG_PCI_IOV
+static ssize_t igb_set_num_vfs(struct device *, struct device_attribute *,
+ const char *, size_t);
+static ssize_t igb_show_num_vfs(struct device *, struct device_attribute *,
+ char *);
+DEVICE_ATTR(num_vfs, S_IRUGO | S_IWUSR, igb_show_num_vfs, igb_set_num_vfs);
+#endif
static pci_ers_result_t igb_io_error_detected(struct pci_dev *,
pci_channel_state_t);
static pci_ers_result_t igb_io_slot_reset(struct pci_dev *);
@@ -178,6 +193,54 @@ MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
+/**
+ * Scale the NIC clock cycle by a large factor so that
+ * relatively small clock corrections can be added or
+ * substracted at each clock tick. The drawbacks of a
+ * large factor are a) that the clock register overflows
+ * more quickly (not such a big deal) and b) that the
+ * increment per tick has to fit into 24 bits.
+ *
+ * Note that
+ * TIMINCA = IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS *
+ * IGB_TSYNC_SCALE
+ * TIMINCA += TIMINCA * adjustment [ppm] / 1e9
+ *
+ * The base scale factor is intentionally a power of two
+ * so that the division in %struct timecounter can be done with
+ * a shift.
+ */
+#define IGB_TSYNC_SHIFT (19)
+#define IGB_TSYNC_SCALE (1<<IGB_TSYNC_SHIFT)
+
+/**
+ * The duration of one clock cycle of the NIC.
+ *
+ * @todo This hard-coded value is part of the specification and might change
+ * in future hardware revisions. Add revision check.
+ */
+#define IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS 16
+
+#if (IGB_TSYNC_SCALE * IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS) >= (1<<24)
+# error IGB_TSYNC_SCALE and/or IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS are too large to fit into TIMINCA
+#endif
+
+/**
+ * igb_read_clock - read raw cycle counter (to be used by time counter)
+ */
+static cycle_t igb_read_clock(const struct cyclecounter *tc)
+{
+ struct igb_adapter *adapter =
+ container_of(tc, struct igb_adapter, cycles);
+ struct e1000_hw *hw = &adapter->hw;
+ u64 stamp;
+
+ stamp = rd32(E1000_SYSTIML);
+ stamp |= (u64)rd32(E1000_SYSTIMH) << 32ULL;
+
+ return stamp;
+}
+
#ifdef DEBUG
/**
* igb_get_hw_dev_name - return device name string
@@ -188,9 +251,44 @@ char *igb_get_hw_dev_name(struct e1000_hw *hw)
struct igb_adapter *adapter = hw->back;
return adapter->netdev->name;
}
+
+/**
+ * igb_get_time_str - format current NIC and system time as string
+ */
+static char *igb_get_time_str(struct igb_adapter *adapter,
+ char buffer[160])
+{
+ cycle_t hw = adapter->cycles.read(&adapter->cycles);
+ struct timespec nic = ns_to_timespec(timecounter_read(&adapter->clock));
+ struct timespec sys;
+ struct timespec delta;
+ getnstimeofday(&sys);
+
+ delta = timespec_sub(nic, sys);
+
+ sprintf(buffer,
+ "HW %llu, NIC %ld.%09lus, SYS %ld.%09lus, NIC-SYS %lds + %09luns",
+ hw,
+ (long)nic.tv_sec, nic.tv_nsec,
+ (long)sys.tv_sec, sys.tv_nsec,
+ (long)delta.tv_sec, delta.tv_nsec);
+
+ return buffer;
+}
#endif
/**
+ * igb_desc_unused - calculate if we have unused descriptors
+ **/
+static int igb_desc_unused(struct igb_ring *ring)
+{
+ if (ring->next_to_clean > ring->next_to_use)
+ return ring->next_to_clean - ring->next_to_use - 1;
+
+ return ring->count + ring->next_to_clean - ring->next_to_use - 1;
+}
+
+/**
* igb_init_module - Driver Registration Routine
*
* igb_init_module is the first routine called when the driver is
@@ -243,6 +341,7 @@ module_exit(igb_exit_module);
static void igb_cache_ring_register(struct igb_adapter *adapter)
{
int i;
+ unsigned int rbase_offset = adapter->vfs_allocated_count;
switch (adapter->hw.mac.type) {
case e1000_82576:
@@ -252,9 +351,11 @@ static void igb_cache_ring_register(struct igb_adapter *adapter)
* and continue consuming queues in the same sequence
*/
for (i = 0; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i].reg_idx = Q_IDX_82576(i);
+ adapter->rx_ring[i].reg_idx = rbase_offset +
+ Q_IDX_82576(i);
for (i = 0; i < adapter->num_tx_queues; i++)
- adapter->tx_ring[i].reg_idx = Q_IDX_82576(i);
+ adapter->tx_ring[i].reg_idx = rbase_offset +
+ Q_IDX_82576(i);
break;
case e1000_82575:
default:
@@ -319,6 +420,9 @@ static void igb_free_queues(struct igb_adapter *adapter)
for (i = 0; i < adapter->num_rx_queues; i++)
netif_napi_del(&adapter->rx_ring[i].napi);
+ adapter->num_rx_queues = 0;
+ adapter->num_tx_queues = 0;
+
kfree(adapter->tx_ring);
kfree(adapter->rx_ring);
}
@@ -354,7 +458,7 @@ static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
a vector number along with a "valid" bit. Sadly, the layout
of the table is somewhat counterintuitive. */
if (rx_queue > IGB_N0_QUEUE) {
- index = (rx_queue >> 1);
+ index = (rx_queue >> 1) + adapter->vfs_allocated_count;
ivar = array_rd32(E1000_IVAR0, index);
if (rx_queue & 0x1) {
/* vector goes into third byte of register */
@@ -369,7 +473,7 @@ static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
array_wr32(E1000_IVAR0, index, ivar);
}
if (tx_queue > IGB_N0_QUEUE) {
- index = (tx_queue >> 1);
+ index = (tx_queue >> 1) + adapter->vfs_allocated_count;
ivar = array_rd32(E1000_IVAR0, index);
if (tx_queue & 0x1) {
/* vector goes into high byte of register */
@@ -407,7 +511,7 @@ static void igb_configure_msix(struct igb_adapter *adapter)
/* Turn on MSI-X capability first, or our settings
* won't stick. And it will take days to debug. */
wr32(E1000_GPIE, E1000_GPIE_MSIX_MODE |
- E1000_GPIE_PBA | E1000_GPIE_EIAME |
+ E1000_GPIE_PBA | E1000_GPIE_EIAME |
E1000_GPIE_NSICR);
for (i = 0; i < adapter->num_tx_queues; i++) {
@@ -506,9 +610,6 @@ static int igb_request_msix(struct igb_adapter *adapter)
goto out;
ring->itr_register = E1000_EITR(0) + (vector << 2);
ring->itr_val = adapter->itr;
- /* overwrite the poll routine for MSIX, we've already done
- * netif_napi_add */
- ring->napi.poll = &igb_clean_rx_ring_msix;
vector++;
}
@@ -546,6 +647,11 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter)
int err;
int numvecs, i;
+ /* Number of supported queues. */
+ /* Having more queues than CPUs doesn't make sense. */
+ adapter->num_rx_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus());
+ adapter->num_tx_queues = min_t(u32, IGB_MAX_TX_QUEUES, num_online_cpus());
+
numvecs = adapter->num_tx_queues + adapter->num_rx_queues + 1;
adapter->msix_entries = kcalloc(numvecs, sizeof(struct msix_entry),
GFP_KERNEL);
@@ -687,7 +793,10 @@ static void igb_irq_enable(struct igb_adapter *adapter)
wr32(E1000_EIAC, adapter->eims_enable_mask);
wr32(E1000_EIAM, adapter->eims_enable_mask);
wr32(E1000_EIMS, adapter->eims_enable_mask);
- wr32(E1000_IMS, E1000_IMS_LSC);
+ if (adapter->vfs_allocated_count)
+ wr32(E1000_MBVFIMR, 0xFF);
+ wr32(E1000_IMS, (E1000_IMS_LSC | E1000_IMS_VMMB |
+ E1000_IMS_DOUTSYNC));
} else {
wr32(E1000_IMS, IMS_ENABLE_MASK);
wr32(E1000_IAM, IMS_ENABLE_MASK);
@@ -778,12 +887,12 @@ static void igb_configure(struct igb_adapter *adapter)
igb_rx_fifo_flush_82575(&adapter->hw);
- /* call IGB_DESC_UNUSED which always leaves
+ /* call igb_desc_unused which always leaves
* at least 1 descriptor unused to make sure
* next_to_use != next_to_clean */
for (i = 0; i < adapter->num_rx_queues; i++) {
struct igb_ring *ring = &adapter->rx_ring[i];
- igb_alloc_rx_buffers_adv(ring, IGB_DESC_UNUSED(ring));
+ igb_alloc_rx_buffers_adv(ring, igb_desc_unused(ring));
}
@@ -811,6 +920,10 @@ int igb_up(struct igb_adapter *adapter)
if (adapter->msix_entries)
igb_configure_msix(adapter);
+ igb_vmm_control(adapter);
+ igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
+ igb_set_vmolr(hw, adapter->vfs_allocated_count);
+
/* Clear any pending interrupts. */
rd32(E1000_ICR);
igb_irq_enable(adapter);
@@ -856,6 +969,10 @@ void igb_down(struct igb_adapter *adapter)
netdev->tx_queue_len = adapter->tx_queue_len;
netif_carrier_off(netdev);
+
+ /* record the stats before reset*/
+ igb_update_stats(adapter);
+
adapter->link_speed = 0;
adapter->link_duplex = 0;
@@ -886,11 +1003,14 @@ void igb_reset(struct igb_adapter *adapter)
/* Repartition Pba for greater than 9k mtu
* To take effect CTRL.RST is required.
*/
- if (mac->type != e1000_82576) {
- pba = E1000_PBA_34K;
- }
- else {
+ switch (mac->type) {
+ case e1000_82576:
pba = E1000_PBA_64K;
+ break;
+ case e1000_82575:
+ default:
+ pba = E1000_PBA_34K;
+ break;
}
if ((adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) &&
@@ -912,7 +1032,7 @@ void igb_reset(struct igb_adapter *adapter)
/* the tx fifo also stores 16 bytes of information about the tx
* but don't include ethernet FCS because hardware appends it */
min_tx_space = (adapter->max_frame_size +
- sizeof(struct e1000_tx_desc) -
+ sizeof(union e1000_adv_tx_desc) -
ETH_FCS_LEN) * 2;
min_tx_space = ALIGN(min_tx_space, 1024);
min_tx_space >>= 10;
@@ -956,6 +1076,20 @@ void igb_reset(struct igb_adapter *adapter)
fc->send_xon = 1;
fc->type = fc->original_type;
+ /* disable receive for all VFs and wait one second */
+ if (adapter->vfs_allocated_count) {
+ int i;
+ for (i = 0 ; i < adapter->vfs_allocated_count; i++)
+ adapter->vf_data[i].clear_to_send = false;
+
+ /* ping all the active vfs to let them know we are going down */
+ igb_ping_all_vfs(adapter);
+
+ /* disable transmits and receives */
+ wr32(E1000_VFRE, 0);
+ wr32(E1000_VFTE, 0);
+ }
+
/* Allow time for pending master requests to run */
adapter->hw.mac.ops.reset_hw(&adapter->hw);
wr32(E1000_WUC, 0);
@@ -972,21 +1106,6 @@ void igb_reset(struct igb_adapter *adapter)
igb_get_phy_info(&adapter->hw);
}
-/**
- * igb_is_need_ioport - determine if an adapter needs ioport resources or not
- * @pdev: PCI device information struct
- *
- * Returns true if an adapter needs ioport resources
- **/
-static int igb_is_need_ioport(struct pci_dev *pdev)
-{
- switch (pdev->device) {
- /* Currently there are no adapters that need ioport resources */
- default:
- return false;
- }
-}
-
static const struct net_device_ops igb_netdev_ops = {
.ndo_open = igb_open,
.ndo_stop = igb_close,
@@ -1025,21 +1144,12 @@ static int __devinit igb_probe(struct pci_dev *pdev,
struct e1000_hw *hw;
const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
unsigned long mmio_start, mmio_len;
- int i, err, pci_using_dac;
+ int err, pci_using_dac;
u16 eeprom_data = 0;
u16 eeprom_apme_mask = IGB_EEPROM_APME;
u32 part_num;
- int bars, need_ioport;
- /* do not allocate ioport bars when not needed */
- need_ioport = igb_is_need_ioport(pdev);
- if (need_ioport) {
- bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
- err = pci_enable_device(pdev);
- } else {
- bars = pci_select_bars(pdev, IORESOURCE_MEM);
- err = pci_enable_device_mem(pdev);
- }
+ err = pci_enable_device_mem(pdev);
if (err)
return err;
@@ -1061,7 +1171,9 @@ static int __devinit igb_probe(struct pci_dev *pdev,
}
}
- err = pci_request_selected_regions(pdev, bars, igb_driver_name);
+ err = pci_request_selected_regions(pdev, pci_select_bars(pdev,
+ IORESOURCE_MEM),
+ igb_driver_name);
if (err)
goto err_pci_reg;
@@ -1076,7 +1188,8 @@ static int __devinit igb_probe(struct pci_dev *pdev,
pci_save_state(pdev);
err = -ENOMEM;
- netdev = alloc_etherdev_mq(sizeof(struct igb_adapter), IGB_MAX_TX_QUEUES);
+ netdev = alloc_etherdev_mq(sizeof(struct igb_adapter),
+ IGB_ABS_MAX_TX_QUEUES);
if (!netdev)
goto err_alloc_etherdev;
@@ -1089,15 +1202,13 @@ static int __devinit igb_probe(struct pci_dev *pdev,
hw = &adapter->hw;
hw->back = adapter;
adapter->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE;
- adapter->bars = bars;
- adapter->need_ioport = need_ioport;
mmio_start = pci_resource_start(pdev, 0);
mmio_len = pci_resource_len(pdev, 0);
err = -EIO;
- adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
- if (!adapter->hw.hw_addr)
+ hw->hw_addr = ioremap(mmio_start, mmio_len);
+ if (!hw->hw_addr)
goto err_ioremap;
netdev->netdev_ops = &igb_netdev_ops;
@@ -1125,8 +1236,9 @@ static int __devinit igb_probe(struct pci_dev *pdev,
/* Initialize skew-specific constants */
err = ei->get_invariants(hw);
if (err)
- goto err_hw_init;
+ goto err_sw_init;
+ /* setup the private structure */
err = igb_sw_init(adapter);
if (err)
goto err_sw_init;
@@ -1158,27 +1270,25 @@ static int __devinit igb_probe(struct pci_dev *pdev,
"PHY reset is blocked due to SOL/IDER session.\n");
netdev->features = NETIF_F_SG |
- NETIF_F_HW_CSUM |
+ NETIF_F_IP_CSUM |
NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER;
+ netdev->features |= NETIF_F_IPV6_CSUM;
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
-#ifdef CONFIG_IGB_LRO
- netdev->features |= NETIF_F_LRO;
-#endif
+ netdev->features |= NETIF_F_GRO;
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_TSO6;
- netdev->vlan_features |= NETIF_F_HW_CSUM;
+ netdev->vlan_features |= NETIF_F_IP_CSUM;
netdev->vlan_features |= NETIF_F_SG;
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
- netdev->features |= NETIF_F_LLTX;
adapter->en_mng_pt = igb_enable_mng_pass_thru(&adapter->hw);
/* before reading the NVM, reset the controller to put the device in a
@@ -1205,25 +1315,15 @@ static int __devinit igb_probe(struct pci_dev *pdev,
goto err_eeprom;
}
- init_timer(&adapter->watchdog_timer);
- adapter->watchdog_timer.function = &igb_watchdog;
- adapter->watchdog_timer.data = (unsigned long) adapter;
-
- init_timer(&adapter->phy_info_timer);
- adapter->phy_info_timer.function = &igb_update_phy_info;
- adapter->phy_info_timer.data = (unsigned long) adapter;
+ setup_timer(&adapter->watchdog_timer, &igb_watchdog,
+ (unsigned long) adapter);
+ setup_timer(&adapter->phy_info_timer, &igb_update_phy_info,
+ (unsigned long) adapter);
INIT_WORK(&adapter->reset_task, igb_reset_task);
INIT_WORK(&adapter->watchdog_task, igb_watchdog_task);
- /* Initialize link & ring properties that are user-changeable */
- adapter->tx_ring->count = 256;
- for (i = 0; i < adapter->num_tx_queues; i++)
- adapter->tx_ring[i].count = adapter->tx_ring->count;
- adapter->rx_ring->count = 256;
- for (i = 0; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i].count = adapter->rx_ring->count;
-
+ /* Initialize link properties that are user-changeable */
adapter->fc_autoneg = true;
hw->mac.autoneg = true;
hw->phy.autoneg_advertised = 0x2f;
@@ -1231,7 +1331,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
hw->fc.original_type = e1000_fc_default;
hw->fc.type = e1000_fc_default;
- adapter->itr_setting = 3;
+ adapter->itr_setting = IGB_DEFAULT_ITR;
adapter->itr = IGB_START_ITR;
igb_validate_mdi_setting(hw);
@@ -1242,10 +1342,10 @@ static int __devinit igb_probe(struct pci_dev *pdev,
* enable the ACPI Magic Packet filter
*/
- if (hw->bus.func == 0 ||
- hw->device_id == E1000_DEV_ID_82575EB_COPPER)
- hw->nvm.ops.read_nvm(hw, NVM_INIT_CONTROL3_PORT_A, 1,
- &eeprom_data);
+ if (hw->bus.func == 0)
+ hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+ else if (hw->bus.func == 1)
+ hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
if (eeprom_data & eeprom_apme_mask)
adapter->eeprom_wol |= E1000_WUFC_MAG;
@@ -1265,6 +1365,16 @@ static int __devinit igb_probe(struct pci_dev *pdev,
if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1)
adapter->eeprom_wol = 0;
break;
+ case E1000_DEV_ID_82576_QUAD_COPPER:
+ /* if quad port adapter, disable WoL on all but port A */
+ if (global_quad_port_a != 0)
+ adapter->eeprom_wol = 0;
+ else
+ adapter->flags |= IGB_FLAG_QUAD_PORT_A;
+ /* Reset for multiple quad port adapters */
+ if (++global_quad_port_a == 4)
+ global_quad_port_a = 0;
+ break;
}
/* initialize the wol settings based on the eeprom settings */
@@ -1287,26 +1397,92 @@ static int __devinit igb_probe(struct pci_dev *pdev,
if (err)
goto err_register;
+#ifdef CONFIG_PCI_IOV
+ /* since iov functionality isn't critical to base device function we
+ * can accept failure. If it fails we don't allow iov to be enabled */
+ if (hw->mac.type == e1000_82576) {
+ err = pci_enable_sriov(pdev, 0);
+ if (!err)
+ err = device_create_file(&netdev->dev,
+ &dev_attr_num_vfs);
+ if (err)
+ dev_err(&pdev->dev, "Failed to initialize IOV\n");
+ }
+
+#endif
#ifdef CONFIG_IGB_DCA
if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IGB_FLAG_DCA_ENABLED;
dev_info(&pdev->dev, "DCA enabled\n");
/* Always use CB2 mode, difference is masked
* in the CB driver. */
- wr32(E1000_DCA_CTRL, 2);
+ wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
igb_setup_dca(adapter);
}
#endif
+ /*
+ * Initialize hardware timer: we keep it running just in case
+ * that some program needs it later on.
+ */
+ memset(&adapter->cycles, 0, sizeof(adapter->cycles));
+ adapter->cycles.read = igb_read_clock;
+ adapter->cycles.mask = CLOCKSOURCE_MASK(64);
+ adapter->cycles.mult = 1;
+ adapter->cycles.shift = IGB_TSYNC_SHIFT;
+ wr32(E1000_TIMINCA,
+ (1<<24) |
+ IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS * IGB_TSYNC_SCALE);
+#if 0
+ /*
+ * Avoid rollover while we initialize by resetting the time counter.
+ */
+ wr32(E1000_SYSTIML, 0x00000000);
+ wr32(E1000_SYSTIMH, 0x00000000);
+#else
+ /*
+ * Set registers so that rollover occurs soon to test this.
+ */
+ wr32(E1000_SYSTIML, 0x00000000);
+ wr32(E1000_SYSTIMH, 0xFF800000);
+#endif
+ wrfl();
+ timecounter_init(&adapter->clock,
+ &adapter->cycles,
+ ktime_to_ns(ktime_get_real()));
+
+ /*
+ * Synchronize our NIC clock against system wall clock. NIC
+ * time stamp reading requires ~3us per sample, each sample
+ * was pretty stable even under load => only require 10
+ * samples for each offset comparison.
+ */
+ memset(&adapter->compare, 0, sizeof(adapter->compare));
+ adapter->compare.source = &adapter->clock;
+ adapter->compare.target = ktime_get_real;
+ adapter->compare.num_samples = 10;
+ timecompare_update(&adapter->compare, 0);
+
+#ifdef DEBUG
+ {
+ char buffer[160];
+ printk(KERN_DEBUG
+ "igb: %s: hw %p initialized timer\n",
+ igb_get_time_str(adapter, buffer),
+ &adapter->hw);
+ }
+#endif
+
dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n");
/* print bus type/speed/width info */
dev_info(&pdev->dev, "%s: (PCIe:%s:%s) %pM\n",
netdev->name,
((hw->bus.speed == e1000_bus_speed_2500)
? "2.5Gb/s" : "unknown"),
- ((hw->bus.width == e1000_bus_width_pcie_x4)
- ? "Width x4" : (hw->bus.width == e1000_bus_width_pcie_x1)
- ? "Width x1" : "unknown"),
+ ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
+ (hw->bus.width == e1000_bus_width_pcie_x2) ? "Width x2" :
+ (hw->bus.width == e1000_bus_width_pcie_x1) ? "Width x1" :
+ "unknown"),
netdev->dev_addr);
igb_read_part_num(hw, &part_num);
@@ -1330,15 +1506,14 @@ err_eeprom:
if (hw->flash_address)
iounmap(hw->flash_address);
- igb_remove_device(hw);
igb_free_queues(adapter);
err_sw_init:
-err_hw_init:
iounmap(hw->hw_addr);
err_ioremap:
free_netdev(netdev);
err_alloc_etherdev:
- pci_release_selected_regions(pdev, bars);
+ pci_release_selected_regions(pdev, pci_select_bars(pdev,
+ IORESOURCE_MEM));
err_pci_reg:
err_dma:
pci_disable_device(pdev);
@@ -1358,9 +1533,7 @@ static void __devexit igb_remove(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
-#ifdef CONFIG_IGB_DCA
struct e1000_hw *hw = &adapter->hw;
-#endif
int err;
/* flush_scheduled work may reschedule our watchdog task, so
@@ -1376,7 +1549,7 @@ static void __devexit igb_remove(struct pci_dev *pdev)
dev_info(&pdev->dev, "DCA disabled\n");
dca_remove_requester(&pdev->dev);
adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
- wr32(E1000_DCA_CTRL, 1);
+ wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_DISABLE);
}
#endif
@@ -1389,15 +1562,29 @@ static void __devexit igb_remove(struct pci_dev *pdev)
if (!igb_check_reset_block(&adapter->hw))
igb_reset_phy(&adapter->hw);
- igb_remove_device(&adapter->hw);
igb_reset_interrupt_capability(adapter);
igb_free_queues(adapter);
- iounmap(adapter->hw.hw_addr);
- if (adapter->hw.flash_address)
- iounmap(adapter->hw.flash_address);
- pci_release_selected_regions(pdev, adapter->bars);
+#ifdef CONFIG_PCI_IOV
+ /* reclaim resources allocated to VFs */
+ if (adapter->vf_data) {
+ /* disable iov and allow time for transactions to clear */
+ pci_disable_sriov(pdev);
+ msleep(500);
+
+ kfree(adapter->vf_data);
+ adapter->vf_data = NULL;
+ wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
+ msleep(100);
+ dev_info(&pdev->dev, "IOV Disabled\n");
+ }
+#endif
+ iounmap(hw->hw_addr);
+ if (hw->flash_address)
+ iounmap(hw->flash_address);
+ pci_release_selected_regions(pdev, pci_select_bars(pdev,
+ IORESOURCE_MEM));
free_netdev(netdev);
@@ -1432,11 +1619,6 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
- /* Number of supported queues. */
- /* Having more queues than CPUs doesn't make sense. */
- adapter->num_rx_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus());
- adapter->num_tx_queues = min_t(u32, IGB_MAX_TX_QUEUES, num_online_cpus());
-
/* This call may decrease the number of queues depending on
* interrupt mode. */
igb_set_interrupt_capability(adapter);
@@ -1499,6 +1681,10 @@ static int igb_open(struct net_device *netdev)
* clean_rx handler before we do so. */
igb_configure(adapter);
+ igb_vmm_control(adapter);
+ igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
+ igb_set_vmolr(hw, adapter->vfs_allocated_count);
+
err = igb_request_irq(adapter);
if (err)
goto err_req_irq;
@@ -1574,7 +1760,6 @@ static int igb_close(struct net_device *netdev)
*
* Return 0 on success, negative on failure
**/
-
int igb_setup_tx_resources(struct igb_adapter *adapter,
struct igb_ring *tx_ring)
{
@@ -1588,7 +1773,7 @@ int igb_setup_tx_resources(struct igb_adapter *adapter,
memset(tx_ring->buffer_info, 0, size);
/* round up to nearest 4K */
- tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
+ tx_ring->size = tx_ring->count * sizeof(union e1000_adv_tx_desc);
tx_ring->size = ALIGN(tx_ring->size, 4096);
tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
@@ -1635,7 +1820,7 @@ static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
for (i = 0; i < IGB_MAX_TX_QUEUES; i++) {
r_idx = i % adapter->num_tx_queues;
adapter->multi_tx_table[i] = &adapter->tx_ring[r_idx];
- }
+ }
return err;
}
@@ -1654,13 +1839,13 @@ static void igb_configure_tx(struct igb_adapter *adapter)
int i, j;
for (i = 0; i < adapter->num_tx_queues; i++) {
- struct igb_ring *ring = &(adapter->tx_ring[i]);
+ struct igb_ring *ring = &adapter->tx_ring[i];
j = ring->reg_idx;
wr32(E1000_TDLEN(j),
- ring->count * sizeof(struct e1000_tx_desc));
+ ring->count * sizeof(union e1000_adv_tx_desc));
tdba = ring->dma;
wr32(E1000_TDBAL(j),
- tdba & 0x00000000ffffffffULL);
+ tdba & 0x00000000ffffffffULL);
wr32(E1000_TDBAH(j), tdba >> 32);
ring->head = E1000_TDH(j);
@@ -1680,12 +1865,11 @@ static void igb_configure_tx(struct igb_adapter *adapter)
wr32(E1000_DCA_TXCTRL(j), txctrl);
}
-
-
- /* Use the default values for the Tx Inter Packet Gap (IPG) timer */
+ /* disable queue 0 to prevent tail bump w/o re-configuration */
+ if (adapter->vfs_allocated_count)
+ wr32(E1000_TXDCTL(0), 0);
/* Program the Transmit Control Register */
-
tctl = rd32(E1000_TCTL);
tctl &= ~E1000_TCTL_CT;
tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
@@ -1709,21 +1893,12 @@ static void igb_configure_tx(struct igb_adapter *adapter)
*
* Returns 0 on success, negative on failure
**/
-
int igb_setup_rx_resources(struct igb_adapter *adapter,
struct igb_ring *rx_ring)
{
struct pci_dev *pdev = adapter->pdev;
int size, desc_len;
-#ifdef CONFIG_IGB_LRO
- size = sizeof(struct net_lro_desc) * MAX_LRO_DESCRIPTORS;
- rx_ring->lro_mgr.lro_arr = vmalloc(size);
- if (!rx_ring->lro_mgr.lro_arr)
- goto err;
- memset(rx_ring->lro_mgr.lro_arr, 0, size);
-#endif
-
size = sizeof(struct igb_buffer) * rx_ring->count;
rx_ring->buffer_info = vmalloc(size);
if (!rx_ring->buffer_info)
@@ -1750,10 +1925,6 @@ int igb_setup_rx_resources(struct igb_adapter *adapter,
return 0;
err:
-#ifdef CONFIG_IGB_LRO
- vfree(rx_ring->lro_mgr.lro_arr);
- rx_ring->lro_mgr.lro_arr = NULL;
-#endif
vfree(rx_ring->buffer_info);
dev_err(&adapter->pdev->dev, "Unable to allocate memory for "
"the receive descriptor ring\n");
@@ -1802,13 +1973,13 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_RDMTS_HALF |
- (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
+ (hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
/*
* enable stripping of CRC. It's unlikely this will break BMC
* redirection as it did with e1000. Newer features require
* that the HW strips the CRC.
- */
+ */
rctl |= E1000_RCTL_SECRC;
/*
@@ -1852,6 +2023,30 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
}
+ /* Attention!!! For SR-IOV PF driver operations you must enable
+ * queue drop for all VF and PF queues to prevent head of line blocking
+ * if an un-trusted VF does not provide descriptors to hardware.
+ */
+ if (adapter->vfs_allocated_count) {
+ u32 vmolr;
+
+ j = adapter->rx_ring[0].reg_idx;
+
+ /* set all queue drop enable bits */
+ wr32(E1000_QDE, ALL_QUEUES);
+ srrctl |= E1000_SRRCTL_DROP_EN;
+
+ /* disable queue 0 to prevent tail write w/o re-config */
+ wr32(E1000_RXDCTL(0), 0);
+
+ vmolr = rd32(E1000_VMOLR(j));
+ if (rctl & E1000_RCTL_LPE)
+ vmolr |= E1000_VMOLR_LPE;
+ if (adapter->num_rx_queues > 0)
+ vmolr |= E1000_VMOLR_RSSE;
+ wr32(E1000_VMOLR(j), vmolr);
+ }
+
for (i = 0; i < adapter->num_rx_queues; i++) {
j = adapter->rx_ring[i].reg_idx;
wr32(E1000_SRRCTL(j), srrctl);
@@ -1861,6 +2056,54 @@ static void igb_setup_rctl(struct igb_adapter *adapter)
}
/**
+ * igb_rlpml_set - set maximum receive packet size
+ * @adapter: board private structure
+ *
+ * Configure maximum receivable packet size.
+ **/
+static void igb_rlpml_set(struct igb_adapter *adapter)
+{
+ u32 max_frame_size = adapter->max_frame_size;
+ struct e1000_hw *hw = &adapter->hw;
+ u16 pf_id = adapter->vfs_allocated_count;
+
+ if (adapter->vlgrp)
+ max_frame_size += VLAN_TAG_SIZE;
+
+ /* if vfs are enabled we set RLPML to the largest possible request
+ * size and set the VMOLR RLPML to the size we need */
+ if (pf_id) {
+ igb_set_vf_rlpml(adapter, max_frame_size, pf_id);
+ max_frame_size = MAX_STD_JUMBO_FRAME_SIZE + VLAN_TAG_SIZE;
+ }
+
+ wr32(E1000_RLPML, max_frame_size);
+}
+
+/**
+ * igb_configure_vt_default_pool - Configure VT default pool
+ * @adapter: board private structure
+ *
+ * Configure the default pool
+ **/
+static void igb_configure_vt_default_pool(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u16 pf_id = adapter->vfs_allocated_count;
+ u32 vtctl;
+
+ /* not in sr-iov mode - do nothing */
+ if (!pf_id)
+ return;
+
+ vtctl = rd32(E1000_VT_CTL);
+ vtctl &= ~(E1000_VT_CTL_DEFAULT_POOL_MASK |
+ E1000_VT_CTL_DISABLE_DEF_POOL);
+ vtctl |= pf_id << E1000_VT_CTL_DEFAULT_POOL_SHIFT;
+ wr32(E1000_VT_CTL, vtctl);
+}
+
+/**
* igb_configure_rx - Configure receive Unit after Reset
* @adapter: board private structure
*
@@ -1872,7 +2115,7 @@ static void igb_configure_rx(struct igb_adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
u32 rctl, rxcsum;
u32 rxdctl;
- int i, j;
+ int i;
/* disable receives while setting up the descriptors */
rctl = rd32(E1000_RCTL);
@@ -1886,14 +2129,14 @@ static void igb_configure_rx(struct igb_adapter *adapter)
/* Setup the HW Rx Head and Tail Descriptor Pointers and
* the Base and Length of the Rx Descriptor Ring */
for (i = 0; i < adapter->num_rx_queues; i++) {
- struct igb_ring *ring = &(adapter->rx_ring[i]);
- j = ring->reg_idx;
+ struct igb_ring *ring = &adapter->rx_ring[i];
+ int j = ring->reg_idx;
rdba = ring->dma;
wr32(E1000_RDBAL(j),
- rdba & 0x00000000ffffffffULL);
+ rdba & 0x00000000ffffffffULL);
wr32(E1000_RDBAH(j), rdba >> 32);
wr32(E1000_RDLEN(j),
- ring->count * sizeof(union e1000_adv_rx_desc));
+ ring->count * sizeof(union e1000_adv_rx_desc));
ring->head = E1000_RDH(j);
ring->tail = E1000_RDT(j);
@@ -1907,16 +2150,6 @@ static void igb_configure_rx(struct igb_adapter *adapter)
rxdctl |= IGB_RX_HTHRESH << 8;
rxdctl |= IGB_RX_WTHRESH << 16;
wr32(E1000_RXDCTL(j), rxdctl);
-#ifdef CONFIG_IGB_LRO
- /* Intitial LRO Settings */
- ring->lro_mgr.max_aggr = MAX_LRO_AGGR;
- ring->lro_mgr.max_desc = MAX_LRO_DESCRIPTORS;
- ring->lro_mgr.get_skb_header = igb_get_skb_hdr;
- ring->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
- ring->lro_mgr.dev = adapter->netdev;
- ring->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
- ring->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
-#endif
}
if (adapter->num_rx_queues > 1) {
@@ -1941,7 +2174,10 @@ static void igb_configure_rx(struct igb_adapter *adapter)
writel(reta.dword,
hw->hw_addr + E1000_RETA(0) + (j & ~3));
}
- mrqc = E1000_MRQC_ENABLE_RSS_4Q;
+ if (adapter->vfs_allocated_count)
+ mrqc = E1000_MRQC_ENABLE_VMDQ_RSS_2Q;
+ else
+ mrqc = E1000_MRQC_ENABLE_RSS_4Q;
/* Fill out hash function seeds */
for (j = 0; j < 10; j++)
@@ -1966,27 +2202,23 @@ static void igb_configure_rx(struct igb_adapter *adapter)
rxcsum |= E1000_RXCSUM_PCSD;
wr32(E1000_RXCSUM, rxcsum);
} else {
+ /* Enable multi-queue for sr-iov */
+ if (adapter->vfs_allocated_count)
+ wr32(E1000_MRQC, E1000_MRQC_ENABLE_VMDQ);
/* Enable Receive Checksum Offload for TCP and UDP */
rxcsum = rd32(E1000_RXCSUM);
- if (adapter->rx_csum) {
- rxcsum |= E1000_RXCSUM_TUOFL;
+ if (adapter->rx_csum)
+ rxcsum |= E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE;
+ else
+ rxcsum &= ~(E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE);
- /* Enable IPv4 payload checksum for UDP fragments
- * Must be used in conjunction with packet-split. */
- if (adapter->rx_ps_hdr_size)
- rxcsum |= E1000_RXCSUM_IPPCSE;
- } else {
- rxcsum &= ~E1000_RXCSUM_TUOFL;
- /* don't need to clear IPPCSE as it defaults to 0 */
- }
wr32(E1000_RXCSUM, rxcsum);
}
- if (adapter->vlgrp)
- wr32(E1000_RLPML,
- adapter->max_frame_size + VLAN_TAG_SIZE);
- else
- wr32(E1000_RLPML, adapter->max_frame_size);
+ /* Set the default pool for the PF's first queue */
+ igb_configure_vt_default_pool(adapter);
+
+ igb_rlpml_set(adapter);
/* Enable Receives */
wr32(E1000_RCTL, rctl);
@@ -2029,14 +2261,10 @@ static void igb_free_all_tx_resources(struct igb_adapter *adapter)
static void igb_unmap_and_free_tx_resource(struct igb_adapter *adapter,
struct igb_buffer *buffer_info)
{
- if (buffer_info->dma) {
- pci_unmap_page(adapter->pdev,
- buffer_info->dma,
- buffer_info->length,
- PCI_DMA_TODEVICE);
- buffer_info->dma = 0;
- }
+ buffer_info->dma = 0;
if (buffer_info->skb) {
+ skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
+ DMA_TO_DEVICE);
dev_kfree_skb_any(buffer_info->skb);
buffer_info->skb = NULL;
}
@@ -2105,11 +2333,6 @@ void igb_free_rx_resources(struct igb_ring *rx_ring)
vfree(rx_ring->buffer_info);
rx_ring->buffer_info = NULL;
-#ifdef CONFIG_IGB_LRO
- vfree(rx_ring->lro_mgr.lro_arr);
- rx_ring->lro_mgr.lro_arr = NULL;
-#endif
-
pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
rx_ring->desc = NULL;
@@ -2209,15 +2432,18 @@ static void igb_clean_all_rx_rings(struct igb_adapter *adapter)
static int igb_set_mac(struct net_device *netdev, void *p)
{
struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
- memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
+ memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
+
+ hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
- adapter->hw.mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
+ igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
return 0;
}
@@ -2237,7 +2463,7 @@ static void igb_set_multi(struct net_device *netdev)
struct e1000_hw *hw = &adapter->hw;
struct e1000_mac_info *mac = &hw->mac;
struct dev_mc_list *mc_ptr;
- u8 *mta_list;
+ u8 *mta_list = NULL;
u32 rctl;
int i;
@@ -2258,17 +2484,15 @@ static void igb_set_multi(struct net_device *netdev)
}
wr32(E1000_RCTL, rctl);
- if (!netdev->mc_count) {
- /* nothing to program, so clear mc list */
- igb_update_mc_addr_list_82575(hw, NULL, 0, 1,
- mac->rar_entry_count);
- return;
+ if (netdev->mc_count) {
+ mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
+ if (!mta_list) {
+ dev_err(&adapter->pdev->dev,
+ "failed to allocate multicast filter list\n");
+ return;
+ }
}
- mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
- if (!mta_list)
- return;
-
/* The shared function expects a packed array of only addresses. */
mc_ptr = netdev->mc_list;
@@ -2278,8 +2502,13 @@ static void igb_set_multi(struct net_device *netdev)
memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
mc_ptr = mc_ptr->next;
}
- igb_update_mc_addr_list_82575(hw, mta_list, i, 1,
- mac->rar_entry_count);
+ igb_update_mc_addr_list(hw, mta_list, i,
+ adapter->vfs_allocated_count + 1,
+ mac->rar_entry_count);
+
+ igb_set_mc_list_pools(adapter, i, mac->rar_entry_count);
+ igb_restore_vf_multicasts(adapter);
+
kfree(mta_list);
}
@@ -2292,6 +2521,46 @@ static void igb_update_phy_info(unsigned long data)
}
/**
+ * igb_has_link - check shared code for link and determine up/down
+ * @adapter: pointer to driver private info
+ **/
+static bool igb_has_link(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ bool link_active = false;
+ s32 ret_val = 0;
+
+ /* get_link_status is set on LSC (link status) interrupt or
+ * rx sequence error interrupt. get_link_status will stay
+ * false until the e1000_check_for_link establishes link
+ * for copper adapters ONLY
+ */
+ switch (hw->phy.media_type) {
+ case e1000_media_type_copper:
+ if (hw->mac.get_link_status) {
+ ret_val = hw->mac.ops.check_for_link(hw);
+ link_active = !hw->mac.get_link_status;
+ } else {
+ link_active = true;
+ }
+ break;
+ case e1000_media_type_fiber:
+ ret_val = hw->mac.ops.check_for_link(hw);
+ link_active = !!(rd32(E1000_STATUS) & E1000_STATUS_LU);
+ break;
+ case e1000_media_type_internal_serdes:
+ ret_val = hw->mac.ops.check_for_link(hw);
+ link_active = hw->mac.serdes_has_link;
+ break;
+ default:
+ case e1000_media_type_unknown:
+ break;
+ }
+
+ return link_active;
+}
+
+/**
* igb_watchdog - Timer Call-back
* @data: pointer to adapter cast into an unsigned long
**/
@@ -2307,34 +2576,16 @@ static void igb_watchdog_task(struct work_struct *work)
struct igb_adapter *adapter = container_of(work,
struct igb_adapter, watchdog_task);
struct e1000_hw *hw = &adapter->hw;
-
struct net_device *netdev = adapter->netdev;
struct igb_ring *tx_ring = adapter->tx_ring;
- struct e1000_mac_info *mac = &adapter->hw.mac;
u32 link;
u32 eics = 0;
- s32 ret_val;
int i;
- if ((netif_carrier_ok(netdev)) &&
- (rd32(E1000_STATUS) & E1000_STATUS_LU))
+ link = igb_has_link(adapter);
+ if ((netif_carrier_ok(netdev)) && link)
goto link_up;
- ret_val = hw->mac.ops.check_for_link(&adapter->hw);
- if ((ret_val == E1000_ERR_PHY) &&
- (hw->phy.type == e1000_phy_igp_3) &&
- (rd32(E1000_CTRL) &
- E1000_PHY_CTRL_GBE_DISABLE))
- dev_info(&adapter->pdev->dev,
- "Gigabit has been disabled, downgrading speed\n");
-
- if ((hw->phy.media_type == e1000_media_type_internal_serdes) &&
- !(rd32(E1000_TXCW) & E1000_TXCW_ANE))
- link = mac->serdes_has_link;
- else
- link = rd32(E1000_STATUS) &
- E1000_STATUS_LU;
-
if (link) {
if (!netif_carrier_ok(netdev)) {
u32 ctrl;
@@ -2373,6 +2624,9 @@ static void igb_watchdog_task(struct work_struct *work)
netif_carrier_on(netdev);
netif_tx_wake_all_queues(netdev);
+ igb_ping_all_vfs(adapter);
+
+ /* link state has changed, schedule phy info update */
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ));
@@ -2386,6 +2640,10 @@ static void igb_watchdog_task(struct work_struct *work)
netdev->name);
netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev);
+
+ igb_ping_all_vfs(adapter);
+
+ /* link state has changed, schedule phy info update */
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ));
@@ -2395,9 +2653,9 @@ static void igb_watchdog_task(struct work_struct *work)
link_up:
igb_update_stats(adapter);
- mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
+ hw->mac.tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
adapter->tpt_old = adapter->stats.tpt;
- mac->collision_delta = adapter->stats.colc - adapter->colc_old;
+ hw->mac.collision_delta = adapter->stats.colc - adapter->colc_old;
adapter->colc_old = adapter->stats.colc;
adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
@@ -2408,7 +2666,7 @@ link_up:
igb_update_adaptive(&adapter->hw);
if (!netif_carrier_ok(netdev)) {
- if (IGB_DESC_UNUSED(tx_ring) + 1 < tx_ring->count) {
+ if (igb_desc_unused(tx_ring) + 1 < tx_ring->count) {
/* We've lost link, so the controller stops DMA,
* but we've got queued Tx work that's never going
* to get done, so reset controller to flush Tx.
@@ -2554,7 +2812,7 @@ static unsigned int igb_update_itr(struct igb_adapter *adapter, u16 itr_setting,
if (bytes > 25000) {
if (packets > 35)
retval = low_latency;
- } else if (bytes < 6000) {
+ } else if (bytes < 1500) {
retval = low_latency;
}
break;
@@ -2586,15 +2844,13 @@ static void igb_set_itr(struct igb_adapter *adapter)
adapter->tx_itr,
adapter->tx_ring->total_packets,
adapter->tx_ring->total_bytes);
-
current_itr = max(adapter->rx_itr, adapter->tx_itr);
} else {
current_itr = adapter->rx_itr;
}
/* conservative mode (itr 3) eliminates the lowest_latency setting */
- if (adapter->itr_setting == 3 &&
- current_itr == lowest_latency)
+ if (adapter->itr_setting == 3 && current_itr == lowest_latency)
current_itr = low_latency;
switch (current_itr) {
@@ -2646,6 +2902,7 @@ set_itr_now:
#define IGB_TX_FLAGS_VLAN 0x00000002
#define IGB_TX_FLAGS_TSO 0x00000004
#define IGB_TX_FLAGS_IPV4 0x00000008
+#define IGB_TX_FLAGS_TSTAMP 0x00000010
#define IGB_TX_FLAGS_VLAN_MASK 0xffff0000
#define IGB_TX_FLAGS_VLAN_SHIFT 16
@@ -2711,7 +2968,7 @@ static inline int igb_tso_adv(struct igb_adapter *adapter,
mss_l4len_idx = (skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT);
mss_l4len_idx |= (l4len << E1000_ADVTXD_L4LEN_SHIFT);
- /* Context index must be unique per ring. */
+ /* For 82575, context index must be unique per ring. */
if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
mss_l4len_idx |= tx_ring->queue_index << 4;
@@ -2756,13 +3013,24 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT);
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ __be16 protocol;
+
+ if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
+ const struct vlan_ethhdr *vhdr =
+ (const struct vlan_ethhdr*)skb->data;
+
+ protocol = vhdr->h_vlan_encapsulated_proto;
+ } else {
+ protocol = skb->protocol;
+ }
+
+ switch (protocol) {
+ case cpu_to_be16(ETH_P_IP):
tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
break;
- case __constant_htons(ETH_P_IPV6):
+ case cpu_to_be16(ETH_P_IPV6):
/* XXX what about other V6 headers?? */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
@@ -2781,6 +3049,8 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
context_desc->mss_l4len_idx =
cpu_to_le32(tx_ring->queue_index << 4);
+ else
+ context_desc->mss_l4len_idx = 0;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
@@ -2793,8 +3063,6 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
return true;
}
-
-
return false;
}
@@ -2809,25 +3077,33 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter,
unsigned int len = skb_headlen(skb);
unsigned int count = 0, i;
unsigned int f;
+ dma_addr_t *map;
i = tx_ring->next_to_use;
+ if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+ return 0;
+ }
+
+ map = skb_shinfo(skb)->dma_maps;
+
buffer_info = &tx_ring->buffer_info[i];
BUG_ON(len >= IGB_MAX_DATA_PER_TXD);
buffer_info->length = len;
/* set time_stamp *before* dma to help avoid a possible race */
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
- buffer_info->dma = pci_map_single(adapter->pdev, skb->data, len,
- PCI_DMA_TODEVICE);
+ buffer_info->dma = map[count];
count++;
- i++;
- if (i == tx_ring->count)
- i = 0;
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
struct skb_frag_struct *frag;
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+
frag = &skb_shinfo(skb)->frags[f];
len = frag->size;
@@ -2836,19 +3112,10 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter,
buffer_info->length = len;
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
- buffer_info->dma = pci_map_page(adapter->pdev,
- frag->page,
- frag->page_offset,
- len,
- PCI_DMA_TODEVICE);
-
+ buffer_info->dma = map[count];
count++;
- i++;
- if (i == tx_ring->count)
- i = 0;
}
- i = ((i == 0) ? tx_ring->count - 1 : i - 1);
tx_ring->buffer_info[i].skb = skb;
tx_ring->buffer_info[first].next_to_watch = i;
@@ -2871,6 +3138,9 @@ static inline void igb_tx_queue_adv(struct igb_adapter *adapter,
if (tx_flags & IGB_TX_FLAGS_VLAN)
cmd_type_len |= E1000_ADVTXD_DCMD_VLE;
+ if (tx_flags & IGB_TX_FLAGS_TSTAMP)
+ cmd_type_len |= E1000_ADVTXD_MAC_TSTAMP;
+
if (tx_flags & IGB_TX_FLAGS_TSO) {
cmd_type_len |= E1000_ADVTXD_DCMD_TSE;
@@ -2933,7 +3203,7 @@ static int __igb_maybe_stop_tx(struct net_device *netdev,
/* We need to check again in a case another CPU has just
* made room available. */
- if (IGB_DESC_UNUSED(tx_ring) < size)
+ if (igb_desc_unused(tx_ring) < size)
return -EBUSY;
/* A reprieve! */
@@ -2945,13 +3215,11 @@ static int __igb_maybe_stop_tx(struct net_device *netdev,
static int igb_maybe_stop_tx(struct net_device *netdev,
struct igb_ring *tx_ring, int size)
{
- if (IGB_DESC_UNUSED(tx_ring) >= size)
+ if (igb_desc_unused(tx_ring) >= size)
return 0;
return __igb_maybe_stop_tx(netdev, tx_ring, size);
}
-#define TXD_USE_COUNT(S) (((S) >> (IGB_MAX_TXD_PWR)) + 1)
-
static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
struct net_device *netdev,
struct igb_ring *tx_ring)
@@ -2959,11 +3227,10 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
struct igb_adapter *adapter = netdev_priv(netdev);
unsigned int first;
unsigned int tx_flags = 0;
- unsigned int len;
u8 hdr_len = 0;
+ int count = 0;
int tso = 0;
-
- len = skb_headlen(skb);
+ union skb_shared_tx *shtx;
if (test_bit(__IGB_DOWN, &adapter->state)) {
dev_kfree_skb_any(skb);
@@ -2984,7 +3251,21 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
/* this is a hard error */
return NETDEV_TX_BUSY;
}
- skb_orphan(skb);
+
+ /*
+ * TODO: check that there currently is no other packet with
+ * time stamping in the queue
+ *
+ * When doing time stamping, keep the connection to the socket
+ * a while longer: it is still needed by skb_hwtstamp_tx(),
+ * called either in igb_tx_hwtstamp() or by our caller when
+ * doing software time stamping.
+ */
+ shtx = skb_tx(skb);
+ if (unlikely(shtx->hardware)) {
+ shtx->in_progress = 1;
+ tx_flags |= IGB_TX_FLAGS_TSTAMP;
+ }
if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
tx_flags |= IGB_TX_FLAGS_VLAN;
@@ -2995,7 +3276,6 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
tx_flags |= IGB_TX_FLAGS_IPV4;
first = tx_ring->next_to_use;
-
tso = skb_is_gso(skb) ? igb_tso_adv(adapter, tx_ring, skb, tx_flags,
&hdr_len) : 0;
@@ -3006,18 +3286,27 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
if (tso)
tx_flags |= IGB_TX_FLAGS_TSO;
- else if (igb_tx_csum_adv(adapter, tx_ring, skb, tx_flags))
- if (skb->ip_summed == CHECKSUM_PARTIAL)
- tx_flags |= IGB_TX_FLAGS_CSUM;
+ else if (igb_tx_csum_adv(adapter, tx_ring, skb, tx_flags) &&
+ (skb->ip_summed == CHECKSUM_PARTIAL))
+ tx_flags |= IGB_TX_FLAGS_CSUM;
- igb_tx_queue_adv(adapter, tx_ring, tx_flags,
- igb_tx_map_adv(adapter, tx_ring, skb, first),
- skb->len, hdr_len);
-
- netdev->trans_start = jiffies;
-
- /* Make sure there is space in the ring for the next send. */
- igb_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 4);
+ /*
+ * count reflects descriptors mapped, if 0 then mapping error
+ * has occured and we need to rewind the descriptor queue
+ */
+ count = igb_tx_map_adv(adapter, tx_ring, skb, first);
+
+ if (count) {
+ igb_tx_queue_adv(adapter, tx_ring, tx_flags, count,
+ skb->len, hdr_len);
+ netdev->trans_start = jiffies;
+ /* Make sure there is space in the ring for the next send. */
+ igb_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 4);
+ } else {
+ dev_kfree_skb_any(skb);
+ tx_ring->buffer_info[first].time_stamp = 0;
+ tx_ring->next_to_use = first;
+ }
return NETDEV_TX_OK;
}
@@ -3028,7 +3317,7 @@ static int igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *netdev)
struct igb_ring *tx_ring;
int r_idx = 0;
- r_idx = skb->queue_mapping & (IGB_MAX_TX_QUEUES - 1);
+ r_idx = skb->queue_mapping & (IGB_ABS_MAX_TX_QUEUES - 1);
tx_ring = adapter->multi_tx_table[r_idx];
/* This goes back to the question of how to logically map a tx queue
@@ -3050,8 +3339,8 @@ static void igb_tx_timeout(struct net_device *netdev)
/* Do the reset outside of interrupt context */
adapter->tx_timeout_count++;
schedule_work(&adapter->reset_task);
- wr32(E1000_EICS, adapter->eims_enable_mask &
- ~(E1000_EIMS_TCP_TIMER | E1000_EIMS_OTHER));
+ wr32(E1000_EICS,
+ (adapter->eims_enable_mask & ~adapter->eims_other));
}
static void igb_reset_task(struct work_struct *work)
@@ -3069,8 +3358,7 @@ static void igb_reset_task(struct work_struct *work)
* Returns the address of the device statistics structure.
* The statistics are actually updated from the timer callback.
**/
-static struct net_device_stats *
-igb_get_stats(struct net_device *netdev)
+static struct net_device_stats *igb_get_stats(struct net_device *netdev)
{
struct igb_adapter *adapter = netdev_priv(netdev);
@@ -3096,7 +3384,6 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
return -EINVAL;
}
-#define MAX_STD_JUMBO_FRAME_SIZE 9234
if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
dev_err(&adapter->pdev->dev, "MTU > 9216 not supported.\n");
return -EINVAL;
@@ -3104,6 +3391,7 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
msleep(1);
+
/* igb_down has a dependency on max_frame_size */
adapter->max_frame_size = max_frame;
if (netif_running(netdev))
@@ -3129,6 +3417,12 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
#else
adapter->rx_buffer_len = PAGE_SIZE / 2;
#endif
+
+ /* if sr-iov is enabled we need to force buffer size to 1K or larger */
+ if (adapter->vfs_allocated_count &&
+ (adapter->rx_buffer_len < IGB_RXBUFFER_1024))
+ adapter->rx_buffer_len = IGB_RXBUFFER_1024;
+
/* adjust allocation if LPE protects us, and we aren't using SBP */
if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
(max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))
@@ -3273,8 +3567,7 @@ void igb_update_stats(struct igb_adapter *adapter)
/* Phy Stats */
if (hw->phy.media_type == e1000_media_type_copper) {
if ((adapter->link_speed == SPEED_1000) &&
- (!igb_read_phy_reg(hw, PHY_1000T_STATUS,
- &phy_tmp))) {
+ (!igb_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
adapter->phy_stats.idle_errors += phy_tmp;
}
@@ -3286,7 +3579,6 @@ void igb_update_stats(struct igb_adapter *adapter)
adapter->stats.mgpdc += rd32(E1000_MGTPDC);
}
-
static irqreturn_t igb_msix_other(int irq, void *data)
{
struct net_device *netdev = data;
@@ -3295,15 +3587,24 @@ static irqreturn_t igb_msix_other(int irq, void *data)
u32 icr = rd32(E1000_ICR);
/* reading ICR causes bit 31 of EICR to be cleared */
- if (!(icr & E1000_ICR_LSC))
- goto no_link_interrupt;
- hw->mac.get_link_status = 1;
- /* guard against interrupt when we're going down */
- if (!test_bit(__IGB_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer, jiffies + 1);
-
-no_link_interrupt:
- wr32(E1000_IMS, E1000_IMS_LSC);
+
+ if(icr & E1000_ICR_DOUTSYNC) {
+ /* HW is reporting DMA is out of sync */
+ adapter->stats.doosync++;
+ }
+
+ /* Check for a mailbox event */
+ if (icr & E1000_ICR_VMMB)
+ igb_msg_task(adapter);
+
+ if (icr & E1000_ICR_LSC) {
+ hw->mac.get_link_status = 1;
+ /* guard against interrupt when we're going down */
+ if (!test_bit(__IGB_DOWN, &adapter->state))
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
+ }
+
+ wr32(E1000_IMS, E1000_IMS_LSC | E1000_IMS_DOUTSYNC | E1000_IMS_VMMB);
wr32(E1000_EIMS, adapter->eims_other);
return IRQ_HANDLED;
@@ -3319,6 +3620,7 @@ static irqreturn_t igb_msix_tx(int irq, void *data)
if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_tx_dca(tx_ring);
#endif
+
tx_ring->total_bytes = 0;
tx_ring->total_packets = 0;
@@ -3339,13 +3641,11 @@ static void igb_write_itr(struct igb_ring *ring)
if ((ring->adapter->itr_setting & 3) && ring->set_itr) {
switch (hw->mac.type) {
case e1000_82576:
- wr32(ring->itr_register,
- ring->itr_val |
+ wr32(ring->itr_register, ring->itr_val |
0x80000000);
break;
default:
- wr32(ring->itr_register,
- ring->itr_val |
+ wr32(ring->itr_register, ring->itr_val |
(ring->itr_val << 16));
break;
}
@@ -3363,8 +3663,8 @@ static irqreturn_t igb_msix_rx(int irq, void *data)
igb_write_itr(rx_ring);
- if (netif_rx_schedule_prep(&rx_ring->napi))
- __netif_rx_schedule(&rx_ring->napi);
+ if (napi_schedule_prep(&rx_ring->napi))
+ __napi_schedule(&rx_ring->napi);
#ifdef CONFIG_IGB_DCA
if (rx_ring->adapter->flags & IGB_FLAG_DCA_ENABLED)
@@ -3386,11 +3686,11 @@ static void igb_update_rx_dca(struct igb_ring *rx_ring)
dca_rxctrl = rd32(E1000_DCA_RXCTRL(q));
if (hw->mac.type == e1000_82576) {
dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK_82576;
- dca_rxctrl |= dca_get_tag(cpu) <<
+ dca_rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu) <<
E1000_DCA_RXCTRL_CPUID_SHIFT;
} else {
dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK;
- dca_rxctrl |= dca_get_tag(cpu);
+ dca_rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
}
dca_rxctrl |= E1000_DCA_RXCTRL_DESC_DCA_EN;
dca_rxctrl |= E1000_DCA_RXCTRL_HEAD_DCA_EN;
@@ -3413,11 +3713,11 @@ static void igb_update_tx_dca(struct igb_ring *tx_ring)
dca_txctrl = rd32(E1000_DCA_TXCTRL(q));
if (hw->mac.type == e1000_82576) {
dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK_82576;
- dca_txctrl |= dca_get_tag(cpu) <<
+ dca_txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu) <<
E1000_DCA_TXCTRL_CPUID_SHIFT;
} else {
dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK;
- dca_txctrl |= dca_get_tag(cpu);
+ dca_txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
}
dca_txctrl |= E1000_DCA_TXCTRL_DESC_DCA_EN;
wr32(E1000_DCA_TXCTRL(q), dca_txctrl);
@@ -3457,7 +3757,7 @@ static int __igb_notify_dca(struct device *dev, void *data)
break;
/* Always use CB2 mode, difference is masked
* in the CB driver. */
- wr32(E1000_DCA_CTRL, 2);
+ wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
if (dca_add_requester(dev) == 0) {
adapter->flags |= IGB_FLAG_DCA_ENABLED;
dev_info(&adapter->pdev->dev, "DCA enabled\n");
@@ -3472,7 +3772,7 @@ static int __igb_notify_dca(struct device *dev, void *data)
dca_remove_requester(dev);
dev_info(&adapter->pdev->dev, "DCA disabled\n");
adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
- wr32(E1000_DCA_CTRL, 1);
+ wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_DISABLE);
}
break;
}
@@ -3492,6 +3792,322 @@ static int igb_notify_dca(struct notifier_block *nb, unsigned long event,
}
#endif /* CONFIG_IGB_DCA */
+static void igb_ping_all_vfs(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 ping;
+ int i;
+
+ for (i = 0 ; i < adapter->vfs_allocated_count; i++) {
+ ping = E1000_PF_CONTROL_MSG;
+ if (adapter->vf_data[i].clear_to_send)
+ ping |= E1000_VT_MSGTYPE_CTS;
+ igb_write_mbx(hw, &ping, 1, i);
+ }
+}
+
+static int igb_set_vf_multicasts(struct igb_adapter *adapter,
+ u32 *msgbuf, u32 vf)
+{
+ int n = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT;
+ u16 *hash_list = (u16 *)&msgbuf[1];
+ struct vf_data_storage *vf_data = &adapter->vf_data[vf];
+ int i;
+
+ /* only up to 30 hash values supported */
+ if (n > 30)
+ n = 30;
+
+ /* salt away the number of multi cast addresses assigned
+ * to this VF for later use to restore when the PF multi cast
+ * list changes
+ */
+ vf_data->num_vf_mc_hashes = n;
+
+ /* VFs are limited to using the MTA hash table for their multicast
+ * addresses */
+ for (i = 0; i < n; i++)
+ vf_data->vf_mc_hashes[i] = hash_list[i];;
+
+ /* Flush and reset the mta with the new values */
+ igb_set_multi(adapter->netdev);
+
+ return 0;
+}
+
+static void igb_restore_vf_multicasts(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ struct vf_data_storage *vf_data;
+ int i, j;
+
+ for (i = 0; i < adapter->vfs_allocated_count; i++) {
+ vf_data = &adapter->vf_data[i];
+ for (j = 0; j < vf_data->num_vf_mc_hashes; j++)
+ igb_mta_set(hw, vf_data->vf_mc_hashes[j]);
+ }
+}
+
+static void igb_clear_vf_vfta(struct igb_adapter *adapter, u32 vf)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 pool_mask, reg, vid;
+ int i;
+
+ pool_mask = 1 << (E1000_VLVF_POOLSEL_SHIFT + vf);
+
+ /* Find the vlan filter for this id */
+ for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
+ reg = rd32(E1000_VLVF(i));
+
+ /* remove the vf from the pool */
+ reg &= ~pool_mask;
+
+ /* if pool is empty then remove entry from vfta */
+ if (!(reg & E1000_VLVF_POOLSEL_MASK) &&
+ (reg & E1000_VLVF_VLANID_ENABLE)) {
+ reg = 0;
+ vid = reg & E1000_VLVF_VLANID_MASK;
+ igb_vfta_set(hw, vid, false);
+ }
+
+ wr32(E1000_VLVF(i), reg);
+ }
+}
+
+static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 reg, i;
+
+ /* It is an error to call this function when VFs are not enabled */
+ if (!adapter->vfs_allocated_count)
+ return -1;
+
+ /* Find the vlan filter for this id */
+ for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
+ reg = rd32(E1000_VLVF(i));
+ if ((reg & E1000_VLVF_VLANID_ENABLE) &&
+ vid == (reg & E1000_VLVF_VLANID_MASK))
+ break;
+ }
+
+ if (add) {
+ if (i == E1000_VLVF_ARRAY_SIZE) {
+ /* Did not find a matching VLAN ID entry that was
+ * enabled. Search for a free filter entry, i.e.
+ * one without the enable bit set
+ */
+ for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
+ reg = rd32(E1000_VLVF(i));
+ if (!(reg & E1000_VLVF_VLANID_ENABLE))
+ break;
+ }
+ }
+ if (i < E1000_VLVF_ARRAY_SIZE) {
+ /* Found an enabled/available entry */
+ reg |= 1 << (E1000_VLVF_POOLSEL_SHIFT + vf);
+
+ /* if !enabled we need to set this up in vfta */
+ if (!(reg & E1000_VLVF_VLANID_ENABLE)) {
+ /* add VID to filter table, if bit already set
+ * PF must have added it outside of table */
+ if (igb_vfta_set(hw, vid, true))
+ reg |= 1 << (E1000_VLVF_POOLSEL_SHIFT +
+ adapter->vfs_allocated_count);
+ reg |= E1000_VLVF_VLANID_ENABLE;
+ }
+ reg &= ~E1000_VLVF_VLANID_MASK;
+ reg |= vid;
+
+ wr32(E1000_VLVF(i), reg);
+ return 0;
+ }
+ } else {
+ if (i < E1000_VLVF_ARRAY_SIZE) {
+ /* remove vf from the pool */
+ reg &= ~(1 << (E1000_VLVF_POOLSEL_SHIFT + vf));
+ /* if pool is empty then remove entry from vfta */
+ if (!(reg & E1000_VLVF_POOLSEL_MASK)) {
+ reg = 0;
+ igb_vfta_set(hw, vid, false);
+ }
+ wr32(E1000_VLVF(i), reg);
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
+{
+ int add = (msgbuf[0] & E1000_VT_MSGINFO_MASK) >> E1000_VT_MSGINFO_SHIFT;
+ int vid = (msgbuf[1] & E1000_VLVF_VLANID_MASK);
+
+ return igb_vlvf_set(adapter, vid, add, vf);
+}
+
+static inline void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf)
+{
+ struct e1000_hw *hw = &adapter->hw;
+
+ /* disable mailbox functionality for vf */
+ adapter->vf_data[vf].clear_to_send = false;
+
+ /* reset offloads to defaults */
+ igb_set_vmolr(hw, vf);
+
+ /* reset vlans for device */
+ igb_clear_vf_vfta(adapter, vf);
+
+ /* reset multicast table array for vf */
+ adapter->vf_data[vf].num_vf_mc_hashes = 0;
+
+ /* Flush and reset the mta with the new values */
+ igb_set_multi(adapter->netdev);
+}
+
+static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
+ u32 reg, msgbuf[3];
+ u8 *addr = (u8 *)(&msgbuf[1]);
+
+ /* process all the same items cleared in a function level reset */
+ igb_vf_reset_event(adapter, vf);
+
+ /* set vf mac address */
+ igb_rar_set(hw, vf_mac, vf + 1);
+ igb_set_rah_pool(hw, vf, vf + 1);
+
+ /* enable transmit and receive for vf */
+ reg = rd32(E1000_VFTE);
+ wr32(E1000_VFTE, reg | (1 << vf));
+ reg = rd32(E1000_VFRE);
+ wr32(E1000_VFRE, reg | (1 << vf));
+
+ /* enable mailbox functionality for vf */
+ adapter->vf_data[vf].clear_to_send = true;
+
+ /* reply to reset with ack and vf mac address */
+ msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_ACK;
+ memcpy(addr, vf_mac, 6);
+ igb_write_mbx(hw, msgbuf, 3, vf);
+}
+
+static int igb_set_vf_mac_addr(struct igb_adapter *adapter, u32 *msg, int vf)
+{
+ unsigned char *addr = (char *)&msg[1];
+ int err = -1;
+
+ if (is_valid_ether_addr(addr))
+ err = igb_set_vf_mac(adapter, vf, addr);
+
+ return err;
+
+}
+
+static void igb_rcv_ack_from_vf(struct igb_adapter *adapter, u32 vf)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 msg = E1000_VT_MSGTYPE_NACK;
+
+ /* if device isn't clear to send it shouldn't be reading either */
+ if (!adapter->vf_data[vf].clear_to_send)
+ igb_write_mbx(hw, &msg, 1, vf);
+}
+
+
+static void igb_msg_task(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 vf;
+
+ for (vf = 0; vf < adapter->vfs_allocated_count; vf++) {
+ /* process any reset requests */
+ if (!igb_check_for_rst(hw, vf)) {
+ adapter->vf_data[vf].clear_to_send = false;
+ igb_vf_reset_event(adapter, vf);
+ }
+
+ /* process any messages pending */
+ if (!igb_check_for_msg(hw, vf))
+ igb_rcv_msg_from_vf(adapter, vf);
+
+ /* process any acks */
+ if (!igb_check_for_ack(hw, vf))
+ igb_rcv_ack_from_vf(adapter, vf);
+
+ }
+}
+
+static int igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf)
+{
+ u32 mbx_size = E1000_VFMAILBOX_SIZE;
+ u32 msgbuf[mbx_size];
+ struct e1000_hw *hw = &adapter->hw;
+ s32 retval;
+
+ retval = igb_read_mbx(hw, msgbuf, mbx_size, vf);
+
+ if (retval)
+ dev_err(&adapter->pdev->dev,
+ "Error receiving message from VF\n");
+
+ /* this is a message we already processed, do nothing */
+ if (msgbuf[0] & (E1000_VT_MSGTYPE_ACK | E1000_VT_MSGTYPE_NACK))
+ return retval;
+
+ /*
+ * until the vf completes a reset it should not be
+ * allowed to start any configuration.
+ */
+
+ if (msgbuf[0] == E1000_VF_RESET) {
+ igb_vf_reset_msg(adapter, vf);
+
+ return retval;
+ }
+
+ if (!adapter->vf_data[vf].clear_to_send) {
+ msgbuf[0] |= E1000_VT_MSGTYPE_NACK;
+ igb_write_mbx(hw, msgbuf, 1, vf);
+ return retval;
+ }
+
+ switch ((msgbuf[0] & 0xFFFF)) {
+ case E1000_VF_SET_MAC_ADDR:
+ retval = igb_set_vf_mac_addr(adapter, msgbuf, vf);
+ break;
+ case E1000_VF_SET_MULTICAST:
+ retval = igb_set_vf_multicasts(adapter, msgbuf, vf);
+ break;
+ case E1000_VF_SET_LPE:
+ retval = igb_set_vf_rlpml(adapter, msgbuf[1], vf);
+ break;
+ case E1000_VF_SET_VLAN:
+ retval = igb_set_vf_vlan(adapter, msgbuf, vf);
+ break;
+ default:
+ dev_err(&adapter->pdev->dev, "Unhandled Msg %08x\n", msgbuf[0]);
+ retval = -1;
+ break;
+ }
+
+ /* notify the VF of the results of what it sent us */
+ if (retval)
+ msgbuf[0] |= E1000_VT_MSGTYPE_NACK;
+ else
+ msgbuf[0] |= E1000_VT_MSGTYPE_ACK;
+
+ msgbuf[0] |= E1000_VT_MSGTYPE_CTS;
+
+ igb_write_mbx(hw, msgbuf, 1, vf);
+
+ return retval;
+}
+
/**
* igb_intr_msi - Interrupt Handler
* @irq: interrupt number
@@ -3507,19 +4123,24 @@ static irqreturn_t igb_intr_msi(int irq, void *data)
igb_write_itr(adapter->rx_ring);
+ if(icr & E1000_ICR_DOUTSYNC) {
+ /* HW is reporting DMA is out of sync */
+ adapter->stats.doosync++;
+ }
+
if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
hw->mac.get_link_status = 1;
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- netif_rx_schedule(&adapter->rx_ring[0].napi);
+ napi_schedule(&adapter->rx_ring[0].napi);
return IRQ_HANDLED;
}
/**
- * igb_intr - Interrupt Handler
+ * igb_intr - Legacy Interrupt Handler
* @irq: interrupt number
* @data: pointer to a network interface device structure
**/
@@ -3531,7 +4152,6 @@ static irqreturn_t igb_intr(int irq, void *data)
/* Interrupt Auto-Mask...upon reading ICR, interrupts are masked. No
* need for the IMC write */
u32 icr = rd32(E1000_ICR);
- u32 eicr = 0;
if (!icr)
return IRQ_NONE; /* Not our interrupt */
@@ -3542,7 +4162,10 @@ static irqreturn_t igb_intr(int irq, void *data)
if (!(icr & E1000_ICR_INT_ASSERTED))
return IRQ_NONE;
- eicr = rd32(E1000_EICR);
+ if(icr & E1000_ICR_DOUTSYNC) {
+ /* HW is reporting DMA is out of sync */
+ adapter->stats.doosync++;
+ }
if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
hw->mac.get_link_status = 1;
@@ -3551,11 +4174,31 @@ static irqreturn_t igb_intr(int irq, void *data)
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- netif_rx_schedule(&adapter->rx_ring[0].napi);
+ napi_schedule(&adapter->rx_ring[0].napi);
return IRQ_HANDLED;
}
+static inline void igb_rx_irq_enable(struct igb_ring *rx_ring)
+{
+ struct igb_adapter *adapter = rx_ring->adapter;
+ struct e1000_hw *hw = &adapter->hw;
+
+ if (adapter->itr_setting & 3) {
+ if (adapter->num_rx_queues == 1)
+ igb_set_itr(adapter);
+ else
+ igb_update_ring_itr(rx_ring);
+ }
+
+ if (!test_bit(__IGB_DOWN, &adapter->state)) {
+ if (adapter->msix_entries)
+ wr32(E1000_EIMS, rx_ring->eims_value);
+ else
+ igb_irq_enable(adapter);
+ }
+}
+
/**
* igb_poll - NAPI Rx polling callback
* @napi: napi polling structure
@@ -3564,70 +4207,64 @@ static irqreturn_t igb_intr(int irq, void *data)
static int igb_poll(struct napi_struct *napi, int budget)
{
struct igb_ring *rx_ring = container_of(napi, struct igb_ring, napi);
- struct igb_adapter *adapter = rx_ring->adapter;
- struct net_device *netdev = adapter->netdev;
- int tx_clean_complete, work_done = 0;
+ int work_done = 0;
- /* this poll routine only supports one tx and one rx queue */
#ifdef CONFIG_IGB_DCA
- if (adapter->flags & IGB_FLAG_DCA_ENABLED)
- igb_update_tx_dca(&adapter->tx_ring[0]);
+ if (rx_ring->adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_rx_dca(rx_ring);
#endif
- tx_clean_complete = igb_clean_tx_irq(&adapter->tx_ring[0]);
+ igb_clean_rx_irq_adv(rx_ring, &work_done, budget);
+ if (rx_ring->buddy) {
#ifdef CONFIG_IGB_DCA
- if (adapter->flags & IGB_FLAG_DCA_ENABLED)
- igb_update_rx_dca(&adapter->rx_ring[0]);
+ if (rx_ring->adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_tx_dca(rx_ring->buddy);
#endif
- igb_clean_rx_irq_adv(&adapter->rx_ring[0], &work_done, budget);
+ if (!igb_clean_tx_irq(rx_ring->buddy))
+ work_done = budget;
+ }
- /* If no Tx and not enough Rx work done, exit the polling mode */
- if ((tx_clean_complete && (work_done < budget)) ||
- !netif_running(netdev)) {
- if (adapter->itr_setting & 3)
- igb_set_itr(adapter);
- netif_rx_complete(napi);
- if (!test_bit(__IGB_DOWN, &adapter->state))
- igb_irq_enable(adapter);
- return 0;
+ /* If not enough Rx work done, exit the polling mode */
+ if (work_done < budget) {
+ napi_complete(napi);
+ igb_rx_irq_enable(rx_ring);
}
- return 1;
+ return work_done;
}
-static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
+/**
+ * igb_hwtstamp - utility function which checks for TX time stamp
+ * @adapter: board private structure
+ * @skb: packet that was just sent
+ *
+ * If we were asked to do hardware stamping and such a time stamp is
+ * available, then it must have been for this skb here because we only
+ * allow only one such packet into the queue.
+ */
+static void igb_tx_hwtstamp(struct igb_adapter *adapter, struct sk_buff *skb)
{
- struct igb_ring *rx_ring = container_of(napi, struct igb_ring, napi);
- struct igb_adapter *adapter = rx_ring->adapter;
+ union skb_shared_tx *shtx = skb_tx(skb);
struct e1000_hw *hw = &adapter->hw;
- struct net_device *netdev = adapter->netdev;
- int work_done = 0;
-#ifdef CONFIG_IGB_DCA
- if (adapter->flags & IGB_FLAG_DCA_ENABLED)
- igb_update_rx_dca(rx_ring);
-#endif
- igb_clean_rx_irq_adv(rx_ring, &work_done, budget);
-
-
- /* If not enough Rx work done, exit the polling mode */
- if ((work_done == 0) || !netif_running(netdev)) {
- netif_rx_complete(napi);
-
- if (adapter->itr_setting & 3) {
- if (adapter->num_rx_queues == 1)
- igb_set_itr(adapter);
- else
- igb_update_ring_itr(rx_ring);
+ if (unlikely(shtx->hardware)) {
+ u32 valid = rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID;
+ if (valid) {
+ u64 regval = rd32(E1000_TXSTMPL);
+ u64 ns;
+ struct skb_shared_hwtstamps shhwtstamps;
+
+ memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+ regval |= (u64)rd32(E1000_TXSTMPH) << 32;
+ ns = timecounter_cyc2time(&adapter->clock,
+ regval);
+ timecompare_update(&adapter->compare, ns);
+ shhwtstamps.hwtstamp = ns_to_ktime(ns);
+ shhwtstamps.syststamp =
+ timecompare_transform(&adapter->compare, ns);
+ skb_tstamp_tx(skb, &shhwtstamps);
}
-
- if (!test_bit(__IGB_DOWN, &adapter->state))
- wr32(E1000_EIMS, rx_ring->eims_value);
-
- return 0;
}
-
- return 1;
}
/**
@@ -3668,6 +4305,8 @@ static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
skb->len;
total_packets += segs;
total_bytes += bytecount;
+
+ igb_tx_hwtstamp(adapter, skb);
}
igb_unmap_and_free_tx_resource(adapter, buffer_info);
@@ -3677,7 +4316,6 @@ static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
if (i == tx_ring->count)
i = 0;
}
-
eop = tx_ring->buffer_info[i].next_to_watch;
eop_desc = E1000_TX_DESC_ADV(*tx_ring, eop);
}
@@ -3686,7 +4324,7 @@ static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
if (unlikely(count &&
netif_carrier_ok(netdev) &&
- IGB_DESC_UNUSED(tx_ring) >= IGB_TX_QUEUE_WAKE)) {
+ igb_desc_unused(tx_ring) >= IGB_TX_QUEUE_WAKE)) {
/* Make sure that anybody stopping the queue after this
* sees the new next_to_clean.
*/
@@ -3742,44 +4380,11 @@ static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
return (count < tx_ring->count);
}
-#ifdef CONFIG_IGB_LRO
- /**
- * igb_get_skb_hdr - helper function for LRO header processing
- * @skb: pointer to sk_buff to be added to LRO packet
- * @iphdr: pointer to ip header structure
- * @tcph: pointer to tcp header structure
- * @hdr_flags: pointer to header flags
- * @priv: pointer to the receive descriptor for the current sk_buff
- **/
-static int igb_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
- u64 *hdr_flags, void *priv)
-{
- union e1000_adv_rx_desc *rx_desc = priv;
- u16 pkt_type = rx_desc->wb.lower.lo_dword.pkt_info &
- (E1000_RXDADV_PKTTYPE_IPV4 | E1000_RXDADV_PKTTYPE_TCP);
-
- /* Verify that this is a valid IPv4 TCP packet */
- if (pkt_type != (E1000_RXDADV_PKTTYPE_IPV4 |
- E1000_RXDADV_PKTTYPE_TCP))
- return -1;
-
- /* Set network headers */
- skb_reset_network_header(skb);
- skb_set_transport_header(skb, ip_hdrlen(skb));
- *iphdr = ip_hdr(skb);
- *tcph = tcp_hdr(skb);
- *hdr_flags = LRO_IPV4 | LRO_TCP;
-
- return 0;
-
-}
-#endif /* CONFIG_IGB_LRO */
-
/**
* igb_receive_skb - helper function to handle rx indications
- * @ring: pointer to receive ring receving this packet
+ * @ring: pointer to receive ring receving this packet
* @status: descriptor status field as written by hardware
- * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
+ * @rx_desc: receive descriptor containing vlan and type information.
* @skb: pointer to sk_buff to be indicated to stack
**/
static void igb_receive_skb(struct igb_ring *ring, u8 status,
@@ -3789,31 +4394,23 @@ static void igb_receive_skb(struct igb_ring *ring, u8 status,
struct igb_adapter * adapter = ring->adapter;
bool vlan_extracted = (adapter->vlgrp && (status & E1000_RXD_STAT_VP));
-#ifdef CONFIG_IGB_LRO
- if (adapter->netdev->features & NETIF_F_LRO &&
- skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ skb_record_rx_queue(skb, ring->queue_index);
+ if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
if (vlan_extracted)
- lro_vlan_hwaccel_receive_skb(&ring->lro_mgr, skb,
- adapter->vlgrp,
- le16_to_cpu(rx_desc->wb.upper.vlan),
- rx_desc);
+ vlan_gro_receive(&ring->napi, adapter->vlgrp,
+ le16_to_cpu(rx_desc->wb.upper.vlan),
+ skb);
else
- lro_receive_skb(&ring->lro_mgr,skb, rx_desc);
- ring->lro_used = 1;
+ napi_gro_receive(&ring->napi, skb);
} else {
-#endif
if (vlan_extracted)
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
le16_to_cpu(rx_desc->wb.upper.vlan));
else
-
netif_receive_skb(skb);
-#ifdef CONFIG_IGB_LRO
}
-#endif
}
-
static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
u32 status_err, struct sk_buff *skb)
{
@@ -3841,17 +4438,19 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
{
struct igb_adapter *adapter = rx_ring->adapter;
struct net_device *netdev = adapter->netdev;
+ struct e1000_hw *hw = &adapter->hw;
struct pci_dev *pdev = adapter->pdev;
union e1000_adv_rx_desc *rx_desc , *next_rxd;
struct igb_buffer *buffer_info , *next_buffer;
struct sk_buff *skb;
- unsigned int i;
- u32 length, hlen, staterr;
bool cleaned = false;
int cleaned_count = 0;
unsigned int total_bytes = 0, total_packets = 0;
+ unsigned int i;
+ u32 length, hlen, staterr;
i = rx_ring->next_to_clean;
+ buffer_info = &rx_ring->buffer_info[i];
rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
@@ -3859,25 +4458,22 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
if (*work_done >= budget)
break;
(*work_done)++;
- buffer_info = &rx_ring->buffer_info[i];
- /* HW will not DMA in data larger than the given buffer, even
- * if it parses the (NFS, of course) header to be larger. In
- * that case, it fills the header buffer and spills the rest
- * into the page.
- */
- hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
- E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
- if (hlen > adapter->rx_ps_hdr_size)
- hlen = adapter->rx_ps_hdr_size;
+ skb = buffer_info->skb;
+ prefetch(skb->data - NET_IP_ALIGN);
+ buffer_info->skb = NULL;
+
+ i++;
+ if (i == rx_ring->count)
+ i = 0;
+ next_rxd = E1000_RX_DESC_ADV(*rx_ring, i);
+ prefetch(next_rxd);
+ next_buffer = &rx_ring->buffer_info[i];
length = le16_to_cpu(rx_desc->wb.upper.length);
cleaned = true;
cleaned_count++;
- skb = buffer_info->skb;
- prefetch(skb->data - NET_IP_ALIGN);
- buffer_info->skb = NULL;
if (!adapter->rx_ps_hdr_size) {
pci_unmap_single(pdev, buffer_info->dma,
adapter->rx_buffer_len +
@@ -3887,10 +4483,19 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
goto send_up;
}
+ /* HW will not DMA in data larger than the given buffer, even
+ * if it parses the (NFS, of course) header to be larger. In
+ * that case, it fills the header buffer and spills the rest
+ * into the page.
+ */
+ hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
+ E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
+ if (hlen > adapter->rx_ps_hdr_size)
+ hlen = adapter->rx_ps_hdr_size;
+
if (!skb_shinfo(skb)->nr_frags) {
pci_unmap_single(pdev, buffer_info->dma,
- adapter->rx_ps_hdr_size +
- NET_IP_ALIGN,
+ adapter->rx_ps_hdr_size + NET_IP_ALIGN,
PCI_DMA_FROMDEVICE);
skb_put(skb, hlen);
}
@@ -3916,13 +4521,6 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
skb->truesize += length;
}
-send_up:
- i++;
- if (i == rx_ring->count)
- i = 0;
- next_rxd = E1000_RX_DESC_ADV(*rx_ring, i);
- prefetch(next_rxd);
- next_buffer = &rx_ring->buffer_info[i];
if (!(staterr & E1000_RXD_STAT_EOP)) {
buffer_info->skb = next_buffer->skb;
@@ -3931,6 +4529,47 @@ send_up:
next_buffer->dma = 0;
goto next_desc;
}
+send_up:
+ /*
+ * If this bit is set, then the RX registers contain
+ * the time stamp. No other packet will be time
+ * stamped until we read these registers, so read the
+ * registers to make them available again. Because
+ * only one packet can be time stamped at a time, we
+ * know that the register values must belong to this
+ * one here and therefore we don't need to compare
+ * any of the additional attributes stored for it.
+ *
+ * If nothing went wrong, then it should have a
+ * skb_shared_tx that we can turn into a
+ * skb_shared_hwtstamps.
+ *
+ * TODO: can time stamping be triggered (thus locking
+ * the registers) without the packet reaching this point
+ * here? In that case RX time stamping would get stuck.
+ *
+ * TODO: in "time stamp all packets" mode this bit is
+ * not set. Need a global flag for this mode and then
+ * always read the registers. Cannot be done without
+ * a race condition.
+ */
+ if (unlikely(staterr & E1000_RXD_STAT_TS)) {
+ u64 regval;
+ u64 ns;
+ struct skb_shared_hwtstamps *shhwtstamps =
+ skb_hwtstamps(skb);
+
+ WARN(!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID),
+ "igb: no RX time stamp available for time stamped packet");
+ regval = rd32(E1000_RXSTMPL);
+ regval |= (u64)rd32(E1000_RXSTMPH) << 32;
+ ns = timecounter_cyc2time(&adapter->clock, regval);
+ timecompare_update(&adapter->compare, ns);
+ memset(shhwtstamps, 0, sizeof(*shhwtstamps));
+ shhwtstamps->hwtstamp = ns_to_ktime(ns);
+ shhwtstamps->syststamp =
+ timecompare_transform(&adapter->compare, ns);
+ }
if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
dev_kfree_skb_irq(skb);
@@ -3958,19 +4597,11 @@ next_desc:
/* use prefetched values */
rx_desc = next_rxd;
buffer_info = next_buffer;
-
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
}
rx_ring->next_to_clean = i;
- cleaned_count = IGB_DESC_UNUSED(rx_ring);
-
-#ifdef CONFIG_IGB_LRO
- if (rx_ring->lro_used) {
- lro_flush_all(&rx_ring->lro_mgr);
- rx_ring->lro_used = 0;
- }
-#endif
+ cleaned_count = igb_desc_unused(rx_ring);
if (cleaned_count)
igb_alloc_rx_buffers_adv(rx_ring, cleaned_count);
@@ -3984,7 +4615,6 @@ next_desc:
return cleaned;
}
-
/**
* igb_alloc_rx_buffers_adv - Replace used receive buffers; packet split
* @adapter: address of board private structure
@@ -3999,10 +4629,17 @@ static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring,
struct igb_buffer *buffer_info;
struct sk_buff *skb;
unsigned int i;
+ int bufsz;
i = rx_ring->next_to_use;
buffer_info = &rx_ring->buffer_info[i];
+ if (adapter->rx_ps_hdr_size)
+ bufsz = adapter->rx_ps_hdr_size;
+ else
+ bufsz = adapter->rx_buffer_len;
+ bufsz += NET_IP_ALIGN;
+
while (cleaned_count--) {
rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
@@ -4018,23 +4655,14 @@ static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring,
buffer_info->page_offset ^= PAGE_SIZE / 2;
}
buffer_info->page_dma =
- pci_map_page(pdev,
- buffer_info->page,
+ pci_map_page(pdev, buffer_info->page,
buffer_info->page_offset,
PAGE_SIZE / 2,
PCI_DMA_FROMDEVICE);
}
if (!buffer_info->skb) {
- int bufsz;
-
- if (adapter->rx_ps_hdr_size)
- bufsz = adapter->rx_ps_hdr_size;
- else
- bufsz = adapter->rx_buffer_len;
- bufsz += NET_IP_ALIGN;
skb = netdev_alloc_skb(netdev, bufsz);
-
if (!skb) {
adapter->alloc_rx_buff_failed++;
goto no_buffers;
@@ -4050,7 +4678,6 @@ static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring,
buffer_info->dma = pci_map_single(pdev, skb->data,
bufsz,
PCI_DMA_FROMDEVICE);
-
}
/* Refresh the desc even if buffer_addrs didn't change because
* each write-back erases this info. */
@@ -4120,6 +4747,163 @@ static int igb_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
}
/**
+ * igb_hwtstamp_ioctl - control hardware time stamping
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ *
+ * Outgoing time stamping can be enabled and disabled. Play nice and
+ * disable it when requested, although it shouldn't case any overhead
+ * when no packet needs it. At most one packet in the queue may be
+ * marked for time stamping, otherwise it would be impossible to tell
+ * for sure to which packet the hardware time stamp belongs.
+ *
+ * Incoming time stamping has to be configured via the hardware
+ * filters. Not all combinations are supported, in particular event
+ * type has to be specified. Matching the kind of event packet is
+ * not supported, with the exception of "all V2 events regardless of
+ * level 2 or 4".
+ *
+ **/
+static int igb_hwtstamp_ioctl(struct net_device *netdev,
+ struct ifreq *ifr, int cmd)
+{
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ struct hwtstamp_config config;
+ u32 tsync_tx_ctl_bit = E1000_TSYNCTXCTL_ENABLED;
+ u32 tsync_rx_ctl_bit = E1000_TSYNCRXCTL_ENABLED;
+ u32 tsync_rx_ctl_type = 0;
+ u32 tsync_rx_cfg = 0;
+ int is_l4 = 0;
+ int is_l2 = 0;
+ short port = 319; /* PTP */
+ u32 regval;
+
+ if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+ return -EFAULT;
+
+ /* reserved for future extensions */
+ if (config.flags)
+ return -EINVAL;
+
+ switch (config.tx_type) {
+ case HWTSTAMP_TX_OFF:
+ tsync_tx_ctl_bit = 0;
+ break;
+ case HWTSTAMP_TX_ON:
+ tsync_tx_ctl_bit = E1000_TSYNCTXCTL_ENABLED;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ switch (config.rx_filter) {
+ case HWTSTAMP_FILTER_NONE:
+ tsync_rx_ctl_bit = 0;
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+ case HWTSTAMP_FILTER_ALL:
+ /*
+ * register TSYNCRXCFG must be set, therefore it is not
+ * possible to time stamp both Sync and Delay_Req messages
+ * => fall back to time stamping all packets
+ */
+ tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_ALL;
+ config.rx_filter = HWTSTAMP_FILTER_ALL;
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+ tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L4_V1;
+ tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE;
+ is_l4 = 1;
+ break;
+ case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+ tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L4_V1;
+ tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE;
+ is_l4 = 1;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+ tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
+ tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE;
+ is_l2 = 1;
+ is_l4 = 1;
+ config.rx_filter = HWTSTAMP_FILTER_SOME;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+ case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+ tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
+ tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE;
+ is_l2 = 1;
+ is_l4 = 1;
+ config.rx_filter = HWTSTAMP_FILTER_SOME;
+ break;
+ case HWTSTAMP_FILTER_PTP_V2_EVENT:
+ case HWTSTAMP_FILTER_PTP_V2_SYNC:
+ case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+ tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_EVENT_V2;
+ config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+ is_l2 = 1;
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ /* enable/disable TX */
+ regval = rd32(E1000_TSYNCTXCTL);
+ regval = (regval & ~E1000_TSYNCTXCTL_ENABLED) | tsync_tx_ctl_bit;
+ wr32(E1000_TSYNCTXCTL, regval);
+
+ /* enable/disable RX, define which PTP packets are time stamped */
+ regval = rd32(E1000_TSYNCRXCTL);
+ regval = (regval & ~E1000_TSYNCRXCTL_ENABLED) | tsync_rx_ctl_bit;
+ regval = (regval & ~0xE) | tsync_rx_ctl_type;
+ wr32(E1000_TSYNCRXCTL, regval);
+ wr32(E1000_TSYNCRXCFG, tsync_rx_cfg);
+
+ /*
+ * Ethertype Filter Queue Filter[0][15:0] = 0x88F7
+ * (Ethertype to filter on)
+ * Ethertype Filter Queue Filter[0][26] = 0x1 (Enable filter)
+ * Ethertype Filter Queue Filter[0][30] = 0x1 (Enable Timestamping)
+ */
+ wr32(E1000_ETQF0, is_l2 ? 0x440088f7 : 0);
+
+ /* L4 Queue Filter[0]: only filter by source and destination port */
+ wr32(E1000_SPQF0, htons(port));
+ wr32(E1000_IMIREXT(0), is_l4 ?
+ ((1<<12) | (1<<19) /* bypass size and control flags */) : 0);
+ wr32(E1000_IMIR(0), is_l4 ?
+ (htons(port)
+ | (0<<16) /* immediate interrupt disabled */
+ | 0 /* (1<<17) bit cleared: do not bypass
+ destination port check */)
+ : 0);
+ wr32(E1000_FTQF0, is_l4 ?
+ (0x11 /* UDP */
+ | (1<<15) /* VF not compared */
+ | (1<<27) /* Enable Timestamping */
+ | (7<<28) /* only source port filter enabled,
+ source/target address and protocol
+ masked */)
+ : ((1<<15) | (15<<28) /* all mask bits set = filter not
+ enabled */));
+
+ wrfl();
+
+ adapter->hwtstamp_config = config;
+
+ /* clear TX/RX time stamp registers, just to be sure */
+ regval = rd32(E1000_TXSTMPH);
+ regval = rd32(E1000_RXSTMPH);
+
+ return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+ -EFAULT : 0;
+}
+
+/**
* igb_ioctl -
* @netdev:
* @ifreq:
@@ -4132,6 +4916,8 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
case SIOCGMIIREG:
case SIOCSMIIREG:
return igb_mii_ioctl(netdev, ifr, cmd);
+ case SIOCSHWTSTAMP:
+ return igb_hwtstamp_ioctl(netdev, ifr, cmd);
default:
return -EOPNOTSUPP;
}
@@ -4158,8 +4944,6 @@ static void igb_vlan_rx_register(struct net_device *netdev,
rctl &= ~E1000_RCTL_CFIEN;
wr32(E1000_RCTL, rctl);
igb_update_mng_vlan(adapter);
- wr32(E1000_RLPML,
- adapter->max_frame_size + VLAN_TAG_SIZE);
} else {
/* disable VLAN tag insert/strip */
ctrl = rd32(E1000_CTRL);
@@ -4170,10 +4954,10 @@ static void igb_vlan_rx_register(struct net_device *netdev,
igb_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
}
- wr32(E1000_RLPML,
- adapter->max_frame_size);
}
+ igb_rlpml_set(adapter);
+
if (!test_bit(__IGB_DOWN, &adapter->state))
igb_irq_enable(adapter);
}
@@ -4182,24 +4966,25 @@ static void igb_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- u32 vfta, index;
+ int pf_id = adapter->vfs_allocated_count;
- if ((adapter->hw.mng_cookie.status &
+ if ((hw->mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
(vid == adapter->mng_vlan_id))
return;
- /* add VID to filter table */
- index = (vid >> 5) & 0x7F;
- vfta = array_rd32(E1000_VFTA, index);
- vfta |= (1 << (vid & 0x1F));
- igb_write_vfta(&adapter->hw, index, vfta);
+
+ /* add vid to vlvf if sr-iov is enabled,
+ * if that fails add directly to filter table */
+ if (igb_vlvf_set(adapter, vid, true, pf_id))
+ igb_vfta_set(hw, vid, true);
+
}
static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- u32 vfta, index;
+ int pf_id = adapter->vfs_allocated_count;
igb_irq_disable(adapter);
vlan_group_set_device(adapter->vlgrp, vid, NULL);
@@ -4215,11 +5000,10 @@ static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
return;
}
- /* remove VID from filter table */
- index = (vid >> 5) & 0x7F;
- vfta = array_rd32(E1000_VFTA, index);
- vfta &= ~(1 << (vid & 0x1F));
- igb_write_vfta(&adapter->hw, index, vfta);
+ /* remove vid from vlvf if sr-iov is enabled,
+ * if not in vlvf remove from vfta */
+ if (igb_vlvf_set(adapter, vid, false, pf_id))
+ igb_vfta_set(hw, vid, false);
}
static void igb_restore_vlan(struct igb_adapter *adapter)
@@ -4276,8 +5060,7 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
return 0;
}
-
-static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
@@ -4336,15 +5119,9 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
wr32(E1000_WUFC, 0);
}
- /* make sure adapter isn't asleep if manageability/wol is enabled */
- if (wufc || adapter->en_mng_pt) {
- pci_enable_wake(pdev, PCI_D3hot, 1);
- pci_enable_wake(pdev, PCI_D3cold, 1);
- } else {
+ *enable_wake = wufc || adapter->en_mng_pt;
+ if (!*enable_wake)
igb_shutdown_fiber_serdes_link_82575(hw);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
- }
/* Release control of h/w to f/w. If f/w is AMT enabled, this
* would have already happened in close and is redundant. */
@@ -4352,12 +5129,29 @@ static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
return 0;
}
#ifdef CONFIG_PM
+static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ int retval;
+ bool wake;
+
+ retval = __igb_shutdown(pdev, &wake);
+ if (retval)
+ return retval;
+
+ if (wake) {
+ pci_prepare_to_sleep(pdev);
+ } else {
+ pci_wake_from_d3(pdev, false);
+ pci_set_power_state(pdev, PCI_D3hot);
+ }
+
+ return 0;
+}
+
static int igb_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
@@ -4368,10 +5162,7 @@ static int igb_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
- if (adapter->need_ioport)
- err = pci_enable_device(pdev);
- else
- err = pci_enable_device_mem(pdev);
+ err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
"igb: Cannot enable PCI device from suspend\n");
@@ -4392,6 +5183,11 @@ static int igb_resume(struct pci_dev *pdev)
/* e1000_power_up_phy(adapter); */
igb_reset(adapter);
+
+ /* let the f/w know that the h/w is now under the control of the
+ * driver. */
+ igb_get_hw_control(adapter);
+
wr32(E1000_WUS, ~0);
if (netif_running(netdev)) {
@@ -4402,17 +5198,20 @@ static int igb_resume(struct pci_dev *pdev)
netif_device_attach(netdev);
- /* let the f/w know that the h/w is now under the control of the
- * driver. */
- igb_get_hw_control(adapter);
-
return 0;
}
#endif
static void igb_shutdown(struct pci_dev *pdev)
{
- igb_suspend(pdev, PMSG_SUSPEND);
+ bool wake;
+
+ __igb_shutdown(pdev, &wake);
+
+ if (system_state == SYSTEM_POWER_OFF) {
+ pci_wake_from_d3(pdev, wake);
+ pci_set_power_state(pdev, PCI_D3hot);
+ }
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -4424,22 +5223,27 @@ static void igb_shutdown(struct pci_dev *pdev)
static void igb_netpoll(struct net_device *netdev)
{
struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
int i;
- int work_done = 0;
- igb_irq_disable(adapter);
- adapter->flags |= IGB_FLAG_IN_NETPOLL;
-
- for (i = 0; i < adapter->num_tx_queues; i++)
- igb_clean_tx_irq(&adapter->tx_ring[i]);
+ if (!adapter->msix_entries) {
+ igb_irq_disable(adapter);
+ napi_schedule(&adapter->rx_ring[0].napi);
+ return;
+ }
- for (i = 0; i < adapter->num_rx_queues; i++)
- igb_clean_rx_irq_adv(&adapter->rx_ring[i],
- &work_done,
- adapter->rx_ring[i].napi.weight);
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ struct igb_ring *tx_ring = &adapter->tx_ring[i];
+ wr32(E1000_EIMC, tx_ring->eims_value);
+ igb_clean_tx_irq(tx_ring);
+ wr32(E1000_EIMS, tx_ring->eims_value);
+ }
- adapter->flags &= ~IGB_FLAG_IN_NETPOLL;
- igb_irq_enable(adapter);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ struct igb_ring *rx_ring = &adapter->rx_ring[i];
+ wr32(E1000_EIMC, rx_ring->eims_value);
+ napi_schedule(&rx_ring->napi);
+ }
}
#endif /* CONFIG_NET_POLL_CONTROLLER */
@@ -4482,12 +5286,7 @@ static pci_ers_result_t igb_io_slot_reset(struct pci_dev *pdev)
pci_ers_result_t result;
int err;
- if (adapter->need_ioport)
- err = pci_enable_device(pdev);
- else
- err = pci_enable_device_mem(pdev);
-
- if (err) {
+ if (pci_enable_device_mem(pdev)) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
result = PCI_ERS_RESULT_DISCONNECT;
@@ -4540,4 +5339,172 @@ static void igb_io_resume(struct pci_dev *pdev)
igb_get_hw_control(adapter);
}
+static inline void igb_set_vmolr(struct e1000_hw *hw, int vfn)
+{
+ u32 reg_data;
+
+ reg_data = rd32(E1000_VMOLR(vfn));
+ reg_data |= E1000_VMOLR_BAM | /* Accept broadcast */
+ E1000_VMOLR_ROPE | /* Accept packets matched in UTA */
+ E1000_VMOLR_ROMPE | /* Accept packets matched in MTA */
+ E1000_VMOLR_AUPE | /* Accept untagged packets */
+ E1000_VMOLR_STRVLAN; /* Strip vlan tags */
+ wr32(E1000_VMOLR(vfn), reg_data);
+}
+
+static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size,
+ int vfn)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 vmolr;
+
+ vmolr = rd32(E1000_VMOLR(vfn));
+ vmolr &= ~E1000_VMOLR_RLPML_MASK;
+ vmolr |= size | E1000_VMOLR_LPE;
+ wr32(E1000_VMOLR(vfn), vmolr);
+
+ return 0;
+}
+
+static inline void igb_set_rah_pool(struct e1000_hw *hw, int pool, int entry)
+{
+ u32 reg_data;
+
+ reg_data = rd32(E1000_RAH(entry));
+ reg_data &= ~E1000_RAH_POOL_MASK;
+ reg_data |= E1000_RAH_POOL_1 << pool;;
+ wr32(E1000_RAH(entry), reg_data);
+}
+
+static void igb_set_mc_list_pools(struct igb_adapter *adapter,
+ int entry_count, u16 total_rar_filters)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ int i = adapter->vfs_allocated_count + 1;
+
+ if ((i + entry_count) < total_rar_filters)
+ total_rar_filters = i + entry_count;
+
+ for (; i < total_rar_filters; i++)
+ igb_set_rah_pool(hw, adapter->vfs_allocated_count, i);
+}
+
+static int igb_set_vf_mac(struct igb_adapter *adapter,
+ int vf, unsigned char *mac_addr)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ int rar_entry = vf + 1; /* VF MAC addresses start at entry 1 */
+
+ igb_rar_set(hw, mac_addr, rar_entry);
+
+ memcpy(adapter->vf_data[vf].vf_mac_addresses, mac_addr, ETH_ALEN);
+
+ igb_set_rah_pool(hw, vf, rar_entry);
+
+ return 0;
+}
+
+static void igb_vmm_control(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 reg_data;
+
+ if (!adapter->vfs_allocated_count)
+ return;
+
+ /* VF's need PF reset indication before they
+ * can send/receive mail */
+ reg_data = rd32(E1000_CTRL_EXT);
+ reg_data |= E1000_CTRL_EXT_PFRSTD;
+ wr32(E1000_CTRL_EXT, reg_data);
+
+ igb_vmdq_set_loopback_pf(hw, true);
+ igb_vmdq_set_replication_pf(hw, true);
+}
+
+#ifdef CONFIG_PCI_IOV
+static ssize_t igb_show_num_vfs(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct igb_adapter *adapter = netdev_priv(to_net_dev(dev));
+
+ return sprintf(buf, "%d\n", adapter->vfs_allocated_count);
+}
+
+static ssize_t igb_set_num_vfs(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct net_device *netdev = to_net_dev(dev);
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ struct pci_dev *pdev = adapter->pdev;
+ unsigned int num_vfs, i;
+ unsigned char mac_addr[ETH_ALEN];
+ int err;
+
+ sscanf(buf, "%u", &num_vfs);
+
+ if (num_vfs > 7)
+ num_vfs = 7;
+
+ /* value unchanged do nothing */
+ if (num_vfs == adapter->vfs_allocated_count)
+ return count;
+
+ if (netdev->flags & IFF_UP)
+ igb_close(netdev);
+
+ igb_reset_interrupt_capability(adapter);
+ igb_free_queues(adapter);
+ adapter->tx_ring = NULL;
+ adapter->rx_ring = NULL;
+ adapter->vfs_allocated_count = 0;
+
+ /* reclaim resources allocated to VFs since we are changing count */
+ if (adapter->vf_data) {
+ /* disable iov and allow time for transactions to clear */
+ pci_disable_sriov(pdev);
+ msleep(500);
+
+ kfree(adapter->vf_data);
+ adapter->vf_data = NULL;
+ wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ);
+ msleep(100);
+ dev_info(&pdev->dev, "IOV Disabled\n");
+ }
+
+ if (num_vfs) {
+ adapter->vf_data = kcalloc(num_vfs,
+ sizeof(struct vf_data_storage),
+ GFP_KERNEL);
+ if (!adapter->vf_data) {
+ dev_err(&pdev->dev, "Could not allocate VF private "
+ "data - IOV enable failed\n");
+ } else {
+ err = pci_enable_sriov(pdev, num_vfs);
+ if (!err) {
+ adapter->vfs_allocated_count = num_vfs;
+ dev_info(&pdev->dev, "%d vfs allocated\n", num_vfs);
+ for (i = 0; i < adapter->vfs_allocated_count; i++) {
+ random_ether_addr(mac_addr);
+ igb_set_vf_mac(adapter, i, mac_addr);
+ }
+ } else {
+ kfree(adapter->vf_data);
+ adapter->vf_data = NULL;
+ }
+ }
+ }
+
+ igb_set_interrupt_capability(adapter);
+ igb_alloc_queues(adapter);
+ igb_reset(adapter);
+
+ if (netdev->flags & IFF_UP)
+ igb_open(netdev);
+
+ return count;
+}
+#endif /* CONFIG_PCI_IOV */
/* igb_main.c */
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
index 17779f9bffc4..ad1795580028 100644
--- a/drivers/net/irda/ali-ircc.c
+++ b/drivers/net/irda/ali-ircc.c
@@ -259,6 +259,20 @@ static void __exit ali_ircc_cleanup(void)
IRDA_DEBUG(2, "%s(), ----------------- End -----------------\n", __func__);
}
+static const struct net_device_ops ali_ircc_sir_ops = {
+ .ndo_open = ali_ircc_net_open,
+ .ndo_stop = ali_ircc_net_close,
+ .ndo_start_xmit = ali_ircc_sir_hard_xmit,
+ .ndo_do_ioctl = ali_ircc_net_ioctl,
+};
+
+static const struct net_device_ops ali_ircc_fir_ops = {
+ .ndo_open = ali_ircc_net_open,
+ .ndo_stop = ali_ircc_net_close,
+ .ndo_start_xmit = ali_ircc_fir_hard_xmit,
+ .ndo_do_ioctl = ali_ircc_net_ioctl,
+};
+
/*
* Function ali_ircc_open (int i, chipio_t *inf)
*
@@ -361,10 +375,7 @@ static int ali_ircc_open(int i, chipio_t *info)
self->tx_fifo.tail = self->tx_buff.head;
/* Override the network functions we need to use */
- dev->hard_start_xmit = ali_ircc_sir_hard_xmit;
- dev->open = ali_ircc_net_open;
- dev->stop = ali_ircc_net_close;
- dev->do_ioctl = ali_ircc_net_ioctl;
+ dev->netdev_ops = &ali_ircc_sir_ops;
err = register_netdev(dev);
if (err) {
@@ -974,7 +985,7 @@ static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud)
ali_ircc_fir_change_speed(self, baud);
/* Install FIR xmit handler*/
- dev->hard_start_xmit = ali_ircc_fir_hard_xmit;
+ dev->netdev_ops = &ali_ircc_fir_ops;
/* Enable Interuupt */
self->ier = IER_EOM; // benjamin 2000/11/20 07:24PM
@@ -988,7 +999,7 @@ static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud)
ali_ircc_sir_change_speed(self, baud);
/* Install SIR xmit handler*/
- dev->hard_start_xmit = ali_ircc_sir_hard_xmit;
+ dev->netdev_ops = &ali_ircc_sir_ops;
}
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 6f3e7f71658d..6b6548b9fda0 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -1524,6 +1524,13 @@ toshoboe_close (struct pci_dev *pci_dev)
free_netdev(self->netdev);
}
+static const struct net_device_ops toshoboe_netdev_ops = {
+ .ndo_open = toshoboe_net_open,
+ .ndo_stop = toshoboe_net_close,
+ .ndo_start_xmit = toshoboe_hard_xmit,
+ .ndo_do_ioctl = toshoboe_net_ioctl,
+};
+
static int
toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
{
@@ -1657,10 +1664,7 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
#endif
SET_NETDEV_DEV(dev, &pci_dev->dev);
- dev->hard_start_xmit = toshoboe_hard_xmit;
- dev->open = toshoboe_net_open;
- dev->stop = toshoboe_net_close;
- dev->do_ioctl = toshoboe_net_ioctl;
+ dev->netdev_ops = &toshoboe_netdev_ops;
err = register_netdev(dev);
if (err)
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 3a22dc41b656..006ba23110db 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1401,6 +1401,14 @@ static inline void irda_usb_init_qos(struct irda_usb_cb *self)
}
/*------------------------------------------------------------------*/
+static const struct net_device_ops irda_usb_netdev_ops = {
+ .ndo_open = irda_usb_net_open,
+ .ndo_stop = irda_usb_net_close,
+ .ndo_do_ioctl = irda_usb_net_ioctl,
+ .ndo_start_xmit = irda_usb_hard_xmit,
+ .ndo_tx_timeout = irda_usb_net_timeout,
+};
+
/*
* Initialise the network side of the irda-usb instance
* Called when a new USB instance is registered in irda_usb_probe()
@@ -1411,15 +1419,9 @@ static inline int irda_usb_open(struct irda_usb_cb *self)
IRDA_DEBUG(1, "%s()\n", __func__);
- irda_usb_init_qos(self);
+ netdev->netdev_ops = &irda_usb_netdev_ops;
- /* Override the network functions we need to use */
- netdev->hard_start_xmit = irda_usb_hard_xmit;
- netdev->tx_timeout = irda_usb_net_timeout;
- netdev->watchdog_timeo = 250*HZ/1000; /* 250 ms > USB timeout */
- netdev->open = irda_usb_net_open;
- netdev->stop = irda_usb_net_close;
- netdev->do_ioctl = irda_usb_net_ioctl;
+ irda_usb_init_qos(self);
return register_netdev(netdev);
}
diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c
index b4a61717254a..9d813bc4502e 100644
--- a/drivers/net/irda/kingsun-sir.c
+++ b/drivers/net/irda/kingsun-sir.c
@@ -418,6 +418,12 @@ static int kingsun_net_ioctl(struct net_device *netdev, struct ifreq *rq,
return ret;
}
+static const struct net_device_ops kingsun_ops = {
+ .ndo_start_xmit = kingsun_hard_xmit,
+ .ndo_open = kingsun_net_open,
+ .ndo_stop = kingsun_net_close,
+ .ndo_do_ioctl = kingsun_net_ioctl,
+};
/*
* This routine is called by the USB subsystem for each new device
@@ -520,10 +526,7 @@ static int kingsun_probe(struct usb_interface *intf,
irda_qos_bits_to_value(&kingsun->qos);
/* Override the network functions we need to use */
- net->hard_start_xmit = kingsun_hard_xmit;
- net->open = kingsun_net_open;
- net->stop = kingsun_net_close;
- net->do_ioctl = kingsun_net_ioctl;
+ net->netdev_ops = &kingsun_ops;
ret = register_netdev(net);
if (ret != 0)
diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c
index 55322fb92cf1..b6ffe9715b61 100644
--- a/drivers/net/irda/ks959-sir.c
+++ b/drivers/net/irda/ks959-sir.c
@@ -668,6 +668,12 @@ static int ks959_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
return ret;
}
+static const struct net_device_ops ks959_ops = {
+ .ndo_start_xmit = ks959_hard_xmit,
+ .ndo_open = ks959_net_open,
+ .ndo_stop = ks959_net_close,
+ .ndo_do_ioctl = ks959_net_ioctl,
+};
/*
* This routine is called by the USB subsystem for each new device
* in the system. We need to check if the device is ours, and in
@@ -780,10 +786,7 @@ static int ks959_probe(struct usb_interface *intf,
irda_qos_bits_to_value(&kingsun->qos);
/* Override the network functions we need to use */
- net->hard_start_xmit = ks959_hard_xmit;
- net->open = ks959_net_open;
- net->stop = ks959_net_close;
- net->do_ioctl = ks959_net_ioctl;
+ net->netdev_ops = &ks959_ops;
ret = register_netdev(net);
if (ret != 0)
diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c
index 5b327b09acd8..64df27f2bfd4 100644
--- a/drivers/net/irda/ksdazzle-sir.c
+++ b/drivers/net/irda/ksdazzle-sir.c
@@ -562,6 +562,13 @@ static int ksdazzle_net_ioctl(struct net_device *netdev, struct ifreq *rq,
return ret;
}
+static const struct net_device_ops ksdazzle_ops = {
+ .ndo_start_xmit = ksdazzle_hard_xmit,
+ .ndo_open = ksdazzle_net_open,
+ .ndo_stop = ksdazzle_net_close,
+ .ndo_do_ioctl = ksdazzle_net_ioctl,
+};
+
/*
* This routine is called by the USB subsystem for each new device
* in the system. We need to check if the device is ours, and in
@@ -684,10 +691,7 @@ static int ksdazzle_probe(struct usb_interface *intf,
irda_qos_bits_to_value(&kingsun->qos);
/* Override the network functions we need to use */
- net->hard_start_xmit = ksdazzle_hard_xmit;
- net->open = ksdazzle_net_open;
- net->stop = ksdazzle_net_close;
- net->do_ioctl = ksdazzle_net_ioctl;
+ net->netdev_ops = &ksdazzle_ops;
ret = register_netdev(net);
if (ret != 0)
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index 85e88daab21a..fac504d0cfd8 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -873,6 +873,13 @@ static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
return ret;
}
+static const struct net_device_ops mcs_netdev_ops = {
+ .ndo_open = mcs_net_open,
+ .ndo_stop = mcs_net_close,
+ .ndo_start_xmit = mcs_hard_xmit,
+ .ndo_do_ioctl = mcs_net_ioctl,
+};
+
/*
* This function is called by the USB subsystem for each new device in the
* system. Need to verify the device and if it is, then start handling it.
@@ -919,11 +926,7 @@ static int mcs_probe(struct usb_interface *intf,
/* Speed change work initialisation*/
INIT_WORK(&mcs->work, mcs_speed_work);
- /* Override the network functions we need to use */
- ndev->hard_start_xmit = mcs_hard_xmit;
- ndev->open = mcs_net_open;
- ndev->stop = mcs_net_close;
- ndev->do_ioctl = mcs_net_ioctl;
+ ndev->netdev_ops = &mcs_netdev_ops;
if (!intf->cur_altsetting)
goto error2;
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index 61e509cb712a..45fd9c1eb343 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -331,6 +331,20 @@ static void __exit nsc_ircc_cleanup(void)
pnp_registered = 0;
}
+static const struct net_device_ops nsc_ircc_sir_ops = {
+ .ndo_open = nsc_ircc_net_open,
+ .ndo_stop = nsc_ircc_net_close,
+ .ndo_start_xmit = nsc_ircc_hard_xmit_sir,
+ .ndo_do_ioctl = nsc_ircc_net_ioctl,
+};
+
+static const struct net_device_ops nsc_ircc_fir_ops = {
+ .ndo_open = nsc_ircc_net_open,
+ .ndo_stop = nsc_ircc_net_close,
+ .ndo_start_xmit = nsc_ircc_hard_xmit_fir,
+ .ndo_do_ioctl = nsc_ircc_net_ioctl,
+};
+
/*
* Function nsc_ircc_open (iobase, irq)
*
@@ -441,10 +455,7 @@ static int __init nsc_ircc_open(chipio_t *info)
self->tx_fifo.tail = self->tx_buff.head;
/* Override the network functions we need to use */
- dev->hard_start_xmit = nsc_ircc_hard_xmit_sir;
- dev->open = nsc_ircc_net_open;
- dev->stop = nsc_ircc_net_close;
- dev->do_ioctl = nsc_ircc_net_ioctl;
+ dev->netdev_ops = &nsc_ircc_sir_ops;
err = register_netdev(dev);
if (err) {
@@ -1320,12 +1331,12 @@ static __u8 nsc_ircc_change_speed(struct nsc_ircc_cb *self, __u32 speed)
switch_bank(iobase, BANK0);
if (speed > 115200) {
/* Install FIR xmit handler */
- dev->hard_start_xmit = nsc_ircc_hard_xmit_fir;
+ dev->netdev_ops = &nsc_ircc_fir_ops;
ier = IER_SFIF_IE;
nsc_ircc_dma_receive(self);
} else {
/* Install SIR xmit handler */
- dev->hard_start_xmit = nsc_ircc_hard_xmit_sir;
+ dev->netdev_ops = &nsc_ircc_sir_ops;
ier = IER_RXHDL_IE;
}
/* Set our current interrupt mask */
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 31794c2363ec..e775338b525f 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -24,9 +24,8 @@
#include <mach/dma.h>
#include <mach/irda.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/regs-uart.h>
+#include <mach/regs-ost.h>
#define FICP __REG(0x40800000) /* Start of FICP area */
#define ICCR0 __REG(0x40800000) /* ICP Control Register 0 */
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index 5b5862499def..d940809762ec 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -753,7 +753,8 @@ static int sirdev_alloc_buffers(struct sir_dev *dev)
dev->rx_buff.truesize = IRDA_SKB_MAX_MTU;
/* Bootstrap ZeroCopy Rx */
- dev->rx_buff.skb = __dev_alloc_skb(dev->rx_buff.truesize, GFP_KERNEL);
+ dev->rx_buff.skb = __netdev_alloc_skb(dev->netdev, dev->rx_buff.truesize,
+ GFP_KERNEL);
if (dev->rx_buff.skb == NULL)
return -ENOMEM;
skb_reserve(dev->rx_buff.skb, 1);
@@ -779,8 +780,7 @@ static int sirdev_alloc_buffers(struct sir_dev *dev)
static void sirdev_free_buffers(struct sir_dev *dev)
{
- if (dev->rx_buff.skb)
- kfree_skb(dev->rx_buff.skb);
+ kfree_skb(dev->rx_buff.skb);
kfree(dev->tx_buff.head);
dev->rx_buff.head = dev->tx_buff.head = NULL;
dev->rx_buff.skb = NULL;
@@ -865,6 +865,12 @@ out:
return 0;
}
+static const struct net_device_ops sirdev_ops = {
+ .ndo_start_xmit = sirdev_hard_xmit,
+ .ndo_open = sirdev_open,
+ .ndo_stop = sirdev_close,
+ .ndo_do_ioctl = sirdev_ioctl,
+};
/* ----------------------------------------------------------------------------- */
struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *name)
@@ -908,10 +914,7 @@ struct sir_dev * sirdev_get_instance(const struct sir_driver *drv, const char *n
dev->netdev = ndev;
/* Override the network functions we need to use */
- ndev->hard_start_xmit = sirdev_hard_xmit;
- ndev->open = sirdev_open;
- ndev->stop = sirdev_close;
- ndev->do_ioctl = sirdev_ioctl;
+ ndev->netdev_ops = &sirdev_ops;
if (register_netdev(ndev)) {
IRDA_ERROR("%s(), register_netdev() failed!\n", __func__);
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index dd73cce10991..59d79807b4d5 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -486,6 +486,26 @@ static int __init smsc_ircc_init(void)
return ret;
}
+static int smsc_ircc_net_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct smsc_ircc_cb *self = netdev_priv(dev);
+
+ if (self->io.speed > 115200)
+ return smsc_ircc_hard_xmit_fir(skb, dev);
+ else
+ return smsc_ircc_hard_xmit_sir(skb, dev);
+}
+
+static const struct net_device_ops smsc_ircc_netdev_ops = {
+ .ndo_open = smsc_ircc_net_open,
+ .ndo_stop = smsc_ircc_net_close,
+ .ndo_do_ioctl = smsc_ircc_net_ioctl,
+ .ndo_start_xmit = smsc_ircc_net_xmit,
+#if SMSC_IRCC2_C_NET_TIMEOUT
+ .ndo_tx_timeout = smsc_ircc_timeout,
+#endif
+};
+
/*
* Function smsc_ircc_open (firbase, sirbase, dma, irq)
*
@@ -519,14 +539,10 @@ static int __init smsc_ircc_open(unsigned int fir_base, unsigned int sir_base, u
goto err_out1;
}
- dev->hard_start_xmit = smsc_ircc_hard_xmit_sir;
#if SMSC_IRCC2_C_NET_TIMEOUT
- dev->tx_timeout = smsc_ircc_timeout;
dev->watchdog_timeo = HZ * 2; /* Allow enough time for speed change */
#endif
- dev->open = smsc_ircc_net_open;
- dev->stop = smsc_ircc_net_close;
- dev->do_ioctl = smsc_ircc_net_ioctl;
+ dev->netdev_ops = &smsc_ircc_netdev_ops;
self = netdev_priv(dev);
self->netdev = dev;
@@ -995,9 +1011,6 @@ static void smsc_ircc_fir_start(struct smsc_ircc_cb *self)
/* Reset everything */
- /* Install FIR transmit handler */
- dev->hard_start_xmit = smsc_ircc_hard_xmit_fir;
-
/* Clear FIFO */
outb(inb(fir_base + IRCC_LCR_A) | IRCC_LCR_A_FIFO_RESET, fir_base + IRCC_LCR_A);
@@ -1894,7 +1907,6 @@ static void smsc_ircc_sir_start(struct smsc_ircc_cb *self)
IRDA_ASSERT(self != NULL, return;);
dev = self->netdev;
IRDA_ASSERT(dev != NULL, return;);
- dev->hard_start_xmit = &smsc_ircc_hard_xmit_sir;
fir_base = self->io.fir_base;
sir_base = self->io.sir_base;
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index 8b1658c6c925..8e5e45caf2f1 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -1007,6 +1007,13 @@ static int stir_net_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
return ret;
}
+static const struct net_device_ops stir_netdev_ops = {
+ .ndo_open = stir_net_open,
+ .ndo_stop = stir_net_close,
+ .ndo_start_xmit = stir_hard_xmit,
+ .ndo_do_ioctl = stir_net_ioctl,
+};
+
/*
* This routine is called by the USB subsystem for each new device
* in the system. We need to check if the device is ours, and in
@@ -1054,10 +1061,7 @@ static int stir_probe(struct usb_interface *intf,
irda_qos_bits_to_value(&stir->qos);
/* Override the network functions we need to use */
- net->hard_start_xmit = stir_hard_xmit;
- net->open = stir_net_open;
- net->stop = stir_net_close;
- net->do_ioctl = stir_net_ioctl;
+ net->netdev_ops = &stir_netdev_ops;
ret = register_netdev(net);
if (ret != 0)
diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c
index 8b3e545924cc..864798502ff9 100644
--- a/drivers/net/irda/via-ircc.c
+++ b/drivers/net/irda/via-ircc.c
@@ -310,6 +310,19 @@ static void __exit via_ircc_cleanup(void)
pci_unregister_driver (&via_driver);
}
+static const struct net_device_ops via_ircc_sir_ops = {
+ .ndo_start_xmit = via_ircc_hard_xmit_sir,
+ .ndo_open = via_ircc_net_open,
+ .ndo_stop = via_ircc_net_close,
+ .ndo_do_ioctl = via_ircc_net_ioctl,
+};
+static const struct net_device_ops via_ircc_fir_ops = {
+ .ndo_start_xmit = via_ircc_hard_xmit_fir,
+ .ndo_open = via_ircc_net_open,
+ .ndo_stop = via_ircc_net_close,
+ .ndo_do_ioctl = via_ircc_net_ioctl,
+};
+
/*
* Function via_ircc_open (iobase, irq)
*
@@ -428,10 +441,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
self->tx_fifo.tail = self->tx_buff.head;
/* Override the network functions we need to use */
- dev->hard_start_xmit = via_ircc_hard_xmit_sir;
- dev->open = via_ircc_net_open;
- dev->stop = via_ircc_net_close;
- dev->do_ioctl = via_ircc_net_ioctl;
+ dev->netdev_ops = &via_ircc_sir_ops;
err = register_netdev(dev);
if (err)
@@ -798,11 +808,11 @@ static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 speed)
if (speed > 115200) {
/* Install FIR xmit handler */
- dev->hard_start_xmit = via_ircc_hard_xmit_fir;
+ dev->netdev_ops = &via_ircc_fir_ops;
via_ircc_dma_receive(self);
} else {
/* Install SIR xmit handler */
- dev->hard_start_xmit = via_ircc_hard_xmit_sir;
+ dev->netdev_ops = &via_ircc_sir_ops;
}
netif_wake_queue(dev);
}
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index 723c4588c803..ac0e4b6b6b66 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -1573,6 +1573,14 @@ static int vlsi_close(struct net_device *ndev)
return 0;
}
+static const struct net_device_ops vlsi_netdev_ops = {
+ .ndo_open = vlsi_open,
+ .ndo_stop = vlsi_close,
+ .ndo_start_xmit = vlsi_hard_start_xmit,
+ .ndo_do_ioctl = vlsi_ioctl,
+ .ndo_tx_timeout = vlsi_tx_timeout,
+};
+
static int vlsi_irda_init(struct net_device *ndev)
{
vlsi_irda_dev_t *idev = netdev_priv(ndev);
@@ -1608,11 +1616,7 @@ static int vlsi_irda_init(struct net_device *ndev)
ndev->flags |= IFF_PORTSEL | IFF_AUTOMEDIA;
ndev->if_port = IF_PORT_UNKNOWN;
- ndev->open = vlsi_open;
- ndev->stop = vlsi_close;
- ndev->hard_start_xmit = vlsi_hard_start_xmit;
- ndev->do_ioctl = vlsi_ioctl;
- ndev->tx_timeout = vlsi_tx_timeout;
+ ndev->netdev_ops = &vlsi_netdev_ops;
ndev->watchdog_timeo = 500*HZ/1000; /* max. allowed turn time for IrLAP */
SET_NETDEV_DEV(ndev, &pdev->dev);
@@ -1867,13 +1871,6 @@ static int __init vlsi_mod_init(void)
* without procfs - it's not required for the driver to work.
*/
vlsi_proc_root = proc_mkdir(PROC_DIR, NULL);
- if (vlsi_proc_root) {
- /* protect registered procdir against module removal.
- * Because we are in the module init path there's no race
- * window after create_proc_entry (and no barrier needed).
- */
- vlsi_proc_root->owner = THIS_MODULE;
- }
ret = pci_register_driver(&vlsi_irda_driver);
diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c
index dc0a2e4d830f..d0883835b0c6 100644
--- a/drivers/net/irda/w83977af_ir.c
+++ b/drivers/net/irda/w83977af_ir.c
@@ -140,6 +140,13 @@ static void __exit w83977af_cleanup(void)
}
}
+static const struct net_device_ops w83977_netdev_ops = {
+ .ndo_open = w83977af_net_open,
+ .ndo_stop = w83977af_net_close,
+ .ndo_start_xmit = w83977af_hard_xmit,
+ .ndo_do_ioctl = w83977af_net_ioctl,
+};
+
/*
* Function w83977af_open (iobase, irq)
*
@@ -231,11 +238,7 @@ static int w83977af_open(int i, unsigned int iobase, unsigned int irq,
self->rx_buff.data = self->rx_buff.head;
self->netdev = dev;
- /* Override the network functions we need to use */
- dev->hard_start_xmit = w83977af_hard_xmit;
- dev->open = w83977af_net_open;
- dev->stop = w83977af_net_close;
- dev->do_ioctl = w83977af_net_ioctl;
+ dev->netdev_ops = &w83977_netdev_ops;
err = register_netdev(dev);
if (err) {
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index eee28d395682..4b0ea66d7a44 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -887,19 +887,13 @@ static void
ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter,
struct ixgb_buffer *buffer_info)
{
- struct pci_dev *pdev = adapter->pdev;
-
- if (buffer_info->dma)
- pci_unmap_page(pdev, buffer_info->dma, buffer_info->length,
- PCI_DMA_TODEVICE);
-
- /* okay to call kfree_skb here instead of kfree_skb_any because
- * this is never called in interrupt context */
- if (buffer_info->skb)
- dev_kfree_skb(buffer_info->skb);
-
- buffer_info->skb = NULL;
buffer_info->dma = 0;
+ if (buffer_info->skb) {
+ skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
+ DMA_TO_DEVICE);
+ dev_kfree_skb_any(buffer_info->skb);
+ buffer_info->skb = NULL;
+ }
buffer_info->time_stamp = 0;
/* these fields must always be initialized in tx
* buffer_info->length = 0;
@@ -1275,17 +1269,23 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
{
struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
struct ixgb_buffer *buffer_info;
- int len = skb->len;
+ int len = skb_headlen(skb);
unsigned int offset = 0, size, count = 0, i;
unsigned int mss = skb_shinfo(skb)->gso_size;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int f;
-
- len -= skb->data_len;
+ dma_addr_t *map;
i = tx_ring->next_to_use;
+ if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+ return 0;
+ }
+
+ map = skb_shinfo(skb)->dma_maps;
+
while (len) {
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_DATA_PER_TXD);
@@ -1297,7 +1297,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
buffer_info->length = size;
WARN_ON(buffer_info->dma != 0);
buffer_info->time_stamp = jiffies;
- buffer_info->dma =
+ buffer_info->dma = map[0] + offset;
pci_map_single(adapter->pdev,
skb->data + offset,
size,
@@ -1307,7 +1307,11 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
len -= size;
offset += size;
count++;
- if (++i == tx_ring->count) i = 0;
+ if (len) {
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+ }
}
for (f = 0; f < nr_frags; f++) {
@@ -1318,6 +1322,10 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
offset = 0;
while (len) {
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+
buffer_info = &tx_ring->buffer_info[i];
size = min(len, IXGB_MAX_DATA_PER_TXD);
@@ -1329,21 +1337,14 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
buffer_info->length = size;
buffer_info->time_stamp = jiffies;
- buffer_info->dma =
- pci_map_page(adapter->pdev,
- frag->page,
- frag->page_offset + offset,
- size,
- PCI_DMA_TODEVICE);
+ buffer_info->dma = map[f + 1] + offset;
buffer_info->next_to_watch = 0;
len -= size;
offset += size;
count++;
- if (++i == tx_ring->count) i = 0;
}
}
- i = (i == 0) ? tx_ring->count - 1 : i - 1;
tx_ring->buffer_info[i].skb = skb;
tx_ring->buffer_info[first].next_to_watch = i;
@@ -1445,6 +1446,7 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
unsigned int first;
unsigned int tx_flags = 0;
int vlan_id = 0;
+ int count = 0;
int tso;
if (test_bit(__IXGB_DOWN, &adapter->flags)) {
@@ -1479,13 +1481,19 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
else if (ixgb_tx_csum(adapter, skb))
tx_flags |= IXGB_TX_FLAGS_CSUM;
- ixgb_tx_queue(adapter, ixgb_tx_map(adapter, skb, first), vlan_id,
- tx_flags);
+ count = ixgb_tx_map(adapter, skb, first);
- netdev->trans_start = jiffies;
+ if (count) {
+ ixgb_tx_queue(adapter, count, vlan_id, tx_flags);
+ netdev->trans_start = jiffies;
+ /* Make sure there is space in the ring for the next send. */
+ ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED);
- /* Make sure there is space in the ring for the next send. */
- ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED);
+ } else {
+ dev_kfree_skb_any(skb);
+ adapter->tx_ring.buffer_info[first].time_stamp = 0;
+ adapter->tx_ring.next_to_use = first;
+ }
return NETDEV_TX_OK;
}
@@ -1721,14 +1729,14 @@ ixgb_intr(int irq, void *data)
if (!test_bit(__IXGB_DOWN, &adapter->flags))
mod_timer(&adapter->watchdog_timer, jiffies);
- if (netif_rx_schedule_prep(&adapter->napi)) {
+ if (napi_schedule_prep(&adapter->napi)) {
/* Disable interrupts and register for poll. The flush
of the posted write is intentionally left out.
*/
IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
- __netif_rx_schedule(&adapter->napi);
+ __napi_schedule(&adapter->napi);
}
return IRQ_HANDLED;
}
@@ -1749,7 +1757,7 @@ ixgb_clean(struct napi_struct *napi, int budget)
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
if (!test_bit(__IXGB_DOWN, &adapter->flags))
ixgb_irq_enable(adapter);
}
@@ -1818,7 +1826,7 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
/* detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of i */
adapter->detect_tx_hung = false;
- if (tx_ring->buffer_info[eop].dma &&
+ if (tx_ring->buffer_info[eop].time_stamp &&
time_after(jiffies, tx_ring->buffer_info[eop].time_stamp + HZ)
&& !(IXGB_READ_REG(&adapter->hw, STATUS) &
IXGB_STATUS_TXOFF)) {
diff --git a/drivers/net/ixgbe/Makefile b/drivers/net/ixgbe/Makefile
index 6e7ef765bcd8..b3f8208ec7be 100644
--- a/drivers/net/ixgbe/Makefile
+++ b/drivers/net/ixgbe/Makefile
@@ -1,7 +1,7 @@
################################################################################
#
# Intel 10 Gigabit PCI Express Linux driver
-# Copyright(c) 1999 - 2007 Intel Corporation.
+# Copyright(c) 1999 - 2009 Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
@@ -33,6 +33,7 @@
obj-$(CONFIG_IXGBE) += ixgbe.o
ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
- ixgbe_82598.o ixgbe_phy.o
+ ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o
-ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o ixgbe_dcb_nl.o
+ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \
+ ixgbe_dcb_82599.o ixgbe_dcb_nl.o
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index e112008f39c1..c26433d14605 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -31,7 +31,6 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
-#include <linux/inet_lro.h>
#include <linux/aer.h>
#include "ixgbe_type.h"
@@ -72,6 +71,7 @@
#define IXGBE_RXBUFFER_128 128 /* Used for packet split */
#define IXGBE_RXBUFFER_256 256 /* Used for packet split */
#define IXGBE_RXBUFFER_2048 2048
+#define IXGBE_MAX_RXBUFFER 16384 /* largest size for a single descriptor */
#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_256
@@ -88,9 +88,6 @@
#define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0x0000e000
#define IXGBE_TX_FLAGS_VLAN_SHIFT 16
-#define IXGBE_MAX_LRO_DESCRIPTORS 8
-#define IXGBE_MAX_LRO_AGGREGATE 32
-
/* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer */
struct ixgbe_tx_buffer {
@@ -142,21 +139,25 @@ struct ixgbe_ring {
/* cpu for tx queue */
int cpu;
#endif
- struct net_lro_mgr lro_mgr;
- bool lro_used;
struct ixgbe_queue_stats stats;
- u16 v_idx; /* maps directly to the index for this ring in the hardware
- * vector array, can also be used for finding the bit in EICR
- * and friends that represents the vector for this ring */
+ u64 v_idx; /* maps directly to the index for this ring in the hardware
+ * vector array, can also be used for finding the bit in EICR
+ * and friends that represents the vector for this ring */
u16 work_limit; /* max work per interrupt */
u16 rx_buf_len;
};
-#define RING_F_DCB 0
-#define RING_F_VMDQ 1
-#define RING_F_RSS 2
+enum ixgbe_ring_f_enum {
+ RING_F_NONE = 0,
+ RING_F_DCB,
+ RING_F_VMDQ,
+ RING_F_RSS,
+
+ RING_F_ARRAY_SIZE /* must be last in enum set */
+};
+
#define IXGBE_MAX_DCB_INDICES 8
#define IXGBE_MAX_RSS_INDICES 16
#define IXGBE_MAX_VMDQ_INDICES 16
@@ -165,8 +166,8 @@ struct ixgbe_ring_feature {
int mask;
};
-#define MAX_RX_QUEUES 64
-#define MAX_TX_QUEUES 32
+#define MAX_RX_QUEUES 128
+#define MAX_TX_QUEUES 128
#define MAX_RX_PACKET_BUFFERS ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) \
? 8 : 1)
@@ -188,10 +189,11 @@ struct ixgbe_q_vector {
};
/* Helper macros to switch between ints/sec and what the register uses.
- * And yes, it's the same math going both ways.
+ * And yes, it's the same math going both ways. The lowest value
+ * supported by all of the ixgbe hardware is 8.
*/
#define EITR_INTS_PER_SEC_TO_REG(_eitr) \
- ((_eitr) ? (1000000000 / ((_eitr) * 256)) : 0)
+ ((_eitr) ? (1000000000 / ((_eitr) * 256)) : 8)
#define EITR_REG_TO_INTS_PER_SEC EITR_INTS_PER_SEC_TO_REG
#define IXGBE_DESC_UNUSED(R) \
@@ -210,9 +212,15 @@ struct ixgbe_q_vector {
#define OTHER_VECTOR 1
#define NON_Q_VECTORS (OTHER_VECTOR)
-#define MAX_MSIX_Q_VECTORS 16
+#define MAX_MSIX_VECTORS_82599 64
+#define MAX_MSIX_Q_VECTORS_82599 64
+#define MAX_MSIX_VECTORS_82598 18
+#define MAX_MSIX_Q_VECTORS_82598 16
+
+#define MAX_MSIX_Q_VECTORS MAX_MSIX_Q_VECTORS_82599
+#define MAX_MSIX_COUNT MAX_MSIX_VECTORS_82599
+
#define MIN_MSIX_Q_VECTORS 2
-#define MAX_MSIX_COUNT (MAX_MSIX_Q_VECTORS + NON_Q_VECTORS)
#define MIN_MSIX_COUNT (MIN_MSIX_Q_VECTORS + NON_Q_VECTORS)
/* board specific private data structure */
@@ -222,7 +230,7 @@ struct ixgbe_adapter {
u16 bd_number;
struct work_struct reset_task;
struct ixgbe_q_vector q_vector[MAX_MSIX_Q_VECTORS];
- char name[MAX_MSIX_COUNT][IFNAMSIZ + 5];
+ char name[MAX_MSIX_COUNT][IFNAMSIZ + 9];
struct ixgbe_dcb_config dcb_cfg;
struct ixgbe_dcb_config temp_dcb_cfg;
u8 dcb_set_bitmap;
@@ -247,10 +255,12 @@ struct ixgbe_adapter {
struct ixgbe_ring *rx_ring; /* One per active queue */
int num_rx_queues;
u64 hw_csum_rx_error;
+ u64 hw_rx_no_dma_resources;
u64 hw_csum_rx_good;
u64 non_eop_descs;
int num_msix_vectors;
- struct ixgbe_ring_feature ring_feature[3];
+ int max_msix_q_vectors; /* true count of q_vectors for device */
+ struct ixgbe_ring_feature ring_feature[RING_F_ARRAY_SIZE];
struct msix_entry *msix_entries;
u64 rx_hdr_split;
@@ -274,6 +284,7 @@ struct ixgbe_adapter {
#define IXGBE_FLAG_DCA_CAPABLE (u32)(1 << 11)
#define IXGBE_FLAG_IMIR_ENABLED (u32)(1 << 12)
#define IXGBE_FLAG_MQ_CAPABLE (u32)(1 << 13)
+#define IXGBE_FLAG_DCB_ENABLED (u32)(1 << 14)
#define IXGBE_FLAG_RSS_ENABLED (u32)(1 << 16)
#define IXGBE_FLAG_RSS_CAPABLE (u32)(1 << 17)
#define IXGBE_FLAG_VMDQ_CAPABLE (u32)(1 << 18)
@@ -281,7 +292,8 @@ struct ixgbe_adapter {
#define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 20)
#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22)
#define IXGBE_FLAG_IN_WATCHDOG_TASK (u32)(1 << 23)
-#define IXGBE_FLAG_DCB_ENABLED (u32)(1 << 24)
+#define IXGBE_FLAG_IN_SFP_LINK_TASK (u32)(1 << 24)
+#define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 25)
/* default to trying for four seconds */
#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
@@ -301,9 +313,6 @@ struct ixgbe_adapter {
unsigned long state;
u64 tx_busy;
- u64 lro_aggregated;
- u64 lro_flushed;
- u64 lro_no_desc;
unsigned int tx_ring_count;
unsigned int rx_ring_count;
@@ -314,6 +323,10 @@ struct ixgbe_adapter {
struct work_struct watchdog_task;
struct work_struct sfp_task;
struct timer_list sfp_timer;
+ struct work_struct multispeed_fiber_task;
+ struct work_struct sfp_config_module_task;
+ u32 wol;
+ u16 eeprom_version;
};
enum ixbge_state_t {
@@ -325,9 +338,11 @@ enum ixbge_state_t {
enum ixgbe_boards {
board_82598,
+ board_82599,
};
extern struct ixgbe_info ixgbe_82598_info;
+extern struct ixgbe_info ixgbe_82599_info;
#ifdef CONFIG_IXGBE_DCB
extern struct dcbnl_rtnl_ops dcbnl_ops;
extern int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
@@ -352,5 +367,6 @@ extern void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter);
extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
void ixgbe_napi_add_all(struct ixgbe_adapter *adapter);
void ixgbe_napi_del_all(struct ixgbe_adapter *adapter);
+extern void ixgbe_write_eitr(struct ixgbe_adapter *, int, u32);
#endif /* _IXGBE_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index ad5699d9ab0d..de4db0dc7879 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -50,6 +50,27 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
u8 *eeprom_data);
/**
+ * ixgbe_get_pcie_msix_count_82598 - Gets MSI-X vector count
+ * @hw: pointer to hardware structure
+ *
+ * Read PCIe configuration space, and get the MSI-X vector count from
+ * the capabilities table.
+ **/
+static u16 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw)
+{
+ struct ixgbe_adapter *adapter = hw->back;
+ u16 msix_count;
+ pci_read_config_word(adapter->pdev, IXGBE_PCIE_MSIX_82598_CAPS,
+ &msix_count);
+ msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
+
+ /* MSI-X count is zero-based in HW, so increment to give proper value */
+ msix_count++;
+
+ return msix_count;
+}
+
+/**
*/
static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
{
@@ -58,6 +79,9 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
s32 ret_val = 0;
u16 list_offset, data_offset;
+ /* Set the bus information prior to PHY identification */
+ mac->ops.get_bus_info(hw);
+
/* Call PHY identify routine to get the phy type */
ixgbe_identify_phy_generic(hw);
@@ -106,6 +130,7 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
+ mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
out:
return ret_val;
@@ -124,18 +149,12 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
bool *autoneg)
{
s32 status = 0;
- s32 autoc_reg;
-
- autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- if (hw->mac.link_settings_loaded) {
- autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE;
- autoc_reg &= ~IXGBE_AUTOC_LMS_MASK;
- autoc_reg |= hw->mac.link_attach_type;
- autoc_reg |= hw->mac.link_mode_select;
- }
-
- switch (autoc_reg & IXGBE_AUTOC_LMS_MASK) {
+ /*
+ * Determine link capabilities based on the stored value of AUTOC,
+ * which represents EEPROM defaults.
+ */
+ switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
*speed = IXGBE_LINK_SPEED_1GB_FULL;
*autoneg = false;
@@ -154,9 +173,9 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
case IXGBE_AUTOC_LMS_KX4_AN:
case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
*speed = IXGBE_LINK_SPEED_UNKNOWN;
- if (autoc_reg & IXGBE_AUTOC_KX4_SUPP)
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
*speed |= IXGBE_LINK_SPEED_10GB_FULL;
- if (autoc_reg & IXGBE_AUTOC_KX_SUPP)
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
*speed |= IXGBE_LINK_SPEED_1GB_FULL;
*autoneg = true;
break;
@@ -213,6 +232,10 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
/* Media type for I82598 is based on device ID */
switch (hw->device_id) {
+ case IXGBE_DEV_ID_82598:
+ case IXGBE_DEV_ID_82598_BX:
+ media_type = ixgbe_media_type_backplane;
+ break;
case IXGBE_DEV_ID_82598AF_DUAL_PORT:
case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
case IXGBE_DEV_ID_82598EB_CX4:
@@ -235,104 +258,75 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
}
/**
- * ixgbe_setup_fc_82598 - Configure flow control settings
+ * ixgbe_fc_enable_82598 - Enable flow control
* @hw: pointer to hardware structure
* @packetbuf_num: packet buffer number (0-7)
*
- * Configures the flow control settings based on SW configuration. This
- * function is used for 802.3x flow control configuration only.
+ * Enable flow control according to the current settings.
**/
-static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
+static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
{
- u32 frctl_reg;
+ s32 ret_val = 0;
+ u32 fctrl_reg;
u32 rmcs_reg;
+ u32 reg;
- if (packetbuf_num < 0 || packetbuf_num > 7) {
- hw_dbg(hw, "Invalid packet buffer number [%d], expected range is"
- " 0-7\n", packetbuf_num);
- }
-
- frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
+ fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
/*
- * 10 gig parts do not have a word in the EEPROM to determine the
- * default flow control setting, so we explicitly set it to full.
- */
- if (hw->fc.type == ixgbe_fc_default)
- hw->fc.type = ixgbe_fc_full;
-
- /*
- * We want to save off the original Flow Control configuration just in
- * case we get disconnected and then reconnected into a different hub
- * or switch with different Flow Control capabilities.
- */
- hw->fc.original_type = hw->fc.type;
-
- /*
- * The possible values of the "flow_control" parameter are:
+ * The possible values of fc.current_mode are:
* 0: Flow control is completely disabled
- * 1: Rx flow control is enabled (we can receive pause frames but not
- * send pause frames).
- * 2: Tx flow control is enabled (we can send pause frames but we do not
- * support receiving pause frames)
+ * 1: Rx flow control is enabled (we can receive pause frames,
+ * but not send pause frames).
+ * 2: Tx flow control is enabled (we can send pause frames but
+ * we do not support receiving pause frames).
* 3: Both Rx and Tx flow control (symmetric) are enabled.
* other: Invalid.
*/
- switch (hw->fc.type) {
+ switch (hw->fc.current_mode) {
case ixgbe_fc_none:
+ /* Flow control completely disabled by software override. */
break;
case ixgbe_fc_rx_pause:
/*
- * Rx Flow control is enabled,
- * and Tx Flow control is disabled.
+ * Rx Flow control is enabled and Tx Flow control is
+ * disabled by software override. Since there really
+ * isn't a way to advertise that we are capable of RX
+ * Pause ONLY, we will advertise that we support both
+ * symmetric and asymmetric Rx PAUSE. Later, we will
+ * disable the adapter's ability to send PAUSE frames.
*/
- frctl_reg |= IXGBE_FCTRL_RFCE;
+ fctrl_reg |= IXGBE_FCTRL_RFCE;
break;
case ixgbe_fc_tx_pause:
/*
- * Tx Flow control is enabled, and Rx Flow control is disabled,
- * by a software over-ride.
+ * Tx Flow control is enabled, and Rx Flow control is
+ * disabled by software override.
*/
rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
break;
case ixgbe_fc_full:
- /*
- * Flow control (both Rx and Tx) is enabled by a software
- * over-ride.
- */
- frctl_reg |= IXGBE_FCTRL_RFCE;
+ /* Flow control (both Rx and Tx) is enabled by SW override. */
+ fctrl_reg |= IXGBE_FCTRL_RFCE;
rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
break;
default:
- /* We should never get here. The value should be 0-3. */
hw_dbg(hw, "Flow control param set incorrectly\n");
+ ret_val = -IXGBE_ERR_CONFIG;
+ goto out;
break;
}
/* Enable 802.3x based flow control settings. */
- IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg);
+ IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
- /*
- * Check for invalid software configuration, zeros are completely
- * invalid for all parameters used past this point, and if we enable
- * flow control with zero water marks, we blast flow control packets.
- */
- if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
- hw_dbg(hw, "Flow control structure initialized incorrectly\n");
- return IXGBE_ERR_INVALID_LINK_SETTINGS;
- }
-
- /*
- * We need to set up the Receive Threshold high and low water
- * marks as well as (optionally) enabling the transmission of
- * XON frames.
- */
- if (hw->fc.type & ixgbe_fc_tx_pause) {
+ /* Set up and enable Rx high/low water mark thresholds, enable XON. */
+ if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
if (hw->fc.send_xon) {
IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
(hw->fc.low_water | IXGBE_FCRTL_XONE));
@@ -340,14 +334,94 @@ static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
hw->fc.low_water);
}
+
IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num),
- (hw->fc.high_water)|IXGBE_FCRTH_FCEN);
+ (hw->fc.high_water | IXGBE_FCRTH_FCEN));
}
- IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time);
+ /* Configure pause time (2 TCs per register) */
+ reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num));
+ if ((packetbuf_num & 1) == 0)
+ reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
+ else
+ reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16);
+ IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg);
+
IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
- return 0;
+out:
+ return ret_val;
+}
+
+/**
+ * ixgbe_setup_fc_82598 - Configure flow control settings
+ * @hw: pointer to hardware structure
+ * @packetbuf_num: packet buffer number (0-7)
+ *
+ * Configures the flow control settings based on SW configuration. This
+ * function is used for 802.3x flow control configuration only.
+ **/
+static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
+{
+ s32 ret_val = 0;
+ ixgbe_link_speed speed;
+ bool link_up;
+
+ /* Validate the packetbuf configuration */
+ if (packetbuf_num < 0 || packetbuf_num > 7) {
+ hw_dbg(hw, "Invalid packet buffer number [%d], expected range is"
+ " 0-7\n", packetbuf_num);
+ ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+ goto out;
+ }
+
+ /*
+ * Validate the water mark configuration. Zero water marks are invalid
+ * because it causes the controller to just blast out fc packets.
+ */
+ if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
+ hw_dbg(hw, "Invalid water mark configuration\n");
+ ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+ goto out;
+ }
+
+ /*
+ * Validate the requested mode. Strict IEEE mode does not allow
+ * ixgbe_fc_rx_pause because it will cause testing anomalies.
+ */
+ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
+ hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
+ ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+ goto out;
+ }
+
+ /*
+ * 10gig parts do not have a word in the EEPROM to determine the
+ * default flow control setting, so we explicitly set it to full.
+ */
+ if (hw->fc.requested_mode == ixgbe_fc_default)
+ hw->fc.requested_mode = ixgbe_fc_full;
+
+ /*
+ * Save off the requested flow control mode for use later. Depending
+ * on the link partner's capabilities, we may or may not use this mode.
+ */
+
+ hw->fc.current_mode = hw->fc.requested_mode;
+
+ /* Decide whether to use autoneg or not. */
+ hw->mac.ops.check_link(hw, &speed, &link_up, false);
+ if (!hw->fc.disable_fc_autoneg && hw->phy.multispeed_fiber &&
+ (speed == IXGBE_LINK_SPEED_1GB_FULL))
+ ret_val = ixgbe_fc_autoneg(hw);
+
+ if (ret_val)
+ goto out;
+
+ ret_val = ixgbe_fc_enable_82598(hw, packetbuf_num);
+
+out:
+ return ret_val;
}
/**
@@ -364,27 +438,17 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
u32 i;
s32 status = 0;
- autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-
- if (hw->mac.link_settings_loaded) {
- autoc_reg &= ~IXGBE_AUTOC_LMS_ATTACH_TYPE;
- autoc_reg &= ~IXGBE_AUTOC_LMS_MASK;
- autoc_reg |= hw->mac.link_attach_type;
- autoc_reg |= hw->mac.link_mode_select;
-
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
- IXGBE_WRITE_FLUSH(hw);
- msleep(50);
- }
-
/* Restart link */
+ autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
/* Only poll for autoneg to complete if specified to do so */
if (hw->phy.autoneg_wait_to_complete) {
- if (hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN ||
- hw->mac.link_mode_select == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
+ if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+ IXGBE_AUTOC_LMS_KX4_AN ||
+ (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+ IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
links_reg = 0; /* Just in case Autoneg time = 0 */
for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
@@ -404,7 +468,6 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
* case we get disconnected and then reconnected into a different hub
* or switch with different Flow Control capabilities.
*/
- hw->fc.original_type = hw->fc.type;
ixgbe_setup_fc_82598(hw, 0);
/* Add delay to filter out noises during initial link setup */
@@ -508,37 +571,43 @@ out:
* Set the link speed in the AUTOC register and restarts link.
**/
static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
- ixgbe_link_speed speed, bool autoneg,
- bool autoneg_wait_to_complete)
+ ixgbe_link_speed speed, bool autoneg,
+ bool autoneg_wait_to_complete)
{
- s32 status = 0;
+ s32 status = 0;
+ ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
+ u32 curr_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 autoc = curr_autoc;
+ u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
- /* If speed is 10G, then check for CX4 or XAUI. */
- if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
- (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4))) {
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
- } else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg)) {
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
- } else if (autoneg) {
- /* BX mode - Autonegotiate 1G */
- if (!(hw->mac.link_attach_type & IXGBE_AUTOC_1G_PMA_PMD))
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_AN;
- else /* KX/KX4 mode */
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN_1G_AN;
- } else {
+ /* Check to see if speed passed in is supported. */
+ ixgbe_get_link_capabilities_82598(hw, &link_capabilities, &autoneg);
+ speed &= link_capabilities;
+
+ if (speed == IXGBE_LINK_SPEED_UNKNOWN)
status = IXGBE_ERR_LINK_SETUP;
+
+ /* Set KX4/KX support according to speed requested */
+ else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN ||
+ link_mode == IXGBE_AUTOC_LMS_KX4_AN_1G_AN) {
+ autoc &= ~IXGBE_AUTOC_KX4_KX_SUPP_MASK;
+ if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+ autoc |= IXGBE_AUTOC_KX4_SUPP;
+ if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+ autoc |= IXGBE_AUTOC_KX_SUPP;
+ if (autoc != curr_autoc)
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
}
if (status == 0) {
hw->phy.autoneg_wait_to_complete = autoneg_wait_to_complete;
- hw->mac.link_settings_loaded = true;
/*
* Setup and restart the link based on the new values in
* ixgbe_hw This will write the AUTOC register based on the new
* stored values
*/
- ixgbe_setup_mac_link_82598(hw);
+ status = ixgbe_setup_mac_link_82598(hw);
}
return status;
@@ -561,10 +630,6 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
/* Restart autonegotiation on PHY */
status = hw->phy.ops.setup_link(hw);
- /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
- hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
-
/* Set up MAC */
ixgbe_setup_mac_link_82598(hw);
@@ -591,10 +656,6 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
autoneg_wait_to_complete);
- /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
- hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
-
/* Set up MAC */
ixgbe_setup_mac_link_82598(hw);
@@ -694,24 +755,16 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_GHECCR, gheccr);
/*
- * AUTOC register which stores link settings gets cleared
- * and reloaded from EEPROM after reset. We need to restore
- * our stored value from init in case SW changed the attach
- * type or speed. If this is the first time and link settings
- * have not been stored, store default settings from AUTOC.
+ * Store the original AUTOC value if it has not been
+ * stored off yet. Otherwise restore the stored original
+ * AUTOC value since the reset operation sets back to deaults.
*/
autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
- if (hw->mac.link_settings_loaded) {
- autoc &= ~(IXGBE_AUTOC_LMS_ATTACH_TYPE);
- autoc &= ~(IXGBE_AUTOC_LMS_MASK);
- autoc |= hw->mac.link_attach_type;
- autoc |= hw->mac.link_mode_select;
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
- } else {
- hw->mac.link_attach_type =
- (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE);
- hw->mac.link_mode_select = (autoc & IXGBE_AUTOC_LMS_MASK);
- hw->mac.link_settings_loaded = true;
+ if (hw->mac.orig_link_settings_stored == false) {
+ hw->mac.orig_autoc = autoc;
+ hw->mac.orig_link_settings_stored = true;
+ } else if (autoc != hw->mac.orig_autoc) {
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
}
/* Store the permanent mac address */
@@ -997,11 +1050,18 @@ out:
*
* Determines physical layer capabilities of the current configuration.
**/
-static s32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
+static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
{
- s32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
switch (hw->device_id) {
+ case IXGBE_DEV_ID_82598:
+ /* Default device ID is mezzanine card KX/KX4 */
+ physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
+ IXGBE_PHYSICAL_LAYER_1000BASE_KX);
+ break;
+ case IXGBE_DEV_ID_82598_BX:
+ physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
case IXGBE_DEV_ID_82598EB_CX4:
case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
@@ -1055,8 +1115,11 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
.clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic,
.get_media_type = &ixgbe_get_media_type_82598,
.get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82598,
+ .enable_rx_dma = &ixgbe_enable_rx_dma_generic,
.get_mac_addr = &ixgbe_get_mac_addr_generic,
.stop_adapter = &ixgbe_stop_adapter_generic,
+ .get_bus_info = &ixgbe_get_bus_info_generic,
+ .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie,
.read_analog_reg8 = &ixgbe_read_analog_reg8_82598,
.write_analog_reg8 = &ixgbe_write_analog_reg8_82598,
.setup_link = &ixgbe_setup_mac_link_82598,
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
new file mode 100644
index 000000000000..beae7e012609
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -0,0 +1,1292 @@
+/*******************************************************************************
+
+ Intel 10 Gigabit PCI Express Linux driver
+ Copyright(c) 1999 - 2009 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+
+#include "ixgbe.h"
+#include "ixgbe_phy.h"
+
+#define IXGBE_82599_MAX_TX_QUEUES 128
+#define IXGBE_82599_MAX_RX_QUEUES 128
+#define IXGBE_82599_RAR_ENTRIES 128
+#define IXGBE_82599_MC_TBL_SIZE 128
+#define IXGBE_82599_VFT_TBL_SIZE 128
+
+s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg);
+enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw);
+s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw);
+s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed, bool autoneg,
+ bool autoneg_wait_to_complete);
+s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw);
+s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *link_up, bool link_up_wait_to_complete);
+s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete);
+static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg);
+static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw);
+static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete);
+s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw);
+s32 ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
+s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
+s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan,
+ u32 vind, bool vlan_on);
+s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw);
+s32 ixgbe_blink_led_stop_82599(struct ixgbe_hw *hw, u32 index);
+s32 ixgbe_blink_led_start_82599(struct ixgbe_hw *hw, u32 index);
+s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw);
+s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val);
+s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val);
+s32 ixgbe_start_hw_rev_0_82599(struct ixgbe_hw *hw);
+s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw);
+s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw);
+u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw);
+
+void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
+{
+ struct ixgbe_mac_info *mac = &hw->mac;
+ if (hw->phy.multispeed_fiber) {
+ /* Set up dual speed SFP+ support */
+ mac->ops.setup_link =
+ &ixgbe_setup_mac_link_multispeed_fiber;
+ mac->ops.setup_link_speed =
+ &ixgbe_setup_mac_link_speed_multispeed_fiber;
+ } else {
+ mac->ops.setup_link =
+ &ixgbe_setup_mac_link_82599;
+ mac->ops.setup_link_speed =
+ &ixgbe_setup_mac_link_speed_82599;
+ }
+}
+
+s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
+{
+ s32 ret_val = 0;
+ u16 list_offset, data_offset, data_value;
+
+ if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
+ ixgbe_init_mac_link_ops_82599(hw);
+ ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
+ &data_offset);
+
+ if (ret_val != 0)
+ goto setup_sfp_out;
+
+ hw->eeprom.ops.read(hw, ++data_offset, &data_value);
+ while (data_value != 0xffff) {
+ IXGBE_WRITE_REG(hw, IXGBE_CORECTL, data_value);
+ IXGBE_WRITE_FLUSH(hw);
+ hw->eeprom.ops.read(hw, ++data_offset, &data_value);
+ }
+ /* Now restart DSP */
+ IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000102);
+ IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000b1d);
+ IXGBE_WRITE_FLUSH(hw);
+ }
+
+setup_sfp_out:
+ return ret_val;
+}
+
+/**
+ * ixgbe_get_pcie_msix_count_82599 - Gets MSI-X vector count
+ * @hw: pointer to hardware structure
+ *
+ * Read PCIe configuration space, and get the MSI-X vector count from
+ * the capabilities table.
+ **/
+u32 ixgbe_get_pcie_msix_count_82599(struct ixgbe_hw *hw)
+{
+ struct ixgbe_adapter *adapter = hw->back;
+ u16 msix_count;
+ pci_read_config_word(adapter->pdev, IXGBE_PCIE_MSIX_82599_CAPS,
+ &msix_count);
+ msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
+
+ /* MSI-X count is zero-based in HW, so increment to give proper value */
+ msix_count++;
+
+ return msix_count;
+}
+
+static s32 ixgbe_get_invariants_82599(struct ixgbe_hw *hw)
+{
+ struct ixgbe_mac_info *mac = &hw->mac;
+ struct ixgbe_phy_info *phy = &hw->phy;
+ s32 ret_val;
+
+ /* Set the bus information prior to PHY identification */
+ mac->ops.get_bus_info(hw);
+
+ /* Call PHY identify routine to get the Cu or SFI phy type */
+ ret_val = phy->ops.identify(hw);
+
+ if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ goto get_invariants_out;
+
+ ixgbe_init_mac_link_ops_82599(hw);
+
+ /* Setup SFP module if there is one present. */
+ ret_val = mac->ops.setup_sfp(hw);
+
+ /* If copper media, overwrite with copper function pointers */
+ if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
+ mac->ops.setup_link = &ixgbe_setup_copper_link_82599;
+ mac->ops.setup_link_speed =
+ &ixgbe_setup_copper_link_speed_82599;
+ mac->ops.get_link_capabilities =
+ &ixgbe_get_copper_link_capabilities_82599;
+ }
+
+ /* PHY Init */
+ switch (hw->phy.type) {
+ case ixgbe_phy_tn:
+ phy->ops.check_link = &ixgbe_check_phy_link_tnx;
+ phy->ops.get_firmware_version =
+ &ixgbe_get_phy_firmware_version_tnx;
+ break;
+ default:
+ break;
+ }
+
+ mac->mcft_size = IXGBE_82599_MC_TBL_SIZE;
+ mac->vft_size = IXGBE_82599_VFT_TBL_SIZE;
+ mac->num_rar_entries = IXGBE_82599_RAR_ENTRIES;
+ mac->max_rx_queues = IXGBE_82599_MAX_RX_QUEUES;
+ mac->max_tx_queues = IXGBE_82599_MAX_TX_QUEUES;
+ mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw);
+
+get_invariants_out:
+ return ret_val;
+}
+
+/**
+ * ixgbe_get_link_capabilities_82599 - Determines link capabilities
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @negotiation: true when autoneg or autotry is enabled
+ *
+ * Determines the link capabilities by reading the AUTOC register.
+ **/
+s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *negotiation)
+{
+ s32 status = 0;
+
+ switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
+ case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+ *speed = IXGBE_LINK_SPEED_1GB_FULL;
+ *negotiation = false;
+ break;
+
+ case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+ *speed = IXGBE_LINK_SPEED_10GB_FULL;
+ *negotiation = false;
+ break;
+
+ case IXGBE_AUTOC_LMS_1G_AN:
+ *speed = IXGBE_LINK_SPEED_1GB_FULL;
+ *negotiation = true;
+ break;
+
+ case IXGBE_AUTOC_LMS_10G_SERIAL:
+ *speed = IXGBE_LINK_SPEED_10GB_FULL;
+ *negotiation = false;
+ break;
+
+ case IXGBE_AUTOC_LMS_KX4_KX_KR:
+ case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
+ *speed = IXGBE_LINK_SPEED_UNKNOWN;
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+ *speed |= IXGBE_LINK_SPEED_10GB_FULL;
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+ *speed |= IXGBE_LINK_SPEED_10GB_FULL;
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+ *speed |= IXGBE_LINK_SPEED_1GB_FULL;
+ *negotiation = true;
+ break;
+
+ case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
+ *speed = IXGBE_LINK_SPEED_100_FULL;
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+ *speed |= IXGBE_LINK_SPEED_10GB_FULL;
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+ *speed |= IXGBE_LINK_SPEED_10GB_FULL;
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+ *speed |= IXGBE_LINK_SPEED_1GB_FULL;
+ *negotiation = true;
+ break;
+
+ case IXGBE_AUTOC_LMS_SGMII_1G_100M:
+ *speed = IXGBE_LINK_SPEED_1GB_FULL | IXGBE_LINK_SPEED_100_FULL;
+ *negotiation = false;
+ break;
+
+ default:
+ status = IXGBE_ERR_LINK_SETUP;
+ goto out;
+ break;
+ }
+
+ if (hw->phy.multispeed_fiber) {
+ *speed |= IXGBE_LINK_SPEED_10GB_FULL |
+ IXGBE_LINK_SPEED_1GB_FULL;
+ *negotiation = true;
+ }
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_get_copper_link_capabilities_82599 - Determines link capabilities
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @autoneg: boolean auto-negotiation value
+ *
+ * Determines the link capabilities by reading the AUTOC register.
+ **/
+static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed *speed,
+ bool *autoneg)
+{
+ s32 status = IXGBE_ERR_LINK_SETUP;
+ u16 speed_ability;
+
+ *speed = 0;
+ *autoneg = true;
+
+ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
+ IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+ &speed_ability);
+
+ if (status == 0) {
+ if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
+ *speed |= IXGBE_LINK_SPEED_10GB_FULL;
+ if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
+ *speed |= IXGBE_LINK_SPEED_1GB_FULL;
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_get_media_type_82599 - Get media type
+ * @hw: pointer to hardware structure
+ *
+ * Returns the media type (fiber, copper, backplane)
+ **/
+enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
+{
+ enum ixgbe_media_type media_type;
+
+ /* Detect if there is a copper PHY attached. */
+ if (hw->phy.type == ixgbe_phy_cu_unknown ||
+ hw->phy.type == ixgbe_phy_tn) {
+ media_type = ixgbe_media_type_copper;
+ goto out;
+ }
+
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82599:
+ case IXGBE_DEV_ID_82599_KX4:
+ /* Default device ID is mezzanine card KX/KX4 */
+ media_type = ixgbe_media_type_backplane;
+ break;
+ case IXGBE_DEV_ID_82599_SFP:
+ media_type = ixgbe_media_type_fiber;
+ break;
+ default:
+ media_type = ixgbe_media_type_unknown;
+ break;
+ }
+out:
+ return media_type;
+}
+
+/**
+ * ixgbe_setup_mac_link_82599 - Setup MAC link settings
+ * @hw: pointer to hardware structure
+ *
+ * Configures link settings based on values in the ixgbe_hw struct.
+ * Restarts the link. Performs autonegotiation if needed.
+ **/
+s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw)
+{
+ u32 autoc_reg;
+ u32 links_reg;
+ u32 i;
+ s32 status = 0;
+
+ /* Restart link */
+ autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ autoc_reg |= IXGBE_AUTOC_AN_RESTART;
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+
+ /* Only poll for autoneg to complete if specified to do so */
+ if (hw->phy.autoneg_wait_to_complete) {
+ if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+ IXGBE_AUTOC_LMS_KX4_KX_KR ||
+ (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+ IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
+ (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
+ IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
+ links_reg = 0; /* Just in case Autoneg time = 0 */
+ for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
+ links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+ if (links_reg & IXGBE_LINKS_KX_AN_COMP)
+ break;
+ msleep(100);
+ }
+ if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
+ status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
+ hw_dbg(hw, "Autoneg did not complete.\n");
+ }
+ }
+ }
+
+ /* Set up flow control */
+ status = ixgbe_setup_fc_generic(hw, 0);
+
+ /* Add delay to filter out noises during initial link setup */
+ msleep(50);
+
+ return status;
+}
+
+/**
+ * ixgbe_setup_mac_link_multispeed_fiber - Setup MAC link settings
+ * @hw: pointer to hardware structure
+ *
+ * Configures link settings based on values in the ixgbe_hw struct.
+ * Restarts the link for multi-speed fiber at 1G speed, if link
+ * fails at 10G.
+ * Performs autonegotiation if needed.
+ **/
+s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw)
+{
+ s32 status = 0;
+ ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_82599_AUTONEG;
+ status = ixgbe_setup_mac_link_speed_multispeed_fiber(hw, link_speed,
+ true, true);
+ return status;
+}
+
+/**
+ * ixgbe_setup_mac_link_speed_multispeed_fiber - Set MAC link speed
+ * @hw: pointer to hardware structure
+ * @speed: new link speed
+ * @autoneg: true if autonegotiation enabled
+ * @autoneg_wait_to_complete: true when waiting for completion is needed
+ *
+ * Set the link speed in the AUTOC register and restarts link.
+ **/
+s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete)
+{
+ s32 status = 0;
+ ixgbe_link_speed phy_link_speed;
+ ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
+ u32 speedcnt = 0;
+ u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+ bool link_up = false;
+ bool negotiation;
+
+ /* Mask off requested but non-supported speeds */
+ hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation);
+ speed &= phy_link_speed;
+
+ /*
+ * Try each speed one by one, highest priority first. We do this in
+ * software because 10gb fiber doesn't support speed autonegotiation.
+ */
+ if (speed & IXGBE_LINK_SPEED_10GB_FULL) {
+ speedcnt++;
+ highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
+
+ /* Set hardware SDP's */
+ esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+
+ ixgbe_setup_mac_link_speed_82599(hw,
+ IXGBE_LINK_SPEED_10GB_FULL,
+ autoneg,
+ autoneg_wait_to_complete);
+
+ msleep(50);
+
+ /* If we have link, just jump out */
+ hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+ if (link_up)
+ goto out;
+ }
+
+ if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
+ speedcnt++;
+ if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
+ highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
+
+ /* Set hardware SDP's */
+ esdp_reg &= ~IXGBE_ESDP_SDP5;
+ esdp_reg |= IXGBE_ESDP_SDP5_DIR;
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+
+ ixgbe_setup_mac_link_speed_82599(
+ hw, IXGBE_LINK_SPEED_1GB_FULL, autoneg,
+ autoneg_wait_to_complete);
+
+ msleep(50);
+
+ /* If we have link, just jump out */
+ hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+ if (link_up)
+ goto out;
+ }
+
+ /*
+ * We didn't get link. Configure back to the highest speed we tried,
+ * (if there was more than one). We call ourselves back with just the
+ * single highest speed that the user requested.
+ */
+ if (speedcnt > 1)
+ status = ixgbe_setup_mac_link_speed_multispeed_fiber(hw,
+ highest_link_speed,
+ autoneg,
+ autoneg_wait_to_complete);
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_check_mac_link_82599 - Determine link and speed status
+ * @hw: pointer to hardware structure
+ * @speed: pointer to link speed
+ * @link_up: true when link is up
+ * @link_up_wait_to_complete: bool used to wait for link up or not
+ *
+ * Reads the links register to determine if link is up and the current speed
+ **/
+s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
+ bool *link_up, bool link_up_wait_to_complete)
+{
+ u32 links_reg;
+ u32 i;
+
+ links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+ if (link_up_wait_to_complete) {
+ for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
+ if (links_reg & IXGBE_LINKS_UP) {
+ *link_up = true;
+ break;
+ } else {
+ *link_up = false;
+ }
+ msleep(100);
+ links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+ }
+ } else {
+ if (links_reg & IXGBE_LINKS_UP)
+ *link_up = true;
+ else
+ *link_up = false;
+ }
+
+ if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
+ IXGBE_LINKS_SPEED_10G_82599)
+ *speed = IXGBE_LINK_SPEED_10GB_FULL;
+ else if ((links_reg & IXGBE_LINKS_SPEED_82599) ==
+ IXGBE_LINKS_SPEED_1G_82599)
+ *speed = IXGBE_LINK_SPEED_1GB_FULL;
+ else
+ *speed = IXGBE_LINK_SPEED_100_FULL;
+
+
+ return 0;
+}
+
+/**
+ * ixgbe_setup_mac_link_speed_82599 - Set MAC link speed
+ * @hw: pointer to hardware structure
+ * @speed: new link speed
+ * @autoneg: true if autonegotiation enabled
+ * @autoneg_wait_to_complete: true when waiting for completion is needed
+ *
+ * Set the link speed in the AUTOC register and restarts link.
+ **/
+s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed, bool autoneg,
+ bool autoneg_wait_to_complete)
+{
+ s32 status = 0;
+ u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+ u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
+ u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+ u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
+ u32 links_reg;
+ u32 i;
+ ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
+
+ /* Check to see if speed passed in is supported. */
+ hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg);
+ speed &= link_capabilities;
+
+ if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
+ status = IXGBE_ERR_LINK_SETUP;
+ } else if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
+ link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
+ link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
+ /* Set KX4/KX/KR support according to speed requested */
+ autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP);
+ if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+ autoc |= IXGBE_AUTOC_KX4_SUPP;
+ if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+ autoc |= IXGBE_AUTOC_KR_SUPP;
+ if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+ autoc |= IXGBE_AUTOC_KX_SUPP;
+ } else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) &&
+ (link_mode == IXGBE_AUTOC_LMS_1G_LINK_NO_AN ||
+ link_mode == IXGBE_AUTOC_LMS_1G_AN)) {
+ /* Switch from 1G SFI to 10G SFI if requested */
+ if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
+ (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)) {
+ autoc &= ~IXGBE_AUTOC_LMS_MASK;
+ autoc |= IXGBE_AUTOC_LMS_10G_SERIAL;
+ }
+ } else if ((pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI) &&
+ (link_mode == IXGBE_AUTOC_LMS_10G_SERIAL)) {
+ /* Switch from 10G SFI to 1G SFI if requested */
+ if ((speed == IXGBE_LINK_SPEED_1GB_FULL) &&
+ (pma_pmd_1g == IXGBE_AUTOC_1G_SFI)) {
+ autoc &= ~IXGBE_AUTOC_LMS_MASK;
+ if (autoneg)
+ autoc |= IXGBE_AUTOC_LMS_1G_AN;
+ else
+ autoc |= IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
+ }
+ }
+
+ if (status == 0) {
+ /* Restart link */
+ autoc |= IXGBE_AUTOC_AN_RESTART;
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
+
+ /* Only poll for autoneg to complete if specified to do so */
+ if (autoneg_wait_to_complete) {
+ if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
+ link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
+ link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
+ links_reg = 0; /*Just in case Autoneg time=0*/
+ for (i = 0; i < IXGBE_AUTO_NEG_TIME; i++) {
+ links_reg =
+ IXGBE_READ_REG(hw, IXGBE_LINKS);
+ if (links_reg & IXGBE_LINKS_KX_AN_COMP)
+ break;
+ msleep(100);
+ }
+ if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
+ status =
+ IXGBE_ERR_AUTONEG_NOT_COMPLETE;
+ hw_dbg(hw, "Autoneg did not "
+ "complete.\n");
+ }
+ }
+ }
+
+ /* Set up flow control */
+ status = ixgbe_setup_fc_generic(hw, 0);
+
+ /* Add delay to filter out noises during initial link setup */
+ msleep(50);
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_setup_copper_link_82599 - Setup copper link settings
+ * @hw: pointer to hardware structure
+ *
+ * Restarts the link on PHY and then MAC. Performs autonegotiation if needed.
+ **/
+static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw)
+{
+ s32 status;
+
+ /* Restart autonegotiation on PHY */
+ status = hw->phy.ops.setup_link(hw);
+
+ /* Set up MAC */
+ ixgbe_setup_mac_link_82599(hw);
+
+ return status;
+}
+
+/**
+ * ixgbe_setup_copper_link_speed_82599 - Set the PHY autoneg advertised field
+ * @hw: pointer to hardware structure
+ * @speed: new link speed
+ * @autoneg: true if autonegotiation enabled
+ * @autoneg_wait_to_complete: true if waiting is needed to complete
+ *
+ * Restarts link on PHY and MAC based on settings passed in.
+ **/
+static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw,
+ ixgbe_link_speed speed,
+ bool autoneg,
+ bool autoneg_wait_to_complete)
+{
+ s32 status;
+
+ /* Setup the PHY according to input speed */
+ status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+ autoneg_wait_to_complete);
+ /* Set up MAC */
+ ixgbe_setup_mac_link_82599(hw);
+
+ return status;
+}
+
+/**
+ * ixgbe_reset_hw_82599 - Perform hardware reset
+ * @hw: pointer to hardware structure
+ *
+ * Resets the hardware by resetting the transmit and receive units, masks
+ * and clears all interrupts, perform a PHY reset, and perform a link (MAC)
+ * reset.
+ **/
+s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
+{
+ s32 status = 0;
+ u32 ctrl, ctrl_ext;
+ u32 i;
+ u32 autoc;
+ u32 autoc2;
+
+ /* Call adapter stop to disable tx/rx and clear interrupts */
+ hw->mac.ops.stop_adapter(hw);
+
+ /* Reset PHY */
+ hw->phy.ops.reset(hw);
+
+ /*
+ * Prevent the PCI-E bus from from hanging by disabling PCI-E master
+ * access and verify no pending requests before reset
+ */
+ if (ixgbe_disable_pcie_master(hw) != 0) {
+ status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
+ hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
+ }
+
+ /*
+ * Issue global reset to the MAC. This needs to be a SW reset.
+ * If link reset is used, it might reset the MAC when mng is using it
+ */
+ ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+ IXGBE_WRITE_REG(hw, IXGBE_CTRL, (ctrl | IXGBE_CTRL_RST));
+ IXGBE_WRITE_FLUSH(hw);
+
+ /* Poll for reset bit to self-clear indicating reset is complete */
+ for (i = 0; i < 10; i++) {
+ udelay(1);
+ ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+ if (!(ctrl & IXGBE_CTRL_RST))
+ break;
+ }
+ if (ctrl & IXGBE_CTRL_RST) {
+ status = IXGBE_ERR_RESET_FAILED;
+ hw_dbg(hw, "Reset polling failed to complete.\n");
+ }
+ /* Clear PF Reset Done bit so PF/VF Mail Ops can work */
+ ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
+ ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD;
+ IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
+
+ msleep(50);
+
+
+
+ /*
+ * Store the original AUTOC/AUTOC2 values if they have not been
+ * stored off yet. Otherwise restore the stored original
+ * values since the reset operation sets back to defaults.
+ */
+ autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+ autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+ if (hw->mac.orig_link_settings_stored == false) {
+ hw->mac.orig_autoc = autoc;
+ hw->mac.orig_autoc2 = autoc2;
+ hw->mac.orig_link_settings_stored = true;
+ } else {
+ if (autoc != hw->mac.orig_autoc)
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc |
+ IXGBE_AUTOC_AN_RESTART));
+
+ if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
+ (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
+ autoc2 &= ~IXGBE_AUTOC2_UPPER_MASK;
+ autoc2 |= (hw->mac.orig_autoc2 &
+ IXGBE_AUTOC2_UPPER_MASK);
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC2, autoc2);
+ }
+ }
+
+ /* Store the permanent mac address */
+ hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
+
+ return status;
+}
+
+/**
+ * ixgbe_clear_vmdq_82599 - Disassociate a VMDq pool index from a rx address
+ * @hw: pointer to hardware struct
+ * @rar: receive address register index to disassociate
+ * @vmdq: VMDq pool index to remove from the rar
+ **/
+s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+ u32 mpsar_lo, mpsar_hi;
+ u32 rar_entries = hw->mac.num_rar_entries;
+
+ if (rar < rar_entries) {
+ mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
+ mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
+
+ if (!mpsar_lo && !mpsar_hi)
+ goto done;
+
+ if (vmdq == IXGBE_CLEAR_VMDQ_ALL) {
+ if (mpsar_lo) {
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0);
+ mpsar_lo = 0;
+ }
+ if (mpsar_hi) {
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0);
+ mpsar_hi = 0;
+ }
+ } else if (vmdq < 32) {
+ mpsar_lo &= ~(1 << vmdq);
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo);
+ } else {
+ mpsar_hi &= ~(1 << (vmdq - 32));
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar_hi);
+ }
+
+ /* was that the last pool using this rar? */
+ if (mpsar_lo == 0 && mpsar_hi == 0 && rar != 0)
+ hw->mac.ops.clear_rar(hw, rar);
+ } else {
+ hw_dbg(hw, "RAR index %d is out of range.\n", rar);
+ }
+
+done:
+ return 0;
+}
+
+/**
+ * ixgbe_set_vmdq_82599 - Associate a VMDq pool index with a rx address
+ * @hw: pointer to hardware struct
+ * @rar: receive address register index to associate with a VMDq index
+ * @vmdq: VMDq pool index
+ **/
+s32 ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+ u32 mpsar;
+ u32 rar_entries = hw->mac.num_rar_entries;
+
+ if (rar < rar_entries) {
+ if (vmdq < 32) {
+ mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar));
+ mpsar |= 1 << vmdq;
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar);
+ } else {
+ mpsar = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar));
+ mpsar |= 1 << (vmdq - 32);
+ IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), mpsar);
+ }
+ } else {
+ hw_dbg(hw, "RAR index %d is out of range.\n", rar);
+ }
+ return 0;
+}
+
+/**
+ * ixgbe_set_vfta_82599 - Set VLAN filter table
+ * @hw: pointer to hardware structure
+ * @vlan: VLAN id to write to VLAN filter
+ * @vind: VMDq output index that maps queue to VLAN id in VFVFB
+ * @vlan_on: boolean flag to turn on/off VLAN in VFVF
+ *
+ * Turn on/off specified VLAN in the VLAN filter table.
+ **/
+s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind,
+ bool vlan_on)
+{
+ u32 regindex;
+ u32 bitindex;
+ u32 bits;
+ u32 first_empty_slot;
+
+ if (vlan > 4095)
+ return IXGBE_ERR_PARAM;
+
+ /*
+ * this is a 2 part operation - first the VFTA, then the
+ * VLVF and VLVFB if vind is set
+ */
+
+ /* Part 1
+ * The VFTA is a bitstring made up of 128 32-bit registers
+ * that enable the particular VLAN id, much like the MTA:
+ * bits[11-5]: which register
+ * bits[4-0]: which bit in the register
+ */
+ regindex = (vlan >> 5) & 0x7F;
+ bitindex = vlan & 0x1F;
+ bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
+ if (vlan_on)
+ bits |= (1 << bitindex);
+ else
+ bits &= ~(1 << bitindex);
+ IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
+
+
+ /* Part 2
+ * If the vind is set
+ * Either vlan_on
+ * make sure the vlan is in VLVF
+ * set the vind bit in the matching VLVFB
+ * Or !vlan_on
+ * clear the pool bit and possibly the vind
+ */
+ if (vind) {
+ /* find the vlanid or the first empty slot */
+ first_empty_slot = 0;
+
+ for (regindex = 1; regindex < IXGBE_VLVF_ENTRIES; regindex++) {
+ bits = IXGBE_READ_REG(hw, IXGBE_VLVF(regindex));
+ if (!bits && !first_empty_slot)
+ first_empty_slot = regindex;
+ else if ((bits & 0x0FFF) == vlan)
+ break;
+ }
+
+ if (regindex >= IXGBE_VLVF_ENTRIES) {
+ if (first_empty_slot)
+ regindex = first_empty_slot;
+ else {
+ hw_dbg(hw, "No space in VLVF.\n");
+ goto out;
+ }
+ }
+
+ if (vlan_on) {
+ /* set the pool bit */
+ if (vind < 32) {
+ bits = IXGBE_READ_REG(hw,
+ IXGBE_VLVFB(regindex * 2));
+ bits |= (1 << vind);
+ IXGBE_WRITE_REG(hw,
+ IXGBE_VLVFB(regindex * 2), bits);
+ } else {
+ bits = IXGBE_READ_REG(hw,
+ IXGBE_VLVFB((regindex * 2) + 1));
+ bits |= (1 << vind);
+ IXGBE_WRITE_REG(hw,
+ IXGBE_VLVFB((regindex * 2) + 1), bits);
+ }
+ } else {
+ /* clear the pool bit */
+ if (vind < 32) {
+ bits = IXGBE_READ_REG(hw,
+ IXGBE_VLVFB(regindex * 2));
+ bits &= ~(1 << vind);
+ IXGBE_WRITE_REG(hw,
+ IXGBE_VLVFB(regindex * 2), bits);
+ bits |= IXGBE_READ_REG(hw,
+ IXGBE_VLVFB((regindex * 2) + 1));
+ } else {
+ bits = IXGBE_READ_REG(hw,
+ IXGBE_VLVFB((regindex * 2) + 1));
+ bits &= ~(1 << vind);
+ IXGBE_WRITE_REG(hw,
+ IXGBE_VLVFB((regindex * 2) + 1), bits);
+ bits |= IXGBE_READ_REG(hw,
+ IXGBE_VLVFB(regindex * 2));
+ }
+ }
+
+ if (bits)
+ IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex),
+ (IXGBE_VLVF_VIEN | vlan));
+ else
+ IXGBE_WRITE_REG(hw, IXGBE_VLVF(regindex), 0);
+ }
+
+out:
+ return 0;
+}
+
+/**
+ * ixgbe_clear_vfta_82599 - Clear VLAN filter table
+ * @hw: pointer to hardware structure
+ *
+ * Clears the VLAN filer table, and the VMDq index associated with the filter
+ **/
+s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw)
+{
+ u32 offset;
+
+ for (offset = 0; offset < hw->mac.vft_size; offset++)
+ IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
+
+ for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) {
+ IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset * 2) + 1), 0);
+ }
+
+ return 0;
+}
+
+/**
+ * ixgbe_blink_led_start_82599 - Blink LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to blink
+ **/
+s32 ixgbe_blink_led_start_82599(struct ixgbe_hw *hw, u32 index)
+{
+ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+ led_reg &= ~IXGBE_LED_MODE_MASK(index);
+ led_reg |= IXGBE_LED_BLINK(index);
+ IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_blink_led_stop_82599 - Stop blinking LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to stop blinking
+ **/
+s32 ixgbe_blink_led_stop_82599(struct ixgbe_hw *hw, u32 index)
+{
+ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+ led_reg &= ~IXGBE_LED_MODE_MASK(index);
+ led_reg &= ~IXGBE_LED_BLINK(index);
+ IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_init_uta_tables_82599 - Initialize the Unicast Table Array
+ * @hw: pointer to hardware structure
+ **/
+s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw)
+{
+ int i;
+ hw_dbg(hw, " Clearing UTA\n");
+
+ for (i = 0; i < 128; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_UTA(i), 0);
+
+ return 0;
+}
+
+/**
+ * ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register
+ * @hw: pointer to hardware structure
+ * @reg: analog register to read
+ * @val: read value
+ *
+ * Performs read operation to Omer analog register specified.
+ **/
+s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val)
+{
+ u32 core_ctl;
+
+ IXGBE_WRITE_REG(hw, IXGBE_CORECTL, IXGBE_CORECTL_WRITE_CMD |
+ (reg << 8));
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(10);
+ core_ctl = IXGBE_READ_REG(hw, IXGBE_CORECTL);
+ *val = (u8)core_ctl;
+
+ return 0;
+}
+
+/**
+ * ixgbe_write_analog_reg8_82599 - Writes 8 bit Omer analog register
+ * @hw: pointer to hardware structure
+ * @reg: atlas register to write
+ * @val: value to write
+ *
+ * Performs write operation to Omer analog register specified.
+ **/
+s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
+{
+ u32 core_ctl;
+
+ core_ctl = (reg << 8) | val;
+ IXGBE_WRITE_REG(hw, IXGBE_CORECTL, core_ctl);
+ IXGBE_WRITE_FLUSH(hw);
+ udelay(10);
+
+ return 0;
+}
+
+/**
+ * ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx
+ * @hw: pointer to hardware structure
+ *
+ * Starts the hardware using the generic start_hw function.
+ * Then performs device-specific:
+ * Clears the rate limiter registers.
+ **/
+s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
+{
+ u32 q_num;
+
+ ixgbe_start_hw_generic(hw);
+
+ /* Clear the rate limiters */
+ for (q_num = 0; q_num < hw->mac.max_tx_queues; q_num++) {
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, q_num);
+ IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
+ }
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_identify_phy_82599 - Get physical layer module
+ * @hw: pointer to hardware structure
+ *
+ * Determines the physical layer module found on the current adapter.
+ **/
+s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
+{
+ s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
+ status = ixgbe_identify_phy_generic(hw);
+ if (status != 0)
+ status = ixgbe_identify_sfp_module_generic(hw);
+ return status;
+}
+
+/**
+ * ixgbe_get_supported_physical_layer_82599 - Returns physical layer type
+ * @hw: pointer to hardware structure
+ *
+ * Determines physical layer capabilities of the current configuration.
+ **/
+u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
+{
+ u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ u8 comp_codes_10g = 0;
+
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82599:
+ case IXGBE_DEV_ID_82599_KX4:
+ /* Default device ID is mezzanine card KX/KX4 */
+ physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
+ IXGBE_PHYSICAL_LAYER_1000BASE_KX);
+ break;
+ case IXGBE_DEV_ID_82599_SFP:
+ hw->phy.ops.identify_sfp(hw);
+
+ switch (hw->phy.sfp_type) {
+ case ixgbe_sfp_type_da_cu:
+ case ixgbe_sfp_type_da_cu_core0:
+ case ixgbe_sfp_type_da_cu_core1:
+ physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+ break;
+ case ixgbe_sfp_type_sr:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+ break;
+ case ixgbe_sfp_type_lr:
+ physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+ break;
+ case ixgbe_sfp_type_srlr_core0:
+ case ixgbe_sfp_type_srlr_core1:
+ hw->phy.ops.read_i2c_eeprom(hw,
+ IXGBE_SFF_10GBE_COMP_CODES,
+ &comp_codes_10g);
+ if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+ physical_layer =
+ IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+ else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+ physical_layer =
+ IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+ else
+ physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ default:
+ physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ break;
+ }
+ break;
+ default:
+ physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+ break;
+ }
+
+ return physical_layer;
+}
+
+/**
+ * ixgbe_enable_rx_dma_82599 - Enable the Rx DMA unit on 82599
+ * @hw: pointer to hardware structure
+ * @regval: register value to write to RXCTRL
+ *
+ * Enables the Rx DMA unit for 82599
+ **/
+s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
+{
+#define IXGBE_MAX_SECRX_POLL 30
+ int i;
+ int secrxreg;
+
+ /*
+ * Workaround for 82599 silicon errata when enabling the Rx datapath.
+ * If traffic is incoming before we enable the Rx unit, it could hang
+ * the Rx DMA unit. Therefore, make sure the security engine is
+ * completely disabled prior to enabling the Rx unit.
+ */
+ secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+ secrxreg |= IXGBE_SECRXCTRL_RX_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
+ for (i = 0; i < IXGBE_MAX_SECRX_POLL; i++) {
+ secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXSTAT);
+ if (secrxreg & IXGBE_SECRXSTAT_SECRX_RDY)
+ break;
+ else
+ udelay(10);
+ }
+
+ /* For informational purposes only */
+ if (i >= IXGBE_MAX_SECRX_POLL)
+ hw_dbg(hw, "Rx unit being enabled before security "
+ "path fully disabled. Continuing with init.\n");
+
+ IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
+ secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+ secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
+ IXGBE_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+static struct ixgbe_mac_operations mac_ops_82599 = {
+ .init_hw = &ixgbe_init_hw_generic,
+ .reset_hw = &ixgbe_reset_hw_82599,
+ .start_hw = &ixgbe_start_hw_82599,
+ .clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic,
+ .get_media_type = &ixgbe_get_media_type_82599,
+ .get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82599,
+ .enable_rx_dma = &ixgbe_enable_rx_dma_82599,
+ .get_mac_addr = &ixgbe_get_mac_addr_generic,
+ .stop_adapter = &ixgbe_stop_adapter_generic,
+ .get_bus_info = &ixgbe_get_bus_info_generic,
+ .set_lan_id = &ixgbe_set_lan_id_multi_port_pcie,
+ .read_analog_reg8 = &ixgbe_read_analog_reg8_82599,
+ .write_analog_reg8 = &ixgbe_write_analog_reg8_82599,
+ .setup_link = &ixgbe_setup_mac_link_82599,
+ .setup_link_speed = &ixgbe_setup_mac_link_speed_82599,
+ .check_link = &ixgbe_check_mac_link_82599,
+ .get_link_capabilities = &ixgbe_get_link_capabilities_82599,
+ .led_on = &ixgbe_led_on_generic,
+ .led_off = &ixgbe_led_off_generic,
+ .blink_led_start = &ixgbe_blink_led_start_82599,
+ .blink_led_stop = &ixgbe_blink_led_stop_82599,
+ .set_rar = &ixgbe_set_rar_generic,
+ .clear_rar = &ixgbe_clear_rar_generic,
+ .set_vmdq = &ixgbe_set_vmdq_82599,
+ .clear_vmdq = &ixgbe_clear_vmdq_82599,
+ .init_rx_addrs = &ixgbe_init_rx_addrs_generic,
+ .update_uc_addr_list = &ixgbe_update_uc_addr_list_generic,
+ .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic,
+ .enable_mc = &ixgbe_enable_mc_generic,
+ .disable_mc = &ixgbe_disable_mc_generic,
+ .clear_vfta = &ixgbe_clear_vfta_82599,
+ .set_vfta = &ixgbe_set_vfta_82599,
+ .setup_fc = &ixgbe_setup_fc_generic,
+ .init_uta_tables = &ixgbe_init_uta_tables_82599,
+ .setup_sfp = &ixgbe_setup_sfp_modules_82599,
+};
+
+static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
+ .init_params = &ixgbe_init_eeprom_params_generic,
+ .read = &ixgbe_read_eeprom_generic,
+ .write = &ixgbe_write_eeprom_generic,
+ .validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
+ .update_checksum = &ixgbe_update_eeprom_checksum_generic,
+};
+
+static struct ixgbe_phy_operations phy_ops_82599 = {
+ .identify = &ixgbe_identify_phy_82599,
+ .identify_sfp = &ixgbe_identify_sfp_module_generic,
+ .reset = &ixgbe_reset_phy_generic,
+ .read_reg = &ixgbe_read_phy_reg_generic,
+ .write_reg = &ixgbe_write_phy_reg_generic,
+ .setup_link = &ixgbe_setup_phy_link_generic,
+ .setup_link_speed = &ixgbe_setup_phy_link_speed_generic,
+ .read_i2c_byte = &ixgbe_read_i2c_byte_generic,
+ .write_i2c_byte = &ixgbe_write_i2c_byte_generic,
+ .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic,
+ .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic,
+};
+
+struct ixgbe_info ixgbe_82599_info = {
+ .mac = ixgbe_mac_82599EB,
+ .get_invariants = &ixgbe_get_invariants_82599,
+ .mac_ops = &mac_ops_82599,
+ .eeprom_ops = &eeprom_ops_82599,
+ .phy_ops = &phy_ops_82599,
+};
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index f67c68404bb3..63ab6671d08e 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -29,6 +29,7 @@
#include <linux/delay.h>
#include <linux/sched.h>
+#include "ixgbe.h"
#include "ixgbe_common.h"
#include "ixgbe_phy.h"
@@ -80,9 +81,6 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
/* Clear the VLAN filter table */
hw->mac.ops.clear_vfta(hw);
- /* Set up link */
- hw->mac.ops.setup_link(hw);
-
/* Clear statistics registers */
hw->mac.ops.clear_hw_cntrs(hw);
@@ -254,6 +252,81 @@ s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr)
}
/**
+ * ixgbe_get_bus_info_generic - Generic set PCI bus info
+ * @hw: pointer to hardware structure
+ *
+ * Sets the PCI bus info (speed, width, type) within the ixgbe_hw structure
+ **/
+s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
+{
+ struct ixgbe_adapter *adapter = hw->back;
+ struct ixgbe_mac_info *mac = &hw->mac;
+ u16 link_status;
+
+ hw->bus.type = ixgbe_bus_type_pci_express;
+
+ /* Get the negotiated link width and speed from PCI config space */
+ pci_read_config_word(adapter->pdev, IXGBE_PCI_LINK_STATUS,
+ &link_status);
+
+ switch (link_status & IXGBE_PCI_LINK_WIDTH) {
+ case IXGBE_PCI_LINK_WIDTH_1:
+ hw->bus.width = ixgbe_bus_width_pcie_x1;
+ break;
+ case IXGBE_PCI_LINK_WIDTH_2:
+ hw->bus.width = ixgbe_bus_width_pcie_x2;
+ break;
+ case IXGBE_PCI_LINK_WIDTH_4:
+ hw->bus.width = ixgbe_bus_width_pcie_x4;
+ break;
+ case IXGBE_PCI_LINK_WIDTH_8:
+ hw->bus.width = ixgbe_bus_width_pcie_x8;
+ break;
+ default:
+ hw->bus.width = ixgbe_bus_width_unknown;
+ break;
+ }
+
+ switch (link_status & IXGBE_PCI_LINK_SPEED) {
+ case IXGBE_PCI_LINK_SPEED_2500:
+ hw->bus.speed = ixgbe_bus_speed_2500;
+ break;
+ case IXGBE_PCI_LINK_SPEED_5000:
+ hw->bus.speed = ixgbe_bus_speed_5000;
+ break;
+ default:
+ hw->bus.speed = ixgbe_bus_speed_unknown;
+ break;
+ }
+
+ mac->ops.set_lan_id(hw);
+
+ return 0;
+}
+
+/**
+ * ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
+ * @hw: pointer to the HW structure
+ *
+ * Determines the LAN function id by reading memory-mapped registers
+ * and swaps the port value if requested.
+ **/
+void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw)
+{
+ struct ixgbe_bus_info *bus = &hw->bus;
+ u32 reg;
+
+ reg = IXGBE_READ_REG(hw, IXGBE_STATUS);
+ bus->func = (reg & IXGBE_STATUS_LAN_ID) >> IXGBE_STATUS_LAN_ID_SHIFT;
+ bus->lan_id = bus->func;
+
+ /* check for a port swap */
+ reg = IXGBE_READ_REG(hw, IXGBE_FACTPS);
+ if (reg & IXGBE_FACTPS_LFS)
+ bus->func ^= 0x1;
+}
+
+/**
* ixgbe_stop_adapter_generic - Generic stop Tx/Rx units
* @hw: pointer to hardware structure
*
@@ -393,6 +466,73 @@ s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
+ * @hw: pointer to hardware structure
+ * @offset: offset within the EEPROM to be written to
+ * @data: 16 bit word to be written to the EEPROM
+ *
+ * If ixgbe_eeprom_update_checksum is not called after this function, the
+ * EEPROM will most likely contain an invalid checksum.
+ **/
+s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
+{
+ s32 status;
+ u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
+
+ hw->eeprom.ops.init_params(hw);
+
+ if (offset >= hw->eeprom.word_size) {
+ status = IXGBE_ERR_EEPROM;
+ goto out;
+ }
+
+ /* Prepare the EEPROM for writing */
+ status = ixgbe_acquire_eeprom(hw);
+
+ if (status == 0) {
+ if (ixgbe_ready_eeprom(hw) != 0) {
+ ixgbe_release_eeprom(hw);
+ status = IXGBE_ERR_EEPROM;
+ }
+ }
+
+ if (status == 0) {
+ ixgbe_standby_eeprom(hw);
+
+ /* Send the WRITE ENABLE command (8 bit opcode ) */
+ ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_WREN_OPCODE_SPI,
+ IXGBE_EEPROM_OPCODE_BITS);
+
+ ixgbe_standby_eeprom(hw);
+
+ /*
+ * Some SPI eeproms use the 8th address bit embedded in the
+ * opcode
+ */
+ if ((hw->eeprom.address_bits == 8) && (offset >= 128))
+ write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+
+ /* Send the Write command (8-bit opcode + addr) */
+ ixgbe_shift_out_eeprom_bits(hw, write_opcode,
+ IXGBE_EEPROM_OPCODE_BITS);
+ ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
+ hw->eeprom.address_bits);
+
+ /* Send the data */
+ data = (data >> 8) | (data << 8);
+ ixgbe_shift_out_eeprom_bits(hw, data, 16);
+ ixgbe_standby_eeprom(hw);
+
+ msleep(hw->eeprom.semaphore_delay);
+ /* Done with writing - release the EEPROM */
+ ixgbe_release_eeprom(hw);
+ }
+
+out:
+ return status;
+}
+
+/**
* ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
* @hw: pointer to hardware structure
* @offset: offset within the EEPROM to be read
@@ -521,7 +661,7 @@ static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw)
static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
{
s32 status = 0;
- u32 eec;
+ u32 eec = 0;
u32 i;
if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0)
@@ -1490,6 +1630,327 @@ s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
}
/**
+ * ixgbe_fc_enable - Enable flow control
+ * @hw: pointer to hardware structure
+ * @packetbuf_num: packet buffer number (0-7)
+ *
+ * Enable flow control according to the current settings.
+ **/
+s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
+{
+ s32 ret_val = 0;
+ u32 mflcn_reg;
+ u32 fccfg_reg;
+ u32 reg;
+
+ mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+ mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE);
+
+ fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
+ fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY);
+
+ /*
+ * The possible values of fc.current_mode are:
+ * 0: Flow control is completely disabled
+ * 1: Rx flow control is enabled (we can receive pause frames,
+ * but not send pause frames).
+ * 2: Tx flow control is enabled (we can send pause frames but
+ * we do not support receiving pause frames).
+ * 3: Both Rx and Tx flow control (symmetric) are enabled.
+ * 4: Priority Flow Control is enabled.
+ * other: Invalid.
+ */
+ switch (hw->fc.current_mode) {
+ case ixgbe_fc_none:
+ /* Flow control completely disabled by software override. */
+ break;
+ case ixgbe_fc_rx_pause:
+ /*
+ * Rx Flow control is enabled and Tx Flow control is
+ * disabled by software override. Since there really
+ * isn't a way to advertise that we are capable of RX
+ * Pause ONLY, we will advertise that we support both
+ * symmetric and asymmetric Rx PAUSE. Later, we will
+ * disable the adapter's ability to send PAUSE frames.
+ */
+ mflcn_reg |= IXGBE_MFLCN_RFCE;
+ break;
+ case ixgbe_fc_tx_pause:
+ /*
+ * Tx Flow control is enabled, and Rx Flow control is
+ * disabled by software override.
+ */
+ fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
+ break;
+ case ixgbe_fc_full:
+ /* Flow control (both Rx and Tx) is enabled by SW override. */
+ mflcn_reg |= IXGBE_MFLCN_RFCE;
+ fccfg_reg |= IXGBE_FCCFG_TFCE_802_3X;
+ break;
+#ifdef CONFIG_DCB
+ case ixgbe_fc_pfc:
+ goto out;
+ break;
+#endif
+ default:
+ hw_dbg(hw, "Flow control param set incorrectly\n");
+ ret_val = -IXGBE_ERR_CONFIG;
+ goto out;
+ break;
+ }
+
+ /* Enable 802.3x based flow control settings. */
+ IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
+ IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
+
+ /* Set up and enable Rx high/low water mark thresholds, enable XON. */
+ if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
+ if (hw->fc.send_xon)
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
+ (hw->fc.low_water | IXGBE_FCRTL_XONE));
+ else
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
+ hw->fc.low_water);
+
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num),
+ (hw->fc.high_water | IXGBE_FCRTH_FCEN));
+ }
+
+ /* Configure pause time (2 TCs per register) */
+ reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num));
+ if ((packetbuf_num & 1) == 0)
+ reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
+ else
+ reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16);
+ IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg);
+
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
+
+out:
+ return ret_val;
+}
+
+/**
+ * ixgbe_fc_autoneg - Configure flow control
+ * @hw: pointer to hardware structure
+ *
+ * Negotiates flow control capabilities with link partner using autoneg and
+ * applies the results.
+ **/
+s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
+{
+ s32 ret_val = 0;
+ u32 i, reg, pcs_anadv_reg, pcs_lpab_reg;
+
+ reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
+
+ /*
+ * The possible values of fc.current_mode are:
+ * 0: Flow control is completely disabled
+ * 1: Rx flow control is enabled (we can receive pause frames,
+ * but not send pause frames).
+ * 2: Tx flow control is enabled (we can send pause frames but
+ * we do not support receiving pause frames).
+ * 3: Both Rx and Tx flow control (symmetric) are enabled.
+ * 4: Priority Flow Control is enabled.
+ * other: Invalid.
+ */
+ switch (hw->fc.current_mode) {
+ case ixgbe_fc_none:
+ /* Flow control completely disabled by software override. */
+ reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+ break;
+ case ixgbe_fc_rx_pause:
+ /*
+ * Rx Flow control is enabled and Tx Flow control is
+ * disabled by software override. Since there really
+ * isn't a way to advertise that we are capable of RX
+ * Pause ONLY, we will advertise that we support both
+ * symmetric and asymmetric Rx PAUSE. Later, we will
+ * disable the adapter's ability to send PAUSE frames.
+ */
+ reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+ break;
+ case ixgbe_fc_tx_pause:
+ /*
+ * Tx Flow control is enabled, and Rx Flow control is
+ * disabled by software override.
+ */
+ reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
+ reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
+ break;
+ case ixgbe_fc_full:
+ /* Flow control (both Rx and Tx) is enabled by SW override. */
+ reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+ break;
+#ifdef CONFIG_DCB
+ case ixgbe_fc_pfc:
+ goto out;
+ break;
+#endif
+ default:
+ hw_dbg(hw, "Flow control param set incorrectly\n");
+ ret_val = -IXGBE_ERR_CONFIG;
+ goto out;
+ break;
+ }
+
+ IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
+ reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
+
+ /* Set PCS register for autoneg */
+ /* Enable and restart autoneg */
+ reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART;
+
+ /* Disable AN timeout */
+ if (hw->fc.strict_ieee)
+ reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
+
+ hw_dbg(hw, "Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg);
+ IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
+
+ /* See if autonegotiation has succeeded */
+ hw->mac.autoneg_succeeded = 0;
+ for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
+ msleep(10);
+ reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
+ if ((reg & (IXGBE_PCS1GLSTA_LINK_OK |
+ IXGBE_PCS1GLSTA_AN_COMPLETE)) ==
+ (IXGBE_PCS1GLSTA_LINK_OK |
+ IXGBE_PCS1GLSTA_AN_COMPLETE)) {
+ if (!(reg & IXGBE_PCS1GLSTA_AN_TIMED_OUT))
+ hw->mac.autoneg_succeeded = 1;
+ break;
+ }
+ }
+
+ if (!hw->mac.autoneg_succeeded) {
+ /* Autoneg failed to achieve a link, so we turn fc off */
+ hw->fc.current_mode = ixgbe_fc_none;
+ hw_dbg(hw, "Flow Control = NONE.\n");
+ goto out;
+ }
+
+ /*
+ * Read the AN advertisement and LP ability registers and resolve
+ * local flow control settings accordingly
+ */
+ pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
+ pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
+ if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) {
+ /*
+ * Now we need to check if the user selected Rx ONLY
+ * of pause frames. In this case, we had to advertise
+ * FULL flow control because we could not advertise RX
+ * ONLY. Hence, we must now check to see if we need to
+ * turn OFF the TRANSMISSION of PAUSE frames.
+ */
+ if (hw->fc.requested_mode == ixgbe_fc_full) {
+ hw->fc.current_mode = ixgbe_fc_full;
+ hw_dbg(hw, "Flow Control = FULL.\n");
+ } else {
+ hw->fc.current_mode = ixgbe_fc_rx_pause;
+ hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
+ }
+ } else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
+ (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
+ hw->fc.current_mode = ixgbe_fc_tx_pause;
+ hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
+ } else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
+ !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
+ (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
+ hw->fc.current_mode = ixgbe_fc_rx_pause;
+ hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
+ } else {
+ hw->fc.current_mode = ixgbe_fc_none;
+ hw_dbg(hw, "Flow Control = NONE.\n");
+ }
+
+out:
+ return ret_val;
+}
+
+/**
+ * ixgbe_setup_fc_generic - Set up flow control
+ * @hw: pointer to hardware structure
+ *
+ * Sets up flow control.
+ **/
+s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
+{
+ s32 ret_val = 0;
+ ixgbe_link_speed speed;
+ bool link_up;
+
+#ifdef CONFIG_DCB
+ if (hw->fc.requested_mode == ixgbe_fc_pfc) {
+ hw->fc.current_mode = hw->fc.requested_mode;
+ goto out;
+ }
+
+#endif
+ /* Validate the packetbuf configuration */
+ if (packetbuf_num < 0 || packetbuf_num > 7) {
+ hw_dbg(hw, "Invalid packet buffer number [%d], expected range "
+ "is 0-7\n", packetbuf_num);
+ ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+ goto out;
+ }
+
+ /*
+ * Validate the water mark configuration. Zero water marks are invalid
+ * because it causes the controller to just blast out fc packets.
+ */
+ if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
+ hw_dbg(hw, "Invalid water mark configuration\n");
+ ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+ goto out;
+ }
+
+ /*
+ * Validate the requested mode. Strict IEEE mode does not allow
+ * ixgbe_fc_rx_pause because it will cause testing anomalies.
+ */
+ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
+ hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict "
+ "IEEE mode\n");
+ ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
+ goto out;
+ }
+
+ /*
+ * 10gig parts do not have a word in the EEPROM to determine the
+ * default flow control setting, so we explicitly set it to full.
+ */
+ if (hw->fc.requested_mode == ixgbe_fc_default)
+ hw->fc.requested_mode = ixgbe_fc_full;
+
+ /*
+ * Save off the requested flow control mode for use later. Depending
+ * on the link partner's capabilities, we may or may not use this mode.
+ */
+ hw->fc.current_mode = hw->fc.requested_mode;
+
+ /* Decide whether to use autoneg or not. */
+ hw->mac.ops.check_link(hw, &speed, &link_up, false);
+ if (!hw->fc.disable_fc_autoneg && hw->phy.multispeed_fiber &&
+ (speed == IXGBE_LINK_SPEED_1GB_FULL))
+ ret_val = ixgbe_fc_autoneg(hw);
+
+ if (ret_val)
+ goto out;
+
+ ret_val = ixgbe_fc_enable(hw, packetbuf_num);
+
+out:
+ return ret_val;
+}
+
+/**
* ixgbe_disable_pcie_master - Disable PCI-express master access
* @hw: pointer to hardware structure
*
@@ -1597,3 +2058,16 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
ixgbe_release_eeprom_semaphore(hw);
}
+/**
+ * ixgbe_enable_rx_dma_generic - Enable the Rx DMA unit
+ * @hw: pointer to hardware structure
+ * @regval: register value to write to RXCTRL
+ *
+ * Enables the Rx DMA unit
+ **/
+s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval)
+{
+ IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, regval);
+
+ return 0;
+}
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index 192f8d012911..24f73e719c3f 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -37,12 +37,14 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw);
s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num);
s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr);
s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw);
+void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw);
s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw);
s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
+s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
u16 *data);
@@ -61,6 +63,10 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
u32 addr_count, ixgbe_mc_addr_itr func);
s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
+s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
+s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num);
+s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packtetbuf_num);
+s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw);
s32 ixgbe_validate_mac_addr(u8 *mac_addr);
s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask);
@@ -72,6 +78,13 @@ s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val);
#define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
+#ifndef writeq
+#define writeq(val, addr) writel((u32) (val), addr); \
+ writel((u32) (val >> 32), (addr + 4));
+#endif
+
+#define IXGBE_WRITE_REG64(a, reg, value) writeq((value), ((a)->hw_addr + (reg)))
+
#define IXGBE_READ_REG(a, reg) readl((a)->hw_addr + (reg))
#define IXGBE_WRITE_REG_ARRAY(a, reg, offset, value) (\
@@ -83,14 +96,11 @@ s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val);
#define IXGBE_WRITE_FLUSH(a) IXGBE_READ_REG(a, IXGBE_STATUS)
#ifdef DEBUG
+extern char *ixgbe_get_hw_dev_name(struct ixgbe_hw *hw);
#define hw_dbg(hw, format, arg...) \
-printk(KERN_DEBUG, "%s: " format, ixgbe_get_hw_dev_name(hw), ##arg);
+ printk(KERN_DEBUG "%s: " format, ixgbe_get_hw_dev_name(hw), ##arg)
#else
-static inline int __attribute__ ((format (printf, 2, 3)))
-hw_dbg(struct ixgbe_hw *hw, const char *format, ...)
-{
- return 0;
-}
+#define hw_dbg(hw, format, arg...) do {} while (0)
#endif
#endif /* IXGBE_COMMON */
diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c
index e2e28ac63dec..a1562287342f 100644
--- a/drivers/net/ixgbe/ixgbe_dcb.c
+++ b/drivers/net/ixgbe/ixgbe_dcb.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -31,6 +31,7 @@
#include "ixgbe_type.h"
#include "ixgbe_dcb.h"
#include "ixgbe_dcb_82598.h"
+#include "ixgbe_dcb_82599.h"
/**
* ixgbe_dcb_config - Struct containing DCB settings.
@@ -215,6 +216,8 @@ s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count);
return ret;
}
@@ -232,6 +235,8 @@ s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count);
return ret;
}
@@ -248,6 +253,8 @@ s32 ixgbe_dcb_config_rx_arbiter(struct ixgbe_hw *hw,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_config_rx_arbiter_82598(hw, dcb_config);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_config_rx_arbiter_82599(hw, dcb_config);
return ret;
}
@@ -264,6 +271,8 @@ s32 ixgbe_dcb_config_tx_desc_arbiter(struct ixgbe_hw *hw,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, dcb_config);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, dcb_config);
return ret;
}
@@ -280,6 +289,8 @@ s32 ixgbe_dcb_config_tx_data_arbiter(struct ixgbe_hw *hw,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, dcb_config);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, dcb_config);
return ret;
}
@@ -296,6 +307,8 @@ s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_config_pfc_82598(hw, dcb_config);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_config_pfc_82599(hw, dcb_config);
return ret;
}
@@ -311,6 +324,8 @@ s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw)
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_config_tc_stats_82598(hw);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_config_tc_stats_82599(hw);
return ret;
}
@@ -327,6 +342,8 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
s32 ret = 0;
if (hw->mac.type == ixgbe_mac_82598EB)
ret = ixgbe_dcb_hw_config_82598(hw, dcb_config);
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ ret = ixgbe_dcb_hw_config_82599(hw, dcb_config);
return ret;
}
diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h
index 75f6efe1e369..64a9fa15c059 100644
--- a/drivers/net/ixgbe/ixgbe_dcb.h
+++ b/drivers/net/ixgbe/ixgbe_dcb.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -75,6 +75,26 @@ enum strict_prio_type {
prio_link
};
+/* DCB capability definitions */
+#define IXGBE_DCB_PG_SUPPORT 0x00000001
+#define IXGBE_DCB_PFC_SUPPORT 0x00000002
+#define IXGBE_DCB_BCN_SUPPORT 0x00000004
+#define IXGBE_DCB_UP2TC_SUPPORT 0x00000008
+#define IXGBE_DCB_GSP_SUPPORT 0x00000010
+
+#define IXGBE_DCB_8_TC_SUPPORT 0x80
+
+struct dcb_support {
+ /* DCB capabilities */
+ u32 capabilities;
+
+ /* Each bit represents a number of TCs configurable in the hw.
+ * If 8 traffic classes can be configured, the value is 0x80.
+ */
+ u8 traffic_classes;
+ u8 pfc_traffic_classes;
+};
+
/* Traffic class bandwidth allocation per direction */
struct tc_bw_alloc {
u8 bwg_id; /* Bandwidth Group (BWG) ID */
@@ -108,38 +128,18 @@ enum dcb_rx_pba_cfg {
pba_80_48 /* PBA[0-3] each use 80KB, PBA[4-7] each use 48KB */
};
-/*
- * This structure contains many values encoded as fixed-point
- * numbers, meaning that some of bits are dedicated to the
- * magnitude and others to the fraction part. In the comments
- * this is shown as f=n, where n is the number of fraction bits.
- * These fraction bits are always the low-order bits. The size
- * of the magnitude is not specified.
- */
-struct bcn_config {
- u32 rp_admin_mode[MAX_TRAFFIC_CLASS]; /* BCN enabled, per TC */
- u32 bcna_option[2]; /* BCNA Port + MAC Addr */
- u32 rp_w; /* Derivative Weight, f=3 */
- u32 rp_gi; /* Increase Gain, f=12 */
- u32 rp_gd; /* Decrease Gain, f=12 */
- u32 rp_ru; /* Rate Unit */
- u32 rp_alpha; /* Max Decrease Factor, f=12 */
- u32 rp_beta; /* Max Increase Factor, f=12 */
- u32 rp_ri; /* Initial Rate */
- u32 rp_td; /* Drift Interval Timer */
- u32 rp_rd; /* Drift Increase */
- u32 rp_tmax; /* Severe Congestion Backoff Timer Range */
- u32 rp_rmin; /* Severe Congestion Restart Rate */
- u32 rp_wrtt; /* RTT Moving Average Weight */
+struct dcb_num_tcs {
+ u8 pg_tcs;
+ u8 pfc_tcs;
};
struct ixgbe_dcb_config {
- struct bcn_config bcn;
-
+ struct dcb_support support;
+ struct dcb_num_tcs num_tcs;
struct tc_configuration tc_config[MAX_TRAFFIC_CLASS];
u8 bw_percentage[2][MAX_BW_GROUP]; /* One each for Tx/Rx */
-
- bool round_robin_enable;
+ bool pfc_mode_enable;
+ bool round_robin_enable;
enum dcb_rx_pba_cfg rx_pba_cfg;
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c
index 2c046b0b5d28..62206273d888 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82598.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -298,7 +298,6 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw,
reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
reg &= ~IXGBE_RMCS_TFCE_802_3X;
/* correct the reporting of our flow control status */
- hw->fc.type = ixgbe_fc_none;
reg |= IXGBE_RMCS_TFCE_PRIORITY;
IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.h b/drivers/net/ixgbe/ixgbe_dcb_82598.h
index 1e6a313719d7..ebbe53c352a7 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82598.h
+++ b/drivers/net/ixgbe/ixgbe_dcb_82598.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2007 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c
new file mode 100644
index 000000000000..470b676c1dae
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c
@@ -0,0 +1,467 @@
+/*******************************************************************************
+
+ Intel 10 Gigabit PCI Express Linux driver
+ Copyright(c) 1999 - 2009 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include "ixgbe.h"
+#include "ixgbe_type.h"
+#include "ixgbe_dcb.h"
+#include "ixgbe_dcb_82599.h"
+
+/**
+ * ixgbe_dcb_get_tc_stats_82599 - Returns status for each traffic class
+ * @hw: pointer to hardware structure
+ * @stats: pointer to statistics structure
+ * @tc_count: Number of elements in bwg_array.
+ *
+ * This function returns the status data for each of the Traffic Classes in use.
+ */
+s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw,
+ struct ixgbe_hw_stats *stats,
+ u8 tc_count)
+{
+ int tc;
+
+ if (tc_count > MAX_TRAFFIC_CLASS)
+ return DCB_ERR_PARAM;
+ /* Statistics pertaining to each traffic class */
+ for (tc = 0; tc < tc_count; tc++) {
+ /* Transmitted Packets */
+ stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc));
+ /* Transmitted Bytes */
+ stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc));
+ /* Received Packets */
+ stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc));
+ /* Received Bytes */
+ stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc));
+ }
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_get_pfc_stats_82599 - Return CBFC status data
+ * @hw: pointer to hardware structure
+ * @stats: pointer to statistics structure
+ * @tc_count: Number of elements in bwg_array.
+ *
+ * This function returns the CBFC status data for each of the Traffic Classes.
+ */
+s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw,
+ struct ixgbe_hw_stats *stats,
+ u8 tc_count)
+{
+ int tc;
+
+ if (tc_count > MAX_TRAFFIC_CLASS)
+ return DCB_ERR_PARAM;
+ for (tc = 0; tc < tc_count; tc++) {
+ /* Priority XOFF Transmitted */
+ stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
+ /* Priority XOFF Received */
+ stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(tc));
+ }
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_config_packet_buffers_82599 - Configure DCB packet buffers
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure packet buffers for DCB mode.
+ */
+s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config)
+{
+ s32 ret_val = 0;
+ u32 value = IXGBE_RXPBSIZE_64KB;
+ u8 i = 0;
+
+ /* Setup Rx packet buffer sizes */
+ switch (dcb_config->rx_pba_cfg) {
+ case pba_80_48:
+ /* Setup the first four at 80KB */
+ value = IXGBE_RXPBSIZE_80KB;
+ for (; i < 4; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
+ /* Setup the last four at 48KB...don't re-init i */
+ value = IXGBE_RXPBSIZE_48KB;
+ /* Fall Through */
+ case pba_equal:
+ default:
+ for (; i < IXGBE_MAX_PACKET_BUFFERS; i++)
+ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
+
+ /* Setup Tx packet buffer sizes */
+ for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i),
+ IXGBE_TXPBSIZE_20KB);
+ IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i),
+ IXGBE_TXPBTHRESH_DCB);
+ }
+ break;
+ }
+
+ return ret_val;
+}
+
+/**
+ * ixgbe_dcb_config_rx_arbiter_82599 - Config Rx Data arbiter
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure Rx Packet Arbiter and credits for each traffic class.
+ */
+s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config)
+{
+ struct tc_bw_alloc *p;
+ u32 reg = 0;
+ u32 credit_refill = 0;
+ u32 credit_max = 0;
+ u8 i = 0;
+
+ /* Disable the arbiter before changing parameters */
+ IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, IXGBE_RTRPCS_ARBDIS);
+
+ /* Map all traffic classes to their UP, 1 to 1 */
+ reg = 0;
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+ reg |= (i << (i * IXGBE_RTRUP2TC_UP_SHIFT));
+ IXGBE_WRITE_REG(hw, IXGBE_RTRUP2TC, reg);
+
+ /* Configure traffic class credits and priority */
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+ p = &dcb_config->tc_config[i].path[DCB_RX_CONFIG];
+
+ credit_refill = p->data_credits_refill;
+ credit_max = p->data_credits_max;
+ reg = credit_refill | (credit_max << IXGBE_RTRPT4C_MCL_SHIFT);
+
+ reg |= (u32)(p->bwg_id) << IXGBE_RTRPT4C_BWG_SHIFT;
+
+ if (p->prio_type == prio_link)
+ reg |= IXGBE_RTRPT4C_LSP;
+
+ IXGBE_WRITE_REG(hw, IXGBE_RTRPT4C(i), reg);
+ }
+
+ /*
+ * Configure Rx packet plane (recycle mode; WSP) and
+ * enable arbiter
+ */
+ reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC;
+ IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg);
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_config_tx_desc_arbiter_82599 - Config Tx Desc. arbiter
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure Tx Descriptor Arbiter and credits for each traffic class.
+ */
+s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config)
+{
+ struct tc_bw_alloc *p;
+ u32 reg, max_credits;
+ u8 i;
+
+ /* Disable the arbiter before changing parameters */
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, IXGBE_RTTDCS_ARBDIS);
+
+ /* Clear the per-Tx queue credits; we use per-TC instead */
+ for (i = 0; i < 128; i++) {
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDT1C, 0);
+ }
+
+ /* Configure traffic class credits and priority */
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+ p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
+ max_credits = dcb_config->tc_config[i].desc_credits_max;
+ reg = max_credits << IXGBE_RTTDT2C_MCL_SHIFT;
+ reg |= p->data_credits_refill;
+ reg |= (u32)(p->bwg_id) << IXGBE_RTTDT2C_BWG_SHIFT;
+
+ if (p->prio_type == prio_group)
+ reg |= IXGBE_RTTDT2C_GSP;
+
+ if (p->prio_type == prio_link)
+ reg |= IXGBE_RTTDT2C_LSP;
+
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDT2C(i), reg);
+ }
+
+ /*
+ * Configure Tx descriptor plane (recycle mode; WSP) and
+ * enable arbiter
+ */
+ reg = IXGBE_RTTDCS_TDPAC | IXGBE_RTTDCS_TDRM;
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_config_tx_data_arbiter_82599 - Config Tx Data arbiter
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure Tx Packet Arbiter and credits for each traffic class.
+ */
+s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config)
+{
+ struct tc_bw_alloc *p;
+ u32 reg;
+ u8 i;
+
+ /* Disable the arbiter before changing parameters */
+ IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, IXGBE_RTTPCS_ARBDIS);
+
+ /* Map all traffic classes to their UP, 1 to 1 */
+ reg = 0;
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+ reg |= (i << (i * IXGBE_RTTUP2TC_UP_SHIFT));
+ IXGBE_WRITE_REG(hw, IXGBE_RTTUP2TC, reg);
+
+ /* Configure traffic class credits and priority */
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+ p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
+ reg = p->data_credits_refill;
+ reg |= (u32)(p->data_credits_max) << IXGBE_RTTPT2C_MCL_SHIFT;
+ reg |= (u32)(p->bwg_id) << IXGBE_RTTPT2C_BWG_SHIFT;
+
+ if (p->prio_type == prio_group)
+ reg |= IXGBE_RTTPT2C_GSP;
+
+ if (p->prio_type == prio_link)
+ reg |= IXGBE_RTTPT2C_LSP;
+
+ IXGBE_WRITE_REG(hw, IXGBE_RTTPT2C(i), reg);
+ }
+
+ /*
+ * Configure Tx packet plane (recycle mode; SP; arb delay) and
+ * enable arbiter
+ */
+ reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM |
+ (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT);
+ IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg);
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_config_pfc_82599 - Configure priority flow control
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure Priority Flow Control (PFC) for each traffic class.
+ */
+s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config)
+{
+ u32 i, reg;
+
+ /* If PFC is disabled globally then fall back to LFC. */
+ if (!dcb_config->pfc_mode_enable) {
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+ hw->mac.ops.setup_fc(hw, i);
+ goto out;
+ }
+
+ /* Configure PFC Tx thresholds per TC */
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+ /* Config and remember Tx */
+ if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
+ dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) {
+ reg = hw->fc.high_water | IXGBE_FCRTH_FCEN;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
+ reg = hw->fc.low_water | IXGBE_FCRTL_XONE;
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
+ } else {
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
+ }
+ }
+
+ /* Configure pause time (2 TCs per register) */
+ reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
+ for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
+ IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
+
+ /* Configure flow control refresh threshold value */
+ IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
+
+ /* Enable Transmit PFC */
+ reg = IXGBE_FCCFG_TFCE_PRIORITY;
+ IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg);
+
+ /*
+ * Enable Receive PFC
+ * We will always honor XOFF frames we receive when
+ * we are in PFC mode.
+ */
+ reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+ reg &= ~IXGBE_MFLCN_RFCE;
+ reg |= IXGBE_MFLCN_RPFCE;
+ IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
+out:
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_config_tc_stats_82599 - Config traffic class statistics
+ * @hw: pointer to hardware structure
+ *
+ * Configure queue statistics registers, all queues belonging to same traffic
+ * class uses a single set of queue statistics counters.
+ */
+s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw)
+{
+ u32 reg = 0;
+ u8 i = 0;
+
+ /*
+ * Receive Queues stats setting
+ * 32 RQSMR registers, each configuring 4 queues.
+ * Set all 16 queues of each TC to the same stat
+ * with TC 'n' going to stat 'n'.
+ */
+ for (i = 0; i < 32; i++) {
+ reg = 0x01010101 * (i / 4);
+ IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
+ }
+ /*
+ * Transmit Queues stats setting
+ * 32 TQSM registers, each controlling 4 queues.
+ * Set all queues of each TC to the same stat
+ * with TC 'n' going to stat 'n'.
+ * Tx queues are allocated non-uniformly to TCs:
+ * 32, 32, 16, 16, 8, 8, 8, 8.
+ */
+ for (i = 0; i < 32; i++) {
+ if (i < 8)
+ reg = 0x00000000;
+ else if (i < 16)
+ reg = 0x01010101;
+ else if (i < 20)
+ reg = 0x02020202;
+ else if (i < 24)
+ reg = 0x03030303;
+ else if (i < 26)
+ reg = 0x04040404;
+ else if (i < 28)
+ reg = 0x05050505;
+ else if (i < 30)
+ reg = 0x06060606;
+ else
+ reg = 0x07070707;
+ IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), reg);
+ }
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_config_82599 - Configure general DCB parameters
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure general DCB parameters.
+ */
+s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw)
+{
+ u32 reg;
+ u32 q;
+
+ /* Disable the Tx desc arbiter so that MTQC can be changed */
+ reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
+ reg |= IXGBE_RTTDCS_ARBDIS;
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
+
+ /* Enable DCB for Rx with 8 TCs */
+ reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
+ switch (reg & IXGBE_MRQC_MRQE_MASK) {
+ case 0:
+ case IXGBE_MRQC_RT4TCEN:
+ /* RSS disabled cases */
+ reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RT8TCEN;
+ break;
+ case IXGBE_MRQC_RSSEN:
+ case IXGBE_MRQC_RTRSS4TCEN:
+ /* RSS enabled cases */
+ reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RTRSS8TCEN;
+ break;
+ default:
+ /* Unsupported value, assume stale data, overwrite no RSS */
+ reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RT8TCEN;
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_MRQC, reg);
+
+ /* Enable DCB for Tx with 8 TCs */
+ reg = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ;
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC, reg);
+
+ /* Disable drop for all queues */
+ for (q = 0; q < 128; q++)
+ IXGBE_WRITE_REG(hw, IXGBE_QDE, q << IXGBE_QDE_IDX_SHIFT);
+
+ /* Enable the Tx desc arbiter */
+ reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
+ reg &= ~IXGBE_RTTDCS_ARBDIS;
+ IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
+
+ return 0;
+}
+
+/**
+ * ixgbe_dcb_hw_config_82599 - Configure and enable DCB
+ * @hw: pointer to hardware structure
+ * @dcb_config: pointer to ixgbe_dcb_config structure
+ *
+ * Configure dcb settings and enable dcb mode.
+ */
+s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config)
+{
+ ixgbe_dcb_config_packet_buffers_82599(hw, dcb_config);
+ ixgbe_dcb_config_82599(hw);
+ ixgbe_dcb_config_rx_arbiter_82599(hw, dcb_config);
+ ixgbe_dcb_config_tx_desc_arbiter_82599(hw, dcb_config);
+ ixgbe_dcb_config_tx_data_arbiter_82599(hw, dcb_config);
+ ixgbe_dcb_config_pfc_82599(hw, dcb_config);
+ ixgbe_dcb_config_tc_stats_82599(hw);
+
+ return 0;
+}
+
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h
new file mode 100644
index 000000000000..9e5e2827e4af
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h
@@ -0,0 +1,127 @@
+/*******************************************************************************
+
+ Intel 10 Gigabit PCI Express Linux driver
+ Copyright(c) 1999 - 2009 Intel Corporation.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms and conditions of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ This program is distributed in the hope it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along with
+ this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "COPYING".
+
+ Contact Information:
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _DCB_82599_CONFIG_H_
+#define _DCB_82599_CONFIG_H_
+
+/* DCB register definitions */
+#define IXGBE_RTTDCS_TDPAC 0x00000001 /* 0 Round Robin,
+ * 1 WSP - Weighted Strict Priority
+ */
+#define IXGBE_RTTDCS_VMPAC 0x00000002 /* 0 Round Robin,
+ * 1 WRR - Weighted Round Robin
+ */
+#define IXGBE_RTTDCS_TDRM 0x00000010 /* Transmit Recycle Mode */
+#define IXGBE_RTTDCS_ARBDIS 0x00000040 /* DCB arbiter disable */
+#define IXGBE_RTTDCS_BDPM 0x00400000 /* Bypass Data Pipe - must clear! */
+#define IXGBE_RTTDCS_BPBFSM 0x00800000 /* Bypass PB Free Space - must
+ * clear!
+ */
+#define IXGBE_RTTDCS_SPEED_CHG 0x80000000 /* Link speed change */
+
+/* Receive UP2TC mapping */
+#define IXGBE_RTRUP2TC_UP_SHIFT 3
+/* Transmit UP2TC mapping */
+#define IXGBE_RTTUP2TC_UP_SHIFT 3
+
+#define IXGBE_RTRPT4C_MCL_SHIFT 12 /* Offset to Max Credit Limit setting */
+#define IXGBE_RTRPT4C_BWG_SHIFT 9 /* Offset to BWG index */
+#define IXGBE_RTRPT4C_GSP 0x40000000 /* GSP enable bit */
+#define IXGBE_RTRPT4C_LSP 0x80000000 /* LSP enable bit */
+
+#define IXGBE_RDRXCTL_MPBEN 0x00000010 /* DMA config for multiple packet
+ * buffers enable
+ */
+#define IXGBE_RDRXCTL_MCEN 0x00000040 /* DMA config for multiple cores
+ * (RSS) enable
+ */
+
+/* RTRPCS Bit Masks */
+#define IXGBE_RTRPCS_RRM 0x00000002 /* Receive Recycle Mode enable */
+/* Receive Arbitration Control: 0 Round Robin, 1 DFP */
+#define IXGBE_RTRPCS_RAC 0x00000004
+#define IXGBE_RTRPCS_ARBDIS 0x00000040 /* Arbitration disable bit */
+
+/* RTTDT2C Bit Masks */
+#define IXGBE_RTTDT2C_MCL_SHIFT 12
+#define IXGBE_RTTDT2C_BWG_SHIFT 9
+#define IXGBE_RTTDT2C_GSP 0x40000000
+#define IXGBE_RTTDT2C_LSP 0x80000000
+
+#define IXGBE_RTTPT2C_MCL_SHIFT 12
+#define IXGBE_RTTPT2C_BWG_SHIFT 9
+#define IXGBE_RTTPT2C_GSP 0x40000000
+#define IXGBE_RTTPT2C_LSP 0x80000000
+
+/* RTTPCS Bit Masks */
+#define IXGBE_RTTPCS_TPPAC 0x00000020 /* 0 Round Robin,
+ * 1 SP - Strict Priority
+ */
+#define IXGBE_RTTPCS_ARBDIS 0x00000040 /* Arbiter disable */
+#define IXGBE_RTTPCS_TPRM 0x00000100 /* Transmit Recycle Mode enable */
+#define IXGBE_RTTPCS_ARBD_SHIFT 22
+#define IXGBE_RTTPCS_ARBD_DCB 0x4 /* Arbitration delay in DCB mode */
+
+#define IXGBE_TXPBSIZE_20KB 0x00005000 /* 20KB Packet Buffer */
+#define IXGBE_TXPBSIZE_40KB 0x0000A000 /* 40KB Packet Buffer */
+#define IXGBE_RXPBSIZE_48KB 0x0000C000 /* 48KB Packet Buffer */
+#define IXGBE_RXPBSIZE_64KB 0x00010000 /* 64KB Packet Buffer */
+#define IXGBE_RXPBSIZE_80KB 0x00014000 /* 80KB Packet Buffer */
+#define IXGBE_RXPBSIZE_128KB 0x00020000 /* 128KB Packet Buffer */
+
+#define IXGBE_TXPBTHRESH_DCB 0xA /* THRESH value for DCB mode */
+
+
+/* DCB hardware-specific driver APIs */
+
+/* DCB PFC functions */
+s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config);
+s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw,
+ struct ixgbe_hw_stats *stats,
+ u8 tc_count);
+
+/* DCB traffic class stats */
+s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw);
+s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw,
+ struct ixgbe_hw_stats *stats,
+ u8 tc_count);
+
+/* DCB config arbiters */
+s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config);
+s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config);
+s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *dcb_config);
+
+
+/* DCB hw initialization */
+s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw,
+ struct ixgbe_dcb_config *config);
+
+#endif /* _DCB_82599_CONFIG_H */
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index 4129976953f5..bd0a0c276952 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -35,6 +35,7 @@
#define BIT_PG_RX 0x04
#define BIT_PG_TX 0x08
#define BIT_BCN 0x10
+#define BIT_LINKSPEED 0x80
int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
struct ixgbe_dcb_config *dst_dcb_cfg, int tc_max)
@@ -89,24 +90,7 @@ int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
src_dcb_cfg->tc_config[i - DCB_PFC_UP_ATTR_0].dcb_pfc;
}
- for (i = DCB_BCN_ATTR_RP_0; i < DCB_BCN_ATTR_RP_ALL; i++) {
- dst_dcb_cfg->bcn.rp_admin_mode[i - DCB_BCN_ATTR_RP_0] =
- src_dcb_cfg->bcn.rp_admin_mode[i - DCB_BCN_ATTR_RP_0];
- }
- dst_dcb_cfg->bcn.bcna_option[0] = src_dcb_cfg->bcn.bcna_option[0];
- dst_dcb_cfg->bcn.bcna_option[1] = src_dcb_cfg->bcn.bcna_option[1];
- dst_dcb_cfg->bcn.rp_alpha = src_dcb_cfg->bcn.rp_alpha;
- dst_dcb_cfg->bcn.rp_beta = src_dcb_cfg->bcn.rp_beta;
- dst_dcb_cfg->bcn.rp_gd = src_dcb_cfg->bcn.rp_gd;
- dst_dcb_cfg->bcn.rp_gi = src_dcb_cfg->bcn.rp_gi;
- dst_dcb_cfg->bcn.rp_tmax = src_dcb_cfg->bcn.rp_tmax;
- dst_dcb_cfg->bcn.rp_td = src_dcb_cfg->bcn.rp_td;
- dst_dcb_cfg->bcn.rp_rmin = src_dcb_cfg->bcn.rp_rmin;
- dst_dcb_cfg->bcn.rp_w = src_dcb_cfg->bcn.rp_w;
- dst_dcb_cfg->bcn.rp_rd = src_dcb_cfg->bcn.rp_rd;
- dst_dcb_cfg->bcn.rp_ru = src_dcb_cfg->bcn.rp_ru;
- dst_dcb_cfg->bcn.rp_wrtt = src_dcb_cfg->bcn.rp_wrtt;
- dst_dcb_cfg->bcn.rp_ri = src_dcb_cfg->bcn.rp_ri;
+ dst_dcb_cfg->pfc_mode_enable = src_dcb_cfg->pfc_mode_enable;
return 0;
}
@@ -120,12 +104,6 @@ static u8 ixgbe_dcbnl_get_state(struct net_device *netdev)
return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED);
}
-static u16 ixgbe_dcb_select_queue(struct net_device *dev, struct sk_buff *skb)
-{
- /* All traffic should default to class 0 */
- return 0;
-}
-
static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
{
u8 err = 0;
@@ -153,8 +131,8 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
kfree(adapter->rx_ring);
adapter->tx_ring = NULL;
adapter->rx_ring = NULL;
- netdev->select_queue = &ixgbe_dcb_select_queue;
+ adapter->hw.fc.requested_mode = ixgbe_fc_pfc;
adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
ixgbe_init_interrupt_scheme(adapter);
@@ -163,6 +141,7 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
} else {
/* Turn off DCB */
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ adapter->hw.fc.requested_mode = ixgbe_fc_default;
if (netif_running(netdev))
netdev->netdev_ops->ndo_stop(netdev);
ixgbe_reset_interrupt_capability(adapter);
@@ -172,7 +151,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
kfree(adapter->rx_ring);
adapter->tx_ring = NULL;
adapter->rx_ring = NULL;
- netdev->select_queue = NULL;
adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
@@ -322,8 +300,10 @@ static void ixgbe_dcbnl_set_pfc_cfg(struct net_device *netdev, int priority,
adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc = setting;
if (adapter->temp_dcb_cfg.tc_config[priority].dcb_pfc !=
- adapter->dcb_cfg.tc_config[priority].dcb_pfc)
+ adapter->dcb_cfg.tc_config[priority].dcb_pfc) {
adapter->dcb_set_bitmap |= BIT_PFC;
+ adapter->temp_dcb_cfg.pfc_mode_enable = true;
+ }
}
static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority,
@@ -444,175 +424,6 @@ static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
return;
}
-static void ixgbe_dcbnl_getbcnrp(struct net_device *netdev, int priority,
- u8 *setting)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- *setting = adapter->dcb_cfg.bcn.rp_admin_mode[priority];
-}
-
-
-static void ixgbe_dcbnl_getbcncfg(struct net_device *netdev, int enum_index,
- u32 *setting)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- switch (enum_index) {
- case DCB_BCN_ATTR_BCNA_0:
- *setting = adapter->dcb_cfg.bcn.bcna_option[0];
- break;
- case DCB_BCN_ATTR_BCNA_1:
- *setting = adapter->dcb_cfg.bcn.bcna_option[1];
- break;
- case DCB_BCN_ATTR_ALPHA:
- *setting = adapter->dcb_cfg.bcn.rp_alpha;
- break;
- case DCB_BCN_ATTR_BETA:
- *setting = adapter->dcb_cfg.bcn.rp_beta;
- break;
- case DCB_BCN_ATTR_GD:
- *setting = adapter->dcb_cfg.bcn.rp_gd;
- break;
- case DCB_BCN_ATTR_GI:
- *setting = adapter->dcb_cfg.bcn.rp_gi;
- break;
- case DCB_BCN_ATTR_TMAX:
- *setting = adapter->dcb_cfg.bcn.rp_tmax;
- break;
- case DCB_BCN_ATTR_TD:
- *setting = adapter->dcb_cfg.bcn.rp_td;
- break;
- case DCB_BCN_ATTR_RMIN:
- *setting = adapter->dcb_cfg.bcn.rp_rmin;
- break;
- case DCB_BCN_ATTR_W:
- *setting = adapter->dcb_cfg.bcn.rp_w;
- break;
- case DCB_BCN_ATTR_RD:
- *setting = adapter->dcb_cfg.bcn.rp_rd;
- break;
- case DCB_BCN_ATTR_RU:
- *setting = adapter->dcb_cfg.bcn.rp_ru;
- break;
- case DCB_BCN_ATTR_WRTT:
- *setting = adapter->dcb_cfg.bcn.rp_wrtt;
- break;
- case DCB_BCN_ATTR_RI:
- *setting = adapter->dcb_cfg.bcn.rp_ri;
- break;
- default:
- *setting = -1;
- }
-}
-
-static void ixgbe_dcbnl_setbcnrp(struct net_device *netdev, int priority,
- u8 setting)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- adapter->temp_dcb_cfg.bcn.rp_admin_mode[priority] = setting;
-
- if (adapter->temp_dcb_cfg.bcn.rp_admin_mode[priority] !=
- adapter->dcb_cfg.bcn.rp_admin_mode[priority])
- adapter->dcb_set_bitmap |= BIT_BCN;
-}
-
-static void ixgbe_dcbnl_setbcncfg(struct net_device *netdev, int enum_index,
- u32 setting)
-{
- struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
- switch (enum_index) {
- case DCB_BCN_ATTR_BCNA_0:
- adapter->temp_dcb_cfg.bcn.bcna_option[0] = setting;
- if (adapter->temp_dcb_cfg.bcn.bcna_option[0] !=
- adapter->dcb_cfg.bcn.bcna_option[0])
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_BCNA_1:
- adapter->temp_dcb_cfg.bcn.bcna_option[1] = setting;
- if (adapter->temp_dcb_cfg.bcn.bcna_option[1] !=
- adapter->dcb_cfg.bcn.bcna_option[1])
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_ALPHA:
- adapter->temp_dcb_cfg.bcn.rp_alpha = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_alpha !=
- adapter->dcb_cfg.bcn.rp_alpha)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_BETA:
- adapter->temp_dcb_cfg.bcn.rp_beta = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_beta !=
- adapter->dcb_cfg.bcn.rp_beta)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_GD:
- adapter->temp_dcb_cfg.bcn.rp_gd = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_gd !=
- adapter->dcb_cfg.bcn.rp_gd)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_GI:
- adapter->temp_dcb_cfg.bcn.rp_gi = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_gi !=
- adapter->dcb_cfg.bcn.rp_gi)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_TMAX:
- adapter->temp_dcb_cfg.bcn.rp_tmax = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_tmax !=
- adapter->dcb_cfg.bcn.rp_tmax)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_TD:
- adapter->temp_dcb_cfg.bcn.rp_td = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_td !=
- adapter->dcb_cfg.bcn.rp_td)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_RMIN:
- adapter->temp_dcb_cfg.bcn.rp_rmin = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_rmin !=
- adapter->dcb_cfg.bcn.rp_rmin)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_W:
- adapter->temp_dcb_cfg.bcn.rp_w = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_w !=
- adapter->dcb_cfg.bcn.rp_w)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_RD:
- adapter->temp_dcb_cfg.bcn.rp_rd = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_rd !=
- adapter->dcb_cfg.bcn.rp_rd)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_RU:
- adapter->temp_dcb_cfg.bcn.rp_ru = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_ru !=
- adapter->dcb_cfg.bcn.rp_ru)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_WRTT:
- adapter->temp_dcb_cfg.bcn.rp_wrtt = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_wrtt !=
- adapter->dcb_cfg.bcn.rp_wrtt)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- case DCB_BCN_ATTR_RI:
- adapter->temp_dcb_cfg.bcn.rp_ri = setting;
- if (adapter->temp_dcb_cfg.bcn.rp_ri !=
- adapter->dcb_cfg.bcn.rp_ri)
- adapter->dcb_set_bitmap |= BIT_BCN;
- break;
- default:
- break;
- }
-}
-
struct dcbnl_rtnl_ops dcbnl_ops = {
.getstate = ixgbe_dcbnl_get_state,
.setstate = ixgbe_dcbnl_set_state,
@@ -633,9 +444,5 @@ struct dcbnl_rtnl_ops dcbnl_ops = {
.setnumtcs = ixgbe_dcbnl_setnumtcs,
.getpfcstate = ixgbe_dcbnl_getpfcstate,
.setpfcstate = ixgbe_dcbnl_setpfcstate,
- .getbcncfg = ixgbe_dcbnl_getbcncfg,
- .getbcnrp = ixgbe_dcbnl_getbcnrp,
- .setbcncfg = ixgbe_dcbnl_setbcncfg,
- .setbcnrp = ixgbe_dcbnl_setbcnrp
};
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 67f87a79154d..aafc120f164e 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -89,8 +89,7 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
{"rx_header_split", IXGBE_STAT(rx_hdr_split)},
{"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)},
{"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)},
- {"lro_aggregated", IXGBE_STAT(lro_aggregated)},
- {"lro_flushed", IXGBE_STAT(lro_flushed)},
+ {"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)},
};
#define IXGBE_QUEUE_STATS_LEN \
@@ -130,8 +129,37 @@ static int ixgbe_get_settings(struct net_device *netdev,
ecmd->advertising |= ADVERTISED_10000baseT_Full;
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
ecmd->advertising |= ADVERTISED_1000baseT_Full;
+ /*
+ * It's possible that phy.autoneg_advertised may not be
+ * set yet. If so display what the default would be -
+ * both 1G and 10G supported.
+ */
+ if (!(ecmd->advertising & (ADVERTISED_1000baseT_Full |
+ ADVERTISED_10000baseT_Full)))
+ ecmd->advertising |= (ADVERTISED_10000baseT_Full |
+ ADVERTISED_1000baseT_Full);
ecmd->port = PORT_TP;
+ } else if (hw->phy.media_type == ixgbe_media_type_backplane) {
+ /* Set as FIBRE until SERDES defined in kernel */
+ switch (hw->device_id) {
+ case IXGBE_DEV_ID_82598:
+ ecmd->supported |= (SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE);
+ ecmd->advertising = (ADVERTISED_10000baseT_Full |
+ ADVERTISED_1000baseT_Full |
+ ADVERTISED_FIBRE);
+ ecmd->port = PORT_FIBRE;
+ break;
+ case IXGBE_DEV_ID_82598_BX:
+ ecmd->supported = (SUPPORTED_1000baseT_Full |
+ SUPPORTED_FIBRE);
+ ecmd->advertising = (ADVERTISED_1000baseT_Full |
+ ADVERTISED_FIBRE);
+ ecmd->port = PORT_FIBRE;
+ ecmd->autoneg = AUTONEG_DISABLE;
+ break;
+ }
} else {
ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising = (ADVERTISED_10000baseT_Full |
@@ -206,13 +234,22 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
- pause->autoneg = (hw->fc.type == ixgbe_fc_full ? 1 : 0);
+ /*
+ * Flow Control Autoneg isn't on if
+ * - we didn't ask for it OR
+ * - it failed, we know this by tx & rx being off
+ */
+ if (hw->fc.disable_fc_autoneg ||
+ (hw->fc.current_mode == ixgbe_fc_none))
+ pause->autoneg = 0;
+ else
+ pause->autoneg = 1;
- if (hw->fc.type == ixgbe_fc_rx_pause) {
+ if (hw->fc.current_mode == ixgbe_fc_rx_pause) {
pause->rx_pause = 1;
- } else if (hw->fc.type == ixgbe_fc_tx_pause) {
+ } else if (hw->fc.current_mode == ixgbe_fc_tx_pause) {
pause->tx_pause = 1;
- } else if (hw->fc.type == ixgbe_fc_full) {
+ } else if (hw->fc.current_mode == ixgbe_fc_full) {
pause->rx_pause = 1;
pause->tx_pause = 1;
}
@@ -224,24 +261,23 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
- if ((pause->autoneg == AUTONEG_ENABLE) ||
- (pause->rx_pause && pause->tx_pause))
- hw->fc.type = ixgbe_fc_full;
+ if (pause->autoneg != AUTONEG_ENABLE)
+ hw->fc.disable_fc_autoneg = true;
+ else
+ hw->fc.disable_fc_autoneg = false;
+
+ if (pause->rx_pause && pause->tx_pause)
+ hw->fc.requested_mode = ixgbe_fc_full;
else if (pause->rx_pause && !pause->tx_pause)
- hw->fc.type = ixgbe_fc_rx_pause;
+ hw->fc.requested_mode = ixgbe_fc_rx_pause;
else if (!pause->rx_pause && pause->tx_pause)
- hw->fc.type = ixgbe_fc_tx_pause;
+ hw->fc.requested_mode = ixgbe_fc_tx_pause;
else if (!pause->rx_pause && !pause->tx_pause)
- hw->fc.type = ixgbe_fc_none;
+ hw->fc.requested_mode = ixgbe_fc_none;
else
return -EINVAL;
- hw->fc.original_type = hw->fc.type;
-
- if (netif_running(netdev))
- ixgbe_reinit_locked(adapter);
- else
- ixgbe_reset(adapter);
+ hw->mac.ops.setup_fc(hw, 0);
return 0;
}
@@ -456,7 +492,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
regs_buff[825] = IXGBE_READ_REG(hw, IXGBE_IP6AT);
regs_buff[826] = IXGBE_READ_REG(hw, IXGBE_WUPL);
regs_buff[827] = IXGBE_READ_REG(hw, IXGBE_WUPM);
- regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT);
+ regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT(0));
regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS);
regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS);
@@ -661,10 +697,17 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ char firmware_version[32];
strncpy(drvinfo->driver, ixgbe_driver_name, 32);
strncpy(drvinfo->version, ixgbe_driver_version, 32);
- strncpy(drvinfo->fw_version, "N/A", 32);
+
+ sprintf(firmware_version, "%d.%d-%d",
+ (adapter->eeprom_version & 0xF000) >> 12,
+ (adapter->eeprom_version & 0x0FF0) >> 4,
+ adapter->eeprom_version & 0x000F);
+
+ strncpy(drvinfo->fw_version, firmware_version, 32);
strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
drvinfo->n_stats = IXGBE_STATS_LEN;
drvinfo->regdump_len = ixgbe_get_regs_len(netdev);
@@ -691,9 +734,10 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_ring *temp_ring;
+ struct ixgbe_ring *temp_tx_ring, *temp_rx_ring;
int i, err;
u32 new_rx_count, new_tx_count;
+ bool need_update = false;
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
@@ -712,80 +756,94 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
return 0;
}
- temp_ring = kcalloc(adapter->num_tx_queues,
- sizeof(struct ixgbe_ring), GFP_KERNEL);
- if (!temp_ring)
- return -ENOMEM;
-
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
msleep(1);
- if (new_tx_count != adapter->tx_ring->count) {
+ temp_tx_ring = kcalloc(adapter->num_tx_queues,
+ sizeof(struct ixgbe_ring), GFP_KERNEL);
+ if (!temp_tx_ring) {
+ err = -ENOMEM;
+ goto err_setup;
+ }
+
+ if (new_tx_count != adapter->tx_ring_count) {
+ memcpy(temp_tx_ring, adapter->tx_ring,
+ adapter->num_tx_queues * sizeof(struct ixgbe_ring));
for (i = 0; i < adapter->num_tx_queues; i++) {
- temp_ring[i].count = new_tx_count;
- err = ixgbe_setup_tx_resources(adapter, &temp_ring[i]);
+ temp_tx_ring[i].count = new_tx_count;
+ err = ixgbe_setup_tx_resources(adapter,
+ &temp_tx_ring[i]);
if (err) {
while (i) {
i--;
ixgbe_free_tx_resources(adapter,
- &temp_ring[i]);
+ &temp_tx_ring[i]);
}
goto err_setup;
}
- temp_ring[i].v_idx = adapter->tx_ring[i].v_idx;
+ temp_tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
}
- if (netif_running(netdev))
- netdev->netdev_ops->ndo_stop(netdev);
- ixgbe_reset_interrupt_capability(adapter);
- ixgbe_napi_del_all(adapter);
- INIT_LIST_HEAD(&netdev->napi_list);
- kfree(adapter->tx_ring);
- adapter->tx_ring = temp_ring;
- temp_ring = NULL;
- adapter->tx_ring_count = new_tx_count;
+ need_update = true;
}
- temp_ring = kcalloc(adapter->num_rx_queues,
- sizeof(struct ixgbe_ring), GFP_KERNEL);
- if (!temp_ring) {
- if (netif_running(netdev))
- netdev->netdev_ops->ndo_open(netdev);
- return -ENOMEM;
+ temp_rx_ring = kcalloc(adapter->num_rx_queues,
+ sizeof(struct ixgbe_ring), GFP_KERNEL);
+ if ((!temp_rx_ring) && (need_update)) {
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ ixgbe_free_tx_resources(adapter, &temp_tx_ring[i]);
+ kfree(temp_tx_ring);
+ err = -ENOMEM;
+ goto err_setup;
}
- if (new_rx_count != adapter->rx_ring->count) {
+ if (new_rx_count != adapter->rx_ring_count) {
+ memcpy(temp_rx_ring, adapter->rx_ring,
+ adapter->num_rx_queues * sizeof(struct ixgbe_ring));
for (i = 0; i < adapter->num_rx_queues; i++) {
- temp_ring[i].count = new_rx_count;
- err = ixgbe_setup_rx_resources(adapter, &temp_ring[i]);
+ temp_rx_ring[i].count = new_rx_count;
+ err = ixgbe_setup_rx_resources(adapter,
+ &temp_rx_ring[i]);
if (err) {
while (i) {
i--;
ixgbe_free_rx_resources(adapter,
- &temp_ring[i]);
+ &temp_rx_ring[i]);
}
goto err_setup;
}
- temp_ring[i].v_idx = adapter->rx_ring[i].v_idx;
+ temp_rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
}
+ need_update = true;
+ }
+
+ /* if rings need to be updated, here's the place to do it in one shot */
+ if (need_update) {
if (netif_running(netdev))
- netdev->netdev_ops->ndo_stop(netdev);
- ixgbe_reset_interrupt_capability(adapter);
- ixgbe_napi_del_all(adapter);
- INIT_LIST_HEAD(&netdev->napi_list);
- kfree(adapter->rx_ring);
- adapter->rx_ring = temp_ring;
- temp_ring = NULL;
-
- adapter->rx_ring_count = new_rx_count;
+ ixgbe_down(adapter);
+
+ /* tx */
+ if (new_tx_count != adapter->tx_ring_count) {
+ kfree(adapter->tx_ring);
+ adapter->tx_ring = temp_tx_ring;
+ temp_tx_ring = NULL;
+ adapter->tx_ring_count = new_tx_count;
+ }
+
+ /* rx */
+ if (new_rx_count != adapter->rx_ring_count) {
+ kfree(adapter->rx_ring);
+ adapter->rx_ring = temp_rx_ring;
+ temp_rx_ring = NULL;
+ adapter->rx_ring_count = new_rx_count;
+ }
}
/* success! */
err = 0;
-err_setup:
- ixgbe_init_interrupt_scheme(adapter);
if (netif_running(netdev))
- netdev->netdev_ops->ndo_open(netdev);
+ ixgbe_up(adapter);
+err_setup:
clear_bit(__IXGBE_RESETTING, &adapter->state);
return err;
}
@@ -808,15 +866,6 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64);
int j, k;
int i;
- u64 aggregated = 0, flushed = 0, no_desc = 0;
- for (i = 0; i < adapter->num_rx_queues; i++) {
- aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated;
- flushed += adapter->rx_ring[i].lro_mgr.stats.flushed;
- no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc;
- }
- adapter->lro_aggregated = aggregated;
- adapter->lro_flushed = flushed;
- adapter->lro_no_desc = no_desc;
ixgbe_update_stats(adapter);
for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
@@ -897,12 +946,50 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
static void ixgbe_get_wol(struct net_device *netdev,
struct ethtool_wolinfo *wol)
{
- wol->supported = 0;
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ wol->supported = WAKE_UCAST | WAKE_MCAST |
+ WAKE_BCAST | WAKE_MAGIC;
wol->wolopts = 0;
+ if (!device_can_wakeup(&adapter->pdev->dev))
+ return;
+
+ if (adapter->wol & IXGBE_WUFC_EX)
+ wol->wolopts |= WAKE_UCAST;
+ if (adapter->wol & IXGBE_WUFC_MC)
+ wol->wolopts |= WAKE_MCAST;
+ if (adapter->wol & IXGBE_WUFC_BC)
+ wol->wolopts |= WAKE_BCAST;
+ if (adapter->wol & IXGBE_WUFC_MAG)
+ wol->wolopts |= WAKE_MAGIC;
+
return;
}
+static int ixgbe_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+ if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
+ return -EOPNOTSUPP;
+
+ adapter->wol = 0;
+
+ if (wol->wolopts & WAKE_UCAST)
+ adapter->wol |= IXGBE_WUFC_EX;
+ if (wol->wolopts & WAKE_MCAST)
+ adapter->wol |= IXGBE_WUFC_MC;
+ if (wol->wolopts & WAKE_BCAST)
+ adapter->wol |= IXGBE_WUFC_BC;
+ if (wol->wolopts & WAKE_MAGIC)
+ adapter->wol |= IXGBE_WUFC_MAG;
+
+ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+ return 0;
+}
+
static int ixgbe_nway_reset(struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -965,40 +1052,47 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *ec)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
int i;
if (ec->tx_max_coalesced_frames_irq)
adapter->tx_ring[0].work_limit = ec->tx_max_coalesced_frames_irq;
if (ec->rx_coalesce_usecs > 1) {
+ /* check the limits */
+ if ((1000000/ec->rx_coalesce_usecs > IXGBE_MAX_INT_RATE) ||
+ (1000000/ec->rx_coalesce_usecs < IXGBE_MIN_INT_RATE))
+ return -EINVAL;
+
/* store the value in ints/second */
adapter->eitr_param = 1000000/ec->rx_coalesce_usecs;
/* static value of interrupt rate */
adapter->itr_setting = adapter->eitr_param;
- /* clear the lower bit */
+ /* clear the lower bit as its used for dynamic state */
adapter->itr_setting &= ~1;
} else if (ec->rx_coalesce_usecs == 1) {
/* 1 means dynamic mode */
adapter->eitr_param = 20000;
adapter->itr_setting = 1;
} else {
- /* any other value means disable eitr, which is best
- * served by setting the interrupt rate very high */
- adapter->eitr_param = 3000000;
+ /*
+ * any other value means disable eitr, which is best
+ * served by setting the interrupt rate very high
+ */
+ adapter->eitr_param = IXGBE_MAX_INT_RATE;
adapter->itr_setting = 0;
}
for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
if (q_vector->txr_count && !q_vector->rxr_count)
+ /* tx vector gets half the rate */
q_vector->eitr = (adapter->eitr_param >> 1);
else
/* rx only or mixed */
q_vector->eitr = adapter->eitr_param;
- IXGBE_WRITE_REG(hw, IXGBE_EITR(i),
- EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
+ ixgbe_write_eitr(adapter, i,
+ EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
}
return 0;
@@ -1012,6 +1106,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
.get_regs_len = ixgbe_get_regs_len,
.get_regs = ixgbe_get_regs,
.get_wol = ixgbe_get_wol,
+ .set_wol = ixgbe_set_wol,
.nway_reset = ixgbe_nway_reset,
.get_link = ethtool_op_get_link,
.get_eeprom_len = ixgbe_get_eeprom_len,
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 5d364a96e35d..286ecc0e6ab7 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -47,12 +47,13 @@ char ixgbe_driver_name[] = "ixgbe";
static const char ixgbe_driver_string[] =
"Intel(R) 10 Gigabit PCI Express Network Driver";
-#define DRV_VERSION "1.3.30-k2"
+#define DRV_VERSION "2.0.8-k2"
const char ixgbe_driver_version[] = DRV_VERSION;
-static char ixgbe_copyright[] = "Copyright (c) 1999-2007 Intel Corporation.";
+static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
static const struct ixgbe_info *ixgbe_info_tbl[] = {
[board_82598] = &ixgbe_82598_info,
+ [board_82599] = &ixgbe_82599_info,
};
/* ixgbe_pci_tbl - PCI Device ID Table
@@ -64,6 +65,8 @@ static const struct ixgbe_info *ixgbe_info_tbl[] = {
* Class, Class Mask, private data (not used) }
*/
static struct pci_device_id ixgbe_pci_tbl[] = {
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598),
+ board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_DUAL_PORT),
board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT),
@@ -82,6 +85,12 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_SFP_LOM),
board_82598 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_BX),
+ board_82598 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4),
+ board_82599 },
+ {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP),
+ board_82599 },
/* required last entry */
{0, }
@@ -125,32 +134,67 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
}
-static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, u16 int_alloc_entry,
- u8 msix_vector)
+/*
+ * ixgbe_set_ivar - set the IVAR registers, mapping interrupt causes to vectors
+ * @adapter: pointer to adapter struct
+ * @direction: 0 for Rx, 1 for Tx, -1 for other causes
+ * @queue: queue to map the corresponding interrupt to
+ * @msix_vector: the vector to map to the corresponding queue
+ *
+ */
+static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction,
+ u8 queue, u8 msix_vector)
{
u32 ivar, index;
-
- msix_vector |= IXGBE_IVAR_ALLOC_VAL;
- index = (int_alloc_entry >> 2) & 0x1F;
- ivar = IXGBE_READ_REG(&adapter->hw, IXGBE_IVAR(index));
- ivar &= ~(0xFF << (8 * (int_alloc_entry & 0x3)));
- ivar |= (msix_vector << (8 * (int_alloc_entry & 0x3)));
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_IVAR(index), ivar);
+ struct ixgbe_hw *hw = &adapter->hw;
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
+ msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+ if (direction == -1)
+ direction = 0;
+ index = (((direction * 64) + queue) >> 2) & 0x1F;
+ ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index));
+ ivar &= ~(0xFF << (8 * (queue & 0x3)));
+ ivar |= (msix_vector << (8 * (queue & 0x3)));
+ IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar);
+ break;
+ case ixgbe_mac_82599EB:
+ if (direction == -1) {
+ /* other causes */
+ msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+ index = ((queue & 1) * 8);
+ ivar = IXGBE_READ_REG(&adapter->hw, IXGBE_IVAR_MISC);
+ ivar &= ~(0xFF << index);
+ ivar |= (msix_vector << index);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_IVAR_MISC, ivar);
+ break;
+ } else {
+ /* tx or rx causes */
+ msix_vector |= IXGBE_IVAR_ALLOC_VAL;
+ index = ((16 * (queue & 1)) + (8 * direction));
+ ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(queue >> 1));
+ ivar &= ~(0xFF << index);
+ ivar |= (msix_vector << index);
+ IXGBE_WRITE_REG(hw, IXGBE_IVAR(queue >> 1), ivar);
+ break;
+ }
+ default:
+ break;
+ }
}
static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
struct ixgbe_tx_buffer
*tx_buffer_info)
{
- if (tx_buffer_info->dma) {
- pci_unmap_page(adapter->pdev, tx_buffer_info->dma,
- tx_buffer_info->length, PCI_DMA_TODEVICE);
- tx_buffer_info->dma = 0;
- }
+ tx_buffer_info->dma = 0;
if (tx_buffer_info->skb) {
+ skb_dma_unmap(&adapter->pdev->dev, tx_buffer_info->skb,
+ DMA_TO_DEVICE);
dev_kfree_skb_any(tx_buffer_info->skb);
tx_buffer_info->skb = NULL;
}
+ tx_buffer_info->time_stamp = 0;
/* tx_buffer_info must be completely set up in the transmit path */
}
@@ -159,15 +203,11 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
unsigned int eop)
{
struct ixgbe_hw *hw = &adapter->hw;
- u32 head, tail;
/* Detect a transmit hang in hardware, this serializes the
* check with the clearing of time_stamp and movement of eop */
- head = IXGBE_READ_REG(hw, tx_ring->head);
- tail = IXGBE_READ_REG(hw, tx_ring->tail);
adapter->detect_tx_hung = false;
- if ((head != tail) &&
- tx_ring->tx_buffer_info[eop].time_stamp &&
+ if (tx_ring->tx_buffer_info[eop].time_stamp &&
time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) &&
!(IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)) {
/* detected Tx unit hang */
@@ -182,7 +222,8 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
" time_stamp <%lx>\n"
" jiffies <%lx>\n",
tx_ring->queue_index,
- head, tail,
+ IXGBE_READ_REG(hw, tx_ring->head),
+ IXGBE_READ_REG(hw, tx_ring->tail),
tx_ring->next_to_use, eop,
tx_ring->tx_buffer_info[eop].time_stamp, jiffies);
return true;
@@ -200,39 +241,39 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
-#define GET_TX_HEAD_FROM_RING(ring) (\
- *(volatile u32 *) \
- ((union ixgbe_adv_tx_desc *)(ring)->desc + (ring)->count))
static void ixgbe_tx_timeout(struct net_device *netdev);
/**
* ixgbe_clean_tx_irq - Reclaim resources after transmit completes
* @adapter: board private structure
* @tx_ring: tx ring to clean
+ *
+ * returns true if transmit work is done
**/
static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
struct ixgbe_ring *tx_ring)
{
- union ixgbe_adv_tx_desc *tx_desc;
- struct ixgbe_tx_buffer *tx_buffer_info;
struct net_device *netdev = adapter->netdev;
- struct sk_buff *skb;
- unsigned int i;
- u32 head, oldhead;
- unsigned int count = 0;
+ union ixgbe_adv_tx_desc *tx_desc, *eop_desc;
+ struct ixgbe_tx_buffer *tx_buffer_info;
+ unsigned int i, eop, count = 0;
unsigned int total_bytes = 0, total_packets = 0;
- rmb();
- head = GET_TX_HEAD_FROM_RING(tx_ring);
- head = le32_to_cpu(head);
i = tx_ring->next_to_clean;
- while (1) {
- while (i != head) {
+ eop = tx_ring->tx_buffer_info[i].next_to_watch;
+ eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
+
+ while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
+ (count < tx_ring->work_limit)) {
+ bool cleaned = false;
+ for ( ; !cleaned; count++) {
+ struct sk_buff *skb;
tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
tx_buffer_info = &tx_ring->tx_buffer_info[i];
+ cleaned = (i == eop);
skb = tx_buffer_info->skb;
- if (skb) {
+ if (cleaned && skb) {
unsigned int segs, bytecount;
/* gso_segs is currently only valid for tcp */
@@ -247,23 +288,17 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
ixgbe_unmap_and_free_tx_resource(adapter,
tx_buffer_info);
+ tx_desc->wb.status = 0;
+
i++;
if (i == tx_ring->count)
i = 0;
-
- count++;
- if (count == tx_ring->count)
- goto done_cleaning;
}
- oldhead = head;
- rmb();
- head = GET_TX_HEAD_FROM_RING(tx_ring);
- head = le32_to_cpu(head);
- if (head == oldhead)
- goto done_cleaning;
- } /* while (1) */
-
-done_cleaning:
+
+ eop = tx_ring->tx_buffer_info[i].next_to_watch;
+ eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
+ }
+
tx_ring->next_to_clean = i;
#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
@@ -291,17 +326,16 @@ done_cleaning:
}
/* re-arm the interrupt */
- if ((total_packets >= tx_ring->work_limit) ||
- (count == tx_ring->count))
+ if (count >= tx_ring->work_limit)
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->v_idx);
tx_ring->total_bytes += total_bytes;
tx_ring->total_packets += total_packets;
- tx_ring->stats.bytes += total_bytes;
tx_ring->stats.packets += total_packets;
+ tx_ring->stats.bytes += total_bytes;
adapter->net_stats.tx_bytes += total_bytes;
adapter->net_stats.tx_packets += total_packets;
- return (total_packets ? true : false);
+ return (count < tx_ring->work_limit);
}
#ifdef CONFIG_IXGBE_DCA
@@ -314,13 +348,19 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
if (rx_ring->cpu != cpu) {
rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q));
- rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK;
- rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK;
+ rxctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+ } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599;
+ rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
+ IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599);
+ }
rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN);
rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
- IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+ IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl);
rx_ring->cpu = cpu;
}
@@ -336,8 +376,14 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
if (tx_ring->cpu != cpu) {
txctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q));
- txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
- txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
+ txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
+ } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599;
+ txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
+ IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
+ }
txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_TXCTRL(q), txctrl);
tx_ring->cpu = cpu;
@@ -403,23 +449,21 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
* @rx_ring: rx descriptor ring (for a specific queue) to setup
* @rx_desc: rx descriptor
**/
-static void ixgbe_receive_skb(struct ixgbe_adapter *adapter,
+static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
struct sk_buff *skb, u8 status,
- struct ixgbe_ring *ring,
union ixgbe_adv_rx_desc *rx_desc)
{
+ struct ixgbe_adapter *adapter = q_vector->adapter;
+ struct napi_struct *napi = &q_vector->napi;
bool is_vlan = (status & IXGBE_RXD_STAT_VP);
u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
- if (adapter->netdev->features & NETIF_F_LRO &&
- skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ skb_record_rx_queue(skb, q_vector - &adapter->q_vector[0]);
+ if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
if (adapter->vlgrp && is_vlan && (tag != 0))
- lro_vlan_hwaccel_receive_skb(&ring->lro_mgr, skb,
- adapter->vlgrp, tag,
- rx_desc);
+ vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
else
- lro_receive_skb(&ring->lro_mgr, skb, rx_desc);
- ring->lro_used = true;
+ napi_gro_receive(napi, skb);
} else {
if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
if (adapter->vlgrp && is_vlan && (tag != 0))
@@ -470,6 +514,19 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
adapter->hw_csum_rx_good++;
}
+static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw,
+ struct ixgbe_ring *rx_ring, u32 val)
+{
+ /*
+ * Force memory writes to complete before letting h/w
+ * know there are new descriptors to fetch. (Only
+ * applicable for weak-ordered memory model archs,
+ * such as IA-64).
+ */
+ wmb();
+ IXGBE_WRITE_REG(hw, IXGBE_RDT(rx_ring->reg_idx), val);
+}
+
/**
* ixgbe_alloc_rx_buffers - Replace used receive buffers; packet split
* @adapter: address of board private structure
@@ -482,6 +539,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
union ixgbe_adv_rx_desc *rx_desc;
struct ixgbe_rx_buffer *bi;
unsigned int i;
+ unsigned int bufsz = rx_ring->rx_buf_len + NET_IP_ALIGN;
i = rx_ring->next_to_use;
bi = &rx_ring->rx_buffer_info[i];
@@ -511,9 +569,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
if (!bi->skb) {
struct sk_buff *skb;
- skb = netdev_alloc_skb(adapter->netdev,
- (rx_ring->rx_buf_len +
- NET_IP_ALIGN));
+ skb = netdev_alloc_skb(adapter->netdev, bufsz);
if (!skb) {
adapter->alloc_rx_buff_failed++;
@@ -528,8 +584,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
skb_reserve(skb, NET_IP_ALIGN);
bi->skb = skb;
- bi->dma = pci_map_single(pdev, skb->data,
- rx_ring->rx_buf_len,
+ bi->dma = pci_map_single(pdev, skb->data, bufsz,
PCI_DMA_FROMDEVICE);
}
/* Refresh the desc even if buffer_addrs didn't change because
@@ -553,14 +608,7 @@ no_buffers:
if (i-- == 0)
i = (rx_ring->count - 1);
- /*
- * Force memory writes to complete before letting h/w
- * know there are new descriptors to fetch. (Only
- * applicable for weak-ordered memory model archs,
- * such as IA-64).
- */
- wmb();
- writel(i, adapter->hw.hw_addr + rx_ring->tail);
+ ixgbe_release_rx_desc(&adapter->hw, rx_ring, i);
}
}
@@ -574,10 +622,11 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
}
-static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
+static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
struct ixgbe_ring *rx_ring,
int *work_done, int work_to_do)
{
+ struct ixgbe_adapter *adapter = q_vector->adapter;
struct pci_dev *pdev = adapter->pdev;
union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
@@ -678,7 +727,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
total_rx_packets++;
skb->protocol = eth_type_trans(skb, adapter->netdev);
- ixgbe_receive_skb(adapter, skb, staterr, rx_ring, rx_desc);
+ ixgbe_receive_skb(q_vector, skb, staterr, rx_desc);
next_desc:
rx_desc->wb.upper.status_error = 0;
@@ -696,11 +745,6 @@ next_desc:
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
}
- if (rx_ring->lro_used) {
- lro_flush_all(&rx_ring->lro_mgr);
- rx_ring->lro_used = false;
- }
-
rx_ring->next_to_clean = i;
cleaned_count = IXGBE_DESC_UNUSED(rx_ring);
@@ -731,7 +775,8 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
- /* Populate the IVAR table and set the ITR values to the
+ /*
+ * Populate the IVAR table and set the ITR values to the
* corresponding register.
*/
for (v_idx = 0; v_idx < q_vectors; v_idx++) {
@@ -742,7 +787,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
for (i = 0; i < q_vector->rxr_count; i++) {
j = adapter->rx_ring[r_idx].reg_idx;
- ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(j), v_idx);
+ ixgbe_set_ivar(adapter, 0, j, v_idx);
r_idx = find_next_bit(q_vector->rxr_idx,
adapter->num_rx_queues,
r_idx + 1);
@@ -752,7 +797,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
for (i = 0; i < q_vector->txr_count; i++) {
j = adapter->tx_ring[r_idx].reg_idx;
- ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(j), v_idx);
+ ixgbe_set_ivar(adapter, 1, j, v_idx);
r_idx = find_next_bit(q_vector->txr_idx,
adapter->num_tx_queues,
r_idx + 1);
@@ -761,15 +806,23 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
/* if this is a tx only vector halve the interrupt rate */
if (q_vector->txr_count && !q_vector->rxr_count)
q_vector->eitr = (adapter->eitr_param >> 1);
- else
+ else if (q_vector->rxr_count)
/* rx only */
q_vector->eitr = adapter->eitr_param;
+ /*
+ * since this is initial set up don't need to call
+ * ixgbe_write_eitr helper
+ */
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx),
EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
}
- ixgbe_set_ivar(adapter, IXGBE_IVAR_OTHER_CAUSES_INDEX, v_idx);
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+ ixgbe_set_ivar(adapter, -1, IXGBE_IVAR_OTHER_CAUSES_INDEX,
+ v_idx);
+ else if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+ ixgbe_set_ivar(adapter, -1, 1, v_idx);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950);
/* set up to autoclear timer, and the vectors */
@@ -845,10 +898,35 @@ update_itr_done:
return retval;
}
+/**
+ * ixgbe_write_eitr - write EITR register in hardware specific way
+ * @adapter: pointer to adapter struct
+ * @v_idx: vector index into q_vector array
+ * @itr_reg: new value to be written in *register* format, not ints/s
+ *
+ * This function is made to be called by ethtool and by the driver
+ * when it needs to update EITR registers at runtime. Hardware
+ * specific quirks/differences are taken care of here.
+ */
+void ixgbe_write_eitr(struct ixgbe_adapter *adapter, int v_idx, u32 itr_reg)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ /* must write high and low 16 bits to reset counter */
+ itr_reg |= (itr_reg << 16);
+ } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ /*
+ * set the WDIS bit to not clear the timer bits and cause an
+ * immediate assertion of the interrupt
+ */
+ itr_reg |= IXGBE_EITR_CNT_WDIS;
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg);
+}
+
static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
{
struct ixgbe_adapter *adapter = q_vector->adapter;
- struct ixgbe_hw *hw = &adapter->hw;
u32 new_itr;
u8 current_itr, ret_itr;
int i, r_idx, v_idx = ((void *)q_vector - (void *)(adapter->q_vector)) /
@@ -903,14 +981,13 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
if (new_itr != q_vector->eitr) {
u32 itr_reg;
+
+ /* save the algorithm value here, not the smoothed one */
+ q_vector->eitr = new_itr;
/* do an exponential smoothing */
new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
- q_vector->eitr = new_itr;
itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
- /* must write high and low 16 bits to reset counter */
- DPRINTK(TX_ERR, DEBUG, "writing eitr(%d): %08X\n", v_idx,
- itr_reg);
- IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg | (itr_reg)<<16);
+ ixgbe_write_eitr(adapter, v_idx, itr_reg);
}
return;
@@ -928,6 +1005,24 @@ static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr)
}
}
+static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ if (eicr & IXGBE_EICR_GPI_SDP1) {
+ /* Clear the interrupt */
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
+ schedule_work(&adapter->multispeed_fiber_task);
+ } else if (eicr & IXGBE_EICR_GPI_SDP2) {
+ /* Clear the interrupt */
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
+ schedule_work(&adapter->sfp_config_module_task);
+ } else {
+ /* Interrupt isn't for us... */
+ return;
+ }
+}
+
static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
@@ -946,13 +1041,25 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
struct net_device *netdev = data;
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
- u32 eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
+ u32 eicr;
+
+ /*
+ * Workaround for Silicon errata. Use clear-by-write instead
+ * of clear-by-read. Reading with EICS will return the
+ * interrupt causes without clearing, which later be done
+ * with the write to EICR.
+ */
+ eicr = IXGBE_READ_REG(hw, IXGBE_EICS);
+ IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr);
if (eicr & IXGBE_EICR_LSC)
ixgbe_check_lsc(adapter);
- ixgbe_check_fan_failure(adapter, eicr);
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ ixgbe_check_fan_failure(adapter, eicr);
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ ixgbe_check_sfp_event(adapter, eicr);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
@@ -1015,7 +1122,7 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
rx_ring = &(adapter->rx_ring[r_idx]);
/* disable interrupts on this vector only */
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx);
- netif_rx_schedule(&q_vector->napi);
+ napi_schedule(&q_vector->napi);
return IRQ_HANDLED;
}
@@ -1052,12 +1159,12 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
ixgbe_update_rx_dca(adapter, rx_ring);
#endif
- ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, budget);
+ ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
/* If all Rx work done, exit the polling mode */
if (work_done < budget) {
- netif_rx_complete(napi);
- if (adapter->itr_setting & 3)
+ napi_complete(napi);
+ if (adapter->itr_setting & 1)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rx_ring->v_idx);
@@ -1095,7 +1202,7 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
ixgbe_update_rx_dca(adapter, rx_ring);
#endif
- ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, budget);
+ ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
enable_mask |= rx_ring->v_idx;
r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
r_idx + 1);
@@ -1105,8 +1212,8 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
rx_ring = &(adapter->rx_ring[r_idx]);
/* If all Rx work done, exit the polling mode */
if (work_done < budget) {
- netif_rx_complete(napi);
- if (adapter->itr_setting & 3)
+ napi_complete(napi);
+ if (adapter->itr_setting & 1)
ixgbe_set_itr_msix(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, enable_mask);
@@ -1276,7 +1383,6 @@ out:
static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
{
- struct ixgbe_hw *hw = &adapter->hw;
struct ixgbe_q_vector *q_vector = adapter->q_vector;
u8 current_itr;
u32 new_itr = q_vector->eitr;
@@ -1311,35 +1417,19 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
if (new_itr != q_vector->eitr) {
u32 itr_reg;
+
+ /* save the algorithm value here, not the smoothed one */
+ q_vector->eitr = new_itr;
/* do an exponential smoothing */
new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
- q_vector->eitr = new_itr;
itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
- /* must write high and low 16 bits to reset counter */
- IXGBE_WRITE_REG(hw, IXGBE_EITR(0), itr_reg | (itr_reg)<<16);
+ ixgbe_write_eitr(adapter, 0, itr_reg);
}
return;
}
/**
- * ixgbe_irq_disable - Mask off interrupt generation on the NIC
- * @adapter: board private structure
- **/
-static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
-{
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
- IXGBE_WRITE_FLUSH(&adapter->hw);
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- int i;
- for (i = 0; i < adapter->num_msix_vectors; i++)
- synchronize_irq(adapter->msix_entries[i].vector);
- } else {
- synchronize_irq(adapter->pdev->irq);
- }
-}
-
-/**
* ixgbe_irq_enable - Enable default interrupt generation settings
* @adapter: board private structure
**/
@@ -1349,7 +1439,21 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
mask = IXGBE_EIMS_ENABLE_MASK;
if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
mask |= IXGBE_EIMS_GPI_SDP1;
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ mask |= IXGBE_EIMS_ECC;
+ mask |= IXGBE_EIMS_GPI_SDP1;
+ mask |= IXGBE_EIMS_GPI_SDP2;
+ }
+
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ /* enable the rest of the queue vectors */
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1),
+ (IXGBE_EIMS_RTX_QUEUE << 16));
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2),
+ ((IXGBE_EIMS_RTX_QUEUE << 16) |
+ IXGBE_EIMS_RTX_QUEUE));
+ }
IXGBE_WRITE_FLUSH(&adapter->hw);
}
@@ -1365,6 +1469,12 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
struct ixgbe_hw *hw = &adapter->hw;
u32 eicr;
+ /*
+ * Workaround for silicon errata. Mask the interrupts
+ * before the read of EICR.
+ */
+ IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
+
/* for NAPI, using EIAM to auto-mask tx/rx interrupt bits on read
* therefore no explict interrupt disable is necessary */
eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
@@ -1379,15 +1489,18 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
if (eicr & IXGBE_EICR_LSC)
ixgbe_check_lsc(adapter);
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ ixgbe_check_sfp_event(adapter, eicr);
+
ixgbe_check_fan_failure(adapter, eicr);
- if (netif_rx_schedule_prep(&adapter->q_vector[0].napi)) {
+ if (napi_schedule_prep(&adapter->q_vector[0].napi)) {
adapter->tx_ring[0].total_packets = 0;
adapter->tx_ring[0].total_bytes = 0;
adapter->rx_ring[0].total_packets = 0;
adapter->rx_ring[0].total_bytes = 0;
/* would disable interrupts here but EIAM disabled it */
- __netif_rx_schedule(&adapter->q_vector[0].napi);
+ __napi_schedule(&adapter->q_vector[0].napi);
}
return IRQ_HANDLED;
@@ -1459,6 +1572,39 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
}
/**
+ * ixgbe_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ **/
+static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
+{
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(2), ~0);
+ }
+ IXGBE_WRITE_FLUSH(&adapter->hw);
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ int i;
+ for (i = 0; i < adapter->num_msix_vectors; i++)
+ synchronize_irq(adapter->msix_entries[i].vector);
+ } else {
+ synchronize_irq(adapter->pdev->irq);
+ }
+}
+
+static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter)
+{
+ u32 mask = IXGBE_EIMS_RTX_QUEUE;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask << 16);
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2),
+ (mask << 16 | mask));
+ }
+ /* skip the flush */
+}
+
+/**
* ixgbe_configure_msi_and_legacy - Initialize PIN (INTA...) and MSI interrupts
*
**/
@@ -1469,8 +1615,8 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_EITR(0),
EITR_INTS_PER_SEC_TO_REG(adapter->eitr_param));
- ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(0), 0);
- ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(0), 0);
+ ixgbe_set_ivar(adapter, 0, 0, 0);
+ ixgbe_set_ivar(adapter, 1, 0, 0);
map_vector_to_rxq(adapter, 0, 0);
map_vector_to_txq(adapter, 0, 0);
@@ -1486,7 +1632,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
**/
static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
{
- u64 tdba, tdwba;
+ u64 tdba;
struct ixgbe_hw *hw = &adapter->hw;
u32 i, j, tdlen, txctrl;
@@ -1499,11 +1645,6 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j),
(tdba & DMA_32BIT_MASK));
IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32));
- tdwba = ring->dma +
- (ring->count * sizeof(union ixgbe_adv_tx_desc));
- tdwba |= IXGBE_TDWBAL_HEAD_WB_ENABLE;
- IXGBE_WRITE_REG(hw, IXGBE_TDWBAL(j), tdwba & DMA_32BIT_MASK);
- IXGBE_WRITE_REG(hw, IXGBE_TDWBAH(j), (tdwba >> 32));
IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), tdlen);
IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0);
IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
@@ -1516,26 +1657,25 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl);
}
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ /* We enable 8 traffic classes, DCB only */
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
+ IXGBE_WRITE_REG(hw, IXGBE_MTQC, (IXGBE_MTQC_RT_ENA |
+ IXGBE_MTQC_8TC_8TQ));
+ }
}
-#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
+#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
{
struct ixgbe_ring *rx_ring;
u32 srrctl;
- int queue0;
+ int queue0 = 0;
unsigned long mask;
- /* program one srrctl register per VMDq index */
- if (adapter->flags & IXGBE_FLAG_VMDQ_ENABLED) {
- long shift, len;
- mask = (unsigned long) adapter->ring_feature[RING_F_RSS].mask;
- len = sizeof(adapter->ring_feature[RING_F_VMDQ].mask) * 8;
- shift = find_first_bit(&mask, len);
- queue0 = index & mask;
- index = (index & mask) >> shift;
- /* program one srrctl per RSS queue since RDRXCTL.MVMEN is enabled */
+ if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ queue0 = index;
} else {
mask = (unsigned long) adapter->ring_feature[RING_F_RSS].mask;
queue0 = index & mask;
@@ -1550,7 +1690,14 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
- srrctl |= IXGBE_RXBUFFER_2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+ u16 bufsz = IXGBE_RXBUFFER_2048;
+ /* grow the amount we can receive on large page machines */
+ if (bufsz < (PAGE_SIZE / 2))
+ bufsz = (PAGE_SIZE / 2);
+ /* cap the bufsz at our largest descriptor size */
+ bufsz = min((u16)IXGBE_MAX_RXBUFFER, bufsz);
+
+ srrctl |= bufsz >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
srrctl |= ((IXGBE_RX_HDR_SIZE <<
IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
@@ -1565,39 +1712,10 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
srrctl |= rx_ring->rx_buf_len >>
IXGBE_SRRCTL_BSIZEPKT_SHIFT;
}
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
-}
-/**
- * ixgbe_get_skb_hdr - helper function for LRO header processing
- * @skb: pointer to sk_buff to be added to LRO packet
- * @iphdr: pointer to ip header structure
- * @tcph: pointer to tcp header structure
- * @hdr_flags: pointer to header flags
- * @priv: private data
- **/
-static int ixgbe_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
- u64 *hdr_flags, void *priv)
-{
- union ixgbe_adv_rx_desc *rx_desc = priv;
-
- /* Verify that this is a valid IPv4 TCP packet */
- if (!((ixgbe_get_pkt_info(rx_desc) & IXGBE_RXDADV_PKTTYPE_IPV4) &&
- (ixgbe_get_pkt_info(rx_desc) & IXGBE_RXDADV_PKTTYPE_TCP)))
- return -1;
-
- /* Set network headers */
- skb_reset_network_header(skb);
- skb_set_transport_header(skb, ip_hdrlen(skb));
- *iphdr = ip_hdr(skb);
- *tcph = tcp_hdr(skb);
- *hdr_flags = LRO_IPV4 | LRO_TCP;
- return 0;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
}
-#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
- (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
-
/**
* ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
* @adapter: board private structure
@@ -1616,8 +1734,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE,
0x6A3E67EA, 0x14364D17, 0x3BED200D};
u32 fctrl, hlreg0;
- u32 pages;
- u32 reta = 0, mrqc;
+ u32 reta = 0, mrqc = 0;
u32 rdrxctl;
int rx_buf_len;
@@ -1627,6 +1744,14 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
/* Set the RX buffer length according to the mode */
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
rx_buf_len = IXGBE_RX_HDR_SIZE;
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ /* PSRTYPE must be initialized in 82599 */
+ u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
+ IXGBE_PSRTYPE_UDPHDR |
+ IXGBE_PSRTYPE_IPV4HDR |
+ IXGBE_PSRTYPE_IPV6HDR;
+ IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype);
+ }
} else {
if (netdev->mtu <= ETH_DATA_LEN)
rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
@@ -1637,6 +1762,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
fctrl |= IXGBE_FCTRL_BAM;
fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */
+ fctrl |= IXGBE_FCTRL_PMCF;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl);
hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
@@ -1646,8 +1772,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
hlreg0 |= IXGBE_HLREG0_JUMBOEN;
IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
- pages = PAGE_USE_COUNT(adapter->netdev->mtu);
-
rdlen = adapter->rx_ring[0].count * sizeof(union ixgbe_adv_rx_desc);
/* disable receives while setting up the descriptors */
rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
@@ -1666,37 +1790,44 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
adapter->rx_ring[i].head = IXGBE_RDH(j);
adapter->rx_ring[i].tail = IXGBE_RDT(j);
adapter->rx_ring[i].rx_buf_len = rx_buf_len;
- /* Intitial LRO Settings */
- adapter->rx_ring[i].lro_mgr.max_aggr = IXGBE_MAX_LRO_AGGREGATE;
- adapter->rx_ring[i].lro_mgr.max_desc = IXGBE_MAX_LRO_DESCRIPTORS;
- adapter->rx_ring[i].lro_mgr.get_skb_header = ixgbe_get_skb_hdr;
- adapter->rx_ring[i].lro_mgr.features = LRO_F_EXTRACT_VLAN_ID;
- if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL))
- adapter->rx_ring[i].lro_mgr.features |= LRO_F_NAPI;
- adapter->rx_ring[i].lro_mgr.dev = adapter->netdev;
- adapter->rx_ring[i].lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
- adapter->rx_ring[i].lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
ixgbe_configure_srrctl(adapter, j);
}
- /*
- * For VMDq support of different descriptor types or
- * buffer sizes through the use of multiple SRRCTL
- * registers, RDRXCTL.MVMEN must be set to 1
- *
- * also, the manual doesn't mention it clearly but DCA hints
- * will only use queue 0's tags unless this bit is set. Side
- * effects of setting this bit are only that SRRCTL must be
- * fully programmed [0..15]
- */
- if (adapter->flags &
- (IXGBE_FLAG_RSS_ENABLED | IXGBE_FLAG_VMDQ_ENABLED)) {
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ /*
+ * For VMDq support of different descriptor types or
+ * buffer sizes through the use of multiple SRRCTL
+ * registers, RDRXCTL.MVMEN must be set to 1
+ *
+ * also, the manual doesn't mention it clearly but DCA hints
+ * will only use queue 0's tags unless this bit is set. Side
+ * effects of setting this bit are only that SRRCTL must be
+ * fully programmed [0..15]
+ */
rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
rdrxctl |= IXGBE_RDRXCTL_MVMEN;
IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
}
+ /* Program MRQC for the distribution of queues */
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ int mask = adapter->flags & (
+ IXGBE_FLAG_RSS_ENABLED
+ | IXGBE_FLAG_DCB_ENABLED
+ );
+
+ switch (mask) {
+ case (IXGBE_FLAG_RSS_ENABLED):
+ mrqc = IXGBE_MRQC_RSSEN;
+ break;
+ case (IXGBE_FLAG_DCB_ENABLED):
+ mrqc = IXGBE_MRQC_RT8TCEN;
+ break;
+ default:
+ break;
+ }
+ }
if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
/* Fill out redirection table */
for (i = 0, j = 0; i < 128; i++, j++) {
@@ -1713,19 +1844,17 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
for (i = 0; i < 10; i++)
IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]);
- mrqc = IXGBE_MRQC_RSSEN
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ mrqc |= IXGBE_MRQC_RSSEN;
/* Perform hash on these packet types */
- | IXGBE_MRQC_RSS_FIELD_IPV4
- | IXGBE_MRQC_RSS_FIELD_IPV4_TCP
- | IXGBE_MRQC_RSS_FIELD_IPV4_UDP
- | IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP
- | IXGBE_MRQC_RSS_FIELD_IPV6_EX
- | IXGBE_MRQC_RSS_FIELD_IPV6
- | IXGBE_MRQC_RSS_FIELD_IPV6_TCP
- | IXGBE_MRQC_RSS_FIELD_IPV6_UDP
- | IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP;
- IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
+ mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4
+ | IXGBE_MRQC_RSS_FIELD_IPV4_TCP
+ | IXGBE_MRQC_RSS_FIELD_IPV4_UDP
+ | IXGBE_MRQC_RSS_FIELD_IPV6
+ | IXGBE_MRQC_RSS_FIELD_IPV6_TCP
+ | IXGBE_MRQC_RSS_FIELD_IPV6_UDP;
}
+ IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM);
@@ -1742,6 +1871,12 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
}
IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum);
+
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
+ rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP;
+ IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
+ }
}
static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
@@ -1775,6 +1910,7 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
u32 ctrl;
+ int i, j;
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_disable(adapter);
@@ -1786,18 +1922,24 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
* not in DCB mode.
*/
ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL);
- ctrl |= IXGBE_VLNCTRL_VME;
- ctrl &= ~IXGBE_VLNCTRL_CFIEN;
- IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
- ixgbe_vlan_rx_add_vid(netdev, 0);
-
- if (grp) {
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+ ctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
+ ctrl &= ~IXGBE_VLNCTRL_CFIEN;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
+ } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ ctrl |= IXGBE_VLNCTRL_VFE;
/* enable VLAN tag insert/strip */
ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_VLNCTRL);
- ctrl |= IXGBE_VLNCTRL_VME;
ctrl &= ~IXGBE_VLNCTRL_CFIEN;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ j = adapter->rx_ring[i].reg_idx;
+ ctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(j));
+ ctrl |= IXGBE_RXDCTL_VME;
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(j), ctrl);
+ }
}
+ ixgbe_vlan_rx_add_vid(netdev, 0);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable(adapter);
@@ -1960,9 +2102,21 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
}
/* Enable VLAN tag insert/strip */
vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
- vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
- vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
- IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE;
+ vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+ IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+ } else if (hw->mac.type == ixgbe_mac_82599EB) {
+ vlnctrl |= IXGBE_VLNCTRL_VFE;
+ vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
+ IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ j = adapter->rx_ring[i].reg_idx;
+ vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
+ vlnctrl |= IXGBE_RXDCTL_VME;
+ IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), vlnctrl);
+ }
+ }
hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true);
}
@@ -1993,13 +2147,115 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
(adapter->rx_ring[i].count - 1));
}
+static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw)
+{
+ switch (hw->phy.type) {
+ case ixgbe_phy_sfp_avago:
+ case ixgbe_phy_sfp_ftl:
+ case ixgbe_phy_sfp_intel:
+ case ixgbe_phy_sfp_unknown:
+ case ixgbe_phy_tw_tyco:
+ case ixgbe_phy_tw_unknown:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * ixgbe_sfp_link_config - set up SFP+ link
+ * @adapter: pointer to private adapter struct
+ **/
+static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ if (hw->phy.multispeed_fiber) {
+ /*
+ * In multispeed fiber setups, the device may not have
+ * had a physical connection when the driver loaded.
+ * If that's the case, the initial link configuration
+ * couldn't get the MAC into 10G or 1G mode, so we'll
+ * never have a link status change interrupt fire.
+ * We need to try and force an autonegotiation
+ * session, then bring up link.
+ */
+ hw->mac.ops.setup_sfp(hw);
+ if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
+ schedule_work(&adapter->multispeed_fiber_task);
+ } else {
+ /*
+ * Direct Attach Cu and non-multispeed fiber modules
+ * still need to be configured properly prior to
+ * attempting link.
+ */
+ if (!(adapter->flags & IXGBE_FLAG_IN_SFP_MOD_TASK))
+ schedule_work(&adapter->sfp_config_module_task);
+ }
+}
+
+/**
+ * ixgbe_non_sfp_link_config - set up non-SFP+ link
+ * @hw: pointer to private hardware struct
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw)
+{
+ u32 autoneg;
+ bool link_up = false;
+ u32 ret = IXGBE_ERR_LINK_SETUP;
+
+ if (hw->mac.ops.check_link)
+ ret = hw->mac.ops.check_link(hw, &autoneg, &link_up, false);
+
+ if (ret)
+ goto link_cfg_out;
+
+ if (hw->mac.ops.get_link_capabilities)
+ ret = hw->mac.ops.get_link_capabilities(hw, &autoneg,
+ &hw->mac.autoneg);
+ if (ret)
+ goto link_cfg_out;
+
+ if (hw->mac.ops.setup_link_speed)
+ ret = hw->mac.ops.setup_link_speed(hw, autoneg, true, link_up);
+link_cfg_out:
+ return ret;
+}
+
+#define IXGBE_MAX_RX_DESC_POLL 10
+static inline void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
+ int rxr)
+{
+ int j = adapter->rx_ring[rxr].reg_idx;
+ int k;
+
+ for (k = 0; k < IXGBE_MAX_RX_DESC_POLL; k++) {
+ if (IXGBE_READ_REG(&adapter->hw,
+ IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE)
+ break;
+ else
+ msleep(1);
+ }
+ if (k >= IXGBE_MAX_RX_DESC_POLL) {
+ DPRINTK(DRV, ERR, "RXDCTL.ENABLE on Rx queue %d "
+ "not set within the polling period\n", rxr);
+ }
+ ixgbe_release_rx_desc(&adapter->hw, &adapter->rx_ring[rxr],
+ (adapter->rx_ring[rxr].count - 1));
+}
+
static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
struct ixgbe_hw *hw = &adapter->hw;
int i, j = 0;
+ int num_rx_rings = adapter->num_rx_queues;
+ int err;
int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
u32 txdctl, rxdctl, mhadd;
+ u32 dmatxctl;
u32 gpie;
ixgbe_get_hw_control(adapter);
@@ -2031,6 +2287,13 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
}
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
+ gpie |= IXGBE_SDP1_GPIEN;
+ gpie |= IXGBE_SDP2_GPIEN;
+ IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
+ }
+
mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) {
mhadd &= ~IXGBE_MHADD_MFS_MASK;
@@ -2044,11 +2307,23 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
/* enable WTHRESH=8 descriptors, to encourage burst writeback */
txdctl |= (8 << 16);
+ IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
+ }
+
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ /* DMATXCTL.EN must be set after all Tx queue config is done */
+ dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
+ dmatxctl |= IXGBE_DMATXCTL_TE;
+ IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl);
+ }
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ j = adapter->tx_ring[i].reg_idx;
+ txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
txdctl |= IXGBE_TXDCTL_ENABLE;
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl);
}
- for (i = 0; i < adapter->num_rx_queues; i++) {
+ for (i = 0; i < num_rx_rings; i++) {
j = adapter->rx_ring[i].reg_idx;
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j));
/* enable PTHRESH=32 descriptors (half the internal cache)
@@ -2057,19 +2332,22 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
rxdctl |= 0x0020;
rxdctl |= IXGBE_RXDCTL_ENABLE;
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), rxdctl);
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ ixgbe_rx_desc_queue_enable(adapter, i);
}
/* enable all receives */
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
- rxdctl |= (IXGBE_RXCTRL_DMBYPS | IXGBE_RXCTRL_RXEN);
- IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxdctl);
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ rxdctl |= (IXGBE_RXCTRL_DMBYPS | IXGBE_RXCTRL_RXEN);
+ else
+ rxdctl |= IXGBE_RXCTRL_RXEN;
+ hw->mac.ops.enable_rx_dma(hw, rxdctl);
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
ixgbe_configure_msix(adapter);
else
ixgbe_configure_msi_and_legacy(adapter);
- ixgbe_napi_add_all(adapter);
-
clear_bit(__IXGBE_DOWN, &adapter->state);
ixgbe_napi_enable_all(adapter);
@@ -2078,6 +2356,28 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
ixgbe_irq_enable(adapter);
+ /*
+ * For hot-pluggable SFP+ devices, a new SFP+ module may have
+ * arrived before interrupts were enabled. We need to kick off
+ * the SFP+ module setup first, then try to bring up link.
+ * If we're not hot-pluggable SFP+, we just need to configure link
+ * and bring it up.
+ */
+ err = hw->phy.ops.identify(hw);
+ if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+ DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err);
+ ixgbe_down(adapter);
+ return err;
+ }
+
+ if (ixgbe_is_sfp(hw)) {
+ ixgbe_sfp_link_config(adapter);
+ } else {
+ err = ixgbe_non_sfp_link_config(hw);
+ if (err)
+ DPRINTK(PROBE, ERR, "link_config FAILED %d\n", err);
+ }
+
/* enable transmits */
netif_tx_start_all_queues(netdev);
@@ -2104,6 +2404,8 @@ int ixgbe_up(struct ixgbe_adapter *adapter)
/* hardware has been reset, we need to reload some things */
ixgbe_configure(adapter);
+ ixgbe_napi_add_all(adapter);
+
return ixgbe_up_complete(adapter);
}
@@ -2165,8 +2467,10 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0;
- writel(0, adapter->hw.hw_addr + rx_ring->head);
- writel(0, adapter->hw.hw_addr + rx_ring->tail);
+ if (rx_ring->head)
+ writel(0, adapter->hw.hw_addr + rx_ring->head);
+ if (rx_ring->tail)
+ writel(0, adapter->hw.hw_addr + rx_ring->tail);
}
/**
@@ -2197,8 +2501,10 @@ static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter,
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
- writel(0, adapter->hw.hw_addr + tx_ring->head);
- writel(0, adapter->hw.hw_addr + tx_ring->tail);
+ if (tx_ring->head)
+ writel(0, adapter->hw.hw_addr + tx_ring->head);
+ if (tx_ring->tail)
+ writel(0, adapter->hw.hw_addr + tx_ring->tail);
}
/**
@@ -2261,6 +2567,11 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j),
(txdctl & ~IXGBE_TXDCTL_ENABLE));
}
+ /* Disable the Tx DMA engine on 82599 */
+ if (hw->mac.type == ixgbe_mac_82599EB)
+ IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,
+ (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
+ ~IXGBE_DMATXCTL_TE));
netif_carrier_off(netdev);
@@ -2297,10 +2608,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
**/
static int ixgbe_poll(struct napi_struct *napi, int budget)
{
- struct ixgbe_q_vector *q_vector = container_of(napi,
- struct ixgbe_q_vector, napi);
+ struct ixgbe_q_vector *q_vector =
+ container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
- int tx_cleaned, work_done = 0;
+ int tx_clean_complete, work_done = 0;
#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
@@ -2309,19 +2620,19 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
}
#endif
- tx_cleaned = ixgbe_clean_tx_irq(adapter, adapter->tx_ring);
- ixgbe_clean_rx_irq(adapter, adapter->rx_ring, &work_done, budget);
+ tx_clean_complete = ixgbe_clean_tx_irq(adapter, adapter->tx_ring);
+ ixgbe_clean_rx_irq(q_vector, adapter->rx_ring, &work_done, budget);
- if (tx_cleaned)
+ if (!tx_clean_complete)
work_done = budget;
/* If budget not fully consumed, exit the polling mode */
if (work_done < budget) {
- netif_rx_complete(napi);
- if (adapter->itr_setting & 3)
+ napi_complete(napi);
+ if (adapter->itr_setting & 1)
ixgbe_set_itr(adapter);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_enable(adapter);
+ ixgbe_irq_enable_queues(adapter);
}
return work_done;
}
@@ -2353,68 +2664,76 @@ static void ixgbe_reset_task(struct work_struct *work)
ixgbe_reinit_locked(adapter);
}
-static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
+#ifdef CONFIG_IXGBE_DCB
+static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter)
{
- int nrq = 1, ntq = 1;
- int feature_mask = 0, rss_i, rss_m;
- int dcb_i, dcb_m;
+ bool ret = false;
- /* Number of supported queues */
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82598EB:
- dcb_i = adapter->ring_feature[RING_F_DCB].indices;
- dcb_m = 0;
- rss_i = adapter->ring_feature[RING_F_RSS].indices;
- rss_m = 0;
- feature_mask |= IXGBE_FLAG_RSS_ENABLED;
- feature_mask |= IXGBE_FLAG_DCB_ENABLED;
-
- switch (adapter->flags & feature_mask) {
- case (IXGBE_FLAG_RSS_ENABLED | IXGBE_FLAG_DCB_ENABLED):
- dcb_m = 0x7 << 3;
- rss_i = min(8, rss_i);
- rss_m = 0x7;
- nrq = dcb_i * rss_i;
- ntq = min(MAX_TX_QUEUES, dcb_i * rss_i);
- break;
- case (IXGBE_FLAG_DCB_ENABLED):
- dcb_m = 0x7 << 3;
- nrq = dcb_i;
- ntq = dcb_i;
- break;
- case (IXGBE_FLAG_RSS_ENABLED):
- rss_m = 0xF;
- nrq = rss_i;
- ntq = rss_i;
- break;
- case 0:
- default:
- dcb_i = 0;
- dcb_m = 0;
- rss_i = 0;
- rss_m = 0;
- nrq = 1;
- ntq = 1;
- break;
- }
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ adapter->ring_feature[RING_F_DCB].mask = 0x7 << 3;
+ adapter->num_rx_queues =
+ adapter->ring_feature[RING_F_DCB].indices;
+ adapter->num_tx_queues =
+ adapter->ring_feature[RING_F_DCB].indices;
+ ret = true;
+ } else {
+ ret = false;
+ }
+
+ return ret;
+}
+#endif
- /* Sanity check, we should never have zero queues */
- nrq = (nrq ?:1);
- ntq = (ntq ?:1);
+/**
+ * ixgbe_set_rss_queues: Allocate queues for RSS
+ * @adapter: board private structure to initialize
+ *
+ * This is our "base" multiqueue mode. RSS (Receive Side Scaling) will try
+ * to allocate one Rx queue per CPU, and if available, one Tx queue per CPU.
+ *
+ **/
+static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
+{
+ bool ret = false;
- adapter->ring_feature[RING_F_DCB].indices = dcb_i;
- adapter->ring_feature[RING_F_DCB].mask = dcb_m;
- adapter->ring_feature[RING_F_RSS].indices = rss_i;
- adapter->ring_feature[RING_F_RSS].mask = rss_m;
- break;
- default:
- nrq = 1;
- ntq = 1;
- break;
+ if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
+ adapter->ring_feature[RING_F_RSS].mask = 0xF;
+ adapter->num_rx_queues =
+ adapter->ring_feature[RING_F_RSS].indices;
+ adapter->num_tx_queues =
+ adapter->ring_feature[RING_F_RSS].indices;
+ ret = true;
+ } else {
+ ret = false;
}
- adapter->num_rx_queues = nrq;
- adapter->num_tx_queues = ntq;
+ return ret;
+}
+
+/*
+ * ixgbe_set_num_queues: Allocate queues for device, feature dependant
+ * @adapter: board private structure to initialize
+ *
+ * This is the top level queue allocation routine. The order here is very
+ * important, starting with the "most" number of features turned on at once,
+ * and ending with the smallest set of features. This way large combinations
+ * can be allocated if they're turned on, and smaller combinations are the
+ * fallthrough conditions.
+ *
+ **/
+static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
+{
+ /* Start with base case */
+ adapter->num_rx_queues = 1;
+ adapter->num_tx_queues = 1;
+
+#ifdef CONFIG_IXGBE_DCB
+ if (ixgbe_set_dcb_queues(adapter))
+ return;
+
+#endif
+ if (ixgbe_set_rss_queues(adapter))
+ return;
}
static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
@@ -2460,71 +2779,104 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
ixgbe_set_num_queues(adapter);
} else {
adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */
- adapter->num_msix_vectors = vectors;
+ /*
+ * Adjust for only the vectors we'll use, which is minimum
+ * of max_msix_q_vectors + NON_Q_VECTORS, or the number of
+ * vectors we were allocated.
+ */
+ adapter->num_msix_vectors = min(vectors,
+ adapter->max_msix_q_vectors + NON_Q_VECTORS);
}
}
/**
- * ixgbe_cache_ring_register - Descriptor ring to register mapping
+ * ixgbe_cache_ring_rss - Descriptor ring to register mapping for RSS
* @adapter: board private structure to initialize
*
- * Once we know the feature-set enabled for the device, we'll cache
- * the register offset the descriptor ring is assigned to.
+ * Cache the descriptor ring offsets for RSS to the assigned rings.
+ *
**/
-static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
+static inline bool ixgbe_cache_ring_rss(struct ixgbe_adapter *adapter)
{
- int feature_mask = 0, rss_i;
- int i, txr_idx, rxr_idx;
- int dcb_i;
+ int i;
+ bool ret = false;
- /* Number of supported queues */
- switch (adapter->hw.mac.type) {
- case ixgbe_mac_82598EB:
- dcb_i = adapter->ring_feature[RING_F_DCB].indices;
- rss_i = adapter->ring_feature[RING_F_RSS].indices;
- txr_idx = 0;
- rxr_idx = 0;
- feature_mask |= IXGBE_FLAG_DCB_ENABLED;
- feature_mask |= IXGBE_FLAG_RSS_ENABLED;
- switch (adapter->flags & feature_mask) {
- case (IXGBE_FLAG_RSS_ENABLED | IXGBE_FLAG_DCB_ENABLED):
- for (i = 0; i < dcb_i; i++) {
- int j;
- /* Rx first */
- for (j = 0; j < adapter->num_rx_queues; j++) {
- adapter->rx_ring[rxr_idx].reg_idx =
- i << 3 | j;
- rxr_idx++;
- }
- /* Tx now */
- for (j = 0; j < adapter->num_tx_queues; j++) {
- adapter->tx_ring[txr_idx].reg_idx =
- i << 2 | (j >> 1);
- if (j & 1)
- txr_idx++;
- }
- }
- case (IXGBE_FLAG_DCB_ENABLED):
+ if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ adapter->rx_ring[i].reg_idx = i;
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ adapter->tx_ring[i].reg_idx = i;
+ ret = true;
+ } else {
+ ret = false;
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_IXGBE_DCB
+/**
+ * ixgbe_cache_ring_dcb - Descriptor ring to register mapping for DCB
+ * @adapter: board private structure to initialize
+ *
+ * Cache the descriptor ring offsets for DCB to the assigned rings.
+ *
+ **/
+static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter)
+{
+ int i;
+ bool ret = false;
+ int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
+
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
/* the number of queues is assumed to be symmetric */
for (i = 0; i < dcb_i; i++) {
adapter->rx_ring[i].reg_idx = i << 3;
adapter->tx_ring[i].reg_idx = i << 2;
}
- break;
- case (IXGBE_FLAG_RSS_ENABLED):
- for (i = 0; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i].reg_idx = i;
- for (i = 0; i < adapter->num_tx_queues; i++)
- adapter->tx_ring[i].reg_idx = i;
- break;
- case 0:
- default:
- break;
+ ret = true;
+ } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+ for (i = 0; i < dcb_i; i++) {
+ adapter->rx_ring[i].reg_idx = i << 4;
+ adapter->tx_ring[i].reg_idx = i << 4;
+ }
+ ret = true;
+ } else {
+ ret = false;
}
- break;
- default:
- break;
+ } else {
+ ret = false;
}
+
+ return ret;
+}
+#endif
+
+/**
+ * ixgbe_cache_ring_register - Descriptor ring to register mapping
+ * @adapter: board private structure to initialize
+ *
+ * Once we know the feature-set enabled for the device, we'll cache
+ * the register offset the descriptor ring is assigned to.
+ *
+ * Note, the order the various feature calls is important. It must start with
+ * the "most" features enabled at the same time, then trickle down to the
+ * least amount of features turned on at once.
+ **/
+static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
+{
+ /* start with default case */
+ adapter->rx_ring[0].reg_idx = 0;
+ adapter->tx_ring[0].reg_idx = 0;
+
+#ifdef CONFIG_IXGBE_DCB
+ if (ixgbe_cache_ring_dcb(adapter))
+ return;
+
+#endif
+ if (ixgbe_cache_ring_rss(adapter))
+ return;
}
/**
@@ -2532,7 +2884,8 @@ static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
* @adapter: board private structure to initialize
*
* We allocate one ring per queue at run-time since we don't know the
- * number of queues at compile-time.
+ * number of queues at compile-time. The polling_netdev array is
+ * intended for Multiqueue, but should work fine with a single queue.
**/
static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
{
@@ -2577,6 +2930,7 @@ err_tx_ring_allocation:
**/
static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
{
+ struct ixgbe_hw *hw = &adapter->hw;
int err = 0;
int vector, v_budget;
@@ -2591,12 +2945,12 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
/*
* At the same time, hardware can only support a maximum of
- * MAX_MSIX_COUNT vectors. With features such as RSS and VMDq,
- * we can easily reach upwards of 64 Rx descriptor queues and
- * 32 Tx queues. Thus, we cap it off in those rare cases where
- * the cpu count also exceeds our vector limit.
+ * hw.mac->max_msix_vectors vectors. With features
+ * such as RSS and VMDq, we can easily surpass the number of Rx and Tx
+ * descriptor queues supported by our device. Thus, we cap it off in
+ * those rare cases where the cpu count also exceeds our vector limit.
*/
- v_budget = min(v_budget, MAX_MSIX_COUNT);
+ v_budget = min(v_budget, (int)hw->mac.max_msix_vectors);
/* A failure in MSI-X entry allocation isn't fatal, but it does
* mean we disable MSI-X capabilities of the adapter. */
@@ -2711,7 +3065,8 @@ static void ixgbe_sfp_timer(unsigned long data)
{
struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
- /* Do the sfp_timer outside of interrupt context due to the
+ /*
+ * Do the sfp_timer outside of interrupt context due to the
* delays that sfp+ detection requires
*/
schedule_work(&adapter->sfp_task);
@@ -2785,6 +3140,10 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->ring_feature[RING_F_RSS].indices = rss;
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
adapter->ring_feature[RING_F_DCB].indices = IXGBE_MAX_DCB_INDICES;
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598;
+ else if (hw->mac.type == ixgbe_mac_82599EB)
+ adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599;
#ifdef CONFIG_IXGBE_DCB
/* Configure DCB traffic classes */
@@ -2805,20 +3164,15 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->ring_feature[RING_F_DCB].indices);
#endif
- if (hw->mac.ops.get_media_type &&
- (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper))
- adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE;
/* default flow control settings */
- hw->fc.original_type = ixgbe_fc_none;
- hw->fc.type = ixgbe_fc_none;
+ hw->fc.requested_mode = ixgbe_fc_full;
+ hw->fc.current_mode = ixgbe_fc_full; /* init for ethtool output */
hw->fc.high_water = IXGBE_DEFAULT_FCRTH;
hw->fc.low_water = IXGBE_DEFAULT_FCRTL;
hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
hw->fc.send_xon = true;
-
- /* select 10G link by default */
- hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
+ hw->fc.disable_fc_autoneg = false;
/* enable itr by default in dynamic mode */
adapter->itr_setting = 1;
@@ -2866,8 +3220,7 @@ int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,
memset(tx_ring->tx_buffer_info, 0, size);
/* round up to nearest 4K */
- tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc) +
- sizeof(u32);
+ tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
tx_ring->size = ALIGN(tx_ring->size, 4096);
tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
@@ -2926,12 +3279,6 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
struct pci_dev *pdev = adapter->pdev;
int size;
- size = sizeof(struct net_lro_desc) * IXGBE_MAX_LRO_DESCRIPTORS;
- rx_ring->lro_mgr.lro_arr = vmalloc(size);
- if (!rx_ring->lro_mgr.lro_arr)
- return -ENOMEM;
- memset(rx_ring->lro_mgr.lro_arr, 0, size);
-
size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
rx_ring->rx_buffer_info = vmalloc(size);
if (!rx_ring->rx_buffer_info) {
@@ -2960,8 +3307,6 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
return 0;
alloc_failed:
- vfree(rx_ring->lro_mgr.lro_arr);
- rx_ring->lro_mgr.lro_arr = NULL;
return -ENOMEM;
}
@@ -3024,7 +3369,8 @@ static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter)
int i;
for (i = 0; i < adapter->num_tx_queues; i++)
- ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]);
+ if (adapter->tx_ring[i].desc)
+ ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]);
}
/**
@@ -3039,9 +3385,6 @@ void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
{
struct pci_dev *pdev = adapter->pdev;
- vfree(rx_ring->lro_mgr.lro_arr);
- rx_ring->lro_mgr.lro_arr = NULL;
-
ixgbe_clean_rx_ring(adapter, rx_ring);
vfree(rx_ring->rx_buffer_info);
@@ -3063,7 +3406,8 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter)
int i;
for (i = 0; i < adapter->num_rx_queues; i++)
- ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]);
+ if (adapter->rx_ring[i].desc)
+ ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]);
}
/**
@@ -3126,6 +3470,8 @@ static int ixgbe_open(struct net_device *netdev)
ixgbe_configure(adapter);
+ ixgbe_napi_add_all(adapter);
+
err = ixgbe_request_irq(adapter);
if (err)
goto err_req_irq;
@@ -3142,10 +3488,10 @@ err_up:
ixgbe_release_hw_control(adapter);
ixgbe_free_irq(adapter);
err_req_irq:
- ixgbe_free_all_rx_resources(adapter);
err_setup_rx:
- ixgbe_free_all_tx_resources(adapter);
+ ixgbe_free_all_rx_resources(adapter);
err_setup_tx:
+ ixgbe_free_all_tx_resources(adapter);
ixgbe_reset(adapter);
return err;
@@ -3180,6 +3526,7 @@ static int ixgbe_close(struct net_device *netdev)
/**
* ixgbe_napi_add_all - prep napi structs for use
* @adapter: private struct
+ *
* helper function to napi_add each possible q_vector->napi
*/
void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
@@ -3252,7 +3599,6 @@ static int ixgbe_resume(struct pci_dev *pdev)
return err;
}
- ixgbe_napi_add_all(adapter);
ixgbe_reset(adapter);
if (netif_running(netdev)) {
@@ -3271,6 +3617,9 @@ static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 ctrl, fctrl;
+ u32 wufc = adapter->wol;
#ifdef CONFIG_PM
int retval = 0;
#endif
@@ -3293,10 +3642,35 @@ static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
retval = pci_save_state(pdev);
if (retval)
return retval;
+
#endif
+ if (wufc) {
+ ixgbe_set_rx_mode(netdev);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
+ /* turn on all-multi mode if wake on multicast is enabled */
+ if (wufc & IXGBE_WUFC_MC) {
+ fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ fctrl |= IXGBE_FCTRL_MPE;
+ IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
+ }
+
+ ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
+ ctrl |= IXGBE_CTRL_GIO_DIS;
+ IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
+
+ IXGBE_WRITE_REG(hw, IXGBE_WUFC, wufc);
+ } else {
+ IXGBE_WRITE_REG(hw, IXGBE_WUC, 0);
+ IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0);
+ }
+
+ if (wufc && hw->mac.type == ixgbe_mac_82599EB) {
+ pci_enable_wake(pdev, PCI_D3hot, 1);
+ pci_enable_wake(pdev, PCI_D3cold, 1);
+ } else {
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
+ }
ixgbe_release_hw_control(adapter);
@@ -3322,6 +3696,12 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
u64 total_mpc = 0;
u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ for (i = 0; i < 16; i++)
+ adapter->hw_rx_no_dma_resources +=
+ IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+ }
+
adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
for (i = 0; i < 8; i++) {
/* for packet buffers not used, the register should read 0 */
@@ -3329,32 +3709,55 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
missed_rx += mpc;
adapter->stats.mpc[i] += mpc;
total_mpc += adapter->stats.mpc[i];
- adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
adapter->stats.qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i));
adapter->stats.qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i));
adapter->stats.qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i));
adapter->stats.qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i));
- adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXONRXC(i));
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw,
+ IXGBE_PXONRXCNT(i));
+ adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw,
+ IXGBE_PXOFFRXCNT(i));
+ adapter->stats.qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+ } else {
+ adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw,
+ IXGBE_PXONRXC(i));
+ adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw,
+ IXGBE_PXOFFRXC(i));
+ }
adapter->stats.pxontxc[i] += IXGBE_READ_REG(hw,
IXGBE_PXONTXC(i));
- adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXOFFRXC(i));
adapter->stats.pxofftxc[i] += IXGBE_READ_REG(hw,
- IXGBE_PXOFFTXC(i));
+ IXGBE_PXOFFTXC(i));
}
adapter->stats.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC);
/* work around hardware counting issue */
adapter->stats.gprc -= missed_rx;
/* 82598 hardware only has a 32 bit counter in the high register */
- adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
- adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
- adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH);
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
+ IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */
+ adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
+ IXGBE_READ_REG(hw, IXGBE_GOTCH); /* to clear */
+ adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL);
+ IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
+ adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
+ adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
+ } else {
+ adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
+ adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
+ adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
+ adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
+ adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH);
+ }
bprc = IXGBE_READ_REG(hw, IXGBE_BPRC);
adapter->stats.bprc += bprc;
adapter->stats.mprc += IXGBE_READ_REG(hw, IXGBE_MPRC);
- adapter->stats.mprc -= bprc;
+ if (hw->mac.type == ixgbe_mac_82598EB)
+ adapter->stats.mprc -= bprc;
adapter->stats.roc += IXGBE_READ_REG(hw, IXGBE_ROC);
adapter->stats.prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64);
adapter->stats.prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127);
@@ -3363,8 +3766,6 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
adapter->stats.prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023);
adapter->stats.prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522);
adapter->stats.rlec += IXGBE_READ_REG(hw, IXGBE_RLEC);
- adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
- adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC);
adapter->stats.lxontxc += lxon;
lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
@@ -3416,17 +3817,54 @@ static void ixgbe_watchdog(unsigned long data)
/* Do the watchdog outside of interrupt context due to the lovely
* delays that some of the newer hardware requires */
if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+ u64 eics = 0;
+ int i;
+
+ for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++)
+ eics |= (1 << i);
+
/* Cause software interrupt to ensure rx rings are cleaned */
- if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
- u32 eics =
- (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1;
- IXGBE_WRITE_REG(hw, IXGBE_EICS, eics);
- } else {
- /* For legacy and MSI interrupts don't set any bits that
- * are enabled for EIAM, because this operation would
- * set *both* EIMS and EICS for any bit in EIAM */
- IXGBE_WRITE_REG(hw, IXGBE_EICS,
- (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
+ switch (hw->mac.type) {
+ case ixgbe_mac_82598EB:
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ IXGBE_WRITE_REG(hw, IXGBE_EICS, (u32)eics);
+ } else {
+ /*
+ * for legacy and MSI interrupts don't set any
+ * bits that are enabled for EIAM, because this
+ * operation would set *both* EIMS and EICS for
+ * any bit in EIAM
+ */
+ IXGBE_WRITE_REG(hw, IXGBE_EICS,
+ (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
+ }
+ break;
+ case ixgbe_mac_82599EB:
+ if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+ /*
+ * EICS(0..15) first 0-15 q vectors
+ * EICS[1] (16..31) q vectors 16-31
+ * EICS[2] (0..31) q vectors 32-63
+ */
+ IXGBE_WRITE_REG(hw, IXGBE_EICS,
+ (u32)(eics & 0xFFFF));
+ IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(1),
+ (u32)(eics & 0xFFFF0000));
+ IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(2),
+ (u32)(eics >> 32));
+ } else {
+ /*
+ * for legacy and MSI interrupts don't set any
+ * bits that are enabled for EIAM, because this
+ * operation would set *both* EIMS and EICS for
+ * any bit in EIAM
+ */
+ IXGBE_WRITE_REG(hw, IXGBE_EICS,
+ (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
+ }
+ break;
+ default:
+ break;
}
/* Reset the timer */
mod_timer(&adapter->watchdog_timer,
@@ -3437,6 +3875,55 @@ static void ixgbe_watchdog(unsigned long data)
}
/**
+ * ixgbe_multispeed_fiber_task - worker thread to configure multispeed fiber
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_multispeed_fiber_task(struct work_struct *work)
+{
+ struct ixgbe_adapter *adapter = container_of(work,
+ struct ixgbe_adapter,
+ multispeed_fiber_task);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 autoneg;
+
+ adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK;
+ if (hw->mac.ops.get_link_capabilities)
+ hw->mac.ops.get_link_capabilities(hw, &autoneg,
+ &hw->mac.autoneg);
+ if (hw->mac.ops.setup_link_speed)
+ hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
+ adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
+ adapter->flags &= ~IXGBE_FLAG_IN_SFP_LINK_TASK;
+}
+
+/**
+ * ixgbe_sfp_config_module_task - worker thread to configure a new SFP+ module
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_sfp_config_module_task(struct work_struct *work)
+{
+ struct ixgbe_adapter *adapter = container_of(work,
+ struct ixgbe_adapter,
+ sfp_config_module_task);
+ struct ixgbe_hw *hw = &adapter->hw;
+ u32 err;
+
+ adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK;
+ err = hw->phy.ops.identify_sfp(hw);
+ if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+ DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err);
+ ixgbe_down(adapter);
+ return;
+ }
+ hw->mac.ops.setup_sfp(hw);
+
+ if (!adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK)
+ /* This will also work for DA Twinax connections */
+ schedule_work(&adapter->multispeed_fiber_task);
+ adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK;
+}
+
+/**
* ixgbe_watchdog_task - worker thread to bring link up
* @work: pointer to work_struct containing our data
**/
@@ -3466,10 +3953,20 @@ static void ixgbe_watchdog_task(struct work_struct *work)
if (link_up) {
if (!netif_carrier_ok(netdev)) {
- u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
- u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
-#define FLOW_RX (frctl & IXGBE_FCTRL_RFCE)
-#define FLOW_TX (rmcs & IXGBE_RMCS_TFCE_802_3X)
+ bool flow_rx, flow_tx;
+
+ if (hw->mac.type == ixgbe_mac_82599EB) {
+ u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+ u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
+ flow_rx = (mflcn & IXGBE_MFLCN_RFCE);
+ flow_tx = (fccfg & IXGBE_FCCFG_TFCE_802_3X);
+ } else {
+ u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
+ flow_rx = (frctl & IXGBE_FCTRL_RFCE);
+ flow_tx = (rmcs & IXGBE_RMCS_TFCE_802_3X);
+ }
+
printk(KERN_INFO "ixgbe: %s NIC Link is Up %s, "
"Flow Control: %s\n",
netdev->name,
@@ -3477,9 +3974,9 @@ static void ixgbe_watchdog_task(struct work_struct *work)
"10 Gbps" :
(link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
"1 Gbps" : "unknown speed")),
- ((FLOW_RX && FLOW_TX) ? "RX/TX" :
- (FLOW_RX ? "RX" :
- (FLOW_TX ? "TX" : "None"))));
+ ((flow_rx && flow_tx) ? "RX/TX" :
+ (flow_rx ? "RX" :
+ (flow_tx ? "TX" : "None"))));
netif_carrier_on(netdev);
} else {
@@ -3619,13 +4116,13 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
if (skb->ip_summed == CHECKSUM_PARTIAL) {
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case cpu_to_be16(ETH_P_IP):
type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
type_tucmd_mlhl |=
IXGBE_ADVTXD_TUCMD_L4T_TCP;
break;
- case __constant_htons(ETH_P_IPV6):
+ case cpu_to_be16(ETH_P_IPV6):
/* XXX what about other V6 headers?? */
if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
type_tucmd_mlhl |=
@@ -3665,32 +4162,39 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
struct sk_buff *skb, unsigned int first)
{
struct ixgbe_tx_buffer *tx_buffer_info;
- unsigned int len = skb->len;
+ unsigned int len = skb_headlen(skb);
unsigned int offset = 0, size, count = 0, i;
unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int f;
-
- len -= skb->data_len;
+ dma_addr_t *map;
i = tx_ring->next_to_use;
+ if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+ return 0;
+ }
+
+ map = skb_shinfo(skb)->dma_maps;
+
while (len) {
tx_buffer_info = &tx_ring->tx_buffer_info[i];
size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
tx_buffer_info->length = size;
- tx_buffer_info->dma = pci_map_single(adapter->pdev,
- skb->data + offset,
- size, PCI_DMA_TODEVICE);
+ tx_buffer_info->dma = map[0] + offset;
tx_buffer_info->time_stamp = jiffies;
tx_buffer_info->next_to_watch = i;
len -= size;
offset += size;
count++;
- i++;
- if (i == tx_ring->count)
- i = 0;
+
+ if (len) {
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+ }
}
for (f = 0; f < nr_frags; f++) {
@@ -3698,33 +4202,27 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
frag = &skb_shinfo(skb)->frags[f];
len = frag->size;
- offset = frag->page_offset;
+ offset = 0;
while (len) {
+ i++;
+ if (i == tx_ring->count)
+ i = 0;
+
tx_buffer_info = &tx_ring->tx_buffer_info[i];
size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
tx_buffer_info->length = size;
- tx_buffer_info->dma = pci_map_page(adapter->pdev,
- frag->page,
- offset,
- size,
- PCI_DMA_TODEVICE);
+ tx_buffer_info->dma = map[f + 1] + offset;
tx_buffer_info->time_stamp = jiffies;
tx_buffer_info->next_to_watch = i;
len -= size;
offset += size;
count++;
- i++;
- if (i == tx_ring->count)
- i = 0;
}
}
- if (i == 0)
- i = tx_ring->count - 1;
- else
- i = i - 1;
+
tx_ring->tx_buffer_info[i].skb = skb;
tx_ring->tx_buffer_info[first].next_to_watch = i;
@@ -3823,6 +4321,16 @@ static int ixgbe_maybe_stop_tx(struct net_device *netdev,
return __ixgbe_maybe_stop_tx(netdev, tx_ring, size);
}
+static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
+ return 0; /* All traffic should default to class 0 */
+
+ return skb_tx_hash(dev, skb);
+}
+
static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -3880,13 +4388,19 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
(skb->ip_summed == CHECKSUM_PARTIAL))
tx_flags |= IXGBE_TX_FLAGS_CSUM;
- ixgbe_tx_queue(adapter, tx_ring, tx_flags,
- ixgbe_tx_map(adapter, tx_ring, skb, first),
- skb->len, hdr_len);
+ count = ixgbe_tx_map(adapter, tx_ring, skb, first);
- netdev->trans_start = jiffies;
+ if (count) {
+ ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len,
+ hdr_len);
+ netdev->trans_start = jiffies;
+ ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
- ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
+ } else {
+ dev_kfree_skb_any(skb);
+ tx_ring->tx_buffer_info[first].time_stamp = 0;
+ tx_ring->next_to_use = first;
+ }
return NETDEV_TX_OK;
}
@@ -3948,30 +4462,11 @@ static void ixgbe_netpoll(struct net_device *netdev)
}
#endif
-/**
- * ixgbe_link_config - set up initial link with default speed and duplex
- * @hw: pointer to private hardware struct
- *
- * Returns 0 on success, negative on failure
- **/
-static int ixgbe_link_config(struct ixgbe_hw *hw)
-{
- u32 autoneg = IXGBE_LINK_SPEED_10GB_FULL;
-
- /* must always autoneg for both 1G and 10G link */
- hw->mac.autoneg = true;
-
- if ((hw->mac.type == ixgbe_mac_82598EB) &&
- (hw->phy.media_type == ixgbe_media_type_copper))
- autoneg = IXGBE_LINK_SPEED_82598_AUTONEG;
-
- return hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
-}
-
static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_open = ixgbe_open,
.ndo_stop = ixgbe_close,
.ndo_start_xmit = ixgbe_xmit_frame,
+ .ndo_select_queue = ixgbe_select_queue,
.ndo_get_stats = ixgbe_get_stats,
.ndo_set_rx_mode = ixgbe_set_rx_mode,
.ndo_set_multicast_list = ixgbe_set_rx_mode,
@@ -4007,7 +4502,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];
static int cards_found;
int i, err, pci_using_dac;
- u16 link_status, link_speed, link_width;
+ u16 pm_value = 0;
u32 part_num, eec;
err = pci_enable_device(pdev);
@@ -4106,6 +4601,13 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
INIT_WORK(&adapter->sfp_task, ixgbe_sfp_task);
+ /* multispeed fiber has its own tasklet, called from GPI SDP1 context */
+ INIT_WORK(&adapter->multispeed_fiber_task, ixgbe_multispeed_fiber_task);
+
+ /* a new SFP+ module arrival, called from GPI SDP2 context */
+ INIT_WORK(&adapter->sfp_config_module_task,
+ ixgbe_sfp_config_module_task);
+
err = ii->get_invariants(hw);
if (err == IXGBE_ERR_SFP_NOT_PRESENT) {
/* start a kernel thread to watch for a module to arrive */
@@ -4142,7 +4644,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_IPV6_CSUM;
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
- netdev->features |= NETIF_F_LRO;
+ netdev->features |= NETIF_F_GRO;
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_TSO6;
@@ -4186,26 +4688,41 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (err)
goto err_sw_init;
+ switch (pdev->device) {
+ case IXGBE_DEV_ID_82599_KX4:
+#define IXGBE_PCIE_PMCSR 0x44
+ adapter->wol = IXGBE_WUFC_MAG;
+ pci_read_config_word(pdev, IXGBE_PCIE_PMCSR, &pm_value);
+ pci_write_config_word(pdev, IXGBE_PCIE_PMCSR,
+ (pm_value | (1 << 8)));
+ break;
+ default:
+ adapter->wol = 0;
+ break;
+ }
+ device_init_wakeup(&adapter->pdev->dev, true);
+ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
/* print bus type/speed/width info */
- pci_read_config_word(pdev, IXGBE_PCI_LINK_STATUS, &link_status);
- link_speed = link_status & IXGBE_PCI_LINK_SPEED;
- link_width = link_status & IXGBE_PCI_LINK_WIDTH;
dev_info(&pdev->dev, "(PCI Express:%s:%s) %pM\n",
- ((link_speed == IXGBE_PCI_LINK_SPEED_5000) ? "5.0Gb/s" :
- (link_speed == IXGBE_PCI_LINK_SPEED_2500) ? "2.5Gb/s" :
- "Unknown"),
- ((link_width == IXGBE_PCI_LINK_WIDTH_8) ? "Width x8" :
- (link_width == IXGBE_PCI_LINK_WIDTH_4) ? "Width x4" :
- (link_width == IXGBE_PCI_LINK_WIDTH_2) ? "Width x2" :
- (link_width == IXGBE_PCI_LINK_WIDTH_1) ? "Width x1" :
+ ((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s":
+ (hw->bus.speed == ixgbe_bus_speed_2500) ? "2.5Gb/s":"Unknown"),
+ ((hw->bus.width == ixgbe_bus_width_pcie_x8) ? "Width x8" :
+ (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "Width x4" :
+ (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" :
"Unknown"),
netdev->dev_addr);
ixgbe_read_pba_num_generic(hw, &part_num);
- dev_info(&pdev->dev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
- hw->mac.type, hw->phy.type,
- (part_num >> 8), (part_num & 0xff));
+ if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present)
+ dev_info(&pdev->dev, "MAC: %d, PHY: %d, SFP+: %d, PBA No: %06x-%03x\n",
+ hw->mac.type, hw->phy.type, hw->phy.sfp_type,
+ (part_num >> 8), (part_num & 0xff));
+ else
+ dev_info(&pdev->dev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
+ hw->mac.type, hw->phy.type,
+ (part_num >> 8), (part_num & 0xff));
- if (link_width <= IXGBE_PCI_LINK_WIDTH_4) {
+ if (hw->bus.width <= ixgbe_bus_width_pcie_x4) {
dev_warn(&pdev->dev, "PCI-Express bandwidth available for "
"this card is not sufficient for optimal "
"performance.\n");
@@ -4213,16 +4730,12 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
"PCI-Express slot is required.\n");
}
+ /* save off EEPROM version number */
+ hw->eeprom.ops.read(hw, 0x29, &adapter->eeprom_version);
+
/* reset the hardware with the new settings */
hw->mac.ops.start_hw(hw);
- /* link_config depends on start_hw being called at least once */
- err = ixgbe_link_config(hw);
- if (err) {
- dev_err(&pdev->dev, "setup_link_speed FAILED %d\n", err);
- goto err_register;
- }
-
netif_carrier_off(netdev);
strcpy(netdev->name, "eth%d");
@@ -4253,6 +4766,8 @@ err_eeprom:
clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
del_timer_sync(&adapter->sfp_timer);
cancel_work_sync(&adapter->sfp_task);
+ cancel_work_sync(&adapter->multispeed_fiber_task);
+ cancel_work_sync(&adapter->sfp_config_module_task);
iounmap(hw->hw_addr);
err_ioremap:
free_netdev(netdev);
@@ -4289,6 +4804,8 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
del_timer_sync(&adapter->sfp_timer);
cancel_work_sync(&adapter->watchdog_task);
cancel_work_sync(&adapter->sfp_task);
+ cancel_work_sync(&adapter->multispeed_fiber_task);
+ cancel_work_sync(&adapter->sfp_config_module_task);
flush_scheduled_work();
#ifdef CONFIG_IXGBE_DCA
@@ -4372,7 +4889,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
pci_enable_wake(pdev, PCI_D3cold, 0);
ixgbe_reset(adapter);
-
+ IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
result = PCI_ERS_RESULT_RECOVERED;
}
@@ -4476,8 +4993,20 @@ static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event,
return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
}
+
#endif /* CONFIG_IXGBE_DCA */
+#ifdef DEBUG
+/**
+ * ixgbe_get_hw_dev_name - return device name string
+ * used by hardware layer to print debugging information
+ **/
+char *ixgbe_get_hw_dev_name(struct ixgbe_hw *hw)
+{
+ struct ixgbe_adapter *adapter = hw->back;
+ return adapter->netdev->name;
+}
+#endif
module_exit(ixgbe_exit_module);
/* ixgbe_main.c */
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index 5a8669aedf64..14e9606aa3b3 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -32,6 +32,18 @@
#include "ixgbe_common.h"
#include "ixgbe_phy.h"
+static void ixgbe_i2c_start(struct ixgbe_hw *hw);
+static void ixgbe_i2c_stop(struct ixgbe_hw *hw);
+static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data);
+static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data);
+static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw);
+static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data);
+static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data);
+static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
+static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
+static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
+static bool ixgbe_get_i2c_data(u32 *i2cctl);
+static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw);
static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
@@ -543,8 +555,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
u8 identifier = 0;
u8 comp_codes_1g = 0;
u8 comp_codes_10g = 0;
- u8 oui_bytes[4] = {0, 0, 0, 0};
+ u8 oui_bytes[3] = {0, 0, 0};
u8 transmission_media = 0;
+ u16 enforce_sfp = 0;
status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
&identifier);
@@ -564,18 +577,48 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
/* ID Module
* =========
- * 0 SFP_DA_CU
- * 1 SFP_SR
- * 2 SFP_LR
+ * 0 SFP_DA_CU
+ * 1 SFP_SR
+ * 2 SFP_LR
+ * 3 SFP_DA_CORE0 - 82599-specific
+ * 4 SFP_DA_CORE1 - 82599-specific
+ * 5 SFP_SR/LR_CORE0 - 82599-specific
+ * 6 SFP_SR/LR_CORE1 - 82599-specific
*/
- if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
- hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
- else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
- hw->phy.sfp_type = ixgbe_sfp_type_sr;
- else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
- hw->phy.sfp_type = ixgbe_sfp_type_lr;
- else
- hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+ if (hw->mac.type == ixgbe_mac_82598EB) {
+ if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
+ hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
+ else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+ hw->phy.sfp_type = ixgbe_sfp_type_sr;
+ else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+ hw->phy.sfp_type = ixgbe_sfp_type_lr;
+ else
+ hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+ } else if (hw->mac.type == ixgbe_mac_82599EB) {
+ if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_da_cu_core0;
+ else
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_da_cu_core1;
+ else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_srlr_core0;
+ else
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_srlr_core1;
+ else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_srlr_core0;
+ else
+ hw->phy.sfp_type =
+ ixgbe_sfp_type_srlr_core1;
+ else
+ hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+ }
/* Determine PHY vendor */
if (hw->phy.type == ixgbe_phy_unknown) {
@@ -607,6 +650,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
case IXGBE_SFF_VENDOR_OUI_AVAGO:
hw->phy.type = ixgbe_phy_sfp_avago;
break;
+ case IXGBE_SFF_VENDOR_OUI_INTEL:
+ hw->phy.type = ixgbe_phy_sfp_intel;
+ break;
default:
if (transmission_media &
IXGBE_SFF_TWIN_AX_CAPABLE)
@@ -616,7 +662,28 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
break;
}
}
- status = 0;
+ if (hw->mac.type == ixgbe_mac_82598EB ||
+ (hw->phy.sfp_type != ixgbe_sfp_type_sr &&
+ hw->phy.sfp_type != ixgbe_sfp_type_lr &&
+ hw->phy.sfp_type != ixgbe_sfp_type_srlr_core0 &&
+ hw->phy.sfp_type != ixgbe_sfp_type_srlr_core1)) {
+ status = 0;
+ goto out;
+ }
+
+ hw->eeprom.ops.read(hw, IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET,
+ &enforce_sfp);
+ if (!(enforce_sfp & IXGBE_PHY_ALLOW_ANY_SFP)) {
+ /* Make sure we're a supported PHY type */
+ if (hw->phy.type == ixgbe_phy_sfp_intel) {
+ status = 0;
+ } else {
+ hw_dbg(hw, "SFP+ module not supported\n");
+ status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+ }
+ } else {
+ status = 0;
+ }
}
out:
@@ -651,7 +718,7 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset);
if ((!*list_offset) || (*list_offset == 0xFFFF))
- return IXGBE_ERR_PHY;
+ return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT;
/* Shift offset to first ID word */
(*list_offset)++;
@@ -688,6 +755,501 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
}
/**
+ * ixgbe_read_i2c_eeprom_generic - Reads 8 bit EEPROM word over I2C interface
+ * @hw: pointer to hardware structure
+ * @byte_offset: EEPROM byte offset to read
+ * @eeprom_data: value read
+ *
+ * Performs byte read operation to SFP module's EEPROM over I2C interface.
+ **/
+s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *eeprom_data)
+{
+ return hw->phy.ops.read_i2c_byte(hw, byte_offset,
+ IXGBE_I2C_EEPROM_DEV_ADDR,
+ eeprom_data);
+}
+
+/**
+ * ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
+ * @hw: pointer to hardware structure
+ * @byte_offset: EEPROM byte offset to write
+ * @eeprom_data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface.
+ **/
+s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 eeprom_data)
+{
+ return hw->phy.ops.write_i2c_byte(hw, byte_offset,
+ IXGBE_I2C_EEPROM_DEV_ADDR,
+ eeprom_data);
+}
+
+/**
+ * ixgbe_read_i2c_byte_generic - Reads 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to read
+ * @data: value read
+ *
+ * Performs byte read operation to SFP module's EEPROM over I2C interface at
+ * a specified deivce address.
+ **/
+s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data)
+{
+ s32 status = 0;
+ u32 max_retry = 1;
+ u32 retry = 0;
+ bool nack = 1;
+
+ do {
+ ixgbe_i2c_start(hw);
+
+ /* Device Address and write indication */
+ status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_get_i2c_ack(hw);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_get_i2c_ack(hw);
+ if (status != 0)
+ goto fail;
+
+ ixgbe_i2c_start(hw);
+
+ /* Device Address and read indication */
+ status = ixgbe_clock_out_i2c_byte(hw, (dev_addr | 0x1));
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_get_i2c_ack(hw);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_clock_in_i2c_byte(hw, data);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_clock_out_i2c_bit(hw, nack);
+ if (status != 0)
+ goto fail;
+
+ ixgbe_i2c_stop(hw);
+ break;
+
+fail:
+ ixgbe_i2c_bus_clear(hw);
+ retry++;
+ if (retry < max_retry)
+ hw_dbg(hw, "I2C byte read error - Retrying.\n");
+ else
+ hw_dbg(hw, "I2C byte read error.\n");
+
+ } while (retry < max_retry);
+
+ return status;
+}
+
+/**
+ * ixgbe_write_i2c_byte_generic - Writes 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to write
+ * @data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface at
+ * a specified device address.
+ **/
+s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data)
+{
+ s32 status = 0;
+ u32 max_retry = 1;
+ u32 retry = 0;
+
+ do {
+ ixgbe_i2c_start(hw);
+
+ status = ixgbe_clock_out_i2c_byte(hw, dev_addr);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_get_i2c_ack(hw);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_clock_out_i2c_byte(hw, byte_offset);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_get_i2c_ack(hw);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_clock_out_i2c_byte(hw, data);
+ if (status != 0)
+ goto fail;
+
+ status = ixgbe_get_i2c_ack(hw);
+ if (status != 0)
+ goto fail;
+
+ ixgbe_i2c_stop(hw);
+ break;
+
+fail:
+ ixgbe_i2c_bus_clear(hw);
+ retry++;
+ if (retry < max_retry)
+ hw_dbg(hw, "I2C byte write error - Retrying.\n");
+ else
+ hw_dbg(hw, "I2C byte write error.\n");
+ } while (retry < max_retry);
+
+ return status;
+}
+
+/**
+ * ixgbe_i2c_start - Sets I2C start condition
+ * @hw: pointer to hardware structure
+ *
+ * Sets I2C start condition (High -> Low on SDA while SCL is High)
+ **/
+static void ixgbe_i2c_start(struct ixgbe_hw *hw)
+{
+ u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+ /* Start condition must begin with data and clock high */
+ ixgbe_set_i2c_data(hw, &i2cctl, 1);
+ ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+ /* Setup time for start condition (4.7us) */
+ udelay(IXGBE_I2C_T_SU_STA);
+
+ ixgbe_set_i2c_data(hw, &i2cctl, 0);
+
+ /* Hold time for start condition (4us) */
+ udelay(IXGBE_I2C_T_HD_STA);
+
+ ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+ /* Minimum low period of clock is 4.7 us */
+ udelay(IXGBE_I2C_T_LOW);
+
+}
+
+/**
+ * ixgbe_i2c_stop - Sets I2C stop condition
+ * @hw: pointer to hardware structure
+ *
+ * Sets I2C stop condition (Low -> High on SDA while SCL is High)
+ **/
+static void ixgbe_i2c_stop(struct ixgbe_hw *hw)
+{
+ u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+ /* Stop condition must begin with data low and clock high */
+ ixgbe_set_i2c_data(hw, &i2cctl, 0);
+ ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+ /* Setup time for stop condition (4us) */
+ udelay(IXGBE_I2C_T_SU_STO);
+
+ ixgbe_set_i2c_data(hw, &i2cctl, 1);
+
+ /* bus free time between stop and start (4.7us)*/
+ udelay(IXGBE_I2C_T_BUF);
+}
+
+/**
+ * ixgbe_clock_in_i2c_byte - Clocks in one byte via I2C
+ * @hw: pointer to hardware structure
+ * @data: data byte to clock in
+ *
+ * Clocks in one byte data via I2C data/clock
+ **/
+static s32 ixgbe_clock_in_i2c_byte(struct ixgbe_hw *hw, u8 *data)
+{
+ s32 status = 0;
+ s32 i;
+ bool bit = 0;
+
+ for (i = 7; i >= 0; i--) {
+ status = ixgbe_clock_in_i2c_bit(hw, &bit);
+ *data |= bit << i;
+
+ if (status != 0)
+ break;
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_clock_out_i2c_byte - Clocks out one byte via I2C
+ * @hw: pointer to hardware structure
+ * @data: data byte clocked out
+ *
+ * Clocks out one byte data via I2C data/clock
+ **/
+static s32 ixgbe_clock_out_i2c_byte(struct ixgbe_hw *hw, u8 data)
+{
+ s32 status = 0;
+ s32 i;
+ u32 i2cctl;
+ bool bit = 0;
+
+ for (i = 7; i >= 0; i--) {
+ bit = (data >> i) & 0x1;
+ status = ixgbe_clock_out_i2c_bit(hw, bit);
+
+ if (status != 0)
+ break;
+ }
+
+ /* Release SDA line (set high) */
+ i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+ i2cctl |= IXGBE_I2C_DATA_OUT;
+ IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, i2cctl);
+
+ return status;
+}
+
+/**
+ * ixgbe_get_i2c_ack - Polls for I2C ACK
+ * @hw: pointer to hardware structure
+ *
+ * Clocks in/out one bit via I2C data/clock
+ **/
+static s32 ixgbe_get_i2c_ack(struct ixgbe_hw *hw)
+{
+ s32 status;
+ u32 i = 0;
+ u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+ u32 timeout = 10;
+ bool ack = 1;
+
+ status = ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+ if (status != 0)
+ goto out;
+
+ /* Minimum high period of clock is 4us */
+ udelay(IXGBE_I2C_T_HIGH);
+
+ /* Poll for ACK. Note that ACK in I2C spec is
+ * transition from 1 to 0 */
+ for (i = 0; i < timeout; i++) {
+ i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+ ack = ixgbe_get_i2c_data(&i2cctl);
+
+ udelay(1);
+ if (ack == 0)
+ break;
+ }
+
+ if (ack == 1) {
+ hw_dbg(hw, "I2C ack was not received.\n");
+ status = IXGBE_ERR_I2C;
+ }
+
+ ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+ /* Minimum low period of clock is 4.7 us */
+ udelay(IXGBE_I2C_T_LOW);
+
+out:
+ return status;
+}
+
+/**
+ * ixgbe_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
+ * @hw: pointer to hardware structure
+ * @data: read data value
+ *
+ * Clocks in one bit via I2C data/clock
+ **/
+static s32 ixgbe_clock_in_i2c_bit(struct ixgbe_hw *hw, bool *data)
+{
+ s32 status;
+ u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+ status = ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+ /* Minimum high period of clock is 4us */
+ udelay(IXGBE_I2C_T_HIGH);
+
+ i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+ *data = ixgbe_get_i2c_data(&i2cctl);
+
+ ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+ /* Minimum low period of clock is 4.7 us */
+ udelay(IXGBE_I2C_T_LOW);
+
+ return status;
+}
+
+/**
+ * ixgbe_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
+ * @hw: pointer to hardware structure
+ * @data: data value to write
+ *
+ * Clocks out one bit via I2C data/clock
+ **/
+static s32 ixgbe_clock_out_i2c_bit(struct ixgbe_hw *hw, bool data)
+{
+ s32 status;
+ u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+
+ status = ixgbe_set_i2c_data(hw, &i2cctl, data);
+ if (status == 0) {
+ status = ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+ /* Minimum high period of clock is 4us */
+ udelay(IXGBE_I2C_T_HIGH);
+
+ ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+ /* Minimum low period of clock is 4.7 us.
+ * This also takes care of the data hold time.
+ */
+ udelay(IXGBE_I2C_T_LOW);
+ } else {
+ status = IXGBE_ERR_I2C;
+ hw_dbg(hw, "I2C data was not set to %X\n", data);
+ }
+
+ return status;
+}
+/**
+ * ixgbe_raise_i2c_clk - Raises the I2C SCL clock
+ * @hw: pointer to hardware structure
+ * @i2cctl: Current value of I2CCTL register
+ *
+ * Raises the I2C clock line '0'->'1'
+ **/
+static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
+{
+ s32 status = 0;
+
+ *i2cctl |= IXGBE_I2C_CLK_OUT;
+
+ IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+
+ /* SCL rise time (1000ns) */
+ udelay(IXGBE_I2C_T_RISE);
+
+ return status;
+}
+
+/**
+ * ixgbe_lower_i2c_clk - Lowers the I2C SCL clock
+ * @hw: pointer to hardware structure
+ * @i2cctl: Current value of I2CCTL register
+ *
+ * Lowers the I2C clock line '1'->'0'
+ **/
+static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl)
+{
+
+ *i2cctl &= ~IXGBE_I2C_CLK_OUT;
+
+ IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+
+ /* SCL fall time (300ns) */
+ udelay(IXGBE_I2C_T_FALL);
+}
+
+/**
+ * ixgbe_set_i2c_data - Sets the I2C data bit
+ * @hw: pointer to hardware structure
+ * @i2cctl: Current value of I2CCTL register
+ * @data: I2C data value (0 or 1) to set
+ *
+ * Sets the I2C data bit
+ **/
+static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data)
+{
+ s32 status = 0;
+
+ if (data)
+ *i2cctl |= IXGBE_I2C_DATA_OUT;
+ else
+ *i2cctl &= ~IXGBE_I2C_DATA_OUT;
+
+ IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl);
+
+ /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
+ udelay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA);
+
+ /* Verify data was set correctly */
+ *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+ if (data != ixgbe_get_i2c_data(i2cctl)) {
+ status = IXGBE_ERR_I2C;
+ hw_dbg(hw, "Error - I2C data was not set to %X.\n", data);
+ }
+
+ return status;
+}
+
+/**
+ * ixgbe_get_i2c_data - Reads the I2C SDA data bit
+ * @hw: pointer to hardware structure
+ * @i2cctl: Current value of I2CCTL register
+ *
+ * Returns the I2C data bit value
+ **/
+static bool ixgbe_get_i2c_data(u32 *i2cctl)
+{
+ bool data;
+
+ if (*i2cctl & IXGBE_I2C_DATA_IN)
+ data = 1;
+ else
+ data = 0;
+
+ return data;
+}
+
+/**
+ * ixgbe_i2c_bus_clear - Clears the I2C bus
+ * @hw: pointer to hardware structure
+ *
+ * Clears the I2C bus by sending nine clock pulses.
+ * Used when data line is stuck low.
+ **/
+static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw)
+{
+ u32 i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL);
+ u32 i;
+
+ ixgbe_set_i2c_data(hw, &i2cctl, 1);
+
+ for (i = 0; i < 9; i++) {
+ ixgbe_raise_i2c_clk(hw, &i2cctl);
+
+ /* Min high period of clock is 4us */
+ udelay(IXGBE_I2C_T_HIGH);
+
+ ixgbe_lower_i2c_clk(hw, &i2cctl);
+
+ /* Min low period of clock is 4.7us*/
+ udelay(IXGBE_I2C_T_LOW);
+ }
+
+ /* Put the i2c bus back to default state */
+ ixgbe_i2c_stop(hw);
+}
+
+/**
* ixgbe_check_phy_link_tnx - Determine link and speed status
* @hw: pointer to hardware structure
*
diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h
index 43a97bc420f5..cc5f1b3287e1 100644
--- a/drivers/net/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ixgbe/ixgbe_phy.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -54,14 +54,15 @@
#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3
/* Bit-shift macros */
-#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 12
-#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 8
-#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT 4
+#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 24
+#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 16
+#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT 8
/* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */
#define IXGBE_SFF_VENDOR_OUI_TYCO 0x00407600
#define IXGBE_SFF_VENDOR_OUI_FTL 0x00906500
#define IXGBE_SFF_VENDOR_OUI_AVAGO 0x00176A00
+#define IXGBE_SFF_VENDOR_OUI_INTEL 0x001B2100
/* I2C SDA and SCL timing parameters for standard mode */
#define IXGBE_I2C_T_HD_STA 4
@@ -101,5 +102,12 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw);
s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw,
u16 *list_offset,
u16 *data_offset);
-
+s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data);
+s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data);
+s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 *eeprom_data);
+s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
+ u8 eeprom_data);
#endif /* _IXGBE_PHY_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index f011c57c9205..030ff0a9ea67 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -1,7 +1,7 @@
/*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver
- Copyright(c) 1999 - 2008 Intel Corporation.
+ Copyright(c) 1999 - 2009 Intel Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
@@ -34,6 +34,8 @@
#define IXGBE_INTEL_VENDOR_ID 0x8086
/* Device IDs */
+#define IXGBE_DEV_ID_82598 0x10B6
+#define IXGBE_DEV_ID_82598_BX 0x1508
#define IXGBE_DEV_ID_82598AF_DUAL_PORT 0x10C6
#define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
#define IXGBE_DEV_ID_82598EB_SFP_LOM 0x10DB
@@ -43,6 +45,9 @@
#define IXGBE_DEV_ID_82598_DA_DUAL_PORT 0x10F1
#define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM 0x10E1
#define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4
+#define IXGBE_DEV_ID_82599 0x10D8
+#define IXGBE_DEV_ID_82599_KX4 0x10F7
+#define IXGBE_DEV_ID_82599_SFP 0x10FB
/* General Registers */
#define IXGBE_CTRL 0x00000
@@ -50,9 +55,12 @@
#define IXGBE_CTRL_EXT 0x00018
#define IXGBE_ESDP 0x00020
#define IXGBE_EODSDP 0x00028
+#define IXGBE_I2CCTL 0x00028
#define IXGBE_LEDCTL 0x00200
#define IXGBE_FRTIMER 0x00048
#define IXGBE_TCPTIMER 0x0004C
+#define IXGBE_CORESPARE 0x00600
+#define IXGBE_EXVET 0x05078
/* NVM Registers */
#define IXGBE_EEC 0x10010
@@ -66,6 +74,19 @@
#define IXGBE_FLOP 0x1013C
#define IXGBE_GRC 0x10200
+/* General Receive Control */
+#define IXGBE_GRC_MNG 0x00000001 /* Manageability Enable */
+#define IXGBE_GRC_APME 0x00000002 /* Advanced Power Management Enable */
+
+#define IXGBE_VPDDIAG0 0x10204
+#define IXGBE_VPDDIAG1 0x10208
+
+/* I2CCTL Bit Masks */
+#define IXGBE_I2C_CLK_IN 0x00000001
+#define IXGBE_I2C_CLK_OUT 0x00000002
+#define IXGBE_I2C_DATA_IN 0x00000004
+#define IXGBE_I2C_DATA_OUT 0x00000008
+
/* Interrupt Registers */
#define IXGBE_EICR 0x00800
#define IXGBE_EICS 0x00808
@@ -73,28 +94,63 @@
#define IXGBE_EIMC 0x00888
#define IXGBE_EIAC 0x00810
#define IXGBE_EIAM 0x00890
-#define IXGBE_EITR(_i) (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : (0x012300 + ((_i) * 4)))
+#define IXGBE_EICS_EX(_i) (0x00A90 + (_i) * 4)
+#define IXGBE_EIMS_EX(_i) (0x00AA0 + (_i) * 4)
+#define IXGBE_EIMC_EX(_i) (0x00AB0 + (_i) * 4)
+#define IXGBE_EIAM_EX(_i) (0x00AD0 + (_i) * 4)
+/*
+ * 82598 EITR is 16 bits but set the limits based on the max
+ * supported by all ixgbe hardware. 82599 EITR is only 12 bits,
+ * with the lower 3 always zero.
+ */
+#define IXGBE_MAX_INT_RATE 488281
+#define IXGBE_MIN_INT_RATE 956
+#define IXGBE_MAX_EITR 0x00000FF8
+#define IXGBE_MIN_EITR 8
+#define IXGBE_EITR(_i) (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : \
+ (0x012300 + (((_i) - 24) * 4)))
+#define IXGBE_EITR_ITR_INT_MASK 0x00000FF8
+#define IXGBE_EITR_LLI_MOD 0x00008000
+#define IXGBE_EITR_CNT_WDIS 0x80000000
#define IXGBE_IVAR(_i) (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */
+#define IXGBE_IVAR_MISC 0x00A00 /* misc MSI-X interrupt causes */
+#define IXGBE_EITRSEL 0x00894
#define IXGBE_MSIXT 0x00000 /* MSI-X Table. 0x0000 - 0x01C */
#define IXGBE_MSIXPBA 0x02000 /* MSI-X Pending bit array */
#define IXGBE_PBACL(_i) (((_i) == 0) ? (0x11068) : (0x110C0 + ((_i) * 4)))
#define IXGBE_GPIE 0x00898
/* Flow Control Registers */
+#define IXGBE_FCADBUL 0x03210
+#define IXGBE_FCADBUH 0x03214
+#define IXGBE_FCAMACL 0x04328
+#define IXGBE_FCAMACH 0x0432C
+#define IXGBE_FCRTH_82599(_i) (0x03260 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_FCRTL_82599(_i) (0x03220 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_PFCTOP 0x03008
#define IXGBE_FCTTV(_i) (0x03200 + ((_i) * 4)) /* 4 of these (0-3) */
#define IXGBE_FCRTL(_i) (0x03220 + ((_i) * 8)) /* 8 of these (0-7) */
#define IXGBE_FCRTH(_i) (0x03260 + ((_i) * 8)) /* 8 of these (0-7) */
#define IXGBE_FCRTV 0x032A0
+#define IXGBE_FCCFG 0x03D00
#define IXGBE_TFCS 0x0CE00
/* Receive DMA Registers */
-#define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : (0x0D000 + ((_i - 64) * 0x40)))
-#define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : (0x0D004 + ((_i - 64) * 0x40)))
-#define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : (0x0D008 + ((_i - 64) * 0x40)))
-#define IXGBE_RDH(_i) (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : (0x0D010 + ((_i - 64) * 0x40)))
-#define IXGBE_RDT(_i) (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : (0x0D018 + ((_i - 64) * 0x40)))
-#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : (0x0D028 + ((_i - 64) * 0x40)))
+#define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : \
+ (0x0D000 + ((_i - 64) * 0x40)))
+#define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : \
+ (0x0D004 + ((_i - 64) * 0x40)))
+#define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : \
+ (0x0D008 + ((_i - 64) * 0x40)))
+#define IXGBE_RDH(_i) (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : \
+ (0x0D010 + ((_i - 64) * 0x40)))
+#define IXGBE_RDT(_i) (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : \
+ (0x0D018 + ((_i - 64) * 0x40)))
+#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : \
+ (0x0D028 + ((_i - 64) * 0x40)))
+#define IXGBE_RDDCC 0x02F20
+#define IXGBE_RXMEMWRAP 0x03190
+#define IXGBE_STARCTRL 0x03024
/*
* Split and Replication Receive Control Registers
* 00-15 : 0x02100 + n*4
@@ -127,10 +183,15 @@
#define IXGBE_DRECCCTL_DISABLE 0
/* Multicast Table Array - 128 entries */
#define IXGBE_MTA(_i) (0x05200 + ((_i) * 4))
-#define IXGBE_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : (0x0A200 + ((_i) * 8)))
-#define IXGBE_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : (0x0A204 + ((_i) * 8)))
+#define IXGBE_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
+ (0x0A200 + ((_i) * 8)))
+#define IXGBE_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
+ (0x0A204 + ((_i) * 8)))
+#define IXGBE_MPSAR_LO(_i) (0x0A600 + ((_i) * 8))
+#define IXGBE_MPSAR_HI(_i) (0x0A604 + ((_i) * 8))
/* Packet split receive type */
-#define IXGBE_PSRTYPE(_i) (((_i) <= 15) ? (0x05480 + ((_i) * 4)) : (0x0EA00 + ((_i) * 4)))
+#define IXGBE_PSRTYPE(_i) (((_i) <= 15) ? (0x05480 + ((_i) * 4)) : \
+ (0x0EA00 + ((_i) * 4)))
/* array of 4096 1-bit vlan filters */
#define IXGBE_VFTA(_i) (0x0A000 + ((_i) * 4))
/*array of 4096 4-bit vlan vmdq indices */
@@ -139,6 +200,28 @@
#define IXGBE_VLNCTRL 0x05088
#define IXGBE_MCSTCTRL 0x05090
#define IXGBE_MRQC 0x05818
+#define IXGBE_SAQF(_i) (0x0E000 + ((_i) * 4)) /* Source Address Queue Filter */
+#define IXGBE_DAQF(_i) (0x0E200 + ((_i) * 4)) /* Dest. Address Queue Filter */
+#define IXGBE_SDPQF(_i) (0x0E400 + ((_i) * 4)) /* Src Dest. Addr Queue Filter */
+#define IXGBE_FTQF(_i) (0x0E600 + ((_i) * 4)) /* Five Tuple Queue Filter */
+#define IXGBE_ETQF(_i) (0x05128 + ((_i) * 4)) /* EType Queue Filter */
+#define IXGBE_ETQS(_i) (0x0EC00 + ((_i) * 4)) /* EType Queue Select */
+#define IXGBE_SYNQF 0x0EC30 /* SYN Packet Queue Filter */
+#define IXGBE_RQTC 0x0EC70
+#define IXGBE_MTQC 0x08120
+#define IXGBE_VLVF(_i) (0x0F100 + ((_i) * 4)) /* 64 of these (0-63) */
+#define IXGBE_VLVFB(_i) (0x0F200 + ((_i) * 4)) /* 128 of these (0-127) */
+#define IXGBE_VT_CTL 0x051B0
+#define IXGBE_VFRE(_i) (0x051E0 + ((_i) * 4))
+#define IXGBE_VFTE(_i) (0x08110 + ((_i) * 4))
+#define IXGBE_QDE 0x2F04
+#define IXGBE_VMOLR(_i) (0x0F000 + ((_i) * 4)) /* 64 total */
+#define IXGBE_UTA(_i) (0x0F400 + ((_i) * 4))
+#define IXGBE_VMRCTL(_i) (0x0F600 + ((_i) * 4))
+#define IXGBE_VMRVLAN(_i) (0x0F610 + ((_i) * 4))
+#define IXGBE_VMRVM(_i) (0x0F630 + ((_i) * 4))
+#define IXGBE_L34T_IMIR(_i) (0x0E800 + ((_i) * 4)) /*128 of these (0-127)*/
+#define IXGBE_LLITHRESH 0x0EC90
#define IXGBE_IMIR(_i) (0x05A80 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* 8 of these (0-7) */
#define IXGBE_IMIRVP 0x05AC0
@@ -146,7 +229,6 @@
#define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */
#define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */
-
/* Transmit DMA registers */
#define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40)) /* 32 of these (0-31)*/
#define IXGBE_TDBAH(_i) (0x06004 + ((_i) * 0x40))
@@ -158,7 +240,20 @@
#define IXGBE_TDWBAH(_i) (0x0603C + ((_i) * 0x40))
#define IXGBE_DTXCTL 0x07E00
+#define IXGBE_DMATXCTL 0x04A80
+#define IXGBE_DTXMXSZRQ 0x08100
+#define IXGBE_DTXTCPFLGL 0x04A88
+#define IXGBE_DTXTCPFLGH 0x04A8C
+#define IXGBE_LBDRPEN 0x0CA00
+#define IXGBE_TXPBTHRESH(_i) (0x04950 + ((_i) * 4)) /* 8 of these 0 - 7 */
+
+#define IXGBE_DMATXCTL_TE 0x1 /* Transmit Enable */
+#define IXGBE_DMATXCTL_NS 0x2 /* No Snoop LSO hdr buffer */
+#define IXGBE_DMATXCTL_GDV 0x8 /* Global Double VLAN */
+#define IXGBE_DMATXCTL_VT_SHIFT 16 /* VLAN EtherType */
#define IXGBE_DCA_TXCTRL(_i) (0x07200 + ((_i) * 4)) /* 16 of these (0-15) */
+/* Tx DCA Control register : 128 of these (0-127) */
+#define IXGBE_DCA_TXCTRL_82599(_i) (0x0600C + ((_i) * 0x40))
#define IXGBE_TIPG 0x0CB00
#define IXGBE_TXPBSIZE(_i) (0x0CC00 + ((_i) * 4)) /* 8 of these */
#define IXGBE_MNGTXMAP 0x0CD10
@@ -175,9 +270,69 @@
#define IXGBE_WUPL 0x05900
#define IXGBE_WUPM 0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */
-#define IXGBE_FHFT 0x09000 /* Flex host filter table 9000-93FC */
-
-/* Music registers */
+#define IXGBE_FHFT(_n) (0x09000 + (_n * 0x100)) /* Flex host filter table */
+#define IXGBE_FHFT_EXT(_n) (0x09800 + (_n * 0x100)) /* Ext Flexible Host
+ * Filter Table */
+
+#define IXGBE_FLEXIBLE_FILTER_COUNT_MAX 4
+#define IXGBE_EXT_FLEXIBLE_FILTER_COUNT_MAX 2
+
+/* Each Flexible Filter is at most 128 (0x80) bytes in length */
+#define IXGBE_FLEXIBLE_FILTER_SIZE_MAX 128
+#define IXGBE_FHFT_LENGTH_OFFSET 0xFC /* Length byte in FHFT */
+#define IXGBE_FHFT_LENGTH_MASK 0x0FF /* Length in lower byte */
+
+/* Definitions for power management and wakeup registers */
+/* Wake Up Control */
+#define IXGBE_WUC_PME_EN 0x00000002 /* PME Enable */
+#define IXGBE_WUC_PME_STATUS 0x00000004 /* PME Status */
+#define IXGBE_WUC_ADVD3WUC 0x00000010 /* D3Cold wake up cap. enable*/
+
+/* Wake Up Filter Control */
+#define IXGBE_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
+#define IXGBE_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
+#define IXGBE_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
+#define IXGBE_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */
+#define IXGBE_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
+#define IXGBE_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
+#define IXGBE_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
+#define IXGBE_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
+#define IXGBE_WUFC_MNG 0x00000100 /* Directed Mgmt Packet Wakeup Enable */
+
+#define IXGBE_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */
+#define IXGBE_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
+#define IXGBE_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
+#define IXGBE_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
+#define IXGBE_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
+#define IXGBE_WUFC_FLX4 0x00100000 /* Flexible Filter 4 Enable */
+#define IXGBE_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */
+#define IXGBE_WUFC_FLX_FILTERS 0x000F0000 /* Mask for 4 flex filters */
+#define IXGBE_WUFC_EXT_FLX_FILTERS 0x00300000 /* Mask for Ext. flex filters */
+#define IXGBE_WUFC_ALL_FILTERS 0x003F00FF /* Mask for all 6 wakeup filters*/
+#define IXGBE_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
+
+/* Wake Up Status */
+#define IXGBE_WUS_LNKC IXGBE_WUFC_LNKC
+#define IXGBE_WUS_MAG IXGBE_WUFC_MAG
+#define IXGBE_WUS_EX IXGBE_WUFC_EX
+#define IXGBE_WUS_MC IXGBE_WUFC_MC
+#define IXGBE_WUS_BC IXGBE_WUFC_BC
+#define IXGBE_WUS_ARP IXGBE_WUFC_ARP
+#define IXGBE_WUS_IPV4 IXGBE_WUFC_IPV4
+#define IXGBE_WUS_IPV6 IXGBE_WUFC_IPV6
+#define IXGBE_WUS_MNG IXGBE_WUFC_MNG
+#define IXGBE_WUS_FLX0 IXGBE_WUFC_FLX0
+#define IXGBE_WUS_FLX1 IXGBE_WUFC_FLX1
+#define IXGBE_WUS_FLX2 IXGBE_WUFC_FLX2
+#define IXGBE_WUS_FLX3 IXGBE_WUFC_FLX3
+#define IXGBE_WUS_FLX4 IXGBE_WUFC_FLX4
+#define IXGBE_WUS_FLX5 IXGBE_WUFC_FLX5
+#define IXGBE_WUS_FLX_FILTERS IXGBE_WUFC_FLX_FILTERS
+
+/* Wake Up Packet Length */
+#define IXGBE_WUPL_LENGTH_MASK 0xFFFF
+
+/* DCB registers */
#define IXGBE_RMCS 0x03D00
#define IXGBE_DPMCS 0x07F40
#define IXGBE_PDPMCS 0x0CD00
@@ -190,6 +345,122 @@
#define IXGBE_TDPT2TCSR(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */
+/* Security Control Registers */
+#define IXGBE_SECTXCTRL 0x08800
+#define IXGBE_SECTXSTAT 0x08804
+#define IXGBE_SECTXBUFFAF 0x08808
+#define IXGBE_SECTXMINIFG 0x08810
+#define IXGBE_SECTXSTAT 0x08804
+#define IXGBE_SECRXCTRL 0x08D00
+#define IXGBE_SECRXSTAT 0x08D04
+
+/* Security Bit Fields and Masks */
+#define IXGBE_SECTXCTRL_SECTX_DIS 0x00000001
+#define IXGBE_SECTXCTRL_TX_DIS 0x00000002
+#define IXGBE_SECTXCTRL_STORE_FORWARD 0x00000004
+
+#define IXGBE_SECTXSTAT_SECTX_RDY 0x00000001
+#define IXGBE_SECTXSTAT_ECC_TXERR 0x00000002
+
+#define IXGBE_SECRXCTRL_SECRX_DIS 0x00000001
+#define IXGBE_SECRXCTRL_RX_DIS 0x00000002
+
+#define IXGBE_SECRXSTAT_SECRX_RDY 0x00000001
+#define IXGBE_SECRXSTAT_ECC_RXERR 0x00000002
+
+/* LinkSec (MacSec) Registers */
+#define IXGBE_LSECTXCAP 0x08A00
+#define IXGBE_LSECRXCAP 0x08F00
+#define IXGBE_LSECTXCTRL 0x08A04
+#define IXGBE_LSECTXSCL 0x08A08 /* SCI Low */
+#define IXGBE_LSECTXSCH 0x08A0C /* SCI High */
+#define IXGBE_LSECTXSA 0x08A10
+#define IXGBE_LSECTXPN0 0x08A14
+#define IXGBE_LSECTXPN1 0x08A18
+#define IXGBE_LSECTXKEY0(_n) (0x08A1C + (4 * (_n))) /* 4 of these (0-3) */
+#define IXGBE_LSECTXKEY1(_n) (0x08A2C + (4 * (_n))) /* 4 of these (0-3) */
+#define IXGBE_LSECRXCTRL 0x08F04
+#define IXGBE_LSECRXSCL 0x08F08
+#define IXGBE_LSECRXSCH 0x08F0C
+#define IXGBE_LSECRXSA(_i) (0x08F10 + (4 * (_i))) /* 2 of these (0-1) */
+#define IXGBE_LSECRXPN(_i) (0x08F18 + (4 * (_i))) /* 2 of these (0-1) */
+#define IXGBE_LSECRXKEY(_n, _m) (0x08F20 + ((0x10 * (_n)) + (4 * (_m))))
+#define IXGBE_LSECTXUT 0x08A3C /* OutPktsUntagged */
+#define IXGBE_LSECTXPKTE 0x08A40 /* OutPktsEncrypted */
+#define IXGBE_LSECTXPKTP 0x08A44 /* OutPktsProtected */
+#define IXGBE_LSECTXOCTE 0x08A48 /* OutOctetsEncrypted */
+#define IXGBE_LSECTXOCTP 0x08A4C /* OutOctetsProtected */
+#define IXGBE_LSECRXUT 0x08F40 /* InPktsUntagged/InPktsNoTag */
+#define IXGBE_LSECRXOCTD 0x08F44 /* InOctetsDecrypted */
+#define IXGBE_LSECRXOCTV 0x08F48 /* InOctetsValidated */
+#define IXGBE_LSECRXBAD 0x08F4C /* InPktsBadTag */
+#define IXGBE_LSECRXNOSCI 0x08F50 /* InPktsNoSci */
+#define IXGBE_LSECRXUNSCI 0x08F54 /* InPktsUnknownSci */
+#define IXGBE_LSECRXUNCH 0x08F58 /* InPktsUnchecked */
+#define IXGBE_LSECRXDELAY 0x08F5C /* InPktsDelayed */
+#define IXGBE_LSECRXLATE 0x08F60 /* InPktsLate */
+#define IXGBE_LSECRXOK(_n) (0x08F64 + (0x04 * (_n))) /* InPktsOk */
+#define IXGBE_LSECRXINV(_n) (0x08F6C + (0x04 * (_n))) /* InPktsInvalid */
+#define IXGBE_LSECRXNV(_n) (0x08F74 + (0x04 * (_n))) /* InPktsNotValid */
+#define IXGBE_LSECRXUNSA 0x08F7C /* InPktsUnusedSa */
+#define IXGBE_LSECRXNUSA 0x08F80 /* InPktsNotUsingSa */
+
+/* LinkSec (MacSec) Bit Fields and Masks */
+#define IXGBE_LSECTXCAP_SUM_MASK 0x00FF0000
+#define IXGBE_LSECTXCAP_SUM_SHIFT 16
+#define IXGBE_LSECRXCAP_SUM_MASK 0x00FF0000
+#define IXGBE_LSECRXCAP_SUM_SHIFT 16
+
+#define IXGBE_LSECTXCTRL_EN_MASK 0x00000003
+#define IXGBE_LSECTXCTRL_DISABLE 0x0
+#define IXGBE_LSECTXCTRL_AUTH 0x1
+#define IXGBE_LSECTXCTRL_AUTH_ENCRYPT 0x2
+#define IXGBE_LSECTXCTRL_AISCI 0x00000020
+#define IXGBE_LSECTXCTRL_PNTHRSH_MASK 0xFFFFFF00
+#define IXGBE_LSECTXCTRL_RSV_MASK 0x000000D8
+
+#define IXGBE_LSECRXCTRL_EN_MASK 0x0000000C
+#define IXGBE_LSECRXCTRL_EN_SHIFT 2
+#define IXGBE_LSECRXCTRL_DISABLE 0x0
+#define IXGBE_LSECRXCTRL_CHECK 0x1
+#define IXGBE_LSECRXCTRL_STRICT 0x2
+#define IXGBE_LSECRXCTRL_DROP 0x3
+#define IXGBE_LSECRXCTRL_PLSH 0x00000040
+#define IXGBE_LSECRXCTRL_RP 0x00000080
+#define IXGBE_LSECRXCTRL_RSV_MASK 0xFFFFFF33
+
+/* IpSec Registers */
+#define IXGBE_IPSTXIDX 0x08900
+#define IXGBE_IPSTXSALT 0x08904
+#define IXGBE_IPSTXKEY(_i) (0x08908 + (4 * (_i))) /* 4 of these (0-3) */
+#define IXGBE_IPSRXIDX 0x08E00
+#define IXGBE_IPSRXIPADDR(_i) (0x08E04 + (4 * (_i))) /* 4 of these (0-3) */
+#define IXGBE_IPSRXSPI 0x08E14
+#define IXGBE_IPSRXIPIDX 0x08E18
+#define IXGBE_IPSRXKEY(_i) (0x08E1C + (4 * (_i))) /* 4 of these (0-3) */
+#define IXGBE_IPSRXSALT 0x08E2C
+#define IXGBE_IPSRXMOD 0x08E30
+
+#define IXGBE_SECTXCTRL_STORE_FORWARD_ENABLE 0x4
+
+/* DCB registers */
+#define IXGBE_RTRPCS 0x02430
+#define IXGBE_RTTDCS 0x04900
+#define IXGBE_RTTPCS 0x0CD00
+#define IXGBE_RTRUP2TC 0x03020
+#define IXGBE_RTTUP2TC 0x0C800
+#define IXGBE_RTRPT4C(_i) (0x02140 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTRPT4S(_i) (0x02160 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTDT2C(_i) (0x04910 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTDT2S(_i) (0x04930 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTPT2C(_i) (0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTPT2S(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_RTTDQSEL 0x04904
+#define IXGBE_RTTDT1C 0x04908
+#define IXGBE_RTTDT1S 0x0490C
+#define IXGBE_RTTDTECC 0x04990
+#define IXGBE_RTTDTECC_NO_BCN 0x00000100
+#define IXGBE_RTTBCNRC 0x04984
/* Stats registers */
#define IXGBE_CRCERRS 0x04000
@@ -204,6 +475,11 @@
#define IXGBE_LXONRXC 0x0CF60
#define IXGBE_LXOFFTXC 0x03F68
#define IXGBE_LXOFFRXC 0x0CF68
+#define IXGBE_LXONRXCNT 0x041A4
+#define IXGBE_LXOFFRXCNT 0x041A8
+#define IXGBE_PXONRXCNT(_i) (0x04140 + ((_i) * 4)) /* 8 of these */
+#define IXGBE_PXOFFRXCNT(_i) (0x04160 + ((_i) * 4)) /* 8 of these */
+#define IXGBE_PXON2OFFCNT(_i) (0x03240 + ((_i) * 4)) /* 8 of these */
#define IXGBE_PXONTXC(_i) (0x03F00 + ((_i) * 4)) /* 8 of these 3F00-3F1C*/
#define IXGBE_PXONRXC(_i) (0x0CF00 + ((_i) * 4)) /* 8 of these CF00-CF1C*/
#define IXGBE_PXOFFTXC(_i) (0x03F20 + ((_i) * 4)) /* 8 of these 3F20-3F3C*/
@@ -243,14 +519,20 @@
#define IXGBE_MPTC 0x040F0
#define IXGBE_BPTC 0x040F4
#define IXGBE_XEC 0x04120
+#define IXGBE_SSVPC 0x08780
-#define IXGBE_RQSMR(_i) (0x02300 + ((_i) * 4)) /* 16 of these */
-#define IXGBE_TQSMR(_i) (((_i) <= 7) ? (0x07300 + ((_i) * 4)) : (0x08600 + ((_i) * 4)))
+#define IXGBE_RQSMR(_i) (0x02300 + ((_i) * 4))
+#define IXGBE_TQSMR(_i) (((_i) <= 7) ? (0x07300 + ((_i) * 4)) : \
+ (0x08600 + ((_i) * 4)))
+#define IXGBE_TQSM(_i) (0x08600 + ((_i) * 4))
#define IXGBE_QPRC(_i) (0x01030 + ((_i) * 0x40)) /* 16 of these */
#define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */
#define IXGBE_QBRC(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */
#define IXGBE_QBTC(_i) (0x06034 + ((_i) * 0x40)) /* 16 of these */
+#define IXGBE_QPRDC(_i) (0x01430 + ((_i) * 0x40)) /* 16 of these */
+#define IXGBE_QBTC_L(_i) (0x08700 + ((_i) * 0x8)) /* 16 of these */
+#define IXGBE_QBTC_H(_i) (0x08704 + ((_i) * 0x8)) /* 16 of these */
/* Management */
#define IXGBE_MAVTV(_i) (0x05010 + ((_i) * 4)) /* 8 of these (0-7) */
@@ -263,6 +545,9 @@
#define IXGBE_MMAL(_i) (0x05910 + ((_i) * 8)) /* 4 of these (0-3) */
#define IXGBE_MMAH(_i) (0x05914 + ((_i) * 8)) /* 4 of these (0-3) */
#define IXGBE_FTFT 0x09400 /* 0x9400-0x97FC */
+#define IXGBE_METF(_i) (0x05190 + ((_i) * 4)) /* 4 of these (0-3) */
+#define IXGBE_MDEF_EXT(_i) (0x05160 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_LSWFW 0x15014
/* ARC Subsystem registers */
#define IXGBE_HICR 0x15F00
@@ -295,16 +580,65 @@
#define IXGBE_DCA_ID 0x11070
#define IXGBE_DCA_CTRL 0x11074
+/* PCIe registers 82599-specific */
+#define IXGBE_GCR_EXT 0x11050
+#define IXGBE_GSCL_5_82599 0x11030
+#define IXGBE_GSCL_6_82599 0x11034
+#define IXGBE_GSCL_7_82599 0x11038
+#define IXGBE_GSCL_8_82599 0x1103C
+#define IXGBE_PHYADR_82599 0x11040
+#define IXGBE_PHYDAT_82599 0x11044
+#define IXGBE_PHYCTL_82599 0x11048
+#define IXGBE_PBACLR_82599 0x11068
+#define IXGBE_CIAA_82599 0x11088
+#define IXGBE_CIAD_82599 0x1108C
+#define IXGBE_PCIE_DIAG_0_82599 0x11090
+#define IXGBE_PCIE_DIAG_1_82599 0x11094
+#define IXGBE_PCIE_DIAG_2_82599 0x11098
+#define IXGBE_PCIE_DIAG_3_82599 0x1109C
+#define IXGBE_PCIE_DIAG_4_82599 0x110A0
+#define IXGBE_PCIE_DIAG_5_82599 0x110A4
+#define IXGBE_PCIE_DIAG_6_82599 0x110A8
+#define IXGBE_PCIE_DIAG_7_82599 0x110C0
+#define IXGBE_INTRPT_CSR_82599 0x110B0
+#define IXGBE_INTRPT_MASK_82599 0x110B8
+#define IXGBE_CDQ_MBR_82599 0x110B4
+#define IXGBE_MISC_REG_82599 0x110F0
+#define IXGBE_ECC_CTRL_0_82599 0x11100
+#define IXGBE_ECC_CTRL_1_82599 0x11104
+#define IXGBE_ECC_STATUS_82599 0x110E0
+#define IXGBE_BAR_CTRL_82599 0x110F4
+
+/* Time Sync Registers */
+#define IXGBE_TSYNCRXCTL 0x05188 /* Rx Time Sync Control register - RW */
+#define IXGBE_TSYNCTXCTL 0x08C00 /* Tx Time Sync Control register - RW */
+#define IXGBE_RXSTMPL 0x051E8 /* Rx timestamp Low - RO */
+#define IXGBE_RXSTMPH 0x051A4 /* Rx timestamp High - RO */
+#define IXGBE_RXSATRL 0x051A0 /* Rx timestamp attribute low - RO */
+#define IXGBE_RXSATRH 0x051A8 /* Rx timestamp attribute high - RO */
+#define IXGBE_RXMTRL 0x05120 /* RX message type register low - RW */
+#define IXGBE_TXSTMPL 0x08C04 /* Tx timestamp value Low - RO */
+#define IXGBE_TXSTMPH 0x08C08 /* Tx timestamp value High - RO */
+#define IXGBE_SYSTIML 0x08C0C /* System time register Low - RO */
+#define IXGBE_SYSTIMH 0x08C10 /* System time register High - RO */
+#define IXGBE_TIMINCA 0x08C14 /* Increment attributes register - RW */
+#define IXGBE_RXUDP 0x08C1C /* Time Sync Rx UDP Port - RW */
+
/* Diagnostic Registers */
#define IXGBE_RDSTATCTL 0x02C20
#define IXGBE_RDSTAT(_i) (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */
#define IXGBE_RDHMPN 0x02F08
#define IXGBE_RIC_DW(_i) (0x02F10 + ((_i) * 4))
#define IXGBE_RDPROBE 0x02F20
+#define IXGBE_RDMAM 0x02F30
+#define IXGBE_RDMAD 0x02F34
#define IXGBE_TDSTATCTL 0x07C20
#define IXGBE_TDSTAT(_i) (0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */
#define IXGBE_TDHMPN 0x07F08
+#define IXGBE_TDHMPN2 0x082FC
+#define IXGBE_TXDESCIC 0x082CC
#define IXGBE_TIC_DW(_i) (0x07F10 + ((_i) * 4))
+#define IXGBE_TIC_DW2(_i) (0x082B0 + ((_i) * 4))
#define IXGBE_TDPROBE 0x07F20
#define IXGBE_TXBUFCTRL 0x0C600
#define IXGBE_TXBUFDATA0 0x0C610
@@ -332,6 +666,8 @@
#define IXGBE_TXDATARDPTR(_i) (0x0C720 + ((_i) * 4)) /* 8 of these C720-C72C*/
#define IXGBE_TXDESCRDPTR(_i) (0x0C730 + ((_i) * 4)) /* 8 of these C730-C73C*/
#define IXGBE_PCIEECCCTL 0x1106C
+#define IXGBE_PCIEECCCTL0 0x11100
+#define IXGBE_PCIEECCCTL1 0x11104
#define IXGBE_PBTXECC 0x0C300
#define IXGBE_PBRXECC 0x03300
#define IXGBE_GHECCR 0x110B0
@@ -357,24 +693,61 @@
#define IXGBE_MSRWD 0x04260
#define IXGBE_MLADD 0x04264
#define IXGBE_MHADD 0x04268
+#define IXGBE_MAXFRS 0x04268
#define IXGBE_TREG 0x0426C
#define IXGBE_PCSS1 0x04288
#define IXGBE_PCSS2 0x0428C
#define IXGBE_XPCSS 0x04290
+#define IXGBE_MFLCN 0x04294
#define IXGBE_SERDESC 0x04298
#define IXGBE_MACS 0x0429C
#define IXGBE_AUTOC 0x042A0
#define IXGBE_LINKS 0x042A4
+#define IXGBE_LINKS2 0x04324
#define IXGBE_AUTOC2 0x042A8
#define IXGBE_AUTOC3 0x042AC
#define IXGBE_ANLP1 0x042B0
#define IXGBE_ANLP2 0x042B4
#define IXGBE_ATLASCTL 0x04800
+#define IXGBE_MMNGC 0x042D0
+#define IXGBE_ANLPNP1 0x042D4
+#define IXGBE_ANLPNP2 0x042D8
+#define IXGBE_KRPCSFC 0x042E0
+#define IXGBE_KRPCSS 0x042E4
+#define IXGBE_FECS1 0x042E8
+#define IXGBE_FECS2 0x042EC
+#define IXGBE_SMADARCTL 0x14F10
+#define IXGBE_MPVC 0x04318
+#define IXGBE_SGMIIC 0x04314
+
+/* Omer CORECTL */
+#define IXGBE_CORECTL 0x014F00
+/* BARCTRL */
+#define IXGBE_BARCTRL 0x110F4
+#define IXGBE_BARCTRL_FLSIZE 0x0700
+#define IXGBE_BARCTRL_CSRSIZE 0x2000
/* RDRXCTL Bit Masks */
#define IXGBE_RDRXCTL_RDMTS_1_2 0x00000000 /* Rx Desc Min Threshold Size */
+#define IXGBE_RDRXCTL_CRCSTRIP 0x00000002 /* CRC Strip */
#define IXGBE_RDRXCTL_MVMEN 0x00000020
#define IXGBE_RDRXCTL_DMAIDONE 0x00000008 /* DMA init cycle done */
+#define IXGBE_RDRXCTL_AGGDIS 0x00010000 /* Aggregation disable */
+
+/* RQTC Bit Masks and Shifts */
+#define IXGBE_RQTC_SHIFT_TC(_i) ((_i) * 4)
+#define IXGBE_RQTC_TC0_MASK (0x7 << 0)
+#define IXGBE_RQTC_TC1_MASK (0x7 << 4)
+#define IXGBE_RQTC_TC2_MASK (0x7 << 8)
+#define IXGBE_RQTC_TC3_MASK (0x7 << 12)
+#define IXGBE_RQTC_TC4_MASK (0x7 << 16)
+#define IXGBE_RQTC_TC5_MASK (0x7 << 20)
+#define IXGBE_RQTC_TC6_MASK (0x7 << 24)
+#define IXGBE_RQTC_TC7_MASK (0x7 << 28)
+
+/* PSRTYPE.RQPL Bit masks and shift */
+#define IXGBE_PSRTYPE_RQPL_MASK 0x7
+#define IXGBE_PSRTYPE_RQPL_SHIFT 29
/* CTRL Bit Masks */
#define IXGBE_CTRL_GIO_DIS 0x00000004 /* Global IO Master Disable bit */
@@ -389,6 +762,7 @@
#define IXGBE_MHADD_MFS_SHIFT 16
/* Extended Device Control */
+#define IXGBE_CTRL_EXT_PFRSTD 0x00004000 /* Physical Function Reset Done */
#define IXGBE_CTRL_EXT_NS_DIS 0x00010000 /* No Snoop disable */
#define IXGBE_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
#define IXGBE_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
@@ -401,6 +775,8 @@
#define IXGBE_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
#define IXGBE_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
+#define IXGBE_DCA_RXCTRL_CPUID_MASK_82599 0xFF000000 /* Rx CPUID Mask */
+#define IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599 24 /* Rx CPUID Shift */
#define IXGBE_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
#define IXGBE_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */
#define IXGBE_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */
@@ -409,6 +785,8 @@
#define IXGBE_DCA_RXCTRL_DESC_HSRO_EN (1 << 15) /* DCA Rx Split Header RO */
#define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
+#define IXGBE_DCA_TXCTRL_CPUID_MASK_82599 0xFF000000 /* Tx CPUID Mask */
+#define IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599 24 /* Tx CPUID Shift */
#define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
#define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
#define IXGBE_DCA_MAX_QUEUES_82598 16 /* DCA regs only on 16 queues */
@@ -452,6 +830,8 @@
#define IXGBE_ATLAS_PDN_TX_1G_QL_ALL 0xF0
#define IXGBE_ATLAS_PDN_TX_AN_QL_ALL 0xF0
+/* Omer bit masks */
+#define IXGBE_CORECTL_WRITE_CMD 0x00010000
/* Device Type definitions for new protocol MDIO commands */
#define IXGBE_MDIO_PMA_PMD_DEV_TYPE 0x1
@@ -479,8 +859,11 @@
#define IXGBE_MDIO_PHY_SPEED_ABILITY 0x4 /* Speed Ability Reg */
#define IXGBE_MDIO_PHY_SPEED_10G 0x0001 /* 10G capable */
#define IXGBE_MDIO_PHY_SPEED_1G 0x0010 /* 1G capable */
+#define IXGBE_MDIO_PHY_EXT_ABILITY 0xB /* Ext Ability Reg */
+#define IXGBE_MDIO_PHY_10GBASET_ABILITY 0x0004 /* 10GBaseT capable */
+#define IXGBE_MDIO_PHY_1000BASET_ABILITY 0x0020 /* 1000BaseT capable */
-#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Address Reg */
+#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */
@@ -495,7 +878,7 @@
#define IXGBE_PHY_REVISION_MASK 0xFFFFFFF0
#define IXGBE_MAX_PHY_ADDR 32
-/* PHY IDs */
+/* PHY IDs*/
#define TN1010_PHY_ID 0x00A19410
#define TNX_FW_REV 0xB
#define QT2022_PHY_ID 0x0043A400
@@ -515,15 +898,22 @@
#define IXGBE_CONTROL_NL 0x000F
#define IXGBE_CONTROL_EOL_NL 0x0FFF
#define IXGBE_CONTROL_SOL_NL 0x0000
+#define IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET 0x002C
+#define IXGBE_PHY_ALLOW_ANY_SFP 0x1
/* General purpose Interrupt Enable */
#define IXGBE_SDP0_GPIEN 0x00000001 /* SDP0 */
#define IXGBE_SDP1_GPIEN 0x00000002 /* SDP1 */
+#define IXGBE_SDP2_GPIEN 0x00000004 /* SDP2 */
#define IXGBE_GPIE_MSIX_MODE 0x00000010 /* MSI-X mode */
#define IXGBE_GPIE_OCD 0x00000020 /* Other Clear Disable */
#define IXGBE_GPIE_EIMEN 0x00000040 /* Immediate Interrupt Enable */
#define IXGBE_GPIE_EIAME 0x40000000
#define IXGBE_GPIE_PBA_SUPPORT 0x80000000
+#define IXGBE_GPIE_VTMODE_MASK 0x0000C000 /* VT Mode Mask */
+#define IXGBE_GPIE_VTMODE_16 0x00004000 /* 16 VFs 8 queues per VF */
+#define IXGBE_GPIE_VTMODE_32 0x00008000 /* 32 VFs 4 queues per VF */
+#define IXGBE_GPIE_VTMODE_64 0x0000C000 /* 64 VFs 2 queues per VF */
/* Transmit Flow Control status */
#define IXGBE_TFCS_TXOFF 0x00000001
@@ -564,6 +954,21 @@
#define IXGBE_VMD_CTL_VMDQ_EN 0x00000001
#define IXGBE_VMD_CTL_VMDQ_FILTER 0x00000002
+/* VT_CTL bitmasks */
+#define IXGBE_VT_CTL_DIS_DEFPL 0x20000000 /* disable default pool */
+#define IXGBE_VT_CTL_REPLEN 0x40000000 /* replication enabled */
+#define IXGBE_VT_CTL_VT_ENABLE 0x00000001 /* Enable VT Mode */
+
+/* VMOLR bitmasks */
+#define IXGBE_VMOLR_AUPE 0x01000000 /* accept untagged packets */
+#define IXGBE_VMOLR_ROMPE 0x02000000 /* accept packets in MTA tbl */
+#define IXGBE_VMOLR_ROPE 0x04000000 /* accept packets in UC tbl */
+#define IXGBE_VMOLR_BAM 0x08000000 /* accept broadcast packets */
+#define IXGBE_VMOLR_MPE 0x10000000 /* multicast promiscuous */
+
+/* VFRE bitmask */
+#define IXGBE_VFRE_ENABLE_ALL 0xFFFFFFFF
+
/* RDHMPN and TDHMPN bitmasks */
#define IXGBE_RDHMPN_RDICADDR 0x007FF800
#define IXGBE_RDHMPN_RDICRDREQ 0x00800000
@@ -572,13 +977,39 @@
#define IXGBE_TDHMPN_TDICRDREQ 0x00800000
#define IXGBE_TDHMPN_TDICADDR_SHIFT 11
+#define IXGBE_RDMAM_MEM_SEL_SHIFT 13
+#define IXGBE_RDMAM_DWORD_SHIFT 9
+#define IXGBE_RDMAM_DESC_COMP_FIFO 1
+#define IXGBE_RDMAM_DFC_CMD_FIFO 2
+#define IXGBE_RDMAM_TCN_STATUS_RAM 4
+#define IXGBE_RDMAM_WB_COLL_FIFO 5
+#define IXGBE_RDMAM_QSC_CNT_RAM 6
+#define IXGBE_RDMAM_QSC_QUEUE_CNT 8
+#define IXGBE_RDMAM_QSC_QUEUE_RAM 0xA
+#define IXGBE_RDMAM_DESC_COM_FIFO_RANGE 135
+#define IXGBE_RDMAM_DESC_COM_FIFO_COUNT 4
+#define IXGBE_RDMAM_DFC_CMD_FIFO_RANGE 48
+#define IXGBE_RDMAM_DFC_CMD_FIFO_COUNT 7
+#define IXGBE_RDMAM_TCN_STATUS_RAM_RANGE 256
+#define IXGBE_RDMAM_TCN_STATUS_RAM_COUNT 9
+#define IXGBE_RDMAM_WB_COLL_FIFO_RANGE 8
+#define IXGBE_RDMAM_WB_COLL_FIFO_COUNT 4
+#define IXGBE_RDMAM_QSC_CNT_RAM_RANGE 64
+#define IXGBE_RDMAM_QSC_CNT_RAM_COUNT 4
+#define IXGBE_RDMAM_QSC_QUEUE_CNT_RANGE 32
+#define IXGBE_RDMAM_QSC_QUEUE_CNT_COUNT 4
+#define IXGBE_RDMAM_QSC_QUEUE_RAM_RANGE 128
+#define IXGBE_RDMAM_QSC_QUEUE_RAM_COUNT 8
+
+#define IXGBE_TXDESCIC_READY 0x80000000
+
/* Receive Checksum Control */
#define IXGBE_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
#define IXGBE_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
/* FCRTL Bit Masks */
-#define IXGBE_FCRTL_XONE 0x80000000 /* bit 31, XON enable */
-#define IXGBE_FCRTH_FCEN 0x80000000 /* Rx Flow control enable */
+#define IXGBE_FCRTL_XONE 0x80000000 /* XON enable */
+#define IXGBE_FCRTH_FCEN 0x80000000 /* Packet buffer fc enable */
/* PAP bit masks*/
#define IXGBE_PAP_TXPAUSECNT_MASK 0x0000FFFF /* Pause counter mask */
@@ -588,19 +1019,29 @@
/* Receive Arbitration Control: 0 Round Robin, 1 DFP */
#define IXGBE_RMCS_RAC 0x00000004
#define IXGBE_RMCS_DFP IXGBE_RMCS_RAC /* Deficit Fixed Priority ena */
-#define IXGBE_RMCS_TFCE_802_3X 0x00000008 /* Tx Priority flow control ena */
-#define IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority flow control ena */
+#define IXGBE_RMCS_TFCE_802_3X 0x00000008 /* Tx Priority FC ena */
+#define IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority FC ena */
#define IXGBE_RMCS_ARBDIS 0x00000040 /* Arbitration disable bit */
+/* FCCFG Bit Masks */
+#define IXGBE_FCCFG_TFCE_802_3X 0x00000008 /* Tx link FC enable */
+#define IXGBE_FCCFG_TFCE_PRIORITY 0x00000010 /* Tx priority FC enable */
/* Interrupt register bitmasks */
/* Extended Interrupt Cause Read */
#define IXGBE_EICR_RTX_QUEUE 0x0000FFFF /* RTx Queue Interrupt */
+#define IXGBE_EICR_FLOW_DIR 0x00010000 /* FDir Exception */
+#define IXGBE_EICR_RX_MISS 0x00020000 /* Packet Buffer Overrun */
+#define IXGBE_EICR_PCI 0x00040000 /* PCI Exception */
+#define IXGBE_EICR_MAILBOX 0x00080000 /* VF to PF Mailbox Interrupt */
#define IXGBE_EICR_LSC 0x00100000 /* Link Status Change */
+#define IXGBE_EICR_LINKSEC 0x00200000 /* PN Threshold */
#define IXGBE_EICR_MNG 0x00400000 /* Manageability Event Interrupt */
#define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */
#define IXGBE_EICR_GPI_SDP1 0x02000000 /* Gen Purpose Interrupt on SDP1 */
+#define IXGBE_EICR_GPI_SDP2 0x04000000 /* Gen Purpose Interrupt on SDP2 */
+#define IXGBE_EICR_ECC 0x10000000 /* ECC Error */
#define IXGBE_EICR_PBUR 0x10000000 /* Packet Buffer Handler Error */
#define IXGBE_EICR_DHER 0x20000000 /* Descriptor Handler Error */
#define IXGBE_EICR_TCP_TIMER 0x40000000 /* TCP Timer */
@@ -608,10 +1049,16 @@
/* Extended Interrupt Cause Set */
#define IXGBE_EICS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define IXGBE_EICS_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */
+#define IXGBE_EICS_RX_MISS IXGBE_EICR_RX_MISS /* Pkt Buffer Overrun */
+#define IXGBE_EICS_PCI IXGBE_EICR_PCI /* PCI Exception */
+#define IXGBE_EICS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
#define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
#define IXGBE_EICS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
#define IXGBE_EICS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define IXGBE_EICS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */
+#define IXGBE_EICS_ECC IXGBE_EICR_ECC /* ECC Error */
#define IXGBE_EICS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
#define IXGBE_EICS_DHER IXGBE_EICR_DHER /* Desc Handler Error */
#define IXGBE_EICS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
@@ -619,10 +1066,16 @@
/* Extended Interrupt Mask Set */
#define IXGBE_EIMS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define IXGBE_EIMS_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */
+#define IXGBE_EIMS_RX_MISS IXGBE_EICR_RX_MISS /* Packet Buffer Overrun */
+#define IXGBE_EIMS_PCI IXGBE_EICR_PCI /* PCI Exception */
+#define IXGBE_EIMS_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
#define IXGBE_EIMS_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EIMS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
#define IXGBE_EIMS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
#define IXGBE_EIMS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define IXGBE_EIMS_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */
+#define IXGBE_EIMS_ECC IXGBE_EICR_ECC /* ECC Error */
#define IXGBE_EIMS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
#define IXGBE_EIMS_DHER IXGBE_EICR_DHER /* Descr Handler Error */
#define IXGBE_EIMS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
@@ -630,10 +1083,16 @@
/* Extended Interrupt Mask Clear */
#define IXGBE_EIMC_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
+#define IXGBE_EIMC_FLOW_DIR IXGBE_EICR_FLOW_DIR /* FDir Exception */
+#define IXGBE_EIMC_RX_MISS IXGBE_EICR_RX_MISS /* Packet Buffer Overrun */
+#define IXGBE_EIMC_PCI IXGBE_EICR_PCI /* PCI Exception */
+#define IXGBE_EIMC_MAILBOX IXGBE_EICR_MAILBOX /* VF to PF Mailbox Int */
#define IXGBE_EIMC_LSC IXGBE_EICR_LSC /* Link Status Change */
#define IXGBE_EIMC_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */
#define IXGBE_EIMC_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */
#define IXGBE_EIMC_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */
+#define IXGBE_EIMC_GPI_SDP2 IXGBE_EICR_GPI_SDP2 /* SDP2 Gen Purpose Int */
+#define IXGBE_EIMC_ECC IXGBE_EICR_ECC /* ECC Error */
#define IXGBE_EIMC_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */
#define IXGBE_EIMC_DHER IXGBE_EICR_DHER /* Desc Handler Err */
#define IXGBE_EIMC_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */
@@ -656,6 +1115,33 @@
#define IXGBE_IMIREXT_CTRL_SYN 0x00020000 /* Check SYN bit in header */
#define IXGBE_IMIREXT_CTRL_FIN 0x00040000 /* Check FIN bit in header */
#define IXGBE_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of control bits */
+#define IXGBE_IMIR_SIZE_BP_82599 0x00001000 /* Packet size bypass */
+#define IXGBE_IMIR_CTRL_URG_82599 0x00002000 /* Check URG bit in header */
+#define IXGBE_IMIR_CTRL_ACK_82599 0x00004000 /* Check ACK bit in header */
+#define IXGBE_IMIR_CTRL_PSH_82599 0x00008000 /* Check PSH bit in header */
+#define IXGBE_IMIR_CTRL_RST_82599 0x00010000 /* Check RST bit in header */
+#define IXGBE_IMIR_CTRL_SYN_82599 0x00020000 /* Check SYN bit in header */
+#define IXGBE_IMIR_CTRL_FIN_82599 0x00040000 /* Check FIN bit in header */
+#define IXGBE_IMIR_CTRL_BP_82599 0x00080000 /* Bypass check of control bits */
+#define IXGBE_IMIR_LLI_EN_82599 0x00100000 /* Enables low latency Int */
+#define IXGBE_IMIR_RX_QUEUE_MASK_82599 0x0000007F /* Rx Queue Mask */
+#define IXGBE_IMIR_RX_QUEUE_SHIFT_82599 21 /* Rx Queue Shift */
+#define IXGBE_IMIRVP_PRIORITY_MASK 0x00000007 /* VLAN priority mask */
+#define IXGBE_IMIRVP_PRIORITY_EN 0x00000008 /* VLAN priority enable */
+
+#define IXGBE_MAX_FTQF_FILTERS 128
+#define IXGBE_FTQF_PROTOCOL_MASK 0x00000003
+#define IXGBE_FTQF_PROTOCOL_TCP 0x00000000
+#define IXGBE_FTQF_PROTOCOL_UDP 0x00000001
+#define IXGBE_FTQF_PROTOCOL_SCTP 2
+#define IXGBE_FTQF_PRIORITY_MASK 0x00000007
+#define IXGBE_FTQF_PRIORITY_SHIFT 2
+#define IXGBE_FTQF_POOL_MASK 0x0000003F
+#define IXGBE_FTQF_POOL_SHIFT 8
+#define IXGBE_FTQF_5TUPLE_MASK_MASK 0x0000001F
+#define IXGBE_FTQF_5TUPLE_MASK_SHIFT 25
+#define IXGBE_FTQF_POOL_MASK_EN 0x40000000
+#define IXGBE_FTQF_QUEUE_ENABLE 0x80000000
/* Interrupt clear mask */
#define IXGBE_IRQ_CLEAR_MASK 0xFFFFFFFF
@@ -675,6 +1161,31 @@
#define IXGBE_IVAR_ALLOC_VAL 0x80 /* Interrupt Allocation valid */
+/* ETYPE Queue Filter/Select Bit Masks */
+#define IXGBE_MAX_ETQF_FILTERS 8
+#define IXGBE_ETQF_BCN 0x10000000 /* bit 28 */
+#define IXGBE_ETQF_1588 0x40000000 /* bit 30 */
+#define IXGBE_ETQF_FILTER_EN 0x80000000 /* bit 31 */
+#define IXGBE_ETQF_POOL_ENABLE (1 << 26) /* bit 26 */
+
+#define IXGBE_ETQS_RX_QUEUE 0x007F0000 /* bits 22:16 */
+#define IXGBE_ETQS_RX_QUEUE_SHIFT 16
+#define IXGBE_ETQS_LLI 0x20000000 /* bit 29 */
+#define IXGBE_ETQS_QUEUE_EN 0x80000000 /* bit 31 */
+
+/*
+ * ETQF filter list: one static filter per filter consumer. This is
+ * to avoid filter collisions later. Add new filters
+ * here!!
+ *
+ * Current filters:
+ * EAPOL 802.1x (0x888e): Filter 0
+ * BCN (0x8904): Filter 1
+ * 1588 (0x88f7): Filter 3
+ */
+#define IXGBE_ETQF_FILTER_EAPOL 0
+#define IXGBE_ETQF_FILTER_BCN 1
+#define IXGBE_ETQF_FILTER_1588 3
/* VLAN Control Bit Masks */
#define IXGBE_VLNCTRL_VET 0x0000FFFF /* bits 0-15 */
#define IXGBE_VLNCTRL_CFI 0x10000000 /* bit 28 */
@@ -682,21 +1193,28 @@
#define IXGBE_VLNCTRL_VFE 0x40000000 /* bit 30 */
#define IXGBE_VLNCTRL_VME 0x80000000 /* bit 31 */
+/* VLAN pool filtering masks */
+#define IXGBE_VLVF_VIEN 0x80000000 /* filter is valid */
+#define IXGBE_VLVF_ENTRIES 64
#define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.1q protocol */
/* STATUS Bit Masks */
-#define IXGBE_STATUS_LAN_ID 0x0000000C /* LAN ID */
-#define IXGBE_STATUS_GIO 0x00080000 /* GIO Master Enable Status */
+#define IXGBE_STATUS_LAN_ID 0x0000000C /* LAN ID */
+#define IXGBE_STATUS_LAN_ID_SHIFT 2 /* LAN ID Shift*/
+#define IXGBE_STATUS_GIO 0x00080000 /* GIO Master Enable Status */
#define IXGBE_STATUS_LAN_ID_0 0x00000000 /* LAN ID 0 */
#define IXGBE_STATUS_LAN_ID_1 0x00000004 /* LAN ID 1 */
/* ESDP Bit Masks */
-#define IXGBE_ESDP_SDP4 0x00000001 /* SDP4 Data Value */
-#define IXGBE_ESDP_SDP5 0x00000002 /* SDP5 Data Value */
+#define IXGBE_ESDP_SDP0 0x00000001
+#define IXGBE_ESDP_SDP1 0x00000002
+#define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */
+#define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */
+#define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */
#define IXGBE_ESDP_SDP4_DIR 0x00000004 /* SDP4 IO direction */
-#define IXGBE_ESDP_SDP5_DIR 0x00000008 /* SDP5 IO direction */
+#define IXGBE_ESDP_SDP5_DIR 0x00002000 /* SDP5 IO direction */
/* LEDCTL Bit Masks */
#define IXGBE_LED_IVRT_BASE 0x00000040
@@ -719,6 +1237,7 @@
#define IXGBE_LED_OFF 0xF
/* AUTOC Bit Masks */
+#define IXGBE_AUTOC_KX4_KX_SUPP_MASK 0xC0000000
#define IXGBE_AUTOC_KX4_SUPP 0x80000000
#define IXGBE_AUTOC_KX_SUPP 0x40000000
#define IXGBE_AUTOC_PAUSE 0x30000000
@@ -727,9 +1246,17 @@
#define IXGBE_AUTOC_AN_RX_LOOSE 0x01000000
#define IXGBE_AUTOC_AN_RX_DRIFT 0x00800000
#define IXGBE_AUTOC_AN_RX_ALIGN 0x007C0000
+#define IXGBE_AUTOC_FECA 0x00040000
+#define IXGBE_AUTOC_FECR 0x00020000
+#define IXGBE_AUTOC_KR_SUPP 0x00010000
#define IXGBE_AUTOC_AN_RESTART 0x00001000
#define IXGBE_AUTOC_FLU 0x00000001
#define IXGBE_AUTOC_LMS_SHIFT 13
+#define IXGBE_AUTOC_LMS_10G_SERIAL (0x3 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_KX_KR (0x4 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_SGMII_1G_100M (0x5 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII (0x7 << IXGBE_AUTOC_LMS_SHIFT)
#define IXGBE_AUTOC_LMS_MASK (0x7 << IXGBE_AUTOC_LMS_SHIFT)
#define IXGBE_AUTOC_LMS_1G_LINK_NO_AN (0x0 << IXGBE_AUTOC_LMS_SHIFT)
#define IXGBE_AUTOC_LMS_10G_LINK_NO_AN (0x1 << IXGBE_AUTOC_LMS_SHIFT)
@@ -738,15 +1265,24 @@
#define IXGBE_AUTOC_LMS_KX4_AN_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT)
#define IXGBE_AUTOC_LMS_ATTACH_TYPE (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
-#define IXGBE_AUTOC_1G_PMA_PMD 0x00000200
-#define IXGBE_AUTOC_10G_PMA_PMD 0x00000180
-#define IXGBE_AUTOC_10G_PMA_PMD_SHIFT 7
-#define IXGBE_AUTOC_1G_PMA_PMD_SHIFT 9
+#define IXGBE_AUTOC_1G_PMA_PMD_MASK 0x00000200
+#define IXGBE_AUTOC_1G_PMA_PMD_SHIFT 9
+#define IXGBE_AUTOC_10G_PMA_PMD_MASK 0x00000180
+#define IXGBE_AUTOC_10G_PMA_PMD_SHIFT 7
#define IXGBE_AUTOC_10G_XAUI (0x0 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
#define IXGBE_AUTOC_10G_KX4 (0x1 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
#define IXGBE_AUTOC_10G_CX4 (0x2 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
#define IXGBE_AUTOC_1G_BX (0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
#define IXGBE_AUTOC_1G_KX (0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC_1G_SFI (0x0 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC_1G_KX_BX (0x1 << IXGBE_AUTOC_1G_PMA_PMD_SHIFT)
+
+#define IXGBE_AUTOC2_UPPER_MASK 0xFFFF0000
+#define IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK 0x00030000
+#define IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT 16
+#define IXGBE_AUTOC2_10G_KR (0x0 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC2_10G_XFI (0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
+#define IXGBE_AUTOC2_10G_SFI (0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
/* LINKS Bit Masks */
#define IXGBE_LINKS_KX_AN_COMP 0x80000000
@@ -756,6 +1292,7 @@
#define IXGBE_LINKS_RX_MODE 0x06000000
#define IXGBE_LINKS_TX_MODE 0x01800000
#define IXGBE_LINKS_XGXS_EN 0x00400000
+#define IXGBE_LINKS_SGMII_EN 0x02000000
#define IXGBE_LINKS_PCS_1G_EN 0x00200000
#define IXGBE_LINKS_1G_AN_EN 0x00100000
#define IXGBE_LINKS_KX_AN_IDLE 0x00080000
@@ -765,9 +1302,35 @@
#define IXGBE_LINKS_TL_FAULT 0x00001000
#define IXGBE_LINKS_SIGNAL 0x00000F00
+#define IXGBE_LINKS_SPEED_82599 0x30000000
+#define IXGBE_LINKS_SPEED_10G_82599 0x30000000
+#define IXGBE_LINKS_SPEED_1G_82599 0x20000000
+#define IXGBE_LINKS_SPEED_100_82599 0x10000000
#define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */
#define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */
+#define FIBER_LINK_UP_LIMIT 50
+
+/* PCS1GLSTA Bit Masks */
+#define IXGBE_PCS1GLSTA_LINK_OK 1
+#define IXGBE_PCS1GLSTA_SYNK_OK 0x10
+#define IXGBE_PCS1GLSTA_AN_COMPLETE 0x10000
+#define IXGBE_PCS1GLSTA_AN_PAGE_RX 0x20000
+#define IXGBE_PCS1GLSTA_AN_TIMED_OUT 0x40000
+#define IXGBE_PCS1GLSTA_AN_REMOTE_FAULT 0x80000
+#define IXGBE_PCS1GLSTA_AN_ERROR_RWS 0x100000
+
+#define IXGBE_PCS1GANA_SYM_PAUSE 0x80
+#define IXGBE_PCS1GANA_ASM_PAUSE 0x100
+
+/* PCS1GLCTL Bit Masks */
+#define IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN 0x00040000 /* PCS 1G autoneg to en */
+#define IXGBE_PCS1GLCTL_FLV_LINK_UP 1
+#define IXGBE_PCS1GLCTL_FORCE_LINK 0x20
+#define IXGBE_PCS1GLCTL_LOW_LINK_LATCH 0x40
+#define IXGBE_PCS1GLCTL_AN_ENABLE 0x10000
+#define IXGBE_PCS1GLCTL_AN_RESTART 0x20000
+
/* SW Semaphore Register bitmasks */
#define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
#define IXGBE_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
@@ -819,6 +1382,11 @@
#define IXGBE_FW_PTR 0x0F
#define IXGBE_PBANUM0_PTR 0x15
#define IXGBE_PBANUM1_PTR 0x16
+#define IXGBE_PCIE_MSIX_82599_CAPS 0x72
+#define IXGBE_PCIE_MSIX_82598_CAPS 0x62
+
+/* MSI-X capability fields masks */
+#define IXGBE_PCIE_MSIX_TBL_SZ_MASK 0x7FF
/* Legacy EEPROM word offsets */
#define IXGBE_ISCSI_BOOT_CAPS 0x0033
@@ -867,6 +1435,8 @@
#define IXGBE_PCI_LINK_SPEED 0xF
#define IXGBE_PCI_LINK_SPEED_2500 0x1
#define IXGBE_PCI_LINK_SPEED_5000 0x2
+#define IXGBE_PCI_HEADER_TYPE_REGISTER 0x0E
+#define IXGBE_PCI_HEADER_TYPE_MULTIFUNC 0x80
/* Number of 100 microseconds we wait for PCI Express master disable */
#define IXGBE_PCI_MASTER_DISABLE_TIMEOUT 800
@@ -919,6 +1489,7 @@
#define IXGBE_RXCTRL_RXEN 0x00000001 /* Enable Receiver */
#define IXGBE_RXCTRL_DMBYPS 0x00000002 /* Descriptor Monitor Bypass */
#define IXGBE_RXDCTL_ENABLE 0x02000000 /* Enable specific Rx Queue */
+#define IXGBE_RXDCTL_VME 0x40000000 /* VLAN mode enable */
#define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */
#define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/
@@ -929,9 +1500,23 @@
/* Receive Priority Flow Control Enable */
#define IXGBE_FCTRL_RPFCE 0x00004000
#define IXGBE_FCTRL_RFCE 0x00008000 /* Receive Flow Control Ena */
+#define IXGBE_MFLCN_PMCF 0x00000001 /* Pass MAC Control Frames */
+#define IXGBE_MFLCN_DPF 0x00000002 /* Discard Pause Frame */
+#define IXGBE_MFLCN_RPFCE 0x00000004 /* Receive Priority FC Enable */
+#define IXGBE_MFLCN_RFCE 0x00000008 /* Receive FC Enable */
/* Multiple Receive Queue Control */
#define IXGBE_MRQC_RSSEN 0x00000001 /* RSS Enable */
+#define IXGBE_MRQC_MRQE_MASK 0xF /* Bits 3:0 */
+#define IXGBE_MRQC_RT8TCEN 0x00000002 /* 8 TC no RSS */
+#define IXGBE_MRQC_RT4TCEN 0x00000003 /* 4 TC no RSS */
+#define IXGBE_MRQC_RTRSS8TCEN 0x00000004 /* 8 TC w/ RSS */
+#define IXGBE_MRQC_RTRSS4TCEN 0x00000005 /* 4 TC w/ RSS */
+#define IXGBE_MRQC_VMDQEN 0x00000008 /* VMDq2 64 pools no RSS */
+#define IXGBE_MRQC_VMDQRSS32EN 0x0000000A /* VMDq2 32 pools w/ RSS */
+#define IXGBE_MRQC_VMDQRSS64EN 0x0000000B /* VMDq2 64 pools w/ RSS */
+#define IXGBE_MRQC_VMDQRT8TCEN 0x0000000C /* VMDq2/RT 16 pool 8 TC */
+#define IXGBE_MRQC_VMDQRT4TCEN 0x0000000D /* VMDq2/RT 32 pool 4 TC */
#define IXGBE_MRQC_RSS_FIELD_MASK 0xFFFF0000
#define IXGBE_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
#define IXGBE_MRQC_RSS_FIELD_IPV4 0x00020000
@@ -942,6 +1527,12 @@
#define IXGBE_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
#define IXGBE_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
#define IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP 0x01000000
+#define IXGBE_MRQC_L3L4TXSWEN 0x00008000
+
+/* Queue Drop Enable */
+#define IXGBE_QDE_ENABLE 0x00000001
+#define IXGBE_QDE_IDX_MASK 0x00007F00
+#define IXGBE_QDE_IDX_SHIFT 8
#define IXGBE_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
#define IXGBE_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
@@ -953,10 +1544,25 @@
#define IXGBE_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
#define IXGBE_TXD_STAT_DD 0x00000001 /* Descriptor Done */
+#define IXGBE_RXDADV_IPSEC_STATUS_SECP 0x00020000
+#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_PROTOCOL 0x08000000
+#define IXGBE_RXDADV_IPSEC_ERROR_INVALID_LENGTH 0x10000000
+#define IXGBE_RXDADV_IPSEC_ERROR_AUTH_FAILED 0x18000000
+#define IXGBE_RXDADV_IPSEC_ERROR_BIT_MASK 0x18000000
+/* Multiple Transmit Queue Command Register */
+#define IXGBE_MTQC_RT_ENA 0x1 /* DCB Enable */
+#define IXGBE_MTQC_VT_ENA 0x2 /* VMDQ2 Enable */
+#define IXGBE_MTQC_64Q_1PB 0x0 /* 64 queues 1 pack buffer */
+#define IXGBE_MTQC_64VF 0x8 /* 2 TX Queues per pool w/64VF's */
+#define IXGBE_MTQC_8TC_8TQ 0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */
+
/* Receive Descriptor bit definitions */
#define IXGBE_RXD_STAT_DD 0x01 /* Descriptor Done */
#define IXGBE_RXD_STAT_EOP 0x02 /* End of Packet */
+#define IXGBE_RXD_STAT_FLM 0x04 /* FDir Match */
#define IXGBE_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
+#define IXGBE_RXDADV_NEXTP_MASK 0x000FFFF0 /* Next Descriptor Index */
+#define IXGBE_RXDADV_NEXTP_SHIFT 0x00000004
#define IXGBE_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */
#define IXGBE_RXD_STAT_L4CS 0x20 /* L4 xsum calculated */
#define IXGBE_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
@@ -965,6 +1571,10 @@
#define IXGBE_RXD_STAT_VEXT 0x200 /* 1st VLAN found */
#define IXGBE_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */
#define IXGBE_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */
+#define IXGBE_RXD_STAT_LLINT 0x800 /* Pkt caused Low Latency Interrupt */
+#define IXGBE_RXD_STAT_TS 0x10000 /* Time Stamp */
+#define IXGBE_RXD_STAT_SECP 0x20000 /* Security Processing */
+#define IXGBE_RXD_STAT_LB 0x40000 /* Loopback Status */
#define IXGBE_RXD_STAT_ACK 0x8000 /* ACK Packet indication */
#define IXGBE_RXD_ERR_CE 0x01 /* CRC Error */
#define IXGBE_RXD_ERR_LE 0x02 /* Length Error */
@@ -973,6 +1583,8 @@
#define IXGBE_RXD_ERR_USE 0x20 /* Undersize Error */
#define IXGBE_RXD_ERR_TCPE 0x40 /* TCP/UDP Checksum Error */
#define IXGBE_RXD_ERR_IPE 0x80 /* IP Checksum Error */
+#define IXGBE_RXDADV_ERR_MASK 0xfff00000 /* RDESC.ERRORS mask */
+#define IXGBE_RXDADV_ERR_SHIFT 20 /* RDESC.ERRORS shift */
#define IXGBE_RXDADV_ERR_HBO 0x00800000 /*Header Buffer Overflow */
#define IXGBE_RXDADV_ERR_CE 0x01000000 /* CRC Error */
#define IXGBE_RXDADV_ERR_LE 0x02000000 /* Length Error */
@@ -987,9 +1599,23 @@
#define IXGBE_RXD_CFI_MASK 0x1000 /* CFI is bit 12 */
#define IXGBE_RXD_CFI_SHIFT 12
+#define IXGBE_RXDADV_STAT_DD IXGBE_RXD_STAT_DD /* Done */
+#define IXGBE_RXDADV_STAT_EOP IXGBE_RXD_STAT_EOP /* End of Packet */
+#define IXGBE_RXDADV_STAT_FLM IXGBE_RXD_STAT_FLM /* FDir Match */
+#define IXGBE_RXDADV_STAT_VP IXGBE_RXD_STAT_VP /* IEEE VLAN Pkt */
+#define IXGBE_RXDADV_STAT_MASK 0x000fffff /* Stat/NEXTP: bit 0-19 */
+
+/* PSRTYPE bit definitions */
+#define IXGBE_PSRTYPE_TCPHDR 0x00000010
+#define IXGBE_PSRTYPE_UDPHDR 0x00000020
+#define IXGBE_PSRTYPE_IPV4HDR 0x00000100
+#define IXGBE_PSRTYPE_IPV6HDR 0x00000200
/* SRRCTL bit definitions */
#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */
+#define IXGBE_SRRCTL_RDMTS_SHIFT 22
+#define IXGBE_SRRCTL_RDMTS_MASK 0x01C00000
+#define IXGBE_SRRCTL_DROP_EN 0x10000000
#define IXGBE_SRRCTL_BSIZEPKT_MASK 0x0000007F
#define IXGBE_SRRCTL_BSIZEHDR_MASK 0x00003F00
#define IXGBE_SRRCTL_DESCTYPE_LEGACY 0x00000000
@@ -1004,6 +1630,7 @@
#define IXGBE_RXDADV_RSSTYPE_MASK 0x0000000F
#define IXGBE_RXDADV_PKTTYPE_MASK 0x0000FFF0
+#define IXGBE_RXDADV_PKTTYPE_MASK_EX 0x0001FFF0
#define IXGBE_RXDADV_HDRBUFLEN_MASK 0x00007FE0
#define IXGBE_RXDADV_HDRBUFLEN_SHIFT 5
#define IXGBE_RXDADV_SPLITHEADER_EN 0x00001000
@@ -1031,6 +1658,20 @@
#define IXGBE_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */
#define IXGBE_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */
#define IXGBE_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */
+#define IXGBE_RXDADV_PKTTYPE_IPSEC_ESP 0x00001000 /* IPSec ESP */
+#define IXGBE_RXDADV_PKTTYPE_IPSEC_AH 0x00002000 /* IPSec AH */
+#define IXGBE_RXDADV_PKTTYPE_LINKSEC 0x00004000 /* LinkSec Encap */
+#define IXGBE_RXDADV_PKTTYPE_ETQF 0x00008000 /* PKTTYPE is ETQF index */
+#define IXGBE_RXDADV_PKTTYPE_ETQF_MASK 0x00000070 /* ETQF has 8 indices */
+#define IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT 4 /* Right-shift 4 bits */
+
+/* Security Processing bit Indication */
+#define IXGBE_RXDADV_LNKSEC_STATUS_SECP 0x00020000
+#define IXGBE_RXDADV_LNKSEC_ERROR_NO_SA_MATCH 0x08000000
+#define IXGBE_RXDADV_LNKSEC_ERROR_REPLAY_ERROR 0x10000000
+#define IXGBE_RXDADV_LNKSEC_ERROR_BIT_MASK 0x18000000
+#define IXGBE_RXDADV_LNKSEC_ERROR_BAD_SIG 0x18000000
+
/* Masks to determine if packets should be dropped due to frame errors */
#define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \
IXGBE_RXD_ERR_CE | \
@@ -1060,6 +1701,14 @@
#define IXGBE_RX_DESC_SPECIAL_PRI_SHIFT 0x000D /* Priority in upper 3 of 16 */
#define IXGBE_TX_DESC_SPECIAL_PRI_SHIFT IXGBE_RX_DESC_SPECIAL_PRI_SHIFT
+/* Little Endian defines */
+#ifndef __le32
+#define __le32 u32
+#endif
+#ifndef __le64
+#define __le64 u64
+
+#endif
/* Transmit Descriptor - Legacy */
struct ixgbe_legacy_tx_desc {
@@ -1147,6 +1796,9 @@ struct ixgbe_adv_tx_context_desc {
/* Adv Transmit Descriptor Config Masks */
#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */
+#define IXGBE_ADVTXD_MAC_LINKSEC 0x00040000 /* Insert LinkSec */
+#define IXGBE_ADVTXD_IPSEC_SA_INDEX_MASK 0x000003FF /* IPSec SA index */
+#define IXGBE_ADVTXD_IPSEC_ESP_LEN_MASK 0x000001FF /* IPSec ESP length */
#define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */
#define IXGBE_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Desc */
#define IXGBE_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
@@ -1181,6 +1833,9 @@ struct ixgbe_adv_tx_context_desc {
#define IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
#define IXGBE_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */
#define IXGBE_ADVTXD_TUCMD_MKRREQ 0x00002000 /*Req requires Markers and CRC*/
+#define IXGBE_ADVTXD_POPTS_IPSEC 0x00000400 /* IPSec offload request */
+#define IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
+#define IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000/* ESP Encrypt Enable */
#define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
@@ -1194,6 +1849,12 @@ typedef u32 ixgbe_link_speed;
#define IXGBE_LINK_SPEED_10GB_FULL 0x0080
#define IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \
IXGBE_LINK_SPEED_10GB_FULL)
+#define IXGBE_LINK_SPEED_82599_AUTONEG (IXGBE_LINK_SPEED_100_FULL | \
+ IXGBE_LINK_SPEED_1GB_FULL | \
+ IXGBE_LINK_SPEED_10GB_FULL)
+
+#define IXGBE_PCIE_DEV_CTRL_2 0xC8
+#define PCIE_COMPL_TO_VALUE 0x05
/* Physical layer type */
typedef u32 ixgbe_physical_layer;
@@ -1210,7 +1871,6 @@ typedef u32 ixgbe_physical_layer;
#define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x0200
#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400
-
enum ixgbe_eeprom_type {
ixgbe_eeprom_uninitialized = 0,
ixgbe_eeprom_spi,
@@ -1220,12 +1880,14 @@ enum ixgbe_eeprom_type {
enum ixgbe_mac_type {
ixgbe_mac_unknown = 0,
ixgbe_mac_82598EB,
+ ixgbe_mac_82599EB,
ixgbe_num_macs
};
enum ixgbe_phy_type {
ixgbe_phy_unknown = 0,
ixgbe_phy_tn,
+ ixgbe_phy_cu_unknown,
ixgbe_phy_qt,
ixgbe_phy_xaui,
ixgbe_phy_nl,
@@ -1234,22 +1896,31 @@ enum ixgbe_phy_type {
ixgbe_phy_sfp_avago,
ixgbe_phy_sfp_ftl,
ixgbe_phy_sfp_unknown,
+ ixgbe_phy_sfp_intel,
ixgbe_phy_generic
};
/*
* SFP+ module type IDs:
*
- * ID Module Type
+ * ID Module Type
* =============
- * 0 SFP_DA_CU
- * 1 SFP_SR
- * 2 SFP_LR
+ * 0 SFP_DA_CU
+ * 1 SFP_SR
+ * 2 SFP_LR
+ * 3 SFP_DA_CU_CORE0 - 82599-specific
+ * 4 SFP_DA_CU_CORE1 - 82599-specific
+ * 5 SFP_SR/LR_CORE0 - 82599-specific
+ * 6 SFP_SR/LR_CORE1 - 82599-specific
*/
enum ixgbe_sfp_type {
ixgbe_sfp_type_da_cu = 0,
ixgbe_sfp_type_sr = 1,
ixgbe_sfp_type_lr = 2,
+ ixgbe_sfp_type_da_cu_core0 = 3,
+ ixgbe_sfp_type_da_cu_core1 = 4,
+ ixgbe_sfp_type_srlr_core0 = 5,
+ ixgbe_sfp_type_srlr_core1 = 6,
ixgbe_sfp_type_not_present = 0xFFFE,
ixgbe_sfp_type_unknown = 0xFFFF
};
@@ -1263,14 +1934,51 @@ enum ixgbe_media_type {
};
/* Flow Control Settings */
-enum ixgbe_fc_type {
+enum ixgbe_fc_mode {
ixgbe_fc_none = 0,
ixgbe_fc_rx_pause,
ixgbe_fc_tx_pause,
ixgbe_fc_full,
+#ifdef CONFIG_DCB
+ ixgbe_fc_pfc,
+#endif
ixgbe_fc_default
};
+/* PCI bus types */
+enum ixgbe_bus_type {
+ ixgbe_bus_type_unknown = 0,
+ ixgbe_bus_type_pci,
+ ixgbe_bus_type_pcix,
+ ixgbe_bus_type_pci_express,
+ ixgbe_bus_type_reserved
+};
+
+/* PCI bus speeds */
+enum ixgbe_bus_speed {
+ ixgbe_bus_speed_unknown = 0,
+ ixgbe_bus_speed_33,
+ ixgbe_bus_speed_66,
+ ixgbe_bus_speed_100,
+ ixgbe_bus_speed_120,
+ ixgbe_bus_speed_133,
+ ixgbe_bus_speed_2500,
+ ixgbe_bus_speed_5000,
+ ixgbe_bus_speed_reserved
+};
+
+/* PCI bus widths */
+enum ixgbe_bus_width {
+ ixgbe_bus_width_unknown = 0,
+ ixgbe_bus_width_pcie_x1,
+ ixgbe_bus_width_pcie_x2,
+ ixgbe_bus_width_pcie_x4 = 4,
+ ixgbe_bus_width_pcie_x8 = 8,
+ ixgbe_bus_width_32,
+ ixgbe_bus_width_64,
+ ixgbe_bus_width_reserved
+};
+
struct ixgbe_addr_filter_info {
u32 num_mc_addrs;
u32 rar_used_count;
@@ -1280,6 +1988,16 @@ struct ixgbe_addr_filter_info {
bool user_set_promisc;
};
+/* Bus parameters */
+struct ixgbe_bus_info {
+ enum ixgbe_bus_speed speed;
+ enum ixgbe_bus_width width;
+ enum ixgbe_bus_type type;
+
+ u16 func;
+ u16 lan_id;
+};
+
/* Flow control parameters */
struct ixgbe_fc_info {
u32 high_water; /* Flow Control High-water */
@@ -1287,8 +2005,9 @@ struct ixgbe_fc_info {
u16 pause_time; /* Flow Control Pause timer */
bool send_xon; /* Flow control send XON */
bool strict_ieee; /* Strict IEEE mode */
- enum ixgbe_fc_type type; /* Type of flow control */
- enum ixgbe_fc_type original_type;
+ bool disable_fc_autoneg; /* Turn off autoneg FC mode */
+ enum ixgbe_fc_mode current_mode; /* FC mode in effect */
+ enum ixgbe_fc_mode requested_mode; /* FC mode requested by caller */
};
/* Statistics counters collected by the MAC */
@@ -1348,6 +2067,14 @@ struct ixgbe_hw_stats {
u64 qptc[16];
u64 qbrc[16];
u64 qbtc[16];
+ u64 qprdc[16];
+ u64 pxon2offc[8];
+ u64 fdirustat_add;
+ u64 fdirustat_remove;
+ u64 fdirfstat_fadd;
+ u64 fdirfstat_fremove;
+ u64 fdirmatch;
+ u64 fdirmiss;
};
/* forward declaration */
@@ -1372,12 +2099,15 @@ struct ixgbe_mac_operations {
s32 (*start_hw)(struct ixgbe_hw *);
s32 (*clear_hw_cntrs)(struct ixgbe_hw *);
enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
- s32 (*get_supported_physical_layer)(struct ixgbe_hw *);
+ u32 (*get_supported_physical_layer)(struct ixgbe_hw *);
s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
s32 (*stop_adapter)(struct ixgbe_hw *);
s32 (*get_bus_info)(struct ixgbe_hw *);
+ void (*set_lan_id)(struct ixgbe_hw *);
s32 (*read_analog_reg8)(struct ixgbe_hw*, u32, u8*);
s32 (*write_analog_reg8)(struct ixgbe_hw*, u32, u8);
+ s32 (*setup_sfp)(struct ixgbe_hw *);
+ s32 (*enable_rx_dma)(struct ixgbe_hw *, u32);
/* Link */
s32 (*setup_link)(struct ixgbe_hw *);
@@ -1433,7 +2163,7 @@ struct ixgbe_phy_operations {
struct ixgbe_eeprom_info {
struct ixgbe_eeprom_operations ops;
enum ixgbe_eeprom_type type;
- u32 semaphore_delay;
+ u32 semaphore_delay;
u16 word_size;
u16 address_bits;
};
@@ -1449,11 +2179,12 @@ struct ixgbe_mac_info {
u32 num_rar_entries;
u32 max_tx_queues;
u32 max_rx_queues;
- u32 link_attach_type;
- u32 link_mode_select;
- bool link_settings_loaded;
+ u32 max_msix_vectors;
+ u32 orig_autoc;
+ u32 orig_autoc2;
+ bool orig_link_settings_stored;
bool autoneg;
- bool autoneg_failed;
+ bool autoneg_succeeded;
};
struct ixgbe_phy_info {
@@ -1467,6 +2198,7 @@ struct ixgbe_phy_info {
bool reset_disable;
ixgbe_autoneg_advertised autoneg_advertised;
bool autoneg_wait_to_complete;
+ bool multispeed_fiber;
};
struct ixgbe_hw {
@@ -1477,6 +2209,7 @@ struct ixgbe_hw {
struct ixgbe_fc_info fc;
struct ixgbe_phy_info phy;
struct ixgbe_eeprom_info eeprom;
+ struct ixgbe_bus_info bus;
u16 device_id;
u16 vendor_id;
u16 subsystem_device_id;
@@ -1515,6 +2248,7 @@ struct ixgbe_info {
#define IXGBE_ERR_I2C -18
#define IXGBE_ERR_SFP_NOT_SUPPORTED -19
#define IXGBE_ERR_SFP_NOT_PRESENT -20
+#define IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT -21
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
#endif /* _IXGBE_TYPE_H_ */
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
index 014745720560..d3bf2f017cc2 100644
--- a/drivers/net/ixp2000/ixpdev.c
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -141,7 +141,7 @@ static int ixpdev_poll(struct napi_struct *napi, int budget)
break;
} while (ixp2000_reg_read(IXP2000_IRQ_THD_RAW_STATUS_A_0) & 0x00ff);
- netif_rx_complete(napi);
+ napi_complete(napi);
ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_SET_A_0, 0x00ff);
return rx;
@@ -204,7 +204,7 @@ static irqreturn_t ixpdev_interrupt(int irq, void *dev_id)
ixp2000_reg_wrb(IXP2000_IRQ_THD_ENABLE_CLEAR_A_0, 0x00ff);
if (likely(napi_schedule_prep(&ip->napi))) {
- __netif_rx_schedule(&ip->napi);
+ __napi_schedule(&ip->napi);
} else {
printk(KERN_CRIT "ixp2000: irq while polling!!\n");
}
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index 334ff9e12cdd..14248cfc3dfd 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -131,7 +131,8 @@ static int __init sonic_probe1(struct net_device *dev)
if (sonic_debug && version_printed++ == 0)
printk(version);
- printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ", lp->device->bus_id, dev->base_addr);
+ printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ",
+ dev_name(lp->device), dev->base_addr);
/*
* Put the sonic into software reset, then
@@ -156,7 +157,8 @@ static int __init sonic_probe1(struct net_device *dev)
if ((lp->descriptors = dma_alloc_coherent(lp->device,
SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
&lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
- printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id);
+ printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n",
+ dev_name(lp->device));
goto out;
}
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index a6e1a35a13cb..860dcd98a07c 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -429,10 +429,9 @@ jme_check_link(struct net_device *netdev, int testonly)
jme->phylink = phylink;
- ghc = jme->reg_ghc & ~(GHC_SPEED_10M |
- GHC_SPEED_100M |
- GHC_SPEED_1000M |
- GHC_DPX);
+ ghc = jme->reg_ghc & ~(GHC_SPEED | GHC_DPX |
+ GHC_TO_CLK_PCIE | GHC_TXMAC_CLK_PCIE |
+ GHC_TO_CLK_GPHY | GHC_TXMAC_CLK_GPHY);
switch (phylink & PHY_LINK_SPEED_MASK) {
case PHY_LINK_SPEED_10M:
ghc |= GHC_SPEED_10M |
@@ -1834,7 +1833,7 @@ jme_tx_vlan(struct sk_buff *skb, __le16 *vlan, u8 *flags)
}
static int
-jme_fill_first_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx)
+jme_fill_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx)
{
struct jme_ring *txring = jme->txring;
struct txdesc *txdesc;
@@ -1864,6 +1863,7 @@ jme_fill_first_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx)
if (jme_tx_tso(skb, &txdesc->desc1.mss, &flags))
jme_tx_csum(jme, skb, &flags);
jme_tx_vlan(skb, &txdesc->desc1.vlan, &flags);
+ jme_map_tx_skb(jme, skb, idx);
txdesc->desc1.flags = flags;
/*
* Set tx buffer info after telling NIC to send
@@ -1933,8 +1933,7 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev)
return NETDEV_TX_BUSY;
}
- jme_map_tx_skb(jme, skb, idx);
- jme_fill_first_tx_desc(jme, skb, idx);
+ jme_fill_tx_desc(jme, skb, idx);
jwrite32(jme, JME_TXCS, jme->reg_txcs |
TXCS_SELECT_QUEUE0 |
@@ -2591,6 +2590,16 @@ static const struct ethtool_ops jme_ethtool_ops = {
static int
jme_pci_dma64(struct pci_dev *pdev)
{
+ if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 &&
+ !pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+ if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
+ return 1;
+
+ if (pdev->device == PCI_DEVICE_ID_JMICRON_JMC250 &&
+ !pci_set_dma_mask(pdev, DMA_40BIT_MASK))
+ if (!pci_set_consistent_dma_mask(pdev, DMA_40BIT_MASK))
+ return 1;
+
if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK))
if (!pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))
return 0;
@@ -2857,7 +2866,11 @@ jme_init_one(struct pci_dev *pdev,
goto err_out_free_shadow;
}
- msg_probe(jme, "JMC250 gigabit%s ver:%x rev:%x macaddr:%pM\n",
+ msg_probe(jme, "%s%s ver:%x rev:%x macaddr:%pM\n",
+ (jme->pdev->device == PCI_DEVICE_ID_JMICRON_JMC250) ?
+ "JMC250 Gigabit Ethernet" :
+ (jme->pdev->device == PCI_DEVICE_ID_JMICRON_JMC260) ?
+ "JMC260 Fast Ethernet" : "Unknown",
(jme->fpgaver != 0) ? " (FPGA)" : "",
(jme->fpgaver != 0) ? jme->fpgaver : jme->chiprev,
jme->rev, netdev->dev_addr);
@@ -3003,7 +3016,7 @@ static struct pci_driver jme_driver = {
static int __init
jme_init_module(void)
{
- printk(KERN_INFO PFX "JMicron JMC250 gigabit ethernet "
+ printk(KERN_INFO PFX "JMicron JMC2XX ethernet "
"driver version %s\n", DRV_VERSION);
return pci_register_driver(&jme_driver);
}
diff --git a/drivers/net/jme.h b/drivers/net/jme.h
index 5154411b5e6b..0996a069ac7b 100644
--- a/drivers/net/jme.h
+++ b/drivers/net/jme.h
@@ -25,7 +25,7 @@
#define __JME_H_INCLUDED__
#define DRV_NAME "jme"
-#define DRV_VERSION "1.0.3"
+#define DRV_VERSION "1.0.4"
#define PFX DRV_NAME ": "
#define PCI_DEVICE_ID_JMICRON_JMC250 0x0250
@@ -398,15 +398,15 @@ struct jme_ring {
#define JME_NAPI_WEIGHT(w) int w
#define JME_NAPI_WEIGHT_VAL(w) w
#define JME_NAPI_WEIGHT_SET(w, r)
-#define JME_RX_COMPLETE(dev, napis) netif_rx_complete(napis)
+#define JME_RX_COMPLETE(dev, napis) napi_complete(napis)
#define JME_NAPI_ENABLE(priv) napi_enable(&priv->napi);
#define JME_NAPI_DISABLE(priv) \
if (!napi_disable_pending(&priv->napi)) \
napi_disable(&priv->napi);
#define JME_RX_SCHEDULE_PREP(priv) \
- netif_rx_schedule_prep(&priv->napi)
+ napi_schedule_prep(&priv->napi)
#define JME_RX_SCHEDULE(priv) \
- __netif_rx_schedule(&priv->napi);
+ __napi_schedule(&priv->napi);
/*
* Jmac Adapter Private data
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index 75010cac76ac..38d6649a29c4 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -334,7 +334,7 @@ static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id)
DMA_STAT_HALT | DMA_STAT_ERR),
&lp->rx_dma_regs->dmasm);
- netif_rx_schedule(&lp->napi);
+ napi_schedule(&lp->napi);
if (dmas & DMA_STAT_ERR)
printk(KERN_ERR DRV_NAME "%s: DMA error\n", dev->name);
@@ -468,7 +468,7 @@ static int korina_poll(struct napi_struct *napi, int budget)
work_done = korina_rx(dev, budget);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
writel(readl(&lp->rx_dma_regs->dmasm) &
~(DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR),
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index d7afb938ea62..633808d447be 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -391,7 +391,8 @@ MODULE_LICENSE("GPL");
*/
static int __init do_lance_probe(struct net_device *dev)
{
- int *port, result;
+ unsigned int *port;
+ int result;
if (high_memory <= phys_to_virt(16*1024*1024))
lance_need_isa_bounce_buffers = 0;
@@ -453,16 +454,28 @@ out:
}
#endif
+static const struct net_device_ops lance_netdev_ops = {
+ .ndo_open = lance_open,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_stop = lance_close,
+ .ndo_get_stats = lance_get_stats,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_tx_timeout = lance_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options)
{
struct lance_private *lp;
- long dma_channels; /* Mark spuriously-busy DMA channels */
+ unsigned long dma_channels; /* Mark spuriously-busy DMA channels */
int i, reset_val, lance_version;
const char *chipname;
/* Flags for specific chips or boards. */
- unsigned char hpJ2405A = 0; /* HP ISA adaptor */
- int hp_builtin = 0; /* HP on-board ethernet. */
- static int did_version; /* Already printed version info. */
+ unsigned char hpJ2405A = 0; /* HP ISA adaptor */
+ int hp_builtin = 0; /* HP on-board ethernet. */
+ static int did_version; /* Already printed version info. */
unsigned long flags;
int err = -ENOMEM;
void __iomem *bios;
@@ -713,12 +726,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
printk(version);
/* The LANCE-specific entries in the device structure. */
- dev->open = lance_open;
- dev->hard_start_xmit = lance_start_xmit;
- dev->stop = lance_close;
- dev->get_stats = lance_get_stats;
- dev->set_multicast_list = set_multicast_list;
- dev->tx_timeout = lance_tx_timeout;
+ dev->netdev_ops = &lance_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
err = register_netdev(dev);
diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c
index 4d1a059921c6..d44bddbee373 100644
--- a/drivers/net/lp486e.c
+++ b/drivers/net/lp486e.c
@@ -952,6 +952,17 @@ static void print_eth(char *add)
(unsigned char) add[12], (unsigned char) add[13]);
}
+static const struct net_device_ops i596_netdev_ops = {
+ .ndo_open = i596_open,
+ .ndo_stop = i596_close,
+ .ndo_start_xmit = i596_start_xmit,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_tx_timeout = i596_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init lp486e_probe(struct net_device *dev) {
struct i596_private *lp;
unsigned char eth_addr[6] = { 0, 0xaa, 0, 0, 0, 0 };
@@ -1014,12 +1025,8 @@ static int __init lp486e_probe(struct net_device *dev) {
printk("\n");
/* The LP486E-specific entries in the device structure. */
- dev->open = &i596_open;
- dev->stop = &i596_close;
- dev->hard_start_xmit = &i596_start_xmit;
- dev->set_multicast_list = &set_multicast_list;
+ dev->netdev_ops = &i596_netdev_ops;
dev->watchdog_timeo = 5*HZ;
- dev->tx_timeout = i596_tx_timeout;
#if 0
/* selftest reports 0x320925ae - don't know what that means */
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index f6c4936e2fa8..f50501013b1c 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -211,10 +211,10 @@ static int macb_mii_probe(struct net_device *dev)
/* attach the mac to the phy */
if (pdata && pdata->is_rmii) {
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&macb_handle_link_change, 0, PHY_INTERFACE_MODE_RMII);
} else {
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&macb_handle_link_change, 0, PHY_INTERFACE_MODE_MII);
}
@@ -513,7 +513,6 @@ static int macb_rx(struct macb *bp, int budget)
static int macb_poll(struct napi_struct *napi, int budget)
{
struct macb *bp = container_of(napi, struct macb, napi);
- struct net_device *dev = bp->dev;
int work_done;
u32 status;
@@ -527,7 +526,7 @@ static int macb_poll(struct napi_struct *napi, int budget)
* this function was called last time, and no packets
* have been received since.
*/
- netif_rx_complete(napi);
+ napi_complete(napi);
goto out;
}
@@ -538,13 +537,13 @@ static int macb_poll(struct napi_struct *napi, int budget)
dev_warn(&bp->pdev->dev,
"No RX buffers complete, status = %02lx\n",
(unsigned long)status);
- netif_rx_complete(napi);
+ napi_complete(napi);
goto out;
}
work_done = macb_rx(bp, budget);
if (work_done < budget)
- netif_rx_complete(napi);
+ napi_complete(napi);
/*
* We've done what we can to clean the buffers. Make sure we
@@ -579,7 +578,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
}
if (status & MACB_RX_INT_FLAGS) {
- if (netif_rx_schedule_prep(&bp->napi)) {
+ if (napi_schedule_prep(&bp->napi)) {
/*
* There's no point taking any more interrupts
* until we have processed the buffers
@@ -587,7 +586,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
dev_dbg(&bp->pdev->dev,
"scheduling RX softirq\n");
- __netif_rx_schedule(&bp->napi);
+ __napi_schedule(&bp->napi);
}
}
@@ -1077,7 +1076,7 @@ static void macb_get_drvinfo(struct net_device *dev,
strcpy(info->driver, bp->pdev->dev.driver->name);
strcpy(info->version, "$Revision: 1.14 $");
- strcpy(info->bus_info, bp->pdev->dev.bus_id);
+ strcpy(info->bus_info, dev_name(&bp->pdev->dev));
}
static struct ethtool_ops macb_ethtool_ops = {
@@ -1234,8 +1233,8 @@ static int __init macb_probe(struct platform_device *pdev)
phydev = bp->phy_dev;
printk(KERN_INFO "%s: attached PHY driver [%s] "
- "(mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
+ phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
return 0;
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index 205bb05c25d6..527166e35d56 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -176,7 +176,8 @@ static int __init macsonic_init(struct net_device *dev)
if ((lp->descriptors = dma_alloc_coherent(lp->device,
SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
&lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
- printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id);
+ printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n",
+ dev_name(lp->device));
return -ENOMEM;
}
@@ -337,7 +338,7 @@ static int __init mac_onboard_sonic_probe(struct net_device *dev)
sonic_version_printed = 1;
}
printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n",
- lp->device->bus_id, dev->base_addr);
+ dev_name(lp->device), dev->base_addr);
/* The PowerBook's SONIC is 16 bit always. */
if (macintosh_config->ident == MAC_MODEL_PB520) {
@@ -370,10 +371,10 @@ static int __init mac_onboard_sonic_probe(struct net_device *dev)
}
printk(KERN_INFO
"%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
- lp->device->bus_id, sr, lp->dma_bitmode?32:16, lp->reg_offset);
+ dev_name(lp->device), sr, lp->dma_bitmode?32:16, lp->reg_offset);
#if 0 /* This is sometimes useful to find out how MacOS configured the card. */
- printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id,
+ printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device),
SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff);
#endif
@@ -525,12 +526,12 @@ static int __init mac_nubus_sonic_probe(struct net_device *dev)
sonic_version_printed = 1;
}
printk(KERN_INFO "%s: %s in slot %X\n",
- lp->device->bus_id, ndev->board->name, ndev->board->slot);
+ dev_name(lp->device), ndev->board->name, ndev->board->slot);
printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
- lp->device->bus_id, SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset);
+ dev_name(lp->device), SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset);
#if 0 /* This is sometimes useful to find out how MacOS configured the card. */
- printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id,
+ printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", dev_name(lp->device),
SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff);
#endif
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 7e24b5048686..70d3ef4a2c5f 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -60,6 +60,47 @@ static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port,
return NULL;
}
+static void macvlan_hash_add(struct macvlan_dev *vlan)
+{
+ struct macvlan_port *port = vlan->port;
+ const unsigned char *addr = vlan->dev->dev_addr;
+
+ hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[addr[5]]);
+}
+
+static void macvlan_hash_del(struct macvlan_dev *vlan)
+{
+ hlist_del_rcu(&vlan->hlist);
+ synchronize_rcu();
+}
+
+static void macvlan_hash_change_addr(struct macvlan_dev *vlan,
+ const unsigned char *addr)
+{
+ macvlan_hash_del(vlan);
+ /* Now that we are unhashed it is safe to change the device
+ * address without confusing packet delivery.
+ */
+ memcpy(vlan->dev->dev_addr, addr, ETH_ALEN);
+ macvlan_hash_add(vlan);
+}
+
+static int macvlan_addr_busy(const struct macvlan_port *port,
+ const unsigned char *addr)
+{
+ /* Test to see if the specified multicast address is
+ * currently in use by the underlying device or
+ * another macvlan.
+ */
+ if (memcmp(port->dev->dev_addr, addr, ETH_ALEN) == 0)
+ return 1;
+
+ if (macvlan_hash_lookup(port, addr))
+ return 1;
+
+ return 0;
+}
+
static void macvlan_broadcast(struct sk_buff *skb,
const struct macvlan_port *port)
{
@@ -184,10 +225,13 @@ static const struct header_ops macvlan_hard_header_ops = {
static int macvlan_open(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
- struct macvlan_port *port = vlan->port;
struct net_device *lowerdev = vlan->lowerdev;
int err;
+ err = -EBUSY;
+ if (macvlan_addr_busy(vlan->port, dev->dev_addr))
+ goto out;
+
err = dev_unicast_add(lowerdev, dev->dev_addr, ETH_ALEN);
if (err < 0)
goto out;
@@ -196,8 +240,7 @@ static int macvlan_open(struct net_device *dev)
if (err < 0)
goto del_unicast;
}
-
- hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[dev->dev_addr[5]]);
+ macvlan_hash_add(vlan);
return 0;
del_unicast:
@@ -217,8 +260,7 @@ static int macvlan_stop(struct net_device *dev)
dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
- hlist_del_rcu(&vlan->hlist);
- synchronize_rcu();
+ macvlan_hash_del(vlan);
return 0;
}
@@ -232,16 +274,21 @@ static int macvlan_set_mac_address(struct net_device *dev, void *p)
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
- if (!(dev->flags & IFF_UP))
- goto out;
+ if (!(dev->flags & IFF_UP)) {
+ /* Just copy in the new address */
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+ } else {
+ /* Rehash and update the device filters */
+ if (macvlan_addr_busy(vlan->port, addr->sa_data))
+ return -EBUSY;
- err = dev_unicast_add(lowerdev, addr->sa_data, ETH_ALEN);
- if (err < 0)
- return err;
- dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+ if ((err = dev_unicast_add(lowerdev, addr->sa_data, ETH_ALEN)))
+ return err;
-out:
- memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+ dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+
+ macvlan_hash_change_addr(vlan, addr->sa_data);
+ }
return 0;
}
@@ -461,12 +508,13 @@ static int macvlan_newlink(struct net_device *dev,
if (lowerdev == NULL)
return -ENODEV;
- /* Don't allow macvlans on top of other macvlans - its not really
- * wrong, but lockdep can't handle it and its not useful for anything
- * you couldn't do directly on top of the real device.
+ /* When creating macvlans on top of other macvlans - use
+ * the real device as the lowerdev.
*/
- if (lowerdev->rtnl_link_ops == dev->rtnl_link_ops)
- return -ENODEV;
+ if (lowerdev->rtnl_link_ops == dev->rtnl_link_ops) {
+ struct macvlan_dev *lowervlan = netdev_priv(lowerdev);
+ lowerdev = lowervlan->lowerdev;
+ }
if (!tb[IFLA_MTU])
dev->mtu = lowerdev->mtu;
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index c336a1f42510..aa08987f6e81 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -398,7 +398,7 @@ static void meth_rx(struct net_device* dev, unsigned long int_status)
int len = (status & 0xffff) - 4; /* omit CRC */
/* length sanity check */
if (len < 60 || len > 1518) {
- printk(KERN_DEBUG "%s: bogus packet size: %ld, status=%#2lx.\n",
+ printk(KERN_DEBUG "%s: bogus packet size: %ld, status=%#2Lx.\n",
dev->name, priv->rx_write,
priv->rx_ring[priv->rx_write]->status.raw);
dev->stats.rx_errors++;
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index 4e7a5faf0351..664835b822fb 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -237,7 +237,7 @@ static void mipsnet_set_mclist(struct net_device *dev)
{
}
-static int __init mipsnet_probe(struct device *dev)
+static int __init mipsnet_probe(struct platform_device *dev)
{
struct net_device *netdev;
int err;
@@ -248,7 +248,7 @@ static int __init mipsnet_probe(struct device *dev)
goto out;
}
- dev_set_drvdata(dev, netdev);
+ platform_set_drvdata(dev, netdev);
netdev->open = mipsnet_open;
netdev->stop = mipsnet_close;
@@ -293,23 +293,25 @@ out:
return err;
}
-static int __devexit mipsnet_device_remove(struct device *device)
+static int __devexit mipsnet_device_remove(struct platform_device *device)
{
- struct net_device *dev = dev_get_drvdata(device);
+ struct net_device *dev = platform_get_drvdata(device);
unregister_netdev(dev);
release_region(dev->base_addr, sizeof(struct mipsnet_regs));
free_netdev(dev);
- dev_set_drvdata(device, NULL);
+ platform_set_drvdata(device, NULL);
return 0;
}
-static struct device_driver mipsnet_driver = {
- .name = mipsnet_string,
- .bus = &platform_bus_type,
- .probe = mipsnet_probe,
- .remove = __devexit_p(mipsnet_device_remove),
+static struct platform_driver mipsnet_driver = {
+ .driver = {
+ .name = mipsnet_string,
+ .owner = THIS_MODULE,
+ },
+ .probe = mipsnet_probe,
+ .remove = __devexit_p(mipsnet_device_remove),
};
static int __init mipsnet_init_module(void)
@@ -319,7 +321,7 @@ static int __init mipsnet_init_module(void)
printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. "
"(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION);
- err = driver_register(&mipsnet_driver);
+ err = platform_driver_register(&mipsnet_driver);
if (err)
printk(KERN_ERR "Driver registration failed\n");
@@ -328,7 +330,7 @@ static int __init mipsnet_init_module(void)
static void __exit mipsnet_exit_module(void)
{
- driver_unregister(&mipsnet_driver);
+ platform_driver_unregister(&mipsnet_driver);
}
module_init(mipsnet_init_module);
diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile
index a7a97bf998f8..21040a0d81fe 100644
--- a/drivers/net/mlx4/Makefile
+++ b/drivers/net/mlx4/Makefile
@@ -1,7 +1,7 @@
obj-$(CONFIG_MLX4_CORE) += mlx4_core.o
mlx4_core-y := alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \
- mr.o pd.o port.o profile.o qp.o reset.o srq.o
+ mr.o pd.o port.o profile.o qp.o reset.o sense.o srq.o
obj-$(CONFIG_MLX4_EN) += mlx4_en.o
diff --git a/drivers/net/mlx4/catas.c b/drivers/net/mlx4/catas.c
index f094ee00c416..aa9674b7f19c 100644
--- a/drivers/net/mlx4/catas.c
+++ b/drivers/net/mlx4/catas.c
@@ -42,7 +42,6 @@ enum {
static DEFINE_SPINLOCK(catas_lock);
static LIST_HEAD(catas_list);
-static struct workqueue_struct *catas_wq;
static struct work_struct catas_work;
static int internal_err_reset = 1;
@@ -77,7 +76,7 @@ static void poll_catas(unsigned long dev_ptr)
list_add(&priv->catas_err.list, &catas_list);
spin_unlock(&catas_lock);
- queue_work(catas_wq, &catas_work);
+ queue_work(mlx4_wq, &catas_work);
}
} else
mod_timer(&priv->catas_err.timer,
@@ -146,18 +145,7 @@ void mlx4_stop_catas_poll(struct mlx4_dev *dev)
spin_unlock_irq(&catas_lock);
}
-int __init mlx4_catas_init(void)
+void __init mlx4_catas_init(void)
{
INIT_WORK(&catas_work, catas_reset);
-
- catas_wq = create_singlethread_workqueue("mlx4_err");
- if (!catas_wq)
- return -ENOMEM;
-
- return 0;
-}
-
-void mlx4_catas_cleanup(void)
-{
- destroy_workqueue(catas_wq);
}
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index 9f6644a44030..303c23de6cac 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -505,7 +505,7 @@ out:
static void mlx4_en_do_get_stats(struct work_struct *work)
{
- struct delayed_work *delay = container_of(work, struct delayed_work, work);
+ struct delayed_work *delay = to_delayed_work(work);
struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv,
stats_task);
struct mlx4_en_dev *mdev = priv->mdev;
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index c61b0bdca1a4..7e40741fb7d8 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -298,7 +298,7 @@ static void mlx4_en_free_rx_buf(struct mlx4_en_priv *priv,
void mlx4_en_rx_refill(struct work_struct *work)
{
- struct delayed_work *delay = container_of(work, struct delayed_work, work);
+ struct delayed_work *delay = to_delayed_work(work);
struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv,
refill_task);
struct mlx4_en_dev *mdev = priv->mdev;
@@ -768,6 +768,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
skb->ip_summed = ip_summed;
skb->protocol = eth_type_trans(skb, dev);
+ skb_record_rx_queue(skb, cq->ring);
/* Push it up the stack */
if (priv->vlgrp && (be32_to_cpu(cqe->vlan_my_qpn) &
@@ -814,7 +815,7 @@ void mlx4_en_rx_irq(struct mlx4_cq *mcq)
struct mlx4_en_priv *priv = netdev_priv(cq->dev);
if (priv->port_up)
- netif_rx_schedule(&cq->napi);
+ napi_schedule(&cq->napi);
else
mlx4_en_arm_cq(priv, cq);
}
@@ -834,7 +835,7 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget)
INC_PERF_COUNTER(priv->pstats.napi_quota);
else {
/* Done for now */
- netif_rx_complete(napi);
+ napi_complete(napi);
mlx4_en_arm_cq(priv, cq);
}
return done;
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 2c19bff7cbab..8830dcb92ec8 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -163,6 +163,7 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
int cqn;
int eqes_found = 0;
int set_ci = 0;
+ int port;
while ((eqe = next_eqe_sw(eq))) {
/*
@@ -203,11 +204,16 @@ static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
break;
case MLX4_EVENT_TYPE_PORT_CHANGE:
- mlx4_dispatch_event(dev,
- eqe->subtype == MLX4_PORT_CHANGE_SUBTYPE_ACTIVE ?
- MLX4_DEV_EVENT_PORT_UP :
- MLX4_DEV_EVENT_PORT_DOWN,
- be32_to_cpu(eqe->event.port_change.port) >> 28);
+ port = be32_to_cpu(eqe->event.port_change.port) >> 28;
+ if (eqe->subtype == MLX4_PORT_CHANGE_SUBTYPE_DOWN) {
+ mlx4_dispatch_event(dev, MLX4_DEV_EVENT_PORT_DOWN,
+ port);
+ mlx4_priv(dev)->sense.do_sense_port[port] = 1;
+ } else {
+ mlx4_dispatch_event(dev, MLX4_DEV_EVENT_PORT_UP,
+ port);
+ mlx4_priv(dev)->sense.do_sense_port[port] = 0;
+ }
break;
case MLX4_EVENT_TYPE_CQ_ERROR:
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 6ef2490d5c3e..a66f5b2fd288 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -51,6 +51,8 @@ MODULE_DESCRIPTION("Mellanox ConnectX HCA low-level driver");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION(DRV_VERSION);
+struct workqueue_struct *mlx4_wq;
+
#ifdef CONFIG_MLX4_DEBUG
int mlx4_debug_level = 0;
@@ -98,24 +100,23 @@ module_param_named(use_prio, use_prio, bool, 0444);
MODULE_PARM_DESC(use_prio, "Enable steering by VLAN priority on ETH ports "
"(0/1, default 0)");
-static int mlx4_check_port_params(struct mlx4_dev *dev,
- enum mlx4_port_type *port_type)
+int mlx4_check_port_params(struct mlx4_dev *dev,
+ enum mlx4_port_type *port_type)
{
int i;
for (i = 0; i < dev->caps.num_ports - 1; i++) {
- if (port_type[i] != port_type[i+1] &&
- !(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) {
- mlx4_err(dev, "Only same port types supported "
- "on this HCA, aborting.\n");
- return -EINVAL;
+ if (port_type[i] != port_type[i + 1]) {
+ if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) {
+ mlx4_err(dev, "Only same port types supported "
+ "on this HCA, aborting.\n");
+ return -EINVAL;
+ }
+ if (port_type[i] == MLX4_PORT_TYPE_ETH &&
+ port_type[i + 1] == MLX4_PORT_TYPE_IB)
+ return -EINVAL;
}
}
- if ((port_type[0] == MLX4_PORT_TYPE_ETH) &&
- (port_type[1] == MLX4_PORT_TYPE_IB)) {
- mlx4_err(dev, "eth-ib configuration is not supported.\n");
- return -EINVAL;
- }
for (i = 0; i < dev->caps.num_ports; i++) {
if (!(port_type[i] & dev->caps.supported_type[i+1])) {
@@ -225,6 +226,9 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev->caps.port_type[i] = MLX4_PORT_TYPE_IB;
else
dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH;
+ dev->caps.possible_type[i] = dev->caps.port_type[i];
+ mlx4_priv(dev)->sense.sense_allowed[i] =
+ dev->caps.supported_type[i] == MLX4_PORT_TYPE_AUTO;
if (dev->caps.log_num_macs > dev_cap->log_max_macs[i]) {
dev->caps.log_num_macs = dev_cap->log_max_macs[i];
@@ -263,14 +267,16 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
* Change the port configuration of the device.
* Every user of this function must hold the port mutex.
*/
-static int mlx4_change_port_types(struct mlx4_dev *dev,
- enum mlx4_port_type *port_types)
+int mlx4_change_port_types(struct mlx4_dev *dev,
+ enum mlx4_port_type *port_types)
{
int err = 0;
int change = 0;
int port;
for (port = 0; port < dev->caps.num_ports; port++) {
+ /* Change the port type only if the new type is different
+ * from the current, and not set to Auto */
if (port_types[port] != dev->caps.port_type[port + 1]) {
change = 1;
dev->caps.port_type[port + 1] = port_types[port];
@@ -302,10 +308,17 @@ static ssize_t show_port_type(struct device *dev,
struct mlx4_port_info *info = container_of(attr, struct mlx4_port_info,
port_attr);
struct mlx4_dev *mdev = info->dev;
+ char type[8];
+
+ sprintf(type, "%s",
+ (mdev->caps.port_type[info->port] == MLX4_PORT_TYPE_IB) ?
+ "ib" : "eth");
+ if (mdev->caps.possible_type[info->port] == MLX4_PORT_TYPE_AUTO)
+ sprintf(buf, "auto (%s)\n", type);
+ else
+ sprintf(buf, "%s\n", type);
- return sprintf(buf, "%s\n",
- mdev->caps.port_type[info->port] == MLX4_PORT_TYPE_IB ?
- "ib" : "eth");
+ return strlen(buf);
}
static ssize_t set_port_type(struct device *dev,
@@ -317,6 +330,7 @@ static ssize_t set_port_type(struct device *dev,
struct mlx4_dev *mdev = info->dev;
struct mlx4_priv *priv = mlx4_priv(mdev);
enum mlx4_port_type types[MLX4_MAX_PORTS];
+ enum mlx4_port_type new_types[MLX4_MAX_PORTS];
int i;
int err = 0;
@@ -324,26 +338,56 @@ static ssize_t set_port_type(struct device *dev,
info->tmp_type = MLX4_PORT_TYPE_IB;
else if (!strcmp(buf, "eth\n"))
info->tmp_type = MLX4_PORT_TYPE_ETH;
+ else if (!strcmp(buf, "auto\n"))
+ info->tmp_type = MLX4_PORT_TYPE_AUTO;
else {
mlx4_err(mdev, "%s is not supported port type\n", buf);
return -EINVAL;
}
+ mlx4_stop_sense(mdev);
mutex_lock(&priv->port_mutex);
- for (i = 0; i < mdev->caps.num_ports; i++)
+ /* Possible type is always the one that was delivered */
+ mdev->caps.possible_type[info->port] = info->tmp_type;
+
+ for (i = 0; i < mdev->caps.num_ports; i++) {
types[i] = priv->port[i+1].tmp_type ? priv->port[i+1].tmp_type :
- mdev->caps.port_type[i+1];
+ mdev->caps.possible_type[i+1];
+ if (types[i] == MLX4_PORT_TYPE_AUTO)
+ types[i] = mdev->caps.port_type[i+1];
+ }
- err = mlx4_check_port_params(mdev, types);
+ if (!(mdev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP)) {
+ for (i = 1; i <= mdev->caps.num_ports; i++) {
+ if (mdev->caps.possible_type[i] == MLX4_PORT_TYPE_AUTO) {
+ mdev->caps.possible_type[i] = mdev->caps.port_type[i];
+ err = -EINVAL;
+ }
+ }
+ }
+ if (err) {
+ mlx4_err(mdev, "Auto sensing is not supported on this HCA. "
+ "Set only 'eth' or 'ib' for both ports "
+ "(should be the same)\n");
+ goto out;
+ }
+
+ mlx4_do_sense_ports(mdev, new_types, types);
+
+ err = mlx4_check_port_params(mdev, new_types);
if (err)
goto out;
- for (i = 1; i <= mdev->caps.num_ports; i++)
- priv->port[i].tmp_type = 0;
+ /* We are about to apply the changes after the configuration
+ * was verified, no need to remember the temporary types
+ * any more */
+ for (i = 0; i < mdev->caps.num_ports; i++)
+ priv->port[i + 1].tmp_type = 0;
- err = mlx4_change_port_types(mdev, types);
+ err = mlx4_change_port_types(mdev, new_types);
out:
+ mlx4_start_sense(mdev);
mutex_unlock(&priv->port_mutex);
return err ? err : count;
}
@@ -1117,6 +1161,9 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (err)
goto err_port;
+ mlx4_sense_init(dev);
+ mlx4_start_sense(dev);
+
pci_set_drvdata(pdev, dev);
return 0;
@@ -1182,6 +1229,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
int p;
if (dev) {
+ mlx4_stop_sense(dev);
mlx4_unregister_device(dev);
for (p = 1; p <= dev->caps.num_ports; p++) {
@@ -1230,6 +1278,8 @@ static struct pci_device_id mlx4_pci_table[] = {
{ PCI_VDEVICE(MELLANOX, 0x673c) }, /* MT25408 "Hermon" QDR PCIe gen2 */
{ PCI_VDEVICE(MELLANOX, 0x6368) }, /* MT25408 "Hermon" EN 10GigE */
{ PCI_VDEVICE(MELLANOX, 0x6750) }, /* MT25408 "Hermon" EN 10GigE PCIe gen2 */
+ { PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */
+ { PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */
{ 0, }
};
@@ -1264,9 +1314,11 @@ static int __init mlx4_init(void)
if (mlx4_verify_params())
return -EINVAL;
- ret = mlx4_catas_init();
- if (ret)
- return ret;
+ mlx4_catas_init();
+
+ mlx4_wq = create_singlethread_workqueue("mlx4");
+ if (!mlx4_wq)
+ return -ENOMEM;
ret = pci_register_driver(&mlx4_driver);
return ret < 0 ? ret : 0;
@@ -1275,7 +1327,7 @@ static int __init mlx4_init(void)
static void __exit mlx4_cleanup(void)
{
pci_unregister_driver(&mlx4_driver);
- mlx4_catas_cleanup();
+ destroy_workqueue(mlx4_wq);
}
module_init(mlx4_init);
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index e0213bad61c7..5bd79c2b184f 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -40,6 +40,7 @@
#include <linux/mutex.h>
#include <linux/radix-tree.h>
#include <linux/timer.h>
+#include <linux/workqueue.h>
#include <linux/mlx4/device.h>
#include <linux/mlx4/driver.h>
@@ -276,6 +277,13 @@ struct mlx4_port_info {
struct mlx4_vlan_table vlan_table;
};
+struct mlx4_sense {
+ struct mlx4_dev *dev;
+ u8 do_sense_port[MLX4_MAX_PORTS + 1];
+ u8 sense_allowed[MLX4_MAX_PORTS + 1];
+ struct delayed_work sense_poll;
+};
+
struct mlx4_priv {
struct mlx4_dev dev;
@@ -305,6 +313,7 @@ struct mlx4_priv {
struct mlx4_uar driver_uar;
void __iomem *kar;
struct mlx4_port_info port[MLX4_MAX_PORTS + 1];
+ struct mlx4_sense sense;
struct mutex port_mutex;
};
@@ -313,6 +322,10 @@ static inline struct mlx4_priv *mlx4_priv(struct mlx4_dev *dev)
return container_of(dev, struct mlx4_priv, dev);
}
+#define MLX4_SENSE_RANGE (HZ * 3)
+
+extern struct workqueue_struct *mlx4_wq;
+
u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap);
void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj);
u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align);
@@ -346,8 +359,7 @@ void mlx4_cleanup_mcg_table(struct mlx4_dev *dev);
void mlx4_start_catas_poll(struct mlx4_dev *dev);
void mlx4_stop_catas_poll(struct mlx4_dev *dev);
-int mlx4_catas_init(void);
-void mlx4_catas_cleanup(void);
+void mlx4_catas_init(void);
int mlx4_restart_one(struct pci_dev *pdev);
int mlx4_register_device(struct mlx4_dev *dev);
void mlx4_unregister_device(struct mlx4_dev *dev);
@@ -379,6 +391,17 @@ void mlx4_srq_event(struct mlx4_dev *dev, u32 srqn, int event_type);
void mlx4_handle_catas_err(struct mlx4_dev *dev);
+void mlx4_do_sense_ports(struct mlx4_dev *dev,
+ enum mlx4_port_type *stype,
+ enum mlx4_port_type *defaults);
+void mlx4_start_sense(struct mlx4_dev *dev);
+void mlx4_stop_sense(struct mlx4_dev *dev);
+void mlx4_sense_init(struct mlx4_dev *dev);
+int mlx4_check_port_params(struct mlx4_dev *dev,
+ enum mlx4_port_type *port_type);
+int mlx4_change_port_types(struct mlx4_dev *dev,
+ enum mlx4_port_type *port_types);
+
void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table);
void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table);
diff --git a/drivers/net/mlx4/port.c b/drivers/net/mlx4/port.c
index 0a057e5dc63b..7cce3342ef8c 100644
--- a/drivers/net/mlx4/port.c
+++ b/drivers/net/mlx4/port.c
@@ -298,20 +298,17 @@ int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
{
struct mlx4_cmd_mailbox *mailbox;
int err;
- u8 is_eth = dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH;
mailbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(mailbox))
return PTR_ERR(mailbox);
memset(mailbox->buf, 0, 256);
- if (is_eth) {
- ((u8 *) mailbox->buf)[3] = 6;
- ((__be16 *) mailbox->buf)[4] = cpu_to_be16(1 << 15);
- ((__be16 *) mailbox->buf)[6] = cpu_to_be16(1 << 15);
- } else
- ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
- err = mlx4_cmd(dev, mailbox->dma, port, is_eth, MLX4_CMD_SET_PORT,
+ if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH)
+ return 0;
+
+ ((__be32 *) mailbox->buf)[1] = dev->caps.ib_port_def_cap[port];
+ err = mlx4_cmd(dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT,
MLX4_CMD_TIME_CLASS_B);
mlx4_free_cmd_mailbox(dev, mailbox);
diff --git a/drivers/net/mlx4/sense.c b/drivers/net/mlx4/sense.c
new file mode 100644
index 000000000000..f36ae691cab3
--- /dev/null
+++ b/drivers/net/mlx4/sense.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/if_ether.h>
+
+#include <linux/mlx4/cmd.h>
+
+#include "mlx4.h"
+
+static int mlx4_SENSE_PORT(struct mlx4_dev *dev, int port,
+ enum mlx4_port_type *type)
+{
+ u64 out_param;
+ int err = 0;
+
+ err = mlx4_cmd_imm(dev, 0, &out_param, port, 0,
+ MLX4_CMD_SENSE_PORT, MLX4_CMD_TIME_CLASS_B);
+ if (err) {
+ mlx4_err(dev, "Sense command failed for port: %d\n", port);
+ return err;
+ }
+
+ if (out_param > 2) {
+ mlx4_err(dev, "Sense returned illegal value: 0x%llx\n", out_param);
+ return EINVAL;
+ }
+
+ *type = out_param;
+ return 0;
+}
+
+void mlx4_do_sense_ports(struct mlx4_dev *dev,
+ enum mlx4_port_type *stype,
+ enum mlx4_port_type *defaults)
+{
+ struct mlx4_sense *sense = &mlx4_priv(dev)->sense;
+ int err;
+ int i;
+
+ for (i = 1; i <= dev->caps.num_ports; i++) {
+ stype[i - 1] = 0;
+ if (sense->do_sense_port[i] && sense->sense_allowed[i] &&
+ dev->caps.possible_type[i] == MLX4_PORT_TYPE_AUTO) {
+ err = mlx4_SENSE_PORT(dev, i, &stype[i - 1]);
+ if (err)
+ stype[i - 1] = defaults[i - 1];
+ } else
+ stype[i - 1] = defaults[i - 1];
+ }
+
+ /*
+ * Adjust port configuration:
+ * If port 1 sensed nothing and port 2 is IB, set both as IB
+ * If port 2 sensed nothing and port 1 is Eth, set both as Eth
+ */
+ if (stype[0] == MLX4_PORT_TYPE_ETH) {
+ for (i = 1; i < dev->caps.num_ports; i++)
+ stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_ETH;
+ }
+ if (stype[dev->caps.num_ports - 1] == MLX4_PORT_TYPE_IB) {
+ for (i = 0; i < dev->caps.num_ports - 1; i++)
+ stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_IB;
+ }
+
+ /*
+ * If sensed nothing, remain in current configuration.
+ */
+ for (i = 0; i < dev->caps.num_ports; i++)
+ stype[i] = stype[i] ? stype[i] : defaults[i];
+
+}
+
+static void mlx4_sense_port(struct work_struct *work)
+{
+ struct delayed_work *delay = to_delayed_work(work);
+ struct mlx4_sense *sense = container_of(delay, struct mlx4_sense,
+ sense_poll);
+ struct mlx4_dev *dev = sense->dev;
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ enum mlx4_port_type stype[MLX4_MAX_PORTS];
+
+ mutex_lock(&priv->port_mutex);
+ mlx4_do_sense_ports(dev, stype, &dev->caps.port_type[1]);
+
+ if (mlx4_check_port_params(dev, stype))
+ goto sense_again;
+
+ if (mlx4_change_port_types(dev, stype))
+ mlx4_err(dev, "Failed to change port_types\n");
+
+sense_again:
+ mutex_unlock(&priv->port_mutex);
+ queue_delayed_work(mlx4_wq , &sense->sense_poll,
+ round_jiffies_relative(MLX4_SENSE_RANGE));
+}
+
+void mlx4_start_sense(struct mlx4_dev *dev)
+{
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ struct mlx4_sense *sense = &priv->sense;
+
+ if (!(dev->caps.flags & MLX4_DEV_CAP_FLAG_DPDP))
+ return;
+
+ queue_delayed_work(mlx4_wq , &sense->sense_poll,
+ round_jiffies_relative(MLX4_SENSE_RANGE));
+}
+
+void mlx4_stop_sense(struct mlx4_dev *dev)
+{
+ cancel_delayed_work_sync(&mlx4_priv(dev)->sense.sense_poll);
+}
+
+void mlx4_sense_init(struct mlx4_dev *dev)
+{
+ struct mlx4_priv *priv = mlx4_priv(dev);
+ struct mlx4_sense *sense = &priv->sense;
+ int port;
+
+ sense->dev = dev;
+ for (port = 1; port <= dev->caps.num_ports; port++)
+ sense->do_sense_port[port] = 1;
+
+ INIT_DELAYED_WORK_DEFERRABLE(&sense->sense_poll, mlx4_sense_port);
+}
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index b0bc3bc18e9c..a56d9d2df73f 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -53,6 +53,7 @@
#include <linux/mv643xx_eth.h>
#include <linux/io.h>
#include <linux/types.h>
+#include <linux/inet_lro.h>
#include <asm/system.h>
static char mv643xx_eth_driver_name[] = "mv643xx_eth";
@@ -227,6 +228,12 @@ struct tx_desc {
#define RX_ENABLE_INTERRUPT 0x20000000
#define RX_FIRST_DESC 0x08000000
#define RX_LAST_DESC 0x04000000
+#define RX_IP_HDR_OK 0x02000000
+#define RX_PKT_IS_IPV4 0x01000000
+#define RX_PKT_IS_ETHERNETV2 0x00800000
+#define RX_PKT_LAYER4_TYPE_MASK 0x00600000
+#define RX_PKT_LAYER4_TYPE_TCP_IPV4 0x00000000
+#define RX_PKT_IS_VLAN_TAGGED 0x00080000
/* TX descriptor command */
#define TX_ENABLE_INTERRUPT 0x00800000
@@ -286,6 +293,9 @@ struct mv643xx_eth_shared_private {
#define TX_BW_CONTROL_OLD_LAYOUT 1
#define TX_BW_CONTROL_NEW_LAYOUT 2
+static int mv643xx_eth_open(struct net_device *dev);
+static int mv643xx_eth_stop(struct net_device *dev);
+
/* per-port *****************************************************************/
struct mib_counters {
@@ -321,6 +331,12 @@ struct mib_counters {
u32 late_collision;
};
+struct lro_counters {
+ u32 lro_aggregated;
+ u32 lro_flushed;
+ u32 lro_no_desc;
+};
+
struct rx_queue {
int index;
@@ -334,6 +350,9 @@ struct rx_queue {
dma_addr_t rx_desc_dma;
int rx_desc_area_size;
struct sk_buff **rx_skb;
+
+ struct net_lro_mgr lro_mgr;
+ struct net_lro_desc lro_arr[8];
};
struct tx_queue {
@@ -369,6 +388,8 @@ struct mv643xx_eth_private {
spinlock_t mib_counters_lock;
struct mib_counters mib_counters;
+ struct lro_counters lro_counters;
+
struct work_struct tx_timeout_task;
struct napi_struct napi;
@@ -385,7 +406,7 @@ struct mv643xx_eth_private {
/*
* RX state.
*/
- int default_rx_ring_size;
+ int rx_ring_size;
unsigned long rx_desc_sram_addr;
int rx_desc_sram_size;
int rxq_count;
@@ -395,7 +416,7 @@ struct mv643xx_eth_private {
/*
* TX state.
*/
- int default_tx_ring_size;
+ int tx_ring_size;
unsigned long tx_desc_sram_addr;
int tx_desc_sram_size;
int txq_count;
@@ -493,12 +514,40 @@ static void txq_maybe_wake(struct tx_queue *txq)
/* rx napi ******************************************************************/
+static int
+mv643xx_get_skb_header(struct sk_buff *skb, void **iphdr, void **tcph,
+ u64 *hdr_flags, void *priv)
+{
+ unsigned long cmd_sts = (unsigned long)priv;
+
+ /*
+ * Make sure that this packet is Ethernet II, is not VLAN
+ * tagged, is IPv4, has a valid IP header, and is TCP.
+ */
+ if ((cmd_sts & (RX_IP_HDR_OK | RX_PKT_IS_IPV4 |
+ RX_PKT_IS_ETHERNETV2 | RX_PKT_LAYER4_TYPE_MASK |
+ RX_PKT_IS_VLAN_TAGGED)) !=
+ (RX_IP_HDR_OK | RX_PKT_IS_IPV4 |
+ RX_PKT_IS_ETHERNETV2 | RX_PKT_LAYER4_TYPE_TCP_IPV4))
+ return -1;
+
+ skb_reset_network_header(skb);
+ skb_set_transport_header(skb, ip_hdrlen(skb));
+ *iphdr = ip_hdr(skb);
+ *tcph = tcp_hdr(skb);
+ *hdr_flags = LRO_IPV4 | LRO_TCP;
+
+ return 0;
+}
+
static int rxq_process(struct rx_queue *rxq, int budget)
{
struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
struct net_device_stats *stats = &mp->dev->stats;
+ int lro_flush_needed;
int rx;
+ lro_flush_needed = 0;
rx = 0;
while (rx < budget && rxq->rx_desc_count) {
struct rx_desc *rx_desc;
@@ -558,7 +607,13 @@ static int rxq_process(struct rx_queue *rxq, int budget)
if (cmd_sts & LAYER_4_CHECKSUM_OK)
skb->ip_summed = CHECKSUM_UNNECESSARY;
skb->protocol = eth_type_trans(skb, mp->dev);
- netif_receive_skb(skb);
+
+ if (skb->dev->features & NETIF_F_LRO &&
+ skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ lro_receive_skb(&rxq->lro_mgr, skb, (void *)cmd_sts);
+ lro_flush_needed = 1;
+ } else
+ netif_receive_skb(skb);
continue;
@@ -579,6 +634,9 @@ err:
dev_kfree_skb(skb);
}
+ if (lro_flush_needed)
+ lro_flush_all(&rxq->lro_mgr);
+
if (rx < budget)
mp->work_rx &= ~(1 << rxq->index);
@@ -907,7 +965,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force)
if (skb != NULL) {
if (skb_queue_len(&mp->rx_recycle) <
- mp->default_rx_ring_size &&
+ mp->rx_ring_size &&
skb_recycle_check(skb, mp->skb_size +
dma_get_cache_alignment() - 1))
__skb_queue_head(&mp->rx_recycle, skb);
@@ -1158,6 +1216,26 @@ static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev)
return stats;
}
+static void mv643xx_eth_grab_lro_stats(struct mv643xx_eth_private *mp)
+{
+ u32 lro_aggregated = 0;
+ u32 lro_flushed = 0;
+ u32 lro_no_desc = 0;
+ int i;
+
+ for (i = 0; i < mp->rxq_count; i++) {
+ struct rx_queue *rxq = mp->rxq + i;
+
+ lro_aggregated += rxq->lro_mgr.stats.aggregated;
+ lro_flushed += rxq->lro_mgr.stats.flushed;
+ lro_no_desc += rxq->lro_mgr.stats.no_desc;
+ }
+
+ mp->lro_counters.lro_aggregated = lro_aggregated;
+ mp->lro_counters.lro_flushed = lro_flushed;
+ mp->lro_counters.lro_no_desc = lro_no_desc;
+}
+
static inline u32 mib_read(struct mv643xx_eth_private *mp, int offset)
{
return rdl(mp, MIB_COUNTERS(mp->port_num) + offset);
@@ -1221,6 +1299,85 @@ static void mib_counters_timer_wrapper(unsigned long _mp)
}
+/* interrupt coalescing *****************************************************/
+/*
+ * Hardware coalescing parameters are set in units of 64 t_clk
+ * cycles. I.e.:
+ *
+ * coal_delay_in_usec = 64000000 * register_value / t_clk_rate
+ *
+ * register_value = coal_delay_in_usec * t_clk_rate / 64000000
+ *
+ * In the ->set*() methods, we round the computed register value
+ * to the nearest integer.
+ */
+static unsigned int get_rx_coal(struct mv643xx_eth_private *mp)
+{
+ u32 val = rdlp(mp, SDMA_CONFIG);
+ u64 temp;
+
+ if (mp->shared->extended_rx_coal_limit)
+ temp = ((val & 0x02000000) >> 10) | ((val & 0x003fff80) >> 7);
+ else
+ temp = (val & 0x003fff00) >> 8;
+
+ temp *= 64000000;
+ do_div(temp, mp->shared->t_clk);
+
+ return (unsigned int)temp;
+}
+
+static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int usec)
+{
+ u64 temp;
+ u32 val;
+
+ temp = (u64)usec * mp->shared->t_clk;
+ temp += 31999999;
+ do_div(temp, 64000000);
+
+ val = rdlp(mp, SDMA_CONFIG);
+ if (mp->shared->extended_rx_coal_limit) {
+ if (temp > 0xffff)
+ temp = 0xffff;
+ val &= ~0x023fff80;
+ val |= (temp & 0x8000) << 10;
+ val |= (temp & 0x7fff) << 7;
+ } else {
+ if (temp > 0x3fff)
+ temp = 0x3fff;
+ val &= ~0x003fff00;
+ val |= (temp & 0x3fff) << 8;
+ }
+ wrlp(mp, SDMA_CONFIG, val);
+}
+
+static unsigned int get_tx_coal(struct mv643xx_eth_private *mp)
+{
+ u64 temp;
+
+ temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4;
+ temp *= 64000000;
+ do_div(temp, mp->shared->t_clk);
+
+ return (unsigned int)temp;
+}
+
+static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int usec)
+{
+ u64 temp;
+
+ temp = (u64)usec * mp->shared->t_clk;
+ temp += 31999999;
+ do_div(temp, 64000000);
+
+ if (temp > 0x3fff)
+ temp = 0x3fff;
+
+ wrlp(mp, TX_FIFO_URGENT_THRESHOLD, temp << 4);
+}
+
+
/* ethtool ******************************************************************/
struct mv643xx_eth_stats {
char stat_string[ETH_GSTRING_LEN];
@@ -1237,6 +1394,10 @@ struct mv643xx_eth_stats {
{ #m, FIELD_SIZEOF(struct mib_counters, m), \
-1, offsetof(struct mv643xx_eth_private, mib_counters.m) }
+#define LROSTAT(m) \
+ { #m, FIELD_SIZEOF(struct lro_counters, m), \
+ -1, offsetof(struct mv643xx_eth_private, lro_counters.m) }
+
static const struct mv643xx_eth_stats mv643xx_eth_stats[] = {
SSTAT(rx_packets),
SSTAT(tx_packets),
@@ -1276,12 +1437,15 @@ static const struct mv643xx_eth_stats mv643xx_eth_stats[] = {
MIBSTAT(bad_crc_event),
MIBSTAT(collision),
MIBSTAT(late_collision),
+ LROSTAT(lro_aggregated),
+ LROSTAT(lro_flushed),
+ LROSTAT(lro_no_desc),
};
static int
-mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+mv643xx_eth_get_settings_phy(struct mv643xx_eth_private *mp,
+ struct ethtool_cmd *cmd)
{
- struct mv643xx_eth_private *mp = netdev_priv(dev);
int err;
err = phy_read_status(mp->phy);
@@ -1298,10 +1462,9 @@ mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
}
static int
-mv643xx_eth_get_settings_phyless(struct net_device *dev,
+mv643xx_eth_get_settings_phyless(struct mv643xx_eth_private *mp,
struct ethtool_cmd *cmd)
{
- struct mv643xx_eth_private *mp = netdev_priv(dev);
u32 port_status;
port_status = rdlp(mp, PORT_STATUS);
@@ -1334,10 +1497,24 @@ mv643xx_eth_get_settings_phyless(struct net_device *dev,
}
static int
+mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ if (mp->phy != NULL)
+ return mv643xx_eth_get_settings_phy(mp, cmd);
+ else
+ return mv643xx_eth_get_settings_phyless(mp, cmd);
+}
+
+static int
mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);
+ if (mp->phy == NULL)
+ return -EINVAL;
+
/*
* The MAC does not support 1000baseT_Half.
*/
@@ -1346,13 +1523,6 @@ mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return phy_ethtool_sset(mp->phy, cmd);
}
-static int
-mv643xx_eth_set_settings_phyless(struct net_device *dev,
- struct ethtool_cmd *cmd)
-{
- return -EINVAL;
-}
-
static void mv643xx_eth_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *drvinfo)
{
@@ -1367,17 +1537,95 @@ static int mv643xx_eth_nway_reset(struct net_device *dev)
{
struct mv643xx_eth_private *mp = netdev_priv(dev);
+ if (mp->phy == NULL)
+ return -EINVAL;
+
return genphy_restart_aneg(mp->phy);
}
-static int mv643xx_eth_nway_reset_phyless(struct net_device *dev)
+static u32 mv643xx_eth_get_link(struct net_device *dev)
{
- return -EINVAL;
+ return !!netif_carrier_ok(dev);
}
-static u32 mv643xx_eth_get_link(struct net_device *dev)
+static int
+mv643xx_eth_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
{
- return !!netif_carrier_ok(dev);
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ ec->rx_coalesce_usecs = get_rx_coal(mp);
+ ec->tx_coalesce_usecs = get_tx_coal(mp);
+
+ return 0;
+}
+
+static int
+mv643xx_eth_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ set_rx_coal(mp, ec->rx_coalesce_usecs);
+ set_tx_coal(mp, ec->tx_coalesce_usecs);
+
+ return 0;
+}
+
+static void
+mv643xx_eth_get_ringparam(struct net_device *dev, struct ethtool_ringparam *er)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ er->rx_max_pending = 4096;
+ er->tx_max_pending = 4096;
+ er->rx_mini_max_pending = 0;
+ er->rx_jumbo_max_pending = 0;
+
+ er->rx_pending = mp->rx_ring_size;
+ er->tx_pending = mp->tx_ring_size;
+ er->rx_mini_pending = 0;
+ er->rx_jumbo_pending = 0;
+}
+
+static int
+mv643xx_eth_set_ringparam(struct net_device *dev, struct ethtool_ringparam *er)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ if (er->rx_mini_pending || er->rx_jumbo_pending)
+ return -EINVAL;
+
+ mp->rx_ring_size = er->rx_pending < 4096 ? er->rx_pending : 4096;
+ mp->tx_ring_size = er->tx_pending < 4096 ? er->tx_pending : 4096;
+
+ if (netif_running(dev)) {
+ mv643xx_eth_stop(dev);
+ if (mv643xx_eth_open(dev)) {
+ dev_printk(KERN_ERR, &dev->dev,
+ "fatal error on re-opening device after "
+ "ring param change\n");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+static u32
+mv643xx_eth_get_rx_csum(struct net_device *dev)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ return !!(rdlp(mp, PORT_CONFIG) & 0x02000000);
+}
+
+static int
+mv643xx_eth_set_rx_csum(struct net_device *dev, u32 rx_csum)
+{
+ struct mv643xx_eth_private *mp = netdev_priv(dev);
+
+ wrlp(mp, PORT_CONFIG, rx_csum ? 0x02000000 : 0x00000000);
+
+ return 0;
}
static void mv643xx_eth_get_strings(struct net_device *dev,
@@ -1403,6 +1651,7 @@ static void mv643xx_eth_get_ethtool_stats(struct net_device *dev,
mv643xx_eth_get_stats(dev);
mib_counters_update(mp);
+ mv643xx_eth_grab_lro_stats(mp);
for (i = 0; i < ARRAY_SIZE(mv643xx_eth_stats); i++) {
const struct mv643xx_eth_stats *stat;
@@ -1434,21 +1683,18 @@ static const struct ethtool_ops mv643xx_eth_ethtool_ops = {
.get_drvinfo = mv643xx_eth_get_drvinfo,
.nway_reset = mv643xx_eth_nway_reset,
.get_link = mv643xx_eth_get_link,
+ .get_coalesce = mv643xx_eth_get_coalesce,
+ .set_coalesce = mv643xx_eth_set_coalesce,
+ .get_ringparam = mv643xx_eth_get_ringparam,
+ .set_ringparam = mv643xx_eth_set_ringparam,
+ .get_rx_csum = mv643xx_eth_get_rx_csum,
+ .set_rx_csum = mv643xx_eth_set_rx_csum,
+ .set_tx_csum = ethtool_op_set_tx_csum,
.set_sg = ethtool_op_set_sg,
.get_strings = mv643xx_eth_get_strings,
.get_ethtool_stats = mv643xx_eth_get_ethtool_stats,
- .get_sset_count = mv643xx_eth_get_sset_count,
-};
-
-static const struct ethtool_ops mv643xx_eth_ethtool_ops_phyless = {
- .get_settings = mv643xx_eth_get_settings_phyless,
- .set_settings = mv643xx_eth_set_settings_phyless,
- .get_drvinfo = mv643xx_eth_get_drvinfo,
- .nway_reset = mv643xx_eth_nway_reset_phyless,
- .get_link = mv643xx_eth_get_link,
- .set_sg = ethtool_op_set_sg,
- .get_strings = mv643xx_eth_get_strings,
- .get_ethtool_stats = mv643xx_eth_get_ethtool_stats,
+ .get_flags = ethtool_op_get_flags,
+ .set_flags = ethtool_op_set_flags,
.get_sset_count = mv643xx_eth_get_sset_count,
};
@@ -1637,7 +1883,7 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index)
rxq->index = index;
- rxq->rx_ring_size = mp->default_rx_ring_size;
+ rxq->rx_ring_size = mp->rx_ring_size;
rxq->rx_desc_count = 0;
rxq->rx_curr_desc = 0;
@@ -1683,6 +1929,19 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index)
nexti * sizeof(struct rx_desc);
}
+ rxq->lro_mgr.dev = mp->dev;
+ memset(&rxq->lro_mgr.stats, 0, sizeof(rxq->lro_mgr.stats));
+ rxq->lro_mgr.features = LRO_F_NAPI;
+ rxq->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
+ rxq->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
+ rxq->lro_mgr.max_desc = ARRAY_SIZE(rxq->lro_arr);
+ rxq->lro_mgr.max_aggr = 32;
+ rxq->lro_mgr.frag_align_pad = 0;
+ rxq->lro_mgr.lro_arr = rxq->lro_arr;
+ rxq->lro_mgr.get_skb_header = mv643xx_get_skb_header;
+
+ memset(&rxq->lro_arr, 0, sizeof(rxq->lro_arr));
+
return 0;
@@ -1737,7 +1996,7 @@ static int txq_init(struct mv643xx_eth_private *mp, int index)
txq->index = index;
- txq->tx_ring_size = mp->default_tx_ring_size;
+ txq->tx_ring_size = mp->tx_ring_size;
txq->tx_desc_count = 0;
txq->tx_curr_desc = 0;
@@ -2061,36 +2320,6 @@ static void port_start(struct mv643xx_eth_private *mp)
}
}
-static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int delay)
-{
- unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
- u32 val;
-
- val = rdlp(mp, SDMA_CONFIG);
- if (mp->shared->extended_rx_coal_limit) {
- if (coal > 0xffff)
- coal = 0xffff;
- val &= ~0x023fff80;
- val |= (coal & 0x8000) << 10;
- val |= (coal & 0x7fff) << 7;
- } else {
- if (coal > 0x3fff)
- coal = 0x3fff;
- val &= ~0x003fff00;
- val |= (coal & 0x3fff) << 8;
- }
- wrlp(mp, SDMA_CONFIG, val);
-}
-
-static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int delay)
-{
- unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
-
- if (coal > 0x3fff)
- coal = 0x3fff;
- wrlp(mp, TX_FIFO_URGENT_THRESHOLD, (coal & 0x3fff) << 4);
-}
-
static void mv643xx_eth_recalc_skb_size(struct mv643xx_eth_private *mp)
{
int skb_size;
@@ -2159,13 +2388,8 @@ static int mv643xx_eth_open(struct net_device *dev)
}
}
- netif_carrier_off(dev);
-
port_start(mp);
- set_rx_coal(mp, 0);
- set_tx_coal(mp, 0);
-
wrlp(mp, INT_MASK_EXT, INT_EXT_LINK_PHY | INT_EXT_TX);
wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
@@ -2531,17 +2755,17 @@ static void set_params(struct mv643xx_eth_private *mp,
else
uc_addr_get(mp, dev->dev_addr);
- mp->default_rx_ring_size = DEFAULT_RX_QUEUE_SIZE;
+ mp->rx_ring_size = DEFAULT_RX_QUEUE_SIZE;
if (pd->rx_queue_size)
- mp->default_rx_ring_size = pd->rx_queue_size;
+ mp->rx_ring_size = pd->rx_queue_size;
mp->rx_desc_sram_addr = pd->rx_sram_addr;
mp->rx_desc_sram_size = pd->rx_sram_size;
mp->rxq_count = pd->rx_queue_count ? : 1;
- mp->default_tx_ring_size = DEFAULT_TX_QUEUE_SIZE;
+ mp->tx_ring_size = DEFAULT_TX_QUEUE_SIZE;
if (pd->tx_queue_size)
- mp->default_tx_ring_size = pd->tx_queue_size;
+ mp->tx_ring_size = pd->tx_queue_size;
mp->tx_desc_sram_addr = pd->tx_sram_addr;
mp->tx_desc_sram_size = pd->tx_sram_size;
@@ -2588,7 +2812,7 @@ static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex)
phy_reset(mp);
- phy_attach(mp->dev, phy->dev.bus_id, 0, PHY_INTERFACE_MODE_GMII);
+ phy_attach(mp->dev, dev_name(&phy->dev), 0, PHY_INTERFACE_MODE_GMII);
if (speed == 0) {
phy->autoneg = AUTONEG_ENABLE;
@@ -2632,6 +2856,21 @@ static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
wrlp(mp, PORT_SERIAL_CONTROL, pscr);
}
+static const struct net_device_ops mv643xx_eth_netdev_ops = {
+ .ndo_open = mv643xx_eth_open,
+ .ndo_stop = mv643xx_eth_stop,
+ .ndo_start_xmit = mv643xx_eth_xmit,
+ .ndo_set_rx_mode = mv643xx_eth_set_rx_mode,
+ .ndo_set_mac_address = mv643xx_eth_set_mac_address,
+ .ndo_do_ioctl = mv643xx_eth_ioctl,
+ .ndo_change_mtu = mv643xx_eth_change_mtu,
+ .ndo_tx_timeout = mv643xx_eth_tx_timeout,
+ .ndo_get_stats = mv643xx_eth_get_stats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = mv643xx_eth_netpoll,
+#endif
+};
+
static int mv643xx_eth_probe(struct platform_device *pdev)
{
struct mv643xx_eth_platform_data *pd;
@@ -2672,12 +2911,10 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
if (pd->phy_addr != MV643XX_ETH_PHY_NONE)
mp->phy = phy_scan(mp, pd->phy_addr);
- if (mp->phy != NULL) {
+ if (mp->phy != NULL)
phy_init(mp, pd->speed, pd->duplex);
- SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops);
- } else {
- SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops_phyless);
- }
+
+ SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops);
init_pscr(mp, pd->speed, pd->duplex);
@@ -2705,18 +2942,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
BUG_ON(!res);
dev->irq = res->start;
- dev->get_stats = mv643xx_eth_get_stats;
- dev->hard_start_xmit = mv643xx_eth_xmit;
- dev->open = mv643xx_eth_open;
- dev->stop = mv643xx_eth_stop;
- dev->set_rx_mode = mv643xx_eth_set_rx_mode;
- dev->set_mac_address = mv643xx_eth_set_mac_address;
- dev->do_ioctl = mv643xx_eth_ioctl;
- dev->change_mtu = mv643xx_eth_change_mtu;
- dev->tx_timeout = mv643xx_eth_tx_timeout;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = mv643xx_eth_netpoll;
-#endif
+ dev->netdev_ops = &mv643xx_eth_netdev_ops;
+
dev->watchdog_timeo = 2 * HZ;
dev->base_addr = 0;
@@ -2728,6 +2955,11 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
if (mp->shared->win_protect)
wrl(mp, WINDOW_PROTECT(mp->port_num), mp->shared->win_protect);
+ netif_carrier_off(dev);
+
+ set_rx_coal(mp, 250);
+ set_tx_coal(mp, 0);
+
err = register_netdev(dev);
if (err)
goto out;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index e9c1296b267e..aea9fdaa3cd5 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1324,6 +1324,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
skb_shinfo(skb)->nr_frags = 0;
}
skb->protocol = eth_type_trans(skb, dev);
+ skb_record_rx_queue(skb, ss - &mgp->ss[0]);
if (mgp->csum_flag) {
if ((skb->protocol == htons(ETH_P_IP)) ||
@@ -1514,7 +1515,7 @@ static int myri10ge_poll(struct napi_struct *napi, int budget)
work_done = myri10ge_clean_rx_done(ss, budget);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
put_be32(htonl(3), ss->irq_claim);
}
return work_done;
@@ -1532,7 +1533,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
/* an interrupt on a non-zero receive-only slice is implicitly
* valid since MSI-X irqs are not shared */
if ((mgp->dev->real_num_tx_queues == 1) && (ss != mgp->ss)) {
- netif_rx_schedule(&ss->napi);
+ napi_schedule(&ss->napi);
return (IRQ_HANDLED);
}
@@ -1543,7 +1544,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg)
/* low bit indicates receives are present, so schedule
* napi poll handler */
if (stats->valid & 1)
- netif_rx_schedule(&ss->napi);
+ napi_schedule(&ss->napi);
if (!mgp->msi_enabled && !mgp->msix_enabled) {
put_be32(0, mgp->irq_deassert);
diff --git a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
index caa6cbbb631e..62a1cbab603f 100644
--- a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
+++ b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
@@ -9,6 +9,7 @@
#define MCP_TYPE_ETH 0x45544820 /* "ETH " */
#define MCP_TYPE_MCP0 0x4d435030 /* "MCP0" */
#define MCP_TYPE_DFLT 0x20202020 /* " " */
+#define MCP_TYPE_ETHZ 0x4554485a /* "ETHZ" */
struct mcp_gen_header {
/* the first 4 fields are filled at compile time */
@@ -43,7 +44,15 @@ struct mcp_gen_header {
unsigned msix_table_addr; /* start address of msix table in firmware */
unsigned bss_addr; /* start of bss */
unsigned features;
+ unsigned ee_hdr_addr;
/* 8 */
};
+struct zmcp_info {
+ unsigned info_len;
+ unsigned zmcp_addr;
+ unsigned zmcp_len;
+ unsigned mcp_edata;
+};
+
#endif /* __MYRI10GE_MCP_GEN_HEADER_H__ */
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 899ed065a147..08534c08d30d 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -748,7 +748,7 @@ static int myri_rebuild_header(struct sk_buff *skb)
switch (eth->h_proto)
{
#ifdef CONFIG_INET
- case __constant_htons(ETH_P_IP):
+ case cpu_to_be16(ETH_P_IP):
return arp_find(eth->h_dest, skb);
#endif
@@ -896,6 +896,17 @@ static const struct header_ops myri_header_ops = {
.cache_update = myri_header_cache_update,
};
+static const struct net_device_ops myri_ops = {
+ .ndo_open = myri_open,
+ .ndo_stop = myri_close,
+ .ndo_start_xmit = myri_start_xmit,
+ .ndo_set_multicast_list = myri_set_multicast,
+ .ndo_tx_timeout = myri_tx_timeout,
+ .ndo_change_mtu = myri_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __devinit myri_sbus_probe(struct of_device *op, const struct of_device_id *match)
{
struct device_node *dp = op->node;
@@ -1048,13 +1059,9 @@ static int __devinit myri_sbus_probe(struct of_device *op, const struct of_devic
sbus_writel((1 << i), mp->cregs + MYRICTRL_IRQLVL);
mp->dev = dev;
- dev->open = &myri_open;
- dev->stop = &myri_close;
- dev->hard_start_xmit = &myri_start_xmit;
- dev->tx_timeout = &myri_tx_timeout;
dev->watchdog_timeo = 5*HZ;
- dev->set_multicast_list = &myri_set_multicast;
dev->irq = op->irqs[0];
+ dev->netdev_ops = &myri_ops;
/* Register interrupt handler now. */
DET(("Requesting MYRIcom IRQ line.\n"));
@@ -1065,7 +1072,6 @@ static int __devinit myri_sbus_probe(struct of_device *op, const struct of_devic
}
dev->mtu = MYRINET_MTU;
- dev->change_mtu = myri_change_mtu;
dev->header_ops = &myri_header_ops;
dev->hard_header_len = (ETH_HLEN + MYRI_PAD_LEN);
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index c5dec54251bf..c9bfe4eea189 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -127,7 +127,7 @@ static int full_duplex[MAX_UNITS];
#define NATSEMI_RX_LIMIT 2046 /* maximum supported by hardware */
/* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
KERN_INFO DRV_NAME " dp8381x driver, version "
DRV_VERSION ", " DRV_RELDATE "\n"
KERN_INFO " originally by Donald Becker <becker@scyld.com>\n"
@@ -2198,10 +2198,10 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]);
- if (netif_rx_schedule_prep(&np->napi)) {
+ if (napi_schedule_prep(&np->napi)) {
/* Disable interrupts and register for poll */
natsemi_irq_disable(dev);
- __netif_rx_schedule(&np->napi);
+ __napi_schedule(&np->napi);
} else
printk(KERN_WARNING
"%s: Ignoring interrupt, status %#08x, mask %#08x.\n",
@@ -2253,7 +2253,7 @@ static int natsemi_poll(struct napi_struct *napi, int budget)
np->intr_status = readl(ioaddr + IntrStatus);
} while (np->intr_status);
- netif_rx_complete(napi);
+ napi_complete(napi);
/* Reenable interrupts providing nothing is trying to shut
* the chip down. */
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index f090d3b9ec94..eb66f658f9d1 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -62,8 +62,9 @@ static int options[MAX_UNITS];
#include "8390.h"
/* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
-KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " D. Becker/P. Gortmaker\n";
+static const char version[] __devinitconst =
+ KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE
+ " D. Becker/P. Gortmaker\n";
#if defined(__powerpc__)
#define inl_le(addr) le32_to_cpu(inl(addr))
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index d304d38cd5d1..eceadf787a67 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -294,14 +294,12 @@ static ssize_t show_remote_port(struct netconsole_target *nt, char *buf)
static ssize_t show_local_ip(struct netconsole_target *nt, char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n",
- HIPQUAD(nt->np.local_ip));
+ return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.local_ip);
}
static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n",
- HIPQUAD(nt->np.remote_ip));
+ return snprintf(buf, PAGE_SIZE, "%pI4\n", &nt->np.remote_ip);
}
static ssize_t show_local_mac(struct netconsole_target *nt, char *buf)
@@ -438,7 +436,7 @@ static ssize_t store_local_ip(struct netconsole_target *nt,
return -EINVAL;
}
- nt->np.local_ip = ntohl(in_aton(buf));
+ nt->np.local_ip = in_aton(buf);
return strnlen(buf, count);
}
@@ -454,7 +452,7 @@ static ssize_t store_remote_ip(struct netconsole_target *nt,
return -EINVAL;
}
- nt->np.remote_ip = ntohl(in_aton(buf));
+ nt->np.remote_ip = in_aton(buf);
return strnlen(buf, count);
}
diff --git a/drivers/net/netxen/Makefile b/drivers/net/netxen/Makefile
index 8e7c4c910d2a..cf01a9130c91 100644
--- a/drivers/net/netxen/Makefile
+++ b/drivers/net/netxen/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 2003 - 2006 NetXen, Inc.
+# Copyright (C) 2003 - 2009 NetXen, Inc.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or
@@ -21,11 +21,10 @@
#
# Contact Information:
# info@netxen.com
-# NetXen,
-# 3965 Freedom Circle, Fourth floor,
-# Santa Clara, CA 95054
+# NetXen Inc,
+# 18922 Forge Drive
+# Cupertino, CA 95014-0701
#
-# Makefile for the NetXen NIC Driver
#
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 1ff066b2281a..c40815169f35 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,9 +22,10 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
+ *
*/
#ifndef _NETXEN_NIC_H_
@@ -65,8 +66,8 @@
#define _NETXEN_NIC_LINUX_MAJOR 4
#define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 11
-#define NETXEN_NIC_LINUX_VERSIONID "4.0.11"
+#define _NETXEN_NIC_LINUX_SUBVERSION 30
+#define NETXEN_NIC_LINUX_VERSIONID "4.0.30"
#define NETXEN_VERSION_CODE(a, b, c) (((a) << 16) + ((b) << 8) + (c))
@@ -77,19 +78,19 @@
#define PHAN_VENDOR_ID 0x4040
-#define RCV_DESC_RINGSIZE \
- (sizeof(struct rcv_desc) * adapter->max_rx_desc_count)
-#define STATUS_DESC_RINGSIZE \
- (sizeof(struct status_desc)* adapter->max_rx_desc_count)
-#define LRO_DESC_RINGSIZE \
- (sizeof(rcvDesc_t) * adapter->max_lro_rx_desc_count)
-#define TX_RINGSIZE \
- (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count)
-#define RCV_BUFFSIZE \
- (sizeof(struct netxen_rx_buffer) * rds_ring->max_rx_desc_count)
+#define RCV_DESC_RINGSIZE(rds_ring) \
+ (sizeof(struct rcv_desc) * (rds_ring)->num_desc)
+#define RCV_BUFF_RINGSIZE(rds_ring) \
+ (sizeof(struct netxen_rx_buffer) * rds_ring->num_desc)
+#define STATUS_DESC_RINGSIZE(sds_ring) \
+ (sizeof(struct status_desc) * (sds_ring)->num_desc)
+#define TX_BUFF_RINGSIZE(adapter) \
+ (sizeof(struct netxen_cmd_buffer) * adapter->num_txd)
+#define TX_DESC_RINGSIZE(adapter) \
+ (sizeof(struct cmd_desc_type0) * adapter->num_txd)
+
#define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
-#define NETXEN_NETDEV_STATUS 0x1
#define NETXEN_RCV_PRODUCER_OFFSET 0
#define NETXEN_RCV_PEG_DB_ID 2
#define NETXEN_HOST_DUMMY_DMA_SIZE 1024
@@ -188,22 +189,12 @@
/* Host writes the following to notify that it has done the init-handshake */
#define PHAN_INITIALIZE_ACK 0xf00f
-#define NUM_RCV_DESC_RINGS 3 /* No of Rcv Descriptor contexts */
-
-/* descriptor types */
-#define RCV_DESC_NORMAL 0x01
-#define RCV_DESC_JUMBO 0x02
-#define RCV_DESC_LRO 0x04
-#define RCV_DESC_NORMAL_CTXID 0
-#define RCV_DESC_JUMBO_CTXID 1
-#define RCV_DESC_LRO_CTXID 2
+#define NUM_RCV_DESC_RINGS 3
+#define NUM_STS_DESC_RINGS 4
-#define RCV_DESC_TYPE(ID) \
- ((ID == RCV_DESC_JUMBO_CTXID) \
- ? RCV_DESC_JUMBO \
- : ((ID == RCV_DESC_LRO_CTXID) \
- ? RCV_DESC_LRO : \
- (RCV_DESC_NORMAL)))
+#define RCV_RING_NORMAL 0
+#define RCV_RING_JUMBO 1
+#define RCV_RING_LRO 2
#define MAX_CMD_DESCRIPTORS 4096
#define MAX_RCV_DESCRIPTORS 16384
@@ -357,10 +348,7 @@ struct cmd_desc_type0 {
__le64 addr_buffer1;
};
- __le16 buffer1_length;
- __le16 buffer2_length;
- __le16 buffer3_length;
- __le16 buffer4_length;
+ __le16 buffer_length[4];
union {
struct {
@@ -391,11 +379,8 @@ struct rcv_desc {
#define STATUS_CKSUM_OK (2)
/* owner bits of status_desc */
-#define STATUS_OWNER_HOST (0x1)
-#define STATUS_OWNER_PHANTOM (0x2)
-
-#define NETXEN_PROT_IP (1)
-#define NETXEN_PROT_UNKNOWN (0)
+#define STATUS_OWNER_HOST (0x1ULL << 56)
+#define STATUS_OWNER_PHANTOM (0x2ULL << 56)
/* Note: sizeof(status_desc) should always be a mutliple of 2 */
@@ -421,15 +406,6 @@ struct rcv_desc {
#define netxen_get_sts_opcode(sts_data) \
(((sts_data) >> 58) & 0x03F)
-#define netxen_get_sts_owner(status_desc) \
- ((le64_to_cpu((status_desc)->status_desc_data) >> 56) & 0x03)
-#define netxen_set_sts_owner(status_desc, val) { \
- (status_desc)->status_desc_data = \
- ((status_desc)->status_desc_data & \
- ~cpu_to_le64(0x3ULL << 56)) | \
- cpu_to_le64((u64)((val) & 0x3) << 56); \
-}
-
struct status_desc {
/* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length
28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset
@@ -712,6 +688,15 @@ typedef enum {
NETXEN_FIXED_START = 0x3F0000 /* backup of crbinit */
} netxen_flash_map_t;
+#define NX_FW_VERSION_OFFSET (NETXEN_USER_START+0x408)
+#define NX_FW_SIZE_OFFSET (NETXEN_USER_START+0x40c)
+#define NX_BIOS_VERSION_OFFSET (NETXEN_USER_START+0x83c)
+#define NX_FW_MAGIC_OFFSET (NETXEN_BRDCFG_START+0x128)
+#define NX_FW_MIN_SIZE (0x3fffff)
+#define NX_P2_MN_ROMIMAGE 0
+#define NX_P3_CT_ROMIMAGE 1
+#define NX_P3_MN_ROMIMAGE 2
+
#define NETXEN_USER_START_OLD NETXEN_PXE_START /* for backward compatibility */
#define NETXEN_FLASH_START (NETXEN_CRBINIT_START)
@@ -739,7 +724,7 @@ extern char netxen_nic_driver_name[];
#endif
/* Number of status descriptors to handle per interrupt */
-#define MAX_STATUS_HANDLE (128)
+#define MAX_STATUS_HANDLE (64)
/*
* netxen_skb_frag{} is to contain mapping info for each SG list. This
@@ -783,9 +768,6 @@ struct netxen_rx_buffer {
u64 dma;
u16 ref_handle;
u16 state;
- u32 lro_expected_frags;
- u32 lro_current_frags;
- u32 lro_length;
};
/* Board types */
@@ -800,21 +782,19 @@ struct netxen_hardware_context {
void __iomem *pci_base0;
void __iomem *pci_base1;
void __iomem *pci_base2;
- unsigned long first_page_group_end;
- unsigned long first_page_group_start;
void __iomem *db_base;
unsigned long db_len;
unsigned long pci_len0;
- u8 cut_through;
int qdr_sn_window;
int ddr_mn_window;
unsigned long mn_win_crb;
unsigned long ms_win_crb;
+ u8 cut_through;
u8 revision_id;
- u16 board_type;
- struct netxen_board_info boardcfg;
+ u16 port_type;
+ int board_type;
u32 linkup;
/* Address of cmd ring in Phantom */
struct cmd_desc_type0 *cmd_desc_head;
@@ -823,8 +803,6 @@ struct netxen_hardware_context {
int pci_func;
};
-#define RCV_RING_LRO RCV_DESC_LRO
-
#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */
#define ETHERNET_FCS_SIZE 4
@@ -850,16 +828,36 @@ struct netxen_adapter_stats {
* be one Rcv Descriptor for normal packets, one for jumbo and may be others.
*/
struct nx_host_rds_ring {
- u32 flags;
u32 producer;
- dma_addr_t phys_addr;
- u32 crb_rcv_producer; /* reg offset */
- struct rcv_desc *desc_head; /* address of rx ring in Phantom */
- u32 max_rx_desc_count;
+ u32 crb_rcv_producer;
+ u32 num_desc;
u32 dma_size;
u32 skb_size;
- struct netxen_rx_buffer *rx_buf_arr; /* rx buffers for receive */
+ u32 flags;
+ struct rcv_desc *desc_head;
+ struct netxen_rx_buffer *rx_buf_arr;
struct list_head free_list;
+ spinlock_t lock;
+ dma_addr_t phys_addr;
+};
+
+struct nx_host_sds_ring {
+ u32 consumer;
+ u32 crb_sts_consumer;
+ u32 crb_intr_mask;
+ u32 num_desc;
+
+ struct status_desc *desc_head;
+ struct netxen_adapter *adapter;
+ struct napi_struct napi;
+ struct list_head free_list[NUM_RCV_DESC_RINGS];
+
+ u16 clean_tx;
+ u16 post_rxd;
+ int irq;
+
+ dma_addr_t phys_addr;
+ char name[IFNAMSIZ+4];
};
/*
@@ -874,10 +872,7 @@ struct netxen_recv_context {
u16 virt_port;
struct nx_host_rds_ring rds_rings[NUM_RCV_DESC_RINGS];
- u32 status_rx_consumer;
- u32 crb_sts_consumer; /* reg offset */
- dma_addr_t rcv_status_desc_phys_addr;
- struct status_desc *rcv_status_desc_head;
+ struct nx_host_sds_ring sds_rings[NUM_STS_DESC_RINGS];
};
/* New HW context creation */
@@ -1203,13 +1198,13 @@ typedef struct {
#define NETXEN_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))
-#define MSIX_ENTRIES_PER_ADAPTER 1
+#define MSIX_ENTRIES_PER_ADAPTER NUM_STS_DESC_RINGS
#define NETXEN_MSIX_TBL_SPACE 8192
#define NETXEN_PCI_REG_MSIX_TBL 0x44
#define NETXEN_DB_MAPSIZE_BYTES 0x1000
-#define NETXEN_NETDEV_WEIGHT 120
+#define NETXEN_NETDEV_WEIGHT 128
#define NETXEN_ADAPTER_UP_MAGIC 777
#define NETXEN_NIC_PEG_TUNE 0
@@ -1224,7 +1219,6 @@ struct netxen_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
int pci_using_dac;
- struct napi_struct napi;
struct net_device_stats net_stats;
int mtu;
int portnum;
@@ -1236,7 +1230,6 @@ struct netxen_adapter {
nx_mac_list_t *mac_list;
struct netxen_legacy_intr_set legacy_intr;
- u32 crb_intr_mask;
struct work_struct watchdog_task;
struct timer_list watchdog_timer;
@@ -1246,20 +1239,20 @@ struct netxen_adapter {
u32 crb_win;
rwlock_t adapter_lock;
- uint64_t dma_mask;
-
u32 cmd_producer;
__le32 *cmd_consumer;
u32 last_cmd_consumer;
u32 crb_addr_cmd_producer;
u32 crb_addr_cmd_consumer;
+ spinlock_t tx_clean_lock;
- u32 max_tx_desc_count;
- u32 max_rx_desc_count;
- u32 max_jumbo_rx_desc_count;
- u32 max_lro_rx_desc_count;
+ u32 num_txd;
+ u32 num_rxd;
+ u32 num_jumbo_rxd;
+ u32 num_lro_rxd;
int max_rds_rings;
+ int max_sds_rings;
u32 flags;
u32 irq;
@@ -1267,9 +1260,9 @@ struct netxen_adapter {
u32 temp;
u32 fw_major;
+ u32 fw_version;
- u8 msix_supported;
- u8 max_possible_rss_rings;
+ int msix_supported;
struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
struct netxen_adapter_stats stats;
@@ -1279,7 +1272,6 @@ struct netxen_adapter {
u16 state;
u16 link_autoneg;
int rx_csum;
- int status;
struct netxen_cmd_buffer *cmd_buf_arr; /* Command buffers for xmit */
@@ -1287,7 +1279,7 @@ struct netxen_adapter {
* Receive instances. These can be either one per port,
* or one per peg, etc.
*/
- struct netxen_recv_context recv_ctx[MAX_RCV_CTX];
+ struct netxen_recv_context recv_ctx;
int is_up;
struct netxen_dummy_dma dummy_dma;
@@ -1398,6 +1390,8 @@ void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value);
void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value);
int netxen_nic_get_board_info(struct netxen_adapter *adapter);
+void netxen_nic_get_firmware_info(struct netxen_adapter *adapter);
+int netxen_nic_wol_supported(struct netxen_adapter *adapter);
int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
ulong off, void *data, int len);
@@ -1471,15 +1465,16 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter);
int netxen_init_firmware(struct netxen_adapter *adapter);
void netxen_nic_clear_stats(struct netxen_adapter *adapter);
void netxen_watchdog_task(struct work_struct *work);
-void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
- u32 ringid);
+void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
+ struct nx_host_rds_ring *rds_ring);
int netxen_process_cmd_ring(struct netxen_adapter *adapter);
-u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
+int netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max);
void netxen_p2_nic_set_multi(struct net_device *netdev);
void netxen_p3_nic_set_multi(struct net_device *netdev);
void netxen_p3_free_mac_list(struct netxen_adapter *adapter);
int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32);
int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
+int netxen_config_rss(struct netxen_adapter *adapter, int enable);
int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 746bdb470418..9234473bc08a 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2008 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,9 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -141,7 +141,7 @@ int
nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu)
{
u32 rcode = NX_RCODE_SUCCESS;
- struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
rcode = netxen_issue_cmd(adapter,
@@ -169,6 +169,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
nx_cardrsp_rds_ring_t *prsp_rds;
nx_cardrsp_sds_ring_t *prsp_sds;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_sds_ring *sds_ring;
dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
u64 phys_addr;
@@ -179,11 +180,10 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
int err;
- struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
- /* only one sds ring for now */
nrds_rings = adapter->max_rds_rings;
- nsds_rings = 1;
+ nsds_rings = adapter->max_sds_rings;
rq_size =
SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings);
@@ -231,7 +231,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
rds_ring = &recv_ctx->rds_rings[i];
prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
- prq_rds[i].ring_size = cpu_to_le32(rds_ring->max_rx_desc_count);
+ prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc);
prq_rds[i].ring_kind = cpu_to_le32(i);
prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size);
}
@@ -239,11 +239,14 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
prq_sds = (nx_hostrq_sds_ring_t *)(prq->data +
le32_to_cpu(prq->sds_ring_offset));
- prq_sds[0].host_phys_addr =
- cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
- prq_sds[0].ring_size = cpu_to_le32(adapter->max_rx_desc_count);
- /* only one msix vector for now */
- prq_sds[0].msi_index = cpu_to_le16(0);
+ for (i = 0; i < nsds_rings; i++) {
+
+ sds_ring = &recv_ctx->sds_rings[i];
+
+ prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
+ prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
+ prq_sds[i].msi_index = cpu_to_le16(i);
+ }
phys_addr = hostrq_phys_addr;
err = netxen_issue_cmd(adapter,
@@ -272,11 +275,16 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
prsp_sds = ((nx_cardrsp_sds_ring_t *)
&prsp->data[le32_to_cpu(prsp->sds_ring_offset)]);
- reg = le32_to_cpu(prsp_sds[0].host_consumer_crb);
- recv_ctx->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
- reg = le32_to_cpu(prsp_sds[0].interrupt_crb);
- adapter->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);
+ for (i = 0; i < le16_to_cpu(prsp->num_sds_rings); i++) {
+ sds_ring = &recv_ctx->sds_rings[i];
+
+ reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
+ sds_ring->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
+
+ reg = le32_to_cpu(prsp_sds[i].interrupt_crb);
+ sds_ring->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);
+ }
recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
recv_ctx->context_id = le16_to_cpu(prsp->context_id);
@@ -292,7 +300,7 @@ out_free_rq:
static void
nx_fw_cmd_destroy_rx_ctx(struct netxen_adapter *adapter)
{
- struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
if (netxen_issue_cmd(adapter,
adapter->ahw.pci_func,
@@ -362,7 +370,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
prq_cds->host_phys_addr =
cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
- prq_cds->ring_size = cpu_to_le32(adapter->max_tx_desc_count);
+ prq_cds->ring_size = cpu_to_le32(adapter->num_txd);
phys_addr = rq_phys_addr;
err = netxen_issue_cmd(adapter,
@@ -488,30 +496,28 @@ netxen_init_old_ctx(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
- int ctx, ring;
+ struct nx_host_sds_ring *sds_ring;
+ int ring;
int func_id = adapter->portnum;
adapter->ctx_desc->cmd_ring_addr =
cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
adapter->ctx_desc->cmd_ring_size =
- cpu_to_le32(adapter->max_tx_desc_count);
+ cpu_to_le32(adapter->num_txd);
- for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
- recv_ctx = &adapter->recv_ctx[ctx];
+ recv_ctx = &adapter->recv_ctx;
- for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- rds_ring = &recv_ctx->rds_rings[ring];
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
- adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
- cpu_to_le64(rds_ring->phys_addr);
- adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
- cpu_to_le32(rds_ring->max_rx_desc_count);
- }
- adapter->ctx_desc->sts_ring_addr =
- cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
- adapter->ctx_desc->sts_ring_size =
- cpu_to_le32(adapter->max_rx_desc_count);
+ adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
+ cpu_to_le64(rds_ring->phys_addr);
+ adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
+ cpu_to_le32(rds_ring->num_desc);
}
+ sds_ring = &recv_ctx->sds_rings[0];
+ adapter->ctx_desc->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr);
+ adapter->ctx_desc->sts_ring_size = cpu_to_le32(sds_ring->num_desc);
adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id),
lower32(adapter->ctx_desc_phys_addr));
@@ -533,9 +539,13 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
u32 state = 0;
void *addr;
int err = 0;
- int ctx, ring;
+ int ring;
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_sds_ring *sds_ring;
+
+ struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = adapter->netdev;
err = netxen_receive_peg_ready(adapter);
if (err) {
@@ -544,12 +554,12 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
return err;
}
- addr = pci_alloc_consistent(adapter->pdev,
+ addr = pci_alloc_consistent(pdev,
sizeof(struct netxen_ring_ctx) + sizeof(uint32_t),
&adapter->ctx_desc_phys_addr);
if (addr == NULL) {
- DPRINTK(ERR, "failed to allocate hw context\n");
+ dev_err(&pdev->dev, "failed to allocate hw context\n");
return -ENOMEM;
}
memset(addr, 0, sizeof(struct netxen_ring_ctx));
@@ -562,61 +572,57 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
(__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx));
/* cmd desc ring */
- addr = pci_alloc_consistent(adapter->pdev,
- sizeof(struct cmd_desc_type0) *
- adapter->max_tx_desc_count,
+ addr = pci_alloc_consistent(pdev,
+ TX_DESC_RINGSIZE(adapter),
&hw->cmd_desc_phys_addr);
if (addr == NULL) {
- printk(KERN_ERR "%s failed to allocate tx desc ring\n",
- netxen_nic_driver_name);
+ dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n",
+ netdev->name);
return -ENOMEM;
}
hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
- for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
- recv_ctx = &adapter->recv_ctx[ctx];
-
- for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- /* rx desc ring */
- rds_ring = &recv_ctx->rds_rings[ring];
- addr = pci_alloc_consistent(adapter->pdev,
- RCV_DESC_RINGSIZE,
- &rds_ring->phys_addr);
- if (addr == NULL) {
- printk(KERN_ERR "%s failed to allocate rx "
- "desc ring[%d]\n",
- netxen_nic_driver_name, ring);
- err = -ENOMEM;
- goto err_out_free;
- }
- rds_ring->desc_head = (struct rcv_desc *)addr;
-
- if (adapter->fw_major < 4)
- rds_ring->crb_rcv_producer =
- recv_crb_registers[adapter->portnum].
- crb_rcv_producer[ring];
- }
+ recv_ctx = &adapter->recv_ctx;
- /* status desc ring */
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
addr = pci_alloc_consistent(adapter->pdev,
- STATUS_DESC_RINGSIZE,
- &recv_ctx->rcv_status_desc_phys_addr);
+ RCV_DESC_RINGSIZE(rds_ring),
+ &rds_ring->phys_addr);
if (addr == NULL) {
- printk(KERN_ERR "%s failed to allocate sts desc ring\n",
- netxen_nic_driver_name);
+ dev_err(&pdev->dev,
+ "%s: failed to allocate rds ring [%d]\n",
+ netdev->name, ring);
err = -ENOMEM;
goto err_out_free;
}
- recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;
+ rds_ring->desc_head = (struct rcv_desc *)addr;
if (adapter->fw_major < 4)
- recv_ctx->crb_sts_consumer =
+ rds_ring->crb_rcv_producer =
recv_crb_registers[adapter->portnum].
- crb_sts_consumer;
+ crb_rcv_producer[ring];
}
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+
+ addr = pci_alloc_consistent(adapter->pdev,
+ STATUS_DESC_RINGSIZE(sds_ring),
+ &sds_ring->phys_addr);
+ if (addr == NULL) {
+ dev_err(&pdev->dev,
+ "%s: failed to allocate sds ring [%d]\n",
+ netdev->name, ring);
+ err = -ENOMEM;
+ goto err_out_free;
+ }
+ sds_ring->desc_head = (struct status_desc *)addr;
+ }
+
+
if (adapter->fw_major >= 4) {
adapter->intr_scheme = INTR_SCHEME_PERPORT;
adapter->msi_mode = MSI_MODE_MULTIFUNC;
@@ -628,12 +634,16 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
if (err)
goto err_out_free;
} else {
+ sds_ring = &recv_ctx->sds_rings[0];
+ sds_ring->crb_sts_consumer =
+ recv_crb_registers[adapter->portnum].crb_sts_consumer;
adapter->intr_scheme = adapter->pci_read_normalize(adapter,
CRB_NIC_CAPABILITIES_FW);
adapter->msi_mode = adapter->pci_read_normalize(adapter,
CRB_NIC_MSI_MODE_FW);
- adapter->crb_intr_mask = sw_int_mask[adapter->portnum];
+ recv_ctx->sds_rings[0].crb_intr_mask =
+ sw_int_mask[adapter->portnum];
err = netxen_init_old_ctx(adapter);
if (err) {
@@ -654,7 +664,8 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
- int ctx, ring;
+ struct nx_host_sds_ring *sds_ring;
+ int ring;
if (adapter->fw_major >= 4) {
nx_fw_cmd_destroy_tx_ctx(adapter);
@@ -673,32 +684,34 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
if (adapter->ahw.cmd_desc_head != NULL) {
pci_free_consistent(adapter->pdev,
sizeof(struct cmd_desc_type0) *
- adapter->max_tx_desc_count,
+ adapter->num_txd,
adapter->ahw.cmd_desc_head,
adapter->ahw.cmd_desc_phys_addr);
adapter->ahw.cmd_desc_head = NULL;
}
- for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
- recv_ctx = &adapter->recv_ctx[ctx];
- for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- rds_ring = &recv_ctx->rds_rings[ring];
-
- if (rds_ring->desc_head != NULL) {
- pci_free_consistent(adapter->pdev,
- RCV_DESC_RINGSIZE,
- rds_ring->desc_head,
- rds_ring->phys_addr);
- rds_ring->desc_head = NULL;
- }
+ recv_ctx = &adapter->recv_ctx;
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
+
+ if (rds_ring->desc_head != NULL) {
+ pci_free_consistent(adapter->pdev,
+ RCV_DESC_RINGSIZE(rds_ring),
+ rds_ring->desc_head,
+ rds_ring->phys_addr);
+ rds_ring->desc_head = NULL;
}
+ }
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
- if (recv_ctx->rcv_status_desc_head != NULL) {
+ if (sds_ring->desc_head != NULL) {
pci_free_consistent(adapter->pdev,
- STATUS_DESC_RINGSIZE,
- recv_ctx->rcv_status_desc_head,
- recv_ctx->rcv_status_desc_phys_addr);
- recv_ctx->rcv_status_desc_head = NULL;
+ STATUS_DESC_RINGSIZE(sds_ring),
+ sds_ring->desc_head,
+ sds_ring->phys_addr);
+ sds_ring->desc_head = NULL;
}
}
}
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 0894a7be0225..a677ff895184 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * ethtool support for netxen nic
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -118,10 +115,9 @@ static int
netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
struct netxen_adapter *adapter = netdev_priv(dev);
- struct netxen_board_info *boardinfo = &adapter->ahw.boardcfg;
/* read which mode */
- if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
ecmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
@@ -140,7 +136,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->duplex = adapter->link_duplex;
ecmd->autoneg = adapter->link_autoneg;
- } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+ } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
u32 val;
adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &val, 4);
@@ -172,7 +168,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->phy_address = adapter->physical_port;
ecmd->transceiver = XCVR_EXTERNAL;
- switch ((netxen_brdtype_t) boardinfo->board_type) {
+ switch ((netxen_brdtype_t)adapter->ahw.board_type) {
case NETXEN_BRDTYPE_P2_SB35_4G:
case NETXEN_BRDTYPE_P2_SB31_2G:
case NETXEN_BRDTYPE_P3_REF_QG:
@@ -188,7 +184,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->supported |= SUPPORTED_TP;
ecmd->advertising |= ADVERTISED_TP;
ecmd->port = PORT_TP;
- ecmd->autoneg = (boardinfo->board_type ==
+ ecmd->autoneg = (adapter->ahw.board_type ==
NETXEN_BRDTYPE_P2_SB31_10G_CX4) ?
(AUTONEG_DISABLE) : (adapter->link_autoneg);
break;
@@ -215,7 +211,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
ecmd->autoneg = AUTONEG_DISABLE;
break;
case NETXEN_BRDTYPE_P3_10G_TP:
- if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
ecmd->autoneg = AUTONEG_DISABLE;
ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
ecmd->advertising |=
@@ -231,7 +227,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
break;
default:
printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
- (netxen_brdtype_t) boardinfo->board_type);
+ (netxen_brdtype_t)adapter->ahw.board_type);
return -EIO;
}
@@ -245,7 +241,7 @@ netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
__u32 status;
/* read which mode */
- if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
/* autonegotiation */
if (adapter->phy_write
&& adapter->phy_write(adapter,
@@ -433,7 +429,7 @@ static u32 netxen_nic_test_link(struct net_device *dev)
int val;
/* read which mode */
- if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
if (adapter->phy_read
&& adapter->phy_read(adapter,
NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
@@ -443,7 +439,7 @@ static u32 netxen_nic_test_link(struct net_device *dev)
val = netxen_get_phy_link(status);
return !val;
}
- } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+ } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
return (val == XG_LINK_UP) ? 0 : 1;
}
@@ -473,95 +469,20 @@ netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
return 0;
}
-#if 0
-static int
-netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
- u8 * bytes)
-{
- struct netxen_adapter *adapter = netdev_priv(dev);
- int offset = eeprom->offset;
- static int flash_start;
- static int ready_to_flash;
- int ret;
-
- if (flash_start == 0) {
- netxen_halt_pegs(adapter);
- ret = netxen_flash_unlock(adapter);
- if (ret < 0) {
- printk(KERN_ERR "%s: Flash unlock failed.\n",
- netxen_nic_driver_name);
- return ret;
- }
- printk(KERN_INFO "%s: flash unlocked. \n",
- netxen_nic_driver_name);
- ret = netxen_flash_erase_secondary(adapter);
- if (ret != FLASH_SUCCESS) {
- printk(KERN_ERR "%s: Flash erase failed.\n",
- netxen_nic_driver_name);
- return ret;
- }
- printk(KERN_INFO "%s: secondary flash erased successfully.\n",
- netxen_nic_driver_name);
- flash_start = 1;
- return 0;
- }
-
- if (offset == NETXEN_BOOTLD_START) {
- ret = netxen_flash_erase_primary(adapter);
- if (ret != FLASH_SUCCESS) {
- printk(KERN_ERR "%s: Flash erase failed.\n",
- netxen_nic_driver_name);
- return ret;
- }
-
- ret = netxen_rom_se(adapter, NETXEN_USER_START);
- if (ret != FLASH_SUCCESS)
- return ret;
- ret = netxen_rom_se(adapter, NETXEN_FIXED_START);
- if (ret != FLASH_SUCCESS)
- return ret;
-
- printk(KERN_INFO "%s: primary flash erased successfully\n",
- netxen_nic_driver_name);
-
- ret = netxen_backup_crbinit(adapter);
- if (ret != FLASH_SUCCESS) {
- printk(KERN_ERR "%s: CRBinit backup failed.\n",
- netxen_nic_driver_name);
- return ret;
- }
- printk(KERN_INFO "%s: CRBinit backup done.\n",
- netxen_nic_driver_name);
- ready_to_flash = 1;
- }
-
- if (!ready_to_flash) {
- printk(KERN_ERR "%s: Invalid write sequence, returning...\n",
- netxen_nic_driver_name);
- return -EINVAL;
- }
-
- return netxen_rom_fast_write_words(adapter, offset, bytes, eeprom->len);
-}
-#endif /* 0 */
-
static void
netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
{
struct netxen_adapter *adapter = netdev_priv(dev);
- int i;
ring->rx_pending = 0;
ring->rx_jumbo_pending = 0;
- for (i = 0; i < MAX_RCV_CTX; ++i) {
- ring->rx_pending += adapter->recv_ctx[i].
- rds_rings[RCV_DESC_NORMAL_CTXID].max_rx_desc_count;
- ring->rx_jumbo_pending += adapter->recv_ctx[i].
- rds_rings[RCV_DESC_JUMBO_CTXID].max_rx_desc_count;
- }
- ring->tx_pending = adapter->max_tx_desc_count;
+ ring->rx_pending += adapter->recv_ctx.
+ rds_rings[RCV_RING_NORMAL].num_desc;
+ ring->rx_jumbo_pending += adapter->recv_ctx.
+ rds_rings[RCV_RING_JUMBO].num_desc;
+ ring->tx_pending = adapter->num_txd;
- if (adapter->ahw.board_type == NETXEN_NIC_GBE)
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE)
ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
else
ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G;
@@ -579,7 +500,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,
__u32 val;
int port = adapter->physical_port;
- if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
return;
/* get flow control settings */
@@ -602,7 +523,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,
pause->tx_pause = !(netxen_gb_get_gb3_mask(val));
break;
}
- } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+ } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
return;
pause->rx_pause = 1;
@@ -613,7 +534,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,
pause->tx_pause = !(netxen_xg_get_xg1_mask(val));
} else {
printk(KERN_ERR"%s: Unknown board type: %x\n",
- netxen_nic_driver_name, adapter->ahw.board_type);
+ netxen_nic_driver_name, adapter->ahw.port_type);
}
}
@@ -625,7 +546,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,
__u32 val;
int port = adapter->physical_port;
/* read mode */
- if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
return -EIO;
/* set flow control */
@@ -669,7 +590,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,
break;
}
netxen_nic_write_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
- } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+ } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
return -EIO;
netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
@@ -688,7 +609,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,
} else {
printk(KERN_ERR "%s: Unknown board type: %x\n",
netxen_nic_driver_name,
- adapter->ahw.board_type);
+ adapter->ahw.port_type);
}
return 0;
}
@@ -810,6 +731,53 @@ static int netxen_nic_set_tso(struct net_device *dev, u32 data)
return 0;
}
+static void
+netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct netxen_adapter *adapter = netdev_priv(dev);
+ u32 wol_cfg = 0;
+
+ wol->supported = 0;
+ wol->wolopts = 0;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return;
+
+ wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+ if (wol_cfg & (1UL << adapter->portnum))
+ wol->supported |= WAKE_MAGIC;
+
+ wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+ if (wol_cfg & (1UL << adapter->portnum))
+ wol->wolopts |= WAKE_MAGIC;
+}
+
+static int
+netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct netxen_adapter *adapter = netdev_priv(dev);
+ u32 wol_cfg = 0;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return -EOPNOTSUPP;
+
+ if (wol->wolopts & ~WAKE_MAGIC)
+ return -EOPNOTSUPP;
+
+ wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+ if (!(wol_cfg & (1 << adapter->portnum)))
+ return -EOPNOTSUPP;
+
+ wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+ if (wol->wolopts & WAKE_MAGIC)
+ wol_cfg |= 1UL << adapter->portnum;
+ else
+ wol_cfg &= ~(1UL << adapter->portnum);
+ netxen_nic_reg_write(adapter, NETXEN_WOL_CONFIG, wol_cfg);
+
+ return 0;
+}
+
/*
* Set the coalescing parameters. Currently only normal is supported.
* If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the
@@ -906,9 +874,6 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_eeprom_len = netxen_nic_get_eeprom_len,
.get_eeprom = netxen_nic_get_eeprom,
-#if 0
- .set_eeprom = netxen_nic_set_eeprom,
-#endif
.get_ringparam = netxen_nic_get_ringparam,
.get_pauseparam = netxen_nic_get_pauseparam,
.set_pauseparam = netxen_nic_set_pauseparam,
@@ -916,6 +881,8 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
.set_sg = ethtool_op_set_sg,
.get_tso = netxen_nic_get_tso,
.set_tso = netxen_nic_set_tso,
+ .get_wol = netxen_nic_get_wol,
+ .set_wol = netxen_nic_set_wol,
.self_test = netxen_nic_diag_test,
.get_strings = netxen_nic_get_strings,
.get_ethtool_stats = netxen_nic_get_ethtool_stats,
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index e80f9e3e5973..016c62129c76 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,9 +22,10 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
+ *
*/
#ifndef __NETXEN_NIC_HDR_H_
@@ -362,12 +363,6 @@ enum {
#define NETXEN_HW_CRB_HUB_AGT_ADR_LPC \
((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_LPC_CRB_AGT_ADR)
-/*
- * MAX_RCV_CTX : The number of receive contexts that are available on
- * the phantom.
- */
-#define MAX_RCV_CTX 1
-
#define NETXEN_SRE_INT_STATUS (NETXEN_CRB_SRE + 0x00034)
#define NETXEN_SRE_PBI_ACTIVE_STATUS (NETXEN_CRB_SRE + 0x01014)
#define NETXEN_SRE_L1RE_CTL (NETXEN_CRB_SRE + 0x03000)
@@ -858,6 +853,12 @@ enum {
#define NETXEN_PORT_MODE_ADDR (NETXEN_CAM_RAM(0x24))
#define NETXEN_WOL_PORT_MODE (NETXEN_CAM_RAM(0x198))
+#define NETXEN_WOL_CONFIG_NV (NETXEN_CAM_RAM(0x184))
+#define NETXEN_WOL_CONFIG (NETXEN_CAM_RAM(0x188))
+
+#define NX_PEG_TUNE_MN_PRESENT 0x1
+#define NX_PEG_TUNE_CAPABILITY (NETXEN_CAM_RAM(0x02c))
+
#define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14)
#define ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 7fea77088108..5026811c04ce 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Source file for NIC routines to access the Phantom hardware
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -35,7 +32,7 @@
#include "netxen_nic_hw.h"
#include "netxen_nic_phan_reg.h"
-
+#include <linux/firmware.h>
#include <net/ip.h>
#define MASK(n) ((1ULL<<(n))-1)
@@ -518,7 +515,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
&cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
producer = get_next_index(producer,
- adapter->max_tx_desc_count);
+ adapter->num_txd);
i++;
} while (i != nr_elements);
@@ -673,6 +670,53 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
return rv;
}
+#define RSS_HASHTYPE_IP_TCP 0x3
+
+int netxen_config_rss(struct netxen_adapter *adapter, int enable)
+{
+ nx_nic_req_t req;
+ u64 word;
+ int i, rv;
+
+ u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
+ 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
+ 0x255b0ec26d5a56daULL };
+
+
+ memset(&req, 0, sizeof(nx_nic_req_t));
+ req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+ word = NX_NIC_H2C_OPCODE_CONFIG_RSS | ((u64)adapter->portnum << 16);
+ req.req_hdr = cpu_to_le64(word);
+
+ /*
+ * RSS request:
+ * bits 3-0: hash_method
+ * 5-4: hash_type_ipv4
+ * 7-6: hash_type_ipv6
+ * 8: enable
+ * 9: use indirection table
+ * 47-10: reserved
+ * 63-48: indirection table mask
+ */
+ word = ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
+ ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
+ ((u64)(enable & 0x1) << 8) |
+ ((0x7ULL) << 48);
+ req.words[0] = cpu_to_le64(word);
+ for (i = 0; i < 5; i++)
+ req.words[i+1] = cpu_to_le64(key[i]);
+
+
+ rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+ if (rv != 0) {
+ printk(KERN_ERR "%s: could not configure RSS\n",
+ adapter->netdev->name);
+ }
+
+ return rv;
+}
+
/*
* netxen_nic_change_mtu - Change the Maximum Transfer Unit
* @returns 0 on success, negative on failure
@@ -709,9 +753,8 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
int size, __le32 * buf)
{
- int i, addr;
+ int i, v, addr;
__le32 *ptr32;
- u32 v;
addr = base;
ptr32 = buf;
@@ -914,13 +957,12 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
u32 win_read;
adapter->crb_win = CRB_HI(*off);
- writel(adapter->crb_win, (void *)(CRB_WINDOW_2M +
- adapter->ahw.pci_base0));
+ writel(adapter->crb_win, (adapter->ahw.pci_base0 + CRB_WINDOW_2M));
/*
* Read back value to make sure write has gone through before trying
* to use it.
*/
- win_read = readl((void *)(CRB_WINDOW_2M + adapter->ahw.pci_base0));
+ win_read = readl(adapter->ahw.pci_base0 + CRB_WINDOW_2M);
if (win_read != adapter->crb_win) {
printk(KERN_ERR "%s: Written crbwin (0x%x) != "
"Read crbwin (0x%x), off=0x%lx\n",
@@ -930,24 +972,69 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
(ulong)adapter->ahw.pci_base0;
}
-int netxen_load_firmware(struct netxen_adapter *adapter)
+static int
+netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname,
+ const struct firmware *fw)
{
- int i;
- u32 data, size = 0;
- u32 flashaddr = NETXEN_BOOTLD_START;
+ u64 *ptr64;
+ u32 i, flashaddr, size;
+ struct pci_dev *pdev = adapter->pdev;
- size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START)/4;
+ if (fw)
+ dev_info(&pdev->dev, "loading firmware from file %s\n", fwname);
+ else
+ dev_info(&pdev->dev, "loading firmware from flash\n");
if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
adapter->pci_write_normalize(adapter,
NETXEN_ROMUSB_GLB_CAS_RST, 1);
- for (i = 0; i < size; i++) {
- if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0)
- return -EIO;
+ if (fw) {
+ __le64 data;
- adapter->pci_mem_write(adapter, flashaddr, &data, 4);
- flashaddr += 4;
+ size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8;
+
+ ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START];
+ flashaddr = NETXEN_BOOTLD_START;
+
+ for (i = 0; i < size; i++) {
+ data = cpu_to_le64(ptr64[i]);
+ adapter->pci_mem_write(adapter, flashaddr, &data, 8);
+ flashaddr += 8;
+ }
+
+ size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET];
+ size = (__force u32)cpu_to_le32(size) / 8;
+
+ ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START];
+ flashaddr = NETXEN_IMAGE_START;
+
+ for (i = 0; i < size; i++) {
+ data = cpu_to_le64(ptr64[i]);
+
+ if (adapter->pci_mem_write(adapter,
+ flashaddr, &data, 8))
+ return -EIO;
+
+ flashaddr += 8;
+ }
+ } else {
+ u32 data;
+
+ size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4;
+ flashaddr = NETXEN_BOOTLD_START;
+
+ for (i = 0; i < size; i++) {
+ if (netxen_rom_fast_read(adapter,
+ flashaddr, (int *)&data) != 0)
+ return -EIO;
+
+ if (adapter->pci_mem_write(adapter,
+ flashaddr, &data, 4))
+ return -EIO;
+
+ flashaddr += 4;
+ }
}
msleep(1);
@@ -964,12 +1051,135 @@ int netxen_load_firmware(struct netxen_adapter *adapter)
return 0;
}
+static int
+netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname,
+ const struct firmware *fw)
+{
+ __le32 val;
+ u32 major, minor, build, ver, min_ver, bios;
+ struct pci_dev *pdev = adapter->pdev;
+
+ if (fw->size < NX_FW_MIN_SIZE)
+ return -EINVAL;
+
+ val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
+ if ((__force u32)val != NETXEN_BDINFO_MAGIC)
+ return -EINVAL;
+
+ val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
+ major = (__force u32)val & 0xff;
+ minor = ((__force u32)val >> 8) & 0xff;
+ build = (__force u32)val >> 16;
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ min_ver = NETXEN_VERSION_CODE(4, 0, 216);
+ else
+ min_ver = NETXEN_VERSION_CODE(3, 4, 216);
+
+ ver = NETXEN_VERSION_CODE(major, minor, build);
+
+ if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
+ dev_err(&pdev->dev,
+ "%s: firmware version %d.%d.%d unsupported\n",
+ fwname, major, minor, build);
+ return -EINVAL;
+ }
+
+ val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
+ netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios);
+ if ((__force u32)val != bios) {
+ dev_err(&pdev->dev, "%s: firmware bios is incompatible\n",
+ fwname);
+ return -EINVAL;
+ }
+
+ /* check if flashed firmware is newer */
+ if (netxen_rom_fast_read(adapter,
+ NX_FW_VERSION_OFFSET, (int *)&val))
+ return -EIO;
+ major = (__force u32)val & 0xff;
+ minor = ((__force u32)val >> 8) & 0xff;
+ build = (__force u32)val >> 16;
+ if (NETXEN_VERSION_CODE(major, minor, build) > ver)
+ return -EINVAL;
+
+ netxen_nic_reg_write(adapter, NETXEN_CAM_RAM(0x1fc),
+ NETXEN_BDINFO_MAGIC);
+ return 0;
+}
+
+static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" };
+
+int netxen_load_firmware(struct netxen_adapter *adapter)
+{
+ u32 capability, flashed_ver;
+ const struct firmware *fw;
+ int fw_type;
+ struct pci_dev *pdev = adapter->pdev;
+ int rc = 0;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+ fw_type = NX_P2_MN_ROMIMAGE;
+ goto request_fw;
+ } else {
+ fw_type = NX_P3_CT_ROMIMAGE;
+ goto request_fw;
+ }
+
+request_mn:
+ capability = 0;
+
+ netxen_rom_fast_read(adapter,
+ NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
+ if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
+ adapter->hw_read_wx(adapter,
+ NX_PEG_TUNE_CAPABILITY, &capability, 4);
+ if (capability & NX_PEG_TUNE_MN_PRESENT) {
+ fw_type = NX_P3_MN_ROMIMAGE;
+ goto request_fw;
+ }
+ }
+
+request_fw:
+ rc = request_firmware(&fw, fw_name[fw_type], &pdev->dev);
+ if (rc != 0) {
+ if (fw_type == NX_P3_CT_ROMIMAGE) {
+ msleep(1);
+ goto request_mn;
+ }
+
+ fw = NULL;
+ goto load_fw;
+ }
+
+ rc = netxen_validate_firmware(adapter, fw_name[fw_type], fw);
+ if (rc != 0) {
+ release_firmware(fw);
+
+ if (fw_type == NX_P3_CT_ROMIMAGE) {
+ msleep(1);
+ goto request_mn;
+ }
+
+ fw = NULL;
+ }
+
+load_fw:
+ rc = netxen_do_load_firmware(adapter, fw_name[fw_type], fw);
+
+ if (fw)
+ release_firmware(fw);
+ return rc;
+}
+
int
netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
ulong off, void *data, int len)
{
void __iomem *addr;
+ BUG_ON(len != 4);
+
if (ADDR_IN_WINDOW1(off)) {
addr = NETXEN_CRB_NORMALIZE(adapter, off);
} else { /* Window 0 */
@@ -977,37 +1187,13 @@ netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
netxen_nic_pci_change_crbwindow_128M(adapter, 0);
}
- DPRINTK(INFO, "writing to base %lx offset %llx addr %p"
- " data %llx len %d\n",
- pci_base(adapter, off), off, addr,
- *(unsigned long long *)data, len);
if (!addr) {
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
return 1;
}
- switch (len) {
- case 1:
- writeb(*(u8 *) data, addr);
- break;
- case 2:
- writew(*(u16 *) data, addr);
- break;
- case 4:
- writel(*(u32 *) data, addr);
- break;
- case 8:
- writeq(*(u64 *) data, addr);
- break;
- default:
- DPRINTK(INFO,
- "writing data %lx to offset %llx, num words=%d\n",
- *(unsigned long *)data, off, (len >> 3));
+ writel(*(u32 *) data, addr);
- netxen_nic_hw_block_write64((u64 __iomem *) data, addr,
- (len >> 3));
- break;
- }
if (!ADDR_IN_WINDOW1(off))
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
@@ -1020,6 +1206,8 @@ netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
{
void __iomem *addr;
+ BUG_ON(len != 4);
+
if (ADDR_IN_WINDOW1(off)) { /* Window 1 */
addr = NETXEN_CRB_NORMALIZE(adapter, off);
} else { /* Window 0 */
@@ -1027,31 +1215,12 @@ netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
netxen_nic_pci_change_crbwindow_128M(adapter, 0);
}
- DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
- pci_base(adapter, off), off, addr);
if (!addr) {
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
return 1;
}
- switch (len) {
- case 1:
- *(u8 *) data = readb(addr);
- break;
- case 2:
- *(u16 *) data = readw(addr);
- break;
- case 4:
- *(u32 *) data = readl(addr);
- break;
- case 8:
- *(u64 *) data = readq(addr);
- break;
- default:
- netxen_nic_hw_block_read64((u64 __iomem *) data, addr,
- (len >> 3));
- break;
- }
- DPRINTK(INFO, "read %lx\n", *(unsigned long *)data);
+
+ *(u32 *)data = readl(addr);
if (!ADDR_IN_WINDOW1(off))
netxen_nic_pci_change_crbwindow_128M(adapter, 1);
@@ -1066,6 +1235,8 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
unsigned long flags = 0;
int rv;
+ BUG_ON(len != 4);
+
rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
if (rv == -1) {
@@ -1079,34 +1250,12 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
write_lock_irqsave(&adapter->adapter_lock, flags);
crb_win_lock(adapter);
netxen_nic_pci_set_crbwindow_2M(adapter, &off);
- }
-
- DPRINTK(1, INFO, "write data %lx to offset %llx, len=%d\n",
- *(unsigned long *)data, off, len);
-
- switch (len) {
- case 1:
- writeb(*(uint8_t *)data, (void *)off);
- break;
- case 2:
- writew(*(uint16_t *)data, (void *)off);
- break;
- case 4:
- writel(*(uint32_t *)data, (void *)off);
- break;
- case 8:
- writeq(*(uint64_t *)data, (void *)off);
- break;
- default:
- DPRINTK(1, INFO,
- "writing data %lx to offset %llx, num words=%d\n",
- *(unsigned long *)data, off, (len>>3));
- break;
- }
- if (rv == 1) {
+ writel(*(uint32_t *)data, (void __iomem *)off);
crb_win_unlock(adapter);
write_unlock_irqrestore(&adapter->adapter_lock, flags);
- }
+ } else
+ writel(*(uint32_t *)data, (void __iomem *)off);
+
return 0;
}
@@ -1118,6 +1267,8 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
unsigned long flags = 0;
int rv;
+ BUG_ON(len != 4);
+
rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
if (rv == -1) {
@@ -1131,33 +1282,11 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
write_lock_irqsave(&adapter->adapter_lock, flags);
crb_win_lock(adapter);
netxen_nic_pci_set_crbwindow_2M(adapter, &off);
- }
-
- DPRINTK(1, INFO, "read from offset %lx, len=%d\n", off, len);
-
- switch (len) {
- case 1:
- *(uint8_t *)data = readb((void *)off);
- break;
- case 2:
- *(uint16_t *)data = readw((void *)off);
- break;
- case 4:
- *(uint32_t *)data = readl((void *)off);
- break;
- case 8:
- *(uint64_t *)data = readq((void *)off);
- break;
- default:
- break;
- }
-
- DPRINTK(1, INFO, "read %lx\n", *(unsigned long *)data);
-
- if (rv == 1) {
+ *(uint32_t *)data = readl((void __iomem *)off);
crb_win_unlock(adapter);
write_unlock_irqrestore(&adapter->adapter_lock, flags);
- }
+ } else
+ *(uint32_t *)data = readl((void __iomem *)off);
return 0;
}
@@ -1419,10 +1548,9 @@ static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter,
u64 off, void *data, int size)
{
unsigned long flags;
- void *addr;
+ void __iomem *addr, *mem_ptr = NULL;
int ret = 0;
u64 start;
- uint8_t *mem_ptr = NULL;
unsigned long mem_base;
unsigned long mem_page;
@@ -1442,7 +1570,7 @@ static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter,
return -1;
}
- addr = (void *)(pci_base_offset(adapter, start));
+ addr = pci_base_offset(adapter, start);
if (!addr) {
write_unlock_irqrestore(&adapter->adapter_lock, flags);
mem_base = pci_resource_start(adapter->pdev, 0);
@@ -1481,7 +1609,6 @@ static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter,
break;
}
write_unlock_irqrestore(&adapter->adapter_lock, flags);
- DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data);
if (mem_ptr)
iounmap(mem_ptr);
@@ -1493,10 +1620,9 @@ netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
void *data, int size)
{
unsigned long flags;
- void *addr;
+ void __iomem *addr, *mem_ptr = NULL;
int ret = 0;
u64 start;
- uint8_t *mem_ptr = NULL;
unsigned long mem_base;
unsigned long mem_page;
@@ -1516,7 +1642,7 @@ netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
return -1;
}
- addr = (void *)(pci_base_offset(adapter, start));
+ addr = pci_base_offset(adapter, start);
if (!addr) {
write_unlock_irqrestore(&adapter->adapter_lock, flags);
mem_base = pci_resource_start(adapter->pdev, 0);
@@ -1553,8 +1679,6 @@ netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
break;
}
write_unlock_irqrestore(&adapter->adapter_lock, flags);
- DPRINTK(1, INFO, "writing data %llx to offset %llx\n",
- *(unsigned long long *)data, start);
if (mem_ptr)
iounmap(mem_ptr);
return ret;
@@ -1566,10 +1690,11 @@ int
netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
u64 off, void *data, int size)
{
- unsigned long flags, mem_crb;
+ unsigned long flags;
int i, j, ret = 0, loop, sz[2], off0;
uint32_t temp;
uint64_t off8, tmpw, word[2] = {0, 0};
+ void __iomem *mem_crb;
/*
* If not MN, go check for MS or invalid.
@@ -1583,7 +1708,7 @@ netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
sz[0] = (size < (8 - off0)) ? size : (8 - off0);
sz[1] = size - sz[0];
loop = ((off0 + size - 1) >> 3) + 1;
- mem_crb = (unsigned long)pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+ mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
if ((size != 8) || (off0 != 0)) {
for (i = 0; i < loop; i++) {
@@ -1621,28 +1746,29 @@ netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
for (i = 0; i < loop; i++) {
writel((uint32_t)(off8 + (i << 3)),
- (void *)(mem_crb+MIU_TEST_AGT_ADDR_LO));
+ (mem_crb+MIU_TEST_AGT_ADDR_LO));
writel(0,
- (void *)(mem_crb+MIU_TEST_AGT_ADDR_HI));
+ (mem_crb+MIU_TEST_AGT_ADDR_HI));
writel(word[i] & 0xffffffff,
- (void *)(mem_crb+MIU_TEST_AGT_WRDATA_LO));
+ (mem_crb+MIU_TEST_AGT_WRDATA_LO));
writel((word[i] >> 32) & 0xffffffff,
- (void *)(mem_crb+MIU_TEST_AGT_WRDATA_HI));
+ (mem_crb+MIU_TEST_AGT_WRDATA_HI));
writel(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
- (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+ (mem_crb+MIU_TEST_AGT_CTRL));
writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
- (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+ (mem_crb+MIU_TEST_AGT_CTRL));
for (j = 0; j < MAX_CTL_CHECK; j++) {
temp = readl(
- (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+ (mem_crb+MIU_TEST_AGT_CTRL));
if ((temp & MIU_TA_CTL_BUSY) == 0)
break;
}
if (j >= MAX_CTL_CHECK) {
- printk("%s: %s Fail to write through agent\n",
- __func__, netxen_nic_driver_name);
+ if (printk_ratelimit())
+ dev_err(&adapter->pdev->dev,
+ "failed to write through agent\n");
ret = -1;
break;
}
@@ -1657,10 +1783,11 @@ int
netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
u64 off, void *data, int size)
{
- unsigned long flags, mem_crb;
+ unsigned long flags;
int i, j = 0, k, start, end, loop, sz[2], off0[2];
uint32_t temp;
uint64_t off8, val, word[2] = {0, 0};
+ void __iomem *mem_crb;
/*
@@ -1675,31 +1802,32 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
sz[1] = size - sz[0];
loop = ((off0[0] + size - 1) >> 3) + 1;
- mem_crb = (unsigned long)pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+ mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
write_lock_irqsave(&adapter->adapter_lock, flags);
netxen_nic_pci_change_crbwindow_128M(adapter, 0);
for (i = 0; i < loop; i++) {
writel((uint32_t)(off8 + (i << 3)),
- (void *)(mem_crb+MIU_TEST_AGT_ADDR_LO));
+ (mem_crb+MIU_TEST_AGT_ADDR_LO));
writel(0,
- (void *)(mem_crb+MIU_TEST_AGT_ADDR_HI));
+ (mem_crb+MIU_TEST_AGT_ADDR_HI));
writel(MIU_TA_CTL_ENABLE,
- (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+ (mem_crb+MIU_TEST_AGT_CTRL));
writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
- (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+ (mem_crb+MIU_TEST_AGT_CTRL));
for (j = 0; j < MAX_CTL_CHECK; j++) {
temp = readl(
- (void *)(mem_crb+MIU_TEST_AGT_CTRL));
+ (mem_crb+MIU_TEST_AGT_CTRL));
if ((temp & MIU_TA_CTL_BUSY) == 0)
break;
}
if (j >= MAX_CTL_CHECK) {
- printk(KERN_ERR "%s: %s Fail to read through agent\n",
- __func__, netxen_nic_driver_name);
+ if (printk_ratelimit())
+ dev_err(&adapter->pdev->dev,
+ "failed to read through agent\n");
break;
}
@@ -1707,7 +1835,7 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
end = (off0[i] + sz[i] - 1) >> 2;
for (k = start; k <= end; k++) {
word[i] |= ((uint64_t) readl(
- (void *)(mem_crb +
+ (mem_crb +
MIU_TEST_AGT_RDDATA(k))) << (32*k));
}
}
@@ -1739,7 +1867,6 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
*(uint64_t *)data = val;
break;
}
- DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data);
return 0;
}
@@ -1835,8 +1962,9 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
}
if (j >= MAX_CTL_CHECK) {
- printk(KERN_ERR "%s: Fail to write through agent\n",
- netxen_nic_driver_name);
+ if (printk_ratelimit())
+ dev_err(&adapter->pdev->dev,
+ "failed to write through agent\n");
ret = -1;
break;
}
@@ -1905,8 +2033,9 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
}
if (j >= MAX_CTL_CHECK) {
- printk(KERN_ERR "%s: Fail to read through agent\n",
- netxen_nic_driver_name);
+ if (printk_ratelimit())
+ dev_err(&adapter->pdev->dev,
+ "failed to read through agent\n");
break;
}
@@ -1948,7 +2077,6 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
*(uint64_t *)data = val;
break;
}
- DPRINTK(1, INFO, "read %llx\n", *(unsigned long long *)data);
return 0;
}
@@ -1983,62 +2111,46 @@ u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off)
return temp;
}
-#if 0
-int
-netxen_nic_erase_pxe(struct netxen_adapter *adapter)
-{
- if (netxen_rom_fast_write(adapter, NETXEN_PXE_START, 0) == -1) {
- printk(KERN_ERR "%s: erase pxe failed\n",
- netxen_nic_driver_name);
- return -1;
- }
- return 0;
-}
-#endif /* 0 */
-
int netxen_nic_get_board_info(struct netxen_adapter *adapter)
{
- int rv = 0;
- int addr = NETXEN_BRDCFG_START;
- struct netxen_board_info *boardinfo;
- int index;
- u32 *ptr32;
-
- boardinfo = &adapter->ahw.boardcfg;
- ptr32 = (u32 *) boardinfo;
-
- for (index = 0; index < sizeof(struct netxen_board_info) / sizeof(u32);
- index++) {
- if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
- return -EIO;
- }
- ptr32++;
- addr += sizeof(u32);
- }
- if (boardinfo->magic != NETXEN_BDINFO_MAGIC) {
- printk("%s: ERROR reading %s board config."
- " Read %x, expected %x\n", netxen_nic_driver_name,
- netxen_nic_driver_name,
- boardinfo->magic, NETXEN_BDINFO_MAGIC);
- rv = -1;
- }
- if (boardinfo->header_version != NETXEN_BDINFO_VERSION) {
- printk("%s: Unknown board config version."
- " Read %x, expected %x\n", netxen_nic_driver_name,
- boardinfo->header_version, NETXEN_BDINFO_VERSION);
- rv = -1;
+ int offset, board_type, magic, header_version;
+ struct pci_dev *pdev = adapter->pdev;
+
+ offset = NETXEN_BRDCFG_START +
+ offsetof(struct netxen_board_info, magic);
+ if (netxen_rom_fast_read(adapter, offset, &magic))
+ return -EIO;
+
+ offset = NETXEN_BRDCFG_START +
+ offsetof(struct netxen_board_info, header_version);
+ if (netxen_rom_fast_read(adapter, offset, &header_version))
+ return -EIO;
+
+ if (magic != NETXEN_BDINFO_MAGIC ||
+ header_version != NETXEN_BDINFO_VERSION) {
+ dev_err(&pdev->dev,
+ "invalid board config, magic=%08x, version=%08x\n",
+ magic, header_version);
+ return -EIO;
}
- if (boardinfo->board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
+ offset = NETXEN_BRDCFG_START +
+ offsetof(struct netxen_board_info, board_type);
+ if (netxen_rom_fast_read(adapter, offset, &board_type))
+ return -EIO;
+
+ adapter->ahw.board_type = board_type;
+
+ if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
u32 gpio = netxen_nic_reg_read(adapter,
NETXEN_ROMUSB_GLB_PAD_GPIO_I);
if ((gpio & 0x8000) == 0)
- boardinfo->board_type = NETXEN_BRDTYPE_P3_10G_TP;
+ board_type = NETXEN_BRDTYPE_P3_10G_TP;
}
- switch ((netxen_brdtype_t) boardinfo->board_type) {
+ switch ((netxen_brdtype_t)board_type) {
case NETXEN_BRDTYPE_P2_SB35_4G:
- adapter->ahw.board_type = NETXEN_NIC_GBE;
+ adapter->ahw.port_type = NETXEN_NIC_GBE;
break;
case NETXEN_BRDTYPE_P2_SB31_10G:
case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
@@ -2054,7 +2166,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
case NETXEN_BRDTYPE_P3_10G_SFP_QT:
case NETXEN_BRDTYPE_P3_10G_XFP:
case NETXEN_BRDTYPE_P3_10000_BASE_T:
- adapter->ahw.board_type = NETXEN_NIC_XGBE;
+ adapter->ahw.port_type = NETXEN_NIC_XGBE;
break;
case NETXEN_BRDTYPE_P1_BD:
case NETXEN_BRDTYPE_P1_SB:
@@ -2063,20 +2175,19 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
case NETXEN_BRDTYPE_P3_REF_QG:
case NETXEN_BRDTYPE_P3_4_GB:
case NETXEN_BRDTYPE_P3_4_GB_MM:
- adapter->ahw.board_type = NETXEN_NIC_GBE;
+ adapter->ahw.port_type = NETXEN_NIC_GBE;
break;
case NETXEN_BRDTYPE_P3_10G_TP:
- adapter->ahw.board_type = (adapter->portnum < 2) ?
+ adapter->ahw.port_type = (adapter->portnum < 2) ?
NETXEN_NIC_XGBE : NETXEN_NIC_GBE;
break;
default:
- printk("%s: Unknown(%x)\n", netxen_nic_driver_name,
- boardinfo->board_type);
- rv = -ENODEV;
+ dev_err(&pdev->dev, "unknown board type %x\n", board_type);
+ adapter->ahw.port_type = NETXEN_NIC_XGBE;
break;
}
- return rv;
+ return 0;
}
/* NIU access sections */
@@ -2122,7 +2233,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
return;
}
- if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
adapter->hw_read_wx(adapter,
NETXEN_PORT_MODE_ADDR, &port_mode, 4);
if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
@@ -2177,32 +2288,27 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
}
}
-void netxen_nic_flash_print(struct netxen_adapter *adapter)
+void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
{
- u32 fw_major = 0;
- u32 fw_minor = 0;
- u32 fw_build = 0;
+ u32 fw_major, fw_minor, fw_build;
char brd_name[NETXEN_MAX_SHORT_NAME];
char serial_num[32];
- int i, addr;
- __le32 *ptr32;
-
- struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
+ int i, addr, val;
+ int *ptr32;
+ struct pci_dev *pdev = adapter->pdev;
adapter->driver_mismatch = 0;
- ptr32 = (u32 *)&serial_num;
+ ptr32 = (int *)&serial_num;
addr = NETXEN_USER_START +
offsetof(struct netxen_new_user_info, serial_num);
for (i = 0; i < 8; i++) {
- if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
- printk("%s: ERROR reading %s board userarea.\n",
- netxen_nic_driver_name,
- netxen_nic_driver_name);
+ if (netxen_rom_fast_read(adapter, addr, &val) == -1) {
+ dev_err(&pdev->dev, "error reading board info\n");
adapter->driver_mismatch = 1;
return;
}
- ptr32++;
+ ptr32[i] = cpu_to_le32(val);
addr += sizeof(u32);
}
@@ -2211,23 +2317,48 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB, &fw_build, 4);
adapter->fw_major = fw_major;
+ adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
if (adapter->portnum == 0) {
- get_brd_name_by_type(board_info->board_type, brd_name);
+ get_brd_name_by_type(adapter->ahw.board_type, brd_name);
printk(KERN_INFO "NetXen %s Board S/N %s Chip rev 0x%x\n",
brd_name, serial_num, adapter->ahw.revision_id);
- printk(KERN_INFO "NetXen Firmware version %d.%d.%d\n",
- fw_major, fw_minor, fw_build);
}
- if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) <
- NETXEN_VERSION_CODE(3, 4, 216)) {
+ if (adapter->fw_version < NETXEN_VERSION_CODE(3, 4, 216)) {
adapter->driver_mismatch = 1;
- printk(KERN_ERR "%s: firmware version %d.%d.%d unsupported\n",
- netxen_nic_driver_name,
+ dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
fw_major, fw_minor, fw_build);
return;
}
+
+ dev_info(&pdev->dev, "firmware version %d.%d.%d\n",
+ fw_major, fw_minor, fw_build);
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+ adapter->hw_read_wx(adapter,
+ NETXEN_MIU_MN_CONTROL, &i, 4);
+ adapter->ahw.cut_through = (i & 0x4) ? 1 : 0;
+ dev_info(&pdev->dev, "firmware running in %s mode\n",
+ adapter->ahw.cut_through ? "cut-through" : "legacy");
+ }
}
+int
+netxen_nic_wol_supported(struct netxen_adapter *adapter)
+{
+ u32 wol_cfg;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return 0;
+
+ wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+ if (wol_cfg & (1UL << adapter->portnum)) {
+ wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+ if (wol_cfg & (1 << adapter->portnum))
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h
index aae737dc77a8..04b47a7993cd 100644
--- a/drivers/net/netxen/netxen_nic_hw.h
+++ b/drivers/net/netxen/netxen_nic_hw.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Structures, enums, and macros for the MAC
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -54,37 +51,12 @@ static inline void writeq(u64 val, void __iomem * addr)
}
#endif
-static inline void netxen_nic_hw_block_write64(u64 __iomem * data_ptr,
- u64 __iomem * addr,
- int num_words)
-{
- int num;
- for (num = 0; num < num_words; num++) {
- writeq(readq((void __iomem *)data_ptr), addr);
- addr++;
- data_ptr++;
- }
-}
-
-static inline void netxen_nic_hw_block_read64(u64 __iomem * data_ptr,
- u64 __iomem * addr, int num_words)
-{
- int num;
- for (num = 0; num < num_words; num++) {
- writeq(readq((void __iomem *)addr), data_ptr);
- addr++;
- data_ptr++;
- }
-
-}
-
struct netxen_adapter;
#define NETXEN_PCI_MAPSIZE_BYTES (NETXEN_PCI_MAPSIZE << 20)
struct netxen_port;
void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
-void netxen_nic_flash_print(struct netxen_adapter *adapter);
typedef u8 netxen_ethernet_macaddr_t[6];
@@ -148,33 +120,6 @@ typedef enum {
#define netxen_gb_get_soft_reset(config_word) \
_netxen_crb_get_bit((config_word), 31)
-/*
- * NIU GB MAC Config Register 1 (applies to GB0, GB1, GB2, GB3)
- *
- * Bit 0 : duplex => 1:full duplex mode, 0:half duplex
- * Bit 1 : crc_enable => 1:append CRC to xmit frames, 0:dont append
- * Bit 2 : padshort => 1:pad short frames and add CRC, 0:dont pad
- * Bit 4 : checklength => 1:check framelen with actual,0:dont check
- * Bit 5 : hugeframes => 1:allow oversize xmit frames, 0:dont allow
- * Bits 8-9 : intfmode => 01:nibble (10/100), 10:byte (1000)
- * Bits 12-15 : preamblelen => preamble field length in bytes, default 7
- */
-
-#define netxen_gb_set_duplex(config_word) \
- ((config_word) |= 1 << 0)
-#define netxen_gb_set_crc_enable(config_word) \
- ((config_word) |= 1 << 1)
-#define netxen_gb_set_padshort(config_word) \
- ((config_word) |= 1 << 2)
-#define netxen_gb_set_checklength(config_word) \
- ((config_word) |= 1 << 4)
-#define netxen_gb_set_hugeframes(config_word) \
- ((config_word) |= 1 << 5)
-#define netxen_gb_set_preamblelen(config_word, val) \
- ((config_word) |= ((val) << 12) & 0xF000)
-#define netxen_gb_set_intfmode(config_word, val) \
- ((config_word) |= ((val) << 8) & 0x300)
-
#define netxen_gb_get_stationaddress_low(config_word) ((config_word) >> 16)
#define netxen_gb_set_mii_mgmt_clockselect(config_word, val) \
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index ffd37bea1628..0759c35f16ac 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Source file for NIC routines to initialize the Phantom Hardware
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -52,17 +49,9 @@ static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
#define NETXEN_NIC_XDMA_RESET 0x8000ff
-static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
- uint32_t ctx, uint32_t ringid);
-
-#if 0
-static void netxen_nic_locked_write_reg(struct netxen_adapter *adapter,
- unsigned long off, int *data)
-{
- void __iomem *addr = pci_base_offset(adapter, off);
- writel(*data, addr);
-}
-#endif /* 0 */
+static void
+netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
+ struct nx_host_rds_ring *rds_ring);
static void crb_addr_transform_setup(void)
{
@@ -160,23 +149,21 @@ void netxen_release_rx_buffers(struct netxen_adapter *adapter)
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
struct netxen_rx_buffer *rx_buf;
- int i, ctxid, ring;
-
- for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
- recv_ctx = &adapter->recv_ctx[ctxid];
- for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- rds_ring = &recv_ctx->rds_rings[ring];
- for (i = 0; i < rds_ring->max_rx_desc_count; ++i) {
- rx_buf = &(rds_ring->rx_buf_arr[i]);
- if (rx_buf->state == NETXEN_BUFFER_FREE)
- continue;
- pci_unmap_single(adapter->pdev,
- rx_buf->dma,
- rds_ring->dma_size,
- PCI_DMA_FROMDEVICE);
- if (rx_buf->skb != NULL)
- dev_kfree_skb_any(rx_buf->skb);
- }
+ int i, ring;
+
+ recv_ctx = &adapter->recv_ctx;
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
+ for (i = 0; i < rds_ring->num_desc; ++i) {
+ rx_buf = &(rds_ring->rx_buf_arr[i]);
+ if (rx_buf->state == NETXEN_BUFFER_FREE)
+ continue;
+ pci_unmap_single(adapter->pdev,
+ rx_buf->dma,
+ rds_ring->dma_size,
+ PCI_DMA_FROMDEVICE);
+ if (rx_buf->skb != NULL)
+ dev_kfree_skb_any(rx_buf->skb);
}
}
}
@@ -188,7 +175,7 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
int i, j;
cmd_buf = adapter->cmd_buf_arr;
- for (i = 0; i < adapter->max_tx_desc_count; i++) {
+ for (i = 0; i < adapter->num_txd; i++) {
buffrag = cmd_buf->frag_array;
if (buffrag->dma) {
pci_unmap_single(adapter->pdev, buffrag->dma,
@@ -204,7 +191,6 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
buffrag->dma = 0ULL;
}
}
- /* Free the skb we received in netxen_nic_xmit_frame */
if (cmd_buf->skb) {
dev_kfree_skb_any(cmd_buf->skb);
cmd_buf->skb = NULL;
@@ -217,18 +203,17 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
- int ctx, ring;
-
- for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) {
- recv_ctx = &adapter->recv_ctx[ctx];
- for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- rds_ring = &recv_ctx->rds_rings[ring];
- if (rds_ring->rx_buf_arr) {
- vfree(rds_ring->rx_buf_arr);
- rds_ring->rx_buf_arr = NULL;
- }
+ int ring;
+
+ recv_ctx = &adapter->recv_ctx;
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
+ if (rds_ring->rx_buf_arr) {
+ vfree(rds_ring->rx_buf_arr);
+ rds_ring->rx_buf_arr = NULL;
}
}
+
if (adapter->cmd_buf_arr)
vfree(adapter->cmd_buf_arr);
return;
@@ -238,90 +223,97 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_sds_ring *sds_ring;
struct netxen_rx_buffer *rx_buf;
- int ctx, ring, i, num_rx_bufs;
+ int ring, i, num_rx_bufs;
struct netxen_cmd_buffer *cmd_buf_arr;
struct net_device *netdev = adapter->netdev;
- cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
+ cmd_buf_arr =
+ (struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(adapter));
if (cmd_buf_arr == NULL) {
printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n",
netdev->name);
return -ENOMEM;
}
- memset(cmd_buf_arr, 0, TX_RINGSIZE);
+ memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(adapter));
adapter->cmd_buf_arr = cmd_buf_arr;
- for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) {
- recv_ctx = &adapter->recv_ctx[ctx];
- for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- rds_ring = &recv_ctx->rds_rings[ring];
- switch (RCV_DESC_TYPE(ring)) {
- case RCV_DESC_NORMAL:
- rds_ring->max_rx_desc_count =
- adapter->max_rx_desc_count;
- rds_ring->flags = RCV_DESC_NORMAL;
- if (adapter->ahw.cut_through) {
- rds_ring->dma_size =
- NX_CT_DEFAULT_RX_BUF_LEN;
- rds_ring->skb_size =
- NX_CT_DEFAULT_RX_BUF_LEN;
- } else {
- rds_ring->dma_size = RX_DMA_MAP_LEN;
- rds_ring->skb_size =
- MAX_RX_BUFFER_LENGTH;
- }
- break;
-
- case RCV_DESC_JUMBO:
- rds_ring->max_rx_desc_count =
- adapter->max_jumbo_rx_desc_count;
- rds_ring->flags = RCV_DESC_JUMBO;
- if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
- rds_ring->dma_size =
- NX_P3_RX_JUMBO_BUF_MAX_LEN;
- else
- rds_ring->dma_size =
- NX_P2_RX_JUMBO_BUF_MAX_LEN;
+ recv_ctx = &adapter->recv_ctx;
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
+ switch (ring) {
+ case RCV_RING_NORMAL:
+ rds_ring->num_desc = adapter->num_rxd;
+ if (adapter->ahw.cut_through) {
+ rds_ring->dma_size =
+ NX_CT_DEFAULT_RX_BUF_LEN;
rds_ring->skb_size =
- rds_ring->dma_size + NET_IP_ALIGN;
- break;
+ NX_CT_DEFAULT_RX_BUF_LEN;
+ } else {
+ rds_ring->dma_size = RX_DMA_MAP_LEN;
+ rds_ring->skb_size =
+ MAX_RX_BUFFER_LENGTH;
+ }
+ break;
- case RCV_RING_LRO:
- rds_ring->max_rx_desc_count =
- adapter->max_lro_rx_desc_count;
- rds_ring->flags = RCV_DESC_LRO;
- rds_ring->dma_size = RX_LRO_DMA_MAP_LEN;
- rds_ring->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
- break;
+ case RCV_RING_JUMBO:
+ rds_ring->num_desc = adapter->num_jumbo_rxd;
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ rds_ring->dma_size =
+ NX_P3_RX_JUMBO_BUF_MAX_LEN;
+ else
+ rds_ring->dma_size =
+ NX_P2_RX_JUMBO_BUF_MAX_LEN;
+ rds_ring->skb_size =
+ rds_ring->dma_size + NET_IP_ALIGN;
+ break;
- }
- rds_ring->rx_buf_arr = (struct netxen_rx_buffer *)
- vmalloc(RCV_BUFFSIZE);
- if (rds_ring->rx_buf_arr == NULL) {
- printk(KERN_ERR "%s: Failed to allocate "
- "rx buffer ring %d\n",
- netdev->name, ring);
- /* free whatever was already allocated */
- goto err_out;
- }
- memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE);
- INIT_LIST_HEAD(&rds_ring->free_list);
- /*
- * Now go through all of them, set reference handles
- * and put them in the queues.
- */
- num_rx_bufs = rds_ring->max_rx_desc_count;
- rx_buf = rds_ring->rx_buf_arr;
- for (i = 0; i < num_rx_bufs; i++) {
- list_add_tail(&rx_buf->list,
- &rds_ring->free_list);
- rx_buf->ref_handle = i;
- rx_buf->state = NETXEN_BUFFER_FREE;
- rx_buf++;
- }
+ case RCV_RING_LRO:
+ rds_ring->num_desc = adapter->num_lro_rxd;
+ rds_ring->dma_size = RX_LRO_DMA_MAP_LEN;
+ rds_ring->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
+ break;
+
+ }
+ rds_ring->rx_buf_arr = (struct netxen_rx_buffer *)
+ vmalloc(RCV_BUFF_RINGSIZE(rds_ring));
+ if (rds_ring->rx_buf_arr == NULL) {
+ printk(KERN_ERR "%s: Failed to allocate "
+ "rx buffer ring %d\n",
+ netdev->name, ring);
+ /* free whatever was already allocated */
+ goto err_out;
+ }
+ memset(rds_ring->rx_buf_arr, 0, RCV_BUFF_RINGSIZE(rds_ring));
+ INIT_LIST_HEAD(&rds_ring->free_list);
+ /*
+ * Now go through all of them, set reference handles
+ * and put them in the queues.
+ */
+ num_rx_bufs = rds_ring->num_desc;
+ rx_buf = rds_ring->rx_buf_arr;
+ for (i = 0; i < num_rx_bufs; i++) {
+ list_add_tail(&rx_buf->list,
+ &rds_ring->free_list);
+ rx_buf->ref_handle = i;
+ rx_buf->state = NETXEN_BUFFER_FREE;
+ rx_buf++;
}
+ spin_lock_init(&rds_ring->lock);
+ }
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ sds_ring->irq = adapter->msix_entries[ring].vector;
+ sds_ring->clean_tx = (ring == 0);
+ sds_ring->post_rxd = (ring == 0);
+ sds_ring->adapter = adapter;
+ sds_ring->num_desc = adapter->num_rxd;
+
+ for (i = 0; i < NUM_RCV_DESC_RINGS; i++)
+ INIT_LIST_HEAD(&sds_ring->free_list[i]);
}
return 0;
@@ -333,7 +325,7 @@ err_out:
void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
{
- switch (adapter->ahw.board_type) {
+ switch (adapter->ahw.port_type) {
case NETXEN_NIC_GBE:
adapter->enable_phy_interrupts =
netxen_niu_gbe_enable_phy_interrupts;
@@ -399,9 +391,6 @@ static u32 netxen_decode_crb_addr(u32 addr)
static long rom_max_timeout = 100;
static long rom_lock_timeout = 10000;
-#if 0
-static long rom_write_timeout = 700;
-#endif
static int rom_lock(struct netxen_adapter *adapter)
{
@@ -452,38 +441,6 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
return 0;
}
-#if 0
-static int netxen_rom_wren(struct netxen_adapter *adapter)
-{
- /* Set write enable latch in ROM status register */
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
- M25P_INSTR_WREN);
- if (netxen_wait_rom_done(adapter)) {
- return -1;
- }
- return 0;
-}
-
-static unsigned int netxen_rdcrbreg(struct netxen_adapter *adapter,
- unsigned int addr)
-{
- unsigned int data = 0xdeaddead;
- data = netxen_nic_reg_read(adapter, addr);
- return data;
-}
-
-static int netxen_do_rom_rdsr(struct netxen_adapter *adapter)
-{
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
- M25P_INSTR_RDSR);
- if (netxen_wait_rom_done(adapter)) {
- return -1;
- }
- return netxen_rdcrbreg(adapter, NETXEN_ROMUSB_ROM_RDATA);
-}
-#endif
-
static void netxen_rom_unlock(struct netxen_adapter *adapter)
{
u32 val;
@@ -493,44 +450,6 @@ static void netxen_rom_unlock(struct netxen_adapter *adapter)
}
-#if 0
-static int netxen_rom_wip_poll(struct netxen_adapter *adapter)
-{
- long timeout = 0;
- long wip = 1;
- int val;
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
- while (wip != 0) {
- val = netxen_do_rom_rdsr(adapter);
- wip = val & 1;
- timeout++;
- if (timeout > rom_max_timeout) {
- return -1;
- }
- }
- return 0;
-}
-
-static int do_rom_fast_write(struct netxen_adapter *adapter, int addr,
- int data)
-{
- if (netxen_rom_wren(adapter)) {
- return -1;
- }
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_WDATA, data);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
- M25P_INSTR_PP);
- if (netxen_wait_rom_done(adapter)) {
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
- return -1;
- }
-
- return netxen_rom_wip_poll(adapter);
-}
-#endif
-
static int do_rom_fast_read(struct netxen_adapter *adapter,
int addr, int *valp)
{
@@ -597,284 +516,6 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
return ret;
}
-#if 0
-int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data)
-{
- int ret = 0;
-
- if (rom_lock(adapter) != 0) {
- return -1;
- }
- ret = do_rom_fast_write(adapter, addr, data);
- netxen_rom_unlock(adapter);
- return ret;
-}
-
-static int do_rom_fast_write_words(struct netxen_adapter *adapter,
- int addr, u8 *bytes, size_t size)
-{
- int addridx = addr;
- int ret = 0;
-
- while (addridx < (addr + size)) {
- int last_attempt = 0;
- int timeout = 0;
- int data;
-
- data = le32_to_cpu((*(__le32*)bytes));
- ret = do_rom_fast_write(adapter, addridx, data);
- if (ret < 0)
- return ret;
-
- while(1) {
- int data1;
-
- ret = do_rom_fast_read(adapter, addridx, &data1);
- if (ret < 0)
- return ret;
-
- if (data1 == data)
- break;
-
- if (timeout++ >= rom_write_timeout) {
- if (last_attempt++ < 4) {
- ret = do_rom_fast_write(adapter,
- addridx, data);
- if (ret < 0)
- return ret;
- }
- else {
- printk(KERN_INFO "Data write did not "
- "succeed at address 0x%x\n", addridx);
- break;
- }
- }
- }
-
- bytes += 4;
- addridx += 4;
- }
-
- return ret;
-}
-
-int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr,
- u8 *bytes, size_t size)
-{
- int ret = 0;
-
- ret = rom_lock(adapter);
- if (ret < 0)
- return ret;
-
- ret = do_rom_fast_write_words(adapter, addr, bytes, size);
- netxen_rom_unlock(adapter);
-
- return ret;
-}
-
-static int netxen_rom_wrsr(struct netxen_adapter *adapter, int data)
-{
- int ret;
-
- ret = netxen_rom_wren(adapter);
- if (ret < 0)
- return ret;
-
- netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_ROM_WDATA, data);
- netxen_crb_writelit_adapter(adapter,
- NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0x1);
-
- ret = netxen_wait_rom_done(adapter);
- if (ret < 0)
- return ret;
-
- return netxen_rom_wip_poll(adapter);
-}
-
-static int netxen_rom_rdsr(struct netxen_adapter *adapter)
-{
- int ret;
-
- ret = rom_lock(adapter);
- if (ret < 0)
- return ret;
-
- ret = netxen_do_rom_rdsr(adapter);
- netxen_rom_unlock(adapter);
- return ret;
-}
-
-int netxen_backup_crbinit(struct netxen_adapter *adapter)
-{
- int ret = FLASH_SUCCESS;
- int val;
- char *buffer = kmalloc(NETXEN_FLASH_SECTOR_SIZE, GFP_KERNEL);
-
- if (!buffer)
- return -ENOMEM;
- /* unlock sector 63 */
- val = netxen_rom_rdsr(adapter);
- val = val & 0xe3;
- ret = netxen_rom_wrsr(adapter, val);
- if (ret != FLASH_SUCCESS)
- goto out_kfree;
-
- ret = netxen_rom_wip_poll(adapter);
- if (ret != FLASH_SUCCESS)
- goto out_kfree;
-
- /* copy sector 0 to sector 63 */
- ret = netxen_rom_fast_read_words(adapter, NETXEN_CRBINIT_START,
- buffer, NETXEN_FLASH_SECTOR_SIZE);
- if (ret != FLASH_SUCCESS)
- goto out_kfree;
-
- ret = netxen_rom_fast_write_words(adapter, NETXEN_FIXED_START,
- buffer, NETXEN_FLASH_SECTOR_SIZE);
- if (ret != FLASH_SUCCESS)
- goto out_kfree;
-
- /* lock sector 63 */
- val = netxen_rom_rdsr(adapter);
- if (!(val & 0x8)) {
- val |= (0x1 << 2);
- /* lock sector 63 */
- if (netxen_rom_wrsr(adapter, val) == 0) {
- ret = netxen_rom_wip_poll(adapter);
- if (ret != FLASH_SUCCESS)
- goto out_kfree;
-
- /* lock SR writes */
- ret = netxen_rom_wip_poll(adapter);
- if (ret != FLASH_SUCCESS)
- goto out_kfree;
- }
- }
-
-out_kfree:
- kfree(buffer);
- return ret;
-}
-
-static int netxen_do_rom_se(struct netxen_adapter *adapter, int addr)
-{
- netxen_rom_wren(adapter);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
- M25P_INSTR_SE);
- if (netxen_wait_rom_done(adapter)) {
- netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
- return -1;
- }
- return netxen_rom_wip_poll(adapter);
-}
-
-static void check_erased_flash(struct netxen_adapter *adapter, int addr)
-{
- int i;
- int val;
- int count = 0, erased_errors = 0;
- int range;
-
- range = (addr == NETXEN_USER_START) ?
- NETXEN_FIXED_START : addr + NETXEN_FLASH_SECTOR_SIZE;
-
- for (i = addr; i < range; i += 4) {
- netxen_rom_fast_read(adapter, i, &val);
- if (val != 0xffffffff)
- erased_errors++;
- count++;
- }
-
- if (erased_errors)
- printk(KERN_INFO "0x%x out of 0x%x words fail to be erased "
- "for sector address: %x\n", erased_errors, count, addr);
-}
-
-int netxen_rom_se(struct netxen_adapter *adapter, int addr)
-{
- int ret = 0;
- if (rom_lock(adapter) != 0) {
- return -1;
- }
- ret = netxen_do_rom_se(adapter, addr);
- netxen_rom_unlock(adapter);
- msleep(30);
- check_erased_flash(adapter, addr);
-
- return ret;
-}
-
-static int netxen_flash_erase_sections(struct netxen_adapter *adapter,
- int start, int end)
-{
- int ret = FLASH_SUCCESS;
- int i;
-
- for (i = start; i < end; i++) {
- ret = netxen_rom_se(adapter, i * NETXEN_FLASH_SECTOR_SIZE);
- if (ret)
- break;
- ret = netxen_rom_wip_poll(adapter);
- if (ret < 0)
- return ret;
- }
-
- return ret;
-}
-
-int
-netxen_flash_erase_secondary(struct netxen_adapter *adapter)
-{
- int ret = FLASH_SUCCESS;
- int start, end;
-
- start = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE;
- end = NETXEN_USER_START / NETXEN_FLASH_SECTOR_SIZE;
- ret = netxen_flash_erase_sections(adapter, start, end);
-
- return ret;
-}
-
-int
-netxen_flash_erase_primary(struct netxen_adapter *adapter)
-{
- int ret = FLASH_SUCCESS;
- int start, end;
-
- start = NETXEN_PRIMARY_START / NETXEN_FLASH_SECTOR_SIZE;
- end = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE;
- ret = netxen_flash_erase_sections(adapter, start, end);
-
- return ret;
-}
-
-void netxen_halt_pegs(struct netxen_adapter *adapter)
-{
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x3c, 1);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x3c, 1);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x3c, 1);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x3c, 1);
-}
-
-int netxen_flash_unlock(struct netxen_adapter *adapter)
-{
- int ret = 0;
-
- ret = netxen_rom_wrsr(adapter, 0);
- if (ret < 0)
- return ret;
-
- ret = netxen_rom_wren(adapter);
- if (ret < 0)
- return ret;
-
- return ret;
-}
-#endif /* 0 */
-
#define NETXEN_BOARDTYPE 0x4008
#define NETXEN_BOARDNUM 0x400c
#define NETXEN_CHIPNUM 0x4010
@@ -1168,6 +809,40 @@ int netxen_receive_peg_ready(struct netxen_adapter *adapter)
return 0;
}
+static int
+netxen_alloc_rx_skb(struct netxen_adapter *adapter,
+ struct nx_host_rds_ring *rds_ring,
+ struct netxen_rx_buffer *buffer)
+{
+ struct sk_buff *skb;
+ dma_addr_t dma;
+ struct pci_dev *pdev = adapter->pdev;
+
+ buffer->skb = dev_alloc_skb(rds_ring->skb_size);
+ if (!buffer->skb)
+ return 1;
+
+ skb = buffer->skb;
+
+ if (!adapter->ahw.cut_through)
+ skb_reserve(skb, 2);
+
+ dma = pci_map_single(pdev, skb->data,
+ rds_ring->dma_size, PCI_DMA_FROMDEVICE);
+
+ if (pci_dma_mapping_error(pdev, dma)) {
+ dev_kfree_skb_any(skb);
+ buffer->skb = NULL;
+ return 1;
+ }
+
+ buffer->skb = skb;
+ buffer->dma = dma;
+ buffer->state = NETXEN_BUFFER_BUSY;
+
+ return 0;
+}
+
static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter,
struct nx_host_rds_ring *rds_ring, u16 index, u16 cksum)
{
@@ -1192,164 +867,121 @@ static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter,
skb->dev = adapter->netdev;
buffer->skb = NULL;
-
no_skb:
buffer->state = NETXEN_BUFFER_FREE;
- buffer->lro_current_frags = 0;
- buffer->lro_expected_frags = 0;
- list_add_tail(&buffer->list, &rds_ring->free_list);
return skb;
}
-/*
- * netxen_process_rcv() send the received packet to the protocol stack.
- * and if the number of receives exceeds RX_BUFFERS_REFILL, then we
- * invoke the routine to send more rx buffers to the Phantom...
- */
-static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
- struct status_desc *desc, struct status_desc *frag_desc)
+static struct netxen_rx_buffer *
+netxen_process_rcv(struct netxen_adapter *adapter,
+ int ring, int index, int length, int cksum, int pkt_offset)
{
struct net_device *netdev = adapter->netdev;
- u64 sts_data = le64_to_cpu(desc->status_desc_data);
- int index = netxen_get_sts_refhandle(sts_data);
- struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
struct netxen_rx_buffer *buffer;
struct sk_buff *skb;
- u32 length = netxen_get_sts_totallength(sts_data);
- u32 desc_ctx;
- u16 pkt_offset = 0, cksum;
- struct nx_host_rds_ring *rds_ring;
+ struct nx_host_rds_ring *rds_ring = &recv_ctx->rds_rings[ring];
- desc_ctx = netxen_get_sts_type(sts_data);
- if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) {
- printk("%s: %s Bad Rcv descriptor ring\n",
- netxen_nic_driver_name, netdev->name);
- return;
- }
+ if (unlikely(index > rds_ring->num_desc))
+ return NULL;
- rds_ring = &recv_ctx->rds_rings[desc_ctx];
- if (unlikely(index > rds_ring->max_rx_desc_count)) {
- DPRINTK(ERR, "Got a buffer index:%x Max is %x\n",
- index, rds_ring->max_rx_desc_count);
- return;
- }
buffer = &rds_ring->rx_buf_arr[index];
- if (desc_ctx == RCV_DESC_LRO_CTXID) {
- buffer->lro_current_frags++;
- if (netxen_get_sts_desc_lro_last_frag(desc)) {
- buffer->lro_expected_frags =
- netxen_get_sts_desc_lro_cnt(desc);
- buffer->lro_length = length;
- }
- if (buffer->lro_current_frags != buffer->lro_expected_frags) {
- if (buffer->lro_expected_frags != 0) {
- printk("LRO: (refhandle:%x) recv frag. "
- "wait for last. flags: %x expected:%d "
- "have:%d\n", index,
- netxen_get_sts_desc_lro_last_frag(desc),
- buffer->lro_expected_frags,
- buffer->lro_current_frags);
- }
- return;
- }
- }
-
- cksum = netxen_get_sts_status(sts_data);
skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum);
if (!skb)
- return;
+ return buffer;
- if (desc_ctx == RCV_DESC_LRO_CTXID) {
- /* True length was only available on the last pkt */
- skb_put(skb, buffer->lro_length);
- } else {
- if (length > rds_ring->skb_size)
- skb_put(skb, rds_ring->skb_size);
- else
- skb_put(skb, length);
+ if (length > rds_ring->skb_size)
+ skb_put(skb, rds_ring->skb_size);
+ else
+ skb_put(skb, length);
- pkt_offset = netxen_get_sts_pkt_offset(sts_data);
- if (pkt_offset)
- skb_pull(skb, pkt_offset);
- }
+
+ if (pkt_offset)
+ skb_pull(skb, pkt_offset);
skb->protocol = eth_type_trans(skb, netdev);
- /*
- * rx buffer chaining is disabled, walk and free
- * any spurious rx buffer chain.
- */
- if (frag_desc) {
- u16 i, nr_frags = desc->nr_frags;
+ netif_receive_skb(skb);
- dev_kfree_skb_any(skb);
- for (i = 0; i < nr_frags; i++) {
- index = le16_to_cpu(frag_desc->frag_handles[i]);
- skb = netxen_process_rxbuf(adapter,
- rds_ring, index, cksum);
- if (skb)
- dev_kfree_skb_any(skb);
- }
- adapter->stats.rxdropped++;
- } else {
- netif_receive_skb(skb);
+ adapter->stats.no_rcv++;
+ adapter->stats.rxbytes += length;
- adapter->stats.no_rcv++;
- adapter->stats.rxbytes += length;
- }
+ return buffer;
}
-/* Process Receive status ring */
-u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
+#define netxen_merge_rx_buffers(list, head) \
+ do { list_splice_tail_init(list, head); } while (0);
+
+int
+netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
{
- struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
- struct status_desc *desc_head = recv_ctx->rcv_status_desc_head;
- struct status_desc *desc, *frag_desc;
- u32 consumer = recv_ctx->status_rx_consumer;
- int count = 0, ring;
+ struct netxen_adapter *adapter = sds_ring->adapter;
+
+ struct list_head *cur;
+
+ struct status_desc *desc;
+ struct netxen_rx_buffer *rxbuf;
+
+ u32 consumer = sds_ring->consumer;
+
+ int count = 0;
u64 sts_data;
- u16 opcode;
+ int opcode, ring, index, length, cksum, pkt_offset;
while (count < max) {
- desc = &desc_head[consumer];
- if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) {
- DPRINTK(ERR, "desc %p ownedby %x\n", desc,
- netxen_get_sts_owner(desc));
+ desc = &sds_ring->desc_head[consumer];
+ sts_data = le64_to_cpu(desc->status_desc_data);
+
+ if (!(sts_data & STATUS_OWNER_HOST))
break;
- }
- sts_data = le64_to_cpu(desc->status_desc_data);
+ ring = netxen_get_sts_type(sts_data);
+ if (ring > RCV_RING_JUMBO)
+ continue;
+
opcode = netxen_get_sts_opcode(sts_data);
- frag_desc = NULL;
- if (opcode == NETXEN_NIC_RXPKT_DESC) {
- if (desc->nr_frags) {
- consumer = get_next_index(consumer,
- adapter->max_rx_desc_count);
- frag_desc = &desc_head[consumer];
- netxen_set_sts_owner(frag_desc,
- STATUS_OWNER_PHANTOM);
- }
- }
- netxen_process_rcv(adapter, ctxid, desc, frag_desc);
+ index = netxen_get_sts_refhandle(sts_data);
+ length = netxen_get_sts_totallength(sts_data);
+ cksum = netxen_get_sts_status(sts_data);
+ pkt_offset = netxen_get_sts_pkt_offset(sts_data);
+
+ rxbuf = netxen_process_rcv(adapter, ring, index,
+ length, cksum, pkt_offset);
+
+ if (rxbuf)
+ list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
- netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM);
+ desc->status_desc_data = cpu_to_le64(STATUS_OWNER_PHANTOM);
- consumer = get_next_index(consumer,
- adapter->max_rx_desc_count);
+ consumer = get_next_index(consumer, sds_ring->num_desc);
count++;
}
- for (ring = 0; ring < adapter->max_rds_rings; ring++)
- netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
- /* update the consumer index in phantom */
- if (count) {
- recv_ctx->status_rx_consumer = consumer;
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ struct nx_host_rds_ring *rds_ring =
+ &adapter->recv_ctx.rds_rings[ring];
- /* Window = 1 */
+ if (!list_empty(&sds_ring->free_list[ring])) {
+ list_for_each(cur, &sds_ring->free_list[ring]) {
+ rxbuf = list_entry(cur,
+ struct netxen_rx_buffer, list);
+ netxen_alloc_rx_skb(adapter, rds_ring, rxbuf);
+ }
+ spin_lock(&rds_ring->lock);
+ netxen_merge_rx_buffers(&sds_ring->free_list[ring],
+ &rds_ring->free_list);
+ spin_unlock(&rds_ring->lock);
+ }
+
+ netxen_post_rx_buffers_nodb(adapter, rds_ring);
+ }
+
+ if (count) {
+ sds_ring->consumer = consumer;
adapter->pci_write_normalize(adapter,
- recv_ctx->crb_sts_consumer, consumer);
+ sds_ring->crb_sts_consumer, consumer);
}
return count;
@@ -1366,7 +998,11 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
struct netxen_skb_frag *frag;
int done = 0;
+ if (!spin_trylock(&adapter->tx_clean_lock))
+ return 1;
+
last_consumer = adapter->last_cmd_consumer;
+ barrier(); /* cmd_consumer can change underneath */
consumer = le32_to_cpu(*(adapter->cmd_consumer));
while (last_consumer != consumer) {
@@ -1389,7 +1025,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
}
last_consumer = get_next_index(last_consumer,
- adapter->max_tx_desc_count);
+ adapter->num_txd);
if (++count >= MAX_STATUS_HANDLE)
break;
}
@@ -1417,75 +1053,55 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
* There is still a possible race condition and the host could miss an
* interrupt. The card has to take care of this.
*/
+ barrier(); /* cmd_consumer can change underneath */
consumer = le32_to_cpu(*(adapter->cmd_consumer));
done = (last_consumer == consumer);
+ spin_unlock(&adapter->tx_clean_lock);
return (done);
}
-/*
- * netxen_post_rx_buffers puts buffer in the Phantom memory
- */
-void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
+void
+netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
+ struct nx_host_rds_ring *rds_ring)
{
- struct pci_dev *pdev = adapter->pdev;
- struct sk_buff *skb;
- struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
- struct nx_host_rds_ring *rds_ring = NULL;
- uint producer;
struct rcv_desc *pdesc;
struct netxen_rx_buffer *buffer;
- int count = 0;
+ int producer, count = 0;
netxen_ctx_msg msg = 0;
- dma_addr_t dma;
struct list_head *head;
- rds_ring = &recv_ctx->rds_rings[ringid];
-
producer = rds_ring->producer;
- head = &rds_ring->free_list;
- /* We can start writing rx descriptors into the phantom memory. */
+ spin_lock(&rds_ring->lock);
+ head = &rds_ring->free_list;
while (!list_empty(head)) {
- skb = dev_alloc_skb(rds_ring->skb_size);
- if (unlikely(!skb)) {
- break;
- }
-
- if (!adapter->ahw.cut_through)
- skb_reserve(skb, 2);
+ buffer = list_entry(head->next, struct netxen_rx_buffer, list);
- dma = pci_map_single(pdev, skb->data,
- rds_ring->dma_size, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, dma)) {
- dev_kfree_skb_any(skb);
- break;
+ if (!buffer->skb) {
+ if (netxen_alloc_rx_skb(adapter, rds_ring, buffer))
+ break;
}
count++;
- buffer = list_entry(head->next, struct netxen_rx_buffer, list);
list_del(&buffer->list);
- buffer->skb = skb;
- buffer->state = NETXEN_BUFFER_BUSY;
- buffer->dma = dma;
-
/* make a rcv descriptor */
pdesc = &rds_ring->desc_head[producer];
- pdesc->addr_buffer = cpu_to_le64(dma);
+ pdesc->addr_buffer = cpu_to_le64(buffer->dma);
pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
- producer = get_next_index(producer, rds_ring->max_rx_desc_count);
+ producer = get_next_index(producer, rds_ring->num_desc);
}
- /* if we did allocate buffers, then write the count to Phantom */
+ spin_unlock(&rds_ring->lock);
+
if (count) {
rds_ring->producer = producer;
- /* Window = 1 */
adapter->pci_write_normalize(adapter,
rds_ring->crb_rcv_producer,
- (producer-1) & (rds_ring->max_rx_desc_count-1));
+ (producer-1) & (rds_ring->num_desc-1));
if (adapter->fw_major < 4) {
/*
@@ -1496,9 +1112,8 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID);
netxen_set_msg_privid(msg);
netxen_set_msg_count(msg,
- ((producer -
- 1) & (rds_ring->
- max_rx_desc_count - 1)));
+ ((producer - 1) &
+ (rds_ring->num_desc - 1)));
netxen_set_msg_ctxid(msg, adapter->portnum);
netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
writel(msg,
@@ -1508,68 +1123,49 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
}
}
-static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
- uint32_t ctx, uint32_t ringid)
+static void
+netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
+ struct nx_host_rds_ring *rds_ring)
{
- struct pci_dev *pdev = adapter->pdev;
- struct sk_buff *skb;
- struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
- struct nx_host_rds_ring *rds_ring = NULL;
- u32 producer;
struct rcv_desc *pdesc;
struct netxen_rx_buffer *buffer;
- int count = 0;
+ int producer, count = 0;
struct list_head *head;
- dma_addr_t dma;
-
- rds_ring = &recv_ctx->rds_rings[ringid];
producer = rds_ring->producer;
+ if (!spin_trylock(&rds_ring->lock))
+ return;
+
head = &rds_ring->free_list;
- /* We can start writing rx descriptors into the phantom memory. */
while (!list_empty(head)) {
- skb = dev_alloc_skb(rds_ring->skb_size);
- if (unlikely(!skb)) {
- break;
- }
-
- if (!adapter->ahw.cut_through)
- skb_reserve(skb, 2);
+ buffer = list_entry(head->next, struct netxen_rx_buffer, list);
- dma = pci_map_single(pdev, skb->data,
- rds_ring->dma_size, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, dma)) {
- dev_kfree_skb_any(skb);
- break;
+ if (!buffer->skb) {
+ if (netxen_alloc_rx_skb(adapter, rds_ring, buffer))
+ break;
}
count++;
- buffer = list_entry(head->next, struct netxen_rx_buffer, list);
list_del(&buffer->list);
- buffer->skb = skb;
- buffer->state = NETXEN_BUFFER_BUSY;
- buffer->dma = dma;
-
/* make a rcv descriptor */
pdesc = &rds_ring->desc_head[producer];
pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
pdesc->addr_buffer = cpu_to_le64(buffer->dma);
- producer = get_next_index(producer, rds_ring->max_rx_desc_count);
+ producer = get_next_index(producer, rds_ring->num_desc);
}
- /* if we did allocate buffers, then write the count to Phantom */
if (count) {
rds_ring->producer = producer;
- /* Window = 1 */
adapter->pci_write_normalize(adapter,
rds_ring->crb_rcv_producer,
- (producer-1) & (rds_ring->max_rx_desc_count-1));
+ (producer - 1) & (rds_ring->num_desc - 1));
wmb();
}
+ spin_unlock(&rds_ring->lock);
}
void netxen_nic_clear_stats(struct netxen_adapter *adapter)
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index c172b6e24a96..1af47257ba82 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Main source file for NetXen NIC Driver on Linux
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -97,20 +94,6 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
-/*
- * In netxen_nic_down(), we must wait for any pending callback requests into
- * netxen_watchdog_task() to complete; eg otherwise the watchdog_timer could be
- * reenabled right after it is deleted in netxen_nic_down().
- * FLUSH_SCHEDULED_WORK() does this synchronization.
- *
- * Normally, schedule_work()/flush_scheduled_work() could have worked, but
- * netxen_nic_close() is invoked with kernel rtnl lock held. netif_carrier_off()
- * call in netxen_nic_close() triggers a schedule_work(&linkwatch_work), and a
- * subsequent call to flush_scheduled_work() in netxen_nic_down() would cause
- * linkwatch_event() to be executed which also attempts to acquire the rtnl
- * lock thus causing a deadlock.
- */
-
static struct workqueue_struct *netxen_workq;
#define SCHEDULE_WORK(tp) queue_work(netxen_workq, tp)
#define FLUSH_SCHEDULED_WORK() flush_workqueue(netxen_workq)
@@ -152,130 +135,148 @@ static uint32_t msi_tgt_status[8] = {
static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
-static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring)
{
- adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0);
+ struct netxen_adapter *adapter = sds_ring->adapter;
+
+ adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0);
}
-static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring)
{
- adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1);
+ struct netxen_adapter *adapter = sds_ring->adapter;
+
+ adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0x1);
if (!NETXEN_IS_MSI_FAMILY(adapter))
adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_mask_reg, 0xfbff);
}
+static void
+netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev)
+{
+ int ring;
+ struct nx_host_sds_ring *sds_ring;
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+ if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
+ adapter->max_sds_rings = (num_online_cpus() >= 4) ? 4 : 2;
+ else
+ adapter->max_sds_rings = 1;
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ netif_napi_add(netdev, &sds_ring->napi,
+ netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
+ }
+}
+
+static void
+netxen_napi_enable(struct netxen_adapter *adapter)
+{
+ int ring;
+ struct nx_host_sds_ring *sds_ring;
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ napi_enable(&sds_ring->napi);
+ netxen_nic_enable_int(sds_ring);
+ }
+}
+
+static void
+netxen_napi_disable(struct netxen_adapter *adapter)
+{
+ int ring;
+ struct nx_host_sds_ring *sds_ring;
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ netxen_nic_disable_int(sds_ring);
+ napi_disable(&sds_ring->napi);
+ }
+}
+
static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
{
struct pci_dev *pdev = adapter->pdev;
- int err;
- uint64_t mask;
-
-#ifdef CONFIG_IA64
- adapter->dma_mask = DMA_32BIT_MASK;
-#else
- if (revision_id >= NX_P3_B0) {
- /* should go to DMA_64BIT_MASK */
- adapter->dma_mask = DMA_39BIT_MASK;
- mask = DMA_39BIT_MASK;
- } else if (revision_id == NX_P3_A2) {
- adapter->dma_mask = DMA_39BIT_MASK;
- mask = DMA_39BIT_MASK;
- } else if (revision_id == NX_P2_C1) {
- adapter->dma_mask = DMA_35BIT_MASK;
- mask = DMA_35BIT_MASK;
- } else {
- adapter->dma_mask = DMA_32BIT_MASK;
- mask = DMA_32BIT_MASK;
- goto set_32_bit_mask;
- }
+ uint64_t mask, cmask;
+ adapter->pci_using_dac = 0;
+
+ mask = DMA_32BIT_MASK;
/*
* Consistent DMA mask is set to 32 bit because it cannot be set to
* 35 bits. For P3 also leave it at 32 bits for now. Only the rings
* come off this pool.
*/
+ cmask = DMA_32BIT_MASK;
+
+#ifndef CONFIG_IA64
+ if (revision_id >= NX_P3_B0)
+ mask = DMA_39BIT_MASK;
+ else if (revision_id == NX_P2_C1)
+ mask = DMA_35BIT_MASK;
+#endif
if (pci_set_dma_mask(pdev, mask) == 0 &&
- pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) == 0) {
+ pci_set_consistent_dma_mask(pdev, cmask) == 0) {
adapter->pci_using_dac = 1;
return 0;
}
-set_32_bit_mask:
-#endif /* CONFIG_IA64 */
- err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
- if (!err)
- err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
- if (err) {
- DPRINTK(ERR, "No usable DMA configuration, aborting:%d\n", err);
- return err;
+ return -EIO;
+}
+
+/* Update addressable range if firmware supports it */
+static int
+nx_update_dma_mask(struct netxen_adapter *adapter)
+{
+ int change, shift, err;
+ uint64_t mask, old_mask;
+ struct pci_dev *pdev = adapter->pdev;
+
+ change = 0;
+
+ shift = netxen_nic_reg_read(adapter, CRB_DMA_SHIFT);
+ if (shift >= 32)
+ return 0;
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id) && (shift > 9))
+ change = 1;
+ else if ((adapter->ahw.revision_id == NX_P2_C1) && (shift <= 4))
+ change = 1;
+
+ if (change) {
+ old_mask = pdev->dma_mask;
+ mask = (1ULL<<(32+shift)) - 1;
+
+ err = pci_set_dma_mask(pdev, mask);
+ if (err)
+ return pci_set_dma_mask(pdev, old_mask);
}
- adapter->pci_using_dac = 0;
return 0;
}
static void netxen_check_options(struct netxen_adapter *adapter)
{
- switch (adapter->ahw.boardcfg.board_type) {
- case NETXEN_BRDTYPE_P3_HMEZ:
- case NETXEN_BRDTYPE_P3_XG_LOM:
- case NETXEN_BRDTYPE_P3_10G_CX4:
- case NETXEN_BRDTYPE_P3_10G_CX4_LP:
- case NETXEN_BRDTYPE_P3_IMEZ:
- case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
- case NETXEN_BRDTYPE_P3_10G_SFP_QT:
- case NETXEN_BRDTYPE_P3_10G_SFP_CT:
- case NETXEN_BRDTYPE_P3_10G_XFP:
- case NETXEN_BRDTYPE_P3_10000_BASE_T:
- adapter->msix_supported = !!use_msi_x;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
- break;
+ if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
+ adapter->num_rxd = MAX_RCV_DESCRIPTORS_10G;
+ else if (adapter->ahw.port_type == NETXEN_NIC_GBE)
+ adapter->num_rxd = MAX_RCV_DESCRIPTORS_1G;
- case NETXEN_BRDTYPE_P2_SB31_10G:
- case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
- case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
- case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
- adapter->msix_supported = 0;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
- break;
-
- case NETXEN_BRDTYPE_P3_REF_QG:
- case NETXEN_BRDTYPE_P3_4_GB:
- case NETXEN_BRDTYPE_P3_4_GB_MM:
- adapter->msix_supported = !!use_msi_x;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
- break;
-
- case NETXEN_BRDTYPE_P2_SB35_4G:
- case NETXEN_BRDTYPE_P2_SB31_2G:
- adapter->msix_supported = 0;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
- break;
-
- case NETXEN_BRDTYPE_P3_10G_TP:
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
adapter->msix_supported = !!use_msi_x;
- if (adapter->ahw.board_type == NETXEN_NIC_XGBE)
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
- else
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
- break;
-
- default:
+ else
adapter->msix_supported = 0;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
- printk(KERN_WARNING "Unknown board type(0x%x)\n",
- adapter->ahw.boardcfg.board_type);
- break;
- }
+ adapter->num_txd = MAX_CMD_DESCRIPTORS_HOST;
+ adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS;
+ adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS;
- adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST;
- adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS;
- adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS;
-
- adapter->max_possible_rss_rings = 1;
return;
}
@@ -336,7 +337,7 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter)
{
u32 val, data;
- val = adapter->ahw.boardcfg.board_type;
+ val = adapter->ahw.board_type;
if ((val == NETXEN_BRDTYPE_P3_HMEZ) ||
(val == NETXEN_BRDTYPE_P3_XG_LOM)) {
if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
@@ -454,91 +455,91 @@ static const struct net_device_ops netxen_netdev_ops = {
#endif
};
-/*
- * netxen_nic_probe()
- *
- * The Linux system will invoke this after identifying the vendor ID and
- * device Id in the pci_tbl supported by this module.
- *
- * A quad port card has one operational PCI config space, (function 0),
- * which is used to access all four ports.
- *
- * This routine will initialize the adapter, and setup the global parameters
- * along with the port's specific structure.
- */
-static int __devinit
-netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static void
+netxen_setup_intr(struct netxen_adapter *adapter)
{
- struct net_device *netdev = NULL;
- struct netxen_adapter *adapter = NULL;
- void __iomem *mem_ptr0 = NULL;
- void __iomem *mem_ptr1 = NULL;
- void __iomem *mem_ptr2 = NULL;
- unsigned long first_page_group_end;
- unsigned long first_page_group_start;
+ struct netxen_legacy_intr_set *legacy_intrp;
+ struct pci_dev *pdev = adapter->pdev;
+ adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
+ adapter->intr_scheme = -1;
+ adapter->msi_mode = -1;
- u8 __iomem *db_ptr = NULL;
- unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0;
- int i = 0, err;
- int first_driver, first_boot;
- u32 val;
- int pci_func_id = PCI_FUNC(pdev->devfn);
- struct netxen_legacy_intr_set *legacy_intrp;
- uint8_t revision_id;
+ if (adapter->ahw.revision_id >= NX_P3_B0)
+ legacy_intrp = &legacy_intr[adapter->ahw.pci_func];
+ else
+ legacy_intrp = &legacy_intr[0];
+ adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit;
+ adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg;
+ adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg;
+ adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg;
- if (pci_func_id == 0)
- printk(KERN_INFO "%s\n", netxen_nic_driver_string);
+ netxen_set_msix_bit(pdev, 0);
- if (pdev->class != 0x020000) {
- printk(KERN_DEBUG "NetXen function %d, class %x will not "
- "be enabled.\n",pci_func_id, pdev->class);
- return -ENODEV;
- }
+ if (adapter->msix_supported) {
- if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
- printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x"
- "will not be enabled.\n",
- NX_P3_A0, NX_P3_B1);
- return -ENODEV;
- }
+ netxen_init_msix_entries(adapter);
+ if (pci_enable_msix(pdev, adapter->msix_entries,
+ MSIX_ENTRIES_PER_ADAPTER))
+ goto request_msi;
- if ((err = pci_enable_device(pdev)))
- return err;
+ adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
+ netxen_set_msix_bit(pdev, 1);
+ dev_info(&pdev->dev, "using msi-x interrupts\n");
- if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
- err = -ENODEV;
- goto err_out_disable_pdev;
+ } else {
+request_msi:
+ if (use_msi && !pci_enable_msi(pdev)) {
+ adapter->flags |= NETXEN_NIC_MSI_ENABLED;
+ dev_info(&pdev->dev, "using msi interrupts\n");
+ } else
+ dev_info(&pdev->dev, "using legacy interrupts\n");
+ adapter->msix_entries[0].vector = pdev->irq;
}
+}
- if ((err = pci_request_regions(pdev, netxen_nic_driver_name)))
- goto err_out_disable_pdev;
-
- pci_set_master(pdev);
+static void
+netxen_teardown_intr(struct netxen_adapter *adapter)
+{
+ if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
+ pci_disable_msix(adapter->pdev);
+ if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
+ pci_disable_msi(adapter->pdev);
+}
- netdev = alloc_etherdev(sizeof(struct netxen_adapter));
- if(!netdev) {
- printk(KERN_ERR"%s: Failed to allocate memory for the "
- "device block.Check system memory resource"
- " usage.\n", netxen_nic_driver_name);
- goto err_out_free_res;
- }
+static void
+netxen_cleanup_pci_map(struct netxen_adapter *adapter)
+{
+ if (adapter->ahw.db_base != NULL)
+ iounmap(adapter->ahw.db_base);
+ if (adapter->ahw.pci_base0 != NULL)
+ iounmap(adapter->ahw.pci_base0);
+ if (adapter->ahw.pci_base1 != NULL)
+ iounmap(adapter->ahw.pci_base1);
+ if (adapter->ahw.pci_base2 != NULL)
+ iounmap(adapter->ahw.pci_base2);
+}
- SET_NETDEV_DEV(netdev, &pdev->dev);
+static int
+netxen_setup_pci_map(struct netxen_adapter *adapter)
+{
+ void __iomem *mem_ptr0 = NULL;
+ void __iomem *mem_ptr1 = NULL;
+ void __iomem *mem_ptr2 = NULL;
+ void __iomem *db_ptr = NULL;
- adapter = netdev_priv(netdev);
- adapter->netdev = netdev;
- adapter->pdev = pdev;
- adapter->ahw.pci_func = pci_func_id;
+ unsigned long mem_base, mem_len, db_base, db_len = 0, pci_len0 = 0;
- revision_id = pdev->revision;
- adapter->ahw.revision_id = revision_id;
+ struct pci_dev *pdev = adapter->pdev;
+ int pci_func = adapter->ahw.pci_func;
- err = nx_set_dma_mask(adapter, revision_id);
- if (err)
- goto err_out_free_netdev;
+ int err = 0;
- rwlock_init(&adapter->adapter_lock);
+ /*
+ * Set the CRB window to invalid. If any register in window 0 is
+ * accessed it should set the window to 0 and then reset it to 1.
+ */
+ adapter->curr_window = 255;
adapter->ahw.qdr_sn_window = -1;
adapter->ahw.ddr_mn_window = -1;
@@ -564,14 +565,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
SECOND_PAGE_GROUP_SIZE);
mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START,
THIRD_PAGE_GROUP_SIZE);
- first_page_group_start = FIRST_PAGE_GROUP_START;
- first_page_group_end = FIRST_PAGE_GROUP_END;
} else if (mem_len == NETXEN_PCI_32MB_SIZE) {
mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE);
mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
- first_page_group_start = 0;
- first_page_group_end = 0;
} else if (mem_len == NETXEN_PCI_2MB_SIZE) {
adapter->hw_write_wx = netxen_nic_hw_write_wx_2M;
adapter->hw_read_wx = netxen_nic_hw_read_wx_2M;
@@ -590,29 +587,33 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_err(&pdev->dev, "failed to map PCI bar 0\n");
return -EIO;
}
-
pci_len0 = mem_len;
- first_page_group_start = 0;
- first_page_group_end = 0;
adapter->ahw.ddr_mn_window = 0;
adapter->ahw.qdr_sn_window = 0;
adapter->ahw.mn_win_crb = 0x100000 + PCIX_MN_WINDOW +
- (pci_func_id * 0x20);
+ (pci_func * 0x20);
adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW;
- if (pci_func_id < 4)
- adapter->ahw.ms_win_crb += (pci_func_id * 0x20);
+ if (pci_func < 4)
+ adapter->ahw.ms_win_crb += (pci_func * 0x20);
else
adapter->ahw.ms_win_crb +=
- 0xA0 + ((pci_func_id - 4) * 0x10);
+ 0xA0 + ((pci_func - 4) * 0x10);
} else {
- err = -EIO;
- goto err_out_free_netdev;
+ return -EIO;
}
dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20));
+ adapter->ahw.pci_base0 = mem_ptr0;
+ adapter->ahw.pci_len0 = pci_len0;
+ adapter->ahw.pci_base1 = mem_ptr1;
+ adapter->ahw.pci_base2 = mem_ptr2;
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ goto skip_doorbell;
+
db_base = pci_resource_start(pdev, 4); /* doorbell is on bar 4 */
db_len = pci_resource_len(pdev, 4);
@@ -620,49 +621,349 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
printk(KERN_ERR "%s: doorbell is disabled\n",
netxen_nic_driver_name);
err = -EIO;
- goto err_out_iounmap;
+ goto err_out;
}
- DPRINTK(INFO, "doorbell ioremap from %lx a size of %lx\n", db_base,
- db_len);
db_ptr = ioremap(db_base, NETXEN_DB_MAPSIZE_BYTES);
if (!db_ptr) {
printk(KERN_ERR "%s: Failed to allocate doorbell map.",
netxen_nic_driver_name);
err = -EIO;
- goto err_out_iounmap;
+ goto err_out;
}
- DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr);
- adapter->ahw.pci_base0 = mem_ptr0;
- adapter->ahw.pci_len0 = pci_len0;
- adapter->ahw.first_page_group_start = first_page_group_start;
- adapter->ahw.first_page_group_end = first_page_group_end;
- adapter->ahw.pci_base1 = mem_ptr1;
- adapter->ahw.pci_base2 = mem_ptr2;
+skip_doorbell:
adapter->ahw.db_base = db_ptr;
adapter->ahw.db_len = db_len;
+ return 0;
- netif_napi_add(netdev, &adapter->napi,
- netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
+err_out:
+ netxen_cleanup_pci_map(adapter);
+ return err;
+}
- if (revision_id >= NX_P3_B0)
- legacy_intrp = &legacy_intr[pci_func_id];
+static int
+netxen_start_firmware(struct netxen_adapter *adapter)
+{
+ int val, err, first_boot;
+ struct pci_dev *pdev = adapter->pdev;
+
+ int first_driver = 0;
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+ if (adapter->ahw.pci_func == 0)
+ first_driver = 1;
+ } else {
+ if (adapter->portnum == 0)
+ first_driver = 1;
+ }
+
+ if (!first_driver)
+ return 0;
+
+ first_boot = adapter->pci_read_normalize(adapter,
+ NETXEN_CAM_RAM(0x1fc));
+
+ err = netxen_check_hw_init(adapter, first_boot);
+ if (err) {
+ dev_err(&pdev->dev, "error in init HW init sequence\n");
+ return err;
+ }
+
+ if (first_boot != 0x55555555) {
+ adapter->pci_write_normalize(adapter,
+ CRB_CMDPEG_STATE, 0);
+ netxen_pinit_from_rom(adapter, 0);
+ msleep(1);
+ }
+
+ netxen_nic_reg_write(adapter, CRB_DMA_SHIFT, 0x55555555);
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ netxen_set_port_mode(adapter);
+
+ netxen_load_firmware(adapter);
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+
+ /* Initialize multicast addr pool owners */
+ val = 0x7654;
+ if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
+ val |= 0x0f000000;
+ netxen_crb_writelit_adapter(adapter,
+ NETXEN_MAC_ADDR_CNTL_REG, val);
+
+ }
+
+ err = netxen_initialize_adapter_offload(adapter);
+ if (err)
+ return err;
+
+ /*
+ * Tell the hardware our version number.
+ */
+ val = (_NETXEN_NIC_LINUX_MAJOR << 16)
+ | ((_NETXEN_NIC_LINUX_MINOR << 8))
+ | (_NETXEN_NIC_LINUX_SUBVERSION);
+ adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, val);
+
+ /* Handshake with the card before we register the devices. */
+ err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
+ if (err) {
+ netxen_free_adapter_offload(adapter);
+ return err;
+ }
+
+ return 0;
+}
+
+static int
+netxen_nic_request_irq(struct netxen_adapter *adapter)
+{
+ irq_handler_t handler;
+ struct nx_host_sds_ring *sds_ring;
+ int err, ring;
+
+ unsigned long flags = IRQF_SAMPLE_RANDOM;
+ struct net_device *netdev = adapter->netdev;
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+ if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
+ (adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
+ printk(KERN_ERR "%s: Firmware interrupt scheme is "
+ "incompatible with driver\n",
+ netdev->name);
+ adapter->driver_mismatch = 1;
+ return -EINVAL;
+ }
+
+ if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
+ handler = netxen_msix_intr;
+ else if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
+ handler = netxen_msi_intr;
+ else {
+ flags |= IRQF_SHARED;
+ handler = netxen_intr;
+ }
+ adapter->irq = netdev->irq;
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ sprintf(sds_ring->name, "%16s[%d]", netdev->name, ring);
+ err = request_irq(sds_ring->irq, handler,
+ flags, sds_ring->name, sds_ring);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static void
+netxen_nic_free_irq(struct netxen_adapter *adapter)
+{
+ int ring;
+ struct nx_host_sds_ring *sds_ring;
+
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ free_irq(sds_ring->irq, sds_ring);
+ }
+}
+
+static int
+netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
+{
+ int err;
+
+ err = adapter->init_port(adapter, adapter->physical_port);
+ if (err) {
+ printk(KERN_ERR "%s: Failed to initialize port %d\n",
+ netxen_nic_driver_name, adapter->portnum);
+ return err;
+ }
+ adapter->macaddr_set(adapter, netdev->dev_addr);
+
+ netxen_nic_set_link_parameters(adapter);
+
+ netxen_set_multicast_list(netdev);
+ if (adapter->set_mtu)
+ adapter->set_mtu(adapter, netdev->mtu);
+
+ adapter->ahw.linkup = 0;
+ mod_timer(&adapter->watchdog_timer, jiffies);
+
+ netxen_napi_enable(adapter);
+
+ if (adapter->max_sds_rings > 1)
+ netxen_config_rss(adapter, 1);
+
+ return 0;
+}
+
+static void
+netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
+{
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+ netxen_napi_disable(adapter);
+
+ if (adapter->stop_port)
+ adapter->stop_port(adapter);
+
+ netxen_release_tx_buffers(adapter);
+
+ FLUSH_SCHEDULED_WORK();
+ del_timer_sync(&adapter->watchdog_timer);
+}
+
+
+static int
+netxen_nic_attach(struct netxen_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ struct pci_dev *pdev = adapter->pdev;
+ int err, ring;
+ struct nx_host_rds_ring *rds_ring;
+
+ err = netxen_init_firmware(adapter);
+ if (err != 0) {
+ printk(KERN_ERR "Failed to init firmware\n");
+ return -EIO;
+ }
+
+ if (adapter->fw_major < 4)
+ adapter->max_rds_rings = 3;
else
- legacy_intrp = &legacy_intr[0];
+ adapter->max_rds_rings = 2;
- adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit;
- adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg;
- adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg;
- adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg;
+ err = netxen_alloc_sw_resources(adapter);
+ if (err) {
+ printk(KERN_ERR "%s: Error in setting sw resources\n",
+ netdev->name);
+ return err;
+ }
- /* this will be read from FW later */
- adapter->intr_scheme = -1;
- adapter->msi_mode = -1;
+ netxen_nic_clear_stats(adapter);
+
+ err = netxen_alloc_hw_resources(adapter);
+ if (err) {
+ printk(KERN_ERR "%s: Error in setting hw resources\n",
+ netdev->name);
+ goto err_out_free_sw;
+ }
+
+ if (adapter->fw_major < 4) {
+ adapter->crb_addr_cmd_producer =
+ crb_cmd_producer[adapter->portnum];
+ adapter->crb_addr_cmd_consumer =
+ crb_cmd_consumer[adapter->portnum];
+
+ netxen_nic_update_cmd_producer(adapter, 0);
+ netxen_nic_update_cmd_consumer(adapter, 0);
+ }
+
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &adapter->recv_ctx.rds_rings[ring];
+ netxen_post_rx_buffers(adapter, ring, rds_ring);
+ }
+
+ err = netxen_nic_request_irq(adapter);
+ if (err) {
+ dev_err(&pdev->dev, "%s: failed to setup interrupt\n",
+ netdev->name);
+ goto err_out_free_rxbuf;
+ }
+
+ adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
+ return 0;
+
+err_out_free_rxbuf:
+ netxen_release_rx_buffers(adapter);
+ netxen_free_hw_resources(adapter);
+err_out_free_sw:
+ netxen_free_sw_resources(adapter);
+ return err;
+}
+
+static void
+netxen_nic_detach(struct netxen_adapter *adapter)
+{
+ netxen_nic_free_irq(adapter);
+
+ netxen_release_rx_buffers(adapter);
+ netxen_free_hw_resources(adapter);
+ netxen_free_sw_resources(adapter);
+
+ adapter->is_up = 0;
+}
+
+static int __devinit
+netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ struct net_device *netdev = NULL;
+ struct netxen_adapter *adapter = NULL;
+ int i = 0, err;
+ int pci_func_id = PCI_FUNC(pdev->devfn);
+ uint8_t revision_id;
+
+ if (pdev->class != 0x020000) {
+ printk(KERN_DEBUG "NetXen function %d, class %x will not "
+ "be enabled.\n",pci_func_id, pdev->class);
+ return -ENODEV;
+ }
+
+ if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
+ printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x"
+ "will not be enabled.\n",
+ NX_P3_A0, NX_P3_B1);
+ return -ENODEV;
+ }
+
+ if ((err = pci_enable_device(pdev)))
+ return err;
+
+ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+ err = -ENODEV;
+ goto err_out_disable_pdev;
+ }
+
+ if ((err = pci_request_regions(pdev, netxen_nic_driver_name)))
+ goto err_out_disable_pdev;
+
+ pci_set_master(pdev);
+
+ netdev = alloc_etherdev(sizeof(struct netxen_adapter));
+ if(!netdev) {
+ printk(KERN_ERR"%s: Failed to allocate memory for the "
+ "device block.Check system memory resource"
+ " usage.\n", netxen_nic_driver_name);
+ goto err_out_free_res;
+ }
+
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+
+ adapter = netdev_priv(netdev);
+ adapter->netdev = netdev;
+ adapter->pdev = pdev;
+ adapter->ahw.pci_func = pci_func_id;
+
+ revision_id = pdev->revision;
+ adapter->ahw.revision_id = revision_id;
+
+ err = nx_set_dma_mask(adapter, revision_id);
+ if (err)
+ goto err_out_free_netdev;
+
+ rwlock_init(&adapter->adapter_lock);
+ spin_lock_init(&adapter->tx_clean_lock);
+
+ err = netxen_setup_pci_map(adapter);
+ if (err)
+ goto err_out_free_netdev;
/* This will be reset for mezz cards */
adapter->portnum = pci_func_id;
- adapter->status &= ~NETXEN_NETDEV_STATUS;
adapter->rx_csum = 1;
adapter->mc_enabled = 0;
if (NX_IS_REVISION_P3(revision_id))
@@ -690,12 +991,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netdev->vlan_features |= NETIF_F_HIGHDMA;
}
- /*
- * Set the CRB window to invalid. If any register in window 0 is
- * accessed it should set the window to 0 and then reset it to 1.
- */
- adapter->curr_window = 255;
-
if (netxen_nic_get_board_info(adapter) != 0) {
printk("%s: Error getting board config info.\n",
netxen_nic_driver_name);
@@ -706,7 +1001,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netxen_initialize_adapter_ops(adapter);
/* Mezz cards have PCI function 0,2,3 enabled */
- switch (adapter->ahw.boardcfg.board_type) {
+ switch (adapter->ahw.board_type) {
case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
if (pci_func_id >= 2)
@@ -716,82 +1011,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
- /*
- * This call will setup various max rx/tx counts.
- * It must be done before any buffer/ring allocations.
- */
- netxen_check_options(adapter);
-
- first_driver = 0;
- if (NX_IS_REVISION_P3(revision_id)) {
- if (adapter->ahw.pci_func == 0)
- first_driver = 1;
- } else {
- if (adapter->portnum == 0)
- first_driver = 1;
- }
-
- if (first_driver) {
- first_boot = adapter->pci_read_normalize(adapter,
- NETXEN_CAM_RAM(0x1fc));
-
- err = netxen_check_hw_init(adapter, first_boot);
- if (err) {
- printk(KERN_ERR "%s: error in init HW init sequence\n",
- netxen_nic_driver_name);
- goto err_out_iounmap;
- }
-
- if (NX_IS_REVISION_P3(revision_id))
- netxen_set_port_mode(adapter);
-
- if (first_boot != 0x55555555) {
- adapter->pci_write_normalize(adapter,
- CRB_CMDPEG_STATE, 0);
- netxen_pinit_from_rom(adapter, 0);
- msleep(1);
- }
- netxen_load_firmware(adapter);
-
- if (NX_IS_REVISION_P2(revision_id)) {
-
- /* Initialize multicast addr pool owners */
- val = 0x7654;
- if (adapter->ahw.board_type == NETXEN_NIC_XGBE)
- val |= 0x0f000000;
- netxen_crb_writelit_adapter(adapter,
- NETXEN_MAC_ADDR_CNTL_REG, val);
-
- }
-
- err = netxen_initialize_adapter_offload(adapter);
- if (err)
- goto err_out_iounmap;
-
- /*
- * Tell the hardware our version number.
- */
- i = (_NETXEN_NIC_LINUX_MAJOR << 16)
- | ((_NETXEN_NIC_LINUX_MINOR << 8))
- | (_NETXEN_NIC_LINUX_SUBVERSION);
- adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i);
-
- /* Handshake with the card before we register the devices. */
- err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
- if (err)
- goto err_out_free_offload;
+ err = netxen_start_firmware(adapter);
+ if (err)
+ goto err_out_iounmap;
- } /* first_driver */
+ nx_update_dma_mask(adapter);
- netxen_nic_flash_print(adapter);
-
- if (NX_IS_REVISION_P3(revision_id)) {
- adapter->hw_read_wx(adapter,
- NETXEN_MIU_MN_CONTROL, &val, 4);
- adapter->ahw.cut_through = (val & 0x4) ? 1 : 0;
- dev_info(&pdev->dev, "firmware running in %s mode\n",
- adapter->ahw.cut_through ? "cut through" : "legacy");
- }
+ netxen_nic_get_firmware_info(adapter);
/*
* See if the firmware gave us a virtual-physical port mapping.
@@ -804,41 +1030,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->physical_port = i;
}
- adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
-
- netxen_set_msix_bit(pdev, 0);
-
- if (NX_IS_REVISION_P3(revision_id)) {
- if ((mem_len != NETXEN_PCI_128MB_SIZE) &&
- mem_len != NETXEN_PCI_2MB_SIZE)
- adapter->msix_supported = 0;
- }
-
- if (adapter->msix_supported) {
+ netxen_check_options(adapter);
- netxen_init_msix_entries(adapter);
+ netxen_setup_intr(adapter);
- if (pci_enable_msix(pdev, adapter->msix_entries,
- MSIX_ENTRIES_PER_ADAPTER))
- goto request_msi;
+ netdev->irq = adapter->msix_entries[0].vector;
- adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
- netxen_set_msix_bit(pdev, 1);
- dev_info(&pdev->dev, "using msi-x interrupts\n");
-
- } else {
-request_msi:
- if (use_msi && !pci_enable_msi(pdev)) {
- adapter->flags |= NETXEN_NIC_MSI_ENABLED;
- dev_info(&pdev->dev, "using msi interrupts\n");
- } else
- dev_info(&pdev->dev, "using legacy interrupts\n");
- }
-
- if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
- netdev->irq = adapter->msix_entries[0].vector;
- else
- netdev->irq = pdev->irq;
+ netxen_napi_add(adapter, netdev);
err = netxen_receive_peg_ready(adapter);
if (err)
@@ -867,7 +1065,7 @@ request_msi:
pci_set_drvdata(pdev, adapter);
- switch (adapter->ahw.board_type) {
+ switch (adapter->ahw.port_type) {
case NETXEN_NIC_GBE:
dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
adapter->netdev->name);
@@ -881,25 +1079,12 @@ request_msi:
return 0;
err_out_disable_msi:
- if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
- pci_disable_msix(pdev);
- if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
- pci_disable_msi(pdev);
+ netxen_teardown_intr(adapter);
-err_out_free_offload:
- if (first_driver)
- netxen_free_adapter_offload(adapter);
+ netxen_free_adapter_offload(adapter);
err_out_iounmap:
- if (db_ptr)
- iounmap(db_ptr);
-
- if (mem_ptr0)
- iounmap(mem_ptr0);
- if (mem_ptr1)
- iounmap(mem_ptr1);
- if (mem_ptr2)
- iounmap(mem_ptr2);
+ netxen_cleanup_pci_map(adapter);
err_out_free_netdev:
free_netdev(netdev);
@@ -927,9 +1112,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
unregister_netdev(netdev);
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
- netxen_free_hw_resources(adapter);
- netxen_release_rx_buffers(adapter);
- netxen_free_sw_resources(adapter);
+ netxen_nic_detach(adapter);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
netxen_p3_free_mac_list(adapter);
@@ -938,20 +1121,9 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
if (adapter->portnum == 0)
netxen_free_adapter_offload(adapter);
- if (adapter->irq)
- free_irq(adapter->irq, adapter);
+ netxen_teardown_intr(adapter);
- if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
- pci_disable_msix(pdev);
- if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
- pci_disable_msi(pdev);
-
- iounmap(adapter->ahw.db_base);
- iounmap(adapter->ahw.pci_base0);
- if (adapter->ahw.pci_base1 != NULL)
- iounmap(adapter->ahw.pci_base1);
- if (adapter->ahw.pci_base2 != NULL)
- iounmap(adapter->ahw.pci_base2);
+ netxen_cleanup_pci_map(adapter);
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -960,125 +1132,95 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
free_netdev(netdev);
}
-/*
- * Called when a network interface is made active
- * @returns 0 on success, negative value on failure
- */
-static int netxen_nic_open(struct net_device *netdev)
+static int
+netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
{
- struct netxen_adapter *adapter = netdev_priv(netdev);
- int err = 0;
- int ctx, ring;
- irq_handler_t handler;
- unsigned long flags = IRQF_SAMPLE_RANDOM;
- if (adapter->driver_mismatch)
- return -EIO;
+ struct netxen_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
- if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) {
- err = netxen_init_firmware(adapter);
- if (err != 0) {
- printk(KERN_ERR "Failed to init firmware\n");
- return -EIO;
- }
+ netif_device_detach(netdev);
- if (adapter->fw_major < 4)
- adapter->max_rds_rings = 3;
- else
- adapter->max_rds_rings = 2;
+ if (netif_running(netdev))
+ netxen_nic_down(adapter, netdev);
- err = netxen_alloc_sw_resources(adapter);
- if (err) {
- printk(KERN_ERR "%s: Error in setting sw resources\n",
- netdev->name);
- return err;
- }
+ if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
+ netxen_nic_detach(adapter);
- netxen_nic_clear_stats(adapter);
+ pci_save_state(pdev);
- err = netxen_alloc_hw_resources(adapter);
- if (err) {
- printk(KERN_ERR "%s: Error in setting hw resources\n",
- netdev->name);
- goto err_out_free_sw;
- }
+ if (netxen_nic_wol_supported(adapter)) {
+ pci_enable_wake(pdev, PCI_D3cold, 1);
+ pci_enable_wake(pdev, PCI_D3hot, 1);
+ }
- if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
- (adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
- printk(KERN_ERR "%s: Firmware interrupt scheme is "
- "incompatible with driver\n",
- netdev->name);
- adapter->driver_mismatch = 1;
- goto err_out_free_hw;
- }
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+}
- if (adapter->fw_major < 4) {
- adapter->crb_addr_cmd_producer =
- crb_cmd_producer[adapter->portnum];
- adapter->crb_addr_cmd_consumer =
- crb_cmd_consumer[adapter->portnum];
+static int
+netxen_nic_resume(struct pci_dev *pdev)
+{
+ struct netxen_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
+ int err;
- netxen_nic_update_cmd_producer(adapter, 0);
- netxen_nic_update_cmd_consumer(adapter, 0);
- }
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
- for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
- for (ring = 0; ring < adapter->max_rds_rings; ring++)
- netxen_post_rx_buffers(adapter, ctx, ring);
- }
- if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
- handler = netxen_msix_intr;
- else if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
- handler = netxen_msi_intr;
- else {
- flags |= IRQF_SHARED;
- handler = netxen_intr;
- }
- adapter->irq = netdev->irq;
- err = request_irq(adapter->irq, handler,
- flags, netdev->name, adapter);
- if (err) {
- printk(KERN_ERR "request_irq failed with: %d\n", err);
- goto err_out_free_rxbuf;
- }
+ err = pci_enable_device(pdev);
+ if (err)
+ return err;
- adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
- }
+ adapter->curr_window = 255;
- /* Done here again so that even if phantom sw overwrote it,
- * we set it */
- err = adapter->init_port(adapter, adapter->physical_port);
+ err = netxen_start_firmware(adapter);
if (err) {
- printk(KERN_ERR "%s: Failed to initialize port %d\n",
- netxen_nic_driver_name, adapter->portnum);
- goto err_out_free_irq;
+ dev_err(&pdev->dev, "failed to start firmware\n");
+ return err;
}
- adapter->macaddr_set(adapter, netdev->dev_addr);
- netxen_nic_set_link_parameters(adapter);
+ if (netif_running(netdev)) {
+ err = netxen_nic_attach(adapter);
+ if (err)
+ return err;
- netxen_set_multicast_list(netdev);
- if (adapter->set_mtu)
- adapter->set_mtu(adapter, netdev->mtu);
+ err = netxen_nic_up(adapter, netdev);
+ if (err)
+ return err;
- adapter->ahw.linkup = 0;
- mod_timer(&adapter->watchdog_timer, jiffies);
+ netif_device_attach(netdev);
+ }
+
+ return 0;
+}
- napi_enable(&adapter->napi);
- netxen_nic_enable_int(adapter);
+static int netxen_nic_open(struct net_device *netdev)
+{
+ struct netxen_adapter *adapter = netdev_priv(netdev);
+ int err = 0;
+
+ if (adapter->driver_mismatch)
+ return -EIO;
+
+ if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) {
+ err = netxen_nic_attach(adapter);
+ if (err)
+ return err;
+ }
+
+ err = netxen_nic_up(adapter, netdev);
+ if (err)
+ goto err_out;
netif_start_queue(netdev);
return 0;
-err_out_free_irq:
- free_irq(adapter->irq, adapter);
-err_out_free_rxbuf:
- netxen_release_rx_buffers(adapter);
-err_out_free_hw:
- netxen_free_hw_resources(adapter);
-err_out_free_sw:
- netxen_free_sw_resources(adapter);
+err_out:
+ netxen_nic_detach(adapter);
return err;
}
@@ -1089,20 +1231,7 @@ static int netxen_nic_close(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
- napi_disable(&adapter->napi);
-
- if (adapter->stop_port)
- adapter->stop_port(adapter);
-
- netxen_nic_disable_int(adapter);
-
- netxen_release_tx_buffers(adapter);
-
- FLUSH_SCHEDULED_WORK();
- del_timer_sync(&adapter->watchdog_timer);
-
+ netxen_nic_down(adapter, netdev);
return 0;
}
@@ -1114,7 +1243,7 @@ static bool netxen_tso_check(struct net_device *netdev,
__be16 protocol = skb->protocol;
u16 flags = 0;
- if (protocol == __constant_htons(ETH_P_8021Q)) {
+ if (protocol == cpu_to_be16(ETH_P_8021Q)) {
struct vlan_ethhdr *vh = (struct vlan_ethhdr *)skb->data;
protocol = vh->h_vlan_encapsulated_proto;
flags = FLAGS_VLAN_TAGGED;
@@ -1127,21 +1256,21 @@ static bool netxen_tso_check(struct net_device *netdev,
desc->total_hdr_length =
skb_transport_offset(skb) + tcp_hdrlen(skb);
- opcode = (protocol == __constant_htons(ETH_P_IPV6)) ?
+ opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ?
TX_TCP_LSO6 : TX_TCP_LSO;
tso = true;
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
u8 l4proto;
- if (protocol == __constant_htons(ETH_P_IP)) {
+ if (protocol == cpu_to_be16(ETH_P_IP)) {
l4proto = ip_hdr(skb)->protocol;
if (l4proto == IPPROTO_TCP)
opcode = TX_TCP_PKT;
else if(l4proto == IPPROTO_UDP)
opcode = TX_UDP_PKT;
- } else if (protocol == __constant_htons(ETH_P_IPV6)) {
+ } else if (protocol == cpu_to_be16(ETH_P_IPV6)) {
l4proto = ipv6_hdr(skb)->nexthdr;
if (l4proto == IPPROTO_TCP)
@@ -1174,7 +1303,16 @@ netxen_clean_tx_dma_mapping(struct pci_dev *pdev,
}
}
-static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static inline void
+netxen_clear_cmddesc(u64 *desc)
+{
+ int i;
+ for (i = 0; i < 8; i++)
+ desc[i] = 0ULL;
+}
+
+static int
+netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
struct netxen_hardware_context *hw = &adapter->ahw;
@@ -1188,7 +1326,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
u32 producer, consumer;
int frag_count, no_of_desc;
- u32 num_txd = adapter->max_tx_desc_count;
+ u32 num_txd = adapter->num_txd;
bool is_tso = false;
frag_count = skb_shinfo(skb)->nr_frags + 1;
@@ -1207,7 +1345,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
/* Copy the descriptors into the hardware */
hwdesc = &hw->cmd_desc_head[producer];
- memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
+ netxen_clear_cmddesc((u64 *)hwdesc);
/* Take skb->data itself */
pbuf = &adapter->cmd_buf_arr[producer];
@@ -1226,7 +1364,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
netxen_set_tx_frags_len(hwdesc, frag_count, skb->len);
netxen_set_tx_port(hwdesc, adapter->portnum);
- hwdesc->buffer1_length = cpu_to_le16(first_seg_len);
+ hwdesc->buffer_length[0] = cpu_to_le16(first_seg_len);
hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
for (i = 1, k = 1; i < frag_count; i++, k++) {
@@ -1239,7 +1377,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
k = 0;
producer = get_next_index(producer, num_txd);
hwdesc = &hw->cmd_desc_head[producer];
- memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
+ netxen_clear_cmddesc((u64 *)hwdesc);
pbuf = &adapter->cmd_buf_arr[producer];
pbuf->skb = NULL;
}
@@ -1259,21 +1397,18 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
buffrag->dma = temp_dma;
buffrag->length = temp_len;
+ hwdesc->buffer_length[k] = cpu_to_le16(temp_len);
switch (k) {
case 0:
- hwdesc->buffer1_length = cpu_to_le16(temp_len);
hwdesc->addr_buffer1 = cpu_to_le64(temp_dma);
break;
case 1:
- hwdesc->buffer2_length = cpu_to_le16(temp_len);
hwdesc->addr_buffer2 = cpu_to_le64(temp_dma);
break;
case 2:
- hwdesc->buffer3_length = cpu_to_le16(temp_len);
hwdesc->addr_buffer3 = cpu_to_le64(temp_dma);
break;
case 3:
- hwdesc->buffer4_length = cpu_to_le16(temp_len);
hwdesc->addr_buffer4 = cpu_to_le64(temp_dma);
break;
}
@@ -1388,7 +1523,7 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
linkup = (val == XG_LINK_UP_P3);
} else {
val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
- if (adapter->ahw.board_type == NETXEN_NIC_GBE)
+ if (adapter->ahw.port_type == NETXEN_NIC_GBE)
linkup = (val >> port) & 1;
else {
val = (val >> port*8) & 0xff;
@@ -1455,13 +1590,11 @@ static void netxen_tx_timeout_task(struct work_struct *work)
printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
netxen_nic_driver_name, adapter->netdev->name);
- netxen_nic_disable_int(adapter);
- napi_disable(&adapter->napi);
+ netxen_napi_disable(adapter);
adapter->netdev->trans_start = jiffies;
- napi_enable(&adapter->napi);
- netxen_nic_enable_int(adapter);
+ netxen_napi_enable(adapter);
netif_wake_queue(adapter->netdev);
}
@@ -1499,7 +1632,8 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
static irqreturn_t netxen_intr(int irq, void *data)
{
- struct netxen_adapter *adapter = data;
+ struct nx_host_sds_ring *sds_ring = data;
+ struct netxen_adapter *adapter = sds_ring->adapter;
u32 status = 0;
status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
@@ -1530,7 +1664,7 @@ static irqreturn_t netxen_intr(int irq, void *data)
/* clear interrupt */
if (adapter->fw_major < 4)
- netxen_nic_disable_int(adapter);
+ netxen_nic_disable_int(sds_ring);
adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_status_reg,
@@ -1539,61 +1673,49 @@ static irqreturn_t netxen_intr(int irq, void *data)
adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
- napi_schedule(&adapter->napi);
+ napi_schedule(&sds_ring->napi);
return IRQ_HANDLED;
}
static irqreturn_t netxen_msi_intr(int irq, void *data)
{
- struct netxen_adapter *adapter = data;
+ struct nx_host_sds_ring *sds_ring = data;
+ struct netxen_adapter *adapter = sds_ring->adapter;
/* clear interrupt */
adapter->pci_write_immediate(adapter,
msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
- napi_schedule(&adapter->napi);
+ napi_schedule(&sds_ring->napi);
return IRQ_HANDLED;
}
static irqreturn_t netxen_msix_intr(int irq, void *data)
{
- struct netxen_adapter *adapter = data;
+ struct nx_host_sds_ring *sds_ring = data;
- napi_schedule(&adapter->napi);
+ napi_schedule(&sds_ring->napi);
return IRQ_HANDLED;
}
static int netxen_nic_poll(struct napi_struct *napi, int budget)
{
- struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi);
+ struct nx_host_sds_ring *sds_ring =
+ container_of(napi, struct nx_host_sds_ring, napi);
+
+ struct netxen_adapter *adapter = sds_ring->adapter;
+
int tx_complete;
- int ctx;
int work_done;
tx_complete = netxen_process_cmd_ring(adapter);
- work_done = 0;
- for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
- /*
- * Fairness issue. This will give undue weight to the
- * receive context 0.
- */
-
- /*
- * To avoid starvation, we give each of our receivers,
- * a fraction of the quota. Sometimes, it might happen that we
- * have enough quota to process every packet, but since all the
- * packets are on one context, it gets only half of the quota,
- * and ends up not processing it.
- */
- work_done += netxen_process_rcv_ring(adapter, ctx,
- budget / MAX_RCV_CTX);
- }
+ work_done = netxen_process_rcv_ring(sds_ring, budget);
if ((work_done < budget) && tx_complete) {
- netif_rx_complete(&adapter->napi);
- netxen_nic_enable_int(adapter);
+ napi_complete(&sds_ring->napi);
+ netxen_nic_enable_int(sds_ring);
}
return work_done;
@@ -1613,13 +1735,17 @@ static struct pci_driver netxen_driver = {
.name = netxen_nic_driver_name,
.id_table = netxen_pci_tbl,
.probe = netxen_nic_probe,
- .remove = __devexit_p(netxen_nic_remove)
+ .remove = __devexit_p(netxen_nic_remove),
+ .suspend = netxen_nic_suspend,
+ .resume = netxen_nic_resume
};
/* Driver Registration on NetXen card */
static int __init netxen_init_module(void)
{
+ printk(KERN_INFO "%s\n", netxen_nic_driver_string);
+
if ((netxen_workq = create_singlethread_workqueue("netxen")) == NULL)
return -ENOMEM;
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
index c3b9c83b32fe..d85203203d4d 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,12 +22,9 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
- *
- *
- * Provides access to the Network Interface Unit h/w block.
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
*
*/
@@ -299,14 +296,6 @@ int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter)
return result;
}
-#if 0
-int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter)
-{
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_ACTIVE_INT, -1);
- return 0;
-}
-#endif /* 0 */
-
static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
{
int result = 0;
@@ -467,104 +456,6 @@ int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
return 0;
}
-#if 0
-/*
- * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts
- * @param enable 0 means don't enable the port
- * 1 means enable (or re-enable) the port
- */
-int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter,
- int port, long enable)
-{
- int result = 0;
- __u32 int_src;
-
- printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d"
- " (device enable = %d)\n", (int)port, (int)enable);
-
- /*
- * The read of the PHY INT status will clear the pending
- * interrupt status
- */
- if (netxen_niu_gbe_phy_read(adapter,
- NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
- &int_src) != 0)
- result = -EINVAL;
- else {
- printk(KERN_INFO PFX "PHY Interrupt source = 0x%x \n", int_src);
- if (netxen_get_phy_int_jabber(int_src))
- printk(KERN_INFO PFX "jabber Interrupt ");
- if (netxen_get_phy_int_polarity_changed(int_src))
- printk(KERN_INFO PFX "polarity changed ");
- if (netxen_get_phy_int_energy_detect(int_src))
- printk(KERN_INFO PFX "energy detect \n");
- if (netxen_get_phy_int_downshift(int_src))
- printk(KERN_INFO PFX "downshift \n");
- if (netxen_get_phy_int_mdi_xover_changed(int_src))
- printk(KERN_INFO PFX "mdi_xover_changed ");
- if (netxen_get_phy_int_fifo_over_underflow(int_src))
- printk(KERN_INFO PFX "fifo_over_underflow ");
- if (netxen_get_phy_int_false_carrier(int_src))
- printk(KERN_INFO PFX "false_carrier ");
- if (netxen_get_phy_int_symbol_error(int_src))
- printk(KERN_INFO PFX "symbol_error ");
- if (netxen_get_phy_int_autoneg_completed(int_src))
- printk(KERN_INFO PFX "autoneg_completed ");
- if (netxen_get_phy_int_page_received(int_src))
- printk(KERN_INFO PFX "page_received ");
- if (netxen_get_phy_int_duplex_changed(int_src))
- printk(KERN_INFO PFX "duplex_changed ");
- if (netxen_get_phy_int_autoneg_error(int_src))
- printk(KERN_INFO PFX "autoneg_error ");
- if ((netxen_get_phy_int_speed_changed(int_src))
- || (netxen_get_phy_int_link_status_changed(int_src))) {
- __u32 status;
-
- printk(KERN_INFO PFX
- "speed_changed or link status changed");
- if (netxen_niu_gbe_phy_read
- (adapter,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
- &status) == 0) {
- if (netxen_get_phy_speed(status) == 2) {
- printk
- (KERN_INFO PFX "Link speed changed"
- " to 1000 Mbps\n");
- netxen_niu_gbe_set_gmii_mode(adapter,
- port,
- enable);
- } else if (netxen_get_phy_speed(status) == 1) {
- printk
- (KERN_INFO PFX "Link speed changed"
- " to 100 Mbps\n");
- netxen_niu_gbe_set_mii_mode(adapter,
- port,
- enable);
- } else if (netxen_get_phy_speed(status) == 0) {
- printk
- (KERN_INFO PFX "Link speed changed"
- " to 10 Mbps\n");
- netxen_niu_gbe_set_mii_mode(adapter,
- port,
- enable);
- } else {
- printk(KERN_ERR PFX "ERROR reading "
- "PHY status. Invalid speed.\n");
- result = -1;
- }
- } else {
- printk(KERN_ERR PFX
- "ERROR reading PHY status.\n");
- result = -1;
- }
-
- }
- printk(KERN_INFO "\n");
- }
- return result;
-}
-#endif /* 0 */
-
/*
* Return the current station MAC address.
* Note that the passed-in value must already be in network byte order.
@@ -641,86 +532,6 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
return 0;
}
-#if 0
-/* Enable a GbE interface */
-int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
- int port, netxen_niu_gbe_ifmode_t mode)
-{
- __u32 mac_cfg0;
- __u32 mac_cfg1;
- __u32 mii_cfg;
-
- if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
- return -EINVAL;
-
- mac_cfg0 = 0;
- netxen_gb_soft_reset(mac_cfg0);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- &mac_cfg0, 4))
- return -EIO;
- mac_cfg0 = 0;
- netxen_gb_enable_tx(mac_cfg0);
- netxen_gb_enable_rx(mac_cfg0);
- netxen_gb_unset_rx_flowctl(mac_cfg0);
- netxen_gb_tx_reset_pb(mac_cfg0);
- netxen_gb_rx_reset_pb(mac_cfg0);
- netxen_gb_tx_reset_mac(mac_cfg0);
- netxen_gb_rx_reset_mac(mac_cfg0);
-
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- &mac_cfg0, 4))
- return -EIO;
- mac_cfg1 = 0;
- netxen_gb_set_preamblelen(mac_cfg1, 0xf);
- netxen_gb_set_duplex(mac_cfg1);
- netxen_gb_set_crc_enable(mac_cfg1);
- netxen_gb_set_padshort(mac_cfg1);
- netxen_gb_set_checklength(mac_cfg1);
- netxen_gb_set_hugeframes(mac_cfg1);
-
- if (mode == NETXEN_NIU_10_100_MB) {
- netxen_gb_set_intfmode(mac_cfg1, 1);
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_1(port),
- &mac_cfg1, 4))
- return -EIO;
-
- /* set mii mode */
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE +
- (port << 3), 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE +
- (port << 3), 1);
-
- } else if (mode == NETXEN_NIU_1000_MB) {
- netxen_gb_set_intfmode(mac_cfg1, 2);
- if (adapter->hw_write_wx(adapter,
- NETXEN_NIU_GB_MAC_CONFIG_1(port),
- &mac_cfg1, 4))
- return -EIO;
- /* set gmii mode */
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE +
- (port << 3), 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE +
- (port << 3), 1);
- }
- mii_cfg = 0;
- netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7);
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port),
- &mii_cfg, 4))
- return -EIO;
- mac_cfg0 = 0;
- netxen_gb_enable_tx(mac_cfg0);
- netxen_gb_enable_rx(mac_cfg0);
- netxen_gb_unset_rx_flowctl(mac_cfg0);
- netxen_gb_unset_tx_flowctl(mac_cfg0);
-
- if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
- &mac_cfg0, 4))
- return -EIO;
- return 0;
-}
-#endif /* 0 */
-
/* Disable a GbE interface */
int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
{
@@ -869,39 +680,6 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
return 0;
}
-#if 0
-/*
- * Return the current station MAC address.
- * Note that the passed-in value must already be in network byte order.
- */
-int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter,
- netxen_ethernet_macaddr_t * addr)
-{
- int phy = adapter->physical_port;
- u32 stationhigh;
- u32 stationlow;
- u8 val[8];
-
- if (addr == NULL)
- return -EINVAL;
- if (phy != 0)
- return -EINVAL;
-
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
- &stationhigh, 4))
- return -EIO;
- if (adapter->hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
- &stationlow, 4))
- return -EIO;
- ((__le32 *)val)[1] = cpu_to_le32(stationhigh);
- ((__le32 *)val)[0] = cpu_to_le32(stationlow);
-
- memcpy(addr, val + 2, 6);
-
- return 0;
-}
-#endif /* 0 */
-
int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
u32 mode)
{
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h
index b293adcc95ab..50183335e43a 100644
--- a/drivers/net/netxen/netxen_nic_phan_reg.h
+++ b/drivers/net/netxen/netxen_nic_phan_reg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003 - 2006 NetXen, Inc.
+ * Copyright (C) 2003 - 2009 NetXen, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -22,9 +22,10 @@
*
* Contact Information:
* info@netxen.com
- * NetXen,
- * 3965 Freedom Circle, Fourth floor,
- * Santa Clara, CA 95054
+ * NetXen Inc,
+ * 18922 Forge Drive
+ * Cupertino, CA 95014-0701
+ *
*/
#ifndef __NIC_PHAN_REG_H_
@@ -90,6 +91,7 @@
#define CRB_RX_LRO_START_NUM NETXEN_NIC_REG(0xc0)
#define CRB_MPORT_MODE NETXEN_NIC_REG(0xc4) /* Multiport Mode */
#define CRB_CMD_RING_SIZE NETXEN_NIC_REG(0xc8)
+#define CRB_DMA_SHIFT NETXEN_NIC_REG(0xcc)
#define CRB_INT_VECTOR NETXEN_NIC_REG(0xd4)
#define CRB_CTX_RESET NETXEN_NIC_REG(0xd8)
#define CRB_HOST_STS_PROD NETXEN_NIC_REG(0xdc)
diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c
index 539e18ab485c..2a8da476ab3d 100644
--- a/drivers/net/ni5010.c
+++ b/drivers/net/ni5010.c
@@ -189,6 +189,17 @@ static void __init trigger_irq(int ioaddr)
outb(MM_EN_XMT|MM_MUX, IE_MMODE); /* Start transmission */
}
+static const struct net_device_ops ni5010_netdev_ops = {
+ .ndo_open = ni5010_open,
+ .ndo_stop = ni5010_close,
+ .ndo_start_xmit = ni5010_send_packet,
+ .ndo_set_multicast_list = ni5010_set_multicast_list,
+ .ndo_tx_timeout = ni5010_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+};
+
/*
* This is the real probe routine. Linux has a history of friendly device
* probes on the ISA bus. A good device probes avoids doing writes, and
@@ -328,13 +339,8 @@ static int __init ni5010_probe1(struct net_device *dev, int ioaddr)
outb(0, IE_RBUF); /* set buffer byte 0 to 0 again */
}
printk("-> bufsize rcv/xmt=%d/%d\n", bufsize_rcv, NI5010_BUFSIZE);
- memset(netdev_priv(dev), 0, sizeof(struct ni5010_local));
- dev->open = ni5010_open;
- dev->stop = ni5010_close;
- dev->hard_start_xmit = ni5010_send_packet;
- dev->set_multicast_list = ni5010_set_multicast_list;
- dev->tx_timeout = ni5010_timeout;
+ dev->netdev_ops = &ni5010_netdev_ops;
dev->watchdog_timeo = HZ/20;
dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */
diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c
index a8bcc00c3302..77d44a061703 100644
--- a/drivers/net/ni52.c
+++ b/drivers/net/ni52.c
@@ -441,6 +441,18 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops ni52_netdev_ops = {
+ .ndo_open = ni52_open,
+ .ndo_stop = ni52_close,
+ .ndo_get_stats = ni52_get_stats,
+ .ndo_tx_timeout = ni52_timeout,
+ .ndo_start_xmit = ni52_send_packet,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __init ni52_probe1(struct net_device *dev, int ioaddr)
{
int i, size, retval;
@@ -561,15 +573,8 @@ static int __init ni52_probe1(struct net_device *dev, int ioaddr)
printk("IRQ %d (assigned and not checked!).\n", dev->irq);
}
- dev->open = ni52_open;
- dev->stop = ni52_close;
- dev->get_stats = ni52_get_stats;
- dev->tx_timeout = ni52_timeout;
+ dev->netdev_ops = &ni52_netdev_ops;
dev->watchdog_timeo = HZ/20;
- dev->hard_start_xmit = ni52_send_packet;
- dev->set_multicast_list = set_multicast_list;
-
- dev->if_port = 0;
return 0;
out:
diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c
index 254057275e0e..6474f02bf783 100644
--- a/drivers/net/ni65.c
+++ b/drivers/net/ni65.c
@@ -237,7 +237,7 @@ struct priv
void *tmdbounce[TMDNUM];
int tmdbouncenum;
int lock,xmit_queued;
- struct net_device_stats stats;
+
void *self;
int cmdr_addr;
int cardno;
@@ -257,7 +257,6 @@ static void ni65_timeout(struct net_device *dev);
static int ni65_close(struct net_device *dev);
static int ni65_alloc_buffer(struct net_device *dev);
static void ni65_free_buffer(struct priv *p);
-static struct net_device_stats *ni65_get_stats(struct net_device *);
static void set_multicast_list(struct net_device *dev);
static int irqtab[] __initdata = { 9,12,15,5 }; /* irq config-translate */
@@ -401,6 +400,17 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops ni65_netdev_ops = {
+ .ndo_open = ni65_open,
+ .ndo_stop = ni65_close,
+ .ndo_start_xmit = ni65_send_packet,
+ .ndo_tx_timeout = ni65_timeout,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*
* this is the real card probe ..
*/
@@ -481,8 +491,9 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
else {
if(dev->dma == 0) {
/* 'stuck test' from lance.c */
- long dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
- (inb(DMA2_STAT_REG) & 0xf0);
+ unsigned long dma_channels =
+ ((inb(DMA1_STAT_REG) >> 4) & 0x0f)
+ | (inb(DMA2_STAT_REG) & 0xf0);
for(i=1;i<5;i++) {
int dma = dmatab[i];
if(test_bit(dma,&dma_channels) || request_dma(dma,"ni6510"))
@@ -548,13 +559,9 @@ static int __init ni65_probe1(struct net_device *dev,int ioaddr)
}
dev->base_addr = ioaddr;
- dev->open = ni65_open;
- dev->stop = ni65_close;
- dev->hard_start_xmit = ni65_send_packet;
- dev->tx_timeout = ni65_timeout;
+ dev->netdev_ops = &ni65_netdev_ops;
dev->watchdog_timeo = HZ/2;
- dev->get_stats = ni65_get_stats;
- dev->set_multicast_list = set_multicast_list;
+
return 0; /* everything is OK */
}
@@ -897,17 +904,16 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
if(csr0 & CSR0_ERR)
{
- struct priv *p = dev->ml_priv;
if(debuglevel > 1)
printk(KERN_ERR "%s: general error: %04x.\n",dev->name,csr0);
if(csr0 & CSR0_BABL)
- p->stats.tx_errors++;
+ dev->stats.tx_errors++;
if(csr0 & CSR0_MISS) {
int i;
for(i=0;i<RMDNUM;i++)
printk("%02x ",p->rmdhead[i].u.s.status);
printk("\n");
- p->stats.rx_errors++;
+ dev->stats.rx_errors++;
}
if(csr0 & CSR0_MERR) {
if(debuglevel > 1)
@@ -922,8 +928,7 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
int j;
for(j=0;j<RMDNUM;j++)
{
- struct priv *p = dev->ml_priv;
- int i,k,num1,num2;
+ int i, num2;
for(i=RMDNUM-1;i>0;i--) {
num2 = (p->rmdnum + i) & (RMDNUM-1);
if(!(p->rmdhead[num2].u.s.status & RCV_OWN))
@@ -931,6 +936,7 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
}
if(i) {
+ int k, num1;
for(k=0;k<RMDNUM;k++) {
num1 = (p->rmdnum + k) & (RMDNUM-1);
if(!(p->rmdhead[num1].u.s.status & RCV_OWN))
@@ -942,7 +948,6 @@ static irqreturn_t ni65_interrupt(int irq, void * dev_id)
if(debuglevel > 0)
{
char buf[256],*buf1;
- int k;
buf1 = buf;
for(k=0;k<RMDNUM;k++) {
sprintf(buf1,"%02x ",(p->rmdhead[k].u.s.status)); /* & RCV_OWN) ); */
@@ -998,12 +1003,12 @@ static void ni65_xmit_intr(struct net_device *dev,int csr0)
#endif
/* checking some errors */
if(tmdp->status2 & XMIT_RTRY)
- p->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
if(tmdp->status2 & XMIT_LCAR)
- p->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
if(tmdp->status2 & (XMIT_BUFF | XMIT_UFLO )) {
/* this stops the xmitter */
- p->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
if(debuglevel > 0)
printk(KERN_ERR "%s: Xmit FIFO/BUFF error\n",dev->name);
if(p->features & INIT_RING_BEFORE_START) {
@@ -1017,12 +1022,12 @@ static void ni65_xmit_intr(struct net_device *dev,int csr0)
if(debuglevel > 2)
printk(KERN_ERR "%s: xmit-error: %04x %02x-%04x\n",dev->name,csr0,(int) tmdstat,(int) tmdp->status2);
if(!(csr0 & CSR0_BABL)) /* don't count errors twice */
- p->stats.tx_errors++;
+ dev->stats.tx_errors++;
tmdp->status2 = 0;
}
else {
- p->stats.tx_bytes -= (short)(tmdp->blen);
- p->stats.tx_packets++;
+ dev->stats.tx_bytes -= (short)(tmdp->blen);
+ dev->stats.tx_packets++;
}
#ifdef XMT_VIA_SKB
@@ -1058,7 +1063,7 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
if(!(rmdstat & RCV_ERR)) {
if(rmdstat & RCV_START)
{
- p->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
printk(KERN_ERR "%s: recv, packet too long: %d\n",dev->name,rmdp->mlen & 0x0fff);
}
}
@@ -1067,16 +1072,16 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
printk(KERN_ERR "%s: receive-error: %04x, lance-status: %04x/%04x\n",
dev->name,(int) rmdstat,csr0,(int) inw(PORT+L_DATAREG) );
if(rmdstat & RCV_FRAM)
- p->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if(rmdstat & RCV_OFLO)
- p->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
if(rmdstat & RCV_CRC)
- p->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if(rmdstat & RCV_BUF_ERR)
- p->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
}
if(!(csr0 & CSR0_MISS)) /* don't count errors twice */
- p->stats.rx_errors++;
+ dev->stats.rx_errors++;
}
else if( (len = (rmdp->mlen & 0x0fff) - 4) >= 60)
{
@@ -1107,20 +1112,20 @@ static void ni65_recv_intr(struct net_device *dev,int csr0)
skb_put(skb,len);
skb_copy_to_linear_data(skb, (unsigned char *) p->recvbounce[p->rmdnum],len);
#endif
- p->stats.rx_packets++;
- p->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);
}
else
{
printk(KERN_ERR "%s: can't alloc new sk_buff\n",dev->name);
- p->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
}
}
else {
printk(KERN_INFO "%s: received runt packet\n",dev->name);
- p->stats.rx_errors++;
+ dev->stats.rx_errors++;
}
rmdp->blen = -(R_BUF_SIZE-8);
rmdp->mlen = 0;
@@ -1214,23 +1219,6 @@ static int ni65_send_packet(struct sk_buff *skb, struct net_device *dev)
return 0;
}
-static struct net_device_stats *ni65_get_stats(struct net_device *dev)
-{
-
-#if 0
- int i;
- struct priv *p = dev->ml_priv;
- for(i=0;i<RMDNUM;i++)
- {
- struct rmd *rmdp = p->rmdhead + ((p->rmdnum + i) & (RMDNUM-1));
- printk("%02x ",rmdp->u.s.status);
- }
- printk("\n");
-#endif
-
- return &((struct priv *)dev->ml_priv)->stats;
-}
-
static void set_multicast_list(struct net_device *dev)
{
if(!ni65_lance_reinit(dev))
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 0c0b752315ca..02c37e2f08a9 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -1115,6 +1115,130 @@ static int link_status_10g_serdes(struct niu *np, int *link_up_p)
return 0;
}
+static int link_status_mii(struct niu *np, int *link_up_p)
+{
+ struct niu_link_config *lp = &np->link_config;
+ int err;
+ int bmsr, advert, ctrl1000, stat1000, lpa, bmcr, estatus;
+ int supported, advertising, active_speed, active_duplex;
+
+ err = mii_read(np, np->phy_addr, MII_BMCR);
+ if (unlikely(err < 0))
+ return err;
+ bmcr = err;
+
+ err = mii_read(np, np->phy_addr, MII_BMSR);
+ if (unlikely(err < 0))
+ return err;
+ bmsr = err;
+
+ err = mii_read(np, np->phy_addr, MII_ADVERTISE);
+ if (unlikely(err < 0))
+ return err;
+ advert = err;
+
+ err = mii_read(np, np->phy_addr, MII_LPA);
+ if (unlikely(err < 0))
+ return err;
+ lpa = err;
+
+ if (likely(bmsr & BMSR_ESTATEN)) {
+ err = mii_read(np, np->phy_addr, MII_ESTATUS);
+ if (unlikely(err < 0))
+ return err;
+ estatus = err;
+
+ err = mii_read(np, np->phy_addr, MII_CTRL1000);
+ if (unlikely(err < 0))
+ return err;
+ ctrl1000 = err;
+
+ err = mii_read(np, np->phy_addr, MII_STAT1000);
+ if (unlikely(err < 0))
+ return err;
+ stat1000 = err;
+ } else
+ estatus = ctrl1000 = stat1000 = 0;
+
+ supported = 0;
+ if (bmsr & BMSR_ANEGCAPABLE)
+ supported |= SUPPORTED_Autoneg;
+ if (bmsr & BMSR_10HALF)
+ supported |= SUPPORTED_10baseT_Half;
+ if (bmsr & BMSR_10FULL)
+ supported |= SUPPORTED_10baseT_Full;
+ if (bmsr & BMSR_100HALF)
+ supported |= SUPPORTED_100baseT_Half;
+ if (bmsr & BMSR_100FULL)
+ supported |= SUPPORTED_100baseT_Full;
+ if (estatus & ESTATUS_1000_THALF)
+ supported |= SUPPORTED_1000baseT_Half;
+ if (estatus & ESTATUS_1000_TFULL)
+ supported |= SUPPORTED_1000baseT_Full;
+ lp->supported = supported;
+
+ advertising = 0;
+ if (advert & ADVERTISE_10HALF)
+ advertising |= ADVERTISED_10baseT_Half;
+ if (advert & ADVERTISE_10FULL)
+ advertising |= ADVERTISED_10baseT_Full;
+ if (advert & ADVERTISE_100HALF)
+ advertising |= ADVERTISED_100baseT_Half;
+ if (advert & ADVERTISE_100FULL)
+ advertising |= ADVERTISED_100baseT_Full;
+ if (ctrl1000 & ADVERTISE_1000HALF)
+ advertising |= ADVERTISED_1000baseT_Half;
+ if (ctrl1000 & ADVERTISE_1000FULL)
+ advertising |= ADVERTISED_1000baseT_Full;
+
+ if (bmcr & BMCR_ANENABLE) {
+ int neg, neg1000;
+
+ lp->active_autoneg = 1;
+ advertising |= ADVERTISED_Autoneg;
+
+ neg = advert & lpa;
+ neg1000 = (ctrl1000 << 2) & stat1000;
+
+ if (neg1000 & (LPA_1000FULL | LPA_1000HALF))
+ active_speed = SPEED_1000;
+ else if (neg & LPA_100)
+ active_speed = SPEED_100;
+ else if (neg & (LPA_10HALF | LPA_10FULL))
+ active_speed = SPEED_10;
+ else
+ active_speed = SPEED_INVALID;
+
+ if ((neg1000 & LPA_1000FULL) || (neg & LPA_DUPLEX))
+ active_duplex = DUPLEX_FULL;
+ else if (active_speed != SPEED_INVALID)
+ active_duplex = DUPLEX_HALF;
+ else
+ active_duplex = DUPLEX_INVALID;
+ } else {
+ lp->active_autoneg = 0;
+
+ if ((bmcr & BMCR_SPEED1000) && !(bmcr & BMCR_SPEED100))
+ active_speed = SPEED_1000;
+ else if (bmcr & BMCR_SPEED100)
+ active_speed = SPEED_100;
+ else
+ active_speed = SPEED_10;
+
+ if (bmcr & BMCR_FULLDPLX)
+ active_duplex = DUPLEX_FULL;
+ else
+ active_duplex = DUPLEX_HALF;
+ }
+
+ lp->active_advertising = advertising;
+ lp->active_speed = active_speed;
+ lp->active_duplex = active_duplex;
+ *link_up_p = !!(bmsr & BMSR_LSTATUS);
+
+ return 0;
+}
+
static int link_status_1g_rgmii(struct niu *np, int *link_up_p)
{
struct niu_link_config *lp = &np->link_config;
@@ -1171,6 +1295,22 @@ out:
return err;
}
+static int link_status_1g(struct niu *np, int *link_up_p)
+{
+ struct niu_link_config *lp = &np->link_config;
+ unsigned long flags;
+ int err;
+
+ spin_lock_irqsave(&np->lock, flags);
+
+ err = link_status_mii(np, link_up_p);
+ lp->supported |= SUPPORTED_TP;
+ lp->active_advertising |= ADVERTISED_TP;
+
+ spin_unlock_irqrestore(&np->lock, flags);
+ return err;
+}
+
static int bcm8704_reset(struct niu *np)
{
int err, limit;
@@ -1676,39 +1816,88 @@ static int mii_init_common(struct niu *np)
return err;
}
- /* XXX configurable XXX */
- /* XXX for now don't advertise half-duplex or asym pause... XXX */
- adv = ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP;
- if (bmsr & BMSR_10FULL)
- adv |= ADVERTISE_10FULL;
- if (bmsr & BMSR_100FULL)
- adv |= ADVERTISE_100FULL;
- err = mii_write(np, np->phy_addr, MII_ADVERTISE, adv);
- if (err)
- return err;
-
- if (bmsr & BMSR_ESTATEN) {
- u16 ctrl1000 = 0;
-
- if (estat & ESTATUS_1000_TFULL)
- ctrl1000 |= ADVERTISE_1000FULL;
- err = mii_write(np, np->phy_addr, MII_CTRL1000, ctrl1000);
+ if (lp->autoneg) {
+ u16 ctrl1000;
+
+ adv = ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP;
+ if ((bmsr & BMSR_10HALF) &&
+ (lp->advertising & ADVERTISED_10baseT_Half))
+ adv |= ADVERTISE_10HALF;
+ if ((bmsr & BMSR_10FULL) &&
+ (lp->advertising & ADVERTISED_10baseT_Full))
+ adv |= ADVERTISE_10FULL;
+ if ((bmsr & BMSR_100HALF) &&
+ (lp->advertising & ADVERTISED_100baseT_Half))
+ adv |= ADVERTISE_100HALF;
+ if ((bmsr & BMSR_100FULL) &&
+ (lp->advertising & ADVERTISED_100baseT_Full))
+ adv |= ADVERTISE_100FULL;
+ err = mii_write(np, np->phy_addr, MII_ADVERTISE, adv);
if (err)
return err;
+
+ if (likely(bmsr & BMSR_ESTATEN)) {
+ ctrl1000 = 0;
+ if ((estat & ESTATUS_1000_THALF) &&
+ (lp->advertising & ADVERTISED_1000baseT_Half))
+ ctrl1000 |= ADVERTISE_1000HALF;
+ if ((estat & ESTATUS_1000_TFULL) &&
+ (lp->advertising & ADVERTISED_1000baseT_Full))
+ ctrl1000 |= ADVERTISE_1000FULL;
+ err = mii_write(np, np->phy_addr,
+ MII_CTRL1000, ctrl1000);
+ if (err)
+ return err;
+ }
+
+ bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
+ } else {
+ /* !lp->autoneg */
+ int fulldpx;
+
+ if (lp->duplex == DUPLEX_FULL) {
+ bmcr |= BMCR_FULLDPLX;
+ fulldpx = 1;
+ } else if (lp->duplex == DUPLEX_HALF)
+ fulldpx = 0;
+ else
+ return -EINVAL;
+
+ if (lp->speed == SPEED_1000) {
+ /* if X-full requested while not supported, or
+ X-half requested while not supported... */
+ if ((fulldpx && !(estat & ESTATUS_1000_TFULL)) ||
+ (!fulldpx && !(estat & ESTATUS_1000_THALF)))
+ return -EINVAL;
+ bmcr |= BMCR_SPEED1000;
+ } else if (lp->speed == SPEED_100) {
+ if ((fulldpx && !(bmsr & BMSR_100FULL)) ||
+ (!fulldpx && !(bmsr & BMSR_100HALF)))
+ return -EINVAL;
+ bmcr |= BMCR_SPEED100;
+ } else if (lp->speed == SPEED_10) {
+ if ((fulldpx && !(bmsr & BMSR_10FULL)) ||
+ (!fulldpx && !(bmsr & BMSR_10HALF)))
+ return -EINVAL;
+ } else
+ return -EINVAL;
}
- bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
err = mii_write(np, np->phy_addr, MII_BMCR, bmcr);
if (err)
return err;
+#if 0
err = mii_read(np, np->phy_addr, MII_BMCR);
if (err < 0)
return err;
+ bmcr = err;
+
err = mii_read(np, np->phy_addr, MII_BMSR);
if (err < 0)
return err;
-#if 0
+ bmsr = err;
+
pr_info(PFX "Port %u after MII init bmcr[%04x] bmsr[%04x]\n",
np->port, bmcr, bmsr);
#endif
@@ -2054,87 +2243,6 @@ static int link_status_10g_hotplug(struct niu *np, int *link_up_p)
return err;
}
-static int link_status_1g(struct niu *np, int *link_up_p)
-{
- struct niu_link_config *lp = &np->link_config;
- u16 current_speed, bmsr;
- unsigned long flags;
- u8 current_duplex;
- int err, link_up;
-
- link_up = 0;
- current_speed = SPEED_INVALID;
- current_duplex = DUPLEX_INVALID;
-
- spin_lock_irqsave(&np->lock, flags);
-
- err = -EINVAL;
- if (np->link_config.loopback_mode != LOOPBACK_DISABLED)
- goto out;
-
- err = mii_read(np, np->phy_addr, MII_BMSR);
- if (err < 0)
- goto out;
-
- bmsr = err;
- if (bmsr & BMSR_LSTATUS) {
- u16 adv, lpa, common, estat;
-
- err = mii_read(np, np->phy_addr, MII_ADVERTISE);
- if (err < 0)
- goto out;
- adv = err;
-
- err = mii_read(np, np->phy_addr, MII_LPA);
- if (err < 0)
- goto out;
- lpa = err;
-
- common = adv & lpa;
-
- err = mii_read(np, np->phy_addr, MII_ESTATUS);
- if (err < 0)
- goto out;
- estat = err;
-
- link_up = 1;
- if (estat & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) {
- current_speed = SPEED_1000;
- if (estat & ESTATUS_1000_TFULL)
- current_duplex = DUPLEX_FULL;
- else
- current_duplex = DUPLEX_HALF;
- } else {
- if (common & ADVERTISE_100BASE4) {
- current_speed = SPEED_100;
- current_duplex = DUPLEX_HALF;
- } else if (common & ADVERTISE_100FULL) {
- current_speed = SPEED_100;
- current_duplex = DUPLEX_FULL;
- } else if (common & ADVERTISE_100HALF) {
- current_speed = SPEED_100;
- current_duplex = DUPLEX_HALF;
- } else if (common & ADVERTISE_10FULL) {
- current_speed = SPEED_10;
- current_duplex = DUPLEX_FULL;
- } else if (common & ADVERTISE_10HALF) {
- current_speed = SPEED_10;
- current_duplex = DUPLEX_HALF;
- } else
- link_up = 0;
- }
- }
- lp->active_speed = current_speed;
- lp->active_duplex = current_duplex;
- err = 0;
-
-out:
- spin_unlock_irqrestore(&np->lock, flags);
-
- *link_up_p = link_up;
- return err;
-}
-
static int niu_link_status(struct niu *np, int *link_up_p)
{
const struct niu_phy_ops *ops = np->phy_ops;
@@ -2284,7 +2392,6 @@ static int serdes_init_10g_serdes(struct niu *np)
struct niu_link_config *lp = &np->link_config;
unsigned long ctrl_reg, test_cfg_reg, pll_cfg, i;
u64 ctrl_val, test_cfg_val, sig, mask, val;
- int err;
u64 reset_val;
switch (np->port) {
@@ -2337,6 +2444,7 @@ static int serdes_init_10g_serdes(struct niu *np)
/* Initialize all 4 lanes of the SERDES. */
for (i = 0; i < 4; i++) {
u32 rxtx_ctrl, glue0;
+ int err;
err = esr_read_rxtx_ctrl(np, i, &rxtx_ctrl);
if (err)
@@ -2456,7 +2564,7 @@ static int niu_determine_phy_disposition(struct niu *np)
case NIU_FLAGS_10G:
/* 10G copper */
- tp = &phy_template_1g_copper;
+ tp = &phy_template_10g_copper;
break;
case NIU_FLAGS_FIBER:
@@ -2873,7 +2981,6 @@ static int tcam_user_ip_class_enable(struct niu *np, unsigned long class,
return 0;
}
-#if 0
static int tcam_user_ip_class_set(struct niu *np, unsigned long class,
int ipv6, u64 protocol_id,
u64 tos_mask, u64 tos_val)
@@ -2901,7 +3008,6 @@ static int tcam_user_ip_class_set(struct niu *np, unsigned long class,
return 0;
}
-#endif
static int tcam_early_init(struct niu *np)
{
@@ -3168,6 +3274,27 @@ static int niu_set_tcam_key(struct niu *np, unsigned long class_code, u64 key)
return 0;
}
+/* Entries for the ports are interleaved in the TCAM */
+static u16 tcam_get_index(struct niu *np, u16 idx)
+{
+ /* One entry reserved for IP fragment rule */
+ if (idx >= (np->clas.tcam_sz - 1))
+ idx = 0;
+ return (np->clas.tcam_top + ((idx+1) * np->parent->num_ports));
+}
+
+static u16 tcam_get_size(struct niu *np)
+{
+ /* One entry reserved for IP fragment rule */
+ return np->clas.tcam_sz - 1;
+}
+
+static u16 tcam_get_valid_entry_cnt(struct niu *np)
+{
+ /* One entry reserved for IP fragment rule */
+ return np->clas.tcam_valid_entries - 1;
+}
+
static void niu_rx_skb_append(struct sk_buff *skb, struct page *page,
u32 offset, u32 size)
{
@@ -3314,7 +3441,8 @@ static int niu_rx_pkt_ignore(struct niu *np, struct rx_ring_info *rp)
return num_rcr;
}
-static int niu_process_rx_pkt(struct niu *np, struct rx_ring_info *rp)
+static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np,
+ struct rx_ring_info *rp)
{
unsigned int index = rp->rcr_index;
struct sk_buff *skb;
@@ -3390,7 +3518,8 @@ static int niu_process_rx_pkt(struct niu *np, struct rx_ring_info *rp)
rp->rx_bytes += skb->len;
skb->protocol = eth_type_trans(skb, np->dev);
- netif_receive_skb(skb);
+ skb_record_rx_queue(skb, rp->rx_channel);
+ napi_gro_receive(napi, skb);
return num_rcr;
}
@@ -3578,7 +3707,8 @@ static inline void niu_sync_rx_discard_stats(struct niu *np,
}
}
-static int niu_rx_work(struct niu *np, struct rx_ring_info *rp, int budget)
+static int niu_rx_work(struct napi_struct *napi, struct niu *np,
+ struct rx_ring_info *rp, int budget)
{
int qlen, rcr_done = 0, work_done = 0;
struct rxdma_mailbox *mbox = rp->mbox;
@@ -3600,7 +3730,7 @@ static int niu_rx_work(struct niu *np, struct rx_ring_info *rp, int budget)
rcr_done = work_done = 0;
qlen = min(qlen, budget);
while (work_done < qlen) {
- rcr_done += niu_process_rx_pkt(np, rp);
+ rcr_done += niu_process_rx_pkt(napi, np, rp);
work_done++;
}
@@ -3648,7 +3778,7 @@ static int niu_poll_core(struct niu *np, struct niu_ldg *lp, int budget)
if (rx_vec & (1 << rp->rx_channel)) {
int this_work_done;
- this_work_done = niu_rx_work(np, rp,
+ this_work_done = niu_rx_work(&lp->napi, np, rp,
budget);
budget -= this_work_done;
@@ -3669,7 +3799,7 @@ static int niu_poll(struct napi_struct *napi, int budget)
work_done = niu_poll_core(np, lp, budget);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
niu_ldg_rearm(np, lp, 1);
}
return work_done;
@@ -4088,12 +4218,12 @@ static void __niu_fastpath_interrupt(struct niu *np, int ldg, u64 v0)
static void niu_schedule_napi(struct niu *np, struct niu_ldg *lp,
u64 v0, u64 v1, u64 v2)
{
- if (likely(netif_rx_schedule_prep(&lp->napi))) {
+ if (likely(napi_schedule_prep(&lp->napi))) {
lp->v0 = v0;
lp->v1 = v1;
lp->v2 = v2;
__niu_fastpath_interrupt(np, lp->ldg_num, v0);
- __netif_rx_schedule(&lp->napi);
+ __napi_schedule(&lp->napi);
}
}
@@ -4890,8 +5020,7 @@ static int niu_set_ip_frag_rule(struct niu *np)
struct niu_tcam_entry *tp;
int index, err;
- /* XXX fix this allocation scheme XXX */
- index = cp->tcam_index;
+ index = cp->tcam_top;
tp = &parent->tcam[index];
/* Note that the noport bit is the same in both ipv4 and
@@ -4908,6 +5037,8 @@ static int niu_set_ip_frag_rule(struct niu *np)
err = tcam_assoc_write(np, index, tp->assoc_data);
if (err)
return err;
+ tp->valid = 1;
+ cp->tcam_valid_entries++;
return 0;
}
@@ -5211,10 +5342,10 @@ static void niu_init_xif_xmac(struct niu *np)
if (np->flags & NIU_FLAGS_10G) {
val |= XMAC_CONFIG_MODE_XGMII;
} else {
- if (lp->active_speed == SPEED_100)
- val |= XMAC_CONFIG_MODE_MII;
- else
+ if (lp->active_speed == SPEED_1000)
val |= XMAC_CONFIG_MODE_GMII;
+ else
+ val |= XMAC_CONFIG_MODE_MII;
}
nw64_mac(XMAC_CONFIG, val);
@@ -6446,11 +6577,11 @@ static u64 niu_compute_tx_flags(struct sk_buff *skb, struct ethhdr *ehdr,
ipv6 = ihl = 0;
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case cpu_to_be16(ETH_P_IP):
ip_proto = ip_hdr(skb)->protocol;
ihl = ip_hdr(skb)->ihl;
break;
- case __constant_htons(ETH_P_IPV6):
+ case cpu_to_be16(ETH_P_IPV6):
ip_proto = ipv6_hdr(skb)->nexthdr;
ihl = (40 >> 2);
ipv6 = 1;
@@ -6702,17 +6833,27 @@ static int niu_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
memset(cmd, 0, sizeof(*cmd));
cmd->phy_address = np->phy_addr;
cmd->supported = lp->supported;
- cmd->advertising = lp->advertising;
- cmd->autoneg = lp->autoneg;
+ cmd->advertising = lp->active_advertising;
+ cmd->autoneg = lp->active_autoneg;
cmd->speed = lp->active_speed;
cmd->duplex = lp->active_duplex;
+ cmd->port = (np->flags & NIU_FLAGS_FIBER) ? PORT_FIBRE : PORT_TP;
+ cmd->transceiver = (np->flags & NIU_FLAGS_XCVR_SERDES) ?
+ XCVR_EXTERNAL : XCVR_INTERNAL;
return 0;
}
static int niu_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
- return -EINVAL;
+ struct niu *np = netdev_priv(dev);
+ struct niu_link_config *lp = &np->link_config;
+
+ lp->advertising = cmd->advertising;
+ lp->speed = cmd->speed;
+ lp->duplex = cmd->duplex;
+ lp->autoneg = cmd->autoneg;
+ return niu_init_link(np);
}
static u32 niu_get_msglevel(struct net_device *dev)
@@ -6727,6 +6868,16 @@ static void niu_set_msglevel(struct net_device *dev, u32 value)
np->msg_enable = value;
}
+static int niu_nway_reset(struct net_device *dev)
+{
+ struct niu *np = netdev_priv(dev);
+
+ if (np->link_config.autoneg)
+ return niu_init_link(np);
+
+ return 0;
+}
+
static int niu_get_eeprom_len(struct net_device *dev)
{
struct niu *np = netdev_priv(dev);
@@ -6778,6 +6929,75 @@ static int niu_get_eeprom(struct net_device *dev,
return 0;
}
+static void niu_ethflow_to_l3proto(int flow_type, u8 *pid)
+{
+ switch (flow_type) {
+ case TCP_V4_FLOW:
+ case TCP_V6_FLOW:
+ *pid = IPPROTO_TCP;
+ break;
+ case UDP_V4_FLOW:
+ case UDP_V6_FLOW:
+ *pid = IPPROTO_UDP;
+ break;
+ case SCTP_V4_FLOW:
+ case SCTP_V6_FLOW:
+ *pid = IPPROTO_SCTP;
+ break;
+ case AH_V4_FLOW:
+ case AH_V6_FLOW:
+ *pid = IPPROTO_AH;
+ break;
+ case ESP_V4_FLOW:
+ case ESP_V6_FLOW:
+ *pid = IPPROTO_ESP;
+ break;
+ default:
+ *pid = 0;
+ break;
+ }
+}
+
+static int niu_class_to_ethflow(u64 class, int *flow_type)
+{
+ switch (class) {
+ case CLASS_CODE_TCP_IPV4:
+ *flow_type = TCP_V4_FLOW;
+ break;
+ case CLASS_CODE_UDP_IPV4:
+ *flow_type = UDP_V4_FLOW;
+ break;
+ case CLASS_CODE_AH_ESP_IPV4:
+ *flow_type = AH_V4_FLOW;
+ break;
+ case CLASS_CODE_SCTP_IPV4:
+ *flow_type = SCTP_V4_FLOW;
+ break;
+ case CLASS_CODE_TCP_IPV6:
+ *flow_type = TCP_V6_FLOW;
+ break;
+ case CLASS_CODE_UDP_IPV6:
+ *flow_type = UDP_V6_FLOW;
+ break;
+ case CLASS_CODE_AH_ESP_IPV6:
+ *flow_type = AH_V6_FLOW;
+ break;
+ case CLASS_CODE_SCTP_IPV6:
+ *flow_type = SCTP_V6_FLOW;
+ break;
+ case CLASS_CODE_USER_PROG1:
+ case CLASS_CODE_USER_PROG2:
+ case CLASS_CODE_USER_PROG3:
+ case CLASS_CODE_USER_PROG4:
+ *flow_type = IP_USER_FLOW;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
static int niu_ethflow_to_class(int flow_type, u64 *class)
{
switch (flow_type) {
@@ -6787,7 +7007,8 @@ static int niu_ethflow_to_class(int flow_type, u64 *class)
case UDP_V4_FLOW:
*class = CLASS_CODE_UDP_IPV4;
break;
- case AH_ESP_V4_FLOW:
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
*class = CLASS_CODE_AH_ESP_IPV4;
break;
case SCTP_V4_FLOW:
@@ -6799,7 +7020,8 @@ static int niu_ethflow_to_class(int flow_type, u64 *class)
case UDP_V6_FLOW:
*class = CLASS_CODE_UDP_IPV6;
break;
- case AH_ESP_V6_FLOW:
+ case AH_V6_FLOW:
+ case ESP_V6_FLOW:
*class = CLASS_CODE_AH_ESP_IPV6;
break;
case SCTP_V6_FLOW:
@@ -6816,8 +7038,6 @@ static u64 niu_flowkey_to_ethflow(u64 flow_key)
{
u64 ethflow = 0;
- if (flow_key & FLOW_KEY_PORT)
- ethflow |= RXH_DEV_PORT;
if (flow_key & FLOW_KEY_L2DA)
ethflow |= RXH_L2DA;
if (flow_key & FLOW_KEY_VLAN)
@@ -6841,8 +7061,6 @@ static int niu_ethflow_to_flowkey(u64 ethflow, u64 *flow_key)
{
u64 key = 0;
- if (ethflow & RXH_DEV_PORT)
- key |= FLOW_KEY_PORT;
if (ethflow & RXH_L2DA)
key |= FLOW_KEY_L2DA;
if (ethflow & RXH_VLAN)
@@ -6864,41 +7082,279 @@ static int niu_ethflow_to_flowkey(u64 ethflow, u64 *flow_key)
}
-static int niu_get_hash_opts(struct net_device *dev, struct ethtool_rxnfc *cmd)
+static int niu_get_hash_opts(struct niu *np, struct ethtool_rxnfc *nfc)
{
- struct niu *np = netdev_priv(dev);
u64 class;
- cmd->data = 0;
+ nfc->data = 0;
- if (!niu_ethflow_to_class(cmd->flow_type, &class))
+ if (!niu_ethflow_to_class(nfc->flow_type, &class))
return -EINVAL;
if (np->parent->tcam_key[class - CLASS_CODE_USER_PROG1] &
TCAM_KEY_DISC)
- cmd->data = RXH_DISCARD;
+ nfc->data = RXH_DISCARD;
else
-
- cmd->data = niu_flowkey_to_ethflow(np->parent->flow_key[class -
+ nfc->data = niu_flowkey_to_ethflow(np->parent->flow_key[class -
CLASS_CODE_USER_PROG1]);
return 0;
}
-static int niu_set_hash_opts(struct net_device *dev, struct ethtool_rxnfc *cmd)
+static void niu_get_ip4fs_from_tcam_key(struct niu_tcam_entry *tp,
+ struct ethtool_rx_flow_spec *fsp)
+{
+
+ fsp->h_u.tcp_ip4_spec.ip4src = (tp->key[3] & TCAM_V4KEY3_SADDR) >>
+ TCAM_V4KEY3_SADDR_SHIFT;
+ fsp->h_u.tcp_ip4_spec.ip4dst = (tp->key[3] & TCAM_V4KEY3_DADDR) >>
+ TCAM_V4KEY3_DADDR_SHIFT;
+ fsp->m_u.tcp_ip4_spec.ip4src = (tp->key_mask[3] & TCAM_V4KEY3_SADDR) >>
+ TCAM_V4KEY3_SADDR_SHIFT;
+ fsp->m_u.tcp_ip4_spec.ip4dst = (tp->key_mask[3] & TCAM_V4KEY3_DADDR) >>
+ TCAM_V4KEY3_DADDR_SHIFT;
+
+ fsp->h_u.tcp_ip4_spec.ip4src =
+ cpu_to_be32(fsp->h_u.tcp_ip4_spec.ip4src);
+ fsp->m_u.tcp_ip4_spec.ip4src =
+ cpu_to_be32(fsp->m_u.tcp_ip4_spec.ip4src);
+ fsp->h_u.tcp_ip4_spec.ip4dst =
+ cpu_to_be32(fsp->h_u.tcp_ip4_spec.ip4dst);
+ fsp->m_u.tcp_ip4_spec.ip4dst =
+ cpu_to_be32(fsp->m_u.tcp_ip4_spec.ip4dst);
+
+ fsp->h_u.tcp_ip4_spec.tos = (tp->key[2] & TCAM_V4KEY2_TOS) >>
+ TCAM_V4KEY2_TOS_SHIFT;
+ fsp->m_u.tcp_ip4_spec.tos = (tp->key_mask[2] & TCAM_V4KEY2_TOS) >>
+ TCAM_V4KEY2_TOS_SHIFT;
+
+ switch (fsp->flow_type) {
+ case TCP_V4_FLOW:
+ case UDP_V4_FLOW:
+ case SCTP_V4_FLOW:
+ fsp->h_u.tcp_ip4_spec.psrc =
+ ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16;
+ fsp->h_u.tcp_ip4_spec.pdst =
+ ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff;
+ fsp->m_u.tcp_ip4_spec.psrc =
+ ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16;
+ fsp->m_u.tcp_ip4_spec.pdst =
+ ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff;
+
+ fsp->h_u.tcp_ip4_spec.psrc =
+ cpu_to_be16(fsp->h_u.tcp_ip4_spec.psrc);
+ fsp->h_u.tcp_ip4_spec.pdst =
+ cpu_to_be16(fsp->h_u.tcp_ip4_spec.pdst);
+ fsp->m_u.tcp_ip4_spec.psrc =
+ cpu_to_be16(fsp->m_u.tcp_ip4_spec.psrc);
+ fsp->m_u.tcp_ip4_spec.pdst =
+ cpu_to_be16(fsp->m_u.tcp_ip4_spec.pdst);
+ break;
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ fsp->h_u.ah_ip4_spec.spi =
+ (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT;
+ fsp->m_u.ah_ip4_spec.spi =
+ (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT;
+
+ fsp->h_u.ah_ip4_spec.spi =
+ cpu_to_be32(fsp->h_u.ah_ip4_spec.spi);
+ fsp->m_u.ah_ip4_spec.spi =
+ cpu_to_be32(fsp->m_u.ah_ip4_spec.spi);
+ break;
+ case IP_USER_FLOW:
+ fsp->h_u.usr_ip4_spec.l4_4_bytes =
+ (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT;
+ fsp->m_u.usr_ip4_spec.l4_4_bytes =
+ (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >>
+ TCAM_V4KEY2_PORT_SPI_SHIFT;
+
+ fsp->h_u.usr_ip4_spec.l4_4_bytes =
+ cpu_to_be32(fsp->h_u.usr_ip4_spec.l4_4_bytes);
+ fsp->m_u.usr_ip4_spec.l4_4_bytes =
+ cpu_to_be32(fsp->m_u.usr_ip4_spec.l4_4_bytes);
+
+ fsp->h_u.usr_ip4_spec.proto =
+ (tp->key[2] & TCAM_V4KEY2_PROTO) >>
+ TCAM_V4KEY2_PROTO_SHIFT;
+ fsp->m_u.usr_ip4_spec.proto =
+ (tp->key_mask[2] & TCAM_V4KEY2_PROTO) >>
+ TCAM_V4KEY2_PROTO_SHIFT;
+
+ fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
+ break;
+ default:
+ break;
+ }
+}
+
+static int niu_get_ethtool_tcam_entry(struct niu *np,
+ struct ethtool_rxnfc *nfc)
+{
+ struct niu_parent *parent = np->parent;
+ struct niu_tcam_entry *tp;
+ struct ethtool_rx_flow_spec *fsp = &nfc->fs;
+ u16 idx;
+ u64 class;
+ int ret = 0;
+
+ idx = tcam_get_index(np, (u16)nfc->fs.location);
+
+ tp = &parent->tcam[idx];
+ if (!tp->valid) {
+ pr_info(PFX "niu%d: %s entry [%d] invalid for idx[%d]\n",
+ parent->index, np->dev->name, (u16)nfc->fs.location, idx);
+ return -EINVAL;
+ }
+
+ /* fill the flow spec entry */
+ class = (tp->key[0] & TCAM_V4KEY0_CLASS_CODE) >>
+ TCAM_V4KEY0_CLASS_CODE_SHIFT;
+ ret = niu_class_to_ethflow(class, &fsp->flow_type);
+
+ if (ret < 0) {
+ pr_info(PFX "niu%d: %s niu_class_to_ethflow failed\n",
+ parent->index, np->dev->name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (fsp->flow_type == AH_V4_FLOW || fsp->flow_type == AH_V6_FLOW) {
+ u32 proto = (tp->key[2] & TCAM_V4KEY2_PROTO) >>
+ TCAM_V4KEY2_PROTO_SHIFT;
+ if (proto == IPPROTO_ESP) {
+ if (fsp->flow_type == AH_V4_FLOW)
+ fsp->flow_type = ESP_V4_FLOW;
+ else
+ fsp->flow_type = ESP_V6_FLOW;
+ }
+ }
+
+ switch (fsp->flow_type) {
+ case TCP_V4_FLOW:
+ case UDP_V4_FLOW:
+ case SCTP_V4_FLOW:
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ niu_get_ip4fs_from_tcam_key(tp, fsp);
+ break;
+ case TCP_V6_FLOW:
+ case UDP_V6_FLOW:
+ case SCTP_V6_FLOW:
+ case AH_V6_FLOW:
+ case ESP_V6_FLOW:
+ /* Not yet implemented */
+ ret = -EINVAL;
+ break;
+ case IP_USER_FLOW:
+ niu_get_ip4fs_from_tcam_key(tp, fsp);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret < 0)
+ goto out;
+
+ if (tp->assoc_data & TCAM_ASSOCDATA_DISC)
+ fsp->ring_cookie = RX_CLS_FLOW_DISC;
+ else
+ fsp->ring_cookie = (tp->assoc_data & TCAM_ASSOCDATA_OFFSET) >>
+ TCAM_ASSOCDATA_OFFSET_SHIFT;
+
+ /* put the tcam size here */
+ nfc->data = tcam_get_size(np);
+out:
+ return ret;
+}
+
+static int niu_get_ethtool_tcam_all(struct niu *np,
+ struct ethtool_rxnfc *nfc,
+ u32 *rule_locs)
+{
+ struct niu_parent *parent = np->parent;
+ struct niu_tcam_entry *tp;
+ int i, idx, cnt;
+ u16 n_entries;
+ unsigned long flags;
+
+
+ /* put the tcam size here */
+ nfc->data = tcam_get_size(np);
+
+ niu_lock_parent(np, flags);
+ n_entries = nfc->rule_cnt;
+ for (cnt = 0, i = 0; i < nfc->data; i++) {
+ idx = tcam_get_index(np, i);
+ tp = &parent->tcam[idx];
+ if (!tp->valid)
+ continue;
+ rule_locs[cnt] = i;
+ cnt++;
+ }
+ niu_unlock_parent(np, flags);
+
+ if (n_entries != cnt) {
+ /* print warning, this should not happen */
+ pr_info(PFX "niu%d: %s In niu_get_ethtool_tcam_all, "
+ "n_entries[%d] != cnt[%d]!!!\n\n",
+ np->parent->index, np->dev->name, n_entries, cnt);
+ }
+
+ return 0;
+}
+
+static int niu_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+ void *rule_locs)
{
struct niu *np = netdev_priv(dev);
+ int ret = 0;
+
+ switch (cmd->cmd) {
+ case ETHTOOL_GRXFH:
+ ret = niu_get_hash_opts(np, cmd);
+ break;
+ case ETHTOOL_GRXRINGS:
+ cmd->data = np->num_rx_rings;
+ break;
+ case ETHTOOL_GRXCLSRLCNT:
+ cmd->rule_cnt = tcam_get_valid_entry_cnt(np);
+ break;
+ case ETHTOOL_GRXCLSRULE:
+ ret = niu_get_ethtool_tcam_entry(np, cmd);
+ break;
+ case ETHTOOL_GRXCLSRLALL:
+ ret = niu_get_ethtool_tcam_all(np, cmd, (u32 *)rule_locs);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int niu_set_hash_opts(struct niu *np, struct ethtool_rxnfc *nfc)
+{
u64 class;
u64 flow_key = 0;
unsigned long flags;
- if (!niu_ethflow_to_class(cmd->flow_type, &class))
+ if (!niu_ethflow_to_class(nfc->flow_type, &class))
return -EINVAL;
if (class < CLASS_CODE_USER_PROG1 ||
class > CLASS_CODE_SCTP_IPV6)
return -EINVAL;
- if (cmd->data & RXH_DISCARD) {
+ if (nfc->data & RXH_DISCARD) {
niu_lock_parent(np, flags);
flow_key = np->parent->tcam_key[class -
CLASS_CODE_USER_PROG1];
@@ -6923,7 +7379,7 @@ static int niu_set_hash_opts(struct net_device *dev, struct ethtool_rxnfc *cmd)
}
}
- if (!niu_ethflow_to_flowkey(cmd->data, &flow_key))
+ if (!niu_ethflow_to_flowkey(nfc->data, &flow_key))
return -EINVAL;
niu_lock_parent(np, flags);
@@ -6934,6 +7390,331 @@ static int niu_set_hash_opts(struct net_device *dev, struct ethtool_rxnfc *cmd)
return 0;
}
+static void niu_get_tcamkey_from_ip4fs(struct ethtool_rx_flow_spec *fsp,
+ struct niu_tcam_entry *tp,
+ int l2_rdc_tab, u64 class)
+{
+ u8 pid = 0;
+ u32 sip, dip, sipm, dipm, spi, spim;
+ u16 sport, dport, spm, dpm;
+
+ sip = be32_to_cpu(fsp->h_u.tcp_ip4_spec.ip4src);
+ sipm = be32_to_cpu(fsp->m_u.tcp_ip4_spec.ip4src);
+ dip = be32_to_cpu(fsp->h_u.tcp_ip4_spec.ip4dst);
+ dipm = be32_to_cpu(fsp->m_u.tcp_ip4_spec.ip4dst);
+
+ tp->key[0] = class << TCAM_V4KEY0_CLASS_CODE_SHIFT;
+ tp->key_mask[0] = TCAM_V4KEY0_CLASS_CODE;
+ tp->key[1] = (u64)l2_rdc_tab << TCAM_V4KEY1_L2RDCNUM_SHIFT;
+ tp->key_mask[1] = TCAM_V4KEY1_L2RDCNUM;
+
+ tp->key[3] = (u64)sip << TCAM_V4KEY3_SADDR_SHIFT;
+ tp->key[3] |= dip;
+
+ tp->key_mask[3] = (u64)sipm << TCAM_V4KEY3_SADDR_SHIFT;
+ tp->key_mask[3] |= dipm;
+
+ tp->key[2] |= ((u64)fsp->h_u.tcp_ip4_spec.tos <<
+ TCAM_V4KEY2_TOS_SHIFT);
+ tp->key_mask[2] |= ((u64)fsp->m_u.tcp_ip4_spec.tos <<
+ TCAM_V4KEY2_TOS_SHIFT);
+ switch (fsp->flow_type) {
+ case TCP_V4_FLOW:
+ case UDP_V4_FLOW:
+ case SCTP_V4_FLOW:
+ sport = be16_to_cpu(fsp->h_u.tcp_ip4_spec.psrc);
+ spm = be16_to_cpu(fsp->m_u.tcp_ip4_spec.psrc);
+ dport = be16_to_cpu(fsp->h_u.tcp_ip4_spec.pdst);
+ dpm = be16_to_cpu(fsp->m_u.tcp_ip4_spec.pdst);
+
+ tp->key[2] |= (((u64)sport << 16) | dport);
+ tp->key_mask[2] |= (((u64)spm << 16) | dpm);
+ niu_ethflow_to_l3proto(fsp->flow_type, &pid);
+ break;
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ spi = be32_to_cpu(fsp->h_u.ah_ip4_spec.spi);
+ spim = be32_to_cpu(fsp->m_u.ah_ip4_spec.spi);
+
+ tp->key[2] |= spi;
+ tp->key_mask[2] |= spim;
+ niu_ethflow_to_l3proto(fsp->flow_type, &pid);
+ break;
+ case IP_USER_FLOW:
+ spi = be32_to_cpu(fsp->h_u.usr_ip4_spec.l4_4_bytes);
+ spim = be32_to_cpu(fsp->m_u.usr_ip4_spec.l4_4_bytes);
+
+ tp->key[2] |= spi;
+ tp->key_mask[2] |= spim;
+ pid = fsp->h_u.usr_ip4_spec.proto;
+ break;
+ default:
+ break;
+ }
+
+ tp->key[2] |= ((u64)pid << TCAM_V4KEY2_PROTO_SHIFT);
+ if (pid) {
+ tp->key_mask[2] |= TCAM_V4KEY2_PROTO;
+ }
+}
+
+static int niu_add_ethtool_tcam_entry(struct niu *np,
+ struct ethtool_rxnfc *nfc)
+{
+ struct niu_parent *parent = np->parent;
+ struct niu_tcam_entry *tp;
+ struct ethtool_rx_flow_spec *fsp = &nfc->fs;
+ struct niu_rdc_tables *rdc_table = &parent->rdc_group_cfg[np->port];
+ int l2_rdc_table = rdc_table->first_table_num;
+ u16 idx;
+ u64 class;
+ unsigned long flags;
+ int err, ret;
+
+ ret = 0;
+
+ idx = nfc->fs.location;
+ if (idx >= tcam_get_size(np))
+ return -EINVAL;
+
+ if (fsp->flow_type == IP_USER_FLOW) {
+ int i;
+ int add_usr_cls = 0;
+ int ipv6 = 0;
+ struct ethtool_usrip4_spec *uspec = &fsp->h_u.usr_ip4_spec;
+ struct ethtool_usrip4_spec *umask = &fsp->m_u.usr_ip4_spec;
+
+ niu_lock_parent(np, flags);
+
+ for (i = 0; i < NIU_L3_PROG_CLS; i++) {
+ if (parent->l3_cls[i]) {
+ if (uspec->proto == parent->l3_cls_pid[i]) {
+ class = parent->l3_cls[i];
+ parent->l3_cls_refcnt[i]++;
+ add_usr_cls = 1;
+ break;
+ }
+ } else {
+ /* Program new user IP class */
+ switch (i) {
+ case 0:
+ class = CLASS_CODE_USER_PROG1;
+ break;
+ case 1:
+ class = CLASS_CODE_USER_PROG2;
+ break;
+ case 2:
+ class = CLASS_CODE_USER_PROG3;
+ break;
+ case 3:
+ class = CLASS_CODE_USER_PROG4;
+ break;
+ default:
+ break;
+ }
+ if (uspec->ip_ver == ETH_RX_NFC_IP6)
+ ipv6 = 1;
+ ret = tcam_user_ip_class_set(np, class, ipv6,
+ uspec->proto,
+ uspec->tos,
+ umask->tos);
+ if (ret)
+ goto out;
+
+ ret = tcam_user_ip_class_enable(np, class, 1);
+ if (ret)
+ goto out;
+ parent->l3_cls[i] = class;
+ parent->l3_cls_pid[i] = uspec->proto;
+ parent->l3_cls_refcnt[i]++;
+ add_usr_cls = 1;
+ break;
+ }
+ }
+ if (!add_usr_cls) {
+ pr_info(PFX "niu%d: %s niu_add_ethtool_tcam_entry: "
+ "Could not find/insert class for pid %d\n",
+ parent->index, np->dev->name, uspec->proto);
+ ret = -EINVAL;
+ goto out;
+ }
+ niu_unlock_parent(np, flags);
+ } else {
+ if (!niu_ethflow_to_class(fsp->flow_type, &class)) {
+ return -EINVAL;
+ }
+ }
+
+ niu_lock_parent(np, flags);
+
+ idx = tcam_get_index(np, idx);
+ tp = &parent->tcam[idx];
+
+ memset(tp, 0, sizeof(*tp));
+
+ /* fill in the tcam key and mask */
+ switch (fsp->flow_type) {
+ case TCP_V4_FLOW:
+ case UDP_V4_FLOW:
+ case SCTP_V4_FLOW:
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ niu_get_tcamkey_from_ip4fs(fsp, tp, l2_rdc_table, class);
+ break;
+ case TCP_V6_FLOW:
+ case UDP_V6_FLOW:
+ case SCTP_V6_FLOW:
+ case AH_V6_FLOW:
+ case ESP_V6_FLOW:
+ /* Not yet implemented */
+ pr_info(PFX "niu%d: %s In niu_add_ethtool_tcam_entry: "
+ "flow %d for IPv6 not implemented\n\n",
+ parent->index, np->dev->name, fsp->flow_type);
+ ret = -EINVAL;
+ goto out;
+ case IP_USER_FLOW:
+ if (fsp->h_u.usr_ip4_spec.ip_ver == ETH_RX_NFC_IP4) {
+ niu_get_tcamkey_from_ip4fs(fsp, tp, l2_rdc_table,
+ class);
+ } else {
+ /* Not yet implemented */
+ pr_info(PFX "niu%d: %s In niu_add_ethtool_tcam_entry: "
+ "usr flow for IPv6 not implemented\n\n",
+ parent->index, np->dev->name);
+ ret = -EINVAL;
+ goto out;
+ }
+ break;
+ default:
+ pr_info(PFX "niu%d: %s In niu_add_ethtool_tcam_entry: "
+ "Unknown flow type %d\n\n",
+ parent->index, np->dev->name, fsp->flow_type);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* fill in the assoc data */
+ if (fsp->ring_cookie == RX_CLS_FLOW_DISC) {
+ tp->assoc_data = TCAM_ASSOCDATA_DISC;
+ } else {
+ if (fsp->ring_cookie >= np->num_rx_rings) {
+ pr_info(PFX "niu%d: %s In niu_add_ethtool_tcam_entry: "
+ "Invalid RX ring %lld\n\n",
+ parent->index, np->dev->name,
+ (long long) fsp->ring_cookie);
+ ret = -EINVAL;
+ goto out;
+ }
+ tp->assoc_data = (TCAM_ASSOCDATA_TRES_USE_OFFSET |
+ (fsp->ring_cookie <<
+ TCAM_ASSOCDATA_OFFSET_SHIFT));
+ }
+
+ err = tcam_write(np, idx, tp->key, tp->key_mask);
+ if (err) {
+ ret = -EINVAL;
+ goto out;
+ }
+ err = tcam_assoc_write(np, idx, tp->assoc_data);
+ if (err) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* validate the entry */
+ tp->valid = 1;
+ np->clas.tcam_valid_entries++;
+out:
+ niu_unlock_parent(np, flags);
+
+ return ret;
+}
+
+static int niu_del_ethtool_tcam_entry(struct niu *np, u32 loc)
+{
+ struct niu_parent *parent = np->parent;
+ struct niu_tcam_entry *tp;
+ u16 idx;
+ unsigned long flags;
+ u64 class;
+ int ret = 0;
+
+ if (loc >= tcam_get_size(np))
+ return -EINVAL;
+
+ niu_lock_parent(np, flags);
+
+ idx = tcam_get_index(np, loc);
+ tp = &parent->tcam[idx];
+
+ /* if the entry is of a user defined class, then update*/
+ class = (tp->key[0] & TCAM_V4KEY0_CLASS_CODE) >>
+ TCAM_V4KEY0_CLASS_CODE_SHIFT;
+
+ if (class >= CLASS_CODE_USER_PROG1 && class <= CLASS_CODE_USER_PROG4) {
+ int i;
+ for (i = 0; i < NIU_L3_PROG_CLS; i++) {
+ if (parent->l3_cls[i] == class) {
+ parent->l3_cls_refcnt[i]--;
+ if (!parent->l3_cls_refcnt[i]) {
+ /* disable class */
+ ret = tcam_user_ip_class_enable(np,
+ class,
+ 0);
+ if (ret)
+ goto out;
+ parent->l3_cls[i] = 0;
+ parent->l3_cls_pid[i] = 0;
+ }
+ break;
+ }
+ }
+ if (i == NIU_L3_PROG_CLS) {
+ pr_info(PFX "niu%d: %s In niu_del_ethtool_tcam_entry,"
+ "Usr class 0x%llx not found \n",
+ parent->index, np->dev->name,
+ (unsigned long long) class);
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+
+ ret = tcam_flush(np, idx);
+ if (ret)
+ goto out;
+
+ /* invalidate the entry */
+ tp->valid = 0;
+ np->clas.tcam_valid_entries--;
+out:
+ niu_unlock_parent(np, flags);
+
+ return ret;
+}
+
+static int niu_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+ struct niu *np = netdev_priv(dev);
+ int ret = 0;
+
+ switch (cmd->cmd) {
+ case ETHTOOL_SRXFH:
+ ret = niu_set_hash_opts(np, cmd);
+ break;
+ case ETHTOOL_SRXCLSRLINS:
+ ret = niu_add_ethtool_tcam_entry(np, cmd);
+ break;
+ case ETHTOOL_SRXCLSRLDEL:
+ ret = niu_del_ethtool_tcam_entry(np, cmd->fs.location);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
static const struct {
const char string[ETH_GSTRING_LEN];
} niu_xmac_stat_keys[] = {
@@ -7158,6 +7939,7 @@ static const struct ethtool_ops niu_ethtool_ops = {
.get_link = ethtool_op_get_link,
.get_msglevel = niu_get_msglevel,
.set_msglevel = niu_set_msglevel,
+ .nway_reset = niu_nway_reset,
.get_eeprom_len = niu_get_eeprom_len,
.get_eeprom = niu_get_eeprom,
.get_settings = niu_get_settings,
@@ -7166,8 +7948,8 @@ static const struct ethtool_ops niu_ethtool_ops = {
.get_stats_count = niu_get_stats_count,
.get_ethtool_stats = niu_get_ethtool_stats,
.phys_id = niu_phys_id,
- .get_rxhash = niu_get_hash_opts,
- .set_rxhash = niu_set_hash_opts,
+ .get_rxnfc = niu_get_nfc,
+ .set_rxnfc = niu_set_nfc,
};
static int niu_ldg_assign_ldn(struct niu *np, struct niu_parent *parent,
@@ -8237,7 +9019,8 @@ static int __devinit niu_classifier_swstate_init(struct niu *np)
niudbg(PROBE, "niu_classifier_swstate_init: num_tcam(%d)\n",
np->parent->tcam_num_entries);
- cp->tcam_index = (u16) np->port;
+ cp->tcam_top = (u16) np->port;
+ cp->tcam_sz = np->parent->tcam_num_entries / np->parent->num_ports;
cp->h1_init = 0xffffffff;
cp->h2_init = 0xffff;
@@ -8257,7 +9040,9 @@ static void __devinit niu_link_config_init(struct niu *np)
ADVERTISED_10000baseT_Full |
ADVERTISED_Autoneg);
lp->speed = lp->active_speed = SPEED_INVALID;
- lp->duplex = lp->active_duplex = DUPLEX_INVALID;
+ lp->duplex = DUPLEX_FULL;
+ lp->active_duplex = DUPLEX_INVALID;
+ lp->autoneg = 1;
#if 0
lp->loopback_mode = LOOPBACK_MAC;
lp->active_speed = SPEED_10000;
diff --git a/drivers/net/niu.h b/drivers/net/niu.h
index e1a7392e8d70..8754e44cadae 100644
--- a/drivers/net/niu.h
+++ b/drivers/net/niu.h
@@ -3004,7 +3004,9 @@ struct niu_classifier {
struct niu_altmac_rdc alt_mac_mappings[16];
struct niu_vlan_rdc vlan_mappings[ENET_VLAN_TBL_NUM_ENTRIES];
- u16 tcam_index;
+ u16 tcam_top;
+ u16 tcam_sz;
+ u16 tcam_valid_entries;
u16 num_alt_mac_mappings;
u32 h1_init;
@@ -3040,6 +3042,7 @@ struct phy_probe_info {
};
struct niu_tcam_entry {
+ u8 valid;
u64 key[4];
u64 key_mask[4];
u64 assoc_data;
@@ -3107,10 +3110,15 @@ struct niu_parent {
struct phy_probe_info phy_probe_info;
struct niu_tcam_entry tcam[NIU_TCAM_ENTRIES_MAX];
- u64 l2_cls[2];
- u64 l3_cls[4];
+
+#define NIU_L2_PROG_CLS 2
+#define NIU_L3_PROG_CLS 4
+ u64 l2_cls[NIU_L2_PROG_CLS];
+ u64 l3_cls[NIU_L3_PROG_CLS];
u64 tcam_key[12];
u64 flow_key[12];
+ u16 l3_cls_refcnt[NIU_L3_PROG_CLS];
+ u8 l3_cls_pid[NIU_L3_PROG_CLS];
};
struct niu_ops {
@@ -3131,16 +3139,19 @@ struct niu_ops {
};
struct niu_link_config {
+ u32 supported;
+
/* Describes what we're trying to get. */
u32 advertising;
- u32 supported;
u16 speed;
u8 duplex;
u8 autoneg;
/* Describes what we actually have. */
+ u32 active_advertising;
u16 active_speed;
u8 active_duplex;
+ u8 active_autoneg;
#define SPEED_INVALID 0xffff
#define DUPLEX_INVALID 0xff
#define AUTONEG_INVALID 0xff
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index e80294d8cc19..221b0c4c824a 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -409,7 +409,7 @@ static int lnksts = 0; /* CFG_LNKSTS bit polarity */
struct rx_info {
spinlock_t lock;
int up;
- long idle;
+ unsigned long idle;
struct sk_buff *skbs[NR_RX_DESC];
@@ -822,8 +822,7 @@ static void ns83820_cleanup_rx(struct ns83820 *dev)
struct sk_buff *skb = dev->rx_info.skbs[i];
dev->rx_info.skbs[i] = NULL;
clear_rx_desc(dev, i);
- if (skb)
- kfree_skb(skb);
+ kfree_skb(skb);
}
}
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index d0349e7d73ea..5eeb5a87b738 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -970,7 +970,7 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
if (*chan->status & PAS_STATUS_ERROR)
reg |= PAS_IOB_DMA_RXCH_RESET_DINTC;
- netif_rx_schedule(&mac->napi);
+ napi_schedule(&mac->napi);
write_iob_reg(PAS_IOB_DMA_RXCH_RESET(chan->chno), reg);
@@ -1010,7 +1010,7 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
mod_timer(&txring->clean_timer, jiffies + (TX_CLEAN_INTERVAL)*2);
- netif_rx_schedule(&mac->napi);
+ napi_schedule(&mac->napi);
if (reg)
write_iob_reg(PAS_IOB_DMA_TXCH_RESET(chan->chno), reg);
@@ -1639,7 +1639,7 @@ static int pasemi_mac_poll(struct napi_struct *napi, int budget)
pkts = pasemi_mac_clean_rx(rx_ring(mac), budget);
if (pkts < budget) {
/* all done, no more packets present */
- netif_rx_complete(napi);
+ napi_complete(napi);
pasemi_mac_restart_rx_intr(mac);
pasemi_mac_restart_tx_intr(mac);
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 2404a838b1fe..8f3872b8985d 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -257,6 +257,18 @@ static void tc574_detach(struct pcmcia_device *p_dev);
local data structures for one device. The device is registered
with Card Services.
*/
+static const struct net_device_ops el3_netdev_ops = {
+ .ndo_open = el3_open,
+ .ndo_stop = el3_close,
+ .ndo_start_xmit = el3_start_xmit,
+ .ndo_tx_timeout = el3_tx_timeout,
+ .ndo_get_stats = el3_get_stats,
+ .ndo_do_ioctl = el3_ioctl,
+ .ndo_set_multicast_list = set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
static int tc574_probe(struct pcmcia_device *link)
{
@@ -284,18 +296,9 @@ static int tc574_probe(struct pcmcia_device *link)
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
- /* The EL3-specific entries in the device structure. */
- dev->hard_start_xmit = &el3_start_xmit;
- dev->get_stats = &el3_get_stats;
- dev->do_ioctl = &el3_ioctl;
+ dev->netdev_ops = &el3_netdev_ops;
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- dev->set_multicast_list = &set_rx_mode;
- dev->open = &el3_open;
- dev->stop = &el3_close;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = el3_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
-#endif
return tc574_config(link);
} /* tc574_attach */
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 1e01b8a6dbf3..cdf661a6092c 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -169,6 +169,19 @@ static void tc589_detach(struct pcmcia_device *p_dev);
======================================================================*/
+static const struct net_device_ops el3_netdev_ops = {
+ .ndo_open = el3_open,
+ .ndo_stop = el3_close,
+ .ndo_start_xmit = el3_start_xmit,
+ .ndo_tx_timeout = el3_tx_timeout,
+ .ndo_set_config = el3_config,
+ .ndo_get_stats = el3_get_stats,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int tc589_probe(struct pcmcia_device *link)
{
struct el3_private *lp;
@@ -195,17 +208,9 @@ static int tc589_probe(struct pcmcia_device *link)
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
- /* The EL3-specific entries in the device structure. */
- dev->hard_start_xmit = &el3_start_xmit;
- dev->set_config = &el3_config;
- dev->get_stats = &el3_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->open = &el3_open;
- dev->stop = &el3_close;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = el3_tx_timeout;
+ dev->netdev_ops = &el3_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
-#endif
+
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
return tc589_config(link);
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 0afa72095810..501a8d7ac2be 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -35,6 +35,7 @@
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <linux/crc32.h>
#include "../8390.h"
@@ -91,6 +92,10 @@ static void axnet_release(struct pcmcia_device *link);
static int axnet_open(struct net_device *dev);
static int axnet_close(struct net_device *dev);
static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int axnet_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static struct net_device_stats *get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+static void axnet_tx_timeout(struct net_device *dev);
static const struct ethtool_ops netdev_ethtool_ops;
static irqreturn_t ei_irq_wrapper(int irq, void *dev_id);
static void ei_watchdog(u_long arg);
@@ -108,7 +113,6 @@ static void block_output(struct net_device *dev, int count,
static void axnet_detach(struct pcmcia_device *p_dev);
-static void axdev_setup(struct net_device *dev);
static void AX88190_init(struct net_device *dev, int startp);
static int ax_open(struct net_device *dev);
static int ax_close(struct net_device *dev);
@@ -134,6 +138,19 @@ static inline axnet_dev_t *PRIV(struct net_device *dev)
return p;
}
+static const struct net_device_ops axnet_netdev_ops = {
+ .ndo_open = axnet_open,
+ .ndo_stop = axnet_close,
+ .ndo_do_ioctl = axnet_ioctl,
+ .ndo_start_xmit = axnet_start_xmit,
+ .ndo_tx_timeout = axnet_tx_timeout,
+ .ndo_get_stats = get_stats,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*======================================================================
axnet_attach() creates an "instance" of the driver, allocating
@@ -146,15 +163,17 @@ static int axnet_probe(struct pcmcia_device *link)
{
axnet_dev_t *info;
struct net_device *dev;
+ struct ei_device *ei_local;
DEBUG(0, "axnet_attach()\n");
- dev = alloc_netdev(sizeof(struct ei_device) + sizeof(axnet_dev_t),
- "eth%d", axdev_setup);
-
+ dev = alloc_etherdev(sizeof(struct ei_device) + sizeof(axnet_dev_t));
if (!dev)
return -ENOMEM;
+ ei_local = netdev_priv(dev);
+ spin_lock_init(&ei_local->page_lock);
+
info = PRIV(dev);
info->p_dev = link;
link->priv = dev;
@@ -163,10 +182,10 @@ static int axnet_probe(struct pcmcia_device *link)
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
- dev->open = &axnet_open;
- dev->stop = &axnet_close;
- dev->do_ioctl = &axnet_ioctl;
+ dev->netdev_ops = &axnet_netdev_ops;
+
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+ dev->watchdog_timeo = TX_TIMEOUT;
return axnet_config(link);
} /* axnet_attach */
@@ -861,7 +880,7 @@ module_exit(exit_axnet_cs);
*/
-static const char *version_8390 =
+static const char version_8390[] = KERN_INFO \
"8390.c:v1.10cvs 9/23/94 Donald Becker (becker@scyld.com)\n";
#include <linux/bitops.h>
@@ -905,14 +924,12 @@ int ei_debug = 1;
/* Index to functions. */
static void ei_tx_intr(struct net_device *dev);
static void ei_tx_err(struct net_device *dev);
-static void axnet_tx_timeout(struct net_device *dev);
static void ei_receive(struct net_device *dev);
static void ei_rx_overrun(struct net_device *dev);
/* Routines generic to NS8390-based boards. */
static void NS8390_trigger_send(struct net_device *dev, unsigned int length,
int start_page);
-static void set_multicast_list(struct net_device *dev);
static void do_set_multicast_list(struct net_device *dev);
/*
@@ -954,15 +971,6 @@ static int ax_open(struct net_device *dev)
unsigned long flags;
struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
-#ifdef HAVE_TX_TIMEOUT
- /* The card I/O part of the driver (e.g. 3c503) can hook a Tx timeout
- wrapper that does e.g. media check & then calls axnet_tx_timeout. */
- if (dev->tx_timeout == NULL)
- dev->tx_timeout = axnet_tx_timeout;
- if (dev->watchdog_timeo <= 0)
- dev->watchdog_timeo = TX_TIMEOUT;
-#endif
-
/*
* Grab the page lock so we own the register set, then call
* the init function.
@@ -1701,30 +1709,6 @@ static void set_multicast_list(struct net_device *dev)
spin_unlock_irqrestore(&dev_lock(dev), flags);
}
-/**
- * axdev_setup - init rest of 8390 device struct
- * @dev: network device structure to init
- *
- * Initialize the rest of the 8390 device structure. Do NOT __init
- * this, as it is used by 8390 based modular drivers too.
- */
-
-static void axdev_setup(struct net_device *dev)
-{
- struct ei_device *ei_local;
- if (ei_debug > 1)
- printk(version_8390);
-
- ei_local = (struct ei_device *)netdev_priv(dev);
- spin_lock_init(&ei_local->page_lock);
-
- dev->hard_start_xmit = &axnet_start_xmit;
- dev->get_stats = get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- ether_setup(dev);
-}
-
/* This page of functions should be 8390 generic */
/* Follow National Semi's recommendations for initializing the "NIC". */
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 69dcfbbabe82..81e6660a433a 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -100,7 +100,6 @@ static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t fjn_interrupt(int irq, void *dev_id);
static void fjn_rx(struct net_device *dev);
static void fjn_reset(struct net_device *dev);
-static struct net_device_stats *fjn_get_stats(struct net_device *dev);
static void set_rx_mode(struct net_device *dev);
static void fjn_tx_timeout(struct net_device *dev);
static const struct ethtool_ops netdev_ethtool_ops;
@@ -118,7 +117,6 @@ typedef enum { MBH10302, MBH10304, TDK, CONTEC, LA501, UNGERMANN,
typedef struct local_info_t {
struct pcmcia_device *p_dev;
dev_node_t node;
- struct net_device_stats stats;
long open_time;
uint tx_started:1;
uint tx_queue;
@@ -229,6 +227,18 @@ typedef struct local_info_t {
#define BANK_1U 0x24 /* bank 1 (CONFIG_1) */
#define BANK_2U 0x28 /* bank 2 (CONFIG_1) */
+static const struct net_device_ops fjn_netdev_ops = {
+ .ndo_open = fjn_open,
+ .ndo_stop = fjn_close,
+ .ndo_start_xmit = fjn_start_xmit,
+ .ndo_tx_timeout = fjn_tx_timeout,
+ .ndo_set_config = fjn_config,
+ .ndo_set_multicast_list = set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int fmvj18x_probe(struct pcmcia_device *link)
{
local_info_t *lp;
@@ -260,17 +270,9 @@ static int fmvj18x_probe(struct pcmcia_device *link)
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
- /* The FMVJ18x specific entries in the device structure. */
- dev->hard_start_xmit = &fjn_start_xmit;
- dev->set_config = &fjn_config;
- dev->get_stats = &fjn_get_stats;
- dev->set_multicast_list = &set_rx_mode;
- dev->open = &fjn_open;
- dev->stop = &fjn_close;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = fjn_tx_timeout;
+ dev->netdev_ops = &fjn_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
-#endif
+
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
return fmvj18x_config(link);
@@ -793,7 +795,7 @@ static irqreturn_t fjn_interrupt(int dummy, void *dev_id)
fjn_rx(dev);
}
if (tx_stat & F_TMT_RDY) {
- lp->stats.tx_packets += lp->sent ;
+ dev->stats.tx_packets += lp->sent ;
lp->sent = 0 ;
if (lp->tx_queue) {
outb(DO_TX | lp->tx_queue, ioaddr + TX_START);
@@ -840,7 +842,7 @@ static void fjn_tx_timeout(struct net_device *dev)
htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)),
htons(inw(ioaddr +10)), htons(inw(ioaddr +12)),
htons(inw(ioaddr +14)));
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
/* ToDo: We should try to restart the adaptor... */
local_irq_disable();
fjn_reset(dev);
@@ -880,7 +882,7 @@ static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev)
DEBUG(4, "%s: Transmitting a packet of length %lu.\n",
dev->name, (unsigned long)skb->len);
- lp->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
/* Disable both interrupts. */
outw(0x0000, ioaddr + TX_INTR);
@@ -1008,7 +1010,6 @@ static void fjn_reset(struct net_device *dev)
static void fjn_rx(struct net_device *dev)
{
- struct local_info_t *lp = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
int boguscount = 10; /* 5 -> 10: by agy 19940922 */
@@ -1027,11 +1028,11 @@ static void fjn_rx(struct net_device *dev)
}
#endif
if ((status & 0xF0) != 0x20) { /* There was an error. */
- lp->stats.rx_errors++;
- if (status & F_LEN_ERR) lp->stats.rx_length_errors++;
- if (status & F_ALG_ERR) lp->stats.rx_frame_errors++;
- if (status & F_CRC_ERR) lp->stats.rx_crc_errors++;
- if (status & F_OVR_FLO) lp->stats.rx_over_errors++;
+ dev->stats.rx_errors++;
+ if (status & F_LEN_ERR) dev->stats.rx_length_errors++;
+ if (status & F_ALG_ERR) dev->stats.rx_frame_errors++;
+ if (status & F_CRC_ERR) dev->stats.rx_crc_errors++;
+ if (status & F_OVR_FLO) dev->stats.rx_over_errors++;
} else {
u_short pkt_len = inw(ioaddr + DATAPORT);
/* Malloc up new buffer. */
@@ -1041,7 +1042,7 @@ static void fjn_rx(struct net_device *dev)
printk(KERN_NOTICE "%s: The FMV-18x claimed a very "
"large packet, size %d.\n", dev->name, pkt_len);
outb(F_SKP_PKT, ioaddr + RX_SKIP);
- lp->stats.rx_errors++;
+ dev->stats.rx_errors++;
break;
}
skb = dev_alloc_skb(pkt_len+2);
@@ -1049,7 +1050,7 @@ static void fjn_rx(struct net_device *dev)
printk(KERN_NOTICE "%s: Memory squeeze, dropping "
"packet (len %d).\n", dev->name, pkt_len);
outb(F_SKP_PKT, ioaddr + RX_SKIP);
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
break;
}
@@ -1070,8 +1071,8 @@ static void fjn_rx(struct net_device *dev)
#endif
netif_rx(skb);
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += pkt_len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
}
if (--boguscount <= 0)
break;
@@ -1191,14 +1192,6 @@ static int fjn_close(struct net_device *dev)
/*====================================================================*/
-static struct net_device_stats *fjn_get_stats(struct net_device *dev)
-{
- local_info_t *lp = netdev_priv(dev);
- return &lp->stats;
-} /* fjn_get_stats */
-
-/*====================================================================*/
-
/*
Set the multicast/promiscuous mode for this adaptor.
*/
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index ec7c588c9ae5..02ef63ed1f99 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -436,6 +436,19 @@ static const struct ethtool_ops netdev_ethtool_ops;
static void nmclan_detach(struct pcmcia_device *p_dev);
+static const struct net_device_ops mace_netdev_ops = {
+ .ndo_open = mace_open,
+ .ndo_stop = mace_close,
+ .ndo_start_xmit = mace_start_xmit,
+ .ndo_tx_timeout = mace_tx_timeout,
+ .ndo_set_config = mace_config,
+ .ndo_get_stats = mace_get_stats,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/* ----------------------------------------------------------------------------
nmclan_attach
Creates an "instance" of the driver, allocating local data
@@ -474,17 +487,9 @@ static int nmclan_probe(struct pcmcia_device *link)
lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
- dev->hard_start_xmit = &mace_start_xmit;
- dev->set_config = &mace_config;
- dev->get_stats = &mace_get_stats;
- dev->set_multicast_list = &set_multicast_list;
+ dev->netdev_ops = &mace_netdev_ops;
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- dev->open = &mace_open;
- dev->stop = &mace_close;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = mace_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
-#endif
return nmclan_config(link);
} /* nmclan_attach */
diff --git a/drivers/net/pcmcia/ositech.h b/drivers/net/pcmcia/ositech.h
deleted file mode 100644
index 4126efc355bd..000000000000
--- a/drivers/net/pcmcia/ositech.h
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- This file contains the firmware of Seven of Diamonds from OSITECH.
- (Special thanks to Kevin MacPherson of OSITECH)
-
- This software may be used and distributed according to the terms of
- the GNU General Public License, incorporated herein by reference.
-*/
-
- static const u_char __Xilinx7OD[] = {
- 0xFF, 0x04, 0xA0, 0x36, 0xF3, 0xEC, 0xFF, 0xFF, 0xFF, 0xDF, 0xFB, 0xFF,
- 0xF3, 0xFF, 0xFF, 0xFF,
- 0xEF, 0x3F, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7F, 0xFE, 0xFF,
- 0xCE, 0xFE, 0xFE, 0xFE,
- 0xFE, 0xDE, 0xBD, 0xDD, 0xFD, 0xFF, 0xFD, 0xCF, 0xF7, 0xBF, 0x7F, 0xFF,
- 0x7F, 0x3F, 0xFE, 0xBF,
- 0xFF, 0xFF, 0xFF, 0xBC, 0xFF, 0xFF, 0xBD, 0xB5, 0x7F, 0x7F, 0xBF, 0xBF,
- 0x7F, 0xFF, 0xEF, 0xFF,
- 0xFF, 0xFF, 0xFB, 0xFF, 0xF7, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xDE,
- 0xFE, 0xFE, 0xFA, 0xDE,
- 0xBD, 0xFD, 0xED, 0xFD, 0xFD, 0xCF, 0xEF, 0xEF, 0xEF, 0xEF, 0xC7, 0xDF,
- 0xDF, 0xDF, 0xDF, 0xDF,
- 0xFF, 0x7E, 0xFE, 0xFD, 0x7D, 0x6D, 0xEE, 0xFE, 0x7C, 0xFB, 0xF4, 0xFB,
- 0xCF, 0xDB, 0xDF, 0xFF,
- 0xFF, 0xBB, 0x7F, 0xFF, 0x7F, 0xFF, 0xF7, 0xFF, 0x9E, 0xBF, 0x3B, 0xBF,
- 0xBF, 0x7F, 0x7F, 0x7F,
- 0x7E, 0x6F, 0xDF, 0xEF, 0xF5, 0xF6, 0xFD, 0xF6, 0xF5, 0xED, 0xEB, 0xFF,
- 0xEF, 0xEF, 0xEF, 0x7E,
- 0x7F, 0x7F, 0x6F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xEF, 0xBF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0x1F, 0x1F, 0xEE, 0xFF, 0xBC,
- 0xB7, 0xFF, 0xDF, 0xFF,
- 0xDF, 0xEF, 0x3B, 0xE3, 0xD3, 0xFF, 0xFB, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF,
- 0xFF, 0xBA, 0xBF, 0x2D,
- 0xDB, 0xBD, 0xFD, 0xDB, 0xDF, 0xFA, 0xFB, 0xFF, 0xEF, 0xFB, 0xDB, 0xF3,
- 0xFF, 0xDF, 0xFD, 0x7F,
- 0xEF, 0xFB, 0xFF, 0xFF, 0xBE, 0xBF, 0x27, 0xBA, 0xFE, 0xFB, 0xDF, 0xFF,
- 0xF6, 0xFF, 0xFF, 0xEF,
- 0xFB, 0xDB, 0xF3, 0xD9, 0x9A, 0x3F, 0xFF, 0xAF, 0xBF, 0xFF, 0xFF, 0xBE,
- 0x3F, 0x37, 0xBD, 0x96,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAE, 0xFB, 0xF3, 0xF3, 0xEB, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xF7, 0xFA, 0xBC, 0xAE, 0xFE, 0xBE, 0xFE, 0xBB, 0x7F, 0xFD, 0xFF,
- 0x7F, 0xEF, 0xF7, 0xFB,
- 0xBB, 0xD7, 0xF7, 0x7F, 0xFF, 0xF7, 0xFF, 0xFF, 0xF7, 0xBC, 0xED, 0xFD,
- 0xBD, 0x9D, 0x7D, 0x7B,
- 0xFB, 0x7B, 0x7B, 0xFB, 0xAF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xF7,
- 0xAA, 0xB9, 0xBF, 0x8F, 0xBF, 0xDF, 0xFF, 0x7F, 0xFF, 0xFF, 0x7F, 0xCF,
- 0xFB, 0xEB, 0xCB, 0xEB,
- 0xEE, 0xFF, 0xFF, 0xD7, 0xFF, 0xFF, 0xFF, 0x3E, 0x33, 0x3F, 0x1C, 0x7C,
- 0xFC, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xCF, 0xD3, 0xF3, 0xE3, 0xF3, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xEB, 0xFE, 0x35,
- 0x3F, 0x3D, 0xFD, 0xFD, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xEF, 0x6F, 0xE3,
- 0xE3, 0xE3, 0xEF, 0xFF,
- 0xFF, 0xDF, 0xFF, 0xFF, 0xF7, 0xFE, 0x3E, 0x5E, 0xFE, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFD, 0xFF, 0xFF,
- 0xAF, 0xCF, 0xF2, 0xCB, 0xCF, 0x8E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD,
- 0xFC, 0x3E, 0x1F, 0x9E,
- 0xAD, 0xFD, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xEF, 0xFF, 0xB3, 0xF7, 0xE7,
- 0xF7, 0xFA, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xEE, 0xEB, 0xAB, 0xAF, 0x9F, 0xE3, 0x7F, 0xFF, 0xDE,
- 0xFF, 0x7F, 0xEE, 0xFF,
- 0xFF, 0xFB, 0x3A, 0xFA, 0xFF, 0xF2, 0x77, 0xFF, 0xFF, 0xF7, 0xFE, 0xFF,
- 0xFE, 0xBD, 0xAE, 0xDE,
- 0x7D, 0x7D, 0xFD, 0xFF, 0xBF, 0xEE, 0xFF, 0xFD, 0xFF, 0xDB, 0xFB, 0xFF,
- 0xF7, 0xEF, 0xFB, 0xFF,
- 0xFF, 0xFE, 0xFF, 0x2D, 0xAF, 0xB9, 0xFD, 0x79, 0xFB, 0xFA, 0xFF, 0xBF,
- 0xEF, 0xFF, 0xFF, 0x91,
- 0xFA, 0xFB, 0xDF, 0xF7, 0xF7, 0xFF, 0xFF, 0xFF, 0xFC, 0xCF, 0x37, 0xBF,
- 0xBF, 0xFF, 0x7F, 0x7F,
- 0xFF, 0xFF, 0xFF, 0xAF, 0xFF, 0xFF, 0xF3, 0xFB, 0xFB, 0xFF, 0xF5, 0xEF,
- 0xFF, 0xFF, 0xF7, 0xFA,
- 0xFF, 0xFF, 0xEE, 0xFA, 0xFE, 0xFB, 0x55, 0xDD, 0xFF, 0x7F, 0xAF, 0xFE,
- 0xFF, 0xFB, 0xFB, 0xF5,
- 0xFF, 0xF7, 0xEF, 0xFF, 0xFF, 0xFF, 0xBE, 0xBD, 0xBD, 0xBD, 0xBD, 0x7D,
- 0x7B, 0x7B, 0x7B, 0x7B,
- 0xFB, 0xAE, 0xFF, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xF7, 0xDA, 0xB7, 0x61,
- 0xFF, 0xB9, 0x59, 0xF3, 0x73, 0xF3, 0xDF, 0x7F, 0x6F, 0xDF, 0xEF, 0xF7,
- 0xEB, 0xEB, 0xD7, 0xFF,
- 0xD7, 0xFF, 0xFF, 0xF7, 0xFE, 0x7F, 0xFB, 0x3E, 0x38, 0x73, 0xF6, 0x7F,
- 0xFC, 0xFF, 0xFF, 0xCF,
- 0xFF, 0xB7, 0xFB, 0xB3, 0xB3, 0x67, 0xFF, 0xE7, 0xFD, 0xFF, 0xEF, 0xF6,
- 0x7F, 0xB7, 0xBC, 0xF5,
- 0x7B, 0xF6, 0xF7, 0xF5, 0xFF, 0xFF, 0xEF, 0xFF, 0xF7, 0xFF, 0xF7, 0xCE,
- 0xE7, 0xFF, 0x9F, 0xFF,
- 0xFF, 0xF5, 0xFE, 0x7D, 0xFF, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xEF, 0xFF, 0xF6,
- 0xCB, 0xDB, 0xEE, 0xFE, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xBE,
- 0x1E, 0x3E, 0xFE, 0xFF,
- 0x7D, 0xFE, 0xFF, 0xFF, 0xEF, 0xBF, 0xE7, 0xFF, 0xE3, 0xE3, 0xFF, 0xDF,
- 0xE7, 0xFF, 0xFF, 0xFF,
- 0xB8, 0xEF, 0xB7, 0x2F, 0xEE, 0xFF, 0xDF, 0xFF, 0xBF, 0xFF, 0x7F, 0xEF,
- 0xEB, 0xBF, 0xA3, 0xD3,
- 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xBE, 0xFD, 0x3F, 0xCF, 0xFD,
- 0xFB, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xAF, 0xFB, 0xBF, 0xBB, 0xBF, 0xDB, 0xFD, 0xFB, 0xFF, 0xFF,
- 0xFF, 0xFF, 0x3E, 0xFE,
- 0x3F, 0xBA, 0xBA, 0xFE, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xEF, 0xC3, 0x7F,
- 0xB2, 0x9B, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0x3C, 0xFF, 0x3F, 0x3C, 0xFF, 0xFE, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xAF, 0xF3, 0xFE, 0xF3, 0xE3, 0xEB, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xF7,
- 0x9A, 0xFE, 0xAF, 0x9E,
- 0xBE, 0xFE, 0xFF, 0xDF, 0xFF, 0xFF, 0x7B, 0xEF, 0xF7, 0xBF, 0xFB, 0xFB,
- 0xFB, 0xFF, 0xFF, 0x7F,
- 0xFF, 0xFF, 0xFF, 0xBC, 0xBD, 0xFD, 0xBD, 0xDD, 0x7D, 0x7B, 0x7B, 0x7B,
- 0x7B, 0xFB, 0xAE, 0xFF,
- 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xF7, 0x9A, 0xFF,
- 0x9F, 0xFF, 0xAF, 0xEF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xCF, 0xF3, 0xFF, 0xEB, 0xFF, 0xEB, 0xFF,
- 0xFF, 0xBF, 0xFF, 0xFF,
- 0xEF, 0xFE, 0xFF, 0x37, 0xFC, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xCF, 0xEF, 0xFD, 0xF3,
- 0xFF, 0xEE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6E, 0xFD, 0x2F, 0xFD,
- 0xFF, 0xFD, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xEF, 0xCF, 0xFF, 0xF3, 0xBF, 0x69, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFE,
- 0xFB, 0x9F, 0xFF, 0xBF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x87,
- 0xFE, 0xDA, 0xEF, 0xCF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xEF, 0xBF, 0xEF, 0xEF, 0xFD,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xEF, 0xFD, 0xFF, 0x7B, 0xFF, 0xEB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xEB, 0xF8, 0xFF, 0xEF,
- 0xAF, 0xFF, 0xFF, 0xBD, 0xFF, 0xFF, 0xFF, 0x7F, 0xEE, 0x7F, 0xEF, 0xFF,
- 0xBB, 0xFF, 0xBF, 0xFB,
- 0xFF, 0xFF, 0xFF, 0xF7, 0xF6, 0xFB, 0xBD, 0xFD, 0xDD, 0xF5, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xAF,
- 0xFF, 0x5F, 0xF5, 0xDF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6,
- 0xF3, 0xFF, 0xDE, 0xFE,
- 0xEF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xDE, 0xDF, 0x5F, 0xDF,
- 0xFD, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xAF, 0xFF, 0xFF,
- 0xEF, 0xED, 0xFF, 0xDF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xDA, 0xBD, 0xBE,
- 0xAE, 0xFE, 0x7F, 0xFD,
- 0xDF, 0xFF, 0xFF, 0x7F, 0xEF, 0xFF, 0xFB, 0xFB, 0xFB, 0x7F, 0xF7, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xF7,
- 0xBC, 0xFD, 0xBD, 0xBD, 0xBD, 0xFD, 0x7B, 0x7B, 0x7B, 0x7B, 0xFB, 0xAE,
- 0xFF, 0xFF, 0xFD, 0xFF,
- 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x9F, 0xBF, 0xBF, 0xCF,
- 0x7F, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xAF, 0xFF, 0xEB, 0xEB, 0xEB, 0xFF, 0xD7, 0xFE, 0xFF, 0xFF,
- 0xBF, 0xE7, 0xFE, 0xBF,
- 0x7F, 0xFC, 0xFF, 0xFF, 0xED, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0xFF, 0xFB,
- 0xFB, 0xFF, 0xFF, 0xDD,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBD, 0xDF, 0x9D, 0xFD, 0xDF, 0xB9,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xEF, 0xFF, 0xFB, 0xEF, 0xEB, 0xFF, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xF6, 0x9F, 0xFF, 0xFC,
- 0xFE, 0xFB, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xDF, 0xFA, 0xCD, 0xCF,
- 0xBF, 0x9F, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xF7, 0xFE, 0xBF, 0xFF, 0xDF, 0xEF, 0x5F, 0xFF, 0xFF, 0xFF,
- 0xFF, 0x7F, 0x6F, 0xFF,
- 0xBB, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0xFF,
- 0x5F, 0xFF, 0xBF, 0xBF,
- 0xF9, 0xFF, 0xFF, 0xFF, 0x7F, 0x6E, 0x7B, 0xFF, 0xEF, 0xFD, 0xEB, 0xDF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xF7, 0xB6, 0x3E, 0xFC, 0xFD, 0xBF, 0x7E, 0xFB, 0xFF, 0xFF, 0xFF, 0xF7,
- 0xEF, 0xF7, 0xF3, 0xF7,
- 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6E, 0x35, 0x79, 0xFF,
- 0xBF, 0xFC, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xEF, 0xFB, 0x53, 0xDF, 0xFF, 0xEB, 0xBF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xBC,
- 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xAF, 0xF5,
- 0xFF, 0xF7, 0xFF, 0xFB,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA, 0xAA, 0xEE, 0xFE, 0x3F, 0x7D,
- 0xFD, 0xFF, 0xFF, 0xFF,
- 0x7F, 0xAF, 0x77, 0xFB, 0xFB, 0xFF, 0xFB, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xF7, 0xBE, 0xBD, 0xBD,
- 0xBD, 0xBD, 0xFD, 0x7B, 0x7B, 0x7B, 0x7B, 0xFB, 0xAE, 0xFF, 0xEF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFC,
- 0xFF, 0xFF, 0xFF, 0xFF, 0x9A, 0xD9, 0xB8, 0xFF, 0xFF, 0x79, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xCF,
- 0xFB, 0xFF, 0xEB, 0xFF, 0xEB, 0xD7, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xDE,
- 0xF8, 0xFB, 0xFE, 0x3F,
- 0xFB, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xAD, 0xBF, 0xFA, 0xFF, 0x73,
- 0xDF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0x3A, 0xF5, 0xB7, 0xFC, 0x3F, 0xF9, 0xFD, 0xFF, 0xFF, 0xFF,
- 0x7F, 0xEF, 0xF3, 0xFF,
- 0xBF, 0xFE, 0xF3, 0x9F, 0xFE, 0xFF, 0xFF, 0xFF, 0xF7, 0x3E, 0xFF, 0xFF,
- 0xFF, 0xBF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xAF, 0xD3, 0xFE, 0xDB, 0xFF, 0xDB, 0xDF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0x3E, 0xFF, 0xBF, 0xFF, 0x7F, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F,
- 0xF3, 0xFF, 0xED, 0xFF,
- 0xF7, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xF6, 0x3C, 0xFE, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0x9F, 0xEF, 0xEF, 0xD1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0x7E, 0xBF,
- 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBB, 0xEF, 0xDF, 0xF1,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE, 0x3E, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xBF,
- 0xEF, 0xFD, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF,
- 0xFC, 0x3E, 0xFE, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2E, 0xEF, 0xF3, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xF7, 0xBA, 0xBE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0x7F, 0xAF, 0xFB,
- 0xFB, 0xFD, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xF2, 0xD6, 0xED,
- 0xBD, 0xBD, 0xBD, 0x7D,
- 0x7B, 0x7B, 0x7B, 0x7B, 0xFB, 0xAF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0x92, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F,
- 0xAF, 0xEB, 0xEB, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFE, 0x2E, 0xFE, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0x4F, 0xEF, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFE,
- 0x3C, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xCE,
- 0xC3, 0xFD, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x5D, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xEF, 0xCF, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xF7, 0xEE, 0x3E, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xEF, 0xDF, 0xE2, 0xFF,
- 0xFF, 0xFF, 0xFB, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0xBE, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0x7F, 0xEE,
- 0x5F, 0xE6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E,
- 0x7D, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xF3, 0xFB, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xBF, 0xF7, 0x36, 0xBE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xEF, 0xD3, 0xF6,
- 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xEE,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xAF, 0xEF, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xBA, 0xBE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEE,
- 0xFB, 0xFA, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xD6, 0xFD, 0xBD, 0xBD, 0xBD,
- 0x7D, 0x7B, 0x7B, 0x7B,
- 0x7B, 0xFB, 0xAE, 0xFF, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xF7, 0xBA, 0xBF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xEF, 0xEB, 0x6B,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFE, 0xBE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0x4F, 0xEF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF,
- 0x3E, 0x6E, 0xFC, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xC3, 0xC9, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0x3E, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xEF, 0xFB,
- 0xD5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE,
- 0xFE, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x6F, 0xEF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFB,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xF6, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE,
- 0xEF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFE, 0xFF, 0xF7, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0x7F, 0xFA, 0xEF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xE7, 0xFF, 0xFE,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xEF, 0xBF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xA7, 0xFF, 0xFC, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0x7F,
- 0xFE, 0xAE, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7,
- 0xF7, 0xFA, 0xFF, 0xFD,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xAF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xF7, 0xBE, 0xBD, 0xBD, 0xBD, 0xBD, 0x7D, 0x7B, 0x7B,
- 0x7B, 0x7B, 0xFB, 0xAF,
- 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCA,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xE7, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xCF, 0xFE, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xDF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xE7, 0xF2, 0xFC,
- 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xAE, 0xEF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x7E, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF,
- 0xFE, 0xFE, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xEF, 0xDD, 0xFE, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xAF, 0xEF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBA, 0xFE,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFA, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xF6, 0x9C, 0xBD, 0xBD, 0xBD, 0xBD, 0x7D, 0x7B, 0x7B, 0x7B, 0x7B, 0xFB,
- 0xAE, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0x7A, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xDF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0x6F, 0xEF, 0xF7, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xF7, 0xFE,
- 0xFE, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xEB,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x9E, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xEF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFE, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xEF, 0xCB, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFD,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xEF,
- 0xEF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFB, 0xAF, 0x7F, 0xFF,
- 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xEF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xBF, 0xFF,
- 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAE,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFA, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0x7F, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xF7, 0xBC, 0xBD,
- 0xBD, 0xBD, 0xBD, 0x7D, 0x7B, 0x7B, 0x7B, 0x7B, 0xFB, 0xAF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0x7F,
- 0xAF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF,
- 0xFE, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF,
- 0xFF, 0xFF, 0xEF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xBF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xEF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFE, 0xFF, 0x9F, 0x9F,
- 0x9F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0xFF, 0xEF, 0xDF, 0xDF, 0xDF, 0xDF, 0xCF, 0xB7, 0xBF, 0xBF,
- 0xBF, 0xBF, 0xFF, 0xBC,
- 0xB9, 0x9D, 0xBD, 0xBD, 0x7D, 0x7B, 0x7B, 0x7B, 0x7B, 0xFB, 0xEF, 0xD7,
- 0xF5, 0xF3, 0xF1, 0xD1,
- 0x65, 0xE3, 0xE3, 0xE3, 0xA3, 0xFF, 0xFE, 0x7F, 0xFE, 0xDE, 0xDE, 0xFF,
- 0xBD, 0xBD, 0xBD, 0xBD,
- 0xDF, 0xEF, 0xFB, 0xF7, 0xF3, 0xF3, 0xF3, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
- 0xFB, 0xFE, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-
- };
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index a6999403f37b..2fbf9f9ddd37 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -39,6 +39,7 @@
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/log2.h>
+#include <linux/etherdevice.h>
#include "../8390.h"
#include <pcmcia/cs_types.h>
@@ -233,6 +234,23 @@ static inline pcnet_dev_t *PRIV(struct net_device *dev)
return (pcnet_dev_t *)(p + sizeof(struct ei_device));
}
+static const struct net_device_ops pcnet_netdev_ops = {
+ .ndo_open = pcnet_open,
+ .ndo_stop = pcnet_close,
+ .ndo_set_config = set_config,
+ .ndo_start_xmit = ei_start_xmit,
+ .ndo_get_stats = ei_get_stats,
+ .ndo_do_ioctl = ei_ioctl,
+ .ndo_set_multicast_list = ei_set_multicast_list,
+ .ndo_tx_timeout = ei_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ei_poll,
+#endif
+};
+
/*======================================================================
pcnet_attach() creates an "instance" of the driver, allocating
@@ -260,9 +278,7 @@ static int pcnet_probe(struct pcmcia_device *link)
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
- dev->open = &pcnet_open;
- dev->stop = &pcnet_close;
- dev->set_config = &set_config;
+ dev->netdev_ops = &pcnet_netdev_ops;
return pcnet_config(link);
} /* pcnet_attach */
@@ -640,18 +656,12 @@ static int pcnet_config(struct pcmcia_device *link)
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- if (info->flags & (IS_DL10019|IS_DL10022)) {
- dev->do_ioctl = &ei_ioctl;
+ if (info->flags & (IS_DL10019|IS_DL10022))
mii_phy_probe(dev);
- }
link->dev_node = &info->node;
SET_NETDEV_DEV(dev, &handle_to_dev(link));
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
-#endif
-
if (register_netdev(dev) != 0) {
printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
link->dev_node = NULL;
@@ -1183,6 +1193,10 @@ static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
pcnet_dev_t *info = PRIV(dev);
u16 *data = (u16 *)&rq->ifr_ifru;
unsigned int mii_addr = dev->base_addr + DLINK_GPIO;
+
+ if (!(info->flags & (IS_DL10019|IS_DL10022)))
+ return -EINVAL;
+
switch (cmd) {
case SIOCGMIIPHY:
data[0] = info->phy_id;
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index fccd53ef3c64..48dbb35747d8 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -42,6 +42,7 @@
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/jiffies.h>
+#include <linux/firmware.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
@@ -55,17 +56,18 @@
#include <asm/system.h>
#include <asm/uaccess.h>
-/* Ositech Seven of Diamonds firmware */
-#include "ositech.h"
-
/*====================================================================*/
static const char *if_names[] = { "auto", "10baseT", "10base2"};
+/* Firmware name */
+#define FIRMWARE_NAME "ositech/Xilinx7OD.bin"
+
/* Module parameters */
MODULE_DESCRIPTION("SMC 91c92 series PCMCIA ethernet driver");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FIRMWARE_NAME);
#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
@@ -108,7 +110,7 @@ struct smc_private {
spinlock_t lock;
u_short manfid;
u_short cardid;
- struct net_device_stats stats;
+
dev_node_t node;
struct sk_buff *saved_skb;
int packets_waiting;
@@ -289,7 +291,6 @@ static void smc_tx_timeout(struct net_device *dev);
static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t smc_interrupt(int irq, void *dev_id);
static void smc_rx(struct net_device *dev);
-static struct net_device_stats *smc_get_stats(struct net_device *dev);
static void set_rx_mode(struct net_device *dev);
static int s9k_config(struct net_device *dev, struct ifmap *map);
static void smc_set_xcvr(struct net_device *dev, int if_port);
@@ -301,6 +302,19 @@ static void mdio_write(struct net_device *dev, int phy_id, int loc, int value);
static int smc_link_ok(struct net_device *dev);
static const struct ethtool_ops ethtool_ops;
+static const struct net_device_ops smc_netdev_ops = {
+ .ndo_open = smc_open,
+ .ndo_stop = smc_close,
+ .ndo_start_xmit = smc_start_xmit,
+ .ndo_tx_timeout = smc_tx_timeout,
+ .ndo_set_config = s9k_config,
+ .ndo_set_multicast_list = set_rx_mode,
+ .ndo_do_ioctl = &smc_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*======================================================================
smc91c92_attach() creates an "instance" of the driver, allocating
@@ -336,18 +350,9 @@ static int smc91c92_probe(struct pcmcia_device *link)
link->conf.IntType = INT_MEMORY_AND_IO;
/* The SMC91c92-specific entries in the device structure. */
- dev->hard_start_xmit = &smc_start_xmit;
- dev->get_stats = &smc_get_stats;
- dev->set_config = &s9k_config;
- dev->set_multicast_list = &set_rx_mode;
- dev->open = &smc_open;
- dev->stop = &smc_close;
- dev->do_ioctl = &smc_ioctl;
+ dev->netdev_ops = &smc_netdev_ops;
SET_ETHTOOL_OPS(dev, &ethtool_ops);
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = smc_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
-#endif
smc->mii_if.dev = dev;
smc->mii_if.mdio_read = mdio_read;
@@ -768,6 +773,26 @@ static int osi_config(struct pcmcia_device *link)
return i;
}
+static int osi_load_firmware(struct pcmcia_device *link)
+{
+ const struct firmware *fw;
+ int i, err;
+
+ err = request_firmware(&fw, FIRMWARE_NAME, &link->dev);
+ if (err) {
+ pr_err("Failed to load firmware \"%s\"\n", FIRMWARE_NAME);
+ return err;
+ }
+
+ /* Download the Seven of Diamonds firmware */
+ for (i = 0; i < fw->size; i++) {
+ outb(fw->data[i], link->io.BasePort1 + 2);
+ udelay(50);
+ }
+ release_firmware(fw);
+ return err;
+}
+
static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
{
struct net_device *dev = link->priv;
@@ -808,11 +833,9 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
(cardid == PRODID_OSITECH_SEVEN)) ||
((manfid == MANFID_PSION) &&
(cardid == PRODID_PSION_NET100))) {
- /* Download the Seven of Diamonds firmware */
- for (i = 0; i < sizeof(__Xilinx7OD); i++) {
- outb(__Xilinx7OD[i], link->io.BasePort1+2);
- udelay(50);
- }
+ rc = osi_load_firmware(link);
+ if (rc)
+ goto free_cfg_mem;
} else if (manfid == MANFID_OSITECH) {
/* Make sure both functions are powered up */
set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
@@ -859,10 +882,10 @@ static int smc91c92_resume(struct pcmcia_device *link)
(smc->cardid == PRODID_OSITECH_SEVEN)) ||
((smc->manfid == MANFID_PSION) &&
(smc->cardid == PRODID_PSION_NET100))) {
- /* Download the Seven of Diamonds firmware */
- for (i = 0; i < sizeof(__Xilinx7OD); i++) {
- outb(__Xilinx7OD[i], link->io.BasePort1+2);
- udelay(50);
+ i = osi_load_firmware(link);
+ if (i) {
+ pr_err("smc91c92_cs: Failed to load firmware\n");
+ return i;
}
}
if (link->open) {
@@ -1291,7 +1314,7 @@ static void smc_hardware_send_packet(struct net_device * dev)
return;
}
- smc->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
/* The card should use the just-allocated buffer. */
outw(packet_no, ioaddr + PNR_ARR);
/* point to the beginning of the packet */
@@ -1340,7 +1363,7 @@ static void smc_tx_timeout(struct net_device *dev)
printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, "
"Tx_status %2.2x status %4.4x.\n",
dev->name, inw(ioaddr)&0xff, inw(ioaddr + 2));
- smc->stats.tx_errors++;
+ dev->stats.tx_errors++;
smc_reset(dev);
dev->trans_start = jiffies;
smc->saved_skb = NULL;
@@ -1362,7 +1385,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (smc->saved_skb) {
/* THIS SHOULD NEVER HAPPEN. */
- smc->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
printk(KERN_DEBUG "%s: Internal error -- sent packet while busy.\n",
dev->name);
return 1;
@@ -1375,7 +1398,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
printk(KERN_ERR "%s: Far too big packet error.\n", dev->name);
dev_kfree_skb (skb);
smc->saved_skb = NULL;
- smc->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
return 0; /* Do not re-queue this packet. */
}
/* A packet is now waiting. */
@@ -1433,11 +1456,11 @@ static void smc_tx_err(struct net_device * dev)
tx_status = inw(ioaddr + DATA_1);
- smc->stats.tx_errors++;
- if (tx_status & TS_LOSTCAR) smc->stats.tx_carrier_errors++;
- if (tx_status & TS_LATCOL) smc->stats.tx_window_errors++;
+ dev->stats.tx_errors++;
+ if (tx_status & TS_LOSTCAR) dev->stats.tx_carrier_errors++;
+ if (tx_status & TS_LATCOL) dev->stats.tx_window_errors++;
if (tx_status & TS_16COL) {
- smc->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
smc->tx_err++;
}
@@ -1474,10 +1497,10 @@ static void smc_eph_irq(struct net_device *dev)
/* Could be a counter roll-over warning: update stats. */
card_stats = inw(ioaddr + COUNTER);
/* single collisions */
- smc->stats.collisions += card_stats & 0xF;
+ dev->stats.collisions += card_stats & 0xF;
card_stats >>= 4;
/* multiple collisions */
- smc->stats.collisions += card_stats & 0xF;
+ dev->stats.collisions += card_stats & 0xF;
#if 0 /* These are for when linux supports these statistics */
card_stats >>= 4; /* deferred */
card_stats >>= 4; /* excess deferred */
@@ -1551,7 +1574,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
if (status & IM_TX_EMPTY_INT) {
outw(IM_TX_EMPTY_INT, ioaddr + INTERRUPT);
mask &= ~IM_TX_EMPTY_INT;
- smc->stats.tx_packets += smc->packets_waiting;
+ dev->stats.tx_packets += smc->packets_waiting;
smc->packets_waiting = 0;
}
if (status & IM_ALLOC_INT) {
@@ -1567,8 +1590,8 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
netif_wake_queue(dev);
}
if (status & IM_RX_OVRN_INT) {
- smc->stats.rx_errors++;
- smc->stats.rx_fifo_errors++;
+ dev->stats.rx_errors++;
+ dev->stats.rx_fifo_errors++;
if (smc->duplex)
smc->rx_ovrn = 1; /* need MC_RESET outside smc_interrupt */
outw(IM_RX_OVRN_INT, ioaddr + INTERRUPT);
@@ -1618,7 +1641,6 @@ irq_done:
static void smc_rx(struct net_device *dev)
{
- struct smc_private *smc = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
int rx_status;
int packet_length; /* Caution: not frame length, rather words
@@ -1649,7 +1671,7 @@ static void smc_rx(struct net_device *dev)
if (skb == NULL) {
DEBUG(1, "%s: Low memory, packet dropped.\n", dev->name);
- smc->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
outw(MC_RELEASE, ioaddr + MMU_CMD);
return;
}
@@ -1662,18 +1684,18 @@ static void smc_rx(struct net_device *dev)
netif_rx(skb);
dev->last_rx = jiffies;
- smc->stats.rx_packets++;
- smc->stats.rx_bytes += packet_length;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += packet_length;
if (rx_status & RS_MULTICAST)
- smc->stats.multicast++;
+ dev->stats.multicast++;
} else {
/* error ... */
- smc->stats.rx_errors++;
+ dev->stats.rx_errors++;
- if (rx_status & RS_ALGNERR) smc->stats.rx_frame_errors++;
+ if (rx_status & RS_ALGNERR) dev->stats.rx_frame_errors++;
if (rx_status & (RS_TOOSHORT | RS_TOOLONG))
- smc->stats.rx_length_errors++;
- if (rx_status & RS_BADCRC) smc->stats.rx_crc_errors++;
+ dev->stats.rx_length_errors++;
+ if (rx_status & RS_BADCRC) dev->stats.rx_crc_errors++;
}
/* Let the MMU free the memory of this packet. */
outw(MC_RELEASE, ioaddr + MMU_CMD);
@@ -1681,15 +1703,6 @@ static void smc_rx(struct net_device *dev)
return;
}
-/*====================================================================*/
-
-static struct net_device_stats *smc_get_stats(struct net_device *dev)
-{
- struct smc_private *smc = netdev_priv(dev);
- /* Nothing to update - the 91c92 is a pretty primative chip. */
- return &smc->stats;
-}
-
/*======================================================================
Calculate values for the hardware multicast filter hash table.
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index fef7e1861d6a..a3685c0d22fc 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -335,7 +335,7 @@ typedef struct local_info_t {
struct net_device *dev;
struct pcmcia_device *p_dev;
dev_node_t node;
- struct net_device_stats stats;
+
int card_type;
int probe_port;
int silicon; /* silicon revision. 0=old CE2, 1=Scipper, 4=Mohawk */
@@ -355,7 +355,6 @@ typedef struct local_info_t {
static int do_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void xirc_tx_timeout(struct net_device *dev);
static void xirc2ps_tx_timeout_task(struct work_struct *work);
-static struct net_device_stats *do_get_stats(struct net_device *dev);
static void set_addresses(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
static int set_card_type(struct pcmcia_device *link, const void *s);
@@ -546,6 +545,19 @@ mii_wr(unsigned int ioaddr, u_char phyaddr, u_char phyreg, unsigned data,
/*============= Main bulk of functions =========================*/
+static const struct net_device_ops netdev_ops = {
+ .ndo_open = do_open,
+ .ndo_stop = do_stop,
+ .ndo_start_xmit = do_start_xmit,
+ .ndo_tx_timeout = xirc_tx_timeout,
+ .ndo_set_config = do_config,
+ .ndo_do_ioctl = do_ioctl,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/****************
* xirc2ps_attach() creates an "instance" of the driver, allocating
* local data structures for one device. The device is registered
@@ -581,19 +593,10 @@ xirc2ps_probe(struct pcmcia_device *link)
link->irq.Instance = dev;
/* Fill in card specific entries */
- dev->hard_start_xmit = &do_start_xmit;
- dev->set_config = &do_config;
- dev->get_stats = &do_get_stats;
- dev->do_ioctl = &do_ioctl;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- dev->set_multicast_list = &set_multicast_list;
- dev->open = &do_open;
- dev->stop = &do_stop;
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = xirc_tx_timeout;
+ dev->netdev_ops = &netdev_ops;
+ dev->ethtool_ops = &netdev_ethtool_ops;
dev->watchdog_timeo = TX_TIMEOUT;
INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task);
-#endif
return xirc2ps_config(link);
} /* xirc2ps_attach */
@@ -1172,7 +1175,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
if (bytes_rcvd > maxrx_bytes && (rsr & PktRxOk)) {
/* too many bytes received during this int, drop the rest of the
* packets */
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
DEBUG(2, "%s: RX drop, too much done\n", dev->name);
} else if (rsr & PktRxOk) {
struct sk_buff *skb;
@@ -1186,7 +1189,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
if (!skb) {
printk(KNOT_XIRC "low memory, packet dropped (size=%u)\n",
pktlen);
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
} else { /* okay get the packet */
skb_reserve(skb, 2);
if (lp->silicon == 0 ) { /* work around a hardware bug */
@@ -1242,24 +1245,24 @@ xirc2ps_interrupt(int irq, void *dev_id)
}
skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += pktlen;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pktlen;
if (!(rsr & PhyPkt))
- lp->stats.multicast++;
+ dev->stats.multicast++;
}
} else { /* bad packet */
DEBUG(5, "rsr=%#02x\n", rsr);
}
if (rsr & PktTooLong) {
- lp->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
DEBUG(3, "%s: Packet too long\n", dev->name);
}
if (rsr & CRCErr) {
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
DEBUG(3, "%s: CRC error\n", dev->name);
}
if (rsr & AlignErr) {
- lp->stats.rx_fifo_errors++; /* okay ? */
+ dev->stats.rx_fifo_errors++; /* okay ? */
DEBUG(3, "%s: Alignment error\n", dev->name);
}
@@ -1270,7 +1273,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
eth_status = GetByte(XIRCREG_ESR);
}
if (rx_status & 0x10) { /* Receive overrun */
- lp->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
PutByte(XIRCREG_CR, ClearRxOvrun);
DEBUG(3, "receive overrun cleared\n");
}
@@ -1283,11 +1286,11 @@ xirc2ps_interrupt(int irq, void *dev_id)
nn = GetByte(XIRCREG0_PTR);
lp->last_ptr_value = nn;
if (nn < n) /* rollover */
- lp->stats.tx_packets += 256 - n;
+ dev->stats.tx_packets += 256 - n;
else if (n == nn) { /* happens sometimes - don't know why */
DEBUG(0, "PTR not changed?\n");
} else
- lp->stats.tx_packets += lp->last_ptr_value - n;
+ dev->stats.tx_packets += lp->last_ptr_value - n;
netif_wake_queue(dev);
}
if (tx_status & 0x0002) { /* Execessive collissions */
@@ -1295,7 +1298,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
PutByte(XIRCREG_CR, RestartTx); /* restart transmitter process */
}
if (tx_status & 0x0040)
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
/* recalculate our work chunk so that we limit the duration of this
* ISR to about 1/10 of a second.
@@ -1353,7 +1356,7 @@ static void
xirc_tx_timeout(struct net_device *dev)
{
local_info_t *lp = netdev_priv(dev);
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
printk(KERN_NOTICE "%s: transmit timed out\n", dev->name);
schedule_work(&lp->tx_timeout_task);
}
@@ -1409,20 +1412,11 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
dev_kfree_skb (skb);
dev->trans_start = jiffies;
- lp->stats.tx_bytes += pktlen;
+ dev->stats.tx_bytes += pktlen;
netif_start_queue(dev);
return 0;
}
-static struct net_device_stats *
-do_get_stats(struct net_device *dev)
-{
- local_info_t *lp = netdev_priv(dev);
-
- /* lp->stats.rx_missed_errors = GetByte(?) */
- return &lp->stats;
-}
-
/****************
* Set all addresses: This first one is the individual address,
* the next 9 addresses are taken from the multicast list and
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 665a4286da39..80124fac65fa 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1397,7 +1397,7 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
if (work_done < budget) {
spin_lock_irqsave(&lp->lock, flags);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
/* clear interrupt masks */
val = lp->a.read_csr(ioaddr, CSR3);
@@ -2592,14 +2592,14 @@ pcnet32_interrupt(int irq, void *dev_id)
dev->name, csr0);
/* unlike for the lance, there is no restart needed */
}
- if (netif_rx_schedule_prep(&lp->napi)) {
+ if (napi_schedule_prep(&lp->napi)) {
u16 val;
/* set interrupt masks */
val = lp->a.read_csr(ioaddr, CSR3);
val |= 0x5f00;
lp->a.write_csr(ioaddr, CSR3, val);
mmiowb();
- __netif_rx_schedule(&lp->napi);
+ __napi_schedule(&lp->napi);
break;
}
csr0 = lp->a.read_csr(ioaddr, CSR0);
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index af28ff7ae176..33984b737233 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -202,16 +202,21 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev,
{
struct device_node *np = NULL;
struct mdio_gpio_platform_data *pdata;
+ int ret;
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
- pdata->mdc = of_get_gpio(ofdev->node, 0);
- pdata->mdio = of_get_gpio(ofdev->node, 1);
-
- if (pdata->mdc < 0 || pdata->mdio < 0)
+ ret = of_get_gpio(ofdev->node, 0);
+ if (ret < 0)
goto out_free;
+ pdata->mdc = ret;
+
+ ret = of_get_gpio(ofdev->node, 1);
+ if (ret < 0)
+ goto out_free;
+ pdata->mdio = ret;
while ((np = of_get_next_child(ofdev->node, np)))
if (!strcmp(np->type, "ethernet-phy"))
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 811a637695ca..b754020cbe75 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/device.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
@@ -98,7 +99,7 @@ int mdiobus_register(struct mii_bus *bus)
bus->dev.parent = bus->parent;
bus->dev.class = &mdio_bus_class;
bus->dev.groups = NULL;
- dev_set_name(&bus->dev, bus->id);
+ dev_set_name(&bus->dev, "%s", bus->id);
err = device_register(&bus->dev);
if (err) {
@@ -286,33 +287,58 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv)
(phydev->phy_id & phydrv->phy_id_mask));
}
+static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
+{
+ struct device_driver *drv = phydev->dev.driver;
+ struct phy_driver *phydrv = to_phy_driver(drv);
+ struct net_device *netdev = phydev->attached_dev;
+
+ if (!drv || !phydrv->suspend)
+ return false;
+
+ /* PHY not attached? May suspend. */
+ if (!netdev)
+ return true;
+
+ /*
+ * Don't suspend PHY if the attched netdev parent may wakeup.
+ * The parent may point to a PCI device, as in tg3 driver.
+ */
+ if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent))
+ return false;
+
+ /*
+ * Also don't suspend PHY if the netdev itself may wakeup. This
+ * is the case for devices w/o underlaying pwr. mgmt. aware bus,
+ * e.g. SoC devices.
+ */
+ if (device_may_wakeup(&netdev->dev))
+ return false;
+
+ return true;
+}
+
/* Suspend and resume. Copied from platform_suspend and
* platform_resume
*/
static int mdio_bus_suspend(struct device * dev, pm_message_t state)
{
- int ret = 0;
- struct device_driver *drv = dev->driver;
- struct phy_driver *phydrv = to_phy_driver(drv);
+ struct phy_driver *phydrv = to_phy_driver(dev->driver);
struct phy_device *phydev = to_phy_device(dev);
- if (drv && phydrv->suspend && !device_may_wakeup(phydev->dev.parent))
- ret = phydrv->suspend(phydev);
-
- return ret;
+ if (!mdio_bus_phy_may_suspend(phydev))
+ return 0;
+ return phydrv->suspend(phydev);
}
static int mdio_bus_resume(struct device * dev)
{
- int ret = 0;
- struct device_driver *drv = dev->driver;
- struct phy_driver *phydrv = to_phy_driver(drv);
+ struct phy_driver *phydrv = to_phy_driver(dev->driver);
struct phy_device *phydev = to_phy_device(dev);
- if (drv && phydrv->resume && !device_may_wakeup(phydev->dev.parent))
- ret = phydrv->resume(phydev);
-
- return ret;
+ if (!mdio_bus_phy_may_suspend(phydev))
+ return 0;
+ return phydrv->resume(phydev);
}
struct bus_type mdio_bus_type = {
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index e4ede6080c9d..3ff1f425f1bb 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -414,7 +414,6 @@ EXPORT_SYMBOL(phy_start_aneg);
static void phy_change(struct work_struct *work);
static void phy_state_machine(struct work_struct *work);
-static void phy_timer(unsigned long data);
/**
* phy_start_machine - start PHY state machine tracking
@@ -434,11 +433,8 @@ void phy_start_machine(struct phy_device *phydev,
{
phydev->adjust_state = handler;
- INIT_WORK(&phydev->state_queue, phy_state_machine);
- init_timer(&phydev->phy_timer);
- phydev->phy_timer.function = &phy_timer;
- phydev->phy_timer.data = (unsigned long) phydev;
- mod_timer(&phydev->phy_timer, jiffies + HZ);
+ INIT_DELAYED_WORK(&phydev->state_queue, phy_state_machine);
+ schedule_delayed_work(&phydev->state_queue, jiffies + HZ);
}
/**
@@ -451,8 +447,7 @@ void phy_start_machine(struct phy_device *phydev,
*/
void phy_stop_machine(struct phy_device *phydev)
{
- del_timer_sync(&phydev->phy_timer);
- cancel_work_sync(&phydev->state_queue);
+ cancel_delayed_work_sync(&phydev->state_queue);
mutex_lock(&phydev->lock);
if (phydev->state > PHY_UP)
@@ -680,11 +675,9 @@ static void phy_change(struct work_struct *work)
if (err)
goto irq_enable_err;
- /* Stop timer and run the state queue now. The work function for
- * state_queue will start the timer up again.
- */
- del_timer(&phydev->phy_timer);
- schedule_work(&phydev->state_queue);
+ /* reschedule state queue work to run as soon as possible */
+ cancel_delayed_work_sync(&phydev->state_queue);
+ schedule_delayed_work(&phydev->state_queue, 0);
return;
@@ -761,14 +754,12 @@ EXPORT_SYMBOL(phy_start);
/**
* phy_state_machine - Handle the state machine
* @work: work_struct that describes the work to be done
- *
- * Description: Scheduled by the state_queue workqueue each time
- * phy_timer is triggered.
*/
static void phy_state_machine(struct work_struct *work)
{
+ struct delayed_work *dwork = to_delayed_work(work);
struct phy_device *phydev =
- container_of(work, struct phy_device, state_queue);
+ container_of(dwork, struct phy_device, state_queue);
int needs_aneg = 0;
int err = 0;
@@ -946,17 +937,6 @@ static void phy_state_machine(struct work_struct *work)
if (err < 0)
phy_error(phydev);
- mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ);
-}
-
-/* PHY timer which schedules the state machine work */
-static void phy_timer(unsigned long data)
-{
- struct phy_device *phydev = (struct phy_device *)data;
-
- /*
- * PHY I/O operations can potentially sleep so we ensure that
- * it's done from a process context
- */
- schedule_work(&phydev->state_queue);
+ schedule_delayed_work(&phydev->state_queue,
+ jiffies + PHY_STATE_TIME * HZ);
}
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index 1387187543e4..5123bb954dd7 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -159,6 +159,30 @@ static struct phy_driver lan911x_int_driver = {
.driver = { .owner = THIS_MODULE, }
};
+static struct phy_driver lan8710_driver = {
+ .phy_id = 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */
+ .phy_id_mask = 0xfffffff0,
+ .name = "SMSC LAN8710/LAN8720",
+
+ .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause
+ | SUPPORTED_Asym_Pause),
+ .flags = PHY_HAS_INTERRUPT | PHY_HAS_MAGICANEG,
+
+ /* basic functions */
+ .config_aneg = genphy_config_aneg,
+ .read_status = genphy_read_status,
+ .config_init = smsc_phy_config_init,
+
+ /* IRQ related */
+ .ack_interrupt = smsc_phy_ack_interrupt,
+ .config_intr = smsc_phy_config_intr,
+
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+
+ .driver = { .owner = THIS_MODULE, }
+};
+
static int __init smsc_init(void)
{
int ret;
@@ -179,8 +203,14 @@ static int __init smsc_init(void)
if (ret)
goto err4;
+ ret = phy_driver_register (&lan8710_driver);
+ if (ret)
+ goto err5;
+
return 0;
+err5:
+ phy_driver_unregister (&lan911x_int_driver);
err4:
phy_driver_unregister (&lan8700_driver);
err3:
@@ -193,6 +223,7 @@ err1:
static void __exit smsc_exit(void)
{
+ phy_driver_unregister (&lan8710_driver);
phy_driver_unregister (&lan911x_int_driver);
phy_driver_unregister (&lan8700_driver);
phy_driver_unregister (&lan8187_driver);
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 6567fabd2e13..6de8399d6dd9 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -157,6 +157,7 @@ ppp_asynctty_open(struct tty_struct *tty)
{
struct asyncppp *ap;
int err;
+ int speed;
if (tty->ops->write == NULL)
return -EOPNOTSUPP;
@@ -187,6 +188,8 @@ ppp_asynctty_open(struct tty_struct *tty)
ap->chan.private = ap;
ap->chan.ops = &async_ops;
ap->chan.mtu = PPP_MRU;
+ speed = tty_get_baud_rate(tty);
+ ap->chan.speed = speed;
err = ppp_register_channel(&ap->chan);
if (err)
goto out_free;
@@ -233,11 +236,9 @@ ppp_asynctty_close(struct tty_struct *tty)
tasklet_kill(&ap->tsk);
ppp_unregister_channel(&ap->chan);
- if (ap->rpkt)
- kfree_skb(ap->rpkt);
+ kfree_skb(ap->rpkt);
skb_queue_purge(&ap->rqueue);
- if (ap->tpkt)
- kfree_skb(ap->tpkt);
+ kfree_skb(ap->tpkt);
kfree(ap);
}
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 7b2728b8f1b7..8ee91421db12 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -49,6 +49,10 @@
#include <net/slhc_vj.h>
#include <asm/atomic.h>
+#include <linux/nsproxy.h>
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
+
#define PPP_VERSION "2.4.2"
/*
@@ -131,6 +135,7 @@ struct ppp {
struct sock_filter *active_filter;/* filter for pkts to reset idle */
unsigned pass_len, active_len;
#endif /* CONFIG_PPP_FILTER */
+ struct net *ppp_net; /* the net we belong to */
};
/*
@@ -155,12 +160,14 @@ struct channel {
struct rw_semaphore chan_sem; /* protects `chan' during chan ioctl */
spinlock_t downl; /* protects `chan', file.xq dequeue */
struct ppp *ppp; /* ppp unit we're connected to */
+ struct net *chan_net; /* the net channel belongs to */
struct list_head clist; /* link in list of channels per unit */
rwlock_t upl; /* protects `ppp' */
#ifdef CONFIG_PPP_MULTILINK
u8 avail; /* flag used in multilink stuff */
u8 had_frag; /* >= 1 fragments have been sent */
u32 lastseq; /* MP: last sequence # received */
+ int speed; /* speed of the corresponding ppp channel*/
#endif /* CONFIG_PPP_MULTILINK */
};
@@ -173,26 +180,35 @@ struct channel {
* channel.downl.
*/
-/*
- * all_ppp_mutex protects the all_ppp_units mapping.
- * It also ensures that finding a ppp unit in the all_ppp_units map
- * and updating its file.refcnt field is atomic.
- */
-static DEFINE_MUTEX(all_ppp_mutex);
static atomic_t ppp_unit_count = ATOMIC_INIT(0);
-static DEFINE_IDR(ppp_units_idr);
-
-/*
- * all_channels_lock protects all_channels and last_channel_index,
- * and the atomicity of find a channel and updating its file.refcnt
- * field.
- */
-static DEFINE_SPINLOCK(all_channels_lock);
-static LIST_HEAD(all_channels);
-static LIST_HEAD(new_channels);
-static int last_channel_index;
static atomic_t channel_count = ATOMIC_INIT(0);
+/* per-net private data for this module */
+static int ppp_net_id;
+struct ppp_net {
+ /* units to ppp mapping */
+ struct idr units_idr;
+
+ /*
+ * all_ppp_mutex protects the units_idr mapping.
+ * It also ensures that finding a ppp unit in the units_idr
+ * map and updating its file.refcnt field is atomic.
+ */
+ struct mutex all_ppp_mutex;
+
+ /* channels */
+ struct list_head all_channels;
+ struct list_head new_channels;
+ int last_channel_index;
+
+ /*
+ * all_channels_lock protects all_channels and
+ * last_channel_index, and the atomicity of find
+ * a channel and updating its file.refcnt field.
+ */
+ spinlock_t all_channels_lock;
+};
+
/* Get the PPP protocol number from a skb */
#define PPP_PROTO(skb) (((skb)->data[0] << 8) + (skb)->data[1])
@@ -216,8 +232,8 @@ static atomic_t channel_count = ATOMIC_INIT(0);
#define seq_after(a, b) ((s32)((a) - (b)) > 0)
/* Prototypes. */
-static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
- unsigned int cmd, unsigned long arg);
+static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
+ struct file *file, unsigned int cmd, unsigned long arg);
static void ppp_xmit_process(struct ppp *ppp);
static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
static void ppp_push(struct ppp *ppp);
@@ -240,12 +256,12 @@ static void ppp_ccp_peek(struct ppp *ppp, struct sk_buff *skb, int inbound);
static void ppp_ccp_closed(struct ppp *ppp);
static struct compressor *find_compressor(int type);
static void ppp_get_stats(struct ppp *ppp, struct ppp_stats *st);
-static struct ppp *ppp_create_interface(int unit, int *retp);
+static struct ppp *ppp_create_interface(struct net *net, int unit, int *retp);
static void init_ppp_file(struct ppp_file *pf, int kind);
static void ppp_shutdown_interface(struct ppp *ppp);
static void ppp_destroy_interface(struct ppp *ppp);
-static struct ppp *ppp_find_unit(int unit);
-static struct channel *ppp_find_channel(int unit);
+static struct ppp *ppp_find_unit(struct ppp_net *pn, int unit);
+static struct channel *ppp_find_channel(struct ppp_net *pn, int unit);
static int ppp_connect_channel(struct channel *pch, int unit);
static int ppp_disconnect_channel(struct channel *pch);
static void ppp_destroy_channel(struct channel *pch);
@@ -256,6 +272,14 @@ static void *unit_find(struct idr *p, int n);
static struct class *ppp_class;
+/* per net-namespace data */
+static inline struct ppp_net *ppp_pernet(struct net *net)
+{
+ BUG_ON(!net);
+
+ return net_generic(net, ppp_net_id);
+}
+
/* Translates a PPP protocol number to a NP index (NP == network protocol) */
static inline int proto_to_npindex(int proto)
{
@@ -544,7 +568,8 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
int __user *p = argp;
if (!pf)
- return ppp_unattached_ioctl(pf, file, cmd, arg);
+ return ppp_unattached_ioctl(current->nsproxy->net_ns,
+ pf, file, cmd, arg);
if (cmd == PPPIOCDETACH) {
/*
@@ -763,12 +788,13 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return err;
}
-static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
- unsigned int cmd, unsigned long arg)
+static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
+ struct file *file, unsigned int cmd, unsigned long arg)
{
int unit, err = -EFAULT;
struct ppp *ppp;
struct channel *chan;
+ struct ppp_net *pn;
int __user *p = (int __user *)arg;
lock_kernel();
@@ -777,7 +803,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
/* Create a new ppp unit */
if (get_user(unit, p))
break;
- ppp = ppp_create_interface(unit, &err);
+ ppp = ppp_create_interface(net, unit, &err);
if (!ppp)
break;
file->private_data = &ppp->file;
@@ -792,29 +818,31 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
/* Attach to an existing ppp unit */
if (get_user(unit, p))
break;
- mutex_lock(&all_ppp_mutex);
err = -ENXIO;
- ppp = ppp_find_unit(unit);
+ pn = ppp_pernet(net);
+ mutex_lock(&pn->all_ppp_mutex);
+ ppp = ppp_find_unit(pn, unit);
if (ppp) {
atomic_inc(&ppp->file.refcnt);
file->private_data = &ppp->file;
err = 0;
}
- mutex_unlock(&all_ppp_mutex);
+ mutex_unlock(&pn->all_ppp_mutex);
break;
case PPPIOCATTCHAN:
if (get_user(unit, p))
break;
- spin_lock_bh(&all_channels_lock);
err = -ENXIO;
- chan = ppp_find_channel(unit);
+ pn = ppp_pernet(net);
+ spin_lock_bh(&pn->all_channels_lock);
+ chan = ppp_find_channel(pn, unit);
if (chan) {
atomic_inc(&chan->file.refcnt);
file->private_data = &chan->file;
err = 0;
}
- spin_unlock_bh(&all_channels_lock);
+ spin_unlock_bh(&pn->all_channels_lock);
break;
default:
@@ -834,6 +862,51 @@ static const struct file_operations ppp_device_fops = {
.release = ppp_release
};
+static __net_init int ppp_init_net(struct net *net)
+{
+ struct ppp_net *pn;
+ int err;
+
+ pn = kzalloc(sizeof(*pn), GFP_KERNEL);
+ if (!pn)
+ return -ENOMEM;
+
+ idr_init(&pn->units_idr);
+ mutex_init(&pn->all_ppp_mutex);
+
+ INIT_LIST_HEAD(&pn->all_channels);
+ INIT_LIST_HEAD(&pn->new_channels);
+
+ spin_lock_init(&pn->all_channels_lock);
+
+ err = net_assign_generic(net, ppp_net_id, pn);
+ if (err) {
+ kfree(pn);
+ return err;
+ }
+
+ return 0;
+}
+
+static __net_exit void ppp_exit_net(struct net *net)
+{
+ struct ppp_net *pn;
+
+ pn = net_generic(net, ppp_net_id);
+ idr_destroy(&pn->units_idr);
+ /*
+ * if someone has cached our net then
+ * further net_generic call will return NULL
+ */
+ net_assign_generic(net, ppp_net_id, NULL);
+ kfree(pn);
+}
+
+static struct pernet_operations ppp_net_ops = {
+ .init = ppp_init_net,
+ .exit = ppp_exit_net,
+};
+
#define PPP_MAJOR 108
/* Called at boot time if ppp is compiled into the kernel,
@@ -843,25 +916,36 @@ static int __init ppp_init(void)
int err;
printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n");
- err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops);
- if (!err) {
- ppp_class = class_create(THIS_MODULE, "ppp");
- if (IS_ERR(ppp_class)) {
- err = PTR_ERR(ppp_class);
- goto out_chrdev;
- }
- device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL,
- "ppp");
+
+ err = register_pernet_gen_device(&ppp_net_id, &ppp_net_ops);
+ if (err) {
+ printk(KERN_ERR "failed to register PPP pernet device (%d)\n", err);
+ goto out;
}
-out:
- if (err)
+ err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops);
+ if (err) {
printk(KERN_ERR "failed to register PPP device (%d)\n", err);
- return err;
+ goto out_net;
+ }
+
+ ppp_class = class_create(THIS_MODULE, "ppp");
+ if (IS_ERR(ppp_class)) {
+ err = PTR_ERR(ppp_class);
+ goto out_chrdev;
+ }
+
+ /* not a big deal if we fail here :-) */
+ device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
+
+ return 0;
out_chrdev:
unregister_chrdev(PPP_MAJOR, "ppp");
- goto out;
+out_net:
+ unregister_pernet_gen_device(ppp_net_id, &ppp_net_ops);
+out:
+ return err;
}
/*
@@ -908,7 +992,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
outf:
kfree_skb(skb);
- ++ppp->dev->stats.tx_dropped;
+ ++dev->stats.tx_dropped;
return 0;
}
@@ -969,6 +1053,7 @@ static void ppp_setup(struct net_device *dev)
dev->tx_queue_len = 3;
dev->type = ARPHRD_PPP;
dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
+ dev->features |= NETIF_F_NETNS_LOCAL;
}
/*
@@ -1161,8 +1246,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
return;
drop:
- if (skb)
- kfree_skb(skb);
+ kfree_skb(skb);
++ppp->dev->stats.tx_errors;
}
@@ -1224,138 +1308,181 @@ ppp_push(struct ppp *ppp)
*/
static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
{
- int len, fragsize;
- int i, bits, hdrlen, mtu;
- int flen;
- int navail, nfree;
- int nbigger;
+ int len, totlen;
+ int i, bits, hdrlen, mtu;
+ int flen;
+ int navail, nfree, nzero;
+ int nbigger;
+ int totspeed;
+ int totfree;
unsigned char *p, *q;
struct list_head *list;
struct channel *pch;
struct sk_buff *frag;
struct ppp_channel *chan;
- nfree = 0; /* # channels which have no packet already queued */
+ totspeed = 0; /*total bitrate of the bundle*/
+ nfree = 0; /* # channels which have no packet already queued */
navail = 0; /* total # of usable channels (not deregistered) */
+ nzero = 0; /* number of channels with zero speed associated*/
+ totfree = 0; /*total # of channels available and
+ *having no queued packets before
+ *starting the fragmentation*/
+
hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
- i = 0;
- list_for_each_entry(pch, &ppp->channels, clist) {
+ i = 0;
+ list_for_each_entry(pch, &ppp->channels, clist) {
navail += pch->avail = (pch->chan != NULL);
- if (pch->avail) {
+ pch->speed = pch->chan->speed;
+ if (pch->avail) {
if (skb_queue_empty(&pch->file.xq) ||
- !pch->had_frag) {
- pch->avail = 2;
- ++nfree;
- }
- if (!pch->had_frag && i < ppp->nxchan)
- ppp->nxchan = i;
+ !pch->had_frag) {
+ if (pch->speed == 0)
+ nzero++;
+ else
+ totspeed += pch->speed;
+
+ pch->avail = 2;
+ ++nfree;
+ ++totfree;
+ }
+ if (!pch->had_frag && i < ppp->nxchan)
+ ppp->nxchan = i;
}
++i;
}
-
/*
- * Don't start sending this packet unless at least half of
- * the channels are free. This gives much better TCP
- * performance if we have a lot of channels.
+ * Don't start sending this packet unless at least half of
+ * the channels are free. This gives much better TCP
+ * performance if we have a lot of channels.
*/
- if (nfree == 0 || nfree < navail / 2)
- return 0; /* can't take now, leave it in xmit_pending */
+ if (nfree == 0 || nfree < navail / 2)
+ return 0; /* can't take now, leave it in xmit_pending */
/* Do protocol field compression (XXX this should be optional) */
- p = skb->data;
- len = skb->len;
+ p = skb->data;
+ len = skb->len;
if (*p == 0) {
++p;
--len;
}
- /*
- * Decide on fragment size.
- * We create a fragment for each free channel regardless of
- * how small they are (i.e. even 0 length) in order to minimize
- * the time that it will take to detect when a channel drops
- * a fragment.
- */
- fragsize = len;
- if (nfree > 1)
- fragsize = DIV_ROUND_UP(fragsize, nfree);
- /* nbigger channels get fragsize bytes, the rest get fragsize-1,
- except if nbigger==0, then they all get fragsize. */
- nbigger = len % nfree;
-
- /* skip to the channel after the one we last used
- and start at that one */
+ totlen = len;
+ nbigger = len % nfree;
+
+ /* skip to the channel after the one we last used
+ and start at that one */
list = &ppp->channels;
- for (i = 0; i < ppp->nxchan; ++i) {
+ for (i = 0; i < ppp->nxchan; ++i) {
list = list->next;
- if (list == &ppp->channels) {
- i = 0;
+ if (list == &ppp->channels) {
+ i = 0;
break;
}
}
- /* create a fragment for each channel */
+ /* create a fragment for each channel */
bits = B;
- while (nfree > 0 || len > 0) {
+ while (nfree > 0 && len > 0) {
list = list->next;
- if (list == &ppp->channels) {
- i = 0;
+ if (list == &ppp->channels) {
+ i = 0;
continue;
}
- pch = list_entry(list, struct channel, clist);
+ pch = list_entry(list, struct channel, clist);
++i;
if (!pch->avail)
continue;
/*
- * Skip this channel if it has a fragment pending already and
- * we haven't given a fragment to all of the free channels.
+ * Skip this channel if it has a fragment pending already and
+ * we haven't given a fragment to all of the free channels.
*/
if (pch->avail == 1) {
- if (nfree > 0)
+ if (nfree > 0)
continue;
} else {
- --nfree;
pch->avail = 1;
}
/* check the channel's mtu and whether it is still attached. */
spin_lock_bh(&pch->downl);
if (pch->chan == NULL) {
- /* can't use this channel, it's being deregistered */
+ /* can't use this channel, it's being deregistered */
+ if (pch->speed == 0)
+ nzero--;
+ else
+ totspeed -= pch->speed;
+
spin_unlock_bh(&pch->downl);
pch->avail = 0;
- if (--navail == 0)
+ totlen = len;
+ totfree--;
+ nfree--;
+ if (--navail == 0)
break;
continue;
}
/*
- * Create a fragment for this channel of
- * min(max(mtu+2-hdrlen, 4), fragsize, len) bytes.
- * If mtu+2-hdrlen < 4, that is a ridiculously small
- * MTU, so we use mtu = 2 + hdrlen.
+ *if the channel speed is not set divide
+ *the packet evenly among the free channels;
+ *otherwise divide it according to the speed
+ *of the channel we are going to transmit on
+ */
+ if (pch->speed == 0) {
+ flen = totlen/nfree ;
+ if (nbigger > 0) {
+ flen++;
+ nbigger--;
+ }
+ } else {
+ flen = (((totfree - nzero)*(totlen + hdrlen*totfree)) /
+ ((totspeed*totfree)/pch->speed)) - hdrlen;
+ if (nbigger > 0) {
+ flen += ((totfree - nzero)*pch->speed)/totspeed;
+ nbigger -= ((totfree - nzero)*pch->speed)/
+ totspeed;
+ }
+ }
+ nfree--;
+
+ /*
+ *check if we are on the last channel or
+ *we exceded the lenght of the data to
+ *fragment
*/
- if (fragsize > len)
- fragsize = len;
- flen = fragsize;
- mtu = pch->chan->mtu + 2 - hdrlen;
- if (mtu < 4)
- mtu = 4;
+ if ((nfree == 0) || (flen > len))
+ flen = len;
+ /*
+ *it is not worth to tx on slow channels:
+ *in that case from the resulting flen according to the
+ *above formula will be equal or less than zero.
+ *Skip the channel in this case
+ */
+ if (flen <= 0) {
+ pch->avail = 2;
+ spin_unlock_bh(&pch->downl);
+ continue;
+ }
+
+ mtu = pch->chan->mtu + 2 - hdrlen;
+ if (mtu < 4)
+ mtu = 4;
if (flen > mtu)
flen = mtu;
- if (flen == len && nfree == 0)
- bits |= E;
- frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
+ if (flen == len)
+ bits |= E;
+ frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
if (!frag)
goto noskb;
- q = skb_put(frag, flen + hdrlen);
+ q = skb_put(frag, flen + hdrlen);
- /* make the MP header */
+ /* make the MP header */
q[0] = PPP_MP >> 8;
q[1] = PPP_MP;
if (ppp->flags & SC_MP_XSHORTSEQ) {
- q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
+ q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
q[3] = ppp->nxseq;
} else {
q[2] = bits;
@@ -1364,43 +1491,28 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
q[5] = ppp->nxseq;
}
- /*
- * Copy the data in.
- * Unfortunately there is a bug in older versions of
- * the Linux PPP multilink reconstruction code where it
- * drops 0-length fragments. Therefore we make sure the
- * fragment has at least one byte of data. Any bytes
- * we add in this situation will end up as padding on the
- * end of the reconstructed packet.
- */
- if (flen == 0)
- *skb_put(frag, 1) = 0;
- else
- memcpy(q + hdrlen, p, flen);
+ memcpy(q + hdrlen, p, flen);
/* try to send it down the channel */
chan = pch->chan;
- if (!skb_queue_empty(&pch->file.xq) ||
- !chan->ops->start_xmit(chan, frag))
+ if (!skb_queue_empty(&pch->file.xq) ||
+ !chan->ops->start_xmit(chan, frag))
skb_queue_tail(&pch->file.xq, frag);
- pch->had_frag = 1;
+ pch->had_frag = 1;
p += flen;
- len -= flen;
+ len -= flen;
++ppp->nxseq;
bits = 0;
spin_unlock_bh(&pch->downl);
-
- if (--nbigger == 0 && fragsize > 0)
- --fragsize;
}
- ppp->nxchan = i;
+ ppp->nxchan = i;
return 1;
noskb:
spin_unlock_bh(&pch->downl);
if (ppp->debug & 1)
- printk(KERN_ERR "PPP: no memory (fragment)\n");
+ printk(KERN_ERR "PPP: no memory (fragment)\n");
++ppp->dev->stats.tx_errors;
++ppp->nxseq;
return 1; /* abandon the frame */
@@ -1986,19 +2098,27 @@ ppp_mp_reconstruct(struct ppp *ppp)
* Channel interface.
*/
-/*
- * Create a new, unattached ppp channel.
- */
-int
-ppp_register_channel(struct ppp_channel *chan)
+/* Create a new, unattached ppp channel. */
+int ppp_register_channel(struct ppp_channel *chan)
+{
+ return ppp_register_net_channel(current->nsproxy->net_ns, chan);
+}
+
+/* Create a new, unattached ppp channel for specified net. */
+int ppp_register_net_channel(struct net *net, struct ppp_channel *chan)
{
struct channel *pch;
+ struct ppp_net *pn;
pch = kzalloc(sizeof(struct channel), GFP_KERNEL);
if (!pch)
return -ENOMEM;
+
+ pn = ppp_pernet(net);
+
pch->ppp = NULL;
pch->chan = chan;
+ pch->chan_net = net;
chan->ppp = pch;
init_ppp_file(&pch->file, CHANNEL);
pch->file.hdrlen = chan->hdrlen;
@@ -2008,11 +2128,13 @@ ppp_register_channel(struct ppp_channel *chan)
init_rwsem(&pch->chan_sem);
spin_lock_init(&pch->downl);
rwlock_init(&pch->upl);
- spin_lock_bh(&all_channels_lock);
- pch->file.index = ++last_channel_index;
- list_add(&pch->list, &new_channels);
+
+ spin_lock_bh(&pn->all_channels_lock);
+ pch->file.index = ++pn->last_channel_index;
+ list_add(&pch->list, &pn->new_channels);
atomic_inc(&channel_count);
- spin_unlock_bh(&all_channels_lock);
+ spin_unlock_bh(&pn->all_channels_lock);
+
return 0;
}
@@ -2053,9 +2175,11 @@ void
ppp_unregister_channel(struct ppp_channel *chan)
{
struct channel *pch = chan->ppp;
+ struct ppp_net *pn;
if (!pch)
return; /* should never happen */
+
chan->ppp = NULL;
/*
@@ -2068,9 +2192,12 @@ ppp_unregister_channel(struct ppp_channel *chan)
spin_unlock_bh(&pch->downl);
up_write(&pch->chan_sem);
ppp_disconnect_channel(pch);
- spin_lock_bh(&all_channels_lock);
+
+ pn = ppp_pernet(pch->chan_net);
+ spin_lock_bh(&pn->all_channels_lock);
list_del(&pch->list);
- spin_unlock_bh(&all_channels_lock);
+ spin_unlock_bh(&pn->all_channels_lock);
+
pch->file.dead = 1;
wake_up_interruptible(&pch->file.rwait);
if (atomic_dec_and_test(&pch->file.refcnt))
@@ -2395,9 +2522,10 @@ ppp_get_stats(struct ppp *ppp, struct ppp_stats *st)
* unit == -1 means allocate a new number.
*/
static struct ppp *
-ppp_create_interface(int unit, int *retp)
+ppp_create_interface(struct net *net, int unit, int *retp)
{
struct ppp *ppp;
+ struct ppp_net *pn;
struct net_device *dev = NULL;
int ret = -ENOMEM;
int i;
@@ -2406,6 +2534,8 @@ ppp_create_interface(int unit, int *retp)
if (!dev)
goto out1;
+ pn = ppp_pernet(net);
+
ppp = netdev_priv(dev);
ppp->dev = dev;
ppp->mru = PPP_MRU;
@@ -2421,17 +2551,23 @@ ppp_create_interface(int unit, int *retp)
skb_queue_head_init(&ppp->mrq);
#endif /* CONFIG_PPP_MULTILINK */
+ /*
+ * drum roll: don't forget to set
+ * the net device is belong to
+ */
+ dev_net_set(dev, net);
+
ret = -EEXIST;
- mutex_lock(&all_ppp_mutex);
+ mutex_lock(&pn->all_ppp_mutex);
if (unit < 0) {
- unit = unit_get(&ppp_units_idr, ppp);
+ unit = unit_get(&pn->units_idr, ppp);
if (unit < 0) {
*retp = unit;
goto out2;
}
} else {
- if (unit_find(&ppp_units_idr, unit))
+ if (unit_find(&pn->units_idr, unit))
goto out2; /* unit already exists */
/*
* if caller need a specified unit number
@@ -2442,7 +2578,7 @@ ppp_create_interface(int unit, int *retp)
* fair but at least pppd will ask us to allocate
* new unit in this case so user is happy :)
*/
- unit = unit_set(&ppp_units_idr, ppp, unit);
+ unit = unit_set(&pn->units_idr, ppp, unit);
if (unit < 0)
goto out2;
}
@@ -2453,20 +2589,22 @@ ppp_create_interface(int unit, int *retp)
ret = register_netdev(dev);
if (ret != 0) {
- unit_put(&ppp_units_idr, unit);
+ unit_put(&pn->units_idr, unit);
printk(KERN_ERR "PPP: couldn't register device %s (%d)\n",
dev->name, ret);
goto out2;
}
+ ppp->ppp_net = net;
+
atomic_inc(&ppp_unit_count);
- mutex_unlock(&all_ppp_mutex);
+ mutex_unlock(&pn->all_ppp_mutex);
*retp = 0;
return ppp;
out2:
- mutex_unlock(&all_ppp_mutex);
+ mutex_unlock(&pn->all_ppp_mutex);
free_netdev(dev);
out1:
*retp = ret;
@@ -2492,7 +2630,11 @@ init_ppp_file(struct ppp_file *pf, int kind)
*/
static void ppp_shutdown_interface(struct ppp *ppp)
{
- mutex_lock(&all_ppp_mutex);
+ struct ppp_net *pn;
+
+ pn = ppp_pernet(ppp->ppp_net);
+ mutex_lock(&pn->all_ppp_mutex);
+
/* This will call dev_close() for us. */
ppp_lock(ppp);
if (!ppp->closing) {
@@ -2502,11 +2644,12 @@ static void ppp_shutdown_interface(struct ppp *ppp)
} else
ppp_unlock(ppp);
- unit_put(&ppp_units_idr, ppp->file.index);
+ unit_put(&pn->units_idr, ppp->file.index);
ppp->file.dead = 1;
ppp->owner = NULL;
wake_up_interruptible(&ppp->file.rwait);
- mutex_unlock(&all_ppp_mutex);
+
+ mutex_unlock(&pn->all_ppp_mutex);
}
/*
@@ -2543,8 +2686,7 @@ static void ppp_destroy_interface(struct ppp *ppp)
ppp->active_filter = NULL;
#endif /* CONFIG_PPP_FILTER */
- if (ppp->xmit_pending)
- kfree_skb(ppp->xmit_pending);
+ kfree_skb(ppp->xmit_pending);
free_netdev(ppp->dev);
}
@@ -2554,9 +2696,9 @@ static void ppp_destroy_interface(struct ppp *ppp)
* The caller should have locked the all_ppp_mutex.
*/
static struct ppp *
-ppp_find_unit(int unit)
+ppp_find_unit(struct ppp_net *pn, int unit)
{
- return unit_find(&ppp_units_idr, unit);
+ return unit_find(&pn->units_idr, unit);
}
/*
@@ -2568,20 +2710,22 @@ ppp_find_unit(int unit)
* when we have a lot of channels in use.
*/
static struct channel *
-ppp_find_channel(int unit)
+ppp_find_channel(struct ppp_net *pn, int unit)
{
struct channel *pch;
- list_for_each_entry(pch, &new_channels, list) {
+ list_for_each_entry(pch, &pn->new_channels, list) {
if (pch->file.index == unit) {
- list_move(&pch->list, &all_channels);
+ list_move(&pch->list, &pn->all_channels);
return pch;
}
}
- list_for_each_entry(pch, &all_channels, list) {
+
+ list_for_each_entry(pch, &pn->all_channels, list) {
if (pch->file.index == unit)
return pch;
}
+
return NULL;
}
@@ -2592,11 +2736,14 @@ static int
ppp_connect_channel(struct channel *pch, int unit)
{
struct ppp *ppp;
+ struct ppp_net *pn;
int ret = -ENXIO;
int hdrlen;
- mutex_lock(&all_ppp_mutex);
- ppp = ppp_find_unit(unit);
+ pn = ppp_pernet(pch->chan_net);
+
+ mutex_lock(&pn->all_ppp_mutex);
+ ppp = ppp_find_unit(pn, unit);
if (!ppp)
goto out;
write_lock_bh(&pch->upl);
@@ -2620,7 +2767,7 @@ ppp_connect_channel(struct channel *pch, int unit)
outl:
write_unlock_bh(&pch->upl);
out:
- mutex_unlock(&all_ppp_mutex);
+ mutex_unlock(&pn->all_ppp_mutex);
return ret;
}
@@ -2677,7 +2824,7 @@ static void __exit ppp_cleanup(void)
unregister_chrdev(PPP_MAJOR, "ppp");
device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
class_destroy(ppp_class);
- idr_destroy(&ppp_units_idr);
+ unregister_pernet_gen_device(ppp_net_id, &ppp_net_ops);
}
/*
@@ -2743,6 +2890,7 @@ static void *unit_find(struct idr *p, int n)
module_init(ppp_init);
module_exit(ppp_cleanup);
+EXPORT_SYMBOL(ppp_register_net_channel);
EXPORT_SYMBOL(ppp_register_channel);
EXPORT_SYMBOL(ppp_unregister_channel);
EXPORT_SYMBOL(ppp_channel_index);
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index 1e892b7b1f8c..d2fa2db13586 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -206,6 +206,7 @@ ppp_sync_open(struct tty_struct *tty)
{
struct syncppp *ap;
int err;
+ int speed;
if (tty->ops->write == NULL)
return -EOPNOTSUPP;
@@ -234,6 +235,8 @@ ppp_sync_open(struct tty_struct *tty)
ap->chan.ops = &sync_ops;
ap->chan.mtu = PPP_MRU;
ap->chan.hdrlen = 2; /* for A/C bytes */
+ speed = tty_get_baud_rate(tty);
+ ap->chan.speed = speed;
err = ppp_register_channel(&ap->chan);
if (err)
goto out_free;
@@ -281,8 +284,7 @@ ppp_sync_close(struct tty_struct *tty)
ppp_unregister_channel(&ap->chan);
skb_queue_purge(&ap->rqueue);
- if (ap->tpkt)
- kfree_skb(ap->tpkt);
+ kfree_skb(ap->tpkt);
kfree(ap);
}
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index c22b30533a14..f0031f1f97e5 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -78,38 +78,73 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/nsproxy.h>
#include <net/net_namespace.h>
+#include <net/netns/generic.h>
#include <net/sock.h>
#include <asm/uaccess.h>
#define PPPOE_HASH_BITS 4
-#define PPPOE_HASH_SIZE (1<<PPPOE_HASH_BITS)
-
-static struct ppp_channel_ops pppoe_chan_ops;
+#define PPPOE_HASH_SIZE (1 << PPPOE_HASH_BITS)
+#define PPPOE_HASH_MASK (PPPOE_HASH_SIZE - 1)
static int pppoe_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb);
static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb);
static const struct proto_ops pppoe_ops;
-static DEFINE_RWLOCK(pppoe_hash_lock);
-
static struct ppp_channel_ops pppoe_chan_ops;
+/* per-net private data for this module */
+static int pppoe_net_id;
+struct pppoe_net {
+ /*
+ * we could use _single_ hash table for all
+ * nets by injecting net id into the hash but
+ * it would increase hash chains and add
+ * a few additional math comparations messy
+ * as well, moreover in case of SMP less locking
+ * controversy here
+ */
+ struct pppox_sock *hash_table[PPPOE_HASH_SIZE];
+ rwlock_t hash_lock;
+};
+
+/* to eliminate a race btw pppoe_flush_dev and pppoe_release */
+static DEFINE_SPINLOCK(flush_lock);
+
+/*
+ * PPPoE could be in the following stages:
+ * 1) Discovery stage (to obtain remote MAC and Session ID)
+ * 2) Session stage (MAC and SID are known)
+ *
+ * Ethernet frames have a special tag for this but
+ * we use simplier approach based on session id
+ */
+static inline bool stage_session(__be16 sid)
+{
+ return sid != 0;
+}
+
+static inline struct pppoe_net *pppoe_pernet(struct net *net)
+{
+ BUG_ON(!net);
+
+ return net_generic(net, pppoe_net_id);
+}
+
static inline int cmp_2_addr(struct pppoe_addr *a, struct pppoe_addr *b)
{
- return (a->sid == b->sid &&
- (memcmp(a->remote, b->remote, ETH_ALEN) == 0));
+ return a->sid == b->sid && !memcmp(a->remote, b->remote, ETH_ALEN);
}
static inline int cmp_addr(struct pppoe_addr *a, __be16 sid, char *addr)
{
- return (a->sid == sid &&
- (memcmp(a->remote,addr,ETH_ALEN) == 0));
+ return a->sid == sid && !memcmp(a->remote, addr, ETH_ALEN);
}
-#if 8%PPPOE_HASH_BITS
+#if 8 % PPPOE_HASH_BITS
#error 8 must be a multiple of PPPOE_HASH_BITS
#endif
@@ -118,69 +153,71 @@ static int hash_item(__be16 sid, unsigned char *addr)
unsigned char hash = 0;
unsigned int i;
- for (i = 0 ; i < ETH_ALEN ; i++) {
+ for (i = 0; i < ETH_ALEN; i++)
hash ^= addr[i];
- }
- for (i = 0 ; i < sizeof(sid_t)*8 ; i += 8 ){
- hash ^= (__force __u32)sid>>i;
- }
- for (i = 8 ; (i>>=1) >= PPPOE_HASH_BITS ; ) {
- hash ^= hash>>i;
- }
+ for (i = 0; i < sizeof(sid_t) * 8; i += 8)
+ hash ^= (__force __u32)sid >> i;
+ for (i = 8; (i >>= 1) >= PPPOE_HASH_BITS;)
+ hash ^= hash >> i;
- return hash & ( PPPOE_HASH_SIZE - 1 );
+ return hash & PPPOE_HASH_MASK;
}
-/* zeroed because its in .bss */
-static struct pppox_sock *item_hash_table[PPPOE_HASH_SIZE];
-
/**********************************************************************
*
* Set/get/delete/rehash items (internal versions)
*
**********************************************************************/
-static struct pppox_sock *__get_item(__be16 sid, unsigned char *addr, int ifindex)
+static struct pppox_sock *__get_item(struct pppoe_net *pn, __be16 sid,
+ unsigned char *addr, int ifindex)
{
int hash = hash_item(sid, addr);
struct pppox_sock *ret;
- ret = item_hash_table[hash];
+ ret = pn->hash_table[hash];
+ while (ret) {
+ if (cmp_addr(&ret->pppoe_pa, sid, addr) &&
+ ret->pppoe_ifindex == ifindex)
+ return ret;
- while (ret && !(cmp_addr(&ret->pppoe_pa, sid, addr) && ret->pppoe_ifindex == ifindex))
ret = ret->next;
+ }
- return ret;
+ return NULL;
}
-static int __set_item(struct pppox_sock *po)
+static int __set_item(struct pppoe_net *pn, struct pppox_sock *po)
{
int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote);
struct pppox_sock *ret;
- ret = item_hash_table[hash];
+ ret = pn->hash_table[hash];
while (ret) {
- if (cmp_2_addr(&ret->pppoe_pa, &po->pppoe_pa) && ret->pppoe_ifindex == po->pppoe_ifindex)
+ if (cmp_2_addr(&ret->pppoe_pa, &po->pppoe_pa) &&
+ ret->pppoe_ifindex == po->pppoe_ifindex)
return -EALREADY;
ret = ret->next;
}
- po->next = item_hash_table[hash];
- item_hash_table[hash] = po;
+ po->next = pn->hash_table[hash];
+ pn->hash_table[hash] = po;
return 0;
}
-static struct pppox_sock *__delete_item(__be16 sid, char *addr, int ifindex)
+static struct pppox_sock *__delete_item(struct pppoe_net *pn, __be16 sid,
+ char *addr, int ifindex)
{
int hash = hash_item(sid, addr);
struct pppox_sock *ret, **src;
- ret = item_hash_table[hash];
- src = &item_hash_table[hash];
+ ret = pn->hash_table[hash];
+ src = &pn->hash_table[hash];
while (ret) {
- if (cmp_addr(&ret->pppoe_pa, sid, addr) && ret->pppoe_ifindex == ifindex) {
+ if (cmp_addr(&ret->pppoe_pa, sid, addr) &&
+ ret->pppoe_ifindex == ifindex) {
*src = ret->next;
break;
}
@@ -197,46 +234,54 @@ static struct pppox_sock *__delete_item(__be16 sid, char *addr, int ifindex)
* Set/get/delete/rehash items
*
**********************************************************************/
-static inline struct pppox_sock *get_item(__be16 sid,
- unsigned char *addr, int ifindex)
+static inline struct pppox_sock *get_item(struct pppoe_net *pn, __be16 sid,
+ unsigned char *addr, int ifindex)
{
struct pppox_sock *po;
- read_lock_bh(&pppoe_hash_lock);
- po = __get_item(sid, addr, ifindex);
+ read_lock_bh(&pn->hash_lock);
+ po = __get_item(pn, sid, addr, ifindex);
if (po)
sock_hold(sk_pppox(po));
- read_unlock_bh(&pppoe_hash_lock);
+ read_unlock_bh(&pn->hash_lock);
return po;
}
-static inline struct pppox_sock *get_item_by_addr(struct sockaddr_pppox *sp)
+static inline struct pppox_sock *get_item_by_addr(struct net *net,
+ struct sockaddr_pppox *sp)
{
struct net_device *dev;
+ struct pppoe_net *pn;
+ struct pppox_sock *pppox_sock;
+
int ifindex;
- dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev);
- if(!dev)
+ dev = dev_get_by_name(net, sp->sa_addr.pppoe.dev);
+ if (!dev)
return NULL;
+
ifindex = dev->ifindex;
+ pn = net_generic(net, pppoe_net_id);
+ pppox_sock = get_item(pn, sp->sa_addr.pppoe.sid,
+ sp->sa_addr.pppoe.remote, ifindex);
dev_put(dev);
- return get_item(sp->sa_addr.pppoe.sid, sp->sa_addr.pppoe.remote, ifindex);
+
+ return pppox_sock;
}
-static inline struct pppox_sock *delete_item(__be16 sid, char *addr, int ifindex)
+static inline struct pppox_sock *delete_item(struct pppoe_net *pn, __be16 sid,
+ char *addr, int ifindex)
{
struct pppox_sock *ret;
- write_lock_bh(&pppoe_hash_lock);
- ret = __delete_item(sid, addr, ifindex);
- write_unlock_bh(&pppoe_hash_lock);
+ write_lock_bh(&pn->hash_lock);
+ ret = __delete_item(pn, sid, addr, ifindex);
+ write_unlock_bh(&pn->hash_lock);
return ret;
}
-
-
/***************************************************************************
*
* Handler for device events.
@@ -246,25 +291,33 @@ static inline struct pppox_sock *delete_item(__be16 sid, char *addr, int ifindex
static void pppoe_flush_dev(struct net_device *dev)
{
- int hash;
+ struct pppoe_net *pn;
+ int i;
+
BUG_ON(dev == NULL);
- write_lock_bh(&pppoe_hash_lock);
- for (hash = 0; hash < PPPOE_HASH_SIZE; hash++) {
- struct pppox_sock *po = item_hash_table[hash];
+ pn = pppoe_pernet(dev_net(dev));
+ if (!pn) /* already freed */
+ return;
+
+ write_lock_bh(&pn->hash_lock);
+ for (i = 0; i < PPPOE_HASH_SIZE; i++) {
+ struct pppox_sock *po = pn->hash_table[i];
while (po != NULL) {
- struct sock *sk = sk_pppox(po);
+ struct sock *sk;
if (po->pppoe_dev != dev) {
po = po->next;
continue;
}
+ sk = sk_pppox(po);
+ spin_lock(&flush_lock);
po->pppoe_dev = NULL;
+ spin_unlock(&flush_lock);
dev_put(dev);
-
/* We always grab the socket lock, followed by the
- * pppoe_hash_lock, in that order. Since we should
+ * hash_lock, in that order. Since we should
* hold the sock lock while doing any unbinding,
* we need to release the lock we're holding.
* Hold a reference to the sock so it doesn't disappear
@@ -273,7 +326,7 @@ static void pppoe_flush_dev(struct net_device *dev)
sock_hold(sk);
- write_unlock_bh(&pppoe_hash_lock);
+ write_unlock_bh(&pn->hash_lock);
lock_sock(sk);
if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
@@ -289,20 +342,17 @@ static void pppoe_flush_dev(struct net_device *dev)
* While the lock was dropped the chain contents may
* have changed.
*/
- write_lock_bh(&pppoe_hash_lock);
- po = item_hash_table[hash];
+ write_lock_bh(&pn->hash_lock);
+ po = pn->hash_table[i];
}
}
- write_unlock_bh(&pppoe_hash_lock);
+ write_unlock_bh(&pn->hash_lock);
}
static int pppoe_device_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
- struct net_device *dev = (struct net_device *) ptr;
-
- if (dev_net(dev) != &init_net)
- return NOTIFY_DONE;
+ struct net_device *dev = (struct net_device *)ptr;
/* Only look at sockets that are using this specific device. */
switch (event) {
@@ -324,12 +374,10 @@ static int pppoe_device_event(struct notifier_block *this,
return NOTIFY_DONE;
}
-
static struct notifier_block pppoe_notifier = {
.notifier_call = pppoe_device_event,
};
-
/************************************************************************
*
* Do the real work of receiving a PPPoE Session frame.
@@ -343,8 +391,8 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
if (sk->sk_state & PPPOX_BOUND) {
ppp_input(&po->chan, skb);
} else if (sk->sk_state & PPPOX_RELAY) {
- relay_po = get_item_by_addr(&po->pppoe_relay);
-
+ relay_po = get_item_by_addr(dev_net(po->pppoe_dev),
+ &po->pppoe_relay);
if (relay_po == NULL)
goto abort_kfree;
@@ -373,22 +421,18 @@ abort_kfree:
* Receive wrapper called in BH context.
*
***********************************************************************/
-static int pppoe_rcv(struct sk_buff *skb,
- struct net_device *dev,
- struct packet_type *pt,
- struct net_device *orig_dev)
-
+static int pppoe_rcv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *pt, struct net_device *orig_dev)
{
struct pppoe_hdr *ph;
struct pppox_sock *po;
+ struct pppoe_net *pn;
int len;
- if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (!skb)
goto out;
- if (dev_net(dev) != &init_net)
- goto drop;
-
if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
goto drop;
@@ -402,7 +446,8 @@ static int pppoe_rcv(struct sk_buff *skb,
if (pskb_trim_rcsum(skb, len))
goto drop;
- po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
+ pn = pppoe_pernet(dev_net(dev));
+ po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
if (!po)
goto drop;
@@ -420,19 +465,16 @@ out:
* This is solely for detection of PADT frames
*
***********************************************************************/
-static int pppoe_disc_rcv(struct sk_buff *skb,
- struct net_device *dev,
- struct packet_type *pt,
- struct net_device *orig_dev)
+static int pppoe_disc_rcv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *pt, struct net_device *orig_dev)
{
struct pppoe_hdr *ph;
struct pppox_sock *po;
+ struct pppoe_net *pn;
- if (dev_net(dev) != &init_net)
- goto abort;
-
- if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
+ skb = skb_share_check(skb, GFP_ATOMIC);
+ if (!skb)
goto out;
if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
@@ -442,7 +484,8 @@ static int pppoe_disc_rcv(struct sk_buff *skb,
if (ph->code != PADT_CODE)
goto abort;
- po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
+ pn = pppoe_pernet(dev_net(dev));
+ po = get_item(pn, ph->sid, eth_hdr(skb)->h_source, dev->ifindex);
if (po) {
struct sock *sk = sk_pppox(po);
@@ -470,17 +513,17 @@ out:
return NET_RX_SUCCESS; /* Lies... :-) */
}
-static struct packet_type pppoes_ptype = {
- .type = __constant_htons(ETH_P_PPP_SES),
+static struct packet_type pppoes_ptype __read_mostly = {
+ .type = cpu_to_be16(ETH_P_PPP_SES),
.func = pppoe_rcv,
};
-static struct packet_type pppoed_ptype = {
- .type = __constant_htons(ETH_P_PPP_DISC),
+static struct packet_type pppoed_ptype __read_mostly = {
+ .type = cpu_to_be16(ETH_P_PPP_DISC),
.func = pppoe_disc_rcv,
};
-static struct proto pppoe_sk_proto = {
+static struct proto pppoe_sk_proto __read_mostly = {
.name = "PPPOE",
.owner = THIS_MODULE,
.obj_size = sizeof(struct pppox_sock),
@@ -493,38 +536,37 @@ static struct proto pppoe_sk_proto = {
**********************************************************************/
static int pppoe_create(struct net *net, struct socket *sock)
{
- int error = -ENOMEM;
struct sock *sk;
sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto);
if (!sk)
- goto out;
+ return -ENOMEM;
sock_init_data(sock, sk);
- sock->state = SS_UNCONNECTED;
- sock->ops = &pppoe_ops;
+ sock->state = SS_UNCONNECTED;
+ sock->ops = &pppoe_ops;
- sk->sk_backlog_rcv = pppoe_rcv_core;
- sk->sk_state = PPPOX_NONE;
- sk->sk_type = SOCK_STREAM;
- sk->sk_family = PF_PPPOX;
- sk->sk_protocol = PX_PROTO_OE;
+ sk->sk_backlog_rcv = pppoe_rcv_core;
+ sk->sk_state = PPPOX_NONE;
+ sk->sk_type = SOCK_STREAM;
+ sk->sk_family = PF_PPPOX;
+ sk->sk_protocol = PX_PROTO_OE;
- error = 0;
-out: return error;
+ return 0;
}
static int pppoe_release(struct socket *sock)
{
struct sock *sk = sock->sk;
struct pppox_sock *po;
+ struct pppoe_net *pn;
if (!sk)
return 0;
lock_sock(sk);
- if (sock_flag(sk, SOCK_DEAD)){
+ if (sock_flag(sk, SOCK_DEAD)) {
release_sock(sk);
return -EBADF;
}
@@ -534,26 +576,39 @@ static int pppoe_release(struct socket *sock)
/* Signal the death of the socket. */
sk->sk_state = PPPOX_DEAD;
+ /*
+ * pppoe_flush_dev could lead to a race with
+ * this routine so we use flush_lock to eliminate
+ * such a case (we only need per-net specific data)
+ */
+ spin_lock(&flush_lock);
+ po = pppox_sk(sk);
+ if (!po->pppoe_dev) {
+ spin_unlock(&flush_lock);
+ goto out;
+ }
+ pn = pppoe_pernet(dev_net(po->pppoe_dev));
+ spin_unlock(&flush_lock);
- /* Write lock on hash lock protects the entire "po" struct from
- * concurrent updates via pppoe_flush_dev. The "po" struct should
- * be considered part of the hash table contents, thus protected
- * by the hash table lock */
- write_lock_bh(&pppoe_hash_lock);
+ /*
+ * protect "po" from concurrent updates
+ * on pppoe_flush_dev
+ */
+ write_lock_bh(&pn->hash_lock);
po = pppox_sk(sk);
- if (po->pppoe_pa.sid) {
- __delete_item(po->pppoe_pa.sid,
- po->pppoe_pa.remote, po->pppoe_ifindex);
- }
+ if (stage_session(po->pppoe_pa.sid))
+ __delete_item(pn, po->pppoe_pa.sid, po->pppoe_pa.remote,
+ po->pppoe_ifindex);
if (po->pppoe_dev) {
dev_put(po->pppoe_dev);
po->pppoe_dev = NULL;
}
- write_unlock_bh(&pppoe_hash_lock);
+ write_unlock_bh(&pn->hash_lock);
+out:
sock_orphan(sk);
sock->sk = NULL;
@@ -564,14 +619,14 @@ static int pppoe_release(struct socket *sock)
return 0;
}
-
static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
int sockaddr_len, int flags)
{
struct sock *sk = sock->sk;
- struct net_device *dev;
- struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;
+ struct sockaddr_pppox *sp = (struct sockaddr_pppox *)uservaddr;
struct pppox_sock *po = pppox_sk(sk);
+ struct net_device *dev;
+ struct pppoe_net *pn;
int error;
lock_sock(sk);
@@ -582,44 +637,45 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
/* Check for already bound sockets */
error = -EBUSY;
- if ((sk->sk_state & PPPOX_CONNECTED) && sp->sa_addr.pppoe.sid)
+ if ((sk->sk_state & PPPOX_CONNECTED) &&
+ stage_session(sp->sa_addr.pppoe.sid))
goto end;
/* Check for already disconnected sockets, on attempts to disconnect */
error = -EALREADY;
- if ((sk->sk_state & PPPOX_DEAD) && !sp->sa_addr.pppoe.sid )
+ if ((sk->sk_state & PPPOX_DEAD) &&
+ !stage_session(sp->sa_addr.pppoe.sid))
goto end;
error = 0;
- if (po->pppoe_pa.sid) {
- pppox_unbind_sock(sk);
-
- /* Delete the old binding */
- delete_item(po->pppoe_pa.sid,po->pppoe_pa.remote,po->pppoe_ifindex);
- if(po->pppoe_dev)
+ /* Delete the old binding */
+ if (stage_session(po->pppoe_pa.sid)) {
+ pppox_unbind_sock(sk);
+ if (po->pppoe_dev) {
+ pn = pppoe_pernet(dev_net(po->pppoe_dev));
+ delete_item(pn, po->pppoe_pa.sid,
+ po->pppoe_pa.remote, po->pppoe_ifindex);
dev_put(po->pppoe_dev);
-
+ }
memset(sk_pppox(po) + 1, 0,
sizeof(struct pppox_sock) - sizeof(struct sock));
-
sk->sk_state = PPPOX_NONE;
}
- /* Don't re-bind if sid==0 */
- if (sp->sa_addr.pppoe.sid != 0) {
- dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev);
-
+ /* Re-bind in session stage only */
+ if (stage_session(sp->sa_addr.pppoe.sid)) {
error = -ENODEV;
+ dev = dev_get_by_name(sock_net(sk), sp->sa_addr.pppoe.dev);
if (!dev)
goto end;
po->pppoe_dev = dev;
po->pppoe_ifindex = dev->ifindex;
-
- write_lock_bh(&pppoe_hash_lock);
- if (!(dev->flags & IFF_UP)){
- write_unlock_bh(&pppoe_hash_lock);
+ pn = pppoe_pernet(dev_net(dev));
+ write_lock_bh(&pn->hash_lock);
+ if (!(dev->flags & IFF_UP)) {
+ write_unlock_bh(&pn->hash_lock);
goto err_put;
}
@@ -627,8 +683,8 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
&sp->sa_addr.pppoe,
sizeof(struct pppoe_addr));
- error = __set_item(po);
- write_unlock_bh(&pppoe_hash_lock);
+ error = __set_item(pn, po);
+ write_unlock_bh(&pn->hash_lock);
if (error < 0)
goto err_put;
@@ -639,7 +695,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
po->chan.private = sk;
po->chan.ops = &pppoe_chan_ops;
- error = ppp_register_channel(&po->chan);
+ error = ppp_register_net_channel(dev_net(dev), &po->chan);
if (error)
goto err_put;
@@ -648,7 +704,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
po->num = sp->sa_addr.pppoe.sid;
- end:
+end:
release_sock(sk);
return error;
err_put:
@@ -659,7 +715,6 @@ err_put:
goto end;
}
-
static int pppoe_getname(struct socket *sock, struct sockaddr *uaddr,
int *usockaddr_len, int peer)
{
@@ -678,7 +733,6 @@ static int pppoe_getname(struct socket *sock, struct sockaddr *uaddr,
return 0;
}
-
static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
unsigned long arg)
{
@@ -690,7 +744,6 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
switch (cmd) {
case PPPIOCGMRU:
err = -ENXIO;
-
if (!(sk->sk_state & PPPOX_CONNECTED))
break;
@@ -698,7 +751,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
if (put_user(po->pppoe_dev->mtu -
sizeof(struct pppoe_hdr) -
PPP_HDRLEN,
- (int __user *) arg))
+ (int __user *)arg))
break;
err = 0;
break;
@@ -709,7 +762,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
break;
err = -EFAULT;
- if (get_user(val,(int __user *) arg))
+ if (get_user(val, (int __user *)arg))
break;
if (val < (po->pppoe_dev->mtu
@@ -722,7 +775,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
case PPPIOCSFLAGS:
err = -EFAULT;
- if (get_user(val, (int __user *) arg))
+ if (get_user(val, (int __user *)arg))
break;
err = 0;
break;
@@ -749,13 +802,12 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
err = -EINVAL;
if (po->pppoe_relay.sa_family != AF_PPPOX ||
- po->pppoe_relay.sa_protocol!= PX_PROTO_OE)
+ po->pppoe_relay.sa_protocol != PX_PROTO_OE)
break;
/* Check that the socket referenced by the address
actually exists. */
- relay_po = get_item_by_addr(&po->pppoe_relay);
-
+ relay_po = get_item_by_addr(sock_net(sk), &po->pppoe_relay);
if (!relay_po)
break;
@@ -781,7 +833,6 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
return err;
}
-
static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len)
{
@@ -808,7 +859,7 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
dev = po->pppoe_dev;
error = -EMSGSIZE;
- if (total_len > (dev->mtu + dev->hard_header_len))
+ if (total_len > (dev->mtu + dev->hard_header_len))
goto end;
@@ -826,13 +877,12 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
skb->dev = dev;
skb->priority = sk->sk_priority;
- skb->protocol = __constant_htons(ETH_P_PPP_SES);
+ skb->protocol = cpu_to_be16(ETH_P_PPP_SES);
- ph = (struct pppoe_hdr *) skb_put(skb, total_len + sizeof(struct pppoe_hdr));
- start = (char *) &ph->tag[0];
+ ph = (struct pppoe_hdr *)skb_put(skb, total_len + sizeof(struct pppoe_hdr));
+ start = (char *)&ph->tag[0];
error = memcpy_fromiovec(start, m->msg_iov, total_len);
-
if (error < 0) {
kfree_skb(skb);
goto end;
@@ -853,7 +903,6 @@ end:
return error;
}
-
/************************************************************************
*
* xmit function for internal use.
@@ -888,7 +937,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
ph->sid = po->num;
ph->length = htons(data_len);
- skb->protocol = __constant_htons(ETH_P_PPP_SES);
+ skb->protocol = cpu_to_be16(ETH_P_PPP_SES);
skb->dev = dev;
dev_hard_header(skb, dev, ETH_P_PPP_SES,
@@ -903,7 +952,6 @@ abort:
return 1;
}
-
/************************************************************************
*
* xmit function called by generic PPP driver
@@ -912,11 +960,10 @@ abort:
***********************************************************************/
static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb)
{
- struct sock *sk = (struct sock *) chan->private;
+ struct sock *sk = (struct sock *)chan->private;
return __pppoe_xmit(sk, skb);
}
-
static struct ppp_channel_ops pppoe_chan_ops = {
.start_xmit = pppoe_xmit,
};
@@ -935,7 +982,6 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock,
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &error);
-
if (error < 0)
goto end;
@@ -968,44 +1014,47 @@ static int pppoe_seq_show(struct seq_file *seq, void *v)
dev_name = po->pppoe_pa.dev;
seq_printf(seq, "%08X %pM %8s\n",
- po->pppoe_pa.sid, po->pppoe_pa.remote, dev_name);
+ po->pppoe_pa.sid, po->pppoe_pa.remote, dev_name);
out:
return 0;
}
-static __inline__ struct pppox_sock *pppoe_get_idx(loff_t pos)
+static inline struct pppox_sock *pppoe_get_idx(struct pppoe_net *pn, loff_t pos)
{
struct pppox_sock *po;
- int i = 0;
+ int i;
- for (; i < PPPOE_HASH_SIZE; i++) {
- po = item_hash_table[i];
+ for (i = 0; i < PPPOE_HASH_SIZE; i++) {
+ po = pn->hash_table[i];
while (po) {
if (!pos--)
goto out;
po = po->next;
}
}
+
out:
return po;
}
static void *pppoe_seq_start(struct seq_file *seq, loff_t *pos)
- __acquires(pppoe_hash_lock)
+ __acquires(pn->hash_lock)
{
+ struct pppoe_net *pn = pppoe_pernet(seq_file_net(seq));
loff_t l = *pos;
- read_lock_bh(&pppoe_hash_lock);
- return l ? pppoe_get_idx(--l) : SEQ_START_TOKEN;
+ read_lock_bh(&pn->hash_lock);
+ return l ? pppoe_get_idx(pn, --l) : SEQ_START_TOKEN;
}
static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
+ struct pppoe_net *pn = pppoe_pernet(seq_file_net(seq));
struct pppox_sock *po;
++*pos;
if (v == SEQ_START_TOKEN) {
- po = pppoe_get_idx(0);
+ po = pppoe_get_idx(pn, 0);
goto out;
}
po = v;
@@ -1015,22 +1064,24 @@ static void *pppoe_seq_next(struct seq_file *seq, void *v, loff_t *pos)
int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote);
while (++hash < PPPOE_HASH_SIZE) {
- po = item_hash_table[hash];
+ po = pn->hash_table[hash];
if (po)
break;
}
}
+
out:
return po;
}
static void pppoe_seq_stop(struct seq_file *seq, void *v)
- __releases(pppoe_hash_lock)
+ __releases(pn->hash_lock)
{
- read_unlock_bh(&pppoe_hash_lock);
+ struct pppoe_net *pn = pppoe_pernet(seq_file_net(seq));
+ read_unlock_bh(&pn->hash_lock);
}
-static struct seq_operations pppoe_seq_ops = {
+static const struct seq_operations pppoe_seq_ops = {
.start = pppoe_seq_start,
.next = pppoe_seq_next,
.stop = pppoe_seq_stop,
@@ -1039,7 +1090,8 @@ static struct seq_operations pppoe_seq_ops = {
static int pppoe_seq_open(struct inode *inode, struct file *file)
{
- return seq_open(file, &pppoe_seq_ops);
+ return seq_open_net(inode, file, &pppoe_seq_ops,
+ sizeof(struct seq_net_private));
}
static const struct file_operations pppoe_seq_fops = {
@@ -1047,74 +1099,115 @@ static const struct file_operations pppoe_seq_fops = {
.open = pppoe_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release,
+ .release = seq_release_net,
};
-static int __init pppoe_proc_init(void)
-{
- struct proc_dir_entry *p;
-
- p = proc_net_fops_create(&init_net, "pppoe", S_IRUGO, &pppoe_seq_fops);
- if (!p)
- return -ENOMEM;
- return 0;
-}
-#else /* CONFIG_PROC_FS */
-static inline int pppoe_proc_init(void) { return 0; }
#endif /* CONFIG_PROC_FS */
static const struct proto_ops pppoe_ops = {
- .family = AF_PPPOX,
- .owner = THIS_MODULE,
- .release = pppoe_release,
- .bind = sock_no_bind,
- .connect = pppoe_connect,
- .socketpair = sock_no_socketpair,
- .accept = sock_no_accept,
- .getname = pppoe_getname,
- .poll = datagram_poll,
- .listen = sock_no_listen,
- .shutdown = sock_no_shutdown,
- .setsockopt = sock_no_setsockopt,
- .getsockopt = sock_no_getsockopt,
- .sendmsg = pppoe_sendmsg,
- .recvmsg = pppoe_recvmsg,
- .mmap = sock_no_mmap,
- .ioctl = pppox_ioctl,
+ .family = AF_PPPOX,
+ .owner = THIS_MODULE,
+ .release = pppoe_release,
+ .bind = sock_no_bind,
+ .connect = pppoe_connect,
+ .socketpair = sock_no_socketpair,
+ .accept = sock_no_accept,
+ .getname = pppoe_getname,
+ .poll = datagram_poll,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .setsockopt = sock_no_setsockopt,
+ .getsockopt = sock_no_getsockopt,
+ .sendmsg = pppoe_sendmsg,
+ .recvmsg = pppoe_recvmsg,
+ .mmap = sock_no_mmap,
+ .ioctl = pppox_ioctl,
};
static struct pppox_proto pppoe_proto = {
- .create = pppoe_create,
- .ioctl = pppoe_ioctl,
- .owner = THIS_MODULE,
+ .create = pppoe_create,
+ .ioctl = pppoe_ioctl,
+ .owner = THIS_MODULE,
};
+static __net_init int pppoe_init_net(struct net *net)
+{
+ struct pppoe_net *pn;
+ struct proc_dir_entry *pde;
+ int err;
+
+ pn = kzalloc(sizeof(*pn), GFP_KERNEL);
+ if (!pn)
+ return -ENOMEM;
+
+ rwlock_init(&pn->hash_lock);
+
+ err = net_assign_generic(net, pppoe_net_id, pn);
+ if (err)
+ goto out;
+
+ pde = proc_net_fops_create(net, "pppoe", S_IRUGO, &pppoe_seq_fops);
+#ifdef CONFIG_PROC_FS
+ if (!pde) {
+ err = -ENOMEM;
+ goto out;
+ }
+#endif
+
+ return 0;
+
+out:
+ kfree(pn);
+ return err;
+}
+
+static __net_exit void pppoe_exit_net(struct net *net)
+{
+ struct pppoe_net *pn;
+
+ proc_net_remove(net, "pppoe");
+ pn = net_generic(net, pppoe_net_id);
+ /*
+ * if someone has cached our net then
+ * further net_generic call will return NULL
+ */
+ net_assign_generic(net, pppoe_net_id, NULL);
+ kfree(pn);
+}
+
+static struct pernet_operations pppoe_net_ops = {
+ .init = pppoe_init_net,
+ .exit = pppoe_exit_net,
+};
static int __init pppoe_init(void)
{
- int err = proto_register(&pppoe_sk_proto, 0);
+ int err;
+ err = proto_register(&pppoe_sk_proto, 0);
if (err)
goto out;
- err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto);
+ err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto);
if (err)
goto out_unregister_pppoe_proto;
- err = pppoe_proc_init();
+ err = register_pernet_gen_device(&pppoe_net_id, &pppoe_net_ops);
if (err)
goto out_unregister_pppox_proto;
dev_add_pack(&pppoes_ptype);
dev_add_pack(&pppoed_ptype);
register_netdevice_notifier(&pppoe_notifier);
-out:
- return err;
+
+ return 0;
+
out_unregister_pppox_proto:
unregister_pppox_proto(PX_PROTO_OE);
out_unregister_pppoe_proto:
proto_unregister(&pppoe_sk_proto);
- goto out;
+out:
+ return err;
}
static void __exit pppoe_exit(void)
@@ -1123,7 +1216,7 @@ static void __exit pppoe_exit(void)
dev_remove_pack(&pppoes_ptype);
dev_remove_pack(&pppoed_ptype);
unregister_netdevice_notifier(&pppoe_notifier);
- remove_proc_entry("pppoe", init_net.proc_net);
+ unregister_pernet_gen_device(pppoe_net_id, &pppoe_net_ops);
proto_unregister(&pppoe_sk_proto);
}
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index f1a946785c6a..5b07dd8e5c04 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -90,7 +90,9 @@
#include <linux/hash.h>
#include <linux/sort.h>
#include <linux/proc_fs.h>
+#include <linux/nsproxy.h>
#include <net/net_namespace.h>
+#include <net/netns/generic.h>
#include <net/dst.h>
#include <net/ip.h>
#include <net/udp.h>
@@ -204,6 +206,7 @@ struct pppol2tp_tunnel
struct sock *sock; /* Parent socket */
struct list_head list; /* Keep a list of all open
* prepared sockets */
+ struct net *pppol2tp_net; /* the net we belong to */
atomic_t ref_count;
};
@@ -227,8 +230,20 @@ static atomic_t pppol2tp_tunnel_count;
static atomic_t pppol2tp_session_count;
static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL };
static struct proto_ops pppol2tp_ops;
-static LIST_HEAD(pppol2tp_tunnel_list);
-static DEFINE_RWLOCK(pppol2tp_tunnel_list_lock);
+
+/* per-net private data for this module */
+static int pppol2tp_net_id;
+struct pppol2tp_net {
+ struct list_head pppol2tp_tunnel_list;
+ rwlock_t pppol2tp_tunnel_list_lock;
+};
+
+static inline struct pppol2tp_net *pppol2tp_pernet(struct net *net)
+{
+ BUG_ON(!net);
+
+ return net_generic(net, pppol2tp_net_id);
+}
/* Helpers to obtain tunnel/session contexts from sockets.
*/
@@ -321,18 +336,19 @@ pppol2tp_session_find(struct pppol2tp_tunnel *tunnel, u16 session_id)
/* Lookup a tunnel by id
*/
-static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id)
+static struct pppol2tp_tunnel *pppol2tp_tunnel_find(struct net *net, u16 tunnel_id)
{
- struct pppol2tp_tunnel *tunnel = NULL;
+ struct pppol2tp_tunnel *tunnel;
+ struct pppol2tp_net *pn = pppol2tp_pernet(net);
- read_lock_bh(&pppol2tp_tunnel_list_lock);
- list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) {
+ read_lock_bh(&pn->pppol2tp_tunnel_list_lock);
+ list_for_each_entry(tunnel, &pn->pppol2tp_tunnel_list, list) {
if (tunnel->stats.tunnel_id == tunnel_id) {
- read_unlock_bh(&pppol2tp_tunnel_list_lock);
+ read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
return tunnel;
}
}
- read_unlock_bh(&pppol2tp_tunnel_list_lock);
+ read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
return NULL;
}
@@ -1287,10 +1303,12 @@ again:
*/
static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel)
{
+ struct pppol2tp_net *pn = pppol2tp_pernet(tunnel->pppol2tp_net);
+
/* Remove from socket list */
- write_lock_bh(&pppol2tp_tunnel_list_lock);
+ write_lock_bh(&pn->pppol2tp_tunnel_list_lock);
list_del_init(&tunnel->list);
- write_unlock_bh(&pppol2tp_tunnel_list_lock);
+ write_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
atomic_dec(&pppol2tp_tunnel_count);
kfree(tunnel);
@@ -1444,13 +1462,14 @@ error:
/* Internal function to prepare a tunnel (UDP) socket to have PPPoX
* sockets attached to it.
*/
-static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
- int *error)
+static struct sock *pppol2tp_prepare_tunnel_socket(struct net *net,
+ int fd, u16 tunnel_id, int *error)
{
int err;
struct socket *sock = NULL;
struct sock *sk;
struct pppol2tp_tunnel *tunnel;
+ struct pppol2tp_net *pn;
struct sock *ret = NULL;
/* Get the tunnel UDP socket from the fd, which was opened by
@@ -1524,11 +1543,15 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
/* Misc init */
rwlock_init(&tunnel->hlist_lock);
+ /* The net we belong to */
+ tunnel->pppol2tp_net = net;
+ pn = pppol2tp_pernet(net);
+
/* Add tunnel to our list */
INIT_LIST_HEAD(&tunnel->list);
- write_lock_bh(&pppol2tp_tunnel_list_lock);
- list_add(&tunnel->list, &pppol2tp_tunnel_list);
- write_unlock_bh(&pppol2tp_tunnel_list_lock);
+ write_lock_bh(&pn->pppol2tp_tunnel_list_lock);
+ list_add(&tunnel->list, &pn->pppol2tp_tunnel_list);
+ write_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
atomic_inc(&pppol2tp_tunnel_count);
/* Bump the reference count. The tunnel context is deleted
@@ -1629,7 +1652,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
* tunnel id.
*/
if ((sp->pppol2tp.s_session == 0) && (sp->pppol2tp.d_session == 0)) {
- tunnel_sock = pppol2tp_prepare_tunnel_socket(sp->pppol2tp.fd,
+ tunnel_sock = pppol2tp_prepare_tunnel_socket(sock_net(sk),
+ sp->pppol2tp.fd,
sp->pppol2tp.s_tunnel,
&error);
if (tunnel_sock == NULL)
@@ -1637,7 +1661,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
tunnel = tunnel_sock->sk_user_data;
} else {
- tunnel = pppol2tp_tunnel_find(sp->pppol2tp.s_tunnel);
+ tunnel = pppol2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel);
/* Error if we can't find the tunnel */
error = -ENOENT;
@@ -1725,7 +1749,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
po->chan.ops = &pppol2tp_chan_ops;
po->chan.mtu = session->mtu;
- error = ppp_register_channel(&po->chan);
+ error = ppp_register_net_channel(sock_net(sk), &po->chan);
if (error)
goto end_put_tun;
@@ -2347,8 +2371,9 @@ end:
#include <linux/seq_file.h>
struct pppol2tp_seq_data {
- struct pppol2tp_tunnel *tunnel; /* current tunnel */
- struct pppol2tp_session *session; /* NULL means get first session in tunnel */
+ struct seq_net_private p;
+ struct pppol2tp_tunnel *tunnel; /* current tunnel */
+ struct pppol2tp_session *session; /* NULL means get first session in tunnel */
};
static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, struct pppol2tp_session *curr)
@@ -2384,17 +2409,18 @@ out:
return session;
}
-static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr)
+static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_net *pn,
+ struct pppol2tp_tunnel *curr)
{
struct pppol2tp_tunnel *tunnel = NULL;
- read_lock_bh(&pppol2tp_tunnel_list_lock);
- if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) {
+ read_lock_bh(&pn->pppol2tp_tunnel_list_lock);
+ if (list_is_last(&curr->list, &pn->pppol2tp_tunnel_list)) {
goto out;
}
tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list);
out:
- read_unlock_bh(&pppol2tp_tunnel_list_lock);
+ read_unlock_bh(&pn->pppol2tp_tunnel_list_lock);
return tunnel;
}
@@ -2402,6 +2428,7 @@ out:
static void *pppol2tp_seq_start(struct seq_file *m, loff_t *offs)
{
struct pppol2tp_seq_data *pd = SEQ_START_TOKEN;
+ struct pppol2tp_net *pn;
loff_t pos = *offs;
if (!pos)
@@ -2409,14 +2436,15 @@ static void *pppol2tp_seq_start(struct seq_file *m, loff_t *offs)
BUG_ON(m->private == NULL);
pd = m->private;
+ pn = pppol2tp_pernet(seq_file_net(m));
if (pd->tunnel == NULL) {
- if (!list_empty(&pppol2tp_tunnel_list))
- pd->tunnel = list_entry(pppol2tp_tunnel_list.next, struct pppol2tp_tunnel, list);
+ if (!list_empty(&pn->pppol2tp_tunnel_list))
+ pd->tunnel = list_entry(pn->pppol2tp_tunnel_list.next, struct pppol2tp_tunnel, list);
} else {
pd->session = next_session(pd->tunnel, pd->session);
if (pd->session == NULL) {
- pd->tunnel = next_tunnel(pd->tunnel);
+ pd->tunnel = next_tunnel(pn, pd->tunnel);
}
}
@@ -2517,7 +2545,7 @@ out:
return 0;
}
-static struct seq_operations pppol2tp_seq_ops = {
+static const struct seq_operations pppol2tp_seq_ops = {
.start = pppol2tp_seq_start,
.next = pppol2tp_seq_next,
.stop = pppol2tp_seq_stop,
@@ -2530,51 +2558,18 @@ static struct seq_operations pppol2tp_seq_ops = {
*/
static int pppol2tp_proc_open(struct inode *inode, struct file *file)
{
- struct seq_file *m;
- struct pppol2tp_seq_data *pd;
- int ret = 0;
-
- ret = seq_open(file, &pppol2tp_seq_ops);
- if (ret < 0)
- goto out;
-
- m = file->private_data;
-
- /* Allocate and fill our proc_data for access later */
- ret = -ENOMEM;
- m->private = kzalloc(sizeof(struct pppol2tp_seq_data), GFP_KERNEL);
- if (m->private == NULL)
- goto out;
-
- pd = m->private;
- ret = 0;
-
-out:
- return ret;
-}
-
-/* Called when /proc file access completes.
- */
-static int pppol2tp_proc_release(struct inode *inode, struct file *file)
-{
- struct seq_file *m = (struct seq_file *)file->private_data;
-
- kfree(m->private);
- m->private = NULL;
-
- return seq_release(inode, file);
+ return seq_open_net(inode, file, &pppol2tp_seq_ops,
+ sizeof(struct pppol2tp_seq_data));
}
-static struct file_operations pppol2tp_proc_fops = {
+static const struct file_operations pppol2tp_proc_fops = {
.owner = THIS_MODULE,
.open = pppol2tp_proc_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = pppol2tp_proc_release,
+ .release = seq_release_net,
};
-static struct proc_dir_entry *pppol2tp_proc;
-
#endif /* CONFIG_PROC_FS */
/*****************************************************************************
@@ -2606,6 +2601,57 @@ static struct pppox_proto pppol2tp_proto = {
.ioctl = pppol2tp_ioctl
};
+static __net_init int pppol2tp_init_net(struct net *net)
+{
+ struct pppol2tp_net *pn;
+ struct proc_dir_entry *pde;
+ int err;
+
+ pn = kzalloc(sizeof(*pn), GFP_KERNEL);
+ if (!pn)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&pn->pppol2tp_tunnel_list);
+ rwlock_init(&pn->pppol2tp_tunnel_list_lock);
+
+ err = net_assign_generic(net, pppol2tp_net_id, pn);
+ if (err)
+ goto out;
+
+ pde = proc_net_fops_create(net, "pppol2tp", S_IRUGO, &pppol2tp_proc_fops);
+#ifdef CONFIG_PROC_FS
+ if (!pde) {
+ err = -ENOMEM;
+ goto out;
+ }
+#endif
+
+ return 0;
+
+out:
+ kfree(pn);
+ return err;
+}
+
+static __net_exit void pppol2tp_exit_net(struct net *net)
+{
+ struct pppoe_net *pn;
+
+ proc_net_remove(net, "pppol2tp");
+ pn = net_generic(net, pppol2tp_net_id);
+ /*
+ * if someone has cached our net then
+ * further net_generic call will return NULL
+ */
+ net_assign_generic(net, pppol2tp_net_id, NULL);
+ kfree(pn);
+}
+
+static struct pernet_operations pppol2tp_net_ops = {
+ .init = pppol2tp_init_net,
+ .exit = pppol2tp_exit_net,
+};
+
static int __init pppol2tp_init(void)
{
int err;
@@ -2617,23 +2663,17 @@ static int __init pppol2tp_init(void)
if (err)
goto out_unregister_pppol2tp_proto;
-#ifdef CONFIG_PROC_FS
- pppol2tp_proc = proc_net_fops_create(&init_net, "pppol2tp", 0,
- &pppol2tp_proc_fops);
- if (!pppol2tp_proc) {
- err = -ENOMEM;
+ err = register_pernet_gen_device(&pppol2tp_net_id, &pppol2tp_net_ops);
+ if (err)
goto out_unregister_pppox_proto;
- }
-#endif /* CONFIG_PROC_FS */
+
printk(KERN_INFO "PPPoL2TP kernel driver, %s\n",
PPPOL2TP_DRV_VERSION);
out:
return err;
-#ifdef CONFIG_PROC_FS
out_unregister_pppox_proto:
unregister_pppox_proto(PX_PROTO_OL2TP);
-#endif
out_unregister_pppol2tp_proto:
proto_unregister(&pppol2tp_sk_proto);
goto out;
@@ -2642,10 +2682,6 @@ out_unregister_pppol2tp_proto:
static void __exit pppol2tp_exit(void)
{
unregister_pppox_proto(PX_PROTO_OL2TP);
-
-#ifdef CONFIG_PROC_FS
- remove_proc_entry("pppol2tp", init_net.proc_net);
-#endif
proto_unregister(&pppol2tp_sk_proto);
}
diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c
index 03aecc97fb45..4f6d33fbc673 100644
--- a/drivers/net/pppox.c
+++ b/drivers/net/pppox.c
@@ -108,9 +108,6 @@ static int pppox_create(struct net *net, struct socket *sock, int protocol)
{
int rc = -EPROTOTYPE;
- if (net != &init_net)
- return -EAFNOSUPPORT;
-
if (protocol < 0 || protocol > PX_MAX_PROTO)
goto out;
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 4b564eda5bd9..30900b30d532 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -745,7 +745,7 @@ static inline struct sk_buff *gelic_put_vlan_tag(struct sk_buff *skb,
/* Move the mac addresses to the top of buffer */
memmove(skb->data, skb->data + VLAN_HLEN, 2 * ETH_ALEN);
- veth->h_vlan_proto = __constant_htons(ETH_P_8021Q);
+ veth->h_vlan_proto = cpu_to_be16(ETH_P_8021Q);
veth->h_vlan_TCI = htons(tag);
return skb;
@@ -1403,6 +1403,19 @@ void gelic_net_tx_timeout(struct net_device *netdev)
atomic_dec(&card->tx_timeout_task_counter);
}
+static const struct net_device_ops gelic_netdevice_ops = {
+ .ndo_open = gelic_net_open,
+ .ndo_stop = gelic_net_stop,
+ .ndo_start_xmit = gelic_net_xmit,
+ .ndo_set_multicast_list = gelic_net_set_multi,
+ .ndo_change_mtu = gelic_net_change_mtu,
+ .ndo_tx_timeout = gelic_net_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = gelic_net_poll_controller,
+#endif
+};
+
/**
* gelic_ether_setup_netdev_ops - initialization of net_device operations
* @netdev: net_device structure
@@ -1412,21 +1425,12 @@ void gelic_net_tx_timeout(struct net_device *netdev)
static void gelic_ether_setup_netdev_ops(struct net_device *netdev,
struct napi_struct *napi)
{
- netdev->open = &gelic_net_open;
- netdev->stop = &gelic_net_stop;
- netdev->hard_start_xmit = &gelic_net_xmit;
- netdev->set_multicast_list = &gelic_net_set_multi;
- netdev->change_mtu = &gelic_net_change_mtu;
- /* tx watchdog */
- netdev->tx_timeout = &gelic_net_tx_timeout;
netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
/* NAPI */
netif_napi_add(netdev, napi,
gelic_net_poll, GELIC_NET_NAPI_WEIGHT);
netdev->ethtool_ops = &gelic_ether_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = gelic_net_poll_controller;
-#endif
+ netdev->netdev_ops = &gelic_netdevice_ops;
}
/**
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index 335da4831ab3..a5ac2bd58b5b 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -2697,6 +2697,19 @@ static int gelic_wl_stop(struct net_device *netdev)
/* -- */
+static const struct net_device_ops gelic_wl_netdevice_ops = {
+ .ndo_open = gelic_wl_open,
+ .ndo_stop = gelic_wl_stop,
+ .ndo_start_xmit = gelic_net_xmit,
+ .ndo_set_multicast_list = gelic_net_set_multi,
+ .ndo_change_mtu = gelic_net_change_mtu,
+ .ndo_tx_timeout = gelic_net_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = gelic_net_poll_controller,
+#endif
+};
+
static struct ethtool_ops gelic_wl_ethtool_ops = {
.get_drvinfo = gelic_net_get_drvinfo,
.get_link = gelic_wl_get_link,
@@ -2711,21 +2724,12 @@ static void gelic_wl_setup_netdev_ops(struct net_device *netdev)
struct gelic_wl_info *wl;
wl = port_wl(netdev_priv(netdev));
BUG_ON(!wl);
- netdev->open = &gelic_wl_open;
- netdev->stop = &gelic_wl_stop;
- netdev->hard_start_xmit = &gelic_net_xmit;
- netdev->set_multicast_list = &gelic_net_set_multi;
- netdev->change_mtu = &gelic_net_change_mtu;
- netdev->wireless_data = &wl->wireless_data;
- netdev->wireless_handlers = &gelic_wl_wext_handler_def;
- /* tx watchdog */
- netdev->tx_timeout = &gelic_net_tx_timeout;
netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
netdev->ethtool_ops = &gelic_wl_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = gelic_net_poll_controller;
-#endif
+ netdev->netdev_ops = &gelic_wl_netdevice_ops;
+ netdev->wireless_data = &wl->wireless_data;
+ netdev->wireless_handlers = &gelic_wl_wext_handler_def;
}
/*
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 189ec29ac7a4..8b2823c8dccf 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -2292,7 +2292,7 @@ static int ql_poll(struct napi_struct *napi, int budget)
if (tx_cleaned + rx_cleaned != budget) {
spin_lock_irqsave(&qdev->hw_lock, hw_flags);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
ql_update_small_bufq_prod_index(qdev);
ql_update_lrg_bufq_prod_index(qdev);
writel(qdev->rsp_consumer_index,
@@ -2351,8 +2351,8 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id)
spin_unlock(&qdev->adapter_lock);
} else if (value & ISP_IMR_DISABLE_CMPL_INT) {
ql_disable_interrupts(qdev);
- if (likely(netif_rx_schedule_prep(&qdev->napi))) {
- __netif_rx_schedule(&qdev->napi);
+ if (likely(napi_schedule_prep(&qdev->napi))) {
+ __napi_schedule(&qdev->napi);
}
} else {
return IRQ_NONE;
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index aff9c5fec738..fcb159e4df54 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -28,8 +28,8 @@
} while (0)
#define QLGE_VENDOR_ID 0x1077
-#define QLGE_DEVICE_ID 0x8012
-
+#define QLGE_DEVICE_ID_8012 0x8012
+#define QLGE_DEVICE_ID_8000 0x8000
#define MAX_CPUS 8
#define MAX_TX_RINGS MAX_CPUS
#define MAX_RX_RINGS ((MAX_CPUS * 2) + 1)
@@ -164,7 +164,7 @@ enum {
CSR_RP = (1 << 10),
CSR_CMD_PARM_SHIFT = 22,
CSR_CMD_NOP = 0x00000000,
- CSR_CMD_SET_RST = 0x1000000,
+ CSR_CMD_SET_RST = 0x10000000,
CSR_CMD_CLR_RST = 0x20000000,
CSR_CMD_SET_PAUSE = 0x30000000,
CSR_CMD_CLR_PAUSE = 0x40000000,
@@ -424,7 +424,7 @@ enum {
RX_SYMBOL_ERR = 0x00000370,
RX_MAC_ERR = 0x00000378,
RX_CTL_PKTS = 0x00000380,
- RX_PAUSE_PKTS = 0x00000384,
+ RX_PAUSE_PKTS = 0x00000388,
RX_64_PKTS = 0x00000390,
RX_65_TO_127_PKTS = 0x00000398,
RX_128_255_PKTS = 0x000003a0,
@@ -733,6 +733,11 @@ enum {
AEN_LINK_DOWN = 0x00008012,
AEN_IDC_CMPLT = 0x00008100,
AEN_IDC_REQ = 0x00008101,
+ AEN_IDC_EXT = 0x00008102,
+ AEN_DCBX_CHG = 0x00008110,
+ AEN_AEN_LOST = 0x00008120,
+ AEN_AEN_SFP_IN = 0x00008130,
+ AEN_AEN_SFP_OUT = 0x00008131,
AEN_FW_INIT_DONE = 0x00008400,
AEN_FW_INIT_FAIL = 0x00008401,
@@ -742,40 +747,48 @@ enum {
MB_CMD_MB_TEST = 0x00000006,
MB_CMD_CSUM_TEST = 0x00000007, /* Verify Checksum */
MB_CMD_ABOUT_FW = 0x00000008,
+ MB_CMD_COPY_RISC_RAM = 0x0000000a,
MB_CMD_LOAD_RISC_RAM = 0x0000000b,
MB_CMD_DUMP_RISC_RAM = 0x0000000c,
MB_CMD_WRITE_RAM = 0x0000000d,
+ MB_CMD_INIT_RISC_RAM = 0x0000000e,
MB_CMD_READ_RAM = 0x0000000f,
MB_CMD_STOP_FW = 0x00000014,
MB_CMD_MAKE_SYS_ERR = 0x0000002a,
+ MB_CMD_WRITE_SFP = 0x00000030,
+ MB_CMD_READ_SFP = 0x00000031,
MB_CMD_INIT_FW = 0x00000060,
- MB_CMD_GET_INIT_CB = 0x00000061,
+ MB_CMD_GET_IFCB = 0x00000061,
MB_CMD_GET_FW_STATE = 0x00000069,
MB_CMD_IDC_REQ = 0x00000100, /* Inter-Driver Communication */
MB_CMD_IDC_ACK = 0x00000101, /* Inter-Driver Communication */
MB_CMD_SET_WOL_MODE = 0x00000110, /* Wake On Lan */
- MB_WOL_DISABLE = 0x00000000,
- MB_WOL_MAGIC_PKT = 0x00000001,
- MB_WOL_FLTR = 0x00000002,
- MB_WOL_UCAST = 0x00000004,
- MB_WOL_MCAST = 0x00000008,
- MB_WOL_BCAST = 0x00000010,
- MB_WOL_LINK_UP = 0x00000020,
- MB_WOL_LINK_DOWN = 0x00000040,
+ MB_WOL_DISABLE = 0,
+ MB_WOL_MAGIC_PKT = (1 << 1),
+ MB_WOL_FLTR = (1 << 2),
+ MB_WOL_UCAST = (1 << 3),
+ MB_WOL_MCAST = (1 << 4),
+ MB_WOL_BCAST = (1 << 5),
+ MB_WOL_LINK_UP = (1 << 6),
+ MB_WOL_LINK_DOWN = (1 << 7),
MB_CMD_SET_WOL_FLTR = 0x00000111, /* Wake On Lan Filter */
- MB_CMD_CLEAR_WOL_FLTR = 0x00000112, /* Wake On Lan Filter */
+ MB_CMD_CLEAR_WOL_FLTR = 0x00000112, /* Wake On Lan Filter */
MB_CMD_SET_WOL_MAGIC = 0x00000113, /* Wake On Lan Magic Packet */
- MB_CMD_CLEAR_WOL_MAGIC = 0x00000114, /* Wake On Lan Magic Packet */
+ MB_CMD_CLEAR_WOL_MAGIC = 0x00000114,/* Wake On Lan Magic Packet */
+ MB_CMD_SET_WOL_IMMED = 0x00000115,
MB_CMD_PORT_RESET = 0x00000120,
MB_CMD_SET_PORT_CFG = 0x00000122,
MB_CMD_GET_PORT_CFG = 0x00000123,
- MB_CMD_SET_ASIC_VOLTS = 0x00000130,
- MB_CMD_GET_SNS_DATA = 0x00000131, /* Temp and Volt Sense data. */
+ MB_CMD_GET_LINK_STS = 0x00000124,
/* Mailbox Command Status. */
MB_CMD_STS_GOOD = 0x00004000, /* Success. */
MB_CMD_STS_INTRMDT = 0x00001000, /* Intermediate Complete. */
- MB_CMD_STS_ERR = 0x00004005, /* Error. */
+ MB_CMD_STS_INVLD_CMD = 0x00004001, /* Invalid. */
+ MB_CMD_STS_XFC_ERR = 0x00004002, /* Interface Error. */
+ MB_CMD_STS_CSUM_ERR = 0x00004003, /* Csum Error. */
+ MB_CMD_STS_ERR = 0x00004005, /* System Error. */
+ MB_CMD_STS_PARAM_ERR = 0x00004006, /* Parameter Error. */
};
struct mbox_params {
@@ -785,7 +798,7 @@ struct mbox_params {
int out_count;
};
-struct flash_params {
+struct flash_params_8012 {
u8 dev_id_str[4];
__le16 size;
__le16 csum;
@@ -795,6 +808,43 @@ struct flash_params {
__le16 res;
};
+/* 8000 device's flash is a different structure
+ * at a different offset in flash.
+ */
+#define FUNC0_FLASH_OFFSET 0x140200
+#define FUNC1_FLASH_OFFSET 0x140600
+
+/* Flash related data structures. */
+struct flash_params_8000 {
+ u8 dev_id_str[4]; /* "8000" */
+ __le16 ver;
+ __le16 size;
+ __le16 csum;
+ __le16 reserved0;
+ __le16 total_size;
+ __le16 entry_count;
+ u8 data_type0;
+ u8 data_size0;
+ u8 mac_addr[6];
+ u8 data_type1;
+ u8 data_size1;
+ u8 mac_addr1[6];
+ u8 data_type2;
+ u8 data_size2;
+ __le16 vlan_id;
+ u8 data_type3;
+ u8 data_size3;
+ __le16 last;
+ u8 reserved1[464];
+ __le16 subsys_ven_id;
+ __le16 subsys_dev_id;
+ u8 reserved2[4];
+};
+
+union flash_params {
+ struct flash_params_8012 flash_params_8012;
+ struct flash_params_8000 flash_params_8000;
+};
/*
* doorbell space for the rx ring context
@@ -968,6 +1018,7 @@ struct ib_mac_iocb_rsp {
__le16 vlan_id; /* 12 bits */
#define IB_MAC_IOCB_RSP_C 0x1000 /* VLAN CFI bit */
#define IB_MAC_IOCB_RSP_COS_SHIFT 12 /* class of service value */
+#define IB_MAC_IOCB_RSP_VLAN_MASK 0x0ffff
__le16 reserved1;
__le32 reserved2[6];
@@ -1033,6 +1084,7 @@ struct wqicb {
#define Q_LEN_CPP_16 0x0001
#define Q_LEN_CPP_32 0x0002
#define Q_LEN_CPP_64 0x0003
+#define Q_LEN_CPP_512 0x0006
__le16 flags;
#define Q_PRI_SHIFT 1
#define Q_FLAGS_LC 0x1000
@@ -1314,27 +1366,49 @@ enum {
QL_DMA64 = (1 << 5),
QL_PROMISCUOUS = (1 << 6),
QL_ALLMULTI = (1 << 7),
+ QL_PORT_CFG = (1 << 8),
+ QL_CAM_RT_SET = (1 << 9),
};
/* link_status bit definitions */
enum {
- LOOPBACK_MASK = 0x00000700,
- LOOPBACK_PCS = 0x00000100,
- LOOPBACK_HSS = 0x00000200,
- LOOPBACK_EXT = 0x00000300,
- PAUSE_MASK = 0x000000c0,
- PAUSE_STD = 0x00000040,
- PAUSE_PRI = 0x00000080,
- SPEED_MASK = 0x00000038,
- SPEED_100Mb = 0x00000000,
- SPEED_1Gb = 0x00000008,
- SPEED_10Gb = 0x00000010,
- LINK_TYPE_MASK = 0x00000007,
- LINK_TYPE_XFI = 0x00000001,
- LINK_TYPE_XAUI = 0x00000002,
- LINK_TYPE_XFI_BP = 0x00000003,
- LINK_TYPE_XAUI_BP = 0x00000004,
- LINK_TYPE_10GBASET = 0x00000005,
+ STS_LOOPBACK_MASK = 0x00000700,
+ STS_LOOPBACK_PCS = 0x00000100,
+ STS_LOOPBACK_HSS = 0x00000200,
+ STS_LOOPBACK_EXT = 0x00000300,
+ STS_PAUSE_MASK = 0x000000c0,
+ STS_PAUSE_STD = 0x00000040,
+ STS_PAUSE_PRI = 0x00000080,
+ STS_SPEED_MASK = 0x00000038,
+ STS_SPEED_100Mb = 0x00000000,
+ STS_SPEED_1Gb = 0x00000008,
+ STS_SPEED_10Gb = 0x00000010,
+ STS_LINK_TYPE_MASK = 0x00000007,
+ STS_LINK_TYPE_XFI = 0x00000001,
+ STS_LINK_TYPE_XAUI = 0x00000002,
+ STS_LINK_TYPE_XFI_BP = 0x00000003,
+ STS_LINK_TYPE_XAUI_BP = 0x00000004,
+ STS_LINK_TYPE_10GBASET = 0x00000005,
+};
+
+/* link_config bit definitions */
+enum {
+ CFG_JUMBO_FRAME_SIZE = 0x00010000,
+ CFG_PAUSE_MASK = 0x00000060,
+ CFG_PAUSE_STD = 0x00000020,
+ CFG_PAUSE_PRI = 0x00000040,
+ CFG_DCBX = 0x00000010,
+ CFG_LOOPBACK_MASK = 0x00000007,
+ CFG_LOOPBACK_PCS = 0x00000002,
+ CFG_LOOPBACK_HSS = 0x00000004,
+ CFG_LOOPBACK_EXT = 0x00000006,
+ CFG_DEFAULT_MAX_FRAME_SIZE = 0x00002580,
+};
+
+struct nic_operations {
+
+ int (*get_flash) (struct ql_adapter *);
+ int (*port_initialize) (struct ql_adapter *);
};
/*
@@ -1377,6 +1451,8 @@ struct ql_adapter {
u32 mailbox_in;
u32 mailbox_out;
+ struct mbox_params idc_mbc;
+ struct mutex mpi_mutex;
int tx_ring_size;
int rx_ring_size;
@@ -1412,8 +1488,10 @@ struct ql_adapter {
u32 port_link_up;
u32 port_init;
u32 link_status;
+ u32 link_config;
+ u32 max_frame_size;
- struct flash_params flash;
+ union flash_params flash;
struct net_device_stats stats;
struct workqueue_struct *q_workqueue;
@@ -1421,6 +1499,11 @@ struct ql_adapter {
struct delayed_work asic_reset_work;
struct delayed_work mpi_reset_work;
struct delayed_work mpi_work;
+ struct delayed_work mpi_port_cfg_work;
+ struct delayed_work mpi_idc_work;
+ struct completion ide_completion;
+ struct nic_operations *nic_ops;
+ u16 device_id;
};
/*
@@ -1493,6 +1576,10 @@ void ql_queue_asic_error(struct ql_adapter *qdev);
u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr);
void ql_set_ethtool_ops(struct net_device *ndev);
int ql_read_xgmac_reg64(struct ql_adapter *qdev, u32 reg, u64 *data);
+void ql_mpi_idc_work(struct work_struct *work);
+void ql_mpi_port_cfg_work(struct work_struct *work);
+int ql_mb_get_fw_state(struct ql_adapter *qdev);
+int ql_cam_route_initialize(struct ql_adapter *qdev);
#if 1
#define QL_ALL_DUMP
diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c
index 379b895ed6e6..40a70c36f5ae 100644
--- a/drivers/net/qlge/qlge_dbg.c
+++ b/drivers/net/qlge/qlge_dbg.c
@@ -83,6 +83,10 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
{
int i;
u32 value[3];
+
+ i = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (i)
+ return;
for (i = 0; i < 4; i++) {
if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) {
printk(KERN_ERR PFX
@@ -111,12 +115,16 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
qdev->ndev->name, i, value[1], value[0]);
}
}
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
void ql_dump_routing_entries(struct ql_adapter *qdev)
{
int i;
u32 value;
+ i = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+ if (i)
+ return;
for (i = 0; i < 16; i++) {
value = 0;
if (ql_get_routing_reg(qdev, i, &value)) {
@@ -131,6 +139,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
qdev->ndev->name, i, value);
}
}
+ ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
}
void ql_dump_regs(struct ql_adapter *qdev)
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 9d922e2ff226..913b2a5fafc9 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -33,7 +33,6 @@
#include <linux/mm.h>
#include <linux/vmalloc.h>
-#include <linux/version.h>
#include "qlge.h"
@@ -271,7 +270,8 @@ static int ql_get_settings(struct net_device *ndev,
ecmd->advertising = ADVERTISED_10000baseT_Full;
ecmd->autoneg = AUTONEG_ENABLE;
ecmd->transceiver = XCVR_EXTERNAL;
- if ((qdev->link_status & LINK_TYPE_MASK) == LINK_TYPE_10GBASET) {
+ if ((qdev->link_status & STS_LINK_TYPE_MASK) ==
+ STS_LINK_TYPE_10GBASET) {
ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg);
ecmd->port = PORT_TP;
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 91191f761fba..170d3540f9c9 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -58,8 +58,8 @@ static const u32 default_msg =
NETIF_MSG_IFUP |
NETIF_MSG_RX_ERR |
NETIF_MSG_TX_ERR |
- NETIF_MSG_TX_QUEUED |
- NETIF_MSG_INTR | NETIF_MSG_TX_DONE | NETIF_MSG_RX_STATUS |
+/* NETIF_MSG_TX_QUEUED | */
+/* NETIF_MSG_INTR | NETIF_MSG_TX_DONE | NETIF_MSG_RX_STATUS | */
/* NETIF_MSG_PKTDATA | */
NETIF_MSG_HW | NETIF_MSG_WOL | 0;
@@ -75,7 +75,8 @@ module_param(irq_type, int, MSIX_IRQ);
MODULE_PARM_DESC(irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
static struct pci_device_id qlge_pci_tbl[] __devinitdata = {
- {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID)},
+ {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8012)},
+ {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID_8000)},
/* required last entry */
{0,}
};
@@ -247,9 +248,6 @@ int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index,
u32 offset = 0;
int status;
- status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
- if (status)
- return status;
switch (type) {
case MAC_ADDR_TYPE_MULTI_MAC:
case MAC_ADDR_TYPE_CAM_MAC:
@@ -308,7 +306,6 @@ int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index,
status = -EPERM;
}
exit:
- ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
return status;
}
@@ -321,9 +318,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
u32 offset = 0;
int status = 0;
- status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
- if (status)
- return status;
switch (type) {
case MAC_ADDR_TYPE_MULTI_MAC:
case MAC_ADDR_TYPE_CAM_MAC:
@@ -334,7 +328,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
(addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) |
(addr[5]);
- QPRINTK(qdev, IFUP, INFO,
+ QPRINTK(qdev, IFUP, DEBUG,
"Adding %s address %pM"
" at index %d in the CAM.\n",
((type ==
@@ -415,7 +409,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
status = -EPERM;
}
exit:
- ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
return status;
}
@@ -426,10 +419,6 @@ int ql_get_routing_reg(struct ql_adapter *qdev, u32 index, u32 *value)
{
int status = 0;
- status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
- if (status)
- goto exit;
-
status = ql_wait_reg_rdy(qdev, RT_IDX, RT_IDX_MW, 0);
if (status)
goto exit;
@@ -441,7 +430,6 @@ int ql_get_routing_reg(struct ql_adapter *qdev, u32 index, u32 *value)
goto exit;
*value = ql_read32(qdev, RT_DATA);
exit:
- ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
return status;
}
@@ -453,13 +441,9 @@ exit:
static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
int enable)
{
- int status;
+ int status = -EINVAL; /* Return error if no mask match. */
u32 value = 0;
- status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
- if (status)
- return status;
-
QPRINTK(qdev, IFUP, DEBUG,
"%s %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s mask %s the routing reg.\n",
(enable ? "Adding" : "Removing"),
@@ -555,7 +539,6 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
ql_write32(qdev, RT_DATA, enable ? mask : 0);
}
exit:
- ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
return status;
}
@@ -604,7 +587,6 @@ u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr)
static u32 ql_disable_completion_interrupt(struct ql_adapter *qdev, u32 intr)
{
u32 var = 0;
- unsigned long hw_flags;
struct intr_context *ctx;
/* HW disables for us if we're MSIX multi interrupts and
@@ -614,14 +596,14 @@ static u32 ql_disable_completion_interrupt(struct ql_adapter *qdev, u32 intr)
return 0;
ctx = qdev->intr_context + intr;
- spin_lock_irqsave(&qdev->hw_lock, hw_flags);
+ spin_lock(&qdev->hw_lock);
if (!atomic_read(&ctx->irq_cnt)) {
ql_write32(qdev, INTR_EN,
ctx->intr_dis_mask);
var = ql_read32(qdev, STS);
}
atomic_inc(&ctx->irq_cnt);
- spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
+ spin_unlock(&qdev->hw_lock);
return var;
}
@@ -641,6 +623,28 @@ static void ql_enable_all_completion_interrupts(struct ql_adapter *qdev)
}
+static int ql_validate_flash(struct ql_adapter *qdev, u32 size, const char *str)
+{
+ int status, i;
+ u16 csum = 0;
+ __le16 *flash = (__le16 *)&qdev->flash;
+
+ status = strncmp((char *)&qdev->flash, str, 4);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Invalid flash signature.\n");
+ return status;
+ }
+
+ for (i = 0; i < size; i++)
+ csum += le16_to_cpu(*flash++);
+
+ if (csum)
+ QPRINTK(qdev, IFUP, ERR,
+ "Invalid flash checksum, csum = 0x%.04x.\n", csum);
+
+ return csum;
+}
+
static int ql_read_flash_word(struct ql_adapter *qdev, int offset, __le32 *data)
{
int status = 0;
@@ -665,23 +669,75 @@ exit:
return status;
}
-static int ql_get_flash_params(struct ql_adapter *qdev)
+static int ql_get_8000_flash_params(struct ql_adapter *qdev)
+{
+ u32 i, size;
+ int status;
+ __le32 *p = (__le32 *)&qdev->flash;
+ u32 offset;
+
+ /* Get flash offset for function and adjust
+ * for dword access.
+ */
+ if (!qdev->func)
+ offset = FUNC0_FLASH_OFFSET / sizeof(u32);
+ else
+ offset = FUNC1_FLASH_OFFSET / sizeof(u32);
+
+ if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
+ return -ETIMEDOUT;
+
+ size = sizeof(struct flash_params_8000) / sizeof(u32);
+ for (i = 0; i < size; i++, p++) {
+ status = ql_read_flash_word(qdev, i+offset, p);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n");
+ goto exit;
+ }
+ }
+
+ status = ql_validate_flash(qdev,
+ sizeof(struct flash_params_8000) / sizeof(u16),
+ "8000");
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Invalid flash.\n");
+ status = -EINVAL;
+ goto exit;
+ }
+
+ if (!is_valid_ether_addr(qdev->flash.flash_params_8000.mac_addr)) {
+ QPRINTK(qdev, IFUP, ERR, "Invalid MAC address.\n");
+ status = -EINVAL;
+ goto exit;
+ }
+
+ memcpy(qdev->ndev->dev_addr,
+ qdev->flash.flash_params_8000.mac_addr,
+ qdev->ndev->addr_len);
+
+exit:
+ ql_sem_unlock(qdev, SEM_FLASH_MASK);
+ return status;
+}
+
+static int ql_get_8012_flash_params(struct ql_adapter *qdev)
{
int i;
int status;
__le32 *p = (__le32 *)&qdev->flash;
u32 offset = 0;
+ u32 size = sizeof(struct flash_params_8012) / sizeof(u32);
/* Second function's parameters follow the first
* function's.
*/
if (qdev->func)
- offset = sizeof(qdev->flash) / sizeof(u32);
+ offset = size;
if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
return -ETIMEDOUT;
- for (i = 0; i < sizeof(qdev->flash) / sizeof(u32); i++, p++) {
+ for (i = 0; i < size; i++, p++) {
status = ql_read_flash_word(qdev, i+offset, p);
if (status) {
QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n");
@@ -689,6 +745,25 @@ static int ql_get_flash_params(struct ql_adapter *qdev)
}
}
+
+ status = ql_validate_flash(qdev,
+ sizeof(struct flash_params_8012) / sizeof(u16),
+ "8012");
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Invalid flash.\n");
+ status = -EINVAL;
+ goto exit;
+ }
+
+ if (!is_valid_ether_addr(qdev->flash.flash_params_8012.mac_addr)) {
+ status = -EINVAL;
+ goto exit;
+ }
+
+ memcpy(qdev->ndev->dev_addr,
+ qdev->flash.flash_params_8012.mac_addr,
+ qdev->ndev->addr_len);
+
exit:
ql_sem_unlock(qdev, SEM_FLASH_MASK);
return status;
@@ -759,13 +834,25 @@ exit:
return status;
}
+static int ql_8000_port_initialize(struct ql_adapter *qdev)
+{
+ int status;
+ status = ql_mb_get_fw_state(qdev);
+ if (status)
+ goto exit;
+ /* Wake up a worker to get/set the TX/RX frame sizes. */
+ queue_delayed_work(qdev->workqueue, &qdev->mpi_port_cfg_work, 0);
+exit:
+ return status;
+}
+
/* Take the MAC Core out of reset.
* Enable statistics counting.
* Take the transmitter/receiver out of reset.
* This functionality may be done in the MPI firmware at a
* later date.
*/
-static int ql_port_initialize(struct ql_adapter *qdev)
+static int ql_8012_port_initialize(struct ql_adapter *qdev)
{
int status = 0;
u32 data;
@@ -881,7 +968,8 @@ static void ql_write_cq_idx(struct rx_ring *rx_ring)
/* Process (refill) a large buffer queue. */
static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
{
- int clean_idx = rx_ring->lbq_clean_idx;
+ u32 clean_idx = rx_ring->lbq_clean_idx;
+ u32 start_idx = clean_idx;
struct bq_desc *lbq_desc;
u64 map;
int i;
@@ -928,19 +1016,23 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
rx_ring->lbq_prod_idx += 16;
if (rx_ring->lbq_prod_idx == rx_ring->lbq_len)
rx_ring->lbq_prod_idx = 0;
+ rx_ring->lbq_free_cnt -= 16;
+ }
+
+ if (start_idx != clean_idx) {
QPRINTK(qdev, RX_STATUS, DEBUG,
"lbq: updating prod idx = %d.\n",
rx_ring->lbq_prod_idx);
ql_write_db_reg(rx_ring->lbq_prod_idx,
rx_ring->lbq_prod_idx_db_reg);
- rx_ring->lbq_free_cnt -= 16;
}
}
/* Process (refill) a small buffer queue. */
static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
{
- int clean_idx = rx_ring->sbq_clean_idx;
+ u32 clean_idx = rx_ring->sbq_clean_idx;
+ u32 start_idx = clean_idx;
struct bq_desc *sbq_desc;
u64 map;
int i;
@@ -990,13 +1082,15 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
rx_ring->sbq_prod_idx += 16;
if (rx_ring->sbq_prod_idx == rx_ring->sbq_len)
rx_ring->sbq_prod_idx = 0;
+ rx_ring->sbq_free_cnt -= 16;
+ }
+
+ if (start_idx != clean_idx) {
QPRINTK(qdev, RX_STATUS, DEBUG,
"sbq: updating prod idx = %d.\n",
rx_ring->sbq_prod_idx);
ql_write_db_reg(rx_ring->sbq_prod_idx,
rx_ring->sbq_prod_idx_db_reg);
-
- rx_ring->sbq_free_cnt -= 16;
}
}
@@ -1412,6 +1506,8 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
{
struct net_device *ndev = qdev->ndev;
struct sk_buff *skb = NULL;
+ u16 vlan_id = (le16_to_cpu(ib_mac_rsp->vlan_id) &
+ IB_MAC_IOCB_RSP_VLAN_MASK)
QL_DUMP_IB_MAC_RSP(ib_mac_rsp);
@@ -1463,18 +1559,26 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
}
}
}
+
qdev->stats.rx_packets++;
qdev->stats.rx_bytes += skb->len;
- skb->protocol = eth_type_trans(skb, ndev);
- if (qdev->vlgrp && (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V)) {
- QPRINTK(qdev, RX_STATUS, DEBUG,
- "Passing a VLAN packet upstream.\n");
- vlan_hwaccel_receive_skb(skb, qdev->vlgrp,
- le16_to_cpu(ib_mac_rsp->vlan_id));
+ skb_record_rx_queue(skb,
+ rx_ring->cq_id - qdev->rss_ring_first_cq_id);
+ if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ if (qdev->vlgrp &&
+ (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) &&
+ (vlan_id != 0))
+ vlan_gro_receive(&rx_ring->napi, qdev->vlgrp,
+ vlan_id, skb);
+ else
+ napi_gro_receive(&rx_ring->napi, skb);
} else {
- QPRINTK(qdev, RX_STATUS, DEBUG,
- "Passing a normal packet upstream.\n");
- netif_receive_skb(skb);
+ if (qdev->vlgrp &&
+ (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) &&
+ (vlan_id != 0))
+ vlan_hwaccel_receive_skb(skb, qdev->vlgrp, vlan_id);
+ else
+ netif_receive_skb(skb);
}
}
@@ -1521,14 +1625,12 @@ static void ql_process_mac_tx_intr(struct ql_adapter *qdev,
/* Fire up a handler to reset the MPI processor. */
void ql_queue_fw_error(struct ql_adapter *qdev)
{
- netif_stop_queue(qdev->ndev);
netif_carrier_off(qdev->ndev);
queue_delayed_work(qdev->workqueue, &qdev->mpi_reset_work, 0);
}
void ql_queue_asic_error(struct ql_adapter *qdev)
{
- netif_stop_queue(qdev->ndev);
netif_carrier_off(qdev->ndev);
ql_disable_interrupts(qdev);
/* Clear adapter up bit to signal the recovery
@@ -1583,6 +1685,7 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
struct ob_mac_iocb_rsp *net_rsp = NULL;
int count = 0;
+ struct tx_ring *tx_ring;
/* While there are entries in the completion queue. */
while (prod != rx_ring->cnsmr_idx) {
@@ -1608,15 +1711,16 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
}
ql_write_cq_idx(rx_ring);
- if (netif_queue_stopped(qdev->ndev) && net_rsp != NULL) {
- struct tx_ring *tx_ring = &qdev->tx_ring[net_rsp->txq_idx];
+ tx_ring = &qdev->tx_ring[net_rsp->txq_idx];
+ if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id) &&
+ net_rsp != NULL) {
if (atomic_read(&tx_ring->queue_stopped) &&
(atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4)))
/*
* The queue got stopped because the tx_ring was full.
* Wake it up, because it's now at least 25% empty.
*/
- netif_wake_queue(qdev->ndev);
+ netif_wake_subqueue(qdev->ndev, tx_ring->wq_id);
}
return count;
@@ -1677,7 +1781,7 @@ static int ql_napi_poll_msix(struct napi_struct *napi, int budget)
rx_ring->cq_id);
if (work_done < budget) {
- __netif_rx_complete(napi);
+ napi_complete(napi);
ql_enable_completion_interrupt(qdev, rx_ring->irq);
}
return work_done;
@@ -1703,19 +1807,29 @@ static void ql_vlan_rx_add_vid(struct net_device *ndev, u16 vid)
{
struct ql_adapter *qdev = netdev_priv(ndev);
u32 enable_bit = MAC_ADDR_E;
+ int status;
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ return;
spin_lock(&qdev->hw_lock);
if (ql_set_mac_addr_reg
(qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) {
QPRINTK(qdev, IFUP, ERR, "Failed to init vlan address.\n");
}
spin_unlock(&qdev->hw_lock);
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
{
struct ql_adapter *qdev = netdev_priv(ndev);
u32 enable_bit = 0;
+ int status;
+
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ return;
spin_lock(&qdev->hw_lock);
if (ql_set_mac_addr_reg
@@ -1723,6 +1837,7 @@ static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
QPRINTK(qdev, IFUP, ERR, "Failed to clear vlan address.\n");
}
spin_unlock(&qdev->hw_lock);
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
@@ -1762,7 +1877,7 @@ static irqreturn_t qlge_msix_tx_isr(int irq, void *dev_id)
static irqreturn_t qlge_msix_rx_isr(int irq, void *dev_id)
{
struct rx_ring *rx_ring = dev_id;
- netif_rx_schedule(&rx_ring->napi);
+ napi_schedule(&rx_ring->napi);
return IRQ_HANDLED;
}
@@ -1848,7 +1963,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
&rx_ring->rx_work,
0);
else
- netif_rx_schedule(&rx_ring->napi);
+ napi_schedule(&rx_ring->napi);
work_done++;
}
}
@@ -1937,7 +2052,7 @@ static int qlge_send(struct sk_buff *skb, struct net_device *ndev)
struct ql_adapter *qdev = netdev_priv(ndev);
int tso;
struct tx_ring *tx_ring;
- u32 tx_ring_idx = (u32) QL_TXQ_IDX(qdev, skb);
+ u32 tx_ring_idx = (u32) skb->queue_mapping;
tx_ring = &qdev->tx_ring[tx_ring_idx];
@@ -1948,7 +2063,7 @@ static int qlge_send(struct sk_buff *skb, struct net_device *ndev)
QPRINTK(qdev, TX_QUEUED, INFO,
"%s: shutting down tx queue %d du to lack of resources.\n",
__func__, tx_ring_idx);
- netif_stop_queue(ndev);
+ netif_stop_subqueue(ndev, tx_ring->wq_id);
atomic_inc(&tx_ring->queue_stopped);
return NETDEV_TX_BUSY;
}
@@ -2029,6 +2144,7 @@ static int ql_alloc_shadow_space(struct ql_adapter *qdev)
"Allocation of RX shadow space failed.\n");
return -ENOMEM;
}
+ memset(qdev->rx_ring_shadow_reg_area, 0, PAGE_SIZE);
qdev->tx_ring_shadow_reg_area =
pci_alloc_consistent(qdev->pdev, PAGE_SIZE,
&qdev->tx_ring_shadow_reg_dma);
@@ -2037,6 +2153,7 @@ static int ql_alloc_shadow_space(struct ql_adapter *qdev)
"Allocation of TX shadow space failed.\n");
goto err_wqp_sh_area;
}
+ memset(qdev->tx_ring_shadow_reg_area, 0, PAGE_SIZE);
return 0;
err_wqp_sh_area:
@@ -2121,47 +2238,6 @@ static void ql_free_lbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring
}
}
-/*
- * Allocate and map a page for each element of the lbq.
- */
-static int ql_alloc_lbq_buffers(struct ql_adapter *qdev,
- struct rx_ring *rx_ring)
-{
- int i;
- struct bq_desc *lbq_desc;
- u64 map;
- __le64 *bq = rx_ring->lbq_base;
-
- for (i = 0; i < rx_ring->lbq_len; i++) {
- lbq_desc = &rx_ring->lbq[i];
- memset(lbq_desc, 0, sizeof(lbq_desc));
- lbq_desc->addr = bq;
- lbq_desc->index = i;
- lbq_desc->p.lbq_page = alloc_page(GFP_ATOMIC);
- if (unlikely(!lbq_desc->p.lbq_page)) {
- QPRINTK(qdev, IFUP, ERR, "failed alloc_page().\n");
- goto mem_error;
- } else {
- map = pci_map_page(qdev->pdev,
- lbq_desc->p.lbq_page,
- 0, PAGE_SIZE, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(qdev->pdev, map)) {
- QPRINTK(qdev, IFUP, ERR,
- "PCI mapping failed.\n");
- goto mem_error;
- }
- pci_unmap_addr_set(lbq_desc, mapaddr, map);
- pci_unmap_len_set(lbq_desc, maplen, PAGE_SIZE);
- *lbq_desc->addr = cpu_to_le64(map);
- }
- bq++;
- }
- return 0;
-mem_error:
- ql_free_lbq_buffers(qdev, rx_ring);
- return -ENOMEM;
-}
-
static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring)
{
int i;
@@ -2184,63 +2260,72 @@ static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring
}
}
-/* Allocate and map an skb for each element of the sbq. */
-static int ql_alloc_sbq_buffers(struct ql_adapter *qdev,
+/* Free all large and small rx buffers associated
+ * with the completion queues for this device.
+ */
+static void ql_free_rx_buffers(struct ql_adapter *qdev)
+{
+ int i;
+ struct rx_ring *rx_ring;
+
+ for (i = 0; i < qdev->rx_ring_count; i++) {
+ rx_ring = &qdev->rx_ring[i];
+ if (rx_ring->lbq)
+ ql_free_lbq_buffers(qdev, rx_ring);
+ if (rx_ring->sbq)
+ ql_free_sbq_buffers(qdev, rx_ring);
+ }
+}
+
+static void ql_alloc_rx_buffers(struct ql_adapter *qdev)
+{
+ struct rx_ring *rx_ring;
+ int i;
+
+ for (i = 0; i < qdev->rx_ring_count; i++) {
+ rx_ring = &qdev->rx_ring[i];
+ if (rx_ring->type != TX_Q)
+ ql_update_buffer_queues(qdev, rx_ring);
+ }
+}
+
+static void ql_init_lbq_ring(struct ql_adapter *qdev,
+ struct rx_ring *rx_ring)
+{
+ int i;
+ struct bq_desc *lbq_desc;
+ __le64 *bq = rx_ring->lbq_base;
+
+ memset(rx_ring->lbq, 0, rx_ring->lbq_len * sizeof(struct bq_desc));
+ for (i = 0; i < rx_ring->lbq_len; i++) {
+ lbq_desc = &rx_ring->lbq[i];
+ memset(lbq_desc, 0, sizeof(*lbq_desc));
+ lbq_desc->index = i;
+ lbq_desc->addr = bq;
+ bq++;
+ }
+}
+
+static void ql_init_sbq_ring(struct ql_adapter *qdev,
struct rx_ring *rx_ring)
{
int i;
struct bq_desc *sbq_desc;
- struct sk_buff *skb;
- u64 map;
__le64 *bq = rx_ring->sbq_base;
+ memset(rx_ring->sbq, 0, rx_ring->sbq_len * sizeof(struct bq_desc));
for (i = 0; i < rx_ring->sbq_len; i++) {
sbq_desc = &rx_ring->sbq[i];
- memset(sbq_desc, 0, sizeof(sbq_desc));
+ memset(sbq_desc, 0, sizeof(*sbq_desc));
sbq_desc->index = i;
sbq_desc->addr = bq;
- skb = netdev_alloc_skb(qdev->ndev, rx_ring->sbq_buf_size);
- if (unlikely(!skb)) {
- /* Better luck next round */
- QPRINTK(qdev, IFUP, ERR,
- "small buff alloc failed for %d bytes at index %d.\n",
- rx_ring->sbq_buf_size, i);
- goto mem_err;
- }
- skb_reserve(skb, QLGE_SB_PAD);
- sbq_desc->p.skb = skb;
- /*
- * Map only half the buffer. Because the
- * other half may get some data copied to it
- * when the completion arrives.
- */
- map = pci_map_single(qdev->pdev,
- skb->data,
- rx_ring->sbq_buf_size / 2,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(qdev->pdev, map)) {
- QPRINTK(qdev, IFUP, ERR, "PCI mapping failed.\n");
- goto mem_err;
- }
- pci_unmap_addr_set(sbq_desc, mapaddr, map);
- pci_unmap_len_set(sbq_desc, maplen, rx_ring->sbq_buf_size / 2);
- *sbq_desc->addr = cpu_to_le64(map);
bq++;
}
- return 0;
-mem_err:
- ql_free_sbq_buffers(qdev, rx_ring);
- return -ENOMEM;
}
static void ql_free_rx_resources(struct ql_adapter *qdev,
struct rx_ring *rx_ring)
{
- if (rx_ring->sbq_len)
- ql_free_sbq_buffers(qdev, rx_ring);
- if (rx_ring->lbq_len)
- ql_free_lbq_buffers(qdev, rx_ring);
-
/* Free the small buffer queue. */
if (rx_ring->sbq_base) {
pci_free_consistent(qdev->pdev,
@@ -2318,11 +2403,7 @@ static int ql_alloc_rx_resources(struct ql_adapter *qdev,
goto err_mem;
}
- if (ql_alloc_sbq_buffers(qdev, rx_ring)) {
- QPRINTK(qdev, IFUP, ERR,
- "Small buffer allocation failed.\n");
- goto err_mem;
- }
+ ql_init_sbq_ring(qdev, rx_ring);
}
if (rx_ring->lbq_len) {
@@ -2350,14 +2431,7 @@ static int ql_alloc_rx_resources(struct ql_adapter *qdev,
goto err_mem;
}
- /*
- * Allocate the buffers.
- */
- if (ql_alloc_lbq_buffers(qdev, rx_ring)) {
- QPRINTK(qdev, IFUP, ERR,
- "Large buffer allocation failed.\n");
- goto err_mem;
- }
+ ql_init_lbq_ring(qdev, rx_ring);
}
return 0;
@@ -2451,6 +2525,7 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
qdev->doorbell_area + (DB_PAGE_SIZE * (128 + rx_ring->cq_id));
int err = 0;
u16 bq_len;
+ u64 tmp;
/* Set up the shadow registers for this ring. */
rx_ring->prod_idx_sh_reg = shadow_reg;
@@ -2496,7 +2571,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
FLAGS_LI; /* Load irq delay values */
if (rx_ring->lbq_len) {
cqicb->flags |= FLAGS_LL; /* Load lbq values */
- *((u64 *) rx_ring->lbq_base_indirect) = rx_ring->lbq_base_dma;
+ tmp = (u64)rx_ring->lbq_base_dma;;
+ *((__le64 *) rx_ring->lbq_base_indirect) = cpu_to_le64(tmp);
cqicb->lbq_addr =
cpu_to_le64(rx_ring->lbq_base_indirect_dma);
bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 :
@@ -2505,25 +2581,26 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
bq_len = (rx_ring->lbq_len == 65536) ? 0 :
(u16) rx_ring->lbq_len;
cqicb->lbq_len = cpu_to_le16(bq_len);
- rx_ring->lbq_prod_idx = rx_ring->lbq_len - 16;
+ rx_ring->lbq_prod_idx = 0;
rx_ring->lbq_curr_idx = 0;
- rx_ring->lbq_clean_idx = rx_ring->lbq_prod_idx;
- rx_ring->lbq_free_cnt = 16;
+ rx_ring->lbq_clean_idx = 0;
+ rx_ring->lbq_free_cnt = rx_ring->lbq_len;
}
if (rx_ring->sbq_len) {
cqicb->flags |= FLAGS_LS; /* Load sbq values */
- *((u64 *) rx_ring->sbq_base_indirect) = rx_ring->sbq_base_dma;
+ tmp = (u64)rx_ring->sbq_base_dma;;
+ *((__le64 *) rx_ring->sbq_base_indirect) = cpu_to_le64(tmp);
cqicb->sbq_addr =
cpu_to_le64(rx_ring->sbq_base_indirect_dma);
cqicb->sbq_buf_size =
- cpu_to_le16(((rx_ring->sbq_buf_size / 2) + 8) & 0xfffffff8);
+ cpu_to_le16((u16)(rx_ring->sbq_buf_size/2));
bq_len = (rx_ring->sbq_len == 65536) ? 0 :
(u16) rx_ring->sbq_len;
cqicb->sbq_len = cpu_to_le16(bq_len);
- rx_ring->sbq_prod_idx = rx_ring->sbq_len - 16;
+ rx_ring->sbq_prod_idx = 0;
rx_ring->sbq_curr_idx = 0;
- rx_ring->sbq_clean_idx = rx_ring->sbq_prod_idx;
- rx_ring->sbq_free_cnt = 16;
+ rx_ring->sbq_clean_idx = 0;
+ rx_ring->sbq_free_cnt = rx_ring->sbq_len;
}
switch (rx_ring->type) {
case TX_Q:
@@ -2569,24 +2646,13 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
QPRINTK(qdev, IFUP, DEBUG, "Invalid rx_ring->type = %d.\n",
rx_ring->type);
}
- QPRINTK(qdev, IFUP, INFO, "Initializing rx work queue.\n");
+ QPRINTK(qdev, IFUP, DEBUG, "Initializing rx work queue.\n");
err = ql_write_cfg(qdev, cqicb, sizeof(struct cqicb),
CFG_LCQ, rx_ring->cq_id);
if (err) {
QPRINTK(qdev, IFUP, ERR, "Failed to load CQICB.\n");
return err;
}
- QPRINTK(qdev, IFUP, INFO, "Successfully loaded CQICB.\n");
- /*
- * Advance the producer index for the buffer queues.
- */
- wmb();
- if (rx_ring->lbq_len)
- ql_write_db_reg(rx_ring->lbq_prod_idx,
- rx_ring->lbq_prod_idx_db_reg);
- if (rx_ring->sbq_len)
- ql_write_db_reg(rx_ring->sbq_prod_idx,
- rx_ring->sbq_prod_idx_db_reg);
return err;
}
@@ -2633,7 +2699,7 @@ static int ql_start_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring)
QPRINTK(qdev, IFUP, ERR, "Failed to load tx_ring.\n");
return err;
}
- QPRINTK(qdev, IFUP, INFO, "Successfully loaded WQICB.\n");
+ QPRINTK(qdev, IFUP, DEBUG, "Successfully loaded WQICB.\n");
return err;
}
@@ -2675,7 +2741,7 @@ static void ql_enable_msix(struct ql_adapter *qdev)
(qdev->pdev, qdev->msi_x_entry, qdev->rx_ring_count)) {
set_bit(QL_MSIX_ENABLED, &qdev->flags);
qdev->intr_count = qdev->rx_ring_count;
- QPRINTK(qdev, IFUP, INFO,
+ QPRINTK(qdev, IFUP, DEBUG,
"MSI-X Enabled, got %d vectors.\n",
qdev->intr_count);
return;
@@ -2802,11 +2868,11 @@ static void ql_free_irq(struct ql_adapter *qdev)
if (test_bit(QL_MSIX_ENABLED, &qdev->flags)) {
free_irq(qdev->msi_x_entry[i].vector,
&qdev->rx_ring[i]);
- QPRINTK(qdev, IFDOWN, ERR,
+ QPRINTK(qdev, IFDOWN, DEBUG,
"freeing msix interrupt %d.\n", i);
} else {
free_irq(qdev->pdev->irq, &qdev->rx_ring[0]);
- QPRINTK(qdev, IFDOWN, ERR,
+ QPRINTK(qdev, IFDOWN, DEBUG,
"freeing msi interrupt %d.\n", i);
}
}
@@ -2837,7 +2903,7 @@ static int ql_request_irq(struct ql_adapter *qdev)
i);
goto err_irq;
} else {
- QPRINTK(qdev, IFUP, INFO,
+ QPRINTK(qdev, IFUP, DEBUG,
"Hooked intr %d, queue type %s%s%s, with name %s.\n",
i,
qdev->rx_ring[i].type ==
@@ -2912,14 +2978,14 @@ static int ql_start_rss(struct ql_adapter *qdev)
get_random_bytes((void *)&ricb->ipv6_hash_key[0], 40);
get_random_bytes((void *)&ricb->ipv4_hash_key[0], 16);
- QPRINTK(qdev, IFUP, INFO, "Initializing RSS.\n");
+ QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n");
status = ql_write_cfg(qdev, ricb, sizeof(ricb), CFG_LR, 0);
if (status) {
QPRINTK(qdev, IFUP, ERR, "Failed to load RICB.\n");
return status;
}
- QPRINTK(qdev, IFUP, INFO, "Successfully loaded RICB.\n");
+ QPRINTK(qdev, IFUP, DEBUG, "Successfully loaded RICB.\n");
return status;
}
@@ -2929,13 +2995,17 @@ static int ql_route_initialize(struct ql_adapter *qdev)
int status = 0;
int i;
+ status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+ if (status)
+ return status;
+
/* Clear all the entries in the routing table. */
for (i = 0; i < 16; i++) {
status = ql_set_routing_reg(qdev, i, 0, 0);
if (status) {
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for CAM packets.\n");
- return status;
+ goto exit;
}
}
@@ -2943,13 +3013,13 @@ static int ql_route_initialize(struct ql_adapter *qdev)
if (status) {
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for error packets.\n");
- return status;
+ goto exit;
}
status = ql_set_routing_reg(qdev, RT_IDX_BCAST_SLOT, RT_IDX_BCAST, 1);
if (status) {
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for broadcast packets.\n");
- return status;
+ goto exit;
}
/* If we have more than one inbound queue, then turn on RSS in the
* routing block.
@@ -2960,17 +3030,39 @@ static int ql_route_initialize(struct ql_adapter *qdev)
if (status) {
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for MATCH RSS packets.\n");
- return status;
+ goto exit;
}
}
status = ql_set_routing_reg(qdev, RT_IDX_CAM_HIT_SLOT,
RT_IDX_CAM_HIT, 1);
- if (status) {
+ if (status)
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for CAM packets.\n");
+exit:
+ ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
+ return status;
+}
+
+int ql_cam_route_initialize(struct ql_adapter *qdev)
+{
+ int status;
+
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ return status;
+ status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr,
+ MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n");
return status;
}
+
+ status = ql_route_initialize(qdev);
+ if (status)
+ QPRINTK(qdev, IFUP, ERR, "Failed to init routing table.\n");
+
return status;
}
@@ -3038,28 +3130,24 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
}
}
- status = ql_port_initialize(qdev);
- if (status) {
- QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
- return status;
- }
+ /* Initialize the port and set the max framesize. */
+ status = qdev->nic_ops->port_initialize(qdev);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
+ return status;
+ }
- status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr,
- MAC_ADDR_TYPE_CAM_MAC, qdev->func);
+ /* Set up the MAC address and frame routing filter. */
+ status = ql_cam_route_initialize(qdev);
if (status) {
- QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n");
- return status;
- }
-
- status = ql_route_initialize(qdev);
- if (status) {
- QPRINTK(qdev, IFUP, ERR, "Failed to init routing table.\n");
+ QPRINTK(qdev, IFUP, ERR,
+ "Failed to init CAM/Routing tables.\n");
return status;
}
/* Start NAPI for the RSS queues. */
for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++) {
- QPRINTK(qdev, IFUP, INFO, "Enabling NAPI for rx_ring[%d].\n",
+ QPRINTK(qdev, IFUP, DEBUG, "Enabling NAPI for rx_ring[%d].\n",
i);
napi_enable(&qdev->rx_ring[i].napi);
}
@@ -3071,36 +3159,23 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
static int ql_adapter_reset(struct ql_adapter *qdev)
{
u32 value;
- int max_wait_time;
int status = 0;
- int resetCnt = 0;
+ unsigned long end_jiffies = jiffies +
+ max((unsigned long)1, usecs_to_jiffies(30));
-#define MAX_RESET_CNT 1
-issueReset:
- resetCnt++;
- QPRINTK(qdev, IFDOWN, DEBUG, "Issue soft reset to chip.\n");
ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR);
- /* Wait for reset to complete. */
- max_wait_time = 3;
- QPRINTK(qdev, IFDOWN, DEBUG, "Wait %d seconds for reset to complete.\n",
- max_wait_time);
+
do {
value = ql_read32(qdev, RST_FO);
if ((value & RST_FO_FR) == 0)
break;
+ cpu_relax();
+ } while (time_before(jiffies, end_jiffies));
- ssleep(1);
- } while ((--max_wait_time));
if (value & RST_FO_FR) {
QPRINTK(qdev, IFDOWN, ERR,
- "Stuck in SoftReset: FSC_SR:0x%08x\n", value);
- if (resetCnt < MAX_RESET_CNT)
- goto issueReset;
- }
- if (max_wait_time == 0) {
- status = -ETIMEDOUT;
- QPRINTK(qdev, IFDOWN, ERR,
"ETIMEOUT!!! errored out of resetting the chip!\n");
+ status = -ETIMEDOUT;
}
return status;
@@ -3123,12 +3198,10 @@ static void ql_display_dev_info(struct net_device *ndev)
static int ql_adapter_down(struct ql_adapter *qdev)
{
- struct net_device *ndev = qdev->ndev;
int i, status = 0;
struct rx_ring *rx_ring;
- netif_stop_queue(ndev);
- netif_carrier_off(ndev);
+ netif_carrier_off(qdev->ndev);
/* Don't kill the reset worker thread if we
* are in the process of recovery.
@@ -3137,6 +3210,8 @@ static int ql_adapter_down(struct ql_adapter *qdev)
cancel_delayed_work_sync(&qdev->asic_reset_work);
cancel_delayed_work_sync(&qdev->mpi_reset_work);
cancel_delayed_work_sync(&qdev->mpi_work);
+ cancel_delayed_work_sync(&qdev->mpi_idc_work);
+ cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
/* The default queue at index 0 is always processed in
* a workqueue.
@@ -3171,6 +3246,8 @@ static int ql_adapter_down(struct ql_adapter *qdev)
for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++)
netif_napi_del(&qdev->rx_ring[i].napi);
+ ql_free_rx_buffers(qdev);
+
spin_lock(&qdev->hw_lock);
status = ql_adapter_reset(qdev);
if (status)
@@ -3184,21 +3261,19 @@ static int ql_adapter_up(struct ql_adapter *qdev)
{
int err = 0;
- spin_lock(&qdev->hw_lock);
err = ql_adapter_initialize(qdev);
if (err) {
QPRINTK(qdev, IFUP, INFO, "Unable to initialize adapter.\n");
spin_unlock(&qdev->hw_lock);
goto err_init;
}
- spin_unlock(&qdev->hw_lock);
set_bit(QL_ADAPTER_UP, &qdev->flags);
+ ql_alloc_rx_buffers(qdev);
+ if ((ql_read32(qdev, STS) & qdev->port_init))
+ netif_carrier_on(qdev->ndev);
ql_enable_interrupts(qdev);
ql_enable_all_completion_interrupts(qdev);
- if ((ql_read32(qdev, STS) & qdev->port_init)) {
- netif_carrier_on(qdev->ndev);
- netif_start_queue(qdev->ndev);
- }
+ netif_tx_start_all_queues(qdev->ndev);
return 0;
err_init:
@@ -3206,28 +3281,6 @@ err_init:
return err;
}
-static int ql_cycle_adapter(struct ql_adapter *qdev)
-{
- int status;
-
- status = ql_adapter_down(qdev);
- if (status)
- goto error;
-
- status = ql_adapter_up(qdev);
- if (status)
- goto error;
-
- return status;
-error:
- QPRINTK(qdev, IFUP, ALERT,
- "Driver up/down cycle failed, closing device\n");
- rtnl_lock();
- dev_close(qdev->ndev);
- rtnl_unlock();
- return status;
-}
-
static void ql_release_adapter_resources(struct ql_adapter *qdev)
{
ql_free_mem_resources(qdev);
@@ -3308,6 +3361,7 @@ static int ql_configure_rings(struct ql_adapter *qdev)
* completion handler rx_rings.
*/
qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count + 1;
+ netif_set_gso_max_size(qdev->ndev, 65536);
for (i = 0; i < qdev->tx_ring_count; i++) {
tx_ring = &qdev->tx_ring[i];
@@ -3414,6 +3468,8 @@ static int qlge_change_mtu(struct net_device *ndev, int new_mtu)
if (ndev->mtu == 1500 && new_mtu == 9000) {
QPRINTK(qdev, IFUP, ERR, "Changing to jumbo MTU.\n");
+ queue_delayed_work(qdev->workqueue,
+ &qdev->mpi_port_cfg_work, 0);
} else if (ndev->mtu == 9000 && new_mtu == 1500) {
QPRINTK(qdev, IFUP, ERR, "Changing to normal MTU.\n");
} else if ((ndev->mtu == 1500 && new_mtu == 1500) ||
@@ -3436,8 +3492,11 @@ static void qlge_set_multicast_list(struct net_device *ndev)
{
struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
struct dev_mc_list *mc_ptr;
- int i;
+ int i, status;
+ status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+ if (status)
+ return;
spin_lock(&qdev->hw_lock);
/*
* Set or clear promiscuous mode if a
@@ -3493,14 +3552,19 @@ static void qlge_set_multicast_list(struct net_device *ndev)
}
if (ndev->mc_count) {
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ goto exit;
for (i = 0, mc_ptr = ndev->mc_list; mc_ptr;
i++, mc_ptr = mc_ptr->next)
if (ql_set_mac_addr_reg(qdev, (u8 *) mc_ptr->dmi_addr,
MAC_ADDR_TYPE_MULTI_MAC, i)) {
QPRINTK(qdev, HW, ERR,
"Failed to loadmulticast address.\n");
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
goto exit;
}
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
if (ql_set_routing_reg
(qdev, RT_IDX_MCAST_MATCH_SLOT, RT_IDX_MCAST_MATCH, 1)) {
QPRINTK(qdev, HW, ERR,
@@ -3511,13 +3575,14 @@ static void qlge_set_multicast_list(struct net_device *ndev)
}
exit:
spin_unlock(&qdev->hw_lock);
+ ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
}
static int qlge_set_mac_address(struct net_device *ndev, void *p)
{
struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
struct sockaddr *addr = p;
- int ret = 0;
+ int status;
if (netif_running(ndev))
return -EBUSY;
@@ -3526,15 +3591,17 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p)
return -EADDRNOTAVAIL;
memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ return status;
spin_lock(&qdev->hw_lock);
- if (ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr,
- MAC_ADDR_TYPE_CAM_MAC, qdev->func)) {/* Unicast */
- QPRINTK(qdev, HW, ERR, "Failed to load MAC address.\n");
- ret = -1;
- }
+ status = ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr,
+ MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
spin_unlock(&qdev->hw_lock);
-
- return ret;
+ if (status)
+ QPRINTK(qdev, HW, ERR, "Failed to load MAC address.\n");
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
+ return status;
}
static void qlge_tx_timeout(struct net_device *ndev)
@@ -3547,9 +3614,37 @@ static void ql_asic_reset_work(struct work_struct *work)
{
struct ql_adapter *qdev =
container_of(work, struct ql_adapter, asic_reset_work.work);
- ql_cycle_adapter(qdev);
+ int status;
+
+ status = ql_adapter_down(qdev);
+ if (status)
+ goto error;
+
+ status = ql_adapter_up(qdev);
+ if (status)
+ goto error;
+
+ return;
+error:
+ QPRINTK(qdev, IFUP, ALERT,
+ "Driver up/down cycle failed, closing device\n");
+ rtnl_lock();
+ set_bit(QL_ADAPTER_UP, &qdev->flags);
+ dev_close(qdev->ndev);
+ rtnl_unlock();
}
+static struct nic_operations qla8012_nic_ops = {
+ .get_flash = ql_get_8012_flash_params,
+ .port_initialize = ql_8012_port_initialize,
+};
+
+static struct nic_operations qla8000_nic_ops = {
+ .get_flash = ql_get_8000_flash_params,
+ .port_initialize = ql_8000_port_initialize,
+};
+
+
static void ql_get_board_info(struct ql_adapter *qdev)
{
qdev->func =
@@ -3568,6 +3663,11 @@ static void ql_get_board_info(struct ql_adapter *qdev)
qdev->mailbox_out = PROC_ADDR_MPI_RISC | PROC_ADDR_FUNC0_MBO;
}
qdev->chip_rev_id = ql_read32(qdev, REV_ID);
+ qdev->device_id = qdev->pdev->device;
+ if (qdev->device_id == QLGE_DEVICE_ID_8012)
+ qdev->nic_ops = &qla8012_nic_ops;
+ else if (qdev->device_id == QLGE_DEVICE_ID_8000)
+ qdev->nic_ops = &qla8000_nic_ops;
}
static void ql_release_all(struct pci_dev *pdev)
@@ -3660,24 +3760,20 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
goto err_out;
}
- ql_get_board_info(qdev);
qdev->ndev = ndev;
qdev->pdev = pdev;
+ ql_get_board_info(qdev);
qdev->msg_enable = netif_msg_init(debug, default_msg);
spin_lock_init(&qdev->hw_lock);
spin_lock_init(&qdev->stats_lock);
/* make sure the EEPROM is good */
- err = ql_get_flash_params(qdev);
+ err = qdev->nic_ops->get_flash(qdev);
if (err) {
dev_err(&pdev->dev, "Invalid FLASH.\n");
goto err_out;
}
- if (!is_valid_ether_addr(qdev->flash.mac_addr))
- goto err_out;
-
- memcpy(ndev->dev_addr, qdev->flash.mac_addr, ndev->addr_len);
memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
/* Set up the default ring sizes. */
@@ -3700,6 +3796,10 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
INIT_DELAYED_WORK(&qdev->asic_reset_work, ql_asic_reset_work);
INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work);
INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work);
+ INIT_DELAYED_WORK(&qdev->mpi_port_cfg_work, ql_mpi_port_cfg_work);
+ INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
+ mutex_init(&qdev->mpi_mutex);
+ init_completion(&qdev->ide_completion);
if (!cards_found) {
dev_info(&pdev->dev, "%s\n", DRV_STRING);
@@ -3737,7 +3837,8 @@ static int __devinit qlge_probe(struct pci_dev *pdev,
static int cards_found = 0;
int err = 0;
- ndev = alloc_etherdev(sizeof(struct ql_adapter));
+ ndev = alloc_etherdev_mq(sizeof(struct ql_adapter),
+ min(MAX_CPUS, (int)num_online_cpus()));
if (!ndev)
return -ENOMEM;
@@ -3757,6 +3858,7 @@ static int __devinit qlge_probe(struct pci_dev *pdev,
| NETIF_F_TSO_ECN
| NETIF_F_HW_VLAN_TX
| NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER);
+ ndev->features |= NETIF_F_GRO;
if (test_bit(QL_DMA64, &qdev->flags))
ndev->features |= NETIF_F_HIGHDMA;
@@ -3779,7 +3881,6 @@ static int __devinit qlge_probe(struct pci_dev *pdev,
return err;
}
netif_carrier_off(ndev);
- netif_stop_queue(ndev);
ql_display_dev_info(ndev);
cards_found++;
return 0;
@@ -3833,7 +3934,6 @@ static pci_ers_result_t qlge_io_slot_reset(struct pci_dev *pdev)
pci_set_master(pdev);
netif_carrier_off(ndev);
- netif_stop_queue(ndev);
ql_adapter_reset(qdev);
/* Make sure the EEPROM is good */
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index fa31891b6e62..9f81b797f10b 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -1,6 +1,26 @@
#include "qlge.h"
-static int ql_read_mbox_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
+static void ql_display_mb_sts(struct ql_adapter *qdev,
+ struct mbox_params *mbcp)
+{
+ int i;
+ static char *err_sts[] = {
+ "Command Complete",
+ "Command Not Supported",
+ "Host Interface Error",
+ "Checksum Error",
+ "Unused Completion Status",
+ "Test Failed",
+ "Command Parameter Error"};
+
+ QPRINTK(qdev, DRV, DEBUG, "%s.\n",
+ err_sts[mbcp->mbox_out[0] & 0x0000000f]);
+ for (i = 0; i < mbcp->out_count; i++)
+ QPRINTK(qdev, DRV, DEBUG, "mbox_out[%d] = 0x%.08x.\n",
+ i, mbcp->mbox_out[i]);
+}
+
+int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
{
int status;
/* wait for reg to come ready */
@@ -19,6 +39,32 @@ exit:
return status;
}
+int ql_write_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 data)
+{
+ int status = 0;
+ /* wait for reg to come ready */
+ status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR);
+ if (status)
+ goto exit;
+ /* write the data to the data reg */
+ ql_write32(qdev, PROC_DATA, data);
+ /* trigger the write */
+ ql_write32(qdev, PROC_ADDR, reg);
+ /* wait for reg to come ready */
+ status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR);
+ if (status)
+ goto exit;
+exit:
+ return status;
+}
+
+int ql_soft_reset_mpi_risc(struct ql_adapter *qdev)
+{
+ int status;
+ status = ql_write_mpi_reg(qdev, 0x00001010, 1);
+ return status;
+}
+
static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
int i, status;
@@ -28,7 +74,7 @@ static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
return -EBUSY;
for (i = 0; i < mbcp->out_count; i++) {
status =
- ql_read_mbox_reg(qdev, qdev->mailbox_out + i,
+ ql_read_mpi_reg(qdev, qdev->mailbox_out + i,
&mbcp->mbox_out[i]);
if (status) {
QPRINTK(qdev, DRV, ERR, "Failed mailbox read.\n");
@@ -39,102 +85,762 @@ static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
return status;
}
+/* Wait for a single mailbox command to complete.
+ * Returns zero on success.
+ */
+static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev)
+{
+ int count = 50; /* TODO: arbitrary for now. */
+ u32 value;
+
+ do {
+ value = ql_read32(qdev, STS);
+ if (value & STS_PI)
+ return 0;
+ udelay(UDELAY_DELAY); /* 10us */
+ } while (--count);
+ return -ETIMEDOUT;
+}
+
+/* Execute a single mailbox command.
+ * Caller must hold PROC_ADDR semaphore.
+ */
+static int ql_exec_mb_cmd(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int i, status;
+
+ /*
+ * Make sure there's nothing pending.
+ * This shouldn't happen.
+ */
+ if (ql_read32(qdev, CSR) & CSR_HRI)
+ return -EIO;
+
+ status = ql_sem_spinlock(qdev, SEM_PROC_REG_MASK);
+ if (status)
+ return status;
+
+ /*
+ * Fill the outbound mailboxes.
+ */
+ for (i = 0; i < mbcp->in_count; i++) {
+ status = ql_write_mpi_reg(qdev, qdev->mailbox_in + i,
+ mbcp->mbox_in[i]);
+ if (status)
+ goto end;
+ }
+ /*
+ * Wake up the MPI firmware.
+ */
+ ql_write32(qdev, CSR, CSR_CMD_SET_H2R_INT);
+end:
+ ql_sem_unlock(qdev, SEM_PROC_REG_MASK);
+ return status;
+}
+
+/* We are being asked by firmware to accept
+ * a change to the port. This is only
+ * a change to max frame sizes (Tx/Rx), pause
+ * paramters, or loopback mode. We wake up a worker
+ * to handler processing this since a mailbox command
+ * will need to be sent to ACK the request.
+ */
+static int ql_idc_req_aen(struct ql_adapter *qdev)
+{
+ int status;
+ struct mbox_params *mbcp = &qdev->idc_mbc;
+
+ QPRINTK(qdev, DRV, ERR, "Enter!\n");
+ /* Get the status data and start up a thread to
+ * handle the request.
+ */
+ mbcp = &qdev->idc_mbc;
+ mbcp->out_count = 4;
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Could not read MPI, resetting ASIC!\n");
+ ql_queue_asic_error(qdev);
+ } else {
+ /* Begin polled mode early so
+ * we don't get another interrupt
+ * when we leave mpi_worker.
+ */
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+ queue_delayed_work(qdev->workqueue, &qdev->mpi_idc_work, 0);
+ }
+ return status;
+}
+
+/* Process an inter-device event completion.
+ * If good, signal the caller's completion.
+ */
+static int ql_idc_cmplt_aen(struct ql_adapter *qdev)
+{
+ int status;
+ struct mbox_params *mbcp = &qdev->idc_mbc;
+ mbcp->out_count = 4;
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Could not read MPI, resetting RISC!\n");
+ ql_queue_fw_error(qdev);
+ } else
+ /* Wake up the sleeping mpi_idc_work thread that is
+ * waiting for this event.
+ */
+ complete(&qdev->ide_completion);
+
+ return status;
+}
+
static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
+ int status;
mbcp->out_count = 2;
- if (ql_get_mb_sts(qdev, mbcp))
- goto exit;
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "%s: Could not get mailbox status.\n", __func__);
+ return;
+ }
qdev->link_status = mbcp->mbox_out[1];
QPRINTK(qdev, DRV, ERR, "Link Up.\n");
- QPRINTK(qdev, DRV, INFO, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]);
- if (!netif_carrier_ok(qdev->ndev)) {
- QPRINTK(qdev, LINK, INFO, "Link is Up.\n");
- netif_carrier_on(qdev->ndev);
- netif_wake_queue(qdev->ndev);
+
+ /* If we're coming back from an IDC event
+ * then set up the CAM and frame routing.
+ */
+ if (test_bit(QL_CAM_RT_SET, &qdev->flags)) {
+ status = ql_cam_route_initialize(qdev);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR,
+ "Failed to init CAM/Routing tables.\n");
+ return;
+ } else
+ clear_bit(QL_CAM_RT_SET, &qdev->flags);
}
-exit:
- /* Clear the MPI firmware status. */
- ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+
+ /* Queue up a worker to check the frame
+ * size information, and fix it if it's not
+ * to our liking.
+ */
+ if (!test_bit(QL_PORT_CFG, &qdev->flags)) {
+ QPRINTK(qdev, DRV, ERR, "Queue Port Config Worker!\n");
+ set_bit(QL_PORT_CFG, &qdev->flags);
+ /* Begin polled mode early so
+ * we don't get another interrupt
+ * when we leave mpi_worker dpc.
+ */
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+ queue_delayed_work(qdev->workqueue,
+ &qdev->mpi_port_cfg_work, 0);
+ }
+
+ netif_carrier_on(qdev->ndev);
}
static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
+ int status;
+
mbcp->out_count = 3;
- if (ql_get_mb_sts(qdev, mbcp)) {
- QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
- goto exit;
- }
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status)
+ QPRINTK(qdev, DRV, ERR, "Link down AEN broken!\n");
+
+ netif_carrier_off(qdev->ndev);
+}
+
+static int ql_sfp_in(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status;
+
+ mbcp->out_count = 5;
+
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status)
+ QPRINTK(qdev, DRV, ERR, "SFP in AEN broken!\n");
+ else
+ QPRINTK(qdev, DRV, ERR, "SFP insertion detected.\n");
+
+ return status;
+}
+
+static int ql_sfp_out(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status;
+
+ mbcp->out_count = 1;
+
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status)
+ QPRINTK(qdev, DRV, ERR, "SFP out AEN broken!\n");
+ else
+ QPRINTK(qdev, DRV, ERR, "SFP removal detected.\n");
+
+ return status;
+}
+
+static int ql_aen_lost(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status;
+
+ mbcp->out_count = 6;
+
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status)
+ QPRINTK(qdev, DRV, ERR, "Lost AEN broken!\n");
+ else {
+ int i;
+ QPRINTK(qdev, DRV, ERR, "Lost AEN detected.\n");
+ for (i = 0; i < mbcp->out_count; i++)
+ QPRINTK(qdev, DRV, ERR, "mbox_out[%d] = 0x%.08x.\n",
+ i, mbcp->mbox_out[i]);
- if (netif_carrier_ok(qdev->ndev)) {
- QPRINTK(qdev, LINK, INFO, "Link is Down.\n");
- netif_carrier_off(qdev->ndev);
- netif_stop_queue(qdev->ndev);
}
- QPRINTK(qdev, DRV, ERR, "Link Down.\n");
- QPRINTK(qdev, DRV, ERR, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]);
-exit:
- /* Clear the MPI firmware status. */
- ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+
+ return status;
}
static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
+ int status;
+
mbcp->out_count = 2;
- if (ql_get_mb_sts(qdev, mbcp)) {
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status) {
QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
- goto exit;
+ } else {
+ QPRINTK(qdev, DRV, ERR, "Firmware Revision = 0x%.08x.\n",
+ mbcp->mbox_out[1]);
+ status = ql_cam_route_initialize(qdev);
+ if (status)
+ QPRINTK(qdev, IFUP, ERR,
+ "Failed to init CAM/Routing tables.\n");
}
- QPRINTK(qdev, DRV, ERR, "Firmware initialized!\n");
- QPRINTK(qdev, DRV, ERR, "Firmware status = 0x%.08x.\n",
- mbcp->mbox_out[0]);
- QPRINTK(qdev, DRV, ERR, "Firmware Revision = 0x%.08x.\n",
- mbcp->mbox_out[1]);
-exit:
- /* Clear the MPI firmware status. */
+}
+
+/* Process an async event and clear it unless it's an
+ * error condition.
+ * This can get called iteratively from the mpi_work thread
+ * when events arrive via an interrupt.
+ * It also gets called when a mailbox command is polling for
+ * it's completion. */
+static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status;
+ int orig_count = mbcp->out_count;
+
+ /* Just get mailbox zero for now. */
+ mbcp->out_count = 1;
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Could not read MPI, resetting ASIC!\n");
+ ql_queue_asic_error(qdev);
+ goto end;
+ }
+
+ switch (mbcp->mbox_out[0]) {
+
+ /* This case is only active when we arrive here
+ * as a result of issuing a mailbox command to
+ * the firmware.
+ */
+ case MB_CMD_STS_INTRMDT:
+ case MB_CMD_STS_GOOD:
+ case MB_CMD_STS_INVLD_CMD:
+ case MB_CMD_STS_XFC_ERR:
+ case MB_CMD_STS_CSUM_ERR:
+ case MB_CMD_STS_ERR:
+ case MB_CMD_STS_PARAM_ERR:
+ /* We can only get mailbox status if we're polling from an
+ * unfinished command. Get the rest of the status data and
+ * return back to the caller.
+ * We only end up here when we're polling for a mailbox
+ * command completion.
+ */
+ mbcp->out_count = orig_count;
+ status = ql_get_mb_sts(qdev, mbcp);
+ return status;
+
+ /* We are being asked by firmware to accept
+ * a change to the port. This is only
+ * a change to max frame sizes (Tx/Rx), pause
+ * paramters, or loopback mode.
+ */
+ case AEN_IDC_REQ:
+ status = ql_idc_req_aen(qdev);
+ break;
+
+ /* Process and inbound IDC event.
+ * This will happen when we're trying to
+ * change tx/rx max frame size, change pause
+ * paramters or loopback mode.
+ */
+ case AEN_IDC_CMPLT:
+ case AEN_IDC_EXT:
+ status = ql_idc_cmplt_aen(qdev);
+ break;
+
+ case AEN_LINK_UP:
+ ql_link_up(qdev, mbcp);
+ break;
+
+ case AEN_LINK_DOWN:
+ ql_link_down(qdev, mbcp);
+ break;
+
+ case AEN_FW_INIT_DONE:
+ /* If we're in process on executing the firmware,
+ * then convert the status to normal mailbox status.
+ */
+ if (mbcp->mbox_in[0] == MB_CMD_EX_FW) {
+ mbcp->out_count = orig_count;
+ status = ql_get_mb_sts(qdev, mbcp);
+ mbcp->mbox_out[0] = MB_CMD_STS_GOOD;
+ return status;
+ }
+ ql_init_fw_done(qdev, mbcp);
+ break;
+
+ case AEN_AEN_SFP_IN:
+ ql_sfp_in(qdev, mbcp);
+ break;
+
+ case AEN_AEN_SFP_OUT:
+ ql_sfp_out(qdev, mbcp);
+ break;
+
+ /* This event can arrive at boot time or after an
+ * MPI reset if the firmware failed to initialize.
+ */
+ case AEN_FW_INIT_FAIL:
+ /* If we're in process on executing the firmware,
+ * then convert the status to normal mailbox status.
+ */
+ if (mbcp->mbox_in[0] == MB_CMD_EX_FW) {
+ mbcp->out_count = orig_count;
+ status = ql_get_mb_sts(qdev, mbcp);
+ mbcp->mbox_out[0] = MB_CMD_STS_ERR;
+ return status;
+ }
+ QPRINTK(qdev, DRV, ERR,
+ "Firmware initialization failed.\n");
+ status = -EIO;
+ ql_queue_fw_error(qdev);
+ break;
+
+ case AEN_SYS_ERR:
+ QPRINTK(qdev, DRV, ERR,
+ "System Error.\n");
+ ql_queue_fw_error(qdev);
+ status = -EIO;
+ break;
+
+ case AEN_AEN_LOST:
+ ql_aen_lost(qdev, mbcp);
+ break;
+
+ default:
+ QPRINTK(qdev, DRV, ERR,
+ "Unsupported AE %.08x.\n", mbcp->mbox_out[0]);
+ /* Clear the MPI firmware status. */
+ }
+end:
ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+ return status;
}
-void ql_mpi_work(struct work_struct *work)
+/* Execute a single mailbox command.
+ * mbcp is a pointer to an array of u32. Each
+ * element in the array contains the value for it's
+ * respective mailbox register.
+ */
+static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status, count;
+
+ mutex_lock(&qdev->mpi_mutex);
+
+ /* Begin polled mode for MPI */
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+
+ /* Load the mailbox registers and wake up MPI RISC. */
+ status = ql_exec_mb_cmd(qdev, mbcp);
+ if (status)
+ goto end;
+
+
+ /* If we're generating a system error, then there's nothing
+ * to wait for.
+ */
+ if (mbcp->mbox_in[0] == MB_CMD_MAKE_SYS_ERR)
+ goto end;
+
+ /* Wait for the command to complete. We loop
+ * here because some AEN might arrive while
+ * we're waiting for the mailbox command to
+ * complete. If more than 5 arrive then we can
+ * assume something is wrong. */
+ count = 5;
+ do {
+ /* Wait for the interrupt to come in. */
+ status = ql_wait_mbx_cmd_cmplt(qdev);
+ if (status)
+ goto end;
+
+ /* Process the event. If it's an AEN, it
+ * will be handled in-line or a worker
+ * will be spawned. If it's our completion
+ * we will catch it below.
+ */
+ status = ql_mpi_handler(qdev, mbcp);
+ if (status)
+ goto end;
+
+ /* It's either the completion for our mailbox
+ * command complete or an AEN. If it's our
+ * completion then get out.
+ */
+ if (((mbcp->mbox_out[0] & 0x0000f000) ==
+ MB_CMD_STS_GOOD) ||
+ ((mbcp->mbox_out[0] & 0x0000f000) ==
+ MB_CMD_STS_INTRMDT))
+ break;
+ } while (--count);
+
+ if (!count) {
+ QPRINTK(qdev, DRV, ERR,
+ "Timed out waiting for mailbox complete.\n");
+ status = -ETIMEDOUT;
+ goto end;
+ }
+
+ /* Now we can clear the interrupt condition
+ * and look at our status.
+ */
+ ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+
+ if (((mbcp->mbox_out[0] & 0x0000f000) !=
+ MB_CMD_STS_GOOD) &&
+ ((mbcp->mbox_out[0] & 0x0000f000) !=
+ MB_CMD_STS_INTRMDT)) {
+ ql_display_mb_sts(qdev, mbcp);
+ status = -EIO;
+ }
+end:
+ mutex_unlock(&qdev->mpi_mutex);
+ /* End polled mode for MPI */
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
+ return status;
+}
+
+/* Get functional state for MPI firmware.
+ * Returns zero on success.
+ */
+int ql_mb_get_fw_state(struct ql_adapter *qdev)
+{
+ struct mbox_params mbc;
+ struct mbox_params *mbcp = &mbc;
+ int status = 0;
+
+ memset(mbcp, 0, sizeof(struct mbox_params));
+
+ mbcp->in_count = 1;
+ mbcp->out_count = 2;
+
+ mbcp->mbox_in[0] = MB_CMD_GET_FW_STATE;
+
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed Get Firmware State.\n");
+ status = -EIO;
+ }
+
+ /* If bit zero is set in mbx 1 then the firmware is
+ * running, but not initialized. This should never
+ * happen.
+ */
+ if (mbcp->mbox_out[1] & 1) {
+ QPRINTK(qdev, DRV, ERR,
+ "Firmware waiting for initialization.\n");
+ status = -EIO;
+ }
+
+ return status;
+}
+
+/* Send and ACK mailbox command to the firmware to
+ * let it continue with the change.
+ */
+int ql_mb_idc_ack(struct ql_adapter *qdev)
{
- struct ql_adapter *qdev =
- container_of(work, struct ql_adapter, mpi_work.work);
struct mbox_params mbc;
struct mbox_params *mbcp = &mbc;
+ int status = 0;
+
+ memset(mbcp, 0, sizeof(struct mbox_params));
+
+ mbcp->in_count = 5;
mbcp->out_count = 1;
- while (ql_read32(qdev, STS) & STS_PI) {
- if (ql_get_mb_sts(qdev, mbcp)) {
- QPRINTK(qdev, DRV, ERR,
- "Could not read MPI, resetting ASIC!\n");
- ql_queue_asic_error(qdev);
- }
+ mbcp->mbox_in[0] = MB_CMD_IDC_ACK;
+ mbcp->mbox_in[1] = qdev->idc_mbc.mbox_out[1];
+ mbcp->mbox_in[2] = qdev->idc_mbc.mbox_out[2];
+ mbcp->mbox_in[3] = qdev->idc_mbc.mbox_out[3];
+ mbcp->mbox_in[4] = qdev->idc_mbc.mbox_out[4];
- switch (mbcp->mbox_out[0]) {
- case AEN_LINK_UP:
- ql_link_up(qdev, mbcp);
- break;
- case AEN_LINK_DOWN:
- ql_link_down(qdev, mbcp);
- break;
- case AEN_FW_INIT_DONE:
- ql_init_fw_done(qdev, mbcp);
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed IDC ACK send.\n");
+ status = -EIO;
+ }
+ return status;
+}
+
+/* Get link settings and maximum frame size settings
+ * for the current port.
+ * Most likely will block.
+ */
+static int ql_mb_set_port_cfg(struct ql_adapter *qdev)
+{
+ struct mbox_params mbc;
+ struct mbox_params *mbcp = &mbc;
+ int status = 0;
+
+ memset(mbcp, 0, sizeof(struct mbox_params));
+
+ mbcp->in_count = 3;
+ mbcp->out_count = 1;
+
+ mbcp->mbox_in[0] = MB_CMD_SET_PORT_CFG;
+ mbcp->mbox_in[1] = qdev->link_config;
+ mbcp->mbox_in[2] = qdev->max_frame_size;
+
+
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] == MB_CMD_STS_INTRMDT) {
+ QPRINTK(qdev, DRV, ERR,
+ "Port Config sent, wait for IDC.\n");
+ } else if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed Set Port Configuration.\n");
+ status = -EIO;
+ }
+ return status;
+}
+
+/* Get link settings and maximum frame size settings
+ * for the current port.
+ * Most likely will block.
+ */
+static int ql_mb_get_port_cfg(struct ql_adapter *qdev)
+{
+ struct mbox_params mbc;
+ struct mbox_params *mbcp = &mbc;
+ int status = 0;
+
+ memset(mbcp, 0, sizeof(struct mbox_params));
+
+ mbcp->in_count = 1;
+ mbcp->out_count = 3;
+
+ mbcp->mbox_in[0] = MB_CMD_GET_PORT_CFG;
+
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed Get Port Configuration.\n");
+ status = -EIO;
+ } else {
+ QPRINTK(qdev, DRV, DEBUG,
+ "Passed Get Port Configuration.\n");
+ qdev->link_config = mbcp->mbox_out[1];
+ qdev->max_frame_size = mbcp->mbox_out[2];
+ }
+ return status;
+}
+
+/* IDC - Inter Device Communication...
+ * Some firmware commands require consent of adjacent FCOE
+ * function. This function waits for the OK, or a
+ * counter-request for a little more time.i
+ * The firmware will complete the request if the other
+ * function doesn't respond.
+ */
+static int ql_idc_wait(struct ql_adapter *qdev)
+{
+ int status = -ETIMEDOUT;
+ long wait_time = 1 * HZ;
+ struct mbox_params *mbcp = &qdev->idc_mbc;
+ do {
+ /* Wait here for the command to complete
+ * via the IDC process.
+ */
+ wait_time =
+ wait_for_completion_timeout(&qdev->ide_completion,
+ wait_time);
+ if (!wait_time) {
+ QPRINTK(qdev, DRV, ERR,
+ "IDC Timeout.\n");
break;
- case MB_CMD_STS_GOOD:
+ }
+ /* Now examine the response from the IDC process.
+ * We might have a good completion or a request for
+ * more wait time.
+ */
+ if (mbcp->mbox_out[0] == AEN_IDC_EXT) {
+ QPRINTK(qdev, DRV, ERR,
+ "IDC Time Extension from function.\n");
+ wait_time += (mbcp->mbox_out[1] >> 8) & 0x0000000f;
+ } else if (mbcp->mbox_out[0] == AEN_IDC_CMPLT) {
+ QPRINTK(qdev, DRV, ERR,
+ "IDC Success.\n");
+ status = 0;
break;
- case AEN_FW_INIT_FAIL:
- case AEN_SYS_ERR:
- case MB_CMD_STS_ERR:
- ql_queue_fw_error(qdev);
- default:
- /* Clear the MPI firmware status. */
- ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+ } else {
+ QPRINTK(qdev, DRV, ERR,
+ "IDC: Invalid State 0x%.04x.\n",
+ mbcp->mbox_out[0]);
+ status = -EIO;
break;
}
+ } while (wait_time);
+
+ return status;
+}
+
+/* API called in work thread context to set new TX/RX
+ * maximum frame size values to match MTU.
+ */
+static int ql_set_port_cfg(struct ql_adapter *qdev)
+{
+ int status;
+ status = ql_mb_set_port_cfg(qdev);
+ if (status)
+ return status;
+ status = ql_idc_wait(qdev);
+ return status;
+}
+
+/* The following routines are worker threads that process
+ * events that may sleep waiting for completion.
+ */
+
+/* This thread gets the maximum TX and RX frame size values
+ * from the firmware and, if necessary, changes them to match
+ * the MTU setting.
+ */
+void ql_mpi_port_cfg_work(struct work_struct *work)
+{
+ struct ql_adapter *qdev =
+ container_of(work, struct ql_adapter, mpi_port_cfg_work.work);
+ struct net_device *ndev = qdev->ndev;
+ int status;
+
+ status = ql_mb_get_port_cfg(qdev);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Bug: Failed to get port config data.\n");
+ goto err;
+ }
+
+ if (ndev->mtu <= 2500)
+ goto end;
+ else if (qdev->link_config & CFG_JUMBO_FRAME_SIZE &&
+ qdev->max_frame_size ==
+ CFG_DEFAULT_MAX_FRAME_SIZE)
+ goto end;
+
+ qdev->link_config |= CFG_JUMBO_FRAME_SIZE;
+ qdev->max_frame_size = CFG_DEFAULT_MAX_FRAME_SIZE;
+ status = ql_set_port_cfg(qdev);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Bug: Failed to set port config data.\n");
+ goto err;
+ }
+end:
+ clear_bit(QL_PORT_CFG, &qdev->flags);
+ return;
+err:
+ ql_queue_fw_error(qdev);
+ goto end;
+}
+
+/* Process an inter-device request. This is issues by
+ * the firmware in response to another function requesting
+ * a change to the port. We set a flag to indicate a change
+ * has been made and then send a mailbox command ACKing
+ * the change request.
+ */
+void ql_mpi_idc_work(struct work_struct *work)
+{
+ struct ql_adapter *qdev =
+ container_of(work, struct ql_adapter, mpi_idc_work.work);
+ int status;
+ struct mbox_params *mbcp = &qdev->idc_mbc;
+ u32 aen;
+
+ aen = mbcp->mbox_out[1] >> 16;
+
+ switch (aen) {
+ default:
+ QPRINTK(qdev, DRV, ERR,
+ "Bug: Unhandled IDC action.\n");
+ break;
+ case MB_CMD_PORT_RESET:
+ case MB_CMD_SET_PORT_CFG:
+ case MB_CMD_STOP_FW:
+ netif_carrier_off(qdev->ndev);
+ /* Signal the resulting link up AEN
+ * that the frame routing and mac addr
+ * needs to be set.
+ * */
+ set_bit(QL_CAM_RT_SET, &qdev->flags);
+ status = ql_mb_idc_ack(qdev);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Bug: No pending IDC!\n");
+ }
+ }
+}
+
+void ql_mpi_work(struct work_struct *work)
+{
+ struct ql_adapter *qdev =
+ container_of(work, struct ql_adapter, mpi_work.work);
+ struct mbox_params mbc;
+ struct mbox_params *mbcp = &mbc;
+
+ mutex_lock(&qdev->mpi_mutex);
+
+ while (ql_read32(qdev, STS) & STS_PI) {
+ memset(mbcp, 0, sizeof(struct mbox_params));
+ mbcp->out_count = 1;
+ ql_mpi_handler(qdev, mbcp);
}
+
+ mutex_unlock(&qdev->mpi_mutex);
ql_enable_completion_interrupt(qdev, 0);
}
@@ -142,9 +848,8 @@ void ql_mpi_reset_work(struct work_struct *work)
{
struct ql_adapter *qdev =
container_of(work, struct ql_adapter, mpi_reset_work.work);
- QPRINTK(qdev, DRV, ERR,
- "Enter, qdev = %p..\n", qdev);
- ql_write32(qdev, CSR, CSR_CMD_SET_RST);
- msleep(50);
- ql_write32(qdev, CSR, CSR_CMD_CLR_RST);
+ cancel_delayed_work_sync(&qdev->mpi_work);
+ cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
+ cancel_delayed_work_sync(&qdev->mpi_idc_work);
+ ql_soft_reset_mpi_risc(qdev);
}
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index b2dcdb5ed8bd..0a37f9902a07 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -49,12 +49,12 @@
#include <asm/processor.h>
#define DRV_NAME "r6040"
-#define DRV_VERSION "0.21"
-#define DRV_RELDATE "09Jan2009"
+#define DRV_VERSION "0.22"
+#define DRV_RELDATE "25Mar2009"
/* PHY CHIP Address */
#define PHY1_ADDR 1 /* For MAC1 */
-#define PHY2_ADDR 2 /* For MAC2 */
+#define PHY2_ADDR 3 /* For MAC2 */
#define PHY_MODE 0x3100 /* PHY CHIP Register 0 */
#define PHY_CAP 0x01E1 /* PHY CHIP Register 4 */
@@ -484,12 +484,12 @@ static int r6040_close(struct net_device *dev)
/* Free Descriptor memory */
if (lp->rx_ring) {
pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
- lp->rx_ring = 0;
+ lp->rx_ring = NULL;
}
if (lp->tx_ring) {
pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma);
- lp->tx_ring = 0;
+ lp->tx_ring = NULL;
}
return 0;
@@ -676,7 +676,7 @@ static int r6040_poll(struct napi_struct *napi, int budget)
work_done = r6040_rx(dev, budget);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
/* Enable RX interrupt */
iowrite16(ioread16(ioaddr + MIER) | RX_INTS, ioaddr + MIER);
}
@@ -713,7 +713,7 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
/* Mask off RX interrupt */
misr &= ~RX_INTS;
- netif_rx_schedule(&lp->napi);
+ napi_schedule(&lp->napi);
}
/* TX interrupt request */
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 43fedb9ecedb..e1a638a05f86 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -2075,8 +2075,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (!tp->pcie_cap && netif_msg_probe(tp))
dev_info(&pdev->dev, "no PCI Express capability\n");
- /* Unneeded ? Don't mess with Mrs. Murphy. */
- rtl8169_irq_mask_and_ack(ioaddr);
+ RTL_W16(IntrMask, 0x0000);
/* Soft reset the chip. */
RTL_W8(ChipCmd, CmdReset);
@@ -2088,6 +2087,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
msleep_interruptible(1);
}
+ RTL_W16(IntrStatus, 0xffff);
+
/* Identify chip attached to board */
rtl8169_get_mac_version(tp, ioaddr);
@@ -3593,8 +3594,8 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
tp->intr_mask = ~tp->napi_event;
- if (likely(netif_rx_schedule_prep(&tp->napi)))
- __netif_rx_schedule(&tp->napi);
+ if (likely(napi_schedule_prep(&tp->napi)))
+ __napi_schedule(&tp->napi);
else if (netif_msg_intr(tp)) {
printk(KERN_INFO "%s: interrupt %04x in poll\n",
dev->name, status);
@@ -3615,7 +3616,7 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
rtl8169_tx_interrupt(dev, tp, ioaddr);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
tp->intr_mask = 0xffff;
/*
* 20040426: the barrier is not strictly required but the
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index a6fd27a2cc3d..ec59e29807a6 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -362,8 +362,7 @@ static int rionet_close(struct net_device *ndev)
netif_carrier_off(ndev);
for (i = 0; i < RIONET_RX_RING_SIZE; i++)
- if (rnet->rx_skb[i])
- kfree_skb(rnet->rx_skb[i]);
+ kfree_skb(rnet->rx_skb[i]);
list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
if (rionet_active[peer->rdev->destid]) {
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index f5c57c059bca..16868b7a5d0a 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -2852,7 +2852,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget)
s2io_chk_rx_buffers(nic, ring);
if (pkts_processed < budget_org) {
- netif_rx_complete(napi);
+ napi_complete(napi);
/*Re Enable MSI-Rx Vector*/
addr = (u8 __iomem *)&bar0->xmsi_mask_reg;
addr += 7 - ring->ring_no;
@@ -2889,7 +2889,7 @@ static int s2io_poll_inta(struct napi_struct *napi, int budget)
break;
}
if (pkts_processed < budget_org) {
- netif_rx_complete(napi);
+ napi_complete(napi);
/* Re enable the Rx interrupts for the ring */
writeq(0, &bar0->rx_traffic_mask);
readl(&bar0->rx_traffic_mask);
@@ -3862,7 +3862,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
ret = pci_enable_msix(nic->pdev, nic->entries, nic->num_entries);
/* We fail init if error or we get less vectors than min required */
if (ret) {
- DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name);
+ DBG_PRINT(ERR_DBG, "s2io: Enabling MSI-X failed\n");
kfree(nic->entries);
nic->mac_control.stats_info->sw_stat.mem_freed
+= (nic->num_entries * sizeof(struct msix_entry));
@@ -4342,7 +4342,7 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id)
val8 = (ring->ring_no == 0) ? 0x7f : 0xff;
writeb(val8, addr);
val8 = readb(addr);
- netif_rx_schedule(&ring->napi);
+ napi_schedule(&ring->napi);
} else {
rx_intr_handler(ring, 0);
s2io_chk_rx_buffers(sp, ring);
@@ -4789,7 +4789,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
if (config->napi) {
if (reason & GEN_INTR_RXTRAFFIC) {
- netif_rx_schedule(&sp->napi);
+ napi_schedule(&sp->napi);
writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask);
writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
readl(&bar0->rx_traffic_int);
@@ -7220,7 +7220,6 @@ static int s2io_card_up(struct s2io_nic * sp)
/* Initialise napi */
if (config->napi) {
- int i;
if (config->intr_type == MSI_X) {
for (i = 0; i < sp->config.rx_ring_num; i++)
napi_enable(&sp->mac_control.rings[i].napi);
@@ -7542,6 +7541,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
send_up:
+ skb_record_rx_queue(skb, ring_no);
queue_rx_frame(skb, RXD_GET_VLAN_TAG(rxdp->Control_2));
aggregate:
sp->mac_control.rings[ring_no].rx_bufs_left -= 1;
@@ -8009,8 +8009,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
if (ret) {
DBG_PRINT(ERR_DBG,
- "%s: MSI-X requested but failed to enable\n",
- dev->name);
+ "s2io: MSI-X requested but failed to enable\n");
sp->config.intr_type = INTA;
}
}
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 31e38fae017f..ce7551e17ba7 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -2039,9 +2039,9 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance)
sbdma_tx_process(sc,&(sc->sbm_txdma), 0);
if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) {
- if (netif_rx_schedule_prep(&sc->napi)) {
+ if (napi_schedule_prep(&sc->napi)) {
__raw_writeq(0, sc->sbm_imr);
- __netif_rx_schedule(&sc->napi);
+ __napi_schedule(&sc->napi);
/* Depend on the exit from poll to reenable intr */
}
else {
@@ -2299,7 +2299,7 @@ static int sbmac_init(struct platform_device *pldev, long long base)
eaddr = sc->sbm_hwaddr;
/*
- * Read the ethernet address. The firwmare left this programmed
+ * Read the ethernet address. The firmware left this programmed
* for us in the ethernet address register for each mac.
*/
@@ -2478,7 +2478,7 @@ static int sbmac_mii_probe(struct net_device *dev)
return -ENXIO;
}
- phy_dev = phy_connect(dev, phy_dev->dev.bus_id, &sbmac_mii_poll, 0,
+ phy_dev = phy_connect(dev, dev_name(&phy_dev->dev), &sbmac_mii_poll, 0,
PHY_INTERFACE_MODE_GMII);
if (IS_ERR(phy_dev)) {
printk(KERN_ERR "%s: could not attach to PHY\n", dev->name);
@@ -2500,7 +2500,7 @@ static int sbmac_mii_probe(struct net_device *dev)
pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
dev->name, phy_dev->drv->name,
- phy_dev->dev.bus_id, phy_dev->irq);
+ dev_name(&phy_dev->dev), phy_dev->irq);
sc->phy_dev = phy_dev;
@@ -2667,7 +2667,7 @@ static int sbmac_poll(struct napi_struct *napi, int budget)
sbdma_tx_process(sc, &(sc->sbm_txdma), 1);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
#ifdef CONFIG_SBMAC_COALESCE
__raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
@@ -2697,7 +2697,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
sbm_base = ioremap_nocache(res->start, res->end - res->start + 1);
if (!sbm_base) {
printk(KERN_ERR "%s: unable to map device registers\n",
- pldev->dev.bus_id);
+ dev_name(&pldev->dev));
err = -ENOMEM;
goto out_out;
}
@@ -2708,7 +2708,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
* If we find a zero, skip this MAC.
*/
sbmac_orig_hwaddr = __raw_readq(sbm_base + R_MAC_ETHERNET_ADDR);
- pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", pldev->dev.bus_id,
+ pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", dev_name(&pldev->dev),
sbmac_orig_hwaddr ? "" : "not ", (long long)res->start);
if (sbmac_orig_hwaddr == 0) {
err = 0;
@@ -2721,7 +2721,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
dev = alloc_etherdev(sizeof(struct sbmac_softc));
if (!dev) {
printk(KERN_ERR "%s: unable to allocate etherdev\n",
- pldev->dev.bus_id);
+ dev_name(&pldev->dev));
err = -ENOMEM;
goto out_unmap;
}
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 8b75bef4a841..c13cbf099b88 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -13,6 +13,9 @@
* Both are almost identical and seem to be based on pci-skeleton.c
*
* Rewritten for 2.6 by Cesar Eduardo Barros
+ *
+ * A datasheet for this chip can be found at
+ * http://www.silan.com.cn/english/products/pdf/SC92031AY.pdf
*/
/* Note about set_mac_address: I don't know how to change the hardware
@@ -31,13 +34,7 @@
#include <asm/irq.h>
-#define PCI_VENDOR_ID_SILAN 0x1904
-#define PCI_DEVICE_ID_SILAN_SC92031 0x2031
-#define PCI_DEVICE_ID_SILAN_8139D 0x8139
-
#define SC92031_NAME "sc92031"
-#define SC92031_DESCRIPTION "Silan SC92031 PCI Fast Ethernet Adapter driver"
-#define SC92031_VERSION "2.0c"
/* BAR 0 is MMIO, BAR 1 is PIO */
#ifndef SC92031_USE_BAR
@@ -1264,7 +1261,6 @@ static void sc92031_ethtool_get_drvinfo(struct net_device *dev,
struct pci_dev *pdev = priv->pdev;
strcpy(drvinfo->driver, SC92031_NAME);
- strcpy(drvinfo->version, SC92031_VERSION);
strcpy(drvinfo->bus_info, pci_name(pdev));
}
@@ -1423,6 +1419,7 @@ static int __devinit sc92031_probe(struct pci_dev *pdev,
struct net_device *dev;
struct sc92031_priv *priv;
u32 mac0, mac1;
+ unsigned long base_addr;
err = pci_enable_device(pdev);
if (unlikely(err < 0))
@@ -1497,6 +1494,14 @@ static int __devinit sc92031_probe(struct pci_dev *pdev,
if (err < 0)
goto out_register_netdev;
+#if SC92031_USE_BAR == 0
+ base_addr = dev->mem_start;
+#elif SC92031_USE_BAR == 1
+ base_addr = dev->base_addr;
+#endif
+ printk(KERN_INFO "%s: SC92031 at 0x%lx, %pM, IRQ %d\n", dev->name,
+ base_addr, dev->dev_addr, dev->irq);
+
return 0;
out_register_netdev:
@@ -1586,8 +1591,8 @@ out:
}
static struct pci_device_id sc92031_pci_device_id_table[] __devinitdata = {
- { PCI_DEVICE(PCI_VENDOR_ID_SILAN, PCI_DEVICE_ID_SILAN_SC92031) },
- { PCI_DEVICE(PCI_VENDOR_ID_SILAN, PCI_DEVICE_ID_SILAN_8139D) },
+ { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x2031) },
+ { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x8139) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, sc92031_pci_device_id_table);
@@ -1603,7 +1608,6 @@ static struct pci_driver sc92031_pci_driver = {
static int __init sc92031_init(void)
{
- printk(KERN_INFO SC92031_DESCRIPTION " " SC92031_VERSION "\n");
return pci_register_driver(&sc92031_pci_driver);
}
@@ -1617,5 +1621,4 @@ module_exit(sc92031_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Cesar Eduardo Barros <cesarb@cesarb.net>");
-MODULE_DESCRIPTION(SC92031_DESCRIPTION);
-MODULE_VERSION(SC92031_VERSION);
+MODULE_DESCRIPTION("Silan SC92031 PCI Fast Ethernet Adapter driver");
diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c
index 12a8ffffeb03..ebbbe09725fe 100644
--- a/drivers/net/seeq8005.c
+++ b/drivers/net/seeq8005.c
@@ -143,6 +143,17 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops seeq8005_netdev_ops = {
+ .ndo_open = seeq8005_open,
+ .ndo_stop = seeq8005_close,
+ .ndo_start_xmit = seeq8005_send_packet,
+ .ndo_tx_timeout = seeq8005_timeout,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/* This is the real probe routine. Linux has a history of friendly device
probes on the ISA bus. A good device probes avoids doing writes, and
verifies that the correct device exists and functions. */
@@ -332,12 +343,8 @@ static int __init seeq8005_probe1(struct net_device *dev, int ioaddr)
}
}
#endif
- dev->open = seeq8005_open;
- dev->stop = seeq8005_close;
- dev->hard_start_xmit = seeq8005_send_packet;
- dev->tx_timeout = seeq8005_timeout;
+ dev->netdev_ops = &seeq8005_netdev_ops;
dev->watchdog_timeo = HZ/20;
- dev->set_multicast_list = set_multicast_list;
dev->flags &= ~IFF_MULTICAST;
return 0;
diff --git a/drivers/net/sfc/Kconfig b/drivers/net/sfc/Kconfig
index c535408ad6be..12a82966b577 100644
--- a/drivers/net/sfc/Kconfig
+++ b/drivers/net/sfc/Kconfig
@@ -2,7 +2,6 @@ config SFC
tristate "Solarflare Solarstorm SFC4000 support"
depends on PCI && INET
select MII
- select INET_LRO
select CRC32
select I2C
select I2C_ALGOBIT
diff --git a/drivers/net/sfc/bitfield.h b/drivers/net/sfc/bitfield.h
index d95c21828014..d54d84c267b9 100644
--- a/drivers/net/sfc/bitfield.h
+++ b/drivers/net/sfc/bitfield.h
@@ -543,7 +543,7 @@ typedef union efx_oword {
/* Static initialiser */
#define EFX_OWORD32(a, b, c, d) \
- { .u32 = { __constant_cpu_to_le32(a), __constant_cpu_to_le32(b), \
- __constant_cpu_to_le32(c), __constant_cpu_to_le32(d) } }
+ { .u32 = { cpu_to_le32(a), cpu_to_le32(b), \
+ cpu_to_le32(c), cpu_to_le32(d) } }
#endif /* EFX_BITFIELD_H */
diff --git a/drivers/net/sfc/boards.c b/drivers/net/sfc/boards.c
index 64903496aa9a..5182ac5a1034 100644
--- a/drivers/net/sfc/boards.c
+++ b/drivers/net/sfc/boards.c
@@ -26,7 +26,7 @@ static void blink_led_timer(unsigned long context)
{
struct efx_nic *efx = (struct efx_nic *)context;
struct efx_blinker *bl = &efx->board_info.blinker;
- efx->board_info.set_fault_led(efx, bl->state);
+ efx->board_info.set_id_led(efx, bl->state);
bl->state = !bl->state;
if (bl->resubmit)
mod_timer(&bl->timer, jiffies + BLINK_INTERVAL);
@@ -48,7 +48,7 @@ static void board_blink(struct efx_nic *efx, bool blink)
blinker->resubmit = false;
if (blinker->timer.function)
del_timer_sync(&blinker->timer);
- efx->board_info.set_fault_led(efx, false);
+ efx->board_info.init_leds(efx);
}
}
@@ -185,7 +185,7 @@ static struct i2c_board_info sfe4002_hwmon_info = {
#define SFE4002_RX_LED (0) /* Green */
#define SFE4002_TX_LED (1) /* Amber */
-static int sfe4002_init_leds(struct efx_nic *efx)
+static void sfe4002_init_leds(struct efx_nic *efx)
{
/* Set the TX and RX LEDs to reflect status and activity, and the
* fault LED off */
@@ -194,11 +194,9 @@ static int sfe4002_init_leds(struct efx_nic *efx)
xfp_set_led(efx, SFE4002_RX_LED,
QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACTSTAT);
xfp_set_led(efx, SFE4002_FAULT_LED, QUAKE_LED_OFF);
- efx->board_info.blinker.led_num = SFE4002_FAULT_LED;
- return 0;
}
-static void sfe4002_fault_led(struct efx_nic *efx, bool state)
+static void sfe4002_set_id_led(struct efx_nic *efx, bool state)
{
xfp_set_led(efx, SFE4002_FAULT_LED, state ? QUAKE_LED_ON :
QUAKE_LED_OFF);
@@ -222,7 +220,67 @@ static int sfe4002_init(struct efx_nic *efx)
return rc;
efx->board_info.monitor = sfe4002_check_hw;
efx->board_info.init_leds = sfe4002_init_leds;
- efx->board_info.set_fault_led = sfe4002_fault_led;
+ efx->board_info.set_id_led = sfe4002_set_id_led;
+ efx->board_info.blink = board_blink;
+ efx->board_info.fini = efx_fini_lm87;
+ return 0;
+}
+
+/*****************************************************************************
+ * Support for the SFN4112F
+ *
+ */
+static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */
+
+static const u8 sfn4112f_lm87_regs[] = {
+ LM87_IN_LIMITS(0, 0x83, 0x91), /* 2.5V: 1.8V +/- 5% */
+ LM87_IN_LIMITS(1, 0x51, 0x5a), /* Vccp1: 1.2V +/- 5% */
+ LM87_IN_LIMITS(2, 0xb6, 0xca), /* 3.3V: 3.3V +/- 5% */
+ LM87_IN_LIMITS(4, 0xb0, 0xe0), /* 12V: 11-14V */
+ LM87_IN_LIMITS(5, 0x44, 0x4b), /* Vccp2: 1.0V +/- 5% */
+ LM87_AIN_LIMITS(1, 0x91, 0xa1), /* AIN2: 1.5V +/- 5% */
+ LM87_TEMP_INT_LIMITS(10, 60), /* board */
+ LM87_TEMP_EXT1_LIMITS(10, 70), /* Falcon */
+ 0
+};
+
+static struct i2c_board_info sfn4112f_hwmon_info = {
+ I2C_BOARD_INFO("lm87", 0x2e),
+ .platform_data = &sfn4112f_lm87_channel,
+ .irq = -1,
+};
+
+#define SFN4112F_ACT_LED 0
+#define SFN4112F_LINK_LED 1
+
+static void sfn4112f_init_leds(struct efx_nic *efx)
+{
+ xfp_set_led(efx, SFN4112F_ACT_LED,
+ QUAKE_LED_RXLINK | QUAKE_LED_LINK_ACT);
+ xfp_set_led(efx, SFN4112F_LINK_LED,
+ QUAKE_LED_RXLINK | QUAKE_LED_LINK_STAT);
+}
+
+static void sfn4112f_set_id_led(struct efx_nic *efx, bool state)
+{
+ xfp_set_led(efx, SFN4112F_LINK_LED,
+ state ? QUAKE_LED_ON : QUAKE_LED_OFF);
+}
+
+static int sfn4112f_check_hw(struct efx_nic *efx)
+{
+ /* Mask out unused sensors */
+ return efx_check_lm87(efx, ~0x48);
+}
+
+static int sfn4112f_init(struct efx_nic *efx)
+{
+ int rc = efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs);
+ if (rc)
+ return rc;
+ efx->board_info.monitor = sfn4112f_check_hw;
+ efx->board_info.init_leds = sfn4112f_init_leds;
+ efx->board_info.set_id_led = sfn4112f_set_id_led;
efx->board_info.blink = board_blink;
efx->board_info.fini = efx_fini_lm87;
return 0;
@@ -243,6 +301,8 @@ static struct efx_board_data board_data[] = {
{ EFX_BOARD_SFE4002, "SFE4002", "XFP adapter", sfe4002_init },
{ EFX_BOARD_SFN4111T, "SFN4111T", "100/1000/10GBASE-T adapter",
sfn4111t_init },
+ { EFX_BOARD_SFN4112F, "SFN4112F", "SFP+ adapter",
+ sfn4112f_init },
};
void efx_set_board_info(struct efx_nic *efx, u16 revision_info)
diff --git a/drivers/net/sfc/boards.h b/drivers/net/sfc/boards.h
index d93c6c6a7548..44942de0e080 100644
--- a/drivers/net/sfc/boards.h
+++ b/drivers/net/sfc/boards.h
@@ -15,6 +15,7 @@ enum efx_board_type {
EFX_BOARD_SFE4001 = 1,
EFX_BOARD_SFE4002 = 2,
EFX_BOARD_SFN4111T = 0x51,
+ EFX_BOARD_SFN4112F = 0x52,
};
extern void efx_set_board_info(struct efx_nic *efx, u16 revision_info);
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 847e9bb0098f..dee23b159df2 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -133,6 +133,16 @@ static int phy_flash_cfg;
module_param(phy_flash_cfg, int, 0644);
MODULE_PARM_DESC(phy_flash_cfg, "Set PHYs into reflash mode initially");
+static unsigned irq_adapt_low_thresh = 10000;
+module_param(irq_adapt_low_thresh, uint, 0644);
+MODULE_PARM_DESC(irq_adapt_low_thresh,
+ "Threshold score for reducing IRQ moderation");
+
+static unsigned irq_adapt_high_thresh = 20000;
+module_param(irq_adapt_high_thresh, uint, 0644);
+MODULE_PARM_DESC(irq_adapt_high_thresh,
+ "Threshold score for increasing IRQ moderation");
+
/**************************************************************************
*
* Utility functions and prototypes
@@ -182,7 +192,6 @@ static int efx_process_channel(struct efx_channel *channel, int rx_quota)
channel->rx_pkt = NULL;
}
- efx_flush_lro(channel);
efx_rx_strategy(channel);
efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]);
@@ -224,12 +233,41 @@ static int efx_poll(struct napi_struct *napi, int budget)
rx_packets = efx_process_channel(channel, budget);
if (rx_packets < budget) {
+ struct efx_nic *efx = channel->efx;
+
+ if (channel->used_flags & EFX_USED_BY_RX &&
+ efx->irq_rx_adaptive &&
+ unlikely(++channel->irq_count == 1000)) {
+ unsigned old_irq_moderation = channel->irq_moderation;
+
+ if (unlikely(channel->irq_mod_score <
+ irq_adapt_low_thresh)) {
+ channel->irq_moderation =
+ max_t(int,
+ channel->irq_moderation -
+ FALCON_IRQ_MOD_RESOLUTION,
+ FALCON_IRQ_MOD_RESOLUTION);
+ } else if (unlikely(channel->irq_mod_score >
+ irq_adapt_high_thresh)) {
+ channel->irq_moderation =
+ min(channel->irq_moderation +
+ FALCON_IRQ_MOD_RESOLUTION,
+ efx->irq_rx_moderation);
+ }
+
+ if (channel->irq_moderation != old_irq_moderation)
+ falcon_set_int_moderation(channel);
+
+ channel->irq_count = 0;
+ channel->irq_mod_score = 0;
+ }
+
/* There is no race here; although napi_disable() will
- * only wait for netif_rx_complete(), this isn't a problem
+ * only wait for napi_complete(), this isn't a problem
* since efx_channel_processed() will have no effect if
* interrupts have already been disabled.
*/
- netif_rx_complete(napi);
+ napi_complete(napi);
efx_channel_processed(channel);
}
@@ -410,6 +448,9 @@ static void efx_init_channels(struct efx_nic *efx)
WARN_ON(channel->rx_pkt != NULL);
efx_rx_strategy(channel);
+
+ netif_napi_add(channel->napi_dev, &channel->napi_str,
+ efx_poll, napi_weight);
}
}
@@ -424,10 +465,6 @@ static void efx_start_channel(struct efx_channel *channel)
EFX_LOG(channel->efx, "starting chan %d\n", channel->channel);
- if (!(channel->efx->net_dev->flags & IFF_UP))
- netif_napi_add(channel->napi_dev, &channel->napi_str,
- efx_poll, napi_weight);
-
/* The interrupt handler for this channel may set work_pending
* as soon as we enable it. Make sure it's cleared before
* then. Similarly, make sure it sees the enabled flag set. */
@@ -558,6 +595,8 @@ static void efx_link_status_changed(struct efx_nic *efx)
}
+static void efx_fini_port(struct efx_nic *efx);
+
/* This call reinitialises the MAC to pick up new PHY settings. The
* caller must hold the mac_lock */
void __efx_reconfigure_port(struct efx_nic *efx)
@@ -593,8 +632,8 @@ void __efx_reconfigure_port(struct efx_nic *efx)
fail:
EFX_ERR(efx, "failed to reconfigure MAC\n");
- efx->phy_op->fini(efx);
- efx->port_initialized = false;
+ efx->port_enabled = false;
+ efx_fini_port(efx);
}
/* Reinitialise the MAC to pick up new PHY settings, even if the port is
@@ -997,7 +1036,7 @@ static int efx_probe_nic(struct efx_nic *efx)
efx_set_channels(efx);
/* Initialise the interrupt moderation settings */
- efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec);
+ efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true);
return 0;
}
@@ -1194,7 +1233,8 @@ void efx_flush_queues(struct efx_nic *efx)
**************************************************************************/
/* Set interrupt moderation parameters */
-void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs)
+void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs,
+ bool rx_adaptive)
{
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
@@ -1204,6 +1244,8 @@ void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs)
efx_for_each_tx_queue(tx_queue, efx)
tx_queue->channel->irq_moderation = tx_usecs;
+ efx->irq_rx_adaptive = rx_adaptive;
+ efx->irq_rx_moderation = rx_usecs;
efx_for_each_rx_queue(rx_queue, efx)
rx_queue->channel->irq_moderation = rx_usecs;
}
@@ -1276,18 +1318,11 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
static int efx_init_napi(struct efx_nic *efx)
{
struct efx_channel *channel;
- int rc;
efx_for_each_channel(channel, efx) {
channel->napi_dev = efx->net_dev;
- rc = efx_lro_init(&channel->lro_mgr, efx);
- if (rc)
- goto err;
}
return 0;
- err:
- efx_fini_napi(efx);
- return rc;
}
static void efx_fini_napi(struct efx_nic *efx)
@@ -1295,7 +1330,6 @@ static void efx_fini_napi(struct efx_nic *efx)
struct efx_channel *channel;
efx_for_each_channel(channel, efx) {
- efx_lro_fini(&channel->lro_mgr);
channel->napi_dev = NULL;
}
}
@@ -1683,7 +1717,8 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method,
rc = efx->phy_op->init(efx);
if (rc)
ok = false;
- } else
+ }
+ if (!ok)
efx->port_initialized = false;
}
@@ -1864,8 +1899,8 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
static struct efx_board efx_dummy_board_info = {
.init = efx_port_dummy_op_int,
- .init_leds = efx_port_dummy_op_int,
- .set_fault_led = efx_port_dummy_op_blink,
+ .init_leds = efx_port_dummy_op_void,
+ .set_id_led = efx_port_dummy_op_blink,
.monitor = efx_port_dummy_op_int,
.blink = efx_port_dummy_op_blink,
.fini = efx_port_dummy_op_void,
@@ -2127,7 +2162,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
net_dev->features |= (NETIF_F_IP_CSUM | NETIF_F_SG |
NETIF_F_HIGHDMA | NETIF_F_TSO);
if (lro)
- net_dev->features |= NETIF_F_LRO;
+ net_dev->features |= NETIF_F_GRO;
/* Mask for features that also apply to VLAN devices */
net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG |
NETIF_F_HIGHDMA | NETIF_F_TSO);
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 55d0f131b0e9..da157aa74b83 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -52,7 +52,7 @@ extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type);
extern void efx_suspend(struct efx_nic *efx);
extern void efx_resume(struct efx_nic *efx);
extern void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs,
- int rx_usecs);
+ int rx_usecs, bool rx_adaptive);
extern int efx_request_power(struct efx_nic *efx, int mw, const char *name);
extern void efx_hex_dump(const u8 *, unsigned int, const char *);
@@ -80,7 +80,7 @@ static inline void efx_schedule_channel(struct efx_channel *channel)
channel->channel, raw_smp_processor_id());
channel->work_pending = true;
- netif_rx_schedule(&channel->napi_str);
+ napi_schedule(&channel->napi_str);
}
#endif /* EFX_EFX_H */
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 7b5924c039b3..64309f4e8b19 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -529,7 +529,14 @@ static int efx_ethtool_nway_reset(struct net_device *net_dev)
{
struct efx_nic *efx = netdev_priv(net_dev);
- return mii_nway_restart(&efx->mii);
+ if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
+ mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
+ MDIO_MMDREG_CTRL1,
+ __ffs(BMCR_ANRESTART), true);
+ return 0;
+ }
+
+ return -EOPNOTSUPP;
}
static u32 efx_ethtool_get_link(struct net_device *net_dev)
@@ -597,7 +604,6 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev,
{
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_tx_queue *tx_queue;
- struct efx_rx_queue *rx_queue;
struct efx_channel *channel;
memset(coalesce, 0, sizeof(*coalesce));
@@ -615,14 +621,8 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev,
}
}
- /* Find lowest IRQ moderation across all used RX queues */
- coalesce->rx_coalesce_usecs_irq = ~((u32) 0);
- efx_for_each_rx_queue(rx_queue, efx) {
- channel = rx_queue->channel;
- if (channel->irq_moderation < coalesce->rx_coalesce_usecs_irq)
- coalesce->rx_coalesce_usecs_irq =
- channel->irq_moderation;
- }
+ coalesce->use_adaptive_rx_coalesce = efx->irq_rx_adaptive;
+ coalesce->rx_coalesce_usecs_irq = efx->irq_rx_moderation;
return 0;
}
@@ -636,10 +636,9 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
- unsigned tx_usecs, rx_usecs;
+ unsigned tx_usecs, rx_usecs, adaptive;
- if (coalesce->use_adaptive_rx_coalesce ||
- coalesce->use_adaptive_tx_coalesce)
+ if (coalesce->use_adaptive_tx_coalesce)
return -EOPNOTSUPP;
if (coalesce->rx_coalesce_usecs || coalesce->tx_coalesce_usecs) {
@@ -650,6 +649,7 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
rx_usecs = coalesce->rx_coalesce_usecs_irq;
tx_usecs = coalesce->tx_coalesce_usecs_irq;
+ adaptive = coalesce->use_adaptive_rx_coalesce;
/* If the channel is shared only allow RX parameters to be set */
efx_for_each_tx_queue(tx_queue, efx) {
@@ -661,7 +661,7 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev,
}
}
- efx_init_irq_moderation(efx, tx_usecs, rx_usecs);
+ efx_init_irq_moderation(efx, tx_usecs, rx_usecs, adaptive);
/* Reset channel to pick up new moderation value. Note that
* this may change the value of the irq_moderation field
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 064307c2277e..d4629ab2c614 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -39,11 +39,16 @@
* @next_buffer_table: First available buffer table id
* @pci_dev2: The secondary PCI device if present
* @i2c_data: Operations and state for I2C bit-bashing algorithm
+ * @int_error_count: Number of internal errors seen recently
+ * @int_error_expire: Time at which error count will be expired
*/
struct falcon_nic_data {
unsigned next_buffer_table;
struct pci_dev *pci_dev2;
struct i2c_algo_bit_data i2c_data;
+
+ unsigned int_error_count;
+ unsigned long int_error_expire;
};
/**************************************************************************
@@ -119,8 +124,12 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold");
#define FALCON_EVQ_SIZE 4096
#define FALCON_EVQ_MASK (FALCON_EVQ_SIZE - 1)
-/* Max number of internal errors. After this resets will not be performed */
-#define FALCON_MAX_INT_ERRORS 4
+/* If FALCON_MAX_INT_ERRORS internal errors occur within
+ * FALCON_INT_ERROR_EXPIRE seconds, we consider the NIC broken and
+ * disable it.
+ */
+#define FALCON_INT_ERROR_EXPIRE 3600
+#define FALCON_MAX_INT_ERRORS 5
/* We poll for events every FLUSH_INTERVAL ms, and check FLUSH_POLL_COUNT times
*/
@@ -146,13 +155,6 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold");
/* Dummy SRAM size code */
#define SRM_NB_BSZ_ONCHIP_ONLY (-1)
-/* Be nice if these (or equiv.) were in linux/pci_regs.h, but they're not. */
-#define PCI_EXP_DEVCAP_PWR_VAL_LBN 18
-#define PCI_EXP_DEVCAP_PWR_SCL_LBN 26
-#define PCI_EXP_DEVCTL_PAYLOAD_LBN 5
-#define PCI_EXP_LNKSTA_LNK_WID 0x3f0
-#define PCI_EXP_LNKSTA_LNK_WID_LBN 4
-
#define FALCON_IS_DUAL_FUNC(efx) \
(falcon_rev(efx) < FALCON_REV_B0)
@@ -727,6 +729,9 @@ static void falcon_handle_tx_event(struct efx_channel *channel,
tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, TX_EV_DESC_PTR);
tx_ev_q_label = EFX_QWORD_FIELD(*event, TX_EV_Q_LABEL);
tx_queue = &efx->tx_queue[tx_ev_q_label];
+ channel->irq_mod_score +=
+ (tx_ev_desc_ptr - tx_queue->read_count) &
+ efx->type->txd_ring_mask;
efx_xmit_done(tx_queue, tx_ev_desc_ptr);
} else if (EFX_QWORD_FIELD(*event, TX_EV_WQ_FF_FULL)) {
/* Rewrite the FIFO write pointer */
@@ -896,6 +901,8 @@ static void falcon_handle_rx_event(struct efx_channel *channel,
discard = true;
}
+ channel->irq_mod_score += 2;
+
/* Handle received packet */
efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt,
checksummed, discard);
@@ -1073,14 +1080,15 @@ void falcon_set_int_moderation(struct efx_channel *channel)
* program is based at 0. So actual interrupt moderation
* achieved is ((x + 1) * res).
*/
- unsigned int res = 5;
- channel->irq_moderation -= (channel->irq_moderation % res);
- if (channel->irq_moderation < res)
- channel->irq_moderation = res;
+ channel->irq_moderation -= (channel->irq_moderation %
+ FALCON_IRQ_MOD_RESOLUTION);
+ if (channel->irq_moderation < FALCON_IRQ_MOD_RESOLUTION)
+ channel->irq_moderation = FALCON_IRQ_MOD_RESOLUTION;
EFX_POPULATE_DWORD_2(timer_cmd,
TIMER_MODE, TIMER_MODE_INT_HLDOFF,
TIMER_VAL,
- (channel->irq_moderation / res) - 1);
+ channel->irq_moderation /
+ FALCON_IRQ_MOD_RESOLUTION - 1);
} else {
EFX_POPULATE_DWORD_2(timer_cmd,
TIMER_MODE, TIMER_MODE_DIS,
@@ -1187,31 +1195,29 @@ static void falcon_poll_flush_events(struct efx_nic *efx)
struct efx_channel *channel = &efx->channel[0];
struct efx_tx_queue *tx_queue;
struct efx_rx_queue *rx_queue;
- unsigned int read_ptr, i;
+ unsigned int read_ptr = channel->eventq_read_ptr;
+ unsigned int end_ptr = (read_ptr - 1) & FALCON_EVQ_MASK;
- read_ptr = channel->eventq_read_ptr;
- for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
+ do {
efx_qword_t *event = falcon_event(channel, read_ptr);
int ev_code, ev_sub_code, ev_queue;
bool ev_failed;
+
if (!falcon_event_present(event))
break;
ev_code = EFX_QWORD_FIELD(*event, EV_CODE);
- if (ev_code != DRIVER_EV_DECODE)
- continue;
-
ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
- switch (ev_sub_code) {
- case TX_DESCQ_FLS_DONE_EV_DECODE:
+ if (ev_code == DRIVER_EV_DECODE &&
+ ev_sub_code == TX_DESCQ_FLS_DONE_EV_DECODE) {
ev_queue = EFX_QWORD_FIELD(*event,
DRIVER_EV_TX_DESCQ_ID);
if (ev_queue < EFX_TX_QUEUE_COUNT) {
tx_queue = efx->tx_queue + ev_queue;
tx_queue->flushed = true;
}
- break;
- case RX_DESCQ_FLS_DONE_EV_DECODE:
+ } else if (ev_code == DRIVER_EV_DECODE &&
+ ev_sub_code == RX_DESCQ_FLS_DONE_EV_DECODE) {
ev_queue = EFX_QWORD_FIELD(*event,
DRIVER_EV_RX_DESCQ_ID);
ev_failed = EFX_QWORD_FIELD(*event,
@@ -1225,11 +1231,10 @@ static void falcon_poll_flush_events(struct efx_nic *efx)
else
rx_queue->flushed = true;
}
- break;
}
read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
- }
+ } while (read_ptr != end_ptr);
}
/* Handle tx and rx flushes at the same time, since they run in
@@ -1377,7 +1382,6 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx)
efx_oword_t *int_ker = efx->irq_status.addr;
efx_oword_t fatal_intr;
int error, mem_perr;
- static int n_int_errors;
falcon_read(efx, &fatal_intr, FATAL_INTR_REG_KER);
error = EFX_OWORD_FIELD(fatal_intr, INT_KER_ERROR);
@@ -1404,7 +1408,14 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx)
pci_clear_master(nic_data->pci_dev2);
falcon_disable_interrupts(efx);
- if (++n_int_errors < FALCON_MAX_INT_ERRORS) {
+ /* Count errors and reset or disable the NIC accordingly */
+ if (nic_data->int_error_count == 0 ||
+ time_after(jiffies, nic_data->int_error_expire)) {
+ nic_data->int_error_count = 0;
+ nic_data->int_error_expire =
+ jiffies + FALCON_INT_ERROR_EXPIRE * HZ;
+ }
+ if (++nic_data->int_error_count < FALCON_MAX_INT_ERRORS) {
EFX_ERR(efx, "SYSTEM ERROR - reset scheduled\n");
efx_schedule_reset(efx, RESET_TYPE_INT_ERROR);
} else {
@@ -1423,6 +1434,7 @@ static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id)
{
struct efx_nic *efx = dev_id;
efx_oword_t *int_ker = efx->irq_status.addr;
+ irqreturn_t result = IRQ_NONE;
struct efx_channel *channel;
efx_dword_t reg;
u32 queues;
@@ -1437,23 +1449,24 @@ static irqreturn_t falcon_legacy_interrupt_b0(int irq, void *dev_id)
if (unlikely(syserr))
return falcon_fatal_interrupt(efx);
- if (queues == 0)
- return IRQ_NONE;
-
- efx->last_irq_cpu = raw_smp_processor_id();
- EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n",
- irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg));
-
/* Schedule processing of any interrupting queues */
- channel = &efx->channel[0];
- while (queues) {
- if (queues & 0x01)
+ efx_for_each_channel(channel, efx) {
+ if ((queues & 1) ||
+ falcon_event_present(
+ falcon_event(channel, channel->eventq_read_ptr))) {
efx_schedule_channel(channel);
- channel++;
+ result = IRQ_HANDLED;
+ }
queues >>= 1;
}
- return IRQ_HANDLED;
+ if (result == IRQ_HANDLED) {
+ efx->last_irq_cpu = raw_smp_processor_id();
+ EFX_TRACE(efx, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n",
+ irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg));
+ }
+
+ return result;
}
@@ -2249,6 +2262,7 @@ static int falcon_probe_phy(struct efx_nic *efx)
efx->phy_op = &falcon_sft9001_phy_ops;
break;
case PHY_TYPE_QT2022C2:
+ case PHY_TYPE_QT2025C:
efx->phy_op = &falcon_xfp_phy_ops;
break;
default:
@@ -3113,8 +3127,10 @@ void falcon_remove_nic(struct efx_nic *efx)
struct falcon_nic_data *nic_data = efx->nic_data;
int rc;
+ /* Remove I2C adapter and clear it in preparation for a retry */
rc = i2c_del_adapter(&efx->i2c_adap);
BUG_ON(rc);
+ memset(&efx->i2c_adap, 0, sizeof(efx->i2c_adap));
falcon_remove_spi_devices(efx);
falcon_free_buffer(efx, &efx->irq_status);
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index 7869c3d74383..77f2e0db7ca1 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -85,6 +85,8 @@ extern void falcon_set_int_moderation(struct efx_channel *channel);
extern void falcon_disable_interrupts(struct efx_nic *efx);
extern void falcon_fini_interrupt(struct efx_nic *efx);
+#define FALCON_IRQ_MOD_RESOLUTION 5
+
/* Global Resources */
extern int falcon_probe_nic(struct efx_nic *efx);
extern int falcon_probe_resources(struct efx_nic *efx);
diff --git a/drivers/net/sfc/falcon_io.h b/drivers/net/sfc/falcon_io.h
index c16da3149fa9..8883092dae97 100644
--- a/drivers/net/sfc/falcon_io.h
+++ b/drivers/net/sfc/falcon_io.h
@@ -238,18 +238,21 @@ static inline void falcon_writel_page(struct efx_nic *efx, efx_dword_t *value,
/* Write dword to Falcon page-mapped register with an extra lock.
*
* As for falcon_writel_page(), but for a register that suffers from
- * SFC bug 3181. Take out a lock so the BIU collector cannot be
- * confused. */
+ * SFC bug 3181. If writing to page 0, take out a lock so the BIU
+ * collector cannot be confused.
+ */
static inline void falcon_writel_page_locked(struct efx_nic *efx,
efx_dword_t *value,
unsigned int reg,
unsigned int page)
{
- unsigned long flags;
+ unsigned long flags = 0;
- spin_lock_irqsave(&efx->biu_lock, flags);
+ if (page == 0)
+ spin_lock_irqsave(&efx->biu_lock, flags);
falcon_writel(efx, value, FALCON_PAGED_REG(page, reg));
- spin_unlock_irqrestore(&efx->biu_lock, flags);
+ if (page == 0)
+ spin_unlock_irqrestore(&efx->biu_lock, flags);
}
#endif /* EFX_FALCON_IO_H */
diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c
index f9e2f95c3b48..9f5ec3eb3418 100644
--- a/drivers/net/sfc/mdio_10g.c
+++ b/drivers/net/sfc/mdio_10g.c
@@ -17,6 +17,21 @@
#include "boards.h"
#include "workarounds.h"
+unsigned mdio_id_oui(u32 id)
+{
+ unsigned oui = 0;
+ int i;
+
+ /* The bits of the OUI are designated a..x, with a=0 and b variable.
+ * In the id register c is the MSB but the OUI is conventionally
+ * written as bytes h..a, p..i, x..q. Reorder the bits accordingly. */
+ for (i = 0; i < 22; ++i)
+ if (id & (1 << (i + 10)))
+ oui |= 1 << (i ^ 7);
+
+ return oui;
+}
+
int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
int spins, int spintime)
{
@@ -125,24 +140,25 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
int mdio_clause45_check_mmds(struct efx_nic *efx,
unsigned int mmd_mask, unsigned int fatal_mask)
{
+ int mmd = 0, probe_mmd, devs0, devs1;
u32 devices;
- int mmd = 0, probe_mmd;
/* Historically we have probed the PHYXS to find out what devices are
* present,but that doesn't work so well if the PHYXS isn't expected
* to exist, if so just find the first item in the list supplied. */
probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
__ffs(mmd_mask);
- devices = (mdio_clause45_read(efx, efx->mii.phy_id,
- probe_mmd, MDIO_MMDREG_DEVS0) |
- mdio_clause45_read(efx, efx->mii.phy_id,
- probe_mmd, MDIO_MMDREG_DEVS1) << 16);
/* Check all the expected MMDs are present */
- if (devices < 0) {
+ devs0 = mdio_clause45_read(efx, efx->mii.phy_id,
+ probe_mmd, MDIO_MMDREG_DEVS0);
+ devs1 = mdio_clause45_read(efx, efx->mii.phy_id,
+ probe_mmd, MDIO_MMDREG_DEVS1);
+ if (devs0 < 0 || devs1 < 0) {
EFX_ERR(efx, "failed to read devices present\n");
return -EIO;
}
+ devices = devs0 | (devs1 << 16);
if ((devices & mmd_mask) != mmd_mask) {
EFX_ERR(efx, "required MMDs not present: got %x, "
"wanted %x\n", devices, mmd_mask);
diff --git a/drivers/net/sfc/mdio_10g.h b/drivers/net/sfc/mdio_10g.h
index 8ba49773ce7e..7014d2279c20 100644
--- a/drivers/net/sfc/mdio_10g.h
+++ b/drivers/net/sfc/mdio_10g.h
@@ -70,10 +70,10 @@
#define MDIO_MMDREG_STAT1_LPABLE_LBN (1)
#define MDIO_MMDREG_STAT1_LPABLE_WIDTH (1)
-/* Bits in ID reg */
-#define MDIO_ID_REV(_id32) (_id32 & 0xf)
-#define MDIO_ID_MODEL(_id32) ((_id32 >> 4) & 0x3f)
-#define MDIO_ID_OUI(_id32) (_id32 >> 10)
+/* Bits in combined ID regs */
+static inline unsigned mdio_id_rev(u32 id) { return id & 0xf; }
+static inline unsigned mdio_id_model(u32 id) { return (id >> 4) & 0x3f; }
+extern unsigned mdio_id_oui(u32 id);
/* Bits in MMDREG_DEVS0/1. Someone thoughtfully layed things out
* so the 'bit present' bit number of an MMD is the number of
diff --git a/drivers/net/sfc/mtd.c b/drivers/net/sfc/mtd.c
index 665cafb88d6a..820c233c3ea0 100644
--- a/drivers/net/sfc/mtd.c
+++ b/drivers/net/sfc/mtd.c
@@ -15,6 +15,7 @@
#define EFX_DRIVER_NAME "sfc_mtd"
#include "net_driver.h"
#include "spi.h"
+#include "efx.h"
#define EFX_SPI_VERIFY_BUF_LEN 16
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index e019ad1fb9a0..e169e5dcd1e6 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -25,15 +25,11 @@
#include <linux/device.h>
#include <linux/highmem.h>
#include <linux/workqueue.h>
-#include <linux/inet_lro.h>
#include <linux/i2c.h>
#include "enum.h"
#include "bitfield.h"
-#define EFX_MAX_LRO_DESCRIPTORS 8
-#define EFX_MAX_LRO_AGGR MAX_SKB_FRAGS
-
/**************************************************************************
*
* Build definitions
@@ -340,13 +336,12 @@ enum efx_rx_alloc_method {
* @eventq_read_ptr: Event queue read pointer
* @last_eventq_read_ptr: Last event queue read pointer value.
* @eventq_magic: Event queue magic value for driver-generated test events
- * @lro_mgr: LRO state
+ * @irq_count: Number of IRQs since last adaptive moderation decision
+ * @irq_mod_score: IRQ moderation score
* @rx_alloc_level: Watermark based heuristic counter for pushing descriptors
* and diagnostic counters
* @rx_alloc_push_pages: RX allocation method currently in use for pushing
* descriptors
- * @rx_alloc_pop_pages: RX allocation method currently in use for popping
- * descriptors
* @n_rx_tobe_disc: Count of RX_TOBE_DISC errors
* @n_rx_ip_frag_err: Count of RX IP fragment errors
* @n_rx_ip_hdr_chksum_err: Count of RX IP header checksum errors
@@ -371,10 +366,11 @@ struct efx_channel {
unsigned int last_eventq_read_ptr;
unsigned int eventq_magic;
- struct net_lro_mgr lro_mgr;
+ unsigned int irq_count;
+ unsigned int irq_mod_score;
+
int rx_alloc_level;
int rx_alloc_push_pages;
- int rx_alloc_pop_pages;
unsigned n_rx_tobe_disc;
unsigned n_rx_ip_frag_err;
@@ -394,13 +390,11 @@ struct efx_channel {
/**
* struct efx_blinker - S/W LED blinking context
- * @led_num: LED ID (board-specific meaning)
* @state: Current state - on or off
* @resubmit: Timer resubmission flag
* @timer: Control timer for blinking
*/
struct efx_blinker {
- int led_num;
bool state;
bool resubmit;
struct timer_list timer;
@@ -413,8 +407,8 @@ struct efx_blinker {
* @major: Major rev. ('A', 'B' ...)
* @minor: Minor rev. (0, 1, ...)
* @init: Initialisation function
- * @init_leds: Sets up board LEDs
- * @set_fault_led: Turns the fault LED on or off
+ * @init_leds: Sets up board LEDs. May be called repeatedly.
+ * @set_id_led: Turns the identification LED on or off
* @blink: Starts/stops blinking
* @monitor: Board-specific health check function
* @fini: Cleanup function
@@ -430,9 +424,9 @@ struct efx_board {
/* As the LEDs are typically attached to the PHY, LEDs
* have a separate init callback that happens later than
* board init. */
- int (*init_leds)(struct efx_nic *efx);
+ void (*init_leds)(struct efx_nic *efx);
+ void (*set_id_led) (struct efx_nic *efx, bool state);
int (*monitor) (struct efx_nic *nic);
- void (*set_fault_led) (struct efx_nic *efx, bool state);
void (*blink) (struct efx_nic *efx, bool start);
void (*fini) (struct efx_nic *nic);
struct efx_blinker blinker;
@@ -459,6 +453,7 @@ enum phy_type {
PHY_TYPE_QT2022C2 = 4,
PHY_TYPE_PM8358 = 6,
PHY_TYPE_SFT9001A = 8,
+ PHY_TYPE_QT2025C = 9,
PHY_TYPE_SFT9001B = 10,
PHY_TYPE_MAX /* Insert any new items before this */
};
@@ -713,6 +708,8 @@ union efx_multicast_hash {
* @membase: Memory BAR value
* @biu_lock: BIU (bus interface unit) lock
* @interrupt_mode: Interrupt mode
+ * @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues
+ * @irq_rx_moderation: IRQ moderation time for RX event queues
* @i2c_adap: I2C adapter
* @board_info: Board-level information
* @state: Device state flag. Serialised by the rtnl_lock.
@@ -794,6 +791,8 @@ struct efx_nic {
void __iomem *membase;
spinlock_t biu_lock;
enum efx_int_mode interrupt_mode;
+ bool irq_rx_adaptive;
+ unsigned int irq_rx_moderation;
struct i2c_adapter i2c_adap;
struct efx_board board_info;
diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h
index 07e855c148bc..c1cff9c0c173 100644
--- a/drivers/net/sfc/phy.h
+++ b/drivers/net/sfc/phy.h
@@ -18,12 +18,16 @@ extern struct efx_phy_operations falcon_sft9001_phy_ops;
extern void tenxpress_phy_blink(struct efx_nic *efx, bool blink);
+/* Wait for the PHY to boot. Return 0 on success, -EINVAL if the PHY failed
+ * to boot due to corrupt flash, or some other negative error code. */
+extern int sft9001_wait_boot(struct efx_nic *efx);
+
/****************************************************************************
- * Exported functions from the driver for XFP optical PHYs
+ * AMCC/Quake QT20xx PHYs
*/
extern struct efx_phy_operations falcon_xfp_phy_ops;
-/* The QUAKE XFP PHY provides various H/W control states for LEDs */
+/* These PHYs provide various H/W control states for LEDs */
#define QUAKE_LED_LINK_INVAL (0)
#define QUAKE_LED_LINK_STAT (1)
#define QUAKE_LED_LINK_ACT (2)
diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c
index b8ba4bbad889..66d7fe3db3e6 100644
--- a/drivers/net/sfc/rx.c
+++ b/drivers/net/sfc/rx.c
@@ -99,109 +99,6 @@ static inline unsigned int efx_rx_buf_size(struct efx_nic *efx)
}
-/**************************************************************************
- *
- * Linux generic LRO handling
- *
- **************************************************************************
- */
-
-static int efx_lro_get_skb_hdr(struct sk_buff *skb, void **ip_hdr,
- void **tcpudp_hdr, u64 *hdr_flags, void *priv)
-{
- struct efx_channel *channel = priv;
- struct iphdr *iph;
- struct tcphdr *th;
-
- iph = (struct iphdr *)skb->data;
- if (skb->protocol != htons(ETH_P_IP) || iph->protocol != IPPROTO_TCP)
- goto fail;
-
- th = (struct tcphdr *)(skb->data + iph->ihl * 4);
-
- *tcpudp_hdr = th;
- *ip_hdr = iph;
- *hdr_flags = LRO_IPV4 | LRO_TCP;
-
- channel->rx_alloc_level += RX_ALLOC_FACTOR_LRO;
- return 0;
-fail:
- channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
- return -1;
-}
-
-static int efx_get_frag_hdr(struct skb_frag_struct *frag, void **mac_hdr,
- void **ip_hdr, void **tcpudp_hdr, u64 *hdr_flags,
- void *priv)
-{
- struct efx_channel *channel = priv;
- struct ethhdr *eh;
- struct iphdr *iph;
-
- /* We support EtherII and VLAN encapsulated IPv4 */
- eh = page_address(frag->page) + frag->page_offset;
- *mac_hdr = eh;
-
- if (eh->h_proto == htons(ETH_P_IP)) {
- iph = (struct iphdr *)(eh + 1);
- } else {
- struct vlan_ethhdr *veh = (struct vlan_ethhdr *)eh;
- if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP))
- goto fail;
-
- iph = (struct iphdr *)(veh + 1);
- }
- *ip_hdr = iph;
-
- /* We can only do LRO over TCP */
- if (iph->protocol != IPPROTO_TCP)
- goto fail;
-
- *hdr_flags = LRO_IPV4 | LRO_TCP;
- *tcpudp_hdr = (struct tcphdr *)((u8 *) iph + iph->ihl * 4);
-
- channel->rx_alloc_level += RX_ALLOC_FACTOR_LRO;
- return 0;
- fail:
- channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
- return -1;
-}
-
-int efx_lro_init(struct net_lro_mgr *lro_mgr, struct efx_nic *efx)
-{
- size_t s = sizeof(struct net_lro_desc) * EFX_MAX_LRO_DESCRIPTORS;
- struct net_lro_desc *lro_arr;
-
- /* Allocate the LRO descriptors structure */
- lro_arr = kzalloc(s, GFP_KERNEL);
- if (lro_arr == NULL)
- return -ENOMEM;
-
- lro_mgr->lro_arr = lro_arr;
- lro_mgr->max_desc = EFX_MAX_LRO_DESCRIPTORS;
- lro_mgr->max_aggr = EFX_MAX_LRO_AGGR;
- lro_mgr->frag_align_pad = EFX_PAGE_SKB_ALIGN;
-
- lro_mgr->get_skb_header = efx_lro_get_skb_hdr;
- lro_mgr->get_frag_header = efx_get_frag_hdr;
- lro_mgr->dev = efx->net_dev;
-
- lro_mgr->features = LRO_F_NAPI;
-
- /* We can pass packets up with the checksum intact */
- lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
-
- lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
-
- return 0;
-}
-
-void efx_lro_fini(struct net_lro_mgr *lro_mgr)
-{
- kfree(lro_mgr->lro_arr);
- lro_mgr->lro_arr = NULL;
-}
-
/**
* efx_init_rx_buffer_skb - create new RX buffer using skb-based allocation
*
@@ -549,77 +446,31 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue,
static void efx_rx_packet_lro(struct efx_channel *channel,
struct efx_rx_buffer *rx_buf)
{
- struct net_lro_mgr *lro_mgr = &channel->lro_mgr;
- void *priv = channel;
+ struct napi_struct *napi = &channel->napi_str;
/* Pass the skb/page into the LRO engine */
if (rx_buf->page) {
- struct skb_frag_struct frags;
+ struct napi_gro_fraginfo info;
- frags.page = rx_buf->page;
- frags.page_offset = efx_rx_buf_offset(rx_buf);
- frags.size = rx_buf->len;
+ info.frags[0].page = rx_buf->page;
+ info.frags[0].page_offset = efx_rx_buf_offset(rx_buf);
+ info.frags[0].size = rx_buf->len;
+ info.nr_frags = 1;
+ info.ip_summed = CHECKSUM_UNNECESSARY;
+ info.len = rx_buf->len;
- lro_receive_frags(lro_mgr, &frags, rx_buf->len,
- rx_buf->len, priv, 0);
+ napi_gro_frags(napi, &info);
EFX_BUG_ON_PARANOID(rx_buf->skb);
rx_buf->page = NULL;
} else {
EFX_BUG_ON_PARANOID(!rx_buf->skb);
- lro_receive_skb(lro_mgr, rx_buf->skb, priv);
+ napi_gro_receive(napi, rx_buf->skb);
rx_buf->skb = NULL;
}
}
-/* Allocate and construct an SKB around a struct page.*/
-static struct sk_buff *efx_rx_mk_skb(struct efx_rx_buffer *rx_buf,
- struct efx_nic *efx,
- int hdr_len)
-{
- struct sk_buff *skb;
-
- /* Allocate an SKB to store the headers */
- skb = netdev_alloc_skb(efx->net_dev, hdr_len + EFX_PAGE_SKB_ALIGN);
- if (unlikely(skb == NULL)) {
- EFX_ERR_RL(efx, "RX out of memory for skb\n");
- return NULL;
- }
-
- EFX_BUG_ON_PARANOID(skb_shinfo(skb)->nr_frags);
- EFX_BUG_ON_PARANOID(rx_buf->len < hdr_len);
-
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- skb_reserve(skb, EFX_PAGE_SKB_ALIGN);
-
- skb->len = rx_buf->len;
- skb->truesize = rx_buf->len + sizeof(struct sk_buff);
- memcpy(skb->data, rx_buf->data, hdr_len);
- skb->tail += hdr_len;
-
- /* Append the remaining page onto the frag list */
- if (unlikely(rx_buf->len > hdr_len)) {
- struct skb_frag_struct *frag = skb_shinfo(skb)->frags;
- frag->page = rx_buf->page;
- frag->page_offset = efx_rx_buf_offset(rx_buf) + hdr_len;
- frag->size = skb->len - hdr_len;
- skb_shinfo(skb)->nr_frags = 1;
- skb->data_len = frag->size;
- } else {
- __free_pages(rx_buf->page, efx->rx_buffer_order);
- skb->data_len = 0;
- }
-
- /* Ownership has transferred from the rx_buf to skb */
- rx_buf->page = NULL;
-
- /* Move past the ethernet header */
- skb->protocol = eth_type_trans(skb, efx->net_dev);
-
- return skb;
-}
-
void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
unsigned int len, bool checksummed, bool discard)
{
@@ -687,7 +538,6 @@ void __efx_rx_packet(struct efx_channel *channel,
{
struct efx_nic *efx = channel->efx;
struct sk_buff *skb;
- bool lro = !!(efx->net_dev->features & NETIF_F_LRO);
/* If we're in loopback test, then pass the packet directly to the
* loopback layer, and free the rx_buf here
@@ -709,41 +559,23 @@ void __efx_rx_packet(struct efx_channel *channel,
efx->net_dev);
}
- /* Both our generic-LRO and SFC-SSR support skb and page based
- * allocation, but neither support switching from one to the
- * other on the fly. If we spot that the allocation mode has
- * changed, then flush the LRO state.
- */
- if (unlikely(channel->rx_alloc_pop_pages != (rx_buf->page != NULL))) {
- efx_flush_lro(channel);
- channel->rx_alloc_pop_pages = (rx_buf->page != NULL);
- }
- if (likely(checksummed && lro)) {
+ if (likely(checksummed || rx_buf->page)) {
efx_rx_packet_lro(channel, rx_buf);
goto done;
}
- /* Form an skb if required */
- if (rx_buf->page) {
- int hdr_len = min(rx_buf->len, EFX_SKB_HEADERS);
- skb = efx_rx_mk_skb(rx_buf, efx, hdr_len);
- if (unlikely(skb == NULL)) {
- efx_free_rx_buffer(efx, rx_buf);
- goto done;
- }
- } else {
- /* We now own the SKB */
- skb = rx_buf->skb;
- rx_buf->skb = NULL;
- }
+ /* We now own the SKB */
+ skb = rx_buf->skb;
+ rx_buf->skb = NULL;
EFX_BUG_ON_PARANOID(rx_buf->page);
EFX_BUG_ON_PARANOID(rx_buf->skb);
EFX_BUG_ON_PARANOID(!skb);
/* Set the SKB flags */
- if (unlikely(!checksummed || !efx->rx_checksum_enabled))
- skb->ip_summed = CHECKSUM_NONE;
+ skb->ip_summed = CHECKSUM_NONE;
+
+ skb_record_rx_queue(skb, channel->channel);
/* Pass the packet up */
netif_receive_skb(skb);
@@ -760,7 +592,7 @@ void efx_rx_strategy(struct efx_channel *channel)
enum efx_rx_alloc_method method = rx_alloc_method;
/* Only makes sense to use page based allocation if LRO is enabled */
- if (!(channel->efx->net_dev->features & NETIF_F_LRO)) {
+ if (!(channel->efx->net_dev->features & NETIF_F_GRO)) {
method = RX_ALLOC_METHOD_SKB;
} else if (method == RX_ALLOC_METHOD_AUTO) {
/* Constrain the rx_alloc_level */
@@ -865,11 +697,6 @@ void efx_remove_rx_queue(struct efx_rx_queue *rx_queue)
rx_queue->buffer = NULL;
}
-void efx_flush_lro(struct efx_channel *channel)
-{
- lro_flush_all(&channel->lro_mgr);
-}
-
module_param(rx_alloc_method, int, 0644);
MODULE_PARM_DESC(rx_alloc_method, "Allocation method used for RX buffers");
diff --git a/drivers/net/sfc/rx.h b/drivers/net/sfc/rx.h
index 0e88a9ddc1c6..42ee7555a80b 100644
--- a/drivers/net/sfc/rx.h
+++ b/drivers/net/sfc/rx.h
@@ -17,9 +17,6 @@ void efx_remove_rx_queue(struct efx_rx_queue *rx_queue);
void efx_init_rx_queue(struct efx_rx_queue *rx_queue);
void efx_fini_rx_queue(struct efx_rx_queue *rx_queue);
-int efx_lro_init(struct net_lro_mgr *lro_mgr, struct efx_nic *efx);
-void efx_lro_fini(struct net_lro_mgr *lro_mgr);
-void efx_flush_lro(struct efx_channel *channel);
void efx_rx_strategy(struct efx_channel *channel);
void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue);
void efx_rx_work(struct work_struct *data);
diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c
index cb25ae5b257a..4eac5da81e5a 100644
--- a/drivers/net/sfc/sfe4001.c
+++ b/drivers/net/sfc/sfe4001.c
@@ -24,6 +24,7 @@
*/
#include <linux/delay.h>
+#include <linux/rtnetlink.h>
#include "net_driver.h"
#include "efx.h"
#include "phy.h"
@@ -398,6 +399,7 @@ static struct i2c_board_info sfn4111t_r5_hwmon_info = {
int sfn4111t_init(struct efx_nic *efx)
{
+ int i = 0;
int rc;
efx->board_info.hwmon_client =
@@ -416,13 +418,20 @@ int sfn4111t_init(struct efx_nic *efx)
if (rc)
goto fail_hwmon;
- if (efx->phy_mode & PHY_MODE_SPECIAL) {
- efx_stats_disable(efx);
- sfn4111t_reset(efx);
- }
-
- return 0;
+ do {
+ if (efx->phy_mode & PHY_MODE_SPECIAL) {
+ /* PHY may not generate a 156.25 MHz clock and MAC
+ * stats fetch will fail. */
+ efx_stats_disable(efx);
+ sfn4111t_reset(efx);
+ }
+ rc = sft9001_wait_boot(efx);
+ if (rc == 0)
+ return 0;
+ efx->phy_mode = PHY_MODE_SPECIAL;
+ } while (rc == -EINVAL && ++i < 2);
+ device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
fail_hwmon:
i2c_unregister_device(efx->board_info.hwmon_client);
return rc;
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index f0efd246962c..e61dc4d4741c 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -8,6 +8,7 @@
*/
#include <linux/delay.h>
+#include <linux/rtnetlink.h>
#include <linux/seq_file.h>
#include "efx.h"
#include "mdio_10g.h"
@@ -157,14 +158,16 @@
#define PCS_10GBASET_BLKLK_WIDTH 1
/* Boot status register */
-#define PCS_BOOT_STATUS_REG 53248
-#define PCS_BOOT_FATAL_ERR_LBN (0)
-#define PCS_BOOT_PROGRESS_LBN (1)
-#define PCS_BOOT_PROGRESS_WIDTH (2)
-#define PCS_BOOT_COMPLETE_LBN (3)
-
-#define PCS_BOOT_MAX_DELAY (100)
-#define PCS_BOOT_POLL_DELAY (10)
+#define PCS_BOOT_STATUS_REG 53248
+#define PCS_BOOT_FATAL_ERROR_LBN 0
+#define PCS_BOOT_PROGRESS_LBN 1
+#define PCS_BOOT_PROGRESS_WIDTH 2
+#define PCS_BOOT_PROGRESS_INIT 0
+#define PCS_BOOT_PROGRESS_WAIT_MDIO 1
+#define PCS_BOOT_PROGRESS_CHECKSUM 2
+#define PCS_BOOT_PROGRESS_JUMP 3
+#define PCS_BOOT_DOWNLOAD_WAIT_LBN 3
+#define PCS_BOOT_CODE_STARTED_LBN 4
/* 100M/1G PHY registers */
#define GPHY_XCONTROL_REG 49152
@@ -229,40 +232,62 @@ static ssize_t set_phy_short_reach(struct device *dev,
static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach,
set_phy_short_reach);
-/* Check that the C166 has booted successfully */
-static int tenxpress_phy_check(struct efx_nic *efx)
+int sft9001_wait_boot(struct efx_nic *efx)
{
- int phy_id = efx->mii.phy_id;
- int count = PCS_BOOT_MAX_DELAY / PCS_BOOT_POLL_DELAY;
+ unsigned long timeout = jiffies + HZ + 1;
int boot_stat;
- /* Wait for the boot to complete (or not) */
- while (count) {
- boot_stat = mdio_clause45_read(efx, phy_id,
+ for (;;) {
+ boot_stat = mdio_clause45_read(efx, efx->mii.phy_id,
MDIO_MMD_PCS,
PCS_BOOT_STATUS_REG);
- if (boot_stat & (1 << PCS_BOOT_COMPLETE_LBN))
- break;
- count--;
- udelay(PCS_BOOT_POLL_DELAY);
- }
+ if (boot_stat >= 0) {
+ EFX_LOG(efx, "PHY boot status = %#x\n", boot_stat);
+ switch (boot_stat &
+ ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
+ (3 << PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) |
+ (1 << PCS_BOOT_CODE_STARTED_LBN))) {
+ case ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
+ (PCS_BOOT_PROGRESS_CHECKSUM <<
+ PCS_BOOT_PROGRESS_LBN)):
+ case ((1 << PCS_BOOT_FATAL_ERROR_LBN) |
+ (PCS_BOOT_PROGRESS_INIT <<
+ PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)):
+ return -EINVAL;
+ case ((PCS_BOOT_PROGRESS_WAIT_MDIO <<
+ PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)):
+ return (efx->phy_mode & PHY_MODE_SPECIAL) ?
+ 0 : -EIO;
+ case ((PCS_BOOT_PROGRESS_JUMP <<
+ PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_CODE_STARTED_LBN)):
+ case ((PCS_BOOT_PROGRESS_JUMP <<
+ PCS_BOOT_PROGRESS_LBN) |
+ (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) |
+ (1 << PCS_BOOT_CODE_STARTED_LBN)):
+ return (efx->phy_mode & PHY_MODE_SPECIAL) ?
+ -EIO : 0;
+ default:
+ if (boot_stat & (1 << PCS_BOOT_FATAL_ERROR_LBN))
+ return -EIO;
+ break;
+ }
+ }
- if (!count) {
- EFX_ERR(efx, "%s: PHY boot timed out. Last status "
- "%x\n", __func__,
- (boot_stat >> PCS_BOOT_PROGRESS_LBN) &
- ((1 << PCS_BOOT_PROGRESS_WIDTH) - 1));
- return -ETIMEDOUT;
- }
+ if (time_after_eq(jiffies, timeout))
+ return -ETIMEDOUT;
- return 0;
+ msleep(50);
+ }
}
static int tenxpress_init(struct efx_nic *efx)
{
int phy_id = efx->mii.phy_id;
int reg;
- int rc;
if (efx->phy_type == PHY_TYPE_SFX7101) {
/* Enable 312.5 MHz clock */
@@ -285,10 +310,6 @@ static int tenxpress_init(struct efx_nic *efx)
false);
}
- rc = tenxpress_phy_check(efx);
- if (rc < 0)
- return rc;
-
/* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
if (efx->phy_type == PHY_TYPE_SFX7101) {
mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
@@ -299,7 +320,7 @@ static int tenxpress_init(struct efx_nic *efx)
PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT);
}
- return rc;
+ return 0;
}
static int tenxpress_phy_init(struct efx_nic *efx)
@@ -571,15 +592,14 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
static void tenxpress_phy_poll(struct efx_nic *efx)
{
struct tenxpress_phy_data *phy_data = efx->phy_data;
- bool change = false, link_ok;
- unsigned link_fc;
+ bool change = false;
if (efx->phy_type == PHY_TYPE_SFX7101) {
- link_ok = sfx7101_link_ok(efx);
+ bool link_ok = sfx7101_link_ok(efx);
if (link_ok != efx->link_up) {
change = true;
} else {
- link_fc = mdio_clause45_get_pause(efx);
+ unsigned int link_fc = mdio_clause45_get_pause(efx);
if (link_fc != efx->link_fc)
change = true;
}
@@ -679,12 +699,10 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
{
struct ethtool_cmd ecmd;
int phy_id = efx->mii.phy_id;
- int rc = 0, rc2, i, res_reg;
-
- if (!(flags & ETH_TEST_FL_OFFLINE))
- return 0;
+ int rc = 0, rc2, i, ctrl_reg, res_reg;
- efx->phy_op->get_settings(efx, &ecmd);
+ if (flags & ETH_TEST_FL_OFFLINE)
+ efx->phy_op->get_settings(efx, &ecmd);
/* Initialise cable diagnostic results to unknown failure */
for (i = 1; i < 9; ++i)
@@ -692,18 +710,22 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
/* Run cable diagnostics; wait up to 5 seconds for them to complete.
* A cable fault is not a self-test failure, but a timeout is. */
+ ctrl_reg = ((1 << CDIAG_CTRL_IMMED_LBN) |
+ (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN));
+ if (flags & ETH_TEST_FL_OFFLINE) {
+ /* Break the link in order to run full diagnostics. We
+ * must reset the PHY to resume normal service. */
+ ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN);
+ }
mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
- PMA_PMD_CDIAG_CTRL_REG,
- (1 << CDIAG_CTRL_IMMED_LBN) |
- (1 << CDIAG_CTRL_BRK_LINK_LBN) |
- (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN));
+ PMA_PMD_CDIAG_CTRL_REG, ctrl_reg);
i = 0;
while (mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
PMA_PMD_CDIAG_CTRL_REG) &
(1 << CDIAG_CTRL_IN_PROG_LBN)) {
if (++i == 50) {
rc = -ETIMEDOUT;
- goto reset;
+ goto out;
}
msleep(100);
}
@@ -728,17 +750,18 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
results[5 + i] = len_reg;
}
- /* We must reset to exit cable diagnostic mode. The BIST will
- * also run when we do this. */
-reset:
- rc2 = tenxpress_special_reset(efx);
- results[0] = rc2 ? -1 : 1;
- if (!rc)
- rc = rc2;
-
- rc2 = efx->phy_op->set_settings(efx, &ecmd);
- if (!rc)
- rc = rc2;
+out:
+ if (flags & ETH_TEST_FL_OFFLINE) {
+ /* Reset, running the BIST and then resuming normal service. */
+ rc2 = tenxpress_special_reset(efx);
+ results[0] = rc2 ? -1 : 1;
+ if (!rc)
+ rc = rc2;
+
+ rc2 = efx->phy_op->set_settings(efx, &ecmd);
+ if (!rc)
+ rc = rc2;
+ }
return rc;
}
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index da3e9ff339f5..d6681edb7014 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -162,6 +162,14 @@ static int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
/* Get size of the initial fragment */
len = skb_headlen(skb);
+ /* Pad if necessary */
+ if (EFX_WORKAROUND_15592(efx) && skb->len <= 32) {
+ EFX_BUG_ON_PARANOID(skb->data_len);
+ len = 32 + 1;
+ if (skb_pad(skb, len - skb->len))
+ return NETDEV_TX_OK;
+ }
+
fill_level = tx_queue->insert_count - tx_queue->old_read_count;
q_space = efx->type->txd_ring_mask - 1 - fill_level;
@@ -376,6 +384,9 @@ int efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
struct efx_nic *efx = netdev_priv(net_dev);
struct efx_tx_queue *tx_queue;
+ if (unlikely(efx->port_inhibited))
+ return NETDEV_TX_BUSY;
+
if (likely(skb->ip_summed == CHECKSUM_PARTIAL))
tx_queue = &efx->tx_queue[EFX_TX_QUEUE_OFFLOAD_CSUM];
else
@@ -397,7 +408,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
* separates the update of read_count from the test of
* stopped. */
smp_mb();
- if (unlikely(tx_queue->stopped)) {
+ if (unlikely(tx_queue->stopped) && likely(efx->port_enabled)) {
fill_level = tx_queue->insert_count - tx_queue->read_count;
if (fill_level < EFX_NETDEV_TX_THRESHOLD(tx_queue)) {
EFX_BUG_ON_PARANOID(!efx_dev_registered(efx));
diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h
index 78de68f4a95b..c821c15445a0 100644
--- a/drivers/net/sfc/workarounds.h
+++ b/drivers/net/sfc/workarounds.h
@@ -36,6 +36,8 @@
#define EFX_WORKAROUND_11482 EFX_WORKAROUND_ALWAYS
/* Flush events can take a very long time to appear */
#define EFX_WORKAROUND_11557 EFX_WORKAROUND_ALWAYS
+/* Truncated IPv4 packets can confuse the TX packet parser */
+#define EFX_WORKAROUND_15592 EFX_WORKAROUND_ALWAYS
/* Spurious parity errors in TSORT buffers */
#define EFX_WORKAROUND_5129 EFX_WORKAROUND_FALCON_A
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index 2d50b6ecf5f9..bb1ef77d5f56 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -7,8 +7,8 @@
* by the Free Software Foundation, incorporated herein by reference.
*/
/*
- * Driver for XFP optical PHYs (plus some support specific to the Quake 2022/32)
- * See www.amcc.com for details (search for qt2032)
+ * Driver for SFP+ and XFP optical PHYs plus some support specific to the
+ * AMCC QT20xx adapters; see www.amcc.com for details
*/
#include <linux/timer.h>
@@ -31,6 +31,21 @@
/* Quake-specific MDIO registers */
#define MDIO_QUAKE_LED0_REG (0xD006)
+/* QT2025C only */
+#define PCS_FW_HEARTBEAT_REG 0xd7ee
+#define PCS_FW_HEARTB_LBN 0
+#define PCS_FW_HEARTB_WIDTH 8
+#define PCS_UC8051_STATUS_REG 0xd7fd
+#define PCS_UC_STATUS_LBN 0
+#define PCS_UC_STATUS_WIDTH 8
+#define PCS_UC_STATUS_FW_SAVE 0x20
+#define PMA_PMD_FTX_CTRL2_REG 0xc309
+#define PMA_PMD_FTX_STATIC_LBN 13
+#define PMA_PMD_VEND1_REG 0xc001
+#define PMA_PMD_VEND1_LBTXD_LBN 15
+#define PCS_VEND1_REG 0xc000
+#define PCS_VEND1_LBTXD_LBN 5
+
void xfp_set_led(struct efx_nic *p, int led, int mode)
{
int addr = MDIO_QUAKE_LED0_REG + led;
@@ -45,7 +60,49 @@ struct xfp_phy_data {
#define XFP_MAX_RESET_TIME 500
#define XFP_RESET_WAIT 10
-/* Reset the PHYXS MMD. This is documented (for the Quake PHY) as doing
+static int qt2025c_wait_reset(struct efx_nic *efx)
+{
+ unsigned long timeout = jiffies + 10 * HZ;
+ int phy_id = efx->mii.phy_id;
+ int reg, old_counter = 0;
+
+ /* Wait for firmware heartbeat to start */
+ for (;;) {
+ int counter;
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
+ PCS_FW_HEARTBEAT_REG);
+ if (reg < 0)
+ return reg;
+ counter = ((reg >> PCS_FW_HEARTB_LBN) &
+ ((1 << PCS_FW_HEARTB_WIDTH) - 1));
+ if (old_counter == 0)
+ old_counter = counter;
+ else if (counter != old_counter)
+ break;
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+ msleep(10);
+ }
+
+ /* Wait for firmware status to look good */
+ for (;;) {
+ reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
+ PCS_UC8051_STATUS_REG);
+ if (reg < 0)
+ return reg;
+ if ((reg &
+ ((1 << PCS_UC_STATUS_WIDTH) - 1) << PCS_UC_STATUS_LBN) >=
+ PCS_UC_STATUS_FW_SAVE)
+ break;
+ if (time_after(jiffies, timeout))
+ return -ETIMEDOUT;
+ msleep(100);
+ }
+
+ return 0;
+}
+
+/* Reset the PHYXS MMD. This is documented (for the Quake PHYs) as doing
* a complete soft reset.
*/
static int xfp_reset_phy(struct efx_nic *efx)
@@ -58,6 +115,12 @@ static int xfp_reset_phy(struct efx_nic *efx)
if (rc < 0)
goto fail;
+ if (efx->phy_type == PHY_TYPE_QT2025C) {
+ rc = qt2025c_wait_reset(efx);
+ if (rc < 0)
+ goto fail;
+ }
+
/* Wait 250ms for the PHY to complete bootup */
msleep(250);
@@ -73,7 +136,7 @@ static int xfp_reset_phy(struct efx_nic *efx)
return rc;
fail:
- EFX_ERR(efx, "XFP: reset timed out!\n");
+ EFX_ERR(efx, "PHY reset timed out\n");
return rc;
}
@@ -88,15 +151,15 @@ static int xfp_phy_init(struct efx_nic *efx)
return -ENOMEM;
efx->phy_data = phy_data;
- EFX_INFO(efx, "XFP: PHY ID reg %x (OUI %x model %x revision"
- " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid),
- MDIO_ID_REV(devid));
+ EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n",
+ devid, mdio_id_oui(devid), mdio_id_model(devid),
+ mdio_id_rev(devid));
phy_data->phy_mode = efx->phy_mode;
rc = xfp_reset_phy(efx);
- EFX_INFO(efx, "XFP: PHY init %s.\n",
+ EFX_INFO(efx, "PHY init %s.\n",
rc ? "failed" : "successful");
if (rc < 0)
goto fail;
@@ -131,12 +194,28 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
{
struct xfp_phy_data *phy_data = efx->phy_data;
- /* Reset the PHY when moving from tx off to tx on */
- if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) &&
- (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
- xfp_reset_phy(efx);
+ if (efx->phy_type == PHY_TYPE_QT2025C) {
+ /* There are several different register bits which can
+ * disable TX (and save power) on direct-attach cables
+ * or optical transceivers, varying somewhat between
+ * firmware versions. Only 'static mode' appears to
+ * cover everything. */
+ mdio_clause45_set_flag(
+ efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
+ PMA_PMD_FTX_CTRL2_REG, PMA_PMD_FTX_STATIC_LBN,
+ efx->phy_mode & PHY_MODE_TX_DISABLED ||
+ efx->phy_mode & PHY_MODE_LOW_POWER ||
+ efx->loopback_mode == LOOPBACK_PCS ||
+ efx->loopback_mode == LOOPBACK_PMAPMD);
+ } else {
+ /* Reset the PHY when moving from tx off to tx on */
+ if (!(efx->phy_mode & PHY_MODE_TX_DISABLED) &&
+ (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
+ xfp_reset_phy(efx);
+
+ mdio_clause45_transmit_disable(efx);
+ }
- mdio_clause45_transmit_disable(efx);
mdio_clause45_phy_reconfigure(efx);
phy_data->phy_mode = efx->phy_mode;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 7f8e514eb5e9..7b1882765a0c 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -687,6 +687,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
{
struct net_device *ndev = netdev;
struct sh_eth_private *mdp = netdev_priv(ndev);
+ irqreturn_t ret = IRQ_NONE;
u32 ioaddr, boguscnt = RX_RING_SIZE;
u32 intr_status = 0;
@@ -696,7 +697,13 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
/* Get interrpt stat */
intr_status = ctrl_inl(ioaddr + EESR);
/* Clear interrupt */
- ctrl_outl(intr_status, ioaddr + EESR);
+ if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
+ EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
+ TX_CHECK | EESR_ERR_CHECK)) {
+ ctrl_outl(intr_status, ioaddr + EESR);
+ ret = IRQ_HANDLED;
+ } else
+ goto other_irq;
if (intr_status & (EESR_FRC | /* Frame recv*/
EESR_RMAF | /* Multi cast address recv*/
@@ -723,9 +730,10 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
ndev->name, intr_status);
}
+other_irq:
spin_unlock(&mdp->lock);
- return IRQ_HANDLED;
+ return ret;
}
static void sh_eth_timer(unsigned long data)
@@ -844,7 +852,13 @@ static int sh_eth_open(struct net_device *ndev)
int ret = 0;
struct sh_eth_private *mdp = netdev_priv(ndev);
- ret = request_irq(ndev->irq, &sh_eth_interrupt, 0, ndev->name, ndev);
+ ret = request_irq(ndev->irq, &sh_eth_interrupt,
+#if defined(CONFIG_CPU_SUBTYPE_SH7763) || defined(CONFIG_CPU_SUBTYPE_SH7764)
+ IRQF_SHARED,
+#else
+ 0,
+#endif
+ ndev->name, ndev);
if (ret) {
printk(KERN_ERR "Can not assign IRQ number to %s\n", CARDNAME);
return ret;
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 73bc7181cc18..1537e13e623d 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -43,8 +43,8 @@
#define SH7763_SKB_ALIGN 32
/* Chip Base Address */
-# define SH_TSU_ADDR 0xFFE01800
-# define ARSTR 0xFFE01800
+# define SH_TSU_ADDR 0xFEE01800
+# define ARSTR SH_TSU_ADDR
/* Chip Registers */
/* E-DMAC */
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index be4465bc0a69..8a70de72ea2c 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -80,8 +80,8 @@
#define SIS900_MODULE_NAME "sis900"
#define SIS900_DRV_VERSION "v1.08.10 Apr. 2 2006"
-static char version[] __devinitdata =
-KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
+static const char version[] __devinitconst =
+ KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
static int max_interrupt_work = 40;
static int multicast_filter_limit = 128;
diff --git a/drivers/net/skfp/h/hwmtm.h b/drivers/net/skfp/h/hwmtm.h
index 1a606d4bfe5e..e1a7e5f683dc 100644
--- a/drivers/net/skfp/h/hwmtm.h
+++ b/drivers/net/skfp/h/hwmtm.h
@@ -145,7 +145,7 @@ struct hw_modul {
int leave_isr ; /* leave fddi_isr immedeately if set */
int isr_flag ; /* set, when HWM is entered from isr */
/*
- * varaibles for the current transmit frame
+ * variables for the current transmit frame
*/
struct s_smt_tx_queue *tx_p ; /* pointer to the transmit queue */
u_long tx_descr ; /* tx descriptor for FORMAC+ */
diff --git a/drivers/net/skfp/h/smc.h b/drivers/net/skfp/h/smc.h
index 94325915e0d5..1758d9548361 100644
--- a/drivers/net/skfp/h/smc.h
+++ b/drivers/net/skfp/h/smc.h
@@ -467,5 +467,22 @@ struct s_smc {
#endif /* DEBUG_BRD && DEBUG */
} ;
+extern const struct fddi_addr fddi_broadcast;
+
+extern void all_selection_criteria(struct s_smc *smc);
+extern void card_stop(struct s_smc *smc);
+extern void init_board(struct s_smc *smc, u_char *mac_addr);
+extern int init_fplus(struct s_smc *smc);
+extern void init_plc(struct s_smc *smc);
+extern int init_smt(struct s_smc *smc, u_char * mac_addr);
+extern void mac1_irq(struct s_smc *smc, u_short stu, u_short stl);
+extern void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l);
+extern void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l);
+extern int pcm_status_twisted(struct s_smc *smc);
+extern void plc1_irq(struct s_smc *smc);
+extern void plc2_irq(struct s_smc *smc);
+extern void read_address(struct s_smc *smc, u_char * mac_addr);
+extern void timer_irq(struct s_smc *smc);
+
#endif /* _SCMECM_ */
diff --git a/drivers/net/skfp/hwmtm.c b/drivers/net/skfp/hwmtm.c
index 4218e97033c9..d322f1b702ac 100644
--- a/drivers/net/skfp/hwmtm.c
+++ b/drivers/net/skfp/hwmtm.c
@@ -97,23 +97,15 @@ static void mac_drv_clear_txd(struct s_smc *smc);
extern void* mac_drv_get_space(struct s_smc *smc, unsigned int size);
extern void* mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size);
-extern void init_board(struct s_smc *smc, u_char *mac_addr);
extern void mac_drv_fill_rxd(struct s_smc *smc);
-extern void plc1_irq(struct s_smc *smc);
extern void mac_drv_tx_complete(struct s_smc *smc,
volatile struct s_smt_fp_txd *txd);
-extern void plc2_irq(struct s_smc *smc);
-extern void mac1_irq(struct s_smc *smc, u_short stu, u_short stl);
-extern void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l);
-extern void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l);
-extern void timer_irq(struct s_smc *smc);
extern void mac_drv_rx_complete(struct s_smc *smc,
volatile struct s_smt_fp_rxd *rxd,
int frag_count, int len);
extern void mac_drv_requeue_rxd(struct s_smc *smc,
volatile struct s_smt_fp_rxd *rxd,
int frag_count);
-extern void init_plc(struct s_smc *smc);
extern void mac_drv_clear_rxd(struct s_smc *smc,
volatile struct s_smt_fp_rxd *rxd, int frag_count);
@@ -136,7 +128,6 @@ extern void dma_complete(struct s_smc *smc, volatile union s_fp_descr *descr,
int flag);
#endif
-extern int init_fplus(struct s_smc *smc);
extern int mac_drv_rx_init(struct s_smc *smc, int len, int fc, char *look_ahead,
int la_len);
diff --git a/drivers/net/skfp/pcmplc.c b/drivers/net/skfp/pcmplc.c
index 74e129f3ce92..f1df2ec8ad41 100644
--- a/drivers/net/skfp/pcmplc.c
+++ b/drivers/net/skfp/pcmplc.c
@@ -198,9 +198,6 @@ static int plc_imsk_na = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK |
static const int plc_imsk_act = PL_PCM_CODE | PL_TRACE_PROP | PL_PCM_BREAK |
PL_PCM_ENABLED | PL_SELF_TEST | PL_EBUF_ERR;
-/* external functions */
-void all_selection_criteria(struct s_smc *smc);
-
/* internal functions */
static void pcm_fsm(struct s_smc *smc, struct s_phy *phy, int cmd);
static void pc_rcode_actions(struct s_smc *smc, int bit, struct s_phy *phy);
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index 9a00e5566af7..e14aec0a7333 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -135,14 +135,11 @@ void dump_data(unsigned char *Data, int length);
// External functions from the hardware module
extern u_int mac_drv_check_space(void);
-extern void read_address(struct s_smc *smc, u_char * mac_addr);
-extern void card_stop(struct s_smc *smc);
extern int mac_drv_init(struct s_smc *smc);
extern void hwm_tx_frag(struct s_smc *smc, char far * virt, u_long phys,
int len, int frame_status);
extern int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count,
int frame_len, int frame_status);
-extern int init_smt(struct s_smc *smc, u_char * mac_addr);
extern void fddi_isr(struct s_smc *smc);
extern void hwm_rx_frag(struct s_smc *smc, char far * virt, u_long phys,
int len, int frame_status);
diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
index 805383b33d3c..83d16fecfac4 100644
--- a/drivers/net/skfp/smt.c
+++ b/drivers/net/skfp/smt.c
@@ -55,16 +55,6 @@ static const struct fddi_addr SMT_Unknown = {
} ;
/*
- * external variables
- */
-extern const struct fddi_addr fddi_broadcast ;
-
-/*
- * external functions
- */
-int pcm_status_twisted(struct s_smc *smc);
-
-/*
* function prototypes
*/
#ifdef LITTLE_ENDIAN
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index c9dbb06f8c94..952d37ffee51 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3214,7 +3214,7 @@ static int skge_poll(struct napi_struct *napi, int to_do)
unsigned long flags;
spin_lock_irqsave(&hw->hw_lock, flags);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
hw->intr_mask |= napimask[skge->port];
skge_write32(hw, B0_IMSK, hw->intr_mask);
skge_read32(hw, B0_IMSK);
@@ -3377,7 +3377,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id)
if (status & (IS_XA1_F|IS_R1_F)) {
struct skge_port *skge = netdev_priv(hw->dev[0]);
hw->intr_mask &= ~(IS_XA1_F|IS_R1_F);
- netif_rx_schedule(&skge->napi);
+ napi_schedule(&skge->napi);
}
if (status & IS_PA_TO_TX1)
@@ -3397,7 +3397,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id)
if (status & (IS_XA2_F|IS_R2_F)) {
hw->intr_mask &= ~(IS_XA2_F|IS_R2_F);
- netif_rx_schedule(&skge->napi);
+ napi_schedule(&skge->napi);
}
if (status & IS_PA_TO_RX2) {
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 994703cc0db3..d01c56eb9627 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1068,13 +1068,16 @@ static void sky2_rx_submit(struct sky2_port *sky2,
}
-static void sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
+static int sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
unsigned size)
{
struct sk_buff *skb = re->skb;
int i;
re->data_addr = pci_map_single(pdev, skb->data, size, PCI_DMA_FROMDEVICE);
+ if (unlikely(pci_dma_mapping_error(pdev, re->data_addr)))
+ return -EIO;
+
pci_unmap_len_set(re, data_size, size);
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
@@ -1083,6 +1086,7 @@ static void sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
skb_shinfo(skb)->frags[i].page_offset,
skb_shinfo(skb)->frags[i].size,
PCI_DMA_FROMDEVICE);
+ return 0;
}
static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re)
@@ -1354,7 +1358,12 @@ static int sky2_rx_start(struct sky2_port *sky2)
if (!re->skb)
goto nomem;
- sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size);
+ if (sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size)) {
+ dev_kfree_skb(re->skb);
+ re->skb = NULL;
+ goto nomem;
+ }
+
sky2_rx_submit(sky2, re);
}
@@ -1547,7 +1556,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
struct sky2_hw *hw = sky2->hw;
struct sky2_tx_le *le = NULL;
struct tx_ring_info *re;
- unsigned i, len;
+ unsigned i, len, first_slot;
dma_addr_t mapping;
u16 mss;
u8 ctrl;
@@ -1555,13 +1564,17 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
if (unlikely(tx_avail(sky2) < tx_le_req(skb)))
return NETDEV_TX_BUSY;
- if (unlikely(netif_msg_tx_queued(sky2)))
- printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
- dev->name, sky2->tx_prod, skb->len);
-
len = skb_headlen(skb);
mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
+ if (pci_dma_mapping_error(hw->pdev, mapping))
+ goto mapping_error;
+
+ first_slot = sky2->tx_prod;
+ if (unlikely(netif_msg_tx_queued(sky2)))
+ printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
+ dev->name, first_slot, skb->len);
+
/* Send high bits if needed */
if (sizeof(dma_addr_t) > sizeof(u32)) {
le = get_tx_le(sky2);
@@ -1648,6 +1661,9 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
frag->size, PCI_DMA_TODEVICE);
+ if (pci_dma_mapping_error(hw->pdev, mapping))
+ goto mapping_unwind;
+
if (sizeof(dma_addr_t) > sizeof(u32)) {
le = get_tx_le(sky2);
le->addr = cpu_to_le32(upper_32_bits(mapping));
@@ -1676,6 +1692,34 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
return NETDEV_TX_OK;
+
+mapping_unwind:
+ for (i = first_slot; i != sky2->tx_prod; i = RING_NEXT(i, TX_RING_SIZE)) {
+ le = sky2->tx_le + i;
+ re = sky2->tx_ring + i;
+
+ switch(le->opcode & ~HW_OWNER) {
+ case OP_LARGESEND:
+ case OP_PACKET:
+ pci_unmap_single(hw->pdev,
+ pci_unmap_addr(re, mapaddr),
+ pci_unmap_len(re, maplen),
+ PCI_DMA_TODEVICE);
+ break;
+ case OP_BUFFER:
+ pci_unmap_page(hw->pdev, pci_unmap_addr(re, mapaddr),
+ pci_unmap_len(re, maplen),
+ PCI_DMA_TODEVICE);
+ break;
+ }
+ }
+
+ sky2->tx_prod = first_slot;
+mapping_error:
+ if (net_ratelimit())
+ dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
}
/*
@@ -2191,7 +2235,11 @@ static struct sk_buff *receive_new(struct sky2_port *sky2,
prefetch(skb->data);
re->skb = nskb;
- sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space);
+ if (sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space)) {
+ dev_kfree_skb(nskb);
+ re->skb = skb;
+ return NULL;
+ }
if (skb_shinfo(skb)->nr_frags)
skb_put_frags(skb, hdr_space, length);
@@ -2687,13 +2735,6 @@ static int sky2_poll(struct napi_struct *napi, int work_limit)
goto done;
}
- /* Bug/Errata workaround?
- * Need to kick the TX irq moderation timer.
- */
- if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
- sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
- sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
- }
napi_complete(napi);
sky2_read32(hw, B0_Y2_SP_LISR);
done:
@@ -3864,6 +3905,86 @@ static const struct ethtool_ops sky2_ethtool_ops = {
static struct dentry *sky2_debug;
+
+/*
+ * Read and parse the first part of Vital Product Data
+ */
+#define VPD_SIZE 128
+#define VPD_MAGIC 0x82
+
+static const struct vpd_tag {
+ char tag[2];
+ char *label;
+} vpd_tags[] = {
+ { "PN", "Part Number" },
+ { "EC", "Engineering Level" },
+ { "MN", "Manufacturer" },
+ { "SN", "Serial Number" },
+ { "YA", "Asset Tag" },
+ { "VL", "First Error Log Message" },
+ { "VF", "Second Error Log Message" },
+ { "VB", "Boot Agent ROM Configuration" },
+ { "VE", "EFI UNDI Configuration" },
+};
+
+static void sky2_show_vpd(struct seq_file *seq, struct sky2_hw *hw)
+{
+ size_t vpd_size;
+ loff_t offs;
+ u8 len;
+ unsigned char *buf;
+ u16 reg2;
+
+ reg2 = sky2_pci_read16(hw, PCI_DEV_REG2);
+ vpd_size = 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
+
+ seq_printf(seq, "%s Product Data\n", pci_name(hw->pdev));
+ buf = kmalloc(vpd_size, GFP_KERNEL);
+ if (!buf) {
+ seq_puts(seq, "no memory!\n");
+ return;
+ }
+
+ if (pci_read_vpd(hw->pdev, 0, vpd_size, buf) < 0) {
+ seq_puts(seq, "VPD read failed\n");
+ goto out;
+ }
+
+ if (buf[0] != VPD_MAGIC) {
+ seq_printf(seq, "VPD tag mismatch: %#x\n", buf[0]);
+ goto out;
+ }
+ len = buf[1];
+ if (len == 0 || len > vpd_size - 4) {
+ seq_printf(seq, "Invalid id length: %d\n", len);
+ goto out;
+ }
+
+ seq_printf(seq, "%.*s\n", len, buf + 3);
+ offs = len + 3;
+
+ while (offs < vpd_size - 4) {
+ int i;
+
+ if (!memcmp("RW", buf + offs, 2)) /* end marker */
+ break;
+ len = buf[offs + 2];
+ if (offs + len + 3 >= vpd_size)
+ break;
+
+ for (i = 0; i < ARRAY_SIZE(vpd_tags); i++) {
+ if (!memcmp(vpd_tags[i].tag, buf + offs, 2)) {
+ seq_printf(seq, " %s: %.*s\n",
+ vpd_tags[i].label, len, buf + offs + 3);
+ break;
+ }
+ }
+ offs += len + 3;
+ }
+out:
+ kfree(buf);
+}
+
static int sky2_debug_show(struct seq_file *seq, void *v)
{
struct net_device *dev = seq->private;
@@ -3873,14 +3994,18 @@ static int sky2_debug_show(struct seq_file *seq, void *v)
unsigned idx, last;
int sop;
- if (!netif_running(dev))
- return -ENETDOWN;
+ sky2_show_vpd(seq, hw);
- seq_printf(seq, "IRQ src=%x mask=%x control=%x\n",
+ seq_printf(seq, "\nIRQ src=%x mask=%x control=%x\n",
sky2_read32(hw, B0_ISRC),
sky2_read32(hw, B0_IMSK),
sky2_read32(hw, B0_Y2_SP_ICR));
+ if (!netif_running(dev)) {
+ seq_printf(seq, "network not running\n");
+ return 0;
+ }
+
napi_disable(&hw->napi);
last = sky2_read16(hw, STAT_PUT_IDX);
@@ -4204,69 +4329,6 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw)
return err;
}
-/*
- * Read and parse the first part of Vital Product Data
- */
-#define VPD_SIZE 128
-#define VPD_MAGIC 0x82
-
-static void __devinit sky2_vpd_info(struct sky2_hw *hw)
-{
- int cap = pci_find_capability(hw->pdev, PCI_CAP_ID_VPD);
- const u8 *p;
- u8 *vpd_buf = NULL;
- u16 len;
- static struct vpd_tag {
- char tag[2];
- char *label;
- } vpd_tags[] = {
- { "PN", "Part Number" },
- { "EC", "Engineering Level" },
- { "MN", "Manufacturer" },
- };
-
- if (!cap)
- goto out;
-
- vpd_buf = kmalloc(VPD_SIZE, GFP_KERNEL);
- if (!vpd_buf)
- goto out;
-
- if (sky2_vpd_read(hw, cap, vpd_buf, 0, VPD_SIZE))
- goto out;
-
- if (vpd_buf[0] != VPD_MAGIC)
- goto out;
- len = vpd_buf[1];
- if (len == 0 || len > VPD_SIZE - 4)
- goto out;
- p = vpd_buf + 3;
- dev_info(&hw->pdev->dev, "%.*s\n", len, p);
- p += len;
-
- while (p < vpd_buf + VPD_SIZE - 4) {
- int i;
-
- if (!memcmp("RW", p, 2)) /* end marker */
- break;
-
- len = p[2];
- if (len > (p - vpd_buf) - 4)
- break;
-
- for (i = 0; i < ARRAY_SIZE(vpd_tags); i++) {
- if (!memcmp(vpd_tags[i].tag, p, 2)) {
- printk(KERN_DEBUG " %s: %.*s\n",
- vpd_tags[i].label, len, p + 3);
- break;
- }
- }
- p += len + 3;
- }
-out:
- kfree(vpd_buf);
-}
-
/* This driver supports yukon2 chipset only */
static const char *sky2_name(u8 chipid, char *buf, int sz)
{
@@ -4294,6 +4356,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
struct net_device *dev;
struct sky2_hw *hw;
int err, using_dac = 0, wol_default;
+ u32 reg;
char buf1[16];
err = pci_enable_device(pdev);
@@ -4327,6 +4390,34 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
}
}
+ /* Get configuration information
+ * Note: only regular PCI config access once to test for HW issues
+ * other PCI access through shared memory for speed and to
+ * avoid MMCONFIG problems.
+ */
+ err = pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
+ if (err) {
+ dev_err(&pdev->dev, "PCI read config failed\n");
+ goto err_out_free_regions;
+ }
+
+ /* size of available VPD, only impact sysfs */
+ err = pci_vpd_truncate(pdev, 1ul << (((reg & PCI_VPD_ROM_SZ) >> 14) + 8));
+ if (err)
+ dev_warn(&pdev->dev, "Can't set VPD size\n");
+
+#ifdef __BIG_ENDIAN
+ /* The sk98lin vendor driver uses hardware byte swapping but
+ * this driver uses software swapping.
+ */
+ reg &= ~PCI_REV_DESC;
+ err = pci_write_config_dword(pdev,PCI_DEV_REG2, reg);
+ if (err) {
+ dev_err(&pdev->dev, "PCI write config failed\n");
+ goto err_out_free_regions;
+ }
+#endif
+
wol_default = device_may_wakeup(&pdev->dev) ? WAKE_MAGIC : 0;
err = -ENOMEM;
@@ -4344,18 +4435,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
goto err_out_free_hw;
}
-#ifdef __BIG_ENDIAN
- /* The sk98lin vendor driver uses hardware byte swapping but
- * this driver uses software swapping.
- */
- {
- u32 reg;
- reg = sky2_pci_read32(hw, PCI_DEV_REG2);
- reg &= ~PCI_REV_DESC;
- sky2_pci_write32(hw, PCI_DEV_REG2, reg);
- }
-#endif
-
/* ring for status responses */
hw->st_le = pci_alloc_consistent(pdev, STATUS_LE_BYTES, &hw->st_dma);
if (!hw->st_le)
@@ -4370,8 +4449,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
sky2_reset(hw);
- sky2_vpd_info(hw);
-
dev = sky2_init_netdev(hw, 0, using_dac, wol_default);
if (!dev) {
err = -ENOMEM;
diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
index 2033fee3143a..0291ea098a06 100644
--- a/drivers/net/smc-ultra.c
+++ b/drivers/net/smc-ultra.c
@@ -142,9 +142,6 @@ static int __init do_ultra_probe(struct net_device *dev)
int base_addr = dev->base_addr;
int irq = dev->irq;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = &ultra_poll;
-#endif
if (base_addr > 0x1ff) /* Check a single specified location. */
return ultra_probe1(dev, base_addr);
else if (base_addr != 0) /* Don't probe at all. */
@@ -199,7 +196,7 @@ static const struct net_device_ops ultra_netdev_ops = {
.ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = ei_poll,
+ .ndo_poll_controller = ultra_poll,
#endif
};
diff --git a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c
index cb6c097a2e0a..7a554adc70fb 100644
--- a/drivers/net/smc-ultra32.c
+++ b/drivers/net/smc-ultra32.c
@@ -153,6 +153,22 @@ out:
return ERR_PTR(err);
}
+
+static const struct net_device_ops ultra32_netdev_ops = {
+ .ndo_open = ultra32_open,
+ .ndo_stop = ultra32_close,
+ .ndo_start_xmit = ei_start_xmit,
+ .ndo_tx_timeout = ei_tx_timeout,
+ .ndo_get_stats = ei_get_stats,
+ .ndo_set_multicast_list = ei_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ei_poll,
+#endif
+};
+
static int __init ultra32_probe1(struct net_device *dev, int ioaddr)
{
int i, edge, media, retval;
@@ -273,11 +289,8 @@ static int __init ultra32_probe1(struct net_device *dev, int ioaddr)
ei_status.block_output = &ultra32_block_output;
ei_status.get_8390_hdr = &ultra32_get_8390_hdr;
ei_status.reset_8390 = &ultra32_reset_8390;
- dev->open = &ultra32_open;
- dev->stop = &ultra32_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ei_poll;
-#endif
+
+ dev->netdev_ops = &ultra32_netdev_ops;
NS8390_init(dev, 0);
return 0;
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 223cde0d43be..293610334a77 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -1545,7 +1545,7 @@ smc911x_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
strncpy(info->driver, CARDNAME, sizeof(info->driver));
strncpy(info->version, version, sizeof(info->version));
- strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
+ strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
}
static int smc911x_ethtool_nwayreset(struct net_device *dev)
diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h
index a45952e72018..8140f7cb4d85 100644
--- a/drivers/net/smc911x.h
+++ b/drivers/net/smc911x.h
@@ -236,8 +236,7 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
* Use a DMA for RX and TX packets.
*/
#include <linux/dma-mapping.h>
-#include <asm/dma.h>
-#include <mach/pxa-regs.h>
+#include <mach/dma.h>
static dma_addr_t rx_dmabuf, tx_dmabuf;
static int rx_dmalen, tx_dmalen;
diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c
index 18d653bbd4e0..9a7973a54116 100644
--- a/drivers/net/smc9194.c
+++ b/drivers/net/smc9194.c
@@ -831,6 +831,17 @@ static int __init smc_findirq(int ioaddr)
#endif
}
+static const struct net_device_ops smc_netdev_ops = {
+ .ndo_open = smc_open,
+ .ndo_stop = smc_close,
+ .ndo_start_xmit = smc_wait_to_send_packet,
+ .ndo_tx_timeout = smc_timeout,
+ .ndo_set_multicast_list = smc_set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*----------------------------------------------------------------------
. Function: smc_probe( int ioaddr )
.
@@ -1044,12 +1055,8 @@ static int __init smc_probe(struct net_device *dev, int ioaddr)
goto err_out;
}
- dev->open = smc_open;
- dev->stop = smc_close;
- dev->hard_start_xmit = smc_wait_to_send_packet;
- dev->tx_timeout = smc_timeout;
+ dev->netdev_ops = &smc_netdev_ops;
dev->watchdog_timeo = HZ/20;
- dev->set_multicast_list = smc_set_multicast_list;
return 0;
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index b215a8d85e62..fdcbaf8dfa73 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1614,7 +1614,7 @@ smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
strncpy(info->driver, CARDNAME, sizeof(info->driver));
strncpy(info->version, version, sizeof(info->version));
- strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
+ strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
}
static int smc_ethtool_nwayreset(struct net_device *dev)
@@ -1643,6 +1643,117 @@ static void smc_ethtool_setmsglevel(struct net_device *dev, u32 level)
lp->msg_enable = level;
}
+static int smc_write_eeprom_word(struct net_device *dev, u16 addr, u16 word)
+{
+ u16 ctl;
+ struct smc_local *lp = netdev_priv(dev);
+ void __iomem *ioaddr = lp->base;
+
+ spin_lock_irq(&lp->lock);
+ /* load word into GP register */
+ SMC_SELECT_BANK(lp, 1);
+ SMC_SET_GP(lp, word);
+ /* set the address to put the data in EEPROM */
+ SMC_SELECT_BANK(lp, 2);
+ SMC_SET_PTR(lp, addr);
+ /* tell it to write */
+ SMC_SELECT_BANK(lp, 1);
+ ctl = SMC_GET_CTL(lp);
+ SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_STORE));
+ /* wait for it to finish */
+ do {
+ udelay(1);
+ } while (SMC_GET_CTL(lp) & CTL_STORE);
+ /* clean up */
+ SMC_SET_CTL(lp, ctl);
+ SMC_SELECT_BANK(lp, 2);
+ spin_unlock_irq(&lp->lock);
+ return 0;
+}
+
+static int smc_read_eeprom_word(struct net_device *dev, u16 addr, u16 *word)
+{
+ u16 ctl;
+ struct smc_local *lp = netdev_priv(dev);
+ void __iomem *ioaddr = lp->base;
+
+ spin_lock_irq(&lp->lock);
+ /* set the EEPROM address to get the data from */
+ SMC_SELECT_BANK(lp, 2);
+ SMC_SET_PTR(lp, addr | PTR_READ);
+ /* tell it to load */
+ SMC_SELECT_BANK(lp, 1);
+ SMC_SET_GP(lp, 0xffff); /* init to known */
+ ctl = SMC_GET_CTL(lp);
+ SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_RELOAD));
+ /* wait for it to finish */
+ do {
+ udelay(1);
+ } while (SMC_GET_CTL(lp) & CTL_RELOAD);
+ /* read word from GP register */
+ *word = SMC_GET_GP(lp);
+ /* clean up */
+ SMC_SET_CTL(lp, ctl);
+ SMC_SELECT_BANK(lp, 2);
+ spin_unlock_irq(&lp->lock);
+ return 0;
+}
+
+static int smc_ethtool_geteeprom_len(struct net_device *dev)
+{
+ return 0x23 * 2;
+}
+
+static int smc_ethtool_geteeprom(struct net_device *dev,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ int i;
+ int imax;
+
+ DBG(1, "Reading %d bytes at %d(0x%x)\n",
+ eeprom->len, eeprom->offset, eeprom->offset);
+ imax = smc_ethtool_geteeprom_len(dev);
+ for (i = 0; i < eeprom->len; i += 2) {
+ int ret;
+ u16 wbuf;
+ int offset = i + eeprom->offset;
+ if (offset > imax)
+ break;
+ ret = smc_read_eeprom_word(dev, offset >> 1, &wbuf);
+ if (ret != 0)
+ return ret;
+ DBG(2, "Read 0x%x from 0x%x\n", wbuf, offset >> 1);
+ data[i] = (wbuf >> 8) & 0xff;
+ data[i+1] = wbuf & 0xff;
+ }
+ return 0;
+}
+
+static int smc_ethtool_seteeprom(struct net_device *dev,
+ struct ethtool_eeprom *eeprom, u8 *data)
+{
+ int i;
+ int imax;
+
+ DBG(1, "Writing %d bytes to %d(0x%x)\n",
+ eeprom->len, eeprom->offset, eeprom->offset);
+ imax = smc_ethtool_geteeprom_len(dev);
+ for (i = 0; i < eeprom->len; i += 2) {
+ int ret;
+ u16 wbuf;
+ int offset = i + eeprom->offset;
+ if (offset > imax)
+ break;
+ wbuf = (data[i] << 8) | data[i + 1];
+ DBG(2, "Writing 0x%x to 0x%x\n", wbuf, offset >> 1);
+ ret = smc_write_eeprom_word(dev, offset >> 1, wbuf);
+ if (ret != 0)
+ return ret;
+ }
+ return 0;
+}
+
+
static const struct ethtool_ops smc_ethtool_ops = {
.get_settings = smc_ethtool_getsettings,
.set_settings = smc_ethtool_setsettings,
@@ -1652,8 +1763,22 @@ static const struct ethtool_ops smc_ethtool_ops = {
.set_msglevel = smc_ethtool_setmsglevel,
.nway_reset = smc_ethtool_nwayreset,
.get_link = ethtool_op_get_link,
-// .get_eeprom = smc_ethtool_geteeprom,
-// .set_eeprom = smc_ethtool_seteeprom,
+ .get_eeprom_len = smc_ethtool_geteeprom_len,
+ .get_eeprom = smc_ethtool_geteeprom,
+ .set_eeprom = smc_ethtool_seteeprom,
+};
+
+static const struct net_device_ops smc_netdev_ops = {
+ .ndo_open = smc_open,
+ .ndo_stop = smc_close,
+ .ndo_start_xmit = smc_hard_start_xmit,
+ .ndo_tx_timeout = smc_timeout,
+ .ndo_set_multicast_list = smc_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = smc_poll_controller,
+#endif
};
/*
@@ -1865,16 +1990,9 @@ static int __devinit smc_probe(struct net_device *dev, void __iomem *ioaddr,
/* Fill in the fields of the device structure with ethernet values. */
ether_setup(dev);
- dev->open = smc_open;
- dev->stop = smc_close;
- dev->hard_start_xmit = smc_hard_start_xmit;
- dev->tx_timeout = smc_timeout;
dev->watchdog_timeo = msecs_to_jiffies(watchdog);
- dev->set_multicast_list = smc_set_multicast_list;
+ dev->netdev_ops = &smc_netdev_ops;
dev->ethtool_ops = &smc_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = smc_poll_controller;
-#endif
tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev);
INIT_WORK(&lp->phy_configure, smc_phy_configure);
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index c4ccd121bc9c..912308eec865 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -44,6 +44,7 @@
defined(CONFIG_MACH_MAINSTONE) ||\
defined(CONFIG_MACH_ZYLONITE) ||\
defined(CONFIG_MACH_LITTLETON) ||\
+ defined(CONFIG_MACH_ZYLONITE2) ||\
defined(CONFIG_ARCH_VIPER)
#include <asm/mach-types.h>
@@ -345,38 +346,6 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#define RPC_LSA_DEFAULT RPC_LED_TX_RX
#define RPC_LSB_DEFAULT RPC_LED_100_10
-#elif defined(CONFIG_SOC_AU1X00)
-
-#include <au1xxx.h>
-
-/* We can only do 16-bit reads and writes in the static memory space. */
-#define SMC_CAN_USE_8BIT 0
-#define SMC_CAN_USE_16BIT 1
-#define SMC_CAN_USE_32BIT 0
-#define SMC_IO_SHIFT 0
-#define SMC_NOWAIT 1
-
-#define SMC_inw(a, r) au_readw((unsigned long)((a) + (r)))
-#define SMC_insw(a, r, p, l) \
- do { \
- unsigned long _a = (unsigned long)((a) + (r)); \
- int _l = (l); \
- u16 *_p = (u16 *)(p); \
- while (_l-- > 0) \
- *_p++ = au_readw(_a); \
- } while(0)
-#define SMC_outw(v, a, r) au_writew(v, (unsigned long)((a) + (r)))
-#define SMC_outsw(a, r, p, l) \
- do { \
- unsigned long _a = (unsigned long)((a) + (r)); \
- int _l = (l); \
- const u16 *_p = (const u16 *)(p); \
- while (_l-- > 0) \
- au_writew(*_p++ , _a); \
- } while(0)
-
-#define SMC_IRQ_FLAGS (0)
-
#elif defined(CONFIG_ARCH_VERSATILE)
#define SMC_CAN_USE_8BIT 1
@@ -494,8 +463,6 @@ struct smc_local {
*/
#include <linux/dma-mapping.h>
#include <mach/dma.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#ifdef SMC_insl
#undef SMC_insl
@@ -1141,6 +1108,16 @@ static const char * chip_ids[ 16 ] = {
#define SMC_GET_MII(lp) SMC_inw(ioaddr, MII_REG(lp))
+#define SMC_GET_GP(lp) SMC_inw(ioaddr, GP_REG(lp))
+
+#define SMC_SET_GP(lp, x) \
+ do { \
+ if (SMC_MUST_ALIGN_WRITE(lp)) \
+ SMC_outl((x)<<16, ioaddr, SMC_REG(lp, 8, 1)); \
+ else \
+ SMC_outw(x, ioaddr, GP_REG(lp)); \
+ } while (0)
+
#define SMC_SET_MII(lp, x) SMC_outw(x, ioaddr, MII_REG(lp))
#define SMC_GET_MIR(lp) SMC_inw(ioaddr, MIR_REG(lp))
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 9a78daec2fe9..af8f60ca0f57 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -368,48 +368,53 @@ out:
return reg;
}
-/* Autodetects and initialises external phy for SMSC9115 and SMSC9117 flavors.
- * If something goes wrong, returns -ENODEV to revert back to internal phy.
- * Performed at initialisation only, so interrupts are enabled */
-static int smsc911x_phy_initialise_external(struct smsc911x_data *pdata)
+/* Switch to external phy. Assumes tx and rx are stopped. */
+static void smsc911x_phy_enable_external(struct smsc911x_data *pdata)
{
unsigned int hwcfg = smsc911x_reg_read(pdata, HW_CFG);
- /* External phy is requested, supported, and detected */
- if (hwcfg & HW_CFG_EXT_PHY_DET_) {
+ /* Disable phy clocks to the MAC */
+ hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
+ hwcfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_;
+ smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+ udelay(10); /* Enough time for clocks to stop */
- /* Switch to external phy. Assuming tx and rx are stopped
- * because smsc911x_phy_initialise is called before
- * smsc911x_rx_initialise and tx_initialise. */
+ /* Switch to external phy */
+ hwcfg |= HW_CFG_EXT_PHY_EN_;
+ smsc911x_reg_write(pdata, HW_CFG, hwcfg);
- /* Disable phy clocks to the MAC */
- hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
- hwcfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_;
- smsc911x_reg_write(pdata, HW_CFG, hwcfg);
- udelay(10); /* Enough time for clocks to stop */
+ /* Enable phy clocks to the MAC */
+ hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
+ hwcfg |= HW_CFG_PHY_CLK_SEL_EXT_PHY_;
+ smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+ udelay(10); /* Enough time for clocks to restart */
- /* Switch to external phy */
- hwcfg |= HW_CFG_EXT_PHY_EN_;
- smsc911x_reg_write(pdata, HW_CFG, hwcfg);
-
- /* Enable phy clocks to the MAC */
- hwcfg &= (~HW_CFG_PHY_CLK_SEL_);
- hwcfg |= HW_CFG_PHY_CLK_SEL_EXT_PHY_;
- smsc911x_reg_write(pdata, HW_CFG, hwcfg);
- udelay(10); /* Enough time for clocks to restart */
+ hwcfg |= HW_CFG_SMI_SEL_;
+ smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+}
- hwcfg |= HW_CFG_SMI_SEL_;
- smsc911x_reg_write(pdata, HW_CFG, hwcfg);
+/* Autodetects and enables external phy if present on supported chips.
+ * autodetection can be overridden by specifying SMSC911X_FORCE_INTERNAL_PHY
+ * or SMSC911X_FORCE_EXTERNAL_PHY in the platform_data flags. */
+static void smsc911x_phy_initialise_external(struct smsc911x_data *pdata)
+{
+ unsigned int hwcfg = smsc911x_reg_read(pdata, HW_CFG);
- SMSC_TRACE(HW, "Successfully switched to external PHY");
+ if (pdata->config.flags & SMSC911X_FORCE_INTERNAL_PHY) {
+ SMSC_TRACE(HW, "Forcing internal PHY");
+ pdata->using_extphy = 0;
+ } else if (pdata->config.flags & SMSC911X_FORCE_EXTERNAL_PHY) {
+ SMSC_TRACE(HW, "Forcing external PHY");
+ smsc911x_phy_enable_external(pdata);
+ pdata->using_extphy = 1;
+ } else if (hwcfg & HW_CFG_EXT_PHY_DET_) {
+ SMSC_TRACE(HW, "HW_CFG EXT_PHY_DET set, using external PHY");
+ smsc911x_phy_enable_external(pdata);
pdata->using_extphy = 1;
} else {
- SMSC_WARNING(HW, "No external PHY detected, "
- "Using internal PHY instead.");
- /* Use internal phy */
- return -ENODEV;
+ SMSC_TRACE(HW, "HW_CFG EXT_PHY_DET clear, using internal PHY");
+ pdata->using_extphy = 0;
}
- return 0;
}
/* Fetches a tx status out of the status fifo */
@@ -769,7 +774,7 @@ static int smsc911x_mii_probe(struct net_device *dev)
return -ENODEV;
}
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&smsc911x_phy_adjust_link, 0, pdata->config.phy_interface);
if (IS_ERR(phydev)) {
@@ -778,7 +783,8 @@ static int smsc911x_mii_probe(struct net_device *dev)
}
pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ dev->name, phydev->drv->name,
+ dev_name(&phydev->dev), phydev->irq);
/* mask with MAC supported features */
phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
@@ -824,22 +830,18 @@ static int __devinit smsc911x_mii_init(struct platform_device *pdev,
pdata->mii_bus->parent = &pdev->dev;
- pdata->using_extphy = 0;
-
switch (pdata->idrev & 0xFFFF0000) {
case 0x01170000:
case 0x01150000:
case 0x117A0000:
case 0x115A0000:
/* External PHY supported, try to autodetect */
- if (smsc911x_phy_initialise_external(pdata) < 0) {
- SMSC_TRACE(HW, "No external PHY detected, "
- "using internal PHY");
- }
+ smsc911x_phy_initialise_external(pdata);
break;
default:
SMSC_TRACE(HW, "External PHY is not supported, "
"using internal PHY");
+ pdata->using_extphy = 0;
break;
}
@@ -893,22 +895,22 @@ static void smsc911x_tx_update_txcounters(struct net_device *dev)
SMSC_WARNING(HW,
"Packet tag reserved bit is high");
} else {
- if (unlikely(tx_stat & 0x00008000)) {
+ if (unlikely(tx_stat & TX_STS_ES_)) {
dev->stats.tx_errors++;
} else {
dev->stats.tx_packets++;
dev->stats.tx_bytes += (tx_stat >> 16);
}
- if (unlikely(tx_stat & 0x00000100)) {
+ if (unlikely(tx_stat & TX_STS_EXCESS_COL_)) {
dev->stats.collisions += 16;
dev->stats.tx_aborted_errors += 1;
} else {
dev->stats.collisions +=
((tx_stat >> 3) & 0xF);
}
- if (unlikely(tx_stat & 0x00000800))
+ if (unlikely(tx_stat & TX_STS_LOST_CARRIER_))
dev->stats.tx_carrier_errors += 1;
- if (unlikely(tx_stat & 0x00000200)) {
+ if (unlikely(tx_stat & TX_STS_LATE_COL_)) {
dev->stats.collisions++;
dev->stats.tx_aborted_errors++;
}
@@ -922,19 +924,17 @@ smsc911x_rx_counterrors(struct net_device *dev, unsigned int rxstat)
{
int crc_err = 0;
- if (unlikely(rxstat & 0x00008000)) {
+ if (unlikely(rxstat & RX_STS_ES_)) {
dev->stats.rx_errors++;
- if (unlikely(rxstat & 0x00000002)) {
+ if (unlikely(rxstat & RX_STS_CRC_ERR_)) {
dev->stats.rx_crc_errors++;
crc_err = 1;
}
}
if (likely(!crc_err)) {
- if (unlikely((rxstat & 0x00001020) == 0x00001020)) {
- /* Frame type indicates length,
- * and length error is set */
+ if (unlikely((rxstat & RX_STS_FRAME_TYPE_) &&
+ (rxstat & RX_STS_LENGTH_ERR_)))
dev->stats.rx_length_errors++;
- }
if (rxstat & RX_STS_MCAST_)
dev->stats.multicast++;
}
@@ -953,7 +953,7 @@ smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes)
do {
udelay(1);
val = smsc911x_reg_read(pdata, RX_DP_CTRL);
- } while (--timeout && (val & RX_DP_CTRL_RX_FFWD_));
+ } while ((val & RX_DP_CTRL_RX_FFWD_) && --timeout);
if (unlikely(timeout == 0))
SMSC_WARNING(HW, "Timed out waiting for "
@@ -984,7 +984,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
/* We processed all packets available. Tell NAPI it can
* stop polling then re-enable rx interrupts */
smsc911x_reg_write(pdata, INT_STS, INT_STS_RSFL_);
- netif_rx_complete(napi);
+ napi_complete(napi);
temp = smsc911x_reg_read(pdata, INT_EN);
temp |= INT_EN_RSFL_EN_;
smsc911x_reg_write(pdata, INT_EN, temp);
@@ -1119,7 +1119,7 @@ static int smsc911x_soft_reset(struct smsc911x_data *pdata)
/* Sets the device MAC address to dev_addr, called with mac_lock held */
static void
-smsc911x_set_mac_address(struct smsc911x_data *pdata, u8 dev_addr[6])
+smsc911x_set_hw_mac_address(struct smsc911x_data *pdata, u8 dev_addr[6])
{
u32 mac_high16 = (dev_addr[5] << 8) | dev_addr[4];
u32 mac_low32 = (dev_addr[3] << 24) | (dev_addr[2] << 16) |
@@ -1160,8 +1160,8 @@ static int smsc911x_open(struct net_device *dev)
/* Make sure EEPROM has finished loading before setting GPIO_CFG */
timeout = 50;
- while ((timeout--) &&
- (smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_)) {
+ while ((smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) &&
+ --timeout) {
udelay(10);
}
@@ -1174,7 +1174,7 @@ static int smsc911x_open(struct net_device *dev)
/* The soft reset above cleared the device's MAC address,
* restore it from local copy (set in probe) */
spin_lock_irq(&pdata->mac_lock);
- smsc911x_set_mac_address(pdata, dev->dev_addr);
+ smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
spin_unlock_irq(&pdata->mac_lock);
/* Initialise irqs, but leave all sources disabled */
@@ -1225,6 +1225,10 @@ static int smsc911x_open(struct net_device *dev)
dev_info(&dev->dev, "SMSC911x/921x identified at %#08lx, IRQ: %d\n",
(unsigned long)pdata->ioaddr, dev->irq);
+ /* Reset the last known duplex and carrier */
+ pdata->last_duplex = -1;
+ pdata->last_carrier = -1;
+
/* Bring the PHY up */
phy_start(pdata->phy_dev);
@@ -1246,7 +1250,7 @@ static int smsc911x_open(struct net_device *dev)
napi_enable(&pdata->napi);
temp = smsc911x_reg_read(pdata, INT_EN);
- temp |= (INT_EN_TDFA_EN_ | INT_EN_RSFL_EN_);
+ temp |= (INT_EN_TDFA_EN_ | INT_EN_RSFL_EN_ | INT_EN_RXSTOP_INT_EN_);
smsc911x_reg_write(pdata, INT_EN, temp);
spin_lock_irq(&pdata->mac_lock);
@@ -1418,11 +1422,6 @@ static void smsc911x_set_multicast_list(struct net_device *dev)
/* Request the hardware to stop, then perform the
* update when we get an RX_STOP interrupt */
- smsc911x_reg_write(pdata, INT_STS, INT_STS_RXSTOP_INT_);
- temp = smsc911x_reg_read(pdata, INT_EN);
- temp |= INT_EN_RXSTOP_INT_EN_;
- smsc911x_reg_write(pdata, INT_EN, temp);
-
temp = smsc911x_mac_read(pdata, MAC_CR);
temp &= ~(MAC_CR_RXEN_);
smsc911x_mac_write(pdata, MAC_CR, temp);
@@ -1461,11 +1460,9 @@ static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id)
/* Called when there is a multicast update scheduled and
* it is now safe to complete the update */
SMSC_TRACE(INTR, "RX Stop interrupt");
- temp = smsc911x_reg_read(pdata, INT_EN);
- temp &= (~INT_EN_RXSTOP_INT_EN_);
- smsc911x_reg_write(pdata, INT_EN, temp);
smsc911x_reg_write(pdata, INT_STS, INT_STS_RXSTOP_INT_);
- smsc911x_rx_multicast_update_workaround(pdata);
+ if (pdata->multicast_update_pending)
+ smsc911x_rx_multicast_update_workaround(pdata);
serviced = IRQ_HANDLED;
}
@@ -1485,16 +1482,16 @@ static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id)
}
if (likely(intsts & inten & INT_STS_RSFL_)) {
- if (likely(netif_rx_schedule_prep(&pdata->napi))) {
+ if (likely(napi_schedule_prep(&pdata->napi))) {
/* Disable Rx interrupts */
temp = smsc911x_reg_read(pdata, INT_EN);
temp &= (~INT_EN_RSFL_EN_);
smsc911x_reg_write(pdata, INT_EN, temp);
/* Schedule a NAPI poll */
- __netif_rx_schedule(&pdata->napi);
+ __napi_schedule(&pdata->napi);
} else {
SMSC_WARNING(RX_ERR,
- "netif_rx_schedule_prep failed");
+ "napi_schedule_prep failed");
}
serviced = IRQ_HANDLED;
}
@@ -1511,6 +1508,31 @@ static void smsc911x_poll_controller(struct net_device *dev)
}
#endif /* CONFIG_NET_POLL_CONTROLLER */
+static int smsc911x_set_mac_address(struct net_device *dev, void *p)
+{
+ struct smsc911x_data *pdata = netdev_priv(dev);
+ struct sockaddr *addr = p;
+
+ /* On older hardware revisions we cannot change the mac address
+ * registers while receiving data. Newer devices can safely change
+ * this at any time. */
+ if (pdata->generation <= 1 && netif_running(dev))
+ return -EBUSY;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
+ spin_lock_irq(&pdata->mac_lock);
+ smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
+ spin_unlock_irq(&pdata->mac_lock);
+
+ dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr);
+
+ return 0;
+}
+
/* Standard ioctls for mii-tool */
static int smsc911x_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
@@ -1545,7 +1567,7 @@ static void smsc911x_ethtool_getdrvinfo(struct net_device *dev,
{
strlcpy(info->driver, SMSC_CHIPNAME, sizeof(info->driver));
strlcpy(info->version, SMSC_DRV_VERSION, sizeof(info->version));
- strlcpy(info->bus_info, dev->dev.parent->bus_id,
+ strlcpy(info->bus_info, dev_name(dev->dev.parent),
sizeof(info->bus_info));
}
@@ -1658,6 +1680,7 @@ static int smsc911x_eeprom_write_location(struct smsc911x_data *pdata,
u8 address, u8 data)
{
u32 op = E2P_CMD_EPC_CMD_ERASE_ | address;
+ u32 temp;
int ret;
SMSC_TRACE(DRV, "address 0x%x, data 0x%x", address, data);
@@ -1666,6 +1689,10 @@ static int smsc911x_eeprom_write_location(struct smsc911x_data *pdata,
if (!ret) {
op = E2P_CMD_EPC_CMD_WRITE_ | address;
smsc911x_reg_write(pdata, E2P_DATA, (u32)data);
+
+ /* Workaround for hardware read-after-write restriction */
+ temp = smsc911x_reg_read(pdata, BYTE_TEST);
+
ret = smsc911x_eeprom_send_cmd(pdata, op);
}
@@ -1741,12 +1768,27 @@ static const struct net_device_ops smsc911x_netdev_ops = {
.ndo_set_multicast_list = smsc911x_set_multicast_list,
.ndo_do_ioctl = smsc911x_do_ioctl,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = smsc911x_set_mac_address,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = smsc911x_poll_controller,
#endif
};
+/* copies the current mac address from hardware to dev->dev_addr */
+static void __devinit smsc911x_read_mac_address(struct net_device *dev)
+{
+ struct smsc911x_data *pdata = netdev_priv(dev);
+ u32 mac_high16 = smsc911x_mac_read(pdata, ADDRH);
+ u32 mac_low32 = smsc911x_mac_read(pdata, ADDRL);
+
+ dev->dev_addr[0] = (u8)(mac_low32);
+ dev->dev_addr[1] = (u8)(mac_low32 >> 8);
+ dev->dev_addr[2] = (u8)(mac_low32 >> 16);
+ dev->dev_addr[3] = (u8)(mac_low32 >> 24);
+ dev->dev_addr[4] = (u8)(mac_high16);
+ dev->dev_addr[5] = (u8)(mac_high16 >> 8);
+}
+
/* Initializing private device structures, only called from probe */
static int __devinit smsc911x_init(struct net_device *dev)
{
@@ -1834,6 +1876,12 @@ static int __devinit smsc911x_init(struct net_device *dev)
SMSC_WARNING(PROBE,
"This driver is not intended for this chip revision");
+ /* workaround for platforms without an eeprom, where the mac address
+ * is stored elsewhere and set by the bootloader. This saves the
+ * mac address before resetting the device */
+ if (pdata->config.flags & SMSC911X_SAVE_MAC_ADDRESS)
+ smsc911x_read_mac_address(dev);
+
/* Reset the LAN911x */
if (smsc911x_soft_reset(pdata))
return -ENODEV;
@@ -1892,11 +1940,10 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
struct net_device *dev;
struct smsc911x_data *pdata;
struct smsc911x_platform_config *config = pdev->dev.platform_data;
- struct resource *res;
+ struct resource *res, *irq_res;
unsigned int intcfg = 0;
- int res_size;
+ int res_size, irq_flags;
int retval;
- DECLARE_MAC_BUF(mac);
pr_info("%s: Driver version %s.\n", SMSC_CHIPNAME, SMSC_DRV_VERSION);
@@ -1919,6 +1966,14 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
}
res_size = res->end - res->start;
+ irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!irq_res) {
+ pr_warning("%s: Could not allocate irq resource.\n",
+ SMSC_CHIPNAME);
+ retval = -ENODEV;
+ goto out_0;
+ }
+
if (!request_mem_region(res->start, res_size, SMSC_CHIPNAME)) {
retval = -EBUSY;
goto out_0;
@@ -1935,7 +1990,8 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
pdata = netdev_priv(dev);
- dev->irq = platform_get_irq(pdev, 0);
+ dev->irq = irq_res->start;
+ irq_flags = irq_res->flags & IRQF_TRIGGER_MASK;
pdata->ioaddr = ioremap_nocache(res->start, res_size);
/* copy config parameters across to pdata */
@@ -1968,8 +2024,8 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
smsc911x_reg_write(pdata, INT_EN, 0);
smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF);
- retval = request_irq(dev->irq, smsc911x_irqhandler, IRQF_DISABLED,
- dev->name, dev);
+ retval = request_irq(dev->irq, smsc911x_irqhandler,
+ irq_flags | IRQF_SHARED, dev->name, dev);
if (retval) {
SMSC_WARNING(PROBE,
"Unable to claim requested irq: %d", dev->irq);
@@ -2000,19 +2056,12 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
/* Check if mac address has been specified when bringing interface up */
if (is_valid_ether_addr(dev->dev_addr)) {
- smsc911x_set_mac_address(pdata, dev->dev_addr);
+ smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
SMSC_TRACE(PROBE, "MAC Address is specified by configuration");
} else {
/* Try reading mac address from device. if EEPROM is present
* it will already have been set */
- u32 mac_high16 = smsc911x_mac_read(pdata, ADDRH);
- u32 mac_low32 = smsc911x_mac_read(pdata, ADDRL);
- dev->dev_addr[0] = (u8)(mac_low32);
- dev->dev_addr[1] = (u8)(mac_low32 >> 8);
- dev->dev_addr[2] = (u8)(mac_low32 >> 16);
- dev->dev_addr[3] = (u8)(mac_low32 >> 24);
- dev->dev_addr[4] = (u8)(mac_high16);
- dev->dev_addr[5] = (u8)(mac_high16 >> 8);
+ smsc911x_read_mac_address(dev);
if (is_valid_ether_addr(dev->dev_addr)) {
/* eeprom values are valid so use them */
@@ -2021,7 +2070,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
} else {
/* eeprom values are invalid, generate random MAC */
random_ether_addr(dev->dev_addr);
- smsc911x_set_mac_address(pdata, dev->dev_addr);
+ smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
SMSC_TRACE(PROBE,
"MAC Address is set to random_ether_addr");
}
@@ -2029,8 +2078,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
spin_unlock_irq(&pdata->mac_lock);
- dev_info(&dev->dev, "MAC Address: %s\n",
- print_mac(mac, dev->dev_addr));
+ dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr);
return 0;
diff --git a/drivers/net/smsc911x.h b/drivers/net/smsc911x.h
index 2b76654bb958..b5716bd8a597 100644
--- a/drivers/net/smsc911x.h
+++ b/drivers/net/smsc911x.h
@@ -81,12 +81,19 @@
#define RX_STATUS_FIFO 0x40
#define RX_STS_ES_ 0x00008000
+#define RX_STS_LENGTH_ERR_ 0x00001000
#define RX_STS_MCAST_ 0x00000400
+#define RX_STS_FRAME_TYPE_ 0x00000020
+#define RX_STS_CRC_ERR_ 0x00000002
#define RX_STATUS_FIFO_PEEK 0x44
#define TX_STATUS_FIFO 0x48
#define TX_STS_ES_ 0x00008000
+#define TX_STS_LOST_CARRIER_ 0x00000800
+#define TX_STS_NO_CARRIER_ 0x00000400
+#define TX_STS_LATE_COL_ 0x00000200
+#define TX_STS_EXCESS_COL_ 0x00000100
#define TX_STATUS_FIFO_PEEK 0x4C
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index 4e15ae068b3f..5959ae86e57d 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -670,7 +670,7 @@ static irqreturn_t smsc9420_isr(int irq, void *dev_id)
smsc9420_pci_flush_write(pd);
ints_to_clear |= (DMAC_STS_RX_ | DMAC_STS_NIS_);
- netif_rx_schedule(&pd->napi);
+ napi_schedule(&pd->napi);
}
if (ints_to_clear)
@@ -807,7 +807,7 @@ static void smsc9420_rx_handoff(struct smsc9420_pdata *pd, const int index,
if (pd->rx_csum) {
u16 hw_csum = get_unaligned_le16(skb_tail_pointer(skb) +
NET_IP_ALIGN + packet_length + 4);
- put_unaligned_le16(cpu_to_le16(hw_csum), &skb->csum);
+ put_unaligned_le16(hw_csum, &skb->csum);
skb->ip_summed = CHECKSUM_COMPLETE;
}
@@ -893,7 +893,7 @@ static int smsc9420_rx_poll(struct napi_struct *napi, int budget)
smsc9420_pci_flush_write(pd);
if (work_done < budget) {
- netif_rx_complete(&pd->napi);
+ napi_complete(&pd->napi);
/* re-enable RX DMA interrupts */
dma_intr_ena = smsc9420_reg_read(pd, DMAC_INTR_ENA);
@@ -1160,7 +1160,7 @@ static int smsc9420_mii_probe(struct net_device *dev)
smsc_info(PROBE, "PHY addr %d, phy_id 0x%08X", phydev->addr,
phydev->phy_id);
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&smsc9420_phy_adjust_link, 0, PHY_INTERFACE_MODE_MII);
if (IS_ERR(phydev)) {
@@ -1169,7 +1169,7 @@ static int smsc9420_mii_probe(struct net_device *dev)
}
pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+ dev->name, phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
/* mask with MAC supported features */
phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 88d2c67788df..90e663f4515c 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1301,7 +1301,7 @@ static int spider_net_poll(struct napi_struct *napi, int budget)
/* if all packets are in the stack, enable interrupts and return 0 */
/* if not, return 1 */
if (packets_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
spider_net_rx_irq_on(card);
card->ignore_rx_ramfull = 0;
}
@@ -1528,7 +1528,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg,
spider_net_refill_rx_chain(card);
spider_net_enable_rxdmac(card);
card->num_rx_ints ++;
- netif_rx_schedule(&card->napi);
+ napi_schedule(&card->napi);
}
show_error = 0;
break;
@@ -1548,7 +1548,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg,
spider_net_refill_rx_chain(card);
spider_net_enable_rxdmac(card);
card->num_rx_ints ++;
- netif_rx_schedule(&card->napi);
+ napi_schedule(&card->napi);
show_error = 0;
break;
@@ -1562,7 +1562,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg,
spider_net_refill_rx_chain(card);
spider_net_enable_rxdmac(card);
card->num_rx_ints ++;
- netif_rx_schedule(&card->napi);
+ napi_schedule(&card->napi);
show_error = 0;
break;
@@ -1656,11 +1656,11 @@ spider_net_interrupt(int irq, void *ptr)
if (status_reg & SPIDER_NET_RXINT ) {
spider_net_rx_irq_off(card);
- netif_rx_schedule(&card->napi);
+ napi_schedule(&card->napi);
card->num_rx_ints ++;
}
if (status_reg & SPIDER_NET_TXINT)
- netif_rx_schedule(&card->napi);
+ napi_schedule(&card->napi);
if (status_reg & SPIDER_NET_LINKINT)
spider_net_link_reset(netdev);
@@ -2259,6 +2259,23 @@ spider_net_tx_timeout(struct net_device *netdev)
card->spider_stats.tx_timeouts++;
}
+static const struct net_device_ops spider_net_ops = {
+ .ndo_open = spider_net_open,
+ .ndo_stop = spider_net_stop,
+ .ndo_start_xmit = spider_net_xmit,
+ .ndo_set_multicast_list = spider_net_set_multi,
+ .ndo_set_mac_address = spider_net_set_mac,
+ .ndo_change_mtu = spider_net_change_mtu,
+ .ndo_do_ioctl = spider_net_do_ioctl,
+ .ndo_tx_timeout = spider_net_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+ /* HW VLAN */
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ /* poll controller */
+ .ndo_poll_controller = spider_net_poll_controller,
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+};
+
/**
* spider_net_setup_netdev_ops - initialization of net_device operations
* @netdev: net_device structure
@@ -2268,21 +2285,8 @@ spider_net_tx_timeout(struct net_device *netdev)
static void
spider_net_setup_netdev_ops(struct net_device *netdev)
{
- netdev->open = &spider_net_open;
- netdev->stop = &spider_net_stop;
- netdev->hard_start_xmit = &spider_net_xmit;
- netdev->set_multicast_list = &spider_net_set_multi;
- netdev->set_mac_address = &spider_net_set_mac;
- netdev->change_mtu = &spider_net_change_mtu;
- netdev->do_ioctl = &spider_net_do_ioctl;
- /* tx watchdog */
- netdev->tx_timeout = &spider_net_tx_timeout;
+ netdev->netdev_ops = &spider_net_ops;
netdev->watchdog_timeo = SPIDER_NET_WATCHDOG_TIMEOUT;
- /* HW VLAN */
-#ifdef CONFIG_NET_POLL_CONTROLLER
- /* poll controller */
- netdev->poll_controller = &spider_net_poll_controller;
-#endif /* CONFIG_NET_POLL_CONTROLLER */
/* ethtool ops */
netdev->ethtool_ops = &spider_net_ethtool_ops;
}
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index da3a76b18eff..fcb943fca4f1 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -178,7 +178,7 @@ static int full_duplex[MAX_UNITS] = {0, };
#define FIRMWARE_TX "adaptec/starfire_tx.bin"
/* These identify the driver base version and may not be removed. */
-static char version[] =
+static const char version[] __devinitconst =
KERN_INFO "starfire.c:v1.03 7/26/2000 Written by Donald Becker <becker@scyld.com>\n"
KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
@@ -1342,8 +1342,8 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
if (intr_status & (IntrRxDone | IntrRxEmpty)) {
u32 enable;
- if (likely(netif_rx_schedule_prep(&np->napi))) {
- __netif_rx_schedule(&np->napi);
+ if (likely(napi_schedule_prep(&np->napi))) {
+ __napi_schedule(&np->napi);
enable = readl(ioaddr + IntrEnable);
enable &= ~(IntrRxDone | IntrRxEmpty);
writel(enable, ioaddr + IntrEnable);
@@ -1587,7 +1587,7 @@ static int netdev_poll(struct napi_struct *napi, int budget)
intr_status = readl(ioaddr + IntrStatus);
} while (intr_status & (IntrRxDone | IntrRxEmpty));
- netif_rx_complete(napi);
+ napi_complete(napi);
intr_status = readl(ioaddr + IntrEnable);
intr_status |= IntrRxDone | IntrRxEmpty;
writel(intr_status, ioaddr + IntrEnable);
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index 7f69c7f176c4..5017d7fcb40c 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -1074,6 +1074,18 @@ static const struct ethtool_ops bigmac_ethtool_ops = {
.get_link = bigmac_get_link,
};
+static const struct net_device_ops bigmac_ops = {
+ .ndo_open = bigmac_open,
+ .ndo_stop = bigmac_close,
+ .ndo_start_xmit = bigmac_start_xmit,
+ .ndo_get_stats = bigmac_get_stats,
+ .ndo_set_multicast_list = bigmac_set_multicast,
+ .ndo_tx_timeout = bigmac_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __devinit bigmac_ether_init(struct of_device *op,
struct of_device *qec_op)
{
@@ -1187,16 +1199,8 @@ static int __devinit bigmac_ether_init(struct of_device *op,
bp->dev = dev;
/* Set links to our BigMAC open and close routines. */
- dev->open = &bigmac_open;
- dev->stop = &bigmac_close;
- dev->hard_start_xmit = &bigmac_start_xmit;
dev->ethtool_ops = &bigmac_ethtool_ops;
-
- /* Set links to BigMAC statistic and multi-cast loading code. */
- dev->get_stats = &bigmac_get_stats;
- dev->set_multicast_list = &bigmac_set_multicast;
-
- dev->tx_timeout = &bigmac_tx_timeout;
+ dev->netdev_ops = &bigmac_ops;
dev->watchdog_timeo = 5*HZ;
/* Finish net device registration. */
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 43695b76606f..c399b1955c1e 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -109,8 +109,9 @@ static char *media[MAX_UNITS];
#endif
/* These identify the driver base version and may not be removed. */
-static char version[] =
-KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n";
+static const char version[] __devinitconst =
+ KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE
+ " Written by Donald Becker\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("Sundance Alta Ethernet driver");
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 0fcb7503363d..c024352c92fd 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -921,7 +921,7 @@ static int gem_poll(struct napi_struct *napi, int budget)
gp->status = readl(gp->regs + GREG_STAT);
} while (gp->status & GREG_STAT_NAPI);
- __netif_rx_complete(napi);
+ __napi_complete(napi);
gem_enable_ints(gp);
spin_unlock_irqrestore(&gp->lock, flags);
@@ -944,7 +944,7 @@ static irqreturn_t gem_interrupt(int irq, void *dev_id)
spin_lock_irqsave(&gp->lock, flags);
- if (netif_rx_schedule_prep(&gp->napi)) {
+ if (napi_schedule_prep(&gp->napi)) {
u32 gem_status = readl(gp->regs + GREG_STAT);
if (gem_status == 0) {
@@ -954,7 +954,7 @@ static irqreturn_t gem_interrupt(int irq, void *dev_id)
}
gp->status = gem_status;
gem_disable_ints(gp);
- __netif_rx_schedule(&gp->napi);
+ __napi_schedule(&gp->napi);
}
spin_unlock_irqrestore(&gp->lock, flags);
@@ -2998,8 +2998,11 @@ static const struct net_device_ops gem_netdev_ops = {
.ndo_do_ioctl = gem_ioctl,
.ndo_tx_timeout = gem_tx_timeout,
.ndo_change_mtu = gem_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = gem_set_mac_address,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = gem_poll_controller,
+#endif
};
static int __devinit gem_init_one(struct pci_dev *pdev,
@@ -3161,10 +3164,6 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
dev->watchdog_timeo = 5 * HZ;
dev->irq = pdev->irq;
dev->dma = 0;
- dev->set_mac_address = gem_set_mac_address;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = gem_poll_controller;
-#endif
/* Set that now, in case PM kicks in now */
pci_set_drvdata(pdev, dev);
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 16c528db7251..afc7b351e5ec 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -1311,6 +1311,17 @@ static const struct ethtool_ops sparc_lance_ethtool_ops = {
.get_link = sparc_lance_get_link,
};
+static const struct net_device_ops sparc_lance_ops = {
+ .ndo_open = lance_open,
+ .ndo_stop = lance_close,
+ .ndo_start_xmit = lance_start_xmit,
+ .ndo_set_multicast_list = lance_set_multicast,
+ .ndo_tx_timeout = lance_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __devinit sparc_lance_probe_one(struct of_device *op,
struct of_device *ledma,
struct of_device *lebuffer)
@@ -1462,13 +1473,9 @@ no_link_test:
lp->dev = dev;
SET_NETDEV_DEV(dev, &op->dev);
- dev->open = &lance_open;
- dev->stop = &lance_close;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->tx_timeout = &lance_tx_timeout;
dev->watchdog_timeo = 5*HZ;
- dev->set_multicast_list = &lance_set_multicast;
dev->ethtool_ops = &sparc_lance_ethtool_ops;
+ dev->netdev_ops = &sparc_lance_ops;
dev->irq = op->irqs[0];
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index fe0c3f244562..c6ec61e0accf 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -829,6 +829,17 @@ fail:
return NULL;
}
+static const struct net_device_ops qec_ops = {
+ .ndo_open = qe_open,
+ .ndo_stop = qe_close,
+ .ndo_start_xmit = qe_start_xmit,
+ .ndo_set_multicast_list = qe_set_multicast,
+ .ndo_tx_timeout = qe_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int __devinit qec_ether_init(struct of_device *op)
{
static unsigned version_printed;
@@ -893,15 +904,11 @@ static int __devinit qec_ether_init(struct of_device *op)
SET_NETDEV_DEV(dev, &op->dev);
- dev->open = qe_open;
- dev->stop = qe_close;
- dev->hard_start_xmit = qe_start_xmit;
- dev->set_multicast_list = qe_set_multicast;
- dev->tx_timeout = qe_tx_timeout;
dev->watchdog_timeo = 5*HZ;
dev->irq = op->irqs[0];
dev->dma = 0;
dev->ethtool_ops = &qe_ethtool_ops;
+ dev->netdev_ops = &qec_ops;
res = register_netdev(dev);
if (res)
diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c
index 611230fef2b6..a82fb2aca4cb 100644
--- a/drivers/net/sunvnet.c
+++ b/drivers/net/sunvnet.c
@@ -1012,6 +1012,16 @@ err_out:
static LIST_HEAD(vnet_list);
static DEFINE_MUTEX(vnet_list_mutex);
+static const struct net_device_ops vnet_ops = {
+ .ndo_open = vnet_open,
+ .ndo_stop = vnet_close,
+ .ndo_set_multicast_list = vnet_set_rx_mode,
+ .ndo_set_mac_address = vnet_set_mac_addr,
+ .ndo_tx_timeout = vnet_tx_timeout,
+ .ndo_change_mtu = vnet_change_mtu,
+ .ndo_start_xmit = vnet_start_xmit,
+};
+
static struct vnet * __devinit vnet_new(const u64 *local_mac)
{
struct net_device *dev;
@@ -1040,15 +1050,9 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac)
INIT_LIST_HEAD(&vp->list);
vp->local_mac = *local_mac;
- dev->open = vnet_open;
- dev->stop = vnet_close;
- dev->set_multicast_list = vnet_set_rx_mode;
- dev->set_mac_address = vnet_set_mac_addr;
- dev->tx_timeout = vnet_tx_timeout;
+ dev->netdev_ops = &vnet_ops;
dev->ethtool_ops = &vnet_ethtool_ops;
dev->watchdog_timeo = VNET_TX_TIMEOUT;
- dev->change_mtu = vnet_change_mtu;
- dev->hard_start_xmit = vnet_start_xmit;
err = register_netdev(dev);
if (err) {
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index bcd0e60cbda9..d91e95b237b7 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -725,7 +725,7 @@ static int tc_mii_probe(struct net_device *dev)
}
/* attach the mac to the phy */
- phydev = phy_connect(dev, phydev->dev.bus_id,
+ phydev = phy_connect(dev, dev_name(&phydev->dev),
&tc_handle_link_change, 0,
lp->chiptype == TC35815_TX4939 ?
PHY_INTERFACE_MODE_RMII : PHY_INTERFACE_MODE_MII);
@@ -735,7 +735,7 @@ static int tc_mii_probe(struct net_device *dev)
}
printk(KERN_INFO "%s: attached PHY driver [%s] "
"(mii_bus:phy_addr=%s, id=%x)\n",
- dev->name, phydev->drv->name, phydev->dev.bus_id,
+ dev->name, phydev->drv->name, dev_name(&phydev->dev),
phydev->phy_id);
/* mask with MAC supported features */
@@ -1609,8 +1609,8 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id)
if (!(dmactl & DMA_IntMask)) {
/* disable interrupts */
tc_writel(dmactl | DMA_IntMask, &tr->DMA_Ctl);
- if (netif_rx_schedule_prep(&lp->napi))
- __netif_rx_schedule(&lp->napi);
+ if (napi_schedule_prep(&lp->napi))
+ __napi_schedule(&lp->napi);
else {
printk(KERN_ERR "%s: interrupt taken in poll\n",
dev->name);
@@ -1908,7 +1908,7 @@ static int tc35815_poll(struct napi_struct *napi, int budget)
do {
tc_writel(status, &tr->Int_Src); /* write to clear */
- handled = tc35815_do_interrupt(dev, status, limit);
+ handled = tc35815_do_interrupt(dev, status, budget - received);
if (handled >= 0) {
received += handled;
if (received >= budget)
@@ -1919,7 +1919,7 @@ static int tc35815_poll(struct napi_struct *napi, int budget)
spin_unlock(&lp->lock);
if (received < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
/* enable interrupts */
tc_writel(tc_readl(&tr->DMA_Ctl) & ~DMA_IntMask, &tr->DMA_Ctl);
}
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index a7a4dc4d6313..7debd1e4e1f7 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -63,7 +63,6 @@
*/
#include "tehuti.h"
-#include "tehuti_fw.h"
static struct pci_device_id __devinitdata bdx_pci_tbl[] = {
{0x1FC9, 0x3009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -265,8 +264,8 @@ static irqreturn_t bdx_isr_napi(int irq, void *dev)
bdx_isr_extra(priv, isr);
if (isr & (IR_RX_DESC_0 | IR_TX_FREE_0)) {
- if (likely(netif_rx_schedule_prep(&priv->napi))) {
- __netif_rx_schedule(&priv->napi);
+ if (likely(napi_schedule_prep(&priv->napi))) {
+ __napi_schedule(&priv->napi);
RET(IRQ_HANDLED);
} else {
/* NOTE: we get here if intr has slipped into window
@@ -302,7 +301,7 @@ static int bdx_poll(struct napi_struct *napi, int budget)
* device lock and allow waiting tasks (eg rmmod) to advance) */
priv->napi_stop = 0;
- netif_rx_complete(napi);
+ napi_complete(napi);
bdx_enable_interrupts(priv);
}
return work_done;
@@ -318,28 +317,41 @@ static int bdx_poll(struct napi_struct *napi, int budget)
static int bdx_fw_load(struct bdx_priv *priv)
{
+ const struct firmware *fw = NULL;
int master, i;
+ int rc;
ENTER;
master = READ_REG(priv, regINIT_SEMAPHORE);
if (!READ_REG(priv, regINIT_STATUS) && master) {
- bdx_tx_push_desc_safe(priv, s_firmLoad, sizeof(s_firmLoad));
+ rc = request_firmware(&fw, "tehuti/firmware.bin", &priv->pdev->dev);
+ if (rc)
+ goto out;
+ bdx_tx_push_desc_safe(priv, (char *)fw->data, fw->size);
mdelay(100);
}
for (i = 0; i < 200; i++) {
- if (READ_REG(priv, regINIT_STATUS))
- break;
+ if (READ_REG(priv, regINIT_STATUS)) {
+ rc = 0;
+ goto out;
+ }
mdelay(2);
}
+ rc = -EIO;
+out:
if (master)
WRITE_REG(priv, regINIT_SEMAPHORE, 1);
+ if (fw)
+ release_firmware(fw);
- if (i == 200) {
+ if (rc) {
ERR("%s: firmware loading failed\n", priv->ndev->name);
- DBG("VPC = 0x%x VIC = 0x%x INIT_STATUS = 0x%x i=%d\n",
- READ_REG(priv, regVPC),
- READ_REG(priv, regVIC), READ_REG(priv, regINIT_STATUS), i);
- RET(-EIO);
+ if (rc == -EIO)
+ DBG("VPC = 0x%x VIC = 0x%x INIT_STATUS = 0x%x i=%d\n",
+ READ_REG(priv, regVPC),
+ READ_REG(priv, regVIC),
+ READ_REG(priv, regINIT_STATUS), i);
+ RET(rc);
} else {
DBG("%s: firmware loading success\n", priv->ndev->name);
RET(0);
@@ -617,13 +629,6 @@ err:
RET(rc);
}
-static void __init bdx_firmware_endianess(void)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(s_firmLoad); i++)
- s_firmLoad[i] = CPU_CHIP_SWAP32(s_firmLoad[i]);
-}
-
static int bdx_range_check(struct bdx_priv *priv, u32 offset)
{
return (offset > (u32) (BDX_REGS_SIZE / priv->nic->port_num)) ?
@@ -2501,7 +2506,6 @@ static void __init print_driver_id(void)
static int __init bdx_module_init(void)
{
ENTER;
- bdx_firmware_endianess();
init_txd_sizes();
print_driver_id();
RET(pci_register_driver(&bdx_pci_driver));
@@ -2521,3 +2525,4 @@ module_exit(bdx_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(BDX_DRV_DESC);
+MODULE_FIRMWARE("tehuti/firmware.bin");
diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h
index efaf84d9757d..dec67e0a9ca2 100644
--- a/drivers/net/tehuti.h
+++ b/drivers/net/tehuti.h
@@ -29,6 +29,7 @@
#include <linux/if_vlan.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
+#include <linux/firmware.h>
#include <asm/byteorder.h>
/* Compile Time Switches */
diff --git a/drivers/net/tehuti_fw.h b/drivers/net/tehuti_fw.h
deleted file mode 100644
index 2c603a8a4383..000000000000
--- a/drivers/net/tehuti_fw.h
+++ /dev/null
@@ -1,10712 +0,0 @@
-/*
- * Tehuti Networks(R) Network Driver
- * Copyright (C) 2007 Tehuti Networks Ltd. All rights reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-/* Loading Firmware */
-/* INT_MEM Ver */
-static u32 s_firmLoad[] = {
- 0x000f0002,
- 0x40718000,
- 0x0000002d,
- 0xc0000000,
- 0x000f0002,
- 0x00718001,
- 0x0000002d,
- 0xc0800000,
- 0x000f0002,
- 0x00718002,
- 0x0000002d,
- 0xc1000000,
- 0x000f0002,
- 0x00718003,
- 0x0000002d,
- 0xc1800000,
- 0x000f0002,
- 0x00718004,
- 0x0000002d,
- 0xc2000000,
- 0x000f0002,
- 0x00718005,
- 0x0000002d,
- 0xc2800000,
- 0x000f0002,
- 0x00718006,
- 0x0000002d,
- 0xc3000000,
- 0x000f0002,
- 0x00718007,
- 0x0000002d,
- 0xc3800000,
- 0x000f0002,
- 0x00718008,
- 0x0000002d,
- 0xc4000000,
- 0x000f0002,
- 0x00718009,
- 0x0000002d,
- 0xc4800000,
- 0x000f0002,
- 0x0071800a,
- 0x0000002d,
- 0xc5000000,
- 0x000f0002,
- 0x0071800b,
- 0x0000002d,
- 0xc5800000,
- 0x000f0002,
- 0x0071800c,
- 0x0000002d,
- 0xc6000000,
- 0x000f0002,
- 0x0071800d,
- 0x0000002d,
- 0xc6800000,
- 0x000f0002,
- 0x0071800e,
- 0x0000002d,
- 0xc7000000,
- 0x000f0002,
- 0x0071800f,
- 0x0000002d,
- 0xc7800000,
- 0x000f0002,
- 0x00718010,
- 0x0000002d,
- 0xc8000000,
- 0x000f0002,
- 0x00718011,
- 0x0000002d,
- 0xc8800000,
- 0x000f0002,
- 0x00718012,
- 0x0000002d,
- 0xc9000000,
- 0x000f0002,
- 0x00718013,
- 0x0000002d,
- 0xc9800000,
- 0x000f0002,
- 0x00718014,
- 0x0000002d,
- 0xca000000,
- 0x000f0002,
- 0x00718015,
- 0x0000002d,
- 0xca800000,
- 0x000f0002,
- 0x00718016,
- 0x0000002d,
- 0xcb000000,
- 0x000f0002,
- 0x00718017,
- 0x0000002d,
- 0xcb800000,
- 0x000f0002,
- 0x00718018,
- 0x0000002d,
- 0xcc000000,
- 0x000f0002,
- 0x00718019,
- 0x0000002d,
- 0xcc800000,
- 0x000f0002,
- 0x0071801a,
- 0x0000002d,
- 0xcd000000,
- 0x000f0002,
- 0x0071801b,
- 0x0000002d,
- 0xcd800000,
- 0x000f0002,
- 0x0071801c,
- 0x0000002d,
- 0xce000000,
- 0x000f0002,
- 0x0071801d,
- 0x0000002d,
- 0xce800000,
- 0x000f0002,
- 0x0071801e,
- 0x0000002d,
- 0xcf000000,
- 0x000f0002,
- 0x0071801f,
- 0x0000002d,
- 0xcf800000,
- 0x000f0002,
- 0x00718020,
- 0x0000002d,
- 0xd0000000,
- 0x000f0002,
- 0x00718021,
- 0x0000002d,
- 0xd0800000,
- 0x000f0002,
- 0x00718022,
- 0x0000002d,
- 0xd1000000,
- 0x000f0002,
- 0x00718023,
- 0x0000002d,
- 0xd1800000,
- 0x000f0002,
- 0x00718024,
- 0x0000002d,
- 0xd2000000,
- 0x000f0002,
- 0x00718025,
- 0x0000002d,
- 0xd2800000,
- 0x000f0002,
- 0x00718026,
- 0x0000002d,
- 0xd3000000,
- 0x000f0002,
- 0x00718027,
- 0x0000002d,
- 0xd3800000,
- 0x000f0002,
- 0x00718028,
- 0x0000002d,
- 0xd4000000,
- 0x000f0002,
- 0x00718029,
- 0x0000002d,
- 0xd4800000,
- 0x000f0002,
- 0x0071802a,
- 0x0000002d,
- 0xd5000000,
- 0x000f0002,
- 0x0071802b,
- 0x0000002d,
- 0xd5800000,
- 0x000f0002,
- 0x0071802c,
- 0x0000002d,
- 0xd6000000,
- 0x000f0002,
- 0x0071802d,
- 0x0000002d,
- 0xd6800000,
- 0x000f0002,
- 0x0071802e,
- 0x0000002d,
- 0xd7000000,
- 0x000f0002,
- 0x0071802f,
- 0x0000002d,
- 0xd7800000,
- 0x000f0002,
- 0x00718030,
- 0x0000002d,
- 0xd8000000,
- 0x000f0002,
- 0x00718031,
- 0x0000002d,
- 0xd8800000,
- 0x000f0002,
- 0x00718032,
- 0x0000002d,
- 0xd9000000,
- 0x000f0002,
- 0x00718033,
- 0x0000002d,
- 0xd9800000,
- 0x000f0002,
- 0x00718034,
- 0x0000002d,
- 0xda000000,
- 0x000f0002,
- 0x00718035,
- 0x0000002d,
- 0xda800000,
- 0x000f0002,
- 0x00718036,
- 0x0000002d,
- 0xdb000000,
- 0x000f0002,
- 0x00718037,
- 0x0000002d,
- 0xdb800000,
- 0x000f0002,
- 0x00718038,
- 0x0000007b,
- 0xdd608000,
- 0x000f0002,
- 0x00718039,
- 0x0000002d,
- 0xdd000000,
- 0x000f0002,
- 0x0071803a,
- 0x0000002d,
- 0xdb800000,
- 0x000f0002,
- 0x0071803b,
- 0x0000002d,
- 0xdd000000,
- 0x000f0002,
- 0x0071803c,
- 0x0000002d,
- 0xdd000000,
- 0x000f0002,
- 0x0071803d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718040,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718041,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718042,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718043,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718044,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718045,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718046,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718047,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718048,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718049,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718050,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718051,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718052,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718053,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718054,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718055,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718056,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718057,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718058,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718059,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718060,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718061,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718062,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718063,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718064,
- 0x0000002d,
- 0xdb000000,
- 0x000f0002,
- 0x00718065,
- 0x0000003f,
- 0xdd000104,
- 0x000f0002,
- 0x00718066,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718067,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718068,
- 0x0000003f,
- 0xdd000804,
- 0x000f0002,
- 0x00718069,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071806a,
- 0x0000003f,
- 0xdd003004,
- 0x000f0002,
- 0x0071806b,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071806c,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071806d,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x0071806e,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071806f,
- 0x0000003f,
- 0xdd003d04,
- 0x000f0002,
- 0x00718070,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718071,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718072,
- 0x0000003f,
- 0xdd000704,
- 0x000f0002,
- 0x00718073,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718074,
- 0x0000003f,
- 0xdd002884,
- 0x000f0002,
- 0x00718075,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718076,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718077,
- 0x0000003f,
- 0xdd003704,
- 0x000f0002,
- 0x00718078,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718079,
- 0x0000003f,
- 0xdd002904,
- 0x000f0002,
- 0x0071807a,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071807b,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071807c,
- 0x0000003f,
- 0xdd04aa04,
- 0x000f0002,
- 0x0071807d,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071807e,
- 0x0000003f,
- 0xdd002804,
- 0x000f0002,
- 0x0071807f,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718080,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718081,
- 0x0000003f,
- 0xdd003104,
- 0x000f0002,
- 0x00718082,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718083,
- 0x0000003f,
- 0xdd002b84,
- 0x000f0002,
- 0x00718084,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718085,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718086,
- 0x0000003f,
- 0xdd01e404,
- 0x000f0002,
- 0x00718087,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718088,
- 0x0000003f,
- 0xd7800084,
- 0x000f0002,
- 0x00718089,
- 0x0000003f,
- 0xd7980001,
- 0x000f0002,
- 0x0071808a,
- 0x00000059,
- 0xd78037ef,
- 0x000f0002,
- 0x0071808b,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071808c,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071808d,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071808e,
- 0x0000002d,
- 0xd7d6027f,
- 0x000f0002,
- 0x0071808f,
- 0x00000018,
- 0x17ff0081,
- 0x000f0002,
- 0x00718090,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718091,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718092,
- 0x0000002d,
- 0xd7d800b8,
- 0x000f0002,
- 0x00718093,
- 0x00000018,
- 0x17eb0081,
- 0x000f0002,
- 0x00718094,
- 0x0000003f,
- 0xdd002904,
- 0x000f0002,
- 0x00718095,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718096,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718097,
- 0x0000003f,
- 0xdd04aa84,
- 0x000f0002,
- 0x00718098,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718099,
- 0x0000003f,
- 0xdd002b04,
- 0x000f0002,
- 0x0071809a,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071809b,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071809c,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x0071809d,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071809e,
- 0x0000003f,
- 0xdd002984,
- 0x000f0002,
- 0x0071809f,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180a0,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180a1,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x007180a2,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180a3,
- 0x0000003f,
- 0xdd002a04,
- 0x000f0002,
- 0x007180a4,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180a5,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180a6,
- 0x0000003f,
- 0xdd009184,
- 0x000f0002,
- 0x007180a7,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180a8,
- 0x0000003f,
- 0xd6801984,
- 0x000f0002,
- 0x007180a9,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007180aa,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007180ab,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007180ac,
- 0x0000003f,
- 0xdd002b04,
- 0x000f0002,
- 0x007180ad,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180ae,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180af,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x007180b0,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180b1,
- 0x0000003f,
- 0xdd002a84,
- 0x000f0002,
- 0x007180b2,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180b3,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180b4,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x007180b5,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180b6,
- 0x0000003f,
- 0xd6800c84,
- 0x000f0002,
- 0x007180b7,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007180b8,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007180b9,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007180ba,
- 0x0000003f,
- 0xdd002a84,
- 0x000f0002,
- 0x007180bb,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180bc,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180bd,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x007180be,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180bf,
- 0x0000003f,
- 0xd6800f84,
- 0x000f0002,
- 0x007180c0,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007180c1,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007180c2,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007180c3,
- 0x0000003f,
- 0xdd002a04,
- 0x000f0002,
- 0x007180c4,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180c5,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180c6,
- 0x0000003f,
- 0xdd001184,
- 0x000f0002,
- 0x007180c7,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180c8,
- 0x0000003f,
- 0xdd002884,
- 0x000f0002,
- 0x007180c9,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180ca,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180cb,
- 0x0000003f,
- 0xdd003784,
- 0x000f0002,
- 0x007180cc,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180cd,
- 0x0000002d,
- 0xd3800000,
- 0x000f0002,
- 0x007180ce,
- 0x0000003f,
- 0xd2003780,
- 0x000f0002,
- 0x007180cf,
- 0x0000003f,
- 0xd1800404,
- 0x000f0002,
- 0x007180d0,
- 0x0000003f,
- 0xd1840001,
- 0x000f0002,
- 0x007180d1,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180d2,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180d3,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180d4,
- 0x0000003f,
- 0xd17fff84,
- 0x000f0002,
- 0x007180d5,
- 0x0000003f,
- 0xd17fff81,
- 0x000f0002,
- 0x007180d6,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180d7,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180d8,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180d9,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180da,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180db,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007180dc,
- 0x0000003f,
- 0xd6800784,
- 0x000f0002,
- 0x007180dd,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007180de,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007180df,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007180e0,
- 0x00000049,
- 0xdd003b63,
- 0x000f0002,
- 0x007180e1,
- 0x00000059,
- 0xdd003b76,
- 0x000f0002,
- 0x007180e2,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180e3,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180e4,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180e5,
- 0x0000002d,
- 0xdd06027f,
- 0x000f0002,
- 0x007180e6,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x007180e7,
- 0x00000045,
- 0xdd003139,
- 0x000f0002,
- 0x007180e8,
- 0x00000094,
- 0x000b313b,
- 0x000f0002,
- 0x007180e9,
- 0x00000094,
- 0x0009313d,
- 0x000f0002,
- 0x007180ea,
- 0x00000094,
- 0x0007313f,
- 0x000f0002,
- 0x007180eb,
- 0x00000094,
- 0x00053b76,
- 0x000f0002,
- 0x007180ec,
- 0x00000009,
- 0xc1ed3d7a,
- 0x000f0002,
- 0x007180ed,
- 0x0000003f,
- 0xd200b780,
- 0x000f0002,
- 0x007180ee,
- 0x0000003f,
- 0xdd002884,
- 0x000f0002,
- 0x007180ef,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007180f0,
- 0x00000069,
- 0xdd003264,
- 0x000f0002,
- 0x007180f1,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007180f2,
- 0x0000003f,
- 0xd6800784,
- 0x000f0002,
- 0x007180f3,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007180f4,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007180f5,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007180f6,
- 0x00000049,
- 0xdd003b63,
- 0x000f0002,
- 0x007180f7,
- 0x00000059,
- 0xdd003b76,
- 0x000f0002,
- 0x007180f8,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180f9,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180fa,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180fb,
- 0x0000002d,
- 0xdd06027f,
- 0x000f0002,
- 0x007180fc,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x007180fd,
- 0x00000045,
- 0xdd00313a,
- 0x000f0002,
- 0x007180fe,
- 0x00000018,
- 0x1d2d3b76,
- 0x000f0002,
- 0x007180ff,
- 0x00000045,
- 0xdd00313c,
- 0x000f0002,
- 0x00718100,
- 0x00000018,
- 0x1d133b76,
- 0x000f0002,
- 0x00718101,
- 0x00000045,
- 0xdd00313e,
- 0x000f0002,
- 0x00718102,
- 0x00000018,
- 0x1d1b3b76,
- 0x000f0002,
- 0x00718103,
- 0x0000003f,
- 0xdd003004,
- 0x000f0002,
- 0x00718104,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718105,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718106,
- 0x0000003f,
- 0xdd000104,
- 0x000f0002,
- 0x00718107,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718108,
- 0x00000009,
- 0xc52d3d7a,
- 0x000f0002,
- 0x00718109,
- 0x00000029,
- 0xd2010064,
- 0x000f0002,
- 0x0071810a,
- 0x0000003f,
- 0xdd002884,
- 0x000f0002,
- 0x0071810b,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071810c,
- 0x00000069,
- 0xdd003264,
- 0x000f0002,
- 0x0071810d,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071810e,
- 0x00000009,
- 0xc2293d7a,
- 0x000f0002,
- 0x0071810f,
- 0x00000029,
- 0xd2000064,
- 0x000f0002,
- 0x00718110,
- 0x0000003f,
- 0xdd002884,
- 0x000f0002,
- 0x00718111,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718112,
- 0x00000069,
- 0xdd003264,
- 0x000f0002,
- 0x00718113,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718114,
- 0x00000049,
- 0xdd003b63,
- 0x000f0002,
- 0x00718115,
- 0x00000059,
- 0xdd003b76,
- 0x000f0002,
- 0x00718116,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718117,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718118,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718119,
- 0x0000002d,
- 0xdd06027f,
- 0x000f0002,
- 0x0071811a,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x0071811b,
- 0x00000045,
- 0xdd00313a,
- 0x000f0002,
- 0x0071811c,
- 0x00000018,
- 0x1d0f3b76,
- 0x000f0002,
- 0x0071811d,
- 0x0000003f,
- 0xdd003004,
- 0x000f0002,
- 0x0071811e,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071811f,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718120,
- 0x0000003f,
- 0xdd000104,
- 0x000f0002,
- 0x00718121,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718122,
- 0x00000009,
- 0xc52d3d7a,
- 0x000f0002,
- 0x00718123,
- 0x0000002d,
- 0xd1080082,
- 0x000f0002,
- 0x00718124,
- 0x00000008,
- 0x23c33d7a,
- 0x000f0002,
- 0x00718125,
- 0x00000049,
- 0xd6003b0a,
- 0x000f0002,
- 0x00718126,
- 0x0000003f,
- 0xd3000004,
- 0x000f0002,
- 0x00718127,
- 0x0000003f,
- 0xd3040001,
- 0x000f0002,
- 0x00718128,
- 0x0000002f,
- 0xd6814085,
- 0x000f0002,
- 0x00718129,
- 0x0000003f,
- 0xd4ffff84,
- 0x000f0002,
- 0x0071812a,
- 0x0000003f,
- 0xd4800781,
- 0x000f0002,
- 0x0071812b,
- 0x0000003f,
- 0xd1ffff84,
- 0x000f0002,
- 0x0071812c,
- 0x0000003f,
- 0xd1800001,
- 0x000f0002,
- 0x0071812d,
- 0x00000049,
- 0xdd003666,
- 0x000f0002,
- 0x0071812e,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x0071812f,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x00718130,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x00718131,
- 0x00000069,
- 0xdd003b69,
- 0x000f0002,
- 0x00718132,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x00718133,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x00718134,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x00718135,
- 0x00000069,
- 0xdd003b69,
- 0x000f0002,
- 0x00718136,
- 0x00000061,
- 0xf600046c,
- 0x000f0002,
- 0x00718137,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x00718138,
- 0x00000018,
- 0x3d6b0081,
- 0x000f0002,
- 0x00718139,
- 0x00000049,
- 0xd600058b,
- 0x000f0002,
- 0x0071813a,
- 0x0000002f,
- 0xd6810106,
- 0x000f0002,
- 0x0071813b,
- 0x0000002d,
- 0xd2000000,
- 0x000f0002,
- 0x0071813c,
- 0x00000021,
- 0xd20000e4,
- 0x000f0002,
- 0x0071813d,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071813e,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x0071813f,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x00718140,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x00718141,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718142,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718143,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x00718144,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x00718145,
- 0x0000002d,
- 0xd1000000,
- 0x000f0002,
- 0x00718146,
- 0x00000049,
- 0xd17a33e4,
- 0x000f0002,
- 0x00718147,
- 0x0000002f,
- 0xd1710162,
- 0x000f0002,
- 0x00718148,
- 0x0000002f,
- 0xd1610162,
- 0x000f0002,
- 0x00718149,
- 0x00000049,
- 0xd14033e3,
- 0x000f0002,
- 0x0071814a,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071814b,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x0071814c,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x0071814d,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x0071814e,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x0071814f,
- 0x00000069,
- 0xd8003162,
- 0x000f0002,
- 0x00718150,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x00718151,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x00718152,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718153,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x00718154,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x00718155,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x00718156,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718157,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718158,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x00718159,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x0071815a,
- 0x0000002d,
- 0xd1000000,
- 0x000f0002,
- 0x0071815b,
- 0x0000002d,
- 0xd16c07e4,
- 0x000f0002,
- 0x0071815c,
- 0x00000049,
- 0xd14033e3,
- 0x000f0002,
- 0x0071815d,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071815e,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x0071815f,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x00718160,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x00718161,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718162,
- 0x00000069,
- 0xd8003162,
- 0x000f0002,
- 0x00718163,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x00718164,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x00718165,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718166,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x00718167,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x00718168,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x00718169,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x0071816a,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x0071816b,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x0071816c,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x0071816d,
- 0x0000002d,
- 0xd1000000,
- 0x000f0002,
- 0x0071816e,
- 0x00000049,
- 0xd17833e4,
- 0x000f0002,
- 0x0071816f,
- 0x0000002f,
- 0xd1710162,
- 0x000f0002,
- 0x00718170,
- 0x0000002f,
- 0xd1610162,
- 0x000f0002,
- 0x00718171,
- 0x00000049,
- 0xd14033e3,
- 0x000f0002,
- 0x00718172,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718173,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x00718174,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x00718175,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x00718176,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718177,
- 0x00000069,
- 0xd8003162,
- 0x000f0002,
- 0x00718178,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x00718179,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x0071817a,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x0071817b,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x0071817c,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x0071817d,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x0071817e,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x0071817f,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x00718180,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x00718181,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x00718182,
- 0x0000002d,
- 0xd1000000,
- 0x000f0002,
- 0x00718183,
- 0x0000002d,
- 0xd16807e4,
- 0x000f0002,
- 0x00718184,
- 0x00000049,
- 0xd14033e3,
- 0x000f0002,
- 0x00718185,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718186,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x00718187,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x00718188,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x00718189,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x0071818a,
- 0x00000069,
- 0xd8003162,
- 0x000f0002,
- 0x0071818b,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x0071818c,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x0071818d,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x0071818e,
- 0x00000008,
- 0x22790081,
- 0x000f0002,
- 0x0071818f,
- 0x00000049,
- 0xd600060c,
- 0x000f0002,
- 0x00718190,
- 0x0000002f,
- 0xd6810106,
- 0x000f0002,
- 0x00718191,
- 0x0000003f,
- 0xd4800002,
- 0x000f0002,
- 0x00718192,
- 0x0000003f,
- 0xd4800084,
- 0x000f0002,
- 0x00718193,
- 0x0000003f,
- 0xd5000102,
- 0x000f0002,
- 0x00718194,
- 0x0000003f,
- 0xd5000184,
- 0x000f0002,
- 0x00718195,
- 0x0000003f,
- 0xd5800202,
- 0x000f0002,
- 0x00718196,
- 0x0000003f,
- 0xd5800204,
- 0x000f0002,
- 0x00718197,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718198,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x00718199,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x0071819a,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x0071819b,
- 0x00000069,
- 0xd80034e9,
- 0x000f0002,
- 0x0071819c,
- 0x00000069,
- 0xd800356a,
- 0x000f0002,
- 0x0071819d,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x0071819e,
- 0x00000031,
- 0xd600016c,
- 0x000f0002,
- 0x0071819f,
- 0x00000041,
- 0xd48034eb,
- 0x000f0002,
- 0x007181a0,
- 0x00000041,
- 0xd500356b,
- 0x000f0002,
- 0x007181a1,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007181a2,
- 0x00000018,
- 0x37eb0081,
- 0x000f0002,
- 0x007181a3,
- 0x00000049,
- 0xd6003b0d,
- 0x000f0002,
- 0x007181a4,
- 0x00000049,
- 0xd6803b07,
- 0x000f0002,
- 0x007181a5,
- 0x0000002d,
- 0xd1000000,
- 0x000f0002,
- 0x007181a6,
- 0x00000049,
- 0xdd003666,
- 0x000f0002,
- 0x007181a7,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181a8,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181a9,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181aa,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181ab,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181ac,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181ad,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181ae,
- 0x00000069,
- 0xdd003b76,
- 0x000f0002,
- 0x007181af,
- 0x00000061,
- 0xf600046c,
- 0x000f0002,
- 0x007181b0,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007181b1,
- 0x00000018,
- 0x37eb0081,
- 0x000f0002,
- 0x007181b2,
- 0x00000049,
- 0xd6003b0e,
- 0x000f0002,
- 0x007181b3,
- 0x00000049,
- 0xd6803b08,
- 0x000f0002,
- 0x007181b4,
- 0x00000049,
- 0xd5803b09,
- 0x000f0002,
- 0x007181b5,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181b6,
- 0x0000002d,
- 0xdd06017f,
- 0x000f0002,
- 0x007181b7,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x007181b8,
- 0x00000049,
- 0xd800366c,
- 0x000f0002,
- 0x007181b9,
- 0x00000069,
- 0xd80035eb,
- 0x000f0002,
- 0x007181ba,
- 0x00000069,
- 0xd80033e7,
- 0x000f0002,
- 0x007181bb,
- 0x00000069,
- 0xd80037ef,
- 0x000f0002,
- 0x007181bc,
- 0x00000041,
- 0xd60007ec,
- 0x000f0002,
- 0x007181bd,
- 0x00000041,
- 0xd580086b,
- 0x000f0002,
- 0x007181be,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007181bf,
- 0x00000018,
- 0x37ed0081,
- 0x000f0002,
- 0x007181c0,
- 0x0000003f,
- 0xd4ffff80,
- 0x000f0002,
- 0x007181c1,
- 0x0000003f,
- 0xd5020004,
- 0x000f0002,
- 0x007181c2,
- 0x0000003f,
- 0xd5180001,
- 0x000f0002,
- 0x007181c3,
- 0x00000049,
- 0xdd003b6a,
- 0x000f0002,
- 0x007181c4,
- 0x00000069,
- 0xdd003b69,
- 0x000f0002,
- 0x007181c5,
- 0x00000069,
- 0xdd003b69,
- 0x000f0002,
- 0x007181c6,
- 0x00000021,
- 0xd50000ea,
- 0x000f0002,
- 0x007181c7,
- 0x00000049,
- 0xdd0e3b6a,
- 0x000f0002,
- 0x007181c8,
- 0x00000035,
- 0xd104007a,
- 0x000f0002,
- 0x007181c9,
- 0x00000018,
- 0x37f50081,
- 0x000f0002,
- 0x007181ca,
- 0x0000003f,
- 0xd4ffff80,
- 0x000f0002,
- 0x007181cb,
- 0x0000003f,
- 0xd5040004,
- 0x000f0002,
- 0x007181cc,
- 0x0000003f,
- 0xd5180001,
- 0x000f0002,
- 0x007181cd,
- 0x00000069,
- 0xdd003b69,
- 0x000f0002,
- 0x007181ce,
- 0x00000069,
- 0xdd003b69,
- 0x000f0002,
- 0x007181cf,
- 0x00000049,
- 0xdd003b6a,
- 0x000f0002,
- 0x007181d0,
- 0x00000051,
- 0xf50000ea,
- 0x000f0002,
- 0x007181d1,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181d2,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181d3,
- 0x00000049,
- 0xdd0e3b6a,
- 0x000f0002,
- 0x007181d4,
- 0x00000035,
- 0xd104807a,
- 0x000f0002,
- 0x007181d5,
- 0x00000018,
- 0x37f50081,
- 0x000f0002,
- 0x007181d6,
- 0x0000003f,
- 0xc77f7f04,
- 0x000f0002,
- 0x007181d7,
- 0x0000003f,
- 0xc77f7f01,
- 0x000f0002,
- 0x007181d8,
- 0x0000003f,
- 0xd6804000,
- 0x000f0002,
- 0x007181d9,
- 0x0000003f,
- 0xd103c000,
- 0x000f0002,
- 0x007181da,
- 0x00000025,
- 0xde2000e2,
- 0x000f0002,
- 0x007181db,
- 0x00000049,
- 0xde80274e,
- 0x000f0002,
- 0x007181dc,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181dd,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181de,
- 0x00000035,
- 0xd10000e2,
- 0x000f0002,
- 0x007181df,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007181e0,
- 0x00000018,
- 0x37f50081,
- 0x000f0002,
- 0x007181e1,
- 0x0000003f,
- 0xdd003004,
- 0x000f0002,
- 0x007181e2,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007181e3,
- 0x00000069,
- 0xdd001d3a,
- 0x000f0002,
- 0x007181e4,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007181e5,
- 0x0000007d,
- 0xc760a713,
- 0x000f0002,
- 0x007181e6,
- 0x00000031,
- 0xc0800041,
- 0x000f0002,
- 0x007181e7,
- 0x00000031,
- 0xc4000048,
- 0x000f0002,
- 0x007181e8,
- 0x00000031,
- 0xc2800045,
- 0x000f0002,
- 0x007181e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f4,
- 0x0000002d,
- 0xdb000000,
- 0x000f0002,
- 0x007181f5,
- 0x0000003f,
- 0xdd003004,
- 0x000f0002,
- 0x007181f6,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007181f7,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007181f8,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x007181f9,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007181fa,
- 0x0000002d,
- 0xd3800000,
- 0x000f0002,
- 0x007181fb,
- 0x0000003f,
- 0xdd000404,
- 0x000f0002,
- 0x007181fc,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007181fd,
- 0x00000069,
- 0xdd000a14,
- 0x000f0002,
- 0x007181fe,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x007181ff,
- 0x00000049,
- 0xd1043394,
- 0x000f0002,
- 0x00718200,
- 0x0000003f,
- 0xdd000484,
- 0x000f0002,
- 0x00718201,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718202,
- 0x00000069,
- 0xdd003162,
- 0x000f0002,
- 0x00718203,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718204,
- 0x0000003f,
- 0xdd000504,
- 0x000f0002,
- 0x00718205,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718206,
- 0x00000069,
- 0xdd000a95,
- 0x000f0002,
- 0x00718207,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718208,
- 0x00000049,
- 0xd1043395,
- 0x000f0002,
- 0x00718209,
- 0x0000003f,
- 0xdd000584,
- 0x000f0002,
- 0x0071820a,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071820b,
- 0x00000069,
- 0xdd003162,
- 0x000f0002,
- 0x0071820c,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071820d,
- 0x0000003f,
- 0xdd000604,
- 0x000f0002,
- 0x0071820e,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071820f,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718210,
- 0x0000003f,
- 0xdd000084,
- 0x000f0002,
- 0x00718211,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718212,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718213,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718214,
- 0x00000069,
- 0xdd000b16,
- 0x000f0002,
- 0x00718215,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718216,
- 0x0000003f,
- 0xdd001004,
- 0x000f0002,
- 0x00718217,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718218,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718219,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x0071821a,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071821b,
- 0x0000003f,
- 0xdd001084,
- 0x000f0002,
- 0x0071821c,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071821d,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071821e,
- 0x0000003f,
- 0xdd018004,
- 0x000f0002,
- 0x0071821f,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718220,
- 0x0000003f,
- 0xdd001104,
- 0x000f0002,
- 0x00718221,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718222,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718223,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718224,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718225,
- 0x0000003f,
- 0xdd001184,
- 0x000f0002,
- 0x00718226,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718227,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718228,
- 0x0000003f,
- 0xdd160004,
- 0x000f0002,
- 0x00718229,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071822a,
- 0x0000003f,
- 0xdd001204,
- 0x000f0002,
- 0x0071822b,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071822c,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071822d,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x0071822e,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071822f,
- 0x0000003f,
- 0xdd001284,
- 0x000f0002,
- 0x00718230,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718231,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718232,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718233,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718234,
- 0x0000003f,
- 0xdd001304,
- 0x000f0002,
- 0x00718235,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718236,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718237,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718238,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718239,
- 0x0000003f,
- 0xdd001384,
- 0x000f0002,
- 0x0071823a,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071823b,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071823c,
- 0x0000003f,
- 0xdd050004,
- 0x000f0002,
- 0x0071823d,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071823e,
- 0x0000003f,
- 0xdd002004,
- 0x000f0002,
- 0x0071823f,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718240,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718241,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718242,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718243,
- 0x0000003f,
- 0xdd002084,
- 0x000f0002,
- 0x00718244,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718245,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718246,
- 0x0000003f,
- 0xdd019004,
- 0x000f0002,
- 0x00718247,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718248,
- 0x0000003f,
- 0xdd002104,
- 0x000f0002,
- 0x00718249,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071824a,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071824b,
- 0x0000003f,
- 0xdd000084,
- 0x000f0002,
- 0x0071824c,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071824d,
- 0x0000003f,
- 0xdd002184,
- 0x000f0002,
- 0x0071824e,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071824f,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718250,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718251,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718252,
- 0x0000003f,
- 0xdd002204,
- 0x000f0002,
- 0x00718253,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718254,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718255,
- 0x0000003f,
- 0xdd000284,
- 0x000f0002,
- 0x00718256,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718257,
- 0x0000003f,
- 0xdd002284,
- 0x000f0002,
- 0x00718258,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718259,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071825a,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x0071825b,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071825c,
- 0x0000003f,
- 0xdd002304,
- 0x000f0002,
- 0x0071825d,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071825e,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071825f,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718260,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718261,
- 0x0000003f,
- 0xdd001804,
- 0x000f0002,
- 0x00718262,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718263,
- 0x00000069,
- 0xdd000b97,
- 0x000f0002,
- 0x00718264,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718265,
- 0x00000049,
- 0xd1043397,
- 0x000f0002,
- 0x00718266,
- 0x0000003f,
- 0xdd001884,
- 0x000f0002,
- 0x00718267,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718268,
- 0x00000069,
- 0xdd003162,
- 0x000f0002,
- 0x00718269,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071826a,
- 0x0000003f,
- 0xdd001904,
- 0x000f0002,
- 0x0071826b,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071826c,
- 0x00000069,
- 0xdd000c18,
- 0x000f0002,
- 0x0071826d,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071826e,
- 0x00000049,
- 0xd1043398,
- 0x000f0002,
- 0x0071826f,
- 0x0000003f,
- 0xdd001984,
- 0x000f0002,
- 0x00718270,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718271,
- 0x00000069,
- 0xdd003162,
- 0x000f0002,
- 0x00718272,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718273,
- 0x0000003f,
- 0xdd001a04,
- 0x000f0002,
- 0x00718274,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718275,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718276,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x00718277,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718278,
- 0x0000003f,
- 0xdd001a84,
- 0x000f0002,
- 0x00718279,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071827a,
- 0x00000069,
- 0xdd000b16,
- 0x000f0002,
- 0x0071827b,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071827c,
- 0x0000003f,
- 0xdd001c04,
- 0x000f0002,
- 0x0071827d,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071827e,
- 0x00000069,
- 0xdd000c99,
- 0x000f0002,
- 0x0071827f,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718280,
- 0x0000003f,
- 0xdd001c84,
- 0x000f0002,
- 0x00718281,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718282,
- 0x00000069,
- 0xdd000d1a,
- 0x000f0002,
- 0x00718283,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718284,
- 0x0000003f,
- 0xdd001d04,
- 0x000f0002,
- 0x00718285,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718286,
- 0x00000069,
- 0xdd000d9b,
- 0x000f0002,
- 0x00718287,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718288,
- 0x00000049,
- 0xd104339b,
- 0x000f0002,
- 0x00718289,
- 0x0000003f,
- 0xdd001d84,
- 0x000f0002,
- 0x0071828a,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071828b,
- 0x00000069,
- 0xdd003162,
- 0x000f0002,
- 0x0071828c,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x0071828d,
- 0x0000003f,
- 0xdd001e04,
- 0x000f0002,
- 0x0071828e,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071828f,
- 0x00000069,
- 0xdd000e1c,
- 0x000f0002,
- 0x00718290,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718291,
- 0x0000003f,
- 0xdd000104,
- 0x000f0002,
- 0x00718292,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x00718293,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718294,
- 0x0000003f,
- 0xdd000f04,
- 0x000f0002,
- 0x00718295,
- 0x00000069,
- 0xdd003d7a,
- 0x000f0002,
- 0x00718296,
- 0x0000007d,
- 0xc760a713,
- 0x000f0002,
- 0x00718297,
- 0x00000031,
- 0xc0800041,
- 0x000f0002,
- 0x00718298,
- 0x00000031,
- 0xc4000048,
- 0x000f0002,
- 0x00718299,
- 0x00000031,
- 0xc2800045,
- 0x000f0002,
- 0x0071829a,
- 0x00000031,
- 0xd680006d,
-/* BRDX_INIT_SDRAM */
- 0x000f000f,
- 0x00700064,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000040,
- 0x00000100,
- 0x00000400,
- 0x00000064,
- 0x00000054,
- 0x00000000,
- 0x00002400,
- 0x00002800,
- 0x00000400,
- 0x00002880,
- 0x00000180,
- 0x00000003,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000051,
- 0x0000017d,
- 0x00000008,
- 0x00000051,
- 0x0000005d,
- 0x00000000,
- 0x00000009,
- 0x00005000,
- 0x00000000,
- 0x00000000,
-/* BRDX_INIT */
- 0x000f000f,
- 0x007001f4,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000040,
- 0x00000100,
- 0x00000400,
- 0x00000064,
- 0x00000054,
- 0x00000000,
- 0x00002400,
- 0x00002800,
- 0x00000400,
- 0x00002880,
- 0x00000180,
- 0x00000003,
- 0x00000000,
- 0x00000000,
- 0x00000000,
- 0x00000051,
- 0x0000017d,
- 0x00000008,
- 0x00000051,
- 0x0000005d,
- 0x00000000,
- 0x00000009,
- 0x00005000,
- 0x00000000,
- 0x00000000,
-/* ZERO_INIT */
- 0x000f0002,
- 0x00700000,
- 0x00000001,
- 0x00000000,
-/* ZERO_INIT */
- 0x000f0002,
- 0x00700000,
- 0x00000001,
- 0x00000000,
-/* Loading operational Firmware */
- 0x000f0002,
- 0x00718000,
- 0x00000025,
- 0xdd0e0002,
- 0x000f0002,
- 0x00718001,
- 0x00000004,
- 0x01d13b76,
- 0x000f0002,
- 0x00718002,
- 0x00000025,
- 0xdd0e0082,
- 0x000f0002,
- 0x00718003,
- 0x00000004,
- 0x02893b76,
- 0x000f0002,
- 0x00718004,
- 0x00000025,
- 0xdd0e0102,
- 0x000f0002,
- 0x00718005,
- 0x00000004,
- 0x02853b76,
- 0x000f0002,
- 0x00718006,
- 0x00000025,
- 0xdd0e0182,
- 0x000f0002,
- 0x00718007,
- 0x00000004,
- 0x03fd3b76,
- 0x000f0002,
- 0x00718008,
- 0x00000009,
- 0xcf813b76,
- 0x000f0002,
- 0x00718009,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071800a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071800b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071800c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071800d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071800e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071800f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718010,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718011,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718012,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718013,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718014,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718015,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718016,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718017,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718018,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718019,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071801a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071801b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071801c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071801d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071801e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071801f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718020,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718021,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718022,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718023,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718024,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718025,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718026,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718027,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718028,
- 0x00000049,
- 0xc0003b00,
- 0x000f0002,
- 0x00718029,
- 0x00000049,
- 0xc0803b02,
- 0x000f0002,
- 0x0071802a,
- 0x00000049,
- 0xc1003b03,
- 0x000f0002,
- 0x0071802b,
- 0x00000049,
- 0xc1803b04,
- 0x000f0002,
- 0x0071802c,
- 0x00000029,
- 0xdf600076,
- 0x000f0002,
- 0x0071802d,
- 0x00000049,
- 0xdf443b7d,
- 0x000f0002,
- 0x0071802e,
- 0x00000079,
- 0xfd609076,
- 0x000f0002,
- 0x0071802f,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718030,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718031,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718032,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718033,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718034,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718035,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718036,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718037,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718038,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718039,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071803f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718040,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718041,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718042,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718043,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718044,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718045,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718046,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718047,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718048,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718049,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071804f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718050,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718051,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718052,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718053,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718054,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718055,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718056,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718057,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718058,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718059,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071805f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718060,
- 0x0000003f,
- 0xdf000003,
- 0x000f0002,
- 0x00718061,
- 0x0000002d,
- 0xdde00f81,
- 0x000f0002,
- 0x00718062,
- 0x0000003f,
- 0xdd800283,
- 0x000f0002,
- 0x00718063,
- 0x0000002d,
- 0xdd040180,
- 0x000f0002,
- 0x00718064,
- 0x0000007d,
- 0xfd150080,
- 0x000f0002,
- 0x00718065,
- 0x0000007a,
- 0x10203b76,
- 0x000f0002,
- 0x00718066,
- 0x0000007a,
- 0x30207b76,
- 0x000f0002,
- 0x00718067,
- 0x00000021,
- 0xd0240060,
- 0x000f0002,
- 0x00718068,
- 0x0000003f,
- 0xdd000104,
- 0x000f0002,
- 0x00718069,
- 0x0000003f,
- 0xdd400281,
- 0x000f0002,
- 0x0071806a,
- 0x00000079,
- 0xdd31bb03,
- 0x000f0002,
- 0x0071806b,
- 0x00000079,
- 0xdd31fb04,
- 0x000f0002,
- 0x0071806c,
- 0x00000079,
- 0xdd31bb76,
- 0x000f0002,
- 0x0071806d,
- 0x00000079,
- 0xdd31fb76,
- 0x000f0002,
- 0x0071806e,
- 0x00000079,
- 0xfd210101,
- 0x000f0002,
- 0x0071806f,
- 0x0000007d,
- 0xfd2b4081,
- 0x000f0002,
- 0x00718070,
- 0x00000040,
- 0x3d003002,
- 0x000f0002,
- 0x00718071,
- 0x00000048,
- 0x1d003b02,
- 0x000f0002,
- 0x00718072,
- 0x00000079,
- 0xdd217b76,
- 0x000f0002,
- 0x00718073,
- 0x0000002d,
- 0xdd04057f,
- 0x000f0002,
- 0x00718074,
- 0x00000018,
- 0x3d7f3b76,
- 0x000f0002,
- 0x00718075,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718076,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718077,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718078,
- 0x00000021,
- 0xe3371f76,
- 0x000f0002,
- 0x00718079,
- 0x00000049,
- 0xdd003b79,
- 0x000f0002,
- 0x0071807a,
- 0x00000079,
- 0xdd21bb76,
- 0x000f0002,
- 0x0071807b,
- 0x00000049,
- 0xdd003b79,
- 0x000f0002,
- 0x0071807c,
- 0x00000079,
- 0xdd21bb76,
- 0x000f0002,
- 0x0071807d,
- 0x00000049,
- 0xdd003b79,
- 0x000f0002,
- 0x0071807e,
- 0x00000079,
- 0xdd21bb76,
- 0x000f0002,
- 0x0071807f,
- 0x00000079,
- 0xfd609076,
- 0x000f0002,
- 0x00718080,
- 0x00000079,
- 0xdd21fb76,
- 0x000f0002,
- 0x00718081,
- 0x0000003f,
- 0xdf000083,
- 0x000f0002,
- 0x00718082,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718083,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718084,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718085,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718086,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718087,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718088,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718089,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071808a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071808b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071808c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071808d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071808e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071808f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718090,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718091,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718092,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718093,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718094,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718095,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718096,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718097,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718098,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718099,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071809a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071809b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071809c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071809d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071809e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071809f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180a0,
- 0x0000002d,
- 0xd0080803,
- 0x000f0002,
- 0x007180a1,
- 0x00000008,
- 0x21b5fb76,
- 0x000f0002,
- 0x007180a2,
- 0x00000079,
- 0xdd010081,
- 0x000f0002,
- 0x007180a3,
- 0x00000079,
- 0xdd018102,
- 0x000f0002,
- 0x007180a4,
- 0x0000007d,
- 0xfd018083,
- 0x000f0002,
- 0x007180a5,
- 0x00000079,
- 0xd0903b76,
- 0x000f0002,
- 0x007180a6,
- 0x00000049,
- 0xd0583b7a,
- 0x000f0002,
- 0x007180a7,
- 0x00000049,
- 0xd2043b00,
- 0x000f0002,
- 0x007180a8,
- 0x0000003d,
- 0xdd400003,
- 0x000f0002,
- 0x007180a9,
- 0x00000024,
- 0x32000264,
- 0x000f0002,
- 0x007180aa,
- 0x0000003d,
- 0xdd7ff803,
- 0x000f0002,
- 0x007180ab,
- 0x00000029,
- 0xd020017a,
- 0x000f0002,
- 0x007180ac,
- 0x00000049,
- 0xd0a43b0e,
- 0x000f0002,
- 0x007180ad,
- 0x0000002d,
- 0xdd0442ff,
- 0x000f0002,
- 0x007180ae,
- 0x00000018,
- 0x3d7f3b76,
- 0x000f0002,
- 0x007180af,
- 0x0000002d,
- 0xdd060082,
- 0x000f0002,
- 0x007180b0,
- 0x00000038,
- 0x300001e0,
- 0x000f0002,
- 0x007180b1,
- 0x00000039,
- 0xd0000160,
- 0x000f0002,
- 0x007180b2,
- 0x00000079,
- 0xd1b13b7c,
- 0x000f0002,
- 0x007180b3,
- 0x0000002d,
- 0xdde00fe3,
- 0x000f0002,
- 0x007180b4,
- 0x00000049,
- 0xd08030e4,
- 0x000f0002,
- 0x007180b5,
- 0x00000079,
- 0xdd317b7c,
- 0x000f0002,
- 0x007180b6,
- 0x00000079,
- 0xdd313b7c,
- 0x000f0002,
- 0x007180b7,
- 0x0000007d,
- 0xfd374082,
- 0x000f0002,
- 0x007180b8,
- 0x00000008,
- 0x017d3b76,
- 0x000f0002,
- 0x007180b9,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180ba,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180bb,
- 0x00000049,
- 0xdd000387,
- 0x000f0002,
- 0x007180bc,
- 0x00000079,
- 0xdd310408,
- 0x000f0002,
- 0x007180bd,
- 0x00000079,
- 0xdd317d7a,
- 0x000f0002,
- 0x007180be,
- 0x00000049,
- 0xd3003b7c,
- 0x000f0002,
- 0x007180bf,
- 0x00000079,
- 0xd381bb7c,
- 0x000f0002,
- 0x007180c0,
- 0x0000007f,
- 0xd101b27c,
- 0x000f0002,
- 0x007180c1,
- 0x00000048,
- 0x51003264,
- 0x000f0002,
- 0x007180c2,
- 0x0000003d,
- 0xdd400003,
- 0x000f0002,
- 0x007180c3,
- 0x00000008,
- 0x01953162,
- 0x000f0002,
- 0x007180c4,
- 0x00000021,
- 0xd3000666,
- 0x000f0002,
- 0x007180c5,
- 0x00000020,
- 0x538000e7,
- 0x000f0002,
- 0x007180c6,
- 0x0000003f,
- 0xdd000800,
- 0x000f0002,
- 0x007180c7,
- 0x00000079,
- 0xdd01b366,
- 0x000f0002,
- 0x007180c8,
- 0x00000079,
- 0xdd01b3e7,
- 0x000f0002,
- 0x007180c9,
- 0x00000075,
- 0xf1018662,
- 0x000f0002,
- 0x007180ca,
- 0x00000075,
- 0xd201b164,
- 0x000f0002,
- 0x007180cb,
- 0x00000078,
- 0x1d007b76,
- 0x000f0002,
- 0x007180cc,
- 0x00000025,
- 0xdd0001e3,
- 0x000f0002,
- 0x007180cd,
- 0x00000008,
- 0x01b13162,
- 0x000f0002,
- 0x007180ce,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180cf,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180d0,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180d1,
- 0x00000021,
- 0xe3379f63,
- 0x000f0002,
- 0x007180d2,
- 0x00000049,
- 0xd3003b7c,
- 0x000f0002,
- 0x007180d3,
- 0x00000079,
- 0xd381bb7c,
- 0x000f0002,
- 0x007180d4,
- 0x0000007f,
- 0xd101b27c,
- 0x000f0002,
- 0x007180d5,
- 0x00000048,
- 0x51003264,
- 0x000f0002,
- 0x007180d6,
- 0x00000075,
- 0xd201b164,
- 0x000f0002,
- 0x007180d7,
- 0x00000078,
- 0x1d007b76,
- 0x000f0002,
- 0x007180d8,
- 0x0000003f,
- 0xdd000004,
- 0x000f0002,
- 0x007180d9,
- 0x00000079,
- 0xdd01c081,
- 0x000f0002,
- 0x007180da,
- 0x00000079,
- 0xfd609076,
- 0x000f0002,
- 0x007180db,
- 0x0000002d,
- 0xdd080803,
- 0x000f0002,
- 0x007180dc,
- 0x00000078,
- 0x3d01c081,
- 0x000f0002,
- 0x007180dd,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007180de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007180e8,
- 0x00000049,
- 0xd18e3b03,
- 0x000f0002,
- 0x007180e9,
- 0x0000002f,
- 0xd18100e3,
- 0x000f0002,
- 0x007180ea,
- 0x0000003f,
- 0xd1801803,
- 0x000f0002,
- 0x007180eb,
- 0x00000049,
- 0xd1043b03,
- 0x000f0002,
- 0x007180ec,
- 0x0000003f,
- 0xdd800203,
- 0x000f0002,
- 0x007180ed,
- 0x00000049,
- 0xd2043b02,
- 0x000f0002,
- 0x007180ee,
- 0x00000049,
- 0xd2843b00,
- 0x000f0002,
- 0x007180ef,
- 0x00000025,
- 0xdd0000e2,
- 0x000f0002,
- 0x007180f0,
- 0x00000094,
- 0x00134162,
- 0x000f0002,
- 0x007180f1,
- 0x00000094,
- 0x000b4362,
- 0x000f0002,
- 0x007180f2,
- 0x00000094,
- 0x001548e2,
- 0x000f0002,
- 0x007180f3,
- 0x00000094,
- 0x001b4962,
- 0x000f0002,
- 0x007180f4,
- 0x00000094,
- 0x002f4076,
- 0x000f0002,
- 0x007180f5,
- 0x00000009,
- 0xcf813d7a,
- 0x000f0002,
- 0x007180f6,
- 0x0000001d,
- 0xfd2b80e5,
- 0x000f0002,
- 0x007180f7,
- 0x00000030,
- 0x31838063,
- 0x000f0002,
- 0x007180f8,
- 0x00000030,
- 0x11828063,
- 0x000f0002,
- 0x007180f9,
- 0x0000001d,
- 0xfd2580e5,
- 0x000f0002,
- 0x007180fa,
- 0x00000030,
- 0x31830063,
- 0x000f0002,
- 0x007180fb,
- 0x00000030,
- 0x11820063,
- 0x000f0002,
- 0x007180fc,
- 0x0000002f,
- 0xd18100e3,
- 0x000f0002,
- 0x007180fd,
- 0x0000001d,
- 0xfd0980e5,
- 0x000f0002,
- 0x007180fe,
- 0x00000030,
- 0x3183d363,
- 0x000f0002,
- 0x007180ff,
- 0x00000030,
- 0x1183d263,
- 0x000f0002,
- 0x00718100,
- 0x0000002f,
- 0xd18100e3,
- 0x000f0002,
- 0x00718101,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x00718102,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x00718103,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x00718104,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x00718105,
- 0x00000025,
- 0xd2000264,
- 0x000f0002,
- 0x00718106,
- 0x00000018,
- 0x7d77fd7a,
- 0x000f0002,
- 0x00718107,
- 0x00000049,
- 0xde203b63,
- 0x000f0002,
- 0x00718108,
- 0x00000049,
- 0xde803b79,
- 0x000f0002,
- 0x00718109,
- 0x00000021,
- 0xd18000e3,
- 0x000f0002,
- 0x0071810a,
- 0x00000009,
- 0xcf813d7a,
- 0x000f0002,
- 0x0071810b,
- 0x00000049,
- 0xdd0031e3,
- 0x000f0002,
- 0x0071810c,
- 0x00000069,
- 0xdd0e3b78,
- 0x000f0002,
- 0x0071810d,
- 0x00000061,
- 0xdd003b76,
- 0x000f0002,
- 0x0071810e,
- 0x0000003f,
- 0xdd000184,
- 0x000f0002,
- 0x0071810f,
- 0x0000003f,
- 0xdd000001,
- 0x000f0002,
- 0x00718110,
- 0x00000035,
- 0xdd0000fa,
- 0x000f0002,
- 0x00718111,
- 0x00000018,
- 0x3b7f3b76,
- 0x000f0002,
- 0x00718112,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718113,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718114,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x00718115,
- 0x00000021,
- 0xd18000e3,
- 0x000f0002,
- 0x00718116,
- 0x00000069,
- 0xdd043b79,
- 0x000f0002,
- 0x00718117,
- 0x00000061,
- 0xf18000e3,
- 0x000f0002,
- 0x00718118,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x00718119,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x0071811a,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x0071811b,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x0071811c,
- 0x00000025,
- 0xd2000264,
- 0x000f0002,
- 0x0071811d,
- 0x00000098,
- 0x605dbb76,
- 0x000f0002,
- 0x0071811e,
- 0x00000009,
- 0xcf813d7a,
- 0x000f0002,
- 0x0071811f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718120,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718121,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718122,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718123,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718124,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718125,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718126,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718127,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718128,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718129,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071812a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071812b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071812c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071812d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071812e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071812f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718130,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718131,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718132,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718133,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718134,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718135,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718136,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718137,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718138,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718139,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071813a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071813b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071813c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071813d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071813e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071813f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718140,
- 0x00000049,
- 0xd4083b01,
- 0x000f0002,
- 0x00718141,
- 0x00000009,
- 0xc28b3d7a,
- 0x000f0002,
- 0x00718142,
- 0x0000003f,
- 0xd4000380,
- 0x000f0002,
- 0x00718143,
- 0x00000009,
- 0xc28b3d7a,
- 0x000f0002,
- 0x00718144,
- 0x00000049,
- 0xd40e3b03,
- 0x000f0002,
- 0x00718145,
- 0x0000003f,
- 0xd6420000,
- 0x000f0002,
- 0x00718146,
- 0x0000002f,
- 0xd2814080,
- 0x000f0002,
- 0x00718147,
- 0x0000002d,
- 0xd2840365,
- 0x000f0002,
- 0x00718148,
- 0x0000003f,
- 0xd6800080,
- 0x000f0002,
- 0x00718149,
- 0x0000003f,
- 0xdd040004,
- 0x000f0002,
- 0x0071814a,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x0071814b,
- 0x00000069,
- 0xdd003b6d,
- 0x000f0002,
- 0x0071814c,
- 0x00000069,
- 0xdd003b6d,
- 0x000f0002,
- 0x0071814d,
- 0x00000031,
- 0xd303d265,
- 0x000f0002,
- 0x0071814e,
- 0x00000049,
- 0xde403b66,
- 0x000f0002,
- 0x0071814f,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x00718150,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x00718151,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x00718152,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x00718153,
- 0x00000049,
- 0xd5803b7e,
- 0x000f0002,
- 0x00718154,
- 0x00000021,
- 0xde4000e6,
- 0x000f0002,
- 0x00718155,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x00718156,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x00718157,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x00718158,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x00718159,
- 0x00000049,
- 0xd5003b7e,
- 0x000f0002,
- 0x0071815a,
- 0x00000079,
- 0xdd013b76,
- 0x000f0002,
- 0x0071815b,
- 0x0000002d,
- 0xdd04407f,
- 0x000f0002,
- 0x0071815c,
- 0x00000018,
- 0x3d7f3b76,
- 0x000f0002,
- 0x0071815d,
- 0x00000079,
- 0xdd01bb76,
- 0x000f0002,
- 0x0071815e,
- 0x00000075,
- 0xfd0180e8,
- 0x000f0002,
- 0x0071815f,
- 0x00000094,
- 0x00154168,
- 0x000f0002,
- 0x00718160,
- 0x00000094,
- 0x002544e8,
- 0x000f0002,
- 0x00718161,
- 0x00000094,
- 0x002341e8,
- 0x000f0002,
- 0x00718162,
- 0x00000094,
- 0x00174568,
- 0x000f0002,
- 0x00718163,
- 0x00000094,
- 0x00154268,
- 0x000f0002,
- 0x00718164,
- 0x00000094,
- 0x002742e8,
- 0x000f0002,
- 0x00718165,
- 0x00000094,
- 0x002d4368,
- 0x000f0002,
- 0x00718166,
- 0x00000094,
- 0x002d4468,
- 0x000f0002,
- 0x00718167,
- 0x00000094,
- 0x003343e8,
- 0x000f0002,
- 0x00718168,
- 0x00000004,
- 0x03973b76,
- 0x000f0002,
- 0x00718169,
- 0x0000000d,
- 0xe30dc165,
- 0x000f0002,
- 0x0071816a,
- 0x00000030,
- 0x32030076,
- 0x000f0002,
- 0x0071816b,
- 0x00000030,
- 0x12020076,
- 0x000f0002,
- 0x0071816c,
- 0x0000003f,
- 0xd4800000,
- 0x000f0002,
- 0x0071816d,
- 0x0000003f,
- 0xd1808000,
- 0x000f0002,
- 0x0071816e,
- 0x0000000d,
- 0xe33fc165,
- 0x000f0002,
- 0x0071816f,
- 0x00000030,
- 0x32046076,
- 0x000f0002,
- 0x00718170,
- 0x00000030,
- 0x12044076,
- 0x000f0002,
- 0x00718171,
- 0x0000003f,
- 0xd4828000,
- 0x000f0002,
- 0x00718172,
- 0x0000003f,
- 0xd1808000,
- 0x000f0002,
- 0x00718173,
- 0x0000000d,
- 0xe33fc165,
- 0x000f0002,
- 0x00718174,
- 0x00000030,
- 0x32042076,
- 0x000f0002,
- 0x00718175,
- 0x00000030,
- 0x12040076,
- 0x000f0002,
- 0x00718176,
- 0x0000003f,
- 0xd4820000,
- 0x000f0002,
- 0x00718177,
- 0x0000000d,
- 0xe363c165,
- 0x000f0002,
- 0x00718178,
- 0x00000030,
- 0x32032076,
- 0x000f0002,
- 0x00718179,
- 0x00000030,
- 0x12030076,
- 0x000f0002,
- 0x0071817a,
- 0x0000003f,
- 0xd4830000,
- 0x000f0002,
- 0x0071817b,
- 0x00000049,
- 0xd2803b76,
- 0x000f0002,
- 0x0071817c,
- 0x0000000d,
- 0xe30dc165,
- 0x000f0002,
- 0x0071817d,
- 0x00000030,
- 0x32038076,
- 0x000f0002,
- 0x0071817e,
- 0x00000030,
- 0x12028076,
- 0x000f0002,
- 0x0071817f,
- 0x0000003f,
- 0xd4810000,
- 0x000f0002,
- 0x00718180,
- 0x0000003f,
- 0xd6020000,
- 0x000f0002,
- 0x00718181,
- 0x0000003f,
- 0xd1810000,
- 0x000f0002,
- 0x00718182,
- 0x0000000d,
- 0xe33fc165,
- 0x000f0002,
- 0x00718183,
- 0x00000030,
- 0x32042076,
- 0x000f0002,
- 0x00718184,
- 0x00000030,
- 0x12040076,
- 0x000f0002,
- 0x00718185,
- 0x0000003f,
- 0xd4820000,
- 0x000f0002,
- 0x00718186,
- 0x00000041,
- 0xd48034eb,
- 0x000f0002,
- 0x00718187,
- 0x00000079,
- 0xdd01bb6a,
- 0x000f0002,
- 0x00718188,
- 0x00000079,
- 0xdd01bb76,
- 0x000f0002,
- 0x00718189,
- 0x0000003f,
- 0xd2001803,
- 0x000f0002,
- 0x0071818a,
- 0x0000003f,
- 0xd1810000,
- 0x000f0002,
- 0x0071818b,
- 0x00000075,
- 0xfd018063,
- 0x000f0002,
- 0x0071818c,
- 0x00000098,
- 0x80693b64,
- 0x000f0002,
- 0x0071818d,
- 0x00000051,
- 0xf20000e4,
- 0x000f0002,
- 0x0071818e,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x0071818f,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x00718190,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x00718191,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x00718192,
- 0x0000002d,
- 0xdd04407f,
- 0x000f0002,
- 0x00718193,
- 0x00000018,
- 0x3d7f3b76,
- 0x000f0002,
- 0x00718194,
- 0x00000049,
- 0xd3c03b38,
- 0x000f0002,
- 0x00718195,
- 0x00000049,
- 0xdd003b64,
- 0x000f0002,
- 0x00718196,
- 0x00000051,
- 0xf20000e4,
- 0x000f0002,
- 0x00718197,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x00718198,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x00718199,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x0071819a,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x0071819b,
- 0x00000049,
- 0xd3a03b38,
- 0x000f0002,
- 0x0071819c,
- 0x00000019,
- 0xdd61bb76,
- 0x000f0002,
- 0x0071819d,
- 0x00000049,
- 0xdd003b67,
- 0x000f0002,
- 0x0071819e,
- 0x00000075,
- 0xf1818263,
- 0x000f0002,
- 0x0071819f,
- 0x00000041,
- 0xd48034eb,
- 0x000f0002,
- 0x007181a0,
- 0x00000079,
- 0xdd01bb6a,
- 0x000f0002,
- 0x007181a1,
- 0x00000079,
- 0xdd01bb76,
- 0x000f0002,
- 0x007181a2,
- 0x0000003f,
- 0xd2001803,
- 0x000f0002,
- 0x007181a3,
- 0x0000003f,
- 0xd1808000,
- 0x000f0002,
- 0x007181a4,
- 0x00000075,
- 0xfd018063,
- 0x000f0002,
- 0x007181a5,
- 0x00000098,
- 0x80373b64,
- 0x000f0002,
- 0x007181a6,
- 0x00000051,
- 0xf20000e4,
- 0x000f0002,
- 0x007181a7,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x007181a8,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007181a9,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007181aa,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007181ab,
- 0x0000002d,
- 0xdd04407f,
- 0x000f0002,
- 0x007181ac,
- 0x00000018,
- 0x3d7f3b76,
- 0x000f0002,
- 0x007181ad,
- 0x00000049,
- 0xd3803b38,
- 0x000f0002,
- 0x007181ae,
- 0x00000019,
- 0xdd6fbb76,
- 0x000f0002,
- 0x007181af,
- 0x00000049,
- 0xdd003b67,
- 0x000f0002,
- 0x007181b0,
- 0x00000075,
- 0xf1818263,
- 0x000f0002,
- 0x007181b1,
- 0x00000041,
- 0xd48034eb,
- 0x000f0002,
- 0x007181b2,
- 0x00000079,
- 0xdd01bb6a,
- 0x000f0002,
- 0x007181b3,
- 0x00000079,
- 0xdd01bb63,
- 0x000f0002,
- 0x007181b4,
- 0x00000075,
- 0xfd018063,
- 0x000f0002,
- 0x007181b5,
- 0x00000098,
- 0x80173b64,
- 0x000f0002,
- 0x007181b6,
- 0x00000049,
- 0xde403b64,
- 0x000f0002,
- 0x007181b7,
- 0x0000003f,
- 0xd6800184,
- 0x000f0002,
- 0x007181b8,
- 0x0000003f,
- 0xd6800001,
- 0x000f0002,
- 0x007181b9,
- 0x00000035,
- 0xd68000ed,
- 0x000f0002,
- 0x007181ba,
- 0x00000018,
- 0x37ff0081,
- 0x000f0002,
- 0x007181bb,
- 0x0000002d,
- 0xdd04407f,
- 0x000f0002,
- 0x007181bc,
- 0x00000018,
- 0x3d7f3b76,
- 0x000f0002,
- 0x007181bd,
- 0x00000021,
- 0xd20000e4,
- 0x000f0002,
- 0x007181be,
- 0x00000019,
- 0xd3ef7b7e,
- 0x000f0002,
- 0x007181bf,
- 0x00000075,
- 0xf1818263,
- 0x000f0002,
- 0x007181c0,
- 0x0000003f,
- 0xd6800000,
- 0x000f0002,
- 0x007181c1,
- 0x0000003f,
- 0xdd040004,
- 0x000f0002,
- 0x007181c2,
- 0x0000003f,
- 0xdd180001,
- 0x000f0002,
- 0x007181c3,
- 0x00000069,
- 0xdd003b6d,
- 0x000f0002,
- 0x007181c4,
- 0x00000069,
- 0xdd003b6d,
- 0x000f0002,
- 0x007181c5,
- 0x0000003f,
- 0xdd000000,
- 0x000f0002,
- 0x007181c6,
- 0x0000002d,
- 0xdd540180,
- 0x000f0002,
- 0x007181c7,
- 0x00000079,
- 0xf3e08076,
- 0x000f0002,
- 0x007181c8,
- 0x00000049,
- 0xd600367a,
- 0x000f0002,
- 0x007181c9,
- 0x00000079,
- 0xdd01fb76,
- 0x000f0002,
- 0x007181ca,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181cb,
- 0x00000049,
- 0xdd003b03,
- 0x000f0002,
- 0x007181cc,
- 0x00000059,
- 0xfd003b76,
- 0x000f0002,
- 0x007181cd,
- 0x0000003f,
- 0xdd801c03,
- 0x000f0002,
- 0x007181ce,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181cf,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181d0,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007181d1,
- 0x0000002d,
- 0xdd06027f,
- 0x000f0002,
- 0x007181d2,
- 0x00000018,
- 0x1d7f3d7a,
- 0x000f0002,
- 0x007181d3,
- 0x00000031,
- 0xd483886b,
- 0x000f0002,
- 0x007181d4,
- 0x00000079,
- 0xdd01bb6a,
- 0x000f0002,
- 0x007181d5,
- 0x00000079,
- 0xf1819076,
- 0x000f0002,
- 0x007181d6,
- 0x00000075,
- 0xfd018063,
- 0x000f0002,
- 0x007181d7,
- 0x00000098,
- 0x8053bb76,
- 0x000f0002,
- 0x007181d8,
- 0x00000019,
- 0xdd7f7b79,
- 0x000f0002,
- 0x007181d9,
- 0x00000075,
- 0xf1818263,
- 0x000f0002,
- 0x007181da,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181db,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181dc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181dd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181f9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181fa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181fb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181fc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181fd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007181fe,
- 0x0000003f,
- 0xdd800203,
- 0x000f0002,
- 0x007181ff,
- 0x00000049,
- 0xd1843b02,
- 0x000f0002,
- 0x00718200,
- 0x00000049,
- 0xdd003b03,
- 0x000f0002,
- 0x00718201,
- 0x00000069,
- 0xdd003b7a,
- 0x000f0002,
- 0x00718202,
- 0x00000049,
- 0xdd003b79,
- 0x000f0002,
- 0x00718203,
- 0x00000065,
- 0xf1800263,
- 0x000f0002,
- 0x00718204,
- 0x00000018,
- 0x7d7d3b76,
- 0x000f0002,
- 0x00718205,
- 0x00000009,
- 0xcf813d7a,
- 0x000f0002,
- 0x00718206,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718207,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718208,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718209,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071820a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071820b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071820c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071820d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071820e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071820f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718210,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718211,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718212,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718213,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718214,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718215,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718216,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718217,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718218,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718219,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071821a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071821b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071821c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071821d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071821e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071821f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718220,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718221,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718222,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718223,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718224,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718225,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718226,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718227,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718228,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718229,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071822a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071822b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071822c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071822d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071822e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071822f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718230,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718231,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718232,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718233,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718234,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718235,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718236,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718237,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718238,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718239,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071823a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071823b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071823c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071823d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071823e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071823f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718240,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718241,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718242,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718243,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718244,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718245,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718246,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718247,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718248,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718249,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071824a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071824b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071824c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071824d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071824e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071824f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718250,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718251,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718252,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718253,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718254,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718255,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718256,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718257,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718258,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718259,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071825a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071825b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071825c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071825d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071825e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071825f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718260,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718261,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718262,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718263,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718264,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718265,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718266,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718267,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718268,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718269,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071826a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071826b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071826c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071826d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071826e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071826f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718270,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718271,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718272,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718273,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718274,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718275,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718276,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718277,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718278,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718279,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071827a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071827b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071827c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071827d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071827e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071827f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718280,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718281,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718282,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718283,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718284,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718285,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718286,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718287,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718288,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718289,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071828a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071828b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071828c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071828d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071828e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071828f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718290,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718291,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718292,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718293,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718294,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718295,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718296,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718297,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718298,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718299,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071829a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071829b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071829c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071829d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071829e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071829f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182a9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182aa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ab,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ac,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ad,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ae,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182af,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182b9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ba,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182bb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182bc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182bd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182be,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182bf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182c9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ca,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182cb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182cc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182cd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ce,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182cf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182d9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182da,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182db,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182dc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182dd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182f9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182fa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182fb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182fc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182fd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182fe,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007182ff,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718300,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718301,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718302,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718303,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718304,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718305,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718306,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718307,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718308,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718309,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071830a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071830b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071830c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071830d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071830e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071830f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718310,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718311,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718312,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718313,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718314,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718315,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718316,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718317,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718318,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718319,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071831a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071831b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071831c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071831d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071831e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071831f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718320,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718321,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718322,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718323,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718324,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718325,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718326,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718327,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718328,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718329,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071832a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071832b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071832c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071832d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071832e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071832f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718330,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718331,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718332,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718333,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718334,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718335,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718336,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718337,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718338,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718339,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071833a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071833b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071833c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071833d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071833e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071833f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718340,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718341,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718342,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718343,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718344,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718345,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718346,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718347,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718348,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718349,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071834a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071834b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071834c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071834d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071834e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071834f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718350,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718351,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718352,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718353,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718354,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718355,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718356,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718357,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718358,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718359,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071835a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071835b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071835c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071835d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071835e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071835f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718360,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718361,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718362,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718363,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718364,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718365,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718366,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718367,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718368,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718369,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071836a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071836b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071836c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071836d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071836e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071836f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718370,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718371,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718372,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718373,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718374,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718375,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718376,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718377,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718378,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718379,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071837a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071837b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071837c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071837d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071837e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071837f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718380,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718381,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718382,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718383,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718384,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718385,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718386,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718387,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718388,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718389,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071838a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071838b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071838c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071838d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071838e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071838f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718390,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718391,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718392,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718393,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718394,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718395,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718396,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718397,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718398,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718399,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071839a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071839b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071839c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071839d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071839e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071839f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183a9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183aa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ab,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ac,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ad,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ae,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183af,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183b9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ba,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183bb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183bc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183bd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183be,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183bf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183c9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ca,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183cb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183cc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183cd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ce,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183cf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183d9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183da,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183db,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183dc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183dd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183f9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183fa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183fb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183fc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183fd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183fe,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007183ff,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718400,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718401,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718402,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718403,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718404,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718405,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718406,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718407,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718408,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718409,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071840a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071840b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071840c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071840d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071840e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071840f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718410,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718411,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718412,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718413,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718414,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718415,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718416,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718417,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718418,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718419,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071841a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071841b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071841c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071841d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071841e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071841f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718420,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718421,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718422,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718423,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718424,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718425,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718426,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718427,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718428,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718429,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071842a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071842b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071842c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071842d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071842e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071842f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718430,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718431,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718432,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718433,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718434,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718435,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718436,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718437,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718438,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718439,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071843a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071843b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071843c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071843d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071843e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071843f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718440,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718441,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718442,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718443,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718444,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718445,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718446,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718447,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718448,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718449,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071844a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071844b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071844c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071844d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071844e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071844f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718450,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718451,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718452,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718453,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718454,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718455,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718456,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718457,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718458,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718459,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071845a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071845b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071845c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071845d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071845e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071845f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718460,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718461,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718462,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718463,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718464,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718465,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718466,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718467,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718468,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718469,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071846a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071846b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071846c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071846d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071846e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071846f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718470,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718471,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718472,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718473,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718474,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718475,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718476,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718477,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718478,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718479,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071847a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071847b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071847c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071847d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071847e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071847f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718480,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718481,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718482,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718483,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718484,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718485,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718486,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718487,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718488,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718489,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071848a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071848b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071848c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071848d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071848e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071848f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718490,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718491,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718492,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718493,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718494,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718495,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718496,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718497,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718498,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718499,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071849a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071849b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071849c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071849d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071849e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071849f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184a9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184aa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ab,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ac,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ad,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ae,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184af,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184b9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ba,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184bb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184bc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184bd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184be,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184bf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184c9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ca,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184cb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184cc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184cd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ce,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184cf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184d9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184da,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184db,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184dc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184dd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184f9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184fa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184fb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184fc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184fd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184fe,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007184ff,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718500,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718501,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718502,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718503,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718504,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718505,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718506,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718507,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718508,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718509,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071850a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071850b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071850c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071850d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071850e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071850f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718510,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718511,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718512,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718513,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718514,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718515,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718516,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718517,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718518,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718519,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071851a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071851b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071851c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071851d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071851e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071851f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718520,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718521,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718522,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718523,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718524,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718525,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718526,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718527,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718528,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718529,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071852a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071852b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071852c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071852d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071852e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071852f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718530,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718531,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718532,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718533,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718534,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718535,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718536,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718537,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718538,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718539,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071853a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071853b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071853c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071853d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071853e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071853f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718540,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718541,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718542,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718543,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718544,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718545,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718546,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718547,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718548,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718549,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071854a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071854b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071854c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071854d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071854e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071854f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718550,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718551,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718552,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718553,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718554,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718555,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718556,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718557,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718558,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718559,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071855a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071855b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071855c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071855d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071855e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071855f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718560,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718561,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718562,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718563,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718564,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718565,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718566,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718567,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718568,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718569,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071856a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071856b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071856c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071856d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071856e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071856f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718570,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718571,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718572,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718573,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718574,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718575,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718576,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718577,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718578,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718579,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071857a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071857b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071857c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071857d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071857e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071857f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718580,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718581,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718582,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718583,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718584,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718585,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718586,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718587,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718588,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718589,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071858a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071858b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071858c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071858d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071858e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071858f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718590,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718591,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718592,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718593,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718594,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718595,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718596,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718597,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718598,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718599,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071859a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071859b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071859c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071859d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071859e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071859f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185a9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185aa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ab,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ac,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ad,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ae,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185af,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185b9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ba,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185bb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185bc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185bd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185be,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185bf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185c9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ca,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185cb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185cc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185cd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ce,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185cf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185d9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185da,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185db,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185dc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185dd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185f9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185fa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185fb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185fc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185fd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185fe,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007185ff,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718600,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718601,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718602,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718603,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718604,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718605,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718606,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718607,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718608,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718609,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071860a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071860b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071860c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071860d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071860e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071860f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718610,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718611,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718612,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718613,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718614,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718615,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718616,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718617,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718618,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718619,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071861a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071861b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071861c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071861d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071861e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071861f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718620,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718621,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718622,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718623,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718624,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718625,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718626,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718627,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718628,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718629,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071862a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071862b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071862c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071862d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071862e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071862f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718630,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718631,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718632,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718633,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718634,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718635,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718636,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718637,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718638,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718639,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071863a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071863b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071863c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071863d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071863e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071863f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718640,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718641,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718642,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718643,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718644,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718645,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718646,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718647,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718648,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718649,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071864a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071864b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071864c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071864d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071864e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071864f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718650,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718651,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718652,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718653,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718654,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718655,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718656,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718657,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718658,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718659,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071865a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071865b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071865c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071865d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071865e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071865f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718660,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718661,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718662,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718663,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718664,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718665,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718666,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718667,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718668,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718669,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071866a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071866b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071866c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071866d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071866e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071866f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718670,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718671,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718672,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718673,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718674,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718675,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718676,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718677,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718678,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718679,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071867a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071867b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071867c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071867d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071867e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071867f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718680,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718681,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718682,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718683,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718684,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718685,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718686,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718687,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718688,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718689,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071868a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071868b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071868c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071868d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071868e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071868f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718690,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718691,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718692,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718693,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718694,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718695,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718696,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718697,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718698,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718699,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071869a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071869b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071869c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071869d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071869e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071869f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186a9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186aa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ab,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ac,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ad,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ae,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186af,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186b9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ba,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186bb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186bc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186bd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186be,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186bf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186c9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ca,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186cb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186cc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186cd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ce,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186cf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186d9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186da,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186db,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186dc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186dd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186de,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186df,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186e9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ea,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186eb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ec,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ed,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ee,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ef,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186f9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186fa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186fb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186fc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186fd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186fe,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007186ff,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718700,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718701,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718702,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718703,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718704,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718705,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718706,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718707,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718708,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718709,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071870a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071870b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071870c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071870d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071870e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071870f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718710,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718711,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718712,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718713,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718714,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718715,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718716,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718717,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718718,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718719,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071871a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071871b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071871c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071871d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071871e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071871f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718720,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718721,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718722,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718723,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718724,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718725,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718726,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718727,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718728,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718729,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071872a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071872b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071872c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071872d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071872e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071872f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718730,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718731,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718732,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718733,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718734,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718735,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718736,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718737,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718738,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718739,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071873a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071873b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071873c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071873d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071873e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071873f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718740,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718741,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718742,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718743,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718744,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718745,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718746,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718747,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718748,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718749,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071874a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071874b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071874c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071874d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071874e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071874f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718750,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718751,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718752,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718753,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718754,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718755,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718756,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718757,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718758,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718759,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071875a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071875b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071875c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071875d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071875e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071875f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718760,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718761,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718762,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718763,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718764,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718765,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718766,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718767,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718768,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718769,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071876a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071876b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071876c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071876d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071876e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071876f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718770,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718771,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718772,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718773,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718774,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718775,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718776,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718777,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718778,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718779,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071877a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071877b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071877c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071877d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071877e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071877f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718780,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718781,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718782,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718783,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718784,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718785,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718786,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718787,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718788,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718789,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071878a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071878b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071878c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071878d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071878e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071878f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718790,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718791,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718792,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718793,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718794,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718795,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718796,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718797,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718798,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x00718799,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071879a,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071879b,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071879c,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071879d,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071879e,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x0071879f,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187a9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187aa,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187ab,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187ac,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187ad,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187ae,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187af,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b0,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b1,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b2,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b3,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b4,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b5,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b6,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b7,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b8,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187b9,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187ba,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187bb,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187bc,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187bd,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187be,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187bf,
- 0x00000000,
- 0x00000000,
- 0x000f0002,
- 0x007187c0,
- 0x00000079,
- 0xfd609076,
- 0x000f0002,
- 0x007187c1,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007187c2,
- 0x0000003d,
- 0xf780006f,
- 0x000f0002,
- 0x007187c3,
- 0x0000003d,
- 0xf780006f,
-/* FINISH INIT Descriptor */
- 0x000f0002,
- 0x807187c4,
- 0x0000003d,
- 0xf780006f,
-};
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index dabdf59f8016..437683aab32c 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -4,7 +4,7 @@
* Copyright (C) 2001, 2002, 2003, 2004 David S. Miller (davem@redhat.com)
* Copyright (C) 2001, 2002, 2003 Jeff Garzik (jgarzik@pobox.com)
* Copyright (C) 2004 Sun Microsystems Inc.
- * Copyright (C) 2005-2007 Broadcom Corporation.
+ * Copyright (C) 2005-2009 Broadcom Corporation.
*
* Firmware is:
* Derived from proprietary unpublished source code,
@@ -68,8 +68,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.97"
-#define DRV_MODULE_RELDATE "December 10, 2008"
+#define DRV_MODULE_VERSION "3.98"
+#define DRV_MODULE_RELDATE "February 25, 2009"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -860,7 +860,7 @@ static int tg3_bmcr_reset(struct tg3 *tp)
static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
{
- struct tg3 *tp = (struct tg3 *)bp->priv;
+ struct tg3 *tp = bp->priv;
u32 val;
if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
@@ -874,7 +874,7 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
{
- struct tg3 *tp = (struct tg3 *)bp->priv;
+ struct tg3 *tp = bp->priv;
if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
return -EAGAIN;
@@ -2050,8 +2050,6 @@ static int tg3_setup_phy(struct tg3 *, int);
static void tg3_write_sig_post_reset(struct tg3 *, int);
static int tg3_halt_cpu(struct tg3 *, u32);
-static int tg3_nvram_lock(struct tg3 *);
-static void tg3_nvram_unlock(struct tg3 *);
static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
{
@@ -2108,6 +2106,194 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
}
/* tp->lock is held. */
+static int tg3_nvram_lock(struct tg3 *tp)
+{
+ if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+ int i;
+
+ if (tp->nvram_lock_cnt == 0) {
+ tw32(NVRAM_SWARB, SWARB_REQ_SET1);
+ for (i = 0; i < 8000; i++) {
+ if (tr32(NVRAM_SWARB) & SWARB_GNT1)
+ break;
+ udelay(20);
+ }
+ if (i == 8000) {
+ tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
+ return -ENODEV;
+ }
+ }
+ tp->nvram_lock_cnt++;
+ }
+ return 0;
+}
+
+/* tp->lock is held. */
+static void tg3_nvram_unlock(struct tg3 *tp)
+{
+ if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+ if (tp->nvram_lock_cnt > 0)
+ tp->nvram_lock_cnt--;
+ if (tp->nvram_lock_cnt == 0)
+ tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
+ }
+}
+
+/* tp->lock is held. */
+static void tg3_enable_nvram_access(struct tg3 *tp)
+{
+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+ !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+ u32 nvaccess = tr32(NVRAM_ACCESS);
+
+ tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
+ }
+}
+
+/* tp->lock is held. */
+static void tg3_disable_nvram_access(struct tg3 *tp)
+{
+ if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
+ !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
+ u32 nvaccess = tr32(NVRAM_ACCESS);
+
+ tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
+ }
+}
+
+static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
+ u32 offset, u32 *val)
+{
+ u32 tmp;
+ int i;
+
+ if (offset > EEPROM_ADDR_ADDR_MASK || (offset % 4) != 0)
+ return -EINVAL;
+
+ tmp = tr32(GRC_EEPROM_ADDR) & ~(EEPROM_ADDR_ADDR_MASK |
+ EEPROM_ADDR_DEVID_MASK |
+ EEPROM_ADDR_READ);
+ tw32(GRC_EEPROM_ADDR,
+ tmp |
+ (0 << EEPROM_ADDR_DEVID_SHIFT) |
+ ((offset << EEPROM_ADDR_ADDR_SHIFT) &
+ EEPROM_ADDR_ADDR_MASK) |
+ EEPROM_ADDR_READ | EEPROM_ADDR_START);
+
+ for (i = 0; i < 1000; i++) {
+ tmp = tr32(GRC_EEPROM_ADDR);
+
+ if (tmp & EEPROM_ADDR_COMPLETE)
+ break;
+ msleep(1);
+ }
+ if (!(tmp & EEPROM_ADDR_COMPLETE))
+ return -EBUSY;
+
+ *val = tr32(GRC_EEPROM_DATA);
+ return 0;
+}
+
+#define NVRAM_CMD_TIMEOUT 10000
+
+static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd)
+{
+ int i;
+
+ tw32(NVRAM_CMD, nvram_cmd);
+ for (i = 0; i < NVRAM_CMD_TIMEOUT; i++) {
+ udelay(10);
+ if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) {
+ udelay(10);
+ break;
+ }
+ }
+
+ if (i == NVRAM_CMD_TIMEOUT)
+ return -EBUSY;
+
+ return 0;
+}
+
+static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr)
+{
+ if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
+ (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
+ (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+ !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
+ (tp->nvram_jedecnum == JEDEC_ATMEL))
+
+ addr = ((addr / tp->nvram_pagesize) <<
+ ATMEL_AT45DB0X1B_PAGE_POS) +
+ (addr % tp->nvram_pagesize);
+
+ return addr;
+}
+
+static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr)
+{
+ if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
+ (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
+ (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
+ !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
+ (tp->nvram_jedecnum == JEDEC_ATMEL))
+
+ addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) *
+ tp->nvram_pagesize) +
+ (addr & ((1 << ATMEL_AT45DB0X1B_PAGE_POS) - 1));
+
+ return addr;
+}
+
+/* NOTE: Data read in from NVRAM is byteswapped according to
+ * the byteswapping settings for all other register accesses.
+ * tg3 devices are BE devices, so on a BE machine, the data
+ * returned will be exactly as it is seen in NVRAM. On a LE
+ * machine, the 32-bit value will be byteswapped.
+ */
+static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
+{
+ int ret;
+
+ if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
+ return tg3_nvram_read_using_eeprom(tp, offset, val);
+
+ offset = tg3_nvram_phys_addr(tp, offset);
+
+ if (offset > NVRAM_ADDR_MSK)
+ return -EINVAL;
+
+ ret = tg3_nvram_lock(tp);
+ if (ret)
+ return ret;
+
+ tg3_enable_nvram_access(tp);
+
+ tw32(NVRAM_ADDR, offset);
+ ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_RD | NVRAM_CMD_GO |
+ NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
+
+ if (ret == 0)
+ *val = tr32(NVRAM_RDDATA);
+
+ tg3_disable_nvram_access(tp);
+
+ tg3_nvram_unlock(tp);
+
+ return ret;
+}
+
+/* Ensures NVRAM data is in bytestream format. */
+static int tg3_nvram_read_be32(struct tg3 *tp, u32 offset, __be32 *val)
+{
+ u32 v;
+ int res = tg3_nvram_read(tp, offset, &v);
+ if (!res)
+ *val = cpu_to_be32(v);
+ return res;
+}
+
+/* tp->lock is held. */
static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1)
{
u32 addr_high, addr_low;
@@ -4206,7 +4392,7 @@ static void tg3_recycle_rx(struct tg3 *tp, u32 opaque_key,
#if TG3_VLAN_TAG_USED
static int tg3_vlan_rx(struct tg3 *tp, struct sk_buff *skb, u16 vlan_tag)
{
- return vlan_hwaccel_receive_skb(skb, tp->vlgrp, vlan_tag);
+ return vlan_gro_receive(&tp->napi, tp->vlgrp, vlan_tag, skb);
}
#endif
@@ -4339,6 +4525,13 @@ static int tg3_rx(struct tg3 *tp, int budget)
skb->ip_summed = CHECKSUM_NONE;
skb->protocol = eth_type_trans(skb, tp->dev);
+
+ if (len > (tp->dev->mtu + ETH_HLEN) &&
+ skb->protocol != htons(ETH_P_8021Q)) {
+ dev_kfree_skb(skb);
+ goto next_pkt;
+ }
+
#if TG3_VLAN_TAG_USED
if (tp->vlgrp != NULL &&
desc->type_flags & RXD_FLAG_VLAN) {
@@ -4346,7 +4539,7 @@ static int tg3_rx(struct tg3 *tp, int budget)
desc->err_vlan & RXD_VLAN_MASK);
} else
#endif
- netif_receive_skb(skb);
+ napi_gro_receive(&tp->napi, skb);
received++;
budget--;
@@ -4461,7 +4654,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(!tg3_has_work(tp))) {
- netif_rx_complete(napi);
+ napi_complete(napi);
tg3_restart_ints(tp);
break;
}
@@ -4471,7 +4664,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
tx_recovery:
/* work_done is guaranteed to be less than budget. */
- netif_rx_complete(napi);
+ napi_complete(napi);
schedule_work(&tp->reset_task);
return work_done;
}
@@ -4520,7 +4713,7 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
if (likely(!tg3_irq_sync(tp)))
- netif_rx_schedule(&tp->napi);
+ napi_schedule(&tp->napi);
return IRQ_HANDLED;
}
@@ -4545,7 +4738,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id)
*/
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
if (likely(!tg3_irq_sync(tp)))
- netif_rx_schedule(&tp->napi);
+ napi_schedule(&tp->napi);
return IRQ_RETVAL(1);
}
@@ -4587,7 +4780,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp))) {
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
- netif_rx_schedule(&tp->napi);
+ napi_schedule(&tp->napi);
} else {
/* No work, shared interrupt perhaps? re-enable
* interrupts, and flush that PCI write
@@ -4633,7 +4826,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
if (tg3_irq_sync(tp))
goto out;
- if (netif_rx_schedule_prep(&tp->napi)) {
+ if (napi_schedule_prep(&tp->napi)) {
prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
/* Update last_tag to mark that this status has been
* seen. Because interrupt may be shared, we may be
@@ -4641,7 +4834,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
* if tg3_poll() is not scheduled.
*/
tp->last_tag = sblk->status_tag;
- __netif_rx_schedule(&tp->napi);
+ __napi_schedule(&tp->napi);
}
out:
return IRQ_RETVAL(handled);
@@ -5631,62 +5824,6 @@ static int tg3_abort_hw(struct tg3 *tp, int silent)
return err;
}
-/* tp->lock is held. */
-static int tg3_nvram_lock(struct tg3 *tp)
-{
- if (tp->tg3_flags & TG3_FLAG_NVRAM) {
- int i;
-
- if (tp->nvram_lock_cnt == 0) {
- tw32(NVRAM_SWARB, SWARB_REQ_SET1);
- for (i = 0; i < 8000; i++) {
- if (tr32(NVRAM_SWARB) & SWARB_GNT1)
- break;
- udelay(20);
- }
- if (i == 8000) {
- tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
- return -ENODEV;
- }
- }
- tp->nvram_lock_cnt++;
- }
- return 0;
-}
-
-/* tp->lock is held. */
-static void tg3_nvram_unlock(struct tg3 *tp)
-{
- if (tp->tg3_flags & TG3_FLAG_NVRAM) {
- if (tp->nvram_lock_cnt > 0)
- tp->nvram_lock_cnt--;
- if (tp->nvram_lock_cnt == 0)
- tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
- }
-}
-
-/* tp->lock is held. */
-static void tg3_enable_nvram_access(struct tg3 *tp)
-{
- if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
- !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
- u32 nvaccess = tr32(NVRAM_ACCESS);
-
- tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
- }
-}
-
-/* tp->lock is held. */
-static void tg3_disable_nvram_access(struct tg3 *tp)
-{
- if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
- !(tp->tg3_flags2 & TG3_FLG2_PROTECTED_NVRAM)) {
- u32 nvaccess = tr32(NVRAM_ACCESS);
-
- tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
- }
-}
-
static void tg3_ape_send_event(struct tg3 *tp, u32 event)
{
int i;
@@ -6824,7 +6961,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
__tg3_set_mac_addr(tp, 0);
/* MTU + ethernet header + FCS + optional VLAN tag */
- tw32(MAC_RX_MTU_SIZE, tp->dev->mtu + ETH_HLEN + 8);
+ tw32(MAC_RX_MTU_SIZE,
+ tp->dev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN);
/* The slot time is changed by tg3_setup_phy if we
* run at gigabit with half duplex.
@@ -8386,17 +8524,13 @@ static int tg3_get_eeprom_len(struct net_device *dev)
return tp->nvram_size;
}
-static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val);
-static int tg3_nvram_read_le(struct tg3 *tp, u32 offset, __le32 *val);
-static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val);
-
static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
{
struct tg3 *tp = netdev_priv(dev);
int ret;
u8 *pd;
u32 i, offset, len, b_offset, b_count;
- __le32 val;
+ __be32 val;
if (tp->link_config.phy_is_low_power)
return -EAGAIN;
@@ -8415,7 +8549,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
/* i.e. offset=1 len=2 */
b_count = len;
}
- ret = tg3_nvram_read_le(tp, offset-b_offset, &val);
+ ret = tg3_nvram_read_be32(tp, offset-b_offset, &val);
if (ret)
return ret;
memcpy(data, ((char*)&val) + b_offset, b_count);
@@ -8427,7 +8561,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
/* read bytes upto the last 4 byte boundary */
pd = &data[eeprom->len];
for (i = 0; i < (len - (len & 3)); i += 4) {
- ret = tg3_nvram_read_le(tp, offset + i, &val);
+ ret = tg3_nvram_read_be32(tp, offset + i, &val);
if (ret) {
eeprom->len += i;
return ret;
@@ -8441,7 +8575,7 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
pd = &data[eeprom->len];
b_count = len & 3;
b_offset = offset + len - b_count;
- ret = tg3_nvram_read_le(tp, b_offset, &val);
+ ret = tg3_nvram_read_be32(tp, b_offset, &val);
if (ret)
return ret;
memcpy(pd, &val, b_count);
@@ -8458,7 +8592,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
int ret;
u32 offset, len, b_offset, odd_len;
u8 *buf;
- __le32 start, end;
+ __be32 start, end;
if (tp->link_config.phy_is_low_power)
return -EAGAIN;
@@ -8471,7 +8605,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
if ((b_offset = (offset & 3))) {
/* adjustments to start on required 4 byte boundary */
- ret = tg3_nvram_read_le(tp, offset-b_offset, &start);
+ ret = tg3_nvram_read_be32(tp, offset-b_offset, &start);
if (ret)
return ret;
len += b_offset;
@@ -8485,7 +8619,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
/* adjustments to end on required 4 byte boundary */
odd_len = 1;
len = (len + 3) & ~3;
- ret = tg3_nvram_read_le(tp, offset+len-4, &end);
+ ret = tg3_nvram_read_be32(tp, offset+len-4, &end);
if (ret)
return ret;
}
@@ -8544,7 +8678,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->duplex = tp->link_config.active_duplex;
}
cmd->phy_address = PHY_ADDR;
- cmd->transceiver = 0;
+ cmd->transceiver = XCVR_INTERNAL;
cmd->autoneg = tp->link_config.autoneg;
cmd->maxtxpkt = 0;
cmd->maxrxpkt = 0;
@@ -8561,26 +8695,58 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return phy_ethtool_sset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
}
- if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
- /* These are the only valid advertisement bits allowed. */
- if (cmd->autoneg == AUTONEG_ENABLE &&
- (cmd->advertising & ~(ADVERTISED_1000baseT_Half |
- ADVERTISED_1000baseT_Full |
- ADVERTISED_Autoneg |
- ADVERTISED_FIBRE)))
- return -EINVAL;
- /* Fiber can only do SPEED_1000. */
- else if ((cmd->autoneg != AUTONEG_ENABLE) &&
- (cmd->speed != SPEED_1000))
- return -EINVAL;
- /* Copper cannot force SPEED_1000. */
- } else if ((cmd->autoneg != AUTONEG_ENABLE) &&
- (cmd->speed == SPEED_1000))
+ if (cmd->autoneg != AUTONEG_ENABLE &&
+ cmd->autoneg != AUTONEG_DISABLE)
return -EINVAL;
- else if ((cmd->speed == SPEED_1000) &&
- (tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+
+ if (cmd->autoneg == AUTONEG_DISABLE &&
+ cmd->duplex != DUPLEX_FULL &&
+ cmd->duplex != DUPLEX_HALF)
return -EINVAL;
+ if (cmd->autoneg == AUTONEG_ENABLE) {
+ u32 mask = ADVERTISED_Autoneg |
+ ADVERTISED_Pause |
+ ADVERTISED_Asym_Pause;
+
+ if (!(tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
+ mask |= ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full;
+
+ if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
+ mask |= ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full |
+ ADVERTISED_TP;
+ else
+ mask |= ADVERTISED_FIBRE;
+
+ if (cmd->advertising & ~mask)
+ return -EINVAL;
+
+ mask &= (ADVERTISED_1000baseT_Half |
+ ADVERTISED_1000baseT_Full |
+ ADVERTISED_100baseT_Half |
+ ADVERTISED_100baseT_Full |
+ ADVERTISED_10baseT_Half |
+ ADVERTISED_10baseT_Full);
+
+ cmd->advertising &= mask;
+ } else {
+ if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
+ if (cmd->speed != SPEED_1000)
+ return -EINVAL;
+
+ if (cmd->duplex != DUPLEX_FULL)
+ return -EINVAL;
+ } else {
+ if (cmd->speed != SPEED_100 &&
+ cmd->speed != SPEED_10)
+ return -EINVAL;
+ }
+ }
+
tg3_full_lock(tp, 0);
tp->link_config.autoneg = cmd->autoneg;
@@ -9025,10 +9191,10 @@ static void tg3_get_ethtool_stats (struct net_device *dev,
static int tg3_test_nvram(struct tg3 *tp)
{
u32 csum, magic;
- __le32 *buf;
+ __be32 *buf;
int i, j, k, err = 0, size;
- if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
+ if (tg3_nvram_read(tp, 0, &magic) != 0)
return -EIO;
if (magic == TG3_EEPROM_MAGIC)
@@ -9062,14 +9228,15 @@ static int tg3_test_nvram(struct tg3 *tp)
err = -EIO;
for (i = 0, j = 0; i < size; i += 4, j++) {
- if ((err = tg3_nvram_read_le(tp, i, &buf[j])) != 0)
+ err = tg3_nvram_read_be32(tp, i, &buf[j]);
+ if (err)
break;
}
if (i < size)
goto out;
/* Selfboot format */
- magic = swab32(le32_to_cpu(buf[0]));
+ magic = be32_to_cpu(buf[0]);
if ((magic & TG3_EEPROM_MAGIC_FW_MSK) ==
TG3_EEPROM_MAGIC_FW) {
u8 *buf8 = (u8 *) buf, csum8 = 0;
@@ -9098,7 +9265,7 @@ static int tg3_test_nvram(struct tg3 *tp)
if ((magic & TG3_EEPROM_MAGIC_HW_MSK) ==
TG3_EEPROM_MAGIC_HW) {
u8 data[NVRAM_SELFBOOT_DATA_SIZE];
- u8 parity[NVRAM_SELFBOOT_DATA_SIZE];
+ u8 parity[NVRAM_SELFBOOT_DATA_SIZE];
u8 *buf8 = (u8 *) buf;
/* Separate the parity bits and the data bytes. */
@@ -9141,13 +9308,13 @@ static int tg3_test_nvram(struct tg3 *tp)
/* Bootstrap checksum at offset 0x10 */
csum = calc_crc((unsigned char *) buf, 0x10);
- if(csum != le32_to_cpu(buf[0x10/4]))
+ if (csum != be32_to_cpu(buf[0x10/4]))
goto out;
/* Manufacturing block starts at offset 0x74, checksum at 0xfc */
csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88);
- if (csum != le32_to_cpu(buf[0xfc/4]))
- goto out;
+ if (csum != be32_to_cpu(buf[0xfc/4]))
+ goto out;
err = 0;
@@ -9856,8 +10023,12 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
{
struct tg3 *tp = netdev_priv(dev);
- if (netif_running(dev))
- tg3_netif_stop(tp);
+ if (!netif_running(dev)) {
+ tp->vlgrp = grp;
+ return;
+ }
+
+ tg3_netif_stop(tp);
tg3_full_lock(tp, 0);
@@ -9866,8 +10037,7 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
/* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */
__tg3_set_rx_mode(dev);
- if (netif_running(dev))
- tg3_netif_start(tp);
+ tg3_netif_start(tp);
tg3_full_unlock(tp);
}
@@ -9974,7 +10144,7 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
tp->nvram_size = EEPROM_CHIP_SIZE;
- if (tg3_nvram_read_swab(tp, 0, &magic) != 0)
+ if (tg3_nvram_read(tp, 0, &magic) != 0)
return;
if ((magic != TG3_EEPROM_MAGIC) &&
@@ -9990,7 +10160,7 @@ static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
cursize = 0x10;
while (cursize < tp->nvram_size) {
- if (tg3_nvram_read_swab(tp, cursize, &val) != 0)
+ if (tg3_nvram_read(tp, cursize, &val) != 0)
return;
if (val == magic)
@@ -10006,7 +10176,7 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp)
{
u32 val;
- if (tg3_nvram_read_swab(tp, 0, &val) != 0)
+ if (tg3_nvram_read(tp, 0, &val) != 0)
return;
/* Selfboot format */
@@ -10017,7 +10187,18 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp)
if (tg3_nvram_read(tp, 0xf0, &val) == 0) {
if (val != 0) {
- tp->nvram_size = (val >> 16) * 1024;
+ /* This is confusing. We want to operate on the
+ * 16-bit value at offset 0xf2. The tg3_nvram_read()
+ * call will read from NVRAM and byteswap the data
+ * according to the byteswapping settings for all
+ * other register accesses. This ensures the data we
+ * want will always reside in the lower 16-bits.
+ * However, the data in NVRAM is in LE format, which
+ * means the data from the NVRAM read will always be
+ * opposite the endianness of the CPU. The 16-bit
+ * byteswap then brings the data to CPU endianness.
+ */
+ tp->nvram_size = swab16((u16)(val & 0x0000ffff)) * 1024;
return;
}
}
@@ -10468,141 +10649,6 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
}
}
-static int tg3_nvram_read_using_eeprom(struct tg3 *tp,
- u32 offset, u32 *val)
-{
- u32 tmp;
- int i;
-
- if (offset > EEPROM_ADDR_ADDR_MASK ||
- (offset % 4) != 0)
- return -EINVAL;
-
- tmp = tr32(GRC_EEPROM_ADDR) & ~(EEPROM_ADDR_ADDR_MASK |
- EEPROM_ADDR_DEVID_MASK |
- EEPROM_ADDR_READ);
- tw32(GRC_EEPROM_ADDR,
- tmp |
- (0 << EEPROM_ADDR_DEVID_SHIFT) |
- ((offset << EEPROM_ADDR_ADDR_SHIFT) &
- EEPROM_ADDR_ADDR_MASK) |
- EEPROM_ADDR_READ | EEPROM_ADDR_START);
-
- for (i = 0; i < 1000; i++) {
- tmp = tr32(GRC_EEPROM_ADDR);
-
- if (tmp & EEPROM_ADDR_COMPLETE)
- break;
- msleep(1);
- }
- if (!(tmp & EEPROM_ADDR_COMPLETE))
- return -EBUSY;
-
- *val = tr32(GRC_EEPROM_DATA);
- return 0;
-}
-
-#define NVRAM_CMD_TIMEOUT 10000
-
-static int tg3_nvram_exec_cmd(struct tg3 *tp, u32 nvram_cmd)
-{
- int i;
-
- tw32(NVRAM_CMD, nvram_cmd);
- for (i = 0; i < NVRAM_CMD_TIMEOUT; i++) {
- udelay(10);
- if (tr32(NVRAM_CMD) & NVRAM_CMD_DONE) {
- udelay(10);
- break;
- }
- }
- if (i == NVRAM_CMD_TIMEOUT) {
- return -EBUSY;
- }
- return 0;
-}
-
-static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr)
-{
- if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
- (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
- (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
- !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
- (tp->nvram_jedecnum == JEDEC_ATMEL))
-
- addr = ((addr / tp->nvram_pagesize) <<
- ATMEL_AT45DB0X1B_PAGE_POS) +
- (addr % tp->nvram_pagesize);
-
- return addr;
-}
-
-static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr)
-{
- if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
- (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
- (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
- !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
- (tp->nvram_jedecnum == JEDEC_ATMEL))
-
- addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) *
- tp->nvram_pagesize) +
- (addr & ((1 << ATMEL_AT45DB0X1B_PAGE_POS) - 1));
-
- return addr;
-}
-
-static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val)
-{
- int ret;
-
- if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
- return tg3_nvram_read_using_eeprom(tp, offset, val);
-
- offset = tg3_nvram_phys_addr(tp, offset);
-
- if (offset > NVRAM_ADDR_MSK)
- return -EINVAL;
-
- ret = tg3_nvram_lock(tp);
- if (ret)
- return ret;
-
- tg3_enable_nvram_access(tp);
-
- tw32(NVRAM_ADDR, offset);
- ret = tg3_nvram_exec_cmd(tp, NVRAM_CMD_RD | NVRAM_CMD_GO |
- NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
-
- if (ret == 0)
- *val = swab32(tr32(NVRAM_RDDATA));
-
- tg3_disable_nvram_access(tp);
-
- tg3_nvram_unlock(tp);
-
- return ret;
-}
-
-static int tg3_nvram_read_le(struct tg3 *tp, u32 offset, __le32 *val)
-{
- u32 v;
- int res = tg3_nvram_read(tp, offset, &v);
- if (!res)
- *val = cpu_to_le32(v);
- return res;
-}
-
-static int tg3_nvram_read_swab(struct tg3 *tp, u32 offset, u32 *val)
-{
- int err;
- u32 tmp;
-
- err = tg3_nvram_read(tp, offset, &tmp);
- *val = swab32(tmp);
- return err;
-}
-
static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
u32 offset, u32 len, u8 *buf)
{
@@ -10611,13 +10657,13 @@ static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp,
for (i = 0; i < len; i += 4) {
u32 addr;
- __le32 data;
+ __be32 data;
addr = offset + i;
memcpy(&data, buf + i, 4);
- tw32(GRC_EEPROM_DATA, le32_to_cpu(data));
+ tw32(GRC_EEPROM_DATA, be32_to_cpu(data));
val = tr32(GRC_EEPROM_ADDR);
tw32(GRC_EEPROM_ADDR, val | EEPROM_ADDR_COMPLETE);
@@ -10667,8 +10713,9 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
phy_addr = offset & ~pagemask;
for (j = 0; j < pagesize; j += 4) {
- if ((ret = tg3_nvram_read_le(tp, phy_addr + j,
- (__le32 *) (tmp + j))))
+ ret = tg3_nvram_read_be32(tp, phy_addr + j,
+ (__be32 *) (tmp + j));
+ if (ret)
break;
}
if (ret)
@@ -10715,7 +10762,7 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
__be32 data;
data = *((__be32 *) (tmp + j));
- /* swab32(le32_to_cpu(data)), actually */
+
tw32(NVRAM_WRDATA, be32_to_cpu(data));
tw32(NVRAM_ADDR, phy_addr + j);
@@ -11178,7 +11225,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
return tg3_phy_init(tp);
/* Reading the PHY ID register can conflict with ASF
- * firwmare access to the PHY hardware.
+ * firmware access to the PHY hardware.
*/
err = 0;
if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
@@ -11301,24 +11348,25 @@ skip_phy_reset:
static void __devinit tg3_read_partno(struct tg3 *tp)
{
- unsigned char vpd_data[256];
+ unsigned char vpd_data[256]; /* in little-endian format */
unsigned int i;
u32 magic;
- if (tg3_nvram_read_swab(tp, 0x0, &magic))
+ if (tg3_nvram_read(tp, 0x0, &magic))
goto out_not_found;
if (magic == TG3_EEPROM_MAGIC) {
for (i = 0; i < 256; i += 4) {
u32 tmp;
- if (tg3_nvram_read(tp, 0x100 + i, &tmp))
+ /* The data is in little-endian format in NVRAM.
+ * Use the big-endian read routines to preserve
+ * the byte order as it exists in NVRAM.
+ */
+ if (tg3_nvram_read_be32(tp, 0x100 + i, &tmp))
goto out_not_found;
- vpd_data[i + 0] = ((tmp >> 0) & 0xff);
- vpd_data[i + 1] = ((tmp >> 8) & 0xff);
- vpd_data[i + 2] = ((tmp >> 16) & 0xff);
- vpd_data[i + 3] = ((tmp >> 24) & 0xff);
+ memcpy(&vpd_data[i], &tmp, sizeof(tmp));
}
} else {
int vpd_cap;
@@ -11344,7 +11392,7 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA,
&tmp);
v = cpu_to_le32(tmp);
- memcpy(&vpd_data[i], &v, 4);
+ memcpy(&vpd_data[i], &v, sizeof(v));
}
}
@@ -11404,15 +11452,79 @@ static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
{
u32 val;
- if (tg3_nvram_read_swab(tp, offset, &val) ||
+ if (tg3_nvram_read(tp, offset, &val) ||
(val & 0xfc000000) != 0x0c000000 ||
- tg3_nvram_read_swab(tp, offset + 4, &val) ||
+ tg3_nvram_read(tp, offset + 4, &val) ||
val != 0)
return 0;
return 1;
}
+static void __devinit tg3_read_bc_ver(struct tg3 *tp)
+{
+ u32 val, offset, start, ver_offset;
+ int i;
+ bool newver = false;
+
+ if (tg3_nvram_read(tp, 0xc, &offset) ||
+ tg3_nvram_read(tp, 0x4, &start))
+ return;
+
+ offset = tg3_nvram_logical_addr(tp, offset);
+
+ if (tg3_nvram_read(tp, offset, &val))
+ return;
+
+ if ((val & 0xfc000000) == 0x0c000000) {
+ if (tg3_nvram_read(tp, offset + 4, &val))
+ return;
+
+ if (val == 0)
+ newver = true;
+ }
+
+ if (newver) {
+ if (tg3_nvram_read(tp, offset + 8, &ver_offset))
+ return;
+
+ offset = offset + ver_offset - start;
+ for (i = 0; i < 16; i += 4) {
+ __be32 v;
+ if (tg3_nvram_read_be32(tp, offset + i, &v))
+ return;
+
+ memcpy(tp->fw_ver + i, &v, sizeof(v));
+ }
+ } else {
+ u32 major, minor;
+
+ if (tg3_nvram_read(tp, TG3_NVM_PTREV_BCVER, &ver_offset))
+ return;
+
+ major = (ver_offset & TG3_NVM_BCVER_MAJMSK) >>
+ TG3_NVM_BCVER_MAJSFT;
+ minor = ver_offset & TG3_NVM_BCVER_MINMSK;
+ snprintf(&tp->fw_ver[0], 32, "v%d.%02d", major, minor);
+ }
+}
+
+static void __devinit tg3_read_hwsb_ver(struct tg3 *tp)
+{
+ u32 val, major, minor;
+
+ /* Use native endian representation */
+ if (tg3_nvram_read(tp, TG3_NVM_HWSB_CFG1, &val))
+ return;
+
+ major = (val & TG3_NVM_HWSB_CFG1_MAJMSK) >>
+ TG3_NVM_HWSB_CFG1_MAJSFT;
+ minor = (val & TG3_NVM_HWSB_CFG1_MINMSK) >>
+ TG3_NVM_HWSB_CFG1_MINSFT;
+
+ snprintf(&tp->fw_ver[0], 32, "sb v%d.%02d", major, minor);
+}
+
static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
{
u32 offset, major, minor, build;
@@ -11438,7 +11550,7 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
return;
}
- if (tg3_nvram_read_swab(tp, offset, &val))
+ if (tg3_nvram_read(tp, offset, &val))
return;
build = (val & TG3_EEPROM_SB_EDH_BLD_MASK) >>
@@ -11458,49 +11570,15 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val)
}
}
-static void __devinit tg3_read_fw_ver(struct tg3 *tp)
+static void __devinit tg3_read_mgmtfw_ver(struct tg3 *tp)
{
u32 val, offset, start;
- u32 ver_offset;
- int i, bcnt;
-
- if (tg3_nvram_read_swab(tp, 0, &val))
- return;
-
- if (val != TG3_EEPROM_MAGIC) {
- if ((val & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW)
- tg3_read_sb_ver(tp, val);
-
- return;
- }
-
- if (tg3_nvram_read_swab(tp, 0xc, &offset) ||
- tg3_nvram_read_swab(tp, 0x4, &start))
- return;
-
- offset = tg3_nvram_logical_addr(tp, offset);
-
- if (!tg3_fw_img_is_valid(tp, offset) ||
- tg3_nvram_read_swab(tp, offset + 8, &ver_offset))
- return;
-
- offset = offset + ver_offset - start;
- for (i = 0; i < 16; i += 4) {
- __le32 v;
- if (tg3_nvram_read_le(tp, offset + i, &v))
- return;
-
- memcpy(tp->fw_ver + i, &v, 4);
- }
-
- if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
- (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
- return;
+ int i, vlen;
for (offset = TG3_NVM_DIR_START;
offset < TG3_NVM_DIR_END;
offset += TG3_NVM_DIRENT_SIZE) {
- if (tg3_nvram_read_swab(tp, offset, &val))
+ if (tg3_nvram_read(tp, offset, &val))
return;
if ((val >> TG3_NVM_DIRTYPE_SHIFT) == TG3_NVM_DIRTYPE_ASFINI)
@@ -11512,36 +11590,87 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
start = 0x08000000;
- else if (tg3_nvram_read_swab(tp, offset - 4, &start))
+ else if (tg3_nvram_read(tp, offset - 4, &start))
return;
- if (tg3_nvram_read_swab(tp, offset + 4, &offset) ||
+ if (tg3_nvram_read(tp, offset + 4, &offset) ||
!tg3_fw_img_is_valid(tp, offset) ||
- tg3_nvram_read_swab(tp, offset + 8, &val))
+ tg3_nvram_read(tp, offset + 8, &val))
return;
offset += val - start;
- bcnt = strlen(tp->fw_ver);
+ vlen = strlen(tp->fw_ver);
- tp->fw_ver[bcnt++] = ',';
- tp->fw_ver[bcnt++] = ' ';
+ tp->fw_ver[vlen++] = ',';
+ tp->fw_ver[vlen++] = ' ';
for (i = 0; i < 4; i++) {
- __le32 v;
- if (tg3_nvram_read_le(tp, offset, &v))
+ __be32 v;
+ if (tg3_nvram_read_be32(tp, offset, &v))
return;
offset += sizeof(v);
- if (bcnt > TG3_VER_SIZE - sizeof(v)) {
- memcpy(&tp->fw_ver[bcnt], &v, TG3_VER_SIZE - bcnt);
+ if (vlen > TG3_VER_SIZE - sizeof(v)) {
+ memcpy(&tp->fw_ver[vlen], &v, TG3_VER_SIZE - vlen);
break;
}
- memcpy(&tp->fw_ver[bcnt], &v, sizeof(v));
- bcnt += sizeof(v);
+ memcpy(&tp->fw_ver[vlen], &v, sizeof(v));
+ vlen += sizeof(v);
}
+}
+
+static void __devinit tg3_read_dash_ver(struct tg3 *tp)
+{
+ int vlen;
+ u32 apedata;
+
+ if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) ||
+ !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+ return;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
+ if (apedata != APE_SEG_SIG_MAGIC)
+ return;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
+ if (!(apedata & APE_FW_STATUS_READY))
+ return;
+
+ apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION);
+
+ vlen = strlen(tp->fw_ver);
+
+ snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " DASH v%d.%d.%d.%d",
+ (apedata & APE_FW_VERSION_MAJMSK) >> APE_FW_VERSION_MAJSFT,
+ (apedata & APE_FW_VERSION_MINMSK) >> APE_FW_VERSION_MINSFT,
+ (apedata & APE_FW_VERSION_REVMSK) >> APE_FW_VERSION_REVSFT,
+ (apedata & APE_FW_VERSION_BLDMSK));
+}
+
+static void __devinit tg3_read_fw_ver(struct tg3 *tp)
+{
+ u32 val;
+
+ if (tg3_nvram_read(tp, 0, &val))
+ return;
+
+ if (val == TG3_EEPROM_MAGIC)
+ tg3_read_bc_ver(tp);
+ else if ((val & TG3_EEPROM_MAGIC_FW_MSK) == TG3_EEPROM_MAGIC_FW)
+ tg3_read_sb_ver(tp, val);
+ else if ((val & TG3_EEPROM_MAGIC_HW_MSK) == TG3_EEPROM_MAGIC_HW)
+ tg3_read_hwsb_ver(tp);
+ else
+ return;
+
+ if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
+ (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
+ return;
+
+ tg3_read_mgmtfw_ver(tp);
tp->fw_ver[TG3_VER_SIZE - 1] = 0;
}
@@ -12312,14 +12441,10 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
}
if (!addr_ok) {
/* Next, try NVRAM. */
- if (!tg3_nvram_read(tp, mac_offset + 0, &hi) &&
- !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
- dev->dev_addr[0] = ((hi >> 16) & 0xff);
- dev->dev_addr[1] = ((hi >> 24) & 0xff);
- dev->dev_addr[2] = ((lo >> 0) & 0xff);
- dev->dev_addr[3] = ((lo >> 8) & 0xff);
- dev->dev_addr[4] = ((lo >> 16) & 0xff);
- dev->dev_addr[5] = ((lo >> 24) & 0xff);
+ if (!tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
+ !tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) {
+ memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2);
+ memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo));
}
/* Finally just fetch it out of the MAC control regs. */
else {
@@ -13200,6 +13325,9 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
}
tg3_ape_lock_init(tp);
+
+ if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
+ tg3_read_dash_ver(tp);
}
/*
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 508def3e077f..cb4c62abdd21 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1719,6 +1719,12 @@
#define TG3_OTP_DEFAULT 0x286c1640
+/* Hardware Selfboot NVRAM layout */
+#define TG3_NVM_HWSB_CFG1 0x00000004
+#define TG3_NVM_HWSB_CFG1_MAJMSK 0xf8000000
+#define TG3_NVM_HWSB_CFG1_MAJSFT 27
+#define TG3_NVM_HWSB_CFG1_MINMSK 0x07c00000
+#define TG3_NVM_HWSB_CFG1_MINSFT 22
#define TG3_EEPROM_MAGIC 0x669955aa
#define TG3_EEPROM_MAGIC_FW 0xa5000000
@@ -1737,6 +1743,10 @@
#define TG3_NVM_DIRENT_SIZE 0xc
#define TG3_NVM_DIRTYPE_SHIFT 24
#define TG3_NVM_DIRTYPE_ASFINI 1
+#define TG3_NVM_PTREV_BCVER 0x94
+#define TG3_NVM_BCVER_MAJMSK 0x0000ff00
+#define TG3_NVM_BCVER_MAJSFT 8
+#define TG3_NVM_BCVER_MINMSK 0x000000ff
#define TG3_EEPROM_SB_F1R0_EDH_OFF 0x10
#define TG3_EEPROM_SB_F1R2_EDH_OFF 0x14
@@ -1967,6 +1977,14 @@
/* APE shared memory. Accessible through BAR1 */
#define TG3_APE_FW_STATUS 0x400c
#define APE_FW_STATUS_READY 0x00000100
+#define TG3_APE_FW_VERSION 0x4018
+#define APE_FW_VERSION_MAJMSK 0xff000000
+#define APE_FW_VERSION_MAJSFT 24
+#define APE_FW_VERSION_MINMSK 0x00ff0000
+#define APE_FW_VERSION_MINSFT 16
+#define APE_FW_VERSION_REVMSK 0x0000ff00
+#define APE_FW_VERSION_REVSFT 8
+#define APE_FW_VERSION_BLDMSK 0x000000ff
#define TG3_APE_HOST_SEG_SIG 0x4200
#define APE_HOST_SEG_SIG_MAGIC 0x484f5354
#define TG3_APE_HOST_SEG_LEN 0x4204
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index 43853e3b210e..534c0f38483c 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -62,6 +62,7 @@
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>
+#include <linux/firmware.h>
#include <net/checksum.h>
@@ -73,8 +74,10 @@
static char version[] __devinitdata =
"3c359.c v1.2.0 2/17/01 - Mike Phillips (mikep@linuxtr.net)" ;
+#define FW_NAME "3com/3C359.bin"
MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ;
MODULE_DESCRIPTION("3Com 3C359 Velocity XL Token Ring Adapter Driver \n") ;
+MODULE_FIRMWARE(FW_NAME);
/* Module paramters */
@@ -114,8 +117,6 @@ MODULE_PARM_DESC(message_level, "3c359: Level of reported messages") ;
* will be stuck with 1555 lines of hex #'s in the code.
*/
-#include "3c359_microcode.h"
-
static struct pci_device_id xl_pci_tbl[] =
{
{PCI_VENDOR_ID_3COM,PCI_DEVICE_ID_3COM_3C359, PCI_ANY_ID, PCI_ANY_ID, },
@@ -274,6 +275,15 @@ static void xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value)
return ;
}
+
+static const struct net_device_ops xl_netdev_ops = {
+ .ndo_open = xl_open,
+ .ndo_stop = xl_close,
+ .ndo_start_xmit = xl_xmit,
+ .ndo_change_mtu = xl_change_mtu,
+ .ndo_set_multicast_list = xl_set_rx_mode,
+ .ndo_set_mac_address = xl_set_mac_address,
+};
static int __devinit xl_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -337,13 +347,7 @@ static int __devinit xl_probe(struct pci_dev *pdev,
return i ;
}
- dev->open=&xl_open;
- dev->hard_start_xmit=&xl_xmit;
- dev->change_mtu=&xl_change_mtu;
- dev->stop=&xl_close;
- dev->do_ioctl=NULL;
- dev->set_multicast_list=&xl_set_rx_mode;
- dev->set_mac_address=&xl_set_mac_address ;
+ dev->netdev_ops = &xl_netdev_ops;
SET_NETDEV_DEV(dev, &pdev->dev);
pci_set_drvdata(pdev,dev) ;
@@ -361,10 +365,30 @@ static int __devinit xl_probe(struct pci_dev *pdev,
return 0;
}
+static int xl_init_firmware(struct xl_private *xl_priv)
+{
+ int err;
+
+ err = request_firmware(&xl_priv->fw, FW_NAME, &xl_priv->pdev->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load firmware \"%s\"\n", FW_NAME);
+ return err;
+ }
+
+ if (xl_priv->fw->size < 16) {
+ printk(KERN_ERR "Bogus length %zu in \"%s\"\n",
+ xl_priv->fw->size, FW_NAME);
+ release_firmware(xl_priv->fw);
+ err = -EINVAL;
+ }
+
+ return err;
+}
static int __devinit xl_init(struct net_device *dev)
{
struct xl_private *xl_priv = netdev_priv(dev);
+ int err;
printk(KERN_INFO "%s \n", version);
printk(KERN_INFO "%s: I/O at %hx, MMIO at %p, using irq %d\n",
@@ -372,8 +396,11 @@ static int __devinit xl_init(struct net_device *dev)
spin_lock_init(&xl_priv->xl_lock) ;
- return xl_hw_reset(dev) ;
+ err = xl_init_firmware(xl_priv);
+ if (err == 0)
+ err = xl_hw_reset(dev);
+ return err;
}
@@ -383,7 +410,7 @@ static int __devinit xl_init(struct net_device *dev)
*/
static int xl_hw_reset(struct net_device *dev)
-{
+{
struct xl_private *xl_priv = netdev_priv(dev);
u8 __iomem *xl_mmio = xl_priv->xl_mmio ;
unsigned long t ;
@@ -393,6 +420,9 @@ static int xl_hw_reset(struct net_device *dev)
u16 start ;
int j ;
+ if (xl_priv->fw == NULL)
+ return -EINVAL;
+
/*
* Reset the card. If the card has got the microcode on board, we have
* missed the initialization interrupt, so we must always do this.
@@ -455,25 +485,30 @@ static int xl_hw_reset(struct net_device *dev)
/*
* Now to write the microcode into the shared ram
- * The microcode must finish at position 0xFFFF, so we must subtract
- * to get the start position for the code
+ * The microcode must finish at position 0xFFFF,
+ * so we must subtract to get the start position for the code
+ *
+ * Looks strange but ensures compiler only uses
+ * 16 bit unsigned int
*/
+ start = (0xFFFF - (xl_priv->fw->size) + 1) ;
- start = (0xFFFF - (mc_size) + 1 ) ; /* Looks strange but ensures compiler only uses 16 bit unsigned int for this */
-
printk(KERN_INFO "3C359: Uploading Microcode: ");
-
- for (i = start, j = 0; j < mc_size; i++, j++) {
- writel(MEM_BYTE_WRITE | 0XD0000 | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(microcode[j],xl_mmio + MMIO_MACDATA) ;
+
+ for (i = start, j = 0; j < xl_priv->fw->size; i++, j++) {
+ writel(MEM_BYTE_WRITE | 0XD0000 | i,
+ xl_mmio + MMIO_MAC_ACCESS_CMD);
+ writeb(xl_priv->fw->data[j], xl_mmio + MMIO_MACDATA);
if (j % 1024 == 0)
printk(".");
}
printk("\n") ;
- for (i=0;i < 16; i++) {
- writel( (MEM_BYTE_WRITE | 0xDFFF0) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ;
- writeb(microcode[mc_size - 16 + i], xl_mmio + MMIO_MACDATA) ;
+ for (i = 0; i < 16; i++) {
+ writel((MEM_BYTE_WRITE | 0xDFFF0) + i,
+ xl_mmio + MMIO_MAC_ACCESS_CMD);
+ writeb(xl_priv->fw->data[xl_priv->fw->size - 16 + i],
+ xl_mmio + MMIO_MACDATA);
}
/*
@@ -1779,6 +1814,7 @@ static void __devexit xl_remove_one (struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
struct xl_private *xl_priv=netdev_priv(dev);
+ release_firmware(xl_priv->fw);
unregister_netdev(dev);
iounmap(xl_priv->xl_mmio) ;
pci_release_regions(pdev) ;
diff --git a/drivers/net/tokenring/3c359.h b/drivers/net/tokenring/3c359.h
index 66b1ff603234..bcb1a6b4a4c7 100644
--- a/drivers/net/tokenring/3c359.h
+++ b/drivers/net/tokenring/3c359.h
@@ -284,5 +284,8 @@ struct xl_private {
u8 xl_laa[6] ;
u32 rx_ring_dma_addr ;
u32 tx_ring_dma_addr ;
+
+ /* firmware section */
+ const struct firmware *fw;
};
diff --git a/drivers/net/tokenring/3c359_microcode.h b/drivers/net/tokenring/3c359_microcode.h
deleted file mode 100644
index 0400c029c077..000000000000
--- a/drivers/net/tokenring/3c359_microcode.h
+++ /dev/null
@@ -1,1581 +0,0 @@
-
-/*
- * The firmware this driver downloads into the tokenring card is a
- * separate program and is not GPL'd source code, even though the Linux
- * side driver and the routine that loads this data into the card are.
- *
- * This firmware is licensed to you strictly for use in conjunction
- * with the use of 3Com 3C359 TokenRing adapters. There is no
- * waranty expressed or implied about its fitness for any purpose.
- */
-
-/* 3c359_microcode.mac: 3Com 3C359 Tokenring microcode.
- *
- * Notes:
- * - Loaded from xl_init upon adapter initialization.
- *
- * Available from 3Com as part of their standard 3C359 driver.
- *
- * mc_size *must* must match the microcode being used, each version is a
- * different length.
- */
-
-static int mc_size = 24880 ;
-
-static const u8 microcode[] = {
- 0xfe,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x33,0x2f,0x30,0x32,0x2f,0x39,0x39,0x20,0x31
-,0x37,0x3a,0x31,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46
-,0x00,0x00,0x07,0xff,0x02,0x00,0xfe,0x9f,0x06,0x00,0x00,0x7c,0x48,0x00,0x00,0x70
-,0x82,0x00,0xff,0xff,0x86,0x00,0xff,0xff,0x88,0x00,0xff,0xff,0x9a,0x00,0xff,0xff
-,0xff,0xff,0x11,0x00,0xc0,0x00,0xff,0xff,0xff,0xff,0x11,0x22,0x33,0x44,0x55,0x66
-,0x33,0x43,0x4f,0x4d,0x20,0x42,0x41,0x42,0x45,0x11,0x40,0xc0,0x00,0xff,0xff,0xff
-,0xff,0x11,0x22,0x33,0x44,0x55,0x66,0x53,0x74,0x61,0x72,0x74,0x20,0x6f,0x66,0x20
-,0x4c,0x4c,0x43,0x20,0x66,0x72,0x61,0x6d,0x65,0x2e,0x20,0x20,0x54,0x6f,0x74,0x61
-,0x6c,0x20,0x64,0x61,0x74,0x61,0x20,0x73,0x69,0x7a,0x65,0x20,0x69,0x73,0x20,0x78
-,0x78,0x78,0x20,0x20,0x20,0x42,0x41,0x42,0x45,0xe8,0xd2,0x01,0x83,0x3e,0xf7,0x34
-,0x00,0x75,0x21,0xe8,0x41,0x00,0x83,0x3e,0xf7,0x34,0x00,0x75,0x17,0xe8,0x82,0x00
-,0x83,0x3e,0xf7,0x34,0x00,0x75,0x0d,0xe8,0xbf,0x00,0x83,0x3e,0xf7,0x34,0x00,0x75
-,0x03,0xe8,0x41,0x02,0xc3,0x1e,0xb8,0x00,0xf0,0x8e,0xd8,0x33,0xf6,0xb9,0x00,0x80
-,0x33,0xdb,0xad,0x03,0xd8,0xe2,0xfb,0x1f,0xb8,0x00,0x00,0x83,0xfb,0x00,0x74,0x03
-,0xb8,0x22,0x00,0xa3,0xf7,0x34,0xc3,0xfa,0xba,0x56,0x00,0xb0,0xff,0xee,0x33,0xc0
-,0x8e,0xc0,0x33,0xf6,0xb9,0xff,0x7f,0x83,0x3e,0xff,0x34,0x00,0x74,0x08,0x8d,0x3e
-,0x30,0x61,0xd1,0xef,0x2b,0xcf,0x26,0x8b,0x1c,0x26,0xc7,0x04,0xff,0xff,0x26,0x83
-,0x3c,0xff,0x75,0x17,0x26,0xc7,0x04,0x00,0x00,0x26,0x83,0x3c,0x00,0x75,0x0c,0x26
-,0x89,0x1c,0x46,0x46,0xe2,0xe0,0xb8,0x00,0x00,0xeb,0x03,0xb8,0x24,0x00,0xa3,0xf7
-,0x34,0xc3,0xfa,0xb4,0xd7,0x9e,0x73,0x3a,0x75,0x38,0x79,0x36,0x7b,0x34,0x9f,0xb1
-,0x05,0xd2,0xec,0x73,0x2d,0xb0,0x40,0xd0,0xe0,0x71,0x27,0x79,0x25,0xd0,0xe0,0x73
-,0x21,0x7b,0x1f,0x32,0xc0,0x75,0x1b,0x32,0xe4,0x9e,0x72,0x16,0x74,0x14,0x78,0x12
-,0x7a,0x10,0x9f,0xd2,0xec,0x72,0x0b,0xd0,0xe4,0x70,0x07,0x75,0x05,0xb8,0x00,0x00
-,0xeb,0x03,0xb8,0x26,0x00,0xa3,0xf7,0x34,0xc3,0xfa,0xba,0x5a,0x00,0x33,0xc0,0xef
-,0xef,0xef,0xef,0xb0,0x00,0xe6,0x56,0xb0,0x00,0xe6,0x54,0xba,0x52,0x00,0xb8,0x01
-,0x01,0xef,0xe8,0xca,0x00,0x3c,0x01,0x75,0x7f,0xe8,0x83,0x00,0xba,0x52,0x00,0xb8
-,0x02,0x02,0xef,0xe8,0xb9,0x00,0x3c,0x02,0x75,0x6e,0xe8,0x7a,0x00,0xba,0x52,0x00
-,0xb8,0x04,0x04,0xef,0xe8,0xa8,0x00,0x3c,0x04,0x75,0x5d,0xe8,0x71,0x00,0xba,0x52
-,0x00,0xb8,0x08,0x08,0xef,0xe8,0x97,0x00,0x3c,0x08,0x75,0x4c,0xe8,0x68,0x00,0xba
-,0x52,0x00,0xb8,0x10,0x10,0xef,0xe8,0x86,0x00,0x3c,0x10,0x75,0x3b,0xe8,0x5f,0x00
-,0xba,0x52,0x00,0xb8,0x20,0x20,0xef,0xe8,0x75,0x00,0x3c,0x20,0x75,0x2a,0xe8,0x56
-,0x00,0xba,0x52,0x00,0xb8,0x40,0x40,0xef,0xe8,0x64,0x00,0x3c,0x40,0x75,0x19,0xe8
-,0x4d,0x00,0xba,0x52,0x00,0xb8,0x80,0x80,0xef,0xe8,0x53,0x00,0x3c,0x80,0x75,0x08
-,0xe8,0x44,0x00,0xb8,0x00,0x00,0xeb,0x03,0xb8,0x28,0x00,0xa3,0xf7,0x34,0xc3,0xba
-,0x5a,0x00,0xb8,0x00,0x80,0xef,0xc3,0xba,0x5a,0x00,0xb8,0x01,0x80,0xef,0xc3,0xba
-,0x5a,0x00,0xb8,0x02,0x80,0xef,0xc3,0xba,0x5a,0x00,0xb8,0x03,0x80,0xef,0xc3,0xba
-,0x5a,0x00,0xb8,0x04,0x80,0xef,0xc3,0xba,0x5a,0x00,0xb8,0x05,0x80,0xef,0xc3,0xba
-,0x5a,0x00,0xb8,0x06,0x80,0xef,0xc3,0xba,0x5a,0x00,0xb8,0x07,0x80,0xef,0xc3,0xb9
-,0xff,0xff,0xe4,0x58,0xe4,0x54,0x3c,0x00,0x75,0x03,0x49,0x75,0xf7,0xc3,0xfa,0x32
-,0xc0,0xe6,0x56,0xe4,0x56,0x3c,0x00,0x74,0x03,0xe9,0x82,0x00,0xb0,0xff,0xe6,0x56
-,0xe4,0x56,0x3c,0xff,0x75,0x78,0xba,0x52,0x00,0xb8,0xff,0xff,0xef,0xed,0x3c,0xff
-,0x75,0x6c,0xb8,0x00,0xff,0xef,0xed,0x3c,0x00,0x75,0x63,0xb0,0xff,0xe6,0x54,0xe4
-,0x54,0x3c,0xff,0x75,0x59,0x32,0xc0,0xe6,0x54,0xe4,0x54,0x3c,0x00,0x75,0x4f,0xb0
-,0x0f,0xe6,0x50,0xe4,0x50,0x24,0x0f,0x3c,0x0f,0x75,0x43,0xb0,0x00,0xe6,0x50,0xe4
-,0x50,0x24,0x0f,0x3c,0x00,0x75,0x37,0x8c,0xc8,0x8e,0xc0,0xbe,0x70,0x00,0x26,0x8b
-,0x14,0x26,0x8b,0x5c,0x02,0xb8,0x00,0x00,0xef,0xed,0x23,0xc3,0x3d,0x00,0x00,0x75
-,0x1d,0xb8,0xff,0xff,0x23,0xc3,0xef,0x8b,0xc8,0xed,0x23,0xc3,0x3b,0xc1,0x75,0x0e
-,0x83,0xc6,0x04,0x26,0x83,0x3c,0xff,0x75,0xd5,0xb8,0x00,0x00,0xeb,0x03,0xb8,0x2a
-,0x00,0xa3,0xf7,0x34,0xc3,0xfa,0x33,0xc0,0xbf,0x00,0x20,0xb9,0x17,0x00,0xf3,0xab
-,0xbf,0x00,0x30,0xb9,0x17,0x00,0xf3,0xab,0xbf,0x00,0x22,0xb9,0x40,0x00,0xf3,0xab
-,0xbf,0x00,0x32,0xb9,0x40,0x00,0xf3,0xab,0xfc,0x1e,0x8c,0xc8,0x8e,0xd8,0x33,0xc0
-,0x8e,0xc0,0xbe,0x92,0x00,0xbf,0x00,0x20,0xb9,0x17,0x00,0xf3,0xa4,0xbe,0xa9,0x00
-,0xbf,0x00,0x22,0xb9,0x40,0x00,0xf3,0xa4,0x1f,0xc7,0x06,0xfb,0x34,0x64,0x00,0xba
-,0x08,0x00,0xb8,0x0f,0x00,0xef,0xe8,0x82,0x01,0xe8,0x9b,0x01,0x72,0x0d,0xc7,0x06
-,0xf7,0x34,0x2c,0x00,0xc7,0x06,0xf9,0x34,0x04,0x00,0xc3,0xba,0x0a,0x00,0x33,0xc0
-,0xef,0xe8,0x98,0x01,0xe8,0xb5,0x01,0xb8,0x17,0x00,0xba,0x9c,0x00,0xef,0xb8,0x00
-,0x10,0xba,0x9a,0x00,0xef,0xb8,0x17,0x00,0xa9,0x01,0x00,0x74,0x01,0x40,0xba,0x8c
-,0x00,0xef,0xb8,0x00,0x18,0xba,0x86,0x00,0xef,0xb8,0x0c,0x00,0xba,0x82,0x00,0xef
-,0xba,0x02,0x00,0xed,0x25,0xf9,0xff,0x0d,0x02,0x00,0xef,0xba,0x06,0x00,0x33,0xc0
-,0xef,0xba,0x04,0x00,0xb8,0x60,0x00,0xef,0xba,0x00,0x00,0xb8,0x18,0x00,0xef,0xba
-,0x80,0x00,0xb9,0xff,0xff,0xed,0xa9,0x01,0x00,0x75,0x04,0xe2,0xf8,0xeb,0x3e,0xba
-,0x0a,0x00,0xed,0xa9,0x00,0x40,0x74,0x35,0xa9,0x00,0x20,0x74,0x30,0x33,0xc0,0xef
-,0x51,0xb9,0xc8,0x00,0xe2,0xfe,0x59,0x1e,0x06,0x1f,0x26,0x8b,0x0e,0x02,0x30,0x83
-,0xf9,0x17,0x75,0x18,0x49,0x49,0xbe,0x02,0x20,0xbf,0x06,0x30,0xf3,0xa6,0x1f,0x23
-,0xc9,0x75,0x0a,0xff,0x0e,0xfb,0x34,0x74,0x12,0xe9,0x4d,0xff,0x1f,0xb8,0x2c,0x00
-,0xbb,0x00,0x00,0xa3,0xf7,0x34,0x89,0x1e,0xf9,0x34,0xc3,0xc7,0x06,0xfb,0x34,0x64
-,0x00,0xe8,0xd3,0x00,0x72,0x0d,0xc7,0x06,0xf7,0x34,0x2c,0x00,0xc7,0x06,0xf9,0x34
-,0x04,0x00,0xc3,0xe8,0xd6,0x00,0xe8,0xf3,0x00,0xb8,0x03,0x00,0xba,0x82,0x00,0xef
-,0xb8,0x40,0x80,0xba,0x98,0x00,0xef,0xb8,0x00,0x11,0xba,0x96,0x00,0xef,0xb8,0x40
-,0x00,0xa9,0x01,0x00,0x74,0x01,0x40,0xba,0x92,0x00,0xef,0xb8,0x00,0x19,0xba,0x8e
-,0x00,0xef,0xba,0x02,0x00,0xed,0x25,0xf9,0xff,0x0d,0x06,0x00,0xef,0xba,0x06,0x00
-,0x33,0xc0,0xef,0xba,0x00,0x00,0xb8,0x18,0x00,0xef,0xba,0x80,0x00,0xb9,0xff,0xff
-,0xed,0xa9,0x20,0x00,0x75,0x04,0xe2,0xf8,0xeb,0x43,0xba,0x0a,0x00,0xed,0xa9,0x00
-,0x40,0x74,0x3a,0xa9,0x00,0x20,0x74,0x35,0x33,0xc0,0xef,0x51,0xb9,0xc8,0x00,0xe2
-,0xfe,0x59,0x1e,0x06,0x1f,0x26,0x8b,0x0e,0x02,0x32,0x83,0xf9,0x40,0x75,0x1d,0x49
-,0x49,0xbe,0x02,0x22,0xbf,0x06,0x32,0xf3,0xa6,0x1f,0x23,0xc9,0x75,0x0f,0xff,0x0e
-,0xfb,0x34,0x74,0x03,0xe9,0x5a,0xff,0xb8,0x00,0x00,0xeb,0x0b,0x1f,0xb8,0x2c,0x00
-,0xbb,0x02,0x00,0x89,0x1e,0xf9,0x34,0xa3,0xf7,0x34,0xc3,0xba,0x02,0x00,0xb8,0x00
-,0x9c,0xef,0xba,0x00,0x00,0xb8,0x00,0x84,0xef,0x33,0xc0,0xef,0xba,0x0a,0x00,0xef
-,0xba,0x0e,0x00,0x33,0xc0,0xef,0xc3,0xba,0x0a,0x00,0xb9,0xff,0xff,0xed,0x25,0x00
-,0x60,0x3d,0x00,0x60,0x74,0x04,0xe2,0xf5,0xf8,0xc3,0xf9,0xc3,0xb0,0x00,0xe6,0x56
-,0xb8,0x00,0xff,0xba,0x52,0x00,0xef,0xb9,0xff,0xff,0xba,0x58,0x00,0xed,0x25,0xef
-,0x00,0x74,0x08,0xba,0x5a,0x00,0x33,0xc0,0xef,0xe2,0xef,0xc3,0xba,0x80,0x00,0xed
-,0xba,0x84,0x00,0xef,0xba,0x80,0x00,0xed,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0xc6,0x06,0xec,0x34,0x15,0x33,0xc0,0x8e,0xd8,0x8e,0xc0,0x1e,0x8c,0xc8,0xbe,0x40
-,0x54,0xbf,0x60,0xfe,0x8e,0xd8,0xb9,0x10,0x00,0xf3,0xa4,0x1f,0xc7,0x06,0x80,0x36
-,0x10,0x35,0xc7,0x06,0x8c,0x36,0x30,0x35,0x8d,0x06,0x38,0x35,0xa3,0x30,0x35,0xa3
-,0x32,0x35,0x05,0x33,0x01,0xa3,0x34,0x35,0xc7,0x06,0x36,0x35,0x50,0x01,0xc7,0x06
-,0x84,0x36,0x80,0xfe,0xc7,0x06,0x88,0x36,0xc0,0xfe,0xc6,0x06,0xc2,0xfe,0xff,0xc6
-,0x06,0x93,0x36,0x80,0xc6,0x06,0x92,0x36,0x00,0xc6,0x06,0x80,0xfe,0x80,0xc7,0x06
-,0x82,0xfe,0x54,0x50,0xc7,0x06,0x84,0xfe,0x2b,0x4d,0xe5,0xce,0xa9,0x02,0x00,0x75
-,0x08,0xc6,0x06,0x81,0xfe,0x23,0xe9,0x05,0x00,0xc6,0x06,0x81,0xfe,0x22,0xa1,0xf7
-,0x34,0xa3,0x86,0xfe,0xb8,0x48,0x34,0x86,0xe0,0xa3,0x88,0xfe,0x8d,0x06,0x4e,0x34
-,0x86,0xe0,0xa3,0x8a,0xfe,0xb8,0x58,0x34,0x86,0xe0,0xa3,0x8c,0xfe,0xb8,0x9c,0x34
-,0x86,0xe0,0xa3,0x8e,0xfe,0x8d,0x06,0x20,0x03,0x86,0xe0,0xa3,0x90,0xfe,0x33,0xc0
-,0xba,0x72,0x00,0xef,0x33,0xc0,0xba,0x74,0x00,0xef,0xba,0x76,0x00,0xef,0xb8,0x80
-,0xfe,0x86,0xe0,0xba,0x72,0x00,0xef,0xe8,0xbf,0x07,0xba,0x0c,0x01,0xb8,0x40,0x40
-,0xef,0xed,0xba,0x6a,0x00,0xb8,0x03,0x00,0xc1,0xe0,0x08,0x0d,0x03,0x00,0xef,0xb9
-,0x0a,0x00,0xe8,0x94,0x00,0xba,0x6a,0x00,0xb8,0x03,0x00,0xc1,0xe0,0x08,0xef,0xa1
-,0x32,0x34,0xa3,0xa2,0x33,0xc7,0x06,0xa6,0x33,0x04,0x00,0x8d,0x06,0xa0,0x33,0xc1
-,0xe8,0x04,0xcd,0x39,0xc7,0x06,0x90,0x36,0xff,0xff,0xe9,0xe3,0x00,0x63,0x0d,0x66
-,0x0d,0x66,0x0d,0x8a,0x0d,0xe6,0x0e,0x75,0x12,0x2e,0x0f,0x03,0x0f,0x50,0x0f,0x60
-,0x0d,0x60,0x0d,0x60,0x0d,0xed,0x0f,0xe9,0x12,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60
-,0x0d,0x60,0x0d,0x22,0x10,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0xfe,0x10,0x60
-,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0xaf,0x0f,0x32,0x10,0x37
-,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60
-,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60,0x0d,0x60
-,0x0d,0x64,0x0e,0x00,0x0f,0x95,0x09,0x60,0x0a,0x49,0xbb,0xff,0xff,0xba,0x6a,0x00
-,0xed,0xa9,0x00,0x20,0x74,0x38,0x80,0x3e,0x80,0xfe,0x12,0x75,0x31,0xe8,0x4a,0x00
-,0xa1,0x32,0x34,0xa3,0xa2,0x33,0xc7,0x06,0xa6,0x33,0x04,0x00,0x8d,0x06,0xa0,0x33
-,0xc1,0xe8,0x04,0xcd,0x39,0xe8,0x22,0x00,0xc7,0x06,0xf3,0x34,0x46,0x00,0xc7,0x06
-,0xf5,0x34,0xff,0xff,0xc7,0x06,0x90,0x36,0xff,0xff,0x58,0xe9,0x32,0x00,0x4b,0x83
-,0xfb,0x00,0x75,0xb9,0x83,0xf9,0x00,0x75,0xb0,0xc3,0x52,0xba,0x6a,0x00,0xb8,0x03
-,0x00,0xc1,0xe0,0x08,0x0d,0x03,0x00,0xef,0x5a,0xc3,0x52,0xba,0x6a,0x00,0xb8,0x03
-,0x00,0xc1,0xe0,0x08,0xef,0x5a,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x68,0x80,0x07,0xa1,0x90,0x36,0xcd,0x35,0x8b,0x36,0x24,0x02,0x2e,0xff,0xa4,0x35
-,0x0a,0xfa,0x8a,0x26,0x94,0x36,0x88,0x26,0xe8,0x34,0xc6,0x06,0x94,0x36,0x00,0xfb
-,0x22,0xe4,0x75,0x01,0xc3,0xf6,0xc4,0x20,0x74,0x7d,0xf6,0xc4,0x08,0x74,0x05,0x80
-,0x0e,0x92,0x36,0x04,0x80,0x26,0xe8,0x34,0xd7,0xc4,0x1e,0x84,0x36,0x26,0x8b,0x37
-,0x81,0xe6,0xff,0x00,0x83,0xfe,0x20,0x76,0x05,0xb0,0x01,0xe9,0x28,0x00,0x53,0x06
-,0xd1,0xe6,0x2e,0xff,0x94,0x9d,0x06,0x07,0x5b,0x26,0x88,0x47,0x02,0x3c,0xff,0x74
-,0x07,0x3c,0xfe,0x75,0x11,0xe9,0x3b,0x00,0xf6,0x06,0x92,0x36,0x08,0x75,0x34,0xf6
-,0x06,0x92,0x36,0x04,0x74,0x2d,0x80,0x26,0x92,0x36,0xf3,0x80,0x3e,0x95,0x36,0x00
-,0x75,0x21,0x26,0x80,0x3f,0x05,0x75,0x13,0xc6,0x06,0x95,0x36,0x00,0x26,0x80,0x7f
-,0x06,0x00,0x74,0x07,0x26,0x8b,0x47,0x04,0xa2,0x95,0x36,0xba,0x0c,0x01,0xb8,0x40
-,0x40,0xef,0xed,0x8a,0x26,0xe8,0x34,0xf6,0xc4,0x10,0x75,0x03,0xe9,0x5b,0x00,0xf6
-,0xc4,0x04,0x74,0x05,0x80,0x0e,0x92,0x36,0x01,0x80,0x26,0xe8,0x34,0xeb,0xc4,0x3e
-,0x88,0x36,0x26,0x8b,0x35,0x83,0xe6,0x7f,0x83,0xfe,0x12,0x72,0x08,0x26,0xc6,0x45
-,0x02,0x01,0xe9,0x24,0x00,0x83,0xc6,0x20,0xd1,0xe6,0x2e,0xff,0x94,0x9d,0x06,0xc4
-,0x3e,0x88,0x36,0x26,0x88,0x45,0x02,0x3c,0xff,0x75,0x0e,0xf6,0x06,0x92,0x36,0x01
-,0x74,0x14,0xf6,0x06,0x92,0x36,0x02,0x75,0x0d,0x80,0x26,0x92,0x36,0xfc,0xba,0x0c
-,0x01,0xb8,0x20,0x20,0xef,0xed,0x8a,0x26,0xe8,0x34,0xf6,0xc4,0x08,0x74,0x22,0x80
-,0x26,0xe8,0x34,0xf7,0x80,0x0e,0x92,0x36,0x04,0xf6,0x06,0x92,0x36,0x08,0x74,0x11
-,0x80,0x26,0x92,0x36,0xf3,0xba,0x0c,0x01,0xb8,0x40,0x40,0xef,0xed,0x8a,0x26,0xe8
-,0x34,0xf6,0xc4,0x04,0x74,0x22,0x80,0x26,0xe8,0x34,0xfb,0x80,0x0e,0x92,0x36,0x01
-,0xf6,0x06,0x92,0x36,0x02,0x75,0x11,0x80,0x26,0x92,0x36,0xfe,0xba,0x0c,0x01,0xb8
-,0x20,0x20,0xef,0xed,0x8a,0x26,0xe8,0x34,0xf6,0xc4,0x01,0x74,0x67,0x80,0x26,0xe8
-,0x34,0xfe,0x80,0x3e,0xe8,0xff,0x00,0x74,0x39,0x80,0x3e,0xe8,0xff,0x04,0x74,0x32
-,0x80,0x3e,0xe8,0xff,0x01,0x75,0x21,0xe5,0x80,0xa9,0x00,0x07,0x74,0x0a,0xba,0x9e
-,0x00,0xb8,0x00,0x02,0xef,0xe9,0xef,0xff,0xc6,0x06,0xe8,0xff,0x03,0xba,0x0c,0x01
-,0xb8,0x08,0x08,0xef,0xed,0xe9,0x28,0x00,0x80,0x3e,0xe8,0xff,0x03,0x74,0x06,0xe9
-,0x1e,0x00,0xe9,0x00,0x00,0xba,0x10,0x01,0xb8,0x02,0x02,0xef,0xed,0xe5,0x00,0x0d
-,0x18,0x00,0xe7,0x00,0xe5,0x82,0x0d,0x02,0x00,0xe7,0x82,0xc6,0x06,0xe8,0xff,0x04
-,0x8a,0x26,0xe8,0x34,0xf6,0xc4,0x02,0x74,0x0d,0x80,0x26,0xe8,0x34,0xfd,0x80,0x26
-,0x92,0x36,0xbf,0xe8,0x4f,0x0b,0xfa,0xa0,0xe8,0x34,0x08,0x06,0x94,0x36,0xc6,0x06
-,0xe8,0x34,0x00,0xfb,0xc3,0xe8,0xe7,0x0f,0xc4,0x1e,0x84,0x36,0x2e,0xff,0x16,0x01
-,0x07,0x26,0x88,0x47,0x02,0xe9,0x7e,0xfe,0xe8,0x2d,0x10,0xc4,0x1e,0x84,0x36,0x2e
-,0xff,0x16,0x03,0x07,0x26,0x88,0x47,0x02,0xe9,0x6b,0xfe,0x8e,0x06,0x26,0x02,0x2e
-,0xff,0x16,0x07,0x07,0xc3,0xc3,0x83,0x3e,0xf5,0x34,0x00,0x74,0x0f,0xff,0x0e,0xf3
-,0x34,0x75,0x09,0xe8,0xc4,0xfd,0xc7,0x06,0xf5,0x34,0x00,0x00,0xf6,0x06,0x93,0x36
-,0x20,0x74,0x30,0xa1,0xc2,0x34,0x3b,0x06,0xe9,0x34,0xa3,0xe9,0x34,0x74,0x24,0x80
-,0x3e,0x95,0x36,0x00,0x75,0x1d,0xf7,0x06,0xe6,0x34,0x20,0x00,0x74,0x12,0xa9,0x20
-,0x00,0x74,0x0d,0x83,0x26,0xc2,0x34,0xdf,0x83,0x26,0xe9,0x34,0xdf,0xe9,0x03,0x00
-,0xe8,0xdd,0x09,0xba,0x06,0x01,0xed,0x8b,0xd0,0x81,0xe2,0x00,0xc0,0xc1,0xea,0x0e
-,0x03,0x16,0x74,0x34,0xc1,0xe0,0x02,0x11,0x06,0x72,0x34,0x73,0x04,0xff,0x06,0x74
-,0x34,0xba,0x02,0x01,0xed,0x8b,0xd0,0x81,0xe2,0x00,0xc0,0xc1,0xea,0x0e,0x03,0x16
-,0x70,0x34,0xc1,0xe0,0x02,0x11,0x06,0x6e,0x34,0x73,0x04,0xff,0x06,0x70,0x34,0xc7
-,0x06,0xa6,0x33,0x04,0x00,0xc7,0x06,0xaa,0x33,0x00,0x00,0x8d,0x06,0xa0,0x33,0xc1
-,0xe8,0x04,0xcd,0x39,0xc3,0x95,0x09,0x95,0x09,0x65,0x09,0x78,0x09,0x95,0x09,0x95
-,0x09,0x91,0x07,0x95,0x09,0x96,0x09,0x8b,0x09,0x95,0x09,0x95,0x09,0x95,0x09,0x95
-,0x09,0x95,0x09,0x95,0x09,0x8b,0xc0,0x8b,0xc0,0x8b,0xc0,0x8b,0xc0,0x8b,0xc0,0x90
-,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xe9,0xcc,0x00,0x8c,0xc0,0x40,0x8e,0xc0,0x26
-,0x8b,0x0e,0x06,0x00,0x86,0xe9,0x26,0x89,0x0e,0x06,0x00,0x8c,0xc2,0xc1,0xe2,0x04
-,0xbe,0x0e,0x00,0x26,0xa1,0x04,0x00,0xd0,0xe0,0x24,0xc0,0x8a,0xe0,0xc0,0xec,0x04
-,0x0a,0xc4,0x26,0xa2,0x05,0x00,0x26,0xa1,0x08,0x00,0xa9,0x00,0xc0,0x74,0x03,0xe9
-,0x9e,0x00,0x26,0xf6,0x06,0x10,0x00,0x80,0x75,0x03,0xe9,0x0a,0x00,0x26,0xa0,0x16
-,0x00,0x24,0x1f,0x32,0xe4,0x03,0xf0,0x80,0x3e,0xec,0x34,0x06,0x72,0x5c,0x80,0x3e
-,0x95,0x36,0x00,0x75,0x66,0x8b,0xfa,0x33,0xdb,0x8e,0xc3,0x26,0x89,0x1d,0x26,0x88
-,0x5d,0x04,0x51,0x50,0xc4,0x1e,0x8c,0x36,0xb9,0x0f,0x00,0x33,0xc0,0xe8,0x21,0x09
-,0x58,0x59,0x0b,0xdb,0x74,0x34,0xfe,0x0e,0xe6,0x3a,0x26,0xc6,0x07,0x81,0x26,0xc6
-,0x47,0x01,0x00,0x26,0xc6,0x47,0x02,0xff,0x26,0xc7,0x47,0x04,0x00,0x00,0x26,0x89
-,0x4f,0x0a,0x86,0xf2,0x26,0x89,0x57,0x06,0x26,0x89,0x77,0x08,0x26,0xc6,0x47,0x09
-,0x00,0x26,0xc6,0x47,0x0c,0x02,0xe8,0x8c,0x09,0xc3,0xff,0x06,0xec,0x33,0x8c,0xc0
-,0x48,0x8e,0xc0,0xfa,0xe8,0x97,0x10,0xfb,0xe9,0xeb,0xff,0x8c,0xc0,0x48,0x8e,0xc0
-,0xfa,0xe8,0x8a,0x10,0xfb,0xc3,0x8c,0xc0,0x8e,0xc0,0xfa,0xe8,0x80,0x10,0xfb,0xc3
-,0x80,0x3e,0x95,0x36,0x00,0x75,0x03,0xe9,0xc2,0x00,0xbf,0x08,0x00,0x26,0xf6,0x06
-,0x10,0x00,0x80,0x75,0x05,0x03,0xfe,0xe9,0x0c,0x00,0x26,0xa0,0x16,0x00,0x24,0x1f
-,0x32,0xe4,0x03,0xf0,0x03,0xfe,0xa0,0x95,0x36,0x3c,0x00,0x75,0x03,0xe9,0x9c,0x00
-,0x3c,0x01,0x74,0x0b,0x3c,0x02,0x74,0x14,0x3c,0x03,0x74,0x1d,0xe9,0x8d,0x00,0xc6
-,0x06,0x96,0x36,0x01,0xe8,0x3c,0x01,0x72,0x27,0xe9,0x80,0x00,0xc6,0x06,0x96,0x36
-,0x02,0xe8,0x83,0x00,0x72,0x1a,0xe9,0x73,0x00,0xc6,0x06,0x96,0x36,0x01,0xe8,0x22
-,0x01,0x72,0x0d,0xc6,0x06,0x96,0x36,0x02,0xe8,0x6c,0x00,0x72,0x03,0xe9,0x5c,0x00
-,0x53,0x06,0x50,0xc4,0x1e,0x8c,0x36,0xb9,0x0b,0x00,0x33,0xc0,0xe8,0x42,0x08,0x58
-,0x26,0xc6,0x07,0x82,0x26,0xc6,0x47,0x02,0xff,0x8d,0x06,0xe0,0xfe,0x86,0xc4,0x26
-,0x89,0x47,0x06,0xa0,0x96,0x36,0x26,0x88,0x47,0x08,0xe8,0xc8,0x08,0x07,0x5b,0x83
-,0x26,0xad,0x36,0xfe,0xa1,0xad,0x36,0xe7,0x04,0xba,0x10,0x01,0xb8,0x80,0x80,0xef
-,0xed,0xba,0x10,0x01,0xb8,0x02,0x02,0xef,0xed,0x52,0xba,0xe0,0x00,0xb8,0x41,0x10
-,0xef,0x5a,0xb8,0x9c,0x03,0xcd,0x39,0xc6,0x06,0x95,0x36,0x00,0x8c,0xc0,0x48,0x8e
-,0xc0,0xfa,0xe8,0xa9,0x0f,0xfb,0xc3,0x1e,0x06,0x1f,0x06,0x33,0xc0,0x8e,0xc0,0x8b
-,0xf0,0x8d,0x3e,0x20,0xf3,0x51,0xb1,0x0a,0x26,0x83,0x7d,0x0c,0x01,0x75,0x2a,0x57
-,0x26,0x83,0x7d,0x0e,0x00,0x74,0x06,0xe8,0x2f,0x00,0xe9,0x03,0x00,0xe8,0x66,0x07
-,0x5f,0x73,0x16,0x33,0xc0,0x8e,0xd8,0x26,0x8b,0x4d,0x12,0x8d,0x75,0x20,0x8d,0x3e
-,0xe0,0xfe,0xf3,0xa4,0x59,0x07,0x1f,0xf9,0xc3,0xfe,0xc9,0x74,0x07,0x81,0xc7,0x20
-,0x01,0xe9,0xc4,0xff,0x59,0x07,0x1f,0xf8,0xc3,0x51,0x50,0x53,0x56,0x52,0x57,0x33
-,0xdb,0x26,0x8a,0x5d,0x0e,0x26,0x8b,0x4d,0x12,0x8d,0x7d,0x20,0x5a,0x87,0xd7,0x26
-,0x8a,0x45,0x14,0x87,0xd7,0x42,0x32,0xff,0x80,0xff,0x08,0x75,0x08,0xfe,0xcb,0x22
-,0xdb,0x75,0xea,0x33,0xdb,0x23,0xdb,0x74,0x06,0xfe,0xc7,0xd0,0xc8,0x73,0x0c,0x50
-,0x26,0x8a,0x05,0x38,0x04,0x58,0x74,0x03,0xe9,0x0a,0x00,0x49,0x46,0x47,0x23,0xc9
-,0x74,0x0a,0xe9,0xd3,0xff,0x5a,0x5e,0x5b,0x58,0x59,0xf8,0xc3,0x5a,0x5e,0x5b,0x58
-,0x59,0xf9,0xc3,0x1e,0x06,0x1f,0x06,0x33,0xc0,0x8e,0xc0,0x86,0xcd,0x2b,0xce,0x8b
-,0xf7,0x8b,0xc1,0x33,0xc9,0x80,0x3c,0xff,0x74,0x16,0x80,0xf9,0x06,0x73,0x09,0x32
-,0xc9,0x46,0x48,0x74,0x2e,0xe9,0xed,0xff,0x3d,0x60,0x00,0x73,0x0c,0xe9,0x23,0x00
-,0xfe,0xc1,0x46,0x48,0x74,0x1d,0xe9,0xdc,0xff,0xb8,0x10,0x00,0x8d,0x3e,0x18,0x34
-,0x32,0xed,0xb1,0x06,0xf3,0xa6,0x74,0x03,0xe9,0x08,0x00,0x48,0x23,0xc0,0x74,0x07
-,0xe9,0xe9,0xff,0x07,0x1f,0xf8,0xc3,0x8d,0x36,0x18,0x34,0x33,0xc0,0x8e,0xd8,0x8d
-,0x3e,0xe0,0xfe,0xb8,0x10,0x00,0xb9,0x06,0x00,0x56,0xf3,0xa4,0x5e,0x48,0x3d,0x00
-,0x00,0x75,0xf3,0x07,0x1f,0xf9,0xc3,0xff,0x06,0xe4,0x33,0xc6,0x06,0xeb,0x34,0x00
-,0x26,0x8b,0x45,0x06,0x86,0xe0,0xc1,0xe8,0x04,0x48,0x06,0x8e,0xc0,0xfe,0x06,0xe6
-,0x3a,0xfa,0xe8,0x69,0x0e,0xfb,0x07,0xb0,0xff,0xc3,0x00,0x00,0x00,0x00,0x00,0x00
-,0xb0,0x01,0xc3,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3
-,0x8b,0x0e,0x97,0x36,0x81,0xe1,0x80,0x30,0x26,0x8b,0x47,0x04,0x25,0x7f,0xcf,0x0b
-,0xc1,0xa3,0x97,0x36,0xa3,0xe6,0x34,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x74
-,0x03,0xb0,0x03,0xc3,0x26,0x8b,0x47,0x08,0xa3,0x97,0x36,0xa3,0xe6,0x34,0x26,0x8a
-,0x47,0x20,0xa2,0xfd,0x34,0x3c,0x01,0x75,0x06,0xc7,0x06,0xa1,0x36,0x00,0x00,0x26
-,0x8a,0x47,0x21,0xa2,0xfe,0x34,0x26,0x8b,0x47,0x0a,0xa3,0x18,0x34,0xa3,0x58,0x34
-,0x26,0x8b,0x47,0x0c,0xa3,0x1a,0x34,0xa3,0x5a,0x34,0x26,0x8b,0x47,0x0e,0xa3,0x1c
-,0x34,0xa3,0x5c,0x34,0xc6,0x06,0x2a,0x34,0xc0,0x26,0x8b,0x47,0x14,0x25,0x7f,0xff
-,0x09,0x06,0x2c,0x34,0x26,0x8b,0x47,0x16,0x25,0xff,0xfe,0x25,0xff,0xfc,0x09,0x06
-,0x2e,0x34,0xc6,0x06,0x00,0x34,0xc0,0x26,0x8b,0x47,0x10,0xa3,0x02,0x34,0x26,0x8b
-,0x47,0x12,0xa3,0x04,0x34,0x06,0x53,0xe8,0x84,0x0a,0x5b,0x07,0x3d,0x00,0x00,0x75
-,0x07,0x80,0x0e,0x92,0x36,0x08,0xb0,0xfe,0xc3,0xb9,0x00,0x01,0xa1,0xac,0x33,0x33
-,0xd2,0xf7,0xf9,0xa3,0xae,0x33,0x91,0x49,0x33,0xd2,0xf7,0xe9,0x05,0x00,0x3b,0xa3
-,0x46,0x34,0xbf,0x00,0x3b,0x89,0x3e,0x44,0x34,0xba,0x68,0x00,0xb8,0xe0,0xe0,0xef
-,0xa1,0xae,0x33,0xe7,0x62,0xa1,0xae,0x33,0xba,0x08,0x01,0xef,0xa1,0x44,0x34,0xe7
-,0x64,0xa1,0x44,0x34,0xba,0x0a,0x01,0xef,0xb8,0x00,0x01,0x2d,0x04,0x00,0x0d,0x00
-,0x10,0xe7,0x92,0xc3,0x3d,0x00,0x00,0x74,0x0a,0x26,0x89,0x47,0x07,0xe8,0x83,0x3a
-,0xb0,0x07,0xc3,0xa1,0xae,0x33,0x26,0x89,0x47,0x2b,0xa1,0x44,0x34,0x26,0x89,0x47
-,0x2d,0xa1,0x46,0x34,0x26,0x89,0x47,0x2f,0x80,0x0e,0x93,0x36,0x20,0xa1,0x88,0x36
-,0x86,0xe0,0x26,0x89,0x47,0x08,0xa1,0x84,0x36,0x86,0xe0,0x26,0x89,0x47,0x0a,0xa1
-,0x80,0x36,0x86,0xe0,0x26,0x89,0x47,0x0c,0xb8,0x60,0xfe,0x86,0xe0,0x26,0x89,0x47
-,0x0e,0xa0,0xa1,0x36,0x26,0x88,0x47,0x10,0x8b,0x36,0x88,0x36,0x26,0xc6,0x44,0x02
-,0xff,0xe5,0x9e,0xa9,0x00,0x08,0x74,0x0c,0xba,0x84,0x00,0xed,0x0d,0x08,0x00,0xef
-,0xba,0x8e,0x00,0xef,0xe5,0x02,0x25,0xf9,0xff,0xe7,0x02,0xba,0x10,0x01,0xb8,0x02
-,0x02,0xef,0xed,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x01,0xc3
-,0x80,0x26,0x93,0x36,0x9f,0xe8,0x8d,0x0a,0x80,0x0e,0x92,0x36,0x08,0xb0,0xfe,0xc3
-,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0xc6,0x06,0x2a
-,0x34,0xc0,0x26,0x8b,0x47,0x06,0x25,0x7f,0xff,0xa3,0x2c,0x34,0x26,0x8b,0x47,0x08
-,0x25,0xff,0xfe,0x25,0xff,0xfc,0xa3,0x2e,0x34,0xcd,0x52,0xb0,0x00,0xc3,0xf6,0x06
-,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0xc6,0x06,0x00,0x34,0xc0,0x26,0x8b,0x47
-,0x06,0xa3,0x02,0x34,0x26,0x8b,0x47,0x08,0xa3,0x04,0x34,0xcd,0x52,0xb0,0x00,0xc3
-,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0x57,0x8d,0x7f,0x06,0x51,0xb9
-,0x07,0x00,0x33,0xc0,0xf3,0xab,0x59,0x8d,0x7f,0x06,0xa1,0x7a,0x34,0x03,0x06,0x39
-,0x37,0x26,0x88,0x05,0xa1,0x95,0x37,0x26,0x88,0x45,0x02,0xa1,0x80,0x34,0x03,0x06
-,0x76,0x34,0x26,0x88,0x45,0x07,0xa1,0xc6,0x34,0x26,0x88,0x45,0x09,0xa1,0xd8,0x33
-,0x26,0x88,0x45,0x0a,0x33,0xc0,0xa3,0x7a,0x34,0xa3,0x39,0x37,0xa3,0x95,0x37,0xa3
-,0x80,0x34,0xa3,0x76,0x34,0xa3,0xc6,0x34,0xa3,0xd8,0x33,0x5f,0xb0,0x00,0xc3,0xf6
-,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0x26,0x8b,0x4f,0x04,0x83,0xf9,0x06
-,0x74,0x12,0x83,0xf9,0x04,0x74,0x0d,0x83,0xf9,0x00,0x74,0x08,0x83,0xf9,0x02,0x74
-,0x03,0xb0,0x01,0xc3,0x89,0x0e,0xe8,0x3a,0x83,0x26,0xab,0x36,0xf9,0x09,0x0e,0xab
-,0x36,0xe5,0x02,0x25,0xf9,0xff,0x0b,0xc1,0xe7,0x02,0xb0,0x00,0xc3,0xf6,0x06,0x93
-,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0x26,0x8b,0x4f,0x04,0x80,0xf9,0xff,0x74,0x08
-,0x80,0xf9,0x00,0x74,0x10,0xb0,0x01,0xc3,0x83,0x0e,0xad,0x36,0x02,0xa1,0xad,0x36
-,0xe7,0x04,0xe9,0x0a,0x00,0x83,0x26,0xad,0x36,0xfd,0xa1,0xad,0x36,0xe7,0x04,0xb0
-,0x00,0xc3,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x04,0xc3,0xe8,0xd5,0x04,0xb0
-,0x00,0xc3,0xf6,0x06,0x93,0x36,0x80,0x75,0x03,0xb0,0x01,0xc3,0x26,0x83,0x7f,0x06
-,0x05,0x75,0x03,0xe9,0x9d,0x00,0x26,0x8b,0x57,0x04,0x26,0x8b,0x47,0x08,0x26,0x81
-,0x7f,0x06,0x00,0x80,0x75,0x08,0xed,0x26,0x89,0x47,0x0a,0xe9,0x9d,0x00,0x26,0x83
-,0x7f,0x06,0x01,0x75,0x04,0xef,0xe9,0x92,0x00,0x26,0x81,0x7f,0x06,0x01,0x80,0x75
-,0x09,0xef,0xed,0x26,0x89,0x47,0x0a,0xe9,0x81,0x00,0x26,0x83,0x7f,0x06,0x02,0x75
-,0x07,0x26,0x21,0x47,0x04,0xe9,0x73,0x00,0x26,0x81,0x7f,0x06,0x02,0x80,0x75,0x0c
-,0x26,0x21,0x47,0x04,0xed,0x26,0x89,0x47,0x0a,0xe9,0x5f,0x00,0x26,0x83,0x7f,0x06
-,0x03,0x75,0x07,0x26,0x09,0x47,0x04,0xe9,0x51,0x00,0x26,0x81,0x7f,0x06,0x03,0x80
-,0x75,0x0c,0x26,0x09,0x47,0x04,0xed,0x26,0x89,0x47,0x0a,0xe9,0x3d,0x00,0x26,0x83
-,0x7f,0x06,0x04,0x75,0x07,0x26,0x31,0x47,0x04,0xe9,0x2f,0x00,0x26,0x81,0x7f,0x06
-,0x04,0x80,0x75,0x0c,0x26,0x31,0x47,0x04,0xed,0x26,0x89,0x47,0x0a,0xe9,0x1b,0x00
-,0xb0,0x01,0xc3,0xfa,0x53,0x26,0x8b,0x4f,0x08,0x0b,0xc9,0x74,0x0c,0x8d,0x1e,0xe0
-,0xfe,0xe8,0x52,0xff,0x83,0xc3,0x08,0xe2,0xf8,0x5b,0xfb,0xb0,0x00,0xc3,0xf6,0x06
-,0x93,0x36,0x80,0x75,0x0a,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xb0,0x01,0xc3,0x8d
-,0x3e,0xe0,0xfe,0xe5,0x00,0x26,0x89,0x05,0xe5,0x02,0x26,0x89,0x45,0x02,0xa1,0xad
-,0x36,0x26,0x89,0x45,0x04,0xe5,0x06,0x26,0x89,0x45,0x06,0xe5,0x08,0x26,0x89,0x45
-,0x08,0xe5,0x0a,0x26,0x89,0x45,0x0a,0xe5,0x0e,0x26,0x89,0x45,0x0c,0xe5,0x48,0x26
-,0x89,0x45,0x0e,0xe5,0x4a,0x26,0x89,0x45,0x10,0xe5,0x4c,0x26,0x89,0x45,0x12,0xa1
-,0xb7,0x36,0x26,0x89,0x45,0x14,0xe5,0x50,0x26,0x89,0x45,0x16,0xe5,0x52,0x26,0x89
-,0x45,0x18,0xe5,0x54,0x26,0x89,0x45,0x1a,0xe5,0x56,0x26,0x89,0x45,0x1c,0xe5,0x58
-,0x26,0x89,0x45,0x1e,0xe5,0x62,0x26,0x89,0x45,0x20,0xe5,0x64,0x26,0x89,0x45,0x22
-,0xe5,0x66,0x26,0x89,0x45,0x24,0xe5,0x68,0x26,0x89,0x45,0x26,0xe5,0x6a,0x26,0x89
-,0x45,0x28,0xe5,0x6c,0x26,0x89,0x45,0x2a,0xe5,0x70,0x26,0x89,0x45,0x2c,0xe5,0x72
-,0x26,0x89,0x45,0x2e,0xe5,0x74,0x26,0x89,0x45,0x30,0xe5,0x76,0x26,0x89,0x45,0x32
-,0xe5,0x7c,0x26,0x89,0x45,0x34,0xe5,0x7e,0x26,0x89,0x45,0x36,0xe5,0x80,0x26,0x89
-,0x45,0x38,0xe5,0x82,0x26,0x89,0x45,0x3a,0xe5,0x86,0x26,0x89,0x45,0x3c,0xe5,0x88
-,0x26,0x89,0x45,0x3e,0xe5,0x9a,0x26,0x89,0x45,0x40,0xe5,0x9e,0x26,0x89,0x45,0x42
-,0xe5,0xcc,0x26,0x89,0x45,0x44,0xe5,0xce,0x26,0x89,0x45,0x46,0xe5,0xd0,0x26,0x89
-,0x45,0x48,0xe5,0xd2,0x26,0x89,0x45,0x4a,0xba,0x00,0x01,0xed,0x11,0x06,0x66,0x34
-,0x73,0x04,0xff,0x06,0x68,0x34,0x26,0x89,0x45,0x4c,0xba,0x02,0x01,0xed,0xc1,0xe0
-,0x02,0x11,0x06,0x6e,0x34,0x73,0x04,0xff,0x06,0x70,0x34,0x26,0x89,0x45,0x4e,0xba
-,0x04,0x01,0xed,0x11,0x06,0x6a,0x34,0x73,0x04,0xff,0x06,0x6c,0x34,0x26,0x89,0x45
-,0x50,0xba,0x06,0x01,0xed,0xc1,0xe0,0x02,0x11,0x06,0x72,0x34,0x73,0x04,0xff,0x06
-,0x74,0x34,0x26,0x89,0x45,0x52,0xba,0x08,0x01,0xed,0x26,0x89,0x45,0x54,0xba,0x0a
-,0x01,0xed,0x26,0x89,0x45,0x56,0xba,0x0c,0x01,0xed,0x26,0x89,0x45,0x58,0xba,0x0e
-,0x01,0xed,0x01,0x06,0x7a,0x34,0x26,0x89,0x45,0x5e,0xba,0x10,0x01,0xed,0x26,0x89
-,0x45,0x5c,0xb0,0x00,0xc3,0xf6,0x06,0x93,0x36,0x80,0x74,0x07,0xf6,0x06,0x93,0x36
-,0x20,0x75,0x03,0xb0,0x01,0xc3,0x26,0x80,0x7f,0x06,0x00,0x75,0x30,0x80,0x3e,0x95
-,0x36,0x00,0x74,0x52,0xc6,0x06,0x95,0x36,0x00,0x83,0x26,0xad,0x36,0xfe,0xa1,0xad
-,0x36,0xe7,0x04,0xba,0x10,0x01,0xb8,0x80,0x80,0xef,0xed,0xba,0x10,0x01,0xb8,0x02
-,0x02,0xef,0xed,0xba,0xe0,0x00,0xb8,0x00,0x10,0xef,0xb0,0x00,0xc3,0x26,0x8b,0x47
-,0x04,0x3d,0x00,0x00,0x74,0x20,0x3d,0x03,0x00,0x77,0x1b,0xba,0x10,0x01,0xb8,0x02
-,0x00,0xef,0xba,0xe0,0x00,0xb8,0x01,0x10,0xef,0x83,0x0e,0xad,0x36,0x01,0xa1,0xad
-,0x36,0xe7,0x04,0xb0,0x00,0xc3,0xb0,0x06,0xc3,0xf6,0x06,0x93,0x36,0x80,0x75,0x03
-,0xb0,0x01,0xc3,0x26,0x83,0x7f,0x04,0x01,0x74,0x0a,0x26,0x83,0x7f,0x04,0x02,0x74
-,0x19,0xb0,0x06,0xc3,0x26,0x83,0x7f,0x06,0x0c,0x77,0xf6,0x26,0x83,0x7f,0x0a,0x60
-,0x77,0xef,0xe8,0x10,0x00,0x72,0x0b,0xb0,0x46,0xc3,0xe8,0x4e,0x00,0x72,0x03,0xb0
-,0x46,0xc3,0xb0,0x00,0xc3,0x51,0xb1,0x0a,0x8b,0x3e,0x20,0xf3,0x26,0x83,0x7d,0x0c
-,0x02,0x75,0x03,0xe9,0x0e,0x00,0xfe,0xc9,0x74,0x07,0x81,0xc7,0x20,0x01,0xe9,0xeb
-,0xff,0x59,0xf8,0xc3,0x57,0x8d,0x7d,0x0e,0x8d,0x77,0x06,0xb9,0x12,0x00,0xf3,0xa4
-,0x8d,0x7d,0x20,0x8d,0x36,0xe0,0xfe,0x26,0x8b,0x4d,0x12,0xf3,0xa4,0xff,0x06,0x01
-,0x35,0x5f,0x26,0xc7,0x45,0x0c,0x01,0x00,0x59,0xf9,0xc3,0x51,0xb1,0x0a,0x8d,0x3e
-,0x20,0xf3,0x8d,0x36,0xe0,0xfe,0x26,0x83,0x7d,0x0c,0x01,0x75,0x1b,0x57,0xe8,0x25
-,0x00,0x5f,0x73,0x14,0x33,0xc0,0xb9,0x20,0x01,0xf3,0xaa,0x26,0xc7,0x45,0x0c,0x02
-,0x00,0xff,0x0e,0x01,0x35,0x59,0xf9,0xc3,0xfe,0xc9,0x74,0x07,0x81,0xc7,0x20,0x01
-,0xe9,0xd3,0xff,0x59,0xf8,0xc3,0x51,0x26,0x8b,0x4d,0x12,0x8d,0x7d,0x20,0xf3,0xa6
-,0x74,0x03,0x59,0xf8,0xc3,0x59,0xf9,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x80,0x3e,0xec,0x34,0x06,0x72,0x33,0xff,0x06,0xf0,0x33,0x50,0xc4,0x1e,0x8c,0x36
-,0xb9,0x0f,0x00,0x33,0xc0,0xe8,0x29,0x00,0x58,0x81,0x26,0xc2,0x34,0xdf,0x7f,0x81
-,0x26,0xe9,0x34,0xdf,0x7f,0x0b,0xdb,0x74,0x11,0x26,0xc6,0x07,0x84,0x26,0xc6,0x47
-,0x02,0xff,0x26,0x89,0x47,0x06,0xe8,0xac,0x00,0xc3,0xff,0x06,0xea,0x33,0xe9,0xf5
-,0xff,0x57,0x26,0x8b,0x3f,0x03,0xf9,0x26,0x3b,0x7f,0x02,0x74,0x16,0x26,0x3b,0x7f
-,0x04,0x7c,0x2a,0x3d,0x00,0x00,0x75,0x13,0x8d,0x7f,0x08,0x03,0xf9,0x26,0x3b,0x7f
-,0x02,0x7c,0x14,0xff,0x06,0xde,0x33,0x33,0xdb,0x5f,0xc3,0x26,0x8b,0x7f,0x02,0x26
-,0x89,0x3f,0x03,0xf9,0xe9,0x06,0x00,0x26,0x89,0x3f,0x26,0x29,0x0f,0x26,0xc7,0x05
-,0xff,0xff,0x26,0x87,0x3f,0x26,0x89,0x0d,0x8d,0x5d,0x02,0x50,0x8b,0xfb,0x83,0xe9
-,0x02,0x33,0xc0,0xf3,0xaa,0x58,0xfe,0x0e,0xec,0x34,0x5f,0xc3,0x8b,0x7c,0x02,0x3b
-,0x3c,0x74,0x2f,0x83,0x3d,0xff,0x75,0x0b,0x8d,0x7c,0x08,0x89,0x7c,0x02,0x83,0x3d
-,0xff,0x74,0x1e,0x8a,0x45,0x02,0x3c,0x81,0x75,0x0c,0x80,0x3e,0xeb,0x34,0x00,0x74
-,0x05,0x33,0xc0,0xe9,0x0b,0x00,0x8b,0x0d,0x01,0x4c,0x02,0x8d,0x75,0x02,0x83,0xe9
-,0x02,0xc3,0x80,0x3e,0xec,0x34,0x06,0x72,0x05,0x33,0xc0,0xe9,0xf3,0xff,0xff,0x06
-,0xee,0x33,0xe9,0xbe,0xff,0xf6,0x06,0x92,0x36,0x40,0x74,0x01,0xc3,0x57,0x56,0x51
-,0x52,0x8b,0x36,0x8c,0x36,0xe8,0xa4,0xff,0x75,0x03,0xe9,0x1a,0x00,0xe9,0x1c,0x00
-,0xfe,0x06,0xec,0x34,0xc4,0x3e,0x80,0x36,0xf3,0xa4,0x80,0x0e,0x92,0x36,0x40,0xba
-,0x0c,0x01,0xb8,0x80,0x80,0xef,0xed,0x5a,0x59,0x5e,0x5f,0xc3,0xff,0x06,0xe0,0x33
-,0x80,0x3c,0x81,0x75,0x0c,0xff,0x06,0xe2,0x33,0xc6,0x06,0xeb,0x34,0x01,0xe9,0xcf
-,0xff,0x80,0x3c,0x84,0x75,0x07,0xff,0x06,0xe6,0x33,0xe9,0xc3,0xff,0xff,0x06,0xe8
-,0x33,0xe9,0xbc,0xff,0x8d,0x3e,0xe0,0xfe,0xa1,0x72,0x34,0xc7,0x06,0x72,0x34,0x00
-,0x00,0x89,0x05,0xa1,0x74,0x34,0xc7,0x06,0x74,0x34,0x00,0x00,0x89,0x45,0x02,0xba
-,0x04,0x01,0xed,0x89,0x45,0x04,0xc7,0x45,0x06,0x00,0x00,0xa1,0x6e,0x34,0xc7,0x06
-,0x6e,0x34,0x00,0x00,0x89,0x45,0x08,0xa1,0x70,0x34,0xc7,0x06,0x70,0x34,0x00,0x00
-,0x89,0x45,0x0a,0xba,0x00,0x01,0xed,0x89,0x45,0x0c,0xc7,0x45,0x0e,0x00,0x00,0x32
-,0xe4,0xba,0x0e,0x01,0xec,0x89,0x45,0x10,0xa1,0x7e,0x34,0xc7,0x06,0x7e,0x34,0x00
-,0x00,0x89,0x45,0x12,0xa1,0x8c,0x34,0xc7,0x06,0x8c,0x34,0x00,0x00,0x89,0x45,0x14
-,0xa1,0x8a,0x34,0xc7,0x06,0x8a,0x34,0x00,0x00,0x89,0x45,0x16,0xa1,0x7c,0x34,0xc7
-,0x06,0x7c,0x34,0x00,0x00,0x89,0x45,0x18,0xa1,0x88,0x34,0xc7,0x06,0x88,0x34,0x00
-,0x00,0x89,0x45,0x1a,0xa1,0xca,0x33,0xc7,0x06,0xca,0x33,0x00,0x00,0x89,0x45,0x1c
-,0xa1,0x78,0x34,0xc7,0x06,0x78,0x34,0x00,0x00,0x89,0x45,0x1e,0xa1,0xc6,0x34,0xc7
-,0x06,0xc6,0x34,0x00,0x00,0x89,0x45,0x20,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0xfa,0x33,0xc0,0x8e,0xd8,0x8e,0xc0,0xb8,0xa0,0x01,0xc1,0xe8,0x04,0x8e,0xd0,0x8d
-,0x26,0x80,0x00,0xe8,0x00,0x01,0xe8,0x10,0xeb,0x8b,0x1e,0xf7,0x34,0x8b,0x16,0xf9
-,0x34,0x8b,0x36,0xff,0x34,0x33,0xc0,0xb9,0xef,0xff,0x8d,0x3e,0x14,0x00,0x2b,0xcf
-,0x2b,0xce,0xd1,0xe9,0xf3,0xab,0x89,0x1e,0xf7,0x34,0x89,0x16,0xf9,0x34,0x83,0xfe
-,0x00,0x74,0x0c,0xb9,0xef,0xff,0xbf,0x80,0xfe,0x2b,0xcf,0xd1,0xe9,0xf3,0xab,0xb9
-,0xff,0xff,0x81,0xe9,0x00,0x3b,0x83,0xfe,0x00,0x74,0x03,0xe9,0x1b,0x00,0x51,0x1e
-,0xb8,0x00,0xe0,0x8e,0xd8,0x33,0xf6,0x8d,0x3e,0x00,0xd8,0xb9,0x00,0x0c,0xf3,0xa5
-,0x1f,0x59,0xbe,0xff,0xff,0x81,0xee,0x00,0xd8,0x2b,0xce,0x81,0xe1,0x00,0xff,0x89
-,0x0e,0xac,0x33,0x8d,0x06,0x20,0x02,0xc1,0xe8,0x04,0xa3,0x32,0x34,0x8e,0xd0,0x36
-,0xc7,0x06,0x1e,0x00,0x80,0x18,0x36,0xc7,0x06,0x22,0x00,0xff,0x7f,0x36,0xc7,0x06
-,0x0a,0x00,0xff,0xff,0x36,0xc7,0x06,0x1c,0x00,0x80,0x00,0x8d,0x06,0xa0,0x02,0xc1
-,0xe8,0x04,0xa3,0x30,0x34,0x8e,0xd0,0x36,0xc7,0x06,0x1e,0x00,0x50,0x28,0x36,0xc7
-,0x06,0x0a,0x00,0xff,0xff,0x36,0xc7,0x06,0x1c,0x00,0x80,0x00,0xb8,0xa0,0x01,0xc1
-,0xe8,0x04,0xa3,0x34,0x34,0xa3,0xf2,0x33,0x8e,0xd0,0x8d,0x26,0x80,0x00,0xb8,0x00
-,0x90,0xe7,0x02,0x8d,0x3e,0x70,0x01,0x8b,0xc7,0xc1,0xe8,0x04,0xb9,0x03,0x00,0x89
-,0x45,0x0e,0x89,0x45,0x02,0xc7,0x05,0xff,0xff,0x83,0xc7,0x10,0x05,0x01,0x00,0xe2
-,0xee,0xe8,0x5b,0x01,0xe5,0xce,0xa3,0xb5,0x36,0xe8,0x21,0x00,0xe8,0x45,0x01,0xa1
-,0x32,0x34,0x8c,0xcb,0xcd,0x37,0x0e,0x58,0xa9,0x00,0xf0,0x74,0x07,0x33,0xf6,0x89
-,0x36,0xff,0x34,0xc3,0x8d,0x36,0x30,0x61,0x89,0x36,0xff,0x34,0xc3,0x33,0xc0,0x8b
-,0xd0,0x8b,0xf2,0xb9,0x68,0x00,0x2e,0x80,0xbc,0xac,0x17,0x80,0x75,0x01,0xef,0x83
-,0xc2,0x02,0x46,0xe2,0xf1,0xb8,0x02,0x00,0xe7,0x50,0xb9,0x5a,0x00,0x33,0xff,0xc7
-,0x05,0x65,0x18,0x8c,0x4d,0x02,0x83,0xc7,0x04,0xe2,0xf4,0x33,0xc0,0x8e,0xc0,0x8c
-,0xc8,0x8e,0xd8,0x8d,0x3e,0x80,0x00,0x8d,0x36,0x9c,0x17,0xb9,0x08,0x00,0xe8,0x37
-,0x00,0x8d,0x36,0x20,0x21,0x8d,0x3e,0xc0,0x00,0xb9,0x0d,0x00,0xe8,0x29,0x00,0x8d
-,0x3e,0x40,0x01,0xb9,0x0a,0x00,0xe8,0x1f,0x00,0xe8,0x4b,0x0e,0x33,0xc0,0x8e,0xd8
-,0xc7,0x06,0x4e,0x37,0x6f,0x17,0xe7,0x48,0xe7,0x4c,0xb8,0x40,0x9c,0xe7,0x4a,0xe5
-,0x48,0x90,0xb8,0x00,0x70,0xe7,0x48,0xc3,0xa5,0x83,0xc7,0x02,0xe2,0xfa,0xc3,0xe5
-,0x4c,0xc3,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe5,0x58,0xd1
-,0xe0,0x73,0x11,0x8b,0xf0,0xd1,0xe6,0x33,0xc0,0x8e,0xd8,0x8b,0xb4,0x80,0x00,0x83
-,0xc6,0x0b,0xff,0xe6,0x1f,0x07,0x5a,0x5f,0x5e,0x59,0x58,0xcf,0x58,0x1c,0xe4,0x1c
-,0x6c,0x1c,0x8e,0x1a,0xc0,0x1f,0x40,0x1a,0x44,0x1c,0x65,0x18,0x80,0x80,0x80,0xff
-,0x80,0x03,0x02,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
-,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
-,0x80,0x03,0x03,0x43,0x80,0x80,0x02,0x80,0x42,0x03,0x02,0xff,0x03,0x01,0x03,0x01
-,0x01,0x03,0x02,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x03,0x01,0x03
-,0x03,0xff,0x01,0x01,0xff,0x01,0xff,0x01,0x01,0x03,0x03,0x03,0xff,0xff,0xff,0xff
-,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
-,0xff,0xff,0xff,0x02,0xb8,0x0f,0x00,0xe7,0x84,0xb8,0x0f,0xf8,0xe7,0x82,0xc3,0xb9
-,0x08,0x00,0x89,0x0e,0xe6,0x3a,0x8d,0x06,0x20,0x03,0x8b,0xd0,0xc1,0xe8,0x04,0xa3
-,0x90,0x01,0x8b,0xc2,0x8b,0xd8,0xc1,0xe8,0x04,0x8e,0xc0,0x05,0x61,0x00,0x26,0xa3
-,0x00,0x00,0xa1,0x30,0x34,0x26,0xa3,0x02,0x00,0x83,0xc3,0x14,0xd1,0xeb,0x26,0x89
-,0x1e,0x08,0x00,0x81,0xc2,0x10,0x06,0xe2,0xd9,0x26,0xc7,0x06,0x00,0x00,0xff,0xff
-,0x8c,0x06,0x92,0x01,0xc3,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8
-,0xe7,0x5a,0xff,0x06,0xbe,0x33,0xba,0xd2,0x00,0xed,0xcf,0x00,0x00,0x00,0x00,0x00
-,0x8c,0xcb,0xa1,0x30,0x34,0xcd,0x37,0xe9,0x06,0xed,0xb8,0x32,0x00,0xc3,0xe8,0x8c
-,0x01,0xfe,0x06,0xe2,0x34,0xe8,0x21,0x01,0x75,0xf0,0xe8,0x53,0x0e,0x81,0x0e,0xaf
-,0x36,0x00,0xc0,0xc7,0x06,0xad,0x36,0x60,0x00,0xf7,0x06,0xe6,0x34,0x80,0x00,0x75
-,0x1a,0xf7,0x06,0xe6,0x34,0x00,0x08,0x74,0x09,0xc7,0x06,0xab,0x36,0x0b,0x00,0xe9
-,0x0f,0x00,0xc7,0x06,0xab,0x36,0x03,0x00,0xe9,0x06,0x00,0xc7,0x06,0xab,0x36,0x11
-,0x9c,0xc7,0x06,0xa9,0x36,0x18,0x00,0xf7,0x06,0xe6,0x34,0x80,0x00,0x75,0x0d,0xf7
-,0x06,0xb5,0x36,0x02,0x00,0x74,0x05,0x83,0x0e,0xa9,0x36,0x20,0xa1,0xa9,0x36,0xe7
-,0x00,0xa1,0xab,0x36,0xe7,0x02,0xf7,0x06,0xe6,0x34,0x80,0x00,0x74,0x2e,0xe8,0xf2
-,0x2f,0x33,0xc0,0x0d,0x41,0x00,0xe7,0x56,0xa1,0xb1,0x36,0x0d,0x00,0x10,0xe7,0x08
-,0xa1,0xb3,0x36,0xe7,0x0a,0xa1,0xaf,0x36,0xe7,0x06,0xb8,0x40,0x00,0xe7,0x4e,0x33
-,0xc0,0xe7,0x0e,0xc7,0x06,0x26,0x02,0x00,0x00,0xe9,0x23,0x00,0xc7,0x06,0x4e,0x37
-,0x3f,0x20,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x80,0x74,0x07,0x26
-,0x81,0x0e,0x08,0x00,0x00,0x80,0xc6,0x06,0xe0,0x34,0x01,0xb8,0x00,0x00,0xc3,0xfe
-,0x06,0xe1,0x34,0xc6,0x06,0xe0,0x34,0x00,0xa1,0x26,0x02,0x0b,0xc0,0x74,0x01,0xc3
-,0xe8,0x04,0x00,0xb8,0x00,0x00,0xc3,0xa1,0xa9,0x36,0xe7,0x00,0x8b,0x1e,0xab,0x36
-,0x83,0xe3,0x06,0xe5,0x02,0x25,0xf9,0xff,0x0b,0xc3,0x0d,0x10,0x00,0xe7,0x02,0xa1
-,0xad,0x36,0xe7,0x04,0xc3,0xb8,0x0a,0x00,0xe7,0x84,0xfe,0x06,0xe5,0x34,0xc6,0x06
-,0xe3,0x34,0x01,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x40,0x74,0x07
-,0x26,0x81,0x0e,0x08,0x00,0x00,0x40,0xc3,0xc7,0x06,0x4e,0x37,0x6f,0x17,0xfe,0x06
-,0xe4,0x34,0xc6,0x06,0xe3,0x34,0x00,0xc3,0xc3,0xf6,0x06,0x18,0x34,0x80,0x75,0x0d
-,0xa1,0x18,0x34,0x0b,0x06,0x1a,0x34,0x0b,0x06,0x1c,0x34,0x75,0x01,0xc3,0xa1,0x2e
-,0x34,0x25,0xff,0xfe,0x8b,0x16,0xe7,0x36,0x81,0xe2,0x00,0x01,0x0b,0xc2,0xa3,0x2e
-,0x34,0x8d,0x16,0x10,0x00,0xbf,0x00,0x00,0xb9,0x08,0x00,0x8b,0x85,0x00,0x34,0xef
-,0x83,0xc2,0x10,0x8b,0x85,0x02,0x34,0xef,0x83,0xc2,0x10,0x8b,0x85,0x04,0x34,0xef
-,0x83,0xc2,0xe2,0x83,0xc7,0x06,0x49,0x75,0xe2,0xb8,0x00,0x00,0x8e,0xc0,0xbe,0x00
-,0x34,0xbf,0xb9,0x36,0xb9,0x18,0x00,0xf3,0xa5,0xb8,0x00,0x00,0xc3,0x33,0xc0,0x8e
-,0xc0,0x8d,0x3e,0xb0,0x33,0xb9,0x08,0x00,0xf3,0xab,0x8d,0x3e,0x3e,0x34,0xb9,0x03
-,0x00,0xf3,0xab,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xba
-,0x33,0xe5,0x56,0x0d,0x20,0x00,0xe7,0x56,0xba,0x7a,0x00,0xed,0x08,0x26,0x94,0x36
-,0x33,0xc0,0xb1,0x08,0x32,0xed,0x06,0x8e,0xc0,0x8d,0x3e,0xe0,0xff,0xf3,0xaa,0x8e
-,0x06,0x32,0x34,0x26,0x81,0x0e,0x08,0x00,0x00,0x02,0x07,0xe5,0x56,0x25,0xdf,0xff
-,0xe7,0x56,0xe9,0xf8,0xfc,0x00,0xbd,0x1b,0x10,0x1b,0xd9,0x1a,0xf3,0x1a,0x50,0x51
-,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xb6,0x33,0x53
-,0x06,0x51,0xe5,0x80,0xa3,0xb4,0x33,0x8b,0xd8,0x8b,0xc8,0x25,0x10,0x00,0xa3,0xed
-,0x34,0x0b,0xc0,0x74,0x14,0xff,0x06,0x80,0x34,0x80,0x3e,0xfe,0x34,0x00,0x74,0x03
-,0xe9,0x06,0x00,0xb8,0x80,0x00,0xe8,0x9d,0x04,0x83,0xe3,0x03,0xd1,0xe3,0x2e,0xff
-,0x97,0x86,0x1a,0x59,0x07,0x5b,0xe9,0xa4,0xfc,0xba,0x20,0x00,0x8e,0x06,0x3c,0x34
-,0x83,0x3e,0x3c,0x34,0x00,0x75,0x03,0xe9,0xf0,0x00,0xc7,0x06,0x3c,0x34,0x00,0x00
-,0xe9,0x2a,0x00,0xba,0x10,0x00,0x8e,0x06,0x3a,0x34,0x83,0x3e,0x3a,0x34,0x00,0x75
-,0x03,0xe9,0xd5,0xff,0xc7,0x06,0x3a,0x34,0x00,0x00,0xe8,0x10,0x00,0xe9,0xc9,0xff
-,0xba,0x10,0x00,0x8e,0x06,0x3a,0x34,0xc7,0x06,0x3a,0x34,0x00,0x00,0x26,0xa1,0x14
-,0x00,0x26,0xa3,0x0c,0x00,0x26,0xa1,0x16,0x00,0x26,0xa3,0x0e,0x00,0x26,0xc6,0x06
-,0x0a,0x00,0x00,0xc1,0xea,0x02,0x23,0xd1,0x74,0x1c,0xba,0x20,0x00,0x26,0xc7,0x06
-,0x0e,0x00,0xea,0x05,0x26,0x0b,0x16,0x0c,0x00,0x26,0x89,0x16,0x0c,0x00,0xff,0x06
-,0x86,0x34,0xff,0x06,0xdc,0x33,0x26,0xa1,0x0c,0x00,0xa9,0x00,0x37,0x74,0x16,0x26
-,0xc6,0x06,0x0a,0x00,0x02,0xa9,0x00,0x30,0x74,0x04,0xff,0x06,0x7a,0x34,0xff,0x06
-,0xda,0x33,0xe9,0x49,0x00,0xc0,0xec,0x07,0x83,0x16,0x8a,0x34,0x00,0x24,0x07,0x3c
-,0x07,0x75,0x04,0xff,0x06,0x8c,0x34,0xff,0x06,0x7e,0x34,0xa1,0x30,0x34,0x8c,0xc3
-,0x8e,0xc0,0x8e,0xdb,0x26,0x83,0x0e,0x08,0x00,0x40,0x8c,0xd8,0x26,0x87,0x06,0x16
-,0x00,0x26,0x83,0x3e,0x14,0x00,0xff,0x74,0x0a,0x8e,0xc0,0x26,0x8c,0x1e,0x00,0x00
-,0xe9,0x05,0x00,0x26,0x8c,0x1e,0x14,0x00,0x33,0xc0,0x8e,0xd8,0xc3,0xc3,0x8c,0xc0
-,0x87,0x06,0x92,0x01,0x3d,0xff,0xff,0x74,0x0d,0x8e,0xd8,0x8c,0x06,0x00,0x00,0x33
-,0xc0,0x8e,0xd8,0xe9,0x04,0x00,0x8c,0x06,0x90,0x01,0xe8,0x01,0x00,0xc3,0x06,0x83
-,0x3e,0x90,0x01,0xff,0x74,0x29,0x83,0x3e,0x3a,0x34,0x00,0x75,0x11,0xba,0x86,0x00
-,0xe8,0x1e,0x00,0x8c,0x06,0x3a,0x34,0x83,0x3e,0x90,0x01,0xff,0x74,0x11,0x83,0x3e
-,0x3c,0x34,0x00,0x75,0x0a,0xba,0x88,0x00,0xe8,0x06,0x00,0x8c,0x06,0x3c,0x34,0x07
-,0xc3,0xa1,0x90,0x01,0x8e,0xc0,0x26,0xa1,0x08,0x00,0xef,0x26,0xa1,0x00,0x00,0x26
-,0xc7,0x06,0x00,0x00,0xff,0xff,0xa3,0x90,0x01,0x3d,0xff,0xff,0x75,0x03,0xa3,0x92
-,0x01,0x83,0x3e,0xed,0x34,0x00,0x74,0x0b,0xb8,0x10,0x00,0xe7,0x84,0xc7,0x06,0xed
-,0x34,0x00,0x00,0xc3,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7
-,0x5a,0xff,0x06,0xbc,0x33,0xe9,0x25,0xfb,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33
-,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xb0,0x33,0xe9,0x11,0xfb,0x50,0x51,0x56,0x57
-,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xb4,0x33,0x06,0xff,0x06
-,0x76,0x34,0x80,0x3e,0xfe,0x34,0x00,0x74,0x04,0x07,0xe9,0xf0,0xfa,0xb8,0x80,0x00
-,0xe8,0xd3,0x02,0x07,0xe9,0xe6,0xfa,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0xc6,0x1d,0x08,0x1d,0x91,0x1e,0x5d,0x1e,0x73,0x1e,0x89,0x1e,0x91,0x1e,0xa8,0x1d
-,0x91,0x1e,0x91,0x1e,0xaf,0x1e,0xaf,0x1e,0x15,0x1d,0x15,0x1d,0x91,0x1e,0x99,0x1f
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00
-,0x00,0x01,0x00,0x10,0x00,0x01,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00
-,0x07,0xe9,0x99,0xfa,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7
-,0x5a,0xff,0x06,0xb2,0x33,0x06,0x68,0xf6,0x1c,0xe5,0x06,0xa3,0xb2,0x33,0x8b,0xf0
-,0x83,0xe6,0x1e,0x2e,0xff,0xa4,0xa0,0x1c,0xe5,0x0c,0xa9,0x80,0x00,0x74,0x06,0xe8
-,0xa4,0x01,0xe5,0x06,0xc3,0x53,0xe5,0x0c,0x8b,0xd8,0xa9,0x01,0x00,0x74,0x14,0x83
-,0x3e,0xe0,0x3a,0x00,0x74,0x0d,0x8e,0x06,0x38,0x34,0xe8,0xbf,0x06,0xc7,0x06,0xe0
-,0x3a,0x00,0x00,0xe5,0x00,0x0d,0x18,0x00,0xe7,0x00,0xe5,0x02,0x0d,0x11,0x00,0xe7
-,0x02,0x8b,0xc3,0x5b,0xa9,0x01,0x00,0x74,0x01,0xc3,0x8b,0xd0,0xb8,0x00,0x08,0xe7
-,0x84,0x8b,0xc2,0x8e,0x06,0x38,0x34,0x26,0xa3,0x0c,0x00,0x8b,0xd0,0xc1,0xe0,0x03
-,0x83,0x16,0x88,0x34,0x00,0xff,0x06,0x7c,0x34,0x26,0x83,0x3e,0x06,0x00,0x0a,0x75
-,0x21,0x8b,0xc2,0x25,0x40,0x18,0x3d,0x40,0x00,0x74,0x0c,0x3d,0x00,0x10,0x75,0x12
-,0x26,0xfe,0x0e,0x0a,0x00,0x74,0x0b,0xf7,0x06,0xef,0x34,0x20,0x00,0x75,0x03,0xe9
-,0x5a,0x06,0x8c,0xc0,0x26,0x8e,0x06,0x02,0x00,0x26,0x83,0x0e,0x08,0x00,0x20,0x26
-,0xa3,0x12,0x00,0x26,0xa3,0x10,0x00,0xc3,0xff,0x06,0xc4,0x33,0xe5,0x0c,0xa9,0x01
-,0x00,0x75,0x01,0xc3,0xa9,0xf0,0x07,0x74,0x01,0xc3,0xff,0x06,0xd4,0x33,0xe5,0x00
-,0x0d,0x18,0x00,0xe7,0x00,0xc3,0xff,0x06,0xca,0x33,0x80,0x3e,0xa0,0x36,0x08,0x75
-,0x14,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x08,0x74,0x07,0x26,0x81
-,0x0e,0x08,0x00,0x00,0x08,0xe5,0x82,0x25,0xfd,0xff,0xe7,0x82,0xe5,0x0c,0x50,0xe5
-,0x80,0x25,0x00,0x07,0xa3,0xe4,0x3a,0xe5,0x8c,0x25,0x00,0x80,0xa3,0xe2,0x3a,0x58
-,0xa9,0x02,0x00,0x75,0x25,0x83,0x3e,0xe2,0x3a,0x00,0x75,0x1e,0x83,0x3e,0xe4,0x3a
-,0x00,0x75,0x17,0xe5,0x08,0x0d,0x00,0x04,0x25,0xff,0x04,0xe7,0x08,0xe8,0x6a,0x01
-,0xe5,0x82,0x0d,0x02,0x00,0xe7,0x82,0xe9,0x21,0x00,0xe8,0x1a,0x06,0x80,0x3e,0xe8
-,0xff,0x00,0x74,0x0a,0x80,0x3e,0xe8,0xff,0x04,0x74,0x03,0xe9,0x0d,0x00,0xc6,0x06
-,0xe8,0xff,0x01,0xba,0x0c,0x01,0xb8,0x08,0x08,0xef,0xed,0x80,0x3e,0x9f,0x36,0x06
-,0x75,0x05,0x83,0x0e,0x99,0x36,0x40,0xb8,0x00,0x01,0xe9,0x09,0x01,0xff,0x06,0xcc
-,0x33,0x81,0x26,0xaf,0x36,0xff,0xf7,0xa1,0xaf,0x36,0xe7,0x06,0xff,0x06,0xc6,0x34
-,0xe9,0x1e,0x00,0xff,0x06,0xce,0x33,0xff,0x06,0x95,0x37,0x81,0x26,0xaf,0x36,0xff
-,0xef,0xa1,0xaf,0x36,0xe7,0x06,0xe9,0x08,0x00,0xff,0x06,0xd0,0x33,0xff,0x06,0x7a
-,0x34,0xff,0x06,0xd2,0x33,0xd1,0xe6,0x8e,0x06,0x30,0x34,0x2e,0x8b,0x84,0xc0,0x1c
-,0x26,0x09,0x06,0x08,0x00,0x2e,0x8b,0x84,0xc2,0x1c,0x09,0x06,0x66,0x37,0xc3,0xe5
-,0x0c,0xa9,0x80,0x00,0x74,0x56,0x50,0xe8,0xf0,0x00,0x58,0xa9,0x00,0x01,0x75,0x07
-,0xff,0x06,0xc6,0x33,0xe9,0x08,0x00,0xff,0x06,0x78,0x34,0xff,0x06,0xc8,0x33,0xe5
-,0x82,0x25,0xfd,0xff,0xe7,0x82,0xe8,0x6e,0x05,0xba,0x10,0x01,0xed,0x80,0x3e,0xe8
-,0xff,0x00,0x74,0x0a,0x80,0x3e,0xe8,0xff,0x04,0x74,0x03,0xe9,0x1d,0x00,0xc6,0x06
-,0xe8,0xff,0x01,0xba,0x0c,0x01,0xb8,0x08,0x08,0xef,0xed,0xe9,0x0d,0x00,0xc6,0x06
-,0xe8,0xff,0x03,0xba,0x0c,0x01,0xb8,0x08,0x08,0xef,0xed,0xc3,0xa9,0x01,0x00,0x74
-,0x1c,0xe8,0x2c,0x00,0x83,0x3e,0xe0,0x3a,0x00,0x74,0x0f,0x06,0x8e,0x06,0x38,0x34
-,0xe8,0xc9,0x04,0xc7,0x06,0xe0,0x3a,0x00,0x00,0x07,0xe9,0x5d,0x00,0x8b,0xd0,0x8e
-,0x06,0x38,0x34,0x26,0xa3,0x0c,0x00,0xe8,0x06,0x00,0x68,0x69,0x1d,0xe9,0x4a,0x00
-,0xa9,0x00,0x04,0x74,0x0a,0xb8,0x00,0x04,0xff,0x06,0xd8,0x33,0xe9,0x17,0x00,0xa9
-,0x00,0x01,0x74,0x0a,0xff,0x06,0x39,0x37,0xb8,0x00,0x01,0xe9,0x08,0x00,0xa9,0x10
-,0x00,0xb8,0x10,0x00,0x74,0x1d,0x09,0x06,0x66,0x37,0x8c,0xc0,0x8e,0x06,0x30,0x34
-,0x26,0xf7,0x06,0x0a,0x00,0x00,0x01,0x74,0x07,0x26,0x81,0x0e,0x08,0x00,0x00,0x01
-,0x8e,0xc0,0xc3,0xff,0x06,0xc2,0x33,0xe9,0xf8,0xff,0xe5,0x00,0x0d,0x18,0x00,0xe7
-,0x00,0xe5,0x02,0x0d,0x11,0x00,0xe7,0x02,0xc3,0x58,0xe9,0x43,0xfd,0xe5,0x08,0x0d
-,0x00,0x04,0x25,0xff,0x04,0xe7,0x08,0xe9,0xe0,0xff,0xe5,0x0e,0xa9,0x00,0x08,0x75
-,0x01,0xc3,0xe9,0xf5,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x50,0x51,0x56,0x57,0x52,0x06,0x1e,0x33,0xc0,0x8e,0xd8,0xe7,0x5a,0xff,0x06,0xb8
-,0x33,0xe5,0x48,0x06,0x53,0x57,0xff,0x16,0x4e,0x37,0x5f,0x5b,0x83,0x3e,0x80,0x01
-,0xff,0x74,0x58,0x8e,0x06,0x80,0x01,0x26,0xff,0x0e,0x08,0x00,0x75,0x4d,0x26,0xa1
-,0x00,0x00,0xa3,0x80,0x01,0x26,0xc7,0x06,0x00,0x00,0xff,0xff,0x8c,0xc0,0x26,0x8e
-,0x06,0x02,0x00,0x26,0x81,0x0e,0x08,0x00,0x80,0x00,0x8b,0xd0,0x26,0x87,0x06,0x1a
-,0x00,0x26,0x83,0x3e,0x18,0x00,0xff,0x74,0x0a,0x8e,0xc0,0x26,0x89,0x16,0x00,0x00
-,0xe9,0x05,0x00,0x26,0x89,0x16,0x18,0x00,0x83,0x3e,0x80,0x01,0xff,0x74,0x0c,0x8e
-,0x06,0x80,0x01,0x26,0x83,0x3e,0x08,0x00,0x00,0x74,0xb3,0x07,0xe9,0x3e,0xf7,0xe5
-,0x4c,0x90,0xe5,0x02,0xa9,0x00,0x20,0x74,0x0d,0x25,0xff,0xdf,0x0d,0x01,0x00,0xe7
-,0x02,0x0d,0x00,0x20,0xe7,0x02,0xe5,0x0a,0x8b,0xd8,0xa3,0xf4,0x33,0x25,0xc3,0x57
-,0x0d,0x00,0x10,0xe7,0x0a,0xf7,0x06,0x9b,0x36,0x00,0x80,0x74,0x37,0xf7,0xc3,0x00
-,0x80,0x74,0x06,0xf7,0xc3,0x00,0x08,0x74,0x5d,0x81,0x26,0xc2,0x34,0x7f,0xff,0xc7
-,0x06,0x35,0x37,0x05,0x00,0xb8,0x80,0x03,0xcd,0x39,0x81,0x26,0x9b,0x36,0xff,0x7f
-,0xc7,0x06,0x0f,0x37,0x04,0x00,0xf7,0x06,0x9b,0x36,0x40,0x00,0x75,0x06,0xc7,0x06
-,0x0f,0x37,0x03,0x00,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x2a,0xf7,0xc3,0x00,0x08
-,0x74,0x24,0x80,0x3e,0x9d,0x36,0x06,0x7c,0x1d,0xff,0x06,0x94,0x34,0x83,0x0e,0x66
-,0x37,0x20,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x01,0x74,0x07,0x26
-,0x81,0x0e,0x08,0x00,0x00,0x01,0xf7,0xc3,0x00,0x20,0x75,0x3b,0xf7,0x06,0x9a,0x37
-,0x80,0x00,0x74,0x0b,0xff,0x06,0x89,0x37,0x33,0xc0,0xe7,0x0e,0xe9,0x04,0x00,0xff
-,0x06,0x3b,0x37,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x1c,0x80,0x26,0x9e,0x36,0xff
-,0x75,0x15,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x08,0x74,0x07,0x26
-,0x81,0x0e,0x08,0x00,0x00,0x08,0xc3,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x02,0x23,0x02,0x23,0x02,0x23,0x02,0x23,0x03,0x23,0xdd,0x22,0x02,0x23,0xfd,0x21
-,0x02,0x23,0xa4,0x24,0xf3,0x24,0x02,0x23,0x8d,0x22,0x7a,0x23,0x02,0x23,0x97,0x24
-,0x1b,0x24,0x75,0x24,0x02,0x23,0x02,0x23,0x8e,0x25,0xfb,0x8e,0x06,0x7e,0x01,0xfb
-,0x26,0x83,0x3e,0x00,0x00,0xff,0x74,0xf2,0x26,0x8e,0x06,0x00,0x00,0xfa,0x26,0x8b
-,0x1e,0x08,0x00,0x26,0x23,0x1e,0x0a,0x00,0x74,0xe5,0x8c,0xc0,0x8e,0xd0,0x26,0x8b
-,0x26,0x02,0x00,0x8c,0x16,0xf2,0x33,0x22,0xff,0x75,0x6a,0x26,0xa1,0x1c,0x00,0x8a
-,0xe3,0x8a,0xdc,0x22,0xd8,0x75,0x0d,0xd0,0xe8,0x24,0xf8,0x0a,0xc0,0x75,0xf2,0xb0
-,0x80,0xe9,0xed,0xff,0xd0,0xe8,0x24,0xf8,0x0a,0xc0,0x75,0x02,0xb0,0x80,0x32,0xe4
-,0x26,0xa3,0x1c,0x00,0xf7,0xc3,0x08,0x00,0x75,0x47,0x2e,0x8a,0x9f,0xc5,0x25,0x2e
-,0x8b,0xbf,0xc5,0x26,0x80,0xc3,0x10,0x26,0x8e,0x1d,0x26,0x8c,0x1e,0x06,0x00,0x8b
-,0x16,0x00,0x00,0xc7,0x06,0x00,0x00,0xff,0xff,0x26,0x89,0x15,0x83,0xfa,0xff,0x75
-,0x0a,0x2e,0x8b,0x97,0xcd,0x26,0x26,0x21,0x16,0x08,0x00,0x33,0xc0,0x8e,0xd8,0x26
-,0x89,0x1e,0x04,0x00,0xc3,0x8a,0xdf,0xb7,0x00,0x2e,0x8a,0x9f,0xc5,0x25,0xe9,0xe0
-,0xff,0x26,0x83,0x26,0x08,0x00,0xf7,0x83,0xc3,0x10,0xe9,0xde,0xff,0x60,0x06,0x1e
-,0x68,0x87,0x25,0x6a,0x00,0x1f,0x8e,0x06,0xf2,0x33,0x8b,0x0e,0x34,0x34,0x39,0x0e
-,0xf2,0x33,0x74,0x0e,0x26,0x81,0x0e,0x0a,0x00,0x00,0x02,0x26,0x81,0x0e,0x08,0x00
-,0x00,0x02,0x26,0x89,0x26,0x02,0x00,0xa3,0xf2,0x33,0x8e,0xd0,0x8d,0x26,0x80,0x00
-,0x36,0x89,0x26,0x02,0x00,0x36,0x89,0x1e,0x20,0x00,0x36,0xc7,0x06,0x08,0x00,0x00
-,0x00,0xb9,0x04,0x00,0xbe,0x00,0x00,0x2e,0x8b,0xbc,0xc5,0x26,0x36,0xc7,0x05,0xff
-,0xff,0x36,0xc7,0x45,0x02,0xff,0xff,0x83,0xc6,0x02,0xe2,0xeb,0x8e,0x06,0x7e,0x01
-,0x36,0x8b,0x0e,0x22,0x00,0x8c,0xc0,0x26,0x83,0x3e,0x00,0x00,0xff,0x26,0x8e,0x06
-,0x00,0x00,0x74,0x07,0x26,0x3b,0x0e,0x22,0x00,0x7d,0xea,0x36,0x8c,0x06,0x00,0x00
-,0x8e,0xc0,0x26,0x8c,0x16,0x00,0x00,0xfb,0x36,0xff,0x2e,0x1e,0x00,0x06,0x1e,0x68
-,0x8b,0x25,0x6a,0x00,0x1f,0x26,0x09,0x36,0x08,0x00,0xf7,0xc6,0x00,0xff,0x74,0x01
-,0xc3,0x56,0x52,0x2e,0x8b,0xb4,0xc5,0x25,0x81,0xe6,0xff,0x00,0x2e,0x8b,0xb4,0xc5
-,0x26,0x8c,0xc2,0x8e,0xc0,0x26,0xc7,0x06,0x00,0x00,0xff,0xff,0x8e,0xc2,0x26,0x83
-,0x3c,0xff,0x74,0x0f,0x8b,0xd0,0x26,0x87,0x54,0x02,0x8e,0xc2,0x26,0xa3,0x00,0x00
-,0xe9,0x07,0x00,0x26,0x89,0x44,0x02,0x26,0x89,0x04,0x5a,0x5e,0xc3,0x06,0x1e,0x68
-,0x8b,0x25,0x6a,0x00,0x1f,0x8e,0x06,0xf2,0x33,0x26,0xa3,0x0a,0x00,0x26,0x89,0x26
-,0x02,0x00,0xa1,0x34,0x34,0x8e,0xd0,0x8d,0x26,0x80,0x00,0x8c,0x16,0xf2,0x33,0xe9
-,0x4d,0xfe,0xcf,0x50,0x1e,0x52,0x53,0x33,0xc0,0x8e,0xd8,0x26,0x83,0x3e,0x04,0x00
-,0xff,0x26,0xc7,0x06,0x04,0x00,0x00,0x00,0x74,0x03,0xe9,0x1a,0x00,0x83,0x3e,0xe6
-,0x3a,0x02,0x76,0x13,0xff,0x06,0xd6,0x33,0x8c,0xc0,0x8e,0x06,0x32,0x34,0xbe,0x40
-,0x00,0x68,0x3a,0x23,0xe9,0x5e,0xff,0xe8,0x84,0xf8,0x5b,0x5a,0x1f,0x58,0xcf,0xe8
-,0xe1,0x00,0x26,0xc6,0x06,0x18,0x00,0x10,0x26,0x8a,0x1e,0x29,0x00,0x88,0x1e,0x1b
-,0x37,0x26,0xc7,0x06,0x0c,0x00,0xff,0x7f,0x26,0xa1,0x0e,0x00,0xe7,0x9c,0x26,0xa1
-,0x08,0x00,0xe7,0x9a,0xe5,0x00,0x80,0xfb,0x08,0x74,0x09,0x0d,0x18,0xac,0xe7,0x00
-,0x07,0x1f,0x58,0xcf,0x0d,0x18,0x00,0xe9,0xf4,0xff,0x50,0x1e,0x06,0x33,0xc0,0x8e
-,0xd8,0x83,0x3e,0xa1,0x36,0x00,0x75,0xb7,0x26,0x8b,0x36,0x06,0x00,0x2e,0xff,0x94
-,0xdc,0x23,0x07,0x1f,0x58,0xcf,0xe8,0x8a,0x00,0xe5,0x00,0x0d,0x18,0x00,0xe7,0x00
-,0xe8,0x49,0x00,0xc3,0x53,0xf7,0x06,0xef,0x34,0x20,0x00,0x75,0x2d,0xe5,0x8c,0x25
-,0x00,0x70,0x8b,0xd8,0xe5,0x8c,0x25,0x00,0x70,0x3b,0xc3,0x74,0x05,0x8b,0xd8,0xe9
-,0xf2,0xff,0x3d,0x00,0x30,0x75,0x10,0xe5,0x02,0x25,0xef,0xff,0xe7,0x02,0xc7,0x06
-,0xe0,0x3a,0xff,0xff,0xe9,0x03,0x00,0xe8,0x12,0x00,0x5b,0xc3,0xa3,0x23,0x96,0x23
-,0xa4,0x23,0xa4,0x23,0x96,0x23,0xa4,0x23,0x96,0x23,0x96,0x23,0x26,0xa0,0x29,0x00
-,0xa2,0x1b,0x37,0x26,0xc7,0x06,0x0c,0x00,0xff,0x7f,0x26,0xa1,0x0e,0x00,0xe7,0x9c
-,0x26,0xa1,0x08,0x00,0xe7,0x9a,0xe5,0x00,0x25,0xff,0x53,0x26,0x8b,0x36,0x06,0x00
-,0x83,0xe6,0x0e,0x2e,0x0b,0x84,0xad,0x25,0xe7,0x00,0xc3,0x06,0x1e,0x68,0x8b,0x25
-,0x6a,0x00,0x1f,0x83,0x0e,0xef,0x34,0x20,0x83,0x0e,0x9b,0x36,0x08,0xe5,0x00,0x25
-,0xef,0xff,0x0d,0x08,0x00,0xe7,0x00,0xe5,0x00,0xa9,0x10,0x00,0x75,0x01,0xc3,0xe5
-,0x00,0xa9,0x10,0x00,0x75,0xf9,0xc3,0x50,0x53,0x51,0x56,0x06,0x1e,0x33,0xc0,0x8e
-,0xd8,0xb8,0x05,0x00,0xe7,0x84,0xe5,0x08,0x0d,0x00,0x04,0x25,0xff,0x04,0xe7,0x08
-,0xe5,0x00,0x0d,0x18,0x00,0xe7,0x00,0xe5,0x02,0x0d,0x11,0x00,0xe7,0x02,0x1f,0x07
-,0x5e,0x59,0x5b,0x58,0xc3,0x50,0x1e,0x33,0xc0,0x8e,0xd8,0xc7,0x06,0xef,0x34,0x00
-,0x00,0x83,0x26,0x9b,0x36,0xf7,0xe5,0x00,0x0d,0x18,0x00,0xe7,0x00,0xe5,0x02,0x0d
-,0x11,0x00,0xe7,0x02,0x1f,0x58,0xcf,0x60,0x06,0x1e,0x68,0x87,0x25,0x6a,0x00,0x1f
-,0xe8,0x16,0xf5,0xc3,0x06,0x1e,0x68,0x8b,0x25,0x6a,0x00,0x1f,0x8e,0xc0,0x26,0x83
-,0x3e,0x0a,0x00,0x00,0x74,0x03,0xe8,0x43,0x00,0x26,0xc7,0x06,0x0a,0x00,0xff,0xff
-,0x26,0x8b,0x16,0x06,0x00,0x8e,0x1e,0x8e,0x01,0x8c,0xd8,0x8b,0xca,0x83,0x3e,0x00
-,0x00,0xff,0x8e,0x1e,0x00,0x00,0x74,0x0a,0x2b,0x16,0x08,0x00,0x73,0xeb,0x29,0x0e
-,0x08,0x00,0x26,0x89,0x0e,0x08,0x00,0x26,0x8c,0x1e,0x00,0x00,0x8e,0xd8,0x8c,0x06
-,0x00,0x00,0xc3,0x60,0x06,0x1e,0x68,0x87,0x25,0x6a,0x00,0x1f,0x8e,0xc0,0x8b,0xc8
-,0x8e,0x1e,0x8e,0x01,0x26,0xc7,0x06,0x0a,0x00,0x00,0x00,0x8c,0xd8,0x83,0x3e,0x00
-,0x00,0xff,0x74,0x25,0x3b,0x0e,0x00,0x00,0x8e,0x1e,0x00,0x00,0x75,0xed,0x8e,0xd8
-,0x26,0xa1,0x00,0x00,0xa3,0x00,0x00,0x3d,0xff,0xff,0x74,0x56,0x8e,0xd8,0x26,0xa1
-,0x08,0x00,0x01,0x06,0x08,0x00,0xe9,0x49,0x00,0x26,0x8e,0x1e,0x02,0x00,0xbe,0x18
-,0x00,0x83,0x3c,0xff,0x74,0x3c,0x39,0x0c,0x74,0x19,0x8e,0x1c,0xbe,0x00,0x00,0x83
-,0x3e,0x00,0x00,0xff,0x74,0x2c,0x39,0x0e,0x00,0x00,0x74,0x07,0x8e,0x1e,0x00,0x00
-,0xe9,0xec,0xff,0x26,0xa1,0x00,0x00,0x89,0x04,0x33,0xc9,0x8e,0xd9,0x3d,0xff,0xff
-,0x75,0x10,0x83,0xfe,0x18,0x75,0x0b,0x26,0x8e,0x1e,0x02,0x00,0x81,0x26,0x08,0x00
-,0x7f,0xff,0x33,0xc0,0x8e,0xd8,0xc3,0x1f,0x07,0x61,0xcf,0x1f,0x07,0xcf,0x60,0x06
-,0x1e,0x68,0x87,0x25,0x6a,0x00,0x1f,0xe5,0x06,0x25,0x1e,0x00,0x3d,0x1e,0x00,0x75
-,0xf6,0xb9,0x08,0x00,0xe5,0x58,0xe7,0x5a,0x23,0xc0,0xe0,0xf8,0xc3,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x00,0x00,0x00,0xa8,0x00,0x8c,0x02,0x04,0x00
-,0x00,0x08,0x10,0x20,0x00,0xff,0x0e,0x0c,0x0c,0x0a,0x0a,0x0a,0x0a,0x08,0x08,0x08
-,0x08,0x08,0x08,0x08,0x08,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06
-,0x06,0x06,0x06,0x06,0x06,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
-,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
-,0x04,0x04,0x04,0x04,0x04,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02
-,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02
-,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02
-,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02
-,0x02,0x02,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x14,0x00,0x10,0x00,0x0c,0x00,0xff,0x7f,0xff
-,0xbf,0xff,0xdf,0xff,0xef,0xff,0xf7,0xff,0xfb,0xff,0xfd,0xff,0xfe,0x7f,0xff,0xbf
-,0xff,0xdf,0xff,0xef,0xff,0xf7,0xff,0xfb,0xff,0xfd,0xff,0xfe,0xff,0x00,0x00,0x00
-,0x80,0x3e,0xe2,0x34,0x01,0x76,0x03,0xe9,0xa5,0x00,0xb8,0x00,0x00,0xe7,0x4e,0xb9
-,0x28,0x00,0xe2,0xfe,0xc6,0x06,0x45,0x37,0x02,0xbf,0x3f,0x28,0x2e,0x8b,0x45,0x08
-,0xe7,0x4e,0xb9,0x28,0x00,0xe2,0xfe,0x2e,0x8b,0x1d,0xc7,0x06,0xb3,0x36,0x40,0x11
-,0xc7,0x06,0xb1,0x36,0x27,0x00,0xc7,0x06,0x46,0x37,0x02,0x00,0xc7,0x06,0x48,0x37
-,0x64,0x00,0xf7,0x06,0xb5,0x36,0x02,0x00,0x75,0x1c,0x2e,0x0b,0x5d,0x02,0x81,0x26
-,0xb3,0x36,0xff,0xfe,0xc7,0x06,0xb1,0x36,0x9c,0x00,0xc7,0x06,0x46,0x37,0x08,0x00
-,0xc7,0x06,0x48,0x37,0x90,0x01,0x89,0x1e,0xb7,0x36,0x89,0x1e,0xfe,0x33,0xbe,0x20
-,0x00,0x8b,0xc3,0xe7,0x4e,0xb9,0x28,0x00,0xe2,0xfe,0x2e,0x8b,0x45,0x04,0xe7,0x4e
-,0xb9,0x28,0x00,0xe2,0xfe,0xe5,0x4e,0x8b,0xcb,0x2e,0x23,0x45,0x06,0x2e,0x23,0x4d
-,0x06,0x3a,0xc1,0x74,0x36,0x4e,0x75,0xd9,0x80,0x3e,0x45,0x37,0x00,0x74,0x0b,0xc6
-,0x06,0x45,0x37,0x00,0xbf,0x2f,0x28,0xe9,0x72,0xff,0xc6,0x06,0x45,0x37,0x01,0xf7
-,0x06,0xb5,0x36,0x02,0x00,0x74,0x14,0xe5,0xce,0x25,0xfd,0xff,0xe7,0xce,0xe8,0x43
-,0x00,0xe5,0xce,0x0d,0x02,0x00,0xe7,0xce,0xe8,0x39,0x00,0x80,0x3e,0xe2,0x34,0x01
-,0x76,0x01,0xc3,0xb8,0xea,0x05,0xe7,0x8c,0xfa,0xe8,0x12,0xf4,0xfb,0x8d,0x06,0xd0
-,0x39,0x8b,0xd8,0xc1,0xe8,0x04,0xa3,0x38,0x34,0x8e,0xc0,0xa1,0x30,0x34,0x26,0xa3
-,0x02,0x00,0x26,0xc7,0x06,0x00,0x00,0xff,0xff,0x83,0xc3,0x18,0xd1,0xeb,0x26,0x89
-,0x1e,0x08,0x00,0xc3,0xe5,0x02,0x0d,0x00,0x40,0xe7,0x02,0xe5,0x00,0x0d,0x04,0x00
-,0xe7,0x00,0xb8,0x00,0x00,0xe7,0x0a,0xe5,0x0a,0xa9,0x00,0x80,0x75,0x14,0xe5,0x08
-,0x0d,0x00,0x10,0xe7,0x08,0xe5,0x0a,0x0d,0x00,0x08,0xb9,0x05,0x00,0xe7,0x0a,0xe2
-,0xfc,0xc3,0xe5,0x08,0x0d,0x00,0x10,0xb9,0x05,0x00,0xe7,0x08,0xe2,0xfc,0xc3,0x04
-,0x0c,0x20,0x00,0x01,0x0c,0x7e,0xff,0x00,0x0c,0x02,0x00,0x10,0x00,0x40,0x00,0x0c
-,0xc6,0x01,0x00,0x00,0xc0,0xf7,0xff,0x00,0xc0,0x02,0x00,0x10,0x00,0x40,0x00,0x00
-,0x33,0xc0,0x8e,0xd8,0x8d,0x3e,0x72,0x49,0x8d,0x36,0xb0,0x37,0xb9,0x14,0x00,0x8b
-,0x1e,0x30,0x34,0x89,0x5c,0x02,0x2e,0x8b,0x45,0x02,0x89,0x44,0x06,0x2e,0x8b,0x05
-,0x89,0x44,0x04,0x83,0xc7,0x04,0x83,0xc6,0x10,0xe2,0xe8,0xc6,0x06,0x9e,0x36,0x0e
-,0xe8,0xfd,0x26,0x68,0x83,0x28,0xa1,0xaa,0x02,0xcd,0x35,0x83,0x3e,0xa1,0x36,0x00
-,0x74,0x03,0xe9,0x3b,0x27,0x33,0xff,0x8e,0x06,0xa6,0x02,0x8b,0x36,0xa4,0x02,0x2e
-,0xff,0xa4,0x2e,0x30,0x83,0x0e,0x99,0x36,0x04,0xc7,0x06,0x37,0x37,0x01,0x00,0xc6
-,0x06,0xca,0x34,0x01,0xe9,0x7d,0x19,0x80,0x3e,0xa0,0x36,0x08,0x74,0xe6,0x80,0x26
-,0x9e,0x36,0xff,0x75,0x1a,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x12,0xf7,0x06,0x9b
-,0x36,0x03,0x00,0x75,0x0a,0x83,0x0e,0x66,0x37,0x10,0xc6,0x06,0xa0,0x36,0x08,0xe9
-,0xfb,0x01,0x80,0x3e,0x9e,0x36,0x02,0x75,0xce,0xc6,0x06,0xa0,0x36,0x06,0xe9,0xec
-,0x01,0xc3,0xe9,0xe8,0x01,0x26,0xc7,0x06,0x0a,0x00,0x00,0x00,0x26,0xff,0x26,0x04
-,0x00,0xa1,0xd1,0x36,0x26,0x39,0x06,0x1a,0x00,0x75,0x22,0xa1,0xd3,0x36,0x26,0x39
-,0x06,0x1c,0x00,0x75,0x18,0xa1,0xd5,0x36,0x26,0x39,0x06,0x1e,0x00,0x75,0x0e,0x26
-,0xf7,0x06,0x0c,0x00,0x40,0x00,0x74,0x05,0x83,0x0e,0x66,0x37,0x40,0x81,0x0e,0xaf
-,0x36,0x00,0x10,0xa1,0xaf,0x36,0xe7,0x06,0x80,0x3e,0x9d,0x36,0x02,0x75,0x06,0xcd
-,0x34,0xe9,0xa2,0x1a,0xc3,0xf7,0x06,0x9b,0x36,0x10,0x00,0x75,0x54,0x26,0xf6,0x06
-,0x0a,0x00,0xff,0x75,0x4c,0x26,0xa0,0x19,0x00,0x24,0xc0,0x3c,0x40,0x75,0x11,0x80
-,0x3e,0x95,0x36,0x00,0x74,0x3b,0x26,0xc7,0x06,0x04,0x00,0xff,0xff,0xe9,0x31,0x00
-,0xe8,0xf1,0x04,0xf7,0x06,0x9b,0x36,0x03,0x00,0x74,0x2f,0x8b,0xd8,0xb8,0x7d,0x03
-,0xcd,0x3a,0x8b,0xc3,0xc6,0x06,0xa0,0x36,0x06,0xf7,0x06,0x9b,0x36,0x02,0x00,0x75
-,0x05,0xc6,0x06,0xa0,0x36,0x04,0x81,0x0e,0x9b,0x36,0x80,0x00,0x83,0x26,0x9b,0x36
-,0xfc,0xe9,0x23,0x01,0xe8,0x87,0x1d,0xe9,0x33,0x01,0x50,0x26,0xa1,0x0c,0x00,0x25
-,0x07,0x00,0x3d,0x07,0x00,0x75,0x03,0xe9,0x84,0x00,0x3d,0x05,0x00,0x75,0x03,0xe9
-,0x7c,0x00,0x83,0x3e,0xe8,0x3a,0x04,0x74,0x75,0x83,0x3e,0xe8,0x3a,0x02,0x74,0x6e
-,0xf7,0x06,0xe6,0x34,0x18,0x80,0x75,0x03,0xe9,0x6a,0x00,0xf7,0x06,0xe6,0x34,0x00
-,0x80,0x74,0x35,0x26,0x80,0x3e,0x29,0x00,0x02,0x75,0x2d,0x51,0x56,0x57,0x8d,0x36
-,0x3e,0x34,0x8d,0x3e,0x20,0x00,0xb9,0x06,0x00,0xf3,0xa6,0x5f,0x5e,0x59,0x74,0x45
-,0x26,0xa1,0x20,0x00,0xa3,0x3e,0x34,0x26,0xa1,0x22,0x00,0xa3,0x40,0x34,0x26,0xa1
-,0x24,0x00,0xa3,0x42,0x34,0xe9,0x26,0x00,0xf7,0x06,0xe6,0x34,0x08,0x00,0x74,0x0b
-,0x26,0x80,0x3e,0x19,0x00,0x00,0x74,0x03,0xe9,0x13,0x00,0xf7,0x06,0xe6,0x34,0x10
-,0x00,0x74,0x12,0x26,0xa0,0x28,0x00,0xc0,0xe8,0x04,0x22,0xc0,0x74,0x07,0x26,0xc7
-,0x06,0x04,0x00,0xff,0xff,0x58,0x23,0xc0,0x74,0x03,0xe9,0x57,0xff,0x81,0x26,0x9b
-,0x36,0xff,0xfe,0x83,0xfe,0x06,0x7f,0x24,0x26,0xa1,0x20,0x00,0x3b,0x06,0xd1,0x36
-,0x75,0x1a,0x26,0xa1,0x22,0x00,0x3b,0x06,0xd3,0x36,0x75,0x10,0x26,0xa1,0x24,0x00
-,0x3b,0x06,0xd5,0x36,0x75,0x06,0x81,0x0e,0x9b,0x36,0x00,0x01,0x26,0xa1,0x20,0x00
-,0x25,0x7f,0xff,0xa3,0xb8,0x34,0x26,0xa1,0x22,0x00,0xa3,0xba,0x34,0x26,0xa1,0x24
-,0x00,0xa3,0xbc,0x34,0x8b,0xc6,0x86,0xc4,0xa3,0xc0,0x34,0xd1,0xe6,0x80,0xfc,0x09
-,0x74,0x03,0xe8,0xaa,0x1c,0x8b,0xc6,0x2e,0xff,0xa4,0x30,0x49,0x26,0xa1,0x0c,0x00
-,0x3d,0xff,0x7f,0x74,0x0f,0x26,0xff,0x26,0x04,0x00,0x8e,0x06,0x38,0x34,0xe8,0x36
-,0x06,0xcd,0x50,0xc3,0xe9,0x16,0x00,0xcd,0x34,0xe9,0x11,0x00,0xcd,0x34,0x89,0x36
-,0x3d,0x37,0xa1,0x9d,0x36,0xa3,0x3f,0x37,0xc6,0x06,0xa0,0x36,0x0c,0xe8,0x8e,0x00
-,0xa1,0x9f,0x36,0x22,0xe4,0x75,0x32,0xf7,0x06,0x4c,0x37,0x01,0x00,0x75,0x2a,0xf6
-,0x06,0x9d,0x36,0x80,0x74,0x07,0x88,0x26,0x9e,0x36,0xe9,0x31,0x00,0x3a,0x06,0x9d
-,0x36,0xa3,0x9d,0x36,0x74,0x28,0x8b,0xf0,0x2e,0xff,0xa4,0x0d,0x2b,0x44,0x29,0xee
-,0x42,0x19,0x44,0xcd,0x44,0x2f,0x45,0x5a,0x45,0x3a,0x26,0x9e,0x36,0x75,0x01,0xc3
-,0x32,0xc0,0x86,0xc4,0x8b,0xf0,0xa2,0x9e,0x36,0x2e,0xff,0xa4,0x20,0x49,0x8b,0x2e
-,0x99,0x36,0x23,0xed,0x75,0x01,0xc3,0xbf,0x01,0x00,0xbe,0x00,0x00,0x85,0xfd,0x75
-,0x1a,0x46,0xd1,0xe7,0xe9,0xf6,0xff,0x2a,0x00,0x29,0x00,0x28,0x00,0x27,0x00,0x25
-,0x00,0x05,0x00,0x07,0x00,0x26,0x00,0x06,0x00,0x20,0x00,0xf7,0xd7,0x21,0x3e,0x99
-,0x36,0xd1,0xe6,0x2e,0x8b,0xb4,0x47,0x2b,0xe9,0x4f,0xff,0xe9,0x56,0xff,0x80,0x26
-,0x9e,0x36,0xff,0x75,0x17,0xf7,0x06,0x4c,0x37,0x01,0x00,0x75,0x0f,0xf6,0x06,0x9d
-,0x36,0x80,0x74,0x08,0xf7,0x06,0x66,0x37,0xff,0xff,0x75,0x07,0xc7,0x06,0x66,0x37
-,0x00,0x00,0xc3,0xf7,0x06,0x41,0x37,0x01,0x00,0x75,0x0b,0xb8,0x7f,0x03,0xcd,0x39
-,0xc7,0x06,0x41,0x37,0x01,0x00,0x33,0xf6,0xb8,0x00,0x40,0x85,0x06,0x66,0x37,0x74
-,0x21,0x80,0xbc,0x54,0x37,0xff,0x74,0x04,0xfe,0x84,0x54,0x37,0x80,0xbc,0x96,0x34
-,0xff,0x74,0x04,0xfe,0x84,0x96,0x34,0x31,0x06,0x66,0x37,0x83,0x3e,0x66,0x37,0x00
-,0x74,0x05,0x46,0xd1,0xe8,0x73,0xd4,0xc3,0xa1,0xf4,0x33,0xa9,0x00,0x88,0x74,0x0b
-,0xa9,0x00,0x10,0x75,0x09,0x8b,0x1e,0x43,0x37,0xff,0xe3,0xe9,0xd7,0x00,0xc7,0x06
-,0x35,0x37,0x05,0x00,0xc7,0x06,0x43,0x37,0x1e,0x2c,0xf7,0x06,0xf4,0x33,0x00,0x08
-,0x74,0x06,0xc7,0x06,0x43,0x37,0x10,0x2c,0xb8,0x80,0x03,0xcd,0x39,0xe9,0xcd,0xfe
-,0xa9,0x00,0x08,0x74,0xd9,0xff,0x0e,0x35,0x37,0x75,0xed,0xe9,0x66,0x00,0xa9,0x00
-,0x08,0x75,0xcb,0xff,0x0e,0x35,0x37,0x75,0xdf,0x81,0x0e,0xc2,0x34,0xc0,0x00,0xf6
-,0x06,0x9d,0x36,0x80,0x74,0x48,0x81,0x0e,0x9b,0x36,0x00,0x80,0xf7,0x06,0x9b,0x36
-,0x01,0x00,0x74,0x1e,0xb8,0x7d,0x03,0xcd,0x3a,0x81,0x0e,0x9b,0x36,0x80,0x00,0x83
-,0x26,0x9b,0x36,0xfe,0xc7,0x06,0x0f,0x37,0x02,0x00,0xc6,0x06,0xa0,0x36,0x04,0xe9
-,0x7b,0xfe,0x80,0x3e,0xa0,0x36,0x04,0x75,0x07,0x83,0x3e,0x0f,0x37,0x01,0x75,0x05
-,0xc6,0x06,0xa0,0x36,0x06,0xc7,0x06,0x0f,0x37,0x02,0x00,0xe9,0x5f,0xfe,0xbe,0x02
-,0x00,0xe9,0x4a,0xfe,0x80,0x26,0x9e,0x36,0xff,0x75,0x3a,0xf6,0x06,0x9d,0x36,0x80
-,0x74,0x2d,0xf7,0x06,0x9b,0x36,0x00,0x20,0x75,0x2b,0xc6,0x06,0xa0,0x36,0x06,0xff
-,0x06,0x94,0x34,0x83,0x0e,0x66,0x37,0x20,0x8e,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a
-,0x00,0x00,0x01,0x74,0x07,0x26,0x81,0x0e,0x08,0x00,0x00,0x01,0xe9,0x06,0x00,0xbe
-,0x04,0x00,0xe9,0x09,0xfe,0x81,0x0e,0xaf,0x36,0x00,0x08,0xa1,0xaf,0x36,0xe7,0x06
-,0xe5,0x0a,0xa9,0x00,0x80,0x74,0x0e,0x81,0x26,0xaf,0x36,0xff,0xf7,0xa1,0xaf,0x36
-,0xe7,0x06,0xe9,0x09,0xff,0xe9,0xf5,0xfd,0xc7,0x06,0x41,0x37,0x00,0x00,0x83,0x0e
-,0x99,0x36,0x02,0xe9,0xe7,0xfd,0x80,0x26,0x9e,0x36,0xff,0x75,0x1d,0xf7,0x06,0x9b
-,0x36,0x00,0x40,0x75,0x05,0x83,0x0e,0x99,0x36,0x08,0x83,0x0e,0x99,0x36,0x20,0x81
-,0x26,0x9b,0x36,0xff,0xbf,0xb8,0x85,0x03,0xcd,0x39,0xe9,0xc0,0xfd,0x80,0x3e,0x9e
-,0x36,0x06,0x74,0x07,0x80,0x3e,0x9e,0x36,0x0a,0x75,0x34,0xf6,0x06,0x9d,0x36,0x80
-,0x75,0x06,0xbe,0x07,0x00,0xe9,0x96,0xfd,0xc6,0x06,0xa0,0x36,0x04,0x83,0x3e,0x0f
-,0x37,0x02,0x74,0x1b,0xc7,0x06,0x0f,0x37,0x04,0x00,0x80,0x3e,0x9e,0x36,0x06,0x75
-,0x0e,0xf7,0x06,0x9b,0x36,0x40,0x00,0x75,0x06,0xc7,0x06,0x0f,0x37,0x03,0x00,0xe9
-,0x7b,0xfd,0x80,0x3e,0x9d,0x36,0x04,0x75,0x12,0x81,0x0e,0xc2,0x34,0x00,0x40,0xff
-,0x06,0x92,0x34,0xc6,0x06,0xa0,0x36,0x06,0xe9,0x62,0xfd,0xbe,0x05,0x00,0xe9,0x4d
-,0xfd,0xf6,0x06,0x9d,0x36,0x80,0x75,0x19,0x83,0x0e,0xc2,0x34,0x04,0xbe,0x06,0x00
-,0xe9,0x3b,0xfd,0x80,0x26,0x9e,0x36,0xff,0x75,0xc5,0xff,0x06,0x31,0x37,0xe9,0x00
-,0x00,0x83,0x26,0xc2,0x34,0xbf,0xc6,0x06,0xa0,0x36,0x06,0xe9,0x2f,0xfd,0xe5,0x0a
-,0x50,0x25,0xc3,0xbf,0xe7,0x0a,0x58,0x80,0x26,0x9e,0x36,0xff,0x75,0x0d,0xa9,0x00
-,0x40,0x75,0x08,0xc6,0x06,0xa0,0x36,0x06,0xe9,0x12,0xfd,0xb8,0x83,0x03,0xcd,0x39
-,0xc3,0xb8,0x7c,0x03,0xcd,0x39,0xf7,0x06,0xf4,0x33,0x00,0x10,0x75,0x09,0xc7,0x06
-,0x33,0x37,0x02,0x00,0xe9,0xf6,0xfc,0xff,0x0e,0x33,0x37,0x74,0x03,0xe9,0xed,0xfc
-,0xff,0x06,0x8e,0x34,0xe8,0xf7,0x19,0x83,0x0e,0xc2,0x34,0x08,0xbe,0x03,0x00,0xe9
-,0xcc,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x04,0x05
-,0x04,0x04,0x04,0x00,0x03,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x04,0x00,0x08,0x08,0x05,0x08,0x08,0x08,0x00,0x03,0x00,0x03,0x03,0x00,0x00
-,0x02,0x04,0x04,0x04,0x04,0x00,0x00,0x08,0x00,0x00,0x0a,0x14,0x00,0x00,0x1a,0x00
-,0x1c,0x00,0x1e,0x20,0x00,0x00,0x04,0x41,0x06,0x0b,0x08,0xc2,0xff,0xe7,0x04,0x03
-,0x06,0x04,0x04,0x05,0x04,0x06,0x04,0x87,0x04,0x03,0x06,0x04,0x04,0x85,0x4e,0xa2
-,0x04,0xcf,0x04,0xcd,0xc7,0x06,0xa2,0x37,0x00,0x00,0xc7,0x06,0xa6,0x37,0x00,0x00
-,0x26,0xa1,0x20,0x00,0x25,0x7f,0xff,0xa3,0xf5,0x36,0x26,0xa1,0x22,0x00,0xa3,0xf7
-,0x36,0x26,0xa1,0x24,0x00,0xa3,0xf9,0x36,0xe8,0x3b,0x19,0x8b,0xf0,0x26,0x8b,0x0e
-,0x0e,0x00,0x2b,0xc8,0x83,0xe9,0x0e,0xb8,0x01,0x80,0x83,0xf9,0x04,0x7c,0x51,0x26
-,0x8a,0x54,0x28,0x88,0x16,0x1c,0x37,0x40,0x26,0x8b,0x6c,0x26,0x86,0xcd,0x3b,0xcd
-,0x86,0xcd,0x89,0x0e,0xa4,0x37,0x75,0x38,0x40,0x32,0xff,0x26,0x8a,0x5c,0x29,0x80
-,0xfb,0x15,0x77,0x25,0x80,0xfb,0x0a,0x74,0x20,0x80,0xfb,0x01,0x74,0x1b,0xb8,0x04
-,0x80,0x2e,0x3a,0x97,0x02,0x2e,0x74,0x07,0x2e,0x3a,0x97,0x18,0x2e,0x75,0x11,0x33
-,0xc0,0x80,0xfb,0x09,0x75,0x4f,0x8b,0xf3,0xc3,0x26,0xc7,0x06,0x04,0x00,0xff,0xff
-,0x50,0x52,0xa1,0xa4,0x37,0x86,0xc4,0x26,0x3b,0x06,0x26,0x00,0x7c,0x32,0x26,0x81
-,0x3e,0x26,0x00,0x00,0x04,0x7e,0x29,0x8d,0x74,0x2a,0x26,0x8b,0x14,0x22,0xd2,0x74
-,0x1f,0x80,0xe6,0xbf,0x80,0xfe,0x09,0x75,0x17,0xc7,0x06,0xa2,0x37,0x01,0x00,0x80
-,0xfa,0x04,0x75,0x0c,0x26,0x8b,0x44,0x02,0xa3,0x03,0x37,0x86,0xc4,0xa3,0xd0,0x34
-,0x5a,0x58,0xe9,0xb1,0xff,0xbd,0x72,0x37,0x2e,0x8a,0x87,0x2e,0x2e,0x22,0xc0,0x74
-,0x16,0x05,0x44,0x2e,0x8b,0xf8,0x2e,0x8b,0x05,0x3e,0x89,0x46,0x00,0x83,0xc5,0x02
-,0x83,0xc7,0x02,0x22,0xe4,0x7d,0xef,0x8d,0x74,0x2a,0x83,0xe9,0x04,0x75,0x03,0xe9
-,0xa1,0x00,0x26,0x8b,0x14,0x22,0xd2,0x75,0x03,0xe9,0x7c,0x00,0xc7,0x06,0xa6,0x37
-,0x01,0x00,0xbf,0x72,0x37,0x8b,0x05,0x83,0xc7,0x02,0x80,0xe6,0xbf,0x80,0xe4,0x3f
-,0x80,0xfe,0x09,0x75,0x22,0x80,0xfa,0x04,0x75,0x5e,0xc7,0x06,0xa2,0x37,0x01,0x00
-,0x26,0x8b,0x44,0x02,0xa3,0x03,0x37,0x86,0xc4,0xa3,0xd0,0x34,0x86,0xc4,0xc7,0x06
-,0xa6,0x37,0x00,0x00,0xe9,0x47,0x00,0x3b,0xfd,0x7e,0x15,0x26,0x8b,0x04,0xa8,0x40
-,0x74,0x06,0xb8,0x07,0x80,0xe9,0x38,0xff,0x32,0xc0,0x26,0x8b,0x04,0xe9,0x2e,0x00
-,0x3a,0xf4,0x75,0xb1,0xc7,0x45,0xfe,0x00,0x00,0x80,0xfe,0x22,0x75,0x0d,0x3a,0xd0
-,0x77,0x16,0xc7,0x06,0xa6,0x37,0x00,0x00,0xe9,0x13,0x00,0x3a,0xd0,0x75,0x09,0xc7
-,0x06,0xa6,0x37,0x00,0x00,0xe9,0x06,0x00,0xb8,0x05,0x80,0xe9,0x02,0xff,0x32,0xf6
-,0x03,0xf2,0x2b,0xca,0xb8,0x05,0x80,0x23,0xc9,0x76,0x03,0xe9,0x64,0xff,0x74,0x03
-,0xe9,0xed,0xfe,0x33,0xc0,0xbf,0x72,0x37,0x8b,0x15,0x47,0x47,0x3b,0xfd,0x7f,0x1b
-,0xf6,0xc6,0x80,0x74,0x16,0xf7,0x06,0xa6,0x37,0x01,0x00,0x74,0x06,0xb8,0x08,0x80
-,0xe9,0xc3,0xfe,0xf6,0xc6,0x40,0x74,0xe0,0xb8,0x07,0x80,0xe9,0xb8,0xfe,0x7d,0x42
-,0xa3,0x45,0x44,0x29,0x44,0x29,0xb7,0x28,0xe2,0x28,0xee,0x2b,0xf2,0x28,0xf5,0x28
-,0x01,0x29,0xac,0x2a,0x44,0x29,0x44,0x29,0x44,0x29,0x44,0x29,0x44,0x29,0x00,0x00
-,0x73,0x36,0x00,0x00,0x03,0x36,0xc5,0x35,0x83,0x35,0x45,0x35,0x07,0x35,0xd2,0x34
-,0x45,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0xa6,0x38,0x00,0x00,0xe0,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0xf2,0x33,0x00,0x00,0xa6,0x33,0x60,0x33,0xfd,0x32,0xbc,0x32,0x77,0x32,0x3c,0x32
-,0xfb,0x31,0x6a,0x31,0x0a,0x31,0xe0,0xe0,0x10,0x10,0x10,0xe0,0xe0,0xe0,0xe0,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0
-,0xe0,0x33,0xff,0x26,0xf6,0x06,0x1a,0x00,0x80,0x74,0x1b,0x26,0x80,0x26,0x1a,0x00
-,0x7f,0x26,0x8b,0x3e,0x26,0x00,0x83,0xe7,0x1f,0x74,0x0b,0x26,0x80,0x0e,0x20,0x00
-,0x80,0x26,0x01,0x3e,0x0e,0x00,0xc3,0x60,0x2e,0x8b,0x84,0xa6,0x30,0x26,0xa3,0x18
-,0x00,0xd1,0xe6,0x2e,0xff,0x94,0x50,0x30,0x61,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4
-,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x16,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26
-,0xc6,0x06,0x19,0x00,0x00,0xe8,0xbf,0x05,0xe8,0x98,0x05,0x26,0xc7,0x06,0x26,0x00
-,0x00,0x08,0x26,0xc6,0x06,0x28,0x00,0x40,0x26,0xc6,0x06,0x29,0x00,0x2a,0xbf,0x2a
-,0x00,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x2a,0xa1,0x93,0x37,0x33,0xdb,0xa9
-,0x40,0x00,0x75,0x02,0xb3,0x01,0xa9,0x00,0x10,0x74,0x02,0xb7,0x88,0xa9,0x00,0x08
-,0x74,0x03,0x80,0xcf,0x44,0x26,0x89,0x5d,0x02,0xc3,0x83,0x0e,0xc2,0x34,0x20,0x26
-,0xc7,0x06,0x04,0x00,0x6b,0x2b,0x26,0xc7,0x06,0x0e,0x00,0x30,0x00,0x26,0xc7,0x06
-,0x06,0x00,0x0a,0x00,0x26,0xc7,0x06,0x0a,0x00,0x04,0x00,0x26,0xc6,0x06,0x19,0x00
-,0x00,0xe8,0x69,0x05,0xe8,0x2c,0x05,0x26,0xc7,0x06,0x26,0x00,0x00,0x22,0x26,0xc6
-,0x06,0x28,0x00,0x60,0x26,0xc6,0x06,0x29,0x00,0x29,0xbf,0x2a,0x00,0x26,0xc6,0x05
-,0x08,0x26,0xc6,0x45,0x01,0x2d,0x8d,0x7d,0x02,0xbe,0x54,0x37,0xb9,0x03,0x00,0xf3
-,0xa5,0x26,0xc6,0x05,0x08,0x26,0xc6,0x45,0x01,0x2e,0x8d,0x7d,0x02,0xbe,0x5a,0x37
-,0xb9,0x03,0x00,0xf3,0xa5,0xe8,0xd4,0x05,0xe8,0x64,0x05,0xb9,0x06,0x00,0xbe,0x54
-,0x37,0x8d,0x2e,0x2c,0x00,0x26,0x8b,0x46,0x00,0x29,0x04,0x83,0xc6,0x02,0x83,0xc5
-,0x02,0x83,0xf9,0x04,0x75,0x02,0x45,0x45,0xe2,0xeb,0xc3,0x26,0xc7,0x06,0x04,0x00
-,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x24,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00
-,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0xe4,0x04,0xe8,0xa7,0x04,0x26,0xc7,0x06,0x26
-,0x00,0x00,0x16,0x26,0xc6,0x06,0x28,0x00,0x60,0x26,0xc6,0x06,0x29,0x00,0x28,0xbf
-,0x2a,0x00,0xe8,0x5b,0x06,0xe8,0x74,0x05,0xe8,0x04,0x05,0xc3,0x26,0xc7,0x06,0x04
-,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x1a,0x00,0x26,0xc7,0x06,0x06,0x00,0x06
-,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0xa3,0x04,0xe8,0x66,0x04,0x26,0xc7,0x06
-,0x26,0x00,0x00,0x0c,0x26,0xc6,0x06,0x28,0x00,0x60,0x26,0xc6,0x06,0x29,0x00,0x27
-,0xbf,0x2a,0x00,0xe8,0x21,0x05,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7
-,0x06,0x0e,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x0a,0x00,0x26,0xc7,0x06,0x0a
-,0x00,0x04,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x4b,0x04,0xe8,0x24,0x04,0x26
-,0xc7,0x06,0x26,0x00,0x00,0x12,0x26,0xc6,0x06,0x28,0x00,0x40,0x26,0xc6,0x06,0x29
-,0x00,0x26,0xbf,0x2a,0x00,0xe8,0xf4,0x04,0xe8,0x84,0x04,0xc3,0x26,0xc7,0x06,0x04
-,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x34,0x00,0x26,0xc7,0x06,0x06,0x00,0x06
-,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x0d,0x04,0xe8,0xe6,0x03,0x26,0xc7,0x06
-,0x26,0x00,0x00,0x26,0x26,0xc6,0x06,0x28,0x00,0x40,0x26,0xc6,0x06,0x29,0x00,0x25
-,0xbf,0x2a,0x00,0xe8,0xb6,0x04,0xe8,0x46,0x04,0xe8,0xfa,0x04,0xc3,0x26,0xc7,0x06
-,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x38,0x00,0xa1,0xa2,0x37,0x50,0x0b
-,0xc0,0x75,0x07,0x26,0xc7,0x06,0x0e,0x00,0x34,0x00,0x26,0xc7,0x06,0x06,0x00,0x06
-,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x99,0x03,0xe8,0xa4,0xfd,0x26,0xc7,0x45
-,0x26,0x00,0x2a,0x58,0x0b,0xc0,0x75,0x06,0x26,0xc7,0x45,0x26,0x00,0x26,0xa1,0x1c
-,0x37,0xc1,0xe0,0x04,0x26,0x88,0x45,0x28,0x26,0xc6,0x45,0x29,0x24,0x83,0xc7,0x2a
-,0xe8,0x29,0x04,0xe8,0xa0,0x04,0xe8,0x22,0x05,0xe8,0xf8,0x03,0xe8,0x09,0x04,0xc3
-,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x32,0x00,0x26,0xc7
-,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x45,0x03,0xe8,0x50
-,0xfd,0x26,0xc7,0x45,0x26,0x00,0x24,0xa1,0x1c,0x37,0xc1,0xe0,0x04,0x26,0x88,0x45
-,0x28,0x26,0xc6,0x45,0x29,0x23,0x83,0xc7,0x2a,0xe8,0xe0,0x03,0xe8,0x6c,0x04,0xe8
-,0x8a,0x04,0xe8,0x9c,0x04,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06
-,0x0e,0x00,0x34,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00
-,0x00,0xe8,0xff,0x02,0xe8,0x0a,0xfd,0x26,0xc7,0x45,0x26,0x00,0x26,0xa1,0x1c,0x37
-,0xc1,0xe0,0x04,0x26,0x88,0x45,0x28,0x26,0xc6,0x45,0x29,0x22,0x83,0xc7,0x2a,0xe8
-,0x9a,0x03,0xe8,0xc7,0x03,0xe8,0x57,0x03,0xe8,0xf8,0x03,0xe8,0x78,0x04,0xe8,0x8a
-,0x04,0xc3,0x26,0xc7,0x06,0x04,0x00,0x74,0x45,0x26,0xc7,0x06,0x0e,0x00,0x3e,0x00
-,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc7,0x06,0x0a,0x00,0x04,0x00,0x26,0xc6
-,0x06,0x19,0x00,0x00,0xe8,0xfc,0x02,0xe8,0xa9,0x02,0x83,0x3e,0x8d,0x37,0x03,0x75
-,0x01,0x90,0x26,0xc7,0x06,0x26,0x00,0x00,0x30,0x26,0xc6,0x06,0x28,0x00,0x50,0x26
-,0xc6,0x06,0x29,0x00,0x20,0xbf,0x2a,0x00,0xe8,0xd0,0x03,0xe8,0x01,0x03,0xe8,0xb5
-,0x03,0xe8,0x9f,0x03,0xc3,0x26,0xc7,0x06,0x04,0x00,0x61,0x43,0xb9,0xf0,0x00,0x83
-,0xe9,0x02,0x26,0x89,0x0e,0x0e,0x00,0x26,0xc7,0x06,0x06,0x00,0x02,0x00,0x26,0xc6
-,0x06,0x19,0x00,0x00,0x26,0xc7,0x06,0x1a,0x00,0x00,0x00,0x26,0xc7,0x06,0x1c,0x00
-,0x00,0x00,0x26,0xc7,0x06,0x1e,0x00,0x00,0x00,0xe8,0x47,0x02,0x83,0xe9,0x0e,0x86
-,0xcd,0x26,0x89,0x0e,0x26,0x00,0x86,0xcd,0x26,0xc6,0x06,0x28,0x00,0x00,0x26,0xc6
-,0x06,0x29,0x00,0x08,0xbf,0x2a,0x00,0x83,0xe9,0x04,0x26,0x89,0x0d,0x26,0xc6,0x45
-,0x01,0x26,0x8d,0x7d,0x02,0x83,0xe9,0x02,0xbb,0x01,0x00,0xb8,0x30,0x30,0x4b,0x75
-,0x17,0xbb,0x0a,0x00,0x8a,0xc4,0x26,0x88,0x05,0xb0,0x31,0x80,0xc4,0x01,0x80,0xfc
-,0x3a,0x75,0x0a,0xb4,0x61,0xe9,0x05,0x00,0x26,0x88,0x05,0x04,0x01,0x47,0x49,0x75
-,0xdd,0xc3,0x26,0xc7,0x06,0x04,0x00,0x04,0x45,0x26,0xc7,0x06,0x0e,0x00,0x12,0x00
-,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00,0x01,0xe8,0xe5,0x01
-,0xe8,0xd0,0x01,0x26,0xc7,0x06,0x26,0x00,0x00,0x04,0x26,0xc6,0x06,0x28,0x00,0x00
-,0x26,0xc6,0x06,0x29,0x00,0x07,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7
-,0x06,0x0e,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19
-,0x00,0x06,0xe8,0x04,0x02,0xe8,0x9b,0x01,0x26,0xc7,0x06,0x26,0x00,0x00,0x12,0x26
-,0xc6,0x06,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x06,0xbf,0x2a,0x00,0xe8,0x6b
-,0x02,0xe8,0xfb,0x01,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e
-,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00,0x05
-,0xe8,0xc6,0x01,0xe8,0x5d,0x01,0x26,0xc7,0x06,0x26,0x00,0x00,0x12,0x26,0xc6,0x06
-,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x05,0xbf,0x2a,0x00,0xe8,0x2d,0x02,0xe8
-,0xbd,0x01,0xc3,0xff,0x06,0x82,0x34,0x26,0xc7,0x06,0x04,0x00,0x3d,0x41,0x26,0xc7
-,0x06,0x0e,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x0e,0x00,0x26,0xc6,0x06,0x19
-,0x00,0x04,0xe8,0x84,0x01,0xe8,0x1b,0x01,0x26,0xc7,0x06,0x26,0x00,0x00,0x12,0x26
-,0xc6,0x06,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x04,0xbf,0x2a,0x00,0xe8,0xeb
-,0x01,0xe8,0x7b,0x01,0xc3,0x26,0xc7,0x06,0x04,0x00,0x67,0x42,0x26,0xc7,0x06,0x0e
-,0x00,0x20,0x00,0x26,0xc7,0x06,0x06,0x00,0x08,0x00,0x26,0xc6,0x06,0x19,0x00,0x03
-,0xe8,0x46,0x01,0xe8,0xdd,0x00,0x26,0xc7,0x06,0x26,0x00,0x00,0x12,0x26,0xc6,0x06
-,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x03,0xbf,0x2a,0x00,0xe8,0xad,0x01,0xe8
-,0x3d,0x01,0xc3,0xff,0x06,0x84,0x34,0x26,0xc7,0x06,0x04,0x00,0x67,0x42,0x26,0xc7
-,0x06,0x0e,0x00,0x24,0x00,0x26,0xc7,0x06,0x06,0x00,0x08,0x00,0x26,0xc6,0x06,0x19
-,0x00,0x02,0xe8,0x04,0x01,0xe8,0x9b,0x00,0x26,0xc7,0x06,0x26,0x00,0x00,0x16,0x26
-,0xc6,0x06,0x28,0x00,0x00,0x26,0xc6,0x06,0x29,0x00,0x02,0xbf,0x2a,0x00,0x26,0xc6
-,0x05,0x04,0x26,0xc6,0x45,0x01,0x01,0xa1,0x0f,0x37,0x86,0xe0,0xf6,0x06,0x6f,0x37
-,0x01,0x75,0x0f,0x39,0x06,0xcc,0x34,0x74,0x09,0x8b,0xd8,0xb8,0x89,0x03,0xcd,0x39
-,0x8b,0xc3,0xa3,0xcc,0x34,0x26,0x89,0x45,0x02,0x8d,0x7d,0x04,0xe8,0x3d,0x01,0xe8
-,0xcd,0x00,0xc3,0x26,0xc7,0x06,0x04,0x00,0xc4,0x2a,0x26,0xc7,0x06,0x0e,0x00,0x1c
-,0x00,0xa1,0xa2,0x37,0x50,0x0b,0xc0,0x75,0x07,0x26,0xc7,0x06,0x0e,0x00,0x18,0x00
-,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x23,0x00
-,0xe8,0x2e,0xfa,0x26,0xc7,0x45,0x26,0x00,0x0e,0x58,0x0b,0xc0,0x75,0x06,0x26,0xc7
-,0x45,0x26,0x00,0x0a,0x26,0xc6,0x45,0x29,0x00,0x83,0xc7,0x2a,0xe8,0xbd,0x00,0xe8
-,0xff,0x00,0xc3,0x56,0x57,0x51,0xb9,0x03,0x00,0xbe,0xd1,0x36,0xbf,0x20,0x00,0xf3
-,0xa5,0x59,0x5f,0x5e,0xc3,0x56,0x57,0x51,0xb9,0x03,0x00,0xbe,0xd1,0x36,0xbf,0x1a
-,0x00,0xf3,0xa5,0x59,0x5f,0x5e,0xc3,0x26,0xc7,0x06,0x1a,0x00,0xc0,0x00,0x26,0xc7
-,0x06,0x1c,0x00,0x00,0x00,0x26,0xc7,0x06,0x1e,0x00,0x00,0x10,0xc3,0x26,0xc7,0x06
-,0x1a,0x00,0xc0,0x00,0x26,0xc7,0x06,0x1c,0x00,0x00,0x00,0x26,0xc7,0x06,0x1e,0x00
-,0x00,0x08,0xc3,0x26,0xc7,0x06,0x1a,0x00,0xc0,0x00,0x26,0xc7,0x06,0x1c,0x00,0x00
-,0x00,0x26,0xc7,0x06,0x1e,0x00,0x00,0x02,0xc3,0x26,0xc7,0x06,0x1a,0x00,0xc0,0x00
-,0x26,0xc7,0x06,0x1c,0x00,0xff,0xff,0x26,0xc7,0x06,0x1e,0x00,0xff,0xff,0xc3,0x26
-,0xc6,0x05,0x08,0x26,0xc6,0x45,0x01,0x02,0x8d,0x7d,0x02,0xbe,0x05,0x37,0xb9,0x03
-,0x00,0xf3,0xa5,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x06,0xa1,0x0d,0x37
-,0x26,0x89,0x45,0x02,0x8d,0x7d,0x04,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01
-,0x07,0xa1,0x0b,0x37,0x26,0x89,0x45,0x02,0x83,0xc7,0x04,0xc3,0xa1,0xa2,0x37,0x0b
-,0xc0,0x74,0x13,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x09,0xa1,0x03,0x37,0x26
-,0x89,0x45,0x02,0x83,0xc7,0x04,0xc3,0x26,0xc6,0x05,0x08,0x26,0xc6,0x45,0x01,0x02
-,0x8d,0x7d,0x02,0xbe,0x05,0x37,0xb9,0x03,0x00,0xf3,0xa5,0xc3,0x26,0xc6,0x05,0x06
-,0x26,0xc6,0x45,0x01,0x0b,0x8d,0x7d,0x02,0xbe,0xef,0x36,0xb9,0x02,0x00,0xf3,0xa5
-,0xc3,0x26,0xc6,0x05,0x06,0x26,0xc6,0x45,0x01,0x20,0xa1,0x68,0x37,0x26,0x89,0x45
-,0x02,0xa1,0x6a,0x37,0x26,0x88,0x65,0x05,0xc1,0xe0,0x04,0x26,0x88,0x45,0x04,0x83
-,0xc7,0x06,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x21,0x26,0xc7,0x45,0x02
-,0x00,0x00,0x83,0xc7,0x04,0xc3,0x26,0xc6,0x05,0x14,0x26,0xc6,0x45,0x01,0x22,0x8d
-,0x7d,0x02,0xbe,0x1f,0x37,0xb9,0x09,0x00,0xf3,0xa5,0xc3,0x26,0xc6,0x05,0x0c,0x26
-,0xc6,0x45,0x01,0x23,0x8d,0x7d,0x02,0x1e,0x0e,0x1f,0x8d,0x36,0x40,0x54,0xb9,0x03
-,0x00,0xf3,0xa5,0x33,0xc0,0xb9,0x02,0x00,0xf3,0xab,0x1f,0xc3,0x26,0xc6,0x05,0x08
-,0x26,0xc6,0x45,0x01,0x28,0x8d,0x7d,0x02,0xbe,0xd1,0x36,0xb9,0x03,0x00,0xf3,0xa5
-,0xc3,0x26,0xc6,0x05,0x08,0x26,0xc6,0x45,0x01,0x29,0xa1,0xc2,0x34,0x86,0xe0,0x26
-,0x89,0x45,0x02,0xa1,0x9b,0x36,0x26,0x89,0x45,0x04,0x26,0x88,0x45,0x06,0x26,0x88
-,0x45,0x07,0x8d,0x7d,0x08,0xc3,0x26,0xc6,0x05,0x06,0x26,0xc6,0x45,0x01,0x2b,0x8d
-,0x7d,0x02,0xbe,0xbb,0x36,0xb9,0x02,0x00,0xf3,0xa5,0xc3,0x26,0xc6,0x05,0x06,0x26
-,0xc6,0x45,0x01,0x2c,0x8d,0x7d,0x02,0xbe,0xe5,0x36,0xb9,0x02,0x00,0xf3,0xa5,0xc3
-,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x30,0xa1,0x37,0x37,0x86,0xe0,0x26,0x89
-,0x45,0x02,0x8d,0x7d,0x04,0xc3,0x26,0xc7,0x06,0x0e,0x00,0x1e,0x00,0x26,0xc7,0x06
-,0x06,0x00,0x02,0x00,0x26,0xc6,0x06,0x19,0x00,0x00,0xe8,0x6c,0xfe,0xe8,0x03,0xfe
-,0x26,0xc7,0x06,0x26,0x00,0x00,0x10,0x26,0xc6,0x06,0x28,0x00,0x30,0x26,0xc6,0x06
-,0x29,0x00,0x11,0xbf,0x2a,0x00,0xe8,0x35,0x00,0xe8,0x45,0x00,0xe8,0x55,0x00,0xc3
-,0x26,0xc7,0x06,0x0e,0x00,0x12,0x00,0x26,0xc7,0x06,0x06,0x00,0x02,0x00,0x26,0xc6
-,0x06,0x19,0x00,0x00,0xe8,0x32,0xfe,0xe8,0xc9,0xfd,0x26,0xc7,0x06,0x26,0x00,0x00
-,0x04,0x26,0xc6,0x06,0x28,0x00,0x30,0x26,0xc6,0x06,0x29,0x00,0x13,0xc3,0x26,0xc6
-,0x05,0x04,0x26,0xc6,0x45,0x01,0x0c,0x26,0xc7,0x45,0x02,0x00,0x01,0x83,0xc7,0x04
-,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x0e,0x26,0xc7,0x45,0x02,0x00,0x02
-,0x83,0xc7,0x04,0xc3,0x26,0xc6,0x05,0x04,0x26,0xc6,0x45,0x01,0x21,0x26,0xc7,0x45
-,0x02,0x00,0x00,0x83,0xc7,0x04,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0xb3,0x39,0xc9,0x39,0x83,0x3a,0xb3,0x39,0xb3,0x39,0xb3,0x39,0x1c,0x3a,0x1c,0x3a
-,0xa3,0xb6,0x34,0xa1,0xe9,0x36,0xa3,0x11,0x37,0xa3,0xd2,0x34,0xa1,0xeb,0x36,0xa3
-,0x13,0x37,0xa3,0xd4,0x34,0xa1,0xed,0x36,0xa3,0x15,0x37,0xa3,0xd6,0x34,0xa1,0x01
-,0x37,0xa3,0xce,0x34,0xa1,0xf7,0x36,0xa3,0x17,0x37,0xa3,0xdc,0x34,0xa1,0xf9,0x36
-,0xa3,0x19,0x37,0xa3,0xde,0x34,0xf7,0x06,0x9b,0x36,0x02,0x00,0x75,0x0c,0x33,0xc0
-,0xa0,0x9e,0x36,0x8b,0xf0,0x2e,0xff,0xa4,0x50,0x39,0xe9,0x0f,0x01,0xbe,0x07,0x00
-,0xe9,0x19,0xf1,0xf6,0x06,0x9d,0x36,0x80,0x74,0xf3,0xc6,0x06,0xa0,0x36,0x02,0xc6
-,0x06,0x6e,0x37,0x08,0xc6,0x06,0x70,0x37,0x02,0xb8,0x88,0x03,0xcd,0x39,0xf6,0x06
-,0x6f,0x37,0x01,0x75,0x4a,0xa1,0xd1,0x36,0x3a,0x06,0xe9,0x36,0x75,0x41,0x3a,0x26
-,0xea,0x36,0x75,0x3b,0xa1,0xd3,0x36,0x3a,0x06,0xeb,0x36,0x75,0x32,0x3a,0x26,0xec
-,0x36,0x75,0x2c,0xa1,0xd5,0x36,0x3a,0x06,0xed,0x36,0x75,0x23,0x3a,0x26,0xee,0x36
-,0x75,0x1d,0xc6,0x06,0x70,0x37,0x02,0xfe,0x0e,0x6e,0x37,0x75,0x0f,0xb8,0x88,0x03
-,0xcd,0x3a,0x83,0x0e,0x9b,0x36,0x12,0xc6,0x06,0xa0,0x36,0x0c,0xe9,0xa8,0xf0,0xa1
-,0x05,0x37,0x26,0x3b,0x06,0x20,0x00,0x75,0x40,0xa1,0x07,0x37,0x26,0x3b,0x06,0x22
-,0x00,0x75,0x36,0xa1,0x09,0x37,0x26,0x3b,0x06,0x24,0x00,0x75,0x2c,0xa0,0x9e,0x36
-,0x3c,0x02,0x75,0x08,0x26,0xf6,0x06,0x18,0x00,0x08,0x75,0x47,0xc6,0x06,0x6e,0x37
-,0x08,0xfe,0x0e,0x70,0x37,0x75,0x1c,0xc6,0x06,0x70,0x37,0x02,0xe5,0x02,0x0d,0x01
-,0x04,0x25,0xef,0xff,0xe7,0x02,0xe9,0x5e,0xf0,0xc6,0x06,0x70,0x37,0x02,0xc6,0x06
-,0x6e,0x37,0x08,0xe5,0x02,0x25,0xff,0xfb,0x0d,0x01,0x00,0x25,0xef,0xff,0xe7,0x02
-,0xe9,0x44,0xf0,0xf7,0x06,0x9b,0x36,0x00,0x01,0x74,0x25,0x26,0xf6,0x06,0x18,0x00
-,0x08,0x75,0xed,0x81,0x26,0x9b,0x36,0x7f,0xff,0xb8,0x89,0x03,0xcd,0x3a,0xb8,0x84
-,0x03,0xcd,0x3a,0xc6,0x06,0xa0,0x36,0x06,0x83,0x26,0xc2,0x34,0xaf,0xe9,0x17,0xf0
-,0xa1,0x01,0x37,0x3a,0x26,0x0f,0x37,0x7f,0xc7,0xe9,0xf7,0xfe,0x83,0x26,0x9b,0x36
-,0xec,0xe8,0x2a,0x0d,0x81,0x0e,0x9b,0x36,0x80,0x00,0xbb,0xff,0x7f,0xcd,0x53,0xc6
-,0x06,0xa0,0x36,0x02,0xe9,0xf0,0xef,0x83,0x0e,0x9b,0x36,0x11,0xc6,0x06,0xa0,0x36
-,0x0c,0xe9,0xf9,0xef,0x44,0x3b,0x2c,0x3b,0xc7,0x2a,0x6b,0x3b,0x44,0x3b,0xc7,0x2a
-,0xc7,0x2a,0xc7,0x2a,0xa3,0xb6,0x34,0x81,0x0e,0xc2,0x34,0x00,0x20,0xf7,0x06,0x41
-,0x37,0x01,0x00,0x74,0x1b,0x8c,0xc3,0xc7,0x06,0x41,0x37,0x00,0x00,0xb8,0x7f,0x03
-,0xcd,0x3a,0x33,0xc0,0x8e,0xc0,0xbf,0x54,0x37,0xb9,0x06,0x00,0xf3,0xab,0x8e,0xc3
-,0x33,0xc0,0xa0,0x9e,0x36,0x8b,0xf0,0x2e,0xff,0xa4,0xe4,0x3a,0xf7,0x06,0x9b,0x36
-,0x00,0x01,0x75,0x21,0x83,0x26,0xc2,0x34,0xbf,0xa1,0xa9,0x36,0xe7,0x00,0xa1,0x9b
-,0x36,0xe9,0x09,0x00,0xa1,0x9b,0x36,0x81,0x26,0x9b,0x36,0xff,0xdf,0xa9,0x00,0x20
-,0x75,0x06,0xe9,0x6e,0x00,0xe9,0x6f,0xef,0x83,0x0e,0x99,0x36,0x04,0xc7,0x06,0x37
-,0x37,0x01,0x00,0xc6,0x06,0xca,0x34,0x01,0xe9,0x58,0x00,0x83,0x0e,0x9b,0x36,0x40
-,0xe8,0x58,0x00,0xa1,0x05,0x37,0x3b,0x06,0xe9,0x36,0x75,0x37,0xa1,0x07,0x37,0x3b
-,0x06,0xeb,0x36,0x75,0x2e,0xa1,0x09,0x37,0x3b,0x06,0xed,0x36,0x75,0x25,0xfe,0x0e
-,0x71,0x37,0x75,0x1c,0xb8,0x87,0x03,0xcd,0x3a,0x83,0x0e,0x99,0x36,0x10,0xa1,0x50
-,0x37,0xc7,0x06,0x50,0x37,0x00,0x00,0x09,0x06,0x99,0x36,0xc6,0x06,0xa0,0x36,0x08
-,0xe9,0x14,0xef,0x83,0x0e,0x99,0x36,0x04,0xc7,0x06,0x37,0x37,0x03,0x00,0xc6,0x06
-,0xca,0x34,0x03,0xc6,0x06,0xa0,0x36,0x0a,0xe9,0xfc,0xee,0xa1,0xd1,0x36,0x26,0x3b
-,0x06,0x20,0x00,0x75,0x15,0xa1,0xd3,0x36,0x26,0x3b,0x06,0x22,0x00,0x75,0x12,0xa1
-,0xd5,0x36,0x26,0x3b,0x06,0x24,0x00,0x75,0x0f,0xc3,0x8d,0x36,0x20,0x00,0xe9,0x0b
-,0x00,0x8d,0x36,0x22,0x00,0xe9,0x04,0x00,0x8d,0x36,0x24,0x00,0x83,0xc4,0x02,0xf7
-,0x06,0xe6,0x34,0x01,0x00,0x74,0x15,0x26,0x3a,0x04,0x77,0x08,0x72,0x0e,0x26,0x3a
-,0x64,0x01,0x72,0x08,0xc6,0x06,0xa0,0x36,0x06,0xe9,0xab,0xee,0xe8,0x7c,0x0a,0x8c
-,0xc0,0x3d,0xff,0xff,0x74,0x1b,0x26,0xc6,0x06,0x18,0x00,0x10,0x26,0xc7,0x06,0x04
-,0x00,0x49,0x3c,0x26,0xc7,0x06,0x06,0x00,0x0c,0x00,0xcd,0x50,0xb9,0x4e,0x00,0xe2
-,0xfe,0xc6,0x06,0xa0,0x36,0x0a,0xe9,0x94,0xee,0xe9,0x7b,0xee,0x8f,0x3c,0x06,0x3d
-,0x06,0x3d,0x06,0x3d,0xd2,0x3c,0xea,0x3c,0x06,0x3d,0x06,0x3d,0xa3,0xb6,0x34,0x81
-,0x26,0xc2,0x34,0xaf,0xdf,0xc7,0x06,0x4c,0x37,0x00,0x00,0xb8,0x8a,0x03,0xcd,0x3a
-,0x80,0x3e,0x9d,0x36,0x04,0x75,0x0c,0x80,0x3e,0x9e,0x36,0x06,0x74,0x05,0xc6,0x06
-,0x9f,0x36,0x06,0x33,0xc0,0xa0,0x9e,0x36,0x8b,0xf0,0x2e,0xff,0xa4,0x4c,0x3c,0xf7
-,0x06,0x9b,0x36,0x00,0x20,0x75,0x0e,0x81,0x26,0x9b,0x36,0xff,0xbf,0xb8,0x8b,0x03
-,0xcd,0x3a,0xe9,0x54,0x00,0xf7,0x06,0x9b,0x36,0x00,0x01,0x74,0x03,0xe9,0x17,0xee
-,0xc7,0x06,0x37,0x37,0x02,0x00,0xc6,0x06,0xca,0x34,0x02,0x83,0x0e,0x99,0x36,0x04
-,0x83,0x0e,0x50,0x37,0x04,0xf6,0x06,0x9d,0x36,0x80,0x75,0x2a,0xe8,0x1f,0x0b,0xe9
-,0x27,0x00,0xf7,0x06,0x9b,0x36,0x00,0x01,0x75,0xd3,0xc7,0x06,0x37,0x37,0x02,0x00
-,0xc6,0x06,0xca,0x34,0x02,0x83,0x0e,0x99,0x36,0x04,0xc6,0x06,0xa0,0x36,0x00,0xf6
-,0x06,0x9d,0x36,0x80,0x74,0x03,0xe8,0xde,0x0a,0x81,0x26,0x9b,0x36,0x7c,0xff,0xbb
-,0xff,0xff,0xcd,0x53,0xcd,0x54,0xe9,0xbe,0xed,0xa3,0xb6,0x34,0xe8,0xad,0x01,0xb8
-,0x86,0x03,0xcd,0x39,0xc7,0x06,0x4c,0x37,0x00,0x00,0x81,0x26,0xc2,0x34,0xaf,0xdf
-,0xf6,0x06,0x9d,0x36,0x80,0x74,0x34,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x56,0xf7
-,0x06,0x9b,0x36,0x00,0x01,0x74,0x27,0xe8,0x35,0x01,0x72,0x1c,0xbe,0x00,0x40,0x85
-,0x36,0xc2,0x34,0x75,0x08,0x09,0x36,0xc2,0x34,0xff,0x06,0x92,0x34,0xe8,0x8b,0x01
-,0x73,0x06,0x81,0x0e,0x99,0x36,0x80,0x00,0xe9,0x6c,0xed,0xe9,0xb5,0x00,0xc7,0x06
-,0x37,0x37,0x02,0x00,0xc6,0x06,0xca,0x34,0x02,0x83,0x0e,0x99,0x36,0x04,0x83,0x0e
-,0x50,0x37,0x04,0x80,0x3e,0x9e,0x36,0x08,0x74,0x03,0xe8,0x5a,0x0a,0xe8,0xef,0x00
-,0x72,0xd6,0xe9,0xc8,0xff,0x80,0x3e,0x9e,0x36,0x0a,0x75,0x12,0xc6,0x06,0xa0,0x36
-,0x00,0xf7,0x06,0x9b,0x36,0x08,0x00,0x74,0x02,0xcd,0x54,0xe8,0x39,0x0a,0x81,0x26
-,0x9b,0x36,0xff,0xbf,0xe8,0xc8,0x00,0x72,0xaf,0xb8,0x8b,0x03,0xcd,0x39,0xe9,0x9c
-,0xff,0xf6,0x06,0x9e,0x36,0xff,0x75,0x58,0xa3,0xb6,0x34,0xe8,0xfe,0x00,0x81,0x26
-,0xc2,0x34,0xff,0xbf,0xf6,0x06,0x9d,0x36,0x80,0x74,0x48,0xf7,0x06,0x9b,0x36,0x00
-,0x20,0x74,0x22,0xf7,0x06,0x9b,0x36,0x00,0x40,0x75,0x08,0xe8,0x91,0x00,0x72,0x30
-,0xe9,0x22,0x00,0x26,0xa1,0x0c,0x00,0xa9,0x60,0x00,0x75,0x24,0x81,0x0e,0x66,0x37
-,0x00,0x08,0xe9,0xd2,0xec,0xc7,0x06,0x4c,0x37,0x00,0x00,0xe8,0x71,0x00,0x72,0x10
-,0xb8,0x8b,0x03,0xcd,0x39,0xe8,0xd3,0x00,0x73,0x06,0x81,0x0e,0x99,0x36,0x80,0x00
-,0xe9,0xb4,0xec,0x80,0x3e,0x9d,0x36,0x04,0x75,0x0c,0x80,0x3e,0x9e,0x36,0x06,0x74
-,0x46,0xc6,0x06,0x9f,0x36,0x06,0xf7,0x06,0x9b,0x36,0x00,0x01,0x74,0x0c,0x80,0x3e
-,0x9d,0x36,0x08,0x75,0x05,0xc6,0x06,0x9f,0x36,0x0a,0xe8,0x32,0x00,0x72,0xd1,0xe8
-,0x99,0x00,0x80,0x3e,0x9d,0x36,0x08,0x75,0x13,0x81,0x0e,0x99,0x36,0x80,0x00,0xf7
-,0x06,0x9b,0x36,0x00,0x20,0x75,0x08,0xb8,0x8b,0x03,0xcd,0x39,0xe9,0x68,0xec,0xc6
-,0x06,0x9f,0x36,0x0a,0xe9,0x60,0xec,0xb8,0x86,0x03,0xcd,0x3a,0xe9,0x58,0xec,0x26
-,0xa1,0x0c,0x00,0xa9,0x60,0x00,0x74,0x08,0x81,0x26,0xc2,0x34,0xff,0xbf,0xf9,0xc3
-,0xf7,0x06,0x9b,0x36,0x00,0x40,0x74,0x13,0x81,0x0e,0x66,0x37,0x00,0x08,0xe8,0x4a
-,0x00,0x73,0x06,0x81,0x0e,0x99,0x36,0x80,0x00,0xf9,0xc3,0x81,0x0e,0x9b,0x36,0x00
-,0x40,0x80,0x26,0x6f,0x37,0xfe,0x81,0x26,0x9b,0x36,0x7f,0xff,0xc6,0x06,0xa0,0x36
-,0x00,0xf8,0xc3,0x81,0x0e,0x99,0x36,0x00,0x01,0xe9,0x21,0xec,0x26,0xa1,0x20,0x00
-,0xa3,0xfb,0x36,0xa3,0xaa,0x34,0x26,0xa1,0x22,0x00,0xa3,0xfd,0x36,0xa3,0xac,0x34
-,0x26,0xa1,0x24,0x00,0xa3,0xff,0x36,0xa3,0xae,0x34,0xc3,0xa1,0x05,0x37,0x26,0x3b
-,0x06,0x20,0x00,0x75,0x19,0xa1,0x07,0x37,0x26,0x3b,0x06,0x22,0x00,0x75,0x0f,0xa1
-,0x09,0x37,0x26,0x3b,0x06,0x24,0x00,0x75,0x05,0xe8,0x02,0x00,0xf8,0xc3,0x51,0x1e
-,0x06,0x8b,0xc7,0x8d,0x36,0x20,0x00,0xbf,0x05,0x37,0xb9,0x03,0x00,0x1e,0x06,0x1f
-,0x07,0xf3,0xa5,0x8b,0xf8,0x8d,0x36,0x20,0x00,0xbf,0xa0,0x34,0xb9,0x03,0x00,0xf3
-,0xa5,0x07,0x1f,0x59,0x8b,0xf8,0xa1,0x07,0x37,0xa3,0xa6,0x34,0xa1,0x09,0x37,0xa3
-,0xa8,0x34,0xf9,0xc3,0xc6,0x06,0xb6,0x34,0x01,0xe9,0x8b,0xeb,0xe8,0x87,0x08,0x8b
-,0xf0,0x05,0x12,0x00,0x26,0x29,0x06,0x0e,0x00,0x26,0x8b,0x44,0x2a,0x26,0x3a,0x06
-,0x0e,0x00,0x75,0x5b,0x26,0x83,0x2e,0x0e,0x00,0x02,0x80,0xfc,0x27,0x75,0x50,0x26
-,0x8b,0x44,0x2c,0xa9,0xff,0xff,0x75,0x47,0x8b,0xfe,0x33,0xc0,0x26,0xf6,0x45,0x3c
-,0x80,0x74,0x06,0x26,0x8a,0x45,0x3a,0x24,0x1f,0x03,0xf8,0x26,0x80,0x7d,0x45,0x09
-,0x75,0x2d,0x8c,0xc2,0x8e,0x06,0x38,0x34,0x8e,0xda,0x8b,0x0e,0x0e,0x00,0x26,0x89
-,0x0e,0x0e,0x00,0x8d,0x74,0x2c,0xbf,0x18,0x00,0xf3,0xa4,0x33,0xc0,0x8e,0xd8,0x26
-,0xc7,0x06,0x04,0x00,0xb5,0x3f,0x26,0xc7,0x06,0x06,0x00,0x06,0x00,0xcd,0x50,0xb8
-,0x06,0x80,0xe9,0xef,0xe9,0x26,0xa1,0x0c,0x00,0xa3,0x93,0x37,0x83,0x0e,0x99,0x36
-,0x01,0xe9,0x00,0xeb,0x26,0x80,0x3e,0x1c,0x00,0xff,0x75,0x2f,0x26,0x80,0x3e,0x1e
-,0x00,0xff,0x75,0x27,0x26,0xf7,0x06,0x0c,0x00,0x40,0x00,0x75,0x1b,0xa1,0xd1,0x36
-,0x26,0xa3,0x1a,0x00,0xa1,0xd3,0x36,0x26,0xa3,0x1c,0x00,0xa1,0xd5,0x36,0x26,0xa3
-,0x1e,0x00,0xb8,0x0a,0x80,0xe8,0x36,0x07,0xe9,0xe2,0xea,0xff,0x06,0x90,0x34,0xbe
-,0x0a,0x00,0xc6,0x06,0xb6,0x34,0x01,0xf6,0x06,0x9d,0x36,0x80,0x75,0x05,0x83,0x0e
-,0xc2,0x34,0x01,0xe9,0xb6,0xea,0x80,0x3e,0x9d,0x36,0x0a,0x75,0x0f,0x26,0xa1,0x0c
-,0x00,0x25,0x07,0x00,0x3d,0x04,0x00,0x75,0x03,0xe8,0x79,0x00,0xa1,0xf3,0x36,0x86
-,0xe0,0xe7,0x1e,0xa3,0xe3,0x36,0x81,0x26,0x0b,0x37,0x00,0x03,0x81,0x26,0x0d,0x37
-,0x7b,0x7f,0x83,0x0e,0x0d,0x37,0x48,0xe8,0x1e,0x00,0x26,0xa1,0x0c,0x00,0x25,0x07
-,0x00,0x3d,0x04,0x00,0x74,0x09,0x26,0xf7,0x06,0x0c,0x00,0x20,0x00,0x75,0x06,0xb8
-,0x01,0x00,0xe9,0x3f,0xe9,0xe9,0x5f,0xea,0xc7,0x06,0x41,0x37,0x00,0x00,0xb8,0x7f
-,0x03,0xcd,0x3a,0xa1,0x1d,0x37,0xa3,0xc4,0x34,0x86,0xe0,0x68,0x7f,0x03,0x1f,0xa3
-,0x06,0x00,0x33,0xc0,0x8e,0xd8,0xa1,0x0b,0x37,0xa3,0xb2,0x34,0xa1,0x0d,0x37,0xa3
-,0xb4,0x34,0xa1,0xf3,0x36,0xa3,0xc8,0x34,0xa1,0xef,0x36,0xa3,0x9c,0x34,0xa1,0xf1
-,0x36,0xa3,0x9e,0x34,0xc3,0x80,0x0e,0x9d,0x36,0x80,0xbe,0x00,0x00,0xe8,0xb4,0x07
-,0xb8,0x7b,0x03,0xcd,0x3a,0xb8,0x7c,0x03,0xcd,0x39,0xc7,0x06,0x33,0x37,0x02,0x00
-,0xa1,0xe5,0x36,0xe7,0x2e,0xa1,0xe7,0x36,0xe7,0x3e,0xb8,0x82,0x03,0xcd,0x3a,0xf7
-,0x06,0x9b,0x36,0x00,0x20,0x75,0x03,0xe8,0xfd,0x06,0xa1,0xd3,0x36,0xa3,0xef,0x36
-,0xa3,0x9c,0x34,0xa1,0xd5,0x36,0xa3,0xf1,0x36,0xa3,0x9e,0x34,0xc3,0xf6,0x06,0x9d
-,0x36,0x80,0x74,0x31,0xbe,0x22,0x00,0xe9,0x17,0x00,0xf6,0x06,0x9d,0x36,0x80,0x74
-,0x24,0xbe,0x23,0x00,0xe9,0x0a,0x00,0xf6,0x06,0x9d,0x36,0x80,0x74,0x17,0xbe,0x24
-,0x00,0x56,0xe8,0xa8,0x05,0x8c,0xc0,0x3d,0xff,0xff,0x5e,0x74,0x05,0xe8,0xd7,0xef
-,0xcd,0x50,0xe9,0x1f,0xe8,0xe9,0x9f,0xe9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0xb8,0x84,0x03,0xcd,0x3a,0xb8,0x8a,0x03,0xcd,0x39,0xe9,0xf7,0x00,0x80,0x3e,0xa0
-,0x36,0x08,0x75,0x2e,0xa9,0xd0,0x07,0x75,0x2c,0xa1,0xb1,0x36,0x0d,0x00,0x04,0xe7
-,0x08,0xe5,0x00,0x25,0xff,0x73,0xe7,0x00,0xb8,0x8a,0x03,0xcd,0x3a,0xe8,0xc3,0x06
-,0x33,0xc0,0xe7,0x0e,0xe5,0x0a,0x25,0xc3,0x17,0xe7,0x0a,0xcd,0x54,0xc6,0x06,0xa0
-,0x36,0x00,0xe9,0x68,0xe9,0xbe,0x04,0x00,0xe9,0x3f,0xe9,0x83,0x26,0x9b,0x36,0xbf
-,0xc6,0x06,0x71,0x37,0x03,0xb8,0x86,0x03,0xcd,0x3a,0xb8,0x88,0x03,0xcd,0x3a,0xb8
-,0x83,0x03,0xcd,0x3a,0xb8,0x87,0x03,0xcd,0x39,0x81,0x0e,0xc2,0x34,0x00,0x20,0xe9
-,0x92,0x00,0xe8,0x49,0x06,0xb8,0x87,0x03,0xcd,0x39,0xbb,0xff,0x7f,0xcd,0x53,0xb8
-,0x84,0x03,0xcd,0x3a,0xb8,0x88,0x03,0xcd,0x3a,0xb8,0x8b,0x03,0xcd,0x3a,0xb8,0x83
-,0x03,0xcd,0x3a,0xb8,0x86,0x03,0xcd,0x3a,0xb8,0x85,0x03,0xcd,0x3a,0xc3,0xe5,0x00
-,0x25,0xff,0x53,0xe7,0x00,0x83,0x0e,0xc2,0x34,0x40,0x83,0x26,0xc2,0x34,0xef,0xe8
-,0x0c,0x06,0xbb,0xff,0x7f,0xcd,0x53,0xb8,0x8a,0x03,0xcd,0x3a,0xb8,0x85,0x03,0xcd
-,0x3a,0xb8,0x86,0x03,0xcd,0x3a,0xb8,0x83,0x03,0xcd,0x3a,0xb8,0x87,0x03,0xcd,0x3a
-,0xb8,0x8b,0x03,0xcd,0x3a,0xb8,0x84,0x03,0xcd,0x3a,0xb8,0x89,0x03,0xcd,0x3a,0xc3
-,0x83,0x0e,0xc2,0x34,0x50,0xe8,0x18,0x04,0xe8,0xd3,0x05,0xf6,0x06,0x6f,0x37,0x01
-,0x75,0x12,0xb8,0x89,0x03,0xcd,0x39,0x83,0x3e,0x0f,0x37,0x00,0x75,0x06,0xc7,0x06
-,0x0f,0x37,0x04,0x00,0xa1,0x9d,0x36,0x80,0xfc,0x08,0x74,0x05,0xb8,0x84,0x03,0xcd
-,0x39,0xe5,0x02,0x0d,0x01,0x08,0x25,0xef,0xff,0xe7,0x02,0xa1,0x9d,0x36,0x86,0xe0
-,0x32,0xe4,0x8b,0xf0,0xd1,0xee,0x33,0xc0,0x0d,0x20,0x00,0x09,0x06,0xad,0x36,0xa1
-,0xad,0x36,0xe7,0x04,0xe9,0x53,0xe8,0xe9,0x5a,0xe8,0x33,0xc0,0xa0,0x1b,0x37,0xd1
-,0xe0,0x3a,0x06,0xa0,0x36,0x75,0x03,0xe9,0xba,0xff,0xe9,0x60,0xe8,0xc7,0x06,0x41
-,0x37,0x00,0x00,0xe8,0xc1,0xe1,0xe8,0x6a,0x06,0x33,0xc0,0x0d,0x41,0x00,0xe7,0x56
-,0xa1,0xb1,0x36,0x0d,0x00,0x10,0xe7,0x08,0xe5,0x02,0x25,0xf9,0xff,0x0d,0x03,0x00
-,0xe7,0x02,0xa1,0xb3,0x36,0xe7,0x0a,0xa1,0xaf,0x36,0xe7,0x06,0xa1,0xad,0x36,0xe7
-,0x04,0xe8,0x7c,0x03,0xe8,0x9f,0x03,0xc7,0x06,0x1d,0x37,0x00,0xc8,0xc7,0x06,0x0b
-,0x37,0x00,0x03,0xc7,0x06,0x0d,0x37,0x7b,0x7f,0x33,0xc0,0xa3,0x99,0x36,0xa3,0x9b
-,0x36,0xa3,0x9d,0x36,0xa3,0x9f,0x36,0xa3,0x4c,0x37,0xa3,0xf3,0x36,0xa3,0xef,0x36
-,0xa3,0xf1,0x36,0xe8,0x82,0xfd,0xc6,0x06,0x9f,0x36,0x02,0xe9,0xef,0xe7,0xe5,0x02
-,0x0d,0x01,0x88,0x25,0xef,0xff,0x0d,0x00,0x40,0x0d,0x00,0x04,0xe7,0x02,0xe8,0xf2
-,0x05,0xe5,0x0a,0x0d,0x40,0x00,0xe7,0x0a,0x33,0xc0,0xa3,0x81,0x37,0xa3,0x85,0x37
-,0xa3,0x83,0x37,0xa3,0x87,0x37,0xa3,0x89,0x37,0xe5,0x00,0x0d,0x00,0x84,0xe7,0x00
-,0xb8,0x8c,0x03,0xcd,0x39,0xb8,0x80,0x00,0xcd,0x35,0xc7,0x06,0xaa,0x02,0xff,0xff
-,0xe5,0x00,0x25,0xff,0x7b,0xe7,0x00,0x81,0x0e,0x9a,0x37,0x80,0x00,0xb8,0x7e,0x03
-,0xcd,0x39,0x33,0xc0,0xe7,0x0e,0xbe,0x08,0x00,0x8e,0x06,0x38,0x34,0xe8,0xa7,0xed
-,0x83,0x26,0xef,0x34,0xdf,0xff,0x06,0x81,0x37,0xcd,0x50,0x83,0x0e,0xef,0x34,0x20
-,0xc3,0xf7,0x06,0x9a,0x37,0x80,0x00,0x74,0x3d,0xa9,0xd0,0x07,0x74,0x10,0xa9,0x00
-,0x04,0x74,0x12,0x33,0xc0,0xe7,0x0e,0xff,0x06,0x87,0x37,0xe9,0xd2,0xff,0xff,0x06
-,0x85,0x37,0xe9,0xcb,0xff,0xff,0x06,0x83,0x37,0xe9,0xc4,0xff,0x83,0x26,0x9a,0x37
-,0x7f,0xa1,0x89,0x37,0x03,0x06,0x87,0x37,0x3d,0x05,0x00,0x7f,0x01,0xc3,0xbb,0xff
-,0x7f,0xcd,0x53,0xe9,0x00,0x00,0xe5,0x02,0x25,0xff,0xfb,0x25,0xef,0xff,0x0d,0x01
-,0x00,0xe7,0x02,0xa1,0x83,0x37,0x3b,0x06,0x46,0x37,0x7f,0x2a,0xa1,0x85,0x37,0x3b
-,0x06,0x48,0x37,0x7c,0x21,0xa1,0x89,0x37,0x03,0x06,0x87,0x37,0x3d,0x05,0x00,0x7f
-,0x15,0xc6,0x06,0x9f,0x36,0x04,0xe5,0x02,0x25,0xff,0xf7,0x0d,0x01,0x00,0x25,0xef
-,0xff,0xe7,0x02,0xe9,0xf7,0xe6,0xbe,0x01,0x00,0xf7,0x06,0x9b,0x36,0x03,0x00,0x74
-,0x0a,0x83,0x26,0x9b,0x36,0xfc,0x83,0x0e,0xc2,0x34,0x04,0xe9,0xd0,0xe6,0xb8,0x7b
-,0x03,0xcd,0x39,0xe5,0x02,0x0d,0x01,0x60,0x25,0xef,0xff,0xe7,0x02,0xc7,0x06,0xf1
-,0x34,0x20,0x03,0xb8,0x8e,0x03,0xcd,0x39,0xc3,0x81,0x26,0xc2,0x34,0x7f,0xff,0x80
-,0x0e,0x6f,0x37,0x01,0xf7,0x06,0x9b,0x36,0x03,0x00,0x74,0xd2,0xb8,0x7b,0x03,0xcd
-,0x3a,0xb8,0x7d,0x03,0xcd,0x39,0x83,0x26,0x9b,0x36,0xef,0x33,0xc0,0xb0,0x8a,0xa2
-,0x9f,0x36,0xa2,0x9d,0x36,0xc7,0x06,0x4c,0x37,0x01,0x00,0xc7,0x06,0x0f,0x37,0x04
-,0x00,0xf7,0x06,0x9b,0x36,0x40,0x00,0x75,0x06,0xc7,0x06,0x0f,0x37,0x03,0x00,0xb8
-,0x8d,0x03,0xcd,0x39,0xe8,0x00,0xd5,0xe5,0x02,0x0d,0x01,0x40,0x25,0xef,0xff,0x8b
-,0xd8,0xb8,0x7c,0x03,0xcd,0x39,0xc7,0x06,0x33,0x37,0x02,0x00,0x8b,0xc3,0x0d,0x00
-,0x20,0x25,0xf9,0xff,0x0b,0x06,0xe8,0x3a,0xe7,0x02,0xc3,0xff,0x0e,0xf1,0x34,0x75
-,0x01,0xc3,0xe5,0x4e,0xa9,0x01,0x00,0x75,0x12,0xe5,0x00,0xa9,0x00,0x04,0x75,0x05
-,0x0d,0x00,0x04,0xe7,0x00,0xb8,0x8e,0x03,0xcd,0x39,0xc3,0xe5,0x00,0xa9,0x00,0x04
-,0x74,0xf3,0x25,0xff,0xfb,0xe7,0x00,0xe9,0xeb,0xff,0xc6,0x06,0xa0,0x36,0x04,0x83
-,0x26,0x9b,0x36,0xfc,0x81,0x0e,0x9b,0x36,0x80,0x00,0xe9,0x10,0xe6,0xb8,0x8e,0x03
-,0xcd,0x3a,0xcd,0x54,0x81,0x0e,0xaf,0x36,0x00,0x18,0xa1,0xaf,0x36,0xe7,0x06,0xb8
-,0x7b,0x03,0xcd,0x39,0xa1,0xd3,0x36,0xa3,0x8f,0x37,0xa1,0xd5,0x36,0xa3,0x91,0x37
-,0xc7,0x06,0x8b,0x37,0x02,0x00,0xc7,0x06,0x8d,0x37,0x02,0x00,0x83,0x0e,0x99,0x36
-,0x40,0xe9,0xd9,0xe5,0x80,0x3e,0x9f,0x36,0x06,0x75,0x15,0xa9,0xd0,0x07,0x75,0xec
-,0x25,0x00,0x18,0x75,0x0e,0xff,0x0e,0x8b,0x37,0x75,0xe1,0xc6,0x06,0x9f,0x36,0x08
-,0xe9,0xba,0xe5,0xff,0x0e,0x8d,0x37,0x75,0xd3,0xbe,0x08,0x00,0xe9,0x9f,0xe5,0xb8
-,0x7b,0x03,0xcd,0x39,0xf7,0x06,0x9b,0x36,0x00,0x20,0x74,0x08,0xc6,0x06,0x9f,0x36
-,0x0a,0xe9,0x0d,0x00,0xf7,0x06,0x9b,0x36,0x00,0x40,0x74,0x0b,0xb8,0x8b,0x03,0xcd
-,0x39,0x81,0x0e,0x99,0x36,0x80,0x00,0xe9,0x83,0xe5,0xb8,0x7b,0x03,0xcd,0x39,0xc7
-,0x06,0x8b,0x37,0x04,0x00,0xc7,0x06,0x8d,0x37,0x04,0x00,0x81,0x0e,0x99,0x36,0x00
-,0x02,0xe9,0x69,0xe5,0xf6,0x06,0x9d,0x36,0x80,0x75,0x1b,0xa9,0xd0,0x07,0x75,0xeb
-,0xa9,0x00,0x18,0x75,0x0c,0xff,0x0e,0x8d,0x37,0x75,0xe0,0xe8,0x17,0xfb,0xe9,0x4c
-,0xe5,0xb8,0x82,0x03,0xcd,0x39,0xc3,0xff,0x0e,0x8b,0x37,0x75,0xce,0xbe,0x09,0x00
-,0xe9,0x2b,0xe5,0xc7,0x06,0x3d,0x37,0x00,0x00,0xc7,0x06,0x9b,0x36,0x00,0x00,0xe8
-,0x3c,0x02,0x81,0x26,0xaf,0x36,0xff,0xe7,0xa1,0xaf,0x36,0xe7,0x06,0x81,0x26,0x9b
-,0x36,0xff,0x7f,0xe5,0x02,0x0d,0x01,0x00,0x25,0xef,0xff,0x25,0xff,0xdf,0xe7,0x02
-,0xbb,0xff,0x7f,0xcd,0x53,0x33,0xc0,0xa3,0x9d,0x36,0xa3,0x9f,0x36,0xe8,0x50,0x00
-,0xe8,0x73,0x00,0xb8,0x81,0x03,0xcd,0x39,0xc3,0xf7,0x06,0x9b,0x36,0x03,0x00,0x74
-,0x0d,0xc6,0x06,0x9f,0x36,0x02,0xc6,0x06,0xa0,0x36,0x00,0xe9,0xdf,0xe4,0x83,0x0e
-,0x9b,0x36,0x10,0xc7,0x06,0x99,0x36,0x00,0x00,0xe8,0xe7,0x02,0xe5,0x56,0x0d,0x02
-,0x00,0xe7,0x56,0xc7,0x06,0xa8,0x02,0x00,0x00,0x8b,0x36,0x3d,0x37,0xe8,0x44,0x02
-,0xc6,0x06,0xa0,0x36,0x0e,0xe9,0xb5,0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x06,0xb8,0x8a,0x03,0xcd,0x3a,0xb8,0x85,0x03,0xcd,0x3a,0xb8,0x86,0x03,0xcd,0x3a
-,0xb8,0x83,0x03,0xcd,0x3a,0xb8,0x87,0x03,0xcd,0x3a,0xb8,0x8b,0x03,0xcd,0x3a,0xb8
-,0x88,0x03,0xcd,0x3a,0x07,0xc3,0x06,0xb8,0x88,0x03,0xcd,0x3a,0xb8,0x7b,0x03,0xcd
-,0x3a,0xb8,0x82,0x03,0xcd,0x3a,0xb8,0x7f,0x03,0xcd,0x3a,0xb8,0x7c,0x03,0xcd,0x3a
-,0xb8,0x7e,0x03,0xcd,0x3a,0xb8,0x80,0x03,0xcd,0x3a,0xb8,0x81,0x03,0xcd,0x3a,0xb8
-,0x84,0x03,0xcd,0x3a,0xb8,0x89,0x03,0xcd,0x3a,0xb8,0x7d,0x03,0xcd,0x3a,0xb8,0x8d
-,0x03,0xcd,0x3a,0xc7,0x06,0x41,0x37,0x00,0x00,0x07,0xc3,0x06,0x8e,0x06,0x38,0x34
-,0x1f,0x8b,0x0e,0x0e,0x00,0x26,0x89,0x0e,0x0e,0x00,0xbe,0x18,0x00,0xbf,0x18,0x00
-,0xf3,0xa4,0x06,0x1e,0x07,0xcd,0x34,0x07,0x33,0xc0,0x8e,0xd8,0xc3,0x26,0xf6,0x06
-,0x20,0x00,0x80,0x74,0x44,0x33,0xc0,0x26,0xa0,0x26,0x00,0x24,0x1f,0x8b,0xf0,0x26
-,0x8b,0x5c,0x28,0x89,0x1e,0x6a,0x37,0x06,0x8e,0x06,0x38,0x34,0x1f,0xc0,0xe3,0x04
-,0x26,0x88,0x5c,0x28,0x8b,0xc6,0xb9,0x06,0x00,0xbe,0x20,0x00,0xbf,0x1a,0x00,0xf3
-,0xa4,0x8b,0xc8,0x83,0xc7,0x06,0xf3,0xa4,0x26,0x81,0x26,0x26,0x00,0x1f,0x80,0x26
-,0x81,0x36,0x26,0x00,0x00,0x80,0xe9,0xa9,0xff,0x26,0x8b,0x1e,0x28,0x00,0x89,0x1e
-,0x6a,0x37,0x06,0x8e,0x06,0x38,0x34,0x1f,0xc0,0xe3,0x04,0x26,0x88,0x1e,0x28,0x00
-,0xb9,0x06,0x00,0xbe,0x20,0x00,0xbf,0x1a,0x00,0xf3,0xa4,0xe9,0x84,0xff,0x86,0xc4
-,0xa3,0x68,0x37,0xe8,0x87,0xff,0xf7,0x06,0x6a,0x37,0x0f,0x00,0x74,0x10,0x80,0x3e
-,0x9e,0x36,0x00,0x75,0x09,0xbe,0x00,0x00,0xe8,0xac,0xe9,0xcd,0x50,0xc3,0xc3,0x50
-,0x56,0x06,0x33,0xc0,0x26,0xf6,0x06,0x20,0x00,0x80,0x74,0x06,0x26,0xa0,0x26,0x00
-,0x24,0x1f,0x8b,0xf0,0x26,0x8b,0x5c,0x26,0x86,0xfb,0x83,0xeb,0x04,0x74,0x4f,0x83
-,0xc6,0x2a,0x8c,0xc0,0x8e,0xd8,0xb9,0x07,0x00,0x33,0xc0,0x8e,0xc0,0xbf,0x72,0x37
-,0xf3,0xab,0x33,0xc9,0x8a,0x0c,0x80,0xf9,0x00,0x75,0x03,0xe9,0x30,0x00,0x3b,0xd9
-,0x73,0x03,0xe9,0x29,0x00,0x2b,0xd9,0x8a,0x44,0x01,0x25,0x3f,0x00,0x74,0x19,0x3d
-,0x0b,0x00,0x7d,0x14,0xd1,0xe0,0x8b,0xf8,0x2e,0x8b,0xbd,0x5c,0x49,0x8d,0x74,0x02
-,0x83,0xe9,0x02,0xf3,0xa4,0xe9,0x02,0x00,0x03,0xf1,0x23,0xdb,0x75,0xc4,0x33,0xc0
-,0x8e,0xd8,0x07,0x5e,0x58,0xc3,0x33,0xc0,0x26,0xf6,0x06,0x20,0x00,0x80,0x74,0x06
-,0x26,0xa0,0x26,0x00,0x24,0x1f,0xc3,0xe5,0x0a,0x25,0xc3,0xbf,0xe7,0x0a,0xb8,0x86
-,0x03,0xcd,0x39,0xb8,0x83,0x03,0xcd,0x39,0x81,0x26,0x9b,0x36,0x7c,0xdf,0xb8,0x85
-,0x03,0xcd,0x3a,0xe5,0x02,0x25,0xff,0xf3,0x0d,0x01,0x00,0x25,0xef,0xff,0xe7,0x02
-,0xe5,0x00,0x25,0xff,0x53,0xe7,0x00,0xa1,0xe7,0x36,0x25,0xff,0xfe,0xa3,0xe7,0x36
-,0xe7,0x3e,0x83,0x26,0x99,0x36,0xcf,0x81,0x0e,0xaf,0x36,0x00,0x10,0xa1,0xaf,0x36
-,0xe7,0x06,0xc3,0xe5,0x02,0x0d,0x01,0x0c,0x25,0xef,0xff,0xe7,0x02,0xa1,0xe7,0x36
-,0x0d,0x00,0x01,0xe7,0x3e,0xa3,0xe7,0x36,0x81,0x0e,0x9b,0x36,0x00,0x20,0x83,0x0e
-,0x99,0x36,0x20,0x81,0x26,0x9b,0x36,0x7c,0xbf,0x81,0x0e,0xaf,0x36,0x00,0x10,0xa1
-,0xaf,0x36,0xe7,0x06,0xb8,0x86,0x03,0xcd,0x39,0xb8,0x85,0x03,0xcd,0x39,0xb8,0x83
-,0x03,0xcd,0x3a,0xc3,0x0b,0xf6,0x75,0x49,0x06,0x8e,0x06,0x32,0x34,0x80,0x3e,0xe0
-,0x34,0x01,0x75,0x1b,0x26,0x89,0x36,0x06,0x00,0x8e,0x06,0x32,0x34,0x26,0xf7,0x06
-,0x0a,0x00,0x00,0x20,0x74,0x07,0x26,0x81,0x0e,0x08,0x00,0x00,0x20,0x07,0xc3,0x80
-,0x3e,0xe3,0x34,0x01,0x75,0x19,0x26,0x89,0x36,0x06,0x00,0x8e,0x06,0x32,0x34,0x26
-,0xf7,0x06,0x0a,0x00,0x00,0x10,0x74,0x07,0x26,0x81,0x0e,0x08,0x00,0x00,0x10,0x07
-,0xc3,0xe9,0xb4,0xff,0x50,0x51,0x57,0x33,0xc0,0xb9,0x06,0x00,0x8e,0xc0,0xbf,0xd1
-,0x36,0xf3,0xae,0x5f,0x74,0x0c,0x26,0xf6,0x06,0x00,0x00,0xc0,0x75,0x04,0xf8,0x59
-,0x58,0xc3,0xf9,0xe9,0xf9,0xff,0x8b,0x05,0x0b,0x45,0x02,0x0b,0x45,0x04,0xc3,0x52
-,0x50,0xe5,0x06,0x25,0x1e,0x00,0x3d,0x1e,0x00,0x75,0xf6,0xb8,0x01,0x80,0xe7,0x5a
-,0x58,0x5a,0xc3,0xe8,0xe9,0xff,0x50,0xe5,0x02,0x25,0xff,0x7f,0x0d,0x01,0x00,0x25
-,0xef,0xff,0xe7,0x02,0x0d,0x00,0x80,0xe7,0x02,0xa1,0xad,0x36,0xe7,0x04,0xa1,0xaf
-,0x36,0xe7,0x06,0x58,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x2e,0x2b,0xce,0x41,0x10,0x42,0x7b,0x41,0x30,0x41,0xa2,0x41,0xaf,0x45,0x44,0x29
-,0xc7,0x2a,0xc7,0x2a,0x60,0x39,0xf4,0x3a,0x5c,0x3c,0x09,0x3d,0xb1,0x3d,0x34,0x3f
-,0xc7,0x2a,0x3c,0x3f,0xc7,0x2a,0xc4,0x3f,0x16,0x40,0x16,0x40,0xed,0x40,0xfa,0x40
-,0x07,0x41,0xc7,0x2a,0xc7,0x2a,0xc7,0x2a,0xc7,0x2a,0xd6,0x52,0x00,0x00,0x01,0x37
-,0xe9,0x36,0xf3,0x36,0xef,0x36,0x1d,0x37,0x0d,0x37,0x0b,0x37,0x9c,0x37,0x03,0x37
-,0xfb,0x36,0x62,0x2d,0x40,0x06,0xd1,0x2d,0xf4,0x01,0xba,0x44,0x40,0x06,0x8c,0x43
-,0x64,0x00,0xe8,0x2c,0xc8,0x00,0xd8,0x2b,0x05,0x00,0xe9,0x45,0x50,0x00,0x97,0x45
-,0xfa,0x00,0xae,0x2d,0x04,0x01,0x6a,0x42,0x02,0x00,0xf6,0x2c,0xbc,0x02,0x93,0x2d
-,0xdc,0x05,0x1d,0x2d,0x64,0x00,0xa1,0x2d,0x14,0x00,0xd7,0x3a,0x08,0x07,0x81,0x2d
-,0x64,0x00,0xb3,0x3e,0x02,0x00,0x30,0x43,0x64,0x00,0xc5,0x2c,0xf4,0x01,0x8b,0x44
-,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x80,0x3e,0xfd,0x34,0x02,0x74,0x0c,0xe8,0x20,0x05,0xc7,0x06,0xa1,0x36,0x00,0x00
-,0xe9,0x9a,0xf8,0xff,0x06,0xc0,0x33,0xe8,0x10,0x05,0x8b,0x36,0x3d,0x37,0xe8,0x73
-,0xfe,0xc3,0xcd,0x34,0xe9,0xe8,0x05,0xc7,0x06,0xa3,0x36,0x00,0x00,0xc7,0x06,0x41
-,0x37,0x00,0x00,0xe8,0xed,0xfe,0x33,0xc0,0x0d,0x41,0x00,0xe7,0x56,0xa1,0xb1,0x36
-,0x0d,0x00,0x10,0xe7,0x08,0xa1,0xb3,0x36,0xe7,0x0a,0xa1,0xaf,0x36,0xe7,0x06,0xa1
-,0xad,0x36,0xe7,0x04,0xe8,0x2b,0x09,0xc7,0x06,0x1d,0x37,0x00,0xc8,0xc7,0x06,0x0b
-,0x37,0x00,0x03,0xc7,0x06,0x0d,0x37,0x7b,0x7f,0x33,0xc0,0xa3,0x9b,0x36,0xa3,0x9d
-,0x36,0xc7,0x06,0x4c,0x37,0x01,0x00,0xc6,0x06,0x9e,0x36,0xff,0xc7,0x06,0x05,0x37
-,0x00,0x00,0xc7,0x06,0x07,0x37,0x00,0x00,0xc7,0x06,0x09,0x37,0x00,0x00,0xa3,0xf3
-,0x36,0xa3,0xef,0x36,0xa3,0xf1,0x36,0xe8,0xfe,0xf5,0xe5,0x02,0x25,0xf9,0xff,0x0d
-,0x03,0x00,0x0d,0x00,0x88,0x25,0xef,0xff,0x0d,0x00,0x40,0x0d,0x00,0x04,0xe7,0x02
-,0xb8,0x8f,0x03,0xcd,0x39,0xb8,0x80,0x00,0xcd,0x35,0xc7,0x06,0xaa,0x02,0xff,0xff
-,0xa1,0xa9,0x36,0xa3,0xa7,0x36,0x0d,0x00,0xa4,0x0d,0x00,0x08,0xe7,0x00,0xa3,0xa9
-,0x36,0xc7,0x06,0xa3,0x36,0x01,0x00,0xc7,0x06,0xa5,0x36,0x0c,0x00,0x83,0x3e,0xa5
-,0x36,0x00,0x75,0x09,0xc7,0x06,0x3d,0x37,0x05,0x00,0xe9,0x13,0xff,0xff,0x0e,0xa5
-,0x36,0xbe,0x11,0x00,0xe8,0x22,0x05,0xb8,0x90,0x03,0xcd,0x39,0xc3,0x83,0x3e,0xa3
-,0x36,0x01,0x74,0xd9,0xc3,0xb8,0x90,0x03,0xcd,0x3a,0x26,0xa0,0x2b,0x00,0x26,0x8b
-,0x1e,0x2c,0x00,0xcd,0x34,0x83,0x3e,0xa3,0x36,0x01,0x74,0x03,0xe9,0xf0,0x04,0x3c
-,0x0f,0x75,0x1e,0x81,0xfb,0x00,0x02,0x75,0x18,0x26,0xa1,0x20,0x00,0xa3,0x05,0x37
-,0x26,0xa1,0x22,0x00,0xa3,0x07,0x37,0x26,0xa1,0x24,0x00,0xa3,0x09,0x37,0xe9,0x09
-,0x00,0xc7,0x06,0x3d,0x37,0x01,0x00,0xe9,0xb6,0xfe,0xc7,0x06,0xa3,0x36,0x02,0x00
-,0xc6,0x06,0x9e,0x36,0xff,0xe8,0xcb,0xfd,0xe8,0x1c,0xd9,0x33,0xc0,0xa3,0x85,0x37
-,0xa3,0x83,0x37,0xa3,0x87,0x37,0xa3,0x89,0x37,0xb8,0x91,0x03,0xcd,0x39,0xb8,0x80
-,0x00,0xcd,0x35,0xc7,0x06,0xaa,0x02,0xff,0xff,0xe5,0x00,0x25,0xff,0x53,0xe7,0x00
-,0x81,0x0e,0x9a,0x37,0x80,0x00,0xb8,0x92,0x03,0xcd,0x39,0x33,0xc0,0xe7,0x0e,0xbe
-,0x08,0x00,0x8e,0x06,0x38,0x34,0xe8,0x8e,0xe5,0x26,0xc7,0x06,0x04,0x00,0x7d,0x4b
-,0x83,0x26,0xef,0x34,0xdf,0xcd,0x50,0x83,0x0e,0xef,0x34,0x20,0xc3,0xf7,0x06,0x9a
-,0x37,0x80,0x00,0x74,0x32,0xa9,0xd0,0x07,0x74,0x0c,0xa9,0x00,0x04,0x74,0x0e,0x33
-,0xc0,0xe7,0x0e,0xe9,0xda,0xff,0xff,0x06,0x85,0x37,0xe9,0xd3,0xff,0xff,0x06,0x83
-,0x37,0xe9,0xcc,0xff,0xc7,0x06,0x3d,0x37,0x01,0x00,0xe9,0x36,0xfe,0x83,0x26,0x9a
-,0x37,0x7f,0xbb,0xff,0x7f,0xcd,0x53,0xe5,0x00,0x0d,0x00,0xac,0xe7,0x00,0xe5,0x02
-,0x25,0xff,0xfb,0x25,0xef,0xff,0x25,0xff,0xf7,0x0d,0x01,0x00,0xe7,0x02,0xa1,0x83
-,0x37,0x3b,0x06,0x46,0x37,0x7f,0xcd,0xa1,0x85,0x37,0x3b,0x06,0x48,0x37,0x7c,0xc4
-,0xc7,0x06,0xa3,0x36,0x03,0x00,0xbe,0x13,0x00,0xe8,0xfd,0x03,0xb8,0x93,0x03,0xcd
-,0x39,0xb8,0x94,0x03,0xcd,0x39,0xb8,0x96,0x03,0xcd,0x39,0xb8,0x95,0x03,0xcd,0x39
-,0xbe,0x06,0x00,0xe8,0xe3,0x03,0xe9,0xd6,0x03,0x83,0x3e,0xa3,0x36,0x03,0x74,0x01
-,0xc3,0xbe,0x13,0x00,0xe8,0xd2,0x03,0xb8,0x94,0x03,0xcd,0x39,0xc3,0xb8,0x94,0x03
-,0xcd,0x3a,0x26,0xa0,0x2b,0x00,0x26,0x8b,0x1e,0x2c,0x00,0xcd,0x34,0x83,0x3e,0xa3
-,0x36,0x03,0x74,0x03,0xe9,0xa8,0x03,0x3c,0x0d,0x75,0x3e,0x83,0xfb,0x00,0x75,0x39
-,0xe5,0x02,0x0d,0x00,0x20,0xe7,0x02,0xb8,0x93,0x03,0xcd,0x3a,0xc7,0x06,0xa3,0x36
-,0x04,0x00,0xbe,0x00,0x00,0xe8,0x0c,0xfc,0xc6,0x06,0x9d,0x36,0x80,0xc6,0x06,0x9e
-,0x36,0x00,0xc7,0x06,0x33,0x37,0x02,0x00,0xb8,0x9a,0x03,0xcd,0x39,0xe8,0xfc,0x00
-,0xc7,0x06,0x4c,0x37,0x00,0x00,0xe9,0x66,0x03,0xc7,0x06,0x3d,0x37,0x08,0x00,0xe9
-,0x61,0xfd,0x83,0x3e,0xa3,0x36,0x03,0x75,0x09,0xc7,0x06,0x3d,0x37,0x05,0x00,0xe9
-,0x51,0xfd,0xe9,0x4a,0x03,0x83,0x3e,0xa3,0x36,0x04,0x74,0x12,0x83,0x3e,0xa3,0x36
-,0x05,0x74,0x0b,0xcd,0x34,0xc7,0x06,0x3d,0x37,0x07,0x00,0xe9,0x35,0xfd,0xc7,0x06
-,0xa3,0x36,0x06,0x00,0xc6,0x06,0x9e,0x36,0xff,0xb8,0x9a,0x03,0xcd,0x3a,0xb8,0x99
-,0x03,0xcd,0x3a,0xb8,0x96,0x03,0xcd,0x3a,0xb8,0x97,0x03,0xcd,0x39,0xb8,0x98,0x03
-,0xcd,0x39,0xb8,0x9b,0x03,0xcd,0x39,0xe9,0x18,0xfd,0xcd,0x34,0x83,0x3e,0xa3,0x36
-,0x04,0x77,0x18,0x83,0x3e,0xa3,0x36,0x03,0x75,0x08,0xf7,0x06,0x9b,0x36,0x00,0x01
-,0x75,0x09,0xc7,0x06,0x3d,0x37,0x01,0x00,0xe9,0xe8,0xfc,0xe9,0xe1,0x02,0xcd,0x34
-,0x83,0x3e,0xa3,0x36,0x02,0x77,0x09,0xc7,0x06,0x3d,0x37,0x01,0x00,0xe9,0xd3,0xfc
-,0x83,0x3e,0xa3,0x36,0x04,0x77,0x05,0xb8,0x96,0x03,0xcd,0x39,0xe9,0xc0,0x02,0x83
-,0x3e,0xa3,0x36,0x03,0x75,0x10,0x26,0xa1,0x0c,0x00,0x25,0x07,0x00,0x50,0x3d,0x04
-,0x00,0x75,0x03,0xe8,0x36,0x00,0xa1,0xf3,0x36,0x86,0xe0,0xe7,0x1e,0xa3,0xe3,0x36
-,0x81,0x26,0x0b,0x37,0x00,0x03,0x81,0x26,0x0d,0x37,0x7b,0x7f,0x83,0x0e,0x0d,0x37
-,0x48,0xe8,0x14,0xf3,0x58,0x3d,0x04,0x00,0x74,0x09,0x26,0xf7,0x06,0x0c,0x00,0x20
-,0x00,0x75,0x06,0xb8,0x01,0x00,0xe9,0x7a,0x02,0xe9,0x86,0xfc,0xa1,0xe5,0x36,0xe7
-,0x2e,0xa1,0xe7,0x36,0xe7,0x3e,0xa1,0xd3,0x36,0xa3,0x9c,0x34,0xa1,0xd5,0x36,0xa3
-,0x9e,0x34,0xc3,0x26,0x80,0x3e,0x1c,0x00,0xff,0x75,0x2f,0x26,0x80,0x3e,0x1e,0x00
-,0xff,0x75,0x27,0x26,0xf7,0x06,0x0c,0x00,0x40,0x00,0x75,0x1b,0xa1,0xd1,0x36,0x26
-,0xa3,0x1a,0x00,0xa1,0xd3,0x36,0x26,0xa3,0x1c,0x00,0xa1,0xd5,0x36,0x26,0xa3,0x1e
-,0x00,0xb8,0x0a,0x80,0xe9,0x2c,0x02,0xe9,0x38,0xfc,0xff,0x06,0x90,0x34,0xbe,0x0a
-,0x00,0xc6,0x06,0xb6,0x34,0x01,0xf6,0x06,0x9d,0x36,0x80,0x75,0x05,0x83,0x0e,0xc2
-,0x34,0x01,0xcd,0x34,0xe9,0x0c,0xfc,0x83,0x3e,0xa3,0x36,0x03,0x75,0x09,0xc7,0x06
-,0x3d,0x37,0x05,0x00,0xe9,0xfc,0xfb,0xe5,0x02,0x0d,0x03,0x00,0x0d,0x00,0x88,0x0d
-,0x00,0x40,0x0d,0x00,0x04,0xe7,0x02,0xc7,0x06,0xa3,0x36,0x05,0x00,0xc6,0x06,0x9e
-,0x36,0xff,0xbe,0x02,0x00,0xe8,0xe1,0x01,0xb8,0x89,0x03,0xcd,0x3a,0xb8,0x9a,0x03
-,0xcd,0x3a,0xb8,0x99,0x03,0xcd,0x39,0xb8,0x97,0x03,0xcd,0x39,0xb8,0x98,0x03,0xcd
-,0x39,0xe9,0xbb,0x01,0x83,0x3e,0xa3,0x36,0x03,0x74,0x0a,0x83,0x3e,0xa3,0x36,0x04
-,0x74,0x03,0xe9,0xaa,0x01,0xbe,0x06,0x00,0xe8,0xae,0x01,0xb8,0x95,0x03,0xcd,0x39
-,0xe9,0x9c,0x01,0x83,0x3e,0xa3,0x36,0x05,0x74,0x03,0xe9,0x92,0x01,0xbe,0x02,0x00
-,0xe8,0x96,0x01,0xb8,0x99,0x03,0xcd,0x39,0xe9,0x84,0x01,0xc7,0x06,0x0f,0x37,0x05
-,0x00,0xe9,0x7b,0x01,0xe5,0x02,0x25,0xff,0xdf,0xe7,0x02,0xc7,0x06,0xa3,0x36,0x07
-,0x00,0xc7,0x06,0x0f,0x37,0x05,0x00,0xe9,0x65,0x01,0xe8,0xd5,0x04,0xc6,0x06,0x9d
-,0x36,0x00,0xc7,0x06,0x9b,0x36,0x00,0x00,0xc7,0x06,0x0f,0x37,0x05,0x00,0xc7,0x06
-,0xa8,0x02,0x00,0x00,0xc7,0x06,0x4c,0x37,0x01,0x00,0xe5,0x02,0x25,0xf9,0xff,0x0d
-,0x03,0x00,0x0d,0x00,0x88,0x25,0xef,0xff,0x0d,0x00,0x40,0x0d,0x00,0x04,0xe7,0x02
-,0xe9,0x67,0xfc,0xb8,0x9a,0x03,0xcd,0x39,0xf7,0x06,0xf4,0x33,0x00,0x10,0x75,0x09
-,0xc7,0x06,0x33,0x37,0x02,0x00,0xe9,0x16,0x01,0xff,0x0e,0x33,0x37,0x74,0x03,0xe9
-,0x0d,0x01,0xff,0x06,0x8e,0x34,0x83,0x0e,0xc2,0x34,0x08,0xc7,0x06,0x3d,0x37,0x03
-,0x00,0xe9,0xff,0xfa,0xc3,0x52,0x50,0xba,0xe0,0x00,0xb8,0x00,0x10,0xef,0x58,0x5a
-,0xc3,0xc7,0x06,0x3d,0x37,0x00,0x00,0xe9,0xe9,0xfa,0xfa,0xe8,0x54,0x04,0xb8,0x80
-,0x03,0x8e,0xc0,0x26,0xc7,0x06,0x04,0x00,0xd8,0x2b,0xb8,0x7f,0x03,0x8e,0xc0,0x26
-,0xc7,0x06,0x04,0x00,0xe8,0x2c,0x33,0xc0,0x8e,0xc0,0xa1,0xa7,0x36,0xa3,0xa9,0x36
-,0xa1,0xa9,0x36,0xe7,0x00,0xa1,0xab,0x36,0xe7,0x02,0xc7,0x06,0x05,0x37,0x00,0x00
-,0xc7,0x06,0x07,0x37,0x00,0x00,0xc7,0x06,0x09,0x37,0x00,0x00,0xc6,0x06,0x9d,0x36
-,0x00,0xc6,0x06,0x9e,0x36,0xff,0xc7,0x06,0x9b,0x36,0x00,0x00,0xc7,0x06,0xa3,0x36
-,0x00,0x00,0xc7,0x06,0x0f,0x37,0x00,0x00,0xc7,0x06,0xa8,0x02,0x00,0x00,0xc7,0x06
-,0x4c,0x37,0x01,0x00,0x81,0x26,0xaf,0x36,0xff,0xe7,0xa1,0xaf,0x36,0xe7,0x06,0xbb
-,0xff,0x7f,0xcd,0x53,0xe8,0x7c,0xf9,0xe5,0x56,0x0d,0x02,0x00,0xe7,0x56,0xfb,0xc3
-,0x8d,0x3e,0xc0,0x53,0x8d,0x36,0xf0,0x38,0xb9,0x0e,0x00,0x8b,0x1e,0x30,0x34,0x89
-,0x5c,0x02,0x2e,0x8b,0x45,0x02,0x89,0x44,0x06,0x2e,0x8b,0x05,0x89,0x44,0x04,0x83
-,0xc7,0x04,0x83,0xc6,0x10,0xe2,0xe8,0xb8,0x80,0x03,0x8e,0xc0,0x26,0xc7,0x06,0x04
-,0x00,0xe2,0x51,0xb8,0x7f,0x03,0x8e,0xc0,0x26,0xc7,0x06,0x04,0x00,0xb2,0x52,0x33
-,0xc0,0x8e,0xc0,0xc7,0x06,0xa1,0x36,0x01,0x00,0xc7,0x06,0x0f,0x37,0x05,0x00,0xc3
-,0x33,0xff,0x8e,0x06,0xa6,0x02,0x8b,0x36,0xa4,0x02,0x2e,0xff,0xa4,0xa0,0x53,0xe8
-,0x8c,0xdb,0xc3,0xe8,0x48,0xf7,0xe9,0xf6,0xff,0x8e,0x06,0x38,0x34,0xe8,0x07,0xe1
-,0x26,0xc7,0x06,0x04,0x00,0xdf,0x4f,0xcd,0x50,0xc3,0x26,0xc7,0x06,0x0a,0x00,0x00
-,0x00,0x26,0xff,0x26,0x04,0x00,0xcd,0x34,0xe9,0xd4,0xff,0xa1,0xd1,0x36,0x26,0x39
-,0x06,0x1a,0x00,0x75,0x22,0xa1,0xd3,0x36,0x26,0x39,0x06,0x1c,0x00,0x75,0x18,0xa1
-,0xd5,0x36,0x26,0x39,0x06,0x1e,0x00,0x75,0x0e,0x26,0xf7,0x06,0x0c,0x00,0x40,0x00
-,0x74,0x05,0x83,0x0e,0x66,0x37,0x40,0x81,0x0e,0xaf,0x36,0x00,0x10,0xa1,0xaf,0x36
-,0xe7,0x06,0x83,0x3e,0xa3,0x36,0x02,0x75,0x05,0xcd,0x34,0xe9,0x56,0xfb,0x83,0x3e
-,0xa3,0x36,0x00,0x74,0xb1,0x83,0x3e,0xa3,0x36,0x05,0x77,0xaa,0x26,0xf6,0x06,0x0a
-,0x00,0xff,0x75,0xa2,0xe8,0xfd,0xdd,0x50,0xf6,0x06,0x93,0x36,0x20,0x75,0x03,0xe9
-,0x8c,0x00,0x26,0xa1,0x0c,0x00,0x25,0x07,0x00,0x3d,0x07,0x00,0x75,0x03,0xe9,0x76
-,0x00,0x3d,0x05,0x00,0x75,0x03,0xe9,0x6e,0x00,0xf7,0x06,0xe6,0x34,0x18,0x80,0x75
-,0x03,0xe9,0x6a,0x00,0xf7,0x06,0xe6,0x34,0x00,0x80,0x74,0x35,0x26,0x80,0x3e,0x29
-,0x00,0x02,0x75,0x2d,0x51,0x56,0x57,0x8d,0x36,0x3e,0x34,0x8d,0x3e,0x20,0x00,0xb9
-,0x06,0x00,0xf3,0xa6,0x5f,0x5e,0x59,0x75,0x45,0x26,0xa1,0x20,0x00,0xa3,0x3e,0x34
-,0x26,0xa1,0x22,0x00,0xa3,0x40,0x34,0x26,0xa1,0x24,0x00,0xa3,0x42,0x34,0xe9,0x26
-,0x00,0xf7,0x06,0xe6,0x34,0x08,0x00,0x74,0x0b,0x26,0x80,0x3e,0x19,0x00,0x00,0x74
-,0x03,0xe9,0x13,0x00,0xf7,0x06,0xe6,0x34,0x10,0x00,0x74,0x12,0x26,0xa0,0x28,0x00
-,0xc0,0xe8,0x04,0x22,0xc0,0x74,0x07,0x26,0xc7,0x06,0x04,0x00,0xff,0xff,0x58,0x23
-,0xc0,0x74,0x03,0xe9,0xdd,0xfe,0x81,0x26,0x9b,0x36,0xff,0xfe,0x26,0xa1,0x20,0x00
-,0x3b,0x06,0xd1,0x36,0x75,0x1a,0x26,0xa1,0x22,0x00,0x3b,0x06,0xd3,0x36,0x75,0x10
-,0x26,0xa1,0x24,0x00,0x3b,0x06,0xd5,0x36,0x75,0x06,0x81,0x0e,0x9b,0x36,0x00,0x01
-,0x26,0xa1,0x20,0x00,0x25,0x7f,0xff,0xa3,0xb8,0x34,0x26,0xa1,0x22,0x00,0xa3,0xba
-,0x34,0x26,0xa1,0x24,0x00,0xa3,0xbc,0x34,0x8b,0xc6,0x86,0xc4,0xa3,0xc0,0x34,0xd1
-,0xe6,0x80,0xfc,0x09,0x74,0x03,0xe8,0xf6,0xf5,0xa1,0x05,0x37,0x0b,0x06,0x07,0x37
-,0x0b,0x06,0x09,0x37,0x74,0x3e,0x26,0xa1,0x20,0x00,0x3b,0x06,0x05,0x37,0x75,0x17
-,0x26,0xa1,0x22,0x00,0x3b,0x06,0x07,0x37,0x75,0x0d,0x26,0xa1,0x24,0x00,0x3b,0x06
-,0x09,0x37,0x75,0x03,0xe9,0x1d,0x00,0x26,0xa0,0x28,0x00,0x24,0x0f,0x3c,0x03,0x74
-,0x1b,0x3c,0x00,0x75,0x0f,0x83,0x3e,0xa3,0x36,0x04,0x74,0x10,0xf7,0x06,0x9b,0x36
-,0x00,0x01,0x74,0x08,0x2e,0xff,0x94,0xf8,0x53,0xe9,0x33,0xfe,0xcd,0x34,0xc7,0x06
-,0x3d,0x37,0x01,0x00,0xe9,0x2c,0xf8,0x83,0x3e,0xa3,0x36,0x05,0x74,0x10,0x83,0x3e
-,0xa3,0x36,0x01,0x7e,0x09,0x83,0xee,0x16,0x2e,0xff,0x94,0x24,0x54,0xc3,0xcd,0x34
-,0xc3,0x26,0xa1,0x0c,0x00,0x3d,0xff,0x7f,0x74,0x05,0x26,0xff,0x26,0x04,0x00,0xe9
-,0xfd,0xfd,0xa1,0xf4,0x33,0xa9,0x00,0x88,0x74,0x0b,0xa9,0x00,0x10,0x75,0x09,0x8b
-,0x1e,0x43,0x37,0xff,0xe3,0xe9,0x97,0x00,0xc7,0x06,0x35,0x37,0x05,0x00,0xc7,0x06
-,0x43,0x37,0x28,0x52,0xf7,0x06,0xf4,0x33,0x00,0x08,0x74,0x06,0xc7,0x06,0x43,0x37
-,0x1a,0x52,0xb8,0x80,0x03,0xcd,0x39,0xe9,0xc5,0xfd,0xa9,0x00,0x08,0x74,0xd9,0xff
-,0x0e,0x35,0x37,0x75,0xed,0xe9,0x30,0x00,0xa9,0x00,0x08,0x75,0xcb,0xff,0x0e,0x35
-,0x37,0x75,0xdf,0x81,0x0e,0xc2,0x34,0xc0,0x00,0xf6,0x06,0x9d,0x36,0x80,0x74,0x0f
-,0x81,0x0e,0x9b,0x36,0x00,0x80,0xc7,0x06,0x0f,0x37,0x02,0x00,0xe9,0x90,0xfd,0xc7
-,0x06,0x3d,0x37,0x02,0x00,0xe9,0x8b,0xf7,0x80,0x26,0x9e,0x36,0xff,0x75,0x30,0xf6
-,0x06,0x9d,0x36,0x80,0x74,0x20,0xff,0x06,0x94,0x34,0x83,0x0e,0x66,0x37,0x20,0x8e
-,0x06,0x30,0x34,0x26,0xf7,0x06,0x0a,0x00,0x00,0x01,0x74,0x07,0x26,0x81,0x0e,0x08
-,0x00,0x00,0x01,0xe9,0x09,0x00,0xc7,0x06,0x3d,0x37,0x04,0x00,0xe9,0x54,0xf7,0x81
-,0x0e,0xaf,0x36,0x00,0x08,0xa1,0xaf,0x36,0xe7,0x06,0xe5,0x0a,0xa9,0x00,0x80,0x74
-,0x0e,0x81,0x26,0xaf,0x36,0xff,0xf7,0xa1,0xaf,0x36,0xe7,0x06,0xe9,0x49,0xff,0xe9
-,0x2d,0xfd,0xc7,0x06,0x41,0x37,0x00,0x00,0xbe,0x29,0x00,0xe8,0x2b,0xfd,0xe9,0x1e
-,0xfd,0xcd,0x34,0x83,0x3e,0xa3,0x36,0x04,0x77,0x09,0xc7,0x06,0x3d,0x37,0x01,0x00
-,0xe9,0x10,0xf7,0xe9,0x09,0xfd,0xcd,0x34,0xc3,0xc7,0x06,0x9b,0x36,0x00,0x00,0xe8
-,0x0c,0xf5,0x81,0x26,0xaf,0x36,0xff,0xe7,0xa1,0xaf,0x36,0xe7,0x06,0x81,0x26,0x9b
-,0x36,0xff,0x7f,0xe5,0x02,0x0d,0x01,0x00,0x25,0xef,0xff,0x25,0xff,0xdf,0xe7,0x02
-,0xbb,0xff,0x7f,0xcd,0x53,0x33,0xc0,0xa3,0x9d,0x36,0xa3,0x9f,0x36,0xe8,0x20,0xf3
-,0xe8,0x43,0xf3,0x83,0x0e,0x9b,0x36,0x10,0xc7,0x06,0x99,0x36,0x00,0x00,0xe8,0xd2
-,0xf5,0xe5,0x56,0x0d,0x02,0x00,0xe7,0x56,0xc7,0x06,0xa8,0x02,0x00,0x00,0xbe,0x00
-,0x00,0xe8,0x30,0xf5,0xc6,0x06,0xa0,0x36,0x0e,0xb8,0x9c,0x03,0xcd,0x39,0xb8,0x80
-,0x00,0xcd,0x35,0xc7,0x06,0xaa,0x02,0xff,0xff,0xc7,0x06,0xa1,0x36,0x01,0x00,0xe9
-,0xa5,0xf6,0x06,0xb8,0x8f,0x03,0xcd,0x3a,0xb8,0x90,0x03,0xcd,0x3a,0xb8,0x91,0x03
-,0xcd,0x3a,0xb8,0x92,0x03,0xcd,0x3a,0xb8,0x93,0x03,0xcd,0x3a,0xb8,0x94,0x03,0xcd
-,0x3a,0xb8,0x95,0x03,0xcd,0x3a,0xb8,0x96,0x03,0xcd,0x3a,0xb8,0x97,0x03,0xcd,0x3a
-,0xb8,0x98,0x03,0xcd,0x3a,0xb8,0x99,0x03,0xcd,0x3a,0xb8,0x9a,0x03,0xcd,0x3a,0xb8
-,0x9b,0x03,0xcd,0x3a,0xb8,0x7f,0x03,0xcd,0x3a,0xb8,0x80,0x03,0xcd,0x3a,0x07,0xc3
-,0xf7,0x49,0xf1,0x4e,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f,0xf8,0x51,0xdf,0x4f
-,0xfa,0x4f,0x0b,0x50,0xd1,0x51,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f,0xdf,0x4f
-,0xe4,0x4e,0x06,0x00,0xcd,0x4a,0x04,0x00,0xe4,0x4e,0x19,0x00,0xad,0x4b,0xfa,0x00
-,0x82,0x4c,0x08,0x07,0x09,0x4c,0x14,0x00,0x24,0x4e,0x64,0x00,0xd7,0x4d,0xf4,0x01
-,0x64,0x4e,0xbc,0x02,0x7a,0x4e,0xe8,0x03,0x43,0x4e,0x02,0x00,0xb3,0x4e,0xf4,0x01
-,0x5b,0x4e,0xf4,0x01,0xe5,0x4e,0x14,0x00,0x06,0x50,0x06,0x50,0x95,0x4c,0xc1,0x52
-,0xc1,0x52,0xfe,0x4c,0xda,0x4c,0x06,0x50,0x06,0x50,0x06,0x50,0x06,0x50,0xb7,0x51
-,0xb7,0x51,0xb7,0x51,0xb7,0x51,0xb7,0x51,0xb7,0x51,0x06,0x50,0xd5,0x4a,0x06,0x50
-,0x1d,0x4c,0x06,0x50,0x83,0x4d,0x1f,0x4d,0x1f,0x4d,0xed,0x40,0xfa,0x40,0x07,0x41
-,0x37,0x37,0x2e,0x37,0x37,0x20,0x20,0x79,0x79,0x2f,0x79,0x79,0x2f,0x79,0x79,0x20
-,0x30,0x31,0x2e,0x39,0x30,0x20,0x20,0x30,0x32,0x2f,0x31,0x37,0x2f,0x39,0x39,0x20
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
-,0x90,0xea,0xc0,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x06
-} ;
diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c
index b566d6d79ecd..b9db1b5a58a3 100644
--- a/drivers/net/tokenring/abyss.c
+++ b/drivers/net/tokenring/abyss.c
@@ -92,6 +92,8 @@ static void abyss_sifwritew(struct net_device *dev, unsigned short val, unsigned
outw(val, dev->base_addr + reg);
}
+static struct net_device_ops abyss_netdev_ops;
+
static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int versionprinted;
@@ -157,8 +159,7 @@ static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_
memcpy(tp->ProductID, "Madge PCI 16/4 Mk2", PROD_ID_SIZE + 1);
- dev->open = abyss_open;
- dev->stop = abyss_close;
+ dev->netdev_ops = &abyss_netdev_ops;
pci_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -450,6 +451,11 @@ static struct pci_driver abyss_driver = {
static int __init abyss_init (void)
{
+ abyss_netdev_ops = tms380tr_netdev_ops;
+
+ abyss_netdev_ops.ndo_open = abyss_open;
+ abyss_netdev_ops.ndo_stop = abyss_close;
+
return pci_register_driver(&abyss_driver);
}
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index fa7bce6e0c6d..9d896116cf76 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -200,7 +200,6 @@ static void tr_rx(struct net_device *dev);
static void ibmtr_reset_timer(struct timer_list*tmr,struct net_device *dev);
static void tok_rerun(unsigned long dev_addr);
static void ibmtr_readlog(struct net_device *dev);
-static struct net_device_stats *tok_get_stats(struct net_device *dev);
static int ibmtr_change_mtu(struct net_device *dev, int mtu);
static void find_turbo_adapters(int *iolist);
@@ -816,18 +815,21 @@ static unsigned char __devinit get_sram_size(struct tok_info *adapt_info)
/*****************************************************************************/
+static const struct net_device_ops trdev_netdev_ops = {
+ .ndo_open = tok_open,
+ .ndo_stop = tok_close,
+ .ndo_start_xmit = tok_send_packet,
+ .ndo_set_multicast_list = tok_set_multicast_list,
+ .ndo_change_mtu = ibmtr_change_mtu,
+};
+
static int __devinit trdev_init(struct net_device *dev)
{
struct tok_info *ti = netdev_priv(dev);
SET_PAGE(ti->srb_page);
ti->open_failure = NO ;
- dev->open = tok_open;
- dev->stop = tok_close;
- dev->hard_start_xmit = tok_send_packet;
- dev->get_stats = tok_get_stats;
- dev->set_multicast_list = tok_set_multicast_list;
- dev->change_mtu = ibmtr_change_mtu;
+ dev->netdev_ops = &trdev_netdev_ops;
return 0;
}
@@ -1460,7 +1462,7 @@ static irqreturn_t tok_interrupt(int irq, void *dev_id)
"%02X\n",
(int)retcode, (int)readb(ti->ssb + 6));
else
- ti->tr_stats.tx_packets++;
+ dev->stats.tx_packets++;
break;
case XMIT_XID_CMD:
DPRINTK("xmit xid ret_code: %02X\n",
@@ -1646,7 +1648,7 @@ static void tr_tx(struct net_device *dev)
break;
}
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- ti->tr_stats.tx_bytes += ti->current_skb->len;
+ dev->stats.tx_bytes += ti->current_skb->len;
dev_kfree_skb_irq(ti->current_skb);
ti->current_skb = NULL;
netif_wake_queue(dev);
@@ -1722,7 +1724,7 @@ static void tr_rx(struct net_device *dev)
if (readb(llc + offsetof(struct trllc, llc)) != UI_CMD) {
SET_PAGE(ti->asb_page);
writeb(DATA_LOST, ti->asb + RETCODE_OFST);
- ti->tr_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
return;
}
@@ -1757,7 +1759,7 @@ static void tr_rx(struct net_device *dev)
if (!(skb = dev_alloc_skb(skb_size))) {
DPRINTK("out of memory. frame dropped.\n");
- ti->tr_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
SET_PAGE(ti->asb_page);
writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
@@ -1813,8 +1815,8 @@ static void tr_rx(struct net_device *dev)
writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
- ti->tr_stats.rx_bytes += skb->len;
- ti->tr_stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
skb->protocol = tr_type_trans(skb, dev);
if (IPv4_p) {
@@ -1876,21 +1878,6 @@ static void ibmtr_readlog(struct net_device *dev)
/*****************************************************************************/
-/* tok_get_stats(): Basically a scaffold routine which will return
- the address of the tr_statistics structure associated with
- this device -- the tr.... structure is an ethnet look-alike
- so at least for this iteration may suffice. */
-
-static struct net_device_stats *tok_get_stats(struct net_device *dev)
-{
-
- struct tok_info *toki;
- toki = netdev_priv(dev);
- return (struct net_device_stats *) &toki->tr_stats;
-}
-
-/*****************************************************************************/
-
static int ibmtr_change_mtu(struct net_device *dev, int mtu)
{
struct tok_info *ti = netdev_priv(dev);
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
index 239c75217b12..f309b8f703bd 100644
--- a/drivers/net/tokenring/lanstreamer.c
+++ b/drivers/net/tokenring/lanstreamer.c
@@ -207,7 +207,6 @@ static int streamer_xmit(struct sk_buff *skb, struct net_device *dev);
static int streamer_close(struct net_device *dev);
static void streamer_set_rx_mode(struct net_device *dev);
static irqreturn_t streamer_interrupt(int irq, void *dev_id);
-static struct net_device_stats *streamer_get_stats(struct net_device *dev);
static int streamer_set_mac_address(struct net_device *dev, void *addr);
static void streamer_arb_cmd(struct net_device *dev);
static int streamer_change_mtu(struct net_device *dev, int mtu);
@@ -222,6 +221,18 @@ struct streamer_private *dev_streamer=NULL;
#endif
#endif
+static const struct net_device_ops streamer_netdev_ops = {
+ .ndo_open = streamer_open,
+ .ndo_stop = streamer_close,
+ .ndo_start_xmit = streamer_xmit,
+ .ndo_change_mtu = streamer_change_mtu,
+#if STREAMER_IOCTL
+ .ndo_do_ioctl = streamer_ioctl,
+#endif
+ .ndo_set_multicast_list = streamer_set_rx_mode,
+ .ndo_set_mac_address = streamer_set_mac_address,
+};
+
static int __devinit streamer_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -321,18 +332,7 @@ static int __devinit streamer_init_one(struct pci_dev *pdev,
init_waitqueue_head(&streamer_priv->srb_wait);
init_waitqueue_head(&streamer_priv->trb_wait);
- dev->open = &streamer_open;
- dev->hard_start_xmit = &streamer_xmit;
- dev->change_mtu = &streamer_change_mtu;
- dev->stop = &streamer_close;
-#if STREAMER_IOCTL
- dev->do_ioctl = &streamer_ioctl;
-#else
- dev->do_ioctl = NULL;
-#endif
- dev->set_multicast_list = &streamer_set_rx_mode;
- dev->get_stats = &streamer_get_stats;
- dev->set_mac_address = &streamer_set_mac_address;
+ dev->netdev_ops = &streamer_netdev_ops;
dev->irq = pdev->irq;
dev->base_addr=pio_start;
SET_NETDEV_DEV(dev, &pdev->dev);
@@ -616,8 +616,6 @@ static int streamer_open(struct net_device *dev)
printk("SISR Mask = %04x\n", readw(streamer_mmio + SISR_MASK));
#endif
do {
- int i;
-
for (i = 0; i < SRB_COMMAND_SIZE; i += 2) {
writew(0, streamer_mmio + LAPDINC);
}
@@ -937,7 +935,7 @@ static void streamer_rx(struct net_device *dev)
if (skb == NULL)
{
printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers. \n", dev->name);
- streamer_priv->streamer_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
} else { /* we allocated an skb OK */
if (buffer_cnt == 1) {
/* release the DMA mapping */
@@ -1009,8 +1007,8 @@ static void streamer_rx(struct net_device *dev)
/* send up to the protocol */
netif_rx(skb);
}
- streamer_priv->streamer_stats.rx_packets++;
- streamer_priv->streamer_stats.rx_bytes += length;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += length;
} /* if skb == null */
} /* end received without errors */
@@ -1053,8 +1051,8 @@ static irqreturn_t streamer_interrupt(int irq, void *dev_id)
while(streamer_priv->streamer_tx_ring[(streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1)].status) {
streamer_priv->tx_ring_last_status = (streamer_priv->tx_ring_last_status + 1) & (STREAMER_TX_RING_SIZE - 1);
streamer_priv->free_tx_ring_entries++;
- streamer_priv->streamer_stats.tx_bytes += streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]->len;
- streamer_priv->streamer_stats.tx_packets++;
+ dev->stats.tx_bytes += streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]->len;
+ dev->stats.tx_packets++;
dev_kfree_skb_irq(streamer_priv->tx_ring_skb[streamer_priv->tx_ring_last_status]);
streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].buffer = 0xdeadbeef;
streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_last_status].status = 0;
@@ -1484,13 +1482,6 @@ static void streamer_srb_bh(struct net_device *dev)
} /* switch srb[0] */
}
-static struct net_device_stats *streamer_get_stats(struct net_device *dev)
-{
- struct streamer_private *streamer_priv;
- streamer_priv = netdev_priv(dev);
- return (struct net_device_stats *) &streamer_priv->streamer_stats;
-}
-
static int streamer_set_mac_address(struct net_device *dev, void *addr)
{
struct sockaddr *saddr = addr;
diff --git a/drivers/net/tokenring/lanstreamer.h b/drivers/net/tokenring/lanstreamer.h
index 13ccee6449c1..3c58d6a3fbc9 100644
--- a/drivers/net/tokenring/lanstreamer.h
+++ b/drivers/net/tokenring/lanstreamer.h
@@ -299,7 +299,6 @@ struct streamer_private {
int tx_ring_free, tx_ring_last_status, rx_ring_last_received,
free_tx_ring_entries;
- struct net_device_stats streamer_stats;
__u16 streamer_lan_status;
__u8 streamer_ring_speed;
__u16 pkt_buf_sz;
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
index 917b4d201e09..456f8bff40be 100644
--- a/drivers/net/tokenring/madgemc.c
+++ b/drivers/net/tokenring/madgemc.c
@@ -142,7 +142,7 @@ static void madgemc_sifwritew(struct net_device *dev, unsigned short val, unsign
return;
}
-
+static struct net_device_ops madgemc_netdev_ops __read_mostly;
static int __devinit madgemc_probe(struct device *device)
{
@@ -168,7 +168,7 @@ static int __devinit madgemc_probe(struct device *device)
goto getout;
}
- dev->dma = 0;
+ dev->netdev_ops = &madgemc_netdev_ops;
card = kmalloc(sizeof(struct card_info), GFP_KERNEL);
if (card==NULL) {
@@ -348,9 +348,6 @@ static int __devinit madgemc_probe(struct device *device)
memcpy(tp->ProductID, "Madge MCA 16/4 ", PROD_ID_SIZE + 1);
- dev->open = madgemc_open;
- dev->stop = madgemc_close;
-
tp->tmspriv = card;
dev_set_drvdata(device, dev);
@@ -692,8 +689,6 @@ static int madgemc_mcaproc(char *buf, int slot, void *d)
len += sprintf(buf+len, "-------\n");
if (curcard) {
- struct net_local *tp = netdev_priv(dev);
-
len += sprintf(buf+len, "Card Revision: %d\n", curcard->cardrev);
len += sprintf(buf+len, "RAM Size: %dkb\n", curcard->ramsize);
len += sprintf(buf+len, "Cable type: %s\n", (curcard->cabletype)?"STP/DB9":"UTP/RJ-45");
@@ -760,6 +755,10 @@ static struct mca_driver madgemc_driver = {
static int __init madgemc_init (void)
{
+ madgemc_netdev_ops = tms380tr_netdev_ops;
+ madgemc_netdev_ops.ndo_open = madgemc_open;
+ madgemc_netdev_ops.ndo_stop = madgemc_close;
+
return mca_register_driver (&madgemc_driver);
}
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
index ecb5c7c96910..d068a9d36883 100644
--- a/drivers/net/tokenring/olympic.c
+++ b/drivers/net/tokenring/olympic.c
@@ -187,7 +187,6 @@ static int olympic_close(struct net_device *dev);
static void olympic_set_rx_mode(struct net_device *dev);
static void olympic_freemem(struct net_device *dev) ;
static irqreturn_t olympic_interrupt(int irq, void *dev_id);
-static struct net_device_stats * olympic_get_stats(struct net_device *dev);
static int olympic_set_mac_address(struct net_device *dev, void *addr) ;
static void olympic_arb_cmd(struct net_device *dev);
static int olympic_change_mtu(struct net_device *dev, int mtu);
@@ -195,6 +194,15 @@ static void olympic_srb_bh(struct net_device *dev) ;
static void olympic_asb_bh(struct net_device *dev) ;
static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) ;
+static const struct net_device_ops olympic_netdev_ops = {
+ .ndo_open = olympic_open,
+ .ndo_stop = olympic_close,
+ .ndo_start_xmit = olympic_xmit,
+ .ndo_change_mtu = olympic_change_mtu,
+ .ndo_set_multicast_list = olympic_set_rx_mode,
+ .ndo_set_mac_address = olympic_set_mac_address,
+};
+
static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct net_device *dev ;
@@ -253,14 +261,7 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device
goto op_free_iomap;
}
- dev->open=&olympic_open;
- dev->hard_start_xmit=&olympic_xmit;
- dev->change_mtu=&olympic_change_mtu;
- dev->stop=&olympic_close;
- dev->do_ioctl=NULL;
- dev->set_multicast_list=&olympic_set_rx_mode;
- dev->get_stats=&olympic_get_stats ;
- dev->set_mac_address=&olympic_set_mac_address ;
+ dev->netdev_ops = &olympic_netdev_ops;
SET_NETDEV_DEV(dev, &pdev->dev);
pci_set_drvdata(pdev,dev) ;
@@ -698,7 +699,6 @@ static int olympic_open(struct net_device *dev)
if (olympic_priv->olympic_network_monitor) {
u8 __iomem *oat;
u8 __iomem *opt;
- int i;
u8 addr[6];
oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr);
opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr);
@@ -785,7 +785,7 @@ static void olympic_rx(struct net_device *dev)
}
olympic_priv->rx_ring_last_received += i ;
olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ;
- olympic_priv->olympic_stats.rx_errors++;
+ dev->stats.rx_errors++;
} else {
if (buffer_cnt == 1) {
@@ -796,7 +796,7 @@ static void olympic_rx(struct net_device *dev)
if (skb == NULL) {
printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers. \n",dev->name) ;
- olympic_priv->olympic_stats.rx_dropped++ ;
+ dev->stats.rx_dropped++;
/* Update counters even though we don't transfer the frame */
olympic_priv->rx_ring_last_received += i ;
olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ;
@@ -862,8 +862,8 @@ static void olympic_rx(struct net_device *dev)
skb->protocol = tr_type_trans(skb,dev);
netif_rx(skb) ;
}
- olympic_priv->olympic_stats.rx_packets++ ;
- olympic_priv->olympic_stats.rx_bytes += length ;
+ dev->stats.rx_packets++ ;
+ dev->stats.rx_bytes += length ;
} /* if skb == null */
} /* If status & 0x3b */
@@ -971,8 +971,8 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id)
olympic_priv->tx_ring_last_status++;
olympic_priv->tx_ring_last_status &= (OLYMPIC_TX_RING_SIZE-1);
olympic_priv->free_tx_ring_entries++;
- olympic_priv->olympic_stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len;
- olympic_priv->olympic_stats.tx_packets++ ;
+ dev->stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len;
+ dev->stats.tx_packets++ ;
pci_unmap_single(olympic_priv->pdev,
le32_to_cpu(olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer),
olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len,PCI_DMA_TODEVICE);
@@ -1344,13 +1344,6 @@ static void olympic_srb_bh(struct net_device *dev)
}
-static struct net_device_stats * olympic_get_stats(struct net_device *dev)
-{
- struct olympic_private *olympic_priv ;
- olympic_priv=netdev_priv(dev);
- return (struct net_device_stats *) &olympic_priv->olympic_stats;
-}
-
static int olympic_set_mac_address (struct net_device *dev, void *addr)
{
struct sockaddr *saddr = addr ;
diff --git a/drivers/net/tokenring/olympic.h b/drivers/net/tokenring/olympic.h
index 10fbba08978f..30631bae4c94 100644
--- a/drivers/net/tokenring/olympic.h
+++ b/drivers/net/tokenring/olympic.h
@@ -275,7 +275,6 @@ struct olympic_private {
struct sk_buff *tx_ring_skb[OLYMPIC_TX_RING_SIZE], *rx_ring_skb[OLYMPIC_RX_RING_SIZE];
int tx_ring_free, tx_ring_last_status, rx_ring_last_received,rx_status_last_received, free_tx_ring_entries;
- struct net_device_stats olympic_stats ;
u16 olympic_lan_status ;
u8 olympic_ring_speed ;
u16 pkt_buf_sz ;
diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
index b8c955f6d31a..16e8783ee9cd 100644
--- a/drivers/net/tokenring/proteon.c
+++ b/drivers/net/tokenring/proteon.c
@@ -116,6 +116,8 @@ nodev:
return -ENODEV;
}
+static struct net_device_ops proteon_netdev_ops __read_mostly;
+
static int __init setup_card(struct net_device *dev, struct device *pdev)
{
struct net_local *tp;
@@ -167,8 +169,7 @@ static int __init setup_card(struct net_device *dev, struct device *pdev)
tp->tmspriv = NULL;
- dev->open = proteon_open;
- dev->stop = tms380tr_close;
+ dev->netdev_ops = &proteon_netdev_ops;
if (dev->irq == 0)
{
@@ -352,6 +353,10 @@ static int __init proteon_init(void)
struct platform_device *pdev;
int i, num = 0, err = 0;
+ proteon_netdev_ops = tms380tr_netdev_ops;
+ proteon_netdev_ops.ndo_open = proteon_open;
+ proteon_netdev_ops.ndo_stop = tms380tr_close;
+
err = platform_driver_register(&proteon_driver);
if (err)
return err;
diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c
index c0f58f08782c..46db5c5395b2 100644
--- a/drivers/net/tokenring/skisa.c
+++ b/drivers/net/tokenring/skisa.c
@@ -133,6 +133,8 @@ static int __init sk_isa_probe1(struct net_device *dev, int ioaddr)
return 0;
}
+static struct net_device_ops sk_isa_netdev_ops __read_mostly;
+
static int __init setup_card(struct net_device *dev, struct device *pdev)
{
struct net_local *tp;
@@ -184,8 +186,7 @@ static int __init setup_card(struct net_device *dev, struct device *pdev)
tp->tmspriv = NULL;
- dev->open = sk_isa_open;
- dev->stop = tms380tr_close;
+ dev->netdev_ops = &sk_isa_netdev_ops;
if (dev->irq == 0)
{
@@ -362,6 +363,10 @@ static int __init sk_isa_init(void)
struct platform_device *pdev;
int i, num = 0, err = 0;
+ sk_isa_netdev_ops = tms380tr_netdev_ops;
+ sk_isa_netdev_ops.ndo_open = sk_isa_open;
+ sk_isa_netdev_ops.ndo_stop = tms380tr_close;
+
err = platform_driver_register(&sk_isa_driver);
if (err)
return err;
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
index 50eb29ce3c87..a91d9c55d78e 100644
--- a/drivers/net/tokenring/smctr.c
+++ b/drivers/net/tokenring/smctr.c
@@ -61,7 +61,8 @@
#include "smctr.h" /* Our Stuff */
-static char version[] __initdata = KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n";
+static const char version[] __initdata =
+ KERN_INFO "smctr.c: v1.4 7/12/00 by jschlst@samba.org\n";
static const char cardname[] = "smctr";
@@ -123,7 +124,6 @@ static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev);
static int smctr_get_physical_drop_number(struct net_device *dev);
static __u8 *smctr_get_rx_pointer(struct net_device *dev, short queue);
static int smctr_get_station_id(struct net_device *dev);
-static struct net_device_stats *smctr_get_stats(struct net_device *dev);
static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue,
__u16 bytes_count);
static int smctr_get_upstream_neighbor_addr(struct net_device *dev);
@@ -3632,6 +3632,14 @@ out:
return ERR_PTR(err);
}
+static const struct net_device_ops smctr_netdev_ops = {
+ .ndo_open = smctr_open,
+ .ndo_stop = smctr_close,
+ .ndo_start_xmit = smctr_send_packet,
+ .ndo_tx_timeout = smctr_timeout,
+ .ndo_get_stats = smctr_get_stats,
+ .ndo_set_multicast_list = smctr_set_multicast_list,
+};
static int __init smctr_probe1(struct net_device *dev, int ioaddr)
{
@@ -3682,13 +3690,8 @@ static int __init smctr_probe1(struct net_device *dev, int ioaddr)
(unsigned int)dev->base_addr,
dev->irq, tp->rom_base, tp->ram_base);
- dev->open = smctr_open;
- dev->stop = smctr_close;
- dev->hard_start_xmit = smctr_send_packet;
- dev->tx_timeout = smctr_timeout;
+ dev->netdev_ops = &smctr_netdev_ops;
dev->watchdog_timeo = HZ;
- dev->get_stats = smctr_get_stats;
- dev->set_multicast_list = &smctr_set_multicast_list;
return (0);
out:
@@ -4392,52 +4395,42 @@ static int smctr_ring_status_chg(struct net_device *dev)
{
case RING_RECOVERY:
printk(KERN_INFO "%s: Ring Recovery\n", dev->name);
- tp->current_ring_status |= RING_RECOVERY;
break;
case SINGLE_STATION:
printk(KERN_INFO "%s: Single Statinon\n", dev->name);
- tp->current_ring_status |= SINGLE_STATION;
break;
case COUNTER_OVERFLOW:
printk(KERN_INFO "%s: Counter Overflow\n", dev->name);
- tp->current_ring_status |= COUNTER_OVERFLOW;
break;
case REMOVE_RECEIVED:
printk(KERN_INFO "%s: Remove Received\n", dev->name);
- tp->current_ring_status |= REMOVE_RECEIVED;
break;
case AUTO_REMOVAL_ERROR:
printk(KERN_INFO "%s: Auto Remove Error\n", dev->name);
- tp->current_ring_status |= AUTO_REMOVAL_ERROR;
break;
case LOBE_WIRE_FAULT:
printk(KERN_INFO "%s: Lobe Wire Fault\n", dev->name);
- tp->current_ring_status |= LOBE_WIRE_FAULT;
break;
case TRANSMIT_BEACON:
printk(KERN_INFO "%s: Transmit Beacon\n", dev->name);
- tp->current_ring_status |= TRANSMIT_BEACON;
break;
case SOFT_ERROR:
printk(KERN_INFO "%s: Soft Error\n", dev->name);
- tp->current_ring_status |= SOFT_ERROR;
break;
case HARD_ERROR:
printk(KERN_INFO "%s: Hard Error\n", dev->name);
- tp->current_ring_status |= HARD_ERROR;
break;
case SIGNAL_LOSS:
printk(KERN_INFO "%s: Signal Loss\n", dev->name);
- tp->current_ring_status |= SIGNAL_LOSS;
break;
default:
diff --git a/drivers/net/tokenring/smctr.h b/drivers/net/tokenring/smctr.h
index 52df7dd815cc..6e5700ab4fc3 100644
--- a/drivers/net/tokenring/smctr.h
+++ b/drivers/net/tokenring/smctr.h
@@ -977,7 +977,6 @@ typedef struct net_local {
__u8 monitor_state_ready;
__u16 ring_status;
__u8 ring_status_flags;
- __u8 current_ring_status;
__u8 state;
__u8 join_state;
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
index 5be34c2fd483..b11bb72dc7ab 100644
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -2330,6 +2330,17 @@ void tmsdev_term(struct net_device *dev)
DMA_BIDIRECTIONAL);
}
+const struct net_device_ops tms380tr_netdev_ops = {
+ .ndo_open = tms380tr_open,
+ .ndo_stop = tms380tr_close,
+ .ndo_start_xmit = tms380tr_send_packet,
+ .ndo_tx_timeout = tms380tr_timeout,
+ .ndo_get_stats = tms380tr_get_stats,
+ .ndo_set_multicast_list = tms380tr_set_multicast_list,
+ .ndo_set_mac_address = tms380tr_set_mac_address,
+};
+EXPORT_SYMBOL(tms380tr_netdev_ops);
+
int tmsdev_init(struct net_device *dev, struct device *pdev)
{
struct net_local *tms_local;
@@ -2353,16 +2364,8 @@ int tmsdev_init(struct net_device *dev, struct device *pdev)
return -ENOMEM;
}
- /* These can be overridden by the card driver if needed */
- dev->open = tms380tr_open;
- dev->stop = tms380tr_close;
- dev->do_ioctl = NULL;
- dev->hard_start_xmit = tms380tr_send_packet;
- dev->tx_timeout = tms380tr_timeout;
+ dev->netdev_ops = &tms380tr_netdev_ops;
dev->watchdog_timeo = HZ;
- dev->get_stats = tms380tr_get_stats;
- dev->set_multicast_list = &tms380tr_set_multicast_list;
- dev->set_mac_address = tms380tr_set_mac_address;
return 0;
}
diff --git a/drivers/net/tokenring/tms380tr.h b/drivers/net/tokenring/tms380tr.h
index 7af76d708849..60b30ee38dcb 100644
--- a/drivers/net/tokenring/tms380tr.h
+++ b/drivers/net/tokenring/tms380tr.h
@@ -14,6 +14,7 @@
#include <linux/interrupt.h>
/* module prototypes */
+extern const struct net_device_ops tms380tr_netdev_ops;
int tms380tr_open(struct net_device *dev);
int tms380tr_close(struct net_device *dev);
irqreturn_t tms380tr_interrupt(int irq, void *dev_id);
diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c
index e2150b3c83d9..f92fe86fdcae 100644
--- a/drivers/net/tokenring/tmspci.c
+++ b/drivers/net/tokenring/tmspci.c
@@ -152,13 +152,13 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic
tp->tmspriv = cardinfo;
+ dev->netdev_ops = &tms380tr_netdev_ops;
+
ret = request_irq(pdev->irq, tms380tr_interrupt, IRQF_SHARED,
dev->name, dev);
if (ret)
goto err_out_tmsdev;
- dev->open = tms380tr_open;
- dev->stop = tms380tr_close;
pci_set_drvdata(pdev, dev);
SET_NETDEV_DEV(dev, &pdev->dev);
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index a9fd2b2ccaf6..bb43e7fb2a50 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -888,7 +888,7 @@ static int tsi108_poll(struct napi_struct *napi, int budget)
if (num_received < budget) {
data->rxpending = 0;
- netif_rx_complete(napi);
+ napi_complete(napi);
TSI_WRITE(TSI108_EC_INTMASK,
TSI_READ(TSI108_EC_INTMASK)
@@ -915,11 +915,11 @@ static void tsi108_rx_int(struct net_device *dev)
*
* This can happen if this code races with tsi108_poll(), which masks
* the interrupts after tsi108_irq_one() read the mask, but before
- * netif_rx_schedule is called. It could also happen due to calls
+ * napi_schedule is called. It could also happen due to calls
* from tsi108_check_rxring().
*/
- if (netif_rx_schedule_prep(&data->napi)) {
+ if (napi_schedule_prep(&data->napi)) {
/* Mask, rather than ack, the receive interrupts. The ack
* will happen in tsi108_poll().
*/
@@ -930,7 +930,7 @@ static void tsi108_rx_int(struct net_device *dev)
| TSI108_INT_RXTHRESH |
TSI108_INT_RXOVERRUN | TSI108_INT_RXERROR |
TSI108_INT_RXWAIT);
- __netif_rx_schedule(&data->napi);
+ __napi_schedule(&data->napi);
} else {
if (!netif_running(dev)) {
/* This can happen if an interrupt occurs while the
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index 6418f74415d7..f9491bd787d1 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -479,7 +479,8 @@
#include "de4x5.h"
-static char version[] __devinitdata = "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
+static const char version[] __devinitconst =
+ KERN_INFO "de4x5.c:V0.546 2001/02/22 davies@maniac.ultranet.com\n";
#define c_char const char
@@ -3941,8 +3942,8 @@ PCI_signature(char *name, struct de4x5_private *lp)
strcpy(name, "DE434/5");
return status;
} else { /* Search for a DEC name in the SROM */
- int i = *((char *)&lp->srom + 19) * 3;
- strncpy(name, (char *)&lp->srom + 26 + i, 8);
+ int tmp = *((char *)&lp->srom + 19) * 3;
+ strncpy(name, (char *)&lp->srom + 26 + tmp, 8);
}
name[8] = '\0';
for (i=0; i<siglen; i++) {
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index 2e5c99941f35..e2c9d0f5a755 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -288,7 +288,7 @@ enum dmfe_CR6_bits {
/* Global variable declaration ----------------------------- */
static int __devinitdata printed_version;
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
KERN_INFO DRV_NAME ": Davicom DM9xxx net driver, version "
DRV_VERSION " (" DRV_RELDATE ")\n";
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index 6c3428a37c0b..c8d220cf2cce 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -103,7 +103,7 @@ void oom_timer(unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
struct tulip_private *tp = netdev_priv(dev);
- netif_rx_schedule(&tp->napi);
+ napi_schedule(&tp->napi);
}
int tulip_poll(struct napi_struct *napi, int budget)
@@ -140,6 +140,7 @@ int tulip_poll(struct napi_struct *napi, int budget)
/* If we own the next entry, it is a new packet. Send it up. */
while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
s32 status = le32_to_cpu(tp->rx_ring[entry].status);
+ short pkt_len;
if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx)
break;
@@ -151,8 +152,28 @@ int tulip_poll(struct napi_struct *napi, int budget)
if (++work_done >= budget)
goto not_done;
- if ((status & 0x38008300) != 0x0300) {
- if ((status & 0x38000300) != 0x0300) {
+ /*
+ * Omit the four octet CRC from the length.
+ * (May not be considered valid until we have
+ * checked status for RxLengthOver2047 bits)
+ */
+ pkt_len = ((status >> 16) & 0x7ff) - 4;
+
+ /*
+ * Maximum pkt_len is 1518 (1514 + vlan header)
+ * Anything higher than this is always invalid
+ * regardless of RxLengthOver2047 bits
+ */
+
+ if ((status & (RxLengthOver2047 |
+ RxDescCRCError |
+ RxDescCollisionSeen |
+ RxDescRunt |
+ RxDescDescErr |
+ RxWholePkt)) != RxWholePkt
+ || pkt_len > 1518) {
+ if ((status & (RxLengthOver2047 |
+ RxWholePkt)) != RxWholePkt) {
/* Ingore earlier buffers. */
if ((status & 0xffff) != 0x7fff) {
if (tulip_debug > 1)
@@ -161,30 +182,23 @@ int tulip_poll(struct napi_struct *napi, int budget)
dev->name, status);
tp->stats.rx_length_errors++;
}
- } else if (status & RxDescFatalErr) {
+ } else {
/* There was a fatal error. */
if (tulip_debug > 2)
printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
dev->name, status);
tp->stats.rx_errors++; /* end of a packet.*/
- if (status & 0x0890) tp->stats.rx_length_errors++;
+ if (pkt_len > 1518 ||
+ (status & RxDescRunt))
+ tp->stats.rx_length_errors++;
+
if (status & 0x0004) tp->stats.rx_frame_errors++;
if (status & 0x0002) tp->stats.rx_crc_errors++;
if (status & 0x0001) tp->stats.rx_fifo_errors++;
}
} else {
- /* Omit the four octet CRC from the length. */
- short pkt_len = ((status >> 16) & 0x7ff) - 4;
struct sk_buff *skb;
-#ifndef final_version
- if (pkt_len > 1518) {
- printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
- dev->name, pkt_len, pkt_len);
- pkt_len = 1518;
- tp->stats.rx_length_errors++;
- }
-#endif
/* Check if the packet is long enough to accept without copying
to a minimally-sized skbuff. */
if (pkt_len < tulip_rx_copybreak
@@ -300,7 +314,7 @@ int tulip_poll(struct napi_struct *napi, int budget)
/* Remove us from polling list and enable RX intr. */
- netif_rx_complete(napi);
+ napi_complete(napi);
iowrite32(tulip_tbl[tp->chip_id].valid_intrs, tp->base_addr+CSR7);
/* The last op happens after poll completion. Which means the following:
@@ -333,10 +347,10 @@ int tulip_poll(struct napi_struct *napi, int budget)
/* Think: timer_pending() was an explicit signature of bug.
* Timer can be pending now but fired and completed
- * before we did netif_rx_complete(). See? We would lose it. */
+ * before we did napi_complete(). See? We would lose it. */
/* remove ourselves from the polling list */
- netif_rx_complete(napi);
+ napi_complete(napi);
return work_done;
}
@@ -356,14 +370,35 @@ static int tulip_rx(struct net_device *dev)
/* If we own the next entry, it is a new packet. Send it up. */
while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
s32 status = le32_to_cpu(tp->rx_ring[entry].status);
+ short pkt_len;
if (tulip_debug > 5)
printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
dev->name, entry, status);
if (--rx_work_limit < 0)
break;
- if ((status & 0x38008300) != 0x0300) {
- if ((status & 0x38000300) != 0x0300) {
+
+ /*
+ Omit the four octet CRC from the length.
+ (May not be considered valid until we have
+ checked status for RxLengthOver2047 bits)
+ */
+ pkt_len = ((status >> 16) & 0x7ff) - 4;
+ /*
+ Maximum pkt_len is 1518 (1514 + vlan header)
+ Anything higher than this is always invalid
+ regardless of RxLengthOver2047 bits
+ */
+
+ if ((status & (RxLengthOver2047 |
+ RxDescCRCError |
+ RxDescCollisionSeen |
+ RxDescRunt |
+ RxDescDescErr |
+ RxWholePkt)) != RxWholePkt
+ || pkt_len > 1518) {
+ if ((status & (RxLengthOver2047 |
+ RxWholePkt)) != RxWholePkt) {
/* Ingore earlier buffers. */
if ((status & 0xffff) != 0x7fff) {
if (tulip_debug > 1)
@@ -372,31 +407,22 @@ static int tulip_rx(struct net_device *dev)
dev->name, status);
tp->stats.rx_length_errors++;
}
- } else if (status & RxDescFatalErr) {
+ } else {
/* There was a fatal error. */
if (tulip_debug > 2)
printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
dev->name, status);
tp->stats.rx_errors++; /* end of a packet.*/
- if (status & 0x0890) tp->stats.rx_length_errors++;
+ if (pkt_len > 1518 ||
+ (status & RxDescRunt))
+ tp->stats.rx_length_errors++;
if (status & 0x0004) tp->stats.rx_frame_errors++;
if (status & 0x0002) tp->stats.rx_crc_errors++;
if (status & 0x0001) tp->stats.rx_fifo_errors++;
}
} else {
- /* Omit the four octet CRC from the length. */
- short pkt_len = ((status >> 16) & 0x7ff) - 4;
struct sk_buff *skb;
-#ifndef final_version
- if (pkt_len > 1518) {
- printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
- dev->name, pkt_len, pkt_len);
- pkt_len = 1518;
- tp->stats.rx_length_errors++;
- }
-#endif
-
/* Check if the packet is long enough to accept without copying
to a minimally-sized skbuff. */
if (pkt_len < tulip_rx_copybreak
@@ -519,7 +545,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance)
rxd++;
/* Mask RX intrs and add the device to poll list. */
iowrite32(tulip_tbl[tp->chip_id].valid_intrs&~RxPollInt, ioaddr + CSR7);
- netif_rx_schedule(&tp->napi);
+ napi_schedule(&tp->napi);
if (!(csr5&~(AbnormalIntr|NormalIntr|RxPollInt|TPLnkPass)))
break;
diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
index 91cf9c863910..daddfa51853e 100644
--- a/drivers/net/tulip/media.c
+++ b/drivers/net/tulip/media.c
@@ -69,11 +69,10 @@ int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
spin_lock_irqsave(&tp->mii_lock, flags);
if (tp->chip_id == LC82C168) {
- int i = 1000;
iowrite32(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
ioread32(ioaddr + 0xA0);
ioread32(ioaddr + 0xA0);
- while (--i > 0) {
+ for (i = 1000; i >= 0; --i) {
barrier();
if ( ! ((retval = ioread32(ioaddr + 0xA0)) & 0x80000000))
break;
@@ -131,13 +130,12 @@ void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int val)
spin_lock_irqsave(&tp->mii_lock, flags);
if (tp->chip_id == LC82C168) {
- int i = 1000;
iowrite32(cmd, ioaddr + 0xA0);
- do {
+ for (i = 1000; i >= 0; --i) {
barrier();
if ( ! (ioread32(ioaddr + 0xA0) & 0x80000000))
break;
- } while (--i > 0);
+ }
spin_unlock_irqrestore(&tp->mii_lock, flags);
return;
}
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
index 19abbc36b60a..0afa2d4f9472 100644
--- a/drivers/net/tulip/tulip.h
+++ b/drivers/net/tulip/tulip.h
@@ -201,8 +201,38 @@ enum desc_status_bits {
DescStartPkt = 0x20000000,
DescEndRing = 0x02000000,
DescUseLink = 0x01000000,
- RxDescFatalErr = 0x008000,
+
+ /*
+ * Error summary flag is logical or of 'CRC Error', 'Collision Seen',
+ * 'Frame Too Long', 'Runt' and 'Descriptor Error' flags generated
+ * within tulip chip.
+ */
+ RxDescErrorSummary = 0x8000,
+ RxDescCRCError = 0x0002,
+ RxDescCollisionSeen = 0x0040,
+
+ /*
+ * 'Frame Too Long' flag is set if packet length including CRC exceeds
+ * 1518. However, a full sized VLAN tagged frame is 1522 bytes
+ * including CRC.
+ *
+ * The tulip chip does not block oversized frames, and if this flag is
+ * set on a receive descriptor it does not indicate the frame has been
+ * truncated. The receive descriptor also includes the actual length.
+ * Therefore we can safety ignore this flag and check the length
+ * ourselves.
+ */
+ RxDescFrameTooLong = 0x0080,
+ RxDescRunt = 0x0800,
+ RxDescDescErr = 0x4000,
RxWholePkt = 0x00000300,
+ /*
+ * Top three bits of 14 bit frame length (status bits 27-29) should
+ * never be set as that would make frame over 2047 bytes. The Receive
+ * Watchdog flag (bit 4) may indicate the length is over 2048 and the
+ * length field is invalid.
+ */
+ RxLengthOver2047 = 0x38000010
};
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index bee75fa87a9c..2abb5d3becc6 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -255,6 +255,7 @@ const char tulip_media_cap[32] =
static void tulip_tx_timeout(struct net_device *dev);
static void tulip_init_ring(struct net_device *dev);
+static void tulip_free_ring(struct net_device *dev);
static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev);
static int tulip_open(struct net_device *dev);
static int tulip_close(struct net_device *dev);
@@ -502,16 +503,21 @@ tulip_open(struct net_device *dev)
{
int retval;
- if ((retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev)))
- return retval;
-
tulip_init_ring (dev);
+ retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev);
+ if (retval)
+ goto free_ring;
+
tulip_up (dev);
netif_start_queue (dev);
return 0;
+
+free_ring:
+ tulip_free_ring (dev);
+ return retval;
}
@@ -768,23 +774,11 @@ static void tulip_down (struct net_device *dev)
tulip_set_power_state (tp, 0, 1);
}
-
-static int tulip_close (struct net_device *dev)
+static void tulip_free_ring (struct net_device *dev)
{
struct tulip_private *tp = netdev_priv(dev);
- void __iomem *ioaddr = tp->base_addr;
int i;
- netif_stop_queue (dev);
-
- tulip_down (dev);
-
- if (tulip_debug > 1)
- printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
- dev->name, ioread32 (ioaddr + CSR5));
-
- free_irq (dev->irq, dev);
-
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb = tp->rx_buffers[i].skb;
@@ -803,6 +797,7 @@ static int tulip_close (struct net_device *dev)
dev_kfree_skb (skb);
}
}
+
for (i = 0; i < TX_RING_SIZE; i++) {
struct sk_buff *skb = tp->tx_buffers[i].skb;
@@ -814,6 +809,24 @@ static int tulip_close (struct net_device *dev)
tp->tx_buffers[i].skb = NULL;
tp->tx_buffers[i].mapping = 0;
}
+}
+
+static int tulip_close (struct net_device *dev)
+{
+ struct tulip_private *tp = netdev_priv(dev);
+ void __iomem *ioaddr = tp->base_addr;
+
+ netif_stop_queue (dev);
+
+ tulip_down (dev);
+
+ if (tulip_debug > 1)
+ printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
+ dev->name, ioread32 (ioaddr + CSR5));
+
+ free_irq (dev->irq, dev);
+
+ tulip_free_ring (dev);
return 0;
}
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 030e02e63023..c227db079621 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -200,7 +200,7 @@ enum uli526x_CR6_bits {
/* Global variable declaration ----------------------------- */
static int __devinitdata printed_version;
-static char version[] __devinitdata =
+static const char version[] __devinitconst =
KERN_INFO DRV_NAME ": ULi M5261/M5263 net driver, version "
DRV_VERSION " (" DRV_RELDATE ")\n";
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index f467bf87817d..c61a01b029af 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -139,9 +139,10 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
/* These identify the driver base version and may not be removed. */
-static char version[] =
-KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) " DRV_RELDATE " Donald Becker <becker@scyld.com>\n"
-KERN_INFO " http://www.scyld.com/network/drivers.html\n";
+static const char version[] __initconst =
+ KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) "
+ DRV_RELDATE " Donald Becker <becker@scyld.com>\n"
+ KERN_INFO " http://www.scyld.com/network/drivers.html\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("Winbond W89c840 Ethernet driver");
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 09fea31d3e36..a1b0697340ba 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -63,6 +63,8 @@
#include <linux/virtio_net.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
+#include <net/rtnetlink.h>
+#include <net/sock.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -87,26 +89,127 @@ struct tap_filter {
unsigned char addr[FLT_EXACT_COUNT][ETH_ALEN];
};
+struct tun_file {
+ atomic_t count;
+ struct tun_struct *tun;
+ struct net *net;
+ wait_queue_head_t read_wait;
+};
+
+struct tun_sock;
+
struct tun_struct {
- struct list_head list;
+ struct tun_file *tfile;
unsigned int flags;
- int attached;
uid_t owner;
gid_t group;
- wait_queue_head_t read_wait;
struct sk_buff_head readq;
struct net_device *dev;
struct fasync_struct *fasync;
struct tap_filter txflt;
+ struct sock *sk;
+ struct socket socket;
#ifdef TUN_DEBUG
int debug;
#endif
};
+struct tun_sock {
+ struct sock sk;
+ struct tun_struct *tun;
+};
+
+static inline struct tun_sock *tun_sk(struct sock *sk)
+{
+ return container_of(sk, struct tun_sock, sk);
+}
+
+static int tun_attach(struct tun_struct *tun, struct file *file)
+{
+ struct tun_file *tfile = file->private_data;
+ const struct cred *cred = current_cred();
+ int err;
+
+ ASSERT_RTNL();
+
+ /* Check permissions */
+ if (((tun->owner != -1 && cred->euid != tun->owner) ||
+ (tun->group != -1 && !in_egroup_p(tun->group))) &&
+ !capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ netif_tx_lock_bh(tun->dev);
+
+ err = -EINVAL;
+ if (tfile->tun)
+ goto out;
+
+ err = -EBUSY;
+ if (tun->tfile)
+ goto out;
+
+ err = 0;
+ tfile->tun = tun;
+ tun->tfile = tfile;
+ dev_hold(tun->dev);
+ atomic_inc(&tfile->count);
+
+out:
+ netif_tx_unlock_bh(tun->dev);
+ return err;
+}
+
+static void __tun_detach(struct tun_struct *tun)
+{
+ struct tun_file *tfile = tun->tfile;
+
+ /* Detach from net device */
+ netif_tx_lock_bh(tun->dev);
+ tfile->tun = NULL;
+ tun->tfile = NULL;
+ netif_tx_unlock_bh(tun->dev);
+
+ /* Drop read queue */
+ skb_queue_purge(&tun->readq);
+
+ /* Drop the extra count on the net device */
+ dev_put(tun->dev);
+}
+
+static void tun_detach(struct tun_struct *tun)
+{
+ rtnl_lock();
+ __tun_detach(tun);
+ rtnl_unlock();
+}
+
+static struct tun_struct *__tun_get(struct tun_file *tfile)
+{
+ struct tun_struct *tun = NULL;
+
+ if (atomic_inc_not_zero(&tfile->count))
+ tun = tfile->tun;
+
+ return tun;
+}
+
+static struct tun_struct *tun_get(struct file *file)
+{
+ return __tun_get(file->private_data);
+}
+
+static void tun_put(struct tun_struct *tun)
+{
+ struct tun_file *tfile = tun->tfile;
+
+ if (atomic_dec_and_test(&tfile->count))
+ tun_detach(tfile->tun);
+}
+
/* TAP filterting */
static void addr_hash_set(u32 *mask, const u8 *addr)
{
@@ -219,13 +322,23 @@ static int check_filter(struct tap_filter *filter, const struct sk_buff *skb)
/* Network device part of the driver */
-static int tun_net_id;
-struct tun_net {
- struct list_head dev_list;
-};
-
static const struct ethtool_ops tun_ethtool_ops;
+/* Net device detach from fd. */
+static void tun_net_uninit(struct net_device *dev)
+{
+ struct tun_struct *tun = netdev_priv(dev);
+ struct tun_file *tfile = tun->tfile;
+
+ /* Inform the methods they need to stop using the dev.
+ */
+ if (tfile) {
+ wake_up_all(&tfile->read_wait);
+ if (atomic_dec_and_test(&tfile->count))
+ __tun_detach(tun);
+ }
+}
+
/* Net device open. */
static int tun_net_open(struct net_device *dev)
{
@@ -248,7 +361,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->dev->name, skb->len);
/* Drop packet if interface is not attached */
- if (!tun->attached)
+ if (!tun->tfile)
goto drop;
/* Drop if the filter does not like it.
@@ -280,7 +393,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
/* Notify and wake up reader process */
if (tun->flags & TUN_FASYNC)
kill_fasync(&tun->fasync, SIGIO, POLL_IN);
- wake_up_interruptible(&tun->read_wait);
+ wake_up_interruptible(&tun->tfile->read_wait);
return 0;
drop:
@@ -312,6 +425,7 @@ tun_net_change_mtu(struct net_device *dev, int new_mtu)
}
static const struct net_device_ops tun_netdev_ops = {
+ .ndo_uninit = tun_net_uninit,
.ndo_open = tun_net_open,
.ndo_stop = tun_net_close,
.ndo_start_xmit = tun_net_xmit,
@@ -319,6 +433,7 @@ static const struct net_device_ops tun_netdev_ops = {
};
static const struct net_device_ops tap_netdev_ops = {
+ .ndo_uninit = tun_net_uninit,
.ndo_open = tun_net_open,
.ndo_stop = tun_net_close,
.ndo_start_xmit = tun_net_xmit,
@@ -365,86 +480,66 @@ static void tun_net_init(struct net_device *dev)
/* Poll */
static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
{
- struct tun_struct *tun = file->private_data;
- unsigned int mask = POLLOUT | POLLWRNORM;
+ struct tun_file *tfile = file->private_data;
+ struct tun_struct *tun = __tun_get(tfile);
+ struct sock *sk = tun->sk;
+ unsigned int mask = 0;
if (!tun)
- return -EBADFD;
+ return POLLERR;
DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);
- poll_wait(file, &tun->read_wait, wait);
+ poll_wait(file, &tfile->read_wait, wait);
if (!skb_queue_empty(&tun->readq))
mask |= POLLIN | POLLRDNORM;
+ if (sock_writeable(sk) ||
+ (!test_and_set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags) &&
+ sock_writeable(sk)))
+ mask |= POLLOUT | POLLWRNORM;
+
+ if (tun->dev->reg_state != NETREG_REGISTERED)
+ mask = POLLERR;
+
+ tun_put(tun);
return mask;
}
/* prepad is the amount to reserve at front. len is length after that.
* linear is a hint as to how much to copy (usually headers). */
-static struct sk_buff *tun_alloc_skb(size_t prepad, size_t len, size_t linear,
- gfp_t gfp)
+static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun,
+ size_t prepad, size_t len,
+ size_t linear, int noblock)
{
+ struct sock *sk = tun->sk;
struct sk_buff *skb;
- unsigned int i;
-
- skb = alloc_skb(prepad + len, gfp|__GFP_NOWARN);
- if (skb) {
- skb_reserve(skb, prepad);
- skb_put(skb, len);
- return skb;
- }
+ int err;
/* Under a page? Don't bother with paged skb. */
if (prepad + len < PAGE_SIZE)
- return NULL;
+ linear = len;
- /* Start with a normal skb, and add pages. */
- skb = alloc_skb(prepad + linear, gfp);
+ skb = sock_alloc_send_pskb(sk, prepad + linear, len - linear, noblock,
+ &err);
if (!skb)
- return NULL;
+ return ERR_PTR(err);
skb_reserve(skb, prepad);
skb_put(skb, linear);
-
- len -= linear;
-
- for (i = 0; i < MAX_SKB_FRAGS; i++) {
- skb_frag_t *f = &skb_shinfo(skb)->frags[i];
-
- f->page = alloc_page(gfp|__GFP_ZERO);
- if (!f->page)
- break;
-
- f->page_offset = 0;
- f->size = PAGE_SIZE;
-
- skb->data_len += PAGE_SIZE;
- skb->len += PAGE_SIZE;
- skb->truesize += PAGE_SIZE;
- skb_shinfo(skb)->nr_frags++;
-
- if (len < PAGE_SIZE) {
- len = 0;
- break;
- }
- len -= PAGE_SIZE;
- }
-
- /* Too large, or alloc fail? */
- if (unlikely(len)) {
- kfree_skb(skb);
- skb = NULL;
- }
+ skb->data_len = len - linear;
+ skb->len += len - linear;
return skb;
}
/* Get packet from user space buffer */
-static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count)
+static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
+ struct iovec *iv, size_t count,
+ int noblock)
{
- struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) };
+ struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
struct sk_buff *skb;
size_t len = count, align = 0;
struct virtio_net_hdr gso = { 0 };
@@ -474,9 +569,11 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
return -EINVAL;
}
- if (!(skb = tun_alloc_skb(align, len, gso.hdr_len, GFP_KERNEL))) {
- tun->dev->stats.rx_dropped++;
- return -ENOMEM;
+ skb = tun_alloc_skb(tun, align, len, gso.hdr_len, noblock);
+ if (IS_ERR(skb)) {
+ if (PTR_ERR(skb) != -EAGAIN)
+ tun->dev->stats.rx_dropped++;
+ return PTR_ERR(skb);
}
if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) {
@@ -562,14 +659,20 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
unsigned long count, loff_t pos)
{
- struct tun_struct *tun = iocb->ki_filp->private_data;
+ struct file *file = iocb->ki_filp;
+ struct tun_struct *tun = tun_get(file);
+ ssize_t result;
if (!tun)
return -EBADFD;
DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count);
- return tun_get_user(tun, (struct iovec *) iv, iov_length(iv, count));
+ result = tun_get_user(tun, (struct iovec *)iv, iov_length(iv, count),
+ file->f_flags & O_NONBLOCK);
+
+ tun_put(tun);
+ return result;
}
/* Put packet to the user space buffer */
@@ -642,7 +745,8 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
unsigned long count, loff_t pos)
{
struct file *file = iocb->ki_filp;
- struct tun_struct *tun = file->private_data;
+ struct tun_file *tfile = file->private_data;
+ struct tun_struct *tun = __tun_get(tfile);
DECLARE_WAITQUEUE(wait, current);
struct sk_buff *skb;
ssize_t len, ret = 0;
@@ -653,10 +757,12 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name);
len = iov_length(iv, count);
- if (len < 0)
- return -EINVAL;
+ if (len < 0) {
+ ret = -EINVAL;
+ goto out;
+ }
- add_wait_queue(&tun->read_wait, &wait);
+ add_wait_queue(&tfile->read_wait, &wait);
while (len) {
current->state = TASK_INTERRUPTIBLE;
@@ -670,6 +776,10 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
ret = -ERESTARTSYS;
break;
}
+ if (tun->dev->reg_state != NETREG_REGISTERED) {
+ ret = -EIO;
+ break;
+ }
/* Nothing to read, let's sleep */
schedule();
@@ -683,8 +793,10 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
}
current->state = TASK_RUNNING;
- remove_wait_queue(&tun->read_wait, &wait);
+ remove_wait_queue(&tfile->read_wait, &wait);
+out:
+ tun_put(tun);
return ret;
}
@@ -693,54 +805,78 @@ static void tun_setup(struct net_device *dev)
struct tun_struct *tun = netdev_priv(dev);
skb_queue_head_init(&tun->readq);
- init_waitqueue_head(&tun->read_wait);
tun->owner = -1;
tun->group = -1;
dev->ethtool_ops = &tun_ethtool_ops;
dev->destructor = free_netdev;
- dev->features |= NETIF_F_NETNS_LOCAL;
}
-static struct tun_struct *tun_get_by_name(struct tun_net *tn, const char *name)
+/* Trivial set of netlink ops to allow deleting tun or tap
+ * device with netlink.
+ */
+static int tun_validate(struct nlattr *tb[], struct nlattr *data[])
+{
+ return -EINVAL;
+}
+
+static struct rtnl_link_ops tun_link_ops __read_mostly = {
+ .kind = DRV_NAME,
+ .priv_size = sizeof(struct tun_struct),
+ .setup = tun_setup,
+ .validate = tun_validate,
+};
+
+static void tun_sock_write_space(struct sock *sk)
{
struct tun_struct *tun;
- ASSERT_RTNL();
- list_for_each_entry(tun, &tn->dev_list, list) {
- if (!strncmp(tun->dev->name, name, IFNAMSIZ))
- return tun;
- }
+ if (!sock_writeable(sk))
+ return;
+
+ if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+ wake_up_interruptible_sync(sk->sk_sleep);
+
+ if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags))
+ return;
- return NULL;
+ tun = container_of(sk, struct tun_sock, sk)->tun;
+ kill_fasync(&tun->fasync, SIGIO, POLL_OUT);
}
+static void tun_sock_destruct(struct sock *sk)
+{
+ dev_put(container_of(sk, struct tun_sock, sk)->tun->dev);
+}
+
+static struct proto tun_proto = {
+ .name = "tun",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct tun_sock),
+};
+
static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
{
- struct tun_net *tn;
+ struct sock *sk;
struct tun_struct *tun;
struct net_device *dev;
- const struct cred *cred = current_cred();
+ struct tun_file *tfile = file->private_data;
int err;
- tn = net_generic(net, tun_net_id);
- tun = tun_get_by_name(tn, ifr->ifr_name);
- if (tun) {
- if (tun->attached)
- return -EBUSY;
-
- /* Check permissions */
- if (((tun->owner != -1 &&
- cred->euid != tun->owner) ||
- (tun->group != -1 &&
- cred->egid != tun->group)) &&
- !capable(CAP_NET_ADMIN)) {
- return -EPERM;
- }
+ dev = __dev_get_by_name(net, ifr->ifr_name);
+ if (dev) {
+ if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops)
+ tun = netdev_priv(dev);
+ else if ((ifr->ifr_flags & IFF_TAP) && dev->netdev_ops == &tap_netdev_ops)
+ tun = netdev_priv(dev);
+ else
+ return -EINVAL;
+
+ err = tun_attach(tun, file);
+ if (err < 0)
+ return err;
}
- else if (__dev_get_by_name(net, ifr->ifr_name))
- return -EINVAL;
else {
char *name;
unsigned long flags = 0;
@@ -771,25 +907,45 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
return -ENOMEM;
dev_net_set(dev, net);
+ dev->rtnl_link_ops = &tun_link_ops;
tun = netdev_priv(dev);
tun->dev = dev;
tun->flags = flags;
tun->txflt.count = 0;
+ err = -ENOMEM;
+ sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto);
+ if (!sk)
+ goto err_free_dev;
+
+ /* This ref count is for tun->sk. */
+ dev_hold(dev);
+ sock_init_data(&tun->socket, sk);
+ sk->sk_write_space = tun_sock_write_space;
+ sk->sk_destruct = tun_sock_destruct;
+ sk->sk_sndbuf = INT_MAX;
+ sk->sk_sleep = &tfile->read_wait;
+
+ tun->sk = sk;
+ container_of(sk, struct tun_sock, sk)->tun = tun;
+
tun_net_init(dev);
if (strchr(dev->name, '%')) {
err = dev_alloc_name(dev, dev->name);
if (err < 0)
- goto err_free_dev;
+ goto err_free_sk;
}
+ err = -EINVAL;
err = register_netdevice(tun->dev);
if (err < 0)
goto err_free_dev;
- list_add(&tun->list, &tn->dev_list);
+ err = tun_attach(tun, file);
+ if (err < 0)
+ goto err_free_dev;
}
DBG(KERN_INFO "%s: tun_set_iff\n", tun->dev->name);
@@ -809,10 +965,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
else
tun->flags &= ~TUN_VNET_HDR;
- file->private_data = tun;
- tun->attached = 1;
- get_net(dev_net(tun->dev));
-
/* Make sure persistent devices do not get stuck in
* xoff state.
*/
@@ -822,6 +974,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
strcpy(ifr->ifr_name, tun->dev->name);
return 0;
+ err_free_sk:
+ sock_put(sk);
err_free_dev:
free_netdev(dev);
failed:
@@ -830,7 +984,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
{
- struct tun_struct *tun = file->private_data;
+ struct tun_struct *tun = tun_get(file);
if (!tun)
return -EBADFD;
@@ -855,6 +1009,7 @@ static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
if (tun->flags & TUN_VNET_HDR)
ifr->ifr_flags |= IFF_VNET_HDR;
+ tun_put(tun);
return 0;
}
@@ -901,22 +1056,34 @@ static int set_offload(struct net_device *dev, unsigned long arg)
static int tun_chr_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct tun_struct *tun = file->private_data;
+ struct tun_file *tfile = file->private_data;
+ struct tun_struct *tun;
void __user* argp = (void __user*)arg;
struct ifreq ifr;
+ int sndbuf;
int ret;
if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
if (copy_from_user(&ifr, argp, sizeof ifr))
return -EFAULT;
+ if (cmd == TUNGETFEATURES) {
+ /* Currently this just means: "what IFF flags are valid?".
+ * This is needed because we never checked for invalid flags on
+ * TUNSETIFF. */
+ return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
+ IFF_VNET_HDR,
+ (unsigned int __user*)argp);
+ }
+
+ tun = __tun_get(tfile);
if (cmd == TUNSETIFF && !tun) {
int err;
ifr.ifr_name[IFNAMSIZ-1] = '\0';
rtnl_lock();
- err = tun_set_iff(current->nsproxy->net_ns, file, &ifr);
+ err = tun_set_iff(tfile->net, file, &ifr);
rtnl_unlock();
if (err)
@@ -927,28 +1094,21 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
return 0;
}
- if (cmd == TUNGETFEATURES) {
- /* Currently this just means: "what IFF flags are valid?".
- * This is needed because we never checked for invalid flags on
- * TUNSETIFF. */
- return put_user(IFF_TUN | IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE |
- IFF_VNET_HDR,
- (unsigned int __user*)argp);
- }
if (!tun)
return -EBADFD;
DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
+ ret = 0;
switch (cmd) {
case TUNGETIFF:
ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr);
if (ret)
- return ret;
+ break;
if (copy_to_user(argp, &ifr, sizeof(ifr)))
- return -EFAULT;
+ ret = -EFAULT;
break;
case TUNSETNOCSUM:
@@ -1000,7 +1160,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
ret = 0;
}
rtnl_unlock();
- return ret;
+ break;
#ifdef TUN_DEBUG
case TUNSETDEBUG:
@@ -1011,24 +1171,25 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
rtnl_lock();
ret = set_offload(tun->dev, arg);
rtnl_unlock();
- return ret;
+ break;
case TUNSETTXFILTER:
/* Can be set only for TAPs */
+ ret = -EINVAL;
if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
- return -EINVAL;
+ break;
rtnl_lock();
ret = update_filter(&tun->txflt, (void __user *)arg);
rtnl_unlock();
- return ret;
+ break;
case SIOCGIFHWADDR:
/* Get hw addres */
memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN);
ifr.ifr_hwaddr.sa_family = tun->dev->type;
if (copy_to_user(argp, &ifr, sizeof ifr))
- return -EFAULT;
- return 0;
+ ret = -EFAULT;
+ break;
case SIOCSIFHWADDR:
/* Set hw address */
@@ -1038,18 +1199,35 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
rtnl_lock();
ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
rtnl_unlock();
- return ret;
+ break;
+
+ case TUNGETSNDBUF:
+ sndbuf = tun->sk->sk_sndbuf;
+ if (copy_to_user(argp, &sndbuf, sizeof(sndbuf)))
+ ret = -EFAULT;
+ break;
+
+ case TUNSETSNDBUF:
+ if (copy_from_user(&sndbuf, argp, sizeof(sndbuf))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ tun->sk->sk_sndbuf = sndbuf;
+ break;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ break;
};
- return 0;
+ tun_put(tun);
+ return ret;
}
static int tun_chr_fasync(int fd, struct file *file, int on)
{
- struct tun_struct *tun = file->private_data;
+ struct tun_struct *tun = tun_get(file);
int ret;
if (!tun)
@@ -1071,42 +1249,50 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
ret = 0;
out:
unlock_kernel();
+ tun_put(tun);
return ret;
}
static int tun_chr_open(struct inode *inode, struct file * file)
{
+ struct tun_file *tfile;
cycle_kernel_lock();
DBG1(KERN_INFO "tunX: tun_chr_open\n");
- file->private_data = NULL;
+
+ tfile = kmalloc(sizeof(*tfile), GFP_KERNEL);
+ if (!tfile)
+ return -ENOMEM;
+ atomic_set(&tfile->count, 0);
+ tfile->tun = NULL;
+ tfile->net = get_net(current->nsproxy->net_ns);
+ init_waitqueue_head(&tfile->read_wait);
+ file->private_data = tfile;
return 0;
}
static int tun_chr_close(struct inode *inode, struct file *file)
{
- struct tun_struct *tun = file->private_data;
-
- if (!tun)
- return 0;
+ struct tun_file *tfile = file->private_data;
+ struct tun_struct *tun = __tun_get(tfile);
- DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
- rtnl_lock();
+ if (tun) {
+ DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
- /* Detach from net device */
- file->private_data = NULL;
- tun->attached = 0;
- put_net(dev_net(tun->dev));
+ rtnl_lock();
+ __tun_detach(tun);
- /* Drop read queue */
- skb_queue_purge(&tun->readq);
+ /* If desireable, unregister the netdevice. */
+ if (!(tun->flags & TUN_PERSIST)) {
+ sock_put(tun->sk);
+ unregister_netdevice(tun->dev);
+ }
- if (!(tun->flags & TUN_PERSIST)) {
- list_del(&tun->list);
- unregister_netdevice(tun->dev);
+ rtnl_unlock();
}
- rtnl_unlock();
+ put_net(tfile->net);
+ kfree(tfile);
return 0;
}
@@ -1187,7 +1373,7 @@ static void tun_set_msglevel(struct net_device *dev, u32 value)
static u32 tun_get_link(struct net_device *dev)
{
struct tun_struct *tun = netdev_priv(dev);
- return tun->attached;
+ return !!tun->tfile;
}
static u32 tun_get_rx_csum(struct net_device *dev)
@@ -1216,45 +1402,6 @@ static const struct ethtool_ops tun_ethtool_ops = {
.set_rx_csum = tun_set_rx_csum
};
-static int tun_init_net(struct net *net)
-{
- struct tun_net *tn;
-
- tn = kmalloc(sizeof(*tn), GFP_KERNEL);
- if (tn == NULL)
- return -ENOMEM;
-
- INIT_LIST_HEAD(&tn->dev_list);
-
- if (net_assign_generic(net, tun_net_id, tn)) {
- kfree(tn);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void tun_exit_net(struct net *net)
-{
- struct tun_net *tn;
- struct tun_struct *tun, *nxt;
-
- tn = net_generic(net, tun_net_id);
-
- rtnl_lock();
- list_for_each_entry_safe(tun, nxt, &tn->dev_list, list) {
- DBG(KERN_INFO "%s cleaned up\n", tun->dev->name);
- unregister_netdevice(tun->dev);
- }
- rtnl_unlock();
-
- kfree(tn);
-}
-
-static struct pernet_operations tun_net_ops = {
- .init = tun_init_net,
- .exit = tun_exit_net,
-};
static int __init tun_init(void)
{
@@ -1263,10 +1410,10 @@ static int __init tun_init(void)
printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT);
- ret = register_pernet_gen_device(&tun_net_id, &tun_net_ops);
+ ret = rtnl_link_register(&tun_link_ops);
if (ret) {
- printk(KERN_ERR "tun: Can't register pernet ops\n");
- goto err_pernet;
+ printk(KERN_ERR "tun: Can't register link_ops\n");
+ goto err_linkops;
}
ret = misc_register(&tun_miscdev);
@@ -1274,18 +1421,17 @@ static int __init tun_init(void)
printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR);
goto err_misc;
}
- return 0;
-
+ return 0;
err_misc:
- unregister_pernet_gen_device(tun_net_id, &tun_net_ops);
-err_pernet:
+ rtnl_link_unregister(&tun_link_ops);
+err_linkops:
return ret;
}
static void tun_cleanup(void)
{
misc_deregister(&tun_miscdev);
- unregister_pernet_gen_device(tun_net_id, &tun_net_ops);
+ rtnl_link_unregister(&tun_link_ops);
}
module_init(tun_init);
diff --git a/drivers/net/typhoon-firmware.h b/drivers/net/typhoon-firmware.h
deleted file mode 100644
index 182d69e99fc5..000000000000
--- a/drivers/net/typhoon-firmware.h
+++ /dev/null
@@ -1,3778 +0,0 @@
-/*
- * Copyright 1999-2004 3Com Corporation. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms of the 3c990img.h
- * microcode software are permitted provided that the following conditions
- * are met:
- * 1. Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistribution in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of 3Com may not be used to endorse or promote products
- * derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY 3COM ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * USER ACKNOWLEDGES AND AGREES THAT PURCHASE OR USE OF THE 3c990img.h
- * MICROCODE SOFTWARE WILL NOT CREATE OR GIVE GROUNDS FOR A LICENSE BY
- * IMPLICATION, ESTOPPEL, OR OTHERWISE IN ANY INTELLECTUAL PROPERTY RIGHTS
- * (PATENT, COPYRIGHT, TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT)
- * EMBODIED IN ANY OTHER 3COM HARDWARE OR SOFTWARE EITHER SOLELY OR IN
- * COMBINATION WITH THE 3c990img.h MICROCODE SOFTWARE
- */
-
- /* ver 03.001.008 */
-static const u8 typhoon_firmware_image[] = {
-0x54, 0x59, 0x50, 0x48, 0x4f, 0x4f, 0x4e, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcb, 0x99, 0xb1, 0xd4,
-0x4c, 0xb8, 0xd0, 0x4b, 0x32, 0x02, 0xd4, 0xee, 0x73, 0x7e, 0x0b, 0x13,
-0x9b, 0xc0, 0xae, 0xf4, 0x40, 0x01, 0x00, 0x00, 0xe8, 0xfc, 0x00, 0x00,
-0x00, 0x00, 0xff, 0xff, 0x39, 0x00, 0x00, 0xea, 0x05, 0x00, 0x00, 0xea,
-0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea,
-0x01, 0x00, 0x00, 0xea, 0x32, 0x02, 0x00, 0xea, 0xc5, 0x14, 0x00, 0xea,
-0x07, 0x00, 0x2d, 0xe9, 0x0e, 0x00, 0xa0, 0xe1, 0x00, 0x10, 0x0f, 0xe1,
-0xd0, 0x20, 0x9f, 0xe5, 0x12, 0xff, 0x2f, 0xe1, 0xfe, 0xff, 0xff, 0xea,
-0x01, 0x00, 0x80, 0xe0, 0x04, 0x20, 0x81, 0xe4, 0x01, 0x00, 0x50, 0xe1,
-0xfc, 0xff, 0xff, 0x1a, 0x0e, 0xf0, 0xa0, 0xe1, 0x00, 0xa0, 0xa0, 0xe1,
-0x0e, 0xb0, 0xa0, 0xe1, 0x00, 0x00, 0xa0, 0xe3, 0xa8, 0x10, 0x9f, 0xe5,
-0x00, 0x00, 0x81, 0xe5, 0xa4, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0x81, 0xe5,
-0x01, 0x16, 0xa0, 0xe3, 0x00, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x80, 0xe3,
-0x00, 0x00, 0x81, 0xe5, 0xd7, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
-0x88, 0xd0, 0x9f, 0xe5, 0xdb, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
-0x7c, 0xd0, 0x9f, 0xe5, 0xd2, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
-0x74, 0xd0, 0x9f, 0xe5, 0xd1, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
-0x6c, 0xd0, 0x9f, 0xe5, 0x9b, 0x14, 0x00, 0xeb, 0xd3, 0x00, 0xa0, 0xe3,
-0x00, 0xf0, 0x21, 0xe1, 0x60, 0xd0, 0x9f, 0xe5, 0x60, 0x00, 0x9f, 0xe5,
-0x60, 0x10, 0x9f, 0xe5, 0x60, 0x20, 0x9f, 0xe5, 0xdb, 0xff, 0xff, 0xeb,
-0x5c, 0x00, 0x9f, 0xe5, 0x5c, 0x10, 0x9f, 0xe5, 0x00, 0x20, 0xa0, 0xe3,
-0xd7, 0xff, 0xff, 0xeb, 0x54, 0x00, 0x9f, 0xe5, 0x54, 0x10, 0x9f, 0xe5,
-0xd4, 0xff, 0xff, 0xeb, 0x0a, 0x00, 0xa0, 0xe1, 0x0b, 0xf0, 0xa0, 0xe1,
-0xd3, 0x10, 0xa0, 0xe3, 0x01, 0xf0, 0x21, 0xe1, 0xd4, 0xff, 0xff, 0xeb,
-0x3c, 0xa0, 0x9f, 0xe5, 0x1a, 0xff, 0x2f, 0xe1, 0xc6, 0xff, 0xff, 0xea,
-0x15, 0x21, 0xff, 0xff, 0x0c, 0x00, 0x10, 0x00, 0x1c, 0x00, 0x10, 0x00,
-0x3c, 0x38, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80, 0xfc, 0x3f, 0x00, 0x80,
-0x7c, 0x34, 0x00, 0x80, 0x80, 0x0f, 0x00, 0x00, 0x80, 0x30, 0x00, 0x80,
-0xad, 0xde, 0xad, 0xde, 0xb0, 0xbb, 0x00, 0x00, 0x24, 0xab, 0x20, 0x40,
-0x48, 0x29, 0x00, 0x00, 0x28, 0x05, 0x00, 0x80, 0xbd, 0xba, 0x21, 0x40,
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x58, 0x57, 0x00, 0x00, 0x86, 0x4b, 0x00, 0x00, 0x60, 0x01, 0xff, 0xff,
-0xb0, 0xb5, 0x07, 0x1c, 0x12, 0x4d, 0x00, 0x24, 0x28, 0x68, 0x00, 0x28,
-0x1e, 0xd0, 0x38, 0x1c, 0x10, 0x49, 0x04, 0xf0, 0x7b, 0xfd, 0x29, 0x68,
-0xc0, 0x46, 0x08, 0x60, 0x00, 0x28, 0x15, 0xd0, 0x38, 0x01, 0x0d, 0x49,
-0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x80, 0x29,
-0x0c, 0xd2, 0x01, 0x31, 0x41, 0x63, 0x28, 0x68, 0xc1, 0x69, 0xc0, 0x46,
-0x29, 0x60, 0x39, 0x07, 0x41, 0x60, 0x04, 0x62, 0xc7, 0x62, 0xb0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x20, 0x1c, 0xfa, 0xe7, 0xe8, 0x17, 0x00, 0x80,
-0xee, 0x05, 0x00, 0x00, 0xa0, 0x1c, 0x00, 0x80, 0x02, 0x49, 0x0a, 0x68,
-0xc0, 0x46, 0xc2, 0x61, 0x08, 0x60, 0x70, 0x47,
-0xe8, 0x17, 0x00, 0x80, 0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00,
-0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xe1, 0x00, 0x10, 0xa0, 0xe1,
-0xc0, 0x10, 0x81, 0xe3, 0x01, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1,
-0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1,
-0xc0, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1,
-0x00, 0x00, 0x0f, 0xe1, 0xc0, 0x00, 0xc0, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
-0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 0x40, 0x00, 0x80, 0xe3,
-0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1,
-0x80, 0x00, 0x10, 0xe3, 0x80, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x21, 0xe1,
-0x00, 0x00, 0x00, 0x12, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x50, 0xe3,
-0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0x13, 0x00, 0xf0, 0x21, 0xe1,
-0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0xe3,
-0x00, 0xf0, 0x21, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0x91, 0x00, 0x00, 0xe0,
-0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x20, 0x80, 0xe0, 0x01, 0x00, 0x80, 0xe0,
-0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x08, 0x4f, 0x64, 0x28, 0x04, 0xd3,
-0x64, 0x20, 0x38, 0x63, 0x00, 0x20, 0xc0, 0x43, 0x03, 0xe0, 0x38, 0x63,
-0x04, 0x49, 0x05, 0xf0, 0x01, 0xfb, 0x78, 0x63, 0xb8, 0x63, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x88, 0x13, 0x00, 0x00,
-0x80, 0xb4, 0x10, 0x4b, 0x00, 0x22, 0x1f, 0x6b, 0x64, 0x2f, 0x03, 0xd2,
-0x09, 0x68, 0x09, 0x68, 0x49, 0x08, 0x02, 0xd2, 0x10, 0x1c, 0x80, 0xbc,
-0x70, 0x47, 0x19, 0x1c, 0xdb, 0x6b, 0x4f, 0x6b, 0xbb, 0x42, 0x05, 0xd2,
-0x40, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x18, 0x18, 0xc8, 0x63, 0xf1, 0xe7,
-0x41, 0x68, 0x05, 0x4b, 0x19, 0x43, 0x41, 0x60, 0x04, 0x48, 0xc1, 0x6b,
-0x01, 0x31, 0xc1, 0x63, 0x02, 0x20, 0xe8, 0xe7, 0x68, 0x0e, 0x00, 0x80,
-0x00, 0x00, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c,
-0x15, 0x4c, 0x00, 0x20, 0x21, 0x6b, 0x64, 0x29, 0x0b, 0xd2, 0xb9, 0x6e,
-0x49, 0x08, 0x08, 0xd3, 0x21, 0x6c, 0xa2, 0x6b, 0x91, 0x42, 0x07, 0xd2,
-0xfa, 0x1d, 0x39, 0x32, 0x52, 0x8b, 0x89, 0x18, 0x21, 0x64, 0x90, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62,
-0x38, 0x6b, 0x02, 0xf0, 0x2d, 0xfe, 0x38, 0x1c, 0x02, 0xf0, 0xe8, 0xfa,
-0x01, 0x20, 0xbb, 0x23, 0x1b, 0x01, 0xe1, 0x18, 0xc8, 0x73, 0x05, 0x49,
-0x0a, 0x6c, 0x12, 0x18, 0x0a, 0x64, 0x04, 0x49, 0x8a, 0x6d, 0x12, 0x18,
-0x8a, 0x65, 0xe4, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80,
-0xa4, 0x2a, 0x00, 0x80, 0x80, 0xb4, 0x0a, 0x48, 0xc0, 0x6d, 0x02, 0x23,
-0x18, 0x40, 0x09, 0x4a, 0x00, 0x21, 0x00, 0x28, 0x03, 0xd0, 0xd1, 0x63,
-0x11, 0x64, 0x80, 0xbc, 0x70, 0x47, 0x06, 0x48, 0x07, 0x68, 0x7b, 0x1c,
-0x03, 0x60, 0x0a, 0x2f, 0xf7, 0xd3, 0x01, 0x60, 0xf3, 0xe7, 0x00, 0x00,
-0xa4, 0x2a, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80, 0xe0, 0x01, 0x00, 0x80,
-0x70, 0x47, 0x02, 0x04, 0x12, 0x0c, 0x00, 0x0c, 0x10, 0x18, 0x0a, 0x04,
-0x12, 0x0c, 0x09, 0x0c, 0x51, 0x18, 0x08, 0x18, 0x01, 0x0c, 0x05, 0xd0,
-0x01, 0x04, 0x09, 0x0c, 0x00, 0x0c, 0x08, 0x18, 0x01, 0x0c, 0xf9, 0xd1,
-0x00, 0x04, 0x00, 0x0c, 0x70, 0x47, 0x80, 0xb4, 0x00, 0x22, 0x00, 0x29,
-0x18, 0xd0, 0x4f, 0x08, 0x7b, 0x1e, 0x00, 0x2f,
-0x06, 0xd0, 0x07, 0x88, 0xba, 0x18, 0x02, 0x30, 0x1f, 0x1c, 0x01, 0x3b,
-0x00, 0x2f, 0xf8, 0xd1, 0x49, 0x08, 0x03, 0xd3, 0x00, 0x88, 0x00, 0x06,
-0x00, 0x0e, 0x82, 0x18, 0x10, 0x0c, 0x05, 0xd0, 0x10, 0x04, 0x00, 0x0c,
-0x11, 0x0c, 0x42, 0x18, 0x10, 0x0c, 0xf9, 0xd1, 0x10, 0x04, 0x00, 0x0c,
-0x80, 0xbc, 0x70, 0x47, 0x80, 0xb5, 0x83, 0x89, 0xc7, 0x89, 0xfb, 0x18,
-0x07, 0x8a, 0xfb, 0x18, 0x47, 0x8a, 0xfb, 0x18, 0x40, 0x7a, 0x00, 0x02,
-0xc7, 0x18, 0x38, 0x0c, 0x05, 0xd0, 0x38, 0x04, 0x00, 0x0c, 0x3b, 0x0c,
-0xc7, 0x18, 0x38, 0x0c, 0xf9, 0xd1, 0x08, 0x1c, 0x11, 0x1c, 0xff, 0xf7,
-0xc8, 0xff, 0x01, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 0xb0, 0xff, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x02, 0x23, 0x82, 0x68, 0x1a, 0x40,
-0x00, 0x27, 0x00, 0x2a, 0x0f, 0xd0, 0x0a, 0x4a, 0x93, 0x69, 0x01, 0x33,
-0x93, 0x61, 0x0a, 0x68, 0x8b, 0x68, 0x9a, 0x18, 0x00, 0x68, 0x1c, 0x18,
-0x57, 0x81, 0x09, 0x69, 0x10, 0x1c, 0xff, 0xf7, 0xac, 0xff, 0xc0, 0x43,
-0x60, 0x81, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x23, 0x82, 0x68, 0x1a, 0x40,
-0x00, 0x27, 0x00, 0x2a, 0x11, 0xd0, 0x4a, 0x68, 0x52, 0x09, 0x0e, 0xd3,
-0x09, 0x4a, 0x13, 0x6a, 0x01, 0x33, 0x13, 0x62, 0xcb, 0x68, 0x02, 0x68,
-0x9c, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x3a, 0x1a, 0x43, 0x12, 0x68,
-0x00, 0xf0, 0x2e, 0xf8, 0x20, 0x82, 0x38, 0x1c, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x80, 0x23,
-0x82, 0x68, 0x1a, 0x40, 0x00, 0x24, 0x00, 0x2a, 0x15, 0xd0, 0x4a, 0x68,
-0x92, 0x09, 0x12, 0xd3, 0x0b, 0x4a, 0xd3, 0x69, 0x01, 0x33, 0xd3, 0x61,
-0xcb, 0x68, 0x02, 0x68, 0x9f, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x3a,
-0x1a, 0x43, 0x12, 0x68, 0x00, 0xf0, 0x0e, 0xf8, 0x00, 0x28, 0x00, 0xd1,
-0x04, 0x48, 0xc0, 0x46, 0xf8, 0x80, 0x20, 0x1c, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00,
-0xb0, 0xb5, 0x14, 0x1c, 0x05, 0x1c, 0x0f, 0x1c, 0x38, 0x69, 0xb9, 0x68,
-0x41, 0x18, 0x38, 0x68, 0xff, 0xf7, 0x53, 0xff, 0xc0, 0x43, 0x01, 0x04,
-0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 0x39, 0xff, 0x04, 0x1c, 0xb8, 0x68,
-0x79, 0x69, 0x40, 0x18, 0x69, 0x68, 0x88, 0x42, 0x0c, 0xd2, 0x2a, 0x68,
-0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, 0x05, 0xf9, 0xc0, 0x43,
-0x01, 0x04, 0x09, 0x0c, 0x20, 0x1c, 0xff, 0xf7, 0x26, 0xff, 0x04, 0x1c,
-0xe0, 0x43, 0x00, 0x04, 0x00, 0x0c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0xc0, 0x08, 0x1a, 0xd3, 0xb8, 0x6a,
-0xf9, 0x6b, 0x40, 0x18, 0x79, 0x6c, 0x00, 0xf0, 0xed, 0xf8, 0xc0, 0x43,
-0x01, 0x04, 0x09, 0x0c, 0x0a, 0x48, 0x07, 0xd0, 0x20, 0x23, 0xb9, 0x69,
-0x19, 0x43, 0xb9, 0x61, 0x01, 0x6b, 0x01, 0x31, 0x01, 0x63, 0x07, 0xe0,
-0xff, 0x23, 0x01, 0x33, 0xb9, 0x69, 0x19, 0x43, 0xb9, 0x61, 0x41, 0x6a,
-0x01, 0x31, 0x41, 0x62, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x0c, 0x2b, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0x41, 0x09,
-0x1c, 0xd3, 0xc0, 0x08, 0x1a, 0xd3, 0xf8, 0x1d, 0x39, 0x30, 0x00, 0x7b,
-0x06, 0x28, 0x15, 0xd1, 0x38, 0x1c, 0x00, 0xf0, 0x53, 0xf8, 0x01, 0x1c,
-0x0a, 0x48, 0x07, 0xd0, 0x40, 0x23, 0xb9, 0x69,
-0x19, 0x43, 0xb9, 0x61, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, 0x07, 0xe0,
-0x01, 0x23, 0x9b, 0x02, 0xb9, 0x69, 0x19, 0x43, 0xb9, 0x61, 0xc1, 0x6a,
-0x01, 0x31, 0xc1, 0x62, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x0c, 0x2b, 0x00, 0x80, 0xb0, 0xb5, 0x07, 0x1c, 0xb8, 0x6b, 0x81, 0x09,
-0x2c, 0xd3, 0xc0, 0x08, 0x2a, 0xd3, 0xf8, 0x1d, 0x39, 0x30, 0x00, 0x7b,
-0x11, 0x28, 0x25, 0xd1, 0xb8, 0x6a, 0x39, 0x6c, 0x40, 0x18, 0x01, 0x23,
-0x9b, 0x07, 0x06, 0x30, 0x18, 0x43, 0x00, 0x68, 0x05, 0x04, 0x2d, 0x0c,
-0x0f, 0x4c, 0x11, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x1f, 0xf8, 0x00, 0x28,
-0x0c, 0xd0, 0xa8, 0x42, 0x02, 0xd1, 0x0c, 0x4b, 0x98, 0x42, 0x07, 0xd0,
-0x80, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61, 0x60, 0x6b, 0x01, 0x30,
-0x60, 0x63, 0x07, 0xe0, 0x01, 0x23, 0x5b, 0x02, 0xb8, 0x69, 0x18, 0x43,
-0xb8, 0x61, 0xa0, 0x6a, 0x01, 0x30, 0xa0, 0x62, 0x00, 0x20, 0xb0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00,
-0xf0, 0xb5, 0xff, 0xb0, 0x99, 0xb0, 0x04, 0x1c, 0xe0, 0x6b, 0x61, 0x6c,
-0x09, 0x18, 0x03, 0xaa, 0x85, 0x18, 0xa3, 0x6a, 0x00, 0x20, 0x8a, 0x08,
-0x01, 0x32, 0x97, 0x92, 0x07, 0xd0, 0x82, 0x00, 0x9f, 0x58, 0x03, 0xae,
-0xb7, 0x50, 0x97, 0x9a, 0x01, 0x30, 0x82, 0x42, 0xf7, 0xd8, 0x60, 0x6a,
-0x01, 0x23, 0x9b, 0x07, 0x04, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46,
-0x02, 0x90, 0x02, 0xaf, 0x3f, 0x88, 0x03, 0xa8, 0xff, 0xf7, 0x87, 0xfe,
-0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xff, 0xf7, 0x6d, 0xfe,
-0x07, 0x1c, 0xe0, 0x6b, 0xa1, 0x6c, 0x40, 0x18, 0x61, 0x6a, 0x01, 0x23,
-0x9b, 0x07, 0x08, 0x31, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46, 0x01, 0x91,
-0x01, 0xa9, 0x09, 0x88, 0x01, 0x31, 0x88, 0x42, 0x0c, 0xd2, 0xa2, 0x6a,
-0x12, 0x18, 0x09, 0x1a, 0x10, 0x1c, 0x00, 0xf0, 0x2f, 0xf8, 0xc0, 0x43,
-0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0xff, 0xf7, 0x50, 0xfe, 0x07, 0x1c,
-0xa8, 0x89, 0xe9, 0x89, 0x08, 0x18, 0x29, 0x8a, 0x08, 0x18, 0x69, 0x8a,
-0x08, 0x18, 0x69, 0x7a, 0x09, 0x02, 0x08, 0x18, 0xa1, 0x6c, 0x62, 0x6c,
-0x89, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, 0x12, 0x0a, 0x11, 0x43,
-0x09, 0x04, 0x09, 0x0c, 0x09, 0x18, 0x08, 0x0c, 0x05, 0xd0, 0x08, 0x04,
-0x00, 0x0c, 0x09, 0x0c, 0x41, 0x18, 0x08, 0x0c, 0xf9, 0xd1, 0x38, 0x1c,
-0xff, 0xf7, 0x2f, 0xfe, 0xc0, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x7f, 0xb0,
-0x19, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb4, 0x00, 0x22,
-0x00, 0x29, 0x2e, 0xd0, 0x83, 0x07, 0x9b, 0x0f, 0xdc, 0x00, 0x47, 0x18,
-0x04, 0x25, 0xef, 0x1b, 0xbf, 0x07, 0xbf, 0x0f, 0xff, 0x00, 0x80, 0x08,
-0x80, 0x00, 0x59, 0x18, 0x03, 0x31, 0x89, 0x08, 0x4d, 0x1e, 0x02, 0xc8,
-0xe1, 0x40, 0xa1, 0x40, 0x6b, 0x1e, 0x00, 0x2d, 0x09, 0xd0, 0x0c, 0x04,
-0x24, 0x0c, 0xa2, 0x18, 0x09, 0x0c, 0x8a, 0x18, 0x02, 0xc8, 0x1c, 0x1c,
-0x01, 0x3b, 0x00, 0x2c, 0xf5, 0xd1, 0xb9, 0x40, 0x08, 0x1c, 0xf8, 0x40,
-0x01, 0x04, 0x09, 0x0c, 0x89, 0x18, 0x00, 0x0c, 0x42, 0x18, 0x10, 0x0c,
-0x05, 0xd0, 0x10, 0x04, 0x00, 0x0c, 0x11, 0x0c, 0x42, 0x18, 0x10, 0x0c,
-0xf9, 0xd1, 0x10, 0x04, 0x00, 0x0c, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0x00,
-0x90, 0xb4, 0x00, 0x20, 0x01, 0x27, 0x11, 0x49, 0x42, 0x00, 0x12, 0x18,
-0xd2, 0x00, 0x53, 0x18, 0x9c, 0x68, 0x01, 0x23,
-0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x03, 0x1b, 0x0b, 0x8a, 0x58,
-0x12, 0x03, 0x12, 0x0b, 0x93, 0x42, 0x0c, 0xd1, 0x01, 0x30, 0x04, 0x28,
-0xec, 0xd3, 0x08, 0x48, 0xc0, 0x6a, 0x01, 0x03, 0x09, 0x0b, 0x07, 0x48,
-0x00, 0x6f, 0x00, 0x03, 0x00, 0x0b, 0x81, 0x42, 0x02, 0xd0, 0x38, 0x1c,
-0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0xa8, 0x03, 0x00, 0x80,
-0x00, 0x40, 0x14, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x98, 0xb4, 0x14, 0x4a,
-0xc0, 0x46, 0x00, 0x92, 0x83, 0x00, 0x13, 0x48, 0xc0, 0x58, 0x07, 0x03,
-0x3f, 0x0b, 0x12, 0x48, 0xc0, 0x58, 0x02, 0x03, 0x12, 0x0b, 0x11, 0x48,
-0xc0, 0x58, 0x00, 0x03, 0x00, 0x0b, 0x10, 0x4c, 0xe4, 0x58, 0x01, 0x23,
-0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x9b, 0x00, 0xcc, 0x00, 0x01, 0x21,
-0x98, 0x42, 0x01, 0xd1, 0x08, 0x1c, 0x09, 0xe0, 0x98, 0x42, 0x03, 0xd9,
-0x10, 0x1a, 0xda, 0x1b, 0x80, 0x18, 0x00, 0xe0, 0x18, 0x1a, 0x84, 0x42,
-0xf4, 0xd3, 0x00, 0x20, 0x98, 0xbc, 0x70, 0x47, 0x55, 0x55, 0x55, 0x55,
-0x20, 0x04, 0x00, 0x80, 0x28, 0x04, 0x00, 0x80, 0x08, 0x04, 0x00, 0x80,
-0x18, 0x04, 0x00, 0x80, 0x80, 0xb4, 0x13, 0x04, 0x00, 0xd0, 0x01, 0x3a,
-0x80, 0x00, 0x0b, 0x1c, 0x13, 0x49, 0x0f, 0x58, 0xc0, 0x46, 0x3b, 0x60,
-0x0b, 0x58, 0xc0, 0x46, 0x5a, 0x60, 0x0a, 0x58, 0x08, 0x32, 0x10, 0x4b,
-0x1b, 0x58, 0x9a, 0x42, 0x01, 0xd3, 0x0f, 0x4a, 0x12, 0x58, 0x0f, 0x4b,
-0x1f, 0x58, 0x01, 0x23, 0x9b, 0x07, 0x3b, 0x43, 0x1b, 0x68, 0x9b, 0x00,
-0x17, 0x03, 0x3f, 0x0b, 0x9f, 0x42, 0x06, 0xd1, 0x0a, 0x48, 0xc1, 0x68,
-0x01, 0x31, 0xc1, 0x60, 0x01, 0x20, 0x80, 0xbc, 0x70, 0x47, 0x08, 0x4b,
-0x1b, 0x58, 0xc0, 0x46, 0x1a, 0x60, 0x0a, 0x50, 0x00, 0x20, 0xf6, 0xe7,
-0x08, 0x04, 0x00, 0x80, 0x28, 0x04, 0x00, 0x80, 0x20, 0x04, 0x00, 0x80,
-0x18, 0x04, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x10, 0x04, 0x00, 0x80,
-0xff, 0x5f, 0x2d, 0xe9, 0x48, 0xfe, 0xff, 0xeb, 0x01, 0xb6, 0xa0, 0xe3,
-0x01, 0xb1, 0x8b, 0xe2, 0x02, 0x8a, 0xa0, 0xe3, 0x01, 0x7a, 0xa0, 0xe3,
-0x01, 0xa9, 0xa0, 0xe3, 0x01, 0x56, 0xa0, 0xe3, 0xc8, 0x60, 0x9f, 0xe5,
-0xc8, 0x90, 0x9f, 0xe5, 0x14, 0x40, 0x9b, 0xe5, 0x00, 0x00, 0x54, 0xe3,
-0x2c, 0x00, 0x00, 0x0a, 0x03, 0x0a, 0x14, 0xe3, 0x11, 0x00, 0x00, 0x0a,
-0x0c, 0x00, 0x96, 0xe5, 0x00, 0x00, 0x50, 0xe3, 0x21, 0x00, 0x00, 0x0a,
-0x01, 0x0a, 0x14, 0xe3, 0x05, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5,
-0x01, 0x0a, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5,
-0x14, 0x70, 0x85, 0xe5, 0x06, 0x00, 0x00, 0xea, 0x02, 0x0a, 0x14, 0xe3,
-0x04, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5, 0x02, 0x0a, 0xc0, 0xe3,
-0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5, 0x14, 0x80, 0x85, 0xe5,
-0x01, 0x09, 0x14, 0xe3, 0x04, 0x00, 0x00, 0x0a, 0x1c, 0x00, 0x96, 0xe5,
-0x01, 0x09, 0xc0, 0xe3, 0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5,
-0x14, 0xa0, 0x85, 0xe5, 0x02, 0x00, 0x14, 0xe3, 0x40, 0x00, 0x00, 0x1b,
-0x01, 0x00, 0x14, 0xe3, 0x54, 0x00, 0x00, 0x1b, 0x02, 0x0b, 0x14, 0xe3,
-0x67, 0x00, 0x00, 0x1b, 0x01, 0x0b, 0x14, 0xe3, 0x20, 0x00, 0x00, 0x1b,
-0x18, 0x00, 0x99, 0xe5, 0x01, 0x00, 0x80, 0xe2, 0x18, 0x00, 0x89, 0xe5,
-0xd5, 0xff, 0xff, 0xea, 0x1c, 0x00, 0x96, 0xe5, 0x01, 0x0a, 0xc0, 0xe3,
-0x1c, 0x00, 0x86, 0xe5, 0x1c, 0x00, 0x85, 0xe5,
-0x14, 0x70, 0x85, 0xe5, 0xe1, 0xff, 0xff, 0xea, 0xff, 0x5f, 0xbd, 0xe8,
-0x04, 0xf0, 0x5e, 0xe2, 0x68, 0x0e, 0x00, 0x80, 0x08, 0x83, 0x20, 0x40,
-0x10, 0x10, 0x1f, 0xe5, 0x14, 0x30, 0x91, 0xe5, 0x00, 0x20, 0xc3, 0xe1,
-0x14, 0x20, 0x81, 0xe5, 0x01, 0x16, 0xa0, 0xe3, 0x0c, 0x20, 0x81, 0xe5,
-0x0b, 0x12, 0xa0, 0xe3, 0x00, 0x00, 0x81, 0xe5, 0x18, 0x10, 0x9f, 0xe5,
-0xb0, 0x24, 0xd1, 0xe1, 0x01, 0x20, 0x82, 0xe2, 0xb0, 0x24, 0xc1, 0xe1,
-0x3c, 0x20, 0x91, 0xe5, 0x00, 0x00, 0x82, 0xe1, 0x3c, 0x00, 0x81, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0xa0, 0x82, 0x20, 0x40, 0xff, 0xff, 0xff, 0xea,
-0xfe, 0xff, 0xff, 0xea, 0x01, 0x0b, 0xa0, 0xe3, 0x01, 0x16, 0xa0, 0xe3,
-0x14, 0x00, 0x81, 0xe5, 0x00, 0x1a, 0x81, 0xe1, 0x24, 0x20, 0x91, 0xe5,
-0x70, 0x00, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x24, 0x20, 0x80, 0xe5,
-0x28, 0x10, 0x91, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x28, 0x10, 0x80, 0xe5,
-0x2c, 0x20, 0x90, 0xe5, 0x01, 0x20, 0x82, 0xe2, 0x2c, 0x20, 0x80, 0xe5,
-0x3f, 0x00, 0x01, 0xe2, 0x3f, 0x00, 0x50, 0xe3, 0x1e, 0xff, 0x2f, 0x11,
-0x18, 0x00, 0x9f, 0xe5, 0x00, 0x10, 0x90, 0xe5, 0x01, 0x10, 0x81, 0xe2,
-0x00, 0x10, 0x80, 0xe5, 0x02, 0x18, 0xa0, 0xe3, 0x0b, 0x02, 0xa0, 0xe3,
-0x00, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x04, 0x00, 0x80,
-0x01, 0x06, 0xa0, 0xe3, 0x01, 0x01, 0x80, 0xe2, 0x00, 0x10, 0x90, 0xe5,
-0x01, 0x08, 0x11, 0xe3, 0x0b, 0x10, 0xa0, 0xe3, 0x02, 0x19, 0x81, 0xe2,
-0x05, 0x00, 0x00, 0x1a, 0x00, 0x20, 0x90, 0xe5, 0x42, 0x28, 0xb0, 0xe1,
-0x05, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x90, 0xe5, 0x02, 0x0c, 0x10, 0xe3,
-0x02, 0x00, 0x00, 0x0a, 0x06, 0x07, 0xa0, 0xe3, 0x4c, 0x11, 0x80, 0xe5,
-0x03, 0x00, 0x00, 0xea, 0x0c, 0x00, 0x9f, 0xe5, 0x00, 0x00, 0x00, 0x00,
-0x40, 0x10, 0x80, 0xe5, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea,
-0x00, 0x00, 0x00, 0x80, 0x01, 0x06, 0xa0, 0xe3, 0x01, 0x01, 0x80, 0xe2,
-0x00, 0x10, 0x90, 0xe5, 0x01, 0x08, 0x11, 0xe3, 0x0c, 0x10, 0xa0, 0xe3,
-0x02, 0x19, 0x81, 0xe2, 0x05, 0x00, 0x00, 0x1a, 0x00, 0x20, 0x90, 0xe5,
-0x42, 0x28, 0xb0, 0xe1, 0x05, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x90, 0xe5,
-0x02, 0x0c, 0x10, 0xe3, 0x02, 0x00, 0x00, 0x0a, 0x06, 0x07, 0xa0, 0xe3,
-0x4c, 0x11, 0x80, 0xe5, 0x03, 0x00, 0x00, 0xea, 0x4c, 0x00, 0x1f, 0xe5,
-0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x80, 0xe5, 0xff, 0xff, 0xff, 0xea,
-0xfe, 0xff, 0xff, 0xea, 0x02, 0x1b, 0xa0, 0xe3, 0x01, 0x06, 0xa0, 0xe3,
-0x14, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x21, 0x1f, 0xe5,
-0x14, 0x30, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x80, 0xe5,
-0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x14, 0x10, 0x82, 0xe5, 0x01, 0x06, 0xa0, 0xe3,
-0x1c, 0x10, 0x82, 0xe5, 0x0c, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x92, 0xe5,
-0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1,
-0xc0, 0x21, 0x1f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x82, 0xe5,
-0x01, 0x16, 0xa0, 0xe3, 0x14, 0x00, 0x82, 0xe5, 0x0c, 0x00, 0x81, 0xe5,
-0x1c, 0x00, 0x92, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x81, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0x80, 0xb5, 0x0f, 0x1c, 0x38, 0x1c, 0x00, 0xf0,
-0x17, 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x1c,
-0x00, 0xf0, 0x92, 0xf8, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x80, 0xb5, 0x0f, 0x1c, 0x38, 0x1c, 0x00, 0xf0, 0x09, 0xf8, 0x00, 0x28,
-0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x84, 0xf8, 0x00, 0x20, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb4, 0x07, 0x68, 0x3a, 0x78, 0xd2, 0x07,
-0xd2, 0x0f, 0x00, 0x24, 0x00, 0x2a, 0x03, 0xd0, 0xff, 0x22, 0x01, 0x32,
-0x42, 0x60, 0x00, 0xe0, 0x44, 0x60, 0x3a, 0x7b, 0x7b, 0x7b, 0x1b, 0x02,
-0x1a, 0x43, 0x81, 0x2a, 0x08, 0xd1, 0x01, 0x23, 0x5b, 0x02, 0x42, 0x68,
-0x1a, 0x43, 0x42, 0x60, 0x04, 0x22, 0xbf, 0x18, 0x82, 0x60, 0x00, 0xe0,
-0x84, 0x60, 0x3a, 0x7b, 0x7b, 0x7b, 0x1b, 0x02, 0x1a, 0x43, 0x08, 0x2a,
-0x06, 0xd1, 0x06, 0x23, 0x41, 0x68, 0x19, 0x43, 0x41, 0x60, 0x81, 0x68,
-0x0e, 0x31, 0x3c, 0xe0, 0xc1, 0x23, 0xdb, 0x00, 0x9a, 0x42, 0x03, 0xd1,
-0x41, 0x68, 0x24, 0x4b, 0x19, 0x43, 0x3e, 0xe0, 0x23, 0x4b, 0x9a, 0x42,
-0x04, 0xd1, 0x01, 0x23, 0x1b, 0x03, 0x41, 0x68, 0x19, 0x43, 0x36, 0xe0,
-0x13, 0x02, 0x12, 0x0a, 0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04,
-0x12, 0x0c, 0x2e, 0x3a, 0x1c, 0x4b, 0x9a, 0x42, 0x2d, 0xd8, 0x01, 0x25,
-0x42, 0x68, 0x15, 0x43, 0x45, 0x60, 0xba, 0x7b, 0xfb, 0x7b, 0x1b, 0x02,
-0x1a, 0x43, 0x18, 0x4b, 0x9a, 0x42, 0x22, 0xd1, 0xfb, 0x1d, 0x09, 0x33,
-0x44, 0xcb, 0x9b, 0x07, 0xdb, 0x0e, 0xda, 0x40, 0x5b, 0x42, 0x20, 0x33,
-0x9e, 0x40, 0x16, 0x43, 0x03, 0x2e, 0x18, 0xd1, 0x39, 0x7d, 0x7b, 0x7d,
-0x1b, 0x02, 0x19, 0x43, 0x08, 0x29, 0x07, 0xd1, 0x04, 0x21, 0x29, 0x43,
-0x41, 0x60, 0x81, 0x68, 0x16, 0x31, 0x81, 0x60, 0x01, 0x21, 0x0a, 0xe0,
-0xc1, 0x23, 0xdb, 0x00, 0x99, 0x42, 0x04, 0xd1, 0x01, 0x21, 0x89, 0x03,
-0x29, 0x43, 0x41, 0x60, 0x00, 0xe0, 0x84, 0x60, 0x00, 0x21, 0x08, 0x1c,
-0xf0, 0xbc, 0x70, 0x47, 0x02, 0x40, 0x00, 0x00, 0x81, 0x80, 0x00, 0x00,
-0xae, 0x05, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x80, 0xb4, 0x42, 0x68,
-0xd1, 0x08, 0x3f, 0xd3, 0x01, 0x68, 0x83, 0x68, 0x59, 0x18, 0x02, 0x39,
-0x8f, 0x78, 0x3f, 0x07, 0x3f, 0x0f, 0x05, 0x2f, 0x03, 0xd1, 0xda, 0x1d,
-0x0d, 0x32, 0xc2, 0x60, 0x05, 0xe0, 0xbf, 0x00, 0xdb, 0x19, 0xc3, 0x60,
-0x08, 0x23, 0x1a, 0x43, 0x42, 0x60, 0x8a, 0x78, 0x12, 0x07, 0x12, 0x0f,
-0x92, 0x00, 0x02, 0x61, 0x0a, 0x79, 0x4b, 0x79, 0x1b, 0x02, 0x1a, 0x43,
-0x13, 0x02, 0x12, 0x0a, 0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04,
-0x12, 0x0c, 0x42, 0x61, 0xca, 0x7a, 0x06, 0x2a, 0x03, 0xd1, 0x10, 0x23,
-0x42, 0x68, 0x1a, 0x43, 0x10, 0xe0, 0x11, 0x2a, 0x03, 0xd1, 0x20, 0x23,
-0x42, 0x68, 0x1a, 0x43, 0x0a, 0xe0, 0x33, 0x2a, 0x03, 0xd1, 0x40, 0x23,
-0x42, 0x68, 0x1a, 0x43, 0x04, 0xe0, 0x32, 0x2a, 0x03, 0xd1, 0x80, 0x23,
-0x42, 0x68, 0x1a, 0x43, 0x42, 0x60, 0xc9, 0x7a, 0xc0, 0x46, 0x01, 0x76,
-0x80, 0xbc, 0x70, 0x47, 0x0a, 0x78, 0xc0, 0x46, 0x02, 0x60, 0x4b, 0x78,
-0x1b, 0x02, 0x1a, 0x43, 0x02, 0x60, 0x8b, 0x78, 0x1b, 0x04, 0x1a, 0x43,
-0x02, 0x60, 0xc9, 0x78, 0x09, 0x06, 0x11, 0x43, 0x01, 0x60, 0x70, 0x47,
-0x80, 0xb5, 0x07, 0x1c, 0x48, 0x68, 0x80, 0x09, 0x26, 0xd3, 0xb8, 0x6a,
-0xc9, 0x68, 0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x02, 0x30, 0x18, 0x43,
-0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x11, 0x23, 0x9b, 0x02, 0x98, 0x42,
-0x18, 0xd1, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46,
-0x48, 0x62, 0x38, 0x6b, 0x02, 0xf0, 0xda, 0xf8, 0x38, 0x1c, 0x01, 0xf0,
-0x95, 0xfd, 0x01, 0x20, 0x07, 0x49, 0xc0, 0x46, 0xc8, 0x73, 0x07, 0x49,
-0x4a, 0x6c, 0x12, 0x18, 0x4a, 0x64, 0x06, 0x49, 0x8a, 0x6d, 0x12, 0x18,
-0x8a, 0x65, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0xfa, 0xe7,
-0x18, 0x1a, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80, 0xa4, 0x2a, 0x00, 0x80,
-0x81, 0x07, 0x19, 0xd0, 0x80, 0x08, 0x80, 0x00, 0x01, 0x23, 0x9b, 0x07,
-0x01, 0x1d, 0x18, 0x43, 0x00, 0x68, 0x19, 0x43, 0x09, 0x68, 0x02, 0x02,
-0x12, 0x0e, 0x12, 0x06, 0x00, 0x0a, 0xff, 0x23, 0x1b, 0x04, 0x18, 0x40,
-0x10, 0x43, 0x0a, 0x0a, 0x12, 0x06, 0x12, 0x0e, 0x10, 0x43, 0x09, 0x02,
-0x1b, 0x0a, 0x19, 0x40, 0x08, 0x43, 0x70, 0x47, 0x01, 0x23, 0x9b, 0x07,
-0x18, 0x43, 0x00, 0x68, 0x01, 0x06, 0x02, 0x02, 0xff, 0x23, 0x1b, 0x04,
-0x1a, 0x40, 0x11, 0x43, 0x02, 0x0a, 0x1b, 0x0a, 0x1a, 0x40, 0x11, 0x43,
-0x00, 0x0e, 0x08, 0x43, 0xed, 0xe7, 0x00, 0x00, 0xf0, 0xb5, 0x04, 0x23,
-0x81, 0x6b, 0x19, 0x40, 0x00, 0x22, 0x00, 0x29, 0x46, 0xd0, 0xc7, 0x1d,
-0x39, 0x37, 0x39, 0x7b, 0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x3f, 0xd1,
-0x01, 0x6b, 0xc0, 0x46, 0x4a, 0x65, 0xc4, 0x1d, 0x2d, 0x34, 0xcd, 0x1d,
-0x2d, 0x35, 0x00, 0x22, 0x93, 0x00, 0xe6, 0x58, 0xc0, 0x46, 0xee, 0x50,
-0x01, 0x32, 0x07, 0x2a, 0xf8, 0xd3, 0x82, 0x6a, 0xc0, 0x46, 0x4a, 0x63,
-0x82, 0x6a, 0xc0, 0x46, 0x8a, 0x62, 0x7a, 0x8b, 0xcb, 0x1d, 0x39, 0x33,
-0x5a, 0x83, 0x40, 0x6a, 0xc0, 0x46, 0x48, 0x62, 0x12, 0x48, 0x01, 0x27,
-0x42, 0x68, 0x00, 0x2a, 0x10, 0xd1, 0xc2, 0x68, 0x00, 0x2a, 0x13, 0xd1,
-0x42, 0x69, 0x00, 0x2a, 0x0d, 0xd1, 0x01, 0x61, 0xc1, 0x60, 0x01, 0x6a,
-0x02, 0x29, 0x02, 0xd3, 0x20, 0x30, 0x07, 0x71, 0x0c, 0xe0, 0x00, 0xf0,
-0x13, 0xf8, 0x09, 0xe0, 0xc2, 0x68, 0x00, 0x2a, 0x02, 0xd1, 0x01, 0x61,
-0xc1, 0x60, 0x03, 0xe0, 0x02, 0x69, 0xc0, 0x46, 0x51, 0x65, 0x01, 0x61,
-0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x10, 0x1c, 0xfa, 0xe7,
-0x6c, 0x06, 0x00, 0x80, 0x80, 0xb5, 0x1e, 0x49, 0x00, 0x22, 0xcb, 0x68,
-0x00, 0x2b, 0x34, 0xd0, 0xc8, 0x1d, 0xf9, 0x30, 0x83, 0x62, 0xcb, 0x68,
-0x9b, 0x6a, 0xc0, 0x46, 0xc3, 0x62, 0xcf, 0x69, 0x7b, 0x00, 0xdf, 0x19,
-0x7f, 0x02, 0x17, 0x4b, 0xff, 0x18, 0xff, 0x37, 0x65, 0x37, 0x83, 0x63,
-0x07, 0x63, 0xcb, 0x1d, 0xff, 0x33, 0x5a, 0x33, 0x1a, 0x72, 0xcb, 0x69,
-0x00, 0x2b, 0x01, 0xd0, 0xca, 0x61, 0x01, 0xe0, 0x01, 0x23, 0xcb, 0x61,
-0x0f, 0x1c, 0xc9, 0x68, 0x49, 0x6a, 0x09, 0x89, 0x01, 0x31, 0x41, 0x63,
-0xf8, 0x1d, 0xff, 0x30, 0x3a, 0x30, 0x42, 0x60, 0x02, 0x82, 0x82, 0x60,
-0xc2, 0x60, 0x38, 0x1c, 0x00, 0xf0, 0xce, 0xfa, 0x38, 0x6a, 0x01, 0x30,
-0x38, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0x0a, 0xf8, 0x80, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x10, 0x1c, 0xfa, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80,
-0xac, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x07, 0x1c, 0xf9, 0x1d, 0xf9, 0x31,
-0x88, 0x6a, 0xc2, 0x1d, 0x2d, 0x32, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x32,
-0x1a, 0x43, 0xc8, 0x6a, 0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x80, 0x18,
-0x82, 0x79, 0xc3, 0x79, 0x1b, 0x02, 0x1a, 0x43, 0x13, 0x02, 0x12, 0x0a,
-0x12, 0x06, 0x12, 0x0e, 0x1a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x02, 0x38,
-0x92, 0x04, 0x92, 0x0c, 0x00, 0x26, 0x25, 0x4d,
-0xec, 0x1d, 0xff, 0x34, 0x3a, 0x34, 0x00, 0x2a, 0x04, 0xd0, 0x20, 0x8a,
-0x01, 0x23, 0x9b, 0x02, 0x18, 0x43, 0x2b, 0xe0, 0x01, 0x23, 0x9b, 0x07,
-0xc2, 0x1d, 0x0d, 0x32, 0x1a, 0x43, 0x12, 0x68, 0x12, 0x04, 0x12, 0x30,
-0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x10, 0x43, 0x03, 0x1c,
-0xf8, 0x1d, 0xff, 0x30, 0x4a, 0x30, 0x82, 0x78, 0xc8, 0x6b, 0x19, 0x1c,
-0x02, 0xf0, 0x02, 0xf8, 0x00, 0x28, 0x04, 0xda, 0x20, 0x8a, 0xff, 0x23,
-0x01, 0x33, 0x18, 0x43, 0x0e, 0xe0, 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31,
-0x08, 0x60, 0x01, 0x04, 0x09, 0x0c, 0x38, 0x1c, 0x00, 0xf0, 0x1c, 0xf8,
-0x00, 0x28, 0x14, 0xd1, 0x20, 0x8a, 0x01, 0x23, 0x5b, 0x02, 0x18, 0x43,
-0x20, 0x82, 0x21, 0x8a, 0x38, 0x1c, 0x00, 0xf0, 0xa2, 0xfb, 0xe8, 0x68,
-0x01, 0x23, 0x9b, 0x07, 0x54, 0x30, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46,
-0xe8, 0x60, 0x30, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20,
-0xfa, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0xf8, 0xb5, 0x07, 0x1c,
-0xfc, 0x1d, 0xf9, 0x34, 0xa0, 0x6b, 0xa6, 0x6a, 0xc5, 0x1d, 0x0d, 0x35,
-0x38, 0x48, 0xc0, 0x6a, 0x4b, 0x00, 0x59, 0x18, 0x49, 0x01, 0x42, 0x18,
-0x01, 0x20, 0x80, 0x07, 0x10, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c,
-0x00, 0x90, 0x01, 0x23, 0x9b, 0x07, 0xd0, 0x1d, 0x05, 0x30, 0x18, 0x43,
-0x00, 0x68, 0x38, 0x1c, 0x29, 0x1c, 0x00, 0xf0, 0xc2, 0xfa, 0xa8, 0x88,
-0x41, 0x07, 0x01, 0xd0, 0x00, 0x20, 0x51, 0xe0, 0x29, 0x89, 0x09, 0x18,
-0x60, 0x6b, 0x81, 0x42, 0xf8, 0xd8, 0x69, 0x89, 0xea, 0x88, 0x89, 0x18,
-0x81, 0x42, 0xf3, 0xd8, 0x00, 0x98, 0x01, 0x28, 0x25, 0xd1, 0xe0, 0x6a,
-0xf1, 0x6b, 0x40, 0x18, 0x71, 0x6c, 0xfa, 0x1d, 0xcd, 0x32, 0x01, 0xf0,
-0x33, 0xf9, 0xfa, 0x1d, 0xff, 0x32, 0x3a, 0x32, 0xe0, 0x6a, 0x51, 0x69,
-0x40, 0x18, 0xc3, 0x1d, 0x03, 0x33, 0x00, 0x20, 0x81, 0x00, 0x5e, 0x58,
-0xc9, 0x19, 0xff, 0x31, 0x01, 0x31, 0x4e, 0x61, 0x01, 0x30, 0x04, 0x28,
-0xf6, 0xd3, 0xe0, 0x6a, 0x51, 0x69, 0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31,
-0x00, 0x20, 0x00, 0x22, 0x43, 0x00, 0xca, 0x52, 0x01, 0x30, 0x06, 0x28,
-0xfa, 0xd3, 0x29, 0x1c, 0x11, 0x4a, 0x00, 0x20, 0xff, 0xf7, 0xae, 0xfb,
-0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43, 0x01, 0x20, 0x21, 0x6b,
-0xff, 0xf7, 0xa6, 0xfb, 0x01, 0x22, 0x52, 0x04, 0x60, 0x6b, 0x02, 0x43,
-0x00, 0x20, 0xe1, 0x6a, 0xff, 0xf7, 0x9e, 0xfb, 0xa1, 0x6b, 0x08, 0x4a,
-0x01, 0x20, 0xff, 0xf7, 0x99, 0xfb, 0x03, 0x20, 0x06, 0x49, 0xc0, 0x46,
-0x48, 0x62, 0x01, 0x20, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x4c, 0x2a, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00, 0x14, 0x00, 0x0f, 0x00,
-0x6c, 0x07, 0x00, 0x80, 0xf0, 0xb5, 0x8d, 0xb0, 0x00, 0x20, 0xb5, 0x4a,
-0xd5, 0x1d, 0xf9, 0x35, 0x68, 0x62, 0x01, 0x20, 0x00, 0x05, 0xb3, 0x49,
-0xc0, 0x46, 0x08, 0x60, 0xa8, 0x6a, 0xc4, 0x1d, 0x2d, 0x34, 0xb1, 0x48,
-0xc0, 0x6a, 0xd7, 0x1d, 0xff, 0x37, 0x3a, 0x37, 0x39, 0x68, 0x4b, 0x00,
-0x59, 0x18, 0x49, 0x01, 0x40, 0x18, 0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d,
-0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x08, 0x30, 0x18, 0x43, 0x00, 0x68,
-0xc0, 0x46, 0x09, 0x90, 0xff, 0x23, 0x1b, 0x02, 0x18, 0x40, 0x00, 0x0a,
-0x0a, 0x90, 0x0a, 0x98, 0xa4, 0x4e, 0x01, 0x28, 0x59, 0xd1, 0x28, 0x6b,
-0xa2, 0x68, 0x80, 0x18, 0xa2, 0x4a, 0x21, 0x69,
-0x09, 0x04, 0x09, 0x0c, 0x01, 0xf0, 0x26, 0xf9, 0x28, 0x6b, 0x79, 0x69,
-0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20, 0x82, 0x00, 0x98, 0x4b,
-0xd3, 0x18, 0xff, 0x33, 0x01, 0x33, 0x5b, 0x69, 0xc0, 0x46, 0x8b, 0x50,
-0x01, 0x30, 0x04, 0x28, 0xf4, 0xd3, 0x00, 0x20, 0x31, 0x1c, 0x82, 0x00,
-0x56, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x04, 0xae,
-0xb3, 0x50, 0x01, 0x30, 0x03, 0x28, 0xf4, 0xd3, 0x00, 0x20, 0x08, 0x90,
-0x90, 0x49, 0x42, 0x00, 0x8b, 0x5a, 0xb2, 0x5a, 0x93, 0x42, 0x13, 0xd0,
-0x8e, 0x48, 0xc1, 0x89, 0x01, 0x31, 0xc1, 0x81, 0xb8, 0x68, 0x00, 0x28,
-0x03, 0xd1, 0x38, 0x8a, 0x10, 0x23, 0x18, 0x43, 0x71, 0xe0, 0x38, 0x8a,
-0x40, 0x23, 0x18, 0x43, 0x6d, 0xe0, 0x00, 0xf0, 0x11, 0xf9, 0x01, 0xf0,
-0x67, 0xff, 0xf5, 0xe0, 0x01, 0x30, 0x06, 0x28, 0xe3, 0xd3, 0x08, 0x98,
-0x00, 0x28, 0x0c, 0xd1, 0xb8, 0x68, 0x41, 0x1c, 0xb9, 0x60, 0x00, 0x28,
-0x03, 0xd1, 0x38, 0x8a, 0x01, 0x23, 0x18, 0x43, 0x02, 0xe0, 0x38, 0x8a,
-0x04, 0x23, 0x18, 0x43, 0x38, 0x82, 0x78, 0x68, 0x01, 0x30, 0x78, 0x60,
-0x62, 0xe0, 0x0a, 0x98, 0x02, 0x28, 0x5f, 0xd1, 0x09, 0x98, 0x40, 0x0c,
-0x73, 0xd3, 0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x01, 0x30, 0x18, 0x43,
-0x00, 0x68, 0xe1, 0x1d, 0x0d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x40, 0x18,
-0x0c, 0x38, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x21, 0x8a, 0x00, 0x6b, 0x4b,
-0xd6, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x04, 0xae,
-0xb3, 0x50, 0x01, 0x31, 0x03, 0x29, 0xf3, 0xd3, 0x00, 0x21, 0x83, 0x1e,
-0x0c, 0x93, 0x68, 0x4a, 0x16, 0x6b, 0xc0, 0x46, 0x0b, 0x96, 0x8a, 0x00,
-0x0c, 0x9b, 0x9b, 0x18, 0x0b, 0x9e, 0x9e, 0x19, 0x01, 0x23, 0x9b, 0x07,
-0x33, 0x43, 0x1b, 0x68, 0x6e, 0x46, 0xb3, 0x50, 0x01, 0x31, 0x04, 0x29,
-0xf1, 0xd3, 0x69, 0x46, 0x8b, 0x1c, 0x07, 0x93, 0x00, 0x21, 0x08, 0x91,
-0x04, 0xae, 0x4a, 0x00, 0x07, 0x9b, 0x9b, 0x5a, 0xb2, 0x5a, 0x93, 0x42,
-0x11, 0xd0, 0x58, 0x48, 0xc1, 0x89, 0x01, 0x31, 0xc1, 0x81, 0xf8, 0x68,
-0x41, 0x1c, 0xf9, 0x60, 0x00, 0x28, 0x03, 0xd1, 0x38, 0x8a, 0x20, 0x23,
-0x18, 0x43, 0x02, 0xe0, 0x38, 0x8a, 0x80, 0x23, 0x18, 0x43, 0x38, 0x82,
-0x8f, 0xe7, 0x01, 0x31, 0x06, 0x29, 0xe4, 0xd3, 0x08, 0x99, 0x00, 0x29,
-0x0d, 0xd1, 0xf9, 0x68, 0x4a, 0x1c, 0xfa, 0x60, 0x00, 0x29, 0x04, 0xd1,
-0x39, 0x8a, 0x02, 0x23, 0x19, 0x43, 0x03, 0xe0, 0x0c, 0xe0, 0x39, 0x8a,
-0x08, 0x23, 0x19, 0x43, 0x39, 0x82, 0x29, 0x6b, 0x08, 0x18, 0x01, 0x23,
-0x9b, 0x07, 0x01, 0x38, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0x20, 0x76,
-0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x11, 0x30, 0x18, 0x43, 0x00, 0x68,
-0x01, 0x06, 0x09, 0x0e, 0x00, 0xe0, 0x19, 0xe0, 0x35, 0x48, 0x2a, 0x6b,
-0xc0, 0x46, 0xea, 0x62, 0x04, 0x29, 0x4f, 0xd1, 0x01, 0x21, 0xc6, 0x1d,
-0xff, 0x36, 0x5a, 0x36, 0x31, 0x72, 0x0a, 0x99, 0x02, 0x29, 0x1e, 0xd1,
-0x09, 0x99, 0x09, 0x0e, 0x49, 0x06, 0x1a, 0xd1, 0xe1, 0x1d, 0x05, 0x31,
-0x19, 0x43, 0x09, 0x68, 0x09, 0x06, 0x09, 0x0e, 0x08, 0x39, 0x1a, 0xe0,
-0x01, 0x23, 0x9b, 0x07, 0xe0, 0x1d, 0x01, 0x30, 0x18, 0x43, 0x00, 0x68,
-0xe1, 0x1d, 0x0d, 0x31, 0x19, 0x43, 0x09, 0x68, 0x40, 0x18, 0x00, 0x04,
-0x00, 0x0c, 0xf9, 0x68, 0x4a, 0x1c, 0xfa, 0x60, 0x00, 0x29, 0xbc, 0xd1,
-0xb6, 0xe7, 0x01, 0x23, 0x9b, 0x07, 0xe1, 0x1d,
-0x05, 0x31, 0x19, 0x43, 0x09, 0x68, 0x09, 0x06, 0x09, 0x0e, 0xa1, 0x60,
-0xe8, 0x6a, 0xc0, 0x46, 0x20, 0x60, 0x20, 0x1c, 0xff, 0xf7, 0x88, 0xfc,
-0x20, 0x7e, 0x33, 0x28, 0x01, 0xd0, 0x32, 0x28, 0x11, 0xd1, 0x01, 0x21,
-0x14, 0x4c, 0xc0, 0x46, 0xf9, 0x60, 0xb9, 0x60, 0x20, 0x1c, 0x00, 0xf0,
-0x85, 0xf8, 0x28, 0x6b, 0xa9, 0x6a, 0xc0, 0x46, 0x88, 0x62, 0x20, 0x1c,
-0xff, 0xf7, 0xc0, 0xfd, 0x00, 0x28, 0x11, 0xd1, 0x0e, 0xe0, 0x00, 0x20,
-0x30, 0x72, 0x11, 0xe0, 0x33, 0x29, 0x01, 0xd0, 0x32, 0x29, 0x0d, 0xd1,
-0x07, 0x1c, 0x00, 0xf0, 0x71, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0xb0, 0xfd,
-0x00, 0x28, 0x01, 0xd1, 0x01, 0xf0, 0x70, 0xfe, 0x0d, 0xb0, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0xf0, 0x12, 0xf8, 0xf6, 0xe7, 0x00, 0x00,
-0x6c, 0x06, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0x4c, 0x2a, 0x00, 0x80,
-0xac, 0xab, 0x20, 0x40, 0x40, 0x07, 0x00, 0x80, 0x82, 0x07, 0x00, 0x80,
-0x0c, 0x2b, 0x00, 0x80, 0x6c, 0x07, 0x00, 0x80, 0xf0, 0xb5, 0x25, 0x48,
-0x41, 0x68, 0x01, 0x31, 0x41, 0x60, 0x24, 0x4f, 0xf9, 0x1d, 0xf9, 0x31,
-0x00, 0x24, 0x88, 0x6a, 0xfa, 0x68, 0xc0, 0x46, 0x94, 0x61, 0x04, 0x22,
-0xfb, 0x68, 0xc0, 0x46, 0xda, 0x60, 0x10, 0x22, 0xfb, 0x68, 0xc0, 0x46,
-0x9a, 0x61, 0xfa, 0x1d, 0xff, 0x32, 0x5a, 0x32, 0x13, 0x7a, 0x1b, 0x4a,
-0x00, 0x2b, 0x0b, 0xd0, 0x15, 0x8a, 0x2e, 0x0a, 0x36, 0x02, 0x33, 0x23,
-0x2b, 0x40, 0x9b, 0x00, 0x1e, 0x43, 0xcc, 0x23, 0x2b, 0x40, 0x9b, 0x08,
-0x33, 0x43, 0x13, 0x82, 0x12, 0x8a, 0xfb, 0x68, 0xc0, 0x46, 0xda, 0x83,
-0x4a, 0x6b, 0xfb, 0x68, 0xc0, 0x46, 0xda, 0x81, 0x0a, 0x6b, 0xc0, 0x46,
-0x82, 0x62, 0xc4, 0x62, 0xc3, 0x1d, 0x39, 0x33, 0x4a, 0x6b, 0xc0, 0x46,
-0x5a, 0x83, 0x04, 0x23, 0x02, 0x68, 0x1a, 0x43, 0x02, 0x60, 0x88, 0x6a,
-0x01, 0xf0, 0x32, 0xfa, 0xf8, 0x68, 0x01, 0x23, 0x9b, 0x07, 0x54, 0x30,
-0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xf8, 0x60, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80,
-0xac, 0x07, 0x00, 0x80, 0x80, 0xb5, 0xc1, 0x1d, 0xf9, 0x31, 0x8a, 0x6a,
-0x01, 0x23, 0x9b, 0x07, 0xd1, 0x1d, 0x45, 0x31, 0x19, 0x43, 0x09, 0x68,
-0x0b, 0x06, 0x1b, 0x0e, 0x01, 0x27, 0xc1, 0x1d, 0xff, 0x31, 0x4a, 0x31,
-0x33, 0x2b, 0x05, 0xd1, 0x8b, 0x70, 0x01, 0x1c, 0x10, 0x1c, 0x00, 0xf0,
-0x0f, 0xf8, 0x06, 0xe0, 0x32, 0x2b, 0x08, 0xd1, 0x8b, 0x70, 0x01, 0x1c,
-0x10, 0x1c, 0x00, 0xf0, 0x3c, 0xf8, 0x38, 0x1c, 0x80, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x20, 0x88, 0x70, 0xf9, 0xe7, 0x90, 0xb4, 0xca, 0x1d,
-0xf9, 0x32, 0x33, 0x27, 0xcc, 0x1d, 0xff, 0x34, 0x4a, 0x34, 0xd3, 0x6a,
-0xc0, 0x46, 0xa7, 0x70, 0xff, 0x31, 0x41, 0x31, 0x07, 0x6c, 0xc0, 0x46,
-0x4f, 0x61, 0xfb, 0x18, 0x39, 0x1c, 0x9f, 0x1e, 0x01, 0x23, 0x9b, 0x07,
-0xfc, 0x1c, 0x23, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x9b, 0x00,
-0x1b, 0x04, 0x1b, 0x0c, 0xc9, 0x18, 0x08, 0x31, 0x01, 0x64, 0x01, 0x23,
-0x9b, 0x07, 0xb9, 0x1c, 0x19, 0x43, 0x09, 0x68, 0x34, 0x30, 0x01, 0x76,
-0xf8, 0x1d, 0x01, 0x30, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0xb9, 0x1d,
-0x19, 0x43, 0xd0, 0x63, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x43,
-0xd0, 0x63, 0x90, 0xbc, 0x70, 0x47, 0xb0, 0xb5, 0xca, 0x1d, 0xf9, 0x32,
-0xc5, 0x1d, 0x2d, 0x35, 0x32, 0x20, 0xcf, 0x1d,
-0xff, 0x37, 0x4a, 0x37, 0xd3, 0x6a, 0xc0, 0x46, 0xb8, 0x70, 0xcc, 0x1d,
-0xff, 0x34, 0x3a, 0x34, 0xe8, 0x68, 0xc0, 0x46, 0x60, 0x61, 0x10, 0x30,
-0xe8, 0x60, 0x60, 0x69, 0xc0, 0x18, 0x87, 0x1e, 0x01, 0x23, 0x9b, 0x07,
-0x38, 0x1d, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0xb9, 0x1c, 0x19, 0x43,
-0xd0, 0x63, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x08, 0x43, 0xd0, 0x63,
-0xf8, 0x1d, 0x03, 0x30, 0xff, 0xf7, 0xfc, 0xfb, 0x20, 0x62, 0xf8, 0x1d,
-0x07, 0x30, 0xff, 0xf7, 0xf7, 0xfb, 0x60, 0x62, 0x00, 0x20, 0x28, 0x76,
-0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf7, 0xb5, 0x81, 0xb0, 0x01, 0x98,
-0xc7, 0x1d, 0xf9, 0x37, 0xb8, 0x6a, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d,
-0x05, 0x34, 0x23, 0x43, 0x1c, 0x68, 0xff, 0x23, 0xfe, 0x33, 0x23, 0x40,
-0x7f, 0x6b, 0x3f, 0x04, 0x3b, 0x43, 0x0b, 0x60, 0x34, 0x30, 0x1c, 0x1c,
-0x80, 0x23, 0x23, 0x40, 0x01, 0x9f, 0xff, 0x37, 0x41, 0x37, 0x00, 0x2b,
-0x3c, 0xd0, 0x0c, 0x23, 0x00, 0x93, 0x00, 0x23, 0x9d, 0x00, 0xae, 0x18,
-0x36, 0x69, 0x6d, 0x18, 0x6e, 0x61, 0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3,
-0x00, 0x23, 0x9d, 0x00, 0xae, 0x18, 0x76, 0x6a, 0x6d, 0x18, 0xae, 0x62,
-0x01, 0x33, 0x05, 0x2b, 0xf7, 0xd3, 0x01, 0x9b, 0xff, 0x33, 0x51, 0x33,
-0x9b, 0x78, 0x33, 0x2b, 0x0e, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0xc5, 0x1d,
-0x01, 0x35, 0x2b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x4b, 0x81, 0x01, 0x23,
-0x9b, 0x07, 0xc5, 0x1d, 0x0d, 0x35, 0x2b, 0x43, 0x1b, 0x68, 0x16, 0xe0,
-0x7b, 0x69, 0xc0, 0x46, 0x4b, 0x81, 0x01, 0x23, 0x9b, 0x07, 0xc5, 0x1d,
-0x0d, 0x35, 0x2b, 0x43, 0x1b, 0x68, 0x7d, 0x69, 0x5d, 0x1b, 0x01, 0x23,
-0x9b, 0x07, 0xc6, 0x1d, 0x01, 0x36, 0x33, 0x43, 0x1b, 0x68, 0xeb, 0x18,
-0x0c, 0x3b, 0x02, 0xe0, 0x00, 0x23, 0x00, 0x93, 0x4b, 0x81, 0xcb, 0x80,
-0x63, 0x09, 0x49, 0xd3, 0x01, 0x23, 0x9b, 0x07, 0xc4, 0x1d, 0x05, 0x34,
-0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x0b, 0x81, 0x01, 0x23, 0x9b, 0x07,
-0xc4, 0x1d, 0x0d, 0x34, 0x23, 0x43, 0x1b, 0x68, 0x0c, 0x89, 0x1b, 0x1b,
-0x00, 0x9c, 0x1c, 0x1b, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x30, 0x18, 0x43,
-0x00, 0x68, 0x20, 0x18, 0x88, 0x80, 0x38, 0x6a, 0x04, 0x0e, 0xff, 0x23,
-0x1b, 0x04, 0x03, 0x40, 0x1b, 0x0a, 0x1c, 0x43, 0xff, 0x23, 0x1b, 0x02,
-0x03, 0x40, 0x1b, 0x02, 0x23, 0x43, 0x00, 0x06, 0x18, 0x43, 0xc8, 0x60,
-0x78, 0x6a, 0x07, 0x0e, 0xff, 0x23, 0x1b, 0x04, 0x03, 0x40, 0x1b, 0x0a,
-0x1f, 0x43, 0xff, 0x23, 0x1b, 0x02, 0x03, 0x40, 0x1b, 0x02, 0x3b, 0x43,
-0x00, 0x06, 0x18, 0x43, 0x08, 0x61, 0xd0, 0x6b, 0xc0, 0x46, 0xc8, 0x63,
-0x90, 0x6b, 0xc0, 0x46, 0x08, 0x64, 0x50, 0x6c, 0xc0, 0x46, 0x48, 0x64,
-0x10, 0x6c, 0xc0, 0x46, 0x88, 0x64, 0xd0, 0x6c, 0xc0, 0x46, 0xc8, 0x64,
-0x90, 0x6c, 0xc0, 0x46, 0x08, 0x65, 0x02, 0xe0, 0x00, 0x23, 0x0b, 0x81,
-0x8b, 0x80, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5,
-0x0f, 0x4a, 0x93, 0x89, 0x01, 0x33, 0x93, 0x81, 0xc2, 0x1d, 0xf9, 0x32,
-0x04, 0x23, 0x90, 0x6a, 0xc0, 0x46, 0xc3, 0x60, 0x10, 0x23, 0x83, 0x61,
-0xcb, 0x0a, 0x01, 0xd3, 0x18, 0x23, 0x83, 0x61, 0xc1, 0x83, 0x51, 0x6b,
-0xc0, 0x46, 0xc1, 0x81, 0x51, 0x6b, 0xc2, 0x1d, 0x39, 0x32, 0x51, 0x83,
-0x04, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x01, 0xf0, 0xc2, 0xf8,
-0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80,
-0xb0, 0xb5, 0x1b, 0x4c, 0x20, 0x6a, 0x02, 0x28, 0x1b, 0xd2, 0x00, 0x20,
-0xe7, 0x1d, 0x19, 0x37, 0x38, 0x71, 0xe1, 0x68, 0xe0, 0x1d, 0xf9, 0x30,
-0x00, 0x29, 0x15, 0xd0, 0x42, 0x6a, 0x00, 0x2a, 0x12, 0xd1, 0x01, 0x25,
-0x0a, 0xe0, 0xff, 0xf7, 0x89, 0xfb, 0x00, 0x28, 0x09, 0xd1, 0x20, 0x6a,
-0x02, 0x28, 0x00, 0xd3, 0x3d, 0x71, 0xe0, 0x68, 0x00, 0x28, 0x02, 0xd0,
-0x38, 0x79, 0x00, 0x28, 0xf1, 0xd0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x40, 0x6a, 0x00, 0x28, 0xf9, 0xd1, 0x00, 0x29, 0xf7, 0xd1, 0x60, 0x69,
-0x00, 0x28, 0x04, 0xd0, 0x06, 0x48, 0x00, 0x68, 0x03, 0xf0, 0xa8, 0xfc,
-0xef, 0xe7, 0x60, 0x68, 0x00, 0x28, 0xec, 0xd0, 0x00, 0xf0, 0x5a, 0xf8,
-0xe9, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0x34, 0x04, 0x00, 0x80,
-0xb0, 0xb5, 0x07, 0x1c, 0x20, 0x23, 0xb8, 0x68, 0x18, 0x40, 0x01, 0x24,
-0x00, 0x25, 0x00, 0x28, 0x0b, 0xd1, 0x38, 0x6a, 0x00, 0x28, 0x03, 0xd1,
-0x28, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x1f, 0x48, 0x01, 0x6e,
-0x01, 0x31, 0x01, 0x66, 0x03, 0xe0, 0x48, 0x68, 0xc4, 0x23, 0x18, 0x40,
-0x03, 0xd1, 0x38, 0x6a, 0x00, 0xf0, 0x0c, 0xfc, 0x2f, 0xe0, 0x38, 0x1c,
-0x00, 0xf0, 0x1c, 0xfc, 0x38, 0x1c, 0x00, 0xf0, 0x7b, 0xfa, 0xb8, 0x68,
-0xc0, 0x08, 0x02, 0xd3, 0x38, 0x6a, 0x00, 0xf0, 0xd1, 0xfb, 0xb8, 0x68,
-0x39, 0x6a, 0xc0, 0x46, 0x88, 0x60, 0x38, 0x6a, 0xc0, 0x46, 0xc5, 0x60,
-0x10, 0x48, 0x41, 0x68, 0x00, 0x29, 0x11, 0xd1, 0xc1, 0x68, 0x00, 0x29,
-0x09, 0xd1, 0x41, 0x69, 0x00, 0x29, 0x06, 0xd1, 0x39, 0x6a, 0xc0, 0x46,
-0x81, 0x60, 0x41, 0x60, 0x00, 0xf0, 0x14, 0xf8, 0x0b, 0xe0, 0x39, 0x6a,
-0xc0, 0x46, 0x81, 0x60, 0x41, 0x60, 0x06, 0xe0, 0x39, 0x6a, 0x82, 0x68,
-0xc0, 0x46, 0xd1, 0x60, 0x39, 0x6a, 0xc0, 0x46, 0x81, 0x60, 0x20, 0x1c,
-0xbd, 0xe7, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80,
-0x90, 0xb5, 0x0b, 0x4c, 0x67, 0x68, 0x00, 0x2f, 0x0f, 0xd0, 0x38, 0x1c,
-0x00, 0xf0, 0x12, 0xf8, 0x00, 0x28, 0x0a, 0xd1, 0x60, 0x68, 0xc0, 0x68,
-0xc0, 0x46, 0x60, 0x60, 0x38, 0x1c, 0x00, 0xf0, 0xc3, 0xfb, 0x00, 0x20,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 0xfa, 0xe7, 0x00, 0x00,
-0x6c, 0x06, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c, 0xfe, 0x1d, 0x49, 0x36,
-0x30, 0x78, 0x40, 0x00, 0xc0, 0x19, 0x85, 0x8b, 0x33, 0x4c, 0x34, 0x4b,
-0x9d, 0x42, 0x3c, 0xd0, 0x38, 0x1c, 0x21, 0x1c, 0x2a, 0x1c, 0x00, 0xf0,
-0x1d, 0xf9, 0x31, 0x48, 0x80, 0x6a, 0x58, 0x21, 0x69, 0x43, 0x40, 0x18,
-0x01, 0x23, 0x9b, 0x07, 0x18, 0x43, 0x00, 0x68, 0x00, 0x04, 0x00, 0x0c,
-0x2c, 0x4d, 0x01, 0x28, 0x1a, 0xd1, 0x30, 0x78, 0xc0, 0x19, 0xc1, 0x1d,
-0x19, 0x31, 0x08, 0x7a, 0x3a, 0x68, 0x80, 0x18, 0x09, 0x7b, 0xea, 0x1d,
-0x21, 0x32, 0x00, 0xf0, 0xe3, 0xfc, 0x30, 0x78, 0xc0, 0x19, 0x20, 0x30,
-0x00, 0x79, 0x39, 0x68, 0x40, 0x18, 0xc1, 0x1d, 0x05, 0x31, 0x00, 0x20,
-0x00, 0x23, 0x42, 0x00, 0x8b, 0x52, 0x01, 0x30, 0x06, 0x28, 0xfa, 0xd3,
-0xa0, 0x88, 0x41, 0x07, 0x0b, 0xd1, 0x21, 0x89, 0x09, 0x18, 0x78, 0x68,
-0x00, 0x04, 0x00, 0x0c, 0x81, 0x42, 0x04, 0xd8, 0x61, 0x89, 0xe2, 0x88,
-0x89, 0x18, 0x81, 0x42, 0x03, 0xd9, 0x00, 0x20, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x21, 0x1c, 0x14, 0x4a, 0x00, 0x20, 0xfe, 0xf7, 0x5a, 0xff,
-0x01, 0x22, 0x52, 0x04, 0x78, 0x68, 0x02, 0x43,
-0x01, 0x20, 0x39, 0x68, 0xfe, 0xf7, 0x52, 0xff, 0x01, 0x22, 0x52, 0x04,
-0x78, 0x68, 0x02, 0x43, 0x00, 0x20, 0x39, 0x68, 0xfe, 0xf7, 0x4a, 0xff,
-0x0b, 0x49, 0x0c, 0x4a, 0x01, 0x20, 0xfe, 0xf7, 0x45, 0xff, 0x01, 0x20,
-0xe9, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x02, 0x21, 0xea, 0x1d, 0xf9, 0x32,
-0x51, 0x62, 0xd9, 0xe7, 0x28, 0xac, 0x20, 0x40, 0xff, 0xff, 0x00, 0x00,
-0x4c, 0x2a, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, 0x54, 0x00, 0x03, 0x00,
-0x14, 0xac, 0x20, 0x40, 0x14, 0x00, 0x07, 0x00, 0xf0, 0xb5, 0x83, 0xb0,
-0x00, 0x21, 0x4f, 0x48, 0xc2, 0x1d, 0xf9, 0x32, 0x51, 0x62, 0x01, 0x21,
-0xc9, 0x04, 0x4d, 0x4a, 0xc0, 0x46, 0x11, 0x60, 0xc1, 0x1d, 0x19, 0x31,
-0x49, 0x79, 0x00, 0x29, 0x04, 0xd1, 0x4a, 0x48, 0x00, 0x68, 0x03, 0xf0,
-0x9b, 0xfb, 0x87, 0xe0, 0x45, 0x48, 0x47, 0x68, 0xfc, 0x1d, 0x49, 0x34,
-0x21, 0x78, 0x48, 0x00, 0xc0, 0x19, 0x80, 0x8b, 0x44, 0x4a, 0x92, 0x6a,
-0x58, 0x23, 0x58, 0x43, 0x15, 0x18, 0x01, 0x23, 0x9b, 0x07, 0xea, 0x1d,
-0x05, 0x32, 0x1a, 0x43, 0x12, 0x68, 0x08, 0x35, 0x2b, 0x43, 0x1d, 0x68,
-0xff, 0x23, 0x1b, 0x02, 0x2b, 0x40, 0x1b, 0x0a, 0x3c, 0x4d, 0x01, 0x2b,
-0x24, 0xd1, 0xc8, 0x19, 0xc1, 0x1d, 0x19, 0x31, 0x08, 0x7a, 0x3a, 0x68,
-0x80, 0x18, 0x39, 0x4a, 0x09, 0x7b, 0x00, 0xf0, 0xc5, 0xfc, 0x20, 0x78,
-0xc0, 0x19, 0x20, 0x30, 0x00, 0x79, 0x39, 0x68, 0x41, 0x18, 0x00, 0x20,
-0x82, 0x00, 0x53, 0x19, 0x9b, 0x6e, 0x6e, 0x46, 0xb3, 0x50, 0x01, 0x30,
-0x03, 0x28, 0xf7, 0xd3, 0xca, 0x1d, 0x05, 0x32, 0x69, 0x46, 0x00, 0x20,
-0x43, 0x00, 0xcd, 0x5a, 0xc0, 0x46, 0xd5, 0x52, 0x01, 0x30, 0x06, 0x28,
-0xf8, 0xd3, 0x2d, 0xe0, 0x02, 0x2b, 0x2b, 0xd1, 0x11, 0x0a, 0x29, 0xd3,
-0x00, 0x21, 0x8a, 0x00, 0x53, 0x19, 0x9b, 0x6e, 0x6e, 0x46, 0xb3, 0x50,
-0x01, 0x31, 0x03, 0x29, 0xf7, 0xd3, 0x21, 0x78, 0x49, 0x00, 0xc9, 0x19,
-0x09, 0x8f, 0x3a, 0x68, 0x8b, 0x18, 0x6a, 0x46, 0x00, 0x21, 0x4d, 0x00,
-0x56, 0x5b, 0xc0, 0x46, 0x5e, 0x53, 0x01, 0x31, 0x06, 0x29, 0xf8, 0xd3,
-0x19, 0x49, 0x8a, 0x6a, 0x13, 0x18, 0x1a, 0x6d, 0x00, 0x9d, 0x55, 0x40,
-0x19, 0x4a, 0xd6, 0x68, 0x75, 0x40, 0x1d, 0x65, 0x89, 0x6a, 0x08, 0x18,
-0x41, 0x6d, 0x02, 0x9b, 0x59, 0x40, 0x92, 0x69, 0x51, 0x40, 0x41, 0x65,
-0x20, 0x78, 0x41, 0x1e, 0x21, 0x70, 0x00, 0x28, 0x0d, 0xd0, 0x38, 0x1c,
-0xff, 0xf7, 0xf4, 0xfe, 0x00, 0x28, 0x0d, 0xd1, 0x08, 0x4a, 0x50, 0x68,
-0xc0, 0x68, 0xc0, 0x46, 0x50, 0x60, 0x38, 0x1c, 0x00, 0xf0, 0xa4, 0xfa,
-0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0, 0x73, 0xfa, 0x01, 0xf0, 0xde, 0xfa,
-0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x6c, 0x06, 0x00, 0x80,
-0x00, 0x00, 0x00, 0xb0, 0x38, 0x04, 0x00, 0x80, 0x4c, 0x2a, 0x00, 0x80,
-0xac, 0xab, 0x20, 0x40, 0x94, 0x06, 0x00, 0x80, 0x08, 0x83, 0x20, 0x40,
-0xf0, 0xb5, 0x82, 0xb0, 0x69, 0x4b, 0x9f, 0x6a, 0x58, 0x23, 0x5a, 0x43,
-0xba, 0x18, 0xc3, 0x1d, 0x49, 0x33, 0x1f, 0x78, 0x01, 0x23, 0x9b, 0x07,
-0xd4, 0x1d, 0x01, 0x34, 0x23, 0x43, 0x1d, 0x68, 0x43, 0x68, 0x1c, 0x04,
-0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x05, 0x36, 0x33, 0x43, 0x1b, 0x68,
-0x1c, 0x43, 0x42, 0x23, 0x1c, 0x43, 0x0c, 0x60, 0xff, 0x26, 0x36, 0x02,
-0x2e, 0x40, 0x01, 0x23, 0x5b, 0x02, 0x9e, 0x42, 0x74, 0xd1, 0x6b, 0x0c,
-0x2b, 0xd3, 0xc3, 0x19, 0x20, 0x33, 0x1b, 0x79,
-0xc0, 0x46, 0x4b, 0x81, 0x7b, 0x00, 0x1b, 0x18, 0x1b, 0x8f, 0x4c, 0x89,
-0x1b, 0x1b, 0xcb, 0x80, 0x00, 0x24, 0xa6, 0x00, 0x01, 0x96, 0xb3, 0x18,
-0xde, 0x1d, 0x09, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68,
-0x01, 0x9e, 0x76, 0x18, 0x73, 0x61, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3,
-0x00, 0x24, 0xa6, 0x00, 0x00, 0x96, 0xb3, 0x18, 0xde, 0x1d, 0x1d, 0x36,
-0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x00, 0x9e, 0x76, 0x18,
-0xb3, 0x62, 0x01, 0x34, 0x05, 0x2c, 0xf0, 0xd3, 0x06, 0xe0, 0x00, 0x23,
-0x4b, 0x81, 0xcb, 0x80, 0x40, 0x23, 0x9c, 0x43, 0x0c, 0x60, 0x23, 0x1c,
-0x6b, 0x0e, 0x4a, 0xd3, 0xc3, 0x19, 0x20, 0x33, 0x1b, 0x79, 0x10, 0x33,
-0x0b, 0x81, 0x7b, 0x00, 0x1b, 0x18, 0x1b, 0x8f, 0x0f, 0x89, 0xdb, 0x1b,
-0x8b, 0x80, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x35, 0x34, 0x23, 0x43,
-0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x63, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d,
-0x31, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x0b, 0x64, 0xab, 0x0e,
-0x21, 0xd2, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x3d, 0x34, 0x23, 0x43,
-0x1b, 0x68, 0xc0, 0x46, 0x4b, 0x64, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d,
-0x39, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0x8b, 0x64, 0x01, 0x23,
-0x9b, 0x07, 0xd4, 0x1d, 0x45, 0x34, 0x23, 0x43, 0x1b, 0x68, 0xc0, 0x46,
-0xcb, 0x64, 0x01, 0x23, 0x9b, 0x07, 0xd4, 0x1d, 0x41, 0x34, 0x23, 0x43,
-0x1b, 0x68, 0xc0, 0x46, 0x0b, 0x65, 0x00, 0xe0, 0x0f, 0xe0, 0xfb, 0x1f,
-0x01, 0x3b, 0x1b, 0x04, 0x1b, 0x0c, 0x07, 0x68, 0xff, 0x18, 0x03, 0x69,
-0x08, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x34, 0xf8, 0x2c, 0xe0, 0x00, 0x23,
-0x0b, 0x81, 0x8b, 0x80, 0x28, 0xe0, 0x00, 0x23, 0x8b, 0x80, 0x0b, 0x81,
-0xc3, 0x19, 0x20, 0x33, 0x1b, 0x7a, 0xc0, 0x46, 0x4b, 0x81, 0x7b, 0x00,
-0x18, 0x18, 0x00, 0x8e, 0xc0, 0x46, 0xc8, 0x80, 0x00, 0x20, 0x87, 0x00,
-0xbb, 0x18, 0xdc, 0x1d, 0x09, 0x34, 0x01, 0x23, 0x9b, 0x07, 0x23, 0x43,
-0x1b, 0x68, 0x7f, 0x18, 0x7b, 0x61, 0x01, 0x30, 0x05, 0x28, 0xf2, 0xd3,
-0x00, 0x20, 0x87, 0x00, 0xbb, 0x18, 0xdc, 0x1d, 0x1d, 0x34, 0x01, 0x23,
-0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x7f, 0x18, 0xbb, 0x62, 0x01, 0x30,
-0x05, 0x28, 0xf2, 0xd3, 0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x4c, 0x2a, 0x00, 0x80, 0x80, 0xb4, 0x1f, 0x1c, 0x3b, 0x0c, 0x18, 0xd2,
-0x17, 0x6d, 0x11, 0x4b, 0xc0, 0x46, 0xdf, 0x60, 0x52, 0x6d, 0xc0, 0x46,
-0x1a, 0x61, 0xc7, 0x60, 0x1a, 0x69, 0xc0, 0x46, 0x02, 0x61, 0xd8, 0x68,
-0xc0, 0x46, 0x08, 0x80, 0xd8, 0x68, 0x00, 0x0c, 0x48, 0x80, 0x18, 0x69,
-0xc0, 0x46, 0x88, 0x80, 0x18, 0x69, 0x00, 0x0c, 0xc8, 0x80, 0x80, 0xbc,
-0x70, 0x47, 0x4a, 0x88, 0x12, 0x04, 0x0b, 0x88, 0x1a, 0x43, 0xc2, 0x60,
-0x8a, 0x88, 0xc9, 0x88, 0x09, 0x04, 0x11, 0x43, 0x01, 0x61, 0xf2, 0xe7,
-0x2c, 0x07, 0x00, 0x80, 0xf1, 0xb5, 0x88, 0xb0, 0x00, 0x22, 0x08, 0x98,
-0x00, 0x6a, 0x08, 0x9b, 0x99, 0x68, 0x49, 0x0a, 0x02, 0xd3, 0x01, 0x27,
-0xff, 0x03, 0x00, 0xe0, 0x00, 0x27, 0x03, 0x8b, 0x00, 0x2b, 0x19, 0xd0,
-0xa3, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, 0x63, 0x43, 0xc9, 0x18,
-0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, 0x19, 0x43, 0x09, 0x68, 0x09, 0x04,
-0x09, 0x0c, 0x02, 0x29, 0x02, 0xd1, 0x08, 0x23, 0x1f, 0x43, 0x07, 0xe0,
-0x41, 0x8b, 0x00, 0x29, 0x02, 0xd0, 0x0c, 0x23,
-0x1f, 0x43, 0x01, 0xe0, 0x04, 0x23, 0x1f, 0x43, 0x83, 0x8a, 0x00, 0x2b,
-0x18, 0xd0, 0x95, 0x49, 0x89, 0x6a, 0x1c, 0x1c, 0x58, 0x23, 0x63, 0x43,
-0xc9, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x58, 0x39, 0x19, 0x43, 0x09, 0x68,
-0x09, 0x04, 0x09, 0x0c, 0x02, 0x29, 0x01, 0xd1, 0x0f, 0x43, 0x07, 0xe0,
-0xc1, 0x8a, 0x00, 0x29, 0x02, 0xd0, 0x03, 0x23, 0x1f, 0x43, 0x01, 0xe0,
-0x01, 0x23, 0x1f, 0x43, 0xc1, 0x1d, 0x39, 0x31, 0x07, 0x91, 0x4b, 0x89,
-0x0c, 0x89, 0x1c, 0x19, 0x24, 0x04, 0x24, 0x0c, 0x08, 0x9d, 0x2d, 0x68,
-0xc0, 0x46, 0x01, 0x95, 0xc9, 0x88, 0x7d, 0x08, 0x1a, 0xd3, 0x1a, 0x1c,
-0xc3, 0x1d, 0x19, 0x33, 0x1a, 0x72, 0x07, 0x9a, 0x92, 0x89, 0xc0, 0x46,
-0x1a, 0x73, 0x07, 0x9a, 0x12, 0x89, 0xc0, 0x46, 0x02, 0x86, 0x04, 0x87,
-0x82, 0x8a, 0x01, 0x3a, 0x82, 0x83, 0x01, 0x22, 0x19, 0x71, 0x08, 0x9b,
-0x1b, 0x68, 0x5b, 0x18, 0x5b, 0x78, 0x9b, 0x00, 0x1b, 0x04, 0x1b, 0x0c,
-0x08, 0x33, 0x59, 0x18, 0xbb, 0x08, 0x47, 0xd3, 0x07, 0x9b, 0x5b, 0x89,
-0x85, 0x18, 0x06, 0x95, 0x20, 0x35, 0x2b, 0x72, 0x07, 0x9b, 0x9b, 0x89,
-0xc0, 0x46, 0x2b, 0x73, 0x07, 0x9b, 0x1b, 0x89, 0x2e, 0x1c, 0x55, 0x00,
-0x2d, 0x18, 0x05, 0x95, 0x2b, 0x86, 0x00, 0x2a, 0x01, 0xd0, 0xc3, 0x8a,
-0x00, 0xe0, 0x83, 0x8a, 0x01, 0x3b, 0x05, 0x9d, 0xc0, 0x46, 0xab, 0x83,
-0x31, 0x71, 0x65, 0x4b, 0x9d, 0x6a, 0x05, 0x9b, 0x9e, 0x8b, 0x58, 0x23,
-0x73, 0x43, 0xeb, 0x18, 0xdd, 0x1d, 0x01, 0x35, 0x01, 0x23, 0x9b, 0x07,
-0x2b, 0x43, 0x1d, 0x68, 0x2b, 0x0e, 0x5b, 0x06, 0x01, 0xd1, 0x08, 0x31,
-0x00, 0xe0, 0x10, 0x31, 0x81, 0x23, 0x5b, 0x02, 0x1d, 0x40, 0x9d, 0x42,
-0x03, 0xd1, 0xe3, 0x1f, 0x05, 0x3b, 0x1c, 0x04, 0x24, 0x0c, 0x05, 0x9b,
-0xc0, 0x46, 0x1c, 0x87, 0x08, 0x9b, 0x1b, 0x68, 0x1b, 0x19, 0x10, 0x3b,
-0x9b, 0x7b, 0x06, 0x9d, 0x40, 0x35, 0x2b, 0x70, 0x2b, 0x78, 0x02, 0x33,
-0xe3, 0x1a, 0x1c, 0x04, 0x24, 0x0c, 0x01, 0x32, 0xbb, 0x08, 0x9b, 0x07,
-0x6d, 0xd0, 0x83, 0x18, 0x20, 0x33, 0x04, 0x93, 0x19, 0x72, 0x01, 0x9b,
-0x5d, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1b, 0x68, 0x1b, 0x07,
-0x1b, 0x0f, 0x9b, 0x00, 0x04, 0x9e, 0xc0, 0x46, 0x33, 0x73, 0x00, 0x95,
-0x2b, 0x78, 0x1b, 0x07, 0x1b, 0x0f, 0x9b, 0x00, 0x04, 0x9d, 0xc0, 0x46,
-0x2b, 0x73, 0x00, 0x9d, 0xeb, 0x78, 0xad, 0x78, 0x1b, 0x02, 0x1d, 0x43,
-0x2b, 0x02, 0x2d, 0x0a, 0x2d, 0x06, 0x2d, 0x0e, 0x2b, 0x43, 0x55, 0x00,
-0x2d, 0x18, 0x2b, 0x86, 0x04, 0x9b, 0xc0, 0x46, 0x59, 0x72, 0x04, 0x9b,
-0x1b, 0x7b, 0x2e, 0x1c, 0x04, 0x9d, 0xc0, 0x46, 0x6b, 0x73, 0x33, 0x8e,
-0xc0, 0x46, 0x73, 0x86, 0x00, 0x9d, 0x2b, 0x78, 0x1b, 0x07, 0x1b, 0x0f,
-0x9b, 0x00, 0x1b, 0x04, 0x1b, 0x0c, 0x59, 0x18, 0x04, 0x25, 0x3d, 0x40,
-0x0e, 0xd0, 0x34, 0x87, 0x03, 0x8b, 0x01, 0x3b, 0xb3, 0x83, 0x13, 0x1c,
-0x1b, 0x18, 0x20, 0x33, 0x19, 0x71, 0x01, 0x9b, 0x5b, 0x18, 0x5b, 0x78,
-0x9b, 0x00, 0x59, 0x18, 0x08, 0x31, 0x01, 0x32, 0x3b, 0x09, 0x37, 0xd3,
-0x00, 0x2d, 0x01, 0xd0, 0x43, 0x8b, 0x00, 0xe0, 0x03, 0x8b, 0x55, 0x00,
-0x2d, 0x18, 0x01, 0x3b, 0xab, 0x83, 0x83, 0x18, 0x03, 0x93, 0x20, 0x33,
-0x19, 0x71, 0x20, 0x4b, 0x9d, 0x6a, 0x53, 0x00, 0x1b, 0x18, 0x02, 0x93,
-0x9e, 0x8b, 0x58, 0x23, 0x73, 0x43, 0xeb, 0x18, 0xdd, 0x1d, 0x01, 0x35,
-0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43, 0x1d, 0x68,
-0x2b, 0x0e, 0x5b, 0x06, 0x02, 0xd1, 0x08, 0x31, 0x01, 0xe0, 0x15, 0xe0,
-0x10, 0x31, 0x81, 0x23, 0x5b, 0x02, 0x1d, 0x40, 0x9d, 0x42, 0x03, 0xd1,
-0xe3, 0x1f, 0x05, 0x3b, 0x1c, 0x04, 0x24, 0x0c, 0x02, 0x9b, 0xc0, 0x46,
-0x1c, 0x87, 0x08, 0x9b, 0x1b, 0x68, 0x1b, 0x19, 0x10, 0x3b, 0x9b, 0x7b,
-0x03, 0x9c, 0x40, 0x34, 0x23, 0x70, 0x01, 0x32, 0x07, 0x9b, 0xc0, 0x46,
-0xd9, 0x80, 0x51, 0x1e, 0xc3, 0x1d, 0x49, 0x33, 0x19, 0x70, 0x07, 0x61,
-0x04, 0x2a, 0x06, 0xd2, 0x06, 0x49, 0x53, 0x00, 0x1b, 0x18, 0x99, 0x83,
-0x01, 0x32, 0x04, 0x2a, 0xf9, 0xd3, 0x09, 0xb0, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00,
-0x70, 0x47, 0x80, 0xb5, 0x8c, 0xb0, 0x07, 0x1c, 0x12, 0x48, 0x01, 0x68,
-0x01, 0x31, 0x01, 0x60, 0x38, 0x68, 0xc0, 0x46, 0x00, 0x90, 0x78, 0x68,
-0xc0, 0x46, 0x01, 0x90, 0xb8, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x0d, 0x48,
-0x41, 0x68, 0xc9, 0x68, 0xc0, 0x46, 0x41, 0x60, 0x38, 0x1c, 0x00, 0xf0,
-0x4f, 0xf8, 0xb8, 0x68, 0x40, 0x09, 0x06, 0xd3, 0x10, 0x23, 0x02, 0x98,
-0x18, 0x43, 0x02, 0x90, 0x68, 0x46, 0x02, 0xf0, 0xe1, 0xff, 0x68, 0x46,
-0x02, 0xf0, 0x9a, 0xfe, 0x0c, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x0c, 0x2b, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80, 0x00, 0xb5, 0x8c, 0xb0,
-0x01, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x68, 0x05, 0x4b, 0x19, 0x43,
-0x01, 0x91, 0x00, 0xf0, 0x2f, 0xf8, 0x68, 0x46, 0x02, 0xf0, 0x84, 0xfe,
-0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
-0x02, 0x6a, 0x03, 0x68, 0xc0, 0x46, 0x13, 0x60, 0x40, 0x68, 0xc0, 0x46,
-0x50, 0x60, 0x40, 0x32, 0x48, 0x68, 0xc0, 0x46, 0x90, 0x80, 0xc8, 0x68,
-0xc0, 0x46, 0xd0, 0x80, 0x48, 0x69, 0xc0, 0x46, 0x10, 0x81, 0x88, 0x68,
-0xc0, 0x46, 0x50, 0x81, 0x08, 0x7e, 0xc0, 0x46, 0x90, 0x73, 0x08, 0x69,
-0xc0, 0x46, 0x90, 0x81, 0x70, 0x47, 0x04, 0x49, 0x08, 0x68, 0x00, 0x28,
-0x00, 0xd1, 0x70, 0x47, 0xc2, 0x68, 0xc0, 0x46, 0x0a, 0x60, 0xfa, 0xe7,
-0x6c, 0x06, 0x00, 0x80, 0x02, 0x49, 0x0a, 0x68, 0xc0, 0x46, 0xc2, 0x60,
-0x08, 0x60, 0x70, 0x47, 0x6c, 0x06, 0x00, 0x80, 0xb0, 0xb4, 0x00, 0x22,
-0x12, 0x4f, 0x7c, 0x7f, 0x01, 0x34, 0x7c, 0x77, 0x03, 0x23, 0xfc, 0x1d,
-0x19, 0x34, 0x38, 0x62, 0x79, 0x62, 0x23, 0x72, 0x0e, 0x4c, 0x25, 0x68,
-0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68, 0x1b, 0x0c, 0x10, 0xd1, 0x24, 0x68,
-0xa3, 0x0a, 0x0d, 0xd3, 0x01, 0x23, 0x0a, 0x4f, 0xc0, 0x46, 0xfb, 0x62,
-0x09, 0x4f, 0x0a, 0x4b, 0xc0, 0x46, 0xdf, 0x60, 0x99, 0x60, 0x58, 0x60,
-0x10, 0x1c, 0x18, 0x60, 0x01, 0x32, 0xfb, 0xe7, 0x10, 0x1c, 0x38, 0x64,
-0x01, 0x32, 0xfb, 0xe7, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40,
-0xc0, 0x00, 0x18, 0x00, 0x02, 0x81, 0x00, 0x00, 0x40, 0x01, 0x18, 0x00,
-0xf0, 0xb5, 0x47, 0x4f, 0x38, 0x68, 0x47, 0x4e, 0x47, 0x4d, 0x07, 0x23,
-0x5b, 0x02, 0xec, 0x18, 0x00, 0x28, 0x1d, 0xd1, 0x20, 0x6b, 0x01, 0x30,
-0x20, 0x63, 0x44, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x43, 0x48, 0x41, 0x69,
-0x00, 0x29, 0x13, 0xd0, 0xc1, 0x1d, 0x69, 0x31, 0x09, 0x7b, 0x00, 0x29,
-0x0e, 0xd0, 0x01, 0x23, 0x9b, 0x07, 0x01, 0x6d, 0x19, 0x43, 0x09, 0x68,
-0xc0, 0x46, 0x81, 0x61, 0xc2, 0x69, 0x91, 0x42, 0x04, 0xd0, 0xf1, 0x6c,
-0x01, 0x31, 0xf1, 0x64, 0x01, 0xf0, 0x50, 0xfe,
-0x38, 0x68, 0x01, 0x28, 0x17, 0xd1, 0x37, 0x48, 0x41, 0x69, 0x00, 0x29,
-0x13, 0xd0, 0xc1, 0x1d, 0x69, 0x31, 0x09, 0x7b, 0x00, 0x29, 0x0e, 0xd0,
-0x01, 0x23, 0x9b, 0x07, 0x01, 0x6d, 0x19, 0x43, 0x09, 0x68, 0xc0, 0x46,
-0x81, 0x61, 0xc2, 0x69, 0x91, 0x42, 0x04, 0xd0, 0xf1, 0x6c, 0x01, 0x31,
-0xf1, 0x64, 0x01, 0xf0, 0x35, 0xfe, 0x38, 0x68, 0x02, 0x28, 0x2f, 0xd1,
-0xbb, 0x23, 0x1b, 0x01, 0xee, 0x18, 0x70, 0x7b, 0x00, 0x28, 0x03, 0xd0,
-0x00, 0x20, 0x70, 0x73, 0x00, 0xf0, 0x4a, 0xfd, 0x30, 0x7b, 0x00, 0x28,
-0x02, 0xd0, 0x78, 0x68, 0x02, 0xf0, 0xaa, 0xff, 0x1b, 0x23, 0xdb, 0x01,
-0xe8, 0x18, 0xc0, 0x8b, 0x04, 0x26, 0x06, 0x40, 0xe0, 0x6a, 0xb0, 0x42,
-0x14, 0xd0, 0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 0x19, 0x28, 0x11, 0xd3,
-0x1b, 0x48, 0x01, 0x7b, 0x00, 0x29, 0x0d, 0xd1, 0xff, 0x30, 0x41, 0x30,
-0x40, 0x78, 0x00, 0x28, 0x08, 0xd1, 0xb8, 0x68, 0x02, 0xf0, 0x90, 0xff,
-0x00, 0x20, 0xf8, 0x60, 0xe6, 0x62, 0x01, 0xe0, 0x00, 0x20, 0xf8, 0x60,
-0x38, 0x68, 0x03, 0x28, 0x0b, 0xd1, 0xec, 0x1d, 0x79, 0x34, 0xe0, 0x6b,
-0x80, 0x08, 0x02, 0xd3, 0x02, 0x20, 0x02, 0xf0, 0x07, 0xfc, 0x02, 0x23,
-0xe0, 0x6b, 0x98, 0x43, 0xe0, 0x63, 0x38, 0x68, 0x01, 0x30, 0x38, 0x60,
-0x03, 0x28, 0x01, 0xd9, 0x00, 0x20, 0x38, 0x60, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x3c, 0x04, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0x40, 0x01, 0x18, 0x00, 0x64, 0x2d, 0x00, 0x80,
-0xe4, 0x2c, 0x00, 0x80, 0x28, 0x05, 0x00, 0x80, 0xb0, 0xb4, 0x1d, 0x48,
-0x84, 0x8a, 0x1d, 0x4a, 0x13, 0x8a, 0xc1, 0x1d, 0x09, 0x31, 0x01, 0x27,
-0x9c, 0x42, 0x03, 0xd1, 0x43, 0x8a, 0x54, 0x8a, 0xa3, 0x42, 0x10, 0xd0,
-0x0b, 0x78, 0x00, 0x2b, 0x0d, 0xd0, 0x4b, 0x78, 0x00, 0x2b, 0x0a, 0xd0,
-0x44, 0x8b, 0x93, 0x8a, 0x9c, 0x42, 0x04, 0xdc, 0x13, 0x4b, 0xc0, 0x46,
-0x5f, 0x60, 0x97, 0x82, 0x01, 0xe0, 0x01, 0x33, 0x93, 0x82, 0xc3, 0x8b,
-0x5c, 0x1c, 0xc4, 0x83, 0x84, 0x8b, 0xa3, 0x42, 0x0e, 0xdb, 0x84, 0x8a,
-0x05, 0x8b, 0x00, 0x23, 0xac, 0x42, 0x05, 0xda, 0x44, 0x8a, 0xc5, 0x8a,
-0xac, 0x42, 0x01, 0xda, 0x4b, 0x70, 0x00, 0xe0, 0x4f, 0x70, 0x43, 0x82,
-0x83, 0x82, 0xc3, 0x83, 0x41, 0x8a, 0xc0, 0x46, 0x51, 0x82, 0x80, 0x8a,
-0xc0, 0x46, 0x10, 0x82, 0xb0, 0xbc, 0x70, 0x47, 0xe8, 0x0e, 0x00, 0x80,
-0x3c, 0x04, 0x00, 0x80, 0x40, 0x01, 0x18, 0x00, 0xf7, 0xb5, 0x91, 0xb0,
-0x6b, 0x46, 0x84, 0x1e, 0x12, 0x99, 0x14, 0x29, 0x1a, 0xd9, 0x00, 0x20,
-0x81, 0x00, 0x67, 0x58, 0xc0, 0x46, 0x57, 0x50, 0x01, 0x30, 0x00, 0x06,
-0x00, 0x0e, 0x10, 0x28, 0xf6, 0xd3, 0x00, 0x21, 0x05, 0x20, 0x87, 0x00,
-0xd6, 0x59, 0x4f, 0x1c, 0x3d, 0x06, 0x2d, 0x0e, 0x0f, 0x1c, 0xbf, 0x00,
-0xde, 0x51, 0x29, 0x1c, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0x28,
-0xf1, 0xd3, 0x09, 0xe0, 0x00, 0x20, 0x81, 0x00, 0x63, 0x58, 0xc0, 0x46,
-0x53, 0x50, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x06, 0x28, 0xf6, 0xd3,
-0x00, 0x20, 0xe0, 0x70, 0x20, 0x72, 0x60, 0x72, 0xa0, 0x72, 0x20, 0x73,
-0x60, 0x73, 0x12, 0x99, 0x14, 0x29, 0x37, 0xd9, 0x69, 0x46, 0x8e, 0x1c,
-0x91, 0x78, 0x09, 0x07, 0x09, 0x0f, 0x89, 0x00, 0x14, 0x39, 0x0d, 0x06,
-0x2d, 0x16, 0x00, 0x27, 0x00, 0x2d, 0x1b, 0xdd, 0xf0, 0x19, 0x10, 0xa9,
-0x00, 0xf0, 0x3d, 0xf8, 0x00, 0x28, 0x0e, 0xd0,
-0x00, 0x20, 0x10, 0xa9, 0x09, 0x78, 0x00, 0x29, 0x09, 0xdd, 0x00, 0x22,
-0x39, 0x18, 0x72, 0x54, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x10, 0xa9,
-0x09, 0x78, 0x88, 0x42, 0xf6, 0xdb, 0x10, 0xa8, 0x00, 0x78, 0x38, 0x18,
-0x07, 0x06, 0x3f, 0x0e, 0xaf, 0x42, 0xe3, 0xdb, 0x68, 0x46, 0xe2, 0x1d,
-0x0d, 0x32, 0x00, 0x21, 0xab, 0x08, 0x5f, 0x1c, 0x08, 0xd0, 0x8b, 0x00,
-0xc4, 0x58, 0xc0, 0x46, 0xd4, 0x50, 0x01, 0x31, 0x09, 0x06, 0x09, 0x0e,
-0x8f, 0x42, 0xf6, 0xd8, 0x14, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x90, 0xb4, 0x87, 0x1e, 0x00, 0x20, 0x89, 0x08, 0x4b, 0x1c, 0x08, 0xd0,
-0x81, 0x00, 0x54, 0x58, 0xc0, 0x46, 0x7c, 0x50, 0x01, 0x30, 0x00, 0x06,
-0x00, 0x0e, 0x83, 0x42, 0xf6, 0xd8, 0x90, 0xbc, 0x70, 0x47, 0x80, 0xb4,
-0x02, 0x78, 0xd2, 0x06, 0xd2, 0x0e, 0x00, 0x23, 0x01, 0x27, 0x01, 0x2a,
-0x01, 0xdc, 0x0f, 0x70, 0x11, 0xe0, 0x40, 0x78, 0xc0, 0x46, 0x08, 0x70,
-0x14, 0x2a, 0x04, 0xd1, 0x08, 0x48, 0x01, 0x7a, 0x01, 0x31, 0x01, 0x72,
-0x07, 0xe0, 0x02, 0x2a, 0x05, 0xd0, 0x05, 0x2a, 0x03, 0xd0, 0x06, 0x2a,
-0x01, 0xd0, 0x15, 0x2a, 0x02, 0xd1, 0x18, 0x1c, 0x80, 0xbc, 0x70, 0x47,
-0x38, 0x1c, 0xfb, 0xe7, 0xe0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x0f, 0x48,
-0x01, 0x23, 0x1b, 0x06, 0x41, 0x69, 0x99, 0x43, 0x1a, 0x09, 0x41, 0x61,
-0xd1, 0x60, 0x00, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x91, 0x61, 0x19, 0x1c,
-0x09, 0x4a, 0xc0, 0x46, 0x11, 0x60, 0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18,
-0x80, 0x69, 0x00, 0x28, 0x03, 0xd0, 0x02, 0xf0, 0x61, 0xfe, 0x08, 0xbc,
-0x18, 0x47, 0x04, 0x48, 0x41, 0x88, 0x01, 0x31, 0x41, 0x80, 0xf8, 0xe7,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0, 0xe0, 0x82, 0x20, 0x40,
-0x70, 0x47, 0x00, 0x00, 0xf0, 0xb5, 0x86, 0xb0, 0x95, 0x4a, 0xd0, 0x68,
-0xd7, 0x1d, 0x79, 0x37, 0x01, 0x28, 0x09, 0xd1, 0x38, 0x89, 0x00, 0x28,
-0x06, 0xd1, 0xd0, 0x6f, 0x02, 0x23, 0x01, 0x68, 0x99, 0x43, 0x01, 0x60,
-0x14, 0x20, 0x38, 0x81, 0x8e, 0x4c, 0x61, 0x6a, 0x8e, 0x48, 0xc3, 0x6b,
-0x59, 0x18, 0xc1, 0x63, 0xa0, 0x6a, 0x19, 0x23, 0xdb, 0x01, 0xd4, 0x18,
-0xa0, 0x62, 0x21, 0x6a, 0x09, 0x03, 0x09, 0x0b, 0x81, 0x42, 0x05, 0xd1,
-0x01, 0x20, 0x40, 0x04, 0x87, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xf3, 0xe0,
-0xbb, 0x8a, 0x58, 0x1c, 0xb8, 0x82, 0x3d, 0x8b, 0x01, 0x20, 0x00, 0x21,
-0xab, 0x42, 0x04, 0xdb, 0xd3, 0x1d, 0x89, 0x33, 0x58, 0x70, 0xb9, 0x82,
-0xf9, 0x83, 0x33, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x05, 0x93, 0x5b, 0x69,
-0x0f, 0x2b, 0x73, 0xd2, 0x00, 0x21, 0x7c, 0x4f, 0xc0, 0x46, 0x39, 0x61,
-0x21, 0x6a, 0x8a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x4b, 0x68, 0x1e, 0x0c,
-0x36, 0x04, 0xfd, 0x1f, 0x09, 0x3d, 0x00, 0x2e, 0x05, 0xd1, 0x3b, 0x2a,
-0x03, 0xd3, 0x01, 0x23, 0xdb, 0x02, 0x9a, 0x42, 0x01, 0xd9, 0xa8, 0x73,
-0xc8, 0xe0, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x31, 0x19, 0x43, 0x09, 0x68,
-0xc0, 0x46, 0x03, 0x91, 0x03, 0xa9, 0x09, 0x88, 0x01, 0x31, 0x09, 0x04,
-0x09, 0x0c, 0x79, 0x82, 0x49, 0x09, 0x05, 0x31, 0x09, 0x06, 0x09, 0x0e,
-0x69, 0x4e, 0xc0, 0x46, 0x02, 0x96, 0x69, 0x48, 0x43, 0x6a, 0xc0, 0x46,
-0x01, 0x93, 0x83, 0x6a, 0xc0, 0x46, 0x00, 0x93, 0xc2, 0x1d, 0x11, 0x32,
-0x80, 0x69, 0x00, 0x03, 0x00, 0x0b, 0x92, 0x68, 0xb3, 0x07, 0x1a, 0x43,
-0x12, 0x68, 0x90, 0x42, 0x01, 0xd1, 0x01, 0x20,
-0x0d, 0xe0, 0x90, 0x42, 0x05, 0xd9, 0x00, 0x9b, 0x18, 0x1a, 0x01, 0x9b,
-0xd2, 0x1a, 0x82, 0x18, 0x00, 0xe0, 0x12, 0x1a, 0x01, 0x20, 0x09, 0x01,
-0x91, 0x42, 0x00, 0xd3, 0x00, 0x20, 0x01, 0x28, 0x65, 0xd1, 0x51, 0x49,
-0x20, 0x69, 0x00, 0x28, 0x62, 0xd0, 0x05, 0x99, 0x48, 0x69, 0x01, 0x30,
-0x48, 0x61, 0x02, 0x20, 0x21, 0x6a, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0,
-0xa7, 0xfc, 0x78, 0x63, 0xbe, 0x60, 0x49, 0x49, 0x22, 0x6a, 0xa3, 0x6b,
-0xd3, 0x18, 0x66, 0x6b, 0xb3, 0x42, 0x00, 0xd9, 0x22, 0x6b, 0xc0, 0x46,
-0xba, 0x62, 0xba, 0x6a, 0x0c, 0x32, 0xfa, 0x62, 0x00, 0x22, 0xfa, 0x61,
-0x03, 0xaa, 0x52, 0x88, 0xd2, 0x09, 0x03, 0xd3, 0x01, 0x22, 0x00, 0xe0,
-0x7b, 0xe0, 0x00, 0xe0, 0x00, 0x22, 0x7a, 0x60, 0x7a, 0x68, 0xc0, 0x46,
-0x02, 0x60, 0x78, 0x8a, 0x41, 0x4e, 0x60, 0x28, 0x04, 0xdc, 0xb0, 0x83,
-0x78, 0x8a, 0xc0, 0x46, 0xf0, 0x83, 0x08, 0xe0, 0x60, 0x20, 0xb0, 0x83,
-0x79, 0x8a, 0xf8, 0x6a, 0x42, 0x18, 0x63, 0x6b, 0x9a, 0x42, 0x03, 0xd8,
-0xf1, 0x83, 0x00, 0x22, 0x3a, 0x63, 0x05, 0xe0, 0x21, 0x6b, 0xc0, 0x46,
-0x39, 0x63, 0x61, 0x6b, 0x08, 0x1a, 0xf0, 0x83, 0x2d, 0x49, 0x78, 0x6b,
-0x42, 0x68, 0xc0, 0x46, 0xba, 0x60, 0x82, 0x68, 0xc0, 0x46, 0xfa, 0x60,
-0x02, 0x69, 0xc0, 0x46, 0x7a, 0x61, 0x40, 0x69, 0xc0, 0x46, 0xb8, 0x61,
-0x2e, 0x4b, 0xc8, 0x18, 0x04, 0x90, 0x00, 0xf0, 0x37, 0xf9, 0x04, 0x98,
-0x00, 0xf0, 0x88, 0xf8, 0x00, 0xf0, 0xf6, 0xfa, 0x78, 0x8a, 0xf1, 0x8b,
-0x88, 0x42, 0x04, 0xd1, 0xf9, 0x6a, 0x08, 0x18, 0x04, 0xe0, 0x38, 0xe0,
-0x32, 0xe0, 0x3a, 0x6b, 0x10, 0x18, 0x40, 0x1a, 0x81, 0x07, 0x02, 0xd0,
-0x80, 0x08, 0x80, 0x00, 0x04, 0x30, 0x61, 0x6b, 0x09, 0x1a, 0xa2, 0x6b,
-0x91, 0x42, 0x00, 0xd2, 0x20, 0x6b, 0xc0, 0x46, 0x20, 0x62, 0xe8, 0x7b,
-0x00, 0x28, 0x08, 0xd0, 0x00, 0x22, 0xea, 0x73, 0x05, 0x99, 0x48, 0x69,
-0x01, 0x38, 0x48, 0x61, 0x78, 0x6b, 0x00, 0xf0, 0x73, 0xfa, 0x18, 0x48,
-0x80, 0x6a, 0x80, 0x06, 0x80, 0x0e, 0x01, 0x28, 0x0a, 0xd1, 0x20, 0x6a,
-0x00, 0x03, 0x00, 0x0b, 0x0b, 0x4c, 0xa1, 0x6a, 0x88, 0x42, 0x03, 0xd0,
-0x06, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x20, 0x40, 0x04,
-0x08, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x06, 0xe0, 0xe0, 0x68, 0x00, 0x28,
-0x01, 0xd0, 0x00, 0xf0, 0xb5, 0xfa, 0x01, 0x20, 0xa8, 0x73, 0xed, 0xe7,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0x40, 0x14, 0x40, 0xa4, 0x2a, 0x00, 0x80,
-0x00, 0x00, 0x00, 0xb0, 0x28, 0x1a, 0x00, 0x80, 0x55, 0x55, 0x55, 0x55,
-0xa8, 0x03, 0x00, 0x80, 0x68, 0x1a, 0x00, 0x80, 0xc4, 0x0b, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x40, 0x80, 0xb5, 0x07, 0x1c, 0x78, 0x6a, 0x40, 0x89,
-0xff, 0x21, 0x01, 0x31, 0x01, 0x40, 0x10, 0x48, 0x02, 0xd1, 0x81, 0x6c,
-0x01, 0x31, 0x81, 0x64, 0x79, 0x6a, 0x49, 0x89, 0x49, 0x0b, 0x02, 0xd2,
-0x41, 0x6c, 0x01, 0x31, 0x41, 0x64, 0x0b, 0x48, 0x41, 0x6a, 0x01, 0x31,
-0x41, 0x62, 0x78, 0x6a, 0x39, 0x6b, 0xc0, 0x46, 0x48, 0x62, 0x38, 0x6b,
-0x00, 0xf0, 0xf8, 0xfb, 0x38, 0x1c, 0x00, 0xf0, 0xb3, 0xf8, 0x01, 0x20,
-0x04, 0x49, 0xc0, 0x46, 0xc8, 0x73, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0xa4, 0x2a, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x18, 0x1a, 0x00, 0x80,
-0xf8, 0xb5, 0x07, 0x1c, 0x00, 0x22, 0xf9, 0x1d, 0x61, 0x31, 0x0d, 0x1c,
-0x78, 0x6a, 0xc0, 0x46, 0x00, 0x90, 0x40, 0x89,
-0x03, 0x0c, 0x01, 0xd2, 0x40, 0x0a, 0x03, 0xd2, 0x38, 0x1c, 0xff, 0xf7,
-0xc1, 0xff, 0x67, 0xe0, 0x35, 0x48, 0xc0, 0x6b, 0x00, 0x09, 0x1f, 0xd3,
-0x08, 0x78, 0x40, 0x08, 0x1c, 0xd2, 0x00, 0x20, 0x43, 0x00, 0xcc, 0x5a,
-0x31, 0x4e, 0x9e, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xf3, 0x18, 0x1b, 0x88,
-0x9c, 0x42, 0x0e, 0xd0, 0xb8, 0x69, 0x39, 0x6b, 0xc0, 0x46, 0x88, 0x61,
-0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 0x38, 0x1c, 0x00, 0xf0,
-0x27, 0xf9, 0x38, 0x1c, 0x00, 0xf0, 0x74, 0xf8, 0x46, 0xe0, 0x01, 0x30,
-0x03, 0x28, 0xe3, 0xdb, 0x02, 0x20, 0x43, 0x00, 0x5c, 0x18, 0xe4, 0x88,
-0x22, 0x4e, 0x9e, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xf3, 0x18, 0x1b, 0x88,
-0x9c, 0x42, 0x03, 0xd1, 0x01, 0x23, 0x01, 0x38, 0xd8, 0x42, 0xf0, 0xdc,
-0x01, 0x23, 0xd8, 0x42, 0xc4, 0xd0, 0x1b, 0x4e, 0x0b, 0x23, 0x1b, 0x02,
-0xf0, 0x18, 0x40, 0x69, 0x00, 0x28, 0x24, 0xd0, 0x7d, 0x63, 0x00, 0x98,
-0x40, 0x89, 0x00, 0x0c, 0x1f, 0xd2, 0x00, 0x24, 0x2d, 0x23, 0x9b, 0x01,
-0xf0, 0x18, 0xc0, 0x6b, 0x35, 0x1c, 0x00, 0x28, 0x17, 0xd0, 0xfe, 0x1d,
-0x2d, 0x36, 0xa2, 0x00, 0x52, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xd2, 0x18,
-0xd2, 0x6b, 0x38, 0x1c, 0x31, 0x1c, 0x02, 0xf0, 0x7b, 0xfc, 0x01, 0x28,
-0x0e, 0xd0, 0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, 0x2d, 0x23, 0x9b, 0x01,
-0xc0, 0x18, 0xc0, 0x6b, 0x00, 0x28, 0xea, 0xd1, 0x01, 0xe0, 0x01, 0x2a,
-0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x08, 0xf8, 0xf8, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80,
-0x80, 0xb5, 0x07, 0x1c, 0xb8, 0x69, 0x39, 0x6b, 0xc0, 0x46, 0x88, 0x61,
-0xf8, 0x68, 0x39, 0x6b, 0xc0, 0x46, 0xc8, 0x60, 0x78, 0x6a, 0x40, 0x89,
-0x01, 0x0c, 0x0e, 0xd2, 0x40, 0x0a, 0x0c, 0xd3, 0x38, 0x68, 0x40, 0x08,
-0x02, 0xd3, 0x38, 0x1c, 0x02, 0xf0, 0x0c, 0xfc, 0x38, 0x1c, 0x00, 0xf0,
-0xbb, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0x08, 0xf8, 0x02, 0xe0, 0x38, 0x1c,
-0xff, 0xf7, 0x30, 0xff, 0x01, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x01, 0x21, 0x00, 0x6b, 0x40, 0x6a, 0xc0, 0x46, 0x01, 0x60, 0x70, 0x47,
-0xb0, 0xb4, 0xc1, 0x1d, 0x39, 0x31, 0x09, 0x8b, 0x89, 0x08, 0x09, 0x04,
-0x09, 0x0c, 0x84, 0x6a, 0xc2, 0x1d, 0x61, 0x32, 0x00, 0x20, 0x00, 0x29,
-0x0c, 0xdd, 0x87, 0x00, 0x3d, 0x19, 0x01, 0x23, 0x9b, 0x07, 0x2b, 0x43,
-0x1b, 0x68, 0xc0, 0x46, 0xd3, 0x51, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c,
-0x88, 0x42, 0xf2, 0xdb, 0xb0, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0xa0, 0xb0,
-0x01, 0x23, 0x9b, 0x07, 0xc1, 0x1d, 0x21, 0x31, 0x19, 0x43, 0x09, 0x68,
-0xc0, 0x46, 0x0b, 0x91, 0xc1, 0x1d, 0x53, 0x31, 0x19, 0x43, 0x1f, 0x91,
-0x09, 0x68, 0x01, 0xaf, 0xfa, 0x1d, 0x39, 0x32, 0x1e, 0x92, 0x17, 0xab,
-0x59, 0x80, 0x3a, 0x49, 0x01, 0x23, 0x9b, 0x07, 0x0a, 0x6a, 0x13, 0x43,
-0xcc, 0x1d, 0x11, 0x34, 0x89, 0x69, 0x09, 0x03, 0x09, 0x0b, 0x22, 0x69,
-0xe5, 0x68, 0xc0, 0x46, 0x1d, 0x95, 0xfc, 0x1d, 0x39, 0x34, 0x64, 0x8b,
-0x64, 0x09, 0x05, 0x34, 0x24, 0x06, 0x24, 0x0e, 0x1c, 0x94, 0x56, 0x1a,
-0x1b, 0x96, 0x1c, 0x9c, 0x2e, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x26,
-0x1d, 0x9d, 0x1a, 0x68, 0x91, 0x42, 0x01, 0xd1, 0x32, 0x1c, 0x0b, 0xe0,
-0x91, 0x42, 0x03, 0xd9, 0x52, 0x1b, 0x1b, 0x9e, 0xb5, 0x18, 0x00, 0xe0,
-0x55, 0x1a, 0x01, 0x22, 0x24, 0x01, 0xac, 0x42,
-0x00, 0xd3, 0x00, 0x22, 0x01, 0x2a, 0xe6, 0xd1, 0x91, 0x07, 0x01, 0x43,
-0x09, 0x68, 0xc0, 0x46, 0x39, 0x60, 0x93, 0x07, 0x01, 0x1d, 0x19, 0x43,
-0x09, 0x68, 0xc0, 0x46, 0x79, 0x60, 0xc1, 0x1d, 0x01, 0x31, 0x19, 0x43,
-0x09, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0x1f, 0x99, 0x09, 0x68, 0x1e, 0x9a,
-0xc0, 0x46, 0x51, 0x83, 0xc1, 0x1d, 0x1d, 0x31, 0x19, 0x43, 0x09, 0x68,
-0xc0, 0x46, 0x38, 0x63, 0x79, 0x62, 0xc1, 0x1d, 0x11, 0x31, 0x19, 0x43,
-0x09, 0x68, 0xc0, 0x46, 0xb9, 0x61, 0xc1, 0x1d, 0x05, 0x31, 0x19, 0x43,
-0x09, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0xc1, 0x1d, 0x17, 0x31, 0x19, 0x43,
-0x09, 0x68, 0xc0, 0x46, 0xf9, 0x83, 0x0e, 0x30, 0x18, 0x43, 0x00, 0x68,
-0xc0, 0x46, 0xf8, 0x81, 0x38, 0x68, 0x40, 0x08, 0x02, 0xd3, 0x38, 0x1c,
-0x02, 0xf0, 0x5c, 0xfb, 0x38, 0x1c, 0x00, 0xf0, 0x0b, 0xf8, 0x38, 0x1c,
-0xff, 0xf7, 0x58, 0xff, 0x20, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0xa8, 0x03, 0x00, 0x80, 0x55, 0x55, 0x55, 0x55, 0xf8, 0xb5, 0x07, 0x1c,
-0xf8, 0x1d, 0x39, 0x30, 0x41, 0x8b, 0x39, 0x4a, 0x91, 0x42, 0x00, 0xdd,
-0x42, 0x83, 0x42, 0x8b, 0xc0, 0x46, 0x00, 0x92, 0x01, 0x20, 0x3a, 0x1d,
-0x06, 0xca, 0xbb, 0x6a, 0x02, 0xf0, 0x0e, 0xff, 0x33, 0x4a, 0xc0, 0x46,
-0x00, 0x92, 0x33, 0x4e, 0x30, 0x6a, 0x33, 0x4c, 0xe1, 0x6d, 0x41, 0x18,
-0x38, 0x6b, 0xc3, 0x1d, 0x05, 0x33, 0x01, 0x20, 0x72, 0x6a, 0x02, 0xf0,
-0xfb, 0xfe, 0xe0, 0x6d, 0x18, 0x30, 0x00, 0x25, 0xb1, 0x6a, 0x81, 0x42,
-0x01, 0xd8, 0xe5, 0x65, 0x00, 0xe0, 0xe0, 0x65, 0x2f, 0x23, 0x9b, 0x01,
-0x20, 0x1c, 0xe1, 0x6d, 0xe4, 0x18, 0x22, 0x68, 0x92, 0x00, 0x27, 0x4b,
-0xc0, 0x46, 0x99, 0x50, 0x26, 0x48, 0xc1, 0x6b, 0x4a, 0x08, 0x05, 0xd3,
-0x49, 0x08, 0x49, 0x00, 0xc1, 0x63, 0x01, 0x20, 0x01, 0xf0, 0xd6, 0xff,
-0x22, 0x4a, 0x1f, 0x48, 0xc1, 0x1d, 0x89, 0x31, 0x0b, 0x78, 0x00, 0x2b,
-0x02, 0xd0, 0x49, 0x78, 0x00, 0x29, 0x00, 0xd1, 0x1e, 0x4a, 0xc0, 0x46,
-0x00, 0x92, 0x20, 0x68, 0x80, 0x00, 0x19, 0x4b, 0xc3, 0x18, 0x05, 0xce,
-0xc1, 0x1d, 0x11, 0x31, 0x01, 0x20, 0x02, 0xf0, 0xc7, 0xfe, 0x14, 0x48,
-0x21, 0x68, 0x01, 0x31, 0x21, 0x60, 0x17, 0x29, 0x00, 0xd3, 0x25, 0x60,
-0x39, 0x6b, 0xc0, 0x46, 0x0d, 0x65, 0x79, 0x6a, 0x3a, 0x6b, 0xc0, 0x46,
-0x51, 0x62, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x81, 0x68, 0x00, 0x29,
-0x03, 0xd1, 0x39, 0x6b, 0xc0, 0x46, 0x81, 0x60, 0x04, 0xe0, 0x39, 0x6b,
-0xc2, 0x68, 0xc0, 0x46, 0x11, 0x65, 0x39, 0x6b, 0xc0, 0x46, 0xc1, 0x60,
-0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xea, 0x05, 0x00, 0x00,
-0x18, 0x00, 0x14, 0x02, 0x7c, 0x29, 0x00, 0x80, 0x68, 0x0e, 0x00, 0x80,
-0x44, 0x82, 0x20, 0x40, 0xe8, 0x0e, 0x00, 0x80, 0x04, 0x00, 0x00, 0x02,
-0x04, 0x00, 0x00, 0x03, 0xf0, 0xb5, 0x11, 0x4e, 0xff, 0x25, 0x01, 0x35,
-0x10, 0x4f, 0xc0, 0x46, 0x35, 0x60, 0x78, 0x69, 0x01, 0x38, 0x78, 0x61,
-0xbc, 0x68, 0x00, 0x2c, 0x10, 0xd0, 0x20, 0x6d, 0xc0, 0x46, 0xb8, 0x60,
-0x20, 0x1c, 0x00, 0xf0, 0x21, 0xf8, 0x20, 0x1c, 0x00, 0xf0, 0x04, 0xfa,
-0x08, 0x48, 0x80, 0x6a, 0x00, 0x0c, 0x00, 0x07, 0xe9, 0xd1, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x05, 0x48, 0xc1, 0x79, 0x01, 0x31, 0xc1, 0x71,
-0xf7, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x28, 0x1b, 0x00, 0x80,
-0x00, 0x00, 0x10, 0x40, 0xa0, 0x82, 0x20, 0x40,
-0x01, 0x20, 0x80, 0x03, 0x01, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x70, 0x47,
-0x00, 0x00, 0x00, 0xb0, 0x90, 0xb5, 0x07, 0x1c, 0x38, 0x68, 0xc0, 0x08,
-0x09, 0xd3, 0x1d, 0x48, 0x01, 0x6a, 0x01, 0x39, 0x01, 0x62, 0x20, 0x30,
-0x00, 0x79, 0x00, 0x28, 0x01, 0xd0, 0xfe, 0xf7, 0xe9, 0xfd, 0x01, 0x23,
-0x9b, 0x07, 0xf8, 0x1d, 0x1d, 0x30, 0x18, 0x43, 0x00, 0x68, 0x16, 0x4c,
-0x61, 0x6a, 0x81, 0x42, 0x21, 0xd1, 0x01, 0x1c, 0x19, 0x43, 0x09, 0x68,
-0x09, 0x04, 0x09, 0x0c, 0x01, 0x29, 0x1a, 0xd1, 0x00, 0xf0, 0x22, 0xf8,
-0x60, 0x62, 0x60, 0x6a, 0x21, 0x6a, 0x88, 0x42, 0x05, 0xd0, 0x01, 0x21,
-0x89, 0x07, 0x01, 0x43, 0x09, 0x68, 0x09, 0x04, 0xf2, 0xd0, 0x51, 0x21,
-0x89, 0x03, 0x62, 0x6a, 0x23, 0x6b, 0x9a, 0x42, 0x02, 0xd1, 0x60, 0x6b,
-0xa2, 0x6b, 0x80, 0x1a, 0x04, 0x38, 0xc8, 0x60, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x20, 0x79, 0x6a, 0xc0, 0x46, 0x08, 0x60, 0xf7, 0xe7,
-0x6c, 0x06, 0x00, 0x80, 0xe8, 0x1a, 0x00, 0x80, 0x01, 0x23, 0x9b, 0x07,
-0xc1, 0x1d, 0x01, 0x31, 0x19, 0x43, 0x09, 0x68, 0x09, 0x04, 0x09, 0x0c,
-0x08, 0x18, 0x0d, 0x30, 0x81, 0x07, 0x02, 0xd0, 0x80, 0x08, 0x80, 0x00,
-0x04, 0x30, 0x04, 0x49, 0x8a, 0x6b, 0x12, 0x18, 0x4b, 0x6b, 0x9a, 0x42,
-0x00, 0xd9, 0x08, 0x6b, 0x70, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80,
-0x00, 0xb5, 0x04, 0x48, 0xc0, 0x68, 0x10, 0x28, 0x01, 0xd3, 0x00, 0xf0,
-0x05, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80,
-0x88, 0xb5, 0x0c, 0x4f, 0x38, 0x79, 0x00, 0x28, 0x11, 0xd1, 0x0b, 0x49,
-0x10, 0x20, 0x02, 0xf0, 0xf5, 0xfd, 0x00, 0x28, 0x0b, 0xd0, 0x01, 0x20,
-0x38, 0x71, 0x08, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x07, 0x48, 0x42, 0x68,
-0x07, 0x4b, 0x01, 0x68, 0x00, 0x20, 0x02, 0xf0, 0xdf, 0xfd, 0x88, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0xf8, 0x1a, 0x00, 0x80, 0xf5, 0x2c, 0xff, 0xff,
-0x10, 0x00, 0x35, 0x02, 0x7c, 0x29, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40,
-0x90, 0xb5, 0x01, 0x20, 0x40, 0x02, 0x10, 0x49, 0xc0, 0x46, 0x08, 0x60,
-0x0f, 0x4f, 0x10, 0x21, 0xf8, 0x1d, 0x3d, 0x30, 0x02, 0xf0, 0x4c, 0xfc,
-0x19, 0x23, 0xdb, 0x01, 0xfc, 0x18, 0xe0, 0x68, 0x00, 0x28, 0x01, 0xd0,
-0x00, 0xf0, 0x14, 0xf8, 0x00, 0x20, 0xc9, 0x23, 0x1b, 0x01, 0xf9, 0x18,
-0x08, 0x71, 0xe0, 0x68, 0x10, 0x28, 0x04, 0xd3, 0x01, 0x20, 0xbb, 0x23,
-0x1b, 0x01, 0xf9, 0x18, 0x48, 0x73, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80, 0xf8, 0xb5, 0x37, 0x48,
-0x19, 0x23, 0xdb, 0x01, 0xc1, 0x18, 0xc9, 0x68, 0x35, 0x4d, 0x10, 0x29,
-0x00, 0xd9, 0x10, 0x21, 0x69, 0x62, 0x32, 0x48, 0xc1, 0x6c, 0x00, 0x6e,
-0x81, 0x42, 0x07, 0xd9, 0x08, 0x1a, 0x07, 0x09, 0x00, 0x24, 0x68, 0x6a,
-0xb8, 0x42, 0x12, 0xd2, 0x07, 0x1c, 0x10, 0xe0, 0x81, 0x42, 0x2a, 0xd2,
-0x2c, 0x4a, 0x52, 0x6b, 0x10, 0x1a, 0x07, 0x09, 0x68, 0x6a, 0xb8, 0x42,
-0x05, 0xd9, 0x0c, 0x09, 0x39, 0x19, 0x88, 0x42, 0x03, 0xd2, 0xc4, 0x1b,
-0x01, 0xe0, 0x00, 0x24, 0x07, 0x1c, 0x3e, 0x19, 0x30, 0x01, 0x25, 0x49,
-0x02, 0xf0, 0x84, 0xfd, 0x00, 0x28, 0x3d, 0xd0, 0x23, 0x48, 0x00, 0x2c,
-0x1a, 0xd1, 0x1e, 0x49, 0x3a, 0x01, 0x6f, 0x62, 0x09, 0x6e, 0x8c, 0x18,
-0x1d, 0x4d, 0x6b, 0x6b, 0xa3, 0x42, 0x00, 0xd8, 0xe4, 0x1a, 0x1e, 0x4b,
-0x1a, 0x43, 0x00, 0x92, 0xea, 0x6a, 0x51, 0x18,
-0x2a, 0x6b, 0x03, 0x1c, 0x20, 0xe0, 0x1b, 0x48, 0x01, 0x6b, 0x01, 0x31,
-0x01, 0x63, 0x00, 0x20, 0x68, 0x62, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x10, 0x49, 0x24, 0x01, 0x3f, 0x01, 0x11, 0x22, 0x52, 0x05, 0x3a, 0x43,
-0x6e, 0x62, 0x00, 0x92, 0x0e, 0x4d, 0xea, 0x6a, 0x09, 0x6e, 0x51, 0x18,
-0x03, 0x1c, 0x06, 0x1c, 0x00, 0x20, 0x2a, 0x6b, 0x02, 0xf0, 0x4a, 0xfd,
-0x0c, 0x4a, 0x22, 0x43, 0x00, 0x92, 0xbb, 0x19, 0xe9, 0x6a, 0x2a, 0x6b,
-0x00, 0x20, 0x02, 0xf0, 0x41, 0xfd, 0x03, 0x48, 0xc0, 0x46, 0x04, 0x66,
-0x00, 0xf0, 0x10, 0xf8, 0x01, 0x20, 0xda, 0xe7, 0x68, 0x0e, 0x00, 0x80,
-0x28, 0x1b, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80, 0x5d, 0x2e, 0xff, 0xff,
-0x44, 0x80, 0x20, 0x40, 0x00, 0x00, 0x36, 0x02, 0xa0, 0x82, 0x20, 0x40,
-0x04, 0x48, 0x01, 0x6e, 0x04, 0x4a, 0x80, 0x30, 0xd1, 0x60, 0x02, 0x23,
-0xc1, 0x6b, 0x19, 0x43, 0xc1, 0x63, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0x90, 0xee, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, 0x01, 0x20, 0x80, 0x02,
-0x1c, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0x27, 0x1b, 0x4e, 0x33, 0x23,
-0x9b, 0x01, 0xf5, 0x18, 0x68, 0x6a, 0x00, 0x28, 0x1d, 0xd9, 0x19, 0x4c,
-0x68, 0x46, 0x10, 0x21, 0x02, 0xf0, 0x90, 0xfb, 0x68, 0x46, 0x00, 0xf0,
-0x33, 0xf8, 0x00, 0x28, 0x04, 0xd0, 0x15, 0x49, 0x48, 0x69, 0x01, 0x30,
-0x48, 0x61, 0x0a, 0xe0, 0x13, 0x49, 0x60, 0x7b, 0x01, 0x30, 0x60, 0x73,
-0x88, 0x79, 0x01, 0x30, 0x88, 0x71, 0x11, 0x48, 0x00, 0x68, 0x02, 0xf0,
-0x65, 0xf9, 0x68, 0x6a, 0x01, 0x37, 0xb8, 0x42, 0xe2, 0xd8, 0xbb, 0x23,
-0x1b, 0x01, 0xf0, 0x18, 0x81, 0x7b, 0x00, 0x29, 0x03, 0xd0, 0x00, 0x21,
-0x81, 0x73, 0xff, 0xf7, 0x05, 0xfb, 0xff, 0xf7, 0xe3, 0xfe, 0x04, 0xb0,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0,
-0x68, 0x0e, 0x00, 0x80, 0xb0, 0x82, 0x20, 0x40, 0x08, 0x83, 0x20, 0x40,
-0xa0, 0x82, 0x20, 0x40, 0x58, 0x04, 0x00, 0x80, 0x90, 0xb4, 0x17, 0x4f,
-0x19, 0x23, 0xdb, 0x01, 0xf9, 0x18, 0x00, 0x22, 0xcb, 0x68, 0x00, 0x2b,
-0x23, 0xd0, 0x01, 0x3b, 0xcb, 0x60, 0x33, 0x23, 0x9b, 0x01, 0xff, 0x18,
-0xbb, 0x69, 0x1c, 0x6d, 0xc0, 0x46, 0xbc, 0x61, 0x04, 0x68, 0xc0, 0x46,
-0x5c, 0x60, 0x44, 0x68, 0xc0, 0x46, 0x9c, 0x60, 0x84, 0x68, 0xc0, 0x46,
-0x1c, 0x61, 0xc0, 0x68, 0xc0, 0x46, 0x58, 0x61, 0x1a, 0x65, 0x08, 0x69,
-0x42, 0x1c, 0x0a, 0x61, 0x00, 0x28, 0x03, 0xd0, 0x38, 0x6a, 0xc0, 0x46,
-0x03, 0x65, 0x00, 0xe0, 0xfb, 0x61, 0x3b, 0x62, 0x18, 0x1c, 0x90, 0xbc,
-0x70, 0x47, 0x10, 0x1c, 0xfb, 0xe7, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x0a, 0x4a, 0x33, 0x23, 0x9b, 0x01, 0xd1, 0x18, 0xc8, 0x69, 0x19, 0x23,
-0xdb, 0x01, 0xd2, 0x18, 0x13, 0x69, 0x00, 0x2b, 0x06, 0xd0, 0x01, 0x3b,
-0x13, 0x61, 0xca, 0x69, 0x12, 0x6d, 0xc0, 0x46, 0xca, 0x61, 0x70, 0x47,
-0x00, 0x21, 0x11, 0x61, 0xfb, 0xe7, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x06, 0x4a, 0x11, 0x69, 0x4b, 0x1c, 0x13, 0x61, 0x40, 0x32, 0x00, 0x29,
-0x01, 0xd0, 0xd1, 0x69, 0x00, 0xe0, 0x00, 0x21, 0x01, 0x65, 0xd0, 0x61,
-0x70, 0x47, 0x00, 0x00, 0xe8, 0x1a, 0x00, 0x80, 0x06, 0x4a, 0xd1, 0x68,
-0x4b, 0x1c, 0xd3, 0x60, 0x40, 0x32, 0x00, 0x29, 0x01, 0xd0, 0x91, 0x69,
-0x00, 0xe0, 0x00, 0x21, 0x01, 0x65, 0x90, 0x61, 0x70, 0x47, 0x00, 0x00,
-0xe8, 0x1a, 0x00, 0x80, 0x90, 0xb4, 0x00, 0x21,
-0x0f, 0x4a, 0x97, 0x89, 0x92, 0x6a, 0x4b, 0x00, 0x1b, 0x18, 0x9b, 0x8a,
-0x00, 0x2b, 0x12, 0xd0, 0xbb, 0x42, 0x10, 0xdc, 0x1c, 0x1c, 0x58, 0x23,
-0x63, 0x43, 0xd3, 0x18, 0xdc, 0x1f, 0x49, 0x3c, 0x01, 0x23, 0x9b, 0x07,
-0x23, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x1b, 0x0e, 0x03, 0x2b, 0x02, 0xd0,
-0x00, 0x20, 0x90, 0xbc, 0x70, 0x47, 0x01, 0x31, 0x04, 0x29, 0xe4, 0xd3,
-0x01, 0x20, 0xf8, 0xe7, 0x4c, 0x2a, 0x00, 0x80, 0xf7, 0xb5, 0x86, 0xb0,
-0x3d, 0x4a, 0x07, 0x1c, 0xd1, 0x69, 0x8f, 0x40, 0x03, 0x1c, 0x14, 0x6a,
-0xe3, 0x40, 0x5f, 0x40, 0x07, 0x9e, 0x8e, 0x40, 0x77, 0x40, 0xcf, 0x40,
-0x94, 0x69, 0xc0, 0x46, 0x05, 0x94, 0x03, 0x1c, 0xa3, 0x40, 0x00, 0x25,
-0x14, 0x69, 0xc0, 0x46, 0x04, 0x94, 0x00, 0x2c, 0x5d, 0xd9, 0x1c, 0x1c,
-0x32, 0x4e, 0x26, 0x43, 0x94, 0x69, 0xe6, 0x40, 0x33, 0x1c, 0x03, 0x96,
-0x53, 0x6a, 0xc0, 0x46, 0x02, 0x93, 0xd2, 0x6a, 0xc0, 0x46, 0x01, 0x92,
-0xbb, 0x00, 0x02, 0x9a, 0xd2, 0x58, 0x13, 0x1c, 0x05, 0x9c, 0xe3, 0x40,
-0x03, 0x9c, 0xa3, 0x42, 0x3e, 0xd1, 0x8a, 0x40, 0xca, 0x40, 0x14, 0x1c,
-0x63, 0x00, 0x1b, 0x19, 0x5b, 0x01, 0x01, 0x9a, 0xd2, 0x18, 0x01, 0x23,
-0x9b, 0x07, 0xd6, 0x1d, 0x01, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06,
-0x1b, 0x0e, 0x03, 0x2b, 0x2c, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d,
-0x51, 0x36, 0x33, 0x43, 0x1b, 0x68, 0x07, 0x9e, 0x1e, 0x40, 0x00, 0x96,
-0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x49, 0x36, 0x33, 0x43, 0x1b, 0x68,
-0x83, 0x42, 0x1b, 0xd1, 0x01, 0x23, 0x9b, 0x07, 0xd6, 0x1d, 0x4d, 0x36,
-0x33, 0x43, 0x1b, 0x68, 0x00, 0x9e, 0xb3, 0x42, 0x12, 0xd1, 0x01, 0x23,
-0x9b, 0x07, 0x1a, 0x43, 0x12, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x08, 0x9b,
-0x32, 0x2b, 0x04, 0xd1, 0x02, 0x2a, 0x07, 0xd1, 0x20, 0x04, 0x00, 0x14,
-0x0f, 0xe0, 0x08, 0x9b, 0x33, 0x2b, 0x01, 0xd1, 0x01, 0x2a, 0xf7, 0xd0,
-0x04, 0x9a, 0x01, 0x37, 0x97, 0x42, 0x00, 0xd3, 0x00, 0x27, 0x04, 0x9a,
-0x01, 0x35, 0xaa, 0x42, 0xae, 0xd8, 0x00, 0x20, 0xc0, 0x43, 0x09, 0xb0,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80,
-0x00, 0x00, 0x00, 0x80, 0xf0, 0xb5, 0x27, 0x4d, 0x68, 0x69, 0x00, 0x28,
-0x06, 0xd0, 0x26, 0x48, 0x00, 0x68, 0x02, 0xf0, 0x2b, 0xf8, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x23, 0x4c, 0x00, 0x26, 0xa0, 0x68, 0x23, 0x4f,
-0x00, 0x28, 0x16, 0xd0, 0x0f, 0xe0, 0x28, 0x6a, 0x02, 0x28, 0x02, 0xd3,
-0x01, 0x20, 0x38, 0x71, 0x0f, 0xe0, 0xa6, 0x60, 0xfd, 0xf7, 0xde, 0xfe,
-0x00, 0x28, 0xea, 0xd1, 0x28, 0x6a, 0x02, 0x28, 0x01, 0xd3, 0x01, 0x20,
-0x38, 0x71, 0xe8, 0x68, 0x00, 0x28, 0x02, 0xd0, 0x38, 0x79, 0x00, 0x28,
-0xe9, 0xd0, 0x68, 0x68, 0x00, 0x28, 0x1b, 0xd0, 0x01, 0x20, 0xa0, 0x60,
-0xfe, 0xf7, 0xbc, 0xfb, 0x00, 0x28, 0xd6, 0xd1, 0x68, 0x68, 0x00, 0x28,
-0xf6, 0xd1, 0x11, 0xe0, 0x00, 0x28, 0xd0, 0xd1, 0x28, 0x6a, 0x02, 0x28,
-0x02, 0xd3, 0x01, 0x20, 0x38, 0x71, 0xca, 0xe7, 0xa6, 0x60, 0xfd, 0xf7,
-0xb9, 0xfe, 0x00, 0x28, 0xc5, 0xd1, 0x28, 0x6a, 0x02, 0x28, 0x01, 0xd3,
-0x01, 0x20, 0x38, 0x71, 0xe8, 0x68, 0x00, 0x28, 0xbd, 0xd0, 0x38, 0x79,
-0x00, 0x28, 0xe7, 0xd0, 0xb9, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80,
-0x5c, 0x04, 0x00, 0x80, 0x4c, 0x2a, 0x00, 0x80, 0x8c, 0x06, 0x00, 0x80,
-0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00,
-0x70, 0x47, 0x00, 0x00, 0x90, 0xb5, 0x40, 0x20, 0x1d, 0x49, 0xc0, 0x46,
-0x08, 0x60, 0x01, 0xf0, 0x9d, 0xfc, 0x03, 0x23, 0x1b, 0x07, 0x41, 0x68,
-0x19, 0x40, 0x0c, 0x0f, 0x61, 0x01, 0x09, 0x1b, 0x89, 0x00, 0x18, 0x4a,
-0x8f, 0x18, 0x01, 0x21, 0x39, 0x80, 0x81, 0x6a, 0xc0, 0x46, 0x79, 0x65,
-0x41, 0x6a, 0xc0, 0x46, 0x79, 0x67, 0xb9, 0x6c, 0xfa, 0x6c, 0x89, 0x18,
-0xb9, 0x64, 0x00, 0x21, 0xf9, 0x64, 0xba, 0x6b, 0x3b, 0x6d, 0xd2, 0x18,
-0xba, 0x63, 0x39, 0x65, 0x42, 0x6a, 0x20, 0x32, 0x51, 0x71, 0x79, 0x6d,
-0x7a, 0x6f, 0xd2, 0x6d, 0xc0, 0x46, 0x11, 0x60, 0xfc, 0xf7, 0xca, 0xff,
-0x20, 0x01, 0x09, 0x49, 0x40, 0x18, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18,
-0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0x78, 0x6f, 0x01, 0xf0, 0xc6, 0xfb,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0,
-0x5c, 0x2b, 0x00, 0x80, 0xa0, 0x1c, 0x00, 0x80, 0xf0, 0xb5, 0x40, 0x20,
-0x12, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x01, 0xf0, 0x59, 0xfc, 0x07, 0x1c,
-0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 0x18, 0x40, 0x06, 0x0f, 0x70, 0x01,
-0x80, 0x1b, 0x80, 0x00, 0x0c, 0x49, 0x44, 0x18, 0xb8, 0x6a, 0xc0, 0x46,
-0x60, 0x65, 0x78, 0x6a, 0xc0, 0x46, 0x60, 0x67, 0x80, 0x6f, 0x05, 0x1d,
-0xe5, 0x63, 0xb9, 0x69, 0x28, 0x1c, 0x02, 0xf0, 0x89, 0xf9, 0x38, 0x1c,
-0x21, 0x1c, 0x32, 0x1c, 0x2b, 0x1c, 0x00, 0xf0, 0x20, 0xf8, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 0x5c, 0x2b, 0x00, 0x80,
-0xf0, 0xb5, 0x4b, 0x6f, 0x9b, 0x6f, 0x1f, 0x1d, 0xcf, 0x63, 0x05, 0x68,
-0x00, 0x23, 0x84, 0x69, 0xa4, 0x08, 0x08, 0xd0, 0x9c, 0x00, 0x2e, 0x59,
-0xc0, 0x46, 0x3e, 0x51, 0x84, 0x69, 0xa4, 0x08, 0x01, 0x33, 0x9c, 0x42,
-0xf6, 0xd8, 0x3b, 0x1c, 0x00, 0xf0, 0x03, 0xf8, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0xff, 0xb5, 0x81, 0xb0, 0x04, 0x1c, 0x1d, 0x1c, 0x0f, 0x1c,
-0x46, 0x48, 0x01, 0x69, 0x01, 0x31, 0x01, 0x61, 0xf9, 0x1d, 0x51, 0x31,
-0xbd, 0x65, 0x00, 0x91, 0x20, 0x1c, 0xfd, 0xf7, 0x5d, 0xfc, 0xf8, 0x6d,
-0x40, 0x09, 0x36, 0xd2, 0xb8, 0x6d, 0x06, 0x7b, 0x43, 0x7b, 0x1b, 0x02,
-0x1e, 0x43, 0x17, 0x21, 0x49, 0x02, 0x01, 0x73, 0x0b, 0x0a, 0x43, 0x73,
-0x00, 0x99, 0x20, 0x1c, 0xfd, 0xf7, 0x4c, 0xfc, 0xb8, 0x6d, 0xc0, 0x46,
-0x06, 0x73, 0x33, 0x0a, 0x43, 0x73, 0xf8, 0x6d, 0x40, 0x09, 0x20, 0xd2,
-0x60, 0x68, 0x01, 0x04, 0x09, 0x0c, 0x03, 0x98, 0x01, 0xf0, 0xcc, 0xfc,
-0x60, 0x68, 0x32, 0x4b, 0x18, 0x43, 0x60, 0x60, 0x20, 0x1c, 0x01, 0xf0,
-0x35, 0xfd, 0x00, 0x25, 0x7d, 0x60, 0xbd, 0x60, 0x3d, 0x64, 0x7d, 0x64,
-0x20, 0x1c, 0xfc, 0xf7, 0x31, 0xff, 0x38, 0x88, 0x40, 0x23, 0x18, 0x43,
-0x38, 0x80, 0x7d, 0x62, 0x29, 0x48, 0xc0, 0x46, 0xb8, 0x62, 0x38, 0x1c,
-0x00, 0xf0, 0xa0, 0xfb, 0x44, 0xe0, 0x20, 0x68, 0x01, 0x23, 0x9b, 0x07,
-0x08, 0x38, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0x78, 0x64, 0x60, 0x68,
-0x02, 0x04, 0x12, 0x0c, 0x78, 0x6e, 0x01, 0x26, 0xc1, 0x1d, 0x0d, 0x31,
-0x8a, 0x42, 0x02, 0xd2, 0x3a, 0x64, 0x08, 0x1c, 0x0e, 0xe0, 0x41, 0x19,
-0x89, 0x89, 0xf0, 0x23, 0x19, 0x40, 0x09, 0x09, 0x89, 0x00, 0x40, 0x18,
-0xf8, 0x60, 0xf9, 0x61, 0x61, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x81, 0x42,
-0x16, 0xd2, 0x39, 0x64, 0x63, 0x68, 0x19, 0x04, 0x09, 0x0c, 0x40, 0x1a,
-0x03, 0x30, 0x80, 0x08, 0x82, 0x00, 0xa0, 0x61,
-0x20, 0x68, 0x09, 0x18, 0x9b, 0x18, 0x63, 0x60, 0xc3, 0x1f, 0x05, 0x3b,
-0x38, 0x1c, 0x00, 0xf0, 0xb6, 0xfa, 0x7e, 0x80, 0x20, 0x1c, 0x00, 0xf0,
-0xbf, 0xfb, 0x0b, 0xe0, 0xb9, 0x68, 0x08, 0x1a, 0x00, 0x25, 0x78, 0x62,
-0xbd, 0x62, 0x38, 0x1c, 0x00, 0xf0, 0x3c, 0xfc, 0x20, 0x1c, 0x39, 0x1c,
-0x00, 0xf0, 0x64, 0xf8, 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x0c, 0x2b, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xc0,
-0xf0, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0x38, 0x6c, 0xf9, 0x6b, 0x0d, 0x18,
-0x21, 0x68, 0x41, 0x18, 0x00, 0x20, 0xa2, 0x69, 0x00, 0x2a, 0x0b, 0xd9,
-0x82, 0x00, 0x56, 0x18, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68,
-0xc0, 0x46, 0xab, 0x50, 0xa2, 0x69, 0x01, 0x30, 0x82, 0x42, 0xf3, 0xd8,
-0x78, 0x6e, 0xf9, 0x6b, 0x09, 0x18, 0x89, 0x89, 0xf0, 0x23, 0x19, 0x40,
-0x09, 0x09, 0x89, 0x00, 0x40, 0x18, 0xf8, 0x60, 0xf9, 0x61, 0x20, 0x68,
-0x01, 0x23, 0x9b, 0x07, 0x08, 0x38, 0x18, 0x43, 0x01, 0x68, 0x78, 0x6c,
-0xfc, 0xf7, 0x95, 0xff, 0x78, 0x64, 0x60, 0x68, 0x01, 0x04, 0x09, 0x0c,
-0xf8, 0x68, 0x81, 0x42, 0x19, 0xd2, 0x39, 0x64, 0x63, 0x68, 0x19, 0x04,
-0x09, 0x0c, 0x40, 0x1a, 0x03, 0x30, 0x80, 0x08, 0x82, 0x00, 0xa0, 0x61,
-0x20, 0x68, 0x09, 0x18, 0x9b, 0x18, 0x63, 0x60, 0xc3, 0x1f, 0x05, 0x3b,
-0x38, 0x1c, 0x00, 0xf0, 0x56, 0xfa, 0x01, 0x20, 0x78, 0x80, 0x20, 0x1c,
-0x00, 0xf0, 0x5e, 0xfb, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xb9, 0x68,
-0x08, 0x1a, 0x78, 0x62, 0x00, 0x20, 0xb8, 0x62, 0x38, 0x1c, 0x00, 0xf0,
-0xd9, 0xfb, 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x01, 0xf8, 0xef, 0xe7,
-0xf0, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x0f, 0x1c, 0x8e, 0x48, 0x41, 0x69,
-0x01, 0x31, 0x41, 0x61, 0x03, 0x20, 0x00, 0x07, 0x61, 0x68, 0x08, 0x40,
-0x06, 0x0f, 0x0a, 0x04, 0x12, 0x0c, 0x20, 0x68, 0x11, 0x18, 0xfb, 0x68,
-0xd2, 0x1a, 0x7b, 0x68, 0x9d, 0x1a, 0xc3, 0x1f, 0x05, 0x3b, 0x38, 0x1c,
-0x2a, 0x1c, 0x00, 0xf0, 0x26, 0xfa, 0x00, 0x20, 0x78, 0x80, 0x20, 0x1c,
-0x00, 0xf0, 0x2e, 0xfb, 0x60, 0x68, 0x40, 0x19, 0x01, 0x04, 0x09, 0x0c,
-0x60, 0x60, 0x30, 0x1c, 0x01, 0xf0, 0xe0, 0xfb, 0x7d, 0x4e, 0x0b, 0x23,
-0x1b, 0x02, 0xf0, 0x18, 0x00, 0x69, 0x00, 0x28, 0x19, 0xd0, 0x00, 0x25,
-0x2d, 0x23, 0x9b, 0x01, 0xf0, 0x18, 0xc0, 0x68, 0x00, 0x28, 0x12, 0xd0,
-0xaa, 0x00, 0x92, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0xd2, 0x68,
-0x20, 0x1c, 0x39, 0x1c, 0x01, 0xf0, 0x1c, 0xfe, 0x01, 0x35, 0xa8, 0x00,
-0x80, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0xc0, 0x68, 0x00, 0x28,
-0xec, 0xd1, 0xf8, 0x6b, 0x01, 0x1f, 0x8a, 0x1c, 0xfa, 0x63, 0xfa, 0x68,
-0x7d, 0x6c, 0x00, 0xf0, 0xbb, 0xf9, 0xc0, 0x43, 0x01, 0x04, 0x09, 0x0c,
-0x28, 0x1c, 0xfc, 0xf7, 0x10, 0xff, 0x03, 0x90, 0xf9, 0x6b, 0x3a, 0x6e,
-0x8e, 0x18, 0x20, 0x68, 0x12, 0x18, 0x01, 0x92, 0x7a, 0x6e, 0x8d, 0x18,
-0x11, 0x18, 0x02, 0x91, 0xc8, 0x1d, 0x09, 0x30, 0xe0, 0x60, 0xb1, 0x88,
-0x08, 0x02, 0x09, 0x0a, 0x09, 0x06, 0x09, 0x0e, 0x08, 0x43, 0x00, 0x04,
-0x00, 0x0c, 0x78, 0x61, 0x68, 0x68, 0x01, 0x0e, 0xff, 0x22, 0x12, 0x04,
-0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 0x02, 0x40,
-0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x08, 0x43, 0x38, 0x61, 0xa8, 0x89,
-0x09, 0x23, 0x1b, 0x02, 0x18, 0x40, 0xb8, 0x61,
-0xa8, 0x89, 0x98, 0x43, 0xa8, 0x81, 0xa8, 0x89, 0x02, 0x99, 0xc0, 0x46,
-0x88, 0x81, 0x00, 0x20, 0x70, 0x80, 0xb0, 0x80, 0x70, 0x81, 0x68, 0x60,
-0x28, 0x82, 0xb9, 0x6e, 0x30, 0x1c, 0xfc, 0xf7, 0xe8, 0xfe, 0x38, 0x86,
-0xfa, 0x69, 0x30, 0x1c, 0x29, 0x1c, 0xfc, 0xf7, 0x03, 0xff, 0x78, 0x86,
-0x3d, 0x8e, 0x78, 0x8e, 0x03, 0x99, 0xfc, 0xf7, 0xc8, 0xfe, 0x00, 0x90,
-0x60, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x39, 0x6e, 0x41, 0x1a, 0x09, 0x04,
-0x09, 0x0c, 0x7a, 0x6e, 0x82, 0x1a, 0x13, 0x04, 0x1b, 0x0c, 0x1a, 0x02,
-0x1b, 0x0a, 0x1a, 0x43, 0x16, 0x04, 0x36, 0x0c, 0xba, 0x68, 0x82, 0x42,
-0x01, 0xd2, 0x00, 0x20, 0x00, 0xe0, 0x10, 0x1a, 0xb8, 0x60, 0x08, 0x02,
-0x09, 0x12, 0x09, 0x06, 0x09, 0x0e, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c,
-0x01, 0x98, 0xc0, 0x46, 0x41, 0x80, 0x28, 0x1c, 0xfc, 0xf7, 0xa3, 0xfe,
-0x05, 0x1c, 0x00, 0x98, 0x31, 0x1c, 0xfc, 0xf7, 0x9e, 0xfe, 0x06, 0x1c,
-0x78, 0x69, 0x00, 0x04, 0x00, 0x0c, 0x01, 0x02, 0x00, 0x0a, 0x08, 0x43,
-0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, 0x81, 0x80, 0x28, 0x1c,
-0xfc, 0xf7, 0x8f, 0xfe, 0x79, 0x69, 0x01, 0x31, 0xc0, 0x43, 0x79, 0x61,
-0x01, 0x9a, 0xc0, 0x46, 0x50, 0x81, 0x38, 0x69, 0x01, 0x0e, 0xff, 0x22,
-0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 0x12, 0x02,
-0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x01, 0x43, 0x30, 0x1c,
-0xfc, 0xf7, 0x77, 0xfe, 0x39, 0x69, 0x7a, 0x68, 0x89, 0x18, 0x39, 0x61,
-0xb9, 0x68, 0x00, 0x29, 0x09, 0xd1, 0x02, 0x99, 0x89, 0x89, 0xba, 0x69,
-0x11, 0x43, 0x02, 0x9a, 0xc0, 0x46, 0x91, 0x81, 0xb9, 0x69, 0xfc, 0xf7,
-0x66, 0xfe, 0x20, 0x82, 0x00, 0x20, 0x60, 0x82, 0xf8, 0x6d, 0x41, 0x08,
-0x16, 0xd3, 0x80, 0x0a, 0x0a, 0xd3, 0x60, 0x68, 0x10, 0x38, 0x01, 0x04,
-0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x21, 0x68, 0xc0, 0x46,
-0x08, 0x82, 0x09, 0xe0, 0x60, 0x68, 0x0c, 0x38, 0x01, 0x04, 0x09, 0x0c,
-0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x21, 0x68, 0xc0, 0x46, 0x88, 0x81,
-0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80,
-0x68, 0x0e, 0x00, 0x80, 0xf1, 0xb5, 0x84, 0xb0, 0x6e, 0x4d, 0x28, 0x69,
-0x01, 0x22, 0x04, 0x99, 0x8a, 0x40, 0x90, 0x43, 0x28, 0x61, 0x04, 0x98,
-0x43, 0x01, 0x18, 0x1a, 0x80, 0x00, 0x16, 0x1c, 0x69, 0x49, 0x44, 0x18,
-0xe0, 0x6b, 0xc0, 0x46, 0x00, 0x90, 0xa0, 0x68, 0x00, 0x28, 0x01, 0xd1,
-0x00, 0x26, 0x26, 0xe0, 0x65, 0x48, 0x41, 0x69, 0x01, 0x31, 0x41, 0x61,
-0x04, 0x98, 0xfc, 0xf7, 0x09, 0xfd, 0x07, 0x1c, 0x03, 0xd1, 0x28, 0x69,
-0x30, 0x43, 0x28, 0x61, 0xb5, 0xe0, 0xa0, 0x68, 0x65, 0x68, 0xa8, 0x42,
-0x00, 0xd2, 0x05, 0x1c, 0xa1, 0x6c, 0xa9, 0x42, 0x16, 0xd2, 0x40, 0x1a,
-0x62, 0x6a, 0x10, 0x1a, 0x00, 0x26, 0x60, 0x62, 0xa6, 0x60, 0xa6, 0x62,
-0x20, 0x88, 0x48, 0x23, 0x18, 0x43, 0x20, 0x80, 0x0d, 0x1c, 0x09, 0xd1,
-0x38, 0x1c, 0xfc, 0xf7, 0x19, 0xfd, 0x03, 0x20, 0x60, 0x80, 0x66, 0x60,
-0x20, 0x1c, 0x00, 0xf0, 0x8d, 0xf9, 0x96, 0xe0, 0xe1, 0x68, 0x38, 0x68,
-0x09, 0x18, 0xc3, 0x1f, 0x05, 0x3b, 0x20, 0x1c, 0x02, 0x39, 0x2a, 0x1c,
-0x00, 0xf0, 0xcd, 0xf8, 0x38, 0x1c, 0x00, 0xf0, 0xd7, 0xf9, 0xe0, 0x68,
-0x46, 0x19, 0x78, 0x68, 0x30, 0x43, 0x78, 0x60, 0x04, 0x98, 0x31, 0x1c,
-0x01, 0xf0, 0x88, 0xfa, 0x21, 0x6e, 0x00, 0x98,
-0x08, 0x18, 0x01, 0x90, 0x70, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x61, 0x6e,
-0x71, 0x1a, 0x0a, 0x04, 0x12, 0x0c, 0x11, 0x02, 0x12, 0x0a, 0x11, 0x43,
-0x09, 0x04, 0x09, 0x0c, 0x02, 0x91, 0x01, 0x02, 0x00, 0x0a, 0x08, 0x43,
-0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46, 0x41, 0x80, 0x20, 0x8e,
-0xfc, 0xf7, 0xcb, 0xfd, 0x06, 0x1c, 0x60, 0x8e, 0x02, 0x99, 0xfc, 0xf7,
-0xc6, 0xfd, 0x03, 0x90, 0x60, 0x69, 0x01, 0x04, 0x09, 0x0c, 0x08, 0x02,
-0x09, 0x0a, 0x08, 0x43, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x98, 0xc0, 0x46,
-0x81, 0x80, 0x30, 0x1c, 0xfc, 0xf7, 0xb7, 0xfd, 0x61, 0x69, 0x01, 0x31,
-0xc0, 0x43, 0x61, 0x61, 0x01, 0x99, 0xc0, 0x46, 0x48, 0x81, 0x60, 0x6e,
-0x00, 0x99, 0x46, 0x18, 0x20, 0x69, 0x01, 0x0e, 0xff, 0x22, 0x12, 0x04,
-0x02, 0x40, 0x12, 0x0a, 0x11, 0x43, 0xff, 0x22, 0x12, 0x02, 0x02, 0x40,
-0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x01, 0x43, 0x71, 0x60, 0x03, 0x98,
-0xfc, 0xf7, 0x9b, 0xfd, 0x21, 0x69, 0x49, 0x19, 0x21, 0x61, 0xa1, 0x68,
-0x49, 0x1b, 0xa1, 0x60, 0x06, 0xd1, 0xb1, 0x89, 0xa2, 0x69, 0x11, 0x43,
-0xb1, 0x81, 0xa1, 0x69, 0xfc, 0xf7, 0x8d, 0xfd, 0x38, 0x82, 0x61, 0x6e,
-0x38, 0x68, 0x09, 0x18, 0x0e, 0x31, 0xf9, 0x60, 0xe2, 0x68, 0x00, 0x99,
-0x04, 0x38, 0x00, 0xf0, 0x4c, 0xf8, 0x02, 0x20, 0x78, 0x82, 0xe0, 0x6d,
-0x41, 0x08, 0x16, 0xd3, 0x80, 0x0a, 0x0a, 0xd3, 0x78, 0x68, 0x10, 0x38,
-0x01, 0x04, 0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x39, 0x68,
-0xc0, 0x46, 0xc8, 0x81, 0x09, 0xe0, 0x78, 0x68, 0x0c, 0x38, 0x01, 0x04,
-0x09, 0x0c, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x39, 0x68, 0xc0, 0x46,
-0x48, 0x81, 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0xd0, 0x2c, 0x00, 0x80, 0x5c, 0x2b, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80,
-0xf7, 0xb5, 0x03, 0x1c, 0x0f, 0x1c, 0x00, 0x20, 0x1c, 0x68, 0x26, 0x04,
-0x31, 0x1c, 0x1d, 0x1d, 0xfc, 0xf7, 0x51, 0xfd, 0x40, 0xc7, 0x02, 0x9a,
-0xd1, 0x1c, 0x89, 0x08, 0x01, 0x39, 0x4a, 0x1e, 0x02, 0x92, 0x00, 0x29,
-0x0d, 0xd0, 0x21, 0x0c, 0x10, 0xcd, 0x22, 0x04, 0x0a, 0x43, 0x11, 0x1c,
-0x16, 0x1c, 0xfc, 0xf7, 0x40, 0xfd, 0x40, 0xc7, 0x02, 0x99, 0x4a, 0x1e,
-0x02, 0x92, 0x00, 0x29, 0xf1, 0xd1, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x80, 0x08, 0x80, 0x00, 0x89, 0x08, 0x89, 0x00, 0x03, 0x32,
-0x93, 0x08, 0x5a, 0x1e, 0x00, 0x2b, 0x05, 0xd0, 0x08, 0xc9, 0x08, 0xc0,
-0x13, 0x1c, 0x01, 0x3a, 0x00, 0x2b, 0xf9, 0xd1, 0x70, 0x47, 0xff, 0xb5,
-0x86, 0xb0, 0x17, 0x1c, 0x00, 0x26, 0x06, 0x98, 0x80, 0x6c, 0xc0, 0x1b,
-0x06, 0x99, 0xc0, 0x46, 0x88, 0x64, 0x01, 0x20, 0xc0, 0x05, 0x06, 0x99,
-0x89, 0x6b, 0xc0, 0x46, 0x01, 0x91, 0x06, 0x99, 0x4c, 0x6b, 0x67, 0xe0,
-0x21, 0x68, 0xc0, 0x46, 0x02, 0x91, 0x61, 0x68, 0xc0, 0x46, 0x03, 0x91,
-0xa1, 0x68, 0xc0, 0x46, 0x04, 0x91, 0x02, 0xa9, 0x49, 0x88, 0xb9, 0x42,
-0x08, 0xd2, 0x02, 0xad, 0x6d, 0x88, 0x02, 0xa9, 0x49, 0x88, 0x7f, 0x1a,
-0x00, 0x21, 0x02, 0xab, 0x59, 0x80, 0x19, 0xe0, 0x02, 0xa9, 0x49, 0x88,
-0xc9, 0x1b, 0x02, 0xab, 0x59, 0x80, 0x3d, 0x1c, 0x00, 0x27, 0x01, 0x21,
-0x49, 0x06, 0x07, 0x9b, 0x9a, 0x07, 0x92, 0x0f, 0x0d, 0xd0, 0xeb, 0x06,
-0xdb, 0x0e, 0x08, 0xd0, 0x1e, 0x2b, 0x08, 0xd3, 0x1e, 0x2b, 0x02, 0xd1,
-0x03, 0x2a, 0x04, 0xd1, 0x01, 0xe0, 0x02, 0x2a,
-0x01, 0xd3, 0x01, 0x26, 0x00, 0x21, 0x29, 0x43, 0x01, 0x43, 0x0a, 0x1c,
-0x00, 0x91, 0x00, 0x20, 0x03, 0x99, 0x04, 0x9a, 0x07, 0x9b, 0x01, 0xf0,
-0x5b, 0xff, 0x07, 0x99, 0x49, 0x19, 0x07, 0x91, 0x00, 0x2e, 0x0a, 0xd0,
-0x1d, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x1d, 0x48, 0x01, 0x6d, 0x42, 0x6d,
-0x00, 0x20, 0x07, 0x9b, 0x01, 0xf0, 0x4c, 0xff, 0x00, 0x26, 0x02, 0xa8,
-0x40, 0x88, 0x00, 0x28, 0x0c, 0xd0, 0x03, 0x98, 0x40, 0x19, 0x03, 0x90,
-0x02, 0x98, 0xc0, 0x46, 0x20, 0x60, 0x03, 0x98, 0xc0, 0x46, 0x60, 0x60,
-0x04, 0x98, 0xc0, 0x46, 0xa0, 0x60, 0x03, 0xe0, 0x01, 0x98, 0x01, 0x38,
-0x01, 0x90, 0x10, 0x34, 0x06, 0x98, 0xc0, 0x46, 0x44, 0x63, 0x01, 0x98,
-0x06, 0x99, 0xc0, 0x46, 0x88, 0x63, 0x00, 0x20, 0x00, 0x2f, 0x02, 0xd0,
-0x01, 0x99, 0x00, 0x29, 0x92, 0xd1, 0x09, 0x4a, 0xc0, 0x46, 0x00, 0x92,
-0x06, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x09, 0x9b, 0x01, 0xf0,
-0x1f, 0xff, 0x0a, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x01, 0x00, 0x00, 0x02, 0x7c, 0x29, 0x00, 0x80, 0x04, 0x00, 0x53, 0x02,
-0x90, 0xb5, 0x0c, 0x1c, 0x07, 0x1c, 0x38, 0x68, 0x01, 0x23, 0x9b, 0x07,
-0x08, 0x38, 0x18, 0x43, 0x01, 0x68, 0x38, 0x8a, 0xfc, 0xf7, 0x85, 0xfc,
-0xc0, 0x43, 0xf9, 0x68, 0xc0, 0x46, 0x08, 0x80, 0x78, 0x8a, 0x39, 0x68,
-0x08, 0x1a, 0x38, 0x60, 0x38, 0x1c, 0x01, 0xf0, 0x8b, 0xf9, 0x38, 0x1c,
-0xfc, 0xf7, 0x8c, 0xfb, 0x20, 0x1c, 0xff, 0xf7, 0x33, 0xfe, 0x90, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x01, 0x88, 0x8a, 0x09, 0x21, 0xd3,
-0xca, 0x09, 0x1f, 0xd2, 0x8a, 0x08, 0x1d, 0xd3, 0x00, 0x21, 0x01, 0x80,
-0x41, 0x80, 0x47, 0x6f, 0x40, 0x6d, 0xfa, 0x1d, 0x19, 0x32, 0x51, 0x71,
-0xfa, 0x6d, 0xc0, 0x46, 0x10, 0x60, 0x3a, 0x6e, 0xc0, 0x46, 0x10, 0x60,
-0x0c, 0x48, 0xc0, 0x46, 0x81, 0x63, 0xc1, 0x6b, 0x49, 0x08, 0x49, 0x00,
-0xc1, 0x63, 0x01, 0x20, 0x00, 0xf0, 0xcc, 0xff, 0x38, 0x1c, 0x00, 0xf0,
-0x6b, 0xff, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0x23, 0x19, 0x43,
-0x01, 0x80, 0x01, 0x88, 0x49, 0x09, 0xf6, 0xd2, 0x00, 0xf0, 0xb0, 0xf8,
-0xf3, 0xe7, 0x00, 0x00, 0xe8, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x07, 0x1c,
-0x10, 0x1c, 0x0d, 0x1c, 0x00, 0x24, 0x5e, 0x1e, 0x00, 0x2b, 0x19, 0xd0,
-0x01, 0x68, 0xc0, 0x46, 0x39, 0x60, 0x41, 0x88, 0x0c, 0x19, 0x41, 0x68,
-0xc0, 0x46, 0x79, 0x60, 0x81, 0x68, 0xc0, 0x46, 0xb9, 0x60, 0xc1, 0x68,
-0xc0, 0x46, 0xf9, 0x60, 0x10, 0x30, 0x10, 0x37, 0xe9, 0x6a, 0x81, 0x42,
-0x02, 0xd8, 0x28, 0x1c, 0x00, 0xf0, 0xec, 0xff, 0x31, 0x1c, 0x01, 0x3e,
-0x00, 0x29, 0xe5, 0xd1, 0x20, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0x21, 0xc1, 0x61, 0x05, 0x49, 0x0a, 0x68, 0x00, 0x2a, 0x01, 0xd1,
-0x08, 0x60, 0x02, 0xe0, 0x4a, 0x68, 0xc0, 0x46, 0xd0, 0x61, 0x48, 0x60,
-0x70, 0x47, 0x00, 0x00, 0xd0, 0x2c, 0x00, 0x80, 0x03, 0x49, 0x08, 0x68,
-0x00, 0x28, 0x02, 0xd0, 0xc2, 0x69, 0xc0, 0x46, 0x0a, 0x60, 0x70, 0x47,
-0xd0, 0x2c, 0x00, 0x80, 0x00, 0x21, 0x81, 0x67, 0x05, 0x49, 0x8a, 0x68,
-0x00, 0x2a, 0x01, 0xd1, 0x88, 0x60, 0x02, 0xe0, 0xca, 0x68, 0xc0, 0x46,
-0x90, 0x67, 0xc8, 0x60, 0x70, 0x47, 0x00, 0x00, 0xd0, 0x2c, 0x00, 0x80,
-0x03, 0x49, 0x88, 0x68, 0x00, 0x28, 0x02, 0xd0, 0x82, 0x6f, 0xc0, 0x46,
-0x8a, 0x60, 0x70, 0x47, 0xd0, 0x2c, 0x00, 0x80,
-0x00, 0xb5, 0x80, 0x20, 0x13, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xff, 0xf7,
-0xd5, 0xff, 0x00, 0x28, 0x1b, 0xd0, 0x03, 0x23, 0x1b, 0x07, 0x41, 0x68,
-0x19, 0x40, 0x0a, 0x0f, 0x51, 0x01, 0x89, 0x1a, 0x89, 0x00, 0x0d, 0x4b,
-0xc9, 0x18, 0x4b, 0x88, 0x00, 0x2b, 0x04, 0xd1, 0x11, 0x1c, 0xff, 0xf7,
-0x3b, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x01, 0x2b, 0x02, 0xd1, 0xff, 0xf7,
-0x05, 0xfc, 0xf8, 0xe7, 0x02, 0x2b, 0xf6, 0xd1, 0xff, 0xf7, 0x4e, 0xfb,
-0xf3, 0xe7, 0x04, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, 0xee, 0xe7,
-0x00, 0x00, 0x00, 0xb0, 0x5c, 0x2b, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40,
-0x00, 0xb5, 0x20, 0x20, 0x0d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xff, 0xf7,
-0xbf, 0xff, 0x00, 0x28, 0x0e, 0xd0, 0x01, 0x88, 0x20, 0x23, 0x19, 0x43,
-0x01, 0x80, 0x01, 0x88, 0x10, 0x23, 0x99, 0x43, 0x01, 0x80, 0x01, 0x88,
-0x09, 0x0a, 0x01, 0xd3, 0xff, 0xf7, 0x2e, 0xff, 0x08, 0xbc, 0x18, 0x47,
-0x03, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, 0xf8, 0xe7, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xb0, 0xa0, 0x82, 0x20, 0x40, 0x98, 0xb5, 0x07, 0x1c,
-0x22, 0x48, 0xc0, 0x46, 0x00, 0x90, 0x22, 0x48, 0xc3, 0x1d, 0x41, 0x33,
-0x41, 0x6d, 0x82, 0x6d, 0x80, 0x6c, 0x00, 0x03, 0x00, 0x0b, 0x9c, 0x68,
-0x01, 0x23, 0x9b, 0x07, 0x23, 0x43, 0x1b, 0x68, 0x98, 0x42, 0x00, 0xd1,
-0x0c, 0xe0, 0x98, 0x42, 0x03, 0xd9, 0x10, 0x1a, 0x59, 0x1a, 0x41, 0x18,
-0x00, 0xe0, 0x19, 0x1a, 0x01, 0x20, 0x10, 0x29, 0x00, 0xd8, 0x00, 0x20,
-0x00, 0x28, 0x1f, 0xd0, 0x78, 0x6a, 0xf9, 0x6a, 0xc0, 0x46, 0x08, 0x60,
-0xb8, 0x6a, 0xf9, 0x6a, 0xc0, 0x46, 0x48, 0x60, 0x10, 0x4a, 0xc0, 0x46,
-0x00, 0x92, 0xfb, 0x6a, 0x0f, 0x48, 0x42, 0x6d, 0x03, 0x20, 0x39, 0x6a,
-0x01, 0xf0, 0xe2, 0xfd, 0x38, 0x88, 0x10, 0x23, 0x18, 0x43, 0x38, 0x80,
-0x38, 0x88, 0x40, 0x23, 0x98, 0x43, 0x38, 0x80, 0x38, 0x1c, 0xff, 0xf7,
-0x55, 0xff, 0x98, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x38, 0x88, 0x40, 0x23,
-0x18, 0x43, 0x38, 0x80, 0xf7, 0xe7, 0x00, 0x00, 0x55, 0x55, 0x55, 0x55,
-0xa8, 0x03, 0x00, 0x80, 0x08, 0x00, 0x11, 0x02, 0x7c, 0x29, 0x00, 0x80,
-0xb0, 0xb5, 0x40, 0x20, 0x2c, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0,
-0xfd, 0xfe, 0x07, 0x1c, 0x40, 0x68, 0x03, 0x23, 0x1b, 0x07, 0x18, 0x40,
-0x05, 0x0f, 0x68, 0x01, 0x40, 0x1b, 0x80, 0x00, 0x26, 0x49, 0x44, 0x18,
-0x20, 0x88, 0x02, 0x23, 0x18, 0x43, 0x20, 0x80, 0x20, 0x88, 0x41, 0x08,
-0x34, 0xd3, 0x40, 0x08, 0x40, 0x00, 0x20, 0x80, 0xa0, 0x6c, 0xe1, 0x6c,
-0x40, 0x18, 0xa0, 0x64, 0x00, 0x20, 0xe0, 0x64, 0xa1, 0x6b, 0x22, 0x6d,
-0x89, 0x18, 0xa1, 0x63, 0x20, 0x65, 0xb8, 0x6a, 0xc0, 0x46, 0x60, 0x65,
-0x03, 0x23, 0x1b, 0x07, 0x78, 0x68, 0x18, 0x40, 0x78, 0x60, 0x61, 0x68,
-0x36, 0x31, 0x94, 0x29, 0x04, 0xd8, 0x38, 0x23, 0x18, 0x43, 0x78, 0x60,
-0x38, 0x20, 0x03, 0xe0, 0x94, 0x23, 0x18, 0x43, 0x78, 0x60, 0x94, 0x20,
-0xb8, 0x61, 0x39, 0x68, 0x78, 0x68, 0x02, 0x04, 0x12, 0x0c, 0x20, 0x1c,
-0xcb, 0x1f, 0x05, 0x3b, 0xff, 0xf7, 0xd7, 0xfd, 0x02, 0x20, 0x60, 0x80,
-0x38, 0x1c, 0xff, 0xf7, 0xdf, 0xfe, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x38, 0x1c, 0xfc, 0xf7, 0x07, 0xfa, 0x28, 0x01, 0x06, 0x49, 0x40, 0x18,
-0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x41, 0x6b, 0x01, 0x39, 0x41, 0x63,
-0xef, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0,
-0x5c, 0x2b, 0x00, 0x80, 0xa0, 0x1c, 0x00, 0x80, 0x90, 0xb5, 0x00, 0x27,
-0x0f, 0x4c, 0x0d, 0xe0, 0x42, 0x6b, 0x01, 0x3a, 0x42, 0x63, 0x00, 0x2a,
-0x05, 0xdc, 0x02, 0x6b, 0xc0, 0x46, 0x42, 0x63, 0xc0, 0x6a, 0x01, 0xf0,
-0xc6, 0xf9, 0x01, 0x37, 0x0b, 0x2f, 0x07, 0xd2, 0x38, 0x01, 0x00, 0x19,
-0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x81, 0x6a, 0x00, 0x29, 0xe9, 0xd1,
-0x01, 0x20, 0x40, 0x06, 0x03, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x90, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0,
-0x10, 0x48, 0xc1, 0x68, 0x01, 0x31, 0xc1, 0x60, 0x0f, 0x49, 0xc8, 0x68,
-0x01, 0x28, 0x17, 0xd1, 0xc8, 0x1d, 0x79, 0x30, 0x02, 0x89, 0x00, 0x2a,
-0x12, 0xd0, 0x01, 0x3a, 0x02, 0x81, 0x02, 0x89, 0x00, 0x2a, 0x0d, 0xd1,
-0x42, 0x89, 0x00, 0x2a, 0x08, 0xd1, 0xc9, 0x6f, 0x02, 0x23, 0x0a, 0x68,
-0x1a, 0x43, 0x0a, 0x60, 0x04, 0x21, 0x01, 0x81, 0x01, 0x21, 0x00, 0xe0,
-0x00, 0x21, 0x41, 0x81, 0x70, 0x47, 0x00, 0x00, 0x08, 0x83, 0x20, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0xb0, 0xb5, 0x07, 0x1c, 0x01, 0x23, 0xf8, 0x1d,
-0x69, 0x30, 0x03, 0x73, 0x1e, 0x48, 0xc2, 0x1d, 0x79, 0x32, 0x54, 0x8a,
-0x61, 0x1c, 0x51, 0x82, 0xd5, 0x8a, 0x00, 0x21, 0xac, 0x42, 0x04, 0xdb,
-0xc4, 0x1d, 0x89, 0x34, 0x63, 0x70, 0x51, 0x82, 0xd1, 0x83, 0x01, 0x23,
-0x9b, 0x07, 0x3a, 0x6d, 0x1a, 0x43, 0x12, 0x68, 0xc0, 0x46, 0xba, 0x61,
-0xfb, 0x69, 0x9a, 0x42, 0x06, 0xd1, 0xf8, 0x6c, 0x12, 0x49, 0xc0, 0x46,
-0x08, 0x60, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x79, 0x61, 0x41, 0x69,
-0xfa, 0x6c, 0x91, 0x43, 0x41, 0x61, 0x01, 0x20, 0x00, 0x05, 0xc1, 0x60,
-0x38, 0x69, 0x02, 0x28, 0xf1, 0xd0, 0xb8, 0x69, 0xf9, 0x69, 0x41, 0x1a,
-0x01, 0xd5, 0x78, 0x6d, 0x41, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8,
-0xf9, 0x69, 0x09, 0x18, 0xf9, 0x61, 0x78, 0x6d, 0x81, 0x42, 0xe2, 0xd3,
-0x08, 0x1a, 0xf8, 0x61, 0xdf, 0xe7, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x00, 0x00, 0x00, 0xb0, 0xf8, 0xb5, 0x04, 0x1c, 0x0f, 0x1c, 0xff, 0x23,
-0x21, 0x33, 0x9f, 0x42, 0x01, 0xd9, 0xff, 0x27, 0x21, 0x37, 0xe1, 0x6e,
-0x38, 0x1c, 0x01, 0xf0, 0xcb, 0xfc, 0x2d, 0x4d, 0x00, 0x28, 0x13, 0xd1,
-0xe0, 0x1d, 0x49, 0x30, 0x01, 0x7a, 0x01, 0x23, 0x19, 0x43, 0x01, 0x72,
-0x29, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x29, 0x48, 0x01, 0x6d, 0x42, 0x6d,
-0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0xb0, 0xfc, 0x00, 0x20, 0xf8, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x20, 0x69, 0x01, 0x30, 0x20, 0x61, 0x23, 0x49,
-0xc8, 0x1d, 0xb9, 0x30, 0x02, 0x6b, 0x92, 0x00, 0x51, 0x18, 0xc0, 0x31,
-0x0f, 0x61, 0x01, 0x6b, 0x01, 0x31, 0x89, 0x07, 0x89, 0x0f, 0x01, 0x63,
-0x20, 0x6b, 0xc2, 0x19, 0x61, 0x6d, 0x8a, 0x42, 0x03, 0xd8, 0x23, 0x22,
-0x12, 0x05, 0x3a, 0x43, 0x05, 0xe0, 0x09, 0x1a, 0x7e, 0x1a, 0x07, 0xd1,
-0x23, 0x22, 0x12, 0x05, 0x0a, 0x43, 0x00, 0x92, 0x61, 0x6e, 0x09, 0x18,
-0xa2, 0x6e, 0x10, 0xe0, 0x11, 0x22, 0x52, 0x05, 0x0a, 0x43, 0x00, 0x92,
-0x61, 0x6e, 0x09, 0x18, 0x00, 0x20, 0xa2, 0x6e, 0x2b, 0x1c, 0x01, 0xf0,
-0x7d, 0xfc, 0x23, 0x22, 0x12, 0x05, 0x32, 0x43, 0x00, 0x92, 0x61, 0x6e,
-0xa2, 0x6e, 0x00, 0x20, 0x2b, 0x1c, 0x01, 0xf0, 0x73, 0xfc, 0x20, 0x6b,
-0xc0, 0x19, 0x00, 0x09, 0x00, 0x01, 0x61, 0x6d, 0x81, 0x42, 0x00, 0xd8,
-0x40, 0x1a, 0x20, 0x63, 0x38, 0x1c, 0xb8, 0xe7,
-0x44, 0x80, 0x20, 0x40, 0x04, 0x00, 0x1b, 0x02, 0x7c, 0x29, 0x00, 0x80,
-0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x01, 0x20, 0xc0, 0x03, 0x0d, 0x49,
-0xc0, 0x46, 0x08, 0x60, 0x0c, 0x49, 0xc8, 0x1d, 0x49, 0x30, 0x02, 0x7a,
-0x00, 0x27, 0x00, 0x2a, 0x03, 0xd0, 0x07, 0x72, 0x08, 0x1c, 0xff, 0xf7,
-0x37, 0xff, 0x08, 0x49, 0xc8, 0x1d, 0x49, 0x30, 0x02, 0x7a, 0x00, 0x2a,
-0x03, 0xd0, 0x07, 0x72, 0x08, 0x1c, 0xff, 0xf7, 0x2d, 0xff, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0, 0x64, 0x2d, 0x00, 0x80,
-0xe4, 0x2c, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c, 0x10, 0x20, 0x18, 0x49,
-0xc0, 0x46, 0x08, 0x60, 0xf8, 0x68, 0x01, 0x30, 0xf8, 0x60, 0x16, 0x48,
-0xc4, 0x1d, 0xb9, 0x34, 0x61, 0x6b, 0x89, 0x00, 0x09, 0x18, 0xc0, 0x31,
-0x09, 0x69, 0x7a, 0x68, 0x92, 0x00, 0xd2, 0x19, 0x51, 0x64, 0x61, 0x6b,
-0x89, 0x00, 0x08, 0x18, 0xc0, 0x30, 0x01, 0x69, 0x78, 0x68, 0x80, 0x00,
-0xc0, 0x19, 0xc0, 0x6b, 0x01, 0xf0, 0xa2, 0xfa, 0x01, 0x23, 0x78, 0x68,
-0x58, 0x40, 0x78, 0x60, 0x60, 0x6b, 0x01, 0x30, 0x80, 0x07, 0x80, 0x0f,
-0x60, 0x63, 0xf8, 0x1d, 0x19, 0x30, 0x40, 0x79, 0x00, 0x28, 0x02, 0xd1,
-0x38, 0x1c, 0x00, 0xf0, 0x07, 0xf8, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80, 0x90, 0xb5, 0x07, 0x1c,
-0x39, 0x48, 0xc0, 0x68, 0x00, 0x28, 0x05, 0xd0, 0xb8, 0x6a, 0xc0, 0x68,
-0x80, 0x09, 0x01, 0xd3, 0x02, 0x20, 0x00, 0xe0, 0x78, 0x6f, 0xfc, 0xf7,
-0x59, 0xf8, 0x04, 0x1c, 0x06, 0xd1, 0x01, 0x20, 0xf9, 0x1d, 0x19, 0x31,
-0x08, 0x71, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf8, 0x6c, 0x2f, 0x49,
-0xc0, 0x46, 0x08, 0x60, 0xba, 0x6a, 0x38, 0x1c, 0x21, 0x1c, 0x00, 0xf0,
-0x59, 0xf8, 0x67, 0x62, 0x00, 0x28, 0x03, 0xd1, 0x20, 0x1c, 0x00, 0xf0,
-0x0b, 0xfd, 0xec, 0xe7, 0xf9, 0x6d, 0x09, 0x68, 0x09, 0x18, 0x09, 0x09,
-0x09, 0x01, 0x7a, 0x6d, 0x8a, 0x42, 0x00, 0xd8, 0x89, 0x1a, 0xa1, 0x62,
-0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x4a, 0x6c, 0x00, 0x2a, 0x07, 0xd0,
-0x4a, 0x6c, 0x12, 0x1a, 0x4a, 0x64, 0x80, 0x08, 0x80, 0x00, 0xb9, 0x6a,
-0x08, 0x18, 0xb8, 0x62, 0x38, 0x68, 0xb9, 0x6a, 0x80, 0x00, 0xc0, 0x19,
-0x42, 0x6b, 0x91, 0x42, 0x0e, 0xd3, 0x00, 0x21, 0x41, 0x64, 0xb8, 0x6a,
-0x39, 0x68, 0x89, 0x00, 0xc9, 0x19, 0x49, 0x6b, 0x40, 0x1a, 0xb8, 0x62,
-0xb9, 0x68, 0x89, 0x00, 0xc9, 0x19, 0xc9, 0x6b, 0x40, 0x18, 0xb8, 0x62,
-0xb8, 0x68, 0x81, 0x00, 0xc9, 0x19, 0x49, 0x6c, 0x00, 0x29, 0xb8, 0xd1,
-0xb9, 0x6a, 0xfa, 0x6b, 0x91, 0x42, 0xb4, 0xd0, 0x3a, 0x6c, 0x91, 0x42,
-0xb1, 0xd0, 0x01, 0x23, 0x58, 0x40, 0xb8, 0x60, 0x80, 0x00, 0xc0, 0x19,
-0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf8, 0x68, 0x00, 0x28, 0x01, 0xd0,
-0x01, 0x38, 0xf8, 0x60, 0x38, 0x69, 0x00, 0x28, 0xa1, 0xd0, 0x01, 0x38,
-0x38, 0x61, 0x9e, 0xe7, 0x68, 0x19, 0x00, 0x80, 0x00, 0x00, 0x00, 0xb0,
-0xf7, 0xb5, 0x90, 0xb0, 0x04, 0x1c, 0x0d, 0x1c, 0x00, 0x20, 0x05, 0x90,
-0x02, 0x90, 0x00, 0x22, 0x01, 0x92, 0xf9, 0x48, 0xc0, 0x6a, 0xc0, 0x46,
-0xa8, 0x61, 0xa0, 0x68, 0x81, 0x00, 0x09, 0x19, 0x49, 0x6b, 0xc0, 0x46,
-0x20, 0x60, 0xe1, 0x62, 0x12, 0x9a, 0xd0, 0x68, 0xc0, 0x46, 0xa8, 0x60,
-0x12, 0x9a, 0x51, 0x78, 0xc0, 0x46, 0x0c, 0x91, 0xf0, 0x48, 0xc0, 0x46,
-0x03, 0x90, 0xd7, 0x1d, 0x09, 0x37, 0xe0, 0x6a,
-0xc1, 0x1b, 0x09, 0x09, 0xe3, 0x1d, 0x19, 0x33, 0x0c, 0x9a, 0xc0, 0x46,
-0x0f, 0x93, 0xeb, 0x4b, 0xc0, 0x46, 0x0e, 0x93, 0x91, 0x42, 0x01, 0xd3,
-0xb8, 0x42, 0x21, 0xd8, 0xe1, 0x68, 0x02, 0x29, 0x1e, 0xd2, 0x01, 0x20,
-0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71, 0x00, 0x20, 0x03, 0x99, 0x01, 0xf0,
-0x57, 0xfb, 0x00, 0x28, 0x03, 0xd1, 0x0e, 0x9b, 0xd8, 0x6b, 0x01, 0x30,
-0xd8, 0x63, 0x01, 0x20, 0x80, 0x06, 0x00, 0x27, 0x68, 0x60, 0xaf, 0x61,
-0xdd, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0xdd, 0x48, 0x01, 0x6d, 0x42, 0x6d,
-0xdc, 0x4b, 0x00, 0x20, 0x01, 0xf0, 0x3a, 0xfb, 0x38, 0x1c, 0x5c, 0xe3,
-0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x7b, 0xfc, 0x07, 0x1c,
-0xd7, 0x48, 0xc0, 0x68, 0x00, 0x28, 0x64, 0xd0, 0x38, 0x78, 0x40, 0x07,
-0x40, 0x0f, 0x03, 0x28, 0x60, 0xd1, 0x05, 0x98, 0x01, 0x30, 0x00, 0x06,
-0x00, 0x0e, 0x05, 0x90, 0x38, 0x78, 0xf0, 0x23, 0x18, 0x40, 0x58, 0xd1,
-0xe0, 0x6a, 0xc0, 0x1b, 0x00, 0x09, 0x0c, 0x99, 0x88, 0x42, 0x02, 0xd2,
-0xe0, 0x68, 0x02, 0x28, 0x05, 0xd3, 0xcb, 0x49, 0x88, 0x68, 0x00, 0xf0,
-0x83, 0xff, 0x06, 0x1c, 0x06, 0xd1, 0x03, 0x9b, 0x28, 0x1c, 0x39, 0x1c,
-0x22, 0x1c, 0x00, 0xf0, 0x8b, 0xfc, 0x16, 0xe1, 0x2e, 0x62, 0xf8, 0x68,
-0x00, 0x28, 0x0d, 0xd0, 0xb8, 0x89, 0x00, 0x28, 0x03, 0xd0, 0xc1, 0x49,
-0xc9, 0x68, 0x00, 0xf0, 0x70, 0xff, 0xf8, 0x89, 0x00, 0x28, 0x03, 0xd0,
-0xbd, 0x49, 0xc9, 0x68, 0x00, 0xf0, 0x69, 0xff, 0x7a, 0x68, 0xc0, 0x46,
-0x72, 0x61, 0xb9, 0x68, 0xc0, 0x46, 0xb1, 0x61, 0x30, 0x1c, 0xb8, 0x49,
-0x09, 0x68, 0x00, 0xf0, 0x5e, 0xff, 0x00, 0x28, 0x17, 0xd1, 0x30, 0x1c,
-0xb4, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x57, 0xff, 0x10, 0x37, 0xe0, 0x6a,
-0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x27, 0xfc, 0x07, 0x1c,
-0x68, 0x68, 0xaf, 0x4b, 0x18, 0x43, 0x68, 0x60, 0x00, 0x20, 0xa8, 0x61,
-0xac, 0x23, 0xa8, 0x68, 0x98, 0x43, 0xa8, 0x60, 0xb0, 0xe0, 0xa8, 0x69,
-0xa8, 0x28, 0x01, 0xd2, 0xa8, 0x20, 0xa8, 0x61, 0x10, 0x37, 0xe0, 0x6a,
-0xb8, 0x42, 0x6c, 0xd8, 0x9c, 0xe0, 0xa5, 0xe0, 0xa4, 0xe0, 0x10, 0x28,
-0x68, 0xd1, 0x03, 0x23, 0x1b, 0x07, 0x68, 0x68, 0x18, 0x40, 0x01, 0x0f,
-0x48, 0x01, 0x40, 0x1a, 0x80, 0x00, 0xa0, 0x4a, 0x82, 0x18, 0x01, 0x92,
-0x78, 0x88, 0x42, 0x0b, 0x31, 0xd3, 0x82, 0x0b, 0x2f, 0xd3, 0x9d, 0x48,
-0xc0, 0x46, 0x03, 0x90, 0x02, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x10, 0x80,
-0x78, 0x88, 0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x60,
-0xb8, 0x68, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, 0x01, 0x9a,
-0xc0, 0x46, 0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x64,
-0x01, 0x9a, 0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x8f, 0x49, 0x40, 0x18,
-0x01, 0x9a, 0xc0, 0x46, 0x50, 0x63, 0x01, 0x9a, 0x50, 0x68, 0x36, 0x30,
-0x94, 0x28, 0x01, 0xd8, 0x38, 0x20, 0x00, 0xe0, 0x94, 0x20, 0xa8, 0x61,
-0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x28, 0xd8, 0x58, 0xe0, 0x7a, 0x88,
-0x92, 0x0b, 0x03, 0xd3, 0x85, 0x48, 0xc0, 0x46, 0x03, 0x90, 0x23, 0xe0,
-0x01, 0x22, 0x12, 0x03, 0x02, 0x40, 0x83, 0x4b, 0x1d, 0xd0, 0x03, 0x93,
-0x00, 0x05, 0x00, 0x0d, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x60, 0xb8, 0x68,
-0x01, 0x9a, 0xc0, 0x46, 0x90, 0x60, 0x78, 0x68, 0x01, 0x9a, 0xc0, 0x46,
-0x10, 0x62, 0x00, 0x20, 0x01, 0x9a, 0xc0, 0x46,
-0x90, 0x64, 0x01, 0x9a, 0xc0, 0x46, 0x90, 0x63, 0x88, 0x02, 0x75, 0x49,
-0x40, 0x18, 0x01, 0x9a, 0xc0, 0x46, 0x50, 0x63, 0x02, 0xe0, 0x33, 0xe0,
-0x2a, 0xe0, 0x03, 0x93, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46, 0x48, 0x71,
-0x12, 0x9a, 0x50, 0x78, 0x05, 0x99, 0x43, 0x1a, 0x0b, 0x93, 0x10, 0x37,
-0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x92, 0xfb,
-0x07, 0x1c, 0x01, 0x9a, 0x50, 0x6b, 0x91, 0x6b, 0x09, 0x01, 0x40, 0x18,
-0x0b, 0x9b, 0x21, 0x1c, 0x3a, 0x1c, 0xff, 0xf7, 0x7d, 0xfb, 0x01, 0x9a,
-0xc0, 0x46, 0xd0, 0x64, 0x01, 0x9a, 0x0b, 0x9b, 0xc0, 0x46, 0x13, 0x65,
-0x01, 0x23, 0x5b, 0x06, 0x68, 0x68, 0x18, 0x43, 0x68, 0x60, 0x00, 0x20,
-0xa8, 0x61, 0x0d, 0xe0, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8,
-0x20, 0x1c, 0x00, 0xf0, 0x71, 0xfb, 0x07, 0x1c, 0x38, 0x78, 0x40, 0x07,
-0x40, 0x0f, 0x03, 0x28, 0x00, 0xd1, 0xf8, 0xe6, 0xa8, 0x69, 0x03, 0x99,
-0x01, 0xf0, 0x26, 0xfa, 0x00, 0x28, 0x2a, 0xd1, 0x38, 0x1c, 0x21, 0x1c,
-0x00, 0xf0, 0x79, 0xfb, 0xa8, 0x68, 0x80, 0x09, 0x04, 0xd3, 0x30, 0x1c,
-0x49, 0x49, 0x49, 0x68, 0x00, 0xf0, 0x81, 0xfe, 0x41, 0x49, 0x00, 0x20,
-0x01, 0xf0, 0x14, 0xfa, 0x00, 0x28, 0x04, 0xd1, 0x0e, 0x9b, 0xd8, 0x6b,
-0x01, 0x30, 0xd8, 0x63, 0x11, 0xe0, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46,
-0x48, 0x71, 0x80, 0x06, 0x00, 0x27, 0x68, 0x60, 0xaf, 0x61, 0x3a, 0x4a,
-0xc0, 0x46, 0x00, 0x92, 0x39, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x39, 0x4b,
-0x00, 0x20, 0x01, 0xf0, 0xf3, 0xf9, 0x00, 0x20, 0x15, 0xe2, 0x05, 0x98,
-0x0c, 0x99, 0x08, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x0c, 0x90, 0x0b, 0x90,
-0x0c, 0x98, 0x00, 0x28, 0x03, 0xd0, 0x01, 0x20, 0x0f, 0x99, 0xc0, 0x46,
-0x48, 0x71, 0x28, 0x68, 0xc0, 0x46, 0x04, 0x90, 0x00, 0x26, 0x00, 0x20,
-0x08, 0x90, 0x00, 0x22, 0x0a, 0x92, 0x0c, 0x98, 0x01, 0x38, 0x0d, 0x90,
-0xa3, 0xe0, 0x78, 0x88, 0x8a, 0x1b, 0x12, 0x04, 0x12, 0x0c, 0x90, 0x42,
-0x05, 0xdd, 0x07, 0x92, 0x80, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x08, 0x90,
-0x00, 0xe0, 0x07, 0x90, 0x08, 0x98, 0x00, 0x28, 0x07, 0xd1, 0x0d, 0x98,
-0x0a, 0x9a, 0x90, 0x42, 0x07, 0xdd, 0x07, 0x98, 0x30, 0x18, 0x88, 0x42,
-0x03, 0xd8, 0x01, 0x20, 0x40, 0x05, 0x06, 0x90, 0x1c, 0xe0, 0x11, 0x20,
-0x40, 0x05, 0x06, 0x90, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd1,
-0x20, 0x48, 0xc0, 0x46, 0x06, 0x90, 0xb1, 0x07, 0x89, 0x0f, 0x0f, 0xd0,
-0x07, 0x98, 0xc0, 0x06, 0xc0, 0x0e, 0x08, 0xd0, 0x1e, 0x28, 0x09, 0xdb,
-0x1e, 0x28, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, 0x01, 0xe0, 0x02, 0x29,
-0x02, 0xd3, 0x01, 0x20, 0x02, 0x90, 0xde, 0xe7, 0x0a, 0x9a, 0x00, 0x2a,
-0x04, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x06, 0x98, 0x18, 0x43, 0x06, 0x90,
-0x07, 0x98, 0x06, 0x99, 0x08, 0x43, 0x02, 0x1c, 0x00, 0x90, 0x04, 0x98,
-0x83, 0x19, 0x1d, 0xe0, 0xe8, 0x0e, 0x00, 0x80, 0x01, 0x49, 0xff, 0xff,
-0x28, 0x0f, 0x00, 0x80, 0x04, 0x00, 0x12, 0x02, 0x7c, 0x29, 0x00, 0x80,
-0x44, 0x80, 0x20, 0x40, 0x68, 0x19, 0x00, 0x80, 0x60, 0x04, 0x00, 0x80,
-0x00, 0x00, 0x00, 0x80, 0x5c, 0x2b, 0x00, 0x80, 0x55, 0x32, 0xff, 0xff,
-0xac, 0x5e, 0x21, 0x40, 0x0d, 0x3d, 0xff, 0xff, 0xcd, 0x31, 0xff, 0xff,
-0x00, 0x00, 0x32, 0x02, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0,
-0x6b, 0xf9, 0x07, 0x98, 0x36, 0x18, 0x02, 0x98,
-0x00, 0x28, 0x16, 0xd0, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x04, 0xd1,
-0x09, 0x23, 0x5b, 0x04, 0x06, 0x98, 0x18, 0x43, 0x06, 0x90, 0x06, 0x98,
-0xc2, 0x4a, 0x02, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0xc1, 0x48,
-0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0x51, 0xf9, 0x00, 0x20,
-0x02, 0x90, 0x08, 0x98, 0x00, 0x28, 0x0b, 0xd1, 0x0b, 0x9b, 0x01, 0x3b,
-0x0b, 0x93, 0x10, 0x37, 0xe0, 0x6a, 0xb8, 0x42, 0x0c, 0xd8, 0x20, 0x1c,
-0x00, 0xf0, 0x8a, 0xfa, 0x07, 0x1c, 0x07, 0xe0, 0x78, 0x68, 0x07, 0x9a,
-0x80, 0x18, 0x78, 0x60, 0x78, 0x88, 0x07, 0x9a, 0x80, 0x1a, 0x78, 0x80,
-0x0a, 0x9a, 0x50, 0x1c, 0x02, 0x04, 0x12, 0x0c, 0x0a, 0x92, 0x0c, 0x98,
-0x0a, 0x9a, 0x82, 0x42, 0x03, 0xda, 0xa9, 0x69, 0xb1, 0x42, 0x00, 0xd9,
-0x53, 0xe7, 0xa8, 0x69, 0xb0, 0x42, 0x6b, 0xd1, 0xa8, 0x68, 0x01, 0x09,
-0x69, 0xd2, 0x08, 0x9a, 0x00, 0x2a, 0x56, 0xd0, 0x0c, 0x99, 0x0a, 0x9a,
-0x8a, 0x42, 0x3e, 0xdb, 0xb1, 0x07, 0x89, 0x0f, 0x0c, 0xd0, 0x08, 0x9a,
-0xd2, 0x06, 0xd2, 0x0e, 0x0b, 0xd0, 0x1e, 0x2a, 0x06, 0xdb, 0x1e, 0x2a,
-0x02, 0xd1, 0x03, 0x29, 0x05, 0xd0, 0x01, 0xe0, 0x02, 0x29, 0x02, 0xd2,
-0x02, 0x99, 0x00, 0x29, 0x21, 0xd0, 0x08, 0x9a, 0xc0, 0x46, 0x00, 0x92,
-0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0,
-0x01, 0xf9, 0x08, 0x98, 0x36, 0x18, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40,
-0x02, 0xd0, 0x01, 0x20, 0x40, 0x06, 0x00, 0xe0, 0x92, 0x48, 0x01, 0x22,
-0x02, 0x43, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x8e, 0x48, 0x01, 0x6d,
-0x42, 0x6d, 0x00, 0x20, 0x01, 0xf0, 0xec, 0xf8, 0x00, 0x20, 0x02, 0x90,
-0x15, 0xe0, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20, 0x40, 0x06,
-0x00, 0xe0, 0x88, 0x48, 0x08, 0x9a, 0x02, 0x43, 0x00, 0xe0, 0x08, 0x9a,
-0xc0, 0x46, 0x00, 0x92, 0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d,
-0x06, 0xca, 0x01, 0xf0, 0xd5, 0xf8, 0x08, 0x98, 0x36, 0x18, 0x10, 0x37,
-0xe0, 0x6a, 0xb8, 0x42, 0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0x14, 0xfa,
-0x07, 0x1c, 0x68, 0x68, 0x80, 0x0e, 0x6b, 0xd2, 0x0a, 0x98, 0xc0, 0x46,
-0x09, 0x90, 0x0c, 0x99, 0x88, 0x42, 0x5c, 0xda, 0x0d, 0x98, 0x09, 0x99,
-0x88, 0x42, 0x03, 0xd0, 0x7a, 0x88, 0x1e, 0xe0, 0x5f, 0xe0, 0x5e, 0xe0,
-0x78, 0x88, 0x01, 0x22, 0x52, 0x06, 0x02, 0x43, 0xa9, 0x68, 0x8c, 0x23,
-0x19, 0x40, 0x02, 0xd1, 0x09, 0x23, 0x5b, 0x04, 0x1a, 0x43, 0xb1, 0x07,
-0x89, 0x0f, 0x0e, 0xd0, 0xc3, 0x06, 0xdb, 0x0e, 0x08, 0xd0, 0x1e, 0x2b,
-0x09, 0xdb, 0x1e, 0x2b, 0x02, 0xd1, 0x03, 0x29, 0x05, 0xd1, 0x01, 0xe0,
-0x02, 0x29, 0x02, 0xd3, 0x01, 0x21, 0x02, 0x91, 0x02, 0x1c, 0x09, 0x98,
-0x00, 0x28, 0x02, 0xd1, 0x01, 0x23, 0xdb, 0x05, 0x1a, 0x43, 0x00, 0x92,
-0x04, 0x98, 0x83, 0x19, 0x00, 0x20, 0x3a, 0x1d, 0x06, 0xca, 0x01, 0xf0,
-0x8f, 0xf8, 0x78, 0x88, 0x86, 0x19, 0x10, 0x37, 0x02, 0x98, 0x00, 0x28,
-0x14, 0xd0, 0xa8, 0x68, 0x8c, 0x23, 0x18, 0x40, 0x02, 0xd0, 0x01, 0x20,
-0x40, 0x06, 0x00, 0xe0, 0x57, 0x48, 0x01, 0x22, 0x02, 0x43, 0x00, 0x92,
-0x04, 0x98, 0x83, 0x19, 0x53, 0x48, 0x01, 0x6d, 0x42, 0x6d, 0x00, 0x20,
-0x01, 0xf0, 0x76, 0xf8, 0x00, 0x20, 0x02, 0x90, 0xe0, 0x6a, 0xb8, 0x42,
-0x03, 0xd8, 0x20, 0x1c, 0x00, 0xf0, 0xb6, 0xf9, 0x07, 0x1c, 0x09, 0x98,
-0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x09, 0x90,
-0x0c, 0x99, 0x88, 0x42, 0xa2, 0xdb, 0x68, 0x68, 0x30, 0x43, 0x01, 0x04,
-0x09, 0x0c, 0x68, 0x60, 0xe8, 0x6a, 0x00, 0xf0, 0x7b, 0xfa, 0x28, 0xe0,
-0x27, 0xe0, 0xa8, 0x68, 0x00, 0x09, 0x14, 0xd3, 0x68, 0x68, 0x80, 0x0e,
-0x15, 0xd2, 0x01, 0x9a, 0x00, 0x2a, 0x12, 0xd0, 0x01, 0x9a, 0x50, 0x6b,
-0x0b, 0x9b, 0x21, 0x1c, 0x3a, 0x1c, 0xff, 0xf7, 0x89, 0xf9, 0x01, 0x9a,
-0xc0, 0x46, 0x90, 0x64, 0x01, 0x9a, 0x0b, 0x9b, 0xc0, 0x46, 0x93, 0x63,
-0x03, 0xe0, 0xe8, 0x6a, 0x31, 0x1c, 0x00, 0xf0, 0x5d, 0xfa, 0x68, 0x68,
-0x30, 0x43, 0x68, 0x60, 0xa8, 0x69, 0xb0, 0x42, 0x05, 0xd9, 0x00, 0x04,
-0x00, 0x0c, 0x80, 0x1b, 0x00, 0xf0, 0xee, 0xf9, 0xae, 0x61, 0xa8, 0x68,
-0x8c, 0x23, 0x18, 0x40, 0x0b, 0xd0, 0x2f, 0x4a, 0xc0, 0x46, 0x00, 0x92,
-0x04, 0x98, 0xc3, 0x1f, 0x05, 0x3b, 0x2a, 0x48, 0x01, 0x6d, 0x42, 0x6d,
-0x00, 0x20, 0x01, 0xf0, 0x23, 0xf8, 0x01, 0x23, 0x9b, 0x07, 0x20, 0x6d,
-0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xa0, 0x61, 0xe1, 0x69, 0x81, 0x42,
-0x12, 0xd0, 0x22, 0x69, 0x02, 0x2a, 0x0f, 0xd2, 0x41, 0x1a, 0x01, 0xd5,
-0x60, 0x6d, 0x41, 0x18, 0x20, 0x1c, 0xff, 0xf7, 0x3f, 0xfb, 0xe1, 0x69,
-0x40, 0x18, 0xe0, 0x61, 0x61, 0x6d, 0x88, 0x42, 0x24, 0xd3, 0x40, 0x1a,
-0xe0, 0x61, 0x21, 0xe0, 0x81, 0x42, 0x1f, 0xd1, 0x20, 0x69, 0x02, 0x28,
-0x1c, 0xd2, 0x01, 0x20, 0x60, 0x61, 0x18, 0x48, 0x41, 0x69, 0xe2, 0x6c,
-0x0a, 0x43, 0x42, 0x61, 0x81, 0x69, 0xe3, 0x6c, 0x99, 0x43, 0x81, 0x61,
-0x01, 0x21, 0x09, 0x05, 0xca, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x08, 0x61,
-0x8b, 0x02, 0x20, 0x6d, 0x18, 0x43, 0x00, 0x68, 0xc0, 0x46, 0xa0, 0x61,
-0xe1, 0x69, 0x81, 0x42, 0x02, 0xd0, 0x20, 0x1c, 0xff, 0xf7, 0xcc, 0xfa,
-0x28, 0x1c, 0x00, 0xf0, 0x0f, 0xf9, 0x0c, 0x98, 0x05, 0x99, 0x40, 0x18,
-0x00, 0x01, 0x10, 0x30, 0x68, 0x61, 0x13, 0xb0, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x7c, 0x29, 0x00, 0x80,
-0x00, 0x00, 0x12, 0x02, 0x04, 0x00, 0x52, 0x02, 0x68, 0x0e, 0x00, 0x80,
-0xf0, 0xb5, 0x40, 0x20, 0x2d, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x00, 0xf0,
-0x03, 0xf9, 0x07, 0x1c, 0x81, 0x69, 0x44, 0x6a, 0xa0, 0x6f, 0x00, 0xf0,
-0x45, 0xfe, 0x00, 0x20, 0xe1, 0x1d, 0x19, 0x31, 0x48, 0x71, 0x79, 0x68,
-0xc9, 0x0e, 0x09, 0xd3, 0xf8, 0x6a, 0x00, 0x01, 0x24, 0x49, 0x40, 0x18,
-0x24, 0x4b, 0xc0, 0x18, 0x01, 0x68, 0x01, 0x39, 0x01, 0x60, 0x36, 0xe0,
-0xe1, 0x6d, 0x09, 0x68, 0x22, 0x6e, 0xc0, 0x46, 0x11, 0x60, 0x20, 0x4e,
-0xf5, 0x1d, 0x79, 0x35, 0x01, 0x23, 0xe9, 0x6b, 0x19, 0x43, 0xe9, 0x63,
-0xb9, 0x6a, 0xe2, 0x6d, 0xc0, 0x46, 0x11, 0x60, 0xb9, 0x6a, 0x22, 0x6e,
-0xc0, 0x46, 0x11, 0x60, 0x61, 0x69, 0x00, 0x29, 0x04, 0xd1, 0xa9, 0x6b,
-0x01, 0x31, 0xa9, 0x63, 0x08, 0x29, 0x07, 0xd3, 0xa8, 0x63, 0x01, 0x20,
-0x00, 0xf0, 0x86, 0xf8, 0xe8, 0x6b, 0x40, 0x08, 0x40, 0x00, 0xe8, 0x63,
-0x78, 0x68, 0x81, 0x0e, 0x0f, 0xd2, 0x0b, 0x23, 0x1b, 0x02, 0xf1, 0x18,
-0xc9, 0x68, 0x00, 0x29, 0x06, 0xd0, 0x00, 0x08, 0x04, 0xd2, 0x20, 0x1c,
-0x39, 0x1c, 0x00, 0xf0, 0x43, 0xf8, 0x02, 0xe0, 0x38, 0x1c, 0x00, 0xf0,
-0x05, 0xfa, 0x38, 0x1c, 0xfb, 0xf7, 0x06, 0xfc, 0x20, 0x1c, 0x00, 0xf0,
-0x0b, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0xb0,
-0xa0, 0x1c, 0x00, 0x80, 0xb4, 0x0c, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x07, 0x1c, 0xf8, 0x1d, 0x19, 0x30,
-0x01, 0x79, 0x00, 0x29, 0x04, 0xd0, 0x00, 0x21, 0x01, 0x71, 0x38, 0x1c,
-0xff, 0xf7, 0x56, 0xfb, 0xf8, 0x68, 0x02, 0x28, 0x0d, 0xd0, 0xb8, 0x68,
-0x80, 0x00, 0xc2, 0x19, 0x50, 0x6c, 0x00, 0x28, 0x11, 0xd0, 0xb8, 0x6a,
-0x41, 0x78, 0x09, 0x01, 0x10, 0x31, 0x52, 0x6b, 0x10, 0x1a, 0x88, 0x42,
-0x05, 0xd3, 0x38, 0x1c, 0xff, 0xf7, 0x42, 0xfb, 0x80, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x38, 0x1c, 0xff, 0xf7, 0x28, 0xfa, 0xf8, 0xe7, 0x78, 0x68,
-0x80, 0x00, 0xc0, 0x19, 0xc0, 0x6b, 0xc0, 0x46, 0xb8, 0x62, 0xf1, 0xe7,
-0xb0, 0xb5, 0x87, 0xb0, 0x0f, 0x1c, 0x80, 0x6f, 0xc0, 0x46, 0x00, 0x90,
-0x00, 0x24, 0x13, 0x4d, 0x0b, 0x23, 0x1b, 0x02, 0xe8, 0x18, 0x80, 0x69,
-0x00, 0x28, 0x17, 0xd0, 0x69, 0x46, 0xa2, 0x00, 0x52, 0x19, 0x0b, 0x23,
-0x1b, 0x02, 0xd2, 0x18, 0x92, 0x69, 0x38, 0x1c, 0x00, 0xf0, 0x92, 0xfb,
-0x00, 0x28, 0x09, 0xd1, 0x01, 0x34, 0xa0, 0x00, 0x40, 0x19, 0x0b, 0x23,
-0x1b, 0x02, 0xc0, 0x18, 0x80, 0x69, 0x00, 0x28, 0xea, 0xd1, 0x01, 0xe0,
-0x01, 0x28, 0x02, 0xd0, 0x38, 0x1c, 0x00, 0xf0, 0x9d, 0xf9, 0x07, 0xb0,
-0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0xb8, 0xb5, 0xc2, 0x07, 0xd2, 0x0f, 0x16, 0x4c, 0x16, 0x49, 0x01, 0xd0,
-0x08, 0x22, 0x08, 0xe0, 0x82, 0x08, 0x05, 0xd3, 0x0c, 0x22, 0xa4, 0x18,
-0x0b, 0x68, 0xdf, 0x1d, 0x15, 0x37, 0x03, 0xe0, 0x1c, 0x22, 0x0b, 0x68,
-0xdf, 0x1d, 0x09, 0x37, 0x0f, 0x4b, 0x1d, 0x78, 0x00, 0x2d, 0x13, 0xd0,
-0x5b, 0x78, 0x00, 0x2b, 0x10, 0xd0, 0x01, 0x23, 0x5b, 0x06, 0x1a, 0x43,
-0x00, 0x28, 0x01, 0xd1, 0x5b, 0x08, 0x1a, 0x43, 0x00, 0x92, 0x4a, 0x68,
-0x01, 0x20, 0x39, 0x1c, 0x23, 0x1c, 0x00, 0xf0, 0xdf, 0xfe, 0xb8, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x03, 0x23, 0x1b, 0x06, 0x1a, 0x43, 0xf1, 0xe7,
-0x90, 0xee, 0x20, 0x40, 0x7c, 0x29, 0x00, 0x80, 0xf8, 0x0e, 0x00, 0x80,
-0x00, 0x21, 0xc1, 0x61, 0x05, 0x49, 0x8a, 0x68, 0x00, 0x2a, 0x01, 0xd1,
-0x88, 0x60, 0x02, 0xe0, 0xca, 0x68, 0xc0, 0x46, 0xd0, 0x61, 0xc8, 0x60,
-0x70, 0x47, 0x00, 0x00, 0x28, 0x0f, 0x00, 0x80, 0x03, 0x49, 0x88, 0x68,
-0x00, 0x28, 0x02, 0xd0, 0xc2, 0x69, 0xc0, 0x46, 0x8a, 0x60, 0x70, 0x47,
-0x28, 0x0f, 0x00, 0x80, 0x01, 0x1c, 0x01, 0x23, 0x88, 0x68, 0x58, 0x40,
-0x88, 0x60, 0xca, 0x68, 0x01, 0x3a, 0xca, 0x60, 0x0a, 0x69, 0x01, 0x3a,
-0x80, 0x00, 0x0a, 0x61, 0x42, 0x18, 0xd0, 0x6b, 0x53, 0x6b, 0xc0, 0x46,
-0xcb, 0x62, 0x0b, 0x68, 0x9b, 0x00, 0x59, 0x18, 0x49, 0x6c, 0x53, 0x6c,
-0xc9, 0x18, 0x51, 0x64, 0x70, 0x47, 0x8a, 0x68, 0x92, 0x00, 0x52, 0x18,
-0xd3, 0x6b, 0x83, 0x42, 0x17, 0xd1, 0xd0, 0x1d, 0x3d, 0x30, 0x0a, 0x68,
-0x92, 0x00, 0x52, 0x18, 0x52, 0x6c, 0x03, 0x68, 0x9a, 0x1a, 0x02, 0x60,
-0x01, 0x23, 0x88, 0x68, 0x58, 0x40, 0x88, 0x60, 0xca, 0x68, 0x01, 0x32,
-0xca, 0x60, 0x0a, 0x69, 0x01, 0x32, 0x80, 0x00, 0x40, 0x18, 0x0a, 0x61,
-0x40, 0x6b, 0xc0, 0x46, 0xc8, 0x62, 0x70, 0x47, 0xb8, 0xb5, 0x04, 0x1c,
-0x1d, 0x1c, 0x17, 0x1c, 0x08, 0x1c, 0x39, 0x1c, 0xff, 0xf7, 0xd9, 0xff,
-0x00, 0x20, 0x29, 0x1c, 0x00, 0xf0, 0x7c, 0xfe, 0x01, 0x20, 0xf9, 0x1d,
-0x19, 0x31, 0x48, 0x71, 0x80, 0x06, 0x60, 0x60, 0x00, 0x20, 0xa0, 0x61,
-0x06, 0x4a, 0xc0, 0x46, 0x00, 0x92, 0x06, 0x48,
-0x01, 0x6d, 0x42, 0x6d, 0x05, 0x4b, 0x00, 0x20, 0x00, 0xf0, 0x62, 0xfe,
-0xb8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x04, 0x00, 0x12, 0x02,
-0x7c, 0x29, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40, 0x06, 0x49, 0x0a, 0x68,
-0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9,
-0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0x00, 0x00,
-0xe4, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40, 0x80, 0x08, 0x80, 0x00,
-0x06, 0x49, 0x0a, 0x68, 0x10, 0x18, 0x08, 0x60, 0x01, 0x23, 0x5b, 0x02,
-0x98, 0x42, 0x03, 0xd9, 0x03, 0x49, 0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71,
-0x70, 0x47, 0x00, 0x00, 0xe4, 0x2d, 0x00, 0x80, 0xa0, 0x82, 0x20, 0x40,
-0x03, 0x30, 0x80, 0x08, 0x80, 0x00, 0x06, 0x49, 0x0a, 0x68, 0x10, 0x18,
-0x08, 0x60, 0x01, 0x23, 0x5b, 0x02, 0x98, 0x42, 0x03, 0xd9, 0x03, 0x49,
-0x0a, 0x79, 0x01, 0x32, 0x0a, 0x71, 0x70, 0x47, 0xe4, 0x2d, 0x00, 0x80,
-0xa0, 0x82, 0x20, 0x40, 0x02, 0x48, 0x41, 0x79, 0x01, 0x31, 0x41, 0x71,
-0x70, 0x47, 0x00, 0x00, 0xa0, 0x82, 0x20, 0x40, 0x90, 0xb4, 0x82, 0x00,
-0x17, 0x4b, 0x9a, 0x58, 0x8b, 0x07, 0x02, 0xd0, 0x89, 0x08, 0x0b, 0x1d,
-0x01, 0xe0, 0x89, 0x08, 0xcb, 0x1c, 0x11, 0x69, 0xd7, 0x68, 0x12, 0x4c,
-0x80, 0x00, 0x20, 0x58, 0x40, 0x68, 0xb9, 0x42, 0x03, 0xd1, 0x81, 0x42,
-0x19, 0xd9, 0x11, 0x68, 0x17, 0xe0, 0x00, 0x24, 0xb9, 0x42, 0x09, 0xd9,
-0x81, 0x42, 0x12, 0xd9, 0x11, 0x68, 0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30,
-0x80, 0x10, 0x98, 0x42, 0x0b, 0xd8, 0x07, 0xe0, 0x81, 0x42, 0x05, 0xd8,
-0x78, 0x1a, 0x00, 0xd5, 0x03, 0x30, 0x80, 0x10, 0x98, 0x42, 0x02, 0xd8,
-0x20, 0x1c, 0x90, 0xbc, 0x70, 0x47, 0xc8, 0x1d, 0x05, 0x30, 0xfa, 0xe7,
-0x70, 0x04, 0x00, 0x80, 0x80, 0xb5, 0x80, 0x00, 0x0f, 0x4a, 0x17, 0x58,
-0x88, 0x07, 0x02, 0xd0, 0x88, 0x08, 0x04, 0x30, 0x01, 0xe0, 0x88, 0x08,
-0x03, 0x30, 0x39, 0x69, 0x7a, 0x68, 0x91, 0x42, 0x09, 0xd9, 0x39, 0x68,
-0xc0, 0x46, 0x39, 0x61, 0xf9, 0x68, 0x7a, 0x68, 0x91, 0x42, 0x02, 0xd9,
-0x39, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x81, 0x00, 0x38, 0x69, 0x00, 0xf0,
-0xd1, 0xfd, 0x38, 0x61, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x70, 0x04, 0x00, 0x80, 0x90, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x01, 0x40,
-0x0c, 0x0f, 0x01, 0x04, 0x09, 0x0c, 0x01, 0x22, 0x92, 0x07, 0x02, 0x40,
-0xa3, 0x00, 0x1c, 0x4f, 0xff, 0x58, 0x89, 0x07, 0x89, 0x0f, 0x00, 0x04,
-0x00, 0x0c, 0x80, 0x08, 0x00, 0x29, 0x00, 0xd0, 0x01, 0x30, 0x00, 0x2a,
-0x01, 0xd0, 0x02, 0x30, 0x00, 0xe0, 0x03, 0x30, 0xf9, 0x68, 0x7a, 0x68,
-0x91, 0x42, 0x02, 0xd9, 0x39, 0x68, 0xc0, 0x46, 0xf9, 0x60, 0x81, 0x00,
-0xf8, 0x68, 0x00, 0xf0, 0xa5, 0xfd, 0xf8, 0x60, 0x0f, 0x48, 0x00, 0x69,
-0x00, 0x28, 0x05, 0xd0, 0x01, 0x20, 0xa0, 0x40, 0x02, 0xd0, 0x20, 0x1c,
-0xfe, 0xf7, 0xca, 0xfc, 0x0b, 0x49, 0xc8, 0x1d, 0x19, 0x30, 0x03, 0x79,
-0x00, 0x22, 0x00, 0x2b, 0x05, 0xd1, 0x09, 0x49, 0xc8, 0x1d, 0x19, 0x30,
-0x03, 0x79, 0x00, 0x2b, 0x03, 0xd0, 0x02, 0x71, 0x08, 0x1c, 0xff, 0xf7,
-0x79, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x70, 0x04, 0x00, 0x80,
-0xd0, 0x2c, 0x00, 0x80, 0x64, 0x2d, 0x00, 0x80, 0xe4, 0x2c, 0x00, 0x80,
-0xb0, 0xb5, 0x2b, 0x49, 0x09, 0x79, 0x00, 0x29, 0x03, 0xd1, 0x41, 0x68,
-0x29, 0x4b, 0x19, 0x43, 0x41, 0x60, 0x81, 0x68,
-0x49, 0x08, 0x02, 0xd3, 0x09, 0x21, 0x09, 0x04, 0x01, 0xe0, 0x0d, 0x21,
-0x09, 0x04, 0x0c, 0xc8, 0x08, 0x38, 0x19, 0x43, 0x87, 0x68, 0xbb, 0x0a,
-0x03, 0xd3, 0x43, 0x68, 0x5b, 0x08, 0x00, 0xd3, 0x01, 0x31, 0x40, 0x68,
-0x03, 0x23, 0x1b, 0x07, 0x18, 0x40, 0x07, 0x0f, 0xf8, 0x00, 0x1d, 0x4c,
-0x00, 0x19, 0x23, 0x68, 0xc0, 0x18, 0x50, 0x30, 0x00, 0x79, 0x01, 0x28,
-0x10, 0xd1, 0x60, 0x68, 0x01, 0x28, 0x0d, 0xd0, 0x10, 0x1c, 0x00, 0xf0,
-0x71, 0xf8, 0x38, 0x01, 0x00, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18,
-0x41, 0x6b, 0x01, 0x39, 0x41, 0x63, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x38, 0x01, 0x00, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x03, 0x6b,
-0x5d, 0x1c, 0x05, 0x63, 0xbd, 0x02, 0x2d, 0x19, 0xdb, 0x00, 0xeb, 0x18,
-0x80, 0x33, 0x19, 0x63, 0xda, 0x62, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63,
-0x01, 0x21, 0xb9, 0x40, 0x22, 0x68, 0x11, 0x43, 0x21, 0x60, 0x01, 0x6b,
-0x80, 0x29, 0xe2, 0xd3, 0x00, 0x21, 0x01, 0x63, 0xdf, 0xe7, 0x00, 0x00,
-0x28, 0x0f, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0xa0, 0x1c, 0x00, 0x80,
-0xf0, 0xb5, 0x1f, 0x4e, 0x70, 0x68, 0x00, 0x28, 0x36, 0xd1, 0x00, 0x24,
-0xb1, 0x68, 0x48, 0x1c, 0xc9, 0x00, 0x89, 0x19, 0xb0, 0x60, 0x32, 0x68,
-0x89, 0x18, 0x60, 0x31, 0x0d, 0x7b, 0x08, 0x28, 0x00, 0xd3, 0xb4, 0x60,
-0x28, 0x01, 0x80, 0x19, 0x19, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x87, 0x6b,
-0x00, 0x2f, 0x21, 0xd0, 0xc1, 0x6a, 0x4b, 0x1c, 0xaa, 0x02, 0x92, 0x19,
-0xc9, 0x00, 0x51, 0x18, 0x80, 0x31, 0xc3, 0x62, 0xca, 0x6a, 0x09, 0x6b,
-0x01, 0x3f, 0x87, 0x63, 0x80, 0x2b, 0x00, 0xd3, 0xc4, 0x62, 0x00, 0x2f,
-0x06, 0xd1, 0x01, 0x27, 0xaf, 0x40, 0x3b, 0x1c, 0xdb, 0x43, 0x37, 0x68,
-0x3b, 0x40, 0x33, 0x60, 0x43, 0x6b, 0x01, 0x3b, 0x43, 0x63, 0x10, 0x1c,
-0x37, 0x1c, 0x00, 0xf0, 0x09, 0xf8, 0x78, 0x68, 0x00, 0x28, 0xc9, 0xd0,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa0, 0x1c, 0x00, 0x80,
-0xf0, 0xb5, 0xcd, 0x0f, 0xed, 0x07, 0x01, 0x24, 0x00, 0x27, 0x2e, 0x4b,
-0x2e, 0x4a, 0x00, 0x2d, 0x1d, 0xd0, 0xd8, 0x6a, 0x01, 0x30, 0xd8, 0x62,
-0x10, 0x1c, 0x52, 0x69, 0x00, 0x2a, 0x12, 0xd0, 0x02, 0x69, 0x53, 0x1c,
-0x92, 0x00, 0x12, 0x18, 0x03, 0x61, 0x91, 0x61, 0x41, 0x69, 0x01, 0x31,
-0x41, 0x61, 0x02, 0x69, 0x0f, 0x2a, 0x00, 0xd3, 0x07, 0x61, 0x0f, 0x29,
-0x00, 0xd3, 0x44, 0x60, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x08, 0x1c,
-0xff, 0xf7, 0xee, 0xfe, 0xf8, 0xe7, 0x15, 0x69, 0x6e, 0x1c, 0xad, 0x00,
-0xad, 0x18, 0x16, 0x61, 0xa9, 0x61, 0x55, 0x69, 0x01, 0x35, 0x55, 0x61,
-0x16, 0x69, 0x0f, 0x2e, 0x00, 0xd3, 0x17, 0x61, 0x0f, 0x2d, 0x00, 0xd3,
-0x54, 0x60, 0x8c, 0x02, 0xa4, 0x0a, 0x16, 0x4f, 0x3a, 0x6f, 0xfd, 0x68,
-0xf9, 0x1d, 0x79, 0x31, 0x01, 0x2d, 0x0c, 0xd1, 0xdb, 0x6d, 0x5b, 0x08,
-0x09, 0xd3, 0x0b, 0x89, 0x00, 0x2b, 0x06, 0xd1, 0xfd, 0x6f, 0x03, 0x3b,
-0x2e, 0x68, 0x33, 0x40, 0x2b, 0x60, 0x14, 0x23, 0x0b, 0x81, 0x10, 0x60,
-0x80, 0x07, 0x80, 0x0a, 0x20, 0x43, 0x03, 0x04, 0x00, 0xd0, 0x01, 0x38,
-0x50, 0x60, 0x09, 0x6a, 0x08, 0x32, 0x91, 0x42, 0x00, 0xd8, 0x07, 0x4a,
-0x00, 0x0d, 0x02, 0xd3, 0x51, 0x20, 0x80, 0x03, 0x82, 0x61, 0x3a, 0x67,
-0xbe, 0xe7, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80, 0xa0, 0x1c, 0x00, 0x80,
-0x68, 0x0e, 0x00, 0x80, 0x24, 0xa7, 0x20, 0x40,
-0xb0, 0xb5, 0x00, 0x28, 0x04, 0xd1, 0x01, 0x20, 0xc0, 0x05, 0x16, 0x49,
-0xc0, 0x46, 0x08, 0x60, 0x15, 0x4c, 0x00, 0x25, 0x67, 0x69, 0x00, 0x2f,
-0x16, 0xd0, 0xe0, 0x68, 0x41, 0x1c, 0x80, 0x00, 0x00, 0x19, 0xe1, 0x60,
-0x80, 0x69, 0x01, 0x3f, 0xff, 0xf7, 0x94, 0xfe, 0xe0, 0x68, 0x0f, 0x28,
-0x00, 0xd3, 0xe5, 0x60, 0xe0, 0x68, 0x80, 0x00, 0x00, 0x19, 0x80, 0x69,
-0x00, 0x08, 0x01, 0xd3, 0x00, 0x2f, 0xea, 0xd1, 0x67, 0x61, 0x03, 0xe0,
-0x08, 0x48, 0x01, 0x6d, 0x01, 0x31, 0x01, 0x65, 0x65, 0x60, 0x20, 0x68,
-0x00, 0x28, 0x01, 0xd0, 0xff, 0xf7, 0x26, 0xff, 0xb0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xa0, 0x1c, 0x00, 0x80,
-0xa0, 0x82, 0x20, 0x40, 0x00, 0x20, 0x70, 0x47, 0xb0, 0xb4, 0x10, 0x23,
-0x82, 0x68, 0x13, 0x40, 0x00, 0x21, 0x00, 0x2b, 0x15, 0xd0, 0x0c, 0x4b,
-0x1a, 0x40, 0x12, 0x01, 0x81, 0x24, 0x14, 0x43, 0x02, 0x68, 0x15, 0x68,
-0x13, 0x1d, 0x80, 0xcb, 0x1b, 0x68, 0x04, 0x3a, 0x02, 0x60, 0x20, 0xc2,
-0x80, 0xc2, 0x08, 0xc2, 0x14, 0x60, 0x42, 0x68, 0x01, 0x23, 0x9b, 0x07,
-0x04, 0x32, 0x1a, 0x43, 0x42, 0x60, 0x08, 0x1c, 0xb0, 0xbc, 0x70, 0x47,
-0x00, 0xf0, 0xff, 0x0f, 0xf0, 0xb4, 0x82, 0x68, 0x53, 0x09, 0x34, 0xd3,
-0x1b, 0x4b, 0x1a, 0x40, 0x12, 0x01, 0x81, 0x26, 0x16, 0x43, 0x03, 0x68,
-0x1d, 0x68, 0x1f, 0x1d, 0x10, 0xcf, 0x3f, 0x68, 0x04, 0x3b, 0x03, 0x60,
-0x20, 0xc3, 0x10, 0xc3, 0x80, 0xc3, 0x1e, 0x60, 0x43, 0x68, 0x1f, 0x1d,
-0x01, 0x23, 0x9b, 0x07, 0x3b, 0x43, 0x43, 0x60, 0xcb, 0x6b, 0x18, 0x1f,
-0xc8, 0x63, 0x80, 0xcb, 0x80, 0xc0, 0x1c, 0x68, 0x1f, 0x1d, 0x03, 0x1d,
-0x04, 0x60, 0x38, 0x1c, 0x3f, 0x68, 0xc0, 0x46, 0x1f, 0x60, 0x1f, 0x1d,
-0x43, 0x68, 0x1c, 0x04, 0x24, 0x0c, 0x81, 0x23, 0x23, 0x43, 0x3b, 0x60,
-0x40, 0x68, 0x00, 0x0c, 0x00, 0x04, 0x10, 0x43, 0x78, 0x60, 0x08, 0x6e,
-0x04, 0x30, 0x08, 0x66, 0x48, 0x6e, 0x04, 0x30, 0x48, 0x66, 0x00, 0x20,
-0xf0, 0xbc, 0x70, 0x47, 0x00, 0xf0, 0xff, 0x0f, 0x80, 0xb4, 0x81, 0x6a,
-0x01, 0x23, 0x9b, 0x07, 0xca, 0x1d, 0x05, 0x32, 0x1a, 0x43, 0x12, 0x68,
-0xcf, 0x1d, 0x01, 0x37, 0x3b, 0x43, 0x1b, 0x68, 0xc0, 0x46, 0xcb, 0x60,
-0x01, 0x23, 0x9b, 0x07, 0x0f, 0x1d, 0x3b, 0x43, 0x1b, 0x68, 0xc0, 0x46,
-0x8b, 0x60, 0x01, 0x23, 0x9b, 0x07, 0x0b, 0x43, 0x1b, 0x68, 0x0c, 0xc1,
-0x02, 0x62, 0x01, 0x6b, 0xc0, 0x46, 0x0a, 0x62, 0x04, 0x23, 0x81, 0x69,
-0x19, 0x43, 0x81, 0x61, 0x02, 0x6b, 0xc0, 0x46, 0x91, 0x61, 0x81, 0x6a,
-0x04, 0x31, 0x81, 0x62, 0x02, 0x6b, 0xc0, 0x46, 0x91, 0x62, 0xc1, 0x1d,
-0x39, 0x31, 0x4a, 0x8b, 0x04, 0x3a, 0x4a, 0x83, 0x49, 0x8b, 0x02, 0x6b,
-0x40, 0x32, 0x51, 0x83, 0xc1, 0x89, 0x04, 0x39, 0xc1, 0x81, 0xc1, 0x68,
-0x00, 0x6b, 0xc0, 0x46, 0xc1, 0x60, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47,
-0x00, 0x47, 0x08, 0x47, 0x10, 0x47, 0x18, 0x47, 0x20, 0x47, 0x28, 0x47,
-0x30, 0x47, 0x38, 0x47, 0x30, 0x40, 0x2d, 0xe9, 0x0c, 0xc0, 0x9d, 0xe5,
-0x0c, 0x48, 0xa0, 0xe1, 0x24, 0x48, 0xb0, 0xe1, 0x1e, 0x00, 0x00, 0x0a,
-0x01, 0xc0, 0x4c, 0xe2, 0x18, 0x40, 0xa0, 0xe3, 0x64, 0x51, 0x9f, 0xe5,
-0x94, 0x50, 0x20, 0xe0, 0x00, 0x50, 0x90, 0xe5, 0x14, 0x40, 0x90, 0xe5,
-0x00, 0x30, 0x85, 0xe5, 0x04, 0xc0, 0x85, 0xe5, 0x08, 0x10, 0x85, 0xe5,
-0x0c, 0x20, 0x85, 0xe5, 0x10, 0x10, 0x90, 0xe5,
-0x10, 0x50, 0x85, 0xe2, 0x01, 0x00, 0x55, 0xe1, 0x0c, 0x50, 0x90, 0x55,
-0x04, 0x00, 0x55, 0xe1, 0x05, 0x00, 0x00, 0x0a, 0x04, 0x10, 0x90, 0xe5,
-0x00, 0x50, 0x80, 0xe5, 0x00, 0x50, 0x81, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
-0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x00, 0x30, 0x93, 0xe5,
-0x08, 0x20, 0x90, 0xe5, 0x01, 0x31, 0x83, 0xe3, 0x02, 0x36, 0x83, 0xe3,
-0x03, 0x00, 0x55, 0xe1, 0x14, 0x30, 0x80, 0xe5, 0xf2, 0xff, 0xff, 0x1a,
-0x01, 0x00, 0xa0, 0xe3, 0xf4, 0xff, 0xff, 0xea, 0x01, 0x06, 0x1c, 0xe3,
-0xf1, 0xff, 0xff, 0x0a, 0xec, 0x10, 0x9f, 0xe5, 0x02, 0xc6, 0xcc, 0xe3,
-0x54, 0x20, 0x91, 0xe5, 0xe4, 0x30, 0x9f, 0xe5, 0x50, 0x10, 0x91, 0xe5,
-0xd9, 0xff, 0xff, 0xea, 0xf0, 0x47, 0x2d, 0xe9, 0x20, 0xc0, 0x9d, 0xe5,
-0x0c, 0x68, 0xa0, 0xe1, 0x26, 0x68, 0xb0, 0xe1, 0x25, 0x00, 0x00, 0x0a,
-0x18, 0x40, 0xa0, 0xe3, 0xb8, 0x50, 0x9f, 0xe5, 0x94, 0x00, 0x00, 0xe0,
-0x05, 0x00, 0x80, 0xe0, 0x08, 0x40, 0x90, 0xe5, 0x04, 0x80, 0x90, 0xe5,
-0x00, 0x70, 0xa0, 0xe3, 0x1f, 0xc0, 0xa0, 0xe3, 0x02, 0xc4, 0x8c, 0xe3,
-0x00, 0x50, 0x90, 0xe5, 0x10, 0x90, 0x90, 0xe5, 0x14, 0xa0, 0x90, 0xe5,
-0x00, 0x30, 0x85, 0xe5, 0x04, 0xc0, 0x85, 0xe5, 0x08, 0x10, 0x85, 0xe5,
-0x0c, 0x20, 0x85, 0xe5, 0x10, 0x50, 0x85, 0xe2, 0x09, 0x00, 0x55, 0xe1,
-0x0c, 0x50, 0x90, 0x55, 0x0a, 0x00, 0x55, 0xe1, 0x15, 0x00, 0x00, 0x0a,
-0x03, 0x70, 0x17, 0xe2, 0x20, 0x10, 0x81, 0xe2, 0x20, 0x30, 0x83, 0xe2,
-0x0a, 0x00, 0x00, 0x0a, 0x00, 0x60, 0x96, 0xe2, 0x01, 0x70, 0x87, 0xe2,
-0x09, 0x00, 0x00, 0x0a, 0x20, 0x60, 0x46, 0xe2, 0x20, 0x00, 0x56, 0xe3,
-0xec, 0xff, 0xff, 0xca, 0x00, 0x70, 0xa0, 0xe3, 0x01, 0xc0, 0x46, 0xe2,
-0x02, 0xc4, 0x8c, 0xe3, 0x00, 0x60, 0xa0, 0xe3, 0xe7, 0xff, 0xff, 0xea,
-0x00, 0x50, 0x88, 0xe5, 0xf2, 0xff, 0xff, 0xea, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x50, 0x80, 0xe5, 0x01, 0x00, 0xa0, 0xe1, 0xf0, 0x47, 0xbd, 0xe8,
-0x1e, 0xff, 0x2f, 0xe1, 0x00, 0xa0, 0x94, 0xe5, 0x0a, 0x00, 0x55, 0xe1,
-0x14, 0xa0, 0x80, 0xe5, 0xe5, 0xff, 0xff, 0x1a, 0x01, 0x10, 0xa0, 0xe3,
-0xf5, 0xff, 0xff, 0xea, 0xa8, 0x03, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80,
-0x00, 0x80, 0x20, 0x40, 0x68, 0x82, 0x9f, 0xe5, 0x0b, 0x92, 0xa0, 0xe3,
-0x64, 0xa2, 0x9f, 0xe5, 0x58, 0xb0, 0x9a, 0xe5, 0x0e, 0xf0, 0xa0, 0xe1,
-0x54, 0xb0, 0x9a, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0x3f, 0x40, 0x2d, 0xe9,
-0x00, 0x00, 0x4f, 0xe1, 0x1f, 0x00, 0x00, 0xe2, 0x12, 0x00, 0x50, 0xe3,
-0x54, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0f, 0xe1, 0x80, 0x00, 0xc0, 0xe3,
-0x00, 0xf0, 0x21, 0xe1, 0x04, 0x50, 0xa0, 0xe3, 0x00, 0x40, 0x99, 0xe5,
-0x09, 0x00, 0x00, 0xea, 0x02, 0x00, 0x14, 0xe3, 0x53, 0x00, 0x00, 0x1b,
-0x80, 0x00, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 0x20, 0x00, 0x14, 0xe3,
-0x59, 0x00, 0x00, 0x1b, 0x02, 0x07, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b,
-0x01, 0x06, 0x14, 0xe3, 0x59, 0x00, 0x00, 0x1b, 0x08, 0x00, 0x14, 0xe3,
-0x45, 0x00, 0x00, 0x1b, 0x02, 0x05, 0x14, 0xe3, 0x4a, 0x00, 0x00, 0x1b,
-0x02, 0x08, 0x14, 0xe3, 0x4b, 0x00, 0x00, 0x1b, 0xe5, 0x0e, 0x14, 0xe3,
-0x07, 0x00, 0x00, 0x0a, 0x04, 0x20, 0x98, 0xe5, 0x0c, 0x10, 0x98, 0xe5,
-0x04, 0x30, 0x52, 0xe2, 0x3c, 0x30, 0xa0, 0xb3, 0x04, 0x30, 0x88, 0xe5,
-0x02, 0x00, 0x91, 0xe7, 0x0f, 0xe0, 0xa0, 0xe1,
-0x10, 0xff, 0x2f, 0xe1, 0x01, 0x50, 0x55, 0xe2, 0x03, 0x00, 0x00, 0x0a,
-0x00, 0x40, 0x99, 0xe5, 0x0c, 0x00, 0x9a, 0xe5, 0x00, 0x00, 0x14, 0xe1,
-0x1b, 0xff, 0x2f, 0x11, 0x08, 0x00, 0x9a, 0xe5, 0x00, 0x00, 0x14, 0xe1,
-0x0b, 0x00, 0x00, 0x0a, 0x01, 0x0c, 0x14, 0xe3, 0x98, 0x01, 0x9f, 0x15,
-0x0f, 0xe0, 0xa0, 0x11, 0x10, 0xff, 0x2f, 0x11, 0x02, 0x04, 0x14, 0xe3,
-0x8c, 0x01, 0x9f, 0x15, 0x0f, 0xe0, 0xa0, 0x11, 0x10, 0xff, 0x2f, 0x11,
-0x01, 0x09, 0x14, 0xe3, 0x80, 0x01, 0x9f, 0x15, 0x0f, 0xe0, 0xa0, 0x11,
-0x10, 0xff, 0x2f, 0x11, 0x04, 0x00, 0x9a, 0xe5, 0x00, 0x00, 0x14, 0xe1,
-0x16, 0x00, 0x00, 0x0a, 0x54, 0xe0, 0x8f, 0xe2, 0x04, 0x00, 0x14, 0xe3,
-0x40, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 0x02, 0x0a, 0x14, 0xe3,
-0x44, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 0x02, 0x09, 0x14, 0xe3,
-0x48, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 0x01, 0x02, 0x14, 0xe3,
-0x4c, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 0x01, 0x04, 0x14, 0xe3,
-0x50, 0x00, 0x9a, 0x15, 0x10, 0xff, 0x2f, 0x11, 0x01, 0x0a, 0x14, 0xe3,
-0x21, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x14, 0xe3, 0x0e, 0x00, 0x00, 0x1b,
-0x10, 0x00, 0x9a, 0xe5, 0x00, 0x00, 0x14, 0xe1, 0x1c, 0x00, 0x00, 0x1b,
-0x00, 0x40, 0x99, 0xe5, 0x04, 0x50, 0xa0, 0xe3, 0x00, 0x40, 0x94, 0xe2,
-0x1b, 0xff, 0x2f, 0x11, 0x3f, 0x40, 0xbd, 0xe8, 0x04, 0xf0, 0x5e, 0xe2,
-0xc0, 0x00, 0x80, 0xe3, 0x00, 0xf0, 0x61, 0xe1, 0xfa, 0xff, 0xff, 0xea,
-0x18, 0x00, 0x9a, 0xe5, 0x1c, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1,
-0x54, 0xb0, 0x9a, 0xe5, 0x1c, 0x10, 0x9a, 0xe5, 0x14, 0x00, 0x9a, 0xe5,
-0x11, 0xff, 0x2f, 0xe1, 0x20, 0x10, 0x9a, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
-0x11, 0xff, 0x2f, 0xe1, 0x24, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1,
-0x28, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x2c, 0x10, 0x9a, 0xe5,
-0x11, 0xff, 0x2f, 0xe1, 0x30, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1,
-0x34, 0x10, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0xfe, 0xff, 0xff, 0xea,
-0x38, 0xe0, 0x9a, 0xe5, 0x3c, 0x10, 0x9a, 0xe5, 0x18, 0x00, 0x9a, 0xe5,
-0x11, 0xff, 0x2f, 0xe1, 0x38, 0xe0, 0x9a, 0xe5, 0x3c, 0x10, 0x9a, 0xe5,
-0x14, 0x00, 0x9a, 0xe5, 0x11, 0xff, 0x2f, 0xe1, 0x64, 0x20, 0x9f, 0xe5,
-0x00, 0x30, 0x92, 0xe5, 0x00, 0x30, 0x53, 0xe0, 0x0a, 0x00, 0x00, 0xba,
-0x00, 0x30, 0x82, 0xe5, 0x0c, 0x00, 0x92, 0xe5, 0x08, 0x30, 0x92, 0xe5,
-0x00, 0x10, 0x91, 0xe2, 0x03, 0x00, 0x00, 0x0a, 0x03, 0x10, 0x80, 0xe7,
-0x04, 0x30, 0x53, 0xe2, 0x3c, 0x30, 0xa0, 0xb3, 0x08, 0x30, 0x82, 0xe5,
-0x01, 0x00, 0xa0, 0xe3, 0x1e, 0xff, 0x2f, 0xe1, 0x3c, 0x10, 0x9f, 0xe5,
-0x00, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x80, 0xe2, 0x00, 0x00, 0x81, 0xe5,
-0x00, 0x00, 0xa0, 0xe3, 0xf8, 0xff, 0xff, 0xea, 0x10, 0x00, 0x9f, 0xe5,
-0x08, 0x10, 0x90, 0xe5, 0x04, 0x10, 0x51, 0xe2, 0x3c, 0x10, 0xa0, 0xb3,
-0x08, 0x10, 0x80, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xe4, 0x2d, 0x00, 0x80,
-0xcc, 0x04, 0x00, 0x80, 0x71, 0x2b, 0xff, 0xff, 0xd1, 0x3d, 0xff, 0xff,
-0xc9, 0x2b, 0xff, 0xff, 0xa0, 0x82, 0x20, 0x40, 0xc9, 0x1c, 0x89, 0x08,
-0x89, 0x00, 0x01, 0x23, 0x85, 0x4a, 0x5b, 0x07, 0x18, 0x43, 0x13, 0x68,
-0x5b, 0x18, 0x13, 0x60, 0x00, 0x1f, 0x81, 0xa3, 0x5b, 0x1a, 0x18, 0x47,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5, 0x04, 0x20, 0xa0, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0xe4, 0x2d, 0x00, 0x80,
-0x98, 0x00, 0x9f, 0xe5, 0x98, 0x10, 0x9f, 0xe5, 0x01, 0x20, 0x40, 0xe0,
-0x94, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5, 0x03, 0x00, 0x50, 0xe1,
-0x03, 0x00, 0x00, 0x1a, 0x04, 0x10, 0x81, 0xe2, 0x04, 0x20, 0x52, 0xe2,
-0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea, 0x78, 0x00, 0x9f, 0xe5,
-0x00, 0x20, 0x80, 0xe5, 0x74, 0x00, 0x9f, 0xe5, 0x74, 0x10, 0x9f, 0xe5,
-0x01, 0x20, 0x40, 0xe0, 0x60, 0x30, 0x9f, 0xe5, 0x00, 0x00, 0x91, 0xe5,
-0x03, 0x00, 0x50, 0xe1, 0x03, 0x00, 0x00, 0x1a, 0x04, 0x10, 0x81, 0xe2,
-0x04, 0x20, 0x52, 0xe2, 0x00, 0x00, 0x00, 0x0a, 0xf8, 0xff, 0xff, 0xea,
-0x50, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5, 0x4c, 0x00, 0x9f, 0xe5,
-0x4c, 0x10, 0x9f, 0xe5, 0x01, 0x20, 0x40, 0xe0, 0x2c, 0x30, 0x9f, 0xe5,
-0x00, 0x00, 0x91, 0xe5, 0x03, 0x00, 0x50, 0xe1, 0x03, 0x00, 0x00, 0x1a,
-0x04, 0x10, 0x81, 0xe2, 0x04, 0x20, 0x52, 0xe2, 0x00, 0x00, 0x00, 0x0a,
-0xf8, 0xff, 0xff, 0xea, 0x28, 0x00, 0x9f, 0xe5, 0x00, 0x20, 0x80, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0x7c, 0x34, 0x00, 0x80, 0x80, 0x30, 0x00, 0x80,
-0xad, 0xde, 0xad, 0xde, 0xc0, 0x04, 0x00, 0x80, 0xfc, 0x37, 0x00, 0x80,
-0x80, 0x34, 0x00, 0x80, 0xc4, 0x04, 0x00, 0x80, 0xfc, 0x3f, 0x00, 0x80,
-0x40, 0x38, 0x00, 0x80, 0xc8, 0x04, 0x00, 0x80, 0x78, 0x47, 0x00, 0x00,
-0x71, 0xea, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x39, 0xfe, 0xff, 0xea,
-0x78, 0x47, 0x00, 0x00, 0x63, 0xfe, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00,
-0x1b, 0xff, 0xff, 0xea, 0x78, 0x47, 0x00, 0x00, 0x6b, 0xea, 0xff, 0xea,
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-0x28, 0x04, 0x00, 0x00, 0xf8, 0x3d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80,
-0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x0b, 0xff, 0xff,
-0x00, 0x00, 0x00, 0x00, 0xd5, 0x0b, 0xff, 0xff, 0x03, 0xff, 0x06, 0x54,
-0x03, 0x00, 0x00, 0x00, 0x75, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
-0xa1, 0x05, 0xff, 0xff, 0x04, 0xff, 0x07, 0x54, 0x03, 0x00, 0x00, 0x00,
-0xb5, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x05, 0xff, 0xff,
-0x05, 0xff, 0x05, 0x54, 0x03, 0x00, 0x00, 0x00, 0x39, 0x04, 0xff, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x55, 0x05, 0xff, 0xff, 0x01, 0xff, 0x04, 0x00,
-0x03, 0x00, 0x00, 0x00, 0x41, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
-0x61, 0x0e, 0xff, 0xff, 0x02, 0xff, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00,
-0xa1, 0x02, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x02, 0xff, 0xff,
-0xff, 0xff, 0x01, 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x9d, 0x0d, 0xff, 0xff, 0x06, 0x00, 0xff, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x3d, 0x50, 0xff, 0xff, 0x81, 0x50, 0xff, 0xff,
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x48, 0x05, 0x00, 0x80, 0x11, 0x75, 0x21, 0x40, 0x1b, 0x75, 0x21, 0x40,
-0x31, 0x75, 0x21, 0x40, 0x49, 0x75, 0x21, 0x40,
-0x55, 0x75, 0x21, 0x40, 0x63, 0x75, 0x21, 0x40, 0x7d, 0x75, 0x21, 0x40,
-0xa9, 0x75, 0x21, 0x40, 0x6d, 0x76, 0x21, 0x40, 0xc5, 0x76, 0x21, 0x40,
-0xd3, 0x76, 0x21, 0x40, 0xdd, 0x76, 0x21, 0x40, 0xe7, 0x76, 0x21, 0x40,
-0x99, 0x77, 0x21, 0x40, 0xa7, 0x77, 0x21, 0x40, 0xb5, 0x77, 0x21, 0x40,
-0x61, 0x78, 0x21, 0x40, 0x5f, 0x7c, 0x21, 0x40, 0xe9, 0x7c, 0x21, 0x40,
-0x89, 0x7d, 0x21, 0x40, 0xbd, 0x7e, 0x21, 0x40, 0xc9, 0x7e, 0x21, 0x40,
-0x29, 0x7f, 0x21, 0x40, 0x8d, 0x7f, 0x21, 0x40, 0xb9, 0x7f, 0x21, 0x40,
-0xdd, 0x7f, 0x21, 0x40, 0x1d, 0x80, 0x21, 0x40, 0x45, 0x80, 0x21, 0x40,
-0x8d, 0x80, 0x21, 0x40, 0x9d, 0x80, 0x21, 0x40, 0xc5, 0x80, 0x21, 0x40,
-0xd5, 0x80, 0x21, 0x40, 0x1d, 0x81, 0x21, 0x40, 0x5b, 0x81, 0x21, 0x40,
-0xb1, 0x81, 0x21, 0x40, 0x11, 0x82, 0x21, 0x40, 0x1b, 0x82, 0x21, 0x40,
-0x1f, 0x82, 0x21, 0x40, 0x8d, 0x82, 0x21, 0x40, 0xd9, 0x82, 0x21, 0x40,
-0x31, 0x83, 0x21, 0x40, 0x6d, 0x83, 0x21, 0x40, 0xd1, 0x83, 0x21, 0x40,
-0x09, 0x84, 0x21, 0x40, 0x19, 0x84, 0x21, 0x40, 0x51, 0x84, 0x21, 0x40,
-0x61, 0x84, 0x21, 0x40, 0x75, 0x84, 0x21, 0x40, 0x9d, 0x84, 0x21, 0x40,
-0xa7, 0x84, 0x21, 0x40, 0xb1, 0x84, 0x21, 0x40, 0x15, 0x85, 0x21, 0x40,
-0x45, 0x85, 0x21, 0x40, 0x51, 0x85, 0x21, 0x40, 0xc5, 0x85, 0x21, 0x40,
-0xcf, 0x85, 0x21, 0x40, 0xd9, 0x85, 0x21, 0x40, 0xe3, 0x85, 0x21, 0x40,
-0xed, 0x85, 0x21, 0x40, 0xf7, 0x85, 0x21, 0x40, 0x01, 0x86, 0x21, 0x40,
-0x0b, 0x86, 0x21, 0x40, 0x15, 0x86, 0x21, 0x40, 0x01, 0x89, 0x21, 0x40,
-0x1f, 0x86, 0x21, 0x40, 0x29, 0x86, 0x21, 0x40, 0x33, 0x86, 0x21, 0x40,
-0x3d, 0x86, 0x21, 0x40, 0x65, 0x86, 0x21, 0x40, 0x6f, 0x86, 0x21, 0x40,
-0xd1, 0x86, 0x21, 0x40, 0xdb, 0x86, 0x21, 0x40, 0xe5, 0x86, 0x21, 0x40,
-0xef, 0x86, 0x21, 0x40, 0xf9, 0x86, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40,
-0x03, 0x87, 0x21, 0x40, 0x69, 0x87, 0x21, 0x40, 0xb5, 0x87, 0x21, 0x40,
-0xf9, 0x87, 0x21, 0x40, 0x09, 0x88, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40,
-0x55, 0x88, 0x21, 0x40, 0x59, 0x88, 0x21, 0x40, 0x5d, 0x88, 0x21, 0x40,
-0xb5, 0x88, 0x21, 0x40, 0xdd, 0x88, 0x21, 0x40, 0xe9, 0x88, 0x21, 0x40,
-0xed, 0x88, 0x21, 0x40, 0xf1, 0x88, 0x21, 0x40, 0xf5, 0x88, 0x21, 0x40,
-0xf9, 0x88, 0x21, 0x40, 0xfd, 0x88, 0x21, 0x40, 0x2d, 0x85, 0x21, 0x40,
-0x89, 0x85, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40,
-0x0d, 0x89, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40, 0xe1, 0x74, 0x21, 0x40,
-0x9d, 0x74, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40,
-0x9d, 0x74, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40, 0x9d, 0x74, 0x21, 0x40,
-0x6b, 0x78, 0x21, 0x40, 0xf5, 0x7b, 0x21, 0x40, 0x31, 0x7c, 0x21, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x18, 0x40, 0x58, 0x01, 0x18, 0x40,
-0x24, 0xa3, 0x20, 0x40, 0x24, 0xa7, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x6c, 0x01, 0x18, 0x40, 0x68, 0x01, 0x18, 0x40,
-0x24, 0x83, 0x20, 0x40, 0x24, 0xa3, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x7c, 0x01, 0x18, 0x40, 0x78, 0x01, 0x18, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x8c, 0x01, 0x18, 0x40,
-0x88, 0x01, 0x18, 0x40, 0x24, 0xa9, 0x20, 0x40, 0x24, 0xab, 0x20, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x08, 0x00, 0x12, 0x00, 0x18, 0x00, 0x12, 0x00, 0x0c, 0x00, 0x12, 0x00,
-0x1c, 0x00, 0x12, 0x00, 0x24, 0xa8, 0x20, 0x40, 0xa4, 0xa8, 0x20, 0x40,
-0xa4, 0xa8, 0x20, 0x40, 0x24, 0xa9, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00,
-0xd1, 0xa8, 0x21, 0x40, 0x2d, 0xaa, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x89, 0x70, 0x21, 0x40, 0xc9, 0xa1, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x57, 0x89, 0x21, 0x40, 0xd1, 0xa8, 0x21, 0x40, 0xc5, 0x2f, 0xff, 0xff,
-0x05, 0x21, 0xff, 0xff, 0xef, 0x20, 0xff, 0xff, 0x59, 0xa7, 0x21, 0x40,
-0x34, 0x2e, 0x00, 0x80, 0x48, 0x2e, 0x00, 0x80, 0x5c, 0x2e, 0x00, 0x80,
-0x30, 0x33, 0x3a, 0x31, 0x31, 0x3a, 0x31, 0x31, 0x00, 0x30, 0x37, 0x2f,
-0x32, 0x33, 0x2f, 0x30, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x31, 0x35,
-0x36, 0x39, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74,
-0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x31, 0x20, 0x33, 0x43,
-0x6f, 0x6d, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69,
-0x6f, 0x6e, 0x0a, 0x00, 0x08, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x53, 0xff, 0xff,
-0x27, 0xf0, 0x7d, 0xfd, 0x00, 0x01, 0x00, 0x02, 0xda, 0x0e, 0x82, 0x00,
-0x01, 0x40, 0x64, 0x04, 0x64, 0x2d, 0x00, 0x80, 0xe4, 0x2c, 0x00, 0x80,
-0x69, 0x3e, 0xff, 0xff, 0xc9, 0x4f, 0xff, 0xff, 0xd5, 0x24, 0xff, 0xff,
-0xc9, 0x3b, 0xff, 0xff, 0x29, 0x3c, 0xff, 0xff, 0x19, 0x1a, 0xff, 0xff,
-0x65, 0x11, 0xff, 0xff, 0xcc, 0x53, 0xff, 0xff, 0x21, 0x40, 0xff, 0xff,
-0x89, 0x70, 0x21, 0x40, 0x49, 0x72, 0x21, 0x40, 0xd9, 0x3f, 0xff, 0xff,
-0x21, 0x9a, 0x21, 0x40, 0x85, 0x24, 0xff, 0xff, 0x64, 0x53, 0xff, 0xff,
-0x8c, 0x53, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
-0x80, 0x30, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
-0x00, 0x00, 0x20, 0x40, 0xb0, 0x50, 0x00, 0x00, 0x7b, 0x0e, 0x00, 0x00,
-0x00, 0x6e, 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xed, 0x89, 0x21, 0x40, 0x8b, 0x89, 0x21, 0x40, 0xa5, 0x8c, 0x21, 0x40,
-0x05, 0x8d, 0x21, 0x40, 0xcd, 0x8d, 0x21, 0x40, 0x8b, 0x8b, 0x21, 0x40,
-0xa9, 0x8e, 0x21, 0x40, 0x15, 0x8f, 0x21, 0x40, 0x69, 0x8b, 0x21, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x59, 0xbd, 0x21, 0x40, 0xc1, 0xbd, 0x21, 0x40, 0x2d, 0xbe, 0x21, 0x40,
-0x00, 0x20, 0x0a, 0x4a, 0x0b, 0x23, 0x1b, 0x02, 0xd1, 0x18, 0x2d, 0x23,
-0x9b, 0x01, 0xd3, 0x18, 0x88, 0x61, 0xd8, 0x60, 0xd8, 0x63, 0x80, 0x32,
-0xc8, 0x60, 0x08, 0x61, 0x48, 0x61, 0xd0, 0x62, 0x03, 0x48, 0xc0, 0x46,
-0x48, 0x60, 0x88, 0x60, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0xfe, 0x03, 0x00, 0x00, 0xf0, 0xb5, 0x84, 0xb0, 0x0c, 0x1c, 0x05, 0x1c,
-0x00, 0x23, 0x00, 0x93, 0xff, 0xf7, 0xde, 0xff, 0x68, 0x49, 0x0b, 0x23,
-0x1b, 0x02, 0xcf, 0x18, 0x78, 0x68, 0x28, 0x40,
-0x00, 0x22, 0xf8, 0x60, 0x3a, 0x61, 0xba, 0x68, 0x22, 0x40, 0x7a, 0x61,
-0x0c, 0x1c, 0x41, 0x09, 0x03, 0xd2, 0x51, 0x09, 0x01, 0xd2, 0x80, 0x0a,
-0x02, 0xd3, 0x60, 0x48, 0x00, 0xf0, 0xc2, 0xf8, 0x01, 0x20, 0xf9, 0x68,
-0x49, 0x09, 0x03, 0xd2, 0x79, 0x69, 0x49, 0x09, 0x00, 0xd2, 0x00, 0x20,
-0x00, 0x06, 0x00, 0x0e, 0x03, 0xf0, 0xd4, 0xfa, 0xf8, 0x68, 0x00, 0x28,
-0x70, 0xd0, 0x00, 0x23, 0x02, 0x93, 0x01, 0x93, 0x54, 0x4a, 0x01, 0x23,
-0x18, 0x43, 0xf8, 0x60, 0x00, 0x20, 0xd5, 0x1d, 0x79, 0x35, 0x03, 0x95,
-0x01, 0x24, 0x00, 0x21, 0x4f, 0x4d, 0xfa, 0x68, 0x22, 0x40, 0x39, 0xd0,
-0x8a, 0x00, 0x52, 0x18, 0x92, 0x00, 0x4e, 0x4b, 0x9b, 0x5c, 0x1e, 0x1c,
-0x83, 0x42, 0x04, 0xd0, 0x4b, 0x4b, 0xd3, 0x18, 0x5b, 0x78, 0x83, 0x42,
-0x2c, 0xd1, 0x49, 0x4b, 0xd2, 0x18, 0xd3, 0x78, 0x03, 0x9d, 0xed, 0x6a,
-0xab, 0x42, 0x02, 0xd9, 0x03, 0x9d, 0xc0, 0x46, 0xeb, 0x62, 0x53, 0x68,
-0x5b, 0x08, 0x01, 0xd3, 0x01, 0x23, 0x00, 0x93, 0x86, 0x42, 0x0a, 0xd1,
-0x95, 0x68, 0x02, 0x9b, 0x5e, 0x1c, 0x02, 0x96, 0x9b, 0x00, 0x3c, 0x4e,
-0x9e, 0x19, 0x0b, 0x23, 0x1b, 0x02, 0xf3, 0x18, 0x9d, 0x61, 0x53, 0x78,
-0x83, 0x42, 0x0d, 0xd1, 0xd2, 0x68, 0x01, 0x9b, 0x5d, 0x1c, 0x01, 0x95,
-0x9b, 0x00, 0x35, 0x4d, 0x5d, 0x19, 0x2d, 0x23, 0x9b, 0x01, 0xeb, 0x18,
-0xda, 0x60, 0x3a, 0x69, 0x01, 0x32, 0x3a, 0x61, 0x64, 0x00, 0x01, 0x31,
-0x0b, 0x29, 0xbd, 0xd3, 0x01, 0x30, 0x09, 0x28, 0xb8, 0xd3, 0x00, 0x20,
-0x02, 0x9b, 0x99, 0x00, 0x2b, 0x4a, 0x89, 0x18, 0x0b, 0x23, 0x1b, 0x02,
-0xc9, 0x18, 0x88, 0x61, 0x01, 0x9b, 0x99, 0x00, 0x89, 0x18, 0x2d, 0x23,
-0x9b, 0x01, 0xc9, 0x18, 0xc8, 0x60, 0x00, 0x9b, 0x00, 0x2b, 0x0c, 0xd1,
-0x81, 0x00, 0x89, 0x18, 0x0b, 0x23, 0x1b, 0x02, 0xc9, 0x18, 0xcb, 0x69,
-0xc0, 0x46, 0x8b, 0x61, 0x01, 0x30, 0x0b, 0x28, 0xf4, 0xd3, 0x08, 0xe0,
-0x07, 0xe0, 0x03, 0x9d, 0xe8, 0x6a, 0x30, 0x28, 0x03, 0xd2, 0x30, 0x20,
-0x03, 0x9d, 0xc0, 0x46, 0xe8, 0x62, 0x19, 0x4a, 0x78, 0x69, 0x00, 0x28,
-0x2a, 0xd0, 0x00, 0x21, 0x01, 0x23, 0x18, 0x43, 0x78, 0x61, 0x00, 0x20,
-0x01, 0x24, 0x00, 0x22, 0x13, 0x4e, 0x7b, 0x69, 0x23, 0x40, 0x10, 0xd0,
-0x93, 0x00, 0x9b, 0x18, 0x9b, 0x00, 0x12, 0x4d, 0x5b, 0x19, 0x9d, 0x78,
-0x85, 0x42, 0x08, 0xd1, 0x1d, 0x69, 0x0b, 0x1c, 0x9b, 0x00, 0x9e, 0x19,
-0x2d, 0x23, 0x9b, 0x01, 0xf3, 0x18, 0xdd, 0x63, 0x01, 0x31, 0x64, 0x00,
-0x01, 0x32, 0x0b, 0x2a, 0xe6, 0xd3, 0x01, 0x30, 0x09, 0x28, 0xe1, 0xd3,
-0x00, 0x20, 0x89, 0x00, 0x04, 0x4a, 0x89, 0x18, 0x2d, 0x23, 0x9b, 0x01,
-0xc9, 0x18, 0xc8, 0x63, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0x30, 0x53, 0xff, 0xff, 0x00, 0x01, 0x00, 0x80,
-0x00, 0x47, 0x08, 0x47, 0x10, 0x47, 0x18, 0x47, 0x78, 0x47, 0xc0, 0x46,
-0x18, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0xc0, 0x46,
-0x10, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x78, 0x47, 0xc0, 0x46,
-0x08, 0xc0, 0x9f, 0xe5, 0x1c, 0xff, 0x2f, 0xe1, 0x38, 0x52, 0xff, 0xff,
-0x88, 0x51, 0xff, 0xff, 0xd5, 0xb0, 0x21, 0x40, 0xf0, 0xb5, 0x04, 0x20,
-0x1a, 0x49, 0x01, 0x25, 0x08, 0x60, 0x1a, 0x4f, 0xbb, 0x23, 0x1b, 0x01,
-0xf8, 0x18, 0x05, 0x73, 0x18, 0x48, 0x41, 0x6b, 0x2c, 0x05, 0x00, 0x20,
-0x7a, 0x6e, 0x17, 0x4b, 0x8a, 0x42, 0x1d, 0xd0,
-0x19, 0x7b, 0x00, 0x29, 0x17, 0xd1, 0xd9, 0x1d, 0xff, 0x31, 0x3a, 0x31,
-0x49, 0x78, 0x1e, 0x1c, 0x00, 0x29, 0x10, 0xd1, 0xb0, 0x60, 0x10, 0x20,
-0x70, 0x60, 0x10, 0x4a, 0x10, 0x49, 0xff, 0xf7, 0xc3, 0xff, 0x00, 0x28,
-0x07, 0xd0, 0x35, 0x73, 0x04, 0x23, 0xb8, 0x69, 0x18, 0x43, 0xb8, 0x61,
-0x20, 0x61, 0x00, 0xf0, 0x17, 0xf8, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x18, 0x73, 0x04, 0x23, 0xb8, 0x69, 0x98, 0x43, 0xb8, 0x61, 0x20, 0x61,
-0xf5, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x68, 0x0e, 0x00, 0x80,
-0x00, 0x01, 0x18, 0x40, 0x28, 0x05, 0x00, 0x80, 0x20, 0x55, 0xff, 0xff,
-0x7d, 0x71, 0x21, 0x40, 0xf8, 0xb5, 0x15, 0x4f, 0x39, 0x6c, 0x15, 0x48,
-0x40, 0x6e, 0x0c, 0x1a, 0x14, 0x4e, 0x71, 0x68, 0x14, 0x4d, 0xa1, 0x42,
-0x06, 0xd8, 0x14, 0x4a, 0x0a, 0x43, 0x00, 0x92, 0xb9, 0x6b, 0x09, 0x18,
-0xfa, 0x6b, 0x11, 0xe0, 0x11, 0x22, 0x52, 0x05, 0x22, 0x43, 0x00, 0x92,
-0xb9, 0x6b, 0x09, 0x18, 0x00, 0x20, 0xfa, 0x6b, 0x2b, 0x1c, 0xff, 0xf7,
-0x8d, 0xff, 0x70, 0x68, 0x00, 0x1b, 0x0a, 0x4a, 0x02, 0x43, 0x00, 0x92,
-0xb9, 0x6b, 0xfa, 0x6b, 0x00, 0x20, 0x2b, 0x1c, 0xff, 0xf7, 0x82, 0xff,
-0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x7c, 0x29, 0x00, 0x80,
-0x68, 0x0e, 0x00, 0x80, 0x28, 0x05, 0x00, 0x80, 0x44, 0x80, 0x20, 0x40,
-0x00, 0x00, 0x37, 0x02, 0xf0, 0xb5, 0x2b, 0x4f, 0xb8, 0x68, 0x79, 0x68,
-0xc0, 0x19, 0x20, 0x30, 0x29, 0x4a, 0xff, 0xf7, 0x63, 0xff, 0x01, 0x20,
-0xc0, 0x02, 0x28, 0x49, 0xc0, 0x46, 0x08, 0x60, 0xb9, 0x68, 0x38, 0x1c,
-0x26, 0x4d, 0x00, 0x24, 0x26, 0x4e, 0xef, 0x1d, 0x79, 0x37, 0x00, 0x29,
-0x31, 0xd1, 0x31, 0x68, 0x0a, 0x78, 0x12, 0x0a, 0x03, 0xd2, 0x04, 0x73,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x49, 0x78, 0x00, 0x29, 0x0c, 0xd1,
-0x05, 0x1c, 0x40, 0x68, 0x00, 0xf0, 0x3e, 0xf9, 0x30, 0x68, 0x00, 0xf0,
-0x67, 0xf8, 0x00, 0x28, 0x26, 0xd1, 0x2c, 0x73, 0xff, 0xf7, 0x58, 0xff,
-0x22, 0xe0, 0x09, 0x01, 0x07, 0x1c, 0x41, 0x60, 0x08, 0x1c, 0x17, 0x4a,
-0x17, 0x49, 0xff, 0xf7, 0x35, 0xff, 0x00, 0x28, 0x07, 0xd1, 0x3c, 0x73,
-0x04, 0x23, 0xa8, 0x69, 0x98, 0x43, 0x99, 0x04, 0xa8, 0x61, 0x08, 0x61,
-0xda, 0xe7, 0x10, 0x20, 0x00, 0xf0, 0x20, 0xf9, 0x10, 0x20, 0xb8, 0x60,
-0xff, 0xf7, 0x82, 0xff, 0xd2, 0xe7, 0x05, 0x1c, 0x40, 0x68, 0x00, 0xf0,
-0x17, 0xf9, 0x30, 0x68, 0x00, 0xf0, 0x40, 0xf8, 0x00, 0x28, 0xd8, 0xd0,
-0x02, 0x23, 0xf8, 0x6b, 0x18, 0x43, 0xf8, 0x63, 0xc4, 0xe7, 0x00, 0x00,
-0x28, 0x05, 0x00, 0x80, 0xa5, 0x55, 0xff, 0xff, 0x00, 0x00, 0x00, 0xb0,
-0x68, 0x0e, 0x00, 0x80, 0xe4, 0x01, 0x00, 0x80, 0x20, 0x55, 0xff, 0xff,
-0x7d, 0x71, 0x21, 0x40, 0x90, 0xb5, 0x01, 0x20, 0x40, 0x03, 0x10, 0x49,
-0x00, 0x27, 0x08, 0x60, 0x0f, 0x4c, 0xe0, 0x1d, 0xff, 0x30, 0x3a, 0x30,
-0x47, 0x70, 0xe0, 0x69, 0x80, 0x00, 0x00, 0x19, 0x00, 0x69, 0x00, 0xf0,
-0xd7, 0xf8, 0xe0, 0x69, 0x00, 0x28, 0x01, 0xd0, 0xe7, 0x61, 0x01, 0xe0,
-0x01, 0x20, 0xe0, 0x61, 0x07, 0x48, 0x02, 0x23, 0xc1, 0x6b, 0x19, 0x43,
-0xc1, 0x63, 0x27, 0x73, 0xff, 0xf7, 0x00, 0xff, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x28, 0x05, 0x00, 0x80,
-0xe8, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x78, 0x88,
-0x6d, 0x28, 0x03, 0xdb, 0x38, 0x1c, 0x00, 0xf0,
-0xf7, 0xf8, 0x17, 0xe0, 0x80, 0x00, 0x0d, 0x49, 0x09, 0x58, 0x38, 0x1c,
-0xff, 0xf7, 0xcb, 0xfe, 0x00, 0x28, 0x0f, 0xd1, 0x39, 0x78, 0xc9, 0x09,
-0x0c, 0xd3, 0x69, 0x46, 0x38, 0x1c, 0x00, 0xf0, 0xcf, 0xf8, 0x68, 0x46,
-0x00, 0x21, 0x00, 0xf0, 0x0b, 0xf8, 0x00, 0x28, 0x01, 0xd1, 0x01, 0x20,
-0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0xe8, 0x01, 0x00, 0x80, 0xf0, 0xb5, 0x82, 0xb0, 0x02, 0x1c, 0x41, 0x4b,
-0xdd, 0x1d, 0xff, 0x35, 0x3a, 0x35, 0x2f, 0x78, 0x00, 0x2f, 0x01, 0xd0,
-0x00, 0x27, 0x00, 0xe0, 0x01, 0x27, 0x2f, 0x70, 0x2f, 0x78, 0xfb, 0x00,
-0xdb, 0x19, 0x5b, 0x01, 0x3a, 0x4f, 0xdc, 0x19, 0x40, 0x78, 0x00, 0x01,
-0xc7, 0x1d, 0x09, 0x37, 0x00, 0x20, 0x83, 0x00, 0xd6, 0x58, 0xc0, 0x46,
-0xe6, 0x50, 0x01, 0x30, 0x04, 0x28, 0xf8, 0xd3, 0x00, 0x29, 0x0f, 0xd0,
-0x00, 0x22, 0xbb, 0x08, 0x01, 0x93, 0x83, 0x42, 0x0b, 0xd9, 0x13, 0x1c,
-0x9b, 0x00, 0xcb, 0x58, 0x86, 0x00, 0xa3, 0x51, 0x01, 0x9b, 0x01, 0x30,
-0x01, 0x32, 0x83, 0x42, 0xf5, 0xd8, 0x00, 0xe0, 0x10, 0x27, 0x2b, 0x48,
-0x02, 0x6d, 0x80, 0x6e, 0x2a, 0x49, 0x82, 0x42, 0x03, 0xd8, 0x82, 0x1a,
-0xcb, 0x6c, 0x9a, 0x1a, 0x00, 0xe0, 0x12, 0x1a, 0xba, 0x42, 0x05, 0xd8,
-0x26, 0x48, 0x81, 0x6b, 0x01, 0x31, 0x81, 0x63, 0x01, 0x20, 0x37, 0xe0,
-0xc3, 0x19, 0xca, 0x6c, 0x93, 0x42, 0x08, 0xd8, 0x22, 0x4a, 0x3a, 0x43,
-0x00, 0x92, 0x0a, 0x1c, 0x49, 0x6c, 0x09, 0x18, 0x92, 0x6c, 0x23, 0x1c,
-0x12, 0xe0, 0x16, 0x1a, 0x00, 0x96, 0x1b, 0x49, 0x49, 0x6c, 0x09, 0x18,
-0x19, 0x48, 0x82, 0x6c, 0x03, 0x20, 0x23, 0x1c, 0xff, 0xf7, 0x5e, 0xfe,
-0xb8, 0x1b, 0x18, 0x4a, 0x02, 0x43, 0x00, 0x92, 0xa3, 0x19, 0x14, 0x48,
-0x82, 0x6c, 0x41, 0x6c, 0x03, 0x20, 0xff, 0xf7, 0x53, 0xfe, 0x01, 0x20,
-0x0d, 0x49, 0xc0, 0x46, 0x68, 0x70, 0x8a, 0x69, 0x92, 0x00, 0x52, 0x18,
-0x17, 0x61, 0x8a, 0x69, 0x00, 0x2a, 0x02, 0xd0, 0x00, 0x27, 0x8f, 0x61,
-0x00, 0xe0, 0x88, 0x61, 0x0c, 0x48, 0x02, 0x23, 0xc1, 0x6b, 0x19, 0x43,
-0xc1, 0x63, 0x00, 0x20, 0x01, 0x27, 0x0a, 0x49, 0xc0, 0x46, 0x4f, 0x73,
-0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x28, 0x05, 0x00, 0x80,
-0x50, 0xba, 0x20, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80,
-0xa0, 0x82, 0x20, 0x40, 0x00, 0x00, 0x19, 0x02, 0xe8, 0x0e, 0x00, 0x80,
-0x18, 0x1a, 0x00, 0x80, 0x07, 0x49, 0x8a, 0x6e, 0x10, 0x18, 0x07, 0x4a,
-0xd2, 0x6c, 0x13, 0x04, 0x1b, 0x0c, 0x83, 0x42, 0x00, 0xd8, 0x80, 0x1a,
-0x88, 0x66, 0x88, 0x6e, 0x03, 0x49, 0xc0, 0x46, 0x48, 0x61, 0x70, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80, 0x90, 0xee, 0x20, 0x40,
-0x06, 0x49, 0x4a, 0x6e, 0x10, 0x18, 0x06, 0x4a, 0x12, 0x6c, 0x82, 0x42,
-0x00, 0xd8, 0x80, 0x1a, 0x48, 0x66, 0x48, 0x6e, 0x03, 0x49, 0xc0, 0x46,
-0x08, 0x61, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x7c, 0x29, 0x00, 0x80,
-0x90, 0xee, 0x20, 0x40, 0x05, 0x22, 0x0a, 0x60, 0x82, 0x88, 0xc0, 0x46,
-0x8a, 0x80, 0x00, 0x22, 0x4a, 0x70, 0x40, 0x88, 0xc0, 0x46, 0x48, 0x80,
-0xca, 0x80, 0x8a, 0x60, 0xca, 0x60, 0x70, 0x47, 0x05, 0x22, 0x02, 0x60,
-0x00, 0x22, 0x82, 0x80, 0x42, 0x70, 0x41, 0x80, 0xc2, 0x80, 0x82, 0x60,
-0xc2, 0x60, 0x70, 0x47, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x0e, 0x48,
-0x41, 0x6b, 0x01, 0x31, 0x41, 0x63, 0x69, 0x46,
-0x38, 0x1c, 0xff, 0xf7, 0xdd, 0xff, 0x38, 0x68, 0xc0, 0x46, 0x00, 0x90,
-0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x01, 0x27, 0xdf, 0x80, 0x68, 0x46,
-0x00, 0x21, 0xff, 0xf7, 0x11, 0xff, 0x00, 0x28, 0x01, 0xd1, 0x38, 0x1c,
-0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0xa0, 0x82, 0x20, 0x40, 0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x09, 0x4a,
-0xc0, 0x46, 0x91, 0x81, 0x69, 0x46, 0xff, 0xf7, 0xbd, 0xff, 0x01, 0x20,
-0x40, 0x02, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7,
-0xf5, 0xfe, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0xe8, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0xff, 0xf7, 0xc3, 0xff, 0x08, 0xbc,
-0x18, 0x47, 0x01, 0x20, 0x03, 0x49, 0xc0, 0x46, 0x08, 0x71, 0xa1, 0x21,
-0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47, 0x28, 0x0f, 0x00, 0x80,
-0x00, 0x20, 0x04, 0x49, 0xc0, 0x46, 0x08, 0x71, 0xff, 0x21, 0xa1, 0x22,
-0x52, 0x03, 0x01, 0x31, 0x91, 0x60, 0x70, 0x47, 0x28, 0x0f, 0x00, 0x80,
-0x02, 0x20, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20, 0x70, 0x47,
-0x01, 0x20, 0x40, 0x02, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x20,
-0x70, 0x47, 0xc0, 0x88, 0xc0, 0x06, 0xc0, 0x0e, 0xa1, 0x21, 0x49, 0x03,
-0x48, 0x61, 0x02, 0x49, 0xc0, 0x46, 0xc8, 0x63, 0x00, 0x20, 0x70, 0x47,
-0xe8, 0x1a, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0, 0x08, 0x49, 0x0f, 0x6b,
-0x69, 0x46, 0xff, 0xf7, 0x71, 0xff, 0xf8, 0x06, 0xc0, 0x0e, 0x01, 0xab,
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xa9, 0xfe, 0x01, 0x20,
-0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0x00, 0x14, 0x40,
-0x80, 0xb5, 0x85, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7,
-0x5b, 0xff, 0xf8, 0x88, 0x04, 0xa9, 0x03, 0xf0, 0xc9, 0xff, 0x01, 0xab,
-0x58, 0x80, 0x01, 0xa8, 0x40, 0x88, 0x00, 0x28, 0x0f, 0xd0, 0x01, 0xa8,
-0x40, 0x88, 0x80, 0x08, 0x03, 0x38, 0x80, 0x08, 0x01, 0x30, 0x04, 0x3b,
-0x58, 0x70, 0x04, 0x98, 0x01, 0x68, 0xc0, 0x46, 0x02, 0x91, 0x40, 0x68,
-0xc0, 0x46, 0x03, 0x90, 0x05, 0xe0, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23,
-0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x04, 0x98, 0xc1, 0x1d, 0x01, 0x31,
-0x68, 0x46, 0xff, 0xf7, 0x75, 0xfe, 0x01, 0x20, 0x05, 0xb0, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x14, 0x4f, 0x39, 0x7b,
-0x00, 0x29, 0x20, 0xd1, 0xf9, 0x1d, 0xff, 0x31, 0x3a, 0x31, 0x49, 0x78,
-0x00, 0x29, 0x1a, 0xd1, 0x10, 0x49, 0x05, 0x22, 0x00, 0x92, 0x08, 0x22,
-0x00, 0xab, 0x5a, 0x80, 0x98, 0x80, 0x06, 0x20, 0x00, 0xab, 0x58, 0x70,
-0x00, 0x24, 0xdc, 0x80, 0x08, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x48, 0x68,
-0xc0, 0x46, 0x03, 0x90, 0x01, 0x20, 0x38, 0x73, 0x68, 0x46, 0x08, 0x31,
-0xff, 0xf7, 0x4c, 0xfe, 0x00, 0x28, 0x00, 0xd0, 0x3c, 0x73, 0x04, 0xb0,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x28, 0x05, 0x00, 0x80,
-0xa4, 0x2a, 0x00, 0x80, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46,
-0x38, 0x1c, 0xff, 0xf7, 0xf9, 0xfe, 0xba, 0x68, 0x0d, 0x4c, 0x0e, 0x48,
-0x00, 0x2a, 0x05, 0xd1, 0x0d, 0x49, 0xff, 0xf7, 0xe4, 0xfc, 0x00, 0x28,
-0x0c, 0xda, 0x05, 0xe0, 0xb9, 0x88, 0x0b, 0x4b, 0xff, 0xf7, 0xdf, 0xfc,
-0x00, 0x28, 0x05, 0xda, 0x01, 0xab, 0x5c, 0x80, 0x68, 0x46, 0x00, 0x21,
-0xff, 0xf7, 0x22, 0xfe, 0x00, 0x20, 0x04, 0xb0,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
-0x0d, 0x76, 0x21, 0x40, 0xc1, 0xbd, 0x21, 0x40, 0x59, 0xbd, 0x21, 0x40,
-0x00, 0xb5, 0xc0, 0x88, 0x03, 0xf0, 0x2e, 0xff, 0x00, 0x20, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0xb5, 0xff, 0xf7, 0xe2, 0xfe, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0xb5, 0xff, 0xf7, 0xdd, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5,
-0x01, 0x1c, 0x02, 0x20, 0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc, 0x18, 0x47,
-0xb0, 0xb5, 0xc6, 0xb0, 0x07, 0x1c, 0x08, 0x1c, 0x69, 0x46, 0xff, 0xf7,
-0xb5, 0xfe, 0x21, 0x48, 0xff, 0xf7, 0xa4, 0xfc, 0x04, 0x1c, 0x20, 0x4a,
-0x00, 0x21, 0x38, 0x1c, 0xff, 0xf7, 0xa0, 0xfc, 0x00, 0x28, 0x27, 0xd0,
-0x04, 0xa9, 0x1d, 0x4a, 0x38, 0x1c, 0xff, 0xf7, 0x99, 0xfc, 0x04, 0xa8,
-0x00, 0x23, 0x01, 0x2f, 0x06, 0xd1, 0x0c, 0xaa, 0x02, 0x32, 0x00, 0x21,
-0x13, 0x60, 0x01, 0x31, 0x10, 0x29, 0xfb, 0xd3, 0x01, 0x68, 0x04, 0x29,
-0x04, 0xd9, 0x89, 0x08, 0x03, 0x39, 0x89, 0x08, 0x01, 0x31, 0x00, 0xe0,
-0x19, 0x1c, 0x00, 0xab, 0x59, 0x70, 0x06, 0xa9, 0x09, 0x78, 0xc0, 0x46,
-0xd9, 0x80, 0x00, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x07, 0x98, 0xc0, 0x46,
-0x03, 0x90, 0x04, 0x33, 0x08, 0xad, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab,
-0x18, 0x70, 0x09, 0x49, 0x20, 0x1c, 0xff, 0xf7, 0x6e, 0xfc, 0x68, 0x46,
-0x29, 0x1c, 0xff, 0xf7, 0xb7, 0xfd, 0x01, 0x20, 0x46, 0xb0, 0xb0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff, 0x59, 0xb1, 0x21, 0x40,
-0x9d, 0xaf, 0x21, 0x40, 0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0x01, 0x1c,
-0x02, 0x20, 0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5,
-0x01, 0x1c, 0x01, 0x20, 0xff, 0xf7, 0xa2, 0xff, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0xb5, 0x01, 0x1c, 0x01, 0x20, 0x00, 0xf0, 0x02, 0xf8, 0x08, 0xbc,
-0x18, 0x47, 0xf0, 0xb5, 0xc7, 0xb0, 0x04, 0x1c, 0x0f, 0x1c, 0x38, 0x1c,
-0x01, 0xa9, 0xff, 0xf7, 0x4d, 0xfe, 0x21, 0x48, 0xff, 0xf7, 0x3c, 0xfc,
-0x00, 0x90, 0x78, 0x78, 0x00, 0x01, 0xba, 0x68, 0x04, 0x30, 0xfc, 0x2a,
-0x25, 0xd8, 0xff, 0x23, 0x09, 0x33, 0x98, 0x42, 0x21, 0xd8, 0x19, 0x2c,
-0x1f, 0xd8, 0xfd, 0x88, 0xf8, 0x68, 0xc0, 0x46, 0x05, 0x90, 0xf9, 0x1d,
-0x09, 0x31, 0x06, 0xab, 0x00, 0x20, 0x7e, 0x78, 0x00, 0x2e, 0x0d, 0xdd,
-0x40, 0xc9, 0x40, 0xc3, 0x40, 0xc9, 0x40, 0xc3, 0x40, 0xc9, 0x40, 0xc3,
-0x40, 0xc9, 0x40, 0xc3, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x7e, 0x78,
-0x86, 0x42, 0xf1, 0xdc, 0x20, 0x1c, 0x05, 0xa9, 0x2b, 0x1c, 0xff, 0xf7,
-0x21, 0xfc, 0x00, 0x28, 0x05, 0xd0, 0x01, 0xa8, 0x00, 0x78, 0x40, 0x23,
-0x18, 0x43, 0x01, 0xab, 0x18, 0x70, 0x07, 0x49, 0x00, 0x98, 0xff, 0xf7,
-0x06, 0xfc, 0x00, 0x21, 0x01, 0xa8, 0xff, 0xf7, 0x4f, 0xfd, 0x01, 0x20,
-0x47, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff,
-0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7, 0x1b, 0xfe, 0x08, 0xbc,
-0x18, 0x47, 0xf0, 0xb5, 0xc6, 0xb0, 0x07, 0x1c, 0xfc, 0x88, 0x25, 0x4d,
-0x68, 0x68, 0x01, 0x30, 0x69, 0x46, 0x68, 0x60, 0x38, 0x1c, 0xff, 0xf7,
-0xf5, 0xfd, 0x10, 0x2c, 0x08, 0xd3, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23,
-0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x17, 0xe0,
-0x78, 0x78, 0x82, 0x00, 0xfb, 0x1d, 0x09, 0x33, 0x00, 0x20, 0xb9, 0x68,
-0x00, 0x2a, 0x15, 0xd9, 0x40, 0xcb, 0x0f, 0x1c,
-0x01, 0x31, 0xbe, 0x42, 0x0d, 0xd0, 0x00, 0xaa, 0x12, 0x78, 0x40, 0x23,
-0x1a, 0x43, 0x00, 0xab, 0x1a, 0x70, 0x04, 0x22, 0xda, 0x80, 0x02, 0x90,
-0x03, 0x91, 0x04, 0x33, 0x68, 0x46, 0x00, 0x21, 0x15, 0xe0, 0x01, 0x30,
-0x90, 0x42, 0xe9, 0xd3, 0x00, 0xab, 0x5c, 0x70, 0x02, 0x94, 0x69, 0x68,
-0xc0, 0x46, 0x03, 0x91, 0xa2, 0x00, 0x00, 0x20, 0x10, 0x33, 0x00, 0x2a,
-0x05, 0xd9, 0x0f, 0x1c, 0x80, 0xc3, 0x01, 0x30, 0x01, 0x31, 0x90, 0x42,
-0xf9, 0xd3, 0x68, 0x46, 0x04, 0xa9, 0xff, 0xf7, 0xf7, 0xfc, 0x01, 0x20,
-0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x9c, 0x03, 0x00, 0x80,
-0x90, 0xb4, 0x23, 0x48, 0x00, 0x68, 0x01, 0x21, 0x42, 0x09, 0x00, 0xd3,
-0x00, 0x21, 0x00, 0x27, 0x3a, 0x1c, 0x43, 0x0b, 0x00, 0xd2, 0x02, 0x22,
-0x11, 0x43, 0x1e, 0x4a, 0x20, 0x24, 0xd3, 0x68, 0x01, 0x2b, 0x2e, 0xd1,
-0x80, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, 0x20, 0x1c, 0x1b, 0x23,
-0xdb, 0x01, 0xd1, 0x18, 0x89, 0x8b, 0x09, 0x0b, 0x00, 0xd2, 0x04, 0x27,
-0x38, 0x43, 0xd1, 0x6f, 0x09, 0x68, 0x09, 0x0a, 0x07, 0xd2, 0xd1, 0x1d,
-0x79, 0x31, 0x09, 0x68, 0x09, 0x68, 0x09, 0x0a, 0x01, 0xd3, 0x08, 0x23,
-0x18, 0x43, 0xe3, 0x23, 0x1b, 0x01, 0xd1, 0x18, 0x89, 0x79, 0x03, 0x29,
-0x02, 0xd1, 0xff, 0x23, 0x01, 0x33, 0x18, 0x43, 0x0b, 0x49, 0x09, 0x6a,
-0x10, 0x22, 0x4b, 0x0a, 0x00, 0xd2, 0x00, 0x22, 0x10, 0x43, 0x89, 0x07,
-0x89, 0x0f, 0x89, 0x01, 0x08, 0x43, 0x90, 0xbc, 0x70, 0x47, 0x40, 0x0c,
-0x00, 0xd2, 0x00, 0x24, 0x0c, 0x43, 0x20, 0x1c, 0xec, 0xe7, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x40, 0x68, 0x0e, 0x00, 0x80, 0xc0, 0x00, 0x18, 0x40,
-0xf0, 0xb5, 0x3a, 0x4c, 0x20, 0x1c, 0x04, 0xf0, 0x07, 0xfa, 0x39, 0x48,
-0xe3, 0x23, 0x1b, 0x01, 0xc7, 0x18, 0xb9, 0x79, 0x37, 0x4e, 0xc5, 0x1d,
-0x79, 0x35, 0x06, 0x29, 0x62, 0xd2, 0x02, 0xa3, 0x5b, 0x5c, 0x5b, 0x00,
-0x9f, 0x44, 0x00, 0x1c, 0x03, 0x0e, 0x1e, 0x37, 0x4e, 0x55, 0x01, 0x20,
-0xb8, 0x71, 0x00, 0x20, 0xb0, 0x60, 0xff, 0xf7, 0x95, 0xff, 0x05, 0x23,
-0x98, 0x43, 0x00, 0xf0, 0x6f, 0xf8, 0x0c, 0xe0, 0xff, 0xf7, 0x8e, 0xff,
-0xc0, 0x08, 0x06, 0xd3, 0xb0, 0x68, 0x41, 0x1c, 0xb1, 0x60, 0x0a, 0x28,
-0x03, 0xd9, 0x04, 0x20, 0x00, 0xe0, 0x02, 0x20, 0xb8, 0x71, 0x64, 0x22,
-0x20, 0x1c, 0x2b, 0xe0, 0x06, 0x1c, 0xc0, 0x6f, 0x80, 0x23, 0x01, 0x68,
-0x19, 0x43, 0x01, 0x60, 0x03, 0x20, 0xb8, 0x71, 0x20, 0x1c, 0x20, 0x4a,
-0x00, 0x21, 0x04, 0xf0, 0x99, 0xf9, 0xf0, 0x6f, 0x04, 0x23, 0x01, 0x68,
-0x99, 0x43, 0x01, 0x60, 0x28, 0x68, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x05, 0x21, 0xb9, 0x71, 0x29, 0x68,
-0x04, 0x23, 0x0a, 0x68, 0x9a, 0x43, 0x0a, 0x60, 0xc0, 0x6f, 0x01, 0x68,
-0x19, 0x43, 0x01, 0x60, 0xff, 0xf7, 0x5a, 0xff, 0x08, 0x23, 0x18, 0x43,
-0x00, 0xf0, 0x34, 0xf8, 0x20, 0x1c, 0x10, 0x4a, 0x00, 0x21, 0x04, 0xf0,
-0x77, 0xf9, 0xe5, 0xe7, 0xff, 0xf7, 0x4e, 0xff, 0x04, 0x23, 0x18, 0x43,
-0x00, 0xf0, 0x28, 0xf8, 0xde, 0xe7, 0x00, 0x20, 0x29, 0x68, 0x60, 0x23,
-0x0a, 0x68, 0x9a, 0x43, 0x0a, 0x60, 0xff, 0xf7, 0xe3, 0xfa, 0xd5, 0xe7,
-0x06, 0x20, 0xb8, 0x71, 0xd2, 0xe7, 0x00, 0x00, 0xa9, 0x79, 0x21, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0x9c, 0x03, 0x00, 0x80, 0x30, 0x75, 0x00, 0x00,
-0x10, 0x27, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x20,
-0x04, 0x49, 0xc0, 0x46, 0x88, 0x71, 0x04, 0x48, 0x01, 0x22, 0x00, 0x21,
-0x04, 0xf0, 0x4e, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x98, 0x1c, 0x00, 0x80,
-0xa9, 0x79, 0x21, 0x40, 0x90, 0xb5, 0x07, 0x1c, 0x31, 0x48, 0x00, 0x68,
-0x79, 0x08, 0x03, 0xd3, 0x10, 0x23, 0x01, 0x1c, 0x99, 0x43, 0x01, 0xe0,
-0x10, 0x21, 0x01, 0x43, 0x2d, 0x4c, 0xe2, 0x68, 0x01, 0x2a, 0x05, 0xd1,
-0x22, 0x79, 0x00, 0x2a, 0x02, 0xd0, 0x01, 0x23, 0x9b, 0x02, 0x19, 0x43,
-0x81, 0x42, 0x02, 0xd0, 0x01, 0x20, 0x00, 0x05, 0x01, 0x60, 0xe0, 0x68,
-0x01, 0x28, 0x20, 0xd1, 0x1b, 0x23, 0xdb, 0x01, 0xe0, 0x18, 0x80, 0x8b,
-0xf9, 0x08, 0x04, 0xd3, 0x01, 0x23, 0xdb, 0x02, 0x01, 0x1c, 0x99, 0x43,
-0x01, 0xe0, 0x01, 0x21, 0xc9, 0x02, 0x81, 0x42, 0x02, 0xd0, 0x00, 0x20,
-0x02, 0xf0, 0x1a, 0xfb, 0x38, 0x09, 0x07, 0xd3, 0xe0, 0x6f, 0x80, 0x23,
-0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 0xe0, 0x18, 0x00, 0x68, 0x00, 0xe0,
-0xe0, 0x6f, 0x80, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x15, 0x48,
-0x01, 0x6a, 0x78, 0x09, 0x03, 0xd3, 0xff, 0x20, 0x01, 0x30, 0x08, 0x43,
-0x03, 0xe0, 0xff, 0x23, 0x08, 0x1c, 0x01, 0x33, 0x98, 0x43, 0x80, 0x08,
-0x80, 0x00, 0xba, 0x09, 0x92, 0x07, 0x92, 0x0f, 0x10, 0x43, 0x88, 0x42,
-0x02, 0xd0, 0x0c, 0x49, 0xc0, 0x46, 0x08, 0x62, 0xe1, 0x68, 0x01, 0x29,
-0x08, 0xd1, 0x79, 0x0a, 0x06, 0xd3, 0xff, 0x23, 0x04, 0x33, 0x18, 0x40,
-0x03, 0x28, 0x01, 0xd1, 0xff, 0xf7, 0x8e, 0xff, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x68, 0x0e, 0x00, 0x80,
-0xc0, 0x00, 0x18, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x80, 0xb5, 0xff, 0xf7,
-0xb1, 0xfe, 0x80, 0x09, 0x1b, 0xd2, 0x0f, 0x48, 0xe3, 0x23, 0x1b, 0x01,
-0xc1, 0x18, 0x4a, 0x79, 0x00, 0x2a, 0x14, 0xd1, 0x01, 0x22, 0x4a, 0x71,
-0x00, 0x27, 0x80, 0x30, 0x00, 0x68, 0x60, 0x23, 0x01, 0x68, 0x99, 0x43,
-0x01, 0x60, 0x08, 0x48, 0x06, 0xe0, 0x02, 0x20, 0x02, 0xf0, 0x8c, 0xfc,
-0x07, 0x20, 0x02, 0xf0, 0x5b, 0xfc, 0x38, 0x1c, 0xff, 0xf7, 0x36, 0xfa,
-0xf5, 0xe7, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0xf4, 0x01, 0xff, 0xff, 0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xff, 0xf7,
-0x37, 0xfc, 0xff, 0xf7, 0x85, 0xfe, 0x01, 0xab, 0x58, 0x80, 0x08, 0x48,
-0x00, 0x68, 0xc0, 0x46, 0x02, 0x90, 0x07, 0x48, 0x00, 0x6a, 0xc0, 0x46,
-0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x67, 0xfb, 0x01, 0x20,
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40,
-0xc0, 0x00, 0x18, 0x40, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46,
-0x38, 0x1c, 0xff, 0xf7, 0x17, 0xfc, 0xf8, 0x88, 0xff, 0xf7, 0x42, 0xff,
-0xff, 0xf7, 0x62, 0xfe, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21,
-0xff, 0xf7, 0x4c, 0xfb, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0xb0, 0xb5, 0xc6, 0xb0, 0xc7, 0x88, 0x69, 0x46, 0xff, 0xf7,
-0x01, 0xfc, 0x01, 0x24, 0x1a, 0x4b, 0x9f, 0x42, 0x0a, 0xd9, 0x00, 0xa8,
-0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20,
-0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 0x20, 0xe0, 0x14, 0x48, 0xff, 0xf7,
-0xe1, 0xf9, 0x05, 0x1c, 0x13, 0x4a, 0x38, 0x1c, 0x04, 0xa9, 0xff, 0xf7,
-0xdd, 0xf9, 0x12, 0x49, 0x28, 0x1c, 0xff, 0xf7, 0xd8, 0xf9, 0x01, 0x2f,
-0x06, 0xd1, 0x0c, 0xa9, 0x00, 0x20, 0x00, 0x22,
-0x0a, 0x60, 0x01, 0x30, 0x10, 0x28, 0xfb, 0xd3, 0x10, 0x20, 0x00, 0xab,
-0x58, 0x70, 0x04, 0x98, 0xc0, 0x46, 0x02, 0x90, 0x05, 0x98, 0xc0, 0x46,
-0x03, 0x90, 0x68, 0x46, 0x06, 0xa9, 0xff, 0xf7, 0x0f, 0xfb, 0x20, 0x1c,
-0x46, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0x01, 0x00, 0x00,
-0x24, 0x02, 0xff, 0xff, 0x9d, 0xaf, 0x21, 0x40, 0x3c, 0x02, 0xff, 0xff,
-0xf0, 0xb5, 0xc6, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7,
-0xbb, 0xfb, 0xfc, 0x88, 0x78, 0x78, 0x01, 0x25, 0x10, 0x28, 0x01, 0xd1,
-0x19, 0x2c, 0x09, 0xd9, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43,
-0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x04, 0x33, 0x27, 0xe0,
-0xb8, 0x68, 0xc0, 0x46, 0x04, 0x90, 0xf8, 0x68, 0xc0, 0x46, 0x05, 0x90,
-0x06, 0xaa, 0xfb, 0x1d, 0x09, 0x33, 0x00, 0x21, 0x78, 0x78, 0x00, 0x28,
-0x0d, 0xdd, 0x00, 0x20, 0x40, 0xcb, 0x40, 0xc2, 0x01, 0x30, 0x00, 0x04,
-0x00, 0x0c, 0x04, 0x28, 0xf8, 0xdb, 0x48, 0x1c, 0x01, 0x04, 0x09, 0x0c,
-0x78, 0x78, 0x88, 0x42, 0xf1, 0xdc, 0x0b, 0x48, 0xff, 0xf7, 0x7e, 0xf9,
-0x07, 0x1c, 0x0a, 0x4a, 0x20, 0x1c, 0x04, 0xa9, 0xff, 0xf7, 0x7a, 0xf9,
-0x08, 0x49, 0x38, 0x1c, 0xff, 0xf7, 0x75, 0xf9, 0x68, 0x46, 0x00, 0x21,
-0xff, 0xf7, 0xbe, 0xfa, 0x28, 0x1c, 0x46, 0xb0, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x24, 0x02, 0xff, 0xff, 0xc5, 0xaf, 0x21, 0x40,
-0x3c, 0x02, 0xff, 0xff, 0xf0, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x00, 0x27,
-0xe6, 0x88, 0xa2, 0x68, 0x47, 0x49, 0x08, 0x79, 0x00, 0x28, 0x08, 0xd0,
-0x00, 0x2e, 0x01, 0xd0, 0x01, 0x2e, 0x01, 0xd1, 0x01, 0x27, 0x01, 0xe0,
-0x04, 0x2e, 0x00, 0xd1, 0x03, 0x26, 0x01, 0x25, 0x41, 0x48, 0x05, 0x2e,
-0x66, 0xd2, 0x02, 0xa3, 0x9b, 0x5d, 0x5b, 0x00, 0x9f, 0x44, 0x00, 0x1c,
-0x03, 0x06, 0x08, 0x0c, 0x10, 0x00, 0x05, 0x80, 0x00, 0x23, 0x03, 0xe0,
-0x05, 0x80, 0x05, 0xe0, 0x00, 0x23, 0x03, 0x80, 0x43, 0x80, 0x06, 0xe0,
-0x00, 0x23, 0x03, 0x80, 0x45, 0x80, 0x02, 0xe0, 0xff, 0x23, 0x01, 0x33,
-0x03, 0x80, 0xcb, 0x1d, 0x79, 0x33, 0x9e, 0x89, 0x01, 0x23, 0x5b, 0x02,
-0x9e, 0x42, 0x02, 0xdb, 0xd2, 0x07, 0xd2, 0x0f, 0x00, 0xe0, 0x01, 0x22,
-0x6d, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x89, 0x88, 0xff, 0x23, 0xe1, 0x33,
-0x99, 0x43, 0x01, 0x23, 0x19, 0x43, 0x06, 0x88, 0xff, 0x33, 0x9e, 0x42,
-0x0d, 0xd1, 0xff, 0x20, 0xe1, 0x30, 0x08, 0x43, 0x00, 0x2a, 0x04, 0xd1,
-0x01, 0x23, 0x9b, 0x02, 0x98, 0x43, 0x01, 0x1c, 0x20, 0xe0, 0x01, 0x21,
-0x89, 0x02, 0x01, 0x43, 0x1c, 0xe0, 0x01, 0x2e, 0x0a, 0xd1, 0x40, 0x88,
-0x01, 0x28, 0x04, 0xd1, 0x60, 0x23, 0x19, 0x43, 0x00, 0x2a, 0x13, 0xd0,
-0x0c, 0xe0, 0x20, 0x23, 0x19, 0x43, 0x0f, 0xe0, 0x00, 0x2e, 0x0d, 0xd1,
-0x40, 0x88, 0x01, 0x28, 0x08, 0xd1, 0xff, 0x23, 0x81, 0x33, 0x19, 0x43,
-0x00, 0x2a, 0x05, 0xd0, 0x01, 0x23, 0x9b, 0x02, 0x19, 0x43, 0x01, 0xe0,
-0x80, 0x23, 0x19, 0x43, 0x04, 0x20, 0x02, 0xf0, 0x75, 0xf9, 0x09, 0x21,
-0x49, 0x02, 0x00, 0x20, 0x02, 0xf0, 0x70, 0xf9, 0x00, 0x2f, 0x02, 0xd1,
-0x00, 0x20, 0x12, 0xe0, 0xff, 0xe7, 0x69, 0x46, 0x20, 0x1c, 0xff, 0xf7,
-0xef, 0xfa, 0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab,
-0x18, 0x70, 0x02, 0x20, 0xd8, 0x80, 0x68, 0x46, 0x00, 0x21, 0x04, 0x33,
-0xff, 0xf7, 0x22, 0xfa, 0x28, 0x1c, 0x04, 0xb0,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x88, 0x1c, 0x00, 0x80, 0xc0, 0x88, 0x51, 0x21, 0x89, 0x03, 0x08, 0x62,
-0x00, 0x20, 0x70, 0x47, 0x80, 0xb5, 0x16, 0x4f, 0xf8, 0x68, 0x01, 0x28,
-0x07, 0xd1, 0x37, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x40, 0x8a, 0x80, 0x21,
-0x01, 0x43, 0x1b, 0x20, 0x07, 0xe0, 0x6d, 0x23, 0x5b, 0x01, 0xf8, 0x18,
-0x80, 0x8b, 0x01, 0x21, 0x49, 0x03, 0x01, 0x43, 0x10, 0x20, 0x02, 0xf0,
-0x33, 0xf9, 0x01, 0x20, 0x71, 0x23, 0x5b, 0x01, 0xf9, 0x18, 0x08, 0x80,
-0x48, 0x80, 0x1b, 0x23, 0xdb, 0x01, 0xf8, 0x18, 0x80, 0x8b, 0x01, 0x23,
-0x1b, 0x03, 0x98, 0x43, 0x41, 0x21, 0x09, 0x02, 0x01, 0x43, 0x00, 0x20,
-0x02, 0xf0, 0x20, 0xf9, 0x00, 0x20, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x17, 0x4f, 0xf8, 0x68, 0x01, 0x28,
-0x08, 0xd1, 0x37, 0x23, 0x9b, 0x01, 0xf8, 0x18, 0x40, 0x8a, 0x80, 0x23,
-0x98, 0x43, 0x01, 0x1c, 0x1b, 0x20, 0x08, 0xe0, 0x6d, 0x23, 0x5b, 0x01,
-0xf8, 0x18, 0x80, 0x8b, 0x01, 0x23, 0x5b, 0x03, 0x98, 0x43, 0x01, 0x1c,
-0x10, 0x20, 0x02, 0xf0, 0x01, 0xf9, 0xff, 0x20, 0x71, 0x23, 0x5b, 0x01,
-0xf9, 0x18, 0x01, 0x30, 0x08, 0x80, 0x1b, 0x23, 0xdb, 0x01, 0xf8, 0x18,
-0x80, 0x8b, 0x41, 0x23, 0x1b, 0x02, 0x98, 0x43, 0x09, 0x21, 0x49, 0x02,
-0x01, 0x43, 0x00, 0x20, 0x02, 0xf0, 0xee, 0xf8, 0x00, 0x20, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x80, 0xb5, 0x84, 0xb0,
-0x08, 0x49, 0xcf, 0x6a, 0x69, 0x46, 0xff, 0xf7, 0x69, 0xfa, 0xb8, 0x05,
-0x80, 0x0d, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7,
-0xa1, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x40, 0x00, 0x14, 0x40, 0xc0, 0x88, 0x9f, 0x23, 0x18, 0x40, 0x05, 0x49,
-0xc9, 0x6a, 0x1b, 0x23, 0x5b, 0x01, 0x19, 0x40, 0x08, 0x43, 0x03, 0x49,
-0xc0, 0x46, 0xc8, 0x62, 0x00, 0x20, 0x70, 0x47, 0x40, 0x00, 0x14, 0x40,
-0x40, 0x00, 0x14, 0x00, 0x80, 0xb5, 0x84, 0xb0, 0x0d, 0x49, 0x0f, 0x6a,
-0x01, 0x2f, 0x01, 0xd1, 0xff, 0x03, 0x07, 0xe0, 0x02, 0x2f, 0x01, 0xd1,
-0x3f, 0x03, 0x03, 0xe0, 0x00, 0x2f, 0x01, 0xd1, 0x01, 0x27, 0xff, 0x02,
-0x69, 0x46, 0xff, 0xf7, 0x35, 0xfa, 0x01, 0xab, 0x5f, 0x80, 0x68, 0x46,
-0x00, 0x21, 0xff, 0xf7, 0x6f, 0xf9, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x14, 0x40, 0xc2, 0x88, 0xa1, 0x20,
-0x40, 0x03, 0x00, 0x21, 0x01, 0x23, 0x5b, 0x03, 0x9a, 0x42, 0x01, 0xd1,
-0x02, 0x22, 0x04, 0xe0, 0x01, 0x23, 0xdb, 0x03, 0x9a, 0x42, 0x02, 0xd1,
-0x01, 0x22, 0x02, 0x62, 0x00, 0xe0, 0x01, 0x62, 0x08, 0x1c, 0x70, 0x47,
-0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x02, 0xf0, 0x9f, 0xf8, 0x69, 0x46,
-0x04, 0x1c, 0x38, 0x1c, 0xff, 0xf7, 0x0a, 0xfa, 0x01, 0xab, 0x5c, 0x80,
-0x09, 0x4f, 0xf8, 0x6d, 0xc0, 0x46, 0x02, 0x90, 0x68, 0x46, 0x00, 0x21,
-0xff, 0xf7, 0x40, 0xf9, 0xf8, 0x6d, 0xc0, 0x07, 0xc0, 0x0f, 0x05, 0x49,
-0xc0, 0x46, 0xc8, 0x62, 0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80, 0x68, 0x1c, 0x00, 0x80,
-0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0x48, 0x61, 0x00, 0x20, 0x70, 0x47,
-0x80, 0x00, 0x14, 0x00, 0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xff, 0xf7,
-0xe3, 0xf9, 0x06, 0x48, 0xc0, 0x68, 0x01, 0xab,
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0x1b, 0xf9, 0x01, 0x20,
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40,
-0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0xc8, 0x60, 0x00, 0x20, 0x70, 0x47,
-0x80, 0x00, 0x14, 0x00, 0x80, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0x87, 0x68,
-0xff, 0xf7, 0xc6, 0xf9, 0x20, 0x2f, 0x07, 0xd2, 0x78, 0x00, 0x0c, 0x49,
-0x40, 0x18, 0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x80, 0x8b, 0x06, 0xe0,
-0x00, 0xa8, 0x00, 0x78, 0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70,
-0x02, 0x20, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7,
-0xef, 0xf8, 0x01, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0x84, 0xb0, 0xc1, 0x88, 0x82, 0x68,
-0x20, 0x2a, 0x04, 0xd2, 0x10, 0x1c, 0x02, 0xf0, 0x17, 0xf8, 0x00, 0x20,
-0x10, 0xe0, 0x69, 0x46, 0xff, 0xf7, 0x9a, 0xf9, 0x00, 0xa8, 0x00, 0x78,
-0x40, 0x23, 0x18, 0x43, 0x00, 0xab, 0x18, 0x70, 0x02, 0x20, 0xd8, 0x80,
-0x68, 0x46, 0x00, 0x21, 0x04, 0x33, 0xff, 0xf7, 0xcd, 0xf8, 0x01, 0x20,
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0xc7, 0x88,
-0x69, 0x46, 0xff, 0xf7, 0x83, 0xf9, 0x10, 0x48, 0xfe, 0xf7, 0x72, 0xff,
-0x02, 0x20, 0x39, 0x1c, 0x02, 0xf0, 0xf2, 0xff, 0x00, 0x28, 0x06, 0xd0,
-0x02, 0x20, 0x39, 0x1c, 0x02, 0xf0, 0x36, 0xff, 0x01, 0xab, 0x58, 0x80,
-0x02, 0xe0, 0x45, 0x20, 0x00, 0xab, 0x18, 0x70, 0x07, 0x49, 0x20, 0x1c,
-0xfe, 0xf7, 0x5f, 0xff, 0x68, 0x46, 0x00, 0x21, 0xff, 0xf7, 0xa8, 0xf8,
-0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x24, 0x02, 0xff, 0xff, 0x3c, 0x02, 0xff, 0xff, 0xb0, 0xb5, 0x84, 0xb0,
-0xc7, 0x88, 0x69, 0x46, 0x84, 0x68, 0xff, 0xf7, 0x57, 0xf9, 0x10, 0x48,
-0xfe, 0xf7, 0x46, 0xff, 0x0f, 0x4a, 0x02, 0x20, 0x39, 0x1c, 0xfe, 0xf7,
-0x43, 0xff, 0x00, 0x28, 0x06, 0xd0, 0x0d, 0x4b, 0x02, 0x20, 0x39, 0x1c,
-0x22, 0x1c, 0xfe, 0xf7, 0x3c, 0xff, 0x02, 0xe0, 0x45, 0x20, 0x00, 0xab,
-0x18, 0x70, 0x09, 0x49, 0x28, 0x1c, 0xfe, 0xf7, 0x32, 0xff, 0x68, 0x46,
-0x00, 0x21, 0xff, 0xf7, 0x7b, 0xf8, 0x01, 0x20, 0x04, 0xb0, 0xb0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x24, 0x02, 0xff, 0xff, 0x59, 0xb1, 0x21, 0x40,
-0x59, 0xb0, 0x21, 0x40, 0x3c, 0x02, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7,
-0x43, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x80, 0xb4,
-0xc2, 0x88, 0x19, 0x4b, 0xa1, 0x21, 0x49, 0x03, 0x00, 0x2a, 0x03, 0xd1,
-0x18, 0x6b, 0x10, 0x23, 0x98, 0x43, 0x04, 0xe0, 0x01, 0x2a, 0x04, 0xd1,
-0x18, 0x6b, 0x10, 0x23, 0x18, 0x43, 0x48, 0x61, 0x1f, 0xe0, 0x02, 0x2a,
-0x1d, 0xd1, 0xc2, 0x68, 0x87, 0x68, 0x00, 0x20, 0x3b, 0x1c, 0xc3, 0x40,
-0xdb, 0x07, 0xdb, 0x0f, 0x9b, 0x02, 0x03, 0x43, 0x0b, 0x61, 0x01, 0x30,
-0x00, 0x04, 0x00, 0x0c, 0x20, 0x28, 0xf3, 0xdb, 0x00, 0x20, 0x13, 0x1c,
-0xc3, 0x40, 0xdb, 0x07, 0xdb, 0x0f, 0x9b, 0x02, 0xc7, 0x1d, 0x19, 0x37,
-0x3b, 0x43, 0x0b, 0x61, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x20, 0x28,
-0xf1, 0xdb, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47, 0x80, 0x00, 0x14, 0x40,
-0x80, 0xb4, 0xc2, 0x88, 0x81, 0x68, 0x10, 0x02, 0x12, 0x0a, 0x10, 0x43,
-0x02, 0x04, 0x12, 0x0c, 0x0c, 0x48, 0xc0, 0x46, 0x02, 0x60, 0x0c, 0x4b,
-0xc0, 0x46, 0x1a, 0x80, 0x0a, 0x0c, 0x17, 0x02,
-0x12, 0x12, 0x3a, 0x43, 0x12, 0x04, 0x12, 0x0c, 0x42, 0x60, 0x5a, 0x80,
-0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02, 0x09, 0x0a, 0x11, 0x43, 0x09, 0x04,
-0x09, 0x0c, 0x81, 0x60, 0x99, 0x80, 0x00, 0x20, 0x80, 0xbc, 0x70, 0x47,
-0x40, 0x00, 0x14, 0x00, 0x28, 0x1b, 0x00, 0x80, 0xb0, 0xb5, 0x84, 0xb0,
-0x13, 0x49, 0x0a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x13, 0x02, 0x12, 0x12,
-0x13, 0x43, 0x4a, 0x68, 0x12, 0x04, 0x12, 0x0c, 0x1f, 0x1c, 0x13, 0x02,
-0x12, 0x12, 0x13, 0x43, 0x89, 0x68, 0x09, 0x04, 0x09, 0x0c, 0x0a, 0x02,
-0x09, 0x12, 0x11, 0x43, 0x0c, 0x04, 0x24, 0x0c, 0x69, 0x46, 0x1d, 0x1c,
-0xff, 0xf7, 0xae, 0xf8, 0x01, 0xab, 0x5f, 0x80, 0x28, 0x04, 0x20, 0x43,
-0x02, 0x90, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xe5, 0xff, 0x01, 0x20,
-0x04, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0x00, 0x14, 0x40,
-0xc1, 0x88, 0x82, 0x68, 0x08, 0x02, 0x09, 0x0a, 0x08, 0x43, 0x00, 0x04,
-0x00, 0x0c, 0x0a, 0x49, 0xc0, 0x46, 0xc8, 0x60, 0x10, 0x0c, 0x03, 0x02,
-0x00, 0x12, 0x18, 0x43, 0x00, 0x04, 0x00, 0x0c, 0x08, 0x61, 0x10, 0x04,
-0x00, 0x0c, 0x02, 0x02, 0x00, 0x0a, 0x10, 0x43, 0x00, 0x04, 0x00, 0x0c,
-0x48, 0x61, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00,
-0x90, 0xb5, 0x84, 0xb0, 0x16, 0x4b, 0xd9, 0x68, 0x09, 0x04, 0x09, 0x0c,
-0x0a, 0x02, 0x09, 0x12, 0x11, 0x43, 0x1a, 0x69, 0x12, 0x04, 0x12, 0x0c,
-0x17, 0x02, 0x12, 0x12, 0x3a, 0x43, 0x5b, 0x69, 0x1b, 0x04, 0x1b, 0x0c,
-0x1f, 0x02, 0x1b, 0x12, 0x3b, 0x43, 0x1f, 0x04, 0x3f, 0x0c, 0x05, 0x23,
-0x00, 0x93, 0x84, 0x88, 0x01, 0xab, 0x1c, 0x80, 0x00, 0x24, 0x04, 0x3b,
-0x5c, 0x70, 0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xd9, 0x80, 0x10, 0x04,
-0x38, 0x43, 0x02, 0x90, 0x03, 0x94, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7,
-0x95, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x40, 0x00, 0x14, 0x40, 0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x8a, 0x6a,
-0x05, 0x21, 0x00, 0x91, 0x81, 0x88, 0x01, 0xab, 0x19, 0x80, 0x00, 0x21,
-0x04, 0x3b, 0x59, 0x70, 0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xda, 0x80,
-0x02, 0x91, 0x03, 0x91, 0x68, 0x46, 0xfe, 0xf7, 0x79, 0xff, 0x01, 0x20,
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x40,
-0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0x88, 0x62, 0x00, 0x20, 0x70, 0x47,
-0xc0, 0x00, 0x14, 0x00, 0x00, 0xb5, 0x84, 0xb0, 0x0b, 0x49, 0x0a, 0x6a,
-0x05, 0x21, 0x00, 0x91, 0x81, 0x88, 0x01, 0xab, 0x19, 0x80, 0x00, 0x21,
-0x04, 0x3b, 0x59, 0x70, 0x40, 0x88, 0x00, 0xab, 0x58, 0x80, 0xda, 0x80,
-0x02, 0x91, 0x03, 0x91, 0x68, 0x46, 0xfe, 0xf7, 0x55, 0xff, 0x01, 0x20,
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x40,
-0xc0, 0x88, 0x02, 0x49, 0xc0, 0x46, 0x08, 0x62, 0x00, 0x20, 0x70, 0x47,
-0xc0, 0x00, 0x14, 0x00, 0x00, 0xb5, 0xc0, 0x88, 0x02, 0x49, 0xfe, 0xf7,
-0xf4, 0xfd, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x75, 0x02, 0xff, 0xff,
-0x00, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xfe, 0xf7, 0xf7, 0xff, 0x06, 0x48,
-0x00, 0x6b, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7,
-0x2f, 0xff, 0x01, 0x20, 0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0xfe, 0xf7, 0xfd, 0xff, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xf8, 0xff,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xf3, 0xff, 0x08, 0xbc,
-0x18, 0x47, 0x80, 0xb5, 0x07, 0x1c, 0x10, 0x48, 0xfe, 0xf7, 0xc6, 0xfd,
-0x01, 0x20, 0x40, 0x02, 0xa1, 0x21, 0x49, 0x03, 0x88, 0x60, 0x00, 0x21,
-0x0c, 0x48, 0xc0, 0x46, 0x01, 0x71, 0x0c, 0x48, 0x02, 0x68, 0x52, 0x0c,
-0x05, 0xd2, 0x02, 0x68, 0x12, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a,
-0x03, 0xd3, 0x08, 0x48, 0xc0, 0x46, 0xc7, 0x60, 0x02, 0xe0, 0x07, 0x48,
-0xc0, 0x46, 0x07, 0x64, 0x08, 0x1c, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0xd5, 0x94, 0x21, 0x40, 0x28, 0x0f, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40,
-0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x01, 0x20,
-0x03, 0x49, 0xc0, 0x46, 0x08, 0x72, 0x12, 0x20, 0xff, 0xf7, 0xcb, 0xff,
-0x08, 0xbc, 0x18, 0x47, 0x88, 0x1c, 0x00, 0x80, 0x00, 0xb5, 0x01, 0x20,
-0x03, 0x49, 0xc0, 0x46, 0x48, 0x72, 0x15, 0x20, 0xff, 0xf7, 0xbf, 0xff,
-0x08, 0xbc, 0x18, 0x47, 0x88, 0x1c, 0x00, 0x80, 0x00, 0xb5, 0x01, 0xf0,
-0xf9, 0xff, 0x01, 0x20, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0,
-0x07, 0x1c, 0xf8, 0x88, 0x02, 0xf0, 0xfe, 0xf8, 0x00, 0x28, 0x0c, 0xd1,
-0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0x82, 0xff, 0x06, 0x48, 0x01, 0xab,
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0xbb, 0xfe, 0x01, 0x20,
-0x00, 0xe0, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0xff, 0xff, 0x00, 0x00, 0x80, 0xb5, 0x84, 0xb0, 0x69, 0x46, 0xfe, 0xf7,
-0x6d, 0xff, 0x01, 0x27, 0x01, 0xab, 0x5f, 0x80, 0x09, 0x48, 0x81, 0x89,
-0x09, 0x04, 0xc2, 0x89, 0x11, 0x43, 0x02, 0x91, 0x81, 0x88, 0x09, 0x04,
-0xc0, 0x88, 0x08, 0x43, 0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7,
-0x9b, 0xfe, 0x38, 0x1c, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x4c, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0xfe, 0xf7, 0x69, 0xff, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x64, 0xff, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0xb5, 0xfe, 0xf7, 0x5f, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5,
-0xfe, 0xf7, 0x5a, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7,
-0x55, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x50, 0xff,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x4b, 0xff, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x46, 0xff, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0xb5, 0xfe, 0xf7, 0x41, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5,
-0xfe, 0xf7, 0x3c, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7,
-0x37, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0x32, 0xff,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x8c, 0xb0, 0x08, 0xa9, 0xfe, 0xf7,
-0x13, 0xff, 0x69, 0x46, 0x08, 0xa8, 0x02, 0xf0, 0xa9, 0xff, 0x02, 0x20,
-0x08, 0xab, 0x58, 0x70, 0x69, 0x46, 0x08, 0xa8, 0xfe, 0xf7, 0x48, 0xfe,
-0x01, 0x20, 0x0c, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7,
-0x19, 0xff, 0x08, 0xbc, 0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c,
-0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0xf8, 0xfe, 0xfa, 0x88, 0x12, 0x49,
-0x01, 0x24, 0xc8, 0x1d, 0x89, 0x30, 0x00, 0x2a, 0x0f, 0xd0, 0x04, 0x70,
-0x44, 0x70, 0xb8, 0x68, 0x00, 0x0c, 0x80, 0x31, 0xc8, 0x82, 0xb8, 0x68,
-0xc0, 0x46, 0x08, 0x83, 0xf8, 0x68, 0x00, 0x0c, 0x48, 0x83, 0xf8, 0x68,
-0xc0, 0x46, 0x88, 0x83, 0x02, 0xe0, 0x00, 0x21,
-0x01, 0x70, 0x41, 0x70, 0x06, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46,
-0x00, 0x21, 0xfe, 0xf7, 0x17, 0xfe, 0x20, 0x1c, 0x04, 0xb0, 0x90, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xff, 0xff, 0x00, 0x00,
-0x00, 0xb5, 0xfe, 0xf7, 0xe3, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5,
-0xfe, 0xf7, 0xde, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7,
-0xd9, 0xfe, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xd4, 0xfe,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0xfe, 0xf7, 0xcf, 0xfe, 0x08, 0xbc,
-0x18, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c,
-0xfe, 0xf7, 0xae, 0xfe, 0xf8, 0x88, 0x03, 0x24, 0xe4, 0x04, 0x04, 0x43,
-0x03, 0x23, 0xdb, 0x04, 0x9c, 0x42, 0x02, 0xd3, 0x0f, 0x4b, 0x9c, 0x42,
-0x06, 0xd9, 0x0f, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46, 0x00, 0x21,
-0xfe, 0xf7, 0xdc, 0xfd, 0x01, 0x20, 0x80, 0x07, 0x20, 0x43, 0x00, 0x68,
-0x00, 0x21, 0x00, 0xab, 0x59, 0x70, 0xfa, 0x88, 0xc0, 0x46, 0xda, 0x80,
-0x02, 0x90, 0x03, 0x91, 0x68, 0x46, 0x04, 0x33, 0xfe, 0xf7, 0xcc, 0xfd,
-0x01, 0x20, 0x04, 0xb0, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0xe0, 0x00, 0x18, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0xb5, 0x84, 0xb0,
-0x07, 0x1c, 0x69, 0x46, 0x38, 0x1c, 0xfe, 0xf7, 0x7b, 0xfe, 0xf8, 0x88,
-0x03, 0x23, 0xdb, 0x04, 0x18, 0x43, 0x98, 0x42, 0x02, 0xd3, 0x0a, 0x4b,
-0x98, 0x42, 0x08, 0xd9, 0x09, 0x48, 0x01, 0xab, 0x58, 0x80, 0x68, 0x46,
-0x00, 0x21, 0xfe, 0xf7, 0xab, 0xfd, 0x01, 0x20, 0x03, 0xe0, 0xb9, 0x68,
-0xc0, 0x46, 0x01, 0x60, 0x00, 0x20, 0x04, 0xb0, 0x80, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0xe0, 0x00, 0x18, 0x00, 0xff, 0xff, 0x00, 0x00,
-0x80, 0xb5, 0x86, 0xb0, 0x02, 0xa9, 0xfe, 0xf7, 0x57, 0xfe, 0x01, 0x27,
-0x02, 0xab, 0x5f, 0x70, 0x00, 0x20, 0xd8, 0x80, 0x0a, 0x48, 0x41, 0x68,
-0xc0, 0x46, 0x04, 0x91, 0x81, 0x68, 0xc0, 0x46, 0x05, 0x91, 0xc1, 0x68,
-0xc0, 0x46, 0x00, 0x91, 0x40, 0x69, 0xc0, 0x46, 0x01, 0x90, 0x69, 0x46,
-0x02, 0xa8, 0xfe, 0xf7, 0x81, 0xfd, 0x38, 0x1c, 0x06, 0xb0, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x19, 0x00, 0x80, 0x00, 0xb5, 0xc1, 0x68,
-0x80, 0x68, 0xfe, 0xf7, 0x47, 0xfb, 0x00, 0x20, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0x20, 0x70, 0x47, 0x90, 0xb5, 0x84, 0xb0, 0x04, 0x1c, 0x0f, 0x1c,
-0x68, 0x46, 0x50, 0x21, 0xfe, 0xf7, 0x36, 0xfe, 0x01, 0xab, 0x5c, 0x80,
-0x02, 0x97, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x61, 0xfd, 0x04, 0xb0,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x84, 0xb0, 0x07, 0x1c,
-0x68, 0x46, 0x51, 0x21, 0xfe, 0xf7, 0x24, 0xfe, 0x01, 0xab, 0x5f, 0x80,
-0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x50, 0xfd, 0x04, 0xb0, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47,
-0x90, 0xb5, 0x84, 0xb0, 0x00, 0x27, 0x12, 0x49, 0x09, 0x68, 0x12, 0x4a,
-0x12, 0x6b, 0x10, 0x23, 0x1a, 0x40, 0x01, 0x24, 0x00, 0x2a, 0x00, 0xd0,
-0x01, 0x27, 0x8a, 0x0c, 0x03, 0xd3, 0x3a, 0x04, 0x12, 0x0c, 0x02, 0x27,
-0x17, 0x43, 0xc9, 0x0c, 0x03, 0xd3, 0x39, 0x04, 0x09, 0x0c, 0x04, 0x27,
-0x0f, 0x43, 0x69, 0x46, 0xfe, 0xf7, 0xec, 0xfd, 0x01, 0xab, 0x5f, 0x80,
-0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x26, 0xfd, 0x20, 0x1c, 0x04, 0xb0,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x40, 0x00, 0xb5, 0x84, 0xb0,
-0x69, 0x46, 0xfe, 0xf7, 0xd7, 0xfd, 0x06, 0x48, 0xc0, 0x6d, 0x01, 0xab,
-0x58, 0x80, 0x68, 0x46, 0x00, 0x21, 0xfe, 0xf7, 0x0f, 0xfd, 0x01, 0x20,
-0x04, 0xb0, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80,
-0x00, 0xb5, 0xfe, 0xf7, 0xdd, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x70, 0x47,
-0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47,
-0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47, 0x00, 0x20, 0x70, 0x47,
-0x00, 0xb5, 0xfe, 0xf7, 0xcb, 0xfd, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x80, 0xb5, 0x85, 0xb0, 0x01, 0xa9, 0xfe, 0xf7, 0xab, 0xfd, 0x00, 0x20,
-0x01, 0xab, 0x58, 0x70, 0x0c, 0x49, 0xc9, 0x68, 0x01, 0x27, 0x01, 0x29,
-0x02, 0xd1, 0x03, 0x97, 0x04, 0x97, 0x01, 0xe0, 0x03, 0x97, 0x04, 0x90,
-0x68, 0x46, 0x01, 0xf0, 0x33, 0xfd, 0x02, 0xab, 0x00, 0x98, 0xc0, 0x46,
-0x58, 0x80, 0x00, 0x21, 0x01, 0xa8, 0xfe, 0xf7, 0xd3, 0xfc, 0x38, 0x1c,
-0x05, 0xb0, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0x70, 0x47, 0x04, 0x49, 0x00, 0x20, 0x00, 0x22, 0x0a, 0x70, 0x01, 0x30,
-0x01, 0x31, 0x68, 0x28, 0xfa, 0xd3, 0x70, 0x47, 0xa0, 0x82, 0x20, 0x40,
-0x00, 0x22, 0x88, 0x42, 0x03, 0xd3, 0x40, 0x1a, 0x01, 0x32, 0x88, 0x42,
-0xfb, 0xd2, 0x10, 0x1c, 0x70, 0x47, 0x88, 0x42, 0x02, 0xd3, 0x40, 0x1a,
-0x88, 0x42, 0xfc, 0xd2, 0x70, 0x47, 0x90, 0xb4, 0x01, 0x1c, 0xff, 0x27,
-0x04, 0x29, 0x27, 0xda, 0x00, 0x20, 0x14, 0x4a, 0x43, 0x00, 0x1b, 0x18,
-0xdb, 0x00, 0xd4, 0x58, 0x63, 0x0c, 0x1a, 0xd2, 0x4b, 0x00, 0x59, 0x18,
-0xc9, 0x00, 0x57, 0x58, 0x43, 0x00, 0x1b, 0x18, 0xdb, 0x00, 0xd7, 0x50,
-0x89, 0x18, 0x9a, 0x18, 0x4f, 0x68, 0xc0, 0x46, 0x57, 0x60, 0x8b, 0x68,
-0xc0, 0x46, 0x93, 0x60, 0x0b, 0x69, 0xc0, 0x46, 0x13, 0x61, 0x4b, 0x69,
-0xc0, 0x46, 0x53, 0x61, 0xc9, 0x68, 0xc0, 0x46, 0xd1, 0x60, 0x90, 0xbc,
-0x70, 0x47, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x04, 0x28, 0xd9, 0xdb,
-0x38, 0x1c, 0xf6, 0xe7, 0x40, 0xab, 0x20, 0x40, 0xf7, 0xb5, 0xc4, 0xb0,
-0x04, 0x1c, 0x00, 0x20, 0x46, 0x9a, 0x11, 0x21, 0x11, 0x40, 0x6e, 0xd0,
-0x00, 0x27, 0x79, 0x00, 0xc9, 0x19, 0xc9, 0x00, 0x57, 0x4a, 0x51, 0x58,
-0x49, 0x0c, 0x03, 0xd2, 0x01, 0x30, 0x00, 0x06, 0x00, 0x0e, 0x04, 0xe0,
-0x79, 0x1c, 0x0f, 0x06, 0x3f, 0x0e, 0x04, 0x2f, 0xef, 0xdb, 0x00, 0x28,
-0x5b, 0xd0, 0x00, 0x26, 0x00, 0x22, 0x00, 0x92, 0x40, 0x23, 0x00, 0x21,
-0x00, 0x20, 0x02, 0xaa, 0x00, 0xf0, 0x88, 0xfa, 0x04, 0xa9, 0x00, 0x20,
-0x82, 0x00, 0x8a, 0x58, 0x12, 0x06, 0x12, 0x0e, 0xa2, 0x42, 0x03, 0xd1,
-0x72, 0x1c, 0x16, 0x06, 0x36, 0x0e, 0x04, 0xe0, 0x01, 0x30, 0x00, 0x06,
-0x00, 0x0e, 0x10, 0x28, 0xf0, 0xdb, 0x00, 0x2e, 0x3d, 0xd0, 0x04, 0x2c,
-0x3e, 0xd1, 0x80, 0x00, 0x08, 0x58, 0x40, 0x01, 0x80, 0x0d, 0x00, 0x22,
-0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x02, 0xaa, 0x00, 0xf0, 0x68, 0xfa,
-0x00, 0x21, 0x01, 0x91, 0x02, 0xa8, 0x05, 0x99, 0x49, 0x0c, 0x89, 0x05,
-0x29, 0xd0, 0xc1, 0x68, 0x0a, 0x06, 0x12, 0x0e, 0x45, 0x9b, 0x9a, 0x42,
-0x11, 0xd1, 0xc0, 0x68, 0x40, 0x01, 0x86, 0x0d, 0x00, 0x22, 0x00, 0x92,
-0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x02, 0xaa, 0x00, 0xf0, 0x50, 0xfa,
-0x01, 0x99, 0x02, 0x9d, 0x48, 0x1c, 0x01, 0x06,
-0x09, 0x0e, 0x01, 0x91, 0x0e, 0xe0, 0x48, 0x01, 0x86, 0x0d, 0x00, 0x22,
-0x00, 0x92, 0x10, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x02, 0xaa, 0x00, 0xf0,
-0x3f, 0xfa, 0x02, 0xa8, 0x05, 0x99, 0x49, 0x0c, 0x89, 0x05, 0xd8, 0xd1,
-0x01, 0x99, 0x00, 0x29, 0x0f, 0xd1, 0xff, 0x20, 0x3d, 0xe0, 0x40, 0xe0,
-0x80, 0x00, 0x08, 0x58, 0x40, 0x01, 0x86, 0x0d, 0x00, 0x22, 0x00, 0x92,
-0x0c, 0x23, 0x00, 0x21, 0x30, 0x1c, 0x02, 0xaa, 0x00, 0xf0, 0x28, 0xfa,
-0x02, 0x9d, 0x01, 0x20, 0x00, 0x04, 0x46, 0x9a, 0x10, 0x43, 0x79, 0x00,
-0xc9, 0x19, 0xc9, 0x00, 0x17, 0x4a, 0xc0, 0x46, 0x50, 0x50, 0x30, 0x1c,
-0x8e, 0x18, 0x70, 0x60, 0x10, 0x20, 0x04, 0x2c, 0x00, 0xd0, 0x0c, 0x20,
-0x04, 0x1c, 0xb0, 0x60, 0x00, 0x20, 0x20, 0x21, 0x46, 0x9a, 0x11, 0x40,
-0x20, 0x29, 0x00, 0xd0, 0x28, 0x1c, 0x30, 0x61, 0x28, 0x19, 0xff, 0x21,
-0xff, 0x30, 0x08, 0x30, 0x09, 0x31, 0xff, 0xf7, 0x19, 0xff, 0x43, 0x01,
-0x18, 0x18, 0xc0, 0x00, 0x00, 0x1b, 0x70, 0x61, 0x00, 0x20, 0x50, 0x21,
-0x46, 0x9a, 0x11, 0x40, 0x50, 0x29, 0x00, 0xd1, 0x28, 0x1c, 0xf0, 0x60,
-0x38, 0x1c, 0x47, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xff, 0x20,
-0xf9, 0xe7, 0x00, 0x00, 0x40, 0xab, 0x20, 0x40, 0x80, 0xb4, 0x00, 0x23,
-0x00, 0x22, 0x00, 0x29, 0x06, 0xd9, 0x87, 0x5c, 0x7b, 0x40, 0x1b, 0x06,
-0x1b, 0x0e, 0x01, 0x32, 0x8a, 0x42, 0xf8, 0xd3, 0xd8, 0x43, 0x00, 0x06,
-0x00, 0x0e, 0x80, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0xc6, 0xb0, 0x04, 0x28,
-0x07, 0xda, 0x41, 0x00, 0x09, 0x18, 0xc9, 0x00, 0x45, 0x91, 0x41, 0x4a,
-0x51, 0x58, 0x4b, 0x0c, 0x02, 0xd2, 0x00, 0x20, 0xc0, 0x43, 0x76, 0xe0,
-0x01, 0x23, 0x5b, 0x04, 0x19, 0x40, 0x43, 0x00, 0x18, 0x18, 0xc0, 0x00,
-0x3a, 0x4a, 0x14, 0x18, 0x00, 0x29, 0x61, 0xd0, 0x00, 0x21, 0x02, 0x91,
-0x20, 0x69, 0xa1, 0x68, 0x45, 0x18, 0x30, 0xd0, 0xff, 0x21, 0x68, 0x1e,
-0x09, 0x31, 0xff, 0xf7, 0xcd, 0xfe, 0x61, 0x68, 0x40, 0x18, 0x01, 0x90,
-0x01, 0x98, 0x81, 0x42, 0x02, 0xd1, 0xa6, 0x68, 0xaf, 0x1b, 0x09, 0xe0,
-0x00, 0x26, 0xff, 0x21, 0x28, 0x1c, 0x09, 0x31, 0xff, 0xf7, 0xc7, 0xfe,
-0x07, 0x1c, 0x01, 0xd1, 0xff, 0x27, 0x09, 0x37, 0x00, 0x22, 0x00, 0x92,
-0x01, 0x98, 0x31, 0x1c, 0x03, 0xaa, 0x3b, 0x1c, 0x00, 0xf0, 0x9e, 0xf9,
-0x03, 0xa8, 0x39, 0x1c, 0xff, 0xf7, 0xac, 0xff, 0xc0, 0x43, 0x02, 0x99,
-0x48, 0x40, 0x01, 0x06, 0x09, 0x0e, 0x02, 0x91, 0xed, 0x1b, 0xa0, 0x68,
-0xa8, 0x42, 0x00, 0xd1, 0x00, 0x25, 0x00, 0x2d, 0xce, 0xd8, 0x02, 0x99,
-0xcf, 0x43, 0x00, 0x22, 0x00, 0x92, 0x0c, 0x23, 0x00, 0x21, 0x60, 0x68,
-0x03, 0xaa, 0x00, 0xf0, 0x83, 0xf9, 0x20, 0x69, 0xc0, 0x46, 0x03, 0x90,
-0x05, 0x98, 0x00, 0x0a, 0x00, 0x02, 0x39, 0x06, 0x09, 0x0e, 0x08, 0x43,
-0x05, 0x90, 0xff, 0x23, 0x1b, 0x02, 0x98, 0x43, 0x05, 0x90, 0x0c, 0x21,
-0x03, 0xa8, 0xff, 0xf7, 0x83, 0xff, 0xff, 0x23, 0x1b, 0x02, 0x05, 0x99,
-0x99, 0x43, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x02, 0x08, 0x43, 0x05, 0x90,
-0x0c, 0x23, 0x00, 0x21, 0x60, 0x68, 0x03, 0xaa, 0x00, 0xf0, 0xca, 0xf9,
-0x00, 0x20, 0x45, 0x99, 0x06, 0x4a, 0xc0, 0x46, 0x50, 0x50, 0xc1, 0x43,
-0x61, 0x60, 0xa1, 0x60, 0xe1, 0x60, 0x21, 0x61, 0x61, 0x61, 0x46, 0xb0,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x40, 0xab, 0x20, 0x40,
-0xb0, 0xb4, 0x4c, 0x42, 0x00, 0x29, 0x00, 0xdb,
-0x0c, 0x1c, 0x00, 0x27, 0xff, 0x43, 0x04, 0x28, 0x21, 0xda, 0x12, 0x4d,
-0x43, 0x00, 0x18, 0x18, 0xc0, 0x00, 0x40, 0x19, 0x01, 0x2a, 0x05, 0xd0,
-0x02, 0x2a, 0x09, 0xd0, 0x03, 0x2a, 0x16, 0xd1, 0x01, 0x69, 0x0b, 0xe0,
-0x00, 0x29, 0x12, 0xdb, 0x02, 0x69, 0x8a, 0x42, 0x0f, 0xd3, 0x05, 0xe0,
-0x00, 0x29, 0x07, 0xda, 0xc1, 0x68, 0xa1, 0x42, 0x09, 0xd3, 0x09, 0x1b,
-0xc1, 0x60, 0xc0, 0x68, 0xb0, 0xbc, 0x70, 0x47, 0xc1, 0x68, 0x09, 0x19,
-0x02, 0x69, 0x91, 0x42, 0xf6, 0xd9, 0x38, 0x1c, 0xf6, 0xe7, 0x00, 0x00,
-0x40, 0xab, 0x20, 0x40, 0xf0, 0xb5, 0x84, 0xb0, 0x17, 0x1c, 0x0d, 0x1c,
-0x00, 0x21, 0x02, 0x91, 0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x2c, 0x49,
-0x8b, 0x58, 0x1b, 0x06, 0x1b, 0x0e, 0x01, 0x93, 0x00, 0x23, 0xdb, 0x43,
-0x04, 0x28, 0x02, 0xda, 0x01, 0x98, 0x40, 0x08, 0x01, 0xd2, 0x18, 0x1c,
-0x46, 0xe0, 0x54, 0x18, 0xe0, 0x68, 0xc2, 0x19, 0x21, 0x69, 0x8a, 0x42,
-0x00, 0xd9, 0x0f, 0x1a, 0x00, 0x2f, 0x3c, 0xd9, 0xa0, 0x68, 0xe1, 0x68,
-0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 0x0d, 0xfe, 0x61, 0x68,
-0x46, 0x18, 0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21, 0x09, 0x31,
-0xff, 0xf7, 0x0d, 0xfe, 0xc2, 0x19, 0xff, 0x21, 0x09, 0x31, 0x8a, 0x42,
-0x14, 0xd9, 0x01, 0x9a, 0xc0, 0x46, 0x00, 0x92, 0x0b, 0x1a, 0x03, 0x93,
-0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 0x00, 0xf0, 0xe1, 0xf8, 0xe0, 0x68,
-0x03, 0x9b, 0xc0, 0x18, 0xe0, 0x60, 0x03, 0x9b, 0x5d, 0x19, 0xff, 0x1a,
-0x02, 0x98, 0x18, 0x18, 0x02, 0x90, 0x10, 0xe0, 0x01, 0x9a, 0xc0, 0x46,
-0x00, 0x92, 0x01, 0x1c, 0x30, 0x1c, 0x2a, 0x1c, 0x3b, 0x1c, 0x00, 0xf0,
-0xcd, 0xf8, 0xe0, 0x68, 0xc0, 0x19, 0xed, 0x19, 0xe0, 0x60, 0x02, 0x98,
-0xc0, 0x19, 0x02, 0x90, 0x00, 0x27, 0x00, 0x2f, 0xc2, 0xd8, 0x02, 0x98,
-0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x40, 0xab, 0x20, 0x40,
-0xf0, 0xb5, 0x83, 0xb0, 0x17, 0x1c, 0x0d, 0x1c, 0x00, 0x21, 0x01, 0x91,
-0x42, 0x00, 0x12, 0x18, 0xd2, 0x00, 0x02, 0x92, 0x30, 0x49, 0x8a, 0x58,
-0x12, 0x06, 0x12, 0x0e, 0x00, 0x24, 0xe4, 0x43, 0x04, 0x28, 0x01, 0xda,
-0x50, 0x09, 0x01, 0xd2, 0x20, 0x1c, 0x51, 0xe0, 0x02, 0x9a, 0x54, 0x18,
-0xe0, 0x68, 0xc2, 0x19, 0x60, 0x69, 0x82, 0x42, 0x01, 0xd9, 0x22, 0x69,
-0x87, 0x1a, 0x00, 0x2f, 0x45, 0xd9, 0x25, 0x4e, 0xa0, 0x68, 0xe1, 0x68,
-0x40, 0x18, 0xff, 0x21, 0x09, 0x31, 0xff, 0xf7, 0xa7, 0xfd, 0x61, 0x68,
-0x40, 0x18, 0x00, 0x90, 0xa0, 0x68, 0xe1, 0x68, 0x40, 0x18, 0xff, 0x21,
-0x09, 0x31, 0xff, 0xf7, 0xa6, 0xfd, 0x02, 0x9a, 0xb1, 0x58, 0x01, 0x23,
-0x5b, 0x04, 0x19, 0x43, 0xb1, 0x50, 0xc1, 0x19, 0xff, 0x22, 0x09, 0x32,
-0x91, 0x42, 0x13, 0xd9, 0x13, 0x1a, 0x01, 0x1c, 0x00, 0x98, 0x2a, 0x1c,
-0x1e, 0x1c, 0x00, 0xf0, 0xdf, 0xf8, 0xe0, 0x68, 0x80, 0x19, 0x75, 0x19,
-0xe0, 0x60, 0x21, 0x69, 0x88, 0x42, 0x00, 0xd9, 0x20, 0x61, 0xbf, 0x1b,
-0x01, 0x98, 0x30, 0x18, 0x01, 0x90, 0x12, 0xe0, 0x01, 0x1c, 0x00, 0x9e,
-0x30, 0x1c, 0x2a, 0x1c, 0x3b, 0x1c, 0x00, 0xf0, 0xcb, 0xf8, 0xe0, 0x68,
-0xc0, 0x19, 0xed, 0x19, 0xe0, 0x60, 0x21, 0x69, 0x88, 0x42, 0x00, 0xd9,
-0x20, 0x61, 0x01, 0x98, 0xc0, 0x19, 0x01, 0x90, 0x00, 0x27, 0x00, 0x2f,
-0xb9, 0xd8, 0x01, 0x98, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x40, 0xab, 0x20, 0x40, 0xb0, 0xb5, 0xc3, 0xb0,
-0x0c, 0x1c, 0x00, 0x27, 0xfa, 0x43, 0x04, 0x28, 0x06, 0xda, 0x41, 0x00,
-0x09, 0x18, 0xc9, 0x00, 0x14, 0x48, 0x45, 0x58, 0x6b, 0x0c, 0x04, 0xd2,
-0x10, 0x1c, 0x43, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x62, 0x09,
-0x1b, 0xd3, 0x00, 0x22, 0x00, 0x92, 0x08, 0x18, 0x40, 0x68, 0x0c, 0x23,
-0x00, 0x21, 0x01, 0xaa, 0x00, 0xf0, 0x30, 0xf8, 0x11, 0x2c, 0x0d, 0xd0,
-0x12, 0x2c, 0x0d, 0xd0, 0x13, 0x2c, 0x05, 0xd0, 0x14, 0x2c, 0x0a, 0xd1,
-0x03, 0x98, 0x00, 0x04, 0x07, 0x0e, 0x06, 0xe0, 0x03, 0x98, 0x07, 0x06,
-0x3f, 0x0e, 0x02, 0xe0, 0x01, 0x9f, 0x00, 0xe0, 0x02, 0x9f, 0x38, 0x1c,
-0xdb, 0xe7, 0x00, 0x00, 0x40, 0xab, 0x20, 0x40, 0x03, 0x49, 0x00, 0x20,
-0x00, 0x22, 0x0a, 0x54, 0x01, 0x30, 0x60, 0x28, 0xfb, 0xd3, 0x70, 0x47,
-0x40, 0xab, 0x20, 0x40, 0x00, 0xb5, 0x02, 0xf0, 0x6f, 0xfa, 0x57, 0x20,
-0x02, 0xf0, 0xcc, 0xf9, 0x02, 0xf0, 0x40, 0xf9, 0x00, 0x0a, 0xfb, 0xd3,
-0x02, 0xf0, 0x4e, 0xfa, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5, 0x82, 0xb0,
-0x07, 0x9d, 0x14, 0x1c, 0x1f, 0x1c, 0x30, 0x4a, 0xd2, 0x6f, 0x20, 0x23,
-0x16, 0x68, 0x9e, 0x43, 0x16, 0x60, 0x33, 0x1c, 0xff, 0x22, 0x01, 0x32,
-0x2a, 0x40, 0x40, 0x02, 0x08, 0x43, 0x05, 0x0a, 0x06, 0x1c, 0x00, 0x0c,
-0x01, 0x90, 0x00, 0x2a, 0x20, 0xd0, 0x02, 0xf0, 0x4b, 0xfa, 0x53, 0x20,
-0x02, 0xf0, 0xa8, 0xf9, 0x01, 0x98, 0xc0, 0x46, 0x00, 0x90, 0x02, 0xf0,
-0xa3, 0xf9, 0x28, 0x1c, 0x02, 0xf0, 0xa0, 0xf9, 0x30, 0x1c, 0x02, 0xf0,
-0x9d, 0xf9, 0x02, 0xf0, 0x23, 0xfa, 0xff, 0xf7, 0xc7, 0xff, 0x02, 0xf0,
-0x37, 0xfa, 0x54, 0x20, 0x02, 0xf0, 0x94, 0xf9, 0x00, 0x98, 0x02, 0xf0,
-0x91, 0xf9, 0x28, 0x1c, 0x02, 0xf0, 0x8e, 0xf9, 0x30, 0x1c, 0x14, 0xe0,
-0x02, 0xf0, 0x2a, 0xfa, 0x52, 0x20, 0x02, 0xf0, 0x87, 0xf9, 0x01, 0x98,
-0x02, 0xf0, 0x84, 0xf9, 0x28, 0x1c, 0x02, 0xf0, 0x81, 0xf9, 0x30, 0x1c,
-0x02, 0xf0, 0x7e, 0xf9, 0x00, 0x20, 0x02, 0xf0, 0x7b, 0xf9, 0x00, 0x20,
-0x02, 0xf0, 0x78, 0xf9, 0x00, 0x20, 0x02, 0xf0, 0x75, 0xf9, 0x00, 0x20,
-0x02, 0xf0, 0x72, 0xf9, 0x00, 0x2f, 0x05, 0xd9, 0x02, 0xf0, 0xe4, 0xf8,
-0x20, 0x70, 0x01, 0x34, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 0xf0, 0xf9,
-0x04, 0x4a, 0xd0, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60,
-0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0xf0, 0xb5, 0x82, 0xb0, 0x14, 0x1c, 0x1f, 0x1c, 0x42, 0x02, 0x0a, 0x43,
-0x15, 0x1c, 0x01, 0x28, 0x54, 0xd0, 0x2c, 0x49, 0xc8, 0x6f, 0x20, 0x23,
-0x02, 0x68, 0x9a, 0x43, 0x02, 0x60, 0xc8, 0x6f, 0x40, 0x23, 0x01, 0x68,
-0x19, 0x43, 0x01, 0x60, 0x02, 0xf0, 0xe6, 0xf9, 0x53, 0x20, 0x02, 0xf0,
-0x43, 0xf9, 0x28, 0x0c, 0x06, 0x1c, 0x02, 0xf0, 0x3f, 0xf9, 0x28, 0x0a,
-0x01, 0x90, 0x00, 0x90, 0x02, 0xf0, 0x3a, 0xf9, 0x28, 0x1c, 0x02, 0xf0,
-0x37, 0xf9, 0x02, 0xf0, 0xbd, 0xf9, 0xff, 0xf7, 0x61, 0xff, 0x02, 0xf0,
-0xd1, 0xf9, 0x84, 0x20, 0x02, 0xf0, 0x2e, 0xf9, 0x30, 0x1c, 0x02, 0xf0,
-0x2b, 0xf9, 0x00, 0x98, 0x02, 0xf0, 0x28, 0xf9, 0x28, 0x1c, 0x02, 0xf0,
-0x25, 0xf9, 0x00, 0x2f, 0x05, 0xd9, 0x20, 0x78, 0x01, 0x34, 0x02, 0xf0,
-0x1f, 0xf9, 0x01, 0x3f, 0xf9, 0xd1, 0x02, 0xf0, 0xa3, 0xf9, 0x02, 0xf0,
-0xb9, 0xf9, 0x83, 0x20, 0x02, 0xf0, 0x16, 0xf9, 0x30, 0x1c, 0x02, 0xf0,
-0x13, 0xf9, 0x01, 0x98, 0x02, 0xf0, 0x10, 0xf9,
-0x28, 0x1c, 0x02, 0xf0, 0x0d, 0xf9, 0x02, 0xf0, 0x93, 0xf9, 0xff, 0xf7,
-0x37, 0xff, 0x07, 0x49, 0xc8, 0x6f, 0x40, 0x23, 0x02, 0x68, 0x9a, 0x43,
-0x02, 0x60, 0xc8, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60,
-0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0x70, 0x47, 0x00, 0x00, 0x80, 0xb5, 0x01, 0xf0, 0x8f, 0xf8, 0x06, 0x4f,
-0xc0, 0x46, 0xf8, 0x60, 0x01, 0xf0, 0xf2, 0xf8, 0x78, 0x80, 0x01, 0xf0,
-0xb1, 0xf8, 0x38, 0x71, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0xb5, 0x01, 0xf0, 0x05, 0xf9, 0x02, 0x49,
-0xc0, 0x46, 0x08, 0x80, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0x0b, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x11, 0xd1, 0xc1, 0x6f, 0x02, 0x23,
-0x0a, 0x68, 0x1a, 0x43, 0x0a, 0x60, 0xc1, 0x6f, 0x80, 0x23, 0x0a, 0x68,
-0x1a, 0x43, 0x0a, 0x60, 0xc1, 0x18, 0x08, 0x68, 0x82, 0x23, 0x02, 0x68,
-0x1a, 0x43, 0x02, 0x60, 0x00, 0x20, 0x08, 0x81, 0x70, 0x47, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb4, 0x4a, 0x49, 0xca, 0x1d, 0x9d, 0x32,
-0x00, 0x20, 0x00, 0x27, 0x83, 0x00, 0xd7, 0x50, 0x01, 0x30, 0x17, 0x28,
-0xfa, 0xd3, 0x46, 0x4c, 0x00, 0x20, 0x82, 0x00, 0xa7, 0x50, 0x01, 0x30,
-0x20, 0x28, 0xfa, 0xd3, 0x43, 0x4a, 0x00, 0x20, 0x83, 0x00, 0xd7, 0x50,
-0x01, 0x30, 0x20, 0x28, 0xfa, 0xd3, 0xa7, 0x61, 0x97, 0x61, 0x4f, 0x65,
-0x8f, 0x65, 0x3f, 0x4d, 0xc0, 0x46, 0x2f, 0x60, 0x6f, 0x60, 0xaf, 0x60,
-0xaf, 0x61, 0xef, 0x60, 0x2f, 0x61, 0x6f, 0x61, 0x00, 0x20, 0xc1, 0x00,
-0x09, 0x18, 0x49, 0x01, 0x35, 0x4b, 0xc9, 0x18, 0x86, 0x00, 0xcb, 0x1d,
-0xf9, 0x33, 0x34, 0x4c, 0x34, 0x19, 0xe3, 0x63, 0x11, 0x23, 0x5b, 0x01,
-0xcb, 0x18, 0x63, 0x63, 0x0d, 0x23, 0x9b, 0x01, 0xcb, 0x18, 0xb4, 0x18,
-0xe3, 0x63, 0x23, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x61, 0x63, 0x01, 0x30,
-0x02, 0x28, 0xe4, 0xdb, 0x29, 0x48, 0xc1, 0x1d, 0xf9, 0x31, 0x29, 0x4c,
-0xc0, 0x46, 0xa1, 0x62, 0x61, 0x6b, 0x0d, 0x23, 0x9b, 0x01, 0xe1, 0x62,
-0xc1, 0x18, 0x91, 0x62, 0x51, 0x6b, 0xc0, 0x46, 0xd1, 0x62, 0x08, 0x21,
-0xe1, 0x64, 0x25, 0x49, 0xc0, 0x46, 0x21, 0x65, 0x24, 0x49, 0x0b, 0x69,
-0xc0, 0x46, 0x63, 0x65, 0xc3, 0x1d, 0x4d, 0x33, 0xe3, 0x65, 0x25, 0x66,
-0x8b, 0x68, 0xc0, 0x46, 0x63, 0x66, 0xcb, 0x68, 0xc0, 0x46, 0xa3, 0x66,
-0x1e, 0x4b, 0xc0, 0x46, 0xe3, 0x66, 0x27, 0x67, 0x0b, 0x23, 0xdb, 0x01,
-0xc3, 0x18, 0xa3, 0x67, 0x67, 0x67, 0x01, 0x26, 0xe3, 0x1d, 0x69, 0x33,
-0x66, 0x61, 0xe7, 0x61, 0x1f, 0x73, 0x02, 0x23, 0xd3, 0x64, 0x17, 0x4b,
-0xc0, 0x46, 0x13, 0x65, 0xcb, 0x69, 0xc0, 0x46, 0x53, 0x65, 0xc3, 0x1d,
-0x51, 0x33, 0xd3, 0x65, 0x2b, 0x1d, 0x13, 0x66, 0x4b, 0x69, 0xc0, 0x46,
-0x53, 0x66, 0x89, 0x69, 0xc0, 0x46, 0x91, 0x66, 0x0f, 0x49, 0xc0, 0x46,
-0xd1, 0x66, 0x16, 0x67, 0x0f, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x90, 0x67,
-0x56, 0x67, 0xd7, 0x61, 0xd0, 0x1d, 0x69, 0x30, 0x56, 0x61, 0x07, 0x73,
-0xf0, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xe4, 0x2c, 0x00, 0x80,
-0x64, 0x2d, 0x00, 0x80, 0x90, 0xee, 0x20, 0x40, 0x30, 0x01, 0x18, 0x00,
-0x7c, 0x29, 0x00, 0x80, 0x00, 0x55, 0xff, 0xff, 0x38, 0x01, 0x18, 0x00,
-0x10, 0x55, 0xff, 0xff, 0x90, 0xb4, 0x00, 0x21, 0x1e, 0x4a, 0xbb, 0x23,
-0x1b, 0x01, 0xd7, 0x18, 0xf9, 0x73, 0x19, 0x23,
-0xdb, 0x01, 0xd0, 0x18, 0x01, 0x24, 0xcd, 0x23, 0x1b, 0x01, 0xd3, 0x18,
-0xc1, 0x61, 0x1c, 0x70, 0x33, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x99, 0x60,
-0xb9, 0x73, 0x59, 0x61, 0x2f, 0x23, 0x9b, 0x01, 0xd3, 0x18, 0x19, 0x60,
-0x13, 0x4b, 0x51, 0x27, 0xbf, 0x03, 0x03, 0x63, 0x3b, 0x60, 0x84, 0x69,
-0xe4, 0x18, 0x44, 0x63, 0x04, 0x3c, 0x7c, 0x60, 0x01, 0x24, 0xe4, 0x02,
-0x84, 0x63, 0x0e, 0x4c, 0xc0, 0x46, 0xbc, 0x60, 0x04, 0x6b, 0xc0, 0x46,
-0x44, 0x62, 0x84, 0x69, 0xe4, 0x18, 0x0b, 0x4b, 0xe3, 0x18, 0xfb, 0x60,
-0x03, 0x6b, 0xc0, 0x46, 0x83, 0x62, 0x43, 0x6a, 0xc0, 0x46, 0x03, 0x62,
-0xc1, 0x63, 0x51, 0x64, 0x91, 0x64, 0xd1, 0x65, 0xd1, 0x66, 0x90, 0xbc,
-0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40,
-0xfc, 0x07, 0x00, 0x00, 0xfc, 0xf7, 0xff, 0xff, 0x90, 0xb4, 0x00, 0x22,
-0x1b, 0x49, 0xc9, 0x23, 0x1b, 0x01, 0xc8, 0x18, 0x02, 0x71, 0x01, 0x20,
-0xbb, 0x23, 0x1b, 0x01, 0xcb, 0x18, 0x58, 0x73, 0x17, 0x48, 0x03, 0x1c,
-0x00, 0x27, 0xdc, 0x1d, 0xc1, 0x34, 0x1c, 0x65, 0x23, 0x1c, 0x01, 0x37,
-0x3f, 0x2f, 0xf8, 0xd3, 0x1a, 0x65, 0x19, 0x23, 0xdb, 0x01, 0xcf, 0x18,
-0x33, 0x23, 0x9b, 0x01, 0xcb, 0x18, 0x3a, 0x61, 0x98, 0x61, 0x40, 0x20,
-0xf8, 0x60, 0xda, 0x61, 0x1a, 0x62, 0xca, 0x64, 0x0a, 0x66, 0x0c, 0x48,
-0xc0, 0x46, 0xc2, 0x60, 0x0b, 0x48, 0x00, 0x6b, 0xc0, 0x06, 0xc0, 0x0e,
-0xf8, 0x63, 0x0a, 0x48, 0x01, 0x68, 0xc0, 0x46, 0x19, 0x80, 0x41, 0x68,
-0xc0, 0x46, 0x59, 0x80, 0x80, 0x68, 0xc0, 0x46, 0x98, 0x80, 0x90, 0xbc,
-0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x90, 0xbc, 0x20, 0x40,
-0x90, 0xee, 0x20, 0x40, 0x80, 0x00, 0x14, 0x40, 0x40, 0x00, 0x14, 0x40,
-0x00, 0x20, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x73, 0xcb, 0x1d, 0xff, 0x33,
-0x3a, 0x33, 0x88, 0x61, 0xc8, 0x61, 0x18, 0x70, 0x06, 0x4a, 0xc0, 0x46,
-0x10, 0x65, 0x50, 0x66, 0x90, 0x66, 0x08, 0x70, 0x58, 0x70, 0xbb, 0x23,
-0x1b, 0x01, 0xd1, 0x18, 0x08, 0x73, 0x70, 0x47, 0x28, 0x05, 0x00, 0x80,
-0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb4, 0x2f, 0x49, 0x2f, 0x4a, 0xc0, 0x46,
-0x11, 0x61, 0x01, 0x23, 0x9b, 0x02, 0xc8, 0x18, 0x50, 0x61, 0x2d, 0x48,
-0xc0, 0x46, 0x10, 0x62, 0xdb, 0x00, 0xc3, 0x18, 0x53, 0x62, 0x00, 0x23,
-0x13, 0x63, 0x53, 0x63, 0x29, 0x4a, 0x2a, 0x4f, 0xd4, 0x1d, 0xff, 0x34,
-0xfa, 0x34, 0x14, 0xc7, 0x08, 0x3f, 0x3b, 0x61, 0x1c, 0x1f, 0x7c, 0x61,
-0x26, 0x4f, 0xc0, 0x46, 0x39, 0x60, 0xb8, 0x61, 0x79, 0x61, 0xf8, 0x62,
-0x3b, 0x63, 0x7b, 0x64, 0xba, 0x64, 0xfa, 0x65, 0x22, 0x4f, 0xfe, 0x1d,
-0xf9, 0x36, 0x22, 0x4d, 0xec, 0x1d, 0x79, 0x34, 0x26, 0x62, 0x51, 0x26,
-0xb6, 0x03, 0x37, 0x61, 0x24, 0x6a, 0xc0, 0x46, 0x74, 0x61, 0x2f, 0x67,
-0x1d, 0x4d, 0x09, 0x27, 0x7f, 0x04, 0xec, 0x1d, 0x75, 0x34, 0x7c, 0x60,
-0x3d, 0x60, 0x1b, 0x4c, 0xc0, 0x46, 0x3c, 0x61, 0xe6, 0x1d, 0x75, 0x36,
-0x7e, 0x61, 0x19, 0x4f, 0xc0, 0x46, 0x7c, 0x60, 0x3d, 0x60, 0x0f, 0x1c,
-0x00, 0x21, 0xff, 0x24, 0x01, 0x34, 0x1d, 0x1c, 0x8b, 0x00, 0xfd, 0x50,
-0x01, 0x31, 0xa1, 0x42, 0xfa, 0xd3, 0x01, 0x1c, 0x00, 0x20, 0x01, 0x27,
-0xff, 0x02, 0x83, 0x00, 0xcd, 0x50, 0x01, 0x30, 0xb8, 0x42, 0xfa, 0xd3,
-0x00, 0x20, 0x81, 0x00, 0x55, 0x50, 0x01, 0x30, 0x80, 0x28, 0xfa, 0xd3,
-0xf0, 0xbc, 0x70, 0x47, 0x24, 0xa3, 0x20, 0x40,
-0x40, 0x01, 0x18, 0x00, 0x24, 0x83, 0x20, 0x40, 0x24, 0xa9, 0x20, 0x40,
-0x80, 0x01, 0x18, 0x00, 0xa8, 0x03, 0x00, 0x80, 0x24, 0xa7, 0x20, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0x24, 0xa8, 0x20, 0x40, 0xa4, 0xa8, 0x20, 0x40,
-0x08, 0x04, 0x00, 0x80, 0xb8, 0xb5, 0x2c, 0x48, 0xfd, 0xf7, 0xba, 0xfd,
-0x01, 0x20, 0x2b, 0x49, 0x0a, 0x68, 0x52, 0x0c, 0x06, 0xd2, 0x0a, 0x68,
-0x12, 0x0c, 0x02, 0xd1, 0x0a, 0x68, 0x92, 0x0a, 0x00, 0xd2, 0x00, 0x20,
-0x04, 0x06, 0x24, 0x0e, 0x25, 0x4a, 0xd7, 0x1d, 0x0d, 0x37, 0x00, 0x23,
-0x00, 0x20, 0x9d, 0x00, 0x78, 0x51, 0x01, 0x33, 0x04, 0x2b, 0xfa, 0xd3,
-0x01, 0x27, 0x3f, 0x05, 0x50, 0x61, 0xf8, 0x60, 0xd0, 0x61, 0xf8, 0x61,
-0x00, 0x23, 0xdb, 0x43, 0x93, 0x61, 0x3b, 0x61, 0x13, 0x62, 0x3b, 0x62,
-0x00, 0x27, 0x1b, 0x4b, 0x8d, 0x68, 0xc0, 0x46, 0x00, 0x95, 0x8d, 0x69,
-0xc0, 0x46, 0x00, 0x95, 0x00, 0x2c, 0x0b, 0xd0, 0xdd, 0x6b, 0xc0, 0x46,
-0x00, 0x95, 0x9d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x5d, 0x6b, 0xc0, 0x46,
-0x00, 0x95, 0x1d, 0x6b, 0xc0, 0x46, 0x00, 0x95, 0x01, 0x37, 0x40, 0x2f,
-0xe8, 0xd3, 0x00, 0x27, 0x6c, 0x46, 0x01, 0x23, 0x5b, 0x07, 0x1c, 0x43,
-0x01, 0xe0, 0x20, 0x60, 0x01, 0x37, 0x0d, 0x68, 0x2b, 0x09, 0x02, 0xd2,
-0x80, 0x2f, 0xf8, 0xd3, 0x01, 0xe0, 0x80, 0x2f, 0x03, 0xd3, 0x08, 0x49,
-0x4b, 0x6e, 0x01, 0x33, 0x4b, 0x66, 0xd0, 0x62, 0xb8, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0xf4, 0x01, 0xff, 0xff, 0x00, 0x00, 0x10, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0x01, 0x18, 0x40, 0xa0, 0x82, 0x20, 0x40,
-0x90, 0xb4, 0x00, 0x21, 0x0e, 0x4f, 0x0f, 0x4a, 0x00, 0x20, 0x4c, 0x01,
-0x64, 0x1a, 0xa4, 0x00, 0xa3, 0x18, 0x58, 0x60, 0x98, 0x60, 0x18, 0x64,
-0x58, 0x64, 0x10, 0x53, 0x58, 0x80, 0xcc, 0x00, 0xe4, 0x19, 0x98, 0x67,
-0xdc, 0x62, 0x01, 0x31, 0x03, 0x29, 0xee, 0xd3, 0x06, 0x49, 0xc0, 0x46,
-0x08, 0x60, 0x48, 0x60, 0x88, 0x60, 0xc8, 0x60, 0x08, 0x61, 0x90, 0xbc,
-0x70, 0x47, 0x00, 0x00, 0xac, 0x66, 0x21, 0x40, 0x5c, 0x2b, 0x00, 0x80,
-0xd0, 0x2c, 0x00, 0x80, 0x64, 0x21, 0x05, 0x48, 0xc0, 0x46, 0x01, 0x63,
-0x00, 0x21, 0xc9, 0x43, 0x41, 0x63, 0x81, 0x63, 0x00, 0x21, 0xc1, 0x63,
-0x01, 0x64, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x80, 0xb4, 0x01, 0x20,
-0x40, 0x02, 0x0a, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x3c, 0x20, 0x48, 0x60,
-0x88, 0x60, 0x08, 0x48, 0xc0, 0x46, 0xc8, 0x60, 0x00, 0x20, 0x07, 0x4a,
-0x87, 0x00, 0xcb, 0x68, 0xc0, 0x46, 0xda, 0x51, 0x01, 0x30, 0x10, 0x28,
-0xf8, 0xd3, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, 0xe4, 0x2d, 0x00, 0x80,
-0xf4, 0x2d, 0x00, 0x80, 0x5d, 0x4c, 0xff, 0xff, 0x12, 0x49, 0x13, 0x48,
-0x67, 0x23, 0x9b, 0x01, 0xca, 0x18, 0x06, 0xc0, 0x08, 0x38, 0x11, 0x4b,
-0xca, 0x18, 0xc1, 0x60, 0x82, 0x60, 0x01, 0x61, 0x0f, 0x49, 0x10, 0x48,
-0xa7, 0x23, 0x9b, 0x01, 0xca, 0x18, 0x06, 0xc0, 0x08, 0x38, 0x0e, 0x4b,
-0xca, 0x18, 0xc1, 0x60, 0x82, 0x60, 0x01, 0x61, 0x0c, 0x48, 0x0d, 0x49,
-0x67, 0x23, 0x9b, 0x01, 0xc2, 0x18, 0x05, 0xc1, 0x08, 0x39, 0x05, 0x4b,
-0xc2, 0x18, 0xc8, 0x60, 0x8a, 0x60, 0x08, 0x61, 0x70, 0x47, 0x00, 0x00,
-0xac, 0x1e, 0x21, 0x40, 0x48, 0x2e, 0x00, 0x80, 0xfc, 0x1f, 0x00, 0x00,
-0xac, 0xee, 0x20, 0x40, 0x34, 0x2e, 0x00, 0x80, 0xfc, 0x2f, 0x00, 0x00,
-0xac, 0x3e, 0x21, 0x40, 0x5c, 0x2e, 0x00, 0x80,
-0x90, 0xb4, 0x00, 0x21, 0x40, 0x4c, 0x00, 0x20, 0x0a, 0x01, 0x12, 0x19,
-0x19, 0x23, 0xdb, 0x01, 0xd2, 0x18, 0xd0, 0x62, 0x10, 0x63, 0x50, 0x63,
-0x90, 0x63, 0x01, 0x31, 0x03, 0x29, 0xf3, 0xd3, 0x3a, 0x49, 0xc0, 0x46,
-0x08, 0x63, 0x48, 0x63, 0x88, 0x63, 0x20, 0x60, 0x01, 0x21, 0xe3, 0x1d,
-0x59, 0x33, 0x60, 0x60, 0x19, 0x71, 0x18, 0x72, 0x98, 0x71, 0x98, 0x72,
-0x59, 0x71, 0x58, 0x72, 0xd8, 0x71, 0xd8, 0x72, 0xe2, 0x1d, 0x49, 0x32,
-0x11, 0x73, 0x19, 0x70, 0x90, 0x73, 0x98, 0x70, 0x51, 0x73, 0x59, 0x70,
-0xd0, 0x73, 0xd8, 0x70, 0x11, 0x71, 0x11, 0x72, 0x90, 0x71, 0x90, 0x72,
-0x50, 0x71, 0x50, 0x72, 0xd0, 0x71, 0xd0, 0x72, 0x18, 0x73, 0x02, 0x22,
-0xe7, 0x1d, 0x69, 0x37, 0x3a, 0x70, 0x99, 0x73, 0xba, 0x70, 0x58, 0x73,
-0x78, 0x70, 0xd8, 0x73, 0xf8, 0x70, 0x39, 0x71, 0x3a, 0x72, 0xb9, 0x71,
-0xb9, 0x72, 0x78, 0x71, 0x7a, 0x72, 0xf9, 0x71, 0xf9, 0x72, 0x39, 0x73,
-0xe3, 0x1d, 0x79, 0x33, 0x1a, 0x70, 0xb9, 0x73, 0x99, 0x70, 0x78, 0x73,
-0x5a, 0x70, 0xf9, 0x73, 0xd9, 0x70, 0x1a, 0x71, 0x1a, 0x72, 0x99, 0x71,
-0x9a, 0x72, 0x58, 0x71, 0x5a, 0x72, 0xd9, 0x71, 0xda, 0x72, 0x19, 0x73,
-0xe7, 0x1d, 0x89, 0x37, 0x3a, 0x70, 0x99, 0x73, 0xb9, 0x70, 0x58, 0x73,
-0x7a, 0x70, 0xd9, 0x73, 0xf9, 0x70, 0x39, 0x71, 0x3a, 0x72, 0xb9, 0x71,
-0xb9, 0x72, 0x78, 0x71, 0x7a, 0x72, 0xf9, 0x71, 0xf9, 0x72, 0x3a, 0x73,
-0xe3, 0x1d, 0x99, 0x33, 0x1a, 0x70, 0xb9, 0x73, 0x9a, 0x70, 0x78, 0x73,
-0x5a, 0x70, 0xf9, 0x73, 0xda, 0x70, 0x19, 0x71, 0x1a, 0x72, 0x99, 0x71,
-0x99, 0x72, 0x58, 0x71, 0x5a, 0x72, 0xd9, 0x71, 0xd9, 0x72, 0x20, 0x61,
-0xe0, 0x60, 0x60, 0x61, 0xa0, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x00,
-0xa0, 0x1c, 0x00, 0x80, 0xe8, 0x19, 0x00, 0x80, 0x81, 0x20, 0x00, 0x02,
-0x01, 0x49, 0xc0, 0x46, 0x88, 0x62, 0x70, 0x47, 0xc0, 0x00, 0x14, 0x00,
-0x09, 0x49, 0x0a, 0x4b, 0xc8, 0x18, 0x04, 0x3b, 0xc9, 0x18, 0x08, 0x60,
-0x00, 0x21, 0xc2, 0x1d, 0x29, 0x32, 0xc2, 0x61, 0x10, 0x1c, 0x01, 0x31,
-0x08, 0x29, 0xf8, 0xd3, 0xc1, 0x1f, 0x29, 0x39, 0x00, 0x20, 0xc8, 0x61,
-0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x84, 0x09, 0x00, 0x00,
-0x06, 0x48, 0x07, 0x49, 0xc0, 0x46, 0x08, 0x80, 0x48, 0x80, 0x00, 0x20,
-0x88, 0x80, 0xc8, 0x80, 0x88, 0x60, 0x04, 0x49, 0xc0, 0x46, 0x48, 0x61,
-0x88, 0x61, 0x70, 0x47, 0xff, 0xff, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80,
-0x6c, 0x06, 0x00, 0x80, 0x00, 0x21, 0x06, 0x48, 0xc2, 0x1d, 0x19, 0x32,
-0xc1, 0x60, 0x01, 0x61, 0xc1, 0x61, 0x01, 0x62, 0x11, 0x71, 0xff, 0x30,
-0x01, 0x30, 0x41, 0x62, 0x70, 0x47, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80,
-0x09, 0x48, 0x0a, 0x4b, 0xc0, 0x46, 0x18, 0x60, 0x00, 0x21, 0xc2, 0x1d,
-0x4d, 0x32, 0xc2, 0x60, 0x10, 0x1c, 0x01, 0x31, 0x14, 0x29, 0xf8, 0xd3,
-0xc1, 0x1f, 0x4d, 0x39, 0x00, 0x20, 0xc8, 0x60, 0x58, 0x60, 0x98, 0x60,
-0x70, 0x47, 0x00, 0x00, 0xd8, 0x07, 0x00, 0x80, 0x6c, 0x06, 0x00, 0x80,
-0x00, 0xb5, 0x0b, 0x49, 0x0b, 0x48, 0xfd, 0xf7, 0xea, 0xfb, 0x0b, 0x48,
-0x00, 0x6a, 0x01, 0x23, 0xdb, 0x03, 0x98, 0x43, 0x09, 0x49, 0xc0, 0x46,
-0x08, 0x62, 0x09, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x04, 0xd1, 0xc0, 0x6f,
-0x80, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x08, 0xbc, 0x18, 0x47,
-0xc1, 0xbd, 0x21, 0x40, 0x75, 0x98, 0x21, 0x40,
-0xc0, 0x00, 0x18, 0x40, 0xc0, 0x00, 0x18, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x00, 0xb5, 0x0f, 0x48, 0xc1, 0x68, 0x01, 0x29, 0x04, 0xd1, 0xc0, 0x6f,
-0x80, 0x23, 0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 0x0b, 0x4b, 0x0c, 0x48,
-0x0c, 0x4a, 0x00, 0x21, 0xfd, 0xf7, 0xbf, 0xfb, 0x0b, 0x48, 0x41, 0x8d,
-0x01, 0x31, 0x41, 0x85, 0x00, 0x21, 0xc1, 0x85, 0x09, 0x48, 0x00, 0x6a,
-0x01, 0x23, 0xdb, 0x03, 0x18, 0x43, 0x08, 0x49, 0xc0, 0x46, 0x08, 0x62,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x59, 0xbd, 0x21, 0x40,
-0x75, 0x98, 0x21, 0x40, 0xb8, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-0xc0, 0x00, 0x18, 0x40, 0xc0, 0x00, 0x18, 0x00, 0xf0, 0xb5, 0x1b, 0x4c,
-0x10, 0x26, 0xe0, 0x68, 0x01, 0x28, 0x08, 0xd1, 0x60, 0x88, 0x00, 0x28,
-0x05, 0xd1, 0x20, 0x79, 0x00, 0x28, 0x02, 0xd1, 0x19, 0x20, 0xa0, 0x67,
-0x00, 0xe0, 0xa6, 0x67, 0x00, 0x20, 0x07, 0x23, 0x5b, 0x02, 0xe5, 0x18,
-0xc1, 0x43, 0xe8, 0x61, 0x69, 0x62, 0x59, 0x08, 0xa1, 0x27, 0x7f, 0x03,
-0x79, 0x60, 0x0f, 0x21, 0x79, 0x60, 0xe1, 0x1d, 0xb9, 0x31, 0x08, 0x71,
-0x01, 0x20, 0xb8, 0x60, 0x40, 0x02, 0xb8, 0x60, 0x00, 0xf0, 0x4c, 0xfa,
-0x00, 0xf0, 0xf0, 0xfa, 0x04, 0x20, 0xb8, 0x60, 0x07, 0x20, 0x78, 0x61,
-0x7e, 0x60, 0x1b, 0x23, 0xdb, 0x01, 0xe0, 0x18, 0xc0, 0x8b, 0x04, 0x23,
-0x18, 0x40, 0xe8, 0x62, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0x90, 0xb4, 0x02, 0x1c, 0x00, 0x20, 0xff, 0x23,
-0x01, 0x33, 0x9a, 0x42, 0x08, 0xd0, 0x01, 0x29, 0x00, 0xd1, 0x01, 0x20,
-0x00, 0x2a, 0x01, 0xd1, 0x02, 0x23, 0x18, 0x43, 0x90, 0xbc, 0x70, 0x47,
-0x1b, 0x4a, 0xd7, 0x68, 0x1a, 0x4b, 0x19, 0x79, 0x1c, 0x1c, 0x37, 0x23,
-0x9b, 0x01, 0xe3, 0x18, 0x01, 0x2f, 0x0d, 0xd1, 0x57, 0x88, 0x00, 0x2f,
-0x0a, 0xd1, 0x00, 0x29, 0x0a, 0xd1, 0x59, 0x8b, 0x0a, 0x09, 0x00, 0xd3,
-0x02, 0x20, 0x49, 0x09, 0xe8, 0xd3, 0x01, 0x23, 0x18, 0x43, 0xe5, 0xe7,
-0x00, 0x29, 0x03, 0xd0, 0x98, 0x8a, 0x80, 0x07, 0x80, 0x0f, 0xdf, 0xe7,
-0x6d, 0x23, 0x5b, 0x01, 0xd1, 0x18, 0x8a, 0x88, 0xff, 0x27, 0x01, 0x37,
-0x17, 0x40, 0x0a, 0x49, 0xc9, 0x88, 0x03, 0xd0, 0x4b, 0x0a, 0x01, 0xd3,
-0x03, 0x20, 0xd1, 0xe7, 0x13, 0x0a, 0x03, 0xd3, 0x0b, 0x0a, 0x01, 0xd3,
-0x02, 0x20, 0xcb, 0xe7, 0xd2, 0x09, 0xc9, 0xd3, 0xc9, 0x09, 0xc7, 0xd3,
-0x01, 0x20, 0xc5, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0x08, 0x1c, 0x00, 0x80,
-0xf0, 0xb5, 0xc1, 0xb0, 0x01, 0x20, 0x00, 0x07, 0x52, 0x49, 0xc0, 0x46,
-0x08, 0x60, 0x52, 0x48, 0x42, 0x69, 0x40, 0x0d, 0xa1, 0x21, 0x49, 0x03,
-0x48, 0x60, 0x50, 0x48, 0xc0, 0x6a, 0x50, 0x4b, 0x18, 0x43, 0x00, 0x21,
-0x03, 0x03, 0x1b, 0x0b, 0x4e, 0x4c, 0x27, 0x6f, 0x3d, 0x03, 0x2d, 0x0b,
-0xe7, 0x1d, 0x79, 0x37, 0xab, 0x42, 0x1c, 0xd0, 0xe3, 0x1d, 0x79, 0x33,
-0x1b, 0x6a, 0xc0, 0x46, 0x40, 0x93, 0x01, 0x23, 0x9b, 0x07, 0x03, 0x43,
-0x1b, 0x68, 0xcc, 0x00, 0x6e, 0x46, 0x33, 0x51, 0x01, 0x23, 0x9b, 0x07,
-0x06, 0x1d, 0x33, 0x43, 0x1b, 0x68, 0x6c, 0x44, 0x63, 0x60, 0x08, 0x30,
-0x01, 0x31, 0x40, 0x9b, 0x83, 0x42, 0x00, 0xd8, 0x3f, 0x48, 0x03, 0x03,
-0x1b, 0x0b, 0xab, 0x42, 0xe7, 0xd1, 0x00, 0x20, 0x01, 0x23, 0x1b, 0x03,
-0x13, 0x40, 0x3c, 0x4c, 0x03, 0xd0, 0x63, 0x6a, 0x01, 0x33, 0x63, 0x62,
-0x09, 0xe0, 0x13, 0x0b, 0x03, 0xd3, 0x23, 0x6a,
-0x01, 0x33, 0x23, 0x62, 0x03, 0xe0, 0x37, 0x4b, 0x5c, 0x6d, 0x01, 0x34,
-0x5c, 0x65, 0x00, 0x29, 0x09, 0xd0, 0x03, 0x1c, 0xdc, 0x00, 0x23, 0x1c,
-0x6b, 0x44, 0x5c, 0x68, 0x01, 0x30, 0x23, 0x0d, 0x01, 0xd2, 0x88, 0x42,
-0xf5, 0xd1, 0x30, 0x4c, 0x25, 0x68, 0x6b, 0x0c, 0x05, 0xd2, 0x23, 0x68,
-0x1b, 0x0c, 0x08, 0xd1, 0x24, 0x68, 0xa3, 0x0a, 0x05, 0xd3, 0x20, 0x24,
-0x2b, 0x4b, 0xc0, 0x46, 0x5c, 0x62, 0x00, 0x24, 0x5c, 0x62, 0x25, 0x4b,
-0x23, 0x4c, 0x51, 0x26, 0xb6, 0x03, 0x23, 0x67, 0x33, 0x61, 0x3d, 0x6a,
-0xc0, 0x46, 0x75, 0x61, 0x02, 0x25, 0xa1, 0x26, 0x76, 0x03, 0x75, 0x60,
-0x01, 0x25, 0xb5, 0x60, 0xe6, 0x1d, 0xb9, 0x36, 0x35, 0x71, 0x88, 0x42,
-0x21, 0xd0, 0x25, 0x1c, 0xc3, 0x00, 0x6c, 0x46, 0xe4, 0x58, 0x2e, 0x6f,
-0x6b, 0x44, 0x34, 0x60, 0x5b, 0x68, 0x2c, 0x6f, 0xc0, 0x46, 0x63, 0x60,
-0x2b, 0x6f, 0x08, 0x33, 0x2b, 0x67, 0x3c, 0x6a, 0xa3, 0x42, 0x02, 0xd3,
-0x12, 0x4b, 0xc0, 0x46, 0x2b, 0x67, 0x03, 0x1c, 0xdb, 0x00, 0x6b, 0x44,
-0x5c, 0x68, 0x01, 0x30, 0x23, 0x0d, 0x04, 0xd3, 0x51, 0x24, 0xa4, 0x03,
-0x2b, 0x6f, 0xc0, 0x46, 0xa3, 0x61, 0x88, 0x42, 0xde, 0xd1, 0x10, 0x0b,
-0x03, 0xd3, 0x0e, 0x49, 0x01, 0x20, 0xfd, 0xf7, 0x74, 0xfa, 0x41, 0xb0,
-0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0,
-0x00, 0x01, 0x14, 0x40, 0x00, 0x40, 0x14, 0x40, 0x00, 0x00, 0x20, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0x24, 0xa7, 0x20, 0x40, 0xa4, 0x2a, 0x00, 0x80,
-0xa0, 0x82, 0x20, 0x40, 0x00, 0x00, 0x10, 0x40, 0xc0, 0x00, 0x18, 0x00,
-0xc9, 0x4f, 0xff, 0xff, 0xf0, 0xb4, 0x00, 0x21, 0x00, 0x23, 0x07, 0x22,
-0x06, 0x24, 0x47, 0x4f, 0xc0, 0x46, 0x3c, 0x61, 0x3a, 0x61, 0x01, 0x33,
-0x20, 0x2b, 0xf9, 0xd3, 0x04, 0x25, 0x3d, 0x61, 0x05, 0x23, 0x3b, 0x61,
-0x3c, 0x61, 0x3a, 0x61, 0x3c, 0x61, 0x3a, 0x61, 0x3d, 0x61, 0x3b, 0x61,
-0x3f, 0x4d, 0xab, 0x6f, 0xde, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23,
-0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f,
-0x9e, 0x08, 0x02, 0x23, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61,
-0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x5e, 0x08, 0x02, 0x23,
-0x1e, 0x40, 0x04, 0x23, 0x33, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x33, 0x43,
-0x3b, 0x61, 0x02, 0x23, 0xae, 0x6f, 0x1e, 0x40, 0x04, 0x23, 0x33, 0x43,
-0x3b, 0x61, 0x05, 0x23, 0x33, 0x43, 0x3b, 0x61, 0xab, 0x6f, 0x5d, 0x00,
-0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23,
-0x2b, 0x43, 0x3b, 0x61, 0xc5, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23,
-0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x85, 0x08,
-0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23,
-0x2b, 0x43, 0x3b, 0x61, 0x45, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23,
-0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x02, 0x25,
-0x05, 0x40, 0x04, 0x23, 0x2b, 0x43, 0x3b, 0x61, 0x05, 0x23, 0x2b, 0x43,
-0x3b, 0x61, 0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x04, 0x23, 0x03, 0x43,
-0x3b, 0x61, 0x05, 0x23, 0x18, 0x43, 0x38, 0x61, 0x00, 0x25, 0x3d, 0x61,
-0x01, 0x23, 0x3b, 0x61, 0x3d, 0x61, 0x3b, 0x61, 0x00, 0x20, 0x3d, 0x61,
-0x0d, 0x4b, 0x1b, 0x69, 0x49, 0x00, 0x1e, 0x1c, 0x02, 0x23, 0x33, 0x40,
-0x19, 0x43, 0x01, 0x23, 0x3b, 0x61, 0x01, 0x30,
-0x10, 0x28, 0xf2, 0xd3, 0x02, 0x20, 0x38, 0x61, 0x03, 0x20, 0x38, 0x61,
-0x3c, 0x61, 0x3a, 0x61, 0x3c, 0x61, 0x3a, 0x61, 0x38, 0x61, 0x48, 0x08,
-0xf0, 0xbc, 0x70, 0x47, 0x80, 0x00, 0x14, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x80, 0x00, 0x14, 0x40, 0xf0, 0xb4, 0x00, 0x24, 0x07, 0x23, 0x06, 0x27,
-0x44, 0x4a, 0xc0, 0x46, 0x17, 0x61, 0x13, 0x61, 0x01, 0x34, 0x20, 0x2c,
-0xf9, 0xd3, 0x04, 0x26, 0x16, 0x61, 0x05, 0x24, 0x14, 0x61, 0x17, 0x61,
-0x07, 0x23, 0x13, 0x61, 0x16, 0x61, 0x14, 0x61, 0x17, 0x61, 0x13, 0x61,
-0x3c, 0x4b, 0x9b, 0x6f, 0xdd, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c,
-0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x37, 0x4b, 0x9b, 0x6f,
-0x9d, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61,
-0x25, 0x43, 0x15, 0x61, 0x32, 0x4b, 0x9b, 0x6f, 0x5d, 0x08, 0x02, 0x23,
-0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61,
-0x2d, 0x4b, 0x9d, 0x6f, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43,
-0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x29, 0x4b, 0x9b, 0x6f, 0x5d, 0x00,
-0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43,
-0x15, 0x61, 0xc5, 0x08, 0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43,
-0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x85, 0x08, 0x02, 0x23, 0x1d, 0x40,
-0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43, 0x15, 0x61, 0x45, 0x08,
-0x02, 0x23, 0x1d, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61, 0x25, 0x43,
-0x15, 0x61, 0x02, 0x25, 0x05, 0x40, 0x2b, 0x1c, 0x33, 0x43, 0x13, 0x61,
-0x25, 0x43, 0x15, 0x61, 0x40, 0x00, 0x02, 0x23, 0x18, 0x40, 0x03, 0x1c,
-0x33, 0x43, 0x13, 0x61, 0x20, 0x43, 0x10, 0x61, 0x17, 0x61, 0x07, 0x23,
-0x13, 0x61, 0x16, 0x61, 0x14, 0x61, 0x4c, 0x00, 0x00, 0x20, 0x0f, 0x21,
-0x25, 0x1c, 0xcd, 0x40, 0x02, 0x23, 0x1d, 0x40, 0x04, 0x23, 0x2b, 0x43,
-0x13, 0x61, 0x05, 0x23, 0x2b, 0x43, 0x13, 0x61, 0x01, 0x30, 0x01, 0x39,
-0x10, 0x28, 0xf1, 0xd3, 0x17, 0x61, 0x07, 0x23, 0x13, 0x61, 0x17, 0x61,
-0x13, 0x61, 0x03, 0x20, 0x10, 0x61, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00,
-0x80, 0x00, 0x14, 0x00, 0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x4f, 0x4d,
-0x08, 0x21, 0x02, 0x20, 0x2a, 0x1c, 0xfd, 0xf7, 0x27, 0xf9, 0x4d, 0x4c,
-0x71, 0x23, 0x5b, 0x01, 0xe7, 0x18, 0x38, 0x80, 0x1a, 0x21, 0x02, 0x20,
-0x2a, 0x1c, 0xfd, 0xf7, 0x1d, 0xf9, 0x78, 0x80, 0x20, 0x79, 0x00, 0x28,
-0x0b, 0xd0, 0x00, 0x20, 0x38, 0x80, 0xe0, 0x68, 0x01, 0x28, 0x10, 0xd1,
-0x44, 0x48, 0x00, 0x68, 0x01, 0x23, 0x9b, 0x02, 0x18, 0x43, 0x99, 0x02,
-0x08, 0x60, 0xe0, 0x68, 0x01, 0x28, 0x06, 0xd1, 0x60, 0x88, 0x00, 0x28,
-0x03, 0xd1, 0xf9, 0x21, 0x12, 0x20, 0xff, 0xf7, 0x43, 0xff, 0x01, 0x21,
-0xc9, 0x03, 0x00, 0x20, 0xff, 0xf7, 0x3e, 0xff, 0x00, 0x25, 0x7d, 0x26,
-0xf6, 0x00, 0x00, 0xe0, 0x01, 0x35, 0x00, 0x20, 0xff, 0xf7, 0x9c, 0xfe,
-0x00, 0x0c, 0x01, 0xd3, 0xb5, 0x42, 0xf7, 0xd3, 0x00, 0x25, 0x05, 0xe0,
-0x03, 0x21, 0x09, 0x03, 0x00, 0x20, 0xff, 0xf7, 0x2b, 0xff, 0x01, 0x35,
-0x00, 0x20, 0xff, 0xf7, 0x8d, 0xfe, 0x40, 0x0b, 0x01, 0xd2, 0xb5, 0x42,
-0xf2, 0xd3, 0x04, 0x20, 0xff, 0xf7, 0x86, 0xfe, 0xff, 0x23, 0xe1, 0x33,
-0x98, 0x43, 0x01, 0x21, 0x01, 0x43, 0x38, 0x88, 0xff, 0x23, 0x01, 0x33,
-0x98, 0x42, 0x03, 0xd1, 0x2f, 0x23, 0x5b, 0x01,
-0x19, 0x43, 0x16, 0xe0, 0x01, 0x28, 0x09, 0xd1, 0x78, 0x88, 0x01, 0x28,
-0x03, 0xd1, 0x23, 0x23, 0x5b, 0x01, 0x19, 0x43, 0x0d, 0xe0, 0x20, 0x23,
-0x19, 0x43, 0x0a, 0xe0, 0x00, 0x28, 0x08, 0xd1, 0x78, 0x88, 0x01, 0x28,
-0x03, 0xd1, 0x0b, 0x23, 0xdb, 0x01, 0x19, 0x43, 0x01, 0xe0, 0x80, 0x23,
-0x19, 0x43, 0x04, 0x20, 0xff, 0xf7, 0xf8, 0xfe, 0x09, 0x21, 0x49, 0x02,
-0x00, 0x20, 0xff, 0xf7, 0xf3, 0xfe, 0xe0, 0x68, 0x00, 0x28, 0x0c, 0xd1,
-0x00, 0x21, 0x1b, 0x20, 0xff, 0xf7, 0xec, 0xfe, 0x1a, 0x20, 0xff, 0xf7,
-0x4f, 0xfe, 0x01, 0x21, 0xc9, 0x03, 0x01, 0x43, 0x1a, 0x20, 0xff, 0xf7,
-0xe3, 0xfe, 0x00, 0x27, 0x03, 0xe0, 0x08, 0x2f, 0x01, 0xd3, 0x0f, 0x2f,
-0x08, 0xd9, 0x38, 0x1c, 0xff, 0xf7, 0x40, 0xfe, 0x79, 0x00, 0x09, 0x19,
-0x1b, 0x23, 0xdb, 0x01, 0xc9, 0x18, 0x88, 0x83, 0x01, 0x37, 0x20, 0x2f,
-0xef, 0xd3, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xed, 0xaf, 0x21, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb0, 0x13, 0x48,
-0x01, 0x68, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x68, 0xc0, 0x46, 0x00, 0x91,
-0x81, 0x68, 0xc0, 0x46, 0x00, 0x91, 0xc1, 0x68, 0xc0, 0x46, 0x00, 0x91,
-0x01, 0x69, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x69, 0xc0, 0x46, 0x00, 0x91,
-0x81, 0x69, 0xc0, 0x46, 0x00, 0x91, 0xc1, 0x69, 0xc0, 0x46, 0x00, 0x91,
-0x01, 0x6a, 0xc0, 0x46, 0x00, 0x91, 0x41, 0x6a, 0xc0, 0x46, 0x00, 0x91,
-0x81, 0x6a, 0xc0, 0x46, 0x00, 0x91, 0xc0, 0x6a, 0xc0, 0x46, 0x00, 0x90,
-0x01, 0xb0, 0x70, 0x47, 0x00, 0x08, 0x14, 0x40, 0xf0, 0xb5, 0x83, 0xb0,
-0x68, 0x4d, 0x1b, 0x23, 0xdb, 0x01, 0xef, 0x18, 0xf8, 0x8b, 0x04, 0x22,
-0x02, 0x40, 0x02, 0x92, 0x71, 0x23, 0x5b, 0x01, 0xe8, 0x18, 0x01, 0x88,
-0xc0, 0x46, 0x01, 0x91, 0x40, 0x88, 0xc0, 0x46, 0x00, 0x90, 0x00, 0x24,
-0x03, 0xe0, 0x08, 0x2c, 0x01, 0xd3, 0x0f, 0x2c, 0x08, 0xd9, 0x20, 0x1c,
-0xff, 0xf7, 0xe8, 0xfd, 0x61, 0x00, 0x49, 0x19, 0x1b, 0x23, 0xdb, 0x01,
-0xc9, 0x18, 0x88, 0x83, 0x01, 0x34, 0x20, 0x2c, 0xef, 0xd3, 0x58, 0x4c,
-0xe0, 0x69, 0x00, 0x28, 0x15, 0xd0, 0x57, 0x4e, 0x20, 0x25, 0x01, 0x3d,
-0x53, 0x49, 0xe0, 0x69, 0x30, 0x40, 0x0b, 0xd0, 0x68, 0x00, 0x40, 0x18,
-0x37, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x81, 0x8b, 0x28, 0x1c, 0xff, 0xf7,
-0x65, 0xfe, 0xe0, 0x69, 0xb0, 0x43, 0xe0, 0x61, 0x76, 0x08, 0x00, 0x2d,
-0xeb, 0xd1, 0x01, 0x20, 0xff, 0xf7, 0xc2, 0xfd, 0x48, 0x49, 0xc0, 0x46,
-0xf8, 0x83, 0xf8, 0x8b, 0xc2, 0x08, 0x25, 0xd3, 0xca, 0x68, 0x01, 0x2a,
-0x13, 0xd1, 0x0a, 0x79, 0x00, 0x2a, 0x1f, 0xd1, 0x49, 0x88, 0x00, 0x29,
-0x1c, 0xd1, 0x01, 0x99, 0x43, 0x4a, 0x00, 0x29, 0x05, 0xd0, 0x01, 0x29,
-0x16, 0xd1, 0x51, 0x8b, 0xc9, 0x08, 0x13, 0xd2, 0x0f, 0xe0, 0x51, 0x8b,
-0x09, 0x09, 0x0f, 0xd2, 0x0b, 0xe0, 0x0a, 0x79, 0x00, 0x2a, 0x0b, 0xd1,
-0x6d, 0x23, 0x5b, 0x01, 0xc9, 0x18, 0x8a, 0x88, 0xc9, 0x88, 0x11, 0x40,
-0x49, 0x09, 0x09, 0x07, 0x02, 0xd1, 0x04, 0x23, 0x98, 0x43, 0xf8, 0x83,
-0xf8, 0x8b, 0x04, 0x21, 0x01, 0x40, 0x02, 0x9a, 0x1f, 0xd0, 0xb9, 0x8b,
-0x4a, 0x0b, 0x27, 0xd3, 0x80, 0x09, 0x25, 0xd3, 0xff, 0x23, 0x01, 0x98,
-0x01, 0x33, 0x98, 0x42, 0x20, 0xd0, 0x00, 0x25, 0x00, 0x98, 0x01, 0x28,
-0x00, 0xd1, 0x05, 0x02, 0x01, 0x98, 0x00, 0x28, 0x02, 0xd1, 0x01, 0x23,
-0x5b, 0x03, 0x1d, 0x43, 0xa9, 0x42, 0x13, 0xd0,
-0x00, 0x20, 0x29, 0x1c, 0xff, 0xf7, 0x10, 0xfe, 0xbd, 0x83, 0x00, 0x20,
-0xc0, 0x43, 0x60, 0x62, 0x0a, 0xe0, 0xb8, 0x8b, 0x40, 0x0b, 0x07, 0xd2,
-0x09, 0x21, 0x49, 0x02, 0x00, 0x20, 0xff, 0xf7, 0x03, 0xfe, 0x09, 0x20,
-0x40, 0x02, 0xb8, 0x83, 0xf8, 0x8b, 0xc0, 0x08, 0x2d, 0xd3, 0x1d, 0x48,
-0xc7, 0x6a, 0x01, 0x98, 0x00, 0x99, 0xff, 0xf7, 0x51, 0xfc, 0xc2, 0x07,
-0xd2, 0x0f, 0x1a, 0x49, 0x03, 0xd0, 0x04, 0x23, 0xcd, 0x6d, 0x2b, 0x43,
-0x03, 0xe0, 0x04, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 0xcb, 0x65,
-0x83, 0x08, 0x03, 0xd3, 0x02, 0x23, 0xcd, 0x6d, 0x2b, 0x43, 0x03, 0xe0,
-0x02, 0x23, 0xcd, 0x6d, 0x9d, 0x43, 0x2b, 0x1c, 0xcb, 0x65, 0x61, 0x6a,
-0x81, 0x42, 0x0c, 0xd0, 0x60, 0x62, 0x0e, 0x48, 0x00, 0x2a, 0x03, 0xd0,
-0xff, 0x21, 0x21, 0x31, 0x39, 0x43, 0x03, 0xe0, 0xff, 0x23, 0x21, 0x33,
-0x9f, 0x43, 0x39, 0x1c, 0xc1, 0x62, 0x03, 0xb0, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0x68, 0x1c, 0x00, 0x80,
-0x00, 0x00, 0x00, 0x80, 0x28, 0x1c, 0x00, 0x80, 0x40, 0x00, 0x14, 0x40,
-0xa4, 0x2a, 0x00, 0x80, 0x40, 0x00, 0x14, 0x00, 0x90, 0xb4, 0x01, 0x22,
-0x20, 0x28, 0x0f, 0xd2, 0x43, 0x00, 0x0f, 0x1c, 0x07, 0x49, 0x5c, 0x18,
-0x37, 0x23, 0x9b, 0x01, 0xe3, 0x18, 0x9f, 0x83, 0x82, 0x40, 0x07, 0x23,
-0x5b, 0x02, 0xc9, 0x18, 0x10, 0x1c, 0xca, 0x69, 0x10, 0x43, 0xc8, 0x61,
-0x90, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x0b, 0x48, 0x40, 0x69,
-0x0b, 0x49, 0xc9, 0x8b, 0x04, 0x22, 0x0a, 0x40, 0x0a, 0x49, 0x06, 0xd0,
-0x01, 0x23, 0xdb, 0x02, 0x98, 0x43, 0x01, 0x23, 0xca, 0x6d, 0x1a, 0x43,
-0x05, 0xe0, 0x01, 0x23, 0xdb, 0x02, 0x18, 0x43, 0xca, 0x6d, 0x52, 0x08,
-0x52, 0x00, 0xca, 0x65, 0x70, 0x47, 0x00, 0x00, 0x80, 0x00, 0x14, 0x40,
-0xe8, 0x1b, 0x00, 0x80, 0xa4, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0x84, 0xb0,
-0xff, 0xf7, 0xde, 0xff, 0x01, 0x1c, 0x05, 0x20, 0x00, 0x90, 0x00, 0x20,
-0x01, 0xab, 0x18, 0x80, 0x04, 0x3b, 0x58, 0x70, 0x1b, 0x22, 0x00, 0xab,
-0x5a, 0x80, 0xd9, 0x80, 0x05, 0x49, 0xc9, 0x6d, 0xc0, 0x46, 0x02, 0x91,
-0x03, 0x90, 0x68, 0x46, 0x00, 0x21, 0xfd, 0xf7, 0x79, 0xf8, 0x04, 0xb0,
-0x08, 0xbc, 0x18, 0x47, 0xa4, 0x2a, 0x00, 0x80, 0x0f, 0x48, 0x01, 0x68,
-0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c, 0x06, 0xd1, 0x00, 0x68,
-0x80, 0x0a, 0x03, 0xd3, 0x0b, 0x48, 0x00, 0x68, 0x00, 0x0c, 0x01, 0xe0,
-0x0a, 0x48, 0x80, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x09, 0x4b, 0x98, 0x42,
-0x05, 0xd0, 0x02, 0x33, 0x98, 0x42, 0x02, 0xd0, 0x07, 0x4b, 0x98, 0x42,
-0x01, 0xd1, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80,
-0x04, 0x99, 0x00, 0x00, 0x07, 0x99, 0x00, 0x00, 0x90, 0xb4, 0x01, 0x24,
-0x21, 0x1c, 0x18, 0x48, 0x02, 0x68, 0x52, 0x0c, 0x06, 0xd2, 0x02, 0x68,
-0x12, 0x0c, 0x02, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x00, 0xd2, 0x00, 0x21,
-0x09, 0x06, 0x09, 0x0e, 0x12, 0x4f, 0x13, 0x4a, 0x02, 0xd0, 0x38, 0x68,
-0x00, 0x0c, 0x00, 0xe0, 0x90, 0x6c, 0x00, 0x04, 0x00, 0x0c, 0x10, 0x4b,
-0x98, 0x42, 0x08, 0xd0, 0x02, 0x33, 0x98, 0x42, 0x05, 0xd0, 0x0e, 0x4b,
-0x98, 0x42, 0x02, 0xd0, 0x02, 0x3b, 0x98, 0x42, 0x0c, 0xd1, 0x00, 0x29,
-0x02, 0xd0, 0xf8, 0x6a, 0x00, 0x0c, 0x00, 0xe0,
-0xd0, 0x6c, 0x40, 0x0a, 0x00, 0xd2, 0x00, 0x24, 0x20, 0x06, 0x00, 0x0e,
-0x90, 0xbc, 0x70, 0x47, 0x00, 0x20, 0xfb, 0xe7, 0x00, 0x00, 0x10, 0x40,
-0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 0x04, 0x99, 0x00, 0x00,
-0x07, 0x99, 0x00, 0x00, 0x0c, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2,
-0x01, 0x68, 0x09, 0x0c, 0x05, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x02, 0xd3,
-0x08, 0x48, 0x80, 0x68, 0x01, 0xe0, 0x08, 0x48, 0x40, 0x6c, 0x00, 0x04,
-0x00, 0x0c, 0x00, 0x21, 0x03, 0x28, 0x03, 0xd0, 0x40, 0x08, 0x01, 0xd3,
-0x01, 0x20, 0x70, 0x47, 0x08, 0x1c, 0xfc, 0xe7, 0x00, 0x00, 0x10, 0x40,
-0x00, 0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x80, 0xf0, 0xb5, 0x01, 0x27,
-0x1a, 0x4c, 0x25, 0x68, 0xff, 0xf7, 0x72, 0xff, 0x03, 0x1c, 0x19, 0x4a,
-0x02, 0x21, 0x01, 0x26, 0x18, 0x48, 0x01, 0x2b, 0x1b, 0xd1, 0xcb, 0x04,
-0x1e, 0x60, 0x55, 0x23, 0x03, 0x60, 0x00, 0x23, 0x43, 0x60, 0x06, 0x68,
-0x55, 0x2e, 0x1b, 0xd1, 0xaa, 0x26, 0x06, 0x60, 0x43, 0x60, 0x03, 0x68,
-0xaa, 0x2b, 0x15, 0xd1, 0x09, 0x23, 0x03, 0x60, 0x05, 0x23, 0x0f, 0x4f,
-0xc0, 0x46, 0x3b, 0x60, 0x03, 0x23, 0x0e, 0x4f, 0xc0, 0x46, 0x3b, 0x60,
-0x11, 0x60, 0x07, 0x68, 0x08, 0xe0, 0x08, 0x23, 0x23, 0x60, 0x04, 0x23,
-0x0a, 0x4f, 0xc0, 0x46, 0x3b, 0x60, 0x11, 0x60, 0x06, 0x60, 0x27, 0x68,
-0xc0, 0x46, 0x25, 0x60, 0x38, 0x1c, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0x24, 0x40, 0x00, 0x00, 0x22, 0x40,
-0x00, 0x00, 0x2a, 0x40, 0x00, 0x00, 0x26, 0x40, 0x00, 0x00, 0x28, 0x40,
-0x80, 0xb5, 0x07, 0x1c, 0xff, 0xf7, 0x30, 0xff, 0x01, 0x28, 0x05, 0xd1,
-0x19, 0x48, 0x00, 0x68, 0x19, 0x49, 0x49, 0x6b, 0x08, 0x40, 0x22, 0xe0,
-0x18, 0x48, 0x01, 0x68, 0x49, 0x0c, 0x05, 0xd2, 0x01, 0x68, 0x09, 0x0c,
-0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, 0x14, 0x48, 0x00, 0x68,
-0x00, 0x0c, 0x01, 0xe0, 0x13, 0x48, 0x80, 0x6c, 0x00, 0x04, 0x00, 0x0c,
-0x12, 0x4b, 0xc0, 0x18, 0x08, 0x28, 0x0b, 0xd2, 0x01, 0xa3, 0x1b, 0x5c,
-0x5b, 0x00, 0x9f, 0x44, 0x05, 0x03, 0x07, 0x03, 0x07, 0x07, 0x05, 0x03,
-0x03, 0x20, 0x02, 0xe0, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, 0x01, 0x21,
-0x38, 0x60, 0x80, 0x07, 0x00, 0xd1, 0x00, 0x21, 0x08, 0x06, 0x00, 0x0e,
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x34, 0x6e, 0x21, 0x40,
-0x00, 0x00, 0x11, 0x40, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x18, 0x40,
-0x00, 0x00, 0x00, 0x80, 0xfe, 0x66, 0xff, 0xff, 0xf0, 0xb5, 0x82, 0xb0,
-0x07, 0x1c, 0x01, 0x20, 0x01, 0x90, 0xff, 0xf7, 0xe7, 0xfe, 0x01, 0x28,
-0x13, 0xd1, 0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x07, 0xd1, 0x00, 0x26,
-0xf6, 0x43, 0x34, 0x1c, 0xa8, 0x2f, 0x02, 0xd1, 0x30, 0x1c, 0x00, 0x96,
-0x35, 0x1c, 0x11, 0x20, 0x00, 0x04, 0x06, 0x62, 0x44, 0x62, 0x85, 0x62,
-0x00, 0x99, 0xc0, 0x46, 0xc1, 0x62, 0x00, 0x21, 0x08, 0x48, 0xc0, 0x46,
-0x01, 0x60, 0x38, 0x2f, 0x01, 0xd0, 0xa8, 0x2f, 0x05, 0xd1, 0x01, 0x21,
-0x01, 0x60, 0xa8, 0x2f, 0x01, 0xd1, 0x03, 0x21, 0x01, 0x60, 0x01, 0x98,
-0x02, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x34, 0x6e, 0x21, 0x40,
-0x70, 0x47, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c,
-0x12, 0x4c, 0x21, 0x68, 0x12, 0x48, 0x81, 0x42, 0x0b, 0xd0, 0x00, 0x23,
-0x21, 0x1c, 0xe2, 0x1d, 0xc1, 0x32, 0x00, 0xe0,
-0x08, 0xc1, 0x91, 0x42, 0xfc, 0xd3, 0x20, 0x60, 0xc8, 0x20, 0xa0, 0x80,
-0x67, 0x72, 0x38, 0x01, 0x00, 0xf0, 0x18, 0xf8, 0x27, 0x72, 0x0a, 0x48,
-0xc0, 0x46, 0xe0, 0x60, 0x09, 0x2f, 0x00, 0xdb, 0x00, 0x27, 0xe0, 0x19,
-0x01, 0x7d, 0x01, 0x31, 0x01, 0x75, 0xe0, 0x88, 0x01, 0x30, 0xe0, 0x80,
-0x01, 0x20, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x00, 0x80,
-0xee, 0xff, 0xc0, 0xd0, 0x08, 0x10, 0x00, 0x03, 0x80, 0xb4, 0x08, 0x4a,
-0xd1, 0x1d, 0x89, 0x31, 0x0b, 0x7a, 0x20, 0x2b, 0x01, 0xd3, 0x00, 0x23,
-0x0b, 0x72, 0x07, 0x1c, 0x08, 0x7a, 0x43, 0x1c, 0x0b, 0x72, 0x80, 0x18,
-0x90, 0x30, 0x47, 0x72, 0x80, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x00, 0x80,
-0x07, 0x49, 0x01, 0x22, 0x12, 0x04, 0x08, 0x68, 0x02, 0x40, 0x01, 0x20,
-0x00, 0x2a, 0x06, 0xd1, 0x0a, 0x68, 0x12, 0x0c, 0x02, 0xd1, 0x09, 0x68,
-0x89, 0x0a, 0x00, 0xd2, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x10, 0x40,
-0x90, 0xb5, 0x07, 0x1c, 0x09, 0x4c, 0x38, 0x1c, 0x21, 0x1c, 0xfc, 0xf7,
-0x91, 0xff, 0x38, 0x1c, 0x00, 0xf0, 0x0e, 0xf8, 0x01, 0x23, 0xd8, 0x42,
-0x01, 0xd1, 0x00, 0x0c, 0xe0, 0x80, 0x00, 0x21, 0x20, 0x1c, 0xfc, 0xf7,
-0xc5, 0xfe, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xc4, 0x66, 0x21, 0x40,
-0xf8, 0xb5, 0x07, 0x1c, 0x79, 0x7a, 0x76, 0x48, 0x00, 0x23, 0x76, 0x4c,
-0x01, 0x29, 0x5d, 0xd1, 0xa2, 0x88, 0xc0, 0x46, 0x00, 0x92, 0xa1, 0x89,
-0x8a, 0x42, 0x74, 0xda, 0xfa, 0x7a, 0x00, 0x2a, 0x15, 0xd0, 0x7a, 0x6c,
-0x00, 0x2a, 0x12, 0xd0, 0x8a, 0x42, 0x10, 0xd8, 0x00, 0x9a, 0x51, 0x1c,
-0xa1, 0x80, 0xa1, 0x88, 0xc0, 0x46, 0x41, 0x81, 0x78, 0x6c, 0x6b, 0x4e,
-0xc0, 0x46, 0xf0, 0x80, 0xa0, 0x6a, 0x58, 0x23, 0x79, 0x6c, 0x59, 0x43,
-0x40, 0x18, 0xc1, 0x1a, 0x28, 0xe0, 0x22, 0x88, 0x01, 0x32, 0x12, 0x04,
-0x12, 0x0c, 0x22, 0x80, 0x8a, 0x42, 0x00, 0xdb, 0x23, 0x80, 0x00, 0x22,
-0x00, 0x29, 0x69, 0xdd, 0x5f, 0x4c, 0xa4, 0x6a, 0x5e, 0x4b, 0x1d, 0x88,
-0x58, 0x23, 0x6b, 0x43, 0xe3, 0x18, 0xde, 0x1d, 0x01, 0x36, 0x01, 0x23,
-0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06, 0x15, 0xd1, 0x58, 0x49,
-0x00, 0x9a, 0x01, 0x32, 0x8a, 0x80, 0x8a, 0x88, 0xc0, 0x46, 0x42, 0x81,
-0x08, 0x88, 0x01, 0x30, 0x54, 0x4e, 0xc0, 0x46, 0xf0, 0x80, 0x58, 0x20,
-0x68, 0x43, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0x39, 0xfb, 0xf0, 0x88,
-0x00, 0x04, 0x00, 0x14, 0x95, 0xe0, 0x4d, 0x4b, 0x01, 0x35, 0x2d, 0x04,
-0x2d, 0x0c, 0x1d, 0x80, 0x8d, 0x42, 0x01, 0xdb, 0x00, 0x25, 0x1d, 0x80,
-0x01, 0x32, 0x12, 0x04, 0x12, 0x14, 0x91, 0x42, 0xce, 0xdc, 0x81, 0xe0,
-0xe1, 0x88, 0xe2, 0x89, 0x91, 0x42, 0x18, 0xda, 0xf9, 0x7a, 0x00, 0x29,
-0x2f, 0xd0, 0x79, 0x6c, 0x49, 0x04, 0x49, 0x0c, 0x79, 0x64, 0x2a, 0xd0,
-0xe2, 0x89, 0x91, 0x42, 0x27, 0xd8, 0xe1, 0x88, 0x01, 0x31, 0xe1, 0x80,
-0xe1, 0x88, 0xc0, 0x46, 0x81, 0x81, 0x01, 0x23, 0xdb, 0x03, 0x78, 0x6c,
-0x18, 0x43, 0x3a, 0x4e, 0xc0, 0x46, 0xf0, 0x80, 0x00, 0xe0, 0x63, 0xe0,
-0xe0, 0x6a, 0x79, 0x6c, 0x4b, 0x00, 0x59, 0x18, 0x49, 0x01, 0x40, 0x18,
-0xc1, 0x1f, 0x59, 0x39, 0x38, 0x1c, 0x00, 0xf0, 0x0f, 0xfb, 0xe0, 0x6a,
-0x79, 0x6c, 0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, 0x80, 0x18, 0x01, 0x39,
-0x09, 0x04, 0x09, 0x0c, 0x60, 0x38, 0x00, 0xf0, 0x89, 0xfb, 0xb6, 0xe7,
-0x4a, 0xe0, 0x61, 0x88, 0x01, 0x31, 0x09, 0x04,
-0x09, 0x0c, 0x61, 0x80, 0xe2, 0x89, 0x91, 0x42, 0x00, 0xdb, 0x63, 0x80,
-0x00, 0x21, 0x00, 0x2a, 0x3e, 0xdd, 0x24, 0x4c, 0xe4, 0x6a, 0x23, 0x4b,
-0x5d, 0x88, 0x6b, 0x00, 0x5b, 0x19, 0x5b, 0x01, 0xe3, 0x18, 0xde, 0x1d,
-0x01, 0x36, 0x01, 0x23, 0x9b, 0x07, 0x33, 0x43, 0x1b, 0x68, 0x1b, 0x06,
-0x20, 0xd1, 0x1c, 0x4e, 0xf1, 0x88, 0x01, 0x31, 0xf1, 0x80, 0xf1, 0x88,
-0xc0, 0x46, 0x81, 0x81, 0x70, 0x88, 0x01, 0x23, 0xdb, 0x03, 0x01, 0x30,
-0x18, 0x43, 0x17, 0x49, 0xc0, 0x46, 0xc8, 0x80, 0x68, 0x00, 0x40, 0x19,
-0x40, 0x01, 0x21, 0x18, 0x38, 0x1c, 0x00, 0xf0, 0xcf, 0xfa, 0x71, 0x88,
-0x4a, 0x00, 0x52, 0x18, 0x52, 0x01, 0xf0, 0x6a, 0x80, 0x18, 0x00, 0xf0,
-0x4d, 0xfb, 0x0e, 0x49, 0xc8, 0x88, 0x79, 0xe7, 0x0b, 0x4b, 0x01, 0x35,
-0x2d, 0x04, 0x2d, 0x0c, 0x5d, 0x80, 0x95, 0x42, 0x01, 0xdb, 0x00, 0x25,
-0x5d, 0x80, 0x01, 0x31, 0x09, 0x04, 0x09, 0x14, 0x8a, 0x42, 0xc2, 0xdc,
-0x01, 0x89, 0x01, 0x31, 0x01, 0x81, 0x00, 0x20, 0xc0, 0x43, 0xf8, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x4c, 0x2b, 0x00, 0x80, 0x4c, 0x2a, 0x00, 0x80,
-0xc4, 0x66, 0x21, 0x40, 0xf0, 0xb4, 0x06, 0x1c, 0x01, 0x23, 0xdb, 0x03,
-0x33, 0x40, 0x01, 0x24, 0x44, 0x4f, 0x00, 0x20, 0x44, 0x4a, 0x45, 0x4d,
-0xd1, 0x1d, 0x39, 0x31, 0x00, 0x2b, 0x41, 0xd0, 0xe3, 0x03, 0xf3, 0x1a,
-0x73, 0xd0, 0xee, 0x89, 0x9e, 0x42, 0x71, 0xd3, 0xee, 0x88, 0x00, 0x2e,
-0x6d, 0xd0, 0xed, 0x6a, 0x5e, 0x1e, 0x73, 0x00, 0x9b, 0x19, 0x5b, 0x01,
-0xed, 0x18, 0xae, 0x68, 0x36, 0x06, 0x36, 0x0e, 0x03, 0x2e, 0x02, 0xd0,
-0xce, 0x89, 0x01, 0x36, 0xce, 0x81, 0x40, 0x35, 0xad, 0x8b, 0xad, 0x00,
-0x35, 0x4e, 0x76, 0x6a, 0xc0, 0x46, 0x70, 0x51, 0x55, 0x89, 0x01, 0x35,
-0x55, 0x81, 0x32, 0x4e, 0xf2, 0x6a, 0xd2, 0x18, 0x90, 0x60, 0xf2, 0x6a,
-0xd2, 0x18, 0x90, 0x63, 0xf2, 0x6a, 0xd2, 0x18, 0xd0, 0x63, 0xf2, 0x6a,
-0xd2, 0x18, 0x10, 0x64, 0xf2, 0x6a, 0xd2, 0x18, 0x50, 0x64, 0xf2, 0x6a,
-0xd2, 0x18, 0x90, 0x64, 0xf2, 0x6a, 0xd2, 0x18, 0xd0, 0x64, 0xf0, 0x88,
-0x01, 0x38, 0xf0, 0x80, 0xf0, 0x88, 0xc0, 0x46, 0x88, 0x81, 0x24, 0x49,
-0x00, 0x28, 0x39, 0xd1, 0x4f, 0x80, 0x37, 0xe0, 0x00, 0x2e, 0x38, 0xd9,
-0xab, 0x89, 0xb3, 0x42, 0x30, 0xd3, 0xab, 0x88, 0x00, 0x2b, 0x2c, 0xd0,
-0x53, 0x89, 0x01, 0x33, 0x53, 0x81, 0x2a, 0x1c, 0xad, 0x6a, 0x58, 0x23,
-0x01, 0x3e, 0x73, 0x43, 0xed, 0x18, 0xae, 0x68, 0x36, 0x06, 0x36, 0x0e,
-0x03, 0x2e, 0x02, 0xd0, 0xce, 0x89, 0x01, 0x36, 0xce, 0x81, 0xa8, 0x60,
-0x95, 0x6a, 0xed, 0x18, 0xa8, 0x63, 0x95, 0x6a, 0xed, 0x18, 0xe8, 0x63,
-0x95, 0x6a, 0xed, 0x18, 0x28, 0x64, 0x95, 0x6a, 0xed, 0x18, 0x68, 0x64,
-0x95, 0x6a, 0xed, 0x18, 0xa8, 0x64, 0x95, 0x6a, 0xeb, 0x18, 0xd8, 0x64,
-0x90, 0x88, 0x01, 0x38, 0x90, 0x80, 0x90, 0x88, 0xc0, 0x46, 0x48, 0x81,
-0x00, 0x28, 0x03, 0xd1, 0x01, 0xe0, 0x04, 0xe0, 0x03, 0xe0, 0x17, 0x80,
-0x20, 0x1c, 0xf0, 0xbc, 0x70, 0x47, 0xca, 0x89, 0x01, 0x32, 0xca, 0x81,
-0xf9, 0xe7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80,
-0x4c, 0x2a, 0x00, 0x80, 0x00, 0xb5, 0x00, 0x21, 0x41, 0x60, 0x10, 0x49,
-0x4a, 0x68, 0x00, 0x2a, 0x10, 0xd1, 0xca, 0x68, 0x00, 0x2a, 0x04, 0xd0,
-0xca, 0x1d, 0x19, 0x32, 0x12, 0x79, 0x00, 0x2a, 0x08, 0xd0, 0x4a, 0x69,
-0x00, 0x2a, 0x0b, 0xd1, 0x88, 0x61, 0x48, 0x61,
-0x00, 0xf0, 0x10, 0xf8, 0x08, 0xbc, 0x18, 0x47, 0x4a, 0x69, 0x00, 0x2a,
-0x02, 0xd1, 0x88, 0x61, 0x48, 0x61, 0xf7, 0xe7, 0x8a, 0x69, 0xc0, 0x46,
-0x50, 0x60, 0x88, 0x61, 0xf2, 0xe7, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80,
-0xb0, 0xb5, 0x2a, 0x48, 0x40, 0x69, 0x00, 0x28, 0x4c, 0xd0, 0x08, 0x22,
-0xc1, 0x68, 0x0a, 0x40, 0x00, 0x27, 0x27, 0x4b, 0xd9, 0x1d, 0xb9, 0x31,
-0x00, 0x2a, 0x11, 0xd0, 0x04, 0x22, 0x25, 0x4c, 0xc0, 0x46, 0x0c, 0x61,
-0x24, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x24, 0x4c, 0xc0, 0x46, 0x8c, 0x62,
-0x23, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x23, 0x4c, 0xc0, 0x46, 0x0c, 0x63,
-0x4f, 0x63, 0x12, 0xe0, 0x05, 0x22, 0x21, 0x4c, 0xc0, 0x46, 0x0c, 0x61,
-0x20, 0x4c, 0xc0, 0x46, 0x4c, 0x62, 0x20, 0x4c, 0xc0, 0x46, 0x8c, 0x62,
-0x1f, 0x4c, 0xc0, 0x46, 0xcc, 0x62, 0x1f, 0x4c, 0xc0, 0x46, 0x0c, 0x63,
-0x1e, 0x4c, 0xc0, 0x46, 0x4c, 0x63, 0x40, 0x24, 0xcc, 0x82, 0x4f, 0x83,
-0x1c, 0x4f, 0x00, 0x21, 0x00, 0x2a, 0x0c, 0xd9, 0x8c, 0x00, 0x05, 0x19,
-0x6d, 0x6a, 0x7d, 0x40, 0xe4, 0x18, 0xff, 0x34, 0x01, 0x34, 0x65, 0x62,
-0x01, 0x31, 0x91, 0x42, 0xf4, 0xd3, 0x10, 0x29, 0x07, 0xd2, 0x8a, 0x00,
-0xd2, 0x18, 0xff, 0x32, 0x01, 0x32, 0x57, 0x62, 0x01, 0x31, 0x10, 0x29,
-0xf7, 0xd3, 0x11, 0x49, 0x00, 0xf0, 0x22, 0xf8, 0xb0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x6c, 0x06, 0x00, 0x80, 0xac, 0xab, 0x20, 0x40,
-0x28, 0x01, 0x40, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
-0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x20, 0x01, 0x40, 0x00,
-0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, 0xdc, 0xfe,
-0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0, 0x36, 0x36, 0x36, 0x36,
-0x30, 0x80, 0x20, 0x40, 0xb0, 0xb5, 0x0f, 0x1c, 0x15, 0x4d, 0xe9, 0x1d,
-0xc9, 0x31, 0x15, 0x4c, 0x23, 0x1c, 0x15, 0x4a, 0x00, 0x20, 0xfc, 0xf7,
-0x44, 0xfb, 0xe9, 0x1d, 0xff, 0x31, 0x1e, 0x31, 0x23, 0x1c, 0x0d, 0x1c,
-0x11, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x3b, 0xfb, 0x29, 0x1c, 0x23, 0x1c,
-0x0e, 0x4a, 0x00, 0x20, 0xfc, 0xf7, 0x35, 0xfb, 0x39, 0x1c, 0x23, 0x1c,
-0x0c, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x2f, 0xfb, 0x00, 0x21, 0x0b, 0x48,
-0xc2, 0x1d, 0x19, 0x32, 0x51, 0x71, 0x01, 0x21, 0xff, 0x30, 0x01, 0x30,
-0x41, 0x62, 0x08, 0x1c, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0xac, 0xab, 0x20, 0x40, 0x75, 0x08, 0xff, 0xff, 0x28, 0x00, 0x03, 0x00,
-0x40, 0x00, 0x02, 0x00, 0x14, 0x00, 0x07, 0x00, 0x6c, 0x06, 0x00, 0x80,
-0xf0, 0xb5, 0x37, 0x4a, 0x50, 0x69, 0x01, 0x23, 0x9b, 0x07, 0x08, 0x30,
-0x18, 0x43, 0x00, 0x68, 0x01, 0x06, 0x09, 0x0e, 0x33, 0x4b, 0x01, 0x29,
-0x49, 0xd1, 0x1f, 0x68, 0x19, 0x1c, 0x32, 0x4b, 0x9f, 0x42, 0x04, 0xd1,
-0xff, 0xf7, 0x3e, 0xff, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x23,
-0x9f, 0x00, 0xcc, 0x59, 0x55, 0x69, 0xef, 0x19, 0x3c, 0x61, 0x01, 0x33,
-0x05, 0x2b, 0xf7, 0xd3, 0x00, 0x0a, 0x00, 0x02, 0x02, 0x23, 0x18, 0x43,
-0x53, 0x69, 0xc0, 0x46, 0x98, 0x60, 0x50, 0x69, 0x08, 0x23, 0xc2, 0x68,
-0x13, 0x40, 0x25, 0x4f, 0xfa, 0x1d, 0xb9, 0x32, 0x00, 0x2b, 0x02, 0xd0,
-0x04, 0x23, 0x23, 0x4c, 0x01, 0xe0, 0x05, 0x23, 0x22, 0x4c, 0xc0, 0x46,
-0x14, 0x61, 0x40, 0x24, 0xd4, 0x82, 0x00, 0x24, 0x54, 0x83, 0x20, 0x4c,
-0x00, 0x22, 0x00, 0x2b, 0x0c, 0xd9, 0x95, 0x00,
-0x46, 0x19, 0x76, 0x6a, 0x66, 0x40, 0xed, 0x19, 0xff, 0x35, 0x01, 0x35,
-0x6e, 0x62, 0x01, 0x32, 0x9a, 0x42, 0xf4, 0xd3, 0x10, 0x2a, 0x07, 0xd2,
-0x93, 0x00, 0xdb, 0x19, 0xff, 0x33, 0x01, 0x33, 0x5c, 0x62, 0x01, 0x32,
-0x10, 0x2a, 0xf7, 0xd3, 0xff, 0xf7, 0x70, 0xff, 0xbc, 0xe7, 0x00, 0x21,
-0x8f, 0x00, 0xdc, 0x59, 0x55, 0x69, 0xef, 0x19, 0x7c, 0x62, 0x01, 0x31,
-0x05, 0x29, 0xf7, 0xd3, 0x00, 0x0a, 0x00, 0x02, 0x03, 0x23, 0x18, 0x43,
-0x51, 0x69, 0xc0, 0x46, 0x88, 0x60, 0x50, 0x69, 0x40, 0x68, 0xc0, 0x46,
-0x50, 0x61, 0x09, 0x48, 0xfc, 0xf7, 0xa4, 0xfa, 0xa4, 0xe7, 0x00, 0x00,
-0x6c, 0x06, 0x00, 0x80, 0x30, 0x80, 0x20, 0x40, 0x67, 0x45, 0x23, 0x01,
-0xac, 0xab, 0x20, 0x40, 0x28, 0x01, 0x40, 0x00, 0x20, 0x01, 0x40, 0x00,
-0x5c, 0x5c, 0x5c, 0x5c, 0x11, 0x31, 0xff, 0xff, 0xf0, 0xb5, 0x07, 0x1c,
-0x3b, 0x48, 0x3c, 0x4c, 0x08, 0x21, 0x20, 0x60, 0xa1, 0x80, 0x00, 0x20,
-0x20, 0x81, 0xe1, 0x80, 0x60, 0x81, 0x39, 0x48, 0xc0, 0x46, 0xe0, 0x60,
-0x38, 0x48, 0xc0, 0x46, 0x20, 0x61, 0x38, 0x48, 0xc0, 0x46, 0x60, 0x61,
-0x37, 0x48, 0xc0, 0x46, 0xa0, 0x61, 0x37, 0x48, 0xc0, 0x46, 0xe0, 0x61,
-0x36, 0x48, 0xc0, 0x46, 0x20, 0x62, 0x36, 0x48, 0xc0, 0x46, 0x60, 0x62,
-0x35, 0x48, 0xc0, 0x46, 0xa0, 0x62, 0x35, 0x48, 0xc0, 0x46, 0xe0, 0x62,
-0x34, 0x48, 0xc0, 0x46, 0x20, 0x63, 0x34, 0x48, 0xc0, 0x46, 0x60, 0x63,
-0x33, 0x48, 0xc0, 0x46, 0xa0, 0x63, 0x33, 0x48, 0xc0, 0x46, 0xe0, 0x63,
-0x32, 0x48, 0xc0, 0x46, 0x20, 0x64, 0x32, 0x48, 0xc0, 0x46, 0x60, 0x64,
-0x31, 0x48, 0xc0, 0x46, 0xa0, 0x64, 0x31, 0x48, 0xc0, 0x46, 0xe0, 0x64,
-0x30, 0x48, 0xc0, 0x46, 0x20, 0x65, 0x30, 0x49, 0xc8, 0x68, 0x02, 0x04,
-0x89, 0x69, 0x4a, 0x40, 0xe3, 0x1d, 0x79, 0x33, 0x09, 0x04, 0xc9, 0x43,
-0xc0, 0x43, 0x48, 0x40, 0xe1, 0x1d, 0xb9, 0x31, 0xda, 0x63, 0x08, 0x60,
-0x29, 0x4d, 0x21, 0x1c, 0x2b, 0x1c, 0x29, 0x4a, 0x00, 0x20, 0xfc, 0xf7,
-0x3e, 0xfa, 0x28, 0x4a, 0xe1, 0x1d, 0xb5, 0x31, 0x01, 0x20, 0x2b, 0x1c,
-0x0e, 0x1c, 0xfc, 0xf7, 0x36, 0xfa, 0x24, 0x4a, 0x00, 0x20, 0x31, 0x1c,
-0x2b, 0x1c, 0xfc, 0xf7, 0x30, 0xfa, 0xe1, 0x1d, 0x4d, 0x31, 0x2b, 0x1c,
-0x20, 0x4a, 0x01, 0x20, 0xfc, 0xf7, 0x29, 0xfa, 0xe0, 0x1d, 0x5d, 0x30,
-0x01, 0x68, 0x00, 0x29, 0xfc, 0xd0, 0x60, 0x6d, 0xc0, 0x46, 0x38, 0x65,
-0x20, 0x6e, 0xc0, 0x46, 0x78, 0x65, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x80, 0x00, 0x08, 0x00, 0x8c, 0xb9, 0x20, 0x40, 0x81, 0x81, 0x48, 0xbd,
-0x79, 0x56, 0x23, 0x8c, 0x93, 0x0c, 0x82, 0x95, 0x1d, 0x0e, 0x12, 0xcf,
-0x9b, 0x3b, 0xc0, 0xe9, 0xe6, 0x55, 0x7c, 0x82, 0x99, 0xf6, 0x78, 0x02,
-0xd1, 0xd7, 0x25, 0x73, 0x72, 0x8c, 0x33, 0x10, 0xf7, 0x03, 0xf1, 0x42,
-0x6c, 0x9b, 0x4a, 0xa7, 0x82, 0x8e, 0x23, 0xa9, 0x90, 0xb1, 0x82, 0x8e,
-0xdc, 0x3f, 0xfb, 0x29, 0x00, 0x62, 0x22, 0x45, 0x88, 0x2b, 0xf1, 0x85,
-0x12, 0x61, 0xd1, 0x73, 0x6e, 0xb1, 0x11, 0x16, 0x08, 0x83, 0x20, 0x40,
-0x75, 0x08, 0xff, 0xff, 0x54, 0x00, 0x03, 0x00, 0x08, 0x00, 0x02, 0x00,
-0x14, 0x00, 0x03, 0x00, 0x80, 0xb5, 0x0f, 0x1c, 0x39, 0x1c, 0x00, 0xf0,
-0x33, 0xf8, 0x38, 0x1c, 0xff, 0xf7, 0x4c, 0xff, 0x03, 0x48, 0x01, 0x89,
-0x01, 0x31, 0x01, 0x81, 0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x0c, 0x2b, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c,
-0x0f, 0x1c, 0x20, 0x1c, 0x39, 0x1c, 0x00, 0xf0, 0x1f, 0xf8, 0xe0, 0x68,
-0x01, 0x0e, 0xff, 0x22, 0x12, 0x04, 0x02, 0x40, 0x12, 0x0a, 0x11, 0x43,
-0xff, 0x22, 0x12, 0x02, 0x02, 0x40, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06,
-0x08, 0x43, 0x38, 0x65, 0x20, 0x69, 0xc0, 0x46, 0x78, 0x65, 0x60, 0x69,
-0xc0, 0x46, 0xb8, 0x65, 0x03, 0x48, 0x01, 0x89, 0x01, 0x31, 0x01, 0x81,
-0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x0c, 0x2b, 0x00, 0x80,
-0x90, 0xb5, 0x00, 0x22, 0x93, 0x00, 0x1f, 0x18, 0xbf, 0x69, 0x5b, 0x18,
-0x5f, 0x62, 0x01, 0x32, 0x05, 0x2a, 0xf7, 0xd3, 0x07, 0x7a, 0xfb, 0x08,
-0x03, 0xd3, 0x00, 0x23, 0x92, 0x00, 0x52, 0x18, 0x13, 0x62, 0x07, 0x6b,
-0xc0, 0x46, 0x8f, 0x63, 0xc7, 0x6a, 0xc0, 0x46, 0xcf, 0x63, 0x87, 0x6b,
-0xc0, 0x46, 0x0f, 0x64, 0x47, 0x6b, 0xc0, 0x46, 0x4f, 0x64, 0x07, 0x6c,
-0xc0, 0x46, 0x8f, 0x64, 0xc2, 0x6b, 0xc0, 0x46, 0xca, 0x64, 0xc2, 0x88,
-0xc0, 0x46, 0x0a, 0x80, 0x82, 0x7a, 0x12, 0x06, 0x03, 0x7a, 0x1b, 0x04,
-0x1a, 0x43, 0xc3, 0x88, 0x1b, 0x02, 0x1a, 0x43, 0x43, 0x7a, 0xdb, 0x07,
-0x1a, 0x43, 0x8a, 0x60, 0x17, 0x1c, 0x83, 0x7a, 0x5a, 0x08, 0x05, 0xd3,
-0x14, 0x22, 0x1c, 0x1c, 0xa3, 0x08, 0x02, 0xd2, 0x15, 0x22, 0x00, 0xe0,
-0x00, 0x22, 0x00, 0x7a, 0x43, 0x08, 0x10, 0xd3, 0xc0, 0x08, 0x02, 0xd3,
-0x88, 0x20, 0x10, 0x43, 0x01, 0xe0, 0x80, 0x20, 0x10, 0x43, 0x3a, 0x0a,
-0x12, 0x02, 0x01, 0x23, 0x1a, 0x43, 0xc8, 0x60, 0x8a, 0x60, 0x08, 0x1c,
-0xff, 0xf7, 0x78, 0xfd, 0x05, 0xe0, 0x38, 0x0a, 0x00, 0x02, 0x03, 0x23,
-0x18, 0x43, 0x88, 0x60, 0xca, 0x60, 0x03, 0x48, 0x01, 0x89, 0x01, 0x31,
-0x01, 0x81, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x0c, 0x2b, 0x00, 0x80,
-0xf0, 0xb4, 0x02, 0x6d, 0x14, 0x4c, 0x15, 0x1c, 0xe7, 0x69, 0xbd, 0x40,
-0x13, 0x1c, 0x26, 0x6a, 0xf3, 0x40, 0x5d, 0x40, 0x2e, 0x1c, 0x45, 0x6d,
-0xbd, 0x40, 0x6e, 0x40, 0x2b, 0x1c, 0x35, 0x1c, 0xfd, 0x40, 0x2f, 0x1c,
-0xbb, 0x00, 0x65, 0x6a, 0xeb, 0x58, 0x00, 0x2b, 0x08, 0xd0, 0x23, 0x69,
-0x01, 0x37, 0x9f, 0x42, 0x00, 0xd3, 0x00, 0x27, 0xbe, 0x00, 0xae, 0x59,
-0x00, 0x2e, 0xf7, 0xd1, 0xa4, 0x69, 0xa2, 0x40, 0x11, 0x43, 0x05, 0x4b,
-0x19, 0x43, 0xba, 0x00, 0xa9, 0x50, 0x40, 0x30, 0x87, 0x83, 0xf0, 0xbc,
-0x70, 0x47, 0x00, 0x00, 0x4c, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
-0x80, 0xb4, 0x00, 0x22, 0x00, 0x23, 0x00, 0x29, 0x05, 0xd9, 0x07, 0x78,
-0x7a, 0x40, 0x01, 0x30, 0x01, 0x33, 0x8b, 0x42, 0xf9, 0xd3, 0xd0, 0x43,
-0x00, 0x06, 0x00, 0x0e, 0x80, 0xbc, 0x70, 0x47, 0xf0, 0xb5, 0x07, 0x1c,
-0x00, 0x24, 0xff, 0x26, 0x09, 0x36, 0x20, 0x1c, 0x00, 0xf0, 0x9a, 0xf8,
-0x00, 0xf0, 0xb8, 0xf9, 0x05, 0x1c, 0x00, 0xf0, 0xc7, 0xfa, 0x3d, 0x70,
-0x28, 0x1c, 0x01, 0x37, 0x01, 0x34, 0xb4, 0x42, 0xf1, 0xd3, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x80, 0xb5, 0x00, 0xf0, 0x93, 0xf8, 0x00, 0xf0,
-0xa7, 0xf9, 0x07, 0x1c, 0x00, 0xf0, 0xb6, 0xfa, 0x38, 0x0a, 0xf6, 0xd3,
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf3, 0xb5, 0x82, 0xb0, 0x02, 0x98,
-0x41, 0x02, 0x53, 0x20, 0x00, 0xf0, 0x64, 0xf8, 0x00, 0xf0, 0xa8, 0xfa,
-0xff, 0xf7, 0xe8, 0xff, 0x00, 0x24, 0x00, 0x20, 0x01, 0x90, 0x2e, 0x20,
-0x00, 0x90, 0x00, 0x25, 0x00, 0x27, 0x02, 0x98, 0x01, 0x28, 0x04, 0xd1,
-0x00, 0x98, 0x84, 0x42, 0x01, 0xd3, 0x00, 0x26,
-0x09, 0xe0, 0x01, 0x98, 0x41, 0x1c, 0x01, 0x91, 0x00, 0xf0, 0x60, 0xf8,
-0x00, 0xf0, 0x7e, 0xf9, 0x06, 0x1c, 0x00, 0xf0, 0x8d, 0xfa, 0xf8, 0x00,
-0x86, 0x40, 0x35, 0x43, 0x01, 0x34, 0x01, 0x37, 0x04, 0x2f, 0xe6, 0xd3,
-0x03, 0x99, 0x20, 0xc1, 0x03, 0x91, 0xff, 0x23, 0x09, 0x33, 0x9c, 0x42,
-0xdd, 0xd3, 0x04, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0xf0, 0xb5,
-0x04, 0x1c, 0x0f, 0x1c, 0x01, 0x2c, 0x2a, 0xd0, 0x16, 0x48, 0xc0, 0x6f,
-0x40, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x00, 0x26, 0x20, 0xcf,
-0xb1, 0x00, 0x84, 0x20, 0x00, 0xf0, 0x24, 0xf8, 0x28, 0x1c, 0x00, 0xf0,
-0xdf, 0xf9, 0x28, 0x0a, 0x00, 0xf0, 0xdc, 0xf9, 0x28, 0x0c, 0x00, 0xf0,
-0xd9, 0xf9, 0x28, 0x0e, 0x00, 0xf0, 0xd6, 0xf9, 0x00, 0xf0, 0x5c, 0xfa,
-0x01, 0x36, 0x42, 0x2e, 0xe9, 0xd3, 0x61, 0x02, 0x83, 0x20, 0x00, 0xf0,
-0x0f, 0xf8, 0x00, 0xf0, 0x53, 0xfa, 0xff, 0xf7, 0x93, 0xff, 0x04, 0x48,
-0xc0, 0x6f, 0x40, 0x23, 0x01, 0x68, 0x99, 0x43, 0x01, 0x60, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x90, 0xb5, 0x04, 0x1c,
-0x0f, 0x1c, 0x00, 0xf0, 0x59, 0xfa, 0x20, 0x1c, 0x00, 0xf0, 0xb6, 0xf9,
-0x38, 0x0c, 0x00, 0xf0, 0xb3, 0xf9, 0x38, 0x0a, 0x00, 0xf0, 0xb0, 0xf9,
-0x38, 0x1c, 0x00, 0xf0, 0xad, 0xf9, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x00, 0xb5, 0x01, 0x1c, 0x54, 0x20, 0xff, 0xf7, 0xe7, 0xff, 0x00, 0x20,
-0x00, 0xf0, 0xa2, 0xf9, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0,
-0x3d, 0xfa, 0x57, 0x20, 0x00, 0xf0, 0x9a, 0xf9, 0x08, 0xbc, 0x18, 0x47,
-0x90, 0xb5, 0x08, 0x4f, 0xfa, 0x6f, 0x20, 0x23, 0x14, 0x68, 0x9c, 0x43,
-0x14, 0x60, 0x23, 0x1c, 0xff, 0xf7, 0x65, 0xff, 0xf8, 0x6f, 0x20, 0x23,
-0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0x90, 0xb5, 0x08, 0x4f, 0xfa, 0x6f, 0x20, 0x23,
-0x14, 0x68, 0x9c, 0x43, 0x14, 0x60, 0x23, 0x1c, 0xff, 0xf7, 0x87, 0xff,
-0xf8, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0x90, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0x04, 0x1c,
-0x0f, 0x1c, 0x18, 0x4e, 0xf0, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x99, 0x43,
-0x01, 0x60, 0x61, 0x02, 0x53, 0x20, 0xff, 0xf7, 0xa5, 0xff, 0x00, 0xf0,
-0xe9, 0xf9, 0xff, 0xf7, 0x29, 0xff, 0xf8, 0x1d, 0x05, 0x30, 0x01, 0x2c,
-0x03, 0xd1, 0x22, 0x2f, 0x01, 0xd3, 0x00, 0x27, 0x0f, 0xe0, 0x44, 0x1c,
-0xff, 0xf7, 0xaa, 0xff, 0x00, 0xf0, 0xc8, 0xf8, 0x07, 0x1c, 0x00, 0xf0,
-0xd7, 0xf9, 0x20, 0x1c, 0xff, 0xf7, 0xa2, 0xff, 0x00, 0xf0, 0xc0, 0xf8,
-0x05, 0x1c, 0x00, 0xf0, 0xcf, 0xf9, 0xf0, 0x6f, 0x20, 0x23, 0x01, 0x68,
-0x19, 0x43, 0x01, 0x60, 0x28, 0x02, 0x38, 0x43, 0xf0, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0xf0, 0xb5, 0xc2, 0xb0,
-0x14, 0x1c, 0x0d, 0x1c, 0x07, 0x1c, 0x01, 0x2f, 0x2f, 0xd0, 0x79, 0x02,
-0x19, 0x4e, 0xf0, 0x6f, 0x20, 0x23, 0x02, 0x68, 0x9a, 0x43, 0x02, 0x60,
-0x53, 0x20, 0xff, 0xf7, 0x6b, 0xff, 0x00, 0xf0, 0xaf, 0xf9, 0xff, 0xf7,
-0xef, 0xfe, 0x68, 0x46, 0xff, 0xf7, 0xd6, 0xfe, 0x6a, 0x46, 0xe8, 0x1d,
-0x05, 0x30, 0x14, 0x54, 0x21, 0x0a, 0x68, 0x44, 0x41, 0x70, 0x68, 0x46,
-0x00, 0x99, 0x0c, 0x30, 0xff, 0xf7, 0xba, 0xfe, 0x02, 0xab, 0x18, 0x70,
-0x00, 0x20, 0x58, 0x70, 0x68, 0x46, 0x0c, 0x21,
-0xff, 0xf7, 0xb2, 0xfe, 0x02, 0xab, 0x58, 0x70, 0x69, 0x46, 0x38, 0x1c,
-0xff, 0xf7, 0x15, 0xff, 0xf0, 0x6f, 0x20, 0x23, 0x01, 0x68, 0x19, 0x43,
-0x01, 0x60, 0x42, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0xff, 0xb5, 0xc2, 0xb0, 0x07, 0x1c, 0x01, 0x2f,
-0x01, 0xd1, 0x01, 0x20, 0x36, 0xe0, 0x6b, 0x46, 0x00, 0x20, 0xc4, 0x43,
-0x10, 0xc3, 0x01, 0x30, 0x42, 0x28, 0xfb, 0xd3, 0x68, 0x46, 0x0c, 0x30,
-0x03, 0x1c, 0x00, 0x24, 0x00, 0x2a, 0x0a, 0xd9, 0x0e, 0x88, 0xc0, 0x46,
-0x06, 0x70, 0x0e, 0x88, 0x36, 0x12, 0x46, 0x70, 0x02, 0x30, 0x02, 0x31,
-0x02, 0x34, 0x94, 0x42, 0xf4, 0xd3, 0x00, 0x92, 0x18, 0x1c, 0x11, 0x1c,
-0xff, 0xf7, 0x7c, 0xfe, 0x04, 0x1c, 0x00, 0x20, 0x01, 0x90, 0x02, 0xab,
-0x1c, 0x70, 0x58, 0x70, 0x9d, 0x70, 0x68, 0x46, 0x0c, 0x21, 0xff, 0xf7,
-0x71, 0xfe, 0x02, 0xab, 0x58, 0x70, 0x45, 0x9b, 0x1d, 0x06, 0x2d, 0x0e,
-0xac, 0x42, 0x03, 0xd1, 0x69, 0x46, 0x38, 0x1c, 0xff, 0xf7, 0x3e, 0xff,
-0x01, 0x20, 0xac, 0x42, 0x00, 0xd1, 0x00, 0x20, 0x46, 0xb0, 0xf0, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0xb0, 0xb5, 0xc2, 0xb0, 0x0f, 0x1c, 0x41, 0x02,
-0x14, 0x4c, 0xe0, 0x6f, 0x20, 0x23, 0x02, 0x68, 0x9a, 0x43, 0x02, 0x60,
-0x53, 0x20, 0xff, 0xf7, 0xef, 0xfe, 0x00, 0xf0, 0x33, 0xf9, 0xff, 0xf7,
-0x73, 0xfe, 0x68, 0x46, 0xff, 0xf7, 0x5a, 0xfe, 0xe0, 0x6f, 0x20, 0x23,
-0x01, 0x68, 0x19, 0x43, 0x02, 0xad, 0x01, 0x60, 0x6d, 0x78, 0x00, 0x24,
-0x02, 0xab, 0x5c, 0x70, 0x68, 0x46, 0x0c, 0x21, 0xff, 0xf7, 0x3c, 0xfe,
-0xa8, 0x42, 0x02, 0xd1, 0x00, 0x98, 0x87, 0x42, 0x01, 0xd3, 0x20, 0x1c,
-0x00, 0xe0, 0x01, 0x20, 0x42, 0xb0, 0xb0, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0xfc, 0x46, 0x60, 0x47, 0x00, 0x00, 0xa0, 0xe3,
-0xb4, 0x22, 0x9f, 0xe5, 0xb4, 0x32, 0x9f, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5,
-0x81, 0x03, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 0x01, 0x03, 0x80, 0xe1,
-0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x93, 0xe5, 0x81, 0x02, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5,
-0x01, 0x02, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5, 0x81, 0x01, 0x80, 0xe1,
-0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x93, 0xe5, 0x01, 0x01, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5,
-0x81, 0x00, 0x80, 0xe1, 0x01, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x93, 0xe5,
-0x01, 0x00, 0x80, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0xfc, 0x46, 0x60, 0x47,
-0xa4, 0x21, 0x9f, 0xe5, 0xa8, 0x31, 0x9f, 0xe5, 0xa0, 0x13, 0xa0, 0xe1,
-0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x20, 0x13, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5,
-0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0xa0, 0x12, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x20, 0x12, 0xa0, 0xe1,
-0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0xa0, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5,
-0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x20, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5, 0xa0, 0x10, 0xa0, 0xe1,
-0x00, 0x10, 0x83, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0xa0, 0xe1, 0x00, 0x10, 0x83, 0xe5,
-0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5, 0x00, 0x10, 0x82, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0xfc, 0x46, 0x60, 0x47, 0xa0, 0x30, 0x9f, 0xe5,
-0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0xfc, 0x46, 0x60, 0x47, 0x70, 0x30, 0x9f, 0xe5,
-0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x1e, 0xff, 0x2f, 0xe1, 0xfc, 0x46, 0x60, 0x47, 0x34, 0x20, 0x9f, 0xe5,
-0x3c, 0x30, 0x9f, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x82, 0xe5,
-0x00, 0x10, 0x82, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5, 0x00, 0x10, 0x83, 0xe5,
-0x00, 0x10, 0x83, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf8, 0x00, 0x18, 0x40,
-0x04, 0x01, 0x18, 0x40, 0x00, 0x01, 0x18, 0x40, 0xfc, 0x00, 0x18, 0x40,
-0x80, 0xb5, 0x00, 0xf0, 0x0c, 0xf8, 0x00, 0x27, 0x38, 0x1c, 0x00, 0xf0,
-0x47, 0xf8, 0x78, 0x1c, 0x07, 0x04, 0x3f, 0x0c, 0x0c, 0x2f, 0xf7, 0xdd,
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x1d, 0x48,
-0x02, 0x68, 0x1d, 0x49, 0x8b, 0x69, 0xd2, 0x18, 0x02, 0x60, 0x02, 0x66,
-0x8a, 0x6a, 0x43, 0x68, 0x9b, 0x18, 0x43, 0x60, 0x93, 0x42, 0x02, 0xd2,
-0x82, 0x68, 0x01, 0x32, 0x82, 0x60, 0xc2, 0x68, 0x0b, 0x6a, 0xd2, 0x18,
-0xc2, 0x60, 0x42, 0x69, 0xcb, 0x68, 0xd2, 0x18, 0x42, 0x61, 0xc2, 0x69,
-0x8b, 0x68, 0xd2, 0x18, 0xc2, 0x61, 0x02, 0x69, 0x0b, 0x69, 0xd2, 0x18,
-0x02, 0x61, 0x82, 0x69, 0x0b, 0x68, 0xd2, 0x18, 0x82, 0x61, 0x02, 0x6b,
-0xcb, 0x69, 0xd2, 0x18, 0x02, 0x63, 0x4a, 0x6a, 0x43, 0x6b, 0x9b, 0x18,
-0x43, 0x63, 0x93, 0x42, 0x02, 0xd2, 0x82, 0x6b, 0x01, 0x32, 0x82, 0x63,
-0xc2, 0x6b, 0x4b, 0x69, 0xd2, 0x18, 0xc2, 0x63, 0x02, 0x6c, 0xc9, 0x6a,
-0x51, 0x18, 0x01, 0x64, 0x70, 0x47, 0x00, 0x00, 0xa4, 0x2a, 0x00, 0x80,
-0x00, 0x08, 0x14, 0x40, 0x88, 0xb5, 0x69, 0x46, 0x00, 0xf0, 0x17, 0xf8,
-0x81, 0x08, 0x0a, 0xd0, 0x00, 0x20, 0x00, 0x29, 0x07, 0xd9, 0x00, 0x22,
-0x83, 0x00, 0x00, 0x9f, 0xc0, 0x46, 0xfa, 0x50, 0x01, 0x30, 0x88, 0x42,
-0xf8, 0xd3, 0x88, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xb5, 0x00, 0xf0,
-0x04, 0xf8, 0x00, 0x04, 0x00, 0x0c, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x22,
-0x00, 0x28, 0x0a, 0xd0, 0x01, 0x28, 0x0a, 0xd0, 0x02, 0x28, 0x0c, 0xd0,
-0x03, 0x28, 0x02, 0xd1, 0x07, 0x48, 0x1c, 0x22, 0x08, 0x60, 0x10, 0x1c,
-0x70, 0x47, 0x06, 0x48, 0x04, 0xe0, 0x06, 0x48, 0x50, 0x22, 0x08, 0x60,
-0xf7, 0xe7, 0x05, 0x48, 0x68, 0x22, 0x08, 0x60, 0xf3, 0xe7, 0x00, 0x00,
-0x08, 0x83, 0x20, 0x40, 0xa4, 0x2a, 0x00, 0x80, 0x0c, 0x2b, 0x00, 0x80,
-0xa0, 0x82, 0x20, 0x40, 0x80, 0xb4, 0x03, 0x22, 0xc2, 0x80, 0x15, 0x4a,
-0xc0, 0x46, 0x82, 0x60, 0x14, 0x4a, 0x12, 0x88, 0x01, 0x32, 0xc2, 0x60,
-0x00, 0x20, 0x13, 0x4a, 0x13, 0x5c, 0xc0, 0x46, 0x0b, 0x70, 0x01, 0x30,
-0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, 0x20, 0x22, 0x0a, 0x70, 0x01, 0x31,
-0x00, 0x20, 0x0e, 0x4b, 0x1f, 0x5c, 0xc0, 0x46, 0x0f, 0x70, 0x01, 0x30,
-0x01, 0x31, 0x08, 0x28, 0xf8, 0xd3, 0x0a, 0x70, 0x01, 0x31, 0x00, 0x20,
-0x09, 0x4a, 0x13, 0x5c, 0xc0, 0x46, 0x0b, 0x70, 0x01, 0x30, 0x01, 0x31,
-0x08, 0x28, 0xf8, 0xd3, 0x00, 0x20, 0x08, 0x70, 0x80, 0xbc, 0x70, 0x47,
-0x08, 0x10, 0x00, 0x03, 0x68, 0x0e, 0x00, 0x80, 0x7c, 0x04, 0x00, 0x80,
-0x85, 0x04, 0x00, 0x80, 0x8e, 0x04, 0x00, 0x80, 0x00, 0xb5, 0x01, 0x23,
-0x0a, 0x48, 0xc1, 0x1d, 0x89, 0x31, 0x4b, 0x70, 0x00, 0x22, 0x0a, 0x70,
-0x64, 0x21, 0x80, 0x30, 0xc1, 0x82, 0x01, 0x83, 0x43, 0x83, 0x7d, 0x21,
-0xc9, 0x00, 0x81, 0x83, 0xc2, 0x83, 0x04, 0x48, 0x01, 0x22, 0x00, 0x21,
-0x00, 0xf0, 0x8e, 0xfb, 0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0xb5, 0x22, 0xff, 0xff, 0x00, 0xb5, 0xff, 0xf7, 0xe1, 0xff, 0x13, 0x48,
-0x02, 0x22, 0x00, 0x21, 0x00, 0xf0, 0x80, 0xfb, 0x01, 0x23, 0xd8, 0x42,
-0x0a, 0xd1, 0x10, 0x48, 0xc1, 0x1d, 0x39, 0x31, 0xca, 0x88, 0x01, 0x32,
-0xca, 0x80, 0x81, 0x79, 0x01, 0x31, 0x81, 0x71, 0xfd, 0xf7, 0x70, 0xf9,
-0x0b, 0x48, 0xc0, 0x68, 0x01, 0x28, 0x05, 0xd1, 0x0a, 0x48, 0x7d, 0x22,
-0xd2, 0x00, 0x00, 0x21, 0x00, 0xf0, 0x68, 0xfb, 0x08, 0x48, 0xfb, 0xf7,
-0xe1, 0xfc, 0x08, 0x48, 0x28, 0x22, 0x00, 0x21, 0x00, 0xf0, 0x60, 0xfb,
-0x08, 0xbc, 0x18, 0x47, 0x79, 0x21, 0xff, 0xff, 0xa0, 0x82, 0x20, 0x40,
-0x68, 0x0e, 0x00, 0x80, 0xa5, 0x7b, 0x21, 0x40,
-0x95, 0x2c, 0xff, 0xff, 0x59, 0x03, 0xff, 0xff, 0x00, 0xb5, 0x10, 0x20,
-0x0f, 0x49, 0xc0, 0x46, 0x08, 0x60, 0x0f, 0x4a, 0x0f, 0x48, 0x64, 0x21,
-0xfb, 0xf7, 0xc6, 0xfc, 0x0e, 0x48, 0x01, 0x22, 0x12, 0x04, 0x01, 0x68,
-0x0a, 0x40, 0x08, 0x21, 0x00, 0x2a, 0x05, 0xd1, 0x02, 0x68, 0x12, 0x0c,
-0x07, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x04, 0xd3, 0x08, 0x48, 0xc0, 0x46,
-0xc1, 0x60, 0x08, 0xbc, 0x18, 0x47, 0x07, 0x48, 0xc0, 0x46, 0x01, 0x64,
-0xf9, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xa5, 0x55, 0xff, 0xff,
-0x7c, 0x29, 0x00, 0x80, 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00,
-0x00, 0x00, 0x00, 0x80, 0xf8, 0xb5, 0x27, 0x48, 0x01, 0x22, 0x12, 0x04,
-0x01, 0x68, 0x0a, 0x40, 0x07, 0x21, 0x00, 0x2a, 0x05, 0xd1, 0x02, 0x68,
-0x12, 0x0c, 0x06, 0xd1, 0x00, 0x68, 0x80, 0x0a, 0x03, 0xd3, 0x21, 0x48,
-0xc0, 0x46, 0xc1, 0x60, 0x02, 0xe0, 0x20, 0x48, 0xc0, 0x46, 0x01, 0x64,
-0x1f, 0x48, 0xfb, 0xf7, 0x87, 0xfc, 0x1f, 0x48, 0xc1, 0x6b, 0xff, 0x29,
-0xfc, 0xd1, 0x81, 0x6b, 0x42, 0x6b, 0x16, 0x1c, 0x0f, 0x1c, 0x1c, 0x4c,
-0x10, 0x23, 0x60, 0x69, 0x18, 0x43, 0x60, 0x61, 0xa1, 0x69, 0x99, 0x43,
-0x1d, 0x04, 0xa1, 0x61, 0xe8, 0x60, 0xa0, 0x69, 0xc0, 0x46, 0x28, 0x61,
-0x16, 0x4a, 0x17, 0x49, 0x64, 0x20, 0xfb, 0xf7, 0x6f, 0xfc, 0x16, 0x4a,
-0xc0, 0x46, 0x00, 0x92, 0x15, 0x4b, 0x00, 0x20, 0x39, 0x1c, 0x32, 0x1c,
-0xfb, 0xf7, 0x6e, 0xfc, 0x13, 0x48, 0xc1, 0x68, 0x08, 0x29, 0xfc, 0xd1,
-0x12, 0x48, 0xfb, 0xf7, 0x5d, 0xfc, 0x10, 0x23, 0x60, 0x69, 0x98, 0x43,
-0x60, 0x61, 0xe8, 0x60, 0x01, 0x20, 0xe3, 0x23, 0x1b, 0x01, 0xe1, 0x18,
-0xc8, 0x71, 0xf8, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00, 0x10, 0x40,
-0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x02, 0xff, 0xff,
-0x00, 0x01, 0x18, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x20, 0x55, 0xff, 0xff,
-0xb5, 0xb6, 0x21, 0x40, 0x64, 0x00, 0x30, 0x02, 0x44, 0x80, 0x20, 0x40,
-0x40, 0x01, 0x18, 0x40, 0xf4, 0x01, 0xff, 0xff, 0x00, 0xb5, 0xfd, 0xf7,
-0x01, 0xff, 0x06, 0x48, 0xfb, 0xf7, 0x32, 0xfc, 0xfd, 0xf7, 0xd6, 0xfe,
-0xfe, 0xf7, 0x04, 0xf8, 0xfe, 0xf7, 0x16, 0xf8, 0xfe, 0xf7, 0x24, 0xf8,
-0x08, 0xbc, 0x18, 0x47, 0x91, 0x03, 0xff, 0xff, 0x90, 0xb5, 0xfd, 0xf7,
-0x6b, 0xfc, 0x34, 0x4f, 0x00, 0x24, 0xf9, 0x68, 0xf8, 0x1d, 0x79, 0x30,
-0x01, 0x29, 0x0f, 0xd1, 0x31, 0x49, 0xc0, 0x46, 0xf9, 0x67, 0x31, 0x49,
-0xc0, 0x46, 0x01, 0x60, 0x30, 0x49, 0xc0, 0x46, 0x0c, 0x60, 0x4c, 0x60,
-0x8c, 0x60, 0xcc, 0x60, 0x0c, 0x61, 0x4c, 0x61, 0x8c, 0x61, 0x04, 0xe0,
-0xf9, 0x1d, 0x7d, 0x31, 0xf9, 0x67, 0x12, 0xc0, 0x08, 0x38, 0x00, 0x68,
-0x60, 0x23, 0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0xf8, 0x6f, 0x20, 0x23,
-0x01, 0x68, 0x19, 0x43, 0x01, 0x60, 0xf8, 0x6f, 0x40, 0x23, 0x01, 0x68,
-0x99, 0x43, 0x01, 0x60, 0x00, 0xf0, 0x54, 0xf8, 0xfd, 0xf7, 0x4e, 0xfc,
-0x00, 0xf0, 0x5e, 0xf9, 0xfd, 0xf7, 0x73, 0xf8, 0xff, 0xf7, 0x0c, 0xfe,
-0xfd, 0xf7, 0x2e, 0xfe, 0xfd, 0xf7, 0xb6, 0xfd, 0xfd, 0xf7, 0xc2, 0xfe,
-0xfd, 0xf7, 0x54, 0xfd, 0xfd, 0xf7, 0x0a, 0xfd, 0xfd, 0xf7, 0x94, 0xfd,
-0x00, 0xf0, 0x1a, 0xfa, 0xfd, 0xf7, 0x9c, 0xff, 0xfd, 0xf7, 0x0a, 0xff,
-0xfd, 0xf7, 0xd2, 0xfe, 0xfd, 0xf7, 0x3c, 0xfc, 0xfb, 0xf7, 0xdc, 0xfa,
-0xff, 0xf7, 0x9c, 0xff, 0x71, 0x23, 0x5b, 0x01,
-0xf8, 0x18, 0x04, 0x72, 0x44, 0x72, 0x07, 0x23, 0x5b, 0x02, 0xf8, 0x18,
-0x04, 0x63, 0xf8, 0x68, 0x01, 0x28, 0x02, 0xd1, 0xa8, 0x20, 0xfe, 0xf7,
-0xb1, 0xfd, 0x09, 0x48, 0xc0, 0x46, 0x44, 0x62, 0x00, 0xf0, 0x18, 0xfa,
-0x07, 0x48, 0xfb, 0xf7, 0xbd, 0xfb, 0x90, 0xbc, 0x08, 0xbc, 0x18, 0x47,
-0x68, 0x0e, 0x00, 0x80, 0x00, 0x01, 0x11, 0x40, 0x04, 0x01, 0x11, 0x40,
-0x00, 0x01, 0x11, 0x00, 0xc0, 0x00, 0x18, 0x00, 0x15, 0x8f, 0x21, 0x40,
-0x00, 0xb5, 0x04, 0x48, 0xfb, 0xf7, 0xaa, 0xfb, 0xfd, 0xf7, 0x5e, 0xff,
-0xfd, 0xf7, 0x24, 0xfc, 0x08, 0xbc, 0x18, 0x47, 0x15, 0x99, 0x21, 0x40,
-0xfa, 0x21, 0x03, 0x48, 0xc0, 0x46, 0x41, 0x62, 0x40, 0x21, 0x41, 0x62,
-0x70, 0x47, 0x00, 0x00, 0xc0, 0x00, 0x18, 0x00, 0x07, 0x48, 0x41, 0x69,
-0x07, 0x4b, 0x19, 0x43, 0x41, 0x61, 0x82, 0x69, 0x9a, 0x43, 0x82, 0x61,
-0x01, 0x22, 0x12, 0x05, 0xd1, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x10, 0x61,
-0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80, 0xfe, 0xaf, 0x9a, 0x10,
-0x00, 0xb5, 0x02, 0x48, 0xfb, 0xf7, 0x80, 0xfb, 0x08, 0xbc, 0x18, 0x47,
-0xc8, 0x57, 0xff, 0xff, 0xf0, 0xb5, 0x24, 0x4c, 0x01, 0x21, 0x09, 0x04,
-0x20, 0x68, 0x01, 0x40, 0x09, 0x20, 0x22, 0x4e, 0x22, 0x4d, 0x00, 0x29,
-0x05, 0xd1, 0x21, 0x68, 0x09, 0x0c, 0x04, 0xd1, 0x21, 0x68, 0x89, 0x0a,
-0x01, 0xd3, 0xf0, 0x60, 0x00, 0xe0, 0x28, 0x64, 0x1d, 0x48, 0xfb, 0xf7,
-0x65, 0xfb, 0x1d, 0x4f, 0x1d, 0x49, 0x88, 0x69, 0x01, 0x30, 0x88, 0x61,
-0x38, 0x7a, 0x00, 0x28, 0x02, 0xd1, 0x78, 0x7a, 0x00, 0x28, 0x1f, 0xd0,
-0x19, 0x48, 0xfb, 0xf7, 0x57, 0xfb, 0x19, 0x48, 0xfb, 0xf7, 0x54, 0xfb,
-0x00, 0x28, 0xfa, 0xd1, 0x38, 0x7a, 0x00, 0x28, 0x02, 0xd0, 0x16, 0x48,
-0xfb, 0xf7, 0x4c, 0xfb, 0x01, 0x21, 0x09, 0x04, 0x20, 0x68, 0x01, 0x40,
-0x14, 0x20, 0x00, 0x29, 0x05, 0xd1, 0x21, 0x68, 0x09, 0x0c, 0x04, 0xd1,
-0x21, 0x68, 0x89, 0x0a, 0x01, 0xd3, 0xf0, 0x60, 0x01, 0xe0, 0x28, 0x64,
-0xff, 0xe7, 0xfe, 0xe7, 0xff, 0xf7, 0x65, 0xfd, 0x0b, 0x48, 0xfb, 0xf7,
-0x35, 0xfb, 0xff, 0xf7, 0xaf, 0xff, 0xcd, 0xe7, 0x00, 0x00, 0x10, 0x40,
-0x40, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x02, 0xff, 0xff,
-0x88, 0x1c, 0x00, 0x80, 0x08, 0x83, 0x20, 0x40, 0xf4, 0x01, 0xff, 0xff,
-0xb5, 0x07, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x99, 0x9f, 0x21, 0x40,
-0x00, 0x20, 0x07, 0x4a, 0x01, 0x21, 0x09, 0x05, 0x50, 0x61, 0xc8, 0x60,
-0xd0, 0x61, 0xc8, 0x61, 0x03, 0x23, 0xdb, 0x04, 0x03, 0x4a, 0x01, 0x21,
-0xd1, 0x63, 0x58, 0x60, 0xfc, 0xe7, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0xc0, 0x00, 0x18, 0x00, 0x80, 0xb5, 0xc0, 0xb0, 0x01, 0x22, 0x00, 0x21,
-0x0a, 0x20, 0xfc, 0xf7, 0xd1, 0xff, 0x07, 0x1c, 0xff, 0x2f, 0x28, 0xd0,
-0x69, 0x46, 0xff, 0x22, 0x38, 0x1c, 0x01, 0x32, 0xfd, 0xf7, 0x54, 0xf9,
-0xff, 0x23, 0x01, 0x33, 0x98, 0x42, 0x1b, 0xd1, 0x0d, 0x98, 0x00, 0x09,
-0x18, 0xd3, 0x38, 0x1c, 0xfd, 0xf7, 0x8d, 0xf8, 0x0e, 0x49, 0x01, 0x22,
-0x12, 0x04, 0x08, 0x68, 0x02, 0x40, 0x0d, 0x48, 0x05, 0xd1, 0x0a, 0x68,
-0x12, 0x0c, 0x06, 0xd1, 0x09, 0x68, 0x89, 0x0a, 0x03, 0xd3, 0x0a, 0x49,
-0xc0, 0x46, 0xc8, 0x60, 0x02, 0xe0, 0x09, 0x49, 0xc0, 0x46, 0x08, 0x64,
-0xff, 0xf7, 0xbc, 0xff, 0x38, 0x1c, 0xfd, 0xf7, 0x74, 0xf8, 0x40, 0xb0,
-0x80, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x40, 0x07, 0x80, 0x00, 0x00, 0x40, 0x01, 0x18, 0x00,
-0x00, 0x00, 0x00, 0x80, 0x00, 0xb5, 0x17, 0x49, 0x01, 0x22, 0x12, 0x04,
-0x08, 0x68, 0x02, 0x40, 0x06, 0x20, 0x00, 0x2a, 0x05, 0xd1, 0x0a, 0x68,
-0x12, 0x0c, 0x06, 0xd1, 0x09, 0x68, 0x89, 0x0a, 0x03, 0xd3, 0x11, 0x49,
-0xc0, 0x46, 0xc8, 0x60, 0x02, 0xe0, 0x10, 0x49, 0xc0, 0x46, 0x08, 0x64,
-0x03, 0x20, 0xfe, 0xf7, 0xd3, 0xfc, 0xfb, 0xf7, 0x0d, 0xff, 0x01, 0x23,
-0x18, 0x43, 0xfb, 0xf7, 0xe7, 0xff, 0xff, 0xf7, 0x83, 0xfe, 0xff, 0xf7,
-0x9d, 0xff, 0xff, 0xf7, 0x05, 0xfe, 0xff, 0xf7, 0xf5, 0xfe, 0xff, 0xf7,
-0x09, 0xff, 0xff, 0xf7, 0x9b, 0xfd, 0xff, 0xf7, 0x21, 0xff, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x40, 0x01, 0x18, 0x00,
-0x00, 0x00, 0x00, 0x80, 0xf0, 0xb4, 0x46, 0x4a, 0x01, 0x21, 0xc9, 0x03,
-0x45, 0x4d, 0x19, 0x23, 0xdb, 0x01, 0xec, 0x18, 0xa1, 0x61, 0x28, 0x88,
-0x40, 0x04, 0x43, 0x4b, 0xc0, 0x18, 0x87, 0x1a, 0x04, 0x20, 0xaf, 0x60,
-0x41, 0x4e, 0xc0, 0x46, 0xb0, 0x61, 0x08, 0x20, 0xc8, 0x23, 0x43, 0x43,
-0xbb, 0x42, 0x21, 0xd9, 0x41, 0x00, 0x3d, 0x4e, 0xc0, 0x46, 0x31, 0x61,
-0xb6, 0x69, 0x20, 0x23, 0x9b, 0x1b, 0x3a, 0x4e, 0xc0, 0x46, 0xf3, 0x61,
-0x10, 0x3b, 0x33, 0x62, 0x8b, 0x00, 0xff, 0x1a, 0x40, 0x08, 0x81, 0x42,
-0x17, 0xd3, 0xb8, 0x23, 0x43, 0x43, 0xbb, 0x42, 0x08, 0xd9, 0x41, 0x1e,
-0x32, 0x4b, 0xc0, 0x46, 0x99, 0x81, 0xd9, 0x81, 0x40, 0x00, 0x02, 0x38,
-0x58, 0x61, 0x0a, 0xe0, 0x01, 0x30, 0x81, 0x42, 0xef, 0xd2, 0x06, 0xe0,
-0x2c, 0x4e, 0xb3, 0x69, 0x01, 0x33, 0xb3, 0x61, 0x40, 0x00, 0x88, 0x42,
-0xd2, 0xd9, 0x2a, 0x49, 0x00, 0x20, 0xa3, 0x69, 0x9b, 0x08, 0x07, 0xd0,
-0x28, 0x4b, 0x87, 0x00, 0xcb, 0x51, 0xa7, 0x69, 0xbf, 0x08, 0x01, 0x30,
-0x87, 0x42, 0xf8, 0xd8, 0x22, 0x49, 0xc0, 0x46, 0x8a, 0x62, 0x8c, 0x89,
-0x58, 0x20, 0x60, 0x43, 0x87, 0x18, 0x00, 0x20, 0x00, 0x22, 0x00, 0x2c,
-0x0a, 0xdd, 0x58, 0x23, 0x43, 0x43, 0x8c, 0x6a, 0xe3, 0x18, 0x01, 0x30,
-0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60, 0x8b, 0x89, 0x83, 0x42, 0xf4, 0xdc,
-0xcf, 0x62, 0xcc, 0x89, 0x60, 0x00, 0x00, 0x19, 0x40, 0x01, 0xc7, 0x19,
-0x00, 0x20, 0x00, 0x2c, 0x0b, 0xdd, 0x43, 0x00, 0x1b, 0x18, 0x5b, 0x01,
-0xcc, 0x6a, 0xe3, 0x18, 0x01, 0x30, 0x00, 0x04, 0x00, 0x0c, 0x9a, 0x60,
-0xcb, 0x89, 0x83, 0x42, 0xf3, 0xdc, 0x4f, 0x62, 0x00, 0x20, 0x0b, 0x69,
-0x00, 0x2b, 0x07, 0xd9, 0x87, 0x00, 0x4b, 0x6a, 0xc0, 0x46, 0xda, 0x51,
-0x0b, 0x69, 0x01, 0x30, 0x83, 0x42, 0xf7, 0xd8, 0x49, 0x6a, 0x80, 0x00,
-0x08, 0x18, 0x04, 0x38, 0x28, 0x61, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00,
-0xb0, 0xbe, 0x21, 0x40, 0x68, 0x0e, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40,
-0x4c, 0x2a, 0x00, 0x80, 0x00, 0x00, 0x20, 0x40, 0x00, 0xad, 0xde, 0x00,
-0x0a, 0x48, 0x01, 0x23, 0x1b, 0x06, 0x41, 0x69, 0x99, 0x43, 0x1a, 0x09,
-0x41, 0x61, 0xd1, 0x60, 0x00, 0x21, 0xa1, 0x22, 0x52, 0x03, 0x91, 0x61,
-0x1b, 0x23, 0xdb, 0x01, 0xc0, 0x18, 0x81, 0x61, 0x01, 0x20, 0x00, 0x06,
-0x59, 0x05, 0x08, 0x60, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x80, 0xb4, 0x02, 0x1c, 0x0b, 0x48, 0x1b, 0x23, 0xdb, 0x01, 0xc3, 0x18,
-0x9a, 0x61, 0x01, 0x23, 0x1b, 0x06, 0x42, 0x69, 0x1a, 0x43, 0x42, 0x61,
-0x87, 0x69, 0x9f, 0x43, 0x01, 0x23, 0x1b, 0x05,
-0x87, 0x61, 0xda, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x18, 0x61, 0xa1, 0x20,
-0x40, 0x03, 0x81, 0x61, 0x80, 0xbc, 0x70, 0x47, 0x68, 0x0e, 0x00, 0x80,
-0x80, 0xb5, 0xff, 0xf7, 0xc9, 0xff, 0x00, 0x20, 0x00, 0xf0, 0x20, 0xf8,
-0x00, 0x20, 0x09, 0x49, 0x00, 0x22, 0x03, 0x01, 0x5f, 0x18, 0x33, 0x23,
-0x9b, 0x01, 0xfb, 0x18, 0x9a, 0x62, 0x01, 0x30, 0x0b, 0x28, 0xf6, 0xd3,
-0x04, 0x48, 0x01, 0x22, 0x00, 0x21, 0x00, 0xf0, 0x33, 0xf8, 0x80, 0xbc,
-0x08, 0xbc, 0x18, 0x47, 0x68, 0x0e, 0x00, 0x80, 0x1d, 0x3e, 0xff, 0xff,
-0x00, 0xb5, 0x02, 0x48, 0x00, 0xf0, 0x04, 0xf8, 0x08, 0xbc, 0x18, 0x47,
-0xa8, 0x61, 0x00, 0x00, 0x80, 0xb4, 0x01, 0x22, 0x12, 0x05, 0x0f, 0x4b,
-0xa1, 0x21, 0x49, 0x03, 0x00, 0x28, 0x0e, 0xd0, 0xc8, 0x61, 0x18, 0x1c,
-0x59, 0x69, 0x53, 0x01, 0x19, 0x43, 0x41, 0x61, 0x87, 0x69, 0x9f, 0x43,
-0x87, 0x61, 0xd1, 0x60, 0x80, 0x69, 0xc0, 0x46, 0x10, 0x61, 0x80, 0xbc,
-0x70, 0x47, 0x18, 0x1c, 0x5f, 0x69, 0x01, 0x23, 0x5b, 0x06, 0x9f, 0x43,
-0x47, 0x61, 0xd7, 0x60, 0x00, 0x20, 0xc8, 0x61, 0xf3, 0xe7, 0x00, 0x00,
-0x68, 0x0e, 0x00, 0x80, 0xb0, 0xb4, 0x07, 0x1c, 0x00, 0x20, 0x17, 0x4c,
-0x03, 0x01, 0x1d, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x9d, 0x6a,
-0xbd, 0x42, 0x05, 0xd1, 0x1d, 0x6b, 0x95, 0x42, 0x02, 0xd1, 0xdb, 0x6a,
-0x8b, 0x42, 0x1c, 0xd0, 0x01, 0x30, 0x0b, 0x28, 0xee, 0xd3, 0x00, 0x20,
-0x03, 0x01, 0x1d, 0x19, 0x33, 0x23, 0x9b, 0x01, 0xeb, 0x18, 0x9b, 0x6a,
-0x00, 0x2b, 0x09, 0xd1, 0x03, 0x01, 0x1c, 0x19, 0x33, 0x23, 0x9b, 0x01,
-0xe3, 0x18, 0x1a, 0x63, 0xd9, 0x62, 0x5a, 0x63, 0x9f, 0x62, 0x02, 0xe0,
-0x01, 0x30, 0x0b, 0x28, 0xea, 0xd3, 0x0b, 0x28, 0x01, 0xd1, 0x00, 0x20,
-0xc0, 0x43, 0xb0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x68, 0x0e, 0x00, 0x80,
-0x90, 0xb4, 0x01, 0x1c, 0x00, 0x22, 0x01, 0x20, 0x16, 0x4f, 0x01, 0xe0,
-0x00, 0x2a, 0x07, 0xd1, 0x03, 0x01, 0xdc, 0x19, 0x33, 0x23, 0x9b, 0x01,
-0xe3, 0x18, 0x9b, 0x69, 0x8b, 0x42, 0x11, 0xd1, 0x02, 0x01, 0xd2, 0x19,
-0x33, 0x23, 0x9b, 0x01, 0xd2, 0x18, 0x93, 0x6a, 0xc0, 0x46, 0x93, 0x61,
-0xd3, 0x6a, 0xc0, 0x46, 0xd3, 0x61, 0x13, 0x6b, 0xc0, 0x46, 0x13, 0x62,
-0x53, 0x6b, 0xc0, 0x46, 0x53, 0x62, 0x01, 0x22, 0x01, 0x30, 0x0b, 0x28,
-0xe0, 0xd3, 0x07, 0x4b, 0x00, 0x2a, 0x02, 0xd1, 0x9a, 0x68, 0x8a, 0x42,
-0x03, 0xd1, 0x00, 0x21, 0x99, 0x60, 0x90, 0xbc, 0x70, 0x47, 0x00, 0x20,
-0xc0, 0x43, 0xfa, 0xe7, 0x68, 0x0e, 0x00, 0x80, 0xe8, 0x1b, 0x00, 0x80,
-0x0b, 0x28, 0x17, 0xda, 0x0c, 0x49, 0x01, 0x23, 0x5b, 0x06, 0x8a, 0x69,
-0x13, 0x43, 0x01, 0x22, 0x12, 0x05, 0x8b, 0x61, 0x13, 0x61, 0x00, 0x01,
-0x40, 0x18, 0x33, 0x23, 0x9b, 0x01, 0xc0, 0x18, 0x03, 0x6b, 0xc0, 0x46,
-0x43, 0x63, 0x53, 0x01, 0x88, 0x69, 0x98, 0x43, 0x88, 0x61, 0x10, 0x61,
-0x01, 0x20, 0x70, 0x47, 0x00, 0x20, 0xfc, 0xe7, 0x68, 0x0e, 0x00, 0x80,
-0x90, 0xb4, 0x08, 0x4a, 0xd0, 0x69, 0x00, 0x21, 0x07, 0x4f, 0xd3, 0x69,
-0x83, 0x42, 0x02, 0xd9, 0xfc, 0x1a, 0x20, 0x18, 0x00, 0xe0, 0xc0, 0x1a,
-0x09, 0x18, 0x18, 0x1c, 0xb9, 0x42, 0xf4, 0xd9, 0x90, 0xbc, 0x70, 0x47,
-0x00, 0x20, 0x14, 0x40, 0xa8, 0x61, 0x00, 0x00, 0x90, 0xb5, 0x07, 0x1c,
-0x00, 0x24, 0x00, 0x2f, 0x04, 0xd3, 0xff, 0xf7, 0xe3, 0xff, 0x01, 0x34,
-0xbc, 0x42, 0xfa, 0xd9, 0x90, 0xbc, 0x08, 0xbc,
-0x18, 0x47, 0x00, 0x00,
-};
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 3af9a9516ccb..9dd4f76a2ff5 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -100,10 +100,11 @@ static const int multicast_filter_limit = 32;
#define PKT_BUF_SZ 1536
#define DRV_MODULE_NAME "typhoon"
-#define DRV_MODULE_VERSION "1.5.8"
-#define DRV_MODULE_RELDATE "06/11/09"
+#define DRV_MODULE_VERSION "1.5.9"
+#define DRV_MODULE_RELDATE "Mar 2, 2009"
#define PFX DRV_MODULE_NAME ": "
#define ERR_PFX KERN_ERR PFX
+#define FIRMWARE_NAME "3com/typhoon.bin"
#include <linux/module.h>
#include <linux/kernel.h>
@@ -129,9 +130,9 @@ static const int multicast_filter_limit = 32;
#include <asm/uaccess.h>
#include <linux/in6.h>
#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
#include "typhoon.h"
-#include "typhoon-firmware.h"
static char version[] __devinitdata =
"typhoon.c: version " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
@@ -139,6 +140,7 @@ static char version[] __devinitdata =
MODULE_AUTHOR("David Dillow <dave@thedillows.org>");
MODULE_VERSION(DRV_MODULE_VERSION);
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FIRMWARE_NAME);
MODULE_DESCRIPTION("3Com Typhoon Family (3C990, 3CR990, and variants)");
MODULE_PARM_DESC(rx_copybreak, "Packets smaller than this are copied and "
"the buffer given back to the NIC. Default "
@@ -1344,14 +1346,74 @@ typhoon_init_rings(struct typhoon *tp)
tp->txHiRing.lastRead = 0;
}
+static const struct firmware *typhoon_fw;
+
+static int
+typhoon_request_firmware(struct typhoon *tp)
+{
+ const struct typhoon_file_header *fHdr;
+ const struct typhoon_section_header *sHdr;
+ const u8 *image_data;
+ u32 numSections;
+ u32 section_len;
+ u32 remaining;
+ int err;
+
+ if (typhoon_fw)
+ return 0;
+
+ err = request_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev);
+ if (err) {
+ printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
+ tp->name, FIRMWARE_NAME);
+ return err;
+ }
+
+ image_data = (u8 *) typhoon_fw->data;
+ remaining = typhoon_fw->size;
+ if (remaining < sizeof(struct typhoon_file_header))
+ goto invalid_fw;
+
+ fHdr = (struct typhoon_file_header *) image_data;
+ if (memcmp(fHdr->tag, "TYPHOON", 8))
+ goto invalid_fw;
+
+ numSections = le32_to_cpu(fHdr->numSections);
+ image_data += sizeof(struct typhoon_file_header);
+ remaining -= sizeof(struct typhoon_file_header);
+
+ while (numSections--) {
+ if (remaining < sizeof(struct typhoon_section_header))
+ goto invalid_fw;
+
+ sHdr = (struct typhoon_section_header *) image_data;
+ image_data += sizeof(struct typhoon_section_header);
+ section_len = le32_to_cpu(sHdr->len);
+
+ if (remaining < section_len)
+ goto invalid_fw;
+
+ image_data += section_len;
+ remaining -= section_len;
+ }
+
+ return 0;
+
+invalid_fw:
+ printk(KERN_ERR "%s: Invalid firmware image\n", tp->name);
+ release_firmware(typhoon_fw);
+ typhoon_fw = NULL;
+ return -EINVAL;
+}
+
static int
typhoon_download_firmware(struct typhoon *tp)
{
void __iomem *ioaddr = tp->ioaddr;
struct pci_dev *pdev = tp->pdev;
- struct typhoon_file_header *fHdr;
- struct typhoon_section_header *sHdr;
- u8 *image_data;
+ const struct typhoon_file_header *fHdr;
+ const struct typhoon_section_header *sHdr;
+ const u8 *image_data;
void *dpage;
dma_addr_t dpage_dma;
__sum16 csum;
@@ -1365,20 +1427,12 @@ typhoon_download_firmware(struct typhoon *tp)
int i;
int err;
- err = -EINVAL;
- fHdr = (struct typhoon_file_header *) typhoon_firmware_image;
- image_data = (u8 *) fHdr;
-
- if(memcmp(fHdr->tag, "TYPHOON", 8)) {
- printk(KERN_ERR "%s: Invalid firmware image!\n", tp->name);
- goto err_out;
- }
+ image_data = (u8 *) typhoon_fw->data;
+ fHdr = (struct typhoon_file_header *) image_data;
/* Cannot just map the firmware image using pci_map_single() as
- * the firmware is part of the kernel/module image, so we allocate
- * some consistent memory to copy the sections into, as it is simpler,
- * and short-lived. If we ever split out and require a userland
- * firmware loader, then we can revisit this.
+ * the firmware is vmalloc()'d and may not be physically contiguous,
+ * so we allocate some consistent memory to copy the sections into.
*/
err = -ENOMEM;
dpage = pci_alloc_consistent(pdev, PAGE_SIZE, &dpage_dma);
@@ -1783,7 +1837,7 @@ typhoon_poll(struct napi_struct *napi, int budget)
}
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
iowrite32(TYPHOON_INTR_NONE,
tp->ioaddr + TYPHOON_REG_INTR_MASK);
typhoon_post_pci_writes(tp->ioaddr);
@@ -1806,10 +1860,10 @@ typhoon_interrupt(int irq, void *dev_instance)
iowrite32(intr_status, ioaddr + TYPHOON_REG_INTR_STATUS);
- if (netif_rx_schedule_prep(&tp->napi)) {
+ if (napi_schedule_prep(&tp->napi)) {
iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
typhoon_post_pci_writes(ioaddr);
- __netif_rx_schedule(&tp->napi);
+ __napi_schedule(&tp->napi);
} else {
printk(KERN_ERR "%s: Error, poll already scheduled\n",
dev->name);
@@ -1944,7 +1998,7 @@ typhoon_start_runtime(struct typhoon *tp)
goto error_out;
INIT_COMMAND_NO_RESPONSE(&xp_cmd, TYPHOON_CMD_VLAN_TYPE_WRITE);
- xp_cmd.parm1 = __constant_cpu_to_le16(ETH_P_8021Q);
+ xp_cmd.parm1 = cpu_to_le16(ETH_P_8021Q);
err = typhoon_issue_command(tp, 1, &xp_cmd, 0, NULL);
if(err < 0)
goto error_out;
@@ -2086,6 +2140,10 @@ typhoon_open(struct net_device *dev)
struct typhoon *tp = netdev_priv(dev);
int err;
+ err = typhoon_request_firmware(tp);
+ if (err)
+ goto out;
+
err = typhoon_wakeup(tp, WaitSleep);
if(err < 0) {
printk(KERN_ERR "%s: unable to wakeup device\n", dev->name);
@@ -2624,6 +2682,8 @@ typhoon_init(void)
static void __exit
typhoon_cleanup(void)
{
+ if (typhoon_fw)
+ release_firmware(typhoon_fw);
pci_unregister_driver(&typhoon_driver);
}
diff --git a/drivers/net/typhoon.h b/drivers/net/typhoon.h
index dd7022ca7354..673fd5125914 100644
--- a/drivers/net/typhoon.h
+++ b/drivers/net/typhoon.h
@@ -174,18 +174,18 @@ struct tx_desc {
u64 tx_addr; /* opaque for hardware, for TX_DESC */
};
__le32 processFlags;
-#define TYPHOON_TX_PF_NO_CRC __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_TX_PF_IP_CHKSUM __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_TX_PF_TCP_CHKSUM __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_TX_PF_TCP_SEGMENT __constant_cpu_to_le32(0x00000008)
-#define TYPHOON_TX_PF_INSERT_VLAN __constant_cpu_to_le32(0x00000010)
-#define TYPHOON_TX_PF_IPSEC __constant_cpu_to_le32(0x00000020)
-#define TYPHOON_TX_PF_VLAN_PRIORITY __constant_cpu_to_le32(0x00000040)
-#define TYPHOON_TX_PF_UDP_CHKSUM __constant_cpu_to_le32(0x00000080)
-#define TYPHOON_TX_PF_PAD_FRAME __constant_cpu_to_le32(0x00000100)
-#define TYPHOON_TX_PF_RESERVED __constant_cpu_to_le32(0x00000e00)
-#define TYPHOON_TX_PF_VLAN_MASK __constant_cpu_to_le32(0x0ffff000)
-#define TYPHOON_TX_PF_INTERNAL __constant_cpu_to_le32(0xf0000000)
+#define TYPHOON_TX_PF_NO_CRC cpu_to_le32(0x00000001)
+#define TYPHOON_TX_PF_IP_CHKSUM cpu_to_le32(0x00000002)
+#define TYPHOON_TX_PF_TCP_CHKSUM cpu_to_le32(0x00000004)
+#define TYPHOON_TX_PF_TCP_SEGMENT cpu_to_le32(0x00000008)
+#define TYPHOON_TX_PF_INSERT_VLAN cpu_to_le32(0x00000010)
+#define TYPHOON_TX_PF_IPSEC cpu_to_le32(0x00000020)
+#define TYPHOON_TX_PF_VLAN_PRIORITY cpu_to_le32(0x00000040)
+#define TYPHOON_TX_PF_UDP_CHKSUM cpu_to_le32(0x00000080)
+#define TYPHOON_TX_PF_PAD_FRAME cpu_to_le32(0x00000100)
+#define TYPHOON_TX_PF_RESERVED cpu_to_le32(0x00000e00)
+#define TYPHOON_TX_PF_VLAN_MASK cpu_to_le32(0x0ffff000)
+#define TYPHOON_TX_PF_INTERNAL cpu_to_le32(0xf0000000)
#define TYPHOON_TX_PF_VLAN_TAG_SHIFT 12
} __attribute__ ((packed));
@@ -203,8 +203,8 @@ struct tcpopt_desc {
u8 flags;
u8 numDesc;
__le16 mss_flags;
-#define TYPHOON_TSO_FIRST __constant_cpu_to_le16(0x1000)
-#define TYPHOON_TSO_LAST __constant_cpu_to_le16(0x2000)
+#define TYPHOON_TSO_FIRST cpu_to_le16(0x1000)
+#define TYPHOON_TSO_LAST cpu_to_le16(0x2000)
__le32 respAddrLo;
__le32 bytesTx;
__le32 status;
@@ -222,8 +222,8 @@ struct ipsec_desc {
u8 flags;
u8 numDesc;
__le16 ipsecFlags;
-#define TYPHOON_IPSEC_GEN_IV __constant_cpu_to_le16(0x0000)
-#define TYPHOON_IPSEC_USE_IV __constant_cpu_to_le16(0x0001)
+#define TYPHOON_IPSEC_GEN_IV cpu_to_le16(0x0000)
+#define TYPHOON_IPSEC_USE_IV cpu_to_le16(0x0001)
__le32 sa1;
__le32 sa2;
__le32 reserved;
@@ -248,41 +248,41 @@ struct rx_desc {
u32 addr; /* opaque, comes from virtAddr */
u32 addrHi; /* opaque, comes from virtAddrHi */
__le32 rxStatus;
-#define TYPHOON_RX_ERR_INTERNAL __constant_cpu_to_le32(0x00000000)
-#define TYPHOON_RX_ERR_FIFO_UNDERRUN __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_RX_ERR_BAD_SSD __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_RX_ERR_RUNT __constant_cpu_to_le32(0x00000003)
-#define TYPHOON_RX_ERR_CRC __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_RX_ERR_OVERSIZE __constant_cpu_to_le32(0x00000005)
-#define TYPHOON_RX_ERR_ALIGN __constant_cpu_to_le32(0x00000006)
-#define TYPHOON_RX_ERR_DRIBBLE __constant_cpu_to_le32(0x00000007)
-#define TYPHOON_RX_PROTO_MASK __constant_cpu_to_le32(0x00000003)
-#define TYPHOON_RX_PROTO_UNKNOWN __constant_cpu_to_le32(0x00000000)
-#define TYPHOON_RX_PROTO_IP __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_RX_PROTO_IPX __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_RX_VLAN __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_RX_IP_FRAG __constant_cpu_to_le32(0x00000008)
-#define TYPHOON_RX_IPSEC __constant_cpu_to_le32(0x00000010)
-#define TYPHOON_RX_IP_CHK_FAIL __constant_cpu_to_le32(0x00000020)
-#define TYPHOON_RX_TCP_CHK_FAIL __constant_cpu_to_le32(0x00000040)
-#define TYPHOON_RX_UDP_CHK_FAIL __constant_cpu_to_le32(0x00000080)
-#define TYPHOON_RX_IP_CHK_GOOD __constant_cpu_to_le32(0x00000100)
-#define TYPHOON_RX_TCP_CHK_GOOD __constant_cpu_to_le32(0x00000200)
-#define TYPHOON_RX_UDP_CHK_GOOD __constant_cpu_to_le32(0x00000400)
+#define TYPHOON_RX_ERR_INTERNAL cpu_to_le32(0x00000000)
+#define TYPHOON_RX_ERR_FIFO_UNDERRUN cpu_to_le32(0x00000001)
+#define TYPHOON_RX_ERR_BAD_SSD cpu_to_le32(0x00000002)
+#define TYPHOON_RX_ERR_RUNT cpu_to_le32(0x00000003)
+#define TYPHOON_RX_ERR_CRC cpu_to_le32(0x00000004)
+#define TYPHOON_RX_ERR_OVERSIZE cpu_to_le32(0x00000005)
+#define TYPHOON_RX_ERR_ALIGN cpu_to_le32(0x00000006)
+#define TYPHOON_RX_ERR_DRIBBLE cpu_to_le32(0x00000007)
+#define TYPHOON_RX_PROTO_MASK cpu_to_le32(0x00000003)
+#define TYPHOON_RX_PROTO_UNKNOWN cpu_to_le32(0x00000000)
+#define TYPHOON_RX_PROTO_IP cpu_to_le32(0x00000001)
+#define TYPHOON_RX_PROTO_IPX cpu_to_le32(0x00000002)
+#define TYPHOON_RX_VLAN cpu_to_le32(0x00000004)
+#define TYPHOON_RX_IP_FRAG cpu_to_le32(0x00000008)
+#define TYPHOON_RX_IPSEC cpu_to_le32(0x00000010)
+#define TYPHOON_RX_IP_CHK_FAIL cpu_to_le32(0x00000020)
+#define TYPHOON_RX_TCP_CHK_FAIL cpu_to_le32(0x00000040)
+#define TYPHOON_RX_UDP_CHK_FAIL cpu_to_le32(0x00000080)
+#define TYPHOON_RX_IP_CHK_GOOD cpu_to_le32(0x00000100)
+#define TYPHOON_RX_TCP_CHK_GOOD cpu_to_le32(0x00000200)
+#define TYPHOON_RX_UDP_CHK_GOOD cpu_to_le32(0x00000400)
__le16 filterResults;
-#define TYPHOON_RX_FILTER_MASK __constant_cpu_to_le16(0x7fff)
-#define TYPHOON_RX_FILTERED __constant_cpu_to_le16(0x8000)
+#define TYPHOON_RX_FILTER_MASK cpu_to_le16(0x7fff)
+#define TYPHOON_RX_FILTERED cpu_to_le16(0x8000)
__le16 ipsecResults;
-#define TYPHOON_RX_OUTER_AH_GOOD __constant_cpu_to_le16(0x0001)
-#define TYPHOON_RX_OUTER_ESP_GOOD __constant_cpu_to_le16(0x0002)
-#define TYPHOON_RX_INNER_AH_GOOD __constant_cpu_to_le16(0x0004)
-#define TYPHOON_RX_INNER_ESP_GOOD __constant_cpu_to_le16(0x0008)
-#define TYPHOON_RX_OUTER_AH_FAIL __constant_cpu_to_le16(0x0010)
-#define TYPHOON_RX_OUTER_ESP_FAIL __constant_cpu_to_le16(0x0020)
-#define TYPHOON_RX_INNER_AH_FAIL __constant_cpu_to_le16(0x0040)
-#define TYPHOON_RX_INNER_ESP_FAIL __constant_cpu_to_le16(0x0080)
-#define TYPHOON_RX_UNKNOWN_SA __constant_cpu_to_le16(0x0100)
-#define TYPHOON_RX_ESP_FORMAT_ERR __constant_cpu_to_le16(0x0200)
+#define TYPHOON_RX_OUTER_AH_GOOD cpu_to_le16(0x0001)
+#define TYPHOON_RX_OUTER_ESP_GOOD cpu_to_le16(0x0002)
+#define TYPHOON_RX_INNER_AH_GOOD cpu_to_le16(0x0004)
+#define TYPHOON_RX_INNER_ESP_GOOD cpu_to_le16(0x0008)
+#define TYPHOON_RX_OUTER_AH_FAIL cpu_to_le16(0x0010)
+#define TYPHOON_RX_OUTER_ESP_FAIL cpu_to_le16(0x0020)
+#define TYPHOON_RX_INNER_AH_FAIL cpu_to_le16(0x0040)
+#define TYPHOON_RX_INNER_ESP_FAIL cpu_to_le16(0x0080)
+#define TYPHOON_RX_UNKNOWN_SA cpu_to_le16(0x0100)
+#define TYPHOON_RX_ESP_FORMAT_ERR cpu_to_le16(0x0200)
__be32 vlanTag;
} __attribute__ ((packed));
@@ -318,31 +318,31 @@ struct cmd_desc {
u8 flags;
u8 numDesc;
__le16 cmd;
-#define TYPHOON_CMD_TX_ENABLE __constant_cpu_to_le16(0x0001)
-#define TYPHOON_CMD_TX_DISABLE __constant_cpu_to_le16(0x0002)
-#define TYPHOON_CMD_RX_ENABLE __constant_cpu_to_le16(0x0003)
-#define TYPHOON_CMD_RX_DISABLE __constant_cpu_to_le16(0x0004)
-#define TYPHOON_CMD_SET_RX_FILTER __constant_cpu_to_le16(0x0005)
-#define TYPHOON_CMD_READ_STATS __constant_cpu_to_le16(0x0007)
-#define TYPHOON_CMD_XCVR_SELECT __constant_cpu_to_le16(0x0013)
-#define TYPHOON_CMD_SET_MAX_PKT_SIZE __constant_cpu_to_le16(0x001a)
-#define TYPHOON_CMD_READ_MEDIA_STATUS __constant_cpu_to_le16(0x001b)
-#define TYPHOON_CMD_GOTO_SLEEP __constant_cpu_to_le16(0x0023)
-#define TYPHOON_CMD_SET_MULTICAST_HASH __constant_cpu_to_le16(0x0025)
-#define TYPHOON_CMD_SET_MAC_ADDRESS __constant_cpu_to_le16(0x0026)
-#define TYPHOON_CMD_READ_MAC_ADDRESS __constant_cpu_to_le16(0x0027)
-#define TYPHOON_CMD_VLAN_TYPE_WRITE __constant_cpu_to_le16(0x002b)
-#define TYPHOON_CMD_CREATE_SA __constant_cpu_to_le16(0x0034)
-#define TYPHOON_CMD_DELETE_SA __constant_cpu_to_le16(0x0035)
-#define TYPHOON_CMD_READ_VERSIONS __constant_cpu_to_le16(0x0043)
-#define TYPHOON_CMD_IRQ_COALESCE_CTRL __constant_cpu_to_le16(0x0045)
-#define TYPHOON_CMD_ENABLE_WAKE_EVENTS __constant_cpu_to_le16(0x0049)
-#define TYPHOON_CMD_SET_OFFLOAD_TASKS __constant_cpu_to_le16(0x004f)
-#define TYPHOON_CMD_HELLO_RESP __constant_cpu_to_le16(0x0057)
-#define TYPHOON_CMD_HALT __constant_cpu_to_le16(0x005d)
-#define TYPHOON_CMD_READ_IPSEC_INFO __constant_cpu_to_le16(0x005e)
-#define TYPHOON_CMD_GET_IPSEC_ENABLE __constant_cpu_to_le16(0x0067)
-#define TYPHOON_CMD_GET_CMD_LVL __constant_cpu_to_le16(0x0069)
+#define TYPHOON_CMD_TX_ENABLE cpu_to_le16(0x0001)
+#define TYPHOON_CMD_TX_DISABLE cpu_to_le16(0x0002)
+#define TYPHOON_CMD_RX_ENABLE cpu_to_le16(0x0003)
+#define TYPHOON_CMD_RX_DISABLE cpu_to_le16(0x0004)
+#define TYPHOON_CMD_SET_RX_FILTER cpu_to_le16(0x0005)
+#define TYPHOON_CMD_READ_STATS cpu_to_le16(0x0007)
+#define TYPHOON_CMD_XCVR_SELECT cpu_to_le16(0x0013)
+#define TYPHOON_CMD_SET_MAX_PKT_SIZE cpu_to_le16(0x001a)
+#define TYPHOON_CMD_READ_MEDIA_STATUS cpu_to_le16(0x001b)
+#define TYPHOON_CMD_GOTO_SLEEP cpu_to_le16(0x0023)
+#define TYPHOON_CMD_SET_MULTICAST_HASH cpu_to_le16(0x0025)
+#define TYPHOON_CMD_SET_MAC_ADDRESS cpu_to_le16(0x0026)
+#define TYPHOON_CMD_READ_MAC_ADDRESS cpu_to_le16(0x0027)
+#define TYPHOON_CMD_VLAN_TYPE_WRITE cpu_to_le16(0x002b)
+#define TYPHOON_CMD_CREATE_SA cpu_to_le16(0x0034)
+#define TYPHOON_CMD_DELETE_SA cpu_to_le16(0x0035)
+#define TYPHOON_CMD_READ_VERSIONS cpu_to_le16(0x0043)
+#define TYPHOON_CMD_IRQ_COALESCE_CTRL cpu_to_le16(0x0045)
+#define TYPHOON_CMD_ENABLE_WAKE_EVENTS cpu_to_le16(0x0049)
+#define TYPHOON_CMD_SET_OFFLOAD_TASKS cpu_to_le16(0x004f)
+#define TYPHOON_CMD_HELLO_RESP cpu_to_le16(0x0057)
+#define TYPHOON_CMD_HALT cpu_to_le16(0x005d)
+#define TYPHOON_CMD_READ_IPSEC_INFO cpu_to_le16(0x005e)
+#define TYPHOON_CMD_GET_IPSEC_ENABLE cpu_to_le16(0x0067)
+#define TYPHOON_CMD_GET_CMD_LVL cpu_to_le16(0x0069)
u16 seqNo;
__le16 parm1;
__le32 parm2;
@@ -380,11 +380,11 @@ struct resp_desc {
/* TYPHOON_CMD_SET_RX_FILTER filter bits (cmd.parm1)
*/
-#define TYPHOON_RX_FILTER_DIRECTED __constant_cpu_to_le16(0x0001)
-#define TYPHOON_RX_FILTER_ALL_MCAST __constant_cpu_to_le16(0x0002)
-#define TYPHOON_RX_FILTER_BROADCAST __constant_cpu_to_le16(0x0004)
-#define TYPHOON_RX_FILTER_PROMISCOUS __constant_cpu_to_le16(0x0008)
-#define TYPHOON_RX_FILTER_MCAST_HASH __constant_cpu_to_le16(0x0010)
+#define TYPHOON_RX_FILTER_DIRECTED cpu_to_le16(0x0001)
+#define TYPHOON_RX_FILTER_ALL_MCAST cpu_to_le16(0x0002)
+#define TYPHOON_RX_FILTER_BROADCAST cpu_to_le16(0x0004)
+#define TYPHOON_RX_FILTER_PROMISCOUS cpu_to_le16(0x0008)
+#define TYPHOON_RX_FILTER_MCAST_HASH cpu_to_le16(0x0010)
/* TYPHOON_CMD_READ_STATS response format
*/
@@ -416,40 +416,40 @@ struct stats_resp {
__le32 rxOverflow;
__le32 rxFiltered;
__le32 linkStatus;
-#define TYPHOON_LINK_STAT_MASK __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_LINK_GOOD __constant_cpu_to_le32(0x00000001)
-#define TYPHOON_LINK_BAD __constant_cpu_to_le32(0x00000000)
-#define TYPHOON_LINK_SPEED_MASK __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_LINK_100MBPS __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_LINK_10MBPS __constant_cpu_to_le32(0x00000000)
-#define TYPHOON_LINK_DUPLEX_MASK __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_LINK_FULL_DUPLEX __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_LINK_HALF_DUPLEX __constant_cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_STAT_MASK cpu_to_le32(0x00000001)
+#define TYPHOON_LINK_GOOD cpu_to_le32(0x00000001)
+#define TYPHOON_LINK_BAD cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_SPEED_MASK cpu_to_le32(0x00000002)
+#define TYPHOON_LINK_100MBPS cpu_to_le32(0x00000002)
+#define TYPHOON_LINK_10MBPS cpu_to_le32(0x00000000)
+#define TYPHOON_LINK_DUPLEX_MASK cpu_to_le32(0x00000004)
+#define TYPHOON_LINK_FULL_DUPLEX cpu_to_le32(0x00000004)
+#define TYPHOON_LINK_HALF_DUPLEX cpu_to_le32(0x00000000)
__le32 unused2;
__le32 unused3;
} __attribute__ ((packed));
/* TYPHOON_CMD_XCVR_SELECT xcvr values (resp.parm1)
*/
-#define TYPHOON_XCVR_10HALF __constant_cpu_to_le16(0x0000)
-#define TYPHOON_XCVR_10FULL __constant_cpu_to_le16(0x0001)
-#define TYPHOON_XCVR_100HALF __constant_cpu_to_le16(0x0002)
-#define TYPHOON_XCVR_100FULL __constant_cpu_to_le16(0x0003)
-#define TYPHOON_XCVR_AUTONEG __constant_cpu_to_le16(0x0004)
+#define TYPHOON_XCVR_10HALF cpu_to_le16(0x0000)
+#define TYPHOON_XCVR_10FULL cpu_to_le16(0x0001)
+#define TYPHOON_XCVR_100HALF cpu_to_le16(0x0002)
+#define TYPHOON_XCVR_100FULL cpu_to_le16(0x0003)
+#define TYPHOON_XCVR_AUTONEG cpu_to_le16(0x0004)
/* TYPHOON_CMD_READ_MEDIA_STATUS (resp.parm1)
*/
-#define TYPHOON_MEDIA_STAT_CRC_STRIP_DISABLE __constant_cpu_to_le16(0x0004)
-#define TYPHOON_MEDIA_STAT_COLLISION_DETECT __constant_cpu_to_le16(0x0010)
-#define TYPHOON_MEDIA_STAT_CARRIER_SENSE __constant_cpu_to_le16(0x0020)
-#define TYPHOON_MEDIA_STAT_POLARITY_REV __constant_cpu_to_le16(0x0400)
-#define TYPHOON_MEDIA_STAT_NO_LINK __constant_cpu_to_le16(0x0800)
+#define TYPHOON_MEDIA_STAT_CRC_STRIP_DISABLE cpu_to_le16(0x0004)
+#define TYPHOON_MEDIA_STAT_COLLISION_DETECT cpu_to_le16(0x0010)
+#define TYPHOON_MEDIA_STAT_CARRIER_SENSE cpu_to_le16(0x0020)
+#define TYPHOON_MEDIA_STAT_POLARITY_REV cpu_to_le16(0x0400)
+#define TYPHOON_MEDIA_STAT_NO_LINK cpu_to_le16(0x0800)
/* TYPHOON_CMD_SET_MULTICAST_HASH enable values (cmd.parm1)
*/
-#define TYPHOON_MCAST_HASH_DISABLE __constant_cpu_to_le16(0x0000)
-#define TYPHOON_MCAST_HASH_ENABLE __constant_cpu_to_le16(0x0001)
-#define TYPHOON_MCAST_HASH_SET __constant_cpu_to_le16(0x0002)
+#define TYPHOON_MCAST_HASH_DISABLE cpu_to_le16(0x0000)
+#define TYPHOON_MCAST_HASH_ENABLE cpu_to_le16(0x0001)
+#define TYPHOON_MCAST_HASH_SET cpu_to_le16(0x0002)
/* TYPHOON_CMD_CREATE_SA descriptor and settings
*/
@@ -459,9 +459,9 @@ struct sa_descriptor {
u16 cmd;
u16 seqNo;
u16 mode;
-#define TYPHOON_SA_MODE_NULL __constant_cpu_to_le16(0x0000)
-#define TYPHOON_SA_MODE_AH __constant_cpu_to_le16(0x0001)
-#define TYPHOON_SA_MODE_ESP __constant_cpu_to_le16(0x0002)
+#define TYPHOON_SA_MODE_NULL cpu_to_le16(0x0000)
+#define TYPHOON_SA_MODE_AH cpu_to_le16(0x0001)
+#define TYPHOON_SA_MODE_ESP cpu_to_le16(0x0002)
u8 hashFlags;
#define TYPHOON_SA_HASH_ENABLE 0x01
#define TYPHOON_SA_HASH_SHA1 0x02
@@ -493,22 +493,22 @@ struct sa_descriptor {
/* TYPHOON_CMD_SET_OFFLOAD_TASKS bits (cmd.parm2 (Tx) & cmd.parm3 (Rx))
* This is all for IPv4.
*/
-#define TYPHOON_OFFLOAD_TCP_CHKSUM __constant_cpu_to_le32(0x00000002)
-#define TYPHOON_OFFLOAD_UDP_CHKSUM __constant_cpu_to_le32(0x00000004)
-#define TYPHOON_OFFLOAD_IP_CHKSUM __constant_cpu_to_le32(0x00000008)
-#define TYPHOON_OFFLOAD_IPSEC __constant_cpu_to_le32(0x00000010)
-#define TYPHOON_OFFLOAD_BCAST_THROTTLE __constant_cpu_to_le32(0x00000020)
-#define TYPHOON_OFFLOAD_DHCP_PREVENT __constant_cpu_to_le32(0x00000040)
-#define TYPHOON_OFFLOAD_VLAN __constant_cpu_to_le32(0x00000080)
-#define TYPHOON_OFFLOAD_FILTERING __constant_cpu_to_le32(0x00000100)
-#define TYPHOON_OFFLOAD_TCP_SEGMENT __constant_cpu_to_le32(0x00000200)
+#define TYPHOON_OFFLOAD_TCP_CHKSUM cpu_to_le32(0x00000002)
+#define TYPHOON_OFFLOAD_UDP_CHKSUM cpu_to_le32(0x00000004)
+#define TYPHOON_OFFLOAD_IP_CHKSUM cpu_to_le32(0x00000008)
+#define TYPHOON_OFFLOAD_IPSEC cpu_to_le32(0x00000010)
+#define TYPHOON_OFFLOAD_BCAST_THROTTLE cpu_to_le32(0x00000020)
+#define TYPHOON_OFFLOAD_DHCP_PREVENT cpu_to_le32(0x00000040)
+#define TYPHOON_OFFLOAD_VLAN cpu_to_le32(0x00000080)
+#define TYPHOON_OFFLOAD_FILTERING cpu_to_le32(0x00000100)
+#define TYPHOON_OFFLOAD_TCP_SEGMENT cpu_to_le32(0x00000200)
/* TYPHOON_CMD_ENABLE_WAKE_EVENTS bits (cmd.parm1)
*/
-#define TYPHOON_WAKE_MAGIC_PKT __constant_cpu_to_le16(0x01)
-#define TYPHOON_WAKE_LINK_EVENT __constant_cpu_to_le16(0x02)
-#define TYPHOON_WAKE_ICMP_ECHO __constant_cpu_to_le16(0x04)
-#define TYPHOON_WAKE_ARP __constant_cpu_to_le16(0x08)
+#define TYPHOON_WAKE_MAGIC_PKT cpu_to_le16(0x01)
+#define TYPHOON_WAKE_LINK_EVENT cpu_to_le16(0x02)
+#define TYPHOON_WAKE_ICMP_ECHO cpu_to_le16(0x04)
+#define TYPHOON_WAKE_ARP cpu_to_le16(0x08)
/* These are used to load the firmware image on the NIC
*/
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index e87986867ba5..d3f39e86eb95 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -24,7 +24,6 @@
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
-#include <linux/fsl_devices.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/workqueue.h>
@@ -39,7 +38,7 @@
#include <asm/ucc_fast.h>
#include "ucc_geth.h"
-#include "ucc_geth_mii.h"
+#include "fsl_pq_mdio.h"
#undef DEBUG
@@ -223,10 +222,10 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth,
(((unsigned)skb->data) & (UCC_GETH_RX_DATA_BUF_ALIGNMENT -
1)));
- skb->dev = ugeth->dev;
+ skb->dev = ugeth->ndev;
out_be32(&((struct qe_bd __iomem *)bd)->buf,
- dma_map_single(&ugeth->dev->dev,
+ dma_map_single(ugeth->dev,
skb->data,
ugeth->ug_info->uf_info.max_rx_buf_length +
UCC_GETH_RX_DATA_BUF_ALIGNMENT,
@@ -1536,32 +1535,15 @@ static void adjust_link(struct net_device *dev)
static int init_phy(struct net_device *dev)
{
struct ucc_geth_private *priv = netdev_priv(dev);
- struct device_node *np = priv->node;
- struct device_node *phy, *mdio;
- const phandle *ph;
- char bus_name[MII_BUS_ID_SIZE];
- const unsigned int *id;
+ struct ucc_geth_info *ug_info = priv->ug_info;
struct phy_device *phydev;
- char phy_id[BUS_ID_SIZE];
priv->oldlink = 0;
priv->oldspeed = 0;
priv->oldduplex = -1;
- ph = of_get_property(np, "phy-handle", NULL);
- phy = of_find_node_by_phandle(*ph);
- mdio = of_get_parent(phy);
-
- id = of_get_property(phy, "reg", NULL);
-
- of_node_put(phy);
- of_node_put(mdio);
-
- uec_mdio_bus_name(bus_name, mdio);
- snprintf(phy_id, sizeof(phy_id), "%s:%02x",
- bus_name, *id);
-
- phydev = phy_connect(dev, phy_id, &adjust_link, 0, priv->phy_interface);
+ phydev = phy_connect(dev, ug_info->phy_bus_id, &adjust_link, 0,
+ priv->phy_interface);
if (IS_ERR(phydev)) {
printk("%s: Could not attach to PHY\n", dev->name);
@@ -1889,7 +1871,7 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
continue;
for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) {
if (ugeth->tx_skbuff[i][j]) {
- dma_unmap_single(&ugeth->dev->dev,
+ dma_unmap_single(ugeth->dev,
in_be32(&((struct qe_bd __iomem *)bd)->buf),
(in_be32((u32 __iomem *)bd) &
BD_LENGTH_MASK),
@@ -1917,7 +1899,7 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
bd = ugeth->p_rx_bd_ring[i];
for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) {
if (ugeth->rx_skbuff[i][j]) {
- dma_unmap_single(&ugeth->dev->dev,
+ dma_unmap_single(ugeth->dev,
in_be32(&((struct qe_bd __iomem *)bd)->buf),
ugeth->ug_info->
uf_info.max_rx_buf_length +
@@ -2026,6 +2008,9 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
/* Disable Rx and Tx */
clrbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX);
+ phy_disconnect(ugeth->phydev);
+ ugeth->phydev = NULL;
+
ucc_geth_memclean(ugeth);
}
@@ -3085,7 +3070,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* set up the buffer descriptor */
out_be32(&((struct qe_bd __iomem *)bd)->buf,
- dma_map_single(&ugeth->dev->dev, skb->data,
+ dma_map_single(ugeth->dev, skb->data,
skb->len, DMA_TO_DEVICE));
/* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */
@@ -3141,7 +3126,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
ugeth_vdbg("%s: IN", __func__);
- dev = ugeth->dev;
+ dev = ugeth->ndev;
/* collect received buffers */
bd = ugeth->rxBd[rxQ];
@@ -3175,7 +3160,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
skb_put(skb, length);
/* Tell the skb what kind of packet this is */
- skb->protocol = eth_type_trans(skb, ugeth->dev);
+ skb->protocol = eth_type_trans(skb, ugeth->ndev);
dev->stats.rx_bytes += length;
/* Send the packet up the stack */
@@ -3266,7 +3251,7 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget)
howmany += ucc_geth_rx(ugeth, i, budget - howmany);
if (howmany < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS);
}
@@ -3297,10 +3282,10 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
/* check for receive events that require processing */
if (ucce & UCCE_RX_EVENTS) {
- if (netif_rx_schedule_prep(&ugeth->napi)) {
+ if (napi_schedule_prep(&ugeth->napi)) {
uccm &= ~UCCE_RX_EVENTS;
out_be32(uccf->p_uccm, uccm);
- __netif_rx_schedule(&ugeth->napi);
+ __napi_schedule(&ugeth->napi);
}
}
@@ -3362,6 +3347,14 @@ static int ucc_geth_open(struct net_device *dev)
return -EINVAL;
}
+ err = init_phy(dev);
+ if (err) {
+ if (netif_msg_ifup(ugeth))
+ ugeth_err("%s: Cannot initialize PHY, aborting.",
+ dev->name);
+ return err;
+ }
+
err = ucc_struct_init(ugeth);
if (err) {
if (netif_msg_ifup(ugeth))
@@ -3398,13 +3391,6 @@ static int ucc_geth_open(struct net_device *dev)
&ugeth->ug_regs->macstnaddr1,
&ugeth->ug_regs->macstnaddr2);
- err = init_phy(dev);
- if (err) {
- if (netif_msg_ifup(ugeth))
- ugeth_err("%s: Cannot initialize PHY, aborting.", dev->name);
- goto out_err;
- }
-
phy_start(ugeth->phydev);
err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
@@ -3445,10 +3431,7 @@ static int ucc_geth_close(struct net_device *dev)
ucc_geth_stop(ugeth);
- free_irq(ugeth->ug_info->uf_info.irq, ugeth->dev);
-
- phy_disconnect(ugeth->phydev);
- ugeth->phydev = NULL;
+ free_irq(ugeth->ug_info->uf_info.irq, ugeth->ndev);
netif_stop_queue(dev);
@@ -3462,7 +3445,7 @@ static void ucc_geth_timeout_work(struct work_struct *work)
struct net_device *dev;
ugeth = container_of(work, struct ucc_geth_private, timeout_work);
- dev = ugeth->dev;
+ dev = ugeth->ndev;
ugeth_vdbg("%s: IN", __func__);
@@ -3518,6 +3501,20 @@ static phy_interface_t to_phy_interface(const char *phy_connection_type)
return PHY_INTERFACE_MODE_MII;
}
+static const struct net_device_ops ucc_geth_netdev_ops = {
+ .ndo_open = ucc_geth_open,
+ .ndo_stop = ucc_geth_close,
+ .ndo_start_xmit = ucc_geth_start_xmit,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_multicast_list = ucc_geth_set_multi,
+ .ndo_tx_timeout = ucc_geth_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = ucc_netpoll,
+#endif
+};
+
static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match)
{
struct device *device = &ofdev->dev;
@@ -3629,10 +3626,12 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
fixed_link = of_get_property(np, "fixed-link", NULL);
if (fixed_link) {
- snprintf(ug_info->mdio_bus, MII_BUS_ID_SIZE, "0");
- ug_info->phy_address = fixed_link[0];
+ snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id),
+ PHY_ID_FMT, "0", fixed_link[0]);
phy = NULL;
} else {
+ char bus_name[MII_BUS_ID_SIZE];
+
ph = of_get_property(np, "phy-handle", NULL);
phy = of_find_node_by_phandle(*ph);
@@ -3643,21 +3642,23 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
prop = of_get_property(phy, "reg", NULL);
if (prop == NULL)
return -1;
- ug_info->phy_address = *prop;
/* Set the bus id */
mdio = of_get_parent(phy);
if (mdio == NULL)
- return -1;
+ return -ENODEV;
err = of_address_to_resource(mdio, 0, &res);
- of_node_put(mdio);
-
- if (err)
- return -1;
- snprintf(ug_info->mdio_bus, MII_BUS_ID_SIZE, "%x", res.start);
+ if (err) {
+ of_node_put(mdio);
+ return err;
+ }
+ fsl_pq_mdio_bus_name(bus_name, mdio);
+ of_node_put(mdio);
+ snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id),
+ "%s:%02x", bus_name, *prop);
}
/* get the phy interface type, or default to MII */
@@ -3730,19 +3731,11 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
/* Fill in the dev structure */
uec_set_ethtool_ops(dev);
- dev->open = ucc_geth_open;
- dev->hard_start_xmit = ucc_geth_start_xmit;
- dev->tx_timeout = ucc_geth_timeout;
+ dev->netdev_ops = &ucc_geth_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work);
netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT);
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = ucc_netpoll;
-#endif
- dev->stop = ucc_geth_close;
-// dev->change_mtu = ucc_geth_change_mtu;
dev->mtu = 1500;
- dev->set_multicast_list = ucc_geth_set_multi;
ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT);
ugeth->phy_interface = phy_interface;
@@ -3762,7 +3755,8 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
memcpy(dev->dev_addr, mac_addr, 6);
ugeth->ug_info = ug_info;
- ugeth->dev = dev;
+ ugeth->dev = device;
+ ugeth->ndev = dev;
ugeth->node = np;
return 0;
@@ -3803,11 +3797,6 @@ static int __init ucc_geth_init(void)
{
int i, ret;
- ret = uec_mdio_init();
-
- if (ret)
- return ret;
-
if (netif_msg_drv(&debug))
printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
for (i = 0; i < 8; i++)
@@ -3816,16 +3805,12 @@ static int __init ucc_geth_init(void)
ret = of_register_platform_driver(&ucc_geth_driver);
- if (ret)
- uec_mdio_exit();
-
return ret;
}
static void __exit ucc_geth_exit(void)
{
of_unregister_platform_driver(&ucc_geth_driver);
- uec_mdio_exit();
}
module_init(ucc_geth_init);
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index 16cbe42ba43c..2f8ee7c87efe 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -20,7 +20,6 @@
#include <linux/kernel.h>
#include <linux/list.h>
-#include <linux/fsl_devices.h>
#include <asm/immap_qe.h>
#include <asm/qe.h>
@@ -28,8 +27,6 @@
#include <asm/ucc.h>
#include <asm/ucc_fast.h>
-#include "ucc_geth_mii.h"
-
#define DRV_DESC "QE UCC Gigabit Ethernet Controller"
#define DRV_NAME "ucc_geth"
#define DRV_VERSION "1.1"
@@ -184,6 +181,18 @@ struct ucc_geth {
#define UCCE_RX_EVENTS (UCCE_RXF | UCC_GETH_UCCE_BSY)
#define UCCE_TX_EVENTS (UCCE_TXB | UCC_GETH_UCCE_TXE)
+/* TBI defines */
+#define ENET_TBI_MII_CR 0x00 /* Control */
+#define ENET_TBI_MII_SR 0x01 /* Status */
+#define ENET_TBI_MII_ANA 0x04 /* AN advertisement */
+#define ENET_TBI_MII_ANLPBPA 0x05 /* AN link partner base page ability */
+#define ENET_TBI_MII_ANEX 0x06 /* AN expansion */
+#define ENET_TBI_MII_ANNPT 0x07 /* AN next page transmit */
+#define ENET_TBI_MII_ANLPANP 0x08 /* AN link partner ability next page */
+#define ENET_TBI_MII_EXST 0x0F /* Extended status */
+#define ENET_TBI_MII_JD 0x10 /* Jitter diagnostics */
+#define ENET_TBI_MII_TBICON 0x11 /* TBI control */
+
/* UCC GETH MACCFG1 (MAC Configuration 1 Register) */
#define MACCFG1_FLOW_RX 0x00000020 /* Flow Control
Rx */
@@ -1091,8 +1100,7 @@ struct ucc_geth_info {
u32 eventRegMask;
u16 pausePeriod;
u16 extensionField;
- u8 phy_address;
- char mdio_bus[MII_BUS_ID_SIZE];
+ char phy_bus_id[BUS_ID_SIZE];
u8 weightfactor[NUM_TX_QUEUES];
u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES];
u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX];
@@ -1120,7 +1128,8 @@ struct ucc_geth_info {
struct ucc_geth_private {
struct ucc_geth_info *ug_info;
struct ucc_fast_private *uccf;
- struct net_device *dev;
+ struct device *dev;
+ struct net_device *ndev;
struct napi_struct napi;
struct work_struct timeout_work;
struct ucc_geth __iomem *ug_regs;
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
index 68a7f5414133..6fcb500257bc 100644
--- a/drivers/net/ucc_geth_ethtool.c
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -28,7 +28,6 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
-#include <linux/fsl_devices.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/phy.h>
@@ -39,7 +38,6 @@
#include <asm/types.h>
#include "ucc_geth.h"
-#include "ucc_geth_mii.h"
static char hw_stat_gstrings[][ETH_GSTRING_LEN] = {
"tx-64-frames",
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
deleted file mode 100644
index 0ada4edd56eb..000000000000
--- a/drivers/net/ucc_geth_mii.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * drivers/net/ucc_geth_mii.c
- *
- * QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation
- * Provides Bus interface for MII Management regs in the UCC register space
- *
- * Copyright (C) 2007 Freescale Semiconductor, Inc.
- *
- * Authors: Li Yang <leoli@freescale.com>
- * Kim Phillips <kim.phillips@freescale.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/unistd.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/crc32.h>
-#include <linux/mii.h>
-#include <linux/phy.h>
-#include <linux/fsl_devices.h>
-#include <linux/of_platform.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/ucc.h>
-
-#include "ucc_geth_mii.h"
-#include "ucc_geth.h"
-
-#define DEBUG
-#ifdef DEBUG
-#define vdbg(format, arg...) printk(KERN_DEBUG , format "\n" , ## arg)
-#else
-#define vdbg(format, arg...) do {} while(0)
-#endif
-
-#define MII_DRV_DESC "QE UCC Ethernet Controller MII Bus"
-#define MII_DRV_NAME "fsl-uec_mdio"
-
-/* Write value to the PHY for this device to the register at regnum, */
-/* waiting until the write is done before it returns. All PHY */
-/* configuration has to be done through the master UEC MIIM regs */
-int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
-{
- struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
-
- /* Setting up the MII Mangement Address Register */
- out_be32(&regs->miimadd,
- (mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | regnum);
-
- /* Setting up the MII Mangement Control Register with the value */
- out_be32(&regs->miimcon, value);
-
- /* Wait till MII management write is complete */
- while ((in_be32(&regs->miimind)) & MIIMIND_BUSY)
- cpu_relax();
-
- return 0;
-}
-
-/* Reads from register regnum in the PHY for device dev, */
-/* returning the value. Clears miimcom first. All PHY */
-/* configuration has to be done through the TSEC1 MIIM regs */
-int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
-{
- struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
- u16 value;
-
- /* Setting up the MII Mangement Address Register */
- out_be32(&regs->miimadd,
- (mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | regnum);
-
- /* Clear miimcom, perform an MII management read cycle */
- out_be32(&regs->miimcom, 0);
- out_be32(&regs->miimcom, MIIMCOM_READ_CYCLE);
-
- /* Wait till MII management write is complete */
- while ((in_be32(&regs->miimind)) & (MIIMIND_BUSY | MIIMIND_NOT_VALID))
- cpu_relax();
-
- /* Read MII management status */
- value = in_be32(&regs->miimstat);
-
- return value;
-}
-
-/* Reset the MIIM registers, and wait for the bus to free */
-static int uec_mdio_reset(struct mii_bus *bus)
-{
- struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
- int timeout = PHY_INIT_TIMEOUT;
-
- mutex_lock(&bus->mdio_lock);
-
- /* Reset the management interface */
- out_be32(&regs->miimcfg, MIIMCFG_RESET_MANAGEMENT);
-
- /* Setup the MII Mgmt clock speed */
- out_be32(&regs->miimcfg, MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112);
-
- /* Wait until the bus is free */
- while ((in_be32(&regs->miimind) & MIIMIND_BUSY) && timeout--)
- cpu_relax();
-
- mutex_unlock(&bus->mdio_lock);
-
- if (timeout < 0) {
- printk(KERN_ERR "%s: The MII Bus is stuck!\n", bus->name);
- return -EBUSY;
- }
-
- return 0;
-}
-
-static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *match)
-{
- struct device *device = &ofdev->dev;
- struct device_node *np = ofdev->node, *tempnp = NULL;
- struct device_node *child = NULL;
- struct ucc_mii_mng __iomem *regs;
- struct mii_bus *new_bus;
- struct resource res;
- int k, err = 0;
-
- new_bus = mdiobus_alloc();
- if (NULL == new_bus)
- return -ENOMEM;
-
- new_bus->name = "UCC Ethernet Controller MII Bus";
- new_bus->read = &uec_mdio_read;
- new_bus->write = &uec_mdio_write;
- new_bus->reset = &uec_mdio_reset;
-
- memset(&res, 0, sizeof(res));
-
- err = of_address_to_resource(np, 0, &res);
- if (err)
- goto reg_map_fail;
-
- uec_mdio_bus_name(new_bus->id, np);
-
- new_bus->irq = kmalloc(32 * sizeof(int), GFP_KERNEL);
-
- if (NULL == new_bus->irq) {
- err = -ENOMEM;
- goto reg_map_fail;
- }
-
- for (k = 0; k < 32; k++)
- new_bus->irq[k] = PHY_POLL;
-
- while ((child = of_get_next_child(np, child)) != NULL) {
- int irq = irq_of_parse_and_map(child, 0);
- if (irq != NO_IRQ) {
- const u32 *id = of_get_property(child, "reg", NULL);
- new_bus->irq[*id] = irq;
- }
- }
-
- /* Set the base address */
- regs = ioremap(res.start, sizeof(struct ucc_mii_mng));
-
- if (NULL == regs) {
- err = -ENOMEM;
- goto ioremap_fail;
- }
-
- new_bus->priv = (void __force *)regs;
-
- new_bus->parent = device;
- dev_set_drvdata(device, new_bus);
-
- /* Read MII management master from device tree */
- while ((tempnp = of_find_compatible_node(tempnp, "network", "ucc_geth"))
- != NULL) {
- struct resource tempres;
-
- err = of_address_to_resource(tempnp, 0, &tempres);
- if (err)
- goto bus_register_fail;
-
- /* if our mdio regs fall within this UCC regs range */
- if ((res.start >= tempres.start) &&
- (res.end <= tempres.end)) {
- /* set this UCC to be the MII master */
- const u32 *id;
-
- id = of_get_property(tempnp, "cell-index", NULL);
- if (!id) {
- id = of_get_property(tempnp, "device-id", NULL);
- if (!id)
- goto bus_register_fail;
- }
-
- ucc_set_qe_mux_mii_mng(*id - 1);
-
- /* assign the TBI an address which won't
- * conflict with the PHYs */
- out_be32(&regs->utbipar, UTBIPAR_INIT_TBIPA);
- break;
- }
- }
-
- err = mdiobus_register(new_bus);
- if (0 != err) {
- printk(KERN_ERR "%s: Cannot register as MDIO bus\n",
- new_bus->name);
- goto bus_register_fail;
- }
-
- return 0;
-
-bus_register_fail:
- iounmap(regs);
-ioremap_fail:
- kfree(new_bus->irq);
-reg_map_fail:
- mdiobus_free(new_bus);
-
- return err;
-}
-
-static int uec_mdio_remove(struct of_device *ofdev)
-{
- struct device *device = &ofdev->dev;
- struct mii_bus *bus = dev_get_drvdata(device);
-
- mdiobus_unregister(bus);
-
- dev_set_drvdata(device, NULL);
-
- iounmap((void __iomem *)bus->priv);
- bus->priv = NULL;
- mdiobus_free(bus);
-
- return 0;
-}
-
-static struct of_device_id uec_mdio_match[] = {
- {
- .type = "mdio",
- .compatible = "ucc_geth_phy",
- },
- {
- .compatible = "fsl,ucc-mdio",
- },
- {},
-};
-
-static struct of_platform_driver uec_mdio_driver = {
- .name = MII_DRV_NAME,
- .probe = uec_mdio_probe,
- .remove = uec_mdio_remove,
- .match_table = uec_mdio_match,
-};
-
-int __init uec_mdio_init(void)
-{
- return of_register_platform_driver(&uec_mdio_driver);
-}
-
-/* called from __init ucc_geth_init, therefore can not be __exit */
-void uec_mdio_exit(void)
-{
- of_unregister_platform_driver(&uec_mdio_driver);
-}
-
-void uec_mdio_bus_name(char *name, struct device_node *np)
-{
- const u32 *reg;
-
- reg = of_get_property(np, "reg", NULL);
-
- snprintf(name, MII_BUS_ID_SIZE, "%s@%x", np->name, reg ? *reg : 0);
-}
-
diff --git a/drivers/net/ucc_geth_mii.h b/drivers/net/ucc_geth_mii.h
deleted file mode 100644
index 840cf80235b7..000000000000
--- a/drivers/net/ucc_geth_mii.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * drivers/net/ucc_geth_mii.h
- *
- * QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation
- * Provides Bus interface for MII Management regs in the UCC register space
- *
- * Copyright (C) 2007 Freescale Semiconductor, Inc.
- *
- * Authors: Li Yang <leoli@freescale.com>
- * Kim Phillips <kim.phillips@freescale.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- */
-#ifndef __UEC_MII_H
-#define __UEC_MII_H
-
-/* UCC GETH MIIMCFG (MII Management Configuration Register) */
-#define MIIMCFG_RESET_MANAGEMENT 0x80000000 /* Reset
- management */
-#define MIIMCFG_NO_PREAMBLE 0x00000010 /* Preamble
- suppress */
-#define MIIMCFG_CLOCK_DIVIDE_SHIFT (31 - 31) /* clock divide
- << shift */
-#define MIIMCFG_CLOCK_DIVIDE_MAX 0xf /* max clock divide */
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_2 0x00000000
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_4 0x00000001
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_6 0x00000002
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_8 0x00000003
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_10 0x00000004
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_14 0x00000005
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_16 0x00000008
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_20 0x00000006
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_28 0x00000007
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_32 0x00000009
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_48 0x0000000a
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_64 0x0000000b
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_80 0x0000000c
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112 0x0000000d
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_160 0x0000000e
-#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_224 0x0000000f
-
-/* UCC GETH MIIMCOM (MII Management Command Register) */
-#define MIIMCOM_SCAN_CYCLE 0x00000002 /* Scan cycle */
-#define MIIMCOM_READ_CYCLE 0x00000001 /* Read cycle */
-
-/* UCC GETH MIIMADD (MII Management Address Register) */
-#define MIIMADD_PHY_ADDRESS_SHIFT (31 - 23) /* PHY Address
- << shift */
-#define MIIMADD_PHY_REGISTER_SHIFT (31 - 31) /* PHY Register
- << shift */
-
-/* UCC GETH MIIMCON (MII Management Control Register) */
-#define MIIMCON_PHY_CONTROL_SHIFT (31 - 31) /* PHY Control
- << shift */
-#define MIIMCON_PHY_STATUS_SHIFT (31 - 31) /* PHY Status
- << shift */
-
-/* UCC GETH MIIMIND (MII Management Indicator Register) */
-#define MIIMIND_NOT_VALID 0x00000004 /* Not valid */
-#define MIIMIND_SCAN 0x00000002 /* Scan in
- progress */
-#define MIIMIND_BUSY 0x00000001
-
-/* Initial TBI Physical Address */
-#define UTBIPAR_INIT_TBIPA 0x1f
-
-struct ucc_mii_mng {
- u32 miimcfg; /* MII management configuration reg */
- u32 miimcom; /* MII management command reg */
- u32 miimadd; /* MII management address reg */
- u32 miimcon; /* MII management control reg */
- u32 miimstat; /* MII management status reg */
- u32 miimind; /* MII management indication reg */
- u8 notcare[28]; /* Space holder */
- u32 utbipar; /* TBI phy address reg */
-} __attribute__ ((packed));
-
-/* TBI / MII Set Register */
-enum enet_tbi_mii_reg {
- ENET_TBI_MII_CR = 0x00, /* Control */
- ENET_TBI_MII_SR = 0x01, /* Status */
- ENET_TBI_MII_ANA = 0x04, /* AN advertisement */
- ENET_TBI_MII_ANLPBPA = 0x05, /* AN link partner base page ability */
- ENET_TBI_MII_ANEX = 0x06, /* AN expansion */
- ENET_TBI_MII_ANNPT = 0x07, /* AN next page transmit */
- ENET_TBI_MII_ANLPANP = 0x08, /* AN link partner ability next page */
- ENET_TBI_MII_EXST = 0x0F, /* Extended status */
- ENET_TBI_MII_JD = 0x10, /* Jitter diagnostics */
- ENET_TBI_MII_TBICON = 0x11 /* TBI control */
-};
-
-int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
-int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
-int __init uec_mdio_init(void);
-void uec_mdio_exit(void);
-void uec_mdio_bus_name(char *name, struct device_node *np);
-#endif /* __UEC_MII_H */
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index 396f821b5ff0..87b4a0289919 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -807,6 +807,18 @@ static int ax88172_link_reset(struct usbnet *dev)
return 0;
}
+static const struct net_device_ops ax88172_netdev_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_change_mtu = usbnet_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = asix_ioctl,
+ .ndo_set_multicast_list = ax88172_set_multicast,
+};
+
static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)
{
int ret = 0;
@@ -846,9 +858,8 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf)
dev->mii.phy_id_mask = 0x3f;
dev->mii.reg_num_mask = 0x1f;
dev->mii.phy_id = asix_get_phy_addr(dev);
- dev->net->do_ioctl = asix_ioctl;
- dev->net->set_multicast_list = ax88172_set_multicast;
+ dev->net->netdev_ops = &ax88172_netdev_ops;
dev->net->ethtool_ops = &ax88172_ethtool_ops;
asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
@@ -898,6 +909,18 @@ static int ax88772_link_reset(struct usbnet *dev)
return 0;
}
+static const struct net_device_ops ax88772_netdev_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_change_mtu = usbnet_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = asix_ioctl,
+ .ndo_set_multicast_list = asix_set_multicast,
+};
+
static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
{
int ret, embd_phy;
@@ -962,7 +985,6 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
dev->mii.mdio_write = asix_mdio_write;
dev->mii.phy_id_mask = 0x1f;
dev->mii.reg_num_mask = 0x1f;
- dev->net->do_ioctl = asix_ioctl;
dev->mii.phy_id = asix_get_phy_addr(dev);
phyid = asix_get_phyid(dev);
@@ -978,7 +1000,7 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
msleep(150);
- dev->net->set_multicast_list = asix_set_multicast;
+ dev->net->netdev_ops = &ax88772_netdev_ops;
dev->net->ethtool_ops = &ax88772_ethtool_ops;
asix_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
@@ -1181,6 +1203,18 @@ static int ax88178_change_mtu(struct net_device *net, int new_mtu)
return 0;
}
+static const struct net_device_ops ax88178_netdev_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = asix_set_multicast,
+ .ndo_do_ioctl = asix_ioctl,
+ .ndo_change_mtu = ax88178_change_mtu,
+};
+
static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
{
struct asix_data *data = (struct asix_data *)&dev->data;
@@ -1247,11 +1281,10 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
dev->mii.phy_id_mask = 0x1f;
dev->mii.reg_num_mask = 0xff;
dev->mii.supports_gmii = 1;
- dev->net->do_ioctl = asix_ioctl;
dev->mii.phy_id = asix_get_phy_addr(dev);
- dev->net->set_multicast_list = asix_set_multicast;
+
+ dev->net->netdev_ops = &ax88178_netdev_ops;
dev->net->ethtool_ops = &ax88178_ethtool_ops;
- dev->net->change_mtu = &ax88178_change_mtu;
phyid = asix_get_phyid(dev);
dbg("PHYID=0x%08x", phyid);
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index cb7acbbb2798..b9dd42574288 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -163,7 +163,6 @@ struct catc {
struct net_device *netdev;
struct usb_device *usbdev;
- struct net_device_stats stats;
unsigned long flags;
unsigned int tx_ptr, tx_idx;
@@ -245,8 +244,8 @@ static void catc_rx_done(struct urb *urb)
if(!catc->is_f5u011) {
pkt_len = le16_to_cpup((__le16*)pkt_start);
if (pkt_len > urb->actual_length) {
- catc->stats.rx_length_errors++;
- catc->stats.rx_errors++;
+ catc->netdev->stats.rx_length_errors++;
+ catc->netdev->stats.rx_errors++;
break;
}
} else {
@@ -262,8 +261,8 @@ static void catc_rx_done(struct urb *urb)
skb->protocol = eth_type_trans(skb, catc->netdev);
netif_rx(skb);
- catc->stats.rx_packets++;
- catc->stats.rx_bytes += pkt_len;
+ catc->netdev->stats.rx_packets++;
+ catc->netdev->stats.rx_bytes += pkt_len;
/* F5U011 only does one packet per RX */
if (catc->is_f5u011)
@@ -386,7 +385,7 @@ static void catc_tx_done(struct urb *urb)
dbg("Tx Reset.");
urb->status = 0;
catc->netdev->trans_start = jiffies;
- catc->stats.tx_errors++;
+ catc->netdev->stats.tx_errors++;
clear_bit(TX_RUNNING, &catc->flags);
netif_wake_queue(catc->netdev);
return;
@@ -412,7 +411,7 @@ static void catc_tx_done(struct urb *urb)
spin_unlock_irqrestore(&catc->tx_lock, flags);
}
-static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+static int catc_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct catc *catc = netdev_priv(netdev);
unsigned long flags;
@@ -443,8 +442,8 @@ static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
spin_unlock_irqrestore(&catc->tx_lock, flags);
if (r >= 0) {
- catc->stats.tx_bytes += skb->len;
- catc->stats.tx_packets++;
+ catc->netdev->stats.tx_bytes += skb->len;
+ catc->netdev->stats.tx_packets++;
}
dev_kfree_skb(skb);
@@ -588,15 +587,15 @@ static void catc_stats_done(struct catc *catc, struct ctrl_queue *q)
switch (index) {
case TxSingleColl:
case TxMultiColl:
- catc->stats.collisions += data - last;
+ catc->netdev->stats.collisions += data - last;
break;
case TxExcessColl:
- catc->stats.tx_aborted_errors += data - last;
- catc->stats.tx_errors += data - last;
+ catc->netdev->stats.tx_aborted_errors += data - last;
+ catc->netdev->stats.tx_errors += data - last;
break;
case RxFramErr:
- catc->stats.rx_frame_errors += data - last;
- catc->stats.rx_errors += data - last;
+ catc->netdev->stats.rx_frame_errors += data - last;
+ catc->netdev->stats.rx_errors += data - last;
break;
}
@@ -614,12 +613,6 @@ static void catc_stats_timer(unsigned long data)
mod_timer(&catc->timer, jiffies + STATS_UPDATE);
}
-static struct net_device_stats *catc_get_stats(struct net_device *netdev)
-{
- struct catc *catc = netdev_priv(netdev);
- return &catc->stats;
-}
-
/*
* Receive modes. Broadcast, Multicast, Promisc.
*/
@@ -750,6 +743,18 @@ static int catc_stop(struct net_device *netdev)
return 0;
}
+static const struct net_device_ops catc_netdev_ops = {
+ .ndo_open = catc_open,
+ .ndo_stop = catc_stop,
+ .ndo_start_xmit = catc_start_xmit,
+
+ .ndo_tx_timeout = catc_tx_timeout,
+ .ndo_set_multicast_list = catc_set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*
* USB probe, disconnect.
*/
@@ -774,13 +779,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
catc = netdev_priv(netdev);
- netdev->open = catc_open;
- netdev->hard_start_xmit = catc_hard_start_xmit;
- netdev->stop = catc_stop;
- netdev->get_stats = catc_get_stats;
- netdev->tx_timeout = catc_tx_timeout;
+ netdev->netdev_ops = &catc_netdev_ops;
netdev->watchdog_timeo = TX_TIMEOUT;
- netdev->set_multicast_list = catc_set_multicast_list;
SET_ETHTOOL_OPS(netdev, &ops);
catc->usbdev = usbdev;
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 81682c6defa0..6fc4f82b0beb 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -419,6 +419,18 @@ static int dm9601_set_mac_address(struct net_device *net, void *p)
return 0;
}
+static const struct net_device_ops dm9601_netdev_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_change_mtu = usbnet_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = dm9601_ioctl,
+ .ndo_set_multicast_list = dm9601_set_multicast,
+ .ndo_set_mac_address = dm9601_set_mac_address,
+};
+
static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
{
int ret;
@@ -428,9 +440,7 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
if (ret)
goto out;
- dev->net->do_ioctl = dm9601_ioctl;
- dev->net->set_multicast_list = dm9601_set_multicast;
- dev->net->set_mac_address = dm9601_set_mac_address;
+ dev->net->netdev_ops = &dm9601_netdev_ops;
dev->net->ethtool_ops = &dm9601_ethtool_ops;
dev->net->hard_header_len += DM_TX_OVERHEAD;
dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index fe98acaead97..f84b78d94c40 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -5,6 +5,7 @@
* Copyright (C) 2008 Option International
* Filip Aben <f.aben@option.com>
* Denis Joseph Barrow <d.barow@option.com>
+ * Jan Dumon <j.dumon@option.com>
* Copyright (C) 2007 Andrew Bird (Sphere Systems Ltd)
* <ajb@spheresystems.co.uk>
* Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de>
@@ -462,9 +463,16 @@ static const struct usb_device_id hso_ids[] = {
{USB_DEVICE(0x0af0, 0x7701)},
{USB_DEVICE(0x0af0, 0x7801)},
{USB_DEVICE(0x0af0, 0x7901)},
- {USB_DEVICE(0x0af0, 0x7361)},
- {USB_DEVICE(0x0af0, 0xd057)},
+ {USB_DEVICE(0x0af0, 0x8200)},
+ {USB_DEVICE(0x0af0, 0x8201)},
+ {USB_DEVICE(0x0af0, 0xd035)},
{USB_DEVICE(0x0af0, 0xd055)},
+ {USB_DEVICE(0x0af0, 0xd155)},
+ {USB_DEVICE(0x0af0, 0xd255)},
+ {USB_DEVICE(0x0af0, 0xd057)},
+ {USB_DEVICE(0x0af0, 0xd157)},
+ {USB_DEVICE(0x0af0, 0xd257)},
+ {USB_DEVICE(0x0af0, 0xd357)},
{}
};
MODULE_DEVICE_TABLE(usb, hso_ids);
@@ -936,8 +944,7 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
if (!odev->rx_buf_missing) {
/* Packet is complete. Inject into stack. */
/* We have IP packet here */
- odev->skb_rx_buf->protocol =
- __constant_htons(ETH_P_IP);
+ odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP);
/* don't check it */
odev->skb_rx_buf->ip_summed =
CHECKSUM_UNNECESSARY;
@@ -1247,7 +1254,7 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb)
* This needs to be a tasklet otherwise we will
* end up recursively calling this function.
*/
-void hso_unthrottle_tasklet(struct hso_serial *serial)
+static void hso_unthrottle_tasklet(struct hso_serial *serial)
{
unsigned long flags;
@@ -1266,7 +1273,7 @@ static void hso_unthrottle(struct tty_struct *tty)
tasklet_hi_schedule(&serial->unthrottle_tasklet);
}
-void hso_unthrottle_workfunc(struct work_struct *work)
+static void hso_unthrottle_workfunc(struct work_struct *work)
{
struct hso_serial *serial =
container_of(work, struct hso_serial,
@@ -1465,9 +1472,9 @@ static int hso_serial_chars_in_buffer(struct tty_struct *tty)
return chars;
}
-int tiocmget_submit_urb(struct hso_serial *serial,
- struct hso_tiocmget *tiocmget,
- struct usb_device *usb)
+static int tiocmget_submit_urb(struct hso_serial *serial,
+ struct hso_tiocmget *tiocmget,
+ struct usb_device *usb)
{
int result;
@@ -2364,12 +2371,6 @@ exit:
return -1;
}
-/* Frees a general hso device */
-static void hso_free_device(struct hso_device *hso_dev)
-{
- kfree(hso_dev);
-}
-
/* Creates a general hso device */
static struct hso_device *hso_create_device(struct usb_interface *intf,
int port_spec)
@@ -2417,24 +2418,33 @@ static void hso_free_net_device(struct hso_device *hso_dev)
if (!hso_net)
return;
+ remove_net_device(hso_net->parent);
+
+ if (hso_net->net) {
+ unregister_netdev(hso_net->net);
+ free_netdev(hso_net->net);
+ }
+
/* start freeing */
for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]);
kfree(hso_net->mux_bulk_rx_buf_pool[i]);
+ hso_net->mux_bulk_rx_buf_pool[i] = NULL;
}
usb_free_urb(hso_net->mux_bulk_tx_urb);
kfree(hso_net->mux_bulk_tx_buf);
+ hso_net->mux_bulk_tx_buf = NULL;
- remove_net_device(hso_net->parent);
-
- if (hso_net->net) {
- unregister_netdev(hso_net->net);
- free_netdev(hso_net->net);
- }
-
- hso_free_device(hso_dev);
+ kfree(hso_dev);
}
+static const struct net_device_ops hso_netdev_ops = {
+ .ndo_open = hso_net_open,
+ .ndo_stop = hso_net_close,
+ .ndo_start_xmit = hso_net_start_xmit,
+ .ndo_tx_timeout = hso_net_tx_timeout,
+};
+
/* initialize the network interface */
static void hso_net_init(struct net_device *net)
{
@@ -2443,10 +2453,7 @@ static void hso_net_init(struct net_device *net)
D1("sizeof hso_net is %d", (int)sizeof(*hso_net));
/* fill in the other fields */
- net->open = hso_net_open;
- net->stop = hso_net_close;
- net->hard_start_xmit = hso_net_start_xmit;
- net->tx_timeout = hso_net_tx_timeout;
+ net->netdev_ops = &hso_netdev_ops;
net->watchdog_timeo = HSO_NET_TX_TIMEOUT;
net->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
net->type = ARPHRD_NONE;
@@ -2529,14 +2536,15 @@ static void hso_create_rfkill(struct hso_device *hso_dev,
}
/* Creates our network device */
-static struct hso_device *hso_create_net_device(struct usb_interface *interface)
+static struct hso_device *hso_create_net_device(struct usb_interface *interface,
+ int port_spec)
{
int result, i;
struct net_device *net;
struct hso_net *hso_net;
struct hso_device *hso_dev;
- hso_dev = hso_create_device(interface, HSO_INTF_MUX | HSO_PORT_NETWORK);
+ hso_dev = hso_create_device(interface, port_spec);
if (!hso_dev)
return NULL;
@@ -2616,12 +2624,12 @@ static void hso_free_tiomget(struct hso_serial *serial)
{
struct hso_tiocmget *tiocmget = serial->tiocmget;
if (tiocmget) {
- kfree(tiocmget);
if (tiocmget->urb) {
usb_free_urb(tiocmget->urb);
tiocmget->urb = NULL;
}
serial->tiocmget = NULL;
+ kfree(tiocmget);
}
}
@@ -2646,7 +2654,7 @@ static void hso_free_serial_device(struct hso_device *hso_dev)
}
hso_free_tiomget(serial);
kfree(serial);
- hso_free_device(hso_dev);
+ kfree(hso_dev);
}
/* Creates a bulk AT channel */
@@ -2727,7 +2735,7 @@ exit2:
exit:
hso_free_tiomget(serial);
kfree(serial);
- hso_free_device(hso_dev);
+ kfree(hso_dev);
return NULL;
}
@@ -2786,7 +2794,7 @@ exit:
kfree(serial);
}
if (hso_dev)
- hso_free_device(hso_dev);
+ kfree(hso_dev);
return NULL;
}
@@ -2936,7 +2944,8 @@ static int hso_probe(struct usb_interface *interface,
if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
/* Create the network device */
if (!disable_net) {
- hso_dev = hso_create_net_device(interface);
+ hso_dev = hso_create_net_device(interface,
+ port_spec);
if (!hso_dev)
goto exit;
tmp_dev = hso_dev;
@@ -2968,7 +2977,7 @@ static int hso_probe(struct usb_interface *interface,
/* It's a regular bulk interface */
if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK)
&& !disable_net)
- hso_dev = hso_create_net_device(interface);
+ hso_dev = hso_create_net_device(interface, port_spec);
else
hso_dev =
hso_create_bulk_serial_device(interface, port_spec);
@@ -2979,8 +2988,6 @@ static int hso_probe(struct usb_interface *interface,
goto exit;
}
- usb_driver_claim_interface(&hso_driver, interface, hso_dev);
-
/* save our data pointer in this device */
usb_set_intfdata(interface, hso_dev);
@@ -2998,8 +3005,6 @@ static void hso_disconnect(struct usb_interface *interface)
/* remove reference of our private data */
usb_set_intfdata(interface, NULL);
-
- usb_driver_release_interface(&hso_driver, interface);
}
static void async_get_intf(struct work_struct *data)
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index 7cb10a0a5316..3d0d0b0b37c5 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -36,7 +36,6 @@
* Run test procedures
* Fix bugs from previous two steps
* Snoop other OSs for any tricks we're not doing
- * SMP locking
* Reduce arbitrary timeouts
* Smart multicast support
* Temporary MAC change support
@@ -796,7 +795,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
int res;
- spin_lock(&kaweth->device_lock);
+ spin_lock_irq(&kaweth->device_lock);
kaweth_async_set_rx_mode(kaweth);
netif_stop_queue(net);
@@ -814,7 +813,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
if (!copied_skb) {
kaweth->stats.tx_errors++;
netif_start_queue(net);
- spin_unlock(&kaweth->device_lock);
+ spin_unlock_irq(&kaweth->device_lock);
return 0;
}
}
@@ -848,7 +847,7 @@ skip:
net->trans_start = jiffies;
}
- spin_unlock(&kaweth->device_lock);
+ spin_unlock_irq(&kaweth->device_lock);
return 0;
}
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index ced8f36ebd01..7ae9afe99a4f 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -486,6 +486,18 @@ static int mcs7830_set_mac_address(struct net_device *netdev, void *p)
return 0;
}
+static const struct net_device_ops mcs7830_netdev_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_change_mtu = usbnet_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = mcs7830_ioctl,
+ .ndo_set_multicast_list = mcs7830_set_multicast,
+ .ndo_set_mac_address = mcs7830_set_mac_address,
+};
+
static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev)
{
struct net_device *net = dev->net;
@@ -495,11 +507,9 @@ static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev)
if (ret)
goto out;
- net->do_ioctl = mcs7830_ioctl;
net->ethtool_ops = &mcs7830_ethtool_ops;
- net->set_multicast_list = mcs7830_set_multicast;
+ net->netdev_ops = &mcs7830_netdev_ops;
mcs7830_set_multicast(net);
- net->set_mac_address = mcs7830_set_mac_address;
/* reserve space for the status byte on rx */
dev->rx_urb_size = ETH_FRAME_LEN + 1;
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index bcd858c567e0..1bf243ef950e 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -169,7 +169,7 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
struct rndis_keepalive_c *msg = (void *)buf;
msg->msg_type = RNDIS_MSG_KEEPALIVE_C;
- msg->msg_len = ccpu2(sizeof *msg);
+ msg->msg_len = cpu_to_le32(sizeof *msg);
msg->status = RNDIS_STATUS_SUCCESS;
retval = usb_control_msg(dev->udev,
usb_sndctrlpipe(dev->udev, 0),
@@ -237,7 +237,7 @@ static int rndis_query(struct usbnet *dev, struct usb_interface *intf,
u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len);
u.get->oid = oid;
u.get->len = cpu_to_le32(in_len);
- u.get->offset = ccpu2(20);
+ u.get->offset = cpu_to_le32(20);
retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
if (unlikely(retval < 0)) {
@@ -266,6 +266,16 @@ response_error:
return -EDOM;
}
+/* same as usbnet_netdev_ops but MTU change not allowed */
+static const struct net_device_ops rndis_netdev_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
int
generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
{
@@ -297,9 +307,9 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
goto fail;
u.init->msg_type = RNDIS_MSG_INIT;
- u.init->msg_len = ccpu2(sizeof *u.init);
- u.init->major_version = ccpu2(1);
- u.init->minor_version = ccpu2(0);
+ u.init->msg_len = cpu_to_le32(sizeof *u.init);
+ u.init->major_version = cpu_to_le32(1);
+ u.init->minor_version = cpu_to_le32(0);
/* max transfer (in spec) is 0x4000 at full speed, but for
* TX we'll stick to one Ethernet packet plus RNDIS framing.
@@ -327,7 +337,8 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
dev->rx_urb_size &= ~(dev->maxpacket - 1);
u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size);
- net->change_mtu = NULL;
+ net->netdev_ops = &rndis_netdev_ops;
+
retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
if (unlikely(retval < 0)) {
/* it might not even be an RNDIS device!! */
@@ -403,10 +414,10 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
/* set a nonzero filter to enable data transfers */
memset(u.set, 0, sizeof *u.set);
u.set->msg_type = RNDIS_MSG_SET;
- u.set->msg_len = ccpu2(4 + sizeof *u.set);
+ u.set->msg_len = cpu_to_le32(4 + sizeof *u.set);
u.set->oid = OID_GEN_CURRENT_PACKET_FILTER;
- u.set->len = ccpu2(4);
- u.set->offset = ccpu2((sizeof *u.set) - 8);
+ u.set->len = cpu_to_le32(4);
+ u.set->offset = cpu_to_le32((sizeof *u.set) - 8);
*(__le32 *)(u.buf + sizeof *u.set) = RNDIS_DEFAULT_FILTER;
retval = rndis_command(dev, u.header, CONTROL_BUFFER_SIZE);
@@ -423,7 +434,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
halt_fail_and_release:
memset(u.halt, 0, sizeof *u.halt);
u.halt->msg_type = RNDIS_MSG_HALT;
- u.halt->msg_len = ccpu2(sizeof *u.halt);
+ u.halt->msg_len = cpu_to_le32(sizeof *u.halt);
(void) rndis_command(dev, (void *)u.halt, CONTROL_BUFFER_SIZE);
fail_and_release:
usb_set_intfdata(info->data, NULL);
@@ -448,7 +459,7 @@ void rndis_unbind(struct usbnet *dev, struct usb_interface *intf)
halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
if (halt) {
halt->msg_type = RNDIS_MSG_HALT;
- halt->msg_len = ccpu2(sizeof *halt);
+ halt->msg_len = cpu_to_le32(sizeof *halt);
(void) rndis_command(dev, (void *)halt, CONTROL_BUFFER_SIZE);
kfree(halt);
}
@@ -543,7 +554,7 @@ fill:
memset(hdr, 0, sizeof *hdr);
hdr->msg_type = RNDIS_MSG_PACKET;
hdr->msg_len = cpu_to_le32(skb->len);
- hdr->data_offset = ccpu2(sizeof(*hdr) - 8);
+ hdr->data_offset = cpu_to_le32(sizeof(*hdr) - 8);
hdr->data_len = cpu_to_le32(len);
/* FIXME make the last packet always be short ... */
@@ -562,9 +573,6 @@ static const struct driver_info rndis_info = {
.tx_fixup = rndis_tx_fixup,
};
-#undef ccpu2
-
-
/*-------------------------------------------------------------------------*/
static const struct usb_device_id products [] = {
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index d8664bf18c00..f9fb454ffa8b 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -155,7 +155,6 @@ struct rtl8150 {
unsigned long flags;
struct usb_device *udev;
struct tasklet_struct tl;
- struct net_device_stats stats;
struct net_device *netdev;
struct urb *rx_urb, *tx_urb, *intr_urb, *ctrl_urb;
struct sk_buff *tx_skb, *rx_skb;
@@ -463,8 +462,8 @@ static void read_bulk_callback(struct urb *urb)
skb_put(dev->rx_skb, pkt_len);
dev->rx_skb->protocol = eth_type_trans(dev->rx_skb, netdev);
netif_rx(dev->rx_skb);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += pkt_len;
spin_lock(&dev->rx_pool_lock);
skb = pull_skb(dev);
@@ -573,13 +572,13 @@ static void intr_callback(struct urb *urb)
d = urb->transfer_buffer;
if (d[0] & TSR_ERRORS) {
- dev->stats.tx_errors++;
+ dev->netdev->stats.tx_errors++;
if (d[INT_TSR] & (TSR_ECOL | TSR_JBR))
- dev->stats.tx_aborted_errors++;
+ dev->netdev->stats.tx_aborted_errors++;
if (d[INT_TSR] & TSR_LCOL)
- dev->stats.tx_window_errors++;
+ dev->netdev->stats.tx_window_errors++;
if (d[INT_TSR] & TSR_LOSS_CRS)
- dev->stats.tx_carrier_errors++;
+ dev->netdev->stats.tx_carrier_errors++;
}
/* Report link status changes to the network stack */
if ((d[INT_MSR] & MSR_LINK) == 0) {
@@ -697,17 +696,12 @@ static void disable_net_traffic(rtl8150_t * dev)
set_registers(dev, CR, 1, &cr);
}
-static struct net_device_stats *rtl8150_netdev_stats(struct net_device *dev)
-{
- return &((rtl8150_t *)netdev_priv(dev))->stats;
-}
-
static void rtl8150_tx_timeout(struct net_device *netdev)
{
rtl8150_t *dev = netdev_priv(netdev);
dev_warn(&netdev->dev, "Tx timeout.\n");
usb_unlink_urb(dev->tx_urb);
- dev->stats.tx_errors++;
+ netdev->stats.tx_errors++;
}
static void rtl8150_set_multicast(struct net_device *netdev)
@@ -747,12 +741,12 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
netif_device_detach(dev->netdev);
else {
dev_warn(&netdev->dev, "failed tx_urb %d\n", res);
- dev->stats.tx_errors++;
+ netdev->stats.tx_errors++;
netif_start_queue(netdev);
}
} else {
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += skb->len;
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += skb->len;
netdev->trans_start = jiffies;
}
@@ -897,6 +891,19 @@ static int rtl8150_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
return res;
}
+static const struct net_device_ops rtl8150_netdev_ops = {
+ .ndo_open = rtl8150_open,
+ .ndo_stop = rtl8150_close,
+ .ndo_do_ioctl = rtl8150_ioctl,
+ .ndo_start_xmit = rtl8150_start_xmit,
+ .ndo_tx_timeout = rtl8150_tx_timeout,
+ .ndo_set_multicast_list = rtl8150_set_multicast,
+ .ndo_set_mac_address = rtl8150_set_mac_address,
+
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int rtl8150_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
@@ -923,15 +930,8 @@ static int rtl8150_probe(struct usb_interface *intf,
dev->udev = udev;
dev->netdev = netdev;
- netdev->open = rtl8150_open;
- netdev->stop = rtl8150_close;
- netdev->do_ioctl = rtl8150_ioctl;
+ netdev->netdev_ops = &rtl8150_netdev_ops;
netdev->watchdog_timeo = RTL8150_TX_TIMEOUT;
- netdev->tx_timeout = rtl8150_tx_timeout;
- netdev->hard_start_xmit = rtl8150_start_xmit;
- netdev->set_multicast_list = rtl8150_set_multicast;
- netdev->set_mac_address = rtl8150_set_mac_address;
- netdev->get_stats = rtl8150_netdev_stats;
SET_ETHTOOL_OPS(netdev, &ops);
dev->intr_interval = 100; /* 100ms */
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 5574abe29c73..dc1665326592 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -55,11 +55,10 @@ struct smsc95xx_priv {
struct usb_context {
struct usb_ctrlrequest req;
- struct completion notify;
struct usbnet *dev;
};
-int turbo_mode = true;
+static int turbo_mode = true;
module_param(turbo_mode, bool, 0644);
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
@@ -307,7 +306,7 @@ static int smsc95xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
return 0;
}
-static void smsc95xx_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
+static void smsc95xx_async_cmd_callback(struct urb *urb)
{
struct usb_context *usb_context = urb->context;
struct usbnet *dev = usb_context->dev;
@@ -316,8 +315,6 @@ static void smsc95xx_async_cmd_callback(struct urb *urb, struct pt_regs *regs)
if (status < 0)
devwarn(dev, "async callback failed with %d", status);
- complete(&usb_context->notify);
-
kfree(usb_context);
usb_free_urb(urb);
}
@@ -348,11 +345,10 @@ static int smsc95xx_write_reg_async(struct usbnet *dev, u16 index, u32 *data)
usb_context->req.wValue = 00;
usb_context->req.wIndex = cpu_to_le16(index);
usb_context->req.wLength = cpu_to_le16(size);
- init_completion(&usb_context->notify);
usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0),
(void *)&usb_context->req, data, size,
- (usb_complete_t)smsc95xx_async_cmd_callback,
+ smsc95xx_async_cmd_callback,
(void *)usb_context);
status = usb_submit_urb(urb, GFP_ATOMIC);
@@ -1012,6 +1008,18 @@ static int smsc95xx_reset(struct usbnet *dev)
return 0;
}
+static const struct net_device_ops smsc95xx_netdev_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_change_mtu = usbnet_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = smsc95xx_ioctl,
+ .ndo_set_multicast_list = smsc95xx_set_multicast,
+};
+
static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
{
struct smsc95xx_priv *pdata = NULL;
@@ -1042,9 +1050,8 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
/* Init all registers */
ret = smsc95xx_reset(dev);
- dev->net->do_ioctl = smsc95xx_ioctl;
+ dev->net->netdev_ops = &smsc95xx_netdev_ops;
dev->net->ethtool_ops = &smsc95xx_ethtool_ops;
- dev->net->set_multicast_list = smsc95xx_set_multicast;
dev->net->flags |= IFF_MULTICAST;
dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD;
return 0;
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index c32284ff3f54..659654f45880 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -223,7 +223,7 @@ EXPORT_SYMBOL_GPL(usbnet_skb_return);
*
*-------------------------------------------------------------------------*/
-static int usbnet_change_mtu (struct net_device *net, int new_mtu)
+int usbnet_change_mtu (struct net_device *net, int new_mtu)
{
struct usbnet *dev = netdev_priv(net);
int ll_mtu = new_mtu + net->hard_header_len;
@@ -246,14 +246,7 @@ static int usbnet_change_mtu (struct net_device *net, int new_mtu)
return 0;
}
-
-/*-------------------------------------------------------------------------*/
-
-static struct net_device_stats *usbnet_get_stats (struct net_device *net)
-{
- struct usbnet *dev = netdev_priv(net);
- return &dev->stats;
-}
+EXPORT_SYMBOL_GPL(usbnet_change_mtu);
/*-------------------------------------------------------------------------*/
@@ -548,7 +541,7 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs);
// precondition: never called in_interrupt
-static int usbnet_stop (struct net_device *net)
+int usbnet_stop (struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
int temp;
@@ -592,6 +585,7 @@ static int usbnet_stop (struct net_device *net)
return 0;
}
+EXPORT_SYMBOL_GPL(usbnet_stop);
/*-------------------------------------------------------------------------*/
@@ -599,7 +593,7 @@ static int usbnet_stop (struct net_device *net)
// precondition: never called in_interrupt
-static int usbnet_open (struct net_device *net)
+int usbnet_open (struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
int retval;
@@ -674,6 +668,7 @@ done:
done_nopm:
return retval;
}
+EXPORT_SYMBOL_GPL(usbnet_open);
/*-------------------------------------------------------------------------*/
@@ -908,7 +903,7 @@ static void tx_complete (struct urb *urb)
/*-------------------------------------------------------------------------*/
-static void usbnet_tx_timeout (struct net_device *net)
+void usbnet_tx_timeout (struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
@@ -917,10 +912,11 @@ static void usbnet_tx_timeout (struct net_device *net)
// FIXME: device recovery -- reset?
}
+EXPORT_SYMBOL_GPL(usbnet_tx_timeout);
/*-------------------------------------------------------------------------*/
-static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
+int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
int length;
@@ -1003,7 +999,7 @@ drop:
}
return retval;
}
-
+EXPORT_SYMBOL_GPL(usbnet_start_xmit);
/*-------------------------------------------------------------------------*/
@@ -1110,6 +1106,15 @@ void usbnet_disconnect (struct usb_interface *intf)
}
EXPORT_SYMBOL_GPL(usbnet_disconnect);
+static const struct net_device_ops usbnet_netdev_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_change_mtu = usbnet_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
/*-------------------------------------------------------------------------*/
@@ -1179,13 +1184,14 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
net->features |= NETIF_F_HIGHDMA;
#endif
- net->change_mtu = usbnet_change_mtu;
- net->get_stats = usbnet_get_stats;
+ net->netdev_ops = &usbnet_netdev_ops;
+#ifdef CONFIG_COMPAT_NET_DEV_OPS
net->hard_start_xmit = usbnet_start_xmit;
net->open = usbnet_open;
net->stop = usbnet_stop;
- net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
net->tx_timeout = usbnet_tx_timeout;
+#endif
+ net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
net->ethtool_ops = &usbnet_ethtool_ops;
// allow device-specific bind/init procedures
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 124fe75b8a8a..015db1cece72 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -19,12 +19,17 @@
#define DRV_NAME "veth"
#define DRV_VERSION "1.0"
+#define MIN_MTU 68 /* Min L3 MTU */
+#define MAX_MTU 65535 /* Max L3 MTU (arbitrary) */
+#define MTU_PAD (ETH_HLEN + 4) /* Max difference between L2 and L3 size MTU */
+
struct veth_net_stats {
unsigned long rx_packets;
unsigned long tx_packets;
unsigned long rx_bytes;
unsigned long tx_bytes;
unsigned long tx_dropped;
+ unsigned long rx_dropped;
};
struct veth_priv {
@@ -147,7 +152,7 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct net_device *rcv = NULL;
struct veth_priv *priv, *rcv_priv;
- struct veth_net_stats *stats;
+ struct veth_net_stats *stats, *rcv_stats;
int length, cpu;
skb_orphan(skb);
@@ -158,9 +163,13 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev)
cpu = smp_processor_id();
stats = per_cpu_ptr(priv->stats, cpu);
+ rcv_stats = per_cpu_ptr(rcv_priv->stats, cpu);
if (!(rcv->flags & IFF_UP))
- goto outf;
+ goto tx_drop;
+
+ if (skb->len > (rcv->mtu + MTU_PAD))
+ goto rx_drop;
skb->pkt_type = PACKET_HOST;
skb->protocol = eth_type_trans(skb, rcv);
@@ -178,17 +187,21 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev)
stats->tx_bytes += length;
stats->tx_packets++;
- stats = per_cpu_ptr(rcv_priv->stats, cpu);
- stats->rx_bytes += length;
- stats->rx_packets++;
+ rcv_stats->rx_bytes += length;
+ rcv_stats->rx_packets++;
netif_rx(skb);
return 0;
-outf:
+tx_drop:
kfree_skb(skb);
stats->tx_dropped++;
return 0;
+
+rx_drop:
+ kfree_skb(skb);
+ rcv_stats->rx_dropped++;
+ return 0;
}
/*
@@ -210,6 +223,7 @@ static struct net_device_stats *veth_get_stats(struct net_device *dev)
dev_stats->rx_bytes = 0;
dev_stats->tx_bytes = 0;
dev_stats->tx_dropped = 0;
+ dev_stats->rx_dropped = 0;
for_each_online_cpu(cpu) {
stats = per_cpu_ptr(priv->stats, cpu);
@@ -219,6 +233,7 @@ static struct net_device_stats *veth_get_stats(struct net_device *dev)
dev_stats->rx_bytes += stats->rx_bytes;
dev_stats->tx_bytes += stats->tx_bytes;
dev_stats->tx_dropped += stats->tx_dropped;
+ dev_stats->rx_dropped += stats->rx_dropped;
}
return dev_stats;
@@ -249,6 +264,19 @@ static int veth_close(struct net_device *dev)
return 0;
}
+static int is_valid_veth_mtu(int new_mtu)
+{
+ return (new_mtu >= MIN_MTU && new_mtu <= MAX_MTU);
+}
+
+static int veth_change_mtu(struct net_device *dev, int new_mtu)
+{
+ if (!is_valid_veth_mtu(new_mtu))
+ return -EINVAL;
+ dev->mtu = new_mtu;
+ return 0;
+}
+
static int veth_dev_init(struct net_device *dev)
{
struct veth_net_stats *stats;
@@ -277,6 +305,7 @@ static const struct net_device_ops veth_netdev_ops = {
.ndo_open = veth_open,
.ndo_stop = veth_close,
.ndo_start_xmit = veth_xmit,
+ .ndo_change_mtu = veth_change_mtu,
.ndo_get_stats = veth_get_stats,
.ndo_set_mac_address = eth_mac_addr,
};
@@ -303,6 +332,10 @@ static int veth_validate(struct nlattr *tb[], struct nlattr *data[])
if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
return -EADDRNOTAVAIL;
}
+ if (tb[IFLA_MTU]) {
+ if (!is_valid_veth_mtu(nla_get_u32(tb[IFLA_MTU])))
+ return -EINVAL;
+ }
return 0;
}
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 3b8e63254277..880eaf07413b 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -109,8 +109,9 @@ static const int multicast_filter_limit = 32;
#include <linux/dmi.h>
/* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
-KERN_INFO DRV_NAME ".c:v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker\n";
+static const char version[] __devinitconst =
+ KERN_INFO DRV_NAME ".c:v1.10-LK" DRV_VERSION " " DRV_RELDATE
+ " Written by Donald Becker\n";
/* This driver was written to use PCI memory space. Some early versions
of the Rhine may only work correctly with I/O space accesses. */
@@ -589,7 +590,7 @@ static int rhine_napipoll(struct napi_struct *napi, int budget)
work_done = rhine_rx(dev, budget);
if (work_done < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
IntrRxDropped | IntrRxNoBuf | IntrTxAborted |
@@ -1319,7 +1320,7 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
IntrPCIErr | IntrStatsMax | IntrLinkChange,
ioaddr + IntrEnable);
- netif_rx_schedule(&rp->napi);
+ napi_schedule(&rp->napi);
}
if (intr_status & (IntrTxErrSummary | IntrTxDone)) {
diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
index 29a33090d3d4..ea43e1832afb 100644
--- a/drivers/net/via-velocity.h
+++ b/drivers/net/via-velocity.h
@@ -183,7 +183,7 @@ struct rdesc1 {
};
enum {
- RX_INTEN = __constant_cpu_to_le16(0x8000)
+ RX_INTEN = cpu_to_le16(0x8000)
};
struct rx_desc {
@@ -210,7 +210,7 @@ struct tdesc1 {
} __attribute__ ((__packed__));
enum {
- TD_QUEUE = __constant_cpu_to_le16(0x8000)
+ TD_QUEUE = cpu_to_le16(0x8000)
};
struct td_buf {
@@ -242,7 +242,7 @@ struct velocity_td_info {
enum velocity_owner {
OWNED_BY_HOST = 0,
- OWNED_BY_NIC = __constant_cpu_to_le16(0x8000)
+ OWNED_BY_NIC = cpu_to_le16(0x8000)
};
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index c68808336c8c..a6f1e19159d8 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -37,12 +37,15 @@ module_param(gso, bool, 0444);
#define MAX_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
#define GOOD_COPY_LEN 128
+#define VIRTNET_SEND_COMMAND_SG_MAX 2
+
struct virtnet_info
{
struct virtio_device *vdev;
- struct virtqueue *rvq, *svq;
+ struct virtqueue *rvq, *svq, *cvq;
struct net_device *dev;
struct napi_struct napi;
+ unsigned int status;
/* The skb we couldn't send because buffers were full. */
struct sk_buff *last_xmit_skb;
@@ -375,9 +378,9 @@ static void skb_recv_done(struct virtqueue *rvq)
{
struct virtnet_info *vi = rvq->vdev->priv;
/* Schedule NAPI, Suppress further interrupts if successful. */
- if (netif_rx_schedule_prep(&vi->napi)) {
+ if (napi_schedule_prep(&vi->napi)) {
rvq->vq_ops->disable_cb(rvq);
- __netif_rx_schedule(&vi->napi);
+ __napi_schedule(&vi->napi);
}
}
@@ -403,11 +406,11 @@ again:
/* Out of packets? */
if (received < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq))
&& napi_schedule_prep(napi)) {
vi->rvq->vq_ops->disable_cb(vi->rvq);
- __netif_rx_schedule(napi);
+ __napi_schedule(napi);
goto again;
}
}
@@ -562,6 +565,22 @@ stop_queue:
goto done;
}
+static int virtnet_set_mac_address(struct net_device *dev, void *p)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ struct virtio_device *vdev = vi->vdev;
+ int ret;
+
+ ret = eth_mac_addr(dev, p);
+ if (ret)
+ return ret;
+
+ vdev->config->set(vdev, offsetof(struct virtio_net_config, mac),
+ dev->dev_addr, dev->addr_len);
+
+ return 0;
+}
+
#ifdef CONFIG_NET_POLL_CONTROLLER
static void virtnet_netpoll(struct net_device *dev)
{
@@ -581,13 +600,60 @@ static int virtnet_open(struct net_device *dev)
* won't get another interrupt, so process any outstanding packets
* now. virtnet_poll wants re-enable the queue, so we disable here.
* We synchronize against interrupts via NAPI_STATE_SCHED */
- if (netif_rx_schedule_prep(&vi->napi)) {
+ if (napi_schedule_prep(&vi->napi)) {
vi->rvq->vq_ops->disable_cb(vi->rvq);
- __netif_rx_schedule(&vi->napi);
+ __napi_schedule(&vi->napi);
}
return 0;
}
+/*
+ * Send command via the control virtqueue and check status. Commands
+ * supported by the hypervisor, as indicated by feature bits, should
+ * never fail unless improperly formated.
+ */
+static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
+ struct scatterlist *data, int out, int in)
+{
+ struct scatterlist sg[VIRTNET_SEND_COMMAND_SG_MAX + 2];
+ struct virtio_net_ctrl_hdr ctrl;
+ virtio_net_ctrl_ack status = ~0;
+ unsigned int tmp;
+
+ if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
+ BUG(); /* Caller should know better */
+ return false;
+ }
+
+ BUG_ON(out + in > VIRTNET_SEND_COMMAND_SG_MAX);
+
+ out++; /* Add header */
+ in++; /* Add return status */
+
+ ctrl.class = class;
+ ctrl.cmd = cmd;
+
+ sg_init_table(sg, out + in);
+
+ sg_set_buf(&sg[0], &ctrl, sizeof(ctrl));
+ memcpy(&sg[1], data, sizeof(struct scatterlist) * (out + in - 2));
+ sg_set_buf(&sg[out + in - 1], &status, sizeof(status));
+
+ if (vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) != 0)
+ BUG();
+
+ vi->cvq->vq_ops->kick(vi->cvq);
+
+ /*
+ * Spin for a response, the kick causes an ioport write, trapping
+ * into the hypervisor, so the request should be handled immediately.
+ */
+ while (!vi->cvq->vq_ops->get_buf(vi->cvq, &tmp))
+ cpu_relax();
+
+ return status == VIRTIO_NET_OK;
+}
+
static int virtnet_close(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
@@ -608,10 +674,104 @@ static int virtnet_set_tx_csum(struct net_device *dev, u32 data)
return ethtool_op_set_tx_hw_csum(dev, data);
}
+static void virtnet_set_rx_mode(struct net_device *dev)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ struct scatterlist sg[2];
+ u8 promisc, allmulti;
+ struct virtio_net_ctrl_mac *mac_data;
+ struct dev_addr_list *addr;
+ void *buf;
+ int i;
+
+ /* We can't dynamicaly set ndo_set_rx_mode, so return gracefully */
+ if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX))
+ return;
+
+ promisc = ((dev->flags & IFF_PROMISC) != 0);
+ allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
+
+ sg_set_buf(sg, &promisc, sizeof(promisc));
+
+ if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
+ VIRTIO_NET_CTRL_RX_PROMISC,
+ sg, 1, 0))
+ dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
+ promisc ? "en" : "dis");
+
+ sg_set_buf(sg, &allmulti, sizeof(allmulti));
+
+ if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
+ VIRTIO_NET_CTRL_RX_ALLMULTI,
+ sg, 1, 0))
+ dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
+ allmulti ? "en" : "dis");
+
+ /* MAC filter - use one buffer for both lists */
+ mac_data = buf = kzalloc(((dev->uc_count + dev->mc_count) * ETH_ALEN) +
+ (2 * sizeof(mac_data->entries)), GFP_ATOMIC);
+ if (!buf) {
+ dev_warn(&dev->dev, "No memory for MAC address buffer\n");
+ return;
+ }
+
+ /* Store the unicast list and count in the front of the buffer */
+ mac_data->entries = dev->uc_count;
+ addr = dev->uc_list;
+ for (i = 0; i < dev->uc_count; i++, addr = addr->next)
+ memcpy(&mac_data->macs[i][0], addr->da_addr, ETH_ALEN);
+
+ sg_set_buf(&sg[0], mac_data,
+ sizeof(mac_data->entries) + (dev->uc_count * ETH_ALEN));
+
+ /* multicast list and count fill the end */
+ mac_data = (void *)&mac_data->macs[dev->uc_count][0];
+
+ mac_data->entries = dev->mc_count;
+ addr = dev->mc_list;
+ for (i = 0; i < dev->mc_count; i++, addr = addr->next)
+ memcpy(&mac_data->macs[i][0], addr->da_addr, ETH_ALEN);
+
+ sg_set_buf(&sg[1], mac_data,
+ sizeof(mac_data->entries) + (dev->mc_count * ETH_ALEN));
+
+ if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC,
+ VIRTIO_NET_CTRL_MAC_TABLE_SET,
+ sg, 2, 0))
+ dev_warn(&dev->dev, "Failed to set MAC fitler table.\n");
+
+ kfree(buf);
+}
+
+static void virnet_vlan_rx_add_vid(struct net_device *dev, u16 vid)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ struct scatterlist sg;
+
+ sg_set_buf(&sg, &vid, sizeof(vid));
+
+ if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
+ VIRTIO_NET_CTRL_VLAN_ADD, &sg, 1, 0))
+ dev_warn(&dev->dev, "Failed to add VLAN ID %d.\n", vid);
+}
+
+static void virnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ struct scatterlist sg;
+
+ sg_set_buf(&sg, &vid, sizeof(vid));
+
+ if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
+ VIRTIO_NET_CTRL_VLAN_DEL, &sg, 1, 0))
+ dev_warn(&dev->dev, "Failed to kill VLAN ID %d.\n", vid);
+}
+
static struct ethtool_ops virtnet_ethtool_ops = {
.set_tx_csum = virtnet_set_tx_csum,
.set_sg = ethtool_op_set_sg,
.set_tso = ethtool_op_set_tso,
+ .get_link = ethtool_op_get_link,
};
#define MIN_MTU 68
@@ -630,13 +790,51 @@ static const struct net_device_ops virtnet_netdev = {
.ndo_stop = virtnet_close,
.ndo_start_xmit = start_xmit,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_mac_address = eth_mac_addr,
+ .ndo_set_mac_address = virtnet_set_mac_address,
+ .ndo_set_rx_mode = virtnet_set_rx_mode,
.ndo_change_mtu = virtnet_change_mtu,
+ .ndo_vlan_rx_add_vid = virnet_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = virnet_vlan_rx_kill_vid,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = virtnet_netpoll,
#endif
};
+static void virtnet_update_status(struct virtnet_info *vi)
+{
+ u16 v;
+
+ if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS))
+ return;
+
+ vi->vdev->config->get(vi->vdev,
+ offsetof(struct virtio_net_config, status),
+ &v, sizeof(v));
+
+ /* Ignore unknown (future) status bits */
+ v &= VIRTIO_NET_S_LINK_UP;
+
+ if (vi->status == v)
+ return;
+
+ vi->status = v;
+
+ if (vi->status & VIRTIO_NET_S_LINK_UP) {
+ netif_carrier_on(vi->dev);
+ netif_wake_queue(vi->dev);
+ } else {
+ netif_carrier_off(vi->dev);
+ netif_stop_queue(vi->dev);
+ }
+}
+
+static void virtnet_config_changed(struct virtio_device *vdev)
+{
+ struct virtnet_info *vi = vdev->priv;
+
+ virtnet_update_status(vi);
+}
+
static int virtnet_probe(struct virtio_device *vdev)
{
int err;
@@ -678,8 +876,11 @@ static int virtnet_probe(struct virtio_device *vdev)
vdev->config->get(vdev,
offsetof(struct virtio_net_config, mac),
dev->dev_addr, dev->addr_len);
- } else
+ } else {
random_ether_addr(dev->dev_addr);
+ vdev->config->set(vdev, offsetof(struct virtio_net_config, mac),
+ dev->dev_addr, dev->addr_len);
+ }
/* Set up our device-specific information */
vi = netdev_priv(dev);
@@ -715,6 +916,17 @@ static int virtnet_probe(struct virtio_device *vdev)
goto free_recv;
}
+ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
+ vi->cvq = vdev->config->find_vq(vdev, 2, NULL);
+ if (IS_ERR(vi->cvq)) {
+ err = PTR_ERR(vi->svq);
+ goto free_send;
+ }
+
+ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VLAN))
+ dev->features |= NETIF_F_HW_VLAN_FILTER;
+ }
+
/* Initialize our empty receive and send queues. */
skb_queue_head_init(&vi->recv);
skb_queue_head_init(&vi->send);
@@ -727,7 +939,7 @@ static int virtnet_probe(struct virtio_device *vdev)
err = register_netdev(dev);
if (err) {
pr_debug("virtio_net: registering device failed\n");
- goto free_send;
+ goto free_ctrl;
}
/* Last of all, set up some receive buffers. */
@@ -739,11 +951,18 @@ static int virtnet_probe(struct virtio_device *vdev)
goto unregister;
}
+ vi->status = VIRTIO_NET_S_LINK_UP;
+ virtnet_update_status(vi);
+ netif_carrier_on(dev);
+
pr_debug("virtnet: registered device %s\n", dev->name);
return 0;
unregister:
unregister_netdev(dev);
+free_ctrl:
+ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ))
+ vdev->config->del_vq(vi->cvq);
free_send:
vdev->config->del_vq(vi->svq);
free_recv:
@@ -775,6 +994,8 @@ static void virtnet_remove(struct virtio_device *vdev)
vdev->config->del_vq(vi->svq);
vdev->config->del_vq(vi->rvq);
+ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ))
+ vdev->config->del_vq(vi->cvq);
unregister_netdev(vi->dev);
while (vi->pages)
@@ -794,7 +1015,8 @@ static unsigned int features[] = {
VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */
- VIRTIO_NET_F_MRG_RXBUF,
+ VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
+ VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
VIRTIO_F_NOTIFY_ON_EMPTY,
};
@@ -806,6 +1028,7 @@ static struct virtio_driver virtio_net = {
.id_table = id_table,
.probe = virtnet_probe,
.remove = __devexit_p(virtnet_remove),
+ .config_changed = virtnet_config_changed,
};
static int __init init(void)
diff --git a/drivers/net/vxge/Makefile b/drivers/net/vxge/Makefile
new file mode 100644
index 000000000000..8992ca26b277
--- /dev/null
+++ b/drivers/net/vxge/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for Neterion Inc's X3100 Series 10 GbE PCIe # I/O
+# Virtualized Server Adapter linux driver
+
+obj-$(CONFIG_VXGE) += vxge.o
+
+vxge-objs := vxge-config.o vxge-traffic.o vxge-ethtool.o vxge-main.o
diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c
new file mode 100644
index 000000000000..6b41c884a337
--- /dev/null
+++ b/drivers/net/vxge/vxge-config.c
@@ -0,0 +1,5264 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice. This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-config.c: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#include <linux/vmalloc.h>
+#include <linux/etherdevice.h>
+#include <linux/pci.h>
+#include <linux/pci_hotplug.h>
+
+#include "vxge-traffic.h"
+#include "vxge-config.h"
+
+/*
+ * __vxge_hw_channel_allocate - Allocate memory for channel
+ * This function allocates required memory for the channel and various arrays
+ * in the channel
+ */
+struct __vxge_hw_channel*
+__vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph,
+ enum __vxge_hw_channel_type type,
+ u32 length, u32 per_dtr_space, void *userdata)
+{
+ struct __vxge_hw_channel *channel;
+ struct __vxge_hw_device *hldev;
+ int size = 0;
+ u32 vp_id;
+
+ hldev = vph->vpath->hldev;
+ vp_id = vph->vpath->vp_id;
+
+ switch (type) {
+ case VXGE_HW_CHANNEL_TYPE_FIFO:
+ size = sizeof(struct __vxge_hw_fifo);
+ break;
+ case VXGE_HW_CHANNEL_TYPE_RING:
+ size = sizeof(struct __vxge_hw_ring);
+ break;
+ default:
+ break;
+ }
+
+ channel = kzalloc(size, GFP_KERNEL);
+ if (channel == NULL)
+ goto exit0;
+ INIT_LIST_HEAD(&channel->item);
+
+ channel->common_reg = hldev->common_reg;
+ channel->first_vp_id = hldev->first_vp_id;
+ channel->type = type;
+ channel->devh = hldev;
+ channel->vph = vph;
+ channel->userdata = userdata;
+ channel->per_dtr_space = per_dtr_space;
+ channel->length = length;
+ channel->vp_id = vp_id;
+
+ channel->work_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
+ if (channel->work_arr == NULL)
+ goto exit1;
+
+ channel->free_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
+ if (channel->free_arr == NULL)
+ goto exit1;
+ channel->free_ptr = length;
+
+ channel->reserve_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
+ if (channel->reserve_arr == NULL)
+ goto exit1;
+ channel->reserve_ptr = length;
+ channel->reserve_top = 0;
+
+ channel->orig_arr = kzalloc(sizeof(void *)*length, GFP_KERNEL);
+ if (channel->orig_arr == NULL)
+ goto exit1;
+
+ return channel;
+exit1:
+ __vxge_hw_channel_free(channel);
+
+exit0:
+ return NULL;
+}
+
+/*
+ * __vxge_hw_channel_free - Free memory allocated for channel
+ * This function deallocates memory from the channel and various arrays
+ * in the channel
+ */
+void __vxge_hw_channel_free(struct __vxge_hw_channel *channel)
+{
+ kfree(channel->work_arr);
+ kfree(channel->free_arr);
+ kfree(channel->reserve_arr);
+ kfree(channel->orig_arr);
+ kfree(channel);
+}
+
+/*
+ * __vxge_hw_channel_initialize - Initialize a channel
+ * This function initializes a channel by properly setting the
+ * various references
+ */
+enum vxge_hw_status
+__vxge_hw_channel_initialize(struct __vxge_hw_channel *channel)
+{
+ u32 i;
+ struct __vxge_hw_virtualpath *vpath;
+
+ vpath = channel->vph->vpath;
+
+ if ((channel->reserve_arr != NULL) && (channel->orig_arr != NULL)) {
+ for (i = 0; i < channel->length; i++)
+ channel->orig_arr[i] = channel->reserve_arr[i];
+ }
+
+ switch (channel->type) {
+ case VXGE_HW_CHANNEL_TYPE_FIFO:
+ vpath->fifoh = (struct __vxge_hw_fifo *)channel;
+ channel->stats = &((struct __vxge_hw_fifo *)
+ channel)->stats->common_stats;
+ break;
+ case VXGE_HW_CHANNEL_TYPE_RING:
+ vpath->ringh = (struct __vxge_hw_ring *)channel;
+ channel->stats = &((struct __vxge_hw_ring *)
+ channel)->stats->common_stats;
+ break;
+ default:
+ break;
+ }
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_channel_reset - Resets a channel
+ * This function resets a channel by properly setting the various references
+ */
+enum vxge_hw_status
+__vxge_hw_channel_reset(struct __vxge_hw_channel *channel)
+{
+ u32 i;
+
+ for (i = 0; i < channel->length; i++) {
+ if (channel->reserve_arr != NULL)
+ channel->reserve_arr[i] = channel->orig_arr[i];
+ if (channel->free_arr != NULL)
+ channel->free_arr[i] = NULL;
+ if (channel->work_arr != NULL)
+ channel->work_arr[i] = NULL;
+ }
+ channel->free_ptr = channel->length;
+ channel->reserve_ptr = channel->length;
+ channel->reserve_top = 0;
+ channel->post_index = 0;
+ channel->compl_index = 0;
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_device_pci_e_init
+ * Initialize certain PCI/PCI-X configuration registers
+ * with recommended values. Save config space for future hw resets.
+ */
+void
+__vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev)
+{
+ u16 cmd = 0;
+
+ /* Set the PErr Repconse bit and SERR in PCI command register. */
+ pci_read_config_word(hldev->pdev, PCI_COMMAND, &cmd);
+ cmd |= 0x140;
+ pci_write_config_word(hldev->pdev, PCI_COMMAND, cmd);
+
+ pci_save_state(hldev->pdev);
+
+ return;
+}
+
+/*
+ * __vxge_hw_device_register_poll
+ * Will poll certain register for specified amount of time.
+ * Will poll until masked bit is not cleared.
+ */
+enum vxge_hw_status
+__vxge_hw_device_register_poll(void __iomem *reg, u64 mask, u32 max_millis)
+{
+ u64 val64;
+ u32 i = 0;
+ enum vxge_hw_status ret = VXGE_HW_FAIL;
+
+ udelay(10);
+
+ do {
+ val64 = readq(reg);
+ if (!(val64 & mask))
+ return VXGE_HW_OK;
+ udelay(100);
+ } while (++i <= 9);
+
+ i = 0;
+ do {
+ val64 = readq(reg);
+ if (!(val64 & mask))
+ return VXGE_HW_OK;
+ mdelay(1);
+ } while (++i <= max_millis);
+
+ return ret;
+}
+
+ /* __vxge_hw_device_vpath_reset_in_prog_check - Check if vpath reset
+ * in progress
+ * This routine checks the vpath reset in progress register is turned zero
+ */
+enum vxge_hw_status
+__vxge_hw_device_vpath_reset_in_prog_check(u64 __iomem *vpath_rst_in_prog)
+{
+ enum vxge_hw_status status;
+ status = __vxge_hw_device_register_poll(vpath_rst_in_prog,
+ VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(0x1ffff),
+ VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+ return status;
+}
+
+/*
+ * __vxge_hw_device_toc_get
+ * This routine sets the swapper and reads the toc pointer and returns the
+ * memory mapped address of the toc
+ */
+struct vxge_hw_toc_reg __iomem *
+__vxge_hw_device_toc_get(void __iomem *bar0)
+{
+ u64 val64;
+ struct vxge_hw_toc_reg __iomem *toc = NULL;
+ enum vxge_hw_status status;
+
+ struct vxge_hw_legacy_reg __iomem *legacy_reg =
+ (struct vxge_hw_legacy_reg __iomem *)bar0;
+
+ status = __vxge_hw_legacy_swapper_set(legacy_reg);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ val64 = readq(&legacy_reg->toc_first_pointer);
+ toc = (struct vxge_hw_toc_reg __iomem *)(bar0+val64);
+exit:
+ return toc;
+}
+
+/*
+ * __vxge_hw_device_reg_addr_get
+ * This routine sets the swapper and reads the toc pointer and initializes the
+ * register location pointers in the device object. It waits until the ric is
+ * completed initializing registers.
+ */
+enum vxge_hw_status
+__vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev)
+{
+ u64 val64;
+ u32 i;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ hldev->legacy_reg = (struct vxge_hw_legacy_reg __iomem *)hldev->bar0;
+
+ hldev->toc_reg = __vxge_hw_device_toc_get(hldev->bar0);
+ if (hldev->toc_reg == NULL) {
+ status = VXGE_HW_FAIL;
+ goto exit;
+ }
+
+ val64 = readq(&hldev->toc_reg->toc_common_pointer);
+ hldev->common_reg =
+ (struct vxge_hw_common_reg __iomem *)(hldev->bar0 + val64);
+
+ val64 = readq(&hldev->toc_reg->toc_mrpcim_pointer);
+ hldev->mrpcim_reg =
+ (struct vxge_hw_mrpcim_reg __iomem *)(hldev->bar0 + val64);
+
+ for (i = 0; i < VXGE_HW_TITAN_SRPCIM_REG_SPACES; i++) {
+ val64 = readq(&hldev->toc_reg->toc_srpcim_pointer[i]);
+ hldev->srpcim_reg[i] =
+ (struct vxge_hw_srpcim_reg __iomem *)
+ (hldev->bar0 + val64);
+ }
+
+ for (i = 0; i < VXGE_HW_TITAN_VPMGMT_REG_SPACES; i++) {
+ val64 = readq(&hldev->toc_reg->toc_vpmgmt_pointer[i]);
+ hldev->vpmgmt_reg[i] =
+ (struct vxge_hw_vpmgmt_reg __iomem *)(hldev->bar0 + val64);
+ }
+
+ for (i = 0; i < VXGE_HW_TITAN_VPATH_REG_SPACES; i++) {
+ val64 = readq(&hldev->toc_reg->toc_vpath_pointer[i]);
+ hldev->vpath_reg[i] =
+ (struct vxge_hw_vpath_reg __iomem *)
+ (hldev->bar0 + val64);
+ }
+
+ val64 = readq(&hldev->toc_reg->toc_kdfc);
+
+ switch (VXGE_HW_TOC_GET_KDFC_INITIAL_BIR(val64)) {
+ case 0:
+ hldev->kdfc = (u8 __iomem *)(hldev->bar0 +
+ VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64));
+ break;
+ case 2:
+ hldev->kdfc = (u8 __iomem *)(hldev->bar1 +
+ VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64));
+ break;
+ case 4:
+ hldev->kdfc = (u8 __iomem *)(hldev->bar2 +
+ VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64));
+ break;
+ default:
+ break;
+ }
+
+ status = __vxge_hw_device_vpath_reset_in_prog_check(
+ (u64 __iomem *)&hldev->common_reg->vpath_rst_in_prog);
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_device_id_get
+ * This routine returns sets the device id and revision numbers into the device
+ * structure
+ */
+void __vxge_hw_device_id_get(struct __vxge_hw_device *hldev)
+{
+ u64 val64;
+
+ val64 = readq(&hldev->common_reg->titan_asic_id);
+ hldev->device_id =
+ (u16)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_DEVICE_ID(val64);
+
+ hldev->major_revision =
+ (u8)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MAJOR_REVISION(val64);
+
+ hldev->minor_revision =
+ (u8)VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MINOR_REVISION(val64);
+
+ return;
+}
+
+/*
+ * __vxge_hw_device_access_rights_get: Get Access Rights of the driver
+ * This routine returns the Access Rights of the driver
+ */
+static u32
+__vxge_hw_device_access_rights_get(u32 host_type, u32 func_id)
+{
+ u32 access_rights = VXGE_HW_DEVICE_ACCESS_RIGHT_VPATH;
+
+ switch (host_type) {
+ case VXGE_HW_NO_MR_NO_SR_NORMAL_FUNCTION:
+ if (func_id == 0) {
+ access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
+ VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
+ }
+ break;
+ case VXGE_HW_MR_NO_SR_VH0_BASE_FUNCTION:
+ access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
+ VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
+ break;
+ case VXGE_HW_NO_MR_SR_VH0_FUNCTION0:
+ access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM |
+ VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
+ break;
+ case VXGE_HW_NO_MR_SR_VH0_VIRTUAL_FUNCTION:
+ case VXGE_HW_SR_VH_VIRTUAL_FUNCTION:
+ case VXGE_HW_MR_SR_VH0_INVALID_CONFIG:
+ break;
+ case VXGE_HW_SR_VH_FUNCTION0:
+ case VXGE_HW_VH_NORMAL_FUNCTION:
+ access_rights |= VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM;
+ break;
+ }
+
+ return access_rights;
+}
+/*
+ * __vxge_hw_device_host_info_get
+ * This routine returns the host type assignments
+ */
+void __vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev)
+{
+ u64 val64;
+ u32 i;
+
+ val64 = readq(&hldev->common_reg->host_type_assignments);
+
+ hldev->host_type =
+ (u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
+
+ hldev->vpath_assignments = readq(&hldev->common_reg->vpath_assignments);
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+ if (!(hldev->vpath_assignments & vxge_mBIT(i)))
+ continue;
+
+ hldev->func_id =
+ __vxge_hw_vpath_func_id_get(i, hldev->vpmgmt_reg[i]);
+
+ hldev->access_rights = __vxge_hw_device_access_rights_get(
+ hldev->host_type, hldev->func_id);
+
+ hldev->first_vp_id = i;
+ break;
+ }
+
+ return;
+}
+
+/*
+ * __vxge_hw_verify_pci_e_info - Validate the pci-e link parameters such as
+ * link width and signalling rate.
+ */
+static enum vxge_hw_status
+__vxge_hw_verify_pci_e_info(struct __vxge_hw_device *hldev)
+{
+ int exp_cap;
+ u16 lnk;
+
+ /* Get the negotiated link width and speed from PCI config space */
+ exp_cap = pci_find_capability(hldev->pdev, PCI_CAP_ID_EXP);
+ pci_read_config_word(hldev->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
+
+ if ((lnk & PCI_EXP_LNKSTA_CLS) != 1)
+ return VXGE_HW_ERR_INVALID_PCI_INFO;
+
+ switch ((lnk & PCI_EXP_LNKSTA_NLW) >> 4) {
+ case PCIE_LNK_WIDTH_RESRV:
+ case PCIE_LNK_X1:
+ case PCIE_LNK_X2:
+ case PCIE_LNK_X4:
+ case PCIE_LNK_X8:
+ break;
+ default:
+ return VXGE_HW_ERR_INVALID_PCI_INFO;
+ }
+
+ return VXGE_HW_OK;
+}
+
+static enum vxge_hw_status
+__vxge_hw_device_is_privilaged(struct __vxge_hw_device *hldev)
+{
+ if ((hldev->host_type == VXGE_HW_NO_MR_NO_SR_NORMAL_FUNCTION ||
+ hldev->host_type == VXGE_HW_MR_NO_SR_VH0_BASE_FUNCTION ||
+ hldev->host_type == VXGE_HW_NO_MR_SR_VH0_FUNCTION0) &&
+ (hldev->func_id == 0))
+ return VXGE_HW_OK;
+ else
+ return VXGE_HW_ERR_PRIVILAGED_OPEARATION;
+}
+
+/*
+ * vxge_hw_wrr_rebalance - Rebalance the RX_WRR and KDFC_WRR calandars.
+ * Rebalance the RX_WRR and KDFC_WRR calandars.
+ */
+static enum
+vxge_hw_status vxge_hw_wrr_rebalance(struct __vxge_hw_device *hldev)
+{
+ u64 val64;
+ u32 wrr_states[VXGE_HW_WEIGHTED_RR_SERVICE_STATES];
+ u32 i, j, how_often = 1;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ status = __vxge_hw_device_is_privilaged(hldev);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ /* Reset the priorities assigned to the WRR arbitration
+ phases for the receive traffic */
+ for (i = 0; i < VXGE_HW_WRR_RING_COUNT; i++)
+ writeq(0, ((&hldev->mrpcim_reg->rx_w_round_robin_0) + i));
+
+ /* Reset the transmit FIFO servicing calendar for FIFOs */
+ for (i = 0; i < VXGE_HW_WRR_FIFO_COUNT; i++) {
+ writeq(0, ((&hldev->mrpcim_reg->kdfc_w_round_robin_0) + i));
+ writeq(0, ((&hldev->mrpcim_reg->kdfc_w_round_robin_20) + i));
+ }
+
+ /* Assign WRR priority 0 for all FIFOs */
+ for (i = 1; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+ writeq(VXGE_HW_KDFC_FIFO_0_CTRL_WRR_NUMBER(0),
+ ((&hldev->mrpcim_reg->kdfc_fifo_0_ctrl) + i));
+
+ writeq(VXGE_HW_KDFC_FIFO_17_CTRL_WRR_NUMBER(0),
+ ((&hldev->mrpcim_reg->kdfc_fifo_17_ctrl) + i));
+ }
+
+ /* Reset to service non-offload doorbells */
+ writeq(0, &hldev->mrpcim_reg->kdfc_entry_type_sel_0);
+ writeq(0, &hldev->mrpcim_reg->kdfc_entry_type_sel_1);
+
+ /* Set priority 0 to all receive queues */
+ writeq(0, &hldev->mrpcim_reg->rx_queue_priority_0);
+ writeq(0, &hldev->mrpcim_reg->rx_queue_priority_1);
+ writeq(0, &hldev->mrpcim_reg->rx_queue_priority_2);
+
+ /* Initialize all the slots as unused */
+ for (i = 0; i < VXGE_HW_WEIGHTED_RR_SERVICE_STATES; i++)
+ wrr_states[i] = -1;
+
+ /* Prepare the Fifo service states */
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+ if (!hldev->config.vp_config[i].min_bandwidth)
+ continue;
+
+ how_often = VXGE_HW_VPATH_BANDWIDTH_MAX /
+ hldev->config.vp_config[i].min_bandwidth;
+ if (how_often) {
+
+ for (j = 0; j < VXGE_HW_WRR_FIFO_SERVICE_STATES;) {
+ if (wrr_states[j] == -1) {
+ wrr_states[j] = i;
+ /* Make sure each fifo is serviced
+ * atleast once */
+ if (i == j)
+ j += VXGE_HW_MAX_VIRTUAL_PATHS;
+ else
+ j += how_often;
+ } else
+ j++;
+ }
+ }
+ }
+
+ /* Fill the unused slots with 0 */
+ for (j = 0; j < VXGE_HW_WEIGHTED_RR_SERVICE_STATES; j++) {
+ if (wrr_states[j] == -1)
+ wrr_states[j] = 0;
+ }
+
+ /* Assign WRR priority number for FIFOs */
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+ writeq(VXGE_HW_KDFC_FIFO_0_CTRL_WRR_NUMBER(i),
+ ((&hldev->mrpcim_reg->kdfc_fifo_0_ctrl) + i));
+
+ writeq(VXGE_HW_KDFC_FIFO_17_CTRL_WRR_NUMBER(i),
+ ((&hldev->mrpcim_reg->kdfc_fifo_17_ctrl) + i));
+ }
+
+ /* Modify the servicing algorithm applied to the 3 types of doorbells.
+ i.e, none-offload, message and offload */
+ writeq(VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_0(0) |
+ VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_1(0) |
+ VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_2(0) |
+ VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_3(0) |
+ VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_4(1) |
+ VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_5(0) |
+ VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_6(0) |
+ VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_7(0),
+ &hldev->mrpcim_reg->kdfc_entry_type_sel_0);
+
+ writeq(VXGE_HW_KDFC_ENTRY_TYPE_SEL_1_NUMBER_8(1),
+ &hldev->mrpcim_reg->kdfc_entry_type_sel_1);
+
+ for (i = 0, j = 0; i < VXGE_HW_WRR_FIFO_COUNT; i++) {
+
+ val64 = VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_0(wrr_states[j++]);
+ val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_1(wrr_states[j++]);
+ val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_2(wrr_states[j++]);
+ val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_3(wrr_states[j++]);
+ val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_4(wrr_states[j++]);
+ val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_5(wrr_states[j++]);
+ val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_6(wrr_states[j++]);
+ val64 |= VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_7(wrr_states[j++]);
+
+ writeq(val64, (&hldev->mrpcim_reg->kdfc_w_round_robin_0 + i));
+ writeq(val64, (&hldev->mrpcim_reg->kdfc_w_round_robin_20 + i));
+ }
+
+ /* Set up the priorities assigned to receive queues */
+ writeq(VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_0(0) |
+ VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_1(1) |
+ VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_2(2) |
+ VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_3(3) |
+ VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_4(4) |
+ VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_5(5) |
+ VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_6(6) |
+ VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_7(7),
+ &hldev->mrpcim_reg->rx_queue_priority_0);
+
+ writeq(VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_8(8) |
+ VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_9(9) |
+ VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_10(10) |
+ VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_11(11) |
+ VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_12(12) |
+ VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_13(13) |
+ VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_14(14) |
+ VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_15(15),
+ &hldev->mrpcim_reg->rx_queue_priority_1);
+
+ writeq(VXGE_HW_RX_QUEUE_PRIORITY_2_RX_Q_NUMBER_16(16),
+ &hldev->mrpcim_reg->rx_queue_priority_2);
+
+ /* Initialize all the slots as unused */
+ for (i = 0; i < VXGE_HW_WEIGHTED_RR_SERVICE_STATES; i++)
+ wrr_states[i] = -1;
+
+ /* Prepare the Ring service states */
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+ if (!hldev->config.vp_config[i].min_bandwidth)
+ continue;
+
+ how_often = VXGE_HW_VPATH_BANDWIDTH_MAX /
+ hldev->config.vp_config[i].min_bandwidth;
+
+ if (how_often) {
+ for (j = 0; j < VXGE_HW_WRR_RING_SERVICE_STATES;) {
+ if (wrr_states[j] == -1) {
+ wrr_states[j] = i;
+ /* Make sure each ring is
+ * serviced atleast once */
+ if (i == j)
+ j += VXGE_HW_MAX_VIRTUAL_PATHS;
+ else
+ j += how_often;
+ } else
+ j++;
+ }
+ }
+ }
+
+ /* Fill the unused slots with 0 */
+ for (j = 0; j < VXGE_HW_WEIGHTED_RR_SERVICE_STATES; j++) {
+ if (wrr_states[j] == -1)
+ wrr_states[j] = 0;
+ }
+
+ for (i = 0, j = 0; i < VXGE_HW_WRR_RING_COUNT; i++) {
+ val64 = VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_0(
+ wrr_states[j++]);
+ val64 |= VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_1(
+ wrr_states[j++]);
+ val64 |= VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_2(
+ wrr_states[j++]);
+ val64 |= VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_3(
+ wrr_states[j++]);
+ val64 |= VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_4(
+ wrr_states[j++]);
+ val64 |= VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_5(
+ wrr_states[j++]);
+ val64 |= VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_6(
+ wrr_states[j++]);
+ val64 |= VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_7(
+ wrr_states[j++]);
+
+ writeq(val64, ((&hldev->mrpcim_reg->rx_w_round_robin_0) + i));
+ }
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_device_initialize
+ * Initialize Titan-V hardware.
+ */
+enum vxge_hw_status __vxge_hw_device_initialize(struct __vxge_hw_device *hldev)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ /* Validate the pci-e link width and speed */
+ status = __vxge_hw_verify_pci_e_info(hldev);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ vxge_hw_wrr_rebalance(hldev);
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_device_hw_info_get - Get the hw information
+ * Returns the vpath mask that has the bits set for each vpath allocated
+ * for the driver, FW version information and the first mac addresse for
+ * each vpath
+ */
+enum vxge_hw_status __devinit
+vxge_hw_device_hw_info_get(void __iomem *bar0,
+ struct vxge_hw_device_hw_info *hw_info)
+{
+ u32 i;
+ u64 val64;
+ struct vxge_hw_toc_reg __iomem *toc;
+ struct vxge_hw_mrpcim_reg __iomem *mrpcim_reg;
+ struct vxge_hw_common_reg __iomem *common_reg;
+ struct vxge_hw_vpath_reg __iomem *vpath_reg;
+ struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg;
+ enum vxge_hw_status status;
+
+ memset(hw_info, 0, sizeof(struct vxge_hw_device_hw_info));
+
+ toc = __vxge_hw_device_toc_get(bar0);
+ if (toc == NULL) {
+ status = VXGE_HW_ERR_CRITICAL;
+ goto exit;
+ }
+
+ val64 = readq(&toc->toc_common_pointer);
+ common_reg = (struct vxge_hw_common_reg __iomem *)(bar0 + val64);
+
+ status = __vxge_hw_device_vpath_reset_in_prog_check(
+ (u64 __iomem *)&common_reg->vpath_rst_in_prog);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ hw_info->vpath_mask = readq(&common_reg->vpath_assignments);
+
+ val64 = readq(&common_reg->host_type_assignments);
+
+ hw_info->host_type =
+ (u32)VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(val64);
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+ if (!((hw_info->vpath_mask) & vxge_mBIT(i)))
+ continue;
+
+ val64 = readq(&toc->toc_vpmgmt_pointer[i]);
+
+ vpmgmt_reg = (struct vxge_hw_vpmgmt_reg __iomem *)
+ (bar0 + val64);
+
+ hw_info->func_id = __vxge_hw_vpath_func_id_get(i, vpmgmt_reg);
+ if (__vxge_hw_device_access_rights_get(hw_info->host_type,
+ hw_info->func_id) &
+ VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM) {
+
+ val64 = readq(&toc->toc_mrpcim_pointer);
+
+ mrpcim_reg = (struct vxge_hw_mrpcim_reg __iomem *)
+ (bar0 + val64);
+
+ writeq(0, &mrpcim_reg->xgmac_gen_fw_memo_mask);
+ wmb();
+ }
+
+ val64 = readq(&toc->toc_vpath_pointer[i]);
+
+ vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64);
+
+ hw_info->function_mode =
+ __vxge_hw_vpath_pci_func_mode_get(i, vpath_reg);
+
+ status = __vxge_hw_vpath_fw_ver_get(i, vpath_reg, hw_info);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ status = __vxge_hw_vpath_card_info_get(i, vpath_reg, hw_info);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ break;
+ }
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+ if (!((hw_info->vpath_mask) & vxge_mBIT(i)))
+ continue;
+
+ val64 = readq(&toc->toc_vpath_pointer[i]);
+ vpath_reg = (struct vxge_hw_vpath_reg __iomem *)(bar0 + val64);
+
+ status = __vxge_hw_vpath_addr_get(i, vpath_reg,
+ hw_info->mac_addrs[i],
+ hw_info->mac_addr_masks[i]);
+ if (status != VXGE_HW_OK)
+ goto exit;
+ }
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_device_initialize - Initialize Titan device.
+ * Initialize Titan device. Note that all the arguments of this public API
+ * are 'IN', including @hldev. Driver cooperates with
+ * OS to find new Titan device, locate its PCI and memory spaces.
+ *
+ * When done, the driver allocates sizeof(struct __vxge_hw_device) bytes for HW
+ * to enable the latter to perform Titan hardware initialization.
+ */
+enum vxge_hw_status __devinit
+vxge_hw_device_initialize(
+ struct __vxge_hw_device **devh,
+ struct vxge_hw_device_attr *attr,
+ struct vxge_hw_device_config *device_config)
+{
+ u32 i;
+ u32 nblocks = 0;
+ struct __vxge_hw_device *hldev = NULL;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ status = __vxge_hw_device_config_check(device_config);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ hldev = (struct __vxge_hw_device *)
+ vmalloc(sizeof(struct __vxge_hw_device));
+ if (hldev == NULL) {
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto exit;
+ }
+
+ memset(hldev, 0, sizeof(struct __vxge_hw_device));
+ hldev->magic = VXGE_HW_DEVICE_MAGIC;
+
+ vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_ALL);
+
+ /* apply config */
+ memcpy(&hldev->config, device_config,
+ sizeof(struct vxge_hw_device_config));
+
+ hldev->bar0 = attr->bar0;
+ hldev->bar1 = attr->bar1;
+ hldev->bar2 = attr->bar2;
+ hldev->pdev = attr->pdev;
+
+ hldev->uld_callbacks.link_up = attr->uld_callbacks.link_up;
+ hldev->uld_callbacks.link_down = attr->uld_callbacks.link_down;
+ hldev->uld_callbacks.crit_err = attr->uld_callbacks.crit_err;
+
+ __vxge_hw_device_pci_e_init(hldev);
+
+ status = __vxge_hw_device_reg_addr_get(hldev);
+ if (status != VXGE_HW_OK)
+ goto exit;
+ __vxge_hw_device_id_get(hldev);
+
+ __vxge_hw_device_host_info_get(hldev);
+
+ /* Incrementing for stats blocks */
+ nblocks++;
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+ if (!(hldev->vpath_assignments & vxge_mBIT(i)))
+ continue;
+
+ if (device_config->vp_config[i].ring.enable ==
+ VXGE_HW_RING_ENABLE)
+ nblocks += device_config->vp_config[i].ring.ring_blocks;
+
+ if (device_config->vp_config[i].fifo.enable ==
+ VXGE_HW_FIFO_ENABLE)
+ nblocks += device_config->vp_config[i].fifo.fifo_blocks;
+ nblocks++;
+ }
+
+ if (__vxge_hw_blockpool_create(hldev,
+ &hldev->block_pool,
+ device_config->dma_blockpool_initial + nblocks,
+ device_config->dma_blockpool_max + nblocks) != VXGE_HW_OK) {
+
+ vxge_hw_device_terminate(hldev);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto exit;
+ }
+
+ status = __vxge_hw_device_initialize(hldev);
+
+ if (status != VXGE_HW_OK) {
+ vxge_hw_device_terminate(hldev);
+ goto exit;
+ }
+
+ *devh = hldev;
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_device_terminate - Terminate Titan device.
+ * Terminate HW device.
+ */
+void
+vxge_hw_device_terminate(struct __vxge_hw_device *hldev)
+{
+ vxge_assert(hldev->magic == VXGE_HW_DEVICE_MAGIC);
+
+ hldev->magic = VXGE_HW_DEVICE_DEAD;
+ __vxge_hw_blockpool_destroy(&hldev->block_pool);
+ vfree(hldev);
+}
+
+/*
+ * vxge_hw_device_stats_get - Get the device hw statistics.
+ * Returns the vpath h/w stats for the device.
+ */
+enum vxge_hw_status
+vxge_hw_device_stats_get(struct __vxge_hw_device *hldev,
+ struct vxge_hw_device_stats_hw_info *hw_stats)
+{
+ u32 i;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+ if (!(hldev->vpaths_deployed & vxge_mBIT(i)) ||
+ (hldev->virtual_paths[i].vp_open ==
+ VXGE_HW_VP_NOT_OPEN))
+ continue;
+
+ memcpy(hldev->virtual_paths[i].hw_stats_sav,
+ hldev->virtual_paths[i].hw_stats,
+ sizeof(struct vxge_hw_vpath_stats_hw_info));
+
+ status = __vxge_hw_vpath_stats_get(
+ &hldev->virtual_paths[i],
+ hldev->virtual_paths[i].hw_stats);
+ }
+
+ memcpy(hw_stats, &hldev->stats.hw_dev_info_stats,
+ sizeof(struct vxge_hw_device_stats_hw_info));
+
+ return status;
+}
+
+/*
+ * vxge_hw_driver_stats_get - Get the device sw statistics.
+ * Returns the vpath s/w stats for the device.
+ */
+enum vxge_hw_status vxge_hw_driver_stats_get(
+ struct __vxge_hw_device *hldev,
+ struct vxge_hw_device_stats_sw_info *sw_stats)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ memcpy(sw_stats, &hldev->stats.sw_dev_info_stats,
+ sizeof(struct vxge_hw_device_stats_sw_info));
+
+ return status;
+}
+
+/*
+ * vxge_hw_mrpcim_stats_access - Access the statistics from the given location
+ * and offset and perform an operation
+ * Get the statistics from the given location and offset.
+ */
+enum vxge_hw_status
+vxge_hw_mrpcim_stats_access(struct __vxge_hw_device *hldev,
+ u32 operation, u32 location, u32 offset, u64 *stat)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ status = __vxge_hw_device_is_privilaged(hldev);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ val64 = VXGE_HW_XMAC_STATS_SYS_CMD_OP(operation) |
+ VXGE_HW_XMAC_STATS_SYS_CMD_STROBE |
+ VXGE_HW_XMAC_STATS_SYS_CMD_LOC_SEL(location) |
+ VXGE_HW_XMAC_STATS_SYS_CMD_OFFSET_SEL(offset);
+
+ status = __vxge_hw_pio_mem_write64(val64,
+ &hldev->mrpcim_reg->xmac_stats_sys_cmd,
+ VXGE_HW_XMAC_STATS_SYS_CMD_STROBE,
+ hldev->config.device_poll_millis);
+
+ if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ))
+ *stat = readq(&hldev->mrpcim_reg->xmac_stats_sys_data);
+ else
+ *stat = 0;
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_device_xmac_aggr_stats_get - Get the Statistics on aggregate port
+ * Get the Statistics on aggregate port
+ */
+enum vxge_hw_status
+vxge_hw_device_xmac_aggr_stats_get(struct __vxge_hw_device *hldev, u32 port,
+ struct vxge_hw_xmac_aggr_stats *aggr_stats)
+{
+ u64 *val64;
+ int i;
+ u32 offset = VXGE_HW_STATS_AGGRn_OFFSET;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ val64 = (u64 *)aggr_stats;
+
+ status = __vxge_hw_device_is_privilaged(hldev);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ for (i = 0; i < sizeof(struct vxge_hw_xmac_aggr_stats) / 8; i++) {
+ status = vxge_hw_mrpcim_stats_access(hldev,
+ VXGE_HW_STATS_OP_READ,
+ VXGE_HW_STATS_LOC_AGGR,
+ ((offset + (104 * port)) >> 3), val64);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ offset += 8;
+ val64++;
+ }
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_device_xmac_port_stats_get - Get the Statistics on a port
+ * Get the Statistics on port
+ */
+enum vxge_hw_status
+vxge_hw_device_xmac_port_stats_get(struct __vxge_hw_device *hldev, u32 port,
+ struct vxge_hw_xmac_port_stats *port_stats)
+{
+ u64 *val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ int i;
+ u32 offset = 0x0;
+ val64 = (u64 *) port_stats;
+
+ status = __vxge_hw_device_is_privilaged(hldev);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ for (i = 0; i < sizeof(struct vxge_hw_xmac_port_stats) / 8; i++) {
+ status = vxge_hw_mrpcim_stats_access(hldev,
+ VXGE_HW_STATS_OP_READ,
+ VXGE_HW_STATS_LOC_AGGR,
+ ((offset + (608 * port)) >> 3), val64);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ offset += 8;
+ val64++;
+ }
+
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_device_xmac_stats_get - Get the XMAC Statistics
+ * Get the XMAC Statistics
+ */
+enum vxge_hw_status
+vxge_hw_device_xmac_stats_get(struct __vxge_hw_device *hldev,
+ struct vxge_hw_xmac_stats *xmac_stats)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ u32 i;
+
+ status = vxge_hw_device_xmac_aggr_stats_get(hldev,
+ 0, &xmac_stats->aggr_stats[0]);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ status = vxge_hw_device_xmac_aggr_stats_get(hldev,
+ 1, &xmac_stats->aggr_stats[1]);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ for (i = 0; i <= VXGE_HW_MAC_MAX_MAC_PORT_ID; i++) {
+
+ status = vxge_hw_device_xmac_port_stats_get(hldev,
+ i, &xmac_stats->port_stats[i]);
+ if (status != VXGE_HW_OK)
+ goto exit;
+ }
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+ if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
+ continue;
+
+ status = __vxge_hw_vpath_xmac_tx_stats_get(
+ &hldev->virtual_paths[i],
+ &xmac_stats->vpath_tx_stats[i]);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ status = __vxge_hw_vpath_xmac_rx_stats_get(
+ &hldev->virtual_paths[i],
+ &xmac_stats->vpath_rx_stats[i]);
+ if (status != VXGE_HW_OK)
+ goto exit;
+ }
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_device_debug_set - Set the debug module, level and timestamp
+ * This routine is used to dynamically change the debug output
+ */
+void vxge_hw_device_debug_set(struct __vxge_hw_device *hldev,
+ enum vxge_debug_level level, u32 mask)
+{
+ if (hldev == NULL)
+ return;
+
+#if defined(VXGE_DEBUG_TRACE_MASK) || \
+ defined(VXGE_DEBUG_ERR_MASK)
+ hldev->debug_module_mask = mask;
+ hldev->debug_level = level;
+#endif
+
+#if defined(VXGE_DEBUG_ERR_MASK)
+ hldev->level_err = level & VXGE_ERR;
+#endif
+
+#if defined(VXGE_DEBUG_TRACE_MASK)
+ hldev->level_trace = level & VXGE_TRACE;
+#endif
+}
+
+/*
+ * vxge_hw_device_error_level_get - Get the error level
+ * This routine returns the current error level set
+ */
+u32 vxge_hw_device_error_level_get(struct __vxge_hw_device *hldev)
+{
+#if defined(VXGE_DEBUG_ERR_MASK)
+ if (hldev == NULL)
+ return VXGE_ERR;
+ else
+ return hldev->level_err;
+#else
+ return 0;
+#endif
+}
+
+/*
+ * vxge_hw_device_trace_level_get - Get the trace level
+ * This routine returns the current trace level set
+ */
+u32 vxge_hw_device_trace_level_get(struct __vxge_hw_device *hldev)
+{
+#if defined(VXGE_DEBUG_TRACE_MASK)
+ if (hldev == NULL)
+ return VXGE_TRACE;
+ else
+ return hldev->level_trace;
+#else
+ return 0;
+#endif
+}
+/*
+ * vxge_hw_device_debug_mask_get - Get the debug mask
+ * This routine returns the current debug mask set
+ */
+u32 vxge_hw_device_debug_mask_get(struct __vxge_hw_device *hldev)
+{
+#if defined(VXGE_DEBUG_TRACE_MASK) || defined(VXGE_DEBUG_ERR_MASK)
+ if (hldev == NULL)
+ return 0;
+ return hldev->debug_module_mask;
+#else
+ return 0;
+#endif
+}
+
+/*
+ * vxge_hw_getpause_data -Pause frame frame generation and reception.
+ * Returns the Pause frame generation and reception capability of the NIC.
+ */
+enum vxge_hw_status vxge_hw_device_getpause_data(struct __vxge_hw_device *hldev,
+ u32 port, u32 *tx, u32 *rx)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
+ status = VXGE_HW_ERR_INVALID_DEVICE;
+ goto exit;
+ }
+
+ if (port > VXGE_HW_MAC_MAX_MAC_PORT_ID) {
+ status = VXGE_HW_ERR_INVALID_PORT;
+ goto exit;
+ }
+
+ if (!(hldev->access_rights & VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) {
+ status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
+ goto exit;
+ }
+
+ val64 = readq(&hldev->mrpcim_reg->rxmac_pause_cfg_port[port]);
+ if (val64 & VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN)
+ *tx = 1;
+ if (val64 & VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN)
+ *rx = 1;
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_device_setpause_data - set/reset pause frame generation.
+ * It can be used to set or reset Pause frame generation or reception
+ * support of the NIC.
+ */
+
+enum vxge_hw_status vxge_hw_device_setpause_data(struct __vxge_hw_device *hldev,
+ u32 port, u32 tx, u32 rx)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
+ status = VXGE_HW_ERR_INVALID_DEVICE;
+ goto exit;
+ }
+
+ if (port > VXGE_HW_MAC_MAX_MAC_PORT_ID) {
+ status = VXGE_HW_ERR_INVALID_PORT;
+ goto exit;
+ }
+
+ status = __vxge_hw_device_is_privilaged(hldev);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ val64 = readq(&hldev->mrpcim_reg->rxmac_pause_cfg_port[port]);
+ if (tx)
+ val64 |= VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN;
+ else
+ val64 &= ~VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN;
+ if (rx)
+ val64 |= VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN;
+ else
+ val64 &= ~VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN;
+
+ writeq(val64, &hldev->mrpcim_reg->rxmac_pause_cfg_port[port]);
+exit:
+ return status;
+}
+
+u16 vxge_hw_device_link_width_get(struct __vxge_hw_device *hldev)
+{
+ int link_width, exp_cap;
+ u16 lnk;
+
+ exp_cap = pci_find_capability(hldev->pdev, PCI_CAP_ID_EXP);
+ pci_read_config_word(hldev->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
+ link_width = (lnk & VXGE_HW_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4;
+ return link_width;
+}
+
+/*
+ * __vxge_hw_ring_block_memblock_idx - Return the memblock index
+ * This function returns the index of memory block
+ */
+static inline u32
+__vxge_hw_ring_block_memblock_idx(u8 *block)
+{
+ return (u32)*((u64 *)(block + VXGE_HW_RING_MEMBLOCK_IDX_OFFSET));
+}
+
+/*
+ * __vxge_hw_ring_block_memblock_idx_set - Sets the memblock index
+ * This function sets index to a memory block
+ */
+static inline void
+__vxge_hw_ring_block_memblock_idx_set(u8 *block, u32 memblock_idx)
+{
+ *((u64 *)(block + VXGE_HW_RING_MEMBLOCK_IDX_OFFSET)) = memblock_idx;
+}
+
+/*
+ * __vxge_hw_ring_block_next_pointer_set - Sets the next block pointer
+ * in RxD block
+ * Sets the next block pointer in RxD block
+ */
+static inline void
+__vxge_hw_ring_block_next_pointer_set(u8 *block, dma_addr_t dma_next)
+{
+ *((u64 *)(block + VXGE_HW_RING_NEXT_BLOCK_POINTER_OFFSET)) = dma_next;
+}
+
+/*
+ * __vxge_hw_ring_first_block_address_get - Returns the dma address of the
+ * first block
+ * Returns the dma address of the first RxD block
+ */
+u64 __vxge_hw_ring_first_block_address_get(struct __vxge_hw_ring *ring)
+{
+ struct vxge_hw_mempool_dma *dma_object;
+
+ dma_object = ring->mempool->memblocks_dma_arr;
+ vxge_assert(dma_object != NULL);
+
+ return dma_object->addr;
+}
+
+/*
+ * __vxge_hw_ring_item_dma_addr - Return the dma address of an item
+ * This function returns the dma address of a given item
+ */
+static dma_addr_t __vxge_hw_ring_item_dma_addr(struct vxge_hw_mempool *mempoolh,
+ void *item)
+{
+ u32 memblock_idx;
+ void *memblock;
+ struct vxge_hw_mempool_dma *memblock_dma_object;
+ ptrdiff_t dma_item_offset;
+
+ /* get owner memblock index */
+ memblock_idx = __vxge_hw_ring_block_memblock_idx(item);
+
+ /* get owner memblock by memblock index */
+ memblock = mempoolh->memblocks_arr[memblock_idx];
+
+ /* get memblock DMA object by memblock index */
+ memblock_dma_object = mempoolh->memblocks_dma_arr + memblock_idx;
+
+ /* calculate offset in the memblock of this item */
+ dma_item_offset = (u8 *)item - (u8 *)memblock;
+
+ return memblock_dma_object->addr + dma_item_offset;
+}
+
+/*
+ * __vxge_hw_ring_rxdblock_link - Link the RxD blocks
+ * This function returns the dma address of a given item
+ */
+static void __vxge_hw_ring_rxdblock_link(struct vxge_hw_mempool *mempoolh,
+ struct __vxge_hw_ring *ring, u32 from,
+ u32 to)
+{
+ u8 *to_item , *from_item;
+ dma_addr_t to_dma;
+
+ /* get "from" RxD block */
+ from_item = mempoolh->items_arr[from];
+ vxge_assert(from_item);
+
+ /* get "to" RxD block */
+ to_item = mempoolh->items_arr[to];
+ vxge_assert(to_item);
+
+ /* return address of the beginning of previous RxD block */
+ to_dma = __vxge_hw_ring_item_dma_addr(mempoolh, to_item);
+
+ /* set next pointer for this RxD block to point on
+ * previous item's DMA start address */
+ __vxge_hw_ring_block_next_pointer_set(from_item, to_dma);
+}
+
+/*
+ * __vxge_hw_ring_mempool_item_alloc - Allocate List blocks for RxD
+ * block callback
+ * This function is callback passed to __vxge_hw_mempool_create to create memory
+ * pool for RxD block
+ */
+static void
+__vxge_hw_ring_mempool_item_alloc(struct vxge_hw_mempool *mempoolh,
+ u32 memblock_index,
+ struct vxge_hw_mempool_dma *dma_object,
+ u32 index, u32 is_last)
+{
+ u32 i;
+ void *item = mempoolh->items_arr[index];
+ struct __vxge_hw_ring *ring =
+ (struct __vxge_hw_ring *)mempoolh->userdata;
+
+ /* format rxds array */
+ for (i = 0; i < ring->rxds_per_block; i++) {
+ void *rxdblock_priv;
+ void *uld_priv;
+ struct vxge_hw_ring_rxd_1 *rxdp;
+
+ u32 reserve_index = ring->channel.reserve_ptr -
+ (index * ring->rxds_per_block + i + 1);
+ u32 memblock_item_idx;
+
+ ring->channel.reserve_arr[reserve_index] = ((u8 *)item) +
+ i * ring->rxd_size;
+
+ /* Note: memblock_item_idx is index of the item within
+ * the memblock. For instance, in case of three RxD-blocks
+ * per memblock this value can be 0, 1 or 2. */
+ rxdblock_priv = __vxge_hw_mempool_item_priv(mempoolh,
+ memblock_index, item,
+ &memblock_item_idx);
+
+ rxdp = (struct vxge_hw_ring_rxd_1 *)
+ ring->channel.reserve_arr[reserve_index];
+
+ uld_priv = ((u8 *)rxdblock_priv + ring->rxd_priv_size * i);
+
+ /* pre-format Host_Control */
+ rxdp->host_control = (u64)(size_t)uld_priv;
+ }
+
+ __vxge_hw_ring_block_memblock_idx_set(item, memblock_index);
+
+ if (is_last) {
+ /* link last one with first one */
+ __vxge_hw_ring_rxdblock_link(mempoolh, ring, index, 0);
+ }
+
+ if (index > 0) {
+ /* link this RxD block with previous one */
+ __vxge_hw_ring_rxdblock_link(mempoolh, ring, index - 1, index);
+ }
+
+ return;
+}
+
+/*
+ * __vxge_hw_ring_initial_replenish - Initial replenish of RxDs
+ * This function replenishes the RxDs from reserve array to work array
+ */
+enum vxge_hw_status
+vxge_hw_ring_replenish(struct __vxge_hw_ring *ring, u16 min_flag)
+{
+ void *rxd;
+ int i = 0;
+ struct __vxge_hw_channel *channel;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ channel = &ring->channel;
+
+ while (vxge_hw_channel_dtr_count(channel) > 0) {
+
+ status = vxge_hw_ring_rxd_reserve(ring, &rxd);
+
+ vxge_assert(status == VXGE_HW_OK);
+
+ if (ring->rxd_init) {
+ status = ring->rxd_init(rxd, channel->userdata);
+ if (status != VXGE_HW_OK) {
+ vxge_hw_ring_rxd_free(ring, rxd);
+ goto exit;
+ }
+ }
+
+ vxge_hw_ring_rxd_post(ring, rxd);
+ if (min_flag) {
+ i++;
+ if (i == VXGE_HW_RING_MIN_BUFF_ALLOCATION)
+ break;
+ }
+ }
+ status = VXGE_HW_OK;
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_ring_create - Create a Ring
+ * This function creates Ring and initializes it.
+ *
+ */
+enum vxge_hw_status
+__vxge_hw_ring_create(struct __vxge_hw_vpath_handle *vp,
+ struct vxge_hw_ring_attr *attr)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_ring *ring;
+ u32 ring_length;
+ struct vxge_hw_ring_config *config;
+ struct __vxge_hw_device *hldev;
+ u32 vp_id;
+ struct vxge_hw_mempool_cbs ring_mp_callback;
+
+ if ((vp == NULL) || (attr == NULL)) {
+ status = VXGE_HW_FAIL;
+ goto exit;
+ }
+
+ hldev = vp->vpath->hldev;
+ vp_id = vp->vpath->vp_id;
+
+ config = &hldev->config.vp_config[vp_id].ring;
+
+ ring_length = config->ring_blocks *
+ vxge_hw_ring_rxds_per_block_get(config->buffer_mode);
+
+ ring = (struct __vxge_hw_ring *)__vxge_hw_channel_allocate(vp,
+ VXGE_HW_CHANNEL_TYPE_RING,
+ ring_length,
+ attr->per_rxd_space,
+ attr->userdata);
+
+ if (ring == NULL) {
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto exit;
+ }
+
+ vp->vpath->ringh = ring;
+ ring->vp_id = vp_id;
+ ring->vp_reg = vp->vpath->vp_reg;
+ ring->common_reg = hldev->common_reg;
+ ring->stats = &vp->vpath->sw_stats->ring_stats;
+ ring->config = config;
+ ring->callback = attr->callback;
+ ring->rxd_init = attr->rxd_init;
+ ring->rxd_term = attr->rxd_term;
+ ring->buffer_mode = config->buffer_mode;
+ ring->rxds_limit = config->rxds_limit;
+
+ ring->rxd_size = vxge_hw_ring_rxd_size_get(config->buffer_mode);
+ ring->rxd_priv_size =
+ sizeof(struct __vxge_hw_ring_rxd_priv) + attr->per_rxd_space;
+ ring->per_rxd_space = attr->per_rxd_space;
+
+ ring->rxd_priv_size =
+ ((ring->rxd_priv_size + VXGE_CACHE_LINE_SIZE - 1) /
+ VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE;
+
+ /* how many RxDs can fit into one block. Depends on configured
+ * buffer_mode. */
+ ring->rxds_per_block =
+ vxge_hw_ring_rxds_per_block_get(config->buffer_mode);
+
+ /* calculate actual RxD block private size */
+ ring->rxdblock_priv_size = ring->rxd_priv_size * ring->rxds_per_block;
+ ring_mp_callback.item_func_alloc = __vxge_hw_ring_mempool_item_alloc;
+ ring->mempool = __vxge_hw_mempool_create(hldev,
+ VXGE_HW_BLOCK_SIZE,
+ VXGE_HW_BLOCK_SIZE,
+ ring->rxdblock_priv_size,
+ ring->config->ring_blocks,
+ ring->config->ring_blocks,
+ &ring_mp_callback,
+ ring);
+
+ if (ring->mempool == NULL) {
+ __vxge_hw_ring_delete(vp);
+ return VXGE_HW_ERR_OUT_OF_MEMORY;
+ }
+
+ status = __vxge_hw_channel_initialize(&ring->channel);
+ if (status != VXGE_HW_OK) {
+ __vxge_hw_ring_delete(vp);
+ goto exit;
+ }
+
+ /* Note:
+ * Specifying rxd_init callback means two things:
+ * 1) rxds need to be initialized by driver at channel-open time;
+ * 2) rxds need to be posted at channel-open time
+ * (that's what the initial_replenish() below does)
+ * Currently we don't have a case when the 1) is done without the 2).
+ */
+ if (ring->rxd_init) {
+ status = vxge_hw_ring_replenish(ring, 1);
+ if (status != VXGE_HW_OK) {
+ __vxge_hw_ring_delete(vp);
+ goto exit;
+ }
+ }
+
+ /* initial replenish will increment the counter in its post() routine,
+ * we have to reset it */
+ ring->stats->common_stats.usage_cnt = 0;
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_ring_abort - Returns the RxD
+ * This function terminates the RxDs of ring
+ */
+enum vxge_hw_status __vxge_hw_ring_abort(struct __vxge_hw_ring *ring)
+{
+ void *rxdh;
+ struct __vxge_hw_channel *channel;
+
+ channel = &ring->channel;
+
+ for (;;) {
+ vxge_hw_channel_dtr_try_complete(channel, &rxdh);
+
+ if (rxdh == NULL)
+ break;
+
+ vxge_hw_channel_dtr_complete(channel);
+
+ if (ring->rxd_term)
+ ring->rxd_term(rxdh, VXGE_HW_RXD_STATE_POSTED,
+ channel->userdata);
+
+ vxge_hw_channel_dtr_free(channel, rxdh);
+ }
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_ring_reset - Resets the ring
+ * This function resets the ring during vpath reset operation
+ */
+enum vxge_hw_status __vxge_hw_ring_reset(struct __vxge_hw_ring *ring)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_channel *channel;
+
+ channel = &ring->channel;
+
+ __vxge_hw_ring_abort(ring);
+
+ status = __vxge_hw_channel_reset(channel);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ if (ring->rxd_init) {
+ status = vxge_hw_ring_replenish(ring, 1);
+ if (status != VXGE_HW_OK)
+ goto exit;
+ }
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_ring_delete - Removes the ring
+ * This function freeup the memory pool and removes the ring
+ */
+enum vxge_hw_status __vxge_hw_ring_delete(struct __vxge_hw_vpath_handle *vp)
+{
+ struct __vxge_hw_ring *ring = vp->vpath->ringh;
+
+ __vxge_hw_ring_abort(ring);
+
+ if (ring->mempool)
+ __vxge_hw_mempool_destroy(ring->mempool);
+
+ vp->vpath->ringh = NULL;
+ __vxge_hw_channel_free(&ring->channel);
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_mempool_grow
+ * Will resize mempool up to %num_allocate value.
+ */
+enum vxge_hw_status
+__vxge_hw_mempool_grow(struct vxge_hw_mempool *mempool, u32 num_allocate,
+ u32 *num_allocated)
+{
+ u32 i, first_time = mempool->memblocks_allocated == 0 ? 1 : 0;
+ u32 n_items = mempool->items_per_memblock;
+ u32 start_block_idx = mempool->memblocks_allocated;
+ u32 end_block_idx = mempool->memblocks_allocated + num_allocate;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ *num_allocated = 0;
+
+ if (end_block_idx > mempool->memblocks_max) {
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto exit;
+ }
+
+ for (i = start_block_idx; i < end_block_idx; i++) {
+ u32 j;
+ u32 is_last = ((end_block_idx - 1) == i);
+ struct vxge_hw_mempool_dma *dma_object =
+ mempool->memblocks_dma_arr + i;
+ void *the_memblock;
+
+ /* allocate memblock's private part. Each DMA memblock
+ * has a space allocated for item's private usage upon
+ * mempool's user request. Each time mempool grows, it will
+ * allocate new memblock and its private part at once.
+ * This helps to minimize memory usage a lot. */
+ mempool->memblocks_priv_arr[i] =
+ vmalloc(mempool->items_priv_size * n_items);
+ if (mempool->memblocks_priv_arr[i] == NULL) {
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto exit;
+ }
+
+ memset(mempool->memblocks_priv_arr[i], 0,
+ mempool->items_priv_size * n_items);
+
+ /* allocate DMA-capable memblock */
+ mempool->memblocks_arr[i] =
+ __vxge_hw_blockpool_malloc(mempool->devh,
+ mempool->memblock_size, dma_object);
+ if (mempool->memblocks_arr[i] == NULL) {
+ vfree(mempool->memblocks_priv_arr[i]);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto exit;
+ }
+
+ (*num_allocated)++;
+ mempool->memblocks_allocated++;
+
+ memset(mempool->memblocks_arr[i], 0, mempool->memblock_size);
+
+ the_memblock = mempool->memblocks_arr[i];
+
+ /* fill the items hash array */
+ for (j = 0; j < n_items; j++) {
+ u32 index = i * n_items + j;
+
+ if (first_time && index >= mempool->items_initial)
+ break;
+
+ mempool->items_arr[index] =
+ ((char *)the_memblock + j*mempool->item_size);
+
+ /* let caller to do more job on each item */
+ if (mempool->item_func_alloc != NULL)
+ mempool->item_func_alloc(mempool, i,
+ dma_object, index, is_last);
+
+ mempool->items_current = index + 1;
+ }
+
+ if (first_time && mempool->items_current ==
+ mempool->items_initial)
+ break;
+ }
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_mempool_create
+ * This function will create memory pool object. Pool may grow but will
+ * never shrink. Pool consists of number of dynamically allocated blocks
+ * with size enough to hold %items_initial number of items. Memory is
+ * DMA-able but client must map/unmap before interoperating with the device.
+ */
+struct vxge_hw_mempool*
+__vxge_hw_mempool_create(
+ struct __vxge_hw_device *devh,
+ u32 memblock_size,
+ u32 item_size,
+ u32 items_priv_size,
+ u32 items_initial,
+ u32 items_max,
+ struct vxge_hw_mempool_cbs *mp_callback,
+ void *userdata)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ u32 memblocks_to_allocate;
+ struct vxge_hw_mempool *mempool = NULL;
+ u32 allocated;
+
+ if (memblock_size < item_size) {
+ status = VXGE_HW_FAIL;
+ goto exit;
+ }
+
+ mempool = (struct vxge_hw_mempool *)
+ vmalloc(sizeof(struct vxge_hw_mempool));
+ if (mempool == NULL) {
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto exit;
+ }
+ memset(mempool, 0, sizeof(struct vxge_hw_mempool));
+
+ mempool->devh = devh;
+ mempool->memblock_size = memblock_size;
+ mempool->items_max = items_max;
+ mempool->items_initial = items_initial;
+ mempool->item_size = item_size;
+ mempool->items_priv_size = items_priv_size;
+ mempool->item_func_alloc = mp_callback->item_func_alloc;
+ mempool->userdata = userdata;
+
+ mempool->memblocks_allocated = 0;
+
+ mempool->items_per_memblock = memblock_size / item_size;
+
+ mempool->memblocks_max = (items_max + mempool->items_per_memblock - 1) /
+ mempool->items_per_memblock;
+
+ /* allocate array of memblocks */
+ mempool->memblocks_arr =
+ (void **) vmalloc(sizeof(void *) * mempool->memblocks_max);
+ if (mempool->memblocks_arr == NULL) {
+ __vxge_hw_mempool_destroy(mempool);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ mempool = NULL;
+ goto exit;
+ }
+ memset(mempool->memblocks_arr, 0,
+ sizeof(void *) * mempool->memblocks_max);
+
+ /* allocate array of private parts of items per memblocks */
+ mempool->memblocks_priv_arr =
+ (void **) vmalloc(sizeof(void *) * mempool->memblocks_max);
+ if (mempool->memblocks_priv_arr == NULL) {
+ __vxge_hw_mempool_destroy(mempool);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ mempool = NULL;
+ goto exit;
+ }
+ memset(mempool->memblocks_priv_arr, 0,
+ sizeof(void *) * mempool->memblocks_max);
+
+ /* allocate array of memblocks DMA objects */
+ mempool->memblocks_dma_arr = (struct vxge_hw_mempool_dma *)
+ vmalloc(sizeof(struct vxge_hw_mempool_dma) *
+ mempool->memblocks_max);
+
+ if (mempool->memblocks_dma_arr == NULL) {
+ __vxge_hw_mempool_destroy(mempool);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ mempool = NULL;
+ goto exit;
+ }
+ memset(mempool->memblocks_dma_arr, 0,
+ sizeof(struct vxge_hw_mempool_dma) *
+ mempool->memblocks_max);
+
+ /* allocate hash array of items */
+ mempool->items_arr =
+ (void **) vmalloc(sizeof(void *) * mempool->items_max);
+ if (mempool->items_arr == NULL) {
+ __vxge_hw_mempool_destroy(mempool);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ mempool = NULL;
+ goto exit;
+ }
+ memset(mempool->items_arr, 0, sizeof(void *) * mempool->items_max);
+
+ /* calculate initial number of memblocks */
+ memblocks_to_allocate = (mempool->items_initial +
+ mempool->items_per_memblock - 1) /
+ mempool->items_per_memblock;
+
+ /* pre-allocate the mempool */
+ status = __vxge_hw_mempool_grow(mempool, memblocks_to_allocate,
+ &allocated);
+ if (status != VXGE_HW_OK) {
+ __vxge_hw_mempool_destroy(mempool);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ mempool = NULL;
+ goto exit;
+ }
+
+exit:
+ return mempool;
+}
+
+/*
+ * vxge_hw_mempool_destroy
+ */
+void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool)
+{
+ u32 i, j;
+ struct __vxge_hw_device *devh = mempool->devh;
+
+ for (i = 0; i < mempool->memblocks_allocated; i++) {
+ struct vxge_hw_mempool_dma *dma_object;
+
+ vxge_assert(mempool->memblocks_arr[i]);
+ vxge_assert(mempool->memblocks_dma_arr + i);
+
+ dma_object = mempool->memblocks_dma_arr + i;
+
+ for (j = 0; j < mempool->items_per_memblock; j++) {
+ u32 index = i * mempool->items_per_memblock + j;
+
+ /* to skip last partially filled(if any) memblock */
+ if (index >= mempool->items_current)
+ break;
+ }
+
+ vfree(mempool->memblocks_priv_arr[i]);
+
+ __vxge_hw_blockpool_free(devh, mempool->memblocks_arr[i],
+ mempool->memblock_size, dma_object);
+ }
+
+ if (mempool->items_arr)
+ vfree(mempool->items_arr);
+
+ if (mempool->memblocks_dma_arr)
+ vfree(mempool->memblocks_dma_arr);
+
+ if (mempool->memblocks_priv_arr)
+ vfree(mempool->memblocks_priv_arr);
+
+ if (mempool->memblocks_arr)
+ vfree(mempool->memblocks_arr);
+
+ vfree(mempool);
+}
+
+/*
+ * __vxge_hw_device_fifo_config_check - Check fifo configuration.
+ * Check the fifo configuration
+ */
+enum vxge_hw_status
+__vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config)
+{
+ if ((fifo_config->fifo_blocks < VXGE_HW_MIN_FIFO_BLOCKS) ||
+ (fifo_config->fifo_blocks > VXGE_HW_MAX_FIFO_BLOCKS))
+ return VXGE_HW_BADCFG_FIFO_BLOCKS;
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_device_vpath_config_check - Check vpath configuration.
+ * Check the vpath configuration
+ */
+enum vxge_hw_status
+__vxge_hw_device_vpath_config_check(struct vxge_hw_vp_config *vp_config)
+{
+ enum vxge_hw_status status;
+
+ if ((vp_config->min_bandwidth < VXGE_HW_VPATH_BANDWIDTH_MIN) ||
+ (vp_config->min_bandwidth >
+ VXGE_HW_VPATH_BANDWIDTH_MAX))
+ return VXGE_HW_BADCFG_VPATH_MIN_BANDWIDTH;
+
+ status = __vxge_hw_device_fifo_config_check(&vp_config->fifo);
+ if (status != VXGE_HW_OK)
+ return status;
+
+ if ((vp_config->mtu != VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) &&
+ ((vp_config->mtu < VXGE_HW_VPATH_MIN_INITIAL_MTU) ||
+ (vp_config->mtu > VXGE_HW_VPATH_MAX_INITIAL_MTU)))
+ return VXGE_HW_BADCFG_VPATH_MTU;
+
+ if ((vp_config->rpa_strip_vlan_tag !=
+ VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) &&
+ (vp_config->rpa_strip_vlan_tag !=
+ VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE) &&
+ (vp_config->rpa_strip_vlan_tag !=
+ VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_DISABLE))
+ return VXGE_HW_BADCFG_VPATH_RPA_STRIP_VLAN_TAG;
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_device_config_check - Check device configuration.
+ * Check the device configuration
+ */
+enum vxge_hw_status
+__vxge_hw_device_config_check(struct vxge_hw_device_config *new_config)
+{
+ u32 i;
+ enum vxge_hw_status status;
+
+ if ((new_config->intr_mode != VXGE_HW_INTR_MODE_IRQLINE) &&
+ (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX) &&
+ (new_config->intr_mode != VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) &&
+ (new_config->intr_mode != VXGE_HW_INTR_MODE_DEF))
+ return VXGE_HW_BADCFG_INTR_MODE;
+
+ if ((new_config->rts_mac_en != VXGE_HW_RTS_MAC_DISABLE) &&
+ (new_config->rts_mac_en != VXGE_HW_RTS_MAC_ENABLE))
+ return VXGE_HW_BADCFG_RTS_MAC_EN;
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+ status = __vxge_hw_device_vpath_config_check(
+ &new_config->vp_config[i]);
+ if (status != VXGE_HW_OK)
+ return status;
+ }
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * vxge_hw_device_config_default_get - Initialize device config with defaults.
+ * Initialize Titan device config with default values.
+ */
+enum vxge_hw_status __devinit
+vxge_hw_device_config_default_get(struct vxge_hw_device_config *device_config)
+{
+ u32 i;
+
+ device_config->dma_blockpool_initial =
+ VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE;
+ device_config->dma_blockpool_max = VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE;
+ device_config->intr_mode = VXGE_HW_INTR_MODE_DEF;
+ device_config->rth_en = VXGE_HW_RTH_DEFAULT;
+ device_config->rth_it_type = VXGE_HW_RTH_IT_TYPE_DEFAULT;
+ device_config->device_poll_millis = VXGE_HW_DEF_DEVICE_POLL_MILLIS;
+ device_config->rts_mac_en = VXGE_HW_RTS_MAC_DEFAULT;
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+ device_config->vp_config[i].vp_id = i;
+
+ device_config->vp_config[i].min_bandwidth =
+ VXGE_HW_VPATH_BANDWIDTH_DEFAULT;
+
+ device_config->vp_config[i].ring.enable = VXGE_HW_RING_DEFAULT;
+
+ device_config->vp_config[i].ring.ring_blocks =
+ VXGE_HW_DEF_RING_BLOCKS;
+
+ device_config->vp_config[i].ring.buffer_mode =
+ VXGE_HW_RING_RXD_BUFFER_MODE_DEFAULT;
+
+ device_config->vp_config[i].ring.scatter_mode =
+ VXGE_HW_RING_SCATTER_MODE_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].ring.rxds_limit =
+ VXGE_HW_DEF_RING_RXDS_LIMIT;
+
+ device_config->vp_config[i].fifo.enable = VXGE_HW_FIFO_ENABLE;
+
+ device_config->vp_config[i].fifo.fifo_blocks =
+ VXGE_HW_MIN_FIFO_BLOCKS;
+
+ device_config->vp_config[i].fifo.max_frags =
+ VXGE_HW_MAX_FIFO_FRAGS;
+
+ device_config->vp_config[i].fifo.memblock_size =
+ VXGE_HW_DEF_FIFO_MEMBLOCK_SIZE;
+
+ device_config->vp_config[i].fifo.alignment_size =
+ VXGE_HW_DEF_FIFO_ALIGNMENT_SIZE;
+
+ device_config->vp_config[i].fifo.intr =
+ VXGE_HW_FIFO_QUEUE_INTR_DEFAULT;
+
+ device_config->vp_config[i].fifo.no_snoop_bits =
+ VXGE_HW_FIFO_NO_SNOOP_DEFAULT;
+ device_config->vp_config[i].tti.intr_enable =
+ VXGE_HW_TIM_INTR_DEFAULT;
+
+ device_config->vp_config[i].tti.btimer_val =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].tti.timer_ac_en =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].tti.timer_ci_en =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].tti.timer_ri_en =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].tti.rtimer_val =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].tti.util_sel =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].tti.ltimer_val =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].tti.urange_a =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].tti.uec_a =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].tti.urange_b =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].tti.uec_b =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].tti.urange_c =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].tti.uec_c =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].tti.uec_d =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.intr_enable =
+ VXGE_HW_TIM_INTR_DEFAULT;
+
+ device_config->vp_config[i].rti.btimer_val =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.timer_ac_en =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.timer_ci_en =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.timer_ri_en =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.rtimer_val =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.util_sel =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.ltimer_val =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.urange_a =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.uec_a =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.urange_b =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.uec_b =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.urange_c =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.uec_c =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].rti.uec_d =
+ VXGE_HW_USE_FLASH_DEFAULT;
+
+ device_config->vp_config[i].mtu =
+ VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU;
+
+ device_config->vp_config[i].rpa_strip_vlan_tag =
+ VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT;
+ }
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * _hw_legacy_swapper_set - Set the swapper bits for the legacy secion.
+ * Set the swapper bits appropriately for the lagacy section.
+ */
+enum vxge_hw_status
+__vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ val64 = readq(&legacy_reg->toc_swapper_fb);
+
+ wmb();
+
+ switch (val64) {
+
+ case VXGE_HW_SWAPPER_INITIAL_VALUE:
+ return status;
+
+ case VXGE_HW_SWAPPER_BYTE_SWAPPED_BIT_FLIPPED:
+ writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
+ &legacy_reg->pifm_rd_swap_en);
+ writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
+ &legacy_reg->pifm_rd_flip_en);
+ writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
+ &legacy_reg->pifm_wr_swap_en);
+ writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
+ &legacy_reg->pifm_wr_flip_en);
+ break;
+
+ case VXGE_HW_SWAPPER_BYTE_SWAPPED:
+ writeq(VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE,
+ &legacy_reg->pifm_rd_swap_en);
+ writeq(VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE,
+ &legacy_reg->pifm_wr_swap_en);
+ break;
+
+ case VXGE_HW_SWAPPER_BIT_FLIPPED:
+ writeq(VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE,
+ &legacy_reg->pifm_rd_flip_en);
+ writeq(VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE,
+ &legacy_reg->pifm_wr_flip_en);
+ break;
+ }
+
+ wmb();
+
+ val64 = readq(&legacy_reg->toc_swapper_fb);
+
+ if (val64 != VXGE_HW_SWAPPER_INITIAL_VALUE)
+ status = VXGE_HW_ERR_SWAPPER_CTRL;
+
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_swapper_set - Set the swapper bits for the vpath.
+ * Set the swapper bits appropriately for the vpath.
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_swapper_set(struct vxge_hw_vpath_reg __iomem *vpath_reg)
+{
+#ifndef __BIG_ENDIAN
+ u64 val64;
+
+ val64 = readq(&vpath_reg->vpath_general_cfg1);
+ wmb();
+ val64 |= VXGE_HW_VPATH_GENERAL_CFG1_CTL_BYTE_SWAPEN;
+ writeq(val64, &vpath_reg->vpath_general_cfg1);
+ wmb();
+#endif
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_kdfc_swapper_set - Set the swapper bits for the kdfc.
+ * Set the swapper bits appropriately for the vpath.
+ */
+enum vxge_hw_status
+__vxge_hw_kdfc_swapper_set(
+ struct vxge_hw_legacy_reg __iomem *legacy_reg,
+ struct vxge_hw_vpath_reg __iomem *vpath_reg)
+{
+ u64 val64;
+
+ val64 = readq(&legacy_reg->pifm_wr_swap_en);
+
+ if (val64 == VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE) {
+ val64 = readq(&vpath_reg->kdfcctl_cfg0);
+ wmb();
+
+ val64 |= VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO0 |
+ VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO1 |
+ VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO2;
+
+ writeq(val64, &vpath_reg->kdfcctl_cfg0);
+ wmb();
+ }
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * vxge_hw_mgmt_device_config - Retrieve device configuration.
+ * Get device configuration. Permits to retrieve at run-time configuration
+ * values that were used to initialize and configure the device.
+ */
+enum vxge_hw_status
+vxge_hw_mgmt_device_config(struct __vxge_hw_device *hldev,
+ struct vxge_hw_device_config *dev_config, int size)
+{
+
+ if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC))
+ return VXGE_HW_ERR_INVALID_DEVICE;
+
+ if (size != sizeof(struct vxge_hw_device_config))
+ return VXGE_HW_ERR_VERSION_CONFLICT;
+
+ memcpy(dev_config, &hldev->config,
+ sizeof(struct vxge_hw_device_config));
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * vxge_hw_mgmt_reg_read - Read Titan register.
+ */
+enum vxge_hw_status
+vxge_hw_mgmt_reg_read(struct __vxge_hw_device *hldev,
+ enum vxge_hw_mgmt_reg_type type,
+ u32 index, u32 offset, u64 *value)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
+ status = VXGE_HW_ERR_INVALID_DEVICE;
+ goto exit;
+ }
+
+ switch (type) {
+ case vxge_hw_mgmt_reg_type_legacy:
+ if (offset > sizeof(struct vxge_hw_legacy_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ *value = readq((void __iomem *)hldev->legacy_reg + offset);
+ break;
+ case vxge_hw_mgmt_reg_type_toc:
+ if (offset > sizeof(struct vxge_hw_toc_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ *value = readq((void __iomem *)hldev->toc_reg + offset);
+ break;
+ case vxge_hw_mgmt_reg_type_common:
+ if (offset > sizeof(struct vxge_hw_common_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ *value = readq((void __iomem *)hldev->common_reg + offset);
+ break;
+ case vxge_hw_mgmt_reg_type_mrpcim:
+ if (!(hldev->access_rights &
+ VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) {
+ status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
+ break;
+ }
+ if (offset > sizeof(struct vxge_hw_mrpcim_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ *value = readq((void __iomem *)hldev->mrpcim_reg + offset);
+ break;
+ case vxge_hw_mgmt_reg_type_srpcim:
+ if (!(hldev->access_rights &
+ VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM)) {
+ status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
+ break;
+ }
+ if (index > VXGE_HW_TITAN_SRPCIM_REG_SPACES - 1) {
+ status = VXGE_HW_ERR_INVALID_INDEX;
+ break;
+ }
+ if (offset > sizeof(struct vxge_hw_srpcim_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ *value = readq((void __iomem *)hldev->srpcim_reg[index] +
+ offset);
+ break;
+ case vxge_hw_mgmt_reg_type_vpmgmt:
+ if ((index > VXGE_HW_TITAN_VPMGMT_REG_SPACES - 1) ||
+ (!(hldev->vpath_assignments & vxge_mBIT(index)))) {
+ status = VXGE_HW_ERR_INVALID_INDEX;
+ break;
+ }
+ if (offset > sizeof(struct vxge_hw_vpmgmt_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ *value = readq((void __iomem *)hldev->vpmgmt_reg[index] +
+ offset);
+ break;
+ case vxge_hw_mgmt_reg_type_vpath:
+ if ((index > VXGE_HW_TITAN_VPATH_REG_SPACES - 1) ||
+ (!(hldev->vpath_assignments & vxge_mBIT(index)))) {
+ status = VXGE_HW_ERR_INVALID_INDEX;
+ break;
+ }
+ if (index > VXGE_HW_TITAN_VPATH_REG_SPACES - 1) {
+ status = VXGE_HW_ERR_INVALID_INDEX;
+ break;
+ }
+ if (offset > sizeof(struct vxge_hw_vpath_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ *value = readq((void __iomem *)hldev->vpath_reg[index] +
+ offset);
+ break;
+ default:
+ status = VXGE_HW_ERR_INVALID_TYPE;
+ break;
+ }
+
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_mgmt_reg_Write - Write Titan register.
+ */
+enum vxge_hw_status
+vxge_hw_mgmt_reg_write(struct __vxge_hw_device *hldev,
+ enum vxge_hw_mgmt_reg_type type,
+ u32 index, u32 offset, u64 value)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if ((hldev == NULL) || (hldev->magic != VXGE_HW_DEVICE_MAGIC)) {
+ status = VXGE_HW_ERR_INVALID_DEVICE;
+ goto exit;
+ }
+
+ switch (type) {
+ case vxge_hw_mgmt_reg_type_legacy:
+ if (offset > sizeof(struct vxge_hw_legacy_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ writeq(value, (void __iomem *)hldev->legacy_reg + offset);
+ break;
+ case vxge_hw_mgmt_reg_type_toc:
+ if (offset > sizeof(struct vxge_hw_toc_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ writeq(value, (void __iomem *)hldev->toc_reg + offset);
+ break;
+ case vxge_hw_mgmt_reg_type_common:
+ if (offset > sizeof(struct vxge_hw_common_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ writeq(value, (void __iomem *)hldev->common_reg + offset);
+ break;
+ case vxge_hw_mgmt_reg_type_mrpcim:
+ if (!(hldev->access_rights &
+ VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM)) {
+ status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
+ break;
+ }
+ if (offset > sizeof(struct vxge_hw_mrpcim_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ writeq(value, (void __iomem *)hldev->mrpcim_reg + offset);
+ break;
+ case vxge_hw_mgmt_reg_type_srpcim:
+ if (!(hldev->access_rights &
+ VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM)) {
+ status = VXGE_HW_ERR_PRIVILAGED_OPEARATION;
+ break;
+ }
+ if (index > VXGE_HW_TITAN_SRPCIM_REG_SPACES - 1) {
+ status = VXGE_HW_ERR_INVALID_INDEX;
+ break;
+ }
+ if (offset > sizeof(struct vxge_hw_srpcim_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ writeq(value, (void __iomem *)hldev->srpcim_reg[index] +
+ offset);
+
+ break;
+ case vxge_hw_mgmt_reg_type_vpmgmt:
+ if ((index > VXGE_HW_TITAN_VPMGMT_REG_SPACES - 1) ||
+ (!(hldev->vpath_assignments & vxge_mBIT(index)))) {
+ status = VXGE_HW_ERR_INVALID_INDEX;
+ break;
+ }
+ if (offset > sizeof(struct vxge_hw_vpmgmt_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ writeq(value, (void __iomem *)hldev->vpmgmt_reg[index] +
+ offset);
+ break;
+ case vxge_hw_mgmt_reg_type_vpath:
+ if ((index > VXGE_HW_TITAN_VPATH_REG_SPACES-1) ||
+ (!(hldev->vpath_assignments & vxge_mBIT(index)))) {
+ status = VXGE_HW_ERR_INVALID_INDEX;
+ break;
+ }
+ if (offset > sizeof(struct vxge_hw_vpath_reg) - 8) {
+ status = VXGE_HW_ERR_INVALID_OFFSET;
+ break;
+ }
+ writeq(value, (void __iomem *)hldev->vpath_reg[index] +
+ offset);
+ break;
+ default:
+ status = VXGE_HW_ERR_INVALID_TYPE;
+ break;
+ }
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_fifo_mempool_item_alloc - Allocate List blocks for TxD
+ * list callback
+ * This function is callback passed to __vxge_hw_mempool_create to create memory
+ * pool for TxD list
+ */
+static void
+__vxge_hw_fifo_mempool_item_alloc(
+ struct vxge_hw_mempool *mempoolh,
+ u32 memblock_index, struct vxge_hw_mempool_dma *dma_object,
+ u32 index, u32 is_last)
+{
+ u32 memblock_item_idx;
+ struct __vxge_hw_fifo_txdl_priv *txdl_priv;
+ struct vxge_hw_fifo_txd *txdp =
+ (struct vxge_hw_fifo_txd *)mempoolh->items_arr[index];
+ struct __vxge_hw_fifo *fifo =
+ (struct __vxge_hw_fifo *)mempoolh->userdata;
+ void *memblock = mempoolh->memblocks_arr[memblock_index];
+
+ vxge_assert(txdp);
+
+ txdp->host_control = (u64) (size_t)
+ __vxge_hw_mempool_item_priv(mempoolh, memblock_index, txdp,
+ &memblock_item_idx);
+
+ txdl_priv = __vxge_hw_fifo_txdl_priv(fifo, txdp);
+
+ vxge_assert(txdl_priv);
+
+ fifo->channel.reserve_arr[fifo->channel.reserve_ptr - 1 - index] = txdp;
+
+ /* pre-format HW's TxDL's private */
+ txdl_priv->dma_offset = (char *)txdp - (char *)memblock;
+ txdl_priv->dma_addr = dma_object->addr + txdl_priv->dma_offset;
+ txdl_priv->dma_handle = dma_object->handle;
+ txdl_priv->memblock = memblock;
+ txdl_priv->first_txdp = txdp;
+ txdl_priv->next_txdl_priv = NULL;
+ txdl_priv->alloc_frags = 0;
+
+ return;
+}
+
+/*
+ * __vxge_hw_fifo_create - Create a FIFO
+ * This function creates FIFO and initializes it.
+ */
+enum vxge_hw_status
+__vxge_hw_fifo_create(struct __vxge_hw_vpath_handle *vp,
+ struct vxge_hw_fifo_attr *attr)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_fifo *fifo;
+ struct vxge_hw_fifo_config *config;
+ u32 txdl_size, txdl_per_memblock;
+ struct vxge_hw_mempool_cbs fifo_mp_callback;
+ struct __vxge_hw_virtualpath *vpath;
+
+ if ((vp == NULL) || (attr == NULL)) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+ vpath = vp->vpath;
+ config = &vpath->hldev->config.vp_config[vpath->vp_id].fifo;
+
+ txdl_size = config->max_frags * sizeof(struct vxge_hw_fifo_txd);
+
+ txdl_per_memblock = config->memblock_size / txdl_size;
+
+ fifo = (struct __vxge_hw_fifo *)__vxge_hw_channel_allocate(vp,
+ VXGE_HW_CHANNEL_TYPE_FIFO,
+ config->fifo_blocks * txdl_per_memblock,
+ attr->per_txdl_space, attr->userdata);
+
+ if (fifo == NULL) {
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto exit;
+ }
+
+ vpath->fifoh = fifo;
+ fifo->nofl_db = vpath->nofl_db;
+
+ fifo->vp_id = vpath->vp_id;
+ fifo->vp_reg = vpath->vp_reg;
+ fifo->stats = &vpath->sw_stats->fifo_stats;
+
+ fifo->config = config;
+
+ /* apply "interrupts per txdl" attribute */
+ fifo->interrupt_type = VXGE_HW_FIFO_TXD_INT_TYPE_UTILZ;
+
+ if (fifo->config->intr)
+ fifo->interrupt_type = VXGE_HW_FIFO_TXD_INT_TYPE_PER_LIST;
+
+ fifo->no_snoop_bits = config->no_snoop_bits;
+
+ /*
+ * FIFO memory management strategy:
+ *
+ * TxDL split into three independent parts:
+ * - set of TxD's
+ * - TxD HW private part
+ * - driver private part
+ *
+ * Adaptative memory allocation used. i.e. Memory allocated on
+ * demand with the size which will fit into one memory block.
+ * One memory block may contain more than one TxDL.
+ *
+ * During "reserve" operations more memory can be allocated on demand
+ * for example due to FIFO full condition.
+ *
+ * Pool of memory memblocks never shrinks except in __vxge_hw_fifo_close
+ * routine which will essentially stop the channel and free resources.
+ */
+
+ /* TxDL common private size == TxDL private + driver private */
+ fifo->priv_size =
+ sizeof(struct __vxge_hw_fifo_txdl_priv) + attr->per_txdl_space;
+ fifo->priv_size = ((fifo->priv_size + VXGE_CACHE_LINE_SIZE - 1) /
+ VXGE_CACHE_LINE_SIZE) * VXGE_CACHE_LINE_SIZE;
+
+ fifo->per_txdl_space = attr->per_txdl_space;
+
+ /* recompute txdl size to be cacheline aligned */
+ fifo->txdl_size = txdl_size;
+ fifo->txdl_per_memblock = txdl_per_memblock;
+
+ fifo->txdl_term = attr->txdl_term;
+ fifo->callback = attr->callback;
+
+ if (fifo->txdl_per_memblock == 0) {
+ __vxge_hw_fifo_delete(vp);
+ status = VXGE_HW_ERR_INVALID_BLOCK_SIZE;
+ goto exit;
+ }
+
+ fifo_mp_callback.item_func_alloc = __vxge_hw_fifo_mempool_item_alloc;
+
+ fifo->mempool =
+ __vxge_hw_mempool_create(vpath->hldev,
+ fifo->config->memblock_size,
+ fifo->txdl_size,
+ fifo->priv_size,
+ (fifo->config->fifo_blocks * fifo->txdl_per_memblock),
+ (fifo->config->fifo_blocks * fifo->txdl_per_memblock),
+ &fifo_mp_callback,
+ fifo);
+
+ if (fifo->mempool == NULL) {
+ __vxge_hw_fifo_delete(vp);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto exit;
+ }
+
+ status = __vxge_hw_channel_initialize(&fifo->channel);
+ if (status != VXGE_HW_OK) {
+ __vxge_hw_fifo_delete(vp);
+ goto exit;
+ }
+
+ vxge_assert(fifo->channel.reserve_ptr);
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_fifo_abort - Returns the TxD
+ * This function terminates the TxDs of fifo
+ */
+enum vxge_hw_status __vxge_hw_fifo_abort(struct __vxge_hw_fifo *fifo)
+{
+ void *txdlh;
+
+ for (;;) {
+ vxge_hw_channel_dtr_try_complete(&fifo->channel, &txdlh);
+
+ if (txdlh == NULL)
+ break;
+
+ vxge_hw_channel_dtr_complete(&fifo->channel);
+
+ if (fifo->txdl_term) {
+ fifo->txdl_term(txdlh,
+ VXGE_HW_TXDL_STATE_POSTED,
+ fifo->channel.userdata);
+ }
+
+ vxge_hw_channel_dtr_free(&fifo->channel, txdlh);
+ }
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_fifo_reset - Resets the fifo
+ * This function resets the fifo during vpath reset operation
+ */
+enum vxge_hw_status __vxge_hw_fifo_reset(struct __vxge_hw_fifo *fifo)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ __vxge_hw_fifo_abort(fifo);
+ status = __vxge_hw_channel_reset(&fifo->channel);
+
+ return status;
+}
+
+/*
+ * __vxge_hw_fifo_delete - Removes the FIFO
+ * This function freeup the memory pool and removes the FIFO
+ */
+enum vxge_hw_status __vxge_hw_fifo_delete(struct __vxge_hw_vpath_handle *vp)
+{
+ struct __vxge_hw_fifo *fifo = vp->vpath->fifoh;
+
+ __vxge_hw_fifo_abort(fifo);
+
+ if (fifo->mempool)
+ __vxge_hw_mempool_destroy(fifo->mempool);
+
+ vp->vpath->fifoh = NULL;
+
+ __vxge_hw_channel_free(&fifo->channel);
+
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_vpath_pci_read - Read the content of given address
+ * in pci config space.
+ * Read from the vpath pci config space.
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_pci_read(struct __vxge_hw_virtualpath *vpath,
+ u32 phy_func_0, u32 offset, u32 *val)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg;
+
+ val64 = VXGE_HW_PCI_CONFIG_ACCESS_CFG1_ADDRESS(offset);
+
+ if (phy_func_0)
+ val64 |= VXGE_HW_PCI_CONFIG_ACCESS_CFG1_SEL_FUNC0;
+
+ writeq(val64, &vp_reg->pci_config_access_cfg1);
+ wmb();
+ writeq(VXGE_HW_PCI_CONFIG_ACCESS_CFG2_REQ,
+ &vp_reg->pci_config_access_cfg2);
+ wmb();
+
+ status = __vxge_hw_device_register_poll(
+ &vp_reg->pci_config_access_cfg2,
+ VXGE_HW_INTR_MASK_ALL, VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ val64 = readq(&vp_reg->pci_config_access_status);
+
+ if (val64 & VXGE_HW_PCI_CONFIG_ACCESS_STATUS_ACCESS_ERR) {
+ status = VXGE_HW_FAIL;
+ *val = 0;
+ } else
+ *val = (u32)vxge_bVALn(val64, 32, 32);
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_func_id_get - Get the function id of the vpath.
+ * Returns the function number of the vpath.
+ */
+u32
+__vxge_hw_vpath_func_id_get(u32 vp_id,
+ struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg)
+{
+ u64 val64;
+
+ val64 = readq(&vpmgmt_reg->vpath_to_func_map_cfg1);
+
+ return
+ (u32)VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(val64);
+}
+
+/*
+ * __vxge_hw_read_rts_ds - Program RTS steering critieria
+ */
+static inline void
+__vxge_hw_read_rts_ds(struct vxge_hw_vpath_reg __iomem *vpath_reg,
+ u64 dta_struct_sel)
+{
+ writeq(0, &vpath_reg->rts_access_steer_ctrl);
+ wmb();
+ writeq(dta_struct_sel, &vpath_reg->rts_access_steer_data0);
+ writeq(0, &vpath_reg->rts_access_steer_data1);
+ wmb();
+ return;
+}
+
+
+/*
+ * __vxge_hw_vpath_card_info_get - Get the serial numbers,
+ * part number and product description.
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_card_info_get(
+ u32 vp_id,
+ struct vxge_hw_vpath_reg __iomem *vpath_reg,
+ struct vxge_hw_device_hw_info *hw_info)
+{
+ u32 i, j;
+ u64 val64;
+ u64 data1 = 0ULL;
+ u64 data2 = 0ULL;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ u8 *serial_number = hw_info->serial_number;
+ u8 *part_number = hw_info->part_number;
+ u8 *product_desc = hw_info->product_desc;
+
+ __vxge_hw_read_rts_ds(vpath_reg,
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER);
+
+ val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+ status = __vxge_hw_pio_mem_write64(val64,
+ &vpath_reg->rts_access_steer_ctrl,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+ VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+ if (status != VXGE_HW_OK)
+ return status;
+
+ val64 = readq(&vpath_reg->rts_access_steer_ctrl);
+
+ if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+ data1 = readq(&vpath_reg->rts_access_steer_data0);
+ ((u64 *)serial_number)[0] = be64_to_cpu(data1);
+
+ data2 = readq(&vpath_reg->rts_access_steer_data1);
+ ((u64 *)serial_number)[1] = be64_to_cpu(data2);
+ status = VXGE_HW_OK;
+ } else
+ *serial_number = 0;
+
+ __vxge_hw_read_rts_ds(vpath_reg,
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER);
+
+ val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+ status = __vxge_hw_pio_mem_write64(val64,
+ &vpath_reg->rts_access_steer_ctrl,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+ VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+ if (status != VXGE_HW_OK)
+ return status;
+
+ val64 = readq(&vpath_reg->rts_access_steer_ctrl);
+
+ if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+
+ data1 = readq(&vpath_reg->rts_access_steer_data0);
+ ((u64 *)part_number)[0] = be64_to_cpu(data1);
+
+ data2 = readq(&vpath_reg->rts_access_steer_data1);
+ ((u64 *)part_number)[1] = be64_to_cpu(data2);
+
+ status = VXGE_HW_OK;
+
+ } else
+ *part_number = 0;
+
+ j = 0;
+
+ for (i = VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0;
+ i <= VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3; i++) {
+
+ __vxge_hw_read_rts_ds(vpath_reg, i);
+
+ val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+ status = __vxge_hw_pio_mem_write64(val64,
+ &vpath_reg->rts_access_steer_ctrl,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+ VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+ if (status != VXGE_HW_OK)
+ return status;
+
+ val64 = readq(&vpath_reg->rts_access_steer_ctrl);
+
+ if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+
+ data1 = readq(&vpath_reg->rts_access_steer_data0);
+ ((u64 *)product_desc)[j++] = be64_to_cpu(data1);
+
+ data2 = readq(&vpath_reg->rts_access_steer_data1);
+ ((u64 *)product_desc)[j++] = be64_to_cpu(data2);
+
+ status = VXGE_HW_OK;
+ } else
+ *product_desc = 0;
+ }
+
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_fw_ver_get - Get the fw version
+ * Returns FW Version
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_fw_ver_get(
+ u32 vp_id,
+ struct vxge_hw_vpath_reg __iomem *vpath_reg,
+ struct vxge_hw_device_hw_info *hw_info)
+{
+ u64 val64;
+ u64 data1 = 0ULL;
+ u64 data2 = 0ULL;
+ struct vxge_hw_device_version *fw_version = &hw_info->fw_version;
+ struct vxge_hw_device_date *fw_date = &hw_info->fw_date;
+ struct vxge_hw_device_version *flash_version = &hw_info->flash_version;
+ struct vxge_hw_device_date *flash_date = &hw_info->flash_date;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+ status = __vxge_hw_pio_mem_write64(val64,
+ &vpath_reg->rts_access_steer_ctrl,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+ VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ val64 = readq(&vpath_reg->rts_access_steer_ctrl);
+
+ if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+
+ data1 = readq(&vpath_reg->rts_access_steer_data0);
+ data2 = readq(&vpath_reg->rts_access_steer_data1);
+
+ fw_date->day =
+ (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY(
+ data1);
+ fw_date->month =
+ (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH(
+ data1);
+ fw_date->year =
+ (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR(
+ data1);
+
+ snprintf(fw_date->date, VXGE_HW_FW_STRLEN, "%2.2d/%2.2d/%4.4d",
+ fw_date->month, fw_date->day, fw_date->year);
+
+ fw_version->major =
+ (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data1);
+ fw_version->minor =
+ (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data1);
+ fw_version->build =
+ (u32)VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data1);
+
+ snprintf(fw_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
+ fw_version->major, fw_version->minor, fw_version->build);
+
+ flash_date->day =
+ (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(data2);
+ flash_date->month =
+ (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(data2);
+ flash_date->year =
+ (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(data2);
+
+ snprintf(flash_date->date, VXGE_HW_FW_STRLEN,
+ "%2.2d/%2.2d/%4.4d",
+ flash_date->month, flash_date->day, flash_date->year);
+
+ flash_version->major =
+ (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(data2);
+ flash_version->minor =
+ (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(data2);
+ flash_version->build =
+ (u32)VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(data2);
+
+ snprintf(flash_version->version, VXGE_HW_FW_STRLEN, "%d.%d.%d",
+ flash_version->major, flash_version->minor,
+ flash_version->build);
+
+ status = VXGE_HW_OK;
+
+ } else
+ status = VXGE_HW_FAIL;
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_pci_func_mode_get - Get the pci mode
+ * Returns pci function mode
+ */
+u64
+__vxge_hw_vpath_pci_func_mode_get(
+ u32 vp_id,
+ struct vxge_hw_vpath_reg __iomem *vpath_reg)
+{
+ u64 val64;
+ u64 data1 = 0ULL;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ __vxge_hw_read_rts_ds(vpath_reg,
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PCI_MODE);
+
+ val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+ status = __vxge_hw_pio_mem_write64(val64,
+ &vpath_reg->rts_access_steer_ctrl,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+ VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ val64 = readq(&vpath_reg->rts_access_steer_ctrl);
+
+ if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+ data1 = readq(&vpath_reg->rts_access_steer_data0);
+ status = VXGE_HW_OK;
+ } else {
+ data1 = 0;
+ status = VXGE_HW_FAIL;
+ }
+exit:
+ return data1;
+}
+
+/**
+ * vxge_hw_device_flick_link_led - Flick (blink) link LED.
+ * @hldev: HW device.
+ * @on_off: TRUE if flickering to be on, FALSE to be off
+ *
+ * Flicker the link LED.
+ */
+enum vxge_hw_status
+vxge_hw_device_flick_link_led(struct __vxge_hw_device *hldev,
+ u64 on_off)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+ if (hldev == NULL) {
+ status = VXGE_HW_ERR_INVALID_DEVICE;
+ goto exit;
+ }
+
+ vp_reg = hldev->vpath_reg[hldev->first_vp_id];
+
+ writeq(0, &vp_reg->rts_access_steer_ctrl);
+ wmb();
+ writeq(on_off, &vp_reg->rts_access_steer_data0);
+ writeq(0, &vp_reg->rts_access_steer_data1);
+ wmb();
+
+ val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LED_CONTROL) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+ status = __vxge_hw_pio_mem_write64(val64,
+ &vp_reg->rts_access_steer_ctrl,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+ VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_rts_table_get - Get the entries from RTS access tables
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_rts_table_get(
+ struct __vxge_hw_vpath_handle *vp,
+ u32 action, u32 rts_table, u32 offset, u64 *data1, u64 *data2)
+{
+ u64 val64;
+ struct __vxge_hw_virtualpath *vpath;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ vpath = vp->vpath;
+ vp_reg = vpath->vp_reg;
+
+ val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(rts_table) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset);
+
+ if ((rts_table ==
+ VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT) ||
+ (rts_table ==
+ VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT) ||
+ (rts_table ==
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK) ||
+ (rts_table ==
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY)) {
+ val64 = val64 | VXGE_HW_RTS_ACCESS_STEER_CTRL_TABLE_SEL;
+ }
+
+ status = __vxge_hw_pio_mem_write64(val64,
+ &vp_reg->rts_access_steer_ctrl,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+ vpath->hldev->config.device_poll_millis);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ val64 = readq(&vp_reg->rts_access_steer_ctrl);
+
+ if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+
+ *data1 = readq(&vp_reg->rts_access_steer_data0);
+
+ if ((rts_table ==
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) ||
+ (rts_table ==
+ VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) {
+ *data2 = readq(&vp_reg->rts_access_steer_data1);
+ }
+ status = VXGE_HW_OK;
+ } else
+ status = VXGE_HW_FAIL;
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_rts_table_set - Set the entries of RTS access tables
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_rts_table_set(
+ struct __vxge_hw_vpath_handle *vp, u32 action, u32 rts_table,
+ u32 offset, u64 data1, u64 data2)
+{
+ u64 val64;
+ struct __vxge_hw_virtualpath *vpath;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ vpath = vp->vpath;
+ vp_reg = vpath->vp_reg;
+
+ writeq(data1, &vp_reg->rts_access_steer_data0);
+ wmb();
+
+ if ((rts_table == VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) ||
+ (rts_table ==
+ VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT)) {
+ writeq(data2, &vp_reg->rts_access_steer_data1);
+ wmb();
+ }
+
+ val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(action) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(rts_table) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(offset);
+
+ status = __vxge_hw_pio_mem_write64(val64,
+ &vp_reg->rts_access_steer_ctrl,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+ vpath->hldev->config.device_poll_millis);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ val64 = readq(&vp_reg->rts_access_steer_ctrl);
+
+ if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS)
+ status = VXGE_HW_OK;
+ else
+ status = VXGE_HW_FAIL;
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_addr_get - Get the hw address entry for this vpath
+ * from MAC address table.
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_addr_get(
+ u32 vp_id, struct vxge_hw_vpath_reg __iomem *vpath_reg,
+ u8 (macaddr)[ETH_ALEN], u8 (macaddr_mask)[ETH_ALEN])
+{
+ u32 i;
+ u64 val64;
+ u64 data1 = 0ULL;
+ u64 data2 = 0ULL;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ val64 = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA) |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE |
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(0);
+
+ status = __vxge_hw_pio_mem_write64(val64,
+ &vpath_reg->rts_access_steer_ctrl,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE,
+ VXGE_HW_DEF_DEVICE_POLL_MILLIS);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ val64 = readq(&vpath_reg->rts_access_steer_ctrl);
+
+ if (val64 & VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS) {
+
+ data1 = readq(&vpath_reg->rts_access_steer_data0);
+ data2 = readq(&vpath_reg->rts_access_steer_data1);
+
+ data1 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data1);
+ data2 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(
+ data2);
+
+ for (i = ETH_ALEN; i > 0; i--) {
+ macaddr[i-1] = (u8)(data1 & 0xFF);
+ data1 >>= 8;
+
+ macaddr_mask[i-1] = (u8)(data2 & 0xFF);
+ data2 >>= 8;
+ }
+ status = VXGE_HW_OK;
+ } else
+ status = VXGE_HW_FAIL;
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_vpath_rts_rth_set - Set/configure RTS hashing.
+ */
+enum vxge_hw_status vxge_hw_vpath_rts_rth_set(
+ struct __vxge_hw_vpath_handle *vp,
+ enum vxge_hw_rth_algoritms algorithm,
+ struct vxge_hw_rth_hash_types *hash_type,
+ u16 bucket_size)
+{
+ u64 data0, data1;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ status = __vxge_hw_vpath_rts_table_get(vp,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG,
+ 0, &data0, &data1);
+
+ data0 &= ~(VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(0xf) |
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(0x3));
+
+ data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_EN |
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(bucket_size) |
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(algorithm);
+
+ if (hash_type->hash_type_tcpipv4_en)
+ data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV4_EN;
+
+ if (hash_type->hash_type_ipv4_en)
+ data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV4_EN;
+
+ if (hash_type->hash_type_tcpipv6_en)
+ data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EN;
+
+ if (hash_type->hash_type_ipv6_en)
+ data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EN;
+
+ if (hash_type->hash_type_tcpipv6ex_en)
+ data0 |=
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EX_EN;
+
+ if (hash_type->hash_type_ipv6ex_en)
+ data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EX_EN;
+
+ if (VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_ACTIVE_TABLE(data0))
+ data0 &= ~VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ACTIVE_TABLE;
+ else
+ data0 |= VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ACTIVE_TABLE;
+
+ status = __vxge_hw_vpath_rts_table_set(vp,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG,
+ 0, data0, 0);
+exit:
+ return status;
+}
+
+static void
+vxge_hw_rts_rth_data0_data1_get(u32 j, u64 *data0, u64 *data1,
+ u16 flag, u8 *itable)
+{
+ switch (flag) {
+ case 1:
+ *data0 = VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_NUM(j)|
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_ENTRY_EN |
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_DATA(
+ itable[j]);
+ case 2:
+ *data0 |=
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_NUM(j)|
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_ENTRY_EN |
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_DATA(
+ itable[j]);
+ case 3:
+ *data1 = VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_NUM(j)|
+ VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_ENTRY_EN |
+ VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_DATA(
+ itable[j]);
+ case 4:
+ *data1 |=
+ VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_NUM(j)|
+ VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_ENTRY_EN |
+ VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_DATA(
+ itable[j]);
+ default:
+ return;
+ }
+}
+/*
+ * vxge_hw_vpath_rts_rth_itable_set - Set/configure indirection table (IT).
+ */
+enum vxge_hw_status vxge_hw_vpath_rts_rth_itable_set(
+ struct __vxge_hw_vpath_handle **vpath_handles,
+ u32 vpath_count,
+ u8 *mtable,
+ u8 *itable,
+ u32 itable_size)
+{
+ u32 i, j, action, rts_table;
+ u64 data0;
+ u64 data1;
+ u32 max_entries;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_vpath_handle *vp = vpath_handles[0];
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ max_entries = (((u32)1) << itable_size);
+
+ if (vp->vpath->hldev->config.rth_it_type
+ == VXGE_HW_RTH_IT_TYPE_SOLO_IT) {
+ action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY;
+ rts_table =
+ VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT;
+
+ for (j = 0; j < max_entries; j++) {
+
+ data1 = 0;
+
+ data0 =
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_BUCKET_DATA(
+ itable[j]);
+
+ status = __vxge_hw_vpath_rts_table_set(vpath_handles[0],
+ action, rts_table, j, data0, data1);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+ }
+
+ for (j = 0; j < max_entries; j++) {
+
+ data1 = 0;
+
+ data0 =
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_ENTRY_EN |
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_BUCKET_DATA(
+ itable[j]);
+
+ status = __vxge_hw_vpath_rts_table_set(
+ vpath_handles[mtable[itable[j]]], action,
+ rts_table, j, data0, data1);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+ }
+ } else {
+ action = VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY;
+ rts_table =
+ VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT;
+ for (i = 0; i < vpath_count; i++) {
+
+ for (j = 0; j < max_entries;) {
+
+ data0 = 0;
+ data1 = 0;
+
+ while (j < max_entries) {
+ if (mtable[itable[j]] != i) {
+ j++;
+ continue;
+ }
+ vxge_hw_rts_rth_data0_data1_get(j,
+ &data0, &data1, 1, itable);
+ j++;
+ break;
+ }
+
+ while (j < max_entries) {
+ if (mtable[itable[j]] != i) {
+ j++;
+ continue;
+ }
+ vxge_hw_rts_rth_data0_data1_get(j,
+ &data0, &data1, 2, itable);
+ j++;
+ break;
+ }
+
+ while (j < max_entries) {
+ if (mtable[itable[j]] != i) {
+ j++;
+ continue;
+ }
+ vxge_hw_rts_rth_data0_data1_get(j,
+ &data0, &data1, 3, itable);
+ j++;
+ break;
+ }
+
+ while (j < max_entries) {
+ if (mtable[itable[j]] != i) {
+ j++;
+ continue;
+ }
+ vxge_hw_rts_rth_data0_data1_get(j,
+ &data0, &data1, 4, itable);
+ j++;
+ break;
+ }
+
+ if (data0 != 0) {
+ status = __vxge_hw_vpath_rts_table_set(
+ vpath_handles[i],
+ action, rts_table,
+ 0, data0, data1);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+ }
+ }
+ }
+ }
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_check_leak - Check for memory leak
+ * @ringh: Handle to the ring object used for receive
+ *
+ * If PRC_RXD_DOORBELL_VPn.NEW_QW_CNT is larger or equal to
+ * PRC_CFG6_VPn.RXD_SPAT then a leak has occurred.
+ * Returns: VXGE_HW_FAIL, if leak has occurred.
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_check_leak(struct __vxge_hw_ring *ring)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ u64 rxd_new_count, rxd_spat;
+
+ if (ring == NULL)
+ return status;
+
+ rxd_new_count = readl(&ring->vp_reg->prc_rxd_doorbell);
+ rxd_spat = readq(&ring->vp_reg->prc_cfg6);
+ rxd_spat = VXGE_HW_PRC_CFG6_RXD_SPAT(rxd_spat);
+
+ if (rxd_new_count >= rxd_spat)
+ status = VXGE_HW_FAIL;
+
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_mgmt_read
+ * This routine reads the vpath_mgmt registers
+ */
+static enum vxge_hw_status
+__vxge_hw_vpath_mgmt_read(
+ struct __vxge_hw_device *hldev,
+ struct __vxge_hw_virtualpath *vpath)
+{
+ u32 i, mtu = 0, max_pyld = 0;
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ for (i = 0; i < VXGE_HW_MAC_MAX_MAC_PORT_ID; i++) {
+
+ val64 = readq(&vpath->vpmgmt_reg->
+ rxmac_cfg0_port_vpmgmt_clone[i]);
+ max_pyld =
+ (u32)
+ VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_GET_MAX_PYLD_LEN
+ (val64);
+ if (mtu < max_pyld)
+ mtu = max_pyld;
+ }
+
+ vpath->max_mtu = mtu + VXGE_HW_MAC_HEADER_MAX_SIZE;
+
+ val64 = readq(&vpath->vpmgmt_reg->xmac_vsport_choices_vp);
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+ if (val64 & vxge_mBIT(i))
+ vpath->vsport_number = i;
+ }
+
+ val64 = readq(&vpath->vpmgmt_reg->xgmac_gen_status_vpmgmt_clone);
+
+ if (val64 & VXGE_HW_XGMAC_GEN_STATUS_VPMGMT_CLONE_XMACJ_NTWK_OK)
+ VXGE_HW_DEVICE_LINK_STATE_SET(vpath->hldev, VXGE_HW_LINK_UP);
+ else
+ VXGE_HW_DEVICE_LINK_STATE_SET(vpath->hldev, VXGE_HW_LINK_DOWN);
+
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_reset_check - Check if resetting the vpath completed
+ * This routine checks the vpath_rst_in_prog register to see if
+ * adapter completed the reset process for the vpath
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath)
+{
+ enum vxge_hw_status status;
+
+ status = __vxge_hw_device_register_poll(
+ &vpath->hldev->common_reg->vpath_rst_in_prog,
+ VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(
+ 1 << (16 - vpath->vp_id)),
+ vpath->hldev->config.device_poll_millis);
+
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_reset
+ * This routine resets the vpath on the device
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_reset(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ val64 = VXGE_HW_CMN_RSTHDLR_CFG0_SW_RESET_VPATH(1 << (16 - vp_id));
+
+ __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
+ &hldev->common_reg->cmn_rsthdlr_cfg0);
+
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_sw_reset
+ * This routine resets the vpath structures
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_sw_reset(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_virtualpath *vpath;
+
+ vpath = (struct __vxge_hw_virtualpath *)&hldev->virtual_paths[vp_id];
+
+ if (vpath->ringh) {
+ status = __vxge_hw_ring_reset(vpath->ringh);
+ if (status != VXGE_HW_OK)
+ goto exit;
+ }
+
+ if (vpath->fifoh)
+ status = __vxge_hw_fifo_reset(vpath->fifoh);
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_prc_configure
+ * This routine configures the prc registers of virtual path using the config
+ * passed
+ */
+void
+__vxge_hw_vpath_prc_configure(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+ u64 val64;
+ struct __vxge_hw_virtualpath *vpath;
+ struct vxge_hw_vp_config *vp_config;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+ vpath = &hldev->virtual_paths[vp_id];
+ vp_reg = vpath->vp_reg;
+ vp_config = vpath->vp_config;
+
+ if (vp_config->ring.enable == VXGE_HW_RING_DISABLE)
+ return;
+
+ val64 = readq(&vp_reg->prc_cfg1);
+ val64 |= VXGE_HW_PRC_CFG1_RTI_TINT_DISABLE;
+ writeq(val64, &vp_reg->prc_cfg1);
+
+ val64 = readq(&vpath->vp_reg->prc_cfg6);
+ val64 |= VXGE_HW_PRC_CFG6_DOORBELL_MODE_EN;
+ writeq(val64, &vpath->vp_reg->prc_cfg6);
+
+ val64 = readq(&vp_reg->prc_cfg7);
+
+ if (vpath->vp_config->ring.scatter_mode !=
+ VXGE_HW_RING_SCATTER_MODE_USE_FLASH_DEFAULT) {
+
+ val64 &= ~VXGE_HW_PRC_CFG7_SCATTER_MODE(0x3);
+
+ switch (vpath->vp_config->ring.scatter_mode) {
+ case VXGE_HW_RING_SCATTER_MODE_A:
+ val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE(
+ VXGE_HW_PRC_CFG7_SCATTER_MODE_A);
+ break;
+ case VXGE_HW_RING_SCATTER_MODE_B:
+ val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE(
+ VXGE_HW_PRC_CFG7_SCATTER_MODE_B);
+ break;
+ case VXGE_HW_RING_SCATTER_MODE_C:
+ val64 |= VXGE_HW_PRC_CFG7_SCATTER_MODE(
+ VXGE_HW_PRC_CFG7_SCATTER_MODE_C);
+ break;
+ }
+ }
+
+ writeq(val64, &vp_reg->prc_cfg7);
+
+ writeq(VXGE_HW_PRC_CFG5_RXD0_ADD(
+ __vxge_hw_ring_first_block_address_get(
+ vpath->ringh) >> 3), &vp_reg->prc_cfg5);
+
+ val64 = readq(&vp_reg->prc_cfg4);
+ val64 |= VXGE_HW_PRC_CFG4_IN_SVC;
+ val64 &= ~VXGE_HW_PRC_CFG4_RING_MODE(0x3);
+
+ val64 |= VXGE_HW_PRC_CFG4_RING_MODE(
+ VXGE_HW_PRC_CFG4_RING_MODE_ONE_BUFFER);
+
+ if (hldev->config.rth_en == VXGE_HW_RTH_DISABLE)
+ val64 |= VXGE_HW_PRC_CFG4_RTH_DISABLE;
+ else
+ val64 &= ~VXGE_HW_PRC_CFG4_RTH_DISABLE;
+
+ writeq(val64, &vp_reg->prc_cfg4);
+ return;
+}
+
+/*
+ * __vxge_hw_vpath_kdfc_configure
+ * This routine configures the kdfc registers of virtual path using the
+ * config passed
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_kdfc_configure(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+ u64 val64;
+ u64 vpath_stride;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_virtualpath *vpath;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+ vpath = &hldev->virtual_paths[vp_id];
+ vp_reg = vpath->vp_reg;
+ status = __vxge_hw_kdfc_swapper_set(hldev->legacy_reg, vp_reg);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ val64 = readq(&vp_reg->kdfc_drbl_triplet_total);
+
+ vpath->max_kdfc_db =
+ (u32)VXGE_HW_KDFC_DRBL_TRIPLET_TOTAL_GET_KDFC_MAX_SIZE(
+ val64+1)/2;
+
+ if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
+
+ vpath->max_nofl_db = vpath->max_kdfc_db;
+
+ if (vpath->max_nofl_db <
+ ((vpath->vp_config->fifo.memblock_size /
+ (vpath->vp_config->fifo.max_frags *
+ sizeof(struct vxge_hw_fifo_txd))) *
+ vpath->vp_config->fifo.fifo_blocks)) {
+
+ return VXGE_HW_BADCFG_FIFO_BLOCKS;
+ }
+ val64 = VXGE_HW_KDFC_FIFO_TRPL_PARTITION_LENGTH_0(
+ (vpath->max_nofl_db*2)-1);
+ }
+
+ writeq(val64, &vp_reg->kdfc_fifo_trpl_partition);
+
+ writeq(VXGE_HW_KDFC_FIFO_TRPL_CTRL_TRIPLET_ENABLE,
+ &vp_reg->kdfc_fifo_trpl_ctrl);
+
+ val64 = readq(&vp_reg->kdfc_trpl_fifo_0_ctrl);
+
+ val64 &= ~(VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE(0x3) |
+ VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(0xFF));
+
+ val64 |= VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE(
+ VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE_NON_OFFLOAD_ONLY) |
+#ifndef __BIG_ENDIAN
+ VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SWAP_EN |
+#endif
+ VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(0);
+
+ writeq(val64, &vp_reg->kdfc_trpl_fifo_0_ctrl);
+ writeq((u64)0, &vp_reg->kdfc_trpl_fifo_0_wb_address);
+ wmb();
+ vpath_stride = readq(&hldev->toc_reg->toc_kdfc_vpath_stride);
+
+ vpath->nofl_db =
+ (struct __vxge_hw_non_offload_db_wrapper __iomem *)
+ (hldev->kdfc + (vp_id *
+ VXGE_HW_TOC_KDFC_VPATH_STRIDE_GET_TOC_KDFC_VPATH_STRIDE(
+ vpath_stride)));
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_mac_configure
+ * This routine configures the mac of virtual path using the config passed
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_mac_configure(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_virtualpath *vpath;
+ struct vxge_hw_vp_config *vp_config;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+ vpath = &hldev->virtual_paths[vp_id];
+ vp_reg = vpath->vp_reg;
+ vp_config = vpath->vp_config;
+
+ writeq(VXGE_HW_XMAC_VSPORT_CHOICE_VSPORT_NUMBER(
+ vpath->vsport_number), &vp_reg->xmac_vsport_choice);
+
+ if (vp_config->ring.enable == VXGE_HW_RING_ENABLE) {
+
+ val64 = readq(&vp_reg->xmac_rpa_vcfg);
+
+ if (vp_config->rpa_strip_vlan_tag !=
+ VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT) {
+ if (vp_config->rpa_strip_vlan_tag)
+ val64 |= VXGE_HW_XMAC_RPA_VCFG_STRIP_VLAN_TAG;
+ else
+ val64 &= ~VXGE_HW_XMAC_RPA_VCFG_STRIP_VLAN_TAG;
+ }
+
+ writeq(val64, &vp_reg->xmac_rpa_vcfg);
+ val64 = readq(&vp_reg->rxmac_vcfg0);
+
+ if (vp_config->mtu !=
+ VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU) {
+ val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff);
+ if ((vp_config->mtu +
+ VXGE_HW_MAC_HEADER_MAX_SIZE) < vpath->max_mtu)
+ val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(
+ vp_config->mtu +
+ VXGE_HW_MAC_HEADER_MAX_SIZE);
+ else
+ val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(
+ vpath->max_mtu);
+ }
+
+ writeq(val64, &vp_reg->rxmac_vcfg0);
+
+ val64 = readq(&vp_reg->rxmac_vcfg1);
+
+ val64 &= ~(VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_BD_MODE(0x3) |
+ VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_EN_MODE);
+
+ if (hldev->config.rth_it_type ==
+ VXGE_HW_RTH_IT_TYPE_MULTI_IT) {
+ val64 |= VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_BD_MODE(
+ 0x2) |
+ VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_EN_MODE;
+ }
+
+ writeq(val64, &vp_reg->rxmac_vcfg1);
+ }
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_tim_configure
+ * This routine configures the tim registers of virtual path using the config
+ * passed
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_tim_configure(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_virtualpath *vpath;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+ struct vxge_hw_vp_config *config;
+
+ vpath = &hldev->virtual_paths[vp_id];
+ vp_reg = vpath->vp_reg;
+ config = vpath->vp_config;
+
+ writeq((u64)0, &vp_reg->tim_dest_addr);
+ writeq((u64)0, &vp_reg->tim_vpath_map);
+ writeq((u64)0, &vp_reg->tim_bitmap);
+ writeq((u64)0, &vp_reg->tim_remap);
+
+ if (config->ring.enable == VXGE_HW_RING_ENABLE)
+ writeq(VXGE_HW_TIM_RING_ASSN_INT_NUM(
+ (vp_id * VXGE_HW_MAX_INTR_PER_VP) +
+ VXGE_HW_VPATH_INTR_RX), &vp_reg->tim_ring_assn);
+
+ val64 = readq(&vp_reg->tim_pci_cfg);
+ val64 |= VXGE_HW_TIM_PCI_CFG_ADD_PAD;
+ writeq(val64, &vp_reg->tim_pci_cfg);
+
+ if (config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
+
+ val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
+
+ if (config->tti.btimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
+ 0x3ffffff);
+ val64 |= VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
+ config->tti.btimer_val);
+ }
+
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN;
+
+ if (config->tti.timer_ac_en != VXGE_HW_USE_FLASH_DEFAULT) {
+ if (config->tti.timer_ac_en)
+ val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
+ else
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
+ }
+
+ if (config->tti.timer_ci_en != VXGE_HW_USE_FLASH_DEFAULT) {
+ if (config->tti.timer_ci_en)
+ val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
+ else
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
+ }
+
+ if (config->tti.urange_a != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(0x3f);
+ val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(
+ config->tti.urange_a);
+ }
+
+ if (config->tti.urange_b != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(0x3f);
+ val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(
+ config->tti.urange_b);
+ }
+
+ if (config->tti.urange_c != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(0x3f);
+ val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(
+ config->tti.urange_c);
+ }
+
+ writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_TX]);
+ val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_TX]);
+
+ if (config->tti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(0xffff);
+ val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(
+ config->tti.uec_a);
+ }
+
+ if (config->tti.uec_b != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(0xffff);
+ val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(
+ config->tti.uec_b);
+ }
+
+ if (config->tti.uec_c != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(0xffff);
+ val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(
+ config->tti.uec_c);
+ }
+
+ if (config->tti.uec_d != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(0xffff);
+ val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(
+ config->tti.uec_d);
+ }
+
+ writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_TX]);
+ val64 = readq(&vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]);
+
+ if (config->tti.timer_ri_en != VXGE_HW_USE_FLASH_DEFAULT) {
+ if (config->tti.timer_ri_en)
+ val64 |= VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
+ else
+ val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
+ }
+
+ if (config->tti.rtimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
+ 0x3ffffff);
+ val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
+ config->tti.rtimer_val);
+ }
+
+ if (config->tti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f);
+ val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(
+ config->tti.util_sel);
+ }
+
+ if (config->tti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
+ 0x3ffffff);
+ val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
+ config->tti.ltimer_val);
+ }
+
+ writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_TX]);
+ }
+
+ if (config->ring.enable == VXGE_HW_RING_ENABLE) {
+
+ val64 = readq(&vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]);
+
+ if (config->rti.btimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
+ 0x3ffffff);
+ val64 |= VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(
+ config->rti.btimer_val);
+ }
+
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN;
+
+ if (config->rti.timer_ac_en != VXGE_HW_USE_FLASH_DEFAULT) {
+ if (config->rti.timer_ac_en)
+ val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
+ else
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC;
+ }
+
+ if (config->rti.timer_ci_en != VXGE_HW_USE_FLASH_DEFAULT) {
+ if (config->rti.timer_ci_en)
+ val64 |= VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
+ else
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI;
+ }
+
+ if (config->rti.urange_a != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(0x3f);
+ val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(
+ config->rti.urange_a);
+ }
+
+ if (config->rti.urange_b != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(0x3f);
+ val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(
+ config->rti.urange_b);
+ }
+
+ if (config->rti.urange_c != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(0x3f);
+ val64 |= VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(
+ config->rti.urange_c);
+ }
+
+ writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_RX]);
+ val64 = readq(&vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]);
+
+ if (config->rti.uec_a != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(0xffff);
+ val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(
+ config->rti.uec_a);
+ }
+
+ if (config->rti.uec_b != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(0xffff);
+ val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(
+ config->rti.uec_b);
+ }
+
+ if (config->rti.uec_c != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(0xffff);
+ val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(
+ config->rti.uec_c);
+ }
+
+ if (config->rti.uec_d != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(0xffff);
+ val64 |= VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(
+ config->rti.uec_d);
+ }
+
+ writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_RX]);
+ val64 = readq(&vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]);
+
+ if (config->rti.timer_ri_en != VXGE_HW_USE_FLASH_DEFAULT) {
+ if (config->rti.timer_ri_en)
+ val64 |= VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
+ else
+ val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI;
+ }
+
+ if (config->rti.rtimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
+ 0x3ffffff);
+ val64 |= VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(
+ config->rti.rtimer_val);
+ }
+
+ if (config->rti.util_sel != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(0x3f);
+ val64 |= VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(
+ config->rti.util_sel);
+ }
+
+ if (config->rti.ltimer_val != VXGE_HW_USE_FLASH_DEFAULT) {
+ val64 &= ~VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
+ 0x3ffffff);
+ val64 |= VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(
+ config->rti.ltimer_val);
+ }
+
+ writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_RX]);
+ }
+
+ val64 = 0;
+ writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_EINTA]);
+ writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_EINTA]);
+ writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_EINTA]);
+ writeq(val64, &vp_reg->tim_cfg1_int_num[VXGE_HW_VPATH_INTR_BMAP]);
+ writeq(val64, &vp_reg->tim_cfg2_int_num[VXGE_HW_VPATH_INTR_BMAP]);
+ writeq(val64, &vp_reg->tim_cfg3_int_num[VXGE_HW_VPATH_INTR_BMAP]);
+
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_initialize
+ * This routine is the final phase of init which initializes the
+ * registers of the vpath using the configuration passed.
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_initialize(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+ u64 val64;
+ u32 val32;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_virtualpath *vpath;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+ vpath = &hldev->virtual_paths[vp_id];
+
+ if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) {
+ status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE;
+ goto exit;
+ }
+ vp_reg = vpath->vp_reg;
+
+ status = __vxge_hw_vpath_swapper_set(vpath->vp_reg);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ status = __vxge_hw_vpath_mac_configure(hldev, vp_id);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ status = __vxge_hw_vpath_kdfc_configure(hldev, vp_id);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ status = __vxge_hw_vpath_tim_configure(hldev, vp_id);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ writeq(0, &vp_reg->gendma_int);
+
+ val64 = readq(&vp_reg->rtdma_rd_optimization_ctrl);
+
+ /* Get MRRS value from device control */
+ status = __vxge_hw_vpath_pci_read(vpath, 1, 0x78, &val32);
+
+ if (status == VXGE_HW_OK) {
+ val32 = (val32 & VXGE_HW_PCI_EXP_DEVCTL_READRQ) >> 12;
+ val64 &=
+ ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(7));
+ val64 |=
+ VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(val32);
+
+ val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_WAIT_FOR_SPACE;
+ }
+
+ val64 &= ~(VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(7));
+ val64 |=
+ VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(
+ VXGE_HW_MAX_PAYLOAD_SIZE_512);
+
+ val64 |= VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY_EN;
+ writeq(val64, &vp_reg->rtdma_rd_optimization_ctrl);
+
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vp_initialize - Initialize Virtual Path structure
+ * This routine is the initial phase of init which resets the vpath and
+ * initializes the software support structures.
+ */
+enum vxge_hw_status
+__vxge_hw_vp_initialize(struct __vxge_hw_device *hldev, u32 vp_id,
+ struct vxge_hw_vp_config *config)
+{
+ struct __vxge_hw_virtualpath *vpath;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (!(hldev->vpath_assignments & vxge_mBIT(vp_id))) {
+ status = VXGE_HW_ERR_VPATH_NOT_AVAILABLE;
+ goto exit;
+ }
+
+ vpath = &hldev->virtual_paths[vp_id];
+
+ vpath->vp_id = vp_id;
+ vpath->vp_open = VXGE_HW_VP_OPEN;
+ vpath->hldev = hldev;
+ vpath->vp_config = config;
+ vpath->vp_reg = hldev->vpath_reg[vp_id];
+ vpath->vpmgmt_reg = hldev->vpmgmt_reg[vp_id];
+
+ __vxge_hw_vpath_reset(hldev, vp_id);
+
+ status = __vxge_hw_vpath_reset_check(vpath);
+
+ if (status != VXGE_HW_OK) {
+ memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
+ goto exit;
+ }
+
+ status = __vxge_hw_vpath_mgmt_read(hldev, vpath);
+
+ if (status != VXGE_HW_OK) {
+ memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
+ goto exit;
+ }
+
+ INIT_LIST_HEAD(&vpath->vpath_handles);
+
+ vpath->sw_stats = &hldev->stats.sw_dev_info_stats.vpath_info[vp_id];
+
+ VXGE_HW_DEVICE_TIM_INT_MASK_SET(hldev->tim_int_mask0,
+ hldev->tim_int_mask1, vp_id);
+
+ status = __vxge_hw_vpath_initialize(hldev, vp_id);
+
+ if (status != VXGE_HW_OK)
+ __vxge_hw_vp_terminate(hldev, vp_id);
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vp_terminate - Terminate Virtual Path structure
+ * This routine closes all channels it opened and freeup memory
+ */
+void
+__vxge_hw_vp_terminate(struct __vxge_hw_device *hldev, u32 vp_id)
+{
+ struct __vxge_hw_virtualpath *vpath;
+
+ vpath = &hldev->virtual_paths[vp_id];
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN)
+ goto exit;
+
+ VXGE_HW_DEVICE_TIM_INT_MASK_RESET(vpath->hldev->tim_int_mask0,
+ vpath->hldev->tim_int_mask1, vpath->vp_id);
+ hldev->stats.hw_dev_info_stats.vpath_info[vpath->vp_id] = NULL;
+
+ memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
+exit:
+ return;
+}
+
+/*
+ * vxge_hw_vpath_mtu_set - Set MTU.
+ * Set new MTU value. Example, to use jumbo frames:
+ * vxge_hw_vpath_mtu_set(my_device, 9600);
+ */
+enum vxge_hw_status
+vxge_hw_vpath_mtu_set(struct __vxge_hw_vpath_handle *vp, u32 new_mtu)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_virtualpath *vpath;
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+ vpath = vp->vpath;
+
+ new_mtu += VXGE_HW_MAC_HEADER_MAX_SIZE;
+
+ if ((new_mtu < VXGE_HW_MIN_MTU) || (new_mtu > vpath->max_mtu))
+ status = VXGE_HW_ERR_INVALID_MTU_SIZE;
+
+ val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
+
+ val64 &= ~VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(0x3fff);
+ val64 |= VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(new_mtu);
+
+ writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
+
+ vpath->vp_config->mtu = new_mtu - VXGE_HW_MAC_HEADER_MAX_SIZE;
+
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_vpath_open - Open a virtual path on a given adapter
+ * This function is used to open access to virtual path of an
+ * adapter for offload, GRO operations. This function returns
+ * synchronously.
+ */
+enum vxge_hw_status
+vxge_hw_vpath_open(struct __vxge_hw_device *hldev,
+ struct vxge_hw_vpath_attr *attr,
+ struct __vxge_hw_vpath_handle **vpath_handle)
+{
+ struct __vxge_hw_virtualpath *vpath;
+ struct __vxge_hw_vpath_handle *vp;
+ enum vxge_hw_status status;
+
+ vpath = &hldev->virtual_paths[attr->vp_id];
+
+ if (vpath->vp_open == VXGE_HW_VP_OPEN) {
+ status = VXGE_HW_ERR_INVALID_STATE;
+ goto vpath_open_exit1;
+ }
+
+ status = __vxge_hw_vp_initialize(hldev, attr->vp_id,
+ &hldev->config.vp_config[attr->vp_id]);
+
+ if (status != VXGE_HW_OK)
+ goto vpath_open_exit1;
+
+ vp = (struct __vxge_hw_vpath_handle *)
+ vmalloc(sizeof(struct __vxge_hw_vpath_handle));
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto vpath_open_exit2;
+ }
+
+ memset(vp, 0, sizeof(struct __vxge_hw_vpath_handle));
+
+ vp->vpath = vpath;
+
+ if (vpath->vp_config->fifo.enable == VXGE_HW_FIFO_ENABLE) {
+ status = __vxge_hw_fifo_create(vp, &attr->fifo_attr);
+ if (status != VXGE_HW_OK)
+ goto vpath_open_exit6;
+ }
+
+ if (vpath->vp_config->ring.enable == VXGE_HW_RING_ENABLE) {
+ status = __vxge_hw_ring_create(vp, &attr->ring_attr);
+ if (status != VXGE_HW_OK)
+ goto vpath_open_exit7;
+
+ __vxge_hw_vpath_prc_configure(hldev, attr->vp_id);
+ }
+
+ vpath->fifoh->tx_intr_num =
+ (attr->vp_id * VXGE_HW_MAX_INTR_PER_VP) +
+ VXGE_HW_VPATH_INTR_TX;
+
+ vpath->stats_block = __vxge_hw_blockpool_block_allocate(hldev,
+ VXGE_HW_BLOCK_SIZE);
+
+ if (vpath->stats_block == NULL) {
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto vpath_open_exit8;
+ }
+
+ vpath->hw_stats = (struct vxge_hw_vpath_stats_hw_info *)vpath->
+ stats_block->memblock;
+ memset(vpath->hw_stats, 0,
+ sizeof(struct vxge_hw_vpath_stats_hw_info));
+
+ hldev->stats.hw_dev_info_stats.vpath_info[attr->vp_id] =
+ vpath->hw_stats;
+
+ vpath->hw_stats_sav =
+ &hldev->stats.hw_dev_info_stats.vpath_info_sav[attr->vp_id];
+ memset(vpath->hw_stats_sav, 0,
+ sizeof(struct vxge_hw_vpath_stats_hw_info));
+
+ writeq(vpath->stats_block->dma_addr, &vpath->vp_reg->stats_cfg);
+
+ status = vxge_hw_vpath_stats_enable(vp);
+ if (status != VXGE_HW_OK)
+ goto vpath_open_exit8;
+
+ list_add(&vp->item, &vpath->vpath_handles);
+
+ hldev->vpaths_deployed |= vxge_mBIT(vpath->vp_id);
+
+ *vpath_handle = vp;
+
+ attr->fifo_attr.userdata = vpath->fifoh;
+ attr->ring_attr.userdata = vpath->ringh;
+
+ return VXGE_HW_OK;
+
+vpath_open_exit8:
+ if (vpath->ringh != NULL)
+ __vxge_hw_ring_delete(vp);
+vpath_open_exit7:
+ if (vpath->fifoh != NULL)
+ __vxge_hw_fifo_delete(vp);
+vpath_open_exit6:
+ vfree(vp);
+vpath_open_exit2:
+ __vxge_hw_vp_terminate(hldev, attr->vp_id);
+vpath_open_exit1:
+
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_rx_doorbell_post - Close the handle got from previous vpath
+ * (vpath) open
+ * @vp: Handle got from previous vpath open
+ *
+ * This function is used to close access to virtual path opened
+ * earlier.
+ */
+void
+vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp)
+{
+ struct __vxge_hw_virtualpath *vpath = NULL;
+ u64 new_count, val64, val164;
+ struct __vxge_hw_ring *ring;
+
+ vpath = vp->vpath;
+ ring = vpath->ringh;
+
+ new_count = readq(&vpath->vp_reg->rxdmem_size);
+ new_count &= 0x1fff;
+ val164 = (VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(new_count));
+
+ writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(val164),
+ &vpath->vp_reg->prc_rxd_doorbell);
+ readl(&vpath->vp_reg->prc_rxd_doorbell);
+
+ val164 /= 2;
+ val64 = readq(&vpath->vp_reg->prc_cfg6);
+ val64 = VXGE_HW_PRC_CFG6_RXD_SPAT(val64);
+ val64 &= 0x1ff;
+
+ /*
+ * Each RxD is of 4 qwords
+ */
+ new_count -= (val64 + 1);
+ val64 = min(val164, new_count) / 4;
+
+ ring->rxds_limit = min(ring->rxds_limit, val64);
+ if (ring->rxds_limit < 4)
+ ring->rxds_limit = 4;
+}
+
+/*
+ * vxge_hw_vpath_close - Close the handle got from previous vpath (vpath) open
+ * This function is used to close access to virtual path opened
+ * earlier.
+ */
+enum vxge_hw_status vxge_hw_vpath_close(struct __vxge_hw_vpath_handle *vp)
+{
+ struct __vxge_hw_virtualpath *vpath = NULL;
+ struct __vxge_hw_device *devh = NULL;
+ u32 vp_id = vp->vpath->vp_id;
+ u32 is_empty = TRUE;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ vpath = vp->vpath;
+ devh = vpath->hldev;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto vpath_close_exit;
+ }
+
+ list_del(&vp->item);
+
+ if (!list_empty(&vpath->vpath_handles)) {
+ list_add(&vp->item, &vpath->vpath_handles);
+ is_empty = FALSE;
+ }
+
+ if (!is_empty) {
+ status = VXGE_HW_FAIL;
+ goto vpath_close_exit;
+ }
+
+ devh->vpaths_deployed &= ~vxge_mBIT(vp_id);
+
+ if (vpath->ringh != NULL)
+ __vxge_hw_ring_delete(vp);
+
+ if (vpath->fifoh != NULL)
+ __vxge_hw_fifo_delete(vp);
+
+ if (vpath->stats_block != NULL)
+ __vxge_hw_blockpool_block_free(devh, vpath->stats_block);
+
+ vfree(vp);
+
+ __vxge_hw_vp_terminate(devh, vp_id);
+
+ vpath->vp_open = VXGE_HW_VP_NOT_OPEN;
+
+vpath_close_exit:
+ return status;
+}
+
+/*
+ * vxge_hw_vpath_reset - Resets vpath
+ * This function is used to request a reset of vpath
+ */
+enum vxge_hw_status vxge_hw_vpath_reset(struct __vxge_hw_vpath_handle *vp)
+{
+ enum vxge_hw_status status;
+ u32 vp_id;
+ struct __vxge_hw_virtualpath *vpath = vp->vpath;
+
+ vp_id = vpath->vp_id;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto exit;
+ }
+
+ status = __vxge_hw_vpath_reset(vpath->hldev, vp_id);
+ if (status == VXGE_HW_OK)
+ vpath->sw_stats->soft_reset_cnt++;
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_vpath_recover_from_reset - Poll for reset complete and re-initialize.
+ * This function poll's for the vpath reset completion and re initializes
+ * the vpath.
+ */
+enum vxge_hw_status
+vxge_hw_vpath_recover_from_reset(struct __vxge_hw_vpath_handle *vp)
+{
+ struct __vxge_hw_virtualpath *vpath = NULL;
+ enum vxge_hw_status status;
+ struct __vxge_hw_device *hldev;
+ u32 vp_id;
+
+ vp_id = vp->vpath->vp_id;
+ vpath = vp->vpath;
+ hldev = vpath->hldev;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto exit;
+ }
+
+ status = __vxge_hw_vpath_reset_check(vpath);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ status = __vxge_hw_vpath_sw_reset(hldev, vp_id);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ status = __vxge_hw_vpath_initialize(hldev, vp_id);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ if (vpath->ringh != NULL)
+ __vxge_hw_vpath_prc_configure(hldev, vp_id);
+
+ memset(vpath->hw_stats, 0,
+ sizeof(struct vxge_hw_vpath_stats_hw_info));
+
+ memset(vpath->hw_stats_sav, 0,
+ sizeof(struct vxge_hw_vpath_stats_hw_info));
+
+ writeq(vpath->stats_block->dma_addr,
+ &vpath->vp_reg->stats_cfg);
+
+ status = vxge_hw_vpath_stats_enable(vp);
+
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_vpath_enable - Enable vpath.
+ * This routine clears the vpath reset thereby enabling a vpath
+ * to start forwarding frames and generating interrupts.
+ */
+void
+vxge_hw_vpath_enable(struct __vxge_hw_vpath_handle *vp)
+{
+ struct __vxge_hw_device *hldev;
+ u64 val64;
+
+ hldev = vp->vpath->hldev;
+
+ val64 = VXGE_HW_CMN_RSTHDLR_CFG1_CLR_VPATH_RESET(
+ 1 << (16 - vp->vpath->vp_id));
+
+ __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
+ &hldev->common_reg->cmn_rsthdlr_cfg1);
+}
+
+/*
+ * vxge_hw_vpath_stats_enable - Enable vpath h/wstatistics.
+ * Enable the DMA vpath statistics. The function is to be called to re-enable
+ * the adapter to update stats into the host memory
+ */
+enum vxge_hw_status
+vxge_hw_vpath_stats_enable(struct __vxge_hw_vpath_handle *vp)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_virtualpath *vpath;
+
+ vpath = vp->vpath;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto exit;
+ }
+
+ memcpy(vpath->hw_stats_sav, vpath->hw_stats,
+ sizeof(struct vxge_hw_vpath_stats_hw_info));
+
+ status = __vxge_hw_vpath_stats_get(vpath, vpath->hw_stats);
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_stats_access - Get the statistics from the given location
+ * and offset and perform an operation
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_stats_access(struct __vxge_hw_virtualpath *vpath,
+ u32 operation, u32 offset, u64 *stat)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto vpath_stats_access_exit;
+ }
+
+ vp_reg = vpath->vp_reg;
+
+ val64 = VXGE_HW_XMAC_STATS_ACCESS_CMD_OP(operation) |
+ VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE |
+ VXGE_HW_XMAC_STATS_ACCESS_CMD_OFFSET_SEL(offset);
+
+ status = __vxge_hw_pio_mem_write64(val64,
+ &vp_reg->xmac_stats_access_cmd,
+ VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE,
+ vpath->hldev->config.device_poll_millis);
+
+ if ((status == VXGE_HW_OK) && (operation == VXGE_HW_STATS_OP_READ))
+ *stat = readq(&vp_reg->xmac_stats_access_data);
+ else
+ *stat = 0;
+
+vpath_stats_access_exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_xmac_tx_stats_get - Get the TX Statistics of a vpath
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_xmac_tx_stats_get(
+ struct __vxge_hw_virtualpath *vpath,
+ struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats)
+{
+ u64 *val64;
+ int i;
+ u32 offset = VXGE_HW_STATS_VPATH_TX_OFFSET;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ val64 = (u64 *) vpath_tx_stats;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto exit;
+ }
+
+ for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_tx_stats) / 8; i++) {
+ status = __vxge_hw_vpath_stats_access(vpath,
+ VXGE_HW_STATS_OP_READ,
+ offset, val64);
+ if (status != VXGE_HW_OK)
+ goto exit;
+ offset++;
+ val64++;
+ }
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_xmac_rx_stats_get - Get the RX Statistics of a vpath
+ */
+enum vxge_hw_status
+__vxge_hw_vpath_xmac_rx_stats_get(struct __vxge_hw_virtualpath *vpath,
+ struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats)
+{
+ u64 *val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ int i;
+ u32 offset = VXGE_HW_STATS_VPATH_RX_OFFSET;
+ val64 = (u64 *) vpath_rx_stats;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto exit;
+ }
+ for (i = 0; i < sizeof(struct vxge_hw_xmac_vpath_rx_stats) / 8; i++) {
+ status = __vxge_hw_vpath_stats_access(vpath,
+ VXGE_HW_STATS_OP_READ,
+ offset >> 3, val64);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ offset += 8;
+ val64++;
+ }
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_stats_get - Get the vpath hw statistics.
+ */
+enum vxge_hw_status __vxge_hw_vpath_stats_get(
+ struct __vxge_hw_virtualpath *vpath,
+ struct vxge_hw_vpath_stats_hw_info *hw_stats)
+{
+ u64 val64;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto exit;
+ }
+ vp_reg = vpath->vp_reg;
+
+ val64 = readq(&vp_reg->vpath_debug_stats0);
+ hw_stats->ini_num_mwr_sent =
+ (u32)VXGE_HW_VPATH_DEBUG_STATS0_GET_INI_NUM_MWR_SENT(val64);
+
+ val64 = readq(&vp_reg->vpath_debug_stats1);
+ hw_stats->ini_num_mrd_sent =
+ (u32)VXGE_HW_VPATH_DEBUG_STATS1_GET_INI_NUM_MRD_SENT(val64);
+
+ val64 = readq(&vp_reg->vpath_debug_stats2);
+ hw_stats->ini_num_cpl_rcvd =
+ (u32)VXGE_HW_VPATH_DEBUG_STATS2_GET_INI_NUM_CPL_RCVD(val64);
+
+ val64 = readq(&vp_reg->vpath_debug_stats3);
+ hw_stats->ini_num_mwr_byte_sent =
+ VXGE_HW_VPATH_DEBUG_STATS3_GET_INI_NUM_MWR_BYTE_SENT(val64);
+
+ val64 = readq(&vp_reg->vpath_debug_stats4);
+ hw_stats->ini_num_cpl_byte_rcvd =
+ VXGE_HW_VPATH_DEBUG_STATS4_GET_INI_NUM_CPL_BYTE_RCVD(val64);
+
+ val64 = readq(&vp_reg->vpath_debug_stats5);
+ hw_stats->wrcrdtarb_xoff =
+ (u32)VXGE_HW_VPATH_DEBUG_STATS5_GET_WRCRDTARB_XOFF(val64);
+
+ val64 = readq(&vp_reg->vpath_debug_stats6);
+ hw_stats->rdcrdtarb_xoff =
+ (u32)VXGE_HW_VPATH_DEBUG_STATS6_GET_RDCRDTARB_XOFF(val64);
+
+ val64 = readq(&vp_reg->vpath_genstats_count01);
+ hw_stats->vpath_genstats_count0 =
+ (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT0(
+ val64);
+
+ val64 = readq(&vp_reg->vpath_genstats_count01);
+ hw_stats->vpath_genstats_count1 =
+ (u32)VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT1(
+ val64);
+
+ val64 = readq(&vp_reg->vpath_genstats_count23);
+ hw_stats->vpath_genstats_count2 =
+ (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT2(
+ val64);
+
+ val64 = readq(&vp_reg->vpath_genstats_count01);
+ hw_stats->vpath_genstats_count3 =
+ (u32)VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT3(
+ val64);
+
+ val64 = readq(&vp_reg->vpath_genstats_count4);
+ hw_stats->vpath_genstats_count4 =
+ (u32)VXGE_HW_VPATH_GENSTATS_COUNT4_GET_PPIF_VPATH_GENSTATS_COUNT4(
+ val64);
+
+ val64 = readq(&vp_reg->vpath_genstats_count5);
+ hw_stats->vpath_genstats_count5 =
+ (u32)VXGE_HW_VPATH_GENSTATS_COUNT5_GET_PPIF_VPATH_GENSTATS_COUNT5(
+ val64);
+
+ status = __vxge_hw_vpath_xmac_tx_stats_get(vpath, &hw_stats->tx_stats);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ status = __vxge_hw_vpath_xmac_rx_stats_get(vpath, &hw_stats->rx_stats);
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ VXGE_HW_VPATH_STATS_PIO_READ(
+ VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM0_OFFSET);
+
+ hw_stats->prog_event_vnum0 =
+ (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM0(val64);
+
+ hw_stats->prog_event_vnum1 =
+ (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM1(val64);
+
+ VXGE_HW_VPATH_STATS_PIO_READ(
+ VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM2_OFFSET);
+
+ hw_stats->prog_event_vnum2 =
+ (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM2(val64);
+
+ hw_stats->prog_event_vnum3 =
+ (u32)VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM3(val64);
+
+ val64 = readq(&vp_reg->rx_multi_cast_stats);
+ hw_stats->rx_multi_cast_frame_discard =
+ (u16)VXGE_HW_RX_MULTI_CAST_STATS_GET_FRAME_DISCARD(val64);
+
+ val64 = readq(&vp_reg->rx_frm_transferred);
+ hw_stats->rx_frm_transferred =
+ (u32)VXGE_HW_RX_FRM_TRANSFERRED_GET_RX_FRM_TRANSFERRED(val64);
+
+ val64 = readq(&vp_reg->rxd_returned);
+ hw_stats->rxd_returned =
+ (u16)VXGE_HW_RXD_RETURNED_GET_RXD_RETURNED(val64);
+
+ val64 = readq(&vp_reg->dbg_stats_rx_mpa);
+ hw_stats->rx_mpa_len_fail_frms =
+ (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_LEN_FAIL_FRMS(val64);
+ hw_stats->rx_mpa_mrk_fail_frms =
+ (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_MRK_FAIL_FRMS(val64);
+ hw_stats->rx_mpa_crc_fail_frms =
+ (u16)VXGE_HW_DBG_STATS_GET_RX_MPA_CRC_FAIL_FRMS(val64);
+
+ val64 = readq(&vp_reg->dbg_stats_rx_fau);
+ hw_stats->rx_permitted_frms =
+ (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_PERMITTED_FRMS(val64);
+ hw_stats->rx_vp_reset_discarded_frms =
+ (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_VP_RESET_DISCARDED_FRMS(val64);
+ hw_stats->rx_wol_frms =
+ (u16)VXGE_HW_DBG_STATS_GET_RX_FAU_RX_WOL_FRMS(val64);
+
+ val64 = readq(&vp_reg->tx_vp_reset_discarded_frms);
+ hw_stats->tx_vp_reset_discarded_frms =
+ (u16)VXGE_HW_TX_VP_RESET_DISCARDED_FRMS_GET_TX_VP_RESET_DISCARDED_FRMS(
+ val64);
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_blockpool_create - Create block pool
+ */
+
+enum vxge_hw_status
+__vxge_hw_blockpool_create(struct __vxge_hw_device *hldev,
+ struct __vxge_hw_blockpool *blockpool,
+ u32 pool_size,
+ u32 pool_max)
+{
+ u32 i;
+ struct __vxge_hw_blockpool_entry *entry = NULL;
+ void *memblock;
+ dma_addr_t dma_addr;
+ struct pci_dev *dma_handle;
+ struct pci_dev *acc_handle;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (blockpool == NULL) {
+ status = VXGE_HW_FAIL;
+ goto blockpool_create_exit;
+ }
+
+ blockpool->hldev = hldev;
+ blockpool->block_size = VXGE_HW_BLOCK_SIZE;
+ blockpool->pool_size = 0;
+ blockpool->pool_max = pool_max;
+ blockpool->req_out = 0;
+
+ INIT_LIST_HEAD(&blockpool->free_block_list);
+ INIT_LIST_HEAD(&blockpool->free_entry_list);
+
+ for (i = 0; i < pool_size + pool_max; i++) {
+ entry = kzalloc(sizeof(struct __vxge_hw_blockpool_entry),
+ GFP_KERNEL);
+ if (entry == NULL) {
+ __vxge_hw_blockpool_destroy(blockpool);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto blockpool_create_exit;
+ }
+ list_add(&entry->item, &blockpool->free_entry_list);
+ }
+
+ for (i = 0; i < pool_size; i++) {
+
+ memblock = vxge_os_dma_malloc(
+ hldev->pdev,
+ VXGE_HW_BLOCK_SIZE,
+ &dma_handle,
+ &acc_handle);
+
+ if (memblock == NULL) {
+ __vxge_hw_blockpool_destroy(blockpool);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto blockpool_create_exit;
+ }
+
+ dma_addr = pci_map_single(hldev->pdev, memblock,
+ VXGE_HW_BLOCK_SIZE, PCI_DMA_BIDIRECTIONAL);
+
+ if (unlikely(pci_dma_mapping_error(hldev->pdev,
+ dma_addr))) {
+
+ vxge_os_dma_free(hldev->pdev, memblock, &acc_handle);
+ __vxge_hw_blockpool_destroy(blockpool);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto blockpool_create_exit;
+ }
+
+ if (!list_empty(&blockpool->free_entry_list))
+ entry = (struct __vxge_hw_blockpool_entry *)
+ list_first_entry(&blockpool->free_entry_list,
+ struct __vxge_hw_blockpool_entry,
+ item);
+
+ if (entry == NULL)
+ entry =
+ kzalloc(sizeof(struct __vxge_hw_blockpool_entry),
+ GFP_KERNEL);
+ if (entry != NULL) {
+ list_del(&entry->item);
+ entry->length = VXGE_HW_BLOCK_SIZE;
+ entry->memblock = memblock;
+ entry->dma_addr = dma_addr;
+ entry->acc_handle = acc_handle;
+ entry->dma_handle = dma_handle;
+ list_add(&entry->item,
+ &blockpool->free_block_list);
+ blockpool->pool_size++;
+ } else {
+ __vxge_hw_blockpool_destroy(blockpool);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto blockpool_create_exit;
+ }
+ }
+
+blockpool_create_exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_blockpool_destroy - Deallocates the block pool
+ */
+
+void __vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool)
+{
+
+ struct __vxge_hw_device *hldev;
+ struct list_head *p, *n;
+ u16 ret;
+
+ if (blockpool == NULL) {
+ ret = 1;
+ goto exit;
+ }
+
+ hldev = blockpool->hldev;
+
+ list_for_each_safe(p, n, &blockpool->free_block_list) {
+
+ pci_unmap_single(hldev->pdev,
+ ((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
+ ((struct __vxge_hw_blockpool_entry *)p)->length,
+ PCI_DMA_BIDIRECTIONAL);
+
+ vxge_os_dma_free(hldev->pdev,
+ ((struct __vxge_hw_blockpool_entry *)p)->memblock,
+ &((struct __vxge_hw_blockpool_entry *) p)->acc_handle);
+
+ list_del(
+ &((struct __vxge_hw_blockpool_entry *)p)->item);
+ kfree(p);
+ blockpool->pool_size--;
+ }
+
+ list_for_each_safe(p, n, &blockpool->free_entry_list) {
+ list_del(
+ &((struct __vxge_hw_blockpool_entry *)p)->item);
+ kfree((void *)p);
+ }
+ ret = 0;
+exit:
+ return;
+}
+
+/*
+ * __vxge_hw_blockpool_blocks_add - Request additional blocks
+ */
+static
+void __vxge_hw_blockpool_blocks_add(struct __vxge_hw_blockpool *blockpool)
+{
+ u32 nreq = 0, i;
+
+ if ((blockpool->pool_size + blockpool->req_out) <
+ VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE) {
+ nreq = VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE;
+ blockpool->req_out += nreq;
+ }
+
+ for (i = 0; i < nreq; i++)
+ vxge_os_dma_malloc_async(
+ ((struct __vxge_hw_device *)blockpool->hldev)->pdev,
+ blockpool->hldev, VXGE_HW_BLOCK_SIZE);
+}
+
+/*
+ * __vxge_hw_blockpool_blocks_remove - Free additional blocks
+ */
+static
+void __vxge_hw_blockpool_blocks_remove(struct __vxge_hw_blockpool *blockpool)
+{
+ struct list_head *p, *n;
+
+ list_for_each_safe(p, n, &blockpool->free_block_list) {
+
+ if (blockpool->pool_size < blockpool->pool_max)
+ break;
+
+ pci_unmap_single(
+ ((struct __vxge_hw_device *)blockpool->hldev)->pdev,
+ ((struct __vxge_hw_blockpool_entry *)p)->dma_addr,
+ ((struct __vxge_hw_blockpool_entry *)p)->length,
+ PCI_DMA_BIDIRECTIONAL);
+
+ vxge_os_dma_free(
+ ((struct __vxge_hw_device *)blockpool->hldev)->pdev,
+ ((struct __vxge_hw_blockpool_entry *)p)->memblock,
+ &((struct __vxge_hw_blockpool_entry *)p)->acc_handle);
+
+ list_del(&((struct __vxge_hw_blockpool_entry *)p)->item);
+
+ list_add(p, &blockpool->free_entry_list);
+
+ blockpool->pool_size--;
+
+ }
+}
+
+/*
+ * vxge_hw_blockpool_block_add - callback for vxge_os_dma_malloc_async
+ * Adds a block to block pool
+ */
+void vxge_hw_blockpool_block_add(
+ struct __vxge_hw_device *devh,
+ void *block_addr,
+ u32 length,
+ struct pci_dev *dma_h,
+ struct pci_dev *acc_handle)
+{
+ struct __vxge_hw_blockpool *blockpool;
+ struct __vxge_hw_blockpool_entry *entry = NULL;
+ dma_addr_t dma_addr;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ u32 req_out;
+
+ blockpool = &devh->block_pool;
+
+ if (block_addr == NULL) {
+ blockpool->req_out--;
+ status = VXGE_HW_FAIL;
+ goto exit;
+ }
+
+ dma_addr = pci_map_single(devh->pdev, block_addr, length,
+ PCI_DMA_BIDIRECTIONAL);
+
+ if (unlikely(pci_dma_mapping_error(devh->pdev, dma_addr))) {
+
+ vxge_os_dma_free(devh->pdev, block_addr, &acc_handle);
+ blockpool->req_out--;
+ status = VXGE_HW_FAIL;
+ goto exit;
+ }
+
+
+ if (!list_empty(&blockpool->free_entry_list))
+ entry = (struct __vxge_hw_blockpool_entry *)
+ list_first_entry(&blockpool->free_entry_list,
+ struct __vxge_hw_blockpool_entry,
+ item);
+
+ if (entry == NULL)
+ entry = (struct __vxge_hw_blockpool_entry *)
+ vmalloc(sizeof(struct __vxge_hw_blockpool_entry));
+ else
+ list_del(&entry->item);
+
+ if (entry != NULL) {
+ entry->length = length;
+ entry->memblock = block_addr;
+ entry->dma_addr = dma_addr;
+ entry->acc_handle = acc_handle;
+ entry->dma_handle = dma_h;
+ list_add(&entry->item, &blockpool->free_block_list);
+ blockpool->pool_size++;
+ status = VXGE_HW_OK;
+ } else
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+
+ blockpool->req_out--;
+
+ req_out = blockpool->req_out;
+exit:
+ return;
+}
+
+/*
+ * __vxge_hw_blockpool_malloc - Allocate a memory block from pool
+ * Allocates a block of memory of given size, either from block pool
+ * or by calling vxge_os_dma_malloc()
+ */
+void *
+__vxge_hw_blockpool_malloc(struct __vxge_hw_device *devh, u32 size,
+ struct vxge_hw_mempool_dma *dma_object)
+{
+ struct __vxge_hw_blockpool_entry *entry = NULL;
+ struct __vxge_hw_blockpool *blockpool;
+ void *memblock = NULL;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ blockpool = &devh->block_pool;
+
+ if (size != blockpool->block_size) {
+
+ memblock = vxge_os_dma_malloc(devh->pdev, size,
+ &dma_object->handle,
+ &dma_object->acc_handle);
+
+ if (memblock == NULL) {
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto exit;
+ }
+
+ dma_object->addr = pci_map_single(devh->pdev, memblock, size,
+ PCI_DMA_BIDIRECTIONAL);
+
+ if (unlikely(pci_dma_mapping_error(devh->pdev,
+ dma_object->addr))) {
+ vxge_os_dma_free(devh->pdev, memblock,
+ &dma_object->acc_handle);
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+ goto exit;
+ }
+
+ } else {
+
+ if (!list_empty(&blockpool->free_block_list))
+ entry = (struct __vxge_hw_blockpool_entry *)
+ list_first_entry(&blockpool->free_block_list,
+ struct __vxge_hw_blockpool_entry,
+ item);
+
+ if (entry != NULL) {
+ list_del(&entry->item);
+ dma_object->addr = entry->dma_addr;
+ dma_object->handle = entry->dma_handle;
+ dma_object->acc_handle = entry->acc_handle;
+ memblock = entry->memblock;
+
+ list_add(&entry->item,
+ &blockpool->free_entry_list);
+ blockpool->pool_size--;
+ }
+
+ if (memblock != NULL)
+ __vxge_hw_blockpool_blocks_add(blockpool);
+ }
+exit:
+ return memblock;
+}
+
+/*
+ * __vxge_hw_blockpool_free - Frees the memory allcoated with
+ __vxge_hw_blockpool_malloc
+ */
+void
+__vxge_hw_blockpool_free(struct __vxge_hw_device *devh,
+ void *memblock, u32 size,
+ struct vxge_hw_mempool_dma *dma_object)
+{
+ struct __vxge_hw_blockpool_entry *entry = NULL;
+ struct __vxge_hw_blockpool *blockpool;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ blockpool = &devh->block_pool;
+
+ if (size != blockpool->block_size) {
+ pci_unmap_single(devh->pdev, dma_object->addr, size,
+ PCI_DMA_BIDIRECTIONAL);
+ vxge_os_dma_free(devh->pdev, memblock, &dma_object->acc_handle);
+ } else {
+
+ if (!list_empty(&blockpool->free_entry_list))
+ entry = (struct __vxge_hw_blockpool_entry *)
+ list_first_entry(&blockpool->free_entry_list,
+ struct __vxge_hw_blockpool_entry,
+ item);
+
+ if (entry == NULL)
+ entry = (struct __vxge_hw_blockpool_entry *)
+ vmalloc(sizeof(
+ struct __vxge_hw_blockpool_entry));
+ else
+ list_del(&entry->item);
+
+ if (entry != NULL) {
+ entry->length = size;
+ entry->memblock = memblock;
+ entry->dma_addr = dma_object->addr;
+ entry->acc_handle = dma_object->acc_handle;
+ entry->dma_handle = dma_object->handle;
+ list_add(&entry->item,
+ &blockpool->free_block_list);
+ blockpool->pool_size++;
+ status = VXGE_HW_OK;
+ } else
+ status = VXGE_HW_ERR_OUT_OF_MEMORY;
+
+ if (status == VXGE_HW_OK)
+ __vxge_hw_blockpool_blocks_remove(blockpool);
+ }
+
+ return;
+}
+
+/*
+ * __vxge_hw_blockpool_block_allocate - Allocates a block from block pool
+ * This function allocates a block from block pool or from the system
+ */
+struct __vxge_hw_blockpool_entry *
+__vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *devh, u32 size)
+{
+ struct __vxge_hw_blockpool_entry *entry = NULL;
+ struct __vxge_hw_blockpool *blockpool;
+
+ blockpool = &devh->block_pool;
+
+ if (size == blockpool->block_size) {
+
+ if (!list_empty(&blockpool->free_block_list))
+ entry = (struct __vxge_hw_blockpool_entry *)
+ list_first_entry(&blockpool->free_block_list,
+ struct __vxge_hw_blockpool_entry,
+ item);
+
+ if (entry != NULL) {
+ list_del(&entry->item);
+ blockpool->pool_size--;
+ }
+ }
+
+ if (entry != NULL)
+ __vxge_hw_blockpool_blocks_add(blockpool);
+
+ return entry;
+}
+
+/*
+ * __vxge_hw_blockpool_block_free - Frees a block from block pool
+ * @devh: Hal device
+ * @entry: Entry of block to be freed
+ *
+ * This function frees a block from block pool
+ */
+void
+__vxge_hw_blockpool_block_free(struct __vxge_hw_device *devh,
+ struct __vxge_hw_blockpool_entry *entry)
+{
+ struct __vxge_hw_blockpool *blockpool;
+
+ blockpool = &devh->block_pool;
+
+ if (entry->length == blockpool->block_size) {
+ list_add(&entry->item, &blockpool->free_block_list);
+ blockpool->pool_size++;
+ }
+
+ __vxge_hw_blockpool_blocks_remove(blockpool);
+
+ return;
+}
diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h
new file mode 100644
index 000000000000..afbdf6f4d224
--- /dev/null
+++ b/drivers/net/vxge/vxge-config.h
@@ -0,0 +1,2259 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice. This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-config.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#ifndef VXGE_CONFIG_H
+#define VXGE_CONFIG_H
+#include <linux/list.h>
+
+#ifndef VXGE_CACHE_LINE_SIZE
+#define VXGE_CACHE_LINE_SIZE 128
+#endif
+
+#define vxge_os_vaprintf(level, mask, fmt, ...) { \
+ char buff[255]; \
+ snprintf(buff, 255, fmt, __VA_ARGS__); \
+ printk(buff); \
+ printk("\n"); \
+}
+
+#ifndef VXGE_ALIGN
+#define VXGE_ALIGN(adrs, size) \
+ (((size) - (((u64)adrs) & ((size)-1))) & ((size)-1))
+#endif
+
+#define VXGE_HW_MIN_MTU 68
+#define VXGE_HW_MAX_MTU 9600
+#define VXGE_HW_DEFAULT_MTU 1500
+
+#ifdef VXGE_DEBUG_ASSERT
+
+/**
+ * vxge_assert
+ * @test: C-condition to check
+ * @fmt: printf like format string
+ *
+ * This function implements traditional assert. By default assertions
+ * are enabled. It can be disabled by undefining VXGE_DEBUG_ASSERT macro in
+ * compilation
+ * time.
+ */
+#define vxge_assert(test) { \
+ if (!(test)) \
+ vxge_os_bug("bad cond: "#test" at %s:%d\n", \
+ __FILE__, __LINE__); }
+#else
+#define vxge_assert(test)
+#endif /* end of VXGE_DEBUG_ASSERT */
+
+/**
+ * enum enum vxge_debug_level
+ * @VXGE_NONE: debug disabled
+ * @VXGE_ERR: all errors going to be logged out
+ * @VXGE_TRACE: all errors plus all kind of verbose tracing print outs
+ * going to be logged out. Very noisy.
+ *
+ * This enumeration going to be used to switch between different
+ * debug levels during runtime if DEBUG macro defined during
+ * compilation. If DEBUG macro not defined than code will be
+ * compiled out.
+ */
+enum vxge_debug_level {
+ VXGE_NONE = 0,
+ VXGE_TRACE = 1,
+ VXGE_ERR = 2
+};
+
+#define NULL_VPID 0xFFFFFFFF
+#ifdef CONFIG_VXGE_DEBUG_TRACE_ALL
+#define VXGE_DEBUG_MODULE_MASK 0xffffffff
+#define VXGE_DEBUG_TRACE_MASK 0xffffffff
+#define VXGE_DEBUG_ERR_MASK 0xffffffff
+#define VXGE_DEBUG_MASK 0x000001ff
+#else
+#define VXGE_DEBUG_MODULE_MASK 0x20000000
+#define VXGE_DEBUG_TRACE_MASK 0x20000000
+#define VXGE_DEBUG_ERR_MASK 0x20000000
+#define VXGE_DEBUG_MASK 0x00000001
+#endif
+
+/*
+ * @VXGE_COMPONENT_LL: do debug for vxge link layer module
+ * @VXGE_COMPONENT_ALL: activate debug for all modules with no exceptions
+ *
+ * This enumeration going to be used to distinguish modules
+ * or libraries during compilation and runtime. Makefile must declare
+ * VXGE_DEBUG_MODULE_MASK macro and set it to proper value.
+ */
+#define VXGE_COMPONENT_LL 0x20000000
+#define VXGE_COMPONENT_ALL 0xffffffff
+
+#define VXGE_HW_BASE_INF 100
+#define VXGE_HW_BASE_ERR 200
+#define VXGE_HW_BASE_BADCFG 300
+
+enum vxge_hw_status {
+ VXGE_HW_OK = 0,
+ VXGE_HW_FAIL = 1,
+ VXGE_HW_PENDING = 2,
+ VXGE_HW_COMPLETIONS_REMAIN = 3,
+
+ VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS = VXGE_HW_BASE_INF + 1,
+ VXGE_HW_INF_OUT_OF_DESCRIPTORS = VXGE_HW_BASE_INF + 2,
+
+ VXGE_HW_ERR_INVALID_HANDLE = VXGE_HW_BASE_ERR + 1,
+ VXGE_HW_ERR_OUT_OF_MEMORY = VXGE_HW_BASE_ERR + 2,
+ VXGE_HW_ERR_VPATH_NOT_AVAILABLE = VXGE_HW_BASE_ERR + 3,
+ VXGE_HW_ERR_VPATH_NOT_OPEN = VXGE_HW_BASE_ERR + 4,
+ VXGE_HW_ERR_WRONG_IRQ = VXGE_HW_BASE_ERR + 5,
+ VXGE_HW_ERR_SWAPPER_CTRL = VXGE_HW_BASE_ERR + 6,
+ VXGE_HW_ERR_INVALID_MTU_SIZE = VXGE_HW_BASE_ERR + 7,
+ VXGE_HW_ERR_INVALID_INDEX = VXGE_HW_BASE_ERR + 8,
+ VXGE_HW_ERR_INVALID_TYPE = VXGE_HW_BASE_ERR + 9,
+ VXGE_HW_ERR_INVALID_OFFSET = VXGE_HW_BASE_ERR + 10,
+ VXGE_HW_ERR_INVALID_DEVICE = VXGE_HW_BASE_ERR + 11,
+ VXGE_HW_ERR_VERSION_CONFLICT = VXGE_HW_BASE_ERR + 12,
+ VXGE_HW_ERR_INVALID_PCI_INFO = VXGE_HW_BASE_ERR + 13,
+ VXGE_HW_ERR_INVALID_TCODE = VXGE_HW_BASE_ERR + 14,
+ VXGE_HW_ERR_INVALID_BLOCK_SIZE = VXGE_HW_BASE_ERR + 15,
+ VXGE_HW_ERR_INVALID_STATE = VXGE_HW_BASE_ERR + 16,
+ VXGE_HW_ERR_PRIVILAGED_OPEARATION = VXGE_HW_BASE_ERR + 17,
+ VXGE_HW_ERR_INVALID_PORT = VXGE_HW_BASE_ERR + 18,
+ VXGE_HW_ERR_FIFO = VXGE_HW_BASE_ERR + 19,
+ VXGE_HW_ERR_VPATH = VXGE_HW_BASE_ERR + 20,
+ VXGE_HW_ERR_CRITICAL = VXGE_HW_BASE_ERR + 21,
+ VXGE_HW_ERR_SLOT_FREEZE = VXGE_HW_BASE_ERR + 22,
+
+ VXGE_HW_BADCFG_RING_INDICATE_MAX_PKTS = VXGE_HW_BASE_BADCFG + 1,
+ VXGE_HW_BADCFG_FIFO_BLOCKS = VXGE_HW_BASE_BADCFG + 2,
+ VXGE_HW_BADCFG_VPATH_MTU = VXGE_HW_BASE_BADCFG + 3,
+ VXGE_HW_BADCFG_VPATH_RPA_STRIP_VLAN_TAG = VXGE_HW_BASE_BADCFG + 4,
+ VXGE_HW_BADCFG_VPATH_MIN_BANDWIDTH = VXGE_HW_BASE_BADCFG + 5,
+ VXGE_HW_BADCFG_INTR_MODE = VXGE_HW_BASE_BADCFG + 6,
+ VXGE_HW_BADCFG_RTS_MAC_EN = VXGE_HW_BASE_BADCFG + 7,
+
+ VXGE_HW_EOF_TRACE_BUF = -1
+};
+
+/**
+ * enum enum vxge_hw_device_link_state - Link state enumeration.
+ * @VXGE_HW_LINK_NONE: Invalid link state.
+ * @VXGE_HW_LINK_DOWN: Link is down.
+ * @VXGE_HW_LINK_UP: Link is up.
+ *
+ */
+enum vxge_hw_device_link_state {
+ VXGE_HW_LINK_NONE,
+ VXGE_HW_LINK_DOWN,
+ VXGE_HW_LINK_UP
+};
+
+/**
+ * struct vxge_hw_device_date - Date Format
+ * @day: Day
+ * @month: Month
+ * @year: Year
+ * @date: Date in string format
+ *
+ * Structure for returning date
+ */
+
+#define VXGE_HW_FW_STRLEN 32
+struct vxge_hw_device_date {
+ u32 day;
+ u32 month;
+ u32 year;
+ char date[VXGE_HW_FW_STRLEN];
+};
+
+struct vxge_hw_device_version {
+ u32 major;
+ u32 minor;
+ u32 build;
+ char version[VXGE_HW_FW_STRLEN];
+};
+
+u64
+__vxge_hw_vpath_pci_func_mode_get(
+ u32 vp_id,
+ struct vxge_hw_vpath_reg __iomem *vpath_reg);
+
+/**
+ * struct vxge_hw_fifo_config - Configuration of fifo.
+ * @enable: Is this fifo to be commissioned
+ * @fifo_blocks: Numbers of TxDL (that is, lists of Tx descriptors)
+ * blocks per queue.
+ * @max_frags: Max number of Tx buffers per TxDL (that is, per single
+ * transmit operation).
+ * No more than 256 transmit buffers can be specified.
+ * @memblock_size: Fifo descriptors are allocated in blocks of @mem_block_size
+ * bytes. Setting @memblock_size to page size ensures
+ * by-page allocation of descriptors. 128K bytes is the
+ * maximum supported block size.
+ * @alignment_size: per Tx fragment DMA-able memory used to align transmit data
+ * (e.g., to align on a cache line).
+ * @intr: Boolean. Use 1 to generate interrupt for each completed TxDL.
+ * Use 0 otherwise.
+ * @no_snoop_bits: If non-zero, specifies no-snoop PCI operation,
+ * which generally improves latency of the host bridge operation
+ * (see PCI specification). For valid values please refer
+ * to struct vxge_hw_fifo_config{} in the driver sources.
+ * Configuration of all Titan fifos.
+ * Note: Valid (min, max) range for each attribute is specified in the body of
+ * the struct vxge_hw_fifo_config{} structure.
+ */
+struct vxge_hw_fifo_config {
+ u32 enable;
+#define VXGE_HW_FIFO_ENABLE 1
+#define VXGE_HW_FIFO_DISABLE 0
+
+ u32 fifo_blocks;
+#define VXGE_HW_MIN_FIFO_BLOCKS 2
+#define VXGE_HW_MAX_FIFO_BLOCKS 128
+
+ u32 max_frags;
+#define VXGE_HW_MIN_FIFO_FRAGS 1
+#define VXGE_HW_MAX_FIFO_FRAGS 256
+
+ u32 memblock_size;
+#define VXGE_HW_MIN_FIFO_MEMBLOCK_SIZE VXGE_HW_BLOCK_SIZE
+#define VXGE_HW_MAX_FIFO_MEMBLOCK_SIZE 131072
+#define VXGE_HW_DEF_FIFO_MEMBLOCK_SIZE 8096
+
+ u32 alignment_size;
+#define VXGE_HW_MIN_FIFO_ALIGNMENT_SIZE 0
+#define VXGE_HW_MAX_FIFO_ALIGNMENT_SIZE 65536
+#define VXGE_HW_DEF_FIFO_ALIGNMENT_SIZE VXGE_CACHE_LINE_SIZE
+
+ u32 intr;
+#define VXGE_HW_FIFO_QUEUE_INTR_ENABLE 1
+#define VXGE_HW_FIFO_QUEUE_INTR_DISABLE 0
+#define VXGE_HW_FIFO_QUEUE_INTR_DEFAULT 0
+
+ u32 no_snoop_bits;
+#define VXGE_HW_FIFO_NO_SNOOP_DISABLED 0
+#define VXGE_HW_FIFO_NO_SNOOP_TXD 1
+#define VXGE_HW_FIFO_NO_SNOOP_FRM 2
+#define VXGE_HW_FIFO_NO_SNOOP_ALL 3
+#define VXGE_HW_FIFO_NO_SNOOP_DEFAULT 0
+
+};
+/**
+ * struct vxge_hw_ring_config - Ring configurations.
+ * @enable: Is this ring to be commissioned
+ * @ring_blocks: Numbers of RxD blocks in the ring
+ * @buffer_mode: Receive buffer mode (1, 2, 3, or 5); for details please refer
+ * to Titan User Guide.
+ * @scatter_mode: Titan supports two receive scatter modes: A and B.
+ * For details please refer to Titan User Guide.
+ * @rx_timer_val: The number of 32ns periods that would be counted between two
+ * timer interrupts.
+ * @greedy_return: If Set it forces the device to return absolutely all RxD
+ * that are consumed and still on board when a timer interrupt
+ * triggers. If Clear, then if the device has already returned
+ * RxD before current timer interrupt trigerred and after the
+ * previous timer interrupt triggered, then the device is not
+ * forced to returned the rest of the consumed RxD that it has
+ * on board which account for a byte count less than the one
+ * programmed into PRC_CFG6.RXD_CRXDT field
+ * @rx_timer_ci: TBD
+ * @backoff_interval_us: Time (in microseconds), after which Titan
+ * tries to download RxDs posted by the host.
+ * Note that the "backoff" does not happen if host posts receive
+ * descriptors in the timely fashion.
+ * Ring configuration.
+ */
+struct vxge_hw_ring_config {
+ u32 enable;
+#define VXGE_HW_RING_ENABLE 1
+#define VXGE_HW_RING_DISABLE 0
+#define VXGE_HW_RING_DEFAULT 1
+
+ u32 ring_blocks;
+#define VXGE_HW_MIN_RING_BLOCKS 1
+#define VXGE_HW_MAX_RING_BLOCKS 128
+#define VXGE_HW_DEF_RING_BLOCKS 2
+
+ u32 buffer_mode;
+#define VXGE_HW_RING_RXD_BUFFER_MODE_1 1
+#define VXGE_HW_RING_RXD_BUFFER_MODE_3 3
+#define VXGE_HW_RING_RXD_BUFFER_MODE_5 5
+#define VXGE_HW_RING_RXD_BUFFER_MODE_DEFAULT 1
+
+ u32 scatter_mode;
+#define VXGE_HW_RING_SCATTER_MODE_A 0
+#define VXGE_HW_RING_SCATTER_MODE_B 1
+#define VXGE_HW_RING_SCATTER_MODE_C 2
+#define VXGE_HW_RING_SCATTER_MODE_USE_FLASH_DEFAULT 0xffffffff
+
+ u64 rxds_limit;
+#define VXGE_HW_DEF_RING_RXDS_LIMIT 44
+};
+
+/**
+ * struct vxge_hw_vp_config - Configuration of virtual path
+ * @vp_id: Virtual Path Id
+ * @min_bandwidth: Minimum Guaranteed bandwidth
+ * @ring: See struct vxge_hw_ring_config{}.
+ * @fifo: See struct vxge_hw_fifo_config{}.
+ * @tti: Configuration of interrupt associated with Transmit.
+ * see struct vxge_hw_tim_intr_config();
+ * @rti: Configuration of interrupt associated with Receive.
+ * see struct vxge_hw_tim_intr_config();
+ * @mtu: mtu size used on this port.
+ * @rpa_strip_vlan_tag: Strip VLAN Tag enable/disable. Instructs the device to
+ * remove the VLAN tag from all received tagged frames that are not
+ * replicated at the internal L2 switch.
+ * 0 - Do not strip the VLAN tag.
+ * 1 - Strip the VLAN tag. Regardless of this setting, VLAN tags are
+ * always placed into the RxDMA descriptor.
+ *
+ * This structure is used by the driver to pass the configuration parameters to
+ * configure Virtual Path.
+ */
+struct vxge_hw_vp_config {
+ u32 vp_id;
+
+#define VXGE_HW_VPATH_PRIORITY_MIN 0
+#define VXGE_HW_VPATH_PRIORITY_MAX 16
+#define VXGE_HW_VPATH_PRIORITY_DEFAULT 0
+
+ u32 min_bandwidth;
+#define VXGE_HW_VPATH_BANDWIDTH_MIN 0
+#define VXGE_HW_VPATH_BANDWIDTH_MAX 100
+#define VXGE_HW_VPATH_BANDWIDTH_DEFAULT 0
+
+ struct vxge_hw_ring_config ring;
+ struct vxge_hw_fifo_config fifo;
+ struct vxge_hw_tim_intr_config tti;
+ struct vxge_hw_tim_intr_config rti;
+
+ u32 mtu;
+#define VXGE_HW_VPATH_MIN_INITIAL_MTU VXGE_HW_MIN_MTU
+#define VXGE_HW_VPATH_MAX_INITIAL_MTU VXGE_HW_MAX_MTU
+#define VXGE_HW_VPATH_USE_FLASH_DEFAULT_INITIAL_MTU 0xffffffff
+
+ u32 rpa_strip_vlan_tag;
+#define VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE 1
+#define VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_DISABLE 0
+#define VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_USE_FLASH_DEFAULT 0xffffffff
+
+};
+/**
+ * struct vxge_hw_device_config - Device configuration.
+ * @dma_blockpool_initial: Initial size of DMA Pool
+ * @dma_blockpool_max: Maximum blocks in DMA pool
+ * @intr_mode: Line, or MSI-X interrupt.
+ *
+ * @rth_en: Enable Receive Traffic Hashing(RTH) using IT(Indirection Table).
+ * @rth_it_type: RTH IT table programming type
+ * @rts_mac_en: Enable Receive Traffic Steering using MAC destination address
+ * @vp_config: Configuration for virtual paths
+ * @device_poll_millis: Specify the interval (in mulliseconds)
+ * to wait for register reads
+ *
+ * Titan configuration.
+ * Contains per-device configuration parameters, including:
+ * - stats sampling interval, etc.
+ *
+ * In addition, struct vxge_hw_device_config{} includes "subordinate"
+ * configurations, including:
+ * - fifos and rings;
+ * - MAC (done at firmware level).
+ *
+ * See Titan User Guide for more details.
+ * Note: Valid (min, max) range for each attribute is specified in the body of
+ * the struct vxge_hw_device_config{} structure. Please refer to the
+ * corresponding include file.
+ * See also: struct vxge_hw_tim_intr_config{}.
+ */
+struct vxge_hw_device_config {
+ u32 dma_blockpool_initial;
+ u32 dma_blockpool_max;
+#define VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE 0
+#define VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE 0
+#define VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE 4
+#define VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE 4096
+
+#define VXGE_HW_MAX_PAYLOAD_SIZE_512 2
+
+ u32 intr_mode;
+#define VXGE_HW_INTR_MODE_IRQLINE 0
+#define VXGE_HW_INTR_MODE_MSIX 1
+#define VXGE_HW_INTR_MODE_MSIX_ONE_SHOT 2
+
+#define VXGE_HW_INTR_MODE_DEF 0
+
+ u32 rth_en;
+#define VXGE_HW_RTH_DISABLE 0
+#define VXGE_HW_RTH_ENABLE 1
+#define VXGE_HW_RTH_DEFAULT 0
+
+ u32 rth_it_type;
+#define VXGE_HW_RTH_IT_TYPE_SOLO_IT 0
+#define VXGE_HW_RTH_IT_TYPE_MULTI_IT 1
+#define VXGE_HW_RTH_IT_TYPE_DEFAULT 0
+
+ u32 rts_mac_en;
+#define VXGE_HW_RTS_MAC_DISABLE 0
+#define VXGE_HW_RTS_MAC_ENABLE 1
+#define VXGE_HW_RTS_MAC_DEFAULT 0
+
+ struct vxge_hw_vp_config vp_config[VXGE_HW_MAX_VIRTUAL_PATHS];
+
+ u32 device_poll_millis;
+#define VXGE_HW_MIN_DEVICE_POLL_MILLIS 1
+#define VXGE_HW_MAX_DEVICE_POLL_MILLIS 100000
+#define VXGE_HW_DEF_DEVICE_POLL_MILLIS 1000
+
+};
+
+/**
+ * function vxge_uld_link_up_f - Link-Up callback provided by driver.
+ * @devh: HW device handle.
+ * Link-up notification callback provided by the driver.
+ * This is one of the per-driver callbacks, see struct vxge_hw_uld_cbs{}.
+ *
+ * See also: struct vxge_hw_uld_cbs{}, vxge_uld_link_down_f{},
+ * vxge_hw_driver_initialize().
+ */
+
+/**
+ * function vxge_uld_link_down_f - Link-Down callback provided by
+ * driver.
+ * @devh: HW device handle.
+ *
+ * Link-Down notification callback provided by the driver.
+ * This is one of the per-driver callbacks, see struct vxge_hw_uld_cbs{}.
+ *
+ * See also: struct vxge_hw_uld_cbs{}, vxge_uld_link_up_f{},
+ * vxge_hw_driver_initialize().
+ */
+
+/**
+ * function vxge_uld_crit_err_f - Critical Error notification callback.
+ * @devh: HW device handle.
+ * (typically - at HW device iinitialization time).
+ * @type: Enumerated hw error, e.g.: double ECC.
+ * @serr_data: Titan status.
+ * @ext_data: Extended data. The contents depends on the @type.
+ *
+ * Link-Down notification callback provided by the driver.
+ * This is one of the per-driver callbacks, see struct vxge_hw_uld_cbs{}.
+ *
+ * See also: struct vxge_hw_uld_cbs{}, enum vxge_hw_event{},
+ * vxge_hw_driver_initialize().
+ */
+
+/**
+ * struct vxge_hw_uld_cbs - driver "slow-path" callbacks.
+ * @link_up: See vxge_uld_link_up_f{}.
+ * @link_down: See vxge_uld_link_down_f{}.
+ * @crit_err: See vxge_uld_crit_err_f{}.
+ *
+ * Driver slow-path (per-driver) callbacks.
+ * Implemented by driver and provided to HW via
+ * vxge_hw_driver_initialize().
+ * Note that these callbacks are not mandatory: HW will not invoke
+ * a callback if NULL is specified.
+ *
+ * See also: vxge_hw_driver_initialize().
+ */
+struct vxge_hw_uld_cbs {
+
+ void (*link_up)(struct __vxge_hw_device *devh);
+ void (*link_down)(struct __vxge_hw_device *devh);
+ void (*crit_err)(struct __vxge_hw_device *devh,
+ enum vxge_hw_event type, u64 ext_data);
+};
+
+/*
+ * struct __vxge_hw_blockpool_entry - Block private data structure
+ * @item: List header used to link.
+ * @length: Length of the block
+ * @memblock: Virtual address block
+ * @dma_addr: DMA Address of the block.
+ * @dma_handle: DMA handle of the block.
+ * @acc_handle: DMA acc handle
+ *
+ * Block is allocated with a header to put the blocks into list.
+ *
+ */
+struct __vxge_hw_blockpool_entry {
+ struct list_head item;
+ u32 length;
+ void *memblock;
+ dma_addr_t dma_addr;
+ struct pci_dev *dma_handle;
+ struct pci_dev *acc_handle;
+};
+
+/*
+ * struct __vxge_hw_blockpool - Block Pool
+ * @hldev: HW device
+ * @block_size: size of each block.
+ * @Pool_size: Number of blocks in the pool
+ * @pool_max: Maximum number of blocks above which to free additional blocks
+ * @req_out: Number of block requests with OS out standing
+ * @free_block_list: List of free blocks
+ *
+ * Block pool contains the DMA blocks preallocated.
+ *
+ */
+struct __vxge_hw_blockpool {
+ struct __vxge_hw_device *hldev;
+ u32 block_size;
+ u32 pool_size;
+ u32 pool_max;
+ u32 req_out;
+ struct list_head free_block_list;
+ struct list_head free_entry_list;
+};
+
+/*
+ * enum enum __vxge_hw_channel_type - Enumerated channel types.
+ * @VXGE_HW_CHANNEL_TYPE_UNKNOWN: Unknown channel.
+ * @VXGE_HW_CHANNEL_TYPE_FIFO: fifo.
+ * @VXGE_HW_CHANNEL_TYPE_RING: ring.
+ * @VXGE_HW_CHANNEL_TYPE_MAX: Maximum number of HW-supported
+ * (and recognized) channel types. Currently: 2.
+ *
+ * Enumerated channel types. Currently there are only two link-layer
+ * channels - Titan fifo and Titan ring. In the future the list will grow.
+ */
+enum __vxge_hw_channel_type {
+ VXGE_HW_CHANNEL_TYPE_UNKNOWN = 0,
+ VXGE_HW_CHANNEL_TYPE_FIFO = 1,
+ VXGE_HW_CHANNEL_TYPE_RING = 2,
+ VXGE_HW_CHANNEL_TYPE_MAX = 3
+};
+
+/*
+ * struct __vxge_hw_channel
+ * @item: List item; used to maintain a list of open channels.
+ * @type: Channel type. See enum vxge_hw_channel_type{}.
+ * @devh: Device handle. HW device object that contains _this_ channel.
+ * @vph: Virtual path handle. Virtual Path Object that contains _this_ channel.
+ * @length: Channel length. Currently allocated number of descriptors.
+ * The channel length "grows" when more descriptors get allocated.
+ * See _hw_mempool_grow.
+ * @reserve_arr: Reserve array. Contains descriptors that can be reserved
+ * by driver for the subsequent send or receive operation.
+ * See vxge_hw_fifo_txdl_reserve(),
+ * vxge_hw_ring_rxd_reserve().
+ * @reserve_ptr: Current pointer in the resrve array
+ * @reserve_top: Reserve top gives the maximum number of dtrs available in
+ * reserve array.
+ * @work_arr: Work array. Contains descriptors posted to the channel.
+ * Note that at any point in time @work_arr contains 3 types of
+ * descriptors:
+ * 1) posted but not yet consumed by Titan device;
+ * 2) consumed but not yet completed;
+ * 3) completed but not yet freed
+ * (via vxge_hw_fifo_txdl_free() or vxge_hw_ring_rxd_free())
+ * @post_index: Post index. At any point in time points on the
+ * position in the channel, which'll contain next to-be-posted
+ * descriptor.
+ * @compl_index: Completion index. At any point in time points on the
+ * position in the channel, which will contain next
+ * to-be-completed descriptor.
+ * @free_arr: Free array. Contains completed descriptors that were freed
+ * (i.e., handed over back to HW) by driver.
+ * See vxge_hw_fifo_txdl_free(), vxge_hw_ring_rxd_free().
+ * @free_ptr: current pointer in free array
+ * @per_dtr_space: Per-descriptor space (in bytes) that channel user can utilize
+ * to store per-operation control information.
+ * @stats: Pointer to common statistics
+ * @userdata: Per-channel opaque (void*) user-defined context, which may be
+ * driver object, ULP connection, etc.
+ * Once channel is open, @userdata is passed back to user via
+ * vxge_hw_channel_callback_f.
+ *
+ * HW channel object.
+ *
+ * See also: enum vxge_hw_channel_type{}, enum vxge_hw_channel_flag
+ */
+struct __vxge_hw_channel {
+ struct list_head item;
+ enum __vxge_hw_channel_type type;
+ struct __vxge_hw_device *devh;
+ struct __vxge_hw_vpath_handle *vph;
+ u32 length;
+ u32 vp_id;
+ void **reserve_arr;
+ u32 reserve_ptr;
+ u32 reserve_top;
+ void **work_arr;
+ u32 post_index ____cacheline_aligned;
+ u32 compl_index ____cacheline_aligned;
+ void **free_arr;
+ u32 free_ptr;
+ void **orig_arr;
+ u32 per_dtr_space;
+ void *userdata;
+ struct vxge_hw_common_reg __iomem *common_reg;
+ u32 first_vp_id;
+ struct vxge_hw_vpath_stats_sw_common_info *stats;
+
+} ____cacheline_aligned;
+
+/*
+ * struct __vxge_hw_virtualpath - Virtual Path
+ *
+ * @vp_id: Virtual path id
+ * @vp_open: This flag specifies if vxge_hw_vp_open is called from LL Driver
+ * @hldev: Hal device
+ * @vp_config: Virtual Path Config
+ * @vp_reg: VPATH Register map address in BAR0
+ * @vpmgmt_reg: VPATH_MGMT register map address
+ * @max_mtu: Max mtu that can be supported
+ * @vsport_number: vsport attached to this vpath
+ * @max_kdfc_db: Maximum kernel mode doorbells
+ * @max_nofl_db: Maximum non offload doorbells
+ * @tx_intr_num: Interrupt Number associated with the TX
+
+ * @ringh: Ring Queue
+ * @fifoh: FIFO Queue
+ * @vpath_handles: Virtual Path handles list
+ * @stats_block: Memory for DMAing stats
+ * @stats: Vpath statistics
+ *
+ * Virtual path structure to encapsulate the data related to a virtual path.
+ * Virtual paths are allocated by the HW upon getting configuration from the
+ * driver and inserted into the list of virtual paths.
+ */
+struct __vxge_hw_virtualpath {
+ u32 vp_id;
+
+ u32 vp_open;
+#define VXGE_HW_VP_NOT_OPEN 0
+#define VXGE_HW_VP_OPEN 1
+
+ struct __vxge_hw_device *hldev;
+ struct vxge_hw_vp_config *vp_config;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+ struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg;
+ struct __vxge_hw_non_offload_db_wrapper __iomem *nofl_db;
+
+ u32 max_mtu;
+ u32 vsport_number;
+ u32 max_kdfc_db;
+ u32 max_nofl_db;
+
+ struct __vxge_hw_ring *____cacheline_aligned ringh;
+ struct __vxge_hw_fifo *____cacheline_aligned fifoh;
+ struct list_head vpath_handles;
+ struct __vxge_hw_blockpool_entry *stats_block;
+ struct vxge_hw_vpath_stats_hw_info *hw_stats;
+ struct vxge_hw_vpath_stats_hw_info *hw_stats_sav;
+ struct vxge_hw_vpath_stats_sw_info *sw_stats;
+};
+
+/*
+ * struct __vxge_hw_vpath_handle - List item to store callback information
+ * @item: List head to keep the item in linked list
+ * @vpath: Virtual path to which this item belongs
+ *
+ * This structure is used to store the callback information.
+ */
+struct __vxge_hw_vpath_handle{
+ struct list_head item;
+ struct __vxge_hw_virtualpath *vpath;
+};
+
+/*
+ * struct __vxge_hw_device
+ *
+ * HW device object.
+ */
+/**
+ * struct __vxge_hw_device - Hal device object
+ * @magic: Magic Number
+ * @device_id: PCI Device Id of the adapter
+ * @major_revision: PCI Device major revision
+ * @minor_revision: PCI Device minor revision
+ * @bar0: BAR0 virtual address.
+ * @bar1: BAR1 virtual address.
+ * @bar2: BAR2 virtual address.
+ * @pdev: Physical device handle
+ * @config: Confguration passed by the LL driver at initialization
+ * @link_state: Link state
+ *
+ * HW device object. Represents Titan adapter
+ */
+struct __vxge_hw_device {
+ u32 magic;
+#define VXGE_HW_DEVICE_MAGIC 0x12345678
+#define VXGE_HW_DEVICE_DEAD 0xDEADDEAD
+ u16 device_id;
+ u8 major_revision;
+ u8 minor_revision;
+ void __iomem *bar0;
+ void __iomem *bar1;
+ void __iomem *bar2;
+ struct pci_dev *pdev;
+ struct net_device *ndev;
+ struct vxge_hw_device_config config;
+ enum vxge_hw_device_link_state link_state;
+
+ struct vxge_hw_uld_cbs uld_callbacks;
+
+ u32 host_type;
+ u32 func_id;
+ u32 access_rights;
+#define VXGE_HW_DEVICE_ACCESS_RIGHT_VPATH 0x1
+#define VXGE_HW_DEVICE_ACCESS_RIGHT_SRPCIM 0x2
+#define VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM 0x4
+ struct vxge_hw_legacy_reg __iomem *legacy_reg;
+ struct vxge_hw_toc_reg __iomem *toc_reg;
+ struct vxge_hw_common_reg __iomem *common_reg;
+ struct vxge_hw_mrpcim_reg __iomem *mrpcim_reg;
+ struct vxge_hw_srpcim_reg __iomem *srpcim_reg \
+ [VXGE_HW_TITAN_SRPCIM_REG_SPACES];
+ struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg \
+ [VXGE_HW_TITAN_VPMGMT_REG_SPACES];
+ struct vxge_hw_vpath_reg __iomem *vpath_reg \
+ [VXGE_HW_TITAN_VPATH_REG_SPACES];
+ u8 __iomem *kdfc;
+ u8 __iomem *usdc;
+ struct __vxge_hw_virtualpath virtual_paths \
+ [VXGE_HW_MAX_VIRTUAL_PATHS];
+ u64 vpath_assignments;
+ u64 vpaths_deployed;
+ u32 first_vp_id;
+ u64 tim_int_mask0[4];
+ u32 tim_int_mask1[4];
+
+ struct __vxge_hw_blockpool block_pool;
+ struct vxge_hw_device_stats stats;
+ u32 debug_module_mask;
+ u32 debug_level;
+ u32 level_err;
+ u32 level_trace;
+};
+
+#define VXGE_HW_INFO_LEN 64
+/**
+ * struct vxge_hw_device_hw_info - Device information
+ * @host_type: Host Type
+ * @func_id: Function Id
+ * @vpath_mask: vpath bit mask
+ * @fw_version: Firmware version
+ * @fw_date: Firmware Date
+ * @flash_version: Firmware version
+ * @flash_date: Firmware Date
+ * @mac_addrs: Mac addresses for each vpath
+ * @mac_addr_masks: Mac address masks for each vpath
+ *
+ * Returns the vpath mask that has the bits set for each vpath allocated
+ * for the driver and the first mac address for each vpath
+ */
+struct vxge_hw_device_hw_info {
+ u32 host_type;
+#define VXGE_HW_NO_MR_NO_SR_NORMAL_FUNCTION 0
+#define VXGE_HW_MR_NO_SR_VH0_BASE_FUNCTION 1
+#define VXGE_HW_NO_MR_SR_VH0_FUNCTION0 2
+#define VXGE_HW_NO_MR_SR_VH0_VIRTUAL_FUNCTION 3
+#define VXGE_HW_MR_SR_VH0_INVALID_CONFIG 4
+#define VXGE_HW_SR_VH_FUNCTION0 5
+#define VXGE_HW_SR_VH_VIRTUAL_FUNCTION 6
+#define VXGE_HW_VH_NORMAL_FUNCTION 7
+ u64 function_mode;
+#define VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION 0
+#define VXGE_HW_FUNCTION_MODE_SINGLE_FUNCTION 1
+#define VXGE_HW_FUNCTION_MODE_SRIOV 2
+#define VXGE_HW_FUNCTION_MODE_MRIOV 3
+ u32 func_id;
+ u64 vpath_mask;
+ struct vxge_hw_device_version fw_version;
+ struct vxge_hw_device_date fw_date;
+ struct vxge_hw_device_version flash_version;
+ struct vxge_hw_device_date flash_date;
+ u8 serial_number[VXGE_HW_INFO_LEN];
+ u8 part_number[VXGE_HW_INFO_LEN];
+ u8 product_desc[VXGE_HW_INFO_LEN];
+ u8 (mac_addrs)[VXGE_HW_MAX_VIRTUAL_PATHS][ETH_ALEN];
+ u8 (mac_addr_masks)[VXGE_HW_MAX_VIRTUAL_PATHS][ETH_ALEN];
+};
+
+/**
+ * struct vxge_hw_device_attr - Device memory spaces.
+ * @bar0: BAR0 virtual address.
+ * @bar1: BAR1 virtual address.
+ * @bar2: BAR2 virtual address.
+ * @pdev: PCI device object.
+ *
+ * Device memory spaces. Includes configuration, BAR0, BAR1, etc. per device
+ * mapped memories. Also, includes a pointer to OS-specific PCI device object.
+ */
+struct vxge_hw_device_attr {
+ void __iomem *bar0;
+ void __iomem *bar1;
+ void __iomem *bar2;
+ struct pci_dev *pdev;
+ struct vxge_hw_uld_cbs uld_callbacks;
+};
+
+#define VXGE_HW_DEVICE_LINK_STATE_SET(hldev, ls) (hldev->link_state = ls)
+
+#define VXGE_HW_DEVICE_TIM_INT_MASK_SET(m0, m1, i) { \
+ if (i < 16) { \
+ m0[0] |= vxge_vBIT(0x8, (i*4), 4); \
+ m0[1] |= vxge_vBIT(0x4, (i*4), 4); \
+ } \
+ else { \
+ m1[0] = 0x80000000; \
+ m1[1] = 0x40000000; \
+ } \
+}
+
+#define VXGE_HW_DEVICE_TIM_INT_MASK_RESET(m0, m1, i) { \
+ if (i < 16) { \
+ m0[0] &= ~vxge_vBIT(0x8, (i*4), 4); \
+ m0[1] &= ~vxge_vBIT(0x4, (i*4), 4); \
+ } \
+ else { \
+ m1[0] = 0; \
+ m1[1] = 0; \
+ } \
+}
+
+#define VXGE_HW_DEVICE_STATS_PIO_READ(loc, offset) { \
+ status = vxge_hw_mrpcim_stats_access(hldev, \
+ VXGE_HW_STATS_OP_READ, \
+ loc, \
+ offset, \
+ &val64); \
+ \
+ if (status != VXGE_HW_OK) \
+ return status; \
+}
+
+#define VXGE_HW_VPATH_STATS_PIO_READ(offset) { \
+ status = __vxge_hw_vpath_stats_access(vpath, \
+ VXGE_HW_STATS_OP_READ, \
+ offset, \
+ &val64); \
+ if (status != VXGE_HW_OK) \
+ return status; \
+}
+
+/*
+ * struct __vxge_hw_ring - Ring channel.
+ * @channel: Channel "base" of this ring, the common part of all HW
+ * channels.
+ * @mempool: Memory pool, the pool from which descriptors get allocated.
+ * (See vxge_hw_mm.h).
+ * @config: Ring configuration, part of device configuration
+ * (see struct vxge_hw_device_config{}).
+ * @ring_length: Length of the ring
+ * @buffer_mode: 1, 3, or 5. The value specifies a receive buffer mode,
+ * as per Titan User Guide.
+ * @rxd_size: RxD sizes for 1-, 3- or 5- buffer modes. As per Titan spec,
+ * 1-buffer mode descriptor is 32 byte long, etc.
+ * @rxd_priv_size: Per RxD size reserved (by HW) for driver to keep
+ * per-descriptor data (e.g., DMA handle for Solaris)
+ * @per_rxd_space: Per rxd space requested by driver
+ * @rxds_per_block: Number of descriptors per hardware-defined RxD
+ * block. Depends on the (1-, 3-, 5-) buffer mode.
+ * @rxdblock_priv_size: Reserved at the end of each RxD block. HW internal
+ * usage. Not to confuse with @rxd_priv_size.
+ * @cmpl_cnt: Completion counter. Is reset to zero upon entering the ISR.
+ * @callback: Channel completion callback. HW invokes the callback when there
+ * are new completions on that channel. In many implementations
+ * the @callback executes in the hw interrupt context.
+ * @rxd_init: Channel's descriptor-initialize callback.
+ * See vxge_hw_ring_rxd_init_f{}.
+ * If not NULL, HW invokes the callback when opening
+ * the ring.
+ * @rxd_term: Channel's descriptor-terminate callback. If not NULL,
+ * HW invokes the callback when closing the corresponding channel.
+ * See also vxge_hw_channel_rxd_term_f{}.
+ * @stats: Statistics for ring
+ * Ring channel.
+ *
+ * Note: The structure is cache line aligned to better utilize
+ * CPU cache performance.
+ */
+struct __vxge_hw_ring {
+ struct __vxge_hw_channel channel;
+ struct vxge_hw_mempool *mempool;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+ struct vxge_hw_common_reg __iomem *common_reg;
+ u32 ring_length;
+ u32 buffer_mode;
+ u32 rxd_size;
+ u32 rxd_priv_size;
+ u32 per_rxd_space;
+ u32 rxds_per_block;
+ u32 rxdblock_priv_size;
+ u32 cmpl_cnt;
+ u32 vp_id;
+ u32 doorbell_cnt;
+ u32 total_db_cnt;
+ u64 rxds_limit;
+
+ enum vxge_hw_status (*callback)(
+ struct __vxge_hw_ring *ringh,
+ void *rxdh,
+ u8 t_code,
+ void *userdata);
+
+ enum vxge_hw_status (*rxd_init)(
+ void *rxdh,
+ void *userdata);
+
+ void (*rxd_term)(
+ void *rxdh,
+ enum vxge_hw_rxd_state state,
+ void *userdata);
+
+ struct vxge_hw_vpath_stats_sw_ring_info *stats ____cacheline_aligned;
+ struct vxge_hw_ring_config *config;
+} ____cacheline_aligned;
+
+/**
+ * enum enum vxge_hw_txdl_state - Descriptor (TXDL) state.
+ * @VXGE_HW_TXDL_STATE_NONE: Invalid state.
+ * @VXGE_HW_TXDL_STATE_AVAIL: Descriptor is available for reservation.
+ * @VXGE_HW_TXDL_STATE_POSTED: Descriptor is posted for processing by the
+ * device.
+ * @VXGE_HW_TXDL_STATE_FREED: Descriptor is free and can be reused for
+ * filling-in and posting later.
+ *
+ * Titan/HW descriptor states.
+ *
+ */
+enum vxge_hw_txdl_state {
+ VXGE_HW_TXDL_STATE_NONE = 0,
+ VXGE_HW_TXDL_STATE_AVAIL = 1,
+ VXGE_HW_TXDL_STATE_POSTED = 2,
+ VXGE_HW_TXDL_STATE_FREED = 3
+};
+/*
+ * struct __vxge_hw_fifo - Fifo.
+ * @channel: Channel "base" of this fifo, the common part of all HW
+ * channels.
+ * @mempool: Memory pool, from which descriptors get allocated.
+ * @config: Fifo configuration, part of device configuration
+ * (see struct vxge_hw_device_config{}).
+ * @interrupt_type: Interrupt type to be used
+ * @no_snoop_bits: See struct vxge_hw_fifo_config{}.
+ * @txdl_per_memblock: Number of TxDLs (TxD lists) per memblock.
+ * on TxDL please refer to Titan UG.
+ * @txdl_size: Configured TxDL size (i.e., number of TxDs in a list), plus
+ * per-TxDL HW private space (struct __vxge_hw_fifo_txdl_priv).
+ * @priv_size: Per-Tx descriptor space reserved for driver
+ * usage.
+ * @per_txdl_space: Per txdl private space for the driver
+ * @callback: Fifo completion callback. HW invokes the callback when there
+ * are new completions on that fifo. In many implementations
+ * the @callback executes in the hw interrupt context.
+ * @txdl_term: Fifo's descriptor-terminate callback. If not NULL,
+ * HW invokes the callback when closing the corresponding fifo.
+ * See also vxge_hw_fifo_txdl_term_f{}.
+ * @stats: Statistics of this fifo
+ *
+ * Fifo channel.
+ * Note: The structure is cache line aligned.
+ */
+struct __vxge_hw_fifo {
+ struct __vxge_hw_channel channel;
+ struct vxge_hw_mempool *mempool;
+ struct vxge_hw_fifo_config *config;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+ struct __vxge_hw_non_offload_db_wrapper __iomem *nofl_db;
+ u64 interrupt_type;
+ u32 no_snoop_bits;
+ u32 txdl_per_memblock;
+ u32 txdl_size;
+ u32 priv_size;
+ u32 per_txdl_space;
+ u32 vp_id;
+ u32 tx_intr_num;
+
+ enum vxge_hw_status (*callback)(
+ struct __vxge_hw_fifo *fifo_handle,
+ void *txdlh,
+ enum vxge_hw_fifo_tcode t_code,
+ void *userdata,
+ void **skb_ptr);
+
+ void (*txdl_term)(
+ void *txdlh,
+ enum vxge_hw_txdl_state state,
+ void *userdata);
+
+ struct vxge_hw_vpath_stats_sw_fifo_info *stats ____cacheline_aligned;
+} ____cacheline_aligned;
+
+/*
+ * struct __vxge_hw_fifo_txdl_priv - Transmit descriptor HW-private data.
+ * @dma_addr: DMA (mapped) address of _this_ descriptor.
+ * @dma_handle: DMA handle used to map the descriptor onto device.
+ * @dma_offset: Descriptor's offset in the memory block. HW allocates
+ * descriptors in memory blocks (see struct vxge_hw_fifo_config{})
+ * Each memblock is a contiguous block of DMA-able memory.
+ * @frags: Total number of fragments (that is, contiguous data buffers)
+ * carried by this TxDL.
+ * @align_vaddr_start: Aligned virtual address start
+ * @align_vaddr: Virtual address of the per-TxDL area in memory used for
+ * alignement. Used to place one or more mis-aligned fragments
+ * @align_dma_addr: DMA address translated from the @align_vaddr.
+ * @align_dma_handle: DMA handle that corresponds to @align_dma_addr.
+ * @align_dma_acch: DMA access handle corresponds to @align_dma_addr.
+ * @align_dma_offset: The current offset into the @align_vaddr area.
+ * Grows while filling the descriptor, gets reset.
+ * @align_used_frags: Number of fragments used.
+ * @alloc_frags: Total number of fragments allocated.
+ * @unused: TODO
+ * @next_txdl_priv: (TODO).
+ * @first_txdp: (TODO).
+ * @linked_txdl_priv: Pointer to any linked TxDL for creating contiguous
+ * TxDL list.
+ * @txdlh: Corresponding txdlh to this TxDL.
+ * @memblock: Pointer to the TxDL memory block or memory page.
+ * on the next send operation.
+ * @dma_object: DMA address and handle of the memory block that contains
+ * the descriptor. This member is used only in the "checked"
+ * version of the HW (to enforce certain assertions);
+ * otherwise it gets compiled out.
+ * @allocated: True if the descriptor is reserved, 0 otherwise. Internal usage.
+ *
+ * Per-transmit decsriptor HW-private data. HW uses the space to keep DMA
+ * information associated with the descriptor. Note that driver can ask HW
+ * to allocate additional per-descriptor space for its own (driver-specific)
+ * purposes.
+ *
+ * See also: struct vxge_hw_ring_rxd_priv{}.
+ */
+struct __vxge_hw_fifo_txdl_priv {
+ dma_addr_t dma_addr;
+ struct pci_dev *dma_handle;
+ ptrdiff_t dma_offset;
+ u32 frags;
+ u8 *align_vaddr_start;
+ u8 *align_vaddr;
+ dma_addr_t align_dma_addr;
+ struct pci_dev *align_dma_handle;
+ struct pci_dev *align_dma_acch;
+ ptrdiff_t align_dma_offset;
+ u32 align_used_frags;
+ u32 alloc_frags;
+ u32 unused;
+ struct __vxge_hw_fifo_txdl_priv *next_txdl_priv;
+ struct vxge_hw_fifo_txd *first_txdp;
+ void *memblock;
+};
+
+/*
+ * struct __vxge_hw_non_offload_db_wrapper - Non-offload Doorbell Wrapper
+ * @control_0: Bits 0 to 7 - Doorbell type.
+ * Bits 8 to 31 - Reserved.
+ * Bits 32 to 39 - The highest TxD in this TxDL.
+ * Bits 40 to 47 - Reserved.
+ * Bits 48 to 55 - Reserved.
+ * Bits 56 to 63 - No snoop flags.
+ * @txdl_ptr: The starting location of the TxDL in host memory.
+ *
+ * Created by the host and written to the adapter via PIO to a Kernel Doorbell
+ * FIFO. All non-offload doorbell wrapper fields must be written by the host as
+ * part of a doorbell write. Consumed by the adapter but is not written by the
+ * adapter.
+ */
+struct __vxge_hw_non_offload_db_wrapper {
+ u64 control_0;
+#define VXGE_HW_NODBW_GET_TYPE(ctrl0) vxge_bVALn(ctrl0, 0, 8)
+#define VXGE_HW_NODBW_TYPE(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_NODBW_TYPE_NODBW 0
+
+#define VXGE_HW_NODBW_GET_LAST_TXD_NUMBER(ctrl0) vxge_bVALn(ctrl0, 32, 8)
+#define VXGE_HW_NODBW_LAST_TXD_NUMBER(val) vxge_vBIT(val, 32, 8)
+
+#define VXGE_HW_NODBW_GET_NO_SNOOP(ctrl0) vxge_bVALn(ctrl0, 56, 8)
+#define VXGE_HW_NODBW_LIST_NO_SNOOP(val) vxge_vBIT(val, 56, 8)
+#define VXGE_HW_NODBW_LIST_NO_SNOOP_TXD_READ_TXD0_WRITE 0x2
+#define VXGE_HW_NODBW_LIST_NO_SNOOP_TX_FRAME_DATA_READ 0x1
+
+ u64 txdl_ptr;
+};
+
+/*
+ * TX Descriptor
+ */
+
+/**
+ * struct vxge_hw_fifo_txd - Transmit Descriptor
+ * @control_0: Bits 0 to 6 - Reserved.
+ * Bit 7 - List Ownership. This field should be initialized
+ * to '1' by the driver before the transmit list pointer is
+ * written to the adapter. This field will be set to '0' by the
+ * adapter once it has completed transmitting the frame or frames in
+ * the list. Note - This field is only valid in TxD0. Additionally,
+ * for multi-list sequences, the driver should not release any
+ * buffers until the ownership of the last list in the multi-list
+ * sequence has been returned to the host.
+ * Bits 8 to 11 - Reserved
+ * Bits 12 to 15 - Transfer_Code. This field is only valid in
+ * TxD0. It is used to describe the status of the transmit data
+ * buffer transfer. This field is always overwritten by the
+ * adapter, so this field may be initialized to any value.
+ * Bits 16 to 17 - Host steering. This field allows the host to
+ * override the selection of the physical transmit port.
+ * Attention:
+ * Normal sounds as if learned from the switch rather than from
+ * the aggregation algorythms.
+ * 00: Normal. Use Destination/MAC Address
+ * lookup to determine the transmit port.
+ * 01: Send on physical Port1.
+ * 10: Send on physical Port0.
+ * 11: Send on both ports.
+ * Bits 18 to 21 - Reserved
+ * Bits 22 to 23 - Gather_Code. This field is set by the host and
+ * is used to describe how individual buffers comprise a frame.
+ * 10: First descriptor of a frame.
+ * 00: Middle of a multi-descriptor frame.
+ * 01: Last descriptor of a frame.
+ * 11: First and last descriptor of a frame (the entire frame
+ * resides in a single buffer).
+ * For multi-descriptor frames, the only valid gather code sequence
+ * is {10, [00], 01}. In other words, the descriptors must be placed
+ * in the list in the correct order.
+ * Bits 24 to 27 - Reserved
+ * Bits 28 to 29 - LSO_Frm_Encap. LSO Frame Encapsulation
+ * definition. Only valid in TxD0. This field allows the host to
+ * indicate the Ethernet encapsulation of an outbound LSO packet.
+ * 00 - classic mode (best guess)
+ * 01 - LLC
+ * 10 - SNAP
+ * 11 - DIX
+ * If "classic mode" is selected, the adapter will attempt to
+ * decode the frame's Ethernet encapsulation by examining the L/T
+ * field as follows:
+ * <= 0x05DC LLC/SNAP encoding; must examine DSAP/SSAP to determine
+ * if packet is IPv4 or IPv6.
+ * 0x8870 Jumbo-SNAP encoding.
+ * 0x0800 IPv4 DIX encoding
+ * 0x86DD IPv6 DIX encoding
+ * others illegal encapsulation
+ * Bits 30 - LSO_ Flag. Large Send Offload (LSO) flag.
+ * Set to 1 to perform segmentation offload for TCP/UDP.
+ * This field is valid only in TxD0.
+ * Bits 31 to 33 - Reserved.
+ * Bits 34 to 47 - LSO_MSS. TCP/UDP LSO Maximum Segment Size
+ * This field is meaningful only when LSO_Control is non-zero.
+ * When LSO_Control is set to TCP_LSO, the single (possibly large)
+ * TCP segment described by this TxDL will be sent as a series of
+ * TCP segments each of which contains no more than LSO_MSS
+ * payload bytes.
+ * When LSO_Control is set to UDP_LSO, the single (possibly large)
+ * UDP datagram described by this TxDL will be sent as a series of
+ * UDP datagrams each of which contains no more than LSO_MSS
+ * payload bytes.
+ * All outgoing frames from this TxDL will have LSO_MSS bytes of UDP
+ * or TCP payload, with the exception of the last, which will have
+ * <= LSO_MSS bytes of payload.
+ * Bits 48 to 63 - Buffer_Size. Number of valid bytes in the
+ * buffer to be read by the adapter. This field is written by the
+ * host. A value of 0 is illegal.
+ * Bits 32 to 63 - This value is written by the adapter upon
+ * completion of a UDP or TCP LSO operation and indicates the number
+ * of UDP or TCP payload bytes that were transmitted. 0x0000 will be
+ * returned for any non-LSO operation.
+ * @control_1: Bits 0 to 4 - Reserved.
+ * Bit 5 - Tx_CKO_IPv4 Set to a '1' to enable IPv4 header checksum
+ * offload. This field is only valid in the first TxD of a frame.
+ * Bit 6 - Tx_CKO_TCP Set to a '1' to enable TCP checksum offload.
+ * This field is only valid in the first TxD of a frame (the TxD's
+ * gather code must be 10 or 11). The driver should only set this
+ * bit if it can guarantee that TCP is present.
+ * Bit 7 - Tx_CKO_UDP Set to a '1' to enable UDP checksum offload.
+ * This field is only valid in the first TxD of a frame (the TxD's
+ * gather code must be 10 or 11). The driver should only set this
+ * bit if it can guarantee that UDP is present.
+ * Bits 8 to 14 - Reserved.
+ * Bit 15 - Tx_VLAN_Enable VLAN tag insertion flag. Set to a '1' to
+ * instruct the adapter to insert the VLAN tag specified by the
+ * Tx_VLAN_Tag field. This field is only valid in the first TxD of
+ * a frame.
+ * Bits 16 to 31 - Tx_VLAN_Tag. Variable portion of the VLAN tag
+ * to be inserted into the frame by the adapter (the first two bytes
+ * of a VLAN tag are always 0x8100). This field is only valid if the
+ * Tx_VLAN_Enable field is set to '1'.
+ * Bits 32 to 33 - Reserved.
+ * Bits 34 to 39 - Tx_Int_Number. Indicates which Tx interrupt
+ * number the frame associated with. This field is written by the
+ * host. It is only valid in the first TxD of a frame.
+ * Bits 40 to 42 - Reserved.
+ * Bit 43 - Set to 1 to exclude the frame from bandwidth metering
+ * functions. This field is valid only in the first TxD
+ * of a frame.
+ * Bits 44 to 45 - Reserved.
+ * Bit 46 - Tx_Int_Per_List Set to a '1' to instruct the adapter to
+ * generate an interrupt as soon as all of the frames in the list
+ * have been transmitted. In order to have per-frame interrupts,
+ * the driver should place a maximum of one frame per list. This
+ * field is only valid in the first TxD of a frame.
+ * Bit 47 - Tx_Int_Utilization Set to a '1' to instruct the adapter
+ * to count the frame toward the utilization interrupt specified in
+ * the Tx_Int_Number field. This field is only valid in the first
+ * TxD of a frame.
+ * Bits 48 to 63 - Reserved.
+ * @buffer_pointer: Buffer start address.
+ * @host_control: Host_Control.Opaque 64bit data stored by driver inside the
+ * Titan descriptor prior to posting the latter on the fifo
+ * via vxge_hw_fifo_txdl_post().The %host_control is returned as is
+ * to the driver with each completed descriptor.
+ *
+ * Transmit descriptor (TxD).Fifo descriptor contains configured number
+ * (list) of TxDs. * For more details please refer to Titan User Guide,
+ * Section 5.4.2 "Transmit Descriptor (TxD) Format".
+ */
+struct vxge_hw_fifo_txd {
+ u64 control_0;
+#define VXGE_HW_FIFO_TXD_LIST_OWN_ADAPTER vxge_mBIT(7)
+
+#define VXGE_HW_FIFO_TXD_T_CODE_GET(ctrl0) vxge_bVALn(ctrl0, 12, 4)
+#define VXGE_HW_FIFO_TXD_T_CODE(val) vxge_vBIT(val, 12, 4)
+#define VXGE_HW_FIFO_TXD_T_CODE_UNUSED VXGE_HW_FIFO_T_CODE_UNUSED
+
+
+#define VXGE_HW_FIFO_TXD_GATHER_CODE(val) vxge_vBIT(val, 22, 2)
+#define VXGE_HW_FIFO_TXD_GATHER_CODE_FIRST VXGE_HW_FIFO_GATHER_CODE_FIRST
+#define VXGE_HW_FIFO_TXD_GATHER_CODE_LAST VXGE_HW_FIFO_GATHER_CODE_LAST
+
+
+#define VXGE_HW_FIFO_TXD_LSO_EN vxge_mBIT(30)
+
+#define VXGE_HW_FIFO_TXD_LSO_MSS(val) vxge_vBIT(val, 34, 14)
+
+#define VXGE_HW_FIFO_TXD_BUFFER_SIZE(val) vxge_vBIT(val, 48, 16)
+
+ u64 control_1;
+#define VXGE_HW_FIFO_TXD_TX_CKO_IPV4_EN vxge_mBIT(5)
+#define VXGE_HW_FIFO_TXD_TX_CKO_TCP_EN vxge_mBIT(6)
+#define VXGE_HW_FIFO_TXD_TX_CKO_UDP_EN vxge_mBIT(7)
+#define VXGE_HW_FIFO_TXD_VLAN_ENABLE vxge_mBIT(15)
+
+#define VXGE_HW_FIFO_TXD_VLAN_TAG(val) vxge_vBIT(val, 16, 16)
+
+#define VXGE_HW_FIFO_TXD_INT_NUMBER(val) vxge_vBIT(val, 34, 6)
+
+#define VXGE_HW_FIFO_TXD_INT_TYPE_PER_LIST vxge_mBIT(46)
+#define VXGE_HW_FIFO_TXD_INT_TYPE_UTILZ vxge_mBIT(47)
+
+ u64 buffer_pointer;
+
+ u64 host_control;
+};
+
+/**
+ * struct vxge_hw_ring_rxd_1 - One buffer mode RxD for ring
+ * @host_control: This field is exclusively for host use and is "readonly"
+ * from the adapter's perspective.
+ * @control_0:Bits 0 to 6 - RTH_Bucket get
+ * Bit 7 - Own Descriptor ownership bit. This bit is set to 1
+ * by the host, and is set to 0 by the adapter.
+ * 0 - Host owns RxD and buffer.
+ * 1 - The adapter owns RxD and buffer.
+ * Bit 8 - Fast_Path_Eligible When set, indicates that the
+ * received frame meets all of the criteria for fast path processing.
+ * The required criteria are as follows:
+ * !SYN &
+ * (Transfer_Code == "Transfer OK") &
+ * (!Is_IP_Fragment) &
+ * ((Is_IPv4 & computed_L3_checksum == 0xFFFF) |
+ * (Is_IPv6)) &
+ * ((Is_TCP & computed_L4_checksum == 0xFFFF) |
+ * (Is_UDP & (computed_L4_checksum == 0xFFFF |
+ * computed _L4_checksum == 0x0000)))
+ * (same meaning for all RxD buffer modes)
+ * Bit 9 - L3 Checksum Correct
+ * Bit 10 - L4 Checksum Correct
+ * Bit 11 - Reserved
+ * Bit 12 to 15 - This field is written by the adapter. It is
+ * used to report the status of the frame transfer to the host.
+ * 0x0 - Transfer OK
+ * 0x4 - RDA Failure During Transfer
+ * 0x5 - Unparseable Packet, such as unknown IPv6 header.
+ * 0x6 - Frame integrity error (FCS or ECC).
+ * 0x7 - Buffer Size Error. The provided buffer(s) were not
+ * appropriately sized and data loss occurred.
+ * 0x8 - Internal ECC Error. RxD corrupted.
+ * 0x9 - IPv4 Checksum error
+ * 0xA - TCP/UDP Checksum error
+ * 0xF - Unknown Error or Multiple Error. Indicates an
+ * unknown problem or that more than one of transfer codes is set.
+ * Bit 16 - SYN The adapter sets this field to indicate that
+ * the incoming frame contained a TCP segment with its SYN bit
+ * set and its ACK bit NOT set. (same meaning for all RxD buffer
+ * modes)
+ * Bit 17 - Is ICMP
+ * Bit 18 - RTH_SPDM_HIT Set to 1 if there was a match in the
+ * Socket Pair Direct Match Table and the frame was steered based
+ * on SPDM.
+ * Bit 19 - RTH_IT_HIT Set to 1 if there was a match in the
+ * Indirection Table and the frame was steered based on hash
+ * indirection.
+ * Bit 20 to 23 - RTH_HASH_TYPE Indicates the function (hash
+ * type) that was used to calculate the hash.
+ * Bit 19 - IS_VLAN Set to '1' if the frame was/is VLAN
+ * tagged.
+ * Bit 25 to 26 - ETHER_ENCAP Reflects the Ethernet encapsulation
+ * of the received frame.
+ * 0x0 - Ethernet DIX
+ * 0x1 - LLC
+ * 0x2 - SNAP (includes Jumbo-SNAP)
+ * 0x3 - IPX
+ * Bit 27 - IS_IPV4 Set to '1' if the frame contains an IPv4 packet.
+ * Bit 28 - IS_IPV6 Set to '1' if the frame contains an IPv6 packet.
+ * Bit 29 - IS_IP_FRAG Set to '1' if the frame contains a fragmented
+ * IP packet.
+ * Bit 30 - IS_TCP Set to '1' if the frame contains a TCP segment.
+ * Bit 31 - IS_UDP Set to '1' if the frame contains a UDP message.
+ * Bit 32 to 47 - L3_Checksum[0:15] The IPv4 checksum value that
+ * arrived with the frame. If the resulting computed IPv4 header
+ * checksum for the frame did not produce the expected 0xFFFF value,
+ * then the transfer code would be set to 0x9.
+ * Bit 48 to 63 - L4_Checksum[0:15] The TCP/UDP checksum value that
+ * arrived with the frame. If the resulting computed TCP/UDP checksum
+ * for the frame did not produce the expected 0xFFFF value, then the
+ * transfer code would be set to 0xA.
+ * @control_1:Bits 0 to 1 - Reserved
+ * Bits 2 to 15 - Buffer0_Size.This field is set by the host and
+ * eventually overwritten by the adapter. The host writes the
+ * available buffer size in bytes when it passes the descriptor to
+ * the adapter. When a frame is delivered the host, the adapter
+ * populates this field with the number of bytes written into the
+ * buffer. The largest supported buffer is 16, 383 bytes.
+ * Bit 16 to 47 - RTH Hash Value 32-bit RTH hash value. Only valid if
+ * RTH_HASH_TYPE (Control_0, bits 20:23) is nonzero.
+ * Bit 48 to 63 - VLAN_Tag[0:15] The contents of the variable portion
+ * of the VLAN tag, if one was detected by the adapter. This field is
+ * populated even if VLAN-tag stripping is enabled.
+ * @buffer0_ptr: Pointer to buffer. This field is populated by the driver.
+ *
+ * One buffer mode RxD for ring structure
+ */
+struct vxge_hw_ring_rxd_1 {
+ u64 host_control;
+ u64 control_0;
+#define VXGE_HW_RING_RXD_RTH_BUCKET_GET(ctrl0) vxge_bVALn(ctrl0, 0, 7)
+
+#define VXGE_HW_RING_RXD_LIST_OWN_ADAPTER vxge_mBIT(7)
+
+#define VXGE_HW_RING_RXD_FAST_PATH_ELIGIBLE_GET(ctrl0) vxge_bVALn(ctrl0, 8, 1)
+
+#define VXGE_HW_RING_RXD_L3_CKSUM_CORRECT_GET(ctrl0) vxge_bVALn(ctrl0, 9, 1)
+
+#define VXGE_HW_RING_RXD_L4_CKSUM_CORRECT_GET(ctrl0) vxge_bVALn(ctrl0, 10, 1)
+
+#define VXGE_HW_RING_RXD_T_CODE_GET(ctrl0) vxge_bVALn(ctrl0, 12, 4)
+#define VXGE_HW_RING_RXD_T_CODE(val) vxge_vBIT(val, 12, 4)
+
+#define VXGE_HW_RING_RXD_T_CODE_UNUSED VXGE_HW_RING_T_CODE_UNUSED
+
+#define VXGE_HW_RING_RXD_SYN_GET(ctrl0) vxge_bVALn(ctrl0, 16, 1)
+
+#define VXGE_HW_RING_RXD_IS_ICMP_GET(ctrl0) vxge_bVALn(ctrl0, 17, 1)
+
+#define VXGE_HW_RING_RXD_RTH_SPDM_HIT_GET(ctrl0) vxge_bVALn(ctrl0, 18, 1)
+
+#define VXGE_HW_RING_RXD_RTH_IT_HIT_GET(ctrl0) vxge_bVALn(ctrl0, 19, 1)
+
+#define VXGE_HW_RING_RXD_RTH_HASH_TYPE_GET(ctrl0) vxge_bVALn(ctrl0, 20, 4)
+
+#define VXGE_HW_RING_RXD_IS_VLAN_GET(ctrl0) vxge_bVALn(ctrl0, 24, 1)
+
+#define VXGE_HW_RING_RXD_ETHER_ENCAP_GET(ctrl0) vxge_bVALn(ctrl0, 25, 2)
+
+#define VXGE_HW_RING_RXD_FRAME_PROTO_GET(ctrl0) vxge_bVALn(ctrl0, 27, 5)
+
+#define VXGE_HW_RING_RXD_L3_CKSUM_GET(ctrl0) vxge_bVALn(ctrl0, 32, 16)
+
+#define VXGE_HW_RING_RXD_L4_CKSUM_GET(ctrl0) vxge_bVALn(ctrl0, 48, 16)
+
+ u64 control_1;
+
+#define VXGE_HW_RING_RXD_1_BUFFER0_SIZE_GET(ctrl1) vxge_bVALn(ctrl1, 2, 14)
+#define VXGE_HW_RING_RXD_1_BUFFER0_SIZE(val) vxge_vBIT(val, 2, 14)
+#define VXGE_HW_RING_RXD_1_BUFFER0_SIZE_MASK vxge_vBIT(0x3FFF, 2, 14)
+
+#define VXGE_HW_RING_RXD_1_RTH_HASH_VAL_GET(ctrl1) vxge_bVALn(ctrl1, 16, 32)
+
+#define VXGE_HW_RING_RXD_VLAN_TAG_GET(ctrl1) vxge_bVALn(ctrl1, 48, 16)
+
+ u64 buffer0_ptr;
+};
+
+enum vxge_hw_rth_algoritms {
+ RTH_ALG_JENKINS = 0,
+ RTH_ALG_MS_RSS = 1,
+ RTH_ALG_CRC32C = 2
+};
+
+/**
+ * struct vxge_hw_rth_hash_types - RTH hash types.
+ * @hash_type_tcpipv4_en: Enables RTH field type HashTypeTcpIPv4
+ * @hash_type_ipv4_en: Enables RTH field type HashTypeIPv4
+ * @hash_type_tcpipv6_en: Enables RTH field type HashTypeTcpIPv6
+ * @hash_type_ipv6_en: Enables RTH field type HashTypeIPv6
+ * @hash_type_tcpipv6ex_en: Enables RTH field type HashTypeTcpIPv6Ex
+ * @hash_type_ipv6ex_en: Enables RTH field type HashTypeIPv6Ex
+ *
+ * Used to pass RTH hash types to rts_rts_set.
+ *
+ * See also: vxge_hw_vpath_rts_rth_set(), vxge_hw_vpath_rts_rth_get().
+ */
+struct vxge_hw_rth_hash_types {
+ u8 hash_type_tcpipv4_en;
+ u8 hash_type_ipv4_en;
+ u8 hash_type_tcpipv6_en;
+ u8 hash_type_ipv6_en;
+ u8 hash_type_tcpipv6ex_en;
+ u8 hash_type_ipv6ex_en;
+};
+
+u32
+vxge_hw_device_debug_mask_get(struct __vxge_hw_device *devh);
+
+void vxge_hw_device_debug_set(
+ struct __vxge_hw_device *devh,
+ enum vxge_debug_level level,
+ u32 mask);
+
+u32
+vxge_hw_device_error_level_get(struct __vxge_hw_device *devh);
+
+u32
+vxge_hw_device_trace_level_get(struct __vxge_hw_device *devh);
+
+u32
+vxge_hw_device_debug_mask_get(struct __vxge_hw_device *devh);
+
+/**
+ * vxge_hw_ring_rxd_size_get - Get the size of ring descriptor.
+ * @buf_mode: Buffer mode (1, 3 or 5)
+ *
+ * This function returns the size of RxD for given buffer mode
+ */
+static inline u32 vxge_hw_ring_rxd_size_get(u32 buf_mode)
+{
+ return sizeof(struct vxge_hw_ring_rxd_1);
+}
+
+/**
+ * vxge_hw_ring_rxds_per_block_get - Get the number of rxds per block.
+ * @buf_mode: Buffer mode (1 buffer mode only)
+ *
+ * This function returns the number of RxD for RxD block for given buffer mode
+ */
+static inline u32 vxge_hw_ring_rxds_per_block_get(u32 buf_mode)
+{
+ return (u32)((VXGE_HW_BLOCK_SIZE-16) /
+ sizeof(struct vxge_hw_ring_rxd_1));
+}
+
+/**
+ * vxge_hw_ring_rxd_1b_set - Prepare 1-buffer-mode descriptor.
+ * @rxdh: Descriptor handle.
+ * @dma_pointer: DMA address of a single receive buffer this descriptor
+ * should carry. Note that by the time vxge_hw_ring_rxd_1b_set is called,
+ * the receive buffer should be already mapped to the device
+ * @size: Size of the receive @dma_pointer buffer.
+ *
+ * Prepare 1-buffer-mode Rx descriptor for posting
+ * (via vxge_hw_ring_rxd_post()).
+ *
+ * This inline helper-function does not return any parameters and always
+ * succeeds.
+ *
+ */
+static inline
+void vxge_hw_ring_rxd_1b_set(
+ void *rxdh,
+ dma_addr_t dma_pointer,
+ u32 size)
+{
+ struct vxge_hw_ring_rxd_1 *rxdp = (struct vxge_hw_ring_rxd_1 *)rxdh;
+ rxdp->buffer0_ptr = dma_pointer;
+ rxdp->control_1 &= ~VXGE_HW_RING_RXD_1_BUFFER0_SIZE_MASK;
+ rxdp->control_1 |= VXGE_HW_RING_RXD_1_BUFFER0_SIZE(size);
+}
+
+/**
+ * vxge_hw_ring_rxd_1b_get - Get data from the completed 1-buf
+ * descriptor.
+ * @vpath_handle: Virtual Path handle.
+ * @rxdh: Descriptor handle.
+ * @dma_pointer: DMA address of a single receive buffer this descriptor
+ * carries. Returned by HW.
+ * @pkt_length: Length (in bytes) of the data in the buffer pointed by
+ *
+ * Retrieve protocol data from the completed 1-buffer-mode Rx descriptor.
+ * This inline helper-function uses completed descriptor to populate receive
+ * buffer pointer and other "out" parameters. The function always succeeds.
+ *
+ */
+static inline
+void vxge_hw_ring_rxd_1b_get(
+ struct __vxge_hw_ring *ring_handle,
+ void *rxdh,
+ u32 *pkt_length)
+{
+ struct vxge_hw_ring_rxd_1 *rxdp = (struct vxge_hw_ring_rxd_1 *)rxdh;
+
+ *pkt_length =
+ (u32)VXGE_HW_RING_RXD_1_BUFFER0_SIZE_GET(rxdp->control_1);
+}
+
+/**
+ * vxge_hw_ring_rxd_1b_info_get - Get extended information associated with
+ * a completed receive descriptor for 1b mode.
+ * @vpath_handle: Virtual Path handle.
+ * @rxdh: Descriptor handle.
+ * @rxd_info: Descriptor information
+ *
+ * Retrieve extended information associated with a completed receive descriptor.
+ *
+ */
+static inline
+void vxge_hw_ring_rxd_1b_info_get(
+ struct __vxge_hw_ring *ring_handle,
+ void *rxdh,
+ struct vxge_hw_ring_rxd_info *rxd_info)
+{
+
+ struct vxge_hw_ring_rxd_1 *rxdp = (struct vxge_hw_ring_rxd_1 *)rxdh;
+ rxd_info->syn_flag =
+ (u32)VXGE_HW_RING_RXD_SYN_GET(rxdp->control_0);
+ rxd_info->is_icmp =
+ (u32)VXGE_HW_RING_RXD_IS_ICMP_GET(rxdp->control_0);
+ rxd_info->fast_path_eligible =
+ (u32)VXGE_HW_RING_RXD_FAST_PATH_ELIGIBLE_GET(rxdp->control_0);
+ rxd_info->l3_cksum_valid =
+ (u32)VXGE_HW_RING_RXD_L3_CKSUM_CORRECT_GET(rxdp->control_0);
+ rxd_info->l3_cksum =
+ (u32)VXGE_HW_RING_RXD_L3_CKSUM_GET(rxdp->control_0);
+ rxd_info->l4_cksum_valid =
+ (u32)VXGE_HW_RING_RXD_L4_CKSUM_CORRECT_GET(rxdp->control_0);
+ rxd_info->l4_cksum =
+ (u32)VXGE_HW_RING_RXD_L4_CKSUM_GET(rxdp->control_0);;
+ rxd_info->frame =
+ (u32)VXGE_HW_RING_RXD_ETHER_ENCAP_GET(rxdp->control_0);
+ rxd_info->proto =
+ (u32)VXGE_HW_RING_RXD_FRAME_PROTO_GET(rxdp->control_0);
+ rxd_info->is_vlan =
+ (u32)VXGE_HW_RING_RXD_IS_VLAN_GET(rxdp->control_0);
+ rxd_info->vlan =
+ (u32)VXGE_HW_RING_RXD_VLAN_TAG_GET(rxdp->control_1);
+ rxd_info->rth_bucket =
+ (u32)VXGE_HW_RING_RXD_RTH_BUCKET_GET(rxdp->control_0);
+ rxd_info->rth_it_hit =
+ (u32)VXGE_HW_RING_RXD_RTH_IT_HIT_GET(rxdp->control_0);
+ rxd_info->rth_spdm_hit =
+ (u32)VXGE_HW_RING_RXD_RTH_SPDM_HIT_GET(rxdp->control_0);
+ rxd_info->rth_hash_type =
+ (u32)VXGE_HW_RING_RXD_RTH_HASH_TYPE_GET(rxdp->control_0);
+ rxd_info->rth_value =
+ (u32)VXGE_HW_RING_RXD_1_RTH_HASH_VAL_GET(rxdp->control_1);
+}
+
+/**
+ * vxge_hw_ring_rxd_private_get - Get driver private per-descriptor data
+ * of 1b mode 3b mode ring.
+ * @rxdh: Descriptor handle.
+ *
+ * Returns: private driver info associated with the descriptor.
+ * driver requests per-descriptor space via vxge_hw_ring_attr.
+ *
+ */
+static inline void *vxge_hw_ring_rxd_private_get(void *rxdh)
+{
+ struct vxge_hw_ring_rxd_1 *rxdp = (struct vxge_hw_ring_rxd_1 *)rxdh;
+ return (void *)(size_t)rxdp->host_control;
+}
+
+/**
+ * vxge_hw_fifo_txdl_cksum_set_bits - Offload checksum.
+ * @txdlh: Descriptor handle.
+ * @cksum_bits: Specifies which checksums are to be offloaded: IPv4,
+ * and/or TCP and/or UDP.
+ *
+ * Ask Titan to calculate IPv4 & transport checksums for _this_ transmit
+ * descriptor.
+ * This API is part of the preparation of the transmit descriptor for posting
+ * (via vxge_hw_fifo_txdl_post()). The related "preparation" APIs include
+ * vxge_hw_fifo_txdl_mss_set(), vxge_hw_fifo_txdl_buffer_set_aligned(),
+ * and vxge_hw_fifo_txdl_buffer_set().
+ * All these APIs fill in the fields of the fifo descriptor,
+ * in accordance with the Titan specification.
+ *
+ */
+static inline void vxge_hw_fifo_txdl_cksum_set_bits(void *txdlh, u64 cksum_bits)
+{
+ struct vxge_hw_fifo_txd *txdp = (struct vxge_hw_fifo_txd *)txdlh;
+ txdp->control_1 |= cksum_bits;
+}
+
+/**
+ * vxge_hw_fifo_txdl_mss_set - Set MSS.
+ * @txdlh: Descriptor handle.
+ * @mss: MSS size for _this_ TCP connection. Passed by TCP stack down to the
+ * driver, which in turn inserts the MSS into the @txdlh.
+ *
+ * This API is part of the preparation of the transmit descriptor for posting
+ * (via vxge_hw_fifo_txdl_post()). The related "preparation" APIs include
+ * vxge_hw_fifo_txdl_buffer_set(), vxge_hw_fifo_txdl_buffer_set_aligned(),
+ * and vxge_hw_fifo_txdl_cksum_set_bits().
+ * All these APIs fill in the fields of the fifo descriptor,
+ * in accordance with the Titan specification.
+ *
+ */
+static inline void vxge_hw_fifo_txdl_mss_set(void *txdlh, int mss)
+{
+ struct vxge_hw_fifo_txd *txdp = (struct vxge_hw_fifo_txd *)txdlh;
+
+ txdp->control_0 |= VXGE_HW_FIFO_TXD_LSO_EN;
+ txdp->control_0 |= VXGE_HW_FIFO_TXD_LSO_MSS(mss);
+}
+
+/**
+ * vxge_hw_fifo_txdl_vlan_set - Set VLAN tag.
+ * @txdlh: Descriptor handle.
+ * @vlan_tag: 16bit VLAN tag.
+ *
+ * Insert VLAN tag into specified transmit descriptor.
+ * The actual insertion of the tag into outgoing frame is done by the hardware.
+ */
+static inline void vxge_hw_fifo_txdl_vlan_set(void *txdlh, u16 vlan_tag)
+{
+ struct vxge_hw_fifo_txd *txdp = (struct vxge_hw_fifo_txd *)txdlh;
+
+ txdp->control_1 |= VXGE_HW_FIFO_TXD_VLAN_ENABLE;
+ txdp->control_1 |= VXGE_HW_FIFO_TXD_VLAN_TAG(vlan_tag);
+}
+
+/**
+ * vxge_hw_fifo_txdl_private_get - Retrieve per-descriptor private data.
+ * @txdlh: Descriptor handle.
+ *
+ * Retrieve per-descriptor private data.
+ * Note that driver requests per-descriptor space via
+ * struct vxge_hw_fifo_attr passed to
+ * vxge_hw_vpath_open().
+ *
+ * Returns: private driver data associated with the descriptor.
+ */
+static inline void *vxge_hw_fifo_txdl_private_get(void *txdlh)
+{
+ struct vxge_hw_fifo_txd *txdp = (struct vxge_hw_fifo_txd *)txdlh;
+
+ return (void *)(size_t)txdp->host_control;
+}
+
+/**
+ * struct vxge_hw_ring_attr - Ring open "template".
+ * @callback: Ring completion callback. HW invokes the callback when there
+ * are new completions on that ring. In many implementations
+ * the @callback executes in the hw interrupt context.
+ * @rxd_init: Ring's descriptor-initialize callback.
+ * See vxge_hw_ring_rxd_init_f{}.
+ * If not NULL, HW invokes the callback when opening
+ * the ring.
+ * @rxd_term: Ring's descriptor-terminate callback. If not NULL,
+ * HW invokes the callback when closing the corresponding ring.
+ * See also vxge_hw_ring_rxd_term_f{}.
+ * @userdata: User-defined "context" of _that_ ring. Passed back to the
+ * user as one of the @callback, @rxd_init, and @rxd_term arguments.
+ * @per_rxd_space: If specified (i.e., greater than zero): extra space
+ * reserved by HW per each receive descriptor.
+ * Can be used to store
+ * and retrieve on completion, information specific
+ * to the driver.
+ *
+ * Ring open "template". User fills the structure with ring
+ * attributes and passes it to vxge_hw_vpath_open().
+ */
+struct vxge_hw_ring_attr {
+ enum vxge_hw_status (*callback)(
+ struct __vxge_hw_ring *ringh,
+ void *rxdh,
+ u8 t_code,
+ void *userdata);
+
+ enum vxge_hw_status (*rxd_init)(
+ void *rxdh,
+ void *userdata);
+
+ void (*rxd_term)(
+ void *rxdh,
+ enum vxge_hw_rxd_state state,
+ void *userdata);
+
+ void *userdata;
+ u32 per_rxd_space;
+};
+
+/**
+ * function vxge_hw_fifo_callback_f - FIFO callback.
+ * @vpath_handle: Virtual path whose Fifo "containing" 1 or more completed
+ * descriptors.
+ * @txdlh: First completed descriptor.
+ * @txdl_priv: Pointer to per txdl space allocated
+ * @t_code: Transfer code, as per Titan User Guide.
+ * Returned by HW.
+ * @host_control: Opaque 64bit data stored by driver inside the Titan
+ * descriptor prior to posting the latter on the fifo
+ * via vxge_hw_fifo_txdl_post(). The @host_control is returned
+ * as is to the driver with each completed descriptor.
+ * @userdata: Opaque per-fifo data specified at fifo open
+ * time, via vxge_hw_vpath_open().
+ *
+ * Fifo completion callback (type declaration). A single per-fifo
+ * callback is specified at fifo open time, via
+ * vxge_hw_vpath_open(). Typically gets called as part of the processing
+ * of the Interrupt Service Routine.
+ *
+ * Fifo callback gets called by HW if, and only if, there is at least
+ * one new completion on a given fifo. Upon processing the first @txdlh driver
+ * is _supposed_ to continue consuming completions using:
+ * - vxge_hw_fifo_txdl_next_completed()
+ *
+ * Note that failure to process new completions in a timely fashion
+ * leads to VXGE_HW_INF_OUT_OF_DESCRIPTORS condition.
+ *
+ * Non-zero @t_code means failure to process transmit descriptor.
+ *
+ * In the "transmit" case the failure could happen, for instance, when the
+ * link is down, in which case Titan completes the descriptor because it
+ * is not able to send the data out.
+ *
+ * For details please refer to Titan User Guide.
+ *
+ * See also: vxge_hw_fifo_txdl_next_completed(), vxge_hw_fifo_txdl_term_f{}.
+ */
+/**
+ * function vxge_hw_fifo_txdl_term_f - Terminate descriptor callback.
+ * @txdlh: First completed descriptor.
+ * @txdl_priv: Pointer to per txdl space allocated
+ * @state: One of the enum vxge_hw_txdl_state{} enumerated states.
+ * @userdata: Per-fifo user data (a.k.a. context) specified at
+ * fifo open time, via vxge_hw_vpath_open().
+ *
+ * Terminate descriptor callback. Unless NULL is specified in the
+ * struct vxge_hw_fifo_attr{} structure passed to vxge_hw_vpath_open()),
+ * HW invokes the callback as part of closing fifo, prior to
+ * de-allocating the ring and associated data structures
+ * (including descriptors).
+ * driver should utilize the callback to (for instance) unmap
+ * and free DMA data buffers associated with the posted (state =
+ * VXGE_HW_TXDL_STATE_POSTED) descriptors,
+ * as well as other relevant cleanup functions.
+ *
+ * See also: struct vxge_hw_fifo_attr{}
+ */
+/**
+ * struct vxge_hw_fifo_attr - Fifo open "template".
+ * @callback: Fifo completion callback. HW invokes the callback when there
+ * are new completions on that fifo. In many implementations
+ * the @callback executes in the hw interrupt context.
+ * @txdl_term: Fifo's descriptor-terminate callback. If not NULL,
+ * HW invokes the callback when closing the corresponding fifo.
+ * See also vxge_hw_fifo_txdl_term_f{}.
+ * @userdata: User-defined "context" of _that_ fifo. Passed back to the
+ * user as one of the @callback, and @txdl_term arguments.
+ * @per_txdl_space: If specified (i.e., greater than zero): extra space
+ * reserved by HW per each transmit descriptor. Can be used to
+ * store, and retrieve on completion, information specific
+ * to the driver.
+ *
+ * Fifo open "template". User fills the structure with fifo
+ * attributes and passes it to vxge_hw_vpath_open().
+ */
+struct vxge_hw_fifo_attr {
+
+ enum vxge_hw_status (*callback)(
+ struct __vxge_hw_fifo *fifo_handle,
+ void *txdlh,
+ enum vxge_hw_fifo_tcode t_code,
+ void *userdata,
+ void **skb_ptr);
+
+ void (*txdl_term)(
+ void *txdlh,
+ enum vxge_hw_txdl_state state,
+ void *userdata);
+
+ void *userdata;
+ u32 per_txdl_space;
+};
+
+/**
+ * struct vxge_hw_vpath_attr - Attributes of virtual path
+ * @vp_id: Identifier of Virtual Path
+ * @ring_attr: Attributes of ring for non-offload receive
+ * @fifo_attr: Attributes of fifo for non-offload transmit
+ *
+ * Attributes of virtual path. This structure is passed as parameter
+ * to the vxge_hw_vpath_open() routine to set the attributes of ring and fifo.
+ */
+struct vxge_hw_vpath_attr {
+ u32 vp_id;
+ struct vxge_hw_ring_attr ring_attr;
+ struct vxge_hw_fifo_attr fifo_attr;
+};
+
+enum vxge_hw_status
+__vxge_hw_blockpool_create(struct __vxge_hw_device *hldev,
+ struct __vxge_hw_blockpool *blockpool,
+ u32 pool_size,
+ u32 pool_max);
+
+void
+__vxge_hw_blockpool_destroy(struct __vxge_hw_blockpool *blockpool);
+
+struct __vxge_hw_blockpool_entry *
+__vxge_hw_blockpool_block_allocate(struct __vxge_hw_device *hldev,
+ u32 size);
+
+void
+__vxge_hw_blockpool_block_free(struct __vxge_hw_device *hldev,
+ struct __vxge_hw_blockpool_entry *entry);
+
+void *
+__vxge_hw_blockpool_malloc(struct __vxge_hw_device *hldev,
+ u32 size,
+ struct vxge_hw_mempool_dma *dma_object);
+
+void
+__vxge_hw_blockpool_free(struct __vxge_hw_device *hldev,
+ void *memblock,
+ u32 size,
+ struct vxge_hw_mempool_dma *dma_object);
+
+enum vxge_hw_status
+__vxge_hw_device_fifo_config_check(struct vxge_hw_fifo_config *fifo_config);
+
+enum vxge_hw_status
+__vxge_hw_device_config_check(struct vxge_hw_device_config *new_config);
+
+enum vxge_hw_status
+vxge_hw_mgmt_device_config(struct __vxge_hw_device *devh,
+ struct vxge_hw_device_config *dev_config, int size);
+
+enum vxge_hw_status __devinit vxge_hw_device_hw_info_get(
+ void __iomem *bar0,
+ struct vxge_hw_device_hw_info *hw_info);
+
+enum vxge_hw_status
+__vxge_hw_vpath_fw_ver_get(
+ u32 vp_id,
+ struct vxge_hw_vpath_reg __iomem *vpath_reg,
+ struct vxge_hw_device_hw_info *hw_info);
+
+enum vxge_hw_status
+__vxge_hw_vpath_card_info_get(
+ u32 vp_id,
+ struct vxge_hw_vpath_reg __iomem *vpath_reg,
+ struct vxge_hw_device_hw_info *hw_info);
+
+enum vxge_hw_status __devinit vxge_hw_device_config_default_get(
+ struct vxge_hw_device_config *device_config);
+
+/**
+ * vxge_hw_device_link_state_get - Get link state.
+ * @devh: HW device handle.
+ *
+ * Get link state.
+ * Returns: link state.
+ */
+static inline
+enum vxge_hw_device_link_state vxge_hw_device_link_state_get(
+ struct __vxge_hw_device *devh)
+{
+ return devh->link_state;
+}
+
+void vxge_hw_device_terminate(struct __vxge_hw_device *devh);
+
+const u8 *
+vxge_hw_device_serial_number_get(struct __vxge_hw_device *devh);
+
+u16 vxge_hw_device_link_width_get(struct __vxge_hw_device *devh);
+
+const u8 *
+vxge_hw_device_product_name_get(struct __vxge_hw_device *devh);
+
+enum vxge_hw_status __devinit vxge_hw_device_initialize(
+ struct __vxge_hw_device **devh,
+ struct vxge_hw_device_attr *attr,
+ struct vxge_hw_device_config *device_config);
+
+enum vxge_hw_status vxge_hw_device_getpause_data(
+ struct __vxge_hw_device *devh,
+ u32 port,
+ u32 *tx,
+ u32 *rx);
+
+enum vxge_hw_status vxge_hw_device_setpause_data(
+ struct __vxge_hw_device *devh,
+ u32 port,
+ u32 tx,
+ u32 rx);
+
+static inline void *vxge_os_dma_malloc(struct pci_dev *pdev,
+ unsigned long size,
+ struct pci_dev **p_dmah,
+ struct pci_dev **p_dma_acch)
+{
+ gfp_t flags;
+ void *vaddr;
+ unsigned long misaligned = 0;
+ *p_dma_acch = *p_dmah = NULL;
+
+ if (in_interrupt())
+ flags = GFP_ATOMIC | GFP_DMA;
+ else
+ flags = GFP_KERNEL | GFP_DMA;
+
+ size += VXGE_CACHE_LINE_SIZE;
+
+ vaddr = kmalloc((size), flags);
+ if (vaddr == NULL)
+ return vaddr;
+ misaligned = (unsigned long)VXGE_ALIGN(*((u64 *)&vaddr),
+ VXGE_CACHE_LINE_SIZE);
+ *(unsigned long *)p_dma_acch = misaligned;
+ vaddr = (void *)((u8 *)vaddr + misaligned);
+ return vaddr;
+}
+
+extern void vxge_hw_blockpool_block_add(
+ struct __vxge_hw_device *devh,
+ void *block_addr,
+ u32 length,
+ struct pci_dev *dma_h,
+ struct pci_dev *acc_handle);
+
+static inline void vxge_os_dma_malloc_async(struct pci_dev *pdev, void *devh,
+ unsigned long size)
+{
+ gfp_t flags;
+ void *vaddr;
+
+ if (in_interrupt())
+ flags = GFP_ATOMIC | GFP_DMA;
+ else
+ flags = GFP_KERNEL | GFP_DMA;
+
+ vaddr = kmalloc((size), flags);
+
+ vxge_hw_blockpool_block_add(devh, vaddr, size, pdev, pdev);
+}
+
+static inline void vxge_os_dma_free(struct pci_dev *pdev, const void *vaddr,
+ struct pci_dev **p_dma_acch)
+{
+ unsigned long misaligned = *(unsigned long *)p_dma_acch;
+ u8 *tmp = (u8 *)vaddr;
+ tmp -= misaligned;
+ kfree((void *)tmp);
+}
+
+/*
+ * __vxge_hw_mempool_item_priv - will return pointer on per item private space
+ */
+static inline void*
+__vxge_hw_mempool_item_priv(
+ struct vxge_hw_mempool *mempool,
+ u32 memblock_idx,
+ void *item,
+ u32 *memblock_item_idx)
+{
+ ptrdiff_t offset;
+ void *memblock = mempool->memblocks_arr[memblock_idx];
+
+
+ offset = (u32)((u8 *)item - (u8 *)memblock);
+ vxge_assert(offset >= 0 && (u32)offset < mempool->memblock_size);
+
+ (*memblock_item_idx) = (u32) offset / mempool->item_size;
+ vxge_assert((*memblock_item_idx) < mempool->items_per_memblock);
+
+ return (u8 *)mempool->memblocks_priv_arr[memblock_idx] +
+ (*memblock_item_idx) * mempool->items_priv_size;
+}
+
+enum vxge_hw_status
+__vxge_hw_mempool_grow(
+ struct vxge_hw_mempool *mempool,
+ u32 num_allocate,
+ u32 *num_allocated);
+
+struct vxge_hw_mempool*
+__vxge_hw_mempool_create(
+ struct __vxge_hw_device *devh,
+ u32 memblock_size,
+ u32 item_size,
+ u32 private_size,
+ u32 items_initial,
+ u32 items_max,
+ struct vxge_hw_mempool_cbs *mp_callback,
+ void *userdata);
+
+struct __vxge_hw_channel*
+__vxge_hw_channel_allocate(struct __vxge_hw_vpath_handle *vph,
+ enum __vxge_hw_channel_type type, u32 length,
+ u32 per_dtr_space, void *userdata);
+
+void
+__vxge_hw_channel_free(
+ struct __vxge_hw_channel *channel);
+
+enum vxge_hw_status
+__vxge_hw_channel_initialize(
+ struct __vxge_hw_channel *channel);
+
+enum vxge_hw_status
+__vxge_hw_channel_reset(
+ struct __vxge_hw_channel *channel);
+
+/*
+ * __vxge_hw_fifo_txdl_priv - Return the max fragments allocated
+ * for the fifo.
+ * @fifo: Fifo
+ * @txdp: Poniter to a TxD
+ */
+static inline struct __vxge_hw_fifo_txdl_priv *
+__vxge_hw_fifo_txdl_priv(
+ struct __vxge_hw_fifo *fifo,
+ struct vxge_hw_fifo_txd *txdp)
+{
+ return (struct __vxge_hw_fifo_txdl_priv *)
+ (((char *)((ulong)txdp->host_control)) +
+ fifo->per_txdl_space);
+}
+
+enum vxge_hw_status vxge_hw_vpath_open(
+ struct __vxge_hw_device *devh,
+ struct vxge_hw_vpath_attr *attr,
+ struct __vxge_hw_vpath_handle **vpath_handle);
+
+enum vxge_hw_status
+__vxge_hw_device_vpath_reset_in_prog_check(u64 __iomem *vpath_rst_in_prog);
+
+enum vxge_hw_status vxge_hw_vpath_close(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status
+vxge_hw_vpath_reset(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status
+vxge_hw_vpath_recover_from_reset(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+void
+vxge_hw_vpath_enable(struct __vxge_hw_vpath_handle *vp);
+
+enum vxge_hw_status
+vxge_hw_vpath_check_leak(struct __vxge_hw_ring *ringh);
+
+enum vxge_hw_status vxge_hw_vpath_mtu_set(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u32 new_mtu);
+
+enum vxge_hw_status vxge_hw_vpath_stats_enable(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status
+__vxge_hw_vpath_stats_access(
+ struct __vxge_hw_virtualpath *vpath,
+ u32 operation,
+ u32 offset,
+ u64 *stat);
+
+enum vxge_hw_status
+__vxge_hw_vpath_xmac_tx_stats_get(
+ struct __vxge_hw_virtualpath *vpath,
+ struct vxge_hw_xmac_vpath_tx_stats *vpath_tx_stats);
+
+enum vxge_hw_status
+__vxge_hw_vpath_xmac_rx_stats_get(
+ struct __vxge_hw_virtualpath *vpath,
+ struct vxge_hw_xmac_vpath_rx_stats *vpath_rx_stats);
+
+enum vxge_hw_status
+__vxge_hw_vpath_stats_get(
+ struct __vxge_hw_virtualpath *vpath,
+ struct vxge_hw_vpath_stats_hw_info *hw_stats);
+
+void
+vxge_hw_vpath_rx_doorbell_init(struct __vxge_hw_vpath_handle *vp);
+
+enum vxge_hw_status
+__vxge_hw_device_vpath_config_check(struct vxge_hw_vp_config *vp_config);
+
+void
+__vxge_hw_device_pci_e_init(struct __vxge_hw_device *hldev);
+
+enum vxge_hw_status
+__vxge_hw_legacy_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg);
+
+enum vxge_hw_status
+__vxge_hw_vpath_swapper_set(struct vxge_hw_vpath_reg __iomem *vpath_reg);
+
+enum vxge_hw_status
+__vxge_hw_kdfc_swapper_set(struct vxge_hw_legacy_reg __iomem *legacy_reg,
+ struct vxge_hw_vpath_reg __iomem *vpath_reg);
+
+enum vxge_hw_status
+__vxge_hw_device_register_poll(
+ void __iomem *reg,
+ u64 mask, u32 max_millis);
+
+#ifndef readq
+static inline u64 readq(void __iomem *addr)
+{
+ u64 ret = 0;
+ ret = readl(addr + 4);
+ ret <<= 32;
+ ret |= readl(addr);
+
+ return ret;
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(u64 val, void __iomem *addr)
+{
+ writel((u32) (val), addr);
+ writel((u32) (val >> 32), (addr + 4));
+}
+#endif
+
+static inline void __vxge_hw_pio_mem_write32_upper(u32 val, void __iomem *addr)
+{
+ writel(val, addr + 4);
+}
+
+static inline void __vxge_hw_pio_mem_write32_lower(u32 val, void __iomem *addr)
+{
+ writel(val, addr);
+}
+
+static inline enum vxge_hw_status
+__vxge_hw_pio_mem_write64(u64 val64, void __iomem *addr,
+ u64 mask, u32 max_millis)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ __vxge_hw_pio_mem_write32_lower((u32)vxge_bVALn(val64, 32, 32), addr);
+ wmb();
+ __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32), addr);
+ wmb();
+
+ status = __vxge_hw_device_register_poll(addr, mask, max_millis);
+ return status;
+}
+
+struct vxge_hw_toc_reg __iomem *
+__vxge_hw_device_toc_get(void __iomem *bar0);
+
+enum vxge_hw_status
+__vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev);
+
+void
+__vxge_hw_device_id_get(struct __vxge_hw_device *hldev);
+
+void
+__vxge_hw_device_host_info_get(struct __vxge_hw_device *hldev);
+
+enum vxge_hw_status
+vxge_hw_device_flick_link_led(struct __vxge_hw_device *devh, u64 on_off);
+
+enum vxge_hw_status
+__vxge_hw_device_initialize(struct __vxge_hw_device *hldev);
+
+enum vxge_hw_status
+__vxge_hw_vpath_pci_read(
+ struct __vxge_hw_virtualpath *vpath,
+ u32 phy_func_0,
+ u32 offset,
+ u32 *val);
+
+enum vxge_hw_status
+__vxge_hw_vpath_addr_get(
+ u32 vp_id,
+ struct vxge_hw_vpath_reg __iomem *vpath_reg,
+ u8 (macaddr)[ETH_ALEN],
+ u8 (macaddr_mask)[ETH_ALEN]);
+
+u32
+__vxge_hw_vpath_func_id_get(
+ u32 vp_id, struct vxge_hw_vpmgmt_reg __iomem *vpmgmt_reg);
+
+enum vxge_hw_status
+__vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath);
+
+/**
+ * vxge_debug
+ * @level: level of debug verbosity.
+ * @mask: mask for the debug
+ * @buf: Circular buffer for tracing
+ * @fmt: printf like format string
+ *
+ * Provides logging facilities. Can be customized on per-module
+ * basis or/and with debug levels. Input parameters, except
+ * module and level, are the same as posix printf. This function
+ * may be compiled out if DEBUG macro was never defined.
+ * See also: enum vxge_debug_level{}.
+ */
+
+#define vxge_trace_aux(level, mask, fmt, ...) \
+{\
+ vxge_os_vaprintf(level, mask, fmt, __VA_ARGS__);\
+}
+
+#define vxge_debug(module, level, mask, fmt, ...) { \
+if ((level >= VXGE_TRACE && ((module & VXGE_DEBUG_TRACE_MASK) == module)) || \
+ (level >= VXGE_ERR && ((module & VXGE_DEBUG_ERR_MASK) == module))) {\
+ if ((mask & VXGE_DEBUG_MASK) == mask)\
+ vxge_trace_aux(level, mask, fmt, __VA_ARGS__); \
+} \
+}
+
+#if (VXGE_COMPONENT_LL & VXGE_DEBUG_MODULE_MASK)
+#define vxge_debug_ll(level, mask, fmt, ...) \
+{\
+ vxge_debug(VXGE_COMPONENT_LL, level, mask, fmt, __VA_ARGS__);\
+}
+
+#else
+#define vxge_debug_ll(level, mask, fmt, ...)
+#endif
+
+enum vxge_hw_status vxge_hw_vpath_rts_rth_itable_set(
+ struct __vxge_hw_vpath_handle **vpath_handles,
+ u32 vpath_count,
+ u8 *mtable,
+ u8 *itable,
+ u32 itable_size);
+
+enum vxge_hw_status vxge_hw_vpath_rts_rth_set(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ enum vxge_hw_rth_algoritms algorithm,
+ struct vxge_hw_rth_hash_types *hash_type,
+ u16 bucket_size);
+
+#endif
diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c
new file mode 100644
index 000000000000..c6736b972635
--- /dev/null
+++ b/drivers/net/vxge/vxge-ethtool.c
@@ -0,0 +1,1148 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice. This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-ethtool.c: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#include<linux/ethtool.h>
+#include <linux/pci.h>
+#include <linux/etherdevice.h>
+
+#include "vxge-ethtool.h"
+
+/**
+ * vxge_ethtool_sset - Sets different link parameters.
+ * @dev: device pointer.
+ * @info: pointer to the structure with parameters given by ethtool to set
+ * link information.
+ *
+ * The function sets different link parameters provided by the user onto
+ * the NIC.
+ * Return value:
+ * 0 on success.
+ */
+
+static int vxge_ethtool_sset(struct net_device *dev, struct ethtool_cmd *info)
+{
+ /* We currently only support 10Gb/FULL */
+ if ((info->autoneg == AUTONEG_ENABLE) ||
+ (info->speed != SPEED_10000) || (info->duplex != DUPLEX_FULL))
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
+ * vxge_ethtool_gset - Return link specific information.
+ * @dev: device pointer.
+ * @info: pointer to the structure with parameters given by ethtool
+ * to return link information.
+ *
+ * Returns link specific information like speed, duplex etc.. to ethtool.
+ * Return value :
+ * return 0 on success.
+ */
+static int vxge_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
+{
+ info->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
+ info->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
+ info->port = PORT_FIBRE;
+
+ info->transceiver = XCVR_EXTERNAL;
+
+ if (netif_carrier_ok(dev)) {
+ info->speed = SPEED_10000;
+ info->duplex = DUPLEX_FULL;
+ } else {
+ info->speed = -1;
+ info->duplex = -1;
+ }
+
+ info->autoneg = AUTONEG_DISABLE;
+ return 0;
+}
+
+/**
+ * vxge_ethtool_gdrvinfo - Returns driver specific information.
+ * @dev: device pointer.
+ * @info: pointer to the structure with parameters given by ethtool to
+ * return driver information.
+ *
+ * Returns driver specefic information like name, version etc.. to ethtool.
+ */
+static void vxge_ethtool_gdrvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct vxgedev *vdev;
+ vdev = (struct vxgedev *)netdev_priv(dev);
+ strlcpy(info->driver, VXGE_DRIVER_NAME, sizeof(VXGE_DRIVER_NAME));
+ strlcpy(info->version, DRV_VERSION, sizeof(DRV_VERSION));
+ strlcpy(info->fw_version, vdev->fw_version, VXGE_HW_FW_STRLEN);
+ strlcpy(info->bus_info, pci_name(vdev->pdev), sizeof(info->bus_info));
+ info->regdump_len = sizeof(struct vxge_hw_vpath_reg)
+ * vdev->no_of_vpath;
+
+ info->n_stats = STAT_LEN;
+}
+
+/**
+ * vxge_ethtool_gregs - dumps the entire space of Titan into the buffer.
+ * @dev: device pointer.
+ * @regs: pointer to the structure with parameters given by ethtool for
+ * dumping the registers.
+ * @reg_space: The input argumnet into which all the registers are dumped.
+ *
+ * Dumps the vpath register space of Titan NIC into the user given
+ * buffer area.
+ */
+static void vxge_ethtool_gregs(struct net_device *dev,
+ struct ethtool_regs *regs, void *space)
+{
+ int index, offset;
+ enum vxge_hw_status status;
+ u64 reg;
+ u8 *reg_space = (u8 *) space;
+ struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
+ pci_get_drvdata(vdev->pdev);
+
+ regs->len = sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath;
+ regs->version = vdev->pdev->subsystem_device;
+ for (index = 0; index < vdev->no_of_vpath; index++) {
+ for (offset = 0; offset < sizeof(struct vxge_hw_vpath_reg);
+ offset += 8) {
+ status = vxge_hw_mgmt_reg_read(hldev,
+ vxge_hw_mgmt_reg_type_vpath,
+ vdev->vpaths[index].device_id,
+ offset, &reg);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "%s:%d Getting reg dump Failed",
+ __func__, __LINE__);
+ return;
+ }
+
+ memcpy((reg_space + offset), &reg, 8);
+ }
+ }
+}
+
+/**
+ * vxge_ethtool_idnic - To physically identify the nic on the system.
+ * @dev : device pointer.
+ * @id : pointer to the structure with identification parameters given by
+ * ethtool.
+ *
+ * Used to physically identify the NIC on the system.
+ * The Link LED will blink for a time specified by the user.
+ * Return value:
+ * 0 on success
+ */
+static int vxge_ethtool_idnic(struct net_device *dev, u32 data)
+{
+ struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
+ pci_get_drvdata(vdev->pdev);
+
+ vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_ON);
+ msleep_interruptible(data ? (data * HZ) : VXGE_MAX_FLICKER_TIME);
+ vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_OFF);
+
+ return 0;
+}
+
+/**
+ * vxge_ethtool_getpause_data - Pause frame frame generation and reception.
+ * @dev : device pointer.
+ * @ep : pointer to the structure with pause parameters given by ethtool.
+ * Description:
+ * Returns the Pause frame generation and reception capability of the NIC.
+ * Return value:
+ * void
+ */
+static void vxge_ethtool_getpause_data(struct net_device *dev,
+ struct ethtool_pauseparam *ep)
+{
+ struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
+ pci_get_drvdata(vdev->pdev);
+
+ vxge_hw_device_getpause_data(hldev, 0, &ep->tx_pause, &ep->rx_pause);
+}
+
+/**
+ * vxge_ethtool_setpause_data - set/reset pause frame generation.
+ * @dev : device pointer.
+ * @ep : pointer to the structure with pause parameters given by ethtool.
+ * Description:
+ * It can be used to set or reset Pause frame generation or reception
+ * support of the NIC.
+ * Return value:
+ * int, returns 0 on Success
+ */
+static int vxge_ethtool_setpause_data(struct net_device *dev,
+ struct ethtool_pauseparam *ep)
+{
+ struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
+ pci_get_drvdata(vdev->pdev);
+
+ vxge_hw_device_setpause_data(hldev, 0, ep->tx_pause, ep->rx_pause);
+
+ vdev->config.tx_pause_enable = ep->tx_pause;
+ vdev->config.rx_pause_enable = ep->rx_pause;
+
+ return 0;
+}
+
+static void vxge_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *estats, u64 *tmp_stats)
+{
+ int j, k;
+ enum vxge_hw_status status;
+ enum vxge_hw_status swstatus;
+ struct vxge_vpath *vpath = NULL;
+
+ struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ struct __vxge_hw_device *hldev = vdev->devh;
+ struct vxge_hw_xmac_stats *xmac_stats;
+ struct vxge_hw_device_stats_sw_info *sw_stats;
+ struct vxge_hw_device_stats_hw_info *hw_stats;
+
+ u64 *ptr = tmp_stats;
+
+ memset(tmp_stats, 0,
+ vxge_ethtool_get_sset_count(dev, ETH_SS_STATS) * sizeof(u64));
+
+ xmac_stats = kzalloc(sizeof(struct vxge_hw_xmac_stats), GFP_KERNEL);
+ if (xmac_stats == NULL) {
+ vxge_debug_init(VXGE_ERR,
+ "%s : %d Memory Allocation failed for xmac_stats",
+ __func__, __LINE__);
+ return;
+ }
+
+ sw_stats = kzalloc(sizeof(struct vxge_hw_device_stats_sw_info),
+ GFP_KERNEL);
+ if (sw_stats == NULL) {
+ kfree(xmac_stats);
+ vxge_debug_init(VXGE_ERR,
+ "%s : %d Memory Allocation failed for sw_stats",
+ __func__, __LINE__);
+ return;
+ }
+
+ hw_stats = kzalloc(sizeof(struct vxge_hw_device_stats_hw_info),
+ GFP_KERNEL);
+ if (hw_stats == NULL) {
+ kfree(xmac_stats);
+ kfree(sw_stats);
+ vxge_debug_init(VXGE_ERR,
+ "%s : %d Memory Allocation failed for hw_stats",
+ __func__, __LINE__);
+ return;
+ }
+
+ *ptr++ = 0;
+ status = vxge_hw_device_xmac_stats_get(hldev, xmac_stats);
+ if (status != VXGE_HW_OK) {
+ if (status != VXGE_HW_ERR_PRIVILAGED_OPEARATION) {
+ vxge_debug_init(VXGE_ERR,
+ "%s : %d Failure in getting xmac stats",
+ __func__, __LINE__);
+ }
+ }
+ swstatus = vxge_hw_driver_stats_get(hldev, sw_stats);
+ if (swstatus != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "%s : %d Failure in getting sw stats",
+ __func__, __LINE__);
+ }
+
+ status = vxge_hw_device_stats_get(hldev, hw_stats);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "%s : %d hw_stats_get error", __func__, __LINE__);
+ }
+
+ for (k = 0; k < vdev->no_of_vpath; k++) {
+ struct vxge_hw_vpath_stats_hw_info *vpath_info;
+
+ vpath = &vdev->vpaths[k];
+ j = vpath->device_id;
+ vpath_info = hw_stats->vpath_info[j];
+ if (!vpath_info) {
+ memset(ptr, 0, (VXGE_HW_VPATH_TX_STATS_LEN +
+ VXGE_HW_VPATH_RX_STATS_LEN) * sizeof(u64));
+ ptr += (VXGE_HW_VPATH_TX_STATS_LEN +
+ VXGE_HW_VPATH_RX_STATS_LEN);
+ continue;
+ }
+
+ *ptr++ = vpath_info->tx_stats.tx_ttl_eth_frms;
+ *ptr++ = vpath_info->tx_stats.tx_ttl_eth_octets;
+ *ptr++ = vpath_info->tx_stats.tx_data_octets;
+ *ptr++ = vpath_info->tx_stats.tx_mcast_frms;
+ *ptr++ = vpath_info->tx_stats.tx_bcast_frms;
+ *ptr++ = vpath_info->tx_stats.tx_ucast_frms;
+ *ptr++ = vpath_info->tx_stats.tx_tagged_frms;
+ *ptr++ = vpath_info->tx_stats.tx_vld_ip;
+ *ptr++ = vpath_info->tx_stats.tx_vld_ip_octets;
+ *ptr++ = vpath_info->tx_stats.tx_icmp;
+ *ptr++ = vpath_info->tx_stats.tx_tcp;
+ *ptr++ = vpath_info->tx_stats.tx_rst_tcp;
+ *ptr++ = vpath_info->tx_stats.tx_udp;
+ *ptr++ = vpath_info->tx_stats.tx_unknown_protocol;
+ *ptr++ = vpath_info->tx_stats.tx_lost_ip;
+ *ptr++ = vpath_info->tx_stats.tx_parse_error;
+ *ptr++ = vpath_info->tx_stats.tx_tcp_offload;
+ *ptr++ = vpath_info->tx_stats.tx_retx_tcp_offload;
+ *ptr++ = vpath_info->tx_stats.tx_lost_ip_offload;
+ *ptr++ = vpath_info->rx_stats.rx_ttl_eth_frms;
+ *ptr++ = vpath_info->rx_stats.rx_vld_frms;
+ *ptr++ = vpath_info->rx_stats.rx_offload_frms;
+ *ptr++ = vpath_info->rx_stats.rx_ttl_eth_octets;
+ *ptr++ = vpath_info->rx_stats.rx_data_octets;
+ *ptr++ = vpath_info->rx_stats.rx_offload_octets;
+ *ptr++ = vpath_info->rx_stats.rx_vld_mcast_frms;
+ *ptr++ = vpath_info->rx_stats.rx_vld_bcast_frms;
+ *ptr++ = vpath_info->rx_stats.rx_accepted_ucast_frms;
+ *ptr++ = vpath_info->rx_stats.rx_accepted_nucast_frms;
+ *ptr++ = vpath_info->rx_stats.rx_tagged_frms;
+ *ptr++ = vpath_info->rx_stats.rx_long_frms;
+ *ptr++ = vpath_info->rx_stats.rx_usized_frms;
+ *ptr++ = vpath_info->rx_stats.rx_osized_frms;
+ *ptr++ = vpath_info->rx_stats.rx_frag_frms;
+ *ptr++ = vpath_info->rx_stats.rx_jabber_frms;
+ *ptr++ = vpath_info->rx_stats.rx_ttl_64_frms;
+ *ptr++ = vpath_info->rx_stats.rx_ttl_65_127_frms;
+ *ptr++ = vpath_info->rx_stats.rx_ttl_128_255_frms;
+ *ptr++ = vpath_info->rx_stats.rx_ttl_256_511_frms;
+ *ptr++ = vpath_info->rx_stats.rx_ttl_512_1023_frms;
+ *ptr++ = vpath_info->rx_stats.rx_ttl_1024_1518_frms;
+ *ptr++ = vpath_info->rx_stats.rx_ttl_1519_4095_frms;
+ *ptr++ = vpath_info->rx_stats.rx_ttl_4096_8191_frms;
+ *ptr++ = vpath_info->rx_stats.rx_ttl_8192_max_frms;
+ *ptr++ = vpath_info->rx_stats.rx_ttl_gt_max_frms;
+ *ptr++ = vpath_info->rx_stats.rx_ip;
+ *ptr++ = vpath_info->rx_stats.rx_accepted_ip;
+ *ptr++ = vpath_info->rx_stats.rx_ip_octets;
+ *ptr++ = vpath_info->rx_stats.rx_err_ip;
+ *ptr++ = vpath_info->rx_stats.rx_icmp;
+ *ptr++ = vpath_info->rx_stats.rx_tcp;
+ *ptr++ = vpath_info->rx_stats.rx_udp;
+ *ptr++ = vpath_info->rx_stats.rx_err_tcp;
+ *ptr++ = vpath_info->rx_stats.rx_lost_frms;
+ *ptr++ = vpath_info->rx_stats.rx_lost_ip;
+ *ptr++ = vpath_info->rx_stats.rx_lost_ip_offload;
+ *ptr++ = vpath_info->rx_stats.rx_various_discard;
+ *ptr++ = vpath_info->rx_stats.rx_sleep_discard;
+ *ptr++ = vpath_info->rx_stats.rx_red_discard;
+ *ptr++ = vpath_info->rx_stats.rx_queue_full_discard;
+ *ptr++ = vpath_info->rx_stats.rx_mpa_ok_frms;
+ }
+ *ptr++ = 0;
+ for (k = 0; k < vdev->max_config_port; k++) {
+ *ptr++ = xmac_stats->aggr_stats[k].tx_frms;
+ *ptr++ = xmac_stats->aggr_stats[k].tx_data_octets;
+ *ptr++ = xmac_stats->aggr_stats[k].tx_mcast_frms;
+ *ptr++ = xmac_stats->aggr_stats[k].tx_bcast_frms;
+ *ptr++ = xmac_stats->aggr_stats[k].tx_discarded_frms;
+ *ptr++ = xmac_stats->aggr_stats[k].tx_errored_frms;
+ *ptr++ = xmac_stats->aggr_stats[k].rx_frms;
+ *ptr++ = xmac_stats->aggr_stats[k].rx_data_octets;
+ *ptr++ = xmac_stats->aggr_stats[k].rx_mcast_frms;
+ *ptr++ = xmac_stats->aggr_stats[k].rx_bcast_frms;
+ *ptr++ = xmac_stats->aggr_stats[k].rx_discarded_frms;
+ *ptr++ = xmac_stats->aggr_stats[k].rx_errored_frms;
+ *ptr++ = xmac_stats->aggr_stats[k].rx_unknown_slow_proto_frms;
+ }
+ *ptr++ = 0;
+ for (k = 0; k < vdev->max_config_port; k++) {
+ *ptr++ = xmac_stats->port_stats[k].tx_ttl_frms;
+ *ptr++ = xmac_stats->port_stats[k].tx_ttl_octets;
+ *ptr++ = xmac_stats->port_stats[k].tx_data_octets;
+ *ptr++ = xmac_stats->port_stats[k].tx_mcast_frms;
+ *ptr++ = xmac_stats->port_stats[k].tx_bcast_frms;
+ *ptr++ = xmac_stats->port_stats[k].tx_ucast_frms;
+ *ptr++ = xmac_stats->port_stats[k].tx_tagged_frms;
+ *ptr++ = xmac_stats->port_stats[k].tx_vld_ip;
+ *ptr++ = xmac_stats->port_stats[k].tx_vld_ip_octets;
+ *ptr++ = xmac_stats->port_stats[k].tx_icmp;
+ *ptr++ = xmac_stats->port_stats[k].tx_tcp;
+ *ptr++ = xmac_stats->port_stats[k].tx_rst_tcp;
+ *ptr++ = xmac_stats->port_stats[k].tx_udp;
+ *ptr++ = xmac_stats->port_stats[k].tx_parse_error;
+ *ptr++ = xmac_stats->port_stats[k].tx_unknown_protocol;
+ *ptr++ = xmac_stats->port_stats[k].tx_pause_ctrl_frms;
+ *ptr++ = xmac_stats->port_stats[k].tx_marker_pdu_frms;
+ *ptr++ = xmac_stats->port_stats[k].tx_lacpdu_frms;
+ *ptr++ = xmac_stats->port_stats[k].tx_drop_ip;
+ *ptr++ = xmac_stats->port_stats[k].tx_marker_resp_pdu_frms;
+ *ptr++ = xmac_stats->port_stats[k].tx_xgmii_char2_match;
+ *ptr++ = xmac_stats->port_stats[k].tx_xgmii_char1_match;
+ *ptr++ = xmac_stats->port_stats[k].tx_xgmii_column2_match;
+ *ptr++ = xmac_stats->port_stats[k].tx_xgmii_column1_match;
+ *ptr++ = xmac_stats->port_stats[k].tx_any_err_frms;
+ *ptr++ = xmac_stats->port_stats[k].tx_drop_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_ttl_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_vld_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_offload_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_ttl_octets;
+ *ptr++ = xmac_stats->port_stats[k].rx_data_octets;
+ *ptr++ = xmac_stats->port_stats[k].rx_offload_octets;
+ *ptr++ = xmac_stats->port_stats[k].rx_vld_mcast_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_vld_bcast_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_accepted_ucast_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_accepted_nucast_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_tagged_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_long_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_usized_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_osized_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_frag_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_jabber_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_ttl_64_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_ttl_65_127_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_ttl_128_255_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_ttl_256_511_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_ttl_512_1023_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_ttl_1024_1518_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_ttl_1519_4095_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_ttl_4096_8191_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_ttl_8192_max_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_ttl_gt_max_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_ip;
+ *ptr++ = xmac_stats->port_stats[k].rx_accepted_ip;
+ *ptr++ = xmac_stats->port_stats[k].rx_ip_octets;
+ *ptr++ = xmac_stats->port_stats[k].rx_err_ip;
+ *ptr++ = xmac_stats->port_stats[k].rx_icmp;
+ *ptr++ = xmac_stats->port_stats[k].rx_tcp;
+ *ptr++ = xmac_stats->port_stats[k].rx_udp;
+ *ptr++ = xmac_stats->port_stats[k].rx_err_tcp;
+ *ptr++ = xmac_stats->port_stats[k].rx_pause_count;
+ *ptr++ = xmac_stats->port_stats[k].rx_pause_ctrl_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_unsup_ctrl_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_fcs_err_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_in_rng_len_err_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_out_rng_len_err_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_drop_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_discarded_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_drop_ip;
+ *ptr++ = xmac_stats->port_stats[k].rx_drop_udp;
+ *ptr++ = xmac_stats->port_stats[k].rx_marker_pdu_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_lacpdu_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_unknown_pdu_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_marker_resp_pdu_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_fcs_discard;
+ *ptr++ = xmac_stats->port_stats[k].rx_illegal_pdu_frms;
+ *ptr++ = xmac_stats->port_stats[k].rx_switch_discard;
+ *ptr++ = xmac_stats->port_stats[k].rx_len_discard;
+ *ptr++ = xmac_stats->port_stats[k].rx_rpa_discard;
+ *ptr++ = xmac_stats->port_stats[k].rx_l2_mgmt_discard;
+ *ptr++ = xmac_stats->port_stats[k].rx_rts_discard;
+ *ptr++ = xmac_stats->port_stats[k].rx_trash_discard;
+ *ptr++ = xmac_stats->port_stats[k].rx_buff_full_discard;
+ *ptr++ = xmac_stats->port_stats[k].rx_red_discard;
+ *ptr++ = xmac_stats->port_stats[k].rx_xgmii_ctrl_err_cnt;
+ *ptr++ = xmac_stats->port_stats[k].rx_xgmii_data_err_cnt;
+ *ptr++ = xmac_stats->port_stats[k].rx_xgmii_char1_match;
+ *ptr++ = xmac_stats->port_stats[k].rx_xgmii_err_sym;
+ *ptr++ = xmac_stats->port_stats[k].rx_xgmii_column1_match;
+ *ptr++ = xmac_stats->port_stats[k].rx_xgmii_char2_match;
+ *ptr++ = xmac_stats->port_stats[k].rx_local_fault;
+ *ptr++ = xmac_stats->port_stats[k].rx_xgmii_column2_match;
+ *ptr++ = xmac_stats->port_stats[k].rx_jettison;
+ *ptr++ = xmac_stats->port_stats[k].rx_remote_fault;
+ }
+
+ *ptr++ = 0;
+ for (k = 0; k < vdev->no_of_vpath; k++) {
+ struct vxge_hw_vpath_stats_sw_info *vpath_info;
+
+ vpath = &vdev->vpaths[k];
+ j = vpath->device_id;
+ vpath_info = (struct vxge_hw_vpath_stats_sw_info *)
+ &sw_stats->vpath_info[j];
+ *ptr++ = vpath_info->soft_reset_cnt;
+ *ptr++ = vpath_info->error_stats.unknown_alarms;
+ *ptr++ = vpath_info->error_stats.network_sustained_fault;
+ *ptr++ = vpath_info->error_stats.network_sustained_ok;
+ *ptr++ = vpath_info->error_stats.kdfcctl_fifo0_overwrite;
+ *ptr++ = vpath_info->error_stats.kdfcctl_fifo0_poison;
+ *ptr++ = vpath_info->error_stats.kdfcctl_fifo0_dma_error;
+ *ptr++ = vpath_info->error_stats.dblgen_fifo0_overflow;
+ *ptr++ = vpath_info->error_stats.statsb_pif_chain_error;
+ *ptr++ = vpath_info->error_stats.statsb_drop_timeout;
+ *ptr++ = vpath_info->error_stats.target_illegal_access;
+ *ptr++ = vpath_info->error_stats.ini_serr_det;
+ *ptr++ = vpath_info->error_stats.prc_ring_bumps;
+ *ptr++ = vpath_info->error_stats.prc_rxdcm_sc_err;
+ *ptr++ = vpath_info->error_stats.prc_rxdcm_sc_abort;
+ *ptr++ = vpath_info->error_stats.prc_quanta_size_err;
+ *ptr++ = vpath_info->ring_stats.common_stats.full_cnt;
+ *ptr++ = vpath_info->ring_stats.common_stats.usage_cnt;
+ *ptr++ = vpath_info->ring_stats.common_stats.usage_max;
+ *ptr++ = vpath_info->ring_stats.common_stats.
+ reserve_free_swaps_cnt;
+ *ptr++ = vpath_info->ring_stats.common_stats.total_compl_cnt;
+ for (j = 0; j < VXGE_HW_DTR_MAX_T_CODE; j++)
+ *ptr++ = vpath_info->ring_stats.rxd_t_code_err_cnt[j];
+ *ptr++ = vpath_info->fifo_stats.common_stats.full_cnt;
+ *ptr++ = vpath_info->fifo_stats.common_stats.usage_cnt;
+ *ptr++ = vpath_info->fifo_stats.common_stats.usage_max;
+ *ptr++ = vpath_info->fifo_stats.common_stats.
+ reserve_free_swaps_cnt;
+ *ptr++ = vpath_info->fifo_stats.common_stats.total_compl_cnt;
+ *ptr++ = vpath_info->fifo_stats.total_posts;
+ *ptr++ = vpath_info->fifo_stats.total_buffers;
+ for (j = 0; j < VXGE_HW_DTR_MAX_T_CODE; j++)
+ *ptr++ = vpath_info->fifo_stats.txd_t_code_err_cnt[j];
+ }
+
+ *ptr++ = 0;
+ for (k = 0; k < vdev->no_of_vpath; k++) {
+ struct vxge_hw_vpath_stats_hw_info *vpath_info;
+ vpath = &vdev->vpaths[k];
+ j = vpath->device_id;
+ vpath_info = hw_stats->vpath_info[j];
+ if (!vpath_info) {
+ memset(ptr, 0, VXGE_HW_VPATH_STATS_LEN * sizeof(u64));
+ ptr += VXGE_HW_VPATH_STATS_LEN;
+ continue;
+ }
+ *ptr++ = vpath_info->ini_num_mwr_sent;
+ *ptr++ = vpath_info->ini_num_mrd_sent;
+ *ptr++ = vpath_info->ini_num_cpl_rcvd;
+ *ptr++ = vpath_info->ini_num_mwr_byte_sent;
+ *ptr++ = vpath_info->ini_num_cpl_byte_rcvd;
+ *ptr++ = vpath_info->wrcrdtarb_xoff;
+ *ptr++ = vpath_info->rdcrdtarb_xoff;
+ *ptr++ = vpath_info->vpath_genstats_count0;
+ *ptr++ = vpath_info->vpath_genstats_count1;
+ *ptr++ = vpath_info->vpath_genstats_count2;
+ *ptr++ = vpath_info->vpath_genstats_count3;
+ *ptr++ = vpath_info->vpath_genstats_count4;
+ *ptr++ = vpath_info->vpath_genstats_count5;
+ *ptr++ = vpath_info->prog_event_vnum0;
+ *ptr++ = vpath_info->prog_event_vnum1;
+ *ptr++ = vpath_info->prog_event_vnum2;
+ *ptr++ = vpath_info->prog_event_vnum3;
+ *ptr++ = vpath_info->rx_multi_cast_frame_discard;
+ *ptr++ = vpath_info->rx_frm_transferred;
+ *ptr++ = vpath_info->rxd_returned;
+ *ptr++ = vpath_info->rx_mpa_len_fail_frms;
+ *ptr++ = vpath_info->rx_mpa_mrk_fail_frms;
+ *ptr++ = vpath_info->rx_mpa_crc_fail_frms;
+ *ptr++ = vpath_info->rx_permitted_frms;
+ *ptr++ = vpath_info->rx_vp_reset_discarded_frms;
+ *ptr++ = vpath_info->rx_wol_frms;
+ *ptr++ = vpath_info->tx_vp_reset_discarded_frms;
+ }
+
+ *ptr++ = 0;
+ *ptr++ = vdev->stats.vpaths_open;
+ *ptr++ = vdev->stats.vpath_open_fail;
+ *ptr++ = vdev->stats.link_up;
+ *ptr++ = vdev->stats.link_down;
+
+ for (k = 0; k < vdev->no_of_vpath; k++) {
+ *ptr += vdev->vpaths[k].fifo.stats.tx_frms;
+ *(ptr + 1) += vdev->vpaths[k].fifo.stats.tx_errors;
+ *(ptr + 2) += vdev->vpaths[k].fifo.stats.tx_bytes;
+ *(ptr + 3) += vdev->vpaths[k].fifo.stats.txd_not_free;
+ *(ptr + 4) += vdev->vpaths[k].fifo.stats.txd_out_of_desc;
+ *(ptr + 5) += vdev->vpaths[k].ring.stats.rx_frms;
+ *(ptr + 6) += vdev->vpaths[k].ring.stats.rx_errors;
+ *(ptr + 7) += vdev->vpaths[k].ring.stats.rx_bytes;
+ *(ptr + 8) += vdev->vpaths[k].ring.stats.rx_mcast;
+ *(ptr + 9) += vdev->vpaths[k].fifo.stats.pci_map_fail +
+ vdev->vpaths[k].ring.stats.pci_map_fail;
+ *(ptr + 10) += vdev->vpaths[k].ring.stats.skb_alloc_fail;
+ }
+
+ ptr += 12;
+
+ kfree(xmac_stats);
+ kfree(sw_stats);
+ kfree(hw_stats);
+}
+
+static void vxge_ethtool_get_strings(struct net_device *dev,
+ u32 stringset, u8 *data)
+{
+ int stat_size = 0;
+ int i, j;
+ struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ switch (stringset) {
+ case ETH_SS_STATS:
+ vxge_add_string("VPATH STATISTICS%s\t\t\t",
+ &stat_size, data, "");
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_add_string("tx_ttl_eth_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_ttl_eth_octects_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_data_octects_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_mcast_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_bcast_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_ucast_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_tagged_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_vld_ip_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_vld_ip_octects_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_icmp_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_tcp_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_rst_tcp_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_udp_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_unknown_proto_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_lost_ip_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_parse_error_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_tcp_offload_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_retx_tcp_offload_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_lost_ip_offload_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_eth_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_vld_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_offload_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_eth_octects_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_data_octects_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_offload_octects_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_vld_mcast_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_vld_bcast_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_accepted_ucast_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_accepted_nucast_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_tagged_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_long_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_usized_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_osized_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_frag_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_jabber_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_64_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_65_127_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_128_255_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_256_511_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_512_1023_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_1024_1518_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_1519_4095_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_4096_8191_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_8192_max_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_gt_max_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ip%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_accepted_ip_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ip_octects_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_err_ip_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_icmp_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_tcp_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_udp_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_err_tcp_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_lost_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_lost_ip_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_lost_ip_offload_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_various_discard_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_sleep_discard_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_red_discard_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_queue_full_discard_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_mpa_ok_frms_%d\t\t\t",
+ &stat_size, data, i);
+ }
+
+ vxge_add_string("\nAGGR STATISTICS%s\t\t\t\t",
+ &stat_size, data, "");
+ for (i = 0; i < vdev->max_config_port; i++) {
+ vxge_add_string("tx_frms_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_data_octects_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_mcast_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_bcast_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_discarded_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_errored_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_frms_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_data_octects_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_mcast_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_bcast_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_discarded_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_errored_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_unknown_slow_proto_frms_%d\t",
+ &stat_size, data, i);
+ }
+
+ vxge_add_string("\nPORT STATISTICS%s\t\t\t\t",
+ &stat_size, data, "");
+ for (i = 0; i < vdev->max_config_port; i++) {
+ vxge_add_string("tx_ttl_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_ttl_octects_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_data_octects_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_mcast_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_bcast_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_ucast_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_tagged_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_vld_ip_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_vld_ip_octects_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_icmp_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_tcp_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_rst_tcp_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_udp_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_parse_error_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_unknown_protocol_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_pause_ctrl_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_marker_pdu_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_lacpdu_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_drop_ip_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_marker_resp_pdu_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_xgmii_char2_match_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_xgmii_char1_match_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_xgmii_column2_match_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_xgmii_column1_match_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_any_err_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_drop_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_vld_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_offload_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_octects_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_data_octects_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_offload_octects_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_vld_mcast_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_vld_bcast_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_accepted_ucast_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_accepted_nucast_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_tagged_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_long_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_usized_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_osized_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_frag_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_jabber_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_64_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_65_127_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_128_255_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_256_511_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_512_1023_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_1024_1518_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_1519_4095_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_4096_8191_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_8192_max_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ttl_gt_max_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ip_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_accepted_ip_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_ip_octets_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_err_ip_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_icmp_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_tcp_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_udp_%d\t\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_err_tcp_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_pause_count_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_pause_ctrl_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_unsup_ctrl_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_fcs_err_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_in_rng_len_err_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_out_rng_len_err_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_drop_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_discard_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_drop_ip_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_drop_udp_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_marker_pdu_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_lacpdu_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_unknown_pdu_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_marker_resp_pdu_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_fcs_discard_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_illegal_pdu_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_switch_discard_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_len_discard_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_rpa_discard_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_l2_mgmt_discard_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_rts_discard_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_trash_discard_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_buff_full_discard_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_red_discard_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_xgmii_ctrl_err_cnt_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_xgmii_data_err_cnt_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_xgmii_char1_match_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_xgmii_err_sym_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_xgmii_column1_match_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_xgmii_char2_match_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_local_fault_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_xgmii_column2_match_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_jettison_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_remote_fault_%d\t\t\t",
+ &stat_size, data, i);
+ }
+
+ vxge_add_string("\n SOFTWARE STATISTICS%s\t\t\t",
+ &stat_size, data, "");
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_add_string("soft_reset_cnt_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("unknown_alarms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("network_sustained_fault_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("network_sustained_ok_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("kdfcctl_fifo0_overwrite_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("kdfcctl_fifo0_poison_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("kdfcctl_fifo0_dma_error_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("dblgen_fifo0_overflow_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("statsb_pif_chain_error_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("statsb_drop_timeout_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("target_illegal_access_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("ini_serr_det_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("prc_ring_bumps_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("prc_rxdcm_sc_err_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("prc_rxdcm_sc_abort_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("prc_quanta_size_err_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("ring_full_cnt_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("ring_usage_cnt_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("ring_usage_max_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("ring_reserve_free_swaps_cnt_%d\t",
+ &stat_size, data, i);
+ vxge_add_string("ring_total_compl_cnt_%d\t\t",
+ &stat_size, data, i);
+ for (j = 0; j < VXGE_HW_DTR_MAX_T_CODE; j++)
+ vxge_add_string("rxd_t_code_err_cnt%d_%d\t\t",
+ &stat_size, data, j, i);
+ vxge_add_string("fifo_full_cnt_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("fifo_usage_cnt_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("fifo_usage_max_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("fifo_reserve_free_swaps_cnt_%d\t",
+ &stat_size, data, i);
+ vxge_add_string("fifo_total_compl_cnt_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("fifo_total_posts_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("fifo_total_buffers_%d\t\t",
+ &stat_size, data, i);
+ for (j = 0; j < VXGE_HW_DTR_MAX_T_CODE; j++)
+ vxge_add_string("txd_t_code_err_cnt%d_%d\t\t",
+ &stat_size, data, j, i);
+ }
+
+ vxge_add_string("\n HARDWARE STATISTICS%s\t\t\t",
+ &stat_size, data, "");
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_add_string("ini_num_mwr_sent_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("ini_num_mrd_sent_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("ini_num_cpl_rcvd_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("ini_num_mwr_byte_sent_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("ini_num_cpl_byte_rcvd_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("wrcrdtarb_xoff_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rdcrdtarb_xoff_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("vpath_genstats_count0_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("vpath_genstats_count1_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("vpath_genstats_count2_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("vpath_genstats_count3_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("vpath_genstats_count4_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("vpath_genstats_count5_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("prog_event_vnum0_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("prog_event_vnum1_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("prog_event_vnum2_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("prog_event_vnum3_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_multi_cast_frame_discard_%d\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_frm_transferred_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rxd_returned_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_mpa_len_fail_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_mpa_mrk_fail_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_mpa_crc_fail_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_permitted_frms_%d\t\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_vp_reset_discarded_frms_%d\t",
+ &stat_size, data, i);
+ vxge_add_string("rx_wol_frms_%d\t\t\t",
+ &stat_size, data, i);
+ vxge_add_string("tx_vp_reset_discarded_frms_%d\t",
+ &stat_size, data, i);
+ }
+
+ memcpy(data + stat_size, &ethtool_driver_stats_keys,
+ sizeof(ethtool_driver_stats_keys));
+ }
+}
+
+static int vxge_ethtool_get_regs_len(struct net_device *dev)
+{
+ struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+
+ return sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath;
+}
+
+static u32 vxge_get_rx_csum(struct net_device *dev)
+{
+ struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+
+ return vdev->rx_csum;
+}
+
+static int vxge_set_rx_csum(struct net_device *dev, u32 data)
+{
+ struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+
+ if (data)
+ vdev->rx_csum = 1;
+ else
+ vdev->rx_csum = 0;
+
+ return 0;
+}
+
+static int vxge_ethtool_op_set_tso(struct net_device *dev, u32 data)
+{
+ if (data)
+ dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
+ else
+ dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+
+ return 0;
+}
+
+static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset)
+{
+ struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+
+ switch (sset) {
+ case ETH_SS_STATS:
+ return VXGE_TITLE_LEN +
+ (vdev->no_of_vpath * VXGE_HW_VPATH_STATS_LEN) +
+ (vdev->max_config_port * VXGE_HW_AGGR_STATS_LEN) +
+ (vdev->max_config_port * VXGE_HW_PORT_STATS_LEN) +
+ (vdev->no_of_vpath * VXGE_HW_VPATH_TX_STATS_LEN) +
+ (vdev->no_of_vpath * VXGE_HW_VPATH_RX_STATS_LEN) +
+ (vdev->no_of_vpath * VXGE_SW_STATS_LEN) +
+ DRIVER_STAT_LEN;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static const struct ethtool_ops vxge_ethtool_ops = {
+ .get_settings = vxge_ethtool_gset,
+ .set_settings = vxge_ethtool_sset,
+ .get_drvinfo = vxge_ethtool_gdrvinfo,
+ .get_regs_len = vxge_ethtool_get_regs_len,
+ .get_regs = vxge_ethtool_gregs,
+ .get_link = ethtool_op_get_link,
+ .get_pauseparam = vxge_ethtool_getpause_data,
+ .set_pauseparam = vxge_ethtool_setpause_data,
+ .get_rx_csum = vxge_get_rx_csum,
+ .set_rx_csum = vxge_set_rx_csum,
+ .get_tx_csum = ethtool_op_get_tx_csum,
+ .set_tx_csum = ethtool_op_set_tx_hw_csum,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+ .get_tso = ethtool_op_get_tso,
+ .set_tso = vxge_ethtool_op_set_tso,
+ .get_strings = vxge_ethtool_get_strings,
+ .phys_id = vxge_ethtool_idnic,
+ .get_sset_count = vxge_ethtool_get_sset_count,
+ .get_ethtool_stats = vxge_get_ethtool_stats,
+};
+
+void initialize_ethtool_ops(struct net_device *ndev)
+{
+ SET_ETHTOOL_OPS(ndev, &vxge_ethtool_ops);
+}
diff --git a/drivers/net/vxge/vxge-ethtool.h b/drivers/net/vxge/vxge-ethtool.h
new file mode 100644
index 000000000000..1c3df0a34acc
--- /dev/null
+++ b/drivers/net/vxge/vxge-ethtool.h
@@ -0,0 +1,67 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice. This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-ethtool.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#ifndef _VXGE_ETHTOOL_H
+#define _VXGE_ETHTOOL_H
+
+#include "vxge-main.h"
+
+/* Ethtool related variables and Macros. */
+static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset);
+
+static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
+ {"\n DRIVER STATISTICS"},
+ {"vpaths_opened"},
+ {"vpath_open_fail_cnt"},
+ {"link_up_cnt"},
+ {"link_down_cnt"},
+ {"tx_frms"},
+ {"tx_errors"},
+ {"tx_bytes"},
+ {"txd_not_free"},
+ {"txd_out_of_desc"},
+ {"rx_frms"},
+ {"rx_errors"},
+ {"rx_bytes"},
+ {"rx_mcast"},
+ {"pci_map_fail_cnt"},
+ {"skb_alloc_fail_cnt"}
+};
+
+#define VXGE_TITLE_LEN 5
+#define VXGE_HW_VPATH_STATS_LEN 27
+#define VXGE_HW_AGGR_STATS_LEN 13
+#define VXGE_HW_PORT_STATS_LEN 94
+#define VXGE_HW_VPATH_TX_STATS_LEN 19
+#define VXGE_HW_VPATH_RX_STATS_LEN 42
+#define VXGE_SW_STATS_LEN 60
+#define VXGE_HW_STATS_LEN (VXGE_HW_VPATH_STATS_LEN +\
+ VXGE_HW_AGGR_STATS_LEN +\
+ VXGE_HW_PORT_STATS_LEN +\
+ VXGE_HW_VPATH_TX_STATS_LEN +\
+ VXGE_HW_VPATH_RX_STATS_LEN)
+
+#define DRIVER_STAT_LEN (sizeof(ethtool_driver_stats_keys)/ETH_GSTRING_LEN)
+#define STAT_LEN (VXGE_HW_STATS_LEN + DRIVER_STAT_LEN + VXGE_SW_STATS_LEN)
+
+/* Maximum flicker time of adapter LED */
+#define VXGE_MAX_FLICKER_TIME (60 * HZ) /* 60 seconds */
+#define VXGE_FLICKER_ON 1
+#define VXGE_FLICKER_OFF 0
+
+#define vxge_add_string(fmt, size, buf, ...) {\
+ snprintf(buf + *size, ETH_GSTRING_LEN, fmt, __VA_ARGS__); \
+ *size += ETH_GSTRING_LEN; \
+}
+
+#endif /*_VXGE_ETHTOOL_H*/
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
new file mode 100644
index 000000000000..61ef16118157
--- /dev/null
+++ b/drivers/net/vxge/vxge-main.c
@@ -0,0 +1,4502 @@
+/******************************************************************************
+* This software may be used and distributed according to the terms of
+* the GNU General Public License (GPL), incorporated herein by reference.
+* Drivers based on or derived from this code fall under the GPL and must
+* retain the authorship, copyright and license notice. This file is not
+* a complete program and may only be used when the entire operating
+* system is licensed under the GPL.
+* See the file COPYING in this distribution for more information.
+*
+* vxge-main.c: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+* Virtualized Server Adapter.
+* Copyright(c) 2002-2009 Neterion Inc.
+*
+* The module loadable parameters that are supported by the driver and a brief
+* explanation of all the variables:
+* vlan_tag_strip:
+* Strip VLAN Tag enable/disable. Instructs the device to remove
+* the VLAN tag from all received tagged frames that are not
+* replicated at the internal L2 switch.
+* 0 - Do not strip the VLAN tag.
+* 1 - Strip the VLAN tag.
+*
+* addr_learn_en:
+* Enable learning the mac address of the guest OS interface in
+* a virtualization environment.
+* 0 - DISABLE
+* 1 - ENABLE
+*
+* max_config_port:
+* Maximum number of port to be supported.
+* MIN -1 and MAX - 2
+*
+* max_config_vpath:
+* This configures the maximum no of VPATH configures for each
+* device function.
+* MIN - 1 and MAX - 17
+*
+* max_config_dev:
+* This configures maximum no of Device function to be enabled.
+* MIN - 1 and MAX - 17
+*
+******************************************************************************/
+
+#include <linux/if_vlan.h>
+#include <linux/pci.h>
+#include <net/ip.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include "vxge-main.h"
+#include "vxge-reg.h"
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION("Neterion's X3100 Series 10GbE PCIe I/O"
+ "Virtualized Server Adapter");
+
+static struct pci_device_id vxge_id_table[] __devinitdata = {
+ {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_TITAN_WIN, PCI_ANY_ID,
+ PCI_ANY_ID},
+ {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_TITAN_UNI, PCI_ANY_ID,
+ PCI_ANY_ID},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, vxge_id_table);
+
+VXGE_MODULE_PARAM_INT(vlan_tag_strip, VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE);
+VXGE_MODULE_PARAM_INT(addr_learn_en, VXGE_HW_MAC_ADDR_LEARN_DEFAULT);
+VXGE_MODULE_PARAM_INT(max_config_port, VXGE_MAX_CONFIG_PORT);
+VXGE_MODULE_PARAM_INT(max_config_vpath, VXGE_USE_DEFAULT);
+VXGE_MODULE_PARAM_INT(max_mac_vpath, VXGE_MAX_MAC_ADDR_COUNT);
+VXGE_MODULE_PARAM_INT(max_config_dev, VXGE_MAX_CONFIG_DEV);
+
+static u16 vpath_selector[VXGE_HW_MAX_VIRTUAL_PATHS] =
+ {0, 1, 3, 3, 7, 7, 7, 7, 15, 15, 15, 15, 15, 15, 15, 15, 31};
+static unsigned int bw_percentage[VXGE_HW_MAX_VIRTUAL_PATHS] =
+ {[0 ...(VXGE_HW_MAX_VIRTUAL_PATHS - 1)] = 0xFF};
+module_param_array(bw_percentage, uint, NULL, 0);
+
+static struct vxge_drv_config *driver_config;
+
+static inline int is_vxge_card_up(struct vxgedev *vdev)
+{
+ return test_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+}
+
+static inline void VXGE_COMPLETE_VPATH_TX(struct vxge_fifo *fifo)
+{
+ unsigned long flags = 0;
+ struct sk_buff *skb_ptr = NULL;
+ struct sk_buff **temp, *head, *skb;
+
+ if (spin_trylock_irqsave(&fifo->tx_lock, flags)) {
+ vxge_hw_vpath_poll_tx(fifo->handle, (void **)&skb_ptr);
+ spin_unlock_irqrestore(&fifo->tx_lock, flags);
+ }
+ /* free SKBs */
+ head = skb_ptr;
+ while (head) {
+ skb = head;
+ temp = (struct sk_buff **)&skb->cb;
+ head = *temp;
+ *temp = NULL;
+ dev_kfree_skb_irq(skb);
+ }
+}
+
+static inline void VXGE_COMPLETE_ALL_TX(struct vxgedev *vdev)
+{
+ int i;
+
+ /* Complete all transmits */
+ for (i = 0; i < vdev->no_of_vpath; i++)
+ VXGE_COMPLETE_VPATH_TX(&vdev->vpaths[i].fifo);
+}
+
+static inline void VXGE_COMPLETE_ALL_RX(struct vxgedev *vdev)
+{
+ int i;
+ struct vxge_ring *ring;
+
+ /* Complete all receives*/
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ ring = &vdev->vpaths[i].ring;
+ vxge_hw_vpath_poll_rx(ring->handle);
+ }
+}
+
+/*
+ * MultiQ manipulation helper functions
+ */
+void vxge_stop_all_tx_queue(struct vxgedev *vdev)
+{
+ int i;
+ struct net_device *dev = vdev->ndev;
+
+ if (vdev->config.tx_steering_type != TX_MULTIQ_STEERING) {
+ for (i = 0; i < vdev->no_of_vpath; i++)
+ vdev->vpaths[i].fifo.queue_state = VPATH_QUEUE_STOP;
+ }
+ netif_tx_stop_all_queues(dev);
+}
+
+void vxge_stop_tx_queue(struct vxge_fifo *fifo)
+{
+ struct net_device *dev = fifo->ndev;
+
+ struct netdev_queue *txq = NULL;
+ if (fifo->tx_steering_type == TX_MULTIQ_STEERING)
+ txq = netdev_get_tx_queue(dev, fifo->driver_id);
+ else {
+ txq = netdev_get_tx_queue(dev, 0);
+ fifo->queue_state = VPATH_QUEUE_STOP;
+ }
+
+ netif_tx_stop_queue(txq);
+}
+
+void vxge_start_all_tx_queue(struct vxgedev *vdev)
+{
+ int i;
+ struct net_device *dev = vdev->ndev;
+
+ if (vdev->config.tx_steering_type != TX_MULTIQ_STEERING) {
+ for (i = 0; i < vdev->no_of_vpath; i++)
+ vdev->vpaths[i].fifo.queue_state = VPATH_QUEUE_START;
+ }
+ netif_tx_start_all_queues(dev);
+}
+
+static void vxge_wake_all_tx_queue(struct vxgedev *vdev)
+{
+ int i;
+ struct net_device *dev = vdev->ndev;
+
+ if (vdev->config.tx_steering_type != TX_MULTIQ_STEERING) {
+ for (i = 0; i < vdev->no_of_vpath; i++)
+ vdev->vpaths[i].fifo.queue_state = VPATH_QUEUE_START;
+ }
+ netif_tx_wake_all_queues(dev);
+}
+
+void vxge_wake_tx_queue(struct vxge_fifo *fifo, struct sk_buff *skb)
+{
+ struct net_device *dev = fifo->ndev;
+
+ int vpath_no = fifo->driver_id;
+ struct netdev_queue *txq = NULL;
+ if (fifo->tx_steering_type == TX_MULTIQ_STEERING) {
+ txq = netdev_get_tx_queue(dev, vpath_no);
+ if (netif_tx_queue_stopped(txq))
+ netif_tx_wake_queue(txq);
+ } else {
+ txq = netdev_get_tx_queue(dev, 0);
+ if (fifo->queue_state == VPATH_QUEUE_STOP)
+ if (netif_tx_queue_stopped(txq)) {
+ fifo->queue_state = VPATH_QUEUE_START;
+ netif_tx_wake_queue(txq);
+ }
+ }
+}
+
+/*
+ * vxge_callback_link_up
+ *
+ * This function is called during interrupt context to notify link up state
+ * change.
+ */
+void
+vxge_callback_link_up(struct __vxge_hw_device *hldev)
+{
+ struct net_device *dev = hldev->ndev;
+ struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+ vdev->ndev->name, __func__, __LINE__);
+ printk(KERN_NOTICE "%s: Link Up\n", vdev->ndev->name);
+ vdev->stats.link_up++;
+
+ netif_carrier_on(vdev->ndev);
+ vxge_wake_all_tx_queue(vdev);
+
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s: %s:%d Exiting...", vdev->ndev->name, __func__, __LINE__);
+}
+
+/*
+ * vxge_callback_link_down
+ *
+ * This function is called during interrupt context to notify link down state
+ * change.
+ */
+void
+vxge_callback_link_down(struct __vxge_hw_device *hldev)
+{
+ struct net_device *dev = hldev->ndev;
+ struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s: %s:%d", vdev->ndev->name, __func__, __LINE__);
+ printk(KERN_NOTICE "%s: Link Down\n", vdev->ndev->name);
+
+ vdev->stats.link_down++;
+ netif_carrier_off(vdev->ndev);
+ vxge_stop_all_tx_queue(vdev);
+
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s: %s:%d Exiting...", vdev->ndev->name, __func__, __LINE__);
+}
+
+/*
+ * vxge_rx_alloc
+ *
+ * Allocate SKB.
+ */
+static struct sk_buff*
+vxge_rx_alloc(void *dtrh, struct vxge_ring *ring, const int skb_size)
+{
+ struct net_device *dev;
+ struct sk_buff *skb;
+ struct vxge_rx_priv *rx_priv;
+
+ dev = ring->ndev;
+ vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+ ring->ndev->name, __func__, __LINE__);
+
+ rx_priv = vxge_hw_ring_rxd_private_get(dtrh);
+
+ /* try to allocate skb first. this one may fail */
+ skb = netdev_alloc_skb(dev, skb_size +
+ VXGE_HW_HEADER_ETHERNET_II_802_3_ALIGN);
+ if (skb == NULL) {
+ vxge_debug_mem(VXGE_ERR,
+ "%s: out of memory to allocate SKB", dev->name);
+ ring->stats.skb_alloc_fail++;
+ return NULL;
+ }
+
+ vxge_debug_mem(VXGE_TRACE,
+ "%s: %s:%d Skb : 0x%p", ring->ndev->name,
+ __func__, __LINE__, skb);
+
+ skb_reserve(skb, VXGE_HW_HEADER_ETHERNET_II_802_3_ALIGN);
+
+ rx_priv->skb = skb;
+ rx_priv->data_size = skb_size;
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__);
+
+ return skb;
+}
+
+/*
+ * vxge_rx_map
+ */
+static int vxge_rx_map(void *dtrh, struct vxge_ring *ring)
+{
+ struct vxge_rx_priv *rx_priv;
+ dma_addr_t dma_addr;
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+ ring->ndev->name, __func__, __LINE__);
+ rx_priv = vxge_hw_ring_rxd_private_get(dtrh);
+
+ dma_addr = pci_map_single(ring->pdev, rx_priv->skb->data,
+ rx_priv->data_size, PCI_DMA_FROMDEVICE);
+
+ if (dma_addr == 0) {
+ ring->stats.pci_map_fail++;
+ return -EIO;
+ }
+ vxge_debug_mem(VXGE_TRACE,
+ "%s: %s:%d 1 buffer mode dma_addr = 0x%llx",
+ ring->ndev->name, __func__, __LINE__,
+ (unsigned long long)dma_addr);
+ vxge_hw_ring_rxd_1b_set(dtrh, dma_addr, rx_priv->data_size);
+
+ rx_priv->data_dma = dma_addr;
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__);
+
+ return 0;
+}
+
+/*
+ * vxge_rx_initial_replenish
+ * Allocation of RxD as an initial replenish procedure.
+ */
+static enum vxge_hw_status
+vxge_rx_initial_replenish(void *dtrh, void *userdata)
+{
+ struct vxge_ring *ring = (struct vxge_ring *)userdata;
+ struct vxge_rx_priv *rx_priv;
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+ ring->ndev->name, __func__, __LINE__);
+ if (vxge_rx_alloc(dtrh, ring,
+ VXGE_LL_MAX_FRAME_SIZE(ring->ndev)) == NULL)
+ return VXGE_HW_FAIL;
+
+ if (vxge_rx_map(dtrh, ring)) {
+ rx_priv = vxge_hw_ring_rxd_private_get(dtrh);
+ dev_kfree_skb(rx_priv->skb);
+
+ return VXGE_HW_FAIL;
+ }
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__);
+
+ return VXGE_HW_OK;
+}
+
+static inline void
+vxge_rx_complete(struct vxge_ring *ring, struct sk_buff *skb, u16 vlan,
+ int pkt_length, struct vxge_hw_ring_rxd_info *ext_info)
+{
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+ ring->ndev->name, __func__, __LINE__);
+ skb_record_rx_queue(skb, ring->driver_id);
+ skb->protocol = eth_type_trans(skb, ring->ndev);
+
+ ring->stats.rx_frms++;
+ ring->stats.rx_bytes += pkt_length;
+
+ if (skb->pkt_type == PACKET_MULTICAST)
+ ring->stats.rx_mcast++;
+
+ vxge_debug_rx(VXGE_TRACE,
+ "%s: %s:%d skb protocol = %d",
+ ring->ndev->name, __func__, __LINE__, skb->protocol);
+
+ if (ring->gro_enable) {
+ if (ring->vlgrp && ext_info->vlan &&
+ (ring->vlan_tag_strip ==
+ VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
+ vlan_gro_receive(&ring->napi, ring->vlgrp,
+ ext_info->vlan, skb);
+ else
+ napi_gro_receive(&ring->napi, skb);
+ } else {
+ if (ring->vlgrp && vlan &&
+ (ring->vlan_tag_strip ==
+ VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
+ vlan_hwaccel_receive_skb(skb, ring->vlgrp, vlan);
+ else
+ netif_receive_skb(skb);
+ }
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__);
+}
+
+static inline void vxge_re_pre_post(void *dtr, struct vxge_ring *ring,
+ struct vxge_rx_priv *rx_priv)
+{
+ pci_dma_sync_single_for_device(ring->pdev,
+ rx_priv->data_dma, rx_priv->data_size, PCI_DMA_FROMDEVICE);
+
+ vxge_hw_ring_rxd_1b_set(dtr, rx_priv->data_dma, rx_priv->data_size);
+ vxge_hw_ring_rxd_pre_post(ring->handle, dtr);
+}
+
+static inline void vxge_post(int *dtr_cnt, void **first_dtr,
+ void *post_dtr, struct __vxge_hw_ring *ringh)
+{
+ int dtr_count = *dtr_cnt;
+ if ((*dtr_cnt % VXGE_HW_RXSYNC_FREQ_CNT) == 0) {
+ if (*first_dtr)
+ vxge_hw_ring_rxd_post_post_wmb(ringh, *first_dtr);
+ *first_dtr = post_dtr;
+ } else
+ vxge_hw_ring_rxd_post_post(ringh, post_dtr);
+ dtr_count++;
+ *dtr_cnt = dtr_count;
+}
+
+/*
+ * vxge_rx_1b_compl
+ *
+ * If the interrupt is because of a received frame or if the receive ring
+ * contains fresh as yet un-processed frames, this function is called.
+ */
+enum vxge_hw_status
+vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
+ u8 t_code, void *userdata)
+{
+ struct vxge_ring *ring = (struct vxge_ring *)userdata;
+ struct net_device *dev = ring->ndev;
+ unsigned int dma_sizes;
+ void *first_dtr = NULL;
+ int dtr_cnt = 0;
+ int data_size;
+ dma_addr_t data_dma;
+ int pkt_length;
+ struct sk_buff *skb;
+ struct vxge_rx_priv *rx_priv;
+ struct vxge_hw_ring_rxd_info ext_info;
+ vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+ ring->ndev->name, __func__, __LINE__);
+ ring->pkts_processed = 0;
+
+ vxge_hw_ring_replenish(ringh, 0);
+
+ do {
+ rx_priv = vxge_hw_ring_rxd_private_get(dtr);
+ skb = rx_priv->skb;
+ data_size = rx_priv->data_size;
+ data_dma = rx_priv->data_dma;
+
+ vxge_debug_rx(VXGE_TRACE,
+ "%s: %s:%d skb = 0x%p",
+ ring->ndev->name, __func__, __LINE__, skb);
+
+ vxge_hw_ring_rxd_1b_get(ringh, dtr, &dma_sizes);
+ pkt_length = dma_sizes;
+
+ vxge_debug_rx(VXGE_TRACE,
+ "%s: %s:%d Packet Length = %d",
+ ring->ndev->name, __func__, __LINE__, pkt_length);
+
+ vxge_hw_ring_rxd_1b_info_get(ringh, dtr, &ext_info);
+
+ /* check skb validity */
+ vxge_assert(skb);
+
+ prefetch((char *)skb + L1_CACHE_BYTES);
+ if (unlikely(t_code)) {
+
+ if (vxge_hw_ring_handle_tcode(ringh, dtr, t_code) !=
+ VXGE_HW_OK) {
+
+ ring->stats.rx_errors++;
+ vxge_debug_rx(VXGE_TRACE,
+ "%s: %s :%d Rx T_code is %d",
+ ring->ndev->name, __func__,
+ __LINE__, t_code);
+
+ /* If the t_code is not supported and if the
+ * t_code is other than 0x5 (unparseable packet
+ * such as unknown UPV6 header), Drop it !!!
+ */
+ vxge_re_pre_post(dtr, ring, rx_priv);
+
+ vxge_post(&dtr_cnt, &first_dtr, dtr, ringh);
+ ring->stats.rx_dropped++;
+ continue;
+ }
+ }
+
+ if (pkt_length > VXGE_LL_RX_COPY_THRESHOLD) {
+
+ if (vxge_rx_alloc(dtr, ring, data_size) != NULL) {
+
+ if (!vxge_rx_map(dtr, ring)) {
+ skb_put(skb, pkt_length);
+
+ pci_unmap_single(ring->pdev, data_dma,
+ data_size, PCI_DMA_FROMDEVICE);
+
+ vxge_hw_ring_rxd_pre_post(ringh, dtr);
+ vxge_post(&dtr_cnt, &first_dtr, dtr,
+ ringh);
+ } else {
+ dev_kfree_skb(rx_priv->skb);
+ rx_priv->skb = skb;
+ rx_priv->data_size = data_size;
+ vxge_re_pre_post(dtr, ring, rx_priv);
+
+ vxge_post(&dtr_cnt, &first_dtr, dtr,
+ ringh);
+ ring->stats.rx_dropped++;
+ break;
+ }
+ } else {
+ vxge_re_pre_post(dtr, ring, rx_priv);
+
+ vxge_post(&dtr_cnt, &first_dtr, dtr, ringh);
+ ring->stats.rx_dropped++;
+ break;
+ }
+ } else {
+ struct sk_buff *skb_up;
+
+ skb_up = netdev_alloc_skb(dev, pkt_length +
+ VXGE_HW_HEADER_ETHERNET_II_802_3_ALIGN);
+ if (skb_up != NULL) {
+ skb_reserve(skb_up,
+ VXGE_HW_HEADER_ETHERNET_II_802_3_ALIGN);
+
+ pci_dma_sync_single_for_cpu(ring->pdev,
+ data_dma, data_size,
+ PCI_DMA_FROMDEVICE);
+
+ vxge_debug_mem(VXGE_TRACE,
+ "%s: %s:%d skb_up = %p",
+ ring->ndev->name, __func__,
+ __LINE__, skb);
+ memcpy(skb_up->data, skb->data, pkt_length);
+
+ vxge_re_pre_post(dtr, ring, rx_priv);
+
+ vxge_post(&dtr_cnt, &first_dtr, dtr,
+ ringh);
+ /* will netif_rx small SKB instead */
+ skb = skb_up;
+ skb_put(skb, pkt_length);
+ } else {
+ vxge_re_pre_post(dtr, ring, rx_priv);
+
+ vxge_post(&dtr_cnt, &first_dtr, dtr, ringh);
+ vxge_debug_rx(VXGE_ERR,
+ "%s: vxge_rx_1b_compl: out of "
+ "memory", dev->name);
+ ring->stats.skb_alloc_fail++;
+ break;
+ }
+ }
+
+ if ((ext_info.proto & VXGE_HW_FRAME_PROTO_TCP_OR_UDP) &&
+ !(ext_info.proto & VXGE_HW_FRAME_PROTO_IP_FRAG) &&
+ ring->rx_csum && /* Offload Rx side CSUM */
+ ext_info.l3_cksum == VXGE_HW_L3_CKSUM_OK &&
+ ext_info.l4_cksum == VXGE_HW_L4_CKSUM_OK)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ else
+ skb->ip_summed = CHECKSUM_NONE;
+
+ vxge_rx_complete(ring, skb, ext_info.vlan,
+ pkt_length, &ext_info);
+
+ ring->budget--;
+ ring->pkts_processed++;
+ if (!ring->budget)
+ break;
+
+ } while (vxge_hw_ring_rxd_next_completed(ringh, &dtr,
+ &t_code) == VXGE_HW_OK);
+
+ if (first_dtr)
+ vxge_hw_ring_rxd_post_post_wmb(ringh, first_dtr);
+
+ dev->last_rx = jiffies;
+
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s:%d Exiting...",
+ __func__, __LINE__);
+ return VXGE_HW_OK;
+}
+
+/*
+ * vxge_xmit_compl
+ *
+ * If an interrupt was raised to indicate DMA complete of the Tx packet,
+ * this function is called. It identifies the last TxD whose buffer was
+ * freed and frees all skbs whose data have already DMA'ed into the NICs
+ * internal memory.
+ */
+enum vxge_hw_status
+vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
+ enum vxge_hw_fifo_tcode t_code, void *userdata,
+ void **skb_ptr)
+{
+ struct vxge_fifo *fifo = (struct vxge_fifo *)userdata;
+ struct sk_buff *skb, *head = NULL;
+ struct sk_buff **temp;
+ int pkt_cnt = 0;
+
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s:%d Entered....", __func__, __LINE__);
+
+ do {
+ int frg_cnt;
+ skb_frag_t *frag;
+ int i = 0, j;
+ struct vxge_tx_priv *txd_priv =
+ vxge_hw_fifo_txdl_private_get(dtr);
+
+ skb = txd_priv->skb;
+ frg_cnt = skb_shinfo(skb)->nr_frags;
+ frag = &skb_shinfo(skb)->frags[0];
+
+ vxge_debug_tx(VXGE_TRACE,
+ "%s: %s:%d fifo_hw = %p dtr = %p "
+ "tcode = 0x%x", fifo->ndev->name, __func__,
+ __LINE__, fifo_hw, dtr, t_code);
+ /* check skb validity */
+ vxge_assert(skb);
+ vxge_debug_tx(VXGE_TRACE,
+ "%s: %s:%d skb = %p itxd_priv = %p frg_cnt = %d",
+ fifo->ndev->name, __func__, __LINE__,
+ skb, txd_priv, frg_cnt);
+ if (unlikely(t_code)) {
+ fifo->stats.tx_errors++;
+ vxge_debug_tx(VXGE_ERR,
+ "%s: tx: dtr %p completed due to "
+ "error t_code %01x", fifo->ndev->name,
+ dtr, t_code);
+ vxge_hw_fifo_handle_tcode(fifo_hw, dtr, t_code);
+ }
+
+ /* for unfragmented skb */
+ pci_unmap_single(fifo->pdev, txd_priv->dma_buffers[i++],
+ skb_headlen(skb), PCI_DMA_TODEVICE);
+
+ for (j = 0; j < frg_cnt; j++) {
+ pci_unmap_page(fifo->pdev,
+ txd_priv->dma_buffers[i++],
+ frag->size, PCI_DMA_TODEVICE);
+ frag += 1;
+ }
+
+ vxge_hw_fifo_txdl_free(fifo_hw, dtr);
+
+ /* Updating the statistics block */
+ fifo->stats.tx_frms++;
+ fifo->stats.tx_bytes += skb->len;
+
+ temp = (struct sk_buff **)&skb->cb;
+ *temp = head;
+ head = skb;
+
+ pkt_cnt++;
+ if (pkt_cnt > fifo->indicate_max_pkts)
+ break;
+
+ } while (vxge_hw_fifo_txdl_next_completed(fifo_hw,
+ &dtr, &t_code) == VXGE_HW_OK);
+
+ vxge_wake_tx_queue(fifo, skb);
+
+ if (skb_ptr)
+ *skb_ptr = (void *) head;
+
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s: %s:%d Exiting...",
+ fifo->ndev->name, __func__, __LINE__);
+ return VXGE_HW_OK;
+}
+
+/* select a vpath to trasmit the packet */
+static u32 vxge_get_vpath_no(struct vxgedev *vdev, struct sk_buff *skb,
+ int *do_lock)
+{
+ u16 queue_len, counter = 0;
+ if (skb->protocol == htons(ETH_P_IP)) {
+ struct iphdr *ip;
+ struct tcphdr *th;
+
+ ip = ip_hdr(skb);
+
+ if ((ip->frag_off & htons(IP_OFFSET|IP_MF)) == 0) {
+ th = (struct tcphdr *)(((unsigned char *)ip) +
+ ip->ihl*4);
+
+ queue_len = vdev->no_of_vpath;
+ counter = (ntohs(th->source) +
+ ntohs(th->dest)) &
+ vdev->vpath_selector[queue_len - 1];
+ if (counter >= queue_len)
+ counter = queue_len - 1;
+
+ if (ip->protocol == IPPROTO_UDP) {
+#ifdef NETIF_F_LLTX
+ *do_lock = 0;
+#endif
+ }
+ }
+ }
+ return counter;
+}
+
+static enum vxge_hw_status vxge_search_mac_addr_in_list(
+ struct vxge_vpath *vpath, u64 del_mac)
+{
+ struct list_head *entry, *next;
+ list_for_each_safe(entry, next, &vpath->mac_addr_list) {
+ if (((struct vxge_mac_addrs *)entry)->macaddr == del_mac)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static int vxge_learn_mac(struct vxgedev *vdev, u8 *mac_header)
+{
+ struct macInfo mac_info;
+ u8 *mac_address = NULL;
+ u64 mac_addr = 0, vpath_vector = 0;
+ int vpath_idx = 0;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_vpath *vpath = NULL;
+ struct __vxge_hw_device *hldev;
+
+ hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev);
+
+ mac_address = (u8 *)&mac_addr;
+ memcpy(mac_address, mac_header, ETH_ALEN);
+
+ /* Is this mac address already in the list? */
+ for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++) {
+ vpath = &vdev->vpaths[vpath_idx];
+ if (vxge_search_mac_addr_in_list(vpath, mac_addr))
+ return vpath_idx;
+ }
+
+ memset(&mac_info, 0, sizeof(struct macInfo));
+ memcpy(mac_info.macaddr, mac_header, ETH_ALEN);
+
+ /* Any vpath has room to add mac address to its da table? */
+ for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++) {
+ vpath = &vdev->vpaths[vpath_idx];
+ if (vpath->mac_addr_cnt < vpath->max_mac_addr_cnt) {
+ /* Add this mac address to this vpath */
+ mac_info.vpath_no = vpath_idx;
+ mac_info.state = VXGE_LL_MAC_ADDR_IN_DA_TABLE;
+ status = vxge_add_mac_addr(vdev, &mac_info);
+ if (status != VXGE_HW_OK)
+ return -EPERM;
+ return vpath_idx;
+ }
+ }
+
+ mac_info.state = VXGE_LL_MAC_ADDR_IN_LIST;
+ vpath_idx = 0;
+ mac_info.vpath_no = vpath_idx;
+ /* Is the first vpath already selected as catch-basin ? */
+ vpath = &vdev->vpaths[vpath_idx];
+ if (vpath->mac_addr_cnt > vpath->max_mac_addr_cnt) {
+ /* Add this mac address to this vpath */
+ if (FALSE == vxge_mac_list_add(vpath, &mac_info))
+ return -EPERM;
+ return vpath_idx;
+ }
+
+ /* Select first vpath as catch-basin */
+ vpath_vector = vxge_mBIT(vpath->device_id);
+ status = vxge_hw_mgmt_reg_write(vpath->vdev->devh,
+ vxge_hw_mgmt_reg_type_mrpcim,
+ 0,
+ (ulong)offsetof(
+ struct vxge_hw_mrpcim_reg,
+ rts_mgr_cbasin_cfg),
+ vpath_vector);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_tx(VXGE_ERR,
+ "%s: Unable to set the vpath-%d in catch-basin mode",
+ VXGE_DRIVER_NAME, vpath->device_id);
+ return -EPERM;
+ }
+
+ if (FALSE == vxge_mac_list_add(vpath, &mac_info))
+ return -EPERM;
+
+ return vpath_idx;
+}
+
+/**
+ * vxge_xmit
+ * @skb : the socket buffer containing the Tx data.
+ * @dev : device pointer.
+ *
+ * This function is the Tx entry point of the driver. Neterion NIC supports
+ * certain protocol assist features on Tx side, namely CSO, S/G, LSO.
+ * NOTE: when device cant queue the pkt, just the trans_start variable will
+ * not be upadted.
+*/
+static int
+vxge_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct vxge_fifo *fifo = NULL;
+ void *dtr_priv;
+ void *dtr = NULL;
+ struct vxgedev *vdev = NULL;
+ enum vxge_hw_status status;
+ int frg_cnt, first_frg_len;
+ skb_frag_t *frag;
+ int i = 0, j = 0, avail;
+ u64 dma_pointer;
+ struct vxge_tx_priv *txdl_priv = NULL;
+ struct __vxge_hw_fifo *fifo_hw;
+ u32 max_mss = 0x0;
+ int offload_type;
+ unsigned long flags = 0;
+ int vpath_no = 0;
+ int do_spin_tx_lock = 1;
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+ dev->name, __func__, __LINE__);
+
+ /* A buffer with no data will be dropped */
+ if (unlikely(skb->len <= 0)) {
+ vxge_debug_tx(VXGE_ERR,
+ "%s: Buffer has no data..", dev->name);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ vdev = (struct vxgedev *)netdev_priv(dev);
+
+ if (unlikely(!is_vxge_card_up(vdev))) {
+ vxge_debug_tx(VXGE_ERR,
+ "%s: vdev not initialized", dev->name);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ if (vdev->config.addr_learn_en) {
+ vpath_no = vxge_learn_mac(vdev, skb->data + ETH_ALEN);
+ if (vpath_no == -EPERM) {
+ vxge_debug_tx(VXGE_ERR,
+ "%s: Failed to store the mac address",
+ dev->name);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+ }
+
+ if (vdev->config.tx_steering_type == TX_MULTIQ_STEERING)
+ vpath_no = skb_get_queue_mapping(skb);
+ else if (vdev->config.tx_steering_type == TX_PORT_STEERING)
+ vpath_no = vxge_get_vpath_no(vdev, skb, &do_spin_tx_lock);
+
+ vxge_debug_tx(VXGE_TRACE, "%s: vpath_no= %d", dev->name, vpath_no);
+
+ if (vpath_no >= vdev->no_of_vpath)
+ vpath_no = 0;
+
+ fifo = &vdev->vpaths[vpath_no].fifo;
+ fifo_hw = fifo->handle;
+
+ if (do_spin_tx_lock)
+ spin_lock_irqsave(&fifo->tx_lock, flags);
+ else {
+ if (unlikely(!spin_trylock_irqsave(&fifo->tx_lock, flags)))
+ return NETDEV_TX_LOCKED;
+ }
+
+ if (vdev->config.tx_steering_type == TX_MULTIQ_STEERING) {
+ if (netif_subqueue_stopped(dev, skb)) {
+ spin_unlock_irqrestore(&fifo->tx_lock, flags);
+ return NETDEV_TX_BUSY;
+ }
+ } else if (unlikely(fifo->queue_state == VPATH_QUEUE_STOP)) {
+ if (netif_queue_stopped(dev)) {
+ spin_unlock_irqrestore(&fifo->tx_lock, flags);
+ return NETDEV_TX_BUSY;
+ }
+ }
+ avail = vxge_hw_fifo_free_txdl_count_get(fifo_hw);
+ if (avail == 0) {
+ vxge_debug_tx(VXGE_ERR,
+ "%s: No free TXDs available", dev->name);
+ fifo->stats.txd_not_free++;
+ vxge_stop_tx_queue(fifo);
+ goto _exit2;
+ }
+
+ status = vxge_hw_fifo_txdl_reserve(fifo_hw, &dtr, &dtr_priv);
+ if (unlikely(status != VXGE_HW_OK)) {
+ vxge_debug_tx(VXGE_ERR,
+ "%s: Out of descriptors .", dev->name);
+ fifo->stats.txd_out_of_desc++;
+ vxge_stop_tx_queue(fifo);
+ goto _exit2;
+ }
+
+ vxge_debug_tx(VXGE_TRACE,
+ "%s: %s:%d fifo_hw = %p dtr = %p dtr_priv = %p",
+ dev->name, __func__, __LINE__,
+ fifo_hw, dtr, dtr_priv);
+
+ if (vdev->vlgrp && vlan_tx_tag_present(skb)) {
+ u16 vlan_tag = vlan_tx_tag_get(skb);
+ vxge_hw_fifo_txdl_vlan_set(dtr, vlan_tag);
+ }
+
+ first_frg_len = skb_headlen(skb);
+
+ dma_pointer = pci_map_single(fifo->pdev, skb->data, first_frg_len,
+ PCI_DMA_TODEVICE);
+
+ if (unlikely(pci_dma_mapping_error(fifo->pdev, dma_pointer))) {
+ vxge_hw_fifo_txdl_free(fifo_hw, dtr);
+ vxge_stop_tx_queue(fifo);
+ fifo->stats.pci_map_fail++;
+ goto _exit2;
+ }
+
+ txdl_priv = vxge_hw_fifo_txdl_private_get(dtr);
+ txdl_priv->skb = skb;
+ txdl_priv->dma_buffers[j] = dma_pointer;
+
+ frg_cnt = skb_shinfo(skb)->nr_frags;
+ vxge_debug_tx(VXGE_TRACE,
+ "%s: %s:%d skb = %p txdl_priv = %p "
+ "frag_cnt = %d dma_pointer = 0x%llx", dev->name,
+ __func__, __LINE__, skb, txdl_priv,
+ frg_cnt, (unsigned long long)dma_pointer);
+
+ vxge_hw_fifo_txdl_buffer_set(fifo_hw, dtr, j++, dma_pointer,
+ first_frg_len);
+
+ frag = &skb_shinfo(skb)->frags[0];
+ for (i = 0; i < frg_cnt; i++) {
+ /* ignore 0 length fragment */
+ if (!frag->size)
+ continue;
+
+ dma_pointer =
+ (u64)pci_map_page(fifo->pdev, frag->page,
+ frag->page_offset, frag->size,
+ PCI_DMA_TODEVICE);
+
+ if (unlikely(pci_dma_mapping_error(fifo->pdev, dma_pointer)))
+ goto _exit0;
+ vxge_debug_tx(VXGE_TRACE,
+ "%s: %s:%d frag = %d dma_pointer = 0x%llx",
+ dev->name, __func__, __LINE__, i,
+ (unsigned long long)dma_pointer);
+
+ txdl_priv->dma_buffers[j] = dma_pointer;
+ vxge_hw_fifo_txdl_buffer_set(fifo_hw, dtr, j++, dma_pointer,
+ frag->size);
+ frag += 1;
+ }
+
+ offload_type = vxge_offload_type(skb);
+
+ if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
+
+ int mss = vxge_tcp_mss(skb);
+ if (mss) {
+ max_mss = dev->mtu + ETH_HLEN -
+ VXGE_HW_TCPIP_HEADER_MAX_SIZE;
+ if (mss > max_mss)
+ mss = max_mss;
+ vxge_debug_tx(VXGE_TRACE,
+ "%s: %s:%d mss = %d",
+ dev->name, __func__, __LINE__, mss);
+ vxge_hw_fifo_txdl_mss_set(dtr, mss);
+ } else {
+ vxge_assert(skb->len <=
+ dev->mtu + VXGE_HW_MAC_HEADER_MAX_SIZE);
+ vxge_assert(0);
+ goto _exit1;
+ }
+ }
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ vxge_hw_fifo_txdl_cksum_set_bits(dtr,
+ VXGE_HW_FIFO_TXD_TX_CKO_IPV4_EN |
+ VXGE_HW_FIFO_TXD_TX_CKO_TCP_EN |
+ VXGE_HW_FIFO_TXD_TX_CKO_UDP_EN);
+
+ vxge_hw_fifo_txdl_post(fifo_hw, dtr);
+ dev->trans_start = jiffies;
+ spin_unlock_irqrestore(&fifo->tx_lock, flags);
+
+ VXGE_COMPLETE_VPATH_TX(fifo);
+ vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d Exiting...",
+ dev->name, __func__, __LINE__);
+ return 0;
+
+_exit0:
+ vxge_debug_tx(VXGE_TRACE, "%s: pci_map_page failed", dev->name);
+
+_exit1:
+ j = 0;
+ frag = &skb_shinfo(skb)->frags[0];
+
+ pci_unmap_single(fifo->pdev, txdl_priv->dma_buffers[j++],
+ skb_headlen(skb), PCI_DMA_TODEVICE);
+
+ for (; j < i; j++) {
+ pci_unmap_page(fifo->pdev, txdl_priv->dma_buffers[j],
+ frag->size, PCI_DMA_TODEVICE);
+ frag += 1;
+ }
+
+ vxge_hw_fifo_txdl_free(fifo_hw, dtr);
+_exit2:
+ dev_kfree_skb(skb);
+ spin_unlock_irqrestore(&fifo->tx_lock, flags);
+ VXGE_COMPLETE_VPATH_TX(fifo);
+
+ return 0;
+}
+
+/*
+ * vxge_rx_term
+ *
+ * Function will be called by hw function to abort all outstanding receive
+ * descriptors.
+ */
+static void
+vxge_rx_term(void *dtrh, enum vxge_hw_rxd_state state, void *userdata)
+{
+ struct vxge_ring *ring = (struct vxge_ring *)userdata;
+ struct vxge_rx_priv *rx_priv =
+ vxge_hw_ring_rxd_private_get(dtrh);
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+ ring->ndev->name, __func__, __LINE__);
+ if (state != VXGE_HW_RXD_STATE_POSTED)
+ return;
+
+ pci_unmap_single(ring->pdev, rx_priv->data_dma,
+ rx_priv->data_size, PCI_DMA_FROMDEVICE);
+
+ dev_kfree_skb(rx_priv->skb);
+
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s: %s:%d Exiting...",
+ ring->ndev->name, __func__, __LINE__);
+}
+
+/*
+ * vxge_tx_term
+ *
+ * Function will be called to abort all outstanding tx descriptors
+ */
+static void
+vxge_tx_term(void *dtrh, enum vxge_hw_txdl_state state, void *userdata)
+{
+ struct vxge_fifo *fifo = (struct vxge_fifo *)userdata;
+ skb_frag_t *frag;
+ int i = 0, j, frg_cnt;
+ struct vxge_tx_priv *txd_priv = vxge_hw_fifo_txdl_private_get(dtrh);
+ struct sk_buff *skb = txd_priv->skb;
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+ if (state != VXGE_HW_TXDL_STATE_POSTED)
+ return;
+
+ /* check skb validity */
+ vxge_assert(skb);
+ frg_cnt = skb_shinfo(skb)->nr_frags;
+ frag = &skb_shinfo(skb)->frags[0];
+
+ /* for unfragmented skb */
+ pci_unmap_single(fifo->pdev, txd_priv->dma_buffers[i++],
+ skb_headlen(skb), PCI_DMA_TODEVICE);
+
+ for (j = 0; j < frg_cnt; j++) {
+ pci_unmap_page(fifo->pdev, txd_priv->dma_buffers[i++],
+ frag->size, PCI_DMA_TODEVICE);
+ frag += 1;
+ }
+
+ dev_kfree_skb(skb);
+
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s:%d Exiting...", __func__, __LINE__);
+}
+
+/**
+ * vxge_set_multicast
+ * @dev: pointer to the device structure
+ *
+ * Entry point for multicast address enable/disable
+ * This function is a driver entry point which gets called by the kernel
+ * whenever multicast addresses must be enabled/disabled. This also gets
+ * called to set/reset promiscuous mode. Depending on the deivce flag, we
+ * determine, if multicast address must be enabled or if promiscuous mode
+ * is to be disabled etc.
+ */
+static void vxge_set_multicast(struct net_device *dev)
+{
+ struct dev_mc_list *mclist;
+ struct vxgedev *vdev;
+ int i, mcast_cnt = 0;
+ struct __vxge_hw_device *hldev;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct macInfo mac_info;
+ int vpath_idx = 0;
+ struct vxge_mac_addrs *mac_entry;
+ struct list_head *list_head;
+ struct list_head *entry, *next;
+ u8 *mac_address = NULL;
+
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s:%d", __func__, __LINE__);
+
+ vdev = (struct vxgedev *)netdev_priv(dev);
+ hldev = (struct __vxge_hw_device *)vdev->devh;
+
+ if (unlikely(!is_vxge_card_up(vdev)))
+ return;
+
+ if ((dev->flags & IFF_ALLMULTI) && (!vdev->all_multi_flg)) {
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_assert(vdev->vpaths[i].is_open);
+ status = vxge_hw_vpath_mcast_enable(
+ vdev->vpaths[i].handle);
+ vdev->all_multi_flg = 1;
+ }
+ } else if ((dev->flags & IFF_ALLMULTI) && (vdev->all_multi_flg)) {
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_assert(vdev->vpaths[i].is_open);
+ status = vxge_hw_vpath_mcast_disable(
+ vdev->vpaths[i].handle);
+ vdev->all_multi_flg = 1;
+ }
+ }
+
+ if (status != VXGE_HW_OK)
+ vxge_debug_init(VXGE_ERR,
+ "failed to %s multicast, status %d",
+ dev->flags & IFF_ALLMULTI ?
+ "enable" : "disable", status);
+
+ if (!vdev->config.addr_learn_en) {
+ if (dev->flags & IFF_PROMISC) {
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_assert(vdev->vpaths[i].is_open);
+ status = vxge_hw_vpath_promisc_enable(
+ vdev->vpaths[i].handle);
+ }
+ } else {
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_assert(vdev->vpaths[i].is_open);
+ status = vxge_hw_vpath_promisc_disable(
+ vdev->vpaths[i].handle);
+ }
+ }
+ }
+
+ memset(&mac_info, 0, sizeof(struct macInfo));
+ /* Update individual M_CAST address list */
+ if ((!vdev->all_multi_flg) && dev->mc_count) {
+
+ mcast_cnt = vdev->vpaths[0].mcast_addr_cnt;
+ list_head = &vdev->vpaths[0].mac_addr_list;
+ if ((dev->mc_count +
+ (vdev->vpaths[0].mac_addr_cnt - mcast_cnt)) >
+ vdev->vpaths[0].max_mac_addr_cnt)
+ goto _set_all_mcast;
+
+ /* Delete previous MC's */
+ for (i = 0; i < mcast_cnt; i++) {
+ if (!list_empty(list_head))
+ mac_entry = (struct vxge_mac_addrs *)
+ list_first_entry(list_head,
+ struct vxge_mac_addrs,
+ item);
+
+ list_for_each_safe(entry, next, list_head) {
+
+ mac_entry = (struct vxge_mac_addrs *) entry;
+ /* Copy the mac address to delete */
+ mac_address = (u8 *)&mac_entry->macaddr;
+ memcpy(mac_info.macaddr, mac_address, ETH_ALEN);
+
+ /* Is this a multicast address */
+ if (0x01 & mac_info.macaddr[0]) {
+ for (vpath_idx = 0; vpath_idx <
+ vdev->no_of_vpath;
+ vpath_idx++) {
+ mac_info.vpath_no = vpath_idx;
+ status = vxge_del_mac_addr(
+ vdev,
+ &mac_info);
+ }
+ }
+ }
+ }
+
+ /* Add new ones */
+ for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
+ i++, mclist = mclist->next) {
+
+ memcpy(mac_info.macaddr, mclist->dmi_addr, ETH_ALEN);
+ for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath;
+ vpath_idx++) {
+ mac_info.vpath_no = vpath_idx;
+ mac_info.state = VXGE_LL_MAC_ADDR_IN_DA_TABLE;
+ status = vxge_add_mac_addr(vdev, &mac_info);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "%s:%d Setting individual"
+ "multicast address failed",
+ __func__, __LINE__);
+ goto _set_all_mcast;
+ }
+ }
+ }
+
+ return;
+_set_all_mcast:
+ mcast_cnt = vdev->vpaths[0].mcast_addr_cnt;
+ /* Delete previous MC's */
+ for (i = 0; i < mcast_cnt; i++) {
+
+ list_for_each_safe(entry, next, list_head) {
+
+ mac_entry = (struct vxge_mac_addrs *) entry;
+ /* Copy the mac address to delete */
+ mac_address = (u8 *)&mac_entry->macaddr;
+ memcpy(mac_info.macaddr, mac_address, ETH_ALEN);
+
+ /* Is this a multicast address */
+ if (0x01 & mac_info.macaddr[0])
+ break;
+ }
+
+ for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath;
+ vpath_idx++) {
+ mac_info.vpath_no = vpath_idx;
+ status = vxge_del_mac_addr(vdev, &mac_info);
+ }
+ }
+
+ /* Enable all multicast */
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_assert(vdev->vpaths[i].is_open);
+ status = vxge_hw_vpath_mcast_enable(
+ vdev->vpaths[i].handle);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "%s:%d Enabling all multicasts failed",
+ __func__, __LINE__);
+ }
+ vdev->all_multi_flg = 1;
+ }
+ dev->flags |= IFF_ALLMULTI;
+ }
+
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s:%d Exiting...", __func__, __LINE__);
+}
+
+/**
+ * vxge_set_mac_addr
+ * @dev: pointer to the device structure
+ *
+ * Update entry "0" (default MAC addr)
+ */
+static int vxge_set_mac_addr(struct net_device *dev, void *p)
+{
+ struct sockaddr *addr = p;
+ struct vxgedev *vdev;
+ struct __vxge_hw_device *hldev;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct macInfo mac_info_new, mac_info_old;
+ int vpath_idx = 0;
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+ vdev = (struct vxgedev *)netdev_priv(dev);
+ hldev = vdev->devh;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EINVAL;
+
+ memset(&mac_info_new, 0, sizeof(struct macInfo));
+ memset(&mac_info_old, 0, sizeof(struct macInfo));
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s:%d Exiting...",
+ __func__, __LINE__);
+
+ /* Get the old address */
+ memcpy(mac_info_old.macaddr, dev->dev_addr, dev->addr_len);
+
+ /* Copy the new address */
+ memcpy(mac_info_new.macaddr, addr->sa_data, dev->addr_len);
+
+ /* First delete the old mac address from all the vpaths
+ as we can't specify the index while adding new mac address */
+ for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++) {
+ struct vxge_vpath *vpath = &vdev->vpaths[vpath_idx];
+ if (!vpath->is_open) {
+ /* This can happen when this interface is added/removed
+ to the bonding interface. Delete this station address
+ from the linked list */
+ vxge_mac_list_del(vpath, &mac_info_old);
+
+ /* Add this new address to the linked list
+ for later restoring */
+ vxge_mac_list_add(vpath, &mac_info_new);
+
+ continue;
+ }
+ /* Delete the station address */
+ mac_info_old.vpath_no = vpath_idx;
+ status = vxge_del_mac_addr(vdev, &mac_info_old);
+ }
+
+ if (unlikely(!is_vxge_card_up(vdev))) {
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ return VXGE_HW_OK;
+ }
+
+ /* Set this mac address to all the vpaths */
+ for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++) {
+ mac_info_new.vpath_no = vpath_idx;
+ mac_info_new.state = VXGE_LL_MAC_ADDR_IN_DA_TABLE;
+ status = vxge_add_mac_addr(vdev, &mac_info_new);
+ if (status != VXGE_HW_OK)
+ return -EINVAL;
+ }
+
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+ return status;
+}
+
+/*
+ * vxge_vpath_intr_enable
+ * @vdev: pointer to vdev
+ * @vp_id: vpath for which to enable the interrupts
+ *
+ * Enables the interrupts for the vpath
+*/
+void vxge_vpath_intr_enable(struct vxgedev *vdev, int vp_id)
+{
+ struct vxge_vpath *vpath = &vdev->vpaths[vp_id];
+ int msix_id, alarm_msix_id;
+ int tim_msix_id[4] = {[0 ...3] = 0};
+
+ vxge_hw_vpath_intr_enable(vpath->handle);
+
+ if (vdev->config.intr_type == INTA)
+ vxge_hw_vpath_inta_unmask_tx_rx(vpath->handle);
+ else {
+ msix_id = vp_id * VXGE_HW_VPATH_MSIX_ACTIVE;
+ alarm_msix_id =
+ VXGE_HW_VPATH_MSIX_ACTIVE * vdev->no_of_vpath - 2;
+
+ tim_msix_id[0] = msix_id;
+ tim_msix_id[1] = msix_id + 1;
+ vxge_hw_vpath_msix_set(vpath->handle, tim_msix_id,
+ alarm_msix_id);
+
+ vxge_hw_vpath_msix_unmask(vpath->handle, msix_id);
+ vxge_hw_vpath_msix_unmask(vpath->handle, msix_id + 1);
+
+ /* enable the alarm vector */
+ vxge_hw_vpath_msix_unmask(vpath->handle, alarm_msix_id);
+ }
+}
+
+/*
+ * vxge_vpath_intr_disable
+ * @vdev: pointer to vdev
+ * @vp_id: vpath for which to disable the interrupts
+ *
+ * Disables the interrupts for the vpath
+*/
+void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id)
+{
+ struct vxge_vpath *vpath = &vdev->vpaths[vp_id];
+ int msix_id;
+
+ vxge_hw_vpath_intr_disable(vpath->handle);
+
+ if (vdev->config.intr_type == INTA)
+ vxge_hw_vpath_inta_mask_tx_rx(vpath->handle);
+ else {
+ msix_id = vp_id * VXGE_HW_VPATH_MSIX_ACTIVE;
+ vxge_hw_vpath_msix_mask(vpath->handle, msix_id);
+ vxge_hw_vpath_msix_mask(vpath->handle, msix_id + 1);
+
+ /* disable the alarm vector */
+ msix_id = VXGE_HW_VPATH_MSIX_ACTIVE * vdev->no_of_vpath - 2;
+ vxge_hw_vpath_msix_mask(vpath->handle, msix_id);
+ }
+}
+
+/*
+ * vxge_reset_vpath
+ * @vdev: pointer to vdev
+ * @vp_id: vpath to reset
+ *
+ * Resets the vpath
+*/
+static int vxge_reset_vpath(struct vxgedev *vdev, int vp_id)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ int ret = 0;
+
+ /* check if device is down already */
+ if (unlikely(!is_vxge_card_up(vdev)))
+ return 0;
+
+ /* is device reset already scheduled */
+ if (test_bit(__VXGE_STATE_RESET_CARD, &vdev->state))
+ return 0;
+
+ if (vdev->vpaths[vp_id].handle) {
+ if (vxge_hw_vpath_reset(vdev->vpaths[vp_id].handle)
+ == VXGE_HW_OK) {
+ if (is_vxge_card_up(vdev) &&
+ vxge_hw_vpath_recover_from_reset(
+ vdev->vpaths[vp_id].handle)
+ != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "vxge_hw_vpath_recover_from_reset"
+ "failed for vpath:%d", vp_id);
+ return status;
+ }
+ } else {
+ vxge_debug_init(VXGE_ERR,
+ "vxge_hw_vpath_reset failed for"
+ "vpath:%d", vp_id);
+ return status;
+ }
+ } else
+ return VXGE_HW_FAIL;
+
+ vxge_restore_vpath_mac_addr(&vdev->vpaths[vp_id]);
+ vxge_restore_vpath_vid_table(&vdev->vpaths[vp_id]);
+
+ /* Enable all broadcast */
+ vxge_hw_vpath_bcast_enable(vdev->vpaths[vp_id].handle);
+
+ /* Enable the interrupts */
+ vxge_vpath_intr_enable(vdev, vp_id);
+
+ smp_wmb();
+
+ /* Enable the flow of traffic through the vpath */
+ vxge_hw_vpath_enable(vdev->vpaths[vp_id].handle);
+
+ smp_wmb();
+ vxge_hw_vpath_rx_doorbell_init(vdev->vpaths[vp_id].handle);
+ vdev->vpaths[vp_id].ring.last_status = VXGE_HW_OK;
+
+ /* Vpath reset done */
+ clear_bit(vp_id, &vdev->vp_reset);
+
+ /* Start the vpath queue */
+ vxge_wake_tx_queue(&vdev->vpaths[vp_id].fifo, NULL);
+
+ return ret;
+}
+
+static int do_vxge_reset(struct vxgedev *vdev, int event)
+{
+ enum vxge_hw_status status;
+ int ret = 0, vp_id, i;
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+ if ((event == VXGE_LL_FULL_RESET) || (event == VXGE_LL_START_RESET)) {
+ /* check if device is down already */
+ if (unlikely(!is_vxge_card_up(vdev)))
+ return 0;
+
+ /* is reset already scheduled */
+ if (test_and_set_bit(__VXGE_STATE_RESET_CARD, &vdev->state))
+ return 0;
+ }
+
+ if (event == VXGE_LL_FULL_RESET) {
+ /* wait for all the vpath reset to complete */
+ for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) {
+ while (test_bit(vp_id, &vdev->vp_reset))
+ msleep(50);
+ }
+
+ /* if execution mode is set to debug, don't reset the adapter */
+ if (unlikely(vdev->exec_mode)) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: execution mode is debug, returning..",
+ vdev->ndev->name);
+ clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+ vxge_stop_all_tx_queue(vdev);
+ return 0;
+ }
+ }
+
+ if (event == VXGE_LL_FULL_RESET) {
+ vxge_hw_device_intr_disable(vdev->devh);
+
+ switch (vdev->cric_err_event) {
+ case VXGE_HW_EVENT_UNKNOWN:
+ vxge_stop_all_tx_queue(vdev);
+ vxge_debug_init(VXGE_ERR,
+ "fatal: %s: Disabling device due to"
+ "unknown error",
+ vdev->ndev->name);
+ ret = -EPERM;
+ goto out;
+ case VXGE_HW_EVENT_RESET_START:
+ break;
+ case VXGE_HW_EVENT_RESET_COMPLETE:
+ case VXGE_HW_EVENT_LINK_DOWN:
+ case VXGE_HW_EVENT_LINK_UP:
+ case VXGE_HW_EVENT_ALARM_CLEARED:
+ case VXGE_HW_EVENT_ECCERR:
+ case VXGE_HW_EVENT_MRPCIM_ECCERR:
+ ret = -EPERM;
+ goto out;
+ case VXGE_HW_EVENT_FIFO_ERR:
+ case VXGE_HW_EVENT_VPATH_ERR:
+ break;
+ case VXGE_HW_EVENT_CRITICAL_ERR:
+ vxge_stop_all_tx_queue(vdev);
+ vxge_debug_init(VXGE_ERR,
+ "fatal: %s: Disabling device due to"
+ "serious error",
+ vdev->ndev->name);
+ /* SOP or device reset required */
+ /* This event is not currently used */
+ ret = -EPERM;
+ goto out;
+ case VXGE_HW_EVENT_SERR:
+ vxge_stop_all_tx_queue(vdev);
+ vxge_debug_init(VXGE_ERR,
+ "fatal: %s: Disabling device due to"
+ "serious error",
+ vdev->ndev->name);
+ ret = -EPERM;
+ goto out;
+ case VXGE_HW_EVENT_SRPCIM_SERR:
+ case VXGE_HW_EVENT_MRPCIM_SERR:
+ ret = -EPERM;
+ goto out;
+ case VXGE_HW_EVENT_SLOT_FREEZE:
+ vxge_stop_all_tx_queue(vdev);
+ vxge_debug_init(VXGE_ERR,
+ "fatal: %s: Disabling device due to"
+ "slot freeze",
+ vdev->ndev->name);
+ ret = -EPERM;
+ goto out;
+ default:
+ break;
+
+ }
+ }
+
+ if ((event == VXGE_LL_FULL_RESET) || (event == VXGE_LL_START_RESET))
+ vxge_stop_all_tx_queue(vdev);
+
+ if (event == VXGE_LL_FULL_RESET) {
+ status = vxge_reset_all_vpaths(vdev);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "fatal: %s: can not reset vpaths",
+ vdev->ndev->name);
+ ret = -EPERM;
+ goto out;
+ }
+ }
+
+ if (event == VXGE_LL_COMPL_RESET) {
+ for (i = 0; i < vdev->no_of_vpath; i++)
+ if (vdev->vpaths[i].handle) {
+ if (vxge_hw_vpath_recover_from_reset(
+ vdev->vpaths[i].handle)
+ != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "vxge_hw_vpath_recover_"
+ "from_reset failed for vpath: "
+ "%d", i);
+ ret = -EPERM;
+ goto out;
+ }
+ } else {
+ vxge_debug_init(VXGE_ERR,
+ "vxge_hw_vpath_reset failed for "
+ "vpath:%d", i);
+ ret = -EPERM;
+ goto out;
+ }
+ }
+
+ if ((event == VXGE_LL_FULL_RESET) || (event == VXGE_LL_COMPL_RESET)) {
+ /* Reprogram the DA table with populated mac addresses */
+ for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) {
+ vxge_restore_vpath_mac_addr(&vdev->vpaths[vp_id]);
+ vxge_restore_vpath_vid_table(&vdev->vpaths[vp_id]);
+ }
+
+ /* enable vpath interrupts */
+ for (i = 0; i < vdev->no_of_vpath; i++)
+ vxge_vpath_intr_enable(vdev, i);
+
+ vxge_hw_device_intr_enable(vdev->devh);
+
+ smp_wmb();
+
+ /* Indicate card up */
+ set_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+
+ /* Get the traffic to flow through the vpaths */
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_hw_vpath_enable(vdev->vpaths[i].handle);
+ smp_wmb();
+ vxge_hw_vpath_rx_doorbell_init(vdev->vpaths[i].handle);
+ }
+
+ vxge_wake_all_tx_queue(vdev);
+ }
+
+out:
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s:%d Exiting...", __func__, __LINE__);
+
+ /* Indicate reset done */
+ if ((event == VXGE_LL_FULL_RESET) || (event == VXGE_LL_COMPL_RESET))
+ clear_bit(__VXGE_STATE_RESET_CARD, &vdev->state);
+ return ret;
+}
+
+/*
+ * vxge_reset
+ * @vdev: pointer to ll device
+ *
+ * driver may reset the chip on events of serr, eccerr, etc
+ */
+int vxge_reset(struct vxgedev *vdev)
+{
+ do_vxge_reset(vdev, VXGE_LL_FULL_RESET);
+ return 0;
+}
+
+/**
+ * vxge_poll - Receive handler when Receive Polling is used.
+ * @dev: pointer to the device structure.
+ * @budget: Number of packets budgeted to be processed in this iteration.
+ *
+ * This function comes into picture only if Receive side is being handled
+ * through polling (called NAPI in linux). It mostly does what the normal
+ * Rx interrupt handler does in terms of descriptor and packet processing
+ * but not in an interrupt context. Also it will process a specified number
+ * of packets at most in one iteration. This value is passed down by the
+ * kernel as the function argument 'budget'.
+ */
+static int vxge_poll_msix(struct napi_struct *napi, int budget)
+{
+ struct vxge_ring *ring =
+ container_of(napi, struct vxge_ring, napi);
+ int budget_org = budget;
+ ring->budget = budget;
+
+ vxge_hw_vpath_poll_rx(ring->handle);
+
+ if (ring->pkts_processed < budget_org) {
+ napi_complete(napi);
+ /* Re enable the Rx interrupts for the vpath */
+ vxge_hw_channel_msix_unmask(
+ (struct __vxge_hw_channel *)ring->handle,
+ ring->rx_vector_no);
+ }
+
+ return ring->pkts_processed;
+}
+
+static int vxge_poll_inta(struct napi_struct *napi, int budget)
+{
+ struct vxgedev *vdev = container_of(napi, struct vxgedev, napi);
+ int pkts_processed = 0;
+ int i;
+ int budget_org = budget;
+ struct vxge_ring *ring;
+
+ struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)
+ pci_get_drvdata(vdev->pdev);
+
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ ring = &vdev->vpaths[i].ring;
+ ring->budget = budget;
+ vxge_hw_vpath_poll_rx(ring->handle);
+ pkts_processed += ring->pkts_processed;
+ budget -= ring->pkts_processed;
+ if (budget <= 0)
+ break;
+ }
+
+ VXGE_COMPLETE_ALL_TX(vdev);
+
+ if (pkts_processed < budget_org) {
+ napi_complete(napi);
+ /* Re enable the Rx interrupts for the ring */
+ vxge_hw_device_unmask_all(hldev);
+ vxge_hw_device_flush_io(hldev);
+ }
+
+ return pkts_processed;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/**
+ * vxge_netpoll - netpoll event handler entry point
+ * @dev : pointer to the device structure.
+ * Description:
+ * This function will be called by upper layer to check for events on the
+ * interface in situations where interrupts are disabled. It is used for
+ * specific in-kernel networking tasks, such as remote consoles and kernel
+ * debugging over the network (example netdump in RedHat).
+ */
+static void vxge_netpoll(struct net_device *dev)
+{
+ struct __vxge_hw_device *hldev;
+ struct vxgedev *vdev;
+
+ vdev = (struct vxgedev *)netdev_priv(dev);
+ hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+ if (pci_channel_offline(vdev->pdev))
+ return;
+
+ disable_irq(dev->irq);
+ vxge_hw_device_clear_tx_rx(hldev);
+
+ vxge_hw_device_clear_tx_rx(hldev);
+ VXGE_COMPLETE_ALL_RX(vdev);
+ VXGE_COMPLETE_ALL_TX(vdev);
+
+ enable_irq(dev->irq);
+
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s:%d Exiting...", __func__, __LINE__);
+ return;
+}
+#endif
+
+/* RTH configuration */
+static enum vxge_hw_status vxge_rth_configure(struct vxgedev *vdev)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_hw_rth_hash_types hash_types;
+ u8 itable[256] = {0}; /* indirection table */
+ u8 mtable[256] = {0}; /* CPU to vpath mapping */
+ int index;
+
+ /*
+ * Filling
+ * - itable with bucket numbers
+ * - mtable with bucket-to-vpath mapping
+ */
+ for (index = 0; index < (1 << vdev->config.rth_bkt_sz); index++) {
+ itable[index] = index;
+ mtable[index] = index % vdev->no_of_vpath;
+ }
+
+ /* Fill RTH hash types */
+ hash_types.hash_type_tcpipv4_en = vdev->config.rth_hash_type_tcpipv4;
+ hash_types.hash_type_ipv4_en = vdev->config.rth_hash_type_ipv4;
+ hash_types.hash_type_tcpipv6_en = vdev->config.rth_hash_type_tcpipv6;
+ hash_types.hash_type_ipv6_en = vdev->config.rth_hash_type_ipv6;
+ hash_types.hash_type_tcpipv6ex_en =
+ vdev->config.rth_hash_type_tcpipv6ex;
+ hash_types.hash_type_ipv6ex_en = vdev->config.rth_hash_type_ipv6ex;
+
+ /* set indirection table, bucket-to-vpath mapping */
+ status = vxge_hw_vpath_rts_rth_itable_set(vdev->vp_handles,
+ vdev->no_of_vpath,
+ mtable, itable,
+ vdev->config.rth_bkt_sz);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "RTH indirection table configuration failed "
+ "for vpath:%d", vdev->vpaths[0].device_id);
+ return status;
+ }
+
+ /*
+ * Because the itable_set() method uses the active_table field
+ * for the target virtual path the RTH config should be updated
+ * for all VPATHs. The h/w only uses the lowest numbered VPATH
+ * when steering frames.
+ */
+ for (index = 0; index < vdev->no_of_vpath; index++) {
+ status = vxge_hw_vpath_rts_rth_set(
+ vdev->vpaths[index].handle,
+ vdev->config.rth_algorithm,
+ &hash_types,
+ vdev->config.rth_bkt_sz);
+
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "RTH configuration failed for vpath:%d",
+ vdev->vpaths[index].device_id);
+ return status;
+ }
+ }
+
+ return status;
+}
+
+int vxge_mac_list_add(struct vxge_vpath *vpath, struct macInfo *mac)
+{
+ struct vxge_mac_addrs *new_mac_entry;
+ u8 *mac_address = NULL;
+
+ if (vpath->mac_addr_cnt >= VXGE_MAX_LEARN_MAC_ADDR_CNT)
+ return TRUE;
+
+ new_mac_entry = kzalloc(sizeof(struct vxge_mac_addrs), GFP_ATOMIC);
+ if (!new_mac_entry) {
+ vxge_debug_mem(VXGE_ERR,
+ "%s: memory allocation failed",
+ VXGE_DRIVER_NAME);
+ return FALSE;
+ }
+
+ list_add(&new_mac_entry->item, &vpath->mac_addr_list);
+
+ /* Copy the new mac address to the list */
+ mac_address = (u8 *)&new_mac_entry->macaddr;
+ memcpy(mac_address, mac->macaddr, ETH_ALEN);
+
+ new_mac_entry->state = mac->state;
+ vpath->mac_addr_cnt++;
+
+ /* Is this a multicast address */
+ if (0x01 & mac->macaddr[0])
+ vpath->mcast_addr_cnt++;
+
+ return TRUE;
+}
+
+/* Add a mac address to DA table */
+enum vxge_hw_status vxge_add_mac_addr(struct vxgedev *vdev, struct macInfo *mac)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_vpath *vpath;
+ enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode;
+
+ if (0x01 & mac->macaddr[0]) /* multicast address */
+ duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE;
+ else
+ duplicate_mode = VXGE_HW_VPATH_MAC_ADDR_REPLACE_DUPLICATE;
+
+ vpath = &vdev->vpaths[mac->vpath_no];
+ status = vxge_hw_vpath_mac_addr_add(vpath->handle, mac->macaddr,
+ mac->macmask, duplicate_mode);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "DA config add entry failed for vpath:%d",
+ vpath->device_id);
+ } else
+ if (FALSE == vxge_mac_list_add(vpath, mac))
+ status = -EPERM;
+
+ return status;
+}
+
+int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac)
+{
+ struct list_head *entry, *next;
+ u64 del_mac = 0;
+ u8 *mac_address = (u8 *) (&del_mac);
+
+ /* Copy the mac address to delete from the list */
+ memcpy(mac_address, mac->macaddr, ETH_ALEN);
+
+ list_for_each_safe(entry, next, &vpath->mac_addr_list) {
+ if (((struct vxge_mac_addrs *)entry)->macaddr == del_mac) {
+ list_del(entry);
+ kfree((struct vxge_mac_addrs *)entry);
+ vpath->mac_addr_cnt--;
+
+ /* Is this a multicast address */
+ if (0x01 & mac->macaddr[0])
+ vpath->mcast_addr_cnt--;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+/* delete a mac address from DA table */
+enum vxge_hw_status vxge_del_mac_addr(struct vxgedev *vdev, struct macInfo *mac)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_vpath *vpath;
+
+ vpath = &vdev->vpaths[mac->vpath_no];
+ status = vxge_hw_vpath_mac_addr_delete(vpath->handle, mac->macaddr,
+ mac->macmask);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "DA config delete entry failed for vpath:%d",
+ vpath->device_id);
+ } else
+ vxge_mac_list_del(vpath, mac);
+ return status;
+}
+
+/* list all mac addresses from DA table */
+enum vxge_hw_status
+static vxge_search_mac_addr_in_da_table(struct vxge_vpath *vpath,
+ struct macInfo *mac)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ unsigned char macmask[ETH_ALEN];
+ unsigned char macaddr[ETH_ALEN];
+
+ status = vxge_hw_vpath_mac_addr_get(vpath->handle,
+ macaddr, macmask);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "DA config list entry failed for vpath:%d",
+ vpath->device_id);
+ return status;
+ }
+
+ while (memcmp(mac->macaddr, macaddr, ETH_ALEN)) {
+
+ status = vxge_hw_vpath_mac_addr_get_next(vpath->handle,
+ macaddr, macmask);
+ if (status != VXGE_HW_OK)
+ break;
+ }
+
+ return status;
+}
+
+/* Store all vlan ids from the list to the vid table */
+enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxgedev *vdev = vpath->vdev;
+ u16 vid;
+
+ if (vdev->vlgrp && vpath->is_open) {
+
+ for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+ if (!vlan_group_get_device(vdev->vlgrp, vid))
+ continue;
+ /* Add these vlan to the vid table */
+ status = vxge_hw_vpath_vid_add(vpath->handle, vid);
+ }
+ }
+
+ return status;
+}
+
+/* Store all mac addresses from the list to the DA table */
+enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct macInfo mac_info;
+ u8 *mac_address = NULL;
+ struct list_head *entry, *next;
+
+ memset(&mac_info, 0, sizeof(struct macInfo));
+
+ if (vpath->is_open) {
+
+ list_for_each_safe(entry, next, &vpath->mac_addr_list) {
+ mac_address =
+ (u8 *)&
+ ((struct vxge_mac_addrs *)entry)->macaddr;
+ memcpy(mac_info.macaddr, mac_address, ETH_ALEN);
+ ((struct vxge_mac_addrs *)entry)->state =
+ VXGE_LL_MAC_ADDR_IN_DA_TABLE;
+ /* does this mac address already exist in da table? */
+ status = vxge_search_mac_addr_in_da_table(vpath,
+ &mac_info);
+ if (status != VXGE_HW_OK) {
+ /* Add this mac address to the DA table */
+ status = vxge_hw_vpath_mac_addr_add(
+ vpath->handle, mac_info.macaddr,
+ mac_info.macmask,
+ VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "DA add entry failed for vpath:%d",
+ vpath->device_id);
+ ((struct vxge_mac_addrs *)entry)->state
+ = VXGE_LL_MAC_ADDR_IN_LIST;
+ }
+ }
+ }
+ }
+
+ return status;
+}
+
+/* reset vpaths */
+enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev)
+{
+ int i;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ for (i = 0; i < vdev->no_of_vpath; i++)
+ if (vdev->vpaths[i].handle) {
+ if (vxge_hw_vpath_reset(vdev->vpaths[i].handle)
+ == VXGE_HW_OK) {
+ if (is_vxge_card_up(vdev) &&
+ vxge_hw_vpath_recover_from_reset(
+ vdev->vpaths[i].handle)
+ != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "vxge_hw_vpath_recover_"
+ "from_reset failed for vpath: "
+ "%d", i);
+ return status;
+ }
+ } else {
+ vxge_debug_init(VXGE_ERR,
+ "vxge_hw_vpath_reset failed for "
+ "vpath:%d", i);
+ return status;
+ }
+ }
+ return status;
+}
+
+/* close vpaths */
+void vxge_close_vpaths(struct vxgedev *vdev, int index)
+{
+ int i;
+ for (i = index; i < vdev->no_of_vpath; i++) {
+ if (vdev->vpaths[i].handle && vdev->vpaths[i].is_open) {
+ vxge_hw_vpath_close(vdev->vpaths[i].handle);
+ vdev->stats.vpaths_open--;
+ }
+ vdev->vpaths[i].is_open = 0;
+ vdev->vpaths[i].handle = NULL;
+ }
+}
+
+/* open vpaths */
+int vxge_open_vpaths(struct vxgedev *vdev)
+{
+ enum vxge_hw_status status;
+ int i;
+ u32 vp_id = 0;
+ struct vxge_hw_vpath_attr attr;
+
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_assert(vdev->vpaths[i].is_configured);
+ attr.vp_id = vdev->vpaths[i].device_id;
+ attr.fifo_attr.callback = vxge_xmit_compl;
+ attr.fifo_attr.txdl_term = vxge_tx_term;
+ attr.fifo_attr.per_txdl_space = sizeof(struct vxge_tx_priv);
+ attr.fifo_attr.userdata = (void *)&vdev->vpaths[i].fifo;
+
+ attr.ring_attr.callback = vxge_rx_1b_compl;
+ attr.ring_attr.rxd_init = vxge_rx_initial_replenish;
+ attr.ring_attr.rxd_term = vxge_rx_term;
+ attr.ring_attr.per_rxd_space = sizeof(struct vxge_rx_priv);
+ attr.ring_attr.userdata = (void *)&vdev->vpaths[i].ring;
+
+ vdev->vpaths[i].ring.ndev = vdev->ndev;
+ vdev->vpaths[i].ring.pdev = vdev->pdev;
+ status = vxge_hw_vpath_open(vdev->devh, &attr,
+ &(vdev->vpaths[i].handle));
+ if (status == VXGE_HW_OK) {
+ vdev->vpaths[i].fifo.handle =
+ (struct __vxge_hw_fifo *)attr.fifo_attr.userdata;
+ vdev->vpaths[i].ring.handle =
+ (struct __vxge_hw_ring *)attr.ring_attr.userdata;
+ vdev->vpaths[i].fifo.tx_steering_type =
+ vdev->config.tx_steering_type;
+ vdev->vpaths[i].fifo.ndev = vdev->ndev;
+ vdev->vpaths[i].fifo.pdev = vdev->pdev;
+ vdev->vpaths[i].fifo.indicate_max_pkts =
+ vdev->config.fifo_indicate_max_pkts;
+ vdev->vpaths[i].ring.rx_vector_no = 0;
+ vdev->vpaths[i].ring.rx_csum = vdev->rx_csum;
+ vdev->vpaths[i].is_open = 1;
+ vdev->vp_handles[i] = vdev->vpaths[i].handle;
+ vdev->vpaths[i].ring.gro_enable =
+ vdev->config.gro_enable;
+ vdev->vpaths[i].ring.vlan_tag_strip =
+ vdev->vlan_tag_strip;
+ vdev->stats.vpaths_open++;
+ } else {
+ vdev->stats.vpath_open_fail++;
+ vxge_debug_init(VXGE_ERR,
+ "%s: vpath: %d failed to open "
+ "with status: %d",
+ vdev->ndev->name, vdev->vpaths[i].device_id,
+ status);
+ vxge_close_vpaths(vdev, 0);
+ return -EPERM;
+ }
+
+ vp_id =
+ ((struct __vxge_hw_vpath_handle *)vdev->vpaths[i].handle)->
+ vpath->vp_id;
+ vdev->vpaths_deployed |= vxge_mBIT(vp_id);
+ }
+ return VXGE_HW_OK;
+}
+
+/*
+ * vxge_isr_napi
+ * @irq: the irq of the device.
+ * @dev_id: a void pointer to the hldev structure of the Titan device
+ * @ptregs: pointer to the registers pushed on the stack.
+ *
+ * This function is the ISR handler of the device when napi is enabled. It
+ * identifies the reason for the interrupt and calls the relevant service
+ * routines.
+ */
+static irqreturn_t vxge_isr_napi(int irq, void *dev_id)
+{
+ struct __vxge_hw_device *hldev = (struct __vxge_hw_device *)dev_id;
+ struct vxgedev *vdev;
+ struct net_device *dev;
+ u64 reason;
+ enum vxge_hw_status status;
+
+ vxge_debug_intr(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+ dev = hldev->ndev;
+ vdev = netdev_priv(dev);
+
+ if (pci_channel_offline(vdev->pdev))
+ return IRQ_NONE;
+
+ if (unlikely(!is_vxge_card_up(vdev)))
+ return IRQ_NONE;
+
+ status = vxge_hw_device_begin_irq(hldev, vdev->exec_mode,
+ &reason);
+ if (status == VXGE_HW_OK) {
+ vxge_hw_device_mask_all(hldev);
+
+ if (reason &
+ VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_TRAFFIC_INT(
+ vdev->vpaths_deployed >>
+ (64 - VXGE_HW_MAX_VIRTUAL_PATHS))) {
+
+ vxge_hw_device_clear_tx_rx(hldev);
+ napi_schedule(&vdev->napi);
+ vxge_debug_intr(VXGE_TRACE,
+ "%s:%d Exiting...", __func__, __LINE__);
+ return IRQ_HANDLED;
+ } else
+ vxge_hw_device_unmask_all(hldev);
+ } else if (unlikely((status == VXGE_HW_ERR_VPATH) ||
+ (status == VXGE_HW_ERR_CRITICAL) ||
+ (status == VXGE_HW_ERR_FIFO))) {
+ vxge_hw_device_mask_all(hldev);
+ vxge_hw_device_flush_io(hldev);
+ return IRQ_HANDLED;
+ } else if (unlikely(status == VXGE_HW_ERR_SLOT_FREEZE))
+ return IRQ_HANDLED;
+
+ vxge_debug_intr(VXGE_TRACE, "%s:%d Exiting...", __func__, __LINE__);
+ return IRQ_NONE;
+}
+
+#ifdef CONFIG_PCI_MSI
+
+static irqreturn_t
+vxge_tx_msix_handle(int irq, void *dev_id)
+{
+ struct vxge_fifo *fifo = (struct vxge_fifo *)dev_id;
+
+ VXGE_COMPLETE_VPATH_TX(fifo);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t
+vxge_rx_msix_napi_handle(int irq, void *dev_id)
+{
+ struct vxge_ring *ring = (struct vxge_ring *)dev_id;
+
+ /* MSIX_IDX for Rx is 1 */
+ vxge_hw_channel_msix_mask((struct __vxge_hw_channel *)ring->handle,
+ ring->rx_vector_no);
+
+ napi_schedule(&ring->napi);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t
+vxge_alarm_msix_handle(int irq, void *dev_id)
+{
+ int i;
+ enum vxge_hw_status status;
+ struct vxge_vpath *vpath = (struct vxge_vpath *)dev_id;
+ struct vxgedev *vdev = vpath->vdev;
+ int alarm_msix_id =
+ VXGE_HW_VPATH_MSIX_ACTIVE * vdev->no_of_vpath - 2;
+
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_hw_vpath_msix_mask(vdev->vpaths[i].handle,
+ alarm_msix_id);
+
+ status = vxge_hw_vpath_alarm_process(vdev->vpaths[i].handle,
+ vdev->exec_mode);
+ if (status == VXGE_HW_OK) {
+
+ vxge_hw_vpath_msix_unmask(vdev->vpaths[i].handle,
+ alarm_msix_id);
+ continue;
+ }
+ vxge_debug_intr(VXGE_ERR,
+ "%s: vxge_hw_vpath_alarm_process failed %x ",
+ VXGE_DRIVER_NAME, status);
+ }
+ return IRQ_HANDLED;
+}
+
+static int vxge_alloc_msix(struct vxgedev *vdev)
+{
+ int j, i, ret = 0;
+ int intr_cnt = 0;
+ int alarm_msix_id = 0, msix_intr_vect = 0;
+ vdev->intr_cnt = 0;
+
+ /* Tx/Rx MSIX Vectors count */
+ vdev->intr_cnt = vdev->no_of_vpath * 2;
+
+ /* Alarm MSIX Vectors count */
+ vdev->intr_cnt++;
+
+ intr_cnt = (vdev->max_vpath_supported * 2) + 1;
+ vdev->entries = kzalloc(intr_cnt * sizeof(struct msix_entry),
+ GFP_KERNEL);
+ if (!vdev->entries) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: memory allocation failed",
+ VXGE_DRIVER_NAME);
+ return -ENOMEM;
+ }
+
+ vdev->vxge_entries = kzalloc(intr_cnt * sizeof(struct vxge_msix_entry),
+ GFP_KERNEL);
+ if (!vdev->vxge_entries) {
+ vxge_debug_init(VXGE_ERR, "%s: memory allocation failed",
+ VXGE_DRIVER_NAME);
+ kfree(vdev->entries);
+ return -ENOMEM;
+ }
+
+ /* Last vector in the list is used for alarm */
+ alarm_msix_id = VXGE_HW_VPATH_MSIX_ACTIVE * vdev->no_of_vpath - 2;
+ for (i = 0, j = 0; i < vdev->max_vpath_supported; i++) {
+
+ msix_intr_vect = i * VXGE_HW_VPATH_MSIX_ACTIVE;
+
+ /* Initialize the fifo vector */
+ vdev->entries[j].entry = msix_intr_vect;
+ vdev->vxge_entries[j].entry = msix_intr_vect;
+ vdev->vxge_entries[j].in_use = 0;
+ j++;
+
+ /* Initialize the ring vector */
+ vdev->entries[j].entry = msix_intr_vect + 1;
+ vdev->vxge_entries[j].entry = msix_intr_vect + 1;
+ vdev->vxge_entries[j].in_use = 0;
+ j++;
+ }
+
+ /* Initialize the alarm vector */
+ vdev->entries[j].entry = alarm_msix_id;
+ vdev->vxge_entries[j].entry = alarm_msix_id;
+ vdev->vxge_entries[j].in_use = 0;
+
+ ret = pci_enable_msix(vdev->pdev, vdev->entries, intr_cnt);
+ /* if driver request exceeeds available irq's, request with a small
+ * number.
+ */
+ if (ret > 0) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: MSI-X enable failed for %d vectors, available: %d",
+ VXGE_DRIVER_NAME, intr_cnt, ret);
+ vdev->max_vpath_supported = vdev->no_of_vpath;
+ intr_cnt = (vdev->max_vpath_supported * 2) + 1;
+
+ /* Reset the alarm vector setting */
+ vdev->entries[j].entry = 0;
+ vdev->vxge_entries[j].entry = 0;
+
+ /* Initialize the alarm vector with new setting */
+ vdev->entries[intr_cnt - 1].entry = alarm_msix_id;
+ vdev->vxge_entries[intr_cnt - 1].entry = alarm_msix_id;
+ vdev->vxge_entries[intr_cnt - 1].in_use = 0;
+
+ ret = pci_enable_msix(vdev->pdev, vdev->entries, intr_cnt);
+ if (!ret)
+ vxge_debug_init(VXGE_ERR,
+ "%s: MSI-X enabled for %d vectors",
+ VXGE_DRIVER_NAME, intr_cnt);
+ }
+
+ if (ret) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: MSI-X enable failed for %d vectors, ret: %d",
+ VXGE_DRIVER_NAME, intr_cnt, ret);
+ kfree(vdev->entries);
+ kfree(vdev->vxge_entries);
+ vdev->entries = NULL;
+ vdev->vxge_entries = NULL;
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static int vxge_enable_msix(struct vxgedev *vdev)
+{
+
+ int i, ret = 0;
+ enum vxge_hw_status status;
+ /* 0 - Tx, 1 - Rx */
+ int tim_msix_id[4];
+ int alarm_msix_id = 0, msix_intr_vect = 0;;
+ vdev->intr_cnt = 0;
+
+ /* allocate msix vectors */
+ ret = vxge_alloc_msix(vdev);
+ if (!ret) {
+ /* Last vector in the list is used for alarm */
+ alarm_msix_id =
+ VXGE_HW_VPATH_MSIX_ACTIVE * vdev->no_of_vpath - 2;
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+
+ /* If fifo or ring are not enabled
+ the MSIX vector for that should be set to 0
+ Hence initializeing this array to all 0s.
+ */
+ memset(tim_msix_id, 0, sizeof(tim_msix_id));
+ msix_intr_vect = i * VXGE_HW_VPATH_MSIX_ACTIVE;
+ tim_msix_id[0] = msix_intr_vect;
+
+ tim_msix_id[1] = msix_intr_vect + 1;
+ vdev->vpaths[i].ring.rx_vector_no = tim_msix_id[1];
+
+ status = vxge_hw_vpath_msix_set(
+ vdev->vpaths[i].handle,
+ tim_msix_id, alarm_msix_id);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "vxge_hw_vpath_msix_set "
+ "failed with status : %x", status);
+ kfree(vdev->entries);
+ kfree(vdev->vxge_entries);
+ pci_disable_msix(vdev->pdev);
+ return -ENODEV;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static void vxge_rem_msix_isr(struct vxgedev *vdev)
+{
+ int intr_cnt;
+
+ for (intr_cnt = 0; intr_cnt < (vdev->max_vpath_supported * 2 + 1);
+ intr_cnt++) {
+ if (vdev->vxge_entries[intr_cnt].in_use) {
+ synchronize_irq(vdev->entries[intr_cnt].vector);
+ free_irq(vdev->entries[intr_cnt].vector,
+ vdev->vxge_entries[intr_cnt].arg);
+ vdev->vxge_entries[intr_cnt].in_use = 0;
+ }
+ }
+
+ kfree(vdev->entries);
+ kfree(vdev->vxge_entries);
+ vdev->entries = NULL;
+ vdev->vxge_entries = NULL;
+
+ if (vdev->config.intr_type == MSI_X)
+ pci_disable_msix(vdev->pdev);
+}
+#endif
+
+static void vxge_rem_isr(struct vxgedev *vdev)
+{
+ struct __vxge_hw_device *hldev;
+ hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev);
+
+#ifdef CONFIG_PCI_MSI
+ if (vdev->config.intr_type == MSI_X) {
+ vxge_rem_msix_isr(vdev);
+ } else
+#endif
+ if (vdev->config.intr_type == INTA) {
+ synchronize_irq(vdev->pdev->irq);
+ free_irq(vdev->pdev->irq, hldev);
+ }
+}
+
+static int vxge_add_isr(struct vxgedev *vdev)
+{
+ int ret = 0;
+ struct __vxge_hw_device *hldev =
+ (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev);
+#ifdef CONFIG_PCI_MSI
+ int vp_idx = 0, intr_idx = 0, intr_cnt = 0, msix_idx = 0, irq_req = 0;
+ u64 function_mode = vdev->config.device_hw_info.function_mode;
+ int pci_fun = PCI_FUNC(vdev->pdev->devfn);
+
+ if (vdev->config.intr_type == MSI_X)
+ ret = vxge_enable_msix(vdev);
+
+ if (ret) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: Enabling MSI-X Failed", VXGE_DRIVER_NAME);
+ if ((function_mode == VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) &&
+ test_and_set_bit(__VXGE_STATE_CARD_UP,
+ &driver_config->inta_dev_open))
+ return VXGE_HW_FAIL;
+ else {
+ vxge_debug_init(VXGE_ERR,
+ "%s: Defaulting to INTA", VXGE_DRIVER_NAME);
+ vdev->config.intr_type = INTA;
+ vxge_hw_device_set_intr_type(vdev->devh,
+ VXGE_HW_INTR_MODE_IRQLINE);
+ vxge_close_vpaths(vdev, 1);
+ vdev->no_of_vpath = 1;
+ vdev->stats.vpaths_open = 1;
+ }
+ }
+
+ if (vdev->config.intr_type == MSI_X) {
+ for (intr_idx = 0;
+ intr_idx < (vdev->no_of_vpath *
+ VXGE_HW_VPATH_MSIX_ACTIVE); intr_idx++) {
+
+ msix_idx = intr_idx % VXGE_HW_VPATH_MSIX_ACTIVE;
+ irq_req = 0;
+
+ switch (msix_idx) {
+ case 0:
+ snprintf(vdev->desc[intr_cnt], VXGE_INTR_STRLEN,
+ "%s:vxge fn: %d vpath: %d Tx MSI-X: %d",
+ vdev->ndev->name, pci_fun, vp_idx,
+ vdev->entries[intr_cnt].entry);
+ ret = request_irq(
+ vdev->entries[intr_cnt].vector,
+ vxge_tx_msix_handle, 0,
+ vdev->desc[intr_cnt],
+ &vdev->vpaths[vp_idx].fifo);
+ vdev->vxge_entries[intr_cnt].arg =
+ &vdev->vpaths[vp_idx].fifo;
+ irq_req = 1;
+ break;
+ case 1:
+ snprintf(vdev->desc[intr_cnt], VXGE_INTR_STRLEN,
+ "%s:vxge fn: %d vpath: %d Rx MSI-X: %d",
+ vdev->ndev->name, pci_fun, vp_idx,
+ vdev->entries[intr_cnt].entry);
+ ret = request_irq(
+ vdev->entries[intr_cnt].vector,
+ vxge_rx_msix_napi_handle,
+ 0,
+ vdev->desc[intr_cnt],
+ &vdev->vpaths[vp_idx].ring);
+ vdev->vxge_entries[intr_cnt].arg =
+ &vdev->vpaths[vp_idx].ring;
+ irq_req = 1;
+ break;
+ }
+
+ if (ret) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: MSIX - %d Registration failed",
+ vdev->ndev->name, intr_cnt);
+ vxge_rem_msix_isr(vdev);
+ if ((function_mode ==
+ VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) &&
+ test_and_set_bit(__VXGE_STATE_CARD_UP,
+ &driver_config->inta_dev_open))
+ return VXGE_HW_FAIL;
+ else {
+ vxge_hw_device_set_intr_type(
+ vdev->devh,
+ VXGE_HW_INTR_MODE_IRQLINE);
+ vdev->config.intr_type = INTA;
+ vxge_debug_init(VXGE_ERR,
+ "%s: Defaulting to INTA"
+ , vdev->ndev->name);
+ vxge_close_vpaths(vdev, 1);
+ vdev->no_of_vpath = 1;
+ vdev->stats.vpaths_open = 1;
+ goto INTA_MODE;
+ }
+ }
+
+ if (irq_req) {
+ /* We requested for this msix interrupt */
+ vdev->vxge_entries[intr_cnt].in_use = 1;
+ vxge_hw_vpath_msix_unmask(
+ vdev->vpaths[vp_idx].handle,
+ intr_idx);
+ intr_cnt++;
+ }
+
+ /* Point to next vpath handler */
+ if (((intr_idx + 1) % VXGE_HW_VPATH_MSIX_ACTIVE == 0)
+ && (vp_idx < (vdev->no_of_vpath - 1)))
+ vp_idx++;
+ }
+
+ intr_cnt = vdev->max_vpath_supported * 2;
+ snprintf(vdev->desc[intr_cnt], VXGE_INTR_STRLEN,
+ "%s:vxge Alarm fn: %d MSI-X: %d",
+ vdev->ndev->name, pci_fun,
+ vdev->entries[intr_cnt].entry);
+ /* For Alarm interrupts */
+ ret = request_irq(vdev->entries[intr_cnt].vector,
+ vxge_alarm_msix_handle, 0,
+ vdev->desc[intr_cnt],
+ &vdev->vpaths[vp_idx]);
+ if (ret) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: MSIX - %d Registration failed",
+ vdev->ndev->name, intr_cnt);
+ vxge_rem_msix_isr(vdev);
+ if ((function_mode ==
+ VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) &&
+ test_and_set_bit(__VXGE_STATE_CARD_UP,
+ &driver_config->inta_dev_open))
+ return VXGE_HW_FAIL;
+ else {
+ vxge_hw_device_set_intr_type(vdev->devh,
+ VXGE_HW_INTR_MODE_IRQLINE);
+ vdev->config.intr_type = INTA;
+ vxge_debug_init(VXGE_ERR,
+ "%s: Defaulting to INTA",
+ vdev->ndev->name);
+ vxge_close_vpaths(vdev, 1);
+ vdev->no_of_vpath = 1;
+ vdev->stats.vpaths_open = 1;
+ goto INTA_MODE;
+ }
+ }
+
+ vxge_hw_vpath_msix_unmask(vdev->vpaths[vp_idx].handle,
+ intr_idx - 2);
+ vdev->vxge_entries[intr_cnt].in_use = 1;
+ vdev->vxge_entries[intr_cnt].arg = &vdev->vpaths[vp_idx];
+ }
+INTA_MODE:
+#endif
+ snprintf(vdev->desc[0], VXGE_INTR_STRLEN, "%s:vxge", vdev->ndev->name);
+
+ if (vdev->config.intr_type == INTA) {
+ ret = request_irq((int) vdev->pdev->irq,
+ vxge_isr_napi,
+ IRQF_SHARED, vdev->desc[0], hldev);
+ if (ret) {
+ vxge_debug_init(VXGE_ERR,
+ "%s %s-%d: ISR registration failed",
+ VXGE_DRIVER_NAME, "IRQ", vdev->pdev->irq);
+ return -ENODEV;
+ }
+ vxge_debug_init(VXGE_TRACE,
+ "new %s-%d line allocated",
+ "IRQ", vdev->pdev->irq);
+ }
+
+ return VXGE_HW_OK;
+}
+
+static void vxge_poll_vp_reset(unsigned long data)
+{
+ struct vxgedev *vdev = (struct vxgedev *)data;
+ int i, j = 0;
+
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ if (test_bit(i, &vdev->vp_reset)) {
+ vxge_reset_vpath(vdev, i);
+ j++;
+ }
+ }
+ if (j && (vdev->config.intr_type != MSI_X)) {
+ vxge_hw_device_unmask_all(vdev->devh);
+ vxge_hw_device_flush_io(vdev->devh);
+ }
+
+ mod_timer(&vdev->vp_reset_timer, jiffies + HZ / 2);
+}
+
+static void vxge_poll_vp_lockup(unsigned long data)
+{
+ struct vxgedev *vdev = (struct vxgedev *)data;
+ int i;
+ struct vxge_ring *ring;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ ring = &vdev->vpaths[i].ring;
+ /* Did this vpath received any packets */
+ if (ring->stats.prev_rx_frms == ring->stats.rx_frms) {
+ status = vxge_hw_vpath_check_leak(ring->handle);
+
+ /* Did it received any packets last time */
+ if ((VXGE_HW_FAIL == status) &&
+ (VXGE_HW_FAIL == ring->last_status)) {
+
+ /* schedule vpath reset */
+ if (!test_and_set_bit(i, &vdev->vp_reset)) {
+
+ /* disable interrupts for this vpath */
+ vxge_vpath_intr_disable(vdev, i);
+
+ /* stop the queue for this vpath */
+ vxge_stop_tx_queue(&vdev->vpaths[i].
+ fifo);
+ continue;
+ }
+ }
+ }
+ ring->stats.prev_rx_frms = ring->stats.rx_frms;
+ ring->last_status = status;
+ }
+
+ /* Check every 1 milli second */
+ mod_timer(&vdev->vp_lockup_timer, jiffies + HZ / 1000);
+}
+
+/**
+ * vxge_open
+ * @dev: pointer to the device structure.
+ *
+ * This function is the open entry point of the driver. It mainly calls a
+ * function to allocate Rx buffers and inserts them into the buffer
+ * descriptors and then enables the Rx part of the NIC.
+ * Return value: '0' on success and an appropriate (-)ve integer as
+ * defined in errno.h file on failure.
+ */
+int
+vxge_open(struct net_device *dev)
+{
+ enum vxge_hw_status status;
+ struct vxgedev *vdev;
+ struct __vxge_hw_device *hldev;
+ int ret = 0;
+ int i;
+ u64 val64, function_mode;
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s: %s:%d", dev->name, __func__, __LINE__);
+
+ vdev = (struct vxgedev *)netdev_priv(dev);
+ hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev);
+ function_mode = vdev->config.device_hw_info.function_mode;
+
+ /* make sure you have link off by default every time Nic is
+ * initialized */
+ netif_carrier_off(dev);
+
+ /* Check for another device already opn with INTA */
+ if ((function_mode == VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION) &&
+ test_bit(__VXGE_STATE_CARD_UP, &driver_config->inta_dev_open)) {
+ ret = -EPERM;
+ goto out0;
+ }
+
+ /* Open VPATHs */
+ status = vxge_open_vpaths(vdev);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: fatal: Vpath open failed", vdev->ndev->name);
+ ret = -EPERM;
+ goto out0;
+ }
+
+ vdev->mtu = dev->mtu;
+
+ status = vxge_add_isr(vdev);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: fatal: ISR add failed", dev->name);
+ ret = -EPERM;
+ goto out1;
+ }
+
+
+ if (vdev->config.intr_type != MSI_X) {
+ netif_napi_add(dev, &vdev->napi, vxge_poll_inta,
+ vdev->config.napi_weight);
+ napi_enable(&vdev->napi);
+ } else {
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ netif_napi_add(dev, &vdev->vpaths[i].ring.napi,
+ vxge_poll_msix, vdev->config.napi_weight);
+ napi_enable(&vdev->vpaths[i].ring.napi);
+ }
+ }
+
+ /* configure RTH */
+ if (vdev->config.rth_steering) {
+ status = vxge_rth_configure(vdev);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: fatal: RTH configuration failed",
+ dev->name);
+ ret = -EPERM;
+ goto out2;
+ }
+ }
+
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ /* set initial mtu before enabling the device */
+ status = vxge_hw_vpath_mtu_set(vdev->vpaths[i].handle,
+ vdev->mtu);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: fatal: can not set new MTU", dev->name);
+ ret = -EPERM;
+ goto out2;
+ }
+ }
+
+ VXGE_DEVICE_DEBUG_LEVEL_SET(VXGE_TRACE, VXGE_COMPONENT_LL, vdev);
+ vxge_debug_init(vdev->level_trace,
+ "%s: MTU is %d", vdev->ndev->name, vdev->mtu);
+ VXGE_DEVICE_DEBUG_LEVEL_SET(VXGE_ERR, VXGE_COMPONENT_LL, vdev);
+
+ /* Reprogram the DA table with populated mac addresses */
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_restore_vpath_mac_addr(&vdev->vpaths[i]);
+ vxge_restore_vpath_vid_table(&vdev->vpaths[i]);
+ }
+
+ /* Enable vpath to sniff all unicast/multicast traffic that not
+ * addressed to them. We allow promiscous mode for PF only
+ */
+
+ val64 = 0;
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++)
+ val64 |= VXGE_HW_RXMAC_AUTHORIZE_ALL_ADDR_VP(i);
+
+ vxge_hw_mgmt_reg_write(vdev->devh,
+ vxge_hw_mgmt_reg_type_mrpcim,
+ 0,
+ (ulong)offsetof(struct vxge_hw_mrpcim_reg,
+ rxmac_authorize_all_addr),
+ val64);
+
+ vxge_hw_mgmt_reg_write(vdev->devh,
+ vxge_hw_mgmt_reg_type_mrpcim,
+ 0,
+ (ulong)offsetof(struct vxge_hw_mrpcim_reg,
+ rxmac_authorize_all_vid),
+ val64);
+
+ vxge_set_multicast(dev);
+
+ /* Enabling Bcast and mcast for all vpath */
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ status = vxge_hw_vpath_bcast_enable(vdev->vpaths[i].handle);
+ if (status != VXGE_HW_OK)
+ vxge_debug_init(VXGE_ERR,
+ "%s : Can not enable bcast for vpath "
+ "id %d", dev->name, i);
+ if (vdev->config.addr_learn_en) {
+ status =
+ vxge_hw_vpath_mcast_enable(vdev->vpaths[i].handle);
+ if (status != VXGE_HW_OK)
+ vxge_debug_init(VXGE_ERR,
+ "%s : Can not enable mcast for vpath "
+ "id %d", dev->name, i);
+ }
+ }
+
+ vxge_hw_device_setpause_data(vdev->devh, 0,
+ vdev->config.tx_pause_enable,
+ vdev->config.rx_pause_enable);
+
+ if (vdev->vp_reset_timer.function == NULL)
+ vxge_os_timer(vdev->vp_reset_timer,
+ vxge_poll_vp_reset, vdev, (HZ/2));
+
+ if (vdev->vp_lockup_timer.function == NULL)
+ vxge_os_timer(vdev->vp_lockup_timer,
+ vxge_poll_vp_lockup, vdev, (HZ/2));
+
+ set_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+
+ smp_wmb();
+
+ if (vxge_hw_device_link_state_get(vdev->devh) == VXGE_HW_LINK_UP) {
+ netif_carrier_on(vdev->ndev);
+ printk(KERN_NOTICE "%s: Link Up\n", vdev->ndev->name);
+ vdev->stats.link_up++;
+ }
+
+ vxge_hw_device_intr_enable(vdev->devh);
+
+ smp_wmb();
+
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_hw_vpath_enable(vdev->vpaths[i].handle);
+ smp_wmb();
+ vxge_hw_vpath_rx_doorbell_init(vdev->vpaths[i].handle);
+ }
+
+ vxge_start_all_tx_queue(vdev);
+ goto out0;
+
+out2:
+ vxge_rem_isr(vdev);
+
+ /* Disable napi */
+ if (vdev->config.intr_type != MSI_X)
+ napi_disable(&vdev->napi);
+ else {
+ for (i = 0; i < vdev->no_of_vpath; i++)
+ napi_disable(&vdev->vpaths[i].ring.napi);
+ }
+
+out1:
+ vxge_close_vpaths(vdev, 0);
+out0:
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s: %s:%d Exiting...",
+ dev->name, __func__, __LINE__);
+ return ret;
+}
+
+/* Loop throught the mac address list and delete all the entries */
+void vxge_free_mac_add_list(struct vxge_vpath *vpath)
+{
+
+ struct list_head *entry, *next;
+ if (list_empty(&vpath->mac_addr_list))
+ return;
+
+ list_for_each_safe(entry, next, &vpath->mac_addr_list) {
+ list_del(entry);
+ kfree((struct vxge_mac_addrs *)entry);
+ }
+}
+
+static void vxge_napi_del_all(struct vxgedev *vdev)
+{
+ int i;
+ if (vdev->config.intr_type != MSI_X)
+ netif_napi_del(&vdev->napi);
+ else {
+ for (i = 0; i < vdev->no_of_vpath; i++)
+ netif_napi_del(&vdev->vpaths[i].ring.napi);
+ }
+ return;
+}
+
+int do_vxge_close(struct net_device *dev, int do_io)
+{
+ enum vxge_hw_status status;
+ struct vxgedev *vdev;
+ struct __vxge_hw_device *hldev;
+ int i;
+ u64 val64, vpath_vector;
+ vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
+ dev->name, __func__, __LINE__);
+
+ vdev = (struct vxgedev *)netdev_priv(dev);
+ hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev);
+
+ /* If vxge_handle_crit_err task is executing,
+ * wait till it completes. */
+ while (test_and_set_bit(__VXGE_STATE_RESET_CARD, &vdev->state))
+ msleep(50);
+
+ clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+ if (do_io) {
+ /* Put the vpath back in normal mode */
+ vpath_vector = vxge_mBIT(vdev->vpaths[0].device_id);
+ status = vxge_hw_mgmt_reg_read(vdev->devh,
+ vxge_hw_mgmt_reg_type_mrpcim,
+ 0,
+ (ulong)offsetof(
+ struct vxge_hw_mrpcim_reg,
+ rts_mgr_cbasin_cfg),
+ &val64);
+
+ if (status == VXGE_HW_OK) {
+ val64 &= ~vpath_vector;
+ status = vxge_hw_mgmt_reg_write(vdev->devh,
+ vxge_hw_mgmt_reg_type_mrpcim,
+ 0,
+ (ulong)offsetof(
+ struct vxge_hw_mrpcim_reg,
+ rts_mgr_cbasin_cfg),
+ val64);
+ }
+
+ /* Remove the function 0 from promiscous mode */
+ vxge_hw_mgmt_reg_write(vdev->devh,
+ vxge_hw_mgmt_reg_type_mrpcim,
+ 0,
+ (ulong)offsetof(struct vxge_hw_mrpcim_reg,
+ rxmac_authorize_all_addr),
+ 0);
+
+ vxge_hw_mgmt_reg_write(vdev->devh,
+ vxge_hw_mgmt_reg_type_mrpcim,
+ 0,
+ (ulong)offsetof(struct vxge_hw_mrpcim_reg,
+ rxmac_authorize_all_vid),
+ 0);
+
+ smp_wmb();
+ }
+ del_timer_sync(&vdev->vp_lockup_timer);
+
+ del_timer_sync(&vdev->vp_reset_timer);
+
+ /* Disable napi */
+ if (vdev->config.intr_type != MSI_X)
+ napi_disable(&vdev->napi);
+ else {
+ for (i = 0; i < vdev->no_of_vpath; i++)
+ napi_disable(&vdev->vpaths[i].ring.napi);
+ }
+
+ netif_carrier_off(vdev->ndev);
+ printk(KERN_NOTICE "%s: Link Down\n", vdev->ndev->name);
+ vxge_stop_all_tx_queue(vdev);
+
+ /* Note that at this point xmit() is stopped by upper layer */
+ if (do_io)
+ vxge_hw_device_intr_disable(vdev->devh);
+
+ mdelay(1000);
+
+ vxge_rem_isr(vdev);
+
+ vxge_napi_del_all(vdev);
+
+ if (do_io)
+ vxge_reset_all_vpaths(vdev);
+
+ vxge_close_vpaths(vdev, 0);
+
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s: %s:%d Exiting...", dev->name, __func__, __LINE__);
+
+ clear_bit(__VXGE_STATE_CARD_UP, &driver_config->inta_dev_open);
+ clear_bit(__VXGE_STATE_RESET_CARD, &vdev->state);
+
+ return 0;
+}
+
+/**
+ * vxge_close
+ * @dev: device pointer.
+ *
+ * This is the stop entry point of the driver. It needs to undo exactly
+ * whatever was done by the open entry point, thus it's usually referred to
+ * as the close function.Among other things this function mainly stops the
+ * Rx side of the NIC and frees all the Rx buffers in the Rx rings.
+ * Return value: '0' on success and an appropriate (-)ve integer as
+ * defined in errno.h file on failure.
+ */
+int
+vxge_close(struct net_device *dev)
+{
+ do_vxge_close(dev, 1);
+ return 0;
+}
+
+/**
+ * vxge_change_mtu
+ * @dev: net device pointer.
+ * @new_mtu :the new MTU size for the device.
+ *
+ * A driver entry point to change MTU size for the device. Before changing
+ * the MTU the device must be stopped.
+ */
+static int vxge_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct vxgedev *vdev = netdev_priv(dev);
+
+ vxge_debug_entryexit(vdev->level_trace,
+ "%s:%d", __func__, __LINE__);
+ if ((new_mtu < VXGE_HW_MIN_MTU) || (new_mtu > VXGE_HW_MAX_MTU)) {
+ vxge_debug_init(vdev->level_err,
+ "%s: mtu size is invalid", dev->name);
+ return -EPERM;
+ }
+
+ /* check if device is down already */
+ if (unlikely(!is_vxge_card_up(vdev))) {
+ /* just store new value, will use later on open() */
+ dev->mtu = new_mtu;
+ vxge_debug_init(vdev->level_err,
+ "%s", "device is down on MTU change");
+ return 0;
+ }
+
+ vxge_debug_init(vdev->level_trace,
+ "trying to apply new MTU %d", new_mtu);
+
+ if (vxge_close(dev))
+ return -EIO;
+
+ dev->mtu = new_mtu;
+ vdev->mtu = new_mtu;
+
+ if (vxge_open(dev))
+ return -EIO;
+
+ vxge_debug_init(vdev->level_trace,
+ "%s: MTU changed to %d", vdev->ndev->name, new_mtu);
+
+ vxge_debug_entryexit(vdev->level_trace,
+ "%s:%d Exiting...", __func__, __LINE__);
+
+ return 0;
+}
+
+/**
+ * vxge_get_stats
+ * @dev: pointer to the device structure
+ *
+ * Updates the device statistics structure. This function updates the device
+ * statistics structure in the net_device structure and returns a pointer
+ * to the same.
+ */
+static struct net_device_stats *
+vxge_get_stats(struct net_device *dev)
+{
+ struct vxgedev *vdev;
+ struct net_device_stats *net_stats;
+ int k;
+
+ vdev = netdev_priv(dev);
+
+ net_stats = &vdev->stats.net_stats;
+
+ memset(net_stats, 0, sizeof(struct net_device_stats));
+
+ for (k = 0; k < vdev->no_of_vpath; k++) {
+ net_stats->rx_packets += vdev->vpaths[k].ring.stats.rx_frms;
+ net_stats->rx_bytes += vdev->vpaths[k].ring.stats.rx_bytes;
+ net_stats->rx_errors += vdev->vpaths[k].ring.stats.rx_errors;
+ net_stats->multicast += vdev->vpaths[k].ring.stats.rx_mcast;
+ net_stats->rx_dropped +=
+ vdev->vpaths[k].ring.stats.rx_dropped;
+
+ net_stats->tx_packets += vdev->vpaths[k].fifo.stats.tx_frms;
+ net_stats->tx_bytes += vdev->vpaths[k].fifo.stats.tx_bytes;
+ net_stats->tx_errors += vdev->vpaths[k].fifo.stats.tx_errors;
+ }
+
+ return net_stats;
+}
+
+/**
+ * vxge_ioctl
+ * @dev: Device pointer.
+ * @ifr: An IOCTL specific structure, that can contain a pointer to
+ * a proprietary structure used to pass information to the driver.
+ * @cmd: This is used to distinguish between the different commands that
+ * can be passed to the IOCTL functions.
+ *
+ * Entry point for the Ioctl.
+ */
+static int vxge_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ return -EOPNOTSUPP;
+}
+
+/**
+ * vxge_tx_watchdog
+ * @dev: pointer to net device structure
+ *
+ * Watchdog for transmit side.
+ * This function is triggered if the Tx Queue is stopped
+ * for a pre-defined amount of time when the Interface is still up.
+ */
+static void
+vxge_tx_watchdog(struct net_device *dev)
+{
+ struct vxgedev *vdev;
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+ vdev = (struct vxgedev *)netdev_priv(dev);
+
+ vdev->cric_err_event = VXGE_HW_EVENT_RESET_START;
+
+ vxge_reset(vdev);
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s:%d Exiting...", __func__, __LINE__);
+}
+
+/**
+ * vxge_vlan_rx_register
+ * @dev: net device pointer.
+ * @grp: vlan group
+ *
+ * Vlan group registration
+ */
+static void
+vxge_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+ struct vxgedev *vdev;
+ struct vxge_vpath *vpath;
+ int vp;
+ u64 vid;
+ enum vxge_hw_status status;
+ int i;
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+ vdev = (struct vxgedev *)netdev_priv(dev);
+
+ vpath = &vdev->vpaths[0];
+ if ((NULL == grp) && (vpath->is_open)) {
+ /* Get the first vlan */
+ status = vxge_hw_vpath_vid_get(vpath->handle, &vid);
+
+ while (status == VXGE_HW_OK) {
+
+ /* Delete this vlan from the vid table */
+ for (vp = 0; vp < vdev->no_of_vpath; vp++) {
+ vpath = &vdev->vpaths[vp];
+ if (!vpath->is_open)
+ continue;
+
+ vxge_hw_vpath_vid_delete(vpath->handle, vid);
+ }
+
+ /* Get the next vlan to be deleted */
+ vpath = &vdev->vpaths[0];
+ status = vxge_hw_vpath_vid_get(vpath->handle, &vid);
+ }
+ }
+
+ vdev->vlgrp = grp;
+
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ if (vdev->vpaths[i].is_configured)
+ vdev->vpaths[i].ring.vlgrp = grp;
+ }
+
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s:%d Exiting...", __func__, __LINE__);
+}
+
+/**
+ * vxge_vlan_rx_add_vid
+ * @dev: net device pointer.
+ * @vid: vid
+ *
+ * Add the vlan id to the devices vlan id table
+ */
+static void
+vxge_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
+{
+ struct vxgedev *vdev;
+ struct vxge_vpath *vpath;
+ int vp_id;
+
+ vdev = (struct vxgedev *)netdev_priv(dev);
+
+ /* Add these vlan to the vid table */
+ for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) {
+ vpath = &vdev->vpaths[vp_id];
+ if (!vpath->is_open)
+ continue;
+ vxge_hw_vpath_vid_add(vpath->handle, vid);
+ }
+}
+
+/**
+ * vxge_vlan_rx_add_vid
+ * @dev: net device pointer.
+ * @vid: vid
+ *
+ * Remove the vlan id from the device's vlan id table
+ */
+static void
+vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+ struct vxgedev *vdev;
+ struct vxge_vpath *vpath;
+ int vp_id;
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+
+ vdev = (struct vxgedev *)netdev_priv(dev);
+
+ vlan_group_set_device(vdev->vlgrp, vid, NULL);
+
+ /* Delete this vlan from the vid table */
+ for (vp_id = 0; vp_id < vdev->no_of_vpath; vp_id++) {
+ vpath = &vdev->vpaths[vp_id];
+ if (!vpath->is_open)
+ continue;
+ vxge_hw_vpath_vid_delete(vpath->handle, vid);
+ }
+ vxge_debug_entryexit(VXGE_TRACE,
+ "%s:%d Exiting...", __func__, __LINE__);
+}
+
+static const struct net_device_ops vxge_netdev_ops = {
+ .ndo_open = vxge_open,
+ .ndo_stop = vxge_close,
+ .ndo_get_stats = vxge_get_stats,
+ .ndo_start_xmit = vxge_xmit,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = vxge_set_multicast,
+
+ .ndo_do_ioctl = vxge_ioctl,
+
+ .ndo_set_mac_address = vxge_set_mac_addr,
+ .ndo_change_mtu = vxge_change_mtu,
+ .ndo_vlan_rx_register = vxge_vlan_rx_register,
+ .ndo_vlan_rx_kill_vid = vxge_vlan_rx_kill_vid,
+ .ndo_vlan_rx_add_vid = vxge_vlan_rx_add_vid,
+
+ .ndo_tx_timeout = vxge_tx_watchdog,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = vxge_netpoll,
+#endif
+};
+
+int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
+ struct vxge_config *config,
+ int high_dma, int no_of_vpath,
+ struct vxgedev **vdev_out)
+{
+ struct net_device *ndev;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxgedev *vdev;
+ int i, ret = 0, no_of_queue = 1;
+ u64 stat;
+
+ *vdev_out = NULL;
+ if (config->tx_steering_type == TX_MULTIQ_STEERING)
+ no_of_queue = no_of_vpath;
+
+ ndev = alloc_etherdev_mq(sizeof(struct vxgedev),
+ no_of_queue);
+ if (ndev == NULL) {
+ vxge_debug_init(
+ vxge_hw_device_trace_level_get(hldev),
+ "%s : device allocation failed", __func__);
+ ret = -ENODEV;
+ goto _out0;
+ }
+
+ vxge_debug_entryexit(
+ vxge_hw_device_trace_level_get(hldev),
+ "%s: %s:%d Entering...",
+ ndev->name, __func__, __LINE__);
+
+ vdev = netdev_priv(ndev);
+ memset(vdev, 0, sizeof(struct vxgedev));
+
+ vdev->ndev = ndev;
+ vdev->devh = hldev;
+ vdev->pdev = hldev->pdev;
+ memcpy(&vdev->config, config, sizeof(struct vxge_config));
+ vdev->rx_csum = 1; /* Enable Rx CSUM by default. */
+
+ SET_NETDEV_DEV(ndev, &vdev->pdev->dev);
+
+ ndev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
+ NETIF_F_HW_VLAN_FILTER;
+ /* Driver entry points */
+ ndev->irq = vdev->pdev->irq;
+ ndev->base_addr = (unsigned long) hldev->bar0;
+
+ ndev->netdev_ops = &vxge_netdev_ops;
+
+ ndev->watchdog_timeo = VXGE_LL_WATCH_DOG_TIMEOUT;
+
+ initialize_ethtool_ops(ndev);
+
+ /* Allocate memory for vpath */
+ vdev->vpaths = kzalloc((sizeof(struct vxge_vpath)) *
+ no_of_vpath, GFP_KERNEL);
+ if (!vdev->vpaths) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: vpath memory allocation failed",
+ vdev->ndev->name);
+ ret = -ENODEV;
+ goto _out1;
+ }
+
+ ndev->features |= NETIF_F_SG;
+
+ ndev->features |= NETIF_F_HW_CSUM;
+ vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
+ "%s : checksuming enabled", __func__);
+
+ if (high_dma) {
+ ndev->features |= NETIF_F_HIGHDMA;
+ vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
+ "%s : using High DMA", __func__);
+ }
+
+ ndev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+
+ if (vdev->config.gro_enable)
+ ndev->features |= NETIF_F_GRO;
+
+ if (vdev->config.tx_steering_type == TX_MULTIQ_STEERING)
+ ndev->real_num_tx_queues = no_of_vpath;
+
+#ifdef NETIF_F_LLTX
+ ndev->features |= NETIF_F_LLTX;
+#endif
+
+ for (i = 0; i < no_of_vpath; i++)
+ spin_lock_init(&vdev->vpaths[i].fifo.tx_lock);
+
+ if (register_netdev(ndev)) {
+ vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
+ "%s: %s : device registration failed!",
+ ndev->name, __func__);
+ ret = -ENODEV;
+ goto _out2;
+ }
+
+ /* Set the factory defined MAC address initially */
+ ndev->addr_len = ETH_ALEN;
+
+ /* Make Link state as off at this point, when the Link change
+ * interrupt comes the state will be automatically changed to
+ * the right state.
+ */
+ netif_carrier_off(ndev);
+
+ vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
+ "%s: Ethernet device registered",
+ ndev->name);
+
+ *vdev_out = vdev;
+
+ /* Resetting the Device stats */
+ status = vxge_hw_mrpcim_stats_access(
+ hldev,
+ VXGE_HW_STATS_OP_CLEAR_ALL_STATS,
+ 0,
+ 0,
+ &stat);
+
+ if (status == VXGE_HW_ERR_PRIVILAGED_OPEARATION)
+ vxge_debug_init(
+ vxge_hw_device_trace_level_get(hldev),
+ "%s: device stats clear returns"
+ "VXGE_HW_ERR_PRIVILAGED_OPEARATION", ndev->name);
+
+ vxge_debug_entryexit(vxge_hw_device_trace_level_get(hldev),
+ "%s: %s:%d Exiting...",
+ ndev->name, __func__, __LINE__);
+
+ return ret;
+_out2:
+ kfree(vdev->vpaths);
+_out1:
+ free_netdev(ndev);
+_out0:
+ return ret;
+}
+
+/*
+ * vxge_device_unregister
+ *
+ * This function will unregister and free network device
+ */
+void
+vxge_device_unregister(struct __vxge_hw_device *hldev)
+{
+ struct vxgedev *vdev;
+ struct net_device *dev;
+ char buf[IFNAMSIZ];
+#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \
+ (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK))
+ u32 level_trace;
+#endif
+
+ dev = hldev->ndev;
+ vdev = netdev_priv(dev);
+#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \
+ (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK))
+ level_trace = vdev->level_trace;
+#endif
+ vxge_debug_entryexit(level_trace,
+ "%s: %s:%d", vdev->ndev->name, __func__, __LINE__);
+
+ memcpy(buf, vdev->ndev->name, IFNAMSIZ);
+
+ /* in 2.6 will call stop() if device is up */
+ unregister_netdev(dev);
+
+ flush_scheduled_work();
+
+ vxge_debug_init(level_trace, "%s: ethernet device unregistered", buf);
+ vxge_debug_entryexit(level_trace,
+ "%s: %s:%d Exiting...", buf, __func__, __LINE__);
+}
+
+/*
+ * vxge_callback_crit_err
+ *
+ * This function is called by the alarm handler in interrupt context.
+ * Driver must analyze it based on the event type.
+ */
+static void
+vxge_callback_crit_err(struct __vxge_hw_device *hldev,
+ enum vxge_hw_event type, u64 vp_id)
+{
+ struct net_device *dev = hldev->ndev;
+ struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
+ int vpath_idx;
+
+ vxge_debug_entryexit(vdev->level_trace,
+ "%s: %s:%d", vdev->ndev->name, __func__, __LINE__);
+
+ /* Note: This event type should be used for device wide
+ * indications only - Serious errors, Slot freeze and critical errors
+ */
+ vdev->cric_err_event = type;
+
+ for (vpath_idx = 0; vpath_idx < vdev->no_of_vpath; vpath_idx++)
+ if (vdev->vpaths[vpath_idx].device_id == vp_id)
+ break;
+
+ if (!test_bit(__VXGE_STATE_RESET_CARD, &vdev->state)) {
+ if (type == VXGE_HW_EVENT_SLOT_FREEZE) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: Slot is frozen", vdev->ndev->name);
+ } else if (type == VXGE_HW_EVENT_SERR) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: Encountered Serious Error",
+ vdev->ndev->name);
+ } else if (type == VXGE_HW_EVENT_CRITICAL_ERR)
+ vxge_debug_init(VXGE_ERR,
+ "%s: Encountered Critical Error",
+ vdev->ndev->name);
+ }
+
+ if ((type == VXGE_HW_EVENT_SERR) ||
+ (type == VXGE_HW_EVENT_SLOT_FREEZE)) {
+ if (unlikely(vdev->exec_mode))
+ clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+ } else if (type == VXGE_HW_EVENT_CRITICAL_ERR) {
+ vxge_hw_device_mask_all(hldev);
+ if (unlikely(vdev->exec_mode))
+ clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+ } else if ((type == VXGE_HW_EVENT_FIFO_ERR) ||
+ (type == VXGE_HW_EVENT_VPATH_ERR)) {
+
+ if (unlikely(vdev->exec_mode))
+ clear_bit(__VXGE_STATE_CARD_UP, &vdev->state);
+ else {
+ /* check if this vpath is already set for reset */
+ if (!test_and_set_bit(vpath_idx, &vdev->vp_reset)) {
+
+ /* disable interrupts for this vpath */
+ vxge_vpath_intr_disable(vdev, vpath_idx);
+
+ /* stop the queue for this vpath */
+ vxge_stop_tx_queue(&vdev->vpaths[vpath_idx].
+ fifo);
+ }
+ }
+ }
+
+ vxge_debug_entryexit(vdev->level_trace,
+ "%s: %s:%d Exiting...",
+ vdev->ndev->name, __func__, __LINE__);
+}
+
+static void verify_bandwidth(void)
+{
+ int i, band_width, total = 0, equal_priority = 0;
+
+ /* 1. If user enters 0 for some fifo, give equal priority to all */
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+ if (bw_percentage[i] == 0) {
+ equal_priority = 1;
+ break;
+ }
+ }
+
+ if (!equal_priority) {
+ /* 2. If sum exceeds 100, give equal priority to all */
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+ if (bw_percentage[i] == 0xFF)
+ break;
+
+ total += bw_percentage[i];
+ if (total > VXGE_HW_VPATH_BANDWIDTH_MAX) {
+ equal_priority = 1;
+ break;
+ }
+ }
+ }
+
+ if (!equal_priority) {
+ /* Is all the bandwidth consumed? */
+ if (total < VXGE_HW_VPATH_BANDWIDTH_MAX) {
+ if (i < VXGE_HW_MAX_VIRTUAL_PATHS) {
+ /* Split rest of bw equally among next VPs*/
+ band_width =
+ (VXGE_HW_VPATH_BANDWIDTH_MAX - total) /
+ (VXGE_HW_MAX_VIRTUAL_PATHS - i);
+ if (band_width < 2) /* min of 2% */
+ equal_priority = 1;
+ else {
+ for (; i < VXGE_HW_MAX_VIRTUAL_PATHS;
+ i++)
+ bw_percentage[i] =
+ band_width;
+ }
+ }
+ } else if (i < VXGE_HW_MAX_VIRTUAL_PATHS)
+ equal_priority = 1;
+ }
+
+ if (equal_priority) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: Assigning equal bandwidth to all the vpaths",
+ VXGE_DRIVER_NAME);
+ bw_percentage[0] = VXGE_HW_VPATH_BANDWIDTH_MAX /
+ VXGE_HW_MAX_VIRTUAL_PATHS;
+ for (i = 1; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++)
+ bw_percentage[i] = bw_percentage[0];
+ }
+
+ return;
+}
+
+/*
+ * Vpath configuration
+ */
+static int __devinit vxge_config_vpaths(
+ struct vxge_hw_device_config *device_config,
+ u64 vpath_mask, struct vxge_config *config_param)
+{
+ int i, no_of_vpaths = 0, default_no_vpath = 0, temp;
+ u32 txdl_size, txdl_per_memblock;
+
+ temp = driver_config->vpath_per_dev;
+ if ((driver_config->vpath_per_dev == VXGE_USE_DEFAULT) &&
+ (max_config_dev == VXGE_MAX_CONFIG_DEV)) {
+ /* No more CPU. Return vpath number as zero.*/
+ if (driver_config->g_no_cpus == -1)
+ return 0;
+
+ if (!driver_config->g_no_cpus)
+ driver_config->g_no_cpus = num_online_cpus();
+
+ driver_config->vpath_per_dev = driver_config->g_no_cpus >> 1;
+ if (!driver_config->vpath_per_dev)
+ driver_config->vpath_per_dev = 1;
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++)
+ if (!vxge_bVALn(vpath_mask, i, 1))
+ continue;
+ else
+ default_no_vpath++;
+ if (default_no_vpath < driver_config->vpath_per_dev)
+ driver_config->vpath_per_dev = default_no_vpath;
+
+ driver_config->g_no_cpus = driver_config->g_no_cpus -
+ (driver_config->vpath_per_dev * 2);
+ if (driver_config->g_no_cpus <= 0)
+ driver_config->g_no_cpus = -1;
+ }
+
+ if (driver_config->vpath_per_dev == 1) {
+ vxge_debug_ll_config(VXGE_TRACE,
+ "%s: Disable tx and rx steering, "
+ "as single vpath is configured", VXGE_DRIVER_NAME);
+ config_param->rth_steering = NO_STEERING;
+ config_param->tx_steering_type = NO_STEERING;
+ device_config->rth_en = 0;
+ }
+
+ /* configure bandwidth */
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++)
+ device_config->vp_config[i].min_bandwidth = bw_percentage[i];
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+ device_config->vp_config[i].vp_id = i;
+ device_config->vp_config[i].mtu = VXGE_HW_DEFAULT_MTU;
+ if (no_of_vpaths < driver_config->vpath_per_dev) {
+ if (!vxge_bVALn(vpath_mask, i, 1)) {
+ vxge_debug_ll_config(VXGE_TRACE,
+ "%s: vpath: %d is not available",
+ VXGE_DRIVER_NAME, i);
+ continue;
+ } else {
+ vxge_debug_ll_config(VXGE_TRACE,
+ "%s: vpath: %d available",
+ VXGE_DRIVER_NAME, i);
+ no_of_vpaths++;
+ }
+ } else {
+ vxge_debug_ll_config(VXGE_TRACE,
+ "%s: vpath: %d is not configured, "
+ "max_config_vpath exceeded",
+ VXGE_DRIVER_NAME, i);
+ break;
+ }
+
+ /* Configure Tx fifo's */
+ device_config->vp_config[i].fifo.enable =
+ VXGE_HW_FIFO_ENABLE;
+ device_config->vp_config[i].fifo.max_frags =
+ MAX_SKB_FRAGS;
+ device_config->vp_config[i].fifo.memblock_size =
+ VXGE_HW_MIN_FIFO_MEMBLOCK_SIZE;
+
+ txdl_size = MAX_SKB_FRAGS * sizeof(struct vxge_hw_fifo_txd);
+ txdl_per_memblock = VXGE_HW_MIN_FIFO_MEMBLOCK_SIZE / txdl_size;
+
+ device_config->vp_config[i].fifo.fifo_blocks =
+ ((VXGE_DEF_FIFO_LENGTH - 1) / txdl_per_memblock) + 1;
+
+ device_config->vp_config[i].fifo.intr =
+ VXGE_HW_FIFO_QUEUE_INTR_DISABLE;
+
+ /* Configure tti properties */
+ device_config->vp_config[i].tti.intr_enable =
+ VXGE_HW_TIM_INTR_ENABLE;
+
+ device_config->vp_config[i].tti.btimer_val =
+ (VXGE_TTI_BTIMER_VAL * 1000) / 272;
+
+ device_config->vp_config[i].tti.timer_ac_en =
+ VXGE_HW_TIM_TIMER_AC_ENABLE;
+
+ /* For msi-x with napi (each vector
+ has a handler of its own) -
+ Set CI to OFF for all vpaths */
+ device_config->vp_config[i].tti.timer_ci_en =
+ VXGE_HW_TIM_TIMER_CI_DISABLE;
+
+ device_config->vp_config[i].tti.timer_ri_en =
+ VXGE_HW_TIM_TIMER_RI_DISABLE;
+
+ device_config->vp_config[i].tti.util_sel =
+ VXGE_HW_TIM_UTIL_SEL_LEGACY_TX_NET_UTIL;
+
+ device_config->vp_config[i].tti.ltimer_val =
+ (VXGE_TTI_LTIMER_VAL * 1000) / 272;
+
+ device_config->vp_config[i].tti.rtimer_val =
+ (VXGE_TTI_RTIMER_VAL * 1000) / 272;
+
+ device_config->vp_config[i].tti.urange_a = TTI_TX_URANGE_A;
+ device_config->vp_config[i].tti.urange_b = TTI_TX_URANGE_B;
+ device_config->vp_config[i].tti.urange_c = TTI_TX_URANGE_C;
+ device_config->vp_config[i].tti.uec_a = TTI_TX_UFC_A;
+ device_config->vp_config[i].tti.uec_b = TTI_TX_UFC_B;
+ device_config->vp_config[i].tti.uec_c = TTI_TX_UFC_C;
+ device_config->vp_config[i].tti.uec_d = TTI_TX_UFC_D;
+
+ /* Configure Rx rings */
+ device_config->vp_config[i].ring.enable =
+ VXGE_HW_RING_ENABLE;
+
+ device_config->vp_config[i].ring.ring_blocks =
+ VXGE_HW_DEF_RING_BLOCKS;
+ device_config->vp_config[i].ring.buffer_mode =
+ VXGE_HW_RING_RXD_BUFFER_MODE_1;
+ device_config->vp_config[i].ring.rxds_limit =
+ VXGE_HW_DEF_RING_RXDS_LIMIT;
+ device_config->vp_config[i].ring.scatter_mode =
+ VXGE_HW_RING_SCATTER_MODE_A;
+
+ /* Configure rti properties */
+ device_config->vp_config[i].rti.intr_enable =
+ VXGE_HW_TIM_INTR_ENABLE;
+
+ device_config->vp_config[i].rti.btimer_val =
+ (VXGE_RTI_BTIMER_VAL * 1000)/272;
+
+ device_config->vp_config[i].rti.timer_ac_en =
+ VXGE_HW_TIM_TIMER_AC_ENABLE;
+
+ device_config->vp_config[i].rti.timer_ci_en =
+ VXGE_HW_TIM_TIMER_CI_DISABLE;
+
+ device_config->vp_config[i].rti.timer_ri_en =
+ VXGE_HW_TIM_TIMER_RI_DISABLE;
+
+ device_config->vp_config[i].rti.util_sel =
+ VXGE_HW_TIM_UTIL_SEL_LEGACY_RX_NET_UTIL;
+
+ device_config->vp_config[i].rti.urange_a =
+ RTI_RX_URANGE_A;
+ device_config->vp_config[i].rti.urange_b =
+ RTI_RX_URANGE_B;
+ device_config->vp_config[i].rti.urange_c =
+ RTI_RX_URANGE_C;
+ device_config->vp_config[i].rti.uec_a = RTI_RX_UFC_A;
+ device_config->vp_config[i].rti.uec_b = RTI_RX_UFC_B;
+ device_config->vp_config[i].rti.uec_c = RTI_RX_UFC_C;
+ device_config->vp_config[i].rti.uec_d = RTI_RX_UFC_D;
+
+ device_config->vp_config[i].rti.rtimer_val =
+ (VXGE_RTI_RTIMER_VAL * 1000) / 272;
+
+ device_config->vp_config[i].rti.ltimer_val =
+ (VXGE_RTI_LTIMER_VAL * 1000) / 272;
+
+ device_config->vp_config[i].rpa_strip_vlan_tag =
+ vlan_tag_strip;
+ }
+
+ driver_config->vpath_per_dev = temp;
+ return no_of_vpaths;
+}
+
+/* initialize device configuratrions */
+static void __devinit vxge_device_config_init(
+ struct vxge_hw_device_config *device_config,
+ int *intr_type)
+{
+ /* Used for CQRQ/SRQ. */
+ device_config->dma_blockpool_initial =
+ VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE;
+
+ device_config->dma_blockpool_max =
+ VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE;
+
+ if (max_mac_vpath > VXGE_MAX_MAC_ADDR_COUNT)
+ max_mac_vpath = VXGE_MAX_MAC_ADDR_COUNT;
+
+#ifndef CONFIG_PCI_MSI
+ vxge_debug_init(VXGE_ERR,
+ "%s: This Kernel does not support "
+ "MSI-X. Defaulting to INTA", VXGE_DRIVER_NAME);
+ *intr_type = INTA;
+#endif
+
+ /* Configure whether MSI-X or IRQL. */
+ switch (*intr_type) {
+ case INTA:
+ device_config->intr_mode = VXGE_HW_INTR_MODE_IRQLINE;
+ break;
+
+ case MSI_X:
+ device_config->intr_mode = VXGE_HW_INTR_MODE_MSIX;
+ break;
+ }
+ /* Timer period between device poll */
+ device_config->device_poll_millis = VXGE_TIMER_DELAY;
+
+ /* Configure mac based steering. */
+ device_config->rts_mac_en = addr_learn_en;
+
+ /* Configure Vpaths */
+ device_config->rth_it_type = VXGE_HW_RTH_IT_TYPE_MULTI_IT;
+
+ vxge_debug_ll_config(VXGE_TRACE, "%s : Device Config Params ",
+ __func__);
+ vxge_debug_ll_config(VXGE_TRACE, "dma_blockpool_initial : %d",
+ device_config->dma_blockpool_initial);
+ vxge_debug_ll_config(VXGE_TRACE, "dma_blockpool_max : %d",
+ device_config->dma_blockpool_max);
+ vxge_debug_ll_config(VXGE_TRACE, "intr_mode : %d",
+ device_config->intr_mode);
+ vxge_debug_ll_config(VXGE_TRACE, "device_poll_millis : %d",
+ device_config->device_poll_millis);
+ vxge_debug_ll_config(VXGE_TRACE, "rts_mac_en : %d",
+ device_config->rts_mac_en);
+ vxge_debug_ll_config(VXGE_TRACE, "rth_en : %d",
+ device_config->rth_en);
+ vxge_debug_ll_config(VXGE_TRACE, "rth_it_type : %d",
+ device_config->rth_it_type);
+}
+
+static void __devinit vxge_print_parm(struct vxgedev *vdev, u64 vpath_mask)
+{
+ int i;
+
+ vxge_debug_init(VXGE_TRACE,
+ "%s: %d Vpath(s) opened",
+ vdev->ndev->name, vdev->no_of_vpath);
+
+ switch (vdev->config.intr_type) {
+ case INTA:
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Interrupt type INTA", vdev->ndev->name);
+ break;
+
+ case MSI_X:
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Interrupt type MSI-X", vdev->ndev->name);
+ break;
+ }
+
+ if (vdev->config.rth_steering) {
+ vxge_debug_init(VXGE_TRACE,
+ "%s: RTH steering enabled for TCP_IPV4",
+ vdev->ndev->name);
+ } else {
+ vxge_debug_init(VXGE_TRACE,
+ "%s: RTH steering disabled", vdev->ndev->name);
+ }
+
+ switch (vdev->config.tx_steering_type) {
+ case NO_STEERING:
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Tx steering disabled", vdev->ndev->name);
+ break;
+ case TX_PRIORITY_STEERING:
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Unsupported tx steering option",
+ vdev->ndev->name);
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Tx steering disabled", vdev->ndev->name);
+ vdev->config.tx_steering_type = 0;
+ break;
+ case TX_VLAN_STEERING:
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Unsupported tx steering option",
+ vdev->ndev->name);
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Tx steering disabled", vdev->ndev->name);
+ vdev->config.tx_steering_type = 0;
+ break;
+ case TX_MULTIQ_STEERING:
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Tx multiqueue steering enabled",
+ vdev->ndev->name);
+ break;
+ case TX_PORT_STEERING:
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Tx port steering enabled",
+ vdev->ndev->name);
+ break;
+ default:
+ vxge_debug_init(VXGE_ERR,
+ "%s: Unsupported tx steering type",
+ vdev->ndev->name);
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Tx steering disabled", vdev->ndev->name);
+ vdev->config.tx_steering_type = 0;
+ }
+
+ if (vdev->config.gro_enable) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: Generic receive offload enabled",
+ vdev->ndev->name);
+ } else
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Generic receive offload disabled",
+ vdev->ndev->name);
+
+ if (vdev->config.addr_learn_en)
+ vxge_debug_init(VXGE_TRACE,
+ "%s: MAC Address learning enabled", vdev->ndev->name);
+
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Rx doorbell mode enabled", vdev->ndev->name);
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+ if (!vxge_bVALn(vpath_mask, i, 1))
+ continue;
+ vxge_debug_ll_config(VXGE_TRACE,
+ "%s: MTU size - %d", vdev->ndev->name,
+ ((struct __vxge_hw_device *)(vdev->devh))->
+ config.vp_config[i].mtu);
+ vxge_debug_init(VXGE_TRACE,
+ "%s: VLAN tag stripping %s", vdev->ndev->name,
+ ((struct __vxge_hw_device *)(vdev->devh))->
+ config.vp_config[i].rpa_strip_vlan_tag
+ ? "Enabled" : "Disabled");
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Ring blocks : %d", vdev->ndev->name,
+ ((struct __vxge_hw_device *)(vdev->devh))->
+ config.vp_config[i].ring.ring_blocks);
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Fifo blocks : %d", vdev->ndev->name,
+ ((struct __vxge_hw_device *)(vdev->devh))->
+ config.vp_config[i].fifo.fifo_blocks);
+ vxge_debug_ll_config(VXGE_TRACE,
+ "%s: Max frags : %d", vdev->ndev->name,
+ ((struct __vxge_hw_device *)(vdev->devh))->
+ config.vp_config[i].fifo.max_frags);
+ break;
+ }
+}
+
+#ifdef CONFIG_PM
+/**
+ * vxge_pm_suspend - vxge power management suspend entry point
+ *
+ */
+static int vxge_pm_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ return -ENOSYS;
+}
+/**
+ * vxge_pm_resume - vxge power management resume entry point
+ *
+ */
+static int vxge_pm_resume(struct pci_dev *pdev)
+{
+ return -ENOSYS;
+}
+
+#endif
+
+/**
+ * vxge_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t vxge_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state)
+{
+ struct __vxge_hw_device *hldev =
+ (struct __vxge_hw_device *) pci_get_drvdata(pdev);
+ struct net_device *netdev = hldev->ndev;
+
+ netif_device_detach(netdev);
+
+ if (netif_running(netdev)) {
+ /* Bring down the card, while avoiding PCI I/O */
+ do_vxge_close(netdev, 0);
+ }
+
+ pci_disable_device(pdev);
+
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * vxge_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot.
+ * At this point, the card has exprienced a hard reset,
+ * followed by fixups by BIOS, and has its config space
+ * set up identically to what it was at cold boot.
+ */
+static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev)
+{
+ struct __vxge_hw_device *hldev =
+ (struct __vxge_hw_device *) pci_get_drvdata(pdev);
+ struct net_device *netdev = hldev->ndev;
+
+ struct vxgedev *vdev = netdev_priv(netdev);
+
+ if (pci_enable_device(pdev)) {
+ printk(KERN_ERR "%s: "
+ "Cannot re-enable device after reset\n",
+ VXGE_DRIVER_NAME);
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+
+ pci_set_master(pdev);
+ vxge_reset(vdev);
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * vxge_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells
+ * us that its OK to resume normal operation.
+ */
+static void vxge_io_resume(struct pci_dev *pdev)
+{
+ struct __vxge_hw_device *hldev =
+ (struct __vxge_hw_device *) pci_get_drvdata(pdev);
+ struct net_device *netdev = hldev->ndev;
+
+ if (netif_running(netdev)) {
+ if (vxge_open(netdev)) {
+ printk(KERN_ERR "%s: "
+ "Can't bring device back up after reset\n",
+ VXGE_DRIVER_NAME);
+ return;
+ }
+ }
+
+ netif_device_attach(netdev);
+}
+
+/**
+ * vxge_probe
+ * @pdev : structure containing the PCI related information of the device.
+ * @pre: List of PCI devices supported by the driver listed in vxge_id_table.
+ * Description:
+ * This function is called when a new PCI device gets detected and initializes
+ * it.
+ * Return value:
+ * returns 0 on success and negative on failure.
+ *
+ */
+static int __devinit
+vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
+{
+ struct __vxge_hw_device *hldev;
+ enum vxge_hw_status status;
+ int ret;
+ int high_dma = 0;
+ u64 vpath_mask = 0;
+ struct vxgedev *vdev;
+ struct vxge_config ll_config;
+ struct vxge_hw_device_config *device_config = NULL;
+ struct vxge_hw_device_attr attr;
+ int i, j, no_of_vpath = 0, max_vpath_supported = 0;
+ u8 *macaddr;
+ struct vxge_mac_addrs *entry;
+ static int bus = -1, device = -1;
+ u8 new_device = 0;
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s:%d", __func__, __LINE__);
+ attr.pdev = pdev;
+
+ if (bus != pdev->bus->number)
+ new_device = 1;
+ if (device != PCI_SLOT(pdev->devfn))
+ new_device = 1;
+
+ bus = pdev->bus->number;
+ device = PCI_SLOT(pdev->devfn);
+
+ if (new_device) {
+ if (driver_config->config_dev_cnt &&
+ (driver_config->config_dev_cnt !=
+ driver_config->total_dev_cnt))
+ vxge_debug_init(VXGE_ERR,
+ "%s: Configured %d of %d devices",
+ VXGE_DRIVER_NAME,
+ driver_config->config_dev_cnt,
+ driver_config->total_dev_cnt);
+ driver_config->config_dev_cnt = 0;
+ driver_config->total_dev_cnt = 0;
+ driver_config->g_no_cpus = 0;
+ driver_config->vpath_per_dev = max_config_vpath;
+ }
+
+ driver_config->total_dev_cnt++;
+ if (++driver_config->config_dev_cnt > max_config_dev) {
+ ret = 0;
+ goto _exit0;
+ }
+
+ device_config = kzalloc(sizeof(struct vxge_hw_device_config),
+ GFP_KERNEL);
+ if (!device_config) {
+ ret = -ENOMEM;
+ vxge_debug_init(VXGE_ERR,
+ "device_config : malloc failed %s %d",
+ __FILE__, __LINE__);
+ goto _exit0;
+ }
+
+ memset(&ll_config, 0, sizeof(struct vxge_config));
+ ll_config.tx_steering_type = TX_MULTIQ_STEERING;
+ ll_config.intr_type = MSI_X;
+ ll_config.napi_weight = NEW_NAPI_WEIGHT;
+ ll_config.rth_steering = RTH_STEERING;
+
+ /* get the default configuration parameters */
+ vxge_hw_device_config_default_get(device_config);
+
+ /* initialize configuration parameters */
+ vxge_device_config_init(device_config, &ll_config.intr_type);
+
+ ret = pci_enable_device(pdev);
+ if (ret) {
+ vxge_debug_init(VXGE_ERR,
+ "%s : can not enable PCI device", __func__);
+ goto _exit0;
+ }
+
+ if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
+ vxge_debug_ll_config(VXGE_TRACE,
+ "%s : using 64bit DMA", __func__);
+
+ high_dma = 1;
+
+ if (pci_set_consistent_dma_mask(pdev,
+ 0xffffffffffffffffULL)) {
+ vxge_debug_init(VXGE_ERR,
+ "%s : unable to obtain 64bit DMA for "
+ "consistent allocations", __func__);
+ ret = -ENOMEM;
+ goto _exit1;
+ }
+ } else if (!pci_set_dma_mask(pdev, 0xffffffffUL)) {
+ vxge_debug_ll_config(VXGE_TRACE,
+ "%s : using 32bit DMA", __func__);
+ } else {
+ ret = -ENOMEM;
+ goto _exit1;
+ }
+
+ if (pci_request_regions(pdev, VXGE_DRIVER_NAME)) {
+ vxge_debug_init(VXGE_ERR,
+ "%s : request regions failed", __func__);
+ ret = -ENODEV;
+ goto _exit1;
+ }
+
+ pci_set_master(pdev);
+
+ attr.bar0 = pci_ioremap_bar(pdev, 0);
+ if (!attr.bar0) {
+ vxge_debug_init(VXGE_ERR,
+ "%s : cannot remap io memory bar0", __func__);
+ ret = -ENODEV;
+ goto _exit2;
+ }
+ vxge_debug_ll_config(VXGE_TRACE,
+ "pci ioremap bar0: %p:0x%llx",
+ attr.bar0,
+ (unsigned long long)pci_resource_start(pdev, 0));
+
+ attr.bar1 = pci_ioremap_bar(pdev, 2);
+ if (!attr.bar1) {
+ vxge_debug_init(VXGE_ERR,
+ "%s : cannot remap io memory bar2", __func__);
+ ret = -ENODEV;
+ goto _exit3;
+ }
+ vxge_debug_ll_config(VXGE_TRACE,
+ "pci ioremap bar1: %p:0x%llx",
+ attr.bar1,
+ (unsigned long long)pci_resource_start(pdev, 2));
+
+ status = vxge_hw_device_hw_info_get(attr.bar0,
+ &ll_config.device_hw_info);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: Reading of hardware info failed."
+ "Please try upgrading the firmware.", VXGE_DRIVER_NAME);
+ ret = -EINVAL;
+ goto _exit4;
+ }
+
+ if (ll_config.device_hw_info.fw_version.major !=
+ VXGE_DRIVER_VERSION_MAJOR) {
+ vxge_debug_init(VXGE_ERR,
+ "FW Ver.(maj): %d not driver's expected version: %d",
+ ll_config.device_hw_info.fw_version.major,
+ VXGE_DRIVER_VERSION_MAJOR);
+ ret = -EINVAL;
+ goto _exit4;
+ }
+
+ vpath_mask = ll_config.device_hw_info.vpath_mask;
+ if (vpath_mask == 0) {
+ vxge_debug_ll_config(VXGE_TRACE,
+ "%s: No vpaths available in device", VXGE_DRIVER_NAME);
+ ret = -EINVAL;
+ goto _exit4;
+ }
+
+ vxge_debug_ll_config(VXGE_TRACE,
+ "%s:%d Vpath mask = %llx", __func__, __LINE__,
+ (unsigned long long)vpath_mask);
+
+ /* Check how many vpaths are available */
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+ if (!((vpath_mask) & vxge_mBIT(i)))
+ continue;
+ max_vpath_supported++;
+ }
+
+ /*
+ * Configure vpaths and get driver configured number of vpaths
+ * which is less than or equal to the maximum vpaths per function.
+ */
+ no_of_vpath = vxge_config_vpaths(device_config, vpath_mask, &ll_config);
+ if (!no_of_vpath) {
+ vxge_debug_ll_config(VXGE_ERR,
+ "%s: No more vpaths to configure", VXGE_DRIVER_NAME);
+ ret = 0;
+ goto _exit4;
+ }
+
+ /* Setting driver callbacks */
+ attr.uld_callbacks.link_up = vxge_callback_link_up;
+ attr.uld_callbacks.link_down = vxge_callback_link_down;
+ attr.uld_callbacks.crit_err = vxge_callback_crit_err;
+
+ status = vxge_hw_device_initialize(&hldev, &attr, device_config);
+ if (status != VXGE_HW_OK) {
+ vxge_debug_init(VXGE_ERR,
+ "Failed to initialize device (%d)", status);
+ ret = -EINVAL;
+ goto _exit4;
+ }
+
+ vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_LL);
+
+ /* set private device info */
+ pci_set_drvdata(pdev, hldev);
+
+ ll_config.gro_enable = VXGE_GRO_ALWAYS_AGGREGATE;
+ ll_config.fifo_indicate_max_pkts = VXGE_FIFO_INDICATE_MAX_PKTS;
+ ll_config.addr_learn_en = addr_learn_en;
+ ll_config.rth_algorithm = RTH_ALG_JENKINS;
+ ll_config.rth_hash_type_tcpipv4 = VXGE_HW_RING_HASH_TYPE_TCP_IPV4;
+ ll_config.rth_hash_type_ipv4 = VXGE_HW_RING_HASH_TYPE_NONE;
+ ll_config.rth_hash_type_tcpipv6 = VXGE_HW_RING_HASH_TYPE_NONE;
+ ll_config.rth_hash_type_ipv6 = VXGE_HW_RING_HASH_TYPE_NONE;
+ ll_config.rth_hash_type_tcpipv6ex = VXGE_HW_RING_HASH_TYPE_NONE;
+ ll_config.rth_hash_type_ipv6ex = VXGE_HW_RING_HASH_TYPE_NONE;
+ ll_config.rth_bkt_sz = RTH_BUCKET_SIZE;
+ ll_config.tx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
+ ll_config.rx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
+
+ if (vxge_device_register(hldev, &ll_config, high_dma, no_of_vpath,
+ &vdev)) {
+ ret = -EINVAL;
+ goto _exit5;
+ }
+
+ vxge_hw_device_debug_set(hldev, VXGE_TRACE, VXGE_COMPONENT_LL);
+ VXGE_COPY_DEBUG_INFO_TO_LL(vdev, vxge_hw_device_error_level_get(hldev),
+ vxge_hw_device_trace_level_get(hldev));
+
+ /* set private HW device info */
+ hldev->ndev = vdev->ndev;
+ vdev->mtu = VXGE_HW_DEFAULT_MTU;
+ vdev->bar0 = attr.bar0;
+ vdev->bar1 = attr.bar1;
+ vdev->max_vpath_supported = max_vpath_supported;
+ vdev->no_of_vpath = no_of_vpath;
+
+ /* Virtual Path count */
+ for (i = 0, j = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+ if (!vxge_bVALn(vpath_mask, i, 1))
+ continue;
+ if (j >= vdev->no_of_vpath)
+ break;
+
+ vdev->vpaths[j].is_configured = 1;
+ vdev->vpaths[j].device_id = i;
+ vdev->vpaths[j].fifo.driver_id = j;
+ vdev->vpaths[j].ring.driver_id = j;
+ vdev->vpaths[j].vdev = vdev;
+ vdev->vpaths[j].max_mac_addr_cnt = max_mac_vpath;
+ memcpy((u8 *)vdev->vpaths[j].macaddr,
+ (u8 *)ll_config.device_hw_info.mac_addrs[i],
+ ETH_ALEN);
+
+ /* Initialize the mac address list header */
+ INIT_LIST_HEAD(&vdev->vpaths[j].mac_addr_list);
+
+ vdev->vpaths[j].mac_addr_cnt = 0;
+ vdev->vpaths[j].mcast_addr_cnt = 0;
+ j++;
+ }
+ vdev->exec_mode = VXGE_EXEC_MODE_DISABLE;
+ vdev->max_config_port = max_config_port;
+
+ vdev->vlan_tag_strip = vlan_tag_strip;
+
+ /* map the hashing selector table to the configured vpaths */
+ for (i = 0; i < vdev->no_of_vpath; i++)
+ vdev->vpath_selector[i] = vpath_selector[i];
+
+ macaddr = (u8 *)vdev->vpaths[0].macaddr;
+
+ ll_config.device_hw_info.serial_number[VXGE_HW_INFO_LEN - 1] = '\0';
+ ll_config.device_hw_info.product_desc[VXGE_HW_INFO_LEN - 1] = '\0';
+ ll_config.device_hw_info.part_number[VXGE_HW_INFO_LEN - 1] = '\0';
+
+ vxge_debug_init(VXGE_TRACE, "%s: SERIAL NUMBER: %s",
+ vdev->ndev->name, ll_config.device_hw_info.serial_number);
+
+ vxge_debug_init(VXGE_TRACE, "%s: PART NUMBER: %s",
+ vdev->ndev->name, ll_config.device_hw_info.part_number);
+
+ vxge_debug_init(VXGE_TRACE, "%s: Neterion %s Server Adapter",
+ vdev->ndev->name, ll_config.device_hw_info.product_desc);
+
+ vxge_debug_init(VXGE_TRACE,
+ "%s: MAC ADDR: %02X:%02X:%02X:%02X:%02X:%02X",
+ vdev->ndev->name, macaddr[0], macaddr[1], macaddr[2],
+ macaddr[3], macaddr[4], macaddr[5]);
+
+ vxge_debug_init(VXGE_TRACE, "%s: Link Width x%d",
+ vdev->ndev->name, vxge_hw_device_link_width_get(hldev));
+
+ vxge_debug_init(VXGE_TRACE,
+ "%s: Firmware version : %s Date : %s", vdev->ndev->name,
+ ll_config.device_hw_info.fw_version.version,
+ ll_config.device_hw_info.fw_date.date);
+
+ vxge_print_parm(vdev, vpath_mask);
+
+ /* Store the fw version for ethttool option */
+ strcpy(vdev->fw_version, ll_config.device_hw_info.fw_version.version);
+ memcpy(vdev->ndev->dev_addr, (u8 *)vdev->vpaths[0].macaddr, ETH_ALEN);
+ memcpy(vdev->ndev->perm_addr, vdev->ndev->dev_addr, ETH_ALEN);
+
+ /* Copy the station mac address to the list */
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ entry = (struct vxge_mac_addrs *)
+ kzalloc(sizeof(struct vxge_mac_addrs),
+ GFP_KERNEL);
+ if (NULL == entry) {
+ vxge_debug_init(VXGE_ERR,
+ "%s: mac_addr_list : memory allocation failed",
+ vdev->ndev->name);
+ ret = -EPERM;
+ goto _exit6;
+ }
+ macaddr = (u8 *)&entry->macaddr;
+ memcpy(macaddr, vdev->ndev->dev_addr, ETH_ALEN);
+ list_add(&entry->item, &vdev->vpaths[i].mac_addr_list);
+ vdev->vpaths[i].mac_addr_cnt = 1;
+ }
+
+ vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d Exiting...",
+ vdev->ndev->name, __func__, __LINE__);
+
+ vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_LL);
+ VXGE_COPY_DEBUG_INFO_TO_LL(vdev, vxge_hw_device_error_level_get(hldev),
+ vxge_hw_device_trace_level_get(hldev));
+
+ return 0;
+
+_exit6:
+ for (i = 0; i < vdev->no_of_vpath; i++)
+ vxge_free_mac_add_list(&vdev->vpaths[i]);
+
+ vxge_device_unregister(hldev);
+_exit5:
+ vxge_hw_device_terminate(hldev);
+_exit4:
+ iounmap(attr.bar1);
+_exit3:
+ iounmap(attr.bar0);
+_exit2:
+ pci_release_regions(pdev);
+_exit1:
+ pci_disable_device(pdev);
+_exit0:
+ kfree(device_config);
+ driver_config->config_dev_cnt--;
+ pci_set_drvdata(pdev, NULL);
+ return ret;
+}
+
+/**
+ * vxge_rem_nic - Free the PCI device
+ * @pdev: structure containing the PCI related information of the device.
+ * Description: This function is called by the Pci subsystem to release a
+ * PCI device and free up all resource held up by the device.
+ */
+static void __devexit
+vxge_remove(struct pci_dev *pdev)
+{
+ struct __vxge_hw_device *hldev;
+ struct vxgedev *vdev = NULL;
+ struct net_device *dev;
+ int i = 0;
+#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \
+ (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK))
+ u32 level_trace;
+#endif
+
+ hldev = (struct __vxge_hw_device *) pci_get_drvdata(pdev);
+
+ if (hldev == NULL)
+ return;
+ dev = hldev->ndev;
+ vdev = netdev_priv(dev);
+
+#if ((VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) || \
+ (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK))
+ level_trace = vdev->level_trace;
+#endif
+ vxge_debug_entryexit(level_trace,
+ "%s:%d", __func__, __LINE__);
+
+ vxge_debug_init(level_trace,
+ "%s : removing PCI device...", __func__);
+ vxge_device_unregister(hldev);
+
+ for (i = 0; i < vdev->no_of_vpath; i++) {
+ vxge_free_mac_add_list(&vdev->vpaths[i]);
+ vdev->vpaths[i].mcast_addr_cnt = 0;
+ vdev->vpaths[i].mac_addr_cnt = 0;
+ }
+
+ kfree(vdev->vpaths);
+
+ iounmap(vdev->bar0);
+ iounmap(vdev->bar1);
+
+ /* we are safe to free it now */
+ free_netdev(dev);
+
+ vxge_debug_init(level_trace,
+ "%s:%d Device unregistered", __func__, __LINE__);
+
+ vxge_hw_device_terminate(hldev);
+
+ pci_disable_device(pdev);
+ pci_release_regions(pdev);
+ pci_set_drvdata(pdev, NULL);
+ vxge_debug_entryexit(level_trace,
+ "%s:%d Exiting...", __func__, __LINE__);
+}
+
+static struct pci_error_handlers vxge_err_handler = {
+ .error_detected = vxge_io_error_detected,
+ .slot_reset = vxge_io_slot_reset,
+ .resume = vxge_io_resume,
+};
+
+static struct pci_driver vxge_driver = {
+ .name = VXGE_DRIVER_NAME,
+ .id_table = vxge_id_table,
+ .probe = vxge_probe,
+ .remove = __devexit_p(vxge_remove),
+#ifdef CONFIG_PM
+ .suspend = vxge_pm_suspend,
+ .resume = vxge_pm_resume,
+#endif
+ .err_handler = &vxge_err_handler,
+};
+
+static int __init
+vxge_starter(void)
+{
+ int ret = 0;
+ char version[32];
+ snprintf(version, 32, "%s", DRV_VERSION);
+
+ printk(KERN_CRIT "%s: Copyright(c) 2002-2009 Neterion Inc\n",
+ VXGE_DRIVER_NAME);
+ printk(KERN_CRIT "%s: Driver version: %s\n",
+ VXGE_DRIVER_NAME, version);
+
+ verify_bandwidth();
+
+ driver_config = kzalloc(sizeof(struct vxge_drv_config), GFP_KERNEL);
+ if (!driver_config)
+ return -ENOMEM;
+
+ ret = pci_register_driver(&vxge_driver);
+
+ if (driver_config->config_dev_cnt &&
+ (driver_config->config_dev_cnt != driver_config->total_dev_cnt))
+ vxge_debug_init(VXGE_ERR,
+ "%s: Configured %d of %d devices",
+ VXGE_DRIVER_NAME, driver_config->config_dev_cnt,
+ driver_config->total_dev_cnt);
+
+ if (ret)
+ kfree(driver_config);
+
+ return ret;
+}
+
+static void __exit
+vxge_closer(void)
+{
+ pci_unregister_driver(&vxge_driver);
+ kfree(driver_config);
+}
+module_init(vxge_starter);
+module_exit(vxge_closer);
diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h
new file mode 100644
index 000000000000..9704b2bd4320
--- /dev/null
+++ b/drivers/net/vxge/vxge-main.h
@@ -0,0 +1,557 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice. This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-main.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#ifndef VXGE_MAIN_H
+#define VXGE_MAIN_H
+
+#include "vxge-traffic.h"
+#include "vxge-config.h"
+#include "vxge-version.h"
+#include <linux/list.h>
+
+#define VXGE_DRIVER_NAME "vxge"
+#define VXGE_DRIVER_VENDOR "Neterion, Inc"
+#define VXGE_DRIVER_VERSION_MAJOR 0
+
+#define DRV_VERSION VXGE_VERSION_MAJOR"."VXGE_VERSION_MINOR"."\
+ VXGE_VERSION_FIX"."VXGE_VERSION_BUILD"-"\
+ VXGE_VERSION_FOR
+
+#define PCI_DEVICE_ID_TITAN_WIN 0x5733
+#define PCI_DEVICE_ID_TITAN_UNI 0x5833
+#define VXGE_USE_DEFAULT 0xffffffff
+#define VXGE_HW_VPATH_MSIX_ACTIVE 4
+#define VXGE_HW_RXSYNC_FREQ_CNT 4
+#define VXGE_LL_WATCH_DOG_TIMEOUT (15 * HZ)
+#define VXGE_LL_RX_COPY_THRESHOLD 256
+#define VXGE_DEF_FIFO_LENGTH 84
+
+#define NO_STEERING 0
+#define PORT_STEERING 0x1
+#define RTH_STEERING 0x2
+#define RX_TOS_STEERING 0x3
+#define RX_VLAN_STEERING 0x4
+#define RTH_BUCKET_SIZE 4
+
+#define TX_PRIORITY_STEERING 1
+#define TX_VLAN_STEERING 2
+#define TX_PORT_STEERING 3
+#define TX_MULTIQ_STEERING 4
+
+#define VXGE_HW_MAC_ADDR_LEARN_DEFAULT VXGE_HW_RTS_MAC_DISABLE
+
+#define VXGE_TTI_BTIMER_VAL 250000
+
+#define VXGE_TTI_LTIMER_VAL 1000
+#define VXGE_TTI_RTIMER_VAL 0
+#define VXGE_RTI_BTIMER_VAL 250
+#define VXGE_RTI_LTIMER_VAL 100
+#define VXGE_RTI_RTIMER_VAL 0
+#define VXGE_FIFO_INDICATE_MAX_PKTS VXGE_DEF_FIFO_LENGTH
+#define VXGE_ISR_POLLING_CNT 8
+#define VXGE_MAX_CONFIG_DEV 0xFF
+#define VXGE_EXEC_MODE_DISABLE 0
+#define VXGE_EXEC_MODE_ENABLE 1
+#define VXGE_MAX_CONFIG_PORT 1
+#define VXGE_ALL_VID_DISABLE 0
+#define VXGE_ALL_VID_ENABLE 1
+#define VXGE_PAUSE_CTRL_DISABLE 0
+#define VXGE_PAUSE_CTRL_ENABLE 1
+
+#define TTI_TX_URANGE_A 5
+#define TTI_TX_URANGE_B 15
+#define TTI_TX_URANGE_C 40
+#define TTI_TX_UFC_A 5
+#define TTI_TX_UFC_B 40
+#define TTI_TX_UFC_C 60
+#define TTI_TX_UFC_D 100
+
+#define RTI_RX_URANGE_A 5
+#define RTI_RX_URANGE_B 15
+#define RTI_RX_URANGE_C 40
+#define RTI_RX_UFC_A 1
+#define RTI_RX_UFC_B 5
+#define RTI_RX_UFC_C 10
+#define RTI_RX_UFC_D 15
+
+/* Milli secs timer period */
+#define VXGE_TIMER_DELAY 10000
+
+#define VXGE_LL_MAX_FRAME_SIZE(dev) ((dev)->mtu + VXGE_HW_MAC_HEADER_MAX_SIZE)
+
+enum vxge_reset_event {
+ /* reset events */
+ VXGE_LL_VPATH_RESET = 0,
+ VXGE_LL_DEVICE_RESET = 1,
+ VXGE_LL_FULL_RESET = 2,
+ VXGE_LL_START_RESET = 3,
+ VXGE_LL_COMPL_RESET = 4
+};
+/* These flags represent the devices temporary state */
+enum vxge_device_state_t {
+__VXGE_STATE_RESET_CARD = 0,
+__VXGE_STATE_CARD_UP
+};
+
+enum vxge_mac_addr_state {
+ /* mac address states */
+ VXGE_LL_MAC_ADDR_IN_LIST = 0,
+ VXGE_LL_MAC_ADDR_IN_DA_TABLE = 1
+};
+
+struct vxge_drv_config {
+ int config_dev_cnt;
+ int total_dev_cnt;
+ unsigned long inta_dev_open;
+ int g_no_cpus;
+ unsigned int vpath_per_dev;
+};
+
+struct macInfo {
+ unsigned char macaddr[ETH_ALEN];
+ unsigned char macmask[ETH_ALEN];
+ unsigned int vpath_no;
+ enum vxge_mac_addr_state state;
+};
+
+struct vxge_config {
+ int tx_pause_enable;
+ int rx_pause_enable;
+
+#define NEW_NAPI_WEIGHT 64
+ int napi_weight;
+#define VXGE_GRO_DONOT_AGGREGATE 0
+#define VXGE_GRO_ALWAYS_AGGREGATE 1
+ int gro_enable;
+ int intr_type;
+#define INTA 0
+#define MSI 1
+#define MSI_X 2
+
+ int addr_learn_en;
+
+ int rth_steering;
+ int rth_algorithm;
+ int rth_hash_type_tcpipv4;
+ int rth_hash_type_ipv4;
+ int rth_hash_type_tcpipv6;
+ int rth_hash_type_ipv6;
+ int rth_hash_type_tcpipv6ex;
+ int rth_hash_type_ipv6ex;
+ int rth_bkt_sz;
+ int rth_jhash_golden_ratio;
+ int tx_steering_type;
+ int fifo_indicate_max_pkts;
+ struct vxge_hw_device_hw_info device_hw_info;
+};
+
+struct vxge_msix_entry {
+ /* Mimicing the msix_entry struct of Kernel. */
+ u16 vector;
+ u16 entry;
+ u16 in_use;
+ void *arg;
+};
+
+/* Software Statistics */
+
+struct vxge_sw_stats {
+ /* Network Stats (interface stats) */
+ struct net_device_stats net_stats;
+
+ /* Tx */
+ u64 tx_frms;
+ u64 tx_errors;
+ u64 tx_bytes;
+ u64 txd_not_free;
+ u64 txd_out_of_desc;
+
+ /* Virtual Path */
+ u64 vpaths_open;
+ u64 vpath_open_fail;
+
+ /* Rx */
+ u64 rx_frms;
+ u64 rx_errors;
+ u64 rx_bytes;
+ u64 rx_mcast;
+
+ /* Misc. */
+ u64 link_up;
+ u64 link_down;
+ u64 pci_map_fail;
+ u64 skb_alloc_fail;
+};
+
+struct vxge_mac_addrs {
+ struct list_head item;
+ u64 macaddr;
+ u64 macmask;
+ enum vxge_mac_addr_state state;
+};
+
+struct vxgedev;
+
+struct vxge_fifo_stats {
+ u64 tx_frms;
+ u64 tx_errors;
+ u64 tx_bytes;
+ u64 txd_not_free;
+ u64 txd_out_of_desc;
+ u64 pci_map_fail;
+};
+
+struct vxge_fifo {
+ struct net_device *ndev;
+ struct pci_dev *pdev;
+ struct __vxge_hw_fifo *handle;
+
+ /* The vpath id maintained in the driver -
+ * 0 to 'maximum_vpaths_in_function - 1'
+ */
+ int driver_id;
+ int tx_steering_type;
+ int indicate_max_pkts;
+ spinlock_t tx_lock;
+ /* flag used to maintain queue state when MULTIQ is not enabled */
+#define VPATH_QUEUE_START 0
+#define VPATH_QUEUE_STOP 1
+ int queue_state;
+
+ /* Tx stats */
+ struct vxge_fifo_stats stats;
+} ____cacheline_aligned;
+
+struct vxge_ring_stats {
+ u64 prev_rx_frms;
+ u64 rx_frms;
+ u64 rx_errors;
+ u64 rx_dropped;
+ u64 rx_bytes;
+ u64 rx_mcast;
+ u64 pci_map_fail;
+ u64 skb_alloc_fail;
+};
+
+struct vxge_ring {
+ struct net_device *ndev;
+ struct pci_dev *pdev;
+ struct __vxge_hw_ring *handle;
+ /* The vpath id maintained in the driver -
+ * 0 to 'maximum_vpaths_in_function - 1'
+ */
+ int driver_id;
+
+ /* copy of the flag indicating whether rx_csum is to be used */
+ u32 rx_csum;
+
+ int pkts_processed;
+ int budget;
+ int gro_enable;
+
+ struct napi_struct napi;
+
+#define VXGE_MAX_MAC_ADDR_COUNT 30
+
+ int vlan_tag_strip;
+ struct vlan_group *vlgrp;
+ int rx_vector_no;
+ enum vxge_hw_status last_status;
+
+ /* Rx stats */
+ struct vxge_ring_stats stats;
+} ____cacheline_aligned;
+
+struct vxge_vpath {
+
+ struct vxge_fifo fifo;
+ struct vxge_ring ring;
+
+ struct __vxge_hw_vpath_handle *handle;
+
+ /* Actual vpath id for this vpath in the device - 0 to 16 */
+ int device_id;
+ int max_mac_addr_cnt;
+ int is_configured;
+ int is_open;
+ struct vxgedev *vdev;
+ u8 (macaddr)[ETH_ALEN];
+ u8 (macmask)[ETH_ALEN];
+
+#define VXGE_MAX_LEARN_MAC_ADDR_CNT 2048
+ /* mac addresses currently programmed into NIC */
+ u16 mac_addr_cnt;
+ u16 mcast_addr_cnt;
+ struct list_head mac_addr_list;
+
+ u32 level_err;
+ u32 level_trace;
+};
+#define VXGE_COPY_DEBUG_INFO_TO_LL(vdev, err, trace) { \
+ for (i = 0; i < vdev->no_of_vpath; i++) { \
+ vdev->vpaths[i].level_err = err; \
+ vdev->vpaths[i].level_trace = trace; \
+ } \
+ vdev->level_err = err; \
+ vdev->level_trace = trace; \
+}
+
+struct vxgedev {
+ struct net_device *ndev;
+ struct pci_dev *pdev;
+ struct __vxge_hw_device *devh;
+ struct vlan_group *vlgrp;
+ int vlan_tag_strip;
+ struct vxge_config config;
+ unsigned long state;
+
+ /* Indicates which vpath to reset */
+ unsigned long vp_reset;
+
+ /* Timer used for polling vpath resets */
+ struct timer_list vp_reset_timer;
+
+ /* Timer used for polling vpath lockup */
+ struct timer_list vp_lockup_timer;
+
+ /*
+ * Flags to track whether device is in All Multicast
+ * or in promiscuous mode.
+ */
+ u16 all_multi_flg;
+
+ /* A flag indicating whether rx_csum is to be used or not. */
+ u32 rx_csum;
+
+ struct vxge_msix_entry *vxge_entries;
+ struct msix_entry *entries;
+ /*
+ * 4 for each vpath * 17;
+ * total is 68
+ */
+#define VXGE_MAX_REQUESTED_MSIX 68
+#define VXGE_INTR_STRLEN 80
+ char desc[VXGE_MAX_REQUESTED_MSIX][VXGE_INTR_STRLEN];
+
+ enum vxge_hw_event cric_err_event;
+
+ int max_vpath_supported;
+ int no_of_vpath;
+
+ struct napi_struct napi;
+ /* A debug option, when enabled and if error condition occurs,
+ * the driver will do following steps:
+ * - mask all interrupts
+ * - Not clear the source of the alarm
+ * - gracefully stop all I/O
+ * A diagnostic dump of register and stats at this point
+ * reveals very useful information.
+ */
+ int exec_mode;
+ int max_config_port;
+ struct vxge_vpath *vpaths;
+
+ struct __vxge_hw_vpath_handle *vp_handles[VXGE_HW_MAX_VIRTUAL_PATHS];
+ void __iomem *bar0;
+ void __iomem *bar1;
+ struct vxge_sw_stats stats;
+ int mtu;
+ /* Below variables are used for vpath selection to transmit a packet */
+ u8 vpath_selector[VXGE_HW_MAX_VIRTUAL_PATHS];
+ u64 vpaths_deployed;
+
+ u32 intr_cnt;
+ u32 level_err;
+ u32 level_trace;
+ char fw_version[VXGE_HW_FW_STRLEN];
+};
+
+struct vxge_rx_priv {
+ struct sk_buff *skb;
+ dma_addr_t data_dma;
+ dma_addr_t data_size;
+};
+
+struct vxge_tx_priv {
+ struct sk_buff *skb;
+ dma_addr_t dma_buffers[MAX_SKB_FRAGS+1];
+};
+
+#define VXGE_MODULE_PARAM_INT(p, val) \
+ static int p = val; \
+ module_param(p, int, 0)
+
+#define vxge_os_bug(fmt...) { printk(fmt); BUG(); }
+
+#define vxge_os_timer(timer, handle, arg, exp) do { \
+ init_timer(&timer); \
+ timer.function = handle; \
+ timer.data = (unsigned long) arg; \
+ mod_timer(&timer, (jiffies + exp)); \
+ } while (0);
+
+int __devinit vxge_device_register(struct __vxge_hw_device *devh,
+ struct vxge_config *config,
+ int high_dma, int no_of_vpath,
+ struct vxgedev **vdev);
+
+void vxge_device_unregister(struct __vxge_hw_device *devh);
+
+void vxge_vpath_intr_enable(struct vxgedev *vdev, int vp_id);
+
+void vxge_vpath_intr_disable(struct vxgedev *vdev, int vp_id);
+
+void vxge_callback_link_up(struct __vxge_hw_device *devh);
+
+void vxge_callback_link_down(struct __vxge_hw_device *devh);
+
+enum vxge_hw_status vxge_add_mac_addr(struct vxgedev *vdev,
+ struct macInfo *mac);
+
+int vxge_mac_list_del(struct vxge_vpath *vpath, struct macInfo *mac);
+
+int vxge_reset(struct vxgedev *vdev);
+
+enum vxge_hw_status
+vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
+ u8 t_code, void *userdata);
+
+enum vxge_hw_status
+vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
+ enum vxge_hw_fifo_tcode t_code, void *userdata, void **skb_ptr);
+
+int vxge_close(struct net_device *dev);
+
+int vxge_open(struct net_device *dev);
+
+void vxge_close_vpaths(struct vxgedev *vdev, int index);
+
+int vxge_open_vpaths(struct vxgedev *vdev);
+
+enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev);
+
+void vxge_stop_all_tx_queue(struct vxgedev *vdev);
+
+void vxge_stop_tx_queue(struct vxge_fifo *fifo);
+
+void vxge_start_all_tx_queue(struct vxgedev *vdev);
+
+void vxge_wake_tx_queue(struct vxge_fifo *fifo, struct sk_buff *skb);
+
+enum vxge_hw_status vxge_add_mac_addr(struct vxgedev *vdev,
+ struct macInfo *mac);
+
+enum vxge_hw_status vxge_del_mac_addr(struct vxgedev *vdev,
+ struct macInfo *mac);
+
+int vxge_mac_list_add(struct vxge_vpath *vpath,
+ struct macInfo *mac);
+
+void vxge_free_mac_add_list(struct vxge_vpath *vpath);
+
+enum vxge_hw_status vxge_restore_vpath_mac_addr(struct vxge_vpath *vpath);
+
+enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath);
+
+int do_vxge_close(struct net_device *dev, int do_io);
+extern void initialize_ethtool_ops(struct net_device *ndev);
+/**
+ * #define VXGE_DEBUG_INIT: debug for initialization functions
+ * #define VXGE_DEBUG_TX : debug transmit related functions
+ * #define VXGE_DEBUG_RX : debug recevice related functions
+ * #define VXGE_DEBUG_MEM : debug memory module
+ * #define VXGE_DEBUG_LOCK: debug locks
+ * #define VXGE_DEBUG_SEM : debug semaphore
+ * #define VXGE_DEBUG_ENTRYEXIT: debug functions by adding entry exit statements
+*/
+#define VXGE_DEBUG_INIT 0x00000001
+#define VXGE_DEBUG_TX 0x00000002
+#define VXGE_DEBUG_RX 0x00000004
+#define VXGE_DEBUG_MEM 0x00000008
+#define VXGE_DEBUG_LOCK 0x00000010
+#define VXGE_DEBUG_SEM 0x00000020
+#define VXGE_DEBUG_ENTRYEXIT 0x00000040
+#define VXGE_DEBUG_INTR 0x00000080
+#define VXGE_DEBUG_LL_CONFIG 0x00000100
+
+/* Debug tracing for VXGE driver */
+#ifndef VXGE_DEBUG_MASK
+#define VXGE_DEBUG_MASK 0x0
+#endif
+
+#if (VXGE_DEBUG_LL_CONFIG & VXGE_DEBUG_MASK)
+#define vxge_debug_ll_config(level, fmt, ...) \
+ vxge_debug_ll(level, VXGE_DEBUG_LL_CONFIG, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_ll_config(level, fmt, ...)
+#endif
+
+#if (VXGE_DEBUG_INIT & VXGE_DEBUG_MASK)
+#define vxge_debug_init(level, fmt, ...) \
+ vxge_debug_ll(level, VXGE_DEBUG_INIT, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_init(level, fmt, ...)
+#endif
+
+#if (VXGE_DEBUG_TX & VXGE_DEBUG_MASK)
+#define vxge_debug_tx(level, fmt, ...) \
+ vxge_debug_ll(level, VXGE_DEBUG_TX, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_tx(level, fmt, ...)
+#endif
+
+#if (VXGE_DEBUG_RX & VXGE_DEBUG_MASK)
+#define vxge_debug_rx(level, fmt, ...) \
+ vxge_debug_ll(level, VXGE_DEBUG_RX, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_rx(level, fmt, ...)
+#endif
+
+#if (VXGE_DEBUG_MEM & VXGE_DEBUG_MASK)
+#define vxge_debug_mem(level, fmt, ...) \
+ vxge_debug_ll(level, VXGE_DEBUG_MEM, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_mem(level, fmt, ...)
+#endif
+
+#if (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK)
+#define vxge_debug_entryexit(level, fmt, ...) \
+ vxge_debug_ll(level, VXGE_DEBUG_ENTRYEXIT, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_entryexit(level, fmt, ...)
+#endif
+
+#if (VXGE_DEBUG_INTR & VXGE_DEBUG_MASK)
+#define vxge_debug_intr(level, fmt, ...) \
+ vxge_debug_ll(level, VXGE_DEBUG_INTR, fmt, __VA_ARGS__)
+#else
+#define vxge_debug_intr(level, fmt, ...)
+#endif
+
+#define VXGE_DEVICE_DEBUG_LEVEL_SET(level, mask, vdev) {\
+ vxge_hw_device_debug_set((struct __vxge_hw_device *)vdev->devh, \
+ level, mask);\
+ VXGE_COPY_DEBUG_INFO_TO_LL(vdev, \
+ vxge_hw_device_error_level_get((struct __vxge_hw_device *) \
+ vdev->devh), \
+ vxge_hw_device_trace_level_get((struct __vxge_hw_device *) \
+ vdev->devh));\
+}
+
+#ifdef NETIF_F_GSO
+#define vxge_tcp_mss(skb) (skb_shinfo(skb)->gso_size)
+#define vxge_udp_mss(skb) (skb_shinfo(skb)->gso_size)
+#define vxge_offload_type(skb) (skb_shinfo(skb)->gso_type)
+#endif
+
+#endif
diff --git a/drivers/net/vxge/vxge-reg.h b/drivers/net/vxge/vxge-reg.h
new file mode 100644
index 000000000000..10f4da32929f
--- /dev/null
+++ b/drivers/net/vxge/vxge-reg.h
@@ -0,0 +1,4608 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice. This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-reg.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O Virtualized
+ * Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#ifndef VXGE_REG_H
+#define VXGE_REG_H
+
+/*
+ * vxge_mBIT(loc) - set bit at offset
+ */
+#define vxge_mBIT(loc) (0x8000000000000000ULL >> (loc))
+
+/*
+ * vxge_vBIT(val, loc, sz) - set bits at offset
+ */
+#define vxge_vBIT(val, loc, sz) (((u64)(val)) << (64-(loc)-(sz)))
+#define vxge_vBIT32(val, loc, sz) (((u32)(val)) << (32-(loc)-(sz)))
+
+/*
+ * vxge_bVALn(bits, loc, n) - Get the value of n bits at location
+ */
+#define vxge_bVALn(bits, loc, n) \
+ ((((u64)bits) >> (64-(loc+n))) & ((0x1ULL << n) - 1))
+
+#define VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_DEVICE_ID(bits) \
+ vxge_bVALn(bits, 0, 16)
+#define VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MAJOR_REVISION(bits) \
+ vxge_bVALn(bits, 48, 8)
+#define VXGE_HW_TITAN_ASIC_ID_GET_INITIAL_MINOR_REVISION(bits) \
+ vxge_bVALn(bits, 56, 8)
+
+#define VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_GET_VPATH_TO_FUNC_MAP_CFG1(bits) \
+ vxge_bVALn(bits, 3, 5)
+#define VXGE_HW_HOST_TYPE_ASSIGNMENTS_GET_HOST_TYPE_ASSIGNMENTS(bits) \
+ vxge_bVALn(bits, 5, 3)
+#define VXGE_HW_PF_SW_RESET_COMMAND 0xA5
+
+#define VXGE_HW_TITAN_PCICFGMGMT_REG_SPACES 17
+#define VXGE_HW_TITAN_SRPCIM_REG_SPACES 17
+#define VXGE_HW_TITAN_VPMGMT_REG_SPACES 17
+#define VXGE_HW_TITAN_VPATH_REG_SPACES 17
+
+#define VXGE_HW_ASIC_MODE_RESERVED 0
+#define VXGE_HW_ASIC_MODE_NO_IOV 1
+#define VXGE_HW_ASIC_MODE_SR_IOV 2
+#define VXGE_HW_ASIC_MODE_MR_IOV 3
+
+#define VXGE_HW_TXMAC_GEN_CFG1_TMAC_PERMA_STOP_EN vxge_mBIT(3)
+#define VXGE_HW_TXMAC_GEN_CFG1_BLOCK_BCAST_TO_WIRE vxge_mBIT(19)
+#define VXGE_HW_TXMAC_GEN_CFG1_BLOCK_BCAST_TO_SWITCH vxge_mBIT(23)
+#define VXGE_HW_TXMAC_GEN_CFG1_HOST_APPEND_FCS vxge_mBIT(31)
+
+#define VXGE_HW_VPATH_IS_FIRST_GET_VPATH_IS_FIRST(bits) vxge_bVALn(bits, 3, 1)
+
+#define VXGE_HW_TIM_VPATH_ASSIGNMENT_GET_BMAP_ROOT(bits) \
+ vxge_bVALn(bits, 0, 32)
+
+#define VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_GET_MAX_PYLD_LEN(bits) \
+ vxge_bVALn(bits, 50, 14)
+
+#define VXGE_HW_XMAC_VSPORT_CHOICES_VP_GET_VSPORT_VECTOR(bits) \
+ vxge_bVALn(bits, 0, 17)
+
+#define VXGE_HW_XMAC_VPATH_TO_VSPORT_VPMGMT_CLONE_GET_VSPORT_NUMBER(bits) \
+ vxge_bVALn(bits, 3, 5)
+
+#define VXGE_HW_KDFC_DRBL_TRIPLET_TOTAL_GET_KDFC_MAX_SIZE(bits) \
+ vxge_bVALn(bits, 17, 15)
+
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE_LEGACY_MODE 0
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE_NON_OFFLOAD_ONLY 1
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE_MULTI_OP_MODE 2
+
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_MODE_MESSAGES_ONLY 0
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_MODE_MULTI_OP_MODE 1
+
+#define VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val) \
+ (val&~VXGE_HW_TOC_KDFC_INITIAL_BIR(7))
+#define VXGE_HW_TOC_GET_KDFC_INITIAL_BIR(val) \
+ vxge_bVALn(val, 61, 3)
+#define VXGE_HW_TOC_GET_USDC_INITIAL_OFFSET(val) \
+ (val&~VXGE_HW_TOC_USDC_INITIAL_BIR(7))
+#define VXGE_HW_TOC_GET_USDC_INITIAL_BIR(val) \
+ vxge_bVALn(val, 61, 3)
+
+#define VXGE_HW_TOC_KDFC_VPATH_STRIDE_GET_TOC_KDFC_VPATH_STRIDE(bits) bits
+#define VXGE_HW_TOC_KDFC_FIFO_STRIDE_GET_TOC_KDFC_FIFO_STRIDE(bits) bits
+
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_GET_KDFC_RCTR0(bits) \
+ vxge_bVALn(bits, 1, 15)
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_GET_KDFC_RCTR1(bits) \
+ vxge_bVALn(bits, 17, 15)
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_GET_KDFC_RCTR2(bits) \
+ vxge_bVALn(bits, 33, 15)
+
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_KDFC_VAPTH_NUM(val) vxge_vBIT(val, 42, 5)
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_KDFC_FIFO_NUM(val) vxge_vBIT(val, 47, 2)
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_KDFC_FIFO_OFFSET(val) \
+ vxge_vBIT(val, 49, 15)
+
+#define VXGE_HW_PRC_CFG4_RING_MODE_ONE_BUFFER 0
+#define VXGE_HW_PRC_CFG4_RING_MODE_THREE_BUFFER 1
+#define VXGE_HW_PRC_CFG4_RING_MODE_FIVE_BUFFER 2
+
+#define VXGE_HW_PRC_CFG7_SCATTER_MODE_A 0
+#define VXGE_HW_PRC_CFG7_SCATTER_MODE_B 2
+#define VXGE_HW_PRC_CFG7_SCATTER_MODE_C 1
+
+#define VXGE_HW_RTS_MGR_STEER_CTRL_WE_READ 0
+#define VXGE_HW_RTS_MGR_STEER_CTRL_WE_WRITE 1
+
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_DA 0
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_VID 1
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_ETYPE 2
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_PN 3
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RANGE_PN 4
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG 5
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT 6
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RTH_JHASH_CFG 7
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK 8
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY 9
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_QOS 10
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_DS 11
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT 12
+#define VXGE_HW_RTS_MGR_STEER_CTRL_DATA_STRUCT_SEL_FW_VERSION 13
+
+#define VXGE_HW_RTS_MGR_STEER_DATA0_GET_DA_MAC_ADDR(bits) \
+ vxge_bVALn(bits, 0, 48)
+#define VXGE_HW_RTS_MGR_STEER_DATA0_DA_MAC_ADDR(val) vxge_vBIT(val, 0, 48)
+
+#define VXGE_HW_RTS_MGR_STEER_DATA1_GET_DA_MAC_ADDR_MASK(bits) \
+ vxge_bVALn(bits, 0, 48)
+#define VXGE_HW_RTS_MGR_STEER_DATA1_DA_MAC_ADDR_MASK(val) vxge_vBIT(val, 0, 48)
+#define VXGE_HW_RTS_MGR_STEER_DATA1_DA_MAC_ADDR_ADD_PRIVILEGED_MODE \
+ vxge_mBIT(54)
+#define VXGE_HW_RTS_MGR_STEER_DATA1_GET_DA_MAC_ADDR_ADD_VPATH(bits) \
+ vxge_bVALn(bits, 55, 5)
+#define VXGE_HW_RTS_MGR_STEER_DATA1_DA_MAC_ADDR_ADD_VPATH(val) \
+ vxge_vBIT(val, 55, 5)
+#define VXGE_HW_RTS_MGR_STEER_DATA1_GET_DA_MAC_ADDR_ADD_MODE(bits) \
+ vxge_bVALn(bits, 62, 2)
+#define VXGE_HW_RTS_MGR_STEER_DATA1_DA_MAC_ADDR_MODE(val) vxge_vBIT(val, 62, 2)
+
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_ADD_ENTRY 0
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_DELETE_ENTRY 1
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY 2
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_NEXT_ENTRY 3
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_ENTRY 0
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_WRITE_ENTRY 1
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_READ_MEMO_ENTRY 3
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LED_CONTROL 4
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_ALL_CLEAR 172
+
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA 0
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID 1
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_ETYPE 2
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_PN 3
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG 5
+#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT 6
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_JHASH_CFG 7
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK 8
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY 9
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_QOS 10
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DS 11
+#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT 12
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO 13
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(bits) \
+ vxge_bVALn(bits, 0, 48)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_DA_MAC_ADDR(val) vxge_vBIT(val, 0, 48)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_VLAN_ID(bits) vxge_bVALn(bits, 0, 12)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_VLAN_ID(val) vxge_vBIT(val, 0, 12)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_ETYPE(bits) vxge_bVALn(bits, 0, 11)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_ETYPE(val) vxge_vBIT(val, 0, 16)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_PN_SRC_DEST_SEL(bits) \
+ vxge_bVALn(bits, 3, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_PN_SRC_DEST_SEL vxge_mBIT(3)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_PN_TCP_UDP_SEL(bits) \
+ vxge_bVALn(bits, 7, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_PN_TCP_UDP_SEL vxge_mBIT(7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_PN_PORT_NUM(bits) \
+ vxge_bVALn(bits, 8, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_PN_PORT_NUM(val) vxge_vBIT(val, 8, 16)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_EN(bits) \
+ vxge_bVALn(bits, 3, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_EN vxge_mBIT(3)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_BUCKET_SIZE(bits) \
+ vxge_bVALn(bits, 4, 4)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_BUCKET_SIZE(val) \
+ vxge_vBIT(val, 4, 4)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_ALG_SEL(bits) \
+ vxge_bVALn(bits, 10, 2)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL(val) \
+ vxge_vBIT(val, 10, 2)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL_JENKINS 0
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL_MS_RSS 1
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ALG_SEL_CRC32C 2
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_TCP_IPV4_EN(bits) \
+ vxge_bVALn(bits, 15, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV4_EN vxge_mBIT(15)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_IPV4_EN(bits) \
+ vxge_bVALn(bits, 19, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV4_EN vxge_mBIT(19)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_TCP_IPV6_EN(bits) \
+ vxge_bVALn(bits, 23, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EN vxge_mBIT(23)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_IPV6_EN(bits) \
+ vxge_bVALn(bits, 27, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EN vxge_mBIT(27)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_TCP_IPV6_EX_EN(bits) \
+ vxge_bVALn(bits, 31, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_TCP_IPV6_EX_EN vxge_mBIT(31)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_RTH_IPV6_EX_EN(bits) \
+ vxge_bVALn(bits, 35, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_RTH_IPV6_EX_EN vxge_mBIT(35)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_ACTIVE_TABLE(bits) \
+ vxge_bVALn(bits, 39, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_ACTIVE_TABLE vxge_mBIT(39)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_GEN_REPL_ENTRY_EN(bits) \
+ vxge_bVALn(bits, 43, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_GEN_REPL_ENTRY_EN vxge_mBIT(43)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_SOLO_IT_ENTRY_EN(bits) \
+ vxge_bVALn(bits, 3, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_ENTRY_EN vxge_mBIT(3)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_SOLO_IT_BUCKET_DATA(bits) \
+ vxge_bVALn(bits, 9, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_SOLO_IT_BUCKET_DATA(val) \
+ vxge_vBIT(val, 9, 7)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_ITEM0_BUCKET_NUM(bits) \
+ vxge_bVALn(bits, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_NUM(val) \
+ vxge_vBIT(val, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_ITEM0_ENTRY_EN(bits) \
+ vxge_bVALn(bits, 8, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_ENTRY_EN vxge_mBIT(8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_ITEM0_BUCKET_DATA(bits) \
+ vxge_bVALn(bits, 9, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM0_BUCKET_DATA(val) \
+ vxge_vBIT(val, 9, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_ITEM1_BUCKET_NUM(bits) \
+ vxge_bVALn(bits, 16, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_NUM(val) \
+ vxge_vBIT(val, 16, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_ITEM1_ENTRY_EN(bits) \
+ vxge_bVALn(bits, 24, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_ENTRY_EN vxge_mBIT(24)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_ITEM1_BUCKET_DATA(bits) \
+ vxge_bVALn(bits, 25, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_ITEM1_BUCKET_DATA(val) \
+ vxge_vBIT(val, 25, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM0_BUCKET_NUM(bits) \
+ vxge_bVALn(bits, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_NUM(val) \
+ vxge_vBIT(val, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM0_ENTRY_EN(bits) \
+ vxge_bVALn(bits, 8, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_ENTRY_EN vxge_mBIT(8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM0_BUCKET_DATA(bits) \
+ vxge_bVALn(bits, 9, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM0_BUCKET_DATA(val) \
+ vxge_vBIT(val, 9, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM1_BUCKET_NUM(bits) \
+ vxge_bVALn(bits, 16, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_NUM(val) \
+ vxge_vBIT(val, 16, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM1_ENTRY_EN(bits) \
+ vxge_bVALn(bits, 24, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_ENTRY_EN vxge_mBIT(24)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM1_BUCKET_DATA(bits) \
+ vxge_bVALn(bits, 25, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM1_BUCKET_DATA(val) \
+ vxge_vBIT(val, 25, 7)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_JHASH_CFG_GOLDEN_RATIO(bits) \
+ vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_JHASH_CFG_GOLDEN_RATIO(val) \
+ vxge_vBIT(val, 0, 32)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_JHASH_CFG_INIT_VALUE(bits) \
+ vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_JHASH_CFG_INIT_VALUE(val) \
+ vxge_vBIT(val, 32, 32)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_MASK_IPV6_SA_MASK(bits) \
+ vxge_bVALn(bits, 0, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_MASK_IPV6_SA_MASK(val) \
+ vxge_vBIT(val, 0, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_MASK_IPV6_DA_MASK(bits) \
+ vxge_bVALn(bits, 16, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_MASK_IPV6_DA_MASK(val) \
+ vxge_vBIT(val, 16, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_MASK_IPV4_SA_MASK(bits) \
+ vxge_bVALn(bits, 32, 4)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_MASK_IPV4_SA_MASK(val) \
+ vxge_vBIT(val, 32, 4)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_MASK_IPV4_DA_MASK(bits) \
+ vxge_bVALn(bits, 36, 4)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_MASK_IPV4_DA_MASK(val) \
+ vxge_vBIT(val, 36, 4)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_MASK_L4SP_MASK(bits) \
+ vxge_bVALn(bits, 40, 2)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_MASK_L4SP_MASK(val) \
+ vxge_vBIT(val, 40, 2)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_MASK_L4DP_MASK(bits) \
+ vxge_bVALn(bits, 42, 2)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_MASK_L4DP_MASK(val) \
+ vxge_vBIT(val, 42, 2)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_RTH_KEY_KEY(bits) \
+ vxge_bVALn(bits, 0, 64)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_RTH_KEY_KEY vxge_vBIT(val, 0, 64)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_QOS_ENTRY_EN(bits) \
+ vxge_bVALn(bits, 3, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_QOS_ENTRY_EN vxge_mBIT(3)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DS_ENTRY_EN(bits) \
+ vxge_bVALn(bits, 3, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_DS_ENTRY_EN vxge_mBIT(3)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(bits) \
+ vxge_bVALn(bits, 0, 48)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_DA_MAC_ADDR_MASK(val) \
+ vxge_vBIT(val, 0, 48)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_DA_MAC_ADDR_MODE(val) \
+ vxge_vBIT(val, 62, 2)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM4_BUCKET_NUM(bits) \
+ vxge_bVALn(bits, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM4_BUCKET_NUM(val) \
+ vxge_vBIT(val, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM4_ENTRY_EN(bits) \
+ vxge_bVALn(bits, 8, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM4_ENTRY_EN vxge_mBIT(8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM4_BUCKET_DATA(bits) \
+ vxge_bVALn(bits, 9, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM4_BUCKET_DATA(val) \
+ vxge_vBIT(val, 9, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM5_BUCKET_NUM(bits) \
+ vxge_bVALn(bits, 16, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM5_BUCKET_NUM(val) \
+ vxge_vBIT(val, 16, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM5_ENTRY_EN(bits) \
+ vxge_bVALn(bits, 24, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM5_ENTRY_EN vxge_mBIT(24)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM5_BUCKET_DATA(bits) \
+ vxge_bVALn(bits, 25, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM5_BUCKET_DATA(val) \
+ vxge_vBIT(val, 25, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM6_BUCKET_NUM(bits) \
+ vxge_bVALn(bits, 32, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM6_BUCKET_NUM(val) \
+ vxge_vBIT(val, 32, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM6_ENTRY_EN(bits) \
+ vxge_bVALn(bits, 40, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM6_ENTRY_EN vxge_mBIT(40)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM6_BUCKET_DATA(bits) \
+ vxge_bVALn(bits, 41, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM6_BUCKET_DATA(val) \
+ vxge_vBIT(val, 41, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM7_BUCKET_NUM(bits) \
+ vxge_bVALn(bits, 48, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM7_BUCKET_NUM(val) \
+ vxge_vBIT(val, 48, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM7_ENTRY_EN(bits) \
+ vxge_bVALn(bits, 56, 1)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM7_ENTRY_EN vxge_mBIT(56)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_RTH_ITEM7_BUCKET_DATA(bits) \
+ vxge_bVALn(bits, 57, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_RTH_ITEM7_BUCKET_DATA(val) \
+ vxge_vBIT(val, 57, 7)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PART_NUMBER 0
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_SERIAL_NUMBER 1
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_VERSION 2
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_PCI_MODE 3
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_0 4
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_1 5
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_2 6
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_MEMO_ITEM_DESC_3 7
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_LED_CONTROL_ON 1
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_LED_CONTROL_OFF 0
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_DAY(bits) \
+ vxge_bVALn(bits, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_FW_VER_DAY(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MONTH(bits) \
+ vxge_bVALn(bits, 8, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_FW_VER_MONTH(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_YEAR(bits) \
+ vxge_bVALn(bits, 16, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_FW_VER_YEAR(val) \
+ vxge_vBIT(val, 16, 16)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(bits) \
+ vxge_bVALn(bits, 32, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_FW_VER_MAJOR vxge_vBIT(val, 32, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(bits) \
+ vxge_bVALn(bits, 40, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_FW_VER_MINOR vxge_vBIT(val, 40, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(bits) \
+ vxge_bVALn(bits, 48, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_FW_VER_BUILD vxge_vBIT(val, 48, 16)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_DAY(bits) \
+ vxge_bVALn(bits, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_DAY(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MONTH(bits) \
+ vxge_bVALn(bits, 8, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_MONTH(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_YEAR(bits) \
+ vxge_bVALn(bits, 16, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_YEAR(val) \
+ vxge_vBIT(val, 16, 16)
+
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MAJOR(bits) \
+ vxge_bVALn(bits, 32, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_MAJOR vxge_vBIT(val, 32, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_MINOR(bits) \
+ vxge_bVALn(bits, 40, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_MINOR vxge_vBIT(val, 40, 8)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(bits) \
+ vxge_bVALn(bits, 48, 16)
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_BUILD vxge_vBIT(val, 48, 16)
+
+#define VXGE_HW_SRPCIM_TO_VPATH_ALARM_REG_GET_PPIF_SRPCIM_TO_VPATH_ALARM(bits)\
+ vxge_bVALn(bits, 0, 18)
+
+#define VXGE_HW_RX_MULTI_CAST_STATS_GET_FRAME_DISCARD(bits) \
+ vxge_bVALn(bits, 48, 16)
+#define VXGE_HW_RX_FRM_TRANSFERRED_GET_RX_FRM_TRANSFERRED(bits) \
+ vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_RXD_RETURNED_GET_RXD_RETURNED(bits) vxge_bVALn(bits, 48, 16)
+#define VXGE_HW_VPATH_DEBUG_STATS0_GET_INI_NUM_MWR_SENT(bits) \
+ vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_VPATH_DEBUG_STATS1_GET_INI_NUM_MRD_SENT(bits) \
+ vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_VPATH_DEBUG_STATS2_GET_INI_NUM_CPL_RCVD(bits) \
+ vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_VPATH_DEBUG_STATS3_GET_INI_NUM_MWR_BYTE_SENT(bits) (bits)
+#define VXGE_HW_VPATH_DEBUG_STATS4_GET_INI_NUM_CPL_BYTE_RCVD(bits) (bits)
+#define VXGE_HW_VPATH_DEBUG_STATS5_GET_WRCRDTARB_XOFF(bits) \
+ vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_VPATH_DEBUG_STATS6_GET_RDCRDTARB_XOFF(bits) \
+ vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT1(bits) \
+ vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_VPATH_GENSTATS_COUNT01_GET_PPIF_VPATH_GENSTATS_COUNT0(bits) \
+ vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT3(bits) \
+ vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_VPATH_GENSTATS_COUNT23_GET_PPIF_VPATH_GENSTATS_COUNT2(bits) \
+ vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_VPATH_GENSTATS_COUNT4_GET_PPIF_VPATH_GENSTATS_COUNT4(bits) \
+ vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_VPATH_GENSTATS_COUNT5_GET_PPIF_VPATH_GENSTATS_COUNT5(bits) \
+ vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_TX_VP_RESET_DISCARDED_FRMS_GET_TX_VP_RESET_DISCARDED_FRMS(bits\
+) vxge_bVALn(bits, 48, 16)
+#define VXGE_HW_DBG_STATS_GET_RX_MPA_CRC_FAIL_FRMS(bits) vxge_bVALn(bits, 0, 16)
+#define VXGE_HW_DBG_STATS_GET_RX_MPA_MRK_FAIL_FRMS(bits) \
+ vxge_bVALn(bits, 16, 16)
+#define VXGE_HW_DBG_STATS_GET_RX_MPA_LEN_FAIL_FRMS(bits) \
+ vxge_bVALn(bits, 32, 16)
+#define VXGE_HW_DBG_STATS_GET_RX_FAU_RX_WOL_FRMS(bits) vxge_bVALn(bits, 0, 16)
+#define VXGE_HW_DBG_STATS_GET_RX_FAU_RX_VP_RESET_DISCARDED_FRMS(bits) \
+ vxge_bVALn(bits, 16, 16)
+#define VXGE_HW_DBG_STATS_GET_RX_FAU_RX_PERMITTED_FRMS(bits) \
+ vxge_bVALn(bits, 32, 16)
+
+#define VXGE_HW_MRPCIM_DEBUG_STATS0_GET_INI_WR_DROP(bits) \
+ vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_MRPCIM_DEBUG_STATS0_GET_INI_RD_DROP(bits) \
+ vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_MRPCIM_DEBUG_STATS1_GET_VPLANE_WRCRDTARB_PH_CRDT_DEPLETED(bits\
+) vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_MRPCIM_DEBUG_STATS2_GET_VPLANE_WRCRDTARB_PD_CRDT_DEPLETED(bits\
+) vxge_bVALn(bits, 32, 32)
+#define \
+VXGE_HW_MRPCIM_DEBUG_STATS3_GET_VPLANE_RDCRDTARB_NPH_CRDT_DEPLETED(bits) \
+ vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_MRPCIM_DEBUG_STATS4_GET_INI_WR_VPIN_DROP(bits) \
+ vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_MRPCIM_DEBUG_STATS4_GET_INI_RD_VPIN_DROP(bits) \
+ vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_GENSTATS_COUNT01_GET_GENSTATS_COUNT1(bits) \
+ vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_GENSTATS_COUNT01_GET_GENSTATS_COUNT0(bits) \
+ vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_GENSTATS_COUNT23_GET_GENSTATS_COUNT3(bits) \
+ vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_GENSTATS_COUNT23_GET_GENSTATS_COUNT2(bits) \
+ vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_GENSTATS_COUNT4_GET_GENSTATS_COUNT4(bits) \
+ vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_GENSTATS_COUNT5_GET_GENSTATS_COUNT5(bits) \
+ vxge_bVALn(bits, 32, 32)
+
+#define VXGE_HW_DEBUG_STATS0_GET_RSTDROP_MSG(bits) vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_DEBUG_STATS0_GET_RSTDROP_CPL(bits) vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_DEBUG_STATS1_GET_RSTDROP_CLIENT0(bits) vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_DEBUG_STATS1_GET_RSTDROP_CLIENT1(bits) vxge_bVALn(bits, 32, 32)
+#define VXGE_HW_DEBUG_STATS2_GET_RSTDROP_CLIENT2(bits) vxge_bVALn(bits, 0, 32)
+#define VXGE_HW_DEBUG_STATS3_GET_VPLANE_DEPL_PH(bits) vxge_bVALn(bits, 0, 16)
+#define VXGE_HW_DEBUG_STATS3_GET_VPLANE_DEPL_NPH(bits) vxge_bVALn(bits, 16, 16)
+#define VXGE_HW_DEBUG_STATS3_GET_VPLANE_DEPL_CPLH(bits) vxge_bVALn(bits, 32, 16)
+#define VXGE_HW_DEBUG_STATS4_GET_VPLANE_DEPL_PD(bits) vxge_bVALn(bits, 0, 16)
+#define VXGE_HW_DEBUG_STATS4_GET_VPLANE_DEPL_NPD(bits) bVAL(bits, 16, 16)
+#define VXGE_HW_DEBUG_STATS4_GET_VPLANE_DEPL_CPLD(bits) vxge_bVALn(bits, 32, 16)
+
+#define VXGE_HW_DBG_STATS_TPA_TX_PATH_GET_TX_PERMITTED_FRMS(bits) \
+ vxge_bVALn(bits, 32, 32)
+
+#define VXGE_HW_DBG_STAT_TX_ANY_FRMS_GET_PORT0_TX_ANY_FRMS(bits) \
+ vxge_bVALn(bits, 0, 8)
+#define VXGE_HW_DBG_STAT_TX_ANY_FRMS_GET_PORT1_TX_ANY_FRMS(bits) \
+ vxge_bVALn(bits, 8, 8)
+#define VXGE_HW_DBG_STAT_TX_ANY_FRMS_GET_PORT2_TX_ANY_FRMS(bits) \
+ vxge_bVALn(bits, 16, 8)
+
+#define VXGE_HW_DBG_STAT_RX_ANY_FRMS_GET_PORT0_RX_ANY_FRMS(bits) \
+ vxge_bVALn(bits, 0, 8)
+#define VXGE_HW_DBG_STAT_RX_ANY_FRMS_GET_PORT1_RX_ANY_FRMS(bits) \
+ vxge_bVALn(bits, 8, 8)
+#define VXGE_HW_DBG_STAT_RX_ANY_FRMS_GET_PORT2_RX_ANY_FRMS(bits) \
+ vxge_bVALn(bits, 16, 8)
+
+#define VXGE_HW_CONFIG_PRIV_H
+
+#define VXGE_HW_SWAPPER_INITIAL_VALUE 0x0123456789abcdefULL
+#define VXGE_HW_SWAPPER_BYTE_SWAPPED 0xefcdab8967452301ULL
+#define VXGE_HW_SWAPPER_BIT_FLIPPED 0x80c4a2e691d5b3f7ULL
+#define VXGE_HW_SWAPPER_BYTE_SWAPPED_BIT_FLIPPED 0xf7b3d591e6a2c480ULL
+
+#define VXGE_HW_SWAPPER_READ_BYTE_SWAP_ENABLE 0xFFFFFFFFFFFFFFFFULL
+#define VXGE_HW_SWAPPER_READ_BYTE_SWAP_DISABLE 0x0000000000000000ULL
+
+#define VXGE_HW_SWAPPER_READ_BIT_FLAP_ENABLE 0xFFFFFFFFFFFFFFFFULL
+#define VXGE_HW_SWAPPER_READ_BIT_FLAP_DISABLE 0x0000000000000000ULL
+
+#define VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_ENABLE 0xFFFFFFFFFFFFFFFFULL
+#define VXGE_HW_SWAPPER_WRITE_BYTE_SWAP_DISABLE 0x0000000000000000ULL
+
+#define VXGE_HW_SWAPPER_WRITE_BIT_FLAP_ENABLE 0xFFFFFFFFFFFFFFFFULL
+#define VXGE_HW_SWAPPER_WRITE_BIT_FLAP_DISABLE 0x0000000000000000ULL
+
+/*
+ * The registers are memory mapped and are native big-endian byte order. The
+ * little-endian hosts are handled by enabling hardware byte-swapping for
+ * register and dma operations.
+ */
+struct vxge_hw_legacy_reg {
+
+ u8 unused00010[0x00010];
+
+/*0x00010*/ u64 toc_swapper_fb;
+#define VXGE_HW_TOC_SWAPPER_FB_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+/*0x00018*/ u64 pifm_rd_swap_en;
+#define VXGE_HW_PIFM_RD_SWAP_EN_PIFM_RD_SWAP_EN(val) vxge_vBIT(val, 0, 64)
+/*0x00020*/ u64 pifm_rd_flip_en;
+#define VXGE_HW_PIFM_RD_FLIP_EN_PIFM_RD_FLIP_EN(val) vxge_vBIT(val, 0, 64)
+/*0x00028*/ u64 pifm_wr_swap_en;
+#define VXGE_HW_PIFM_WR_SWAP_EN_PIFM_WR_SWAP_EN(val) vxge_vBIT(val, 0, 64)
+/*0x00030*/ u64 pifm_wr_flip_en;
+#define VXGE_HW_PIFM_WR_FLIP_EN_PIFM_WR_FLIP_EN(val) vxge_vBIT(val, 0, 64)
+/*0x00038*/ u64 toc_first_pointer;
+#define VXGE_HW_TOC_FIRST_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+/*0x00040*/ u64 host_access_en;
+#define VXGE_HW_HOST_ACCESS_EN_HOST_ACCESS_EN(val) vxge_vBIT(val, 0, 64)
+
+} __packed;
+
+struct vxge_hw_toc_reg {
+
+ u8 unused00050[0x00050];
+
+/*0x00050*/ u64 toc_common_pointer;
+#define VXGE_HW_TOC_COMMON_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+/*0x00058*/ u64 toc_memrepair_pointer;
+#define VXGE_HW_TOC_MEMREPAIR_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+/*0x00060*/ u64 toc_pcicfgmgmt_pointer[17];
+#define VXGE_HW_TOC_PCICFGMGMT_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+ u8 unused001e0[0x001e0-0x000e8];
+
+/*0x001e0*/ u64 toc_mrpcim_pointer;
+#define VXGE_HW_TOC_MRPCIM_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+/*0x001e8*/ u64 toc_srpcim_pointer[17];
+#define VXGE_HW_TOC_SRPCIM_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+ u8 unused00278[0x00278-0x00270];
+
+/*0x00278*/ u64 toc_vpmgmt_pointer[17];
+#define VXGE_HW_TOC_VPMGMT_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+ u8 unused00390[0x00390-0x00300];
+
+/*0x00390*/ u64 toc_vpath_pointer[17];
+#define VXGE_HW_TOC_VPATH_POINTER_INITIAL_VAL(val) vxge_vBIT(val, 0, 64)
+ u8 unused004a0[0x004a0-0x00418];
+
+/*0x004a0*/ u64 toc_kdfc;
+#define VXGE_HW_TOC_KDFC_INITIAL_OFFSET(val) vxge_vBIT(val, 0, 61)
+#define VXGE_HW_TOC_KDFC_INITIAL_BIR(val) vxge_vBIT(val, 61, 3)
+/*0x004a8*/ u64 toc_usdc;
+#define VXGE_HW_TOC_USDC_INITIAL_OFFSET(val) vxge_vBIT(val, 0, 61)
+#define VXGE_HW_TOC_USDC_INITIAL_BIR(val) vxge_vBIT(val, 61, 3)
+/*0x004b0*/ u64 toc_kdfc_vpath_stride;
+#define VXGE_HW_TOC_KDFC_VPATH_STRIDE_INITIAL_TOC_KDFC_VPATH_STRIDE(val) \
+ vxge_vBIT(val, 0, 64)
+/*0x004b8*/ u64 toc_kdfc_fifo_stride;
+#define VXGE_HW_TOC_KDFC_FIFO_STRIDE_INITIAL_TOC_KDFC_FIFO_STRIDE(val) \
+ vxge_vBIT(val, 0, 64)
+
+} __packed;
+
+struct vxge_hw_common_reg {
+
+ u8 unused00a00[0x00a00];
+
+/*0x00a00*/ u64 prc_status1;
+#define VXGE_HW_PRC_STATUS1_PRC_VP_QUIESCENT(n) vxge_mBIT(n)
+/*0x00a08*/ u64 rxdcm_reset_in_progress;
+#define VXGE_HW_RXDCM_RESET_IN_PROGRESS_PRC_VP(n) vxge_mBIT(n)
+/*0x00a10*/ u64 replicq_flush_in_progress;
+#define VXGE_HW_REPLICQ_FLUSH_IN_PROGRESS_NOA_VP(n) vxge_mBIT(n)
+/*0x00a18*/ u64 rxpe_cmds_reset_in_progress;
+#define VXGE_HW_RXPE_CMDS_RESET_IN_PROGRESS_NOA_VP(n) vxge_mBIT(n)
+/*0x00a20*/ u64 mxp_cmds_reset_in_progress;
+#define VXGE_HW_MXP_CMDS_RESET_IN_PROGRESS_NOA_VP(n) vxge_mBIT(n)
+/*0x00a28*/ u64 noffload_reset_in_progress;
+#define VXGE_HW_NOFFLOAD_RESET_IN_PROGRESS_PRC_VP(n) vxge_mBIT(n)
+/*0x00a30*/ u64 rd_req_in_progress;
+#define VXGE_HW_RD_REQ_IN_PROGRESS_VP(n) vxge_mBIT(n)
+/*0x00a38*/ u64 rd_req_outstanding;
+#define VXGE_HW_RD_REQ_OUTSTANDING_VP(n) vxge_mBIT(n)
+/*0x00a40*/ u64 kdfc_reset_in_progress;
+#define VXGE_HW_KDFC_RESET_IN_PROGRESS_NOA_VP(n) vxge_mBIT(n)
+ u8 unused00b00[0x00b00-0x00a48];
+
+/*0x00b00*/ u64 one_cfg_vp;
+#define VXGE_HW_ONE_CFG_VP_RDY(n) vxge_mBIT(n)
+/*0x00b08*/ u64 one_common;
+#define VXGE_HW_ONE_COMMON_PET_VPATH_RESET_IN_PROGRESS(n) vxge_mBIT(n)
+ u8 unused00b80[0x00b80-0x00b10];
+
+/*0x00b80*/ u64 tim_int_en;
+#define VXGE_HW_TIM_INT_EN_TIM_VP(n) vxge_mBIT(n)
+/*0x00b88*/ u64 tim_set_int_en;
+#define VXGE_HW_TIM_SET_INT_EN_VP(n) vxge_mBIT(n)
+/*0x00b90*/ u64 tim_clr_int_en;
+#define VXGE_HW_TIM_CLR_INT_EN_VP(n) vxge_mBIT(n)
+/*0x00b98*/ u64 tim_mask_int_during_reset;
+#define VXGE_HW_TIM_MASK_INT_DURING_RESET_VPATH(n) vxge_mBIT(n)
+/*0x00ba0*/ u64 tim_reset_in_progress;
+#define VXGE_HW_TIM_RESET_IN_PROGRESS_TIM_VPATH(n) vxge_mBIT(n)
+/*0x00ba8*/ u64 tim_outstanding_bmap;
+#define VXGE_HW_TIM_OUTSTANDING_BMAP_TIM_VPATH(n) vxge_mBIT(n)
+ u8 unused00c00[0x00c00-0x00bb0];
+
+/*0x00c00*/ u64 msg_reset_in_progress;
+#define VXGE_HW_MSG_RESET_IN_PROGRESS_MSG_COMPOSITE(val) vxge_vBIT(val, 0, 17)
+/*0x00c08*/ u64 msg_mxp_mr_ready;
+#define VXGE_HW_MSG_MXP_MR_READY_MP_BOOTED(n) vxge_mBIT(n)
+/*0x00c10*/ u64 msg_uxp_mr_ready;
+#define VXGE_HW_MSG_UXP_MR_READY_UP_BOOTED(n) vxge_mBIT(n)
+/*0x00c18*/ u64 msg_dmq_noni_rtl_prefetch;
+#define VXGE_HW_MSG_DMQ_NONI_RTL_PREFETCH_BYPASS_ENABLE(n) vxge_mBIT(n)
+/*0x00c20*/ u64 msg_umq_rtl_bwr;
+#define VXGE_HW_MSG_UMQ_RTL_BWR_PREFETCH_DISABLE(n) vxge_mBIT(n)
+ u8 unused00d00[0x00d00-0x00c28];
+
+/*0x00d00*/ u64 cmn_rsthdlr_cfg0;
+#define VXGE_HW_CMN_RSTHDLR_CFG0_SW_RESET_VPATH(val) vxge_vBIT(val, 0, 17)
+/*0x00d08*/ u64 cmn_rsthdlr_cfg1;
+#define VXGE_HW_CMN_RSTHDLR_CFG1_CLR_VPATH_RESET(val) vxge_vBIT(val, 0, 17)
+/*0x00d10*/ u64 cmn_rsthdlr_cfg2;
+#define VXGE_HW_CMN_RSTHDLR_CFG2_SW_RESET_FIFO0(val) vxge_vBIT(val, 0, 17)
+/*0x00d18*/ u64 cmn_rsthdlr_cfg3;
+#define VXGE_HW_CMN_RSTHDLR_CFG3_SW_RESET_FIFO1(val) vxge_vBIT(val, 0, 17)
+/*0x00d20*/ u64 cmn_rsthdlr_cfg4;
+#define VXGE_HW_CMN_RSTHDLR_CFG4_SW_RESET_FIFO2(val) vxge_vBIT(val, 0, 17)
+ u8 unused00d40[0x00d40-0x00d28];
+
+/*0x00d40*/ u64 cmn_rsthdlr_cfg8;
+#define VXGE_HW_CMN_RSTHDLR_CFG8_INCR_VPATH_INST_NUM(val) vxge_vBIT(val, 0, 17)
+/*0x00d48*/ u64 stats_cfg0;
+#define VXGE_HW_STATS_CFG0_STATS_ENABLE(val) vxge_vBIT(val, 0, 17)
+ u8 unused00da8[0x00da8-0x00d50];
+
+/*0x00da8*/ u64 clear_msix_mask_vect[4];
+#define VXGE_HW_CLEAR_MSIX_MASK_VECT_CLEAR_MSIX_MASK_VECT(val) \
+ vxge_vBIT(val, 0, 17)
+/*0x00dc8*/ u64 set_msix_mask_vect[4];
+#define VXGE_HW_SET_MSIX_MASK_VECT_SET_MSIX_MASK_VECT(val) vxge_vBIT(val, 0, 17)
+/*0x00de8*/ u64 clear_msix_mask_all_vect;
+#define VXGE_HW_CLEAR_MSIX_MASK_ALL_VECT_CLEAR_MSIX_MASK_ALL_VECT(val) \
+ vxge_vBIT(val, 0, 17)
+/*0x00df0*/ u64 set_msix_mask_all_vect;
+#define VXGE_HW_SET_MSIX_MASK_ALL_VECT_SET_MSIX_MASK_ALL_VECT(val) \
+ vxge_vBIT(val, 0, 17)
+/*0x00df8*/ u64 mask_vector[4];
+#define VXGE_HW_MASK_VECTOR_MASK_VECTOR(val) vxge_vBIT(val, 0, 17)
+/*0x00e18*/ u64 msix_pending_vector[4];
+#define VXGE_HW_MSIX_PENDING_VECTOR_MSIX_PENDING_VECTOR(val) \
+ vxge_vBIT(val, 0, 17)
+/*0x00e38*/ u64 clr_msix_one_shot_vec[4];
+#define VXGE_HW_CLR_MSIX_ONE_SHOT_VEC_CLR_MSIX_ONE_SHOT_VEC(val) \
+ vxge_vBIT(val, 0, 17)
+/*0x00e58*/ u64 titan_asic_id;
+#define VXGE_HW_TITAN_ASIC_ID_INITIAL_DEVICE_ID(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_TITAN_ASIC_ID_INITIAL_MAJOR_REVISION(val) vxge_vBIT(val, 48, 8)
+#define VXGE_HW_TITAN_ASIC_ID_INITIAL_MINOR_REVISION(val) vxge_vBIT(val, 56, 8)
+/*0x00e60*/ u64 titan_general_int_status;
+#define VXGE_HW_TITAN_GENERAL_INT_STATUS_MRPCIM_ALARM_INT vxge_mBIT(0)
+#define VXGE_HW_TITAN_GENERAL_INT_STATUS_SRPCIM_ALARM_INT vxge_mBIT(1)
+#define VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_ALARM_INT vxge_mBIT(2)
+#define VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_TRAFFIC_INT(val) \
+ vxge_vBIT(val, 3, 17)
+ u8 unused00e70[0x00e70-0x00e68];
+
+/*0x00e70*/ u64 titan_mask_all_int;
+#define VXGE_HW_TITAN_MASK_ALL_INT_ALARM vxge_mBIT(7)
+#define VXGE_HW_TITAN_MASK_ALL_INT_TRAFFIC vxge_mBIT(15)
+ u8 unused00e80[0x00e80-0x00e78];
+
+/*0x00e80*/ u64 tim_int_status0;
+#define VXGE_HW_TIM_INT_STATUS0_TIM_INT_STATUS0(val) vxge_vBIT(val, 0, 64)
+/*0x00e88*/ u64 tim_int_mask0;
+#define VXGE_HW_TIM_INT_MASK0_TIM_INT_MASK0(val) vxge_vBIT(val, 0, 64)
+/*0x00e90*/ u64 tim_int_status1;
+#define VXGE_HW_TIM_INT_STATUS1_TIM_INT_STATUS1(val) vxge_vBIT(val, 0, 4)
+/*0x00e98*/ u64 tim_int_mask1;
+#define VXGE_HW_TIM_INT_MASK1_TIM_INT_MASK1(val) vxge_vBIT(val, 0, 4)
+/*0x00ea0*/ u64 rti_int_status;
+#define VXGE_HW_RTI_INT_STATUS_RTI_INT_STATUS(val) vxge_vBIT(val, 0, 17)
+/*0x00ea8*/ u64 rti_int_mask;
+#define VXGE_HW_RTI_INT_MASK_RTI_INT_MASK(val) vxge_vBIT(val, 0, 17)
+/*0x00eb0*/ u64 adapter_status;
+#define VXGE_HW_ADAPTER_STATUS_RTDMA_RTDMA_READY vxge_mBIT(0)
+#define VXGE_HW_ADAPTER_STATUS_WRDMA_WRDMA_READY vxge_mBIT(1)
+#define VXGE_HW_ADAPTER_STATUS_KDFC_KDFC_READY vxge_mBIT(2)
+#define VXGE_HW_ADAPTER_STATUS_TPA_TMAC_BUF_EMPTY vxge_mBIT(3)
+#define VXGE_HW_ADAPTER_STATUS_RDCTL_PIC_QUIESCENT vxge_mBIT(4)
+#define VXGE_HW_ADAPTER_STATUS_XGMAC_NETWORK_FAULT vxge_mBIT(5)
+#define VXGE_HW_ADAPTER_STATUS_ROCRC_OFFLOAD_QUIESCENT vxge_mBIT(6)
+#define VXGE_HW_ADAPTER_STATUS_G3IF_FB_G3IF_FB_GDDR3_READY vxge_mBIT(7)
+#define VXGE_HW_ADAPTER_STATUS_G3IF_CM_G3IF_CM_GDDR3_READY vxge_mBIT(8)
+#define VXGE_HW_ADAPTER_STATUS_RIC_RIC_RUNNING vxge_mBIT(9)
+#define VXGE_HW_ADAPTER_STATUS_CMG_C_PLL_IN_LOCK vxge_mBIT(10)
+#define VXGE_HW_ADAPTER_STATUS_XGMAC_X_PLL_IN_LOCK vxge_mBIT(11)
+#define VXGE_HW_ADAPTER_STATUS_FBIF_M_PLL_IN_LOCK vxge_mBIT(12)
+#define VXGE_HW_ADAPTER_STATUS_PCC_PCC_IDLE(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_ADAPTER_STATUS_ROCRC_RC_PRC_QUIESCENT(val) vxge_vBIT(val, 44, 8)
+/*0x00eb8*/ u64 gen_ctrl;
+#define VXGE_HW_GEN_CTRL_SPI_MRPCIM_WR_DIS vxge_mBIT(0)
+#define VXGE_HW_GEN_CTRL_SPI_MRPCIM_RD_DIS vxge_mBIT(1)
+#define VXGE_HW_GEN_CTRL_SPI_SRPCIM_WR_DIS vxge_mBIT(2)
+#define VXGE_HW_GEN_CTRL_SPI_SRPCIM_RD_DIS vxge_mBIT(3)
+#define VXGE_HW_GEN_CTRL_SPI_DEBUG_DIS vxge_mBIT(4)
+#define VXGE_HW_GEN_CTRL_SPI_APP_LTSSM_TIMER_DIS vxge_mBIT(5)
+#define VXGE_HW_GEN_CTRL_SPI_NOT_USED(val) vxge_vBIT(val, 6, 4)
+ u8 unused00ed0[0x00ed0-0x00ec0];
+
+/*0x00ed0*/ u64 adapter_ready;
+#define VXGE_HW_ADAPTER_READY_ADAPTER_READY vxge_mBIT(63)
+/*0x00ed8*/ u64 outstanding_read;
+#define VXGE_HW_OUTSTANDING_READ_OUTSTANDING_READ(val) vxge_vBIT(val, 0, 17)
+/*0x00ee0*/ u64 vpath_rst_in_prog;
+#define VXGE_HW_VPATH_RST_IN_PROG_VPATH_RST_IN_PROG(val) vxge_vBIT(val, 0, 17)
+/*0x00ee8*/ u64 vpath_reg_modified;
+#define VXGE_HW_VPATH_REG_MODIFIED_VPATH_REG_MODIFIED(val) vxge_vBIT(val, 0, 17)
+ u8 unused00fc0[0x00fc0-0x00ef0];
+
+/*0x00fc0*/ u64 cp_reset_in_progress;
+#define VXGE_HW_CP_RESET_IN_PROGRESS_CP_VPATH(n) vxge_mBIT(n)
+ u8 unused01080[0x01080-0x00fc8];
+
+/*0x01080*/ u64 xgmac_ready;
+#define VXGE_HW_XGMAC_READY_XMACJ_READY(val) vxge_vBIT(val, 0, 17)
+ u8 unused010c0[0x010c0-0x01088];
+
+/*0x010c0*/ u64 fbif_ready;
+#define VXGE_HW_FBIF_READY_FAU_READY(val) vxge_vBIT(val, 0, 17)
+ u8 unused01100[0x01100-0x010c8];
+
+/*0x01100*/ u64 vplane_assignments;
+#define VXGE_HW_VPLANE_ASSIGNMENTS_VPLANE_ASSIGNMENTS(val) vxge_vBIT(val, 3, 5)
+/*0x01108*/ u64 vpath_assignments;
+#define VXGE_HW_VPATH_ASSIGNMENTS_VPATH_ASSIGNMENTS(val) vxge_vBIT(val, 0, 17)
+/*0x01110*/ u64 resource_assignments;
+#define VXGE_HW_RESOURCE_ASSIGNMENTS_RESOURCE_ASSIGNMENTS(val) \
+ vxge_vBIT(val, 0, 17)
+/*0x01118*/ u64 host_type_assignments;
+#define VXGE_HW_HOST_TYPE_ASSIGNMENTS_HOST_TYPE_ASSIGNMENTS(val) \
+ vxge_vBIT(val, 5, 3)
+ u8 unused01128[0x01128-0x01120];
+
+/*0x01128*/ u64 max_resource_assignments;
+#define VXGE_HW_MAX_RESOURCE_ASSIGNMENTS_PCI_MAX_VPLANE(val) \
+ vxge_vBIT(val, 3, 5)
+#define VXGE_HW_MAX_RESOURCE_ASSIGNMENTS_PCI_MAX_VPATHS(val) \
+ vxge_vBIT(val, 11, 5)
+/*0x01130*/ u64 pf_vpath_assignments;
+#define VXGE_HW_PF_VPATH_ASSIGNMENTS_PF_VPATH_ASSIGNMENTS(val) \
+ vxge_vBIT(val, 0, 17)
+ u8 unused01200[0x01200-0x01138];
+
+/*0x01200*/ u64 rts_access_icmp;
+#define VXGE_HW_RTS_ACCESS_ICMP_EN(val) vxge_vBIT(val, 0, 17)
+/*0x01208*/ u64 rts_access_tcpsyn;
+#define VXGE_HW_RTS_ACCESS_TCPSYN_EN(val) vxge_vBIT(val, 0, 17)
+/*0x01210*/ u64 rts_access_zl4pyld;
+#define VXGE_HW_RTS_ACCESS_ZL4PYLD_EN(val) vxge_vBIT(val, 0, 17)
+/*0x01218*/ u64 rts_access_l4prtcl_tcp;
+#define VXGE_HW_RTS_ACCESS_L4PRTCL_TCP_EN(val) vxge_vBIT(val, 0, 17)
+/*0x01220*/ u64 rts_access_l4prtcl_udp;
+#define VXGE_HW_RTS_ACCESS_L4PRTCL_UDP_EN(val) vxge_vBIT(val, 0, 17)
+/*0x01228*/ u64 rts_access_l4prtcl_flex;
+#define VXGE_HW_RTS_ACCESS_L4PRTCL_FLEX_EN(val) vxge_vBIT(val, 0, 17)
+/*0x01230*/ u64 rts_access_ipfrag;
+#define VXGE_HW_RTS_ACCESS_IPFRAG_EN(val) vxge_vBIT(val, 0, 17)
+
+} __packed;
+
+struct vxge_hw_memrepair_reg {
+ u64 unused1;
+ u64 unused2;
+} __packed;
+
+struct vxge_hw_pcicfgmgmt_reg {
+
+/*0x00000*/ u64 resource_no;
+#define VXGE_HW_RESOURCE_NO_PFN_OR_VF BIT(3)
+/*0x00008*/ u64 bargrp_pf_or_vf_bar0_mask;
+#define VXGE_HW_BARGRP_PF_OR_VF_BAR0_MASK_BARGRP_PF_OR_VF_BAR0_MASK(val) \
+ vxge_vBIT(val, 2, 6)
+/*0x00010*/ u64 bargrp_pf_or_vf_bar1_mask;
+#define VXGE_HW_BARGRP_PF_OR_VF_BAR1_MASK_BARGRP_PF_OR_VF_BAR1_MASK(val) \
+ vxge_vBIT(val, 2, 6)
+/*0x00018*/ u64 bargrp_pf_or_vf_bar2_mask;
+#define VXGE_HW_BARGRP_PF_OR_VF_BAR2_MASK_BARGRP_PF_OR_VF_BAR2_MASK(val) \
+ vxge_vBIT(val, 2, 6)
+/*0x00020*/ u64 msixgrp_no;
+#define VXGE_HW_MSIXGRP_NO_TABLE_SIZE(val) vxge_vBIT(val, 5, 11)
+
+} __packed;
+
+struct vxge_hw_mrpcim_reg {
+/*0x00000*/ u64 g3fbct_int_status;
+#define VXGE_HW_G3FBCT_INT_STATUS_ERR_G3IF_INT vxge_mBIT(0)
+/*0x00008*/ u64 g3fbct_int_mask;
+/*0x00010*/ u64 g3fbct_err_reg;
+#define VXGE_HW_G3FBCT_ERR_REG_G3IF_SM_ERR vxge_mBIT(4)
+#define VXGE_HW_G3FBCT_ERR_REG_G3IF_GDDR3_DECC vxge_mBIT(5)
+#define VXGE_HW_G3FBCT_ERR_REG_G3IF_GDDR3_U_DECC vxge_mBIT(6)
+#define VXGE_HW_G3FBCT_ERR_REG_G3IF_CTRL_FIFO_DECC vxge_mBIT(7)
+#define VXGE_HW_G3FBCT_ERR_REG_G3IF_GDDR3_SECC vxge_mBIT(29)
+#define VXGE_HW_G3FBCT_ERR_REG_G3IF_GDDR3_U_SECC vxge_mBIT(30)
+#define VXGE_HW_G3FBCT_ERR_REG_G3IF_CTRL_FIFO_SECC vxge_mBIT(31)
+/*0x00018*/ u64 g3fbct_err_mask;
+/*0x00020*/ u64 g3fbct_err_alarm;
+
+ u8 unused00a00[0x00a00-0x00028];
+
+/*0x00a00*/ u64 wrdma_int_status;
+#define VXGE_HW_WRDMA_INT_STATUS_RC_ALARM_RC_INT vxge_mBIT(0)
+#define VXGE_HW_WRDMA_INT_STATUS_RXDRM_SM_ERR_RXDRM_INT vxge_mBIT(1)
+#define VXGE_HW_WRDMA_INT_STATUS_RXDCM_SM_ERR_RXDCM_SM_INT vxge_mBIT(2)
+#define VXGE_HW_WRDMA_INT_STATUS_RXDWM_SM_ERR_RXDWM_INT vxge_mBIT(3)
+#define VXGE_HW_WRDMA_INT_STATUS_RDA_ERR_RDA_INT vxge_mBIT(6)
+#define VXGE_HW_WRDMA_INT_STATUS_RDA_ECC_DB_RDA_ECC_DB_INT vxge_mBIT(8)
+#define VXGE_HW_WRDMA_INT_STATUS_RDA_ECC_SG_RDA_ECC_SG_INT vxge_mBIT(9)
+#define VXGE_HW_WRDMA_INT_STATUS_FRF_ALARM_FRF_INT vxge_mBIT(12)
+#define VXGE_HW_WRDMA_INT_STATUS_ROCRC_ALARM_ROCRC_INT vxge_mBIT(13)
+#define VXGE_HW_WRDMA_INT_STATUS_WDE0_ALARM_WDE0_INT vxge_mBIT(14)
+#define VXGE_HW_WRDMA_INT_STATUS_WDE1_ALARM_WDE1_INT vxge_mBIT(15)
+#define VXGE_HW_WRDMA_INT_STATUS_WDE2_ALARM_WDE2_INT vxge_mBIT(16)
+#define VXGE_HW_WRDMA_INT_STATUS_WDE3_ALARM_WDE3_INT vxge_mBIT(17)
+/*0x00a08*/ u64 wrdma_int_mask;
+/*0x00a10*/ u64 rc_alarm_reg;
+#define VXGE_HW_RC_ALARM_REG_FTC_SM_ERR vxge_mBIT(0)
+#define VXGE_HW_RC_ALARM_REG_FTC_SM_PHASE_ERR vxge_mBIT(1)
+#define VXGE_HW_RC_ALARM_REG_BTDWM_SM_ERR vxge_mBIT(2)
+#define VXGE_HW_RC_ALARM_REG_BTC_SM_ERR vxge_mBIT(3)
+#define VXGE_HW_RC_ALARM_REG_BTDCM_SM_ERR vxge_mBIT(4)
+#define VXGE_HW_RC_ALARM_REG_BTDRM_SM_ERR vxge_mBIT(5)
+#define VXGE_HW_RC_ALARM_REG_RMM_RXD_RC_ECC_DB_ERR vxge_mBIT(6)
+#define VXGE_HW_RC_ALARM_REG_RMM_RXD_RC_ECC_SG_ERR vxge_mBIT(7)
+#define VXGE_HW_RC_ALARM_REG_RHS_RXD_RHS_ECC_DB_ERR vxge_mBIT(8)
+#define VXGE_HW_RC_ALARM_REG_RHS_RXD_RHS_ECC_SG_ERR vxge_mBIT(9)
+#define VXGE_HW_RC_ALARM_REG_RMM_SM_ERR vxge_mBIT(10)
+#define VXGE_HW_RC_ALARM_REG_BTC_VPATH_MISMATCH_ERR vxge_mBIT(12)
+/*0x00a18*/ u64 rc_alarm_mask;
+/*0x00a20*/ u64 rc_alarm_alarm;
+/*0x00a28*/ u64 rxdrm_sm_err_reg;
+#define VXGE_HW_RXDRM_SM_ERR_REG_PRC_VP(n) vxge_mBIT(n)
+/*0x00a30*/ u64 rxdrm_sm_err_mask;
+/*0x00a38*/ u64 rxdrm_sm_err_alarm;
+/*0x00a40*/ u64 rxdcm_sm_err_reg;
+#define VXGE_HW_RXDCM_SM_ERR_REG_PRC_VP(n) vxge_mBIT(n)
+/*0x00a48*/ u64 rxdcm_sm_err_mask;
+/*0x00a50*/ u64 rxdcm_sm_err_alarm;
+/*0x00a58*/ u64 rxdwm_sm_err_reg;
+#define VXGE_HW_RXDWM_SM_ERR_REG_PRC_VP(n) vxge_mBIT(n)
+/*0x00a60*/ u64 rxdwm_sm_err_mask;
+/*0x00a68*/ u64 rxdwm_sm_err_alarm;
+/*0x00a70*/ u64 rda_err_reg;
+#define VXGE_HW_RDA_ERR_REG_RDA_SM0_ERR_ALARM vxge_mBIT(0)
+#define VXGE_HW_RDA_ERR_REG_RDA_MISC_ERR vxge_mBIT(1)
+#define VXGE_HW_RDA_ERR_REG_RDA_PCIX_ERR vxge_mBIT(2)
+#define VXGE_HW_RDA_ERR_REG_RDA_RXD_ECC_DB_ERR vxge_mBIT(3)
+#define VXGE_HW_RDA_ERR_REG_RDA_FRM_ECC_DB_ERR vxge_mBIT(4)
+#define VXGE_HW_RDA_ERR_REG_RDA_UQM_ECC_DB_ERR vxge_mBIT(5)
+#define VXGE_HW_RDA_ERR_REG_RDA_IMM_ECC_DB_ERR vxge_mBIT(6)
+#define VXGE_HW_RDA_ERR_REG_RDA_TIM_ECC_DB_ERR vxge_mBIT(7)
+/*0x00a78*/ u64 rda_err_mask;
+/*0x00a80*/ u64 rda_err_alarm;
+/*0x00a88*/ u64 rda_ecc_db_reg;
+#define VXGE_HW_RDA_ECC_DB_REG_RDA_RXD_ERR(n) vxge_mBIT(n)
+/*0x00a90*/ u64 rda_ecc_db_mask;
+/*0x00a98*/ u64 rda_ecc_db_alarm;
+/*0x00aa0*/ u64 rda_ecc_sg_reg;
+#define VXGE_HW_RDA_ECC_SG_REG_RDA_RXD_ERR(n) vxge_mBIT(n)
+/*0x00aa8*/ u64 rda_ecc_sg_mask;
+/*0x00ab0*/ u64 rda_ecc_sg_alarm;
+/*0x00ab8*/ u64 rqa_err_reg;
+#define VXGE_HW_RQA_ERR_REG_RQA_SM_ERR_ALARM vxge_mBIT(0)
+/*0x00ac0*/ u64 rqa_err_mask;
+/*0x00ac8*/ u64 rqa_err_alarm;
+/*0x00ad0*/ u64 frf_alarm_reg;
+#define VXGE_HW_FRF_ALARM_REG_PRC_VP_FRF_SM_ERR(n) vxge_mBIT(n)
+/*0x00ad8*/ u64 frf_alarm_mask;
+/*0x00ae0*/ u64 frf_alarm_alarm;
+/*0x00ae8*/ u64 rocrc_alarm_reg;
+#define VXGE_HW_ROCRC_ALARM_REG_QCQ_QCC_BYP_ECC_DB vxge_mBIT(0)
+#define VXGE_HW_ROCRC_ALARM_REG_QCQ_QCC_BYP_ECC_SG vxge_mBIT(1)
+#define VXGE_HW_ROCRC_ALARM_REG_NOA_NMA_SM_ERR vxge_mBIT(2)
+#define VXGE_HW_ROCRC_ALARM_REG_NOA_IMMM_ECC_DB vxge_mBIT(3)
+#define VXGE_HW_ROCRC_ALARM_REG_NOA_IMMM_ECC_SG vxge_mBIT(4)
+#define VXGE_HW_ROCRC_ALARM_REG_UDQ_UMQM_ECC_DB vxge_mBIT(5)
+#define VXGE_HW_ROCRC_ALARM_REG_UDQ_UMQM_ECC_SG vxge_mBIT(6)
+#define VXGE_HW_ROCRC_ALARM_REG_NOA_RCBM_ECC_DB vxge_mBIT(11)
+#define VXGE_HW_ROCRC_ALARM_REG_NOA_RCBM_ECC_SG vxge_mBIT(12)
+#define VXGE_HW_ROCRC_ALARM_REG_QCQ_MULTI_EGB_RSVD_ERR vxge_mBIT(13)
+#define VXGE_HW_ROCRC_ALARM_REG_QCQ_MULTI_EGB_OWN_ERR vxge_mBIT(14)
+#define VXGE_HW_ROCRC_ALARM_REG_QCQ_MULTI_BYP_OWN_ERR vxge_mBIT(15)
+#define VXGE_HW_ROCRC_ALARM_REG_QCQ_OWN_NOT_ASSIGNED_ERR vxge_mBIT(16)
+#define VXGE_HW_ROCRC_ALARM_REG_QCQ_OWN_RSVD_SYNC_ERR vxge_mBIT(17)
+#define VXGE_HW_ROCRC_ALARM_REG_QCQ_LOST_EGB_ERR vxge_mBIT(18)
+#define VXGE_HW_ROCRC_ALARM_REG_RCQ_BYPQ0_OVERFLOW vxge_mBIT(19)
+#define VXGE_HW_ROCRC_ALARM_REG_RCQ_BYPQ1_OVERFLOW vxge_mBIT(20)
+#define VXGE_HW_ROCRC_ALARM_REG_RCQ_BYPQ2_OVERFLOW vxge_mBIT(21)
+#define VXGE_HW_ROCRC_ALARM_REG_NOA_WCT_CMD_FIFO_ERR vxge_mBIT(22)
+/*0x00af0*/ u64 rocrc_alarm_mask;
+/*0x00af8*/ u64 rocrc_alarm_alarm;
+/*0x00b00*/ u64 wde0_alarm_reg;
+#define VXGE_HW_WDE0_ALARM_REG_WDE0_DCC_SM_ERR vxge_mBIT(0)
+#define VXGE_HW_WDE0_ALARM_REG_WDE0_PRM_SM_ERR vxge_mBIT(1)
+#define VXGE_HW_WDE0_ALARM_REG_WDE0_CP_SM_ERR vxge_mBIT(2)
+#define VXGE_HW_WDE0_ALARM_REG_WDE0_CP_CMD_ERR vxge_mBIT(3)
+#define VXGE_HW_WDE0_ALARM_REG_WDE0_PCR_SM_ERR vxge_mBIT(4)
+/*0x00b08*/ u64 wde0_alarm_mask;
+/*0x00b10*/ u64 wde0_alarm_alarm;
+/*0x00b18*/ u64 wde1_alarm_reg;
+#define VXGE_HW_WDE1_ALARM_REG_WDE1_DCC_SM_ERR vxge_mBIT(0)
+#define VXGE_HW_WDE1_ALARM_REG_WDE1_PRM_SM_ERR vxge_mBIT(1)
+#define VXGE_HW_WDE1_ALARM_REG_WDE1_CP_SM_ERR vxge_mBIT(2)
+#define VXGE_HW_WDE1_ALARM_REG_WDE1_CP_CMD_ERR vxge_mBIT(3)
+#define VXGE_HW_WDE1_ALARM_REG_WDE1_PCR_SM_ERR vxge_mBIT(4)
+/*0x00b20*/ u64 wde1_alarm_mask;
+/*0x00b28*/ u64 wde1_alarm_alarm;
+/*0x00b30*/ u64 wde2_alarm_reg;
+#define VXGE_HW_WDE2_ALARM_REG_WDE2_DCC_SM_ERR vxge_mBIT(0)
+#define VXGE_HW_WDE2_ALARM_REG_WDE2_PRM_SM_ERR vxge_mBIT(1)
+#define VXGE_HW_WDE2_ALARM_REG_WDE2_CP_SM_ERR vxge_mBIT(2)
+#define VXGE_HW_WDE2_ALARM_REG_WDE2_CP_CMD_ERR vxge_mBIT(3)
+#define VXGE_HW_WDE2_ALARM_REG_WDE2_PCR_SM_ERR vxge_mBIT(4)
+/*0x00b38*/ u64 wde2_alarm_mask;
+/*0x00b40*/ u64 wde2_alarm_alarm;
+/*0x00b48*/ u64 wde3_alarm_reg;
+#define VXGE_HW_WDE3_ALARM_REG_WDE3_DCC_SM_ERR vxge_mBIT(0)
+#define VXGE_HW_WDE3_ALARM_REG_WDE3_PRM_SM_ERR vxge_mBIT(1)
+#define VXGE_HW_WDE3_ALARM_REG_WDE3_CP_SM_ERR vxge_mBIT(2)
+#define VXGE_HW_WDE3_ALARM_REG_WDE3_CP_CMD_ERR vxge_mBIT(3)
+#define VXGE_HW_WDE3_ALARM_REG_WDE3_PCR_SM_ERR vxge_mBIT(4)
+/*0x00b50*/ u64 wde3_alarm_mask;
+/*0x00b58*/ u64 wde3_alarm_alarm;
+
+ u8 unused00be8[0x00be8-0x00b60];
+
+/*0x00be8*/ u64 rx_w_round_robin_0;
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_0(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_1(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_2(val) vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_3(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_4(val) vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_5(val) vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_6(val) vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_0_RX_W_PRIORITY_SS_7(val) vxge_vBIT(val, 59, 5)
+/*0x00bf0*/ u64 rx_w_round_robin_1;
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_8(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_9(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_10(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_11(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_12(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_13(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_14(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_1_RX_W_PRIORITY_SS_15(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00bf8*/ u64 rx_w_round_robin_2;
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_16(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_17(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_18(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_19(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_20(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_21(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_22(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_2_RX_W_PRIORITY_SS_23(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c00*/ u64 rx_w_round_robin_3;
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_24(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_25(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_26(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_27(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_28(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_29(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_30(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_3_RX_W_PRIORITY_SS_31(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c08*/ u64 rx_w_round_robin_4;
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_32(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_33(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_34(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_35(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_36(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_37(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_38(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_4_RX_W_PRIORITY_SS_39(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c10*/ u64 rx_w_round_robin_5;
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_40(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_41(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_42(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_43(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_44(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_45(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_46(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_5_RX_W_PRIORITY_SS_47(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c18*/ u64 rx_w_round_robin_6;
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_48(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_49(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_50(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_51(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_52(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_53(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_54(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_6_RX_W_PRIORITY_SS_55(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c20*/ u64 rx_w_round_robin_7;
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_56(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_57(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_58(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_59(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_60(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_61(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_62(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_7_RX_W_PRIORITY_SS_63(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c28*/ u64 rx_w_round_robin_8;
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_64(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_65(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_66(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_67(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_68(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_69(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_70(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_8_RX_W_PRIORITY_SS_71(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c30*/ u64 rx_w_round_robin_9;
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_72(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_73(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_74(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_75(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_76(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_77(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_78(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_9_RX_W_PRIORITY_SS_79(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c38*/ u64 rx_w_round_robin_10;
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_80(val) \
+ vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_81(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_82(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_83(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_84(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_85(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_86(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_10_RX_W_PRIORITY_SS_87(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c40*/ u64 rx_w_round_robin_11;
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_88(val) \
+ vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_89(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_90(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_91(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_92(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_93(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_94(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_11_RX_W_PRIORITY_SS_95(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c48*/ u64 rx_w_round_robin_12;
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_96(val) \
+ vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_97(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_98(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_99(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_100(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_101(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_102(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_12_RX_W_PRIORITY_SS_103(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c50*/ u64 rx_w_round_robin_13;
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_104(val) \
+ vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_105(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_106(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_107(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_108(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_109(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_110(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_13_RX_W_PRIORITY_SS_111(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c58*/ u64 rx_w_round_robin_14;
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_112(val) \
+ vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_113(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_114(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_115(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_116(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_117(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_118(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_14_RX_W_PRIORITY_SS_119(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c60*/ u64 rx_w_round_robin_15;
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_120(val) \
+ vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_121(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_122(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_123(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_124(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_125(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_126(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_15_RX_W_PRIORITY_SS_127(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c68*/ u64 rx_w_round_robin_16;
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_128(val) \
+ vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_129(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_130(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_131(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_132(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_133(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_134(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_16_RX_W_PRIORITY_SS_135(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c70*/ u64 rx_w_round_robin_17;
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_136(val) \
+ vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_137(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_138(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_139(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_140(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_141(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_142(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_17_RX_W_PRIORITY_SS_143(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c78*/ u64 rx_w_round_robin_18;
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_144(val) \
+ vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_145(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_146(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_147(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_148(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_149(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_150(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_18_RX_W_PRIORITY_SS_151(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c80*/ u64 rx_w_round_robin_19;
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_152(val) \
+ vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_153(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_154(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_155(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_156(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_157(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_158(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_19_RX_W_PRIORITY_SS_159(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c88*/ u64 rx_w_round_robin_20;
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_160(val) \
+ vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_161(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_162(val) \
+ vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_163(val) \
+ vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_164(val) \
+ vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_165(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_166(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_20_RX_W_PRIORITY_SS_167(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00c90*/ u64 rx_w_round_robin_21;
+#define VXGE_HW_RX_W_ROUND_ROBIN_21_RX_W_PRIORITY_SS_168(val) \
+ vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_21_RX_W_PRIORITY_SS_169(val) \
+ vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_W_ROUND_ROBIN_21_RX_W_PRIORITY_SS_170(val) \
+ vxge_vBIT(val, 19, 5)
+
+#define VXGE_HW_WRR_RING_SERVICE_STATES 171
+#define VXGE_HW_WRR_RING_COUNT 22
+
+/*0x00c98*/ u64 rx_queue_priority_0;
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_0(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_1(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_2(val) vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_3(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_4(val) vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_5(val) vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_6(val) vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_0_RX_Q_NUMBER_7(val) vxge_vBIT(val, 59, 5)
+/*0x00ca0*/ u64 rx_queue_priority_1;
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_8(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_9(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_10(val) vxge_vBIT(val, 19, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_11(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_12(val) vxge_vBIT(val, 35, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_13(val) vxge_vBIT(val, 43, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_14(val) vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RX_QUEUE_PRIORITY_1_RX_Q_NUMBER_15(val) vxge_vBIT(val, 59, 5)
+/*0x00ca8*/ u64 rx_queue_priority_2;
+#define VXGE_HW_RX_QUEUE_PRIORITY_2_RX_Q_NUMBER_16(val) vxge_vBIT(val, 3, 5)
+ u8 unused00cc8[0x00cc8-0x00cb0];
+
+/*0x00cc8*/ u64 replication_queue_priority;
+#define VXGE_HW_REPLICATION_QUEUE_PRIORITY_REPLICATION_QUEUE_PRIORITY(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00cd0*/ u64 rx_queue_select;
+#define VXGE_HW_RX_QUEUE_SELECT_NUMBER(n) vxge_mBIT(n)
+#define VXGE_HW_RX_QUEUE_SELECT_ENABLE_CODE vxge_mBIT(15)
+#define VXGE_HW_RX_QUEUE_SELECT_ENABLE_HIERARCHICAL_PRTY vxge_mBIT(23)
+/*0x00cd8*/ u64 rqa_vpbp_ctrl;
+#define VXGE_HW_RQA_VPBP_CTRL_WR_XON_DIS vxge_mBIT(15)
+#define VXGE_HW_RQA_VPBP_CTRL_ROCRC_DIS vxge_mBIT(23)
+#define VXGE_HW_RQA_VPBP_CTRL_TXPE_DIS vxge_mBIT(31)
+/*0x00ce0*/ u64 rx_multi_cast_ctrl;
+#define VXGE_HW_RX_MULTI_CAST_CTRL_TIME_OUT_DIS vxge_mBIT(0)
+#define VXGE_HW_RX_MULTI_CAST_CTRL_FRM_DROP_DIS vxge_mBIT(1)
+#define VXGE_HW_RX_MULTI_CAST_CTRL_NO_RXD_TIME_OUT_CNT(val) \
+ vxge_vBIT(val, 2, 30)
+#define VXGE_HW_RX_MULTI_CAST_CTRL_TIME_OUT_CNT(val) vxge_vBIT(val, 32, 32)
+/*0x00ce8*/ u64 wde_prm_ctrl;
+#define VXGE_HW_WDE_PRM_CTRL_SPAV_THRESHOLD(val) vxge_vBIT(val, 2, 10)
+#define VXGE_HW_WDE_PRM_CTRL_SPLIT_THRESHOLD(val) vxge_vBIT(val, 18, 14)
+#define VXGE_HW_WDE_PRM_CTRL_SPLIT_ON_1ST_ROW vxge_mBIT(32)
+#define VXGE_HW_WDE_PRM_CTRL_SPLIT_ON_ROW_BNDRY vxge_mBIT(33)
+#define VXGE_HW_WDE_PRM_CTRL_FB_ROW_SIZE(val) vxge_vBIT(val, 46, 2)
+/*0x00cf0*/ u64 noa_ctrl;
+#define VXGE_HW_NOA_CTRL_FRM_PRTY_QUOTA(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_NOA_CTRL_NON_FRM_PRTY_QUOTA(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_NOA_CTRL_IGNORE_KDFC_IF_STATUS vxge_mBIT(16)
+#define VXGE_HW_NOA_CTRL_MAX_JOB_CNT_FOR_WDE0(val) vxge_vBIT(val, 37, 4)
+#define VXGE_HW_NOA_CTRL_MAX_JOB_CNT_FOR_WDE1(val) vxge_vBIT(val, 45, 4)
+#define VXGE_HW_NOA_CTRL_MAX_JOB_CNT_FOR_WDE2(val) vxge_vBIT(val, 53, 4)
+#define VXGE_HW_NOA_CTRL_MAX_JOB_CNT_FOR_WDE3(val) vxge_vBIT(val, 60, 4)
+/*0x00cf8*/ u64 phase_cfg;
+#define VXGE_HW_PHASE_CFG_QCC_WR_PHASE_EN vxge_mBIT(0)
+#define VXGE_HW_PHASE_CFG_QCC_RD_PHASE_EN vxge_mBIT(3)
+#define VXGE_HW_PHASE_CFG_IMMM_WR_PHASE_EN vxge_mBIT(7)
+#define VXGE_HW_PHASE_CFG_IMMM_RD_PHASE_EN vxge_mBIT(11)
+#define VXGE_HW_PHASE_CFG_UMQM_WR_PHASE_EN vxge_mBIT(15)
+#define VXGE_HW_PHASE_CFG_UMQM_RD_PHASE_EN vxge_mBIT(19)
+#define VXGE_HW_PHASE_CFG_RCBM_WR_PHASE_EN vxge_mBIT(23)
+#define VXGE_HW_PHASE_CFG_RCBM_RD_PHASE_EN vxge_mBIT(27)
+#define VXGE_HW_PHASE_CFG_RXD_RC_WR_PHASE_EN vxge_mBIT(31)
+#define VXGE_HW_PHASE_CFG_RXD_RC_RD_PHASE_EN vxge_mBIT(35)
+#define VXGE_HW_PHASE_CFG_RXD_RHS_WR_PHASE_EN vxge_mBIT(39)
+#define VXGE_HW_PHASE_CFG_RXD_RHS_RD_PHASE_EN vxge_mBIT(43)
+/*0x00d00*/ u64 rcq_bypq_cfg;
+#define VXGE_HW_RCQ_BYPQ_CFG_OVERFLOW_THRESHOLD(val) vxge_vBIT(val, 10, 22)
+#define VXGE_HW_RCQ_BYPQ_CFG_BYP_ON_THRESHOLD(val) vxge_vBIT(val, 39, 9)
+#define VXGE_HW_RCQ_BYPQ_CFG_BYP_OFF_THRESHOLD(val) vxge_vBIT(val, 55, 9)
+ u8 unused00e00[0x00e00-0x00d08];
+
+/*0x00e00*/ u64 doorbell_int_status;
+#define VXGE_HW_DOORBELL_INT_STATUS_KDFC_ERR_REG_TXDMA_KDFC_INT vxge_mBIT(7)
+#define VXGE_HW_DOORBELL_INT_STATUS_USDC_ERR_REG_TXDMA_USDC_INT vxge_mBIT(15)
+/*0x00e08*/ u64 doorbell_int_mask;
+/*0x00e10*/ u64 kdfc_err_reg;
+#define VXGE_HW_KDFC_ERR_REG_KDFC_KDFC_ECC_SG_ERR vxge_mBIT(7)
+#define VXGE_HW_KDFC_ERR_REG_KDFC_KDFC_ECC_DB_ERR vxge_mBIT(15)
+#define VXGE_HW_KDFC_ERR_REG_KDFC_KDFC_SM_ERR_ALARM vxge_mBIT(23)
+#define VXGE_HW_KDFC_ERR_REG_KDFC_KDFC_MISC_ERR_1 vxge_mBIT(32)
+#define VXGE_HW_KDFC_ERR_REG_KDFC_KDFC_PCIX_ERR vxge_mBIT(39)
+/*0x00e18*/ u64 kdfc_err_mask;
+/*0x00e20*/ u64 kdfc_err_reg_alarm;
+#define VXGE_HW_KDFC_ERR_REG_ALARM_KDFC_KDFC_ECC_SG_ERR vxge_mBIT(7)
+#define VXGE_HW_KDFC_ERR_REG_ALARM_KDFC_KDFC_ECC_DB_ERR vxge_mBIT(15)
+#define VXGE_HW_KDFC_ERR_REG_ALARM_KDFC_KDFC_SM_ERR_ALARM vxge_mBIT(23)
+#define VXGE_HW_KDFC_ERR_REG_ALARM_KDFC_KDFC_MISC_ERR_1 vxge_mBIT(32)
+#define VXGE_HW_KDFC_ERR_REG_ALARM_KDFC_KDFC_PCIX_ERR vxge_mBIT(39)
+ u8 unused00e40[0x00e40-0x00e28];
+/*0x00e40*/ u64 kdfc_vp_partition_0;
+#define VXGE_HW_KDFC_VP_PARTITION_0_ENABLE vxge_mBIT(0)
+#define VXGE_HW_KDFC_VP_PARTITION_0_NUMBER_0(val) vxge_vBIT(val, 5, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_0_LENGTH_0(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_0_NUMBER_1(val) vxge_vBIT(val, 37, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_0_LENGTH_1(val) vxge_vBIT(val, 49, 15)
+/*0x00e48*/ u64 kdfc_vp_partition_1;
+#define VXGE_HW_KDFC_VP_PARTITION_1_NUMBER_2(val) vxge_vBIT(val, 5, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_1_LENGTH_2(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_1_NUMBER_3(val) vxge_vBIT(val, 37, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_1_LENGTH_3(val) vxge_vBIT(val, 49, 15)
+/*0x00e50*/ u64 kdfc_vp_partition_2;
+#define VXGE_HW_KDFC_VP_PARTITION_2_NUMBER_4(val) vxge_vBIT(val, 5, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_2_LENGTH_4(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_2_NUMBER_5(val) vxge_vBIT(val, 37, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_2_LENGTH_5(val) vxge_vBIT(val, 49, 15)
+/*0x00e58*/ u64 kdfc_vp_partition_3;
+#define VXGE_HW_KDFC_VP_PARTITION_3_NUMBER_6(val) vxge_vBIT(val, 5, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_3_LENGTH_6(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_3_NUMBER_7(val) vxge_vBIT(val, 37, 3)
+#define VXGE_HW_KDFC_VP_PARTITION_3_LENGTH_7(val) vxge_vBIT(val, 49, 15)
+/*0x00e60*/ u64 kdfc_vp_partition_4;
+#define VXGE_HW_KDFC_VP_PARTITION_4_LENGTH_8(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_4_LENGTH_9(val) vxge_vBIT(val, 49, 15)
+/*0x00e68*/ u64 kdfc_vp_partition_5;
+#define VXGE_HW_KDFC_VP_PARTITION_5_LENGTH_10(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_5_LENGTH_11(val) vxge_vBIT(val, 49, 15)
+/*0x00e70*/ u64 kdfc_vp_partition_6;
+#define VXGE_HW_KDFC_VP_PARTITION_6_LENGTH_12(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_6_LENGTH_13(val) vxge_vBIT(val, 49, 15)
+/*0x00e78*/ u64 kdfc_vp_partition_7;
+#define VXGE_HW_KDFC_VP_PARTITION_7_LENGTH_14(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_VP_PARTITION_7_LENGTH_15(val) vxge_vBIT(val, 49, 15)
+/*0x00e80*/ u64 kdfc_vp_partition_8;
+#define VXGE_HW_KDFC_VP_PARTITION_8_LENGTH_16(val) vxge_vBIT(val, 17, 15)
+/*0x00e88*/ u64 kdfc_w_round_robin_0;
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_0(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_1(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_2(val) vxge_vBIT(val, 19, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_3(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_4(val) vxge_vBIT(val, 35, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_5(val) vxge_vBIT(val, 43, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_6(val) vxge_vBIT(val, 51, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_0_NUMBER_7(val) vxge_vBIT(val, 59, 5)
+
+ u8 unused0f28[0x0f28-0x0e90];
+
+/*0x00f28*/ u64 kdfc_w_round_robin_20;
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_0(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_1(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_2(val) vxge_vBIT(val, 19, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_3(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_4(val) vxge_vBIT(val, 35, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_5(val) vxge_vBIT(val, 43, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_6(val) vxge_vBIT(val, 51, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_20_NUMBER_7(val) vxge_vBIT(val, 59, 5)
+
+#define VXGE_HW_WRR_FIFO_COUNT 20
+
+ u8 unused0fc8[0x0fc8-0x0f30];
+
+/*0x00fc8*/ u64 kdfc_w_round_robin_40;
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_0(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_1(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_2(val) vxge_vBIT(val, 19, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_3(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_4(val) vxge_vBIT(val, 35, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_5(val) vxge_vBIT(val, 43, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_6(val) vxge_vBIT(val, 51, 5)
+#define VXGE_HW_KDFC_W_ROUND_ROBIN_40_NUMBER_7(val) vxge_vBIT(val, 59, 5)
+
+ u8 unused1068[0x01068-0x0fd0];
+
+/*0x01068*/ u64 kdfc_entry_type_sel_0;
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_0(val) vxge_vBIT(val, 6, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_1(val) vxge_vBIT(val, 14, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_2(val) vxge_vBIT(val, 22, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_3(val) vxge_vBIT(val, 30, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_4(val) vxge_vBIT(val, 38, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_5(val) vxge_vBIT(val, 46, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_6(val) vxge_vBIT(val, 54, 2)
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_0_NUMBER_7(val) vxge_vBIT(val, 62, 2)
+/*0x01070*/ u64 kdfc_entry_type_sel_1;
+#define VXGE_HW_KDFC_ENTRY_TYPE_SEL_1_NUMBER_8(val) vxge_vBIT(val, 6, 2)
+/*0x01078*/ u64 kdfc_fifo_0_ctrl;
+#define VXGE_HW_KDFC_FIFO_0_CTRL_WRR_NUMBER(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_WEIGHTED_RR_SERVICE_STATES 176
+#define VXGE_HW_WRR_FIFO_SERVICE_STATES 153
+
+ u8 unused1100[0x01100-0x1080];
+
+/*0x01100*/ u64 kdfc_fifo_17_ctrl;
+#define VXGE_HW_KDFC_FIFO_17_CTRL_WRR_NUMBER(val) vxge_vBIT(val, 3, 5)
+
+ u8 unused1600[0x01600-0x1108];
+
+/*0x01600*/ u64 rxmac_int_status;
+#define VXGE_HW_RXMAC_INT_STATUS_RXMAC_GEN_ERR_RXMAC_GEN_INT vxge_mBIT(3)
+#define VXGE_HW_RXMAC_INT_STATUS_RXMAC_ECC_ERR_RXMAC_ECC_INT vxge_mBIT(7)
+#define VXGE_HW_RXMAC_INT_STATUS_RXMAC_VARIOUS_ERR_RXMAC_VARIOUS_INT \
+ vxge_mBIT(11)
+/*0x01608*/ u64 rxmac_int_mask;
+ u8 unused01618[0x01618-0x01610];
+
+/*0x01618*/ u64 rxmac_gen_err_reg;
+/*0x01620*/ u64 rxmac_gen_err_mask;
+/*0x01628*/ u64 rxmac_gen_err_alarm;
+/*0x01630*/ u64 rxmac_ecc_err_reg;
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RMAC_PORT0_RMAC_RTS_PART_SG_ERR(val) \
+ vxge_vBIT(val, 0, 4)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RMAC_PORT0_RMAC_RTS_PART_DB_ERR(val) \
+ vxge_vBIT(val, 4, 4)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RMAC_PORT1_RMAC_RTS_PART_SG_ERR(val) \
+ vxge_vBIT(val, 8, 4)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RMAC_PORT1_RMAC_RTS_PART_DB_ERR(val) \
+ vxge_vBIT(val, 12, 4)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RMAC_PORT2_RMAC_RTS_PART_SG_ERR(val) \
+ vxge_vBIT(val, 16, 4)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RMAC_PORT2_RMAC_RTS_PART_DB_ERR(val) \
+ vxge_vBIT(val, 20, 4)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_DA_LKP_PRT0_SG_ERR(val) \
+ vxge_vBIT(val, 24, 2)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_DA_LKP_PRT0_DB_ERR(val) \
+ vxge_vBIT(val, 26, 2)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_DA_LKP_PRT1_SG_ERR(val) \
+ vxge_vBIT(val, 28, 2)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_DA_LKP_PRT1_DB_ERR(val) \
+ vxge_vBIT(val, 30, 2)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_VID_LKP_SG_ERR vxge_mBIT(32)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_VID_LKP_DB_ERR vxge_mBIT(33)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_PN_LKP_PRT0_SG_ERR vxge_mBIT(34)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_PN_LKP_PRT0_DB_ERR vxge_mBIT(35)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_PN_LKP_PRT1_SG_ERR vxge_mBIT(36)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_PN_LKP_PRT1_DB_ERR vxge_mBIT(37)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_PN_LKP_PRT2_SG_ERR vxge_mBIT(38)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_PN_LKP_PRT2_DB_ERR vxge_mBIT(39)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_RTH_MASK_SG_ERR(val) \
+ vxge_vBIT(val, 40, 7)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_RTH_MASK_DB_ERR(val) \
+ vxge_vBIT(val, 47, 7)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_RTH_LKP_SG_ERR(val) \
+ vxge_vBIT(val, 54, 3)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_RTH_LKP_DB_ERR(val) \
+ vxge_vBIT(val, 57, 3)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_DS_LKP_SG_ERR \
+ vxge_mBIT(60)
+#define VXGE_HW_RXMAC_ECC_ERR_REG_RTSJ_RMAC_DS_LKP_DB_ERR \
+ vxge_mBIT(61)
+/*0x01638*/ u64 rxmac_ecc_err_mask;
+/*0x01640*/ u64 rxmac_ecc_err_alarm;
+/*0x01648*/ u64 rxmac_various_err_reg;
+#define VXGE_HW_RXMAC_VARIOUS_ERR_REG_RMAC_RMAC_PORT0_FSM_ERR vxge_mBIT(0)
+#define VXGE_HW_RXMAC_VARIOUS_ERR_REG_RMAC_RMAC_PORT1_FSM_ERR vxge_mBIT(1)
+#define VXGE_HW_RXMAC_VARIOUS_ERR_REG_RMAC_RMAC_PORT2_FSM_ERR vxge_mBIT(2)
+#define VXGE_HW_RXMAC_VARIOUS_ERR_REG_RMACJ_RMACJ_FSM_ERR vxge_mBIT(3)
+/*0x01650*/ u64 rxmac_various_err_mask;
+/*0x01658*/ u64 rxmac_various_err_alarm;
+/*0x01660*/ u64 rxmac_gen_cfg;
+#define VXGE_HW_RXMAC_GEN_CFG_SCALE_RMAC_UTIL vxge_mBIT(11)
+/*0x01668*/ u64 rxmac_authorize_all_addr;
+#define VXGE_HW_RXMAC_AUTHORIZE_ALL_ADDR_VP(n) vxge_mBIT(n)
+/*0x01670*/ u64 rxmac_authorize_all_vid;
+#define VXGE_HW_RXMAC_AUTHORIZE_ALL_VID_VP(n) vxge_mBIT(n)
+ u8 unused016c0[0x016c0-0x01678];
+
+/*0x016c0*/ u64 rxmac_red_rate_repl_queue;
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_CRATE_THR0(val) vxge_vBIT(val, 0, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_CRATE_THR1(val) vxge_vBIT(val, 4, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_CRATE_THR2(val) vxge_vBIT(val, 8, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_CRATE_THR3(val) vxge_vBIT(val, 12, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_FRATE_THR0(val) vxge_vBIT(val, 16, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_FRATE_THR1(val) vxge_vBIT(val, 20, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_FRATE_THR2(val) vxge_vBIT(val, 24, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_FRATE_THR3(val) vxge_vBIT(val, 28, 4)
+#define VXGE_HW_RXMAC_RED_RATE_REPL_QUEUE_TRICKLE_EN vxge_mBIT(35)
+ u8 unused016e0[0x016e0-0x016c8];
+
+/*0x016e0*/ u64 rxmac_cfg0_port[3];
+#define VXGE_HW_RXMAC_CFG0_PORT_RMAC_EN vxge_mBIT(3)
+#define VXGE_HW_RXMAC_CFG0_PORT_STRIP_FCS vxge_mBIT(7)
+#define VXGE_HW_RXMAC_CFG0_PORT_DISCARD_PFRM vxge_mBIT(11)
+#define VXGE_HW_RXMAC_CFG0_PORT_IGNORE_FCS_ERR vxge_mBIT(15)
+#define VXGE_HW_RXMAC_CFG0_PORT_IGNORE_LONG_ERR vxge_mBIT(19)
+#define VXGE_HW_RXMAC_CFG0_PORT_IGNORE_USIZED_ERR vxge_mBIT(23)
+#define VXGE_HW_RXMAC_CFG0_PORT_IGNORE_LEN_MISMATCH vxge_mBIT(27)
+#define VXGE_HW_RXMAC_CFG0_PORT_MAX_PYLD_LEN(val) vxge_vBIT(val, 50, 14)
+ u8 unused01710[0x01710-0x016f8];
+
+/*0x01710*/ u64 rxmac_cfg2_port[3];
+#define VXGE_HW_RXMAC_CFG2_PORT_PROM_EN vxge_mBIT(3)
+/*0x01728*/ u64 rxmac_pause_cfg_port[3];
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_GEN_EN vxge_mBIT(3)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_RCV_EN vxge_mBIT(7)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_ACCEL_SEND(val) vxge_vBIT(val, 9, 3)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_DUAL_THR vxge_mBIT(15)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_HIGH_PTIME(val) vxge_vBIT(val, 20, 16)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_IGNORE_PF_FCS_ERR vxge_mBIT(39)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_IGNORE_PF_LEN_ERR vxge_mBIT(43)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_LIMITER_EN vxge_mBIT(47)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_MAX_LIMIT(val) vxge_vBIT(val, 48, 8)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_PERMIT_RATEMGMT_CTRL vxge_mBIT(59)
+ u8 unused01758[0x01758-0x01740];
+
+/*0x01758*/ u64 rxmac_red_cfg0_port[3];
+#define VXGE_HW_RXMAC_RED_CFG0_PORT_RED_EN_VP(n) vxge_mBIT(n)
+/*0x01770*/ u64 rxmac_red_cfg1_port[3];
+#define VXGE_HW_RXMAC_RED_CFG1_PORT_FINE_EN vxge_mBIT(3)
+#define VXGE_HW_RXMAC_RED_CFG1_PORT_RED_EN_REPL_QUEUE vxge_mBIT(11)
+/*0x01788*/ u64 rxmac_red_cfg2_port[3];
+#define VXGE_HW_RXMAC_RED_CFG2_PORT_TRICKLE_EN_VP(n) vxge_mBIT(n)
+/*0x017a0*/ u64 rxmac_link_util_port[3];
+#define VXGE_HW_RXMAC_LINK_UTIL_PORT_RMAC_RMAC_UTILIZATION(val) \
+ vxge_vBIT(val, 1, 7)
+#define VXGE_HW_RXMAC_LINK_UTIL_PORT_RMAC_UTIL_CFG(val) vxge_vBIT(val, 8, 4)
+#define VXGE_HW_RXMAC_LINK_UTIL_PORT_RMAC_RMAC_FRAC_UTIL(val) \
+ vxge_vBIT(val, 12, 4)
+#define VXGE_HW_RXMAC_LINK_UTIL_PORT_RMAC_PKT_WEIGHT(val) vxge_vBIT(val, 16, 4)
+#define VXGE_HW_RXMAC_LINK_UTIL_PORT_RMAC_RMAC_SCALE_FACTOR vxge_mBIT(23)
+ u8 unused017d0[0x017d0-0x017b8];
+
+/*0x017d0*/ u64 rxmac_status_port[3];
+#define VXGE_HW_RXMAC_STATUS_PORT_RMAC_RX_FRM_RCVD vxge_mBIT(3)
+ u8 unused01800[0x01800-0x017e8];
+
+/*0x01800*/ u64 rxmac_rx_pa_cfg0;
+#define VXGE_HW_RXMAC_RX_PA_CFG0_IGNORE_FRAME_ERR vxge_mBIT(3)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_SUPPORT_SNAP_AB_N vxge_mBIT(7)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_SEARCH_FOR_HAO vxge_mBIT(18)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_SUPPORT_MOBILE_IPV6_HDRS vxge_mBIT(19)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_IPV6_STOP_SEARCHING vxge_mBIT(23)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_NO_PS_IF_UNKNOWN vxge_mBIT(27)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_SEARCH_FOR_ETYPE vxge_mBIT(35)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_TOSS_ANY_FRM_IF_L3_CSUM_ERR vxge_mBIT(39)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_TOSS_OFFLD_FRM_IF_L3_CSUM_ERR vxge_mBIT(43)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_TOSS_ANY_FRM_IF_L4_CSUM_ERR vxge_mBIT(47)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_TOSS_OFFLD_FRM_IF_L4_CSUM_ERR vxge_mBIT(51)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_TOSS_ANY_FRM_IF_RPA_ERR vxge_mBIT(55)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_TOSS_OFFLD_FRM_IF_RPA_ERR vxge_mBIT(59)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_JUMBO_SNAP_EN vxge_mBIT(63)
+/*0x01808*/ u64 rxmac_rx_pa_cfg1;
+#define VXGE_HW_RXMAC_RX_PA_CFG1_REPL_IPV4_TCP_INCL_PH vxge_mBIT(3)
+#define VXGE_HW_RXMAC_RX_PA_CFG1_REPL_IPV6_TCP_INCL_PH vxge_mBIT(7)
+#define VXGE_HW_RXMAC_RX_PA_CFG1_REPL_IPV4_UDP_INCL_PH vxge_mBIT(11)
+#define VXGE_HW_RXMAC_RX_PA_CFG1_REPL_IPV6_UDP_INCL_PH vxge_mBIT(15)
+#define VXGE_HW_RXMAC_RX_PA_CFG1_REPL_L4_INCL_CF vxge_mBIT(19)
+#define VXGE_HW_RXMAC_RX_PA_CFG1_REPL_STRIP_VLAN_TAG vxge_mBIT(23)
+ u8 unused01828[0x01828-0x01810];
+
+/*0x01828*/ u64 rts_mgr_cfg0;
+#define VXGE_HW_RTS_MGR_CFG0_RTS_DP_SP_PRIORITY vxge_mBIT(3)
+#define VXGE_HW_RTS_MGR_CFG0_FLEX_L4PRTCL_VALUE(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_RTS_MGR_CFG0_ICMP_TRASH vxge_mBIT(35)
+#define VXGE_HW_RTS_MGR_CFG0_TCPSYN_TRASH vxge_mBIT(39)
+#define VXGE_HW_RTS_MGR_CFG0_ZL4PYLD_TRASH vxge_mBIT(43)
+#define VXGE_HW_RTS_MGR_CFG0_L4PRTCL_TCP_TRASH vxge_mBIT(47)
+#define VXGE_HW_RTS_MGR_CFG0_L4PRTCL_UDP_TRASH vxge_mBIT(51)
+#define VXGE_HW_RTS_MGR_CFG0_L4PRTCL_FLEX_TRASH vxge_mBIT(55)
+#define VXGE_HW_RTS_MGR_CFG0_IPFRAG_TRASH vxge_mBIT(59)
+/*0x01830*/ u64 rts_mgr_cfg1;
+#define VXGE_HW_RTS_MGR_CFG1_DA_ACTIVE_TABLE vxge_mBIT(3)
+#define VXGE_HW_RTS_MGR_CFG1_PN_ACTIVE_TABLE vxge_mBIT(7)
+/*0x01838*/ u64 rts_mgr_criteria_priority;
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_ETYPE(val) vxge_vBIT(val, 5, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_ICMP_TCPSYN(val) vxge_vBIT(val, 9, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_L4PN(val) vxge_vBIT(val, 13, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_RANGE_L4PN(val) vxge_vBIT(val, 17, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_RTH_IT(val) vxge_vBIT(val, 21, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_DS(val) vxge_vBIT(val, 25, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_QOS(val) vxge_vBIT(val, 29, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_ZL4PYLD(val) vxge_vBIT(val, 33, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_L4PRTCL(val) vxge_vBIT(val, 37, 3)
+/*0x01840*/ u64 rts_mgr_da_pause_cfg;
+#define VXGE_HW_RTS_MGR_DA_PAUSE_CFG_VPATH_VECTOR(val) vxge_vBIT(val, 0, 17)
+/*0x01848*/ u64 rts_mgr_da_slow_proto_cfg;
+#define VXGE_HW_RTS_MGR_DA_SLOW_PROTO_CFG_VPATH_VECTOR(val) \
+ vxge_vBIT(val, 0, 17)
+ u8 unused01890[0x01890-0x01850];
+/*0x01890*/ u64 rts_mgr_cbasin_cfg;
+ u8 unused01968[0x01968-0x01898];
+
+/*0x01968*/ u64 dbg_stat_rx_any_frms;
+#define VXGE_HW_DBG_STAT_RX_ANY_FRMS_PORT0_RX_ANY_FRMS(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_DBG_STAT_RX_ANY_FRMS_PORT1_RX_ANY_FRMS(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_DBG_STAT_RX_ANY_FRMS_PORT2_RX_ANY_FRMS(val) \
+ vxge_vBIT(val, 16, 8)
+ u8 unused01a00[0x01a00-0x01970];
+
+/*0x01a00*/ u64 rxmac_red_rate_vp[17];
+#define VXGE_HW_RXMAC_RED_RATE_VP_CRATE_THR0(val) vxge_vBIT(val, 0, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_CRATE_THR1(val) vxge_vBIT(val, 4, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_CRATE_THR2(val) vxge_vBIT(val, 8, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_CRATE_THR3(val) vxge_vBIT(val, 12, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_FRATE_THR0(val) vxge_vBIT(val, 16, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_FRATE_THR1(val) vxge_vBIT(val, 20, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_FRATE_THR2(val) vxge_vBIT(val, 24, 4)
+#define VXGE_HW_RXMAC_RED_RATE_VP_FRATE_THR3(val) vxge_vBIT(val, 28, 4)
+ u8 unused01e00[0x01e00-0x01a88];
+
+/*0x01e00*/ u64 xgmac_int_status;
+#define VXGE_HW_XGMAC_INT_STATUS_XMAC_GEN_ERR_XMAC_GEN_INT vxge_mBIT(3)
+#define VXGE_HW_XGMAC_INT_STATUS_XMAC_LINK_ERR_PORT0_XMAC_LINK_INT_PORT0 \
+ vxge_mBIT(7)
+#define VXGE_HW_XGMAC_INT_STATUS_XMAC_LINK_ERR_PORT1_XMAC_LINK_INT_PORT1 \
+ vxge_mBIT(11)
+#define VXGE_HW_XGMAC_INT_STATUS_XGXS_GEN_ERR_XGXS_GEN_INT vxge_mBIT(15)
+#define VXGE_HW_XGMAC_INT_STATUS_ASIC_NTWK_ERR_ASIC_NTWK_INT vxge_mBIT(19)
+#define VXGE_HW_XGMAC_INT_STATUS_ASIC_GPIO_ERR_ASIC_GPIO_INT vxge_mBIT(23)
+/*0x01e08*/ u64 xgmac_int_mask;
+/*0x01e10*/ u64 xmac_gen_err_reg;
+#define VXGE_HW_XMAC_GEN_ERR_REG_LAGC_LAG_PORT0_ACTOR_CHURN_DETECTED \
+ vxge_mBIT(7)
+#define VXGE_HW_XMAC_GEN_ERR_REG_LAGC_LAG_PORT0_PARTNER_CHURN_DETECTED \
+ vxge_mBIT(11)
+#define VXGE_HW_XMAC_GEN_ERR_REG_LAGC_LAG_PORT0_RECEIVED_LACPDU vxge_mBIT(15)
+#define VXGE_HW_XMAC_GEN_ERR_REG_LAGC_LAG_PORT1_ACTOR_CHURN_DETECTED \
+ vxge_mBIT(19)
+#define VXGE_HW_XMAC_GEN_ERR_REG_LAGC_LAG_PORT1_PARTNER_CHURN_DETECTED \
+ vxge_mBIT(23)
+#define VXGE_HW_XMAC_GEN_ERR_REG_LAGC_LAG_PORT1_RECEIVED_LACPDU vxge_mBIT(27)
+#define VXGE_HW_XMAC_GEN_ERR_REG_XLCM_LAG_FAILOVER_DETECTED vxge_mBIT(31)
+#define VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE0_SG_ERR(val) \
+ vxge_vBIT(val, 40, 2)
+#define VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE0_DB_ERR(val) \
+ vxge_vBIT(val, 42, 2)
+#define VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE1_SG_ERR(val) \
+ vxge_vBIT(val, 44, 2)
+#define VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE1_DB_ERR(val) \
+ vxge_vBIT(val, 46, 2)
+#define VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE2_SG_ERR(val) \
+ vxge_vBIT(val, 48, 2)
+#define VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE2_DB_ERR(val) \
+ vxge_vBIT(val, 50, 2)
+#define VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE3_SG_ERR(val) \
+ vxge_vBIT(val, 52, 2)
+#define VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE3_DB_ERR(val) \
+ vxge_vBIT(val, 54, 2)
+#define VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE4_SG_ERR(val) \
+ vxge_vBIT(val, 56, 2)
+#define VXGE_HW_XMAC_GEN_ERR_REG_XSTATS_RMAC_STATS_TILE4_DB_ERR(val) \
+ vxge_vBIT(val, 58, 2)
+#define VXGE_HW_XMAC_GEN_ERR_REG_XMACJ_XMAC_FSM_ERR vxge_mBIT(63)
+/*0x01e18*/ u64 xmac_gen_err_mask;
+/*0x01e20*/ u64 xmac_gen_err_alarm;
+/*0x01e28*/ u64 xmac_link_err_port_reg[2];
+#define VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_DOWN vxge_mBIT(3)
+#define VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_UP vxge_mBIT(7)
+#define VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_WENT_DOWN vxge_mBIT(11)
+#define VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_WENT_UP vxge_mBIT(15)
+#define VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_REAFFIRMED_FAULT \
+ vxge_mBIT(19)
+#define VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_REAFFIRMED_OK vxge_mBIT(23)
+#define VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_LINK_DOWN vxge_mBIT(27)
+#define VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_LINK_UP vxge_mBIT(31)
+#define VXGE_HW_XMAC_LINK_ERR_PORT_REG_RATEMGMT_RATE_CHANGE vxge_mBIT(35)
+#define VXGE_HW_XMAC_LINK_ERR_PORT_REG_RATEMGMT_LASI_INV vxge_mBIT(39)
+#define VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMDIO_MDIO_MGR_ACCESS_COMPLETE \
+ vxge_mBIT(47)
+/*0x01e30*/ u64 xmac_link_err_port_mask[2];
+/*0x01e38*/ u64 xmac_link_err_port_alarm[2];
+/*0x01e58*/ u64 xgxs_gen_err_reg;
+#define VXGE_HW_XGXS_GEN_ERR_REG_XGXS_XGXS_FSM_ERR vxge_mBIT(63)
+/*0x01e60*/ u64 xgxs_gen_err_mask;
+/*0x01e68*/ u64 xgxs_gen_err_alarm;
+/*0x01e70*/ u64 asic_ntwk_err_reg;
+#define VXGE_HW_ASIC_NTWK_ERR_REG_XMACJ_NTWK_DOWN vxge_mBIT(3)
+#define VXGE_HW_ASIC_NTWK_ERR_REG_XMACJ_NTWK_UP vxge_mBIT(7)
+#define VXGE_HW_ASIC_NTWK_ERR_REG_XMACJ_NTWK_WENT_DOWN vxge_mBIT(11)
+#define VXGE_HW_ASIC_NTWK_ERR_REG_XMACJ_NTWK_WENT_UP vxge_mBIT(15)
+#define VXGE_HW_ASIC_NTWK_ERR_REG_XMACJ_NTWK_REAFFIRMED_FAULT vxge_mBIT(19)
+#define VXGE_HW_ASIC_NTWK_ERR_REG_XMACJ_NTWK_REAFFIRMED_OK vxge_mBIT(23)
+/*0x01e78*/ u64 asic_ntwk_err_mask;
+/*0x01e80*/ u64 asic_ntwk_err_alarm;
+/*0x01e88*/ u64 asic_gpio_err_reg;
+#define VXGE_HW_ASIC_GPIO_ERR_REG_XMACJ_GPIO_INT(n) vxge_mBIT(n)
+/*0x01e90*/ u64 asic_gpio_err_mask;
+/*0x01e98*/ u64 asic_gpio_err_alarm;
+/*0x01ea0*/ u64 xgmac_gen_status;
+#define VXGE_HW_XGMAC_GEN_STATUS_XMACJ_NTWK_OK vxge_mBIT(3)
+#define VXGE_HW_XGMAC_GEN_STATUS_XMACJ_NTWK_DATA_RATE vxge_mBIT(11)
+/*0x01ea8*/ u64 xgmac_gen_fw_memo_status;
+#define VXGE_HW_XGMAC_GEN_FW_MEMO_STATUS_XMACJ_EVENTS_PENDING(val) \
+ vxge_vBIT(val, 0, 17)
+/*0x01eb0*/ u64 xgmac_gen_fw_memo_mask;
+#define VXGE_HW_XGMAC_GEN_FW_MEMO_MASK_MASK(val) vxge_vBIT(val, 0, 64)
+/*0x01eb8*/ u64 xgmac_gen_fw_vpath_to_vsport_status;
+#define VXGE_HW_XGMAC_GEN_FW_VPATH_TO_VSPORT_STATUS_XMACJ_EVENTS_PENDING(val) \
+ vxge_vBIT(val, 0, 17)
+/*0x01ec0*/ u64 xgmac_main_cfg_port[2];
+#define VXGE_HW_XGMAC_MAIN_CFG_PORT_PORT_EN vxge_mBIT(3)
+ u8 unused01f40[0x01f40-0x01ed0];
+
+/*0x01f40*/ u64 xmac_gen_cfg;
+#define VXGE_HW_XMAC_GEN_CFG_RATEMGMT_MAC_RATE_SEL(val) vxge_vBIT(val, 2, 2)
+#define VXGE_HW_XMAC_GEN_CFG_TX_HEAD_DROP_WHEN_FAULT vxge_mBIT(7)
+#define VXGE_HW_XMAC_GEN_CFG_FAULT_BEHAVIOUR vxge_mBIT(27)
+#define VXGE_HW_XMAC_GEN_CFG_PERIOD_NTWK_UP(val) vxge_vBIT(val, 28, 4)
+#define VXGE_HW_XMAC_GEN_CFG_PERIOD_NTWK_DOWN(val) vxge_vBIT(val, 32, 4)
+/*0x01f48*/ u64 xmac_timestamp;
+#define VXGE_HW_XMAC_TIMESTAMP_EN vxge_mBIT(3)
+#define VXGE_HW_XMAC_TIMESTAMP_USE_LINK_ID(val) vxge_vBIT(val, 6, 2)
+#define VXGE_HW_XMAC_TIMESTAMP_INTERVAL(val) vxge_vBIT(val, 12, 4)
+#define VXGE_HW_XMAC_TIMESTAMP_TIMER_RESTART vxge_mBIT(19)
+#define VXGE_HW_XMAC_TIMESTAMP_XMACJ_ROLLOVER_CNT(val) vxge_vBIT(val, 32, 16)
+/*0x01f50*/ u64 xmac_stats_gen_cfg;
+#define VXGE_HW_XMAC_STATS_GEN_CFG_PRTAGGR_CUM_TIMER(val) vxge_vBIT(val, 4, 4)
+#define VXGE_HW_XMAC_STATS_GEN_CFG_VPATH_CUM_TIMER(val) vxge_vBIT(val, 8, 4)
+#define VXGE_HW_XMAC_STATS_GEN_CFG_VLAN_HANDLING vxge_mBIT(15)
+/*0x01f58*/ u64 xmac_stats_sys_cmd;
+#define VXGE_HW_XMAC_STATS_SYS_CMD_OP(val) vxge_vBIT(val, 5, 3)
+#define VXGE_HW_XMAC_STATS_SYS_CMD_STROBE vxge_mBIT(15)
+#define VXGE_HW_XMAC_STATS_SYS_CMD_LOC_SEL(val) vxge_vBIT(val, 27, 5)
+#define VXGE_HW_XMAC_STATS_SYS_CMD_OFFSET_SEL(val) vxge_vBIT(val, 32, 8)
+/*0x01f60*/ u64 xmac_stats_sys_data;
+#define VXGE_HW_XMAC_STATS_SYS_DATA_XSMGR_DATA(val) vxge_vBIT(val, 0, 64)
+ u8 unused01f80[0x01f80-0x01f68];
+
+/*0x01f80*/ u64 asic_ntwk_ctrl;
+#define VXGE_HW_ASIC_NTWK_CTRL_REQ_TEST_NTWK vxge_mBIT(3)
+#define VXGE_HW_ASIC_NTWK_CTRL_PORT0_REQ_TEST_PORT vxge_mBIT(11)
+#define VXGE_HW_ASIC_NTWK_CTRL_PORT1_REQ_TEST_PORT vxge_mBIT(15)
+/*0x01f88*/ u64 asic_ntwk_cfg_show_port_info;
+#define VXGE_HW_ASIC_NTWK_CFG_SHOW_PORT_INFO_VP(n) vxge_mBIT(n)
+/*0x01f90*/ u64 asic_ntwk_cfg_port_num;
+#define VXGE_HW_ASIC_NTWK_CFG_PORT_NUM_VP(n) vxge_mBIT(n)
+/*0x01f98*/ u64 xmac_cfg_port[3];
+#define VXGE_HW_XMAC_CFG_PORT_XGMII_LOOPBACK vxge_mBIT(3)
+#define VXGE_HW_XMAC_CFG_PORT_XGMII_REVERSE_LOOPBACK vxge_mBIT(7)
+#define VXGE_HW_XMAC_CFG_PORT_XGMII_TX_BEHAV vxge_mBIT(11)
+#define VXGE_HW_XMAC_CFG_PORT_XGMII_RX_BEHAV vxge_mBIT(15)
+/*0x01fb0*/ u64 xmac_station_addr_port[2];
+#define VXGE_HW_XMAC_STATION_ADDR_PORT_MAC_ADDR(val) vxge_vBIT(val, 0, 48)
+ u8 unused02020[0x02020-0x01fc0];
+
+/*0x02020*/ u64 lag_cfg;
+#define VXGE_HW_LAG_CFG_EN vxge_mBIT(3)
+#define VXGE_HW_LAG_CFG_MODE(val) vxge_vBIT(val, 6, 2)
+#define VXGE_HW_LAG_CFG_TX_DISCARD_BEHAV vxge_mBIT(11)
+#define VXGE_HW_LAG_CFG_RX_DISCARD_BEHAV vxge_mBIT(15)
+#define VXGE_HW_LAG_CFG_PREF_INDIV_PORT_NUM vxge_mBIT(19)
+/*0x02028*/ u64 lag_status;
+#define VXGE_HW_LAG_STATUS_XLCM_WAITING_TO_FAILBACK vxge_mBIT(3)
+#define VXGE_HW_LAG_STATUS_XLCM_TIMER_VAL_COLD_FAILOVER(val) \
+ vxge_vBIT(val, 8, 8)
+/*0x02030*/ u64 lag_active_passive_cfg;
+#define VXGE_HW_LAG_ACTIVE_PASSIVE_CFG_HOT_STANDBY vxge_mBIT(3)
+#define VXGE_HW_LAG_ACTIVE_PASSIVE_CFG_LACP_DECIDES vxge_mBIT(7)
+#define VXGE_HW_LAG_ACTIVE_PASSIVE_CFG_PREF_ACTIVE_PORT_NUM vxge_mBIT(11)
+#define VXGE_HW_LAG_ACTIVE_PASSIVE_CFG_AUTO_FAILBACK vxge_mBIT(15)
+#define VXGE_HW_LAG_ACTIVE_PASSIVE_CFG_FAILBACK_EN vxge_mBIT(19)
+#define VXGE_HW_LAG_ACTIVE_PASSIVE_CFG_COLD_FAILOVER_TIMEOUT(val) \
+ vxge_vBIT(val, 32, 16)
+ u8 unused02040[0x02040-0x02038];
+
+/*0x02040*/ u64 lag_lacp_cfg;
+#define VXGE_HW_LAG_LACP_CFG_EN vxge_mBIT(3)
+#define VXGE_HW_LAG_LACP_CFG_LACP_BEGIN vxge_mBIT(7)
+#define VXGE_HW_LAG_LACP_CFG_DISCARD_LACP vxge_mBIT(11)
+#define VXGE_HW_LAG_LACP_CFG_LIBERAL_LEN_CHK vxge_mBIT(15)
+/*0x02048*/ u64 lag_timer_cfg_1;
+#define VXGE_HW_LAG_TIMER_CFG_1_FAST_PER(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_LAG_TIMER_CFG_1_SLOW_PER(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_LAG_TIMER_CFG_1_SHORT_TIMEOUT(val) vxge_vBIT(val, 32, 16)
+#define VXGE_HW_LAG_TIMER_CFG_1_LONG_TIMEOUT(val) vxge_vBIT(val, 48, 16)
+/*0x02050*/ u64 lag_timer_cfg_2;
+#define VXGE_HW_LAG_TIMER_CFG_2_CHURN_DET(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_LAG_TIMER_CFG_2_AGGR_WAIT(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_LAG_TIMER_CFG_2_SHORT_TIMER_SCALE(val) vxge_vBIT(val, 32, 16)
+#define VXGE_HW_LAG_TIMER_CFG_2_LONG_TIMER_SCALE(val) vxge_vBIT(val, 48, 16)
+/*0x02058*/ u64 lag_sys_id;
+#define VXGE_HW_LAG_SYS_ID_ADDR(val) vxge_vBIT(val, 0, 48)
+#define VXGE_HW_LAG_SYS_ID_USE_PORT_ADDR vxge_mBIT(51)
+#define VXGE_HW_LAG_SYS_ID_ADDR_SEL vxge_mBIT(55)
+/*0x02060*/ u64 lag_sys_cfg;
+#define VXGE_HW_LAG_SYS_CFG_SYS_PRI(val) vxge_vBIT(val, 0, 16)
+ u8 unused02070[0x02070-0x02068];
+
+/*0x02070*/ u64 lag_aggr_addr_cfg[2];
+#define VXGE_HW_LAG_AGGR_ADDR_CFG_ADDR(val) vxge_vBIT(val, 0, 48)
+#define VXGE_HW_LAG_AGGR_ADDR_CFG_USE_PORT_ADDR vxge_mBIT(51)
+#define VXGE_HW_LAG_AGGR_ADDR_CFG_ADDR_SEL vxge_mBIT(55)
+/*0x02080*/ u64 lag_aggr_id_cfg[2];
+#define VXGE_HW_LAG_AGGR_ID_CFG_ID(val) vxge_vBIT(val, 0, 16)
+/*0x02090*/ u64 lag_aggr_admin_key[2];
+#define VXGE_HW_LAG_AGGR_ADMIN_KEY_KEY(val) vxge_vBIT(val, 0, 16)
+/*0x020a0*/ u64 lag_aggr_alt_admin_key;
+#define VXGE_HW_LAG_AGGR_ALT_ADMIN_KEY_KEY(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_LAG_AGGR_ALT_ADMIN_KEY_ALT_AGGR vxge_mBIT(19)
+/*0x020a8*/ u64 lag_aggr_oper_key[2];
+#define VXGE_HW_LAG_AGGR_OPER_KEY_LAGC_KEY(val) vxge_vBIT(val, 0, 16)
+/*0x020b8*/ u64 lag_aggr_partner_sys_id[2];
+#define VXGE_HW_LAG_AGGR_PARTNER_SYS_ID_LAGC_ADDR(val) vxge_vBIT(val, 0, 48)
+/*0x020c8*/ u64 lag_aggr_partner_info[2];
+#define VXGE_HW_LAG_AGGR_PARTNER_INFO_LAGC_SYS_PRI(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_LAG_AGGR_PARTNER_INFO_LAGC_OPER_KEY(val) \
+ vxge_vBIT(val, 16, 16)
+/*0x020d8*/ u64 lag_aggr_state[2];
+#define VXGE_HW_LAG_AGGR_STATE_LAGC_TX vxge_mBIT(3)
+#define VXGE_HW_LAG_AGGR_STATE_LAGC_RX vxge_mBIT(7)
+#define VXGE_HW_LAG_AGGR_STATE_LAGC_READY vxge_mBIT(11)
+#define VXGE_HW_LAG_AGGR_STATE_LAGC_INDIVIDUAL vxge_mBIT(15)
+ u8 unused020f0[0x020f0-0x020e8];
+
+/*0x020f0*/ u64 lag_port_cfg[2];
+#define VXGE_HW_LAG_PORT_CFG_EN vxge_mBIT(3)
+#define VXGE_HW_LAG_PORT_CFG_DISCARD_SLOW_PROTO vxge_mBIT(7)
+#define VXGE_HW_LAG_PORT_CFG_HOST_CHOSEN_AGGR vxge_mBIT(11)
+#define VXGE_HW_LAG_PORT_CFG_DISCARD_UNKNOWN_SLOW_PROTO vxge_mBIT(15)
+/*0x02100*/ u64 lag_port_actor_admin_cfg[2];
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_CFG_PORT_NUM(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_CFG_PORT_PRI(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_CFG_KEY_10G(val) vxge_vBIT(val, 32, 16)
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_CFG_KEY_1G(val) vxge_vBIT(val, 48, 16)
+/*0x02110*/ u64 lag_port_actor_admin_state[2];
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_LACP_ACTIVITY vxge_mBIT(3)
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_LACP_TIMEOUT vxge_mBIT(7)
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_AGGREGATION vxge_mBIT(11)
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_SYNCHRONIZATION vxge_mBIT(15)
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_COLLECTING vxge_mBIT(19)
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_DISTRIBUTING vxge_mBIT(23)
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_DEFAULTED vxge_mBIT(27)
+#define VXGE_HW_LAG_PORT_ACTOR_ADMIN_STATE_EXPIRED vxge_mBIT(31)
+/*0x02120*/ u64 lag_port_partner_admin_sys_id[2];
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_SYS_ID_ADDR(val) vxge_vBIT(val, 0, 48)
+/*0x02130*/ u64 lag_port_partner_admin_cfg[2];
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_CFG_SYS_PRI(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_CFG_KEY(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_CFG_PORT_NUM(val) \
+ vxge_vBIT(val, 32, 16)
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_CFG_PORT_PRI(val) \
+ vxge_vBIT(val, 48, 16)
+/*0x02140*/ u64 lag_port_partner_admin_state[2];
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_LACP_ACTIVITY vxge_mBIT(3)
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_LACP_TIMEOUT vxge_mBIT(7)
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_AGGREGATION vxge_mBIT(11)
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_SYNCHRONIZATION vxge_mBIT(15)
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_COLLECTING vxge_mBIT(19)
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_DISTRIBUTING vxge_mBIT(23)
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_DEFAULTED vxge_mBIT(27)
+#define VXGE_HW_LAG_PORT_PARTNER_ADMIN_STATE_EXPIRED vxge_mBIT(31)
+/*0x02150*/ u64 lag_port_to_aggr[2];
+#define VXGE_HW_LAG_PORT_TO_AGGR_LAGC_AGGR_ID(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_LAG_PORT_TO_AGGR_LAGC_AGGR_VLD_ID vxge_mBIT(19)
+/*0x02160*/ u64 lag_port_actor_oper_key[2];
+#define VXGE_HW_LAG_PORT_ACTOR_OPER_KEY_LAGC_KEY(val) vxge_vBIT(val, 0, 16)
+/*0x02170*/ u64 lag_port_actor_oper_state[2];
+#define VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_LACP_ACTIVITY vxge_mBIT(3)
+#define VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_LACP_TIMEOUT vxge_mBIT(7)
+#define VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_AGGREGATION vxge_mBIT(11)
+#define VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_SYNCHRONIZATION vxge_mBIT(15)
+#define VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_COLLECTING vxge_mBIT(19)
+#define VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_DISTRIBUTING vxge_mBIT(23)
+#define VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_DEFAULTED vxge_mBIT(27)
+#define VXGE_HW_LAG_PORT_ACTOR_OPER_STATE_LAGC_EXPIRED vxge_mBIT(31)
+/*0x02180*/ u64 lag_port_partner_oper_sys_id[2];
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_SYS_ID_LAGC_ADDR(val) \
+ vxge_vBIT(val, 0, 48)
+/*0x02190*/ u64 lag_port_partner_oper_info[2];
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_INFO_LAGC_SYS_PRI(val) \
+ vxge_vBIT(val, 0, 16)
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_INFO_LAGC_KEY(val) \
+ vxge_vBIT(val, 16, 16)
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_INFO_LAGC_PORT_NUM(val) \
+ vxge_vBIT(val, 32, 16)
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_INFO_LAGC_PORT_PRI(val) \
+ vxge_vBIT(val, 48, 16)
+/*0x021a0*/ u64 lag_port_partner_oper_state[2];
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_LACP_ACTIVITY vxge_mBIT(3)
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_LACP_TIMEOUT vxge_mBIT(7)
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_AGGREGATION vxge_mBIT(11)
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_SYNCHRONIZATION \
+ vxge_mBIT(15)
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_COLLECTING vxge_mBIT(19)
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_DISTRIBUTING vxge_mBIT(23)
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_DEFAULTED vxge_mBIT(27)
+#define VXGE_HW_LAG_PORT_PARTNER_OPER_STATE_LAGC_EXPIRED vxge_mBIT(31)
+/*0x021b0*/ u64 lag_port_state_vars[2];
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_READY vxge_mBIT(3)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_SELECTED(val) vxge_vBIT(val, 6, 2)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_AGGR_NUM vxge_mBIT(11)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PORT_MOVED vxge_mBIT(15)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PORT_ENABLED vxge_mBIT(18)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PORT_DISABLED vxge_mBIT(19)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_NTT vxge_mBIT(23)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_ACTOR_CHURN vxge_mBIT(27)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PARTNER_CHURN vxge_mBIT(31)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_ACTOR_INFO_LEN_MISMATCH \
+ vxge_mBIT(32)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PARTNER_INFO_LEN_MISMATCH \
+ vxge_mBIT(33)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_COLL_INFO_LEN_MISMATCH vxge_mBIT(34)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_TERM_INFO_LEN_MISMATCH vxge_mBIT(35)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_RX_FSM_STATE(val) vxge_vBIT(val, 37, 3)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_MUX_FSM_STATE(val) \
+ vxge_vBIT(val, 41, 3)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_MUX_REASON(val) vxge_vBIT(val, 44, 4)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_ACTOR_CHURN_STATE vxge_mBIT(54)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PARTNER_CHURN_STATE vxge_mBIT(55)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_ACTOR_CHURN_COUNT(val) \
+ vxge_vBIT(val, 56, 4)
+#define VXGE_HW_LAG_PORT_STATE_VARS_LAGC_PARTNER_CHURN_COUNT(val) \
+ vxge_vBIT(val, 60, 4)
+/*0x021c0*/ u64 lag_port_timer_cntr[2];
+#define VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_CURRENT_WHILE(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_PERIODIC_WHILE(val) \
+ vxge_vBIT(val, 8, 8)
+#define VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_WAIT_WHILE(val) vxge_vBIT(val, 16, 8)
+#define VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_TX_LACP(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_ACTOR_SYNC_TRANSITION_COUNT(val) \
+ vxge_vBIT(val, 32, 8)
+#define VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_PARTNER_SYNC_TRANSITION_COUNT(val) \
+ vxge_vBIT(val, 40, 8)
+#define VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_ACTOR_CHANGE_COUNT(val) \
+ vxge_vBIT(val, 48, 8)
+#define VXGE_HW_LAG_PORT_TIMER_CNTR_LAGC_PARTNER_CHANGE_COUNT(val) \
+ vxge_vBIT(val, 56, 8)
+ u8 unused02208[0x02700-0x021d0];
+
+/*0x02700*/ u64 rtdma_int_status;
+#define VXGE_HW_RTDMA_INT_STATUS_PDA_ALARM_PDA_INT vxge_mBIT(1)
+#define VXGE_HW_RTDMA_INT_STATUS_PCC_ERROR_PCC_INT vxge_mBIT(2)
+#define VXGE_HW_RTDMA_INT_STATUS_LSO_ERROR_LSO_INT vxge_mBIT(4)
+#define VXGE_HW_RTDMA_INT_STATUS_SM_ERROR_SM_INT vxge_mBIT(5)
+/*0x02708*/ u64 rtdma_int_mask;
+/*0x02710*/ u64 pda_alarm_reg;
+#define VXGE_HW_PDA_ALARM_REG_PDA_HSC_FIFO_ERR vxge_mBIT(0)
+#define VXGE_HW_PDA_ALARM_REG_PDA_SM_ERR vxge_mBIT(1)
+/*0x02718*/ u64 pda_alarm_mask;
+/*0x02720*/ u64 pda_alarm_alarm;
+/*0x02728*/ u64 pcc_error_reg;
+#define VXGE_HW_PCC_ERROR_REG_PCC_PCC_FRM_BUF_SBE(n) vxge_mBIT(n)
+#define VXGE_HW_PCC_ERROR_REG_PCC_PCC_TXDO_SBE(n) vxge_mBIT(n)
+#define VXGE_HW_PCC_ERROR_REG_PCC_PCC_FRM_BUF_DBE(n) vxge_mBIT(n)
+#define VXGE_HW_PCC_ERROR_REG_PCC_PCC_TXDO_DBE(n) vxge_mBIT(n)
+#define VXGE_HW_PCC_ERROR_REG_PCC_PCC_FSM_ERR_ALARM(n) vxge_mBIT(n)
+#define VXGE_HW_PCC_ERROR_REG_PCC_PCC_SERR(n) vxge_mBIT(n)
+/*0x02730*/ u64 pcc_error_mask;
+/*0x02738*/ u64 pcc_error_alarm;
+/*0x02740*/ u64 lso_error_reg;
+#define VXGE_HW_LSO_ERROR_REG_PCC_LSO_ABORT(n) vxge_mBIT(n)
+#define VXGE_HW_LSO_ERROR_REG_PCC_LSO_FSM_ERR_ALARM(n) vxge_mBIT(n)
+/*0x02748*/ u64 lso_error_mask;
+/*0x02750*/ u64 lso_error_alarm;
+/*0x02758*/ u64 sm_error_reg;
+#define VXGE_HW_SM_ERROR_REG_SM_FSM_ERR_ALARM vxge_mBIT(15)
+/*0x02760*/ u64 sm_error_mask;
+/*0x02768*/ u64 sm_error_alarm;
+
+ u8 unused027a8[0x027a8-0x02770];
+
+/*0x027a8*/ u64 txd_ownership_ctrl;
+#define VXGE_HW_TXD_OWNERSHIP_CTRL_KEEP_OWNERSHIP vxge_mBIT(7)
+/*0x027b0*/ u64 pcc_cfg;
+#define VXGE_HW_PCC_CFG_PCC_ENABLE(n) vxge_mBIT(n)
+#define VXGE_HW_PCC_CFG_PCC_ECC_ENABLE_N(n) vxge_mBIT(n)
+/*0x027b8*/ u64 pcc_control;
+#define VXGE_HW_PCC_CONTROL_FE_ENABLE(val) vxge_vBIT(val, 6, 2)
+#define VXGE_HW_PCC_CONTROL_EARLY_ASSIGN_EN vxge_mBIT(15)
+#define VXGE_HW_PCC_CONTROL_UNBLOCK_DB_ERR vxge_mBIT(31)
+/*0x027c0*/ u64 pda_status1;
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_0_CTR(val) vxge_vBIT(val, 4, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_1_CTR(val) vxge_vBIT(val, 12, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_2_CTR(val) vxge_vBIT(val, 20, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_3_CTR(val) vxge_vBIT(val, 28, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_4_CTR(val) vxge_vBIT(val, 36, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_5_CTR(val) vxge_vBIT(val, 44, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_6_CTR(val) vxge_vBIT(val, 52, 4)
+#define VXGE_HW_PDA_STATUS1_PDA_WRAP_7_CTR(val) vxge_vBIT(val, 60, 4)
+/*0x027c8*/ u64 rtdma_bw_timer;
+#define VXGE_HW_RTDMA_BW_TIMER_TIMER_CTRL(val) vxge_vBIT(val, 12, 4)
+
+ u8 unused02900[0x02900-0x027d0];
+/*0x02900*/ u64 g3cmct_int_status;
+#define VXGE_HW_G3CMCT_INT_STATUS_ERR_G3IF_INT vxge_mBIT(0)
+/*0x02908*/ u64 g3cmct_int_mask;
+/*0x02910*/ u64 g3cmct_err_reg;
+#define VXGE_HW_G3CMCT_ERR_REG_G3IF_SM_ERR vxge_mBIT(4)
+#define VXGE_HW_G3CMCT_ERR_REG_G3IF_GDDR3_DECC vxge_mBIT(5)
+#define VXGE_HW_G3CMCT_ERR_REG_G3IF_GDDR3_U_DECC vxge_mBIT(6)
+#define VXGE_HW_G3CMCT_ERR_REG_G3IF_CTRL_FIFO_DECC vxge_mBIT(7)
+#define VXGE_HW_G3CMCT_ERR_REG_G3IF_GDDR3_SECC vxge_mBIT(29)
+#define VXGE_HW_G3CMCT_ERR_REG_G3IF_GDDR3_U_SECC vxge_mBIT(30)
+#define VXGE_HW_G3CMCT_ERR_REG_G3IF_CTRL_FIFO_SECC vxge_mBIT(31)
+/*0x02918*/ u64 g3cmct_err_mask;
+/*0x02920*/ u64 g3cmct_err_alarm;
+ u8 unused03000[0x03000-0x02928];
+
+/*0x03000*/ u64 mc_int_status;
+#define VXGE_HW_MC_INT_STATUS_MC_ERR_MC_INT vxge_mBIT(3)
+#define VXGE_HW_MC_INT_STATUS_GROCRC_ALARM_ROCRC_INT vxge_mBIT(7)
+#define VXGE_HW_MC_INT_STATUS_FAU_GEN_ERR_FAU_GEN_INT vxge_mBIT(11)
+#define VXGE_HW_MC_INT_STATUS_FAU_ECC_ERR_FAU_ECC_INT vxge_mBIT(15)
+/*0x03008*/ u64 mc_int_mask;
+/*0x03010*/ u64 mc_err_reg;
+#define VXGE_HW_MC_ERR_REG_MC_XFMD_MEM_ECC_SG_ERR_A vxge_mBIT(3)
+#define VXGE_HW_MC_ERR_REG_MC_XFMD_MEM_ECC_SG_ERR_B vxge_mBIT(4)
+#define VXGE_HW_MC_ERR_REG_MC_G3IF_RD_FIFO_ECC_SG_ERR vxge_mBIT(5)
+#define VXGE_HW_MC_ERR_REG_MC_MIRI_ECC_SG_ERR_0 vxge_mBIT(6)
+#define VXGE_HW_MC_ERR_REG_MC_MIRI_ECC_SG_ERR_1 vxge_mBIT(7)
+#define VXGE_HW_MC_ERR_REG_MC_XFMD_MEM_ECC_DB_ERR_A vxge_mBIT(10)
+#define VXGE_HW_MC_ERR_REG_MC_XFMD_MEM_ECC_DB_ERR_B vxge_mBIT(11)
+#define VXGE_HW_MC_ERR_REG_MC_G3IF_RD_FIFO_ECC_DB_ERR vxge_mBIT(12)
+#define VXGE_HW_MC_ERR_REG_MC_MIRI_ECC_DB_ERR_0 vxge_mBIT(13)
+#define VXGE_HW_MC_ERR_REG_MC_MIRI_ECC_DB_ERR_1 vxge_mBIT(14)
+#define VXGE_HW_MC_ERR_REG_MC_SM_ERR vxge_mBIT(15)
+/*0x03018*/ u64 mc_err_mask;
+/*0x03020*/ u64 mc_err_alarm;
+/*0x03028*/ u64 grocrc_alarm_reg;
+#define VXGE_HW_GROCRC_ALARM_REG_XFMD_WR_FIFO_ERR vxge_mBIT(3)
+#define VXGE_HW_GROCRC_ALARM_REG_WDE2MSR_RD_FIFO_ERR vxge_mBIT(7)
+/*0x03030*/ u64 grocrc_alarm_mask;
+/*0x03038*/ u64 grocrc_alarm_alarm;
+ u8 unused03100[0x03100-0x03040];
+
+/*0x03100*/ u64 rx_thresh_cfg_repl;
+#define VXGE_HW_RX_THRESH_CFG_REPL_PAUSE_LOW_THR(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_RX_THRESH_CFG_REPL_PAUSE_HIGH_THR(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_RX_THRESH_CFG_REPL_RED_THR_0(val) vxge_vBIT(val, 16, 8)
+#define VXGE_HW_RX_THRESH_CFG_REPL_RED_THR_1(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_RX_THRESH_CFG_REPL_RED_THR_2(val) vxge_vBIT(val, 32, 8)
+#define VXGE_HW_RX_THRESH_CFG_REPL_RED_THR_3(val) vxge_vBIT(val, 40, 8)
+#define VXGE_HW_RX_THRESH_CFG_REPL_GLOBAL_WOL_EN vxge_mBIT(62)
+#define VXGE_HW_RX_THRESH_CFG_REPL_EXACT_VP_MATCH_REQ vxge_mBIT(63)
+ u8 unused033b8[0x033b8-0x03108];
+
+/*0x033b8*/ u64 fbmc_ecc_cfg;
+#define VXGE_HW_FBMC_ECC_CFG_ENABLE(val) vxge_vBIT(val, 3, 5)
+ u8 unused03400[0x03400-0x033c0];
+
+/*0x03400*/ u64 pcipif_int_status;
+#define VXGE_HW_PCIPIF_INT_STATUS_DBECC_ERR_DBECC_ERR_INT vxge_mBIT(3)
+#define VXGE_HW_PCIPIF_INT_STATUS_SBECC_ERR_SBECC_ERR_INT vxge_mBIT(7)
+#define VXGE_HW_PCIPIF_INT_STATUS_GENERAL_ERR_GENERAL_ERR_INT vxge_mBIT(11)
+#define VXGE_HW_PCIPIF_INT_STATUS_SRPCIM_MSG_SRPCIM_MSG_INT vxge_mBIT(15)
+#define VXGE_HW_PCIPIF_INT_STATUS_MRPCIM_SPARE_R1_MRPCIM_SPARE_R1_INT \
+ vxge_mBIT(19)
+/*0x03408*/ u64 pcipif_int_mask;
+/*0x03410*/ u64 dbecc_err_reg;
+#define VXGE_HW_DBECC_ERR_REG_PCI_RETRY_BUF_DB_ERR vxge_mBIT(3)
+#define VXGE_HW_DBECC_ERR_REG_PCI_RETRY_SOT_DB_ERR vxge_mBIT(7)
+#define VXGE_HW_DBECC_ERR_REG_PCI_P_HDR_DB_ERR vxge_mBIT(11)
+#define VXGE_HW_DBECC_ERR_REG_PCI_P_DATA_DB_ERR vxge_mBIT(15)
+#define VXGE_HW_DBECC_ERR_REG_PCI_NP_HDR_DB_ERR vxge_mBIT(19)
+#define VXGE_HW_DBECC_ERR_REG_PCI_NP_DATA_DB_ERR vxge_mBIT(23)
+/*0x03418*/ u64 dbecc_err_mask;
+/*0x03420*/ u64 dbecc_err_alarm;
+/*0x03428*/ u64 sbecc_err_reg;
+#define VXGE_HW_SBECC_ERR_REG_PCI_RETRY_BUF_SG_ERR vxge_mBIT(3)
+#define VXGE_HW_SBECC_ERR_REG_PCI_RETRY_SOT_SG_ERR vxge_mBIT(7)
+#define VXGE_HW_SBECC_ERR_REG_PCI_P_HDR_SG_ERR vxge_mBIT(11)
+#define VXGE_HW_SBECC_ERR_REG_PCI_P_DATA_SG_ERR vxge_mBIT(15)
+#define VXGE_HW_SBECC_ERR_REG_PCI_NP_HDR_SG_ERR vxge_mBIT(19)
+#define VXGE_HW_SBECC_ERR_REG_PCI_NP_DATA_SG_ERR vxge_mBIT(23)
+/*0x03430*/ u64 sbecc_err_mask;
+/*0x03438*/ u64 sbecc_err_alarm;
+/*0x03440*/ u64 general_err_reg;
+#define VXGE_HW_GENERAL_ERR_REG_PCI_DROPPED_ILLEGAL_CFG vxge_mBIT(3)
+#define VXGE_HW_GENERAL_ERR_REG_PCI_ILLEGAL_MEM_MAP_PROG vxge_mBIT(7)
+#define VXGE_HW_GENERAL_ERR_REG_PCI_LINK_RST_FSM_ERR vxge_mBIT(11)
+#define VXGE_HW_GENERAL_ERR_REG_PCI_RX_ILLEGAL_TLP_VPLANE vxge_mBIT(15)
+#define VXGE_HW_GENERAL_ERR_REG_PCI_TRAINING_RESET_DET vxge_mBIT(19)
+#define VXGE_HW_GENERAL_ERR_REG_PCI_PCI_LINK_DOWN_DET vxge_mBIT(23)
+#define VXGE_HW_GENERAL_ERR_REG_PCI_RESET_ACK_DLLP vxge_mBIT(27)
+/*0x03448*/ u64 general_err_mask;
+/*0x03450*/ u64 general_err_alarm;
+/*0x03458*/ u64 srpcim_msg_reg;
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE0_RMSG_INT \
+ vxge_mBIT(0)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE1_RMSG_INT \
+ vxge_mBIT(1)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE2_RMSG_INT \
+ vxge_mBIT(2)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE3_RMSG_INT \
+ vxge_mBIT(3)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE4_RMSG_INT \
+ vxge_mBIT(4)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE5_RMSG_INT \
+ vxge_mBIT(5)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE6_RMSG_INT \
+ vxge_mBIT(6)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE7_RMSG_INT \
+ vxge_mBIT(7)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE8_RMSG_INT \
+ vxge_mBIT(8)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE9_RMSG_INT \
+ vxge_mBIT(9)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE10_RMSG_INT \
+ vxge_mBIT(10)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE11_RMSG_INT \
+ vxge_mBIT(11)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE12_RMSG_INT \
+ vxge_mBIT(12)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE13_RMSG_INT \
+ vxge_mBIT(13)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE14_RMSG_INT \
+ vxge_mBIT(14)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE15_RMSG_INT \
+ vxge_mBIT(15)
+#define VXGE_HW_SRPCIM_MSG_REG_SWIF_SRPCIM_TO_MRPCIM_VPLANE16_RMSG_INT \
+ vxge_mBIT(16)
+/*0x03460*/ u64 srpcim_msg_mask;
+/*0x03468*/ u64 srpcim_msg_alarm;
+ u8 unused03600[0x03600-0x03470];
+
+/*0x03600*/ u64 gcmg1_int_status;
+#define VXGE_HW_GCMG1_INT_STATUS_GSSCC_ERR_GSSCC_INT vxge_mBIT(0)
+#define VXGE_HW_GCMG1_INT_STATUS_GSSC0_ERR0_GSSC0_0_INT vxge_mBIT(1)
+#define VXGE_HW_GCMG1_INT_STATUS_GSSC0_ERR1_GSSC0_1_INT vxge_mBIT(2)
+#define VXGE_HW_GCMG1_INT_STATUS_GSSC1_ERR0_GSSC1_0_INT vxge_mBIT(3)
+#define VXGE_HW_GCMG1_INT_STATUS_GSSC1_ERR1_GSSC1_1_INT vxge_mBIT(4)
+#define VXGE_HW_GCMG1_INT_STATUS_GSSC2_ERR0_GSSC2_0_INT vxge_mBIT(5)
+#define VXGE_HW_GCMG1_INT_STATUS_GSSC2_ERR1_GSSC2_1_INT vxge_mBIT(6)
+#define VXGE_HW_GCMG1_INT_STATUS_UQM_ERR_UQM_INT vxge_mBIT(7)
+#define VXGE_HW_GCMG1_INT_STATUS_GQCC_ERR_GQCC_INT vxge_mBIT(8)
+/*0x03608*/ u64 gcmg1_int_mask;
+ u8 unused03a00[0x03a00-0x03610];
+
+/*0x03a00*/ u64 pcmg1_int_status;
+#define VXGE_HW_PCMG1_INT_STATUS_PSSCC_ERR_PSSCC_INT vxge_mBIT(0)
+#define VXGE_HW_PCMG1_INT_STATUS_PQCC_ERR_PQCC_INT vxge_mBIT(1)
+#define VXGE_HW_PCMG1_INT_STATUS_PQCC_CQM_ERR_PQCC_CQM_INT vxge_mBIT(2)
+#define VXGE_HW_PCMG1_INT_STATUS_PQCC_SQM_ERR_PQCC_SQM_INT vxge_mBIT(3)
+/*0x03a08*/ u64 pcmg1_int_mask;
+ u8 unused04000[0x04000-0x03a10];
+
+/*0x04000*/ u64 one_int_status;
+#define VXGE_HW_ONE_INT_STATUS_RXPE_ERR_RXPE_INT vxge_mBIT(7)
+#define VXGE_HW_ONE_INT_STATUS_TXPE_BCC_MEM_SG_ECC_ERR_TXPE_BCC_MEM_SG_ECC_INT \
+ vxge_mBIT(13)
+#define VXGE_HW_ONE_INT_STATUS_TXPE_BCC_MEM_DB_ECC_ERR_TXPE_BCC_MEM_DB_ECC_INT \
+ vxge_mBIT(14)
+#define VXGE_HW_ONE_INT_STATUS_TXPE_ERR_TXPE_INT vxge_mBIT(15)
+#define VXGE_HW_ONE_INT_STATUS_DLM_ERR_DLM_INT vxge_mBIT(23)
+#define VXGE_HW_ONE_INT_STATUS_PE_ERR_PE_INT vxge_mBIT(31)
+#define VXGE_HW_ONE_INT_STATUS_RPE_ERR_RPE_INT vxge_mBIT(39)
+#define VXGE_HW_ONE_INT_STATUS_RPE_FSM_ERR_RPE_FSM_INT vxge_mBIT(47)
+#define VXGE_HW_ONE_INT_STATUS_OES_ERR_OES_INT vxge_mBIT(55)
+/*0x04008*/ u64 one_int_mask;
+ u8 unused04818[0x04818-0x04010];
+
+/*0x04818*/ u64 noa_wct_ctrl;
+#define VXGE_HW_NOA_WCT_CTRL_VP_INT_NUM vxge_mBIT(0)
+/*0x04820*/ u64 rc_cfg2;
+#define VXGE_HW_RC_CFG2_BUFF1_SIZE(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_RC_CFG2_BUFF2_SIZE(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_RC_CFG2_BUFF3_SIZE(val) vxge_vBIT(val, 32, 16)
+#define VXGE_HW_RC_CFG2_BUFF4_SIZE(val) vxge_vBIT(val, 48, 16)
+/*0x04828*/ u64 rc_cfg3;
+#define VXGE_HW_RC_CFG3_BUFF5_SIZE(val) vxge_vBIT(val, 0, 16)
+/*0x04830*/ u64 rx_multi_cast_ctrl1;
+#define VXGE_HW_RX_MULTI_CAST_CTRL1_ENABLE vxge_mBIT(7)
+#define VXGE_HW_RX_MULTI_CAST_CTRL1_DELAY_COUNT(val) vxge_vBIT(val, 11, 5)
+/*0x04838*/ u64 rxdm_dbg_rd;
+#define VXGE_HW_RXDM_DBG_RD_ADDR(val) vxge_vBIT(val, 0, 12)
+#define VXGE_HW_RXDM_DBG_RD_ENABLE vxge_mBIT(31)
+/*0x04840*/ u64 rxdm_dbg_rd_data;
+#define VXGE_HW_RXDM_DBG_RD_DATA_RMC_RXDM_DBG_RD_DATA(val) vxge_vBIT(val, 0, 64)
+/*0x04848*/ u64 rqa_top_prty_for_vh[17];
+#define VXGE_HW_RQA_TOP_PRTY_FOR_VH_RQA_TOP_PRTY_FOR_VH(val) \
+ vxge_vBIT(val, 59, 5)
+ u8 unused04900[0x04900-0x048d0];
+
+/*0x04900*/ u64 tim_status;
+#define VXGE_HW_TIM_STATUS_TIM_RESET_IN_PROGRESS vxge_mBIT(0)
+/*0x04908*/ u64 tim_ecc_enable;
+#define VXGE_HW_TIM_ECC_ENABLE_VBLS_N vxge_mBIT(7)
+#define VXGE_HW_TIM_ECC_ENABLE_BMAP_N vxge_mBIT(15)
+#define VXGE_HW_TIM_ECC_ENABLE_BMAP_MSG_N vxge_mBIT(23)
+/*0x04910*/ u64 tim_bp_ctrl;
+#define VXGE_HW_TIM_BP_CTRL_RD_XON vxge_mBIT(7)
+#define VXGE_HW_TIM_BP_CTRL_WR_XON vxge_mBIT(15)
+#define VXGE_HW_TIM_BP_CTRL_ROCRC_BYP vxge_mBIT(23)
+/*0x04918*/ u64 tim_resource_assignment_vh[17];
+#define VXGE_HW_TIM_RESOURCE_ASSIGNMENT_VH_BMAP_ROOT(val) vxge_vBIT(val, 0, 32)
+/*0x049a0*/ u64 tim_bmap_mapping_vp_err[17];
+#define VXGE_HW_TIM_BMAP_MAPPING_VP_ERR_TIM_DEST_VPATH(val) vxge_vBIT(val, 3, 5)
+ u8 unused04b00[0x04b00-0x04a28];
+
+/*0x04b00*/ u64 gcmg2_int_status;
+#define VXGE_HW_GCMG2_INT_STATUS_GXTMC_ERR_GXTMC_INT vxge_mBIT(7)
+#define VXGE_HW_GCMG2_INT_STATUS_GCP_ERR_GCP_INT vxge_mBIT(15)
+#define VXGE_HW_GCMG2_INT_STATUS_CMC_ERR_CMC_INT vxge_mBIT(23)
+/*0x04b08*/ u64 gcmg2_int_mask;
+/*0x04b10*/ u64 gxtmc_err_reg;
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_MEM_DB_ERR(val) vxge_vBIT(val, 0, 4)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_MEM_SG_ERR(val) vxge_vBIT(val, 4, 4)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_CMC_RD_DATA_DB_ERR vxge_mBIT(8)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_REQ_FIFO_ERR vxge_mBIT(9)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_REQ_DATA_FIFO_ERR vxge_mBIT(10)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_WR_RSP_FIFO_ERR vxge_mBIT(11)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_RD_RSP_FIFO_ERR vxge_mBIT(12)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_WRP_FIFO_ERR vxge_mBIT(13)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_WRP_ERR vxge_mBIT(14)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_RRP_FIFO_ERR vxge_mBIT(15)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_RRP_ERR vxge_mBIT(16)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_DATA_SM_ERR vxge_mBIT(17)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_CMC0_IF_ERR vxge_mBIT(18)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_ARB_SM_ERR vxge_mBIT(19)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_CFC_SM_ERR vxge_mBIT(20)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_DFETCH_CREDIT_OVERFLOW \
+ vxge_mBIT(21)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_DFETCH_CREDIT_UNDERFLOW \
+ vxge_mBIT(22)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_DFETCH_SM_ERR vxge_mBIT(23)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_RCTRL_CREDIT_OVERFLOW \
+ vxge_mBIT(24)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_RCTRL_CREDIT_UNDERFLOW \
+ vxge_mBIT(25)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_RCTRL_SM_ERR vxge_mBIT(26)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_WCOMPL_SM_ERR vxge_mBIT(27)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_WCOMPL_TAG_ERR vxge_mBIT(28)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_WREQ_SM_ERR vxge_mBIT(29)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_BDT_CMI_WREQ_FIFO_ERR vxge_mBIT(30)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_CP2BDT_RFIFO_POP_ERR vxge_mBIT(31)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_XTMC_BDT_CMI_OP_ERR vxge_mBIT(32)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_XTMC_BDT_DFETCH_OP_ERR vxge_mBIT(33)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_XTMC_BDT_DFIFO_ERR vxge_mBIT(34)
+#define VXGE_HW_GXTMC_ERR_REG_XTMC_CMI_ARB_SM_ERR vxge_mBIT(35)
+/*0x04b18*/ u64 gxtmc_err_mask;
+/*0x04b20*/ u64 gxtmc_err_alarm;
+/*0x04b28*/ u64 cmc_err_reg;
+#define VXGE_HW_CMC_ERR_REG_CMC_CMC_SM_ERR vxge_mBIT(0)
+/*0x04b30*/ u64 cmc_err_mask;
+/*0x04b38*/ u64 cmc_err_alarm;
+/*0x04b40*/ u64 gcp_err_reg;
+#define VXGE_HW_GCP_ERR_REG_CP_H2L2CP_FIFO_ERR vxge_mBIT(0)
+#define VXGE_HW_GCP_ERR_REG_CP_STC2CP_FIFO_ERR vxge_mBIT(1)
+#define VXGE_HW_GCP_ERR_REG_CP_STE2CP_FIFO_ERR vxge_mBIT(2)
+#define VXGE_HW_GCP_ERR_REG_CP_TTE2CP_FIFO_ERR vxge_mBIT(3)
+/*0x04b48*/ u64 gcp_err_mask;
+/*0x04b50*/ u64 gcp_err_alarm;
+ u8 unused04f00[0x04f00-0x04b58];
+
+/*0x04f00*/ u64 pcmg2_int_status;
+#define VXGE_HW_PCMG2_INT_STATUS_PXTMC_ERR_PXTMC_INT vxge_mBIT(7)
+#define VXGE_HW_PCMG2_INT_STATUS_CP_EXC_CP_XT_EXC_INT vxge_mBIT(15)
+#define VXGE_HW_PCMG2_INT_STATUS_CP_ERR_CP_ERR_INT vxge_mBIT(23)
+/*0x04f08*/ u64 pcmg2_int_mask;
+/*0x04f10*/ u64 pxtmc_err_reg;
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_XT_PIF_SRAM_DB_ERR(val) vxge_vBIT(val, 0, 2)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_REQ_FIFO_ERR vxge_mBIT(2)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_PRSP_FIFO_ERR vxge_mBIT(3)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_WRSP_FIFO_ERR vxge_mBIT(4)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_REQ_FIFO_ERR vxge_mBIT(5)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_PRSP_FIFO_ERR vxge_mBIT(6)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_WRSP_FIFO_ERR vxge_mBIT(7)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_REQ_FIFO_ERR vxge_mBIT(8)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_PRSP_FIFO_ERR vxge_mBIT(9)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_WRSP_FIFO_ERR vxge_mBIT(10)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_REQ_FIFO_ERR vxge_mBIT(11)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_REQ_DATA_FIFO_ERR vxge_mBIT(12)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_WR_RSP_FIFO_ERR vxge_mBIT(13)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_RD_RSP_FIFO_ERR vxge_mBIT(14)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_REQ_SHADOW_ERR vxge_mBIT(15)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_RSP_SHADOW_ERR vxge_mBIT(16)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_REQ_SHADOW_ERR vxge_mBIT(17)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_RSP_SHADOW_ERR vxge_mBIT(18)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_REQ_SHADOW_ERR vxge_mBIT(19)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_RSP_SHADOW_ERR vxge_mBIT(20)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_XIL_SHADOW_ERR vxge_mBIT(21)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_ARB_SHADOW_ERR vxge_mBIT(22)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_RAM_SHADOW_ERR vxge_mBIT(23)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CMW_SHADOW_ERR vxge_mBIT(24)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CMR_SHADOW_ERR vxge_mBIT(25)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_REQ_FSM_ERR vxge_mBIT(26)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_MPT_RSP_FSM_ERR vxge_mBIT(27)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_REQ_FSM_ERR vxge_mBIT(28)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_UPT_RSP_FSM_ERR vxge_mBIT(29)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_REQ_FSM_ERR vxge_mBIT(30)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CPT_RSP_FSM_ERR vxge_mBIT(31)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_XIL_FSM_ERR vxge_mBIT(32)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_ARB_FSM_ERR vxge_mBIT(33)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CMW_FSM_ERR vxge_mBIT(34)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CMR_FSM_ERR vxge_mBIT(35)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_MXP_RD_PROT_ERR vxge_mBIT(36)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_UXP_RD_PROT_ERR vxge_mBIT(37)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CXP_RD_PROT_ERR vxge_mBIT(38)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_MXP_WR_PROT_ERR vxge_mBIT(39)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_UXP_WR_PROT_ERR vxge_mBIT(40)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CXP_WR_PROT_ERR vxge_mBIT(41)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_MXP_INV_ADDR_ERR vxge_mBIT(42)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_UXP_INV_ADDR_ERR vxge_mBIT(43)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CXP_INV_ADDR_ERR vxge_mBIT(44)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_MXP_RD_PROT_INFO_ERR vxge_mBIT(45)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_UXP_RD_PROT_INFO_ERR vxge_mBIT(46)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CXP_RD_PROT_INFO_ERR vxge_mBIT(47)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_MXP_WR_PROT_INFO_ERR vxge_mBIT(48)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_UXP_WR_PROT_INFO_ERR vxge_mBIT(49)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CXP_WR_PROT_INFO_ERR vxge_mBIT(50)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_MXP_INV_ADDR_INFO_ERR vxge_mBIT(51)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_UXP_INV_ADDR_INFO_ERR vxge_mBIT(52)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CXP_INV_ADDR_INFO_ERR vxge_mBIT(53)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_XT_PIF_SRAM_SG_ERR(val) vxge_vBIT(val, 54, 2)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CP2BDT_DFIFO_PUSH_ERR vxge_mBIT(56)
+#define VXGE_HW_PXTMC_ERR_REG_XTMC_CP2BDT_RFIFO_PUSH_ERR vxge_mBIT(57)
+/*0x04f18*/ u64 pxtmc_err_mask;
+/*0x04f20*/ u64 pxtmc_err_alarm;
+/*0x04f28*/ u64 cp_err_reg;
+#define VXGE_HW_CP_ERR_REG_CP_CP_DCACHE_SG_ERR(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_CP_ERR_REG_CP_CP_ICACHE_SG_ERR(val) vxge_vBIT(val, 8, 2)
+#define VXGE_HW_CP_ERR_REG_CP_CP_DTAG_SG_ERR vxge_mBIT(10)
+#define VXGE_HW_CP_ERR_REG_CP_CP_ITAG_SG_ERR vxge_mBIT(11)
+#define VXGE_HW_CP_ERR_REG_CP_CP_TRACE_SG_ERR vxge_mBIT(12)
+#define VXGE_HW_CP_ERR_REG_CP_DMA2CP_SG_ERR vxge_mBIT(13)
+#define VXGE_HW_CP_ERR_REG_CP_MP2CP_SG_ERR vxge_mBIT(14)
+#define VXGE_HW_CP_ERR_REG_CP_QCC2CP_SG_ERR vxge_mBIT(15)
+#define VXGE_HW_CP_ERR_REG_CP_STC2CP_SG_ERR(val) vxge_vBIT(val, 16, 2)
+#define VXGE_HW_CP_ERR_REG_CP_CP_DCACHE_DB_ERR(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_CP_ERR_REG_CP_CP_ICACHE_DB_ERR(val) vxge_vBIT(val, 32, 2)
+#define VXGE_HW_CP_ERR_REG_CP_CP_DTAG_DB_ERR vxge_mBIT(34)
+#define VXGE_HW_CP_ERR_REG_CP_CP_ITAG_DB_ERR vxge_mBIT(35)
+#define VXGE_HW_CP_ERR_REG_CP_CP_TRACE_DB_ERR vxge_mBIT(36)
+#define VXGE_HW_CP_ERR_REG_CP_DMA2CP_DB_ERR vxge_mBIT(37)
+#define VXGE_HW_CP_ERR_REG_CP_MP2CP_DB_ERR vxge_mBIT(38)
+#define VXGE_HW_CP_ERR_REG_CP_QCC2CP_DB_ERR vxge_mBIT(39)
+#define VXGE_HW_CP_ERR_REG_CP_STC2CP_DB_ERR(val) vxge_vBIT(val, 40, 2)
+#define VXGE_HW_CP_ERR_REG_CP_H2L2CP_FIFO_ERR vxge_mBIT(48)
+#define VXGE_HW_CP_ERR_REG_CP_STC2CP_FIFO_ERR vxge_mBIT(49)
+#define VXGE_HW_CP_ERR_REG_CP_STE2CP_FIFO_ERR vxge_mBIT(50)
+#define VXGE_HW_CP_ERR_REG_CP_TTE2CP_FIFO_ERR vxge_mBIT(51)
+#define VXGE_HW_CP_ERR_REG_CP_SWIF2CP_FIFO_ERR vxge_mBIT(52)
+#define VXGE_HW_CP_ERR_REG_CP_CP2DMA_FIFO_ERR vxge_mBIT(53)
+#define VXGE_HW_CP_ERR_REG_CP_DAM2CP_FIFO_ERR vxge_mBIT(54)
+#define VXGE_HW_CP_ERR_REG_CP_MP2CP_FIFO_ERR vxge_mBIT(55)
+#define VXGE_HW_CP_ERR_REG_CP_QCC2CP_FIFO_ERR vxge_mBIT(56)
+#define VXGE_HW_CP_ERR_REG_CP_DMA2CP_FIFO_ERR vxge_mBIT(57)
+#define VXGE_HW_CP_ERR_REG_CP_CP_WAKE_FSM_INTEGRITY_ERR vxge_mBIT(60)
+#define VXGE_HW_CP_ERR_REG_CP_CP_PMON_FSM_INTEGRITY_ERR vxge_mBIT(61)
+#define VXGE_HW_CP_ERR_REG_CP_DMA_RD_SHADOW_ERR vxge_mBIT(62)
+#define VXGE_HW_CP_ERR_REG_CP_PIFT_CREDIT_ERR vxge_mBIT(63)
+/*0x04f30*/ u64 cp_err_mask;
+/*0x04f38*/ u64 cp_err_alarm;
+ u8 unused04fe8[0x04f50-0x04f40];
+
+/*0x04f50*/ u64 cp_exc_reg;
+#define VXGE_HW_CP_EXC_REG_CP_CP_CAUSE_INFO_INT vxge_mBIT(47)
+#define VXGE_HW_CP_EXC_REG_CP_CP_CAUSE_CRIT_INT vxge_mBIT(55)
+#define VXGE_HW_CP_EXC_REG_CP_CP_SERR vxge_mBIT(63)
+/*0x04f58*/ u64 cp_exc_mask;
+/*0x04f60*/ u64 cp_exc_alarm;
+/*0x04f68*/ u64 cp_exc_cause;
+#define VXGE_HW_CP_EXC_CAUSE_CP_CP_CAUSE(val) vxge_vBIT(val, 32, 32)
+ u8 unused05200[0x05200-0x04f70];
+
+/*0x05200*/ u64 msg_int_status;
+#define VXGE_HW_MSG_INT_STATUS_TIM_ERR_TIM_INT vxge_mBIT(7)
+#define VXGE_HW_MSG_INT_STATUS_MSG_EXC_MSG_XT_EXC_INT vxge_mBIT(60)
+#define VXGE_HW_MSG_INT_STATUS_MSG_ERR3_MSG_ERR3_INT vxge_mBIT(61)
+#define VXGE_HW_MSG_INT_STATUS_MSG_ERR2_MSG_ERR2_INT vxge_mBIT(62)
+#define VXGE_HW_MSG_INT_STATUS_MSG_ERR_MSG_ERR_INT vxge_mBIT(63)
+/*0x05208*/ u64 msg_int_mask;
+/*0x05210*/ u64 tim_err_reg;
+#define VXGE_HW_TIM_ERR_REG_TIM_VBLS_SG_ERR vxge_mBIT(4)
+#define VXGE_HW_TIM_ERR_REG_TIM_BMAP_PA_SG_ERR vxge_mBIT(5)
+#define VXGE_HW_TIM_ERR_REG_TIM_BMAP_PB_SG_ERR vxge_mBIT(6)
+#define VXGE_HW_TIM_ERR_REG_TIM_BMAP_MSG_SG_ERR vxge_mBIT(7)
+#define VXGE_HW_TIM_ERR_REG_TIM_VBLS_DB_ERR vxge_mBIT(12)
+#define VXGE_HW_TIM_ERR_REG_TIM_BMAP_PA_DB_ERR vxge_mBIT(13)
+#define VXGE_HW_TIM_ERR_REG_TIM_BMAP_PB_DB_ERR vxge_mBIT(14)
+#define VXGE_HW_TIM_ERR_REG_TIM_BMAP_MSG_DB_ERR vxge_mBIT(15)
+#define VXGE_HW_TIM_ERR_REG_TIM_BMAP_MEM_CNTRL_SM_ERR vxge_mBIT(18)
+#define VXGE_HW_TIM_ERR_REG_TIM_BMAP_MSG_MEM_CNTRL_SM_ERR vxge_mBIT(19)
+#define VXGE_HW_TIM_ERR_REG_TIM_MPIF_PCIWR_ERR vxge_mBIT(20)
+#define VXGE_HW_TIM_ERR_REG_TIM_ROCRC_BMAP_UPDT_FIFO_ERR vxge_mBIT(22)
+#define VXGE_HW_TIM_ERR_REG_TIM_CREATE_BMAPMSG_FIFO_ERR vxge_mBIT(23)
+#define VXGE_HW_TIM_ERR_REG_TIM_ROCRCIF_MISMATCH vxge_mBIT(46)
+#define VXGE_HW_TIM_ERR_REG_TIM_BMAP_MAPPING_VP_ERR(n) vxge_mBIT(n)
+/*0x05218*/ u64 tim_err_mask;
+/*0x05220*/ u64 tim_err_alarm;
+/*0x05228*/ u64 msg_err_reg;
+#define VXGE_HW_MSG_ERR_REG_UP_UXP_WAKE_FSM_INTEGRITY_ERR vxge_mBIT(0)
+#define VXGE_HW_MSG_ERR_REG_MP_MXP_WAKE_FSM_INTEGRITY_ERR vxge_mBIT(1)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_DMQ_DMA_READ_CMD_FSM_INTEGRITY_ERR \
+ vxge_mBIT(2)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_DMQ_DMA_RESP_FSM_INTEGRITY_ERR \
+ vxge_mBIT(3)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_DMQ_OWN_FSM_INTEGRITY_ERR vxge_mBIT(4)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_PDA_ACC_FSM_INTEGRITY_ERR vxge_mBIT(5)
+#define VXGE_HW_MSG_ERR_REG_MP_MXP_PMON_FSM_INTEGRITY_ERR vxge_mBIT(6)
+#define VXGE_HW_MSG_ERR_REG_UP_UXP_PMON_FSM_INTEGRITY_ERR vxge_mBIT(7)
+#define VXGE_HW_MSG_ERR_REG_UP_UXP_DTAG_SG_ERR vxge_mBIT(8)
+#define VXGE_HW_MSG_ERR_REG_UP_UXP_ITAG_SG_ERR vxge_mBIT(10)
+#define VXGE_HW_MSG_ERR_REG_MP_MXP_DTAG_SG_ERR vxge_mBIT(12)
+#define VXGE_HW_MSG_ERR_REG_MP_MXP_ITAG_SG_ERR vxge_mBIT(14)
+#define VXGE_HW_MSG_ERR_REG_UP_UXP_TRACE_SG_ERR vxge_mBIT(16)
+#define VXGE_HW_MSG_ERR_REG_MP_MXP_TRACE_SG_ERR vxge_mBIT(17)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_CMG2MSG_SG_ERR vxge_mBIT(18)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_TXPE2MSG_SG_ERR vxge_mBIT(19)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_RXPE2MSG_SG_ERR vxge_mBIT(20)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_RPE2MSG_SG_ERR vxge_mBIT(21)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_UMQ_SG_ERR vxge_mBIT(26)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_BWR_PF_SG_ERR vxge_mBIT(27)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_DMQ_ECC_SG_ERR vxge_mBIT(29)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_DMA_RESP_ECC_SG_ERR vxge_mBIT(31)
+#define VXGE_HW_MSG_ERR_REG_MSG_XFMDQRY_FSM_INTEGRITY_ERR vxge_mBIT(33)
+#define VXGE_HW_MSG_ERR_REG_MSG_FRMQRY_FSM_INTEGRITY_ERR vxge_mBIT(34)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_UMQ_WRITE_FSM_INTEGRITY_ERR vxge_mBIT(35)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_UMQ_BWR_PF_FSM_INTEGRITY_ERR \
+ vxge_mBIT(36)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_REG_RESP_FIFO_ERR vxge_mBIT(38)
+#define VXGE_HW_MSG_ERR_REG_UP_UXP_DTAG_DB_ERR vxge_mBIT(39)
+#define VXGE_HW_MSG_ERR_REG_UP_UXP_ITAG_DB_ERR vxge_mBIT(41)
+#define VXGE_HW_MSG_ERR_REG_MP_MXP_DTAG_DB_ERR vxge_mBIT(43)
+#define VXGE_HW_MSG_ERR_REG_MP_MXP_ITAG_DB_ERR vxge_mBIT(45)
+#define VXGE_HW_MSG_ERR_REG_UP_UXP_TRACE_DB_ERR vxge_mBIT(47)
+#define VXGE_HW_MSG_ERR_REG_MP_MXP_TRACE_DB_ERR vxge_mBIT(48)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_CMG2MSG_DB_ERR vxge_mBIT(49)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_TXPE2MSG_DB_ERR vxge_mBIT(50)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_RXPE2MSG_DB_ERR vxge_mBIT(51)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_RPE2MSG_DB_ERR vxge_mBIT(52)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_REG_READ_FIFO_ERR vxge_mBIT(53)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_MXP2UXP_FIFO_ERR vxge_mBIT(54)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_KDFC_SIF_FIFO_ERR vxge_mBIT(55)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_CXP2SWIF_FIFO_ERR vxge_mBIT(56)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_UMQ_DB_ERR vxge_mBIT(57)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_BWR_PF_DB_ERR vxge_mBIT(58)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_BWR_SIF_FIFO_ERR vxge_mBIT(59)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_DMQ_ECC_DB_ERR vxge_mBIT(60)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_DMA_READ_FIFO_ERR vxge_mBIT(61)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_DMA_RESP_ECC_DB_ERR vxge_mBIT(62)
+#define VXGE_HW_MSG_ERR_REG_MSG_QUE_UXP2MXP_FIFO_ERR vxge_mBIT(63)
+/*0x05230*/ u64 msg_err_mask;
+/*0x05238*/ u64 msg_err_alarm;
+ u8 unused05340[0x05340-0x05240];
+
+/*0x05340*/ u64 msg_exc_reg;
+#define VXGE_HW_MSG_EXC_REG_MP_MXP_CAUSE_INFO_INT vxge_mBIT(50)
+#define VXGE_HW_MSG_EXC_REG_MP_MXP_CAUSE_CRIT_INT vxge_mBIT(51)
+#define VXGE_HW_MSG_EXC_REG_UP_UXP_CAUSE_INFO_INT vxge_mBIT(54)
+#define VXGE_HW_MSG_EXC_REG_UP_UXP_CAUSE_CRIT_INT vxge_mBIT(55)
+#define VXGE_HW_MSG_EXC_REG_MP_MXP_SERR vxge_mBIT(62)
+#define VXGE_HW_MSG_EXC_REG_UP_UXP_SERR vxge_mBIT(63)
+/*0x05348*/ u64 msg_exc_mask;
+/*0x05350*/ u64 msg_exc_alarm;
+/*0x05358*/ u64 msg_exc_cause;
+#define VXGE_HW_MSG_EXC_CAUSE_MP_MXP(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_MSG_EXC_CAUSE_UP_UXP(val) vxge_vBIT(val, 32, 32)
+ u8 unused05368[0x05380-0x05360];
+
+/*0x05380*/ u64 msg_err2_reg;
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_CMG2MSG_DISPATCH_FSM_INTEGRITY_ERR \
+ vxge_mBIT(0)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_DMQ_DISPATCH_FSM_INTEGRITY_ERR \
+ vxge_mBIT(1)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_SWIF_DISPATCH_FSM_INTEGRITY_ERR \
+ vxge_mBIT(2)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_PIC_WRITE_FSM_INTEGRITY_ERR \
+ vxge_mBIT(3)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_SWIFREG_FSM_INTEGRITY_ERR vxge_mBIT(4)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_TIM_WRITE_FSM_INTEGRITY_ERR \
+ vxge_mBIT(5)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_UMQ_TA_FSM_INTEGRITY_ERR vxge_mBIT(6)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_TXPE_TA_FSM_INTEGRITY_ERR vxge_mBIT(7)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_RXPE_TA_FSM_INTEGRITY_ERR vxge_mBIT(8)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_SWIF_TA_FSM_INTEGRITY_ERR vxge_mBIT(9)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_DMA_TA_FSM_INTEGRITY_ERR vxge_mBIT(10)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_CP_TA_FSM_INTEGRITY_ERR vxge_mBIT(11)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA16_FSM_INTEGRITY_ERR \
+ vxge_mBIT(12)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA15_FSM_INTEGRITY_ERR \
+ vxge_mBIT(13)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA14_FSM_INTEGRITY_ERR \
+ vxge_mBIT(14)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA13_FSM_INTEGRITY_ERR \
+ vxge_mBIT(15)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA12_FSM_INTEGRITY_ERR \
+ vxge_mBIT(16)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA11_FSM_INTEGRITY_ERR \
+ vxge_mBIT(17)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA10_FSM_INTEGRITY_ERR \
+ vxge_mBIT(18)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA9_FSM_INTEGRITY_ERR \
+ vxge_mBIT(19)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA8_FSM_INTEGRITY_ERR \
+ vxge_mBIT(20)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA7_FSM_INTEGRITY_ERR \
+ vxge_mBIT(21)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA6_FSM_INTEGRITY_ERR \
+ vxge_mBIT(22)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA5_FSM_INTEGRITY_ERR \
+ vxge_mBIT(23)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA4_FSM_INTEGRITY_ERR \
+ vxge_mBIT(24)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA3_FSM_INTEGRITY_ERR \
+ vxge_mBIT(25)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA2_FSM_INTEGRITY_ERR \
+ vxge_mBIT(26)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA1_FSM_INTEGRITY_ERR \
+ vxge_mBIT(27)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_LONGTERMUMQ_TA0_FSM_INTEGRITY_ERR \
+ vxge_mBIT(28)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_FBMC_OWN_FSM_INTEGRITY_ERR vxge_mBIT(29)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_TXPE2MSG_DISPATCH_FSM_INTEGRITY_ERR \
+ vxge_mBIT(30)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_RXPE2MSG_DISPATCH_FSM_INTEGRITY_ERR \
+ vxge_mBIT(31)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_RPE2MSG_DISPATCH_FSM_INTEGRITY_ERR \
+ vxge_mBIT(32)
+#define VXGE_HW_MSG_ERR2_REG_MP_MP_PIFT_IF_CREDIT_CNT_ERR vxge_mBIT(33)
+#define VXGE_HW_MSG_ERR2_REG_UP_UP_PIFT_IF_CREDIT_CNT_ERR vxge_mBIT(34)
+#define VXGE_HW_MSG_ERR2_REG_MSG_QUE_UMQ2PIC_CMD_FIFO_ERR vxge_mBIT(62)
+#define VXGE_HW_MSG_ERR2_REG_TIM_TIM2MSG_CMD_FIFO_ERR vxge_mBIT(63)
+/*0x05388*/ u64 msg_err2_mask;
+/*0x05390*/ u64 msg_err2_alarm;
+/*0x05398*/ u64 msg_err3_reg;
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR0 vxge_mBIT(0)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR1 vxge_mBIT(1)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR2 vxge_mBIT(2)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR3 vxge_mBIT(3)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR4 vxge_mBIT(4)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR5 vxge_mBIT(5)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR6 vxge_mBIT(6)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_SG_ERR7 vxge_mBIT(7)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_ICACHE_SG_ERR0 vxge_mBIT(8)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_ICACHE_SG_ERR1 vxge_mBIT(9)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR0 vxge_mBIT(16)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR1 vxge_mBIT(17)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR2 vxge_mBIT(18)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR3 vxge_mBIT(19)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR4 vxge_mBIT(20)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR5 vxge_mBIT(21)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR6 vxge_mBIT(22)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_SG_ERR7 vxge_mBIT(23)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_ICACHE_SG_ERR0 vxge_mBIT(24)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_ICACHE_SG_ERR1 vxge_mBIT(25)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR0 vxge_mBIT(32)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR1 vxge_mBIT(33)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR2 vxge_mBIT(34)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR3 vxge_mBIT(35)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR4 vxge_mBIT(36)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR5 vxge_mBIT(37)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR6 vxge_mBIT(38)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_DCACHE_DB_ERR7 vxge_mBIT(39)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_ICACHE_DB_ERR0 vxge_mBIT(40)
+#define VXGE_HW_MSG_ERR3_REG_UP_UXP_ICACHE_DB_ERR1 vxge_mBIT(41)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR0 vxge_mBIT(48)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR1 vxge_mBIT(49)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR2 vxge_mBIT(50)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR3 vxge_mBIT(51)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR4 vxge_mBIT(52)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR5 vxge_mBIT(53)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR6 vxge_mBIT(54)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_DCACHE_DB_ERR7 vxge_mBIT(55)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_ICACHE_DB_ERR0 vxge_mBIT(56)
+#define VXGE_HW_MSG_ERR3_REG_MP_MXP_ICACHE_DB_ERR1 vxge_mBIT(57)
+/*0x053a0*/ u64 msg_err3_mask;
+/*0x053a8*/ u64 msg_err3_alarm;
+ u8 unused05600[0x05600-0x053b0];
+
+/*0x05600*/ u64 fau_gen_err_reg;
+#define VXGE_HW_FAU_GEN_ERR_REG_FMPF_PORT0_PERMANENT_STOP vxge_mBIT(3)
+#define VXGE_HW_FAU_GEN_ERR_REG_FMPF_PORT1_PERMANENT_STOP vxge_mBIT(7)
+#define VXGE_HW_FAU_GEN_ERR_REG_FMPF_PORT2_PERMANENT_STOP vxge_mBIT(11)
+#define VXGE_HW_FAU_GEN_ERR_REG_FALR_AUTO_LRO_NOTIFICATION vxge_mBIT(15)
+/*0x05608*/ u64 fau_gen_err_mask;
+/*0x05610*/ u64 fau_gen_err_alarm;
+/*0x05618*/ u64 fau_ecc_err_reg;
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT0_FAU_MAC2F_N_SG_ERR vxge_mBIT(0)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT0_FAU_MAC2F_N_DB_ERR vxge_mBIT(1)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT0_FAU_MAC2F_W_SG_ERR(val) \
+ vxge_vBIT(val, 2, 2)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT0_FAU_MAC2F_W_DB_ERR(val) \
+ vxge_vBIT(val, 4, 2)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT1_FAU_MAC2F_N_SG_ERR vxge_mBIT(6)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT1_FAU_MAC2F_N_DB_ERR vxge_mBIT(7)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT1_FAU_MAC2F_W_SG_ERR(val) \
+ vxge_vBIT(val, 8, 2)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT1_FAU_MAC2F_W_DB_ERR(val) \
+ vxge_vBIT(val, 10, 2)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT2_FAU_MAC2F_N_SG_ERR vxge_mBIT(12)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT2_FAU_MAC2F_N_DB_ERR vxge_mBIT(13)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT2_FAU_MAC2F_W_SG_ERR(val) \
+ vxge_vBIT(val, 14, 2)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_PORT2_FAU_MAC2F_W_DB_ERR(val) \
+ vxge_vBIT(val, 16, 2)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_FAU_XFMD_INS_SG_ERR(val) \
+ vxge_vBIT(val, 18, 2)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAU_FAU_XFMD_INS_DB_ERR(val) \
+ vxge_vBIT(val, 20, 2)
+#define VXGE_HW_FAU_ECC_ERR_REG_FAUJ_FAU_FSM_ERR vxge_mBIT(31)
+/*0x05620*/ u64 fau_ecc_err_mask;
+/*0x05628*/ u64 fau_ecc_err_alarm;
+ u8 unused05658[0x05658-0x05630];
+/*0x05658*/ u64 fau_pa_cfg;
+#define VXGE_HW_FAU_PA_CFG_REPL_L4_COMP_CSUM vxge_mBIT(3)
+#define VXGE_HW_FAU_PA_CFG_REPL_L3_INCL_CF vxge_mBIT(7)
+#define VXGE_HW_FAU_PA_CFG_REPL_L3_COMP_CSUM vxge_mBIT(11)
+ u8 unused05668[0x05668-0x05660];
+
+/*0x05668*/ u64 dbg_stats_fau_rx_path;
+#define VXGE_HW_DBG_STATS_FAU_RX_PATH_RX_PERMITTED_FRMS(val) \
+ vxge_vBIT(val, 32, 32)
+ u8 unused056c0[0x056c0-0x05670];
+
+/*0x056c0*/ u64 fau_lag_cfg;
+#define VXGE_HW_FAU_LAG_CFG_COLL_ALG(val) vxge_vBIT(val, 2, 2)
+#define VXGE_HW_FAU_LAG_CFG_INCR_RX_AGGR_STATS vxge_mBIT(7)
+ u8 unused05800[0x05800-0x056c8];
+
+/*0x05800*/ u64 tpa_int_status;
+#define VXGE_HW_TPA_INT_STATUS_ORP_ERR_ORP_INT vxge_mBIT(15)
+#define VXGE_HW_TPA_INT_STATUS_PTM_ALARM_PTM_INT vxge_mBIT(23)
+#define VXGE_HW_TPA_INT_STATUS_TPA_ERROR_TPA_INT vxge_mBIT(31)
+/*0x05808*/ u64 tpa_int_mask;
+/*0x05810*/ u64 orp_err_reg;
+#define VXGE_HW_ORP_ERR_REG_ORP_FIFO_SG_ERR vxge_mBIT(3)
+#define VXGE_HW_ORP_ERR_REG_ORP_FIFO_DB_ERR vxge_mBIT(7)
+#define VXGE_HW_ORP_ERR_REG_ORP_XFMD_FIFO_UFLOW_ERR vxge_mBIT(11)
+#define VXGE_HW_ORP_ERR_REG_ORP_FRM_FIFO_UFLOW_ERR vxge_mBIT(15)
+#define VXGE_HW_ORP_ERR_REG_ORP_XFMD_RCV_FSM_ERR vxge_mBIT(19)
+#define VXGE_HW_ORP_ERR_REG_ORP_OUTREAD_FSM_ERR vxge_mBIT(23)
+#define VXGE_HW_ORP_ERR_REG_ORP_OUTQEM_FSM_ERR vxge_mBIT(27)
+#define VXGE_HW_ORP_ERR_REG_ORP_XFMD_RCV_SHADOW_ERR vxge_mBIT(31)
+#define VXGE_HW_ORP_ERR_REG_ORP_OUTREAD_SHADOW_ERR vxge_mBIT(35)
+#define VXGE_HW_ORP_ERR_REG_ORP_OUTQEM_SHADOW_ERR vxge_mBIT(39)
+#define VXGE_HW_ORP_ERR_REG_ORP_OUTFRM_SHADOW_ERR vxge_mBIT(43)
+#define VXGE_HW_ORP_ERR_REG_ORP_OPTPRS_SHADOW_ERR vxge_mBIT(47)
+/*0x05818*/ u64 orp_err_mask;
+/*0x05820*/ u64 orp_err_alarm;
+/*0x05828*/ u64 ptm_alarm_reg;
+#define VXGE_HW_PTM_ALARM_REG_PTM_RDCTRL_SYNC_ERR vxge_mBIT(3)
+#define VXGE_HW_PTM_ALARM_REG_PTM_RDCTRL_FIFO_ERR vxge_mBIT(7)
+#define VXGE_HW_PTM_ALARM_REG_XFMD_RD_FIFO_ERR vxge_mBIT(11)
+#define VXGE_HW_PTM_ALARM_REG_WDE2MSR_WR_FIFO_ERR vxge_mBIT(15)
+#define VXGE_HW_PTM_ALARM_REG_PTM_FRMM_ECC_DB_ERR(val) vxge_vBIT(val, 18, 2)
+#define VXGE_HW_PTM_ALARM_REG_PTM_FRMM_ECC_SG_ERR(val) vxge_vBIT(val, 22, 2)
+/*0x05830*/ u64 ptm_alarm_mask;
+/*0x05838*/ u64 ptm_alarm_alarm;
+/*0x05840*/ u64 tpa_error_reg;
+#define VXGE_HW_TPA_ERROR_REG_TPA_FSM_ERR_ALARM vxge_mBIT(3)
+#define VXGE_HW_TPA_ERROR_REG_TPA_TPA_DA_LKUP_PRT0_DB_ERR vxge_mBIT(7)
+#define VXGE_HW_TPA_ERROR_REG_TPA_TPA_DA_LKUP_PRT0_SG_ERR vxge_mBIT(11)
+/*0x05848*/ u64 tpa_error_mask;
+/*0x05850*/ u64 tpa_error_alarm;
+/*0x05858*/ u64 tpa_global_cfg;
+#define VXGE_HW_TPA_GLOBAL_CFG_SUPPORT_SNAP_AB_N vxge_mBIT(7)
+#define VXGE_HW_TPA_GLOBAL_CFG_ECC_ENABLE_N vxge_mBIT(35)
+ u8 unused05868[0x05870-0x05860];
+
+/*0x05870*/ u64 ptm_ecc_cfg;
+#define VXGE_HW_PTM_ECC_CFG_PTM_FRMM_ECC_EN_N vxge_mBIT(3)
+/*0x05878*/ u64 ptm_phase_cfg;
+#define VXGE_HW_PTM_PHASE_CFG_FRMM_WR_PHASE_EN vxge_mBIT(3)
+#define VXGE_HW_PTM_PHASE_CFG_FRMM_RD_PHASE_EN vxge_mBIT(7)
+ u8 unused05898[0x05898-0x05880];
+
+/*0x05898*/ u64 dbg_stats_tpa_tx_path;
+#define VXGE_HW_DBG_STATS_TPA_TX_PATH_TX_PERMITTED_FRMS(val) \
+ vxge_vBIT(val, 32, 32)
+ u8 unused05900[0x05900-0x058a0];
+
+/*0x05900*/ u64 tmac_int_status;
+#define VXGE_HW_TMAC_INT_STATUS_TXMAC_GEN_ERR_TXMAC_GEN_INT vxge_mBIT(3)
+#define VXGE_HW_TMAC_INT_STATUS_TXMAC_ECC_ERR_TXMAC_ECC_INT vxge_mBIT(7)
+/*0x05908*/ u64 tmac_int_mask;
+/*0x05910*/ u64 txmac_gen_err_reg;
+#define VXGE_HW_TXMAC_GEN_ERR_REG_TMACJ_PERMANENT_STOP vxge_mBIT(3)
+#define VXGE_HW_TXMAC_GEN_ERR_REG_TMACJ_NO_VALID_VSPORT vxge_mBIT(7)
+/*0x05918*/ u64 txmac_gen_err_mask;
+/*0x05920*/ u64 txmac_gen_err_alarm;
+/*0x05928*/ u64 txmac_ecc_err_reg;
+#define VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMAC_TPA2MAC_SG_ERR vxge_mBIT(3)
+#define VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMAC_TPA2MAC_DB_ERR vxge_mBIT(7)
+#define VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMAC_TPA2M_SB_SG_ERR vxge_mBIT(11)
+#define VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMAC_TPA2M_SB_DB_ERR vxge_mBIT(15)
+#define VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMAC_TPA2M_DA_SG_ERR vxge_mBIT(19)
+#define VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMAC_TPA2M_DA_DB_ERR vxge_mBIT(23)
+#define VXGE_HW_TXMAC_ECC_ERR_REG_TMAC_TMAC_PORT0_FSM_ERR vxge_mBIT(27)
+#define VXGE_HW_TXMAC_ECC_ERR_REG_TMAC_TMAC_PORT1_FSM_ERR vxge_mBIT(31)
+#define VXGE_HW_TXMAC_ECC_ERR_REG_TMAC_TMAC_PORT2_FSM_ERR vxge_mBIT(35)
+#define VXGE_HW_TXMAC_ECC_ERR_REG_TMACJ_TMACJ_FSM_ERR vxge_mBIT(39)
+/*0x05930*/ u64 txmac_ecc_err_mask;
+/*0x05938*/ u64 txmac_ecc_err_alarm;
+ u8 unused05978[0x05978-0x05940];
+
+/*0x05978*/ u64 dbg_stat_tx_any_frms;
+#define VXGE_HW_DBG_STAT_TX_ANY_FRMS_PORT0_TX_ANY_FRMS(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_DBG_STAT_TX_ANY_FRMS_PORT1_TX_ANY_FRMS(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_DBG_STAT_TX_ANY_FRMS_PORT2_TX_ANY_FRMS(val) \
+ vxge_vBIT(val, 16, 8)
+ u8 unused059a0[0x059a0-0x05980];
+
+/*0x059a0*/ u64 txmac_link_util_port[3];
+#define VXGE_HW_TXMAC_LINK_UTIL_PORT_TMAC_TMAC_UTILIZATION(val) \
+ vxge_vBIT(val, 1, 7)
+#define VXGE_HW_TXMAC_LINK_UTIL_PORT_TMAC_UTIL_CFG(val) vxge_vBIT(val, 8, 4)
+#define VXGE_HW_TXMAC_LINK_UTIL_PORT_TMAC_TMAC_FRAC_UTIL(val) \
+ vxge_vBIT(val, 12, 4)
+#define VXGE_HW_TXMAC_LINK_UTIL_PORT_TMAC_PKT_WEIGHT(val) vxge_vBIT(val, 16, 4)
+#define VXGE_HW_TXMAC_LINK_UTIL_PORT_TMAC_TMAC_SCALE_FACTOR vxge_mBIT(23)
+/*0x059b8*/ u64 txmac_cfg0_port[3];
+#define VXGE_HW_TXMAC_CFG0_PORT_TMAC_EN vxge_mBIT(3)
+#define VXGE_HW_TXMAC_CFG0_PORT_APPEND_PAD vxge_mBIT(7)
+#define VXGE_HW_TXMAC_CFG0_PORT_PAD_BYTE(val) vxge_vBIT(val, 8, 8)
+/*0x059d0*/ u64 txmac_cfg1_port[3];
+#define VXGE_HW_TXMAC_CFG1_PORT_AVG_IPG(val) vxge_vBIT(val, 40, 8)
+/*0x059e8*/ u64 txmac_status_port[3];
+#define VXGE_HW_TXMAC_STATUS_PORT_TMAC_TX_FRM_SENT vxge_mBIT(3)
+ u8 unused05a20[0x05a20-0x05a00];
+
+/*0x05a20*/ u64 lag_distrib_dest;
+#define VXGE_HW_LAG_DISTRIB_DEST_MAP_VPATH(n) vxge_mBIT(n)
+/*0x05a28*/ u64 lag_marker_cfg;
+#define VXGE_HW_LAG_MARKER_CFG_GEN_RCVR_EN vxge_mBIT(3)
+#define VXGE_HW_LAG_MARKER_CFG_RESP_EN vxge_mBIT(7)
+#define VXGE_HW_LAG_MARKER_CFG_RESP_TIMEOUT(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_LAG_MARKER_CFG_SLOW_PROTO_MRKR_MIN_INTERVAL(val) \
+ vxge_vBIT(val, 32, 16)
+#define VXGE_HW_LAG_MARKER_CFG_THROTTLE_MRKR_RESP vxge_mBIT(51)
+/*0x05a30*/ u64 lag_tx_cfg;
+#define VXGE_HW_LAG_TX_CFG_INCR_TX_AGGR_STATS vxge_mBIT(3)
+#define VXGE_HW_LAG_TX_CFG_DISTRIB_ALG_SEL(val) vxge_vBIT(val, 6, 2)
+#define VXGE_HW_LAG_TX_CFG_DISTRIB_REMAP_IF_FAIL vxge_mBIT(11)
+#define VXGE_HW_LAG_TX_CFG_COLL_MAX_DELAY(val) vxge_vBIT(val, 16, 16)
+/*0x05a38*/ u64 lag_tx_status;
+#define VXGE_HW_LAG_TX_STATUS_TLAG_TIMER_VAL_EMPTIED_LINK(val) \
+ vxge_vBIT(val, 0, 8)
+#define VXGE_HW_LAG_TX_STATUS_TLAG_TIMER_VAL_SLOW_PROTO_MRKR(val) \
+ vxge_vBIT(val, 8, 8)
+#define VXGE_HW_LAG_TX_STATUS_TLAG_TIMER_VAL_SLOW_PROTO_MRKRRESP(val) \
+ vxge_vBIT(val, 16, 8)
+ u8 unused05d48[0x05d48-0x05a40];
+
+/*0x05d48*/ u64 srpcim_to_mrpcim_vplane_rmsg[17];
+#define \
+VXGE_HAL_SRPCIM_TO_MRPCIM_VPLANE_RMSG_SWIF_SRPCIM_TO_MRPCIM_VPLANE_RMSG(val)\
+ vxge_vBIT(val, 0, 64)
+ u8 unused06420[0x06420-0x05dd0];
+
+/*0x06420*/ u64 mrpcim_to_srpcim_vplane_wmsg[17];
+#define VXGE_HW_MRPCIM_TO_SRPCIM_VPLANE_WMSG_MRPCIM_TO_SRPCIM_VPLANE_WMSG(val) \
+ vxge_vBIT(val, 0, 64)
+/*0x064a8*/ u64 mrpcim_to_srpcim_vplane_wmsg_trig[17];
+
+/*0x06530*/ u64 debug_stats0;
+#define VXGE_HW_DEBUG_STATS0_RSTDROP_MSG(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_DEBUG_STATS0_RSTDROP_CPL(val) vxge_vBIT(val, 32, 32)
+/*0x06538*/ u64 debug_stats1;
+#define VXGE_HW_DEBUG_STATS1_RSTDROP_CLIENT0(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_DEBUG_STATS1_RSTDROP_CLIENT1(val) vxge_vBIT(val, 32, 32)
+/*0x06540*/ u64 debug_stats2;
+#define VXGE_HW_DEBUG_STATS2_RSTDROP_CLIENT2(val) vxge_vBIT(val, 0, 32)
+/*0x06548*/ u64 debug_stats3_vplane[17];
+#define VXGE_HW_DEBUG_STATS3_VPLANE_DEPL_PH(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_DEBUG_STATS3_VPLANE_DEPL_NPH(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_DEBUG_STATS3_VPLANE_DEPL_CPLH(val) vxge_vBIT(val, 32, 16)
+/*0x065d0*/ u64 debug_stats4_vplane[17];
+#define VXGE_HW_DEBUG_STATS4_VPLANE_DEPL_PD(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_DEBUG_STATS4_VPLANE_DEPL_NPD(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_DEBUG_STATS4_VPLANE_DEPL_CPLD(val) vxge_vBIT(val, 32, 16)
+
+ u8 unused07000[0x07000-0x06658];
+
+/*0x07000*/ u64 mrpcim_general_int_status;
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_PIC_INT vxge_mBIT(0)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_PCI_INT vxge_mBIT(1)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_RTDMA_INT vxge_mBIT(2)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_WRDMA_INT vxge_mBIT(3)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_G3CMCT_INT vxge_mBIT(4)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_GCMG1_INT vxge_mBIT(5)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_GCMG2_INT vxge_mBIT(6)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_GCMG3_INT vxge_mBIT(7)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_G3CMIFL_INT vxge_mBIT(8)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_G3CMIFU_INT vxge_mBIT(9)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_PCMG1_INT vxge_mBIT(10)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_PCMG2_INT vxge_mBIT(11)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_PCMG3_INT vxge_mBIT(12)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_XMAC_INT vxge_mBIT(13)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_RXMAC_INT vxge_mBIT(14)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_TMAC_INT vxge_mBIT(15)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_G3FBIF_INT vxge_mBIT(16)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_FBMC_INT vxge_mBIT(17)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_G3FBCT_INT vxge_mBIT(18)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_TPA_INT vxge_mBIT(19)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_DRBELL_INT vxge_mBIT(20)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_ONE_INT vxge_mBIT(21)
+#define VXGE_HW_MRPCIM_GENERAL_INT_STATUS_MSG_INT vxge_mBIT(22)
+/*0x07008*/ u64 mrpcim_general_int_mask;
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_PIC_INT vxge_mBIT(0)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_PCI_INT vxge_mBIT(1)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_RTDMA_INT vxge_mBIT(2)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_WRDMA_INT vxge_mBIT(3)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_G3CMCT_INT vxge_mBIT(4)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_GCMG1_INT vxge_mBIT(5)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_GCMG2_INT vxge_mBIT(6)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_GCMG3_INT vxge_mBIT(7)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_G3CMIFL_INT vxge_mBIT(8)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_G3CMIFU_INT vxge_mBIT(9)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_PCMG1_INT vxge_mBIT(10)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_PCMG2_INT vxge_mBIT(11)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_PCMG3_INT vxge_mBIT(12)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_XMAC_INT vxge_mBIT(13)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_RXMAC_INT vxge_mBIT(14)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_TMAC_INT vxge_mBIT(15)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_G3FBIF_INT vxge_mBIT(16)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_FBMC_INT vxge_mBIT(17)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_G3FBCT_INT vxge_mBIT(18)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_TPA_INT vxge_mBIT(19)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_DRBELL_INT vxge_mBIT(20)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_ONE_INT vxge_mBIT(21)
+#define VXGE_HW_MRPCIM_GENERAL_INT_MASK_MSG_INT vxge_mBIT(22)
+/*0x07010*/ u64 mrpcim_ppif_int_status;
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_INI_ERRORS_INI_INT vxge_mBIT(3)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_DMA_ERRORS_DMA_INT vxge_mBIT(7)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_TGT_ERRORS_TGT_INT vxge_mBIT(11)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_CONFIG_ERRORS_CONFIG_INT vxge_mBIT(15)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_CRDT_INT vxge_mBIT(19)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_PLL_ERRORS_PLL_INT vxge_mBIT(27)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE0_CRD_INT_VPLANE0_INT\
+ vxge_mBIT(31)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE1_CRD_INT_VPLANE1_INT\
+ vxge_mBIT(32)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE2_CRD_INT_VPLANE2_INT\
+ vxge_mBIT(33)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE3_CRD_INT_VPLANE3_INT\
+ vxge_mBIT(34)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE4_CRD_INT_VPLANE4_INT\
+ vxge_mBIT(35)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE5_CRD_INT_VPLANE5_INT\
+ vxge_mBIT(36)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE6_CRD_INT_VPLANE6_INT\
+ vxge_mBIT(37)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE7_CRD_INT_VPLANE7_INT\
+ vxge_mBIT(38)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE8_CRD_INT_VPLANE8_INT\
+ vxge_mBIT(39)
+#define VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE9_CRD_INT_VPLANE9_INT\
+ vxge_mBIT(40)
+#define \
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE10_CRD_INT_VPLANE10_INT \
+ vxge_mBIT(41)
+#define \
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE11_CRD_INT_VPLANE11_INT \
+ vxge_mBIT(42)
+#define \
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE12_CRD_INT_VPLANE12_INT \
+ vxge_mBIT(43)
+#define \
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE13_CRD_INT_VPLANE13_INT \
+ vxge_mBIT(44)
+#define \
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE14_CRD_INT_VPLANE14_INT \
+ vxge_mBIT(45)
+#define \
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE15_CRD_INT_VPLANE15_INT \
+ vxge_mBIT(46)
+#define \
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_CRDT_ERRORS_VPLANE16_CRD_INT_VPLANE16_INT \
+ vxge_mBIT(47)
+#define \
+VXGE_HW_MRPCIM_PPIF_INT_STATUS_VPATH_TO_MRPCIM_ALARM_VPATH_TO_MRPCIM_ALARM_INT \
+ vxge_mBIT(55)
+/*0x07018*/ u64 mrpcim_ppif_int_mask;
+ u8 unused07028[0x07028-0x07020];
+
+/*0x07028*/ u64 ini_errors_reg;
+#define VXGE_HW_INI_ERRORS_REG_SCPL_CPL_TIMEOUT_UNUSED_TAG vxge_mBIT(3)
+#define VXGE_HW_INI_ERRORS_REG_SCPL_CPL_TIMEOUT vxge_mBIT(7)
+#define VXGE_HW_INI_ERRORS_REG_DCPL_FSM_ERR vxge_mBIT(11)
+#define VXGE_HW_INI_ERRORS_REG_DCPL_POISON vxge_mBIT(12)
+#define VXGE_HW_INI_ERRORS_REG_DCPL_UNSUPPORTED vxge_mBIT(15)
+#define VXGE_HW_INI_ERRORS_REG_DCPL_ABORT vxge_mBIT(19)
+#define VXGE_HW_INI_ERRORS_REG_INI_TLP_ABORT vxge_mBIT(23)
+#define VXGE_HW_INI_ERRORS_REG_INI_DLLP_ABORT vxge_mBIT(27)
+#define VXGE_HW_INI_ERRORS_REG_INI_ECRC_ERR vxge_mBIT(31)
+#define VXGE_HW_INI_ERRORS_REG_INI_BUF_DB_ERR vxge_mBIT(35)
+#define VXGE_HW_INI_ERRORS_REG_INI_BUF_SG_ERR vxge_mBIT(39)
+#define VXGE_HW_INI_ERRORS_REG_INI_DATA_OVERFLOW vxge_mBIT(43)
+#define VXGE_HW_INI_ERRORS_REG_INI_HDR_OVERFLOW vxge_mBIT(47)
+#define VXGE_HW_INI_ERRORS_REG_INI_MRD_SYS_DROP vxge_mBIT(51)
+#define VXGE_HW_INI_ERRORS_REG_INI_MWR_SYS_DROP vxge_mBIT(55)
+#define VXGE_HW_INI_ERRORS_REG_INI_MRD_CLIENT_DROP vxge_mBIT(59)
+#define VXGE_HW_INI_ERRORS_REG_INI_MWR_CLIENT_DROP vxge_mBIT(63)
+/*0x07030*/ u64 ini_errors_mask;
+/*0x07038*/ u64 ini_errors_alarm;
+/*0x07040*/ u64 dma_errors_reg;
+#define VXGE_HW_DMA_ERRORS_REG_RDARB_FSM_ERR vxge_mBIT(3)
+#define VXGE_HW_DMA_ERRORS_REG_WRARB_FSM_ERR vxge_mBIT(7)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_WRDMA_WR_HDR_OVERFLOW vxge_mBIT(8)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_WRDMA_WR_HDR_UNDERFLOW vxge_mBIT(9)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_WRDMA_WR_DATA_OVERFLOW vxge_mBIT(10)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_WRDMA_WR_DATA_UNDERFLOW vxge_mBIT(11)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_MSG_WR_HDR_OVERFLOW vxge_mBIT(12)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_MSG_WR_HDR_UNDERFLOW vxge_mBIT(13)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_MSG_WR_DATA_OVERFLOW vxge_mBIT(14)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_MSG_WR_DATA_UNDERFLOW vxge_mBIT(15)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_STATS_WR_HDR_OVERFLOW vxge_mBIT(16)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_STATS_WR_HDR_UNDERFLOW vxge_mBIT(17)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_STATS_WR_DATA_OVERFLOW vxge_mBIT(18)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_STATS_WR_DATA_UNDERFLOW vxge_mBIT(19)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_RTDMA_WR_HDR_OVERFLOW vxge_mBIT(20)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_RTDMA_WR_HDR_UNDERFLOW vxge_mBIT(21)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_RTDMA_WR_DATA_OVERFLOW vxge_mBIT(22)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_RTDMA_WR_DATA_UNDERFLOW vxge_mBIT(23)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_WRDMA_RD_HDR_OVERFLOW vxge_mBIT(24)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_WRDMA_RD_HDR_UNDERFLOW vxge_mBIT(25)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_RTDMA_RD_HDR_OVERFLOW vxge_mBIT(28)
+#define VXGE_HW_DMA_ERRORS_REG_DMA_RTDMA_RD_HDR_UNDERFLOW vxge_mBIT(29)
+#define VXGE_HW_DMA_ERRORS_REG_DBLGEN_FSM_ERR vxge_mBIT(32)
+#define VXGE_HW_DMA_ERRORS_REG_DBLGEN_CREDIT_FSM_ERR vxge_mBIT(33)
+#define VXGE_HW_DMA_ERRORS_REG_DBLGEN_DMA_WRR_SM_ERR vxge_mBIT(34)
+/*0x07048*/ u64 dma_errors_mask;
+/*0x07050*/ u64 dma_errors_alarm;
+/*0x07058*/ u64 tgt_errors_reg;
+#define VXGE_HW_TGT_ERRORS_REG_TGT_VENDOR_MSG vxge_mBIT(0)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_MSG_UNLOCK vxge_mBIT(1)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_ILLEGAL_TLP_BE vxge_mBIT(2)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_BOOT_WRITE vxge_mBIT(3)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_PIF_WR_CROSS_QWRANGE vxge_mBIT(4)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_PIF_READ_CROSS_QWRANGE vxge_mBIT(5)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_KDFC_READ vxge_mBIT(6)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_USDC_READ vxge_mBIT(7)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_USDC_WR_CROSS_QWRANGE vxge_mBIT(8)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_MSIX_BEYOND_RANGE vxge_mBIT(9)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_WR_TO_KDFC_POISON vxge_mBIT(10)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_WR_TO_USDC_POISON vxge_mBIT(11)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_WR_TO_PIF_POISON vxge_mBIT(12)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_WR_TO_MSIX_POISON vxge_mBIT(13)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_WR_TO_MRIOV_POISON vxge_mBIT(14)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_NOT_MEM_TLP vxge_mBIT(15)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_UNKNOWN_MEM_TLP vxge_mBIT(16)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_REQ_FSM_ERR vxge_mBIT(17)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_CPL_FSM_ERR vxge_mBIT(18)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_KDFC_PROT_ERR vxge_mBIT(19)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_SWIF_PROT_ERR vxge_mBIT(20)
+#define VXGE_HW_TGT_ERRORS_REG_TGT_MRIOV_MEM_MAP_CFG_ERR vxge_mBIT(21)
+/*0x07060*/ u64 tgt_errors_mask;
+/*0x07068*/ u64 tgt_errors_alarm;
+/*0x07070*/ u64 config_errors_reg;
+#define VXGE_HW_CONFIG_ERRORS_REG_I2C_ILLEGAL_STOP_COND vxge_mBIT(3)
+#define VXGE_HW_CONFIG_ERRORS_REG_I2C_ILLEGAL_START_COND vxge_mBIT(7)
+#define VXGE_HW_CONFIG_ERRORS_REG_I2C_EXP_RD_CNT vxge_mBIT(11)
+#define VXGE_HW_CONFIG_ERRORS_REG_I2C_EXTRA_CYCLE vxge_mBIT(15)
+#define VXGE_HW_CONFIG_ERRORS_REG_I2C_MAIN_FSM_ERR vxge_mBIT(19)
+#define VXGE_HW_CONFIG_ERRORS_REG_I2C_REQ_COLLISION vxge_mBIT(23)
+#define VXGE_HW_CONFIG_ERRORS_REG_I2C_REG_FSM_ERR vxge_mBIT(27)
+#define VXGE_HW_CONFIG_ERRORS_REG_CFGM_I2C_TIMEOUT vxge_mBIT(31)
+#define VXGE_HW_CONFIG_ERRORS_REG_RIC_I2C_TIMEOUT vxge_mBIT(35)
+#define VXGE_HW_CONFIG_ERRORS_REG_CFGM_FSM_ERR vxge_mBIT(39)
+#define VXGE_HW_CONFIG_ERRORS_REG_RIC_FSM_ERR vxge_mBIT(43)
+#define VXGE_HW_CONFIG_ERRORS_REG_PIFM_ILLEGAL_ACCESS vxge_mBIT(47)
+#define VXGE_HW_CONFIG_ERRORS_REG_PIFM_TIMEOUT vxge_mBIT(51)
+#define VXGE_HW_CONFIG_ERRORS_REG_PIFM_FSM_ERR vxge_mBIT(55)
+#define VXGE_HW_CONFIG_ERRORS_REG_PIFM_TO_FSM_ERR vxge_mBIT(59)
+#define VXGE_HW_CONFIG_ERRORS_REG_RIC_RIC_RD_TIMEOUT vxge_mBIT(63)
+/*0x07078*/ u64 config_errors_mask;
+/*0x07080*/ u64 config_errors_alarm;
+ u8 unused07090[0x07090-0x07088];
+
+/*0x07090*/ u64 crdt_errors_reg;
+#define VXGE_HW_CRDT_ERRORS_REG_WRCRDTARB_FSM_ERR vxge_mBIT(11)
+#define VXGE_HW_CRDT_ERRORS_REG_WRCRDTARB_INTCTL_ILLEGAL_CRD_DEAL \
+ vxge_mBIT(15)
+#define VXGE_HW_CRDT_ERRORS_REG_WRCRDTARB_PDA_ILLEGAL_CRD_DEAL vxge_mBIT(19)
+#define VXGE_HW_CRDT_ERRORS_REG_WRCRDTARB_PCI_MSG_ILLEGAL_CRD_DEAL \
+ vxge_mBIT(23)
+#define VXGE_HW_CRDT_ERRORS_REG_RDCRDTARB_FSM_ERR vxge_mBIT(35)
+#define VXGE_HW_CRDT_ERRORS_REG_RDCRDTARB_RDA_ILLEGAL_CRD_DEAL vxge_mBIT(39)
+#define VXGE_HW_CRDT_ERRORS_REG_RDCRDTARB_PDA_ILLEGAL_CRD_DEAL vxge_mBIT(43)
+#define VXGE_HW_CRDT_ERRORS_REG_RDCRDTARB_DBLGEN_ILLEGAL_CRD_DEAL \
+ vxge_mBIT(47)
+/*0x07098*/ u64 crdt_errors_mask;
+/*0x070a0*/ u64 crdt_errors_alarm;
+ u8 unused070b0[0x070b0-0x070a8];
+
+/*0x070b0*/ u64 mrpcim_general_errors_reg;
+#define VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_STATSB_FSM_ERR vxge_mBIT(3)
+#define VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_XGEN_FSM_ERR vxge_mBIT(7)
+#define VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_XMEM_FSM_ERR vxge_mBIT(11)
+#define VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_KDFCCTL_FSM_ERR vxge_mBIT(15)
+#define VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_MRIOVCTL_FSM_ERR vxge_mBIT(19)
+#define VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_SPI_FLSH_ERR vxge_mBIT(23)
+#define VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_SPI_IIC_ACK_ERR vxge_mBIT(27)
+#define VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_SPI_IIC_CHKSUM_ERR vxge_mBIT(31)
+#define VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_INI_SERR_DET vxge_mBIT(35)
+#define VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_INTCTL_MSIX_FSM_ERR vxge_mBIT(39)
+#define VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_INTCTL_MSI_OVERFLOW vxge_mBIT(43)
+#define VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_PPIF_PCI_NOT_FLUSH_DURING_SW_RESET \
+ vxge_mBIT(47)
+#define VXGE_HW_MRPCIM_GENERAL_ERRORS_REG_PPIF_SW_RESET_FSM_ERR vxge_mBIT(51)
+/*0x070b8*/ u64 mrpcim_general_errors_mask;
+/*0x070c0*/ u64 mrpcim_general_errors_alarm;
+ u8 unused070d0[0x070d0-0x070c8];
+
+/*0x070d0*/ u64 pll_errors_reg;
+#define VXGE_HW_PLL_ERRORS_REG_CORE_CMG_PLL_OOL vxge_mBIT(3)
+#define VXGE_HW_PLL_ERRORS_REG_CORE_FB_PLL_OOL vxge_mBIT(7)
+#define VXGE_HW_PLL_ERRORS_REG_CORE_X_PLL_OOL vxge_mBIT(11)
+/*0x070d8*/ u64 pll_errors_mask;
+/*0x070e0*/ u64 pll_errors_alarm;
+/*0x070e8*/ u64 srpcim_to_mrpcim_alarm_reg;
+#define VXGE_HW_SRPCIM_TO_MRPCIM_ALARM_REG_PPIF_SRPCIM_TO_MRPCIM_ALARM(val) \
+ vxge_vBIT(val, 0, 17)
+/*0x070f0*/ u64 srpcim_to_mrpcim_alarm_mask;
+/*0x070f8*/ u64 srpcim_to_mrpcim_alarm_alarm;
+/*0x07100*/ u64 vpath_to_mrpcim_alarm_reg;
+#define VXGE_HW_VPATH_TO_MRPCIM_ALARM_REG_PPIF_VPATH_TO_MRPCIM_ALARM(val) \
+ vxge_vBIT(val, 0, 17)
+/*0x07108*/ u64 vpath_to_mrpcim_alarm_mask;
+/*0x07110*/ u64 vpath_to_mrpcim_alarm_alarm;
+ u8 unused07128[0x07128-0x07118];
+
+/*0x07128*/ u64 crdt_errors_vplane_reg[17];
+#define VXGE_HW_CRDT_ERRORS_VPLANE_REG_WRCRDTARB_P_H_CONSUME_CRDT_ERR \
+ vxge_mBIT(3)
+#define VXGE_HW_CRDT_ERRORS_VPLANE_REG_WRCRDTARB_P_D_CONSUME_CRDT_ERR \
+ vxge_mBIT(7)
+#define VXGE_HW_CRDT_ERRORS_VPLANE_REG_WRCRDTARB_P_H_RETURN_CRDT_ERR \
+ vxge_mBIT(11)
+#define VXGE_HW_CRDT_ERRORS_VPLANE_REG_WRCRDTARB_P_D_RETURN_CRDT_ERR \
+ vxge_mBIT(15)
+#define VXGE_HW_CRDT_ERRORS_VPLANE_REG_RDCRDTARB_NP_H_CONSUME_CRDT_ERR \
+ vxge_mBIT(19)
+#define VXGE_HW_CRDT_ERRORS_VPLANE_REG_RDCRDTARB_NP_H_RETURN_CRDT_ERR \
+ vxge_mBIT(23)
+#define VXGE_HW_CRDT_ERRORS_VPLANE_REG_RDCRDTARB_TAG_CONSUME_TAG_ERR \
+ vxge_mBIT(27)
+#define VXGE_HW_CRDT_ERRORS_VPLANE_REG_RDCRDTARB_TAG_RETURN_TAG_ERR \
+ vxge_mBIT(31)
+/*0x07130*/ u64 crdt_errors_vplane_mask[17];
+/*0x07138*/ u64 crdt_errors_vplane_alarm[17];
+ u8 unused072f0[0x072f0-0x072c0];
+
+/*0x072f0*/ u64 mrpcim_rst_in_prog;
+#define VXGE_HW_MRPCIM_RST_IN_PROG_MRPCIM_RST_IN_PROG vxge_mBIT(7)
+/*0x072f8*/ u64 mrpcim_reg_modified;
+#define VXGE_HW_MRPCIM_REG_MODIFIED_MRPCIM_REG_MODIFIED vxge_mBIT(7)
+
+ u8 unused07378[0x07378-0x07300];
+
+/*0x07378*/ u64 write_arb_pending;
+#define VXGE_HW_WRITE_ARB_PENDING_WRARB_WRDMA vxge_mBIT(3)
+#define VXGE_HW_WRITE_ARB_PENDING_WRARB_RTDMA vxge_mBIT(7)
+#define VXGE_HW_WRITE_ARB_PENDING_WRARB_MSG vxge_mBIT(11)
+#define VXGE_HW_WRITE_ARB_PENDING_WRARB_STATSB vxge_mBIT(15)
+#define VXGE_HW_WRITE_ARB_PENDING_WRARB_INTCTL vxge_mBIT(19)
+/*0x07380*/ u64 read_arb_pending;
+#define VXGE_HW_READ_ARB_PENDING_RDARB_WRDMA vxge_mBIT(3)
+#define VXGE_HW_READ_ARB_PENDING_RDARB_RTDMA vxge_mBIT(7)
+#define VXGE_HW_READ_ARB_PENDING_RDARB_DBLGEN vxge_mBIT(11)
+/*0x07388*/ u64 dmaif_dmadbl_pending;
+#define VXGE_HW_DMAIF_DMADBL_PENDING_DMAIF_WRDMA_WR vxge_mBIT(0)
+#define VXGE_HW_DMAIF_DMADBL_PENDING_DMAIF_WRDMA_RD vxge_mBIT(1)
+#define VXGE_HW_DMAIF_DMADBL_PENDING_DMAIF_RTDMA_WR vxge_mBIT(2)
+#define VXGE_HW_DMAIF_DMADBL_PENDING_DMAIF_RTDMA_RD vxge_mBIT(3)
+#define VXGE_HW_DMAIF_DMADBL_PENDING_DMAIF_MSG_WR vxge_mBIT(4)
+#define VXGE_HW_DMAIF_DMADBL_PENDING_DMAIF_STATS_WR vxge_mBIT(5)
+#define VXGE_HW_DMAIF_DMADBL_PENDING_DBLGEN_IN_PROG(val) \
+ vxge_vBIT(val, 13, 51)
+/*0x07390*/ u64 wrcrdtarb_status0_vplane[17];
+#define VXGE_HW_WRCRDTARB_STATUS0_VPLANE_WRCRDTARB_ABS_AVAIL_P_H(val) \
+ vxge_vBIT(val, 0, 8)
+/*0x07418*/ u64 wrcrdtarb_status1_vplane[17];
+#define VXGE_HW_WRCRDTARB_STATUS1_VPLANE_WRCRDTARB_ABS_AVAIL_P_D(val) \
+ vxge_vBIT(val, 4, 12)
+ u8 unused07500[0x07500-0x074a0];
+
+/*0x07500*/ u64 mrpcim_general_cfg1;
+#define VXGE_HW_MRPCIM_GENERAL_CFG1_CLEAR_SERR vxge_mBIT(7)
+/*0x07508*/ u64 mrpcim_general_cfg2;
+#define VXGE_HW_MRPCIM_GENERAL_CFG2_INS_TX_WR_TD vxge_mBIT(3)
+#define VXGE_HW_MRPCIM_GENERAL_CFG2_INS_TX_RD_TD vxge_mBIT(7)
+#define VXGE_HW_MRPCIM_GENERAL_CFG2_INS_TX_CPL_TD vxge_mBIT(11)
+#define VXGE_HW_MRPCIM_GENERAL_CFG2_INI_TIMEOUT_EN_MWR vxge_mBIT(15)
+#define VXGE_HW_MRPCIM_GENERAL_CFG2_INI_TIMEOUT_EN_MRD vxge_mBIT(19)
+#define VXGE_HW_MRPCIM_GENERAL_CFG2_IGNORE_VPATH_RST_FOR_MSIX vxge_mBIT(23)
+#define VXGE_HW_MRPCIM_GENERAL_CFG2_FLASH_READ_MSB vxge_mBIT(27)
+#define VXGE_HW_MRPCIM_GENERAL_CFG2_DIS_HOST_PIPELINE_WR vxge_mBIT(31)
+#define VXGE_HW_MRPCIM_GENERAL_CFG2_MRPCIM_STATS_ENABLE vxge_mBIT(43)
+#define VXGE_HW_MRPCIM_GENERAL_CFG2_MRPCIM_STATS_MAP_TO_VPATH(val) \
+ vxge_vBIT(val, 47, 5)
+#define VXGE_HW_MRPCIM_GENERAL_CFG2_EN_BLOCK_MSIX_DUE_TO_SERR vxge_mBIT(55)
+#define VXGE_HW_MRPCIM_GENERAL_CFG2_FORCE_SENDING_INTA vxge_mBIT(59)
+#define VXGE_HW_MRPCIM_GENERAL_CFG2_DIS_SWIF_PROT_ON_RDS vxge_mBIT(63)
+/*0x07510*/ u64 mrpcim_general_cfg3;
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_PROTECTION_CA_OR_UNSUPN vxge_mBIT(0)
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_ILLEGAL_RD_CA_OR_UNSUPN vxge_mBIT(3)
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_RD_BYTE_SWAPEN vxge_mBIT(7)
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_RD_BIT_FLIPEN vxge_mBIT(11)
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_WR_BYTE_SWAPEN vxge_mBIT(15)
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_WR_BIT_FLIPEN vxge_mBIT(19)
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_MR_MAX_MVFS(val) vxge_vBIT(val, 20, 16)
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_MR_MVF_TBL_SIZE(val) \
+ vxge_vBIT(val, 36, 16)
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_PF0_SW_RESET_EN vxge_mBIT(55)
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_REG_MODIFIED_CFG(val) vxge_vBIT(val, 56, 2)
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_CPL_ECC_ENABLE_N vxge_mBIT(59)
+#define VXGE_HW_MRPCIM_GENERAL_CFG3_BYPASS_DAISY_CHAIN vxge_mBIT(63)
+/*0x07518*/ u64 mrpcim_stats_start_host_addr;
+#define VXGE_HW_MRPCIM_STATS_START_HOST_ADDR_MRPCIM_STATS_START_HOST_ADDR(val)\
+ vxge_vBIT(val, 0, 57)
+
+ u8 unused07950[0x07950-0x07520];
+
+/*0x07950*/ u64 rdcrdtarb_cfg0;
+#define VXGE_HW_RDCRDTARB_CFG0_RDA_MAX_OUTSTANDING_RDS(val) \
+ vxge_vBIT(val, 18, 6)
+#define VXGE_HW_RDCRDTARB_CFG0_PDA_MAX_OUTSTANDING_RDS(val) \
+ vxge_vBIT(val, 26, 6)
+#define VXGE_HW_RDCRDTARB_CFG0_DBLGEN_MAX_OUTSTANDING_RDS(val) \
+ vxge_vBIT(val, 34, 6)
+#define VXGE_HW_RDCRDTARB_CFG0_WAIT_CNT(val) vxge_vBIT(val, 48, 4)
+#define VXGE_HW_RDCRDTARB_CFG0_MAX_OUTSTANDING_RDS(val) vxge_vBIT(val, 54, 6)
+#define VXGE_HW_RDCRDTARB_CFG0_EN_XON vxge_mBIT(63)
+ u8 unused07be8[0x07be8-0x07958];
+
+/*0x07be8*/ u64 bf_sw_reset;
+#define VXGE_HW_BF_SW_RESET_BF_SW_RESET(val) vxge_vBIT(val, 0, 8)
+/*0x07bf0*/ u64 sw_reset_status;
+#define VXGE_HW_SW_RESET_STATUS_RESET_CMPLT vxge_mBIT(7)
+#define VXGE_HW_SW_RESET_STATUS_INIT_CMPLT vxge_mBIT(15)
+ u8 unused07d30[0x07d30-0x07bf8];
+
+/*0x07d30*/ u64 mrpcim_debug_stats0;
+#define VXGE_HW_MRPCIM_DEBUG_STATS0_INI_WR_DROP(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_MRPCIM_DEBUG_STATS0_INI_RD_DROP(val) vxge_vBIT(val, 32, 32)
+/*0x07d38*/ u64 mrpcim_debug_stats1_vplane[17];
+#define VXGE_HW_MRPCIM_DEBUG_STATS1_VPLANE_WRCRDTARB_PH_CRDT_DEPLETED(val) \
+ vxge_vBIT(val, 32, 32)
+/*0x07dc0*/ u64 mrpcim_debug_stats2_vplane[17];
+#define VXGE_HW_MRPCIM_DEBUG_STATS2_VPLANE_WRCRDTARB_PD_CRDT_DEPLETED(val) \
+ vxge_vBIT(val, 32, 32)
+/*0x07e48*/ u64 mrpcim_debug_stats3_vplane[17];
+#define VXGE_HW_MRPCIM_DEBUG_STATS3_VPLANE_RDCRDTARB_NPH_CRDT_DEPLETED(val) \
+ vxge_vBIT(val, 32, 32)
+/*0x07ed0*/ u64 mrpcim_debug_stats4;
+#define VXGE_HW_MRPCIM_DEBUG_STATS4_INI_WR_VPIN_DROP(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_MRPCIM_DEBUG_STATS4_INI_RD_VPIN_DROP(val) \
+ vxge_vBIT(val, 32, 32)
+/*0x07ed8*/ u64 genstats_count01;
+#define VXGE_HW_GENSTATS_COUNT01_GENSTATS_COUNT1(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_GENSTATS_COUNT01_GENSTATS_COUNT0(val) vxge_vBIT(val, 32, 32)
+/*0x07ee0*/ u64 genstats_count23;
+#define VXGE_HW_GENSTATS_COUNT23_GENSTATS_COUNT3(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_GENSTATS_COUNT23_GENSTATS_COUNT2(val) vxge_vBIT(val, 32, 32)
+/*0x07ee8*/ u64 genstats_count4;
+#define VXGE_HW_GENSTATS_COUNT4_GENSTATS_COUNT4(val) vxge_vBIT(val, 32, 32)
+/*0x07ef0*/ u64 genstats_count5;
+#define VXGE_HW_GENSTATS_COUNT5_GENSTATS_COUNT5(val) vxge_vBIT(val, 32, 32)
+
+ u8 unused07f08[0x07f08-0x07ef8];
+
+/*0x07f08*/ u64 genstats_cfg[6];
+#define VXGE_HW_GENSTATS_CFG_DTYPE_SEL(val) vxge_vBIT(val, 3, 5)
+#define VXGE_HW_GENSTATS_CFG_CLIENT_NO_SEL(val) vxge_vBIT(val, 9, 3)
+#define VXGE_HW_GENSTATS_CFG_WR_RD_CPL_SEL(val) vxge_vBIT(val, 14, 2)
+#define VXGE_HW_GENSTATS_CFG_VPATH_SEL(val) vxge_vBIT(val, 31, 17)
+/*0x07f38*/ u64 genstat_64bit_cfg;
+#define VXGE_HW_GENSTAT_64BIT_CFG_EN_FOR_GENSTATS0 vxge_mBIT(3)
+#define VXGE_HW_GENSTAT_64BIT_CFG_EN_FOR_GENSTATS2 vxge_mBIT(7)
+ u8 unused08000[0x08000-0x07f40];
+/*0x08000*/ u64 gcmg3_int_status;
+#define VXGE_HW_GCMG3_INT_STATUS_GSTC_ERR0_GSTC0_INT vxge_mBIT(0)
+#define VXGE_HW_GCMG3_INT_STATUS_GSTC_ERR1_GSTC1_INT vxge_mBIT(1)
+#define VXGE_HW_GCMG3_INT_STATUS_GH2L_ERR0_GH2L0_INT vxge_mBIT(2)
+#define VXGE_HW_GCMG3_INT_STATUS_GHSQ_ERR_GH2L1_INT vxge_mBIT(3)
+#define VXGE_HW_GCMG3_INT_STATUS_GHSQ_ERR2_GH2L2_INT vxge_mBIT(4)
+#define VXGE_HW_GCMG3_INT_STATUS_GH2L_SMERR0_GH2L3_INT vxge_mBIT(5)
+#define VXGE_HW_GCMG3_INT_STATUS_GHSQ_ERR3_GH2L4_INT vxge_mBIT(6)
+/*0x08008*/ u64 gcmg3_int_mask;
+ u8 unused09000[0x09000-0x8010];
+
+/*0x09000*/ u64 g3ifcmd_fb_int_status;
+#define VXGE_HW_G3IFCMD_FB_INT_STATUS_ERR_G3IF_INT vxge_mBIT(0)
+/*0x09008*/ u64 g3ifcmd_fb_int_mask;
+/*0x09010*/ u64 g3ifcmd_fb_err_reg;
+#define VXGE_HW_G3IFCMD_FB_ERR_REG_G3IF_CK_DLL_LOCK vxge_mBIT(6)
+#define VXGE_HW_G3IFCMD_FB_ERR_REG_G3IF_SM_ERR vxge_mBIT(7)
+#define VXGE_HW_G3IFCMD_FB_ERR_REG_G3IF_RWDQS_DLL_LOCK(val) \
+ vxge_vBIT(val, 24, 8)
+#define VXGE_HW_G3IFCMD_FB_ERR_REG_G3IF_IOCAL_FAULT vxge_mBIT(55)
+/*0x09018*/ u64 g3ifcmd_fb_err_mask;
+/*0x09020*/ u64 g3ifcmd_fb_err_alarm;
+
+ u8 unused09400[0x09400-0x09028];
+
+/*0x09400*/ u64 g3ifcmd_cmu_int_status;
+#define VXGE_HW_G3IFCMD_CMU_INT_STATUS_ERR_G3IF_INT vxge_mBIT(0)
+/*0x09408*/ u64 g3ifcmd_cmu_int_mask;
+/*0x09410*/ u64 g3ifcmd_cmu_err_reg;
+#define VXGE_HW_G3IFCMD_CMU_ERR_REG_G3IF_CK_DLL_LOCK vxge_mBIT(6)
+#define VXGE_HW_G3IFCMD_CMU_ERR_REG_G3IF_SM_ERR vxge_mBIT(7)
+#define VXGE_HW_G3IFCMD_CMU_ERR_REG_G3IF_RWDQS_DLL_LOCK(val) \
+ vxge_vBIT(val, 24, 8)
+#define VXGE_HW_G3IFCMD_CMU_ERR_REG_G3IF_IOCAL_FAULT vxge_mBIT(55)
+/*0x09418*/ u64 g3ifcmd_cmu_err_mask;
+/*0x09420*/ u64 g3ifcmd_cmu_err_alarm;
+
+ u8 unused09800[0x09800-0x09428];
+
+/*0x09800*/ u64 g3ifcmd_cml_int_status;
+#define VXGE_HW_G3IFCMD_CML_INT_STATUS_ERR_G3IF_INT vxge_mBIT(0)
+/*0x09808*/ u64 g3ifcmd_cml_int_mask;
+/*0x09810*/ u64 g3ifcmd_cml_err_reg;
+#define VXGE_HW_G3IFCMD_CML_ERR_REG_G3IF_CK_DLL_LOCK vxge_mBIT(6)
+#define VXGE_HW_G3IFCMD_CML_ERR_REG_G3IF_SM_ERR vxge_mBIT(7)
+#define VXGE_HW_G3IFCMD_CML_ERR_REG_G3IF_RWDQS_DLL_LOCK(val) \
+ vxge_vBIT(val, 24, 8)
+#define VXGE_HW_G3IFCMD_CML_ERR_REG_G3IF_IOCAL_FAULT vxge_mBIT(55)
+/*0x09818*/ u64 g3ifcmd_cml_err_mask;
+/*0x09820*/ u64 g3ifcmd_cml_err_alarm;
+ u8 unused09b00[0x09b00-0x09828];
+
+/*0x09b00*/ u64 vpath_to_vplane_map[17];
+#define VXGE_HW_VPATH_TO_VPLANE_MAP_VPATH_TO_VPLANE_MAP(val) \
+ vxge_vBIT(val, 3, 5)
+ u8 unused09c30[0x09c30-0x09b88];
+
+/*0x09c30*/ u64 xgxs_cfg_port[2];
+#define VXGE_HW_XGXS_CFG_PORT_SIG_DETECT_FORCE_LOS(val) vxge_vBIT(val, 16, 4)
+#define VXGE_HW_XGXS_CFG_PORT_SIG_DETECT_FORCE_VALID(val) vxge_vBIT(val, 20, 4)
+#define VXGE_HW_XGXS_CFG_PORT_SEL_INFO_0 vxge_mBIT(27)
+#define VXGE_HW_XGXS_CFG_PORT_SEL_INFO_1(val) vxge_vBIT(val, 29, 3)
+#define VXGE_HW_XGXS_CFG_PORT_TX_LANE0_SKEW(val) vxge_vBIT(val, 32, 4)
+#define VXGE_HW_XGXS_CFG_PORT_TX_LANE1_SKEW(val) vxge_vBIT(val, 36, 4)
+#define VXGE_HW_XGXS_CFG_PORT_TX_LANE2_SKEW(val) vxge_vBIT(val, 40, 4)
+#define VXGE_HW_XGXS_CFG_PORT_TX_LANE3_SKEW(val) vxge_vBIT(val, 44, 4)
+/*0x09c40*/ u64 xgxs_rxber_cfg_port[2];
+#define VXGE_HW_XGXS_RXBER_CFG_PORT_INTERVAL_DUR(val) vxge_vBIT(val, 0, 4)
+#define VXGE_HW_XGXS_RXBER_CFG_PORT_RXGXS_INTERVAL_CNT(val) \
+ vxge_vBIT(val, 16, 48)
+/*0x09c50*/ u64 xgxs_rxber_status_port[2];
+#define VXGE_HW_XGXS_RXBER_STATUS_PORT_RXGXS_RXGXS_LANE_A_ERR_CNT(val) \
+ vxge_vBIT(val, 0, 16)
+#define VXGE_HW_XGXS_RXBER_STATUS_PORT_RXGXS_RXGXS_LANE_B_ERR_CNT(val) \
+ vxge_vBIT(val, 16, 16)
+#define VXGE_HW_XGXS_RXBER_STATUS_PORT_RXGXS_RXGXS_LANE_C_ERR_CNT(val) \
+ vxge_vBIT(val, 32, 16)
+#define VXGE_HW_XGXS_RXBER_STATUS_PORT_RXGXS_RXGXS_LANE_D_ERR_CNT(val) \
+ vxge_vBIT(val, 48, 16)
+/*0x09c60*/ u64 xgxs_status_port[2];
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_TX_ACTIVITY(val) vxge_vBIT(val, 0, 4)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_RX_ACTIVITY(val) vxge_vBIT(val, 4, 4)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_CTC_FIFO_ERR BIT(11)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_BYTE_SYNC_LOST(val) \
+ vxge_vBIT(val, 12, 4)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_CTC_ERR(val) vxge_vBIT(val, 16, 4)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_ALIGNMENT_ERR vxge_mBIT(23)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_DEC_ERR(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_SKIP_INS_REQ(val) \
+ vxge_vBIT(val, 32, 4)
+#define VXGE_HW_XGXS_STATUS_PORT_XMACJ_PCS_SKIP_DEL_REQ(val) \
+ vxge_vBIT(val, 36, 4)
+/*0x09c70*/ u64 xgxs_pma_reset_port[2];
+#define VXGE_HW_XGXS_PMA_RESET_PORT_SERDES_RESET(val) vxge_vBIT(val, 0, 8)
+ u8 unused09c90[0x09c90-0x09c80];
+
+/*0x09c90*/ u64 xgxs_static_cfg_port[2];
+#define VXGE_HW_XGXS_STATIC_CFG_PORT_FW_CTRL_SERDES vxge_mBIT(3)
+ u8 unused09d40[0x09d40-0x09ca0];
+
+/*0x09d40*/ u64 xgxs_info_port[2];
+#define VXGE_HW_XGXS_INFO_PORT_XMACJ_INFO_0(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_XGXS_INFO_PORT_XMACJ_INFO_1(val) vxge_vBIT(val, 32, 32)
+/*0x09d50*/ u64 ratemgmt_cfg_port[2];
+#define VXGE_HW_RATEMGMT_CFG_PORT_MODE(val) vxge_vBIT(val, 2, 2)
+#define VXGE_HW_RATEMGMT_CFG_PORT_RATE vxge_mBIT(7)
+#define VXGE_HW_RATEMGMT_CFG_PORT_FIXED_USE_FSM vxge_mBIT(11)
+#define VXGE_HW_RATEMGMT_CFG_PORT_ANTP_USE_FSM vxge_mBIT(15)
+#define VXGE_HW_RATEMGMT_CFG_PORT_ANBE_USE_FSM vxge_mBIT(19)
+/*0x09d60*/ u64 ratemgmt_status_port[2];
+#define VXGE_HW_RATEMGMT_STATUS_PORT_RATEMGMT_COMPLETE vxge_mBIT(3)
+#define VXGE_HW_RATEMGMT_STATUS_PORT_RATEMGMT_RATE vxge_mBIT(7)
+#define VXGE_HW_RATEMGMT_STATUS_PORT_RATEMGMT_MAC_MATCHES_PHY vxge_mBIT(11)
+ u8 unused09d80[0x09d80-0x09d70];
+
+/*0x09d80*/ u64 ratemgmt_fixed_cfg_port[2];
+#define VXGE_HW_RATEMGMT_FIXED_CFG_PORT_RESTART vxge_mBIT(7)
+/*0x09d90*/ u64 ratemgmt_antp_cfg_port[2];
+#define VXGE_HW_RATEMGMT_ANTP_CFG_PORT_RESTART vxge_mBIT(7)
+#define VXGE_HW_RATEMGMT_ANTP_CFG_PORT_USE_PREAMBLE_EXT_PHY vxge_mBIT(11)
+#define VXGE_HW_RATEMGMT_ANTP_CFG_PORT_USE_ACT_SEL vxge_mBIT(15)
+#define VXGE_HW_RATEMGMT_ANTP_CFG_PORT_T_RETRY_PHY_QUERY(val) \
+ vxge_vBIT(val, 16, 4)
+#define VXGE_HW_RATEMGMT_ANTP_CFG_PORT_T_WAIT_MDIO_RESPONSE(val) \
+ vxge_vBIT(val, 20, 4)
+#define VXGE_HW_RATEMGMT_ANTP_CFG_PORT_T_LDOWN_REAUTO_RESPONSE(val) \
+ vxge_vBIT(val, 24, 4)
+#define VXGE_HW_RATEMGMT_ANTP_CFG_PORT_ADVERTISE_10G vxge_mBIT(31)
+#define VXGE_HW_RATEMGMT_ANTP_CFG_PORT_ADVERTISE_1G vxge_mBIT(35)
+/*0x09da0*/ u64 ratemgmt_anbe_cfg_port[2];
+#define VXGE_HW_RATEMGMT_ANBE_CFG_PORT_RESTART vxge_mBIT(7)
+#define VXGE_HW_RATEMGMT_ANBE_CFG_PORT_PARALLEL_DETECT_10G_KX4_ENABLE \
+ vxge_mBIT(11)
+#define VXGE_HW_RATEMGMT_ANBE_CFG_PORT_PARALLEL_DETECT_1G_KX_ENABLE \
+ vxge_mBIT(15)
+#define VXGE_HW_RATEMGMT_ANBE_CFG_PORT_T_SYNC_10G_KX4(val) vxge_vBIT(val, 16, 4)
+#define VXGE_HW_RATEMGMT_ANBE_CFG_PORT_T_SYNC_1G_KX(val) vxge_vBIT(val, 20, 4)
+#define VXGE_HW_RATEMGMT_ANBE_CFG_PORT_T_DME_EXCHANGE(val) vxge_vBIT(val, 24, 4)
+#define VXGE_HW_RATEMGMT_ANBE_CFG_PORT_ADVERTISE_10G_KX4 vxge_mBIT(31)
+#define VXGE_HW_RATEMGMT_ANBE_CFG_PORT_ADVERTISE_1G_KX vxge_mBIT(35)
+/*0x09db0*/ u64 anbe_cfg_port[2];
+#define VXGE_HW_ANBE_CFG_PORT_RESET_CFG_REGS(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_ANBE_CFG_PORT_ALIGN_10G_KX4_OVERRIDE(val) vxge_vBIT(val, 10, 2)
+#define VXGE_HW_ANBE_CFG_PORT_SYNC_1G_KX_OVERRIDE(val) vxge_vBIT(val, 14, 2)
+/*0x09dc0*/ u64 anbe_mgr_ctrl_port[2];
+#define VXGE_HW_ANBE_MGR_CTRL_PORT_WE vxge_mBIT(3)
+#define VXGE_HW_ANBE_MGR_CTRL_PORT_STROBE vxge_mBIT(7)
+#define VXGE_HW_ANBE_MGR_CTRL_PORT_ADDR(val) vxge_vBIT(val, 15, 9)
+#define VXGE_HW_ANBE_MGR_CTRL_PORT_DATA(val) vxge_vBIT(val, 32, 32)
+ u8 unused09de0[0x09de0-0x09dd0];
+
+/*0x09de0*/ u64 anbe_fw_mstr_port[2];
+#define VXGE_HW_ANBE_FW_MSTR_PORT_CONNECT_BEAN_TO_SERDES vxge_mBIT(3)
+#define VXGE_HW_ANBE_FW_MSTR_PORT_TX_ZEROES_TO_SERDES vxge_mBIT(7)
+/*0x09df0*/ u64 anbe_hwfsm_gen_status_port[2];
+#define VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_CHOSE_10G_KX4_USING_PD \
+ vxge_mBIT(3)
+#define VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_CHOSE_10G_KX4_USING_DME \
+ vxge_mBIT(7)
+#define VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_CHOSE_1G_KX_USING_PD \
+ vxge_mBIT(11)
+#define VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_CHOSE_1G_KX_USING_DME \
+ vxge_mBIT(15)
+#define VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_ANBEFSM_STATE(val) \
+ vxge_vBIT(val, 18, 6)
+#define VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_BEAN_NEXT_PAGE_RECEIVED \
+ vxge_mBIT(27)
+#define VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_BEAN_BASE_PAGE_RECEIVED \
+ vxge_mBIT(35)
+#define VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_BEAN_AUTONEG_COMPLETE \
+ vxge_mBIT(39)
+#define VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_NP_BEFORE_BP \
+ vxge_mBIT(43)
+#define \
+VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_AN_COMPLETE_BEFORE_BP \
+ vxge_mBIT(47)
+#define \
+VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_AN_COMPLETE_BEFORE_NP \
+vxge_mBIT(51)
+#define \
+VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_MODE_WHEN_AN_COMPLETE \
+ vxge_mBIT(55)
+#define VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_COUNT_BP(val) \
+ vxge_vBIT(val, 56, 4)
+#define VXGE_HW_ANBE_HWFSM_GEN_STATUS_PORT_RATEMGMT_COUNT_NP(val) \
+ vxge_vBIT(val, 60, 4)
+/*0x09e00*/ u64 anbe_hwfsm_bp_status_port[2];
+#define VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_FEC_ENABLE \
+ vxge_mBIT(32)
+#define VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_FEC_ABILITY \
+ vxge_mBIT(33)
+#define VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_10G_KR_CAPABLE \
+ vxge_mBIT(40)
+#define VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_10G_KX4_CAPABLE \
+ vxge_mBIT(41)
+#define VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_1G_KX_CAPABLE \
+ vxge_mBIT(42)
+#define VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_TX_NONCE(val) \
+ vxge_vBIT(val, 43, 5)
+#define VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_NP vxge_mBIT(48)
+#define VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_ACK vxge_mBIT(49)
+#define VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_REMOTE_FAULT \
+ vxge_mBIT(50)
+#define VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_ASM_DIR vxge_mBIT(51)
+#define VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_PAUSE vxge_mBIT(53)
+#define VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_ECHOED_NONCE(val) \
+ vxge_vBIT(val, 54, 5)
+#define VXGE_HW_ANBE_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_SELECTOR_FIELD(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x09e10*/ u64 anbe_hwfsm_np_status_port[2];
+#define VXGE_HW_ANBE_HWFSM_NP_STATUS_PORT_RATEMGMT_NP_BITS_47_TO_32(val) \
+ vxge_vBIT(val, 16, 16)
+#define VXGE_HW_ANBE_HWFSM_NP_STATUS_PORT_RATEMGMT_NP_BITS_31_TO_0(val) \
+ vxge_vBIT(val, 32, 32)
+ u8 unused09e30[0x09e30-0x09e20];
+
+/*0x09e30*/ u64 antp_gen_cfg_port[2];
+/*0x09e40*/ u64 antp_hwfsm_gen_status_port[2];
+#define VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_CHOSE_10G vxge_mBIT(3)
+#define VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_CHOSE_1G vxge_mBIT(7)
+#define VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_ANTPFSM_STATE(val) \
+ vxge_vBIT(val, 10, 6)
+#define VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_AUTONEG_COMPLETE \
+ vxge_mBIT(23)
+#define VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_NO_LP_XNP \
+ vxge_mBIT(27)
+#define VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_GOT_LP_XNP vxge_mBIT(31)
+#define VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_MESSAGE_CODE \
+ vxge_mBIT(35)
+#define VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_NO_HCD \
+ vxge_mBIT(43)
+#define VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_FOUND_HCD vxge_mBIT(47)
+#define VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_UNEXPECTED_INVALID_RATE \
+ vxge_mBIT(51)
+#define VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_VALID_RATE vxge_mBIT(55)
+#define VXGE_HW_ANTP_HWFSM_GEN_STATUS_PORT_RATEMGMT_PERSISTENT_LDOWN \
+ vxge_mBIT(59)
+/*0x09e50*/ u64 antp_hwfsm_bp_status_port[2];
+#define VXGE_HW_ANTP_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_NP vxge_mBIT(0)
+#define VXGE_HW_ANTP_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_ACK vxge_mBIT(1)
+#define VXGE_HW_ANTP_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_RF vxge_mBIT(2)
+#define VXGE_HW_ANTP_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_XNP vxge_mBIT(3)
+#define VXGE_HW_ANTP_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_ABILITY_FIELD(val) \
+ vxge_vBIT(val, 4, 7)
+#define VXGE_HW_ANTP_HWFSM_BP_STATUS_PORT_RATEMGMT_BP_SELECTOR_FIELD(val) \
+ vxge_vBIT(val, 11, 5)
+/*0x09e60*/ u64 antp_hwfsm_xnp_status_port[2];
+#define VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_NP vxge_mBIT(0)
+#define VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_ACK vxge_mBIT(1)
+#define VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_MP vxge_mBIT(2)
+#define VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_ACK2 vxge_mBIT(3)
+#define VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_TOGGLE vxge_mBIT(4)
+#define VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_MESSAGE_CODE(val) \
+ vxge_vBIT(val, 5, 11)
+#define VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_UNF_CODE_FIELD1(val) \
+ vxge_vBIT(val, 16, 16)
+#define VXGE_HW_ANTP_HWFSM_XNP_STATUS_PORT_RATEMGMT_XNP_UNF_CODE_FIELD2(val) \
+ vxge_vBIT(val, 32, 16)
+/*0x09e70*/ u64 mdio_mgr_access_port[2];
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_STROBE_ONE BIT(3)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_OP_TYPE(val) vxge_vBIT(val, 5, 3)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_DEVAD(val) vxge_vBIT(val, 11, 5)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_ADDR(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_DATA(val) vxge_vBIT(val, 32, 16)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_ST_PATTERN(val) vxge_vBIT(val, 49, 2)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_PREAMBLE vxge_mBIT(51)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_PRTAD(val) vxge_vBIT(val, 55, 5)
+#define VXGE_HW_MDIO_MGR_ACCESS_PORT_STROBE_TWO vxge_mBIT(63)
+ u8 unused0a200[0x0a200-0x09e80];
+/*0x0a200*/ u64 xmac_vsport_choices_vh[17];
+#define VXGE_HW_XMAC_VSPORT_CHOICES_VH_VSPORT_VECTOR(val) vxge_vBIT(val, 0, 17)
+ u8 unused0a400[0x0a400-0x0a288];
+
+/*0x0a400*/ u64 rx_thresh_cfg_vp[17];
+#define VXGE_HW_RX_THRESH_CFG_VP_PAUSE_LOW_THR(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_RX_THRESH_CFG_VP_PAUSE_HIGH_THR(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_RX_THRESH_CFG_VP_RED_THR_0(val) vxge_vBIT(val, 16, 8)
+#define VXGE_HW_RX_THRESH_CFG_VP_RED_THR_1(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_RX_THRESH_CFG_VP_RED_THR_2(val) vxge_vBIT(val, 32, 8)
+#define VXGE_HW_RX_THRESH_CFG_VP_RED_THR_3(val) vxge_vBIT(val, 40, 8)
+ u8 unused0ac90[0x0ac90-0x0a488];
+} __packed;
+
+/*VXGE_HW_SRPCIM_REGS_H*/
+struct vxge_hw_srpcim_reg {
+
+/*0x00000*/ u64 tim_mr2sr_resource_assignment_vh;
+#define VXGE_HW_TIM_MR2SR_RESOURCE_ASSIGNMENT_VH_BMAP_ROOT(val) \
+ vxge_vBIT(val, 0, 32)
+ u8 unused00100[0x00100-0x00008];
+
+/*0x00100*/ u64 srpcim_pcipif_int_status;
+#define VXGE_HW_SRPCIM_PCIPIF_INT_STATUS_MRPCIM_MSG_MRPCIM_MSG_INT BIT(3)
+#define VXGE_HW_SRPCIM_PCIPIF_INT_STATUS_VPATH_MSG_VPATH_MSG_INT BIT(7)
+#define VXGE_HW_SRPCIM_PCIPIF_INT_STATUS_SRPCIM_SPARE_R1_SRPCIM_SPARE_R1_INT \
+ BIT(11)
+/*0x00108*/ u64 srpcim_pcipif_int_mask;
+/*0x00110*/ u64 mrpcim_msg_reg;
+#define VXGE_HW_MRPCIM_MSG_REG_SWIF_MRPCIM_TO_SRPCIM_RMSG_INT BIT(3)
+/*0x00118*/ u64 mrpcim_msg_mask;
+/*0x00120*/ u64 mrpcim_msg_alarm;
+/*0x00128*/ u64 vpath_msg_reg;
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH0_TO_SRPCIM_RMSG_INT BIT(0)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH1_TO_SRPCIM_RMSG_INT BIT(1)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH2_TO_SRPCIM_RMSG_INT BIT(2)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH3_TO_SRPCIM_RMSG_INT BIT(3)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH4_TO_SRPCIM_RMSG_INT BIT(4)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH5_TO_SRPCIM_RMSG_INT BIT(5)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH6_TO_SRPCIM_RMSG_INT BIT(6)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH7_TO_SRPCIM_RMSG_INT BIT(7)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH8_TO_SRPCIM_RMSG_INT BIT(8)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH9_TO_SRPCIM_RMSG_INT BIT(9)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH10_TO_SRPCIM_RMSG_INT BIT(10)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH11_TO_SRPCIM_RMSG_INT BIT(11)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH12_TO_SRPCIM_RMSG_INT BIT(12)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH13_TO_SRPCIM_RMSG_INT BIT(13)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH14_TO_SRPCIM_RMSG_INT BIT(14)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH15_TO_SRPCIM_RMSG_INT BIT(15)
+#define VXGE_HW_VPATH_MSG_REG_SWIF_VPATH16_TO_SRPCIM_RMSG_INT BIT(16)
+/*0x00130*/ u64 vpath_msg_mask;
+/*0x00138*/ u64 vpath_msg_alarm;
+ u8 unused00160[0x00160-0x00140];
+
+/*0x00160*/ u64 srpcim_to_mrpcim_wmsg;
+#define VXGE_HW_SRPCIM_TO_MRPCIM_WMSG_SRPCIM_TO_MRPCIM_WMSG(val) \
+ vxge_vBIT(val, 0, 64)
+/*0x00168*/ u64 srpcim_to_mrpcim_wmsg_trig;
+#define VXGE_HW_SRPCIM_TO_MRPCIM_WMSG_TRIG_SRPCIM_TO_MRPCIM_WMSG_TRIG BIT(0)
+/*0x00170*/ u64 mrpcim_to_srpcim_rmsg;
+#define VXGE_HW_MRPCIM_TO_SRPCIM_RMSG_SWIF_MRPCIM_TO_SRPCIM_RMSG(val) \
+ vxge_vBIT(val, 0, 64)
+/*0x00178*/ u64 vpath_to_srpcim_rmsg_sel;
+#define VXGE_HW_VPATH_TO_SRPCIM_RMSG_SEL_VPATH_TO_SRPCIM_RMSG_SEL(val) \
+ vxge_vBIT(val, 0, 5)
+/*0x00180*/ u64 vpath_to_srpcim_rmsg;
+#define VXGE_HW_VPATH_TO_SRPCIM_RMSG_SWIF_VPATH_TO_SRPCIM_RMSG(val) \
+ vxge_vBIT(val, 0, 64)
+ u8 unused00200[0x00200-0x00188];
+
+/*0x00200*/ u64 srpcim_general_int_status;
+#define VXGE_HW_SRPCIM_GENERAL_INT_STATUS_PIC_INT BIT(0)
+#define VXGE_HW_SRPCIM_GENERAL_INT_STATUS_PCI_INT BIT(3)
+#define VXGE_HW_SRPCIM_GENERAL_INT_STATUS_XMAC_INT BIT(7)
+ u8 unused00210[0x00210-0x00208];
+
+/*0x00210*/ u64 srpcim_general_int_mask;
+#define VXGE_HW_SRPCIM_GENERAL_INT_MASK_PIC_INT BIT(0)
+#define VXGE_HW_SRPCIM_GENERAL_INT_MASK_PCI_INT BIT(3)
+#define VXGE_HW_SRPCIM_GENERAL_INT_MASK_XMAC_INT BIT(7)
+ u8 unused00220[0x00220-0x00218];
+
+/*0x00220*/ u64 srpcim_ppif_int_status;
+
+/*0x00228*/ u64 srpcim_ppif_int_mask;
+/*0x00230*/ u64 srpcim_gen_errors_reg;
+#define VXGE_HW_SRPCIM_GEN_ERRORS_REG_PCICONFIG_PF_STATUS_ERR BIT(3)
+#define VXGE_HW_SRPCIM_GEN_ERRORS_REG_PCICONFIG_PF_UNCOR_ERR BIT(7)
+#define VXGE_HW_SRPCIM_GEN_ERRORS_REG_PCICONFIG_PF_COR_ERR BIT(11)
+#define VXGE_HW_SRPCIM_GEN_ERRORS_REG_INTCTRL_SCHED_INT BIT(15)
+#define VXGE_HW_SRPCIM_GEN_ERRORS_REG_INI_SERR_DET BIT(19)
+#define VXGE_HW_SRPCIM_GEN_ERRORS_REG_TGT_PF_ILLEGAL_ACCESS BIT(23)
+/*0x00238*/ u64 srpcim_gen_errors_mask;
+/*0x00240*/ u64 srpcim_gen_errors_alarm;
+/*0x00248*/ u64 mrpcim_to_srpcim_alarm_reg;
+#define VXGE_HW_MRPCIM_TO_SRPCIM_ALARM_REG_PPIF_MRPCIM_TO_SRPCIM_ALARM BIT(3)
+/*0x00250*/ u64 mrpcim_to_srpcim_alarm_mask;
+/*0x00258*/ u64 mrpcim_to_srpcim_alarm_alarm;
+/*0x00260*/ u64 vpath_to_srpcim_alarm_reg;
+
+/*0x00268*/ u64 vpath_to_srpcim_alarm_mask;
+/*0x00270*/ u64 vpath_to_srpcim_alarm_alarm;
+ u8 unused00280[0x00280-0x00278];
+
+/*0x00280*/ u64 pf_sw_reset;
+#define VXGE_HW_PF_SW_RESET_PF_SW_RESET(val) vxge_vBIT(val, 0, 8)
+/*0x00288*/ u64 srpcim_general_cfg1;
+#define VXGE_HW_SRPCIM_GENERAL_CFG1_BOOT_BYTE_SWAPEN BIT(19)
+#define VXGE_HW_SRPCIM_GENERAL_CFG1_BOOT_BIT_FLIPEN BIT(23)
+#define VXGE_HW_SRPCIM_GENERAL_CFG1_MSIX_ADDR_SWAPEN BIT(27)
+#define VXGE_HW_SRPCIM_GENERAL_CFG1_MSIX_ADDR_FLIPEN BIT(31)
+#define VXGE_HW_SRPCIM_GENERAL_CFG1_MSIX_DATA_SWAPEN BIT(35)
+#define VXGE_HW_SRPCIM_GENERAL_CFG1_MSIX_DATA_FLIPEN BIT(39)
+/*0x00290*/ u64 srpcim_interrupt_cfg1;
+#define VXGE_HW_SRPCIM_INTERRUPT_CFG1_ALARM_MAP_TO_MSG(val) vxge_vBIT(val, 1, 7)
+#define VXGE_HW_SRPCIM_INTERRUPT_CFG1_TRAFFIC_CLASS(val) vxge_vBIT(val, 9, 3)
+ u8 unused002a8[0x002a8-0x00298];
+
+/*0x002a8*/ u64 srpcim_clear_msix_mask;
+#define VXGE_HW_SRPCIM_CLEAR_MSIX_MASK_SRPCIM_CLEAR_MSIX_MASK BIT(0)
+/*0x002b0*/ u64 srpcim_set_msix_mask;
+#define VXGE_HW_SRPCIM_SET_MSIX_MASK_SRPCIM_SET_MSIX_MASK BIT(0)
+/*0x002b8*/ u64 srpcim_clr_msix_one_shot;
+#define VXGE_HW_SRPCIM_CLR_MSIX_ONE_SHOT_SRPCIM_CLR_MSIX_ONE_SHOT BIT(0)
+/*0x002c0*/ u64 srpcim_rst_in_prog;
+#define VXGE_HW_SRPCIM_RST_IN_PROG_SRPCIM_RST_IN_PROG BIT(7)
+/*0x002c8*/ u64 srpcim_reg_modified;
+#define VXGE_HW_SRPCIM_REG_MODIFIED_SRPCIM_REG_MODIFIED BIT(7)
+/*0x002d0*/ u64 tgt_pf_illegal_access;
+#define VXGE_HW_TGT_PF_ILLEGAL_ACCESS_SWIF_REGION(val) vxge_vBIT(val, 1, 7)
+/*0x002d8*/ u64 srpcim_msix_status;
+#define VXGE_HW_SRPCIM_MSIX_STATUS_INTCTL_SRPCIM_MSIX_MASK BIT(3)
+#define VXGE_HW_SRPCIM_MSIX_STATUS_INTCTL_SRPCIM_MSIX_PENDING_VECTOR BIT(7)
+ u8 unused00880[0x00880-0x002e0];
+
+/*0x00880*/ u64 xgmac_sr_int_status;
+#define VXGE_HW_XGMAC_SR_INT_STATUS_ASIC_NTWK_SR_ERR_ASIC_NTWK_SR_INT BIT(3)
+/*0x00888*/ u64 xgmac_sr_int_mask;
+/*0x00890*/ u64 asic_ntwk_sr_err_reg;
+#define VXGE_HW_ASIC_NTWK_SR_ERR_REG_XMACJ_NTWK_SUSTAINED_FAULT BIT(3)
+#define VXGE_HW_ASIC_NTWK_SR_ERR_REG_XMACJ_NTWK_SUSTAINED_OK BIT(7)
+#define VXGE_HW_ASIC_NTWK_SR_ERR_REG_XMACJ_NTWK_SUSTAINED_FAULT_OCCURRED \
+ BIT(11)
+#define VXGE_HW_ASIC_NTWK_SR_ERR_REG_XMACJ_NTWK_SUSTAINED_OK_OCCURRED BIT(15)
+/*0x00898*/ u64 asic_ntwk_sr_err_mask;
+/*0x008a0*/ u64 asic_ntwk_sr_err_alarm;
+ u8 unused008c0[0x008c0-0x008a8];
+
+/*0x008c0*/ u64 xmac_vsport_choices_sr_clone;
+#define VXGE_HW_XMAC_VSPORT_CHOICES_SR_CLONE_VSPORT_VECTOR(val) \
+ vxge_vBIT(val, 0, 17)
+ u8 unused00900[0x00900-0x008c8];
+
+/*0x00900*/ u64 mr_rqa_top_prty_for_vh;
+#define VXGE_HW_MR_RQA_TOP_PRTY_FOR_VH_RQA_TOP_PRTY_FOR_VH(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00908*/ u64 umq_vh_data_list_empty;
+#define VXGE_HW_UMQ_VH_DATA_LIST_EMPTY_ROCRC_UMQ_VH_DATA_LIST_EMPTY \
+ BIT(0)
+/*0x00910*/ u64 wde_cfg;
+#define VXGE_HW_WDE_CFG_NS0_FORCE_MWB_START BIT(0)
+#define VXGE_HW_WDE_CFG_NS0_FORCE_MWB_END BIT(1)
+#define VXGE_HW_WDE_CFG_NS0_FORCE_QB_START BIT(2)
+#define VXGE_HW_WDE_CFG_NS0_FORCE_QB_END BIT(3)
+#define VXGE_HW_WDE_CFG_NS0_FORCE_MPSB_START BIT(4)
+#define VXGE_HW_WDE_CFG_NS0_FORCE_MPSB_END BIT(5)
+#define VXGE_HW_WDE_CFG_NS0_MWB_OPT_EN BIT(6)
+#define VXGE_HW_WDE_CFG_NS0_QB_OPT_EN BIT(7)
+#define VXGE_HW_WDE_CFG_NS0_MPSB_OPT_EN BIT(8)
+#define VXGE_HW_WDE_CFG_NS1_FORCE_MWB_START BIT(9)
+#define VXGE_HW_WDE_CFG_NS1_FORCE_MWB_END BIT(10)
+#define VXGE_HW_WDE_CFG_NS1_FORCE_QB_START BIT(11)
+#define VXGE_HW_WDE_CFG_NS1_FORCE_QB_END BIT(12)
+#define VXGE_HW_WDE_CFG_NS1_FORCE_MPSB_START BIT(13)
+#define VXGE_HW_WDE_CFG_NS1_FORCE_MPSB_END BIT(14)
+#define VXGE_HW_WDE_CFG_NS1_MWB_OPT_EN BIT(15)
+#define VXGE_HW_WDE_CFG_NS1_QB_OPT_EN BIT(16)
+#define VXGE_HW_WDE_CFG_NS1_MPSB_OPT_EN BIT(17)
+#define VXGE_HW_WDE_CFG_DISABLE_QPAD_FOR_UNALIGNED_ADDR BIT(19)
+#define VXGE_HW_WDE_CFG_ALIGNMENT_PREFERENCE(val) vxge_vBIT(val, 30, 2)
+#define VXGE_HW_WDE_CFG_MEM_WORD_SIZE(val) vxge_vBIT(val, 46, 2)
+
+} __packed;
+
+/*VXGE_HW_VPMGMT_REGS_H*/
+struct vxge_hw_vpmgmt_reg {
+
+ u8 unused00040[0x00040-0x00000];
+
+/*0x00040*/ u64 vpath_to_func_map_cfg1;
+#define VXGE_HW_VPATH_TO_FUNC_MAP_CFG1_VPATH_TO_FUNC_MAP_CFG1(val) \
+ vxge_vBIT(val, 3, 5)
+/*0x00048*/ u64 vpath_is_first;
+#define VXGE_HW_VPATH_IS_FIRST_VPATH_IS_FIRST vxge_mBIT(3)
+/*0x00050*/ u64 srpcim_to_vpath_wmsg;
+#define VXGE_HW_SRPCIM_TO_VPATH_WMSG_SRPCIM_TO_VPATH_WMSG(val) \
+ vxge_vBIT(val, 0, 64)
+/*0x00058*/ u64 srpcim_to_vpath_wmsg_trig;
+#define VXGE_HW_SRPCIM_TO_VPATH_WMSG_TRIG_SRPCIM_TO_VPATH_WMSG_TRIG \
+ vxge_mBIT(0)
+ u8 unused00100[0x00100-0x00060];
+
+/*0x00100*/ u64 tim_vpath_assignment;
+#define VXGE_HW_TIM_VPATH_ASSIGNMENT_BMAP_ROOT(val) vxge_vBIT(val, 0, 32)
+ u8 unused00140[0x00140-0x00108];
+
+/*0x00140*/ u64 rqa_top_prty_for_vp;
+#define VXGE_HW_RQA_TOP_PRTY_FOR_VP_RQA_TOP_PRTY_FOR_VP(val) \
+ vxge_vBIT(val, 59, 5)
+ u8 unused001c0[0x001c0-0x00148];
+
+/*0x001c0*/ u64 rxmac_rx_pa_cfg0_vpmgmt_clone;
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_IGNORE_FRAME_ERR vxge_mBIT(3)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_SUPPORT_SNAP_AB_N vxge_mBIT(7)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_SEARCH_FOR_HAO vxge_mBIT(18)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_SUPPORT_MOBILE_IPV6_HDRS \
+ vxge_mBIT(19)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_IPV6_STOP_SEARCHING \
+ vxge_mBIT(23)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_NO_PS_IF_UNKNOWN vxge_mBIT(27)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_SEARCH_FOR_ETYPE vxge_mBIT(35)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_TOSS_ANY_FRM_IF_L3_CSUM_ERR \
+ vxge_mBIT(39)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_TOSS_OFFLD_FRM_IF_L3_CSUM_ERR \
+ vxge_mBIT(43)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_TOSS_ANY_FRM_IF_L4_CSUM_ERR \
+ vxge_mBIT(47)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_TOSS_OFFLD_FRM_IF_L4_CSUM_ERR \
+ vxge_mBIT(51)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_TOSS_ANY_FRM_IF_RPA_ERR \
+ vxge_mBIT(55)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_TOSS_OFFLD_FRM_IF_RPA_ERR \
+ vxge_mBIT(59)
+#define VXGE_HW_RXMAC_RX_PA_CFG0_VPMGMT_CLONE_JUMBO_SNAP_EN vxge_mBIT(63)
+/*0x001c8*/ u64 rts_mgr_cfg0_vpmgmt_clone;
+#define VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_RTS_DP_SP_PRIORITY vxge_mBIT(3)
+#define VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_FLEX_L4PRTCL_VALUE(val) \
+ vxge_vBIT(val, 24, 8)
+#define VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_ICMP_TRASH vxge_mBIT(35)
+#define VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_TCPSYN_TRASH vxge_mBIT(39)
+#define VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_ZL4PYLD_TRASH vxge_mBIT(43)
+#define VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_L4PRTCL_TCP_TRASH vxge_mBIT(47)
+#define VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_L4PRTCL_UDP_TRASH vxge_mBIT(51)
+#define VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_L4PRTCL_FLEX_TRASH vxge_mBIT(55)
+#define VXGE_HW_RTS_MGR_CFG0_VPMGMT_CLONE_IPFRAG_TRASH vxge_mBIT(59)
+/*0x001d0*/ u64 rts_mgr_criteria_priority_vpmgmt_clone;
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_ETYPE(val) \
+ vxge_vBIT(val, 5, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_ICMP_TCPSYN(val) \
+ vxge_vBIT(val, 9, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_L4PN(val) \
+ vxge_vBIT(val, 13, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_RANGE_L4PN(val) \
+ vxge_vBIT(val, 17, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_RTH_IT(val) \
+ vxge_vBIT(val, 21, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_DS(val) \
+ vxge_vBIT(val, 25, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_QOS(val) \
+ vxge_vBIT(val, 29, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_ZL4PYLD(val) \
+ vxge_vBIT(val, 33, 3)
+#define VXGE_HW_RTS_MGR_CRITERIA_PRIORITY_VPMGMT_CLONE_L4PRTCL(val) \
+ vxge_vBIT(val, 37, 3)
+/*0x001d8*/ u64 rxmac_cfg0_port_vpmgmt_clone[3];
+#define VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_RMAC_EN vxge_mBIT(3)
+#define VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_STRIP_FCS vxge_mBIT(7)
+#define VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_DISCARD_PFRM vxge_mBIT(11)
+#define VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_IGNORE_FCS_ERR vxge_mBIT(15)
+#define VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_IGNORE_LONG_ERR vxge_mBIT(19)
+#define VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_IGNORE_USIZED_ERR vxge_mBIT(23)
+#define VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_IGNORE_LEN_MISMATCH \
+ vxge_mBIT(27)
+#define VXGE_HW_RXMAC_CFG0_PORT_VPMGMT_CLONE_MAX_PYLD_LEN(val) \
+ vxge_vBIT(val, 50, 14)
+/*0x001f0*/ u64 rxmac_pause_cfg_port_vpmgmt_clone[3];
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_GEN_EN vxge_mBIT(3)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_RCV_EN vxge_mBIT(7)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_ACCEL_SEND(val) \
+ vxge_vBIT(val, 9, 3)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_DUAL_THR vxge_mBIT(15)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_HIGH_PTIME(val) \
+ vxge_vBIT(val, 20, 16)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_IGNORE_PF_FCS_ERR \
+ vxge_mBIT(39)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_IGNORE_PF_LEN_ERR \
+ vxge_mBIT(43)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_LIMITER_EN vxge_mBIT(47)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_MAX_LIMIT(val) \
+ vxge_vBIT(val, 48, 8)
+#define VXGE_HW_RXMAC_PAUSE_CFG_PORT_VPMGMT_CLONE_PERMIT_RATEMGMT_CTRL \
+ vxge_mBIT(59)
+ u8 unused00240[0x00240-0x00208];
+
+/*0x00240*/ u64 xmac_vsport_choices_vp;
+#define VXGE_HW_XMAC_VSPORT_CHOICES_VP_VSPORT_VECTOR(val) vxge_vBIT(val, 0, 17)
+ u8 unused00260[0x00260-0x00248];
+
+/*0x00260*/ u64 xgmac_gen_status_vpmgmt_clone;
+#define VXGE_HW_XGMAC_GEN_STATUS_VPMGMT_CLONE_XMACJ_NTWK_OK vxge_mBIT(3)
+#define VXGE_HW_XGMAC_GEN_STATUS_VPMGMT_CLONE_XMACJ_NTWK_DATA_RATE \
+ vxge_mBIT(11)
+/*0x00268*/ u64 xgmac_status_port_vpmgmt_clone[2];
+#define VXGE_HW_XGMAC_STATUS_PORT_VPMGMT_CLONE_RMAC_REMOTE_FAULT \
+ vxge_mBIT(3)
+#define VXGE_HW_XGMAC_STATUS_PORT_VPMGMT_CLONE_RMAC_LOCAL_FAULT vxge_mBIT(7)
+#define VXGE_HW_XGMAC_STATUS_PORT_VPMGMT_CLONE_XMACJ_MAC_PHY_LAYER_AVAIL \
+ vxge_mBIT(11)
+#define VXGE_HW_XGMAC_STATUS_PORT_VPMGMT_CLONE_XMACJ_PORT_OK vxge_mBIT(15)
+/*0x00278*/ u64 xmac_gen_cfg_vpmgmt_clone;
+#define VXGE_HW_XMAC_GEN_CFG_VPMGMT_CLONE_RATEMGMT_MAC_RATE_SEL(val) \
+ vxge_vBIT(val, 2, 2)
+#define VXGE_HW_XMAC_GEN_CFG_VPMGMT_CLONE_TX_HEAD_DROP_WHEN_FAULT \
+ vxge_mBIT(7)
+#define VXGE_HW_XMAC_GEN_CFG_VPMGMT_CLONE_FAULT_BEHAVIOUR vxge_mBIT(27)
+#define VXGE_HW_XMAC_GEN_CFG_VPMGMT_CLONE_PERIOD_NTWK_UP(val) \
+ vxge_vBIT(val, 28, 4)
+#define VXGE_HW_XMAC_GEN_CFG_VPMGMT_CLONE_PERIOD_NTWK_DOWN(val) \
+ vxge_vBIT(val, 32, 4)
+/*0x00280*/ u64 xmac_timestamp_vpmgmt_clone;
+#define VXGE_HW_XMAC_TIMESTAMP_VPMGMT_CLONE_EN vxge_mBIT(3)
+#define VXGE_HW_XMAC_TIMESTAMP_VPMGMT_CLONE_USE_LINK_ID(val) \
+ vxge_vBIT(val, 6, 2)
+#define VXGE_HW_XMAC_TIMESTAMP_VPMGMT_CLONE_INTERVAL(val) vxge_vBIT(val, 12, 4)
+#define VXGE_HW_XMAC_TIMESTAMP_VPMGMT_CLONE_TIMER_RESTART vxge_mBIT(19)
+#define VXGE_HW_XMAC_TIMESTAMP_VPMGMT_CLONE_XMACJ_ROLLOVER_CNT(val) \
+ vxge_vBIT(val, 32, 16)
+/*0x00288*/ u64 xmac_stats_gen_cfg_vpmgmt_clone;
+#define VXGE_HW_XMAC_STATS_GEN_CFG_VPMGMT_CLONE_PRTAGGR_CUM_TIMER(val) \
+ vxge_vBIT(val, 4, 4)
+#define VXGE_HW_XMAC_STATS_GEN_CFG_VPMGMT_CLONE_VPATH_CUM_TIMER(val) \
+ vxge_vBIT(val, 8, 4)
+#define VXGE_HW_XMAC_STATS_GEN_CFG_VPMGMT_CLONE_VLAN_HANDLING vxge_mBIT(15)
+/*0x00290*/ u64 xmac_cfg_port_vpmgmt_clone[3];
+#define VXGE_HW_XMAC_CFG_PORT_VPMGMT_CLONE_XGMII_LOOPBACK vxge_mBIT(3)
+#define VXGE_HW_XMAC_CFG_PORT_VPMGMT_CLONE_XGMII_REVERSE_LOOPBACK \
+ vxge_mBIT(7)
+#define VXGE_HW_XMAC_CFG_PORT_VPMGMT_CLONE_XGMII_TX_BEHAV vxge_mBIT(11)
+#define VXGE_HW_XMAC_CFG_PORT_VPMGMT_CLONE_XGMII_RX_BEHAV vxge_mBIT(15)
+ u8 unused002c0[0x002c0-0x002a8];
+
+/*0x002c0*/ u64 txmac_gen_cfg0_vpmgmt_clone;
+#define VXGE_HW_TXMAC_GEN_CFG0_VPMGMT_CLONE_CHOSEN_TX_PORT vxge_mBIT(7)
+/*0x002c8*/ u64 txmac_cfg0_port_vpmgmt_clone[3];
+#define VXGE_HW_TXMAC_CFG0_PORT_VPMGMT_CLONE_TMAC_EN vxge_mBIT(3)
+#define VXGE_HW_TXMAC_CFG0_PORT_VPMGMT_CLONE_APPEND_PAD vxge_mBIT(7)
+#define VXGE_HW_TXMAC_CFG0_PORT_VPMGMT_CLONE_PAD_BYTE(val) vxge_vBIT(val, 8, 8)
+ u8 unused00300[0x00300-0x002e0];
+
+/*0x00300*/ u64 wol_mp_crc;
+#define VXGE_HW_WOL_MP_CRC_CRC(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_WOL_MP_CRC_RC_EN vxge_mBIT(63)
+/*0x00308*/ u64 wol_mp_mask_a;
+#define VXGE_HW_WOL_MP_MASK_A_MASK(val) vxge_vBIT(val, 0, 64)
+/*0x00310*/ u64 wol_mp_mask_b;
+#define VXGE_HW_WOL_MP_MASK_B_MASK(val) vxge_vBIT(val, 0, 64)
+ u8 unused00360[0x00360-0x00318];
+
+/*0x00360*/ u64 fau_pa_cfg_vpmgmt_clone;
+#define VXGE_HW_FAU_PA_CFG_VPMGMT_CLONE_REPL_L4_COMP_CSUM vxge_mBIT(3)
+#define VXGE_HW_FAU_PA_CFG_VPMGMT_CLONE_REPL_L3_INCL_CF vxge_mBIT(7)
+#define VXGE_HW_FAU_PA_CFG_VPMGMT_CLONE_REPL_L3_COMP_CSUM vxge_mBIT(11)
+/*0x00368*/ u64 rx_datapath_util_vp_clone;
+#define VXGE_HW_RX_DATAPATH_UTIL_VP_CLONE_FAU_RX_UTILIZATION(val) \
+ vxge_vBIT(val, 7, 9)
+#define VXGE_HW_RX_DATAPATH_UTIL_VP_CLONE_RX_UTIL_CFG(val) \
+ vxge_vBIT(val, 16, 4)
+#define VXGE_HW_RX_DATAPATH_UTIL_VP_CLONE_FAU_RX_FRAC_UTIL(val) \
+ vxge_vBIT(val, 20, 4)
+#define VXGE_HW_RX_DATAPATH_UTIL_VP_CLONE_RX_PKT_WEIGHT(val) \
+ vxge_vBIT(val, 24, 4)
+ u8 unused00380[0x00380-0x00370];
+
+/*0x00380*/ u64 tx_datapath_util_vp_clone;
+#define VXGE_HW_TX_DATAPATH_UTIL_VP_CLONE_TPA_TX_UTILIZATION(val) \
+ vxge_vBIT(val, 7, 9)
+#define VXGE_HW_TX_DATAPATH_UTIL_VP_CLONE_TX_UTIL_CFG(val) \
+ vxge_vBIT(val, 16, 4)
+#define VXGE_HW_TX_DATAPATH_UTIL_VP_CLONE_TPA_TX_FRAC_UTIL(val) \
+ vxge_vBIT(val, 20, 4)
+#define VXGE_HW_TX_DATAPATH_UTIL_VP_CLONE_TX_PKT_WEIGHT(val) \
+ vxge_vBIT(val, 24, 4)
+
+} __packed;
+
+struct vxge_hw_vpath_reg {
+
+ u8 unused00300[0x00300];
+
+/*0x00300*/ u64 usdc_vpath;
+#define VXGE_HW_USDC_VPATH_SGRP_ASSIGN(val) vxge_vBIT(val, 0, 32)
+ u8 unused00a00[0x00a00-0x00308];
+
+/*0x00a00*/ u64 wrdma_alarm_status;
+#define VXGE_HW_WRDMA_ALARM_STATUS_PRC_ALARM_PRC_INT vxge_mBIT(1)
+/*0x00a08*/ u64 wrdma_alarm_mask;
+ u8 unused00a30[0x00a30-0x00a10];
+
+/*0x00a30*/ u64 prc_alarm_reg;
+#define VXGE_HW_PRC_ALARM_REG_PRC_RING_BUMP vxge_mBIT(0)
+#define VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ERR vxge_mBIT(1)
+#define VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ABORT vxge_mBIT(2)
+#define VXGE_HW_PRC_ALARM_REG_PRC_QUANTA_SIZE_ERR vxge_mBIT(3)
+/*0x00a38*/ u64 prc_alarm_mask;
+/*0x00a40*/ u64 prc_alarm_alarm;
+/*0x00a48*/ u64 prc_cfg1;
+#define VXGE_HW_PRC_CFG1_RX_TIMER_VAL(val) vxge_vBIT(val, 3, 29)
+#define VXGE_HW_PRC_CFG1_TIM_RING_BUMP_INT_ENABLE vxge_mBIT(34)
+#define VXGE_HW_PRC_CFG1_RTI_TINT_DISABLE vxge_mBIT(35)
+#define VXGE_HW_PRC_CFG1_GREEDY_RETURN vxge_mBIT(36)
+#define VXGE_HW_PRC_CFG1_QUICK_SHOT vxge_mBIT(37)
+#define VXGE_HW_PRC_CFG1_RX_TIMER_CI vxge_mBIT(39)
+#define VXGE_HW_PRC_CFG1_RESET_TIMER_ON_RXD_RET(val) vxge_vBIT(val, 40, 2)
+ u8 unused00a60[0x00a60-0x00a50];
+
+/*0x00a60*/ u64 prc_cfg4;
+#define VXGE_HW_PRC_CFG4_IN_SVC vxge_mBIT(7)
+#define VXGE_HW_PRC_CFG4_RING_MODE(val) vxge_vBIT(val, 14, 2)
+#define VXGE_HW_PRC_CFG4_RXD_NO_SNOOP vxge_mBIT(22)
+#define VXGE_HW_PRC_CFG4_FRM_NO_SNOOP vxge_mBIT(23)
+#define VXGE_HW_PRC_CFG4_RTH_DISABLE vxge_mBIT(31)
+#define VXGE_HW_PRC_CFG4_IGNORE_OWNERSHIP vxge_mBIT(32)
+#define VXGE_HW_PRC_CFG4_SIGNAL_BENIGN_OVFLW vxge_mBIT(36)
+#define VXGE_HW_PRC_CFG4_BIMODAL_INTERRUPT vxge_mBIT(37)
+#define VXGE_HW_PRC_CFG4_BACKOFF_INTERVAL(val) vxge_vBIT(val, 40, 24)
+/*0x00a68*/ u64 prc_cfg5;
+#define VXGE_HW_PRC_CFG5_RXD0_ADD(val) vxge_vBIT(val, 0, 61)
+/*0x00a70*/ u64 prc_cfg6;
+#define VXGE_HW_PRC_CFG6_FRM_PAD_EN vxge_mBIT(0)
+#define VXGE_HW_PRC_CFG6_QSIZE_ALIGNED_RXD vxge_mBIT(2)
+#define VXGE_HW_PRC_CFG6_DOORBELL_MODE_EN vxge_mBIT(5)
+#define VXGE_HW_PRC_CFG6_L3_CPC_TRSFR_CODE_EN vxge_mBIT(8)
+#define VXGE_HW_PRC_CFG6_L4_CPC_TRSFR_CODE_EN vxge_mBIT(9)
+#define VXGE_HW_PRC_CFG6_RXD_CRXDT(val) vxge_vBIT(val, 23, 9)
+#define VXGE_HW_PRC_CFG6_RXD_SPAT(val) vxge_vBIT(val, 36, 9)
+/*0x00a78*/ u64 prc_cfg7;
+#define VXGE_HW_PRC_CFG7_SCATTER_MODE(val) vxge_vBIT(val, 6, 2)
+#define VXGE_HW_PRC_CFG7_SMART_SCAT_EN vxge_mBIT(11)
+#define VXGE_HW_PRC_CFG7_RXD_NS_CHG_EN vxge_mBIT(12)
+#define VXGE_HW_PRC_CFG7_NO_HDR_SEPARATION vxge_mBIT(14)
+#define VXGE_HW_PRC_CFG7_RXD_BUFF_SIZE_MASK(val) vxge_vBIT(val, 20, 4)
+#define VXGE_HW_PRC_CFG7_BUFF_SIZE0_MASK(val) vxge_vBIT(val, 27, 5)
+/*0x00a80*/ u64 tim_dest_addr;
+#define VXGE_HW_TIM_DEST_ADDR_TIM_DEST_ADDR(val) vxge_vBIT(val, 0, 64)
+/*0x00a88*/ u64 prc_rxd_doorbell;
+#define VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(val) vxge_vBIT(val, 48, 16)
+/*0x00a90*/ u64 rqa_prty_for_vp;
+#define VXGE_HW_RQA_PRTY_FOR_VP_RQA_PRTY_FOR_VP(val) vxge_vBIT(val, 59, 5)
+/*0x00a98*/ u64 rxdmem_size;
+#define VXGE_HW_RXDMEM_SIZE_PRC_RXDMEM_SIZE(val) vxge_vBIT(val, 51, 13)
+/*0x00aa0*/ u64 frm_in_progress_cnt;
+#define VXGE_HW_FRM_IN_PROGRESS_CNT_PRC_FRM_IN_PROGRESS_CNT(val) \
+ vxge_vBIT(val, 59, 5)
+/*0x00aa8*/ u64 rx_multi_cast_stats;
+#define VXGE_HW_RX_MULTI_CAST_STATS_FRAME_DISCARD(val) vxge_vBIT(val, 48, 16)
+/*0x00ab0*/ u64 rx_frm_transferred;
+#define VXGE_HW_RX_FRM_TRANSFERRED_RX_FRM_TRANSFERRED(val) \
+ vxge_vBIT(val, 32, 32)
+/*0x00ab8*/ u64 rxd_returned;
+#define VXGE_HW_RXD_RETURNED_RXD_RETURNED(val) vxge_vBIT(val, 48, 16)
+ u8 unused00c00[0x00c00-0x00ac0];
+
+/*0x00c00*/ u64 kdfc_fifo_trpl_partition;
+#define VXGE_HW_KDFC_FIFO_TRPL_PARTITION_LENGTH_0(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_FIFO_TRPL_PARTITION_LENGTH_1(val) vxge_vBIT(val, 33, 15)
+#define VXGE_HW_KDFC_FIFO_TRPL_PARTITION_LENGTH_2(val) vxge_vBIT(val, 49, 15)
+/*0x00c08*/ u64 kdfc_fifo_trpl_ctrl;
+#define VXGE_HW_KDFC_FIFO_TRPL_CTRL_TRIPLET_ENABLE vxge_mBIT(7)
+/*0x00c10*/ u64 kdfc_trpl_fifo_0_ctrl;
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_MODE(val) vxge_vBIT(val, 14, 2)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_FLIP_EN vxge_mBIT(22)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SWAP_EN vxge_mBIT(23)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_INT_CTRL(val) vxge_vBIT(val, 26, 2)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_CTRL_STRUC vxge_mBIT(28)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_ADD_PAD vxge_mBIT(29)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_NO_SNOOP vxge_mBIT(30)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_RLX_ORD vxge_mBIT(31)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_SELECT(val) vxge_vBIT(val, 32, 8)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_INT_NO(val) vxge_vBIT(val, 41, 7)
+#define VXGE_HW_KDFC_TRPL_FIFO_0_CTRL_BIT_MAP(val) vxge_vBIT(val, 48, 16)
+/*0x00c18*/ u64 kdfc_trpl_fifo_1_ctrl;
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_MODE(val) vxge_vBIT(val, 14, 2)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_FLIP_EN vxge_mBIT(22)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_SWAP_EN vxge_mBIT(23)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_INT_CTRL(val) vxge_vBIT(val, 26, 2)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_CTRL_STRUC vxge_mBIT(28)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_ADD_PAD vxge_mBIT(29)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_NO_SNOOP vxge_mBIT(30)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_RLX_ORD vxge_mBIT(31)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_SELECT(val) vxge_vBIT(val, 32, 8)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_INT_NO(val) vxge_vBIT(val, 41, 7)
+#define VXGE_HW_KDFC_TRPL_FIFO_1_CTRL_BIT_MAP(val) vxge_vBIT(val, 48, 16)
+/*0x00c20*/ u64 kdfc_trpl_fifo_2_ctrl;
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_FLIP_EN vxge_mBIT(22)
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_SWAP_EN vxge_mBIT(23)
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_INT_CTRL(val) vxge_vBIT(val, 26, 2)
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_CTRL_STRUC vxge_mBIT(28)
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_ADD_PAD vxge_mBIT(29)
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_NO_SNOOP vxge_mBIT(30)
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_RLX_ORD vxge_mBIT(31)
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_SELECT(val) vxge_vBIT(val, 32, 8)
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_INT_NO(val) vxge_vBIT(val, 41, 7)
+#define VXGE_HW_KDFC_TRPL_FIFO_2_CTRL_BIT_MAP(val) vxge_vBIT(val, 48, 16)
+/*0x00c28*/ u64 kdfc_trpl_fifo_0_wb_address;
+#define VXGE_HW_KDFC_TRPL_FIFO_0_WB_ADDRESS_ADD(val) vxge_vBIT(val, 0, 64)
+/*0x00c30*/ u64 kdfc_trpl_fifo_1_wb_address;
+#define VXGE_HW_KDFC_TRPL_FIFO_1_WB_ADDRESS_ADD(val) vxge_vBIT(val, 0, 64)
+/*0x00c38*/ u64 kdfc_trpl_fifo_2_wb_address;
+#define VXGE_HW_KDFC_TRPL_FIFO_2_WB_ADDRESS_ADD(val) vxge_vBIT(val, 0, 64)
+/*0x00c40*/ u64 kdfc_trpl_fifo_offset;
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_KDFC_RCTR0(val) vxge_vBIT(val, 1, 15)
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_KDFC_RCTR1(val) vxge_vBIT(val, 17, 15)
+#define VXGE_HW_KDFC_TRPL_FIFO_OFFSET_KDFC_RCTR2(val) vxge_vBIT(val, 33, 15)
+/*0x00c48*/ u64 kdfc_drbl_triplet_total;
+#define VXGE_HW_KDFC_DRBL_TRIPLET_TOTAL_KDFC_MAX_SIZE(val) \
+ vxge_vBIT(val, 17, 15)
+ u8 unused00c60[0x00c60-0x00c50];
+
+/*0x00c60*/ u64 usdc_drbl_ctrl;
+#define VXGE_HW_USDC_DRBL_CTRL_FLIP_EN vxge_mBIT(22)
+#define VXGE_HW_USDC_DRBL_CTRL_SWAP_EN vxge_mBIT(23)
+/*0x00c68*/ u64 usdc_vp_ready;
+#define VXGE_HW_USDC_VP_READY_USDC_HTN_READY vxge_mBIT(7)
+#define VXGE_HW_USDC_VP_READY_USDC_SRQ_READY vxge_mBIT(15)
+#define VXGE_HW_USDC_VP_READY_USDC_CQRQ_READY vxge_mBIT(23)
+/*0x00c70*/ u64 kdfc_status;
+#define VXGE_HW_KDFC_STATUS_KDFC_WRR_0_READY vxge_mBIT(0)
+#define VXGE_HW_KDFC_STATUS_KDFC_WRR_1_READY vxge_mBIT(1)
+#define VXGE_HW_KDFC_STATUS_KDFC_WRR_2_READY vxge_mBIT(2)
+ u8 unused00c80[0x00c80-0x00c78];
+
+/*0x00c80*/ u64 xmac_rpa_vcfg;
+#define VXGE_HW_XMAC_RPA_VCFG_IPV4_TCP_INCL_PH vxge_mBIT(3)
+#define VXGE_HW_XMAC_RPA_VCFG_IPV6_TCP_INCL_PH vxge_mBIT(7)
+#define VXGE_HW_XMAC_RPA_VCFG_IPV4_UDP_INCL_PH vxge_mBIT(11)
+#define VXGE_HW_XMAC_RPA_VCFG_IPV6_UDP_INCL_PH vxge_mBIT(15)
+#define VXGE_HW_XMAC_RPA_VCFG_L4_INCL_CF vxge_mBIT(19)
+#define VXGE_HW_XMAC_RPA_VCFG_STRIP_VLAN_TAG vxge_mBIT(23)
+/*0x00c88*/ u64 rxmac_vcfg0;
+#define VXGE_HW_RXMAC_VCFG0_RTS_MAX_FRM_LEN(val) vxge_vBIT(val, 2, 14)
+#define VXGE_HW_RXMAC_VCFG0_RTS_USE_MIN_LEN vxge_mBIT(19)
+#define VXGE_HW_RXMAC_VCFG0_RTS_MIN_FRM_LEN(val) vxge_vBIT(val, 26, 14)
+#define VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN vxge_mBIT(43)
+#define VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN vxge_mBIT(47)
+#define VXGE_HW_RXMAC_VCFG0_BCAST_EN vxge_mBIT(51)
+#define VXGE_HW_RXMAC_VCFG0_ALL_VID_EN vxge_mBIT(55)
+/*0x00c90*/ u64 rxmac_vcfg1;
+#define VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_BD_MODE(val) vxge_vBIT(val, 42, 2)
+#define VXGE_HW_RXMAC_VCFG1_RTS_RTH_MULTI_IT_EN_MODE vxge_mBIT(47)
+#define VXGE_HW_RXMAC_VCFG1_CONTRIB_L2_FLOW vxge_mBIT(51)
+/*0x00c98*/ u64 rts_access_steer_ctrl;
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION(val) vxge_vBIT(val, 1, 7)
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL(val) vxge_vBIT(val, 8, 4)
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_STROBE vxge_mBIT(15)
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_BEHAV_TBL_SEL vxge_mBIT(23)
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_TABLE_SEL vxge_mBIT(27)
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_RMACJ_STATUS vxge_mBIT(0)
+#define VXGE_HW_RTS_ACCESS_STEER_CTRL_OFFSET(val) vxge_vBIT(val, 40, 8)
+/*0x00ca0*/ u64 rts_access_steer_data0;
+#define VXGE_HW_RTS_ACCESS_STEER_DATA0_DATA(val) vxge_vBIT(val, 0, 64)
+/*0x00ca8*/ u64 rts_access_steer_data1;
+#define VXGE_HW_RTS_ACCESS_STEER_DATA1_DATA(val) vxge_vBIT(val, 0, 64)
+ u8 unused00d00[0x00d00-0x00cb0];
+
+/*0x00d00*/ u64 xmac_vsport_choice;
+#define VXGE_HW_XMAC_VSPORT_CHOICE_VSPORT_NUMBER(val) vxge_vBIT(val, 3, 5)
+/*0x00d08*/ u64 xmac_stats_cfg;
+/*0x00d10*/ u64 xmac_stats_access_cmd;
+#define VXGE_HW_XMAC_STATS_ACCESS_CMD_OP(val) vxge_vBIT(val, 6, 2)
+#define VXGE_HW_XMAC_STATS_ACCESS_CMD_STROBE vxge_mBIT(15)
+#define VXGE_HW_XMAC_STATS_ACCESS_CMD_OFFSET_SEL(val) vxge_vBIT(val, 32, 8)
+/*0x00d18*/ u64 xmac_stats_access_data;
+#define VXGE_HW_XMAC_STATS_ACCESS_DATA_XSMGR_DATA(val) vxge_vBIT(val, 0, 64)
+/*0x00d20*/ u64 asic_ntwk_vp_ctrl;
+#define VXGE_HW_ASIC_NTWK_VP_CTRL_REQ_TEST_NTWK vxge_mBIT(3)
+#define VXGE_HW_ASIC_NTWK_VP_CTRL_XMACJ_SHOW_PORT_INFO vxge_mBIT(55)
+#define VXGE_HW_ASIC_NTWK_VP_CTRL_XMACJ_PORT_NUM vxge_mBIT(63)
+ u8 unused00d30[0x00d30-0x00d28];
+
+/*0x00d30*/ u64 xgmac_vp_int_status;
+#define VXGE_HW_XGMAC_VP_INT_STATUS_ASIC_NTWK_VP_ERR_ASIC_NTWK_VP_INT \
+ vxge_mBIT(3)
+/*0x00d38*/ u64 xgmac_vp_int_mask;
+/*0x00d40*/ u64 asic_ntwk_vp_err_reg;
+#define VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT vxge_mBIT(3)
+#define VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK vxge_mBIT(7)
+#define VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR \
+ vxge_mBIT(11)
+#define VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR \
+ vxge_mBIT(15)
+#define VXGE_HW_ASIC_NTWK_VP_ERR_REG_XMACJ_NTWK_REAFFIRMED_FAULT \
+ vxge_mBIT(19)
+#define VXGE_HW_ASIC_NTWK_VP_ERR_REG_XMACJ_NTWK_REAFFIRMED_OK vxge_mBIT(23)
+/*0x00d48*/ u64 asic_ntwk_vp_err_mask;
+/*0x00d50*/ u64 asic_ntwk_vp_err_alarm;
+ u8 unused00d80[0x00d80-0x00d58];
+
+/*0x00d80*/ u64 rtdma_bw_ctrl;
+#define VXGE_HW_RTDMA_BW_CTRL_BW_CTRL_EN vxge_mBIT(39)
+#define VXGE_HW_RTDMA_BW_CTRL_DESIRED_BW(val) vxge_vBIT(val, 46, 18)
+/*0x00d88*/ u64 rtdma_rd_optimization_ctrl;
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_GEN_INT_AFTER_ABORT vxge_mBIT(3)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_PAD_MODE(val) vxge_vBIT(val, 6, 2)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_PAD_PATTERN(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_WAIT_FOR_SPACE vxge_mBIT(19)
+#define VXGE_HW_PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_FILL_THRESH(val) \
+ vxge_vBIT(val, 21, 3)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_TXD_PYLD_WMARK_EN vxge_mBIT(28)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_TXD_PYLD_WMARK(val) \
+ vxge_vBIT(val, 29, 3)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY_EN vxge_mBIT(35)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_FB_ADDR_BDRY(val) \
+ vxge_vBIT(val, 37, 3)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_TXD_WAIT_FOR_SPACE vxge_mBIT(43)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_TXD_FILL_THRESH(val) \
+ vxge_vBIT(val, 51, 5)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_TXD_ADDR_BDRY_EN vxge_mBIT(59)
+#define VXGE_HW_RTDMA_RD_OPTIMIZATION_CTRL_TXD_ADDR_BDRY(val) \
+ vxge_vBIT(val, 61, 3)
+/*0x00d90*/ u64 pda_pcc_job_monitor;
+#define VXGE_HW_PDA_PCC_JOB_MONITOR_PDA_PCC_JOB_STATUS vxge_mBIT(7)
+/*0x00d98*/ u64 tx_protocol_assist_cfg;
+#define VXGE_HW_TX_PROTOCOL_ASSIST_CFG_LSOV2_EN vxge_mBIT(6)
+#define VXGE_HW_TX_PROTOCOL_ASSIST_CFG_IPV6_KEEP_SEARCHING vxge_mBIT(7)
+ u8 unused01000[0x01000-0x00da0];
+
+/*0x01000*/ u64 tim_cfg1_int_num[4];
+#define VXGE_HW_TIM_CFG1_INT_NUM_BTIMER_VAL(val) vxge_vBIT(val, 6, 26)
+#define VXGE_HW_TIM_CFG1_INT_NUM_BITMP_EN vxge_mBIT(35)
+#define VXGE_HW_TIM_CFG1_INT_NUM_TXFRM_CNT_EN vxge_mBIT(36)
+#define VXGE_HW_TIM_CFG1_INT_NUM_TXD_CNT_EN vxge_mBIT(37)
+#define VXGE_HW_TIM_CFG1_INT_NUM_TIMER_AC vxge_mBIT(38)
+#define VXGE_HW_TIM_CFG1_INT_NUM_TIMER_CI vxge_mBIT(39)
+#define VXGE_HW_TIM_CFG1_INT_NUM_URNG_A(val) vxge_vBIT(val, 41, 7)
+#define VXGE_HW_TIM_CFG1_INT_NUM_URNG_B(val) vxge_vBIT(val, 49, 7)
+#define VXGE_HW_TIM_CFG1_INT_NUM_URNG_C(val) vxge_vBIT(val, 57, 7)
+/*0x01020*/ u64 tim_cfg2_int_num[4];
+#define VXGE_HW_TIM_CFG2_INT_NUM_UEC_A(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_TIM_CFG2_INT_NUM_UEC_B(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_TIM_CFG2_INT_NUM_UEC_C(val) vxge_vBIT(val, 32, 16)
+#define VXGE_HW_TIM_CFG2_INT_NUM_UEC_D(val) vxge_vBIT(val, 48, 16)
+/*0x01040*/ u64 tim_cfg3_int_num[4];
+#define VXGE_HW_TIM_CFG3_INT_NUM_TIMER_RI vxge_mBIT(0)
+#define VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_EVENT_SF(val) vxge_vBIT(val, 1, 4)
+#define VXGE_HW_TIM_CFG3_INT_NUM_RTIMER_VAL(val) vxge_vBIT(val, 6, 26)
+#define VXGE_HW_TIM_CFG3_INT_NUM_UTIL_SEL(val) vxge_vBIT(val, 32, 6)
+#define VXGE_HW_TIM_CFG3_INT_NUM_LTIMER_VAL(val) vxge_vBIT(val, 38, 26)
+/*0x01060*/ u64 tim_wrkld_clc;
+#define VXGE_HW_TIM_WRKLD_CLC_WRKLD_EVAL_PRD(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_TIM_WRKLD_CLC_WRKLD_EVAL_DIV(val) vxge_vBIT(val, 35, 5)
+#define VXGE_HW_TIM_WRKLD_CLC_CNT_FRM_BYTE vxge_mBIT(40)
+#define VXGE_HW_TIM_WRKLD_CLC_CNT_RX_TX(val) vxge_vBIT(val, 41, 2)
+#define VXGE_HW_TIM_WRKLD_CLC_CNT_LNK_EN vxge_mBIT(43)
+#define VXGE_HW_TIM_WRKLD_CLC_HOST_UTIL(val) vxge_vBIT(val, 57, 7)
+/*0x01068*/ u64 tim_bitmap;
+#define VXGE_HW_TIM_BITMAP_MASK(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_TIM_BITMAP_LLROOT_RXD_EN vxge_mBIT(32)
+#define VXGE_HW_TIM_BITMAP_LLROOT_TXD_EN vxge_mBIT(33)
+/*0x01070*/ u64 tim_ring_assn;
+#define VXGE_HW_TIM_RING_ASSN_INT_NUM(val) vxge_vBIT(val, 6, 2)
+/*0x01078*/ u64 tim_remap;
+#define VXGE_HW_TIM_REMAP_TX_EN vxge_mBIT(5)
+#define VXGE_HW_TIM_REMAP_RX_EN vxge_mBIT(6)
+#define VXGE_HW_TIM_REMAP_OFFLOAD_EN vxge_mBIT(7)
+#define VXGE_HW_TIM_REMAP_TO_VPATH_NUM(val) vxge_vBIT(val, 11, 5)
+/*0x01080*/ u64 tim_vpath_map;
+#define VXGE_HW_TIM_VPATH_MAP_BMAP_ROOT(val) vxge_vBIT(val, 0, 32)
+/*0x01088*/ u64 tim_pci_cfg;
+#define VXGE_HW_TIM_PCI_CFG_ADD_PAD vxge_mBIT(7)
+#define VXGE_HW_TIM_PCI_CFG_NO_SNOOP vxge_mBIT(15)
+#define VXGE_HW_TIM_PCI_CFG_RELAXED vxge_mBIT(23)
+#define VXGE_HW_TIM_PCI_CFG_CTL_STR vxge_mBIT(31)
+ u8 unused01100[0x01100-0x01090];
+
+/*0x01100*/ u64 sgrp_assign;
+#define VXGE_HW_SGRP_ASSIGN_SGRP_ASSIGN(val) vxge_vBIT(val, 0, 64)
+/*0x01108*/ u64 sgrp_aoa_and_result;
+#define VXGE_HW_SGRP_AOA_AND_RESULT_PET_SGRP_AOA_AND_RESULT(val) \
+ vxge_vBIT(val, 0, 64)
+/*0x01110*/ u64 rpe_pci_cfg;
+#define VXGE_HW_RPE_PCI_CFG_PAD_LRO_DATA_ENABLE vxge_mBIT(7)
+#define VXGE_HW_RPE_PCI_CFG_PAD_LRO_HDR_ENABLE vxge_mBIT(8)
+#define VXGE_HW_RPE_PCI_CFG_PAD_LRO_CQE_ENABLE vxge_mBIT(9)
+#define VXGE_HW_RPE_PCI_CFG_PAD_NONLL_CQE_ENABLE vxge_mBIT(10)
+#define VXGE_HW_RPE_PCI_CFG_PAD_BASE_LL_CQE_ENABLE vxge_mBIT(11)
+#define VXGE_HW_RPE_PCI_CFG_PAD_LL_CQE_IDATA_ENABLE vxge_mBIT(12)
+#define VXGE_HW_RPE_PCI_CFG_PAD_CQRQ_IR_ENABLE vxge_mBIT(13)
+#define VXGE_HW_RPE_PCI_CFG_PAD_CQSQ_IR_ENABLE vxge_mBIT(14)
+#define VXGE_HW_RPE_PCI_CFG_PAD_CQRR_IR_ENABLE vxge_mBIT(15)
+#define VXGE_HW_RPE_PCI_CFG_NOSNOOP_DATA vxge_mBIT(18)
+#define VXGE_HW_RPE_PCI_CFG_NOSNOOP_NONLL_CQE vxge_mBIT(19)
+#define VXGE_HW_RPE_PCI_CFG_NOSNOOP_LL_CQE vxge_mBIT(20)
+#define VXGE_HW_RPE_PCI_CFG_NOSNOOP_CQRQ_IR vxge_mBIT(21)
+#define VXGE_HW_RPE_PCI_CFG_NOSNOOP_CQSQ_IR vxge_mBIT(22)
+#define VXGE_HW_RPE_PCI_CFG_NOSNOOP_CQRR_IR vxge_mBIT(23)
+#define VXGE_HW_RPE_PCI_CFG_RELAXED_DATA vxge_mBIT(26)
+#define VXGE_HW_RPE_PCI_CFG_RELAXED_NONLL_CQE vxge_mBIT(27)
+#define VXGE_HW_RPE_PCI_CFG_RELAXED_LL_CQE vxge_mBIT(28)
+#define VXGE_HW_RPE_PCI_CFG_RELAXED_CQRQ_IR vxge_mBIT(29)
+#define VXGE_HW_RPE_PCI_CFG_RELAXED_CQSQ_IR vxge_mBIT(30)
+#define VXGE_HW_RPE_PCI_CFG_RELAXED_CQRR_IR vxge_mBIT(31)
+/*0x01118*/ u64 rpe_lro_cfg;
+#define VXGE_HW_RPE_LRO_CFG_SUPPRESS_LRO_ETH_TRLR vxge_mBIT(7)
+#define VXGE_HW_RPE_LRO_CFG_ALLOW_LRO_SNAP_SNAPJUMBO_MRG vxge_mBIT(11)
+#define VXGE_HW_RPE_LRO_CFG_ALLOW_LRO_LLC_LLCJUMBO_MRG vxge_mBIT(15)
+#define VXGE_HW_RPE_LRO_CFG_INCL_ACK_CNT_IN_CQE vxge_mBIT(23)
+/*0x01120*/ u64 pe_mr2vp_ack_blk_limit;
+#define VXGE_HW_PE_MR2VP_ACK_BLK_LIMIT_BLK_LIMIT(val) vxge_vBIT(val, 32, 32)
+/*0x01128*/ u64 pe_mr2vp_rirr_lirr_blk_limit;
+#define VXGE_HW_PE_MR2VP_RIRR_LIRR_BLK_LIMIT_RIRR_BLK_LIMIT(val) \
+ vxge_vBIT(val, 0, 32)
+#define VXGE_HW_PE_MR2VP_RIRR_LIRR_BLK_LIMIT_LIRR_BLK_LIMIT(val) \
+ vxge_vBIT(val, 32, 32)
+/*0x01130*/ u64 txpe_pci_nce_cfg;
+#define VXGE_HW_TXPE_PCI_NCE_CFG_NCE_THRESH(val) vxge_vBIT(val, 0, 32)
+#define VXGE_HW_TXPE_PCI_NCE_CFG_PAD_TOWI_ENABLE vxge_mBIT(55)
+#define VXGE_HW_TXPE_PCI_NCE_CFG_NOSNOOP_TOWI vxge_mBIT(63)
+ u8 unused01180[0x01180-0x01138];
+
+/*0x01180*/ u64 msg_qpad_en_cfg;
+#define VXGE_HW_MSG_QPAD_EN_CFG_UMQ_BWR_READ vxge_mBIT(3)
+#define VXGE_HW_MSG_QPAD_EN_CFG_DMQ_BWR_READ vxge_mBIT(7)
+#define VXGE_HW_MSG_QPAD_EN_CFG_MXP_GENDMA_READ vxge_mBIT(11)
+#define VXGE_HW_MSG_QPAD_EN_CFG_UXP_GENDMA_READ vxge_mBIT(15)
+#define VXGE_HW_MSG_QPAD_EN_CFG_UMQ_MSG_WRITE vxge_mBIT(19)
+#define VXGE_HW_MSG_QPAD_EN_CFG_UMQDMQ_IR_WRITE vxge_mBIT(23)
+#define VXGE_HW_MSG_QPAD_EN_CFG_MXP_GENDMA_WRITE vxge_mBIT(27)
+#define VXGE_HW_MSG_QPAD_EN_CFG_UXP_GENDMA_WRITE vxge_mBIT(31)
+/*0x01188*/ u64 msg_pci_cfg;
+#define VXGE_HW_MSG_PCI_CFG_GENDMA_NO_SNOOP vxge_mBIT(3)
+#define VXGE_HW_MSG_PCI_CFG_UMQDMQ_IR_NO_SNOOP vxge_mBIT(7)
+#define VXGE_HW_MSG_PCI_CFG_UMQ_NO_SNOOP vxge_mBIT(11)
+#define VXGE_HW_MSG_PCI_CFG_DMQ_NO_SNOOP vxge_mBIT(15)
+/*0x01190*/ u64 umqdmq_ir_init;
+#define VXGE_HW_UMQDMQ_IR_INIT_HOST_WRITE_ADD(val) vxge_vBIT(val, 0, 64)
+/*0x01198*/ u64 dmq_ir_int;
+#define VXGE_HW_DMQ_IR_INT_IMMED_ENABLE vxge_mBIT(6)
+#define VXGE_HW_DMQ_IR_INT_EVENT_ENABLE vxge_mBIT(7)
+#define VXGE_HW_DMQ_IR_INT_NUMBER(val) vxge_vBIT(val, 9, 7)
+#define VXGE_HW_DMQ_IR_INT_BITMAP(val) vxge_vBIT(val, 16, 16)
+/*0x011a0*/ u64 dmq_bwr_init_add;
+#define VXGE_HW_DMQ_BWR_INIT_ADD_HOST(val) vxge_vBIT(val, 0, 64)
+/*0x011a8*/ u64 dmq_bwr_init_byte;
+#define VXGE_HW_DMQ_BWR_INIT_BYTE_COUNT(val) vxge_vBIT(val, 0, 32)
+/*0x011b0*/ u64 dmq_ir;
+#define VXGE_HW_DMQ_IR_POLICY(val) vxge_vBIT(val, 0, 8)
+/*0x011b8*/ u64 umq_int;
+#define VXGE_HW_UMQ_INT_IMMED_ENABLE vxge_mBIT(6)
+#define VXGE_HW_UMQ_INT_EVENT_ENABLE vxge_mBIT(7)
+#define VXGE_HW_UMQ_INT_NUMBER(val) vxge_vBIT(val, 9, 7)
+#define VXGE_HW_UMQ_INT_BITMAP(val) vxge_vBIT(val, 16, 16)
+/*0x011c0*/ u64 umq_mr2vp_bwr_pfch_init;
+#define VXGE_HW_UMQ_MR2VP_BWR_PFCH_INIT_NUMBER(val) vxge_vBIT(val, 0, 8)
+/*0x011c8*/ u64 umq_bwr_pfch_ctrl;
+#define VXGE_HW_UMQ_BWR_PFCH_CTRL_POLL_EN vxge_mBIT(3)
+/*0x011d0*/ u64 umq_mr2vp_bwr_eol;
+#define VXGE_HW_UMQ_MR2VP_BWR_EOL_POLL_LATENCY(val) vxge_vBIT(val, 32, 32)
+/*0x011d8*/ u64 umq_bwr_init_add;
+#define VXGE_HW_UMQ_BWR_INIT_ADD_HOST(val) vxge_vBIT(val, 0, 64)
+/*0x011e0*/ u64 umq_bwr_init_byte;
+#define VXGE_HW_UMQ_BWR_INIT_BYTE_COUNT(val) vxge_vBIT(val, 0, 32)
+/*0x011e8*/ u64 gendma_int;
+#define VXGE_HW_GENDMA_INT_IMMED_ENABLE vxge_mBIT(6)
+#define VXGE_HW_GENDMA_INT_EVENT_ENABLE vxge_mBIT(7)
+#define VXGE_HW_GENDMA_INT_NUMBER(val) vxge_vBIT(val, 9, 7)
+#define VXGE_HW_GENDMA_INT_BITMAP(val) vxge_vBIT(val, 16, 16)
+/*0x011f0*/ u64 umqdmq_ir_init_notify;
+#define VXGE_HW_UMQDMQ_IR_INIT_NOTIFY_PULSE vxge_mBIT(3)
+/*0x011f8*/ u64 dmq_init_notify;
+#define VXGE_HW_DMQ_INIT_NOTIFY_PULSE vxge_mBIT(3)
+/*0x01200*/ u64 umq_init_notify;
+#define VXGE_HW_UMQ_INIT_NOTIFY_PULSE vxge_mBIT(3)
+ u8 unused01380[0x01380-0x01208];
+
+/*0x01380*/ u64 tpa_cfg;
+#define VXGE_HW_TPA_CFG_IGNORE_FRAME_ERR vxge_mBIT(3)
+#define VXGE_HW_TPA_CFG_IPV6_STOP_SEARCHING vxge_mBIT(7)
+#define VXGE_HW_TPA_CFG_L4_PSHDR_PRESENT vxge_mBIT(11)
+#define VXGE_HW_TPA_CFG_SUPPORT_MOBILE_IPV6_HDRS vxge_mBIT(15)
+ u8 unused01400[0x01400-0x01388];
+
+/*0x01400*/ u64 tx_vp_reset_discarded_frms;
+#define VXGE_HW_TX_VP_RESET_DISCARDED_FRMS_TX_VP_RESET_DISCARDED_FRMS(val) \
+ vxge_vBIT(val, 48, 16)
+ u8 unused01480[0x01480-0x01408];
+
+/*0x01480*/ u64 fau_rpa_vcfg;
+#define VXGE_HW_FAU_RPA_VCFG_L4_COMP_CSUM vxge_mBIT(7)
+#define VXGE_HW_FAU_RPA_VCFG_L3_INCL_CF vxge_mBIT(11)
+#define VXGE_HW_FAU_RPA_VCFG_L3_COMP_CSUM vxge_mBIT(15)
+ u8 unused014d0[0x014d0-0x01488];
+
+/*0x014d0*/ u64 dbg_stats_rx_mpa;
+#define VXGE_HW_DBG_STATS_RX_MPA_CRC_FAIL_FRMS(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_DBG_STATS_RX_MPA_MRK_FAIL_FRMS(val) vxge_vBIT(val, 16, 16)
+#define VXGE_HW_DBG_STATS_RX_MPA_LEN_FAIL_FRMS(val) vxge_vBIT(val, 32, 16)
+/*0x014d8*/ u64 dbg_stats_rx_fau;
+#define VXGE_HW_DBG_STATS_RX_FAU_RX_WOL_FRMS(val) vxge_vBIT(val, 0, 16)
+#define VXGE_HW_DBG_STATS_RX_FAU_RX_VP_RESET_DISCARDED_FRMS(val) \
+ vxge_vBIT(val, 16, 16)
+#define VXGE_HW_DBG_STATS_RX_FAU_RX_PERMITTED_FRMS(val) \
+ vxge_vBIT(val, 32, 32)
+ u8 unused014f0[0x014f0-0x014e0];
+
+/*0x014f0*/ u64 fbmc_vp_rdy;
+#define VXGE_HW_FBMC_VP_RDY_QUEUE_SPAV_FM vxge_mBIT(0)
+ u8 unused01e00[0x01e00-0x014f8];
+
+/*0x01e00*/ u64 vpath_pcipif_int_status;
+#define \
+VXGE_HW_VPATH_PCIPIF_INT_STATUS_SRPCIM_MSG_TO_VPATH_SRPCIM_MSG_TO_VPATH_INT \
+ vxge_mBIT(3)
+#define VXGE_HW_VPATH_PCIPIF_INT_STATUS_VPATH_SPARE_R1_VPATH_SPARE_R1_INT \
+ vxge_mBIT(7)
+/*0x01e08*/ u64 vpath_pcipif_int_mask;
+ u8 unused01e20[0x01e20-0x01e10];
+
+/*0x01e20*/ u64 srpcim_msg_to_vpath_reg;
+#define VXGE_HW_SRPCIM_MSG_TO_VPATH_REG_SWIF_SRPCIM_TO_VPATH_RMSG_INT \
+ vxge_mBIT(3)
+/*0x01e28*/ u64 srpcim_msg_to_vpath_mask;
+/*0x01e30*/ u64 srpcim_msg_to_vpath_alarm;
+ u8 unused01ea0[0x01ea0-0x01e38];
+
+/*0x01ea0*/ u64 vpath_to_srpcim_wmsg;
+#define VXGE_HW_VPATH_TO_SRPCIM_WMSG_VPATH_TO_SRPCIM_WMSG(val) \
+ vxge_vBIT(val, 0, 64)
+/*0x01ea8*/ u64 vpath_to_srpcim_wmsg_trig;
+#define VXGE_HW_VPATH_TO_SRPCIM_WMSG_TRIG_VPATH_TO_SRPCIM_WMSG_TRIG \
+ vxge_mBIT(0)
+ u8 unused02000[0x02000-0x01eb0];
+
+/*0x02000*/ u64 vpath_general_int_status;
+#define VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT vxge_mBIT(3)
+#define VXGE_HW_VPATH_GENERAL_INT_STATUS_PCI_INT vxge_mBIT(7)
+#define VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT vxge_mBIT(15)
+#define VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT vxge_mBIT(19)
+/*0x02008*/ u64 vpath_general_int_mask;
+#define VXGE_HW_VPATH_GENERAL_INT_MASK_PIC_INT vxge_mBIT(3)
+#define VXGE_HW_VPATH_GENERAL_INT_MASK_PCI_INT vxge_mBIT(7)
+#define VXGE_HW_VPATH_GENERAL_INT_MASK_WRDMA_INT vxge_mBIT(15)
+#define VXGE_HW_VPATH_GENERAL_INT_MASK_XMAC_INT vxge_mBIT(19)
+/*0x02010*/ u64 vpath_ppif_int_status;
+#define VXGE_HW_VPATH_PPIF_INT_STATUS_KDFCCTL_ERRORS_KDFCCTL_INT \
+ vxge_mBIT(3)
+#define VXGE_HW_VPATH_PPIF_INT_STATUS_GENERAL_ERRORS_GENERAL_INT \
+ vxge_mBIT(7)
+#define VXGE_HW_VPATH_PPIF_INT_STATUS_PCI_CONFIG_ERRORS_PCI_CONFIG_INT \
+ vxge_mBIT(11)
+#define \
+VXGE_HW_VPATH_PPIF_INT_STATUS_MRPCIM_TO_VPATH_ALARM_MRPCIM_TO_VPATH_ALARM_INT \
+ vxge_mBIT(15)
+#define \
+VXGE_HW_VPATH_PPIF_INT_STATUS_SRPCIM_TO_VPATH_ALARM_SRPCIM_TO_VPATH_ALARM_INT \
+ vxge_mBIT(19)
+/*0x02018*/ u64 vpath_ppif_int_mask;
+/*0x02020*/ u64 kdfcctl_errors_reg;
+#define VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_OVRWR vxge_mBIT(3)
+#define VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_OVRWR vxge_mBIT(7)
+#define VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_OVRWR vxge_mBIT(11)
+#define VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_POISON vxge_mBIT(15)
+#define VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_POISON vxge_mBIT(19)
+#define VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_POISON vxge_mBIT(23)
+#define VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_DMA_ERR vxge_mBIT(31)
+#define VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_DMA_ERR vxge_mBIT(35)
+#define VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_DMA_ERR vxge_mBIT(39)
+/*0x02028*/ u64 kdfcctl_errors_mask;
+/*0x02030*/ u64 kdfcctl_errors_alarm;
+ u8 unused02040[0x02040-0x02038];
+
+/*0x02040*/ u64 general_errors_reg;
+#define VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO0_OVRFLOW vxge_mBIT(3)
+#define VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO1_OVRFLOW vxge_mBIT(7)
+#define VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO2_OVRFLOW vxge_mBIT(11)
+#define VXGE_HW_GENERAL_ERRORS_REG_STATSB_PIF_CHAIN_ERR vxge_mBIT(15)
+#define VXGE_HW_GENERAL_ERRORS_REG_STATSB_DROP_TIMEOUT_REQ vxge_mBIT(19)
+#define VXGE_HW_GENERAL_ERRORS_REG_TGT_ILLEGAL_ACCESS vxge_mBIT(27)
+#define VXGE_HW_GENERAL_ERRORS_REG_INI_SERR_DET vxge_mBIT(31)
+/*0x02048*/ u64 general_errors_mask;
+/*0x02050*/ u64 general_errors_alarm;
+/*0x02058*/ u64 pci_config_errors_reg;
+#define VXGE_HW_PCI_CONFIG_ERRORS_REG_PCICONFIG_STATUS_ERR vxge_mBIT(3)
+#define VXGE_HW_PCI_CONFIG_ERRORS_REG_PCICONFIG_UNCOR_ERR vxge_mBIT(7)
+#define VXGE_HW_PCI_CONFIG_ERRORS_REG_PCICONFIG_COR_ERR vxge_mBIT(11)
+/*0x02060*/ u64 pci_config_errors_mask;
+/*0x02068*/ u64 pci_config_errors_alarm;
+/*0x02070*/ u64 mrpcim_to_vpath_alarm_reg;
+#define VXGE_HW_MRPCIM_TO_VPATH_ALARM_REG_PPIF_MRPCIM_TO_VPATH_ALARM \
+ vxge_mBIT(3)
+/*0x02078*/ u64 mrpcim_to_vpath_alarm_mask;
+/*0x02080*/ u64 mrpcim_to_vpath_alarm_alarm;
+/*0x02088*/ u64 srpcim_to_vpath_alarm_reg;
+#define VXGE_HW_SRPCIM_TO_VPATH_ALARM_REG_PPIF_SRPCIM_TO_VPATH_ALARM(val) \
+ vxge_vBIT(val, 0, 17)
+/*0x02090*/ u64 srpcim_to_vpath_alarm_mask;
+/*0x02098*/ u64 srpcim_to_vpath_alarm_alarm;
+ u8 unused02108[0x02108-0x020a0];
+
+/*0x02108*/ u64 kdfcctl_status;
+#define VXGE_HW_KDFCCTL_STATUS_KDFCCTL_FIFO0_PRES(val) vxge_vBIT(val, 0, 8)
+#define VXGE_HW_KDFCCTL_STATUS_KDFCCTL_FIFO1_PRES(val) vxge_vBIT(val, 8, 8)
+#define VXGE_HW_KDFCCTL_STATUS_KDFCCTL_FIFO2_PRES(val) vxge_vBIT(val, 16, 8)
+#define VXGE_HW_KDFCCTL_STATUS_KDFCCTL_FIFO0_OVRWR(val) vxge_vBIT(val, 24, 8)
+#define VXGE_HW_KDFCCTL_STATUS_KDFCCTL_FIFO1_OVRWR(val) vxge_vBIT(val, 32, 8)
+#define VXGE_HW_KDFCCTL_STATUS_KDFCCTL_FIFO2_OVRWR(val) vxge_vBIT(val, 40, 8)
+/*0x02110*/ u64 rsthdlr_status;
+#define VXGE_HW_RSTHDLR_STATUS_RSTHDLR_CURRENT_RESET vxge_mBIT(3)
+#define VXGE_HW_RSTHDLR_STATUS_RSTHDLR_CURRENT_VPIN(val) vxge_vBIT(val, 6, 2)
+/*0x02118*/ u64 fifo0_status;
+#define VXGE_HW_FIFO0_STATUS_DBLGEN_FIFO0_RDIDX(val) vxge_vBIT(val, 0, 12)
+/*0x02120*/ u64 fifo1_status;
+#define VXGE_HW_FIFO1_STATUS_DBLGEN_FIFO1_RDIDX(val) vxge_vBIT(val, 0, 12)
+/*0x02128*/ u64 fifo2_status;
+#define VXGE_HW_FIFO2_STATUS_DBLGEN_FIFO2_RDIDX(val) vxge_vBIT(val, 0, 12)
+ u8 unused02158[0x02158-0x02130];
+
+/*0x02158*/ u64 tgt_illegal_access;
+#define VXGE_HW_TGT_ILLEGAL_ACCESS_SWIF_REGION(val) vxge_vBIT(val, 1, 7)
+ u8 unused02200[0x02200-0x02160];
+
+/*0x02200*/ u64 vpath_general_cfg1;
+#define VXGE_HW_VPATH_GENERAL_CFG1_TC_VALUE(val) vxge_vBIT(val, 1, 3)
+#define VXGE_HW_VPATH_GENERAL_CFG1_DATA_BYTE_SWAPEN vxge_mBIT(7)
+#define VXGE_HW_VPATH_GENERAL_CFG1_DATA_FLIPEN vxge_mBIT(11)
+#define VXGE_HW_VPATH_GENERAL_CFG1_CTL_BYTE_SWAPEN vxge_mBIT(15)
+#define VXGE_HW_VPATH_GENERAL_CFG1_CTL_FLIPEN vxge_mBIT(23)
+#define VXGE_HW_VPATH_GENERAL_CFG1_MSIX_ADDR_SWAPEN vxge_mBIT(51)
+#define VXGE_HW_VPATH_GENERAL_CFG1_MSIX_ADDR_FLIPEN vxge_mBIT(55)
+#define VXGE_HW_VPATH_GENERAL_CFG1_MSIX_DATA_SWAPEN vxge_mBIT(59)
+#define VXGE_HW_VPATH_GENERAL_CFG1_MSIX_DATA_FLIPEN vxge_mBIT(63)
+/*0x02208*/ u64 vpath_general_cfg2;
+#define VXGE_HW_VPATH_GENERAL_CFG2_SIZE_QUANTUM(val) vxge_vBIT(val, 1, 3)
+/*0x02210*/ u64 vpath_general_cfg3;
+#define VXGE_HW_VPATH_GENERAL_CFG3_IGNORE_VPATH_RST_FOR_INTA vxge_mBIT(3)
+ u8 unused02220[0x02220-0x02218];
+
+/*0x02220*/ u64 kdfcctl_cfg0;
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO0 vxge_mBIT(1)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO1 vxge_mBIT(2)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_SWAPEN_FIFO2 vxge_mBIT(3)
+#define VXGE_HW_KDFCCTL_CFG0_BIT_FLIPEN_FIFO0 vxge_mBIT(5)
+#define VXGE_HW_KDFCCTL_CFG0_BIT_FLIPEN_FIFO1 vxge_mBIT(6)
+#define VXGE_HW_KDFCCTL_CFG0_BIT_FLIPEN_FIFO2 vxge_mBIT(7)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE0_FIFO0 vxge_mBIT(9)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE0_FIFO1 vxge_mBIT(10)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE0_FIFO2 vxge_mBIT(11)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE1_FIFO0 vxge_mBIT(13)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE1_FIFO1 vxge_mBIT(14)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE1_FIFO2 vxge_mBIT(15)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE2_FIFO0 vxge_mBIT(17)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE2_FIFO1 vxge_mBIT(18)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE2_FIFO2 vxge_mBIT(19)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE3_FIFO0 vxge_mBIT(21)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE3_FIFO1 vxge_mBIT(22)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE3_FIFO2 vxge_mBIT(23)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE4_FIFO0 vxge_mBIT(25)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE4_FIFO1 vxge_mBIT(26)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE4_FIFO2 vxge_mBIT(27)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE5_FIFO0 vxge_mBIT(29)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE5_FIFO1 vxge_mBIT(30)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE5_FIFO2 vxge_mBIT(31)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE6_FIFO0 vxge_mBIT(33)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE6_FIFO1 vxge_mBIT(34)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE6_FIFO2 vxge_mBIT(35)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE7_FIFO0 vxge_mBIT(37)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE7_FIFO1 vxge_mBIT(38)
+#define VXGE_HW_KDFCCTL_CFG0_BYTE_MASK_BYTE7_FIFO2 vxge_mBIT(39)
+
+ u8 unused02268[0x02268-0x02228];
+
+/*0x02268*/ u64 stats_cfg;
+#define VXGE_HW_STATS_CFG_START_HOST_ADDR(val) vxge_vBIT(val, 0, 57)
+/*0x02270*/ u64 interrupt_cfg0;
+#define VXGE_HW_INTERRUPT_CFG0_MSIX_FOR_RXTI(val) vxge_vBIT(val, 1, 7)
+#define VXGE_HW_INTERRUPT_CFG0_GROUP0_MSIX_FOR_TXTI(val) vxge_vBIT(val, 9, 7)
+#define VXGE_HW_INTERRUPT_CFG0_GROUP1_MSIX_FOR_TXTI(val) vxge_vBIT(val, 17, 7)
+#define VXGE_HW_INTERRUPT_CFG0_GROUP2_MSIX_FOR_TXTI(val) vxge_vBIT(val, 25, 7)
+#define VXGE_HW_INTERRUPT_CFG0_GROUP3_MSIX_FOR_TXTI(val) vxge_vBIT(val, 33, 7)
+ u8 unused02280[0x02280-0x02278];
+
+/*0x02280*/ u64 interrupt_cfg2;
+#define VXGE_HW_INTERRUPT_CFG2_ALARM_MAP_TO_MSG(val) vxge_vBIT(val, 1, 7)
+/*0x02288*/ u64 one_shot_vect0_en;
+#define VXGE_HW_ONE_SHOT_VECT0_EN_ONE_SHOT_VECT0_EN vxge_mBIT(3)
+/*0x02290*/ u64 one_shot_vect1_en;
+#define VXGE_HW_ONE_SHOT_VECT1_EN_ONE_SHOT_VECT1_EN vxge_mBIT(3)
+/*0x02298*/ u64 one_shot_vect2_en;
+#define VXGE_HW_ONE_SHOT_VECT2_EN_ONE_SHOT_VECT2_EN vxge_mBIT(3)
+/*0x022a0*/ u64 one_shot_vect3_en;
+#define VXGE_HW_ONE_SHOT_VECT3_EN_ONE_SHOT_VECT3_EN vxge_mBIT(3)
+ u8 unused022b0[0x022b0-0x022a8];
+
+/*0x022b0*/ u64 pci_config_access_cfg1;
+#define VXGE_HW_PCI_CONFIG_ACCESS_CFG1_ADDRESS(val) vxge_vBIT(val, 0, 12)
+#define VXGE_HW_PCI_CONFIG_ACCESS_CFG1_SEL_FUNC0 vxge_mBIT(15)
+/*0x022b8*/ u64 pci_config_access_cfg2;
+#define VXGE_HW_PCI_CONFIG_ACCESS_CFG2_REQ vxge_mBIT(0)
+/*0x022c0*/ u64 pci_config_access_status;
+#define VXGE_HW_PCI_CONFIG_ACCESS_STATUS_ACCESS_ERR vxge_mBIT(0)
+#define VXGE_HW_PCI_CONFIG_ACCESS_STATUS_DATA(val) vxge_vBIT(val, 32, 32)
+ u8 unused02300[0x02300-0x022c8];
+
+/*0x02300*/ u64 vpath_debug_stats0;
+#define VXGE_HW_VPATH_DEBUG_STATS0_INI_NUM_MWR_SENT(val) vxge_vBIT(val, 0, 32)
+/*0x02308*/ u64 vpath_debug_stats1;
+#define VXGE_HW_VPATH_DEBUG_STATS1_INI_NUM_MRD_SENT(val) vxge_vBIT(val, 0, 32)
+/*0x02310*/ u64 vpath_debug_stats2;
+#define VXGE_HW_VPATH_DEBUG_STATS2_INI_NUM_CPL_RCVD(val) vxge_vBIT(val, 0, 32)
+/*0x02318*/ u64 vpath_debug_stats3;
+#define VXGE_HW_VPATH_DEBUG_STATS3_INI_NUM_MWR_BYTE_SENT(val) \
+ vxge_vBIT(val, 0, 64)
+/*0x02320*/ u64 vpath_debug_stats4;
+#define VXGE_HW_VPATH_DEBUG_STATS4_INI_NUM_CPL_BYTE_RCVD(val) \
+ vxge_vBIT(val, 0, 64)
+/*0x02328*/ u64 vpath_debug_stats5;
+#define VXGE_HW_VPATH_DEBUG_STATS5_WRCRDTARB_XOFF(val) vxge_vBIT(val, 32, 32)
+/*0x02330*/ u64 vpath_debug_stats6;
+#define VXGE_HW_VPATH_DEBUG_STATS6_RDCRDTARB_XOFF(val) vxge_vBIT(val, 32, 32)
+/*0x02338*/ u64 vpath_genstats_count01;
+#define VXGE_HW_VPATH_GENSTATS_COUNT01_PPIF_VPATH_GENSTATS_COUNT1(val) \
+ vxge_vBIT(val, 0, 32)
+#define VXGE_HW_VPATH_GENSTATS_COUNT01_PPIF_VPATH_GENSTATS_COUNT0(val) \
+ vxge_vBIT(val, 32, 32)
+/*0x02340*/ u64 vpath_genstats_count23;
+#define VXGE_HW_VPATH_GENSTATS_COUNT23_PPIF_VPATH_GENSTATS_COUNT3(val) \
+ vxge_vBIT(val, 0, 32)
+#define VXGE_HW_VPATH_GENSTATS_COUNT23_PPIF_VPATH_GENSTATS_COUNT2(val) \
+ vxge_vBIT(val, 32, 32)
+/*0x02348*/ u64 vpath_genstats_count4;
+#define VXGE_HW_VPATH_GENSTATS_COUNT4_PPIF_VPATH_GENSTATS_COUNT4(val) \
+ vxge_vBIT(val, 32, 32)
+/*0x02350*/ u64 vpath_genstats_count5;
+#define VXGE_HW_VPATH_GENSTATS_COUNT5_PPIF_VPATH_GENSTATS_COUNT5(val) \
+ vxge_vBIT(val, 32, 32)
+ u8 unused02648[0x02648-0x02358];
+} __packed;
+
+#define VXGE_HW_EEPROM_SIZE (0x01 << 11)
+
+/* Capability lists */
+#define VXGE_HW_PCI_EXP_LNKCAP_LNK_SPEED 0xf /* Supported Link speeds */
+#define VXGE_HW_PCI_EXP_LNKCAP_LNK_WIDTH 0x3f0 /* Supported Link speeds. */
+#define VXGE_HW_PCI_EXP_LNKCAP_LW_RES 0x0 /* Reserved. */
+
+#endif
diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c
new file mode 100644
index 000000000000..7be0ae10d69b
--- /dev/null
+++ b/drivers/net/vxge/vxge-traffic.c
@@ -0,0 +1,2528 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice. This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-traffic.c: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#include <linux/etherdevice.h>
+
+#include "vxge-traffic.h"
+#include "vxge-config.h"
+#include "vxge-main.h"
+
+/*
+ * vxge_hw_vpath_intr_enable - Enable vpath interrupts.
+ * @vp: Virtual Path handle.
+ *
+ * Enable vpath interrupts. The function is to be executed the last in
+ * vpath initialization sequence.
+ *
+ * See also: vxge_hw_vpath_intr_disable()
+ */
+enum vxge_hw_status vxge_hw_vpath_intr_enable(struct __vxge_hw_vpath_handle *vp)
+{
+ u64 val64;
+
+ struct __vxge_hw_virtualpath *vpath;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ vpath = vp->vpath;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto exit;
+ }
+
+ vp_reg = vpath->vp_reg;
+
+ writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->kdfcctl_errors_reg);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->general_errors_reg);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->pci_config_errors_reg);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->mrpcim_to_vpath_alarm_reg);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->srpcim_to_vpath_alarm_reg);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->vpath_ppif_int_status);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->srpcim_msg_to_vpath_reg);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->vpath_pcipif_int_status);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->prc_alarm_reg);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->wrdma_alarm_status);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->asic_ntwk_vp_err_reg);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->xgmac_vp_int_status);
+
+ val64 = readq(&vp_reg->vpath_general_int_status);
+
+ /* Mask unwanted interrupts */
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->vpath_pcipif_int_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->srpcim_msg_to_vpath_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->srpcim_to_vpath_alarm_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->mrpcim_to_vpath_alarm_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->pci_config_errors_mask);
+
+ /* Unmask the individual interrupts */
+
+ writeq((u32)vxge_bVALn((VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO1_OVRFLOW|
+ VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO2_OVRFLOW|
+ VXGE_HW_GENERAL_ERRORS_REG_STATSB_DROP_TIMEOUT_REQ|
+ VXGE_HW_GENERAL_ERRORS_REG_STATSB_PIF_CHAIN_ERR), 0, 32),
+ &vp_reg->general_errors_mask);
+
+ __vxge_hw_pio_mem_write32_upper(
+ (u32)vxge_bVALn((VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_OVRWR|
+ VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_OVRWR|
+ VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_POISON|
+ VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO2_POISON|
+ VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_DMA_ERR|
+ VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO1_DMA_ERR), 0, 32),
+ &vp_reg->kdfcctl_errors_mask);
+
+ __vxge_hw_pio_mem_write32_upper(0, &vp_reg->vpath_ppif_int_mask);
+
+ __vxge_hw_pio_mem_write32_upper(
+ (u32)vxge_bVALn(VXGE_HW_PRC_ALARM_REG_PRC_RING_BUMP, 0, 32),
+ &vp_reg->prc_alarm_mask);
+
+ __vxge_hw_pio_mem_write32_upper(0, &vp_reg->wrdma_alarm_mask);
+ __vxge_hw_pio_mem_write32_upper(0, &vp_reg->xgmac_vp_int_mask);
+
+ if (vpath->hldev->first_vp_id != vpath->vp_id)
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->asic_ntwk_vp_err_mask);
+ else
+ __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn((
+ VXGE_HW_ASIC_NTWK_VP_ERR_REG_XMACJ_NTWK_REAFFIRMED_FAULT |
+ VXGE_HW_ASIC_NTWK_VP_ERR_REG_XMACJ_NTWK_REAFFIRMED_OK), 0, 32),
+ &vp_reg->asic_ntwk_vp_err_mask);
+
+ __vxge_hw_pio_mem_write32_upper(0,
+ &vp_reg->vpath_general_int_mask);
+exit:
+ return status;
+
+}
+
+/*
+ * vxge_hw_vpath_intr_disable - Disable vpath interrupts.
+ * @vp: Virtual Path handle.
+ *
+ * Disable vpath interrupts. The function is to be executed the last in
+ * vpath initialization sequence.
+ *
+ * See also: vxge_hw_vpath_intr_enable()
+ */
+enum vxge_hw_status vxge_hw_vpath_intr_disable(
+ struct __vxge_hw_vpath_handle *vp)
+{
+ u64 val64;
+
+ struct __vxge_hw_virtualpath *vpath;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ vpath = vp->vpath;
+
+ if (vpath->vp_open == VXGE_HW_VP_NOT_OPEN) {
+ status = VXGE_HW_ERR_VPATH_NOT_OPEN;
+ goto exit;
+ }
+ vp_reg = vpath->vp_reg;
+
+ __vxge_hw_pio_mem_write32_upper(
+ (u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->vpath_general_int_mask);
+
+ val64 = VXGE_HW_TIM_CLR_INT_EN_VP(1 << (16 - vpath->vp_id));
+
+ writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->kdfcctl_errors_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->general_errors_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->pci_config_errors_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->mrpcim_to_vpath_alarm_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->srpcim_to_vpath_alarm_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->vpath_ppif_int_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->srpcim_msg_to_vpath_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->vpath_pcipif_int_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->wrdma_alarm_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->prc_alarm_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->xgmac_vp_int_mask);
+
+ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->asic_ntwk_vp_err_mask);
+
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_channel_msix_mask - Mask MSIX Vector.
+ * @channeh: Channel for rx or tx handle
+ * @msix_id: MSIX ID
+ *
+ * The function masks the msix interrupt for the given msix_id
+ *
+ * Returns: 0
+ */
+void vxge_hw_channel_msix_mask(struct __vxge_hw_channel *channel, int msix_id)
+{
+
+ __vxge_hw_pio_mem_write32_upper(
+ (u32)vxge_bVALn(vxge_mBIT(channel->first_vp_id+(msix_id/4)),
+ 0, 32),
+ &channel->common_reg->set_msix_mask_vect[msix_id%4]);
+
+ return;
+}
+
+/**
+ * vxge_hw_channel_msix_unmask - Unmask the MSIX Vector.
+ * @channeh: Channel for rx or tx handle
+ * @msix_id: MSI ID
+ *
+ * The function unmasks the msix interrupt for the given msix_id
+ *
+ * Returns: 0
+ */
+void
+vxge_hw_channel_msix_unmask(struct __vxge_hw_channel *channel, int msix_id)
+{
+
+ __vxge_hw_pio_mem_write32_upper(
+ (u32)vxge_bVALn(vxge_mBIT(channel->first_vp_id+(msix_id/4)),
+ 0, 32),
+ &channel->common_reg->clear_msix_mask_vect[msix_id%4]);
+
+ return;
+}
+
+/**
+ * vxge_hw_device_set_intr_type - Updates the configuration
+ * with new interrupt type.
+ * @hldev: HW device handle.
+ * @intr_mode: New interrupt type
+ */
+u32 vxge_hw_device_set_intr_type(struct __vxge_hw_device *hldev, u32 intr_mode)
+{
+
+ if ((intr_mode != VXGE_HW_INTR_MODE_IRQLINE) &&
+ (intr_mode != VXGE_HW_INTR_MODE_MSIX) &&
+ (intr_mode != VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) &&
+ (intr_mode != VXGE_HW_INTR_MODE_DEF))
+ intr_mode = VXGE_HW_INTR_MODE_IRQLINE;
+
+ hldev->config.intr_mode = intr_mode;
+ return intr_mode;
+}
+
+/**
+ * vxge_hw_device_intr_enable - Enable interrupts.
+ * @hldev: HW device handle.
+ * @op: One of the enum vxge_hw_device_intr enumerated values specifying
+ * the type(s) of interrupts to enable.
+ *
+ * Enable Titan interrupts. The function is to be executed the last in
+ * Titan initialization sequence.
+ *
+ * See also: vxge_hw_device_intr_disable()
+ */
+void vxge_hw_device_intr_enable(struct __vxge_hw_device *hldev)
+{
+ u32 i;
+ u64 val64;
+ u32 val32;
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+ if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
+ continue;
+
+ vxge_hw_vpath_intr_enable(
+ VXGE_HW_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i]));
+ }
+
+ if (hldev->config.intr_mode == VXGE_HW_INTR_MODE_IRQLINE) {
+ val64 = hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_TX] |
+ hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_RX];
+
+ if (val64 != 0) {
+ writeq(val64, &hldev->common_reg->tim_int_status0);
+
+ writeq(~val64, &hldev->common_reg->tim_int_mask0);
+ }
+
+ val32 = hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_TX] |
+ hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_RX];
+
+ if (val32 != 0) {
+ __vxge_hw_pio_mem_write32_upper(val32,
+ &hldev->common_reg->tim_int_status1);
+
+ __vxge_hw_pio_mem_write32_upper(~val32,
+ &hldev->common_reg->tim_int_mask1);
+ }
+ }
+
+ val64 = readq(&hldev->common_reg->titan_general_int_status);
+
+ vxge_hw_device_unmask_all(hldev);
+
+ return;
+}
+
+/**
+ * vxge_hw_device_intr_disable - Disable Titan interrupts.
+ * @hldev: HW device handle.
+ * @op: One of the enum vxge_hw_device_intr enumerated values specifying
+ * the type(s) of interrupts to disable.
+ *
+ * Disable Titan interrupts.
+ *
+ * See also: vxge_hw_device_intr_enable()
+ */
+void vxge_hw_device_intr_disable(struct __vxge_hw_device *hldev)
+{
+ u32 i;
+
+ vxge_hw_device_mask_all(hldev);
+
+ /* mask all the tim interrupts */
+ writeq(VXGE_HW_INTR_MASK_ALL, &hldev->common_reg->tim_int_mask0);
+ __vxge_hw_pio_mem_write32_upper(VXGE_HW_DEFAULT_32,
+ &hldev->common_reg->tim_int_mask1);
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+ if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
+ continue;
+
+ vxge_hw_vpath_intr_disable(
+ VXGE_HW_VIRTUAL_PATH_HANDLE(&hldev->virtual_paths[i]));
+ }
+
+ return;
+}
+
+/**
+ * vxge_hw_device_mask_all - Mask all device interrupts.
+ * @hldev: HW device handle.
+ *
+ * Mask all device interrupts.
+ *
+ * See also: vxge_hw_device_unmask_all()
+ */
+void vxge_hw_device_mask_all(struct __vxge_hw_device *hldev)
+{
+ u64 val64;
+
+ val64 = VXGE_HW_TITAN_MASK_ALL_INT_ALARM |
+ VXGE_HW_TITAN_MASK_ALL_INT_TRAFFIC;
+
+ __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
+ &hldev->common_reg->titan_mask_all_int);
+
+ return;
+}
+
+/**
+ * vxge_hw_device_unmask_all - Unmask all device interrupts.
+ * @hldev: HW device handle.
+ *
+ * Unmask all device interrupts.
+ *
+ * See also: vxge_hw_device_mask_all()
+ */
+void vxge_hw_device_unmask_all(struct __vxge_hw_device *hldev)
+{
+ u64 val64 = 0;
+
+ if (hldev->config.intr_mode == VXGE_HW_INTR_MODE_IRQLINE)
+ val64 = VXGE_HW_TITAN_MASK_ALL_INT_TRAFFIC;
+
+ __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(val64, 0, 32),
+ &hldev->common_reg->titan_mask_all_int);
+
+ return;
+}
+
+/**
+ * vxge_hw_device_flush_io - Flush io writes.
+ * @hldev: HW device handle.
+ *
+ * The function performs a read operation to flush io writes.
+ *
+ * Returns: void
+ */
+void vxge_hw_device_flush_io(struct __vxge_hw_device *hldev)
+{
+ u32 val32;
+
+ val32 = readl(&hldev->common_reg->titan_general_int_status);
+}
+
+/**
+ * vxge_hw_device_begin_irq - Begin IRQ processing.
+ * @hldev: HW device handle.
+ * @skip_alarms: Do not clear the alarms
+ * @reason: "Reason" for the interrupt, the value of Titan's
+ * general_int_status register.
+ *
+ * The function performs two actions, It first checks whether (shared IRQ) the
+ * interrupt was raised by the device. Next, it masks the device interrupts.
+ *
+ * Note:
+ * vxge_hw_device_begin_irq() does not flush MMIO writes through the
+ * bridge. Therefore, two back-to-back interrupts are potentially possible.
+ *
+ * Returns: 0, if the interrupt is not "ours" (note that in this case the
+ * device remain enabled).
+ * Otherwise, vxge_hw_device_begin_irq() returns 64bit general adapter
+ * status.
+ */
+enum vxge_hw_status vxge_hw_device_begin_irq(struct __vxge_hw_device *hldev,
+ u32 skip_alarms, u64 *reason)
+{
+ u32 i;
+ u64 val64;
+ u64 adapter_status;
+ u64 vpath_mask;
+ enum vxge_hw_status ret = VXGE_HW_OK;
+
+ val64 = readq(&hldev->common_reg->titan_general_int_status);
+
+ if (unlikely(!val64)) {
+ /* not Titan interrupt */
+ *reason = 0;
+ ret = VXGE_HW_ERR_WRONG_IRQ;
+ goto exit;
+ }
+
+ if (unlikely(val64 == VXGE_HW_ALL_FOXES)) {
+
+ adapter_status = readq(&hldev->common_reg->adapter_status);
+
+ if (adapter_status == VXGE_HW_ALL_FOXES) {
+
+ __vxge_hw_device_handle_error(hldev,
+ NULL_VPID, VXGE_HW_EVENT_SLOT_FREEZE);
+ *reason = 0;
+ ret = VXGE_HW_ERR_SLOT_FREEZE;
+ goto exit;
+ }
+ }
+
+ hldev->stats.sw_dev_info_stats.total_intr_cnt++;
+
+ *reason = val64;
+
+ vpath_mask = hldev->vpaths_deployed >>
+ (64 - VXGE_HW_MAX_VIRTUAL_PATHS);
+
+ if (val64 &
+ VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_TRAFFIC_INT(vpath_mask)) {
+ hldev->stats.sw_dev_info_stats.traffic_intr_cnt++;
+
+ return VXGE_HW_OK;
+ }
+
+ hldev->stats.sw_dev_info_stats.not_traffic_intr_cnt++;
+
+ if (unlikely(val64 &
+ VXGE_HW_TITAN_GENERAL_INT_STATUS_VPATH_ALARM_INT)) {
+
+ enum vxge_hw_status error_level = VXGE_HW_OK;
+
+ hldev->stats.sw_dev_err_stats.vpath_alarms++;
+
+ for (i = 0; i < VXGE_HW_MAX_VIRTUAL_PATHS; i++) {
+
+ if (!(hldev->vpaths_deployed & vxge_mBIT(i)))
+ continue;
+
+ ret = __vxge_hw_vpath_alarm_process(
+ &hldev->virtual_paths[i], skip_alarms);
+
+ error_level = VXGE_HW_SET_LEVEL(ret, error_level);
+
+ if (unlikely((ret == VXGE_HW_ERR_CRITICAL) ||
+ (ret == VXGE_HW_ERR_SLOT_FREEZE)))
+ break;
+ }
+
+ ret = error_level;
+ }
+exit:
+ return ret;
+}
+
+/*
+ * __vxge_hw_device_handle_link_up_ind
+ * @hldev: HW device handle.
+ *
+ * Link up indication handler. The function is invoked by HW when
+ * Titan indicates that the link is up for programmable amount of time.
+ */
+enum vxge_hw_status
+__vxge_hw_device_handle_link_up_ind(struct __vxge_hw_device *hldev)
+{
+ /*
+ * If the previous link state is not down, return.
+ */
+ if (hldev->link_state == VXGE_HW_LINK_UP)
+ goto exit;
+
+ hldev->link_state = VXGE_HW_LINK_UP;
+
+ /* notify driver */
+ if (hldev->uld_callbacks.link_up)
+ hldev->uld_callbacks.link_up(hldev);
+exit:
+ return VXGE_HW_OK;
+}
+
+/*
+ * __vxge_hw_device_handle_link_down_ind
+ * @hldev: HW device handle.
+ *
+ * Link down indication handler. The function is invoked by HW when
+ * Titan indicates that the link is down.
+ */
+enum vxge_hw_status
+__vxge_hw_device_handle_link_down_ind(struct __vxge_hw_device *hldev)
+{
+ /*
+ * If the previous link state is not down, return.
+ */
+ if (hldev->link_state == VXGE_HW_LINK_DOWN)
+ goto exit;
+
+ hldev->link_state = VXGE_HW_LINK_DOWN;
+
+ /* notify driver */
+ if (hldev->uld_callbacks.link_down)
+ hldev->uld_callbacks.link_down(hldev);
+exit:
+ return VXGE_HW_OK;
+}
+
+/**
+ * __vxge_hw_device_handle_error - Handle error
+ * @hldev: HW device
+ * @vp_id: Vpath Id
+ * @type: Error type. Please see enum vxge_hw_event{}
+ *
+ * Handle error.
+ */
+enum vxge_hw_status
+__vxge_hw_device_handle_error(
+ struct __vxge_hw_device *hldev,
+ u32 vp_id,
+ enum vxge_hw_event type)
+{
+ switch (type) {
+ case VXGE_HW_EVENT_UNKNOWN:
+ break;
+ case VXGE_HW_EVENT_RESET_START:
+ case VXGE_HW_EVENT_RESET_COMPLETE:
+ case VXGE_HW_EVENT_LINK_DOWN:
+ case VXGE_HW_EVENT_LINK_UP:
+ goto out;
+ case VXGE_HW_EVENT_ALARM_CLEARED:
+ goto out;
+ case VXGE_HW_EVENT_ECCERR:
+ case VXGE_HW_EVENT_MRPCIM_ECCERR:
+ goto out;
+ case VXGE_HW_EVENT_FIFO_ERR:
+ case VXGE_HW_EVENT_VPATH_ERR:
+ case VXGE_HW_EVENT_CRITICAL_ERR:
+ case VXGE_HW_EVENT_SERR:
+ break;
+ case VXGE_HW_EVENT_SRPCIM_SERR:
+ case VXGE_HW_EVENT_MRPCIM_SERR:
+ goto out;
+ case VXGE_HW_EVENT_SLOT_FREEZE:
+ break;
+ default:
+ vxge_assert(0);
+ goto out;
+ }
+
+ /* notify driver */
+ if (hldev->uld_callbacks.crit_err)
+ hldev->uld_callbacks.crit_err(
+ (struct __vxge_hw_device *)hldev,
+ type, vp_id);
+out:
+
+ return VXGE_HW_OK;
+}
+
+/**
+ * vxge_hw_device_clear_tx_rx - Acknowledge (that is, clear) the
+ * condition that has caused the Tx and RX interrupt.
+ * @hldev: HW device.
+ *
+ * Acknowledge (that is, clear) the condition that has caused
+ * the Tx and Rx interrupt.
+ * See also: vxge_hw_device_begin_irq(),
+ * vxge_hw_device_mask_tx_rx(), vxge_hw_device_unmask_tx_rx().
+ */
+void vxge_hw_device_clear_tx_rx(struct __vxge_hw_device *hldev)
+{
+
+ if ((hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_TX] != 0) ||
+ (hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_RX] != 0)) {
+ writeq((hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_TX] |
+ hldev->tim_int_mask0[VXGE_HW_VPATH_INTR_RX]),
+ &hldev->common_reg->tim_int_status0);
+ }
+
+ if ((hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_TX] != 0) ||
+ (hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_RX] != 0)) {
+ __vxge_hw_pio_mem_write32_upper(
+ (hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_TX] |
+ hldev->tim_int_mask1[VXGE_HW_VPATH_INTR_RX]),
+ &hldev->common_reg->tim_int_status1);
+ }
+
+ return;
+}
+
+/*
+ * vxge_hw_channel_dtr_alloc - Allocate a dtr from the channel
+ * @channel: Channel
+ * @dtrh: Buffer to return the DTR pointer
+ *
+ * Allocates a dtr from the reserve array. If the reserve array is empty,
+ * it swaps the reserve and free arrays.
+ *
+ */
+enum vxge_hw_status
+vxge_hw_channel_dtr_alloc(struct __vxge_hw_channel *channel, void **dtrh)
+{
+ void **tmp_arr;
+
+ if (channel->reserve_ptr - channel->reserve_top > 0) {
+_alloc_after_swap:
+ *dtrh = channel->reserve_arr[--channel->reserve_ptr];
+
+ return VXGE_HW_OK;
+ }
+
+ /* switch between empty and full arrays */
+
+ /* the idea behind such a design is that by having free and reserved
+ * arrays separated we basically separated irq and non-irq parts.
+ * i.e. no additional lock need to be done when we free a resource */
+
+ if (channel->length - channel->free_ptr > 0) {
+
+ tmp_arr = channel->reserve_arr;
+ channel->reserve_arr = channel->free_arr;
+ channel->free_arr = tmp_arr;
+ channel->reserve_ptr = channel->length;
+ channel->reserve_top = channel->free_ptr;
+ channel->free_ptr = channel->length;
+
+ channel->stats->reserve_free_swaps_cnt++;
+
+ goto _alloc_after_swap;
+ }
+
+ channel->stats->full_cnt++;
+
+ *dtrh = NULL;
+ return VXGE_HW_INF_OUT_OF_DESCRIPTORS;
+}
+
+/*
+ * vxge_hw_channel_dtr_post - Post a dtr to the channel
+ * @channelh: Channel
+ * @dtrh: DTR pointer
+ *
+ * Posts a dtr to work array.
+ *
+ */
+void vxge_hw_channel_dtr_post(struct __vxge_hw_channel *channel, void *dtrh)
+{
+ vxge_assert(channel->work_arr[channel->post_index] == NULL);
+
+ channel->work_arr[channel->post_index++] = dtrh;
+
+ /* wrap-around */
+ if (channel->post_index == channel->length)
+ channel->post_index = 0;
+}
+
+/*
+ * vxge_hw_channel_dtr_try_complete - Returns next completed dtr
+ * @channel: Channel
+ * @dtr: Buffer to return the next completed DTR pointer
+ *
+ * Returns the next completed dtr with out removing it from work array
+ *
+ */
+void
+vxge_hw_channel_dtr_try_complete(struct __vxge_hw_channel *channel, void **dtrh)
+{
+ vxge_assert(channel->compl_index < channel->length);
+
+ *dtrh = channel->work_arr[channel->compl_index];
+}
+
+/*
+ * vxge_hw_channel_dtr_complete - Removes next completed dtr from the work array
+ * @channel: Channel handle
+ *
+ * Removes the next completed dtr from work array
+ *
+ */
+void vxge_hw_channel_dtr_complete(struct __vxge_hw_channel *channel)
+{
+ channel->work_arr[channel->compl_index] = NULL;
+
+ /* wrap-around */
+ if (++channel->compl_index == channel->length)
+ channel->compl_index = 0;
+
+ channel->stats->total_compl_cnt++;
+}
+
+/*
+ * vxge_hw_channel_dtr_free - Frees a dtr
+ * @channel: Channel handle
+ * @dtr: DTR pointer
+ *
+ * Returns the dtr to free array
+ *
+ */
+void vxge_hw_channel_dtr_free(struct __vxge_hw_channel *channel, void *dtrh)
+{
+ channel->free_arr[--channel->free_ptr] = dtrh;
+}
+
+/*
+ * vxge_hw_channel_dtr_count
+ * @channel: Channel handle. Obtained via vxge_hw_channel_open().
+ *
+ * Retreive number of DTRs available. This function can not be called
+ * from data path. ring_initial_replenishi() is the only user.
+ */
+int vxge_hw_channel_dtr_count(struct __vxge_hw_channel *channel)
+{
+ return (channel->reserve_ptr - channel->reserve_top) +
+ (channel->length - channel->free_ptr);
+}
+
+/**
+ * vxge_hw_ring_rxd_reserve - Reserve ring descriptor.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Reserved descriptor. On success HW fills this "out" parameter
+ * with a valid handle.
+ *
+ * Reserve Rx descriptor for the subsequent filling-in driver
+ * and posting on the corresponding channel (@channelh)
+ * via vxge_hw_ring_rxd_post().
+ *
+ * Returns: VXGE_HW_OK - success.
+ * VXGE_HW_INF_OUT_OF_DESCRIPTORS - Currently no descriptors available.
+ *
+ */
+enum vxge_hw_status vxge_hw_ring_rxd_reserve(struct __vxge_hw_ring *ring,
+ void **rxdh)
+{
+ enum vxge_hw_status status;
+ struct __vxge_hw_channel *channel;
+
+ channel = &ring->channel;
+
+ status = vxge_hw_channel_dtr_alloc(channel, rxdh);
+
+ if (status == VXGE_HW_OK) {
+ struct vxge_hw_ring_rxd_1 *rxdp =
+ (struct vxge_hw_ring_rxd_1 *)*rxdh;
+
+ rxdp->control_0 = rxdp->control_1 = 0;
+ }
+
+ return status;
+}
+
+/**
+ * vxge_hw_ring_rxd_free - Free descriptor.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor handle.
+ *
+ * Free the reserved descriptor. This operation is "symmetrical" to
+ * vxge_hw_ring_rxd_reserve. The "free-ing" completes the descriptor's
+ * lifecycle.
+ *
+ * After free-ing (see vxge_hw_ring_rxd_free()) the descriptor again can
+ * be:
+ *
+ * - reserved (vxge_hw_ring_rxd_reserve);
+ *
+ * - posted (vxge_hw_ring_rxd_post);
+ *
+ * - completed (vxge_hw_ring_rxd_next_completed);
+ *
+ * - and recycled again (vxge_hw_ring_rxd_free).
+ *
+ * For alternative state transitions and more details please refer to
+ * the design doc.
+ *
+ */
+void vxge_hw_ring_rxd_free(struct __vxge_hw_ring *ring, void *rxdh)
+{
+ struct __vxge_hw_channel *channel;
+
+ channel = &ring->channel;
+
+ vxge_hw_channel_dtr_free(channel, rxdh);
+
+}
+
+/**
+ * vxge_hw_ring_rxd_pre_post - Prepare rxd and post
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor handle.
+ *
+ * This routine prepares a rxd and posts
+ */
+void vxge_hw_ring_rxd_pre_post(struct __vxge_hw_ring *ring, void *rxdh)
+{
+ struct __vxge_hw_channel *channel;
+
+ channel = &ring->channel;
+
+ vxge_hw_channel_dtr_post(channel, rxdh);
+}
+
+/**
+ * vxge_hw_ring_rxd_post_post - Process rxd after post.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor handle.
+ *
+ * Processes rxd after post
+ */
+void vxge_hw_ring_rxd_post_post(struct __vxge_hw_ring *ring, void *rxdh)
+{
+ struct vxge_hw_ring_rxd_1 *rxdp = (struct vxge_hw_ring_rxd_1 *)rxdh;
+ struct __vxge_hw_channel *channel;
+
+ channel = &ring->channel;
+
+ rxdp->control_0 |= VXGE_HW_RING_RXD_LIST_OWN_ADAPTER;
+
+ if (ring->stats->common_stats.usage_cnt > 0)
+ ring->stats->common_stats.usage_cnt--;
+}
+
+/**
+ * vxge_hw_ring_rxd_post - Post descriptor on the ring.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor obtained via vxge_hw_ring_rxd_reserve().
+ *
+ * Post descriptor on the ring.
+ * Prior to posting the descriptor should be filled in accordance with
+ * Host/Titan interface specification for a given service (LL, etc.).
+ *
+ */
+void vxge_hw_ring_rxd_post(struct __vxge_hw_ring *ring, void *rxdh)
+{
+ struct vxge_hw_ring_rxd_1 *rxdp = (struct vxge_hw_ring_rxd_1 *)rxdh;
+ struct __vxge_hw_channel *channel;
+
+ channel = &ring->channel;
+
+ wmb();
+ rxdp->control_0 |= VXGE_HW_RING_RXD_LIST_OWN_ADAPTER;
+
+ vxge_hw_channel_dtr_post(channel, rxdh);
+
+ if (ring->stats->common_stats.usage_cnt > 0)
+ ring->stats->common_stats.usage_cnt--;
+}
+
+/**
+ * vxge_hw_ring_rxd_post_post_wmb - Process rxd after post with memory barrier.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor handle.
+ *
+ * Processes rxd after post with memory barrier.
+ */
+void vxge_hw_ring_rxd_post_post_wmb(struct __vxge_hw_ring *ring, void *rxdh)
+{
+ struct __vxge_hw_channel *channel;
+
+ channel = &ring->channel;
+
+ wmb();
+ vxge_hw_ring_rxd_post_post(ring, rxdh);
+}
+
+/**
+ * vxge_hw_ring_rxd_next_completed - Get the _next_ completed descriptor.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor handle. Returned by HW.
+ * @t_code: Transfer code, as per Titan User Guide,
+ * Receive Descriptor Format. Returned by HW.
+ *
+ * Retrieve the _next_ completed descriptor.
+ * HW uses ring callback (*vxge_hw_ring_callback_f) to notifiy
+ * driver of new completed descriptors. After that
+ * the driver can use vxge_hw_ring_rxd_next_completed to retrieve the rest
+ * completions (the very first completion is passed by HW via
+ * vxge_hw_ring_callback_f).
+ *
+ * Implementation-wise, the driver is free to call
+ * vxge_hw_ring_rxd_next_completed either immediately from inside the
+ * ring callback, or in a deferred fashion and separate (from HW)
+ * context.
+ *
+ * Non-zero @t_code means failure to fill-in receive buffer(s)
+ * of the descriptor.
+ * For instance, parity error detected during the data transfer.
+ * In this case Titan will complete the descriptor and indicate
+ * for the host that the received data is not to be used.
+ * For details please refer to Titan User Guide.
+ *
+ * Returns: VXGE_HW_OK - success.
+ * VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS - No completed descriptors
+ * are currently available for processing.
+ *
+ * See also: vxge_hw_ring_callback_f{},
+ * vxge_hw_fifo_rxd_next_completed(), enum vxge_hw_status{}.
+ */
+enum vxge_hw_status vxge_hw_ring_rxd_next_completed(
+ struct __vxge_hw_ring *ring, void **rxdh, u8 *t_code)
+{
+ struct __vxge_hw_channel *channel;
+ struct vxge_hw_ring_rxd_1 *rxdp;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ channel = &ring->channel;
+
+ vxge_hw_channel_dtr_try_complete(channel, rxdh);
+
+ rxdp = (struct vxge_hw_ring_rxd_1 *)*rxdh;
+ if (rxdp == NULL) {
+ status = VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS;
+ goto exit;
+ }
+
+ /* check whether it is not the end */
+ if (!(rxdp->control_0 & VXGE_HW_RING_RXD_LIST_OWN_ADAPTER)) {
+
+ vxge_assert(((struct vxge_hw_ring_rxd_1 *)rxdp)->host_control !=
+ 0);
+
+ ++ring->cmpl_cnt;
+ vxge_hw_channel_dtr_complete(channel);
+
+ *t_code = (u8)VXGE_HW_RING_RXD_T_CODE_GET(rxdp->control_0);
+
+ vxge_assert(*t_code != VXGE_HW_RING_RXD_T_CODE_UNUSED);
+
+ ring->stats->common_stats.usage_cnt++;
+ if (ring->stats->common_stats.usage_max <
+ ring->stats->common_stats.usage_cnt)
+ ring->stats->common_stats.usage_max =
+ ring->stats->common_stats.usage_cnt;
+
+ status = VXGE_HW_OK;
+ goto exit;
+ }
+
+ /* reset it. since we don't want to return
+ * garbage to the driver */
+ *rxdh = NULL;
+ status = VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS;
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_ring_handle_tcode - Handle transfer code.
+ * @ring: Handle to the ring object used for receive
+ * @rxdh: Descriptor handle.
+ * @t_code: One of the enumerated (and documented in the Titan user guide)
+ * "transfer codes".
+ *
+ * Handle descriptor's transfer code. The latter comes with each completed
+ * descriptor.
+ *
+ * Returns: one of the enum vxge_hw_status{} enumerated types.
+ * VXGE_HW_OK - for success.
+ * VXGE_HW_ERR_CRITICAL - when encounters critical error.
+ */
+enum vxge_hw_status vxge_hw_ring_handle_tcode(
+ struct __vxge_hw_ring *ring, void *rxdh, u8 t_code)
+{
+ struct __vxge_hw_channel *channel;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ channel = &ring->channel;
+
+ /* If the t_code is not supported and if the
+ * t_code is other than 0x5 (unparseable packet
+ * such as unknown UPV6 header), Drop it !!!
+ */
+
+ if (t_code == 0 || t_code == 5) {
+ status = VXGE_HW_OK;
+ goto exit;
+ }
+
+ if (t_code > 0xF) {
+ status = VXGE_HW_ERR_INVALID_TCODE;
+ goto exit;
+ }
+
+ ring->stats->rxd_t_code_err_cnt[t_code]++;
+exit:
+ return status;
+}
+
+/**
+ * __vxge_hw_non_offload_db_post - Post non offload doorbell
+ *
+ * @fifo: fifohandle
+ * @txdl_ptr: The starting location of the TxDL in host memory
+ * @num_txds: The highest TxD in this TxDL (0 to 255 means 1 to 256)
+ * @no_snoop: No snoop flags
+ *
+ * This function posts a non-offload doorbell to doorbell FIFO
+ *
+ */
+static void __vxge_hw_non_offload_db_post(struct __vxge_hw_fifo *fifo,
+ u64 txdl_ptr, u32 num_txds, u32 no_snoop)
+{
+ struct __vxge_hw_channel *channel;
+
+ channel = &fifo->channel;
+
+ writeq(VXGE_HW_NODBW_TYPE(VXGE_HW_NODBW_TYPE_NODBW) |
+ VXGE_HW_NODBW_LAST_TXD_NUMBER(num_txds) |
+ VXGE_HW_NODBW_GET_NO_SNOOP(no_snoop),
+ &fifo->nofl_db->control_0);
+
+ wmb();
+
+ writeq(txdl_ptr, &fifo->nofl_db->txdl_ptr);
+ wmb();
+
+}
+
+/**
+ * vxge_hw_fifo_free_txdl_count_get - returns the number of txdls available in
+ * the fifo
+ * @fifoh: Handle to the fifo object used for non offload send
+ */
+u32 vxge_hw_fifo_free_txdl_count_get(struct __vxge_hw_fifo *fifoh)
+{
+ return vxge_hw_channel_dtr_count(&fifoh->channel);
+}
+
+/**
+ * vxge_hw_fifo_txdl_reserve - Reserve fifo descriptor.
+ * @fifoh: Handle to the fifo object used for non offload send
+ * @txdlh: Reserved descriptor. On success HW fills this "out" parameter
+ * with a valid handle.
+ * @txdl_priv: Buffer to return the pointer to per txdl space
+ *
+ * Reserve a single TxDL (that is, fifo descriptor)
+ * for the subsequent filling-in by driver)
+ * and posting on the corresponding channel (@channelh)
+ * via vxge_hw_fifo_txdl_post().
+ *
+ * Note: it is the responsibility of driver to reserve multiple descriptors
+ * for lengthy (e.g., LSO) transmit operation. A single fifo descriptor
+ * carries up to configured number (fifo.max_frags) of contiguous buffers.
+ *
+ * Returns: VXGE_HW_OK - success;
+ * VXGE_HW_INF_OUT_OF_DESCRIPTORS - Currently no descriptors available
+ *
+ */
+enum vxge_hw_status vxge_hw_fifo_txdl_reserve(
+ struct __vxge_hw_fifo *fifo,
+ void **txdlh, void **txdl_priv)
+{
+ struct __vxge_hw_channel *channel;
+ enum vxge_hw_status status;
+ int i;
+
+ channel = &fifo->channel;
+
+ status = vxge_hw_channel_dtr_alloc(channel, txdlh);
+
+ if (status == VXGE_HW_OK) {
+ struct vxge_hw_fifo_txd *txdp =
+ (struct vxge_hw_fifo_txd *)*txdlh;
+ struct __vxge_hw_fifo_txdl_priv *priv;
+
+ priv = __vxge_hw_fifo_txdl_priv(fifo, txdp);
+
+ /* reset the TxDL's private */
+ priv->align_dma_offset = 0;
+ priv->align_vaddr_start = priv->align_vaddr;
+ priv->align_used_frags = 0;
+ priv->frags = 0;
+ priv->alloc_frags = fifo->config->max_frags;
+ priv->next_txdl_priv = NULL;
+
+ *txdl_priv = (void *)(size_t)txdp->host_control;
+
+ for (i = 0; i < fifo->config->max_frags; i++) {
+ txdp = ((struct vxge_hw_fifo_txd *)*txdlh) + i;
+ txdp->control_0 = txdp->control_1 = 0;
+ }
+ }
+
+ return status;
+}
+
+/**
+ * vxge_hw_fifo_txdl_buffer_set - Set transmit buffer pointer in the
+ * descriptor.
+ * @fifo: Handle to the fifo object used for non offload send
+ * @txdlh: Descriptor handle.
+ * @frag_idx: Index of the data buffer in the caller's scatter-gather list
+ * (of buffers).
+ * @dma_pointer: DMA address of the data buffer referenced by @frag_idx.
+ * @size: Size of the data buffer (in bytes).
+ *
+ * This API is part of the preparation of the transmit descriptor for posting
+ * (via vxge_hw_fifo_txdl_post()). The related "preparation" APIs include
+ * vxge_hw_fifo_txdl_mss_set() and vxge_hw_fifo_txdl_cksum_set_bits().
+ * All three APIs fill in the fields of the fifo descriptor,
+ * in accordance with the Titan specification.
+ *
+ */
+void vxge_hw_fifo_txdl_buffer_set(struct __vxge_hw_fifo *fifo,
+ void *txdlh, u32 frag_idx,
+ dma_addr_t dma_pointer, u32 size)
+{
+ struct __vxge_hw_fifo_txdl_priv *txdl_priv;
+ struct vxge_hw_fifo_txd *txdp, *txdp_last;
+ struct __vxge_hw_channel *channel;
+
+ channel = &fifo->channel;
+
+ txdl_priv = __vxge_hw_fifo_txdl_priv(fifo, txdlh);
+ txdp = (struct vxge_hw_fifo_txd *)txdlh + txdl_priv->frags;
+
+ if (frag_idx != 0)
+ txdp->control_0 = txdp->control_1 = 0;
+ else {
+ txdp->control_0 |= VXGE_HW_FIFO_TXD_GATHER_CODE(
+ VXGE_HW_FIFO_TXD_GATHER_CODE_FIRST);
+ txdp->control_1 |= fifo->interrupt_type;
+ txdp->control_1 |= VXGE_HW_FIFO_TXD_INT_NUMBER(
+ fifo->tx_intr_num);
+ if (txdl_priv->frags) {
+ txdp_last = (struct vxge_hw_fifo_txd *)txdlh +
+ (txdl_priv->frags - 1);
+ txdp_last->control_0 |= VXGE_HW_FIFO_TXD_GATHER_CODE(
+ VXGE_HW_FIFO_TXD_GATHER_CODE_LAST);
+ }
+ }
+
+ vxge_assert(frag_idx < txdl_priv->alloc_frags);
+
+ txdp->buffer_pointer = (u64)dma_pointer;
+ txdp->control_0 |= VXGE_HW_FIFO_TXD_BUFFER_SIZE(size);
+ fifo->stats->total_buffers++;
+ txdl_priv->frags++;
+}
+
+/**
+ * vxge_hw_fifo_txdl_post - Post descriptor on the fifo channel.
+ * @fifo: Handle to the fifo object used for non offload send
+ * @txdlh: Descriptor obtained via vxge_hw_fifo_txdl_reserve()
+ * @frags: Number of contiguous buffers that are part of a single
+ * transmit operation.
+ *
+ * Post descriptor on the 'fifo' type channel for transmission.
+ * Prior to posting the descriptor should be filled in accordance with
+ * Host/Titan interface specification for a given service (LL, etc.).
+ *
+ */
+void vxge_hw_fifo_txdl_post(struct __vxge_hw_fifo *fifo, void *txdlh)
+{
+ struct __vxge_hw_fifo_txdl_priv *txdl_priv;
+ struct vxge_hw_fifo_txd *txdp_last;
+ struct vxge_hw_fifo_txd *txdp_first;
+ struct __vxge_hw_channel *channel;
+
+ channel = &fifo->channel;
+
+ txdl_priv = __vxge_hw_fifo_txdl_priv(fifo, txdlh);
+ txdp_first = (struct vxge_hw_fifo_txd *)txdlh;
+
+ txdp_last = (struct vxge_hw_fifo_txd *)txdlh + (txdl_priv->frags - 1);
+ txdp_last->control_0 |=
+ VXGE_HW_FIFO_TXD_GATHER_CODE(VXGE_HW_FIFO_TXD_GATHER_CODE_LAST);
+ txdp_first->control_0 |= VXGE_HW_FIFO_TXD_LIST_OWN_ADAPTER;
+
+ vxge_hw_channel_dtr_post(&fifo->channel, txdlh);
+
+ __vxge_hw_non_offload_db_post(fifo,
+ (u64)(size_t)txdl_priv->dma_addr,
+ txdl_priv->frags - 1,
+ fifo->no_snoop_bits);
+
+ fifo->stats->total_posts++;
+ fifo->stats->common_stats.usage_cnt++;
+ if (fifo->stats->common_stats.usage_max <
+ fifo->stats->common_stats.usage_cnt)
+ fifo->stats->common_stats.usage_max =
+ fifo->stats->common_stats.usage_cnt;
+}
+
+/**
+ * vxge_hw_fifo_txdl_next_completed - Retrieve next completed descriptor.
+ * @fifo: Handle to the fifo object used for non offload send
+ * @txdlh: Descriptor handle. Returned by HW.
+ * @t_code: Transfer code, as per Titan User Guide,
+ * Transmit Descriptor Format.
+ * Returned by HW.
+ *
+ * Retrieve the _next_ completed descriptor.
+ * HW uses channel callback (*vxge_hw_channel_callback_f) to notifiy
+ * driver of new completed descriptors. After that
+ * the driver can use vxge_hw_fifo_txdl_next_completed to retrieve the rest
+ * completions (the very first completion is passed by HW via
+ * vxge_hw_channel_callback_f).
+ *
+ * Implementation-wise, the driver is free to call
+ * vxge_hw_fifo_txdl_next_completed either immediately from inside the
+ * channel callback, or in a deferred fashion and separate (from HW)
+ * context.
+ *
+ * Non-zero @t_code means failure to process the descriptor.
+ * The failure could happen, for instance, when the link is
+ * down, in which case Titan completes the descriptor because it
+ * is not able to send the data out.
+ *
+ * For details please refer to Titan User Guide.
+ *
+ * Returns: VXGE_HW_OK - success.
+ * VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS - No completed descriptors
+ * are currently available for processing.
+ *
+ */
+enum vxge_hw_status vxge_hw_fifo_txdl_next_completed(
+ struct __vxge_hw_fifo *fifo, void **txdlh,
+ enum vxge_hw_fifo_tcode *t_code)
+{
+ struct __vxge_hw_channel *channel;
+ struct vxge_hw_fifo_txd *txdp;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ channel = &fifo->channel;
+
+ vxge_hw_channel_dtr_try_complete(channel, txdlh);
+
+ txdp = (struct vxge_hw_fifo_txd *)*txdlh;
+ if (txdp == NULL) {
+ status = VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS;
+ goto exit;
+ }
+
+ /* check whether host owns it */
+ if (!(txdp->control_0 & VXGE_HW_FIFO_TXD_LIST_OWN_ADAPTER)) {
+
+ vxge_assert(txdp->host_control != 0);
+
+ vxge_hw_channel_dtr_complete(channel);
+
+ *t_code = (u8)VXGE_HW_FIFO_TXD_T_CODE_GET(txdp->control_0);
+
+ if (fifo->stats->common_stats.usage_cnt > 0)
+ fifo->stats->common_stats.usage_cnt--;
+
+ status = VXGE_HW_OK;
+ goto exit;
+ }
+
+ /* no more completions */
+ *txdlh = NULL;
+ status = VXGE_HW_INF_NO_MORE_COMPLETED_DESCRIPTORS;
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_fifo_handle_tcode - Handle transfer code.
+ * @fifo: Handle to the fifo object used for non offload send
+ * @txdlh: Descriptor handle.
+ * @t_code: One of the enumerated (and documented in the Titan user guide)
+ * "transfer codes".
+ *
+ * Handle descriptor's transfer code. The latter comes with each completed
+ * descriptor.
+ *
+ * Returns: one of the enum vxge_hw_status{} enumerated types.
+ * VXGE_HW_OK - for success.
+ * VXGE_HW_ERR_CRITICAL - when encounters critical error.
+ */
+enum vxge_hw_status vxge_hw_fifo_handle_tcode(struct __vxge_hw_fifo *fifo,
+ void *txdlh,
+ enum vxge_hw_fifo_tcode t_code)
+{
+ struct __vxge_hw_channel *channel;
+
+ enum vxge_hw_status status = VXGE_HW_OK;
+ channel = &fifo->channel;
+
+ if (((t_code & 0x7) < 0) || ((t_code & 0x7) > 0x4)) {
+ status = VXGE_HW_ERR_INVALID_TCODE;
+ goto exit;
+ }
+
+ fifo->stats->txd_t_code_err_cnt[t_code]++;
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_fifo_txdl_free - Free descriptor.
+ * @fifo: Handle to the fifo object used for non offload send
+ * @txdlh: Descriptor handle.
+ *
+ * Free the reserved descriptor. This operation is "symmetrical" to
+ * vxge_hw_fifo_txdl_reserve. The "free-ing" completes the descriptor's
+ * lifecycle.
+ *
+ * After free-ing (see vxge_hw_fifo_txdl_free()) the descriptor again can
+ * be:
+ *
+ * - reserved (vxge_hw_fifo_txdl_reserve);
+ *
+ * - posted (vxge_hw_fifo_txdl_post);
+ *
+ * - completed (vxge_hw_fifo_txdl_next_completed);
+ *
+ * - and recycled again (vxge_hw_fifo_txdl_free).
+ *
+ * For alternative state transitions and more details please refer to
+ * the design doc.
+ *
+ */
+void vxge_hw_fifo_txdl_free(struct __vxge_hw_fifo *fifo, void *txdlh)
+{
+ struct __vxge_hw_fifo_txdl_priv *txdl_priv;
+ u32 max_frags;
+ struct __vxge_hw_channel *channel;
+
+ channel = &fifo->channel;
+
+ txdl_priv = __vxge_hw_fifo_txdl_priv(fifo,
+ (struct vxge_hw_fifo_txd *)txdlh);
+
+ max_frags = fifo->config->max_frags;
+
+ vxge_hw_channel_dtr_free(channel, txdlh);
+}
+
+/**
+ * vxge_hw_vpath_mac_addr_add - Add the mac address entry for this vpath
+ * to MAC address table.
+ * @vp: Vpath handle.
+ * @macaddr: MAC address to be added for this vpath into the list
+ * @macaddr_mask: MAC address mask for macaddr
+ * @duplicate_mode: Duplicate MAC address add mode. Please see
+ * enum vxge_hw_vpath_mac_addr_add_mode{}
+ *
+ * Adds the given mac address and mac address mask into the list for this
+ * vpath.
+ * see also: vxge_hw_vpath_mac_addr_delete, vxge_hw_vpath_mac_addr_get and
+ * vxge_hw_vpath_mac_addr_get_next
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_add(
+ struct __vxge_hw_vpath_handle *vp,
+ u8 (macaddr)[ETH_ALEN],
+ u8 (macaddr_mask)[ETH_ALEN],
+ enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode)
+{
+ u32 i;
+ u64 data1 = 0ULL;
+ u64 data2 = 0ULL;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ for (i = 0; i < ETH_ALEN; i++) {
+ data1 <<= 8;
+ data1 |= (u8)macaddr[i];
+
+ data2 <<= 8;
+ data2 |= (u8)macaddr_mask[i];
+ }
+
+ switch (duplicate_mode) {
+ case VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE:
+ i = 0;
+ break;
+ case VXGE_HW_VPATH_MAC_ADDR_DISCARD_DUPLICATE:
+ i = 1;
+ break;
+ case VXGE_HW_VPATH_MAC_ADDR_REPLACE_DUPLICATE:
+ i = 2;
+ break;
+ default:
+ i = 0;
+ break;
+ }
+
+ status = __vxge_hw_vpath_rts_table_set(vp,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_ADD_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA,
+ 0,
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_DA_MAC_ADDR(data1),
+ VXGE_HW_RTS_ACCESS_STEER_DATA1_DA_MAC_ADDR_MASK(data2)|
+ VXGE_HW_RTS_ACCESS_STEER_DATA1_DA_MAC_ADDR_MODE(i));
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_mac_addr_get - Get the first mac address entry for this vpath
+ * from MAC address table.
+ * @vp: Vpath handle.
+ * @macaddr: First MAC address entry for this vpath in the list
+ * @macaddr_mask: MAC address mask for macaddr
+ *
+ * Returns the first mac address and mac address mask in the list for this
+ * vpath.
+ * see also: vxge_hw_vpath_mac_addr_get_next
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_get(
+ struct __vxge_hw_vpath_handle *vp,
+ u8 (macaddr)[ETH_ALEN],
+ u8 (macaddr_mask)[ETH_ALEN])
+{
+ u32 i;
+ u64 data1 = 0ULL;
+ u64 data2 = 0ULL;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ status = __vxge_hw_vpath_rts_table_get(vp,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA,
+ 0, &data1, &data2);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ data1 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data1);
+
+ data2 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(data2);
+
+ for (i = ETH_ALEN; i > 0; i--) {
+ macaddr[i-1] = (u8)(data1 & 0xFF);
+ data1 >>= 8;
+
+ macaddr_mask[i-1] = (u8)(data2 & 0xFF);
+ data2 >>= 8;
+ }
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_mac_addr_get_next - Get the next mac address entry for this
+ * vpath
+ * from MAC address table.
+ * @vp: Vpath handle.
+ * @macaddr: Next MAC address entry for this vpath in the list
+ * @macaddr_mask: MAC address mask for macaddr
+ *
+ * Returns the next mac address and mac address mask in the list for this
+ * vpath.
+ * see also: vxge_hw_vpath_mac_addr_get
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_get_next(
+ struct __vxge_hw_vpath_handle *vp,
+ u8 (macaddr)[ETH_ALEN],
+ u8 (macaddr_mask)[ETH_ALEN])
+{
+ u32 i;
+ u64 data1 = 0ULL;
+ u64 data2 = 0ULL;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ status = __vxge_hw_vpath_rts_table_get(vp,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_NEXT_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA,
+ 0, &data1, &data2);
+
+ if (status != VXGE_HW_OK)
+ goto exit;
+
+ data1 = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(data1);
+
+ data2 = VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_DA_MAC_ADDR_MASK(data2);
+
+ for (i = ETH_ALEN; i > 0; i--) {
+ macaddr[i-1] = (u8)(data1 & 0xFF);
+ data1 >>= 8;
+
+ macaddr_mask[i-1] = (u8)(data2 & 0xFF);
+ data2 >>= 8;
+ }
+
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_mac_addr_delete - Delete the mac address entry for this vpath
+ * to MAC address table.
+ * @vp: Vpath handle.
+ * @macaddr: MAC address to be added for this vpath into the list
+ * @macaddr_mask: MAC address mask for macaddr
+ *
+ * Delete the given mac address and mac address mask into the list for this
+ * vpath.
+ * see also: vxge_hw_vpath_mac_addr_add, vxge_hw_vpath_mac_addr_get and
+ * vxge_hw_vpath_mac_addr_get_next
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_delete(
+ struct __vxge_hw_vpath_handle *vp,
+ u8 (macaddr)[ETH_ALEN],
+ u8 (macaddr_mask)[ETH_ALEN])
+{
+ u32 i;
+ u64 data1 = 0ULL;
+ u64 data2 = 0ULL;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ for (i = 0; i < ETH_ALEN; i++) {
+ data1 <<= 8;
+ data1 |= (u8)macaddr[i];
+
+ data2 <<= 8;
+ data2 |= (u8)macaddr_mask[i];
+ }
+
+ status = __vxge_hw_vpath_rts_table_set(vp,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_DELETE_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DA,
+ 0,
+ VXGE_HW_RTS_ACCESS_STEER_DATA0_DA_MAC_ADDR(data1),
+ VXGE_HW_RTS_ACCESS_STEER_DATA1_DA_MAC_ADDR_MASK(data2));
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_vid_add - Add the vlan id entry for this vpath
+ * to vlan id table.
+ * @vp: Vpath handle.
+ * @vid: vlan id to be added for this vpath into the list
+ *
+ * Adds the given vlan id into the list for this vpath.
+ * see also: vxge_hw_vpath_vid_delete, vxge_hw_vpath_vid_get and
+ * vxge_hw_vpath_vid_get_next
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_vid_add(struct __vxge_hw_vpath_handle *vp, u64 vid)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ status = __vxge_hw_vpath_rts_table_set(vp,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_ADD_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID,
+ 0, VXGE_HW_RTS_ACCESS_STEER_DATA0_VLAN_ID(vid), 0);
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_vid_get - Get the first vid entry for this vpath
+ * from vlan id table.
+ * @vp: Vpath handle.
+ * @vid: Buffer to return vlan id
+ *
+ * Returns the first vlan id in the list for this vpath.
+ * see also: vxge_hw_vpath_vid_get_next
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_vid_get(struct __vxge_hw_vpath_handle *vp, u64 *vid)
+{
+ u64 data;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ status = __vxge_hw_vpath_rts_table_get(vp,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_FIRST_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID,
+ 0, vid, &data);
+
+ *vid = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_VLAN_ID(*vid);
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_vid_get_next - Get the next vid entry for this vpath
+ * from vlan id table.
+ * @vp: Vpath handle.
+ * @vid: Buffer to return vlan id
+ *
+ * Returns the next vlan id in the list for this vpath.
+ * see also: vxge_hw_vpath_vid_get
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_vid_get_next(struct __vxge_hw_vpath_handle *vp, u64 *vid)
+{
+ u64 data;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ status = __vxge_hw_vpath_rts_table_get(vp,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_LIST_NEXT_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID,
+ 0, vid, &data);
+
+ *vid = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_VLAN_ID(*vid);
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_vid_delete - Delete the vlan id entry for this vpath
+ * to vlan id table.
+ * @vp: Vpath handle.
+ * @vid: vlan id to be added for this vpath into the list
+ *
+ * Adds the given vlan id into the list for this vpath.
+ * see also: vxge_hw_vpath_vid_add, vxge_hw_vpath_vid_get and
+ * vxge_hw_vpath_vid_get_next
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_vid_delete(struct __vxge_hw_vpath_handle *vp, u64 vid)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ status = __vxge_hw_vpath_rts_table_set(vp,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_ACTION_DELETE_ENTRY,
+ VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_VID,
+ 0, VXGE_HW_RTS_ACCESS_STEER_DATA0_VLAN_ID(vid), 0);
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_promisc_enable - Enable promiscuous mode.
+ * @vp: Vpath handle.
+ *
+ * Enable promiscuous mode of Titan-e operation.
+ *
+ * See also: vxge_hw_vpath_promisc_disable().
+ */
+enum vxge_hw_status vxge_hw_vpath_promisc_enable(
+ struct __vxge_hw_vpath_handle *vp)
+{
+ u64 val64;
+ struct __vxge_hw_virtualpath *vpath;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if ((vp == NULL) || (vp->vpath->ringh == NULL)) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ vpath = vp->vpath;
+
+ /* Enable promiscous mode for function 0 only */
+ if (!(vpath->hldev->access_rights &
+ VXGE_HW_DEVICE_ACCESS_RIGHT_MRPCIM))
+ return VXGE_HW_OK;
+
+ val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
+
+ if (!(val64 & VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN)) {
+
+ val64 |= VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN |
+ VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN |
+ VXGE_HW_RXMAC_VCFG0_BCAST_EN |
+ VXGE_HW_RXMAC_VCFG0_ALL_VID_EN;
+
+ writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
+ }
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_promisc_disable - Disable promiscuous mode.
+ * @vp: Vpath handle.
+ *
+ * Disable promiscuous mode of Titan-e operation.
+ *
+ * See also: vxge_hw_vpath_promisc_enable().
+ */
+enum vxge_hw_status vxge_hw_vpath_promisc_disable(
+ struct __vxge_hw_vpath_handle *vp)
+{
+ u64 val64;
+ struct __vxge_hw_virtualpath *vpath;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if ((vp == NULL) || (vp->vpath->ringh == NULL)) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ vpath = vp->vpath;
+
+ val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
+
+ if (val64 & VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN) {
+
+ val64 &= ~(VXGE_HW_RXMAC_VCFG0_UCAST_ALL_ADDR_EN |
+ VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN |
+ VXGE_HW_RXMAC_VCFG0_ALL_VID_EN);
+
+ writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
+ }
+exit:
+ return status;
+}
+
+/*
+ * vxge_hw_vpath_bcast_enable - Enable broadcast
+ * @vp: Vpath handle.
+ *
+ * Enable receiving broadcasts.
+ */
+enum vxge_hw_status vxge_hw_vpath_bcast_enable(
+ struct __vxge_hw_vpath_handle *vp)
+{
+ u64 val64;
+ struct __vxge_hw_virtualpath *vpath;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if ((vp == NULL) || (vp->vpath->ringh == NULL)) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ vpath = vp->vpath;
+
+ val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
+
+ if (!(val64 & VXGE_HW_RXMAC_VCFG0_BCAST_EN)) {
+ val64 |= VXGE_HW_RXMAC_VCFG0_BCAST_EN;
+ writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
+ }
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_mcast_enable - Enable multicast addresses.
+ * @vp: Vpath handle.
+ *
+ * Enable Titan-e multicast addresses.
+ * Returns: VXGE_HW_OK on success.
+ *
+ */
+enum vxge_hw_status vxge_hw_vpath_mcast_enable(
+ struct __vxge_hw_vpath_handle *vp)
+{
+ u64 val64;
+ struct __vxge_hw_virtualpath *vpath;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if ((vp == NULL) || (vp->vpath->ringh == NULL)) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ vpath = vp->vpath;
+
+ val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
+
+ if (!(val64 & VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN)) {
+ val64 |= VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN;
+ writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
+ }
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_mcast_disable - Disable multicast addresses.
+ * @vp: Vpath handle.
+ *
+ * Disable Titan-e multicast addresses.
+ * Returns: VXGE_HW_OK - success.
+ * VXGE_HW_ERR_INVALID_HANDLE - Invalid handle
+ *
+ */
+enum vxge_hw_status
+vxge_hw_vpath_mcast_disable(struct __vxge_hw_vpath_handle *vp)
+{
+ u64 val64;
+ struct __vxge_hw_virtualpath *vpath;
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if ((vp == NULL) || (vp->vpath->ringh == NULL)) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ vpath = vp->vpath;
+
+ val64 = readq(&vpath->vp_reg->rxmac_vcfg0);
+
+ if (val64 & VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN) {
+ val64 &= ~VXGE_HW_RXMAC_VCFG0_MCAST_ALL_ADDR_EN;
+ writeq(val64, &vpath->vp_reg->rxmac_vcfg0);
+ }
+exit:
+ return status;
+}
+
+/*
+ * __vxge_hw_vpath_alarm_process - Process Alarms.
+ * @vpath: Virtual Path.
+ * @skip_alarms: Do not clear the alarms
+ *
+ * Process vpath alarms.
+ *
+ */
+enum vxge_hw_status __vxge_hw_vpath_alarm_process(
+ struct __vxge_hw_virtualpath *vpath,
+ u32 skip_alarms)
+{
+ u64 val64;
+ u64 alarm_status;
+ u64 pic_status;
+ struct __vxge_hw_device *hldev = NULL;
+ enum vxge_hw_event alarm_event = VXGE_HW_EVENT_UNKNOWN;
+ u64 mask64;
+ struct vxge_hw_vpath_stats_sw_info *sw_stats;
+ struct vxge_hw_vpath_reg __iomem *vp_reg;
+
+ if (vpath == NULL) {
+ alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN,
+ alarm_event);
+ goto out;
+ }
+
+ hldev = vpath->hldev;
+ vp_reg = vpath->vp_reg;
+ alarm_status = readq(&vp_reg->vpath_general_int_status);
+
+ if (alarm_status == VXGE_HW_ALL_FOXES) {
+ alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_SLOT_FREEZE,
+ alarm_event);
+ goto out;
+ }
+
+ sw_stats = vpath->sw_stats;
+
+ if (alarm_status & ~(
+ VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT |
+ VXGE_HW_VPATH_GENERAL_INT_STATUS_PCI_INT |
+ VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT |
+ VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT)) {
+ sw_stats->error_stats.unknown_alarms++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN,
+ alarm_event);
+ goto out;
+ }
+
+ if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_XMAC_INT) {
+
+ val64 = readq(&vp_reg->xgmac_vp_int_status);
+
+ if (val64 &
+ VXGE_HW_XGMAC_VP_INT_STATUS_ASIC_NTWK_VP_ERR_ASIC_NTWK_VP_INT) {
+
+ val64 = readq(&vp_reg->asic_ntwk_vp_err_reg);
+
+ if (((val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT) &&
+ (!(val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK))) ||
+ ((val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR)
+ && (!(val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR)
+ ))) {
+ sw_stats->error_stats.network_sustained_fault++;
+
+ writeq(
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT,
+ &vp_reg->asic_ntwk_vp_err_mask);
+
+ __vxge_hw_device_handle_link_down_ind(hldev);
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_LINK_DOWN, alarm_event);
+ }
+
+ if (((val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK) &&
+ (!(val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT))) ||
+ ((val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK_OCCURR)
+ && (!(val64 &
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_FLT_OCCURR)
+ ))) {
+
+ sw_stats->error_stats.network_sustained_ok++;
+
+ writeq(
+ VXGE_HW_ASIC_NW_VP_ERR_REG_XMACJ_STN_OK,
+ &vp_reg->asic_ntwk_vp_err_mask);
+
+ __vxge_hw_device_handle_link_up_ind(hldev);
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_LINK_UP, alarm_event);
+ }
+
+ writeq(VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->asic_ntwk_vp_err_reg);
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_ALARM_CLEARED, alarm_event);
+
+ if (skip_alarms)
+ return VXGE_HW_OK;
+ }
+ }
+
+ if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_PIC_INT) {
+
+ pic_status = readq(&vp_reg->vpath_ppif_int_status);
+
+ if (pic_status &
+ VXGE_HW_VPATH_PPIF_INT_STATUS_GENERAL_ERRORS_GENERAL_INT) {
+
+ val64 = readq(&vp_reg->general_errors_reg);
+ mask64 = readq(&vp_reg->general_errors_mask);
+
+ if ((val64 &
+ VXGE_HW_GENERAL_ERRORS_REG_INI_SERR_DET) &
+ ~mask64) {
+ sw_stats->error_stats.ini_serr_det++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_SERR, alarm_event);
+ }
+
+ if ((val64 &
+ VXGE_HW_GENERAL_ERRORS_REG_DBLGEN_FIFO0_OVRFLOW) &
+ ~mask64) {
+ sw_stats->error_stats.dblgen_fifo0_overflow++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_FIFO_ERR, alarm_event);
+ }
+
+ if ((val64 &
+ VXGE_HW_GENERAL_ERRORS_REG_STATSB_PIF_CHAIN_ERR) &
+ ~mask64)
+ sw_stats->error_stats.statsb_pif_chain_error++;
+
+ if ((val64 &
+ VXGE_HW_GENERAL_ERRORS_REG_STATSB_DROP_TIMEOUT_REQ) &
+ ~mask64)
+ sw_stats->error_stats.statsb_drop_timeout++;
+
+ if ((val64 &
+ VXGE_HW_GENERAL_ERRORS_REG_TGT_ILLEGAL_ACCESS) &
+ ~mask64)
+ sw_stats->error_stats.target_illegal_access++;
+
+ if (!skip_alarms) {
+ writeq(VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->general_errors_reg);
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_ALARM_CLEARED,
+ alarm_event);
+ }
+ }
+
+ if (pic_status &
+ VXGE_HW_VPATH_PPIF_INT_STATUS_KDFCCTL_ERRORS_KDFCCTL_INT) {
+
+ val64 = readq(&vp_reg->kdfcctl_errors_reg);
+ mask64 = readq(&vp_reg->kdfcctl_errors_mask);
+
+ if ((val64 &
+ VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_OVRWR) &
+ ~mask64) {
+ sw_stats->error_stats.kdfcctl_fifo0_overwrite++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_FIFO_ERR,
+ alarm_event);
+ }
+
+ if ((val64 &
+ VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_POISON) &
+ ~mask64) {
+ sw_stats->error_stats.kdfcctl_fifo0_poison++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_FIFO_ERR,
+ alarm_event);
+ }
+
+ if ((val64 &
+ VXGE_HW_KDFCCTL_ERRORS_REG_KDFCCTL_FIFO0_DMA_ERR) &
+ ~mask64) {
+ sw_stats->error_stats.kdfcctl_fifo0_dma_error++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_FIFO_ERR,
+ alarm_event);
+ }
+
+ if (!skip_alarms) {
+ writeq(VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->kdfcctl_errors_reg);
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_ALARM_CLEARED,
+ alarm_event);
+ }
+ }
+
+ }
+
+ if (alarm_status & VXGE_HW_VPATH_GENERAL_INT_STATUS_WRDMA_INT) {
+
+ val64 = readq(&vp_reg->wrdma_alarm_status);
+
+ if (val64 & VXGE_HW_WRDMA_ALARM_STATUS_PRC_ALARM_PRC_INT) {
+
+ val64 = readq(&vp_reg->prc_alarm_reg);
+ mask64 = readq(&vp_reg->prc_alarm_mask);
+
+ if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RING_BUMP)&
+ ~mask64)
+ sw_stats->error_stats.prc_ring_bumps++;
+
+ if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ERR) &
+ ~mask64) {
+ sw_stats->error_stats.prc_rxdcm_sc_err++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_VPATH_ERR,
+ alarm_event);
+ }
+
+ if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_RXDCM_SC_ABORT)
+ & ~mask64) {
+ sw_stats->error_stats.prc_rxdcm_sc_abort++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_VPATH_ERR,
+ alarm_event);
+ }
+
+ if ((val64 & VXGE_HW_PRC_ALARM_REG_PRC_QUANTA_SIZE_ERR)
+ & ~mask64) {
+ sw_stats->error_stats.prc_quanta_size_err++;
+
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_VPATH_ERR,
+ alarm_event);
+ }
+
+ if (!skip_alarms) {
+ writeq(VXGE_HW_INTR_MASK_ALL,
+ &vp_reg->prc_alarm_reg);
+ alarm_event = VXGE_HW_SET_LEVEL(
+ VXGE_HW_EVENT_ALARM_CLEARED,
+ alarm_event);
+ }
+ }
+ }
+out:
+ hldev->stats.sw_dev_err_stats.vpath_alarms++;
+
+ if ((alarm_event == VXGE_HW_EVENT_ALARM_CLEARED) ||
+ (alarm_event == VXGE_HW_EVENT_UNKNOWN))
+ return VXGE_HW_OK;
+
+ __vxge_hw_device_handle_error(hldev, vpath->vp_id, alarm_event);
+
+ if (alarm_event == VXGE_HW_EVENT_SERR)
+ return VXGE_HW_ERR_CRITICAL;
+
+ return (alarm_event == VXGE_HW_EVENT_SLOT_FREEZE) ?
+ VXGE_HW_ERR_SLOT_FREEZE :
+ (alarm_event == VXGE_HW_EVENT_FIFO_ERR) ? VXGE_HW_ERR_FIFO :
+ VXGE_HW_ERR_VPATH;
+}
+
+/*
+ * vxge_hw_vpath_alarm_process - Process Alarms.
+ * @vpath: Virtual Path.
+ * @skip_alarms: Do not clear the alarms
+ *
+ * Process vpath alarms.
+ *
+ */
+enum vxge_hw_status vxge_hw_vpath_alarm_process(
+ struct __vxge_hw_vpath_handle *vp,
+ u32 skip_alarms)
+{
+ enum vxge_hw_status status = VXGE_HW_OK;
+
+ if (vp == NULL) {
+ status = VXGE_HW_ERR_INVALID_HANDLE;
+ goto exit;
+ }
+
+ status = __vxge_hw_vpath_alarm_process(vp->vpath, skip_alarms);
+exit:
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_msix_set - Associate MSIX vectors with TIM interrupts and
+ * alrms
+ * @vp: Virtual Path handle.
+ * @tim_msix_id: MSIX vectors associated with VXGE_HW_MAX_INTR_PER_VP number of
+ * interrupts(Can be repeated). If fifo or ring are not enabled
+ * the MSIX vector for that should be set to 0
+ * @alarm_msix_id: MSIX vector for alarm.
+ *
+ * This API will associate a given MSIX vector numbers with the four TIM
+ * interrupts and alarm interrupt.
+ */
+enum vxge_hw_status
+vxge_hw_vpath_msix_set(struct __vxge_hw_vpath_handle *vp, int *tim_msix_id,
+ int alarm_msix_id)
+{
+ u64 val64;
+ struct __vxge_hw_virtualpath *vpath = vp->vpath;
+ struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg;
+ u32 first_vp_id = vpath->hldev->first_vp_id;
+
+ val64 = VXGE_HW_INTERRUPT_CFG0_GROUP0_MSIX_FOR_TXTI(
+ (first_vp_id * 4) + tim_msix_id[0]) |
+ VXGE_HW_INTERRUPT_CFG0_GROUP1_MSIX_FOR_TXTI(
+ (first_vp_id * 4) + tim_msix_id[1]) |
+ VXGE_HW_INTERRUPT_CFG0_GROUP2_MSIX_FOR_TXTI(
+ (first_vp_id * 4) + tim_msix_id[2]);
+
+ val64 |= VXGE_HW_INTERRUPT_CFG0_GROUP3_MSIX_FOR_TXTI(
+ (first_vp_id * 4) + tim_msix_id[3]);
+
+ writeq(val64, &vp_reg->interrupt_cfg0);
+
+ writeq(VXGE_HW_INTERRUPT_CFG2_ALARM_MAP_TO_MSG(
+ (first_vp_id * 4) + alarm_msix_id),
+ &vp_reg->interrupt_cfg2);
+
+ if (vpath->hldev->config.intr_mode ==
+ VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) {
+ __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(
+ VXGE_HW_ONE_SHOT_VECT1_EN_ONE_SHOT_VECT1_EN,
+ 0, 32), &vp_reg->one_shot_vect1_en);
+ }
+
+ if (vpath->hldev->config.intr_mode ==
+ VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) {
+ __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(
+ VXGE_HW_ONE_SHOT_VECT2_EN_ONE_SHOT_VECT2_EN,
+ 0, 32), &vp_reg->one_shot_vect2_en);
+
+ __vxge_hw_pio_mem_write32_upper((u32)vxge_bVALn(
+ VXGE_HW_ONE_SHOT_VECT3_EN_ONE_SHOT_VECT3_EN,
+ 0, 32), &vp_reg->one_shot_vect3_en);
+ }
+
+ return VXGE_HW_OK;
+}
+
+/**
+ * vxge_hw_vpath_msix_mask - Mask MSIX Vector.
+ * @vp: Virtual Path handle.
+ * @msix_id: MSIX ID
+ *
+ * The function masks the msix interrupt for the given msix_id
+ *
+ * Returns: 0,
+ * Otherwise, VXGE_HW_ERR_WRONG_IRQ if the msix index is out of range
+ * status.
+ * See also:
+ */
+void
+vxge_hw_vpath_msix_mask(struct __vxge_hw_vpath_handle *vp, int msix_id)
+{
+ struct __vxge_hw_device *hldev = vp->vpath->hldev;
+ __vxge_hw_pio_mem_write32_upper(
+ (u32) vxge_bVALn(vxge_mBIT(hldev->first_vp_id +
+ (msix_id / 4)), 0, 32),
+ &hldev->common_reg->set_msix_mask_vect[msix_id % 4]);
+
+ return;
+}
+
+/**
+ * vxge_hw_vpath_msix_clear - Clear MSIX Vector.
+ * @vp: Virtual Path handle.
+ * @msix_id: MSI ID
+ *
+ * The function clears the msix interrupt for the given msix_id
+ *
+ * Returns: 0,
+ * Otherwise, VXGE_HW_ERR_WRONG_IRQ if the msix index is out of range
+ * status.
+ * See also:
+ */
+void
+vxge_hw_vpath_msix_clear(struct __vxge_hw_vpath_handle *vp, int msix_id)
+{
+ struct __vxge_hw_device *hldev = vp->vpath->hldev;
+ if (hldev->config.intr_mode ==
+ VXGE_HW_INTR_MODE_MSIX_ONE_SHOT) {
+ __vxge_hw_pio_mem_write32_upper(
+ (u32)vxge_bVALn(vxge_mBIT(hldev->first_vp_id +
+ (msix_id/4)), 0, 32),
+ &hldev->common_reg->
+ clr_msix_one_shot_vec[msix_id%4]);
+ } else {
+ __vxge_hw_pio_mem_write32_upper(
+ (u32)vxge_bVALn(vxge_mBIT(hldev->first_vp_id +
+ (msix_id/4)), 0, 32),
+ &hldev->common_reg->
+ clear_msix_mask_vect[msix_id%4]);
+ }
+
+ return;
+}
+
+/**
+ * vxge_hw_vpath_msix_unmask - Unmask the MSIX Vector.
+ * @vp: Virtual Path handle.
+ * @msix_id: MSI ID
+ *
+ * The function unmasks the msix interrupt for the given msix_id
+ *
+ * Returns: 0,
+ * Otherwise, VXGE_HW_ERR_WRONG_IRQ if the msix index is out of range
+ * status.
+ * See also:
+ */
+void
+vxge_hw_vpath_msix_unmask(struct __vxge_hw_vpath_handle *vp, int msix_id)
+{
+ struct __vxge_hw_device *hldev = vp->vpath->hldev;
+ __vxge_hw_pio_mem_write32_upper(
+ (u32)vxge_bVALn(vxge_mBIT(hldev->first_vp_id +
+ (msix_id/4)), 0, 32),
+ &hldev->common_reg->clear_msix_mask_vect[msix_id%4]);
+
+ return;
+}
+
+/**
+ * vxge_hw_vpath_msix_mask_all - Mask all MSIX vectors for the vpath.
+ * @vp: Virtual Path handle.
+ *
+ * The function masks all msix interrupt for the given vpath
+ *
+ */
+void
+vxge_hw_vpath_msix_mask_all(struct __vxge_hw_vpath_handle *vp)
+{
+
+ __vxge_hw_pio_mem_write32_upper(
+ (u32)vxge_bVALn(vxge_mBIT(vp->vpath->vp_id), 0, 32),
+ &vp->vpath->hldev->common_reg->set_msix_mask_all_vect);
+
+ return;
+}
+
+/**
+ * vxge_hw_vpath_inta_mask_tx_rx - Mask Tx and Rx interrupts.
+ * @vp: Virtual Path handle.
+ *
+ * Mask Tx and Rx vpath interrupts.
+ *
+ * See also: vxge_hw_vpath_inta_mask_tx_rx()
+ */
+void vxge_hw_vpath_inta_mask_tx_rx(struct __vxge_hw_vpath_handle *vp)
+{
+ u64 tim_int_mask0[4] = {[0 ...3] = 0};
+ u32 tim_int_mask1[4] = {[0 ...3] = 0};
+ u64 val64;
+ struct __vxge_hw_device *hldev = vp->vpath->hldev;
+
+ VXGE_HW_DEVICE_TIM_INT_MASK_SET(tim_int_mask0,
+ tim_int_mask1, vp->vpath->vp_id);
+
+ val64 = readq(&hldev->common_reg->tim_int_mask0);
+
+ if ((tim_int_mask0[VXGE_HW_VPATH_INTR_TX] != 0) ||
+ (tim_int_mask0[VXGE_HW_VPATH_INTR_RX] != 0)) {
+ writeq((tim_int_mask0[VXGE_HW_VPATH_INTR_TX] |
+ tim_int_mask0[VXGE_HW_VPATH_INTR_RX] | val64),
+ &hldev->common_reg->tim_int_mask0);
+ }
+
+ val64 = readl(&hldev->common_reg->tim_int_mask1);
+
+ if ((tim_int_mask1[VXGE_HW_VPATH_INTR_TX] != 0) ||
+ (tim_int_mask1[VXGE_HW_VPATH_INTR_RX] != 0)) {
+ __vxge_hw_pio_mem_write32_upper(
+ (tim_int_mask1[VXGE_HW_VPATH_INTR_TX] |
+ tim_int_mask1[VXGE_HW_VPATH_INTR_RX] | val64),
+ &hldev->common_reg->tim_int_mask1);
+ }
+
+ return;
+}
+
+/**
+ * vxge_hw_vpath_inta_unmask_tx_rx - Unmask Tx and Rx interrupts.
+ * @vp: Virtual Path handle.
+ *
+ * Unmask Tx and Rx vpath interrupts.
+ *
+ * See also: vxge_hw_vpath_inta_mask_tx_rx()
+ */
+void vxge_hw_vpath_inta_unmask_tx_rx(struct __vxge_hw_vpath_handle *vp)
+{
+ u64 tim_int_mask0[4] = {[0 ...3] = 0};
+ u32 tim_int_mask1[4] = {[0 ...3] = 0};
+ u64 val64;
+ struct __vxge_hw_device *hldev = vp->vpath->hldev;
+
+ VXGE_HW_DEVICE_TIM_INT_MASK_SET(tim_int_mask0,
+ tim_int_mask1, vp->vpath->vp_id);
+
+ val64 = readq(&hldev->common_reg->tim_int_mask0);
+
+ if ((tim_int_mask0[VXGE_HW_VPATH_INTR_TX] != 0) ||
+ (tim_int_mask0[VXGE_HW_VPATH_INTR_RX] != 0)) {
+ writeq((~(tim_int_mask0[VXGE_HW_VPATH_INTR_TX] |
+ tim_int_mask0[VXGE_HW_VPATH_INTR_RX])) & val64,
+ &hldev->common_reg->tim_int_mask0);
+ }
+
+ if ((tim_int_mask1[VXGE_HW_VPATH_INTR_TX] != 0) ||
+ (tim_int_mask1[VXGE_HW_VPATH_INTR_RX] != 0)) {
+ __vxge_hw_pio_mem_write32_upper(
+ (~(tim_int_mask1[VXGE_HW_VPATH_INTR_TX] |
+ tim_int_mask1[VXGE_HW_VPATH_INTR_RX])) & val64,
+ &hldev->common_reg->tim_int_mask1);
+ }
+
+ return;
+}
+
+/**
+ * vxge_hw_vpath_poll_rx - Poll Rx Virtual Path for completed
+ * descriptors and process the same.
+ * @ring: Handle to the ring object used for receive
+ *
+ * The function polls the Rx for the completed descriptors and calls
+ * the driver via supplied completion callback.
+ *
+ * Returns: VXGE_HW_OK, if the polling is completed successful.
+ * VXGE_HW_COMPLETIONS_REMAIN: There are still more completed
+ * descriptors available which are yet to be processed.
+ *
+ * See also: vxge_hw_vpath_poll_rx()
+ */
+enum vxge_hw_status vxge_hw_vpath_poll_rx(struct __vxge_hw_ring *ring)
+{
+ u8 t_code;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ void *first_rxdh;
+ u64 val64 = 0;
+ int new_count = 0;
+
+ ring->cmpl_cnt = 0;
+
+ status = vxge_hw_ring_rxd_next_completed(ring, &first_rxdh, &t_code);
+ if (status == VXGE_HW_OK)
+ ring->callback(ring, first_rxdh,
+ t_code, ring->channel.userdata);
+
+ if (ring->cmpl_cnt != 0) {
+ ring->doorbell_cnt += ring->cmpl_cnt;
+ if (ring->doorbell_cnt >= ring->rxds_limit) {
+ /*
+ * Each RxD is of 4 qwords, update the number of
+ * qwords replenished
+ */
+ new_count = (ring->doorbell_cnt * 4);
+
+ /* For each block add 4 more qwords */
+ ring->total_db_cnt += ring->doorbell_cnt;
+ if (ring->total_db_cnt >= ring->rxds_per_block) {
+ new_count += 4;
+ /* Reset total count */
+ ring->total_db_cnt %= ring->rxds_per_block;
+ }
+ writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(new_count),
+ &ring->vp_reg->prc_rxd_doorbell);
+ val64 =
+ readl(&ring->common_reg->titan_general_int_status);
+ ring->doorbell_cnt = 0;
+ }
+ }
+
+ return status;
+}
+
+/**
+ * vxge_hw_vpath_poll_tx - Poll Tx for completed descriptors and process
+ * the same.
+ * @fifo: Handle to the fifo object used for non offload send
+ *
+ * The function polls the Tx for the completed descriptors and calls
+ * the driver via supplied completion callback.
+ *
+ * Returns: VXGE_HW_OK, if the polling is completed successful.
+ * VXGE_HW_COMPLETIONS_REMAIN: There are still more completed
+ * descriptors available which are yet to be processed.
+ *
+ * See also: vxge_hw_vpath_poll_tx().
+ */
+enum vxge_hw_status vxge_hw_vpath_poll_tx(struct __vxge_hw_fifo *fifo,
+ void **skb_ptr)
+{
+ enum vxge_hw_fifo_tcode t_code;
+ void *first_txdlh;
+ enum vxge_hw_status status = VXGE_HW_OK;
+ struct __vxge_hw_channel *channel;
+
+ channel = &fifo->channel;
+
+ status = vxge_hw_fifo_txdl_next_completed(fifo,
+ &first_txdlh, &t_code);
+ if (status == VXGE_HW_OK)
+ if (fifo->callback(fifo, first_txdlh,
+ t_code, channel->userdata, skb_ptr) != VXGE_HW_OK)
+ status = VXGE_HW_COMPLETIONS_REMAIN;
+
+ return status;
+}
diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h
new file mode 100644
index 000000000000..7567a1140d07
--- /dev/null
+++ b/drivers/net/vxge/vxge-traffic.h
@@ -0,0 +1,2409 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice. This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-traffic.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#ifndef VXGE_TRAFFIC_H
+#define VXGE_TRAFFIC_H
+
+#include "vxge-reg.h"
+#include "vxge-version.h"
+
+#define VXGE_HW_DTR_MAX_T_CODE 16
+#define VXGE_HW_ALL_FOXES 0xFFFFFFFFFFFFFFFFULL
+#define VXGE_HW_INTR_MASK_ALL 0xFFFFFFFFFFFFFFFFULL
+#define VXGE_HW_MAX_VIRTUAL_PATHS 17
+
+#define VXGE_HW_MAC_MAX_MAC_PORT_ID 2
+
+#define VXGE_HW_DEFAULT_32 0xffffffff
+/* frames sizes */
+#define VXGE_HW_HEADER_802_2_SIZE 3
+#define VXGE_HW_HEADER_SNAP_SIZE 5
+#define VXGE_HW_HEADER_VLAN_SIZE 4
+#define VXGE_HW_MAC_HEADER_MAX_SIZE \
+ (ETH_HLEN + \
+ VXGE_HW_HEADER_802_2_SIZE + \
+ VXGE_HW_HEADER_VLAN_SIZE + \
+ VXGE_HW_HEADER_SNAP_SIZE)
+
+#define VXGE_HW_TCPIP_HEADER_MAX_SIZE (64 + 64)
+
+/* 32bit alignments */
+#define VXGE_HW_HEADER_ETHERNET_II_802_3_ALIGN 2
+#define VXGE_HW_HEADER_802_2_SNAP_ALIGN 2
+#define VXGE_HW_HEADER_802_2_ALIGN 3
+#define VXGE_HW_HEADER_SNAP_ALIGN 1
+
+#define VXGE_HW_L3_CKSUM_OK 0xFFFF
+#define VXGE_HW_L4_CKSUM_OK 0xFFFF
+
+/* Forward declarations */
+struct __vxge_hw_device;
+struct __vxge_hw_vpath_handle;
+struct vxge_hw_vp_config;
+struct __vxge_hw_virtualpath;
+struct __vxge_hw_channel;
+struct __vxge_hw_fifo;
+struct __vxge_hw_ring;
+struct vxge_hw_ring_attr;
+struct vxge_hw_mempool;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/*VXGE_HW_STATUS_H*/
+
+#define VXGE_HW_EVENT_BASE 0
+#define VXGE_LL_EVENT_BASE 100
+
+/**
+ * enum vxge_hw_event- Enumerates slow-path HW events.
+ * @VXGE_HW_EVENT_UNKNOWN: Unknown (and invalid) event.
+ * @VXGE_HW_EVENT_SERR: Serious vpath hardware error event.
+ * @VXGE_HW_EVENT_ECCERR: vpath ECC error event.
+ * @VXGE_HW_EVENT_VPATH_ERR: Error local to the respective vpath
+ * @VXGE_HW_EVENT_FIFO_ERR: FIFO Doorbell fifo error.
+ * @VXGE_HW_EVENT_SRPCIM_SERR: srpcim hardware error event.
+ * @VXGE_HW_EVENT_MRPCIM_SERR: mrpcim hardware error event.
+ * @VXGE_HW_EVENT_MRPCIM_ECCERR: mrpcim ecc error event.
+ * @VXGE_HW_EVENT_RESET_START: Privileged entity is starting device reset
+ * @VXGE_HW_EVENT_RESET_COMPLETE: Device reset has been completed
+ * @VXGE_HW_EVENT_SLOT_FREEZE: Slot-freeze event. Driver tries to distinguish
+ * slot-freeze from the rest critical events (e.g. ECC) when it is
+ * impossible to PIO read "through" the bus, i.e. when getting all-foxes.
+ *
+ * enum vxge_hw_event enumerates slow-path HW eventis.
+ *
+ * See also: struct vxge_hw_uld_cbs{}, vxge_uld_link_up_f{},
+ * vxge_uld_link_down_f{}.
+ */
+enum vxge_hw_event {
+ VXGE_HW_EVENT_UNKNOWN = 0,
+ /* HW events */
+ VXGE_HW_EVENT_RESET_START = VXGE_HW_EVENT_BASE + 1,
+ VXGE_HW_EVENT_RESET_COMPLETE = VXGE_HW_EVENT_BASE + 2,
+ VXGE_HW_EVENT_LINK_DOWN = VXGE_HW_EVENT_BASE + 3,
+ VXGE_HW_EVENT_LINK_UP = VXGE_HW_EVENT_BASE + 4,
+ VXGE_HW_EVENT_ALARM_CLEARED = VXGE_HW_EVENT_BASE + 5,
+ VXGE_HW_EVENT_ECCERR = VXGE_HW_EVENT_BASE + 6,
+ VXGE_HW_EVENT_MRPCIM_ECCERR = VXGE_HW_EVENT_BASE + 7,
+ VXGE_HW_EVENT_FIFO_ERR = VXGE_HW_EVENT_BASE + 8,
+ VXGE_HW_EVENT_VPATH_ERR = VXGE_HW_EVENT_BASE + 9,
+ VXGE_HW_EVENT_CRITICAL_ERR = VXGE_HW_EVENT_BASE + 10,
+ VXGE_HW_EVENT_SERR = VXGE_HW_EVENT_BASE + 11,
+ VXGE_HW_EVENT_SRPCIM_SERR = VXGE_HW_EVENT_BASE + 12,
+ VXGE_HW_EVENT_MRPCIM_SERR = VXGE_HW_EVENT_BASE + 13,
+ VXGE_HW_EVENT_SLOT_FREEZE = VXGE_HW_EVENT_BASE + 14,
+};
+
+#define VXGE_HW_SET_LEVEL(a, b) (((a) > (b)) ? (a) : (b))
+
+/*
+ * struct vxge_hw_mempool_dma - Represents DMA objects passed to the
+ caller.
+ */
+struct vxge_hw_mempool_dma {
+ dma_addr_t addr;
+ struct pci_dev *handle;
+ struct pci_dev *acc_handle;
+};
+
+/*
+ * vxge_hw_mempool_item_f - Mempool item alloc/free callback
+ * @mempoolh: Memory pool handle.
+ * @memblock: Address of memory block
+ * @memblock_index: Index of memory block
+ * @item: Item that gets allocated or freed.
+ * @index: Item's index in the memory pool.
+ * @is_last: True, if this item is the last one in the pool; false - otherwise.
+ * userdata: Per-pool user context.
+ *
+ * Memory pool allocation/deallocation callback.
+ */
+
+/*
+ * struct vxge_hw_mempool - Memory pool.
+ */
+struct vxge_hw_mempool {
+
+ void (*item_func_alloc)(
+ struct vxge_hw_mempool *mempoolh,
+ u32 memblock_index,
+ struct vxge_hw_mempool_dma *dma_object,
+ u32 index,
+ u32 is_last);
+
+ void *userdata;
+ void **memblocks_arr;
+ void **memblocks_priv_arr;
+ struct vxge_hw_mempool_dma *memblocks_dma_arr;
+ struct __vxge_hw_device *devh;
+ u32 memblock_size;
+ u32 memblocks_max;
+ u32 memblocks_allocated;
+ u32 item_size;
+ u32 items_max;
+ u32 items_initial;
+ u32 items_current;
+ u32 items_per_memblock;
+ void **items_arr;
+ u32 items_priv_size;
+};
+
+#define VXGE_HW_MAX_INTR_PER_VP 4
+#define VXGE_HW_VPATH_INTR_TX 0
+#define VXGE_HW_VPATH_INTR_RX 1
+#define VXGE_HW_VPATH_INTR_EINTA 2
+#define VXGE_HW_VPATH_INTR_BMAP 3
+
+#define VXGE_HW_BLOCK_SIZE 4096
+
+/**
+ * struct vxge_hw_tim_intr_config - Titan Tim interrupt configuration.
+ * @intr_enable: Set to 1, if interrupt is enabled.
+ * @btimer_val: Boundary Timer Initialization value in units of 272 ns.
+ * @timer_ac_en: Timer Automatic Cancel. 1 : Automatic Canceling Enable: when
+ * asserted, other interrupt-generating entities will cancel the
+ * scheduled timer interrupt.
+ * @timer_ci_en: Timer Continuous Interrupt. 1 : Continuous Interrupting Enable:
+ * When asserted, an interrupt will be generated every time the
+ * boundary timer expires, even if no traffic has been transmitted
+ * on this interrupt.
+ * @timer_ri_en: Timer Consecutive (Re-) Interrupt 1 : Consecutive
+ * (Re-) Interrupt Enable: When asserted, an interrupt will be
+ * generated the next time the timer expires, even if no traffic has
+ * been transmitted on this interrupt. (This will only happen once
+ * each time that this value is written to the TIM.) This bit is
+ * cleared by H/W at the end of the current-timer-interval when
+ * the interrupt is triggered.
+ * @rtimer_val: Restriction Timer Initialization value in units of 272 ns.
+ * @util_sel: Utilization Selector. Selects which of the workload approximations
+ * to use (e.g. legacy Tx utilization, Tx/Rx utilization, host
+ * specified utilization etc.), selects one of
+ * the 17 host configured values.
+ * 0-Virtual Path 0
+ * 1-Virtual Path 1
+ * ...
+ * 16-Virtual Path 17
+ * 17-Legacy Tx network utilization, provided by TPA
+ * 18-Legacy Rx network utilization, provided by FAU
+ * 19-Average of legacy Rx and Tx utilization calculated from link
+ * utilization values.
+ * 20-31-Invalid configurations
+ * 32-Host utilization for Virtual Path 0
+ * 33-Host utilization for Virtual Path 1
+ * ...
+ * 48-Host utilization for Virtual Path 17
+ * 49-Legacy Tx network utilization, provided by TPA
+ * 50-Legacy Rx network utilization, provided by FAU
+ * 51-Average of legacy Rx and Tx utilization calculated from
+ * link utilization values.
+ * 52-63-Invalid configurations
+ * @ltimer_val: Latency Timer Initialization Value in units of 272 ns.
+ * @txd_cnt_en: TxD Return Event Count Enable. This configuration bit when set
+ * to 1 enables counting of TxD0 returns (signalled by PCC's),
+ * towards utilization event count values.
+ * @urange_a: Defines the upper limit (in percent) for this utilization range
+ * to be active. This range is considered active
+ * if 0 = UTIL = URNG_A
+ * and the UEC_A field (below) is non-zero.
+ * @uec_a: Utilization Event Count A. If this range is active, the adapter will
+ * wait until UEC_A events have occurred on the interrupt before
+ * generating an interrupt.
+ * @urange_b: Link utilization range B.
+ * @uec_b: Utilization Event Count B.
+ * @urange_c: Link utilization range C.
+ * @uec_c: Utilization Event Count C.
+ * @urange_d: Link utilization range D.
+ * @uec_d: Utilization Event Count D.
+ * Traffic Interrupt Controller Module interrupt configuration.
+ */
+struct vxge_hw_tim_intr_config {
+
+ u32 intr_enable;
+#define VXGE_HW_TIM_INTR_ENABLE 1
+#define VXGE_HW_TIM_INTR_DISABLE 0
+#define VXGE_HW_TIM_INTR_DEFAULT 0
+
+ u32 btimer_val;
+#define VXGE_HW_MIN_TIM_BTIMER_VAL 0
+#define VXGE_HW_MAX_TIM_BTIMER_VAL 67108864
+#define VXGE_HW_USE_FLASH_DEFAULT 0xffffffff
+
+ u32 timer_ac_en;
+#define VXGE_HW_TIM_TIMER_AC_ENABLE 1
+#define VXGE_HW_TIM_TIMER_AC_DISABLE 0
+
+ u32 timer_ci_en;
+#define VXGE_HW_TIM_TIMER_CI_ENABLE 1
+#define VXGE_HW_TIM_TIMER_CI_DISABLE 0
+
+ u32 timer_ri_en;
+#define VXGE_HW_TIM_TIMER_RI_ENABLE 1
+#define VXGE_HW_TIM_TIMER_RI_DISABLE 0
+
+ u32 rtimer_val;
+#define VXGE_HW_MIN_TIM_RTIMER_VAL 0
+#define VXGE_HW_MAX_TIM_RTIMER_VAL 67108864
+
+ u32 util_sel;
+#define VXGE_HW_TIM_UTIL_SEL_LEGACY_TX_NET_UTIL 17
+#define VXGE_HW_TIM_UTIL_SEL_LEGACY_RX_NET_UTIL 18
+#define VXGE_HW_TIM_UTIL_SEL_LEGACY_TX_RX_AVE_NET_UTIL 19
+#define VXGE_HW_TIM_UTIL_SEL_PER_VPATH 63
+
+ u32 ltimer_val;
+#define VXGE_HW_MIN_TIM_LTIMER_VAL 0
+#define VXGE_HW_MAX_TIM_LTIMER_VAL 67108864
+
+ /* Line utilization interrupts */
+ u32 urange_a;
+#define VXGE_HW_MIN_TIM_URANGE_A 0
+#define VXGE_HW_MAX_TIM_URANGE_A 100
+
+ u32 uec_a;
+#define VXGE_HW_MIN_TIM_UEC_A 0
+#define VXGE_HW_MAX_TIM_UEC_A 65535
+
+ u32 urange_b;
+#define VXGE_HW_MIN_TIM_URANGE_B 0
+#define VXGE_HW_MAX_TIM_URANGE_B 100
+
+ u32 uec_b;
+#define VXGE_HW_MIN_TIM_UEC_B 0
+#define VXGE_HW_MAX_TIM_UEC_B 65535
+
+ u32 urange_c;
+#define VXGE_HW_MIN_TIM_URANGE_C 0
+#define VXGE_HW_MAX_TIM_URANGE_C 100
+
+ u32 uec_c;
+#define VXGE_HW_MIN_TIM_UEC_C 0
+#define VXGE_HW_MAX_TIM_UEC_C 65535
+
+ u32 uec_d;
+#define VXGE_HW_MIN_TIM_UEC_D 0
+#define VXGE_HW_MAX_TIM_UEC_D 65535
+};
+
+#define VXGE_HW_STATS_OP_READ 0
+#define VXGE_HW_STATS_OP_CLEAR_STAT 1
+#define VXGE_HW_STATS_OP_CLEAR_ALL_VPATH_STATS 2
+#define VXGE_HW_STATS_OP_CLEAR_ALL_STATS_OF_LOC 2
+#define VXGE_HW_STATS_OP_CLEAR_ALL_STATS 3
+
+#define VXGE_HW_STATS_LOC_AGGR 17
+#define VXGE_HW_STATS_AGGRn_OFFSET 0x00720
+
+#define VXGE_HW_STATS_VPATH_TX_OFFSET 0x0
+#define VXGE_HW_STATS_VPATH_RX_OFFSET 0x00090
+
+#define VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM0_OFFSET (0x001d0 >> 3)
+#define VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM0(bits) \
+ vxge_bVALn(bits, 0, 32)
+
+#define VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM1(bits) \
+ vxge_bVALn(bits, 32, 32)
+
+#define VXGE_HW_STATS_VPATH_PROG_EVENT_VNUM2_OFFSET (0x001d8 >> 3)
+#define VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM2(bits) \
+ vxge_bVALn(bits, 0, 32)
+
+#define VXGE_HW_STATS_GET_VPATH_PROG_EVENT_VNUM3(bits) \
+ vxge_bVALn(bits, 32, 32)
+
+/**
+ * struct vxge_hw_xmac_aggr_stats - Per-Aggregator XMAC Statistics
+ *
+ * @tx_frms: Count of data frames transmitted on this Aggregator on all
+ * its Aggregation ports. Does not include LACPDUs or Marker PDUs.
+ * However, does include frames discarded by the Distribution
+ * function.
+ * @tx_data_octets: Count of data and padding octets of frames transmitted
+ * on this Aggregator on all its Aggregation ports. Does not include
+ * octets of LACPDUs or Marker PDUs. However, does include octets of
+ * frames discarded by the Distribution function.
+ * @tx_mcast_frms: Count of data frames transmitted (to a group destination
+ * address other than the broadcast address) on this Aggregator on
+ * all its Aggregation ports. Does not include LACPDUs or Marker
+ * PDUs. However, does include frames discarded by the Distribution
+ * function.
+ * @tx_bcast_frms: Count of broadcast data frames transmitted on this Aggregator
+ * on all its Aggregation ports. Does not include LACPDUs or Marker
+ * PDUs. However, does include frames discarded by the Distribution
+ * function.
+ * @tx_discarded_frms: Count of data frames to be transmitted on this Aggregator
+ * that are discarded by the Distribution function. This occurs when
+ * conversation are allocated to different ports and have to be
+ * flushed on old ports
+ * @tx_errored_frms: Count of data frames transmitted on this Aggregator that
+ * experience transmission errors on its Aggregation ports.
+ * @rx_frms: Count of data frames received on this Aggregator on all its
+ * Aggregation ports. Does not include LACPDUs or Marker PDUs.
+ * Also, does not include frames discarded by the Collection
+ * function.
+ * @rx_data_octets: Count of data and padding octets of frames received on this
+ * Aggregator on all its Aggregation ports. Does not include octets
+ * of LACPDUs or Marker PDUs. Also, does not include
+ * octets of frames
+ * discarded by the Collection function.
+ * @rx_mcast_frms: Count of data frames received (from a group destination
+ * address other than the broadcast address) on this Aggregator on
+ * all its Aggregation ports. Does not include LACPDUs or Marker
+ * PDUs. Also, does not include frames discarded by the Collection
+ * function.
+ * @rx_bcast_frms: Count of broadcast data frames received on this Aggregator on
+ * all its Aggregation ports. Does not include LACPDUs or Marker
+ * PDUs. Also, does not include frames discarded by the Collection
+ * function.
+ * @rx_discarded_frms: Count of data frames received on this Aggregator that are
+ * discarded by the Collection function because the Collection
+ * function was disabled on the port which the frames are received.
+ * @rx_errored_frms: Count of data frames received on this Aggregator that are
+ * discarded by its Aggregation ports, or are discarded by the
+ * Collection function of the Aggregator, or that are discarded by
+ * the Aggregator due to detection of an illegal Slow Protocols PDU.
+ * @rx_unknown_slow_proto_frms: Count of data frames received on this Aggregator
+ * that are discarded by its Aggregation ports due to detection of
+ * an unknown Slow Protocols PDU.
+ *
+ * Per aggregator XMAC RX statistics.
+ */
+struct vxge_hw_xmac_aggr_stats {
+/*0x000*/ u64 tx_frms;
+/*0x008*/ u64 tx_data_octets;
+/*0x010*/ u64 tx_mcast_frms;
+/*0x018*/ u64 tx_bcast_frms;
+/*0x020*/ u64 tx_discarded_frms;
+/*0x028*/ u64 tx_errored_frms;
+/*0x030*/ u64 rx_frms;
+/*0x038*/ u64 rx_data_octets;
+/*0x040*/ u64 rx_mcast_frms;
+/*0x048*/ u64 rx_bcast_frms;
+/*0x050*/ u64 rx_discarded_frms;
+/*0x058*/ u64 rx_errored_frms;
+/*0x060*/ u64 rx_unknown_slow_proto_frms;
+} __packed;
+
+/**
+ * struct vxge_hw_xmac_port_stats - XMAC Port Statistics
+ *
+ * @tx_ttl_frms: Count of successfully transmitted MAC frames
+ * @tx_ttl_octets: Count of total octets of transmitted frames, not including
+ * framing characters (i.e. less framing bits). To determine the
+ * total octets of transmitted frames, including framing characters,
+ * multiply PORTn_TX_TTL_FRMS by 8 and add it to this stat (unless
+ * otherwise configured, this stat only counts frames that have
+ * 8 bytes of preamble for each frame). This stat can be configured
+ * (see XMAC_STATS_GLOBAL_CFG.TTL_FRMS_HANDLING) to count everything
+ * including the preamble octets.
+ * @tx_data_octets: Count of data and padding octets of successfully transmitted
+ * frames.
+ * @tx_mcast_frms: Count of successfully transmitted frames to a group address
+ * other than the broadcast address.
+ * @tx_bcast_frms: Count of successfully transmitted frames to the broadcast
+ * group address.
+ * @tx_ucast_frms: Count of transmitted frames containing a unicast address.
+ * Includes discarded frames that are not sent to the network.
+ * @tx_tagged_frms: Count of transmitted frames containing a VLAN tag.
+ * @tx_vld_ip: Count of transmitted IP datagrams that are passed to the network.
+ * @tx_vld_ip_octets: Count of total octets of transmitted IP datagrams that
+ * are passed to the network.
+ * @tx_icmp: Count of transmitted ICMP messages. Includes messages not sent
+ * due to problems within ICMP.
+ * @tx_tcp: Count of transmitted TCP segments. Does not include segments
+ * containing retransmitted octets.
+ * @tx_rst_tcp: Count of transmitted TCP segments containing the RST flag.
+ * @tx_udp: Count of transmitted UDP datagrams.
+ * @tx_parse_error: Increments when the TPA is unable to parse a packet. This
+ * generally occurs when a packet is corrupt somehow, including
+ * packets that have IP version mismatches, invalid Layer 2 control
+ * fields, etc. L3/L4 checksums are not offloaded, but the packet
+ * is still be transmitted.
+ * @tx_unknown_protocol: Increments when the TPA encounters an unknown
+ * protocol, such as a new IPv6 extension header, or an unsupported
+ * Routing Type. The packet still has a checksum calculated but it
+ * may be incorrect.
+ * @tx_pause_ctrl_frms: Count of MAC PAUSE control frames that are transmitted.
+ * Since, the only control frames supported by this device are
+ * PAUSE frames, this register is a count of all transmitted MAC
+ * control frames.
+ * @tx_marker_pdu_frms: Count of Marker PDUs transmitted
+ * on this Aggregation port.
+ * @tx_lacpdu_frms: Count of LACPDUs transmitted on this Aggregation port.
+ * @tx_drop_ip: Count of transmitted IP datagrams that could not be passed to
+ * the network. Increments because of:
+ * 1) An internal processing error
+ * (such as an uncorrectable ECC error). 2) A frame parsing error
+ * during IP checksum calculation.
+ * @tx_marker_resp_pdu_frms: Count of Marker Response PDUs transmitted on this
+ * Aggregation port.
+ * @tx_xgmii_char2_match: Maintains a count of the number of transmitted XGMII
+ * characters that match a pattern that is programmable through
+ * register XMAC_STATS_TX_XGMII_CHAR_PORTn. By default, the pattern
+ * is set to /T/ (i.e. the terminate character), thus the statistic
+ * tracks the number of transmitted Terminate characters.
+ * @tx_xgmii_char1_match: Maintains a count of the number of transmitted XGMII
+ * characters that match a pattern that is programmable through
+ * register XMAC_STATS_TX_XGMII_CHAR_PORTn. By default, the pattern
+ * is set to /S/ (i.e. the start character),
+ * thus the statistic tracks
+ * the number of transmitted Start characters.
+ * @tx_xgmii_column2_match: Maintains a count of the number of transmitted XGMII
+ * columns that match a pattern that is programmable through register
+ * XMAC_STATS_TX_XGMII_COLUMN2_PORTn. By default, the pattern is set
+ * to 4 x /E/ (i.e. a column containing all error characters), thus
+ * the statistic tracks the number of Error columns transmitted at
+ * any time. If XMAC_STATS_TX_XGMII_BEHAV_COLUMN2_PORTn.NEAR_COL1 is
+ * set to 1, then this stat increments when COLUMN2 is found within
+ * 'n' clocks after COLUMN1. Here, 'n' is defined by
+ * XMAC_STATS_TX_XGMII_BEHAV_COLUMN2_PORTn.NUM_COL (if 'n' is set
+ * to 0, then it means to search anywhere for COLUMN2).
+ * @tx_xgmii_column1_match: Maintains a count of the number of transmitted XGMII
+ * columns that match a pattern that is programmable through register
+ * XMAC_STATS_TX_XGMII_COLUMN1_PORTn. By default, the pattern is set
+ * to 4 x /I/ (i.e. a column containing all idle characters),
+ * thus the statistic tracks the number of transmitted Idle columns.
+ * @tx_any_err_frms: Count of transmitted frames containing any error that
+ * prevents them from being passed to the network. Increments if
+ * there is an ECC while reading the frame out of the transmit
+ * buffer. Also increments if the transmit protocol assist (TPA)
+ * block determines that the frame should not be sent.
+ * @tx_drop_frms: Count of frames that could not be sent for no other reason
+ * than internal MAC processing. Increments once whenever the
+ * transmit buffer is flushed (due to an ECC error on a memory
+ * descriptor).
+ * @rx_ttl_frms: Count of total received MAC frames, including frames received
+ * with frame-too-long, FCS, or length errors. This stat can be
+ * configured (see XMAC_STATS_GLOBAL_CFG.TTL_FRMS_HANDLING) to count
+ * everything, even "frames" as small one byte of preamble.
+ * @rx_vld_frms: Count of successfully received MAC frames. Does not include
+ * frames received with frame-too-long, FCS, or length errors.
+ * @rx_offload_frms: Count of offloaded received frames that are passed to
+ * the host.
+ * @rx_ttl_octets: Count of total octets of received frames, not including
+ * framing characters (i.e. less framing bits). To determine the
+ * total octets of received frames, including framing characters,
+ * multiply PORTn_RX_TTL_FRMS by 8 and add it to this stat (unless
+ * otherwise configured, this stat only counts frames that have 8
+ * bytes of preamble for each frame). This stat can be configured
+ * (see XMAC_STATS_GLOBAL_CFG.TTL_FRMS_HANDLING) to count everything,
+ * even the preamble octets of "frames" as small one byte of preamble
+ * @rx_data_octets: Count of data and padding octets of successfully received
+ * frames. Does not include frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_offload_octets: Count of total octets, not including framing
+ * characters, of offloaded received frames that are passed
+ * to the host.
+ * @rx_vld_mcast_frms: Count of successfully received MAC frames containing a
+ * nonbroadcast group address. Does not include frames received
+ * with frame-too-long, FCS, or length errors.
+ * @rx_vld_bcast_frms: Count of successfully received MAC frames containing
+ * the broadcast group address. Does not include frames received
+ * with frame-too-long, FCS, or length errors.
+ * @rx_accepted_ucast_frms: Count of successfully received frames containing
+ * a unicast address. Only includes frames that are passed to
+ * the system.
+ * @rx_accepted_nucast_frms: Count of successfully received frames containing
+ * a non-unicast (broadcast or multicast) address. Only includes
+ * frames that are passed to the system. Could include, for instance,
+ * non-unicast frames that contain FCS errors if the MAC_ERROR_CFG
+ * register is set to pass FCS-errored frames to the host.
+ * @rx_tagged_frms: Count of received frames containing a VLAN tag.
+ * @rx_long_frms: Count of received frames that are longer than RX_MAX_PYLD_LEN
+ * + 18 bytes (+ 22 bytes if VLAN-tagged).
+ * @rx_usized_frms: Count of received frames of length (including FCS, but not
+ * framing bits) less than 64 octets, that are otherwise well-formed.
+ * In other words, counts runts.
+ * @rx_osized_frms: Count of received frames of length (including FCS, but not
+ * framing bits) more than 1518 octets, that are otherwise
+ * well-formed. Note: If register XMAC_STATS_GLOBAL_CFG.VLAN_HANDLING
+ * is set to 1, then "more than 1518 octets" becomes "more than 1518
+ * (1522 if VLAN-tagged) octets".
+ * @rx_frag_frms: Count of received frames of length (including FCS, but not
+ * framing bits) less than 64 octets that had bad FCS. In other
+ * words, counts fragments.
+ * @rx_jabber_frms: Count of received frames of length (including FCS, but not
+ * framing bits) more than 1518 octets that had bad FCS. In other
+ * words, counts jabbers. Note: If register
+ * XMAC_STATS_GLOBAL_CFG.VLAN_HANDLING is set to 1, then "more than
+ * 1518 octets" becomes "more than 1518 (1522 if VLAN-tagged)
+ * octets".
+ * @rx_ttl_64_frms: Count of total received MAC frames with length (including
+ * FCS, but not framing bits) of exactly 64 octets. Includes frames
+ * received with frame-too-long, FCS, or length errors.
+ * @rx_ttl_65_127_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) of between 65 and 127
+ * octets inclusive. Includes frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_ttl_128_255_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) of between 128 and 255
+ * octets inclusive. Includes frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_ttl_256_511_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) of between 256 and 511
+ * octets inclusive. Includes frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_ttl_512_1023_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) of between 512 and 1023
+ * octets inclusive. Includes frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_ttl_1024_1518_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) of between 1024 and 1518
+ * octets inclusive. Includes frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_ttl_1519_4095_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) of between 1519 and 4095
+ * octets inclusive. Includes frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_ttl_4096_8191_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) of between 4096 and 8191
+ * octets inclusive. Includes frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_ttl_8192_max_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) of between 8192 and
+ * RX_MAX_PYLD_LEN+18 octets inclusive. Includes frames received
+ * with frame-too-long, FCS, or length errors.
+ * @rx_ttl_gt_max_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) exceeding
+ * RX_MAX_PYLD_LEN+18 (+22 bytes if VLAN-tagged) octets inclusive.
+ * Includes frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_ip: Count of received IP datagrams. Includes errored IP datagrams.
+ * @rx_accepted_ip: Count of received IP datagrams that
+ * are passed to the system.
+ * @rx_ip_octets: Count of number of octets in received IP datagrams. Includes
+ * errored IP datagrams.
+ * @rx_err_ip: Count of received IP datagrams containing errors. For example,
+ * bad IP checksum.
+ * @rx_icmp: Count of received ICMP messages. Includes errored ICMP messages.
+ * @rx_tcp: Count of received TCP segments. Includes errored TCP segments.
+ * Note: This stat contains a count of all received TCP segments,
+ * regardless of whether or not they pertain to an established
+ * connection.
+ * @rx_udp: Count of received UDP datagrams.
+ * @rx_err_tcp: Count of received TCP segments containing errors. For example,
+ * bad TCP checksum.
+ * @rx_pause_count: Count of number of pause quanta that the MAC has been in
+ * the paused state. Recall, one pause quantum equates to 512
+ * bit times.
+ * @rx_pause_ctrl_frms: Count of received MAC PAUSE control frames.
+ * @rx_unsup_ctrl_frms: Count of received MAC control frames that do not
+ * contain the PAUSE opcode. The sum of RX_PAUSE_CTRL_FRMS and
+ * this register is a count of all received MAC control frames.
+ * Note: This stat may be configured to count all layer 2 errors
+ * (i.e. length errors and FCS errors).
+ * @rx_fcs_err_frms: Count of received MAC frames that do not pass FCS. Does
+ * not include frames received with frame-too-long or
+ * frame-too-short error.
+ * @rx_in_rng_len_err_frms: Count of received frames with a length/type field
+ * value between 46 (42 for VLAN-tagged frames) and 1500 (also 1500
+ * for VLAN-tagged frames), inclusive, that does not match the
+ * number of data octets (including pad) received. Also contains
+ * a count of received frames with a length/type field less than
+ * 46 (42 for VLAN-tagged frames) and the number of data octets
+ * (including pad) received is greater than 46 (42 for VLAN-tagged
+ * frames).
+ * @rx_out_rng_len_err_frms: Count of received frames with length/type field
+ * between 1501 and 1535 decimal, inclusive.
+ * @rx_drop_frms: Count of received frames that could not be passed to the host.
+ * See PORTn_RX_L2_MGMT_DISCARD, PORTn_RX_RPA_DISCARD,
+ * PORTn_RX_TRASH_DISCARD, PORTn_RX_RTS_DISCARD, PORTn_RX_RED_DISCARD
+ * for a list of reasons. Because the RMAC drops one frame at a time,
+ * this stat also indicates the number of drop events.
+ * @rx_discarded_frms: Count of received frames containing
+ * any error that prevents
+ * them from being passed to the system. See PORTn_RX_FCS_DISCARD,
+ * PORTn_RX_LEN_DISCARD, and PORTn_RX_SWITCH_DISCARD for a list of
+ * reasons.
+ * @rx_drop_ip: Count of received IP datagrams that could not be passed to the
+ * host. See PORTn_RX_DROP_FRMS for a list of reasons.
+ * @rx_drop_udp: Count of received UDP datagrams that are not delivered to the
+ * host. See PORTn_RX_DROP_FRMS for a list of reasons.
+ * @rx_marker_pdu_frms: Count of valid Marker PDUs received on this Aggregation
+ * port.
+ * @rx_lacpdu_frms: Count of valid LACPDUs received on this Aggregation port.
+ * @rx_unknown_pdu_frms: Count of received frames (on this Aggregation port)
+ * that carry the Slow Protocols EtherType, but contain an unknown
+ * PDU. Or frames that contain the Slow Protocols group MAC address,
+ * but do not carry the Slow Protocols EtherType.
+ * @rx_marker_resp_pdu_frms: Count of valid Marker Response PDUs received on
+ * this Aggregation port.
+ * @rx_fcs_discard: Count of received frames that are discarded because the
+ * FCS check failed.
+ * @rx_illegal_pdu_frms: Count of received frames (on this Aggregation port)
+ * that carry the Slow Protocols EtherType, but contain a badly
+ * formed PDU. Or frames that carry the Slow Protocols EtherType,
+ * but contain an illegal value of Protocol Subtype.
+ * @rx_switch_discard: Count of received frames that are discarded by the
+ * internal switch because they did not have an entry in the
+ * Filtering Database. This includes frames that had an invalid
+ * destination MAC address or VLAN ID. It also includes frames are
+ * discarded because they did not satisfy the length requirements
+ * of the target VPATH.
+ * @rx_len_discard: Count of received frames that are discarded because of an
+ * invalid frame length (includes fragments, oversized frames and
+ * mismatch between frame length and length/type field). This stat
+ * can be configured
+ * (see XMAC_STATS_GLOBAL_CFG.LEN_DISCARD_HANDLING).
+ * @rx_rpa_discard: Count of received frames that were discarded because the
+ * receive protocol assist (RPA) discovered and error in the frame
+ * or was unable to parse the frame.
+ * @rx_l2_mgmt_discard: Count of Layer 2 management frames (eg. pause frames,
+ * Link Aggregation Control Protocol (LACP) frames, etc.) that are
+ * discarded.
+ * @rx_rts_discard: Count of received frames that are discarded by the receive
+ * traffic steering (RTS) logic. Includes those frame discarded
+ * because the SSC response contradicted the switch table, because
+ * the SSC timed out, or because the target queue could not fit the
+ * frame.
+ * @rx_trash_discard: Count of received frames that are discarded because
+ * receive traffic steering (RTS) steered the frame to the trash
+ * queue.
+ * @rx_buff_full_discard: Count of received frames that are discarded because
+ * internal buffers are full. Includes frames discarded because the
+ * RTS logic is waiting for an SSC lookup that has no timeout bound.
+ * Also, includes frames that are dropped because the MAC2FAU buffer
+ * is nearly full -- this can happen if the external receive buffer
+ * is full and the receive path is backing up.
+ * @rx_red_discard: Count of received frames that are discarded because of RED
+ * (Random Early Discard).
+ * @rx_xgmii_ctrl_err_cnt: Maintains a count of unexpected or misplaced control
+ * characters occuring between times of normal data transmission
+ * (i.e. not included in RX_XGMII_DATA_ERR_CNT). This counter is
+ * incremented when either -
+ * 1) The Reconciliation Sublayer (RS) is expecting one control
+ * character and gets another (i.e. is expecting a Start
+ * character, but gets another control character).
+ * 2) Start control character is not in lane 0
+ * Only increments the count by one for each XGMII column.
+ * @rx_xgmii_data_err_cnt: Maintains a count of unexpected control characters
+ * during normal data transmission. If the Reconciliation Sublayer
+ * (RS) receives a control character, other than a terminate control
+ * character, during receipt of data octets then this register is
+ * incremented. Also increments if the start frame delimiter is not
+ * found in the correct location. Only increments the count by one
+ * for each XGMII column.
+ * @rx_xgmii_char1_match: Maintains a count of the number of XGMII characters
+ * that match a pattern that is programmable through register
+ * XMAC_STATS_RX_XGMII_CHAR_PORTn. By default, the pattern is set
+ * to /E/ (i.e. the error character), thus the statistic tracks the
+ * number of Error characters received at any time.
+ * @rx_xgmii_err_sym: Count of the number of symbol errors in the received
+ * XGMII data (i.e. PHY indicates "Receive Error" on the XGMII).
+ * Only includes symbol errors that are observed between the XGMII
+ * Start Frame Delimiter and End Frame Delimiter, inclusive. And
+ * only increments the count by one for each frame.
+ * @rx_xgmii_column1_match: Maintains a count of the number of XGMII columns
+ * that match a pattern that is programmable through register
+ * XMAC_STATS_RX_XGMII_COLUMN1_PORTn. By default, the pattern is set
+ * to 4 x /E/ (i.e. a column containing all error characters), thus
+ * the statistic tracks the number of Error columns received at any
+ * time.
+ * @rx_xgmii_char2_match: Maintains a count of the number of XGMII characters
+ * that match a pattern that is programmable through register
+ * XMAC_STATS_RX_XGMII_CHAR_PORTn. By default, the pattern is set
+ * to /E/ (i.e. the error character), thus the statistic tracks the
+ * number of Error characters received at any time.
+ * @rx_local_fault: Maintains a count of the number of times that link
+ * transitioned from "up" to "down" due to a local fault.
+ * @rx_xgmii_column2_match: Maintains a count of the number of XGMII columns
+ * that match a pattern that is programmable through register
+ * XMAC_STATS_RX_XGMII_COLUMN2_PORTn. By default, the pattern is set
+ * to 4 x /E/ (i.e. a column containing all error characters), thus
+ * the statistic tracks the number of Error columns received at any
+ * time. If XMAC_STATS_RX_XGMII_BEHAV_COLUMN2_PORTn.NEAR_COL1 is set
+ * to 1, then this stat increments when COLUMN2 is found within 'n'
+ * clocks after COLUMN1. Here, 'n' is defined by
+ * XMAC_STATS_RX_XGMII_BEHAV_COLUMN2_PORTn.NUM_COL (if 'n' is set to
+ * 0, then it means to search anywhere for COLUMN2).
+ * @rx_jettison: Count of received frames that are jettisoned because internal
+ * buffers are full.
+ * @rx_remote_fault: Maintains a count of the number of times that link
+ * transitioned from "up" to "down" due to a remote fault.
+ *
+ * XMAC Port Statistics.
+ */
+struct vxge_hw_xmac_port_stats {
+/*0x000*/ u64 tx_ttl_frms;
+/*0x008*/ u64 tx_ttl_octets;
+/*0x010*/ u64 tx_data_octets;
+/*0x018*/ u64 tx_mcast_frms;
+/*0x020*/ u64 tx_bcast_frms;
+/*0x028*/ u64 tx_ucast_frms;
+/*0x030*/ u64 tx_tagged_frms;
+/*0x038*/ u64 tx_vld_ip;
+/*0x040*/ u64 tx_vld_ip_octets;
+/*0x048*/ u64 tx_icmp;
+/*0x050*/ u64 tx_tcp;
+/*0x058*/ u64 tx_rst_tcp;
+/*0x060*/ u64 tx_udp;
+/*0x068*/ u32 tx_parse_error;
+/*0x06c*/ u32 tx_unknown_protocol;
+/*0x070*/ u64 tx_pause_ctrl_frms;
+/*0x078*/ u32 tx_marker_pdu_frms;
+/*0x07c*/ u32 tx_lacpdu_frms;
+/*0x080*/ u32 tx_drop_ip;
+/*0x084*/ u32 tx_marker_resp_pdu_frms;
+/*0x088*/ u32 tx_xgmii_char2_match;
+/*0x08c*/ u32 tx_xgmii_char1_match;
+/*0x090*/ u32 tx_xgmii_column2_match;
+/*0x094*/ u32 tx_xgmii_column1_match;
+/*0x098*/ u32 unused1;
+/*0x09c*/ u16 tx_any_err_frms;
+/*0x09e*/ u16 tx_drop_frms;
+/*0x0a0*/ u64 rx_ttl_frms;
+/*0x0a8*/ u64 rx_vld_frms;
+/*0x0b0*/ u64 rx_offload_frms;
+/*0x0b8*/ u64 rx_ttl_octets;
+/*0x0c0*/ u64 rx_data_octets;
+/*0x0c8*/ u64 rx_offload_octets;
+/*0x0d0*/ u64 rx_vld_mcast_frms;
+/*0x0d8*/ u64 rx_vld_bcast_frms;
+/*0x0e0*/ u64 rx_accepted_ucast_frms;
+/*0x0e8*/ u64 rx_accepted_nucast_frms;
+/*0x0f0*/ u64 rx_tagged_frms;
+/*0x0f8*/ u64 rx_long_frms;
+/*0x100*/ u64 rx_usized_frms;
+/*0x108*/ u64 rx_osized_frms;
+/*0x110*/ u64 rx_frag_frms;
+/*0x118*/ u64 rx_jabber_frms;
+/*0x120*/ u64 rx_ttl_64_frms;
+/*0x128*/ u64 rx_ttl_65_127_frms;
+/*0x130*/ u64 rx_ttl_128_255_frms;
+/*0x138*/ u64 rx_ttl_256_511_frms;
+/*0x140*/ u64 rx_ttl_512_1023_frms;
+/*0x148*/ u64 rx_ttl_1024_1518_frms;
+/*0x150*/ u64 rx_ttl_1519_4095_frms;
+/*0x158*/ u64 rx_ttl_4096_8191_frms;
+/*0x160*/ u64 rx_ttl_8192_max_frms;
+/*0x168*/ u64 rx_ttl_gt_max_frms;
+/*0x170*/ u64 rx_ip;
+/*0x178*/ u64 rx_accepted_ip;
+/*0x180*/ u64 rx_ip_octets;
+/*0x188*/ u64 rx_err_ip;
+/*0x190*/ u64 rx_icmp;
+/*0x198*/ u64 rx_tcp;
+/*0x1a0*/ u64 rx_udp;
+/*0x1a8*/ u64 rx_err_tcp;
+/*0x1b0*/ u64 rx_pause_count;
+/*0x1b8*/ u64 rx_pause_ctrl_frms;
+/*0x1c0*/ u64 rx_unsup_ctrl_frms;
+/*0x1c8*/ u64 rx_fcs_err_frms;
+/*0x1d0*/ u64 rx_in_rng_len_err_frms;
+/*0x1d8*/ u64 rx_out_rng_len_err_frms;
+/*0x1e0*/ u64 rx_drop_frms;
+/*0x1e8*/ u64 rx_discarded_frms;
+/*0x1f0*/ u64 rx_drop_ip;
+/*0x1f8*/ u64 rx_drop_udp;
+/*0x200*/ u32 rx_marker_pdu_frms;
+/*0x204*/ u32 rx_lacpdu_frms;
+/*0x208*/ u32 rx_unknown_pdu_frms;
+/*0x20c*/ u32 rx_marker_resp_pdu_frms;
+/*0x210*/ u32 rx_fcs_discard;
+/*0x214*/ u32 rx_illegal_pdu_frms;
+/*0x218*/ u32 rx_switch_discard;
+/*0x21c*/ u32 rx_len_discard;
+/*0x220*/ u32 rx_rpa_discard;
+/*0x224*/ u32 rx_l2_mgmt_discard;
+/*0x228*/ u32 rx_rts_discard;
+/*0x22c*/ u32 rx_trash_discard;
+/*0x230*/ u32 rx_buff_full_discard;
+/*0x234*/ u32 rx_red_discard;
+/*0x238*/ u32 rx_xgmii_ctrl_err_cnt;
+/*0x23c*/ u32 rx_xgmii_data_err_cnt;
+/*0x240*/ u32 rx_xgmii_char1_match;
+/*0x244*/ u32 rx_xgmii_err_sym;
+/*0x248*/ u32 rx_xgmii_column1_match;
+/*0x24c*/ u32 rx_xgmii_char2_match;
+/*0x250*/ u32 rx_local_fault;
+/*0x254*/ u32 rx_xgmii_column2_match;
+/*0x258*/ u32 rx_jettison;
+/*0x25c*/ u32 rx_remote_fault;
+} __packed;
+
+/**
+ * struct vxge_hw_xmac_vpath_tx_stats - XMAC Vpath Tx Statistics
+ *
+ * @tx_ttl_eth_frms: Count of successfully transmitted MAC frames.
+ * @tx_ttl_eth_octets: Count of total octets of transmitted frames,
+ * not including framing characters (i.e. less framing bits).
+ * To determine the total octets of transmitted frames, including
+ * framing characters, multiply TX_TTL_ETH_FRMS by 8 and add it to
+ * this stat (the device always prepends 8 bytes of preamble for
+ * each frame)
+ * @tx_data_octets: Count of data and padding octets of successfully transmitted
+ * frames.
+ * @tx_mcast_frms: Count of successfully transmitted frames to a group address
+ * other than the broadcast address.
+ * @tx_bcast_frms: Count of successfully transmitted frames to the broadcast
+ * group address.
+ * @tx_ucast_frms: Count of transmitted frames containing a unicast address.
+ * Includes discarded frames that are not sent to the network.
+ * @tx_tagged_frms: Count of transmitted frames containing a VLAN tag.
+ * @tx_vld_ip: Count of transmitted IP datagrams that are passed to the network.
+ * @tx_vld_ip_octets: Count of total octets of transmitted IP datagrams that
+ * are passed to the network.
+ * @tx_icmp: Count of transmitted ICMP messages. Includes messages not sent due
+ * to problems within ICMP.
+ * @tx_tcp: Count of transmitted TCP segments. Does not include segments
+ * containing retransmitted octets.
+ * @tx_rst_tcp: Count of transmitted TCP segments containing the RST flag.
+ * @tx_udp: Count of transmitted UDP datagrams.
+ * @tx_unknown_protocol: Increments when the TPA encounters an unknown protocol,
+ * such as a new IPv6 extension header, or an unsupported Routing
+ * Type. The packet still has a checksum calculated but it may be
+ * incorrect.
+ * @tx_lost_ip: Count of transmitted IP datagrams that could not be passed
+ * to the network. Increments because of: 1) An internal processing
+ * error (such as an uncorrectable ECC error). 2) A frame parsing
+ * error during IP checksum calculation.
+ * @tx_parse_error: Increments when the TPA is unable to parse a packet. This
+ * generally occurs when a packet is corrupt somehow, including
+ * packets that have IP version mismatches, invalid Layer 2 control
+ * fields, etc. L3/L4 checksums are not offloaded, but the packet
+ * is still be transmitted.
+ * @tx_tcp_offload: For frames belonging to offloaded sessions only, a count
+ * of transmitted TCP segments. Does not include segments containing
+ * retransmitted octets.
+ * @tx_retx_tcp_offload: For frames belonging to offloaded sessions only, the
+ * total number of segments retransmitted. Retransmitted segments
+ * that are sourced by the host are counted by the host.
+ * @tx_lost_ip_offload: For frames belonging to offloaded sessions only, a count
+ * of transmitted IP datagrams that could not be passed to the
+ * network.
+ *
+ * XMAC Vpath TX Statistics.
+ */
+struct vxge_hw_xmac_vpath_tx_stats {
+ u64 tx_ttl_eth_frms;
+ u64 tx_ttl_eth_octets;
+ u64 tx_data_octets;
+ u64 tx_mcast_frms;
+ u64 tx_bcast_frms;
+ u64 tx_ucast_frms;
+ u64 tx_tagged_frms;
+ u64 tx_vld_ip;
+ u64 tx_vld_ip_octets;
+ u64 tx_icmp;
+ u64 tx_tcp;
+ u64 tx_rst_tcp;
+ u64 tx_udp;
+ u32 tx_unknown_protocol;
+ u32 tx_lost_ip;
+ u32 unused1;
+ u32 tx_parse_error;
+ u64 tx_tcp_offload;
+ u64 tx_retx_tcp_offload;
+ u64 tx_lost_ip_offload;
+} __packed;
+
+/**
+ * struct vxge_hw_xmac_vpath_rx_stats - XMAC Vpath RX Statistics
+ *
+ * @rx_ttl_eth_frms: Count of successfully received MAC frames.
+ * @rx_vld_frms: Count of successfully received MAC frames. Does not include
+ * frames received with frame-too-long, FCS, or length errors.
+ * @rx_offload_frms: Count of offloaded received frames that are passed to
+ * the host.
+ * @rx_ttl_eth_octets: Count of total octets of received frames, not including
+ * framing characters (i.e. less framing bits). Only counts octets
+ * of frames that are at least 14 bytes (18 bytes for VLAN-tagged)
+ * before FCS. To determine the total octets of received frames,
+ * including framing characters, multiply RX_TTL_ETH_FRMS by 8 and
+ * add it to this stat (the stat RX_TTL_ETH_FRMS only counts frames
+ * that have the required 8 bytes of preamble).
+ * @rx_data_octets: Count of data and padding octets of successfully received
+ * frames. Does not include frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_offload_octets: Count of total octets, not including framing characters,
+ * of offloaded received frames that are passed to the host.
+ * @rx_vld_mcast_frms: Count of successfully received MAC frames containing a
+ * nonbroadcast group address. Does not include frames received with
+ * frame-too-long, FCS, or length errors.
+ * @rx_vld_bcast_frms: Count of successfully received MAC frames containing the
+ * broadcast group address. Does not include frames received with
+ * frame-too-long, FCS, or length errors.
+ * @rx_accepted_ucast_frms: Count of successfully received frames containing
+ * a unicast address. Only includes frames that are passed to the
+ * system.
+ * @rx_accepted_nucast_frms: Count of successfully received frames containing
+ * a non-unicast (broadcast or multicast) address. Only includes
+ * frames that are passed to the system. Could include, for instance,
+ * non-unicast frames that contain FCS errors if the MAC_ERROR_CFG
+ * register is set to pass FCS-errored frames to the host.
+ * @rx_tagged_frms: Count of received frames containing a VLAN tag.
+ * @rx_long_frms: Count of received frames that are longer than RX_MAX_PYLD_LEN
+ * + 18 bytes (+ 22 bytes if VLAN-tagged).
+ * @rx_usized_frms: Count of received frames of length (including FCS, but not
+ * framing bits) less than 64 octets, that are otherwise well-formed.
+ * In other words, counts runts.
+ * @rx_osized_frms: Count of received frames of length (including FCS, but not
+ * framing bits) more than 1518 octets, that are otherwise
+ * well-formed.
+ * @rx_frag_frms: Count of received frames of length (including FCS, but not
+ * framing bits) less than 64 octets that had bad FCS.
+ * In other words, counts fragments.
+ * @rx_jabber_frms: Count of received frames of length (including FCS, but not
+ * framing bits) more than 1518 octets that had bad FCS. In other
+ * words, counts jabbers.
+ * @rx_ttl_64_frms: Count of total received MAC frames with length (including
+ * FCS, but not framing bits) of exactly 64 octets. Includes frames
+ * received with frame-too-long, FCS, or length errors.
+ * @rx_ttl_65_127_frms: Count of total received MAC frames
+ * with length (including
+ * FCS, but not framing bits) of between 65 and 127 octets inclusive.
+ * Includes frames received with frame-too-long, FCS,
+ * or length errors.
+ * @rx_ttl_128_255_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits)
+ * of between 128 and 255 octets
+ * inclusive. Includes frames received with frame-too-long, FCS,
+ * or length errors.
+ * @rx_ttl_256_511_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits)
+ * of between 256 and 511 octets
+ * inclusive. Includes frames received with frame-too-long, FCS, or
+ * length errors.
+ * @rx_ttl_512_1023_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) of between 512 and 1023
+ * octets inclusive. Includes frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_ttl_1024_1518_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) of between 1024 and 1518
+ * octets inclusive. Includes frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_ttl_1519_4095_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) of between 1519 and 4095
+ * octets inclusive. Includes frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_ttl_4096_8191_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) of between 4096 and 8191
+ * octets inclusive. Includes frames received with frame-too-long,
+ * FCS, or length errors.
+ * @rx_ttl_8192_max_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) of between 8192 and
+ * RX_MAX_PYLD_LEN+18 octets inclusive. Includes frames received
+ * with frame-too-long, FCS, or length errors.
+ * @rx_ttl_gt_max_frms: Count of total received MAC frames with length
+ * (including FCS, but not framing bits) exceeding RX_MAX_PYLD_LEN+18
+ * (+22 bytes if VLAN-tagged) octets inclusive. Includes frames
+ * received with frame-too-long, FCS, or length errors.
+ * @rx_ip: Count of received IP datagrams. Includes errored IP datagrams.
+ * @rx_accepted_ip: Count of received IP datagrams that
+ * are passed to the system.
+ * @rx_ip_octets: Count of number of octets in received IP datagrams.
+ * Includes errored IP datagrams.
+ * @rx_err_ip: Count of received IP datagrams containing errors. For example,
+ * bad IP checksum.
+ * @rx_icmp: Count of received ICMP messages. Includes errored ICMP messages.
+ * @rx_tcp: Count of received TCP segments. Includes errored TCP segments.
+ * Note: This stat contains a count of all received TCP segments,
+ * regardless of whether or not they pertain to an established
+ * connection.
+ * @rx_udp: Count of received UDP datagrams.
+ * @rx_err_tcp: Count of received TCP segments containing errors. For example,
+ * bad TCP checksum.
+ * @rx_lost_frms: Count of received frames that could not be passed to the host.
+ * See RX_QUEUE_FULL_DISCARD and RX_RED_DISCARD
+ * for a list of reasons.
+ * @rx_lost_ip: Count of received IP datagrams that could not be passed to
+ * the host. See RX_LOST_FRMS for a list of reasons.
+ * @rx_lost_ip_offload: For frames belonging to offloaded sessions only, a count
+ * of received IP datagrams that could not be passed to the host.
+ * See RX_LOST_FRMS for a list of reasons.
+ * @rx_various_discard: Count of received frames that are discarded because
+ * the target receive queue is full.
+ * @rx_sleep_discard: Count of received frames that are discarded because the
+ * target VPATH is asleep (a Wake-on-LAN magic packet can be used
+ * to awaken the VPATH).
+ * @rx_red_discard: Count of received frames that are discarded because of RED
+ * (Random Early Discard).
+ * @rx_queue_full_discard: Count of received frames that are discarded because
+ * the target receive queue is full.
+ * @rx_mpa_ok_frms: Count of received frames that pass the MPA checks.
+ *
+ * XMAC Vpath RX Statistics.
+ */
+struct vxge_hw_xmac_vpath_rx_stats {
+ u64 rx_ttl_eth_frms;
+ u64 rx_vld_frms;
+ u64 rx_offload_frms;
+ u64 rx_ttl_eth_octets;
+ u64 rx_data_octets;
+ u64 rx_offload_octets;
+ u64 rx_vld_mcast_frms;
+ u64 rx_vld_bcast_frms;
+ u64 rx_accepted_ucast_frms;
+ u64 rx_accepted_nucast_frms;
+ u64 rx_tagged_frms;
+ u64 rx_long_frms;
+ u64 rx_usized_frms;
+ u64 rx_osized_frms;
+ u64 rx_frag_frms;
+ u64 rx_jabber_frms;
+ u64 rx_ttl_64_frms;
+ u64 rx_ttl_65_127_frms;
+ u64 rx_ttl_128_255_frms;
+ u64 rx_ttl_256_511_frms;
+ u64 rx_ttl_512_1023_frms;
+ u64 rx_ttl_1024_1518_frms;
+ u64 rx_ttl_1519_4095_frms;
+ u64 rx_ttl_4096_8191_frms;
+ u64 rx_ttl_8192_max_frms;
+ u64 rx_ttl_gt_max_frms;
+ u64 rx_ip;
+ u64 rx_accepted_ip;
+ u64 rx_ip_octets;
+ u64 rx_err_ip;
+ u64 rx_icmp;
+ u64 rx_tcp;
+ u64 rx_udp;
+ u64 rx_err_tcp;
+ u64 rx_lost_frms;
+ u64 rx_lost_ip;
+ u64 rx_lost_ip_offload;
+ u16 rx_various_discard;
+ u16 rx_sleep_discard;
+ u16 rx_red_discard;
+ u16 rx_queue_full_discard;
+ u64 rx_mpa_ok_frms;
+} __packed;
+
+/**
+ * struct vxge_hw_xmac_stats - XMAC Statistics
+ *
+ * @aggr_stats: Statistics on aggregate port(port 0, port 1)
+ * @port_stats: Staticstics on ports(wire 0, wire 1, lag)
+ * @vpath_tx_stats: Per vpath XMAC TX stats
+ * @vpath_rx_stats: Per vpath XMAC RX stats
+ *
+ * XMAC Statistics.
+ */
+struct vxge_hw_xmac_stats {
+ struct vxge_hw_xmac_aggr_stats
+ aggr_stats[VXGE_HW_MAC_MAX_MAC_PORT_ID];
+ struct vxge_hw_xmac_port_stats
+ port_stats[VXGE_HW_MAC_MAX_MAC_PORT_ID+1];
+ struct vxge_hw_xmac_vpath_tx_stats
+ vpath_tx_stats[VXGE_HW_MAX_VIRTUAL_PATHS];
+ struct vxge_hw_xmac_vpath_rx_stats
+ vpath_rx_stats[VXGE_HW_MAX_VIRTUAL_PATHS];
+};
+
+/**
+ * struct vxge_hw_vpath_stats_hw_info - Titan vpath hardware statistics.
+ * @ini_num_mwr_sent: The number of PCI memory writes initiated by the PIC block
+ * for the given VPATH
+ * @ini_num_mrd_sent: The number of PCI memory reads initiated by the PIC block
+ * @ini_num_cpl_rcvd: The number of PCI read completions received by the
+ * PIC block
+ * @ini_num_mwr_byte_sent: The number of PCI memory write bytes sent by the PIC
+ * block to the host
+ * @ini_num_cpl_byte_rcvd: The number of PCI read completion bytes received by
+ * the PIC block
+ * @wrcrdtarb_xoff: TBD
+ * @rdcrdtarb_xoff: TBD
+ * @vpath_genstats_count0: TBD
+ * @vpath_genstats_count1: TBD
+ * @vpath_genstats_count2: TBD
+ * @vpath_genstats_count3: TBD
+ * @vpath_genstats_count4: TBD
+ * @vpath_gennstats_count5: TBD
+ * @tx_stats: Transmit stats
+ * @rx_stats: Receive stats
+ * @prog_event_vnum1: Programmable statistic. Increments when internal logic
+ * detects a certain event. See register
+ * XMAC_STATS_CFG.EVENT_VNUM1_CFG for more information.
+ * @prog_event_vnum0: Programmable statistic. Increments when internal logic
+ * detects a certain event. See register
+ * XMAC_STATS_CFG.EVENT_VNUM0_CFG for more information.
+ * @prog_event_vnum3: Programmable statistic. Increments when internal logic
+ * detects a certain event. See register
+ * XMAC_STATS_CFG.EVENT_VNUM3_CFG for more information.
+ * @prog_event_vnum2: Programmable statistic. Increments when internal logic
+ * detects a certain event. See register
+ * XMAC_STATS_CFG.EVENT_VNUM2_CFG for more information.
+ * @rx_multi_cast_frame_discard: TBD
+ * @rx_frm_transferred: TBD
+ * @rxd_returned: TBD
+ * @rx_mpa_len_fail_frms: Count of received frames
+ * that fail the MPA length check
+ * @rx_mpa_mrk_fail_frms: Count of received frames
+ * that fail the MPA marker check
+ * @rx_mpa_crc_fail_frms: Count of received frames that fail the MPA CRC check
+ * @rx_permitted_frms: Count of frames that pass through the FAU and on to the
+ * frame buffer (and subsequently to the host).
+ * @rx_vp_reset_discarded_frms: Count of receive frames that are discarded
+ * because the VPATH is in reset
+ * @rx_wol_frms: Count of received "magic packet" frames. Stat increments
+ * whenever the received frame matches the VPATH's Wake-on-LAN
+ * signature(s) CRC.
+ * @tx_vp_reset_discarded_frms: Count of transmit frames that are discarded
+ * because the VPATH is in reset. Includes frames that are discarded
+ * because the current VPIN does not match that VPIN of the frame
+ *
+ * Titan vpath hardware statistics.
+ */
+struct vxge_hw_vpath_stats_hw_info {
+/*0x000*/ u32 ini_num_mwr_sent;
+/*0x004*/ u32 unused1;
+/*0x008*/ u32 ini_num_mrd_sent;
+/*0x00c*/ u32 unused2;
+/*0x010*/ u32 ini_num_cpl_rcvd;
+/*0x014*/ u32 unused3;
+/*0x018*/ u64 ini_num_mwr_byte_sent;
+/*0x020*/ u64 ini_num_cpl_byte_rcvd;
+/*0x028*/ u32 wrcrdtarb_xoff;
+/*0x02c*/ u32 unused4;
+/*0x030*/ u32 rdcrdtarb_xoff;
+/*0x034*/ u32 unused5;
+/*0x038*/ u32 vpath_genstats_count0;
+/*0x03c*/ u32 vpath_genstats_count1;
+/*0x040*/ u32 vpath_genstats_count2;
+/*0x044*/ u32 vpath_genstats_count3;
+/*0x048*/ u32 vpath_genstats_count4;
+/*0x04c*/ u32 unused6;
+/*0x050*/ u32 vpath_genstats_count5;
+/*0x054*/ u32 unused7;
+/*0x058*/ struct vxge_hw_xmac_vpath_tx_stats tx_stats;
+/*0x0e8*/ struct vxge_hw_xmac_vpath_rx_stats rx_stats;
+/*0x220*/ u64 unused9;
+/*0x228*/ u32 prog_event_vnum1;
+/*0x22c*/ u32 prog_event_vnum0;
+/*0x230*/ u32 prog_event_vnum3;
+/*0x234*/ u32 prog_event_vnum2;
+/*0x238*/ u16 rx_multi_cast_frame_discard;
+/*0x23a*/ u8 unused10[6];
+/*0x240*/ u32 rx_frm_transferred;
+/*0x244*/ u32 unused11;
+/*0x248*/ u16 rxd_returned;
+/*0x24a*/ u8 unused12[6];
+/*0x252*/ u16 rx_mpa_len_fail_frms;
+/*0x254*/ u16 rx_mpa_mrk_fail_frms;
+/*0x256*/ u16 rx_mpa_crc_fail_frms;
+/*0x258*/ u16 rx_permitted_frms;
+/*0x25c*/ u64 rx_vp_reset_discarded_frms;
+/*0x25e*/ u64 rx_wol_frms;
+/*0x260*/ u64 tx_vp_reset_discarded_frms;
+} __packed;
+
+
+/**
+ * struct vxge_hw_device_stats_mrpcim_info - Titan mrpcim hardware statistics.
+ * @pic.ini_rd_drop 0x0000 4 Number of DMA reads initiated
+ * by the adapter that were discarded because the VPATH is out of service
+ * @pic.ini_wr_drop 0x0004 4 Number of DMA writes initiated by the
+ * adapter that were discared because the VPATH is out of service
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane0] 0x0008 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane1] 0x0010 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane2] 0x0018 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane3] 0x0020 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane4] 0x0028 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane5] 0x0030 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane6] 0x0038 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane7] 0x0040 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane8] 0x0048 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane9] 0x0050 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane10] 0x0058 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane11] 0x0060 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane12] 0x0068 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane13] 0x0070 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane14] 0x0078 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane15] 0x0080 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_ph_crdt_depleted[vplane16] 0x0088 4 Number of times
+ * the posted header credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane0] 0x0090 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane1] 0x0098 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane2] 0x00a0 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane3] 0x00a8 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane4] 0x00b0 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane5] 0x00b8 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane6] 0x00c0 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane7] 0x00c8 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane8] 0x00d0 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane9] 0x00d8 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane10] 0x00e0 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane11] 0x00e8 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane12] 0x00f0 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane13] 0x00f8 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane14] 0x0100 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane15] 0x0108 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.wrcrdtarb_pd_crdt_depleted[vplane16] 0x0110 4 Number of times
+ * the posted data credits for upstream PCI writes were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane0] 0x0118 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane1] 0x0120 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane2] 0x0128 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane3] 0x0130 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane4] 0x0138 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane5] 0x0140 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane6] 0x0148 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane7] 0x0150 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane8] 0x0158 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane9] 0x0160 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane10] 0x0168 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane11] 0x0170 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane12] 0x0178 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane13] 0x0180 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane14] 0x0188 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane15] 0x0190 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.rdcrdtarb_nph_crdt_depleted[vplane16] 0x0198 4 Number of times
+ * the non-posted header credits for upstream PCI reads were depleted
+ * @pic.ini_rd_vpin_drop 0x01a0 4 Number of DMA reads initiated by
+ * the adapter that were discarded because the VPATH instance number does
+ * not match
+ * @pic.ini_wr_vpin_drop 0x01a4 4 Number of DMA writes initiated
+ * by the adapter that were discarded because the VPATH instance number
+ * does not match
+ * @pic.genstats_count0 0x01a8 4 Configurable statistic #1. Refer
+ * to the GENSTATS0_CFG for information on configuring this statistic
+ * @pic.genstats_count1 0x01ac 4 Configurable statistic #2. Refer
+ * to the GENSTATS1_CFG for information on configuring this statistic
+ * @pic.genstats_count2 0x01b0 4 Configurable statistic #3. Refer
+ * to the GENSTATS2_CFG for information on configuring this statistic
+ * @pic.genstats_count3 0x01b4 4 Configurable statistic #4. Refer
+ * to the GENSTATS3_CFG for information on configuring this statistic
+ * @pic.genstats_count4 0x01b8 4 Configurable statistic #5. Refer
+ * to the GENSTATS4_CFG for information on configuring this statistic
+ * @pic.genstats_count5 0x01c0 4 Configurable statistic #6. Refer
+ * to the GENSTATS5_CFG for information on configuring this statistic
+ * @pci.rstdrop_cpl 0x01c8 4
+ * @pci.rstdrop_msg 0x01cc 4
+ * @pci.rstdrop_client1 0x01d0 4
+ * @pci.rstdrop_client0 0x01d4 4
+ * @pci.rstdrop_client2 0x01d8 4
+ * @pci.depl_cplh[vplane0] 0x01e2 2 Number of times completion
+ * header credits were depleted
+ * @pci.depl_nph[vplane0] 0x01e4 2 Number of times non posted
+ * header credits were depleted
+ * @pci.depl_ph[vplane0] 0x01e6 2 Number of times the posted
+ * header credits were depleted
+ * @pci.depl_cplh[vplane1] 0x01ea 2
+ * @pci.depl_nph[vplane1] 0x01ec 2
+ * @pci.depl_ph[vplane1] 0x01ee 2
+ * @pci.depl_cplh[vplane2] 0x01f2 2
+ * @pci.depl_nph[vplane2] 0x01f4 2
+ * @pci.depl_ph[vplane2] 0x01f6 2
+ * @pci.depl_cplh[vplane3] 0x01fa 2
+ * @pci.depl_nph[vplane3] 0x01fc 2
+ * @pci.depl_ph[vplane3] 0x01fe 2
+ * @pci.depl_cplh[vplane4] 0x0202 2
+ * @pci.depl_nph[vplane4] 0x0204 2
+ * @pci.depl_ph[vplane4] 0x0206 2
+ * @pci.depl_cplh[vplane5] 0x020a 2
+ * @pci.depl_nph[vplane5] 0x020c 2
+ * @pci.depl_ph[vplane5] 0x020e 2
+ * @pci.depl_cplh[vplane6] 0x0212 2
+ * @pci.depl_nph[vplane6] 0x0214 2
+ * @pci.depl_ph[vplane6] 0x0216 2
+ * @pci.depl_cplh[vplane7] 0x021a 2
+ * @pci.depl_nph[vplane7] 0x021c 2
+ * @pci.depl_ph[vplane7] 0x021e 2
+ * @pci.depl_cplh[vplane8] 0x0222 2
+ * @pci.depl_nph[vplane8] 0x0224 2
+ * @pci.depl_ph[vplane8] 0x0226 2
+ * @pci.depl_cplh[vplane9] 0x022a 2
+ * @pci.depl_nph[vplane9] 0x022c 2
+ * @pci.depl_ph[vplane9] 0x022e 2
+ * @pci.depl_cplh[vplane10] 0x0232 2
+ * @pci.depl_nph[vplane10] 0x0234 2
+ * @pci.depl_ph[vplane10] 0x0236 2
+ * @pci.depl_cplh[vplane11] 0x023a 2
+ * @pci.depl_nph[vplane11] 0x023c 2
+ * @pci.depl_ph[vplane11] 0x023e 2
+ * @pci.depl_cplh[vplane12] 0x0242 2
+ * @pci.depl_nph[vplane12] 0x0244 2
+ * @pci.depl_ph[vplane12] 0x0246 2
+ * @pci.depl_cplh[vplane13] 0x024a 2
+ * @pci.depl_nph[vplane13] 0x024c 2
+ * @pci.depl_ph[vplane13] 0x024e 2
+ * @pci.depl_cplh[vplane14] 0x0252 2
+ * @pci.depl_nph[vplane14] 0x0254 2
+ * @pci.depl_ph[vplane14] 0x0256 2
+ * @pci.depl_cplh[vplane15] 0x025a 2
+ * @pci.depl_nph[vplane15] 0x025c 2
+ * @pci.depl_ph[vplane15] 0x025e 2
+ * @pci.depl_cplh[vplane16] 0x0262 2
+ * @pci.depl_nph[vplane16] 0x0264 2
+ * @pci.depl_ph[vplane16] 0x0266 2
+ * @pci.depl_cpld[vplane0] 0x026a 2 Number of times completion data
+ * credits were depleted
+ * @pci.depl_npd[vplane0] 0x026c 2 Number of times non posted data
+ * credits were depleted
+ * @pci.depl_pd[vplane0] 0x026e 2 Number of times the posted data
+ * credits were depleted
+ * @pci.depl_cpld[vplane1] 0x0272 2
+ * @pci.depl_npd[vplane1] 0x0274 2
+ * @pci.depl_pd[vplane1] 0x0276 2
+ * @pci.depl_cpld[vplane2] 0x027a 2
+ * @pci.depl_npd[vplane2] 0x027c 2
+ * @pci.depl_pd[vplane2] 0x027e 2
+ * @pci.depl_cpld[vplane3] 0x0282 2
+ * @pci.depl_npd[vplane3] 0x0284 2
+ * @pci.depl_pd[vplane3] 0x0286 2
+ * @pci.depl_cpld[vplane4] 0x028a 2
+ * @pci.depl_npd[vplane4] 0x028c 2
+ * @pci.depl_pd[vplane4] 0x028e 2
+ * @pci.depl_cpld[vplane5] 0x0292 2
+ * @pci.depl_npd[vplane5] 0x0294 2
+ * @pci.depl_pd[vplane5] 0x0296 2
+ * @pci.depl_cpld[vplane6] 0x029a 2
+ * @pci.depl_npd[vplane6] 0x029c 2
+ * @pci.depl_pd[vplane6] 0x029e 2
+ * @pci.depl_cpld[vplane7] 0x02a2 2
+ * @pci.depl_npd[vplane7] 0x02a4 2
+ * @pci.depl_pd[vplane7] 0x02a6 2
+ * @pci.depl_cpld[vplane8] 0x02aa 2
+ * @pci.depl_npd[vplane8] 0x02ac 2
+ * @pci.depl_pd[vplane8] 0x02ae 2
+ * @pci.depl_cpld[vplane9] 0x02b2 2
+ * @pci.depl_npd[vplane9] 0x02b4 2
+ * @pci.depl_pd[vplane9] 0x02b6 2
+ * @pci.depl_cpld[vplane10] 0x02ba 2
+ * @pci.depl_npd[vplane10] 0x02bc 2
+ * @pci.depl_pd[vplane10] 0x02be 2
+ * @pci.depl_cpld[vplane11] 0x02c2 2
+ * @pci.depl_npd[vplane11] 0x02c4 2
+ * @pci.depl_pd[vplane11] 0x02c6 2
+ * @pci.depl_cpld[vplane12] 0x02ca 2
+ * @pci.depl_npd[vplane12] 0x02cc 2
+ * @pci.depl_pd[vplane12] 0x02ce 2
+ * @pci.depl_cpld[vplane13] 0x02d2 2
+ * @pci.depl_npd[vplane13] 0x02d4 2
+ * @pci.depl_pd[vplane13] 0x02d6 2
+ * @pci.depl_cpld[vplane14] 0x02da 2
+ * @pci.depl_npd[vplane14] 0x02dc 2
+ * @pci.depl_pd[vplane14] 0x02de 2
+ * @pci.depl_cpld[vplane15] 0x02e2 2
+ * @pci.depl_npd[vplane15] 0x02e4 2
+ * @pci.depl_pd[vplane15] 0x02e6 2
+ * @pci.depl_cpld[vplane16] 0x02ea 2
+ * @pci.depl_npd[vplane16] 0x02ec 2
+ * @pci.depl_pd[vplane16] 0x02ee 2
+ * @xgmac_port[3];
+ * @xgmac_aggr[2];
+ * @xgmac.global_prog_event_gnum0 0x0ae0 8 Programmable statistic.
+ * Increments when internal logic detects a certain event. See register
+ * XMAC_STATS_GLOBAL_CFG.EVENT_GNUM0_CFG for more information.
+ * @xgmac.global_prog_event_gnum1 0x0ae8 8 Programmable statistic.
+ * Increments when internal logic detects a certain event. See register
+ * XMAC_STATS_GLOBAL_CFG.EVENT_GNUM1_CFG for more information.
+ * @xgmac.orp_lro_events 0x0af8 8
+ * @xgmac.orp_bs_events 0x0b00 8
+ * @xgmac.orp_iwarp_events 0x0b08 8
+ * @xgmac.tx_permitted_frms 0x0b14 4
+ * @xgmac.port2_tx_any_frms 0x0b1d 1
+ * @xgmac.port1_tx_any_frms 0x0b1e 1
+ * @xgmac.port0_tx_any_frms 0x0b1f 1
+ * @xgmac.port2_rx_any_frms 0x0b25 1
+ * @xgmac.port1_rx_any_frms 0x0b26 1
+ * @xgmac.port0_rx_any_frms 0x0b27 1
+ *
+ * Titan mrpcim hardware statistics.
+ */
+struct vxge_hw_device_stats_mrpcim_info {
+/*0x0000*/ u32 pic_ini_rd_drop;
+/*0x0004*/ u32 pic_ini_wr_drop;
+/*0x0008*/ struct {
+ /*0x0000*/ u32 pic_wrcrdtarb_ph_crdt_depleted;
+ /*0x0004*/ u32 unused1;
+ } pic_wrcrdtarb_ph_crdt_depleted_vplane[17];
+/*0x0090*/ struct {
+ /*0x0000*/ u32 pic_wrcrdtarb_pd_crdt_depleted;
+ /*0x0004*/ u32 unused2;
+ } pic_wrcrdtarb_pd_crdt_depleted_vplane[17];
+/*0x0118*/ struct {
+ /*0x0000*/ u32 pic_rdcrdtarb_nph_crdt_depleted;
+ /*0x0004*/ u32 unused3;
+ } pic_rdcrdtarb_nph_crdt_depleted_vplane[17];
+/*0x01a0*/ u32 pic_ini_rd_vpin_drop;
+/*0x01a4*/ u32 pic_ini_wr_vpin_drop;
+/*0x01a8*/ u32 pic_genstats_count0;
+/*0x01ac*/ u32 pic_genstats_count1;
+/*0x01b0*/ u32 pic_genstats_count2;
+/*0x01b4*/ u32 pic_genstats_count3;
+/*0x01b8*/ u32 pic_genstats_count4;
+/*0x01bc*/ u32 unused4;
+/*0x01c0*/ u32 pic_genstats_count5;
+/*0x01c4*/ u32 unused5;
+/*0x01c8*/ u32 pci_rstdrop_cpl;
+/*0x01cc*/ u32 pci_rstdrop_msg;
+/*0x01d0*/ u32 pci_rstdrop_client1;
+/*0x01d4*/ u32 pci_rstdrop_client0;
+/*0x01d8*/ u32 pci_rstdrop_client2;
+/*0x01dc*/ u32 unused6;
+/*0x01e0*/ struct {
+ /*0x0000*/ u16 unused7;
+ /*0x0002*/ u16 pci_depl_cplh;
+ /*0x0004*/ u16 pci_depl_nph;
+ /*0x0006*/ u16 pci_depl_ph;
+ } pci_depl_h_vplane[17];
+/*0x0268*/ struct {
+ /*0x0000*/ u16 unused8;
+ /*0x0002*/ u16 pci_depl_cpld;
+ /*0x0004*/ u16 pci_depl_npd;
+ /*0x0006*/ u16 pci_depl_pd;
+ } pci_depl_d_vplane[17];
+/*0x02f0*/ struct vxge_hw_xmac_port_stats xgmac_port[3];
+/*0x0a10*/ struct vxge_hw_xmac_aggr_stats xgmac_aggr[2];
+/*0x0ae0*/ u64 xgmac_global_prog_event_gnum0;
+/*0x0ae8*/ u64 xgmac_global_prog_event_gnum1;
+/*0x0af0*/ u64 unused7;
+/*0x0af8*/ u64 unused8;
+/*0x0b00*/ u64 unused9;
+/*0x0b08*/ u64 unused10;
+/*0x0b10*/ u32 unused11;
+/*0x0b14*/ u32 xgmac_tx_permitted_frms;
+/*0x0b18*/ u32 unused12;
+/*0x0b1c*/ u8 unused13;
+/*0x0b1d*/ u8 xgmac_port2_tx_any_frms;
+/*0x0b1e*/ u8 xgmac_port1_tx_any_frms;
+/*0x0b1f*/ u8 xgmac_port0_tx_any_frms;
+/*0x0b20*/ u32 unused14;
+/*0x0b24*/ u8 unused15;
+/*0x0b25*/ u8 xgmac_port2_rx_any_frms;
+/*0x0b26*/ u8 xgmac_port1_rx_any_frms;
+/*0x0b27*/ u8 xgmac_port0_rx_any_frms;
+} __packed;
+
+/**
+ * struct vxge_hw_device_stats_hw_info - Titan hardware statistics.
+ * @vpath_info: VPath statistics
+ * @vpath_info_sav: Vpath statistics saved
+ *
+ * Titan hardware statistics.
+ */
+struct vxge_hw_device_stats_hw_info {
+ struct vxge_hw_vpath_stats_hw_info
+ *vpath_info[VXGE_HW_MAX_VIRTUAL_PATHS];
+ struct vxge_hw_vpath_stats_hw_info
+ vpath_info_sav[VXGE_HW_MAX_VIRTUAL_PATHS];
+};
+
+/**
+ * struct vxge_hw_vpath_stats_sw_common_info - HW common
+ * statistics for queues.
+ * @full_cnt: Number of times the queue was full
+ * @usage_cnt: usage count.
+ * @usage_max: Maximum usage
+ * @reserve_free_swaps_cnt: Reserve/free swap counter. Internal usage.
+ * @total_compl_cnt: Total descriptor completion count.
+ *
+ * Hw queue counters
+ * See also: struct vxge_hw_vpath_stats_sw_fifo_info{},
+ * struct vxge_hw_vpath_stats_sw_ring_info{},
+ */
+struct vxge_hw_vpath_stats_sw_common_info {
+ u32 full_cnt;
+ u32 usage_cnt;
+ u32 usage_max;
+ u32 reserve_free_swaps_cnt;
+ u32 total_compl_cnt;
+};
+
+/**
+ * struct vxge_hw_vpath_stats_sw_fifo_info - HW fifo statistics
+ * @common_stats: Common counters for all queues
+ * @total_posts: Total number of postings on the queue.
+ * @total_buffers: Total number of buffers posted.
+ * @txd_t_code_err_cnt: Array of transmit transfer codes. The position
+ * (index) in this array reflects the transfer code type, for instance
+ * 0xA - "loss of link".
+ * Value txd_t_code_err_cnt[i] reflects the
+ * number of times the corresponding transfer code was encountered.
+ *
+ * HW fifo counters
+ * See also: struct vxge_hw_vpath_stats_sw_common_info{},
+ * struct vxge_hw_vpath_stats_sw_ring_info{},
+ */
+struct vxge_hw_vpath_stats_sw_fifo_info {
+ struct vxge_hw_vpath_stats_sw_common_info common_stats;
+ u32 total_posts;
+ u32 total_buffers;
+ u32 txd_t_code_err_cnt[VXGE_HW_DTR_MAX_T_CODE];
+};
+
+/**
+ * struct vxge_hw_vpath_stats_sw_ring_info - HW ring statistics
+ * @common_stats: Common counters for all queues
+ * @rxd_t_code_err_cnt: Array of receive transfer codes. The position
+ * (index) in this array reflects the transfer code type,
+ * for instance
+ * 0x7 - for "invalid receive buffer size", or 0x8 - for ECC.
+ * Value rxd_t_code_err_cnt[i] reflects the
+ * number of times the corresponding transfer code was encountered.
+ *
+ * HW ring counters
+ * See also: struct vxge_hw_vpath_stats_sw_common_info{},
+ * struct vxge_hw_vpath_stats_sw_fifo_info{},
+ */
+struct vxge_hw_vpath_stats_sw_ring_info {
+ struct vxge_hw_vpath_stats_sw_common_info common_stats;
+ u32 rxd_t_code_err_cnt[VXGE_HW_DTR_MAX_T_CODE];
+
+};
+
+/**
+ * struct vxge_hw_vpath_stats_sw_err - HW vpath error statistics
+ * @unknown_alarms:
+ * @network_sustained_fault:
+ * @network_sustained_ok:
+ * @kdfcctl_fifo0_overwrite:
+ * @kdfcctl_fifo0_poison:
+ * @kdfcctl_fifo0_dma_error:
+ * @dblgen_fifo0_overflow:
+ * @statsb_pif_chain_error:
+ * @statsb_drop_timeout:
+ * @target_illegal_access:
+ * @ini_serr_det:
+ * @prc_ring_bumps:
+ * @prc_rxdcm_sc_err:
+ * @prc_rxdcm_sc_abort:
+ * @prc_quanta_size_err:
+ *
+ * HW vpath error statistics
+ */
+struct vxge_hw_vpath_stats_sw_err {
+ u32 unknown_alarms;
+ u32 network_sustained_fault;
+ u32 network_sustained_ok;
+ u32 kdfcctl_fifo0_overwrite;
+ u32 kdfcctl_fifo0_poison;
+ u32 kdfcctl_fifo0_dma_error;
+ u32 dblgen_fifo0_overflow;
+ u32 statsb_pif_chain_error;
+ u32 statsb_drop_timeout;
+ u32 target_illegal_access;
+ u32 ini_serr_det;
+ u32 prc_ring_bumps;
+ u32 prc_rxdcm_sc_err;
+ u32 prc_rxdcm_sc_abort;
+ u32 prc_quanta_size_err;
+};
+
+/**
+ * struct vxge_hw_vpath_stats_sw_info - HW vpath sw statistics
+ * @soft_reset_cnt: Number of times soft reset is done on this vpath.
+ * @error_stats: error counters for the vpath
+ * @ring_stats: counters for ring belonging to the vpath
+ * @fifo_stats: counters for fifo belonging to the vpath
+ *
+ * HW vpath sw statistics
+ * See also: struct vxge_hw_device_info{} }.
+ */
+struct vxge_hw_vpath_stats_sw_info {
+ u32 soft_reset_cnt;
+ struct vxge_hw_vpath_stats_sw_err error_stats;
+ struct vxge_hw_vpath_stats_sw_ring_info ring_stats;
+ struct vxge_hw_vpath_stats_sw_fifo_info fifo_stats;
+};
+
+/**
+ * struct vxge_hw_device_stats_sw_info - HW own per-device statistics.
+ *
+ * @not_traffic_intr_cnt: Number of times the host was interrupted
+ * without new completions.
+ * "Non-traffic interrupt counter".
+ * @traffic_intr_cnt: Number of traffic interrupts for the device.
+ * @total_intr_cnt: Total number of traffic interrupts for the device.
+ * @total_intr_cnt == @traffic_intr_cnt +
+ * @not_traffic_intr_cnt
+ * @soft_reset_cnt: Number of times soft reset is done on this device.
+ * @vpath_info: please see struct vxge_hw_vpath_stats_sw_info{}
+ * HW per-device statistics.
+ */
+struct vxge_hw_device_stats_sw_info {
+ u32 not_traffic_intr_cnt;
+ u32 traffic_intr_cnt;
+ u32 total_intr_cnt;
+ u32 soft_reset_cnt;
+ struct vxge_hw_vpath_stats_sw_info
+ vpath_info[VXGE_HW_MAX_VIRTUAL_PATHS];
+};
+
+/**
+ * struct vxge_hw_device_stats_sw_err - HW device error statistics.
+ * @vpath_alarms: Number of vpath alarms
+ *
+ * HW Device error stats
+ */
+struct vxge_hw_device_stats_sw_err {
+ u32 vpath_alarms;
+};
+
+/**
+ * struct vxge_hw_device_stats - Contains HW per-device statistics,
+ * including hw.
+ * @devh: HW device handle.
+ * @dma_addr: DMA addres of the %hw_info. Given to device to fill-in the stats.
+ * @hw_info_dmah: DMA handle used to map hw statistics onto the device memory
+ * space.
+ * @hw_info_dma_acch: One more DMA handle used subsequently to free the
+ * DMA object. Note that this and the previous handle have
+ * physical meaning for Solaris; on Windows and Linux the
+ * corresponding value will be simply pointer to PCI device.
+ *
+ * @hw_dev_info_stats: Titan statistics maintained by the hardware.
+ * @sw_dev_info_stats: HW's "soft" device informational statistics, e.g. number
+ * of completions per interrupt.
+ * @sw_dev_err_stats: HW's "soft" device error statistics.
+ *
+ * Structure-container of HW per-device statistics. Note that per-channel
+ * statistics are kept in separate structures under HW's fifo and ring
+ * channels.
+ */
+struct vxge_hw_device_stats {
+ /* handles */
+ struct __vxge_hw_device *devh;
+
+ /* HW device hardware statistics */
+ struct vxge_hw_device_stats_hw_info hw_dev_info_stats;
+
+ /* HW device "soft" stats */
+ struct vxge_hw_device_stats_sw_err sw_dev_err_stats;
+ struct vxge_hw_device_stats_sw_info sw_dev_info_stats;
+
+};
+
+enum vxge_hw_status vxge_hw_device_hw_stats_enable(
+ struct __vxge_hw_device *devh);
+
+enum vxge_hw_status vxge_hw_device_stats_get(
+ struct __vxge_hw_device *devh,
+ struct vxge_hw_device_stats_hw_info *hw_stats);
+
+enum vxge_hw_status vxge_hw_driver_stats_get(
+ struct __vxge_hw_device *devh,
+ struct vxge_hw_device_stats_sw_info *sw_stats);
+
+enum vxge_hw_status vxge_hw_mrpcim_stats_enable(struct __vxge_hw_device *devh);
+
+enum vxge_hw_status vxge_hw_mrpcim_stats_disable(struct __vxge_hw_device *devh);
+
+enum vxge_hw_status
+vxge_hw_mrpcim_stats_access(
+ struct __vxge_hw_device *devh,
+ u32 operation,
+ u32 location,
+ u32 offset,
+ u64 *stat);
+
+enum vxge_hw_status
+vxge_hw_device_xmac_aggr_stats_get(struct __vxge_hw_device *devh, u32 port,
+ struct vxge_hw_xmac_aggr_stats *aggr_stats);
+
+enum vxge_hw_status
+vxge_hw_device_xmac_port_stats_get(struct __vxge_hw_device *devh, u32 port,
+ struct vxge_hw_xmac_port_stats *port_stats);
+
+enum vxge_hw_status
+vxge_hw_device_xmac_stats_get(struct __vxge_hw_device *devh,
+ struct vxge_hw_xmac_stats *xmac_stats);
+
+/**
+ * enum enum vxge_hw_mgmt_reg_type - Register types.
+ *
+ * @vxge_hw_mgmt_reg_type_legacy: Legacy registers
+ * @vxge_hw_mgmt_reg_type_toc: TOC Registers
+ * @vxge_hw_mgmt_reg_type_common: Common Registers
+ * @vxge_hw_mgmt_reg_type_mrpcim: mrpcim registers
+ * @vxge_hw_mgmt_reg_type_srpcim: srpcim registers
+ * @vxge_hw_mgmt_reg_type_vpmgmt: vpath management registers
+ * @vxge_hw_mgmt_reg_type_vpath: vpath registers
+ *
+ * Register type enumaration
+ */
+enum vxge_hw_mgmt_reg_type {
+ vxge_hw_mgmt_reg_type_legacy = 0,
+ vxge_hw_mgmt_reg_type_toc = 1,
+ vxge_hw_mgmt_reg_type_common = 2,
+ vxge_hw_mgmt_reg_type_mrpcim = 3,
+ vxge_hw_mgmt_reg_type_srpcim = 4,
+ vxge_hw_mgmt_reg_type_vpmgmt = 5,
+ vxge_hw_mgmt_reg_type_vpath = 6
+};
+
+enum vxge_hw_status
+vxge_hw_mgmt_reg_read(struct __vxge_hw_device *devh,
+ enum vxge_hw_mgmt_reg_type type,
+ u32 index,
+ u32 offset,
+ u64 *value);
+
+enum vxge_hw_status
+vxge_hw_mgmt_reg_write(struct __vxge_hw_device *devh,
+ enum vxge_hw_mgmt_reg_type type,
+ u32 index,
+ u32 offset,
+ u64 value);
+
+/**
+ * enum enum vxge_hw_rxd_state - Descriptor (RXD) state.
+ * @VXGE_HW_RXD_STATE_NONE: Invalid state.
+ * @VXGE_HW_RXD_STATE_AVAIL: Descriptor is available for reservation.
+ * @VXGE_HW_RXD_STATE_POSTED: Descriptor is posted for processing by the
+ * device.
+ * @VXGE_HW_RXD_STATE_FREED: Descriptor is free and can be reused for
+ * filling-in and posting later.
+ *
+ * Titan/HW descriptor states.
+ *
+ */
+enum vxge_hw_rxd_state {
+ VXGE_HW_RXD_STATE_NONE = 0,
+ VXGE_HW_RXD_STATE_AVAIL = 1,
+ VXGE_HW_RXD_STATE_POSTED = 2,
+ VXGE_HW_RXD_STATE_FREED = 3
+};
+
+/**
+ * struct vxge_hw_ring_rxd_info - Extended information associated with a
+ * completed ring descriptor.
+ * @syn_flag: SYN flag
+ * @is_icmp: Is ICMP
+ * @fast_path_eligible: Fast Path Eligible flag
+ * @l3_cksum: in L3 checksum is valid
+ * @l3_cksum: Result of IP checksum check (by Titan hardware).
+ * This field containing VXGE_HW_L3_CKSUM_OK would mean that
+ * the checksum is correct, otherwise - the datagram is
+ * corrupted.
+ * @l4_cksum: in L4 checksum is valid
+ * @l4_cksum: Result of TCP/UDP checksum check (by Titan hardware).
+ * This field containing VXGE_HW_L4_CKSUM_OK would mean that
+ * the checksum is correct. Otherwise - the packet is
+ * corrupted.
+ * @frame: Zero or more of enum vxge_hw_frame_type flags.
+ * See enum vxge_hw_frame_type{}.
+ * @proto: zero or more of enum vxge_hw_frame_proto flags. Reporting bits for
+ * various higher-layer protocols, including (but note restricted to)
+ * TCP and UDP. See enum vxge_hw_frame_proto{}.
+ * @is_vlan: If vlan tag is valid
+ * @vlan: VLAN tag extracted from the received frame.
+ * @rth_bucket: RTH bucket
+ * @rth_it_hit: Set, If RTH hash value calculated by the Titan hardware
+ * has a matching entry in the Indirection table.
+ * @rth_spdm_hit: Set, If RTH hash value calculated by the Titan hardware
+ * has a matching entry in the Socket Pair Direct Match table.
+ * @rth_hash_type: RTH hash code of the function used to calculate the hash.
+ * @rth_value: Receive Traffic Hashing(RTH) hash value. Produced by Titan
+ * hardware if RTH is enabled.
+ */
+struct vxge_hw_ring_rxd_info {
+ u32 syn_flag;
+ u32 is_icmp;
+ u32 fast_path_eligible;
+ u32 l3_cksum_valid;
+ u32 l3_cksum;
+ u32 l4_cksum_valid;
+ u32 l4_cksum;
+ u32 frame;
+ u32 proto;
+ u32 is_vlan;
+ u32 vlan;
+ u32 rth_bucket;
+ u32 rth_it_hit;
+ u32 rth_spdm_hit;
+ u32 rth_hash_type;
+ u32 rth_value;
+};
+
+/**
+ * enum enum vxge_hw_ring_hash_type - RTH hash types
+ * @VXGE_HW_RING_HASH_TYPE_NONE: No Hash
+ * @VXGE_HW_RING_HASH_TYPE_TCP_IPV4: TCP IPv4
+ * @VXGE_HW_RING_HASH_TYPE_UDP_IPV4: UDP IPv4
+ * @VXGE_HW_RING_HASH_TYPE_IPV4: IPv4
+ * @VXGE_HW_RING_HASH_TYPE_TCP_IPV6: TCP IPv6
+ * @VXGE_HW_RING_HASH_TYPE_UDP_IPV6: UDP IPv6
+ * @VXGE_HW_RING_HASH_TYPE_IPV6: IPv6
+ * @VXGE_HW_RING_HASH_TYPE_TCP_IPV6_EX: TCP IPv6 extension
+ * @VXGE_HW_RING_HASH_TYPE_UDP_IPV6_EX: UDP IPv6 extension
+ * @VXGE_HW_RING_HASH_TYPE_IPV6_EX: IPv6 extension
+ *
+ * RTH hash types
+ */
+enum vxge_hw_ring_hash_type {
+ VXGE_HW_RING_HASH_TYPE_NONE = 0x0,
+ VXGE_HW_RING_HASH_TYPE_TCP_IPV4 = 0x1,
+ VXGE_HW_RING_HASH_TYPE_UDP_IPV4 = 0x2,
+ VXGE_HW_RING_HASH_TYPE_IPV4 = 0x3,
+ VXGE_HW_RING_HASH_TYPE_TCP_IPV6 = 0x4,
+ VXGE_HW_RING_HASH_TYPE_UDP_IPV6 = 0x5,
+ VXGE_HW_RING_HASH_TYPE_IPV6 = 0x6,
+ VXGE_HW_RING_HASH_TYPE_TCP_IPV6_EX = 0x7,
+ VXGE_HW_RING_HASH_TYPE_UDP_IPV6_EX = 0x8,
+ VXGE_HW_RING_HASH_TYPE_IPV6_EX = 0x9
+};
+
+enum vxge_hw_status vxge_hw_ring_rxd_reserve(
+ struct __vxge_hw_ring *ring_handle,
+ void **rxdh);
+
+void
+vxge_hw_ring_rxd_pre_post(
+ struct __vxge_hw_ring *ring_handle,
+ void *rxdh);
+
+void
+vxge_hw_ring_rxd_post_post(
+ struct __vxge_hw_ring *ring_handle,
+ void *rxdh);
+
+enum vxge_hw_status
+vxge_hw_ring_replenish(struct __vxge_hw_ring *ring_handle, u16 min_flag);
+
+void
+vxge_hw_ring_rxd_post_post_wmb(
+ struct __vxge_hw_ring *ring_handle,
+ void *rxdh);
+
+void vxge_hw_ring_rxd_post(
+ struct __vxge_hw_ring *ring_handle,
+ void *rxdh);
+
+enum vxge_hw_status vxge_hw_ring_rxd_next_completed(
+ struct __vxge_hw_ring *ring_handle,
+ void **rxdh,
+ u8 *t_code);
+
+enum vxge_hw_status vxge_hw_ring_handle_tcode(
+ struct __vxge_hw_ring *ring_handle,
+ void *rxdh,
+ u8 t_code);
+
+void vxge_hw_ring_rxd_free(
+ struct __vxge_hw_ring *ring_handle,
+ void *rxdh);
+
+/**
+ * enum enum vxge_hw_frame_proto - Higher-layer ethernet protocols.
+ * @VXGE_HW_FRAME_PROTO_VLAN_TAGGED: VLAN.
+ * @VXGE_HW_FRAME_PROTO_IPV4: IPv4.
+ * @VXGE_HW_FRAME_PROTO_IPV6: IPv6.
+ * @VXGE_HW_FRAME_PROTO_IP_FRAG: IP fragmented.
+ * @VXGE_HW_FRAME_PROTO_TCP: TCP.
+ * @VXGE_HW_FRAME_PROTO_UDP: UDP.
+ * @VXGE_HW_FRAME_PROTO_TCP_OR_UDP: TCP or UDP.
+ *
+ * Higher layer ethernet protocols and options.
+ */
+enum vxge_hw_frame_proto {
+ VXGE_HW_FRAME_PROTO_VLAN_TAGGED = 0x80,
+ VXGE_HW_FRAME_PROTO_IPV4 = 0x10,
+ VXGE_HW_FRAME_PROTO_IPV6 = 0x08,
+ VXGE_HW_FRAME_PROTO_IP_FRAG = 0x04,
+ VXGE_HW_FRAME_PROTO_TCP = 0x02,
+ VXGE_HW_FRAME_PROTO_UDP = 0x01,
+ VXGE_HW_FRAME_PROTO_TCP_OR_UDP = (VXGE_HW_FRAME_PROTO_TCP | \
+ VXGE_HW_FRAME_PROTO_UDP)
+};
+
+/**
+ * enum enum vxge_hw_fifo_gather_code - Gather codes used in fifo TxD
+ * @VXGE_HW_FIFO_GATHER_CODE_FIRST: First TxDL
+ * @VXGE_HW_FIFO_GATHER_CODE_MIDDLE: Middle TxDL
+ * @VXGE_HW_FIFO_GATHER_CODE_LAST: Last TxDL
+ * @VXGE_HW_FIFO_GATHER_CODE_FIRST_LAST: First and Last TxDL.
+ *
+ * These gather codes are used to indicate the position of a TxD in a TxD list
+ */
+enum vxge_hw_fifo_gather_code {
+ VXGE_HW_FIFO_GATHER_CODE_FIRST = 0x2,
+ VXGE_HW_FIFO_GATHER_CODE_MIDDLE = 0x0,
+ VXGE_HW_FIFO_GATHER_CODE_LAST = 0x1,
+ VXGE_HW_FIFO_GATHER_CODE_FIRST_LAST = 0x3
+};
+
+/**
+ * enum enum vxge_hw_fifo_tcode - tcodes used in fifo
+ * @VXGE_HW_FIFO_T_CODE_OK: Transfer OK
+ * @VXGE_HW_FIFO_T_CODE_PCI_READ_CORRUPT: PCI read transaction (either TxD or
+ * frame data) returned with corrupt data.
+ * @VXGE_HW_FIFO_T_CODE_PCI_READ_FAIL:PCI read transaction was returned
+ * with no data.
+ * @VXGE_HW_FIFO_T_CODE_INVALID_MSS: The host attempted to send either a
+ * frame or LSO MSS that was too long (>9800B).
+ * @VXGE_HW_FIFO_T_CODE_LSO_ERROR: Error detected during TCP/UDP Large Send
+ * Offload operation, due to improper header template,
+ * unsupported protocol, etc.
+ * @VXGE_HW_FIFO_T_CODE_UNUSED: Unused
+ * @VXGE_HW_FIFO_T_CODE_MULTI_ERROR: Set to 1 by the adapter if multiple
+ * data buffer transfer errors are encountered (see below).
+ * Otherwise it is set to 0.
+ *
+ * These tcodes are returned in various API for TxD status
+ */
+enum vxge_hw_fifo_tcode {
+ VXGE_HW_FIFO_T_CODE_OK = 0x0,
+ VXGE_HW_FIFO_T_CODE_PCI_READ_CORRUPT = 0x1,
+ VXGE_HW_FIFO_T_CODE_PCI_READ_FAIL = 0x2,
+ VXGE_HW_FIFO_T_CODE_INVALID_MSS = 0x3,
+ VXGE_HW_FIFO_T_CODE_LSO_ERROR = 0x4,
+ VXGE_HW_FIFO_T_CODE_UNUSED = 0x7,
+ VXGE_HW_FIFO_T_CODE_MULTI_ERROR = 0x8
+};
+
+enum vxge_hw_status vxge_hw_fifo_txdl_reserve(
+ struct __vxge_hw_fifo *fifoh,
+ void **txdlh,
+ void **txdl_priv);
+
+void vxge_hw_fifo_txdl_buffer_set(
+ struct __vxge_hw_fifo *fifo_handle,
+ void *txdlh,
+ u32 frag_idx,
+ dma_addr_t dma_pointer,
+ u32 size);
+
+void vxge_hw_fifo_txdl_post(
+ struct __vxge_hw_fifo *fifo_handle,
+ void *txdlh);
+
+u32 vxge_hw_fifo_free_txdl_count_get(
+ struct __vxge_hw_fifo *fifo_handle);
+
+enum vxge_hw_status vxge_hw_fifo_txdl_next_completed(
+ struct __vxge_hw_fifo *fifoh,
+ void **txdlh,
+ enum vxge_hw_fifo_tcode *t_code);
+
+enum vxge_hw_status vxge_hw_fifo_handle_tcode(
+ struct __vxge_hw_fifo *fifoh,
+ void *txdlh,
+ enum vxge_hw_fifo_tcode t_code);
+
+void vxge_hw_fifo_txdl_free(
+ struct __vxge_hw_fifo *fifoh,
+ void *txdlh);
+
+/*
+ * Device
+ */
+
+#define VXGE_HW_RING_NEXT_BLOCK_POINTER_OFFSET (VXGE_HW_BLOCK_SIZE-8)
+#define VXGE_HW_RING_MEMBLOCK_IDX_OFFSET (VXGE_HW_BLOCK_SIZE-16)
+#define VXGE_HW_RING_MIN_BUFF_ALLOCATION 64
+
+/*
+ * struct __vxge_hw_ring_rxd_priv - Receive descriptor HW-private data.
+ * @dma_addr: DMA (mapped) address of _this_ descriptor.
+ * @dma_handle: DMA handle used to map the descriptor onto device.
+ * @dma_offset: Descriptor's offset in the memory block. HW allocates
+ * descriptors in memory blocks of %VXGE_HW_BLOCK_SIZE
+ * bytes. Each memblock is contiguous DMA-able memory. Each
+ * memblock contains 1 or more 4KB RxD blocks visible to the
+ * Titan hardware.
+ * @dma_object: DMA address and handle of the memory block that contains
+ * the descriptor. This member is used only in the "checked"
+ * version of the HW (to enforce certain assertions);
+ * otherwise it gets compiled out.
+ * @allocated: True if the descriptor is reserved, 0 otherwise. Internal usage.
+ *
+ * Per-receive decsriptor HW-private data. HW uses the space to keep DMA
+ * information associated with the descriptor. Note that driver can ask HW
+ * to allocate additional per-descriptor space for its own (driver-specific)
+ * purposes.
+ */
+struct __vxge_hw_ring_rxd_priv {
+ dma_addr_t dma_addr;
+ struct pci_dev *dma_handle;
+ ptrdiff_t dma_offset;
+#ifdef VXGE_DEBUG_ASSERT
+ struct vxge_hw_mempool_dma *dma_object;
+#endif
+};
+
+/* ========================= RING PRIVATE API ============================= */
+u64
+__vxge_hw_ring_first_block_address_get(
+ struct __vxge_hw_ring *ringh);
+
+enum vxge_hw_status
+__vxge_hw_ring_create(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ struct vxge_hw_ring_attr *attr);
+
+enum vxge_hw_status
+__vxge_hw_ring_abort(
+ struct __vxge_hw_ring *ringh);
+
+enum vxge_hw_status
+__vxge_hw_ring_reset(
+ struct __vxge_hw_ring *ringh);
+
+enum vxge_hw_status
+__vxge_hw_ring_delete(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+/* ========================= FIFO PRIVATE API ============================= */
+
+struct vxge_hw_fifo_attr;
+
+enum vxge_hw_status
+__vxge_hw_fifo_create(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ struct vxge_hw_fifo_attr *attr);
+
+enum vxge_hw_status
+__vxge_hw_fifo_abort(
+ struct __vxge_hw_fifo *fifoh);
+
+enum vxge_hw_status
+__vxge_hw_fifo_reset(
+ struct __vxge_hw_fifo *ringh);
+
+enum vxge_hw_status
+__vxge_hw_fifo_delete(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+struct vxge_hw_mempool_cbs {
+ void (*item_func_alloc)(
+ struct vxge_hw_mempool *mempoolh,
+ u32 memblock_index,
+ struct vxge_hw_mempool_dma *dma_object,
+ u32 index,
+ u32 is_last);
+};
+
+void
+__vxge_hw_mempool_destroy(
+ struct vxge_hw_mempool *mempool);
+
+#define VXGE_HW_VIRTUAL_PATH_HANDLE(vpath) \
+ ((struct __vxge_hw_vpath_handle *)(vpath)->vpath_handles.next)
+
+enum vxge_hw_status
+__vxge_hw_vpath_rts_table_get(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u32 action,
+ u32 rts_table,
+ u32 offset,
+ u64 *data1,
+ u64 *data2);
+
+enum vxge_hw_status
+__vxge_hw_vpath_rts_table_set(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u32 action,
+ u32 rts_table,
+ u32 offset,
+ u64 data1,
+ u64 data2);
+
+enum vxge_hw_status
+__vxge_hw_vpath_reset(
+ struct __vxge_hw_device *devh,
+ u32 vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_sw_reset(
+ struct __vxge_hw_device *devh,
+ u32 vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_enable(
+ struct __vxge_hw_device *devh,
+ u32 vp_id);
+
+void
+__vxge_hw_vpath_prc_configure(
+ struct __vxge_hw_device *devh,
+ u32 vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_kdfc_configure(
+ struct __vxge_hw_device *devh,
+ u32 vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_mac_configure(
+ struct __vxge_hw_device *devh,
+ u32 vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_tim_configure(
+ struct __vxge_hw_device *devh,
+ u32 vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_initialize(
+ struct __vxge_hw_device *devh,
+ u32 vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vp_initialize(
+ struct __vxge_hw_device *devh,
+ u32 vp_id,
+ struct vxge_hw_vp_config *config);
+
+void
+__vxge_hw_vp_terminate(
+ struct __vxge_hw_device *devh,
+ u32 vp_id);
+
+enum vxge_hw_status
+__vxge_hw_vpath_alarm_process(
+ struct __vxge_hw_virtualpath *vpath,
+ u32 skip_alarms);
+
+void vxge_hw_device_intr_enable(
+ struct __vxge_hw_device *devh);
+
+u32 vxge_hw_device_set_intr_type(struct __vxge_hw_device *devh, u32 intr_mode);
+
+void vxge_hw_device_intr_disable(
+ struct __vxge_hw_device *devh);
+
+void vxge_hw_device_mask_all(
+ struct __vxge_hw_device *devh);
+
+void vxge_hw_device_unmask_all(
+ struct __vxge_hw_device *devh);
+
+enum vxge_hw_status vxge_hw_device_begin_irq(
+ struct __vxge_hw_device *devh,
+ u32 skip_alarms,
+ u64 *reason);
+
+void vxge_hw_device_clear_tx_rx(
+ struct __vxge_hw_device *devh);
+
+/*
+ * Virtual Paths
+ */
+
+u32 vxge_hw_vpath_id(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_vpath_mac_addr_add_mode {
+ VXGE_HW_VPATH_MAC_ADDR_ADD_DUPLICATE = 0,
+ VXGE_HW_VPATH_MAC_ADDR_DISCARD_DUPLICATE = 1,
+ VXGE_HW_VPATH_MAC_ADDR_REPLACE_DUPLICATE = 2
+};
+
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_add(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u8 (macaddr)[ETH_ALEN],
+ u8 (macaddr_mask)[ETH_ALEN],
+ enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode);
+
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_get(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u8 (macaddr)[ETH_ALEN],
+ u8 (macaddr_mask)[ETH_ALEN]);
+
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_get_next(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u8 (macaddr)[ETH_ALEN],
+ u8 (macaddr_mask)[ETH_ALEN]);
+
+enum vxge_hw_status
+vxge_hw_vpath_mac_addr_delete(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u8 (macaddr)[ETH_ALEN],
+ u8 (macaddr_mask)[ETH_ALEN]);
+
+enum vxge_hw_status
+vxge_hw_vpath_vid_add(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u64 vid);
+
+enum vxge_hw_status
+vxge_hw_vpath_vid_get(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u64 *vid);
+
+enum vxge_hw_status
+vxge_hw_vpath_vid_get_next(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u64 *vid);
+
+enum vxge_hw_status
+vxge_hw_vpath_vid_delete(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u64 vid);
+
+enum vxge_hw_status
+vxge_hw_vpath_etype_add(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u64 etype);
+
+enum vxge_hw_status
+vxge_hw_vpath_etype_get(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u64 *etype);
+
+enum vxge_hw_status
+vxge_hw_vpath_etype_get_next(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u64 *etype);
+
+enum vxge_hw_status
+vxge_hw_vpath_etype_delete(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u64 etype);
+
+enum vxge_hw_status vxge_hw_vpath_promisc_enable(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_promisc_disable(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_bcast_enable(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_mcast_enable(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_mcast_disable(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_poll_rx(
+ struct __vxge_hw_ring *ringh);
+
+enum vxge_hw_status vxge_hw_vpath_poll_tx(
+ struct __vxge_hw_fifo *fifoh,
+ void **skb_ptr);
+
+enum vxge_hw_status vxge_hw_vpath_alarm_process(
+ struct __vxge_hw_vpath_handle *vpath_handle,
+ u32 skip_alarms);
+
+enum vxge_hw_status
+vxge_hw_vpath_msix_set(struct __vxge_hw_vpath_handle *vpath_handle,
+ int *tim_msix_id, int alarm_msix_id);
+
+void
+vxge_hw_vpath_msix_mask(struct __vxge_hw_vpath_handle *vpath_handle,
+ int msix_id);
+
+void vxge_hw_device_flush_io(struct __vxge_hw_device *devh);
+
+void
+vxge_hw_vpath_msix_clear(struct __vxge_hw_vpath_handle *vpath_handle,
+ int msix_id);
+
+void
+vxge_hw_vpath_msix_unmask(struct __vxge_hw_vpath_handle *vpath_handle,
+ int msix_id);
+
+void
+vxge_hw_vpath_msix_mask_all(struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_intr_enable(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+enum vxge_hw_status vxge_hw_vpath_intr_disable(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+void vxge_hw_vpath_inta_mask_tx_rx(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+void vxge_hw_vpath_inta_unmask_tx_rx(
+ struct __vxge_hw_vpath_handle *vpath_handle);
+
+void
+vxge_hw_channel_msix_mask(struct __vxge_hw_channel *channelh, int msix_id);
+
+void
+vxge_hw_channel_msix_unmask(struct __vxge_hw_channel *channelh, int msix_id);
+
+enum vxge_hw_status
+vxge_hw_channel_dtr_alloc(struct __vxge_hw_channel *channel, void **dtrh);
+
+void
+vxge_hw_channel_dtr_post(struct __vxge_hw_channel *channel, void *dtrh);
+
+void
+vxge_hw_channel_dtr_try_complete(struct __vxge_hw_channel *channel,
+ void **dtrh);
+
+void
+vxge_hw_channel_dtr_complete(struct __vxge_hw_channel *channel);
+
+void
+vxge_hw_channel_dtr_free(struct __vxge_hw_channel *channel, void *dtrh);
+
+int
+vxge_hw_channel_dtr_count(struct __vxge_hw_channel *channel);
+
+/* ========================== PRIVATE API ================================= */
+
+enum vxge_hw_status
+__vxge_hw_device_handle_link_up_ind(struct __vxge_hw_device *hldev);
+
+enum vxge_hw_status
+__vxge_hw_device_handle_link_down_ind(struct __vxge_hw_device *hldev);
+
+enum vxge_hw_status
+__vxge_hw_device_handle_error(
+ struct __vxge_hw_device *hldev,
+ u32 vp_id,
+ enum vxge_hw_event type);
+
+#endif
diff --git a/drivers/net/vxge/vxge-version.h b/drivers/net/vxge/vxge-version.h
new file mode 100644
index 000000000000..7da02c545ed5
--- /dev/null
+++ b/drivers/net/vxge/vxge-version.h
@@ -0,0 +1,23 @@
+/******************************************************************************
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL), incorporated herein by reference.
+ * Drivers based on or derived from this code fall under the GPL and must
+ * retain the authorship, copyright and license notice. This file is not
+ * a complete program and may only be used when the entire operating
+ * system is licensed under the GPL.
+ * See the file COPYING in this distribution for more information.
+ *
+ * vxge-version.h: Driver for Neterion Inc's X3100 Series 10GbE PCIe I/O
+ * Virtualized Server Adapter.
+ * Copyright(c) 2002-2009 Neterion Inc.
+ ******************************************************************************/
+#ifndef VXGE_VERSION_H
+
+#define VXGE_VERSION_H
+
+#define VXGE_VERSION_MAJOR "2"
+#define VXGE_VERSION_MINOR "0"
+#define VXGE_VERSION_FIX "1"
+#define VXGE_VERSION_BUILD "17129"
+#define VXGE_VERSION_FOR "k"
+#endif
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index b46897996f7e..9693b0fd323d 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -296,7 +296,13 @@ static void c101_destroy_card(card_t *card)
kfree(card);
}
-
+static const struct net_device_ops c101_ops = {
+ .ndo_open = c101_open,
+ .ndo_stop = c101_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = c101_ioctl,
+};
static int __init c101_run(unsigned long irq, unsigned long winbase)
{
@@ -367,9 +373,7 @@ static int __init c101_run(unsigned long irq, unsigned long winbase)
dev->mem_start = winbase;
dev->mem_end = winbase + C101_MAPPED_RAM_SIZE - 1;
dev->tx_queue_len = 50;
- dev->do_ioctl = c101_ioctl;
- dev->open = c101_open;
- dev->stop = c101_close;
+ dev->netdev_ops = &c101_ops;
hdlc->attach = sca_attach;
hdlc->xmit = sca_xmit;
card->settings.clock_type = CLOCK_EXT;
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index d80b72e22dea..61581ee5f08c 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -427,6 +427,15 @@ static void __exit cosa_exit(void)
}
module_exit(cosa_exit);
+static const struct net_device_ops cosa_ops = {
+ .ndo_open = cosa_net_open,
+ .ndo_stop = cosa_net_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = cosa_net_ioctl,
+ .ndo_tx_timeout = cosa_net_timeout,
+};
+
static int cosa_probe(int base, int irq, int dma)
{
struct cosa_data *cosa = cosa_cards+nr_cards;
@@ -575,10 +584,7 @@ static int cosa_probe(int base, int irq, int dma)
}
dev_to_hdlc(chan->netdev)->attach = cosa_net_attach;
dev_to_hdlc(chan->netdev)->xmit = cosa_net_tx;
- chan->netdev->open = cosa_net_open;
- chan->netdev->stop = cosa_net_close;
- chan->netdev->do_ioctl = cosa_net_ioctl;
- chan->netdev->tx_timeout = cosa_net_timeout;
+ chan->netdev->netdev_ops = &cosa_ops;
chan->netdev->watchdog_timeo = TX_TIMEOUT;
chan->netdev->base_addr = chan->cosa->datareg;
chan->netdev->irq = chan->cosa->irq;
@@ -725,8 +731,7 @@ static char *cosa_net_setup_rx(struct channel_data *chan, int size)
* We can safely fall back to non-dma-able memory, because we have
* the cosa->bouncebuf pre-allocated.
*/
- if (chan->rx_skb)
- kfree_skb(chan->rx_skb);
+ kfree_skb(chan->rx_skb);
chan->rx_skb = dev_alloc_skb(size);
if (chan->rx_skb == NULL) {
printk(KERN_NOTICE "%s: Memory squeeze, dropping packet\n",
@@ -993,8 +998,8 @@ static struct fasync_struct *fasync[256] = { NULL, };
static int cosa_fasync(struct inode *inode, struct file *file, int on)
{
int port = iminor(inode);
- int rv = fasync_helper(inode, file, on, &fasync[port]);
- return rv < 0 ? rv : 0;
+
+ return fasync_helper(inode, file, on, &fasync[port]);
}
#endif
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index 5fa52923efa8..35dea3bea95d 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -355,12 +355,6 @@ static int cycx_wan_update(struct wan_device *wandev)
return 0;
}
-/* callback to initialize device */
-static void cycx_x25_chan_setup(struct net_device *dev)
-{
- dev->init = cycx_netdevice_init;
-}
-
/* Create new logical channel.
* This routine is called by the router when ROUTER_IFNEW IOCTL is being
* handled.
@@ -476,6 +470,27 @@ static const struct header_ops cycx_header_ops = {
.rebuild = cycx_netdevice_rebuild_header,
};
+static const struct net_device_ops cycx_netdev_ops = {
+ .ndo_init = cycx_netdevice_init,
+ .ndo_open = cycx_netdevice_open,
+ .ndo_stop = cycx_netdevice_stop,
+ .ndo_start_xmit = cycx_netdevice_hard_start_xmit,
+ .ndo_get_stats = cycx_netdevice_get_stats,
+};
+
+static void cycx_x25_chan_setup(struct net_device *dev)
+{
+ /* Initialize device driver entry points */
+ dev->netdev_ops = &cycx_netdev_ops;
+ dev->header_ops = &cycx_header_ops;
+
+ /* Initialize media-specific parameters */
+ dev->mtu = CYCX_X25_CHAN_MTU;
+ dev->type = ARPHRD_HWX25; /* ARP h/w type */
+ dev->hard_header_len = 0; /* media header length */
+ dev->addr_len = 0; /* hardware address length */
+}
+
/* Initialize Linux network interface.
*
* This routine is called only once for each interface, during Linux network
@@ -487,20 +502,6 @@ static int cycx_netdevice_init(struct net_device *dev)
struct cycx_device *card = chan->card;
struct wan_device *wandev = &card->wandev;
- /* Initialize device driver entry points */
- dev->open = cycx_netdevice_open;
- dev->stop = cycx_netdevice_stop;
- dev->header_ops = &cycx_header_ops;
-
- dev->hard_start_xmit = cycx_netdevice_hard_start_xmit;
- dev->get_stats = cycx_netdevice_get_stats;
-
- /* Initialize media-specific parameters */
- dev->mtu = CYCX_X25_CHAN_MTU;
- dev->type = ARPHRD_HWX25; /* ARP h/w type */
- dev->hard_header_len = 0; /* media header length */
- dev->addr_len = 0; /* hardware address length */
-
if (!chan->svc)
*(__be16*)dev->dev_addr = htons(chan->lcn);
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
index a297e3efa05d..e8d155c3e59f 100644
--- a/drivers/net/wan/dlci.c
+++ b/drivers/net/wan/dlci.c
@@ -114,7 +114,7 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
if (!pskb_may_pull(skb, sizeof(*hdr))) {
printk(KERN_NOTICE "%s: invalid data no header\n",
dev->name);
- dlp->stats.rx_errors++;
+ dev->stats.rx_errors++;
kfree_skb(skb);
return;
}
@@ -127,7 +127,7 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
if (hdr->control != FRAD_I_UI)
{
printk(KERN_NOTICE "%s: Invalid header flag 0x%02X.\n", dev->name, hdr->control);
- dlp->stats.rx_errors++;
+ dev->stats.rx_errors++;
}
else
switch(hdr->IP_NLPID)
@@ -136,14 +136,14 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
if (hdr->NLPID != FRAD_P_SNAP)
{
printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->NLPID);
- dlp->stats.rx_errors++;
+ dev->stats.rx_errors++;
break;
}
if (hdr->OUI[0] + hdr->OUI[1] + hdr->OUI[2] != 0)
{
printk(KERN_NOTICE "%s: Unsupported organizationally unique identifier 0x%02X-%02X-%02X.\n", dev->name, hdr->OUI[0], hdr->OUI[1], hdr->OUI[2]);
- dlp->stats.rx_errors++;
+ dev->stats.rx_errors++;
break;
}
@@ -164,12 +164,12 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
case FRAD_P_Q933:
case FRAD_P_CLNP:
printk(KERN_NOTICE "%s: Unsupported NLPID 0x%02X.\n", dev->name, hdr->pad);
- dlp->stats.rx_errors++;
+ dev->stats.rx_errors++;
break;
default:
printk(KERN_NOTICE "%s: Invalid pad byte 0x%02X.\n", dev->name, hdr->pad);
- dlp->stats.rx_errors++;
+ dev->stats.rx_errors++;
break;
}
@@ -178,9 +178,9 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
/* we've set up the protocol, so discard the header */
skb_reset_mac_header(skb);
skb_pull(skb, header);
- dlp->stats.rx_bytes += skb->len;
+ dev->stats.rx_bytes += skb->len;
netif_rx(skb);
- dlp->stats.rx_packets++;
+ dev->stats.rx_packets++;
}
else
dev_kfree_skb(skb);
@@ -200,19 +200,19 @@ static int dlci_transmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
- ret = dlp->slave->hard_start_xmit(skb, dlp->slave);
+ ret = dlp->slave->netdev_ops->ndo_start_xmit(skb, dlp->slave);
switch (ret)
{
case DLCI_RET_OK:
- dlp->stats.tx_packets++;
+ dev->stats.tx_packets++;
ret = 0;
break;
case DLCI_RET_ERR:
- dlp->stats.tx_errors++;
+ dev->stats.tx_errors++;
ret = 0;
break;
case DLCI_RET_DROP:
- dlp->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
ret = 1;
break;
}
@@ -295,11 +295,9 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int dlci_change_mtu(struct net_device *dev, int new_mtu)
{
- struct dlci_local *dlp;
-
- dlp = netdev_priv(dev);
+ struct dlci_local *dlp = netdev_priv(dev);
- return((*dlp->slave->change_mtu)(dlp->slave, new_mtu));
+ return dev_set_mtu(dlp->slave, new_mtu);
}
static int dlci_open(struct net_device *dev)
@@ -342,15 +340,6 @@ static int dlci_close(struct net_device *dev)
return 0;
}
-static struct net_device_stats *dlci_get_stats(struct net_device *dev)
-{
- struct dlci_local *dlp;
-
- dlp = netdev_priv(dev);
-
- return(&dlp->stats);
-}
-
static int dlci_add(struct dlci_add *dlci)
{
struct net_device *master, *slave;
@@ -488,18 +477,21 @@ static const struct header_ops dlci_header_ops = {
.create = dlci_header,
};
+static const struct net_device_ops dlci_netdev_ops = {
+ .ndo_open = dlci_open,
+ .ndo_stop = dlci_close,
+ .ndo_do_ioctl = dlci_dev_ioctl,
+ .ndo_start_xmit = dlci_transmit,
+ .ndo_change_mtu = dlci_change_mtu,
+};
+
static void dlci_setup(struct net_device *dev)
{
struct dlci_local *dlp = netdev_priv(dev);
dev->flags = 0;
- dev->open = dlci_open;
- dev->stop = dlci_close;
- dev->do_ioctl = dlci_dev_ioctl;
- dev->hard_start_xmit = dlci_transmit;
dev->header_ops = &dlci_header_ops;
- dev->get_stats = dlci_get_stats;
- dev->change_mtu = dlci_change_mtu;
+ dev->netdev_ops = &dlci_netdev_ops;
dev->destructor = free_netdev;
dlp->receive = dlci_receive;
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 888025db2f02..8face5db8f32 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -883,6 +883,15 @@ static inline int dscc4_set_quartz(struct dscc4_dev_priv *dpriv, int hz)
return ret;
}
+static const struct net_device_ops dscc4_ops = {
+ .ndo_open = dscc4_open,
+ .ndo_stop = dscc4_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = dscc4_ioctl,
+ .ndo_tx_timeout = dscc4_tx_timeout,
+};
+
static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr)
{
struct dscc4_pci_priv *ppriv;
@@ -916,13 +925,8 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr)
hdlc_device *hdlc = dev_to_hdlc(d);
d->base_addr = (unsigned long)ioaddr;
- d->init = NULL;
d->irq = pdev->irq;
- d->open = dscc4_open;
- d->stop = dscc4_close;
- d->set_multicast_list = NULL;
- d->do_ioctl = dscc4_ioctl;
- d->tx_timeout = dscc4_tx_timeout;
+ d->netdev_ops = &dscc4_ops;
d->watchdog_timeo = TX_TIMEOUT;
SET_NETDEV_DEV(d, &pdev->dev);
@@ -1048,7 +1052,7 @@ static int dscc4_open(struct net_device *dev)
struct dscc4_pci_priv *ppriv;
int ret = -EAGAIN;
- if ((dscc4_loopback_check(dpriv) < 0) || !dev->hard_start_xmit)
+ if ((dscc4_loopback_check(dpriv) < 0))
goto err;
if ((ret = hdlc_open(dev)))
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 48a2c9d28950..25c9ef6a1815 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -69,7 +69,7 @@ MODULE_LICENSE("GPL");
#endif
/*
- * Modules parameters and associated varaibles
+ * Modules parameters and associated variables
*/
static int fst_txq_low = FST_LOW_WATER_MARK;
static int fst_txq_high = FST_HIGH_WATER_MARK;
@@ -2424,6 +2424,15 @@ fst_init_card(struct fst_card_info *card)
type_strings[card->type], card->irq, card->nports);
}
+static const struct net_device_ops fst_ops = {
+ .ndo_open = fst_open,
+ .ndo_stop = fst_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = fst_ioctl,
+ .ndo_tx_timeout = fst_tx_timeout,
+};
+
/*
* Initialise card when detected.
* Returns 0 to indicate success, or errno otherwise.
@@ -2565,12 +2574,9 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->base_addr = card->pci_conf;
dev->irq = card->irq;
- dev->tx_queue_len = FST_TX_QUEUE_LEN;
- dev->open = fst_open;
- dev->stop = fst_close;
- dev->do_ioctl = fst_ioctl;
- dev->watchdog_timeo = FST_TX_TIMEOUT;
- dev->tx_timeout = fst_tx_timeout;
+ dev->netdev_ops = &fst_ops;
+ dev->tx_queue_len = FST_TX_QUEUE_LEN;
+ dev->watchdog_timeo = FST_TX_TIMEOUT;
hdlc->attach = fst_attach;
hdlc->xmit = fst_start_xmit;
}
diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c
index 08b3536944fe..497b003d7239 100644
--- a/drivers/net/wan/hd64572.c
+++ b/drivers/net/wan/hd64572.c
@@ -341,7 +341,7 @@ static int sca_poll(struct napi_struct *napi, int budget)
received = sca_rx_done(port, budget);
if (received < budget) {
- netif_rx_complete(napi);
+ napi_complete(napi);
enable_intr(port);
}
@@ -359,7 +359,7 @@ static irqreturn_t sca_intr(int irq, void *dev_id)
if (port && (isr0 & (i ? 0x08002200 : 0x00080022))) {
handled = 1;
disable_intr(port);
- netif_rx_schedule(&port->napi);
+ napi_schedule(&port->napi);
}
}
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
index 1f2a140c9f7c..7596eae1b35c 100644
--- a/drivers/net/wan/hdlc.c
+++ b/drivers/net/wan/hdlc.c
@@ -44,7 +44,7 @@ static const char* version = "HDLC support module revision 1.22";
static struct hdlc_proto *first_proto;
-static int hdlc_change_mtu(struct net_device *dev, int new_mtu)
+int hdlc_change_mtu(struct net_device *dev, int new_mtu)
{
if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU))
return -EINVAL;
@@ -52,15 +52,6 @@ static int hdlc_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
-
-
-static struct net_device_stats *hdlc_get_stats(struct net_device *dev)
-{
- return &dev->stats;
-}
-
-
-
static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *p, struct net_device *orig_dev)
{
@@ -75,7 +66,15 @@ static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
return hdlc->proto->netif_rx(skb);
}
+int hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ hdlc_device *hdlc = dev_to_hdlc(dev);
+
+ if (hdlc->proto->xmit)
+ return hdlc->proto->xmit(skb, dev);
+ return hdlc->xmit(skb, dev); /* call hardware driver directly */
+}
static inline void hdlc_proto_start(struct net_device *dev)
{
@@ -102,11 +101,11 @@ static int hdlc_device_event(struct notifier_block *this, unsigned long event,
hdlc_device *hdlc;
unsigned long flags;
int on;
-
+
if (dev_net(dev) != &init_net)
return NOTIFY_DONE;
- if (dev->get_stats != hdlc_get_stats)
+ if (!(dev->priv_flags & IFF_WAN_HDLC))
return NOTIFY_DONE; /* not an HDLC device */
if (event != NETDEV_CHANGE)
@@ -233,15 +232,13 @@ static void hdlc_setup_dev(struct net_device *dev)
/* Re-init all variables changed by HDLC protocol drivers,
* including ether_setup() called from hdlc_raw_eth.c.
*/
- dev->get_stats = hdlc_get_stats;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+ dev->priv_flags = IFF_WAN_HDLC;
dev->mtu = HDLC_MAX_MTU;
dev->type = ARPHRD_RAWHDLC;
dev->hard_header_len = 16;
dev->addr_len = 0;
dev->header_ops = &hdlc_null_ops;
-
- dev->change_mtu = hdlc_change_mtu;
}
static void hdlc_setup(struct net_device *dev)
@@ -339,6 +336,8 @@ MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
MODULE_DESCRIPTION("HDLC support module");
MODULE_LICENSE("GPL v2");
+EXPORT_SYMBOL(hdlc_change_mtu);
+EXPORT_SYMBOL(hdlc_start_xmit);
EXPORT_SYMBOL(hdlc_open);
EXPORT_SYMBOL(hdlc_close);
EXPORT_SYMBOL(hdlc_ioctl);
@@ -349,8 +348,8 @@ EXPORT_SYMBOL(unregister_hdlc_protocol);
EXPORT_SYMBOL(attach_hdlc_protocol);
EXPORT_SYMBOL(detach_hdlc_protocol);
-static struct packet_type hdlc_packet_type = {
- .type = __constant_htons(ETH_P_HDLC),
+static struct packet_type hdlc_packet_type __read_mostly = {
+ .type = cpu_to_be16(ETH_P_HDLC),
.func = hdlc_rcv,
};
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 44e64b15dbd1..cf5fd17ad707 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -117,7 +117,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
data->type = htonl(type);
data->par1 = par1;
data->par2 = par2;
- data->rel = __constant_htons(0xFFFF);
+ data->rel = cpu_to_be16(0xFFFF);
/* we will need do_div here if 1000 % HZ != 0 */
data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ));
@@ -136,20 +136,20 @@ static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev)
struct hdlc_header *data = (struct hdlc_header*)skb->data;
if (skb->len < sizeof(struct hdlc_header))
- return __constant_htons(ETH_P_HDLC);
+ return cpu_to_be16(ETH_P_HDLC);
if (data->address != CISCO_MULTICAST &&
data->address != CISCO_UNICAST)
- return __constant_htons(ETH_P_HDLC);
+ return cpu_to_be16(ETH_P_HDLC);
switch(data->protocol) {
- case __constant_htons(ETH_P_IP):
- case __constant_htons(ETH_P_IPX):
- case __constant_htons(ETH_P_IPV6):
+ case cpu_to_be16(ETH_P_IP):
+ case cpu_to_be16(ETH_P_IPX):
+ case cpu_to_be16(ETH_P_IPV6):
skb_pull(skb, sizeof(struct hdlc_header));
return data->protocol;
default:
- return __constant_htons(ETH_P_HDLC);
+ return cpu_to_be16(ETH_P_HDLC);
}
}
@@ -194,7 +194,7 @@ static int cisco_rx(struct sk_buff *skb)
case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */
in_dev = dev->ip_ptr;
addr = 0;
- mask = __constant_htonl(~0); /* is the mask correct? */
+ mask = ~cpu_to_be32(0); /* is the mask correct? */
if (in_dev != NULL) {
struct in_ifaddr **ifap = &in_dev->ifa_list;
@@ -382,7 +382,6 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
memcpy(&state(hdlc)->settings, &new_settings, size);
spin_lock_init(&state(hdlc)->lock);
- dev->hard_start_xmit = hdlc->xmit;
dev->header_ops = &cisco_header_ops;
dev->type = ARPHRD_CISCO;
netif_dormant_on(dev);
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index f1ddd7c3459c..800530101093 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -278,31 +278,31 @@ static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
struct sk_buff *skb = *skb_p;
switch (skb->protocol) {
- case __constant_htons(NLPID_CCITT_ANSI_LMI):
+ case cpu_to_be16(NLPID_CCITT_ANSI_LMI):
head_len = 4;
skb_push(skb, head_len);
skb->data[3] = NLPID_CCITT_ANSI_LMI;
break;
- case __constant_htons(NLPID_CISCO_LMI):
+ case cpu_to_be16(NLPID_CISCO_LMI):
head_len = 4;
skb_push(skb, head_len);
skb->data[3] = NLPID_CISCO_LMI;
break;
- case __constant_htons(ETH_P_IP):
+ case cpu_to_be16(ETH_P_IP):
head_len = 4;
skb_push(skb, head_len);
skb->data[3] = NLPID_IP;
break;
- case __constant_htons(ETH_P_IPV6):
+ case cpu_to_be16(ETH_P_IPV6):
head_len = 4;
skb_push(skb, head_len);
skb->data[3] = NLPID_IPV6;
break;
- case __constant_htons(ETH_P_802_3):
+ case cpu_to_be16(ETH_P_802_3):
head_len = 10;
if (skb_headroom(skb) < head_len) {
struct sk_buff *skb2 = skb_realloc_headroom(skb,
@@ -426,7 +426,7 @@ static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
skb_put(skb, pad);
memset(skb->data + len, 0, pad);
}
- skb->protocol = __constant_htons(ETH_P_802_3);
+ skb->protocol = cpu_to_be16(ETH_P_802_3);
}
if (!fr_hard_header(&skb, pvc->dlci)) {
dev->stats.tx_bytes += skb->len;
@@ -444,18 +444,6 @@ static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}
-
-
-static int pvc_change_mtu(struct net_device *dev, int new_mtu)
-{
- if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
-}
-
-
-
static inline void fr_log_dlci_active(pvc_device *pvc)
{
printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n",
@@ -508,10 +496,10 @@ static void fr_lmi_send(struct net_device *dev, int fullrep)
memset(skb->data, 0, len);
skb_reserve(skb, 4);
if (lmi == LMI_CISCO) {
- skb->protocol = __constant_htons(NLPID_CISCO_LMI);
+ skb->protocol = cpu_to_be16(NLPID_CISCO_LMI);
fr_hard_header(&skb, LMI_CISCO_DLCI);
} else {
- skb->protocol = __constant_htons(NLPID_CCITT_ANSI_LMI);
+ skb->protocol = cpu_to_be16(NLPID_CCITT_ANSI_LMI);
fr_hard_header(&skb, LMI_CCITT_ANSI_DLCI);
}
data = skb_tail_pointer(skb);
@@ -1068,6 +1056,14 @@ static void pvc_setup(struct net_device *dev)
dev->addr_len = 2;
}
+static const struct net_device_ops pvc_ops = {
+ .ndo_open = pvc_open,
+ .ndo_stop = pvc_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = pvc_xmit,
+ .ndo_do_ioctl = pvc_ioctl,
+};
+
static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
{
hdlc_device *hdlc = dev_to_hdlc(frad);
@@ -1104,11 +1100,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
*(__be16*)dev->dev_addr = htons(dlci);
dlci_to_q922(dev->broadcast, dlci);
}
- dev->hard_start_xmit = pvc_xmit;
- dev->open = pvc_open;
- dev->stop = pvc_close;
- dev->do_ioctl = pvc_ioctl;
- dev->change_mtu = pvc_change_mtu;
+ dev->netdev_ops = &pvc_ops;
dev->mtu = HDLC_MAX_MTU;
dev->tx_queue_len = 0;
dev->ml_priv = pvc;
@@ -1260,8 +1252,6 @@ static int fr_ioctl(struct net_device *dev, struct ifreq *ifr)
state(hdlc)->dce_pvc_count = 0;
}
memcpy(&state(hdlc)->settings, &new_settings, size);
-
- dev->hard_start_xmit = hdlc->xmit;
dev->type = ARPHRD_FRAD;
return 0;
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 57fe714c1c7f..72a7cdab4245 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -150,11 +150,11 @@ static __be16 ppp_type_trans(struct sk_buff *skb, struct net_device *dev)
return htons(ETH_P_HDLC);
switch (data->protocol) {
- case __constant_htons(PID_IP):
+ case cpu_to_be16(PID_IP):
skb_pull(skb, sizeof(struct hdlc_header));
return htons(ETH_P_IP);
- case __constant_htons(PID_IPV6):
+ case cpu_to_be16(PID_IPV6):
skb_pull(skb, sizeof(struct hdlc_header));
return htons(ETH_P_IPV6);
@@ -558,7 +558,6 @@ out:
return NET_RX_DROP;
}
-
static void ppp_timer(unsigned long arg)
{
struct proto *proto = (struct proto *)arg;
@@ -679,7 +678,6 @@ static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
ppp->keepalive_interval = 10;
ppp->keepalive_timeout = 60;
- dev->hard_start_xmit = hdlc->xmit;
dev->hard_header_len = sizeof(struct hdlc_header);
dev->header_ops = &ppp_header_ops;
dev->type = ARPHRD_PPP;
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c
index 8612311748f4..19f51fdd5522 100644
--- a/drivers/net/wan/hdlc_raw.c
+++ b/drivers/net/wan/hdlc_raw.c
@@ -27,11 +27,9 @@ static int raw_ioctl(struct net_device *dev, struct ifreq *ifr);
static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev)
{
- return __constant_htons(ETH_P_IP);
+ return cpu_to_be16(ETH_P_IP);
}
-
-
static struct hdlc_proto proto = {
.type_trans = raw_type_trans,
.ioctl = raw_ioctl,
@@ -86,7 +84,6 @@ static int raw_ioctl(struct net_device *dev, struct ifreq *ifr)
if (result)
return result;
memcpy(hdlc->state, &new_settings, size);
- dev->hard_start_xmit = hdlc->xmit;
dev->type = ARPHRD_RAWHDLC;
netif_dormant_off(dev);
return 0;
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c
index a13fc3207520..49e68f5ca5f2 100644
--- a/drivers/net/wan/hdlc_raw_eth.c
+++ b/drivers/net/wan/hdlc_raw_eth.c
@@ -45,6 +45,7 @@ static int eth_tx(struct sk_buff *skb, struct net_device *dev)
static struct hdlc_proto proto = {
.type_trans = eth_type_trans,
+ .xmit = eth_tx,
.ioctl = raw_eth_ioctl,
.module = THIS_MODULE,
};
@@ -56,9 +57,7 @@ static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
const size_t size = sizeof(raw_hdlc_proto);
raw_hdlc_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev);
- int result;
- int (*old_ch_mtu)(struct net_device *, int);
- int old_qlen;
+ int result, old_qlen;
switch (ifr->ifr_settings.type) {
case IF_GET_PROTO:
@@ -99,11 +98,8 @@ static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
if (result)
return result;
memcpy(hdlc->state, &new_settings, size);
- dev->hard_start_xmit = eth_tx;
- old_ch_mtu = dev->change_mtu;
old_qlen = dev->tx_queue_len;
ether_setup(dev);
- dev->change_mtu = old_ch_mtu;
dev->tx_queue_len = old_qlen;
random_ether_addr(dev->dev_addr);
netif_dormant_off(dev);
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
index cbcbf6f0414c..b1dc29ed1583 100644
--- a/drivers/net/wan/hdlc_x25.c
+++ b/drivers/net/wan/hdlc_x25.c
@@ -184,6 +184,7 @@ static struct hdlc_proto proto = {
.close = x25_close,
.ioctl = x25_ioctl,
.netif_rx = x25_rx,
+ .xmit = x25_xmit,
.module = THIS_MODULE,
};
@@ -213,7 +214,6 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
if ((result = attach_hdlc_protocol(dev, &proto, 0)))
return result;
- dev->hard_start_xmit = x25_xmit;
dev->type = ARPHRD_X25;
netif_dormant_off(dev);
return 0;
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index af54f0cf1b35..567d4f5062d6 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -173,6 +173,14 @@ static int hostess_attach(struct net_device *dev, unsigned short encoding,
* Description block for a Comtrol Hostess SV11 card
*/
+static const struct net_device_ops hostess_ops = {
+ .ndo_open = hostess_open,
+ .ndo_stop = hostess_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = hostess_ioctl,
+};
+
static struct z8530_dev *sv11_init(int iobase, int irq)
{
struct z8530_dev *sv;
@@ -267,9 +275,7 @@ static struct z8530_dev *sv11_init(int iobase, int irq)
dev_to_hdlc(netdev)->attach = hostess_attach;
dev_to_hdlc(netdev)->xmit = hostess_queue_xmit;
- netdev->open = hostess_open;
- netdev->stop = hostess_close;
- netdev->do_ioctl = hostess_ioctl;
+ netdev->netdev_ops = &hostess_ops;
netdev->base_addr = iobase;
netdev->irq = irq;
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index 0dbd85b0162d..3bf7d3f447db 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -622,7 +622,7 @@ static void hss_hdlc_rx_irq(void *pdev)
printk(KERN_DEBUG "%s: hss_hdlc_rx_irq\n", dev->name);
#endif
qmgr_disable_irq(queue_ids[port->id].rx);
- netif_rx_schedule(&port->napi);
+ napi_schedule(&port->napi);
}
static int hss_hdlc_poll(struct napi_struct *napi, int budget)
@@ -649,15 +649,15 @@ static int hss_hdlc_poll(struct napi_struct *napi, int budget)
if ((n = queue_get_desc(rxq, port, 0)) < 0) {
#if DEBUG_RX
printk(KERN_DEBUG "%s: hss_hdlc_poll"
- " netif_rx_complete\n", dev->name);
+ " napi_complete\n", dev->name);
#endif
- netif_rx_complete(napi);
+ napi_complete(napi);
qmgr_enable_irq(rxq);
if (!qmgr_stat_empty(rxq) &&
- netif_rx_reschedule(napi)) {
+ napi_reschedule(napi)) {
#if DEBUG_RX
printk(KERN_DEBUG "%s: hss_hdlc_poll"
- " netif_rx_reschedule succeeded\n",
+ " napi_reschedule succeeded\n",
dev->name);
#endif
qmgr_disable_irq(rxq);
@@ -1069,7 +1069,7 @@ static int hss_hdlc_open(struct net_device *dev)
hss_start_hdlc(port);
/* we may already have RX data, enables IRQ */
- netif_rx_schedule(&port->napi);
+ napi_schedule(&port->napi);
return 0;
err_unlock:
@@ -1230,6 +1230,14 @@ static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
* initialization
****************************************************************************/
+static const struct net_device_ops hss_hdlc_ops = {
+ .ndo_open = hss_hdlc_open,
+ .ndo_stop = hss_hdlc_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = hss_hdlc_ioctl,
+};
+
static int __devinit hss_init_one(struct platform_device *pdev)
{
struct port *port;
@@ -1254,9 +1262,7 @@ static int __devinit hss_init_one(struct platform_device *pdev)
hdlc = dev_to_hdlc(dev);
hdlc->attach = hss_hdlc_attach;
hdlc->xmit = hss_hdlc_xmit;
- dev->open = hss_hdlc_open;
- dev->stop = hss_hdlc_close;
- dev->do_ioctl = hss_hdlc_ioctl;
+ dev->netdev_ops = &hss_hdlc_ops;
dev->tx_queue_len = 100;
port->clock_type = CLOCK_EXT;
port->clock_rate = 2048000;
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index 5b61b3eef45f..2dd78d20eb05 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -55,7 +55,6 @@ struct lapbethdev {
struct list_head node;
struct net_device *ethdev; /* link to ethernet device */
struct net_device *axdev; /* lapbeth device (lapb#) */
- struct net_device_stats stats; /* some statistics */
};
static LIST_HEAD(lapbeth_devices);
@@ -107,10 +106,9 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
if (!netif_running(lapbeth->axdev))
goto drop_unlock;
- lapbeth->stats.rx_packets++;
-
len = skb->data[0] + skb->data[1] * 256;
- lapbeth->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
skb_pull(skb, 2); /* Remove the length bytes */
skb_trim(skb, len); /* Set the length of the data */
@@ -210,8 +208,8 @@ static void lapbeth_data_transmit(struct net_device *ndev, struct sk_buff *skb)
*ptr++ = size % 256;
*ptr++ = size / 256;
- lapbeth->stats.tx_packets++;
- lapbeth->stats.tx_bytes += size;
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += size;
skb->dev = dev = lapbeth->ethdev;
@@ -255,15 +253,6 @@ static void lapbeth_disconnected(struct net_device *dev, int reason)
}
/*
- * Statistics
- */
-static struct net_device_stats *lapbeth_get_stats(struct net_device *dev)
-{
- struct lapbethdev *lapbeth = netdev_priv(dev);
- return &lapbeth->stats;
-}
-
-/*
* Set AX.25 callsign
*/
static int lapbeth_set_mac_address(struct net_device *dev, void *addr)
@@ -314,14 +303,17 @@ static int lapbeth_close(struct net_device *dev)
/* ------------------------------------------------------------------------ */
+static const struct net_device_ops lapbeth_netdev_ops = {
+ .ndo_open = lapbeth_open,
+ .ndo_stop = lapbeth_close,
+ .ndo_start_xmit = lapbeth_xmit,
+ .ndo_set_mac_address = lapbeth_set_mac_address,
+};
+
static void lapbeth_setup(struct net_device *dev)
{
- dev->hard_start_xmit = lapbeth_xmit;
- dev->open = lapbeth_open;
- dev->stop = lapbeth_close;
+ dev->netdev_ops = &lapbeth_netdev_ops;
dev->destructor = free_netdev;
- dev->set_mac_address = lapbeth_set_mac_address;
- dev->get_stats = lapbeth_get_stats;
dev->type = ARPHRD_X25;
dev->hard_header_len = 3;
dev->mtu = 1000;
@@ -421,8 +413,8 @@ static int lapbeth_device_event(struct notifier_block *this,
/* ------------------------------------------------------------------------ */
-static struct packet_type lapbeth_packet_type = {
- .type = __constant_htons(ETH_P_DEC),
+static struct packet_type lapbeth_packet_type __read_mostly = {
+ .type = cpu_to_be16(ETH_P_DEC),
.func = lapbeth_rcv,
};
@@ -430,7 +422,8 @@ static struct notifier_block lapbeth_dev_notifier = {
.notifier_call = lapbeth_device_event,
};
-static char banner[] __initdata = KERN_INFO "LAPB Ethernet driver version 0.02\n";
+static const char banner[] __initconst =
+ KERN_INFO "LAPB Ethernet driver version 0.02\n";
static int __init lapbeth_init_driver(void)
{
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index feac3b99f8fe..45b1822c962d 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -806,6 +806,16 @@ static int lmc_attach(struct net_device *dev, unsigned short encoding,
return -EINVAL;
}
+static const struct net_device_ops lmc_ops = {
+ .ndo_open = lmc_open,
+ .ndo_stop = lmc_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = lmc_ioctl,
+ .ndo_tx_timeout = lmc_driver_timeout,
+ .ndo_get_stats = lmc_get_stats,
+};
+
static int __devinit lmc_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -849,11 +859,7 @@ static int __devinit lmc_init_one(struct pci_dev *pdev,
dev->type = ARPHRD_HDLC;
dev_to_hdlc(dev)->xmit = lmc_start_xmit;
dev_to_hdlc(dev)->attach = lmc_attach;
- dev->open = lmc_open;
- dev->stop = lmc_close;
- dev->get_stats = lmc_get_stats;
- dev->do_ioctl = lmc_ioctl;
- dev->tx_timeout = lmc_driver_timeout;
+ dev->netdev_ops = &lmc_ops;
dev->watchdog_timeo = HZ; /* 1 second */
dev->tx_queue_len = 100;
sc->lmc_device = dev;
@@ -1059,9 +1065,6 @@ static int lmc_open(struct net_device *dev)
if ((err = lmc_proto_open(sc)) != 0)
return err;
- dev->do_ioctl = lmc_ioctl;
-
-
netif_start_queue(dev);
sc->extra_stats.tx_tbusy0++;
diff --git a/drivers/net/wan/lmc/lmc_proto.c b/drivers/net/wan/lmc/lmc_proto.c
index 94b4c208b013..044a48175c42 100644
--- a/drivers/net/wan/lmc/lmc_proto.c
+++ b/drivers/net/wan/lmc/lmc_proto.c
@@ -51,30 +51,15 @@
void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
{
lmc_trace(sc->lmc_device, "lmc_proto_attach in");
- switch(sc->if_type){
- case LMC_PPP:
- {
- struct net_device *dev = sc->lmc_device;
- dev->do_ioctl = lmc_ioctl;
- }
- break;
- case LMC_NET:
- {
+ if (sc->if_type == LMC_NET) {
struct net_device *dev = sc->lmc_device;
/*
* They set a few basics because they don't use HDLC
*/
dev->flags |= IFF_POINTOPOINT;
-
dev->hard_header_len = 0;
dev->addr_len = 0;
}
- case LMC_RAW: /* Setup the task queue, maybe we should notify someone? */
- {
- }
- default:
- break;
- }
lmc_trace(sc->lmc_device, "lmc_proto_attach out");
}
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
index 697715ae80f4..83da596e2052 100644
--- a/drivers/net/wan/n2.c
+++ b/drivers/net/wan/n2.c
@@ -324,7 +324,13 @@ static void n2_destroy_card(card_t *card)
kfree(card);
}
-
+static const struct net_device_ops n2_ops = {
+ .ndo_open = n2_open,
+ .ndo_stop = n2_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = n2_ioctl,
+};
static int __init n2_run(unsigned long io, unsigned long irq,
unsigned long winbase, long valid0, long valid1)
@@ -460,9 +466,7 @@ static int __init n2_run(unsigned long io, unsigned long irq,
dev->mem_start = winbase;
dev->mem_end = winbase + USE_WINDOWSIZE - 1;
dev->tx_queue_len = 50;
- dev->do_ioctl = n2_ioctl;
- dev->open = n2_open;
- dev->stop = n2_close;
+ dev->netdev_ops = &n2_ops;
hdlc->attach = sca_attach;
hdlc->xmit = sca_xmit;
port->settings.clock_type = CLOCK_EXT;
diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c
index f247e5d9002a..60ece54bdd94 100644
--- a/drivers/net/wan/pc300too.c
+++ b/drivers/net/wan/pc300too.c
@@ -287,7 +287,13 @@ static void pc300_pci_remove_one(struct pci_dev *pdev)
kfree(card);
}
-
+static const struct net_device_ops pc300_ops = {
+ .ndo_open = pc300_open,
+ .ndo_stop = pc300_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = pc300_ioctl,
+};
static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -448,9 +454,7 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
dev->mem_start = ramphys;
dev->mem_end = ramphys + ramsize - 1;
dev->tx_queue_len = 50;
- dev->do_ioctl = pc300_ioctl;
- dev->open = pc300_open;
- dev->stop = pc300_close;
+ dev->netdev_ops = &pc300_ops;
hdlc->attach = sca_attach;
hdlc->xmit = sca_xmit;
port->settings.clock_type = CLOCK_EXT;
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index 1104d3a692f7..e035d8c57e11 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -265,7 +265,13 @@ static void pci200_pci_remove_one(struct pci_dev *pdev)
kfree(card);
}
-
+static const struct net_device_ops pci200_ops = {
+ .ndo_open = pci200_open,
+ .ndo_stop = pci200_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = pci200_ioctl,
+};
static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -395,9 +401,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
dev->mem_start = ramphys;
dev->mem_end = ramphys + ramsize - 1;
dev->tx_queue_len = 50;
- dev->do_ioctl = pci200_ioctl;
- dev->open = pci200_open;
- dev->stop = pci200_close;
+ dev->netdev_ops = &pci200_ops;
hdlc->attach = sca_attach;
hdlc->xmit = sca_xmit;
port->settings.clock_type = CLOCK_EXT;
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index 0aa28e1d4366..f4211fe0f445 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -68,7 +68,6 @@
/* device private data */
struct net_local {
- struct net_device_stats stats;
struct timer_list watchdog;
spinlock_t lock;
@@ -117,7 +116,6 @@ static int sbni_open( struct net_device * );
static int sbni_close( struct net_device * );
static int sbni_start_xmit( struct sk_buff *, struct net_device * );
static int sbni_ioctl( struct net_device *, struct ifreq *, int );
-static struct net_device_stats *sbni_get_stats( struct net_device * );
static void set_multicast_list( struct net_device * );
static irqreturn_t sbni_interrupt( int, void * );
@@ -208,15 +206,21 @@ sbni_isa_probe( struct net_device *dev )
}
}
+static const struct net_device_ops sbni_netdev_ops = {
+ .ndo_open = sbni_open,
+ .ndo_stop = sbni_close,
+ .ndo_start_xmit = sbni_start_xmit,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_do_ioctl = sbni_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static void __init sbni_devsetup(struct net_device *dev)
{
ether_setup( dev );
- dev->open = &sbni_open;
- dev->stop = &sbni_close;
- dev->hard_start_xmit = &sbni_start_xmit;
- dev->get_stats = &sbni_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->do_ioctl = &sbni_ioctl;
+ dev->netdev_ops = &sbni_netdev_ops;
}
int __init sbni_probe(int unit)
@@ -229,6 +233,8 @@ int __init sbni_probe(int unit)
if (!dev)
return -ENOMEM;
+ dev->netdev_ops = &sbni_netdev_ops;
+
sprintf(dev->name, "sbni%d", unit);
netdev_boot_setup_check(dev);
@@ -723,13 +729,11 @@ upload_data( struct net_device *dev, unsigned framelen, unsigned frameno,
nl->wait_frameno = 0,
nl->inppos = 0,
#ifdef CONFIG_SBNI_MULTILINE
- ((struct net_local *)netdev_priv(nl->master))
- ->stats.rx_errors++,
- ((struct net_local *)netdev_priv(nl->master))
- ->stats.rx_missed_errors++;
+ nl->master->stats.rx_errors++,
+ nl->master->stats.rx_missed_errors++;
#else
- nl->stats.rx_errors++,
- nl->stats.rx_missed_errors++;
+ dev->stats.rx_errors++,
+ dev->stats.rx_missed_errors++;
#endif
/* now skip all frames until is_first != 0 */
} else
@@ -742,13 +746,11 @@ upload_data( struct net_device *dev, unsigned framelen, unsigned frameno,
*/
nl->wait_frameno = 0,
#ifdef CONFIG_SBNI_MULTILINE
- ((struct net_local *)netdev_priv(nl->master))
- ->stats.rx_errors++,
- ((struct net_local *)netdev_priv(nl->master))
- ->stats.rx_crc_errors++;
+ nl->master->stats.rx_errors++,
+ nl->master->stats.rx_crc_errors++;
#else
- nl->stats.rx_errors++,
- nl->stats.rx_crc_errors++;
+ dev->stats.rx_errors++,
+ dev->stats.rx_crc_errors++;
#endif
return frame_ok;
@@ -756,15 +758,16 @@ upload_data( struct net_device *dev, unsigned framelen, unsigned frameno,
static inline void
-send_complete( struct net_local *nl )
+send_complete( struct net_device *dev )
{
+ struct net_local *nl = netdev_priv(dev);
+
#ifdef CONFIG_SBNI_MULTILINE
- ((struct net_local *)netdev_priv(nl->master))->stats.tx_packets++;
- ((struct net_local *)netdev_priv(nl->master))->stats.tx_bytes
- += nl->tx_buf_p->len;
+ nl->master->stats.tx_packets++;
+ nl->master->stats.tx_bytes += nl->tx_buf_p->len;
#else
- nl->stats.tx_packets++;
- nl->stats.tx_bytes += nl->tx_buf_p->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += nl->tx_buf_p->len;
#endif
dev_kfree_skb_irq( nl->tx_buf_p );
@@ -792,7 +795,7 @@ interpret_ack( struct net_device *dev, unsigned ack )
nl->maxframe,
nl->tx_buf_p->len - nl->outpos);
else
- send_complete( nl ),
+ send_complete( dev ),
#ifdef CONFIG_SBNI_MULTILINE
netif_wake_queue( nl->master );
#else
@@ -881,13 +884,11 @@ drop_xmit_queue( struct net_device *dev )
dev_kfree_skb_any( nl->tx_buf_p ),
nl->tx_buf_p = NULL,
#ifdef CONFIG_SBNI_MULTILINE
- ((struct net_local *)netdev_priv(nl->master))
- ->stats.tx_errors++,
- ((struct net_local *)netdev_priv(nl->master))
- ->stats.tx_carrier_errors++;
+ nl->master->stats.tx_errors++,
+ nl->master->stats.tx_carrier_errors++;
#else
- nl->stats.tx_errors++,
- nl->stats.tx_carrier_errors++;
+ dev->stats.tx_errors++,
+ dev->stats.tx_carrier_errors++;
#endif
nl->tx_frameno = 0;
@@ -1017,14 +1018,13 @@ indicate_pkt( struct net_device *dev )
#ifdef CONFIG_SBNI_MULTILINE
skb->protocol = eth_type_trans( skb, nl->master );
netif_rx( skb );
- ++((struct net_local *)netdev_priv(nl->master))->stats.rx_packets;
- ((struct net_local *)netdev_priv(nl->master))->stats.rx_bytes +=
- nl->inppos;
+ ++nl->master->stats.rx_packets;
+ nl->master->stats.rx_bytes += nl->inppos;
#else
skb->protocol = eth_type_trans( skb, dev );
netif_rx( skb );
- ++nl->stats.rx_packets;
- nl->stats.rx_bytes += nl->inppos;
+ ++dev->stats.rx_packets;
+ dev->stats.rx_bytes += nl->inppos;
#endif
nl->rx_buf_p = NULL; /* protocol driver will clear this sk_buff */
}
@@ -1197,7 +1197,7 @@ sbni_open( struct net_device *dev )
handler_attached:
spin_lock( &nl->lock );
- memset( &nl->stats, 0, sizeof(struct net_device_stats) );
+ memset( &dev->stats, 0, sizeof(struct net_device_stats) );
memset( &nl->in_stats, 0, sizeof(struct sbni_in_stats) );
card_start( dev );
@@ -1413,7 +1413,7 @@ enslave( struct net_device *dev, struct net_device *slave_dev )
/* Summary statistics of MultiLine operation will be stored
in master's counters */
- memset( &snl->stats, 0, sizeof(struct net_device_stats) );
+ memset( &slave_dev->stats, 0, sizeof(struct net_device_stats) );
netif_stop_queue( slave_dev );
netif_wake_queue( dev ); /* Now we are able to transmit */
@@ -1464,14 +1464,6 @@ emancipate( struct net_device *dev )
#endif
-
-static struct net_device_stats *
-sbni_get_stats( struct net_device *dev )
-{
- return &((struct net_local *)netdev_priv(dev))->stats;
-}
-
-
static void
set_multicast_list( struct net_device *dev )
{
@@ -1520,17 +1512,18 @@ int __init init_module( void )
}
void
-cleanup_module( void )
+cleanup_module(void)
{
- struct net_device *dev;
- int num;
+ int i;
- for( num = 0; num < SBNI_MAX_NUM_CARDS; ++num )
- if( (dev = sbni_cards[ num ]) != NULL ) {
- unregister_netdev( dev );
- release_region( dev->base_addr, SBNI_IO_EXTENT );
- free_netdev( dev );
+ for (i = 0; i < SBNI_MAX_NUM_CARDS; ++i) {
+ struct net_device *dev = sbni_cards[i];
+ if (dev != NULL) {
+ unregister_netdev(dev);
+ release_region(dev->base_addr, SBNI_IO_EXTENT);
+ free_netdev(dev);
}
+ }
}
#else /* MODULE */
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index 6a07ba9371db..1d637f407a0c 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -714,19 +714,19 @@ static int sdla_transmit(struct sk_buff *skb, struct net_device *dev)
switch (ret)
{
case SDLA_RET_OK:
- flp->stats.tx_packets++;
+ dev->stats.tx_packets++;
ret = DLCI_RET_OK;
break;
case SDLA_RET_CIR_OVERFLOW:
case SDLA_RET_BUF_OVERSIZE:
case SDLA_RET_NO_BUFS:
- flp->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
ret = DLCI_RET_DROP;
break;
default:
- flp->stats.tx_errors++;
+ dev->stats.tx_errors++;
ret = DLCI_RET_ERR;
break;
}
@@ -807,7 +807,7 @@ static void sdla_receive(struct net_device *dev)
if (i == CONFIG_DLCI_MAX)
{
printk(KERN_NOTICE "%s: Received packet from invalid DLCI %i, ignoring.", dev->name, dlci);
- flp->stats.rx_errors++;
+ dev->stats.rx_errors++;
success = 0;
}
}
@@ -819,7 +819,7 @@ static void sdla_receive(struct net_device *dev)
if (skb == NULL)
{
printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
- flp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
success = 0;
}
else
@@ -859,7 +859,7 @@ static void sdla_receive(struct net_device *dev)
if (success)
{
- flp->stats.rx_packets++;
+ dev->stats.rx_packets++;
dlp = netdev_priv(master);
(*dlp->receive)(skb, master);
}
@@ -1590,13 +1590,14 @@ fail:
return err;
}
-static struct net_device_stats *sdla_stats(struct net_device *dev)
-{
- struct frad_local *flp;
- flp = netdev_priv(dev);
-
- return(&flp->stats);
-}
+static const struct net_device_ops sdla_netdev_ops = {
+ .ndo_open = sdla_open,
+ .ndo_stop = sdla_close,
+ .ndo_do_ioctl = sdla_ioctl,
+ .ndo_set_config = sdla_set_config,
+ .ndo_start_xmit = sdla_transmit,
+ .ndo_change_mtu = sdla_change_mtu,
+};
static void setup_sdla(struct net_device *dev)
{
@@ -1604,20 +1605,13 @@ static void setup_sdla(struct net_device *dev)
netdev_boot_setup_check(dev);
+ dev->netdev_ops = &sdla_netdev_ops;
dev->flags = 0;
dev->type = 0xFFFF;
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->mtu = SDLA_MAX_MTU;
- dev->open = sdla_open;
- dev->stop = sdla_close;
- dev->do_ioctl = sdla_ioctl;
- dev->set_config = sdla_set_config;
- dev->get_stats = sdla_stats;
- dev->hard_start_xmit = sdla_transmit;
- dev->change_mtu = sdla_change_mtu;
-
flp->activate = sdla_activate;
flp->deactivate = sdla_deactivate;
flp->assoc = sdla_assoc;
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
index 0941a26f6e3f..23b269027453 100644
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -169,6 +169,14 @@ static int sealevel_attach(struct net_device *dev, unsigned short encoding,
return -EINVAL;
}
+static const struct net_device_ops sealevel_ops = {
+ .ndo_open = sealevel_open,
+ .ndo_stop = sealevel_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = sealevel_ioctl,
+};
+
static int slvl_setup(struct slvl_device *sv, int iobase, int irq)
{
struct net_device *dev = alloc_hdlcdev(sv);
@@ -177,9 +185,7 @@ static int slvl_setup(struct slvl_device *sv, int iobase, int irq)
dev_to_hdlc(dev)->attach = sealevel_attach;
dev_to_hdlc(dev)->xmit = sealevel_queue_xmit;
- dev->open = sealevel_open;
- dev->stop = sealevel_close;
- dev->do_ioctl = sealevel_ioctl;
+ dev->netdev_ops = &sealevel_ops;
dev->base_addr = iobase;
dev->irq = irq;
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index 4bffb67ebcae..887acb0dc807 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -547,6 +547,15 @@ static void wanxl_pci_remove_one(struct pci_dev *pdev)
#include "wanxlfw.inc"
+static const struct net_device_ops wanxl_ops = {
+ .ndo_open = wanxl_open,
+ .ndo_stop = wanxl_close,
+ .ndo_change_mtu = hdlc_change_mtu,
+ .ndo_start_xmit = hdlc_start_xmit,
+ .ndo_do_ioctl = wanxl_ioctl,
+ .ndo_get_stats = wanxl_get_stats,
+};
+
static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -777,12 +786,9 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
hdlc = dev_to_hdlc(dev);
spin_lock_init(&port->lock);
dev->tx_queue_len = 50;
- dev->do_ioctl = wanxl_ioctl;
- dev->open = wanxl_open;
- dev->stop = wanxl_close;
+ dev->netdev_ops = &wanxl_ops;
hdlc->attach = wanxl_attach;
hdlc->xmit = wanxl_xmit;
- dev->get_stats = wanxl_get_stats;
port->card = card;
port->node = i;
get_status(port)->clocking = CLOCK_EXT;
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index e6e2ce3e7bcf..d67e208ab375 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -142,7 +142,7 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
memcpy(sl->xbuff, sl->xhead, sl->xleft);
} else {
sl->xleft = 0;
- sl->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
}
}
sl->xhead = sl->xbuff;
@@ -153,7 +153,7 @@ static int x25_asy_change_mtu(struct net_device *dev, int newmtu)
memcpy(sl->rbuff, rbuff, sl->rcount);
} else {
sl->rcount = 0;
- sl->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
set_bit(SLF_ERROR, &sl->flags);
}
}
@@ -188,18 +188,19 @@ static inline void x25_asy_unlock(struct x25_asy *sl)
static void x25_asy_bump(struct x25_asy *sl)
{
+ struct net_device *dev = sl->dev;
struct sk_buff *skb;
int count;
int err;
count = sl->rcount;
- sl->stats.rx_bytes += count;
+ dev->stats.rx_bytes += count;
skb = dev_alloc_skb(count+1);
if (skb == NULL) {
printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n",
sl->dev->name);
- sl->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
skb_push(skb, 1); /* LAPB internal control */
@@ -211,7 +212,7 @@ static void x25_asy_bump(struct x25_asy *sl)
printk(KERN_DEBUG "x25_asy: data received err - %d\n", err);
} else {
netif_rx(skb);
- sl->stats.rx_packets++;
+ dev->stats.rx_packets++;
}
}
@@ -226,7 +227,7 @@ static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len)
len = mtu;
printk(KERN_DEBUG "%s: truncating oversized transmit packet!\n",
sl->dev->name);
- sl->stats.tx_dropped++;
+ sl->dev->stats.tx_dropped++;
x25_asy_unlock(sl);
return;
}
@@ -266,7 +267,7 @@ static void x25_asy_write_wakeup(struct tty_struct *tty)
if (sl->xleft <= 0) {
/* Now serial buffer is almost free & we can start
* transmission of another packet */
- sl->stats.tx_packets++;
+ sl->dev->stats.tx_packets++;
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
x25_asy_unlock(sl);
return;
@@ -383,7 +384,7 @@ static void x25_asy_data_transmit(struct net_device *dev, struct sk_buff *skb)
/* We were not busy, so we are now... :-) */
if (skb != NULL) {
x25_asy_lock(sl);
- sl->stats.tx_bytes += skb->len;
+ dev->stats.tx_bytes += skb->len;
x25_asy_encaps(sl, skb->data, skb->len);
dev_kfree_skb(skb);
}
@@ -533,7 +534,7 @@ static void x25_asy_receive_buf(struct tty_struct *tty,
while (count--) {
if (fp && *fp++) {
if (!test_and_set_bit(SLF_ERROR, &sl->flags))
- sl->stats.rx_errors++;
+ sl->dev->stats.rx_errors++;
cp++;
continue;
}
@@ -608,14 +609,6 @@ static void x25_asy_close_tty(struct tty_struct *tty)
x25_asy_free(sl);
}
-
-static struct net_device_stats *x25_asy_get_stats(struct net_device *dev)
-{
- struct x25_asy *sl = netdev_priv(dev);
- return &sl->stats;
-}
-
-
/************************************************************************
* STANDARD X.25 ENCAPSULATION *
************************************************************************/
@@ -682,7 +675,7 @@ static void x25_asy_unesc(struct x25_asy *sl, unsigned char s)
sl->rbuff[sl->rcount++] = s;
return;
}
- sl->stats.rx_over_errors++;
+ sl->dev->stats.rx_over_errors++;
set_bit(SLF_ERROR, &sl->flags);
}
}
@@ -719,6 +712,14 @@ static int x25_asy_open_dev(struct net_device *dev)
return 0;
}
+static const struct net_device_ops x25_asy_netdev_ops = {
+ .ndo_open = x25_asy_open_dev,
+ .ndo_stop = x25_asy_close,
+ .ndo_start_xmit = x25_asy_xmit,
+ .ndo_tx_timeout = x25_asy_timeout,
+ .ndo_change_mtu = x25_asy_change_mtu,
+};
+
/* Initialise the X.25 driver. Called by the device init code */
static void x25_asy_setup(struct net_device *dev)
{
@@ -734,13 +735,8 @@ static void x25_asy_setup(struct net_device *dev)
*/
dev->mtu = SL_MTU;
- dev->hard_start_xmit = x25_asy_xmit;
- dev->tx_timeout = x25_asy_timeout;
+ dev->netdev_ops = &x25_asy_netdev_ops;
dev->watchdog_timeo = HZ*20;
- dev->open = x25_asy_open_dev;
- dev->stop = x25_asy_close;
- dev->get_stats = x25_asy_get_stats;
- dev->change_mtu = x25_asy_change_mtu;
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->type = ARPHRD_X25;
diff --git a/drivers/net/wan/x25_asy.h b/drivers/net/wan/x25_asy.h
index 41770200ceb6..8f0fc2e57e2b 100644
--- a/drivers/net/wan/x25_asy.h
+++ b/drivers/net/wan/x25_asy.h
@@ -28,10 +28,6 @@ struct x25_asy {
unsigned char *xbuff; /* transmitter buffer */
unsigned char *xhead; /* pointer to next byte to XMIT */
int xleft; /* bytes left in XMIT queue */
-
- /* X.25 interface statistics. */
- struct net_device_stats stats;
-
int buffsize; /* Max buffers sizes */
unsigned long flags; /* Flag values/ mode etc */
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
index 3d00971fe5ee..ad4e79c4c5c3 100644
--- a/drivers/net/wan/z85230.c
+++ b/drivers/net/wan/z85230.c
@@ -1775,7 +1775,8 @@ EXPORT_SYMBOL(z8530_queue_xmit);
/*
* Module support
*/
-static char banner[] __initdata = KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n";
+static const char banner[] __initdata =
+ KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n";
static int __init z85230_init_driver(void)
{
diff --git a/drivers/net/wimax/i2400m/Makefile b/drivers/net/wimax/i2400m/Makefile
index 1696e936cf5a..5d9e018d31af 100644
--- a/drivers/net/wimax/i2400m/Makefile
+++ b/drivers/net/wimax/i2400m/Makefile
@@ -8,6 +8,7 @@ i2400m-y := \
driver.o \
fw.o \
op-rfkill.o \
+ sysfs.o \
netdev.o \
tx.o \
rx.o
diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c
index 15d9f51b292c..b3cadb626fe0 100644
--- a/drivers/net/wimax/i2400m/control.c
+++ b/drivers/net/wimax/i2400m/control.c
@@ -52,7 +52,6 @@
*
* i2400m_dev_initalize() Called by i2400m_dev_start()
* i2400m_set_init_config()
- * i2400m_firmware_check()
* i2400m_cmd_get_state()
* i2400m_dev_shutdown() Called by i2400m_dev_stop()
* i2400m->bus_reset()
@@ -942,8 +941,8 @@ error_cmd_failed:
/* Firmware interface versions we support */
enum {
I2400M_HDIv_MAJOR = 9,
- I2400M_HDIv_MAJOR_2 = 8,
I2400M_HDIv_MINOR = 1,
+ I2400M_HDIv_MINOR_2 = 2,
};
@@ -959,6 +958,10 @@ enum {
* Long function, but quite simple; first chunk launches the command
* and double checks the reply for the right TLV. Then we process the
* TLV (where the meat is).
+ *
+ * Once we process the TLV that gives us the firmware's interface
+ * version, we encode it and save it in i2400m->fw_version for future
+ * reference.
*/
int i2400m_firmware_check(struct i2400m *i2400m)
{
@@ -1009,22 +1012,20 @@ int i2400m_firmware_check(struct i2400m *i2400m)
minor = le16_to_cpu(l4mv->minor);
branch = le16_to_cpu(l4mv->branch);
result = -EINVAL;
- if (major != I2400M_HDIv_MAJOR
- && major != I2400M_HDIv_MAJOR_2) {
- dev_err(dev, "unsupported major fw interface version "
+ if (major != I2400M_HDIv_MAJOR) {
+ dev_err(dev, "unsupported major fw version "
"%u.%u.%u\n", major, minor, branch);
goto error_bad_major;
}
- if (major == I2400M_HDIv_MAJOR_2)
- dev_err(dev, "deprecated major fw interface version "
- "%u.%u.%u\n", major, minor, branch);
result = 0;
- if (minor != I2400M_HDIv_MINOR)
- dev_warn(dev, "untested minor fw firmware version %u.%u.%u\n",
+ if (minor < I2400M_HDIv_MINOR_2 && minor > I2400M_HDIv_MINOR)
+ dev_warn(dev, "untested minor fw version %u.%u.%u\n",
major, minor, branch);
-error_bad_major:
+ /* Yes, we ignore the branch -- we don't have to track it */
+ i2400m->fw_version = major << 16 | minor;
dev_info(dev, "firmware interface version %u.%u.%u\n",
major, minor, branch);
+error_bad_major:
error_no_tlv:
error_cmd_failed:
kfree_skb(ack_skb);
@@ -1221,6 +1222,77 @@ EXPORT_SYMBOL_GPL(i2400m_set_init_config);
/**
+ * i2400m_set_idle_timeout - Set the device's idle mode timeout
+ *
+ * @i2400m: i2400m device descriptor
+ *
+ * @msecs: milliseconds for the timeout to enter idle mode. Between
+ * 100 to 300000 (5m); 0 to disable. In increments of 100.
+ *
+ * After this @msecs of the link being idle (no data being sent or
+ * received), the device will negotiate with the basestation entering
+ * idle mode for saving power. The connection is maintained, but
+ * getting out of it (done in tx.c) will require some negotiation,
+ * possible crypto re-handshake and a possible DHCP re-lease.
+ *
+ * Only available if fw_version >= 0x00090002.
+ *
+ * Returns: 0 if ok, < 0 errno code on error.
+ */
+int i2400m_set_idle_timeout(struct i2400m *i2400m, unsigned msecs)
+{
+ int result;
+ struct device *dev = i2400m_dev(i2400m);
+ struct sk_buff *ack_skb;
+ struct {
+ struct i2400m_l3l4_hdr hdr;
+ struct i2400m_tlv_config_idle_timeout cit;
+ } *cmd;
+ const struct i2400m_l3l4_hdr *ack;
+ size_t ack_len;
+ char strerr[32];
+
+ result = -ENOSYS;
+ if (i2400m_le_v1_3(i2400m))
+ goto error_alloc;
+ result = -ENOMEM;
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ goto error_alloc;
+ cmd->hdr.type = cpu_to_le16(I2400M_MT_GET_STATE);
+ cmd->hdr.length = cpu_to_le16(sizeof(*cmd) - sizeof(cmd->hdr));
+ cmd->hdr.version = cpu_to_le16(I2400M_L3L4_VERSION);
+
+ cmd->cit.hdr.type =
+ cpu_to_le16(I2400M_TLV_CONFIG_IDLE_TIMEOUT);
+ cmd->cit.hdr.length = cpu_to_le16(sizeof(cmd->cit.timeout));
+ cmd->cit.timeout = cpu_to_le32(msecs);
+
+ ack_skb = i2400m_msg_to_dev(i2400m, cmd, sizeof(*cmd));
+ if (IS_ERR(ack_skb)) {
+ dev_err(dev, "Failed to issue 'set idle timeout' command: "
+ "%ld\n", PTR_ERR(ack_skb));
+ result = PTR_ERR(ack_skb);
+ goto error_msg_to_dev;
+ }
+ ack = wimax_msg_data_len(ack_skb, &ack_len);
+ result = i2400m_msg_check_status(ack, strerr, sizeof(strerr));
+ if (result < 0) {
+ dev_err(dev, "'set idle timeout' (0x%04x) command failed: "
+ "%d - %s\n", I2400M_MT_GET_STATE, result, strerr);
+ goto error_cmd_failed;
+ }
+ result = 0;
+ kfree_skb(ack_skb);
+error_cmd_failed:
+error_msg_to_dev:
+ kfree(cmd);
+error_alloc:
+ return result;
+}
+
+
+/**
* i2400m_dev_initialize - Initialize the device once communications are ready
*
* @i2400m: device descriptor
@@ -1238,26 +1310,55 @@ int i2400m_dev_initialize(struct i2400m *i2400m)
int result;
struct device *dev = i2400m_dev(i2400m);
struct i2400m_tlv_config_idle_parameters idle_params;
+ struct i2400m_tlv_config_idle_timeout idle_timeout;
+ struct i2400m_tlv_config_d2h_data_format df;
+ struct i2400m_tlv_config_dl_host_reorder dlhr;
const struct i2400m_tlv_hdr *args[9];
unsigned argc = 0;
d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
- /* Useless for now...might change */
+ /* Disable idle mode? (enabled by default) */
if (i2400m_idle_mode_disabled) {
- idle_params.hdr.type =
- cpu_to_le16(I2400M_TLV_CONFIG_IDLE_PARAMETERS);
- idle_params.hdr.length = cpu_to_le16(
- sizeof(idle_params) - sizeof(idle_params.hdr));
- idle_params.idle_timeout = 0;
- idle_params.idle_paging_interval = 0;
- args[argc++] = &idle_params.hdr;
+ if (i2400m_le_v1_3(i2400m)) {
+ idle_params.hdr.type =
+ cpu_to_le16(I2400M_TLV_CONFIG_IDLE_PARAMETERS);
+ idle_params.hdr.length = cpu_to_le16(
+ sizeof(idle_params) - sizeof(idle_params.hdr));
+ idle_params.idle_timeout = 0;
+ idle_params.idle_paging_interval = 0;
+ args[argc++] = &idle_params.hdr;
+ } else {
+ idle_timeout.hdr.type =
+ cpu_to_le16(I2400M_TLV_CONFIG_IDLE_TIMEOUT);
+ idle_timeout.hdr.length = cpu_to_le16(
+ sizeof(idle_timeout) - sizeof(idle_timeout.hdr));
+ idle_timeout.timeout = 0;
+ args[argc++] = &idle_timeout.hdr;
+ }
+ }
+ if (i2400m_ge_v1_4(i2400m)) {
+ /* Enable extended RX data format? */
+ df.hdr.type =
+ cpu_to_le16(I2400M_TLV_CONFIG_D2H_DATA_FORMAT);
+ df.hdr.length = cpu_to_le16(
+ sizeof(df) - sizeof(df.hdr));
+ df.format = 1;
+ args[argc++] = &df.hdr;
+
+ /* Enable RX data reordering?
+ * (switch flipped in rx.c:i2400m_rx_setup() after fw upload) */
+ if (i2400m->rx_reorder) {
+ dlhr.hdr.type =
+ cpu_to_le16(I2400M_TLV_CONFIG_DL_HOST_REORDER);
+ dlhr.hdr.length = cpu_to_le16(
+ sizeof(dlhr) - sizeof(dlhr.hdr));
+ dlhr.reorder = 1;
+ args[argc++] = &dlhr.hdr;
+ }
}
result = i2400m_set_init_config(i2400m, args, argc);
if (result < 0)
goto error;
- result = i2400m_firmware_check(i2400m); /* fw versions ok? */
- if (result < 0)
- goto error;
/*
* Update state: Here it just calls a get state; parsing the
* result (System State TLV and RF Status TLV [done in the rx
@@ -1266,6 +1367,8 @@ int i2400m_dev_initialize(struct i2400m *i2400m)
*/
result = i2400m_cmd_get_state(i2400m);
error:
+ if (result < 0)
+ dev_err(dev, "failed to initialize the device: %d\n", result);
d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
return result;
}
diff --git a/drivers/net/wimax/i2400m/debug-levels.h b/drivers/net/wimax/i2400m/debug-levels.h
index 3183baa16a52..48fbfaa0d403 100644
--- a/drivers/net/wimax/i2400m/debug-levels.h
+++ b/drivers/net/wimax/i2400m/debug-levels.h
@@ -38,6 +38,7 @@ enum d_module {
D_SUBMODULE_DECLARE(netdev),
D_SUBMODULE_DECLARE(rfkill),
D_SUBMODULE_DECLARE(rx),
+ D_SUBMODULE_DECLARE(sysfs),
D_SUBMODULE_DECLARE(tx),
};
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index e80a0b65a754..07a54bad237b 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -48,6 +48,7 @@
* i2400m_dev_bootstrap()
* i2400m_tx_setup()
* i2400m->bus_dev_start()
+ * i2400m_firmware_check()
* i2400m_check_mac_addr()
* wimax_dev_add()
*
@@ -75,6 +76,11 @@ MODULE_PARM_DESC(idle_mode_disabled,
"If true, the device will not enable idle mode negotiation "
"with the base station (when connected) to save power.");
+int i2400m_rx_reorder_disabled; /* 0 (rx reorder enabled) by default */
+module_param_named(rx_reorder_disabled, i2400m_rx_reorder_disabled, int, 0644);
+MODULE_PARM_DESC(rx_reorder_disabled,
+ "If true, RX reordering will be disabled.");
+
/**
* i2400m_queue_work - schedule work on a i2400m's queue
*
@@ -395,6 +401,9 @@ retry:
result = i2400m_tx_setup(i2400m);
if (result < 0)
goto error_tx_setup;
+ result = i2400m_rx_setup(i2400m);
+ if (result < 0)
+ goto error_rx_setup;
result = i2400m->bus_dev_start(i2400m);
if (result < 0)
goto error_bus_dev_start;
@@ -404,6 +413,9 @@ retry:
dev_err(dev, "cannot create workqueue\n");
goto error_create_workqueue;
}
+ result = i2400m_firmware_check(i2400m); /* fw versions ok? */
+ if (result < 0)
+ goto error_fw_check;
/* At this point is ok to send commands to the device */
result = i2400m_check_mac_addr(i2400m);
if (result < 0)
@@ -421,10 +433,13 @@ retry:
error_dev_initialize:
error_check_mac_addr:
+error_fw_check:
destroy_workqueue(i2400m->work_queue);
error_create_workqueue:
i2400m->bus_dev_stop(i2400m);
error_bus_dev_start:
+ i2400m_rx_release(i2400m);
+error_rx_setup:
i2400m_tx_release(i2400m);
error_tx_setup:
error_bootstrap:
@@ -472,6 +487,7 @@ void __i2400m_dev_stop(struct i2400m *i2400m)
i2400m->ready = 0;
destroy_workqueue(i2400m->work_queue);
i2400m->bus_dev_stop(i2400m);
+ i2400m_rx_release(i2400m);
i2400m_tx_release(i2400m);
wimax_state_change(wimax_dev, WIMAX_ST_DOWN);
d_fnend(3, dev, "(i2400m %p) = 0\n", i2400m);
@@ -613,7 +629,7 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
snprintf(wimax_dev->name, sizeof(wimax_dev->name),
- "i2400m-%s:%s", dev->bus->name, dev->bus_id);
+ "i2400m-%s:%s", dev->bus->name, dev_name(dev));
i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL);
if (i2400m->bm_cmd_buf == NULL) {
@@ -657,6 +673,11 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
wimax_state_change(wimax_dev, WIMAX_ST_UNINITIALIZED);
/* Now setup all that requires a registered net and wimax device. */
+ result = sysfs_create_group(&net_dev->dev.kobj, &i2400m_dev_attr_group);
+ if (result < 0) {
+ dev_err(dev, "cannot setup i2400m's sysfs: %d\n", result);
+ goto error_sysfs_setup;
+ }
result = i2400m_debugfs_add(i2400m);
if (result < 0) {
dev_err(dev, "cannot setup i2400m's debugfs: %d\n", result);
@@ -666,6 +687,9 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
return result;
error_debugfs_setup:
+ sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj,
+ &i2400m_dev_attr_group);
+error_sysfs_setup:
wimax_dev_rm(&i2400m->wimax_dev);
error_wimax_dev_add:
i2400m_dev_stop(i2400m);
@@ -697,6 +721,8 @@ void i2400m_release(struct i2400m *i2400m)
netif_stop_queue(i2400m->wimax_dev.net_dev);
i2400m_debugfs_rm(i2400m);
+ sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj,
+ &i2400m_dev_attr_group);
wimax_dev_rm(&i2400m->wimax_dev);
i2400m_dev_stop(i2400m);
unregister_netdev(i2400m->wimax_dev.net_dev);
diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c
index 1d8271f34c38..675c6ce810c0 100644
--- a/drivers/net/wimax/i2400m/fw.c
+++ b/drivers/net/wimax/i2400m/fw.c
@@ -140,10 +140,10 @@
static const __le32 i2400m_ACK_BARKER[4] = {
- __constant_cpu_to_le32(I2400M_ACK_BARKER),
- __constant_cpu_to_le32(I2400M_ACK_BARKER),
- __constant_cpu_to_le32(I2400M_ACK_BARKER),
- __constant_cpu_to_le32(I2400M_ACK_BARKER)
+ cpu_to_le32(I2400M_ACK_BARKER),
+ cpu_to_le32(I2400M_ACK_BARKER),
+ cpu_to_le32(I2400M_ACK_BARKER),
+ cpu_to_le32(I2400M_ACK_BARKER)
};
@@ -483,7 +483,7 @@ ssize_t i2400m_dnload_bcf(struct i2400m *i2400m,
if (offset + section_size > bcf_len) {
dev_err(dev, "fw %s: bad section #%zu, "
"end (@%zu) beyond EOF (@%zu)\n",
- i2400m->bus_fw_name, section,
+ i2400m->fw_name, section,
offset + section_size, bcf_len);
ret = -EINVAL;
goto error_section_beyond_eof;
@@ -493,7 +493,7 @@ ssize_t i2400m_dnload_bcf(struct i2400m *i2400m,
&ack, sizeof(ack), I2400M_BM_CMD_RAW);
if (ret < 0) {
dev_err(dev, "fw %s: section #%zu (@%zu %zu B) "
- "failed %d\n", i2400m->bus_fw_name, section,
+ "failed %d\n", i2400m->fw_name, section,
offset, sizeof(*bh) + data_size, (int) ret);
goto error_send;
}
@@ -771,8 +771,8 @@ static
int i2400m_dnload_init_nonsigned(struct i2400m *i2400m)
{
#define POKE(a, d) { \
- .address = __constant_cpu_to_le32(a), \
- .data = __constant_cpu_to_le32(d) \
+ .address = cpu_to_le32(a), \
+ .data = cpu_to_le32(d) \
}
static const struct {
__le32 address;
@@ -874,7 +874,7 @@ int i2400m_dnload_init(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf)
if (result < 0)
dev_err(dev, "fw %s: non-signed download "
"initialization failed: %d\n",
- i2400m->bus_fw_name, result);
+ i2400m->fw_name, result);
} else if (i2400m->sboot == 0
&& (module_id & I2400M_BCF_MOD_ID_POKES)) {
/* non-signed boot process with pokes, nothing to do */
@@ -886,7 +886,7 @@ int i2400m_dnload_init(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf)
if (result < 0)
dev_err(dev, "fw %s: signed boot download "
"initialization failed: %d\n",
- i2400m->bus_fw_name, result);
+ i2400m->fw_name, result);
}
return result;
}
@@ -915,7 +915,7 @@ int i2400m_fw_check(struct i2400m *i2400m,
if (bcf_size < sizeof(*bcf)) { /* big enough header? */
dev_err(dev, "firmware %s too short: "
"%zu B vs %zu (at least) expected\n",
- i2400m->bus_fw_name, bcf_size, sizeof(*bcf));
+ i2400m->fw_name, bcf_size, sizeof(*bcf));
goto error;
}
@@ -931,7 +931,7 @@ int i2400m_fw_check(struct i2400m *i2400m,
if (bcf_size != size) { /* annoyingly paranoid */
dev_err(dev, "firmware %s: bad size, got "
"%zu B vs %u expected\n",
- i2400m->bus_fw_name, bcf_size, size);
+ i2400m->fw_name, bcf_size, size);
goto error;
}
@@ -943,7 +943,7 @@ int i2400m_fw_check(struct i2400m *i2400m,
if (module_type != 6) { /* built for the right hardware? */
dev_err(dev, "bad fw %s: unexpected module type 0x%x; "
- "aborting\n", i2400m->bus_fw_name, module_type);
+ "aborting\n", i2400m->fw_name, module_type);
goto error;
}
@@ -951,10 +951,10 @@ int i2400m_fw_check(struct i2400m *i2400m,
result = 0;
if (module_vendor != 0x8086)
dev_err(dev, "bad fw %s? unexpected vendor 0x%04x\n",
- i2400m->bus_fw_name, module_vendor);
+ i2400m->fw_name, module_vendor);
if (date < 0x20080300)
dev_err(dev, "bad fw %s? build date too old %08x\n",
- i2400m->bus_fw_name, date);
+ i2400m->fw_name, date);
error:
return result;
}
@@ -1016,7 +1016,7 @@ hw_reboot:
goto error_dev_rebooted;
if (ret < 0) {
dev_err(dev, "fw %s: download failed: %d\n",
- i2400m->bus_fw_name, ret);
+ i2400m->fw_name, ret);
goto error_dnload_bcf;
}
@@ -1026,12 +1026,12 @@ hw_reboot:
if (ret < 0) {
dev_err(dev, "fw %s: "
"download finalization failed: %d\n",
- i2400m->bus_fw_name, ret);
+ i2400m->fw_name, ret);
goto error_dnload_finalize;
}
d_printf(2, dev, "fw %s successfully uploaded\n",
- i2400m->bus_fw_name);
+ i2400m->fw_name);
i2400m->boot_mode = 0;
error_dnload_finalize:
error_dnload_bcf:
@@ -1067,28 +1067,41 @@ error_dev_rebooted:
*/
int i2400m_dev_bootstrap(struct i2400m *i2400m, enum i2400m_bri flags)
{
- int ret = 0;
+ int ret = 0, itr = 0;
struct device *dev = i2400m_dev(i2400m);
const struct firmware *fw;
const struct i2400m_bcf_hdr *bcf; /* Firmware data */
+ const char *fw_name;
d_fnstart(5, dev, "(i2400m %p)\n", i2400m);
+
/* Load firmware files to memory. */
- ret = request_firmware(&fw, i2400m->bus_fw_name, dev);
- if (ret) {
- dev_err(dev, "fw %s: request failed: %d\n",
- i2400m->bus_fw_name, ret);
- goto error_fw_req;
+ itr = 0;
+ while(1) {
+ fw_name = i2400m->bus_fw_names[itr];
+ if (fw_name == NULL) {
+ dev_err(dev, "Could not find a usable firmware image\n");
+ ret = -ENOENT;
+ goto error_no_fw;
+ }
+ ret = request_firmware(&fw, fw_name, dev);
+ if (ret == 0)
+ break; /* got it */
+ if (ret < 0)
+ dev_err(dev, "fw %s: cannot load file: %d\n",
+ fw_name, ret);
+ itr++;
}
- bcf = (void *) fw->data;
+ bcf = (void *) fw->data;
+ i2400m->fw_name = fw_name;
ret = i2400m_fw_check(i2400m, bcf, fw->size);
if (ret < 0)
goto error_fw_bad;
ret = i2400m_fw_dnload(i2400m, bcf, fw->size, flags);
error_fw_bad:
release_firmware(fw);
-error_fw_req:
+error_no_fw:
d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret);
return ret;
}
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index 3b9d27ea2950..3ae2df38b59a 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -156,10 +156,6 @@ enum {
};
-/* Firmware version we request when pulling the fw image file */
-#define I2400M_FW_VERSION "1.4"
-
-
/**
* i2400m_reset_type - methods to reset a device
*
@@ -178,6 +174,7 @@ enum i2400m_reset_type {
};
struct i2400m_reset_ctx;
+struct i2400m_roq;
/**
* struct i2400m - descriptor for an Intel 2400m
@@ -242,10 +239,14 @@ struct i2400m_reset_ctx;
* The caller to this function will check if the response is a
* barker that indicates the device going into reset mode.
*
- * @bus_fw_name: [fill] name of the firmware image (in most cases,
- * they are all the same for a single release, except that they
- * have the type of the bus embedded in the name (eg:
- * i2400m-fw-X-VERSION.sbcf, where X is the bus name).
+ * @bus_fw_names: [fill] a NULL-terminated array with the names of the
+ * firmware images to try loading. This is made a list so we can
+ * support backward compatibility of firmware releases (eg: if we
+ * can't find the default v1.4, we try v1.3). In general, the name
+ * should be i2400m-fw-X-VERSION.sbcf, where X is the bus name.
+ * The list is tried in order and the first one that loads is
+ * used. The fw loader will set i2400m->fw_name to point to the
+ * active firmware image.
*
* @bus_bm_mac_addr_impaired: [fill] Set to true if the device's MAC
* address provided in boot mode is kind of broken and needs to
@@ -257,6 +258,9 @@ struct i2400m_reset_ctx;
* force this to be the first field so that we can get from
* netdev_priv() the right pointer.
*
+ * @rx_reorder: 1 if RX reordering is enabled; this can only be
+ * set at probe time.
+ *
* @state: device's state (as reported by it)
*
* @state_wq: waitqueue that is woken up whenever the state changes
@@ -313,6 +317,12 @@ struct i2400m_reset_ctx;
*
* @rx_size_max: buggest RX message received.
*
+ * @rx_roq: RX ReOrder queues. (fw >= v1.4) When packets are received
+ * out of order, the device will ask the driver to hold certain
+ * packets until the ones that are received out of order can be
+ * delivered. Then the driver can release them to the host. See
+ * drivers/net/i2400m/rx.c for details.
+ *
* @init_mutex: Mutex used for serializing the device bringup
* sequence; this way if the device reboots in the middle, we
* don't try to do a bringup again while we are tearing down the
@@ -364,6 +374,11 @@ struct i2400m_reset_ctx;
* These have to be in a separate directory, a child of
* (wimax_dev->debugfs_dentry) so they can be removed when the
* module unloads, as we don't keep each dentry.
+ *
+ * @fw_name: name of the firmware image that is currently being used.
+ *
+ * @fw_version: version of the firmware interface, Major.minor,
+ * encoded in the high word and low word (major << 16 | minor).
*/
struct i2400m {
struct wimax_dev wimax_dev; /* FIRST! See doc */
@@ -372,6 +387,7 @@ struct i2400m {
unsigned boot_mode:1; /* is the device in boot mode? */
unsigned sboot:1; /* signed or unsigned fw boot */
unsigned ready:1; /* all probing steps done */
+ unsigned rx_reorder:1; /* RX reorder is enabled */
u8 trace_msg_from_user; /* echo rx msgs to 'trace' pipe */
/* typed u8 so debugfs/u8 can tweak */
enum i2400m_system_state state;
@@ -388,7 +404,7 @@ struct i2400m {
size_t, int flags);
ssize_t (*bus_bm_wait_for_ack)(struct i2400m *,
struct i2400m_bootrom_header *, size_t);
- const char *bus_fw_name;
+ const char **bus_fw_names;
unsigned bus_bm_mac_addr_impaired:1;
spinlock_t tx_lock; /* protect TX state */
@@ -400,10 +416,11 @@ struct i2400m {
unsigned tx_pl_num, tx_pl_max, tx_pl_min,
tx_num, tx_size_acc, tx_size_min, tx_size_max;
- /* RX stats */
+ /* RX stuff */
spinlock_t rx_lock; /* protect RX state */
unsigned rx_pl_num, rx_pl_max, rx_pl_min,
rx_num, rx_size_acc, rx_size_min, rx_size_max;
+ struct i2400m_roq *rx_roq; /* not under rx_lock! */
struct mutex msg_mutex; /* serialize command execution */
struct completion msg_completion;
@@ -421,6 +438,8 @@ struct i2400m {
struct sk_buff *wake_tx_skb;
struct dentry *debugfs_dentry;
+ const char *fw_name; /* name of the current firmware image */
+ unsigned long fw_version; /* version of the firmware interface */
};
@@ -435,6 +454,7 @@ void i2400m_init(struct i2400m *i2400m)
wimax_dev_init(&i2400m->wimax_dev);
i2400m->boot_mode = 1;
+ i2400m->rx_reorder = 1;
init_waitqueue_head(&i2400m->state_wq);
spin_lock_init(&i2400m->tx_lock);
@@ -578,12 +598,19 @@ unsigned i2400m_brh_get_signature(const struct i2400m_bootrom_header *hdr)
* Driver / device setup and internal functions
*/
extern void i2400m_netdev_setup(struct net_device *net_dev);
+extern int i2400m_sysfs_setup(struct device_driver *);
+extern void i2400m_sysfs_release(struct device_driver *);
extern int i2400m_tx_setup(struct i2400m *);
extern void i2400m_wake_tx_work(struct work_struct *);
extern void i2400m_tx_release(struct i2400m *);
+extern int i2400m_rx_setup(struct i2400m *);
+extern void i2400m_rx_release(struct i2400m *);
+
extern void i2400m_net_rx(struct i2400m *, struct sk_buff *, unsigned,
const void *, int);
+extern void i2400m_net_erx(struct i2400m *, struct sk_buff *,
+ enum i2400m_cs);
enum i2400m_pt;
extern int i2400m_tx(struct i2400m *, const void *, size_t, enum i2400m_pt);
@@ -664,17 +691,17 @@ extern struct i2400m_msg_hdr *i2400m_tx_msg_get(struct i2400m *, size_t *);
extern void i2400m_tx_msg_sent(struct i2400m *);
static const __le32 i2400m_NBOOT_BARKER[4] = {
- __constant_cpu_to_le32(I2400M_NBOOT_BARKER),
- __constant_cpu_to_le32(I2400M_NBOOT_BARKER),
- __constant_cpu_to_le32(I2400M_NBOOT_BARKER),
- __constant_cpu_to_le32(I2400M_NBOOT_BARKER)
+ cpu_to_le32(I2400M_NBOOT_BARKER),
+ cpu_to_le32(I2400M_NBOOT_BARKER),
+ cpu_to_le32(I2400M_NBOOT_BARKER),
+ cpu_to_le32(I2400M_NBOOT_BARKER)
};
static const __le32 i2400m_SBOOT_BARKER[4] = {
- __constant_cpu_to_le32(I2400M_SBOOT_BARKER),
- __constant_cpu_to_le32(I2400M_SBOOT_BARKER),
- __constant_cpu_to_le32(I2400M_SBOOT_BARKER),
- __constant_cpu_to_le32(I2400M_SBOOT_BARKER)
+ cpu_to_le32(I2400M_SBOOT_BARKER),
+ cpu_to_le32(I2400M_SBOOT_BARKER),
+ cpu_to_le32(I2400M_SBOOT_BARKER),
+ cpu_to_le32(I2400M_SBOOT_BARKER)
};
@@ -721,6 +748,7 @@ extern struct sk_buff *i2400m_get_device_info(struct i2400m *);
extern int i2400m_firmware_check(struct i2400m *);
extern int i2400m_set_init_config(struct i2400m *,
const struct i2400m_tlv_hdr **, size_t);
+extern int i2400m_set_idle_timeout(struct i2400m *, unsigned);
static inline
struct usb_endpoint_descriptor *usb_get_epd(struct usb_interface *iface, int ep)
@@ -733,6 +761,32 @@ extern int i2400m_op_rfkill_sw_toggle(struct wimax_dev *,
extern void i2400m_report_tlv_rf_switches_status(
struct i2400m *, const struct i2400m_tlv_rf_switches_status *);
+/*
+ * Helpers for firmware backwards compability
+ *
+ * As we aim to support at least the firmware version that was
+ * released with the previous kernel/driver release, some code will be
+ * conditionally executed depending on the firmware version. On each
+ * release, the code to support fw releases past the last two ones
+ * will be purged.
+ *
+ * By making it depend on this macros, it is easier to keep it a tab
+ * on what has to go and what not.
+ */
+static inline
+unsigned i2400m_le_v1_3(struct i2400m *i2400m)
+{
+ /* running fw is lower or v1.3 */
+ return i2400m->fw_version <= 0x00090001;
+}
+
+static inline
+unsigned i2400m_ge_v1_4(struct i2400m *i2400m)
+{
+ /* running fw is higher or v1.4 */
+ return i2400m->fw_version >= 0x00090002;
+}
+
/*
* Do a millisecond-sleep for allowing wireshark to dump all the data
@@ -750,6 +804,7 @@ void __i2400m_msleep(unsigned ms)
/* Module parameters */
extern int i2400m_idle_mode_disabled;
+extern int i2400m_rx_reorder_disabled;
#endif /* #ifndef __I2400M_H__ */
diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c
index 63fe708e8a31..6b1fe7a81f25 100644
--- a/drivers/net/wimax/i2400m/netdev.c
+++ b/drivers/net/wimax/i2400m/netdev.c
@@ -28,13 +28,12 @@
* space and from the other side. The world is (sadly) configured to
* take in only Ethernet devices...
*
- * Because of this, currently there is an copy-each-rxed-packet
- * overhead on the RX path. Each IP packet has to be reallocated to
- * add an ethernet header (as there is no space in what we get from
- * the device). This is a known drawback and coming versions of the
- * device's firmware are being changed to add header space that can be
- * used to insert the ethernet header without having to reallocate and
- * copy.
+ * Because of this, when using firmwares <= v1.3, there is an
+ * copy-each-rxed-packet overhead on the RX path. Each IP packet has
+ * to be reallocated to add an ethernet header (as there is no space
+ * in what we get from the device). This is a known drawback and
+ * firmwares >= 1.4 add header space that can be used to insert the
+ * ethernet header without having to reallocate and copy.
*
* TX error handling is tricky; because we have to FIFO/queue the
* buffers for transmission (as the hardware likes it aggregated), we
@@ -67,7 +66,9 @@
* i2400m_tx_timeout Called when the device times out
*
* i2400m_net_rx Called by the RX code when a data frame is
- * available.
+ * available (firmware <= 1.3)
+ * i2400m_net_erx Called by the RX code when a data frame is
+ * available (firmware >= 1.4).
* i2400m_netdev_setup Called to setup all the netdev stuff from
* alloc_netdev.
*/
@@ -396,30 +397,18 @@ void i2400m_tx_timeout(struct net_device *net_dev)
* Create a fake ethernet header
*
* For emulating an ethernet device, every received IP header has to
- * be prefixed with an ethernet header.
- *
- * What we receive has (potentially) many IP packets concatenated with
- * no ETH_HLEN bytes prefixed. Thus there is no space for an eth
- * header.
- *
- * We would have to reallocate or do ugly fragment tricks in order to
- * add it.
- *
- * But what we do is use the header space of the RX transaction
- * (*msg_hdr) as we don't need it anymore; then we'll point all the
- * data skbs there, as they share the same backing store.
- *
- * We only support IPv4 for v3 firmware.
+ * be prefixed with an ethernet header. Fake it with the given
+ * protocol.
*/
static
void i2400m_rx_fake_eth_header(struct net_device *net_dev,
- void *_eth_hdr)
+ void *_eth_hdr, __be16 protocol)
{
struct ethhdr *eth_hdr = _eth_hdr;
memcpy(eth_hdr->h_dest, net_dev->dev_addr, sizeof(eth_hdr->h_dest));
memset(eth_hdr->h_source, 0, sizeof(eth_hdr->h_dest));
- eth_hdr->h_proto = __constant_cpu_to_be16(ETH_P_IP);
+ eth_hdr->h_proto = protocol;
}
@@ -432,6 +421,13 @@ void i2400m_rx_fake_eth_header(struct net_device *net_dev,
* @buf: pointer to the buffer containing the data
* @len: buffer's length
*
+ * This is only used now for the v1.3 firmware. It will be deprecated
+ * in >= 2.6.31.
+ *
+ * Note that due to firmware limitations, we don't have space to add
+ * an ethernet header, so we need to copy each packet. Firmware
+ * versions >= v1.4 fix this [see i2400m_net_erx()].
+ *
* We just clone the skb and set it up so that it's skb->data pointer
* points to "buf" and it's length.
*
@@ -478,7 +474,8 @@ void i2400m_net_rx(struct i2400m *i2400m, struct sk_buff *skb_rx,
memcpy(skb_put(skb, buf_len), buf, buf_len);
}
i2400m_rx_fake_eth_header(i2400m->wimax_dev.net_dev,
- skb->data - ETH_HLEN);
+ skb->data - ETH_HLEN,
+ cpu_to_be16(ETH_P_IP));
skb_set_mac_header(skb, -ETH_HLEN);
skb->dev = i2400m->wimax_dev.net_dev;
skb->protocol = htons(ETH_P_IP);
@@ -494,6 +491,73 @@ error_skb_realloc:
}
+/*
+ * i2400m_net_erx - pass a network packet to the stack (extended version)
+ *
+ * @i2400m: device descriptor
+ * @skb: the skb where the packet is - the skb should be set to point
+ * at the IP packet; this function will add ethernet headers if
+ * needed.
+ * @cs: packet type
+ *
+ * This is only used now for firmware >= v1.4. Note it is quite
+ * similar to i2400m_net_rx() (used only for v1.3 firmware).
+ *
+ * This function is normally run from a thread context. However, we
+ * still use netif_rx() instead of netif_receive_skb() as was
+ * recommended in the mailing list. Reason is in some stress tests
+ * when sending/receiving a lot of data we seem to hit a softlock in
+ * the kernel's TCP implementation [aroudn tcp_delay_timer()]. Using
+ * netif_rx() took care of the issue.
+ *
+ * This is, of course, still open to do more research on why running
+ * with netif_receive_skb() hits this softlock. FIXME.
+ */
+void i2400m_net_erx(struct i2400m *i2400m, struct sk_buff *skb,
+ enum i2400m_cs cs)
+{
+ struct net_device *net_dev = i2400m->wimax_dev.net_dev;
+ struct device *dev = i2400m_dev(i2400m);
+ int protocol;
+
+ d_fnstart(2, dev, "(i2400m %p skb %p [%u] cs %d)\n",
+ i2400m, skb, skb->len, cs);
+ switch(cs) {
+ case I2400M_CS_IPV4_0:
+ case I2400M_CS_IPV4:
+ protocol = ETH_P_IP;
+ i2400m_rx_fake_eth_header(i2400m->wimax_dev.net_dev,
+ skb->data - ETH_HLEN,
+ cpu_to_be16(ETH_P_IP));
+ skb_set_mac_header(skb, -ETH_HLEN);
+ skb->dev = i2400m->wimax_dev.net_dev;
+ skb->protocol = htons(ETH_P_IP);
+ net_dev->stats.rx_packets++;
+ net_dev->stats.rx_bytes += skb->len;
+ break;
+ default:
+ dev_err(dev, "ERX: BUG? CS type %u unsupported\n", cs);
+ goto error;
+
+ }
+ d_printf(3, dev, "ERX: receiving %d bytes to the network stack\n",
+ skb->len);
+ d_dump(4, dev, skb->data, skb->len);
+ netif_rx_ni(skb); /* see notes in function header */
+error:
+ d_fnend(2, dev, "(i2400m %p skb %p [%u] cs %d) = void\n",
+ i2400m, skb, skb->len, cs);
+}
+
+static const struct net_device_ops i2400m_netdev_ops = {
+ .ndo_open = i2400m_open,
+ .ndo_stop = i2400m_stop,
+ .ndo_start_xmit = i2400m_hard_start_xmit,
+ .ndo_tx_timeout = i2400m_tx_timeout,
+ .ndo_change_mtu = i2400m_change_mtu,
+};
+
+
/**
* i2400m_netdev_setup - Setup setup @net_dev's i2400m private data
*
@@ -513,11 +577,7 @@ void i2400m_netdev_setup(struct net_device *net_dev)
& (~IFF_BROADCAST /* i2400m is P2P */
& ~IFF_MULTICAST);
net_dev->watchdog_timeo = I2400M_TX_TIMEOUT;
- net_dev->open = i2400m_open;
- net_dev->stop = i2400m_stop;
- net_dev->hard_start_xmit = i2400m_hard_start_xmit;
- net_dev->change_mtu = i2400m_change_mtu;
- net_dev->tx_timeout = i2400m_tx_timeout;
+ net_dev->netdev_ops = &i2400m_netdev_ops;
d_fnend(3, NULL, "(net_dev %p) = void\n", net_dev);
}
EXPORT_SYMBOL_GPL(i2400m_netdev_setup);
diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c
index 6922022710ac..02419bfd64b5 100644
--- a/drivers/net/wimax/i2400m/rx.c
+++ b/drivers/net/wimax/i2400m/rx.c
@@ -39,7 +39,7 @@
* - Use skb_clone(), break up processing in chunks
* - Split transport/device specific
* - Make buffer size dynamic to exert less memory pressure
- *
+ * - RX reorder support
*
* This handles the RX path.
*
@@ -69,6 +69,50 @@
* See tx.c for a deeper description on alignment requirements and
* other fun facts of it.
*
+ * DATA PACKETS
+ *
+ * In firmwares <= v1.3, data packets have no header for RX, but they
+ * do for TX (currently unused).
+ *
+ * In firmware >= 1.4, RX packets have an extended header (16
+ * bytes). This header conveys information for management of host
+ * reordering of packets (the device offloads storage of the packets
+ * for reordering to the host). Read below for more information.
+ *
+ * The header is used as dummy space to emulate an ethernet header and
+ * thus be able to act as an ethernet device without having to reallocate.
+ *
+ * DATA RX REORDERING
+ *
+ * Starting in firmware v1.4, the device can deliver packets for
+ * delivery with special reordering information; this allows it to
+ * more effectively do packet management when some frames were lost in
+ * the radio traffic.
+ *
+ * Thus, for RX packets that come out of order, the device gives the
+ * driver enough information to queue them properly and then at some
+ * point, the signal to deliver the whole (or part) of the queued
+ * packets to the networking stack. There are 16 such queues.
+ *
+ * This only happens when a packet comes in with the "need reorder"
+ * flag set in the RX header. When such bit is set, the following
+ * operations might be indicated:
+ *
+ * - reset queue: send all queued packets to the OS
+ *
+ * - queue: queue a packet
+ *
+ * - update ws: update the queue's window start and deliver queued
+ * packets that meet the criteria
+ *
+ * - queue & update ws: queue a packet, update the window start and
+ * deliver queued packets that meet the criteria
+ *
+ * (delivery criteria: the packet's [normalized] sequence number is
+ * lower than the new [normalized] window start).
+ *
+ * See the i2400m_roq_*() functions for details.
+ *
* ROADMAP
*
* i2400m_rx
@@ -76,6 +120,19 @@
* i2400m_rx_pl_descr_check
* i2400m_rx_payload
* i2400m_net_rx
+ * i2400m_rx_edata
+ * i2400m_net_erx
+ * i2400m_roq_reset
+ * i2400m_net_erx
+ * i2400m_roq_queue
+ * __i2400m_roq_queue
+ * i2400m_roq_update_ws
+ * __i2400m_roq_update_ws
+ * i2400m_net_erx
+ * i2400m_roq_queue_update_ws
+ * __i2400m_roq_queue
+ * __i2400m_roq_update_ws
+ * i2400m_net_erx
* i2400m_rx_ctl
* i2400m_msg_size_check
* i2400m_report_hook_work [in a workqueue]
@@ -177,8 +234,7 @@ void i2400m_rx_ctl_ack(struct i2400m *i2400m,
return;
error_waiter_cancelled:
- if (ack_skb)
- kfree_skb(ack_skb);
+ kfree_skb(ack_skb);
error_no_waiter:
spin_unlock_irqrestore(&i2400m->rx_lock, flags);
return;
@@ -265,8 +321,6 @@ error_check:
}
-
-
/*
* Receive and send up a trace
*
@@ -317,30 +371,628 @@ error_check:
/*
+ * Reorder queue data stored on skb->cb while the skb is queued in the
+ * reorder queues.
+ */
+struct i2400m_roq_data {
+ unsigned sn; /* Serial number for the skb */
+ enum i2400m_cs cs; /* packet type for the skb */
+};
+
+
+/*
+ * ReOrder Queue
+ *
+ * @ws: Window Start; sequence number where the current window start
+ * is for this queue
+ * @queue: the skb queue itself
+ * @log: circular ring buffer used to log information about the
+ * reorder process in this queue that can be displayed in case of
+ * error to help diagnose it.
+ *
+ * This is the head for a list of skbs. In the skb->cb member of the
+ * skb when queued here contains a 'struct i2400m_roq_data' were we
+ * store the sequence number (sn) and the cs (packet type) coming from
+ * the RX payload header from the device.
+ */
+struct i2400m_roq
+{
+ unsigned ws;
+ struct sk_buff_head queue;
+ struct i2400m_roq_log *log;
+};
+
+
+static
+void __i2400m_roq_init(struct i2400m_roq *roq)
+{
+ roq->ws = 0;
+ skb_queue_head_init(&roq->queue);
+}
+
+
+static
+unsigned __i2400m_roq_index(struct i2400m *i2400m, struct i2400m_roq *roq)
+{
+ return ((unsigned long) roq - (unsigned long) i2400m->rx_roq)
+ / sizeof(*roq);
+}
+
+
+/*
+ * Normalize a sequence number based on the queue's window start
+ *
+ * nsn = (sn - ws) % 2048
+ *
+ * Note that if @sn < @roq->ws, we still need a positive number; %'s
+ * sign is implementation specific, so we normalize it by adding 2048
+ * to bring it to be positive.
+ */
+static
+unsigned __i2400m_roq_nsn(struct i2400m_roq *roq, unsigned sn)
+{
+ int r;
+ r = ((int) sn - (int) roq->ws) % 2048;
+ if (r < 0)
+ r += 2048;
+ return r;
+}
+
+
+/*
+ * Circular buffer to keep the last N reorder operations
+ *
+ * In case something fails, dumb then to try to come up with what
+ * happened.
+ */
+enum {
+ I2400M_ROQ_LOG_LENGTH = 32,
+};
+
+struct i2400m_roq_log {
+ struct i2400m_roq_log_entry {
+ enum i2400m_ro_type type;
+ unsigned ws, count, sn, nsn, new_ws;
+ } entry[I2400M_ROQ_LOG_LENGTH];
+ unsigned in, out;
+};
+
+
+/* Print a log entry */
+static
+void i2400m_roq_log_entry_print(struct i2400m *i2400m, unsigned index,
+ unsigned e_index,
+ struct i2400m_roq_log_entry *e)
+{
+ struct device *dev = i2400m_dev(i2400m);
+
+ switch(e->type) {
+ case I2400M_RO_TYPE_RESET:
+ dev_err(dev, "q#%d reset ws %u cnt %u sn %u/%u"
+ " - new nws %u\n",
+ index, e->ws, e->count, e->sn, e->nsn, e->new_ws);
+ break;
+ case I2400M_RO_TYPE_PACKET:
+ dev_err(dev, "q#%d queue ws %u cnt %u sn %u/%u\n",
+ index, e->ws, e->count, e->sn, e->nsn);
+ break;
+ case I2400M_RO_TYPE_WS:
+ dev_err(dev, "q#%d update_ws ws %u cnt %u sn %u/%u"
+ " - new nws %u\n",
+ index, e->ws, e->count, e->sn, e->nsn, e->new_ws);
+ break;
+ case I2400M_RO_TYPE_PACKET_WS:
+ dev_err(dev, "q#%d queue_update_ws ws %u cnt %u sn %u/%u"
+ " - new nws %u\n",
+ index, e->ws, e->count, e->sn, e->nsn, e->new_ws);
+ break;
+ default:
+ dev_err(dev, "q#%d BUG? entry %u - unknown type %u\n",
+ index, e_index, e->type);
+ break;
+ }
+}
+
+
+static
+void i2400m_roq_log_add(struct i2400m *i2400m,
+ struct i2400m_roq *roq, enum i2400m_ro_type type,
+ unsigned ws, unsigned count, unsigned sn,
+ unsigned nsn, unsigned new_ws)
+{
+ struct i2400m_roq_log_entry *e;
+ unsigned cnt_idx;
+ int index = __i2400m_roq_index(i2400m, roq);
+
+ /* if we run out of space, we eat from the end */
+ if (roq->log->in - roq->log->out == I2400M_ROQ_LOG_LENGTH)
+ roq->log->out++;
+ cnt_idx = roq->log->in++ % I2400M_ROQ_LOG_LENGTH;
+ e = &roq->log->entry[cnt_idx];
+
+ e->type = type;
+ e->ws = ws;
+ e->count = count;
+ e->sn = sn;
+ e->nsn = nsn;
+ e->new_ws = new_ws;
+
+ if (d_test(1))
+ i2400m_roq_log_entry_print(i2400m, index, cnt_idx, e);
+}
+
+
+/* Dump all the entries in the FIFO and reinitialize it */
+static
+void i2400m_roq_log_dump(struct i2400m *i2400m, struct i2400m_roq *roq)
+{
+ unsigned cnt, cnt_idx;
+ struct i2400m_roq_log_entry *e;
+ int index = __i2400m_roq_index(i2400m, roq);
+
+ BUG_ON(roq->log->out > roq->log->in);
+ for (cnt = roq->log->out; cnt < roq->log->in; cnt++) {
+ cnt_idx = cnt % I2400M_ROQ_LOG_LENGTH;
+ e = &roq->log->entry[cnt_idx];
+ i2400m_roq_log_entry_print(i2400m, index, cnt_idx, e);
+ memset(e, 0, sizeof(*e));
+ }
+ roq->log->in = roq->log->out = 0;
+}
+
+
+/*
+ * Backbone for the queuing of an skb (by normalized sequence number)
+ *
+ * @i2400m: device descriptor
+ * @roq: reorder queue where to add
+ * @skb: the skb to add
+ * @sn: the sequence number of the skb
+ * @nsn: the normalized sequence number of the skb (pre-computed by the
+ * caller from the @sn and @roq->ws).
+ *
+ * We try first a couple of quick cases:
+ *
+ * - the queue is empty
+ * - the skb would be appended to the queue
+ *
+ * These will be the most common operations.
+ *
+ * If these fail, then we have to do a sorted insertion in the queue,
+ * which is the slowest path.
+ *
+ * We don't have to acquire a reference count as we are going to own it.
+ */
+static
+void __i2400m_roq_queue(struct i2400m *i2400m, struct i2400m_roq *roq,
+ struct sk_buff *skb, unsigned sn, unsigned nsn)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ struct sk_buff *skb_itr;
+ struct i2400m_roq_data *roq_data_itr, *roq_data;
+ unsigned nsn_itr;
+
+ d_fnstart(4, dev, "(i2400m %p roq %p skb %p sn %u nsn %u)\n",
+ i2400m, roq, skb, sn, nsn);
+
+ roq_data = (struct i2400m_roq_data *) &skb->cb;
+ BUILD_BUG_ON(sizeof(*roq_data) > sizeof(skb->cb));
+ roq_data->sn = sn;
+ d_printf(3, dev, "ERX: roq %p [ws %u] nsn %d sn %u\n",
+ roq, roq->ws, nsn, roq_data->sn);
+
+ /* Queues will be empty on not-so-bad environments, so try
+ * that first */
+ if (skb_queue_empty(&roq->queue)) {
+ d_printf(2, dev, "ERX: roq %p - first one\n", roq);
+ __skb_queue_head(&roq->queue, skb);
+ goto out;
+ }
+ /* Now try append, as most of the operations will be that */
+ skb_itr = skb_peek_tail(&roq->queue);
+ roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+ nsn_itr = __i2400m_roq_nsn(roq, roq_data_itr->sn);
+ /* NSN bounds assumed correct (checked when it was queued) */
+ if (nsn >= nsn_itr) {
+ d_printf(2, dev, "ERX: roq %p - appended after %p (nsn %d sn %u)\n",
+ roq, skb_itr, nsn_itr, roq_data_itr->sn);
+ __skb_queue_tail(&roq->queue, skb);
+ goto out;
+ }
+ /* None of the fast paths option worked. Iterate to find the
+ * right spot where to insert the packet; we know the queue is
+ * not empty, so we are not the first ones; we also know we
+ * are not going to be the last ones. The list is sorted, so
+ * we have to insert before the the first guy with an nsn_itr
+ * greater that our nsn. */
+ skb_queue_walk(&roq->queue, skb_itr) {
+ roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+ nsn_itr = __i2400m_roq_nsn(roq, roq_data_itr->sn);
+ /* NSN bounds assumed correct (checked when it was queued) */
+ if (nsn_itr > nsn) {
+ d_printf(2, dev, "ERX: roq %p - queued before %p "
+ "(nsn %d sn %u)\n", roq, skb_itr, nsn_itr,
+ roq_data_itr->sn);
+ __skb_queue_before(&roq->queue, skb_itr, skb);
+ goto out;
+ }
+ }
+ /* If we get here, that is VERY bad -- print info to help
+ * diagnose and crash it */
+ dev_err(dev, "SW BUG? failed to insert packet\n");
+ dev_err(dev, "ERX: roq %p [ws %u] skb %p nsn %d sn %u\n",
+ roq, roq->ws, skb, nsn, roq_data->sn);
+ skb_queue_walk(&roq->queue, skb_itr) {
+ roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+ nsn_itr = __i2400m_roq_nsn(roq, roq_data_itr->sn);
+ /* NSN bounds assumed correct (checked when it was queued) */
+ dev_err(dev, "ERX: roq %p skb_itr %p nsn %d sn %u\n",
+ roq, skb_itr, nsn_itr, roq_data_itr->sn);
+ }
+ BUG();
+out:
+ d_fnend(4, dev, "(i2400m %p roq %p skb %p sn %u nsn %d) = void\n",
+ i2400m, roq, skb, sn, nsn);
+ return;
+}
+
+
+/*
+ * Backbone for the update window start operation
+ *
+ * @i2400m: device descriptor
+ * @roq: Reorder queue
+ * @sn: New sequence number
+ *
+ * Updates the window start of a queue; when doing so, it must deliver
+ * to the networking stack all the queued skb's whose normalized
+ * sequence number is lower than the new normalized window start.
+ */
+static
+unsigned __i2400m_roq_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq,
+ unsigned sn)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ struct sk_buff *skb_itr, *tmp_itr;
+ struct i2400m_roq_data *roq_data_itr;
+ unsigned new_nws, nsn_itr;
+
+ new_nws = __i2400m_roq_nsn(roq, sn);
+ if (unlikely(new_nws >= 1024) && d_test(1)) {
+ dev_err(dev, "SW BUG? __update_ws new_nws %u (sn %u ws %u)\n",
+ new_nws, sn, roq->ws);
+ WARN_ON(1);
+ i2400m_roq_log_dump(i2400m, roq);
+ }
+ skb_queue_walk_safe(&roq->queue, skb_itr, tmp_itr) {
+ roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+ nsn_itr = __i2400m_roq_nsn(roq, roq_data_itr->sn);
+ /* NSN bounds assumed correct (checked when it was queued) */
+ if (nsn_itr < new_nws) {
+ d_printf(2, dev, "ERX: roq %p - release skb %p "
+ "(nsn %u/%u new nws %u)\n",
+ roq, skb_itr, nsn_itr, roq_data_itr->sn,
+ new_nws);
+ __skb_unlink(skb_itr, &roq->queue);
+ i2400m_net_erx(i2400m, skb_itr, roq_data_itr->cs);
+ }
+ else
+ break; /* rest of packets all nsn_itr > nws */
+ }
+ roq->ws = sn;
+ return new_nws;
+}
+
+
+/*
+ * Reset a queue
+ *
+ * @i2400m: device descriptor
+ * @cin: Queue Index
+ *
+ * Deliver all the packets and reset the window-start to zero. Name is
+ * kind of misleading.
+ */
+static
+void i2400m_roq_reset(struct i2400m *i2400m, struct i2400m_roq *roq)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ struct sk_buff *skb_itr, *tmp_itr;
+ struct i2400m_roq_data *roq_data_itr;
+
+ d_fnstart(2, dev, "(i2400m %p roq %p)\n", i2400m, roq);
+ i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_RESET,
+ roq->ws, skb_queue_len(&roq->queue),
+ ~0, ~0, 0);
+ skb_queue_walk_safe(&roq->queue, skb_itr, tmp_itr) {
+ roq_data_itr = (struct i2400m_roq_data *) &skb_itr->cb;
+ d_printf(2, dev, "ERX: roq %p - release skb %p (sn %u)\n",
+ roq, skb_itr, roq_data_itr->sn);
+ __skb_unlink(skb_itr, &roq->queue);
+ i2400m_net_erx(i2400m, skb_itr, roq_data_itr->cs);
+ }
+ roq->ws = 0;
+ d_fnend(2, dev, "(i2400m %p roq %p) = void\n", i2400m, roq);
+ return;
+}
+
+
+/*
+ * Queue a packet
+ *
+ * @i2400m: device descriptor
+ * @cin: Queue Index
+ * @skb: containing the packet data
+ * @fbn: First block number of the packet in @skb
+ * @lbn: Last block number of the packet in @skb
+ *
+ * The hardware is asking the driver to queue a packet for later
+ * delivery to the networking stack.
+ */
+static
+void i2400m_roq_queue(struct i2400m *i2400m, struct i2400m_roq *roq,
+ struct sk_buff * skb, unsigned lbn)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ unsigned nsn, len;
+
+ d_fnstart(2, dev, "(i2400m %p roq %p skb %p lbn %u) = void\n",
+ i2400m, roq, skb, lbn);
+ len = skb_queue_len(&roq->queue);
+ nsn = __i2400m_roq_nsn(roq, lbn);
+ if (unlikely(nsn >= 1024)) {
+ dev_err(dev, "SW BUG? queue nsn %d (lbn %u ws %u)\n",
+ nsn, lbn, roq->ws);
+ i2400m_roq_log_dump(i2400m, roq);
+ i2400m->bus_reset(i2400m, I2400M_RT_WARM);
+ } else {
+ __i2400m_roq_queue(i2400m, roq, skb, lbn, nsn);
+ i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_PACKET,
+ roq->ws, len, lbn, nsn, ~0);
+ }
+ d_fnend(2, dev, "(i2400m %p roq %p skb %p lbn %u) = void\n",
+ i2400m, roq, skb, lbn);
+ return;
+}
+
+
+/*
+ * Update the window start in a reorder queue and deliver all skbs
+ * with a lower window start
+ *
+ * @i2400m: device descriptor
+ * @roq: Reorder queue
+ * @sn: New sequence number
+ */
+static
+void i2400m_roq_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq,
+ unsigned sn)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ unsigned old_ws, nsn, len;
+
+ d_fnstart(2, dev, "(i2400m %p roq %p sn %u)\n", i2400m, roq, sn);
+ old_ws = roq->ws;
+ len = skb_queue_len(&roq->queue);
+ nsn = __i2400m_roq_update_ws(i2400m, roq, sn);
+ i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_WS,
+ old_ws, len, sn, nsn, roq->ws);
+ d_fnstart(2, dev, "(i2400m %p roq %p sn %u) = void\n", i2400m, roq, sn);
+ return;
+}
+
+
+/*
+ * Queue a packet and update the window start
+ *
+ * @i2400m: device descriptor
+ * @cin: Queue Index
+ * @skb: containing the packet data
+ * @fbn: First block number of the packet in @skb
+ * @sn: Last block number of the packet in @skb
+ *
+ * Note that unlike i2400m_roq_update_ws(), which sets the new window
+ * start to @sn, in here we'll set it to @sn + 1.
+ */
+static
+void i2400m_roq_queue_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq,
+ struct sk_buff * skb, unsigned sn)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ unsigned nsn, old_ws, len;
+
+ d_fnstart(2, dev, "(i2400m %p roq %p skb %p sn %u)\n",
+ i2400m, roq, skb, sn);
+ len = skb_queue_len(&roq->queue);
+ nsn = __i2400m_roq_nsn(roq, sn);
+ old_ws = roq->ws;
+ if (unlikely(nsn >= 1024)) {
+ dev_err(dev, "SW BUG? queue_update_ws nsn %u (sn %u ws %u)\n",
+ nsn, sn, roq->ws);
+ i2400m_roq_log_dump(i2400m, roq);
+ i2400m->bus_reset(i2400m, I2400M_RT_WARM);
+ } else {
+ /* if the queue is empty, don't bother as we'd queue
+ * it and inmediately unqueue it -- just deliver it */
+ if (len == 0) {
+ struct i2400m_roq_data *roq_data;
+ roq_data = (struct i2400m_roq_data *) &skb->cb;
+ i2400m_net_erx(i2400m, skb, roq_data->cs);
+ }
+ else {
+ __i2400m_roq_queue(i2400m, roq, skb, sn, nsn);
+ __i2400m_roq_update_ws(i2400m, roq, sn + 1);
+ }
+ i2400m_roq_log_add(i2400m, roq, I2400M_RO_TYPE_PACKET_WS,
+ old_ws, len, sn, nsn, roq->ws);
+ }
+ d_fnend(2, dev, "(i2400m %p roq %p skb %p sn %u) = void\n",
+ i2400m, roq, skb, sn);
+ return;
+}
+
+
+/*
+ * Receive and send up an extended data packet
+ *
+ * @i2400m: device descriptor
+ * @skb_rx: skb that contains the extended data packet
+ * @single_last: 1 if the payload is the only one or the last one of
+ * the skb.
+ * @payload: pointer to the packet's data inside the skb
+ * @size: size of the payload
+ *
+ * Starting in v1.4 of the i2400m's firmware, the device can send data
+ * packets to the host in an extended format that; this incudes a 16
+ * byte header (struct i2400m_pl_edata_hdr). Using this header's space
+ * we can fake ethernet headers for ethernet device emulation without
+ * having to copy packets around.
+ *
+ * This function handles said path.
+ *
+ *
+ * Receive and send up an extended data packet that requires no reordering
+ *
+ * @i2400m: device descriptor
+ * @skb_rx: skb that contains the extended data packet
+ * @single_last: 1 if the payload is the only one or the last one of
+ * the skb.
+ * @payload: pointer to the packet's data (past the actual extended
+ * data payload header).
+ * @size: size of the payload
+ *
+ * Pass over to the networking stack a data packet that might have
+ * reordering requirements.
+ *
+ * This needs to the decide if the skb in which the packet is
+ * contained can be reused or if it needs to be cloned. Then it has to
+ * be trimmed in the edges so that the beginning is the space for eth
+ * header and then pass it to i2400m_net_erx() for the stack
+ *
+ * Assumes the caller has verified the sanity of the payload (size,
+ * etc) already.
+ */
+static
+void i2400m_rx_edata(struct i2400m *i2400m, struct sk_buff *skb_rx,
+ unsigned single_last, const void *payload, size_t size)
+{
+ struct device *dev = i2400m_dev(i2400m);
+ const struct i2400m_pl_edata_hdr *hdr = payload;
+ struct net_device *net_dev = i2400m->wimax_dev.net_dev;
+ struct sk_buff *skb;
+ enum i2400m_cs cs;
+ u32 reorder;
+ unsigned ro_needed, ro_type, ro_cin, ro_sn;
+ struct i2400m_roq *roq;
+ struct i2400m_roq_data *roq_data;
+
+ BUILD_BUG_ON(ETH_HLEN > sizeof(*hdr));
+
+ d_fnstart(2, dev, "(i2400m %p skb_rx %p single %u payload %p "
+ "size %zu)\n", i2400m, skb_rx, single_last, payload, size);
+ if (size < sizeof(*hdr)) {
+ dev_err(dev, "ERX: HW BUG? message with short header (%zu "
+ "vs %zu bytes expected)\n", size, sizeof(*hdr));
+ goto error;
+ }
+
+ if (single_last) {
+ skb = skb_get(skb_rx);
+ d_printf(3, dev, "ERX: skb %p reusing\n", skb);
+ } else {
+ skb = skb_clone(skb_rx, GFP_KERNEL);
+ if (skb == NULL) {
+ dev_err(dev, "ERX: no memory to clone skb\n");
+ net_dev->stats.rx_dropped++;
+ goto error_skb_clone;
+ }
+ d_printf(3, dev, "ERX: skb %p cloned from %p\n", skb, skb_rx);
+ }
+ /* now we have to pull and trim so that the skb points to the
+ * beginning of the IP packet; the netdev part will add the
+ * ethernet header as needed - we know there is enough space
+ * because we checked in i2400m_rx_edata(). */
+ skb_pull(skb, payload + sizeof(*hdr) - (void *) skb->data);
+ skb_trim(skb, (void *) skb_end_pointer(skb) - payload - sizeof(*hdr));
+
+ reorder = le32_to_cpu(hdr->reorder);
+ ro_needed = reorder & I2400M_RO_NEEDED;
+ cs = hdr->cs;
+ if (ro_needed) {
+ ro_type = (reorder >> I2400M_RO_TYPE_SHIFT) & I2400M_RO_TYPE;
+ ro_cin = (reorder >> I2400M_RO_CIN_SHIFT) & I2400M_RO_CIN;
+ ro_sn = (reorder >> I2400M_RO_SN_SHIFT) & I2400M_RO_SN;
+
+ roq = &i2400m->rx_roq[ro_cin];
+ roq_data = (struct i2400m_roq_data *) &skb->cb;
+ roq_data->sn = ro_sn;
+ roq_data->cs = cs;
+ d_printf(2, dev, "ERX: reorder needed: "
+ "type %u cin %u [ws %u] sn %u/%u len %zuB\n",
+ ro_type, ro_cin, roq->ws, ro_sn,
+ __i2400m_roq_nsn(roq, ro_sn), size);
+ d_dump(2, dev, payload, size);
+ switch(ro_type) {
+ case I2400M_RO_TYPE_RESET:
+ i2400m_roq_reset(i2400m, roq);
+ kfree_skb(skb); /* no data here */
+ break;
+ case I2400M_RO_TYPE_PACKET:
+ i2400m_roq_queue(i2400m, roq, skb, ro_sn);
+ break;
+ case I2400M_RO_TYPE_WS:
+ i2400m_roq_update_ws(i2400m, roq, ro_sn);
+ kfree_skb(skb); /* no data here */
+ break;
+ case I2400M_RO_TYPE_PACKET_WS:
+ i2400m_roq_queue_update_ws(i2400m, roq, skb, ro_sn);
+ break;
+ default:
+ dev_err(dev, "HW BUG? unknown reorder type %u\n", ro_type);
+ }
+ }
+ else
+ i2400m_net_erx(i2400m, skb, cs);
+error_skb_clone:
+error:
+ d_fnend(2, dev, "(i2400m %p skb_rx %p single %u payload %p "
+ "size %zu) = void\n", i2400m, skb_rx, single_last, payload, size);
+ return;
+}
+
+
+/*
* Act on a received payload
*
* @i2400m: device instance
* @skb_rx: skb where the transaction was received
- * @single: 1 if there is only one payload, 0 otherwise
+ * @single_last: 1 this is the only payload or the last one (so the
+ * skb can be reused instead of cloned).
* @pld: payload descriptor
* @payload: payload data
*
* Upon reception of a payload, look at its guts in the payload
- * descriptor and decide what to do with it.
+ * descriptor and decide what to do with it. If it is a single payload
+ * skb or if the last skb is a data packet, the skb will be referenced
+ * and modified (so it doesn't have to be cloned).
*/
static
void i2400m_rx_payload(struct i2400m *i2400m, struct sk_buff *skb_rx,
- unsigned single, const struct i2400m_pld *pld,
+ unsigned single_last, const struct i2400m_pld *pld,
const void *payload)
{
struct device *dev = i2400m_dev(i2400m);
size_t pl_size = i2400m_pld_size(pld);
enum i2400m_pt pl_type = i2400m_pld_type(pld);
+ d_printf(7, dev, "RX: received payload type %u, %zu bytes\n",
+ pl_type, pl_size);
+ d_dump(8, dev, payload, pl_size);
+
switch (pl_type) {
case I2400M_PT_DATA:
d_printf(3, dev, "RX: data payload %zu bytes\n", pl_size);
- i2400m_net_rx(i2400m, skb_rx, single, payload, pl_size);
+ i2400m_net_rx(i2400m, skb_rx, single_last, payload, pl_size);
break;
case I2400M_PT_CTRL:
i2400m_rx_ctl(i2400m, skb_rx, payload, pl_size);
@@ -348,6 +1000,10 @@ void i2400m_rx_payload(struct i2400m *i2400m, struct sk_buff *skb_rx,
case I2400M_PT_TRACE:
i2400m_rx_trace(i2400m, payload, pl_size);
break;
+ case I2400M_PT_EDATA:
+ d_printf(3, dev, "ERX: data payload %zu bytes\n", pl_size);
+ i2400m_rx_edata(i2400m, skb_rx, single_last, payload, pl_size);
+ break;
default: /* Anything else shouldn't come to the host */
if (printk_ratelimit())
dev_err(dev, "RX: HW BUG? unexpected payload type %u\n",
@@ -475,7 +1131,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
const struct i2400m_msg_hdr *msg_hdr;
size_t pl_itr, pl_size, skb_len;
unsigned long flags;
- unsigned num_pls;
+ unsigned num_pls, single_last;
skb_len = skb->len;
d_fnstart(4, dev, "(i2400m %p skb %p [size %zu])\n",
@@ -504,7 +1160,8 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
pl_itr, skb->len);
if (result < 0)
goto error_pl_descr_check;
- i2400m_rx_payload(i2400m, skb, num_pls == 1, &msg_hdr->pld[i],
+ single_last = num_pls == 1 || i == num_pls - 1;
+ i2400m_rx_payload(i2400m, skb, single_last, &msg_hdr->pld[i],
skb->data + pl_itr);
pl_itr += ALIGN(pl_size, I2400M_PL_PAD);
cond_resched(); /* Don't monopolize */
@@ -532,3 +1189,73 @@ error_msg_hdr_check:
return result;
}
EXPORT_SYMBOL_GPL(i2400m_rx);
+
+
+/*
+ * Initialize the RX queue and infrastructure
+ *
+ * This sets up all the RX reordering infrastructures, which will not
+ * be used if reordering is not enabled or if the firmware does not
+ * support it. The device is told to do reordering in
+ * i2400m_dev_initialize(), where it also looks at the value of the
+ * i2400m->rx_reorder switch before taking a decission.
+ *
+ * Note we allocate the roq queues in one chunk and the actual logging
+ * support for it (logging) in another one and then we setup the
+ * pointers from the first to the last.
+ */
+int i2400m_rx_setup(struct i2400m *i2400m)
+{
+ int result = 0;
+ struct device *dev = i2400m_dev(i2400m);
+
+ i2400m->rx_reorder = i2400m_rx_reorder_disabled? 0 : 1;
+ if (i2400m->rx_reorder) {
+ unsigned itr;
+ size_t size;
+ struct i2400m_roq_log *rd;
+
+ result = -ENOMEM;
+
+ size = sizeof(i2400m->rx_roq[0]) * (I2400M_RO_CIN + 1);
+ i2400m->rx_roq = kzalloc(size, GFP_KERNEL);
+ if (i2400m->rx_roq == NULL) {
+ dev_err(dev, "RX: cannot allocate %zu bytes for "
+ "reorder queues\n", size);
+ goto error_roq_alloc;
+ }
+
+ size = sizeof(*i2400m->rx_roq[0].log) * (I2400M_RO_CIN + 1);
+ rd = kzalloc(size, GFP_KERNEL);
+ if (rd == NULL) {
+ dev_err(dev, "RX: cannot allocate %zu bytes for "
+ "reorder queues log areas\n", size);
+ result = -ENOMEM;
+ goto error_roq_log_alloc;
+ }
+
+ for(itr = 0; itr < I2400M_RO_CIN + 1; itr++) {
+ __i2400m_roq_init(&i2400m->rx_roq[itr]);
+ i2400m->rx_roq[itr].log = &rd[itr];
+ }
+ }
+ return 0;
+
+error_roq_log_alloc:
+ kfree(i2400m->rx_roq);
+error_roq_alloc:
+ return result;
+}
+
+
+/* Tear down the RX queue and infrastructure */
+void i2400m_rx_release(struct i2400m *i2400m)
+{
+ if (i2400m->rx_reorder) {
+ unsigned itr;
+ for(itr = 0; itr < I2400M_RO_CIN + 1; itr++)
+ __skb_queue_purge(&i2400m->rx_roq[itr].queue);
+ kfree(i2400m->rx_roq[0].log);
+ kfree(i2400m->rx_roq);
+ }
+}
diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c
index 1bfa283bbd8a..5ac5e76701cd 100644
--- a/drivers/net/wimax/i2400m/sdio.c
+++ b/drivers/net/wimax/i2400m/sdio.c
@@ -70,8 +70,13 @@
static int ioe_timeout = 2;
module_param(ioe_timeout, int, 0);
-/* Our firmware file name */
-#define I2400MS_FW_FILE_NAME "i2400m-fw-sdio-" I2400M_FW_VERSION ".sbcf"
+/* Our firmware file name list */
+static const char *i2400ms_bus_fw_names[] = {
+#define I2400MS_FW_FILE_NAME "i2400m-fw-sdio-1.3.sbcf"
+ I2400MS_FW_FILE_NAME,
+ NULL
+};
+
/*
* Enable the SDIO function
@@ -255,16 +260,16 @@ int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
container_of(i2400m, struct i2400ms, i2400m);
struct device *dev = i2400m_dev(i2400m);
static const __le32 i2400m_WARM_BOOT_BARKER[4] = {
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
};
static const __le32 i2400m_COLD_BOOT_BARKER[4] = {
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
};
if (rt == I2400M_RT_WARM)
@@ -401,7 +406,7 @@ int i2400ms_probe(struct sdio_func *func,
i2400m->bus_reset = i2400ms_bus_reset;
i2400m->bus_bm_cmd_send = i2400ms_bus_bm_cmd_send;
i2400m->bus_bm_wait_for_ack = i2400ms_bus_bm_wait_for_ack;
- i2400m->bus_fw_name = I2400MS_FW_FILE_NAME;
+ i2400m->bus_fw_names = i2400ms_bus_fw_names;
i2400m->bus_bm_mac_addr_impaired = 1;
result = i2400ms_enable_function(i2400ms->func);
diff --git a/drivers/net/wimax/i2400m/sysfs.c b/drivers/net/wimax/i2400m/sysfs.c
new file mode 100644
index 000000000000..1237109f251a
--- /dev/null
+++ b/drivers/net/wimax/i2400m/sysfs.c
@@ -0,0 +1,80 @@
+/*
+ * Intel Wireless WiMAX Connection 2400m
+ * Sysfs interfaces to show driver and device information
+ *
+ *
+ * Copyright (C) 2007 Intel Corporation <linux-wimax@intel.com>
+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include "i2400m.h"
+
+
+#define D_SUBMODULE sysfs
+#include "debug-levels.h"
+
+
+/*
+ * Set the idle timeout (msecs)
+ *
+ * FIXME: eventually this should be a common WiMAX stack method, but
+ * would like to wait to see how other devices manage it.
+ */
+static
+ssize_t i2400m_idle_timeout_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ ssize_t result;
+ struct i2400m *i2400m = net_dev_to_i2400m(to_net_dev(dev));
+ unsigned val;
+
+ result = -EINVAL;
+ if (sscanf(buf, "%u\n", &val) != 1)
+ goto error_no_unsigned;
+ if (val != 0 && (val < 100 || val > 300000 || val % 100 != 0)) {
+ dev_err(dev, "idle_timeout: %u: invalid msecs specification; "
+ "valid values are 0, 100-300000 in 100 increments\n",
+ val);
+ goto error_bad_value;
+ }
+ result = i2400m_set_idle_timeout(i2400m, val);
+ if (result >= 0)
+ result = size;
+error_no_unsigned:
+error_bad_value:
+ return result;
+}
+
+static
+DEVICE_ATTR(i2400m_idle_timeout, S_IWUSR,
+ NULL, i2400m_idle_timeout_store);
+
+static
+struct attribute *i2400m_dev_attrs[] = {
+ &dev_attr_i2400m_idle_timeout.attr,
+ NULL,
+};
+
+struct attribute_group i2400m_dev_attr_group = {
+ .name = NULL, /* we want them in the same directory */
+ .attrs = i2400m_dev_attrs,
+};
diff --git a/drivers/net/wimax/i2400m/usb-notif.c b/drivers/net/wimax/i2400m/usb-notif.c
index 9702c22b2497..6add27c3f35c 100644
--- a/drivers/net/wimax/i2400m/usb-notif.c
+++ b/drivers/net/wimax/i2400m/usb-notif.c
@@ -102,7 +102,7 @@ int i2400mu_notification_grok(struct i2400mu *i2400mu, const void *buf,
dev_err(dev, "HW BUG? Unknown/unexpected data in notification "
"message (%zu bytes)\n", buf_len);
snprintf(prefix, sizeof(prefix), "%s %s: ",
- dev_driver_string(dev) , dev->bus_id);
+ dev_driver_string(dev), dev_name(dev));
if (buf_len > 64) {
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET,
8, 4, buf, 64, 0);
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index c6d93465c7e2..ca4151a9e222 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -73,7 +73,14 @@
/* Our firmware file name */
-#define I2400MU_FW_FILE_NAME "i2400m-fw-usb-" I2400M_FW_VERSION ".sbcf"
+static const char *i2400mu_bus_fw_names[] = {
+#define I2400MU_FW_FILE_NAME_v1_4 "i2400m-fw-usb-1.4.sbcf"
+ I2400MU_FW_FILE_NAME_v1_4,
+#define I2400MU_FW_FILE_NAME_v1_3 "i2400m-fw-usb-1.3.sbcf"
+ I2400MU_FW_FILE_NAME_v1_3,
+ NULL,
+};
+
static
int i2400mu_bus_dev_start(struct i2400m *i2400m)
@@ -211,16 +218,16 @@ int i2400mu_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
container_of(i2400m, struct i2400mu, i2400m);
struct device *dev = i2400m_dev(i2400m);
static const __le32 i2400m_WARM_BOOT_BARKER[4] = {
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
+ cpu_to_le32(I2400M_WARM_RESET_BARKER),
};
static const __le32 i2400m_COLD_BOOT_BARKER[4] = {
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
- __constant_cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
+ cpu_to_le32(I2400M_COLD_RESET_BARKER),
};
d_fnstart(3, dev, "(i2400m %p rt %u)\n", i2400m, rt);
@@ -394,7 +401,7 @@ int i2400mu_probe(struct usb_interface *iface,
i2400m->bus_reset = i2400mu_bus_reset;
i2400m->bus_bm_cmd_send = i2400mu_bus_bm_cmd_send;
i2400m->bus_bm_wait_for_ack = i2400mu_bus_bm_wait_for_ack;
- i2400m->bus_fw_name = I2400MU_FW_FILE_NAME;
+ i2400m->bus_fw_names = i2400mu_bus_fw_names;
i2400m->bus_bm_mac_addr_impaired = 0;
#ifdef CONFIG_PM
@@ -594,4 +601,5 @@ module_exit(i2400mu_driver_exit);
MODULE_AUTHOR("Intel Corporation <linux-wimax@intel.com>");
MODULE_DESCRIPTION("Intel 2400M WiMAX networking for USB");
MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(I2400MU_FW_FILE_NAME);
+MODULE_FIRMWARE(I2400MU_FW_FILE_NAME_v1_4);
+MODULE_FIRMWARE(I2400MU_FW_FILE_NAME_v1_3);
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index e4f9f747de88..8a0823588c51 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -151,6 +151,12 @@ config LIBERTAS_SDIO
---help---
A driver for Marvell Libertas 8385 and 8686 SDIO devices.
+config LIBERTAS_SPI
+ tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
+ depends on LIBERTAS && SPI && GENERIC_GPIO
+ ---help---
+ A driver for Marvell Libertas 8686 SPI devices.
+
config LIBERTAS_DEBUG
bool "Enable full debugging output in the Libertas module."
depends on LIBERTAS
@@ -188,127 +194,6 @@ config AIRO
The driver can be compiled as a module and will be named "airo".
-config HERMES
- tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
- depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211
- select WIRELESS_EXT
- select FW_LOADER
- select CRYPTO
- select CRYPTO_MICHAEL_MIC
- ---help---
- A driver for 802.11b wireless cards based on the "Hermes" or
- Intersil HFA384x (Prism 2) MAC controller. This includes the vast
- majority of the PCMCIA 802.11b cards (which are nearly all rebadges)
- - except for the Cisco/Aironet cards. Cards supported include the
- Apple Airport (not a PCMCIA card), WavelanIEEE/Orinoco,
- Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya,
- IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear
- MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel
- IPW2011, and Symbol Spectrum24 High Rate amongst others.
-
- This option includes the guts of the driver, but in order to
- actually use a card you will also need to enable support for PCMCIA
- Hermes cards, PLX9052 based PCI adaptors or the Apple Airport below.
-
- You will also very likely also need the Wireless Tools in order to
- configure your card and that /etc/pcmcia/wireless.opts works :
- <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
-
-config HERMES_CACHE_FW_ON_INIT
- bool "Cache Hermes firmware on driver initialisation"
- depends on HERMES
- default y
- ---help---
- Say Y to cache any firmware required by the Hermes drivers
- on startup. The firmware will remain cached until the
- driver is unloaded. The cache uses 64K of RAM.
-
- Otherwise load the firmware from userspace as required. In
- this case the driver should be unloaded and restarted
- whenever the firmware is changed.
-
- If you are not sure, say Y.
-
-config APPLE_AIRPORT
- tristate "Apple Airport support (built-in)"
- depends on PPC_PMAC && HERMES
- help
- Say Y here to support the Airport 802.11b wireless Ethernet hardware
- built into the Macintosh iBook and other recent PowerPC-based
- Macintosh machines. This is essentially a Lucent Orinoco card with
- a non-standard interface.
-
- This driver does not support the Airport Extreme (802.11b/g). Use
- the BCM43xx driver for Airport Extreme cards.
-
-config PLX_HERMES
- tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)"
- depends on PCI && HERMES
- help
- Enable support for PCMCIA cards supported by the "Hermes" (aka
- orinoco) driver when used in PLX9052 based PCI adaptors. These
- adaptors are not a full PCMCIA controller but act as a more limited
- PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
- 802.11b PCMCIA cards can be used in desktop machines. The Netgear
- MA301 is such an adaptor.
-
-config TMD_HERMES
- tristate "Hermes in TMD7160 based PCI adaptor support"
- depends on PCI && HERMES
- help
- Enable support for PCMCIA cards supported by the "Hermes" (aka
- orinoco) driver when used in TMD7160 based PCI adaptors. These
- adaptors are not a full PCMCIA controller but act as a more limited
- PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
- 802.11b PCMCIA cards can be used in desktop machines.
-
-config NORTEL_HERMES
- tristate "Nortel emobility PCI adaptor support"
- depends on PCI && HERMES
- help
- Enable support for PCMCIA cards supported by the "Hermes" (aka
- orinoco) driver when used in Nortel emobility PCI adaptors. These
- adaptors are not full PCMCIA controllers, but act as a more limited
- PCI <-> PCMCIA bridge.
-
-config PCI_HERMES
- tristate "Prism 2.5 PCI 802.11b adaptor support"
- depends on PCI && HERMES
- help
- Enable support for PCI and mini-PCI 802.11b wireless NICs based on
- the Prism 2.5 chipset. These are true PCI cards, not the 802.11b
- PCMCIA cards bundled with PCI<->PCMCIA adaptors which are also
- common. Some of the built-in wireless adaptors in laptops are of
- this variety.
-
-config PCMCIA_HERMES
- tristate "Hermes PCMCIA card support"
- depends on PCMCIA && HERMES
- ---help---
- A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
- as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
- EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and
- others). It should also be usable on various Prism II based cards
- such as the Linksys, D-Link and Farallon Skyline. It should also
- work on Symbol cards such as the 3Com AirConnect and Ericsson WLAN.
-
- You will very likely need the Wireless Tools in order to
- configure your card and that /etc/pcmcia/wireless.opts works:
- <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
-
-config PCMCIA_SPECTRUM
- tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
- depends on PCMCIA && HERMES
- ---help---
-
- This is a driver for 802.11b cards using RAM-loadable Symbol
- firmware, such as Symbol Wireless Networker LA4100, CompactFlash
- cards by Socket Communications and Intel PRO/Wireless 2011B.
-
- This driver requires firmware download on startup. Utilities
- for downloading Symbol firmware are available at
- <http://sourceforge.net/projects/orinoco/>
-
config ATMEL
tristate "Atmel at76c50x chipset 802.11b support"
depends on (PCI || PCMCIA) && WLAN_80211
@@ -343,6 +228,14 @@ config PCMCIA_ATMEL
Enable support for PCMCIA cards containing the
Atmel at76c502 and at76c504 chips.
+config AT76C50X_USB
+ tristate "Atmel at76c503/at76c505/at76c505a USB cards"
+ depends on MAC80211 && WLAN_80211 && USB
+ select FW_LOADER
+ ---help---
+ Enable support for USB Wireless devices using Atmel at76c503,
+ at76c505 or at76c505a chips.
+
config AIRO_CS
tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
depends on PCMCIA && (BROKEN || !M32R) && WLAN_80211
@@ -580,9 +473,19 @@ config MAC80211_HWSIM
To compile this driver as a module, choose M here: the module will be
called mac80211_hwsim. If unsure, say N.
+config MWL8K
+ tristate "Marvell 88W8xxx PCI/PCIe Wireless support"
+ depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
+ ---help---
+ This driver supports Marvell TOPDOG 802.11 wireless cards.
+
+ To compile this driver as a module, choose M here: the module
+ will be called mwl8k. If unsure, say N.
+
source "drivers/net/wireless/p54/Kconfig"
source "drivers/net/wireless/ath5k/Kconfig"
source "drivers/net/wireless/ath9k/Kconfig"
+source "drivers/net/wireless/ar9170/Kconfig"
source "drivers/net/wireless/ipw2x00/Kconfig"
source "drivers/net/wireless/iwlwifi/Kconfig"
source "drivers/net/wireless/hostap/Kconfig"
@@ -590,5 +493,6 @@ source "drivers/net/wireless/b43/Kconfig"
source "drivers/net/wireless/b43legacy/Kconfig"
source "drivers/net/wireless/zd1211rw/Kconfig"
source "drivers/net/wireless/rt2x00/Kconfig"
+source "drivers/net/wireless/orinoco/Kconfig"
endmenu
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index ac590e1ca8be..50e7fba7f0ea 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -24,6 +24,8 @@ obj-$(CONFIG_ATMEL) += atmel.o
obj-$(CONFIG_PCI_ATMEL) += atmel_pci.o
obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o
+obj-$(CONFIG_AT76C50X_USB) += at76c50x-usb.o
+
obj-$(CONFIG_PRISM54) += prism54/
obj-$(CONFIG_HOSTAP) += hostap/
@@ -46,6 +48,8 @@ obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/
obj-$(CONFIG_ADM8211) += adm8211.o
+obj-$(CONFIG_MWL8K) += mwl8k.o
+
obj-$(CONFIG_IWLWIFI) += iwlwifi/
obj-$(CONFIG_RT2X00) += rt2x00/
@@ -53,5 +57,6 @@ obj-$(CONFIG_P54_COMMON) += p54/
obj-$(CONFIG_ATH5K) += ath5k/
obj-$(CONFIG_ATH9K) += ath9k/
+obj-$(CONFIG_AR9170_USB) += ar9170/
obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index fc4322ca669f..f21a6171c691 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -496,39 +496,41 @@ typedef struct {
* so all rid access should use the read/writeXXXRid routines.
*/
-/* This is redundant for x86 archs, but it seems necessary for ARM */
-#pragma pack(1)
-
/* This structure came from an email sent to me from an engineer at
aironet for inclusion into this driver */
-typedef struct {
+typedef struct WepKeyRid WepKeyRid;
+struct WepKeyRid {
__le16 len;
__le16 kindex;
u8 mac[ETH_ALEN];
__le16 klen;
u8 key[16];
-} WepKeyRid;
+} __attribute__ ((packed));
/* These structures are from the Aironet's PC4500 Developers Manual */
-typedef struct {
+typedef struct Ssid Ssid;
+struct Ssid {
__le16 len;
u8 ssid[32];
-} Ssid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct SsidRid SsidRid;
+struct SsidRid {
__le16 len;
Ssid ssids[3];
-} SsidRid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct ModulationRid ModulationRid;
+struct ModulationRid {
__le16 len;
__le16 modulation;
#define MOD_DEFAULT cpu_to_le16(0)
#define MOD_CCK cpu_to_le16(1)
#define MOD_MOK cpu_to_le16(2)
-} ModulationRid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct ConfigRid ConfigRid;
+struct ConfigRid {
__le16 len; /* sizeof(ConfigRid) */
__le16 opmode; /* operating mode */
#define MODE_STA_IBSS cpu_to_le16(0)
@@ -649,9 +651,10 @@ typedef struct {
#define MAGIC_STAY_IN_CAM (1<<10)
u8 magicControl;
__le16 autoWake;
-} ConfigRid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct StatusRid StatusRid;
+struct StatusRid {
__le16 len;
u8 mac[ETH_ALEN];
__le16 mode;
@@ -707,21 +710,23 @@ typedef struct {
#define STAT_LEAPFAILED 91
#define STAT_LEAPTIMEDOUT 92
#define STAT_LEAPCOMPLETE 93
-} StatusRid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct StatsRid StatsRid;
+struct StatsRid {
__le16 len;
__le16 spacer;
__le32 vals[100];
-} StatsRid;
-
+} __attribute__ ((packed));
-typedef struct {
+typedef struct APListRid APListRid;
+struct APListRid {
__le16 len;
u8 ap[4][ETH_ALEN];
-} APListRid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct CapabilityRid CapabilityRid;
+struct CapabilityRid {
__le16 len;
char oui[3];
char zero;
@@ -748,17 +753,18 @@ typedef struct {
__le16 bootBlockVer;
__le16 requiredHard;
__le16 extSoftCap;
-} CapabilityRid;
-
+} __attribute__ ((packed));
/* Only present on firmware >= 5.30.17 */
-typedef struct {
+typedef struct BSSListRidExtra BSSListRidExtra;
+struct BSSListRidExtra {
__le16 unknown[4];
u8 fixed[12]; /* WLAN management frame */
u8 iep[624];
-} BSSListRidExtra;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct BSSListRid BSSListRid;
+struct BSSListRid {
__le16 len;
__le16 index; /* First is 0 and 0xffff means end of list */
#define RADIO_FH 1 /* Frequency hopping radio type */
@@ -789,33 +795,37 @@ typedef struct {
/* Only present on firmware >= 5.30.17 */
BSSListRidExtra extra;
-} BSSListRid;
+} __attribute__ ((packed));
typedef struct {
BSSListRid bss;
struct list_head list;
} BSSListElement;
-typedef struct {
+typedef struct tdsRssiEntry tdsRssiEntry;
+struct tdsRssiEntry {
u8 rssipct;
u8 rssidBm;
-} tdsRssiEntry;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct tdsRssiRid tdsRssiRid;
+struct tdsRssiRid {
u16 len;
tdsRssiEntry x[256];
-} tdsRssiRid;
+} __attribute__ ((packed));
-typedef struct {
- u16 len;
- u16 state;
- u16 multicastValid;
+typedef struct MICRid MICRid;
+struct MICRid {
+ __le16 len;
+ __le16 state;
+ __le16 multicastValid;
u8 multicast[16];
- u16 unicastValid;
+ __le16 unicastValid;
u8 unicast[16];
-} MICRid;
+} __attribute__ ((packed));
-typedef struct {
+typedef struct MICBuffer MICBuffer;
+struct MICBuffer {
__be16 typelen;
union {
@@ -830,15 +840,13 @@ typedef struct {
} u;
__be32 mic;
__be32 seq;
-} MICBuffer;
+} __attribute__ ((packed));
typedef struct {
u8 da[ETH_ALEN];
u8 sa[ETH_ALEN];
} etherHead;
-#pragma pack()
-
#define TXCTL_TXOK (1<<1) /* report if tx is ok */
#define TXCTL_TXEX (1<<2) /* report if tx fails */
#define TXCTL_802_3 (0<<3) /* 802.3 packet */
@@ -981,6 +989,14 @@ typedef struct {
dma_addr_t host_addr;
} TxFid;
+struct rx_hdr {
+ __le16 status, len;
+ u8 rssi[2];
+ u8 rate;
+ u8 freq;
+ __le16 tmp[4];
+} __attribute__ ((packed));
+
typedef struct {
unsigned int ctl: 15;
unsigned int rdy: 1;
@@ -1070,10 +1086,6 @@ static WifiCtlHdr wifictlhdr8023 = {
}
};
-// Frequency list (map channels to frequencies)
-static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
- 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
-
// A few details needed for WEP (Wireless Equivalent Privacy)
#define MAX_KEY_SIZE 13 // 128 (?) bits
#define MIN_KEY_SIZE 5 // 40 bits RC4 - WEP
@@ -1082,12 +1094,6 @@ typedef struct wep_key_t {
u8 key[16]; /* 40-bit and 104-bit keys */
} wep_key_t;
-/* Backward compatibility */
-#ifndef IW_ENCODE_NOKEY
-#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
-#define IW_ENCODE_MODE (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)
-#endif /* IW_ENCODE_NOKEY */
-
/* List of Wireless Handlers (new API) */
static const struct iw_handler_def airo_handler_def;
@@ -1155,7 +1161,7 @@ struct airo_info {
use the high bit to mark whether it is in use. */
#define MAX_FIDS 6
#define MPI_MAX_FIDS 1
- int fids[MAX_FIDS];
+ u32 fids[MAX_FIDS];
ConfigRid config;
char keyindex; // Used with auto wep
char defindex; // Used with auto wep
@@ -1229,6 +1235,9 @@ struct airo_info {
#define PCI_SHARED_LEN 2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
char proc_name[IFNAMSIZ];
+ int wep_capable;
+ int max_wep_idx;
+
/* WPA-related stuff */
unsigned int bssListFirst;
unsigned int bssListNext;
@@ -1287,6 +1296,29 @@ static void emmh32_update(emmh32_context *context, u8 *pOctets, int len);
static void emmh32_final(emmh32_context *context, u8 digest[4]);
static int flashpchar(struct airo_info *ai,int byte,int dwelltime);
+static void age_mic_context(miccntx *cur, miccntx *old, u8 *key, int key_len,
+ struct crypto_cipher *tfm)
+{
+ /* If the current MIC context is valid and its key is the same as
+ * the MIC register, there's nothing to do.
+ */
+ if (cur->valid && (memcmp(cur->key, key, key_len) == 0))
+ return;
+
+ /* Age current mic Context */
+ memcpy(old, cur, sizeof(*cur));
+
+ /* Initialize new context */
+ memcpy(cur->key, key, key_len);
+ cur->window = 33; /* Window always points to the middle */
+ cur->rx = 0; /* Rx Sequence numbers */
+ cur->tx = 0; /* Tx sequence numbers */
+ cur->valid = 1; /* Key is now valid */
+
+ /* Give key to mic seed */
+ emmh32_setseed(&cur->seed, key, key_len, tfm);
+}
+
/* micinit - Initialize mic seed */
static void micinit(struct airo_info *ai)
@@ -1297,49 +1329,26 @@ static void micinit(struct airo_info *ai)
PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);
up(&ai->sem);
- ai->micstats.enabled = (mic_rid.state & 0x00FF) ? 1 : 0;
-
- if (ai->micstats.enabled) {
- /* Key must be valid and different */
- if (mic_rid.multicastValid && (!ai->mod[0].mCtx.valid ||
- (memcmp (ai->mod[0].mCtx.key, mic_rid.multicast,
- sizeof(ai->mod[0].mCtx.key)) != 0))) {
- /* Age current mic Context */
- memcpy(&ai->mod[1].mCtx,&ai->mod[0].mCtx,sizeof(miccntx));
- /* Initialize new context */
- memcpy(&ai->mod[0].mCtx.key,mic_rid.multicast,sizeof(mic_rid.multicast));
- ai->mod[0].mCtx.window = 33; //Window always points to the middle
- ai->mod[0].mCtx.rx = 0; //Rx Sequence numbers
- ai->mod[0].mCtx.tx = 0; //Tx sequence numbers
- ai->mod[0].mCtx.valid = 1; //Key is now valid
-
- /* Give key to mic seed */
- emmh32_setseed(&ai->mod[0].mCtx.seed,mic_rid.multicast,sizeof(mic_rid.multicast), ai->tfm);
- }
-
- /* Key must be valid and different */
- if (mic_rid.unicastValid && (!ai->mod[0].uCtx.valid ||
- (memcmp(ai->mod[0].uCtx.key, mic_rid.unicast,
- sizeof(ai->mod[0].uCtx.key)) != 0))) {
- /* Age current mic Context */
- memcpy(&ai->mod[1].uCtx,&ai->mod[0].uCtx,sizeof(miccntx));
- /* Initialize new context */
- memcpy(&ai->mod[0].uCtx.key,mic_rid.unicast,sizeof(mic_rid.unicast));
-
- ai->mod[0].uCtx.window = 33; //Window always points to the middle
- ai->mod[0].uCtx.rx = 0; //Rx Sequence numbers
- ai->mod[0].uCtx.tx = 0; //Tx sequence numbers
- ai->mod[0].uCtx.valid = 1; //Key is now valid
-
- //Give key to mic seed
- emmh32_setseed(&ai->mod[0].uCtx.seed, mic_rid.unicast, sizeof(mic_rid.unicast), ai->tfm);
- }
- } else {
- /* So next time we have a valid key and mic is enabled, we will update
- * the sequence number if the key is the same as before.
- */
+ ai->micstats.enabled = (le16_to_cpu(mic_rid.state) & 0x00FF) ? 1 : 0;
+ if (!ai->micstats.enabled) {
+ /* So next time we have a valid key and mic is enabled, we will
+ * update the sequence number if the key is the same as before.
+ */
ai->mod[0].uCtx.valid = 0;
ai->mod[0].mCtx.valid = 0;
+ return;
+ }
+
+ if (mic_rid.multicastValid) {
+ age_mic_context(&ai->mod[0].mCtx, &ai->mod[1].mCtx,
+ mic_rid.multicast, sizeof(mic_rid.multicast),
+ ai->tfm);
+ }
+
+ if (mic_rid.unicastValid) {
+ age_mic_context(&ai->mod[0].uCtx, &ai->mod[1].uCtx,
+ mic_rid.unicast, sizeof(mic_rid.unicast),
+ ai->tfm);
}
}
@@ -2637,17 +2646,21 @@ static const struct header_ops airo_header_ops = {
.parse = wll_header_parse,
};
+static const struct net_device_ops airo11_netdev_ops = {
+ .ndo_open = airo_open,
+ .ndo_stop = airo_close,
+ .ndo_start_xmit = airo_start_xmit11,
+ .ndo_get_stats = airo_get_stats,
+ .ndo_set_mac_address = airo_set_mac_address,
+ .ndo_do_ioctl = airo_ioctl,
+ .ndo_change_mtu = airo_change_mtu,
+};
+
static void wifi_setup(struct net_device *dev)
{
+ dev->netdev_ops = &airo11_netdev_ops;
dev->header_ops = &airo_header_ops;
- dev->hard_start_xmit = &airo_start_xmit11;
- dev->get_stats = &airo_get_stats;
- dev->set_mac_address = &airo_set_mac_address;
- dev->do_ioctl = &airo_ioctl;
dev->wireless_handlers = &airo_handler_def;
- dev->change_mtu = &airo_change_mtu;
- dev->open = &airo_open;
- dev->stop = &airo_close;
dev->type = ARPHRD_IEEE80211;
dev->hard_header_len = ETH_HLEN;
@@ -2730,27 +2743,30 @@ static void airo_networks_initialize(struct airo_info *ai)
&ai->network_free_list);
}
-static int airo_test_wpa_capable(struct airo_info *ai)
-{
- int status;
- CapabilityRid cap_rid;
-
- status = readCapabilityRid(ai, &cap_rid, 1);
- if (status != SUCCESS) return 0;
+static const struct net_device_ops airo_netdev_ops = {
+ .ndo_open = airo_open,
+ .ndo_stop = airo_close,
+ .ndo_start_xmit = airo_start_xmit,
+ .ndo_get_stats = airo_get_stats,
+ .ndo_set_multicast_list = airo_set_multicast_list,
+ .ndo_set_mac_address = airo_set_mac_address,
+ .ndo_do_ioctl = airo_ioctl,
+ .ndo_change_mtu = airo_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
- /* Only firmware versions 5.30.17 or better can do WPA */
- if (le16_to_cpu(cap_rid.softVer) > 0x530
- || (le16_to_cpu(cap_rid.softVer) == 0x530
- && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
- airo_print_info("", "WPA is supported.");
- return 1;
- }
+static const struct net_device_ops mpi_netdev_ops = {
+ .ndo_open = airo_open,
+ .ndo_stop = airo_close,
+ .ndo_start_xmit = mpi_start_xmit,
+ .ndo_get_stats = airo_get_stats,
+ .ndo_set_multicast_list = airo_set_multicast_list,
+ .ndo_set_mac_address = airo_set_mac_address,
+ .ndo_do_ioctl = airo_ioctl,
+ .ndo_change_mtu = airo_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
- /* No WPA support */
- airo_print_info("", "WPA unsupported (only firmware versions 5.30.17"
- " and greater support WPA. Detected %s)", cap_rid.prodVer);
- return 0;
-}
static struct net_device *_init_airo_card( unsigned short irq, int port,
int is_pcmcia, struct pci_dev *pci,
@@ -2759,6 +2775,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
struct net_device *dev;
struct airo_info *ai;
int i, rc;
+ CapabilityRid cap_rid;
/* Create the network device object. */
dev = alloc_netdev(sizeof(*ai), "", ether_setup);
@@ -2788,22 +2805,16 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
goto err_out_free;
airo_networks_initialize (ai);
+ skb_queue_head_init (&ai->txq);
+
/* The Airo-specific entries in the device structure. */
- if (test_bit(FLAG_MPI,&ai->flags)) {
- skb_queue_head_init (&ai->txq);
- dev->hard_start_xmit = &mpi_start_xmit;
- } else
- dev->hard_start_xmit = &airo_start_xmit;
- dev->get_stats = &airo_get_stats;
- dev->set_multicast_list = &airo_set_multicast_list;
- dev->set_mac_address = &airo_set_mac_address;
- dev->do_ioctl = &airo_ioctl;
+ if (test_bit(FLAG_MPI,&ai->flags))
+ dev->netdev_ops = &mpi_netdev_ops;
+ else
+ dev->netdev_ops = &airo_netdev_ops;
dev->wireless_handlers = &airo_handler_def;
ai->wireless_data.spy_data = &ai->spy_data;
dev->wireless_data = &ai->wireless_data;
- dev->change_mtu = &airo_change_mtu;
- dev->open = &airo_open;
- dev->stop = &airo_close;
dev->irq = irq;
dev->base_addr = port;
@@ -2828,7 +2839,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
}
if (probe) {
- if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) {
+ if (setup_card(ai, dev->dev_addr, 1) != SUCCESS) {
airo_print_err(dev->name, "MAC could not be enabled" );
rc = -EIO;
goto err_out_map;
@@ -2838,28 +2849,50 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
set_bit(FLAG_FLASHING, &ai->flags);
}
+ strcpy(dev->name, "eth%d");
+ rc = register_netdev(dev);
+ if (rc) {
+ airo_print_err(dev->name, "Couldn't register_netdev");
+ goto err_out_map;
+ }
+ ai->wifidev = init_wifidev(ai, dev);
+ if (!ai->wifidev)
+ goto err_out_reg;
+
+ rc = readCapabilityRid(ai, &cap_rid, 1);
+ if (rc != SUCCESS) {
+ rc = -EIO;
+ goto err_out_wifi;
+ }
+ /* WEP capability discovery */
+ ai->wep_capable = (cap_rid.softCap & cpu_to_le16(0x02)) ? 1 : 0;
+ ai->max_wep_idx = (cap_rid.softCap & cpu_to_le16(0x80)) ? 3 : 0;
+
+ airo_print_info(dev->name, "Firmware version %x.%x.%02x",
+ ((le16_to_cpu(cap_rid.softVer) >> 8) & 0xF),
+ (le16_to_cpu(cap_rid.softVer) & 0xFF),
+ le16_to_cpu(cap_rid.softSubVer));
+
/* Test for WPA support */
- if (airo_test_wpa_capable(ai)) {
+ /* Only firmware versions 5.30.17 or better can do WPA */
+ if (le16_to_cpu(cap_rid.softVer) > 0x530
+ || (le16_to_cpu(cap_rid.softVer) == 0x530
+ && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
+ airo_print_info(ai->dev->name, "WPA supported.");
+
set_bit(FLAG_WPA_CAPABLE, &ai->flags);
ai->bssListFirst = RID_WPA_BSSLISTFIRST;
ai->bssListNext = RID_WPA_BSSLISTNEXT;
ai->bssListRidLen = sizeof(BSSListRid);
} else {
+ airo_print_info(ai->dev->name, "WPA unsupported with firmware "
+ "versions older than 5.30.17.");
+
ai->bssListFirst = RID_BSSLISTFIRST;
ai->bssListNext = RID_BSSLISTNEXT;
ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
}
- strcpy(dev->name, "eth%d");
- rc = register_netdev(dev);
- if (rc) {
- airo_print_err(dev->name, "Couldn't register_netdev");
- goto err_out_map;
- }
- ai->wifidev = init_wifidev(ai, dev);
- if (!ai->wifidev)
- goto err_out_reg;
-
set_bit(FLAG_REGISTERED,&ai->flags);
airo_print_info(dev->name, "MAC enabled %pM", dev->dev_addr);
@@ -3127,314 +3160,354 @@ static int header_len(__le16 ctl)
return 24;
}
-static irqreturn_t airo_interrupt(int irq, void *dev_id)
+static void airo_handle_cisco_mic(struct airo_info *ai)
{
- struct net_device *dev = dev_id;
+ if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) {
+ set_bit(JOB_MIC, &ai->jobs);
+ wake_up_interruptible(&ai->thr_wait);
+ }
+}
+
+/* Airo Status codes */
+#define STAT_NOBEACON 0x8000 /* Loss of sync - missed beacons */
+#define STAT_MAXRETRIES 0x8001 /* Loss of sync - max retries */
+#define STAT_MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
+#define STAT_FORCELOSS 0x8003 /* Loss of sync - host request */
+#define STAT_TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
+#define STAT_DEAUTH 0x8100 /* low byte is 802.11 reason code */
+#define STAT_DISASSOC 0x8200 /* low byte is 802.11 reason code */
+#define STAT_ASSOC_FAIL 0x8400 /* low byte is 802.11 reason code */
+#define STAT_AUTH_FAIL 0x0300 /* low byte is 802.11 reason code */
+#define STAT_ASSOC 0x0400 /* Associated */
+#define STAT_REASSOC 0x0600 /* Reassociated? Only on firmware >= 5.30.17 */
+
+static void airo_print_status(const char *devname, u16 status)
+{
+ u8 reason = status & 0xFF;
+
+ switch (status) {
+ case STAT_NOBEACON:
+ airo_print_dbg(devname, "link lost (missed beacons)");
+ break;
+ case STAT_MAXRETRIES:
+ case STAT_MAXARL:
+ airo_print_dbg(devname, "link lost (max retries)");
+ break;
+ case STAT_FORCELOSS:
+ airo_print_dbg(devname, "link lost (local choice)");
+ break;
+ case STAT_TSFSYNC:
+ airo_print_dbg(devname, "link lost (TSF sync lost)");
+ break;
+ case STAT_DEAUTH:
+ airo_print_dbg(devname, "deauthenticated (reason: %d)", reason);
+ break;
+ case STAT_DISASSOC:
+ airo_print_dbg(devname, "disassociated (reason: %d)", reason);
+ break;
+ case STAT_ASSOC_FAIL:
+ airo_print_dbg(devname, "association failed (reason: %d)",
+ reason);
+ break;
+ case STAT_AUTH_FAIL:
+ airo_print_dbg(devname, "authentication failed (reason: %d)",
+ reason);
+ break;
+ default:
+ break;
+ }
+}
+
+static void airo_handle_link(struct airo_info *ai)
+{
+ union iwreq_data wrqu;
+ int scan_forceloss = 0;
u16 status;
- u16 fid;
- struct airo_info *apriv = dev->ml_priv;
- u16 savedInterrupts = 0;
- int handled = 0;
- if (!netif_device_present(dev))
- return IRQ_NONE;
+ /* Get new status and acknowledge the link change */
+ status = le16_to_cpu(IN4500(ai, LINKSTAT));
+ OUT4500(ai, EVACK, EV_LINK);
- for (;;) {
- status = IN4500( apriv, EVSTAT );
- if ( !(status & STATUS_INTS) || status == 0xffff ) break;
+ if ((status == STAT_FORCELOSS) && (ai->scan_timeout > 0))
+ scan_forceloss = 1;
- handled = 1;
+ airo_print_status(ai->dev->name, status);
- if ( status & EV_AWAKE ) {
- OUT4500( apriv, EVACK, EV_AWAKE );
- OUT4500( apriv, EVACK, EV_AWAKE );
- }
+ if ((status == STAT_ASSOC) || (status == STAT_REASSOC)) {
+ if (auto_wep)
+ ai->expires = 0;
+ if (ai->list_bss_task)
+ wake_up_process(ai->list_bss_task);
+ set_bit(FLAG_UPDATE_UNI, &ai->flags);
+ set_bit(FLAG_UPDATE_MULTI, &ai->flags);
- if (!savedInterrupts) {
- savedInterrupts = IN4500( apriv, EVINTEN );
- OUT4500( apriv, EVINTEN, 0 );
+ if (down_trylock(&ai->sem) != 0) {
+ set_bit(JOB_EVENT, &ai->jobs);
+ wake_up_interruptible(&ai->thr_wait);
+ } else
+ airo_send_event(ai->dev);
+ } else if (!scan_forceloss) {
+ if (auto_wep && !ai->expires) {
+ ai->expires = RUN_AT(3*HZ);
+ wake_up_interruptible(&ai->thr_wait);
}
- if ( status & EV_MIC ) {
- OUT4500( apriv, EVACK, EV_MIC );
- if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {
- set_bit(JOB_MIC, &apriv->jobs);
- wake_up_interruptible(&apriv->thr_wait);
- }
- }
- if ( status & EV_LINK ) {
- union iwreq_data wrqu;
- int scan_forceloss = 0;
- /* The link status has changed, if you want to put a
- monitor hook in, do it here. (Remember that
- interrupts are still disabled!)
- */
- u16 newStatus = IN4500(apriv, LINKSTAT);
- OUT4500( apriv, EVACK, EV_LINK);
- /* Here is what newStatus means: */
-#define NOBEACON 0x8000 /* Loss of sync - missed beacons */
-#define MAXRETRIES 0x8001 /* Loss of sync - max retries */
-#define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
-#define FORCELOSS 0x8003 /* Loss of sync - host request */
-#define TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
-#define DEAUTH 0x8100 /* Deauthentication (low byte is reason code) */
-#define DISASS 0x8200 /* Disassociation (low byte is reason code) */
-#define ASSFAIL 0x8400 /* Association failure (low byte is reason
- code) */
-#define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
- code) */
-#define ASSOCIATED 0x0400 /* Associated */
-#define REASSOCIATED 0x0600 /* Reassociated? Only on firmware >= 5.30.17 */
-#define RC_RESERVED 0 /* Reserved return code */
-#define RC_NOREASON 1 /* Unspecified reason */
-#define RC_AUTHINV 2 /* Previous authentication invalid */
-#define RC_DEAUTH 3 /* Deauthenticated because sending station is
- leaving */
-#define RC_NOACT 4 /* Disassociated due to inactivity */
-#define RC_MAXLOAD 5 /* Disassociated because AP is unable to handle
- all currently associated stations */
-#define RC_BADCLASS2 6 /* Class 2 frame received from
- non-Authenticated station */
-#define RC_BADCLASS3 7 /* Class 3 frame received from
- non-Associated station */
-#define RC_STATLEAVE 8 /* Disassociated because sending station is
- leaving BSS */
-#define RC_NOAUTH 9 /* Station requesting (Re)Association is not
- Authenticated with the responding station */
- if (newStatus == FORCELOSS && apriv->scan_timeout > 0)
- scan_forceloss = 1;
- if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) {
- if (auto_wep)
- apriv->expires = 0;
- if (apriv->list_bss_task)
- wake_up_process(apriv->list_bss_task);
- set_bit(FLAG_UPDATE_UNI, &apriv->flags);
- set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
-
- if (down_trylock(&apriv->sem) != 0) {
- set_bit(JOB_EVENT, &apriv->jobs);
- wake_up_interruptible(&apriv->thr_wait);
- } else
- airo_send_event(dev);
- } else if (!scan_forceloss) {
- if (auto_wep && !apriv->expires) {
- apriv->expires = RUN_AT(3*HZ);
- wake_up_interruptible(&apriv->thr_wait);
- }
+ /* Send event to user space */
+ memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(ai->dev, SIOCGIWAP, &wrqu, NULL);
+ }
+}
- /* Send event to user space */
- memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);
- }
- }
+static void airo_handle_rx(struct airo_info *ai)
+{
+ struct sk_buff *skb = NULL;
+ __le16 fc, v, *buffer, tmpbuf[4];
+ u16 len, hdrlen = 0, gap, fid;
+ struct rx_hdr hdr;
+ int success = 0;
- /* Check to see if there is something to receive */
- if ( status & EV_RX ) {
- struct sk_buff *skb = NULL;
- __le16 fc, v;
- u16 len, hdrlen = 0;
-#pragma pack(1)
- struct {
- __le16 status, len;
- u8 rssi[2];
- u8 rate;
- u8 freq;
- __le16 tmp[4];
- } hdr;
-#pragma pack()
- u16 gap;
- __le16 tmpbuf[4];
- __le16 *buffer;
-
- if (test_bit(FLAG_MPI,&apriv->flags)) {
- if (test_bit(FLAG_802_11, &apriv->flags))
- mpi_receive_802_11(apriv);
- else
- mpi_receive_802_3(apriv);
- OUT4500(apriv, EVACK, EV_RX);
- goto exitrx;
- }
+ if (test_bit(FLAG_MPI, &ai->flags)) {
+ if (test_bit(FLAG_802_11, &ai->flags))
+ mpi_receive_802_11(ai);
+ else
+ mpi_receive_802_3(ai);
+ OUT4500(ai, EVACK, EV_RX);
+ return;
+ }
- fid = IN4500( apriv, RXFID );
-
- /* Get the packet length */
- if (test_bit(FLAG_802_11, &apriv->flags)) {
- bap_setup (apriv, fid, 4, BAP0);
- bap_read (apriv, (__le16*)&hdr, sizeof(hdr), BAP0);
- /* Bad CRC. Ignore packet */
- if (le16_to_cpu(hdr.status) & 2)
- hdr.len = 0;
- if (apriv->wifidev == NULL)
- hdr.len = 0;
- } else {
- bap_setup (apriv, fid, 0x36, BAP0);
- bap_read (apriv, &hdr.len, 2, BAP0);
- }
- len = le16_to_cpu(hdr.len);
+ fid = IN4500(ai, RXFID);
- if (len > AIRO_DEF_MTU) {
- airo_print_err(apriv->dev->name, "Bad size %d", len);
- goto badrx;
- }
- if (len == 0)
- goto badrx;
+ /* Get the packet length */
+ if (test_bit(FLAG_802_11, &ai->flags)) {
+ bap_setup (ai, fid, 4, BAP0);
+ bap_read (ai, (__le16*)&hdr, sizeof(hdr), BAP0);
+ /* Bad CRC. Ignore packet */
+ if (le16_to_cpu(hdr.status) & 2)
+ hdr.len = 0;
+ if (ai->wifidev == NULL)
+ hdr.len = 0;
+ } else {
+ bap_setup(ai, fid, 0x36, BAP0);
+ bap_read(ai, &hdr.len, 2, BAP0);
+ }
+ len = le16_to_cpu(hdr.len);
- if (test_bit(FLAG_802_11, &apriv->flags)) {
- bap_read (apriv, &fc, sizeof(fc), BAP0);
- hdrlen = header_len(fc);
- } else
- hdrlen = ETH_ALEN * 2;
+ if (len > AIRO_DEF_MTU) {
+ airo_print_err(ai->dev->name, "Bad size %d", len);
+ goto done;
+ }
+ if (len == 0)
+ goto done;
- skb = dev_alloc_skb( len + hdrlen + 2 + 2 );
- if ( !skb ) {
- dev->stats.rx_dropped++;
- goto badrx;
- }
- skb_reserve(skb, 2); /* This way the IP header is aligned */
- buffer = (__le16*)skb_put (skb, len + hdrlen);
- if (test_bit(FLAG_802_11, &apriv->flags)) {
- buffer[0] = fc;
- bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
- if (hdrlen == 24)
- bap_read (apriv, tmpbuf, 6, BAP0);
-
- bap_read (apriv, &v, sizeof(v), BAP0);
- gap = le16_to_cpu(v);
- if (gap) {
- if (gap <= 8) {
- bap_read (apriv, tmpbuf, gap, BAP0);
- } else {
- airo_print_err(apriv->dev->name, "gaplen too "
- "big. Problems will follow...");
- }
- }
- bap_read (apriv, buffer + hdrlen/2, len, BAP0);
+ if (test_bit(FLAG_802_11, &ai->flags)) {
+ bap_read(ai, &fc, sizeof (fc), BAP0);
+ hdrlen = header_len(fc);
+ } else
+ hdrlen = ETH_ALEN * 2;
+
+ skb = dev_alloc_skb(len + hdrlen + 2 + 2);
+ if (!skb) {
+ ai->dev->stats.rx_dropped++;
+ goto done;
+ }
+
+ skb_reserve(skb, 2); /* This way the IP header is aligned */
+ buffer = (__le16 *) skb_put(skb, len + hdrlen);
+ if (test_bit(FLAG_802_11, &ai->flags)) {
+ buffer[0] = fc;
+ bap_read(ai, buffer + 1, hdrlen - 2, BAP0);
+ if (hdrlen == 24)
+ bap_read(ai, tmpbuf, 6, BAP0);
+
+ bap_read(ai, &v, sizeof(v), BAP0);
+ gap = le16_to_cpu(v);
+ if (gap) {
+ if (gap <= 8) {
+ bap_read(ai, tmpbuf, gap, BAP0);
} else {
- MICBuffer micbuf;
- bap_read (apriv, buffer, ETH_ALEN*2, BAP0);
- if (apriv->micstats.enabled) {
- bap_read (apriv,(__le16*)&micbuf,sizeof(micbuf),BAP0);
- if (ntohs(micbuf.typelen) > 0x05DC)
- bap_setup (apriv, fid, 0x44, BAP0);
- else {
- if (len <= sizeof(micbuf))
- goto badmic;
-
- len -= sizeof(micbuf);
- skb_trim (skb, len + hdrlen);
- }
- }
- bap_read(apriv,buffer+ETH_ALEN,len,BAP0);
- if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {
-badmic:
- dev_kfree_skb_irq (skb);
-badrx:
- OUT4500( apriv, EVACK, EV_RX);
- goto exitrx;
+ airo_print_err(ai->dev->name, "gaplen too "
+ "big. Problems will follow...");
+ }
+ }
+ bap_read(ai, buffer + hdrlen/2, len, BAP0);
+ } else {
+ MICBuffer micbuf;
+
+ bap_read(ai, buffer, ETH_ALEN * 2, BAP0);
+ if (ai->micstats.enabled) {
+ bap_read(ai, (__le16 *) &micbuf, sizeof (micbuf), BAP0);
+ if (ntohs(micbuf.typelen) > 0x05DC)
+ bap_setup(ai, fid, 0x44, BAP0);
+ else {
+ if (len <= sizeof (micbuf)) {
+ dev_kfree_skb_irq(skb);
+ goto done;
}
+
+ len -= sizeof(micbuf);
+ skb_trim(skb, len + hdrlen);
}
+ }
+
+ bap_read(ai, buffer + ETH_ALEN, len, BAP0);
+ if (decapsulate(ai, &micbuf, (etherHead*) buffer, len))
+ dev_kfree_skb_irq (skb);
+ else
+ success = 1;
+ }
+
#ifdef WIRELESS_SPY
- if (apriv->spy_data.spy_number > 0) {
- char *sa;
- struct iw_quality wstats;
- /* Prepare spy data : addr + qual */
- if (!test_bit(FLAG_802_11, &apriv->flags)) {
- sa = (char*)buffer + 6;
- bap_setup (apriv, fid, 8, BAP0);
- bap_read (apriv, (__le16*)hdr.rssi, 2, BAP0);
- } else
- sa = (char*)buffer + 10;
- wstats.qual = hdr.rssi[0];
- if (apriv->rssi)
- wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
- else
- wstats.level = (hdr.rssi[1] + 321) / 2;
- wstats.noise = apriv->wstats.qual.noise;
- wstats.updated = IW_QUAL_LEVEL_UPDATED
- | IW_QUAL_QUAL_UPDATED
- | IW_QUAL_DBM;
- /* Update spy records */
- wireless_spy_update(dev, sa, &wstats);
- }
+ if (success && (ai->spy_data.spy_number > 0)) {
+ char *sa;
+ struct iw_quality wstats;
+
+ /* Prepare spy data : addr + qual */
+ if (!test_bit(FLAG_802_11, &ai->flags)) {
+ sa = (char *) buffer + 6;
+ bap_setup(ai, fid, 8, BAP0);
+ bap_read(ai, (__le16 *) hdr.rssi, 2, BAP0);
+ } else
+ sa = (char *) buffer + 10;
+ wstats.qual = hdr.rssi[0];
+ if (ai->rssi)
+ wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
+ else
+ wstats.level = (hdr.rssi[1] + 321) / 2;
+ wstats.noise = ai->wstats.qual.noise;
+ wstats.updated = IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_QUAL_UPDATED
+ | IW_QUAL_DBM;
+ /* Update spy records */
+ wireless_spy_update(ai->dev, sa, &wstats);
+ }
#endif /* WIRELESS_SPY */
- OUT4500( apriv, EVACK, EV_RX);
- if (test_bit(FLAG_802_11, &apriv->flags)) {
- skb_reset_mac_header(skb);
- skb->pkt_type = PACKET_OTHERHOST;
- skb->dev = apriv->wifidev;
- skb->protocol = htons(ETH_P_802_2);
- } else
- skb->protocol = eth_type_trans(skb,dev);
- skb->ip_summed = CHECKSUM_NONE;
+done:
+ OUT4500(ai, EVACK, EV_RX);
+
+ if (success) {
+ if (test_bit(FLAG_802_11, &ai->flags)) {
+ skb_reset_mac_header(skb);
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->dev = ai->wifidev;
+ skb->protocol = htons(ETH_P_802_2);
+ } else
+ skb->protocol = eth_type_trans(skb, ai->dev);
+ skb->ip_summed = CHECKSUM_NONE;
+
+ netif_rx(skb);
+ }
+}
+
+static void airo_handle_tx(struct airo_info *ai, u16 status)
+{
+ int i, len = 0, index = -1;
+ u16 fid;
- netif_rx( skb );
+ if (test_bit(FLAG_MPI, &ai->flags)) {
+ unsigned long flags;
+
+ if (status & EV_TXEXC)
+ get_tx_error(ai, -1);
+
+ spin_lock_irqsave(&ai->aux_lock, flags);
+ if (!skb_queue_empty(&ai->txq)) {
+ spin_unlock_irqrestore(&ai->aux_lock,flags);
+ mpi_send_packet(ai->dev);
+ } else {
+ clear_bit(FLAG_PENDING_XMIT, &ai->flags);
+ spin_unlock_irqrestore(&ai->aux_lock,flags);
+ netif_wake_queue(ai->dev);
}
-exitrx:
+ OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
+ return;
+ }
- /* Check to see if a packet has been transmitted */
- if ( status & ( EV_TX|EV_TXCPY|EV_TXEXC ) ) {
- int i;
- int len = 0;
- int index = -1;
-
- if (test_bit(FLAG_MPI,&apriv->flags)) {
- unsigned long flags;
-
- if (status & EV_TXEXC)
- get_tx_error(apriv, -1);
- spin_lock_irqsave(&apriv->aux_lock, flags);
- if (!skb_queue_empty(&apriv->txq)) {
- spin_unlock_irqrestore(&apriv->aux_lock,flags);
- mpi_send_packet (dev);
- } else {
- clear_bit(FLAG_PENDING_XMIT, &apriv->flags);
- spin_unlock_irqrestore(&apriv->aux_lock,flags);
- netif_wake_queue (dev);
- }
- OUT4500( apriv, EVACK,
- status & (EV_TX|EV_TXCPY|EV_TXEXC));
- goto exittx;
- }
+ fid = IN4500(ai, TXCOMPLFID);
+
+ for(i = 0; i < MAX_FIDS; i++) {
+ if ((ai->fids[i] & 0xffff) == fid) {
+ len = ai->fids[i] >> 16;
+ index = i;
+ }
+ }
- fid = IN4500(apriv, TXCOMPLFID);
+ if (index != -1) {
+ if (status & EV_TXEXC)
+ get_tx_error(ai, index);
- for( i = 0; i < MAX_FIDS; i++ ) {
- if ( ( apriv->fids[i] & 0xffff ) == fid ) {
- len = apriv->fids[i] >> 16;
- index = i;
- }
- }
- if (index != -1) {
- if (status & EV_TXEXC)
- get_tx_error(apriv, index);
- OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
- /* Set up to be used again */
- apriv->fids[index] &= 0xffff;
- if (index < MAX_FIDS / 2) {
- if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags))
- netif_wake_queue(dev);
- } else {
- if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags))
- netif_wake_queue(apriv->wifidev);
- }
- } else {
- OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
- airo_print_err(apriv->dev->name, "Unallocated FID was "
- "used to xmit" );
- }
+ OUT4500(ai, EVACK, status & (EV_TX | EV_TXEXC));
+
+ /* Set up to be used again */
+ ai->fids[index] &= 0xffff;
+ if (index < MAX_FIDS / 2) {
+ if (!test_bit(FLAG_PENDING_XMIT, &ai->flags))
+ netif_wake_queue(ai->dev);
+ } else {
+ if (!test_bit(FLAG_PENDING_XMIT11, &ai->flags))
+ netif_wake_queue(ai->wifidev);
+ }
+ } else {
+ OUT4500(ai, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
+ airo_print_err(ai->dev->name, "Unallocated FID was used to xmit");
+ }
+}
+
+static irqreturn_t airo_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ u16 status, savedInterrupts = 0;
+ struct airo_info *ai = dev->ml_priv;
+ int handled = 0;
+
+ if (!netif_device_present(dev))
+ return IRQ_NONE;
+
+ for (;;) {
+ status = IN4500(ai, EVSTAT);
+ if (!(status & STATUS_INTS) || (status == 0xffff))
+ break;
+
+ handled = 1;
+
+ if (status & EV_AWAKE) {
+ OUT4500(ai, EVACK, EV_AWAKE);
+ OUT4500(ai, EVACK, EV_AWAKE);
+ }
+
+ if (!savedInterrupts) {
+ savedInterrupts = IN4500(ai, EVINTEN);
+ OUT4500(ai, EVINTEN, 0);
+ }
+
+ if (status & EV_MIC) {
+ OUT4500(ai, EVACK, EV_MIC);
+ airo_handle_cisco_mic(ai);
}
-exittx:
- if ( status & ~STATUS_INTS & ~IGNORE_INTS )
- airo_print_warn(apriv->dev->name, "Got weird status %x",
+
+ if (status & EV_LINK) {
+ /* Link status changed */
+ airo_handle_link(ai);
+ }
+
+ /* Check to see if there is something to receive */
+ if (status & EV_RX)
+ airo_handle_rx(ai);
+
+ /* Check to see if a packet has been transmitted */
+ if (status & (EV_TX | EV_TXCPY | EV_TXEXC))
+ airo_handle_tx(ai, status);
+
+ if ( status & ~STATUS_INTS & ~IGNORE_INTS ) {
+ airo_print_warn(ai->dev->name, "Got weird status %x",
status & ~STATUS_INTS & ~IGNORE_INTS );
+ }
}
if (savedInterrupts)
- OUT4500( apriv, EVINTEN, savedInterrupts );
+ OUT4500(ai, EVINTEN, savedInterrupts);
- /* done.. */
return IRQ_RETVAL(handled);
}
@@ -3613,18 +3686,10 @@ static void mpi_receive_802_11(struct airo_info *ai)
struct sk_buff *skb = NULL;
u16 len, hdrlen = 0;
__le16 fc;
-#pragma pack(1)
- struct {
- __le16 status, len;
- u8 rssi[2];
- u8 rate;
- u8 freq;
- __le16 tmp[4];
- } hdr;
-#pragma pack()
+ struct rx_hdr hdr;
u16 gap;
u16 *buffer;
- char *ptr = ai->rxfids[0].virtual_host_addr+4;
+ char *ptr = ai->rxfids[0].virtual_host_addr + 4;
memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
memcpy ((char *)&hdr, ptr, sizeof(hdr));
@@ -3691,6 +3756,7 @@ static void mpi_receive_802_11(struct airo_info *ai)
skb->protocol = htons(ETH_P_802_2);
skb->ip_summed = CHECKSUM_NONE;
netif_rx( skb );
+
badrx:
if (rxd.valid == 0) {
rxd.valid = 1;
@@ -3705,7 +3771,6 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
Cmd cmd;
Resp rsp;
int status;
- int i;
SsidRid mySsid;
__le16 lastindex;
WepKeyRid wkr;
@@ -3747,6 +3812,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
if (lock)
up(&ai->sem);
if (ai->config.len == 0) {
+ int i;
tdsRssiRid rssi_rid;
CapabilityRid cap_rid;
@@ -3794,14 +3860,12 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
/* Check to see if there are any insmod configured
rates to add */
if ( rates[0] ) {
- int i = 0;
memset(ai->config.rates,0,sizeof(ai->config.rates));
for( i = 0; i < 8 && rates[i]; i++ ) {
ai->config.rates[i] = rates[i];
}
}
if ( basic_rate > 0 ) {
- int i;
for( i = 0; i < 8; i++ ) {
if ( ai->config.rates[i] == basic_rate ||
!ai->config.rates ) {
@@ -4428,7 +4492,6 @@ static int setup_proc_entry( struct net_device *dev,
goto fail;
apriv->proc_entry->uid = proc_uid;
apriv->proc_entry->gid = proc_gid;
- apriv->proc_entry->owner = THIS_MODULE;
/* Setup the StatsDelta */
entry = proc_create_data("StatsDelta",
@@ -4686,7 +4749,7 @@ static int proc_stats_rid_open( struct inode *inode,
StatsRid stats;
int i, j;
__le32 *vals = stats.vals;
- int len = le16_to_cpu(stats.len);
+ int len;
if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
return -ENOMEM;
@@ -4697,6 +4760,7 @@ static int proc_stats_rid_open( struct inode *inode,
}
readStatsRid(apriv, &stats, rid, 1);
+ len = le16_to_cpu(stats.len);
j = 0;
for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
@@ -5131,55 +5195,98 @@ static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
return rc;
}
-/* Returns the length of the key at the index. If index == 0xffff
- * the index of the transmit key is returned. If the key doesn't exist,
- * -1 will be returned.
+/* Returns the WEP key at the specified index, or -1 if that key does
+ * not exist. The buffer is assumed to be at least 16 bytes in length.
*/
-static int get_wep_key(struct airo_info *ai, u16 index) {
+static int get_wep_key(struct airo_info *ai, u16 index, char *buf, u16 buflen)
+{
WepKeyRid wkr;
int rc;
__le16 lastindex;
rc = readWepKeyRid(ai, &wkr, 1, 1);
- if (rc == SUCCESS) do {
+ if (rc != SUCCESS)
+ return -1;
+ do {
lastindex = wkr.kindex;
- if (wkr.kindex == cpu_to_le16(index)) {
- if (index == 0xffff) {
- return wkr.mac[0];
- }
- return le16_to_cpu(wkr.klen);
+ if (le16_to_cpu(wkr.kindex) == index) {
+ int klen = min_t(int, buflen, le16_to_cpu(wkr.klen));
+ memcpy(buf, wkr.key, klen);
+ return klen;
}
- readWepKeyRid(ai, &wkr, 0, 1);
+ rc = readWepKeyRid(ai, &wkr, 0, 1);
+ if (rc != SUCCESS)
+ return -1;
} while (lastindex != wkr.kindex);
return -1;
}
-static int set_wep_key(struct airo_info *ai, u16 index,
- const char *key, u16 keylen, int perm, int lock )
+static int get_wep_tx_idx(struct airo_info *ai)
+{
+ WepKeyRid wkr;
+ int rc;
+ __le16 lastindex;
+
+ rc = readWepKeyRid(ai, &wkr, 1, 1);
+ if (rc != SUCCESS)
+ return -1;
+ do {
+ lastindex = wkr.kindex;
+ if (wkr.kindex == cpu_to_le16(0xffff))
+ return wkr.mac[0];
+ rc = readWepKeyRid(ai, &wkr, 0, 1);
+ if (rc != SUCCESS)
+ return -1;
+ } while (lastindex != wkr.kindex);
+ return -1;
+}
+
+static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
+ u16 keylen, int perm, int lock)
{
static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
WepKeyRid wkr;
+ int rc;
- memset(&wkr, 0, sizeof(wkr));
if (keylen == 0) {
-// We are selecting which key to use
- wkr.len = cpu_to_le16(sizeof(wkr));
- wkr.kindex = cpu_to_le16(0xffff);
- wkr.mac[0] = (char)index;
- if (perm) ai->defindex = (char)index;
- } else {
-// We are actually setting the key
- wkr.len = cpu_to_le16(sizeof(wkr));
- wkr.kindex = cpu_to_le16(index);
- wkr.klen = cpu_to_le16(keylen);
- memcpy( wkr.key, key, keylen );
- memcpy( wkr.mac, macaddr, ETH_ALEN );
+ airo_print_err(ai->dev->name, "%s: key length to set was zero",
+ __func__);
+ return -1;
}
+ memset(&wkr, 0, sizeof(wkr));
+ wkr.len = cpu_to_le16(sizeof(wkr));
+ wkr.kindex = cpu_to_le16(index);
+ wkr.klen = cpu_to_le16(keylen);
+ memcpy(wkr.key, key, keylen);
+ memcpy(wkr.mac, macaddr, ETH_ALEN);
+
if (perm) disable_MAC(ai, lock);
- writeWepKeyRid(ai, &wkr, perm, lock);
+ rc = writeWepKeyRid(ai, &wkr, perm, lock);
if (perm) enable_MAC(ai, lock);
- return 0;
+ return rc;
+}
+
+static int set_wep_tx_idx(struct airo_info *ai, u16 index, int perm, int lock)
+{
+ WepKeyRid wkr;
+ int rc;
+
+ memset(&wkr, 0, sizeof(wkr));
+ wkr.len = cpu_to_le16(sizeof(wkr));
+ wkr.kindex = cpu_to_le16(0xffff);
+ wkr.mac[0] = (char)index;
+
+ if (perm) {
+ ai->defindex = (char)index;
+ disable_MAC(ai, lock);
+ }
+
+ rc = writeWepKeyRid(ai, &wkr, perm, lock);
+
+ if (perm)
+ enable_MAC(ai, lock);
+ return rc;
}
static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
@@ -5187,7 +5294,7 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
struct proc_dir_entry *dp = PDE(inode);
struct net_device *dev = dp->data;
struct airo_info *ai = dev->ml_priv;
- int i;
+ int i, rc;
char key[16];
u16 index = 0;
int j = 0;
@@ -5201,7 +5308,12 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
(data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
index = data->wbuffer[0] - '0';
if (data->wbuffer[1] == '\n') {
- set_wep_key(ai, index, NULL, 0, 1, 1);
+ rc = set_wep_tx_idx(ai, index, 1, 1);
+ if (rc < 0) {
+ airo_print_err(ai->dev->name, "failed to set "
+ "WEP transmit index to %d: %d.",
+ index, rc);
+ }
return;
}
j = 2;
@@ -5220,7 +5332,12 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
break;
}
}
- set_wep_key(ai, index, key, i/3, 1, 1);
+
+ rc = set_wep_key(ai, index, key, i/3, 1, 1);
+ if (rc < 0) {
+ airo_print_err(ai->dev->name, "failed to set WEP key at index "
+ "%d: %d.", index, rc);
+ }
}
static int proc_wepkey_open( struct inode *inode, struct file *file )
@@ -5451,13 +5568,13 @@ static void timer_func( struct net_device *dev ) {
break;
case AUTH_SHAREDKEY:
if (apriv->keyindex < auto_wep) {
- set_wep_key(apriv, apriv->keyindex, NULL, 0, 0, 0);
+ set_wep_tx_idx(apriv, apriv->keyindex, 0, 0);
apriv->config.authType = AUTH_SHAREDKEY;
apriv->keyindex++;
} else {
/* Drop to ENCRYPT */
apriv->keyindex = 0;
- set_wep_key(apriv, apriv->defindex, NULL, 0, 0, 0);
+ set_wep_tx_idx(apriv, apriv->defindex, 0, 0);
apriv->config.authType = AUTH_ENCRYPT;
}
break;
@@ -5725,16 +5842,12 @@ static int airo_set_freq(struct net_device *dev,
int rc = -EINPROGRESS; /* Call commit handler */
/* If setting by frequency, convert to a channel */
- if((fwrq->e == 1) &&
- (fwrq->m >= (int) 2.412e8) &&
- (fwrq->m <= (int) 2.487e8)) {
+ if(fwrq->e == 1) {
int f = fwrq->m / 100000;
- int c = 0;
- while((c < 14) && (f != frequency_list[c]))
- c++;
+
/* Hack to fall through... */
fwrq->e = 0;
- fwrq->m = c + 1;
+ fwrq->m = ieee80211_freq_to_dsss_chan(f);
}
/* Setting by channel number */
if((fwrq->m > 1000) || (fwrq->e > 0))
@@ -5778,7 +5891,7 @@ static int airo_get_freq(struct net_device *dev,
ch = le16_to_cpu(status_rid.channel);
if((ch > 0) && (ch < 15)) {
- fwrq->m = frequency_list[ch - 1] * 100000;
+ fwrq->m = ieee80211_dsss_chan_to_freq(ch) * 100000;
fwrq->e = 1;
} else {
fwrq->m = ch;
@@ -6234,11 +6347,9 @@ static int airo_get_mode(struct net_device *dev,
return 0;
}
-static inline int valid_index(CapabilityRid *p, int index)
+static inline int valid_index(struct airo_info *ai, int index)
{
- if (index < 0)
- return 0;
- return index < (p->softCap & cpu_to_le16(0x80) ? 4 : 1);
+ return (index >= 0) && (index <= ai->max_wep_idx);
}
/*------------------------------------------------------------------*/
@@ -6251,16 +6362,13 @@ static int airo_set_encode(struct net_device *dev,
char *extra)
{
struct airo_info *local = dev->ml_priv;
- CapabilityRid cap_rid; /* Card capability info */
- int perm = ( dwrq->flags & IW_ENCODE_TEMP ? 0 : 1 );
+ int perm = (dwrq->flags & IW_ENCODE_TEMP ? 0 : 1);
__le16 currentAuthType = local->config.authType;
+ int rc = 0;
- /* Is WEP supported ? */
- readCapabilityRid(local, &cap_rid, 1);
- /* Older firmware doesn't support this...
- if(!(cap_rid.softCap & cpu_to_le16(2))) {
+ if (!local->wep_capable)
return -EOPNOTSUPP;
- } */
+
readConfigRid(local, 1);
/* Basic checking: do we have a key to set ?
@@ -6272,14 +6380,21 @@ static int airo_set_encode(struct net_device *dev,
if (dwrq->length > 0) {
wep_key_t key;
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- int current_index = get_wep_key(local, 0xffff);
+ int current_index;
+
/* Check the size of the key */
if (dwrq->length > MAX_KEY_SIZE) {
return -EINVAL;
}
+
+ current_index = get_wep_tx_idx(local);
+ if (current_index < 0)
+ current_index = 0;
+
/* Check the index (none -> use current) */
- if (!valid_index(&cap_rid, index))
+ if (!valid_index(local, index))
index = current_index;
+
/* Set the length */
if (dwrq->length > MIN_KEY_SIZE)
key.len = MAX_KEY_SIZE;
@@ -6296,7 +6411,13 @@ static int airo_set_encode(struct net_device *dev,
/* Copy the key in the driver */
memcpy(key.key, extra, dwrq->length);
/* Send the key to the card */
- set_wep_key(local, index, key.key, key.len, perm, 1);
+ rc = set_wep_key(local, index, key.key, key.len, perm, 1);
+ if (rc < 0) {
+ airo_print_err(local->dev->name, "failed to set"
+ " WEP key at index %d: %d.",
+ index, rc);
+ return rc;
+ }
}
/* WE specify that if a valid key is set, encryption
* should be enabled (user may turn it off later)
@@ -6308,12 +6429,19 @@ static int airo_set_encode(struct net_device *dev,
} else {
/* Do we want to just set the transmit key index ? */
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- if (valid_index(&cap_rid, index)) {
- set_wep_key(local, index, NULL, 0, perm, 1);
- } else
+ if (valid_index(local, index)) {
+ rc = set_wep_tx_idx(local, index, perm, 1);
+ if (rc < 0) {
+ airo_print_err(local->dev->name, "failed to set"
+ " WEP transmit index to %d: %d.",
+ index, rc);
+ return rc;
+ }
+ } else {
/* Don't complain if only change the mode */
if (!(dwrq->flags & IW_ENCODE_MODE))
return -EINVAL;
+ }
}
/* Read the flags */
if(dwrq->flags & IW_ENCODE_DISABLED)
@@ -6339,14 +6467,13 @@ static int airo_get_encode(struct net_device *dev,
{
struct airo_info *local = dev->ml_priv;
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
- CapabilityRid cap_rid; /* Card capability info */
+ u8 buf[16];
- /* Is it supported ? */
- readCapabilityRid(local, &cap_rid, 1);
- if(!(cap_rid.softCap & cpu_to_le16(2))) {
+ if (!local->wep_capable)
return -EOPNOTSUPP;
- }
+
readConfigRid(local, 1);
+
/* Check encryption mode */
switch(local->config.authType) {
case AUTH_ENCRYPT:
@@ -6365,14 +6492,17 @@ static int airo_get_encode(struct net_device *dev,
memset(extra, 0, 16);
/* Which key do we want ? -1 -> tx index */
- if (!valid_index(&cap_rid, index))
- index = get_wep_key(local, 0xffff);
+ if (!valid_index(local, index)) {
+ index = get_wep_tx_idx(local);
+ if (index < 0)
+ index = 0;
+ }
dwrq->flags |= index + 1;
+
/* Copy the key to the user buffer */
- dwrq->length = get_wep_key(local, index);
- if (dwrq->length > 16) {
- dwrq->length=0;
- }
+ dwrq->length = get_wep_key(local, index, &buf[0], sizeof(buf));
+ memcpy(extra, buf, dwrq->length);
+
return 0;
}
@@ -6388,28 +6518,27 @@ static int airo_set_encodeext(struct net_device *dev,
struct airo_info *local = dev->ml_priv;
struct iw_point *encoding = &wrqu->encoding;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- CapabilityRid cap_rid; /* Card capability info */
int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
__le16 currentAuthType = local->config.authType;
- int idx, key_len, alg = ext->alg, set_key = 1;
+ int idx, key_len, alg = ext->alg, set_key = 1, rc;
wep_key_t key;
- /* Is WEP supported ? */
- readCapabilityRid(local, &cap_rid, 1);
- /* Older firmware doesn't support this...
- if(!(cap_rid.softCap & cpu_to_le16(2))) {
+ if (!local->wep_capable)
return -EOPNOTSUPP;
- } */
+
readConfigRid(local, 1);
/* Determine and validate the key index */
idx = encoding->flags & IW_ENCODE_INDEX;
if (idx) {
- if (!valid_index(&cap_rid, idx - 1))
+ if (!valid_index(local, idx - 1))
return -EINVAL;
idx--;
- } else
- idx = get_wep_key(local, 0xffff);
+ } else {
+ idx = get_wep_tx_idx(local);
+ if (idx < 0)
+ idx = 0;
+ }
if (encoding->flags & IW_ENCODE_DISABLED)
alg = IW_ENCODE_ALG_NONE;
@@ -6418,7 +6547,13 @@ static int airo_set_encodeext(struct net_device *dev,
/* Only set transmit key index here, actual
* key is set below if needed.
*/
- set_wep_key(local, idx, NULL, 0, perm, 1);
+ rc = set_wep_tx_idx(local, idx, perm, 1);
+ if (rc < 0) {
+ airo_print_err(local->dev->name, "failed to set "
+ "WEP transmit index to %d: %d.",
+ idx, rc);
+ return rc;
+ }
set_key = ext->key_len > 0 ? 1 : 0;
}
@@ -6444,7 +6579,12 @@ static int airo_set_encodeext(struct net_device *dev,
return -EINVAL;
}
/* Send the key to the card */
- set_wep_key(local, idx, key.key, key.len, perm, 1);
+ rc = set_wep_key(local, idx, key.key, key.len, perm, 1);
+ if (rc < 0) {
+ airo_print_err(local->dev->name, "failed to set WEP key"
+ " at index %d: %d.", idx, rc);
+ return rc;
+ }
}
/* Read the flags */
@@ -6474,14 +6614,12 @@ static int airo_get_encodeext(struct net_device *dev,
struct airo_info *local = dev->ml_priv;
struct iw_point *encoding = &wrqu->encoding;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- CapabilityRid cap_rid; /* Card capability info */
int idx, max_key_len;
+ u8 buf[16];
- /* Is it supported ? */
- readCapabilityRid(local, &cap_rid, 1);
- if(!(cap_rid.softCap & cpu_to_le16(2))) {
+ if (!local->wep_capable)
return -EOPNOTSUPP;
- }
+
readConfigRid(local, 1);
max_key_len = encoding->length - sizeof(*ext);
@@ -6490,11 +6628,14 @@ static int airo_get_encodeext(struct net_device *dev,
idx = encoding->flags & IW_ENCODE_INDEX;
if (idx) {
- if (!valid_index(&cap_rid, idx - 1))
+ if (!valid_index(local, idx - 1))
return -EINVAL;
idx--;
- } else
- idx = get_wep_key(local, 0xffff);
+ } else {
+ idx = get_wep_tx_idx(local);
+ if (idx < 0)
+ idx = 0;
+ }
encoding->flags = idx + 1;
memset(ext, 0, sizeof(*ext));
@@ -6517,10 +6658,8 @@ static int airo_get_encodeext(struct net_device *dev,
memset(extra, 0, 16);
/* Copy the key to the user buffer */
- ext->key_len = get_wep_key(local, idx);
- if (ext->key_len > 16) {
- ext->key_len=0;
- }
+ ext->key_len = get_wep_key(local, idx, &buf[0], sizeof(buf));
+ memcpy(extra, buf, ext->key_len);
return 0;
}
@@ -6795,8 +6934,8 @@ static int airo_get_range(struct net_device *dev,
k = 0;
for(i = 0; i < 14; i++) {
range->freq[k].i = i + 1; /* List index */
- range->freq[k].m = frequency_list[i] * 100000;
- range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
+ range->freq[k].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
+ range->freq[k++].e = 1; /* Values in MHz -> * 10^5 * 10 */
}
range->num_frequency = k;
@@ -7031,11 +7170,15 @@ static int airo_get_aplist(struct net_device *dev,
{
struct airo_info *local = dev->ml_priv;
struct sockaddr *address = (struct sockaddr *) extra;
- struct iw_quality qual[IW_MAX_AP];
+ struct iw_quality *qual;
BSSListRid BSSList;
int i;
int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
+ qual = kmalloc(IW_MAX_AP * sizeof(*qual), GFP_KERNEL);
+ if (!qual)
+ return -ENOMEM;
+
for (i = 0; i < IW_MAX_AP; i++) {
u16 dBm;
if (readBSSListRid(local, loseSync, &BSSList))
@@ -7090,6 +7233,7 @@ static int airo_get_aplist(struct net_device *dev,
}
dwrq->length = i;
+ kfree(qual);
return 0;
}
@@ -7189,10 +7333,7 @@ static inline char *airo_translate_scan(struct net_device *dev,
/* Add frequency */
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
- /* iwe.u.freq.m containt the channel (starting 1), our
- * frequency_list array start at index 0...
- */
- iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
+ iwe.u.freq.m = ieee80211_dsss_chan_to_freq(iwe.u.freq.m) * 100000;
iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event(info, current_ev, end_buf,
&iwe, IW_EV_FREQ_LEN);
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index 27696c20f4c2..d0593ed9170e 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -16,8 +16,8 @@
In addition this module was derived from dummy_cs.
The initial developer of dummy_cs is David A. Hinds
<dahinds@users.sourceforge.net>. Portions created by David A. Hinds
- are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-
+ are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+
======================================================================*/
#ifdef __IN_PCMCIA_PACKAGE__
@@ -38,7 +38,7 @@
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <asm/system.h>
#include "airo.h"
@@ -54,7 +54,7 @@
static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0);
static char *version = "$Revision: 1.2 $";
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
+#define DEBUG(n, args...) if (pc_debug > (n)) printk(KERN_DEBUG args);
#else
#define DEBUG(n, args...)
#endif
@@ -62,9 +62,9 @@ static char *version = "$Revision: 1.2 $";
/*====================================================================*/
MODULE_AUTHOR("Benjamin Reed");
-MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
- cards. This is the module that links the PCMCIA card \
- with the airo module.");
+MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet "
+ "cards. This is the module that links the PCMCIA card "
+ "with the airo module.");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
@@ -76,7 +76,7 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
event is received. The config() and release() entry points are
used to configure or release a socket, in response to card
insertion and ejection events. They are invoked from the airo_cs
- event handler.
+ event handler.
*/
static int airo_config(struct pcmcia_device *link);
@@ -103,8 +103,9 @@ static void airo_detach(struct pcmcia_device *p_dev);
by one struct pcmcia_device structure (defined in ds.h).
You may not want to use a linked list for this -- for example, the
- memory card driver uses an array of struct pcmcia_device pointers, where minor
- device numbers are used to derive the corresponding array index.
+ memory card driver uses an array of struct pcmcia_device pointers,
+ where minor device numbers are used to derive the corresponding
+ array index.
*/
/*
@@ -122,22 +123,22 @@ static void airo_detach(struct pcmcia_device *p_dev);
device IO routines can use a flag like this to throttle IO to a
card that is not ready to accept it.
*/
-
+
typedef struct local_info_t {
dev_node_t node;
struct net_device *eth_dev;
} local_info_t;
/*======================================================================
-
+
airo_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
-
+
The dev_link structure is initialized, but we don't actually
configure the card at this point -- we wait until we receive a
card insertion event.
-
+
======================================================================*/
static int airo_probe(struct pcmcia_device *p_dev)
@@ -150,7 +151,7 @@ static int airo_probe(struct pcmcia_device *p_dev)
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
p_dev->irq.Handler = NULL;
-
+
/*
General socket configuration defaults can go here. In this
client, we assume very little, and rely on the CIS for almost
@@ -160,7 +161,7 @@ static int airo_probe(struct pcmcia_device *p_dev)
*/
p_dev->conf.Attributes = 0;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
-
+
/* Allocate space for private device-specific data */
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
if (!local) {
@@ -173,12 +174,12 @@ static int airo_probe(struct pcmcia_device *p_dev)
} /* airo_attach */
/*======================================================================
-
+
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
-
+
======================================================================*/
static void airo_detach(struct pcmcia_device *link)
@@ -187,20 +188,20 @@ static void airo_detach(struct pcmcia_device *link)
airo_release(link);
- if ( ((local_info_t*)link->priv)->eth_dev ) {
- stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
+ if (((local_info_t *)link->priv)->eth_dev) {
+ stop_airo_card(((local_info_t *)link->priv)->eth_dev, 0);
}
- ((local_info_t*)link->priv)->eth_dev = NULL;
+ ((local_info_t *)link->priv)->eth_dev = NULL;
kfree(link->priv);
} /* airo_detach */
/*======================================================================
-
+
airo_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
device available to the system.
-
+
======================================================================*/
#define CS_CHECK(fn, ret) \
@@ -325,26 +326,28 @@ static int airo_config(struct pcmcia_device *link)
*/
if (link->conf.Attributes & CONF_ENABLE_IRQ)
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-
+
/*
This actually configures the PCMCIA socket -- setting up
the I/O windows and the interrupt mapping, and putting the
card and host interface into "Memory and IO" mode.
*/
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
- ((local_info_t*)link->priv)->eth_dev =
- init_airo_card( link->irq.AssignedIRQ,
- link->io.BasePort1, 1, &handle_to_dev(link) );
- if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed;
-
+ CS_CHECK(RequestConfiguration,
+ pcmcia_request_configuration(link, &link->conf));
+ ((local_info_t *)link->priv)->eth_dev =
+ init_airo_card(link->irq.AssignedIRQ,
+ link->io.BasePort1, 1, &handle_to_dev(link));
+ if (!((local_info_t *)link->priv)->eth_dev)
+ goto cs_failed;
+
/*
At this point, the dev_node_t structure(s) need to be
initialized and arranged in a linked list at link->dev_node.
*/
- strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
+ strcpy(dev->node.dev_name, ((local_info_t *)link->priv)->eth_dev->name);
dev->node.major = dev->node.minor = 0;
link->dev_node = &dev->node;
-
+
/* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x: ",
dev->node.dev_name, link->conf.ConfigIndex);
@@ -374,11 +377,11 @@ static int airo_config(struct pcmcia_device *link)
} /* airo_config */
/*======================================================================
-
+
After a card is removed, airo_release() will unregister the
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
-
+
======================================================================*/
static void airo_release(struct pcmcia_device *link)
@@ -475,7 +478,7 @@ static void airo_cs_cleanup(void)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
+ POSSIBILITY OF SUCH DAMAGE.
*/
module_init(airo_cs_init);
diff --git a/drivers/net/wireless/ar9170/Kconfig b/drivers/net/wireless/ar9170/Kconfig
new file mode 100644
index 000000000000..de4281fda129
--- /dev/null
+++ b/drivers/net/wireless/ar9170/Kconfig
@@ -0,0 +1,17 @@
+config AR9170_USB
+ tristate "Atheros AR9170 802.11n USB support"
+ depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
+ select FW_LOADER
+ help
+ This is a driver for the Atheros "otus" 802.11n USB devices.
+
+ These devices require additional firmware (2 files).
+ For now, these files can be downloaded from here:
+ http://wireless.kernel.org/en/users/Drivers/ar9170
+
+ If you choose to build a module, it'll be called ar9170usb.
+
+config AR9170_LEDS
+ bool
+ depends on AR9170_USB && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = AR9170_USB)
+ default y
diff --git a/drivers/net/wireless/ar9170/Makefile b/drivers/net/wireless/ar9170/Makefile
new file mode 100644
index 000000000000..8d91c7ee3215
--- /dev/null
+++ b/drivers/net/wireless/ar9170/Makefile
@@ -0,0 +1,3 @@
+ar9170usb-objs := usb.o main.o cmd.o mac.o phy.o led.o
+
+obj-$(CONFIG_AR9170_USB) += ar9170usb.o
diff --git a/drivers/net/wireless/ar9170/ar9170.h b/drivers/net/wireless/ar9170/ar9170.h
new file mode 100644
index 000000000000..f4fb2e94aea0
--- /dev/null
+++ b/drivers/net/wireless/ar9170/ar9170.h
@@ -0,0 +1,209 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Driver specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef __AR9170_H
+#define __AR9170_H
+
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <net/wireless.h>
+#include <net/mac80211.h>
+#ifdef CONFIG_AR9170_LEDS
+#include <linux/leds.h>
+#endif /* CONFIG_AR9170_LEDS */
+#include "eeprom.h"
+#include "hw.h"
+
+#define PAYLOAD_MAX (AR9170_MAX_CMD_LEN/4 - 1)
+
+enum ar9170_bw {
+ AR9170_BW_20,
+ AR9170_BW_40_BELOW,
+ AR9170_BW_40_ABOVE,
+
+ __AR9170_NUM_BW,
+};
+
+enum ar9170_rf_init_mode {
+ AR9170_RFI_NONE,
+ AR9170_RFI_WARM,
+ AR9170_RFI_COLD,
+};
+
+#define AR9170_MAX_RX_BUFFER_SIZE 8192
+
+#ifdef CONFIG_AR9170_LEDS
+struct ar9170;
+
+struct ar9170_led {
+ struct ar9170 *ar;
+ struct led_classdev l;
+ char name[32];
+ unsigned int toggled;
+ bool registered;
+};
+
+#endif /* CONFIG_AR9170_LEDS */
+
+enum ar9170_device_state {
+ AR9170_UNKNOWN_STATE,
+ AR9170_STOPPED,
+ AR9170_IDLE,
+ AR9170_STARTED,
+ AR9170_ASSOCIATED,
+};
+
+struct ar9170 {
+ struct ieee80211_hw *hw;
+ struct mutex mutex;
+ enum ar9170_device_state state;
+
+ int (*open)(struct ar9170 *);
+ void (*stop)(struct ar9170 *);
+ int (*tx)(struct ar9170 *, struct sk_buff *, bool, unsigned int);
+ int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 ,
+ void *, u32 , void *);
+ void (*callback_cmd)(struct ar9170 *, u32 , void *);
+
+ /* interface mode settings */
+ struct ieee80211_vif *vif;
+ u8 mac_addr[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
+
+ /* beaconing */
+ struct sk_buff *beacon;
+ struct work_struct beacon_work;
+
+ /* cryptographic engine */
+ u64 usedkeys;
+ bool rx_software_decryption;
+ bool disable_offload;
+
+ /* filter settings */
+ struct work_struct filter_config_work;
+ u64 cur_mc_hash, want_mc_hash;
+ u32 cur_filter, want_filter;
+ unsigned int filter_changed;
+ bool sniffer_enabled;
+
+ /* PHY */
+ struct ieee80211_channel *channel;
+ int noise[4];
+
+ /* power calibration data */
+ u8 power_5G_leg[4];
+ u8 power_2G_cck[4];
+ u8 power_2G_ofdm[4];
+ u8 power_5G_ht20[8];
+ u8 power_5G_ht40[8];
+ u8 power_2G_ht20[8];
+ u8 power_2G_ht40[8];
+
+#ifdef CONFIG_AR9170_LEDS
+ struct delayed_work led_work;
+ struct ar9170_led leds[AR9170_NUM_LEDS];
+#endif /* CONFIG_AR9170_LEDS */
+
+ /* qos queue settings */
+ spinlock_t tx_stats_lock;
+ struct ieee80211_tx_queue_stats tx_stats[5];
+ struct ieee80211_tx_queue_params edcf[5];
+
+ spinlock_t cmdlock;
+ __le32 cmdbuf[PAYLOAD_MAX + 1];
+
+ /* MAC statistics */
+ struct ieee80211_low_level_stats stats;
+
+ /* EEPROM */
+ struct ar9170_eeprom eeprom;
+
+ /* global tx status for unregistered Stations. */
+ struct sk_buff_head global_tx_status;
+ struct sk_buff_head global_tx_status_waste;
+ struct delayed_work tx_status_janitor;
+};
+
+struct ar9170_sta_info {
+ struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
+};
+
+#define IS_STARTED(a) (a->state >= AR9170_STARTED)
+#define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE)
+
+#define AR9170_FILTER_CHANGED_PROMISC BIT(0)
+#define AR9170_FILTER_CHANGED_MULTICAST BIT(1)
+#define AR9170_FILTER_CHANGED_FRAMEFILTER BIT(2)
+
+/* exported interface */
+void *ar9170_alloc(size_t priv_size);
+int ar9170_register(struct ar9170 *ar, struct device *pdev);
+void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
+void ar9170_unregister(struct ar9170 *ar);
+void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
+ bool update_statistics, u16 tx_status);
+
+/* MAC */
+int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+int ar9170_init_mac(struct ar9170 *ar);
+int ar9170_set_qos(struct ar9170 *ar);
+int ar9170_update_multicast(struct ar9170 *ar);
+int ar9170_update_frame_filter(struct ar9170 *ar);
+int ar9170_set_operating_mode(struct ar9170 *ar);
+int ar9170_set_beacon_timers(struct ar9170 *ar);
+int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
+int ar9170_update_beacon(struct ar9170 *ar);
+void ar9170_new_beacon(struct work_struct *work);
+int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
+ u8 keyidx, u8 *keydata, int keylen);
+int ar9170_disable_key(struct ar9170 *ar, u8 id);
+
+/* LEDs */
+#ifdef CONFIG_AR9170_LEDS
+int ar9170_register_leds(struct ar9170 *ar);
+void ar9170_unregister_leds(struct ar9170 *ar);
+#endif /* CONFIG_AR9170_LEDS */
+int ar9170_init_leds(struct ar9170 *ar);
+int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state);
+
+/* PHY / RF */
+int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band);
+int ar9170_init_rf(struct ar9170 *ar);
+int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
+ enum ar9170_rf_init_mode rfi, enum ar9170_bw bw);
+
+#endif /* __AR9170_H */
diff --git a/drivers/net/wireless/ar9170/cmd.c b/drivers/net/wireless/ar9170/cmd.c
new file mode 100644
index 000000000000..f57a6200167b
--- /dev/null
+++ b/drivers/net/wireless/ar9170/cmd.c
@@ -0,0 +1,129 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Basic HW register/memory/command access functions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ar9170.h"
+#include "cmd.h"
+
+int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
+{
+ int err;
+
+ if (unlikely(!IS_ACCEPTING_CMD(ar)))
+ return 0;
+
+ err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL);
+ if (err)
+ printk(KERN_DEBUG "%s: writing memory failed\n",
+ wiphy_name(ar->hw->wiphy));
+ return err;
+}
+
+int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
+{
+ __le32 buf[2] = {
+ cpu_to_le32(reg),
+ cpu_to_le32(val),
+ };
+ int err;
+
+ if (unlikely(!IS_ACCEPTING_CMD(ar)))
+ return 0;
+
+ err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf),
+ (u8 *) buf, 0, NULL);
+ if (err)
+ printk(KERN_DEBUG "%s: writing reg %#x (val %#x) failed\n",
+ wiphy_name(ar->hw->wiphy), reg, val);
+ return err;
+}
+
+static int ar9170_read_mreg(struct ar9170 *ar, int nregs,
+ const u32 *regs, u32 *out)
+{
+ int i, err;
+ __le32 *offs, *res;
+
+ if (unlikely(!IS_ACCEPTING_CMD(ar)))
+ return 0;
+
+ /* abuse "out" for the register offsets, must be same length */
+ offs = (__le32 *)out;
+ for (i = 0; i < nregs; i++)
+ offs[i] = cpu_to_le32(regs[i]);
+
+ /* also use the same buffer for the input */
+ res = (__le32 *)out;
+
+ err = ar->exec_cmd(ar, AR9170_CMD_RREG,
+ 4 * nregs, (u8 *)offs,
+ 4 * nregs, (u8 *)res);
+ if (err)
+ return err;
+
+ /* convert result to cpu endian */
+ for (i = 0; i < nregs; i++)
+ out[i] = le32_to_cpu(res[i]);
+
+ return 0;
+}
+
+int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
+{
+ return ar9170_read_mreg(ar, 1, &reg, val);
+}
+
+int ar9170_echo_test(struct ar9170 *ar, u32 v)
+{
+ __le32 echobuf = cpu_to_le32(v);
+ __le32 echores;
+ int err;
+
+ if (unlikely(!IS_ACCEPTING_CMD(ar)))
+ return -ENODEV;
+
+ err = ar->exec_cmd(ar, AR9170_CMD_ECHO,
+ 4, (u8 *)&echobuf,
+ 4, (u8 *)&echores);
+ if (err)
+ return err;
+
+ if (echobuf != echores)
+ return -EINVAL;
+
+ return 0;
+}
diff --git a/drivers/net/wireless/ar9170/cmd.h b/drivers/net/wireless/ar9170/cmd.h
new file mode 100644
index 000000000000..a4f0e50e52b4
--- /dev/null
+++ b/drivers/net/wireless/ar9170/cmd.h
@@ -0,0 +1,91 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Basic HW register/memory/command access functions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef __CMD_H
+#define __CMD_H
+
+#include "ar9170.h"
+
+/* basic HW access */
+int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len);
+int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
+int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val);
+int ar9170_echo_test(struct ar9170 *ar, u32 v);
+
+/*
+ * Macros to facilitate writing multiple registers in a single
+ * write-combining USB command. Note that when the first group
+ * fails the whole thing will fail without any others attempted,
+ * but you won't know which write in the group failed.
+ */
+#define ar9170_regwrite_begin(ar) \
+do { \
+ int __nreg = 0, __err = 0; \
+ struct ar9170 *__ar = ar;
+
+#define ar9170_regwrite(r, v) do { \
+ __ar->cmdbuf[2 * __nreg + 1] = cpu_to_le32(r); \
+ __ar->cmdbuf[2 * __nreg + 2] = cpu_to_le32(v); \
+ __nreg++; \
+ if ((__nreg >= PAYLOAD_MAX/2)) { \
+ if (IS_ACCEPTING_CMD(__ar)) \
+ __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \
+ 8 * __nreg, \
+ (u8 *) &__ar->cmdbuf[1], \
+ 0, NULL); \
+ __nreg = 0; \
+ if (__err) \
+ goto __regwrite_out; \
+ } \
+} while (0)
+
+#define ar9170_regwrite_finish() \
+__regwrite_out : \
+ if (__nreg) { \
+ if (IS_ACCEPTING_CMD(__ar)) \
+ __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \
+ 8 * __nreg, \
+ (u8 *) &__ar->cmdbuf[1], \
+ 0, NULL); \
+ __nreg = 0; \
+ }
+
+#define ar9170_regwrite_result() \
+ __err; \
+} while (0);
+
+#endif /* __CMD_H */
diff --git a/drivers/net/wireless/ar9170/eeprom.h b/drivers/net/wireless/ar9170/eeprom.h
new file mode 100644
index 000000000000..d2c8cc83f1dd
--- /dev/null
+++ b/drivers/net/wireless/ar9170/eeprom.h
@@ -0,0 +1,179 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * EEPROM layout
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef __AR9170_EEPROM_H
+#define __AR9170_EEPROM_H
+
+#define AR5416_MAX_CHAINS 2
+#define AR5416_MODAL_SPURS 5
+
+struct ar9170_eeprom_modal {
+ __le32 antCtrlChain[AR5416_MAX_CHAINS];
+ __le32 antCtrlCommon;
+ s8 antennaGainCh[AR5416_MAX_CHAINS];
+ u8 switchSettling;
+ u8 txRxAttenCh[AR5416_MAX_CHAINS];
+ u8 rxTxMarginCh[AR5416_MAX_CHAINS];
+ s8 adcDesiredSize;
+ s8 pgaDesiredSize;
+ u8 xlnaGainCh[AR5416_MAX_CHAINS];
+ u8 txEndToXpaOff;
+ u8 txEndToRxOn;
+ u8 txFrameToXpaOn;
+ u8 thresh62;
+ s8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
+ u8 xpdGain;
+ u8 xpd;
+ s8 iqCalICh[AR5416_MAX_CHAINS];
+ s8 iqCalQCh[AR5416_MAX_CHAINS];
+ u8 pdGainOverlap;
+ u8 ob;
+ u8 db;
+ u8 xpaBiasLvl;
+ u8 pwrDecreaseFor2Chain;
+ u8 pwrDecreaseFor3Chain;
+ u8 txFrameToDataStart;
+ u8 txFrameToPaOn;
+ u8 ht40PowerIncForPdadc;
+ u8 bswAtten[AR5416_MAX_CHAINS];
+ u8 bswMargin[AR5416_MAX_CHAINS];
+ u8 swSettleHt40;
+ u8 reserved[22];
+ struct spur_channel {
+ __le16 spurChan;
+ u8 spurRangeLow;
+ u8 spurRangeHigh;
+ } __packed spur_channels[AR5416_MODAL_SPURS];
+} __packed;
+
+#define AR5416_NUM_PD_GAINS 4
+#define AR5416_PD_GAIN_ICEPTS 5
+
+struct ar9170_calibration_data_per_freq {
+ u8 pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+ u8 vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+} __packed;
+
+#define AR5416_NUM_5G_CAL_PIERS 8
+#define AR5416_NUM_2G_CAL_PIERS 4
+
+#define AR5416_NUM_5G_TARGET_PWRS 8
+#define AR5416_NUM_2G_CCK_TARGET_PWRS 3
+#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4
+#define AR5416_MAX_NUM_TGT_PWRS 8
+
+struct ar9170_calibration_target_power_legacy {
+ u8 freq;
+ u8 power[4];
+} __packed;
+
+struct ar9170_calibration_target_power_ht {
+ u8 freq;
+ u8 power[8];
+} __packed;
+
+#define AR5416_NUM_CTLS 24
+
+struct ar9170_calctl_edges {
+ u8 channel;
+#define AR9170_CALCTL_EDGE_FLAGS 0xC0
+ u8 power_flags;
+} __packed;
+
+#define AR5416_NUM_BAND_EDGES 8
+
+struct ar9170_calctl_data {
+ struct ar9170_calctl_edges
+ control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+} __packed;
+
+
+struct ar9170_eeprom {
+ __le16 length;
+ __le16 checksum;
+ __le16 version;
+ u8 operating_flags;
+#define AR9170_OPFLAG_5GHZ 1
+#define AR9170_OPFLAG_2GHZ 2
+ u8 misc;
+ __le16 reg_domain[2];
+ u8 mac_address[6];
+ u8 rx_mask;
+ u8 tx_mask;
+ __le16 rf_silent;
+ __le16 bluetooth_options;
+ __le16 device_capabilities;
+ __le32 build_number;
+ u8 deviceType;
+ u8 reserved[33];
+
+ u8 customer_data[64];
+
+ struct ar9170_eeprom_modal
+ modal_header[2];
+
+ u8 cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS];
+ u8 cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS];
+
+ struct ar9170_calibration_data_per_freq
+ cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS],
+ cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
+
+ /* power calibration data */
+ struct ar9170_calibration_target_power_legacy
+ cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS];
+ struct ar9170_calibration_target_power_ht
+ cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS],
+ cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS];
+
+ struct ar9170_calibration_target_power_legacy
+ cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS],
+ cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS];
+ struct ar9170_calibration_target_power_ht
+ cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS],
+ cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS];
+
+ /* conformance testing limits */
+ u8 ctl_index[AR5416_NUM_CTLS];
+ struct ar9170_calctl_data
+ ctl_data[AR5416_NUM_CTLS];
+
+ u8 pad;
+ __le16 subsystem_id;
+} __packed;
+
+#endif /* __AR9170_EEPROM_H */
diff --git a/drivers/net/wireless/ar9170/hw.h b/drivers/net/wireless/ar9170/hw.h
new file mode 100644
index 000000000000..13091bd9d815
--- /dev/null
+++ b/drivers/net/wireless/ar9170/hw.h
@@ -0,0 +1,417 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Hardware-specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef __AR9170_HW_H
+#define __AR9170_HW_H
+
+#define AR9170_MAX_CMD_LEN 64
+
+enum ar9170_cmd {
+ AR9170_CMD_RREG = 0x00,
+ AR9170_CMD_WREG = 0x01,
+ AR9170_CMD_RMEM = 0x02,
+ AR9170_CMD_WMEM = 0x03,
+ AR9170_CMD_BITAND = 0x04,
+ AR9170_CMD_BITOR = 0x05,
+ AR9170_CMD_EKEY = 0x28,
+ AR9170_CMD_DKEY = 0x29,
+ AR9170_CMD_FREQUENCY = 0x30,
+ AR9170_CMD_RF_INIT = 0x31,
+ AR9170_CMD_SYNTH = 0x32,
+ AR9170_CMD_FREQ_START = 0x33,
+ AR9170_CMD_ECHO = 0x80,
+ AR9170_CMD_TALLY = 0x81,
+ AR9170_CMD_TALLY_APD = 0x82,
+ AR9170_CMD_CONFIG = 0x83,
+ AR9170_CMD_RESET = 0x90,
+ AR9170_CMD_DKRESET = 0x91,
+ AR9170_CMD_DKTX_STATUS = 0x92,
+ AR9170_CMD_FDC = 0xA0,
+ AR9170_CMD_WREEPROM = 0xB0,
+ AR9170_CMD_WFLASH = 0xB0,
+ AR9170_CMD_FLASH_ERASE = 0xB1,
+ AR9170_CMD_FLASH_PROG = 0xB2,
+ AR9170_CMD_FLASH_CHKSUM = 0xB3,
+ AR9170_CMD_FLASH_READ = 0xB4,
+ AR9170_CMD_FW_DL_INIT = 0xB5,
+ AR9170_CMD_MEM_WREEPROM = 0xBB,
+};
+
+/* endpoints */
+#define AR9170_EP_TX 1
+#define AR9170_EP_RX 2
+#define AR9170_EP_IRQ 3
+#define AR9170_EP_CMD 4
+
+#define AR9170_EEPROM_START 0x1600
+
+#define AR9170_GPIO_REG_BASE 0x1d0100
+#define AR9170_GPIO_REG_PORT_TYPE AR9170_GPIO_REG_BASE
+#define AR9170_GPIO_REG_DATA (AR9170_GPIO_REG_BASE + 4)
+#define AR9170_NUM_LEDS 2
+
+
+#define AR9170_USB_REG_BASE 0x1e1000
+#define AR9170_USB_REG_DMA_CTL (AR9170_USB_REG_BASE + 0x108)
+#define AR9170_DMA_CTL_ENABLE_TO_DEVICE 0x1
+#define AR9170_DMA_CTL_ENABLE_FROM_DEVICE 0x2
+#define AR9170_DMA_CTL_HIGH_SPEED 0x4
+#define AR9170_DMA_CTL_PACKET_MODE 0x8
+
+#define AR9170_USB_REG_MAX_AGG_UPLOAD (AR9170_USB_REG_BASE + 0x110)
+#define AR9170_USB_REG_UPLOAD_TIME_CTL (AR9170_USB_REG_BASE + 0x114)
+
+
+
+#define AR9170_MAC_REG_BASE 0x1c3000
+
+#define AR9170_MAC_REG_TSF_L (AR9170_MAC_REG_BASE + 0x514)
+#define AR9170_MAC_REG_TSF_H (AR9170_MAC_REG_BASE + 0x518)
+
+#define AR9170_MAC_REG_ATIM_WINDOW (AR9170_MAC_REG_BASE + 0x51C)
+#define AR9170_MAC_REG_BCN_PERIOD (AR9170_MAC_REG_BASE + 0x520)
+#define AR9170_MAC_REG_PRETBTT (AR9170_MAC_REG_BASE + 0x524)
+
+#define AR9170_MAC_REG_MAC_ADDR_L (AR9170_MAC_REG_BASE + 0x610)
+#define AR9170_MAC_REG_MAC_ADDR_H (AR9170_MAC_REG_BASE + 0x614)
+#define AR9170_MAC_REG_BSSID_L (AR9170_MAC_REG_BASE + 0x618)
+#define AR9170_MAC_REG_BSSID_H (AR9170_MAC_REG_BASE + 0x61c)
+
+#define AR9170_MAC_REG_GROUP_HASH_TBL_L (AR9170_MAC_REG_BASE + 0x624)
+#define AR9170_MAC_REG_GROUP_HASH_TBL_H (AR9170_MAC_REG_BASE + 0x628)
+
+#define AR9170_MAC_REG_RX_TIMEOUT (AR9170_MAC_REG_BASE + 0x62C)
+
+#define AR9170_MAC_REG_BASIC_RATE (AR9170_MAC_REG_BASE + 0x630)
+#define AR9170_MAC_REG_MANDATORY_RATE (AR9170_MAC_REG_BASE + 0x634)
+#define AR9170_MAC_REG_RTS_CTS_RATE (AR9170_MAC_REG_BASE + 0x638)
+#define AR9170_MAC_REG_BACKOFF_PROTECT (AR9170_MAC_REG_BASE + 0x63c)
+#define AR9170_MAC_REG_RX_THRESHOLD (AR9170_MAC_REG_BASE + 0x640)
+#define AR9170_MAC_REG_RX_PE_DELAY (AR9170_MAC_REG_BASE + 0x64C)
+
+#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK (AR9170_MAC_REG_BASE + 0x658)
+#define AR9170_MAC_REG_SNIFFER (AR9170_MAC_REG_BASE + 0x674)
+#define AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC BIT(0)
+#define AR9170_MAC_REG_SNIFFER_DEFAULTS 0x02000000
+#define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678)
+#define AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE BIT(3)
+#define AR9170_MAC_REG_ENCRYPTION_DEFAULTS 0x70
+
+#define AR9170_MAC_REG_MISC_680 (AR9170_MAC_REG_BASE + 0x680)
+#define AR9170_MAC_REG_TX_UNDERRUN (AR9170_MAC_REG_BASE + 0x688)
+
+#define AR9170_MAC_REG_FRAMETYPE_FILTER (AR9170_MAC_REG_BASE + 0x68c)
+#define AR9170_MAC_REG_FTF_ASSOC_REQ BIT(0)
+#define AR9170_MAC_REG_FTF_ASSOC_RESP BIT(1)
+#define AR9170_MAC_REG_FTF_REASSOC_REQ BIT(2)
+#define AR9170_MAC_REG_FTF_REASSOC_RESP BIT(3)
+#define AR9170_MAC_REG_FTF_PRB_REQ BIT(4)
+#define AR9170_MAC_REG_FTF_PRB_RESP BIT(5)
+#define AR9170_MAC_REG_FTF_BIT6 BIT(6)
+#define AR9170_MAC_REG_FTF_BIT7 BIT(7)
+#define AR9170_MAC_REG_FTF_BEACON BIT(8)
+#define AR9170_MAC_REG_FTF_ATIM BIT(9)
+#define AR9170_MAC_REG_FTF_DEASSOC BIT(10)
+#define AR9170_MAC_REG_FTF_AUTH BIT(11)
+#define AR9170_MAC_REG_FTF_DEAUTH BIT(12)
+#define AR9170_MAC_REG_FTF_BIT13 BIT(13)
+#define AR9170_MAC_REG_FTF_BIT14 BIT(14)
+#define AR9170_MAC_REG_FTF_BIT15 BIT(15)
+#define AR9170_MAC_REG_FTF_BAR BIT(24)
+#define AR9170_MAC_REG_FTF_BIT25 BIT(25)
+#define AR9170_MAC_REG_FTF_PSPOLL BIT(26)
+#define AR9170_MAC_REG_FTF_RTS BIT(27)
+#define AR9170_MAC_REG_FTF_CTS BIT(28)
+#define AR9170_MAC_REG_FTF_ACK BIT(29)
+#define AR9170_MAC_REG_FTF_CFE BIT(30)
+#define AR9170_MAC_REG_FTF_CFE_ACK BIT(31)
+#define AR9170_MAC_REG_FTF_DEFAULTS 0x0500ffff
+#define AR9170_MAC_REG_FTF_MONITOR 0xfd00ffff
+
+#define AR9170_MAC_REG_RX_TOTAL (AR9170_MAC_REG_BASE + 0x6A0)
+#define AR9170_MAC_REG_RX_CRC32 (AR9170_MAC_REG_BASE + 0x6A4)
+#define AR9170_MAC_REG_RX_CRC16 (AR9170_MAC_REG_BASE + 0x6A8)
+#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI (AR9170_MAC_REG_BASE + 0x6AC)
+#define AR9170_MAC_REG_RX_OVERRUN (AR9170_MAC_REG_BASE + 0x6B0)
+#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL (AR9170_MAC_REG_BASE + 0x6BC)
+#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6CC)
+#define AR9170_MAC_REG_TX_TOTAL (AR9170_MAC_REG_BASE + 0x6F4)
+
+
+#define AR9170_MAC_REG_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0x690)
+#define AR9170_MAC_REG_EIFS_AND_SIFS (AR9170_MAC_REG_BASE + 0x698)
+
+#define AR9170_MAC_REG_SLOT_TIME (AR9170_MAC_REG_BASE + 0x6F0)
+
+#define AR9170_MAC_REG_POWERMANAGEMENT (AR9170_MAC_REG_BASE + 0x700)
+#define AR9170_MAC_REG_POWERMGT_IBSS 0xe0
+#define AR9170_MAC_REG_POWERMGT_AP 0xa1
+#define AR9170_MAC_REG_POWERMGT_STA 0x2
+#define AR9170_MAC_REG_POWERMGT_AP_WDS 0x3
+#define AR9170_MAC_REG_POWERMGT_DEFAULTS (0xf << 24)
+
+#define AR9170_MAC_REG_ROLL_CALL_TBL_L (AR9170_MAC_REG_BASE + 0x704)
+#define AR9170_MAC_REG_ROLL_CALL_TBL_H (AR9170_MAC_REG_BASE + 0x708)
+
+#define AR9170_MAC_REG_AC0_CW (AR9170_MAC_REG_BASE + 0xB00)
+#define AR9170_MAC_REG_AC1_CW (AR9170_MAC_REG_BASE + 0xB04)
+#define AR9170_MAC_REG_AC2_CW (AR9170_MAC_REG_BASE + 0xB08)
+#define AR9170_MAC_REG_AC3_CW (AR9170_MAC_REG_BASE + 0xB0C)
+#define AR9170_MAC_REG_AC4_CW (AR9170_MAC_REG_BASE + 0xB10)
+#define AR9170_MAC_REG_AC1_AC0_AIFS (AR9170_MAC_REG_BASE + 0xB14)
+#define AR9170_MAC_REG_AC3_AC2_AIFS (AR9170_MAC_REG_BASE + 0xB18)
+
+#define AR9170_MAC_REG_RETRY_MAX (AR9170_MAC_REG_BASE + 0xB28)
+
+#define AR9170_MAC_REG_FCS_SELECT (AR9170_MAC_REG_BASE + 0xBB0)
+#define AR9170_MAC_FCS_SWFCS 0x1
+#define AR9170_MAC_FCS_FIFO_PROT 0x4
+
+
+#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND (AR9170_MAC_REG_BASE + 0xB30)
+
+#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44)
+#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48)
+
+#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00)
+#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50)
+
+#define AR9170_MAC_REG_TXRX_MPI (AR9170_MAC_REG_BASE + 0xD7C)
+#define AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f
+#define AR9170_MAC_TXRX_MPI_TX_TO_MASK 0x0000fff0
+#define AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000
+#define AR9170_MAC_TXRX_MPI_RX_TO_MASK 0xfff00000
+
+#define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xD84)
+#define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xD88)
+#define AR9170_MAC_REG_BCN_PLCP (AR9170_MAC_REG_BASE + 0xD90)
+#define AR9170_MAC_REG_BCN_CTRL (AR9170_MAC_REG_BASE + 0xD94)
+#define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xDA0)
+#define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xDA4)
+
+
+#define AR9170_PWR_REG_BASE 0x1D4000
+
+#define AR9170_PWR_REG_CLOCK_SEL (AR9170_PWR_REG_BASE + 0x008)
+#define AR9170_PWR_CLK_AHB_40MHZ 0
+#define AR9170_PWR_CLK_AHB_20_22MHZ 1
+#define AR9170_PWR_CLK_AHB_40_44MHZ 2
+#define AR9170_PWR_CLK_AHB_80_88MHZ 3
+#define AR9170_PWR_CLK_DAC_160_INV_DLY 0x70
+
+
+/* put beacon here in memory */
+#define AR9170_BEACON_BUFFER_ADDRESS 0x117900
+
+
+struct ar9170_tx_control {
+ __le16 length;
+ __le16 mac_control;
+ __le32 phy_control;
+ u8 frame_data[0];
+} __packed;
+
+/* these are either-or */
+#define AR9170_TX_MAC_PROT_RTS 0x0001
+#define AR9170_TX_MAC_PROT_CTS 0x0002
+
+#define AR9170_TX_MAC_NO_ACK 0x0004
+/* if unset, MAC will only do SIFS space before frame */
+#define AR9170_TX_MAC_BACKOFF 0x0008
+#define AR9170_TX_MAC_BURST 0x0010
+#define AR9170_TX_MAC_AGGR 0x0020
+
+/* encryption is a two-bit field */
+#define AR9170_TX_MAC_ENCR_NONE 0x0000
+#define AR9170_TX_MAC_ENCR_RC4 0x0040
+#define AR9170_TX_MAC_ENCR_CENC 0x0080
+#define AR9170_TX_MAC_ENCR_AES 0x00c0
+
+#define AR9170_TX_MAC_MMIC 0x0100
+#define AR9170_TX_MAC_HW_DURATION 0x0200
+#define AR9170_TX_MAC_QOS_SHIFT 10
+#define AR9170_TX_MAC_QOS_MASK (3 << AR9170_TX_MAC_QOS_SHIFT)
+#define AR9170_TX_MAC_AGGR_QOS_BIT1 0x0400
+#define AR9170_TX_MAC_AGGR_QOS_BIT2 0x0800
+#define AR9170_TX_MAC_DISABLE_TXOP 0x1000
+#define AR9170_TX_MAC_TXOP_RIFS 0x2000
+#define AR9170_TX_MAC_IMM_AMPDU 0x4000
+#define AR9170_TX_MAC_RATE_PROBE 0x8000
+
+/* either-or */
+#define AR9170_TX_PHY_MOD_CCK 0x00000000
+#define AR9170_TX_PHY_MOD_OFDM 0x00000001
+#define AR9170_TX_PHY_MOD_HT 0x00000002
+
+/* depends on modulation */
+#define AR9170_TX_PHY_SHORT_PREAMBLE 0x00000004
+#define AR9170_TX_PHY_GREENFIELD 0x00000004
+
+#define AR9170_TX_PHY_BW_SHIFT 3
+#define AR9170_TX_PHY_BW_MASK (3 << AR9170_TX_PHY_BW_SHIFT)
+#define AR9170_TX_PHY_BW_20MHZ 0
+#define AR9170_TX_PHY_BW_40MHZ 2
+#define AR9170_TX_PHY_BW_40MHZ_DUP 3
+
+#define AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT 6
+#define AR9170_TX_PHY_TX_HEAVY_CLIP_MASK (7 << AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT)
+
+#define AR9170_TX_PHY_TX_PWR_SHIFT 9
+#define AR9170_TX_PHY_TX_PWR_MASK (0x3f << AR9170_TX_PHY_TX_PWR_SHIFT)
+
+/* not part of the hw-spec */
+#define AR9170_TX_PHY_QOS_SHIFT 25
+#define AR9170_TX_PHY_QOS_MASK (3 << AR9170_TX_PHY_QOS_SHIFT)
+
+#define AR9170_TX_PHY_TXCHAIN_SHIFT 15
+#define AR9170_TX_PHY_TXCHAIN_MASK (7 << AR9170_TX_PHY_TXCHAIN_SHIFT)
+#define AR9170_TX_PHY_TXCHAIN_1 1
+/* use for cck, ofdm 6/9/12/18/24 and HT if capable */
+#define AR9170_TX_PHY_TXCHAIN_2 5
+
+#define AR9170_TX_PHY_MCS_SHIFT 18
+#define AR9170_TX_PHY_MCS_MASK (0x7f << AR9170_TX_PHY_MCS_SHIFT)
+
+#define AR9170_TX_PHY_SHORT_GI 0x80000000
+
+struct ar9170_rx_head {
+ u8 plcp[12];
+};
+
+struct ar9170_rx_tail {
+ union {
+ struct {
+ u8 rssi_ant0, rssi_ant1, rssi_ant2,
+ rssi_ant0x, rssi_ant1x, rssi_ant2x,
+ rssi_combined;
+ };
+ u8 rssi[7];
+ };
+
+ u8 evm_stream0[6], evm_stream1[6];
+ u8 phy_err;
+ u8 SAidx, DAidx;
+ u8 error;
+ u8 status;
+};
+
+#define AR9170_ENC_ALG_NONE 0x0
+#define AR9170_ENC_ALG_WEP64 0x1
+#define AR9170_ENC_ALG_TKIP 0x2
+#define AR9170_ENC_ALG_AESCCMP 0x4
+#define AR9170_ENC_ALG_WEP128 0x5
+#define AR9170_ENC_ALG_WEP256 0x6
+#define AR9170_ENC_ALG_CENC 0x7
+
+#define AR9170_RX_ENC_SOFTWARE 0x8
+
+static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t)
+{
+ return (t->SAidx & 0xc0) >> 4 |
+ (t->DAidx & 0xc0) >> 6;
+}
+
+#define AR9170_RX_STATUS_MODULATION_MASK 0x03
+#define AR9170_RX_STATUS_MODULATION_CCK 0x00
+#define AR9170_RX_STATUS_MODULATION_OFDM 0x01
+#define AR9170_RX_STATUS_MODULATION_HT 0x02
+#define AR9170_RX_STATUS_MODULATION_DUPOFDM 0x03
+
+/* depends on modulation */
+#define AR9170_RX_STATUS_SHORT_PREAMBLE 0x08
+#define AR9170_RX_STATUS_GREENFIELD 0x08
+
+#define AR9170_RX_STATUS_MPDU_MASK 0x30
+#define AR9170_RX_STATUS_MPDU_SINGLE 0x00
+#define AR9170_RX_STATUS_MPDU_FIRST 0x10
+#define AR9170_RX_STATUS_MPDU_MIDDLE 0x20
+#define AR9170_RX_STATUS_MPDU_LAST 0x30
+
+
+#define AR9170_RX_ERROR_RXTO 0x01
+#define AR9170_RX_ERROR_OVERRUN 0x02
+#define AR9170_RX_ERROR_DECRYPT 0x04
+#define AR9170_RX_ERROR_FCS 0x08
+#define AR9170_RX_ERROR_WRONG_RA 0x10
+#define AR9170_RX_ERROR_PLCP 0x20
+#define AR9170_RX_ERROR_MMIC 0x40
+
+struct ar9170_cmd_tx_status {
+ __le16 unkn;
+ u8 dst[ETH_ALEN];
+ __le32 rate;
+ __le16 status;
+} __packed;
+
+#define AR9170_TX_STATUS_COMPLETE 0x00
+#define AR9170_TX_STATUS_RETRY 0x01
+#define AR9170_TX_STATUS_FAILED 0x02
+
+struct ar9170_cmd_ba_failed_count {
+ __le16 failed;
+ __le16 rate;
+} __packed;
+
+struct ar9170_cmd_response {
+ u8 flag;
+ u8 type;
+
+ union {
+ struct ar9170_cmd_tx_status tx_status;
+ struct ar9170_cmd_ba_failed_count ba_fail_cnt;
+ u8 data[0];
+ };
+} __packed;
+
+/* QoS */
+
+/* mac80211 queue to HW/FW map */
+static const u8 ar9170_qos_hwmap[4] = { 3, 2, 0, 1 };
+
+/* HW/FW queue to mac80211 map */
+static const u8 ar9170_qos_mac80211map[4] = { 2, 3, 1, 0 };
+
+enum ar9170_txq {
+ AR9170_TXQ_BE,
+ AR9170_TXQ_BK,
+ AR9170_TXQ_VI,
+ AR9170_TXQ_VO,
+
+ __AR9170_NUM_TXQ,
+};
+
+#endif /* __AR9170_HW_H */
diff --git a/drivers/net/wireless/ar9170/led.c b/drivers/net/wireless/ar9170/led.c
new file mode 100644
index 000000000000..341cead7f606
--- /dev/null
+++ b/drivers/net/wireless/ar9170/led.c
@@ -0,0 +1,171 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * LED handling
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ar9170.h"
+#include "cmd.h"
+
+int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state)
+{
+ return ar9170_write_reg(ar, AR9170_GPIO_REG_DATA, led_state);
+}
+
+int ar9170_init_leds(struct ar9170 *ar)
+{
+ int err;
+
+ /* disable LEDs */
+ /* GPIO [0/1 mode: output, 2/3: input] */
+ err = ar9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3);
+ if (err)
+ goto out;
+
+ /* GPIO 0/1 value: off */
+ err = ar9170_set_leds_state(ar, 0);
+
+out:
+ return err;
+}
+
+#ifdef CONFIG_AR9170_LEDS
+static void ar9170_update_leds(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170, led_work.work);
+ int i, tmp, blink_delay = 1000;
+ u32 led_val = 0;
+ bool rerun = false;
+
+ if (unlikely(!IS_ACCEPTING_CMD(ar)))
+ return ;
+
+ mutex_lock(&ar->mutex);
+ for (i = 0; i < AR9170_NUM_LEDS; i++)
+ if (ar->leds[i].toggled) {
+ led_val |= 1 << i;
+
+ tmp = 70 + 200 / (ar->leds[i].toggled);
+ if (tmp < blink_delay)
+ blink_delay = tmp;
+
+ if (ar->leds[i].toggled > 1)
+ ar->leds[i].toggled = 0;
+
+ rerun = true;
+ }
+
+ ar9170_set_leds_state(ar, led_val);
+ mutex_unlock(&ar->mutex);
+
+ if (rerun)
+ queue_delayed_work(ar->hw->workqueue, &ar->led_work,
+ msecs_to_jiffies(blink_delay));
+}
+
+static void ar9170_led_brightness_set(struct led_classdev *led,
+ enum led_brightness brightness)
+{
+ struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
+ struct ar9170 *ar = arl->ar;
+
+ arl->toggled++;
+
+ if (likely(IS_ACCEPTING_CMD(ar) && brightness))
+ queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10);
+}
+
+static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
+ char *trigger)
+{
+ int err;
+
+ snprintf(ar->leds[i].name, sizeof(ar->leds[i].name),
+ "ar9170-%s::%s", wiphy_name(ar->hw->wiphy), name);
+
+ ar->leds[i].ar = ar;
+ ar->leds[i].l.name = ar->leds[i].name;
+ ar->leds[i].l.brightness_set = ar9170_led_brightness_set;
+ ar->leds[i].l.brightness = 0;
+ ar->leds[i].l.default_trigger = trigger;
+
+ err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
+ &ar->leds[i].l);
+ if (err)
+ printk(KERN_ERR "%s: failed to register %s LED (%d).\n",
+ wiphy_name(ar->hw->wiphy), ar->leds[i].name, err);
+ else
+ ar->leds[i].registered = true;
+
+ return err;
+}
+
+void ar9170_unregister_leds(struct ar9170 *ar)
+{
+ int i;
+
+ cancel_delayed_work_sync(&ar->led_work);
+
+ for (i = 0; i < AR9170_NUM_LEDS; i++)
+ if (ar->leds[i].registered) {
+ led_classdev_unregister(&ar->leds[i].l);
+ ar->leds[i].registered = false;
+ }
+}
+
+int ar9170_register_leds(struct ar9170 *ar)
+{
+ int err;
+
+ INIT_DELAYED_WORK(&ar->led_work, ar9170_update_leds);
+
+ err = ar9170_register_led(ar, 0, "tx",
+ ieee80211_get_tx_led_name(ar->hw));
+ if (err)
+ goto fail;
+
+ err = ar9170_register_led(ar, 1, "assoc",
+ ieee80211_get_assoc_led_name(ar->hw));
+ if (err)
+ goto fail;
+
+ return 0;
+
+fail:
+ ar9170_unregister_leds(ar);
+ return err;
+}
+
+#endif /* CONFIG_AR9170_LEDS */
diff --git a/drivers/net/wireless/ar9170/mac.c b/drivers/net/wireless/ar9170/mac.c
new file mode 100644
index 000000000000..c8fa3073169f
--- /dev/null
+++ b/drivers/net/wireless/ar9170/mac.c
@@ -0,0 +1,452 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * MAC programming
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "ar9170.h"
+#include "cmd.h"
+
+int ar9170_set_qos(struct ar9170 *ar)
+{
+ ar9170_regwrite_begin(ar);
+
+ ar9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
+ (ar->edcf[0].cw_max << 16));
+ ar9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
+ (ar->edcf[1].cw_max << 16));
+ ar9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
+ (ar->edcf[2].cw_max << 16));
+ ar9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
+ (ar->edcf[3].cw_max << 16));
+ ar9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
+ (ar->edcf[4].cw_max << 16));
+
+ ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_AIFS,
+ ((ar->edcf[0].aifs * 9 + 10)) |
+ ((ar->edcf[1].aifs * 9 + 10) << 12) |
+ ((ar->edcf[2].aifs * 9 + 10) << 24));
+ ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_AIFS,
+ ((ar->edcf[2].aifs * 9 + 10) >> 8) |
+ ((ar->edcf[3].aifs * 9 + 10) << 4) |
+ ((ar->edcf[4].aifs * 9 + 10) << 16));
+
+ ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
+ ar->edcf[0].txop | ar->edcf[1].txop << 16);
+ ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
+ ar->edcf[1].txop | ar->edcf[3].txop << 16);
+
+ ar9170_regwrite_finish();
+
+ return ar9170_regwrite_result();
+}
+
+int ar9170_init_mac(struct ar9170 *ar)
+{
+ ar9170_regwrite_begin(ar);
+
+ ar9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
+
+ ar9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0);
+
+ /* enable MMIC */
+ ar9170_regwrite(AR9170_MAC_REG_SNIFFER,
+ AR9170_MAC_REG_SNIFFER_DEFAULTS);
+
+ ar9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
+
+ ar9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
+ ar9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
+ ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
+
+ /* CF-END mode */
+ ar9170_regwrite(0x1c3b2c, 0x19000000);
+
+ /* NAV protects ACK only (in TXOP) */
+ ar9170_regwrite(0x1c3b38, 0x201);
+
+ /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
+ /* OTUS set AM to 0x1 */
+ ar9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
+
+ ar9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
+
+ /* AGG test code*/
+ /* Aggregation MAX number and timeout */
+ ar9170_regwrite(0x1c3b9c, 0x10000a);
+
+ ar9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
+ AR9170_MAC_REG_FTF_DEFAULTS);
+
+ /* Enable deaggregator, response in sniffer mode */
+ ar9170_regwrite(0x1c3c40, 0x1 | 1<<30);
+
+ /* rate sets */
+ ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
+ ar9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
+ ar9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
+
+ /* MIMO response control */
+ ar9170_regwrite(0x1c3694, 0x4003C1E);/* bit 26~28 otus-AM */
+
+ /* switch MAC to OTUS interface */
+ ar9170_regwrite(0x1c3600, 0x3);
+
+ ar9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
+
+ /* set PHY register read timeout (??) */
+ ar9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
+
+ /* Disable Rx TimeOut, workaround for BB. */
+ ar9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
+
+ /* Set CPU clock frequency to 88/80MHz */
+ ar9170_regwrite(AR9170_PWR_REG_CLOCK_SEL,
+ AR9170_PWR_CLK_AHB_80_88MHZ |
+ AR9170_PWR_CLK_DAC_160_INV_DLY);
+
+ /* Set WLAN DMA interrupt mode: generate int per packet */
+ ar9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
+
+ ar9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
+ AR9170_MAC_FCS_FIFO_PROT);
+
+ /* Disables the CF_END frame, undocumented register */
+ ar9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
+ 0x141E0F48);
+
+ ar9170_regwrite_finish();
+
+ return ar9170_regwrite_result();
+}
+
+static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
+{
+ static const u8 zero[ETH_ALEN] = { 0 };
+
+ if (!mac)
+ mac = zero;
+
+ ar9170_regwrite_begin(ar);
+
+ ar9170_regwrite(reg,
+ (mac[3] << 24) | (mac[2] << 16) |
+ (mac[1] << 8) | mac[0]);
+
+ ar9170_regwrite(reg + 4, (mac[5] << 8) | mac[4]);
+
+ ar9170_regwrite_finish();
+
+ return ar9170_regwrite_result();
+}
+
+int ar9170_update_multicast(struct ar9170 *ar)
+{
+ int err;
+
+ ar9170_regwrite_begin(ar);
+ ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H,
+ ar->want_mc_hash >> 32);
+ ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L,
+ ar->want_mc_hash);
+
+ ar9170_regwrite_finish();
+ err = ar9170_regwrite_result();
+
+ if (err)
+ return err;
+
+ ar->cur_mc_hash = ar->want_mc_hash;
+
+ return 0;
+}
+
+int ar9170_update_frame_filter(struct ar9170 *ar)
+{
+ int err;
+
+ err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER,
+ ar->want_filter);
+
+ if (err)
+ return err;
+
+ ar->cur_filter = ar->want_filter;
+
+ return 0;
+}
+
+static int ar9170_set_promiscouous(struct ar9170 *ar)
+{
+ u32 encr_mode, sniffer;
+ int err;
+
+ err = ar9170_read_reg(ar, AR9170_MAC_REG_SNIFFER, &sniffer);
+ if (err)
+ return err;
+
+ err = ar9170_read_reg(ar, AR9170_MAC_REG_ENCRYPTION, &encr_mode);
+ if (err)
+ return err;
+
+ if (ar->sniffer_enabled) {
+ sniffer |= AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
+
+ /*
+ * Rx decryption works in place.
+ *
+ * If we don't disable it, the hardware will render all
+ * encrypted frames which are encrypted with an unknown
+ * key useless.
+ */
+
+ encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
+ ar->sniffer_enabled = true;
+ } else {
+ sniffer &= ~AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
+
+ if (ar->rx_software_decryption)
+ encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
+ else
+ encr_mode &= ~AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
+ }
+
+ ar9170_regwrite_begin(ar);
+ ar9170_regwrite(AR9170_MAC_REG_ENCRYPTION, encr_mode);
+ ar9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
+ ar9170_regwrite_finish();
+
+ return ar9170_regwrite_result();
+}
+
+int ar9170_set_operating_mode(struct ar9170 *ar)
+{
+ u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS;
+ u8 *mac_addr, *bssid;
+ int err;
+
+ if (ar->vif) {
+ mac_addr = ar->mac_addr;
+ bssid = ar->bssid;
+
+ switch (ar->vif->type) {
+ case NL80211_IFTYPE_MESH_POINT:
+ case NL80211_IFTYPE_ADHOC:
+ pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS;
+ break;
+/* case NL80211_IFTYPE_AP:
+ pm_mode |= AR9170_MAC_REG_POWERMGT_AP;
+ break;*/
+ case NL80211_IFTYPE_WDS:
+ pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS;
+ break;
+ case NL80211_IFTYPE_MONITOR:
+ ar->sniffer_enabled = true;
+ ar->rx_software_decryption = true;
+ break;
+ default:
+ pm_mode |= AR9170_MAC_REG_POWERMGT_STA;
+ break;
+ }
+ } else {
+ mac_addr = NULL;
+ bssid = NULL;
+ }
+
+ err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
+ if (err)
+ return err;
+
+ err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
+ if (err)
+ return err;
+
+ err = ar9170_set_promiscouous(ar);
+ if (err)
+ return err;
+
+ ar9170_regwrite_begin(ar);
+
+ ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode);
+ ar9170_regwrite_finish();
+
+ return ar9170_regwrite_result();
+}
+
+int ar9170_set_hwretry_limit(struct ar9170 *ar, unsigned int max_retry)
+{
+ u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
+
+ return ar9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
+}
+
+int ar9170_set_beacon_timers(struct ar9170 *ar)
+{
+ u32 v = 0;
+ u32 pretbtt = 0;
+
+ v |= ar->hw->conf.beacon_int;
+
+ if (ar->vif) {
+ switch (ar->vif->type) {
+ case NL80211_IFTYPE_MESH_POINT:
+ case NL80211_IFTYPE_ADHOC:
+ v |= BIT(25);
+ break;
+ case NL80211_IFTYPE_AP:
+ v |= BIT(24);
+ pretbtt = (ar->hw->conf.beacon_int - 6) << 16;
+ break;
+ default:
+ break;
+ }
+
+ v |= ar->vif->bss_conf.dtim_period << 16;
+ }
+
+ ar9170_regwrite_begin(ar);
+
+ ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
+ ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
+ ar9170_regwrite_finish();
+ return ar9170_regwrite_result();
+}
+
+int ar9170_update_beacon(struct ar9170 *ar)
+{
+ struct sk_buff *skb;
+ __le32 *data, *old = NULL;
+ u32 word;
+ int i;
+
+ skb = ieee80211_beacon_get(ar->hw, ar->vif);
+ if (!skb)
+ return -ENOMEM;
+
+ data = (__le32 *)skb->data;
+ if (ar->beacon)
+ old = (__le32 *)ar->beacon->data;
+
+ ar9170_regwrite_begin(ar);
+ for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
+ /*
+ * XXX: This accesses beyond skb data for up
+ * to the last 3 bytes!!
+ */
+
+ if (old && (data[i] == old[i]))
+ continue;
+
+ word = le32_to_cpu(data[i]);
+ ar9170_regwrite(AR9170_BEACON_BUFFER_ADDRESS + 4 * i, word);
+ }
+
+ /* XXX: use skb->cb info */
+ if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+ ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
+ ((skb->len + 4) << (3+16)) + 0x0400);
+ else
+ ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
+ ((skb->len + 4) << (3+16)) + 0x0400);
+
+ ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
+ ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
+ ar9170_regwrite(AR9170_MAC_REG_BCN_CTRL, 1);
+
+ ar9170_regwrite_finish();
+
+ dev_kfree_skb(ar->beacon);
+ ar->beacon = skb;
+
+ return ar9170_regwrite_result();
+}
+
+void ar9170_new_beacon(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170,
+ beacon_work);
+ struct sk_buff *skb;
+
+ if (unlikely(!IS_STARTED(ar)))
+ return ;
+
+ mutex_lock(&ar->mutex);
+
+ if (!ar->vif)
+ goto out;
+
+ ar9170_update_beacon(ar);
+
+ rcu_read_lock();
+ while ((skb = ieee80211_get_buffered_bc(ar->hw, ar->vif)))
+ ar9170_op_tx(ar->hw, skb);
+
+ rcu_read_unlock();
+
+ out:
+ mutex_unlock(&ar->mutex);
+}
+
+int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
+ u8 keyidx, u8 *keydata, int keylen)
+{
+ __le32 vals[7];
+ static const u8 bcast[ETH_ALEN] =
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ u8 dummy;
+
+ mac = mac ? : bcast;
+
+ vals[0] = cpu_to_le32((keyidx << 16) + id);
+ vals[1] = cpu_to_le32(mac[1] << 24 | mac[0] << 16 | ktype);
+ vals[2] = cpu_to_le32(mac[5] << 24 | mac[4] << 16 |
+ mac[3] << 8 | mac[2]);
+ memset(&vals[3], 0, 16);
+ if (keydata)
+ memcpy(&vals[3], keydata, keylen);
+
+ return ar->exec_cmd(ar, AR9170_CMD_EKEY,
+ sizeof(vals), (u8 *)vals,
+ 1, &dummy);
+}
+
+int ar9170_disable_key(struct ar9170 *ar, u8 id)
+{
+ __le32 val = cpu_to_le32(id);
+ u8 dummy;
+
+ return ar->exec_cmd(ar, AR9170_CMD_EKEY,
+ sizeof(val), (u8 *)&val,
+ 1, &dummy);
+}
diff --git a/drivers/net/wireless/ar9170/main.c b/drivers/net/wireless/ar9170/main.c
new file mode 100644
index 000000000000..5996ff9f7f47
--- /dev/null
+++ b/drivers/net/wireless/ar9170/main.c
@@ -0,0 +1,1671 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * mac80211 interaction code
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, Christian Lamparter <chunkeey@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include "ar9170.h"
+#include "hw.h"
+#include "cmd.h"
+
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+
+#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \
+ .bitrate = (_bitrate), \
+ .flags = (_flags), \
+ .hw_value = (_hw_rate) | (_txpidx) << 4, \
+}
+
+static struct ieee80211_rate __ar9170_ratetable[] = {
+ RATE(10, 0, 0, 0),
+ RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
+ RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
+ RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
+ RATE(60, 0xb, 0, 0),
+ RATE(90, 0xf, 0, 0),
+ RATE(120, 0xa, 0, 0),
+ RATE(180, 0xe, 0, 0),
+ RATE(240, 0x9, 0, 0),
+ RATE(360, 0xd, 1, 0),
+ RATE(480, 0x8, 2, 0),
+ RATE(540, 0xc, 3, 0),
+};
+#undef RATE
+
+#define ar9170_g_ratetable (__ar9170_ratetable + 0)
+#define ar9170_g_ratetable_size 12
+#define ar9170_a_ratetable (__ar9170_ratetable + 4)
+#define ar9170_a_ratetable_size 8
+
+/*
+ * NB: The hw_value is used as an index into the ar9170_phy_freq_params
+ * array in phy.c so that we don't have to do frequency lookups!
+ */
+#define CHAN(_freq, _idx) { \
+ .center_freq = (_freq), \
+ .hw_value = (_idx), \
+ .max_power = 18, /* XXX */ \
+}
+
+static struct ieee80211_channel ar9170_2ghz_chantable[] = {
+ CHAN(2412, 0),
+ CHAN(2417, 1),
+ CHAN(2422, 2),
+ CHAN(2427, 3),
+ CHAN(2432, 4),
+ CHAN(2437, 5),
+ CHAN(2442, 6),
+ CHAN(2447, 7),
+ CHAN(2452, 8),
+ CHAN(2457, 9),
+ CHAN(2462, 10),
+ CHAN(2467, 11),
+ CHAN(2472, 12),
+ CHAN(2484, 13),
+};
+
+static struct ieee80211_channel ar9170_5ghz_chantable[] = {
+ CHAN(4920, 14),
+ CHAN(4940, 15),
+ CHAN(4960, 16),
+ CHAN(4980, 17),
+ CHAN(5040, 18),
+ CHAN(5060, 19),
+ CHAN(5080, 20),
+ CHAN(5180, 21),
+ CHAN(5200, 22),
+ CHAN(5220, 23),
+ CHAN(5240, 24),
+ CHAN(5260, 25),
+ CHAN(5280, 26),
+ CHAN(5300, 27),
+ CHAN(5320, 28),
+ CHAN(5500, 29),
+ CHAN(5520, 30),
+ CHAN(5540, 31),
+ CHAN(5560, 32),
+ CHAN(5580, 33),
+ CHAN(5600, 34),
+ CHAN(5620, 35),
+ CHAN(5640, 36),
+ CHAN(5660, 37),
+ CHAN(5680, 38),
+ CHAN(5700, 39),
+ CHAN(5745, 40),
+ CHAN(5765, 41),
+ CHAN(5785, 42),
+ CHAN(5805, 43),
+ CHAN(5825, 44),
+ CHAN(5170, 45),
+ CHAN(5190, 46),
+ CHAN(5210, 47),
+ CHAN(5230, 48),
+};
+#undef CHAN
+
+static struct ieee80211_supported_band ar9170_band_2GHz = {
+ .channels = ar9170_2ghz_chantable,
+ .n_channels = ARRAY_SIZE(ar9170_2ghz_chantable),
+ .bitrates = ar9170_g_ratetable,
+ .n_bitrates = ar9170_g_ratetable_size,
+};
+
+#ifdef AR9170_QUEUE_DEBUG
+/*
+ * In case some wants works with AR9170's crazy tx_status queueing techniques.
+ * He might need this rather useful probing function.
+ *
+ * NOTE: caller must hold the queue's spinlock!
+ */
+
+static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
+{
+ struct ar9170_tx_control *txc = (void *) skb->data;
+ struct ieee80211_hdr *hdr = (void *)txc->frame_data;
+
+ printk(KERN_DEBUG "%s: => FRAME [skb:%p, queue:%d, DA:[%pM] "
+ "mac_control:%04x, phy_control:%08x]\n",
+ wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
+ ieee80211_get_DA(hdr), le16_to_cpu(txc->mac_control),
+ le32_to_cpu(txc->phy_control));
+}
+
+static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar,
+ struct sk_buff_head *queue)
+{
+ struct sk_buff *skb;
+ int i = 0;
+
+ printk(KERN_DEBUG "---[ cut here ]---\n");
+ printk(KERN_DEBUG "%s: %d entries in tx_status queue.\n",
+ wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
+
+ skb_queue_walk(queue, skb) {
+ struct ar9170_tx_control *txc = (void *) skb->data;
+ struct ieee80211_hdr *hdr = (void *)txc->frame_data;
+
+ printk(KERN_DEBUG "index:%d => \n", i);
+ ar9170_print_txheader(ar, skb);
+ }
+ printk(KERN_DEBUG "---[ end ]---\n");
+}
+#endif /* AR9170_QUEUE_DEBUG */
+
+static struct ieee80211_supported_band ar9170_band_5GHz = {
+ .channels = ar9170_5ghz_chantable,
+ .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
+ .bitrates = ar9170_a_ratetable,
+ .n_bitrates = ar9170_a_ratetable_size,
+};
+
+void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
+ bool valid_status, u16 tx_status)
+{
+ struct ieee80211_tx_info *txinfo;
+ unsigned int retries = 0, queue = skb_get_queue_mapping(skb);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ar->tx_stats_lock, flags);
+ ar->tx_stats[queue].len--;
+ if (ieee80211_queue_stopped(ar->hw, queue))
+ ieee80211_wake_queue(ar->hw, queue);
+ spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+
+ txinfo = IEEE80211_SKB_CB(skb);
+ ieee80211_tx_info_clear_status(txinfo);
+
+ switch (tx_status) {
+ case AR9170_TX_STATUS_RETRY:
+ retries = 2;
+ case AR9170_TX_STATUS_COMPLETE:
+ txinfo->flags |= IEEE80211_TX_STAT_ACK;
+ break;
+
+ case AR9170_TX_STATUS_FAILED:
+ retries = ar->hw->conf.long_frame_max_tx_count;
+ break;
+
+ default:
+ printk(KERN_ERR "%s: invalid tx_status response (%x).\n",
+ wiphy_name(ar->hw->wiphy), tx_status);
+ break;
+ }
+
+ if (valid_status)
+ txinfo->status.rates[0].count = retries + 1;
+
+ skb_pull(skb, sizeof(struct ar9170_tx_control));
+ ieee80211_tx_status_irqsafe(ar->hw, skb);
+}
+
+static struct sk_buff *ar9170_find_skb_in_queue(struct ar9170 *ar,
+ const u8 *mac,
+ const u32 queue,
+ struct sk_buff_head *q)
+{
+ unsigned long flags;
+ struct sk_buff *skb;
+
+ spin_lock_irqsave(&q->lock, flags);
+ skb_queue_walk(q, skb) {
+ struct ar9170_tx_control *txc = (void *) skb->data;
+ struct ieee80211_hdr *hdr = (void *) txc->frame_data;
+ u32 txc_queue = (le32_to_cpu(txc->phy_control) &
+ AR9170_TX_PHY_QOS_MASK) >>
+ AR9170_TX_PHY_QOS_SHIFT;
+
+ if ((queue != txc_queue) ||
+ (compare_ether_addr(ieee80211_get_DA(hdr), mac)))
+ continue;
+
+ __skb_unlink(skb, q);
+ spin_unlock_irqrestore(&q->lock, flags);
+ return skb;
+ }
+ spin_unlock_irqrestore(&q->lock, flags);
+ return NULL;
+}
+
+static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac,
+ const u32 queue)
+{
+ struct ieee80211_sta *sta;
+ struct sk_buff *skb;
+
+ /*
+ * Unfortunately, the firmware does not tell to which (queued) frame
+ * this transmission status report belongs to.
+ *
+ * So we have to make risky guesses - with the scarce information
+ * the firmware provided (-> destination MAC, and phy_control) -
+ * and hope that we picked the right one...
+ */
+ rcu_read_lock();
+ sta = ieee80211_find_sta(ar->hw, mac);
+
+ if (likely(sta)) {
+ struct ar9170_sta_info *sta_priv = (void *) sta->drv_priv;
+ skb = skb_dequeue(&sta_priv->tx_status[queue]);
+ rcu_read_unlock();
+ if (likely(skb))
+ return skb;
+ } else
+ rcu_read_unlock();
+
+ /* scan the waste queue for candidates */
+ skb = ar9170_find_skb_in_queue(ar, mac, queue,
+ &ar->global_tx_status_waste);
+ if (!skb) {
+ /* so it still _must_ be in the global list. */
+ skb = ar9170_find_skb_in_queue(ar, mac, queue,
+ &ar->global_tx_status);
+ }
+
+#ifdef AR9170_QUEUE_DEBUG
+ if (unlikely((!skb) && net_ratelimit())) {
+ printk(KERN_ERR "%s: ESS:[%pM] does not have any "
+ "outstanding frames in this queue (%d).\n",
+ wiphy_name(ar->hw->wiphy), mac, queue);
+ }
+#endif /* AR9170_QUEUE_DEBUG */
+ return skb;
+}
+
+/*
+ * This worker tries to keep the global tx_status queue empty.
+ * So we can guarantee that incoming tx_status reports for
+ * unregistered stations are always synced with the actual
+ * frame - which we think - belongs to.
+ */
+
+static void ar9170_tx_status_janitor(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170,
+ tx_status_janitor.work);
+ struct sk_buff *skb;
+
+ if (unlikely(!IS_STARTED(ar)))
+ return ;
+
+ mutex_lock(&ar->mutex);
+ /* recycle the garbage back to mac80211... one by one. */
+ while ((skb = skb_dequeue(&ar->global_tx_status_waste))) {
+#ifdef AR9170_QUEUE_DEBUG
+ printk(KERN_DEBUG "%s: dispose queued frame =>\n",
+ wiphy_name(ar->hw->wiphy));
+ ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+ ar9170_handle_tx_status(ar, skb, false,
+ AR9170_TX_STATUS_FAILED);
+ }
+
+ while ((skb = skb_dequeue(&ar->global_tx_status))) {
+#ifdef AR9170_QUEUE_DEBUG
+ printk(KERN_DEBUG "%s: moving frame into waste queue =>\n",
+ wiphy_name(ar->hw->wiphy));
+
+ ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+ skb_queue_tail(&ar->global_tx_status_waste, skb);
+ }
+
+ /* recall the janitor in 100ms - if there's garbage in the can. */
+ if (skb_queue_len(&ar->global_tx_status_waste) > 0)
+ queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
+ msecs_to_jiffies(100));
+
+ mutex_unlock(&ar->mutex);
+}
+
+static void ar9170_handle_command_response(struct ar9170 *ar,
+ void *buf, u32 len)
+{
+ struct ar9170_cmd_response *cmd = (void *) buf;
+
+ if ((cmd->type & 0xc0) != 0xc0) {
+ ar->callback_cmd(ar, len, buf);
+ return;
+ }
+
+ /* hardware event handlers */
+ switch (cmd->type) {
+ case 0xc1: {
+ /*
+ * TX status notification:
+ * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
+ *
+ * XX always 81
+ * YY always 00
+ * M1-M6 is the MAC address
+ * R1-R4 is the transmit rate
+ * S1-S2 is the transmit status
+ */
+
+ struct sk_buff *skb;
+ u32 queue = (le32_to_cpu(cmd->tx_status.rate) &
+ AR9170_TX_PHY_QOS_MASK) >> AR9170_TX_PHY_QOS_SHIFT;
+
+ skb = ar9170_find_queued_skb(ar, cmd->tx_status.dst, queue);
+ if (unlikely(!skb))
+ return ;
+
+ ar9170_handle_tx_status(ar, skb, true,
+ le16_to_cpu(cmd->tx_status.status));
+ break;
+ }
+
+ case 0xc0:
+ /*
+ * pre-TBTT event
+ */
+ if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
+ queue_work(ar->hw->workqueue, &ar->beacon_work);
+ break;
+
+ case 0xc2:
+ /*
+ * (IBSS) beacon send notification
+ * bytes: 04 c2 XX YY B4 B3 B2 B1
+ *
+ * XX always 80
+ * YY always 00
+ * B1-B4 "should" be the number of send out beacons.
+ */
+ break;
+
+ case 0xc3:
+ /* End of Atim Window */
+ break;
+
+ case 0xc4:
+ case 0xc5:
+ /* BlockACK events */
+ break;
+
+ case 0xc6:
+ /* Watchdog Interrupt */
+ break;
+
+ case 0xc9:
+ /* retransmission issue / SIFS/EIFS collision ?! */
+ break;
+
+ default:
+ printk(KERN_INFO "received unhandled event %x\n", cmd->type);
+ print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
+ break;
+ }
+}
+
+/*
+ * If the frame alignment is right (or the kernel has
+ * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
+ * is only a single MPDU in the USB frame, then we can
+ * submit to mac80211 the SKB directly. However, since
+ * there may be multiple packets in one SKB in stream
+ * mode, and we need to observe the proper ordering,
+ * this is non-trivial.
+ */
+static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
+{
+ struct sk_buff *skb;
+ struct ar9170_rx_head *head = (void *)buf;
+ struct ar9170_rx_tail *tail;
+ struct ieee80211_rx_status status;
+ int mpdu_len, i;
+ u8 error, antennas = 0, decrypt;
+ __le16 fc;
+ int reserved;
+
+ if (unlikely(!IS_STARTED(ar)))
+ return ;
+
+ /* Received MPDU */
+ mpdu_len = len;
+ mpdu_len -= sizeof(struct ar9170_rx_head);
+ mpdu_len -= sizeof(struct ar9170_rx_tail);
+ BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
+ BUILD_BUG_ON(sizeof(struct ar9170_rx_tail) != 24);
+
+ if (mpdu_len <= FCS_LEN)
+ return;
+
+ tail = (void *)(buf + sizeof(struct ar9170_rx_head) + mpdu_len);
+
+ for (i = 0; i < 3; i++)
+ if (tail->rssi[i] != 0x80)
+ antennas |= BIT(i);
+
+ /* post-process RSSI */
+ for (i = 0; i < 7; i++)
+ if (tail->rssi[i] & 0x80)
+ tail->rssi[i] = ((tail->rssi[i] & 0x7f) + 1) & 0x7f;
+
+ memset(&status, 0, sizeof(status));
+
+ status.band = ar->channel->band;
+ status.freq = ar->channel->center_freq;
+ status.signal = ar->noise[0] + tail->rssi_combined;
+ status.noise = ar->noise[0];
+ status.antenna = antennas;
+
+ switch (tail->status & AR9170_RX_STATUS_MODULATION_MASK) {
+ case AR9170_RX_STATUS_MODULATION_CCK:
+ if (tail->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
+ status.flag |= RX_FLAG_SHORTPRE;
+ switch (head->plcp[0]) {
+ case 0x0a:
+ status.rate_idx = 0;
+ break;
+ case 0x14:
+ status.rate_idx = 1;
+ break;
+ case 0x37:
+ status.rate_idx = 2;
+ break;
+ case 0x6e:
+ status.rate_idx = 3;
+ break;
+ default:
+ if ((!ar->sniffer_enabled) && (net_ratelimit()))
+ printk(KERN_ERR "%s: invalid plcp cck rate "
+ "(%x).\n", wiphy_name(ar->hw->wiphy),
+ head->plcp[0]);
+ return;
+ }
+ break;
+ case AR9170_RX_STATUS_MODULATION_OFDM:
+ switch (head->plcp[0] & 0xF) {
+ case 0xB:
+ status.rate_idx = 0;
+ break;
+ case 0xF:
+ status.rate_idx = 1;
+ break;
+ case 0xA:
+ status.rate_idx = 2;
+ break;
+ case 0xE:
+ status.rate_idx = 3;
+ break;
+ case 0x9:
+ status.rate_idx = 4;
+ break;
+ case 0xD:
+ status.rate_idx = 5;
+ break;
+ case 0x8:
+ status.rate_idx = 6;
+ break;
+ case 0xC:
+ status.rate_idx = 7;
+ break;
+ default:
+ if ((!ar->sniffer_enabled) && (net_ratelimit()))
+ printk(KERN_ERR "%s: invalid plcp ofdm rate "
+ "(%x).\n", wiphy_name(ar->hw->wiphy),
+ head->plcp[0]);
+ return;
+ }
+ if (status.band == IEEE80211_BAND_2GHZ)
+ status.rate_idx += 4;
+ break;
+ case AR9170_RX_STATUS_MODULATION_HT:
+ case AR9170_RX_STATUS_MODULATION_DUPOFDM:
+ /* XXX */
+
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: invalid modulation\n",
+ wiphy_name(ar->hw->wiphy));
+ return;
+ }
+
+ error = tail->error;
+
+ if (error & AR9170_RX_ERROR_MMIC) {
+ status.flag |= RX_FLAG_MMIC_ERROR;
+ error &= ~AR9170_RX_ERROR_MMIC;
+ }
+
+ if (error & AR9170_RX_ERROR_PLCP) {
+ status.flag |= RX_FLAG_FAILED_PLCP_CRC;
+ error &= ~AR9170_RX_ERROR_PLCP;
+ }
+
+ if (error & AR9170_RX_ERROR_FCS) {
+ status.flag |= RX_FLAG_FAILED_FCS_CRC;
+ error &= ~AR9170_RX_ERROR_FCS;
+ }
+
+ decrypt = ar9170_get_decrypt_type(tail);
+ if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
+ decrypt != AR9170_ENC_ALG_NONE)
+ status.flag |= RX_FLAG_DECRYPTED;
+
+ /* ignore wrong RA errors */
+ error &= ~AR9170_RX_ERROR_WRONG_RA;
+
+ if (error & AR9170_RX_ERROR_DECRYPT) {
+ error &= ~AR9170_RX_ERROR_DECRYPT;
+
+ /*
+ * Rx decryption is done in place,
+ * the original data is lost anyway.
+ */
+ return ;
+ }
+
+ /* drop any other error frames */
+ if ((error) && (net_ratelimit())) {
+ printk(KERN_DEBUG "%s: errors: %#x\n",
+ wiphy_name(ar->hw->wiphy), error);
+ return;
+ }
+
+ buf += sizeof(struct ar9170_rx_head);
+ fc = *(__le16 *)buf;
+
+ if (ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc))
+ reserved = 32 + 2;
+ else
+ reserved = 32;
+
+ skb = dev_alloc_skb(mpdu_len + reserved);
+ if (!skb)
+ return;
+
+ skb_reserve(skb, reserved);
+ memcpy(skb_put(skb, mpdu_len), buf, mpdu_len);
+ ieee80211_rx_irqsafe(ar->hw, skb, &status);
+}
+
+void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
+{
+ unsigned int i, tlen, resplen;
+ u8 *tbuf, *respbuf;
+
+ tbuf = skb->data;
+ tlen = skb->len;
+
+ while (tlen >= 4) {
+ int clen = tbuf[1] << 8 | tbuf[0];
+ int wlen = (clen + 3) & ~3;
+
+ /*
+ * parse stream (if any)
+ */
+ if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
+ printk(KERN_ERR "%s: missing tag!\n",
+ wiphy_name(ar->hw->wiphy));
+ return ;
+ }
+ if (wlen > tlen - 4) {
+ printk(KERN_ERR "%s: invalid RX (%d, %d, %d)\n",
+ wiphy_name(ar->hw->wiphy), clen, wlen, tlen);
+ print_hex_dump(KERN_DEBUG, "data: ",
+ DUMP_PREFIX_OFFSET,
+ 16, 1, tbuf, tlen, true);
+ return ;
+ }
+ resplen = clen;
+ respbuf = tbuf + 4;
+ tbuf += wlen + 4;
+ tlen -= wlen + 4;
+
+ i = 0;
+
+ /* weird thing, but this is the same in the original driver */
+ while (resplen > 2 && i < 12 &&
+ respbuf[0] == 0xff && respbuf[1] == 0xff) {
+ i += 2;
+ resplen -= 2;
+ respbuf += 2;
+ }
+
+ if (resplen < 4)
+ continue;
+
+ /* found the 6 * 0xffff marker? */
+ if (i == 12)
+ ar9170_handle_command_response(ar, respbuf, resplen);
+ else
+ ar9170_handle_mpdu(ar, respbuf, resplen);
+ }
+
+ if (tlen)
+ printk(KERN_ERR "%s: buffer remains!\n",
+ wiphy_name(ar->hw->wiphy));
+}
+
+#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \
+do { \
+ queue.aifs = ai_fs; \
+ queue.cw_min = cwmin; \
+ queue.cw_max = cwmax; \
+ queue.txop = _txop; \
+} while (0)
+
+static int ar9170_op_start(struct ieee80211_hw *hw)
+{
+ struct ar9170 *ar = hw->priv;
+ int err, i;
+
+ mutex_lock(&ar->mutex);
+
+ /* reinitialize queues statistics */
+ memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
+ for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++)
+ ar->tx_stats[i].limit = 8;
+
+ /* reset QoS defaults */
+ AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/
+ AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023, 0); /* BACKGROUND */
+ AR9170_FILL_QUEUE(ar->edcf[2], 2, 7, 15, 94); /* VIDEO */
+ AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */
+ AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
+
+ err = ar->open(ar);
+ if (err)
+ goto out;
+
+ err = ar9170_init_mac(ar);
+ if (err)
+ goto out;
+
+ err = ar9170_set_qos(ar);
+ if (err)
+ goto out;
+
+ err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
+ if (err)
+ goto out;
+
+ err = ar9170_init_rf(ar);
+ if (err)
+ goto out;
+
+ /* start DMA */
+ err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
+ if (err)
+ goto out;
+
+ ar->state = AR9170_STARTED;
+
+out:
+ mutex_unlock(&ar->mutex);
+ return err;
+}
+
+static void ar9170_op_stop(struct ieee80211_hw *hw)
+{
+ struct ar9170 *ar = hw->priv;
+
+ if (IS_STARTED(ar))
+ ar->state = AR9170_IDLE;
+
+ mutex_lock(&ar->mutex);
+
+ cancel_delayed_work_sync(&ar->tx_status_janitor);
+ cancel_work_sync(&ar->filter_config_work);
+ cancel_work_sync(&ar->beacon_work);
+ skb_queue_purge(&ar->global_tx_status_waste);
+ skb_queue_purge(&ar->global_tx_status);
+
+ if (IS_ACCEPTING_CMD(ar)) {
+ ar9170_set_leds_state(ar, 0);
+
+ /* stop DMA */
+ ar9170_write_reg(ar, 0x1c3d30, 0);
+ ar->stop(ar);
+ }
+
+ mutex_unlock(&ar->mutex);
+}
+
+int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct ar9170 *ar = hw->priv;
+ struct ieee80211_hdr *hdr;
+ struct ar9170_tx_control *txc;
+ struct ieee80211_tx_info *info;
+ struct ieee80211_rate *rate = NULL;
+ struct ieee80211_tx_rate *txrate;
+ unsigned int queue = skb_get_queue_mapping(skb);
+ unsigned long flags = 0;
+ struct ar9170_sta_info *sta_info = NULL;
+ u32 power, chains;
+ u16 keytype = 0;
+ u16 len, icv = 0;
+ int err;
+ bool tx_status;
+
+ if (unlikely(!IS_STARTED(ar)))
+ goto err_free;
+
+ hdr = (void *)skb->data;
+ info = IEEE80211_SKB_CB(skb);
+ len = skb->len;
+
+ spin_lock_irqsave(&ar->tx_stats_lock, flags);
+ if (ar->tx_stats[queue].limit < ar->tx_stats[queue].len) {
+ spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+ return NETDEV_TX_OK;
+ }
+
+ ar->tx_stats[queue].len++;
+ ar->tx_stats[queue].count++;
+ if (ar->tx_stats[queue].limit == ar->tx_stats[queue].len)
+ ieee80211_stop_queue(hw, queue);
+
+ spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+
+ txc = (void *)skb_push(skb, sizeof(*txc));
+
+ tx_status = (((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) != 0) ||
+ ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) != 0));
+
+ if (info->control.hw_key) {
+ icv = info->control.hw_key->icv_len;
+
+ switch (info->control.hw_key->alg) {
+ case ALG_WEP:
+ keytype = AR9170_TX_MAC_ENCR_RC4;
+ break;
+ case ALG_TKIP:
+ keytype = AR9170_TX_MAC_ENCR_RC4;
+ break;
+ case ALG_CCMP:
+ keytype = AR9170_TX_MAC_ENCR_AES;
+ break;
+ default:
+ WARN_ON(1);
+ goto err_dequeue;
+ }
+ }
+
+ /* Length */
+ txc->length = cpu_to_le16(len + icv + 4);
+
+ txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
+ AR9170_TX_MAC_BACKOFF);
+ txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
+ AR9170_TX_MAC_QOS_SHIFT);
+ txc->mac_control |= cpu_to_le16(keytype);
+ txc->phy_control = cpu_to_le32(0);
+
+ if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+ txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
+
+ if (info->flags & IEEE80211_TX_CTL_AMPDU)
+ txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
+
+ txrate = &info->control.rates[0];
+
+ if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
+ txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
+ else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
+ txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
+
+ if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
+ txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
+
+ if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
+
+ if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
+ /* this works because 40 MHz is 2 and dup is 3 */
+ if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
+ txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
+
+ if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
+ txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
+
+ if (txrate->flags & IEEE80211_TX_RC_MCS) {
+ u32 r = txrate->idx;
+ u8 *txpower;
+
+ r <<= AR9170_TX_PHY_MCS_SHIFT;
+ if (WARN_ON(r & ~AR9170_TX_PHY_MCS_MASK))
+ goto err_dequeue;
+ txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
+ txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
+
+ if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
+ if (info->band == IEEE80211_BAND_5GHZ)
+ txpower = ar->power_5G_ht40;
+ else
+ txpower = ar->power_2G_ht40;
+ } else {
+ if (info->band == IEEE80211_BAND_5GHZ)
+ txpower = ar->power_5G_ht20;
+ else
+ txpower = ar->power_2G_ht20;
+ }
+
+ power = txpower[(txrate->idx) & 7];
+ } else {
+ u8 *txpower;
+ u32 mod;
+ u32 phyrate;
+ u8 idx = txrate->idx;
+
+ if (info->band != IEEE80211_BAND_2GHZ) {
+ idx += 4;
+ txpower = ar->power_5G_leg;
+ mod = AR9170_TX_PHY_MOD_OFDM;
+ } else {
+ if (idx < 4) {
+ txpower = ar->power_2G_cck;
+ mod = AR9170_TX_PHY_MOD_CCK;
+ } else {
+ mod = AR9170_TX_PHY_MOD_OFDM;
+ txpower = ar->power_2G_ofdm;
+ }
+ }
+
+ rate = &__ar9170_ratetable[idx];
+
+ phyrate = rate->hw_value & 0xF;
+ power = txpower[(rate->hw_value & 0x30) >> 4];
+ phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
+
+ txc->phy_control |= cpu_to_le32(mod);
+ txc->phy_control |= cpu_to_le32(phyrate);
+ }
+
+ power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
+ power &= AR9170_TX_PHY_TX_PWR_MASK;
+ txc->phy_control |= cpu_to_le32(power);
+
+ /* set TX chains */
+ if (ar->eeprom.tx_mask == 1) {
+ chains = AR9170_TX_PHY_TXCHAIN_1;
+ } else {
+ chains = AR9170_TX_PHY_TXCHAIN_2;
+
+ /* >= 36M legacy OFDM - use only one chain */
+ if (rate && rate->bitrate >= 360)
+ chains = AR9170_TX_PHY_TXCHAIN_1;
+ }
+ txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
+
+ if (tx_status) {
+ txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
+ /*
+ * WARNING:
+ * Putting the QoS queue bits into an unexplored territory is
+ * certainly not elegant.
+ *
+ * In my defense: This idea provides a reasonable way to
+ * smuggle valuable information to the tx_status callback.
+ * Also, the idea behind this bit-abuse came straight from
+ * the original driver code.
+ */
+
+ txc->phy_control |=
+ cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
+
+ if (info->control.sta) {
+ sta_info = (void *) info->control.sta->drv_priv;
+ skb_queue_tail(&sta_info->tx_status[queue], skb);
+ } else {
+ skb_queue_tail(&ar->global_tx_status, skb);
+
+ queue_delayed_work(ar->hw->workqueue,
+ &ar->tx_status_janitor,
+ msecs_to_jiffies(100));
+ }
+ }
+
+ err = ar->tx(ar, skb, tx_status, 0);
+ if (unlikely(tx_status && err)) {
+ if (info->control.sta)
+ skb_unlink(skb, &sta_info->tx_status[queue]);
+ else
+ skb_unlink(skb, &ar->global_tx_status);
+ }
+
+ return NETDEV_TX_OK;
+
+err_dequeue:
+ spin_lock_irqsave(&ar->tx_stats_lock, flags);
+ ar->tx_stats[queue].len--;
+ ar->tx_stats[queue].count--;
+ spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+
+err_free:
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+}
+
+static int ar9170_op_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct ar9170 *ar = hw->priv;
+ int err = 0;
+
+ mutex_lock(&ar->mutex);
+
+ if (ar->vif) {
+ err = -EBUSY;
+ goto unlock;
+ }
+
+ ar->vif = conf->vif;
+ memcpy(ar->mac_addr, conf->mac_addr, ETH_ALEN);
+
+ if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
+ ar->rx_software_decryption = true;
+ ar->disable_offload = true;
+ }
+
+ ar->cur_filter = 0;
+ ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS;
+ err = ar9170_update_frame_filter(ar);
+ if (err)
+ goto unlock;
+
+ err = ar9170_set_operating_mode(ar);
+
+unlock:
+ mutex_unlock(&ar->mutex);
+ return err;
+}
+
+static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct ar9170 *ar = hw->priv;
+
+ mutex_lock(&ar->mutex);
+ ar->vif = NULL;
+ ar->want_filter = 0;
+ ar9170_update_frame_filter(ar);
+ ar9170_set_beacon_timers(ar);
+ dev_kfree_skb(ar->beacon);
+ ar->beacon = NULL;
+ ar->sniffer_enabled = false;
+ ar->rx_software_decryption = false;
+ ar9170_set_operating_mode(ar);
+ mutex_unlock(&ar->mutex);
+}
+
+static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct ar9170 *ar = hw->priv;
+ int err = 0;
+
+ mutex_lock(&ar->mutex);
+
+ if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
+ /* TODO */
+ err = 0;
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
+ /* TODO */
+ err = 0;
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_PS) {
+ /* TODO */
+ err = 0;
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ /* TODO */
+ err = 0;
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+ /*
+ * is it long_frame_max_tx_count or short_frame_max_tx_count?
+ */
+
+ err = ar9170_set_hwretry_limit(ar,
+ ar->hw->conf.long_frame_max_tx_count);
+ if (err)
+ goto out;
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) {
+ err = ar9170_set_beacon_timers(ar);
+ if (err)
+ goto out;
+ }
+
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ err = ar9170_set_channel(ar, hw->conf.channel,
+ AR9170_RFI_NONE, AR9170_BW_20);
+ if (err)
+ goto out;
+ /* adjust slot time for 5 GHz */
+ if (hw->conf.channel->band == IEEE80211_BAND_5GHZ)
+ err = ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
+ 9 << 10);
+ }
+
+out:
+ mutex_unlock(&ar->mutex);
+ return err;
+}
+
+static int ar9170_op_config_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_if_conf *conf)
+{
+ struct ar9170 *ar = hw->priv;
+ int err = 0;
+
+ mutex_lock(&ar->mutex);
+
+ if (conf->changed & IEEE80211_IFCC_BSSID) {
+ memcpy(ar->bssid, conf->bssid, ETH_ALEN);
+ err = ar9170_set_operating_mode(ar);
+ }
+
+ if (conf->changed & IEEE80211_IFCC_BEACON) {
+ err = ar9170_update_beacon(ar);
+
+ if (err)
+ goto out;
+ err = ar9170_set_beacon_timers(ar);
+ }
+
+out:
+ mutex_unlock(&ar->mutex);
+ return err;
+}
+
+static void ar9170_set_filters(struct work_struct *work)
+{
+ struct ar9170 *ar = container_of(work, struct ar9170,
+ filter_config_work);
+ int err;
+
+ mutex_lock(&ar->mutex);
+ if (unlikely(!IS_STARTED(ar)))
+ goto unlock;
+
+ if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) {
+ err = ar9170_set_operating_mode(ar);
+ if (err)
+ goto unlock;
+ }
+
+ if (ar->filter_changed & AR9170_FILTER_CHANGED_MULTICAST) {
+ err = ar9170_update_multicast(ar);
+ if (err)
+ goto unlock;
+ }
+
+ if (ar->filter_changed & AR9170_FILTER_CHANGED_FRAMEFILTER)
+ err = ar9170_update_frame_filter(ar);
+
+unlock:
+ mutex_unlock(&ar->mutex);
+}
+
+static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *new_flags,
+ int mc_count, struct dev_mc_list *mclist)
+{
+ struct ar9170 *ar = hw->priv;
+
+ /* mask supported flags */
+ *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
+ FIF_PROMISC_IN_BSS;
+
+ /*
+ * We can support more by setting the sniffer bit and
+ * then checking the error flags, later.
+ */
+
+ if (changed_flags & FIF_ALLMULTI) {
+ if (*new_flags & FIF_ALLMULTI) {
+ ar->want_mc_hash = ~0ULL;
+ } else {
+ u64 mchash;
+ int i;
+
+ /* always get broadcast frames */
+ mchash = 1ULL << (0xff>>2);
+
+ for (i = 0; i < mc_count; i++) {
+ if (WARN_ON(!mclist))
+ break;
+ mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
+ mclist = mclist->next;
+ }
+ ar->want_mc_hash = mchash;
+ }
+ ar->filter_changed |= AR9170_FILTER_CHANGED_MULTICAST;
+ }
+
+ if (changed_flags & FIF_CONTROL) {
+ u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
+ AR9170_MAC_REG_FTF_RTS |
+ AR9170_MAC_REG_FTF_CTS |
+ AR9170_MAC_REG_FTF_ACK |
+ AR9170_MAC_REG_FTF_CFE |
+ AR9170_MAC_REG_FTF_CFE_ACK;
+
+ if (*new_flags & FIF_CONTROL)
+ ar->want_filter = ar->cur_filter | filter;
+ else
+ ar->want_filter = ar->cur_filter & ~filter;
+
+ ar->filter_changed |= AR9170_FILTER_CHANGED_FRAMEFILTER;
+ }
+
+ if (changed_flags & FIF_PROMISC_IN_BSS) {
+ ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
+ ar->filter_changed |= AR9170_FILTER_CHANGED_PROMISC;
+ }
+
+ if (likely(IS_STARTED(ar)))
+ queue_work(ar->hw->workqueue, &ar->filter_config_work);
+}
+
+static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changed)
+{
+ struct ar9170 *ar = hw->priv;
+ int err = 0;
+
+ mutex_lock(&ar->mutex);
+
+ ar9170_regwrite_begin(ar);
+
+ if (changed & BSS_CHANGED_ASSOC) {
+ ar->state = bss_conf->assoc ? AR9170_ASSOCIATED : ar->state;
+
+#ifndef CONFIG_AR9170_LEDS
+ /* enable assoc LED. */
+ err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
+#endif /* CONFIG_AR9170_LEDS */
+ }
+
+ if (changed & BSS_CHANGED_HT) {
+ /* TODO */
+ err = 0;
+ }
+
+ if (changed & BSS_CHANGED_ERP_SLOT) {
+ u32 slottime = 20;
+
+ if (bss_conf->use_short_slot)
+ slottime = 9;
+
+ ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, slottime << 10);
+ }
+
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ u32 cck, ofdm;
+
+ if (hw->conf.channel->band == IEEE80211_BAND_5GHZ) {
+ ofdm = bss_conf->basic_rates;
+ cck = 0;
+ } else {
+ /* four cck rates */
+ cck = bss_conf->basic_rates & 0xf;
+ ofdm = bss_conf->basic_rates >> 4;
+ }
+ ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE,
+ ofdm << 8 | cck);
+ }
+
+ ar9170_regwrite_finish();
+ err = ar9170_regwrite_result();
+ mutex_unlock(&ar->mutex);
+}
+
+static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
+{
+ struct ar9170 *ar = hw->priv;
+ int err;
+ u32 tsf_low;
+ u32 tsf_high;
+ u64 tsf;
+
+ mutex_lock(&ar->mutex);
+ err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low);
+ if (!err)
+ err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high);
+ mutex_unlock(&ar->mutex);
+
+ if (WARN_ON(err))
+ return 0;
+
+ tsf = tsf_high;
+ tsf = (tsf << 32) | tsf_low;
+ return tsf;
+}
+
+static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ struct ar9170 *ar = hw->priv;
+ int err = 0, i;
+ u8 ktype;
+
+ if ((!ar->vif) || (ar->disable_offload))
+ return -EOPNOTSUPP;
+
+ switch (key->alg) {
+ case ALG_WEP:
+ if (key->keylen == LEN_WEP40)
+ ktype = AR9170_ENC_ALG_WEP64;
+ else
+ ktype = AR9170_ENC_ALG_WEP128;
+ break;
+ case ALG_TKIP:
+ ktype = AR9170_ENC_ALG_TKIP;
+ break;
+ case ALG_CCMP:
+ ktype = AR9170_ENC_ALG_AESCCMP;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ mutex_lock(&ar->mutex);
+ if (cmd == SET_KEY) {
+ if (unlikely(!IS_STARTED(ar))) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ /* group keys need all-zeroes address */
+ if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+ sta = NULL;
+
+ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+ for (i = 0; i < 64; i++)
+ if (!(ar->usedkeys & BIT(i)))
+ break;
+ if (i == 64) {
+ ar->rx_software_decryption = true;
+ ar9170_set_operating_mode(ar);
+ err = -ENOSPC;
+ goto out;
+ }
+ } else {
+ i = 64 + key->keyidx;
+ }
+
+ key->hw_key_idx = i;
+
+ err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
+ key->key, min_t(u8, 16, key->keylen));
+ if (err)
+ goto out;
+
+ if (key->alg == ALG_TKIP) {
+ err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
+ ktype, 1, key->key + 16, 16);
+ if (err)
+ goto out;
+
+ /*
+ * hardware is not capable generating the MMIC
+ * for fragmented frames!
+ */
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ }
+
+ if (i < 64)
+ ar->usedkeys |= BIT(i);
+
+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ } else {
+ if (unlikely(!IS_STARTED(ar))) {
+ /* The device is gone... together with the key ;-) */
+ err = 0;
+ goto out;
+ }
+
+ err = ar9170_disable_key(ar, key->hw_key_idx);
+ if (err)
+ goto out;
+
+ if (key->hw_key_idx < 64) {
+ ar->usedkeys &= ~BIT(key->hw_key_idx);
+ } else {
+ err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
+ AR9170_ENC_ALG_NONE, 0,
+ NULL, 0);
+ if (err)
+ goto out;
+
+ if (key->alg == ALG_TKIP) {
+ err = ar9170_upload_key(ar, key->hw_key_idx,
+ NULL,
+ AR9170_ENC_ALG_NONE, 1,
+ NULL, 0);
+ if (err)
+ goto out;
+ }
+
+ }
+ }
+
+ ar9170_regwrite_begin(ar);
+ ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
+ ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
+ ar9170_regwrite_finish();
+ err = ar9170_regwrite_result();
+
+out:
+ mutex_unlock(&ar->mutex);
+
+ return err;
+}
+
+static void ar9170_sta_notify(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ enum sta_notify_cmd cmd,
+ struct ieee80211_sta *sta)
+{
+ struct ar9170 *ar = hw->priv;
+ struct ar9170_sta_info *info = (void *) sta->drv_priv;
+ struct sk_buff *skb;
+ unsigned int i;
+
+ switch (cmd) {
+ case STA_NOTIFY_ADD:
+ for (i = 0; i < ar->hw->queues; i++)
+ skb_queue_head_init(&info->tx_status[i]);
+ break;
+
+ case STA_NOTIFY_REMOVE:
+
+ /*
+ * transfer all outstanding frames that need a tx_status
+ * reports to the global tx_status queue
+ */
+
+ for (i = 0; i < ar->hw->queues; i++) {
+ while ((skb = skb_dequeue(&info->tx_status[i]))) {
+#ifdef AR9170_QUEUE_DEBUG
+ printk(KERN_DEBUG "%s: queueing frame in "
+ "global tx_status queue =>\n",
+ wiphy_name(ar->hw->wiphy));
+
+ ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+ skb_queue_tail(&ar->global_tx_status, skb);
+ }
+ }
+ queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
+ msecs_to_jiffies(100));
+ break;
+
+ default:
+ break;
+ }
+}
+
+static int ar9170_get_stats(struct ieee80211_hw *hw,
+ struct ieee80211_low_level_stats *stats)
+{
+ struct ar9170 *ar = hw->priv;
+ u32 val;
+ int err;
+
+ mutex_lock(&ar->mutex);
+ err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
+ ar->stats.dot11ACKFailureCount += val;
+
+ memcpy(stats, &ar->stats, sizeof(*stats));
+ mutex_unlock(&ar->mutex);
+
+ return 0;
+}
+
+static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
+ struct ieee80211_tx_queue_stats *tx_stats)
+{
+ struct ar9170 *ar = hw->priv;
+
+ spin_lock_bh(&ar->tx_stats_lock);
+ memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
+ spin_unlock_bh(&ar->tx_stats_lock);
+
+ return 0;
+}
+
+static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *param)
+{
+ struct ar9170 *ar = hw->priv;
+ int ret;
+
+ mutex_lock(&ar->mutex);
+ if ((param) && !(queue > ar->hw->queues)) {
+ memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
+ param, sizeof(*param));
+
+ ret = ar9170_set_qos(ar);
+ } else
+ ret = -EINVAL;
+
+ mutex_unlock(&ar->mutex);
+ return ret;
+}
+
+static const struct ieee80211_ops ar9170_ops = {
+ .start = ar9170_op_start,
+ .stop = ar9170_op_stop,
+ .tx = ar9170_op_tx,
+ .add_interface = ar9170_op_add_interface,
+ .remove_interface = ar9170_op_remove_interface,
+ .config = ar9170_op_config,
+ .config_interface = ar9170_op_config_interface,
+ .configure_filter = ar9170_op_configure_filter,
+ .conf_tx = ar9170_conf_tx,
+ .bss_info_changed = ar9170_op_bss_info_changed,
+ .get_tsf = ar9170_op_get_tsf,
+ .set_key = ar9170_set_key,
+ .sta_notify = ar9170_sta_notify,
+ .get_stats = ar9170_get_stats,
+ .get_tx_stats = ar9170_get_tx_stats,
+};
+
+void *ar9170_alloc(size_t priv_size)
+{
+ struct ieee80211_hw *hw;
+ struct ar9170 *ar;
+ int i;
+
+ hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
+ if (!hw)
+ return ERR_PTR(-ENOMEM);
+
+ ar = hw->priv;
+ ar->hw = hw;
+
+ mutex_init(&ar->mutex);
+ spin_lock_init(&ar->cmdlock);
+ spin_lock_init(&ar->tx_stats_lock);
+ skb_queue_head_init(&ar->global_tx_status);
+ skb_queue_head_init(&ar->global_tx_status_waste);
+ INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
+ INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
+ INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor);
+
+ /* all hw supports 2.4 GHz, so set channel to 1 by default */
+ ar->channel = &ar9170_2ghz_chantable[0];
+
+ /* first part of wiphy init */
+ ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_WDS) |
+ BIT(NL80211_IFTYPE_ADHOC);
+ ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_NOISE_DBM;
+
+ ar->hw->queues = __AR9170_NUM_TXQ;
+ ar->hw->extra_tx_headroom = 8;
+ ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
+
+ ar->hw->max_rates = 1;
+ ar->hw->max_rate_tries = 3;
+
+ for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
+ ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
+
+ return ar;
+}
+
+static int ar9170_read_eeprom(struct ar9170 *ar)
+{
+#define RW 8 /* number of words to read at once */
+#define RB (sizeof(u32) * RW)
+ DECLARE_MAC_BUF(mbuf);
+ u8 *eeprom = (void *)&ar->eeprom;
+ u8 *addr = ar->eeprom.mac_address;
+ __le32 offsets[RW];
+ int i, j, err, bands = 0;
+
+ BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
+
+ BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
+#ifndef __CHECKER__
+ /* don't want to handle trailing remains */
+ BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
+#endif
+
+ for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
+ for (j = 0; j < RW; j++)
+ offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
+ RB * i + 4 * j);
+
+ err = ar->exec_cmd(ar, AR9170_CMD_RREG,
+ RB, (u8 *) &offsets,
+ RB, eeprom + RB * i);
+ if (err)
+ return err;
+ }
+
+#undef RW
+#undef RB
+
+ if (ar->eeprom.length == cpu_to_le16(0xFFFF))
+ return -ENODATA;
+
+ if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
+ ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
+ bands++;
+ }
+ if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
+ ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
+ bands++;
+ }
+ /*
+ * I measured this, a bandswitch takes roughly
+ * 135 ms and a frequency switch about 80.
+ *
+ * FIXME: measure these values again once EEPROM settings
+ * are used, that will influence them!
+ */
+ if (bands == 2)
+ ar->hw->channel_change_time = 135 * 1000;
+ else
+ ar->hw->channel_change_time = 80 * 1000;
+
+ /* second part of wiphy init */
+ SET_IEEE80211_PERM_ADDR(ar->hw, addr);
+
+ return bands ? 0 : -EINVAL;
+}
+
+int ar9170_register(struct ar9170 *ar, struct device *pdev)
+{
+ int err;
+
+ /* try to read EEPROM, init MAC addr */
+ err = ar9170_read_eeprom(ar);
+ if (err)
+ goto err_out;
+
+ err = ieee80211_register_hw(ar->hw);
+ if (err)
+ goto err_out;
+
+ err = ar9170_init_leds(ar);
+ if (err)
+ goto err_unreg;
+
+#ifdef CONFIG_AR9170_LEDS
+ err = ar9170_register_leds(ar);
+ if (err)
+ goto err_unreg;
+#endif /* CONFIG_AR9170_LEDS */
+
+ dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
+ wiphy_name(ar->hw->wiphy));
+
+ return err;
+
+err_unreg:
+ ieee80211_unregister_hw(ar->hw);
+
+err_out:
+ return err;
+}
+
+void ar9170_unregister(struct ar9170 *ar)
+{
+#ifdef CONFIG_AR9170_LEDS
+ ar9170_unregister_leds(ar);
+#endif /* CONFIG_AR9170_LEDS */
+
+ ieee80211_unregister_hw(ar->hw);
+ mutex_destroy(&ar->mutex);
+}
diff --git a/drivers/net/wireless/ar9170/phy.c b/drivers/net/wireless/ar9170/phy.c
new file mode 100644
index 000000000000..6ce20754b8e7
--- /dev/null
+++ b/drivers/net/wireless/ar9170/phy.c
@@ -0,0 +1,1240 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * PHY and RF code
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/bitrev.h>
+#include "ar9170.h"
+#include "cmd.h"
+
+static int ar9170_init_power_cal(struct ar9170 *ar)
+{
+ ar9170_regwrite_begin(ar);
+
+ ar9170_regwrite(0x1bc000 + 0x993c, 0x7f);
+ ar9170_regwrite(0x1bc000 + 0x9934, 0x3f3f3f3f);
+ ar9170_regwrite(0x1bc000 + 0x9938, 0x3f3f3f3f);
+ ar9170_regwrite(0x1bc000 + 0xa234, 0x3f3f3f3f);
+ ar9170_regwrite(0x1bc000 + 0xa238, 0x3f3f3f3f);
+ ar9170_regwrite(0x1bc000 + 0xa38c, 0x3f3f3f3f);
+ ar9170_regwrite(0x1bc000 + 0xa390, 0x3f3f3f3f);
+ ar9170_regwrite(0x1bc000 + 0xa3cc, 0x3f3f3f3f);
+ ar9170_regwrite(0x1bc000 + 0xa3d0, 0x3f3f3f3f);
+ ar9170_regwrite(0x1bc000 + 0xa3d4, 0x3f3f3f3f);
+
+ ar9170_regwrite_finish();
+ return ar9170_regwrite_result();
+}
+
+struct ar9170_phy_init {
+ u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20;
+};
+
+static struct ar9170_phy_init ar5416_phy_init[] = {
+ { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+ { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, },
+ { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, },
+ { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, },
+ { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, },
+ { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, },
+ { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, },
+ { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
+ { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, },
+ { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
+ { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
+ { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+ { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, },
+ { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, },
+ { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, },
+ { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, },
+ { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, },
+ { 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, },
+ { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, },
+ { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, },
+ { 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, },
+ { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, },
+ { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, },
+ { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, },
+ { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, },
+ { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, },
+ { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, },
+ { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, },
+ { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, },
+ { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+ { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
+ { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, },
+ { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, },
+ { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, },
+ { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, },
+ { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, },
+ { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, },
+ { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+ { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, },
+ { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, },
+ { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+ { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+ { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, },
+ { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, },
+ { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, },
+ { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, },
+ { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, },
+ { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, },
+ { 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, },
+ { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, },
+ { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, },
+ { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, },
+ { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, },
+ { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, },
+ { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, },
+ { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, },
+ { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, },
+ { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, },
+ { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, },
+ { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, },
+ { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, },
+ { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, },
+ { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, },
+ { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, },
+ { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, },
+ { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
+ { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, },
+ { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, },
+ { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, },
+ { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, },
+ { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, },
+ { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, },
+ { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, },
+ { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, },
+ { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, },
+ { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, },
+ { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, },
+ { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, },
+ { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, },
+ { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, },
+ { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, },
+ { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, },
+ { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, },
+ { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, },
+ { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, },
+ { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, },
+ { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, },
+ { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, },
+ { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, },
+ { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, },
+ { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, },
+ { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, },
+ { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, },
+ { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, },
+ { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, },
+ { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+ { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+ { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, },
+ { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, },
+ { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
+ { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, },
+ { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, },
+ { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, },
+ { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, },
+ { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, },
+ { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, },
+ { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, },
+ { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
+ { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, },
+ { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, },
+ { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, },
+ { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, },
+ { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, },
+ { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, },
+ { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, },
+ { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
+ { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, },
+ { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, },
+ { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, },
+ { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, },
+ { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, },
+ { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, },
+ { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, },
+ { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, },
+ { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, },
+ { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
+ { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, },
+ { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, },
+ { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, },
+ { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, },
+ { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, },
+ { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, },
+ { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, },
+ { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, },
+ { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, },
+ { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, },
+ { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+ { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
+ { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
+ { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, },
+ { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, },
+ { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, },
+ { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+ { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, },
+ { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, },
+ { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, },
+ { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, },
+ { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, },
+ { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, },
+ { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, },
+ { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, },
+ { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, },
+ { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, },
+ { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, },
+ { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, },
+ { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+ { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
+ { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, },
+ { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, },
+ { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, },
+ { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, },
+ { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+ { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, },
+ { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+ { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, },
+ { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, },
+ { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, },
+ { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, },
+ { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, },
+ { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, },
+ { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, },
+ { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, },
+ { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, },
+ { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, },
+ { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, },
+ { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, },
+ { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+ { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+ { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+ { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, },
+ { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, },
+ { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, },
+ { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+ { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, },
+ { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+ { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+ { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+ { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+ { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, },
+ { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
+ { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
+ { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+ { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+ { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+ { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
+ { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
+ { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+ { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+ { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+/* { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */
+ { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
+ { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, },
+ { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, },
+ { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
+ { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, },
+ { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, },
+ { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, },
+ { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, },
+ { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, },
+ { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, },
+ { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, },
+ { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, },
+ { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, },
+ { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, },
+ { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, },
+ { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
+};
+
+int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
+{
+ int i, err;
+ u32 val;
+ bool is_2ghz = band == IEEE80211_BAND_2GHZ;
+ bool is_40mhz = false; /* XXX: for now */
+
+ ar9170_regwrite_begin(ar);
+
+ for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
+ if (is_40mhz) {
+ if (is_2ghz)
+ val = ar5416_phy_init[i]._2ghz_40;
+ else
+ val = ar5416_phy_init[i]._5ghz_40;
+ } else {
+ if (is_2ghz)
+ val = ar5416_phy_init[i]._2ghz_20;
+ else
+ val = ar5416_phy_init[i]._5ghz_20;
+ }
+
+ ar9170_regwrite(ar5416_phy_init[i].reg, val);
+ }
+
+ ar9170_regwrite_finish();
+ err = ar9170_regwrite_result();
+ if (err)
+ return err;
+
+ /* XXX: use EEPROM data here! */
+
+ err = ar9170_init_power_cal(ar);
+ if (err)
+ return err;
+
+ /* XXX: remove magic! */
+ if (is_2ghz)
+ err = ar9170_write_reg(ar, 0x1d4014, 0x5163);
+ else
+ err = ar9170_write_reg(ar, 0x1d4014, 0x5143);
+
+ return err;
+}
+
+struct ar9170_rf_init {
+ u32 reg, _5ghz, _2ghz;
+};
+
+static struct ar9170_rf_init ar9170_rf_init[] = {
+ /* bank 0 */
+ { 0x1c58b0, 0x1e5795e5, 0x1e5795e5},
+ { 0x1c58e0, 0x02008020, 0x02008020},
+ /* bank 1 */
+ { 0x1c58b0, 0x02108421, 0x02108421},
+ { 0x1c58ec, 0x00000008, 0x00000008},
+ /* bank 2 */
+ { 0x1c58b0, 0x0e73ff17, 0x0e73ff17},
+ { 0x1c58e0, 0x00000420, 0x00000420},
+ /* bank 3 */
+ { 0x1c58f0, 0x01400018, 0x01c00018},
+ /* bank 4 */
+ { 0x1c58b0, 0x000001a1, 0x000001a1},
+ { 0x1c58e8, 0x00000001, 0x00000001},
+ /* bank 5 */
+ { 0x1c58b0, 0x00000013, 0x00000013},
+ { 0x1c58e4, 0x00000002, 0x00000002},
+ /* bank 6 */
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00004000, 0x00004000},
+ { 0x1c58b0, 0x00006c00, 0x00006c00},
+ { 0x1c58b0, 0x00002c00, 0x00002c00},
+ { 0x1c58b0, 0x00004800, 0x00004800},
+ { 0x1c58b0, 0x00004000, 0x00004000},
+ { 0x1c58b0, 0x00006000, 0x00006000},
+ { 0x1c58b0, 0x00001000, 0x00001000},
+ { 0x1c58b0, 0x00004000, 0x00004000},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00087c00, 0x00087c00},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00005400, 0x00005400},
+ { 0x1c58b0, 0x00000c00, 0x00000c00},
+ { 0x1c58b0, 0x00001800, 0x00001800},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00006c00, 0x00006c00},
+ { 0x1c58b0, 0x00006c00, 0x00006c00},
+ { 0x1c58b0, 0x00007c00, 0x00007c00},
+ { 0x1c58b0, 0x00002c00, 0x00002c00},
+ { 0x1c58b0, 0x00003c00, 0x00003c00},
+ { 0x1c58b0, 0x00003800, 0x00003800},
+ { 0x1c58b0, 0x00001c00, 0x00001c00},
+ { 0x1c58b0, 0x00000800, 0x00000800},
+ { 0x1c58b0, 0x00000408, 0x00000408},
+ { 0x1c58b0, 0x00004c15, 0x00004c15},
+ { 0x1c58b0, 0x00004188, 0x00004188},
+ { 0x1c58b0, 0x0000201e, 0x0000201e},
+ { 0x1c58b0, 0x00010408, 0x00010408},
+ { 0x1c58b0, 0x00000801, 0x00000801},
+ { 0x1c58b0, 0x00000c08, 0x00000c08},
+ { 0x1c58b0, 0x0000181e, 0x0000181e},
+ { 0x1c58b0, 0x00001016, 0x00001016},
+ { 0x1c58b0, 0x00002800, 0x00002800},
+ { 0x1c58b0, 0x00004010, 0x00004010},
+ { 0x1c58b0, 0x0000081c, 0x0000081c},
+ { 0x1c58b0, 0x00000115, 0x00000115},
+ { 0x1c58b0, 0x00000015, 0x00000015},
+ { 0x1c58b0, 0x00000066, 0x00000066},
+ { 0x1c58b0, 0x0000001c, 0x0000001c},
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00000004, 0x00000004},
+ { 0x1c58b0, 0x00000015, 0x00000015},
+ { 0x1c58b0, 0x0000001f, 0x0000001f},
+ { 0x1c58e0, 0x00000000, 0x00000400},
+ /* bank 7 */
+ { 0x1c58b0, 0x000000a0, 0x000000a0},
+ { 0x1c58b0, 0x00000000, 0x00000000},
+ { 0x1c58b0, 0x00000040, 0x00000040},
+ { 0x1c58f0, 0x0000001c, 0x0000001c},
+};
+
+static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
+{
+ int err, i;
+
+ ar9170_regwrite_begin(ar);
+
+ for (i = 0; i < ARRAY_SIZE(ar9170_rf_init); i++)
+ ar9170_regwrite(ar9170_rf_init[i].reg,
+ band5ghz ? ar9170_rf_init[i]._5ghz
+ : ar9170_rf_init[i]._2ghz);
+
+ ar9170_regwrite_finish();
+ err = ar9170_regwrite_result();
+ if (err)
+ printk(KERN_ERR "%s: rf init failed\n",
+ wiphy_name(ar->hw->wiphy));
+ return err;
+}
+
+static int ar9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
+ u32 freq, enum ar9170_bw bw)
+{
+ int err;
+ u32 d0, d1, td0, td1, fd0, fd1;
+ u8 chansel;
+ u8 refsel0 = 1, refsel1 = 0;
+ u8 lf_synth = 0;
+
+ switch (bw) {
+ case AR9170_BW_40_ABOVE:
+ freq += 10;
+ break;
+ case AR9170_BW_40_BELOW:
+ freq -= 10;
+ break;
+ case AR9170_BW_20:
+ break;
+ case __AR9170_NUM_BW:
+ BUG();
+ }
+
+ if (band5ghz) {
+ if (freq % 10) {
+ chansel = (freq - 4800) / 5;
+ } else {
+ chansel = ((freq - 4800) / 10) * 2;
+ refsel0 = 0;
+ refsel1 = 1;
+ }
+ chansel = byte_rev_table[chansel];
+ } else {
+ if (freq == 2484) {
+ chansel = 10 + (freq - 2274) / 5;
+ lf_synth = 1;
+ } else
+ chansel = 16 + (freq - 2272) / 5;
+ chansel *= 4;
+ chansel = byte_rev_table[chansel];
+ }
+
+ d1 = chansel;
+ d0 = 0x21 |
+ refsel0 << 3 |
+ refsel1 << 2 |
+ lf_synth << 1;
+ td0 = d0 & 0x1f;
+ td1 = d1 & 0x1f;
+ fd0 = td1 << 5 | td0;
+
+ td0 = (d0 >> 5) & 0x7;
+ td1 = (d1 >> 5) & 0x7;
+ fd1 = td1 << 5 | td0;
+
+ ar9170_regwrite_begin(ar);
+
+ ar9170_regwrite(0x1c58b0, fd0);
+ ar9170_regwrite(0x1c58e8, fd1);
+
+ ar9170_regwrite_finish();
+ err = ar9170_regwrite_result();
+ if (err)
+ return err;
+
+ msleep(10);
+
+ return 0;
+}
+
+struct ar9170_phy_freq_params {
+ u8 coeff_exp;
+ u16 coeff_man;
+ u8 coeff_exp_shgi;
+ u16 coeff_man_shgi;
+};
+
+struct ar9170_phy_freq_entry {
+ u16 freq;
+ struct ar9170_phy_freq_params params[__AR9170_NUM_BW];
+};
+
+/* NB: must be in sync with channel tables in main! */
+static const struct ar9170_phy_freq_entry ar9170_phy_freq_params[] = {
+/*
+ * freq,
+ * 20MHz,
+ * 40MHz (below),
+ * 40Mhz (above),
+ */
+ { 2412, {
+ { 3, 21737, 3, 19563, },
+ { 3, 21827, 3, 19644, },
+ { 3, 21647, 3, 19482, },
+ } },
+ { 2417, {
+ { 3, 21692, 3, 19523, },
+ { 3, 21782, 3, 19604, },
+ { 3, 21602, 3, 19442, },
+ } },
+ { 2422, {
+ { 3, 21647, 3, 19482, },
+ { 3, 21737, 3, 19563, },
+ { 3, 21558, 3, 19402, },
+ } },
+ { 2427, {
+ { 3, 21602, 3, 19442, },
+ { 3, 21692, 3, 19523, },
+ { 3, 21514, 3, 19362, },
+ } },
+ { 2432, {
+ { 3, 21558, 3, 19402, },
+ { 3, 21647, 3, 19482, },
+ { 3, 21470, 3, 19323, },
+ } },
+ { 2437, {
+ { 3, 21514, 3, 19362, },
+ { 3, 21602, 3, 19442, },
+ { 3, 21426, 3, 19283, },
+ } },
+ { 2442, {
+ { 3, 21470, 3, 19323, },
+ { 3, 21558, 3, 19402, },
+ { 3, 21382, 3, 19244, },
+ } },
+ { 2447, {
+ { 3, 21426, 3, 19283, },
+ { 3, 21514, 3, 19362, },
+ { 3, 21339, 3, 19205, },
+ } },
+ { 2452, {
+ { 3, 21382, 3, 19244, },
+ { 3, 21470, 3, 19323, },
+ { 3, 21295, 3, 19166, },
+ } },
+ { 2457, {
+ { 3, 21339, 3, 19205, },
+ { 3, 21426, 3, 19283, },
+ { 3, 21252, 3, 19127, },
+ } },
+ { 2462, {
+ { 3, 21295, 3, 19166, },
+ { 3, 21382, 3, 19244, },
+ { 3, 21209, 3, 19088, },
+ } },
+ { 2467, {
+ { 3, 21252, 3, 19127, },
+ { 3, 21339, 3, 19205, },
+ { 3, 21166, 3, 19050, },
+ } },
+ { 2472, {
+ { 3, 21209, 3, 19088, },
+ { 3, 21295, 3, 19166, },
+ { 3, 21124, 3, 19011, },
+ } },
+ { 2484, {
+ { 3, 21107, 3, 18996, },
+ { 3, 21192, 3, 19073, },
+ { 3, 21022, 3, 18920, },
+ } },
+ { 4920, {
+ { 4, 21313, 4, 19181, },
+ { 4, 21356, 4, 19220, },
+ { 4, 21269, 4, 19142, },
+ } },
+ { 4940, {
+ { 4, 21226, 4, 19104, },
+ { 4, 21269, 4, 19142, },
+ { 4, 21183, 4, 19065, },
+ } },
+ { 4960, {
+ { 4, 21141, 4, 19027, },
+ { 4, 21183, 4, 19065, },
+ { 4, 21098, 4, 18988, },
+ } },
+ { 4980, {
+ { 4, 21056, 4, 18950, },
+ { 4, 21098, 4, 18988, },
+ { 4, 21014, 4, 18912, },
+ } },
+ { 5040, {
+ { 4, 20805, 4, 18725, },
+ { 4, 20846, 4, 18762, },
+ { 4, 20764, 4, 18687, },
+ } },
+ { 5060, {
+ { 4, 20723, 4, 18651, },
+ { 4, 20764, 4, 18687, },
+ { 4, 20682, 4, 18614, },
+ } },
+ { 5080, {
+ { 4, 20641, 4, 18577, },
+ { 4, 20682, 4, 18614, },
+ { 4, 20601, 4, 18541, },
+ } },
+ { 5180, {
+ { 4, 20243, 4, 18219, },
+ { 4, 20282, 4, 18254, },
+ { 4, 20204, 4, 18183, },
+ } },
+ { 5200, {
+ { 4, 20165, 4, 18148, },
+ { 4, 20204, 4, 18183, },
+ { 4, 20126, 4, 18114, },
+ } },
+ { 5220, {
+ { 4, 20088, 4, 18079, },
+ { 4, 20126, 4, 18114, },
+ { 4, 20049, 4, 18044, },
+ } },
+ { 5240, {
+ { 4, 20011, 4, 18010, },
+ { 4, 20049, 4, 18044, },
+ { 4, 19973, 4, 17976, },
+ } },
+ { 5260, {
+ { 4, 19935, 4, 17941, },
+ { 4, 19973, 4, 17976, },
+ { 4, 19897, 4, 17907, },
+ } },
+ { 5280, {
+ { 4, 19859, 4, 17873, },
+ { 4, 19897, 4, 17907, },
+ { 4, 19822, 4, 17840, },
+ } },
+ { 5300, {
+ { 4, 19784, 4, 17806, },
+ { 4, 19822, 4, 17840, },
+ { 4, 19747, 4, 17772, },
+ } },
+ { 5320, {
+ { 4, 19710, 4, 17739, },
+ { 4, 19747, 4, 17772, },
+ { 4, 19673, 4, 17706, },
+ } },
+ { 5500, {
+ { 4, 19065, 4, 17159, },
+ { 4, 19100, 4, 17190, },
+ { 4, 19030, 4, 17127, },
+ } },
+ { 5520, {
+ { 4, 18996, 4, 17096, },
+ { 4, 19030, 4, 17127, },
+ { 4, 18962, 4, 17065, },
+ } },
+ { 5540, {
+ { 4, 18927, 4, 17035, },
+ { 4, 18962, 4, 17065, },
+ { 4, 18893, 4, 17004, },
+ } },
+ { 5560, {
+ { 4, 18859, 4, 16973, },
+ { 4, 18893, 4, 17004, },
+ { 4, 18825, 4, 16943, },
+ } },
+ { 5580, {
+ { 4, 18792, 4, 16913, },
+ { 4, 18825, 4, 16943, },
+ { 4, 18758, 4, 16882, },
+ } },
+ { 5600, {
+ { 4, 18725, 4, 16852, },
+ { 4, 18758, 4, 16882, },
+ { 4, 18691, 4, 16822, },
+ } },
+ { 5620, {
+ { 4, 18658, 4, 16792, },
+ { 4, 18691, 4, 16822, },
+ { 4, 18625, 4, 16762, },
+ } },
+ { 5640, {
+ { 4, 18592, 4, 16733, },
+ { 4, 18625, 4, 16762, },
+ { 4, 18559, 4, 16703, },
+ } },
+ { 5660, {
+ { 4, 18526, 4, 16673, },
+ { 4, 18559, 4, 16703, },
+ { 4, 18493, 4, 16644, },
+ } },
+ { 5680, {
+ { 4, 18461, 4, 16615, },
+ { 4, 18493, 4, 16644, },
+ { 4, 18428, 4, 16586, },
+ } },
+ { 5700, {
+ { 4, 18396, 4, 16556, },
+ { 4, 18428, 4, 16586, },
+ { 4, 18364, 4, 16527, },
+ } },
+ { 5745, {
+ { 4, 18252, 4, 16427, },
+ { 4, 18284, 4, 16455, },
+ { 4, 18220, 4, 16398, },
+ } },
+ { 5765, {
+ { 4, 18189, 5, 32740, },
+ { 4, 18220, 4, 16398, },
+ { 4, 18157, 5, 32683, },
+ } },
+ { 5785, {
+ { 4, 18126, 5, 32626, },
+ { 4, 18157, 5, 32683, },
+ { 4, 18094, 5, 32570, },
+ } },
+ { 5805, {
+ { 4, 18063, 5, 32514, },
+ { 4, 18094, 5, 32570, },
+ { 4, 18032, 5, 32458, },
+ } },
+ { 5825, {
+ { 4, 18001, 5, 32402, },
+ { 4, 18032, 5, 32458, },
+ { 4, 17970, 5, 32347, },
+ } },
+ { 5170, {
+ { 4, 20282, 4, 18254, },
+ { 4, 20321, 4, 18289, },
+ { 4, 20243, 4, 18219, },
+ } },
+ { 5190, {
+ { 4, 20204, 4, 18183, },
+ { 4, 20243, 4, 18219, },
+ { 4, 20165, 4, 18148, },
+ } },
+ { 5210, {
+ { 4, 20126, 4, 18114, },
+ { 4, 20165, 4, 18148, },
+ { 4, 20088, 4, 18079, },
+ } },
+ { 5230, {
+ { 4, 20049, 4, 18044, },
+ { 4, 20088, 4, 18079, },
+ { 4, 20011, 4, 18010, },
+ } },
+};
+
+static const struct ar9170_phy_freq_params *
+ar9170_get_hw_dyn_params(struct ieee80211_channel *channel,
+ enum ar9170_bw bw)
+{
+ unsigned int chanidx = 0;
+ u16 freq = 2412;
+
+ if (channel) {
+ chanidx = channel->hw_value;
+ freq = channel->center_freq;
+ }
+
+ BUG_ON(chanidx >= ARRAY_SIZE(ar9170_phy_freq_params));
+
+ BUILD_BUG_ON(__AR9170_NUM_BW != 3);
+
+ WARN_ON(ar9170_phy_freq_params[chanidx].freq != freq);
+
+ return &ar9170_phy_freq_params[chanidx].params[bw];
+}
+
+
+int ar9170_init_rf(struct ar9170 *ar)
+{
+ const struct ar9170_phy_freq_params *freqpar;
+ __le32 cmd[7];
+ int err;
+
+ err = ar9170_init_rf_banks_0_7(ar, false);
+ if (err)
+ return err;
+
+ err = ar9170_init_rf_bank4_pwr(ar, false, 2412, AR9170_BW_20);
+ if (err)
+ return err;
+
+ freqpar = ar9170_get_hw_dyn_params(NULL, AR9170_BW_20);
+
+ cmd[0] = cpu_to_le32(2412 * 1000);
+ cmd[1] = cpu_to_le32(0);
+ cmd[2] = cpu_to_le32(1);
+ cmd[3] = cpu_to_le32(freqpar->coeff_exp);
+ cmd[4] = cpu_to_le32(freqpar->coeff_man);
+ cmd[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
+ cmd[6] = cpu_to_le32(freqpar->coeff_man_shgi);
+
+ /* RF_INIT echoes the command back to us */
+ err = ar->exec_cmd(ar, AR9170_CMD_RF_INIT,
+ sizeof(cmd), (u8 *)cmd,
+ sizeof(cmd), (u8 *)cmd);
+ if (err)
+ return err;
+
+ msleep(1000);
+
+ return ar9170_echo_test(ar, 0xaabbccdd);
+}
+
+static int ar9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f)
+{
+ int idx = nfreqs - 2;
+
+ while (idx >= 0) {
+ if (f >= freqs[idx])
+ return idx;
+ idx--;
+ }
+
+ return 0;
+}
+
+static s32 ar9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
+{
+ /* nothing to interpolate, it's horizontal */
+ if (y2 == y1)
+ return y1;
+
+ /* check if we hit one of the edges */
+ if (x == x1)
+ return y1;
+ if (x == x2)
+ return y2;
+
+ /* x1 == x2 is bad, hopefully == x */
+ if (x2 == x1)
+ return y1;
+
+ return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1));
+}
+
+static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
+{
+#define SHIFT 8
+ s32 y;
+
+ y = ar9170_interpolate_s32(x << SHIFT,
+ x1 << SHIFT, y1 << SHIFT,
+ x2 << SHIFT, y2 << SHIFT);
+
+ /*
+ * XXX: unwrap this expression
+ * Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)?
+ * Can we rely on the compiler to optimise away the div?
+ */
+ return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1));
+#undef SHIFT
+}
+
+static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
+{
+ struct ar9170_calibration_target_power_legacy *ctpl;
+ struct ar9170_calibration_target_power_ht *ctph;
+ u8 *ctpres;
+ int ntargets;
+ int idx, i, n;
+ u8 ackpower, ackchains, f;
+ u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
+
+ if (freq < 3000)
+ f = freq - 2300;
+ else
+ f = (freq - 4800)/5;
+
+ /*
+ * cycle through the various modes
+ *
+ * legacy modes first: 5G, 2G CCK, 2G OFDM
+ */
+ for (i = 0; i < 3; i++) {
+ switch (i) {
+ case 0: /* 5 GHz legacy */
+ ctpl = &ar->eeprom.cal_tgt_pwr_5G[0];
+ ntargets = AR5416_NUM_5G_TARGET_PWRS;
+ ctpres = ar->power_5G_leg;
+ break;
+ case 1: /* 2.4 GHz CCK */
+ ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0];
+ ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS;
+ ctpres = ar->power_2G_cck;
+ break;
+ case 2: /* 2.4 GHz OFDM */
+ ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0];
+ ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+ ctpres = ar->power_2G_ofdm;
+ break;
+ default:
+ BUG();
+ }
+
+ for (n = 0; n < ntargets; n++) {
+ if (ctpl[n].freq == 0xff)
+ break;
+ pwr_freqs[n] = ctpl[n].freq;
+ }
+ ntargets = n;
+ idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
+ for (n = 0; n < 4; n++)
+ ctpres[n] = ar9170_interpolate_u8(
+ f,
+ ctpl[idx + 0].freq,
+ ctpl[idx + 0].power[n],
+ ctpl[idx + 1].freq,
+ ctpl[idx + 1].power[n]);
+ }
+
+ /*
+ * HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40
+ */
+ for (i = 0; i < 4; i++) {
+ switch (i) {
+ case 0: /* 5 GHz HT 20 */
+ ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0];
+ ntargets = AR5416_NUM_5G_TARGET_PWRS;
+ ctpres = ar->power_5G_ht20;
+ break;
+ case 1: /* 5 GHz HT 40 */
+ ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0];
+ ntargets = AR5416_NUM_5G_TARGET_PWRS;
+ ctpres = ar->power_5G_ht40;
+ break;
+ case 2: /* 2.4 GHz HT 20 */
+ ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0];
+ ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+ ctpres = ar->power_2G_ht20;
+ break;
+ case 3: /* 2.4 GHz HT 40 */
+ ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0];
+ ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+ ctpres = ar->power_2G_ht40;
+ break;
+ default:
+ BUG();
+ }
+
+ for (n = 0; n < ntargets; n++) {
+ if (ctph[n].freq == 0xff)
+ break;
+ pwr_freqs[n] = ctph[n].freq;
+ }
+ ntargets = n;
+ idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
+ for (n = 0; n < 8; n++)
+ ctpres[n] = ar9170_interpolate_u8(
+ f,
+ ctph[idx + 0].freq,
+ ctph[idx + 0].power[n],
+ ctph[idx + 1].freq,
+ ctph[idx + 1].power[n]);
+ }
+
+ /* set ACK/CTS TX power */
+ ar9170_regwrite_begin(ar);
+
+ if (ar->eeprom.tx_mask != 1)
+ ackchains = AR9170_TX_PHY_TXCHAIN_2;
+ else
+ ackchains = AR9170_TX_PHY_TXCHAIN_1;
+
+ if (freq < 3000)
+ ackpower = ar->power_2G_ofdm[0] & 0x3f;
+ else
+ ackpower = ar->power_5G_leg[0] & 0x3f;
+
+ ar9170_regwrite(0x1c3694, ackpower << 20 | ackchains << 26);
+ ar9170_regwrite(0x1c3bb4, ackpower << 5 | ackchains << 11 |
+ ackpower << 21 | ackchains << 27);
+
+ ar9170_regwrite_finish();
+ return ar9170_regwrite_result();
+}
+
+static int ar9170_calc_noise_dbm(u32 raw_noise)
+{
+ if (raw_noise & 0x100)
+ return ~((raw_noise & 0x0ff) >> 1);
+ else
+ return (raw_noise & 0xff) >> 1;
+}
+
+int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
+ enum ar9170_rf_init_mode rfi, enum ar9170_bw bw)
+{
+ const struct ar9170_phy_freq_params *freqpar;
+ u32 cmd, tmp, offs;
+ __le32 vals[8];
+ int i, err;
+ bool bandswitch;
+
+ /* clear BB heavy clip enable */
+ err = ar9170_write_reg(ar, 0x1c59e0, 0x200);
+ if (err)
+ return err;
+
+ /* may be NULL at first setup */
+ if (ar->channel)
+ bandswitch = ar->channel->band != channel->band;
+ else
+ bandswitch = true;
+
+ /* HW workaround */
+ if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] &&
+ channel->center_freq <= 2417)
+ bandswitch = true;
+
+ err = ar->exec_cmd(ar, AR9170_CMD_FREQ_START, 0, NULL, 0, NULL);
+ if (err)
+ return err;
+
+ if (rfi != AR9170_RFI_NONE || bandswitch) {
+ u32 val = 0x400;
+
+ if (rfi == AR9170_RFI_COLD)
+ val = 0x800;
+
+ /* warm/cold reset BB/ADDA */
+ err = ar9170_write_reg(ar, 0x1d4004, val);
+ if (err)
+ return err;
+
+ err = ar9170_write_reg(ar, 0x1d4004, 0x0);
+ if (err)
+ return err;
+
+ err = ar9170_init_phy(ar, channel->band);
+ if (err)
+ return err;
+
+ err = ar9170_init_rf_banks_0_7(ar,
+ channel->band == IEEE80211_BAND_5GHZ);
+ if (err)
+ return err;
+
+ cmd = AR9170_CMD_RF_INIT;
+ } else {
+ cmd = AR9170_CMD_FREQUENCY;
+ }
+
+ err = ar9170_init_rf_bank4_pwr(ar,
+ channel->band == IEEE80211_BAND_5GHZ,
+ channel->center_freq, bw);
+ if (err)
+ return err;
+
+ switch (bw) {
+ case AR9170_BW_20:
+ tmp = 0x240;
+ offs = 0;
+ break;
+ case AR9170_BW_40_BELOW:
+ tmp = 0x2c4;
+ offs = 3;
+ break;
+ case AR9170_BW_40_ABOVE:
+ tmp = 0x2d4;
+ offs = 1;
+ break;
+ default:
+ BUG();
+ return -ENOSYS;
+ }
+
+ if (0 /* 2 streams capable */)
+ tmp |= 0x100;
+
+ err = ar9170_write_reg(ar, 0x1c5804, tmp);
+ if (err)
+ return err;
+
+ err = ar9170_set_power_cal(ar, channel->center_freq, bw);
+ if (err)
+ return err;
+
+ freqpar = ar9170_get_hw_dyn_params(channel, bw);
+
+ vals[0] = cpu_to_le32(channel->center_freq * 1000);
+ vals[1] = cpu_to_le32(bw == AR9170_BW_20 ? 0 : 1);
+ vals[2] = cpu_to_le32(offs << 2 | 1);
+ vals[3] = cpu_to_le32(freqpar->coeff_exp);
+ vals[4] = cpu_to_le32(freqpar->coeff_man);
+ vals[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
+ vals[6] = cpu_to_le32(freqpar->coeff_man_shgi);
+ vals[7] = cpu_to_le32(1000);
+
+ err = ar->exec_cmd(ar, cmd, sizeof(vals), (u8 *)vals,
+ sizeof(vals), (u8 *)vals);
+ if (err)
+ return err;
+
+ for (i = 0; i < 2; i++) {
+ ar->noise[i] = ar9170_calc_noise_dbm(
+ (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff);
+
+ ar->noise[i + 2] = ar9170_calc_noise_dbm(
+ (le32_to_cpu(vals[5 + i]) >> 23) & 0x1ff);
+ }
+
+ ar->channel = channel;
+ return 0;
+}
diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ar9170/usb.c
new file mode 100644
index 000000000000..ad296840893e
--- /dev/null
+++ b/drivers/net/wireless/ar9170/usb.c
@@ -0,0 +1,748 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * USB - frontend
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, Christian Lamparter <chunkeey@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include "ar9170.h"
+#include "cmd.h"
+#include "hw.h"
+#include "usb.h"
+
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
+MODULE_FIRMWARE("ar9170-1.fw");
+MODULE_FIRMWARE("ar9170-2.fw");
+
+static struct usb_device_id ar9170_usb_ids[] = {
+ /* Atheros 9170 */
+ { USB_DEVICE(0x0cf3, 0x9170) },
+ /* Atheros TG121N */
+ { USB_DEVICE(0x0cf3, 0x1001) },
+ /* D-Link DWA 160A */
+ { USB_DEVICE(0x07d1, 0x3c10) },
+ /* Netgear WNDA3100 */
+ { USB_DEVICE(0x0846, 0x9010) },
+ /* Netgear WN111 v2 */
+ { USB_DEVICE(0x0846, 0x9001) },
+ /* Zydas ZD1221 */
+ { USB_DEVICE(0x0ace, 0x1221) },
+ /* Z-Com UB81 BG */
+ { USB_DEVICE(0x0cde, 0x0023) },
+ /* Z-Com UB82 ABG */
+ { USB_DEVICE(0x0cde, 0x0026) },
+ /* Arcadyan WN7512 */
+ { USB_DEVICE(0x083a, 0xf522) },
+ /* Planex GWUS300 */
+ { USB_DEVICE(0x2019, 0x5304) },
+ /* IO-Data WNGDNUS2 */
+ { USB_DEVICE(0x04bb, 0x093f) },
+
+ /* terminate */
+ {}
+};
+MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
+
+static void ar9170_usb_tx_urb_complete_free(struct urb *urb)
+{
+ struct sk_buff *skb = urb->context;
+ struct ar9170_usb *aru = (struct ar9170_usb *)
+ usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+
+ if (!aru) {
+ dev_kfree_skb_irq(skb);
+ return ;
+ }
+
+ ar9170_handle_tx_status(&aru->common, skb, false,
+ AR9170_TX_STATUS_COMPLETE);
+}
+
+static void ar9170_usb_tx_urb_complete(struct urb *urb)
+{
+}
+
+static void ar9170_usb_irq_completed(struct urb *urb)
+{
+ struct ar9170_usb *aru = urb->context;
+
+ switch (urb->status) {
+ /* everything is fine */
+ case 0:
+ break;
+
+ /* disconnect */
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ENODEV:
+ case -ESHUTDOWN:
+ goto free;
+
+ default:
+ goto resubmit;
+ }
+
+ print_hex_dump_bytes("ar9170 irq: ", DUMP_PREFIX_OFFSET,
+ urb->transfer_buffer, urb->actual_length);
+
+resubmit:
+ usb_anchor_urb(urb, &aru->rx_submitted);
+ if (usb_submit_urb(urb, GFP_ATOMIC)) {
+ usb_unanchor_urb(urb);
+ goto free;
+ }
+
+ return;
+
+free:
+ usb_buffer_free(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
+}
+
+static void ar9170_usb_rx_completed(struct urb *urb)
+{
+ struct sk_buff *skb = urb->context;
+ struct ar9170_usb *aru = (struct ar9170_usb *)
+ usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+ int err;
+
+ if (!aru)
+ goto free;
+
+ switch (urb->status) {
+ /* everything is fine */
+ case 0:
+ break;
+
+ /* disconnect */
+ case -ENOENT:
+ case -ECONNRESET:
+ case -ENODEV:
+ case -ESHUTDOWN:
+ goto free;
+
+ default:
+ goto resubmit;
+ }
+
+ skb_put(skb, urb->actual_length);
+ ar9170_rx(&aru->common, skb);
+
+resubmit:
+ skb_reset_tail_pointer(skb);
+ skb_trim(skb, 0);
+
+ usb_anchor_urb(urb, &aru->rx_submitted);
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err) {
+ usb_unanchor_urb(urb);
+ dev_kfree_skb_irq(skb);
+ }
+
+ return ;
+
+free:
+ dev_kfree_skb_irq(skb);
+ return;
+}
+
+static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
+ struct urb *urb, gfp_t gfp)
+{
+ struct sk_buff *skb;
+
+ skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp);
+ if (!skb)
+ return -ENOMEM;
+
+ /* reserve some space for mac80211's radiotap */
+ skb_reserve(skb, 32);
+
+ usb_fill_bulk_urb(urb, aru->udev,
+ usb_rcvbulkpipe(aru->udev, AR9170_EP_RX),
+ skb->data, min(skb_tailroom(skb),
+ AR9170_MAX_RX_BUFFER_SIZE),
+ ar9170_usb_rx_completed, skb);
+
+ return 0;
+}
+
+static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
+{
+ struct urb *urb = NULL;
+ void *ibuf;
+ int err = -ENOMEM;
+
+ /* initialize interrupt endpoint */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb)
+ goto out;
+
+ ibuf = usb_buffer_alloc(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
+ if (!ibuf)
+ goto out;
+
+ usb_fill_int_urb(urb, aru->udev,
+ usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf,
+ 64, ar9170_usb_irq_completed, aru, 1);
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ usb_anchor_urb(urb, &aru->rx_submitted);
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err) {
+ usb_unanchor_urb(urb);
+ usb_buffer_free(aru->udev, 64, urb->transfer_buffer,
+ urb->transfer_dma);
+ }
+
+out:
+ usb_free_urb(urb);
+ return err;
+}
+
+static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru)
+{
+ struct urb *urb;
+ int i;
+ int err = -EINVAL;
+
+ for (i = 0; i < AR9170_NUM_RX_URBS; i++) {
+ err = -ENOMEM;
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb)
+ goto err_out;
+
+ err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL);
+ if (err) {
+ usb_free_urb(urb);
+ goto err_out;
+ }
+
+ usb_anchor_urb(urb, &aru->rx_submitted);
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err) {
+ usb_unanchor_urb(urb);
+ dev_kfree_skb_any((void *) urb->transfer_buffer);
+ usb_free_urb(urb);
+ goto err_out;
+ }
+ usb_free_urb(urb);
+ }
+
+ /* the device now waiting for a firmware. */
+ aru->common.state = AR9170_IDLE;
+ return 0;
+
+err_out:
+
+ usb_kill_anchored_urbs(&aru->rx_submitted);
+ return err;
+}
+
+static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
+{
+ int ret;
+
+ aru->common.state = AR9170_UNKNOWN_STATE;
+
+ usb_unlink_anchored_urbs(&aru->tx_submitted);
+
+ /* give the LED OFF command and the deauth frame a chance to air. */
+ ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
+ msecs_to_jiffies(100));
+ if (ret == 0)
+ dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
+ usb_poison_anchored_urbs(&aru->tx_submitted);
+
+ usb_poison_anchored_urbs(&aru->rx_submitted);
+}
+
+static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
+ unsigned int plen, void *payload,
+ unsigned int outlen, void *out)
+{
+ struct ar9170_usb *aru = (void *) ar;
+ struct urb *urb = NULL;
+ unsigned long flags;
+ int err = -ENOMEM;
+
+ if (unlikely(!IS_ACCEPTING_CMD(ar)))
+ return -EPERM;
+
+ if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
+ return -EINVAL;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (unlikely(!urb))
+ goto err_free;
+
+ ar->cmdbuf[0] = cpu_to_le32(plen);
+ ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
+ /* writing multiple regs fills this buffer already */
+ if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
+ memcpy(&ar->cmdbuf[1], payload, plen);
+
+ spin_lock_irqsave(&aru->common.cmdlock, flags);
+ aru->readbuf = (u8 *)out;
+ aru->readlen = outlen;
+ spin_unlock_irqrestore(&aru->common.cmdlock, flags);
+
+ usb_fill_int_urb(urb, aru->udev,
+ usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
+ aru->common.cmdbuf, plen + 4,
+ ar9170_usb_tx_urb_complete, NULL, 1);
+
+ usb_anchor_urb(urb, &aru->tx_submitted);
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err) {
+ usb_unanchor_urb(urb);
+ usb_free_urb(urb);
+ goto err_unbuf;
+ }
+ usb_free_urb(urb);
+
+ err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
+ if (err == 0) {
+ err = -ETIMEDOUT;
+ goto err_unbuf;
+ }
+
+ if (outlen >= 0 && aru->readlen != outlen) {
+ err = -EMSGSIZE;
+ goto err_unbuf;
+ }
+
+ return 0;
+
+err_unbuf:
+ /* Maybe the device was removed in the second we were waiting? */
+ if (IS_STARTED(ar)) {
+ dev_err(&aru->udev->dev, "no command feedback "
+ "received (%d).\n", err);
+
+ /* provide some maybe useful debug information */
+ print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
+ aru->common.cmdbuf, plen + 4);
+ dump_stack();
+ }
+
+ /* invalidate to avoid completing the next prematurely */
+ spin_lock_irqsave(&aru->common.cmdlock, flags);
+ aru->readbuf = NULL;
+ aru->readlen = 0;
+ spin_unlock_irqrestore(&aru->common.cmdlock, flags);
+
+err_free:
+
+ return err;
+}
+
+static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb,
+ bool txstatus_needed, unsigned int extra_len)
+{
+ struct ar9170_usb *aru = (struct ar9170_usb *) ar;
+ struct urb *urb;
+ int err;
+
+ if (unlikely(!IS_STARTED(ar))) {
+ /* Seriously, what were you drink... err... thinking!? */
+ return -EPERM;
+ }
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (unlikely(!urb))
+ return -ENOMEM;
+
+ usb_fill_bulk_urb(urb, aru->udev,
+ usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
+ skb->data, skb->len + extra_len, (txstatus_needed ?
+ ar9170_usb_tx_urb_complete :
+ ar9170_usb_tx_urb_complete_free), skb);
+ urb->transfer_flags |= URB_ZERO_PACKET;
+
+ usb_anchor_urb(urb, &aru->tx_submitted);
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (unlikely(err))
+ usb_unanchor_urb(urb);
+
+ usb_free_urb(urb);
+ return err;
+}
+
+static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
+{
+ struct ar9170_usb *aru = (void *) ar;
+ unsigned long flags;
+ u32 in, out;
+
+ if (!buffer)
+ return ;
+
+ in = le32_to_cpup((__le32 *)buffer);
+ out = le32_to_cpu(ar->cmdbuf[0]);
+
+ /* mask off length byte */
+ out &= ~0xFF;
+
+ if (aru->readlen >= 0) {
+ /* add expected length */
+ out |= aru->readlen;
+ } else {
+ /* add obtained length */
+ out |= in & 0xFF;
+ }
+
+ /*
+ * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response
+ * length and we cannot predict the correct length in advance.
+ * So we only check if we provided enough space for the data.
+ */
+ if (unlikely(out < in)) {
+ dev_warn(&aru->udev->dev, "received invalid command response "
+ "got %d bytes, instead of %d bytes "
+ "and the resp length is %d bytes\n",
+ in, out, len);
+ print_hex_dump_bytes("ar9170 invalid resp: ",
+ DUMP_PREFIX_OFFSET, buffer, len);
+ /*
+ * Do not complete, then the command times out,
+ * and we get a stack trace from there.
+ */
+ return ;
+ }
+
+ spin_lock_irqsave(&aru->common.cmdlock, flags);
+ if (aru->readbuf && len > 0) {
+ memcpy(aru->readbuf, buffer + 4, len - 4);
+ aru->readbuf = NULL;
+ }
+ complete(&aru->cmd_wait);
+ spin_unlock_irqrestore(&aru->common.cmdlock, flags);
+}
+
+static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
+ size_t len, u32 addr, bool complete)
+{
+ int transfer, err;
+ u8 *buf = kmalloc(4096, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+
+ while (len) {
+ transfer = min_t(int, len, 4096);
+ memcpy(buf, data, transfer);
+
+ err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
+ 0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
+ addr >> 8, 0, buf, transfer, 1000);
+
+ if (err < 0) {
+ kfree(buf);
+ return err;
+ }
+
+ len -= transfer;
+ data += transfer;
+ addr += transfer;
+ }
+ kfree(buf);
+
+ if (complete) {
+ err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
+ 0x31 /* FW DL COMPLETE */,
+ 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000);
+ }
+
+ return 0;
+}
+
+static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
+{
+ int err = 0;
+
+ err = request_firmware(&aru->init_values, "ar9170-1.fw",
+ &aru->udev->dev);
+ if (err) {
+ dev_err(&aru->udev->dev, "file with init values not found.\n");
+ return err;
+ }
+
+ err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
+ if (err) {
+ release_firmware(aru->init_values);
+ dev_err(&aru->udev->dev, "firmware file not found.\n");
+ return err;
+ }
+
+ return err;
+}
+
+static int ar9170_usb_reset(struct ar9170_usb *aru)
+{
+ int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
+
+ if (lock) {
+ ret = usb_lock_device_for_reset(aru->udev, aru->intf);
+ if (ret < 0) {
+ dev_err(&aru->udev->dev, "unable to lock device "
+ "for reset (%d).\n", ret);
+ return ret;
+ }
+ }
+
+ ret = usb_reset_device(aru->udev);
+ if (lock)
+ usb_unlock_device(aru->udev);
+
+ /* let it rest - for a second - */
+ msleep(1000);
+
+ return ret;
+}
+
+static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
+{
+ int err;
+
+ /* First, upload initial values to device RAM */
+ err = ar9170_usb_upload(aru, aru->init_values->data,
+ aru->init_values->size, 0x102800, false);
+ if (err) {
+ dev_err(&aru->udev->dev, "firmware part 1 "
+ "upload failed (%d).\n", err);
+ return err;
+ }
+
+ /* Then, upload the firmware itself and start it */
+ return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
+ 0x200000, true);
+}
+
+static int ar9170_usb_init_transport(struct ar9170_usb *aru)
+{
+ struct ar9170 *ar = (void *) &aru->common;
+ int err;
+
+ ar9170_regwrite_begin(ar);
+
+ /* Set USB Rx stream mode MAX packet number to 2 */
+ ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4);
+
+ /* Set USB Rx stream mode timeout to 10us */
+ ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80);
+
+ ar9170_regwrite_finish();
+
+ err = ar9170_regwrite_result();
+ if (err)
+ dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err);
+
+ return err;
+}
+
+static void ar9170_usb_stop(struct ar9170 *ar)
+{
+ struct ar9170_usb *aru = (void *) ar;
+ int ret;
+
+ if (IS_ACCEPTING_CMD(ar))
+ aru->common.state = AR9170_STOPPED;
+
+ /* lets wait a while until the tx - queues are dried out */
+ ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
+ msecs_to_jiffies(1000));
+ if (ret == 0)
+ dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
+
+ usb_poison_anchored_urbs(&aru->tx_submitted);
+
+ /*
+ * Note:
+ * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
+ * Else we would end up with a unresponsive device...
+ */
+}
+
+static int ar9170_usb_open(struct ar9170 *ar)
+{
+ struct ar9170_usb *aru = (void *) ar;
+ int err;
+
+ usb_unpoison_anchored_urbs(&aru->tx_submitted);
+ err = ar9170_usb_init_transport(aru);
+ if (err) {
+ usb_poison_anchored_urbs(&aru->tx_submitted);
+ return err;
+ }
+
+ aru->common.state = AR9170_IDLE;
+ return 0;
+}
+
+static int ar9170_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct ar9170_usb *aru;
+ struct ar9170 *ar;
+ struct usb_device *udev;
+ int err;
+
+ aru = ar9170_alloc(sizeof(*aru));
+ if (IS_ERR(aru)) {
+ err = PTR_ERR(aru);
+ goto out;
+ }
+
+ udev = interface_to_usbdev(intf);
+ usb_get_dev(udev);
+ aru->udev = udev;
+ aru->intf = intf;
+ ar = &aru->common;
+
+ usb_set_intfdata(intf, aru);
+ SET_IEEE80211_DEV(ar->hw, &udev->dev);
+
+ init_usb_anchor(&aru->rx_submitted);
+ init_usb_anchor(&aru->tx_submitted);
+ init_completion(&aru->cmd_wait);
+
+ aru->common.stop = ar9170_usb_stop;
+ aru->common.open = ar9170_usb_open;
+ aru->common.tx = ar9170_usb_tx;
+ aru->common.exec_cmd = ar9170_usb_exec_cmd;
+ aru->common.callback_cmd = ar9170_usb_callback_cmd;
+
+ err = ar9170_usb_reset(aru);
+ if (err)
+ goto err_unlock;
+
+ err = ar9170_usb_request_firmware(aru);
+ if (err)
+ goto err_unlock;
+
+ err = ar9170_usb_alloc_rx_irq_urb(aru);
+ if (err)
+ goto err_freefw;
+
+ err = ar9170_usb_alloc_rx_bulk_urbs(aru);
+ if (err)
+ goto err_unrx;
+
+ err = ar9170_usb_upload_firmware(aru);
+ if (err) {
+ err = ar9170_echo_test(&aru->common, 0x60d43110);
+ if (err) {
+ /* force user invention, by disabling the device */
+ err = usb_driver_set_configuration(aru->udev, -1);
+ dev_err(&aru->udev->dev, "device is in a bad state. "
+ "please reconnect it!\n");
+ goto err_unrx;
+ }
+ }
+
+ err = ar9170_usb_open(ar);
+ if (err)
+ goto err_unrx;
+
+ err = ar9170_register(ar, &udev->dev);
+
+ ar9170_usb_stop(ar);
+ if (err)
+ goto err_unrx;
+
+ return 0;
+
+err_unrx:
+ ar9170_usb_cancel_urbs(aru);
+
+err_freefw:
+ release_firmware(aru->init_values);
+ release_firmware(aru->firmware);
+
+err_unlock:
+ usb_set_intfdata(intf, NULL);
+ usb_put_dev(udev);
+ ieee80211_free_hw(ar->hw);
+out:
+ return err;
+}
+
+static void ar9170_usb_disconnect(struct usb_interface *intf)
+{
+ struct ar9170_usb *aru = usb_get_intfdata(intf);
+
+ if (!aru)
+ return;
+
+ aru->common.state = AR9170_IDLE;
+ ar9170_unregister(&aru->common);
+ ar9170_usb_cancel_urbs(aru);
+
+ release_firmware(aru->init_values);
+ release_firmware(aru->firmware);
+
+ usb_put_dev(aru->udev);
+ usb_set_intfdata(intf, NULL);
+ ieee80211_free_hw(aru->common.hw);
+}
+
+static struct usb_driver ar9170_driver = {
+ .name = "ar9170usb",
+ .probe = ar9170_usb_probe,
+ .disconnect = ar9170_usb_disconnect,
+ .id_table = ar9170_usb_ids,
+ .soft_unbind = 1,
+};
+
+static int __init ar9170_init(void)
+{
+ return usb_register(&ar9170_driver);
+}
+
+static void __exit ar9170_exit(void)
+{
+ usb_deregister(&ar9170_driver);
+}
+
+module_init(ar9170_init);
+module_exit(ar9170_exit);
diff --git a/drivers/net/wireless/ar9170/usb.h b/drivers/net/wireless/ar9170/usb.h
new file mode 100644
index 000000000000..f5852924cd64
--- /dev/null
+++ b/drivers/net/wireless/ar9170/usb.h
@@ -0,0 +1,74 @@
+/*
+ * Atheros AR9170 USB driver
+ *
+ * Driver specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, Christian Lamparter <chunkeey@web.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ * Copyright (c) 2007-2008 Atheros Communications, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef __USB_H
+#define __USB_H
+
+#include <linux/usb.h>
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <linux/leds.h>
+#include <net/wireless.h>
+#include <net/mac80211.h>
+#include <linux/firmware.h>
+#include "eeprom.h"
+#include "hw.h"
+#include "ar9170.h"
+
+#define AR9170_NUM_RX_URBS 16
+
+struct firmware;
+
+struct ar9170_usb {
+ struct ar9170 common;
+ struct usb_device *udev;
+ struct usb_interface *intf;
+
+ struct usb_anchor rx_submitted;
+ struct usb_anchor tx_submitted;
+
+ spinlock_t cmdlock;
+ struct completion cmd_wait;
+ int readlen;
+ u8 *readbuf;
+
+ const struct firmware *init_values;
+ const struct firmware *firmware;
+};
+
+#endif /* __USB_H */
diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c
index 14c11656e82c..a54a67c425c8 100644
--- a/drivers/net/wireless/arlan-main.c
+++ b/drivers/net/wireless/arlan-main.c
@@ -1030,7 +1030,17 @@ static int arlan_mac_addr(struct net_device *dev, void *p)
return 0;
}
-
+static const struct net_device_ops arlan_netdev_ops = {
+ .ndo_open = arlan_open,
+ .ndo_stop = arlan_close,
+ .ndo_start_xmit = arlan_tx,
+ .ndo_get_stats = arlan_statistics,
+ .ndo_set_multicast_list = arlan_set_multicast,
+ .ndo_change_mtu = arlan_change_mtu,
+ .ndo_set_mac_address = arlan_mac_addr,
+ .ndo_tx_timeout = arlan_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+};
static int __init arlan_setup_device(struct net_device *dev, int num)
{
@@ -1042,14 +1052,7 @@ static int __init arlan_setup_device(struct net_device *dev, int num)
ap->conf = (struct arlan_shmem *)(ap+1);
dev->tx_queue_len = tx_queue_len;
- dev->open = arlan_open;
- dev->stop = arlan_close;
- dev->hard_start_xmit = arlan_tx;
- dev->get_stats = arlan_statistics;
- dev->set_multicast_list = arlan_set_multicast;
- dev->change_mtu = arlan_change_mtu;
- dev->set_mac_address = arlan_mac_addr;
- dev->tx_timeout = arlan_tx_timeout;
+ dev->netdev_ops = &arlan_netdev_ops;
dev->watchdog_timeo = 3*HZ;
ap->irq_test_done = 0;
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
new file mode 100644
index 000000000000..0c02f1c2bd94
--- /dev/null
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -0,0 +1,2501 @@
+/*
+ * at76c503/at76c505 USB driver
+ *
+ * Copyright (c) 2002 - 2003 Oliver Kurth
+ * Copyright (c) 2004 Joerg Albert <joerg.albert@gmx.de>
+ * Copyright (c) 2004 Nick Jones
+ * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
+ * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org>
+ * Copyright (c) 2007 Kalle Valo <kalle.valo@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This file is part of the Berlios driver for WLAN USB devices based on the
+ * Atmel AT76C503A/505/505A.
+ *
+ * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
+ *
+ * TODO list is at the wiki:
+ *
+ * http://wireless.kernel.org/en/users/Drivers/at76c50x-usb#TODO
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <net/ieee80211_radiotap.h>
+#include <linux/firmware.h>
+#include <linux/leds.h>
+#include <net/mac80211.h>
+
+#include "at76c50x-usb.h"
+
+/* Version information */
+#define DRIVER_NAME "at76c50x-usb"
+#define DRIVER_VERSION "0.17"
+#define DRIVER_DESC "Atmel at76x USB Wireless LAN Driver"
+
+/* at76_debug bits */
+#define DBG_PROGRESS 0x00000001 /* authentication/accociation */
+#define DBG_BSS_TABLE 0x00000002 /* show BSS table after scans */
+#define DBG_IOCTL 0x00000004 /* ioctl calls / settings */
+#define DBG_MAC_STATE 0x00000008 /* MAC state transitions */
+#define DBG_TX_DATA 0x00000010 /* tx header */
+#define DBG_TX_DATA_CONTENT 0x00000020 /* tx content */
+#define DBG_TX_MGMT 0x00000040 /* tx management */
+#define DBG_RX_DATA 0x00000080 /* rx data header */
+#define DBG_RX_DATA_CONTENT 0x00000100 /* rx data content */
+#define DBG_RX_MGMT 0x00000200 /* rx mgmt frame headers */
+#define DBG_RX_BEACON 0x00000400 /* rx beacon */
+#define DBG_RX_CTRL 0x00000800 /* rx control */
+#define DBG_RX_MGMT_CONTENT 0x00001000 /* rx mgmt content */
+#define DBG_RX_FRAGS 0x00002000 /* rx data fragment handling */
+#define DBG_DEVSTART 0x00004000 /* fw download, device start */
+#define DBG_URB 0x00008000 /* rx urb status, ... */
+#define DBG_RX_ATMEL_HDR 0x00010000 /* Atmel-specific Rx headers */
+#define DBG_PROC_ENTRY 0x00020000 /* procedure entries/exits */
+#define DBG_PM 0x00040000 /* power management settings */
+#define DBG_BSS_MATCH 0x00080000 /* BSS match failures */
+#define DBG_PARAMS 0x00100000 /* show configured parameters */
+#define DBG_WAIT_COMPLETE 0x00200000 /* command completion */
+#define DBG_RX_FRAGS_SKB 0x00400000 /* skb header of Rx fragments */
+#define DBG_BSS_TABLE_RM 0x00800000 /* purging bss table entries */
+#define DBG_MONITOR_MODE 0x01000000 /* monitor mode */
+#define DBG_MIB 0x02000000 /* dump all MIBs on startup */
+#define DBG_MGMT_TIMER 0x04000000 /* dump mgmt_timer ops */
+#define DBG_WE_EVENTS 0x08000000 /* dump wireless events */
+#define DBG_FW 0x10000000 /* firmware download */
+#define DBG_DFU 0x20000000 /* device firmware upgrade */
+#define DBG_CMD 0x40000000
+#define DBG_MAC80211 0x80000000
+
+#define DBG_DEFAULTS 0
+
+/* Use our own dbg macro */
+#define at76_dbg(bits, format, arg...) \
+ do { \
+ if (at76_debug & (bits)) \
+ printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \
+ ## arg); \
+ } while (0)
+
+#define at76_dbg_dump(bits, buf, len, format, arg...) \
+ do { \
+ if (at76_debug & (bits)) { \
+ printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \
+ ## arg); \
+ print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, \
+ buf, len); \
+ } \
+ } while (0)
+
+static uint at76_debug = DBG_DEFAULTS;
+
+/* Protect against concurrent firmware loading and parsing */
+static struct mutex fw_mutex;
+
+static struct fwentry firmwares[] = {
+ [0] = { "" },
+ [BOARD_503_ISL3861] = { "atmel_at76c503-i3861.bin" },
+ [BOARD_503_ISL3863] = { "atmel_at76c503-i3863.bin" },
+ [BOARD_503] = { "atmel_at76c503-rfmd.bin" },
+ [BOARD_503_ACC] = { "atmel_at76c503-rfmd-acc.bin" },
+ [BOARD_505] = { "atmel_at76c505-rfmd.bin" },
+ [BOARD_505_2958] = { "atmel_at76c505-rfmd2958.bin" },
+ [BOARD_505A] = { "atmel_at76c505a-rfmd2958.bin" },
+ [BOARD_505AMX] = { "atmel_at76c505amx-rfmd.bin" },
+};
+
+#define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops)
+
+static struct usb_device_id dev_table[] = {
+ /*
+ * at76c503-i3861
+ */
+ /* Generic AT76C503/3861 device */
+ { USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Linksys WUSB11 v2.1/v2.6 */
+ { USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Netgear MA101 rev. A */
+ { USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Tekram U300C / Allnet ALL0193 */
+ { USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* HP HN210W J7801A */
+ { USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Sitecom/Z-Com/Zyxel M4Y-750 */
+ { USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Dynalink/Askey WLL013 (intersil) */
+ { USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */
+ { USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* BenQ AWL300 */
+ { USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Addtron AWU-120, Compex WLU11 */
+ { USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Intel AP310 AnyPoint II USB */
+ { USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Dynalink L11U */
+ { USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* Arescom WL-210, FCC id 07J-GL2411USB */
+ { USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* I-O DATA WN-B11/USB */
+ { USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /* BT Voyager 1010 */
+ { USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ /*
+ * at76c503-i3863
+ */
+ /* Generic AT76C503/3863 device */
+ { USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863) },
+ /* Samsung SWL-2100U */
+ { USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863) },
+ /*
+ * at76c503-rfmd
+ */
+ /* Generic AT76C503/RFMD device */
+ { USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503) },
+ /* Dynalink/Askey WLL013 (rfmd) */
+ { USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503) },
+ /* Linksys WUSB11 v2.6 */
+ { USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503) },
+ /* Network Everywhere NWU11B */
+ { USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503) },
+ /* Netgear MA101 rev. B */
+ { USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503) },
+ /* D-Link DWL-120 rev. E */
+ { USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503) },
+ /* Actiontec 802UAT1, HWU01150-01UK */
+ { USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503) },
+ /* AirVast W-Buddie WN210 */
+ { USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503) },
+ /* Dick Smith Electronics XH1153 802.11b USB adapter */
+ { USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503) },
+ /* CNet CNUSB611 */
+ { USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503) },
+ /* FiberLine FL-WL200U */
+ { USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503) },
+ /* BenQ AWL400 USB stick */
+ { USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503) },
+ /* 3Com 3CRSHEW696 */
+ { USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503) },
+ /* Siemens Santis ADSL WLAN USB adapter WLL 013 */
+ { USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503) },
+ /* Belkin F5D6050, version 2 */
+ { USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503) },
+ /* iBlitzz, BWU613 (not *B or *SB) */
+ { USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503) },
+ /* Gigabyte GN-WLBM101 */
+ { USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503) },
+ /* Planex GW-US11S */
+ { USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503) },
+ /* Internal WLAN adapter in h5[4,5]xx series iPAQs */
+ { USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503) },
+ /* Corega Wireless LAN USB-11 mini */
+ { USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503) },
+ /* Corega Wireless LAN USB-11 mini2 */
+ { USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503) },
+ /* Uniden PCW100 */
+ { USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503) },
+ /*
+ * at76c503-rfmd-acc
+ */
+ /* SMC2664W */
+ { USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC) },
+ /* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */
+ { USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC) },
+ /*
+ * at76c505-rfmd
+ */
+ /* Generic AT76C505/RFMD */
+ { USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505) },
+ /*
+ * at76c505-rfmd2958
+ */
+ /* Generic AT76C505/RFMD, OvisLink WL-1130USB */
+ { USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
+ /* Fiberline FL-WL240U */
+ { USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958) },
+ /* CNet CNUSB-611G */
+ { USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958) },
+ /* Linksys WUSB11 v2.8 */
+ { USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958) },
+ /* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */
+ { USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958) },
+ /* Corega WLAN USB Stick 11 */
+ { USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
+ /* Microstar MSI Box MS6978 */
+ { USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958) },
+ /*
+ * at76c505a-rfmd2958
+ */
+ /* Generic AT76C505A device */
+ { USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A) },
+ /* Generic AT76C505AS device */
+ { USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) },
+ /* Siemens Gigaset USB WLAN Adapter 11 */
+ { USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) },
+ /*
+ * at76c505amx-rfmd
+ */
+ /* Generic AT76C505AMX device */
+ { USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX) },
+ { }
+};
+
+MODULE_DEVICE_TABLE(usb, dev_table);
+
+/* Supported rates of this hardware, bit 7 marks basic rates */
+static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 };
+
+static const char *const preambles[] = { "long", "short", "auto" };
+
+/* Firmware download */
+/* DFU states */
+#define STATE_IDLE 0x00
+#define STATE_DETACH 0x01
+#define STATE_DFU_IDLE 0x02
+#define STATE_DFU_DOWNLOAD_SYNC 0x03
+#define STATE_DFU_DOWNLOAD_BUSY 0x04
+#define STATE_DFU_DOWNLOAD_IDLE 0x05
+#define STATE_DFU_MANIFEST_SYNC 0x06
+#define STATE_DFU_MANIFEST 0x07
+#define STATE_DFU_MANIFEST_WAIT_RESET 0x08
+#define STATE_DFU_UPLOAD_IDLE 0x09
+#define STATE_DFU_ERROR 0x0a
+
+/* DFU commands */
+#define DFU_DETACH 0
+#define DFU_DNLOAD 1
+#define DFU_UPLOAD 2
+#define DFU_GETSTATUS 3
+#define DFU_CLRSTATUS 4
+#define DFU_GETSTATE 5
+#define DFU_ABORT 6
+
+#define FW_BLOCK_SIZE 1024
+
+struct dfu_status {
+ unsigned char status;
+ unsigned char poll_timeout[3];
+ unsigned char state;
+ unsigned char string;
+} __attribute__((packed));
+
+static inline int at76_is_intersil(enum board_type board)
+{
+ return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863);
+}
+
+static inline int at76_is_503rfmd(enum board_type board)
+{
+ return (board == BOARD_503 || board == BOARD_503_ACC);
+}
+
+static inline int at76_is_505a(enum board_type board)
+{
+ return (board == BOARD_505A || board == BOARD_505AMX);
+}
+
+/* Load a block of the first (internal) part of the firmware */
+static int at76_load_int_fw_block(struct usb_device *udev, int blockno,
+ void *block, int size)
+{
+ return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), DFU_DNLOAD,
+ USB_TYPE_CLASS | USB_DIR_OUT |
+ USB_RECIP_INTERFACE, blockno, 0, block, size,
+ USB_CTRL_GET_TIMEOUT);
+}
+
+static int at76_dfu_get_status(struct usb_device *udev,
+ struct dfu_status *status)
+{
+ int ret;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATUS,
+ USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
+ 0, 0, status, sizeof(struct dfu_status),
+ USB_CTRL_GET_TIMEOUT);
+ return ret;
+}
+
+static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state)
+{
+ int ret;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATE,
+ USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
+ 0, 0, state, 1, USB_CTRL_GET_TIMEOUT);
+ return ret;
+}
+
+/* Convert timeout from the DFU status to jiffies */
+static inline unsigned long at76_get_timeout(struct dfu_status *s)
+{
+ return msecs_to_jiffies((s->poll_timeout[2] << 16)
+ | (s->poll_timeout[1] << 8)
+ | (s->poll_timeout[0]));
+}
+
+/* Load internal firmware from the buffer. If manifest_sync_timeout > 0, use
+ * its value in jiffies in the MANIFEST_SYNC state. */
+static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
+ int manifest_sync_timeout)
+{
+ u8 *block;
+ struct dfu_status dfu_stat_buf;
+ int ret = 0;
+ int need_dfu_state = 1;
+ int is_done = 0;
+ u8 dfu_state = 0;
+ u32 dfu_timeout = 0;
+ int bsize = 0;
+ int blockno = 0;
+
+ at76_dbg(DBG_DFU, "%s( %p, %u, %d)", __func__, buf, size,
+ manifest_sync_timeout);
+
+ if (!size) {
+ dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n");
+ return -EINVAL;
+ }
+
+ block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
+ if (!block)
+ return -ENOMEM;
+
+ do {
+ if (need_dfu_state) {
+ ret = at76_dfu_get_state(udev, &dfu_state);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "cannot get DFU state: %d\n", ret);
+ goto exit;
+ }
+ need_dfu_state = 0;
+ }
+
+ switch (dfu_state) {
+ case STATE_DFU_DOWNLOAD_SYNC:
+ at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_SYNC");
+ ret = at76_dfu_get_status(udev, &dfu_stat_buf);
+ if (ret >= 0) {
+ dfu_state = dfu_stat_buf.state;
+ dfu_timeout = at76_get_timeout(&dfu_stat_buf);
+ need_dfu_state = 0;
+ } else
+ dev_printk(KERN_ERR, &udev->dev,
+ "at76_dfu_get_status returned %d\n",
+ ret);
+ break;
+
+ case STATE_DFU_DOWNLOAD_BUSY:
+ at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_BUSY");
+ need_dfu_state = 1;
+
+ at76_dbg(DBG_DFU, "DFU: Resetting device");
+ schedule_timeout_interruptible(dfu_timeout);
+ break;
+
+ case STATE_DFU_DOWNLOAD_IDLE:
+ at76_dbg(DBG_DFU, "DOWNLOAD...");
+ /* fall through */
+ case STATE_DFU_IDLE:
+ at76_dbg(DBG_DFU, "DFU IDLE");
+
+ bsize = min_t(int, size, FW_BLOCK_SIZE);
+ memcpy(block, buf, bsize);
+ at76_dbg(DBG_DFU, "int fw, size left = %5d, "
+ "bsize = %4d, blockno = %2d", size, bsize,
+ blockno);
+ ret =
+ at76_load_int_fw_block(udev, blockno, block, bsize);
+ buf += bsize;
+ size -= bsize;
+ blockno++;
+
+ if (ret != bsize)
+ dev_printk(KERN_ERR, &udev->dev,
+ "at76_load_int_fw_block "
+ "returned %d\n", ret);
+ need_dfu_state = 1;
+ break;
+
+ case STATE_DFU_MANIFEST_SYNC:
+ at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_SYNC");
+
+ ret = at76_dfu_get_status(udev, &dfu_stat_buf);
+ if (ret < 0)
+ break;
+
+ dfu_state = dfu_stat_buf.state;
+ dfu_timeout = at76_get_timeout(&dfu_stat_buf);
+ need_dfu_state = 0;
+
+ /* override the timeout from the status response,
+ needed for AT76C505A */
+ if (manifest_sync_timeout > 0)
+ dfu_timeout = manifest_sync_timeout;
+
+ at76_dbg(DBG_DFU, "DFU: Waiting for manifest phase");
+ schedule_timeout_interruptible(dfu_timeout);
+ break;
+
+ case STATE_DFU_MANIFEST:
+ at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST");
+ is_done = 1;
+ break;
+
+ case STATE_DFU_MANIFEST_WAIT_RESET:
+ at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_WAIT_RESET");
+ is_done = 1;
+ break;
+
+ case STATE_DFU_UPLOAD_IDLE:
+ at76_dbg(DBG_DFU, "STATE_DFU_UPLOAD_IDLE");
+ break;
+
+ case STATE_DFU_ERROR:
+ at76_dbg(DBG_DFU, "STATE_DFU_ERROR");
+ ret = -EPIPE;
+ break;
+
+ default:
+ at76_dbg(DBG_DFU, "DFU UNKNOWN STATE (%d)", dfu_state);
+ ret = -EINVAL;
+ break;
+ }
+ } while (!is_done && (ret >= 0));
+
+exit:
+ kfree(block);
+ if (ret >= 0)
+ ret = 0;
+
+ return ret;
+}
+
+#define HEX2STR_BUFFERS 4
+#define HEX2STR_MAX_LEN 64
+#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
+
+/* Convert binary data into hex string */
+static char *hex2str(void *buf, int len)
+{
+ static atomic_t a = ATOMIC_INIT(0);
+ static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1];
+ char *ret = bufs[atomic_inc_return(&a) & (HEX2STR_BUFFERS - 1)];
+ char *obuf = ret;
+ u8 *ibuf = buf;
+
+ if (len > HEX2STR_MAX_LEN)
+ len = HEX2STR_MAX_LEN;
+
+ if (len <= 0) {
+ ret[0] = '\0';
+ return ret;
+ }
+
+ while (len--) {
+ *obuf++ = BIN2HEX(*ibuf >> 4);
+ *obuf++ = BIN2HEX(*ibuf & 0xf);
+ *obuf++ = '-';
+ ibuf++;
+ }
+ *(--obuf) = '\0';
+
+ return ret;
+}
+
+#define MAC2STR_BUFFERS 4
+
+static inline char *mac2str(u8 *mac)
+{
+ static atomic_t a = ATOMIC_INIT(0);
+ static char bufs[MAC2STR_BUFFERS][6 * 3];
+ char *str;
+
+ str = bufs[atomic_inc_return(&a) & (MAC2STR_BUFFERS - 1)];
+ sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ return str;
+}
+
+/* LED trigger */
+static int tx_activity;
+static void at76_ledtrig_tx_timerfunc(unsigned long data);
+static DEFINE_TIMER(ledtrig_tx_timer, at76_ledtrig_tx_timerfunc, 0, 0);
+DEFINE_LED_TRIGGER(ledtrig_tx);
+
+static void at76_ledtrig_tx_timerfunc(unsigned long data)
+{
+ static int tx_lastactivity;
+
+ if (tx_lastactivity != tx_activity) {
+ tx_lastactivity = tx_activity;
+ led_trigger_event(ledtrig_tx, LED_FULL);
+ mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
+ } else
+ led_trigger_event(ledtrig_tx, LED_OFF);
+}
+
+static void at76_ledtrig_tx_activity(void)
+{
+ tx_activity++;
+ if (!timer_pending(&ledtrig_tx_timer))
+ mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
+}
+
+static int at76_remap(struct usb_device *udev)
+{
+ int ret;
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0a,
+ USB_TYPE_VENDOR | USB_DIR_OUT |
+ USB_RECIP_INTERFACE, 0, 0, NULL, 0,
+ USB_CTRL_GET_TIMEOUT);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int at76_get_op_mode(struct usb_device *udev)
+{
+ int ret;
+ u8 saved;
+ u8 *op_mode;
+
+ op_mode = kmalloc(1, GFP_NOIO);
+ if (!op_mode)
+ return -ENOMEM;
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, 0x01, 0, op_mode, 1,
+ USB_CTRL_GET_TIMEOUT);
+ saved = *op_mode;
+ kfree(op_mode);
+
+ if (ret < 0)
+ return ret;
+ else if (ret < 1)
+ return -EIO;
+ else
+ return saved;
+}
+
+/* Load a block of the second ("external") part of the firmware */
+static inline int at76_load_ext_fw_block(struct usb_device *udev, int blockno,
+ void *block, int size)
+{
+ return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
+ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
+ 0x0802, blockno, block, size,
+ USB_CTRL_GET_TIMEOUT);
+}
+
+static inline int at76_get_hw_cfg(struct usb_device *udev,
+ union at76_hwcfg *buf, int buf_size)
+{
+ return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, 0x0a02, 0,
+ buf, buf_size, USB_CTRL_GET_TIMEOUT);
+}
+
+/* Intersil boards use a different "value" for GetHWConfig requests */
+static inline int at76_get_hw_cfg_intersil(struct usb_device *udev,
+ union at76_hwcfg *buf, int buf_size)
+{
+ return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, 0x0902, 0,
+ buf, buf_size, USB_CTRL_GET_TIMEOUT);
+}
+
+/* Get the hardware configuration for the adapter and put it to the appropriate
+ * fields of 'priv' (the GetHWConfig request and interpretation of the result
+ * depends on the board type) */
+static int at76_get_hw_config(struct at76_priv *priv)
+{
+ int ret;
+ union at76_hwcfg *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL);
+
+ if (!hwcfg)
+ return -ENOMEM;
+
+ if (at76_is_intersil(priv->board_type)) {
+ ret = at76_get_hw_cfg_intersil(priv->udev, hwcfg,
+ sizeof(hwcfg->i));
+ if (ret < 0)
+ goto exit;
+ memcpy(priv->mac_addr, hwcfg->i.mac_addr, ETH_ALEN);
+ priv->regulatory_domain = hwcfg->i.regulatory_domain;
+ } else if (at76_is_503rfmd(priv->board_type)) {
+ ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r3));
+ if (ret < 0)
+ goto exit;
+ memcpy(priv->mac_addr, hwcfg->r3.mac_addr, ETH_ALEN);
+ priv->regulatory_domain = hwcfg->r3.regulatory_domain;
+ } else {
+ ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r5));
+ if (ret < 0)
+ goto exit;
+ memcpy(priv->mac_addr, hwcfg->r5.mac_addr, ETH_ALEN);
+ priv->regulatory_domain = hwcfg->r5.regulatory_domain;
+ }
+
+exit:
+ kfree(hwcfg);
+ if (ret < 0)
+ printk(KERN_ERR "%s: cannot get HW Config (error %d)\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ return ret;
+}
+
+static struct reg_domain const *at76_get_reg_domain(u16 code)
+{
+ int i;
+ static struct reg_domain const fd_tab[] = {
+ { 0x10, "FCC (USA)", 0x7ff }, /* ch 1-11 */
+ { 0x20, "IC (Canada)", 0x7ff }, /* ch 1-11 */
+ { 0x30, "ETSI (most of Europe)", 0x1fff }, /* ch 1-13 */
+ { 0x31, "Spain", 0x600 }, /* ch 10-11 */
+ { 0x32, "France", 0x1e00 }, /* ch 10-13 */
+ { 0x40, "MKK (Japan)", 0x2000 }, /* ch 14 */
+ { 0x41, "MKK1 (Japan)", 0x3fff }, /* ch 1-14 */
+ { 0x50, "Israel", 0x3fc }, /* ch 3-9 */
+ { 0x00, "<unknown>", 0xffffffff } /* ch 1-32 */
+ };
+
+ /* Last entry is fallback for unknown domain code */
+ for (i = 0; i < ARRAY_SIZE(fd_tab) - 1; i++)
+ if (code == fd_tab[i].code)
+ break;
+
+ return &fd_tab[i];
+}
+
+static inline int at76_get_mib(struct usb_device *udev, u16 mib, void *buf,
+ int buf_size)
+{
+ int ret;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, mib << 8, 0, buf, buf_size,
+ USB_CTRL_GET_TIMEOUT);
+ if (ret >= 0 && ret != buf_size)
+ return -EIO;
+ return ret;
+}
+
+/* Return positive number for status, negative for an error */
+static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
+{
+ u8 *stat_buf;
+ int ret;
+
+ stat_buf = kmalloc(40, GFP_NOIO);
+ if (!stat_buf)
+ return -ENOMEM;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, cmd, 0, stat_buf,
+ 40, USB_CTRL_GET_TIMEOUT);
+ if (ret >= 0)
+ ret = stat_buf[5];
+ kfree(stat_buf);
+
+ return ret;
+}
+
+#define MAKE_CMD_CASE(c) case (c): return #c
+static const char *at76_get_cmd_string(u8 cmd_status)
+{
+ switch (cmd_status) {
+ MAKE_CMD_CASE(CMD_SET_MIB);
+ MAKE_CMD_CASE(CMD_GET_MIB);
+ MAKE_CMD_CASE(CMD_SCAN);
+ MAKE_CMD_CASE(CMD_JOIN);
+ MAKE_CMD_CASE(CMD_START_IBSS);
+ MAKE_CMD_CASE(CMD_RADIO_ON);
+ MAKE_CMD_CASE(CMD_RADIO_OFF);
+ MAKE_CMD_CASE(CMD_STARTUP);
+ }
+
+ return "UNKNOWN";
+}
+
+static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
+ int buf_size)
+{
+ int ret;
+ struct at76_command *cmd_buf = kmalloc(sizeof(struct at76_command) +
+ buf_size, GFP_KERNEL);
+
+ if (!cmd_buf)
+ return -ENOMEM;
+
+ cmd_buf->cmd = cmd;
+ cmd_buf->reserved = 0;
+ cmd_buf->size = cpu_to_le16(buf_size);
+ memcpy(cmd_buf->data, buf, buf_size);
+
+ at76_dbg_dump(DBG_CMD, cmd_buf, sizeof(struct at76_command) + buf_size,
+ "issuing command %s (0x%02x)",
+ at76_get_cmd_string(cmd), cmd);
+
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
+ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
+ 0, 0, cmd_buf,
+ sizeof(struct at76_command) + buf_size,
+ USB_CTRL_GET_TIMEOUT);
+ kfree(cmd_buf);
+ return ret;
+}
+
+#define MAKE_CMD_STATUS_CASE(c) case (c): return #c
+static const char *at76_get_cmd_status_string(u8 cmd_status)
+{
+ switch (cmd_status) {
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_IDLE);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_COMPLETE);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_UNKNOWN);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_INVALID_PARAMETER);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_FUNCTION_NOT_SUPPORTED);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_TIME_OUT);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_IN_PROGRESS);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_HOST_FAILURE);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_SCAN_FAILED);
+ }
+
+ return "UNKNOWN";
+}
+
+/* Wait until the command is completed */
+static int at76_wait_completion(struct at76_priv *priv, int cmd)
+{
+ int status = 0;
+ unsigned long timeout = jiffies + CMD_COMPLETION_TIMEOUT;
+
+ do {
+ status = at76_get_cmd_status(priv->udev, cmd);
+ if (status < 0) {
+ printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n",
+ wiphy_name(priv->hw->wiphy), status);
+ break;
+ }
+
+ at76_dbg(DBG_WAIT_COMPLETE,
+ "%s: Waiting on cmd %d, status = %d (%s)",
+ wiphy_name(priv->hw->wiphy), cmd, status,
+ at76_get_cmd_status_string(status));
+
+ if (status != CMD_STATUS_IN_PROGRESS
+ && status != CMD_STATUS_IDLE)
+ break;
+
+ schedule_timeout_interruptible(HZ / 10); /* 100 ms */
+ if (time_after(jiffies, timeout)) {
+ printk(KERN_ERR
+ "%s: completion timeout for command %d\n",
+ wiphy_name(priv->hw->wiphy), cmd);
+ status = -ETIMEDOUT;
+ break;
+ }
+ } while (1);
+
+ return status;
+}
+
+static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
+{
+ int ret;
+
+ ret = at76_set_card_command(priv->udev, CMD_SET_MIB, buf,
+ offsetof(struct set_mib_buffer,
+ data) + buf->size);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_wait_completion(priv, CMD_SET_MIB);
+ if (ret != CMD_STATUS_COMPLETE) {
+ printk(KERN_INFO
+ "%s: set_mib: at76_wait_completion failed "
+ "with %d\n", wiphy_name(priv->hw->wiphy), ret);
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+/* Return < 0 on error, == 0 if no command sent, == 1 if cmd sent */
+static int at76_set_radio(struct at76_priv *priv, int enable)
+{
+ int ret;
+ int cmd;
+
+ if (priv->radio_on == enable)
+ return 0;
+
+ cmd = enable ? CMD_RADIO_ON : CMD_RADIO_OFF;
+
+ ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
+ if (ret < 0)
+ printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), cmd, ret);
+ else
+ ret = 1;
+
+ priv->radio_on = enable;
+ return ret;
+}
+
+/* Set current power save mode (AT76_PM_OFF/AT76_PM_ON/AT76_PM_SMART) */
+static int at76_set_pm_mode(struct at76_priv *priv)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, power_mgmt_mode);
+ priv->mib_buf.data.byte = priv->pm_mode;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ return ret;
+}
+
+static int at76_set_preamble(struct at76_priv *priv, u8 type)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_LOCAL;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_local, preamble_type);
+ priv->mib_buf.data.byte = type;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ return ret;
+}
+
+static int at76_set_frag(struct at76_priv *priv, u16 size)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac, frag_threshold);
+ priv->mib_buf.data.word = cpu_to_le16(size);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ return ret;
+}
+
+static int at76_set_rts(struct at76_priv *priv, u16 size)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac, rts_threshold);
+ priv->mib_buf.data.word = cpu_to_le16(size);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (rts) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ return ret;
+}
+
+static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_LOCAL;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_local, txautorate_fallback);
+ priv->mib_buf.data.byte = onoff;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ return ret;
+}
+
+static void at76_dump_mib_mac_addr(struct at76_priv *priv)
+{
+ int i;
+ int ret;
+ struct mib_mac_addr *m = kmalloc(sizeof(struct mib_mac_addr),
+ GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
+ sizeof(struct mib_mac_addr));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x",
+ wiphy_name(priv->hw->wiphy),
+ mac2str(m->mac_addr), m->res[0], m->res[1]);
+ for (i = 0; i < ARRAY_SIZE(m->group_addr); i++)
+ at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, "
+ "status %d", wiphy_name(priv->hw->wiphy), i,
+ mac2str(m->group_addr[i]), m->group_addr_status[i]);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_mac_wep(struct at76_priv *priv)
+{
+ int i;
+ int ret;
+ int key_len;
+ struct mib_mac_wep *m = kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
+ sizeof(struct mib_mac_wep));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u "
+ "key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u "
+ "encr_level %u key %d", wiphy_name(priv->hw->wiphy),
+ m->privacy_invoked, m->wep_default_key_id,
+ m->wep_key_mapping_len, m->exclude_unencrypted,
+ le32_to_cpu(m->wep_icv_error_count),
+ le32_to_cpu(m->wep_excluded_count), m->encryption_level,
+ m->wep_default_key_id);
+
+ key_len = (m->encryption_level == 1) ?
+ WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
+
+ for (i = 0; i < WEP_KEYS; i++)
+ at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s",
+ wiphy_name(priv->hw->wiphy), i,
+ hex2str(m->wep_default_keyvalue[i], key_len));
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_mac_mgmt *m = kmalloc(sizeof(struct mib_mac_mgmt),
+ GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
+ sizeof(struct mib_mac_mgmt));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration "
+ "%d medium_occupancy_limit %d station_id 0x%x ATIM_window %d "
+ "CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d "
+ "current_bssid %s current_essid %s current_bss_type %d "
+ "pm_mode %d ibss_change %d res %d "
+ "multi_domain_capability_implemented %d "
+ "international_roaming %d country_string %.3s",
+ wiphy_name(priv->hw->wiphy), le16_to_cpu(m->beacon_period),
+ le16_to_cpu(m->CFP_max_duration),
+ le16_to_cpu(m->medium_occupancy_limit),
+ le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window),
+ m->CFP_mode, m->privacy_option_implemented, m->DTIM_period,
+ m->CFP_period, mac2str(m->current_bssid),
+ hex2str(m->current_essid, IW_ESSID_MAX_SIZE),
+ m->current_bss_type, m->power_mgmt_mode, m->ibss_change,
+ m->res, m->multi_domain_capability_implemented,
+ m->multi_domain_capability_enabled, m->country_string);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_mac(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_mac *m = kmalloc(sizeof(struct mib_mac), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MAC: max_tx_msdu_lifetime %d "
+ "max_rx_lifetime %d frag_threshold %d rts_threshold %d "
+ "cwmin %d cwmax %d short_retry_time %d long_retry_time %d "
+ "scan_type %d scan_channel %d probe_delay %u "
+ "min_channel_time %d max_channel_time %d listen_int %d "
+ "desired_ssid %s desired_bssid %s desired_bsstype %d",
+ wiphy_name(priv->hw->wiphy),
+ le32_to_cpu(m->max_tx_msdu_lifetime),
+ le32_to_cpu(m->max_rx_lifetime),
+ le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold),
+ le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax),
+ m->short_retry_time, m->long_retry_time, m->scan_type,
+ m->scan_channel, le16_to_cpu(m->probe_delay),
+ le16_to_cpu(m->min_channel_time),
+ le16_to_cpu(m->max_channel_time),
+ le16_to_cpu(m->listen_interval),
+ hex2str(m->desired_ssid, IW_ESSID_MAX_SIZE),
+ mac2str(m->desired_bssid), m->desired_bsstype);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_phy(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_phy *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB PHY: ed_threshold %d slot_time %d "
+ "sifs_time %d preamble_length %d plcp_header_length %d "
+ "mpdu_max_length %d cca_mode_supported %d operation_rate_set "
+ "0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d "
+ "phy_type %d current_reg_domain %d",
+ wiphy_name(priv->hw->wiphy), le32_to_cpu(m->ed_threshold),
+ le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time),
+ le16_to_cpu(m->preamble_length),
+ le16_to_cpu(m->plcp_header_length),
+ le16_to_cpu(m->mpdu_max_length),
+ le16_to_cpu(m->cca_mode_supported), m->operation_rate_set[0],
+ m->operation_rate_set[1], m->operation_rate_set[2],
+ m->operation_rate_set[3], m->channel_id, m->current_cca_mode,
+ m->phy_type, m->current_reg_domain);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_local(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_local *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d "
+ "txautorate_fallback %d ssid_size %d promiscuous_mode %d "
+ "preamble_type %d", wiphy_name(priv->hw->wiphy),
+ m->beacon_enable,
+ m->txautorate_fallback, m->ssid_size, m->promiscuous_mode,
+ m->preamble_type);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_mdomain(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_mdomain *m = kmalloc(sizeof(struct mib_mdomain), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
+ sizeof(struct mib_mdomain));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s",
+ wiphy_name(priv->hw->wiphy),
+ hex2str(m->channel_list, sizeof(m->channel_list)));
+
+ at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s",
+ wiphy_name(priv->hw->wiphy),
+ hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel)));
+exit:
+ kfree(m);
+}
+
+/* Enable monitor mode */
+static int at76_start_monitor(struct at76_priv *priv)
+{
+ struct at76_req_scan scan;
+ int ret;
+
+ memset(&scan, 0, sizeof(struct at76_req_scan));
+ memset(scan.bssid, 0xff, ETH_ALEN);
+
+ scan.channel = priv->channel;
+ scan.scan_type = SCAN_TYPE_PASSIVE;
+ scan.international_scan = 0;
+
+ ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+ if (ret >= 0)
+ ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
+
+ return ret;
+}
+
+/* Calculate padding from txbuf->wlength (which excludes the USB TX header),
+ likely to compensate a flaw in the AT76C503A USB part ... */
+static inline int at76_calc_padding(int wlen)
+{
+ /* add the USB TX header */
+ wlen += AT76_TX_HDRLEN;
+
+ wlen = wlen % 64;
+
+ if (wlen < 50)
+ return 50 - wlen;
+
+ if (wlen >= 61)
+ return 64 + 50 - wlen;
+
+ return 0;
+}
+
+static void at76_rx_callback(struct urb *urb)
+{
+ struct at76_priv *priv = urb->context;
+
+ priv->rx_tasklet.data = (unsigned long)urb;
+ tasklet_schedule(&priv->rx_tasklet);
+ return;
+}
+
+static int at76_submit_rx_urb(struct at76_priv *priv)
+{
+ int ret;
+ int size;
+ struct sk_buff *skb = priv->rx_skb;
+
+ if (!priv->rx_urb) {
+ printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n",
+ wiphy_name(priv->hw->wiphy), __func__);
+ return -EFAULT;
+ }
+
+ if (!skb) {
+ skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
+ if (!skb) {
+ printk(KERN_ERR "%s: cannot allocate rx skbuff\n",
+ wiphy_name(priv->hw->wiphy));
+ ret = -ENOMEM;
+ goto exit;
+ }
+ priv->rx_skb = skb;
+ } else {
+ skb_push(skb, skb_headroom(skb));
+ skb_trim(skb, 0);
+ }
+
+ size = skb_tailroom(skb);
+ usb_fill_bulk_urb(priv->rx_urb, priv->udev, priv->rx_pipe,
+ skb_put(skb, size), size, at76_rx_callback, priv);
+ ret = usb_submit_urb(priv->rx_urb, GFP_ATOMIC);
+ if (ret < 0) {
+ if (ret == -ENODEV)
+ at76_dbg(DBG_DEVSTART,
+ "usb_submit_urb returned -ENODEV");
+ else
+ printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ }
+
+exit:
+ if (ret < 0 && ret != -ENODEV)
+ printk(KERN_ERR "%s: cannot submit rx urb - please unload the "
+ "driver and/or power cycle the device\n",
+ wiphy_name(priv->hw->wiphy));
+
+ return ret;
+}
+
+/* Download external firmware */
+static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
+{
+ int ret;
+ int op_mode;
+ int blockno = 0;
+ int bsize;
+ u8 *block;
+ u8 *buf = fwe->extfw;
+ int size = fwe->extfw_size;
+
+ if (!buf || !size)
+ return -ENOENT;
+
+ op_mode = at76_get_op_mode(udev);
+ at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
+
+ if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
+ dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n",
+ op_mode);
+ return -EINVAL;
+ }
+
+ block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
+ if (!block)
+ return -ENOMEM;
+
+ at76_dbg(DBG_DEVSTART, "downloading external firmware");
+
+ /* for fw >= 0.100, the device needs an extra empty block */
+ do {
+ bsize = min_t(int, size, FW_BLOCK_SIZE);
+ memcpy(block, buf, bsize);
+ at76_dbg(DBG_DEVSTART,
+ "ext fw, size left = %5d, bsize = %4d, blockno = %2d",
+ size, bsize, blockno);
+ ret = at76_load_ext_fw_block(udev, blockno, block, bsize);
+ if (ret != bsize) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "loading %dth firmware block failed: %d\n",
+ blockno, ret);
+ goto exit;
+ }
+ buf += bsize;
+ size -= bsize;
+ blockno++;
+ } while (bsize > 0);
+
+ if (at76_is_505a(fwe->board_type)) {
+ at76_dbg(DBG_DEVSTART, "200 ms delay for 505a");
+ schedule_timeout_interruptible(HZ / 5 + 1);
+ }
+
+exit:
+ kfree(block);
+ if (ret < 0)
+ dev_printk(KERN_ERR, &udev->dev,
+ "downloading external firmware failed: %d\n", ret);
+ return ret;
+}
+
+/* Download internal firmware */
+static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe)
+{
+ int ret;
+ int need_remap = !at76_is_505a(fwe->board_type);
+
+ ret = at76_usbdfu_download(udev, fwe->intfw, fwe->intfw_size,
+ need_remap ? 0 : 2 * HZ);
+
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "downloading internal fw failed with %d\n", ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_DEVSTART, "sending REMAP");
+
+ /* no REMAP for 505A (see SF driver) */
+ if (need_remap) {
+ ret = at76_remap(udev);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "sending REMAP failed with %d\n", ret);
+ goto exit;
+ }
+ }
+
+ at76_dbg(DBG_DEVSTART, "sleeping for 2 seconds");
+ schedule_timeout_interruptible(2 * HZ + 1);
+ usb_reset_device(udev);
+
+exit:
+ return ret;
+}
+
+static int at76_startup_device(struct at76_priv *priv)
+{
+ struct at76_card_config *ccfg = &priv->card_config;
+ int ret;
+
+ at76_dbg(DBG_PARAMS,
+ "%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d "
+ "keylen %d", wiphy_name(priv->hw->wiphy), priv->essid_size,
+ priv->essid, hex2str(priv->essid, IW_ESSID_MAX_SIZE),
+ priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
+ priv->channel, priv->wep_enabled ? "enabled" : "disabled",
+ priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]);
+ at76_dbg(DBG_PARAMS,
+ "%s param: preamble %s rts %d retry %d frag %d "
+ "txrate %s auth_mode %d", wiphy_name(priv->hw->wiphy),
+ preambles[priv->preamble_type], priv->rts_threshold,
+ priv->short_retry_limit, priv->frag_threshold,
+ priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate ==
+ TX_RATE_2MBIT ? "2MBit" : priv->txrate ==
+ TX_RATE_5_5MBIT ? "5.5MBit" : priv->txrate ==
+ TX_RATE_11MBIT ? "11MBit" : priv->txrate ==
+ TX_RATE_AUTO ? "auto" : "<invalid>", priv->auth_mode);
+ at76_dbg(DBG_PARAMS,
+ "%s param: pm_mode %d pm_period %d auth_mode %s "
+ "scan_times %d %d scan_mode %s",
+ wiphy_name(priv->hw->wiphy), priv->pm_mode, priv->pm_period,
+ priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret",
+ priv->scan_min_time, priv->scan_max_time,
+ priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive");
+
+ memset(ccfg, 0, sizeof(struct at76_card_config));
+ ccfg->promiscuous_mode = 0;
+ ccfg->short_retry_limit = priv->short_retry_limit;
+
+ if (priv->wep_enabled) {
+ if (priv->wep_keys_len[priv->wep_key_id] > WEP_SMALL_KEY_LEN)
+ ccfg->encryption_type = 2;
+ else
+ ccfg->encryption_type = 1;
+
+ /* jal: always exclude unencrypted if WEP is active */
+ ccfg->exclude_unencrypted = 1;
+ } else {
+ ccfg->exclude_unencrypted = 0;
+ ccfg->encryption_type = 0;
+ }
+
+ ccfg->rts_threshold = cpu_to_le16(priv->rts_threshold);
+ ccfg->fragmentation_threshold = cpu_to_le16(priv->frag_threshold);
+
+ memcpy(ccfg->basic_rate_set, hw_rates, 4);
+ /* jal: really needed, we do a set_mib for autorate later ??? */
+ ccfg->auto_rate_fallback = (priv->txrate == TX_RATE_AUTO ? 1 : 0);
+ ccfg->channel = priv->channel;
+ ccfg->privacy_invoked = priv->wep_enabled;
+ memcpy(ccfg->current_ssid, priv->essid, IW_ESSID_MAX_SIZE);
+ ccfg->ssid_len = priv->essid_size;
+
+ ccfg->wep_default_key_id = priv->wep_key_id;
+ memcpy(ccfg->wep_default_key_value, priv->wep_keys,
+ sizeof(priv->wep_keys));
+
+ ccfg->short_preamble = priv->preamble_type;
+ ccfg->beacon_period = cpu_to_le16(priv->beacon_period);
+
+ ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config,
+ sizeof(struct at76_card_config));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ return ret;
+ }
+
+ at76_wait_completion(priv, CMD_STARTUP);
+
+ /* remove BSSID from previous run */
+ memset(priv->bssid, 0, ETH_ALEN);
+
+ if (at76_set_radio(priv, 1) == 1)
+ at76_wait_completion(priv, CMD_RADIO_ON);
+
+ ret = at76_set_preamble(priv, priv->preamble_type);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_set_frag(priv, priv->frag_threshold);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_set_rts(priv, priv->rts_threshold);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_set_autorate_fallback(priv,
+ priv->txrate == TX_RATE_AUTO ? 1 : 0);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_set_pm_mode(priv);
+ if (ret < 0)
+ return ret;
+
+ if (at76_debug & DBG_MIB) {
+ at76_dump_mib_mac(priv);
+ at76_dump_mib_mac_addr(priv);
+ at76_dump_mib_mac_mgmt(priv);
+ at76_dump_mib_mac_wep(priv);
+ at76_dump_mib_mdomain(priv);
+ at76_dump_mib_phy(priv);
+ at76_dump_mib_local(priv);
+ }
+
+ return 0;
+}
+
+/* Enable or disable promiscuous mode */
+static void at76_work_set_promisc(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_set_promisc);
+ int ret = 0;
+
+ if (priv->device_unplugged)
+ return;
+
+ mutex_lock(&priv->mtx);
+
+ priv->mib_buf.type = MIB_LOCAL;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_local, promiscuous_mode);
+ priv->mib_buf.data.byte = priv->promisc ? 1 : 0;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+
+ mutex_unlock(&priv->mtx);
+}
+
+/* Submit Rx urb back to the device */
+static void at76_work_submit_rx(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_submit_rx);
+
+ mutex_lock(&priv->mtx);
+ at76_submit_rx_urb(priv);
+ mutex_unlock(&priv->mtx);
+}
+
+static void at76_rx_tasklet(unsigned long param)
+{
+ struct urb *urb = (struct urb *)param;
+ struct at76_priv *priv = urb->context;
+ struct at76_rx_buffer *buf;
+ struct ieee80211_rx_status rx_status = { 0 };
+
+ if (priv->device_unplugged) {
+ at76_dbg(DBG_DEVSTART, "device unplugged");
+ if (urb)
+ at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
+ return;
+ }
+
+ if (!priv->rx_skb || !priv->rx_skb->data)
+ return;
+
+ buf = (struct at76_rx_buffer *)priv->rx_skb->data;
+
+ if (urb->status != 0) {
+ if (urb->status != -ENOENT && urb->status != -ECONNRESET)
+ at76_dbg(DBG_URB,
+ "%s %s: - nonzero Rx bulk status received: %d",
+ __func__, wiphy_name(priv->hw->wiphy),
+ urb->status);
+ return;
+ }
+
+ at76_dbg(DBG_RX_ATMEL_HDR,
+ "%s: rx frame: rate %d rssi %d noise %d link %d",
+ wiphy_name(priv->hw->wiphy), buf->rx_rate, buf->rssi,
+ buf->noise_level, buf->link_quality);
+
+ skb_pull(priv->rx_skb, AT76_RX_HDRLEN);
+ skb_trim(priv->rx_skb, le16_to_cpu(buf->wlength));
+ at76_dbg_dump(DBG_RX_DATA, priv->rx_skb->data,
+ priv->rx_skb->len, "RX: len=%d", priv->rx_skb->len);
+
+ rx_status.signal = buf->rssi;
+ rx_status.flag |= RX_FLAG_DECRYPTED;
+ rx_status.flag |= RX_FLAG_IV_STRIPPED;
+
+ at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d",
+ priv->rx_skb->len, priv->rx_skb->data_len);
+ ieee80211_rx_irqsafe(priv->hw, priv->rx_skb, &rx_status);
+
+ /* Use a new skb for the next receive */
+ priv->rx_skb = NULL;
+
+ at76_submit_rx_urb(priv);
+}
+
+/* Load firmware into kernel memory and parse it */
+static struct fwentry *at76_load_firmware(struct usb_device *udev,
+ enum board_type board_type)
+{
+ int ret;
+ char *str;
+ struct at76_fw_header *fwh;
+ struct fwentry *fwe = &firmwares[board_type];
+
+ mutex_lock(&fw_mutex);
+
+ if (fwe->loaded) {
+ at76_dbg(DBG_FW, "re-using previously loaded fw");
+ goto exit;
+ }
+
+ at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
+ ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
+ fwe->fwname);
+ dev_printk(KERN_ERR, &udev->dev,
+ "you may need to download the firmware from "
+ "http://developer.berlios.de/projects/at76c503a/\n");
+ goto exit;
+ }
+
+ at76_dbg(DBG_FW, "got it.");
+ fwh = (struct at76_fw_header *)(fwe->fw->data);
+
+ if (fwe->fw->size <= sizeof(*fwh)) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "firmware is too short (0x%zx)\n", fwe->fw->size);
+ goto exit;
+ }
+
+ /* CRC currently not checked */
+ fwe->board_type = le32_to_cpu(fwh->board_type);
+ if (fwe->board_type != board_type) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "board type mismatch, requested %u, got %u\n",
+ board_type, fwe->board_type);
+ goto exit;
+ }
+
+ fwe->fw_version.major = fwh->major;
+ fwe->fw_version.minor = fwh->minor;
+ fwe->fw_version.patch = fwh->patch;
+ fwe->fw_version.build = fwh->build;
+
+ str = (char *)fwh + le32_to_cpu(fwh->str_offset);
+ fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
+ fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
+ fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
+ fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
+
+ fwe->loaded = 1;
+
+ dev_printk(KERN_DEBUG, &udev->dev,
+ "using firmware %s (version %d.%d.%d-%d)\n",
+ fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
+
+ at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
+ le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
+ le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
+ at76_dbg(DBG_DEVSTART, "firmware id %s", str);
+
+exit:
+ mutex_unlock(&fw_mutex);
+
+ if (fwe->loaded)
+ return fwe;
+ else
+ return NULL;
+}
+
+static void at76_mac80211_tx_callback(struct urb *urb)
+{
+ struct at76_priv *priv = urb->context;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(priv->tx_skb);
+
+ at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ break;
+ case -ENOENT:
+ case -ECONNRESET:
+ /* fail, urb has been unlinked */
+ /* FIXME: add error message */
+ break;
+ default:
+ at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
+ __func__, urb->status);
+ break;
+ }
+
+ memset(&info->status, 0, sizeof(info->status));
+
+ ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb);
+
+ priv->tx_skb = NULL;
+
+ ieee80211_wake_queues(priv->hw);
+}
+
+static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct at76_priv *priv = hw->priv;
+ struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ int padding, submit_len, ret;
+
+ at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+ if (priv->tx_urb->status == -EINPROGRESS) {
+ printk(KERN_ERR "%s: %s called while tx urb is pending\n",
+ wiphy_name(priv->hw->wiphy), __func__);
+ return NETDEV_TX_BUSY;
+ }
+
+ ieee80211_stop_queues(hw);
+
+ at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
+
+ WARN_ON(priv->tx_skb != NULL);
+
+ priv->tx_skb = skb;
+ padding = at76_calc_padding(skb->len);
+ submit_len = AT76_TX_HDRLEN + skb->len + padding;
+
+ /* setup 'Atmel' header */
+ memset(tx_buffer, 0, sizeof(*tx_buffer));
+ tx_buffer->padding = padding;
+ tx_buffer->wlength = cpu_to_le16(skb->len);
+ tx_buffer->tx_rate = ieee80211_get_tx_rate(hw, info)->hw_value;
+ memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved));
+ memcpy(tx_buffer->packet, skb->data, skb->len);
+
+ at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr",
+ wiphy_name(priv->hw->wiphy), le16_to_cpu(tx_buffer->wlength),
+ tx_buffer->padding, tx_buffer->tx_rate);
+
+ /* send stuff */
+ at76_dbg_dump(DBG_TX_DATA_CONTENT, tx_buffer, submit_len,
+ "%s(): tx_buffer %d bytes:", __func__, submit_len);
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
+ submit_len, at76_mac80211_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret) {
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ if (ret == -EINVAL)
+ printk(KERN_ERR
+ "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
+ wiphy_name(priv->hw->wiphy), priv->tx_urb,
+ priv->tx_urb->hcpriv, priv->tx_urb->complete);
+ }
+
+ return 0;
+}
+
+static int at76_mac80211_start(struct ieee80211_hw *hw)
+{
+ struct at76_priv *priv = hw->priv;
+ int ret;
+
+ at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+ mutex_lock(&priv->mtx);
+
+ ret = at76_submit_rx_urb(priv);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ goto error;
+ }
+
+ at76_startup_device(priv);
+
+ at76_start_monitor(priv);
+
+error:
+ mutex_unlock(&priv->mtx);
+
+ return 0;
+}
+
+static void at76_mac80211_stop(struct ieee80211_hw *hw)
+{
+ struct at76_priv *priv = hw->priv;
+
+ at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+ mutex_lock(&priv->mtx);
+
+ if (!priv->device_unplugged) {
+ /* We are called by "ifconfig ethX down", not because the
+ * device is not available anymore. */
+ at76_set_radio(priv, 0);
+
+ /* We unlink rx_urb because at76_open() re-submits it.
+ * If unplugged, at76_delete_device() takes care of it. */
+ usb_kill_urb(priv->rx_urb);
+ }
+
+ mutex_unlock(&priv->mtx);
+}
+
+static int at76_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct at76_priv *priv = hw->priv;
+ int ret = 0;
+
+ at76_dbg(DBG_MAC80211, "%s()", __func__);
+
+ mutex_lock(&priv->mtx);
+
+ switch (conf->type) {
+ case NL80211_IFTYPE_STATION:
+ priv->iw_mode = IW_MODE_INFRA;
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ goto exit;
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+
+ return ret;
+}
+
+static void at76_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ at76_dbg(DBG_MAC80211, "%s()", __func__);
+}
+
+static int at76_join(struct at76_priv *priv)
+{
+ struct at76_req_join join;
+ int ret;
+
+ memset(&join, 0, sizeof(struct at76_req_join));
+ memcpy(join.essid, priv->essid, priv->essid_size);
+ join.essid_size = priv->essid_size;
+ memcpy(join.bssid, priv->bssid, ETH_ALEN);
+ join.bss_type = INFRASTRUCTURE_MODE;
+ join.channel = priv->channel;
+ join.timeout = cpu_to_le16(2000);
+
+ at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__);
+ ret = at76_set_card_command(priv->udev, CMD_JOIN, &join,
+ sizeof(struct at76_req_join));
+
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ return 0;
+ }
+
+ ret = at76_wait_completion(priv, CMD_JOIN);
+ at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret);
+ if (ret != CMD_STATUS_COMPLETE) {
+ printk(KERN_ERR "%s: at76_wait_completion failed: %d\n",
+ wiphy_name(priv->hw->wiphy), ret);
+ return 0;
+ }
+
+ at76_set_pm_mode(priv);
+
+ return 0;
+}
+
+static void at76_dwork_hw_scan(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_hw_scan.work);
+ int ret;
+
+ if (priv->device_unplugged)
+ return;
+
+ mutex_lock(&priv->mtx);
+
+ ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
+ at76_dbg(DBG_MAC80211, "%s: CMD_SCAN status 0x%02x", __func__, ret);
+
+ /* FIXME: add maximum time for scan to complete */
+
+ if (ret != CMD_STATUS_COMPLETE) {
+ queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
+ SCAN_POLL_INTERVAL);
+ goto exit;
+ }
+
+ ieee80211_scan_completed(priv->hw, false);
+
+ if (is_valid_ether_addr(priv->bssid))
+ at76_join(priv);
+
+ ieee80211_wake_queues(priv->hw);
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+static int at76_hw_scan(struct ieee80211_hw *hw,
+ struct cfg80211_scan_request *req)
+{
+ struct at76_priv *priv = hw->priv;
+ struct at76_req_scan scan;
+ u8 *ssid = NULL;
+ int ret, len = 0;
+
+ at76_dbg(DBG_MAC80211, "%s():", __func__);
+
+ if (priv->device_unplugged)
+ return 0;
+
+ mutex_lock(&priv->mtx);
+
+ ieee80211_stop_queues(hw);
+
+ memset(&scan, 0, sizeof(struct at76_req_scan));
+ memset(scan.bssid, 0xFF, ETH_ALEN);
+
+ if (req->n_ssids) {
+ scan.scan_type = SCAN_TYPE_ACTIVE;
+ ssid = req->ssids[0].ssid;
+ len = req->ssids[0].ssid_len;
+ } else {
+ scan.scan_type = SCAN_TYPE_PASSIVE;
+ }
+
+ if (len) {
+ memcpy(scan.essid, ssid, len);
+ scan.essid_size = len;
+ }
+
+ scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
+ scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
+ scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000);
+ scan.international_scan = 0;
+
+ at76_dbg(DBG_MAC80211, "%s: sending CMD_SCAN", __func__);
+ ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+
+ if (ret < 0) {
+ err("CMD_SCAN failed: %d", ret);
+ goto exit;
+ }
+
+ queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
+ SCAN_POLL_INTERVAL);
+
+exit:
+ mutex_unlock(&priv->mtx);
+
+ return 0;
+}
+
+static int at76_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct at76_priv *priv = hw->priv;
+
+ at76_dbg(DBG_MAC80211, "%s(): channel %d radio %d",
+ __func__, hw->conf.channel->hw_value,
+ hw->conf.radio_enabled);
+ at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:");
+
+ mutex_lock(&priv->mtx);
+
+ priv->channel = hw->conf.channel->hw_value;
+
+ if (is_valid_ether_addr(priv->bssid))
+ at76_join(priv);
+ else
+ at76_start_monitor(priv);
+
+ mutex_unlock(&priv->mtx);
+
+ return 0;
+}
+
+static int at76_config_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_if_conf *conf)
+{
+ struct at76_priv *priv = hw->priv;
+
+ at76_dbg(DBG_MAC80211, "%s():", __func__);
+ at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:");
+
+ mutex_lock(&priv->mtx);
+
+ memcpy(priv->bssid, conf->bssid, ETH_ALEN);
+
+ if (is_valid_ether_addr(priv->bssid))
+ /* mac80211 is joining a bss */
+ at76_join(priv);
+
+ mutex_unlock(&priv->mtx);
+
+ return 0;
+}
+
+/* must be atomic */
+static void at76_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags, int mc_count,
+ struct dev_addr_list *mc_list)
+{
+ struct at76_priv *priv = hw->priv;
+ int flags;
+
+ at76_dbg(DBG_MAC80211, "%s(): changed_flags=0x%08x "
+ "total_flags=0x%08x mc_count=%d",
+ __func__, changed_flags, *total_flags, mc_count);
+
+ flags = changed_flags & AT76_SUPPORTED_FILTERS;
+ *total_flags = AT76_SUPPORTED_FILTERS;
+
+ /* Bail out after updating flags to prevent a WARN_ON in mac80211. */
+ if (priv->device_unplugged)
+ return;
+
+ /* FIXME: access to priv->promisc should be protected with
+ * priv->mtx, but it's impossible because this function needs to be
+ * atomic */
+
+ if (flags && !priv->promisc) {
+ /* mac80211 wants us to enable promiscuous mode */
+ priv->promisc = 1;
+ } else if (!flags && priv->promisc) {
+ /* we need to disable promiscuous mode */
+ priv->promisc = 0;
+ } else
+ return;
+
+ queue_work(hw->workqueue, &priv->work_set_promisc);
+}
+
+static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
+{
+ struct at76_priv *priv = hw->priv;
+
+ int i;
+
+ at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
+ "key->keylen %d",
+ __func__, cmd, key->alg, key->keyidx, key->keylen);
+
+ if (key->alg != ALG_WEP)
+ return -EOPNOTSUPP;
+
+ key->hw_key_idx = key->keyidx;
+
+ mutex_lock(&priv->mtx);
+
+ switch (cmd) {
+ case SET_KEY:
+ memcpy(priv->wep_keys[key->keyidx], key->key, key->keylen);
+ priv->wep_keys_len[key->keyidx] = key->keylen;
+
+ /* FIXME: find out how to do this properly */
+ priv->wep_key_id = key->keyidx;
+
+ break;
+ case DISABLE_KEY:
+ default:
+ priv->wep_keys_len[key->keyidx] = 0;
+ break;
+ }
+
+ priv->wep_enabled = 0;
+
+ for (i = 0; i < WEP_KEYS; i++) {
+ if (priv->wep_keys_len[i] != 0)
+ priv->wep_enabled = 1;
+ }
+
+ at76_startup_device(priv);
+
+ mutex_unlock(&priv->mtx);
+
+ return 0;
+}
+
+static const struct ieee80211_ops at76_ops = {
+ .tx = at76_mac80211_tx,
+ .add_interface = at76_add_interface,
+ .remove_interface = at76_remove_interface,
+ .config = at76_config,
+ .config_interface = at76_config_interface,
+ .configure_filter = at76_configure_filter,
+ .start = at76_mac80211_start,
+ .stop = at76_mac80211_stop,
+ .hw_scan = at76_hw_scan,
+ .set_key = at76_set_key,
+};
+
+/* Allocate network device and initialize private data */
+static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
+{
+ struct ieee80211_hw *hw;
+ struct at76_priv *priv;
+
+ hw = ieee80211_alloc_hw(sizeof(struct at76_priv), &at76_ops);
+ if (!hw) {
+ printk(KERN_ERR DRIVER_NAME ": could not register"
+ " ieee80211_hw\n");
+ return NULL;
+ }
+
+ priv = hw->priv;
+ priv->hw = hw;
+
+ priv->udev = udev;
+
+ mutex_init(&priv->mtx);
+ INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc);
+ INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
+ INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan);
+
+ tasklet_init(&priv->rx_tasklet, at76_rx_tasklet, 0);
+
+ priv->pm_mode = AT76_PM_OFF;
+ priv->pm_period = 0;
+
+ /* unit us */
+ priv->hw->channel_change_time = 100000;
+
+ return priv;
+}
+
+static int at76_alloc_urbs(struct at76_priv *priv,
+ struct usb_interface *interface)
+{
+ struct usb_endpoint_descriptor *endpoint, *ep_in, *ep_out;
+ int i;
+ int buffer_size;
+ struct usb_host_interface *iface_desc;
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
+
+ at76_dbg(DBG_URB, "%s: NumEndpoints %d ", __func__,
+ interface->altsetting[0].desc.bNumEndpoints);
+
+ ep_in = NULL;
+ ep_out = NULL;
+ iface_desc = interface->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ at76_dbg(DBG_URB, "%s: %d. endpoint: addr 0x%x attr 0x%x",
+ __func__, i, endpoint->bEndpointAddress,
+ endpoint->bmAttributes);
+
+ if (!ep_in && usb_endpoint_is_bulk_in(endpoint))
+ ep_in = endpoint;
+
+ if (!ep_out && usb_endpoint_is_bulk_out(endpoint))
+ ep_out = endpoint;
+ }
+
+ if (!ep_in || !ep_out) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "bulk endpoints missing\n");
+ return -ENXIO;
+ }
+
+ priv->rx_pipe = usb_rcvbulkpipe(priv->udev, ep_in->bEndpointAddress);
+ priv->tx_pipe = usb_sndbulkpipe(priv->udev, ep_out->bEndpointAddress);
+
+ priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+ priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!priv->rx_urb || !priv->tx_urb) {
+ dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n");
+ return -ENOMEM;
+ }
+
+ buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE;
+ priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!priv->bulk_out_buffer) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot allocate output buffer\n");
+ return -ENOMEM;
+ }
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
+
+ return 0;
+}
+
+static struct ieee80211_rate at76_rates[] = {
+ { .bitrate = 10, .hw_value = TX_RATE_1MBIT, },
+ { .bitrate = 20, .hw_value = TX_RATE_2MBIT, },
+ { .bitrate = 55, .hw_value = TX_RATE_5_5MBIT, },
+ { .bitrate = 110, .hw_value = TX_RATE_11MBIT, },
+};
+
+static struct ieee80211_channel at76_channels[] = {
+ { .center_freq = 2412, .hw_value = 1 },
+ { .center_freq = 2417, .hw_value = 2 },
+ { .center_freq = 2422, .hw_value = 3 },
+ { .center_freq = 2427, .hw_value = 4 },
+ { .center_freq = 2432, .hw_value = 5 },
+ { .center_freq = 2437, .hw_value = 6 },
+ { .center_freq = 2442, .hw_value = 7 },
+ { .center_freq = 2447, .hw_value = 8 },
+ { .center_freq = 2452, .hw_value = 9 },
+ { .center_freq = 2457, .hw_value = 10 },
+ { .center_freq = 2462, .hw_value = 11 },
+ { .center_freq = 2467, .hw_value = 12 },
+ { .center_freq = 2472, .hw_value = 13 },
+ { .center_freq = 2484, .hw_value = 14 }
+};
+
+static struct ieee80211_supported_band at76_supported_band = {
+ .channels = at76_channels,
+ .n_channels = ARRAY_SIZE(at76_channels),
+ .bitrates = at76_rates,
+ .n_bitrates = ARRAY_SIZE(at76_rates),
+};
+
+/* Register network device and initialize the hardware */
+static int at76_init_new_device(struct at76_priv *priv,
+ struct usb_interface *interface)
+{
+ int ret;
+
+ /* set up the endpoint information */
+ /* check out the endpoints */
+
+ at76_dbg(DBG_DEVSTART, "USB interface: %d endpoints",
+ interface->cur_altsetting->desc.bNumEndpoints);
+
+ ret = at76_alloc_urbs(priv, interface);
+ if (ret < 0)
+ goto exit;
+
+ /* MAC address */
+ ret = at76_get_hw_config(priv);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot get MAC address\n");
+ goto exit;
+ }
+
+ priv->domain = at76_get_reg_domain(priv->regulatory_domain);
+
+ priv->channel = DEF_CHANNEL;
+ priv->iw_mode = IW_MODE_INFRA;
+ priv->rts_threshold = DEF_RTS_THRESHOLD;
+ priv->frag_threshold = DEF_FRAG_THRESHOLD;
+ priv->short_retry_limit = DEF_SHORT_RETRY_LIMIT;
+ priv->txrate = TX_RATE_AUTO;
+ priv->preamble_type = PREAMBLE_TYPE_LONG;
+ priv->beacon_period = 100;
+ priv->auth_mode = WLAN_AUTH_OPEN;
+ priv->scan_min_time = DEF_SCAN_MIN_TIME;
+ priv->scan_max_time = DEF_SCAN_MAX_TIME;
+ priv->scan_mode = SCAN_TYPE_ACTIVE;
+ priv->device_unplugged = 0;
+
+ /* mac80211 initialisation */
+ priv->hw->wiphy->max_scan_ssids = 1;
+ priv->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+ priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &at76_supported_band;
+ priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_SIGNAL_UNSPEC;
+ priv->hw->max_signal = 100;
+
+ SET_IEEE80211_DEV(priv->hw, &interface->dev);
+ SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
+
+ ret = ieee80211_register_hw(priv->hw);
+ if (ret) {
+ printk(KERN_ERR "cannot register mac80211 hw (status %d)!\n",
+ ret);
+ goto exit;
+ }
+
+ priv->mac80211_registered = 1;
+
+ printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
+ wiphy_name(priv->hw->wiphy),
+ dev_name(&interface->dev), mac2str(priv->mac_addr),
+ priv->fw_version.major, priv->fw_version.minor,
+ priv->fw_version.patch, priv->fw_version.build);
+ printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n",
+ wiphy_name(priv->hw->wiphy),
+ priv->regulatory_domain, priv->domain->name);
+
+exit:
+ return ret;
+}
+
+static void at76_delete_device(struct at76_priv *priv)
+{
+ at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
+
+ /* The device is gone, don't bother turning it off */
+ priv->device_unplugged = 1;
+
+ tasklet_kill(&priv->rx_tasklet);
+
+ if (priv->mac80211_registered) {
+ cancel_delayed_work(&priv->dwork_hw_scan);
+ flush_workqueue(priv->hw->workqueue);
+ ieee80211_unregister_hw(priv->hw);
+ }
+
+ if (priv->tx_urb) {
+ usb_kill_urb(priv->tx_urb);
+ usb_free_urb(priv->tx_urb);
+ }
+ if (priv->rx_urb) {
+ usb_kill_urb(priv->rx_urb);
+ usb_free_urb(priv->rx_urb);
+ }
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__);
+
+ kfree(priv->bulk_out_buffer);
+
+ del_timer_sync(&ledtrig_tx_timer);
+
+ if (priv->rx_skb)
+ kfree_skb(priv->rx_skb);
+
+ usb_put_dev(priv->udev);
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/ieee80211_hw",
+ __func__);
+ ieee80211_free_hw(priv->hw);
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
+}
+
+static int at76_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ int ret;
+ struct at76_priv *priv;
+ struct fwentry *fwe;
+ struct usb_device *udev;
+ int op_mode;
+ int need_ext_fw = 0;
+ struct mib_fw_version fwv;
+ int board_type = (int)id->driver_info;
+
+ udev = usb_get_dev(interface_to_usbdev(interface));
+
+ /* Load firmware into kernel memory */
+ fwe = at76_load_firmware(udev, board_type);
+ if (!fwe) {
+ ret = -ENOENT;
+ goto error;
+ }
+
+ op_mode = at76_get_op_mode(udev);
+
+ at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
+
+ /* we get OPMODE_NONE with 2.4.23, SMC2662W-AR ???
+ we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
+
+ if (op_mode == OPMODE_HW_CONFIG_MODE) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot handle a device in HW_CONFIG_MODE\n");
+ ret = -EBUSY;
+ goto error;
+ }
+
+ if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH
+ && op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
+ /* download internal firmware part */
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading internal firmware\n");
+ ret = at76_load_internal_fw(udev, fwe);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d downloading internal firmware\n",
+ ret);
+ goto error;
+ }
+ usb_put_dev(udev);
+ return ret;
+ }
+
+ /* Internal firmware already inside the device. Get firmware
+ * version to test if external firmware is loaded.
+ * This works only for newer firmware, e.g. the Intersil 0.90.x
+ * says "control timeout on ep0in" and subsequent
+ * at76_get_op_mode() fail too :-( */
+
+ /* if version >= 0.100.x.y or device with built-in flash we can
+ * query the device for the fw version */
+ if ((fwe->fw_version.major > 0 || fwe->fw_version.minor >= 100)
+ || (op_mode == OPMODE_NORMAL_NIC_WITH_FLASH)) {
+ ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
+ if (ret < 0 || (fwv.major | fwv.minor) == 0)
+ need_ext_fw = 1;
+ } else
+ /* No way to check firmware version, reload to be sure */
+ need_ext_fw = 1;
+
+ if (need_ext_fw) {
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading external firmware\n");
+
+ ret = at76_load_external_fw(udev, fwe);
+ if (ret)
+ goto error;
+
+ /* Re-check firmware version */
+ ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d getting firmware version\n", ret);
+ goto error;
+ }
+ }
+
+ priv = at76_alloc_new_device(udev);
+ if (!priv) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ usb_set_intfdata(interface, priv);
+
+ memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version));
+ priv->board_type = board_type;
+
+ ret = at76_init_new_device(priv, interface);
+ if (ret < 0)
+ at76_delete_device(priv);
+
+ return ret;
+
+error:
+ usb_put_dev(udev);
+ return ret;
+}
+
+static void at76_disconnect(struct usb_interface *interface)
+{
+ struct at76_priv *priv;
+
+ priv = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
+
+ /* Disconnect after loading internal firmware */
+ if (!priv)
+ return;
+
+ printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy));
+ at76_delete_device(priv);
+ dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
+}
+
+/* Structure for registering this driver with the USB subsystem */
+static struct usb_driver at76_driver = {
+ .name = DRIVER_NAME,
+ .probe = at76_probe,
+ .disconnect = at76_disconnect,
+ .id_table = dev_table,
+};
+
+static int __init at76_mod_init(void)
+{
+ int result;
+
+ printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " loading\n");
+
+ mutex_init(&fw_mutex);
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&at76_driver);
+ if (result < 0)
+ printk(KERN_ERR DRIVER_NAME
+ ": usb_register failed (status %d)\n", result);
+
+ led_trigger_register_simple("at76_usb-tx", &ledtrig_tx);
+ return result;
+}
+
+static void __exit at76_mod_exit(void)
+{
+ int i;
+
+ printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " unloading\n");
+ usb_deregister(&at76_driver);
+ for (i = 0; i < ARRAY_SIZE(firmwares); i++) {
+ if (firmwares[i].fw)
+ release_firmware(firmwares[i].fw);
+ }
+ led_trigger_unregister_simple(ledtrig_tx);
+}
+
+module_param_named(debug, at76_debug, uint, 0600);
+MODULE_PARM_DESC(debug, "Debugging level");
+
+module_init(at76_mod_init);
+module_exit(at76_mod_exit);
+
+MODULE_AUTHOR("Oliver Kurth <oku@masqmail.cx>");
+MODULE_AUTHOR("Joerg Albert <joerg.albert@gmx.de>");
+MODULE_AUTHOR("Alex <alex@foogod.com>");
+MODULE_AUTHOR("Nick Jones");
+MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>");
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
+MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>");
+MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/at76c50x-usb.h b/drivers/net/wireless/at76c50x-usb.h
new file mode 100644
index 000000000000..1ec5ccffdbc0
--- /dev/null
+++ b/drivers/net/wireless/at76c50x-usb.h
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2002,2003 Oliver Kurth
+ * (c) 2003,2004 Joerg Albert <joerg.albert@gmx.de>
+ * (c) 2007 Guido Guenther <agx@sigxcpu.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This driver was based on information from the Sourceforge driver
+ * released and maintained by Atmel:
+ *
+ * http://sourceforge.net/projects/atmelwlandriver/
+ *
+ * Although the code was completely re-written,
+ * it would have been impossible without Atmel's decision to
+ * release an Open Source driver (unfortunately the firmware was
+ * kept binary only). Thanks for that decision to Atmel!
+ */
+
+#ifndef _AT76_USB_H
+#define _AT76_USB_H
+
+/* Board types */
+enum board_type {
+ BOARD_503_ISL3861 = 1,
+ BOARD_503_ISL3863 = 2,
+ BOARD_503 = 3,
+ BOARD_503_ACC = 4,
+ BOARD_505 = 5,
+ BOARD_505_2958 = 6,
+ BOARD_505A = 7,
+ BOARD_505AMX = 8
+};
+
+#define CMD_STATUS_IDLE 0x00
+#define CMD_STATUS_COMPLETE 0x01
+#define CMD_STATUS_UNKNOWN 0x02
+#define CMD_STATUS_INVALID_PARAMETER 0x03
+#define CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
+#define CMD_STATUS_TIME_OUT 0x07
+#define CMD_STATUS_IN_PROGRESS 0x08
+#define CMD_STATUS_HOST_FAILURE 0xff
+#define CMD_STATUS_SCAN_FAILED 0xf0
+
+/* answers to get op mode */
+#define OPMODE_NONE 0x00
+#define OPMODE_NORMAL_NIC_WITH_FLASH 0x01
+#define OPMODE_HW_CONFIG_MODE 0x02
+#define OPMODE_DFU_MODE_WITH_FLASH 0x03
+#define OPMODE_NORMAL_NIC_WITHOUT_FLASH 0x04
+
+#define CMD_SET_MIB 0x01
+#define CMD_GET_MIB 0x02
+#define CMD_SCAN 0x03
+#define CMD_JOIN 0x04
+#define CMD_START_IBSS 0x05
+#define CMD_RADIO_ON 0x06
+#define CMD_RADIO_OFF 0x07
+#define CMD_STARTUP 0x0B
+
+#define MIB_LOCAL 0x01
+#define MIB_MAC_ADDR 0x02
+#define MIB_MAC 0x03
+#define MIB_MAC_MGMT 0x05
+#define MIB_MAC_WEP 0x06
+#define MIB_PHY 0x07
+#define MIB_FW_VERSION 0x08
+#define MIB_MDOMAIN 0x09
+
+#define ADHOC_MODE 1
+#define INFRASTRUCTURE_MODE 2
+
+/* values for struct mib_local, field preamble_type */
+#define PREAMBLE_TYPE_LONG 0
+#define PREAMBLE_TYPE_SHORT 1
+#define PREAMBLE_TYPE_AUTO 2
+
+/* values for tx_rate */
+#define TX_RATE_1MBIT 0
+#define TX_RATE_2MBIT 1
+#define TX_RATE_5_5MBIT 2
+#define TX_RATE_11MBIT 3
+#define TX_RATE_AUTO 4
+
+/* power management modes */
+#define AT76_PM_OFF 1
+#define AT76_PM_ON 2
+#define AT76_PM_SMART 3
+
+struct hwcfg_r505 {
+ u8 cr39_values[14];
+ u8 reserved1[14];
+ u8 bb_cr[14];
+ u8 pidvid[4];
+ u8 mac_addr[ETH_ALEN];
+ u8 regulatory_domain;
+ u8 reserved2[14];
+ u8 cr15_values[14];
+ u8 reserved3[3];
+} __attribute__((packed));
+
+struct hwcfg_rfmd {
+ u8 cr20_values[14];
+ u8 cr21_values[14];
+ u8 bb_cr[14];
+ u8 pidvid[4];
+ u8 mac_addr[ETH_ALEN];
+ u8 regulatory_domain;
+ u8 low_power_values[14];
+ u8 normal_power_values[14];
+ u8 reserved1[3];
+} __attribute__((packed));
+
+struct hwcfg_intersil {
+ u8 mac_addr[ETH_ALEN];
+ u8 cr31_values[14];
+ u8 cr58_values[14];
+ u8 pidvid[4];
+ u8 regulatory_domain;
+ u8 reserved[1];
+} __attribute__((packed));
+
+union at76_hwcfg {
+ struct hwcfg_intersil i;
+ struct hwcfg_rfmd r3;
+ struct hwcfg_r505 r5;
+};
+
+#define WEP_SMALL_KEY_LEN (40 / 8)
+#define WEP_LARGE_KEY_LEN (104 / 8)
+#define WEP_KEYS (4)
+
+struct at76_card_config {
+ u8 exclude_unencrypted;
+ u8 promiscuous_mode;
+ u8 short_retry_limit;
+ u8 encryption_type;
+ __le16 rts_threshold;
+ __le16 fragmentation_threshold; /* 256..2346 */
+ u8 basic_rate_set[4];
+ u8 auto_rate_fallback; /* 0,1 */
+ u8 channel;
+ u8 privacy_invoked;
+ u8 wep_default_key_id; /* 0..3 */
+ u8 current_ssid[32];
+ u8 wep_default_key_value[4][WEP_LARGE_KEY_LEN];
+ u8 ssid_len;
+ u8 short_preamble;
+ __le16 beacon_period;
+} __attribute__((packed));
+
+struct at76_command {
+ u8 cmd;
+ u8 reserved;
+ __le16 size;
+ u8 data[0];
+} __attribute__((packed));
+
+/* Length of Atmel-specific Rx header before 802.11 frame */
+#define AT76_RX_HDRLEN offsetof(struct at76_rx_buffer, packet)
+
+struct at76_rx_buffer {
+ __le16 wlength;
+ u8 rx_rate;
+ u8 newbss;
+ u8 fragmentation;
+ u8 rssi;
+ u8 link_quality;
+ u8 noise_level;
+ __le32 rx_time;
+ u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
+} __attribute__((packed));
+
+/* Length of Atmel-specific Tx header before 802.11 frame */
+#define AT76_TX_HDRLEN offsetof(struct at76_tx_buffer, packet)
+
+struct at76_tx_buffer {
+ __le16 wlength;
+ u8 tx_rate;
+ u8 padding;
+ u8 reserved[4];
+ u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
+} __attribute__((packed));
+
+/* defines for scan_type below */
+#define SCAN_TYPE_ACTIVE 0
+#define SCAN_TYPE_PASSIVE 1
+
+struct at76_req_scan {
+ u8 bssid[ETH_ALEN];
+ u8 essid[32];
+ u8 scan_type;
+ u8 channel;
+ __le16 probe_delay;
+ __le16 min_channel_time;
+ __le16 max_channel_time;
+ u8 essid_size;
+ u8 international_scan;
+} __attribute__((packed));
+
+struct at76_req_ibss {
+ u8 bssid[ETH_ALEN];
+ u8 essid[32];
+ u8 bss_type;
+ u8 channel;
+ u8 essid_size;
+ u8 reserved[3];
+} __attribute__((packed));
+
+struct at76_req_join {
+ u8 bssid[ETH_ALEN];
+ u8 essid[32];
+ u8 bss_type;
+ u8 channel;
+ __le16 timeout;
+ u8 essid_size;
+ u8 reserved;
+} __attribute__((packed));
+
+struct set_mib_buffer {
+ u8 type;
+ u8 size;
+ u8 index;
+ u8 reserved;
+ union {
+ u8 byte;
+ __le16 word;
+ u8 addr[ETH_ALEN];
+ } data;
+} __attribute__((packed));
+
+struct mib_local {
+ u16 reserved0;
+ u8 beacon_enable;
+ u8 txautorate_fallback;
+ u8 reserved1;
+ u8 ssid_size;
+ u8 promiscuous_mode;
+ u16 reserved2;
+ u8 preamble_type;
+ u16 reserved3;
+} __attribute__((packed));
+
+struct mib_mac_addr {
+ u8 mac_addr[ETH_ALEN];
+ u8 res[2]; /* ??? */
+ u8 group_addr[4][ETH_ALEN];
+ u8 group_addr_status[4];
+} __attribute__((packed));
+
+struct mib_mac {
+ __le32 max_tx_msdu_lifetime;
+ __le32 max_rx_lifetime;
+ __le16 frag_threshold;
+ __le16 rts_threshold;
+ __le16 cwmin;
+ __le16 cwmax;
+ u8 short_retry_time;
+ u8 long_retry_time;
+ u8 scan_type; /* active or passive */
+ u8 scan_channel;
+ __le16 probe_delay; /* delay before ProbeReq in active scan, RO */
+ __le16 min_channel_time;
+ __le16 max_channel_time;
+ __le16 listen_interval;
+ u8 desired_ssid[32];
+ u8 desired_bssid[ETH_ALEN];
+ u8 desired_bsstype; /* ad-hoc or infrastructure */
+ u8 reserved2;
+} __attribute__((packed));
+
+struct mib_mac_mgmt {
+ __le16 beacon_period;
+ __le16 CFP_max_duration;
+ __le16 medium_occupancy_limit;
+ __le16 station_id; /* assoc id */
+ __le16 ATIM_window;
+ u8 CFP_mode;
+ u8 privacy_option_implemented;
+ u8 DTIM_period;
+ u8 CFP_period;
+ u8 current_bssid[ETH_ALEN];
+ u8 current_essid[32];
+ u8 current_bss_type;
+ u8 power_mgmt_mode;
+ /* rfmd and 505 */
+ u8 ibss_change;
+ u8 res;
+ u8 multi_domain_capability_implemented;
+ u8 multi_domain_capability_enabled;
+ u8 country_string[3];
+ u8 reserved[3];
+} __attribute__((packed));
+
+struct mib_mac_wep {
+ u8 privacy_invoked; /* 0 disable encr., 1 enable encr */
+ u8 wep_default_key_id;
+ u8 wep_key_mapping_len;
+ u8 exclude_unencrypted;
+ __le32 wep_icv_error_count;
+ __le32 wep_excluded_count;
+ u8 wep_default_keyvalue[WEP_KEYS][WEP_LARGE_KEY_LEN];
+ u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */
+} __attribute__((packed));
+
+struct mib_phy {
+ __le32 ed_threshold;
+
+ __le16 slot_time;
+ __le16 sifs_time;
+ __le16 preamble_length;
+ __le16 plcp_header_length;
+ __le16 mpdu_max_length;
+ __le16 cca_mode_supported;
+
+ u8 operation_rate_set[4];
+ u8 channel_id;
+ u8 current_cca_mode;
+ u8 phy_type;
+ u8 current_reg_domain;
+} __attribute__((packed));
+
+struct mib_fw_version {
+ u8 major;
+ u8 minor;
+ u8 patch;
+ u8 build;
+} __attribute__((packed));
+
+struct mib_mdomain {
+ u8 tx_powerlevel[14];
+ u8 channel_list[14]; /* 0 for invalid channels */
+} __attribute__((packed));
+
+struct at76_fw_header {
+ __le32 crc; /* CRC32 of the whole image */
+ __le32 board_type; /* firmware compatibility code */
+ u8 build; /* firmware build number */
+ u8 patch; /* firmware patch level */
+ u8 minor; /* firmware minor version */
+ u8 major; /* firmware major version */
+ __le32 str_offset; /* offset of the copyright string */
+ __le32 int_fw_offset; /* internal firmware image offset */
+ __le32 int_fw_len; /* internal firmware image length */
+ __le32 ext_fw_offset; /* external firmware image offset */
+ __le32 ext_fw_len; /* external firmware image length */
+} __attribute__((packed));
+
+/* a description of a regulatory domain and the allowed channels */
+struct reg_domain {
+ u16 code;
+ char const *name;
+ u32 channel_map; /* if bit N is set, channel (N+1) is allowed */
+};
+
+/* Data for one loaded firmware file */
+struct fwentry {
+ const char *const fwname;
+ const struct firmware *fw;
+ int extfw_size;
+ int intfw_size;
+ /* pointer to loaded firmware, no need to free */
+ u8 *extfw; /* external firmware, extfw_size bytes long */
+ u8 *intfw; /* internal firmware, intfw_size bytes long */
+ enum board_type board_type; /* board type */
+ struct mib_fw_version fw_version;
+ int loaded; /* Loaded and parsed successfully */
+};
+
+struct at76_priv {
+ struct usb_device *udev; /* USB device pointer */
+
+ struct sk_buff *rx_skb; /* skbuff for receiving data */
+ struct sk_buff *tx_skb; /* skbuff for transmitting data */
+ void *bulk_out_buffer; /* buffer for sending data */
+
+ struct urb *tx_urb; /* URB for sending data */
+ struct urb *rx_urb; /* URB for receiving data */
+
+ unsigned int tx_pipe; /* bulk out pipe */
+ unsigned int rx_pipe; /* bulk in pipe */
+
+ struct mutex mtx; /* locks this structure */
+
+ /* work queues */
+ struct work_struct work_set_promisc;
+ struct work_struct work_submit_rx;
+ struct delayed_work dwork_hw_scan;
+
+ struct tasklet_struct rx_tasklet;
+
+ /* the WEP stuff */
+ int wep_enabled; /* 1 if WEP is enabled */
+ int wep_key_id; /* key id to be used */
+ u8 wep_keys[WEP_KEYS][WEP_LARGE_KEY_LEN]; /* WEP keys */
+ u8 wep_keys_len[WEP_KEYS]; /* length of WEP keys */
+
+ int channel;
+ int iw_mode;
+ u8 bssid[ETH_ALEN];
+ u8 essid[IW_ESSID_MAX_SIZE];
+ int essid_size;
+ int radio_on;
+ int promisc;
+
+ int preamble_type; /* 0 - long, 1 - short, 2 - auto */
+ int auth_mode; /* authentication type: 0 open, 1 shared key */
+ int txrate; /* 0,1,2,3 = 1,2,5.5,11 Mbps, 4 is auto */
+ int frag_threshold; /* threshold for fragmentation of tx packets */
+ int rts_threshold; /* threshold for RTS mechanism */
+ int short_retry_limit;
+
+ int scan_min_time; /* scan min channel time */
+ int scan_max_time; /* scan max channel time */
+ int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
+ int scan_need_any; /* if set, need to scan for any ESSID */
+
+ u16 assoc_id; /* current association ID, if associated */
+
+ u8 pm_mode; /* power management mode */
+ u32 pm_period; /* power management period in microseconds */
+
+ struct reg_domain const *domain; /* reg domain description */
+
+ /* These fields contain HW config provided by the device (not all of
+ * these fields are used by all board types) */
+ u8 mac_addr[ETH_ALEN];
+ u8 regulatory_domain;
+
+ struct at76_card_config card_config;
+
+ enum board_type board_type;
+ struct mib_fw_version fw_version;
+
+ unsigned int device_unplugged:1;
+ unsigned int netdev_registered:1;
+ struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */
+
+ int beacon_period; /* period of mgmt beacons, Kus */
+
+ struct ieee80211_hw *hw;
+ int mac80211_registered;
+};
+
+#define AT76_SUPPORTED_FILTERS FIF_PROMISC_IN_BSS
+
+#define SCAN_POLL_INTERVAL (HZ / 4)
+
+#define CMD_COMPLETION_TIMEOUT (5 * HZ)
+
+#define DEF_RTS_THRESHOLD 1536
+#define DEF_FRAG_THRESHOLD 1536
+#define DEF_SHORT_RETRY_LIMIT 8
+#define DEF_CHANNEL 10
+#define DEF_SCAN_MIN_TIME 10
+#define DEF_SCAN_MAX_TIME 120
+
+/* the max padding size for tx in bytes (see calc_padding) */
+#define MAX_PADDING_SIZE 53
+
+#endif /* _AT76_USB_H */
diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath5k/Makefile
index 719cfaef7085..84a74c5248e5 100644
--- a/drivers/net/wireless/ath5k/Makefile
+++ b/drivers/net/wireless/ath5k/Makefile
@@ -10,5 +10,6 @@ ath5k-y += phy.o
ath5k-y += reset.o
ath5k-y += attach.o
ath5k-y += base.o
+ath5k-y += led.o
ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o
obj-$(CONFIG_ATH5K) += ath5k.o
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 183ffc8e62ca..0b616e72fe05 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -165,9 +165,6 @@
#define AR5K_INI_VAL_XR 0
#define AR5K_INI_VAL_MAX 5
-#define AR5K_RF5111_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS
-#define AR5K_RF5112_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS
-
/* Used for BSSID etc manipulation */
#define AR5K_LOW_ID(_a)( \
(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \
@@ -207,9 +204,9 @@
#define AR5K_TUNE_CWMAX_11B 1023
#define AR5K_TUNE_CWMAX_XR 7
#define AR5K_TUNE_NOISE_FLOOR -72
-#define AR5K_TUNE_MAX_TXPOWER 60
-#define AR5K_TUNE_DEFAULT_TXPOWER 30
-#define AR5K_TUNE_TPC_TXPOWER true
+#define AR5K_TUNE_MAX_TXPOWER 63
+#define AR5K_TUNE_DEFAULT_TXPOWER 25
+#define AR5K_TUNE_TPC_TXPOWER false
#define AR5K_TUNE_ANT_DIVERSITY true
#define AR5K_TUNE_HWTXTRIES 4
@@ -225,6 +222,7 @@
#endif
/* Initial values */
+#define AR5K_INIT_CYCRSSI_THR1 2
#define AR5K_INIT_TX_LATENCY 502
#define AR5K_INIT_USEC 39
#define AR5K_INIT_USEC_TURBO 79
@@ -316,7 +314,7 @@ struct ath5k_srev_name {
#define AR5K_SREV_AR5424 0x90 /* Condor */
#define AR5K_SREV_AR5413 0xa4 /* Eagle lite */
#define AR5K_SREV_AR5414 0xa0 /* Eagle */
-#define AR5K_SREV_AR2415 0xb0 /* Cobra */
+#define AR5K_SREV_AR2415 0xb0 /* Talon */
#define AR5K_SREV_AR5416 0xc0 /* PCI-E */
#define AR5K_SREV_AR5418 0xca /* PCI-E */
#define AR5K_SREV_AR2425 0xe0 /* Swan */
@@ -334,7 +332,7 @@ struct ath5k_srev_name {
#define AR5K_SREV_RAD_2112B 0x46
#define AR5K_SREV_RAD_2413 0x50
#define AR5K_SREV_RAD_5413 0x60
-#define AR5K_SREV_RAD_2316 0x70
+#define AR5K_SREV_RAD_2316 0x70 /* Cobra SoC */
#define AR5K_SREV_RAD_2317 0x80
#define AR5K_SREV_RAD_5424 0xa0 /* Mostly same as 5413 */
#define AR5K_SREV_RAD_2425 0xa2
@@ -342,7 +340,8 @@ struct ath5k_srev_name {
#define AR5K_SREV_PHY_5211 0x30
#define AR5K_SREV_PHY_5212 0x41
-#define AR5K_SREV_PHY_2112B 0x43
+#define AR5K_SREV_PHY_5212A 0x42
+#define AR5K_SREV_PHY_5212B 0x43
#define AR5K_SREV_PHY_2413 0x45
#define AR5K_SREV_PHY_5413 0x61
#define AR5K_SREV_PHY_2425 0x70
@@ -552,11 +551,11 @@ enum ath5k_pkt_type {
*/
#define AR5K_TXPOWER_OFDM(_r, _v) ( \
((0 & 1) << ((_v) + 6)) | \
- (((ah->ah_txpower.txp_rates[(_r)]) & 0x3f) << (_v)) \
+ (((ah->ah_txpower.txp_rates_power_table[(_r)]) & 0x3f) << (_v)) \
)
#define AR5K_TXPOWER_CCK(_r, _v) ( \
- (ah->ah_txpower.txp_rates[(_r)] & 0x3f) << (_v) \
+ (ah->ah_txpower.txp_rates_power_table[(_r)] & 0x3f) << (_v) \
)
/*
@@ -649,49 +648,21 @@ struct ath5k_beacon_state {
enum ath5k_rfgain {
AR5K_RFGAIN_INACTIVE = 0,
+ AR5K_RFGAIN_ACTIVE,
AR5K_RFGAIN_READ_REQUESTED,
AR5K_RFGAIN_NEED_CHANGE,
};
-#define AR5K_GAIN_CRN_FIX_BITS_5111 4
-#define AR5K_GAIN_CRN_FIX_BITS_5112 7
-#define AR5K_GAIN_CRN_MAX_FIX_BITS AR5K_GAIN_CRN_FIX_BITS_5112
-#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN 15
-#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN 20
-#define AR5K_GAIN_CCK_PROBE_CORR 5
-#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA 15
-#define AR5K_GAIN_STEP_COUNT 10
-#define AR5K_GAIN_PARAM_TX_CLIP 0
-#define AR5K_GAIN_PARAM_PD_90 1
-#define AR5K_GAIN_PARAM_PD_84 2
-#define AR5K_GAIN_PARAM_GAIN_SEL 3
-#define AR5K_GAIN_PARAM_MIX_ORN 0
-#define AR5K_GAIN_PARAM_PD_138 1
-#define AR5K_GAIN_PARAM_PD_137 2
-#define AR5K_GAIN_PARAM_PD_136 3
-#define AR5K_GAIN_PARAM_PD_132 4
-#define AR5K_GAIN_PARAM_PD_131 5
-#define AR5K_GAIN_PARAM_PD_130 6
-#define AR5K_GAIN_CHECK_ADJUST(_g) \
- ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
-
-struct ath5k_gain_opt_step {
- s16 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
- s32 gos_gain;
-};
-
struct ath5k_gain {
- u32 g_step_idx;
- u32 g_current;
- u32 g_target;
- u32 g_low;
- u32 g_high;
- u32 g_f_corr;
- u32 g_active;
- const struct ath5k_gain_opt_step *g_step;
+ u8 g_step_idx;
+ u8 g_current;
+ u8 g_target;
+ u8 g_low;
+ u8 g_high;
+ u8 g_f_corr;
+ u8 g_state;
};
-
/********************\
COMMON DEFINITIONS
\********************/
@@ -1053,7 +1024,6 @@ struct ath5k_hw {
bool ah_running;
bool ah_single_chip;
bool ah_combined_mic;
- enum ath5k_rfgain ah_rf_gain;
u32 ah_mac_srev;
u16 ah_mac_version;
@@ -1061,7 +1031,6 @@ struct ath5k_hw {
u16 ah_phy_revision;
u16 ah_radio_5ghz_revision;
u16 ah_radio_2ghz_revision;
- u32 ah_phy_spending;
enum ath5k_version ah_version;
enum ath5k_radio ah_radio;
@@ -1112,16 +1081,29 @@ struct ath5k_hw {
u32 ah_txq_isr;
u32 *ah_rf_banks;
size_t ah_rf_banks_size;
+ size_t ah_rf_regs_count;
struct ath5k_gain ah_gain;
- u32 ah_offset[AR5K_MAX_RF_BANKS];
+ u8 ah_offset[AR5K_MAX_RF_BANKS];
+
struct {
- u16 txp_pcdac[AR5K_EEPROM_POWER_TABLE_SIZE];
- u16 txp_rates[AR5K_MAX_RATES];
- s16 txp_min;
- s16 txp_max;
+ /* Temporary tables used for interpolation */
+ u8 tmpL[AR5K_EEPROM_N_PD_GAINS]
+ [AR5K_EEPROM_POWER_TABLE_SIZE];
+ u8 tmpR[AR5K_EEPROM_N_PD_GAINS]
+ [AR5K_EEPROM_POWER_TABLE_SIZE];
+ u8 txp_pd_table[AR5K_EEPROM_POWER_TABLE_SIZE * 2];
+ u16 txp_rates_power_table[AR5K_MAX_RATES];
+ u8 txp_min_idx;
bool txp_tpc;
+ /* Values in 0.25dB units */
+ s16 txp_min_pwr;
+ s16 txp_max_pwr;
+ s16 txp_offset;
s16 txp_ofdm;
+ /* Values in dB units */
+ s16 txp_cck_ofdm_pwr_delta;
+ s16 txp_cck_ofdm_gainf_delta;
} ah_txpower;
struct {
@@ -1159,6 +1141,12 @@ struct ath5k_hw {
extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
extern void ath5k_hw_detach(struct ath5k_hw *ah);
+/* LED functions */
+extern int ath5k_init_leds(struct ath5k_softc *sc);
+extern void ath5k_led_enable(struct ath5k_softc *sc);
+extern void ath5k_led_off(struct ath5k_softc *sc);
+extern void ath5k_unregister_leds(struct ath5k_softc *sc);
+
/* Reset Functions */
extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel);
@@ -1185,7 +1173,9 @@ extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_l
/* EEPROM access functions */
extern int ath5k_eeprom_init(struct ath5k_hw *ah);
+extern void ath5k_eeprom_detach(struct ath5k_hw *ah);
extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
+extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
/* Protocol Control Unit Functions */
extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
@@ -1206,6 +1196,7 @@ extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
/* Beacon control functions */
extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah);
extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
+extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
#if 0
@@ -1260,10 +1251,12 @@ extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
/* Initialize RF */
-extern int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode);
-extern int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq);
-extern enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah);
-extern int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah);
+extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel,
+ unsigned int mode);
+extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
+extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
+extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
/* PHY/RF channel functions */
extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
@@ -1276,8 +1269,8 @@ extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant);
extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
/* TX power setup */
-extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int txpower);
-extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power);
+extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
+extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 ee_mode, u8 txpower);
/*
* Functions used internaly
@@ -1285,6 +1278,7 @@ extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power);
/*
* Translate usec to hw clock units
+ * TODO: Half/quarter rate
*/
static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
{
@@ -1293,6 +1287,7 @@ static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
/*
* Translate hw clock units to usec
+ * TODO: Half/quarter rate
*/
static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
{
diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath5k/attach.c
index dea378f76731..70d376c63aac 100644
--- a/drivers/net/wireless/ath5k/attach.c
+++ b/drivers/net/wireless/ath5k/attach.c
@@ -34,14 +34,14 @@
static int ath5k_hw_post(struct ath5k_hw *ah)
{
- int i, c;
- u16 cur_reg;
- u16 regs[2] = {AR5K_STA_ID0, AR5K_PHY(8)};
- u32 var_pattern;
- u32 static_pattern[4] = {
+ static const u32 static_pattern[4] = {
0x55555555, 0xaaaaaaaa,
0x66666666, 0x99999999
};
+ static const u16 regs[2] = { AR5K_STA_ID0, AR5K_PHY(8) };
+ int i, c;
+ u16 cur_reg;
+ u32 var_pattern;
u32 init_val;
u32 cur_val;
@@ -106,7 +106,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
{
struct ath5k_hw *ah;
struct pci_dev *pdev = sc->pdev;
- u8 mac[ETH_ALEN] = {};
int ret;
u32 srev;
@@ -169,7 +168,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
ah->ah_single_chip = false;
ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
CHANNEL_2GHZ);
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
break;
case AR5K_SREV_RAD_5112:
case AR5K_SREV_RAD_2112:
@@ -177,38 +175,31 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
ah->ah_single_chip = false;
ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
CHANNEL_2GHZ);
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
break;
case AR5K_SREV_RAD_2413:
ah->ah_radio = AR5K_RF2413;
ah->ah_single_chip = true;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
break;
case AR5K_SREV_RAD_5413:
ah->ah_radio = AR5K_RF5413;
ah->ah_single_chip = true;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
break;
case AR5K_SREV_RAD_2316:
ah->ah_radio = AR5K_RF2316;
ah->ah_single_chip = true;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316;
break;
case AR5K_SREV_RAD_2317:
ah->ah_radio = AR5K_RF2317;
ah->ah_single_chip = true;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2317;
break;
case AR5K_SREV_RAD_5424:
if (ah->ah_mac_version == AR5K_SREV_AR2425 ||
ah->ah_mac_version == AR5K_SREV_AR2417){
ah->ah_radio = AR5K_RF2425;
ah->ah_single_chip = true;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
} else {
ah->ah_radio = AR5K_RF5413;
ah->ah_single_chip = true;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
}
break;
default:
@@ -227,29 +218,25 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
ah->ah_radio = AR5K_RF2425;
ah->ah_single_chip = true;
ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
} else if (srev == AR5K_SREV_AR5213A &&
- ah->ah_phy_revision == AR5K_SREV_PHY_2112B) {
+ ah->ah_phy_revision == AR5K_SREV_PHY_5212B) {
ah->ah_radio = AR5K_RF5112;
ah->ah_single_chip = false;
- ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2112B;
+ ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
} else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) {
ah->ah_radio = AR5K_RF2316;
ah->ah_single_chip = true;
ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316;
} else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) ||
ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
ah->ah_radio = AR5K_RF5413;
ah->ah_single_chip = true;
ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
} else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) ||
ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
ah->ah_radio = AR5K_RF2413;
ah->ah_single_chip = true;
ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
- ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
} else {
ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
ret = -ENODEV;
@@ -324,14 +311,14 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
}
/* MAC address is cleared until add_interface */
- ath5k_hw_set_lladdr(ah, mac);
+ ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){});
/* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
memset(ah->ah_bssid, 0xff, ETH_ALEN);
ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
ath5k_hw_set_opmode(ah);
- ath5k_hw_set_rfgain_opt(ah);
+ ath5k_hw_rfgain_opt_init(ah);
return ah;
err_free:
@@ -354,6 +341,8 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
if (ah->ah_rf_banks != NULL)
kfree(ah->ah_rf_banks);
+ ath5k_eeprom_detach(ah);
+
/* assume interrupts are down */
kfree(ah);
}
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 1d77ee9d6e99..5d57d774e466 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -79,7 +79,7 @@ MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
/* Known PCI ids */
-static struct pci_device_id ath5k_pci_id_table[] __devinitdata = {
+static const struct pci_device_id ath5k_pci_id_table[] = {
{ PCI_VDEVICE(ATHEROS, 0x0207), .driver_data = AR5K_AR5210 }, /* 5210 early */
{ PCI_VDEVICE(ATHEROS, 0x0007), .driver_data = AR5K_AR5210 }, /* 5210 */
{ PCI_VDEVICE(ATHEROS, 0x0011), .driver_data = AR5K_AR5211 }, /* 5311 - this is on AHB bus !*/
@@ -103,7 +103,7 @@ static struct pci_device_id ath5k_pci_id_table[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
/* Known SREVs */
-static struct ath5k_srev_name srev_names[] = {
+static const struct ath5k_srev_name srev_names[] = {
{ "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 },
{ "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 },
{ "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A },
@@ -142,7 +142,7 @@ static struct ath5k_srev_name srev_names[] = {
{ "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN },
};
-static struct ieee80211_rate ath5k_rates[] = {
+static const struct ieee80211_rate ath5k_rates[] = {
{ .bitrate = 10,
.hw_value = ATH5K_RATE_CODE_1M, },
{ .bitrate = 20,
@@ -232,13 +232,14 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
int mc_count, struct dev_mc_list *mclist);
static int ath5k_set_key(struct ieee80211_hw *hw,
enum set_key_cmd cmd,
- const u8 *local_addr, const u8 *addr,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key);
static int ath5k_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats);
static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
struct ieee80211_tx_queue_stats *stats);
static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
+static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
static void ath5k_reset_tsf(struct ieee80211_hw *hw);
static int ath5k_beacon_update(struct ath5k_softc *sc,
struct sk_buff *skb);
@@ -247,7 +248,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf,
u32 changes);
-static struct ieee80211_ops ath5k_hw_ops = {
+static const struct ieee80211_ops ath5k_hw_ops = {
.tx = ath5k_tx,
.start = ath5k_start,
.stop = ath5k_stop,
@@ -261,6 +262,7 @@ static struct ieee80211_ops ath5k_hw_ops = {
.conf_tx = NULL,
.get_tx_stats = ath5k_get_tx_stats,
.get_tsf = ath5k_get_tsf,
+ .set_tsf = ath5k_set_tsf,
.reset_tsf = ath5k_reset_tsf,
.bss_info_changed = ath5k_bss_info_changed,
};
@@ -308,6 +310,19 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
bf->skb = NULL;
}
+static inline void ath5k_rxbuf_free(struct ath5k_softc *sc,
+ struct ath5k_buf *bf)
+{
+ BUG_ON(!bf);
+ if (!bf->skb)
+ return;
+ pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
+ PCI_DMA_FROMDEVICE);
+ dev_kfree_skb_any(bf->skb);
+ bf->skb = NULL;
+}
+
+
/* Queues setup */
static struct ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc,
int qtype, int subtype);
@@ -335,6 +350,7 @@ static int ath5k_beacon_setup(struct ath5k_softc *sc,
static void ath5k_beacon_send(struct ath5k_softc *sc);
static void ath5k_beacon_config(struct ath5k_softc *sc);
static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
+static void ath5k_tasklet_beacon(unsigned long data);
static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
{
@@ -347,18 +363,13 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
}
/* Interrupt handling */
-static int ath5k_init(struct ath5k_softc *sc, bool is_resume);
+static int ath5k_init(struct ath5k_softc *sc);
static int ath5k_stop_locked(struct ath5k_softc *sc);
-static int ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend);
+static int ath5k_stop_hw(struct ath5k_softc *sc);
static irqreturn_t ath5k_intr(int irq, void *dev_id);
static void ath5k_tasklet_reset(unsigned long data);
static void ath5k_calibrate(unsigned long data);
-/* LED functions */
-static int ath5k_init_leds(struct ath5k_softc *sc);
-static void ath5k_led_enable(struct ath5k_softc *sc);
-static void ath5k_led_off(struct ath5k_softc *sc);
-static void ath5k_unregister_leds(struct ath5k_softc *sc);
/*
* Module init/exit functions
@@ -653,8 +664,6 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
ath5k_led_off(sc);
- ath5k_stop_hw(sc, true);
-
free_irq(pdev->irq, sc);
pci_save_state(pdev);
pci_disable_device(pdev);
@@ -676,27 +685,15 @@ ath5k_pci_resume(struct pci_dev *pdev)
if (err)
return err;
- /*
- * Suspend/Resume resets the PCI configuration space, so we have to
- * re-disable the RETRY_TIMEOUT register (0x41) to keep
- * PCI Tx retries from interfering with C3 CPU state
- */
- pci_write_config_byte(pdev, 0x41, 0);
-
err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
if (err) {
ATH5K_ERR(sc, "request_irq failed\n");
goto err_no_irq;
}
- err = ath5k_init(sc, true);
- if (err)
- goto err_irq;
ath5k_led_enable(sc);
-
return 0;
-err_irq:
- free_irq(pdev->irq, sc);
+
err_no_irq:
pci_disable_device(pdev);
return err;
@@ -781,6 +778,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
+ tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
ret = ath5k_eeprom_read_mac(ah, mac);
@@ -1090,8 +1088,18 @@ ath5k_mode_setup(struct ath5k_softc *sc)
static inline int
ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
{
- WARN_ON(hw_rix < 0 || hw_rix > AR5K_MAX_RATES);
- return sc->rate_idx[sc->curband->band][hw_rix];
+ int rix;
+
+ /* return base rate on errors */
+ if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES,
+ "hw_rix out of bounds: %x\n", hw_rix))
+ return 0;
+
+ rix = sc->rate_idx[sc->curband->band][hw_rix];
+ if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix))
+ rix = 0;
+
+ return rix;
}
/***************\
@@ -1188,6 +1196,10 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
struct ieee80211_rate *rate;
unsigned int mrr_rate[3], mrr_tries[3];
int i, ret;
+ u16 hw_rate;
+ u16 cts_rate = 0;
+ u16 duration = 0;
+ u8 rc_flags;
flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
@@ -1195,20 +1207,42 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
PCI_DMA_TODEVICE);
+ rate = ieee80211_get_tx_rate(sc->hw, info);
+
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
flags |= AR5K_TXDESC_NOACK;
+ rc_flags = info->control.rates[0].flags;
+ hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
+ rate->hw_value_short : rate->hw_value;
+
pktlen = skb->len;
+ /* FIXME: If we are in g mode and rate is a CCK rate
+ * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
+ * from tx power (value is in dB units already) */
if (info->control.hw_key) {
keyidx = info->control.hw_key->hw_key_idx;
pktlen += info->control.hw_key->icv_len;
}
+ if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+ flags |= AR5K_TXDESC_RTSENA;
+ cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
+ duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
+ sc->vif, pktlen, info));
+ }
+ if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+ flags |= AR5K_TXDESC_CTSENA;
+ cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
+ duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
+ sc->vif, pktlen, info));
+ }
ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
(sc->power_level * 2),
- ieee80211_get_tx_rate(sc->hw, info)->hw_value,
- info->control.rates[0].count, keyidx, 0, flags, 0, 0);
+ hw_rate,
+ info->control.rates[0].count, keyidx, 0, flags,
+ cts_rate, duration);
if (ret)
goto err_unmap;
@@ -1324,7 +1358,7 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
list_for_each_entry(bf, &sc->txbuf, list)
ath5k_txbuf_free(sc, bf);
list_for_each_entry(bf, &sc->rxbuf, list)
- ath5k_txbuf_free(sc, bf);
+ ath5k_rxbuf_free(sc, bf);
/* Free memory associated with all descriptors */
pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
@@ -1668,6 +1702,34 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
}
}
+static void ath5k_tasklet_beacon(unsigned long data)
+{
+ struct ath5k_softc *sc = (struct ath5k_softc *) data;
+
+ /*
+ * Software beacon alert--time to send a beacon.
+ *
+ * In IBSS mode we use this interrupt just to
+ * keep track of the next TBTT (target beacon
+ * transmission time) in order to detect wether
+ * automatic TSF updates happened.
+ */
+ if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+ /* XXX: only if VEOL suppported */
+ u64 tsf = ath5k_hw_get_tsf64(sc->ah);
+ sc->nexttbtt += sc->bintval;
+ ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+ "SWBA nexttbtt: %x hw_tu: %x "
+ "TSF: %llx\n",
+ sc->nexttbtt,
+ TSF_TO_TU(tsf),
+ (unsigned long long) tsf);
+ } else {
+ spin_lock(&sc->block);
+ ath5k_beacon_send(sc);
+ spin_unlock(&sc->block);
+ }
+}
static void
ath5k_tasklet_rx(unsigned long data)
@@ -1987,6 +2049,9 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
antenna = sc->bsent & 4 ? 2 : 1;
}
+ /* FIXME: If we are in g mode and rate is a CCK rate
+ * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
+ * from tx power (value is in dB units already) */
ds->ds_data = bf->skbaddr;
ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
ieee80211_get_hdrlen_from_skb(skb),
@@ -2008,9 +2073,8 @@ err_unmap:
* frame contents are done as needed and the slot time is
* also adjusted based on current state.
*
- * this is usually called from interrupt context (ath5k_intr())
- * but also from ath5k_beacon_config() in IBSS mode which in turn
- * can be called from a tasklet and user context
+ * This is called from software irq context (beacontq or restq
+ * tasklets) or user context from ath5k_beacon_config.
*/
static void
ath5k_beacon_send(struct ath5k_softc *sc)
@@ -2177,10 +2241,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
*
* @sc: struct ath5k_softc pointer we are operating on
*
- * When operating in station mode we want to receive a BMISS interrupt when we
- * stop seeing beacons from the AP we've associated with so we can look for
- * another AP to associate with.
- *
* In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
* interrupts to detect TSF updates only.
*/
@@ -2188,14 +2248,13 @@ static void
ath5k_beacon_config(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
+ unsigned long flags;
ath5k_hw_set_imr(ah, 0);
sc->bmisscount = 0;
sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
- if (sc->opmode == NL80211_IFTYPE_STATION) {
- sc->imask |= AR5K_INT_BMISS;
- } else if (sc->opmode == NL80211_IFTYPE_ADHOC ||
+ if (sc->opmode == NL80211_IFTYPE_ADHOC ||
sc->opmode == NL80211_IFTYPE_MESH_POINT ||
sc->opmode == NL80211_IFTYPE_AP) {
/*
@@ -2211,9 +2270,9 @@ ath5k_beacon_config(struct ath5k_softc *sc)
if (sc->opmode == NL80211_IFTYPE_ADHOC) {
if (ath5k_hw_hasveol(ah)) {
- spin_lock(&sc->block);
+ spin_lock_irqsave(&sc->block, flags);
ath5k_beacon_send(sc);
- spin_unlock(&sc->block);
+ spin_unlock_irqrestore(&sc->block, flags);
}
} else
ath5k_beacon_update_timers(sc, -1);
@@ -2228,18 +2287,13 @@ ath5k_beacon_config(struct ath5k_softc *sc)
\********************/
static int
-ath5k_init(struct ath5k_softc *sc, bool is_resume)
+ath5k_init(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
int ret, i;
mutex_lock(&sc->lock);
- if (is_resume && !test_bit(ATH_STAT_STARTED, sc->status))
- goto out_ok;
-
- __clear_bit(ATH_STAT_STARTED, sc->status);
-
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
/*
@@ -2259,7 +2313,7 @@ ath5k_init(struct ath5k_softc *sc, bool is_resume)
sc->curband = &sc->sbands[sc->curchan->band];
sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
- AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
+ AR5K_INT_FATAL | AR5K_INT_GLOBAL;
ret = ath5k_reset(sc, false, false);
if (ret)
goto done;
@@ -2271,15 +2325,12 @@ ath5k_init(struct ath5k_softc *sc, bool is_resume)
for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
ath5k_hw_reset_key(ah, i);
- __set_bit(ATH_STAT_STARTED, sc->status);
-
/* Set ack to be sent at low bit-rates */
ath5k_hw_set_ack_bitrate_high(ah, false);
mod_timer(&sc->calib_tim, round_jiffies(jiffies +
msecs_to_jiffies(ath5k_calinterval * 1000)));
-out_ok:
ret = 0;
done:
mmiowb();
@@ -2334,7 +2385,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
* stop is preempted).
*/
static int
-ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
+ath5k_stop_hw(struct ath5k_softc *sc)
{
int ret;
@@ -2365,8 +2416,6 @@ ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
}
}
ath5k_txbuf_free(sc, sc->bbuf);
- if (!is_suspend)
- __clear_bit(ATH_STAT_STARTED, sc->status);
mmiowb();
mutex_unlock(&sc->lock);
@@ -2375,6 +2424,7 @@ ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
tasklet_kill(&sc->rxtq);
tasklet_kill(&sc->txtq);
tasklet_kill(&sc->restq);
+ tasklet_kill(&sc->beacontq);
return ret;
}
@@ -2392,16 +2442,9 @@ ath5k_intr(int irq, void *dev_id)
return IRQ_NONE;
do {
- /*
- * Figure out the reason(s) for the interrupt. Note
- * that get_isr returns a pseudo-ISR that may include
- * bits we haven't explicitly enabled so we mask the
- * value to insure we only process bits we requested.
- */
ath5k_hw_get_isr(ah, &status); /* NB: clears IRQ too */
ATH5K_DBG(sc, ATH5K_DEBUG_INTR, "status 0x%x/0x%x\n",
status, sc->imask);
- status &= sc->imask; /* discard unasked for bits */
if (unlikely(status & AR5K_INT_FATAL)) {
/*
* Fatal errors are unrecoverable.
@@ -2412,32 +2455,7 @@ ath5k_intr(int irq, void *dev_id)
tasklet_schedule(&sc->restq);
} else {
if (status & AR5K_INT_SWBA) {
- /*
- * Software beacon alert--time to send a beacon.
- * Handle beacon transmission directly; deferring
- * this is too slow to meet timing constraints
- * under load.
- *
- * In IBSS mode we use this interrupt just to
- * keep track of the next TBTT (target beacon
- * transmission time) in order to detect wether
- * automatic TSF updates happened.
- */
- if (sc->opmode == NL80211_IFTYPE_ADHOC) {
- /* XXX: only if VEOL suppported */
- u64 tsf = ath5k_hw_get_tsf64(ah);
- sc->nexttbtt += sc->bintval;
- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
- "SWBA nexttbtt: %x hw_tu: %x "
- "TSF: %llx\n",
- sc->nexttbtt,
- TSF_TO_TU(tsf),
- (unsigned long long) tsf);
- } else {
- spin_lock(&sc->block);
- ath5k_beacon_send(sc);
- spin_unlock(&sc->block);
- }
+ tasklet_schedule(&sc->beacontq);
}
if (status & AR5K_INT_RXEOL) {
/*
@@ -2457,6 +2475,7 @@ ath5k_intr(int irq, void *dev_id)
| AR5K_INT_TXERR | AR5K_INT_TXEOL))
tasklet_schedule(&sc->txtq);
if (status & AR5K_INT_BMISS) {
+ /* TODO */
}
if (status & AR5K_INT_MIB) {
/*
@@ -2496,7 +2515,7 @@ ath5k_calibrate(unsigned long data)
ieee80211_frequency_to_channel(sc->curchan->center_freq),
sc->curchan->hw_value);
- if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) {
+ if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
/*
* Rfgain is out of bounds, reset the chip
* to load new gain values.
@@ -2514,130 +2533,6 @@ ath5k_calibrate(unsigned long data)
}
-
-/***************\
-* LED functions *
-\***************/
-
-static void
-ath5k_led_enable(struct ath5k_softc *sc)
-{
- if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
- ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
- ath5k_led_off(sc);
- }
-}
-
-static void
-ath5k_led_on(struct ath5k_softc *sc)
-{
- if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
- return;
- ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
-}
-
-static void
-ath5k_led_off(struct ath5k_softc *sc)
-{
- if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
- return;
- ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
-}
-
-static void
-ath5k_led_brightness_set(struct led_classdev *led_dev,
- enum led_brightness brightness)
-{
- struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
- led_dev);
-
- if (brightness == LED_OFF)
- ath5k_led_off(led->sc);
- else
- ath5k_led_on(led->sc);
-}
-
-static int
-ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
- const char *name, char *trigger)
-{
- int err;
-
- led->sc = sc;
- strncpy(led->name, name, sizeof(led->name));
- led->led_dev.name = led->name;
- led->led_dev.default_trigger = trigger;
- led->led_dev.brightness_set = ath5k_led_brightness_set;
-
- err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
- if (err) {
- ATH5K_WARN(sc, "could not register LED %s\n", name);
- led->sc = NULL;
- }
- return err;
-}
-
-static void
-ath5k_unregister_led(struct ath5k_led *led)
-{
- if (!led->sc)
- return;
- led_classdev_unregister(&led->led_dev);
- ath5k_led_off(led->sc);
- led->sc = NULL;
-}
-
-static void
-ath5k_unregister_leds(struct ath5k_softc *sc)
-{
- ath5k_unregister_led(&sc->rx_led);
- ath5k_unregister_led(&sc->tx_led);
-}
-
-
-static int
-ath5k_init_leds(struct ath5k_softc *sc)
-{
- int ret = 0;
- struct ieee80211_hw *hw = sc->hw;
- struct pci_dev *pdev = sc->pdev;
- char name[ATH5K_LED_MAX_NAME_LEN + 1];
-
- /*
- * Auto-enable soft led processing for IBM cards and for
- * 5211 minipci cards.
- */
- if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
- pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) {
- __set_bit(ATH_STAT_LEDSOFT, sc->status);
- sc->led_pin = 0;
- sc->led_on = 0; /* active low */
- }
- /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
- if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {
- __set_bit(ATH_STAT_LEDSOFT, sc->status);
- sc->led_pin = 1;
- sc->led_on = 1; /* active high */
- }
- if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
- goto out;
-
- ath5k_led_enable(sc);
-
- snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
- ret = ath5k_register_led(sc, &sc->rx_led, name,
- ieee80211_get_rx_led_name(hw));
- if (ret)
- goto out;
-
- snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
- ret = ath5k_register_led(sc, &sc->tx_led, name,
- ieee80211_get_tx_led_name(hw));
-out:
- return ret;
-}
-
-
/********************\
* Mac80211 functions *
\********************/
@@ -2667,7 +2562,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
if (skb_headroom(skb) < padsize) {
ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
" headroom to pad %d\n", hdrlen, padsize);
- return NETDEV_TX_BUSY;
+ goto drop_packet;
}
skb_push(skb, padsize);
memmove(skb->data, skb->data+padsize, hdrlen);
@@ -2678,7 +2573,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
spin_unlock_irqrestore(&sc->txbuflock, flags);
ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
- return NETDEV_TX_BUSY;
+ goto drop_packet;
}
bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
list_del(&bf->list);
@@ -2695,10 +2590,12 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
list_add_tail(&bf->list, &sc->txbuf);
sc->txbuf_len++;
spin_unlock_irqrestore(&sc->txbuflock, flags);
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
+ goto drop_packet;
}
+ return NETDEV_TX_OK;
+drop_packet:
+ dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
@@ -2721,12 +2618,6 @@ ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel)
goto err;
}
- /*
- * This is needed only to setup initial state
- * but it's best done after a reset.
- */
- ath5k_hw_set_txpower_limit(sc->ah, 0);
-
ret = ath5k_rx_start(sc);
if (ret) {
ATH5K_ERR(sc, "can't start recv logic\n");
@@ -2766,12 +2657,12 @@ ath5k_reset_wake(struct ath5k_softc *sc)
static int ath5k_start(struct ieee80211_hw *hw)
{
- return ath5k_init(hw->priv, false);
+ return ath5k_init(hw->priv);
}
static void ath5k_stop(struct ieee80211_hw *hw)
{
- ath5k_stop_hw(hw->priv, false);
+ ath5k_stop_hw(hw->priv);
}
static int ath5k_add_interface(struct ieee80211_hw *hw,
@@ -2856,7 +2747,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
{
struct ath5k_softc *sc = hw->priv;
struct ath5k_hw *ah = sc->ah;
- int ret;
+ int ret = 0;
mutex_lock(&sc->lock);
if (sc->vif != vif) {
@@ -2882,9 +2773,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
ath5k_beacon_update(sc, beacon);
}
- mutex_unlock(&sc->lock);
- return ath5k_reset_wake(sc);
unlock:
mutex_unlock(&sc->lock);
return ret;
@@ -3020,8 +2909,8 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
static int
ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_addr, const u8 *addr,
- struct ieee80211_key_conf *key)
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
struct ath5k_softc *sc = hw->priv;
int ret = 0;
@@ -3044,7 +2933,8 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
switch (cmd) {
case SET_KEY:
- ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, addr);
+ ret = ath5k_hw_set_key(sc->ah, key->keyidx, key,
+ sta ? sta->addr : NULL);
if (ret) {
ATH5K_ERR(sc, "can't set the key\n");
goto unlock;
@@ -3104,6 +2994,14 @@ ath5k_get_tsf(struct ieee80211_hw *hw)
}
static void
+ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+ struct ath5k_softc *sc = hw->priv;
+
+ ath5k_hw_set_tsf64(sc->ah, tsf);
+}
+
+static void
ath5k_reset_tsf(struct ieee80211_hw *hw)
{
struct ath5k_softc *sc = hw->priv;
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
index facc60ddada2..822956114cd7 100644
--- a/drivers/net/wireless/ath5k/base.h
+++ b/drivers/net/wireless/ath5k/base.h
@@ -112,7 +112,7 @@ struct ath5k_softc {
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
struct ieee80211_channel channels[ATH_CHAN_MAX];
struct ieee80211_rate rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
- u8 rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
+ s8 rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
enum nl80211_iftype opmode;
struct ath5k_hw *ah; /* Atheros HW */
@@ -148,8 +148,7 @@ struct ath5k_softc {
u8 bssidmask[ETH_ALEN];
unsigned int led_pin, /* GPIO pin for driving LED */
- led_on, /* pin setting for LED on */
- led_off; /* off time for current blink */
+ led_on; /* pin setting for LED on */
struct tasklet_struct restq; /* reset tasklet */
@@ -170,6 +169,7 @@ struct ath5k_softc {
struct ath5k_led tx_led; /* tx led */
spinlock_t block; /* protects beacon */
+ struct tasklet_struct beacontq; /* beacon intr tasklet */
struct ath5k_buf *bbuf; /* beacon buffer */
unsigned int bhalq, /* SW q for outgoing beacons */
bmisscount, /* missed beacon transmits */
diff --git a/drivers/net/wireless/ath5k/caps.c b/drivers/net/wireless/ath5k/caps.c
index 150f5ed204a0..367a6c7d3cc7 100644
--- a/drivers/net/wireless/ath5k/caps.c
+++ b/drivers/net/wireless/ath5k/caps.c
@@ -85,7 +85,8 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
/* Enable 802.11b if a 2GHz capable radio (2111/5112) is
* connected */
if (AR5K_EEPROM_HDR_11B(ee_header) ||
- AR5K_EEPROM_HDR_11G(ee_header)) {
+ (AR5K_EEPROM_HDR_11G(ee_header) &&
+ ah->ah_version != AR5K_AR5211)) {
/* 2312 */
ah->ah_capabilities.cap_range.range_2ghz_min = 2412;
ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
@@ -94,7 +95,8 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
__set_bit(AR5K_MODE_11B,
ah->ah_capabilities.cap_mode);
- if (AR5K_EEPROM_HDR_11G(ee_header))
+ if (AR5K_EEPROM_HDR_11G(ee_header) &&
+ ah->ah_version != AR5K_AR5211)
__set_bit(AR5K_MODE_11G,
ah->ah_capabilities.cap_mode);
}
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c
index ccaeb5c219d2..9770bb3d40f9 100644
--- a/drivers/net/wireless/ath5k/debug.c
+++ b/drivers/net/wireless/ath5k/debug.c
@@ -82,14 +82,14 @@ static int ath5k_debugfs_open(struct inode *inode, struct file *file)
/* debugfs: registers */
struct reg {
- char *name;
+ const char *name;
int addr;
};
#define REG_STRUCT_INIT(r) { #r, r }
/* just a few random registers, might want to add more */
-static struct reg regs[] = {
+static const struct reg regs[] = {
REG_STRUCT_INIT(AR5K_CR),
REG_STRUCT_INIT(AR5K_RXDP),
REG_STRUCT_INIT(AR5K_CFG),
@@ -142,7 +142,7 @@ static struct reg regs[] = {
static void *reg_start(struct seq_file *seq, loff_t *pos)
{
- return *pos < ARRAY_SIZE(regs) ? &regs[*pos] : NULL;
+ return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
}
static void reg_stop(struct seq_file *seq, void *p)
@@ -153,7 +153,7 @@ static void reg_stop(struct seq_file *seq, void *p)
static void *reg_next(struct seq_file *seq, void *p, loff_t *pos)
{
++*pos;
- return *pos < ARRAY_SIZE(regs) ? &regs[*pos] : NULL;
+ return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
}
static int reg_show(struct seq_file *seq, void *p)
@@ -165,7 +165,7 @@ static int reg_show(struct seq_file *seq, void *p)
return 0;
}
-static struct seq_operations register_seq_ops = {
+static const struct seq_operations register_seq_ops = {
.start = reg_start,
.next = reg_next,
.stop = reg_stop,
@@ -193,43 +193,6 @@ static const struct file_operations fops_registers = {
};
-/* debugfs: TSF */
-
-static ssize_t read_file_tsf(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath5k_softc *sc = file->private_data;
- char buf[100];
- snprintf(buf, sizeof(buf), "0x%016llx\n",
- (unsigned long long)ath5k_hw_get_tsf64(sc->ah));
- return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
-}
-
-static ssize_t write_file_tsf(struct file *file,
- const char __user *userbuf,
- size_t count, loff_t *ppos)
-{
- struct ath5k_softc *sc = file->private_data;
- char buf[20];
-
- if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
- return -EFAULT;
-
- if (strncmp(buf, "reset", 5) == 0) {
- ath5k_hw_reset_tsf(sc->ah);
- printk(KERN_INFO "debugfs reset TSF\n");
- }
- return count;
-}
-
-static const struct file_operations fops_tsf = {
- .read = read_file_tsf,
- .write = write_file_tsf,
- .open = ath5k_debugfs_open,
- .owner = THIS_MODULE,
-};
-
-
/* debugfs: beacons */
static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
@@ -327,7 +290,7 @@ static const struct file_operations fops_reset = {
/* debugfs: debug level */
-static struct {
+static const struct {
enum ath5k_debug_level level;
const char *name;
const char *desc;
@@ -423,9 +386,6 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUGO,
sc->debug.debugfs_phydir, sc, &fops_registers);
- sc->debug.debugfs_tsf = debugfs_create_file("tsf", S_IWUSR | S_IRUGO,
- sc->debug.debugfs_phydir, sc, &fops_tsf);
-
sc->debug.debugfs_beacon = debugfs_create_file("beacon", S_IWUSR | S_IRUGO,
sc->debug.debugfs_phydir, sc, &fops_beacon);
@@ -444,7 +404,6 @@ ath5k_debug_finish_device(struct ath5k_softc *sc)
{
debugfs_remove(sc->debug.debugfs_debug);
debugfs_remove(sc->debug.debugfs_registers);
- debugfs_remove(sc->debug.debugfs_tsf);
debugfs_remove(sc->debug.debugfs_beacon);
debugfs_remove(sc->debug.debugfs_reset);
debugfs_remove(sc->debug.debugfs_phydir);
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h
index ffc529393306..66f69f04e55e 100644
--- a/drivers/net/wireless/ath5k/debug.h
+++ b/drivers/net/wireless/ath5k/debug.h
@@ -72,7 +72,6 @@ struct ath5k_dbg_info {
struct dentry *debugfs_phydir;
struct dentry *debugfs_debug;
struct dentry *debugfs_registers;
- struct dentry *debugfs_tsf;
struct dentry *debugfs_beacon;
struct dentry *debugfs_reset;
};
diff --git a/drivers/net/wireless/ath5k/desc.c b/drivers/net/wireless/ath5k/desc.c
index b40a9287a39a..dc30a2b70a6b 100644
--- a/drivers/net/wireless/ath5k/desc.c
+++ b/drivers/net/wireless/ath5k/desc.c
@@ -194,6 +194,10 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
return -EINVAL;
}
+ tx_power += ah->ah_txpower.txp_offset;
+ if (tx_power > AR5K_TUNE_MAX_TXPOWER)
+ tx_power = AR5K_TUNE_MAX_TXPOWER;
+
/* Clear descriptor */
memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath5k/eeprom.c
index 1cb7edfae625..c0fb3b09ba45 100644
--- a/drivers/net/wireless/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath5k/eeprom.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2008 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -98,11 +98,6 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
int ret;
u16 val;
- /* Initial TX thermal adjustment values */
- ee->ee_tx_clip = 4;
- ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
- ee->ee_gain_select = 1;
-
/*
* Read values from EEPROM and store them in the capability structure
*/
@@ -137,6 +132,18 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
+
+ /* XXX: Don't know which versions include these two */
+ AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2);
+
+ if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3)
+ AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3);
+
+ if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) {
+ AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4);
+ AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5);
+ AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6);
+ }
}
if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
@@ -192,7 +199,7 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
/* Get antenna modes */
ah->ah_antenna[mode][0] =
- (ee->ee_ant_control[mode][0] << 4) | 0x1;
+ (ee->ee_ant_control[mode][0] << 4);
ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
ee->ee_ant_control[mode][1] |
(ee->ee_ant_control[mode][2] << 6) |
@@ -213,7 +220,8 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
}
/*
- * Read supported modes from eeprom
+ * Read supported modes and some mode-specific calibration data
+ * from eeprom
*/
static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
unsigned int mode)
@@ -228,22 +236,22 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
switch(mode) {
case AR5K_EEPROM_MODE_11A:
- ee->ee_ob[mode][3] = (val >> 5) & 0x7;
- ee->ee_db[mode][3] = (val >> 2) & 0x7;
- ee->ee_ob[mode][2] = (val << 1) & 0x7;
+ ee->ee_ob[mode][3] = (val >> 5) & 0x7;
+ ee->ee_db[mode][3] = (val >> 2) & 0x7;
+ ee->ee_ob[mode][2] = (val << 1) & 0x7;
AR5K_EEPROM_READ(o++, val);
- ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
- ee->ee_db[mode][2] = (val >> 12) & 0x7;
- ee->ee_ob[mode][1] = (val >> 9) & 0x7;
- ee->ee_db[mode][1] = (val >> 6) & 0x7;
- ee->ee_ob[mode][0] = (val >> 3) & 0x7;
- ee->ee_db[mode][0] = val & 0x7;
+ ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
+ ee->ee_db[mode][2] = (val >> 12) & 0x7;
+ ee->ee_ob[mode][1] = (val >> 9) & 0x7;
+ ee->ee_db[mode][1] = (val >> 6) & 0x7;
+ ee->ee_ob[mode][0] = (val >> 3) & 0x7;
+ ee->ee_db[mode][0] = val & 0x7;
break;
case AR5K_EEPROM_MODE_11G:
case AR5K_EEPROM_MODE_11B:
- ee->ee_ob[mode][1] = (val >> 4) & 0x7;
- ee->ee_db[mode][1] = val & 0x7;
+ ee->ee_ob[mode][1] = (val >> 4) & 0x7;
+ ee->ee_db[mode][1] = val & 0x7;
break;
}
@@ -315,6 +323,9 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0)
goto done;
+ /* Note: >= v5 have bg freq piers on another location
+ * so these freq piers are ignored for >= v5 (should be 0xff
+ * anyway) */
switch(mode) {
case AR5K_EEPROM_MODE_11A:
if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
@@ -442,7 +453,7 @@ ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah,
return 0;
}
-
+/* Read mode-specific data (except power calibration data) */
static int
ath5k_eeprom_init_modes(struct ath5k_hw *ah)
{
@@ -488,56 +499,47 @@ ath5k_eeprom_init_modes(struct ath5k_hw *ah)
return 0;
}
-static inline void
-ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
-{
- const static u16 intercepts3[] =
- { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
- const static u16 intercepts3_2[] =
- { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
- const u16 *ip;
- int i;
-
- if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
- ip = intercepts3_2;
- else
- ip = intercepts3;
-
- for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
- *vp++ = (ip[i] * max + (100 - ip[i]) * min) / 100;
-}
-
+/* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff
+ * frequency mask) */
static inline int
ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
- struct ath5k_chan_pcal_info *pc, u8 *count)
+ struct ath5k_chan_pcal_info *pc, unsigned int mode)
{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
int o = *offset;
int i = 0;
- u8 f1, f2;
+ u8 freq1, freq2;
int ret;
u16 val;
+ ee->ee_n_piers[mode] = 0;
while(i < max) {
AR5K_EEPROM_READ(o++, val);
- f1 = (val >> 8) & 0xff;
- f2 = val & 0xff;
-
- if (f1)
- pc[i++].freq = f1;
+ freq1 = val & 0xff;
+ if (!freq1)
+ break;
- if (f2)
- pc[i++].freq = f2;
+ pc[i++].freq = ath5k_eeprom_bin2freq(ee,
+ freq1, mode);
+ ee->ee_n_piers[mode]++;
- if (!f1 || !f2)
+ freq2 = (val >> 8) & 0xff;
+ if (!freq2)
break;
+
+ pc[i++].freq = ath5k_eeprom_bin2freq(ee,
+ freq2, mode);
+ ee->ee_n_piers[mode]++;
}
+
+ /* return new offset */
*offset = o;
- *count = i;
return 0;
}
+/* Read frequency piers for 802.11a */
static int
ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
{
@@ -550,7 +552,7 @@ ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
ath5k_eeprom_read_freq_list(ah, &offset,
AR5K_EEPROM_N_5GHZ_CHAN, pcal,
- &ee->ee_n_piers[AR5K_EEPROM_MODE_11A]);
+ AR5K_EEPROM_MODE_11A);
} else {
mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version);
@@ -577,23 +579,25 @@ ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
AR5K_EEPROM_READ(offset++, val);
pcal[9].freq |= (val >> 10) & 0x3f;
+
+ /* Fixed number of piers */
ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10;
- }
- for(i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i += 1) {
- pcal[i].freq = ath5k_eeprom_bin2freq(ee,
+ for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
+ pcal[i].freq = ath5k_eeprom_bin2freq(ee,
pcal[i].freq, AR5K_EEPROM_MODE_11A);
+ }
}
return 0;
}
+/* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */
static inline int
ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
struct ath5k_chan_pcal_info *pcal;
- int i;
switch(mode) {
case AR5K_EEPROM_MODE_11B:
@@ -608,23 +612,134 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
ath5k_eeprom_read_freq_list(ah, &offset,
AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal,
- &ee->ee_n_piers[mode]);
- for(i = 0; i < AR5K_EEPROM_N_2GHZ_CHAN_2413; i += 1) {
- pcal[i].freq = ath5k_eeprom_bin2freq(ee,
- pcal[i].freq, mode);
- }
+ mode);
return 0;
}
+/*
+ * Read power calibration for RF5111 chips
+ *
+ * For RF5111 we have an XPD -eXternal Power Detector- curve
+ * for each calibrated channel. Each curve has 0,5dB Power steps
+ * on x axis and PCDAC steps (offsets) on y axis and looks like an
+ * exponential function. To recreate the curve we read 11 points
+ * here and interpolate later.
+ */
+
+/* Used to match PCDAC steps with power values on RF5111 chips
+ * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC
+ * steps that match with the power values we read from eeprom. On
+ * older eeprom versions (< 3.2) these steps are equaly spaced at
+ * 10% of the pcdac curve -until the curve reaches it's maximum-
+ * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
+ * these 11 steps are spaced in a different way. This function returns
+ * the pcdac steps based on eeprom version and curve min/max so that we
+ * can have pcdac/pwr points.
+ */
+static inline void
+ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
+{
+ const static u16 intercepts3[] =
+ { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
+ const static u16 intercepts3_2[] =
+ { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
+ const u16 *ip;
+ int i;
+
+ if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
+ ip = intercepts3_2;
+ else
+ ip = intercepts3;
+
+ for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
+ vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
+}
+
+/* Convert RF5111 specific data to generic raw data
+ * used by interpolation code */
+static int
+ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
+ struct ath5k_chan_pcal_info *chinfo)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ struct ath5k_chan_pcal_info_rf5111 *pcinfo;
+ struct ath5k_pdgain_info *pd;
+ u8 pier, point, idx;
+ u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+
+ /* Fill raw data for each calibration pier */
+ for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+
+ pcinfo = &chinfo[pier].rf5111_info;
+
+ /* Allocate pd_curves for this cal pier */
+ chinfo[pier].pd_curves =
+ kcalloc(AR5K_EEPROM_N_PD_CURVES,
+ sizeof(struct ath5k_pdgain_info),
+ GFP_KERNEL);
+
+ if (!chinfo[pier].pd_curves)
+ return -ENOMEM;
+
+ /* Only one curve for RF5111
+ * find out which one and place
+ * in in pd_curves.
+ * Note: ee_x_gain is reversed here */
+ for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
+
+ if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) {
+ pdgain_idx[0] = idx;
+ break;
+ }
+ }
+
+ ee->ee_pd_gains[mode] = 1;
+
+ pd = &chinfo[pier].pd_curves[idx];
+
+ pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111;
+
+ /* Allocate pd points for this curve */
+ pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
+ sizeof(u8), GFP_KERNEL);
+ if (!pd->pd_step)
+ return -ENOMEM;
+
+ pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
+ sizeof(s16), GFP_KERNEL);
+ if (!pd->pd_pwr)
+ return -ENOMEM;
+
+ /* Fill raw dataset
+ * (convert power to 0.25dB units
+ * for RF5112 combatibility) */
+ for (point = 0; point < pd->pd_points; point++) {
+ /* Absolute values */
+ pd->pd_pwr[point] = 2 * pcinfo->pwr[point];
+
+ /* Already sorted */
+ pd->pd_step[point] = pcinfo->pcdac[point];
+ }
+
+ /* Set min/max pwr */
+ chinfo[pier].min_pwr = pd->pd_pwr[0];
+ chinfo[pier].max_pwr = pd->pd_pwr[10];
+
+ }
+
+ return 0;
+}
+
+/* Parse EEPROM data */
static int
ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
struct ath5k_chan_pcal_info *pcal;
int offset, ret;
- int i, j;
+ int i;
u16 val;
offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
@@ -704,26 +819,167 @@ ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min,
cdata->pcdac_max, cdata->pcdac);
+ }
+
+ return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal);
+}
+
+
+/*
+ * Read power calibration for RF5112 chips
+ *
+ * For RF5112 we have 4 XPD -eXternal Power Detector- curves
+ * for each calibrated channel on 0, -6, -12 and -18dbm but we only
+ * use the higher (3) and the lower (0) curves. Each curve has 0.5dB
+ * power steps on x axis and PCDAC steps on y axis and looks like a
+ * linear function. To recreate the curve and pass the power values
+ * on hw, we read 4 points for xpd 0 (lower gain -> max power)
+ * and 3 points for xpd 3 (higher gain -> lower power) here and
+ * interpolate later.
+ *
+ * Note: Many vendors just use xpd 0 so xpd 3 is zeroed.
+ */
+
+/* Convert RF5112 specific data to generic raw data
+ * used by interpolation code */
+static int
+ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
+ struct ath5k_chan_pcal_info *chinfo)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ struct ath5k_chan_pcal_info_rf5112 *pcinfo;
+ u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+ unsigned int pier, pdg, point;
+
+ /* Fill raw data for each calibration pier */
+ for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+
+ pcinfo = &chinfo[pier].rf5112_info;
+
+ /* Allocate pd_curves for this cal pier */
+ chinfo[pier].pd_curves =
+ kcalloc(AR5K_EEPROM_N_PD_CURVES,
+ sizeof(struct ath5k_pdgain_info),
+ GFP_KERNEL);
+
+ if (!chinfo[pier].pd_curves)
+ return -ENOMEM;
+
+ /* Fill pd_curves */
+ for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+
+ u8 idx = pdgain_idx[pdg];
+ struct ath5k_pdgain_info *pd =
+ &chinfo[pier].pd_curves[idx];
+
+ /* Lowest gain curve (max power) */
+ if (pdg == 0) {
+ /* One more point for better accuracy */
+ pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS;
+
+ /* Allocate pd points for this curve */
+ pd->pd_step = kcalloc(pd->pd_points,
+ sizeof(u8), GFP_KERNEL);
+
+ if (!pd->pd_step)
+ return -ENOMEM;
+
+ pd->pd_pwr = kcalloc(pd->pd_points,
+ sizeof(s16), GFP_KERNEL);
+
+ if (!pd->pd_pwr)
+ return -ENOMEM;
+
+
+ /* Fill raw dataset
+ * (all power levels are in 0.25dB units) */
+ pd->pd_step[0] = pcinfo->pcdac_x0[0];
+ pd->pd_pwr[0] = pcinfo->pwr_x0[0];
+
+ for (point = 1; point < pd->pd_points;
+ point++) {
+ /* Absolute values */
+ pd->pd_pwr[point] =
+ pcinfo->pwr_x0[point];
+
+ /* Deltas */
+ pd->pd_step[point] =
+ pd->pd_step[point - 1] +
+ pcinfo->pcdac_x0[point];
+ }
+
+ /* Set min power for this frequency */
+ chinfo[pier].min_pwr = pd->pd_pwr[0];
+
+ /* Highest gain curve (min power) */
+ } else if (pdg == 1) {
+
+ pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS;
+
+ /* Allocate pd points for this curve */
+ pd->pd_step = kcalloc(pd->pd_points,
+ sizeof(u8), GFP_KERNEL);
+
+ if (!pd->pd_step)
+ return -ENOMEM;
+
+ pd->pd_pwr = kcalloc(pd->pd_points,
+ sizeof(s16), GFP_KERNEL);
+
+ if (!pd->pd_pwr)
+ return -ENOMEM;
- for (j = 0; j < AR5K_EEPROM_N_PCDAC; j++) {
- cdata->pwr[j] = (u16)
- (AR5K_EEPROM_POWER_STEP * cdata->pwr[j]);
+ /* Fill raw dataset
+ * (all power levels are in 0.25dB units) */
+ for (point = 0; point < pd->pd_points;
+ point++) {
+ /* Absolute values */
+ pd->pd_pwr[point] =
+ pcinfo->pwr_x3[point];
+
+ /* Fixed points */
+ pd->pd_step[point] =
+ pcinfo->pcdac_x3[point];
+ }
+
+ /* Since we have a higher gain curve
+ * override min power */
+ chinfo[pier].min_pwr = pd->pd_pwr[0];
+ }
}
}
return 0;
}
+/* Parse EEPROM data */
static int
ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info;
struct ath5k_chan_pcal_info *gen_chan_info;
+ u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
u32 offset;
- unsigned int i, c;
+ u8 i, c;
u16 val;
int ret;
+ u8 pd_gains = 0;
+
+ /* Count how many curves we have and
+ * identify them (which one of the 4
+ * available curves we have on each count).
+ * Curves are stored from lower (x0) to
+ * higher (x3) gain */
+ for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) {
+ /* ee_x_gain[mode] is x gain mask */
+ if ((ee->ee_x_gain[mode] >> i) & 0x1)
+ pdgain_idx[pd_gains++] = i;
+ }
+ ee->ee_pd_gains[mode] = pd_gains;
+
+ if (pd_gains == 0 || pd_gains > 2)
+ return -EINVAL;
switch (mode) {
case AR5K_EEPROM_MODE_11A:
@@ -761,13 +1017,13 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
for (i = 0; i < ee->ee_n_piers[mode]; i++) {
chan_pcal_info = &gen_chan_info[i].rf5112_info;
- /* Power values in dBm * 4
+ /* Power values in quarter dB
* for the lower xpd gain curve
* (0 dBm -> higher output power) */
for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr_x0[c] = (val & 0xff);
- chan_pcal_info->pwr_x0[++c] = ((val >> 8) & 0xff);
+ chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff);
+ chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff);
}
/* PCDAC steps
@@ -778,42 +1034,61 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f);
chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f);
- /* Power values in dBm * 4
+ /* Power values in quarter dB
* for the higher xpd gain curve
* (18 dBm -> lower output power) */
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr_x3[0] = (val & 0xff);
- chan_pcal_info->pwr_x3[1] = ((val >> 8) & 0xff);
+ chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff);
+ chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff);
AR5K_EEPROM_READ(offset++, val);
chan_pcal_info->pwr_x3[2] = (val & 0xff);
/* PCDAC steps
* corresponding to the above power
- * measurements (static) */
+ * measurements (fixed) */
chan_pcal_info->pcdac_x3[0] = 20;
chan_pcal_info->pcdac_x3[1] = 35;
chan_pcal_info->pcdac_x3[2] = 63;
if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) {
- chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0xff);
+ chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f);
/* Last xpd0 power level is also channel maximum */
gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3];
} else {
chan_pcal_info->pcdac_x0[0] = 1;
- gen_chan_info[i].max_pwr = ((val >> 8) & 0xff);
+ gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff);
}
- /* Recreate pcdac_x0 table for this channel using pcdac steps */
- chan_pcal_info->pcdac_x0[1] += chan_pcal_info->pcdac_x0[0];
- chan_pcal_info->pcdac_x0[2] += chan_pcal_info->pcdac_x0[1];
- chan_pcal_info->pcdac_x0[3] += chan_pcal_info->pcdac_x0[2];
}
- return 0;
+ return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info);
}
+
+/*
+ * Read power calibration for RF2413 chips
+ *
+ * For RF2413 we have a Power to PDDAC table (Power Detector)
+ * instead of a PCDAC and 4 pd gain curves for each calibrated channel.
+ * Each curve has power on x axis in 0.5 db steps and PDDADC steps on y
+ * axis and looks like an exponential function like the RF5111 curve.
+ *
+ * To recreate the curves we read here the points and interpolate
+ * later. Note that in most cases only 2 (higher and lower) curves are
+ * used (like RF5112) but vendors have the oportunity to include all
+ * 4 curves on eeprom. The final curve (higher power) has an extra
+ * point for better accuracy like RF5112.
+ */
+
+/* For RF2413 power calibration data doesn't start on a fixed location and
+ * if a mode is not supported, it's section is missing -not zeroed-.
+ * So we need to calculate the starting offset for each section by using
+ * these two functions */
+
+/* Return the size of each section based on the mode and the number of pd
+ * gains available (maximum 4). */
static inline unsigned int
ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
{
@@ -826,6 +1101,8 @@ ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
return sz;
}
+/* Return the starting offset for a section based on the modes supported
+ * and each section's size. */
static unsigned int
ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
{
@@ -834,11 +1111,15 @@ ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
switch(mode) {
case AR5K_EEPROM_MODE_11G:
if (AR5K_EEPROM_HDR_11B(ee->ee_header))
- offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11B) + 2;
+ offset += ath5k_pdgains_size_2413(ee,
+ AR5K_EEPROM_MODE_11B) +
+ AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
/* fall through */
case AR5K_EEPROM_MODE_11B:
if (AR5K_EEPROM_HDR_11A(ee->ee_header))
- offset += ath5k_pdgains_size_2413(ee, AR5K_EEPROM_MODE_11A) + 5;
+ offset += ath5k_pdgains_size_2413(ee,
+ AR5K_EEPROM_MODE_11A) +
+ AR5K_EEPROM_N_5GHZ_CHAN / 2;
/* fall through */
case AR5K_EEPROM_MODE_11A:
break;
@@ -849,24 +1130,117 @@ ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
return offset;
}
+/* Convert RF2413 specific data to generic raw data
+ * used by interpolation code */
+static int
+ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
+ struct ath5k_chan_pcal_info *chinfo)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ struct ath5k_chan_pcal_info_rf2413 *pcinfo;
+ u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+ unsigned int pier, pdg, point;
+
+ /* Fill raw data for each calibration pier */
+ for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+
+ pcinfo = &chinfo[pier].rf2413_info;
+
+ /* Allocate pd_curves for this cal pier */
+ chinfo[pier].pd_curves =
+ kcalloc(AR5K_EEPROM_N_PD_CURVES,
+ sizeof(struct ath5k_pdgain_info),
+ GFP_KERNEL);
+
+ if (!chinfo[pier].pd_curves)
+ return -ENOMEM;
+
+ /* Fill pd_curves */
+ for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+
+ u8 idx = pdgain_idx[pdg];
+ struct ath5k_pdgain_info *pd =
+ &chinfo[pier].pd_curves[idx];
+
+ /* One more point for the highest power
+ * curve (lowest gain) */
+ if (pdg == ee->ee_pd_gains[mode] - 1)
+ pd->pd_points = AR5K_EEPROM_N_PD_POINTS;
+ else
+ pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1;
+
+ /* Allocate pd points for this curve */
+ pd->pd_step = kcalloc(pd->pd_points,
+ sizeof(u8), GFP_KERNEL);
+
+ if (!pd->pd_step)
+ return -ENOMEM;
+
+ pd->pd_pwr = kcalloc(pd->pd_points,
+ sizeof(s16), GFP_KERNEL);
+
+ if (!pd->pd_pwr)
+ return -ENOMEM;
+
+ /* Fill raw dataset
+ * convert all pwr levels to
+ * quarter dB for RF5112 combatibility */
+ pd->pd_step[0] = pcinfo->pddac_i[pdg];
+ pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg];
+
+ for (point = 1; point < pd->pd_points; point++) {
+
+ pd->pd_pwr[point] = pd->pd_pwr[point - 1] +
+ 2 * pcinfo->pwr[pdg][point - 1];
+
+ pd->pd_step[point] = pd->pd_step[point - 1] +
+ pcinfo->pddac[pdg][point - 1];
+
+ }
+
+ /* Highest gain curve -> min power */
+ if (pdg == 0)
+ chinfo[pier].min_pwr = pd->pd_pwr[0];
+
+ /* Lowest gain curve -> max power */
+ if (pdg == ee->ee_pd_gains[mode] - 1)
+ chinfo[pier].max_pwr =
+ pd->pd_pwr[pd->pd_points - 1];
+ }
+ }
+
+ return 0;
+}
+
+/* Parse EEPROM data */
static int
ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- struct ath5k_chan_pcal_info_rf2413 *chan_pcal_info;
- struct ath5k_chan_pcal_info *gen_chan_info;
- unsigned int i, c;
+ struct ath5k_chan_pcal_info_rf2413 *pcinfo;
+ struct ath5k_chan_pcal_info *chinfo;
+ u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
u32 offset;
- int ret;
+ int idx, i, ret;
u16 val;
u8 pd_gains = 0;
- if (ee->ee_x_gain[mode] & 0x1) pd_gains++;
- if ((ee->ee_x_gain[mode] >> 1) & 0x1) pd_gains++;
- if ((ee->ee_x_gain[mode] >> 2) & 0x1) pd_gains++;
- if ((ee->ee_x_gain[mode] >> 3) & 0x1) pd_gains++;
+ /* Count how many curves we have and
+ * identify them (which one of the 4
+ * available curves we have on each count).
+ * Curves are stored from higher to
+ * lower gain so we go backwards */
+ for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) {
+ /* ee_x_gain[mode] is x gain mask */
+ if ((ee->ee_x_gain[mode] >> idx) & 0x1)
+ pdgain_idx[pd_gains++] = idx;
+
+ }
ee->ee_pd_gains[mode] = pd_gains;
+ if (pd_gains == 0)
+ return -EINVAL;
+
offset = ath5k_cal_data_offset_2413(ee, mode);
switch (mode) {
case AR5K_EEPROM_MODE_11A:
@@ -875,7 +1249,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
ath5k_eeprom_init_11a_pcal_freq(ah, offset);
offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
- gen_chan_info = ee->ee_pwr_cal_a;
+ chinfo = ee->ee_pwr_cal_a;
break;
case AR5K_EEPROM_MODE_11B:
if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
@@ -883,7 +1257,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
ath5k_eeprom_init_11bg_2413(ah, mode, offset);
offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
- gen_chan_info = ee->ee_pwr_cal_b;
+ chinfo = ee->ee_pwr_cal_b;
break;
case AR5K_EEPROM_MODE_11G:
if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
@@ -891,41 +1265,35 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
ath5k_eeprom_init_11bg_2413(ah, mode, offset);
offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
- gen_chan_info = ee->ee_pwr_cal_g;
+ chinfo = ee->ee_pwr_cal_g;
break;
default:
return -EINVAL;
}
- if (pd_gains == 0)
- return 0;
-
for (i = 0; i < ee->ee_n_piers[mode]; i++) {
- chan_pcal_info = &gen_chan_info[i].rf2413_info;
+ pcinfo = &chinfo[i].rf2413_info;
/*
* Read pwr_i, pddac_i and the first
* 2 pd points (pwr, pddac)
*/
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr_i[0] = val & 0x1f;
- chan_pcal_info->pddac_i[0] = (val >> 5) & 0x7f;
- chan_pcal_info->pwr[0][0] =
- (val >> 12) & 0xf;
+ pcinfo->pwr_i[0] = val & 0x1f;
+ pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
+ pcinfo->pwr[0][0] = (val >> 12) & 0xf;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac[0][0] = val & 0x3f;
- chan_pcal_info->pwr[0][1] = (val >> 6) & 0xf;
- chan_pcal_info->pddac[0][1] =
- (val >> 10) & 0x3f;
+ pcinfo->pddac[0][0] = val & 0x3f;
+ pcinfo->pwr[0][1] = (val >> 6) & 0xf;
+ pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr[0][2] = val & 0xf;
- chan_pcal_info->pddac[0][2] =
- (val >> 4) & 0x3f;
+ pcinfo->pwr[0][2] = val & 0xf;
+ pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
- chan_pcal_info->pwr[0][3] = 0;
- chan_pcal_info->pddac[0][3] = 0;
+ pcinfo->pwr[0][3] = 0;
+ pcinfo->pddac[0][3] = 0;
if (pd_gains > 1) {
/*
@@ -933,44 +1301,36 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
* so it only has 2 pd points.
* Continue wih pd gain 1.
*/
- chan_pcal_info->pwr_i[1] = (val >> 10) & 0x1f;
+ pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
- chan_pcal_info->pddac_i[1] = (val >> 15) & 0x1;
+ pcinfo->pddac_i[1] = (val >> 15) & 0x1;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac_i[1] |= (val & 0x3F) << 1;
+ pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
- chan_pcal_info->pwr[1][0] = (val >> 6) & 0xf;
- chan_pcal_info->pddac[1][0] =
- (val >> 10) & 0x3f;
+ pcinfo->pwr[1][0] = (val >> 6) & 0xf;
+ pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr[1][1] = val & 0xf;
- chan_pcal_info->pddac[1][1] =
- (val >> 4) & 0x3f;
- chan_pcal_info->pwr[1][2] =
- (val >> 10) & 0xf;
-
- chan_pcal_info->pddac[1][2] =
- (val >> 14) & 0x3;
+ pcinfo->pwr[1][1] = val & 0xf;
+ pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
+ pcinfo->pwr[1][2] = (val >> 10) & 0xf;
+
+ pcinfo->pddac[1][2] = (val >> 14) & 0x3;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac[1][2] |=
- (val & 0xF) << 2;
+ pcinfo->pddac[1][2] |= (val & 0xF) << 2;
- chan_pcal_info->pwr[1][3] = 0;
- chan_pcal_info->pddac[1][3] = 0;
+ pcinfo->pwr[1][3] = 0;
+ pcinfo->pddac[1][3] = 0;
} else if (pd_gains == 1) {
/*
* Pd gain 0 is the last one so
* read the extra point.
*/
- chan_pcal_info->pwr[0][3] =
- (val >> 10) & 0xf;
+ pcinfo->pwr[0][3] = (val >> 10) & 0xf;
- chan_pcal_info->pddac[0][3] =
- (val >> 14) & 0x3;
+ pcinfo->pddac[0][3] = (val >> 14) & 0x3;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac[0][3] |=
- (val & 0xF) << 2;
+ pcinfo->pddac[0][3] |= (val & 0xF) << 2;
}
/*
@@ -978,105 +1338,65 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
* as above.
*/
if (pd_gains > 2) {
- chan_pcal_info->pwr_i[2] = (val >> 4) & 0x1f;
- chan_pcal_info->pddac_i[2] = (val >> 9) & 0x7f;
+ pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
+ pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr[2][0] =
- (val >> 0) & 0xf;
- chan_pcal_info->pddac[2][0] =
- (val >> 4) & 0x3f;
- chan_pcal_info->pwr[2][1] =
- (val >> 10) & 0xf;
-
- chan_pcal_info->pddac[2][1] =
- (val >> 14) & 0x3;
+ pcinfo->pwr[2][0] = (val >> 0) & 0xf;
+ pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
+ pcinfo->pwr[2][1] = (val >> 10) & 0xf;
+
+ pcinfo->pddac[2][1] = (val >> 14) & 0x3;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac[2][1] |=
- (val & 0xF) << 2;
+ pcinfo->pddac[2][1] |= (val & 0xF) << 2;
- chan_pcal_info->pwr[2][2] =
- (val >> 4) & 0xf;
- chan_pcal_info->pddac[2][2] =
- (val >> 8) & 0x3f;
+ pcinfo->pwr[2][2] = (val >> 4) & 0xf;
+ pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
- chan_pcal_info->pwr[2][3] = 0;
- chan_pcal_info->pddac[2][3] = 0;
+ pcinfo->pwr[2][3] = 0;
+ pcinfo->pddac[2][3] = 0;
} else if (pd_gains == 2) {
- chan_pcal_info->pwr[1][3] =
- (val >> 4) & 0xf;
- chan_pcal_info->pddac[1][3] =
- (val >> 8) & 0x3f;
+ pcinfo->pwr[1][3] = (val >> 4) & 0xf;
+ pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
}
if (pd_gains > 3) {
- chan_pcal_info->pwr_i[3] = (val >> 14) & 0x3;
+ pcinfo->pwr_i[3] = (val >> 14) & 0x3;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
+ pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
- chan_pcal_info->pddac_i[3] = (val >> 3) & 0x7f;
- chan_pcal_info->pwr[3][0] =
- (val >> 10) & 0xf;
- chan_pcal_info->pddac[3][0] =
- (val >> 14) & 0x3;
+ pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
+ pcinfo->pwr[3][0] = (val >> 10) & 0xf;
+ pcinfo->pddac[3][0] = (val >> 14) & 0x3;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac[3][0] |=
- (val & 0xF) << 2;
- chan_pcal_info->pwr[3][1] =
- (val >> 4) & 0xf;
- chan_pcal_info->pddac[3][1] =
- (val >> 8) & 0x3f;
-
- chan_pcal_info->pwr[3][2] =
- (val >> 14) & 0x3;
+ pcinfo->pddac[3][0] |= (val & 0xF) << 2;
+ pcinfo->pwr[3][1] = (val >> 4) & 0xf;
+ pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
+
+ pcinfo->pwr[3][2] = (val >> 14) & 0x3;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr[3][2] |=
- ((val >> 0) & 0x3) << 2;
+ pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
- chan_pcal_info->pddac[3][2] =
- (val >> 2) & 0x3f;
- chan_pcal_info->pwr[3][3] =
- (val >> 8) & 0xf;
+ pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
+ pcinfo->pwr[3][3] = (val >> 8) & 0xf;
- chan_pcal_info->pddac[3][3] =
- (val >> 12) & 0xF;
+ pcinfo->pddac[3][3] = (val >> 12) & 0xF;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pddac[3][3] |=
- ((val >> 0) & 0x3) << 4;
+ pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
} else if (pd_gains == 3) {
- chan_pcal_info->pwr[2][3] =
- (val >> 14) & 0x3;
+ pcinfo->pwr[2][3] = (val >> 14) & 0x3;
AR5K_EEPROM_READ(offset++, val);
- chan_pcal_info->pwr[2][3] |=
- ((val >> 0) & 0x3) << 2;
-
- chan_pcal_info->pddac[2][3] =
- (val >> 2) & 0x3f;
- }
+ pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
- for (c = 0; c < pd_gains; c++) {
- /* Recreate pwr table for this channel using pwr steps */
- chan_pcal_info->pwr[c][0] += chan_pcal_info->pwr_i[c] * 2;
- chan_pcal_info->pwr[c][1] += chan_pcal_info->pwr[c][0];
- chan_pcal_info->pwr[c][2] += chan_pcal_info->pwr[c][1];
- chan_pcal_info->pwr[c][3] += chan_pcal_info->pwr[c][2];
- if (chan_pcal_info->pwr[c][3] == chan_pcal_info->pwr[c][2])
- chan_pcal_info->pwr[c][3] = 0;
-
- /* Recreate pddac table for this channel using pddac steps */
- chan_pcal_info->pddac[c][0] += chan_pcal_info->pddac_i[c];
- chan_pcal_info->pddac[c][1] += chan_pcal_info->pddac[c][0];
- chan_pcal_info->pddac[c][2] += chan_pcal_info->pddac[c][1];
- chan_pcal_info->pddac[c][3] += chan_pcal_info->pddac[c][2];
- if (chan_pcal_info->pddac[c][3] == chan_pcal_info->pddac[c][2])
- chan_pcal_info->pddac[c][3] = 0;
+ pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
}
}
- return 0;
+ return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo);
}
+
/*
* Read per rate target power (this is the maximum tx power
* supported by the card). This info is used when setting
@@ -1084,11 +1404,12 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
*
* This also works for v5 EEPROMs.
*/
-static int ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
+static int
+ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
struct ath5k_rate_pcal_info *rate_pcal_info;
- u16 *rate_target_pwr_num;
+ u8 *rate_target_pwr_num;
u32 offset;
u16 val;
int ret, i;
@@ -1163,6 +1484,20 @@ static int ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned
return 0;
}
+/*
+ * Read per channel calibration info from EEPROM
+ *
+ * This info is used to calibrate the baseband power table. Imagine
+ * that for each channel there is a power curve that's hw specific
+ * (depends on amplifier etc) and we try to "correct" this curve using
+ * offests we pass on to phy chip (baseband -> before amplifier) so that
+ * it can use accurate power values when setting tx power (takes amplifier's
+ * performance on each channel into account).
+ *
+ * EEPROM provides us with the offsets for some pre-calibrated channels
+ * and we have to interpolate to create the full table for these channels and
+ * also the table for any channel.
+ */
static int
ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
{
@@ -1180,7 +1515,9 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
else
read_pcal = ath5k_eeprom_read_pcal_info_5111;
- for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
+
+ for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G;
+ mode++) {
err = read_pcal(ah, mode);
if (err)
return err;
@@ -1193,7 +1530,63 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
return 0;
}
-/* Read conformance test limits */
+static int
+ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ struct ath5k_chan_pcal_info *chinfo;
+ u8 pier, pdg;
+
+ switch (mode) {
+ case AR5K_EEPROM_MODE_11A:
+ if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
+ return 0;
+ chinfo = ee->ee_pwr_cal_a;
+ break;
+ case AR5K_EEPROM_MODE_11B:
+ if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
+ return 0;
+ chinfo = ee->ee_pwr_cal_b;
+ break;
+ case AR5K_EEPROM_MODE_11G:
+ if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
+ return 0;
+ chinfo = ee->ee_pwr_cal_g;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+ if (!chinfo[pier].pd_curves)
+ continue;
+
+ for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+ struct ath5k_pdgain_info *pd =
+ &chinfo[pier].pd_curves[pdg];
+
+ if (pd != NULL) {
+ kfree(pd->pd_step);
+ kfree(pd->pd_pwr);
+ }
+ }
+
+ kfree(chinfo[pier].pd_curves);
+ }
+
+ return 0;
+}
+
+void
+ath5k_eeprom_detach(struct ath5k_hw *ah)
+{
+ u8 mode;
+
+ for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
+ ath5k_eeprom_free_pcal_info(ah, mode);
+}
+
+/* Read conformance test limits used for regulatory control */
static int
ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
{
@@ -1328,19 +1721,17 @@ ath5k_eeprom_init(struct ath5k_hw *ah)
return 0;
}
+
/*
* Read the MAC address from eeprom
*/
int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
{
- u8 mac_d[ETH_ALEN];
+ u8 mac_d[ETH_ALEN] = {};
u32 total, offset;
u16 data;
int octet, ret;
- memset(mac, 0, ETH_ALEN);
- memset(mac_d, 0, ETH_ALEN);
-
ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
if (ret)
return ret;
@@ -1356,11 +1747,23 @@ int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
octet += 2;
}
- memcpy(mac, mac_d, ETH_ALEN);
-
if (!total || total == 3 * 0xffff)
return -EINVAL;
+ memcpy(mac, mac_d, ETH_ALEN);
+
return 0;
}
+bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah)
+{
+ u16 data;
+
+ ath5k_hw_eeprom_read(ah, AR5K_EEPROM_IS_HB63, &data);
+
+ if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && data)
+ return true;
+ else
+ return false;
+}
+
diff --git a/drivers/net/wireless/ath5k/eeprom.h b/drivers/net/wireless/ath5k/eeprom.h
index 09eb7d0176a4..b0c0606dea0b 100644
--- a/drivers/net/wireless/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath5k/eeprom.h
@@ -25,6 +25,7 @@
#define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */
#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
+#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */
#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
#define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */
#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
@@ -172,6 +173,7 @@
#define AR5K_EEPROM_N_5GHZ_CHAN 10
#define AR5K_EEPROM_N_2GHZ_CHAN 3
#define AR5K_EEPROM_N_2GHZ_CHAN_2413 4
+#define AR5K_EEPROM_N_2GHZ_CHAN_MAX 4
#define AR5K_EEPROM_MAX_CHAN 10
#define AR5K_EEPROM_N_PWR_POINTS_5111 11
#define AR5K_EEPROM_N_PCDAC 11
@@ -192,7 +194,7 @@
#define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10)
#define AR5K_EEPROM_N_CTLS(_v) AR5K_EEPROM_OFF(_v, 16, 32)
#define AR5K_EEPROM_MAX_CTLS 32
-#define AR5K_EEPROM_N_XPD_PER_CHANNEL 4
+#define AR5K_EEPROM_N_PD_CURVES 4
#define AR5K_EEPROM_N_XPD0_POINTS 4
#define AR5K_EEPROM_N_XPD3_POINTS 3
#define AR5K_EEPROM_N_PD_GAINS 4
@@ -231,7 +233,7 @@ enum ath5k_ctl_mode {
AR5K_CTL_11B = 1,
AR5K_CTL_11G = 2,
AR5K_CTL_TURBO = 3,
- AR5K_CTL_108G = 4,
+ AR5K_CTL_TURBOG = 4,
AR5K_CTL_2GHT20 = 5,
AR5K_CTL_5GHT20 = 6,
AR5K_CTL_2GHT40 = 7,
@@ -239,65 +241,114 @@ enum ath5k_ctl_mode {
AR5K_CTL_MODE_M = 15,
};
+/* Default CTL ids for the 3 main reg domains.
+ * Atheros only uses these by default but vendors
+ * can have up to 32 different CTLs for different
+ * scenarios. Note that theese values are ORed with
+ * the mode id (above) so we can have up to 24 CTL
+ * datasets out of these 3 main regdomains. That leaves
+ * 8 ids that can be used by vendors and since 0x20 is
+ * missing from HAL sources i guess this is the set of
+ * custom CTLs vendors can use. */
+#define AR5K_CTL_FCC 0x10
+#define AR5K_CTL_CUSTOM 0x20
+#define AR5K_CTL_ETSI 0x30
+#define AR5K_CTL_MKK 0x40
+
+/* Indicates a CTL with only mode set and
+ * no reg domain mapping, such CTLs are used
+ * for world roaming domains or simply when
+ * a reg domain is not set */
+#define AR5K_CTL_NO_REGDOMAIN 0xf0
+
+/* Indicates an empty (invalid) CTL */
+#define AR5K_CTL_NO_CTL 0xff
+
/* Per channel calibration data, used for power table setup */
struct ath5k_chan_pcal_info_rf5111 {
/* Power levels in half dbm units
* for one power curve. */
- u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111];
+ u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111];
/* PCDAC table steps
* for the above values */
- u8 pcdac[AR5K_EEPROM_N_PWR_POINTS_5111];
+ u8 pcdac[AR5K_EEPROM_N_PWR_POINTS_5111];
/* Starting PCDAC step */
- u8 pcdac_min;
+ u8 pcdac_min;
/* Final PCDAC step */
- u8 pcdac_max;
+ u8 pcdac_max;
};
struct ath5k_chan_pcal_info_rf5112 {
/* Power levels in quarter dBm units
* for lower (0) and higher (3)
- * level curves */
- s8 pwr_x0[AR5K_EEPROM_N_XPD0_POINTS];
- s8 pwr_x3[AR5K_EEPROM_N_XPD3_POINTS];
+ * level curves in 0.25dB units */
+ s8 pwr_x0[AR5K_EEPROM_N_XPD0_POINTS];
+ s8 pwr_x3[AR5K_EEPROM_N_XPD3_POINTS];
/* PCDAC table steps
* for the above values */
- u8 pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS];
- u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
+ u8 pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS];
+ u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
};
struct ath5k_chan_pcal_info_rf2413 {
/* Starting pwr/pddac values */
- s8 pwr_i[AR5K_EEPROM_N_PD_GAINS];
- u8 pddac_i[AR5K_EEPROM_N_PD_GAINS];
- /* (pwr,pddac) points */
- s8 pwr[AR5K_EEPROM_N_PD_GAINS]
- [AR5K_EEPROM_N_PD_POINTS];
- u8 pddac[AR5K_EEPROM_N_PD_GAINS]
- [AR5K_EEPROM_N_PD_POINTS];
+ s8 pwr_i[AR5K_EEPROM_N_PD_GAINS];
+ u8 pddac_i[AR5K_EEPROM_N_PD_GAINS];
+ /* (pwr,pddac) points
+ * power levels in 0.5dB units */
+ s8 pwr[AR5K_EEPROM_N_PD_GAINS]
+ [AR5K_EEPROM_N_PD_POINTS];
+ u8 pddac[AR5K_EEPROM_N_PD_GAINS]
+ [AR5K_EEPROM_N_PD_POINTS];
+};
+
+enum ath5k_powertable_type {
+ AR5K_PWRTABLE_PWR_TO_PCDAC = 0,
+ AR5K_PWRTABLE_LINEAR_PCDAC = 1,
+ AR5K_PWRTABLE_PWR_TO_PDADC = 2,
+};
+
+struct ath5k_pdgain_info {
+ u8 pd_points;
+ u8 *pd_step;
+ /* Power values are in
+ * 0.25dB units */
+ s16 *pd_pwr;
};
struct ath5k_chan_pcal_info {
/* Frequency */
u16 freq;
- /* Max available power */
- s8 max_pwr;
+ /* Tx power boundaries */
+ s16 max_pwr;
+ s16 min_pwr;
union {
struct ath5k_chan_pcal_info_rf5111 rf5111_info;
struct ath5k_chan_pcal_info_rf5112 rf5112_info;
struct ath5k_chan_pcal_info_rf2413 rf2413_info;
};
+ /* Raw values used by phy code
+ * Curves are stored in order from lower
+ * gain to higher gain (max txpower -> min txpower) */
+ struct ath5k_pdgain_info *pd_curves;
};
-/* Per rate calibration data for each mode, used for power table setup */
+/* Per rate calibration data for each mode,
+ * used for rate power table setup.
+ * Note: Values in 0.5dB units */
struct ath5k_rate_pcal_info {
u16 freq; /* Frequency */
- /* Power level for 6-24Mbit/s rates */
+ /* Power level for 6-24Mbit/s rates or
+ * 1Mb rate */
u16 target_power_6to24;
- /* Power level for 36Mbit rate */
+ /* Power level for 36Mbit rate or
+ * 2Mb rate */
u16 target_power_36;
- /* Power level for 48Mbit rate */
+ /* Power level for 48Mbit rate or
+ * 5.5Mbit rate */
u16 target_power_48;
- /* Power level for 54Mbit rate */
+ /* Power level for 54Mbit rate or
+ * 11Mbit rate */
u16 target_power_54;
};
@@ -329,12 +380,6 @@ struct ath5k_eeprom_info {
u16 ee_cck_ofdm_power_delta;
u16 ee_scaled_cck_delta;
- /* Used for tx thermal adjustment (eeprom_init, rfregs) */
- u16 ee_tx_clip;
- u16 ee_pwd_84;
- u16 ee_pwd_90;
- u16 ee_gain_select;
-
/* RF Calibration settings (reset, rfregs) */
u16 ee_i_cal[AR5K_EEPROM_N_MODES];
u16 ee_q_cal[AR5K_EEPROM_N_MODES];
@@ -362,23 +407,25 @@ struct ath5k_eeprom_info {
/* Power calibration data */
u16 ee_false_detect[AR5K_EEPROM_N_MODES];
- /* Number of pd gain curves per mode (RF2413) */
- u8 ee_pd_gains[AR5K_EEPROM_N_MODES];
+ /* Number of pd gain curves per mode */
+ u8 ee_pd_gains[AR5K_EEPROM_N_MODES];
+ /* Back mapping pdcurve number -> pdcurve index in pd->pd_curves */
+ u8 ee_pdc_to_idx[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PD_GAINS];
- u8 ee_n_piers[AR5K_EEPROM_N_MODES];
+ u8 ee_n_piers[AR5K_EEPROM_N_MODES];
struct ath5k_chan_pcal_info ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN];
- struct ath5k_chan_pcal_info ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN];
- struct ath5k_chan_pcal_info ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN];
+ struct ath5k_chan_pcal_info ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
+ struct ath5k_chan_pcal_info ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
/* Per rate target power levels */
- u16 ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES];
+ u8 ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES];
struct ath5k_rate_pcal_info ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN];
- struct ath5k_rate_pcal_info ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN];
- struct ath5k_rate_pcal_info ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN];
+ struct ath5k_rate_pcal_info ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
+ struct ath5k_rate_pcal_info ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
/* Conformance test limits (Unused) */
- u16 ee_ctls;
- u16 ee_ctl[AR5K_EEPROM_MAX_CTLS];
+ u8 ee_ctls;
+ u8 ee_ctl[AR5K_EEPROM_MAX_CTLS];
struct ath5k_edge_power ee_ctl_pwr[AR5K_EEPROM_N_EDGES * AR5K_EEPROM_MAX_CTLS];
/* Noise Floor Calibration settings */
diff --git a/drivers/net/wireless/ath5k/gpio.c b/drivers/net/wireless/ath5k/gpio.c
index b77205adc180..64a27e73d02e 100644
--- a/drivers/net/wireless/ath5k/gpio.c
+++ b/drivers/net/wireless/ath5k/gpio.c
@@ -83,7 +83,7 @@ void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
{
ATH5K_TRACE(ah->ah_sc);
- if (gpio > AR5K_NUM_GPIO)
+ if (gpio >= AR5K_NUM_GPIO)
return -EINVAL;
ath5k_hw_reg_write(ah,
@@ -99,7 +99,7 @@ int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
{
ATH5K_TRACE(ah->ah_sc);
- if (gpio > AR5K_NUM_GPIO)
+ if (gpio >= AR5K_NUM_GPIO)
return -EINVAL;
ath5k_hw_reg_write(ah,
@@ -115,7 +115,7 @@ int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
{
ATH5K_TRACE(ah->ah_sc);
- if (gpio > AR5K_NUM_GPIO)
+ if (gpio >= AR5K_NUM_GPIO)
return 0xffffffff;
/* GPIO input magic */
@@ -131,7 +131,7 @@ int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
u32 data;
ATH5K_TRACE(ah->ah_sc);
- if (gpio > AR5K_NUM_GPIO)
+ if (gpio >= AR5K_NUM_GPIO)
return -EINVAL;
/* GPIO output magic */
@@ -154,7 +154,7 @@ void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
u32 data;
ATH5K_TRACE(ah->ah_sc);
- if (gpio > AR5K_NUM_GPIO)
+ if (gpio >= AR5K_NUM_GPIO)
return;
/*
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
index 450bd6e945ff..61fb621ed20d 100644
--- a/drivers/net/wireless/ath5k/initvals.c
+++ b/drivers/net/wireless/ath5k/initvals.c
@@ -2,7 +2,7 @@
* Initial register settings functions
*
* Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
* Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -340,7 +340,7 @@ static const struct ath5k_ini ar5211_ini[] = {
* common on all cards/modes.
* Note: Table is rewritten during
* txpower setup later using calibration
- * data etc. so next write is non-common
+ * data etc. so next write is non-common */
{ AR5K_PHY_PCDAC_TXPOWER(1), 0x06ff05ff },
{ AR5K_PHY_PCDAC_TXPOWER(2), 0x07ff07ff },
{ AR5K_PHY_PCDAC_TXPOWER(3), 0x08ff08ff },
@@ -371,7 +371,7 @@ static const struct ath5k_ini ar5211_ini[] = {
{ AR5K_PHY_PCDAC_TXPOWER(28), 0x3aff3aff },
{ AR5K_PHY_PCDAC_TXPOWER(29), 0x3aff3aff },
{ AR5K_PHY_PCDAC_TXPOWER(30), 0x3aff3aff },
- { AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff },*/
+ { AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff },
{ AR5K_PHY_CCKTXCTL, 0x00000000 },
{ AR5K_PHY(642), 0x503e4646 },
{ AR5K_PHY_GAIN_2GHZ, 0x6480416c },
@@ -386,85 +386,85 @@ static const struct ath5k_ini ar5211_ini[] = {
};
/* Initial mode-specific settings for AR5211
- * XXX: how about g / gTurbo ? RF5111 supports it, how about AR5211 ?
- * Maybe 5211 supports OFDM-only g but we need to test it !
+ * 5211 supports OFDM-only g (draft g) but we
+ * need to test it !
*/
static const struct ath5k_ini_mode ar5211_ini_mode[] = {
{ AR5K_TXCFG,
- /* a aTurbo b */
- { 0x00000015, 0x00000015, 0x0000001d } },
+ /* a aTurbo b g (OFDM) */
+ { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(0),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(1),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(2),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(3),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(4),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(5),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(6),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(7),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(8),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(9),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
{ AR5K_DCU_GBL_IFS_SLOT,
- { 0x00000168, 0x000001e0, 0x000001b8 } },
+ { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } },
{ AR5K_DCU_GBL_IFS_SIFS,
- { 0x00000230, 0x000001e0, 0x000000b0 } },
+ { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } },
{ AR5K_DCU_GBL_IFS_EIFS,
- { 0x00000d98, 0x00001180, 0x00001f48 } },
+ { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } },
{ AR5K_DCU_GBL_IFS_MISC,
- { 0x0000a0e0, 0x00014068, 0x00005880 } },
+ { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } },
{ AR5K_TIME_OUT,
- { 0x04000400, 0x08000800, 0x20003000 } },
+ { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } },
{ AR5K_USEC_5211,
- { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95 } },
+ { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } },
{ AR5K_PHY_TURBO,
- { 0x00000000, 0x00000003, 0x00000000 } },
+ { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } },
{ AR5K_PHY(8),
- { 0x02020200, 0x02020200, 0x02010200 } },
+ { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } },
{ AR5K_PHY(9),
- { 0x00000e0e, 0x00000e0e, 0x00000707 } },
+ { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } },
{ AR5K_PHY(10),
- { 0x0a020001, 0x0a020001, 0x05010000 } },
+ { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } },
{ AR5K_PHY(13),
- { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
{ AR5K_PHY(14),
- { 0x00000007, 0x00000007, 0x0000000b } },
+ { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } },
{ AR5K_PHY(17),
- { 0x1372169c, 0x137216a5, 0x137216a8 } },
+ { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } },
{ AR5K_PHY(18),
- { 0x0018ba67, 0x0018ba67, 0x0018ba69 } },
+ { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
{ AR5K_PHY(20),
- { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
+ { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e } },
+ { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x31375d5e, 0x31375d5e, 0x313a5d5e } },
+ { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
{ AR5K_PHY_AGCCTL,
- { 0x0000bd10, 0x0000bd10, 0x0000bd38 } },
+ { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
{ AR5K_PHY_NF,
- { 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+ { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
{ AR5K_PHY_RX_DELAY,
- { 0x00002710, 0x00002710, 0x0000157c } },
+ { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } },
{ AR5K_PHY(70),
- { 0x00000190, 0x00000190, 0x00000084 } },
+ { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0x6fe01020, 0x6fe01020, 0x6fe00920 } },
- { AR5K_PHY_PCDAC_TXPOWER_BASE_5211,
- { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff } },
+ { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
+ { AR5K_PHY_PCDAC_TXPOWER_BASE,
+ { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
{ AR5K_RF_BUFFER_CONTROL_4,
- { 0x00000010, 0x00000014, 0x00000010 } },
+ { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } },
};
/* Initial register settings for AR5212 */
-static const struct ath5k_ini ar5212_ini[] = {
+static const struct ath5k_ini ar5212_ini_common_start[] = {
{ AR5K_RXDP, 0x00000000 },
{ AR5K_RXCFG, 0x00000005 },
{ AR5K_MIBC, 0x00000000 },
@@ -485,91 +485,83 @@ static const struct ath5k_ini ar5212_ini[] = {
{ AR5K_QUEUE_TXDP(9), 0x00000000 },
{ AR5K_DCU_FP, 0x00000000 },
{ AR5K_DCU_TXP, 0x00000000 },
- { AR5K_DCU_TX_FILTER_0_BASE, 0x00000000 },
- /* Unknown table */
- { 0x1078, 0x00000000 },
- { 0x10b8, 0x00000000 },
- { 0x10f8, 0x00000000 },
- { 0x1138, 0x00000000 },
- { 0x1178, 0x00000000 },
- { 0x11b8, 0x00000000 },
- { 0x11f8, 0x00000000 },
- { 0x1238, 0x00000000 },
- { 0x1278, 0x00000000 },
- { 0x12b8, 0x00000000 },
- { 0x12f8, 0x00000000 },
- { 0x1338, 0x00000000 },
- { 0x1378, 0x00000000 },
- { 0x13b8, 0x00000000 },
- { 0x13f8, 0x00000000 },
- { 0x1438, 0x00000000 },
- { 0x1478, 0x00000000 },
- { 0x14b8, 0x00000000 },
- { 0x14f8, 0x00000000 },
- { 0x1538, 0x00000000 },
- { 0x1578, 0x00000000 },
- { 0x15b8, 0x00000000 },
- { 0x15f8, 0x00000000 },
- { 0x1638, 0x00000000 },
- { 0x1678, 0x00000000 },
- { 0x16b8, 0x00000000 },
- { 0x16f8, 0x00000000 },
- { 0x1738, 0x00000000 },
- { 0x1778, 0x00000000 },
- { 0x17b8, 0x00000000 },
- { 0x17f8, 0x00000000 },
- { 0x103c, 0x00000000 },
- { 0x107c, 0x00000000 },
- { 0x10bc, 0x00000000 },
- { 0x10fc, 0x00000000 },
- { 0x113c, 0x00000000 },
- { 0x117c, 0x00000000 },
- { 0x11bc, 0x00000000 },
- { 0x11fc, 0x00000000 },
- { 0x123c, 0x00000000 },
- { 0x127c, 0x00000000 },
- { 0x12bc, 0x00000000 },
- { 0x12fc, 0x00000000 },
- { 0x133c, 0x00000000 },
- { 0x137c, 0x00000000 },
- { 0x13bc, 0x00000000 },
- { 0x13fc, 0x00000000 },
- { 0x143c, 0x00000000 },
- { 0x147c, 0x00000000 },
+ /* Tx filter table 0 (32 entries) */
+ { AR5K_DCU_TX_FILTER_0(0), 0x00000000 }, /* DCU 0 */
+ { AR5K_DCU_TX_FILTER_0(1), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(2), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(3), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(4), 0x00000000 }, /* DCU 1 */
+ { AR5K_DCU_TX_FILTER_0(5), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(6), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(7), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(8), 0x00000000 }, /* DCU 2 */
+ { AR5K_DCU_TX_FILTER_0(9), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(10), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(11), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(12), 0x00000000 }, /* DCU 3 */
+ { AR5K_DCU_TX_FILTER_0(13), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(14), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(15), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(16), 0x00000000 }, /* DCU 4 */
+ { AR5K_DCU_TX_FILTER_0(17), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(18), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(19), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(20), 0x00000000 }, /* DCU 5 */
+ { AR5K_DCU_TX_FILTER_0(21), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(22), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(23), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(24), 0x00000000 }, /* DCU 6 */
+ { AR5K_DCU_TX_FILTER_0(25), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(26), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(27), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(28), 0x00000000 }, /* DCU 7 */
+ { AR5K_DCU_TX_FILTER_0(29), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(30), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_0(31), 0x00000000 },
+ /* Tx filter table 1 (16 entries) */
+ { AR5K_DCU_TX_FILTER_1(0), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(1), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(2), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(3), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(4), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(5), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(6), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(7), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(8), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(9), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(10), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(11), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(12), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(13), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(14), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_1(15), 0x00000000 },
+ { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
+ { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
{ AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
{ AR5K_DCU_TX_FILTER_SET, 0x00000000 },
{ AR5K_STA_ID1, 0x00000000 },
{ AR5K_BSS_ID0, 0x00000000 },
{ AR5K_BSS_ID1, 0x00000000 },
- /*{ AR5K_RSSI_THR, 0x00000000 },*/ /* Found on SuperAG cards */
- { AR5K_BEACON_5211, 0x00000000 }, /* Found on SuperAG cards */
- { AR5K_CFP_PERIOD_5211, 0x00000000 }, /* Found on SuperAG cards */
- { AR5K_TIMER0_5211, 0x00000030 }, /* Found on SuperAG cards */
- { AR5K_TIMER1_5211, 0x0007ffff }, /* Found on SuperAG cards */
- { AR5K_TIMER2_5211, 0x01ffffff }, /* Found on SuperAG cards */
- { AR5K_TIMER3_5211, 0x00000031 }, /* Found on SuperAG cards */
- { AR5K_CFP_DUR_5211, 0x00000000 }, /* Found on SuperAG cards */
+ { AR5K_BEACON_5211, 0x00000000 },
+ { AR5K_CFP_PERIOD_5211, 0x00000000 },
+ { AR5K_TIMER0_5211, 0x00000030 },
+ { AR5K_TIMER1_5211, 0x0007ffff },
+ { AR5K_TIMER2_5211, 0x01ffffff },
+ { AR5K_TIMER3_5211, 0x00000031 },
+ { AR5K_CFP_DUR_5211, 0x00000000 },
{ AR5K_RX_FILTER_5211, 0x00000000 },
{ AR5K_DIAG_SW_5211, 0x00000000 },
{ AR5K_ADDAC_TEST, 0x00000000 },
{ AR5K_DEFAULT_ANTENNA, 0x00000000 },
- { 0x8080, 0x00000000 },
- /*{ 0x805c, 0xffffc7ff },*/ /* Old value */
- { 0x805c, 0x000fc78f },
- { AR5K_NAV_5211, 0x00000000 }, /* Not found on recent */
- { AR5K_RTS_OK_5211, 0x00000000 }, /* dumps but it makes */
- { AR5K_RTS_FAIL_5211, 0x00000000 }, /* sense to reset counters */
- { AR5K_ACK_FAIL_5211, 0x00000000 }, /* since pcu registers */
- { AR5K_FCS_FAIL_5211, 0x00000000 }, /* are skiped during chan*/
- { AR5K_BEACON_CNT_5211, 0x00000000 }, /* change */
+ { AR5K_FRAME_CTL_QOSM, 0x000fc78f },
{ AR5K_XRMODE, 0x2a82301a },
{ AR5K_XRDELAY, 0x05dc01e0 },
{ AR5K_XRTIMEOUT, 0x1f402710 },
{ AR5K_XRCHIRP, 0x01f40000 },
{ AR5K_XRSTOMP, 0x00001e1c },
- { AR5K_SLEEP0, 0x0002aaaa }, /* Found on SuperAG cards */
- { AR5K_SLEEP1, 0x02005555 }, /* Found on SuperAG cards */
- { AR5K_SLEEP2, 0x00000000 }, /* Found on SuperAG cards */
+ { AR5K_SLEEP0, 0x0002aaaa },
+ { AR5K_SLEEP1, 0x02005555 },
+ { AR5K_SLEEP2, 0x00000000 },
{ AR5K_BSS_IDM0, 0xffffffff },
{ AR5K_BSS_IDM1, 0x0000ffff },
{ AR5K_TXPC, 0x00000000 },
@@ -577,7 +569,8 @@ static const struct ath5k_ini ar5212_ini[] = {
{ AR5K_PROFCNT_RX, 0x00000000 },
{ AR5K_PROFCNT_RXCLR, 0x00000000 },
{ AR5K_PROFCNT_CYCLE, 0x00000000 },
- { 0x80fc, 0x00000088 },
+ { AR5K_QUIET_CTL1, 0x00000088 },
+ /* Initial rate duration table (32 entries )*/
{ AR5K_RATE_DUR(0), 0x00000000 },
{ AR5K_RATE_DUR(1), 0x0000008c },
{ AR5K_RATE_DUR(2), 0x000000e4 },
@@ -610,881 +603,625 @@ static const struct ath5k_ini ar5212_ini[] = {
{ AR5K_RATE_DUR(29), 0x0000007f },
{ AR5K_RATE_DUR(30), 0x000000a2 },
{ AR5K_RATE_DUR(31), 0x00000000 },
- { 0x8100, 0x00010002},
+ { AR5K_QUIET_CTL2, 0x00010002 },
{ AR5K_TSF_PARM, 0x00000001 },
- { 0x8108, 0x000000c0 },
+ { AR5K_QOS_NOACK, 0x000000c0 },
{ AR5K_PHY_ERR_FIL, 0x00000000 },
- { 0x8110, 0x00000168 },
- { 0x8114, 0x00000000 },
- /* Some kind of table
- * also notice ...03<-02<-01<-00) */
- { 0x87c0, 0x03020100 },
- { 0x87c4, 0x07060504 },
- { 0x87c8, 0x0b0a0908 },
- { 0x87cc, 0x0f0e0d0c },
- { 0x87d0, 0x13121110 },
- { 0x87d4, 0x17161514 },
- { 0x87d8, 0x1b1a1918 },
- { 0x87dc, 0x1f1e1d1c },
- /* loop ? */
- { 0x87e0, 0x03020100 },
- { 0x87e4, 0x07060504 },
- { 0x87e8, 0x0b0a0908 },
- { 0x87ec, 0x0f0e0d0c },
- { 0x87f0, 0x13121110 },
- { 0x87f4, 0x17161514 },
- { 0x87f8, 0x1b1a1918 },
- { 0x87fc, 0x1f1e1d1c },
- /* PHY registers */
- /*{ AR5K_PHY_AGC, 0x00000000 },*/
- { AR5K_PHY(3), 0xad848e19 },
- { AR5K_PHY(4), 0x7d28e000 },
- { AR5K_PHY_TIMING_3, 0x9c0a9f6b },
- { AR5K_PHY_ACT, 0x00000000 },
- /*{ AR5K_PHY(11), 0x00022ffe },*/
- /*{ AR5K_PHY(15), 0x00020100 },*/
- { AR5K_PHY(16), 0x206a017a },
- /*{ AR5K_PHY(19), 0x1284613c },*/
- { AR5K_PHY(21), 0x00000859 },
- { AR5K_PHY(64), 0x00000000 },
- { AR5K_PHY(65), 0x00000000 },
- { AR5K_PHY(66), 0x00000000 },
- { AR5K_PHY(67), 0x00800000 },
- { AR5K_PHY(68), 0x00000001 },
+ { AR5K_XRLAT_TX, 0x00000168 },
+ { AR5K_ACKSIFS, 0x00000000 },
+ /* Rate -> db table
+ * notice ...03<-02<-01<-00 ! */
+ { AR5K_RATE2DB(0), 0x03020100 },
+ { AR5K_RATE2DB(1), 0x07060504 },
+ { AR5K_RATE2DB(2), 0x0b0a0908 },
+ { AR5K_RATE2DB(3), 0x0f0e0d0c },
+ { AR5K_RATE2DB(4), 0x13121110 },
+ { AR5K_RATE2DB(5), 0x17161514 },
+ { AR5K_RATE2DB(6), 0x1b1a1918 },
+ { AR5K_RATE2DB(7), 0x1f1e1d1c },
+ /* Db -> Rate table */
+ { AR5K_DB2RATE(0), 0x03020100 },
+ { AR5K_DB2RATE(1), 0x07060504 },
+ { AR5K_DB2RATE(2), 0x0b0a0908 },
+ { AR5K_DB2RATE(3), 0x0f0e0d0c },
+ { AR5K_DB2RATE(4), 0x13121110 },
+ { AR5K_DB2RATE(5), 0x17161514 },
+ { AR5K_DB2RATE(6), 0x1b1a1918 },
+ { AR5K_DB2RATE(7), 0x1f1e1d1c },
+ /* PHY registers (Common settings
+ * for all chips/modes) */
+ { AR5K_PHY(3), 0xad848e19 },
+ { AR5K_PHY(4), 0x7d28e000 },
+ { AR5K_PHY_TIMING_3, 0x9c0a9f6b },
+ { AR5K_PHY_ACT, 0x00000000 },
+ { AR5K_PHY(16), 0x206a017a },
+ { AR5K_PHY(21), 0x00000859 },
+ { AR5K_PHY_BIN_MASK_1, 0x00000000 },
+ { AR5K_PHY_BIN_MASK_2, 0x00000000 },
+ { AR5K_PHY_BIN_MASK_3, 0x00000000 },
+ { AR5K_PHY_BIN_MASK_CTL, 0x00800000 },
+ { AR5K_PHY_ANT_CTL, 0x00000001 },
/*{ AR5K_PHY(71), 0x0000092a },*/ /* Old value */
- { AR5K_PHY(71), 0x00000c80 },
- { AR5K_PHY_IQ, 0x05100000 },
- { AR5K_PHY(74), 0x00000001 },
- { AR5K_PHY(75), 0x00000004 },
+ { AR5K_PHY_MAX_RX_LEN, 0x00000c80 },
+ { AR5K_PHY_IQ, 0x05100000 },
+ { AR5K_PHY_WARM_RESET, 0x00000001 },
+ { AR5K_PHY_CTL, 0x00000004 },
{ AR5K_PHY_TXPOWER_RATE1, 0x1e1f2022 },
{ AR5K_PHY_TXPOWER_RATE2, 0x0a0b0c0d },
{ AR5K_PHY_TXPOWER_RATE_MAX, 0x0000003f },
- /*{ AR5K_PHY(80), 0x00000004 },*/
- { AR5K_PHY(82), 0x9280b212 },
- { AR5K_PHY_RADAR, 0x5d50e188 },
+ { AR5K_PHY(82), 0x9280b212 },
+ { AR5K_PHY_RADAR, 0x5d50e188 },
/*{ AR5K_PHY(86), 0x000000ff },*/
- { AR5K_PHY(87), 0x004b6a8e },
- { AR5K_PHY(90), 0x000003ce },
- { AR5K_PHY(92), 0x192fb515 },
- /*{ AR5K_PHY(93), 0x00000000 },*/
- { AR5K_PHY(94), 0x00000001 },
- { AR5K_PHY(95), 0x00000000 },
+ { AR5K_PHY(87), 0x004b6a8e },
+ { AR5K_PHY_NFTHRES, 0x000003ce },
+ { AR5K_PHY_RESTART, 0x192fb515 },
+ { AR5K_PHY(94), 0x00000001 },
+ { AR5K_PHY_RFBUS_REQ, 0x00000000 },
/*{ AR5K_PHY(644), 0x0080a333 },*/ /* Old value */
/*{ AR5K_PHY(645), 0x00206c10 },*/ /* Old value */
- { AR5K_PHY(644), 0x00806333 },
- { AR5K_PHY(645), 0x00106c10 },
- { AR5K_PHY(646), 0x009c4060 },
- { AR5K_PHY(647), 0x1483800a },
- /* { AR5K_PHY(648), 0x018830c6 },*/ /* 2413/2425 */
- { AR5K_PHY(648), 0x01831061 },
- { AR5K_PHY(649), 0x00000400 },
+ { AR5K_PHY(644), 0x00806333 },
+ { AR5K_PHY(645), 0x00106c10 },
+ { AR5K_PHY(646), 0x009c4060 },
+ /* { AR5K_PHY(647), 0x1483800a }, */
+ /* { AR5K_PHY(648), 0x01831061 }, */ /* Old value */
+ { AR5K_PHY(648), 0x018830c6 },
+ { AR5K_PHY(649), 0x00000400 },
/*{ AR5K_PHY(650), 0x000001b5 },*/
- { AR5K_PHY(651), 0x00000000 },
+ { AR5K_PHY(651), 0x00000000 },
{ AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
{ AR5K_PHY_TXPOWER_RATE2, 0x20202020 },
/*{ AR5K_PHY(655), 0x13c889af },*/
- { AR5K_PHY(656), 0x38490a20 },
- { AR5K_PHY(657), 0x00007bb6 },
- { AR5K_PHY(658), 0x0fff3ffc },
- /*{ AR5K_PHY_CCKTXCTL, 0x00000000 },*/
+ { AR5K_PHY(656), 0x38490a20 },
+ { AR5K_PHY(657), 0x00007bb6 },
+ { AR5K_PHY(658), 0x0fff3ffc },
};
/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
- { AR5K_PHY(640),
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00000008, 0x00000008, 0x0000000b, 0x0000000e, 0x0000000e } },
- { AR5K_PHY(0),
- { 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(0),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ /* a/XR aTurbo b g (DYN) gTurbo */
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(1),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(2),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(3),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(4),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(5),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(6),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(7),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(8),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_QUEUE_DFS_LOCAL_IFS(9),
- { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+ { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
{ AR5K_DCU_GBL_IFS_SIFS,
- { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
+ { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
{ AR5K_DCU_GBL_IFS_SLOT,
- { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
+ { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
{ AR5K_DCU_GBL_IFS_EIFS,
- { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
+ { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
{ AR5K_DCU_GBL_IFS_MISC,
- { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
+ { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
{ AR5K_TIME_OUT,
- { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
+ { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
{ AR5K_PHY_TURBO,
- { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
+ { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
{ AR5K_PHY(8),
- { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
- { AR5K_PHY(9),
- { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
- { AR5K_PHY(17),
- { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
+ { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
+ { AR5K_PHY_RF_CTL2,
+ { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
+ { AR5K_PHY_SETTLING,
+ { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
{ AR5K_PHY_AGCCTL,
- { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
+ { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
{ AR5K_PHY_NF,
- { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
- { AR5K_PHY(26),
- { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
+ { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+ { AR5K_PHY_WEAK_OFDM_HIGH_THR,
+ { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
{ AR5K_PHY(70),
- { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
- { AR5K_PHY(73),
- { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
+ { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
+ { AR5K_PHY_OFDM_SELFCORR,
+ { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
{ 0xa230,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
};
/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
-/* New dump pending */
-static const struct ath5k_ini_mode ar5212_rf5111_ini_mode_end[] = {
- { AR5K_PHY(640), /* This one differs from ar5212_ini_mode_start ! */
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00000000, 0x00000000, 0x00000003, 0x00000006, 0x00000006 } },
+static const struct ath5k_ini_mode rf5111_ini_mode_end[] = {
{ AR5K_TXCFG,
- { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+ /* a/XR aTurbo b g (DYN) gTurbo */
+ { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
{ AR5K_USEC_5211,
- { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
- { AR5K_PHY(10),
- { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
- { AR5K_PHY(13),
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
- { AR5K_PHY(14),
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
- { AR5K_PHY(18),
- { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
- { AR5K_PHY(20),
- { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+ { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
+ { AR5K_PHY_RF_CTL3,
+ { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
+ { AR5K_PHY_RF_CTL4,
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { AR5K_PHY_PA_CTL,
+ { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { AR5K_PHY_GAIN,
+ { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
+ { AR5K_PHY_DESIRED_SIZE,
+ { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
+ { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
- { AR5K_PHY(27),
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
+ { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
+ { AR5K_PHY_WEAK_OFDM_LOW_THR,
+ { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
{ AR5K_PHY_RX_DELAY,
- { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
+ { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
+ { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
- { 0xa21c,
- { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
- { AR5K_DCU_FP,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY_AGC,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(11),
- { 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe } },
- { AR5K_PHY(15),
- { 0x00020100, 0x00020100, 0x00020100, 0x00020100, 0x00020100 } },
- { AR5K_PHY(19),
- { 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c } },
- { AR5K_PHY_PAPD_PROBE,
- { 0x00004883, 0x00004883, 0x00004883, 0x00004883, 0x00004883 } },
- { AR5K_PHY(80),
- { 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 } },
- { AR5K_PHY(86),
- { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
- { AR5K_PHY(93),
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY_SPENDING,
- { 0x00000018, 0x00000018, 0x00000018, 0x00000018, 0x00000018 } },
- { AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(642),
- { 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
- { 0xa228,
- { 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5 } },
- { 0xa23c,
- { 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
+ { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
+ { AR5K_PHY_CCK_RX_CTL_4,
+ { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf5111_ini_common_end[] = {
+ { AR5K_DCU_FP, 0x00000000 },
+ { AR5K_PHY_AGC, 0x00000000 },
+ { AR5K_PHY_ADC_CTL, 0x00022ffe },
+ { 0x983c, 0x00020100 },
+ { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
+ { AR5K_PHY_PAPD_PROBE, 0x00004883 },
+ { 0x9940, 0x00000004 },
+ { 0x9958, 0x000000ff },
+ { 0x9974, 0x00000000 },
+ { AR5K_PHY_SPENDING, 0x00000018 },
+ { AR5K_PHY_CCKTXCTL, 0x00000000 },
+ { AR5K_PHY_CCK_CROSSCORR, 0xd03e6788 },
+ { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
+ { 0xa23c, 0x13c889af },
};
/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
-/* XXX: No dumps for turbog yet, but i found settings from old values so it should be ok */
-static const struct ath5k_ini_mode ar5212_rf5112_ini_mode_end[] = {
+static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g (DYN) gTurbo */
- { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+ /* a/XR aTurbo b g (DYN) gTurbo */
+ { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
{ AR5K_USEC_5211,
- { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
- { AR5K_PHY(10),
- { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
- { AR5K_PHY(13),
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
- { AR5K_PHY(14),
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
- { AR5K_PHY(18),
- { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
- { AR5K_PHY(20),
- { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+ { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+ { AR5K_PHY_RF_CTL3,
+ { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+ { AR5K_PHY_RF_CTL4,
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { AR5K_PHY_PA_CTL,
+ { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { AR5K_PHY_GAIN,
+ { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
+ { AR5K_PHY_DESIRED_SIZE,
+ { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
{ AR5K_PHY_SIG,
- { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
+ { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
- { AR5K_PHY(27),
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
+ { AR5K_PHY_WEAK_OFDM_LOW_THR,
+ { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
+ { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
- { AR5K_PHY(642),
- { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
+ { AR5K_PHY_CCK_CROSSCORR,
+ { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
- { 0xa21c,
- { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
- { AR5K_DCU_FP,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY_AGC,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(11),
- { 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe } },
- { AR5K_PHY(15),
- { 0x00020100, 0x00020100, 0x00020100, 0x00020100, 0x00020100 } },
- { AR5K_PHY(19),
- { 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c } },
- { AR5K_PHY_PAPD_PROBE,
- { 0x00004882, 0x00004882, 0x00004882, 0x00004882, 0x00004882 } },
- { AR5K_PHY(80),
- { 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 } },
- { AR5K_PHY(86),
- { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
- { AR5K_PHY(93),
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa228,
- { 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5 } },
- { 0xa23c,
- { 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
+ { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
+ { AR5K_PHY_CCK_RX_CTL_4,
+ { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf5112_ini_common_end[] = {
+ { AR5K_DCU_FP, 0x00000000 },
+ { AR5K_PHY_AGC, 0x00000000 },
+ { AR5K_PHY_ADC_CTL, 0x00022ffe },
+ { 0x983c, 0x00020100 },
+ { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
+ { AR5K_PHY_PAPD_PROBE, 0x00004882 },
+ { 0x9940, 0x00000004 },
+ { 0x9958, 0x000000ff },
+ { 0x9974, 0x00000000 },
+ { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
+ { 0xa23c, 0x13c889af },
};
/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
-/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
- * minor tweaking based on dumps from other chips */
static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* a/XR aTurbo b g gTurbo */
- { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+ /* a/XR aTurbo b g (DYN) gTurbo */
+ { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
{ AR5K_USEC_5211,
- { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
- { AR5K_PHY(10),
- { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
- { AR5K_PHY(13),
- { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
- { AR5K_PHY(14),
- { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
- { AR5K_PHY(18),
- { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
- { AR5K_PHY(20),
- { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
+ { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+ { AR5K_PHY_RF_CTL3,
+ { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+ { AR5K_PHY_RF_CTL4,
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { AR5K_PHY_PA_CTL,
+ { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { AR5K_PHY_GAIN,
+ { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
+ { AR5K_PHY_DESIRED_SIZE,
+ { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
{ AR5K_PHY_SIG,
- { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+ { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
- { AR5K_PHY(27),
- { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+ { AR5K_PHY_WEAK_OFDM_LOW_THR,
+ { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+ { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(642),
- { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { AR5K_PHY_CCK_CROSSCORR,
+ { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
- { 0xa21c,
- { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+ { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
+ { AR5K_PHY_CCK_RX_CTL_4,
+ { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
{ 0xa300,
- { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
+ { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
{ 0xa304,
- { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
+ { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
{ 0xa308,
- { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
+ { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
{ 0xa30c,
- { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
+ { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
{ 0xa310,
- { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
+ { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
{ 0xa314,
- { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
+ { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
{ 0xa318,
- { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
+ { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
{ 0xa31c,
- { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
+ { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
{ 0xa320,
- { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
+ { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
{ 0xa324,
- { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
+ { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
{ 0xa328,
- { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
+ { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
{ 0xa32c,
- { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
+ { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
{ 0xa330,
- { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
+ { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
{ 0xa334,
- { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
- { AR5K_DCU_FP,
- { 0x000003e0, 0x000003e0, 0x000003e0, 0x000003e0, 0x000003e0 } },
- { 0x4068,
- { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
- { 0x8060,
- { 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f } },
- { 0x809c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x80a0,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8118,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x811c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8120,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8124,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8128,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x812c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8130,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8134,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8138,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x813c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8140,
- { 0x800003f9, 0x800003f9, 0x800003f9, 0x800003f9, 0x800003f9 } },
- { 0x8144,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY_AGC,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(11),
- { 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000 } },
- { AR5K_PHY(15),
- { 0x00200400, 0x00200400, 0x00200400, 0x00200400, 0x00200400 } },
- { AR5K_PHY(19),
- { 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c } },
- { AR5K_PHY_SCR,
- { 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f } },
- { AR5K_PHY_SLMT,
- { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
- { AR5K_PHY_SCAL,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
- { AR5K_PHY(86),
- { 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff } },
- { AR5K_PHY(96),
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(97),
- { 0x02800000, 0x02800000, 0x02800000, 0x02800000, 0x02800000 } },
- { AR5K_PHY(104),
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(120),
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(121),
- { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa } },
- { AR5K_PHY(122),
- { 0x3c466478, 0x3c466478, 0x3c466478, 0x3c466478, 0x3c466478 } },
- { AR5K_PHY(123),
- { 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa } },
- { AR5K_PHY_SCLOCK,
- { 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c } },
- { AR5K_PHY_SDELAY,
- { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
- { AR5K_PHY_SPENDING,
- { 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000014 } },
- { 0xa228,
- { 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5 } },
- { 0xa23c,
- { 0x93c889af, 0x93c889af, 0x93c889af, 0x93c889af, 0x93c889af } },
- { 0xa24c,
- { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
- { 0xa250,
- { 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000 } },
- { 0xa254,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa258,
- { 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380 } },
- { 0xa25c,
- { 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01 } },
- { 0xa260,
- { 0x5f690f01, 0x5f690f01, 0x5f690f01, 0x5f690f01, 0x5f690f01 } },
- { 0xa264,
- { 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11 } },
- { 0xa268,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa26c,
- { 0x0c30c16a, 0x0c30c16a, 0x0c30c16a, 0x0c30c16a, 0x0c30c16a } },
- { 0xa270,
- { 0x00820820, 0x00820820, 0x00820820, 0x00820820, 0x00820820 } },
- { 0xa274,
- { 0x081b7caa, 0x081b7caa, 0x081b7caa, 0x081b7caa, 0x081b7caa } },
- { 0xa278,
- { 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce } },
- { 0xa27c,
- { 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce } },
- { 0xa338,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa33c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa340,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa344,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa348,
- { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
- { 0xa34c,
- { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
- { 0xa350,
- { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
- { 0xa354,
- { 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff } },
- { 0xa358,
- { 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f } },
- { 0xa35c,
- { 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f } },
- { 0xa360,
- { 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207 } },
- { 0xa364,
- { 0x17601685, 0x17601685, 0x17601685, 0x17601685, 0x17601685 } },
- { 0xa368,
- { 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104 } },
- { 0xa36c,
- { 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03 } },
- { 0xa370,
- { 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883 } },
- { 0xa374,
- { 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803 } },
- { 0xa378,
- { 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682 } },
- { 0xa37c,
- { 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482 } },
- { 0xa380,
- { 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba } },
- { 0xa384,
- { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } },
+ { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
+};
+
+static const struct ath5k_ini rf5413_ini_common_end[] = {
+ { AR5K_DCU_FP, 0x000003e0 },
+ { AR5K_5414_CBCFG, 0x00000010 },
+ { AR5K_SEQ_MASK, 0x0000000f },
+ { 0x809c, 0x00000000 },
+ { 0x80a0, 0x00000000 },
+ { AR5K_MIC_QOS_CTL, 0x00000000 },
+ { AR5K_MIC_QOS_SEL, 0x00000000 },
+ { AR5K_MISC_MODE, 0x00000000 },
+ { AR5K_OFDM_FIL_CNT, 0x00000000 },
+ { AR5K_CCK_FIL_CNT, 0x00000000 },
+ { AR5K_PHYERR_CNT1, 0x00000000 },
+ { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+ { AR5K_PHYERR_CNT2, 0x00000000 },
+ { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+ { AR5K_TSF_THRES, 0x00000000 },
+ { 0x8140, 0x800003f9 },
+ { 0x8144, 0x00000000 },
+ { AR5K_PHY_AGC, 0x00000000 },
+ { AR5K_PHY_ADC_CTL, 0x0000a000 },
+ { 0x983c, 0x00200400 },
+ { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+ { AR5K_PHY_SCR, 0x0000001f },
+ { AR5K_PHY_SLMT, 0x00000080 },
+ { AR5K_PHY_SCAL, 0x0000000e },
+ { 0x9958, 0x00081fff },
+ { AR5K_PHY_TIMING_7, 0x00000000 },
+ { AR5K_PHY_TIMING_8, 0x02800000 },
+ { AR5K_PHY_TIMING_11, 0x00000000 },
+ { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+ { 0x99e4, 0xaaaaaaaa },
+ { 0x99e8, 0x3c466478 },
+ { 0x99ec, 0x000000aa },
+ { AR5K_PHY_SCLOCK, 0x0000000c },
+ { AR5K_PHY_SDELAY, 0x000000ff },
+ { AR5K_PHY_SPENDING, 0x00000014 },
+ { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
+ { 0xa23c, 0x93c889af },
+ { AR5K_PHY_FAST_ADC, 0x00000001 },
+ { 0xa250, 0x0000a000 },
+ { AR5K_PHY_BLUETOOTH, 0x00000000 },
+ { AR5K_PHY_TPC_RG1, 0x0cc75380 },
+ { 0xa25c, 0x0f0f0f01 },
+ { 0xa260, 0x5f690f01 },
+ { 0xa264, 0x00418a11 },
+ { 0xa268, 0x00000000 },
+ { AR5K_PHY_TPC_RG5, 0x0c30c16a },
+ { 0xa270, 0x00820820 },
+ { 0xa274, 0x081b7caa },
+ { 0xa278, 0x1ce739ce },
+ { 0xa27c, 0x051701ce },
+ { 0xa338, 0x00000000 },
+ { 0xa33c, 0x00000000 },
+ { 0xa340, 0x00000000 },
+ { 0xa344, 0x00000000 },
+ { 0xa348, 0x3fffffff },
+ { 0xa34c, 0x3fffffff },
+ { 0xa350, 0x3fffffff },
+ { 0xa354, 0x0003ffff },
+ { 0xa358, 0x79a8aa1f },
+ { 0xa35c, 0x066c420f },
+ { 0xa360, 0x0f282207 },
+ { 0xa364, 0x17601685 },
+ { 0xa368, 0x1f801104 },
+ { 0xa36c, 0x37a00c03 },
+ { 0xa370, 0x3fc40883 },
+ { 0xa374, 0x57c00803 },
+ { 0xa378, 0x5fd80682 },
+ { 0xa37c, 0x7fe00482 },
+ { 0xa380, 0x7f3c7bba },
+ { 0xa384, 0xf3307ff0 },
};
/* Initial mode-specific settings for RF2413/2414 (Written after ar5212_ini) */
-/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
- * minor tweaking based on dumps from other chips */
+/* XXX: a mode ? */
static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* b g gTurbo */
- { 0x00000015, 0x00000015, 0x00000015 } },
+ /* a/XR aTurbo b g (DYN) gTurbo */
+ { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
{ AR5K_USEC_5211,
- { 0x04e01395, 0x12e013ab, 0x098813cf } },
- { AR5K_PHY(10),
- { 0x05020000, 0x0a020001, 0x0a020001 } },
- { AR5K_PHY(13),
- { 0x00000e00, 0x00000e00, 0x00000e00 } },
- { AR5K_PHY(14),
- { 0x0000000a, 0x0000000a, 0x0000000a } },
- { AR5K_PHY(18),
- { 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
- { AR5K_PHY(20),
- { 0x0de8b0da, 0x0c98b0da, 0x0c98b0da } },
+ { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+ { AR5K_PHY_RF_CTL3,
+ { 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } },
+ { AR5K_PHY_RF_CTL4,
+ { 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } },
+ { AR5K_PHY_PA_CTL,
+ { 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } },
+ { AR5K_PHY_GAIN,
+ { 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
+ { AR5K_PHY_DESIRED_SIZE,
+ { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } },
{ AR5K_PHY_SIG,
- { 0x7ee80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+ { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3137665e, 0x3139605e, 0x3139605e } },
- { AR5K_PHY(27),
- { 0x050cb081, 0x050cb081, 0x050cb081 } },
+ { 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } },
+ { AR5K_PHY_WEAK_OFDM_LOW_THR,
+ { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x0000044c, 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+ { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(642),
- { 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { AR5K_PHY_CCK_CROSSCORR,
+ { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x0042c140, 0x0042c140, 0x0042c140 } },
- { 0xa21c,
- { 0x1863800a, 0x1883800a, 0x1883800a } },
- { AR5K_DCU_FP,
- { 0x000003e0, 0x000003e0, 0x000003e0 } },
- { 0x8060,
- { 0x0000000f, 0x0000000f, 0x0000000f } },
- { 0x8118,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x811c,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8120,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8124,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8128,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x812c,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8130,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8134,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8138,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x813c,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0x8140,
- { 0x800000a8, 0x800000a8, 0x800000a8 } },
- { 0x8144,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY_AGC,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(11),
- { 0x0000a000, 0x0000a000, 0x0000a000 } },
- { AR5K_PHY(15),
- { 0x00200400, 0x00200400, 0x00200400 } },
- { AR5K_PHY(19),
- { 0x1284233c, 0x1284233c, 0x1284233c } },
- { AR5K_PHY_SCR,
- { 0x0000001f, 0x0000001f, 0x0000001f } },
- { AR5K_PHY_SLMT,
- { 0x00000080, 0x00000080, 0x00000080 } },
- { AR5K_PHY_SCAL,
- { 0x0000000e, 0x0000000e, 0x0000000e } },
- { AR5K_PHY(86),
- { 0x000000ff, 0x000000ff, 0x000000ff } },
- { AR5K_PHY(96),
- { 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(97),
- { 0x02800000, 0x02800000, 0x02800000 } },
- { AR5K_PHY(104),
- { 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(120),
- { 0x00000000, 0x00000000, 0x00000000 } },
- { AR5K_PHY(121),
- { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa } },
- { AR5K_PHY(122),
- { 0x3c466478, 0x3c466478, 0x3c466478 } },
- { AR5K_PHY(123),
- { 0x000000aa, 0x000000aa, 0x000000aa } },
- { AR5K_PHY_SCLOCK,
- { 0x0000000c, 0x0000000c, 0x0000000c } },
- { AR5K_PHY_SDELAY,
- { 0x000000ff, 0x000000ff, 0x000000ff } },
- { AR5K_PHY_SPENDING,
- { 0x00000014, 0x00000014, 0x00000014 } },
- { 0xa228,
- { 0x000009b5, 0x000009b5, 0x000009b5 } },
- { 0xa23c,
- { 0x93c889af, 0x93c889af, 0x93c889af } },
- { 0xa24c,
- { 0x00000001, 0x00000001, 0x00000001 } },
- { 0xa250,
- { 0x0000a000, 0x0000a000, 0x0000a000 } },
- { 0xa254,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa258,
- { 0x0cc75380, 0x0cc75380, 0x0cc75380 } },
- { 0xa25c,
- { 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01 } },
- { 0xa260,
- { 0x5f690f01, 0x5f690f01, 0x5f690f01 } },
- { 0xa264,
- { 0x00418a11, 0x00418a11, 0x00418a11 } },
- { 0xa268,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa26c,
- { 0x0c30c16a, 0x0c30c16a, 0x0c30c16a } },
- { 0xa270,
- { 0x00820820, 0x00820820, 0x00820820 } },
- { 0xa274,
- { 0x001b7caa, 0x001b7caa, 0x001b7caa } },
- { 0xa278,
- { 0x1ce739ce, 0x1ce739ce, 0x1ce739ce } },
- { 0xa27c,
- { 0x051701ce, 0x051701ce, 0x051701ce } },
- { 0xa300,
- { 0x18010000, 0x18010000, 0x18010000 } },
- { 0xa304,
- { 0x30032602, 0x30032602, 0x30032602 } },
- { 0xa308,
- { 0x48073e06, 0x48073e06, 0x48073e06 } },
- { 0xa30c,
- { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
- { 0xa310,
- { 0x641a600f, 0x641a600f, 0x641a600f } },
- { 0xa314,
- { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
- { 0xa318,
- { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
- { 0xa31c,
- { 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
- { 0xa320,
- { 0x9d4f970f, 0x9d4f970f, 0x9d4f970f } },
- { 0xa324,
- { 0xa5cfa18f, 0xa5cfa18f, 0xa5cfa18f } },
- { 0xa328,
- { 0xb55faf1f, 0xb55faf1f, 0xb55faf1f } },
- { 0xa32c,
- { 0xbddfb99f, 0xbddfb99f, 0xbddfb99f } },
- { 0xa330,
- { 0xcd7fc73f, 0xcd7fc73f, 0xcd7fc73f } },
- { 0xa334,
- { 0xd5ffd1bf, 0xd5ffd1bf, 0xd5ffd1bf } },
- { 0xa338,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa33c,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa340,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa344,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 0xa348,
- { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
- { 0xa34c,
- { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
- { 0xa350,
- { 0x3fffffff, 0x3fffffff, 0x3fffffff } },
- { 0xa354,
- { 0x0003ffff, 0x0003ffff, 0x0003ffff } },
- { 0xa358,
- { 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f } },
- { 0xa35c,
- { 0x066c420f, 0x066c420f, 0x066c420f } },
- { 0xa360,
- { 0x0f282207, 0x0f282207, 0x0f282207 } },
- { 0xa364,
- { 0x17601685, 0x17601685, 0x17601685 } },
- { 0xa368,
- { 0x1f801104, 0x1f801104, 0x1f801104 } },
- { 0xa36c,
- { 0x37a00c03, 0x37a00c03, 0x37a00c03 } },
- { 0xa370,
- { 0x3fc40883, 0x3fc40883, 0x3fc40883 } },
- { 0xa374,
- { 0x57c00803, 0x57c00803, 0x57c00803 } },
- { 0xa378,
- { 0x5fd80682, 0x5fd80682, 0x5fd80682 } },
- { 0xa37c,
- { 0x7fe00482, 0x7fe00482, 0x7fe00482 } },
- { 0xa380,
- { 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba } },
- { 0xa384,
- { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } },
+ { 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } },
+ { AR5K_PHY_CCK_RX_CTL_4,
+ { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf2413_ini_common_end[] = {
+ { AR5K_DCU_FP, 0x000003e0 },
+ { AR5K_SEQ_MASK, 0x0000000f },
+ { AR5K_MIC_QOS_CTL, 0x00000000 },
+ { AR5K_MIC_QOS_SEL, 0x00000000 },
+ { AR5K_MISC_MODE, 0x00000000 },
+ { AR5K_OFDM_FIL_CNT, 0x00000000 },
+ { AR5K_CCK_FIL_CNT, 0x00000000 },
+ { AR5K_PHYERR_CNT1, 0x00000000 },
+ { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+ { AR5K_PHYERR_CNT2, 0x00000000 },
+ { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+ { AR5K_TSF_THRES, 0x00000000 },
+ { 0x8140, 0x800000a8 },
+ { 0x8144, 0x00000000 },
+ { AR5K_PHY_AGC, 0x00000000 },
+ { AR5K_PHY_ADC_CTL, 0x0000a000 },
+ { 0x983c, 0x00200400 },
+ { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+ { AR5K_PHY_SCR, 0x0000001f },
+ { AR5K_PHY_SLMT, 0x00000080 },
+ { AR5K_PHY_SCAL, 0x0000000e },
+ { 0x9958, 0x000000ff },
+ { AR5K_PHY_TIMING_7, 0x00000000 },
+ { AR5K_PHY_TIMING_8, 0x02800000 },
+ { AR5K_PHY_TIMING_11, 0x00000000 },
+ { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+ { 0x99e4, 0xaaaaaaaa },
+ { 0x99e8, 0x3c466478 },
+ { 0x99ec, 0x000000aa },
+ { AR5K_PHY_SCLOCK, 0x0000000c },
+ { AR5K_PHY_SDELAY, 0x000000ff },
+ { AR5K_PHY_SPENDING, 0x00000014 },
+ { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
+ { 0xa23c, 0x93c889af },
+ { AR5K_PHY_FAST_ADC, 0x00000001 },
+ { 0xa250, 0x0000a000 },
+ { AR5K_PHY_BLUETOOTH, 0x00000000 },
+ { AR5K_PHY_TPC_RG1, 0x0cc75380 },
+ { 0xa25c, 0x0f0f0f01 },
+ { 0xa260, 0x5f690f01 },
+ { 0xa264, 0x00418a11 },
+ { 0xa268, 0x00000000 },
+ { AR5K_PHY_TPC_RG5, 0x0c30c16a },
+ { 0xa270, 0x00820820 },
+ { 0xa274, 0x001b7caa },
+ { 0xa278, 0x1ce739ce },
+ { 0xa27c, 0x051701ce },
+ { 0xa300, 0x18010000 },
+ { 0xa304, 0x30032602 },
+ { 0xa308, 0x48073e06 },
+ { 0xa30c, 0x560b4c0a },
+ { 0xa310, 0x641a600f },
+ { 0xa314, 0x784f6e1b },
+ { 0xa318, 0x868f7c5a },
+ { 0xa31c, 0x8ecf865b },
+ { 0xa320, 0x9d4f970f },
+ { 0xa324, 0xa5cfa18f },
+ { 0xa328, 0xb55faf1f },
+ { 0xa32c, 0xbddfb99f },
+ { 0xa330, 0xcd7fc73f },
+ { 0xa334, 0xd5ffd1bf },
+ { 0xa338, 0x00000000 },
+ { 0xa33c, 0x00000000 },
+ { 0xa340, 0x00000000 },
+ { 0xa344, 0x00000000 },
+ { 0xa348, 0x3fffffff },
+ { 0xa34c, 0x3fffffff },
+ { 0xa350, 0x3fffffff },
+ { 0xa354, 0x0003ffff },
+ { 0xa358, 0x79a8aa1f },
+ { 0xa35c, 0x066c420f },
+ { 0xa360, 0x0f282207 },
+ { 0xa364, 0x17601685 },
+ { 0xa368, 0x1f801104 },
+ { 0xa36c, 0x37a00c03 },
+ { 0xa370, 0x3fc40883 },
+ { 0xa374, 0x57c00803 },
+ { 0xa378, 0x5fd80682 },
+ { 0xa37c, 0x7fe00482 },
+ { 0xa380, 0x7f3c7bba },
+ { 0xa384, 0xf3307ff0 },
};
/* Initial mode-specific settings for RF2425 (Written after ar5212_ini) */
-/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
- * minor tweaking based on dumps from other chips */
+/* XXX: a mode ? */
static const struct ath5k_ini_mode rf2425_ini_mode_end[] = {
{ AR5K_TXCFG,
- /* g gTurbo */
- { 0x00000015, 0x00000015 } },
+ /* a/XR aTurbo b g (DYN) gTurbo */
+ { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
{ AR5K_USEC_5211,
- { 0x12e013ab, 0x098813cf } },
+ { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
{ AR5K_PHY_TURBO,
- { 0x00000000, 0x00000003 } },
- { AR5K_PHY(10),
- { 0x0a020001, 0x0a020001 } },
- { AR5K_PHY(13),
- { 0x00000e0e, 0x00000e0e } },
- { AR5K_PHY(14),
- { 0x0000000b, 0x0000000b } },
- { AR5K_PHY(17),
- { 0x13721422, 0x13721422 } },
- { AR5K_PHY(18),
- { 0x00199a65, 0x00199a65 } },
- { AR5K_PHY(20),
- { 0x0c98b0da, 0x0c98b0da } },
+ { 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } },
+ { AR5K_PHY_RF_CTL3,
+ { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+ { AR5K_PHY_RF_CTL4,
+ { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+ { AR5K_PHY_PA_CTL,
+ { 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } },
+ { AR5K_PHY_SETTLING,
+ { 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } },
+ { AR5K_PHY_GAIN,
+ { 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } },
+ { AR5K_PHY_DESIRED_SIZE,
+ { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
{ AR5K_PHY_SIG,
- { 0x7ec80d2e, 0x7ec80d2e } },
+ { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
{ AR5K_PHY_AGCCOARSE,
- { 0x3139605e, 0x3139605e } },
- { AR5K_PHY(27),
- { 0x050cb081, 0x050cb081 } },
+ { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+ { AR5K_PHY_WEAK_OFDM_LOW_THR,
+ { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
{ AR5K_PHY_RX_DELAY,
- { 0x00000898, 0x000007d0 } },
+ { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
{ AR5K_PHY_FRAME_CTL_5211,
- { 0xf7b81000, 0xf7b81000 } },
+ { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
{ AR5K_PHY_CCKTXCTL,
- { 0x00000000, 0x00000000 } },
- { AR5K_PHY(642),
- { 0xd03e6788, 0xd03e6788 } },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { AR5K_PHY_CCK_CROSSCORR,
+ { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
{ AR5K_PHY_GAIN_2GHZ,
- { 0x0052c140, 0x0052c140 } },
- { 0xa21c,
- { 0x1883800a, 0x1883800a } },
+ { 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } },
+ { AR5K_PHY_CCK_RX_CTL_4,
+ { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
{ 0xa324,
- { 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa328,
- { 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa32c,
- { 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa330,
- { 0xa7cfa7cf, 0xa7cfa7cf } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
{ 0xa334,
- { 0xa7cfa7cf, 0xa7cfa7cf } },
- { AR5K_DCU_FP,
- { 0x000003e0, 0x000003e0 } },
- { 0x8060,
- { 0x0000000f, 0x0000000f } },
- { 0x809c,
- { 0x00000000, 0x00000000 } },
- { 0x80a0,
- { 0x00000000, 0x00000000 } },
- { 0x8118,
- { 0x00000000, 0x00000000 } },
- { 0x811c,
- { 0x00000000, 0x00000000 } },
- { 0x8120,
- { 0x00000000, 0x00000000 } },
- { 0x8124,
- { 0x00000000, 0x00000000 } },
- { 0x8128,
- { 0x00000000, 0x00000000 } },
- { 0x812c,
- { 0x00000000, 0x00000000 } },
- { 0x8130,
- { 0x00000000, 0x00000000 } },
- { 0x8134,
- { 0x00000000, 0x00000000 } },
- { 0x8138,
- { 0x00000000, 0x00000000 } },
- { 0x813c,
- { 0x00000000, 0x00000000 } },
- { 0x8140,
- { 0x800003f9, 0x800003f9 } },
- { 0x8144,
- { 0x00000000, 0x00000000 } },
- { AR5K_PHY_AGC,
- { 0x00000000, 0x00000000 } },
- { AR5K_PHY(11),
- { 0x0000a000, 0x0000a000 } },
- { AR5K_PHY(15),
- { 0x00200400, 0x00200400 } },
- { AR5K_PHY(19),
- { 0x1284233c, 0x1284233c } },
- { AR5K_PHY_SCR,
- { 0x0000001f, 0x0000001f } },
- { AR5K_PHY_SLMT,
- { 0x00000080, 0x00000080 } },
- { AR5K_PHY_SCAL,
- { 0x0000000e, 0x0000000e } },
- { AR5K_PHY(86),
- { 0x00081fff, 0x00081fff } },
- { AR5K_PHY(96),
- { 0x00000000, 0x00000000 } },
- { AR5K_PHY(97),
- { 0x02800000, 0x02800000 } },
- { AR5K_PHY(104),
- { 0x00000000, 0x00000000 } },
- { AR5K_PHY(119),
- { 0xfebadbe8, 0xfebadbe8 } },
- { AR5K_PHY(120),
- { 0x00000000, 0x00000000 } },
- { AR5K_PHY(121),
- { 0xaaaaaaaa, 0xaaaaaaaa } },
- { AR5K_PHY(122),
- { 0x3c466478, 0x3c466478 } },
- { AR5K_PHY(123),
- { 0x000000aa, 0x000000aa } },
- { AR5K_PHY_SCLOCK,
- { 0x0000000c, 0x0000000c } },
- { AR5K_PHY_SDELAY,
- { 0x000000ff, 0x000000ff } },
- { AR5K_PHY_SPENDING,
- { 0x00000014, 0x00000014 } },
- { 0xa228,
- { 0x000009b5, 0x000009b5 } },
- { AR5K_PHY_TXPOWER_RATE3,
- { 0x20202020, 0x20202020 } },
- { AR5K_PHY_TXPOWER_RATE4,
- { 0x20202020, 0x20202020 } },
- { 0xa23c,
- { 0x93c889af, 0x93c889af } },
- { 0xa24c,
- { 0x00000001, 0x00000001 } },
- { 0xa250,
- { 0x0000a000, 0x0000a000 } },
- { 0xa254,
- { 0x00000000, 0x00000000 } },
- { 0xa258,
- { 0x0cc75380, 0x0cc75380 } },
- { 0xa25c,
- { 0x0f0f0f01, 0x0f0f0f01 } },
- { 0xa260,
- { 0x5f690f01, 0x5f690f01 } },
- { 0xa264,
- { 0x00418a11, 0x00418a11 } },
- { 0xa268,
- { 0x00000000, 0x00000000 } },
- { 0xa26c,
- { 0x0c30c166, 0x0c30c166 } },
- { 0xa270,
- { 0x00820820, 0x00820820 } },
- { 0xa274,
- { 0x081a3caa, 0x081a3caa } },
- { 0xa278,
- { 0x1ce739ce, 0x1ce739ce } },
- { 0xa27c,
- { 0x051701ce, 0x051701ce } },
- { 0xa300,
- { 0x16010000, 0x16010000 } },
- { 0xa304,
- { 0x2c032402, 0x2c032402 } },
- { 0xa308,
- { 0x48433e42, 0x48433e42 } },
- { 0xa30c,
- { 0x5a0f500b, 0x5a0f500b } },
- { 0xa310,
- { 0x6c4b624a, 0x6c4b624a } },
- { 0xa314,
- { 0x7e8b748a, 0x7e8b748a } },
- { 0xa318,
- { 0x96cf8ccb, 0x96cf8ccb } },
- { 0xa31c,
- { 0xa34f9d0f, 0xa34f9d0f } },
- { 0xa320,
- { 0xa7cfa58f, 0xa7cfa58f } },
- { 0xa348,
- { 0x3fffffff, 0x3fffffff } },
- { 0xa34c,
- { 0x3fffffff, 0x3fffffff } },
- { 0xa350,
- { 0x3fffffff, 0x3fffffff } },
- { 0xa354,
- { 0x0003ffff, 0x0003ffff } },
- { 0xa358,
- { 0x79a8aa1f, 0x79a8aa1f } },
- { 0xa35c,
- { 0x066c420f, 0x066c420f } },
- { 0xa360,
- { 0x0f282207, 0x0f282207 } },
- { 0xa364,
- { 0x17601685, 0x17601685 } },
- { 0xa368,
- { 0x1f801104, 0x1f801104 } },
- { 0xa36c,
- { 0x37a00c03, 0x37a00c03 } },
- { 0xa370,
- { 0x3fc40883, 0x3fc40883 } },
- { 0xa374,
- { 0x57c00803, 0x57c00803 } },
- { 0xa378,
- { 0x5fd80682, 0x5fd80682 } },
- { 0xa37c,
- { 0x7fe00482, 0x7fe00482 } },
- { 0xa380,
- { 0x7f3c7bba, 0x7f3c7bba } },
- { 0xa384,
- { 0xf3307ff0, 0xf3307ff0 } },
+ { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+};
+
+static const struct ath5k_ini rf2425_ini_common_end[] = {
+ { AR5K_DCU_FP, 0x000003e0 },
+ { AR5K_SEQ_MASK, 0x0000000f },
+ { 0x809c, 0x00000000 },
+ { 0x80a0, 0x00000000 },
+ { AR5K_MIC_QOS_CTL, 0x00000000 },
+ { AR5K_MIC_QOS_SEL, 0x00000000 },
+ { AR5K_MISC_MODE, 0x00000000 },
+ { AR5K_OFDM_FIL_CNT, 0x00000000 },
+ { AR5K_CCK_FIL_CNT, 0x00000000 },
+ { AR5K_PHYERR_CNT1, 0x00000000 },
+ { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+ { AR5K_PHYERR_CNT2, 0x00000000 },
+ { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+ { AR5K_TSF_THRES, 0x00000000 },
+ { 0x8140, 0x800003f9 },
+ { 0x8144, 0x00000000 },
+ { AR5K_PHY_AGC, 0x00000000 },
+ { AR5K_PHY_ADC_CTL, 0x0000a000 },
+ { 0x983c, 0x00200400 },
+ { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+ { AR5K_PHY_SCR, 0x0000001f },
+ { AR5K_PHY_SLMT, 0x00000080 },
+ { AR5K_PHY_SCAL, 0x0000000e },
+ { 0x9958, 0x00081fff },
+ { AR5K_PHY_TIMING_7, 0x00000000 },
+ { AR5K_PHY_TIMING_8, 0x02800000 },
+ { AR5K_PHY_TIMING_11, 0x00000000 },
+ { 0x99dc, 0xfebadbe8 },
+ { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+ { 0x99e4, 0xaaaaaaaa },
+ { 0x99e8, 0x3c466478 },
+ { 0x99ec, 0x000000aa },
+ { AR5K_PHY_SCLOCK, 0x0000000c },
+ { AR5K_PHY_SDELAY, 0x000000ff },
+ { AR5K_PHY_SPENDING, 0x00000014 },
+ { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
+ { AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
+ { AR5K_PHY_TXPOWER_RATE4, 0x20202020 },
+ { 0xa23c, 0x93c889af },
+ { AR5K_PHY_FAST_ADC, 0x00000001 },
+ { 0xa250, 0x0000a000 },
+ { AR5K_PHY_BLUETOOTH, 0x00000000 },
+ { AR5K_PHY_TPC_RG1, 0x0cc75380 },
+ { 0xa25c, 0x0f0f0f01 },
+ { 0xa260, 0x5f690f01 },
+ { 0xa264, 0x00418a11 },
+ { 0xa268, 0x00000000 },
+ { AR5K_PHY_TPC_RG5, 0x0c30c166 },
+ { 0xa270, 0x00820820 },
+ { 0xa274, 0x081a3caa },
+ { 0xa278, 0x1ce739ce },
+ { 0xa27c, 0x051701ce },
+ { 0xa300, 0x16010000 },
+ { 0xa304, 0x2c032402 },
+ { 0xa308, 0x48433e42 },
+ { 0xa30c, 0x5a0f500b },
+ { 0xa310, 0x6c4b624a },
+ { 0xa314, 0x7e8b748a },
+ { 0xa318, 0x96cf8ccb },
+ { 0xa31c, 0xa34f9d0f },
+ { 0xa320, 0xa7cfa58f },
+ { 0xa348, 0x3fffffff },
+ { 0xa34c, 0x3fffffff },
+ { 0xa350, 0x3fffffff },
+ { 0xa354, 0x0003ffff },
+ { 0xa358, 0x79a8aa1f },
+ { 0xa35c, 0x066c420f },
+ { 0xa360, 0x0f282207 },
+ { 0xa364, 0x17601685 },
+ { 0xa368, 0x1f801104 },
+ { 0xa36c, 0x37a00c03 },
+ { 0xa370, 0x3fc40883 },
+ { 0xa374, 0x57c00803 },
+ { 0xa378, 0x5fd80682 },
+ { 0xa37c, 0x7fe00482 },
+ { 0xa380, 0x7f3c7bba },
+ { 0xa384, 0xf3307ff0 },
};
/*
@@ -1560,7 +1297,7 @@ static const struct ath5k_ini rf5111_ini_bbgain[] = {
{ AR5K_BB_GAIN(63), 0x00000016 },
};
-/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414) */
+/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414+) */
static const struct ath5k_ini rf5112_ini_bbgain[] = {
{ AR5K_BB_GAIN(0), 0x00000000 },
{ AR5K_BB_GAIN(1), 0x00000001 },
@@ -1691,87 +1428,97 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
/*
* Write initial settings common for all modes
*/
- ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini),
- ar5212_ini, change_channel);
+ ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start),
+ ar5212_ini_common_start, change_channel);
/* Second set of mode-specific settings */
- if (ah->ah_radio == AR5K_RF5111) {
+ switch (ah->ah_radio) {
+ case AR5K_RF5111:
ath5k_hw_ini_mode_registers(ah,
- ARRAY_SIZE(ar5212_rf5111_ini_mode_end),
- ar5212_rf5111_ini_mode_end, mode);
+ ARRAY_SIZE(rf5111_ini_mode_end),
+ rf5111_ini_mode_end, mode);
+
+ ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf5111_ini_common_end),
+ rf5111_ini_common_end, change_channel);
/* Baseband gain table */
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5111_ini_bbgain),
rf5111_ini_bbgain, change_channel);
- } else if (ah->ah_radio == AR5K_RF5112) {
+ break;
+ case AR5K_RF5112:
ath5k_hw_ini_mode_registers(ah,
- ARRAY_SIZE(ar5212_rf5112_ini_mode_end),
- ar5212_rf5112_ini_mode_end, mode);
+ ARRAY_SIZE(rf5112_ini_mode_end),
+ rf5112_ini_mode_end, mode);
+
+ ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf5112_ini_common_end),
+ rf5112_ini_common_end, change_channel);
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
rf5112_ini_bbgain, change_channel);
- } else if (ah->ah_radio == AR5K_RF5413) {
+ break;
+ case AR5K_RF5413:
ath5k_hw_ini_mode_registers(ah,
ARRAY_SIZE(rf5413_ini_mode_end),
rf5413_ini_mode_end, mode);
ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf5413_ini_common_end),
+ rf5413_ini_common_end, change_channel);
+
+ ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
rf5112_ini_bbgain, change_channel);
- } else if (ah->ah_radio == AR5K_RF2413) {
-
- if (mode < 2) {
- ATH5K_ERR(ah->ah_sc,
- "unsupported channel mode: %d\n", mode);
- return -EINVAL;
- }
- mode = mode - 2;
-
- /* Override a setting from ar5212_ini */
- ath5k_hw_reg_write(ah, 0x018830c6, AR5K_PHY(648));
+ break;
+ case AR5K_RF2316:
+ case AR5K_RF2413:
ath5k_hw_ini_mode_registers(ah,
ARRAY_SIZE(rf2413_ini_mode_end),
rf2413_ini_mode_end, mode);
- /* Baseband gain table */
ath5k_hw_ini_registers(ah,
- ARRAY_SIZE(rf5112_ini_bbgain),
- rf5112_ini_bbgain, change_channel);
-
- } else if (ah->ah_radio == AR5K_RF2425) {
+ ARRAY_SIZE(rf2413_ini_common_end),
+ rf2413_ini_common_end, change_channel);
- if (mode < 2) {
- ATH5K_ERR(ah->ah_sc,
- "unsupported channel mode: %d\n", mode);
- return -EINVAL;
+ /* Override settings from rf2413_ini_common_end */
+ if (ah->ah_radio == AR5K_RF2316) {
+ ath5k_hw_reg_write(ah, 0x00004000,
+ AR5K_PHY_AGC);
+ ath5k_hw_reg_write(ah, 0x081b7caa,
+ 0xa274);
}
- /* Map b to g */
- if (mode == 2)
- mode = 0;
- else
- mode = mode - 3;
-
- /* Override a setting from ar5212_ini */
- ath5k_hw_reg_write(ah, 0x018830c6, AR5K_PHY(648));
+ ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf5112_ini_bbgain),
+ rf5112_ini_bbgain, change_channel);
+ break;
+ case AR5K_RF2317:
+ case AR5K_RF2425:
ath5k_hw_ini_mode_registers(ah,
ARRAY_SIZE(rf2425_ini_mode_end),
rf2425_ini_mode_end, mode);
- /* Baseband gain table */
+ ath5k_hw_ini_registers(ah,
+ ARRAY_SIZE(rf2425_ini_common_end),
+ rf2425_ini_common_end, change_channel);
+
ath5k_hw_ini_registers(ah,
ARRAY_SIZE(rf5112_ini_bbgain),
rf5112_ini_bbgain, change_channel);
+ break;
+ default:
+ return -EINVAL;
}
diff --git a/drivers/net/wireless/ath5k/led.c b/drivers/net/wireless/ath5k/led.c
new file mode 100644
index 000000000000..19555fb79c9b
--- /dev/null
+++ b/drivers/net/wireless/ath5k/led.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2005 Atheros Communications, Inc.
+ * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2009 Bob Copeland <me@bobcopeland.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include <linux/pci.h>
+#include "ath5k.h"
+#include "base.h"
+
+#define ATH_SDEVICE(subv,subd) \
+ .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
+ .subvendor = (subv), .subdevice = (subd)
+
+#define ATH_LED(pin,polarity) .driver_data = (((pin) << 8) | (polarity))
+#define ATH_PIN(data) ((data) >> 8)
+#define ATH_POLARITY(data) ((data) & 0xff)
+
+/* Devices we match on for LED config info (typically laptops) */
+static const struct pci_device_id ath5k_led_devices[] = {
+ /* IBM-specific AR5212 */
+ { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
+ /* AR5211 */
+ { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) },
+ /* HP Compaq nc6xx, nc4000, nx6000 */
+ { ATH_SDEVICE(PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID), ATH_LED(1, 1) },
+ /* Acer Aspire One A150 (maximlevitsky@gmail.com) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe008), ATH_LED(3, 0) },
+ /* Acer Ferrari 5000 (russ.dill@gmail.com) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
+ /* E-machines E510 (tuliom@gmail.com) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
+ /* Acer Extensa 5620z (nekoreeve@gmail.com) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
+ { }
+};
+
+void ath5k_led_enable(struct ath5k_softc *sc)
+{
+ if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
+ ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
+ ath5k_led_off(sc);
+ }
+}
+
+void ath5k_led_on(struct ath5k_softc *sc)
+{
+ if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+ return;
+ ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
+}
+
+void ath5k_led_off(struct ath5k_softc *sc)
+{
+ if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+ return;
+ ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
+}
+
+static void
+ath5k_led_brightness_set(struct led_classdev *led_dev,
+ enum led_brightness brightness)
+{
+ struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
+ led_dev);
+
+ if (brightness == LED_OFF)
+ ath5k_led_off(led->sc);
+ else
+ ath5k_led_on(led->sc);
+}
+
+static int
+ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
+ const char *name, char *trigger)
+{
+ int err;
+
+ led->sc = sc;
+ strncpy(led->name, name, sizeof(led->name));
+ led->led_dev.name = led->name;
+ led->led_dev.default_trigger = trigger;
+ led->led_dev.brightness_set = ath5k_led_brightness_set;
+
+ err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
+ if (err) {
+ ATH5K_WARN(sc, "could not register LED %s\n", name);
+ led->sc = NULL;
+ }
+ return err;
+}
+
+static void
+ath5k_unregister_led(struct ath5k_led *led)
+{
+ if (!led->sc)
+ return;
+ led_classdev_unregister(&led->led_dev);
+ ath5k_led_off(led->sc);
+ led->sc = NULL;
+}
+
+void ath5k_unregister_leds(struct ath5k_softc *sc)
+{
+ ath5k_unregister_led(&sc->rx_led);
+ ath5k_unregister_led(&sc->tx_led);
+}
+
+int ath5k_init_leds(struct ath5k_softc *sc)
+{
+ int ret = 0;
+ struct ieee80211_hw *hw = sc->hw;
+ struct pci_dev *pdev = sc->pdev;
+ char name[ATH5K_LED_MAX_NAME_LEN + 1];
+ const struct pci_device_id *match;
+
+ match = pci_match_id(&ath5k_led_devices[0], pdev);
+ if (match) {
+ __set_bit(ATH_STAT_LEDSOFT, sc->status);
+ sc->led_pin = ATH_PIN(match->driver_data);
+ sc->led_on = ATH_POLARITY(match->driver_data);
+ }
+
+ if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+ goto out;
+
+ ath5k_led_enable(sc);
+
+ snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
+ ret = ath5k_register_led(sc, &sc->rx_led, name,
+ ieee80211_get_rx_led_name(hw));
+ if (ret)
+ goto out;
+
+ snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
+ ret = ath5k_register_led(sc, &sc->tx_led, name,
+ ieee80211_get_tx_led_name(hw));
+out:
+ return ret;
+}
+
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c
index 75eb9f43c741..55122f1e1986 100644
--- a/drivers/net/wireless/ath5k/pcu.c
+++ b/drivers/net/wireless/ath5k/pcu.c
@@ -646,6 +646,22 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
}
/**
+ * ath5k_hw_set_tsf64 - Set a new 64bit TSF
+ *
+ * @ah: The &struct ath5k_hw
+ * @tsf64: The new 64bit TSF
+ *
+ * Sets the new TSF
+ */
+void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64)
+{
+ ATH5K_TRACE(ah->ah_sc);
+
+ ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32);
+ ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32);
+}
+
+/**
* ath5k_hw_reset_tsf - Force a TSF reset
*
* @ah: The &struct ath5k_hw
@@ -1026,6 +1042,9 @@ int ath5k_keycache_type(const struct ieee80211_key_conf *key)
return AR5K_KEYTABLE_TYPE_40;
else if (key->keylen == LEN_WEP104)
return AR5K_KEYTABLE_TYPE_104;
+ return -EINVAL;
+ default:
+ return -EINVAL;
}
return -EINVAL;
}
@@ -1041,7 +1060,7 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
__le32 key_v[5] = {};
__le32 key0 = 0, key1 = 0;
__le32 *rxmic, *txmic;
- u32 keytype;
+ int keytype;
u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
bool is_tkip;
const u8 *key_ptr;
@@ -1139,7 +1158,7 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
/* MAC may be NULL if it's a broadcast key. In this case no need to
* to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
- if (unlikely(mac == NULL)) {
+ if (!mac) {
low_id = 0xffffffff;
high_id = 0xffff | AR5K_KEYTABLE_VALID;
} else {
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
index 7ba18e09463b..9e2faae5ae94 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -2,8 +2,9 @@
* PHY functions
*
* Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
* Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -26,1138 +27,193 @@
#include "ath5k.h"
#include "reg.h"
#include "base.h"
-
-/* Struct to hold initial RF register values (RF Banks) */
-struct ath5k_ini_rf {
- u8 rf_bank; /* check out ath5k_reg.h */
- u16 rf_register; /* register address */
- u32 rf_value[5]; /* register value for different modes (above) */
-};
-
-/*
- * Mode-specific RF Gain table (64bytes) for RF5111/5112
- * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
- * RF Gain values are included in AR5K_AR5210_INI)
- */
-struct ath5k_ini_rfgain {
- u16 rfg_register; /* RF Gain register address */
- u32 rfg_value[2]; /* [freq (see below)] */
-};
-
-struct ath5k_gain_opt {
- u32 go_default;
- u32 go_steps_count;
- const struct ath5k_gain_opt_step go_step[AR5K_GAIN_STEP_COUNT];
-};
-
-/* RF5111 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_5111[] = {
- { 0, 0x989c,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 0, 0x989c,
- { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
- { 0, 0x989c,
- { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
- { 0, 0x98d4,
- { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
- { 1, 0x98d4,
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d4,
- { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
- { 3, 0x98d8,
- { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
- { 6, 0x989c,
- { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
- { 6, 0x989c,
- { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
- { 6, 0x989c,
- { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
- { 6, 0x989c,
- { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
- { 6, 0x989c,
- { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
- { 6, 0x98d4,
- { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
- { 7, 0x989c,
- { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
- { 7, 0x989c,
- { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
- { 7, 0x989c,
- { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
- { 7, 0x989c,
- { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
- { 7, 0x989c,
- { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
- { 7, 0x989c,
- { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
- { 7, 0x989c,
- { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
-};
-
-/* Initial RF Gain settings for RF5111 */
-static const struct ath5k_ini_rfgain rfgain_5111[] = {
- /* 5Ghz 2Ghz */
- { AR5K_RF_GAIN(0), { 0x000001a9, 0x00000000 } },
- { AR5K_RF_GAIN(1), { 0x000001e9, 0x00000040 } },
- { AR5K_RF_GAIN(2), { 0x00000029, 0x00000080 } },
- { AR5K_RF_GAIN(3), { 0x00000069, 0x00000150 } },
- { AR5K_RF_GAIN(4), { 0x00000199, 0x00000190 } },
- { AR5K_RF_GAIN(5), { 0x000001d9, 0x000001d0 } },
- { AR5K_RF_GAIN(6), { 0x00000019, 0x00000010 } },
- { AR5K_RF_GAIN(7), { 0x00000059, 0x00000044 } },
- { AR5K_RF_GAIN(8), { 0x00000099, 0x00000084 } },
- { AR5K_RF_GAIN(9), { 0x000001a5, 0x00000148 } },
- { AR5K_RF_GAIN(10), { 0x000001e5, 0x00000188 } },
- { AR5K_RF_GAIN(11), { 0x00000025, 0x000001c8 } },
- { AR5K_RF_GAIN(12), { 0x000001c8, 0x00000014 } },
- { AR5K_RF_GAIN(13), { 0x00000008, 0x00000042 } },
- { AR5K_RF_GAIN(14), { 0x00000048, 0x00000082 } },
- { AR5K_RF_GAIN(15), { 0x00000088, 0x00000178 } },
- { AR5K_RF_GAIN(16), { 0x00000198, 0x000001b8 } },
- { AR5K_RF_GAIN(17), { 0x000001d8, 0x000001f8 } },
- { AR5K_RF_GAIN(18), { 0x00000018, 0x00000012 } },
- { AR5K_RF_GAIN(19), { 0x00000058, 0x00000052 } },
- { AR5K_RF_GAIN(20), { 0x00000098, 0x00000092 } },
- { AR5K_RF_GAIN(21), { 0x000001a4, 0x0000017c } },
- { AR5K_RF_GAIN(22), { 0x000001e4, 0x000001bc } },
- { AR5K_RF_GAIN(23), { 0x00000024, 0x000001fc } },
- { AR5K_RF_GAIN(24), { 0x00000064, 0x0000000a } },
- { AR5K_RF_GAIN(25), { 0x000000a4, 0x0000004a } },
- { AR5K_RF_GAIN(26), { 0x000000e4, 0x0000008a } },
- { AR5K_RF_GAIN(27), { 0x0000010a, 0x0000015a } },
- { AR5K_RF_GAIN(28), { 0x0000014a, 0x0000019a } },
- { AR5K_RF_GAIN(29), { 0x0000018a, 0x000001da } },
- { AR5K_RF_GAIN(30), { 0x000001ca, 0x0000000e } },
- { AR5K_RF_GAIN(31), { 0x0000000a, 0x0000004e } },
- { AR5K_RF_GAIN(32), { 0x0000004a, 0x0000008e } },
- { AR5K_RF_GAIN(33), { 0x0000008a, 0x0000015e } },
- { AR5K_RF_GAIN(34), { 0x000001ba, 0x0000019e } },
- { AR5K_RF_GAIN(35), { 0x000001fa, 0x000001de } },
- { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000009 } },
- { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000049 } },
- { AR5K_RF_GAIN(38), { 0x00000186, 0x00000089 } },
- { AR5K_RF_GAIN(39), { 0x000001c6, 0x00000179 } },
- { AR5K_RF_GAIN(40), { 0x00000006, 0x000001b9 } },
- { AR5K_RF_GAIN(41), { 0x00000046, 0x000001f9 } },
- { AR5K_RF_GAIN(42), { 0x00000086, 0x00000039 } },
- { AR5K_RF_GAIN(43), { 0x000000c6, 0x00000079 } },
- { AR5K_RF_GAIN(44), { 0x000000c6, 0x000000b9 } },
- { AR5K_RF_GAIN(45), { 0x000000c6, 0x000001bd } },
- { AR5K_RF_GAIN(46), { 0x000000c6, 0x000001fd } },
- { AR5K_RF_GAIN(47), { 0x000000c6, 0x0000003d } },
- { AR5K_RF_GAIN(48), { 0x000000c6, 0x0000007d } },
- { AR5K_RF_GAIN(49), { 0x000000c6, 0x000000bd } },
- { AR5K_RF_GAIN(50), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(51), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(52), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(53), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(54), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(55), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(56), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(57), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(58), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(59), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(60), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(61), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(62), { 0x000000c6, 0x000000fd } },
- { AR5K_RF_GAIN(63), { 0x000000c6, 0x000000fd } },
-};
-
-static const struct ath5k_gain_opt rfgain_opt_5111 = {
- 4,
- 9,
- {
- { { 4, 1, 1, 1 }, 6 },
- { { 4, 0, 1, 1 }, 4 },
- { { 3, 1, 1, 1 }, 3 },
- { { 4, 0, 0, 1 }, 1 },
- { { 4, 1, 1, 0 }, 0 },
- { { 4, 0, 1, 0 }, -2 },
- { { 3, 1, 1, 0 }, -3 },
- { { 4, 0, 0, 0 }, -4 },
- { { 2, 1, 1, 0 }, -6 }
- }
-};
-
-/* RF5112 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_5112[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
- { 3, 0x98dc,
- { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
- { 6, 0x989c,
- { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
- { 6, 0x989c,
- { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
- { 6, 0x989c,
- { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
- { 6, 0x989c,
- { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
- { 6, 0x989c,
- { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
- { 6, 0x989c,
- { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
- { 6, 0x989c,
- { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
- { 6, 0x989c,
- { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
- { 6, 0x989c,
- { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
- { 6, 0x989c,
- { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
- { 6, 0x989c,
- { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
- { 6, 0x989c,
- { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
- { 6, 0x989c,
- { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
- { 6, 0x989c,
- { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
- { 6, 0x989c,
- { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
- { 6, 0x989c,
- { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
- { 6, 0x989c,
- { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
- { 6, 0x989c,
- { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
- { 6, 0x989c,
- { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
- { 6, 0x989c,
- { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
- { 6, 0x989c,
- { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
- { 6, 0x989c,
- { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
- { 6, 0x989c,
- { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
- { 6, 0x989c,
- { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
- { 6, 0x989c,
- { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
- { 6, 0x989c,
- { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
- { 6, 0x989c,
- { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
- { 6, 0x989c,
- { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
- { 6, 0x989c,
- { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
- { 6, 0x98d0,
- { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
- { 7, 0x989c,
- { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
- { 7, 0x989c,
- { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
- { 7, 0x989c,
- { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
- { 7, 0x989c,
- { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
- { 7, 0x989c,
- { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
- { 7, 0x989c,
- { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
- { 7, 0x989c,
- { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
- { 7, 0x989c,
- { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
- { 7, 0x989c,
- { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
- { 7, 0x989c,
- { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
- { 7, 0x989c,
- { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
- { 7, 0x989c,
- { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
- { 7, 0x98c4,
- { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
-};
-
-/* RF5112A mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_5112a[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
- { 3, 0x98dc,
- { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
- { 6, 0x989c,
- { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
- { 6, 0x989c,
- { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
- { 6, 0x989c,
- { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
- { 6, 0x989c,
- { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
- { 6, 0x989c,
- { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
- { 6, 0x989c,
- { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
- { 6, 0x989c,
- { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
- { 6, 0x989c,
- { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
- { 6, 0x989c,
- { 0x00190000, 0x00190000, 0x00190000, 0x00190000, 0x00190000 } },
- { 6, 0x989c,
- { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
- { 6, 0x989c,
- { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
- { 6, 0x989c,
- { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
- { 6, 0x989c,
- { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
- { 6, 0x989c,
- { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, 0x989c,
- { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
- { 6, 0x989c,
- { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
- { 6, 0x989c,
- { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
- { 6, 0x989c,
- { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
- { 6, 0x989c,
- { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
- { 6, 0x989c,
- { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
- { 6, 0x989c,
- { 0x00020080, 0x00020080, 0x00020080, 0x00020080, 0x00020080 } },
- { 6, 0x989c,
- { 0x00080009, 0x00080009, 0x00080009, 0x00080009, 0x00080009 } },
- { 6, 0x989c,
- { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
- { 6, 0x989c,
- { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
- { 6, 0x989c,
- { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
- { 6, 0x989c,
- { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
- { 6, 0x989c,
- { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
- { 6, 0x98d8,
- { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
- { 7, 0x989c,
- { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
- { 7, 0x989c,
- { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
- { 7, 0x989c,
- { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
- { 7, 0x989c,
- { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
- { 7, 0x989c,
- { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
- { 7, 0x989c,
- { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
- { 7, 0x989c,
- { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
- { 7, 0x989c,
- { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
- { 7, 0x989c,
- { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
- { 7, 0x989c,
- { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
- { 7, 0x989c,
- { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
- { 7, 0x989c,
- { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
- { 7, 0x98c4,
- { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
-};
-
-
-static const struct ath5k_ini_rf rfregs_2112a[] = {
- { 1, AR5K_RF_BUFFER_CONTROL_4,
- /* mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020 } },
- { 2, AR5K_RF_BUFFER_CONTROL_3,
- { 0x03060408, 0x03060408, 0x03070408 } },
- { 3, AR5K_RF_BUFFER_CONTROL_6,
- { 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, AR5K_RF_BUFFER,
- { 0x0a000000, 0x0a000000, 0x0a000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00800000, 0x00800000, 0x00800000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00010000, 0x00010000, 0x00010000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00180000, 0x00180000, 0x00180000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x006e0000, 0x006e0000, 0x006e0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00c70000, 0x00c70000, 0x00c70000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x004b0000, 0x004b0000, 0x004b0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x04480000, 0x04480000, 0x04480000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00e40000, 0x00e40000, 0x00e40000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x043f0000, 0x043f0000, 0x043f0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x0c0c0000, 0x0c0c0000, 0x0c0c0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x02190000, 0x02190000, 0x02190000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00240000, 0x00240000, 0x00240000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00b40000, 0x00b40000, 0x00b40000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00990000, 0x00990000, 0x00990000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00500000, 0x00500000, 0x00500000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x002a0000, 0x002a0000, 0x002a0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00120000, 0x00120000, 0x00120000 } },
- { 6, AR5K_RF_BUFFER,
- { 0xc0320000, 0xc0320000, 0xc0320000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x01740000, 0x01740000, 0x01740000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00110000, 0x00110000, 0x00110000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x86280000, 0x86280000, 0x86280000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x31840000, 0x31840000, 0x31840000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00f20080, 0x00f20080, 0x00f20080 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00070019, 0x00070019, 0x00070019 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x000000b2, 0x000000b2, 0x000000b2 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00b02184, 0x00b02184, 0x00b02184 } },
- { 6, AR5K_RF_BUFFER,
- { 0x004125a4, 0x004125a4, 0x004125a4 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00119220, 0x00119220, 0x00119220 } },
- { 6, AR5K_RF_BUFFER,
- { 0x001a4800, 0x001a4800, 0x001a4800 } },
- { 6, AR5K_RF_BUFFER_CONTROL_5,
- { 0x000b0230, 0x000b0230, 0x000b0230 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000094, 0x00000094, 0x00000094 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000091, 0x00000091, 0x00000091 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000012, 0x00000012, 0x00000012 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000080, 0x00000080, 0x00000080 } },
- { 7, AR5K_RF_BUFFER,
- { 0x000000d9, 0x000000d9, 0x000000d9 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000060, 0x00000060, 0x00000060 } },
- { 7, AR5K_RF_BUFFER,
- { 0x000000f0, 0x000000f0, 0x000000f0 } },
- { 7, AR5K_RF_BUFFER,
- { 0x000000a2, 0x000000a2, 0x000000a2 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000052, 0x00000052, 0x00000052 } },
- { 7, AR5K_RF_BUFFER,
- { 0x000000d4, 0x000000d4, 0x000000d4 } },
- { 7, AR5K_RF_BUFFER,
- { 0x000014cc, 0x000014cc, 0x000014cc } },
- { 7, AR5K_RF_BUFFER,
- { 0x0000048c, 0x0000048c, 0x0000048c } },
- { 7, AR5K_RF_BUFFER_CONTROL_1,
- { 0x00000003, 0x00000003, 0x00000003 } },
-};
-
-/* RF5413/5414 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_5413[] = {
- { 1, 0x98d4,
- /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
- { 2, 0x98d0,
- { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
- { 3, 0x98dc,
- { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
- { 6, 0x989c,
- { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
- { 6, 0x989c,
- { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
- { 6, 0x989c,
- { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
- { 6, 0x989c,
- { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
- { 6, 0x989c,
- { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
- { 6, 0x989c,
- { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
- { 6, 0x989c,
- { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
- { 6, 0x989c,
- { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
- { 6, 0x989c,
- { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
- { 6, 0x989c,
- { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
- { 6, 0x989c,
- { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
- { 6, 0x989c,
- { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
- { 6, 0x989c,
- { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
- { 6, 0x989c,
- { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
- { 6, 0x989c,
- { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
- { 6, 0x989c,
- { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
- { 6, 0x989c,
- { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
- { 6, 0x989c,
- { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
- { 6, 0x989c,
- { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
- { 6, 0x989c,
- { 0x00510040, 0x00510040, 0x005100a0, 0x005100a0, 0x005100a0 } },
- { 6, 0x989c,
- { 0x0050006a, 0x0050006a, 0x005000dd, 0x005000dd, 0x005000dd } },
- { 6, 0x989c,
- { 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
- { 6, 0x989c,
- { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
- { 6, 0x989c,
- { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
- { 6, 0x989c,
- { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00003600 } },
- { 6, 0x98c8,
- { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
- { 7, 0x989c,
- { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
- { 7, 0x989c,
- { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
- { 7, 0x98cc,
- { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-/* RF2413/2414 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_2413[] = {
- { 1, AR5K_RF_BUFFER_CONTROL_4,
- /* mode b mode g mode gTurbo */
- { 0x00000020, 0x00000020, 0x00000020 } },
- { 2, AR5K_RF_BUFFER_CONTROL_3,
- { 0x02001408, 0x02001408, 0x02001408 } },
- { 3, AR5K_RF_BUFFER_CONTROL_6,
- { 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
- { 6, AR5K_RF_BUFFER,
- { 0xf0000000, 0xf0000000, 0xf0000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x03000000, 0x03000000, 0x03000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x40400000, 0x40400000, 0x40400000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x65050000, 0x65050000, 0x65050000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00420000, 0x00420000, 0x00420000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00b50000, 0x00b50000, 0x00b50000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00030000, 0x00030000, 0x00030000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00f70000, 0x00f70000, 0x00f70000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x009d0000, 0x009d0000, 0x009d0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00220000, 0x00220000, 0x00220000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x04220000, 0x04220000, 0x04220000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00230018, 0x00230018, 0x00230018 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00280050, 0x00280050, 0x00280050 } },
- { 6, AR5K_RF_BUFFER,
- { 0x005000c3, 0x005000c3, 0x005000c3 } },
- { 6, AR5K_RF_BUFFER,
- { 0x0004007f, 0x0004007f, 0x0004007f } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000458, 0x00000458, 0x00000458 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x0000c000, 0x0000c000, 0x0000c000 } },
- { 6, AR5K_RF_BUFFER_CONTROL_5,
- { 0x00400230, 0x00400230, 0x00400230 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00006400, 0x00006400, 0x00006400 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000800, 0x00000800, 0x00000800 } },
- { 7, AR5K_RF_BUFFER_CONTROL_2,
- { 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-/* RF2425 mode-specific init registers */
-static const struct ath5k_ini_rf rfregs_2425[] = {
- { 1, AR5K_RF_BUFFER_CONTROL_4,
- /* mode g mode gTurbo */
- { 0x00000020, 0x00000020 } },
- { 2, AR5K_RF_BUFFER_CONTROL_3,
- { 0x02001408, 0x02001408 } },
- { 3, AR5K_RF_BUFFER_CONTROL_6,
- { 0x00e020c0, 0x00e020c0 } },
- { 6, AR5K_RF_BUFFER,
- { 0x10000000, 0x10000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x002a0000, 0x002a0000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00100000, 0x00100000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00020000, 0x00020000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00730000, 0x00730000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00f80000, 0x00f80000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00e70000, 0x00e70000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00140000, 0x00140000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00910040, 0x00910040 } },
- { 6, AR5K_RF_BUFFER,
- { 0x0007001a, 0x0007001a } },
- { 6, AR5K_RF_BUFFER,
- { 0x00410000, 0x00410000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00810060, 0x00810060 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00020803, 0x00020803 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00000000, 0x00000000 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00001660, 0x00001660 } },
- { 6, AR5K_RF_BUFFER,
- { 0x00001688, 0x00001688 } },
- { 6, AR5K_RF_BUFFER_CONTROL_1,
- { 0x00000001, 0x00000001 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00006400, 0x00006400 } },
- { 7, AR5K_RF_BUFFER,
- { 0x00000800, 0x00000800 } },
- { 7, AR5K_RF_BUFFER_CONTROL_2,
- { 0x0000000e, 0x0000000e } },
-};
-
-/* Initial RF Gain settings for RF5112 */
-static const struct ath5k_ini_rfgain rfgain_5112[] = {
- /* 5Ghz 2Ghz */
- { AR5K_RF_GAIN(0), { 0x00000007, 0x00000007 } },
- { AR5K_RF_GAIN(1), { 0x00000047, 0x00000047 } },
- { AR5K_RF_GAIN(2), { 0x00000087, 0x00000087 } },
- { AR5K_RF_GAIN(3), { 0x000001a0, 0x000001a0 } },
- { AR5K_RF_GAIN(4), { 0x000001e0, 0x000001e0 } },
- { AR5K_RF_GAIN(5), { 0x00000020, 0x00000020 } },
- { AR5K_RF_GAIN(6), { 0x00000060, 0x00000060 } },
- { AR5K_RF_GAIN(7), { 0x000001a1, 0x000001a1 } },
- { AR5K_RF_GAIN(8), { 0x000001e1, 0x000001e1 } },
- { AR5K_RF_GAIN(9), { 0x00000021, 0x00000021 } },
- { AR5K_RF_GAIN(10), { 0x00000061, 0x00000061 } },
- { AR5K_RF_GAIN(11), { 0x00000162, 0x00000162 } },
- { AR5K_RF_GAIN(12), { 0x000001a2, 0x000001a2 } },
- { AR5K_RF_GAIN(13), { 0x000001e2, 0x000001e2 } },
- { AR5K_RF_GAIN(14), { 0x00000022, 0x00000022 } },
- { AR5K_RF_GAIN(15), { 0x00000062, 0x00000062 } },
- { AR5K_RF_GAIN(16), { 0x00000163, 0x00000163 } },
- { AR5K_RF_GAIN(17), { 0x000001a3, 0x000001a3 } },
- { AR5K_RF_GAIN(18), { 0x000001e3, 0x000001e3 } },
- { AR5K_RF_GAIN(19), { 0x00000023, 0x00000023 } },
- { AR5K_RF_GAIN(20), { 0x00000063, 0x00000063 } },
- { AR5K_RF_GAIN(21), { 0x00000184, 0x00000184 } },
- { AR5K_RF_GAIN(22), { 0x000001c4, 0x000001c4 } },
- { AR5K_RF_GAIN(23), { 0x00000004, 0x00000004 } },
- { AR5K_RF_GAIN(24), { 0x000001ea, 0x0000000b } },
- { AR5K_RF_GAIN(25), { 0x0000002a, 0x0000004b } },
- { AR5K_RF_GAIN(26), { 0x0000006a, 0x0000008b } },
- { AR5K_RF_GAIN(27), { 0x000000aa, 0x000001ac } },
- { AR5K_RF_GAIN(28), { 0x000001ab, 0x000001ec } },
- { AR5K_RF_GAIN(29), { 0x000001eb, 0x0000002c } },
- { AR5K_RF_GAIN(30), { 0x0000002b, 0x00000012 } },
- { AR5K_RF_GAIN(31), { 0x0000006b, 0x00000052 } },
- { AR5K_RF_GAIN(32), { 0x000000ab, 0x00000092 } },
- { AR5K_RF_GAIN(33), { 0x000001ac, 0x00000193 } },
- { AR5K_RF_GAIN(34), { 0x000001ec, 0x000001d3 } },
- { AR5K_RF_GAIN(35), { 0x0000002c, 0x00000013 } },
- { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000053 } },
- { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000093 } },
- { AR5K_RF_GAIN(38), { 0x000000ba, 0x00000194 } },
- { AR5K_RF_GAIN(39), { 0x000001bb, 0x000001d4 } },
- { AR5K_RF_GAIN(40), { 0x000001fb, 0x00000014 } },
- { AR5K_RF_GAIN(41), { 0x0000003b, 0x0000003a } },
- { AR5K_RF_GAIN(42), { 0x0000007b, 0x0000007a } },
- { AR5K_RF_GAIN(43), { 0x000000bb, 0x000000ba } },
- { AR5K_RF_GAIN(44), { 0x000001bc, 0x000001bb } },
- { AR5K_RF_GAIN(45), { 0x000001fc, 0x000001fb } },
- { AR5K_RF_GAIN(46), { 0x0000003c, 0x0000003b } },
- { AR5K_RF_GAIN(47), { 0x0000007c, 0x0000007b } },
- { AR5K_RF_GAIN(48), { 0x000000bc, 0x000000bb } },
- { AR5K_RF_GAIN(49), { 0x000000fc, 0x000001bc } },
- { AR5K_RF_GAIN(50), { 0x000000fc, 0x000001fc } },
- { AR5K_RF_GAIN(51), { 0x000000fc, 0x0000003c } },
- { AR5K_RF_GAIN(52), { 0x000000fc, 0x0000007c } },
- { AR5K_RF_GAIN(53), { 0x000000fc, 0x000000bc } },
- { AR5K_RF_GAIN(54), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(55), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(56), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(57), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(58), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(59), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(60), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(61), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(62), { 0x000000fc, 0x000000fc } },
- { AR5K_RF_GAIN(63), { 0x000000fc, 0x000000fc } },
-};
-
-/* Initial RF Gain settings for RF5413 */
-static const struct ath5k_ini_rfgain rfgain_5413[] = {
- /* 5Ghz 2Ghz */
- { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
- { AR5K_RF_GAIN(1), { 0x00000040, 0x00000040 } },
- { AR5K_RF_GAIN(2), { 0x00000080, 0x00000080 } },
- { AR5K_RF_GAIN(3), { 0x000001a1, 0x00000161 } },
- { AR5K_RF_GAIN(4), { 0x000001e1, 0x000001a1 } },
- { AR5K_RF_GAIN(5), { 0x00000021, 0x000001e1 } },
- { AR5K_RF_GAIN(6), { 0x00000061, 0x00000021 } },
- { AR5K_RF_GAIN(7), { 0x00000188, 0x00000061 } },
- { AR5K_RF_GAIN(8), { 0x000001c8, 0x00000188 } },
- { AR5K_RF_GAIN(9), { 0x00000008, 0x000001c8 } },
- { AR5K_RF_GAIN(10), { 0x00000048, 0x00000008 } },
- { AR5K_RF_GAIN(11), { 0x00000088, 0x00000048 } },
- { AR5K_RF_GAIN(12), { 0x000001a9, 0x00000088 } },
- { AR5K_RF_GAIN(13), { 0x000001e9, 0x00000169 } },
- { AR5K_RF_GAIN(14), { 0x00000029, 0x000001a9 } },
- { AR5K_RF_GAIN(15), { 0x00000069, 0x000001e9 } },
- { AR5K_RF_GAIN(16), { 0x000001d0, 0x00000029 } },
- { AR5K_RF_GAIN(17), { 0x00000010, 0x00000069 } },
- { AR5K_RF_GAIN(18), { 0x00000050, 0x00000190 } },
- { AR5K_RF_GAIN(19), { 0x00000090, 0x000001d0 } },
- { AR5K_RF_GAIN(20), { 0x000001b1, 0x00000010 } },
- { AR5K_RF_GAIN(21), { 0x000001f1, 0x00000050 } },
- { AR5K_RF_GAIN(22), { 0x00000031, 0x00000090 } },
- { AR5K_RF_GAIN(23), { 0x00000071, 0x00000171 } },
- { AR5K_RF_GAIN(24), { 0x000001b8, 0x000001b1 } },
- { AR5K_RF_GAIN(25), { 0x000001f8, 0x000001f1 } },
- { AR5K_RF_GAIN(26), { 0x00000038, 0x00000031 } },
- { AR5K_RF_GAIN(27), { 0x00000078, 0x00000071 } },
- { AR5K_RF_GAIN(28), { 0x00000199, 0x00000198 } },
- { AR5K_RF_GAIN(29), { 0x000001d9, 0x000001d8 } },
- { AR5K_RF_GAIN(30), { 0x00000019, 0x00000018 } },
- { AR5K_RF_GAIN(31), { 0x00000059, 0x00000058 } },
- { AR5K_RF_GAIN(32), { 0x00000099, 0x00000098 } },
- { AR5K_RF_GAIN(33), { 0x000000d9, 0x00000179 } },
- { AR5K_RF_GAIN(34), { 0x000000f9, 0x000001b9 } },
- { AR5K_RF_GAIN(35), { 0x000000f9, 0x000001f9 } },
- { AR5K_RF_GAIN(36), { 0x000000f9, 0x00000039 } },
- { AR5K_RF_GAIN(37), { 0x000000f9, 0x00000079 } },
- { AR5K_RF_GAIN(38), { 0x000000f9, 0x000000b9 } },
- { AR5K_RF_GAIN(39), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(40), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(41), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(42), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(43), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(44), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(45), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(46), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(47), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(48), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(49), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(50), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(51), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(52), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(53), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(54), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(55), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(56), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(57), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(58), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(59), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(60), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(61), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(62), { 0x000000f9, 0x000000f9 } },
- { AR5K_RF_GAIN(63), { 0x000000f9, 0x000000f9 } },
-};
-
-/* Initial RF Gain settings for RF2413 */
-static const struct ath5k_ini_rfgain rfgain_2413[] = {
- { AR5K_RF_GAIN(0), { 0x00000000 } },
- { AR5K_RF_GAIN(1), { 0x00000040 } },
- { AR5K_RF_GAIN(2), { 0x00000080 } },
- { AR5K_RF_GAIN(3), { 0x00000181 } },
- { AR5K_RF_GAIN(4), { 0x000001c1 } },
- { AR5K_RF_GAIN(5), { 0x00000001 } },
- { AR5K_RF_GAIN(6), { 0x00000041 } },
- { AR5K_RF_GAIN(7), { 0x00000081 } },
- { AR5K_RF_GAIN(8), { 0x00000168 } },
- { AR5K_RF_GAIN(9), { 0x000001a8 } },
- { AR5K_RF_GAIN(10), { 0x000001e8 } },
- { AR5K_RF_GAIN(11), { 0x00000028 } },
- { AR5K_RF_GAIN(12), { 0x00000068 } },
- { AR5K_RF_GAIN(13), { 0x00000189 } },
- { AR5K_RF_GAIN(14), { 0x000001c9 } },
- { AR5K_RF_GAIN(15), { 0x00000009 } },
- { AR5K_RF_GAIN(16), { 0x00000049 } },
- { AR5K_RF_GAIN(17), { 0x00000089 } },
- { AR5K_RF_GAIN(18), { 0x00000190 } },
- { AR5K_RF_GAIN(19), { 0x000001d0 } },
- { AR5K_RF_GAIN(20), { 0x00000010 } },
- { AR5K_RF_GAIN(21), { 0x00000050 } },
- { AR5K_RF_GAIN(22), { 0x00000090 } },
- { AR5K_RF_GAIN(23), { 0x00000191 } },
- { AR5K_RF_GAIN(24), { 0x000001d1 } },
- { AR5K_RF_GAIN(25), { 0x00000011 } },
- { AR5K_RF_GAIN(26), { 0x00000051 } },
- { AR5K_RF_GAIN(27), { 0x00000091 } },
- { AR5K_RF_GAIN(28), { 0x00000178 } },
- { AR5K_RF_GAIN(29), { 0x000001b8 } },
- { AR5K_RF_GAIN(30), { 0x000001f8 } },
- { AR5K_RF_GAIN(31), { 0x00000038 } },
- { AR5K_RF_GAIN(32), { 0x00000078 } },
- { AR5K_RF_GAIN(33), { 0x00000199 } },
- { AR5K_RF_GAIN(34), { 0x000001d9 } },
- { AR5K_RF_GAIN(35), { 0x00000019 } },
- { AR5K_RF_GAIN(36), { 0x00000059 } },
- { AR5K_RF_GAIN(37), { 0x00000099 } },
- { AR5K_RF_GAIN(38), { 0x000000d9 } },
- { AR5K_RF_GAIN(39), { 0x000000f9 } },
- { AR5K_RF_GAIN(40), { 0x000000f9 } },
- { AR5K_RF_GAIN(41), { 0x000000f9 } },
- { AR5K_RF_GAIN(42), { 0x000000f9 } },
- { AR5K_RF_GAIN(43), { 0x000000f9 } },
- { AR5K_RF_GAIN(44), { 0x000000f9 } },
- { AR5K_RF_GAIN(45), { 0x000000f9 } },
- { AR5K_RF_GAIN(46), { 0x000000f9 } },
- { AR5K_RF_GAIN(47), { 0x000000f9 } },
- { AR5K_RF_GAIN(48), { 0x000000f9 } },
- { AR5K_RF_GAIN(49), { 0x000000f9 } },
- { AR5K_RF_GAIN(50), { 0x000000f9 } },
- { AR5K_RF_GAIN(51), { 0x000000f9 } },
- { AR5K_RF_GAIN(52), { 0x000000f9 } },
- { AR5K_RF_GAIN(53), { 0x000000f9 } },
- { AR5K_RF_GAIN(54), { 0x000000f9 } },
- { AR5K_RF_GAIN(55), { 0x000000f9 } },
- { AR5K_RF_GAIN(56), { 0x000000f9 } },
- { AR5K_RF_GAIN(57), { 0x000000f9 } },
- { AR5K_RF_GAIN(58), { 0x000000f9 } },
- { AR5K_RF_GAIN(59), { 0x000000f9 } },
- { AR5K_RF_GAIN(60), { 0x000000f9 } },
- { AR5K_RF_GAIN(61), { 0x000000f9 } },
- { AR5K_RF_GAIN(62), { 0x000000f9 } },
- { AR5K_RF_GAIN(63), { 0x000000f9 } },
-};
-
-/* Initial RF Gain settings for RF2425 */
-static const struct ath5k_ini_rfgain rfgain_2425[] = {
- { AR5K_RF_GAIN(0), { 0x00000000 } },
- { AR5K_RF_GAIN(1), { 0x00000040 } },
- { AR5K_RF_GAIN(2), { 0x00000080 } },
- { AR5K_RF_GAIN(3), { 0x00000181 } },
- { AR5K_RF_GAIN(4), { 0x000001c1 } },
- { AR5K_RF_GAIN(5), { 0x00000001 } },
- { AR5K_RF_GAIN(6), { 0x00000041 } },
- { AR5K_RF_GAIN(7), { 0x00000081 } },
- { AR5K_RF_GAIN(8), { 0x00000188 } },
- { AR5K_RF_GAIN(9), { 0x000001c8 } },
- { AR5K_RF_GAIN(10), { 0x00000008 } },
- { AR5K_RF_GAIN(11), { 0x00000048 } },
- { AR5K_RF_GAIN(12), { 0x00000088 } },
- { AR5K_RF_GAIN(13), { 0x00000189 } },
- { AR5K_RF_GAIN(14), { 0x000001c9 } },
- { AR5K_RF_GAIN(15), { 0x00000009 } },
- { AR5K_RF_GAIN(16), { 0x00000049 } },
- { AR5K_RF_GAIN(17), { 0x00000089 } },
- { AR5K_RF_GAIN(18), { 0x000001b0 } },
- { AR5K_RF_GAIN(19), { 0x000001f0 } },
- { AR5K_RF_GAIN(20), { 0x00000030 } },
- { AR5K_RF_GAIN(21), { 0x00000070 } },
- { AR5K_RF_GAIN(22), { 0x00000171 } },
- { AR5K_RF_GAIN(23), { 0x000001b1 } },
- { AR5K_RF_GAIN(24), { 0x000001f1 } },
- { AR5K_RF_GAIN(25), { 0x00000031 } },
- { AR5K_RF_GAIN(26), { 0x00000071 } },
- { AR5K_RF_GAIN(27), { 0x000001b8 } },
- { AR5K_RF_GAIN(28), { 0x000001f8 } },
- { AR5K_RF_GAIN(29), { 0x00000038 } },
- { AR5K_RF_GAIN(30), { 0x00000078 } },
- { AR5K_RF_GAIN(31), { 0x000000b8 } },
- { AR5K_RF_GAIN(32), { 0x000001b9 } },
- { AR5K_RF_GAIN(33), { 0x000001f9 } },
- { AR5K_RF_GAIN(34), { 0x00000039 } },
- { AR5K_RF_GAIN(35), { 0x00000079 } },
- { AR5K_RF_GAIN(36), { 0x000000b9 } },
- { AR5K_RF_GAIN(37), { 0x000000f9 } },
- { AR5K_RF_GAIN(38), { 0x000000f9 } },
- { AR5K_RF_GAIN(39), { 0x000000f9 } },
- { AR5K_RF_GAIN(40), { 0x000000f9 } },
- { AR5K_RF_GAIN(41), { 0x000000f9 } },
- { AR5K_RF_GAIN(42), { 0x000000f9 } },
- { AR5K_RF_GAIN(43), { 0x000000f9 } },
- { AR5K_RF_GAIN(44), { 0x000000f9 } },
- { AR5K_RF_GAIN(45), { 0x000000f9 } },
- { AR5K_RF_GAIN(46), { 0x000000f9 } },
- { AR5K_RF_GAIN(47), { 0x000000f9 } },
- { AR5K_RF_GAIN(48), { 0x000000f9 } },
- { AR5K_RF_GAIN(49), { 0x000000f9 } },
- { AR5K_RF_GAIN(50), { 0x000000f9 } },
- { AR5K_RF_GAIN(51), { 0x000000f9 } },
- { AR5K_RF_GAIN(52), { 0x000000f9 } },
- { AR5K_RF_GAIN(53), { 0x000000f9 } },
- { AR5K_RF_GAIN(54), { 0x000000f9 } },
- { AR5K_RF_GAIN(55), { 0x000000f9 } },
- { AR5K_RF_GAIN(56), { 0x000000f9 } },
- { AR5K_RF_GAIN(57), { 0x000000f9 } },
- { AR5K_RF_GAIN(58), { 0x000000f9 } },
- { AR5K_RF_GAIN(59), { 0x000000f9 } },
- { AR5K_RF_GAIN(60), { 0x000000f9 } },
- { AR5K_RF_GAIN(61), { 0x000000f9 } },
- { AR5K_RF_GAIN(62), { 0x000000f9 } },
- { AR5K_RF_GAIN(63), { 0x000000f9 } },
-};
-
-static const struct ath5k_gain_opt rfgain_opt_5112 = {
- 1,
- 8,
- {
- { { 3, 0, 0, 0, 0, 0, 0 }, 6 },
- { { 2, 0, 0, 0, 0, 0, 0 }, 0 },
- { { 1, 0, 0, 0, 0, 0, 0 }, -3 },
- { { 0, 0, 0, 0, 0, 0, 0 }, -6 },
- { { 0, 1, 1, 0, 0, 0, 0 }, -8 },
- { { 0, 1, 1, 0, 1, 1, 0 }, -10 },
- { { 0, 1, 0, 1, 1, 1, 0 }, -13 },
- { { 0, 1, 0, 1, 1, 0, 1 }, -16 },
- }
-};
+#include "rfbuffer.h"
+#include "rfgain.h"
/*
* Used to modify RF Banks before writing them to AR5K_RF_BUFFER
*/
-static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits,
- u32 first, u32 col, bool set)
+static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
+ const struct ath5k_rf_reg *rf_regs,
+ u32 val, u8 reg_id, bool set)
{
- u32 mask, entry, last, data, shift, position;
- s32 left;
+ const struct ath5k_rf_reg *rfreg = NULL;
+ u8 offset, bank, num_bits, col, position;
+ u16 entry;
+ u32 mask, data, last_bit, bits_shifted, first_bit;
+ u32 *rfb;
+ s32 bits_left;
int i;
data = 0;
+ rfb = ah->ah_rf_banks;
- if (rf == NULL)
+ for (i = 0; i < ah->ah_rf_regs_count; i++) {
+ if (rf_regs[i].index == reg_id) {
+ rfreg = &rf_regs[i];
+ break;
+ }
+ }
+
+ if (rfb == NULL || rfreg == NULL) {
+ ATH5K_PRINTF("Rf register not found!\n");
/* should not happen */
return 0;
+ }
- if (!(col <= 3 && bits <= 32 && first + bits <= 319)) {
+ bank = rfreg->bank;
+ num_bits = rfreg->field.len;
+ first_bit = rfreg->field.pos;
+ col = rfreg->field.col;
+
+ /* first_bit is an offset from bank's
+ * start. Since we have all banks on
+ * the same array, we use this offset
+ * to mark each bank's start */
+ offset = ah->ah_offset[bank];
+
+ /* Boundary check */
+ if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) {
ATH5K_PRINTF("invalid values at offset %u\n", offset);
return 0;
}
- entry = ((first - 1) / 8) + offset;
- position = (first - 1) % 8;
+ entry = ((first_bit - 1) / 8) + offset;
+ position = (first_bit - 1) % 8;
if (set)
- data = ath5k_hw_bitswap(reg, bits);
+ data = ath5k_hw_bitswap(val, num_bits);
+
+ for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
+ position = 0, entry++) {
+
+ last_bit = (position + bits_left > 8) ? 8 :
+ position + bits_left;
- for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) {
- last = (position + left > 8) ? 8 : position + left;
- mask = (((1 << last) - 1) ^ ((1 << position) - 1)) << (col * 8);
+ mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) <<
+ (col * 8);
if (set) {
- rf[entry] &= ~mask;
- rf[entry] |= ((data << position) << (col * 8)) & mask;
+ rfb[entry] &= ~mask;
+ rfb[entry] |= ((data << position) << (col * 8)) & mask;
data >>= (8 - position);
} else {
- data = (((rf[entry] & mask) >> (col * 8)) >> position)
- << shift;
- shift += last - position;
+ data |= (((rfb[entry] & mask) >> (col * 8)) >> position)
+ << bits_shifted;
+ bits_shifted += last_bit - position;
}
- left -= 8 - position;
+ bits_left -= 8 - position;
}
- data = set ? 1 : ath5k_hw_bitswap(data, bits);
+ data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
return data;
}
-static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
+/**********************\
+* RF Gain optimization *
+\**********************/
+
+/*
+ * This code is used to optimize rf gain on different environments
+ * (temprature mostly) based on feedback from a power detector.
+ *
+ * It's only used on RF5111 and RF5112, later RF chips seem to have
+ * auto adjustment on hw -notice they have a much smaller BANK 7 and
+ * no gain optimization ladder-.
+ *
+ * For more infos check out this patent doc
+ * http://www.freepatentsonline.com/7400691.html
+ *
+ * This paper describes power drops as seen on the receiver due to
+ * probe packets
+ * http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues
+ * %20of%20Power%20Control.pdf
+ *
+ * And this is the MadWiFi bug entry related to the above
+ * http://madwifi-project.org/ticket/1659
+ * with various measurements and diagrams
+ *
+ * TODO: Deal with power drops due to probes by setting an apropriate
+ * tx power on the probe packets ! Make this part of the calibration process.
+ */
+
+/* Initialize ah_gain durring attach */
+int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
+{
+ /* Initialize the gain optimization values */
+ switch (ah->ah_radio) {
+ case AR5K_RF5111:
+ ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
+ ah->ah_gain.g_low = 20;
+ ah->ah_gain.g_high = 35;
+ ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+ break;
+ case AR5K_RF5112:
+ ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
+ ah->ah_gain.g_low = 20;
+ ah->ah_gain.g_high = 85;
+ ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* Schedule a gain probe check on the next transmited packet.
+ * That means our next packet is going to be sent with lower
+ * tx power and a Peak to Average Power Detector (PAPD) will try
+ * to measure the gain.
+ *
+ * TODO: Use propper tx power setting for the probe packet so
+ * that we don't observe a serious power drop on the receiver
+ *
+ * XXX: How about forcing a tx packet (bypassing PCU arbitrator etc)
+ * just after we enable the probe so that we don't mess with
+ * standard traffic ? Maybe it's time to use sw interrupts and
+ * a probe tasklet !!!
+ */
+static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
+{
+
+ /* Skip if gain calibration is inactive or
+ * we already handle a probe request */
+ if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
+ return;
+
+ /* Send the packet with 2dB below max power as
+ * patent doc suggest */
+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max_pwr - 4,
+ AR5K_PHY_PAPD_PROBE_TXPOWER) |
+ AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
+
+ ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
+
+}
+
+/* Calculate gain_F measurement correction
+ * based on the current step for RF5112 rev. 2 */
+static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
{
u32 mix, step;
u32 *rf;
+ const struct ath5k_gain_opt *go;
+ const struct ath5k_gain_opt_step *g_step;
+ const struct ath5k_rf_reg *rf_regs;
+
+ /* Only RF5112 Rev. 2 supports it */
+ if ((ah->ah_radio != AR5K_RF5112) ||
+ (ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A))
+ return 0;
+
+ go = &rfgain_opt_5112;
+ rf_regs = rf_regs_5112a;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
+
+ g_step = &go->go_step[ah->ah_gain.g_step_idx];
if (ah->ah_rf_banks == NULL)
return 0;
@@ -1165,11 +221,15 @@ static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
rf = ah->ah_rf_banks;
ah->ah_gain.g_f_corr = 0;
- if (ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, false) != 1)
+ /* No VGA (Variable Gain Amplifier) override, skip */
+ if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, false) != 1)
return 0;
- step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 4, 32, 0, false);
- mix = ah->ah_gain.g_step->gos_param[0];
+ /* Mix gain stepping */
+ step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, false);
+
+ /* Mix gain override */
+ mix = g_step->gos_param[0];
switch (mix) {
case 3:
@@ -1189,9 +249,14 @@ static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
return ah->ah_gain.g_f_corr;
}
-static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
+/* Check if current gain_F measurement is in the range of our
+ * power detector windows. If we get a measurement outside range
+ * we know it's not accurate (detectors can't measure anything outside
+ * their detection window) so we must ignore it */
+static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
{
- u32 step, mix, level[4];
+ const struct ath5k_rf_reg *rf_regs;
+ u32 step, mix_ovr, level[4];
u32 *rf;
if (ah->ah_rf_banks == NULL)
@@ -1200,23 +265,33 @@ static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
rf = ah->ah_rf_banks;
if (ah->ah_radio == AR5K_RF5111) {
- step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 6, 37, 0,
- false);
+
+ rf_regs = rf_regs_5111;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
+
+ step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP,
+ false);
+
level[0] = 0;
- level[1] = (step == 0x3f) ? 0x32 : step + 4;
- level[2] = (step != 0x3f) ? 0x40 : level[0];
- level[3] = level[2] + 0x32;
+ level[1] = (step == 63) ? 50 : step + 4;
+ level[2] = (step != 63) ? 64 : level[0];
+ level[3] = level[2] + 50 ;
ah->ah_gain.g_high = level[3] -
- (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
+ (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
ah->ah_gain.g_low = level[0] +
- (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
+ (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
} else {
- mix = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0,
- false);
+
+ rf_regs = rf_regs_5112;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
+
+ mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR,
+ false);
+
level[0] = level[2] = 0;
- if (mix == 1) {
+ if (mix_ovr == 1) {
level[1] = level[3] = 83;
} else {
level[1] = level[3] = 107;
@@ -1230,9 +305,12 @@ static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
ah->ah_gain.g_current <= level[3]);
}
-static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah)
+/* Perform gain_F adjustment by choosing the right set
+ * of parameters from rf gain optimization ladder */
+static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
{
const struct ath5k_gain_opt *go;
+ const struct ath5k_gain_opt_step *g_step;
int ret = 0;
switch (ah->ah_radio) {
@@ -1246,35 +324,39 @@ static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah)
return 0;
}
- ah->ah_gain.g_step = &go->go_step[ah->ah_gain.g_step_idx];
+ g_step = &go->go_step[ah->ah_gain.g_step_idx];
if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
+
+ /* Reached maximum */
if (ah->ah_gain.g_step_idx == 0)
return -1;
+
for (ah->ah_gain.g_target = ah->ah_gain.g_current;
ah->ah_gain.g_target >= ah->ah_gain.g_high &&
ah->ah_gain.g_step_idx > 0;
- ah->ah_gain.g_step =
- &go->go_step[ah->ah_gain.g_step_idx])
+ g_step = &go->go_step[ah->ah_gain.g_step_idx])
ah->ah_gain.g_target -= 2 *
(go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
- ah->ah_gain.g_step->gos_gain);
+ g_step->gos_gain);
ret = 1;
goto done;
}
if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
+
+ /* Reached minimum */
if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
return -2;
+
for (ah->ah_gain.g_target = ah->ah_gain.g_current;
ah->ah_gain.g_target <= ah->ah_gain.g_low &&
ah->ah_gain.g_step_idx < go->go_steps_count-1;
- ah->ah_gain.g_step =
- &go->go_step[ah->ah_gain.g_step_idx])
+ g_step = &go->go_step[ah->ah_gain.g_step_idx])
ah->ah_gain.g_target -= 2 *
(go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
- ah->ah_gain.g_step->gos_gain);
+ g_step->gos_gain);
ret = 2;
goto done;
@@ -1289,468 +371,449 @@ done:
return ret;
}
-/*
- * Read EEPROM Calibration data, modify RF Banks and Initialize RF5111
- */
-static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah,
- struct ieee80211_channel *channel, unsigned int mode)
+/* Main callback for thermal rf gain calibration engine
+ * Check for a new gain reading and schedule an adjustment
+ * if needed.
+ *
+ * TODO: Use sw interrupt to schedule reset if gain_F needs
+ * adjustment */
+enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
{
+ u32 data, type;
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- u32 *rf;
- const unsigned int rf_size = ARRAY_SIZE(rfregs_5111);
- unsigned int i;
- int obdb = -1, bank = -1;
- u32 ee_mode;
-
- AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
-
- rf = ah->ah_rf_banks;
-
- /* Copy values to modify them */
- for (i = 0; i < rf_size; i++) {
- if (rfregs_5111[i].rf_bank >= AR5K_RF5111_INI_RF_MAX_BANKS) {
- ATH5K_ERR(ah->ah_sc, "invalid bank\n");
- return -EINVAL;
- }
- if (bank != rfregs_5111[i].rf_bank) {
- bank = rfregs_5111[i].rf_bank;
- ah->ah_offset[bank] = i;
- }
+ ATH5K_TRACE(ah->ah_sc);
- rf[i] = rfregs_5111[i].rf_value[mode];
- }
+ if (ah->ah_rf_banks == NULL ||
+ ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
+ return AR5K_RFGAIN_INACTIVE;
- /* Modify bank 0 */
- if (channel->hw_value & CHANNEL_2GHZ) {
- if (channel->hw_value & CHANNEL_CCK)
- ee_mode = AR5K_EEPROM_MODE_11B;
- else
- ee_mode = AR5K_EEPROM_MODE_11G;
- obdb = 0;
+ /* No check requested, either engine is inactive
+ * or an adjustment is already requested */
+ if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
+ goto done;
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0],
- ee->ee_ob[ee_mode][obdb], 3, 119, 0, true))
- return -EINVAL;
+ /* Read the PAPD (Peak to Average Power Detector)
+ * register */
+ data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0],
- ee->ee_ob[ee_mode][obdb], 3, 122, 0, true))
- return -EINVAL;
+ /* No probe is scheduled, read gain_F measurement */
+ if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
+ ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
+ type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
- obdb = 1;
- /* Modify bank 6 */
- } else {
- /* For 11a, Turbo and XR */
- ee_mode = AR5K_EEPROM_MODE_11A;
- obdb = channel->center_freq >= 5725 ? 3 :
- (channel->center_freq >= 5500 ? 2 :
- (channel->center_freq >= 5260 ? 1 :
- (channel->center_freq > 4000 ? 0 : -1)));
+ /* If tx packet is CCK correct the gain_F measurement
+ * by cck ofdm gain delta */
+ if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) {
+ if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
+ ah->ah_gain.g_current +=
+ ee->ee_cck_ofdm_gain_delta;
+ else
+ ah->ah_gain.g_current +=
+ AR5K_GAIN_CCK_PROBE_CORR;
+ }
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_pwd_84, 1, 51, 3, true))
- return -EINVAL;
+ /* Further correct gain_F measurement for
+ * RF5112A radios */
+ if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
+ ath5k_hw_rf_gainf_corr(ah);
+ ah->ah_gain.g_current =
+ ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
+ (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
+ 0;
+ }
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_pwd_90, 1, 45, 3, true))
- return -EINVAL;
+ /* Check if measurement is ok and if we need
+ * to adjust gain, schedule a gain adjustment,
+ * else switch back to the acive state */
+ if (ath5k_hw_rf_check_gainf_readback(ah) &&
+ AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
+ ath5k_hw_rf_gainf_adjust(ah)) {
+ ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
+ } else {
+ ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+ }
}
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- !ee->ee_xpd[ee_mode], 1, 95, 0, true))
- return -EINVAL;
-
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_x_gain[ee_mode], 4, 96, 0, true))
- return -EINVAL;
-
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ?
- ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, true))
- return -EINVAL;
+done:
+ return ah->ah_gain.g_state;
+}
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ?
- ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, true))
- return -EINVAL;
+/* Write initial rf gain table to set the RF sensitivity
+ * this one works on all RF chips and has nothing to do
+ * with gain_F calibration */
+int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
+{
+ const struct ath5k_ini_rfgain *ath5k_rfg;
+ unsigned int i, size;
- /* Modify bank 7 */
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
- ee->ee_i_gain[ee_mode], 6, 29, 0, true))
+ switch (ah->ah_radio) {
+ case AR5K_RF5111:
+ ath5k_rfg = rfgain_5111;
+ size = ARRAY_SIZE(rfgain_5111);
+ break;
+ case AR5K_RF5112:
+ ath5k_rfg = rfgain_5112;
+ size = ARRAY_SIZE(rfgain_5112);
+ break;
+ case AR5K_RF2413:
+ ath5k_rfg = rfgain_2413;
+ size = ARRAY_SIZE(rfgain_2413);
+ break;
+ case AR5K_RF2316:
+ ath5k_rfg = rfgain_2316;
+ size = ARRAY_SIZE(rfgain_2316);
+ break;
+ case AR5K_RF5413:
+ ath5k_rfg = rfgain_5413;
+ size = ARRAY_SIZE(rfgain_5413);
+ break;
+ case AR5K_RF2317:
+ case AR5K_RF2425:
+ ath5k_rfg = rfgain_2425;
+ size = ARRAY_SIZE(rfgain_2425);
+ break;
+ default:
return -EINVAL;
+ }
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
- ee->ee_xpd[ee_mode], 1, 4, 0, true))
+ switch (freq) {
+ case AR5K_INI_RFGAIN_2GHZ:
+ case AR5K_INI_RFGAIN_5GHZ:
+ break;
+ default:
return -EINVAL;
+ }
- /* Write RF values */
- for (i = 0; i < rf_size; i++) {
+ for (i = 0; i < size; i++) {
AR5K_REG_WAIT(i);
- ath5k_hw_reg_write(ah, rf[i], rfregs_5111[i].rf_register);
+ ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
+ (u32)ath5k_rfg[i].rfg_register);
}
return 0;
}
+
+
+/********************\
+* RF Registers setup *
+\********************/
+
+
/*
- * Read EEPROM Calibration data, modify RF Banks and Initialize RF5112
+ * Setup RF registers by writing rf buffer on hw
*/
-static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah,
- struct ieee80211_channel *channel, unsigned int mode)
+int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+ unsigned int mode)
{
- const struct ath5k_ini_rf *rf_ini;
+ const struct ath5k_rf_reg *rf_regs;
+ const struct ath5k_ini_rfbuffer *ini_rfb;
+ const struct ath5k_gain_opt *go = NULL;
+ const struct ath5k_gain_opt_step *g_step;
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- u32 *rf;
- unsigned int rf_size, i;
- int obdb = -1, bank = -1;
- u32 ee_mode;
-
- AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
+ u8 ee_mode = 0;
+ u32 *rfb;
+ int i, obdb = -1, bank = -1;
- rf = ah->ah_rf_banks;
+ switch (ah->ah_radio) {
+ case AR5K_RF5111:
+ rf_regs = rf_regs_5111;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
+ ini_rfb = rfb_5111;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111);
+ go = &rfgain_opt_5111;
+ break;
+ case AR5K_RF5112:
+ if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
+ rf_regs = rf_regs_5112a;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
+ ini_rfb = rfb_5112a;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a);
+ } else {
+ rf_regs = rf_regs_5112;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
+ ini_rfb = rfb_5112;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112);
+ }
+ go = &rfgain_opt_5112;
+ break;
+ case AR5K_RF2413:
+ rf_regs = rf_regs_2413;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413);
+ ini_rfb = rfb_2413;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413);
+ break;
+ case AR5K_RF2316:
+ rf_regs = rf_regs_2316;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316);
+ ini_rfb = rfb_2316;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316);
+ break;
+ case AR5K_RF5413:
+ rf_regs = rf_regs_5413;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413);
+ ini_rfb = rfb_5413;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413);
+ break;
+ case AR5K_RF2317:
+ rf_regs = rf_regs_2425;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
+ ini_rfb = rfb_2317;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317);
+ break;
+ case AR5K_RF2425:
+ rf_regs = rf_regs_2425;
+ ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
+ if (ah->ah_mac_srev < AR5K_SREV_AR2417) {
+ ini_rfb = rfb_2425;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425);
+ } else {
+ ini_rfb = rfb_2417;
+ ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417);
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
- if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_2112A
- && !test_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode)) {
- rf_ini = rfregs_2112a;
- rf_size = ARRAY_SIZE(rfregs_5112a);
- if (mode < 2) {
- ATH5K_ERR(ah->ah_sc, "invalid channel mode: %i\n",
- mode);
- return -EINVAL;
+ /* If it's the first time we set rf buffer, allocate
+ * ah->ah_rf_banks based on ah->ah_rf_banks_size
+ * we set above */
+ if (ah->ah_rf_banks == NULL) {
+ ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size,
+ GFP_KERNEL);
+ if (ah->ah_rf_banks == NULL) {
+ ATH5K_ERR(ah->ah_sc, "out of memory\n");
+ return -ENOMEM;
}
- mode = mode - 2; /*no a/turboa modes for 2112*/
- } else if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
- rf_ini = rfregs_5112a;
- rf_size = ARRAY_SIZE(rfregs_5112a);
- } else {
- rf_ini = rfregs_5112;
- rf_size = ARRAY_SIZE(rfregs_5112);
}
/* Copy values to modify them */
- for (i = 0; i < rf_size; i++) {
- if (rf_ini[i].rf_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) {
+ rfb = ah->ah_rf_banks;
+
+ for (i = 0; i < ah->ah_rf_banks_size; i++) {
+ if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) {
ATH5K_ERR(ah->ah_sc, "invalid bank\n");
return -EINVAL;
}
- if (bank != rf_ini[i].rf_bank) {
- bank = rf_ini[i].rf_bank;
+ /* Bank changed, write down the offset */
+ if (bank != ini_rfb[i].rfb_bank) {
+ bank = ini_rfb[i].rfb_bank;
ah->ah_offset[bank] = i;
}
- rf[i] = rf_ini[i].rf_value[mode];
+ rfb[i] = ini_rfb[i].rfb_mode_data[mode];
}
- /* Modify bank 6 */
+ /* Set Output and Driver bias current (OB/DB) */
if (channel->hw_value & CHANNEL_2GHZ) {
- if (channel->hw_value & CHANNEL_OFDM)
+
+ if (channel->hw_value & CHANNEL_CCK)
+ ee_mode = AR5K_EEPROM_MODE_11B;
+ else
ee_mode = AR5K_EEPROM_MODE_11G;
+
+ /* For RF511X/RF211X combination we
+ * use b_OB and b_DB parameters stored
+ * in eeprom on ee->ee_ob[ee_mode][0]
+ *
+ * For all other chips we use OB/DB for 2Ghz
+ * stored in the b/g modal section just like
+ * 802.11a on ee->ee_ob[ee_mode][1] */
+ if ((ah->ah_radio == AR5K_RF5111) ||
+ (ah->ah_radio == AR5K_RF5112))
+ obdb = 0;
else
- ee_mode = AR5K_EEPROM_MODE_11B;
- obdb = 0;
+ obdb = 1;
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_ob[ee_mode][obdb], 3, 287, 0, true))
- return -EINVAL;
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
+ AR5K_RF_OB_2GHZ, true);
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_ob[ee_mode][obdb], 3, 290, 0, true))
- return -EINVAL;
- } else {
- /* For 11a, Turbo and XR */
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
+ AR5K_RF_DB_2GHZ, true);
+
+ /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */
+ } else if ((channel->hw_value & CHANNEL_5GHZ) ||
+ (ah->ah_radio == AR5K_RF5111)) {
+
+ /* For 11a, Turbo and XR we need to choose
+ * OB/DB based on frequency range */
ee_mode = AR5K_EEPROM_MODE_11A;
- obdb = channel->center_freq >= 5725 ? 3 :
- (channel->center_freq >= 5500 ? 2 :
+ obdb = channel->center_freq >= 5725 ? 3 :
+ (channel->center_freq >= 5500 ? 2 :
(channel->center_freq >= 5260 ? 1 :
- (channel->center_freq > 4000 ? 0 : -1)));
+ (channel->center_freq > 4000 ? 0 : -1)));
- if (obdb == -1)
+ if (obdb < 0)
return -EINVAL;
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_ob[ee_mode][obdb], 3, 279, 0, true))
- return -EINVAL;
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
+ AR5K_RF_OB_5GHZ, true);
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_ob[ee_mode][obdb], 3, 282, 0, true))
- return -EINVAL;
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
+ AR5K_RF_DB_5GHZ, true);
}
- ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_x_gain[ee_mode], 2, 270, 0, true);
- ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_x_gain[ee_mode], 2, 257, 0, true);
-
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
- ee->ee_xpd[ee_mode], 1, 302, 0, true))
- return -EINVAL;
+ g_step = &go->go_step[ah->ah_gain.g_step_idx];
- /* Modify bank 7 */
- if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
- ee->ee_i_gain[ee_mode], 6, 14, 0, true))
- return -EINVAL;
+ /* Bank Modifications (chip-specific) */
+ if (ah->ah_radio == AR5K_RF5111) {
- /* Write RF values */
- for (i = 0; i < rf_size; i++)
- ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rf_register);
+ /* Set gain_F settings according to current step */
+ if (channel->hw_value & CHANNEL_OFDM) {
- return 0;
-}
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
+ AR5K_PHY_FRAME_CTL_TX_CLIP,
+ g_step->gos_param[0]);
-/*
- * Initialize RF5413/5414 and future chips
- * (until we come up with a better solution)
- */
-static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah,
- struct ieee80211_channel *channel, unsigned int mode)
-{
- const struct ath5k_ini_rf *rf_ini;
- u32 *rf;
- unsigned int rf_size, i;
- int bank = -1;
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
+ AR5K_RF_PWD_90, true);
- AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX);
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
+ AR5K_RF_PWD_84, true);
- rf = ah->ah_rf_banks;
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
+ AR5K_RF_RFGAIN_SEL, true);
- switch (ah->ah_radio) {
- case AR5K_RF5413:
- rf_ini = rfregs_5413;
- rf_size = ARRAY_SIZE(rfregs_5413);
- break;
- case AR5K_RF2413:
- rf_ini = rfregs_2413;
- rf_size = ARRAY_SIZE(rfregs_2413);
+ /* We programmed gain_F parameters, switch back
+ * to active state */
+ ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
- if (mode < 2) {
- ATH5K_ERR(ah->ah_sc,
- "invalid channel mode: %i\n", mode);
- return -EINVAL;
}
- mode = mode - 2;
- break;
- case AR5K_RF2425:
- rf_ini = rfregs_2425;
- rf_size = ARRAY_SIZE(rfregs_2425);
+ /* Bank 6/7 setup */
- if (mode < 2) {
- ATH5K_ERR(ah->ah_sc,
- "invalid channel mode: %i\n", mode);
- return -EINVAL;
- }
+ ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode],
+ AR5K_RF_PWD_XPD, true);
- /* Map b to g */
- if (mode == 2)
- mode = 0;
- else
- mode = mode - 3;
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode],
+ AR5K_RF_XPD_GAIN, true);
- break;
- default:
- return -EINVAL;
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
+ AR5K_RF_GAIN_I, true);
+
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
+ AR5K_RF_PLO_SEL, true);
+
+ /* TODO: Half/quarter channel support */
}
- /* Copy values to modify them */
- for (i = 0; i < rf_size; i++) {
- if (rf_ini[i].rf_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) {
- ATH5K_ERR(ah->ah_sc, "invalid bank\n");
- return -EINVAL;
- }
+ if (ah->ah_radio == AR5K_RF5112) {
- if (bank != rf_ini[i].rf_bank) {
- bank = rf_ini[i].rf_bank;
- ah->ah_offset[bank] = i;
- }
+ /* Set gain_F settings according to current step */
+ if (channel->hw_value & CHANNEL_OFDM) {
- rf[i] = rf_ini[i].rf_value[mode];
- }
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
+ AR5K_RF_MIXGAIN_OVR, true);
- /*
- * After compairing dumps from different cards
- * we get the same RF_BUFFER settings (diff returns
- * 0 lines). It seems that RF_BUFFER settings are static
- * and are written unmodified (no EEPROM stuff
- * is used because calibration data would be
- * different between different cards and would result
- * different RF_BUFFER settings)
- */
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
+ AR5K_RF_PWD_138, true);
- /* Write RF values */
- for (i = 0; i < rf_size; i++)
- ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rf_register);
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
+ AR5K_RF_PWD_137, true);
- return 0;
-}
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
+ AR5K_RF_PWD_136, true);
-/*
- * Initialize RF
- */
-int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- unsigned int mode)
-{
- int (*func)(struct ath5k_hw *, struct ieee80211_channel *, unsigned int);
- int ret;
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4],
+ AR5K_RF_PWD_132, true);
- switch (ah->ah_radio) {
- case AR5K_RF5111:
- ah->ah_rf_banks_size = sizeof(rfregs_5111);
- func = ath5k_hw_rf5111_rfregs;
- break;
- case AR5K_RF5112:
- if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
- ah->ah_rf_banks_size = sizeof(rfregs_5112a);
- else
- ah->ah_rf_banks_size = sizeof(rfregs_5112);
- func = ath5k_hw_rf5112_rfregs;
- break;
- case AR5K_RF5413:
- ah->ah_rf_banks_size = sizeof(rfregs_5413);
- func = ath5k_hw_rf5413_rfregs;
- break;
- case AR5K_RF2413:
- ah->ah_rf_banks_size = sizeof(rfregs_2413);
- func = ath5k_hw_rf5413_rfregs;
- break;
- case AR5K_RF2425:
- ah->ah_rf_banks_size = sizeof(rfregs_2425);
- func = ath5k_hw_rf5413_rfregs;
- break;
- default:
- return -EINVAL;
- }
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5],
+ AR5K_RF_PWD_131, true);
- if (ah->ah_rf_banks == NULL) {
- /* XXX do extra checks? */
- ah->ah_rf_banks = kmalloc(ah->ah_rf_banks_size, GFP_KERNEL);
- if (ah->ah_rf_banks == NULL) {
- ATH5K_ERR(ah->ah_sc, "out of memory\n");
- return -ENOMEM;
+ ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6],
+ AR5K_RF_PWD_130, true);
+
+ /* We programmed gain_F parameters, switch back
+ * to active state */
+ ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
}
- }
- ret = func(ah, channel, mode);
- if (!ret)
- ah->ah_rf_gain = AR5K_RFGAIN_INACTIVE;
+ /* Bank 6/7 setup */
- return ret;
-}
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
+ AR5K_RF_XPD_SEL, true);
-int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq)
-{
- const struct ath5k_ini_rfgain *ath5k_rfg;
- unsigned int i, size;
+ if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
+ /* Rev. 1 supports only one xpd */
+ ath5k_hw_rfb_op(ah, rf_regs,
+ ee->ee_x_gain[ee_mode],
+ AR5K_RF_XPD_GAIN, true);
- switch (ah->ah_radio) {
- case AR5K_RF5111:
- ath5k_rfg = rfgain_5111;
- size = ARRAY_SIZE(rfgain_5111);
- break;
- case AR5K_RF5112:
- ath5k_rfg = rfgain_5112;
- size = ARRAY_SIZE(rfgain_5112);
- break;
- case AR5K_RF5413:
- ath5k_rfg = rfgain_5413;
- size = ARRAY_SIZE(rfgain_5413);
- break;
- case AR5K_RF2413:
- ath5k_rfg = rfgain_2413;
- size = ARRAY_SIZE(rfgain_2413);
- freq = 0; /* only 2Ghz */
- break;
- case AR5K_RF2425:
- ath5k_rfg = rfgain_2425;
- size = ARRAY_SIZE(rfgain_2425);
- freq = 0; /* only 2Ghz */
- break;
- default:
- return -EINVAL;
- }
+ } else {
+ /* TODO: Set high and low gain bits */
+ ath5k_hw_rfb_op(ah, rf_regs,
+ ee->ee_x_gain[ee_mode],
+ AR5K_RF_PD_GAIN_LO, true);
+ ath5k_hw_rfb_op(ah, rf_regs,
+ ee->ee_x_gain[ee_mode],
+ AR5K_RF_PD_GAIN_HI, true);
- switch (freq) {
- case AR5K_INI_RFGAIN_2GHZ:
- case AR5K_INI_RFGAIN_5GHZ:
- break;
- default:
- return -EINVAL;
- }
+ /* Lower synth voltage on Rev 2 */
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_HIGH_VC_CP, true);
- for (i = 0; i < size; i++) {
- AR5K_REG_WAIT(i);
- ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
- (u32)ath5k_rfg[i].rfg_register);
- }
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_MID_VC_CP, true);
- return 0;
-}
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_LOW_VC_CP, true);
-enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah)
-{
- u32 data, type;
+ ath5k_hw_rfb_op(ah, rf_regs, 2,
+ AR5K_RF_PUSH_UP, true);
- ATH5K_TRACE(ah->ah_sc);
+ /* Decrease power consumption on 5213+ BaseBand */
+ if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+ ath5k_hw_rfb_op(ah, rf_regs, 1,
+ AR5K_RF_PAD2GND, true);
- if (ah->ah_rf_banks == NULL || !ah->ah_gain.g_active ||
- ah->ah_version <= AR5K_AR5211)
- return AR5K_RFGAIN_INACTIVE;
+ ath5k_hw_rfb_op(ah, rf_regs, 1,
+ AR5K_RF_XB2_LVL, true);
- if (ah->ah_rf_gain != AR5K_RFGAIN_READ_REQUESTED)
- goto done;
+ ath5k_hw_rfb_op(ah, rf_regs, 1,
+ AR5K_RF_XB5_LVL, true);
- data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
+ ath5k_hw_rfb_op(ah, rf_regs, 1,
+ AR5K_RF_PWD_167, true);
- if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
- ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
- type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
+ ath5k_hw_rfb_op(ah, rf_regs, 1,
+ AR5K_RF_PWD_166, true);
+ }
+ }
- if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK)
- ah->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR;
+ ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
+ AR5K_RF_GAIN_I, true);
- if (ah->ah_radio >= AR5K_RF5112) {
- ath5k_hw_rfregs_gainf_corr(ah);
- ah->ah_gain.g_current =
- ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
- (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
- 0;
- }
+ /* TODO: Half/quarter channel support */
- if (ath5k_hw_rfregs_gain_readback(ah) &&
- AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
- ath5k_hw_rfregs_gain_adjust(ah))
- ah->ah_rf_gain = AR5K_RFGAIN_NEED_CHANGE;
}
-done:
- return ah->ah_rf_gain;
-}
+ if (ah->ah_radio == AR5K_RF5413 &&
+ channel->hw_value & CHANNEL_2GHZ) {
-int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah)
-{
- /* Initialize the gain optimization values */
- switch (ah->ah_radio) {
- case AR5K_RF5111:
- ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
- ah->ah_gain.g_step =
- &rfgain_opt_5111.go_step[ah->ah_gain.g_step_idx];
- ah->ah_gain.g_low = 20;
- ah->ah_gain.g_high = 35;
- ah->ah_gain.g_active = 1;
- break;
- case AR5K_RF5112:
- ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
- ah->ah_gain.g_step =
- &rfgain_opt_5112.go_step[ah->ah_gain.g_step_idx];
- ah->ah_gain.g_low = 20;
- ah->ah_gain.g_high = 85;
- ah->ah_gain.g_active = 1;
- break;
- default:
- return -EINVAL;
+ ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
+ true);
+
+ /* Set optimum value for early revisions (on pci-e chips) */
+ if (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
+ ah->ah_mac_srev < AR5K_SREV_AR5413)
+ ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3),
+ AR5K_RF_PWD_ICLOBUF_2G, true);
+
+ }
+
+ /* Write RF banks on hw */
+ for (i = 0; i < ah->ah_rf_banks_size; i++) {
+ AR5K_REG_WAIT(i);
+ ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register);
}
return 0;
}
+
/**************************\
PHY/RF channel functions
\**************************/
@@ -2271,13 +1334,8 @@ done:
* as often as I/Q calibration.*/
ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
- /* Request RF gain */
- if (channel->hw_value & CHANNEL_5GHZ) {
- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max,
- AR5K_PHY_PAPD_PROBE_TXPOWER) |
- AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
- ah->ah_rf_gain = AR5K_RFGAIN_READ_REQUESTED;
- }
+ /* Initiate a gain_F calibration */
+ ath5k_hw_request_rfgain_probe(ah);
return 0;
}
@@ -2378,93 +1436,1120 @@ unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
return false; /*XXX: What do we return for 5210 ?*/
}
+
+/****************\
+* TX power setup *
+\****************/
+
+/*
+ * Helper functions
+ */
+
+/*
+ * Do linear interpolation between two given (x, y) points
+ */
+static s16
+ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right,
+ s16 y_left, s16 y_right)
+{
+ s16 ratio, result;
+
+ /* Avoid divide by zero and skip interpolation
+ * if we have the same point */
+ if ((x_left == x_right) || (y_left == y_right))
+ return y_left;
+
+ /*
+ * Since we use ints and not fps, we need to scale up in
+ * order to get a sane ratio value (or else we 'll eg. get
+ * always 1 instead of 1.25, 1.75 etc). We scale up by 100
+ * to have some accuracy both for 0.5 and 0.25 steps.
+ */
+ ratio = ((100 * y_right - 100 * y_left)/(x_right - x_left));
+
+ /* Now scale down to be in range */
+ result = y_left + (ratio * (target - x_left) / 100);
+
+ return result;
+}
+
+/*
+ * Find vertical boundary (min pwr) for the linear PCDAC curve.
+ *
+ * Since we have the top of the curve and we draw the line below
+ * until we reach 1 (1 pcdac step) we need to know which point
+ * (x value) that is so that we don't go below y axis and have negative
+ * pcdac values when creating the curve, or fill the table with zeroes.
+ */
+static s16
+ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
+ const s16 *pwrL, const s16 *pwrR)
+{
+ s8 tmp;
+ s16 min_pwrL, min_pwrR;
+ s16 pwr_i = pwrL[0];
+
+ do {
+ pwr_i--;
+ tmp = (s8) ath5k_get_interpolated_value(pwr_i,
+ pwrL[0], pwrL[1],
+ stepL[0], stepL[1]);
+
+ } while (tmp > 1);
+
+ min_pwrL = pwr_i;
+
+ pwr_i = pwrR[0];
+ do {
+ pwr_i--;
+ tmp = (s8) ath5k_get_interpolated_value(pwr_i,
+ pwrR[0], pwrR[1],
+ stepR[0], stepR[1]);
+
+ } while (tmp > 1);
+
+ min_pwrR = pwr_i;
+
+ /* Keep the right boundary so that it works for both curves */
+ return max(min_pwrL, min_pwrR);
+}
+
+/*
+ * Interpolate (pwr,vpd) points to create a Power to PDADC or a
+ * Power to PCDAC curve.
+ *
+ * Each curve has power on x axis (in 0.5dB units) and PCDAC/PDADC
+ * steps (offsets) on y axis. Power can go up to 31.5dB and max
+ * PCDAC/PDADC step for each curve is 64 but we can write more than
+ * one curves on hw so we can go up to 128 (which is the max step we
+ * can write on the final table).
+ *
+ * We write y values (PCDAC/PDADC steps) on hw.
+ */
+static void
+ath5k_create_power_curve(s16 pmin, s16 pmax,
+ const s16 *pwr, const u8 *vpd,
+ u8 num_points,
+ u8 *vpd_table, u8 type)
+{
+ u8 idx[2] = { 0, 1 };
+ s16 pwr_i = 2*pmin;
+ int i;
+
+ if (num_points < 2)
+ return;
+
+ /* We want the whole line, so adjust boundaries
+ * to cover the entire power range. Note that
+ * power values are already 0.25dB so no need
+ * to multiply pwr_i by 2 */
+ if (type == AR5K_PWRTABLE_LINEAR_PCDAC) {
+ pwr_i = pmin;
+ pmin = 0;
+ pmax = 63;
+ }
+
+ /* Find surrounding turning points (TPs)
+ * and interpolate between them */
+ for (i = 0; (i <= (u16) (pmax - pmin)) &&
+ (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
+
+ /* We passed the right TP, move to the next set of TPs
+ * if we pass the last TP, extrapolate above using the last
+ * two TPs for ratio */
+ if ((pwr_i > pwr[idx[1]]) && (idx[1] < num_points - 1)) {
+ idx[0]++;
+ idx[1]++;
+ }
+
+ vpd_table[i] = (u8) ath5k_get_interpolated_value(pwr_i,
+ pwr[idx[0]], pwr[idx[1]],
+ vpd[idx[0]], vpd[idx[1]]);
+
+ /* Increase by 0.5dB
+ * (0.25 dB units) */
+ pwr_i += 2;
+ }
+}
+
+/*
+ * Get the surrounding per-channel power calibration piers
+ * for a given frequency so that we can interpolate between
+ * them and come up with an apropriate dataset for our current
+ * channel.
+ */
+static void
+ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel,
+ struct ath5k_chan_pcal_info **pcinfo_l,
+ struct ath5k_chan_pcal_info **pcinfo_r)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ struct ath5k_chan_pcal_info *pcinfo;
+ u8 idx_l, idx_r;
+ u8 mode, max, i;
+ u32 target = channel->center_freq;
+
+ idx_l = 0;
+ idx_r = 0;
+
+ if (!(channel->hw_value & CHANNEL_OFDM)) {
+ pcinfo = ee->ee_pwr_cal_b;
+ mode = AR5K_EEPROM_MODE_11B;
+ } else if (channel->hw_value & CHANNEL_2GHZ) {
+ pcinfo = ee->ee_pwr_cal_g;
+ mode = AR5K_EEPROM_MODE_11G;
+ } else {
+ pcinfo = ee->ee_pwr_cal_a;
+ mode = AR5K_EEPROM_MODE_11A;
+ }
+ max = ee->ee_n_piers[mode] - 1;
+
+ /* Frequency is below our calibrated
+ * range. Use the lowest power curve
+ * we have */
+ if (target < pcinfo[0].freq) {
+ idx_l = idx_r = 0;
+ goto done;
+ }
+
+ /* Frequency is above our calibrated
+ * range. Use the highest power curve
+ * we have */
+ if (target > pcinfo[max].freq) {
+ idx_l = idx_r = max;
+ goto done;
+ }
+
+ /* Frequency is inside our calibrated
+ * channel range. Pick the surrounding
+ * calibration piers so that we can
+ * interpolate */
+ for (i = 0; i <= max; i++) {
+
+ /* Frequency matches one of our calibration
+ * piers, no need to interpolate, just use
+ * that calibration pier */
+ if (pcinfo[i].freq == target) {
+ idx_l = idx_r = i;
+ goto done;
+ }
+
+ /* We found a calibration pier that's above
+ * frequency, use this pier and the previous
+ * one to interpolate */
+ if (target < pcinfo[i].freq) {
+ idx_r = i;
+ idx_l = idx_r - 1;
+ goto done;
+ }
+ }
+
+done:
+ *pcinfo_l = &pcinfo[idx_l];
+ *pcinfo_r = &pcinfo[idx_r];
+
+ return;
+}
+
+/*
+ * Get the surrounding per-rate power calibration data
+ * for a given frequency and interpolate between power
+ * values to set max target power supported by hw for
+ * each rate.
+ */
+static void
+ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel,
+ struct ath5k_rate_pcal_info *rates)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ struct ath5k_rate_pcal_info *rpinfo;
+ u8 idx_l, idx_r;
+ u8 mode, max, i;
+ u32 target = channel->center_freq;
+
+ idx_l = 0;
+ idx_r = 0;
+
+ if (!(channel->hw_value & CHANNEL_OFDM)) {
+ rpinfo = ee->ee_rate_tpwr_b;
+ mode = AR5K_EEPROM_MODE_11B;
+ } else if (channel->hw_value & CHANNEL_2GHZ) {
+ rpinfo = ee->ee_rate_tpwr_g;
+ mode = AR5K_EEPROM_MODE_11G;
+ } else {
+ rpinfo = ee->ee_rate_tpwr_a;
+ mode = AR5K_EEPROM_MODE_11A;
+ }
+ max = ee->ee_rate_target_pwr_num[mode] - 1;
+
+ /* Get the surrounding calibration
+ * piers - same as above */
+ if (target < rpinfo[0].freq) {
+ idx_l = idx_r = 0;
+ goto done;
+ }
+
+ if (target > rpinfo[max].freq) {
+ idx_l = idx_r = max;
+ goto done;
+ }
+
+ for (i = 0; i <= max; i++) {
+
+ if (rpinfo[i].freq == target) {
+ idx_l = idx_r = i;
+ goto done;
+ }
+
+ if (target < rpinfo[i].freq) {
+ idx_r = i;
+ idx_l = idx_r - 1;
+ goto done;
+ }
+ }
+
+done:
+ /* Now interpolate power value, based on the frequency */
+ rates->freq = target;
+
+ rates->target_power_6to24 =
+ ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+ rpinfo[idx_r].freq,
+ rpinfo[idx_l].target_power_6to24,
+ rpinfo[idx_r].target_power_6to24);
+
+ rates->target_power_36 =
+ ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+ rpinfo[idx_r].freq,
+ rpinfo[idx_l].target_power_36,
+ rpinfo[idx_r].target_power_36);
+
+ rates->target_power_48 =
+ ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+ rpinfo[idx_r].freq,
+ rpinfo[idx_l].target_power_48,
+ rpinfo[idx_r].target_power_48);
+
+ rates->target_power_54 =
+ ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+ rpinfo[idx_r].freq,
+ rpinfo[idx_l].target_power_54,
+ rpinfo[idx_r].target_power_54);
+}
+
+/*
+ * Get the max edge power for this channel if
+ * we have such data from EEPROM's Conformance Test
+ * Limits (CTL), and limit max power if needed.
+ *
+ * FIXME: Only works for world regulatory domains
+ */
+static void
+ath5k_get_max_ctl_power(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ struct ath5k_edge_power *rep = ee->ee_ctl_pwr;
+ u8 *ctl_val = ee->ee_ctl;
+ s16 max_chan_pwr = ah->ah_txpower.txp_max_pwr / 4;
+ s16 edge_pwr = 0;
+ u8 rep_idx;
+ u8 i, ctl_mode;
+ u8 ctl_idx = 0xFF;
+ u32 target = channel->center_freq;
+
+ /* Find out a CTL for our mode that's not mapped
+ * on a specific reg domain.
+ *
+ * TODO: Map our current reg domain to one of the 3 available
+ * reg domain ids so that we can support more CTLs. */
+ switch (channel->hw_value & CHANNEL_MODES) {
+ case CHANNEL_A:
+ ctl_mode = AR5K_CTL_11A | AR5K_CTL_NO_REGDOMAIN;
+ break;
+ case CHANNEL_G:
+ ctl_mode = AR5K_CTL_11G | AR5K_CTL_NO_REGDOMAIN;
+ break;
+ case CHANNEL_B:
+ ctl_mode = AR5K_CTL_11B | AR5K_CTL_NO_REGDOMAIN;
+ break;
+ case CHANNEL_T:
+ ctl_mode = AR5K_CTL_TURBO | AR5K_CTL_NO_REGDOMAIN;
+ break;
+ case CHANNEL_TG:
+ ctl_mode = AR5K_CTL_TURBOG | AR5K_CTL_NO_REGDOMAIN;
+ break;
+ case CHANNEL_XR:
+ /* Fall through */
+ default:
+ return;
+ }
+
+ for (i = 0; i < ee->ee_ctls; i++) {
+ if (ctl_val[i] == ctl_mode) {
+ ctl_idx = i;
+ break;
+ }
+ }
+
+ /* If we have a CTL dataset available grab it and find the
+ * edge power for our frequency */
+ if (ctl_idx == 0xFF)
+ return;
+
+ /* Edge powers are sorted by frequency from lower
+ * to higher. Each CTL corresponds to 8 edge power
+ * measurements. */
+ rep_idx = ctl_idx * AR5K_EEPROM_N_EDGES;
+
+ /* Don't do boundaries check because we
+ * might have more that one bands defined
+ * for this mode */
+
+ /* Get the edge power that's closer to our
+ * frequency */
+ for (i = 0; i < AR5K_EEPROM_N_EDGES; i++) {
+ rep_idx += i;
+ if (target <= rep[rep_idx].freq)
+ edge_pwr = (s16) rep[rep_idx].edge;
+ }
+
+ if (edge_pwr)
+ ah->ah_txpower.txp_max_pwr = 4*min(edge_pwr, max_chan_pwr);
+}
+
+
/*
- * TX power setup
+ * Power to PCDAC table functions
+ */
+
+/*
+ * Fill Power to PCDAC table on RF5111
+ *
+ * No further processing is needed for RF5111, the only thing we have to
+ * do is fill the values below and above calibration range since eeprom data
+ * may not cover the entire PCDAC table.
*/
+static void
+ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min,
+ s16 *table_max)
+{
+ u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
+ u8 *pcdac_tmp = ah->ah_txpower.tmpL[0];
+ u8 pcdac_0, pcdac_n, pcdac_i, pwr_idx, i;
+ s16 min_pwr, max_pwr;
+
+ /* Get table boundaries */
+ min_pwr = table_min[0];
+ pcdac_0 = pcdac_tmp[0];
+
+ max_pwr = table_max[0];
+ pcdac_n = pcdac_tmp[table_max[0] - table_min[0]];
+
+ /* Extrapolate below minimum using pcdac_0 */
+ pcdac_i = 0;
+ for (i = 0; i < min_pwr; i++)
+ pcdac_out[pcdac_i++] = pcdac_0;
+
+ /* Copy values from pcdac_tmp */
+ pwr_idx = min_pwr;
+ for (i = 0 ; pwr_idx <= max_pwr &&
+ pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) {
+ pcdac_out[pcdac_i++] = pcdac_tmp[i];
+ pwr_idx++;
+ }
+
+ /* Extrapolate above maximum */
+ while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE)
+ pcdac_out[pcdac_i++] = pcdac_n;
+
+}
/*
- * Initialize the tx power table (not fully implemented)
+ * Combine available XPD Curves and fill Linear Power to PCDAC table
+ * on RF5112
+ *
+ * RFX112 can have up to 2 curves (one for low txpower range and one for
+ * higher txpower range). We need to put them both on pcdac_out and place
+ * them in the correct location. In case we only have one curve available
+ * just fit it on pcdac_out (it's supposed to cover the entire range of
+ * available pwr levels since it's always the higher power curve). Extrapolate
+ * below and above final table if needed.
*/
-static void ath5k_txpower_table(struct ath5k_hw *ah,
- struct ieee80211_channel *channel, s16 max_power)
+static void
+ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
+ s16 *table_max, u8 pdcurves)
{
- unsigned int i, min, max, n;
- u16 txpower, *rates;
-
- rates = ah->ah_txpower.txp_rates;
-
- txpower = AR5K_TUNE_DEFAULT_TXPOWER * 2;
- if (max_power > txpower)
- txpower = max_power > AR5K_TUNE_MAX_TXPOWER ?
- AR5K_TUNE_MAX_TXPOWER : max_power;
-
- for (i = 0; i < AR5K_MAX_RATES; i++)
- rates[i] = txpower;
-
- /* XXX setup target powers by rate */
-
- ah->ah_txpower.txp_min = rates[7];
- ah->ah_txpower.txp_max = rates[0];
- ah->ah_txpower.txp_ofdm = rates[0];
-
- /* Calculate the power table */
- n = ARRAY_SIZE(ah->ah_txpower.txp_pcdac);
- min = AR5K_EEPROM_PCDAC_START;
- max = AR5K_EEPROM_PCDAC_STOP;
- for (i = 0; i < n; i += AR5K_EEPROM_PCDAC_STEP)
- ah->ah_txpower.txp_pcdac[i] =
-#ifdef notyet
- min + ((i * (max - min)) / n);
-#else
- min;
+ u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
+ u8 *pcdac_low_pwr;
+ u8 *pcdac_high_pwr;
+ u8 *pcdac_tmp;
+ u8 pwr;
+ s16 max_pwr_idx;
+ s16 min_pwr_idx;
+ s16 mid_pwr_idx = 0;
+ /* Edge flag turs on the 7nth bit on the PCDAC
+ * to delcare the higher power curve (force values
+ * to be greater than 64). If we only have one curve
+ * we don't need to set this, if we have 2 curves and
+ * fill the table backwards this can also be used to
+ * switch from higher power curve to lower power curve */
+ u8 edge_flag;
+ int i;
+
+ /* When we have only one curve available
+ * that's the higher power curve. If we have
+ * two curves the first is the high power curve
+ * and the next is the low power curve. */
+ if (pdcurves > 1) {
+ pcdac_low_pwr = ah->ah_txpower.tmpL[1];
+ pcdac_high_pwr = ah->ah_txpower.tmpL[0];
+ mid_pwr_idx = table_max[1] - table_min[1] - 1;
+ max_pwr_idx = (table_max[0] - table_min[0]) / 2;
+
+ /* If table size goes beyond 31.5dB, keep the
+ * upper 31.5dB range when setting tx power.
+ * Note: 126 = 31.5 dB in quarter dB steps */
+ if (table_max[0] - table_min[1] > 126)
+ min_pwr_idx = table_max[0] - 126;
+ else
+ min_pwr_idx = table_min[1];
+
+ /* Since we fill table backwards
+ * start from high power curve */
+ pcdac_tmp = pcdac_high_pwr;
+
+ edge_flag = 0x40;
+#if 0
+ /* If both min and max power limits are in lower
+ * power curve's range, only use the low power curve.
+ * TODO: min/max levels are related to target
+ * power values requested from driver/user
+ * XXX: Is this really needed ? */
+ if (min_pwr < table_max[1] &&
+ max_pwr < table_max[1]) {
+ edge_flag = 0;
+ pcdac_tmp = pcdac_low_pwr;
+ max_pwr_idx = (table_max[1] - table_min[1])/2;
+ }
#endif
+ } else {
+ pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */
+ pcdac_high_pwr = ah->ah_txpower.tmpL[0];
+ min_pwr_idx = table_min[0];
+ max_pwr_idx = (table_max[0] - table_min[0]) / 2;
+ pcdac_tmp = pcdac_high_pwr;
+ edge_flag = 0;
+ }
+
+ /* This is used when setting tx power*/
+ ah->ah_txpower.txp_min_idx = min_pwr_idx/2;
+
+ /* Fill Power to PCDAC table backwards */
+ pwr = max_pwr_idx;
+ for (i = 63; i >= 0; i--) {
+ /* Entering lower power range, reset
+ * edge flag and set pcdac_tmp to lower
+ * power curve.*/
+ if (edge_flag == 0x40 &&
+ (2*pwr <= (table_max[1] - table_min[0]) || pwr == 0)) {
+ edge_flag = 0x00;
+ pcdac_tmp = pcdac_low_pwr;
+ pwr = mid_pwr_idx/2;
+ }
+
+ /* Don't go below 1, extrapolate below if we have
+ * already swithced to the lower power curve -or
+ * we only have one curve and edge_flag is zero
+ * anyway */
+ if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) {
+ while (i >= 0) {
+ pcdac_out[i] = pcdac_out[i + 1];
+ i--;
+ }
+ break;
+ }
+
+ pcdac_out[i] = pcdac_tmp[pwr] | edge_flag;
+
+ /* Extrapolate above if pcdac is greater than
+ * 126 -this can happen because we OR pcdac_out
+ * value with edge_flag on high power curve */
+ if (pcdac_out[i] > 126)
+ pcdac_out[i] = 126;
+
+ /* Decrease by a 0.5dB step */
+ pwr--;
+ }
+}
+
+/* Write PCDAC values on hw */
+static void
+ath5k_setup_pcdac_table(struct ath5k_hw *ah)
+{
+ u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
+ int i;
+
+ /*
+ * Write TX power values
+ */
+ for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
+ ath5k_hw_reg_write(ah,
+ (((pcdac_out[2*i + 0] << 8 | 0xff) & 0xffff) << 0) |
+ (((pcdac_out[2*i + 1] << 8 | 0xff) & 0xffff) << 16),
+ AR5K_PHY_PCDAC_TXPOWER(i));
+ }
}
+
/*
- * Set transmition power
+ * Power to PDADC table functions
*/
-int /*O.K. - txpower_table is unimplemented so this doesn't work*/
-ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- unsigned int txpower)
+
+/*
+ * Set the gain boundaries and create final Power to PDADC table
+ *
+ * We can have up to 4 pd curves, we need to do a simmilar process
+ * as we do for RF5112. This time we don't have an edge_flag but we
+ * set the gain boundaries on a separate register.
+ */
+static void
+ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
+ s16 *pwr_min, s16 *pwr_max, u8 pdcurves)
{
- bool tpc = ah->ah_txpower.txp_tpc;
- unsigned int i;
+ u8 gain_boundaries[AR5K_EEPROM_N_PD_GAINS];
+ u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
+ u8 *pdadc_tmp;
+ s16 pdadc_0;
+ u8 pdadc_i, pdadc_n, pwr_step, pdg, max_idx, table_size;
+ u8 pd_gain_overlap;
+
+ /* Note: Register value is initialized on initvals
+ * there is no feedback from hw.
+ * XXX: What about pd_gain_overlap from EEPROM ? */
+ pd_gain_overlap = (u8) ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG5) &
+ AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP;
+
+ /* Create final PDADC table */
+ for (pdg = 0, pdadc_i = 0; pdg < pdcurves; pdg++) {
+ pdadc_tmp = ah->ah_txpower.tmpL[pdg];
+
+ if (pdg == pdcurves - 1)
+ /* 2 dB boundary stretch for last
+ * (higher power) curve */
+ gain_boundaries[pdg] = pwr_max[pdg] + 4;
+ else
+ /* Set gain boundary in the middle
+ * between this curve and the next one */
+ gain_boundaries[pdg] =
+ (pwr_max[pdg] + pwr_min[pdg + 1]) / 2;
+
+ /* Sanity check in case our 2 db stretch got out of
+ * range. */
+ if (gain_boundaries[pdg] > AR5K_TUNE_MAX_TXPOWER)
+ gain_boundaries[pdg] = AR5K_TUNE_MAX_TXPOWER;
+
+ /* For the first curve (lower power)
+ * start from 0 dB */
+ if (pdg == 0)
+ pdadc_0 = 0;
+ else
+ /* For the other curves use the gain overlap */
+ pdadc_0 = (gain_boundaries[pdg - 1] - pwr_min[pdg]) -
+ pd_gain_overlap;
- ATH5K_TRACE(ah->ah_sc);
- if (txpower > AR5K_TUNE_MAX_TXPOWER) {
- ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
- return -EINVAL;
+ /* Force each power step to be at least 0.5 dB */
+ if ((pdadc_tmp[1] - pdadc_tmp[0]) > 1)
+ pwr_step = pdadc_tmp[1] - pdadc_tmp[0];
+ else
+ pwr_step = 1;
+
+ /* If pdadc_0 is negative, we need to extrapolate
+ * below this pdgain by a number of pwr_steps */
+ while ((pdadc_0 < 0) && (pdadc_i < 128)) {
+ s16 tmp = pdadc_tmp[0] + pdadc_0 * pwr_step;
+ pdadc_out[pdadc_i++] = (tmp < 0) ? 0 : (u8) tmp;
+ pdadc_0++;
+ }
+
+ /* Set last pwr level, using gain boundaries */
+ pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg];
+ /* Limit it to be inside pwr range */
+ table_size = pwr_max[pdg] - pwr_min[pdg];
+ max_idx = (pdadc_n < table_size) ? pdadc_n : table_size;
+
+ /* Fill pdadc_out table */
+ while (pdadc_0 < max_idx)
+ pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++];
+
+ /* Need to extrapolate above this pdgain? */
+ if (pdadc_n <= max_idx)
+ continue;
+
+ /* Force each power step to be at least 0.5 dB */
+ if ((pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]) > 1)
+ pwr_step = pdadc_tmp[table_size - 1] -
+ pdadc_tmp[table_size - 2];
+ else
+ pwr_step = 1;
+
+ /* Extrapolate above */
+ while ((pdadc_0 < (s16) pdadc_n) &&
+ (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2)) {
+ s16 tmp = pdadc_tmp[table_size - 1] +
+ (pdadc_0 - max_idx) * pwr_step;
+ pdadc_out[pdadc_i++] = (tmp > 127) ? 127 : (u8) tmp;
+ pdadc_0++;
+ }
+ }
+
+ while (pdg < AR5K_EEPROM_N_PD_GAINS) {
+ gain_boundaries[pdg] = gain_boundaries[pdg - 1];
+ pdg++;
+ }
+
+ while (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2) {
+ pdadc_out[pdadc_i] = pdadc_out[pdadc_i - 1];
+ pdadc_i++;
}
+ /* Set gain boundaries */
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_SM(pd_gain_overlap,
+ AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP) |
+ AR5K_REG_SM(gain_boundaries[0],
+ AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1) |
+ AR5K_REG_SM(gain_boundaries[1],
+ AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2) |
+ AR5K_REG_SM(gain_boundaries[2],
+ AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3) |
+ AR5K_REG_SM(gain_boundaries[3],
+ AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4),
+ AR5K_PHY_TPC_RG5);
+
+ /* Used for setting rate power table */
+ ah->ah_txpower.txp_min_idx = pwr_min[0];
+
+}
+
+/* Write PDADC values on hw */
+static void
+ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah,
+ u8 pdcurves, u8 *pdg_to_idx)
+{
+ u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
+ u32 reg;
+ u8 i;
+
+ /* Select the right pdgain curves */
+
+ /* Clear current settings */
+ reg = ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG1);
+ reg &= ~(AR5K_PHY_TPC_RG1_PDGAIN_1 |
+ AR5K_PHY_TPC_RG1_PDGAIN_2 |
+ AR5K_PHY_TPC_RG1_PDGAIN_3 |
+ AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
+
/*
- * RF2413 for some reason can't
- * transmit anything if we call
- * this funtion, so we skip it
- * until we fix txpower.
+ * Use pd_gains curve from eeprom
*
- * XXX: Assume same for RF2425
- * to be safe.
+ * This overrides the default setting from initvals
+ * in case some vendors (e.g. Zcomax) don't use the default
+ * curves. If we don't honor their settings we 'll get a
+ * 5dB (1 * gain overlap ?) drop.
*/
- if ((ah->ah_radio == AR5K_RF2413) || (ah->ah_radio == AR5K_RF2425))
- return 0;
-
- /* Reset TX power values */
- memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
- ah->ah_txpower.txp_tpc = tpc;
+ reg |= AR5K_REG_SM(pdcurves, AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
- /* Initialize TX power table */
- ath5k_txpower_table(ah, channel, txpower);
+ switch (pdcurves) {
+ case 3:
+ reg |= AR5K_REG_SM(pdg_to_idx[2], AR5K_PHY_TPC_RG1_PDGAIN_3);
+ /* Fall through */
+ case 2:
+ reg |= AR5K_REG_SM(pdg_to_idx[1], AR5K_PHY_TPC_RG1_PDGAIN_2);
+ /* Fall through */
+ case 1:
+ reg |= AR5K_REG_SM(pdg_to_idx[0], AR5K_PHY_TPC_RG1_PDGAIN_1);
+ break;
+ }
+ ath5k_hw_reg_write(ah, reg, AR5K_PHY_TPC_RG1);
/*
* Write TX power values
*/
for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
ath5k_hw_reg_write(ah,
- ((((ah->ah_txpower.txp_pcdac[(i << 1) + 1] << 8) | 0xff) & 0xffff) << 16) |
- (((ah->ah_txpower.txp_pcdac[(i << 1) ] << 8) | 0xff) & 0xffff),
- AR5K_PHY_PCDAC_TXPOWER(i));
+ ((pdadc_out[4*i + 0] & 0xff) << 0) |
+ ((pdadc_out[4*i + 1] & 0xff) << 8) |
+ ((pdadc_out[4*i + 2] & 0xff) << 16) |
+ ((pdadc_out[4*i + 3] & 0xff) << 24),
+ AR5K_PHY_PDADC_TXPOWER(i));
+ }
+}
+
+
+/*
+ * Common code for PCDAC/PDADC tables
+ */
+
+/*
+ * This is the main function that uses all of the above
+ * to set PCDAC/PDADC table on hw for the current channel.
+ * This table is used for tx power calibration on the basband,
+ * without it we get weird tx power levels and in some cases
+ * distorted spectral mask
+ */
+static int
+ath5k_setup_channel_powertable(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel,
+ u8 ee_mode, u8 type)
+{
+ struct ath5k_pdgain_info *pdg_L, *pdg_R;
+ struct ath5k_chan_pcal_info *pcinfo_L;
+ struct ath5k_chan_pcal_info *pcinfo_R;
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
+ s16 table_min[AR5K_EEPROM_N_PD_GAINS];
+ s16 table_max[AR5K_EEPROM_N_PD_GAINS];
+ u8 *tmpL;
+ u8 *tmpR;
+ u32 target = channel->center_freq;
+ int pdg, i;
+
+ /* Get surounding freq piers for this channel */
+ ath5k_get_chan_pcal_surrounding_piers(ah, channel,
+ &pcinfo_L,
+ &pcinfo_R);
+
+ /* Loop over pd gain curves on
+ * surounding freq piers by index */
+ for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) {
+
+ /* Fill curves in reverse order
+ * from lower power (max gain)
+ * to higher power. Use curve -> idx
+ * backmaping we did on eeprom init */
+ u8 idx = pdg_curve_to_idx[pdg];
+
+ /* Grab the needed curves by index */
+ pdg_L = &pcinfo_L->pd_curves[idx];
+ pdg_R = &pcinfo_R->pd_curves[idx];
+
+ /* Initialize the temp tables */
+ tmpL = ah->ah_txpower.tmpL[pdg];
+ tmpR = ah->ah_txpower.tmpR[pdg];
+
+ /* Set curve's x boundaries and create
+ * curves so that they cover the same
+ * range (if we don't do that one table
+ * will have values on some range and the
+ * other one won't have any so interpolation
+ * will fail) */
+ table_min[pdg] = min(pdg_L->pd_pwr[0],
+ pdg_R->pd_pwr[0]) / 2;
+
+ table_max[pdg] = max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
+ pdg_R->pd_pwr[pdg_R->pd_points - 1]) / 2;
+
+ /* Now create the curves on surrounding channels
+ * and interpolate if needed to get the final
+ * curve for this gain on this channel */
+ switch (type) {
+ case AR5K_PWRTABLE_LINEAR_PCDAC:
+ /* Override min/max so that we don't loose
+ * accuracy (don't divide by 2) */
+ table_min[pdg] = min(pdg_L->pd_pwr[0],
+ pdg_R->pd_pwr[0]);
+
+ table_max[pdg] =
+ max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
+ pdg_R->pd_pwr[pdg_R->pd_points - 1]);
+
+ /* Override minimum so that we don't get
+ * out of bounds while extrapolating
+ * below. Don't do this when we have 2
+ * curves and we are on the high power curve
+ * because table_min is ok in this case */
+ if (!(ee->ee_pd_gains[ee_mode] > 1 && pdg == 0)) {
+
+ table_min[pdg] =
+ ath5k_get_linear_pcdac_min(pdg_L->pd_step,
+ pdg_R->pd_step,
+ pdg_L->pd_pwr,
+ pdg_R->pd_pwr);
+
+ /* Don't go too low because we will
+ * miss the upper part of the curve.
+ * Note: 126 = 31.5dB (max power supported)
+ * in 0.25dB units */
+ if (table_max[pdg] - table_min[pdg] > 126)
+ table_min[pdg] = table_max[pdg] - 126;
+ }
+
+ /* Fall through */
+ case AR5K_PWRTABLE_PWR_TO_PCDAC:
+ case AR5K_PWRTABLE_PWR_TO_PDADC:
+
+ ath5k_create_power_curve(table_min[pdg],
+ table_max[pdg],
+ pdg_L->pd_pwr,
+ pdg_L->pd_step,
+ pdg_L->pd_points, tmpL, type);
+
+ /* We are in a calibration
+ * pier, no need to interpolate
+ * between freq piers */
+ if (pcinfo_L == pcinfo_R)
+ continue;
+
+ ath5k_create_power_curve(table_min[pdg],
+ table_max[pdg],
+ pdg_R->pd_pwr,
+ pdg_R->pd_step,
+ pdg_R->pd_points, tmpR, type);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Interpolate between curves
+ * of surounding freq piers to
+ * get the final curve for this
+ * pd gain. Re-use tmpL for interpolation
+ * output */
+ for (i = 0; (i < (u16) (table_max[pdg] - table_min[pdg])) &&
+ (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
+ tmpL[i] = (u8) ath5k_get_interpolated_value(target,
+ (s16) pcinfo_L->freq,
+ (s16) pcinfo_R->freq,
+ (s16) tmpL[i],
+ (s16) tmpR[i]);
+ }
+ }
+
+ /* Now we have a set of curves for this
+ * channel on tmpL (x range is table_max - table_min
+ * and y values are tmpL[pdg][]) sorted in the same
+ * order as EEPROM (because we've used the backmaping).
+ * So for RF5112 it's from higher power to lower power
+ * and for RF2413 it's from lower power to higher power.
+ * For RF5111 we only have one curve. */
+
+ /* Fill min and max power levels for this
+ * channel by interpolating the values on
+ * surounding channels to complete the dataset */
+ ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target,
+ (s16) pcinfo_L->freq,
+ (s16) pcinfo_R->freq,
+ pcinfo_L->min_pwr, pcinfo_R->min_pwr);
+
+ ah->ah_txpower.txp_max_pwr = ath5k_get_interpolated_value(target,
+ (s16) pcinfo_L->freq,
+ (s16) pcinfo_R->freq,
+ pcinfo_L->max_pwr, pcinfo_R->max_pwr);
+
+ /* We are ready to go, fill PCDAC/PDADC
+ * table and write settings on hardware */
+ switch (type) {
+ case AR5K_PWRTABLE_LINEAR_PCDAC:
+ /* For RF5112 we can have one or two curves
+ * and each curve covers a certain power lvl
+ * range so we need to do some more processing */
+ ath5k_combine_linear_pcdac_curves(ah, table_min, table_max,
+ ee->ee_pd_gains[ee_mode]);
+
+ /* Set txp.offset so that we can
+ * match max power value with max
+ * table index */
+ ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
+
+ /* Write settings on hw */
+ ath5k_setup_pcdac_table(ah);
+ break;
+ case AR5K_PWRTABLE_PWR_TO_PCDAC:
+ /* We are done for RF5111 since it has only
+ * one curve, just fit the curve on the table */
+ ath5k_fill_pwr_to_pcdac_table(ah, table_min, table_max);
+
+ /* No rate powertable adjustment for RF5111 */
+ ah->ah_txpower.txp_min_idx = 0;
+ ah->ah_txpower.txp_offset = 0;
+
+ /* Write settings on hw */
+ ath5k_setup_pcdac_table(ah);
+ break;
+ case AR5K_PWRTABLE_PWR_TO_PDADC:
+ /* Set PDADC boundaries and fill
+ * final PDADC table */
+ ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
+ ee->ee_pd_gains[ee_mode]);
+
+ /* Write settings on hw */
+ ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx);
+
+ /* Set txp.offset, note that table_min
+ * can be negative */
+ ah->ah_txpower.txp_offset = table_min[0];
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Per-rate tx power setting
+ *
+ * This is the code that sets the desired tx power (below
+ * maximum) on hw for each rate (we also have TPC that sets
+ * power per packet). We do that by providing an index on the
+ * PCDAC/PDADC table we set up.
+ */
+
+/*
+ * Set rate power table
+ *
+ * For now we only limit txpower based on maximum tx power
+ * supported by hw (what's inside rate_info). We need to limit
+ * this even more, based on regulatory domain etc.
+ *
+ * Rate power table contains indices to PCDAC/PDADC table (0.5dB steps)
+ * and is indexed as follows:
+ * rates[0] - rates[7] -> OFDM rates
+ * rates[8] - rates[14] -> CCK rates
+ * rates[15] -> XR rates (they all have the same power)
+ */
+static void
+ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
+ struct ath5k_rate_pcal_info *rate_info,
+ u8 ee_mode)
+{
+ unsigned int i;
+ u16 *rates;
+
+ /* max_pwr is power level we got from driver/user in 0.5dB
+ * units, switch to 0.25dB units so we can compare */
+ max_pwr *= 2;
+ max_pwr = min(max_pwr, (u16) ah->ah_txpower.txp_max_pwr) / 2;
+
+ /* apply rate limits */
+ rates = ah->ah_txpower.txp_rates_power_table;
+
+ /* OFDM rates 6 to 24Mb/s */
+ for (i = 0; i < 5; i++)
+ rates[i] = min(max_pwr, rate_info->target_power_6to24);
+
+ /* Rest OFDM rates */
+ rates[5] = min(rates[0], rate_info->target_power_36);
+ rates[6] = min(rates[0], rate_info->target_power_48);
+ rates[7] = min(rates[0], rate_info->target_power_54);
+
+ /* CCK rates */
+ /* 1L */
+ rates[8] = min(rates[0], rate_info->target_power_6to24);
+ /* 2L */
+ rates[9] = min(rates[0], rate_info->target_power_36);
+ /* 2S */
+ rates[10] = min(rates[0], rate_info->target_power_36);
+ /* 5L */
+ rates[11] = min(rates[0], rate_info->target_power_48);
+ /* 5S */
+ rates[12] = min(rates[0], rate_info->target_power_48);
+ /* 11L */
+ rates[13] = min(rates[0], rate_info->target_power_54);
+ /* 11S */
+ rates[14] = min(rates[0], rate_info->target_power_54);
+
+ /* XR rates */
+ rates[15] = min(rates[0], rate_info->target_power_6to24);
+
+ /* CCK rates have different peak to average ratio
+ * so we have to tweak their power so that gainf
+ * correction works ok. For this we use OFDM to
+ * CCK delta from eeprom */
+ if ((ee_mode == AR5K_EEPROM_MODE_11G) &&
+ (ah->ah_phy_revision < AR5K_SREV_PHY_5212A))
+ for (i = 8; i <= 15; i++)
+ rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
+
+ ah->ah_txpower.txp_min_pwr = rates[7];
+ ah->ah_txpower.txp_max_pwr = rates[0];
+ ah->ah_txpower.txp_ofdm = rates[7];
+}
+
+
+/*
+ * Set transmition power
+ */
+int
+ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+ u8 ee_mode, u8 txpower)
+{
+ struct ath5k_rate_pcal_info rate_info;
+ u8 type;
+ int ret;
+
+ ATH5K_TRACE(ah->ah_sc);
+ if (txpower > AR5K_TUNE_MAX_TXPOWER) {
+ ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
+ return -EINVAL;
+ }
+ if (txpower == 0)
+ txpower = AR5K_TUNE_DEFAULT_TXPOWER;
+
+ /* Reset TX power values */
+ memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
+ ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
+ ah->ah_txpower.txp_min_pwr = 0;
+ ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;
+
+ /* Initialize TX power table */
+ switch (ah->ah_radio) {
+ case AR5K_RF5111:
+ type = AR5K_PWRTABLE_PWR_TO_PCDAC;
+ break;
+ case AR5K_RF5112:
+ type = AR5K_PWRTABLE_LINEAR_PCDAC;
+ break;
+ case AR5K_RF2413:
+ case AR5K_RF5413:
+ case AR5K_RF2316:
+ case AR5K_RF2317:
+ case AR5K_RF2425:
+ type = AR5K_PWRTABLE_PWR_TO_PDADC;
+ break;
+ default:
+ return -EINVAL;
}
+ /* FIXME: Only on channel/mode change */
+ ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type);
+ if (ret)
+ return ret;
+
+ /* Limit max power if we have a CTL available */
+ ath5k_get_max_ctl_power(ah, channel);
+
+ /* FIXME: Tx power limit for this regdomain
+ * XXX: Mac80211/CRDA will do that anyway ? */
+
+ /* FIXME: Antenna reduction stuff */
+
+ /* FIXME: Limit power on turbo modes */
+
+ /* FIXME: TPC scale reduction */
+
+ /* Get surounding channels for per-rate power table
+ * calibration */
+ ath5k_get_rate_pcal_data(ah, channel, &rate_info);
+
+ /* Setup rate power table */
+ ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode);
+
+ /* Write rate power table on hw */
ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) |
AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) |
AR5K_TXPOWER_OFDM(0, 0), AR5K_PHY_TXPOWER_RATE1);
@@ -2481,26 +2566,34 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4);
- if (ah->ah_txpower.txp_tpc)
+ /* FIXME: TPC support */
+ if (ah->ah_txpower.txp_tpc) {
ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
- else
+
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_ACK) |
+ AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CTS) |
+ AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP),
+ AR5K_TPC);
+ } else {
ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX |
AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
+ }
return 0;
}
-int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power)
+int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 mode, u8 txpower)
{
/*Just a try M.F.*/
struct ieee80211_channel *channel = &ah->ah_current_channel;
ATH5K_TRACE(ah->ah_sc);
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
- "changing txpower to %d\n", power);
+ "changing txpower to %d\n", txpower);
- return ath5k_hw_txpower(ah, channel, power);
+ return ath5k_hw_txpower(ah, channel, mode, txpower);
}
#undef _ATH5K_PHY
diff --git a/drivers/net/wireless/ath5k/qcu.c b/drivers/net/wireless/ath5k/qcu.c
index 1b7bc50ea8eb..5094c394a4b2 100644
--- a/drivers/net/wireless/ath5k/qcu.c
+++ b/drivers/net/wireless/ath5k/qcu.c
@@ -148,6 +148,7 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
*/
u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
{
+ u32 pending;
ATH5K_TRACE(ah->ah_sc);
AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
@@ -159,7 +160,15 @@ u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
if (ah->ah_version == AR5K_AR5210)
return false;
- return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT;
+ pending = (AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT);
+
+ /* It's possible to have no frames pending even if TXE
+ * is set. To indicate that q has not stopped return
+ * true */
+ if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
+ return true;
+
+ return pending;
}
/*
@@ -324,8 +333,18 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
/*
* Set misc registers
*/
- ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY,
- AR5K_QUEUE_MISC(queue));
+ /* Enable DCU early termination for this queue */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+ AR5K_QCU_MISC_DCU_EARLY);
+
+ /* Enable DCU to wait for next fragment from QCU */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+ AR5K_DCU_MISC_FRAG_WAIT);
+
+ /* On Maui and Spirit use the global seqnum on DCU */
+ if (ah->ah_mac_version < AR5K_SREV_AR5211)
+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+ AR5K_DCU_MISC_SEQNUM_CTL);
if (tq->tqi_cbr_period) {
ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
@@ -341,7 +360,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
AR5K_QCU_MISC_CBR_THRES_ENABLE);
}
- if (tq->tqi_ready_time)
+ if (tq->tqi_ready_time &&
+ (tq->tqi_type != AR5K_TX_QUEUE_ID_CAB))
ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
AR5K_QCU_RDYTIMECFG_INTVAL) |
AR5K_QCU_RDYTIMECFG_ENABLE,
@@ -383,13 +403,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
AR5K_DCU_MISC_ARBLOCK_CTL_S) |
AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
AR5K_DCU_MISC_BCN_ENABLE);
-
- ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
- (AR5K_TUNE_SW_BEACON_RESP -
- AR5K_TUNE_DMA_BEACON_RESP) -
- AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
- AR5K_QCU_RDYTIMECFG_ENABLE,
- AR5K_QUEUE_RDYTIMECFG(queue));
break;
case AR5K_TX_QUEUE_CAB:
@@ -398,6 +411,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
AR5K_QCU_MISC_CBREXP_DIS |
AR5K_QCU_MISC_CBREXP_BCN_DIS);
+ ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
+ (AR5K_TUNE_SW_BEACON_RESP -
+ AR5K_TUNE_DMA_BEACON_RESP) -
+ AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
+ AR5K_QCU_RDYTIMECFG_ENABLE,
+ AR5K_QUEUE_RDYTIMECFG(queue));
+
AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
(AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
AR5K_DCU_MISC_ARBLOCK_CTL_S));
@@ -413,6 +433,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
break;
}
+ /* TODO: Handle frame compression */
+
/*
* Enable interrupts for this tx queue
* in the secondary interrupt mask registers
@@ -483,6 +505,9 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
* by setting AR5K_TXNOFRM to zero */
if (ah->ah_txq_imr_nofrm == 0)
ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
+
+ /* Set QCU mask for this DCU to save power */
+ AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
}
return 0;
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
index 9189ab13286c..7070d1543cdc 100644
--- a/drivers/net/wireless/ath5k/reg.h
+++ b/drivers/net/wireless/ath5k/reg.h
@@ -187,6 +187,7 @@
#define AR5K_TXCFG_FRMPAD_DIS 0x00002000 /* [5211+] */
#define AR5K_TXCFG_RDY_CBR_DIS 0x00004000 /* Ready time CBR disable [5211+] */
#define AR5K_TXCFG_JUMBO_FRM_MODE 0x00008000 /* Jumbo frame mode [5211+] */
+#define AR5K_TXCFG_DCU_DBL_BUF_DIS 0x00008000 /* Disable double buffering on DCU */
#define AR5K_TXCFG_DCU_CACHING_DIS 0x00010000 /* Disable DCU caching */
/*
@@ -753,7 +754,7 @@
*/
#define AR5K_DCU_SEQNUM_BASE 0x1140
#define AR5K_DCU_SEQNUM_M 0x00000fff
-#define AR5K_QUEUE_DFS_SEQNUM(_q) AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
+#define AR5K_QUEUE_DCU_SEQNUM(_q) AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
/*
* DCU global IFS SIFS register
@@ -811,6 +812,8 @@
/*
* DCU transmit filter table 0 (32 entries)
+ * each entry contains a 32bit slice of the
+ * 128bit tx filter for each DCU (4 slices per DCU)
*/
#define AR5K_DCU_TX_FILTER_0_BASE 0x1038
#define AR5K_DCU_TX_FILTER_0(_n) (AR5K_DCU_TX_FILTER_0_BASE + (_n * 64))
@@ -819,7 +822,7 @@
* DCU transmit filter table 1 (16 entries)
*/
#define AR5K_DCU_TX_FILTER_1_BASE 0x103c
-#define AR5K_DCU_TX_FILTER_1(_n) (AR5K_DCU_TX_FILTER_1_BASE + ((_n - 32) * 64))
+#define AR5K_DCU_TX_FILTER_1(_n) (AR5K_DCU_TX_FILTER_1_BASE + (_n * 64))
/*
* DCU clear transmit filter register
@@ -1447,7 +1450,7 @@
AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
/*
- * Last beacon timestamp register
+ * Last beacon timestamp register (Read Only)
*/
#define AR5K_LAST_TSTP 0x8080
@@ -1465,7 +1468,7 @@
#define AR5K_ADDAC_TEST_TRIG_PTY 0x00020000 /* Trigger polarity */
#define AR5K_ADDAC_TEST_RXCONT 0x00040000 /* Continuous capture */
#define AR5K_ADDAC_TEST_CAPTURE 0x00080000 /* Begin capture */
-#define AR5K_ADDAC_TEST_TST_ARM 0x00100000 /* Test ARM (Adaptive Radio Mode ?) */
+#define AR5K_ADDAC_TEST_TST_ARM 0x00100000 /* ARM rx buffer for capture */
/*
* Default antenna register [5211+]
@@ -1551,6 +1554,19 @@
/*===5212 Specific PCU registers===*/
/*
+ * Transmit power control register
+ */
+#define AR5K_TPC 0x80e8
+#define AR5K_TPC_ACK 0x0000003f /* ack frames */
+#define AR5K_TPC_ACK_S 0
+#define AR5K_TPC_CTS 0x00003f00 /* cts frames */
+#define AR5K_TPC_CTS_S 8
+#define AR5K_TPC_CHIRP 0x003f0000 /* chirp frames */
+#define AR5K_TPC_CHIRP_S 16
+#define AR5K_TPC_DOPPLER 0x0f000000 /* doppler chirp span */
+#define AR5K_TPC_DOPPLER_S 24
+
+/*
* XR (eXtended Range) mode register
*/
#define AR5K_XRMODE 0x80c0 /* Register Address */
@@ -1677,7 +1693,7 @@
* TSF parameter register
*/
#define AR5K_TSF_PARM 0x8104 /* Register Address */
-#define AR5K_TSF_PARM_INC_M 0x000000ff /* Mask for TSF increment */
+#define AR5K_TSF_PARM_INC 0x000000ff /* Mask for TSF increment */
#define AR5K_TSF_PARM_INC_S 0
/*
@@ -1689,7 +1705,7 @@
#define AR5K_QOS_NOACK_BIT_OFFSET 0x00000070 /* ??? */
#define AR5K_QOS_NOACK_BIT_OFFSET_S 4
#define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000180 /* ??? */
-#define AR5K_QOS_NOACK_BYTE_OFFSET_S 8
+#define AR5K_QOS_NOACK_BYTE_OFFSET_S 7
/*
* PHY error filter register
@@ -1848,15 +1864,14 @@
* TST_2 (Misc config parameters)
*/
#define AR5K_PHY_TST2 0x9800 /* Register Address */
-#define AR5K_PHY_TST2_TRIG_SEL 0x00000001 /* Trigger select (?) (field ?) */
-#define AR5K_PHY_TST2_TRIG 0x00000010 /* Trigger (?) (field ?) */
-#define AR5K_PHY_TST2_CBUS_MODE 0x00000100 /* Cardbus mode (?) */
-/* bit reserved */
+#define AR5K_PHY_TST2_TRIG_SEL 0x00000007 /* Trigger select (?)*/
+#define AR5K_PHY_TST2_TRIG 0x00000010 /* Trigger (?) */
+#define AR5K_PHY_TST2_CBUS_MODE 0x00000060 /* Cardbus mode (?) */
#define AR5K_PHY_TST2_CLK32 0x00000400 /* CLK_OUT is CLK32 (32Khz external) */
#define AR5K_PHY_TST2_CHANCOR_DUMP_EN 0x00000800 /* Enable Chancor dump (?) */
#define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP 0x00001000 /* Even Chancor dump (?) */
#define AR5K_PHY_TST2_RFSILENT_EN 0x00002000 /* Enable RFSILENT */
-#define AR5K_PHY_TST2_ALT_RFDATA 0x00004000 /* Alternate RFDATA (5-2GHz switch) */
+#define AR5K_PHY_TST2_ALT_RFDATA 0x00004000 /* Alternate RFDATA (5-2GHz switch ?) */
#define AR5K_PHY_TST2_MINI_OBS_EN 0x00008000 /* Enable mini OBS (?) */
#define AR5K_PHY_TST2_RX2_IS_RX5_INV 0x00010000 /* 2GHz rx path is the 5GHz path inverted (?) */
#define AR5K_PHY_TST2_SLOW_CLK160 0x00020000 /* Slow CLK160 (?) */
@@ -1926,8 +1941,8 @@
#define AR5K_PHY_RF_CTL2_TXF2TXD_START_S 0
#define AR5K_PHY_RF_CTL3 0x9828 /* Register Address */
-#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000000f /* TX end to XLNA on */
-#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 0
+#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000ff00 /* TX end to XLNA on */
+#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 8
#define AR5K_PHY_ADC_CTL 0x982c
#define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF 0x00000003
@@ -1961,7 +1976,7 @@
#define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */
#define AR5K_PHY_SETTLING_AGC_S 0
#define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */
-#define AR5K_PHY_SETTLINK_SWITCH_S 7
+#define AR5K_PHY_SETTLING_SWITCH_S 7
/*
* PHY Gain registers
@@ -2067,14 +2082,14 @@
* PHY sleep registers [5112+]
*/
#define AR5K_PHY_SCR 0x9870
-#define AR5K_PHY_SCR_32MHZ 0x0000001f
#define AR5K_PHY_SLMT 0x9874
#define AR5K_PHY_SLMT_32MHZ 0x0000007f
#define AR5K_PHY_SCAL 0x9878
#define AR5K_PHY_SCAL_32MHZ 0x0000000e
-
+#define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a
+#define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032
/*
* PHY PLL (Phase Locked Loop) control register
@@ -2101,34 +2116,10 @@
/*
* RF Buffer register
*
- * There are some special control registers on the RF chip
- * that hold various operation settings related mostly to
- * the analog parts (channel, gain adjustment etc).
- *
- * We don't write on those registers directly but
- * we send a data packet on the buffer register and
- * then write on another special register to notify hw
- * to apply the settings. This is done so that control registers
- * can be dynamicaly programmed during operation and the settings
- * are applied faster on the hw.
- *
- * We sent such data packets during rf initialization and channel change
- * through ath5k_hw_rf*_rfregs and ath5k_hw_rf*_channel functions.
- *
- * The data packets we send during initializadion are inside ath5k_ini_rf
- * struct (see ath5k_hw.h) and each one is related to an "rf register bank".
- * We use *rfregs functions to modify them acording to current operation
- * mode and eeprom values and pass them all together to the chip.
- *
* It's obvious from the code that 0x989c is the buffer register but
* for the other special registers that we write to after sending each
* packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
* for now. It's interesting that they are also used for some other operations.
- *
- * Also check out hw.h and U.S. Patent 6677779 B1 (about buffer
- * registers and control registers):
- *
- * http://www.google.com/patents?id=qNURAAAAEBAJ
*/
#define AR5K_RF_BUFFER 0x989c
@@ -2178,7 +2169,8 @@
#define AR5K_PHY_ANT_CTL_TXRX_EN 0x00000001 /* Enable TX/RX (?) */
#define AR5K_PHY_ANT_CTL_SECTORED_ANT 0x00000004 /* Sectored Antenna */
#define AR5K_PHY_ANT_CTL_HITUNE5 0x00000008 /* Hitune5 (?) */
-#define AR5K_PHY_ANT_CTL_SWTABLE_IDLE 0x00000010 /* Switch table idle (?) */
+#define AR5K_PHY_ANT_CTL_SWTABLE_IDLE 0x000003f0 /* Switch table idle (?) */
+#define AR5K_PHY_ANT_CTL_SWTABLE_IDLE_S 4
/*
* PHY receiver delay register [5111+]
@@ -2218,7 +2210,7 @@
#define AR5K_PHY_OFDM_SELFCORR 0x9924 /* Register Address */
#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN 0x00000001 /* Enable cyclic RSSI thr 1 */
#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1 0x000000fe /* Mask for Cyclic RSSI threshold 1 */
-#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 0
+#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 1
#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3 0x00000100 /* Cyclic RSSI threshold 3 (field) (?) */
#define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN 0x00008000 /* Enable 1A RSSI threshold (?) */
#define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR 0x00010000 /* 1A RSSI threshold (field) (?) */
@@ -2243,9 +2235,7 @@
#define AR5K_PHY_CTL_LOW_FREQ_SLE_EN 0x00000080 /* Enable low freq sleep */
/*
- * PHY PAPD probe register [5111+ (?)]
- * Is this only present in 5212 ?
- * Because it's always 0 in 5211 initialization code
+ * PHY PAPD probe register [5111+]
*/
#define AR5K_PHY_PAPD_PROBE 0x9930
#define AR5K_PHY_PAPD_PROBE_SH_HI_PAR 0x00000001
@@ -2303,6 +2293,15 @@
AR5K_PHY_FRAME_CTL_TIMING_ERR
/*
+ * PHY Tx Power adjustment register [5212A+]
+ */
+#define AR5K_PHY_TX_PWR_ADJ 0x994c
+#define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA 0x00000fc0
+#define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA_S 6
+#define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX 0x00fc0000
+#define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX_S 18
+
+/*
* PHY radar detection register [5111+]
*/
#define AR5K_PHY_RADAR 0x9954
@@ -2355,7 +2354,7 @@
#define AR5K_PHY_SIGMA_DELTA_FILT2_S 3
#define AR5K_PHY_SIGMA_DELTA_FILT1 0x00001f00
#define AR5K_PHY_SIGMA_DELTA_FILT1_S 8
-#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ff3000
+#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000
#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S 13
/*
@@ -2387,21 +2386,21 @@
#define AR5K_PHY_BIN_MASK2_4_MASK_4 0x00003fff
#define AR5K_PHY_BIN_MASK2_4_MASK_4_S 0
-#define AR_PHY_TIMING_9 0x9998
-#define AR_PHY_TIMING_10 0x999c
-#define AR_PHY_TIMING_10_PILOT_MASK_2 0x000fffff
-#define AR_PHY_TIMING_10_PILOT_MASK_2_S 0
+#define AR5K_PHY_TIMING_9 0x9998
+#define AR5K_PHY_TIMING_10 0x999c
+#define AR5K_PHY_TIMING_10_PILOT_MASK_2 0x000fffff
+#define AR5K_PHY_TIMING_10_PILOT_MASK_2_S 0
/*
* Spur mitigation control
*/
-#define AR_PHY_TIMING_11 0x99a0 /* Register address */
-#define AR_PHY_TIMING_11_SPUR_DELTA_PHASE 0x000fffff /* Spur delta phase */
-#define AR_PHY_TIMING_11_SPUR_DELTA_PHASE_S 0
-#define AR_PHY_TIMING_11_SPUR_FREQ_SD 0x3ff00000 /* Freq sigma delta */
-#define AR_PHY_TIMING_11_SPUR_FREQ_SD_S 20
-#define AR_PHY_TIMING_11_USE_SPUR_IN_AGC 0x40000000 /* Spur filter in AGC detector */
-#define AR_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000 /* Spur filter in OFDM self correlator */
+#define AR5K_PHY_TIMING_11 0x99a0 /* Register address */
+#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE 0x000fffff /* Spur delta phase */
+#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE_S 0
+#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD 0x3ff00000 /* Freq sigma delta */
+#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD_S 20
+#define AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC 0x40000000 /* Spur filter in AGC detector */
+#define AR5K_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000 /* Spur filter in OFDM self correlator */
/*
* Gain tables
@@ -2483,17 +2482,7 @@
#define AR5K_PHY_SDELAY 0x99f4
#define AR5K_PHY_SDELAY_32MHZ 0x000000ff
#define AR5K_PHY_SPENDING 0x99f8
-#define AR5K_PHY_SPENDING_14 0x00000014
-#define AR5K_PHY_SPENDING_18 0x00000018
-#define AR5K_PHY_SPENDING_RF5111 0x00000018
-#define AR5K_PHY_SPENDING_RF5112 0x00000014
-/* #define AR5K_PHY_SPENDING_RF5112A 0x0000000e */
-/* #define AR5K_PHY_SPENDING_RF5424 0x00000012 */
-#define AR5K_PHY_SPENDING_RF5413 0x00000018
-#define AR5K_PHY_SPENDING_RF2413 0x00000018
-#define AR5K_PHY_SPENDING_RF2316 0x00000018
-#define AR5K_PHY_SPENDING_RF2317 0x00000018
-#define AR5K_PHY_SPENDING_RF2425 0x00000014
+
/*
* PHY PAPD I (power?) table (?)
@@ -2505,11 +2494,7 @@
/*
* PHY PCDAC TX power table
*/
-#define AR5K_PHY_PCDAC_TXPOWER_BASE_5211 0xa180
-#define AR5K_PHY_PCDAC_TXPOWER_BASE_2413 0xa280
-#define AR5K_PHY_PCDAC_TXPOWER_BASE (ah->ah_radio >= AR5K_RF2413 ? \
- AR5K_PHY_PCDAC_TXPOWER_BASE_2413 :\
- AR5K_PHY_PCDAC_TXPOWER_BASE_5211)
+#define AR5K_PHY_PCDAC_TXPOWER_BASE 0xa180
#define AR5K_PHY_PCDAC_TXPOWER(_n) (AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2))
/*
@@ -2578,6 +2563,12 @@
#define AR5K_PHY_TPC_RG1 0xa258
#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN 0x0000c000
#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S 14
+#define AR5K_PHY_TPC_RG1_PDGAIN_1 0x00030000
+#define AR5K_PHY_TPC_RG1_PDGAIN_1_S 16
+#define AR5K_PHY_TPC_RG1_PDGAIN_2 0x000c0000
+#define AR5K_PHY_TPC_RG1_PDGAIN_2_S 18
+#define AR5K_PHY_TPC_RG1_PDGAIN_3 0x00300000
+#define AR5K_PHY_TPC_RG1_PDGAIN_3_S 20
#define AR5K_PHY_TPC_RG5 0xa26C
#define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP 0x0000000F
@@ -2590,3 +2581,9 @@
#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S 16
#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4 0x0FC00000
#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S 22
+
+/*
+ * PHY PDADC Tx power table
+ */
+#define AR5K_PHY_PDADC_TXPOWER_BASE 0xa280
+#define AR5K_PHY_PDADC_TXPOWER(_n) (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2))
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c
index dc2d7d8bdb7a..7a17d31b2fd9 100644
--- a/drivers/net/wireless/ath5k/reset.c
+++ b/drivers/net/wireless/ath5k/reset.c
@@ -25,7 +25,8 @@
Reset functions and helpers
\*****************************/
-#include <linux/pci.h>
+#include <linux/pci.h> /* To determine if a card is pci-e */
+#include <linux/bitops.h> /* For get_bitmask_order */
#include "ath5k.h"
#include "reg.h"
#include "base.h"
@@ -37,10 +38,14 @@
* @ah: the &struct ath5k_hw
* @channel: the currently set channel upon reset
*
- * Write the OFDM timings for the AR5212 upon reset. This is a helper for
- * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
- * depending on the bandwidth of the channel.
+ * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
+ * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset().
*
+ * Since delta slope is floating point we split it on its exponent and
+ * mantissa and provide these values on hw.
+ *
+ * For more infos i think this patent is related
+ * http://www.freepatentsonline.com/7184495.html
*/
static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
struct ieee80211_channel *channel)
@@ -53,23 +58,34 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
!(channel->hw_value & CHANNEL_OFDM))
BUG();
- /* Seems there are two PLLs, one for baseband sampling and one
- * for tuning. Tuning basebands are 40 MHz or 80MHz when in
- * turbo. */
- clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40;
- coef_scaled = ((5 * (clock << 24)) / 2) /
- channel->center_freq;
+ /* Get coefficient
+ * ALGO: coef = (5 * clock * carrier_freq) / 2)
+ * we scale coef by shifting clock value by 24 for
+ * better precision since we use integers */
+ /* TODO: Half/quarter rate */
+ clock = ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO);
- for (coef_exp = 31; coef_exp > 0; coef_exp--)
- if ((coef_scaled >> coef_exp) & 0x1)
- break;
+ coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
+
+ /* Get exponent
+ * ALGO: coef_exp = 14 - highest set bit position */
+ coef_exp = get_bitmask_order(coef_scaled);
+ /* Doesn't make sense if it's zero*/
if (!coef_exp)
return -EINVAL;
+ /* Note: we've shifted coef_scaled by 24 */
coef_exp = 14 - (coef_exp - 24);
+
+
+ /* Get mantissa (significant digits)
+ * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
coef_man = coef_scaled +
(1 << (24 - coef_exp - 1));
+
+ /* Calculate delta slope coefficient exponent
+ * and mantissa (remove scaling) and set them on hw */
ds_coef_man = coef_man >> (24 - coef_exp);
ds_coef_exp = coef_exp - 16;
@@ -86,20 +102,27 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
* index into rates for control rates, we can set it up like this because
* this is only used for AR5212 and we know it supports G mode
*/
-static int control_rates[] =
+static const unsigned int control_rates[] =
{ 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
/**
- * ath5k_hw_write_rate_duration - set rate duration during hw resets
+ * ath5k_hw_write_rate_duration - fill rate code to duration table
*
* @ah: the &struct ath5k_hw
* @mode: one of enum ath5k_driver_mode
*
- * Write the rate duration table upon hw reset. This is a helper for
- * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout for
- * the hardware for the current mode for each rate. The rates which are capable
- * of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have another
- * register for the short preamble ACK timeout calculation.
+ * Write the rate code to duration table upon hw reset. This is a helper for
+ * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on
+ * the hardware, based on current mode, for each rate. The rates which are
+ * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
+ * different rate code so we write their value twice (one for long preample
+ * and one for short).
+ *
+ * Note: Band doesn't matter here, if we set the values for OFDM it works
+ * on both a and g modes. So all we have to do is set values for all g rates
+ * that include all OFDM and CCK rates. If we operate in turbo or xr/half/
+ * quarter rate mode, we need to use another set of bitrates (that's why we
+ * need the mode parameter) but we don't handle these proprietary modes yet.
*/
static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
unsigned int mode)
@@ -275,7 +298,8 @@ commit:
}
/*
- * Bring up MAC + PHY Chips
+ * Bring up MAC + PHY Chips and program PLL
+ * TODO: Half/Quarter rate support
*/
int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
{
@@ -333,7 +357,11 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
}
} else if (flags & CHANNEL_5GHZ) {
mode |= AR5K_PHY_MODE_FREQ_5GHZ;
- clock |= AR5K_PHY_PLL_40MHZ;
+
+ if (ah->ah_radio == AR5K_RF5413)
+ clock |= AR5K_PHY_PLL_40MHZ_5413;
+ else
+ clock |= AR5K_PHY_PLL_40MHZ;
if (flags & CHANNEL_OFDM)
mode |= AR5K_PHY_MODE_MOD_OFDM;
@@ -391,10 +419,14 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
}
if (ah->ah_version != AR5K_AR5210) {
- /* ...set the PHY operating mode */
- ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
- udelay(300);
+ /* ...update PLL if needed */
+ if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) {
+ ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
+ udelay(300);
+ }
+
+ /* ...set the PHY operating mode */
ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
}
@@ -403,22 +435,399 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
}
/*
+ * If there is an external 32KHz crystal available, use it
+ * as ref. clock instead of 32/40MHz clock and baseband clocks
+ * to save power during sleep or restore normal 32/40MHz
+ * operation.
+ *
+ * XXX: When operating on 32KHz certain PHY registers (27 - 31,
+ * 123 - 127) require delay on access.
+ */
+static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ u32 scal, spending, usec32;
+
+ /* Only set 32KHz settings if we have an external
+ * 32KHz crystal present */
+ if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
+ AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
+ enable) {
+
+ /* 1 usec/cycle */
+ AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
+ /* Set up tsf increment on each cycle */
+ AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
+
+ /* Set baseband sleep control registers
+ * and sleep control rate */
+ ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ spending = 0x14;
+ else
+ spending = 0x18;
+ ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+ ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
+ ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
+ ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
+ ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
+ } else {
+ ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
+ ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
+ ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
+ ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
+ }
+
+ /* Enable sleep clock operation */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_EN);
+
+ } else {
+
+ /* Disable sleep clock operation and
+ * restore default parameters */
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_EN);
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
+
+ ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
+ ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
+
+ if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
+ scal = AR5K_PHY_SCAL_32MHZ_2417;
+ else if (ath5k_eeprom_is_hb63(ah))
+ scal = AR5K_PHY_SCAL_32MHZ_HB63;
+ else
+ scal = AR5K_PHY_SCAL_32MHZ;
+ ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
+
+ ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
+ ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ spending = 0x14;
+ else
+ spending = 0x18;
+ ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413))
+ usec32 = 39;
+ else
+ usec32 = 31;
+ AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32);
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
+ }
+ return;
+}
+
+static bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ u8 refclk_freq;
+
+ if ((ah->ah_radio == AR5K_RF5112) ||
+ (ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+ refclk_freq = 40;
+ else
+ refclk_freq = 32;
+
+ if ((channel->center_freq % refclk_freq != 0) &&
+ ((channel->center_freq % refclk_freq < 10) ||
+ (channel->center_freq % refclk_freq > 22)))
+ return true;
+ else
+ return false;
+}
+
+/* TODO: Half/Quarter rate */
+static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel)
+{
+ if (ah->ah_version == AR5K_AR5212 &&
+ ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+
+ /* Setup ADC control */
+ ath5k_hw_reg_write(ah,
+ (AR5K_REG_SM(2,
+ AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) |
+ AR5K_REG_SM(2,
+ AR5K_PHY_ADC_CTL_INBUFGAIN_ON) |
+ AR5K_PHY_ADC_CTL_PWD_DAC_OFF |
+ AR5K_PHY_ADC_CTL_PWD_ADC_OFF),
+ AR5K_PHY_ADC_CTL);
+
+
+
+ /* Disable barker RSSI threshold */
+ AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
+ AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR);
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
+ AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2);
+
+ /* Set the mute mask */
+ ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
+ }
+
+ /* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */
+ if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B)
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH);
+
+ /* Enable DCU double buffering */
+ if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B)
+ AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
+ AR5K_TXCFG_DCU_DBL_BUF_DIS);
+
+ /* Set DAC/ADC delays */
+ if (ah->ah_version == AR5K_AR5212) {
+ u32 scal;
+ if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
+ scal = AR5K_PHY_SCAL_32MHZ_2417;
+ else if (ath5k_eeprom_is_hb63(ah))
+ scal = AR5K_PHY_SCAL_32MHZ_HB63;
+ else
+ scal = AR5K_PHY_SCAL_32MHZ;
+ ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
+ }
+
+ /* Set fast ADC */
+ if ((ah->ah_radio == AR5K_RF5413) ||
+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+ u32 fast_adc = true;
+
+ if (channel->center_freq == 2462 ||
+ channel->center_freq == 2467)
+ fast_adc = 0;
+
+ /* Only update if needed */
+ if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc)
+ ath5k_hw_reg_write(ah, fast_adc,
+ AR5K_PHY_FAST_ADC);
+ }
+
+ /* Fix for first revision of the RF5112 RF chipset */
+ if (ah->ah_radio == AR5K_RF5112 &&
+ ah->ah_radio_5ghz_revision <
+ AR5K_SREV_RAD_5112A) {
+ u32 data;
+ ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
+ AR5K_PHY_CCKTXCTL);
+ if (channel->hw_value & CHANNEL_5GHZ)
+ data = 0xffb81020;
+ else
+ data = 0xffb80d20;
+ ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
+ }
+
+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+ u32 usec_reg;
+ /* 5311 has different tx/rx latency masks
+ * from 5211, since we deal 5311 the same
+ * as 5211 when setting initvals, shift
+ * values here to their proper locations */
+ usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
+ ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 |
+ AR5K_USEC_32 |
+ AR5K_USEC_TX_LATENCY_5211 |
+ AR5K_REG_SM(29,
+ AR5K_USEC_RX_LATENCY_5210)),
+ AR5K_USEC_5211);
+ /* Clear QCU/DCU clock gating register */
+ ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);
+ /* Set DAC/ADC delays */
+ ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL);
+ /* Enable PCU FIFO corruption ECO */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
+ AR5K_DIAG_SW_ECO_ENABLE);
+ }
+}
+
+static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
+ struct ieee80211_channel *channel, u8 *ant, u8 ee_mode)
+{
+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+ s16 cck_ofdm_pwr_delta;
+
+ /* Adjust power delta for channel 14 */
+ if (channel->center_freq == 2484)
+ cck_ofdm_pwr_delta =
+ ((ee->ee_cck_ofdm_power_delta -
+ ee->ee_scaled_cck_delta) * 2) / 10;
+ else
+ cck_ofdm_pwr_delta =
+ (ee->ee_cck_ofdm_power_delta * 2) / 10;
+
+ /* Set CCK to OFDM power delta on tx power
+ * adjustment register */
+ if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+ if (channel->hw_value == CHANNEL_G)
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),
+ AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
+ AR5K_REG_SM((cck_ofdm_pwr_delta * -1),
+ AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX),
+ AR5K_PHY_TX_PWR_ADJ);
+ else
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ);
+ } else {
+ /* For older revs we scale power on sw during tx power
+ * setup */
+ ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta;
+ ah->ah_txpower.txp_cck_ofdm_gainf_delta =
+ ee->ee_cck_ofdm_gain_delta;
+ }
+
+ /* Set antenna idle switch table */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
+ AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
+ (ah->ah_antenna[ee_mode][0] |
+ AR5K_PHY_ANT_CTL_TXRX_EN));
+
+ /* Set antenna switch table */
+ ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
+ AR5K_PHY_ANT_SWITCH_TABLE_0);
+ ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
+ AR5K_PHY_ANT_SWITCH_TABLE_1);
+
+ /* Noise floor threshold */
+ ath5k_hw_reg_write(ah,
+ AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
+ AR5K_PHY_NFTHRES);
+
+ if ((channel->hw_value & CHANNEL_TURBO) &&
+ (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {
+ /* Switch settling time (Turbo) */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+ AR5K_PHY_SETTLING_SWITCH,
+ ee->ee_switch_settling_turbo[ee_mode]);
+
+ /* Tx/Rx attenuation (Turbo) */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
+ AR5K_PHY_GAIN_TXRX_ATTEN,
+ ee->ee_atn_tx_rx_turbo[ee_mode]);
+
+ /* ADC/PGA desired size (Turbo) */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+ AR5K_PHY_DESIRED_SIZE_ADC,
+ ee->ee_adc_desired_size_turbo[ee_mode]);
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+ AR5K_PHY_DESIRED_SIZE_PGA,
+ ee->ee_pga_desired_size_turbo[ee_mode]);
+
+ /* Tx/Rx margin (Turbo) */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
+ AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
+ ee->ee_margin_tx_rx_turbo[ee_mode]);
+
+ } else {
+ /* Switch settling time */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+ AR5K_PHY_SETTLING_SWITCH,
+ ee->ee_switch_settling[ee_mode]);
+
+ /* Tx/Rx attenuation */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
+ AR5K_PHY_GAIN_TXRX_ATTEN,
+ ee->ee_atn_tx_rx[ee_mode]);
+
+ /* ADC/PGA desired size */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+ AR5K_PHY_DESIRED_SIZE_ADC,
+ ee->ee_adc_desired_size[ee_mode]);
+
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+ AR5K_PHY_DESIRED_SIZE_PGA,
+ ee->ee_pga_desired_size[ee_mode]);
+
+ /* Tx/Rx margin */
+ if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
+ AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
+ ee->ee_margin_tx_rx[ee_mode]);
+ }
+
+ /* XPA delays */
+ ath5k_hw_reg_write(ah,
+ (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
+ (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
+ (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
+ (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
+
+ /* XLNA delay */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3,
+ AR5K_PHY_RF_CTL3_TXE2XLNA_ON,
+ ee->ee_tx_end2xlna_enable[ee_mode]);
+
+ /* Thresh64 (ANI) */
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF,
+ AR5K_PHY_NF_THRESH62,
+ ee->ee_thr_62[ee_mode]);
+
+
+ /* False detect backoff for channels
+ * that have spur noise. Write the new
+ * cyclic power RSSI threshold. */
+ if (ath5k_hw_chan_has_spur_noise(ah, channel))
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
+ AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
+ AR5K_INIT_CYCRSSI_THR1 +
+ ee->ee_false_detect[ee_mode]);
+ else
+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
+ AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
+ AR5K_INIT_CYCRSSI_THR1);
+
+ /* I/Q correction
+ * TODO: Per channel i/q infos ? */
+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
+ AR5K_PHY_IQ_CORR_ENABLE |
+ (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
+ ee->ee_q_cal[ee_mode]);
+
+ /* Heavy clipping -disable for now */
+ if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
+ ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
+
+ return;
+}
+
+/*
* Main reset function
*/
int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
struct ieee80211_channel *channel, bool change_channel)
{
- struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
- struct pci_dev *pdev = ah->ah_sc->pdev;
- u32 data, s_seq, s_ant, s_led[3], dma_size;
- unsigned int i, mode, freq, ee_mode, ant[2];
- int ret;
+ u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo;
+ u32 phy_tst1;
+ u8 mode, freq, ee_mode, ant[2];
+ int i, ret;
ATH5K_TRACE(ah->ah_sc);
- s_seq = 0;
s_ant = 0;
ee_mode = 0;
+ staid1_flags = 0;
+ tsf_up = 0;
+ tsf_lo = 0;
freq = 0;
mode = 0;
@@ -427,48 +836,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
*/
/*DCU/Antenna selection not available on 5210*/
if (ah->ah_version != AR5K_AR5210) {
- if (change_channel) {
- /* Seq number for queue 0 -do this for all queues ? */
- s_seq = ath5k_hw_reg_read(ah,
- AR5K_QUEUE_DFS_SEQNUM(0));
- /*Default antenna*/
- s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
- }
- }
-
- /*GPIOs*/
- s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE;
- s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
- s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
-
- if (change_channel && ah->ah_rf_banks != NULL)
- ath5k_hw_get_rf_gain(ah);
-
-
- /*Wakeup the device*/
- ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
- if (ret)
- return ret;
-
- /*
- * Initialize operating mode
- */
- ah->ah_op_mode = op_mode;
-
- /*
- * 5111/5112 Settings
- * 5210 only comes with RF5110
- */
- if (ah->ah_version != AR5K_AR5210) {
- if (ah->ah_radio != AR5K_RF5111 &&
- ah->ah_radio != AR5K_RF5112 &&
- ah->ah_radio != AR5K_RF5413 &&
- ah->ah_radio != AR5K_RF2413 &&
- ah->ah_radio != AR5K_RF2425) {
- ATH5K_ERR(ah->ah_sc,
- "invalid phy radio: %u\n", ah->ah_radio);
- return -EINVAL;
- }
switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A:
@@ -491,8 +858,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
freq = AR5K_INI_RFGAIN_5GHZ;
ee_mode = AR5K_EEPROM_MODE_11A;
break;
- /*Is this ok on 5211 too ?*/
case CHANNEL_TG:
+ if (ah->ah_version == AR5K_AR5211) {
+ ATH5K_ERR(ah->ah_sc,
+ "TurboG mode not available on 5211");
+ return -EINVAL;
+ }
mode = AR5K_MODE_11G_TURBO;
freq = AR5K_INI_RFGAIN_2GHZ;
ee_mode = AR5K_EEPROM_MODE_11G;
@@ -513,11 +884,93 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
return -EINVAL;
}
- /* PHY access enable */
- ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+ if (change_channel) {
+ /*
+ * Save frame sequence count
+ * For revs. after Oahu, only save
+ * seq num for DCU 0 (Global seq num)
+ */
+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+
+ for (i = 0; i < 10; i++)
+ s_seq[i] = ath5k_hw_reg_read(ah,
+ AR5K_QUEUE_DCU_SEQNUM(i));
+
+ } else {
+ s_seq[0] = ath5k_hw_reg_read(ah,
+ AR5K_QUEUE_DCU_SEQNUM(0));
+ }
+
+ /* TSF accelerates on AR5211 durring reset
+ * As a workaround save it here and restore
+ * it later so that it's back in time after
+ * reset. This way it'll get re-synced on the
+ * next beacon without breaking ad-hoc.
+ *
+ * On AR5212 TSF is almost preserved across a
+ * reset so it stays back in time anyway and
+ * we don't have to save/restore it.
+ *
+ * XXX: Since this breaks power saving we have
+ * to disable power saving until we receive the
+ * next beacon, so we can resync beacon timers */
+ if (ah->ah_version == AR5K_AR5211) {
+ tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+ tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
+ }
+ }
+
+ /* Save default antenna */
+ s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
+ if (ah->ah_version == AR5K_AR5212) {
+ /* Restore normal 32/40MHz clock operation
+ * to avoid register access delay on certain
+ * PHY registers */
+ ath5k_hw_set_sleep_clock(ah, false);
+
+ /* Since we are going to write rf buffer
+ * check if we have any pending gain_F
+ * optimization settings */
+ if (change_channel && ah->ah_rf_banks != NULL)
+ ath5k_hw_gainf_calibrate(ah);
+ }
}
+ /*GPIOs*/
+ s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
+ AR5K_PCICFG_LEDSTATE;
+ s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
+ s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
+
+ /* AR5K_STA_ID1 flags, only preserve antenna
+ * settings and ack/cts rate mode */
+ staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) &
+ (AR5K_STA_ID1_DEFAULT_ANTENNA |
+ AR5K_STA_ID1_DESC_ANTENNA |
+ AR5K_STA_ID1_RTS_DEF_ANTENNA |
+ AR5K_STA_ID1_ACKCTS_6MB |
+ AR5K_STA_ID1_BASE_RATE_11B |
+ AR5K_STA_ID1_SELFGEN_DEF_ANT);
+
+ /* Wakeup the device */
+ ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
+ if (ret)
+ return ret;
+
+ /*
+ * Initialize operating mode
+ */
+ ah->ah_op_mode = op_mode;
+
+ /* PHY access enable */
+ if (ah->ah_mac_srev >= AR5K_SREV_AR5211)
+ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+ else
+ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40,
+ AR5K_PHY(0));
+
+ /* Write initial settings */
ret = ath5k_hw_write_initvals(ah, mode, change_channel);
if (ret)
return ret;
@@ -526,69 +979,29 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
* 5211/5212 Specific
*/
if (ah->ah_version != AR5K_AR5210) {
+
/*
* Write initial RF gain settings
* This should work for both 5111/5112
*/
- ret = ath5k_hw_rfgain(ah, freq);
+ ret = ath5k_hw_rfgain_init(ah, freq);
if (ret)
return ret;
mdelay(1);
/*
- * Write some more initial register settings for revised chips
+ * Tweak initval settings for revised
+ * chipsets and add some more config
+ * bits
*/
- if (ah->ah_version == AR5K_AR5212 &&
- ah->ah_phy_revision > 0x41) {
- ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
-
- if (channel->hw_value == CHANNEL_G)
- if (ah->ah_mac_srev < AR5K_SREV_AR2413)
- ath5k_hw_reg_write(ah, 0x00f80d80,
- 0x994c);
- else if (ah->ah_mac_srev < AR5K_SREV_AR5424)
- ath5k_hw_reg_write(ah, 0x00380140,
- 0x994c);
- else if (ah->ah_mac_srev < AR5K_SREV_AR2425)
- ath5k_hw_reg_write(ah, 0x00fc0ec0,
- 0x994c);
- else /* 2425 */
- ath5k_hw_reg_write(ah, 0x00fc0fc0,
- 0x994c);
- else
- ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
-
- /* Got this from legacy-hal */
- AR5K_REG_DISABLE_BITS(ah, 0xa228, 0x200);
-
- AR5K_REG_MASKED_BITS(ah, 0xa228, 0x800, 0xfffe03ff);
-
- /* Just write 0x9b5 ? */
- /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */
- ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
- ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
- ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
- }
-
- /* Fix for first revision of the RF5112 RF chipset */
- if (ah->ah_radio >= AR5K_RF5112 &&
- ah->ah_radio_5ghz_revision <
- AR5K_SREV_RAD_5112A) {
- ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
- AR5K_PHY_CCKTXCTL);
- if (channel->hw_value & CHANNEL_5GHZ)
- data = 0xffb81020;
- else
- data = 0xffb80d20;
- ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
- data = 0;
- }
+ ath5k_hw_tweak_initval_settings(ah, channel);
/*
* Set TX power (FIXME)
*/
- ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER);
+ ret = ath5k_hw_txpower(ah, channel, ee_mode,
+ AR5K_TUNE_DEFAULT_TXPOWER);
if (ret)
return ret;
@@ -601,15 +1014,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ath5k_hw_write_rate_duration(ah, mode);
/*
- * Write RF registers
+ * Write RF buffer
*/
- ret = ath5k_hw_rfregs(ah, channel, mode);
+ ret = ath5k_hw_rfregs_init(ah, channel, mode);
if (ret)
return ret;
- /*
- * Configure additional registers
- */
/* Write OFDM timings on 5212*/
if (ah->ah_version == AR5K_AR5212 &&
@@ -631,17 +1041,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
}
/*
- * Set channel and calibrate the PHY
- */
- ret = ath5k_hw_channel(ah, channel);
- if (ret)
- return ret;
-
- /* Set antenna mode */
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL,
- ah->ah_antenna[ee_mode][0], 0xfffffc06);
-
- /*
* In case a fixed antenna was set as default
* write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
* registers.
@@ -656,54 +1055,16 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ant[1] = AR5K_ANT_FIXED_B;
}
- ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
- AR5K_PHY_ANT_SWITCH_TABLE_0);
- ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
- AR5K_PHY_ANT_SWITCH_TABLE_1);
-
/* Commit values from EEPROM */
- if (ah->ah_radio == AR5K_RF5111)
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
- AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip);
-
- ath5k_hw_reg_write(ah,
- AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
- AR5K_PHY_NFTHRES);
-
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING,
- (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
- 0xffffc07f);
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
- (ee->ee_atn_tx_rx[ee_mode] << 12) & 0x3f000,
- 0xfffc0fff);
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
- (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
- ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
- 0xffff0000);
-
- ath5k_hw_reg_write(ah,
- (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
- (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
- (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
- (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
-
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3,
- ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF,
- (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
- AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01);
-
- AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
- AR5K_PHY_IQ_CORR_ENABLE |
- (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
- ee->ee_q_cal[ee_mode]);
-
- if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
- AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
- ee->ee_margin_tx_rx[ee_mode]);
+ ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode);
} else {
+ /*
+ * For 5210 we do all initialization using
+ * initvals, so we don't have to modify
+ * any settings (5210 also only supports
+ * a/aturbo modes)
+ */
mdelay(1);
/* Disable phy and wait */
ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
@@ -713,100 +1074,154 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/*
* Restore saved values
*/
+
/*DCU/Antenna selection not available on 5210*/
if (ah->ah_version != AR5K_AR5210) {
- ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0));
+
+ if (change_channel) {
+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+ for (i = 0; i < 10; i++)
+ ath5k_hw_reg_write(ah, s_seq[i],
+ AR5K_QUEUE_DCU_SEQNUM(i));
+ } else {
+ ath5k_hw_reg_write(ah, s_seq[0],
+ AR5K_QUEUE_DCU_SEQNUM(0));
+ }
+
+
+ if (ah->ah_version == AR5K_AR5211) {
+ ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
+ ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
+ }
+ }
+
ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
}
+
+ /* Ledstate */
AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
+
+ /* Gpio settings */
ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
+ /* Restore sta_id flags and preserve our mac address*/
+ ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id),
+ AR5K_STA_ID0);
+ ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id),
+ AR5K_STA_ID1);
+
+
/*
- * Misc
+ * Configure PCU
*/
+
+ /* Restore bssid and bssid mask */
/* XXX: add ah->aid once mac80211 gives this to us */
ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+ /* Set PCU config */
ath5k_hw_set_opmode(ah);
- /*PISR/SISR Not available on 5210*/
- if (ah->ah_version != AR5K_AR5210) {
+
+ /* Clear any pending interrupts
+ * PISR/SISR Not available on 5210 */
+ if (ah->ah_version != AR5K_AR5210)
ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
- /* If we later allow tuning for this, store into sc structure */
- data = AR5K_TUNE_RSSI_THRES |
- AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
- ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
+
+ /* Set RSSI/BRSSI thresholds
+ *
+ * Note: If we decide to set this value
+ * dynamicaly, have in mind that when AR5K_RSSI_THR
+ * register is read it might return 0x40 if we haven't
+ * wrote anything to it plus BMISS RSSI threshold is zeroed.
+ * So doing a save/restore procedure here isn't the right
+ * choice. Instead store it on ath5k_hw */
+ ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
+ AR5K_TUNE_BMISS_THRES <<
+ AR5K_RSSI_THR_BMISS_S),
+ AR5K_RSSI_THR);
+
+ /* MIC QoS support */
+ if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
+ ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
+ ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
}
+ /* QoS NOACK Policy */
+ if (ah->ah_version == AR5K_AR5212) {
+ ath5k_hw_reg_write(ah,
+ AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
+ AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |
+ AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
+ AR5K_QOS_NOACK);
+ }
+
+
/*
- * Set Rx/Tx DMA Configuration
- *
- * Set maximum DMA size (512) except for PCI-E cards since
- * it causes rx overruns and tx errors (tested on 5424 but since
- * rx overruns also occur on 5416/5418 with madwifi we set 128
- * for all PCI-E cards to be safe).
- *
- * In dumps this is 128 for allchips.
- *
- * XXX: need to check 5210 for this
- * TODO: Check out tx triger level, it's always 64 on dumps but I
- * guess we can tweak it and see how it goes ;-)
+ * Configure PHY
*/
- dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B;
- if (ah->ah_version != AR5K_AR5210) {
- AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
- AR5K_TXCFG_SDMAMR, dma_size);
- AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
- AR5K_RXCFG_SDMAMW, dma_size);
- }
+
+ /* Set channel on PHY */
+ ret = ath5k_hw_channel(ah, channel);
+ if (ret)
+ return ret;
/*
* Enable the PHY and wait until completion
+ * This includes BaseBand and Synthesizer
+ * activation.
*/
ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
/*
* On 5211+ read activation -> rx delay
* and use it.
+ *
+ * TODO: Half/quarter rate support
*/
if (ah->ah_version != AR5K_AR5210) {
- data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
+ u32 delay;
+ delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
AR5K_PHY_RX_DELAY_M;
- data = (channel->hw_value & CHANNEL_CCK) ?
- ((data << 2) / 22) : (data / 10);
+ delay = (channel->hw_value & CHANNEL_CCK) ?
+ ((delay << 2) / 22) : (delay / 10);
- udelay(100 + (2 * data));
- data = 0;
+ udelay(100 + (2 * delay));
} else {
mdelay(1);
}
/*
- * Perform ADC test (?)
+ * Perform ADC test to see if baseband is ready
+ * Set tx hold and check adc test register
*/
- data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
+ phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
for (i = 0; i <= 20; i++) {
if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
break;
udelay(200);
}
- ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1);
- data = 0;
+ ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
/*
- * Start automatic gain calibration
+ * Start automatic gain control calibration
*
* During AGC calibration RX path is re-routed to
- * a signal detector so we don't receive anything.
+ * a power detector so we don't receive anything.
*
* This method is used to calibrate some static offsets
* used together with on-the fly I/Q calibration (the
* one performed via ath5k_hw_phy_calibrate), that doesn't
* interrupt rx path.
*
+ * While rx path is re-routed to the power detector we also
+ * start a noise floor calibration, to measure the
+ * card's noise floor (the noise we measure when we are not
+ * transmiting or receiving anything).
+ *
* If we are in a noisy environment AGC calibration may time
- * out.
+ * out and/or noise floor calibration might timeout.
*/
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
AR5K_PHY_AGCCTL_CAL);
@@ -828,30 +1243,37 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
AR5K_PHY_AGCCTL_CAL, 0, false)) {
ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
channel->center_freq);
- return -EAGAIN;
}
/*
- * Start noise floor calibration
- *
* If we run NF calibration before AGC, it always times out.
* Binary HAL starts NF and AGC calibration at the same time
- * and only waits for AGC to finish. I believe that's wrong because
- * during NF calibration, rx path is also routed to a detector, so if
- * it doesn't finish we won't have RX.
- *
- * XXX: Find an interval that's OK for all cards...
+ * and only waits for AGC to finish. Also if AGC or NF cal.
+ * times out, reset doesn't fail on binary HAL. I believe
+ * that's wrong because since rx path is routed to a detector,
+ * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211
+ * enables noise floor calibration after offset calibration and if noise
+ * floor calibration fails, reset fails. I believe that's
+ * a better approach, we just need to find a polling interval
+ * that suits best, even if reset continues we need to make
+ * sure that rx path is ready.
*/
ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
+
+ /*
+ * Configure QCUs/DCUs
+ */
+
+ /* TODO: HW Compression support for data queues */
+ /* TODO: Burst prefetch for data queues */
+
/*
* Reset queues and start beacon timers at the end of the reset routine
+ * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
+ * Note: If we want we can assign multiple qcus on one dcu.
*/
for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
- /*No QCU on 5210*/
- if (ah->ah_version != AR5K_AR5210)
- AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i);
-
ret = ath5k_hw_reset_tx_queue(ah, i);
if (ret) {
ATH5K_ERR(ah->ah_sc,
@@ -860,14 +1282,40 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
}
}
+
+ /*
+ * Configure DMA/Interrupts
+ */
+
+ /*
+ * Set Rx/Tx DMA Configuration
+ *
+ * Set standard DMA size (128). Note that
+ * a DMA size of 512 causes rx overruns and tx errors
+ * on pci-e cards (tested on 5424 but since rx overruns
+ * also occur on 5416/5418 with madwifi we set 128
+ * for all PCI-E cards to be safe).
+ *
+ * XXX: need to check 5210 for this
+ * TODO: Check out tx triger level, it's always 64 on dumps but I
+ * guess we can tweak it and see how it goes ;-)
+ */
+ if (ah->ah_version != AR5K_AR5210) {
+ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
+ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
+ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
+ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
+ }
+
/* Pre-enable interrupts on 5211/5212*/
if (ah->ah_version != AR5K_AR5210)
ath5k_hw_set_imr(ah, ah->ah_imr);
/*
- * Set RF kill flags if supported by the device (read from the EEPROM)
- * Disable gpio_intr for now since it results system hang.
- * TODO: Handle this in ath5k_intr
+ * Setup RFKill interrupt if rfkill flag is set on eeprom.
+ * TODO: Use gpio pin and polarity infos from eeprom
+ * TODO: Handle this in ath5k_intr because it'll result
+ * a nasty interrupt storm.
*/
#if 0
if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
@@ -880,33 +1328,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
}
#endif
- /*
- * Set the 32MHz reference clock on 5212 phy clock sleep register
- *
- * TODO: Find out how to switch to external 32Khz clock to save power
- */
- if (ah->ah_version == AR5K_AR5212) {
- ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
- ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
- ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
- ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
- ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
- ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
-
- data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ;
- data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ?
- 0x00000f80 : 0x00001380 ;
- ath5k_hw_reg_write(ah, data, AR5K_USEC_5211);
- data = 0;
- }
-
- if (ah->ah_version == AR5K_AR5212) {
- ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
- ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
- ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
- if (ah->ah_mac_srev >= AR5K_SREV_AR2413)
- ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
- }
+ /* Enable 32KHz clock function for AR5212+ chips
+ * Set clocks to 32KHz operation and use an
+ * external 32KHz crystal when sleeping if one
+ * exists */
+ if (ah->ah_version == AR5K_AR5212)
+ ath5k_hw_set_sleep_clock(ah, true);
/*
* Disable beacons and reset the register
diff --git a/drivers/net/wireless/ath5k/rfbuffer.h b/drivers/net/wireless/ath5k/rfbuffer.h
new file mode 100644
index 000000000000..e50baff66175
--- /dev/null
+++ b/drivers/net/wireless/ath5k/rfbuffer.h
@@ -0,0 +1,1181 @@
+/*
+ * RF Buffer handling functions
+ *
+ * Copyright (c) 2009 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+
+/*
+ * There are some special registers on the RF chip
+ * that control various operation settings related mostly to
+ * the analog parts (channel, gain adjustment etc).
+ *
+ * We don't write on those registers directly but
+ * we send a data packet on the chip, using a special register,
+ * that holds all the settings we need. After we 've sent the
+ * data packet, we write on another special register to notify hw
+ * to apply the settings. This is done so that control registers
+ * can be dynamicaly programmed during operation and the settings
+ * are applied faster on the hw.
+ *
+ * We call each data packet an "RF Bank" and all the data we write
+ * (all RF Banks) "RF Buffer". This file holds initial RF Buffer
+ * data for the different RF chips, and various info to match RF
+ * Buffer offsets with specific RF registers so that we can access
+ * them. We tweak these settings on rfregs_init function.
+ *
+ * Also check out reg.h and U.S. Patent 6677779 B1 (about buffer
+ * registers and control registers):
+ *
+ * http://www.google.com/patents?id=qNURAAAAEBAJ
+ */
+
+
+/*
+ * Struct to hold default mode specific RF
+ * register values (RF Banks)
+ */
+struct ath5k_ini_rfbuffer {
+ u8 rfb_bank; /* RF Bank number */
+ u16 rfb_ctrl_register; /* RF Buffer control register */
+ u32 rfb_mode_data[5]; /* RF Buffer data for each mode */
+};
+
+/*
+ * Struct to hold RF Buffer field
+ * infos used to access certain RF
+ * analog registers
+ */
+struct ath5k_rfb_field {
+ u8 len; /* Field length */
+ u16 pos; /* Offset on the raw packet */
+ u8 col; /* Column -used for shifting */
+};
+
+/*
+ * RF analog register definition
+ */
+struct ath5k_rf_reg {
+ u8 bank; /* RF Buffer Bank number */
+ u8 index; /* Register's index on rf_regs_idx */
+ struct ath5k_rfb_field field; /* RF Buffer field for this register */
+};
+
+/* Map RF registers to indexes
+ * We do this to handle common bits and make our
+ * life easier by using an index for each register
+ * instead of a full rfb_field */
+enum ath5k_rf_regs_idx {
+ /* BANK 6 */
+ AR5K_RF_OB_2GHZ = 0,
+ AR5K_RF_OB_5GHZ,
+ AR5K_RF_DB_2GHZ,
+ AR5K_RF_DB_5GHZ,
+ AR5K_RF_FIXED_BIAS_A,
+ AR5K_RF_FIXED_BIAS_B,
+ AR5K_RF_PWD_XPD,
+ AR5K_RF_XPD_SEL,
+ AR5K_RF_XPD_GAIN,
+ AR5K_RF_PD_GAIN_LO,
+ AR5K_RF_PD_GAIN_HI,
+ AR5K_RF_HIGH_VC_CP,
+ AR5K_RF_MID_VC_CP,
+ AR5K_RF_LOW_VC_CP,
+ AR5K_RF_PUSH_UP,
+ AR5K_RF_PAD2GND,
+ AR5K_RF_XB2_LVL,
+ AR5K_RF_XB5_LVL,
+ AR5K_RF_PWD_ICLOBUF_2G,
+ AR5K_RF_PWD_84,
+ AR5K_RF_PWD_90,
+ AR5K_RF_PWD_130,
+ AR5K_RF_PWD_131,
+ AR5K_RF_PWD_132,
+ AR5K_RF_PWD_136,
+ AR5K_RF_PWD_137,
+ AR5K_RF_PWD_138,
+ AR5K_RF_PWD_166,
+ AR5K_RF_PWD_167,
+ AR5K_RF_DERBY_CHAN_SEL_MODE,
+ /* BANK 7 */
+ AR5K_RF_GAIN_I,
+ AR5K_RF_PLO_SEL,
+ AR5K_RF_RFGAIN_SEL,
+ AR5K_RF_RFGAIN_STEP,
+ AR5K_RF_WAIT_S,
+ AR5K_RF_WAIT_I,
+ AR5K_RF_MAX_TIME,
+ AR5K_RF_MIXVGA_OVR,
+ AR5K_RF_MIXGAIN_OVR,
+ AR5K_RF_MIXGAIN_STEP,
+ AR5K_RF_PD_DELAY_A,
+ AR5K_RF_PD_DELAY_B,
+ AR5K_RF_PD_DELAY_XR,
+ AR5K_RF_PD_PERIOD_A,
+ AR5K_RF_PD_PERIOD_B,
+ AR5K_RF_PD_PERIOD_XR,
+};
+
+
+/*******************\
+* RF5111 (Sombrero) *
+\*******************/
+
+/* BANK 6 len pos col */
+#define AR5K_RF5111_OB_2GHZ { 3, 119, 0 }
+#define AR5K_RF5111_DB_2GHZ { 3, 122, 0 }
+
+#define AR5K_RF5111_OB_5GHZ { 3, 104, 0 }
+#define AR5K_RF5111_DB_5GHZ { 3, 107, 0 }
+
+#define AR5K_RF5111_PWD_XPD { 1, 95, 0 }
+#define AR5K_RF5111_XPD_GAIN { 4, 96, 0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5111_PWD(_n) { 1, (135 - _n), 3 }
+
+/* BANK 7 len pos col */
+#define AR5K_RF5111_GAIN_I { 6, 29, 0 }
+#define AR5K_RF5111_PLO_SEL { 1, 4, 0 }
+#define AR5K_RF5111_RFGAIN_SEL { 1, 36, 0 }
+#define AR5K_RF5111_RFGAIN_STEP { 6, 37, 0 }
+/* Only on AR5212 BaseBand and up */
+#define AR5K_RF5111_WAIT_S { 5, 19, 0 }
+#define AR5K_RF5111_WAIT_I { 5, 24, 0 }
+#define AR5K_RF5111_MAX_TIME { 2, 49, 0 }
+
+static const struct ath5k_rf_reg rf_regs_5111[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF5111_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF5111_DB_2GHZ},
+ {6, AR5K_RF_OB_5GHZ, AR5K_RF5111_OB_5GHZ},
+ {6, AR5K_RF_DB_5GHZ, AR5K_RF5111_DB_5GHZ},
+ {6, AR5K_RF_PWD_XPD, AR5K_RF5111_PWD_XPD},
+ {6, AR5K_RF_XPD_GAIN, AR5K_RF5111_XPD_GAIN},
+ {6, AR5K_RF_PWD_84, AR5K_RF5111_PWD(84)},
+ {6, AR5K_RF_PWD_90, AR5K_RF5111_PWD(90)},
+ {7, AR5K_RF_GAIN_I, AR5K_RF5111_GAIN_I},
+ {7, AR5K_RF_PLO_SEL, AR5K_RF5111_PLO_SEL},
+ {7, AR5K_RF_RFGAIN_SEL, AR5K_RF5111_RFGAIN_SEL},
+ {7, AR5K_RF_RFGAIN_STEP, AR5K_RF5111_RFGAIN_STEP},
+ {7, AR5K_RF_WAIT_S, AR5K_RF5111_WAIT_S},
+ {7, AR5K_RF_WAIT_I, AR5K_RF5111_WAIT_I},
+ {7, AR5K_RF_MAX_TIME, AR5K_RF5111_MAX_TIME}
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5111[] = {
+ { 0, 0x989c,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 0, 0x989c,
+ { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
+ { 0, 0x989c,
+ { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
+ { 0, 0x98d4,
+ { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
+ { 1, 0x98d4,
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d4,
+ { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
+ { 3, 0x98d8,
+ { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c,
+ { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
+ { 6, 0x989c,
+ { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
+ { 6, 0x989c,
+ { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
+ { 6, 0x989c,
+ { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
+ { 6, 0x989c,
+ { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
+ { 6, 0x98d4,
+ { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
+ { 7, 0x989c,
+ { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
+ { 7, 0x989c,
+ { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
+ { 7, 0x989c,
+ { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
+ { 7, 0x989c,
+ { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
+ { 7, 0x989c,
+ { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
+ { 7, 0x989c,
+ { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
+ { 7, 0x989c,
+ { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***********************\
+* RF5112/RF2112 (Derby) *
+\***********************/
+
+/* BANK 7 (Common) len pos col */
+#define AR5K_RF5112X_GAIN_I { 6, 14, 0 }
+#define AR5K_RF5112X_MIXVGA_OVR { 1, 36, 0 }
+#define AR5K_RF5112X_MIXGAIN_OVR { 2, 37, 0 }
+#define AR5K_RF5112X_MIXGAIN_STEP { 4, 32, 0 }
+#define AR5K_RF5112X_PD_DELAY_A { 4, 58, 0 }
+#define AR5K_RF5112X_PD_DELAY_B { 4, 62, 0 }
+#define AR5K_RF5112X_PD_DELAY_XR { 4, 66, 0 }
+#define AR5K_RF5112X_PD_PERIOD_A { 4, 70, 0 }
+#define AR5K_RF5112X_PD_PERIOD_B { 4, 74, 0 }
+#define AR5K_RF5112X_PD_PERIOD_XR { 4, 78, 0 }
+
+/* RFX112 (Derby 1) */
+
+/* BANK 6 len pos col */
+#define AR5K_RF5112_OB_2GHZ { 3, 269, 0 }
+#define AR5K_RF5112_DB_2GHZ { 3, 272, 0 }
+
+#define AR5K_RF5112_OB_5GHZ { 3, 261, 0 }
+#define AR5K_RF5112_DB_5GHZ { 3, 264, 0 }
+
+#define AR5K_RF5112_FIXED_BIAS_A { 1, 260, 0 }
+#define AR5K_RF5112_FIXED_BIAS_B { 1, 259, 0 }
+
+#define AR5K_RF5112_XPD_SEL { 1, 284, 0 }
+#define AR5K_RF5112_XPD_GAIN { 2, 252, 0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5112_PWD(_n) { 1, (302 - _n), 3 }
+
+static const struct ath5k_rf_reg rf_regs_5112[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF5112_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF5112_DB_2GHZ},
+ {6, AR5K_RF_OB_5GHZ, AR5K_RF5112_OB_5GHZ},
+ {6, AR5K_RF_DB_5GHZ, AR5K_RF5112_DB_5GHZ},
+ {6, AR5K_RF_FIXED_BIAS_A, AR5K_RF5112_FIXED_BIAS_A},
+ {6, AR5K_RF_FIXED_BIAS_B, AR5K_RF5112_FIXED_BIAS_B},
+ {6, AR5K_RF_XPD_SEL, AR5K_RF5112_XPD_SEL},
+ {6, AR5K_RF_XPD_GAIN, AR5K_RF5112_XPD_GAIN},
+ {6, AR5K_RF_PWD_130, AR5K_RF5112_PWD(130)},
+ {6, AR5K_RF_PWD_131, AR5K_RF5112_PWD(131)},
+ {6, AR5K_RF_PWD_132, AR5K_RF5112_PWD(132)},
+ {6, AR5K_RF_PWD_136, AR5K_RF5112_PWD(136)},
+ {6, AR5K_RF_PWD_137, AR5K_RF5112_PWD(137)},
+ {6, AR5K_RF_PWD_138, AR5K_RF5112_PWD(138)},
+ {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I},
+ {7, AR5K_RF_MIXVGA_OVR, AR5K_RF5112X_MIXVGA_OVR},
+ {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR},
+ {7, AR5K_RF_MIXGAIN_STEP, AR5K_RF5112X_MIXGAIN_STEP},
+ {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A},
+ {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B},
+ {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR},
+ {7, AR5K_RF_PD_PERIOD_A, AR5K_RF5112X_PD_PERIOD_A},
+ {7, AR5K_RF_PD_PERIOD_B, AR5K_RF5112X_PD_PERIOD_B},
+ {7, AR5K_RF_PD_PERIOD_XR, AR5K_RF5112X_PD_PERIOD_XR},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5112[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
+ { 3, 0x98dc,
+ { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
+ { 6, 0x989c,
+ { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
+ { 6, 0x989c,
+ { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
+ { 6, 0x989c,
+ { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
+ { 6, 0x989c,
+ { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
+ { 6, 0x989c,
+ { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+ { 6, 0x989c,
+ { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+ { 6, 0x989c,
+ { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
+ { 6, 0x989c,
+ { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
+ { 6, 0x989c,
+ { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+ { 6, 0x989c,
+ { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
+ { 6, 0x989c,
+ { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
+ { 6, 0x989c,
+ { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
+ { 6, 0x989c,
+ { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
+ { 6, 0x989c,
+ { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
+ { 6, 0x989c,
+ { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+ { 6, 0x989c,
+ { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+ { 6, 0x989c,
+ { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
+ { 6, 0x989c,
+ { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
+ { 6, 0x989c,
+ { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
+ { 6, 0x989c,
+ { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
+ { 6, 0x989c,
+ { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
+ { 6, 0x989c,
+ { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
+ { 6, 0x989c,
+ { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
+ { 6, 0x989c,
+ { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
+ { 6, 0x989c,
+ { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
+ { 6, 0x989c,
+ { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
+ { 6, 0x989c,
+ { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
+ { 6, 0x989c,
+ { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
+ { 6, 0x989c,
+ { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
+ { 6, 0x98d0,
+ { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
+ { 7, 0x989c,
+ { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
+ { 7, 0x989c,
+ { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
+ { 7, 0x989c,
+ { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
+ { 7, 0x989c,
+ { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
+ { 7, 0x989c,
+ { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
+ { 7, 0x989c,
+ { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+ { 7, 0x989c,
+ { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
+ { 7, 0x989c,
+ { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
+ { 7, 0x989c,
+ { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
+ { 7, 0x989c,
+ { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
+ { 7, 0x989c,
+ { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
+ { 7, 0x989c,
+ { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
+ { 7, 0x98c4,
+ { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+};
+
+/* RFX112A (Derby 2) */
+
+/* BANK 6 len pos col */
+#define AR5K_RF5112A_OB_2GHZ { 3, 287, 0 }
+#define AR5K_RF5112A_DB_2GHZ { 3, 290, 0 }
+
+#define AR5K_RF5112A_OB_5GHZ { 3, 279, 0 }
+#define AR5K_RF5112A_DB_5GHZ { 3, 282, 0 }
+
+#define AR5K_RF5112A_FIXED_BIAS_A { 1, 278, 0 }
+#define AR5K_RF5112A_FIXED_BIAS_B { 1, 277, 0 }
+
+#define AR5K_RF5112A_XPD_SEL { 1, 302, 0 }
+#define AR5K_RF5112A_PDGAINLO { 2, 270, 0 }
+#define AR5K_RF5112A_PDGAINHI { 2, 257, 0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5112A_PWD(_n) { 1, (306 - _n), 3 }
+
+/* Voltage regulators */
+#define AR5K_RF5112A_HIGH_VC_CP { 2, 90, 2 }
+#define AR5K_RF5112A_MID_VC_CP { 2, 92, 2 }
+#define AR5K_RF5112A_LOW_VC_CP { 2, 94, 2 }
+#define AR5K_RF5112A_PUSH_UP { 1, 254, 2 }
+
+/* Power consumption */
+#define AR5K_RF5112A_PAD2GND { 1, 281, 1 }
+#define AR5K_RF5112A_XB2_LVL { 2, 1, 3 }
+#define AR5K_RF5112A_XB5_LVL { 2, 3, 3 }
+
+static const struct ath5k_rf_reg rf_regs_5112a[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF5112A_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF5112A_DB_2GHZ},
+ {6, AR5K_RF_OB_5GHZ, AR5K_RF5112A_OB_5GHZ},
+ {6, AR5K_RF_DB_5GHZ, AR5K_RF5112A_DB_5GHZ},
+ {6, AR5K_RF_FIXED_BIAS_A, AR5K_RF5112A_FIXED_BIAS_A},
+ {6, AR5K_RF_FIXED_BIAS_B, AR5K_RF5112A_FIXED_BIAS_B},
+ {6, AR5K_RF_XPD_SEL, AR5K_RF5112A_XPD_SEL},
+ {6, AR5K_RF_PD_GAIN_LO, AR5K_RF5112A_PDGAINLO},
+ {6, AR5K_RF_PD_GAIN_HI, AR5K_RF5112A_PDGAINHI},
+ {6, AR5K_RF_PWD_130, AR5K_RF5112A_PWD(130)},
+ {6, AR5K_RF_PWD_131, AR5K_RF5112A_PWD(131)},
+ {6, AR5K_RF_PWD_132, AR5K_RF5112A_PWD(132)},
+ {6, AR5K_RF_PWD_136, AR5K_RF5112A_PWD(136)},
+ {6, AR5K_RF_PWD_137, AR5K_RF5112A_PWD(137)},
+ {6, AR5K_RF_PWD_138, AR5K_RF5112A_PWD(138)},
+ {6, AR5K_RF_PWD_166, AR5K_RF5112A_PWD(166)},
+ {6, AR5K_RF_PWD_167, AR5K_RF5112A_PWD(167)},
+ {6, AR5K_RF_HIGH_VC_CP, AR5K_RF5112A_HIGH_VC_CP},
+ {6, AR5K_RF_MID_VC_CP, AR5K_RF5112A_MID_VC_CP},
+ {6, AR5K_RF_LOW_VC_CP, AR5K_RF5112A_LOW_VC_CP},
+ {6, AR5K_RF_PUSH_UP, AR5K_RF5112A_PUSH_UP},
+ {6, AR5K_RF_PAD2GND, AR5K_RF5112A_PAD2GND},
+ {6, AR5K_RF_XB2_LVL, AR5K_RF5112A_XB2_LVL},
+ {6, AR5K_RF_XB5_LVL, AR5K_RF5112A_XB5_LVL},
+ {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I},
+ {7, AR5K_RF_MIXVGA_OVR, AR5K_RF5112X_MIXVGA_OVR},
+ {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR},
+ {7, AR5K_RF_MIXGAIN_STEP, AR5K_RF5112X_MIXGAIN_STEP},
+ {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A},
+ {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B},
+ {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR},
+ {7, AR5K_RF_PD_PERIOD_A, AR5K_RF5112X_PD_PERIOD_A},
+ {7, AR5K_RF_PD_PERIOD_B, AR5K_RF5112X_PD_PERIOD_B},
+ {7, AR5K_RF_PD_PERIOD_XR, AR5K_RF5112X_PD_PERIOD_XR},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
+ { 3, 0x98dc,
+ { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c,
+ { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
+ { 6, 0x989c,
+ { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c,
+ { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
+ { 6, 0x989c,
+ { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
+ { 6, 0x989c,
+ { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
+ { 6, 0x989c,
+ { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
+ { 6, 0x989c,
+ { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
+ { 6, 0x989c,
+ { 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000 } },
+ { 6, 0x989c,
+ { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
+ { 6, 0x989c,
+ { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+ { 6, 0x989c,
+ { 0x02190000, 0x02190000, 0x02190000, 0x02190000, 0x02190000 } },
+ { 6, 0x989c,
+ { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
+ { 6, 0x989c,
+ { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
+ { 6, 0x989c,
+ { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
+ { 6, 0x989c,
+ { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
+ { 6, 0x989c,
+ { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c,
+ { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+ { 6, 0x989c,
+ { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
+ { 6, 0x989c,
+ { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
+ { 6, 0x989c,
+ { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+ { 6, 0x989c,
+ { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
+ { 6, 0x989c,
+ { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
+ { 6, 0x989c,
+ { 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080 } },
+ { 6, 0x989c,
+ { 0x00270019, 0x00270019, 0x00270019, 0x00270019, 0x00270019 } },
+ { 6, 0x989c,
+ { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
+ { 6, 0x989c,
+ { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
+ { 6, 0x989c,
+ { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
+ { 6, 0x989c,
+ { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
+ { 6, 0x989c,
+ { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
+ { 6, 0x98d8,
+ { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
+ { 7, 0x989c,
+ { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
+ { 7, 0x989c,
+ { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
+ { 7, 0x989c,
+ { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
+ { 7, 0x989c,
+ { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
+ { 7, 0x989c,
+ { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
+ { 7, 0x989c,
+ { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+ { 7, 0x989c,
+ { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
+ { 7, 0x989c,
+ { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
+ { 7, 0x989c,
+ { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
+ { 7, 0x989c,
+ { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
+ { 7, 0x989c,
+ { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
+ { 7, 0x989c,
+ { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
+ { 7, 0x98c4,
+ { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+};
+
+
+
+/******************\
+* RF2413 (Griffin) *
+\******************/
+
+/* BANK 6 len pos col */
+#define AR5K_RF2413_OB_2GHZ { 3, 168, 0 }
+#define AR5K_RF2413_DB_2GHZ { 3, 165, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2413[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF2413_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF2413_DB_2GHZ},
+};
+
+/* Default mode specific settings
+ * XXX: a/aTurbo ???
+ */
+static const struct ath5k_ini_rfbuffer rfb_2413[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+ { 3, 0x98dc,
+ { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c,
+ { 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000 } },
+ { 6, 0x989c,
+ { 0x65050000, 0x65050000, 0x65050000, 0x65050000, 0x65050000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00420000, 0x00420000, 0x00420000, 0x00420000, 0x00420000 } },
+ { 6, 0x989c,
+ { 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000 } },
+ { 6, 0x989c,
+ { 0x00030000, 0x00030000, 0x00030000, 0x00030000, 0x00030000 } },
+ { 6, 0x989c,
+ { 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000 } },
+ { 6, 0x989c,
+ { 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000 } },
+ { 6, 0x989c,
+ { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
+ { 6, 0x989c,
+ { 0x04220000, 0x04220000, 0x04220000, 0x04220000, 0x04220000 } },
+ { 6, 0x989c,
+ { 0x00230018, 0x00230018, 0x00230018, 0x00230018, 0x00230018 } },
+ { 6, 0x989c,
+ { 0x00280000, 0x00280000, 0x00280060, 0x00280060, 0x00280060 } },
+ { 6, 0x989c,
+ { 0x005000c0, 0x005000c0, 0x005000c3, 0x005000c3, 0x005000c3 } },
+ { 6, 0x989c,
+ { 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f } },
+ { 6, 0x989c,
+ { 0x00000458, 0x00000458, 0x00000458, 0x00000458, 0x00000458 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000 } },
+ { 6, 0x98d8,
+ { 0x00400230, 0x00400230, 0x00400230, 0x00400230, 0x00400230 } },
+ { 7, 0x989c,
+ { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c,
+ { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***************************\
+* RF2315/RF2316 (Cobra SoC) *
+\***************************/
+
+/* BANK 6 len pos col */
+#define AR5K_RF2316_OB_2GHZ { 3, 178, 0 }
+#define AR5K_RF2316_DB_2GHZ { 3, 175, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2316[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF2316_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF2316_DB_2GHZ},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_2316[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+ { 3, 0x98dc,
+ { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 } },
+ { 6, 0x989c,
+ { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
+ { 6, 0x989c,
+ { 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x95150000, 0x95150000, 0x95150000, 0x95150000, 0x95150000 } },
+ { 6, 0x989c,
+ { 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000 } },
+ { 6, 0x989c,
+ { 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000 } },
+ { 6, 0x989c,
+ { 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000 } },
+ { 6, 0x989c,
+ { 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
+ { 6, 0x989c,
+ { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
+ { 6, 0x989c,
+ { 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000 } },
+ { 6, 0x989c,
+ { 0x10880000, 0x10880000, 0x10880000, 0x10880000, 0x10880000 } },
+ { 6, 0x989c,
+ { 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060 } },
+ { 6, 0x989c,
+ { 0x00a00000, 0x00a00000, 0x00a00080, 0x00a00080, 0x00a00080 } },
+ { 6, 0x989c,
+ { 0x00400000, 0x00400000, 0x0040000d, 0x0040000d, 0x0040000d } },
+ { 6, 0x989c,
+ { 0x00110400, 0x00110400, 0x00110400, 0x00110400, 0x00110400 } },
+ { 6, 0x989c,
+ { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+ { 6, 0x989c,
+ { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+ { 6, 0x989c,
+ { 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00 } },
+ { 6, 0x989c,
+ { 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8 } },
+ { 6, 0x98c0,
+ { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
+ { 7, 0x989c,
+ { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c,
+ { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/******************************\
+* RF5413/RF5424 (Eagle/Condor) *
+\******************************/
+
+/* BANK 6 len pos col */
+#define AR5K_RF5413_OB_2GHZ { 3, 241, 0 }
+#define AR5K_RF5413_DB_2GHZ { 3, 238, 0 }
+
+#define AR5K_RF5413_OB_5GHZ { 3, 247, 0 }
+#define AR5K_RF5413_DB_5GHZ { 3, 244, 0 }
+
+#define AR5K_RF5413_PWD_ICLOBUF2G { 3, 131, 3 }
+#define AR5K_RF5413_DERBY_CHAN_SEL_MODE { 1, 291, 2 }
+
+static const struct ath5k_rf_reg rf_regs_5413[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF5413_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF5413_DB_2GHZ},
+ {6, AR5K_RF_OB_5GHZ, AR5K_RF5413_OB_5GHZ},
+ {6, AR5K_RF_DB_5GHZ, AR5K_RF5413_DB_5GHZ},
+ {6, AR5K_RF_PWD_ICLOBUF_2G, AR5K_RF5413_PWD_ICLOBUF2G},
+ {6, AR5K_RF_DERBY_CHAN_SEL_MODE, AR5K_RF5413_DERBY_CHAN_SEL_MODE},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5413[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
+ { 3, 0x98dc,
+ { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
+ { 6, 0x989c,
+ { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
+ { 6, 0x989c,
+ { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
+ { 6, 0x989c,
+ { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
+ { 6, 0x989c,
+ { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
+ { 6, 0x989c,
+ { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
+ { 6, 0x989c,
+ { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+ { 6, 0x989c,
+ { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
+ { 6, 0x989c,
+ { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
+ { 6, 0x989c,
+ { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
+ { 6, 0x989c,
+ { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
+ { 6, 0x989c,
+ { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
+ { 6, 0x989c,
+ { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
+ { 6, 0x989c,
+ { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
+ { 6, 0x989c,
+ { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
+ { 6, 0x989c,
+ { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
+ { 6, 0x989c,
+ { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
+ { 6, 0x989c,
+ { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
+ { 6, 0x989c,
+ { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
+ { 6, 0x989c,
+ { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
+ { 6, 0x989c,
+ { 0x00510040, 0x00510040, 0x00510040, 0x00510040, 0x00510040 } },
+ { 6, 0x989c,
+ { 0x005000da, 0x005000da, 0x005000da, 0x005000da, 0x005000da } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
+ { 6, 0x989c,
+ { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00002c00 } },
+ { 6, 0x98c8,
+ { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
+ { 7, 0x989c,
+ { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c,
+ { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***************************\
+* RF2425/RF2417 (Swan/Nala) *
+* AR2317 (Spider SoC) *
+\***************************/
+
+/* BANK 6 len pos col */
+#define AR5K_RF2425_OB_2GHZ { 3, 193, 0 }
+#define AR5K_RF2425_DB_2GHZ { 3, 190, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2425[] = {
+ {6, AR5K_RF_OB_2GHZ, AR5K_RF2425_OB_2GHZ},
+ {6, AR5K_RF_DB_2GHZ, AR5K_RF2425_DB_2GHZ},
+};
+
+/* Default mode specific settings
+ * XXX: a/aTurbo ?
+ */
+static const struct ath5k_ini_rfbuffer rfb_2425[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc,
+ { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c,
+ { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+ { 6, 0x989c,
+ { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+ { 6, 0x989c,
+ { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c,
+ { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+ { 6, 0x989c,
+ { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
+ { 6, 0x989c,
+ { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
+ { 6, 0x989c,
+ { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+ { 6, 0x989c,
+ { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
+ { 6, 0x989c,
+ { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+ { 6, 0x989c,
+ { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+ { 6, 0x989c,
+ { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+ { 6, 0x989c,
+ { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
+ { 6, 0x98c4,
+ { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+ { 7, 0x989c,
+ { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c,
+ { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+/*
+ * TODO: Handle the few differences with swan during
+ * bank modification and get rid of this
+ */
+static const struct ath5k_ini_rfbuffer rfb_2317[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+ { 3, 0x98dc,
+ { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c,
+ { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+ { 6, 0x989c,
+ { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+ { 6, 0x989c,
+ { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c,
+ { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+ { 6, 0x989c,
+ { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
+ { 6, 0x989c,
+ { 0x00140100, 0x00140100, 0x00140100, 0x00140100, 0x00140100 } },
+ { 6, 0x989c,
+ { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+ { 6, 0x989c,
+ { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
+ { 6, 0x989c,
+ { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+ { 6, 0x989c,
+ { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+ { 6, 0x989c,
+ { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+ { 6, 0x989c,
+ { 0x00009688, 0x00009688, 0x00009688, 0x00009688, 0x00009688 } },
+ { 6, 0x98c4,
+ { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+ { 7, 0x989c,
+ { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c,
+ { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+/*
+ * TODO: Handle the few differences with swan during
+ * bank modification and get rid of this
+ * XXX: a/aTurbo ?
+ */
+static const struct ath5k_ini_rfbuffer rfb_2417[] = {
+ { 1, 0x98d4,
+ /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
+ { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+ { 2, 0x98d0,
+ { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
+ { 3, 0x98dc,
+ { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+ { 6, 0x989c,
+ { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+ { 6, 0x989c,
+ { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+ { 6, 0x989c,
+ { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+ { 6, 0x989c,
+ { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+ { 6, 0x989c,
+ { 0x00e70000, 0x00e70000, 0x80e70000, 0x80e70000, 0x00e70000 } },
+ { 6, 0x989c,
+ { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
+ { 6, 0x989c,
+ { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+ { 6, 0x989c,
+ { 0x0007001a, 0x0007001a, 0x0207001a, 0x0207001a, 0x0007001a } },
+ { 6, 0x989c,
+ { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+ { 6, 0x989c,
+ { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+ { 6, 0x989c,
+ { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ { 6, 0x989c,
+ { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+ { 6, 0x989c,
+ { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
+ { 6, 0x98c4,
+ { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+ { 7, 0x989c,
+ { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+ { 7, 0x989c,
+ { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+ { 7, 0x98cc,
+ { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
diff --git a/drivers/net/wireless/ath5k/rfgain.h b/drivers/net/wireless/ath5k/rfgain.h
new file mode 100644
index 000000000000..1354d8c392c8
--- /dev/null
+++ b/drivers/net/wireless/ath5k/rfgain.h
@@ -0,0 +1,516 @@
+/*
+ * RF Gain optimization
+ *
+ * Copyright (c) 2004-2009 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+ * Mode-specific RF Gain table (64bytes) for RF5111/5112
+ * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
+ * RF Gain values are included in AR5K_AR5210_INI)
+ */
+struct ath5k_ini_rfgain {
+ u16 rfg_register; /* RF Gain register address */
+ u32 rfg_value[2]; /* [freq (see below)] */
+};
+
+/* Initial RF Gain settings for RF5111 */
+static const struct ath5k_ini_rfgain rfgain_5111[] = {
+ /* 5Ghz 2Ghz */
+ { AR5K_RF_GAIN(0), { 0x000001a9, 0x00000000 } },
+ { AR5K_RF_GAIN(1), { 0x000001e9, 0x00000040 } },
+ { AR5K_RF_GAIN(2), { 0x00000029, 0x00000080 } },
+ { AR5K_RF_GAIN(3), { 0x00000069, 0x00000150 } },
+ { AR5K_RF_GAIN(4), { 0x00000199, 0x00000190 } },
+ { AR5K_RF_GAIN(5), { 0x000001d9, 0x000001d0 } },
+ { AR5K_RF_GAIN(6), { 0x00000019, 0x00000010 } },
+ { AR5K_RF_GAIN(7), { 0x00000059, 0x00000044 } },
+ { AR5K_RF_GAIN(8), { 0x00000099, 0x00000084 } },
+ { AR5K_RF_GAIN(9), { 0x000001a5, 0x00000148 } },
+ { AR5K_RF_GAIN(10), { 0x000001e5, 0x00000188 } },
+ { AR5K_RF_GAIN(11), { 0x00000025, 0x000001c8 } },
+ { AR5K_RF_GAIN(12), { 0x000001c8, 0x00000014 } },
+ { AR5K_RF_GAIN(13), { 0x00000008, 0x00000042 } },
+ { AR5K_RF_GAIN(14), { 0x00000048, 0x00000082 } },
+ { AR5K_RF_GAIN(15), { 0x00000088, 0x00000178 } },
+ { AR5K_RF_GAIN(16), { 0x00000198, 0x000001b8 } },
+ { AR5K_RF_GAIN(17), { 0x000001d8, 0x000001f8 } },
+ { AR5K_RF_GAIN(18), { 0x00000018, 0x00000012 } },
+ { AR5K_RF_GAIN(19), { 0x00000058, 0x00000052 } },
+ { AR5K_RF_GAIN(20), { 0x00000098, 0x00000092 } },
+ { AR5K_RF_GAIN(21), { 0x000001a4, 0x0000017c } },
+ { AR5K_RF_GAIN(22), { 0x000001e4, 0x000001bc } },
+ { AR5K_RF_GAIN(23), { 0x00000024, 0x000001fc } },
+ { AR5K_RF_GAIN(24), { 0x00000064, 0x0000000a } },
+ { AR5K_RF_GAIN(25), { 0x000000a4, 0x0000004a } },
+ { AR5K_RF_GAIN(26), { 0x000000e4, 0x0000008a } },
+ { AR5K_RF_GAIN(27), { 0x0000010a, 0x0000015a } },
+ { AR5K_RF_GAIN(28), { 0x0000014a, 0x0000019a } },
+ { AR5K_RF_GAIN(29), { 0x0000018a, 0x000001da } },
+ { AR5K_RF_GAIN(30), { 0x000001ca, 0x0000000e } },
+ { AR5K_RF_GAIN(31), { 0x0000000a, 0x0000004e } },
+ { AR5K_RF_GAIN(32), { 0x0000004a, 0x0000008e } },
+ { AR5K_RF_GAIN(33), { 0x0000008a, 0x0000015e } },
+ { AR5K_RF_GAIN(34), { 0x000001ba, 0x0000019e } },
+ { AR5K_RF_GAIN(35), { 0x000001fa, 0x000001de } },
+ { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000009 } },
+ { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000049 } },
+ { AR5K_RF_GAIN(38), { 0x00000186, 0x00000089 } },
+ { AR5K_RF_GAIN(39), { 0x000001c6, 0x00000179 } },
+ { AR5K_RF_GAIN(40), { 0x00000006, 0x000001b9 } },
+ { AR5K_RF_GAIN(41), { 0x00000046, 0x000001f9 } },
+ { AR5K_RF_GAIN(42), { 0x00000086, 0x00000039 } },
+ { AR5K_RF_GAIN(43), { 0x000000c6, 0x00000079 } },
+ { AR5K_RF_GAIN(44), { 0x000000c6, 0x000000b9 } },
+ { AR5K_RF_GAIN(45), { 0x000000c6, 0x000001bd } },
+ { AR5K_RF_GAIN(46), { 0x000000c6, 0x000001fd } },
+ { AR5K_RF_GAIN(47), { 0x000000c6, 0x0000003d } },
+ { AR5K_RF_GAIN(48), { 0x000000c6, 0x0000007d } },
+ { AR5K_RF_GAIN(49), { 0x000000c6, 0x000000bd } },
+ { AR5K_RF_GAIN(50), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(51), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(52), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(53), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(54), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(55), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(56), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(57), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(58), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(59), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(60), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(61), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(62), { 0x000000c6, 0x000000fd } },
+ { AR5K_RF_GAIN(63), { 0x000000c6, 0x000000fd } },
+};
+
+/* Initial RF Gain settings for RF5112 */
+static const struct ath5k_ini_rfgain rfgain_5112[] = {
+ /* 5Ghz 2Ghz */
+ { AR5K_RF_GAIN(0), { 0x00000007, 0x00000007 } },
+ { AR5K_RF_GAIN(1), { 0x00000047, 0x00000047 } },
+ { AR5K_RF_GAIN(2), { 0x00000087, 0x00000087 } },
+ { AR5K_RF_GAIN(3), { 0x000001a0, 0x000001a0 } },
+ { AR5K_RF_GAIN(4), { 0x000001e0, 0x000001e0 } },
+ { AR5K_RF_GAIN(5), { 0x00000020, 0x00000020 } },
+ { AR5K_RF_GAIN(6), { 0x00000060, 0x00000060 } },
+ { AR5K_RF_GAIN(7), { 0x000001a1, 0x000001a1 } },
+ { AR5K_RF_GAIN(8), { 0x000001e1, 0x000001e1 } },
+ { AR5K_RF_GAIN(9), { 0x00000021, 0x00000021 } },
+ { AR5K_RF_GAIN(10), { 0x00000061, 0x00000061 } },
+ { AR5K_RF_GAIN(11), { 0x00000162, 0x00000162 } },
+ { AR5K_RF_GAIN(12), { 0x000001a2, 0x000001a2 } },
+ { AR5K_RF_GAIN(13), { 0x000001e2, 0x000001e2 } },
+ { AR5K_RF_GAIN(14), { 0x00000022, 0x00000022 } },
+ { AR5K_RF_GAIN(15), { 0x00000062, 0x00000062 } },
+ { AR5K_RF_GAIN(16), { 0x00000163, 0x00000163 } },
+ { AR5K_RF_GAIN(17), { 0x000001a3, 0x000001a3 } },
+ { AR5K_RF_GAIN(18), { 0x000001e3, 0x000001e3 } },
+ { AR5K_RF_GAIN(19), { 0x00000023, 0x00000023 } },
+ { AR5K_RF_GAIN(20), { 0x00000063, 0x00000063 } },
+ { AR5K_RF_GAIN(21), { 0x00000184, 0x00000184 } },
+ { AR5K_RF_GAIN(22), { 0x000001c4, 0x000001c4 } },
+ { AR5K_RF_GAIN(23), { 0x00000004, 0x00000004 } },
+ { AR5K_RF_GAIN(24), { 0x000001ea, 0x0000000b } },
+ { AR5K_RF_GAIN(25), { 0x0000002a, 0x0000004b } },
+ { AR5K_RF_GAIN(26), { 0x0000006a, 0x0000008b } },
+ { AR5K_RF_GAIN(27), { 0x000000aa, 0x000001ac } },
+ { AR5K_RF_GAIN(28), { 0x000001ab, 0x000001ec } },
+ { AR5K_RF_GAIN(29), { 0x000001eb, 0x0000002c } },
+ { AR5K_RF_GAIN(30), { 0x0000002b, 0x00000012 } },
+ { AR5K_RF_GAIN(31), { 0x0000006b, 0x00000052 } },
+ { AR5K_RF_GAIN(32), { 0x000000ab, 0x00000092 } },
+ { AR5K_RF_GAIN(33), { 0x000001ac, 0x00000193 } },
+ { AR5K_RF_GAIN(34), { 0x000001ec, 0x000001d3 } },
+ { AR5K_RF_GAIN(35), { 0x0000002c, 0x00000013 } },
+ { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000053 } },
+ { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000093 } },
+ { AR5K_RF_GAIN(38), { 0x000000ba, 0x00000194 } },
+ { AR5K_RF_GAIN(39), { 0x000001bb, 0x000001d4 } },
+ { AR5K_RF_GAIN(40), { 0x000001fb, 0x00000014 } },
+ { AR5K_RF_GAIN(41), { 0x0000003b, 0x0000003a } },
+ { AR5K_RF_GAIN(42), { 0x0000007b, 0x0000007a } },
+ { AR5K_RF_GAIN(43), { 0x000000bb, 0x000000ba } },
+ { AR5K_RF_GAIN(44), { 0x000001bc, 0x000001bb } },
+ { AR5K_RF_GAIN(45), { 0x000001fc, 0x000001fb } },
+ { AR5K_RF_GAIN(46), { 0x0000003c, 0x0000003b } },
+ { AR5K_RF_GAIN(47), { 0x0000007c, 0x0000007b } },
+ { AR5K_RF_GAIN(48), { 0x000000bc, 0x000000bb } },
+ { AR5K_RF_GAIN(49), { 0x000000fc, 0x000001bc } },
+ { AR5K_RF_GAIN(50), { 0x000000fc, 0x000001fc } },
+ { AR5K_RF_GAIN(51), { 0x000000fc, 0x0000003c } },
+ { AR5K_RF_GAIN(52), { 0x000000fc, 0x0000007c } },
+ { AR5K_RF_GAIN(53), { 0x000000fc, 0x000000bc } },
+ { AR5K_RF_GAIN(54), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(55), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(56), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(57), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(58), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(59), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(60), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(61), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(62), { 0x000000fc, 0x000000fc } },
+ { AR5K_RF_GAIN(63), { 0x000000fc, 0x000000fc } },
+};
+
+/* Initial RF Gain settings for RF2413 */
+static const struct ath5k_ini_rfgain rfgain_2413[] = {
+ { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
+ { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } },
+ { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } },
+ { AR5K_RF_GAIN(3), { 0x00000000, 0x00000181 } },
+ { AR5K_RF_GAIN(4), { 0x00000000, 0x000001c1 } },
+ { AR5K_RF_GAIN(5), { 0x00000000, 0x00000001 } },
+ { AR5K_RF_GAIN(6), { 0x00000000, 0x00000041 } },
+ { AR5K_RF_GAIN(7), { 0x00000000, 0x00000081 } },
+ { AR5K_RF_GAIN(8), { 0x00000000, 0x00000168 } },
+ { AR5K_RF_GAIN(9), { 0x00000000, 0x000001a8 } },
+ { AR5K_RF_GAIN(10), { 0x00000000, 0x000001e8 } },
+ { AR5K_RF_GAIN(11), { 0x00000000, 0x00000028 } },
+ { AR5K_RF_GAIN(12), { 0x00000000, 0x00000068 } },
+ { AR5K_RF_GAIN(13), { 0x00000000, 0x00000189 } },
+ { AR5K_RF_GAIN(14), { 0x00000000, 0x000001c9 } },
+ { AR5K_RF_GAIN(15), { 0x00000000, 0x00000009 } },
+ { AR5K_RF_GAIN(16), { 0x00000000, 0x00000049 } },
+ { AR5K_RF_GAIN(17), { 0x00000000, 0x00000089 } },
+ { AR5K_RF_GAIN(18), { 0x00000000, 0x00000190 } },
+ { AR5K_RF_GAIN(19), { 0x00000000, 0x000001d0 } },
+ { AR5K_RF_GAIN(20), { 0x00000000, 0x00000010 } },
+ { AR5K_RF_GAIN(21), { 0x00000000, 0x00000050 } },
+ { AR5K_RF_GAIN(22), { 0x00000000, 0x00000090 } },
+ { AR5K_RF_GAIN(23), { 0x00000000, 0x00000191 } },
+ { AR5K_RF_GAIN(24), { 0x00000000, 0x000001d1 } },
+ { AR5K_RF_GAIN(25), { 0x00000000, 0x00000011 } },
+ { AR5K_RF_GAIN(26), { 0x00000000, 0x00000051 } },
+ { AR5K_RF_GAIN(27), { 0x00000000, 0x00000091 } },
+ { AR5K_RF_GAIN(28), { 0x00000000, 0x00000178 } },
+ { AR5K_RF_GAIN(29), { 0x00000000, 0x000001b8 } },
+ { AR5K_RF_GAIN(30), { 0x00000000, 0x000001f8 } },
+ { AR5K_RF_GAIN(31), { 0x00000000, 0x00000038 } },
+ { AR5K_RF_GAIN(32), { 0x00000000, 0x00000078 } },
+ { AR5K_RF_GAIN(33), { 0x00000000, 0x00000199 } },
+ { AR5K_RF_GAIN(34), { 0x00000000, 0x000001d9 } },
+ { AR5K_RF_GAIN(35), { 0x00000000, 0x00000019 } },
+ { AR5K_RF_GAIN(36), { 0x00000000, 0x00000059 } },
+ { AR5K_RF_GAIN(37), { 0x00000000, 0x00000099 } },
+ { AR5K_RF_GAIN(38), { 0x00000000, 0x000000d9 } },
+ { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f9 } },
+};
+
+/* Initial RF Gain settings for AR2316 */
+static const struct ath5k_ini_rfgain rfgain_2316[] = {
+ { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
+ { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } },
+ { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } },
+ { AR5K_RF_GAIN(3), { 0x00000000, 0x000000c0 } },
+ { AR5K_RF_GAIN(4), { 0x00000000, 0x000000e0 } },
+ { AR5K_RF_GAIN(5), { 0x00000000, 0x000000e0 } },
+ { AR5K_RF_GAIN(6), { 0x00000000, 0x00000128 } },
+ { AR5K_RF_GAIN(7), { 0x00000000, 0x00000128 } },
+ { AR5K_RF_GAIN(8), { 0x00000000, 0x00000128 } },
+ { AR5K_RF_GAIN(9), { 0x00000000, 0x00000168 } },
+ { AR5K_RF_GAIN(10), { 0x00000000, 0x000001a8 } },
+ { AR5K_RF_GAIN(11), { 0x00000000, 0x000001e8 } },
+ { AR5K_RF_GAIN(12), { 0x00000000, 0x00000028 } },
+ { AR5K_RF_GAIN(13), { 0x00000000, 0x00000068 } },
+ { AR5K_RF_GAIN(14), { 0x00000000, 0x000000a8 } },
+ { AR5K_RF_GAIN(15), { 0x00000000, 0x000000e8 } },
+ { AR5K_RF_GAIN(16), { 0x00000000, 0x000000e8 } },
+ { AR5K_RF_GAIN(17), { 0x00000000, 0x00000130 } },
+ { AR5K_RF_GAIN(18), { 0x00000000, 0x00000130 } },
+ { AR5K_RF_GAIN(19), { 0x00000000, 0x00000170 } },
+ { AR5K_RF_GAIN(20), { 0x00000000, 0x000001b0 } },
+ { AR5K_RF_GAIN(21), { 0x00000000, 0x000001f0 } },
+ { AR5K_RF_GAIN(22), { 0x00000000, 0x00000030 } },
+ { AR5K_RF_GAIN(23), { 0x00000000, 0x00000070 } },
+ { AR5K_RF_GAIN(24), { 0x00000000, 0x000000b0 } },
+ { AR5K_RF_GAIN(25), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(26), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(27), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(28), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(29), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(30), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(31), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(32), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(33), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(34), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(35), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(36), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(37), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(38), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f0 } },
+ { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f0 } },
+};
+
+
+/* Initial RF Gain settings for RF5413 */
+static const struct ath5k_ini_rfgain rfgain_5413[] = {
+ /* 5Ghz 2Ghz */
+ { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
+ { AR5K_RF_GAIN(1), { 0x00000040, 0x00000040 } },
+ { AR5K_RF_GAIN(2), { 0x00000080, 0x00000080 } },
+ { AR5K_RF_GAIN(3), { 0x000001a1, 0x00000161 } },
+ { AR5K_RF_GAIN(4), { 0x000001e1, 0x000001a1 } },
+ { AR5K_RF_GAIN(5), { 0x00000021, 0x000001e1 } },
+ { AR5K_RF_GAIN(6), { 0x00000061, 0x00000021 } },
+ { AR5K_RF_GAIN(7), { 0x00000188, 0x00000061 } },
+ { AR5K_RF_GAIN(8), { 0x000001c8, 0x00000188 } },
+ { AR5K_RF_GAIN(9), { 0x00000008, 0x000001c8 } },
+ { AR5K_RF_GAIN(10), { 0x00000048, 0x00000008 } },
+ { AR5K_RF_GAIN(11), { 0x00000088, 0x00000048 } },
+ { AR5K_RF_GAIN(12), { 0x000001a9, 0x00000088 } },
+ { AR5K_RF_GAIN(13), { 0x000001e9, 0x00000169 } },
+ { AR5K_RF_GAIN(14), { 0x00000029, 0x000001a9 } },
+ { AR5K_RF_GAIN(15), { 0x00000069, 0x000001e9 } },
+ { AR5K_RF_GAIN(16), { 0x000001d0, 0x00000029 } },
+ { AR5K_RF_GAIN(17), { 0x00000010, 0x00000069 } },
+ { AR5K_RF_GAIN(18), { 0x00000050, 0x00000190 } },
+ { AR5K_RF_GAIN(19), { 0x00000090, 0x000001d0 } },
+ { AR5K_RF_GAIN(20), { 0x000001b1, 0x00000010 } },
+ { AR5K_RF_GAIN(21), { 0x000001f1, 0x00000050 } },
+ { AR5K_RF_GAIN(22), { 0x00000031, 0x00000090 } },
+ { AR5K_RF_GAIN(23), { 0x00000071, 0x00000171 } },
+ { AR5K_RF_GAIN(24), { 0x000001b8, 0x000001b1 } },
+ { AR5K_RF_GAIN(25), { 0x000001f8, 0x000001f1 } },
+ { AR5K_RF_GAIN(26), { 0x00000038, 0x00000031 } },
+ { AR5K_RF_GAIN(27), { 0x00000078, 0x00000071 } },
+ { AR5K_RF_GAIN(28), { 0x00000199, 0x00000198 } },
+ { AR5K_RF_GAIN(29), { 0x000001d9, 0x000001d8 } },
+ { AR5K_RF_GAIN(30), { 0x00000019, 0x00000018 } },
+ { AR5K_RF_GAIN(31), { 0x00000059, 0x00000058 } },
+ { AR5K_RF_GAIN(32), { 0x00000099, 0x00000098 } },
+ { AR5K_RF_GAIN(33), { 0x000000d9, 0x00000179 } },
+ { AR5K_RF_GAIN(34), { 0x000000f9, 0x000001b9 } },
+ { AR5K_RF_GAIN(35), { 0x000000f9, 0x000001f9 } },
+ { AR5K_RF_GAIN(36), { 0x000000f9, 0x00000039 } },
+ { AR5K_RF_GAIN(37), { 0x000000f9, 0x00000079 } },
+ { AR5K_RF_GAIN(38), { 0x000000f9, 0x000000b9 } },
+ { AR5K_RF_GAIN(39), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(40), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(41), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(42), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(43), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(44), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(45), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(46), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(47), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(48), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(49), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(50), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(51), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(52), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(53), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(54), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(55), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(56), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(57), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(58), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(59), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(60), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(61), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(62), { 0x000000f9, 0x000000f9 } },
+ { AR5K_RF_GAIN(63), { 0x000000f9, 0x000000f9 } },
+};
+
+
+/* Initial RF Gain settings for RF2425 */
+static const struct ath5k_ini_rfgain rfgain_2425[] = {
+ { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
+ { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } },
+ { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } },
+ { AR5K_RF_GAIN(3), { 0x00000000, 0x00000181 } },
+ { AR5K_RF_GAIN(4), { 0x00000000, 0x000001c1 } },
+ { AR5K_RF_GAIN(5), { 0x00000000, 0x00000001 } },
+ { AR5K_RF_GAIN(6), { 0x00000000, 0x00000041 } },
+ { AR5K_RF_GAIN(7), { 0x00000000, 0x00000081 } },
+ { AR5K_RF_GAIN(8), { 0x00000000, 0x00000188 } },
+ { AR5K_RF_GAIN(9), { 0x00000000, 0x000001c8 } },
+ { AR5K_RF_GAIN(10), { 0x00000000, 0x00000008 } },
+ { AR5K_RF_GAIN(11), { 0x00000000, 0x00000048 } },
+ { AR5K_RF_GAIN(12), { 0x00000000, 0x00000088 } },
+ { AR5K_RF_GAIN(13), { 0x00000000, 0x00000189 } },
+ { AR5K_RF_GAIN(14), { 0x00000000, 0x000001c9 } },
+ { AR5K_RF_GAIN(15), { 0x00000000, 0x00000009 } },
+ { AR5K_RF_GAIN(16), { 0x00000000, 0x00000049 } },
+ { AR5K_RF_GAIN(17), { 0x00000000, 0x00000089 } },
+ { AR5K_RF_GAIN(18), { 0x00000000, 0x000001b0 } },
+ { AR5K_RF_GAIN(19), { 0x00000000, 0x000001f0 } },
+ { AR5K_RF_GAIN(20), { 0x00000000, 0x00000030 } },
+ { AR5K_RF_GAIN(21), { 0x00000000, 0x00000070 } },
+ { AR5K_RF_GAIN(22), { 0x00000000, 0x00000171 } },
+ { AR5K_RF_GAIN(23), { 0x00000000, 0x000001b1 } },
+ { AR5K_RF_GAIN(24), { 0x00000000, 0x000001f1 } },
+ { AR5K_RF_GAIN(25), { 0x00000000, 0x00000031 } },
+ { AR5K_RF_GAIN(26), { 0x00000000, 0x00000071 } },
+ { AR5K_RF_GAIN(27), { 0x00000000, 0x000001b8 } },
+ { AR5K_RF_GAIN(28), { 0x00000000, 0x000001f8 } },
+ { AR5K_RF_GAIN(29), { 0x00000000, 0x00000038 } },
+ { AR5K_RF_GAIN(30), { 0x00000000, 0x00000078 } },
+ { AR5K_RF_GAIN(31), { 0x00000000, 0x000000b8 } },
+ { AR5K_RF_GAIN(32), { 0x00000000, 0x000001b9 } },
+ { AR5K_RF_GAIN(33), { 0x00000000, 0x000001f9 } },
+ { AR5K_RF_GAIN(34), { 0x00000000, 0x00000039 } },
+ { AR5K_RF_GAIN(35), { 0x00000000, 0x00000079 } },
+ { AR5K_RF_GAIN(36), { 0x00000000, 0x000000b9 } },
+ { AR5K_RF_GAIN(37), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(38), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f9 } },
+ { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f9 } },
+};
+
+#define AR5K_GAIN_CRN_FIX_BITS_5111 4
+#define AR5K_GAIN_CRN_FIX_BITS_5112 7
+#define AR5K_GAIN_CRN_MAX_FIX_BITS AR5K_GAIN_CRN_FIX_BITS_5112
+#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN 15
+#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN 20
+#define AR5K_GAIN_CCK_PROBE_CORR 5
+#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA 15
+#define AR5K_GAIN_STEP_COUNT 10
+
+/* Check if our current measurement is inside our
+ * current variable attenuation window */
+#define AR5K_GAIN_CHECK_ADJUST(_g) \
+ ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
+
+struct ath5k_gain_opt_step {
+ s8 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
+ s8 gos_gain;
+};
+
+struct ath5k_gain_opt {
+ u8 go_default;
+ u8 go_steps_count;
+ const struct ath5k_gain_opt_step go_step[AR5K_GAIN_STEP_COUNT];
+};
+
+/*
+ * Parameters on gos_param:
+ * 1) Tx clip PHY register
+ * 2) PWD 90 RF register
+ * 3) PWD 84 RF register
+ * 4) RFGainSel RF register
+ */
+static const struct ath5k_gain_opt rfgain_opt_5111 = {
+ 4,
+ 9,
+ {
+ { { 4, 1, 1, 1 }, 6 },
+ { { 4, 0, 1, 1 }, 4 },
+ { { 3, 1, 1, 1 }, 3 },
+ { { 4, 0, 0, 1 }, 1 },
+ { { 4, 1, 1, 0 }, 0 },
+ { { 4, 0, 1, 0 }, -2 },
+ { { 3, 1, 1, 0 }, -3 },
+ { { 4, 0, 0, 0 }, -4 },
+ { { 2, 1, 1, 0 }, -6 }
+ }
+};
+
+/*
+ * Parameters on gos_param:
+ * 1) Mixgain ovr RF register
+ * 2) PWD 138 RF register
+ * 3) PWD 137 RF register
+ * 4) PWD 136 RF register
+ * 5) PWD 132 RF register
+ * 6) PWD 131 RF register
+ * 7) PWD 130 RF register
+ */
+static const struct ath5k_gain_opt rfgain_opt_5112 = {
+ 1,
+ 8,
+ {
+ { { 3, 0, 0, 0, 0, 0, 0 }, 6 },
+ { { 2, 0, 0, 0, 0, 0, 0 }, 0 },
+ { { 1, 0, 0, 0, 0, 0, 0 }, -3 },
+ { { 0, 0, 0, 0, 0, 0, 0 }, -6 },
+ { { 0, 1, 1, 0, 0, 0, 0 }, -8 },
+ { { 0, 1, 1, 0, 1, 1, 0 }, -10 },
+ { { 0, 1, 0, 1, 1, 1, 0 }, -13 },
+ { { 0, 1, 0, 1, 1, 0, 1 }, -16 },
+ }
+};
+
diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath9k/Makefile
index 1209d14613ac..1a4d4eab6fe8 100644
--- a/drivers/net/wireless/ath9k/Makefile
+++ b/drivers/net/wireless/ath9k/Makefile
@@ -9,8 +9,11 @@ ath9k-y += hw.o \
main.o \
recv.o \
xmit.o \
+ virtual.o \
rc.o
+ath9k-$(CONFIG_PCI) += pci.o
+ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o
obj-$(CONFIG_ATH9K) += ath9k.o
diff --git a/drivers/net/wireless/ath9k/ahb.c b/drivers/net/wireless/ath9k/ahb.c
new file mode 100644
index 000000000000..0e65c51ba176
--- /dev/null
+++ b/drivers/net/wireless/ath9k/ahb.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/nl80211.h>
+#include <linux/platform_device.h>
+#include <linux/ath9k_platform.h>
+#include "ath9k.h"
+
+/* return bus cachesize in 4B word units */
+static void ath_ahb_read_cachesize(struct ath_softc *sc, int *csz)
+{
+ *csz = L1_CACHE_BYTES >> 2;
+}
+
+static void ath_ahb_cleanup(struct ath_softc *sc)
+{
+ iounmap(sc->mem);
+}
+
+static bool ath_ahb_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
+{
+ struct ath_softc *sc = ah->ah_sc;
+ struct platform_device *pdev = to_platform_device(sc->dev);
+ struct ath9k_platform_data *pdata;
+
+ pdata = (struct ath9k_platform_data *) pdev->dev.platform_data;
+ if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "%s: flash read failed, offset %08x is out of range\n",
+ __func__, off);
+ return false;
+ }
+
+ *data = pdata->eeprom_data[off];
+ return true;
+}
+
+static struct ath_bus_ops ath_ahb_bus_ops = {
+ .read_cachesize = ath_ahb_read_cachesize,
+ .cleanup = ath_ahb_cleanup,
+
+ .eeprom_read = ath_ahb_eeprom_read,
+};
+
+static int ath_ahb_probe(struct platform_device *pdev)
+{
+ void __iomem *mem;
+ struct ath_wiphy *aphy;
+ struct ath_softc *sc;
+ struct ieee80211_hw *hw;
+ struct resource *res;
+ int irq;
+ int ret = 0;
+ struct ath_hw *ah;
+
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "no platform data specified\n");
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no memory resource found\n");
+ ret = -ENXIO;
+ goto err_out;
+ }
+
+ mem = ioremap_nocache(res->start, res->end - res->start + 1);
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no IRQ resource found\n");
+ ret = -ENXIO;
+ goto err_iounmap;
+ }
+
+ irq = res->start;
+
+ hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
+ sizeof(struct ath_softc), &ath9k_ops);
+ if (hw == NULL) {
+ dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
+ ret = -ENOMEM;
+ goto err_iounmap;
+ }
+
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+ platform_set_drvdata(pdev, hw);
+
+ aphy = hw->priv;
+ sc = (struct ath_softc *) (aphy + 1);
+ aphy->sc = sc;
+ aphy->hw = hw;
+ sc->pri_wiphy = aphy;
+ sc->hw = hw;
+ sc->dev = &pdev->dev;
+ sc->mem = mem;
+ sc->bus_ops = &ath_ahb_bus_ops;
+ sc->irq = irq;
+
+ ret = ath_attach(AR5416_AR9100_DEVID, sc);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
+ ret = -ENODEV;
+ goto err_free_hw;
+ }
+
+ ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq failed, err=%d\n", ret);
+ ret = -EIO;
+ goto err_detach;
+ }
+
+ ah = sc->sc_ah;
+ printk(KERN_INFO
+ "%s: Atheros AR%s MAC/BB Rev:%x, "
+ "AR%s RF Rev:%x, mem=0x%lx, irq=%d\n",
+ wiphy_name(hw->wiphy),
+ ath_mac_bb_name(ah->hw_version.macVersion),
+ ah->hw_version.macRev,
+ ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
+ ah->hw_version.phyRev,
+ (unsigned long)mem, irq);
+
+ return 0;
+
+ err_detach:
+ ath_detach(sc);
+ err_free_hw:
+ ieee80211_free_hw(hw);
+ platform_set_drvdata(pdev, NULL);
+ err_iounmap:
+ iounmap(mem);
+ err_out:
+ return ret;
+}
+
+static int ath_ahb_remove(struct platform_device *pdev)
+{
+ struct ieee80211_hw *hw = platform_get_drvdata(pdev);
+
+ if (hw) {
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ ath_cleanup(sc);
+ platform_set_drvdata(pdev, NULL);
+ }
+
+ return 0;
+}
+
+static struct platform_driver ath_ahb_driver = {
+ .probe = ath_ahb_probe,
+ .remove = ath_ahb_remove,
+ .driver = {
+ .name = "ath9k",
+ .owner = THIS_MODULE,
+ },
+};
+
+int ath_ahb_init(void)
+{
+ return platform_driver_register(&ath_ahb_driver);
+}
+
+void ath_ahb_exit(void)
+{
+ platform_driver_unregister(&ath_ahb_driver);
+}
diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath9k/ani.c
index 251e2d9a7a4a..6c5e887d50d7 100644
--- a/drivers/net/wireless/ath9k/ani.c
+++ b/drivers/net/wireless/ath9k/ani.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,23 +14,19 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
-static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
+static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
struct ath9k_channel *chan)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
- for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
- if (ahp->ah_ani[i].c.channel == chan->channel)
+ for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
+ if (ah->ani[i].c &&
+ ah->ani[i].c->channel == chan->channel)
return i;
- if (ahp->ah_ani[i].c.channel == 0) {
- ahp->ah_ani[i].c.channel = chan->channel;
- ahp->ah_ani[i].c.channelFlags = chan->channelFlags;
+ if (ah->ani[i].c == NULL) {
+ ah->ani[i].c = chan;
return i;
}
}
@@ -41,41 +37,40 @@ static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
return 0;
}
-static bool ath9k_hw_ani_control(struct ath_hal *ah,
+static bool ath9k_hw_ani_control(struct ath_hw *ah,
enum ath9k_ani_cmd cmd, int param)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416AniState *aniState = ahp->ah_curani;
+ struct ar5416AniState *aniState = ah->curani;
- switch (cmd & ahp->ah_ani_function) {
+ switch (cmd & ah->ani_function) {
case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
u32 level = param;
- if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) {
+ if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"level out of range (%u > %u)\n",
level,
- (unsigned)ARRAY_SIZE(ahp->ah_totalSizeDesired));
+ (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
return false;
}
REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
AR_PHY_DESIRED_SZ_TOT_DES,
- ahp->ah_totalSizeDesired[level]);
+ ah->totalSizeDesired[level]);
REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
AR_PHY_AGC_CTL1_COARSE_LOW,
- ahp->ah_coarseLow[level]);
+ ah->coarse_low[level]);
REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
AR_PHY_AGC_CTL1_COARSE_HIGH,
- ahp->ah_coarseHigh[level]);
+ ah->coarse_high[level]);
REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
AR_PHY_FIND_SIG_FIRPWR,
- ahp->ah_firpwr[level]);
+ ah->firpwr[level]);
if (level > aniState->noiseImmunityLevel)
- ahp->ah_stats.ast_ani_niup++;
+ ah->stats.ast_ani_niup++;
else if (level < aniState->noiseImmunityLevel)
- ahp->ah_stats.ast_ani_nidown++;
+ ah->stats.ast_ani_nidown++;
aniState->noiseImmunityLevel = level;
break;
}
@@ -129,9 +124,9 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
if (!on != aniState->ofdmWeakSigDetectOff) {
if (on)
- ahp->ah_stats.ast_ani_ofdmon++;
+ ah->stats.ast_ani_ofdmon++;
else
- ahp->ah_stats.ast_ani_ofdmoff++;
+ ah->stats.ast_ani_ofdmoff++;
aniState->ofdmWeakSigDetectOff = !on;
}
break;
@@ -145,9 +140,9 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
weakSigThrCck[high]);
if (high != aniState->cckWeakSigThreshold) {
if (high)
- ahp->ah_stats.ast_ani_cckhigh++;
+ ah->stats.ast_ani_cckhigh++;
else
- ahp->ah_stats.ast_ani_ccklow++;
+ ah->stats.ast_ani_ccklow++;
aniState->cckWeakSigThreshold = high;
}
break;
@@ -167,9 +162,9 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
AR_PHY_FIND_SIG_FIRSTEP,
firstep[level]);
if (level > aniState->firstepLevel)
- ahp->ah_stats.ast_ani_stepup++;
+ ah->stats.ast_ani_stepup++;
else if (level < aniState->firstepLevel)
- ahp->ah_stats.ast_ani_stepdown++;
+ ah->stats.ast_ani_stepdown++;
aniState->firstepLevel = level;
break;
}
@@ -190,9 +185,9 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
AR_PHY_TIMING5_CYCPWR_THR1,
cycpwrThr1[level]);
if (level > aniState->spurImmunityLevel)
- ahp->ah_stats.ast_ani_spurup++;
+ ah->stats.ast_ani_spurup++;
else if (level < aniState->spurImmunityLevel)
- ahp->ah_stats.ast_ani_spurdown++;
+ ah->stats.ast_ani_spurdown++;
aniState->spurImmunityLevel = level;
break;
}
@@ -223,7 +218,7 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
return true;
}
-static void ath9k_hw_update_mibstats(struct ath_hal *ah,
+static void ath9k_hw_update_mibstats(struct ath_hw *ah,
struct ath9k_mib_stats *stats)
{
stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
@@ -233,18 +228,17 @@ static void ath9k_hw_update_mibstats(struct ath_hal *ah,
stats->beacons += REG_READ(ah, AR_BEACON_CNT);
}
-static void ath9k_ani_restart(struct ath_hal *ah)
+static void ath9k_ani_restart(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416AniState *aniState;
if (!DO_ANI(ah))
return;
- aniState = ahp->ah_curani;
+ aniState = ah->curani;
aniState->listenTime = 0;
- if (ahp->ah_hasHwPhyCounters) {
+ if (ah->has_hw_phycounters) {
if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
aniState->ofdmPhyErrBase = 0;
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
@@ -270,24 +264,22 @@ static void ath9k_ani_restart(struct ath_hal *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
- ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+ ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
}
aniState->ofdmPhyErrCount = 0;
aniState->cckPhyErrCount = 0;
}
-static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
+static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
struct ar5416AniState *aniState;
- enum wireless_mode mode;
int32_t rssi;
if (!DO_ANI(ah))
return;
- aniState = ahp->ah_curani;
+ aniState = ah->curani;
if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
@@ -303,14 +295,14 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
}
}
- if (ah->ah_opmode == NL80211_IFTYPE_AP) {
+ if (ah->opmode == NL80211_IFTYPE_AP) {
if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel + 1);
}
return;
}
- rssi = BEACON_RSSI(ahp);
+ rssi = BEACON_RSSI(ah);
if (rssi > aniState->rssiThrHigh) {
if (!aniState->ofdmWeakSigDetectOff) {
if (ath9k_hw_ani_control(ah,
@@ -336,8 +328,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
aniState->firstepLevel + 1);
return;
} else {
- mode = ath9k_hw_chan2wmode(ah, chan);
- if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
+ if (conf->channel->band == IEEE80211_BAND_2GHZ) {
if (!aniState->ofdmWeakSigDetectOff)
ath9k_hw_ani_control(ah,
ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
@@ -350,39 +341,36 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
}
}
-static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
+static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
struct ar5416AniState *aniState;
- enum wireless_mode mode;
int32_t rssi;
if (!DO_ANI(ah))
return;
- aniState = ahp->ah_curani;
+ aniState = ah->curani;
if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
aniState->noiseImmunityLevel + 1)) {
return;
}
}
- if (ah->ah_opmode == NL80211_IFTYPE_AP) {
+ if (ah->opmode == NL80211_IFTYPE_AP) {
if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel + 1);
}
return;
}
- rssi = BEACON_RSSI(ahp);
+ rssi = BEACON_RSSI(ah);
if (rssi > aniState->rssiThrLow) {
if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel + 1);
} else {
- mode = ath9k_hw_chan2wmode(ah, chan);
- if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
+ if (conf->channel->band == IEEE80211_BAND_2GHZ) {
if (aniState->firstepLevel > 0)
ath9k_hw_ani_control(ah,
ATH9K_ANI_FIRSTEP_LEVEL, 0);
@@ -390,22 +378,21 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
}
}
-static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
+static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416AniState *aniState;
int32_t rssi;
- aniState = ahp->ah_curani;
+ aniState = ah->curani;
- if (ah->ah_opmode == NL80211_IFTYPE_AP) {
+ if (ah->opmode == NL80211_IFTYPE_AP) {
if (aniState->firstepLevel > 0) {
if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel - 1))
return;
}
} else {
- rssi = BEACON_RSSI(ahp);
+ rssi = BEACON_RSSI(ah);
if (rssi > aniState->rssiThrHigh) {
/* XXX: Handle me */
} else if (rssi > aniState->rssiThrLow) {
@@ -444,9 +431,8 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
}
}
-static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
+static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416AniState *aniState;
u32 txFrameCount, rxFrameCount, cycleCount;
int32_t listenTime;
@@ -455,11 +441,11 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
rxFrameCount = REG_READ(ah, AR_RFCNT);
cycleCount = REG_READ(ah, AR_CCCNT);
- aniState = ahp->ah_curani;
+ aniState = ah->curani;
if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
listenTime = 0;
- ahp->ah_stats.ast_ani_lzero++;
+ ah->stats.ast_ani_lzero++;
} else {
int32_t ccdelta = cycleCount - aniState->cycleCount;
int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
@@ -473,25 +459,24 @@ static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
return listenTime;
}
-void ath9k_ani_reset(struct ath_hal *ah)
+void ath9k_ani_reset(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416AniState *aniState;
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ath9k_channel *chan = ah->curchan;
int index;
if (!DO_ANI(ah))
return;
index = ath9k_hw_get_ani_channel_idx(ah, chan);
- aniState = &ahp->ah_ani[index];
- ahp->ah_curani = aniState;
+ aniState = &ah->ani[index];
+ ah->curani = aniState;
- if (DO_ANI(ah) && ah->ah_opmode != NL80211_IFTYPE_STATION
- && ah->ah_opmode != NL80211_IFTYPE_ADHOC) {
+ if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION
+ && ah->opmode != NL80211_IFTYPE_ADHOC) {
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
- "Reset ANI state opmode %u\n", ah->ah_opmode);
- ahp->ah_stats.ast_ani_reset++;
+ "Reset ANI state opmode %u\n", ah->opmode);
+ ah->stats.ast_ani_reset++;
ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
@@ -504,15 +489,15 @@ void ath9k_ani_reset(struct ath_hal *ah)
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
ATH9K_RX_FILTER_PHYERR);
- if (ah->ah_opmode == NL80211_IFTYPE_AP) {
- ahp->ah_curani->ofdmTrigHigh =
- ah->ah_config.ofdm_trig_high;
- ahp->ah_curani->ofdmTrigLow =
- ah->ah_config.ofdm_trig_low;
- ahp->ah_curani->cckTrigHigh =
- ah->ah_config.cck_trig_high;
- ahp->ah_curani->cckTrigLow =
- ah->ah_config.cck_trig_low;
+ if (ah->opmode == NL80211_IFTYPE_AP) {
+ ah->curani->ofdmTrigHigh =
+ ah->config.ofdm_trig_high;
+ ah->curani->ofdmTrigLow =
+ ah->config.ofdm_trig_low;
+ ah->curani->cckTrigHigh =
+ ah->config.cck_trig_high;
+ ah->curani->cckTrigLow =
+ ah->config.cck_trig_low;
}
ath9k_ani_restart(ah);
return;
@@ -533,7 +518,7 @@ void ath9k_ani_reset(struct ath_hal *ah)
if (aniState->firstepLevel != 0)
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel);
- if (ahp->ah_hasHwPhyCounters) {
+ if (ah->has_hw_phycounters) {
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
~ATH9K_RX_FILTER_PHYERR);
ath9k_ani_restart(ah);
@@ -547,31 +532,33 @@ void ath9k_ani_reset(struct ath_hal *ah)
}
}
-void ath9k_hw_ani_monitor(struct ath_hal *ah,
+void ath9k_hw_ani_monitor(struct ath_hw *ah,
const struct ath9k_node_stats *stats,
struct ath9k_channel *chan)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416AniState *aniState;
int32_t listenTime;
- aniState = ahp->ah_curani;
- ahp->ah_stats.ast_nodestats = *stats;
+ if (!DO_ANI(ah))
+ return;
+
+ aniState = ah->curani;
+ ah->stats.ast_nodestats = *stats;
listenTime = ath9k_hw_ani_get_listen_time(ah);
if (listenTime < 0) {
- ahp->ah_stats.ast_ani_lneg++;
+ ah->stats.ast_ani_lneg++;
ath9k_ani_restart(ah);
return;
}
aniState->listenTime += listenTime;
- if (ahp->ah_hasHwPhyCounters) {
+ if (ah->has_hw_phycounters) {
u32 phyCnt1, phyCnt2;
u32 ofdmPhyErrCnt, cckPhyErrCnt;
- ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+ ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
@@ -604,27 +591,24 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah,
}
ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
- ahp->ah_stats.ast_ani_ofdmerrs +=
+ ah->stats.ast_ani_ofdmerrs +=
ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
- ahp->ah_stats.ast_ani_cckerrs +=
+ ah->stats.ast_ani_cckerrs +=
cckPhyErrCnt - aniState->cckPhyErrCount;
aniState->cckPhyErrCount = cckPhyErrCnt;
}
- if (!DO_ANI(ah))
- return;
-
- if (aniState->listenTime > 5 * ahp->ah_aniPeriod) {
+ if (aniState->listenTime > 5 * ah->aniperiod) {
if (aniState->ofdmPhyErrCount <= aniState->listenTime *
aniState->ofdmTrigLow / 1000 &&
aniState->cckPhyErrCount <= aniState->listenTime *
aniState->cckTrigLow / 1000)
ath9k_hw_ani_lower_immunity(ah);
ath9k_ani_restart(ah);
- } else if (aniState->listenTime > ahp->ah_aniPeriod) {
+ } else if (aniState->listenTime > ah->aniperiod) {
if (aniState->ofdmPhyErrCount > aniState->listenTime *
aniState->ofdmTrigHigh / 1000) {
ath9k_hw_ani_ofdm_err_trigger(ah);
@@ -638,20 +622,16 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah,
}
}
-bool ath9k_hw_phycounters(struct ath_hal *ah)
+bool ath9k_hw_phycounters(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- return ahp->ah_hasHwPhyCounters ? true : false;
+ return ah->has_hw_phycounters ? true : false;
}
-void ath9k_enable_mib_counters(struct ath_hal *ah)
+void ath9k_enable_mib_counters(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n");
- ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
+ ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
REG_WRITE(ah, AR_FILT_OFDM, 0);
REG_WRITE(ah, AR_FILT_CCK, 0);
@@ -662,21 +642,18 @@ void ath9k_enable_mib_counters(struct ath_hal *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
}
-void ath9k_hw_disable_mib_counters(struct ath_hal *ah)
+/* Freeze the MIB counters, get the stats and then clear them */
+void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disable MIB counters\n");
-
- REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC);
-
- ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
-
+ REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
+ ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+ REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC);
REG_WRITE(ah, AR_FILT_OFDM, 0);
REG_WRITE(ah, AR_FILT_CCK, 0);
}
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
+u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
u32 *rxc_pcnt,
u32 *rxf_pcnt,
u32 *txf_pcnt)
@@ -721,10 +698,9 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
* any of the MIB counters overflow/trigger so don't assume we're
* here because a PHY error counter triggered.
*/
-void ath9k_hw_procmibevent(struct ath_hal *ah,
+void ath9k_hw_procmibevent(struct ath_hw *ah,
const struct ath9k_node_stats *stats)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 phyCnt1, phyCnt2;
/* Reset these counters regardless */
@@ -734,8 +710,8 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
/* Clear the mib counters and save them in the stats */
- ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
- ahp->ah_stats.ast_nodestats = *stats;
+ ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+ ah->stats.ast_nodestats = *stats;
if (!DO_ANI(ah))
return;
@@ -745,17 +721,17 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
- struct ar5416AniState *aniState = ahp->ah_curani;
+ struct ar5416AniState *aniState = ah->curani;
u32 ofdmPhyErrCnt, cckPhyErrCnt;
/* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
- ahp->ah_stats.ast_ani_ofdmerrs +=
+ ah->stats.ast_ani_ofdmerrs +=
ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
- ahp->ah_stats.ast_ani_cckerrs +=
+ ah->stats.ast_ani_cckerrs +=
cckPhyErrCnt - aniState->cckPhyErrCount;
aniState->cckPhyErrCount = cckPhyErrCnt;
@@ -774,9 +750,8 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
}
}
-void ath9k_hw_ani_setup(struct ath_hal *ah)
+void ath9k_hw_ani_setup(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
@@ -785,66 +760,63 @@ void ath9k_hw_ani_setup(struct ath_hal *ah)
const int firpwr[] = { -78, -78, -78, -78, -80 };
for (i = 0; i < 5; i++) {
- ahp->ah_totalSizeDesired[i] = totalSizeDesired[i];
- ahp->ah_coarseHigh[i] = coarseHigh[i];
- ahp->ah_coarseLow[i] = coarseLow[i];
- ahp->ah_firpwr[i] = firpwr[i];
+ ah->totalSizeDesired[i] = totalSizeDesired[i];
+ ah->coarse_high[i] = coarseHigh[i];
+ ah->coarse_low[i] = coarseLow[i];
+ ah->firpwr[i] = firpwr[i];
}
}
-void ath9k_hw_ani_attach(struct ath_hal *ah)
+void ath9k_hw_ani_attach(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n");
- ahp->ah_hasHwPhyCounters = 1;
-
- memset(ahp->ah_ani, 0, sizeof(ahp->ah_ani));
- for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
- ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
- ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
- ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
- ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
- ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
- ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
- ahp->ah_ani[i].ofdmWeakSigDetectOff =
+ ah->has_hw_phycounters = 1;
+
+ memset(ah->ani, 0, sizeof(ah->ani));
+ for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
+ ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
+ ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
+ ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
+ ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
+ ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
+ ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
+ ah->ani[i].ofdmWeakSigDetectOff =
!ATH9K_ANI_USE_OFDM_WEAK_SIG;
- ahp->ah_ani[i].cckWeakSigThreshold =
+ ah->ani[i].cckWeakSigThreshold =
ATH9K_ANI_CCK_WEAK_SIG_THR;
- ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
- ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
- if (ahp->ah_hasHwPhyCounters) {
- ahp->ah_ani[i].ofdmPhyErrBase =
+ ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
+ ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
+ if (ah->has_hw_phycounters) {
+ ah->ani[i].ofdmPhyErrBase =
AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
- ahp->ah_ani[i].cckPhyErrBase =
+ ah->ani[i].cckPhyErrBase =
AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
}
}
- if (ahp->ah_hasHwPhyCounters) {
+ if (ah->has_hw_phycounters) {
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"Setting OfdmErrBase = 0x%08x\n",
- ahp->ah_ani[0].ofdmPhyErrBase);
+ ah->ani[0].ofdmPhyErrBase);
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
- ahp->ah_ani[0].cckPhyErrBase);
+ ah->ani[0].cckPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase);
- REG_WRITE(ah, AR_PHY_ERR_2, ahp->ah_ani[0].cckPhyErrBase);
+ REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
+ REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
ath9k_enable_mib_counters(ah);
}
- ahp->ah_aniPeriod = ATH9K_ANI_PERIOD;
- if (ah->ah_config.enable_ani)
- ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
+ ah->aniperiod = ATH9K_ANI_PERIOD;
+ if (ah->config.enable_ani)
+ ah->proc_phyerr |= HAL_PROCESS_ANI;
}
-void ath9k_hw_ani_detach(struct ath_hal *ah)
+void ath9k_hw_ani_detach(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detach ANI\n");
- if (ahp->ah_hasHwPhyCounters) {
+ if (ah->has_hw_phycounters) {
ath9k_hw_disable_mib_counters(ah);
REG_WRITE(ah, AR_PHY_ERR_1, 0);
REG_WRITE(ah, AR_PHY_ERR_2, 0);
diff --git a/drivers/net/wireless/ath9k/ani.h b/drivers/net/wireless/ath9k/ani.h
new file mode 100644
index 000000000000..08b4e7ed5ff0
--- /dev/null
+++ b/drivers/net/wireless/ath9k/ani.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ANI_H
+#define ANI_H
+
+#define HAL_PROCESS_ANI 0x00000001
+#define ATH9K_RSSI_EP_MULTIPLIER (1<<7)
+
+#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI))
+
+#define HAL_EP_RND(x, mul) \
+ ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+#define BEACON_RSSI(ahp) \
+ HAL_EP_RND(ahp->stats.ast_nodestats.ns_avgbrssi, \
+ ATH9K_RSSI_EP_MULTIPLIER)
+
+#define ATH9K_ANI_OFDM_TRIG_HIGH 500
+#define ATH9K_ANI_OFDM_TRIG_LOW 200
+#define ATH9K_ANI_CCK_TRIG_HIGH 200
+#define ATH9K_ANI_CCK_TRIG_LOW 100
+#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
+#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
+#define ATH9K_ANI_CCK_WEAK_SIG_THR false
+#define ATH9K_ANI_SPUR_IMMUNE_LVL 7
+#define ATH9K_ANI_FIRSTEP_LVL 0
+#define ATH9K_ANI_RSSI_THR_HIGH 40
+#define ATH9K_ANI_RSSI_THR_LOW 7
+#define ATH9K_ANI_PERIOD 100
+
+#define HAL_NOISE_IMMUNE_MAX 4
+#define HAL_SPUR_IMMUNE_MAX 7
+#define HAL_FIRST_STEP_MAX 2
+
+enum ath9k_ani_cmd {
+ ATH9K_ANI_PRESENT = 0x1,
+ ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
+ ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
+ ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
+ ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
+ ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
+ ATH9K_ANI_MODE = 0x40,
+ ATH9K_ANI_PHYERR_RESET = 0x80,
+ ATH9K_ANI_ALL = 0xff
+};
+
+struct ath9k_mib_stats {
+ u32 ackrcv_bad;
+ u32 rts_bad;
+ u32 rts_good;
+ u32 fcs_bad;
+ u32 beacons;
+};
+
+struct ath9k_node_stats {
+ u32 ns_avgbrssi;
+ u32 ns_avgrssi;
+ u32 ns_avgtxrssi;
+ u32 ns_avgtxrate;
+};
+
+struct ar5416AniState {
+ struct ath9k_channel *c;
+ u8 noiseImmunityLevel;
+ u8 spurImmunityLevel;
+ u8 firstepLevel;
+ u8 ofdmWeakSigDetectOff;
+ u8 cckWeakSigThreshold;
+ u32 listenTime;
+ u32 ofdmTrigHigh;
+ u32 ofdmTrigLow;
+ int32_t cckTrigHigh;
+ int32_t cckTrigLow;
+ int32_t rssiThrLow;
+ int32_t rssiThrHigh;
+ u32 noiseFloor;
+ u32 txFrameCount;
+ u32 rxFrameCount;
+ u32 cycleCount;
+ u32 ofdmPhyErrCount;
+ u32 cckPhyErrCount;
+ u32 ofdmPhyErrBase;
+ u32 cckPhyErrBase;
+ int16_t pktRssi[2];
+ int16_t ofdmErrRssi[2];
+ int16_t cckErrRssi[2];
+};
+
+struct ar5416Stats {
+ u32 ast_ani_niup;
+ u32 ast_ani_nidown;
+ u32 ast_ani_spurup;
+ u32 ast_ani_spurdown;
+ u32 ast_ani_ofdmon;
+ u32 ast_ani_ofdmoff;
+ u32 ast_ani_cckhigh;
+ u32 ast_ani_ccklow;
+ u32 ast_ani_stepup;
+ u32 ast_ani_stepdown;
+ u32 ast_ani_ofdmerrs;
+ u32 ast_ani_cckerrs;
+ u32 ast_ani_reset;
+ u32 ast_ani_lzero;
+ u32 ast_ani_lneg;
+ struct ath9k_mib_stats ast_mibstats;
+ struct ath9k_node_stats ast_nodestats;
+};
+#define ah_mibStats stats.ast_mibstats
+
+void ath9k_ani_reset(struct ath_hw *ah);
+void ath9k_hw_ani_monitor(struct ath_hw *ah,
+ const struct ath9k_node_stats *stats,
+ struct ath9k_channel *chan);
+bool ath9k_hw_phycounters(struct ath_hw *ah);
+void ath9k_enable_mib_counters(struct ath_hw *ah);
+void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
+u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
+ u32 *rxf_pcnt, u32 *txf_pcnt);
+void ath9k_hw_procmibevent(struct ath_hw *ah,
+ const struct ath9k_node_stats *stats);
+void ath9k_hw_ani_setup(struct ath_hw *ah);
+void ath9k_hw_ani_attach(struct ath_hw *ah);
+void ath9k_hw_ani_detach(struct ath_hw *ah);
+
+#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
index d27813502953..2689a08a2844 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -17,1041 +17,741 @@
#ifndef ATH9K_H
#define ATH9K_H
-#include <linux/io.h>
-
-#define ATHEROS_VENDOR_ID 0x168c
-
-#define AR5416_DEVID_PCI 0x0023
-#define AR5416_DEVID_PCIE 0x0024
-#define AR9160_DEVID_PCI 0x0027
-#define AR9280_DEVID_PCI 0x0029
-#define AR9280_DEVID_PCIE 0x002a
-#define AR9285_DEVID_PCIE 0x002b
-
-#define AR5416_AR9100_DEVID 0x000b
-
-#define AR_SUBVENDOR_ID_NOG 0x0e11
-#define AR_SUBVENDOR_ID_NEW_A 0x7065
-
-#define ATH9K_TXERR_XRETRY 0x01
-#define ATH9K_TXERR_FILT 0x02
-#define ATH9K_TXERR_FIFO 0x04
-#define ATH9K_TXERR_XTXOP 0x08
-#define ATH9K_TXERR_TIMER_EXPIRED 0x10
-
-#define ATH9K_TX_BA 0x01
-#define ATH9K_TX_PWRMGMT 0x02
-#define ATH9K_TX_DESC_CFG_ERR 0x04
-#define ATH9K_TX_DATA_UNDERRUN 0x08
-#define ATH9K_TX_DELIM_UNDERRUN 0x10
-#define ATH9K_TX_SW_ABORTED 0x40
-#define ATH9K_TX_SW_FILTERED 0x80
-
-#define NBBY 8
-
-struct ath_tx_status {
- u32 ts_tstamp;
- u16 ts_seqnum;
- u8 ts_status;
- u8 ts_ratecode;
- u8 ts_rateindex;
- int8_t ts_rssi;
- u8 ts_shortretry;
- u8 ts_longretry;
- u8 ts_virtcol;
- u8 ts_antenna;
- u8 ts_flags;
- int8_t ts_rssi_ctl0;
- int8_t ts_rssi_ctl1;
- int8_t ts_rssi_ctl2;
- int8_t ts_rssi_ext0;
- int8_t ts_rssi_ext1;
- int8_t ts_rssi_ext2;
- u8 pad[3];
- u32 ba_low;
- u32 ba_high;
- u32 evm0;
- u32 evm1;
- u32 evm2;
-};
+#include <linux/etherdevice.h>
+#include <linux/device.h>
+#include <net/mac80211.h>
+#include <linux/leds.h>
+#include <linux/rfkill.h>
-struct ath_rx_status {
- u32 rs_tstamp;
- u16 rs_datalen;
- u8 rs_status;
- u8 rs_phyerr;
- int8_t rs_rssi;
- u8 rs_keyix;
- u8 rs_rate;
- u8 rs_antenna;
- u8 rs_more;
- int8_t rs_rssi_ctl0;
- int8_t rs_rssi_ctl1;
- int8_t rs_rssi_ctl2;
- int8_t rs_rssi_ext0;
- int8_t rs_rssi_ext1;
- int8_t rs_rssi_ext2;
- u8 rs_isaggr;
- u8 rs_moreaggr;
- u8 rs_num_delims;
- u8 rs_flags;
- u32 evm0;
- u32 evm1;
- u32 evm2;
-};
+#include "hw.h"
+#include "rc.h"
+#include "debug.h"
-#define ATH9K_RXERR_CRC 0x01
-#define ATH9K_RXERR_PHY 0x02
-#define ATH9K_RXERR_FIFO 0x04
-#define ATH9K_RXERR_DECRYPT 0x08
-#define ATH9K_RXERR_MIC 0x10
-
-#define ATH9K_RX_MORE 0x01
-#define ATH9K_RX_MORE_AGGR 0x02
-#define ATH9K_RX_GI 0x04
-#define ATH9K_RX_2040 0x08
-#define ATH9K_RX_DELIM_CRC_PRE 0x10
-#define ATH9K_RX_DELIM_CRC_POST 0x20
-#define ATH9K_RX_DECRYPT_BUSY 0x40
-
-#define ATH9K_RXKEYIX_INVALID ((u8)-1)
-#define ATH9K_TXKEYIX_INVALID ((u32)-1)
-
-struct ath_desc {
- u32 ds_link;
- u32 ds_data;
- u32 ds_ctl0;
- u32 ds_ctl1;
- u32 ds_hw[20];
- union {
- struct ath_tx_status tx;
- struct ath_rx_status rx;
- void *stats;
- } ds_us;
- void *ds_vdata;
-} __packed;
-
-#define ds_txstat ds_us.tx
-#define ds_rxstat ds_us.rx
-#define ds_stat ds_us.stats
-
-#define ATH9K_TXDESC_CLRDMASK 0x0001
-#define ATH9K_TXDESC_NOACK 0x0002
-#define ATH9K_TXDESC_RTSENA 0x0004
-#define ATH9K_TXDESC_CTSENA 0x0008
-/* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for
- * the descriptor its marked on. We take a tx interrupt to reap
- * descriptors when the h/w hits an EOL condition or
- * when the descriptor is specifically marked to generate
- * an interrupt with this flag. Descriptors should be
- * marked periodically to insure timely replenishing of the
- * supply needed for sending frames. Defering interrupts
- * reduces system load and potentially allows more concurrent
- * work to be done but if done to aggressively can cause
- * senders to backup. When the hardware queue is left too
- * large rate control information may also be too out of
- * date. An Alternative for this is TX interrupt mitigation
- * but this needs more testing. */
-#define ATH9K_TXDESC_INTREQ 0x0010
-#define ATH9K_TXDESC_VEOL 0x0020
-#define ATH9K_TXDESC_EXT_ONLY 0x0040
-#define ATH9K_TXDESC_EXT_AND_CTL 0x0080
-#define ATH9K_TXDESC_VMF 0x0100
-#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
-#define ATH9K_TXDESC_CAB 0x0400
-
-#define ATH9K_RXDESC_INTREQ 0x0020
-
-enum wireless_mode {
- ATH9K_MODE_11A = 0,
- ATH9K_MODE_11B = 2,
- ATH9K_MODE_11G = 3,
- ATH9K_MODE_11NA_HT20 = 6,
- ATH9K_MODE_11NG_HT20 = 7,
- ATH9K_MODE_11NA_HT40PLUS = 8,
- ATH9K_MODE_11NA_HT40MINUS = 9,
- ATH9K_MODE_11NG_HT40PLUS = 10,
- ATH9K_MODE_11NG_HT40MINUS = 11,
- ATH9K_MODE_MAX
-};
+struct ath_node;
-enum ath9k_hw_caps {
- ATH9K_HW_CAP_CHAN_SPREAD = BIT(0),
- ATH9K_HW_CAP_MIC_AESCCM = BIT(1),
- ATH9K_HW_CAP_MIC_CKIP = BIT(2),
- ATH9K_HW_CAP_MIC_TKIP = BIT(3),
- ATH9K_HW_CAP_CIPHER_AESCCM = BIT(4),
- ATH9K_HW_CAP_CIPHER_CKIP = BIT(5),
- ATH9K_HW_CAP_CIPHER_TKIP = BIT(6),
- ATH9K_HW_CAP_VEOL = BIT(7),
- ATH9K_HW_CAP_BSSIDMASK = BIT(8),
- ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(9),
- ATH9K_HW_CAP_CHAN_HALFRATE = BIT(10),
- ATH9K_HW_CAP_CHAN_QUARTERRATE = BIT(11),
- ATH9K_HW_CAP_HT = BIT(12),
- ATH9K_HW_CAP_GTT = BIT(13),
- ATH9K_HW_CAP_FASTCC = BIT(14),
- ATH9K_HW_CAP_RFSILENT = BIT(15),
- ATH9K_HW_CAP_WOW = BIT(16),
- ATH9K_HW_CAP_CST = BIT(17),
- ATH9K_HW_CAP_ENHANCEDPM = BIT(18),
- ATH9K_HW_CAP_AUTOSLEEP = BIT(19),
- ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(20),
- ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT = BIT(21),
-};
+/* Macro to expand scalars to 64-bit objects */
-enum ath9k_capability_type {
- ATH9K_CAP_CIPHER = 0,
- ATH9K_CAP_TKIP_MIC,
- ATH9K_CAP_TKIP_SPLIT,
- ATH9K_CAP_PHYCOUNTERS,
- ATH9K_CAP_DIVERSITY,
- ATH9K_CAP_TXPOW,
- ATH9K_CAP_PHYDIAG,
- ATH9K_CAP_MCAST_KEYSRCH,
- ATH9K_CAP_TSF_ADJUST,
- ATH9K_CAP_WME_TKIPMIC,
- ATH9K_CAP_RFSILENT,
- ATH9K_CAP_ANT_CFG_2GHZ,
- ATH9K_CAP_ANT_CFG_5GHZ
-};
+#define ito64(x) (sizeof(x) == 8) ? \
+ (((unsigned long long int)(x)) & (0xff)) : \
+ (sizeof(x) == 16) ? \
+ (((unsigned long long int)(x)) & 0xffff) : \
+ ((sizeof(x) == 32) ? \
+ (((unsigned long long int)(x)) & 0xffffffff) : \
+ (unsigned long long int)(x))
-struct ath9k_hw_capabilities {
- u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
- DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
- u16 total_queues;
- u16 keycache_size;
- u16 low_5ghz_chan, high_5ghz_chan;
- u16 low_2ghz_chan, high_2ghz_chan;
- u16 num_mr_retries;
- u16 rts_aggr_limit;
- u8 tx_chainmask;
- u8 rx_chainmask;
- u16 tx_triglevel_max;
- u16 reg_cap;
- u8 num_gpio_pins;
- u8 num_antcfg_2ghz;
- u8 num_antcfg_5ghz;
-};
+/* increment with wrap-around */
+#define INCR(_l, _sz) do { \
+ (_l)++; \
+ (_l) &= ((_sz) - 1); \
+ } while (0)
-struct ath9k_ops_config {
- int dma_beacon_response_time;
- int sw_beacon_response_time;
- int additional_swba_backoff;
- int ack_6mb;
- int cwm_ignore_extcca;
- u8 pcie_powersave_enable;
- u8 pcie_l1skp_enable;
- u8 pcie_clock_req;
- u32 pcie_waen;
- int pcie_power_reset;
- u8 pcie_restore;
- u8 analog_shiftreg;
- u8 ht_enable;
- u32 ofdm_trig_low;
- u32 ofdm_trig_high;
- u32 cck_trig_high;
- u32 cck_trig_low;
- u32 enable_ani;
- u8 noise_immunity_level;
- u32 ofdm_weaksignal_det;
- u32 cck_weaksignal_thr;
- u8 spur_immunity_level;
- u8 firstep_level;
- int8_t rssi_thr_high;
- int8_t rssi_thr_low;
- u16 diversity_control;
- u16 antenna_switch_swap;
- int serialize_regmode;
- int intr_mitigation;
-#define SPUR_DISABLE 0
-#define SPUR_ENABLE_IOCTL 1
-#define SPUR_ENABLE_EEPROM 2
-#define AR_EEPROM_MODAL_SPURS 5
-#define AR_SPUR_5413_1 1640
-#define AR_SPUR_5413_2 1200
-#define AR_NO_SPUR 0x8000
-#define AR_BASE_FREQ_2GHZ 2300
-#define AR_BASE_FREQ_5GHZ 4900
-#define AR_SPUR_FEEQ_BOUND_HT40 19
-#define AR_SPUR_FEEQ_BOUND_HT20 10
- int spurmode;
- u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
-};
+/* decrement with wrap-around */
+#define DECR(_l, _sz) do { \
+ (_l)--; \
+ (_l) &= ((_sz) - 1); \
+ } while (0)
-enum ath9k_tx_queue {
- ATH9K_TX_QUEUE_INACTIVE = 0,
- ATH9K_TX_QUEUE_DATA,
- ATH9K_TX_QUEUE_BEACON,
- ATH9K_TX_QUEUE_CAB,
- ATH9K_TX_QUEUE_UAPSD,
- ATH9K_TX_QUEUE_PSPOLL
-};
-
-#define ATH9K_NUM_TX_QUEUES 10
-
-enum ath9k_tx_queue_subtype {
- ATH9K_WME_AC_BK = 0,
- ATH9K_WME_AC_BE,
- ATH9K_WME_AC_VI,
- ATH9K_WME_AC_VO,
- ATH9K_WME_UPSD
-};
+#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
-enum ath9k_tx_queue_flags {
- TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
- TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
- TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
- TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
- TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
- TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
- TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
- TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
- TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
-};
-
-#define ATH9K_TXQ_USEDEFAULT ((u32) -1)
+#define ASSERT(exp) do { \
+ if (unlikely(!(exp))) { \
+ BUG(); \
+ } \
+ } while (0)
-#define ATH9K_DECOMP_MASK_SIZE 128
-#define ATH9K_READY_TIME_LO_BOUND 50
-#define ATH9K_READY_TIME_HI_BOUND 96
+#define TSF_TO_TU(_h,_l) \
+ ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
-enum ath9k_pkt_type {
- ATH9K_PKT_TYPE_NORMAL = 0,
- ATH9K_PKT_TYPE_ATIM,
- ATH9K_PKT_TYPE_PSPOLL,
- ATH9K_PKT_TYPE_BEACON,
- ATH9K_PKT_TYPE_PROBE_RESP,
- ATH9K_PKT_TYPE_CHIRP,
- ATH9K_PKT_TYPE_GRP_POLL,
-};
+#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i))
-struct ath9k_tx_queue_info {
- u32 tqi_ver;
- enum ath9k_tx_queue tqi_type;
- enum ath9k_tx_queue_subtype tqi_subtype;
- enum ath9k_tx_queue_flags tqi_qflags;
- u32 tqi_priority;
- u32 tqi_aifs;
- u32 tqi_cwmin;
- u32 tqi_cwmax;
- u16 tqi_shretry;
- u16 tqi_lgretry;
- u32 tqi_cbrPeriod;
- u32 tqi_cbrOverflowLimit;
- u32 tqi_burstTime;
- u32 tqi_readyTime;
- u32 tqi_physCompBuf;
- u32 tqi_intFlags;
-};
+static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-enum ath9k_rx_filter {
- ATH9K_RX_FILTER_UCAST = 0x00000001,
- ATH9K_RX_FILTER_MCAST = 0x00000002,
- ATH9K_RX_FILTER_BCAST = 0x00000004,
- ATH9K_RX_FILTER_CONTROL = 0x00000008,
- ATH9K_RX_FILTER_BEACON = 0x00000010,
- ATH9K_RX_FILTER_PROM = 0x00000020,
- ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
- ATH9K_RX_FILTER_PSPOLL = 0x00004000,
- ATH9K_RX_FILTER_PHYERR = 0x00000100,
- ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
+struct ath_config {
+ u32 ath_aggr_prot;
+ u16 txpowlimit;
+ u8 cabqReadytime;
+ u8 swBeaconProcess;
};
-enum ath9k_int {
- ATH9K_INT_RX = 0x00000001,
- ATH9K_INT_RXDESC = 0x00000002,
- ATH9K_INT_RXNOFRM = 0x00000008,
- ATH9K_INT_RXEOL = 0x00000010,
- ATH9K_INT_RXORN = 0x00000020,
- ATH9K_INT_TX = 0x00000040,
- ATH9K_INT_TXDESC = 0x00000080,
- ATH9K_INT_TIM_TIMER = 0x00000100,
- ATH9K_INT_TXURN = 0x00000800,
- ATH9K_INT_MIB = 0x00001000,
- ATH9K_INT_RXPHY = 0x00004000,
- ATH9K_INT_RXKCM = 0x00008000,
- ATH9K_INT_SWBA = 0x00010000,
- ATH9K_INT_BMISS = 0x00040000,
- ATH9K_INT_BNR = 0x00100000,
- ATH9K_INT_TIM = 0x00200000,
- ATH9K_INT_DTIM = 0x00400000,
- ATH9K_INT_DTIMSYNC = 0x00800000,
- ATH9K_INT_GPIO = 0x01000000,
- ATH9K_INT_CABEND = 0x02000000,
- ATH9K_INT_CST = 0x10000000,
- ATH9K_INT_GTT = 0x20000000,
- ATH9K_INT_FATAL = 0x40000000,
- ATH9K_INT_GLOBAL = 0x80000000,
- ATH9K_INT_BMISC = ATH9K_INT_TIM |
- ATH9K_INT_DTIM |
- ATH9K_INT_DTIMSYNC |
- ATH9K_INT_CABEND,
- ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
- ATH9K_INT_RXDESC |
- ATH9K_INT_RXEOL |
- ATH9K_INT_RXORN |
- ATH9K_INT_TXURN |
- ATH9K_INT_TXDESC |
- ATH9K_INT_MIB |
- ATH9K_INT_RXPHY |
- ATH9K_INT_RXKCM |
- ATH9K_INT_SWBA |
- ATH9K_INT_BMISS |
- ATH9K_INT_GPIO,
- ATH9K_INT_NOCARD = 0xffffffff
-};
+/*************************/
+/* Descriptor Management */
+/*************************/
-#define ATH9K_RATESERIES_RTS_CTS 0x0001
-#define ATH9K_RATESERIES_2040 0x0002
-#define ATH9K_RATESERIES_HALFGI 0x0004
+#define ATH_TXBUF_RESET(_bf) do { \
+ (_bf)->bf_status = 0; \
+ (_bf)->bf_lastbf = NULL; \
+ (_bf)->bf_next = NULL; \
+ memset(&((_bf)->bf_state), 0, \
+ sizeof(struct ath_buf_state)); \
+ } while (0)
-struct ath9k_11n_rate_series {
- u32 Tries;
- u32 Rate;
- u32 PktDuration;
- u32 ChSel;
- u32 RateFlags;
-};
+/**
+ * enum buffer_type - Buffer type flags
+ *
+ * @BUF_HT: Send this buffer using HT capabilities
+ * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
+ * @BUF_AGGR: Indicates whether the buffer can be aggregated
+ * (used in aggregation scheduling)
+ * @BUF_RETRY: Indicates whether the buffer is retried
+ * @BUF_XRETRY: To denote excessive retries of the buffer
+ */
+enum buffer_type {
+ BUF_HT = BIT(1),
+ BUF_AMPDU = BIT(2),
+ BUF_AGGR = BIT(3),
+ BUF_RETRY = BIT(4),
+ BUF_XRETRY = BIT(5),
+};
+
+struct ath_buf_state {
+ int bfs_nframes;
+ u16 bfs_al;
+ u16 bfs_frmlen;
+ int bfs_seqno;
+ int bfs_tidno;
+ int bfs_retries;
+ u32 bf_type;
+ u32 bfs_keyix;
+ enum ath9k_key_type bfs_keytype;
+};
+
+#define bf_nframes bf_state.bfs_nframes
+#define bf_al bf_state.bfs_al
+#define bf_frmlen bf_state.bfs_frmlen
+#define bf_retries bf_state.bfs_retries
+#define bf_seqno bf_state.bfs_seqno
+#define bf_tidno bf_state.bfs_tidno
+#define bf_keyix bf_state.bfs_keyix
+#define bf_keytype bf_state.bfs_keytype
+#define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT)
+#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
+#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
+#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
+#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
+
+struct ath_buf {
+ struct list_head list;
+ struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
+ an aggregate) */
+ struct ath_buf *bf_next; /* next subframe in the aggregate */
+ void *bf_mpdu; /* enclosing frame structure */
+ struct ath_desc *bf_desc; /* virtual addr of desc */
+ dma_addr_t bf_daddr; /* physical addr of desc */
+ dma_addr_t bf_buf_addr; /* physical addr of data buffer */
+ u32 bf_status;
+ u16 bf_flags;
+ struct ath_buf_state bf_state;
+ dma_addr_t bf_dmacontext;
+};
+
+#define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0)
+#define ATH_BUFSTATUS_STALE 0x00000002
+
+struct ath_descdma {
+ const char *dd_name;
+ struct ath_desc *dd_desc;
+ dma_addr_t dd_desc_paddr;
+ u32 dd_desc_len;
+ struct ath_buf *dd_bufptr;
+ dma_addr_t dd_dmacontext;
+};
+
+int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
+ struct list_head *head, const char *name,
+ int nbuf, int ndesc);
+void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
+ struct list_head *head);
+
+/***********/
+/* RX / TX */
+/***********/
+
+#define ATH_MAX_ANTENNA 3
+#define ATH_RXBUF 512
+#define WME_NUM_TID 16
+#define ATH_TXBUF 512
+#define ATH_TXMAXTRY 13
+#define ATH_11N_TXMAXTRY 10
+#define ATH_MGT_TXMAXTRY 4
+#define WME_BA_BMP_SIZE 64
+#define WME_MAX_BA WME_BA_BMP_SIZE
+#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
+
+#define TID_TO_WME_AC(_tid) \
+ ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
+ (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
+ (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
+ WME_AC_VO)
+
+#define WME_AC_BE 0
+#define WME_AC_BK 1
+#define WME_AC_VI 2
+#define WME_AC_VO 3
+#define WME_NUM_AC 4
+
+#define ADDBA_EXCHANGE_ATTEMPTS 10
+#define ATH_AGGR_DELIM_SZ 4
+#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
+/* number of delimiters for encryption padding */
+#define ATH_AGGR_ENCRYPTDELIM 10
+/* minimum h/w qdepth to be sustained to maximize aggregation */
+#define ATH_AGGR_MIN_QDEPTH 2
+#define ATH_AMPDU_SUBFRAME_DEFAULT 32
+#define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1)
+#define ATH_AMPDU_LIMIT_DEFAULT ATH_AMPDU_LIMIT_MAX
+
+#define IEEE80211_SEQ_SEQ_SHIFT 4
+#define IEEE80211_SEQ_MAX 4096
+#define IEEE80211_MIN_AMPDU_BUF 0x8
+#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
+#define IEEE80211_WEP_IVLEN 3
+#define IEEE80211_WEP_KIDLEN 1
+#define IEEE80211_WEP_CRCLEN 4
+#define IEEE80211_MAX_MPDU_LEN (3840 + FCS_LEN + \
+ (IEEE80211_WEP_IVLEN + \
+ IEEE80211_WEP_KIDLEN + \
+ IEEE80211_WEP_CRCLEN))
+
+/* return whether a bit at index _n in bitmap _bm is set
+ * _sz is the size of the bitmap */
+#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \
+ ((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
+
+/* return block-ack bitmap index given sequence and starting sequence */
+#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
+
+/* returns delimiter padding required given the packet length */
+#define ATH_AGGR_GET_NDELIM(_len) \
+ (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
+ (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
+
+#define BAW_WITHIN(_start, _bawsz, _seqno) \
+ ((((_seqno) - (_start)) & 4095) < (_bawsz))
+
+#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
+#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
+#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
+#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
+
+enum ATH_AGGR_STATUS {
+ ATH_AGGR_DONE,
+ ATH_AGGR_BAW_CLOSED,
+ ATH_AGGR_LIMITED,
+};
+
+struct ath_txq {
+ u32 axq_qnum;
+ u32 *axq_link;
+ struct list_head axq_q;
+ spinlock_t axq_lock;
+ u32 axq_depth;
+ u8 axq_aggr_depth;
+ u32 axq_totalqueued;
+ bool stopped;
+ struct ath_buf *axq_linkbuf;
+
+ /* first desc of the last descriptor that contains CTS */
+ struct ath_desc *axq_lastdsWithCTS;
+
+ /* final desc of the gating desc that determines whether
+ lastdsWithCTS has been DMA'ed or not */
+ struct ath_desc *axq_gatingds;
+
+ struct list_head axq_acq;
+};
+
+#define AGGR_CLEANUP BIT(1)
+#define AGGR_ADDBA_COMPLETE BIT(2)
+#define AGGR_ADDBA_PROGRESS BIT(3)
+
+struct ath_atx_tid {
+ struct list_head list;
+ struct list_head buf_q;
+ struct ath_node *an;
+ struct ath_atx_ac *ac;
+ struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
+ u16 seq_start;
+ u16 seq_next;
+ u16 baw_size;
+ int tidno;
+ int baw_head; /* first un-acked tx buffer */
+ int baw_tail; /* next unused tx buffer slot */
+ int sched;
+ int paused;
+ u8 state;
+ int addba_exchangeattempts;
+};
+
+struct ath_atx_ac {
+ int sched;
+ int qnum;
+ struct list_head list;
+ struct list_head tid_q;
+};
+
+struct ath_tx_control {
+ struct ath_txq *txq;
+ int if_id;
+ enum ath9k_internal_frame_type frame_type;
+};
+
+#define ATH_TX_ERROR 0x01
+#define ATH_TX_XRETRY 0x02
+#define ATH_TX_BAR 0x04
+
+/* All RSSI values are noise floor adjusted */
+struct ath_tx_stat {
+ int rssi;
+ int rssictl[ATH_MAX_ANTENNA];
+ int rssiextn[ATH_MAX_ANTENNA];
+ int rateieee;
+ int rateKbps;
+ int ratecode;
+ int flags;
+ u32 airtime; /* time on air per final tx rate */
+};
+
+struct aggr_rifs_param {
+ int param_max_frames;
+ int param_max_len;
+ int param_rl;
+ int param_al;
+ struct ath_rc_series *param_rcs;
+};
+
+struct ath_node {
+ struct ath_softc *an_sc;
+ struct ath_atx_tid tid[WME_NUM_TID];
+ struct ath_atx_ac ac[WME_NUM_AC];
+ u16 maxampdu;
+ u8 mpdudensity;
+};
+
+struct ath_tx {
+ u16 seq_no;
+ u32 txqsetup;
+ int hwq_map[ATH9K_WME_AC_VO+1];
+ spinlock_t txbuflock;
+ struct list_head txbuf;
+ struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
+ struct ath_descdma txdma;
+};
+
+struct ath_rx {
+ u8 defant;
+ u8 rxotherant;
+ u32 *rxlink;
+ int bufsize;
+ unsigned int rxfilter;
+ spinlock_t rxflushlock;
+ spinlock_t rxbuflock;
+ struct list_head rxbuf;
+ struct ath_descdma rxdma;
+};
+
+int ath_startrecv(struct ath_softc *sc);
+bool ath_stoprecv(struct ath_softc *sc);
+void ath_flushrecv(struct ath_softc *sc);
+u32 ath_calcrxfilter(struct ath_softc *sc);
+int ath_rx_init(struct ath_softc *sc, int nbufs);
+void ath_rx_cleanup(struct ath_softc *sc);
+int ath_rx_tasklet(struct ath_softc *sc, int flush);
+struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
+void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
+int ath_tx_setup(struct ath_softc *sc, int haltype);
+void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
+void ath_draintxq(struct ath_softc *sc,
+ struct ath_txq *txq, bool retry_tx);
+void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
+void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
+void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
+int ath_tx_init(struct ath_softc *sc, int nbufs);
+int ath_tx_cleanup(struct ath_softc *sc);
+struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
+int ath_txq_update(struct ath_softc *sc, int qnum,
+ struct ath9k_tx_queue_info *q);
+int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct ath_tx_control *txctl);
+void ath_tx_tasklet(struct ath_softc *sc);
+void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
+bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+ u16 tid, u16 *ssn);
+int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
+
+/********/
+/* VIFs */
+/********/
+
+struct ath_vif {
+ int av_bslot;
+ __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
+ enum nl80211_iftype av_opmode;
+ struct ath_buf *av_bcbuf;
+ struct ath_tx_control av_btxctl;
+ u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */
+};
+
+/*******************/
+/* Beacon Handling */
+/*******************/
-#define CHANNEL_CW_INT 0x00002
-#define CHANNEL_CCK 0x00020
-#define CHANNEL_OFDM 0x00040
-#define CHANNEL_2GHZ 0x00080
-#define CHANNEL_5GHZ 0x00100
-#define CHANNEL_PASSIVE 0x00200
-#define CHANNEL_DYN 0x00400
-#define CHANNEL_HALF 0x04000
-#define CHANNEL_QUARTER 0x08000
-#define CHANNEL_HT20 0x10000
-#define CHANNEL_HT40PLUS 0x20000
-#define CHANNEL_HT40MINUS 0x40000
-
-#define CHANNEL_INTERFERENCE 0x01
-#define CHANNEL_DFS 0x02
-#define CHANNEL_4MS_LIMIT 0x04
-#define CHANNEL_DFS_CLEAR 0x08
-#define CHANNEL_DISALLOW_ADHOC 0x10
-#define CHANNEL_PER_11D_ADHOC 0x20
-
-#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
-#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
-#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
-#define CHANNEL_G_HT20 (CHANNEL_2GHZ|CHANNEL_HT20)
-#define CHANNEL_A_HT20 (CHANNEL_5GHZ|CHANNEL_HT20)
-#define CHANNEL_G_HT40PLUS (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
-#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
-#define CHANNEL_A_HT40PLUS (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
-#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
-#define CHANNEL_ALL \
- (CHANNEL_OFDM| \
- CHANNEL_CCK| \
- CHANNEL_2GHZ | \
- CHANNEL_5GHZ | \
- CHANNEL_HT20 | \
- CHANNEL_HT40PLUS | \
- CHANNEL_HT40MINUS)
-
-struct ath9k_channel {
- u16 channel;
- u32 channelFlags;
- u8 privFlags;
- int8_t maxRegTxPower;
- int8_t maxTxPower;
- int8_t minTxPower;
- u32 chanmode;
- int32_t CalValid;
- bool oneTimeCalsDone;
- int8_t iCoff;
- int8_t qCoff;
- int16_t rawNoiseFloor;
- int8_t antennaMax;
- u32 regDmnFlags;
- u32 conformanceTestLimit[3]; /* 0:11a, 1: 11b, 2:11g */
-#ifdef ATH_NF_PER_CHAN
- struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
-#endif
-};
+/*
+ * Regardless of the number of beacons we stagger, (i.e. regardless of the
+ * number of BSSIDs) if a given beacon does not go out even after waiting this
+ * number of beacon intervals, the game's up.
+ */
+#define BSTUCK_THRESH (9 * ATH_BCBUF)
+#define ATH_BCBUF 4
+#define ATH_DEFAULT_BINTVAL 100 /* TU */
+#define ATH_DEFAULT_BMISS_LIMIT 10
+#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
+
+struct ath_beacon_config {
+ u16 beacon_interval;
+ u16 listen_interval;
+ u16 dtim_period;
+ u16 bmiss_timeout;
+ u8 dtim_count;
+};
+
+struct ath_beacon {
+ enum {
+ OK, /* no change needed */
+ UPDATE, /* update pending */
+ COMMIT /* beacon sent, commit change */
+ } updateslot; /* slot time update fsm */
+
+ u32 beaconq;
+ u32 bmisscnt;
+ u32 ast_be_xmit;
+ u64 bc_tstamp;
+ struct ieee80211_vif *bslot[ATH_BCBUF];
+ struct ath_wiphy *bslot_aphy[ATH_BCBUF];
+ int slottime;
+ int slotupdate;
+ struct ath9k_tx_queue_info beacon_qi;
+ struct ath_descdma bdma;
+ struct ath_txq *cabq;
+ struct list_head bbuf;
+};
+
+void ath_beacon_tasklet(unsigned long data);
+void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
+int ath_beaconq_setup(struct ath_hw *ah);
+int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif);
+void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
+
+/*******/
+/* ANI */
+/*******/
-#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
- (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
- (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
- (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
-#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
- (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
- (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
- (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
-#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
-#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
-#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
-#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
-#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
-#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
-
-/* These macros check chanmode and not channelFlags */
-#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
-#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) || \
- ((_c)->chanmode == CHANNEL_G_HT20))
-#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) || \
- ((_c)->chanmode == CHANNEL_A_HT40MINUS) || \
- ((_c)->chanmode == CHANNEL_G_HT40PLUS) || \
- ((_c)->chanmode == CHANNEL_G_HT40MINUS))
-#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
-
-#define IS_CHAN_IN_PUBLIC_SAFETY_BAND(_c) ((_c) > 4940 && (_c) < 4990)
-#define IS_CHAN_A_5MHZ_SPACED(_c) \
- ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \
- (((_c)->channel % 20) != 0) && \
- (((_c)->channel % 10) != 0))
-
-struct ath9k_keyval {
- u8 kv_type;
- u8 kv_pad;
- u16 kv_len;
- u8 kv_val[16];
- u8 kv_mic[8];
- u8 kv_txmic[8];
-};
+#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */
+#define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */
+#define ATH_ANI_POLLINTERVAL 100 /* 100 ms */
+#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
+#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
-enum ath9k_key_type {
- ATH9K_KEY_TYPE_CLEAR,
- ATH9K_KEY_TYPE_WEP,
- ATH9K_KEY_TYPE_AES,
- ATH9K_KEY_TYPE_TKIP,
+struct ath_ani {
+ bool caldone;
+ int16_t noise_floor;
+ unsigned int longcal_timer;
+ unsigned int shortcal_timer;
+ unsigned int resetcal_timer;
+ unsigned int checkani_timer;
+ struct timer_list timer;
};
-enum ath9k_cipher {
- ATH9K_CIPHER_WEP = 0,
- ATH9K_CIPHER_AES_OCB = 1,
- ATH9K_CIPHER_AES_CCM = 2,
- ATH9K_CIPHER_CKIP = 3,
- ATH9K_CIPHER_TKIP = 4,
- ATH9K_CIPHER_CLR = 5,
- ATH9K_CIPHER_MIC = 127
-};
+/********************/
+/* LED Control */
+/********************/
-#define AR_EEPROM_EEPCAP_COMPRESS_DIS 0x0001
-#define AR_EEPROM_EEPCAP_AES_DIS 0x0002
-#define AR_EEPROM_EEPCAP_FASTFRAME_DIS 0x0004
-#define AR_EEPROM_EEPCAP_BURST_DIS 0x0008
-#define AR_EEPROM_EEPCAP_MAXQCU 0x01F0
-#define AR_EEPROM_EEPCAP_MAXQCU_S 4
-#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN 0x0200
-#define AR_EEPROM_EEPCAP_KC_ENTRIES 0xF000
-#define AR_EEPROM_EEPCAP_KC_ENTRIES_S 12
-
-#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND 0x0040
-#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN 0x0080
-#define AR_EEPROM_EEREGCAP_EN_KK_U2 0x0100
-#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND 0x0200
-#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD 0x0400
-#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A 0x0800
-
-#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0 0x4000
-#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
-
-#define SD_NO_CTL 0xE0
-#define NO_CTL 0xff
-#define CTL_MODE_M 7
-#define CTL_11A 0
-#define CTL_11B 1
-#define CTL_11G 2
-#define CTL_2GHT20 5
-#define CTL_5GHT20 6
-#define CTL_2GHT40 7
-#define CTL_5GHT40 8
-
-#define AR_EEPROM_MAC(i) (0x1d+(i))
-
-#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
-#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
-#define AR_EEPROM_RFSILENT_POLARITY 0x0002
-#define AR_EEPROM_RFSILENT_POLARITY_S 1
-
-#define CTRY_DEBUG 0x1ff
-#define CTRY_DEFAULT 0
-
-enum reg_ext_bitmap {
- REG_EXT_JAPAN_MIDBAND = 1,
- REG_EXT_FCC_DFS_HT40 = 2,
- REG_EXT_JAPAN_NONDFS_HT40 = 3,
- REG_EXT_JAPAN_DFS_HT40 = 4
-};
+#define ATH_LED_PIN 1
+#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
+#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
-struct ath9k_country_entry {
- u16 countryCode;
- u16 regDmnEnum;
- u16 regDmn5G;
- u16 regDmn2G;
- u8 isMultidomain;
- u8 iso[3];
+enum ath_led_type {
+ ATH_LED_RADIO,
+ ATH_LED_ASSOC,
+ ATH_LED_TX,
+ ATH_LED_RX
};
-#define REG_WRITE(_ah, _reg, _val) iowrite32(_val, _ah->ah_sh + _reg)
-#define REG_READ(_ah, _reg) ioread32(_ah->ah_sh + _reg)
-
-#define SM(_v, _f) (((_v) << _f##_S) & _f)
-#define MS(_v, _f) (((_v) & _f) >> _f##_S)
-#define REG_RMW(_a, _r, _set, _clr) \
- REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
-#define REG_RMW_FIELD(_a, _r, _f, _v) \
- REG_WRITE(_a, _r, \
- (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
-#define REG_SET_BIT(_a, _r, _f) \
- REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
-#define REG_CLR_BIT(_a, _r, _f) \
- REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
-
-#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
-
-#define INIT_AIFS 2
-#define INIT_CWMIN 15
-#define INIT_CWMIN_11B 31
-#define INIT_CWMAX 1023
-#define INIT_SH_RETRY 10
-#define INIT_LG_RETRY 10
-#define INIT_SSH_RETRY 32
-#define INIT_SLG_RETRY 32
-
-#define WLAN_CTRL_FRAME_SIZE (2+2+6+4)
-
-#define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1)
-#define ATH_AMPDU_LIMIT_DEFAULT ATH_AMPDU_LIMIT_MAX
-
-#define IEEE80211_WEP_IVLEN 3
-#define IEEE80211_WEP_KIDLEN 1
-#define IEEE80211_WEP_CRCLEN 4
-#define IEEE80211_MAX_MPDU_LEN (3840 + FCS_LEN + \
- (IEEE80211_WEP_IVLEN + \
- IEEE80211_WEP_KIDLEN + \
- IEEE80211_WEP_CRCLEN))
-#define MAX_RATE_POWER 63
-
-enum ath9k_power_mode {
- ATH9K_PM_AWAKE = 0,
- ATH9K_PM_FULL_SLEEP,
- ATH9K_PM_NETWORK_SLEEP,
- ATH9K_PM_UNDEFINED
+struct ath_led {
+ struct ath_softc *sc;
+ struct led_classdev led_cdev;
+ enum ath_led_type led_type;
+ char name[32];
+ bool registered;
};
-struct ath9k_mib_stats {
- u32 ackrcv_bad;
- u32 rts_bad;
- u32 rts_good;
- u32 fcs_bad;
- u32 beacons;
-};
+/* Rfkill */
+#define ATH_RFKILL_POLL_INTERVAL 2000 /* msecs */
-enum ath9k_ant_setting {
- ATH9K_ANT_VARIABLE = 0,
- ATH9K_ANT_FIXED_A,
- ATH9K_ANT_FIXED_B
+struct ath_rfkill {
+ struct rfkill *rfkill;
+ struct delayed_work rfkill_poll;
+ char rfkill_name[32];
};
-#define ATH9K_SLOT_TIME_6 6
-#define ATH9K_SLOT_TIME_9 9
-#define ATH9K_SLOT_TIME_20 20
+/********************/
+/* Main driver core */
+/********************/
-enum ath9k_ht_macmode {
- ATH9K_HT_MACMODE_20 = 0,
- ATH9K_HT_MACMODE_2040 = 1,
-};
-
-enum ath9k_ht_extprotspacing {
- ATH9K_HT_EXTPROTSPACING_20 = 0,
- ATH9K_HT_EXTPROTSPACING_25 = 1,
-};
+/*
+ * Default cache line size, in bytes.
+ * Used when PCI device not fully initialized by bootrom/BIOS
+*/
+#define DEFAULT_CACHELINE 32
+#define ATH_DEFAULT_NOISE_FLOOR -95
+#define ATH_REGCLASSIDS_MAX 10
+#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
+#define ATH_MAX_SW_RETRIES 10
+#define ATH_CHAN_MAX 255
+#define IEEE80211_WEP_NKID 4 /* number of key ids */
-struct ath9k_ht_cwm {
- enum ath9k_ht_macmode ht_macmode;
+/*
+ * The key cache is used for h/w cipher state and also for
+ * tracking station state such as the current tx antenna.
+ * We also setup a mapping table between key cache slot indices
+ * and station state to short-circuit node lookups on rx.
+ * Different parts have different size key caches. We handle
+ * up to ATH_KEYMAX entries (could dynamically allocate state).
+ */
+#define ATH_KEYMAX 128 /* max key cache size we handle */
+
+#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
+#define ATH_RSSI_DUMMY_MARKER 0x127
+#define ATH_RATE_DUMMY_MARKER 0
+
+#define SC_OP_INVALID BIT(0)
+#define SC_OP_BEACONS BIT(1)
+#define SC_OP_RXAGGR BIT(2)
+#define SC_OP_TXAGGR BIT(3)
+#define SC_OP_CHAINMASK_UPDATE BIT(4)
+#define SC_OP_FULL_RESET BIT(5)
+#define SC_OP_PREAMBLE_SHORT BIT(6)
+#define SC_OP_PROTECT_ENABLE BIT(7)
+#define SC_OP_RXFLUSH BIT(8)
+#define SC_OP_LED_ASSOCIATED BIT(9)
+#define SC_OP_RFKILL_REGISTERED BIT(10)
+#define SC_OP_RFKILL_SW_BLOCKED BIT(11)
+#define SC_OP_RFKILL_HW_BLOCKED BIT(12)
+#define SC_OP_WAIT_FOR_BEACON BIT(13)
+#define SC_OP_LED_ON BIT(14)
+#define SC_OP_SCANNING BIT(15)
+#define SC_OP_TSF_RESET BIT(16)
+
+struct ath_bus_ops {
+ void (*read_cachesize)(struct ath_softc *sc, int *csz);
+ void (*cleanup)(struct ath_softc *sc);
+ bool (*eeprom_read)(struct ath_hw *ah, u32 off, u16 *data);
+};
+
+struct ath_wiphy;
+
+struct ath_softc {
+ struct ieee80211_hw *hw;
+ struct device *dev;
+
+ spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */
+ struct ath_wiphy *pri_wiphy;
+ struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may
+ * have NULL entries */
+ int num_sec_wiphy; /* number of sec_wiphy pointers in the array */
+ int chan_idx;
+ int chan_is_ht;
+ struct ath_wiphy *next_wiphy;
+ struct work_struct chan_work;
+ int wiphy_select_failures;
+ unsigned long wiphy_select_first_fail;
+ struct delayed_work wiphy_work;
+ unsigned long wiphy_scheduler_int;
+ int wiphy_scheduler_index;
+
+ struct tasklet_struct intr_tq;
+ struct tasklet_struct bcon_tasklet;
+ struct ath_hw *sc_ah;
+ void __iomem *mem;
+ int irq;
+ spinlock_t sc_resetlock;
+ spinlock_t sc_serial_rw;
+ struct mutex mutex;
+
+ u8 curbssid[ETH_ALEN];
+ u8 bssidmask[ETH_ALEN];
+ u32 intrstatus;
+ u32 sc_flags; /* SC_OP_* */
+ u16 curtxpow;
+ u16 curaid;
+ u16 cachelsz;
+ u8 nbcnvifs;
+ u16 nvifs;
+ u8 tx_chainmask;
+ u8 rx_chainmask;
+ u32 keymax;
+ DECLARE_BITMAP(keymap, ATH_KEYMAX);
+ u8 splitmic;
+ atomic_t ps_usecount;
+ enum ath9k_int imask;
enum ath9k_ht_extprotspacing ht_extprotspacing;
-};
-
-enum ath9k_ani_cmd {
- ATH9K_ANI_PRESENT = 0x1,
- ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
- ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
- ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
- ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
- ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
- ATH9K_ANI_MODE = 0x40,
- ATH9K_ANI_PHYERR_RESET = 0x80,
- ATH9K_ANI_ALL = 0xff
-};
-
-enum {
- WLAN_RC_PHY_OFDM,
- WLAN_RC_PHY_CCK,
- WLAN_RC_PHY_HT_20_SS,
- WLAN_RC_PHY_HT_20_DS,
- WLAN_RC_PHY_HT_40_SS,
- WLAN_RC_PHY_HT_40_DS,
- WLAN_RC_PHY_HT_20_SS_HGI,
- WLAN_RC_PHY_HT_20_DS_HGI,
- WLAN_RC_PHY_HT_40_SS_HGI,
- WLAN_RC_PHY_HT_40_DS_HGI,
- WLAN_RC_PHY_MAX
-};
-
-enum ath9k_tp_scale {
- ATH9K_TP_SCALE_MAX = 0,
- ATH9K_TP_SCALE_50,
- ATH9K_TP_SCALE_25,
- ATH9K_TP_SCALE_12,
- ATH9K_TP_SCALE_MIN
-};
-
-enum ser_reg_mode {
- SER_REG_MODE_OFF = 0,
- SER_REG_MODE_ON = 1,
- SER_REG_MODE_AUTO = 2,
-};
-
-#define AR_PHY_CCA_MAX_GOOD_VALUE -85
-#define AR_PHY_CCA_MAX_HIGH_VALUE -62
-#define AR_PHY_CCA_MIN_BAD_VALUE -121
-#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3
-#define AR_PHY_CCA_FILTERWINDOW_LENGTH 5
-
-#define ATH9K_NF_CAL_HIST_MAX 5
-#define NUM_NF_READINGS 6
-
-struct ath9k_nfcal_hist {
- int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
- u8 currIndex;
- int16_t privNF;
- u8 invalidNFcount;
-};
-
-struct ath9k_beacon_state {
- u32 bs_nexttbtt;
- u32 bs_nextdtim;
- u32 bs_intval;
-#define ATH9K_BEACON_PERIOD 0x0000ffff
-#define ATH9K_BEACON_ENA 0x00800000
-#define ATH9K_BEACON_RESET_TSF 0x01000000
- u32 bs_dtimperiod;
- u16 bs_cfpperiod;
- u16 bs_cfpmaxduration;
- u32 bs_cfpnext;
- u16 bs_timoffset;
- u16 bs_bmissthreshold;
- u32 bs_sleepduration;
-};
-
-struct ath9k_node_stats {
- u32 ns_avgbrssi;
- u32 ns_avgrssi;
- u32 ns_avgtxrssi;
- u32 ns_avgtxrate;
-};
-
-#define ATH9K_RSSI_EP_MULTIPLIER (1<<7)
-
-#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
-#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
-#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2
-#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5
-#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6
-
-enum {
- ATH9K_RESET_POWER_ON,
- ATH9K_RESET_WARM,
- ATH9K_RESET_COLD,
-};
-
-#define AH_USE_EEPROM 0x1
-
-struct ath_hal {
- u32 ah_magic;
- u16 ah_devid;
- u16 ah_subvendorid;
- u32 ah_macVersion;
- u16 ah_macRev;
- u16 ah_phyRev;
- u16 ah_analog5GhzRev;
- u16 ah_analog2GhzRev;
-
- void __iomem *ah_sh;
- struct ath_softc *ah_sc;
-
- enum nl80211_iftype ah_opmode;
- struct ath9k_ops_config ah_config;
- struct ath9k_hw_capabilities ah_caps;
-
- u16 ah_countryCode;
- u32 ah_flags;
- int16_t ah_powerLimit;
- u16 ah_maxPowerLevel;
- u32 ah_tpScale;
- u16 ah_currentRD;
- u16 ah_currentRDExt;
- u16 ah_currentRDInUse;
- u16 ah_currentRD5G;
- u16 ah_currentRD2G;
- char ah_iso[4];
-
- struct ath9k_channel ah_channels[150];
- struct ath9k_channel *ah_curchan;
- u32 ah_nchan;
-
- bool ah_isPciExpress;
- u16 ah_txTrigLevel;
- u16 ah_rfsilent;
- u32 ah_rfkill_gpio;
- u32 ah_rfkill_polarity;
-
-#ifndef ATH_NF_PER_CHAN
- struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
+ enum ath9k_ht_macmode tx_chan_width;
+
+ struct ath_config config;
+ struct ath_rx rx;
+ struct ath_tx tx;
+ struct ath_beacon beacon;
+ struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
+ struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
+ struct ath_rate_table *cur_rate_table;
+ struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
+
+ struct ath_led radio_led;
+ struct ath_led assoc_led;
+ struct ath_led tx_led;
+ struct ath_led rx_led;
+ struct delayed_work ath_led_blink_work;
+ int led_on_duration;
+ int led_off_duration;
+ int led_on_cnt;
+ int led_off_cnt;
+
+ struct ath_rfkill rf_kill;
+ struct ath_ani ani;
+ struct ath9k_node_stats nodestats;
+#ifdef CONFIG_ATH9K_DEBUG
+ struct ath9k_debug debug;
+#endif
+ struct ath_bus_ops *bus_ops;
+};
+
+struct ath_wiphy {
+ struct ath_softc *sc; /* shared for all virtual wiphys */
+ struct ieee80211_hw *hw;
+ enum ath_wiphy_state {
+ ATH_WIPHY_INACTIVE,
+ ATH_WIPHY_ACTIVE,
+ ATH_WIPHY_PAUSING,
+ ATH_WIPHY_PAUSED,
+ ATH_WIPHY_SCAN,
+ } state;
+ int chan_idx;
+ int chan_is_ht;
+};
+
+int ath_reset(struct ath_softc *sc, bool retry_tx);
+int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
+int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
+int ath_cabq_update(struct ath_softc *);
+
+static inline void ath_read_cachesize(struct ath_softc *sc, int *csz)
+{
+ sc->bus_ops->read_cachesize(sc, csz);
+}
+
+static inline void ath_bus_cleanup(struct ath_softc *sc)
+{
+ sc->bus_ops->cleanup(sc);
+}
+
+extern struct ieee80211_ops ath9k_ops;
+
+irqreturn_t ath_isr(int irq, void *dev);
+void ath_cleanup(struct ath_softc *sc);
+int ath_attach(u16 devid, struct ath_softc *sc);
+void ath_detach(struct ath_softc *sc);
+const char *ath_mac_bb_name(u32 mac_bb_version);
+const char *ath_rf_name(u16 rf_version);
+void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
+void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
+ struct ath9k_channel *ichan);
+void ath_update_chainmask(struct ath_softc *sc, int is_ht);
+int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
+ struct ath9k_channel *hchan);
+void ath_radio_enable(struct ath_softc *sc);
+void ath_radio_disable(struct ath_softc *sc);
+
+#ifdef CONFIG_PCI
+int ath_pci_init(void);
+void ath_pci_exit(void);
+#else
+static inline int ath_pci_init(void) { return 0; };
+static inline void ath_pci_exit(void) {};
#endif
-};
-
-struct chan_centers {
- u16 synth_center;
- u16 ctl_center;
- u16 ext_center;
-};
-struct ath_rate_table;
-
-/* Helpers */
-
-enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
- const struct ath9k_channel *chan);
-bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val);
-u32 ath9k_hw_reverse_bits(u32 val, u32 n);
-bool ath9k_get_channel_edges(struct ath_hal *ah,
- u16 flags, u16 *low,
- u16 *high);
-u16 ath9k_hw_computetxtime(struct ath_hal *ah,
- struct ath_rate_table *rates,
- u32 frameLen, u16 rateix,
- bool shortPreamble);
-u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
-void ath9k_hw_get_channel_centers(struct ath_hal *ah,
- struct ath9k_channel *chan,
- struct chan_centers *centers);
-
-/* Attach, Detach */
-
-const char *ath9k_hw_probe(u16 vendorid, u16 devid);
-void ath9k_hw_detach(struct ath_hal *ah);
-struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
- void __iomem *mem, int *error);
-void ath9k_hw_rfdetach(struct ath_hal *ah);
-
-
-/* HW Reset */
-
-bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
- enum ath9k_ht_macmode macmode,
- u8 txchainmask, u8 rxchainmask,
- enum ath9k_ht_extprotspacing extprotspacing,
- bool bChannelChange, int *status);
-
-/* Key Cache Management */
-
-bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry);
-bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac);
-bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
- const struct ath9k_keyval *k,
- const u8 *mac, int xorKey);
-bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry);
-
-/* Power Management */
-
-bool ath9k_hw_setpower(struct ath_hal *ah,
- enum ath9k_power_mode mode);
-void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore);
-
-/* Beacon timers */
-
-void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period);
-void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
- const struct ath9k_beacon_state *bs);
-/* HW Capabilities */
-
-bool ath9k_hw_fill_cap_info(struct ath_hal *ah);
-bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
- u32 capability, u32 *result);
-bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
- u32 capability, u32 setting, int *status);
-
-/* GPIO / RFKILL / Antennae */
-
-void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio);
-u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio);
-void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
- u32 ah_signal_type);
-void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val);
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-void ath9k_enable_rfkill(struct ath_hal *ah);
+#ifdef CONFIG_ATHEROS_AR71XX
+int ath_ahb_init(void);
+void ath_ahb_exit(void);
+#else
+static inline int ath_ahb_init(void) { return 0; };
+static inline void ath_ahb_exit(void) {};
#endif
-int ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg);
-u32 ath9k_hw_getdefantenna(struct ath_hal *ah);
-void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna);
-bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
- enum ath9k_ant_setting settings,
- struct ath9k_channel *chan,
- u8 *tx_chainmask,
- u8 *rx_chainmask,
- u8 *antenna_cfgd);
-
-/* General Operation */
-
-u32 ath9k_hw_getrxfilter(struct ath_hal *ah);
-void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits);
-bool ath9k_hw_phy_disable(struct ath_hal *ah);
-bool ath9k_hw_disable(struct ath_hal *ah);
-bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit);
-void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac);
-bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac);
-void ath9k_hw_setopmode(struct ath_hal *ah);
-void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0, u32 filter1);
-void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask);
-bool ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask);
-void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId);
-u64 ath9k_hw_gettsf64(struct ath_hal *ah);
-void ath9k_hw_reset_tsf(struct ath_hal *ah);
-bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting);
-bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us);
-void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode);
-
-/* Regulatory */
-
-bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah);
-struct ath9k_channel* ath9k_regd_check_channel(struct ath_hal *ah,
- const struct ath9k_channel *c);
-u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan);
-u32 ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
- struct ath9k_channel *chan);
-bool ath9k_regd_init_channels(struct ath_hal *ah,
- u32 maxchans, u32 *nchans, u8 *regclassids,
- u32 maxregids, u32 *nregids, u16 cc,
- bool enableOutdoor, bool enableExtendedChannels);
-/* ANI */
+static inline void ath9k_ps_wakeup(struct ath_softc *sc)
+{
+ if (atomic_inc_return(&sc->ps_usecount) == 1)
+ if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) {
+ sc->sc_ah->restore_mode = sc->sc_ah->power_mode;
+ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+ }
+}
+
+static inline void ath9k_ps_restore(struct ath_softc *sc)
+{
+ if (atomic_dec_and_test(&sc->ps_usecount))
+ if ((sc->hw->conf.flags & IEEE80211_CONF_PS) &&
+ !(sc->sc_flags & SC_OP_WAIT_FOR_BEACON))
+ ath9k_hw_setpower(sc->sc_ah,
+ sc->sc_ah->restore_mode);
+}
+
+
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw);
+int ath9k_wiphy_add(struct ath_softc *sc);
+int ath9k_wiphy_del(struct ath_wiphy *aphy);
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb);
+int ath9k_wiphy_pause(struct ath_wiphy *aphy);
+int ath9k_wiphy_unpause(struct ath_wiphy *aphy);
+int ath9k_wiphy_select(struct ath_wiphy *aphy);
+void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int);
+void ath9k_wiphy_chan_work(struct work_struct *work);
+bool ath9k_wiphy_started(struct ath_softc *sc);
+void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
+ struct ath_wiphy *selected);
+bool ath9k_wiphy_scanning(struct ath_softc *sc);
+void ath9k_wiphy_work(struct work_struct *work);
-void ath9k_ani_reset(struct ath_hal *ah);
-void ath9k_hw_ani_monitor(struct ath_hal *ah,
- const struct ath9k_node_stats *stats,
- struct ath9k_channel *chan);
-bool ath9k_hw_phycounters(struct ath_hal *ah);
-void ath9k_enable_mib_counters(struct ath_hal *ah);
-void ath9k_hw_disable_mib_counters(struct ath_hal *ah);
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
- u32 *rxc_pcnt,
- u32 *rxf_pcnt,
- u32 *txf_pcnt);
-void ath9k_hw_procmibevent(struct ath_hal *ah,
- const struct ath9k_node_stats *stats);
-void ath9k_hw_ani_setup(struct ath_hal *ah);
-void ath9k_hw_ani_attach(struct ath_hal *ah);
-void ath9k_hw_ani_detach(struct ath_hal *ah);
-
-/* Calibration */
-
-void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
- bool *isCalDone);
-void ath9k_hw_start_nfcal(struct ath_hal *ah);
-void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan);
-int16_t ath9k_hw_getnf(struct ath_hal *ah,
- struct ath9k_channel *chan);
-void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah);
-s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan);
-bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
- u8 rxchainmask, bool longcal,
- bool *isCalDone);
-bool ath9k_hw_init_cal(struct ath_hal *ah,
- struct ath9k_channel *chan);
-
-
-/* EEPROM */
-
-int ath9k_hw_set_txpower(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u16 cfgCtl,
- u8 twiceAntennaReduction,
- u8 twiceMaxRegulatoryPower,
- u8 powerLimit);
-void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan);
-bool ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
- struct ath9k_channel *chan,
- int16_t *ratesArray,
- u16 cfgCtl,
- u8 AntennaReduction,
- u8 twiceMaxRegulatoryPower,
- u8 powerLimit);
-bool ath9k_hw_set_power_cal_table(struct ath_hal *ah,
- struct ath9k_channel *chan,
- int16_t *pTxPowerIndexOffset);
-bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
- struct ath9k_channel *chan);
-int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u8 index, u16 *config);
-u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah,
- enum ieee80211_band freq_band);
-u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz);
-int ath9k_hw_eeprom_attach(struct ath_hal *ah);
-
-/* Interrupt Handling */
-
-bool ath9k_hw_intrpend(struct ath_hal *ah);
-bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked);
-enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah);
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints);
-
-/* MAC (PCU/QCU) */
-
-u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q);
-bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp);
-bool ath9k_hw_txstart(struct ath_hal *ah, u32 q);
-u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q);
-bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel);
-bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q);
-bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
- u32 segLen, bool firstSeg,
- bool lastSeg, const struct ath_desc *ds0);
-void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds);
-int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds);
-void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
- u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
- u32 keyIx, enum ath9k_key_type keyType, u32 flags);
-void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
- struct ath_desc *lastds,
- u32 durUpdateEn, u32 rtsctsRate,
- u32 rtsctsDuration,
- struct ath9k_11n_rate_series series[],
- u32 nseries, u32 flags);
-void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
- u32 aggrLen);
-void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
- u32 numDelims);
-void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds);
-void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds);
-void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
- u32 burstDuration);
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
- u32 vmf);
-void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs);
-bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
- const struct ath9k_tx_queue_info *qinfo);
-bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
- struct ath9k_tx_queue_info *qinfo);
-int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
- const struct ath9k_tx_queue_info *qinfo);
-bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q);
-bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q);
-int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
- u32 pa, struct ath_desc *nds, u64 tsf);
-bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
- u32 size, u32 flags);
-bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set);
-void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp);
-void ath9k_hw_rxena(struct ath_hal *ah);
-void ath9k_hw_startpcureceive(struct ath_hal *ah);
-void ath9k_hw_stoppcurecv(struct ath_hal *ah);
-bool ath9k_hw_stopdmarecv(struct ath_hal *ah);
+/*
+ * Read and write, they both share the same lock. We do this to serialize
+ * reads and writes on Atheros 802.11n PCI devices only. This is required
+ * as the FIFO on these devices can only accept sanely 2 requests. After
+ * that the device goes bananas. Serializing the reads/writes prevents this
+ * from happening.
+ */
-#endif
+static inline void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
+{
+ if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+ unsigned long flags;
+ spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+ iowrite32(val, ah->ah_sc->mem + reg_offset);
+ spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+ } else
+ iowrite32(val, ah->ah_sc->mem + reg_offset);
+}
+
+static inline unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
+{
+ u32 val;
+ if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+ unsigned long flags;
+ spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+ val = ioread32(ah->ah_sc->mem + reg_offset);
+ spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+ } else
+ val = ioread32(ah->ah_sc->mem + reg_offset);
+ return val;
+}
+
+#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index 3ab0b43aaf93..ec995730632d 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,9 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
+#include "ath9k.h"
+
+#define FUDGE 2
/*
* This function will modify certain transmit queue properties depending on
@@ -23,11 +25,11 @@
*/
static int ath_beaconq_config(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath9k_tx_queue_info qi;
ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
+ if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
/* Always burst out beacon and CAB traffic. */
qi.tqi_aifs = 1;
qi.tqi_cwmin = 0;
@@ -44,46 +46,33 @@ static int ath_beaconq_config(struct ath_softc *sc)
"unable to update h/w beacon queue parameters\n");
return 0;
} else {
- ath9k_hw_resettxqueue(ah, sc->beacon.beaconq); /* push to h/w */
+ ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
return 1;
}
}
-static void ath_bstuck_process(struct ath_softc *sc)
-{
- DPRINTF(sc, ATH_DBG_BEACON,
- "stuck beacon; resetting (bmiss count %u)\n",
- sc->beacon.bmisscnt);
- ath_reset(sc, false);
-}
-
/*
* Associates the beacon frame buffer with a transmit descriptor. Will set
* up all required antenna switch parameters, rate codes, and channel flags.
* Beacons are always sent out at the lowest rate, and are not retried.
*/
-static void ath_beacon_setup(struct ath_softc *sc,
- struct ath_vap *avp, struct ath_buf *bf)
+static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
+ struct ath_buf *bf)
{
struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath_desc *ds;
struct ath9k_11n_rate_series series[4];
struct ath_rate_table *rt;
- int flags, antenna;
- u8 rix, rate;
- int ctsrate = 0;
- int ctsduration = 0;
-
- DPRINTF(sc, ATH_DBG_BEACON, "m %p len %u\n", skb, skb->len);
+ int flags, antenna, ctsrate = 0, ctsduration = 0;
+ u8 rate;
- /* setup descriptors */
ds = bf->bf_desc;
-
flags = ATH9K_TXDESC_NOACK;
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC &&
- (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+ if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
+ (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) &&
+ (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
ds->ds_link = bf->bf_daddr; /* self-linked */
flags |= ATH9K_TXDESC_VEOL;
/* Let hardware handle antenna switching. */
@@ -92,65 +81,53 @@ static void ath_beacon_setup(struct ath_softc *sc,
ds->ds_link = 0;
/*
* Switch antenna every beacon.
- * Should only switch every beacon period, not for every
- * SWBA's
- * XXX assumes two antenna
+ * Should only switch every beacon period, not for every SWBA
+ * XXX assumes two antennae
*/
- antenna = ((sc->beacon.ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1);
+ antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
}
ds->ds_data = bf->bf_buf_addr;
- /*
- * Calculate rate code.
- * XXX everything at min xmit rate
- */
- rix = 0;
rt = sc->cur_rate_table;
- rate = rt->info[rix].ratecode;
+ rate = rt->info[0].ratecode;
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
- rate |= rt->info[rix].short_preamble;
-
- ath9k_hw_set11n_txdesc(ah, ds,
- skb->len + FCS_LEN, /* frame length */
- ATH9K_PKT_TYPE_BEACON, /* Atheros packet type */
- MAX_RATE_POWER, /* FIXME */
- ATH9K_TXKEYIX_INVALID, /* no encryption */
- ATH9K_KEY_TYPE_CLEAR, /* no encryption */
- flags /* no ack,
- veol for beacons */
- );
+ rate |= rt->info[0].short_preamble;
+
+ ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
+ ATH9K_PKT_TYPE_BEACON,
+ MAX_RATE_POWER,
+ ATH9K_TXKEYIX_INVALID,
+ ATH9K_KEY_TYPE_CLEAR,
+ flags);
/* NB: beacon's BufLen must be a multiple of 4 bytes */
- ath9k_hw_filltxdesc(ah, ds,
- roundup(skb->len, 4), /* buffer length */
- true, /* first segment */
- true, /* last segment */
- ds /* first descriptor */
- );
+ ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
+ true, true, ds);
memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
series[0].Tries = 1;
series[0].Rate = rate;
- series[0].ChSel = sc->sc_tx_chainmask;
+ series[0].ChSel = sc->tx_chainmask;
series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
- ath9k_hw_set11n_ratescenario(ah, ds, ds, 0,
- ctsrate, ctsduration, series, 4, 0);
+ ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
+ series, 4, 0);
}
-/* Generate beacon frame and queue cab data for a vap */
-static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
+static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
struct ath_buf *bf;
- struct ath_vap *avp;
+ struct ath_vif *avp;
struct sk_buff *skb;
struct ath_txq *cabq;
- struct ieee80211_vif *vif;
struct ieee80211_tx_info *info;
int cabq_depth;
- vif = sc->sc_vaps[if_id];
- ASSERT(vif);
+ if (aphy->state != ATH_WIPHY_ACTIVE)
+ return NULL;
avp = (void *)vif->drv_priv;
cabq = sc->beacon.cabq;
@@ -161,19 +138,24 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
return NULL;
}
+ /* Release the old beacon first */
+
bf = avp->av_bcbuf;
skb = (struct sk_buff *)bf->bf_mpdu;
if (skb) {
- pci_unmap_single(sc->pdev, bf->bf_dmacontext,
- skb->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(sc->dev, bf->bf_dmacontext,
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
}
- skb = ieee80211_beacon_get(sc->hw, vif);
+ /* Get a new beacon from mac80211 */
+
+ skb = ieee80211_beacon_get(hw, vif);
bf->bf_mpdu = skb;
if (skb == NULL)
return NULL;
+ ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
+ avp->tsf_adjust;
info = IEEE80211_SKB_CB(skb);
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
@@ -188,54 +170,42 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
}
bf->bf_buf_addr = bf->bf_dmacontext =
- pci_map_single(sc->pdev, skb->data,
- skb->len,
- PCI_DMA_TODEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) {
+ dma_map_single(sc->dev, skb->data,
+ skb->len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
- DPRINTF(sc, ATH_DBG_CONFIG,
- "pci_dma_mapping_error() on beaconing\n");
+ DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error on beaconing\n");
return NULL;
}
- skb = ieee80211_get_buffered_bc(sc->hw, vif);
+ skb = ieee80211_get_buffered_bc(hw, vif);
/*
* if the CABQ traffic from previous DTIM is pending and the current
* beacon is also a DTIM.
- * 1) if there is only one vap let the cab traffic continue.
- * 2) if there are more than one vap and we are using staggered
+ * 1) if there is only one vif let the cab traffic continue.
+ * 2) if there are more than one vif and we are using staggered
* beacons, then drain the cabq by dropping all the frames in
- * the cabq so that the current vaps cab traffic can be scheduled.
+ * the cabq so that the current vifs cab traffic can be scheduled.
*/
spin_lock_bh(&cabq->axq_lock);
cabq_depth = cabq->axq_depth;
spin_unlock_bh(&cabq->axq_lock);
if (skb && cabq_depth) {
- /*
- * Unlock the cabq lock as ath_tx_draintxq acquires
- * the lock again which is a common function and that
- * acquires txq lock inside.
- */
- if (sc->sc_nvaps > 1) {
- ath_tx_draintxq(sc, cabq, false);
+ if (sc->nvifs > 1) {
DPRINTF(sc, ATH_DBG_BEACON,
- "flush previous cabq traffic\n");
+ "Flushing previous cabq traffic\n");
+ ath_draintxq(sc, cabq, false);
}
}
- /* Construct tx descriptor. */
ath_beacon_setup(sc, avp, bf);
- /*
- * Enable the CAB queue before the beacon queue to
- * insure cab frames are triggered by this beacon.
- */
while (skb) {
- ath_tx_cabq(sc, skb);
- skb = ieee80211_get_buffered_bc(sc->hw, vif);
+ ath_tx_cabq(hw, skb);
+ skb = ieee80211_get_buffered_bc(hw, vif);
}
return bf;
@@ -245,28 +215,22 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
* Startup beacon transmission for adhoc mode when they are sent entirely
* by the hardware using the self-linked descriptor + veol trick.
*/
-static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
+static void ath_beacon_start_adhoc(struct ath_softc *sc,
+ struct ieee80211_vif *vif)
{
- struct ieee80211_vif *vif;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath_buf *bf;
- struct ath_vap *avp;
+ struct ath_vif *avp;
struct sk_buff *skb;
- vif = sc->sc_vaps[if_id];
- ASSERT(vif);
-
avp = (void *)vif->drv_priv;
- if (avp->av_bcbuf == NULL) {
- DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n",
- avp, avp != NULL ? avp->av_bcbuf : NULL);
+ if (avp->av_bcbuf == NULL)
return;
- }
+
bf = avp->av_bcbuf;
skb = (struct sk_buff *) bf->bf_mpdu;
- /* Construct tx descriptor. */
ath_beacon_setup(sc, avp, bf);
/* NB: caller is known to have already stopped tx dma */
@@ -276,7 +240,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
}
-int ath_beaconq_setup(struct ath_hal *ah)
+int ath_beaconq_setup(struct ath_hw *ah)
{
struct ath9k_tx_queue_info qi;
@@ -288,18 +252,14 @@ int ath_beaconq_setup(struct ath_hal *ah)
return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
}
-int ath_beacon_alloc(struct ath_softc *sc, int if_id)
+int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
{
- struct ieee80211_vif *vif;
- struct ath_vap *avp;
- struct ieee80211_hdr *hdr;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_vif *avp;
struct ath_buf *bf;
struct sk_buff *skb;
__le64 tstamp;
- vif = sc->sc_vaps[if_id];
- ASSERT(vif);
-
avp = (void *)vif->drv_priv;
/* Allocate a beacon descriptor if we haven't done so. */
@@ -310,51 +270,46 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
struct ath_buf, list);
list_del(&avp->av_bcbuf->list);
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP ||
- !(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+ if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
+ !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
int slot;
/*
- * Assign the vap to a beacon xmit slot. As
+ * Assign the vif to a beacon xmit slot. As
* above, this cannot fail to find one.
*/
avp->av_bslot = 0;
for (slot = 0; slot < ATH_BCBUF; slot++)
- if (sc->beacon.bslot[slot] == ATH_IF_ID_ANY) {
+ if (sc->beacon.bslot[slot] == NULL) {
/*
* XXX hack, space out slots to better
* deal with misses
*/
if (slot+1 < ATH_BCBUF &&
- sc->beacon.bslot[slot+1] ==
- ATH_IF_ID_ANY) {
+ sc->beacon.bslot[slot+1] == NULL) {
avp->av_bslot = slot+1;
break;
}
avp->av_bslot = slot;
/* NB: keep looking for a double slot */
}
- BUG_ON(sc->beacon.bslot[avp->av_bslot] != ATH_IF_ID_ANY);
- sc->beacon.bslot[avp->av_bslot] = if_id;
- sc->sc_nbcnvaps++;
+ BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
+ sc->beacon.bslot[avp->av_bslot] = vif;
+ sc->beacon.bslot_aphy[avp->av_bslot] = aphy;
+ sc->nbcnvifs++;
}
}
- /* release the previous beacon frame , if it already exists. */
+ /* release the previous beacon frame, if it already exists. */
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
skb = (struct sk_buff *)bf->bf_mpdu;
- pci_unmap_single(sc->pdev, bf->bf_dmacontext,
- skb->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(sc->dev, bf->bf_dmacontext,
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
}
- /*
- * NB: the beacon data buffer must be 32-bit aligned.
- * FIXME: Fill avp->av_btxctl.txpower and
- * avp->av_btxctl.shortPreamble
- */
+ /* NB: the beacon data buffer must be 32-bit aligned. */
skb = ieee80211_beacon_get(sc->hw, vif);
if (skb == NULL) {
DPRINTF(sc, ATH_DBG_BEACON, "cannot get skb\n");
@@ -363,75 +318,65 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
-
- /*
- * Calculate a TSF adjustment factor required for
- * staggered beacons. Note that we assume the format
- * of the beacon frame leaves the tstamp field immediately
- * following the header.
- */
+ /* Calculate a TSF adjustment factor required for staggered beacons. */
if (avp->av_bslot > 0) {
u64 tsfadjust;
- __le64 val;
int intval;
intval = sc->hw->conf.beacon_int ?
sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
/*
- * The beacon interval is in TU's; the TSF in usecs.
- * We figure out how many TU's to add to align the
- * timestamp then convert to TSF units and handle
- * byte swapping before writing it in the frame.
- * The hardware will then add this each time a beacon
- * frame is sent. Note that we align vap's 1..N
- * and leave vap 0 untouched. This means vap 0
- * has a timestamp in one beacon interval while the
- * others get a timestamp aligned to the next interval.
+ * Calculate the TSF offset for this beacon slot, i.e., the
+ * number of usecs that need to be added to the timestamp field
+ * in Beacon and Probe Response frames. Beacon slot 0 is
+ * processed at the correct offset, so it does not require TSF
+ * adjustment. Other slots are adjusted to get the timestamp
+ * close to the TBTT for the BSS.
*/
- tsfadjust = (intval * (ATH_BCBUF - avp->av_bslot)) / ATH_BCBUF;
- val = cpu_to_le64(tsfadjust << 10); /* TU->TSF */
+ tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
+ avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
DPRINTF(sc, ATH_DBG_BEACON,
"stagger beacons, bslot %d intval %u tsfadjust %llu\n",
avp->av_bslot, intval, (unsigned long long)tsfadjust);
- hdr = (struct ieee80211_hdr *)skb->data;
- memcpy(&hdr[1], &val, sizeof(val));
- }
+ ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
+ avp->tsf_adjust;
+ } else
+ avp->tsf_adjust = cpu_to_le64(0);
bf->bf_mpdu = skb;
bf->bf_buf_addr = bf->bf_dmacontext =
- pci_map_single(sc->pdev, skb->data,
- skb->len,
- PCI_DMA_TODEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_buf_addr))) {
+ dma_map_single(sc->dev, skb->data,
+ skb->len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
- DPRINTF(sc, ATH_DBG_CONFIG,
- "pci_dma_mapping_error() on beacon alloc\n");
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "dma_mapping_error on beacon alloc\n");
return -ENOMEM;
}
return 0;
}
-void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
+void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
{
if (avp->av_bcbuf != NULL) {
struct ath_buf *bf;
if (avp->av_bslot != -1) {
- sc->beacon.bslot[avp->av_bslot] = ATH_IF_ID_ANY;
- sc->sc_nbcnvaps--;
+ sc->beacon.bslot[avp->av_bslot] = NULL;
+ sc->beacon.bslot_aphy[avp->av_bslot] = NULL;
+ sc->nbcnvifs--;
}
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
- pci_unmap_single(sc->pdev, bf->bf_dmacontext,
- skb->len,
- PCI_DMA_TODEVICE);
+ dma_unmap_single(sc->dev, bf->bf_dmacontext,
+ skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
}
@@ -441,92 +386,45 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
}
}
-void ath9k_beacon_tasklet(unsigned long data)
+void ath_beacon_tasklet(unsigned long data)
{
struct ath_softc *sc = (struct ath_softc *)data;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath_buf *bf = NULL;
- int slot, if_id;
- u32 bfaddr;
- u32 rx_clear = 0, rx_frame = 0, tx_frame = 0;
- u32 show_cycles = 0;
- u32 bc = 0; /* beacon count */
+ struct ieee80211_vif *vif;
+ struct ath_wiphy *aphy;
+ int slot;
+ u32 bfaddr, bc = 0, tsftu;
u64 tsf;
- u32 tsftu;
u16 intval;
- if (sc->sc_flags & SC_OP_NO_RESET) {
- show_cycles = ath9k_hw_GetMibCycleCountsPct(ah,
- &rx_clear, &rx_frame, &tx_frame);
- }
-
/*
* Check if the previous beacon has gone out. If
* not don't try to post another, skip this period
* and wait for the next. Missed beacons indicate
* a problem and should not occur. If we miss too
* many consecutive beacons reset the device.
- *
- * FIXME: Clean up this mess !!
*/
if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
sc->beacon.bmisscnt++;
- /* XXX: doth needs the chanchange IE countdown decremented.
- * We should consider adding a mac80211 call to indicate
- * a beacon miss so appropriate action could be taken
- * (in that layer).
- */
+
if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
- if (sc->sc_flags & SC_OP_NO_RESET) {
- DPRINTF(sc, ATH_DBG_BEACON,
- "missed %u consecutive beacons\n",
- sc->beacon.bmisscnt);
- if (show_cycles) {
- /*
- * Display cycle counter stats from HW
- * to aide in debug of stickiness.
- */
- DPRINTF(sc, ATH_DBG_BEACON,
- "busy times: rx_clear=%d, "
- "rx_frame=%d, tx_frame=%d\n",
- rx_clear, rx_frame,
- tx_frame);
- } else {
- DPRINTF(sc, ATH_DBG_BEACON,
- "unable to obtain "
- "busy times\n");
- }
- } else {
- DPRINTF(sc, ATH_DBG_BEACON,
- "missed %u consecutive beacons\n",
- sc->beacon.bmisscnt);
- }
+ DPRINTF(sc, ATH_DBG_BEACON,
+ "missed %u consecutive beacons\n",
+ sc->beacon.bmisscnt);
} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
- if (sc->sc_flags & SC_OP_NO_RESET) {
- if (sc->beacon.bmisscnt == BSTUCK_THRESH) {
- DPRINTF(sc, ATH_DBG_BEACON,
- "beacon is officially "
- "stuck\n");
- }
- } else {
- DPRINTF(sc, ATH_DBG_BEACON,
- "beacon is officially stuck\n");
- ath_bstuck_process(sc);
- }
+ DPRINTF(sc, ATH_DBG_BEACON,
+ "beacon is officially stuck\n");
+ ath_reset(sc, false);
}
+
return;
}
if (sc->beacon.bmisscnt != 0) {
- if (sc->sc_flags & SC_OP_NO_RESET) {
- DPRINTF(sc, ATH_DBG_BEACON,
- "resume beacon xmit after %u misses\n",
- sc->beacon.bmisscnt);
- } else {
- DPRINTF(sc, ATH_DBG_BEACON,
- "resume beacon xmit after %u misses\n",
- sc->beacon.bmisscnt);
- }
+ DPRINTF(sc, ATH_DBG_BEACON,
+ "resume beacon xmit after %u misses\n",
+ sc->beacon.bmisscnt);
sc->beacon.bmisscnt = 0;
}
@@ -542,21 +440,30 @@ void ath9k_beacon_tasklet(unsigned long data)
tsf = ath9k_hw_gettsf64(ah);
tsftu = TSF_TO_TU(tsf>>32, tsf);
slot = ((tsftu % intval) * ATH_BCBUF) / intval;
- if_id = sc->beacon.bslot[(slot + 1) % ATH_BCBUF];
+ /*
+ * Reverse the slot order to get slot 0 on the TBTT offset that does
+ * not require TSF adjustment and other slots adding
+ * slot/ATH_BCBUF * beacon_int to timestamp. For example, with
+ * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 ..
+ * and slot 0 is at correct offset to TBTT.
+ */
+ slot = ATH_BCBUF - slot - 1;
+ vif = sc->beacon.bslot[slot];
+ aphy = sc->beacon.bslot_aphy[slot];
DPRINTF(sc, ATH_DBG_BEACON,
- "slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
- slot, (unsigned long long)tsf, tsftu,
- intval, if_id);
+ "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
+ slot, tsf, tsftu, intval, vif);
bfaddr = 0;
- if (if_id != ATH_IF_ID_ANY) {
- bf = ath_beacon_generate(sc, if_id);
+ if (vif) {
+ bf = ath_beacon_generate(aphy->hw, vif);
if (bf != NULL) {
bfaddr = bf->bf_daddr;
bc = 1;
}
}
+
/*
* Handle slot time change when a non-ERP station joins/leaves
* an 11g network. The 802.11 layer notifies us via callback,
@@ -573,7 +480,6 @@ void ath9k_beacon_tasklet(unsigned long data)
* interval has passed. When bursting slot is always left
* set to ATH_BCBUF so this check is a noop.
*/
- /* XXX locking */
if (sc->beacon.updateslot == UPDATE) {
sc->beacon.updateslot = COMMIT; /* commit next beacon */
sc->beacon.slotupdate = slot;
@@ -590,265 +496,251 @@ void ath9k_beacon_tasklet(unsigned long data)
if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
DPRINTF(sc, ATH_DBG_FATAL,
"beacon queue %u did not stop?\n", sc->beacon.beaconq);
- /* NB: the HAL still stops DMA, so proceed */
}
/* NB: cabq traffic should already be queued and primed */
ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
ath9k_hw_txstart(ah, sc->beacon.beaconq);
- sc->beacon.ast_be_xmit += bc; /* XXX per-vap? */
+ sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */
}
}
/*
- * Configure the beacon and sleep timers.
- *
- * When operating as an AP this resets the TSF and sets
- * up the hardware to notify us when we need to issue beacons.
- *
- * When operating in station mode this sets up the beacon
- * timers according to the timestamp of the last received
- * beacon and the current TSF, configures PCF and DTIM
- * handling, programs the sleep registers so the hardware
- * will wakeup in time to receive beacons, and configures
- * the beacon miss handling so we'll receive a BMISS
- * interrupt when we stop seeing beacons from the AP
- * we've associated with.
+ * For multi-bss ap support beacons are either staggered evenly over N slots or
+ * burst together. For the former arrange for the SWBA to be delivered for each
+ * slot. Slots that are not occupied will generate nothing.
*/
-void ath_beacon_config(struct ath_softc *sc, int if_id)
+static void ath_beacon_config_ap(struct ath_softc *sc,
+ struct ath_beacon_config *conf,
+ struct ath_vif *avp)
{
- struct ieee80211_vif *vif;
- struct ath_hal *ah = sc->sc_ah;
- struct ath_beacon_config conf;
- struct ath_vap *avp;
- enum nl80211_iftype opmode;
u32 nexttbtt, intval;
- if (if_id != ATH_IF_ID_ANY) {
- vif = sc->sc_vaps[if_id];
- ASSERT(vif);
- avp = (void *)vif->drv_priv;
- opmode = avp->av_opmode;
- } else {
- opmode = sc->sc_ah->ah_opmode;
- }
+ /* Configure the timers only when the TSF has to be reset */
- memset(&conf, 0, sizeof(struct ath_beacon_config));
+ if (!(sc->sc_flags & SC_OP_TSF_RESET))
+ return;
- conf.beacon_interval = sc->hw->conf.beacon_int ?
- sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
- conf.listen_interval = 1;
- conf.dtim_period = conf.beacon_interval;
- conf.dtim_count = 1;
- conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
+ /* NB: the beacon interval is kept internally in TU's */
+ intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+ intval /= ATH_BCBUF; /* for staggered beacons */
+ nexttbtt = intval;
+ intval |= ATH9K_BEACON_RESET_TSF;
- /* extract tstamp from last beacon and convert to TU */
- nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
+ /*
+ * In AP mode we enable the beacon timers and SWBA interrupts to
+ * prepare beacon frames.
+ */
+ intval |= ATH9K_BEACON_ENA;
+ sc->imask |= ATH9K_INT_SWBA;
+ ath_beaconq_config(sc);
- /* XXX conditionalize multi-bss support? */
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
- /*
- * For multi-bss ap support beacons are either staggered
- * evenly over N slots or burst together. For the former
- * arrange for the SWBA to be delivered for each slot.
- * Slots that are not occupied will generate nothing.
- */
- /* NB: the beacon interval is kept internally in TU's */
- intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
- intval /= ATH_BCBUF; /* for staggered beacons */
- } else {
- intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
- }
+ /* Set the computed AP beacon timers */
- if (nexttbtt == 0) /* e.g. for ap mode */
- nexttbtt = intval;
- else if (intval) /* NB: can be 0 for monitor mode */
- nexttbtt = roundup(nexttbtt, intval);
+ ath9k_hw_set_interrupts(sc->sc_ah, 0);
+ ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+ sc->beacon.bmisscnt = 0;
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
- DPRINTF(sc, ATH_DBG_BEACON, "nexttbtt %u intval %u (%u)\n",
- nexttbtt, intval, conf.beacon_interval);
+ /* Clear the reset TSF flag, so that subsequent beacon updation
+ will not reset the HW TSF. */
- /* Check for NL80211_IFTYPE_AP and sc_nostabeacons for WDS client */
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) {
- struct ath9k_beacon_state bs;
- u64 tsf;
- u32 tsftu;
- int dtimperiod, dtimcount, sleepduration;
- int cfpperiod, cfpcount;
+ sc->sc_flags &= ~SC_OP_TSF_RESET;
+}
- /*
- * Setup dtim and cfp parameters according to
- * last beacon we received (which may be none).
- */
- dtimperiod = conf.dtim_period;
- if (dtimperiod <= 0) /* NB: 0 if not known */
- dtimperiod = 1;
- dtimcount = conf.dtim_count;
- if (dtimcount >= dtimperiod) /* NB: sanity check */
- dtimcount = 0;
- cfpperiod = 1; /* NB: no PCF support yet */
- cfpcount = 0;
-
- sleepduration = conf.listen_interval * intval;
- if (sleepduration <= 0)
- sleepduration = intval;
+/*
+ * This sets up the beacon timers according to the timestamp of the last
+ * received beacon and the current TSF, configures PCF and DTIM
+ * handling, programs the sleep registers so the hardware will wakeup in
+ * time to receive beacons, and configures the beacon miss handling so
+ * we'll receive a BMISS interrupt when we stop seeing beacons from the AP
+ * we've associated with.
+ */
+static void ath_beacon_config_sta(struct ath_softc *sc,
+ struct ath_beacon_config *conf,
+ struct ath_vif *avp)
+{
+ struct ath9k_beacon_state bs;
+ int dtimperiod, dtimcount, sleepduration;
+ int cfpperiod, cfpcount;
+ u32 nexttbtt = 0, intval, tsftu;
+ u64 tsf;
-#define FUDGE 2
- /*
- * Pull nexttbtt forward to reflect the current
- * TSF and calculate dtim+cfp state for the result.
- */
- tsf = ath9k_hw_gettsf64(ah);
- tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
- do {
- nexttbtt += intval;
- if (--dtimcount < 0) {
- dtimcount = dtimperiod - 1;
- if (--cfpcount < 0)
- cfpcount = cfpperiod - 1;
- }
- } while (nexttbtt < tsftu);
-#undef FUDGE
- memset(&bs, 0, sizeof(bs));
- bs.bs_intval = intval;
- bs.bs_nexttbtt = nexttbtt;
- bs.bs_dtimperiod = dtimperiod*intval;
- bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
- bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
- bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
- bs.bs_cfpmaxduration = 0;
+ memset(&bs, 0, sizeof(bs));
+ intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
- /*
- * Calculate the number of consecutive beacons to miss
- * before taking a BMISS interrupt. The configuration
- * is specified in TU so we only need calculate based
- * on the beacon interval. Note that we clamp the
- * result to at most 15 beacons.
- */
- if (sleepduration > intval) {
- bs.bs_bmissthreshold = conf.listen_interval *
- ATH_DEFAULT_BMISS_LIMIT / 2;
- } else {
- bs.bs_bmissthreshold =
- DIV_ROUND_UP(conf.bmiss_timeout, intval);
- if (bs.bs_bmissthreshold > 15)
- bs.bs_bmissthreshold = 15;
- else if (bs.bs_bmissthreshold <= 0)
- bs.bs_bmissthreshold = 1;
- }
+ /*
+ * Setup dtim and cfp parameters according to
+ * last beacon we received (which may be none).
+ */
+ dtimperiod = conf->dtim_period;
+ if (dtimperiod <= 0) /* NB: 0 if not known */
+ dtimperiod = 1;
+ dtimcount = conf->dtim_count;
+ if (dtimcount >= dtimperiod) /* NB: sanity check */
+ dtimcount = 0;
+ cfpperiod = 1; /* NB: no PCF support yet */
+ cfpcount = 0;
+
+ sleepduration = conf->listen_interval * intval;
+ if (sleepduration <= 0)
+ sleepduration = intval;
- /*
- * Calculate sleep duration. The configuration is
- * given in ms. We insure a multiple of the beacon
- * period is used. Also, if the sleep duration is
- * greater than the DTIM period then it makes senses
- * to make it a multiple of that.
- *
- * XXX fixed at 100ms
- */
+ /*
+ * Pull nexttbtt forward to reflect the current
+ * TSF and calculate dtim+cfp state for the result.
+ */
+ tsf = ath9k_hw_gettsf64(sc->sc_ah);
+ tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
+ do {
+ nexttbtt += intval;
+ if (--dtimcount < 0) {
+ dtimcount = dtimperiod - 1;
+ if (--cfpcount < 0)
+ cfpcount = cfpperiod - 1;
+ }
+ } while (nexttbtt < tsftu);
- bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100),
- sleepduration);
- if (bs.bs_sleepduration > bs.bs_dtimperiod)
- bs.bs_sleepduration = bs.bs_dtimperiod;
+ bs.bs_intval = intval;
+ bs.bs_nexttbtt = nexttbtt;
+ bs.bs_dtimperiod = dtimperiod*intval;
+ bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
+ bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
+ bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
+ bs.bs_cfpmaxduration = 0;
- DPRINTF(sc, ATH_DBG_BEACON,
- "tsf %llu "
- "tsf:tu %u "
- "intval %u "
- "nexttbtt %u "
- "dtim %u "
- "nextdtim %u "
- "bmiss %u "
- "sleep %u "
- "cfp:period %u "
- "maxdur %u "
- "next %u "
- "timoffset %u\n",
- (unsigned long long)tsf, tsftu,
- bs.bs_intval,
- bs.bs_nexttbtt,
- bs.bs_dtimperiod,
- bs.bs_nextdtim,
- bs.bs_bmissthreshold,
- bs.bs_sleepduration,
- bs.bs_cfpperiod,
- bs.bs_cfpmaxduration,
- bs.bs_cfpnext,
- bs.bs_timoffset
- );
-
- ath9k_hw_set_interrupts(ah, 0);
- ath9k_hw_set_sta_beacon_timers(ah, &bs);
- sc->sc_imask |= ATH9K_INT_BMISS;
- ath9k_hw_set_interrupts(ah, sc->sc_imask);
+ /*
+ * Calculate the number of consecutive beacons to miss* before taking
+ * a BMISS interrupt. The configuration is specified in TU so we only
+ * need calculate based on the beacon interval. Note that we clamp the
+ * result to at most 15 beacons.
+ */
+ if (sleepduration > intval) {
+ bs.bs_bmissthreshold = conf->listen_interval *
+ ATH_DEFAULT_BMISS_LIMIT / 2;
} else {
- u64 tsf;
- u32 tsftu;
- ath9k_hw_set_interrupts(ah, 0);
- if (nexttbtt == intval)
- intval |= ATH9K_BEACON_RESET_TSF;
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) {
- /*
- * Pull nexttbtt forward to reflect the current
- * TSF
- */
-#define FUDGE 2
- if (!(intval & ATH9K_BEACON_RESET_TSF)) {
- tsf = ath9k_hw_gettsf64(ah);
- tsftu = TSF_TO_TU((u32)(tsf>>32),
- (u32)tsf) + FUDGE;
- do {
- nexttbtt += intval;
- } while (nexttbtt < tsftu);
- }
-#undef FUDGE
- DPRINTF(sc, ATH_DBG_BEACON,
- "IBSS nexttbtt %u intval %u (%u)\n",
- nexttbtt,
- intval & ~ATH9K_BEACON_RESET_TSF,
- conf.beacon_interval);
-
- /*
- * In IBSS mode enable the beacon timers but only
- * enable SWBA interrupts if we need to manually
- * prepare beacon frames. Otherwise we use a
- * self-linked tx descriptor and let the hardware
- * deal with things.
- */
- intval |= ATH9K_BEACON_ENA;
- if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
- sc->sc_imask |= ATH9K_INT_SWBA;
- ath_beaconq_config(sc);
- } else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
- /*
- * In AP mode we enable the beacon timers and
- * SWBA interrupts to prepare beacon frames.
- */
- intval |= ATH9K_BEACON_ENA;
- sc->sc_imask |= ATH9K_INT_SWBA; /* beacon prepare */
- ath_beaconq_config(sc);
- }
- ath9k_hw_beaconinit(ah, nexttbtt, intval);
- sc->beacon.bmisscnt = 0;
- ath9k_hw_set_interrupts(ah, sc->sc_imask);
- /*
- * When using a self-linked beacon descriptor in
- * ibss mode load it once here.
- */
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC &&
- (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
- ath_beacon_start_adhoc(sc, 0);
+ bs.bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, intval);
+ if (bs.bs_bmissthreshold > 15)
+ bs.bs_bmissthreshold = 15;
+ else if (bs.bs_bmissthreshold <= 0)
+ bs.bs_bmissthreshold = 1;
}
+
+ /*
+ * Calculate sleep duration. The configuration is given in ms.
+ * We ensure a multiple of the beacon period is used. Also, if the sleep
+ * duration is greater than the DTIM period then it makes senses
+ * to make it a multiple of that.
+ *
+ * XXX fixed at 100ms
+ */
+
+ bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
+ if (bs.bs_sleepduration > bs.bs_dtimperiod)
+ bs.bs_sleepduration = bs.bs_dtimperiod;
+
+ /* TSF out of range threshold fixed at 1 second */
+ bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
+
+ DPRINTF(sc, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
+ DPRINTF(sc, ATH_DBG_BEACON,
+ "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
+ bs.bs_bmissthreshold, bs.bs_sleepduration,
+ bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
+
+ /* Set the computed STA beacon timers */
+
+ ath9k_hw_set_interrupts(sc->sc_ah, 0);
+ ath9k_hw_set_sta_beacon_timers(sc->sc_ah, &bs);
+ sc->imask |= ATH9K_INT_BMISS;
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
}
-void ath_beacon_sync(struct ath_softc *sc, int if_id)
+static void ath_beacon_config_adhoc(struct ath_softc *sc,
+ struct ath_beacon_config *conf,
+ struct ath_vif *avp,
+ struct ieee80211_vif *vif)
{
+ u64 tsf;
+ u32 tsftu, intval, nexttbtt;
+
+ intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+
+ /* Pull nexttbtt forward to reflect the current TSF */
+
+ nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
+ if (nexttbtt == 0)
+ nexttbtt = intval;
+ else if (intval)
+ nexttbtt = roundup(nexttbtt, intval);
+
+ tsf = ath9k_hw_gettsf64(sc->sc_ah);
+ tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
+ do {
+ nexttbtt += intval;
+ } while (nexttbtt < tsftu);
+
+ DPRINTF(sc, ATH_DBG_BEACON,
+ "IBSS nexttbtt %u intval %u (%u)\n",
+ nexttbtt, intval, conf->beacon_interval);
+
/*
- * Resync beacon timers using the tsf of the
- * beacon frame we just received.
+ * In IBSS mode enable the beacon timers but only enable SWBA interrupts
+ * if we need to manually prepare beacon frames. Otherwise we use a
+ * self-linked tx descriptor and let the hardware deal with things.
*/
- ath_beacon_config(sc, if_id);
- sc->sc_flags |= SC_OP_BEACONS;
+ intval |= ATH9K_BEACON_ENA;
+ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
+ sc->imask |= ATH9K_INT_SWBA;
+
+ ath_beaconq_config(sc);
+
+ /* Set the computed ADHOC beacon timers */
+
+ ath9k_hw_set_interrupts(sc->sc_ah, 0);
+ ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+ sc->beacon.bmisscnt = 0;
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
+ ath_beacon_start_adhoc(sc, vif);
+}
+
+void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
+{
+ struct ath_beacon_config conf;
+
+ /* Setup the beacon configuration parameters */
+
+ memset(&conf, 0, sizeof(struct ath_beacon_config));
+ conf.beacon_interval = sc->hw->conf.beacon_int ?
+ sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
+ conf.listen_interval = 1;
+ conf.dtim_period = conf.beacon_interval;
+ conf.dtim_count = 1;
+ conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
+
+ if (vif) {
+ struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
+
+ switch(avp->av_opmode) {
+ case NL80211_IFTYPE_AP:
+ ath_beacon_config_ap(sc, &conf, avp);
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
+ ath_beacon_config_adhoc(sc, &conf, avp, vif);
+ break;
+ case NL80211_IFTYPE_STATION:
+ ath_beacon_config_sta(sc, &conf, avp);
+ break;
+ default:
+ DPRINTF(sc, ATH_DBG_CONFIG,
+ "Unsupported beaconing mode\n");
+ return;
+ }
+
+ sc->sc_flags |= SC_OP_BEACONS;
+ }
}
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c
index 3c7454fc51bd..e2d62e97131c 100644
--- a/drivers/net/wireless/ath9k/calib.c
+++ b/drivers/net/wireless/ath9k/calib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,12 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
-
-static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
+#include "ath9k.h"
/* We can tune this as we go by monitoring really low values */
#define ATH9K_NF_TOO_LOW -60
@@ -28,7 +23,7 @@ static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
* is incorrect and we should use the static NF value. Later we can try to
* find out why they are reporting these values */
-static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf)
+static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf)
{
if (nf > ATH9K_NF_TOO_LOW) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
@@ -91,7 +86,7 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
return;
}
-static void ath9k_hw_do_getnf(struct ath_hal *ah,
+static void ath9k_hw_do_getnf(struct ath_hw *ah,
int16_t nfarray[NUM_NF_READINGS])
{
int16_t nf;
@@ -107,27 +102,29 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah,
"NF calibrated [ctl] [chain 0] is %d\n", nf);
nfarray[0] = nf;
- if (AR_SREV_9280_10_OR_LATER(ah))
- nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
- AR9280_PHY_CH1_MINCCA_PWR);
- else
- nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
- AR_PHY_CH1_MINCCA_PWR);
-
- if (nf & 0x100)
- nf = 0 - ((nf ^ 0x1ff) + 1);
- DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "NF calibrated [ctl] [chain 1] is %d\n", nf);
- nfarray[1] = nf;
+ if (!AR_SREV_9285(ah)) {
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+ AR9280_PHY_CH1_MINCCA_PWR);
+ else
+ nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+ AR_PHY_CH1_MINCCA_PWR);
- if (!AR_SREV_9280(ah)) {
- nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
- AR_PHY_CH2_MINCCA_PWR);
if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "NF calibrated [ctl] [chain 2] is %d\n", nf);
- nfarray[2] = nf;
+ "NF calibrated [ctl] [chain 1] is %d\n", nf);
+ nfarray[1] = nf;
+
+ if (!AR_SREV_9280(ah)) {
+ nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
+ AR_PHY_CH2_MINCCA_PWR);
+ if (nf & 0x100)
+ nf = 0 - ((nf ^ 0x1ff) + 1);
+ DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+ "NF calibrated [ctl] [chain 2] is %d\n", nf);
+ nfarray[2] = nf;
+ }
}
if (AR_SREV_9280_10_OR_LATER(ah))
@@ -143,58 +140,52 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah,
"NF calibrated [ext] [chain 0] is %d\n", nf);
nfarray[3] = nf;
- if (AR_SREV_9280_10_OR_LATER(ah))
- nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
- AR9280_PHY_CH1_EXT_MINCCA_PWR);
- else
- nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
- AR_PHY_CH1_EXT_MINCCA_PWR);
-
- if (nf & 0x100)
- nf = 0 - ((nf ^ 0x1ff) + 1);
- DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "NF calibrated [ext] [chain 1] is %d\n", nf);
- nfarray[4] = nf;
+ if (!AR_SREV_9285(ah)) {
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+ AR9280_PHY_CH1_EXT_MINCCA_PWR);
+ else
+ nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+ AR_PHY_CH1_EXT_MINCCA_PWR);
- if (!AR_SREV_9280(ah)) {
- nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
- AR_PHY_CH2_EXT_MINCCA_PWR);
if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "NF calibrated [ext] [chain 2] is %d\n", nf);
- nfarray[5] = nf;
+ "NF calibrated [ext] [chain 1] is %d\n", nf);
+ nfarray[4] = nf;
+
+ if (!AR_SREV_9280(ah)) {
+ nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
+ AR_PHY_CH2_EXT_MINCCA_PWR);
+ if (nf & 0x100)
+ nf = 0 - ((nf ^ 0x1ff) + 1);
+ DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+ "NF calibrated [ext] [chain 2] is %d\n", nf);
+ nfarray[5] = nf;
+ }
}
}
-static bool getNoiseFloorThresh(struct ath_hal *ah,
- const struct ath9k_channel *chan,
+static bool getNoiseFloorThresh(struct ath_hw *ah,
+ enum ieee80211_band band,
int16_t *nft)
{
- switch (chan->chanmode) {
- case CHANNEL_A:
- case CHANNEL_A_HT20:
- case CHANNEL_A_HT40PLUS:
- case CHANNEL_A_HT40MINUS:
- *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5);
+ switch (band) {
+ case IEEE80211_BAND_5GHZ:
+ *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_5);
break;
- case CHANNEL_B:
- case CHANNEL_G:
- case CHANNEL_G_HT20:
- case CHANNEL_G_HT40PLUS:
- case CHANNEL_G_HT40MINUS:
- *nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2);
+ case IEEE80211_BAND_2GHZ:
+ *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_2);
break;
default:
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "invalid channel flags 0x%x\n", chan->channelFlags);
+ BUG_ON(1);
return false;
}
return true;
}
-static void ath9k_hw_setup_calibration(struct ath_hal *ah,
+static void ath9k_hw_setup_calibration(struct ath_hw *ah,
struct hal_cal_list *currCal)
{
REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
@@ -228,10 +219,9 @@ static void ath9k_hw_setup_calibration(struct ath_hal *ah,
AR_PHY_TIMING_CTRL4_DO_CAL);
}
-static void ath9k_hw_reset_calibration(struct ath_hal *ah,
+static void ath9k_hw_reset_calibration(struct ath_hw *ah,
struct hal_cal_list *currCal)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
ath9k_hw_setup_calibration(ah, currCal);
@@ -239,23 +229,21 @@ static void ath9k_hw_reset_calibration(struct ath_hal *ah,
currCal->calState = CAL_RUNNING;
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- ahp->ah_Meas0.sign[i] = 0;
- ahp->ah_Meas1.sign[i] = 0;
- ahp->ah_Meas2.sign[i] = 0;
- ahp->ah_Meas3.sign[i] = 0;
+ ah->meas0.sign[i] = 0;
+ ah->meas1.sign[i] = 0;
+ ah->meas2.sign[i] = 0;
+ ah->meas3.sign[i] = 0;
}
- ahp->ah_CalSamples = 0;
+ ah->cal_samples = 0;
}
-static void ath9k_hw_per_calibration(struct ath_hal *ah,
+static void ath9k_hw_per_calibration(struct ath_hw *ah,
struct ath9k_channel *ichan,
u8 rxchainmask,
struct hal_cal_list *currCal,
bool *isCalDone)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
*isCalDone = false;
if (currCal->calState == CAL_RUNNING) {
@@ -263,9 +251,9 @@ static void ath9k_hw_per_calibration(struct ath_hal *ah,
AR_PHY_TIMING_CTRL4_DO_CAL)) {
currCal->calData->calCollect(ah);
- ahp->ah_CalSamples++;
+ ah->cal_samples++;
- if (ahp->ah_CalSamples >= currCal->calData->calNumSamples) {
+ if (ah->cal_samples >= currCal->calData->calNumSamples) {
int i, numChains = 0;
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
if (rxchainmask & (1 << i))
@@ -285,113 +273,105 @@ static void ath9k_hw_per_calibration(struct ath_hal *ah,
}
}
-static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
- struct ath9k_channel *chan,
+/* Assumes you are talking about the currently configured channel */
+static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
enum hal_cal_types calType)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- bool retval = false;
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
- switch (calType & ahp->ah_suppCals) {
- case IQ_MISMATCH_CAL:
- if (!IS_CHAN_B(chan))
- retval = true;
- break;
+ switch (calType & ah->supp_cals) {
+ case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
+ return true;
case ADC_GAIN_CAL:
case ADC_DC_CAL:
- if (!IS_CHAN_B(chan)
- && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
- retval = true;
+ if (conf->channel->band == IEEE80211_BAND_5GHZ &&
+ conf_is_ht20(conf))
+ return true;
break;
}
-
- return retval;
+ return false;
}
-static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
+static void ath9k_hw_iqcal_collect(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- ahp->ah_totalPowerMeasI[i] +=
+ ah->totalPowerMeasI[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
- ahp->ah_totalPowerMeasQ[i] +=
+ ah->totalPowerMeasQ[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
- ahp->ah_totalIqCorrMeas[i] +=
+ ah->totalIqCorrMeas[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
- ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
- ahp->ah_totalPowerMeasQ[i],
- ahp->ah_totalIqCorrMeas[i]);
+ ah->cal_samples, i, ah->totalPowerMeasI[i],
+ ah->totalPowerMeasQ[i],
+ ah->totalIqCorrMeas[i]);
}
}
-static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
+static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- ahp->ah_totalAdcIOddPhase[i] +=
+ ah->totalAdcIOddPhase[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
- ahp->ah_totalAdcIEvenPhase[i] +=
+ ah->totalAdcIEvenPhase[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
- ahp->ah_totalAdcQOddPhase[i] +=
+ ah->totalAdcQOddPhase[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
- ahp->ah_totalAdcQEvenPhase[i] +=
+ ah->totalAdcQEvenPhase[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
"oddq=0x%08x; evenq=0x%08x;\n",
- ahp->ah_CalSamples, i,
- ahp->ah_totalAdcIOddPhase[i],
- ahp->ah_totalAdcIEvenPhase[i],
- ahp->ah_totalAdcQOddPhase[i],
- ahp->ah_totalAdcQEvenPhase[i]);
+ ah->cal_samples, i,
+ ah->totalAdcIOddPhase[i],
+ ah->totalAdcIEvenPhase[i],
+ ah->totalAdcQOddPhase[i],
+ ah->totalAdcQEvenPhase[i]);
}
}
-static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
+static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int i;
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
+ ah->totalAdcDcOffsetIOddPhase[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
- ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
+ ah->totalAdcDcOffsetIEvenPhase[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
- ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
+ ah->totalAdcDcOffsetQOddPhase[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
- ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
+ ah->totalAdcDcOffsetQEvenPhase[i] +=
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
"oddq=0x%08x; evenq=0x%08x;\n",
- ahp->ah_CalSamples, i,
- ahp->ah_totalAdcDcOffsetIOddPhase[i],
- ahp->ah_totalAdcDcOffsetIEvenPhase[i],
- ahp->ah_totalAdcDcOffsetQOddPhase[i],
- ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
+ ah->cal_samples, i,
+ ah->totalAdcDcOffsetIOddPhase[i],
+ ah->totalAdcDcOffsetIEvenPhase[i],
+ ah->totalAdcDcOffsetQOddPhase[i],
+ ah->totalAdcDcOffsetQEvenPhase[i]);
}
}
-static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
+static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 powerMeasQ, powerMeasI, iqCorrMeas;
u32 qCoffDenom, iCoffDenom;
int32_t qCoff, iCoff;
int iqCorrNeg, i;
for (i = 0; i < numChains; i++) {
- powerMeasI = ahp->ah_totalPowerMeasI[i];
- powerMeasQ = ahp->ah_totalPowerMeasQ[i];
- iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
+ powerMeasI = ah->totalPowerMeasI[i];
+ powerMeasQ = ah->totalPowerMeasQ[i];
+ iqCorrMeas = ah->totalIqCorrMeas[i];
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"Starting IQ Cal and Correction for Chain %d\n",
@@ -399,7 +379,7 @@ static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"Orignal: Chn %diq_corr_meas = 0x%08x\n",
- i, ahp->ah_totalIqCorrMeas[i]);
+ i, ah->totalIqCorrMeas[i]);
iqCorrNeg = 0;
@@ -457,17 +437,16 @@ static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
}
-static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
+static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
u32 qGainMismatch, iGainMismatch, val, i;
for (i = 0; i < numChains; i++) {
- iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
- iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
- qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
- qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
+ iOddMeasOffset = ah->totalAdcIOddPhase[i];
+ iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
+ qOddMeasOffset = ah->totalAdcQOddPhase[i];
+ qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"Starting ADC Gain Cal for Chain %d\n", i);
@@ -515,21 +494,20 @@ static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
}
-static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
+static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 iOddMeasOffset, iEvenMeasOffset, val, i;
int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
const struct hal_percal_data *calData =
- ahp->ah_cal_list_curr->calData;
+ ah->cal_list_curr->calData;
u32 numSamples =
(1 << (calData->calCountMax + 5)) * calData->calNumSamples;
for (i = 0; i < numChains; i++) {
- iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
- iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
- qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
- qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
+ iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
+ iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
+ qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
+ qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"Starting ADC DC Offset Cal for Chain %d\n", i);
@@ -573,53 +551,42 @@ static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
}
-void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
- bool *isCalDone)
+/* This is done for the currently configured channel */
+bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_channel *ichan =
- ath9k_regd_check_channel(ah, chan);
- struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+ struct hal_cal_list *currCal = ah->cal_list_curr;
- *isCalDone = true;
+ if (!ah->curchan)
+ return true;
if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
- return;
+ return true;
if (currCal == NULL)
- return;
-
- if (ichan == NULL) {
- DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "invalid channel %u/0x%x; no mapping\n",
- chan->channel, chan->channelFlags);
- return;
- }
-
+ return true;
if (currCal->calState != CAL_DONE) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"Calibration state incorrect, %d\n",
currCal->calState);
- return;
+ return true;
}
-
- if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
- return;
+ if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType))
+ return true;
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "Resetting Cal %d state for channel %u/0x%x\n",
- currCal->calData->calType, chan->channel,
- chan->channelFlags);
+ "Resetting Cal %d state for channel %u\n",
+ currCal->calData->calType, conf->channel->center_freq);
- ichan->CalValid &= ~currCal->calData->calType;
+ ah->curchan->CalValid &= ~currCal->calData->calType;
currCal->calState = CAL_WAITING;
- *isCalDone = false;
+ return false;
}
-void ath9k_hw_start_nfcal(struct ath_hal *ah)
+void ath9k_hw_start_nfcal(struct ath_hw *ah)
{
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_ENABLE_NF);
@@ -628,7 +595,7 @@ void ath9k_hw_start_nfcal(struct ath_hal *ah)
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
}
-void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
{
struct ath9k_nfcal_hist *h;
int i, j;
@@ -643,16 +610,14 @@ void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
};
u8 chainmask;
- if (AR_SREV_9280(ah))
+ if (AR_SREV_9285(ah))
+ chainmask = 0x9;
+ else if (AR_SREV_9280(ah))
chainmask = 0x1B;
else
chainmask = 0x3F;
-#ifdef ATH_NF_PER_CHAN
- h = chan->nfCalHist;
-#else
h = ah->nfCalHist;
-#endif
for (i = 0; i < NUM_NF_READINGS; i++) {
if (chainmask & (1 << i)) {
@@ -686,18 +651,13 @@ void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
}
}
-int16_t ath9k_hw_getnf(struct ath_hal *ah,
+int16_t ath9k_hw_getnf(struct ath_hw *ah,
struct ath9k_channel *chan)
{
int16_t nf, nfThresh;
int16_t nfarray[NUM_NF_READINGS] = { 0 };
struct ath9k_nfcal_hist *h;
- u8 chainmask;
-
- if (AR_SREV_9280(ah))
- chainmask = 0x1B;
- else
- chainmask = 0x3F;
+ struct ieee80211_channel *c = chan->chan;
chan->channelFlags &= (~CHANNEL_CW_INT);
if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
@@ -709,7 +669,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah,
} else {
ath9k_hw_do_getnf(ah, nfarray);
nf = nfarray[0];
- if (getNoiseFloorThresh(ah, chan, &nfThresh)
+ if (getNoiseFloorThresh(ah, c->band, &nfThresh)
&& nf > nfThresh) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"noise floor failed detected; "
@@ -719,11 +679,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah,
}
}
-#ifdef ATH_NF_PER_CHAN
- h = chan->nfCalHist;
-#else
h = ah->nfCalHist;
-#endif
ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
chan->rawNoiseFloor = h[0].privNF;
@@ -731,7 +687,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah,
return chan->rawNoiseFloor;
}
-void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
{
int i, j;
@@ -745,26 +701,16 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
AR_PHY_CCA_MAX_GOOD_VALUE;
}
}
- return;
}
-s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
{
- struct ath9k_channel *ichan;
s16 nf;
- ichan = ath9k_regd_check_channel(ah, chan);
- if (ichan == NULL) {
- DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "invalid channel %u/0x%x; no mapping\n",
- chan->channel, chan->channelFlags);
- return ATH_DEFAULT_NOISE_FLOOR;
- }
- if (ichan->rawNoiseFloor == 0) {
- enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
- nf = NOISE_FLOOR[mode];
- } else
- nf = ichan->rawNoiseFloor;
+ if (chan->rawNoiseFloor == 0)
+ nf = -96;
+ else
+ nf = chan->rawNoiseFloor;
if (!ath9k_hw_nf_in_range(ah, nf))
nf = ATH_DEFAULT_NOISE_FLOOR;
@@ -772,53 +718,34 @@ s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
return nf;
}
-bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
- u8 rxchainmask, bool longcal,
- bool *isCalDone)
+static void ath9k_olc_temp_compensation(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
- struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
+ u32 rddata, i;
+ int delta, currPDADC, regval;
- *isCalDone = true;
+ rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
- if (ichan == NULL) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "invalid channel %u/0x%x; no mapping\n",
- chan->channel, chan->channelFlags);
- return false;
- }
+ currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
- if (currCal &&
- (currCal->calState == CAL_RUNNING ||
- currCal->calState == CAL_WAITING)) {
- ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
- isCalDone);
- if (*isCalDone) {
- ahp->ah_cal_list_curr = currCal = currCal->calNext;
-
- if (currCal->calState == CAL_WAITING) {
- *isCalDone = false;
- ath9k_hw_reset_calibration(ah, currCal);
- }
- }
- }
+ if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
+ delta = (currPDADC - ah->initPDADC + 4) / 8;
+ else
+ delta = (currPDADC - ah->initPDADC + 5) / 10;
- if (longcal) {
- ath9k_hw_getnf(ah, ichan);
- ath9k_hw_loadnf(ah, ah->ah_curchan);
- ath9k_hw_start_nfcal(ah);
+ if (delta != ah->PDADCdelta) {
+ ah->PDADCdelta = delta;
+ for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
+ regval = ah->originalGain[i] - delta;
+ if (regval < 0)
+ regval = 0;
- if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
- chan->channelFlags |= CHANNEL_CW_INT;
- ichan->channelFlags &= ~CHANNEL_CW_INT;
+ REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4,
+ AR_PHY_TX_GAIN, regval);
}
}
-
- return true;
}
-static inline void ath9k_hw_9285_pa_cal(struct ath_hal *ah)
+static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
{
u32 regVal;
@@ -913,59 +840,171 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hal *ah)
}
-bool ath9k_hw_init_cal(struct ath_hal *ah,
+bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
+ u8 rxchainmask, bool longcal,
+ bool *isCalDone)
+{
+ struct hal_cal_list *currCal = ah->cal_list_curr;
+
+ *isCalDone = true;
+
+ if (currCal &&
+ (currCal->calState == CAL_RUNNING ||
+ currCal->calState == CAL_WAITING)) {
+ ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
+ isCalDone);
+ if (*isCalDone) {
+ ah->cal_list_curr = currCal = currCal->calNext;
+
+ if (currCal->calState == CAL_WAITING) {
+ *isCalDone = false;
+ ath9k_hw_reset_calibration(ah, currCal);
+ }
+ }
+ }
+
+ if (longcal) {
+ if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
+ ath9k_hw_9285_pa_cal(ah);
+
+ if (OLC_FOR_AR9280_20_LATER)
+ ath9k_olc_temp_compensation(ah);
+ ath9k_hw_getnf(ah, chan);
+ ath9k_hw_loadnf(ah, ah->curchan);
+ ath9k_hw_start_nfcal(ah);
+
+ if (chan->channelFlags & CHANNEL_CW_INT)
+ chan->channelFlags &= ~CHANNEL_CW_INT;
+ }
+
+ return true;
+}
+
+static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+ REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+ if (chan->channelFlags & CHANNEL_HT20) {
+ REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+ REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+ REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+ AR_PHY_AGC_CONTROL_FLTR_CAL);
+ REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
+ if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+ AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset "
+ "calibration failed to complete in "
+ "1ms; noisy ??\n");
+ return false;
+ }
+ REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+ REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+ REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+ }
+ REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
+ if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+ 0, AH_WAIT_TIMEOUT)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset calibration "
+ "failed to complete in 1ms; noisy ??\n");
+ return false;
+ }
+
+ REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+ REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+
+ return true;
+}
+
+bool ath9k_hw_init_cal(struct ath_hw *ah,
struct ath9k_channel *chan)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
+ if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
+ if (!ar9285_clc(ah, chan))
+ return false;
+ } else if (AR_SREV_9280_10_OR_LATER(ah)) {
+ REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+
+ /* Kick off the cal */
+ REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+ REG_READ(ah, AR_PHY_AGC_CONTROL) |
+ AR_PHY_AGC_CONTROL_CAL);
+
+ if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+ AR_PHY_AGC_CONTROL_CAL, 0,
+ AH_WAIT_TIMEOUT)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+ "offset calibration failed to complete in 1ms; "
+ "noisy environment?\n");
+ return false;
+ }
+
+ REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+ }
+ /* Calibrate the AGC */
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
- REG_READ(ah, AR_PHY_AGC_CONTROL) |
- AR_PHY_AGC_CONTROL_CAL);
+ REG_READ(ah, AR_PHY_AGC_CONTROL) |
+ AR_PHY_AGC_CONTROL_CAL);
- if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
+ if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+ 0, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"offset calibration failed to complete in 1ms; "
"noisy environment?\n");
return false;
}
+ if (AR_SREV_9280_10_OR_LATER(ah)) {
+ REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+ REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+ }
+
+ /* Do PA Calibration */
if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
ath9k_hw_9285_pa_cal(ah);
+ /* Do NF Calibration */
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
- REG_READ(ah, AR_PHY_AGC_CONTROL) |
- AR_PHY_AGC_CONTROL_NF);
+ REG_READ(ah, AR_PHY_AGC_CONTROL) |
+ AR_PHY_AGC_CONTROL_NF);
- ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
+ ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
- if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
- INIT_CAL(&ahp->ah_adcGainCalData);
- INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
+ if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
+ INIT_CAL(&ah->adcgain_caldata);
+ INSERT_CAL(ah, &ah->adcgain_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "enabling ADC Gain Calibration.\n");
+ "enabling ADC Gain Calibration.\n");
}
- if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
- INIT_CAL(&ahp->ah_adcDcCalData);
- INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
+ if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
+ INIT_CAL(&ah->adcdc_caldata);
+ INSERT_CAL(ah, &ah->adcdc_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "enabling ADC DC Calibration.\n");
+ "enabling ADC DC Calibration.\n");
}
- if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
- INIT_CAL(&ahp->ah_iqCalData);
- INSERT_CAL(ahp, &ahp->ah_iqCalData);
+ if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
+ INIT_CAL(&ah->iq_caldata);
+ INSERT_CAL(ah, &ah->iq_caldata);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
- "enabling IQ Calibration.\n");
+ "enabling IQ Calibration.\n");
}
- ahp->ah_cal_list_curr = ahp->ah_cal_list;
+ ah->cal_list_curr = ah->cal_list;
- if (ahp->ah_cal_list_curr)
- ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr);
+ if (ah->cal_list_curr)
+ ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
}
- ichan->CalValid = 0;
+ chan->CalValid = 0;
return true;
}
diff --git a/drivers/net/wireless/ath9k/calib.h b/drivers/net/wireless/ath9k/calib.h
new file mode 100644
index 000000000000..1c74bd50700d
--- /dev/null
+++ b/drivers/net/wireless/ath9k/calib.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef CALIB_H
+#define CALIB_H
+
+extern const struct hal_percal_data iq_cal_multi_sample;
+extern const struct hal_percal_data iq_cal_single_sample;
+extern const struct hal_percal_data adc_gain_cal_multi_sample;
+extern const struct hal_percal_data adc_gain_cal_single_sample;
+extern const struct hal_percal_data adc_dc_cal_multi_sample;
+extern const struct hal_percal_data adc_dc_cal_single_sample;
+extern const struct hal_percal_data adc_init_dc_cal;
+
+#define AR_PHY_CCA_MAX_GOOD_VALUE -85
+#define AR_PHY_CCA_MAX_HIGH_VALUE -62
+#define AR_PHY_CCA_MIN_BAD_VALUE -140
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH 5
+
+#define NUM_NF_READINGS 6
+#define ATH9K_NF_CAL_HIST_MAX 5
+
+struct ar5416IniArray {
+ u32 *ia_array;
+ u32 ia_rows;
+ u32 ia_columns;
+};
+
+#define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \
+ (iniarray)->ia_array = (u32 *)(array); \
+ (iniarray)->ia_rows = (rows); \
+ (iniarray)->ia_columns = (columns); \
+ } while (0)
+
+#define INI_RA(iniarray, row, column) \
+ (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)])
+
+#define INIT_CAL(_perCal) do { \
+ (_perCal)->calState = CAL_WAITING; \
+ (_perCal)->calNext = NULL; \
+ } while (0)
+
+#define INSERT_CAL(_ahp, _perCal) \
+ do { \
+ if ((_ahp)->cal_list_last == NULL) { \
+ (_ahp)->cal_list = \
+ (_ahp)->cal_list_last = (_perCal); \
+ ((_ahp)->cal_list_last)->calNext = (_perCal); \
+ } else { \
+ ((_ahp)->cal_list_last)->calNext = (_perCal); \
+ (_ahp)->cal_list_last = (_perCal); \
+ (_perCal)->calNext = (_ahp)->cal_list; \
+ } \
+ } while (0)
+
+enum hal_cal_types {
+ ADC_DC_INIT_CAL = 0x1,
+ ADC_GAIN_CAL = 0x2,
+ ADC_DC_CAL = 0x4,
+ IQ_MISMATCH_CAL = 0x8
+};
+
+enum hal_cal_state {
+ CAL_INACTIVE,
+ CAL_WAITING,
+ CAL_RUNNING,
+ CAL_DONE
+};
+
+#define MIN_CAL_SAMPLES 1
+#define MAX_CAL_SAMPLES 64
+#define INIT_LOG_COUNT 5
+#define PER_MIN_LOG_COUNT 2
+#define PER_MAX_LOG_COUNT 10
+
+struct hal_percal_data {
+ enum hal_cal_types calType;
+ u32 calNumSamples;
+ u32 calCountMax;
+ void (*calCollect) (struct ath_hw *);
+ void (*calPostProc) (struct ath_hw *, u8);
+};
+
+struct hal_cal_list {
+ const struct hal_percal_data *calData;
+ enum hal_cal_state calState;
+ struct hal_cal_list *calNext;
+};
+
+struct ath9k_nfcal_hist {
+ int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
+ u8 currIndex;
+ int16_t privNF;
+ u8 invalidNFcount;
+};
+
+bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
+void ath9k_hw_start_nfcal(struct ath_hw *ah);
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
+int16_t ath9k_hw_getnf(struct ath_hw *ah,
+ struct ath9k_channel *chan);
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
+bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
+ u8 rxchainmask, bool longcal,
+ bool *isCalDone);
+bool ath9k_hw_init_cal(struct ath_hw *ah,
+ struct ath9k_channel *chan);
+
+#endif /* CALIB_H */
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
deleted file mode 100644
index 4ca2aed236e0..000000000000
--- a/drivers/net/wireless/ath9k/core.h
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- * Copyright (c) 2008 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef CORE_H
-#define CORE_H
-
-#include <linux/etherdevice.h>
-#include <linux/pci.h>
-#include <net/mac80211.h>
-#include <linux/leds.h>
-#include <linux/rfkill.h>
-
-#include "ath9k.h"
-#include "rc.h"
-
-struct ath_node;
-
-/* Macro to expand scalars to 64-bit objects */
-
-#define ito64(x) (sizeof(x) == 8) ? \
- (((unsigned long long int)(x)) & (0xff)) : \
- (sizeof(x) == 16) ? \
- (((unsigned long long int)(x)) & 0xffff) : \
- ((sizeof(x) == 32) ? \
- (((unsigned long long int)(x)) & 0xffffffff) : \
- (unsigned long long int)(x))
-
-/* increment with wrap-around */
-#define INCR(_l, _sz) do { \
- (_l)++; \
- (_l) &= ((_sz) - 1); \
- } while (0)
-
-/* decrement with wrap-around */
-#define DECR(_l, _sz) do { \
- (_l)--; \
- (_l) &= ((_sz) - 1); \
- } while (0)
-
-#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
-
-#define ASSERT(exp) do { \
- if (unlikely(!(exp))) { \
- BUG(); \
- } \
- } while (0)
-
-#define TSF_TO_TU(_h,_l) \
- ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
-
-#define ATH_TXQ_SETUP(sc, i) ((sc)->tx.txqsetup & (1<<i))
-
-static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-enum ATH_DEBUG {
- ATH_DBG_RESET = 0x00000001,
- ATH_DBG_REG_IO = 0x00000002,
- ATH_DBG_QUEUE = 0x00000004,
- ATH_DBG_EEPROM = 0x00000008,
- ATH_DBG_CALIBRATE = 0x00000010,
- ATH_DBG_CHANNEL = 0x00000020,
- ATH_DBG_INTERRUPT = 0x00000040,
- ATH_DBG_REGULATORY = 0x00000080,
- ATH_DBG_ANI = 0x00000100,
- ATH_DBG_POWER_MGMT = 0x00000200,
- ATH_DBG_XMIT = 0x00000400,
- ATH_DBG_BEACON = 0x00001000,
- ATH_DBG_CONFIG = 0x00002000,
- ATH_DBG_KEYCACHE = 0x00004000,
- ATH_DBG_FATAL = 0x00008000,
- ATH_DBG_ANY = 0xffffffff
-};
-
-#define DBG_DEFAULT (ATH_DBG_FATAL)
-
-#ifdef CONFIG_ATH9K_DEBUG
-
-/**
- * struct ath_interrupt_stats - Contains statistics about interrupts
- * @total: Total no. of interrupts generated so far
- * @rxok: RX with no errors
- * @rxeol: RX with no more RXDESC available
- * @rxorn: RX FIFO overrun
- * @txok: TX completed at the requested rate
- * @txurn: TX FIFO underrun
- * @mib: MIB regs reaching its threshold
- * @rxphyerr: RX with phy errors
- * @rx_keycache_miss: RX with key cache misses
- * @swba: Software Beacon Alert
- * @bmiss: Beacon Miss
- * @bnr: Beacon Not Ready
- * @cst: Carrier Sense TImeout
- * @gtt: Global TX Timeout
- * @tim: RX beacon TIM occurrence
- * @cabend: RX End of CAB traffic
- * @dtimsync: DTIM sync lossage
- * @dtim: RX Beacon with DTIM
- */
-struct ath_interrupt_stats {
- u32 total;
- u32 rxok;
- u32 rxeol;
- u32 rxorn;
- u32 txok;
- u32 txeol;
- u32 txurn;
- u32 mib;
- u32 rxphyerr;
- u32 rx_keycache_miss;
- u32 swba;
- u32 bmiss;
- u32 bnr;
- u32 cst;
- u32 gtt;
- u32 tim;
- u32 cabend;
- u32 dtimsync;
- u32 dtim;
-};
-
-struct ath_stats {
- struct ath_interrupt_stats istats;
-};
-
-struct ath9k_debug {
- int debug_mask;
- struct dentry *debugfs_root;
- struct dentry *debugfs_phy;
- struct dentry *debugfs_dma;
- struct dentry *debugfs_interrupt;
- struct ath_stats stats;
-};
-
-void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
-int ath9k_init_debug(struct ath_softc *sc);
-void ath9k_exit_debug(struct ath_softc *sc);
-void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
-
-#else
-
-static inline void DPRINTF(struct ath_softc *sc, int dbg_mask,
- const char *fmt, ...)
-{
-}
-
-static inline int ath9k_init_debug(struct ath_softc *sc)
-{
- return 0;
-}
-
-static inline void ath9k_exit_debug(struct ath_softc *sc)
-{
-}
-
-static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
- enum ath9k_int status)
-{
-}
-
-#endif /* CONFIG_ATH9K_DEBUG */
-
-struct ath_config {
- u32 ath_aggr_prot;
- u16 txpowlimit;
- u16 txpowlimit_override;
- u8 cabqReadytime;
- u8 swBeaconProcess;
-};
-
-/*************************/
-/* Descriptor Management */
-/*************************/
-
-#define ATH_TXBUF_RESET(_bf) do { \
- (_bf)->bf_status = 0; \
- (_bf)->bf_lastbf = NULL; \
- (_bf)->bf_lastfrm = NULL; \
- (_bf)->bf_next = NULL; \
- memset(&((_bf)->bf_state), 0, \
- sizeof(struct ath_buf_state)); \
- } while (0)
-
-enum buffer_type {
- BUF_DATA = BIT(0),
- BUF_AGGR = BIT(1),
- BUF_AMPDU = BIT(2),
- BUF_HT = BIT(3),
- BUF_RETRY = BIT(4),
- BUF_XRETRY = BIT(5),
- BUF_SHORT_PREAMBLE = BIT(6),
- BUF_BAR = BIT(7),
- BUF_PSPOLL = BIT(8),
- BUF_AGGR_BURST = BIT(9),
- BUF_CALC_AIRTIME = BIT(10),
-};
-
-struct ath_buf_state {
- int bfs_nframes; /* # frames in aggregate */
- u16 bfs_al; /* length of aggregate */
- u16 bfs_frmlen; /* length of frame */
- int bfs_seqno; /* sequence number */
- int bfs_tidno; /* tid of this frame */
- int bfs_retries; /* current retries */
- u32 bf_type; /* BUF_* (enum buffer_type) */
- u32 bfs_keyix;
- enum ath9k_key_type bfs_keytype;
-};
-
-#define bf_nframes bf_state.bfs_nframes
-#define bf_al bf_state.bfs_al
-#define bf_frmlen bf_state.bfs_frmlen
-#define bf_retries bf_state.bfs_retries
-#define bf_seqno bf_state.bfs_seqno
-#define bf_tidno bf_state.bfs_tidno
-#define bf_rcs bf_state.bfs_rcs
-#define bf_keyix bf_state.bfs_keyix
-#define bf_keytype bf_state.bfs_keytype
-#define bf_isdata(bf) (bf->bf_state.bf_type & BUF_DATA)
-#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
-#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
-#define bf_isht(bf) (bf->bf_state.bf_type & BUF_HT)
-#define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY)
-#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
-#define bf_isshpreamble(bf) (bf->bf_state.bf_type & BUF_SHORT_PREAMBLE)
-#define bf_isbar(bf) (bf->bf_state.bf_type & BUF_BAR)
-#define bf_ispspoll(bf) (bf->bf_state.bf_type & BUF_PSPOLL)
-#define bf_isaggrburst(bf) (bf->bf_state.bf_type & BUF_AGGR_BURST)
-
-/*
- * Abstraction of a contiguous buffer to transmit/receive. There is only
- * a single hw descriptor encapsulated here.
- */
-struct ath_buf {
- struct list_head list;
- struct list_head *last;
- struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
- an aggregate) */
- struct ath_buf *bf_lastfrm; /* last buf of this frame */
- struct ath_buf *bf_next; /* next subframe in the aggregate */
- void *bf_mpdu; /* enclosing frame structure */
- struct ath_desc *bf_desc; /* virtual addr of desc */
- dma_addr_t bf_daddr; /* physical addr of desc */
- dma_addr_t bf_buf_addr; /* physical addr of data buffer */
- u32 bf_status;
- u16 bf_flags; /* tx descriptor flags */
- struct ath_buf_state bf_state; /* buffer state */
- dma_addr_t bf_dmacontext;
-};
-
-#define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0)
-
-/* hw processing complete, desc processed by hal */
-#define ATH_BUFSTATUS_DONE 0x00000001
-/* hw processing complete, desc hold for hw */
-#define ATH_BUFSTATUS_STALE 0x00000002
-/* Rx-only: OS is done with this packet and it's ok to queued it to hw */
-#define ATH_BUFSTATUS_FREE 0x00000004
-
-/* DMA state for tx/rx descriptors */
-
-struct ath_descdma {
- const char *dd_name;
- struct ath_desc *dd_desc; /* descriptors */
- dma_addr_t dd_desc_paddr; /* physical addr of dd_desc */
- u32 dd_desc_len; /* size of dd_desc */
- struct ath_buf *dd_bufptr; /* associated buffers */
- dma_addr_t dd_dmacontext;
-};
-
-int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
- struct list_head *head, const char *name,
- int nbuf, int ndesc);
-void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
- struct list_head *head);
-
-/***********/
-/* RX / TX */
-/***********/
-
-#define ATH_MAX_ANTENNA 3
-#define ATH_RXBUF 512
-#define WME_NUM_TID 16
-#define ATH_TXBUF 512
-#define ATH_TXMAXTRY 13
-#define ATH_11N_TXMAXTRY 10
-#define ATH_MGT_TXMAXTRY 4
-#define WME_BA_BMP_SIZE 64
-#define WME_MAX_BA WME_BA_BMP_SIZE
-#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
-
-#define TID_TO_WME_AC(_tid) \
- ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
- (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
- (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
- WME_AC_VO)
-
-#define WME_AC_BE 0
-#define WME_AC_BK 1
-#define WME_AC_VI 2
-#define WME_AC_VO 3
-#define WME_NUM_AC 4
-
-#define ADDBA_EXCHANGE_ATTEMPTS 10
-#define ATH_AGGR_DELIM_SZ 4
-#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
-/* number of delimiters for encryption padding */
-#define ATH_AGGR_ENCRYPTDELIM 10
-/* minimum h/w qdepth to be sustained to maximize aggregation */
-#define ATH_AGGR_MIN_QDEPTH 2
-#define ATH_AMPDU_SUBFRAME_DEFAULT 32
-#define IEEE80211_SEQ_SEQ_SHIFT 4
-#define IEEE80211_SEQ_MAX 4096
-#define IEEE80211_MIN_AMPDU_BUF 0x8
-#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
-
-/* return whether a bit at index _n in bitmap _bm is set
- * _sz is the size of the bitmap */
-#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \
- ((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
-
-/* return block-ack bitmap index given sequence and starting sequence */
-#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
-
-/* returns delimiter padding required given the packet length */
-#define ATH_AGGR_GET_NDELIM(_len) \
- (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
- (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
-
-#define BAW_WITHIN(_start, _bawsz, _seqno) \
- ((((_seqno) - (_start)) & 4095) < (_bawsz))
-
-#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
-#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
-#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
-#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
-
-enum ATH_AGGR_STATUS {
- ATH_AGGR_DONE,
- ATH_AGGR_BAW_CLOSED,
- ATH_AGGR_LIMITED,
- ATH_AGGR_SHORTPKT,
- ATH_AGGR_8K_LIMITED,
-};
-
-struct ath_txq {
- u32 axq_qnum; /* hardware q number */
- u32 *axq_link; /* link ptr in last TX desc */
- struct list_head axq_q; /* transmit queue */
- spinlock_t axq_lock;
- unsigned long axq_lockflags; /* intr state when must cli */
- u32 axq_depth; /* queue depth */
- u8 axq_aggr_depth; /* aggregates queued */
- u32 axq_totalqueued; /* total ever queued */
- bool stopped; /* Is mac80211 queue stopped ? */
- struct ath_buf *axq_linkbuf; /* virtual addr of last buffer*/
-
- /* first desc of the last descriptor that contains CTS */
- struct ath_desc *axq_lastdsWithCTS;
-
- /* final desc of the gating desc that determines whether
- lastdsWithCTS has been DMA'ed or not */
- struct ath_desc *axq_gatingds;
-
- struct list_head axq_acq;
-};
-
-#define AGGR_CLEANUP BIT(1)
-#define AGGR_ADDBA_COMPLETE BIT(2)
-#define AGGR_ADDBA_PROGRESS BIT(3)
-
-/* per TID aggregate tx state for a destination */
-struct ath_atx_tid {
- struct list_head list; /* round-robin tid entry */
- struct list_head buf_q; /* pending buffers */
- struct ath_node *an;
- struct ath_atx_ac *ac;
- struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; /* active tx frames */
- u16 seq_start;
- u16 seq_next;
- u16 baw_size;
- int tidno;
- int baw_head; /* first un-acked tx buffer */
- int baw_tail; /* next unused tx buffer slot */
- int sched;
- int paused;
- u8 state;
- int addba_exchangeattempts;
-};
-
-/* per access-category aggregate tx state for a destination */
-struct ath_atx_ac {
- int sched; /* dest-ac is scheduled */
- int qnum; /* H/W queue number associated
- with this AC */
- struct list_head list; /* round-robin txq entry */
- struct list_head tid_q; /* queue of TIDs with buffers */
-};
-
-/* per-frame tx control block */
-struct ath_tx_control {
- struct ath_txq *txq;
- int if_id;
-};
-
-/* per frame tx status block */
-struct ath_xmit_status {
- int retries; /* number of retries to successufully
- transmit this frame */
- int flags; /* status of transmit */
-#define ATH_TX_ERROR 0x01
-#define ATH_TX_XRETRY 0x02
-#define ATH_TX_BAR 0x04
-};
-
-/* All RSSI values are noise floor adjusted */
-struct ath_tx_stat {
- int rssi;
- int rssictl[ATH_MAX_ANTENNA];
- int rssiextn[ATH_MAX_ANTENNA];
- int rateieee;
- int rateKbps;
- int ratecode;
- int flags;
- u32 airtime; /* time on air per final tx rate */
-};
-
-struct aggr_rifs_param {
- int param_max_frames;
- int param_max_len;
- int param_rl;
- int param_al;
- struct ath_rc_series *param_rcs;
-};
-
-struct ath_node {
- struct ath_softc *an_sc;
- struct ath_atx_tid tid[WME_NUM_TID];
- struct ath_atx_ac ac[WME_NUM_AC];
- u16 maxampdu;
- u8 mpdudensity;
-};
-
-struct ath_tx {
- u16 seq_no;
- u32 txqsetup;
- int hwq_map[ATH9K_WME_AC_VO+1];
- spinlock_t txbuflock;
- struct list_head txbuf;
- struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
- struct ath_descdma txdma;
-};
-
-struct ath_rx {
- u8 defant;
- u8 rxotherant;
- u32 *rxlink;
- int bufsize;
- unsigned int rxfilter;
- spinlock_t rxflushlock;
- spinlock_t rxbuflock;
- struct list_head rxbuf;
- struct ath_descdma rxdma;
-};
-
-int ath_startrecv(struct ath_softc *sc);
-bool ath_stoprecv(struct ath_softc *sc);
-void ath_flushrecv(struct ath_softc *sc);
-u32 ath_calcrxfilter(struct ath_softc *sc);
-int ath_rx_init(struct ath_softc *sc, int nbufs);
-void ath_rx_cleanup(struct ath_softc *sc);
-int ath_rx_tasklet(struct ath_softc *sc, int flush);
-struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
-void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
-int ath_tx_setup(struct ath_softc *sc, int haltype);
-void ath_draintxq(struct ath_softc *sc, bool retry_tx);
-void ath_tx_draintxq(struct ath_softc *sc,
- struct ath_txq *txq, bool retry_tx);
-void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
-void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
-void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an);
-void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
-int ath_tx_init(struct ath_softc *sc, int nbufs);
-int ath_tx_cleanup(struct ath_softc *sc);
-int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
-struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
-int ath_txq_update(struct ath_softc *sc, int qnum,
- struct ath9k_tx_queue_info *q);
-int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
- struct ath_tx_control *txctl);
-void ath_tx_tasklet(struct ath_softc *sc);
-u32 ath_txq_depth(struct ath_softc *sc, int qnum);
-u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum);
-void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
-void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid);
-bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
-void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tidno);
-int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
- u16 tid, u16 *ssn);
-int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
-
-/********/
-/* VAPs */
-/********/
-
-/*
- * Define the scheme that we select MAC address for multiple
- * BSS on the same radio. The very first VAP will just use the MAC
- * address from the EEPROM. For the next 3 VAPs, we set the
- * U/L bit (bit 1) in MAC address, and use the next two bits as the
- * index of the VAP.
- */
-
-#define ATH_SET_VAP_BSSID_MASK(bssid_mask) \
- ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02))
-
-struct ath_vap {
- int av_bslot;
- enum nl80211_iftype av_opmode;
- struct ath_buf *av_bcbuf;
- struct ath_tx_control av_btxctl;
-};
-
-/*******************/
-/* Beacon Handling */
-/*******************/
-
-/*
- * Regardless of the number of beacons we stagger, (i.e. regardless of the
- * number of BSSIDs) if a given beacon does not go out even after waiting this
- * number of beacon intervals, the game's up.
- */
-#define BSTUCK_THRESH (9 * ATH_BCBUF)
-#define ATH_BCBUF 1
-#define ATH_DEFAULT_BINTVAL 100 /* TU */
-#define ATH_DEFAULT_BMISS_LIMIT 10
-#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
-
-struct ath_beacon_config {
- u16 beacon_interval;
- u16 listen_interval;
- u16 dtim_period;
- u16 bmiss_timeout;
- u8 dtim_count;
- u8 tim_offset;
- union {
- u64 last_tsf;
- u8 last_tstamp[8];
- } u; /* last received beacon/probe response timestamp of this BSS. */
-};
-
-struct ath_beacon {
- enum {
- OK, /* no change needed */
- UPDATE, /* update pending */
- COMMIT /* beacon sent, commit change */
- } updateslot; /* slot time update fsm */
-
- u32 beaconq;
- u32 bmisscnt;
- u32 ast_be_xmit;
- u64 bc_tstamp;
- int bslot[ATH_BCBUF];
- int slottime;
- int slotupdate;
- struct ath9k_tx_queue_info beacon_qi;
- struct ath_descdma bdma;
- struct ath_txq *cabq;
- struct list_head bbuf;
-};
-
-void ath9k_beacon_tasklet(unsigned long data);
-void ath_beacon_config(struct ath_softc *sc, int if_id);
-int ath_beaconq_setup(struct ath_hal *ah);
-int ath_beacon_alloc(struct ath_softc *sc, int if_id);
-void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp);
-void ath_beacon_sync(struct ath_softc *sc, int if_id);
-
-/*******/
-/* ANI */
-/*******/
-
-/* ANI values for STA only.
- FIXME: Add appropriate values for AP later */
-
-#define ATH_ANI_POLLINTERVAL 100 /* 100 milliseconds between ANI poll */
-#define ATH_SHORT_CALINTERVAL 1000 /* 1 second between calibrations */
-#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds between calibrations */
-#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes between calibrations */
-
-struct ath_ani {
- bool sc_caldone;
- int16_t sc_noise_floor;
- unsigned int sc_longcal_timer;
- unsigned int sc_shortcal_timer;
- unsigned int sc_resetcal_timer;
- unsigned int sc_checkani_timer;
- struct timer_list timer;
-};
-
-/********************/
-/* LED Control */
-/********************/
-
-#define ATH_LED_PIN 1
-
-enum ath_led_type {
- ATH_LED_RADIO,
- ATH_LED_ASSOC,
- ATH_LED_TX,
- ATH_LED_RX
-};
-
-struct ath_led {
- struct ath_softc *sc;
- struct led_classdev led_cdev;
- enum ath_led_type led_type;
- char name[32];
- bool registered;
-};
-
-/* Rfkill */
-#define ATH_RFKILL_POLL_INTERVAL 2000 /* msecs */
-
-struct ath_rfkill {
- struct rfkill *rfkill;
- struct delayed_work rfkill_poll;
- char rfkill_name[32];
-};
-
-/********************/
-/* Main driver core */
-/********************/
-
-/*
- * Default cache line size, in bytes.
- * Used when PCI device not fully initialized by bootrom/BIOS
-*/
-#define DEFAULT_CACHELINE 32
-#define ATH_DEFAULT_NOISE_FLOOR -95
-#define ATH_REGCLASSIDS_MAX 10
-#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
-#define ATH_MAX_SW_RETRIES 10
-#define ATH_CHAN_MAX 255
-#define IEEE80211_WEP_NKID 4 /* number of key ids */
-#define IEEE80211_RATE_VAL 0x7f
-/*
- * The key cache is used for h/w cipher state and also for
- * tracking station state such as the current tx antenna.
- * We also setup a mapping table between key cache slot indices
- * and station state to short-circuit node lookups on rx.
- * Different parts have different size key caches. We handle
- * up to ATH_KEYMAX entries (could dynamically allocate state).
- */
-#define ATH_KEYMAX 128 /* max key cache size we handle */
-
-#define ATH_IF_ID_ANY 0xff
-#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
-#define ATH_RSSI_DUMMY_MARKER 0x127
-#define ATH_RATE_DUMMY_MARKER 0
-
-enum PROT_MODE {
- PROT_M_NONE = 0,
- PROT_M_RTSCTS,
- PROT_M_CTSONLY
-};
-
-#define SC_OP_INVALID BIT(0)
-#define SC_OP_BEACONS BIT(1)
-#define SC_OP_RXAGGR BIT(2)
-#define SC_OP_TXAGGR BIT(3)
-#define SC_OP_CHAINMASK_UPDATE BIT(4)
-#define SC_OP_FULL_RESET BIT(5)
-#define SC_OP_NO_RESET BIT(6)
-#define SC_OP_PREAMBLE_SHORT BIT(7)
-#define SC_OP_PROTECT_ENABLE BIT(8)
-#define SC_OP_RXFLUSH BIT(9)
-#define SC_OP_LED_ASSOCIATED BIT(10)
-#define SC_OP_RFKILL_REGISTERED BIT(11)
-#define SC_OP_RFKILL_SW_BLOCKED BIT(12)
-#define SC_OP_RFKILL_HW_BLOCKED BIT(13)
-
-struct ath_softc {
- struct ieee80211_hw *hw;
- struct pci_dev *pdev;
- struct tasklet_struct intr_tq;
- struct tasklet_struct bcon_tasklet;
- struct ath_hal *sc_ah;
- void __iomem *mem;
- spinlock_t sc_resetlock;
- struct mutex mutex;
-
- u8 sc_curbssid[ETH_ALEN];
- u8 sc_myaddr[ETH_ALEN];
- u8 sc_bssidmask[ETH_ALEN];
- u32 sc_intrstatus;
- u32 sc_flags; /* SC_OP_* */
- u16 sc_curtxpow;
- u16 sc_curaid;
- u16 sc_cachelsz;
- u8 sc_nbcnvaps;
- u16 sc_nvaps;
- u8 sc_tx_chainmask;
- u8 sc_rx_chainmask;
- u32 sc_keymax;
- DECLARE_BITMAP(sc_keymap, ATH_KEYMAX);
- u8 sc_splitmic;
- u8 sc_protrix;
- enum ath9k_int sc_imask;
- enum PROT_MODE sc_protmode;
- enum ath9k_ht_extprotspacing sc_ht_extprotspacing;
- enum ath9k_ht_macmode tx_chan_width;
-
- struct ath_config sc_config;
- struct ath_rx rx;
- struct ath_tx tx;
- struct ath_beacon beacon;
- struct ieee80211_vif *sc_vaps[ATH_BCBUF];
- struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
- struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
- struct ath_rate_table *cur_rate_table;
- struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX];
- struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
- struct ath_led radio_led;
- struct ath_led assoc_led;
- struct ath_led tx_led;
- struct ath_led rx_led;
- struct ath_rfkill rf_kill;
- struct ath_ani sc_ani;
- struct ath9k_node_stats sc_halstats;
-#ifdef CONFIG_ATH9K_DEBUG
- struct ath9k_debug sc_debug;
-#endif
-};
-
-int ath_reset(struct ath_softc *sc, bool retry_tx);
-int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
-int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
-int ath_cabq_update(struct ath_softc *);
-
-#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath9k/debug.c
index a80ed576830f..fdf9528fa49b 100644
--- a/drivers/net/wireless/ath9k/debug.c
+++ b/drivers/net/wireless/ath9k/debug.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,19 +14,21 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
-#include "reg.h"
-#include "hw.h"
+#include <asm/unaligned.h>
+
+#include "ath9k.h"
static unsigned int ath9k_debug = DBG_DEFAULT;
module_param_named(debug, ath9k_debug, uint, 0);
+static struct dentry *ath9k_debugfs_root;
+
void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...)
{
if (!sc)
return;
- if (sc->sc_debug.debug_mask & dbg_mask) {
+ if (sc->debug.debug_mask & dbg_mask) {
va_list args;
va_start(args, fmt);
@@ -46,7 +48,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
char buf[1024];
unsigned int len = 0;
u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
@@ -132,41 +134,41 @@ static const struct file_operations fops_dma = {
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
{
if (status)
- sc->sc_debug.stats.istats.total++;
+ sc->debug.stats.istats.total++;
if (status & ATH9K_INT_RX)
- sc->sc_debug.stats.istats.rxok++;
+ sc->debug.stats.istats.rxok++;
if (status & ATH9K_INT_RXEOL)
- sc->sc_debug.stats.istats.rxeol++;
+ sc->debug.stats.istats.rxeol++;
if (status & ATH9K_INT_RXORN)
- sc->sc_debug.stats.istats.rxorn++;
+ sc->debug.stats.istats.rxorn++;
if (status & ATH9K_INT_TX)
- sc->sc_debug.stats.istats.txok++;
+ sc->debug.stats.istats.txok++;
if (status & ATH9K_INT_TXURN)
- sc->sc_debug.stats.istats.txurn++;
+ sc->debug.stats.istats.txurn++;
if (status & ATH9K_INT_MIB)
- sc->sc_debug.stats.istats.mib++;
+ sc->debug.stats.istats.mib++;
if (status & ATH9K_INT_RXPHY)
- sc->sc_debug.stats.istats.rxphyerr++;
+ sc->debug.stats.istats.rxphyerr++;
if (status & ATH9K_INT_RXKCM)
- sc->sc_debug.stats.istats.rx_keycache_miss++;
+ sc->debug.stats.istats.rx_keycache_miss++;
if (status & ATH9K_INT_SWBA)
- sc->sc_debug.stats.istats.swba++;
+ sc->debug.stats.istats.swba++;
if (status & ATH9K_INT_BMISS)
- sc->sc_debug.stats.istats.bmiss++;
+ sc->debug.stats.istats.bmiss++;
if (status & ATH9K_INT_BNR)
- sc->sc_debug.stats.istats.bnr++;
+ sc->debug.stats.istats.bnr++;
if (status & ATH9K_INT_CST)
- sc->sc_debug.stats.istats.cst++;
+ sc->debug.stats.istats.cst++;
if (status & ATH9K_INT_GTT)
- sc->sc_debug.stats.istats.gtt++;
+ sc->debug.stats.istats.gtt++;
if (status & ATH9K_INT_TIM)
- sc->sc_debug.stats.istats.tim++;
+ sc->debug.stats.istats.tim++;
if (status & ATH9K_INT_CABEND)
- sc->sc_debug.stats.istats.cabend++;
+ sc->debug.stats.istats.cabend++;
if (status & ATH9K_INT_DTIMSYNC)
- sc->sc_debug.stats.istats.dtimsync++;
+ sc->debug.stats.istats.dtimsync++;
if (status & ATH9K_INT_DTIM)
- sc->sc_debug.stats.istats.dtim++;
+ sc->debug.stats.istats.dtim++;
}
static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
@@ -177,41 +179,41 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
unsigned int len = 0;
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "RX", sc->sc_debug.stats.istats.rxok);
+ "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "RXEOL", sc->sc_debug.stats.istats.rxeol);
+ "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "RXORN", sc->sc_debug.stats.istats.rxorn);
+ "%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "TX", sc->sc_debug.stats.istats.txok);
+ "%8s: %10u\n", "TX", sc->debug.stats.istats.txok);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "TXURN", sc->sc_debug.stats.istats.txurn);
+ "%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "MIB", sc->sc_debug.stats.istats.mib);
+ "%8s: %10u\n", "MIB", sc->debug.stats.istats.mib);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "RXPHY", sc->sc_debug.stats.istats.rxphyerr);
+ "%8s: %10u\n", "RXPHY", sc->debug.stats.istats.rxphyerr);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "RXKCM", sc->sc_debug.stats.istats.rx_keycache_miss);
+ "%8s: %10u\n", "RXKCM", sc->debug.stats.istats.rx_keycache_miss);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "SWBA", sc->sc_debug.stats.istats.swba);
+ "%8s: %10u\n", "SWBA", sc->debug.stats.istats.swba);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "BMISS", sc->sc_debug.stats.istats.bmiss);
+ "%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "BNR", sc->sc_debug.stats.istats.bnr);
+ "%8s: %10u\n", "BNR", sc->debug.stats.istats.bnr);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "CST", sc->sc_debug.stats.istats.cst);
+ "%8s: %10u\n", "CST", sc->debug.stats.istats.cst);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "GTT", sc->sc_debug.stats.istats.gtt);
+ "%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "TIM", sc->sc_debug.stats.istats.tim);
+ "%8s: %10u\n", "TIM", sc->debug.stats.istats.tim);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "CABEND", sc->sc_debug.stats.istats.cabend);
+ "%8s: %10u\n", "CABEND", sc->debug.stats.istats.cabend);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "DTIMSYNC", sc->sc_debug.stats.istats.dtimsync);
+ "%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "DTIM", sc->sc_debug.stats.istats.dtim);
+ "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
len += snprintf(buf + len, sizeof(buf) - len,
- "%8s: %10u\n", "TOTAL", sc->sc_debug.stats.istats.total);
+ "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
@@ -222,29 +224,308 @@ static const struct file_operations fops_interrupt = {
.owner = THIS_MODULE
};
-int ath9k_init_debug(struct ath_softc *sc)
+static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb)
{
- sc->sc_debug.debug_mask = ath9k_debug;
+ struct ath_tx_info_priv *tx_info_priv = NULL;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_rate *rates = tx_info->status.rates;
+ int final_ts_idx, idx;
- sc->sc_debug.debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
- if (!sc->sc_debug.debugfs_root)
- goto err;
+ tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+ final_ts_idx = tx_info_priv->tx.ts_rateindex;
+ idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate;
+
+ sc->debug.stats.n_rcstats[idx].success++;
+}
+
+static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb)
+{
+ struct ath_tx_info_priv *tx_info_priv = NULL;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_rate *rates = tx_info->status.rates;
+ int final_ts_idx, idx;
+
+ tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+ final_ts_idx = tx_info_priv->tx.ts_rateindex;
+ idx = rates[final_ts_idx].idx;
+
+ sc->debug.stats.legacy_rcstats[idx].success++;
+}
+
+void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
+{
+ if (conf_is_ht(&sc->hw->conf))
+ ath_debug_stat_11n_rc(sc, skb);
+ else
+ ath_debug_stat_legacy_rc(sc, skb);
+}
+
+/* FIXME: legacy rates, later on .. */
+void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+ int xretries, int retries, u8 per)
+{
+ if (conf_is_ht(&sc->hw->conf)) {
+ int idx = sc->cur_rate_table->info[rix].dot11rate;
+
+ sc->debug.stats.n_rcstats[idx].xretries += xretries;
+ sc->debug.stats.n_rcstats[idx].retries += retries;
+ sc->debug.stats.n_rcstats[idx].per = per;
+ }
+}
+
+static ssize_t ath_read_file_stat_11n_rc(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ char buf[1024];
+ unsigned int len = 0;
+ int i = 0;
+
+ len += sprintf(buf, "%7s %13s %8s %8s %6s\n\n", "Rate", "Success",
+ "Retries", "XRetries", "PER");
+
+ for (i = 0; i <= 15; i++) {
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "%5s%3d: %8u %8u %8u %8u\n", "MCS", i,
+ sc->debug.stats.n_rcstats[i].success,
+ sc->debug.stats.n_rcstats[i].retries,
+ sc->debug.stats.n_rcstats[i].xretries,
+ sc->debug.stats.n_rcstats[i].per);
+ }
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath_read_file_stat_legacy_rc(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ char buf[512];
+ unsigned int len = 0;
+ int i = 0;
+
+ len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success");
- sc->sc_debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
- sc->sc_debug.debugfs_root);
- if (!sc->sc_debug.debugfs_phy)
+ for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
+ len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n",
+ sc->cur_rate_table->info[i].ratekbps / 1000,
+ sc->debug.stats.legacy_rcstats[i].success);
+ }
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+
+ if (sc->cur_rate_table == NULL)
+ return 0;
+
+ if (conf_is_ht(&sc->hw->conf))
+ return ath_read_file_stat_11n_rc(file, user_buf, count, ppos);
+ else
+ return ath_read_file_stat_legacy_rc(file, user_buf, count ,ppos);
+}
+
+static const struct file_operations fops_rcstat = {
+ .read = read_file_rcstat,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE
+};
+
+static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
+{
+ switch (state) {
+ case ATH_WIPHY_INACTIVE:
+ return "INACTIVE";
+ case ATH_WIPHY_ACTIVE:
+ return "ACTIVE";
+ case ATH_WIPHY_PAUSING:
+ return "PAUSING";
+ case ATH_WIPHY_PAUSED:
+ return "PAUSED";
+ case ATH_WIPHY_SCAN:
+ return "SCAN";
+ }
+ return "?";
+}
+
+static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ char buf[512];
+ unsigned int len = 0;
+ int i;
+ u8 addr[ETH_ALEN];
+
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "primary: %s (%s chan=%d ht=%d)\n",
+ wiphy_name(sc->pri_wiphy->hw->wiphy),
+ ath_wiphy_state_str(sc->pri_wiphy->state),
+ sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ struct ath_wiphy *aphy = sc->sec_wiphy[i];
+ if (aphy == NULL)
+ continue;
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "secondary: %s (%s chan=%d ht=%d)\n",
+ wiphy_name(aphy->hw->wiphy),
+ ath_wiphy_state_str(aphy->state),
+ aphy->chan_idx, aphy->chan_is_ht);
+ }
+
+ put_unaligned_le32(REG_READ(sc->sc_ah, AR_STA_ID0), addr);
+ put_unaligned_le16(REG_READ(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "addr: %pM\n", addr);
+ put_unaligned_le32(REG_READ(sc->sc_ah, AR_BSSMSKL), addr);
+ put_unaligned_le16(REG_READ(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4);
+ len += snprintf(buf + len, sizeof(buf) - len,
+ "addrmask: %pM\n", addr);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static struct ath_wiphy * get_wiphy(struct ath_softc *sc, const char *name)
+{
+ int i;
+ if (strcmp(name, wiphy_name(sc->pri_wiphy->hw->wiphy)) == 0)
+ return sc->pri_wiphy;
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ struct ath_wiphy *aphy = sc->sec_wiphy[i];
+ if (aphy && strcmp(name, wiphy_name(aphy->hw->wiphy)) == 0)
+ return aphy;
+ }
+ return NULL;
+}
+
+static int del_wiphy(struct ath_softc *sc, const char *name)
+{
+ struct ath_wiphy *aphy = get_wiphy(sc, name);
+ if (!aphy)
+ return -ENOENT;
+ return ath9k_wiphy_del(aphy);
+}
+
+static int pause_wiphy(struct ath_softc *sc, const char *name)
+{
+ struct ath_wiphy *aphy = get_wiphy(sc, name);
+ if (!aphy)
+ return -ENOENT;
+ return ath9k_wiphy_pause(aphy);
+}
+
+static int unpause_wiphy(struct ath_softc *sc, const char *name)
+{
+ struct ath_wiphy *aphy = get_wiphy(sc, name);
+ if (!aphy)
+ return -ENOENT;
+ return ath9k_wiphy_unpause(aphy);
+}
+
+static int select_wiphy(struct ath_softc *sc, const char *name)
+{
+ struct ath_wiphy *aphy = get_wiphy(sc, name);
+ if (!aphy)
+ return -ENOENT;
+ return ath9k_wiphy_select(aphy);
+}
+
+static int schedule_wiphy(struct ath_softc *sc, const char *msec)
+{
+ ath9k_wiphy_set_scheduler(sc, simple_strtoul(msec, NULL, 0));
+ return 0;
+}
+
+static ssize_t write_file_wiphy(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ char buf[50];
+ size_t len;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+ buf[len] = '\0';
+ if (len > 0 && buf[len - 1] == '\n')
+ buf[len - 1] = '\0';
+
+ if (strncmp(buf, "add", 3) == 0) {
+ int res = ath9k_wiphy_add(sc);
+ if (res < 0)
+ return res;
+ } else if (strncmp(buf, "del=", 4) == 0) {
+ int res = del_wiphy(sc, buf + 4);
+ if (res < 0)
+ return res;
+ } else if (strncmp(buf, "pause=", 6) == 0) {
+ int res = pause_wiphy(sc, buf + 6);
+ if (res < 0)
+ return res;
+ } else if (strncmp(buf, "unpause=", 8) == 0) {
+ int res = unpause_wiphy(sc, buf + 8);
+ if (res < 0)
+ return res;
+ } else if (strncmp(buf, "select=", 7) == 0) {
+ int res = select_wiphy(sc, buf + 7);
+ if (res < 0)
+ return res;
+ } else if (strncmp(buf, "schedule=", 9) == 0) {
+ int res = schedule_wiphy(sc, buf + 9);
+ if (res < 0)
+ return res;
+ } else
+ return -EOPNOTSUPP;
+
+ return count;
+}
+
+static const struct file_operations fops_wiphy = {
+ .read = read_file_wiphy,
+ .write = write_file_wiphy,
+ .open = ath9k_debugfs_open,
+ .owner = THIS_MODULE
+};
+
+
+int ath9k_init_debug(struct ath_softc *sc)
+{
+ sc->debug.debug_mask = ath9k_debug;
+
+ sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
+ ath9k_debugfs_root);
+ if (!sc->debug.debugfs_phy)
goto err;
- sc->sc_debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
- sc->sc_debug.debugfs_phy, sc, &fops_dma);
- if (!sc->sc_debug.debugfs_dma)
+ sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
+ sc->debug.debugfs_phy, sc, &fops_dma);
+ if (!sc->debug.debugfs_dma)
goto err;
- sc->sc_debug.debugfs_interrupt = debugfs_create_file("interrupt",
+ sc->debug.debugfs_interrupt = debugfs_create_file("interrupt",
S_IRUGO,
- sc->sc_debug.debugfs_phy,
+ sc->debug.debugfs_phy,
sc, &fops_interrupt);
- if (!sc->sc_debug.debugfs_interrupt)
+ if (!sc->debug.debugfs_interrupt)
+ goto err;
+
+ sc->debug.debugfs_rcstat = debugfs_create_file("rcstat",
+ S_IRUGO,
+ sc->debug.debugfs_phy,
+ sc, &fops_rcstat);
+ if (!sc->debug.debugfs_rcstat)
+ goto err;
+
+ sc->debug.debugfs_wiphy = debugfs_create_file(
+ "wiphy", S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc,
+ &fops_wiphy);
+ if (!sc->debug.debugfs_wiphy)
goto err;
return 0;
@@ -255,8 +536,24 @@ err:
void ath9k_exit_debug(struct ath_softc *sc)
{
- debugfs_remove(sc->sc_debug.debugfs_interrupt);
- debugfs_remove(sc->sc_debug.debugfs_dma);
- debugfs_remove(sc->sc_debug.debugfs_phy);
- debugfs_remove(sc->sc_debug.debugfs_root);
+ debugfs_remove(sc->debug.debugfs_wiphy);
+ debugfs_remove(sc->debug.debugfs_rcstat);
+ debugfs_remove(sc->debug.debugfs_interrupt);
+ debugfs_remove(sc->debug.debugfs_dma);
+ debugfs_remove(sc->debug.debugfs_phy);
+}
+
+int ath9k_debug_create_root(void)
+{
+ ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
+ if (!ath9k_debugfs_root)
+ return -ENOENT;
+
+ return 0;
+}
+
+void ath9k_debug_remove_root(void)
+{
+ debugfs_remove(ath9k_debugfs_root);
+ ath9k_debugfs_root = NULL;
}
diff --git a/drivers/net/wireless/ath9k/debug.h b/drivers/net/wireless/ath9k/debug.h
new file mode 100644
index 000000000000..7b0e5419d2bc
--- /dev/null
+++ b/drivers/net/wireless/ath9k/debug.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+enum ATH_DEBUG {
+ ATH_DBG_RESET = 0x00000001,
+ ATH_DBG_REG_IO = 0x00000002,
+ ATH_DBG_QUEUE = 0x00000004,
+ ATH_DBG_EEPROM = 0x00000008,
+ ATH_DBG_CALIBRATE = 0x00000010,
+ ATH_DBG_CHANNEL = 0x00000020,
+ ATH_DBG_INTERRUPT = 0x00000040,
+ ATH_DBG_REGULATORY = 0x00000080,
+ ATH_DBG_ANI = 0x00000100,
+ ATH_DBG_POWER_MGMT = 0x00000200,
+ ATH_DBG_XMIT = 0x00000400,
+ ATH_DBG_BEACON = 0x00001000,
+ ATH_DBG_CONFIG = 0x00002000,
+ ATH_DBG_KEYCACHE = 0x00004000,
+ ATH_DBG_FATAL = 0x00008000,
+ ATH_DBG_ANY = 0xffffffff
+};
+
+#define DBG_DEFAULT (ATH_DBG_FATAL)
+
+#ifdef CONFIG_ATH9K_DEBUG
+
+/**
+ * struct ath_interrupt_stats - Contains statistics about interrupts
+ * @total: Total no. of interrupts generated so far
+ * @rxok: RX with no errors
+ * @rxeol: RX with no more RXDESC available
+ * @rxorn: RX FIFO overrun
+ * @txok: TX completed at the requested rate
+ * @txurn: TX FIFO underrun
+ * @mib: MIB regs reaching its threshold
+ * @rxphyerr: RX with phy errors
+ * @rx_keycache_miss: RX with key cache misses
+ * @swba: Software Beacon Alert
+ * @bmiss: Beacon Miss
+ * @bnr: Beacon Not Ready
+ * @cst: Carrier Sense TImeout
+ * @gtt: Global TX Timeout
+ * @tim: RX beacon TIM occurrence
+ * @cabend: RX End of CAB traffic
+ * @dtimsync: DTIM sync lossage
+ * @dtim: RX Beacon with DTIM
+ */
+struct ath_interrupt_stats {
+ u32 total;
+ u32 rxok;
+ u32 rxeol;
+ u32 rxorn;
+ u32 txok;
+ u32 txeol;
+ u32 txurn;
+ u32 mib;
+ u32 rxphyerr;
+ u32 rx_keycache_miss;
+ u32 swba;
+ u32 bmiss;
+ u32 bnr;
+ u32 cst;
+ u32 gtt;
+ u32 tim;
+ u32 cabend;
+ u32 dtimsync;
+ u32 dtim;
+};
+
+struct ath_legacy_rc_stats {
+ u32 success;
+};
+
+struct ath_11n_rc_stats {
+ u32 success;
+ u32 retries;
+ u32 xretries;
+ u8 per;
+};
+
+struct ath_stats {
+ struct ath_interrupt_stats istats;
+ struct ath_legacy_rc_stats legacy_rcstats[12]; /* max(11a,11b,11g) */
+ struct ath_11n_rc_stats n_rcstats[16]; /* 0..15 MCS rates */
+};
+
+struct ath9k_debug {
+ int debug_mask;
+ struct dentry *debugfs_phy;
+ struct dentry *debugfs_dma;
+ struct dentry *debugfs_interrupt;
+ struct dentry *debugfs_rcstat;
+ struct dentry *debugfs_wiphy;
+ struct ath_stats stats;
+};
+
+void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
+int ath9k_init_debug(struct ath_softc *sc);
+void ath9k_exit_debug(struct ath_softc *sc);
+int ath9k_debug_create_root(void);
+void ath9k_debug_remove_root(void);
+void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
+void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
+void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+ int xretries, int retries, u8 per);
+
+#else
+
+static inline void DPRINTF(struct ath_softc *sc, int dbg_mask,
+ const char *fmt, ...)
+{
+}
+
+static inline int ath9k_init_debug(struct ath_softc *sc)
+{
+ return 0;
+}
+
+static inline void ath9k_exit_debug(struct ath_softc *sc)
+{
+}
+
+static inline int ath9k_debug_create_root(void)
+{
+ return 0;
+}
+
+static inline void ath9k_debug_remove_root(void)
+{
+}
+
+static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
+ enum ath9k_int status)
+{
+}
+
+static inline void ath_debug_stat_rc(struct ath_softc *sc,
+ struct sk_buff *skb)
+{
+}
+
+static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+ int xretries, int retries, u8 per)
+{
+}
+
+#endif /* CONFIG_ATH9K_DEBUG */
+
+#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c
index acd6c5374d44..ffc36b0361c7 100644
--- a/drivers/net/wireless/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath9k/eeprom.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,12 +14,9 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
-static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
+static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah,
u32 reg, u32 mask,
u32 shift, u32 val)
{
@@ -30,7 +27,7 @@ static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
REG_WRITE(ah, reg, regVal);
- if (ah->ah_config.analog_shiftreg)
+ if (ah->config.analog_shiftreg)
udelay(100);
return;
@@ -91,254 +88,288 @@ static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList,
return false;
}
-static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off, u16 *data)
+static inline bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
{
- (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
+ struct ath_softc *sc = ah->ah_sc;
- if (!ath9k_hw_wait(ah,
- AR_EEPROM_STATUS_DATA,
- AR_EEPROM_STATUS_DATA_BUSY |
- AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
- return false;
- }
-
- *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
- AR_EEPROM_STATUS_DATA_VAL);
-
- return true;
+ return sc->bus_ops->eeprom_read(ah, off, data);
}
-static int ath9k_hw_flash_map(struct ath_hal *ah)
+static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
+ u8 *pVpdList, u16 numIntercepts,
+ u8 *pRetVpdList)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
+ u16 i, k;
+ u8 currPwr = pwrMin;
+ u16 idxL = 0, idxR = 0;
- if (!ahp->ah_cal_mem) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "cannot remap eeprom region \n");
- return -EIO;
+ for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
+ ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
+ numIntercepts, &(idxL),
+ &(idxR));
+ if (idxR < 1)
+ idxR = 1;
+ if (idxL == numIntercepts - 1)
+ idxL = (u16) (numIntercepts - 2);
+ if (pPwrList[idxL] == pPwrList[idxR])
+ k = pVpdList[idxL];
+ else
+ k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
+ (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
+ (pPwrList[idxR] - pPwrList[idxL]));
+ pRetVpdList[i] = (u8) k;
+ currPwr += 2;
}
- return 0;
-}
-
-static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off, u16 *data)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- *data = ioread16(ahp->ah_cal_mem + off);
-
return true;
}
-static inline bool ath9k_hw_nvram_read(struct ath_hal *ah, u32 off, u16 *data)
-{
- if (ath9k_hw_use_flash(ah))
- return ath9k_hw_flash_read(ah, off, data);
- else
- return ath9k_hw_eeprom_read(ah, off, data);
-}
-
-static bool ath9k_hw_fill_4k_eeprom(struct ath_hal *ah)
+static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ struct cal_target_power_leg *powInfo,
+ u16 numChannels,
+ struct cal_target_power_leg *pNewPower,
+ u16 numRates, bool isExtTarget)
{
-#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
- u16 *eep_data;
- int addr, eep_start_loc = 0;
+ struct chan_centers centers;
+ u16 clo, chi;
+ int i;
+ int matchIndex = -1, lowIndex = -1;
+ u16 freq;
- eep_start_loc = 64;
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
+ freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
- if (!ath9k_hw_use_flash(ah)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Reading from EEPROM, not flash\n");
+ if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
+ IS_CHAN_2GHZ(chan))) {
+ matchIndex = 0;
+ } else {
+ for (i = 0; (i < numChannels) &&
+ (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+ if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+ IS_CHAN_2GHZ(chan))) {
+ matchIndex = i;
+ break;
+ } else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+ IS_CHAN_2GHZ(chan))) &&
+ (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+ IS_CHAN_2GHZ(chan)))) {
+ lowIndex = i - 1;
+ break;
+ }
+ }
+ if ((matchIndex == -1) && (lowIndex == -1))
+ matchIndex = i - 1;
}
- eep_data = (u16 *)eep;
+ if (matchIndex != -1) {
+ *pNewPower = powInfo[matchIndex];
+ } else {
+ clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+ IS_CHAN_2GHZ(chan));
+ chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+ IS_CHAN_2GHZ(chan));
- for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
- if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Unable to read eeprom region \n");
- return false;
+ for (i = 0; i < numRates; i++) {
+ pNewPower->tPow2x[i] =
+ (u8)ath9k_hw_interpolate(freq, clo, chi,
+ powInfo[lowIndex].tPow2x[i],
+ powInfo[lowIndex + 1].tPow2x[i]);
}
- eep_data++;
}
- return true;
-#undef SIZE_EEPROM_4K
}
-static bool ath9k_hw_fill_def_eeprom(struct ath_hal *ah)
+static void ath9k_get_txgain_index(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ struct calDataPerFreqOpLoop *rawDatasetOpLoop,
+ u8 *calChans, u16 availPiers, u8 *pwr, u8 *pcdacIdx)
{
-#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
- u16 *eep_data;
- int addr, ar5416_eep_start_loc = 0x100;
+ u8 pcdac, i = 0;
+ u16 idxL = 0, idxR = 0, numPiers;
+ bool match;
+ struct chan_centers centers;
- eep_data = (u16 *)eep;
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
- for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
- if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
- eep_data)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Unable to read eeprom region\n");
- return false;
- }
- eep_data++;
- }
- return true;
-#undef SIZE_EEPROM_DEF
-}
+ for (numPiers = 0; numPiers < availPiers; numPiers++)
+ if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
+ break;
-static bool (*ath9k_fill_eeprom[]) (struct ath_hal *) = {
- ath9k_hw_fill_def_eeprom,
- ath9k_hw_fill_4k_eeprom
-};
+ match = ath9k_hw_get_lower_upper_index(
+ (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
+ calChans, numPiers, &idxL, &idxR);
+ if (match) {
+ pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
+ *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
+ } else {
+ pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
+ *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
+ rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
+ }
-static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ while (pcdac > ah->originalGain[i] &&
+ i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
+ i++;
- return ath9k_fill_eeprom[ahp->ah_eep_map](ah);
+ *pcdacIdx = i;
+ return;
}
-static int ath9k_hw_check_def_eeprom(struct ath_hal *ah)
+static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
+ u32 initTxGain,
+ int txPower,
+ u8 *pPDADCValues)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep =
- (struct ar5416_eeprom_def *) &ahp->ah_eeprom.def;
- u16 *eepdata, temp, magic, magic2;
- u32 sum = 0, el;
- bool need_swap = false;
- int i, addr, size;
+ u32 i;
+ u32 offset;
- if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
- &magic)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Reading Magic # failed\n");
- return false;
- }
+ REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
+ AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+ REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
+ AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
- if (!ath9k_hw_use_flash(ah)) {
+ REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
+ AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Read Magic = 0x%04X\n", magic);
+ offset = txPower;
+ for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
+ if (i < offset)
+ pPDADCValues[i] = 0x0;
+ else
+ pPDADCValues[i] = 0xFF;
+}
- if (magic != AR5416_EEPROM_MAGIC) {
- magic2 = swab16(magic);
- if (magic2 == AR5416_EEPROM_MAGIC) {
- size = sizeof(struct ar5416_eeprom_def);
- need_swap = true;
- eepdata = (u16 *) (&ahp->ah_eeprom);
- for (addr = 0; addr < size / sizeof(u16); addr++) {
- temp = swab16(*eepdata);
- *eepdata = temp;
- eepdata++;
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "0x%04X ", *eepdata);
+static void ath9k_hw_get_target_powers(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ struct cal_target_power_ht *powInfo,
+ u16 numChannels,
+ struct cal_target_power_ht *pNewPower,
+ u16 numRates, bool isHt40Target)
+{
+ struct chan_centers centers;
+ u16 clo, chi;
+ int i;
+ int matchIndex = -1, lowIndex = -1;
+ u16 freq;
- if (((addr + 1) % 6) == 0)
- DPRINTF(ah->ah_sc,
- ATH_DBG_EEPROM, "\n");
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
+ freq = isHt40Target ? centers.synth_center : centers.ctl_center;
+
+ if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
+ matchIndex = 0;
+ } else {
+ for (i = 0; (i < numChannels) &&
+ (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+ if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+ IS_CHAN_2GHZ(chan))) {
+ matchIndex = i;
+ break;
+ } else
+ if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+ IS_CHAN_2GHZ(chan))) &&
+ (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+ IS_CHAN_2GHZ(chan)))) {
+ lowIndex = i - 1;
+ break;
}
- } else {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Invalid EEPROM Magic. "
- "endianness mismatch.\n");
- return -EINVAL;
- }
}
+ if ((matchIndex == -1) && (lowIndex == -1))
+ matchIndex = i - 1;
}
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
- need_swap ? "True" : "False");
-
- if (need_swap)
- el = swab16(ahp->ah_eeprom.def.baseEepHeader.length);
- else
- el = ahp->ah_eeprom.def.baseEepHeader.length;
-
- if (el > sizeof(struct ar5416_eeprom_def))
- el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
- else
- el = el / sizeof(u16);
-
- eepdata = (u16 *)(&ahp->ah_eeprom);
-
- for (i = 0; i < el; i++)
- sum ^= *eepdata++;
-
- if (need_swap) {
- u32 integer, j;
- u16 word;
-
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "EEPROM Endianness is not native.. Changing \n");
-
- word = swab16(eep->baseEepHeader.length);
- eep->baseEepHeader.length = word;
+ if (matchIndex != -1) {
+ *pNewPower = powInfo[matchIndex];
+ } else {
+ clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+ IS_CHAN_2GHZ(chan));
+ chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+ IS_CHAN_2GHZ(chan));
- word = swab16(eep->baseEepHeader.checksum);
- eep->baseEepHeader.checksum = word;
+ for (i = 0; i < numRates; i++) {
+ pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
+ clo, chi,
+ powInfo[lowIndex].tPow2x[i],
+ powInfo[lowIndex + 1].tPow2x[i]);
+ }
+ }
+}
- word = swab16(eep->baseEepHeader.version);
- eep->baseEepHeader.version = word;
+static u16 ath9k_hw_get_max_edge_power(u16 freq,
+ struct cal_ctl_edges *pRdEdgesPower,
+ bool is2GHz, int num_band_edges)
+{
+ u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ int i;
- word = swab16(eep->baseEepHeader.regDmn[0]);
- eep->baseEepHeader.regDmn[0] = word;
+ for (i = 0; (i < num_band_edges) &&
+ (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+ if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
+ twiceMaxEdgePower = pRdEdgesPower[i].tPower;
+ break;
+ } else if ((i > 0) &&
+ (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
+ is2GHz))) {
+ if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
+ is2GHz) < freq &&
+ pRdEdgesPower[i - 1].flag) {
+ twiceMaxEdgePower =
+ pRdEdgesPower[i - 1].tPower;
+ }
+ break;
+ }
+ }
- word = swab16(eep->baseEepHeader.regDmn[1]);
- eep->baseEepHeader.regDmn[1] = word;
+ return twiceMaxEdgePower;
+}
- word = swab16(eep->baseEepHeader.rfSilent);
- eep->baseEepHeader.rfSilent = word;
+/****************************************/
+/* EEPROM Operations for 4K sized cards */
+/****************************************/
- word = swab16(eep->baseEepHeader.blueToothOptions);
- eep->baseEepHeader.blueToothOptions = word;
+static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
+{
+ return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
+}
- word = swab16(eep->baseEepHeader.deviceCap);
- eep->baseEepHeader.deviceCap = word;
+static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
+{
+ return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
+}
- for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
- struct modal_eep_header *pModal =
- &eep->modalHeader[j];
- integer = swab32(pModal->antCtrlCommon);
- pModal->antCtrlCommon = integer;
+static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
+{
+#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+ u16 *eep_data = (u16 *)&ah->eeprom.map4k;
+ int addr, eep_start_loc = 0;
- for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- integer = swab32(pModal->antCtrlChain[i]);
- pModal->antCtrlChain[i] = integer;
- }
+ eep_start_loc = 64;
- for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
- word = swab16(pModal->spurChans[i].spurChan);
- pModal->spurChans[i].spurChan = word;
- }
- }
+ if (!ath9k_hw_use_flash(ah)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Reading from EEPROM, not flash\n");
}
- if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER ||
- ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
- sum, ar5416_get_eep_ver(ahp));
- return -EINVAL;
+ for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
+ if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Unable to read eeprom region \n");
+ return false;
+ }
+ eep_data++;
}
- return 0;
+ return true;
+#undef SIZE_EEPROM_4K
}
-static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
+static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
{
#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ar5416_eeprom_4k *eep =
- (struct ar5416_eeprom_4k *) &ahp->ah_eeprom.map4k;
+ (struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
u16 *eepdata, temp, magic, magic2;
u32 sum = 0, el;
bool need_swap = false;
@@ -346,38 +377,30 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
if (!ath9k_hw_use_flash(ah)) {
-
if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
&magic)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Reading Magic # failed\n");
return false;
}
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "Read Magic = 0x%04X\n", magic);
+ "Read Magic = 0x%04X\n", magic);
if (magic != AR5416_EEPROM_MAGIC) {
magic2 = swab16(magic);
if (magic2 == AR5416_EEPROM_MAGIC) {
need_swap = true;
- eepdata = (u16 *) (&ahp->ah_eeprom);
+ eepdata = (u16 *) (&ah->eeprom);
for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
temp = swab16(*eepdata);
*eepdata = temp;
eepdata++;
-
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "0x%04X ", *eepdata);
-
- if (((addr + 1) % 6) == 0)
- DPRINTF(ah->ah_sc,
- ATH_DBG_EEPROM, "\n");
}
} else {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Invalid EEPROM Magic. "
"endianness mismatch.\n");
return -EINVAL;
@@ -389,16 +412,16 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
need_swap ? "True" : "False");
if (need_swap)
- el = swab16(ahp->ah_eeprom.map4k.baseEepHeader.length);
+ el = swab16(ah->eeprom.map4k.baseEepHeader.length);
else
- el = ahp->ah_eeprom.map4k.baseEepHeader.length;
+ el = ah->eeprom.map4k.baseEepHeader.length;
- if (el > sizeof(struct ar5416_eeprom_def))
+ if (el > sizeof(struct ar5416_eeprom_4k))
el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
else
el = el / sizeof(u16);
- eepdata = (u16 *)(&ahp->ah_eeprom);
+ eepdata = (u16 *)(&ah->eeprom);
for (i = 0; i < el; i++)
sum ^= *eepdata++;
@@ -408,7 +431,7 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
u16 word;
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "EEPROM Endianness is not native.. Changing \n");
+ "EEPROM Endianness is not native.. Changing\n");
word = swab16(eep->baseEepHeader.length);
eep->baseEepHeader.length = word;
@@ -448,11 +471,11 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
}
}
- if (sum != 0xffff || ar5416_get_eep4k_ver(ahp) != AR5416_EEP_VER ||
- ar5416_get_eep4k_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
+ ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
- sum, ar5416_get_eep4k_ver(ahp));
+ sum, ah->eep_ops->get_eeprom_ver(ah));
return -EINVAL;
}
@@ -460,48 +483,50 @@ static int ath9k_hw_check_4k_eeprom(struct ath_hal *ah)
#undef EEPROM_4K_SIZE
}
-static int (*ath9k_check_eeprom[]) (struct ath_hal *) = {
- ath9k_hw_check_def_eeprom,
- ath9k_hw_check_4k_eeprom
-};
-
-static inline int ath9k_hw_check_eeprom(struct ath_hal *ah)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- return ath9k_check_eeprom[ahp->ah_eep_map](ah);
-}
-
-static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
- u8 *pVpdList, u16 numIntercepts,
- u8 *pRetVpdList)
+static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
+ enum eeprom_param param)
{
- u16 i, k;
- u8 currPwr = pwrMin;
- u16 idxL = 0, idxR = 0;
+ struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+ struct modal_eep_4k_header *pModal = &eep->modalHeader;
+ struct base_eep_header_4k *pBase = &eep->baseEepHeader;
- for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
- ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
- numIntercepts, &(idxL),
- &(idxR));
- if (idxR < 1)
- idxR = 1;
- if (idxL == numIntercepts - 1)
- idxL = (u16) (numIntercepts - 2);
- if (pPwrList[idxL] == pPwrList[idxR])
- k = pVpdList[idxL];
- else
- k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
- (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
- (pPwrList[idxR] - pPwrList[idxL]));
- pRetVpdList[i] = (u8) k;
- currPwr += 2;
+ switch (param) {
+ case EEP_NFTHRESH_2:
+ return pModal->noiseFloorThreshCh[0];
+ case AR_EEPROM_MAC(0):
+ return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+ case AR_EEPROM_MAC(1):
+ return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+ case AR_EEPROM_MAC(2):
+ return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+ case EEP_REG_0:
+ return pBase->regDmn[0];
+ case EEP_REG_1:
+ return pBase->regDmn[1];
+ case EEP_OP_CAP:
+ return pBase->deviceCap;
+ case EEP_OP_MODE:
+ return pBase->opCapFlags;
+ case EEP_RF_SILENT:
+ return pBase->rfSilent;
+ case EEP_OB_2:
+ return pModal->ob_01;
+ case EEP_DB_2:
+ return pModal->db1_01;
+ case EEP_MINOR_REV:
+ return pBase->version & AR5416_EEP_VER_MINOR_MASK;
+ case EEP_TX_MASK:
+ return pBase->txMask;
+ case EEP_RX_MASK:
+ return pBase->rxMask;
+ case EEP_FRAC_N_5G:
+ return 0;
+ default:
+ return 0;
}
-
- return true;
}
-static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah,
+static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
struct ath9k_channel *chan,
struct cal_data_per_freq_4k *pRawDataSet,
u8 *bChans, u16 availPiers,
@@ -605,7 +630,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah,
pPdGainBoundaries[i] =
min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
- if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
+ if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
minDelta = pPdGainBoundaries[0] - 23;
pPdGainBoundaries[0] = 23;
} else {
@@ -644,7 +669,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah,
vpdTableI[i][sizeCurrVpdTable - 2]);
vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
- if (tgtIndex > maxIndex) {
+ if (tgtIndex >= maxIndex) {
while ((ss <= tgtIndex) &&
(k < (AR5416_NUM_PDADC_VALUES - 1))) {
tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
@@ -669,451 +694,20 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hal *ah,
#undef TMP_VAL_VPD_TABLE
}
-static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hal *ah,
- struct ath9k_channel *chan,
- struct cal_data_per_freq *pRawDataSet,
- u8 *bChans, u16 availPiers,
- u16 tPdGainOverlap, int16_t *pMinCalPower,
- u16 *pPdGainBoundaries, u8 *pPDADCValues,
- u16 numXpdGains)
-{
- int i, j, k;
- int16_t ss;
- u16 idxL = 0, idxR = 0, numPiers;
- static u8 vpdTableL[AR5416_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
- static u8 vpdTableR[AR5416_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
- static u8 vpdTableI[AR5416_NUM_PD_GAINS]
- [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-
- u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
- u8 minPwrT4[AR5416_NUM_PD_GAINS];
- u8 maxPwrT4[AR5416_NUM_PD_GAINS];
- int16_t vpdStep;
- int16_t tmpVal;
- u16 sizeCurrVpdTable, maxIndex, tgtIndex;
- bool match;
- int16_t minDelta = 0;
- struct chan_centers centers;
-
- ath9k_hw_get_channel_centers(ah, chan, &centers);
-
- for (numPiers = 0; numPiers < availPiers; numPiers++) {
- if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
- break;
- }
-
- match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
- IS_CHAN_2GHZ(chan)),
- bChans, numPiers, &idxL, &idxR);
-
- if (match) {
- for (i = 0; i < numXpdGains; i++) {
- minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
- maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pRawDataSet[idxL].pwrPdg[i],
- pRawDataSet[idxL].vpdPdg[i],
- AR5416_PD_GAIN_ICEPTS,
- vpdTableI[i]);
- }
- } else {
- for (i = 0; i < numXpdGains; i++) {
- pVpdL = pRawDataSet[idxL].vpdPdg[i];
- pPwrL = pRawDataSet[idxL].pwrPdg[i];
- pVpdR = pRawDataSet[idxR].vpdPdg[i];
- pPwrR = pRawDataSet[idxR].pwrPdg[i];
-
- minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
-
- maxPwrT4[i] =
- min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
- pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
-
-
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pPwrL, pVpdL,
- AR5416_PD_GAIN_ICEPTS,
- vpdTableL[i]);
- ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
- pPwrR, pVpdR,
- AR5416_PD_GAIN_ICEPTS,
- vpdTableR[i]);
-
- for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
- vpdTableI[i][j] =
- (u8)(ath9k_hw_interpolate((u16)
- FREQ2FBIN(centers.
- synth_center,
- IS_CHAN_2GHZ
- (chan)),
- bChans[idxL], bChans[idxR],
- vpdTableL[i][j], vpdTableR[i][j]));
- }
- }
- }
-
- *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
-
- k = 0;
-
- for (i = 0; i < numXpdGains; i++) {
- if (i == (numXpdGains - 1))
- pPdGainBoundaries[i] =
- (u16)(maxPwrT4[i] / 2);
- else
- pPdGainBoundaries[i] =
- (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
-
- pPdGainBoundaries[i] =
- min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
-
- if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
- minDelta = pPdGainBoundaries[0] - 23;
- pPdGainBoundaries[0] = 23;
- } else {
- minDelta = 0;
- }
-
- if (i == 0) {
- if (AR_SREV_9280_10_OR_LATER(ah))
- ss = (int16_t)(0 - (minPwrT4[i] / 2));
- else
- ss = 0;
- } else {
- ss = (int16_t)((pPdGainBoundaries[i - 1] -
- (minPwrT4[i] / 2)) -
- tPdGainOverlap + 1 + minDelta);
- }
- vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
- vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
- while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
- tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
- pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
- ss++;
- }
-
- sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
- tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
- (minPwrT4[i] / 2));
- maxIndex = (tgtIndex < sizeCurrVpdTable) ?
- tgtIndex : sizeCurrVpdTable;
-
- while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
- pPDADCValues[k++] = vpdTableI[i][ss++];
- }
-
- vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
- vpdTableI[i][sizeCurrVpdTable - 2]);
- vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
- if (tgtIndex > maxIndex) {
- while ((ss <= tgtIndex) &&
- (k < (AR5416_NUM_PDADC_VALUES - 1))) {
- tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
- (ss - maxIndex + 1) * vpdStep));
- pPDADCValues[k++] = (u8)((tmpVal > 255) ?
- 255 : tmpVal);
- ss++;
- }
- }
- }
-
- while (i < AR5416_PD_GAINS_IN_MASK) {
- pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
- i++;
- }
-
- while (k < AR5416_NUM_PDADC_VALUES) {
- pPDADCValues[k] = pPDADCValues[k - 1];
- k++;
- }
-
- return;
-}
-
-static void ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
- struct ath9k_channel *chan,
- struct cal_target_power_leg *powInfo,
- u16 numChannels,
- struct cal_target_power_leg *pNewPower,
- u16 numRates, bool isExtTarget)
-{
- struct chan_centers centers;
- u16 clo, chi;
- int i;
- int matchIndex = -1, lowIndex = -1;
- u16 freq;
-
- ath9k_hw_get_channel_centers(ah, chan, &centers);
- freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
-
- if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
- IS_CHAN_2GHZ(chan))) {
- matchIndex = 0;
- } else {
- for (i = 0; (i < numChannels) &&
- (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
- if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
- IS_CHAN_2GHZ(chan))) {
- matchIndex = i;
- break;
- } else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
- IS_CHAN_2GHZ(chan))) &&
- (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
- IS_CHAN_2GHZ(chan)))) {
- lowIndex = i - 1;
- break;
- }
- }
- if ((matchIndex == -1) && (lowIndex == -1))
- matchIndex = i - 1;
- }
-
- if (matchIndex != -1) {
- *pNewPower = powInfo[matchIndex];
- } else {
- clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
- IS_CHAN_2GHZ(chan));
- chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
- IS_CHAN_2GHZ(chan));
-
- for (i = 0; i < numRates; i++) {
- pNewPower->tPow2x[i] =
- (u8)ath9k_hw_interpolate(freq, clo, chi,
- powInfo[lowIndex].tPow2x[i],
- powInfo[lowIndex + 1].tPow2x[i]);
- }
- }
-}
-
-static void ath9k_hw_get_target_powers(struct ath_hal *ah,
- struct ath9k_channel *chan,
- struct cal_target_power_ht *powInfo,
- u16 numChannels,
- struct cal_target_power_ht *pNewPower,
- u16 numRates, bool isHt40Target)
-{
- struct chan_centers centers;
- u16 clo, chi;
- int i;
- int matchIndex = -1, lowIndex = -1;
- u16 freq;
-
- ath9k_hw_get_channel_centers(ah, chan, &centers);
- freq = isHt40Target ? centers.synth_center : centers.ctl_center;
-
- if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
- matchIndex = 0;
- } else {
- for (i = 0; (i < numChannels) &&
- (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
- if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
- IS_CHAN_2GHZ(chan))) {
- matchIndex = i;
- break;
- } else
- if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
- IS_CHAN_2GHZ(chan))) &&
- (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
- IS_CHAN_2GHZ(chan)))) {
- lowIndex = i - 1;
- break;
- }
- }
- if ((matchIndex == -1) && (lowIndex == -1))
- matchIndex = i - 1;
- }
-
- if (matchIndex != -1) {
- *pNewPower = powInfo[matchIndex];
- } else {
- clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
- IS_CHAN_2GHZ(chan));
- chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
- IS_CHAN_2GHZ(chan));
-
- for (i = 0; i < numRates; i++) {
- pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
- clo, chi,
- powInfo[lowIndex].tPow2x[i],
- powInfo[lowIndex + 1].tPow2x[i]);
- }
- }
-}
-
-static u16 ath9k_hw_get_max_edge_power(u16 freq,
- struct cal_ctl_edges *pRdEdgesPower,
- bool is2GHz, int num_band_edges)
-{
- u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
- int i;
-
- for (i = 0; (i < num_band_edges) &&
- (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
- if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
- twiceMaxEdgePower = pRdEdgesPower[i].tPower;
- break;
- } else if ((i > 0) &&
- (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
- is2GHz))) {
- if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
- is2GHz) < freq &&
- pRdEdgesPower[i - 1].flag) {
- twiceMaxEdgePower =
- pRdEdgesPower[i - 1].tPower;
- }
- break;
- }
- }
-
- return twiceMaxEdgePower;
-}
-
-static bool ath9k_hw_set_def_power_cal_table(struct ath_hal *ah,
+static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
struct ath9k_channel *chan,
int16_t *pTxPowerIndexOffset)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
- struct cal_data_per_freq *pRawDataset;
- u8 *pCalBChans = NULL;
- u16 pdGainOverlap_t2;
- static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
- u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
- u16 numPiers, i, j;
- int16_t tMinCalPower;
- u16 numXpdGain, xpdMask;
- u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
- u32 reg32, regOffset, regChainOffset;
- int16_t modalIdx;
-
- modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
- xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
-
- if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
- pdGainOverlap_t2 =
- pEepData->modalHeader[modalIdx].pdGainOverlap;
- } else {
- pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
- AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
- }
-
- if (IS_CHAN_2GHZ(chan)) {
- pCalBChans = pEepData->calFreqPier2G;
- numPiers = AR5416_NUM_2G_CAL_PIERS;
- } else {
- pCalBChans = pEepData->calFreqPier5G;
- numPiers = AR5416_NUM_5G_CAL_PIERS;
- }
-
- numXpdGain = 0;
-
- for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
- if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
- if (numXpdGain >= AR5416_NUM_PD_GAINS)
- break;
- xpdGainValues[numXpdGain] =
- (u16)(AR5416_PD_GAINS_IN_MASK - i);
- numXpdGain++;
- }
- }
-
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
- (numXpdGain - 1) & 0x3);
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
- xpdGainValues[0]);
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
- xpdGainValues[1]);
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
- xpdGainValues[2]);
-
- for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- if (AR_SREV_5416_V20_OR_LATER(ah) &&
- (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
- (i != 0)) {
- regChainOffset = (i == 1) ? 0x2000 : 0x1000;
- } else
- regChainOffset = i * 0x1000;
-
- if (pEepData->baseEepHeader.txMask & (1 << i)) {
- if (IS_CHAN_2GHZ(chan))
- pRawDataset = pEepData->calPierData2G[i];
- else
- pRawDataset = pEepData->calPierData5G[i];
-
- ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan,
- pRawDataset, pCalBChans,
- numPiers, pdGainOverlap_t2,
- &tMinCalPower, gainBoundaries,
- pdadcValues, numXpdGain);
-
- if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
- REG_WRITE(ah,
- AR_PHY_TPCRG5 + regChainOffset,
- SM(pdGainOverlap_t2,
- AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
- | SM(gainBoundaries[0],
- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
- | SM(gainBoundaries[1],
- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
- | SM(gainBoundaries[2],
- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
- | SM(gainBoundaries[3],
- AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
- }
-
- regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
- for (j = 0; j < 32; j++) {
- reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
- ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
- ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
- ((pdadcValues[4 * j + 3] & 0xFF) << 24);
- REG_WRITE(ah, regOffset, reg32);
-
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
- "PDADC (%d,%4x): %4.4x %8.8x\n",
- i, regChainOffset, regOffset,
- reg32);
- DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
- "PDADC: Chain %d | PDADC %3d "
- "Value %3d | PDADC %3d Value %3d | "
- "PDADC %3d Value %3d | PDADC %3d "
- "Value %3d |\n",
- i, 4 * j, pdadcValues[4 * j],
- 4 * j + 1, pdadcValues[4 * j + 1],
- 4 * j + 2, pdadcValues[4 * j + 2],
- 4 * j + 3,
- pdadcValues[4 * j + 3]);
-
- regOffset += 4;
- }
- }
- }
-
- *pTxPowerIndexOffset = 0;
-
- return true;
-}
-
-static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
- struct ath9k_channel *chan,
- int16_t *pTxPowerIndexOffset)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
+ struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
struct cal_data_per_freq_4k *pRawDataset;
u8 *pCalBChans = NULL;
u16 pdGainOverlap_t2;
static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
- u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+ u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
u16 numPiers, i, j;
int16_t tMinCalPower;
u16 numXpdGain, xpdMask;
- u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+ u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
u32 reg32, regOffset, regChainOffset;
xpdMask = pEepData->modalHeader.xpdGain;
@@ -1128,16 +722,16 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
}
pCalBChans = pEepData->calFreqPier2G;
- numPiers = AR5416_NUM_2G_CAL_PIERS;
+ numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
numXpdGain = 0;
- for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
- if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
- if (numXpdGain >= AR5416_NUM_PD_GAINS)
+ for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
+ if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
+ if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
break;
xpdGainValues[numXpdGain] =
- (u16)(AR5416_PD_GAINS_IN_MASK - i);
+ (u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i);
numXpdGain++;
}
}
@@ -1148,12 +742,11 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
xpdGainValues[0]);
REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
xpdGainValues[1]);
- REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
- xpdGainValues[2]);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
- for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- if (AR_SREV_5416_V20_OR_LATER(ah) &&
- (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5) &&
+ for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
+ if (AR_SREV_5416_20_OR_LATER(ah) &&
+ (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
(i != 0)) {
regChainOffset = (i == 1) ? 0x2000 : 0x1000;
} else
@@ -1168,7 +761,7 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
&tMinCalPower, gainBoundaries,
pdadcValues, numXpdGain);
- if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
+ if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
SM(pdGainOverlap_t2,
AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
@@ -1216,298 +809,7 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hal *ah,
return true;
}
-static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hal *ah,
- struct ath9k_channel *chan,
- int16_t *ratesArray,
- u16 cfgCtl,
- u16 AntennaReduction,
- u16 twiceMaxRegulatoryPower,
- u16 powerLimit)
-{
-#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
-#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
-
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
- u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
- static const u16 tpScaleReductionTable[5] =
- { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
-
- int i;
- int16_t twiceLargestAntenna;
- struct cal_ctl_data *rep;
- struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
- 0, { 0, 0, 0, 0}
- };
- struct cal_target_power_leg targetPowerOfdmExt = {
- 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
- 0, { 0, 0, 0, 0 }
- };
- struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
- 0, {0, 0, 0, 0}
- };
- u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
- u16 ctlModesFor11a[] =
- { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
- u16 ctlModesFor11g[] =
- { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
- CTL_2GHT40
- };
- u16 numCtlModes, *pCtlMode, ctlMode, freq;
- struct chan_centers centers;
- int tx_chainmask;
- u16 twiceMinEdgePower;
-
- tx_chainmask = ahp->ah_txchainmask;
-
- ath9k_hw_get_channel_centers(ah, chan, &centers);
-
- twiceLargestAntenna = max(
- pEepData->modalHeader
- [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
- pEepData->modalHeader
- [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
-
- twiceLargestAntenna = max((u8)twiceLargestAntenna,
- pEepData->modalHeader
- [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
-
- twiceLargestAntenna = (int16_t)min(AntennaReduction -
- twiceLargestAntenna, 0);
-
- maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
-
- if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
- maxRegAllowedPower -=
- (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
- }
-
- scaledPower = min(powerLimit, maxRegAllowedPower);
-
- switch (ar5416_get_ntxchains(tx_chainmask)) {
- case 1:
- break;
- case 2:
- scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
- break;
- case 3:
- scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
- break;
- }
-
- scaledPower = max((u16)0, scaledPower);
-
- if (IS_CHAN_2GHZ(chan)) {
- numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
- SUB_NUM_CTL_MODES_AT_2G_40;
- pCtlMode = ctlModesFor11g;
-
- ath9k_hw_get_legacy_target_powers(ah, chan,
- pEepData->calTargetPowerCck,
- AR5416_NUM_2G_CCK_TARGET_POWERS,
- &targetPowerCck, 4, false);
- ath9k_hw_get_legacy_target_powers(ah, chan,
- pEepData->calTargetPower2G,
- AR5416_NUM_2G_20_TARGET_POWERS,
- &targetPowerOfdm, 4, false);
- ath9k_hw_get_target_powers(ah, chan,
- pEepData->calTargetPower2GHT20,
- AR5416_NUM_2G_20_TARGET_POWERS,
- &targetPowerHt20, 8, false);
-
- if (IS_CHAN_HT40(chan)) {
- numCtlModes = ARRAY_SIZE(ctlModesFor11g);
- ath9k_hw_get_target_powers(ah, chan,
- pEepData->calTargetPower2GHT40,
- AR5416_NUM_2G_40_TARGET_POWERS,
- &targetPowerHt40, 8, true);
- ath9k_hw_get_legacy_target_powers(ah, chan,
- pEepData->calTargetPowerCck,
- AR5416_NUM_2G_CCK_TARGET_POWERS,
- &targetPowerCckExt, 4, true);
- ath9k_hw_get_legacy_target_powers(ah, chan,
- pEepData->calTargetPower2G,
- AR5416_NUM_2G_20_TARGET_POWERS,
- &targetPowerOfdmExt, 4, true);
- }
- } else {
- numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
- SUB_NUM_CTL_MODES_AT_5G_40;
- pCtlMode = ctlModesFor11a;
-
- ath9k_hw_get_legacy_target_powers(ah, chan,
- pEepData->calTargetPower5G,
- AR5416_NUM_5G_20_TARGET_POWERS,
- &targetPowerOfdm, 4, false);
- ath9k_hw_get_target_powers(ah, chan,
- pEepData->calTargetPower5GHT20,
- AR5416_NUM_5G_20_TARGET_POWERS,
- &targetPowerHt20, 8, false);
-
- if (IS_CHAN_HT40(chan)) {
- numCtlModes = ARRAY_SIZE(ctlModesFor11a);
- ath9k_hw_get_target_powers(ah, chan,
- pEepData->calTargetPower5GHT40,
- AR5416_NUM_5G_40_TARGET_POWERS,
- &targetPowerHt40, 8, true);
- ath9k_hw_get_legacy_target_powers(ah, chan,
- pEepData->calTargetPower5G,
- AR5416_NUM_5G_20_TARGET_POWERS,
- &targetPowerOfdmExt, 4, true);
- }
- }
-
- for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
- bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
- (pCtlMode[ctlMode] == CTL_2GHT40);
- if (isHt40CtlMode)
- freq = centers.synth_center;
- else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
- freq = centers.ext_center;
- else
- freq = centers.ctl_center;
-
- if (ar5416_get_eep_ver(ahp) == 14 && ar5416_get_eep_rev(ahp) <= 2)
- twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
- "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
- "EXT_ADDITIVE %d\n",
- ctlMode, numCtlModes, isHt40CtlMode,
- (pCtlMode[ctlMode] & EXT_ADDITIVE));
-
- for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
- " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
- "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
- "chan %d\n",
- i, cfgCtl, pCtlMode[ctlMode],
- pEepData->ctlIndex[i], chan->channel);
-
- if ((((cfgCtl & ~CTL_MODE_M) |
- (pCtlMode[ctlMode] & CTL_MODE_M)) ==
- pEepData->ctlIndex[i]) ||
- (((cfgCtl & ~CTL_MODE_M) |
- (pCtlMode[ctlMode] & CTL_MODE_M)) ==
- ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
- rep = &(pEepData->ctlData[i]);
-
- twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
- rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
- IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
-
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
- " MATCH-EE_IDX %d: ch %d is2 %d "
- "2xMinEdge %d chainmask %d chains %d\n",
- i, freq, IS_CHAN_2GHZ(chan),
- twiceMinEdgePower, tx_chainmask,
- ar5416_get_ntxchains
- (tx_chainmask));
- if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
- twiceMaxEdgePower = min(twiceMaxEdgePower,
- twiceMinEdgePower);
- } else {
- twiceMaxEdgePower = twiceMinEdgePower;
- break;
- }
- }
- }
-
- minCtlPower = min(twiceMaxEdgePower, scaledPower);
-
- DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
- " SEL-Min ctlMode %d pCtlMode %d "
- "2xMaxEdge %d sP %d minCtlPwr %d\n",
- ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
- scaledPower, minCtlPower);
-
- switch (pCtlMode[ctlMode]) {
- case CTL_11B:
- for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
- targetPowerCck.tPow2x[i] =
- min((u16)targetPowerCck.tPow2x[i],
- minCtlPower);
- }
- break;
- case CTL_11A:
- case CTL_11G:
- for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
- targetPowerOfdm.tPow2x[i] =
- min((u16)targetPowerOfdm.tPow2x[i],
- minCtlPower);
- }
- break;
- case CTL_5GHT20:
- case CTL_2GHT20:
- for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
- targetPowerHt20.tPow2x[i] =
- min((u16)targetPowerHt20.tPow2x[i],
- minCtlPower);
- }
- break;
- case CTL_11B_EXT:
- targetPowerCckExt.tPow2x[0] = min((u16)
- targetPowerCckExt.tPow2x[0],
- minCtlPower);
- break;
- case CTL_11A_EXT:
- case CTL_11G_EXT:
- targetPowerOfdmExt.tPow2x[0] = min((u16)
- targetPowerOfdmExt.tPow2x[0],
- minCtlPower);
- break;
- case CTL_5GHT40:
- case CTL_2GHT40:
- for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
- targetPowerHt40.tPow2x[i] =
- min((u16)targetPowerHt40.tPow2x[i],
- minCtlPower);
- }
- break;
- default:
- break;
- }
- }
-
- ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
- ratesArray[rate18mb] = ratesArray[rate24mb] =
- targetPowerOfdm.tPow2x[0];
- ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
- ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
- ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
- ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
-
- for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
- ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
-
- if (IS_CHAN_2GHZ(chan)) {
- ratesArray[rate1l] = targetPowerCck.tPow2x[0];
- ratesArray[rate2s] = ratesArray[rate2l] =
- targetPowerCck.tPow2x[1];
- ratesArray[rate5_5s] = ratesArray[rate5_5l] =
- targetPowerCck.tPow2x[2];
- ;
- ratesArray[rate11s] = ratesArray[rate11l] =
- targetPowerCck.tPow2x[3];
- ;
- }
- if (IS_CHAN_HT40(chan)) {
- for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
- ratesArray[rateHt40_0 + i] =
- targetPowerHt40.tPow2x[i];
- }
- ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
- ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
- ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
- if (IS_CHAN_2GHZ(chan)) {
- ratesArray[rateExtCck] =
- targetPowerCckExt.tPow2x[0];
- }
- }
- return true;
-}
-
-static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
+static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
struct ath9k_channel *chan,
int16_t *ratesArray,
u16 cfgCtl,
@@ -1515,8 +817,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
u16 twiceMaxRegulatoryPower,
u16 powerLimit)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
+ struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
static const u16 tpScaleReductionTable[5] =
{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
@@ -1544,7 +845,7 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
int tx_chainmask;
u16 twiceMinEdgePower;
- tx_chainmask = ahp->ah_txchainmask;
+ tx_chainmask = ah->txchainmask;
ath9k_hw_get_channel_centers(ah, chan, &centers);
@@ -1555,9 +856,9 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
- if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
+ if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
maxRegAllowedPower -=
- (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
+ (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
}
scaledPower = min(powerLimit, maxRegAllowedPower);
@@ -1605,8 +906,8 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
else
freq = centers.ctl_center;
- if (ar5416_get_eep_ver(ahp) == 14 &&
- ar5416_get_eep_rev(ahp) <= 2)
+ if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+ ah->eep_ops->get_eeprom_rev(ah) <= 2)
twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
@@ -1743,17 +1044,15 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hal *ah,
return true;
}
-static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u16 cfgCtl,
- u8 twiceAntennaReduction,
- u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ u16 cfgCtl,
+ u8 twiceAntennaReduction,
+ u8 twiceMaxRegulatoryPower,
+ u8 powerLimit)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *pEepData = &ahp->ah_eeprom.def;
- struct modal_eep_header *pModal =
- &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
+ struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+ struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
int16_t ratesArray[Ar5416RateSize];
int16_t txPowerIndexOffset = 0;
u8 ht40PowerIncForPdadc = 2;
@@ -1766,7 +1065,7 @@ static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
}
- if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
+ if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
&ratesArray[0], cfgCtl,
twiceAntennaReduction,
twiceMaxRegulatoryPower,
@@ -1777,7 +1076,7 @@ static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
return -EIO;
}
- if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) {
+ if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"ath9k_hw_set_txpower: unable to set power table\n");
return -EIO;
@@ -1856,10 +1155,6 @@ static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
}
- REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
- ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
- | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
-
i = rate6mb;
if (IS_CHAN_HT40(chan))
@@ -1868,272 +1163,572 @@ static int ath9k_hw_def_set_txpower(struct ath_hal *ah,
i = rateHt20_0;
if (AR_SREV_9280_10_OR_LATER(ah))
- ah->ah_maxPowerLevel =
+ ah->regulatory.max_power_level =
ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
else
- ah->ah_maxPowerLevel = ratesArray[i];
+ ah->regulatory.max_power_level = ratesArray[i];
return 0;
}
-static int ath9k_hw_4k_set_txpower(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u16 cfgCtl,
- u8 twiceAntennaReduction,
- u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
+ struct ath9k_channel *chan)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *pEepData = &ahp->ah_eeprom.map4k;
- struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
- int16_t ratesArray[Ar5416RateSize];
- int16_t txPowerIndexOffset = 0;
- u8 ht40PowerIncForPdadc = 2;
- int i;
+ struct modal_eep_4k_header *pModal;
+ struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+ u8 biaslevel;
- memset(ratesArray, 0, sizeof(ratesArray));
+ if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+ return;
- if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
- ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
- }
+ if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+ return;
- if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
- &ratesArray[0], cfgCtl,
- twiceAntennaReduction,
- twiceMaxRegulatoryPower,
- powerLimit)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set "
- "tx power per rate table\n");
- return -EIO;
- }
+ pModal = &eep->modalHeader;
- if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "ath9k_hw_set_txpower: unable to set power table\n");
- return -EIO;
+ if (pModal->xpaBiasLvl != 0xff) {
+ biaslevel = pModal->xpaBiasLvl;
+ INI_RA(&ah->iniAddac, 7, 1) =
+ (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
}
+}
- for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
- ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
- if (ratesArray[i] > AR5416_MAX_RATE_POWER)
- ratesArray[i] = AR5416_MAX_RATE_POWER;
- }
+static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
+ struct modal_eep_4k_header *pModal,
+ struct ar5416_eeprom_4k *eep,
+ u8 txRxAttenLocal, int regChainOffset)
+{
+ REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+ pModal->antCtrlChain[0]);
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- for (i = 0; i < Ar5416RateSize; i++)
- ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+ REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
+ (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
+ ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+ AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+ SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+ SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+ if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_3) {
+ txRxAttenLocal = pModal->txRxAttenCh[0];
+
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+ pModal->xatten2Margin[0]);
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
}
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
- ATH9K_POW_SM(ratesArray[rate18mb], 24)
- | ATH9K_POW_SM(ratesArray[rate12mb], 16)
- | ATH9K_POW_SM(ratesArray[rate9mb], 8)
- | ATH9K_POW_SM(ratesArray[rate6mb], 0));
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
- ATH9K_POW_SM(ratesArray[rate54mb], 24)
- | ATH9K_POW_SM(ratesArray[rate48mb], 16)
- | ATH9K_POW_SM(ratesArray[rate36mb], 8)
- | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+ REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+ AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+ REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+ AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
- if (IS_CHAN_2GHZ(chan)) {
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
- ATH9K_POW_SM(ratesArray[rate2s], 24)
- | ATH9K_POW_SM(ratesArray[rate2l], 16)
- | ATH9K_POW_SM(ratesArray[rateXr], 8)
- | ATH9K_POW_SM(ratesArray[rate1l], 0));
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
- ATH9K_POW_SM(ratesArray[rate11s], 24)
- | ATH9K_POW_SM(ratesArray[rate11l], 16)
- | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
- | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+ if (AR_SREV_9285_11(ah))
+ REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+}
+
+static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+{
+ struct modal_eep_4k_header *pModal;
+ struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+ u8 txRxAttenLocal;
+ u8 ob[5], db1[5], db2[5];
+ u8 ant_div_control1, ant_div_control2;
+ u32 regVal;
+
+ pModal = &eep->modalHeader;
+ txRxAttenLocal = 23;
+
+ REG_WRITE(ah, AR_PHY_SWITCH_COM,
+ ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
+
+ /* Single chain for 4K EEPROM*/
+ ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0);
+
+ /* Initialize Ant Diversity settings from EEPROM */
+ if (pModal->version == 3) {
+ ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
+ ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
+ regVal = REG_READ(ah, 0x99ac);
+ regVal &= (~(0x7f000000));
+ regVal |= ((ant_div_control1 & 0x1) << 24);
+ regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
+ regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
+ regVal |= ((ant_div_control2 & 0x3) << 25);
+ regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
+ REG_WRITE(ah, 0x99ac, regVal);
+ regVal = REG_READ(ah, 0x99ac);
+ regVal = REG_READ(ah, 0xa208);
+ regVal &= (~(0x1 << 13));
+ regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
+ REG_WRITE(ah, 0xa208, regVal);
+ regVal = REG_READ(ah, 0xa208);
}
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
- ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
- | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
- | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
- | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
- ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
- | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
- | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
- | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+ if (pModal->version >= 2) {
+ ob[0] = (pModal->ob_01 & 0xf);
+ ob[1] = (pModal->ob_01 >> 4) & 0xf;
+ ob[2] = (pModal->ob_234 & 0xf);
+ ob[3] = ((pModal->ob_234 >> 4) & 0xf);
+ ob[4] = ((pModal->ob_234 >> 8) & 0xf);
- if (IS_CHAN_HT40(chan)) {
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
- ATH9K_POW_SM(ratesArray[rateHt40_3] +
- ht40PowerIncForPdadc, 24)
- | ATH9K_POW_SM(ratesArray[rateHt40_2] +
- ht40PowerIncForPdadc, 16)
- | ATH9K_POW_SM(ratesArray[rateHt40_1] +
- ht40PowerIncForPdadc, 8)
- | ATH9K_POW_SM(ratesArray[rateHt40_0] +
- ht40PowerIncForPdadc, 0));
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
- ATH9K_POW_SM(ratesArray[rateHt40_7] +
- ht40PowerIncForPdadc, 24)
- | ATH9K_POW_SM(ratesArray[rateHt40_6] +
- ht40PowerIncForPdadc, 16)
- | ATH9K_POW_SM(ratesArray[rateHt40_5] +
- ht40PowerIncForPdadc, 8)
- | ATH9K_POW_SM(ratesArray[rateHt40_4] +
- ht40PowerIncForPdadc, 0));
+ db1[0] = (pModal->db1_01 & 0xf);
+ db1[1] = ((pModal->db1_01 >> 4) & 0xf);
+ db1[2] = (pModal->db1_234 & 0xf);
+ db1[3] = ((pModal->db1_234 >> 4) & 0xf);
+ db1[4] = ((pModal->db1_234 >> 8) & 0xf);
- REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
- ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
- | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
- | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
- | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+ db2[0] = (pModal->db2_01 & 0xf);
+ db2[1] = ((pModal->db2_01 >> 4) & 0xf);
+ db2[2] = (pModal->db2_234 & 0xf);
+ db2[3] = ((pModal->db2_234 >> 4) & 0xf);
+ db2[4] = ((pModal->db2_234 >> 8) & 0xf);
+
+ } else if (pModal->version == 1) {
+ ob[0] = (pModal->ob_01 & 0xf);
+ ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
+ db1[0] = (pModal->db1_01 & 0xf);
+ db1[1] = db1[2] = db1[3] =
+ db1[4] = ((pModal->db1_01 >> 4) & 0xf);
+ db2[0] = (pModal->db2_01 & 0xf);
+ db2[1] = db2[2] = db2[3] =
+ db2[4] = ((pModal->db2_01 >> 4) & 0xf);
+ } else {
+ int i;
+ for (i = 0; i < 5; i++) {
+ ob[i] = pModal->ob_01;
+ db1[i] = pModal->db1_01;
+ db2[i] = pModal->db1_01;
+ }
}
- i = rate6mb;
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
- if (IS_CHAN_HT40(chan))
- i = rateHt40_0;
- else if (IS_CHAN_HT20(chan))
- i = rateHt20_0;
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+ AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
- if (AR_SREV_9280_10_OR_LATER(ah))
- ah->ah_maxPowerLevel =
- ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
- else
- ah->ah_maxPowerLevel = ratesArray[i];
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
+ ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+ AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
- return 0;
-}
-static int (*ath9k_set_txpower[]) (struct ath_hal *,
- struct ath9k_channel *,
- u16, u8, u8, u8) = {
- ath9k_hw_def_set_txpower,
- ath9k_hw_4k_set_txpower
-};
+ if (AR_SREV_9285_11(ah))
+ REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+
+ REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+ pModal->switchSettling);
+ REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
+ pModal->adcDesiredSize);
+
+ REG_WRITE(ah, AR_PHY_RF_CTL4,
+ SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
+ SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
+ SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) |
+ SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+ REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+ pModal->txEndToRxOn);
+ REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
+ pModal->thresh62);
+ REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
+ pModal->thresh62);
+
+ if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_2) {
+ REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
+ pModal->txFrameToDataStart);
+ REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
+ pModal->txFrameToPaOn);
+ }
-int ath9k_hw_set_txpower(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u16 cfgCtl,
- u8 twiceAntennaReduction,
- u8 twiceMaxRegulatoryPower,
- u8 powerLimit)
+ if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_3) {
+ if (IS_CHAN_HT40(chan))
+ REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+ AR_PHY_SETTLING_SWITCH,
+ pModal->swSettleHt40);
+ }
+}
+
+static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
+ struct ath9k_channel *chan)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+ struct modal_eep_4k_header *pModal = &eep->modalHeader;
- return ath9k_set_txpower[ahp->ah_eep_map](ah, chan, cfgCtl,
- twiceAntennaReduction, twiceMaxRegulatoryPower,
- powerLimit);
+ return pModal->antCtrlCommon & 0xFFFF;
}
-static void ath9k_hw_set_def_addac(struct ath_hal *ah,
- struct ath9k_channel *chan)
+static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
+ enum ieee80211_band freq_band)
{
-#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
- struct modal_eep_header *pModal;
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
- u8 biaslevel;
+ return 1;
+}
- if (ah->ah_macVersion != AR_SREV_VERSION_9160)
- return;
+static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
+{
+#define EEP_MAP4K_SPURCHAN \
+ (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
- if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
- return;
+ u16 spur_val = AR_NO_SPUR;
- pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+ DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+ "Getting spur idx %d is2Ghz. %d val %x\n",
+ i, is2GHz, ah->config.spurchans[i][is2GHz]);
- if (pModal->xpaBiasLvl != 0xff) {
- biaslevel = pModal->xpaBiasLvl;
- } else {
- u16 resetFreqBin, freqBin, freqCount = 0;
- struct chan_centers centers;
+ switch (ah->config.spurmode) {
+ case SPUR_DISABLE:
+ break;
+ case SPUR_ENABLE_IOCTL:
+ spur_val = ah->config.spurchans[i][is2GHz];
+ DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+ "Getting spur val from new loc. %d\n", spur_val);
+ break;
+ case SPUR_ENABLE_EEPROM:
+ spur_val = EEP_MAP4K_SPURCHAN;
+ break;
+ }
- ath9k_hw_get_channel_centers(ah, chan, &centers);
+ return spur_val;
- resetFreqBin = FREQ2FBIN(centers.synth_center,
- IS_CHAN_2GHZ(chan));
- freqBin = XPA_LVL_FREQ(0) & 0xff;
- biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
+#undef EEP_MAP4K_SPURCHAN
+}
- freqCount++;
+static struct eeprom_ops eep_4k_ops = {
+ .check_eeprom = ath9k_hw_4k_check_eeprom,
+ .get_eeprom = ath9k_hw_4k_get_eeprom,
+ .fill_eeprom = ath9k_hw_4k_fill_eeprom,
+ .get_eeprom_ver = ath9k_hw_4k_get_eeprom_ver,
+ .get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev,
+ .get_num_ant_config = ath9k_hw_4k_get_num_ant_config,
+ .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg,
+ .set_board_values = ath9k_hw_4k_set_board_values,
+ .set_addac = ath9k_hw_4k_set_addac,
+ .set_txpower = ath9k_hw_4k_set_txpower,
+ .get_spur_channel = ath9k_hw_4k_get_spur_channel
+};
- while (freqCount < 3) {
- if (XPA_LVL_FREQ(freqCount) == 0x0)
- break;
+/************************************************/
+/* EEPROM Operations for non-4K (Default) cards */
+/************************************************/
- freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
- if (resetFreqBin >= freqBin)
- biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
- else
- break;
- freqCount++;
- }
- }
+static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
+{
+ return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
+}
- if (IS_CHAN_2GHZ(chan)) {
- INI_RA(&ahp->ah_iniAddac, 7, 1) = (INI_RA(&ahp->ah_iniAddac,
- 7, 1) & (~0x18)) | biaslevel << 3;
- } else {
- INI_RA(&ahp->ah_iniAddac, 6, 1) = (INI_RA(&ahp->ah_iniAddac,
- 6, 1) & (~0xc0)) | biaslevel << 6;
+static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
+{
+ return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
+}
+
+static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
+{
+#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
+ u16 *eep_data = (u16 *)&ah->eeprom.def;
+ int addr, ar5416_eep_start_loc = 0x100;
+
+ for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
+ if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
+ eep_data)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "Unable to read eeprom region\n");
+ return false;
+ }
+ eep_data++;
}
-#undef XPA_LVL_FREQ
+ return true;
+#undef SIZE_EEPROM_DEF
}
-static void ath9k_hw_set_4k_addac(struct ath_hal *ah,
- struct ath9k_channel *chan)
+static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
{
- struct modal_eep_4k_header *pModal;
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
- u8 biaslevel;
+ struct ar5416_eeprom_def *eep =
+ (struct ar5416_eeprom_def *) &ah->eeprom.def;
+ u16 *eepdata, temp, magic, magic2;
+ u32 sum = 0, el;
+ bool need_swap = false;
+ int i, addr, size;
- if (ah->ah_macVersion != AR_SREV_VERSION_9160)
- return;
+ if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n");
+ return false;
+ }
- if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
- return;
+ if (!ath9k_hw_use_flash(ah)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Read Magic = 0x%04X\n", magic);
- pModal = &eep->modalHeader;
+ if (magic != AR5416_EEPROM_MAGIC) {
+ magic2 = swab16(magic);
- if (pModal->xpaBiasLvl != 0xff) {
- biaslevel = pModal->xpaBiasLvl;
- INI_RA(&ahp->ah_iniAddac, 7, 1) =
- (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
+ if (magic2 == AR5416_EEPROM_MAGIC) {
+ size = sizeof(struct ar5416_eeprom_def);
+ need_swap = true;
+ eepdata = (u16 *) (&ah->eeprom);
+
+ for (addr = 0; addr < size / sizeof(u16); addr++) {
+ temp = swab16(*eepdata);
+ *eepdata = temp;
+ eepdata++;
+ }
+ } else {
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "Invalid EEPROM Magic. "
+ "Endianness mismatch.\n");
+ return -EINVAL;
+ }
+ }
}
-}
-static void (*ath9k_set_addac[]) (struct ath_hal *, struct ath9k_channel *) = {
- ath9k_hw_set_def_addac,
- ath9k_hw_set_4k_addac
-};
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
+ need_swap ? "True" : "False");
+
+ if (need_swap)
+ el = swab16(ah->eeprom.def.baseEepHeader.length);
+ else
+ el = ah->eeprom.def.baseEepHeader.length;
+
+ if (el > sizeof(struct ar5416_eeprom_def))
+ el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
+ else
+ el = el / sizeof(u16);
+
+ eepdata = (u16 *)(&ah->eeprom);
+
+ for (i = 0; i < el; i++)
+ sum ^= *eepdata++;
+
+ if (need_swap) {
+ u32 integer, j;
+ u16 word;
+
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "EEPROM Endianness is not native.. Changing.\n");
+
+ word = swab16(eep->baseEepHeader.length);
+ eep->baseEepHeader.length = word;
+
+ word = swab16(eep->baseEepHeader.checksum);
+ eep->baseEepHeader.checksum = word;
+
+ word = swab16(eep->baseEepHeader.version);
+ eep->baseEepHeader.version = word;
+
+ word = swab16(eep->baseEepHeader.regDmn[0]);
+ eep->baseEepHeader.regDmn[0] = word;
+
+ word = swab16(eep->baseEepHeader.regDmn[1]);
+ eep->baseEepHeader.regDmn[1] = word;
+
+ word = swab16(eep->baseEepHeader.rfSilent);
+ eep->baseEepHeader.rfSilent = word;
+
+ word = swab16(eep->baseEepHeader.blueToothOptions);
+ eep->baseEepHeader.blueToothOptions = word;
+
+ word = swab16(eep->baseEepHeader.deviceCap);
+ eep->baseEepHeader.deviceCap = word;
+
+ for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
+ struct modal_eep_header *pModal =
+ &eep->modalHeader[j];
+ integer = swab32(pModal->antCtrlCommon);
+ pModal->antCtrlCommon = integer;
-void ath9k_hw_set_addac(struct ath_hal *ah, struct ath9k_channel *chan)
+ for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+ integer = swab32(pModal->antCtrlChain[i]);
+ pModal->antCtrlChain[i] = integer;
+ }
+
+ for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+ word = swab16(pModal->spurChans[i].spurChan);
+ pModal->spurChans[i].spurChan = word;
+ }
+ }
+ }
+
+ if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
+ ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+ sum, ah->eep_ops->get_eeprom_ver(ah));
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
+ enum eeprom_param param)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+ struct modal_eep_header *pModal = eep->modalHeader;
+ struct base_eep_header *pBase = &eep->baseEepHeader;
- ath9k_set_addac[ahp->ah_eep_map](ah, chan);
+ switch (param) {
+ case EEP_NFTHRESH_5:
+ return pModal[0].noiseFloorThreshCh[0];
+ case EEP_NFTHRESH_2:
+ return pModal[1].noiseFloorThreshCh[0];
+ case AR_EEPROM_MAC(0):
+ return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+ case AR_EEPROM_MAC(1):
+ return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+ case AR_EEPROM_MAC(2):
+ return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+ case EEP_REG_0:
+ return pBase->regDmn[0];
+ case EEP_REG_1:
+ return pBase->regDmn[1];
+ case EEP_OP_CAP:
+ return pBase->deviceCap;
+ case EEP_OP_MODE:
+ return pBase->opCapFlags;
+ case EEP_RF_SILENT:
+ return pBase->rfSilent;
+ case EEP_OB_5:
+ return pModal[0].ob;
+ case EEP_DB_5:
+ return pModal[0].db;
+ case EEP_OB_2:
+ return pModal[1].ob;
+ case EEP_DB_2:
+ return pModal[1].db;
+ case EEP_MINOR_REV:
+ return AR5416_VER_MASK;
+ case EEP_TX_MASK:
+ return pBase->txMask;
+ case EEP_RX_MASK:
+ return pBase->rxMask;
+ case EEP_RXGAIN_TYPE:
+ return pBase->rxGainType;
+ case EEP_TXGAIN_TYPE:
+ return pBase->txGainType;
+ case EEP_OL_PWRCTRL:
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+ return pBase->openLoopPwrCntl ? true : false;
+ else
+ return false;
+ case EEP_RC_CHAIN_MASK:
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+ return pBase->rcChainMask;
+ else
+ return 0;
+ case EEP_DAC_HPWR_5G:
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
+ return pBase->dacHiPwrMode_5G;
+ else
+ return 0;
+ case EEP_FRAC_N_5G:
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
+ return pBase->frac_n_5g;
+ else
+ return 0;
+ default:
+ return 0;
+ }
}
+static void ath9k_hw_def_set_gain(struct ath_hw *ah,
+ struct modal_eep_header *pModal,
+ struct ar5416_eeprom_def *eep,
+ u8 txRxAttenLocal, int regChainOffset, int i)
+{
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
+ txRxAttenLocal = pModal->txRxAttenCh[i];
+
+ if (AR_SREV_9280_10_OR_LATER(ah)) {
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+ pModal->bswMargin[i]);
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+ pModal->bswAtten[i]);
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+ pModal->xatten2Margin[i]);
+ REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ AR_PHY_GAIN_2GHZ_XATTEN2_DB,
+ pModal->xatten2Db[i]);
+ } else {
+ REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+ ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
+ | SM(pModal-> bswMargin[i],
+ AR_PHY_GAIN_2GHZ_BSW_MARGIN));
+ REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+ (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+ ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
+ | SM(pModal->bswAtten[i],
+ AR_PHY_GAIN_2GHZ_BSW_ATTEN));
+ }
+ }
+ if (AR_SREV_9280_10_OR_LATER(ah)) {
+ REG_RMW_FIELD(ah,
+ AR_PHY_RXGAIN + regChainOffset,
+ AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+ REG_RMW_FIELD(ah,
+ AR_PHY_RXGAIN + regChainOffset,
+ AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
+ } else {
+ REG_WRITE(ah,
+ AR_PHY_RXGAIN + regChainOffset,
+ (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
+ ~AR_PHY_RXGAIN_TXRX_ATTEN)
+ | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
+ REG_WRITE(ah,
+ AR_PHY_GAIN_2GHZ + regChainOffset,
+ (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+ ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
+ SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
+ }
+}
-/* XXX: Clean me up, make me more legible */
-static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
- struct ath9k_channel *chan)
+static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
+ struct ath9k_channel *chan)
{
struct modal_eep_header *pModal;
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+ struct ar5416_eeprom_def *eep = &ah->eeprom.def;
int i, regChainOffset;
u8 txRxAttenLocal;
- u16 ant_config;
pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-
txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
- ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config);
- REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
+ REG_WRITE(ah, AR_PHY_SWITCH_COM,
+ ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
if (AR_SREV_9280(ah)) {
@@ -2141,9 +1736,8 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
break;
}
- if (AR_SREV_5416_V20_OR_LATER(ah) &&
- (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
- && (i != 0))
+ if (AR_SREV_5416_20_OR_LATER(ah) &&
+ (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
regChainOffset = (i == 1) ? 0x2000 : 0x1000;
else
regChainOffset = i * 0x1000;
@@ -2152,9 +1746,7 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
pModal->antCtrlChain[i]);
REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
- (REG_READ(ah,
- AR_PHY_TIMING_CTRL4(0) +
- regChainOffset) &
+ (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
SM(pModal->iqCalICh[i],
@@ -2162,89 +1754,9 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
SM(pModal->iqCalQCh[i],
AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
- if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
- if ((eep->baseEepHeader.version &
- AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_3) {
- txRxAttenLocal = pModal->txRxAttenCh[i];
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- REG_RMW_FIELD(ah,
- AR_PHY_GAIN_2GHZ +
- regChainOffset,
- AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
- pModal->
- bswMargin[i]);
- REG_RMW_FIELD(ah,
- AR_PHY_GAIN_2GHZ +
- regChainOffset,
- AR_PHY_GAIN_2GHZ_XATTEN1_DB,
- pModal->
- bswAtten[i]);
- REG_RMW_FIELD(ah,
- AR_PHY_GAIN_2GHZ +
- regChainOffset,
- AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
- pModal->
- xatten2Margin[i]);
- REG_RMW_FIELD(ah,
- AR_PHY_GAIN_2GHZ +
- regChainOffset,
- AR_PHY_GAIN_2GHZ_XATTEN2_DB,
- pModal->
- xatten2Db[i]);
- } else {
- REG_WRITE(ah,
- AR_PHY_GAIN_2GHZ +
- regChainOffset,
- (REG_READ(ah,
- AR_PHY_GAIN_2GHZ +
- regChainOffset) &
- ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
- | SM(pModal->
- bswMargin[i],
- AR_PHY_GAIN_2GHZ_BSW_MARGIN));
- REG_WRITE(ah,
- AR_PHY_GAIN_2GHZ +
- regChainOffset,
- (REG_READ(ah,
- AR_PHY_GAIN_2GHZ +
- regChainOffset) &
- ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
- | SM(pModal->bswAtten[i],
- AR_PHY_GAIN_2GHZ_BSW_ATTEN));
- }
- }
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- REG_RMW_FIELD(ah,
- AR_PHY_RXGAIN +
- regChainOffset,
- AR9280_PHY_RXGAIN_TXRX_ATTEN,
- txRxAttenLocal);
- REG_RMW_FIELD(ah,
- AR_PHY_RXGAIN +
- regChainOffset,
- AR9280_PHY_RXGAIN_TXRX_MARGIN,
- pModal->rxTxMarginCh[i]);
- } else {
- REG_WRITE(ah,
- AR_PHY_RXGAIN + regChainOffset,
- (REG_READ(ah,
- AR_PHY_RXGAIN +
- regChainOffset) &
- ~AR_PHY_RXGAIN_TXRX_ATTEN) |
- SM(txRxAttenLocal,
- AR_PHY_RXGAIN_TXRX_ATTEN));
- REG_WRITE(ah,
- AR_PHY_GAIN_2GHZ +
- regChainOffset,
- (REG_READ(ah,
- AR_PHY_GAIN_2GHZ +
- regChainOffset) &
- ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
- SM(pModal->rxTxMarginCh[i],
- AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
- }
- }
+ if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah))
+ ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
+ regChainOffset, i);
}
if (AR_SREV_9280_10_OR_LATER(ah)) {
@@ -2291,8 +1803,6 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
AR_AN_TOP2_LOCALBIAS,
AR_AN_TOP2_LOCALBIAS_S,
pModal->local_bias);
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "ForceXPAon: %d\n",
- pModal->force_xpaon);
REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
pModal->force_xpaon);
}
@@ -2318,6 +1828,7 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
pModal->txEndToRxOn);
+
if (AR_SREV_9280_10_OR_LATER(ah)) {
REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
pModal->thresh62);
@@ -2332,8 +1843,7 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
pModal->thresh62);
}
- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
AR_PHY_TX_END_DATA_START,
pModal->txFrameToDataStart);
@@ -2341,296 +1851,880 @@ static bool ath9k_hw_eeprom_set_def_board_values(struct ath_hal *ah,
pModal->txFrameToPaOn);
}
- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_3) {
+ if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
if (IS_CHAN_HT40(chan))
REG_RMW_FIELD(ah, AR_PHY_SETTLING,
AR_PHY_SETTLING_SWITCH,
pModal->swSettleHt40);
}
- return true;
+ if (AR_SREV_9280_20_OR_LATER(ah) &&
+ AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+ REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
+ AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
+ pModal->miscBits);
+
+
+ if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
+ if (IS_CHAN_2GHZ(chan))
+ REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+ eep->baseEepHeader.dacLpMode);
+ else if (eep->baseEepHeader.dacHiPwrMode_5G)
+ REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
+ else
+ REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+ eep->baseEepHeader.dacLpMode);
+
+ REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
+ pModal->miscBits >> 2);
+
+ REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
+ AR_PHY_TX_DESIRED_SCALE_CCK,
+ eep->baseEepHeader.desiredScaleCCK);
+ }
}
-static bool ath9k_hw_eeprom_set_4k_board_values(struct ath_hal *ah,
- struct ath9k_channel *chan)
+static void ath9k_hw_def_set_addac(struct ath_hw *ah,
+ struct ath9k_channel *chan)
{
- struct modal_eep_4k_header *pModal;
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
- int regChainOffset;
- u8 txRxAttenLocal;
- u16 ant_config = 0;
- u8 ob[5], db1[5], db2[5];
- u8 ant_div_control1, ant_div_control2;
- u32 regVal;
+#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
+ struct modal_eep_header *pModal;
+ struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+ u8 biaslevel;
+ if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+ return;
- pModal = &eep->modalHeader;
+ if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+ return;
- txRxAttenLocal = 23;
+ pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
- ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config);
- REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
+ if (pModal->xpaBiasLvl != 0xff) {
+ biaslevel = pModal->xpaBiasLvl;
+ } else {
+ u16 resetFreqBin, freqBin, freqCount = 0;
+ struct chan_centers centers;
- regChainOffset = 0;
- REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
- pModal->antCtrlChain[0]);
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
- REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
- (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
- ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
- AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
- SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
- SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+ resetFreqBin = FREQ2FBIN(centers.synth_center,
+ IS_CHAN_2GHZ(chan));
+ freqBin = XPA_LVL_FREQ(0) & 0xff;
+ biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_3) {
- txRxAttenLocal = pModal->txRxAttenCh[0];
- REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
- AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
- REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
- AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
- REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
- AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
- pModal->xatten2Margin[0]);
- REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
- AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
- }
+ freqCount++;
- REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
- AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
- REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
- AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+ while (freqCount < 3) {
+ if (XPA_LVL_FREQ(freqCount) == 0x0)
+ break;
- if (AR_SREV_9285_11(ah))
- REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+ freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
+ if (resetFreqBin >= freqBin)
+ biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
+ else
+ break;
+ freqCount++;
+ }
+ }
- /* Initialize Ant Diversity settings from EEPROM */
- if (pModal->version == 3) {
- ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
- ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
- regVal = REG_READ(ah, 0x99ac);
- regVal &= (~(0x7f000000));
- regVal |= ((ant_div_control1 & 0x1) << 24);
- regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
- regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
- regVal |= ((ant_div_control2 & 0x3) << 25);
- regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
- REG_WRITE(ah, 0x99ac, regVal);
- regVal = REG_READ(ah, 0x99ac);
- regVal = REG_READ(ah, 0xa208);
- regVal &= (~(0x1 << 13));
- regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
- REG_WRITE(ah, 0xa208, regVal);
- regVal = REG_READ(ah, 0xa208);
+ if (IS_CHAN_2GHZ(chan)) {
+ INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
+ 7, 1) & (~0x18)) | biaslevel << 3;
+ } else {
+ INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
+ 6, 1) & (~0xc0)) | biaslevel << 6;
}
+#undef XPA_LVL_FREQ
+}
- if (pModal->version >= 2) {
- ob[0] = (pModal->ob_01 & 0xf);
- ob[1] = (pModal->ob_01 >> 4) & 0xf;
- ob[2] = (pModal->ob_234 & 0xf);
- ob[3] = ((pModal->ob_234 >> 4) & 0xf);
- ob[4] = ((pModal->ob_234 >> 8) & 0xf);
+static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ struct cal_data_per_freq *pRawDataSet,
+ u8 *bChans, u16 availPiers,
+ u16 tPdGainOverlap, int16_t *pMinCalPower,
+ u16 *pPdGainBoundaries, u8 *pPDADCValues,
+ u16 numXpdGains)
+{
+ int i, j, k;
+ int16_t ss;
+ u16 idxL = 0, idxR = 0, numPiers;
+ static u8 vpdTableL[AR5416_NUM_PD_GAINS]
+ [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+ static u8 vpdTableR[AR5416_NUM_PD_GAINS]
+ [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+ static u8 vpdTableI[AR5416_NUM_PD_GAINS]
+ [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
- db1[0] = (pModal->db1_01 & 0xf);
- db1[1] = ((pModal->db1_01 >> 4) & 0xf);
- db1[2] = (pModal->db1_234 & 0xf);
- db1[3] = ((pModal->db1_234 >> 4) & 0xf);
- db1[4] = ((pModal->db1_234 >> 8) & 0xf);
+ u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+ u8 minPwrT4[AR5416_NUM_PD_GAINS];
+ u8 maxPwrT4[AR5416_NUM_PD_GAINS];
+ int16_t vpdStep;
+ int16_t tmpVal;
+ u16 sizeCurrVpdTable, maxIndex, tgtIndex;
+ bool match;
+ int16_t minDelta = 0;
+ struct chan_centers centers;
- db2[0] = (pModal->db2_01 & 0xf);
- db2[1] = ((pModal->db2_01 >> 4) & 0xf);
- db2[2] = (pModal->db2_234 & 0xf);
- db2[3] = ((pModal->db2_234 >> 4) & 0xf);
- db2[4] = ((pModal->db2_234 >> 8) & 0xf);
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
- } else if (pModal->version == 1) {
+ for (numPiers = 0; numPiers < availPiers; numPiers++) {
+ if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
+ break;
+ }
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "EEPROM Model version is set to 1 \n");
- ob[0] = (pModal->ob_01 & 0xf);
- ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
- db1[0] = (pModal->db1_01 & 0xf);
- db1[1] = db1[2] = db1[3] =
- db1[4] = ((pModal->db1_01 >> 4) & 0xf);
- db2[0] = (pModal->db2_01 & 0xf);
- db2[1] = db2[2] = db2[3] =
- db2[4] = ((pModal->db2_01 >> 4) & 0xf);
+ match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
+ IS_CHAN_2GHZ(chan)),
+ bChans, numPiers, &idxL, &idxR);
+
+ if (match) {
+ for (i = 0; i < numXpdGains; i++) {
+ minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
+ maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ pRawDataSet[idxL].pwrPdg[i],
+ pRawDataSet[idxL].vpdPdg[i],
+ AR5416_PD_GAIN_ICEPTS,
+ vpdTableI[i]);
+ }
} else {
- int i;
- for (i = 0; i < 5; i++) {
- ob[i] = pModal->ob_01;
- db1[i] = pModal->db1_01;
- db2[i] = pModal->db1_01;
+ for (i = 0; i < numXpdGains; i++) {
+ pVpdL = pRawDataSet[idxL].vpdPdg[i];
+ pPwrL = pRawDataSet[idxL].pwrPdg[i];
+ pVpdR = pRawDataSet[idxR].vpdPdg[i];
+ pPwrR = pRawDataSet[idxR].pwrPdg[i];
+
+ minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+ maxPwrT4[i] =
+ min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
+ pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
+
+
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ pPwrL, pVpdL,
+ AR5416_PD_GAIN_ICEPTS,
+ vpdTableL[i]);
+ ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+ pPwrR, pVpdR,
+ AR5416_PD_GAIN_ICEPTS,
+ vpdTableR[i]);
+
+ for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+ vpdTableI[i][j] =
+ (u8)(ath9k_hw_interpolate((u16)
+ FREQ2FBIN(centers.
+ synth_center,
+ IS_CHAN_2GHZ
+ (chan)),
+ bChans[idxL], bChans[idxR],
+ vpdTableL[i][j], vpdTableR[i][j]));
+ }
}
}
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
+ *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
- AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
+ k = 0;
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
- ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
- AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
+ for (i = 0; i < numXpdGains; i++) {
+ if (i == (numXpdGains - 1))
+ pPdGainBoundaries[i] =
+ (u16)(maxPwrT4[i] / 2);
+ else
+ pPdGainBoundaries[i] =
+ (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+ pPdGainBoundaries[i] =
+ min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
- if (AR_SREV_9285_11(ah))
- REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+ if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
+ minDelta = pPdGainBoundaries[0] - 23;
+ pPdGainBoundaries[0] = 23;
+ } else {
+ minDelta = 0;
+ }
- REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
- pModal->switchSettling);
- REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
- pModal->adcDesiredSize);
+ if (i == 0) {
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ ss = (int16_t)(0 - (minPwrT4[i] / 2));
+ else
+ ss = 0;
+ } else {
+ ss = (int16_t)((pPdGainBoundaries[i - 1] -
+ (minPwrT4[i] / 2)) -
+ tPdGainOverlap + 1 + minDelta);
+ }
+ vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+ vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
- REG_WRITE(ah, AR_PHY_RF_CTL4,
- SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
- SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
- SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) |
- SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+ while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+ tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+ pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+ ss++;
+ }
- REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
- pModal->txEndToRxOn);
- REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
- pModal->thresh62);
- REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
- pModal->thresh62);
+ sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+ tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
+ (minPwrT4[i] / 2));
+ maxIndex = (tgtIndex < sizeCurrVpdTable) ?
+ tgtIndex : sizeCurrVpdTable;
- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
- REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
- pModal->txFrameToDataStart);
- REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
- pModal->txFrameToPaOn);
+ while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+ pPDADCValues[k++] = vpdTableI[i][ss++];
+ }
+
+ vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+ vpdTableI[i][sizeCurrVpdTable - 2]);
+ vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+ if (tgtIndex > maxIndex) {
+ while ((ss <= tgtIndex) &&
+ (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+ tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
+ (ss - maxIndex + 1) * vpdStep));
+ pPDADCValues[k++] = (u8)((tmpVal > 255) ?
+ 255 : tmpVal);
+ ss++;
+ }
+ }
}
- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_3) {
- if (IS_CHAN_HT40(chan))
- REG_RMW_FIELD(ah, AR_PHY_SETTLING,
- AR_PHY_SETTLING_SWITCH,
- pModal->swSettleHt40);
+ while (i < AR5416_PD_GAINS_IN_MASK) {
+ pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
+ i++;
}
- return true;
-}
+ while (k < AR5416_NUM_PDADC_VALUES) {
+ pPDADCValues[k] = pPDADCValues[k - 1];
+ k++;
+ }
-static bool (*ath9k_eeprom_set_board_values[])(struct ath_hal *,
- struct ath9k_channel *) = {
- ath9k_hw_eeprom_set_def_board_values,
- ath9k_hw_eeprom_set_4k_board_values
-};
+ return;
+}
-bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
- struct ath9k_channel *chan)
+static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ int16_t *pTxPowerIndexOffset)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
+#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
+#define SM_PDGAIN_B(x, y) \
+ SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
+
+ struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+ struct cal_data_per_freq *pRawDataset;
+ u8 *pCalBChans = NULL;
+ u16 pdGainOverlap_t2;
+ static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+ u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+ u16 numPiers, i, j;
+ int16_t tMinCalPower;
+ u16 numXpdGain, xpdMask;
+ u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+ u32 reg32, regOffset, regChainOffset;
+ int16_t modalIdx;
+
+ modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
+ xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
+
+ if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_2) {
+ pdGainOverlap_t2 =
+ pEepData->modalHeader[modalIdx].pdGainOverlap;
+ } else {
+ pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+ }
+
+ if (IS_CHAN_2GHZ(chan)) {
+ pCalBChans = pEepData->calFreqPier2G;
+ numPiers = AR5416_NUM_2G_CAL_PIERS;
+ } else {
+ pCalBChans = pEepData->calFreqPier5G;
+ numPiers = AR5416_NUM_5G_CAL_PIERS;
+ }
+
+ if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
+ pRawDataset = pEepData->calPierData2G[0];
+ ah->initPDADC = ((struct calDataPerFreqOpLoop *)
+ pRawDataset)->vpdPdg[0][0];
+ }
+
+ numXpdGain = 0;
+
+ for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+ if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+ if (numXpdGain >= AR5416_NUM_PD_GAINS)
+ break;
+ xpdGainValues[numXpdGain] =
+ (u16)(AR5416_PD_GAINS_IN_MASK - i);
+ numXpdGain++;
+ }
+ }
+
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+ (numXpdGain - 1) & 0x3);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+ xpdGainValues[0]);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+ xpdGainValues[1]);
+ REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+ xpdGainValues[2]);
+
+ for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+ if (AR_SREV_5416_20_OR_LATER(ah) &&
+ (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
+ (i != 0)) {
+ regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+ } else
+ regChainOffset = i * 0x1000;
+
+ if (pEepData->baseEepHeader.txMask & (1 << i)) {
+ if (IS_CHAN_2GHZ(chan))
+ pRawDataset = pEepData->calPierData2G[i];
+ else
+ pRawDataset = pEepData->calPierData5G[i];
+
+
+ if (OLC_FOR_AR9280_20_LATER) {
+ u8 pcdacIdx;
+ u8 txPower;
- return ath9k_eeprom_set_board_values[ahp->ah_eep_map](ah, chan);
+ ath9k_get_txgain_index(ah, chan,
+ (struct calDataPerFreqOpLoop *)pRawDataset,
+ pCalBChans, numPiers, &txPower, &pcdacIdx);
+ ath9k_olc_get_pdadcs(ah, pcdacIdx,
+ txPower/2, pdadcValues);
+ } else {
+ ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
+ chan, pRawDataset,
+ pCalBChans, numPiers,
+ pdGainOverlap_t2,
+ &tMinCalPower,
+ gainBoundaries,
+ pdadcValues,
+ numXpdGain);
+ }
+
+ if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
+ if (OLC_FOR_AR9280_20_LATER) {
+ REG_WRITE(ah,
+ AR_PHY_TPCRG5 + regChainOffset,
+ SM(0x6,
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
+ SM_PD_GAIN(1) | SM_PD_GAIN(2) |
+ SM_PD_GAIN(3) | SM_PD_GAIN(4));
+ } else {
+ REG_WRITE(ah,
+ AR_PHY_TPCRG5 + regChainOffset,
+ SM(pdGainOverlap_t2,
+ AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
+ SM_PDGAIN_B(0, 1) |
+ SM_PDGAIN_B(1, 2) |
+ SM_PDGAIN_B(2, 3) |
+ SM_PDGAIN_B(3, 4));
+ }
+ }
+
+ regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+ for (j = 0; j < 32; j++) {
+ reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+ ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+ ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
+ ((pdadcValues[4 * j + 3] & 0xFF) << 24);
+ REG_WRITE(ah, regOffset, reg32);
+
+ DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ "PDADC (%d,%4x): %4.4x %8.8x\n",
+ i, regChainOffset, regOffset,
+ reg32);
+ DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
+ "PDADC: Chain %d | PDADC %3d "
+ "Value %3d | PDADC %3d Value %3d | "
+ "PDADC %3d Value %3d | PDADC %3d "
+ "Value %3d |\n",
+ i, 4 * j, pdadcValues[4 * j],
+ 4 * j + 1, pdadcValues[4 * j + 1],
+ 4 * j + 2, pdadcValues[4 * j + 2],
+ 4 * j + 3,
+ pdadcValues[4 * j + 3]);
+
+ regOffset += 4;
+ }
+ }
+ }
+
+ *pTxPowerIndexOffset = 0;
+
+ return true;
+#undef SM_PD_GAIN
+#undef SM_PDGAIN_B
}
-static int ath9k_hw_get_def_eeprom_antenna_cfg(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u8 index, u16 *config)
+static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ int16_t *ratesArray,
+ u16 cfgCtl,
+ u16 AntennaReduction,
+ u16 twiceMaxRegulatoryPower,
+ u16 powerLimit)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
- struct modal_eep_header *pModal =
- &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
- struct base_eep_header *pBase = &eep->baseEepHeader;
+#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
+#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
- switch (index) {
- case 0:
- *config = pModal->antCtrlCommon & 0xFFFF;
- return 0;
+ struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+ u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+ static const u16 tpScaleReductionTable[5] =
+ { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+
+ int i;
+ int16_t twiceLargestAntenna;
+ struct cal_ctl_data *rep;
+ struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+ 0, { 0, 0, 0, 0}
+ };
+ struct cal_target_power_leg targetPowerOfdmExt = {
+ 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
+ 0, { 0, 0, 0, 0 }
+ };
+ struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+ 0, {0, 0, 0, 0}
+ };
+ u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+ u16 ctlModesFor11a[] =
+ { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
+ u16 ctlModesFor11g[] =
+ { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
+ CTL_2GHT40
+ };
+ u16 numCtlModes, *pCtlMode, ctlMode, freq;
+ struct chan_centers centers;
+ int tx_chainmask;
+ u16 twiceMinEdgePower;
+
+ tx_chainmask = ah->txchainmask;
+
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+ twiceLargestAntenna = max(
+ pEepData->modalHeader
+ [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
+ pEepData->modalHeader
+ [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
+
+ twiceLargestAntenna = max((u8)twiceLargestAntenna,
+ pEepData->modalHeader
+ [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
+
+ twiceLargestAntenna = (int16_t)min(AntennaReduction -
+ twiceLargestAntenna, 0);
+
+ maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+ if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
+ maxRegAllowedPower -=
+ (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
+ }
+
+ scaledPower = min(powerLimit, maxRegAllowedPower);
+
+ switch (ar5416_get_ntxchains(tx_chainmask)) {
case 1:
- if (pBase->version >= 0x0E0D) {
- if (pModal->useAnt1) {
- *config =
- ((pModal->antCtrlCommon & 0xFFFF0000) >> 16);
- return 0;
- }
- }
break;
- default:
+ case 2:
+ scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+ break;
+ case 3:
+ scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
break;
}
- return -EINVAL;
+ scaledPower = max((u16)0, scaledPower);
+
+ if (IS_CHAN_2GHZ(chan)) {
+ numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
+ SUB_NUM_CTL_MODES_AT_2G_40;
+ pCtlMode = ctlModesFor11g;
+
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPowerCck,
+ AR5416_NUM_2G_CCK_TARGET_POWERS,
+ &targetPowerCck, 4, false);
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPower2G,
+ AR5416_NUM_2G_20_TARGET_POWERS,
+ &targetPowerOfdm, 4, false);
+ ath9k_hw_get_target_powers(ah, chan,
+ pEepData->calTargetPower2GHT20,
+ AR5416_NUM_2G_20_TARGET_POWERS,
+ &targetPowerHt20, 8, false);
+
+ if (IS_CHAN_HT40(chan)) {
+ numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+ ath9k_hw_get_target_powers(ah, chan,
+ pEepData->calTargetPower2GHT40,
+ AR5416_NUM_2G_40_TARGET_POWERS,
+ &targetPowerHt40, 8, true);
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPowerCck,
+ AR5416_NUM_2G_CCK_TARGET_POWERS,
+ &targetPowerCckExt, 4, true);
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPower2G,
+ AR5416_NUM_2G_20_TARGET_POWERS,
+ &targetPowerOfdmExt, 4, true);
+ }
+ } else {
+ numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
+ SUB_NUM_CTL_MODES_AT_5G_40;
+ pCtlMode = ctlModesFor11a;
+
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPower5G,
+ AR5416_NUM_5G_20_TARGET_POWERS,
+ &targetPowerOfdm, 4, false);
+ ath9k_hw_get_target_powers(ah, chan,
+ pEepData->calTargetPower5GHT20,
+ AR5416_NUM_5G_20_TARGET_POWERS,
+ &targetPowerHt20, 8, false);
+
+ if (IS_CHAN_HT40(chan)) {
+ numCtlModes = ARRAY_SIZE(ctlModesFor11a);
+ ath9k_hw_get_target_powers(ah, chan,
+ pEepData->calTargetPower5GHT40,
+ AR5416_NUM_5G_40_TARGET_POWERS,
+ &targetPowerHt40, 8, true);
+ ath9k_hw_get_legacy_target_powers(ah, chan,
+ pEepData->calTargetPower5G,
+ AR5416_NUM_5G_20_TARGET_POWERS,
+ &targetPowerOfdmExt, 4, true);
+ }
+ }
+
+ for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+ bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+ (pCtlMode[ctlMode] == CTL_2GHT40);
+ if (isHt40CtlMode)
+ freq = centers.synth_center;
+ else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+ freq = centers.ext_center;
+ else
+ freq = centers.ctl_center;
+
+ if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+ ah->eep_ops->get_eeprom_rev(ah) <= 2)
+ twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
+ "EXT_ADDITIVE %d\n",
+ ctlMode, numCtlModes, isHt40CtlMode,
+ (pCtlMode[ctlMode] & EXT_ADDITIVE));
+
+ for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
+ "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
+ "chan %d\n",
+ i, cfgCtl, pCtlMode[ctlMode],
+ pEepData->ctlIndex[i], chan->channel);
+
+ if ((((cfgCtl & ~CTL_MODE_M) |
+ (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+ pEepData->ctlIndex[i]) ||
+ (((cfgCtl & ~CTL_MODE_M) |
+ (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+ ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
+ rep = &(pEepData->ctlData[i]);
+
+ twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
+ rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
+ IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
+
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ " MATCH-EE_IDX %d: ch %d is2 %d "
+ "2xMinEdge %d chainmask %d chains %d\n",
+ i, freq, IS_CHAN_2GHZ(chan),
+ twiceMinEdgePower, tx_chainmask,
+ ar5416_get_ntxchains
+ (tx_chainmask));
+ if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+ twiceMaxEdgePower = min(twiceMaxEdgePower,
+ twiceMinEdgePower);
+ } else {
+ twiceMaxEdgePower = twiceMinEdgePower;
+ break;
+ }
+ }
+ }
+
+ minCtlPower = min(twiceMaxEdgePower, scaledPower);
+
+ DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
+ " SEL-Min ctlMode %d pCtlMode %d "
+ "2xMaxEdge %d sP %d minCtlPwr %d\n",
+ ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
+ scaledPower, minCtlPower);
+
+ switch (pCtlMode[ctlMode]) {
+ case CTL_11B:
+ for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
+ targetPowerCck.tPow2x[i] =
+ min((u16)targetPowerCck.tPow2x[i],
+ minCtlPower);
+ }
+ break;
+ case CTL_11A:
+ case CTL_11G:
+ for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
+ targetPowerOfdm.tPow2x[i] =
+ min((u16)targetPowerOfdm.tPow2x[i],
+ minCtlPower);
+ }
+ break;
+ case CTL_5GHT20:
+ case CTL_2GHT20:
+ for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
+ targetPowerHt20.tPow2x[i] =
+ min((u16)targetPowerHt20.tPow2x[i],
+ minCtlPower);
+ }
+ break;
+ case CTL_11B_EXT:
+ targetPowerCckExt.tPow2x[0] = min((u16)
+ targetPowerCckExt.tPow2x[0],
+ minCtlPower);
+ break;
+ case CTL_11A_EXT:
+ case CTL_11G_EXT:
+ targetPowerOfdmExt.tPow2x[0] = min((u16)
+ targetPowerOfdmExt.tPow2x[0],
+ minCtlPower);
+ break;
+ case CTL_5GHT40:
+ case CTL_2GHT40:
+ for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+ targetPowerHt40.tPow2x[i] =
+ min((u16)targetPowerHt40.tPow2x[i],
+ minCtlPower);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
+ ratesArray[rate18mb] = ratesArray[rate24mb] =
+ targetPowerOfdm.tPow2x[0];
+ ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+ ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+ ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+ ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+ for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+ ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+ if (IS_CHAN_2GHZ(chan)) {
+ ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+ ratesArray[rate2s] = ratesArray[rate2l] =
+ targetPowerCck.tPow2x[1];
+ ratesArray[rate5_5s] = ratesArray[rate5_5l] =
+ targetPowerCck.tPow2x[2];
+ ;
+ ratesArray[rate11s] = ratesArray[rate11l] =
+ targetPowerCck.tPow2x[3];
+ ;
+ }
+ if (IS_CHAN_HT40(chan)) {
+ for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+ ratesArray[rateHt40_0 + i] =
+ targetPowerHt40.tPow2x[i];
+ }
+ ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+ ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
+ ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+ if (IS_CHAN_2GHZ(chan)) {
+ ratesArray[rateExtCck] =
+ targetPowerCckExt.tPow2x[0];
+ }
+ }
+ return true;
}
-static int ath9k_hw_get_4k_eeprom_antenna_cfg(struct ath_hal *ah,
+static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
struct ath9k_channel *chan,
- u8 index, u16 *config)
+ u16 cfgCtl,
+ u8 twiceAntennaReduction,
+ u8 twiceMaxRegulatoryPower,
+ u8 powerLimit)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
- struct modal_eep_4k_header *pModal = &eep->modalHeader;
+#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
+ struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+ struct modal_eep_header *pModal =
+ &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
+ int16_t ratesArray[Ar5416RateSize];
+ int16_t txPowerIndexOffset = 0;
+ u8 ht40PowerIncForPdadc = 2;
+ int i, cck_ofdm_delta = 0;
- switch (index) {
- case 0:
- *config = pModal->antCtrlCommon & 0xFFFF;
- return 0;
- default:
- break;
+ memset(ratesArray, 0, sizeof(ratesArray));
+
+ if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+ AR5416_EEP_MINOR_VER_2) {
+ ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
}
- return -EINVAL;
-}
+ if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
+ &ratesArray[0], cfgCtl,
+ twiceAntennaReduction,
+ twiceMaxRegulatoryPower,
+ powerLimit)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "ath9k_hw_set_txpower: unable to set "
+ "tx power per rate table\n");
+ return -EIO;
+ }
-static int (*ath9k_get_eeprom_antenna_cfg[])(struct ath_hal *,
- struct ath9k_channel *,
- u8, u16 *) = {
- ath9k_hw_get_def_eeprom_antenna_cfg,
- ath9k_hw_get_4k_eeprom_antenna_cfg
-};
+ if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) {
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "ath9k_hw_set_txpower: unable to set power table\n");
+ return -EIO;
+ }
-int ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal *ah,
- struct ath9k_channel *chan,
- u8 index, u16 *config)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+ ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
+ if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+ ratesArray[i] = AR5416_MAX_RATE_POWER;
+ }
- return ath9k_get_eeprom_antenna_cfg[ahp->ah_eep_map](ah, chan,
- index, config);
-}
+ if (AR_SREV_9280_10_OR_LATER(ah)) {
+ for (i = 0; i < Ar5416RateSize; i++)
+ ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+ }
-static u8 ath9k_hw_get_4k_num_ant_config(struct ath_hal *ah,
- enum ieee80211_band freq_band)
-{
- return 1;
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+ ATH9K_POW_SM(ratesArray[rate18mb], 24)
+ | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+ | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+ | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+ ATH9K_POW_SM(ratesArray[rate54mb], 24)
+ | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+ | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+ | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+ if (IS_CHAN_2GHZ(chan)) {
+ if (OLC_FOR_AR9280_20_LATER) {
+ cck_ofdm_delta = 2;
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+ ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
+ | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
+ | ATH9K_POW_SM(ratesArray[rateXr], 8)
+ | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+ ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
+ | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
+ | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
+ | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
+ } else {
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+ ATH9K_POW_SM(ratesArray[rate2s], 24)
+ | ATH9K_POW_SM(ratesArray[rate2l], 16)
+ | ATH9K_POW_SM(ratesArray[rateXr], 8)
+ | ATH9K_POW_SM(ratesArray[rate1l], 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+ ATH9K_POW_SM(ratesArray[rate11s], 24)
+ | ATH9K_POW_SM(ratesArray[rate11l], 16)
+ | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+ | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+ }
+ }
+
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+ ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+ | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+ | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+ | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+ ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+ | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+ | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+ | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+ if (IS_CHAN_HT40(chan)) {
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+ ATH9K_POW_SM(ratesArray[rateHt40_3] +
+ ht40PowerIncForPdadc, 24)
+ | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+ ht40PowerIncForPdadc, 16)
+ | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+ ht40PowerIncForPdadc, 8)
+ | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+ ht40PowerIncForPdadc, 0));
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+ ATH9K_POW_SM(ratesArray[rateHt40_7] +
+ ht40PowerIncForPdadc, 24)
+ | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+ ht40PowerIncForPdadc, 16)
+ | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+ ht40PowerIncForPdadc, 8)
+ | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+ ht40PowerIncForPdadc, 0));
+ if (OLC_FOR_AR9280_20_LATER) {
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+ ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+ | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
+ | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+ | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
+ } else {
+ REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+ ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+ | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+ | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+ | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+ }
+ }
+
+ REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
+ ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
+ | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
+
+ i = rate6mb;
+
+ if (IS_CHAN_HT40(chan))
+ i = rateHt40_0;
+ else if (IS_CHAN_HT20(chan))
+ i = rateHt20_0;
+
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ ah->regulatory.max_power_level =
+ ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+ else
+ ah->regulatory.max_power_level = ratesArray[i];
+
+ switch(ar5416_get_ntxchains(ah->txchainmask)) {
+ case 1:
+ break;
+ case 2:
+ ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
+ break;
+ case 3:
+ ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
+ break;
+ default:
+ DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+ "Invalid chainmask configuration\n");
+ break;
+ }
+
+ return 0;
}
-static u8 ath9k_hw_get_def_num_ant_config(struct ath_hal *ah,
+static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
enum ieee80211_band freq_band)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
+ struct ar5416_eeprom_def *eep = &ah->eeprom.def;
struct modal_eep_header *pModal =
&(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
struct base_eep_header *pBase = &eep->baseEepHeader;
@@ -2645,180 +2739,75 @@ static u8 ath9k_hw_get_def_num_ant_config(struct ath_hal *ah,
return num_ant_config;
}
-static u8 (*ath9k_get_num_ant_config[])(struct ath_hal *,
- enum ieee80211_band) = {
- ath9k_hw_get_def_num_ant_config,
- ath9k_hw_get_4k_num_ant_config
-};
-
-u8 ath9k_hw_get_num_ant_config(struct ath_hal *ah,
- enum ieee80211_band freq_band)
+static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
+ struct ath9k_channel *chan)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+ struct modal_eep_header *pModal =
+ &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
- return ath9k_get_num_ant_config[ahp->ah_eep_map](ah, freq_band);
+ return pModal->antCtrlCommon & 0xFFFF;
}
-u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah, u16 i, bool is2GHz)
+static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
{
-#define EEP_MAP4K_SPURCHAN \
- (ahp->ah_eeprom.map4k.modalHeader.spurChans[i].spurChan)
#define EEP_DEF_SPURCHAN \
- (ahp->ah_eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
- struct ath_hal_5416 *ahp = AH5416(ah);
+ (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
+
u16 spur_val = AR_NO_SPUR;
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"Getting spur idx %d is2Ghz. %d val %x\n",
- i, is2GHz, ah->ah_config.spurchans[i][is2GHz]);
+ i, is2GHz, ah->config.spurchans[i][is2GHz]);
- switch (ah->ah_config.spurmode) {
+ switch (ah->config.spurmode) {
case SPUR_DISABLE:
break;
case SPUR_ENABLE_IOCTL:
- spur_val = ah->ah_config.spurchans[i][is2GHz];
+ spur_val = ah->config.spurchans[i][is2GHz];
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"Getting spur val from new loc. %d\n", spur_val);
break;
case SPUR_ENABLE_EEPROM:
- if (ahp->ah_eep_map == EEP_MAP_4KBITS)
- spur_val = EEP_MAP4K_SPURCHAN;
- else
- spur_val = EEP_DEF_SPURCHAN;
+ spur_val = EEP_DEF_SPURCHAN;
break;
-
}
return spur_val;
-#undef EEP_DEF_SPURCHAN
-#undef EEP_MAP4K_SPURCHAN
-}
-
-static u32 ath9k_hw_get_eeprom_4k(struct ath_hal *ah,
- enum eeprom_param param)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_4k *eep = &ahp->ah_eeprom.map4k;
- struct modal_eep_4k_header *pModal = &eep->modalHeader;
- struct base_eep_header_4k *pBase = &eep->baseEepHeader;
-
- switch (param) {
- case EEP_NFTHRESH_2:
- return pModal[1].noiseFloorThreshCh[0];
- case AR_EEPROM_MAC(0):
- return pBase->macAddr[0] << 8 | pBase->macAddr[1];
- case AR_EEPROM_MAC(1):
- return pBase->macAddr[2] << 8 | pBase->macAddr[3];
- case AR_EEPROM_MAC(2):
- return pBase->macAddr[4] << 8 | pBase->macAddr[5];
- case EEP_REG_0:
- return pBase->regDmn[0];
- case EEP_REG_1:
- return pBase->regDmn[1];
- case EEP_OP_CAP:
- return pBase->deviceCap;
- case EEP_OP_MODE:
- return pBase->opCapFlags;
- case EEP_RF_SILENT:
- return pBase->rfSilent;
- case EEP_OB_2:
- return pModal->ob_01;
- case EEP_DB_2:
- return pModal->db1_01;
- case EEP_MINOR_REV:
- return pBase->version & AR5416_EEP_VER_MINOR_MASK;
- case EEP_TX_MASK:
- return pBase->txMask;
- case EEP_RX_MASK:
- return pBase->rxMask;
- default:
- return 0;
- }
-}
-
-static u32 ath9k_hw_get_eeprom_def(struct ath_hal *ah,
- enum eeprom_param param)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ar5416_eeprom_def *eep = &ahp->ah_eeprom.def;
- struct modal_eep_header *pModal = eep->modalHeader;
- struct base_eep_header *pBase = &eep->baseEepHeader;
- switch (param) {
- case EEP_NFTHRESH_5:
- return pModal[0].noiseFloorThreshCh[0];
- case EEP_NFTHRESH_2:
- return pModal[1].noiseFloorThreshCh[0];
- case AR_EEPROM_MAC(0):
- return pBase->macAddr[0] << 8 | pBase->macAddr[1];
- case AR_EEPROM_MAC(1):
- return pBase->macAddr[2] << 8 | pBase->macAddr[3];
- case AR_EEPROM_MAC(2):
- return pBase->macAddr[4] << 8 | pBase->macAddr[5];
- case EEP_REG_0:
- return pBase->regDmn[0];
- case EEP_REG_1:
- return pBase->regDmn[1];
- case EEP_OP_CAP:
- return pBase->deviceCap;
- case EEP_OP_MODE:
- return pBase->opCapFlags;
- case EEP_RF_SILENT:
- return pBase->rfSilent;
- case EEP_OB_5:
- return pModal[0].ob;
- case EEP_DB_5:
- return pModal[0].db;
- case EEP_OB_2:
- return pModal[1].ob;
- case EEP_DB_2:
- return pModal[1].db;
- case EEP_MINOR_REV:
- return pBase->version & AR5416_EEP_VER_MINOR_MASK;
- case EEP_TX_MASK:
- return pBase->txMask;
- case EEP_RX_MASK:
- return pBase->rxMask;
- case EEP_RXGAIN_TYPE:
- return pBase->rxGainType;
- case EEP_TXGAIN_TYPE:
- return pBase->txGainType;
-
- default:
- return 0;
- }
+#undef EEP_DEF_SPURCHAN
}
-static u32 (*ath9k_get_eeprom[])(struct ath_hal *, enum eeprom_param) = {
- ath9k_hw_get_eeprom_def,
- ath9k_hw_get_eeprom_4k
+static struct eeprom_ops eep_def_ops = {
+ .check_eeprom = ath9k_hw_def_check_eeprom,
+ .get_eeprom = ath9k_hw_def_get_eeprom,
+ .fill_eeprom = ath9k_hw_def_fill_eeprom,
+ .get_eeprom_ver = ath9k_hw_def_get_eeprom_ver,
+ .get_eeprom_rev = ath9k_hw_def_get_eeprom_rev,
+ .get_num_ant_config = ath9k_hw_def_get_num_ant_config,
+ .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg,
+ .set_board_values = ath9k_hw_def_set_board_values,
+ .set_addac = ath9k_hw_def_set_addac,
+ .set_txpower = ath9k_hw_def_set_txpower,
+ .get_spur_channel = ath9k_hw_def_get_spur_channel
};
-u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
- enum eeprom_param param)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- return ath9k_get_eeprom[ahp->ah_eep_map](ah, param);
-}
-
-int ath9k_hw_eeprom_attach(struct ath_hal *ah)
+int ath9k_hw_eeprom_attach(struct ath_hw *ah)
{
int status;
- struct ath_hal_5416 *ahp = AH5416(ah);
- if (ath9k_hw_use_flash(ah))
- ath9k_hw_flash_map(ah);
-
- if (AR_SREV_9285(ah))
- ahp->ah_eep_map = EEP_MAP_4KBITS;
- else
- ahp->ah_eep_map = EEP_MAP_DEFAULT;
+ if (AR_SREV_9285(ah)) {
+ ah->eep_map = EEP_MAP_4KBITS;
+ ah->eep_ops = &eep_4k_ops;
+ } else {
+ ah->eep_map = EEP_MAP_DEFAULT;
+ ah->eep_ops = &eep_def_ops;
+ }
- if (!ath9k_hw_fill_eeprom(ah))
+ if (!ah->eep_ops->fill_eeprom(ah))
return -EIO;
- status = ath9k_hw_check_eeprom(ah);
+ status = ah->eep_ops->check_eeprom(ah);
return status;
}
diff --git a/drivers/net/wireless/ath9k/eeprom.h b/drivers/net/wireless/ath9k/eeprom.h
new file mode 100644
index 000000000000..25b68c881ff1
--- /dev/null
+++ b/drivers/net/wireless/ath9k/eeprom.h
@@ -0,0 +1,507 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef EEPROM_H
+#define EEPROM_H
+
+#define AH_USE_EEPROM 0x1
+
+#ifdef __BIG_ENDIAN
+#define AR5416_EEPROM_MAGIC 0x5aa5
+#else
+#define AR5416_EEPROM_MAGIC 0xa55a
+#endif
+
+#define CTRY_DEBUG 0x1ff
+#define CTRY_DEFAULT 0
+
+#define AR_EEPROM_EEPCAP_COMPRESS_DIS 0x0001
+#define AR_EEPROM_EEPCAP_AES_DIS 0x0002
+#define AR_EEPROM_EEPCAP_FASTFRAME_DIS 0x0004
+#define AR_EEPROM_EEPCAP_BURST_DIS 0x0008
+#define AR_EEPROM_EEPCAP_MAXQCU 0x01F0
+#define AR_EEPROM_EEPCAP_MAXQCU_S 4
+#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN 0x0200
+#define AR_EEPROM_EEPCAP_KC_ENTRIES 0xF000
+#define AR_EEPROM_EEPCAP_KC_ENTRIES_S 12
+
+#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND 0x0040
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN 0x0080
+#define AR_EEPROM_EEREGCAP_EN_KK_U2 0x0100
+#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND 0x0200
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD 0x0400
+#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A 0x0800
+
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0 0x4000
+#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
+
+#define AR5416_EEPROM_MAGIC_OFFSET 0x0
+#define AR5416_EEPROM_S 2
+#define AR5416_EEPROM_OFFSET 0x2000
+#define AR5416_EEPROM_MAX 0xae0
+
+#define AR5416_EEPROM_START_ADDR \
+ (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
+
+#define SD_NO_CTL 0xE0
+#define NO_CTL 0xff
+#define CTL_MODE_M 7
+#define CTL_11A 0
+#define CTL_11B 1
+#define CTL_11G 2
+#define CTL_2GHT20 5
+#define CTL_5GHT20 6
+#define CTL_2GHT40 7
+#define CTL_5GHT40 8
+
+#define EXT_ADDITIVE (0x8000)
+#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
+#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
+#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
+
+#define SUB_NUM_CTL_MODES_AT_5G_40 2
+#define SUB_NUM_CTL_MODES_AT_2G_40 3
+
+#define INCREASE_MAXPOW_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
+#define INCREASE_MAXPOW_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
+
+/*
+ * For AR9285 and later chipsets, the following bits are not being programmed
+ * in EEPROM and so need to be enabled always.
+ *
+ * Bit 0: en_fcc_mid
+ * Bit 1: en_jap_mid
+ * Bit 2: en_fcc_dfs_ht40
+ * Bit 3: en_jap_ht40
+ * Bit 4: en_jap_dfs_ht40
+ */
+#define AR9285_RDEXT_DEFAULT 0x1F
+
+#define AR_EEPROM_MAC(i) (0x1d+(i))
+#define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
+#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
+#define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM))
+
+#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
+#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
+ ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
+
+#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
+#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
+#define AR_EEPROM_RFSILENT_POLARITY 0x0002
+#define AR_EEPROM_RFSILENT_POLARITY_S 1
+
+#define EEP_RFSILENT_ENABLED 0x0001
+#define EEP_RFSILENT_ENABLED_S 0
+#define EEP_RFSILENT_POLARITY 0x0002
+#define EEP_RFSILENT_POLARITY_S 1
+#define EEP_RFSILENT_GPIO_SEL 0x001c
+#define EEP_RFSILENT_GPIO_SEL_S 2
+
+#define AR5416_OPFLAGS_11A 0x01
+#define AR5416_OPFLAGS_11G 0x02
+#define AR5416_OPFLAGS_N_5G_HT40 0x04
+#define AR5416_OPFLAGS_N_2G_HT40 0x08
+#define AR5416_OPFLAGS_N_5G_HT20 0x10
+#define AR5416_OPFLAGS_N_2G_HT20 0x20
+
+#define AR5416_EEP_NO_BACK_VER 0x1
+#define AR5416_EEP_VER 0xE
+#define AR5416_EEP_VER_MINOR_MASK 0x0FFF
+#define AR5416_EEP_MINOR_VER_2 0x2
+#define AR5416_EEP_MINOR_VER_3 0x3
+#define AR5416_EEP_MINOR_VER_7 0x7
+#define AR5416_EEP_MINOR_VER_9 0x9
+#define AR5416_EEP_MINOR_VER_16 0x10
+#define AR5416_EEP_MINOR_VER_17 0x11
+#define AR5416_EEP_MINOR_VER_19 0x13
+#define AR5416_EEP_MINOR_VER_20 0x14
+#define AR5416_EEP_MINOR_VER_22 0x16
+
+#define AR5416_NUM_5G_CAL_PIERS 8
+#define AR5416_NUM_2G_CAL_PIERS 4
+#define AR5416_NUM_5G_20_TARGET_POWERS 8
+#define AR5416_NUM_5G_40_TARGET_POWERS 8
+#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
+#define AR5416_NUM_2G_20_TARGET_POWERS 4
+#define AR5416_NUM_2G_40_TARGET_POWERS 4
+#define AR5416_NUM_CTLS 24
+#define AR5416_NUM_BAND_EDGES 8
+#define AR5416_NUM_PD_GAINS 4
+#define AR5416_PD_GAINS_IN_MASK 4
+#define AR5416_PD_GAIN_ICEPTS 5
+#define AR5416_EEPROM_MODAL_SPURS 5
+#define AR5416_MAX_RATE_POWER 63
+#define AR5416_NUM_PDADC_VALUES 128
+#define AR5416_BCHAN_UNUSED 0xFF
+#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
+#define AR5416_MAX_CHAINS 3
+#define AR5416_PWR_TABLE_OFFSET -5
+
+/* Rx gain type values */
+#define AR5416_EEP_RXGAIN_23DB_BACKOFF 0
+#define AR5416_EEP_RXGAIN_13DB_BACKOFF 1
+#define AR5416_EEP_RXGAIN_ORIG 2
+
+/* Tx gain type values */
+#define AR5416_EEP_TXGAIN_ORIGINAL 0
+#define AR5416_EEP_TXGAIN_HIGH_POWER 1
+
+#define AR5416_EEP4K_START_LOC 64
+#define AR5416_EEP4K_NUM_2G_CAL_PIERS 3
+#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
+#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS 3
+#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS 3
+#define AR5416_EEP4K_NUM_CTLS 12
+#define AR5416_EEP4K_NUM_BAND_EDGES 4
+#define AR5416_EEP4K_NUM_PD_GAINS 2
+#define AR5416_EEP4K_PD_GAINS_IN_MASK 4
+#define AR5416_EEP4K_PD_GAIN_ICEPTS 5
+#define AR5416_EEP4K_MAX_CHAINS 1
+
+#define AR9280_TX_GAIN_TABLE_SIZE 22
+
+enum eeprom_param {
+ EEP_NFTHRESH_5,
+ EEP_NFTHRESH_2,
+ EEP_MAC_MSW,
+ EEP_MAC_MID,
+ EEP_MAC_LSW,
+ EEP_REG_0,
+ EEP_REG_1,
+ EEP_OP_CAP,
+ EEP_OP_MODE,
+ EEP_RF_SILENT,
+ EEP_OB_5,
+ EEP_DB_5,
+ EEP_OB_2,
+ EEP_DB_2,
+ EEP_MINOR_REV,
+ EEP_TX_MASK,
+ EEP_RX_MASK,
+ EEP_RXGAIN_TYPE,
+ EEP_TXGAIN_TYPE,
+ EEP_OL_PWRCTRL,
+ EEP_RC_CHAIN_MASK,
+ EEP_DAC_HPWR_5G,
+ EEP_FRAC_N_5G
+};
+
+enum ar5416_rates {
+ rate6mb, rate9mb, rate12mb, rate18mb,
+ rate24mb, rate36mb, rate48mb, rate54mb,
+ rate1l, rate2l, rate2s, rate5_5l,
+ rate5_5s, rate11l, rate11s, rateXr,
+ rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
+ rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
+ rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
+ rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
+ rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
+ Ar5416RateSize
+};
+
+enum ath9k_hal_freq_band {
+ ATH9K_HAL_FREQ_BAND_5GHZ = 0,
+ ATH9K_HAL_FREQ_BAND_2GHZ = 1
+};
+
+struct base_eep_header {
+ u16 length;
+ u16 checksum;
+ u16 version;
+ u8 opCapFlags;
+ u8 eepMisc;
+ u16 regDmn[2];
+ u8 macAddr[6];
+ u8 rxMask;
+ u8 txMask;
+ u16 rfSilent;
+ u16 blueToothOptions;
+ u16 deviceCap;
+ u32 binBuildNumber;
+ u8 deviceType;
+ u8 pwdclkind;
+ u8 futureBase_1[2];
+ u8 rxGainType;
+ u8 dacHiPwrMode_5G;
+ u8 openLoopPwrCntl;
+ u8 dacLpMode;
+ u8 txGainType;
+ u8 rcChainMask;
+ u8 desiredScaleCCK;
+ u8 power_table_offset;
+ u8 frac_n_5g;
+ u8 futureBase_3[21];
+} __packed;
+
+struct base_eep_header_4k {
+ u16 length;
+ u16 checksum;
+ u16 version;
+ u8 opCapFlags;
+ u8 eepMisc;
+ u16 regDmn[2];
+ u8 macAddr[6];
+ u8 rxMask;
+ u8 txMask;
+ u16 rfSilent;
+ u16 blueToothOptions;
+ u16 deviceCap;
+ u32 binBuildNumber;
+ u8 deviceType;
+ u8 txGainType;
+} __packed;
+
+
+struct spur_chan {
+ u16 spurChan;
+ u8 spurRangeLow;
+ u8 spurRangeHigh;
+} __packed;
+
+struct modal_eep_header {
+ u32 antCtrlChain[AR5416_MAX_CHAINS];
+ u32 antCtrlCommon;
+ u8 antennaGainCh[AR5416_MAX_CHAINS];
+ u8 switchSettling;
+ u8 txRxAttenCh[AR5416_MAX_CHAINS];
+ u8 rxTxMarginCh[AR5416_MAX_CHAINS];
+ u8 adcDesiredSize;
+ u8 pgaDesiredSize;
+ u8 xlnaGainCh[AR5416_MAX_CHAINS];
+ u8 txEndToXpaOff;
+ u8 txEndToRxOn;
+ u8 txFrameToXpaOn;
+ u8 thresh62;
+ u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
+ u8 xpdGain;
+ u8 xpd;
+ u8 iqCalICh[AR5416_MAX_CHAINS];
+ u8 iqCalQCh[AR5416_MAX_CHAINS];
+ u8 pdGainOverlap;
+ u8 ob;
+ u8 db;
+ u8 xpaBiasLvl;
+ u8 pwrDecreaseFor2Chain;
+ u8 pwrDecreaseFor3Chain;
+ u8 txFrameToDataStart;
+ u8 txFrameToPaOn;
+ u8 ht40PowerIncForPdadc;
+ u8 bswAtten[AR5416_MAX_CHAINS];
+ u8 bswMargin[AR5416_MAX_CHAINS];
+ u8 swSettleHt40;
+ u8 xatten2Db[AR5416_MAX_CHAINS];
+ u8 xatten2Margin[AR5416_MAX_CHAINS];
+ u8 ob_ch1;
+ u8 db_ch1;
+ u8 useAnt1:1,
+ force_xpaon:1,
+ local_bias:1,
+ femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
+ u8 miscBits;
+ u16 xpaBiasLvlFreq[3];
+ u8 futureModal[6];
+
+ struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+} __packed;
+
+struct calDataPerFreqOpLoop {
+ u8 pwrPdg[2][5];
+ u8 vpdPdg[2][5];
+ u8 pcdac[2][5];
+ u8 empty[2][5];
+} __packed;
+
+struct modal_eep_4k_header {
+ u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
+ u32 antCtrlCommon;
+ u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 switchSettling;
+ u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 adcDesiredSize;
+ u8 pgaDesiredSize;
+ u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 txEndToXpaOff;
+ u8 txEndToRxOn;
+ u8 txFrameToXpaOn;
+ u8 thresh62;
+ u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 xpdGain;
+ u8 xpd;
+ u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS];
+ u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
+ u8 pdGainOverlap;
+ u8 ob_01;
+ u8 db1_01;
+ u8 xpaBiasLvl;
+ u8 txFrameToDataStart;
+ u8 txFrameToPaOn;
+ u8 ht40PowerIncForPdadc;
+ u8 bswAtten[AR5416_EEP4K_MAX_CHAINS];
+ u8 bswMargin[AR5416_EEP4K_MAX_CHAINS];
+ u8 swSettleHt40;
+ u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS];
+ u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
+ u8 db2_01;
+ u8 version;
+ u16 ob_234;
+ u16 db1_234;
+ u16 db2_234;
+ u8 futureModal[4];
+
+ struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+} __packed;
+
+
+struct cal_data_per_freq {
+ u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+ u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+} __packed;
+
+struct cal_data_per_freq_4k {
+ u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+ u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+} __packed;
+
+struct cal_target_power_leg {
+ u8 bChannel;
+ u8 tPow2x[4];
+} __packed;
+
+struct cal_target_power_ht {
+ u8 bChannel;
+ u8 tPow2x[8];
+} __packed;
+
+
+#ifdef __BIG_ENDIAN_BITFIELD
+struct cal_ctl_edges {
+ u8 bChannel;
+ u8 flag:2, tPower:6;
+} __packed;
+#else
+struct cal_ctl_edges {
+ u8 bChannel;
+ u8 tPower:6, flag:2;
+} __packed;
+#endif
+
+struct cal_ctl_data {
+ struct cal_ctl_edges
+ ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+} __packed;
+
+struct cal_ctl_data_4k {
+ struct cal_ctl_edges
+ ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
+} __packed;
+
+struct ar5416_eeprom_def {
+ struct base_eep_header baseEepHeader;
+ u8 custData[64];
+ struct modal_eep_header modalHeader[2];
+ u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
+ u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
+ struct cal_data_per_freq
+ calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
+ struct cal_data_per_freq
+ calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
+ struct cal_target_power_leg
+ calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
+ struct cal_target_power_leg
+ calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
+ struct cal_target_power_leg
+ calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
+ u8 ctlIndex[AR5416_NUM_CTLS];
+ struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
+ u8 padding;
+} __packed;
+
+struct ar5416_eeprom_4k {
+ struct base_eep_header_4k baseEepHeader;
+ u8 custData[20];
+ struct modal_eep_4k_header modalHeader;
+ u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
+ struct cal_data_per_freq_4k
+ calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
+ struct cal_target_power_leg
+ calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
+ struct cal_target_power_leg
+ calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+ struct cal_target_power_ht
+ calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
+ u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
+ struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
+ u8 padding;
+} __packed;
+
+enum reg_ext_bitmap {
+ REG_EXT_JAPAN_MIDBAND = 1,
+ REG_EXT_FCC_DFS_HT40 = 2,
+ REG_EXT_JAPAN_NONDFS_HT40 = 3,
+ REG_EXT_JAPAN_DFS_HT40 = 4
+};
+
+struct ath9k_country_entry {
+ u16 countryCode;
+ u16 regDmnEnum;
+ u16 regDmn5G;
+ u16 regDmn2G;
+ u8 isMultidomain;
+ u8 iso[3];
+};
+
+enum ath9k_eep_map {
+ EEP_MAP_DEFAULT = 0x0,
+ EEP_MAP_4KBITS,
+ EEP_MAP_MAX
+};
+
+struct eeprom_ops {
+ int (*check_eeprom)(struct ath_hw *hw);
+ u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
+ bool (*fill_eeprom)(struct ath_hw *hw);
+ int (*get_eeprom_ver)(struct ath_hw *hw);
+ int (*get_eeprom_rev)(struct ath_hw *hw);
+ u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band);
+ u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
+ struct ath9k_channel *chan);
+ void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
+ void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
+ int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
+ u16 cfgCtl, u8 twiceAntennaReduction,
+ u8 twiceMaxRegulatoryPower, u8 powerLimit);
+ u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
+};
+
+#define ar5416_get_ntxchains(_txchainmask) \
+ (((_txchainmask >> 2) & 1) + \
+ ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
+
+int ath9k_hw_eeprom_attach(struct ath_hw *ah);
+
+#endif /* EEPROM_H */
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index 34474edefc97..b15eaf8417ff 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -17,88 +17,80 @@
#include <linux/io.h>
#include <asm/unaligned.h>
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
#include "initvals.h"
-static const u8 CLOCK_RATE[] = { 40, 80, 22, 44, 88, 40 };
+static int btcoex_enable;
+module_param(btcoex_enable, bool, 0);
+MODULE_PARM_DESC(btcoex_enable, "Enable Bluetooth coexistence support");
-extern struct hal_percal_data iq_cal_multi_sample;
-extern struct hal_percal_data iq_cal_single_sample;
-extern struct hal_percal_data adc_gain_cal_multi_sample;
-extern struct hal_percal_data adc_gain_cal_single_sample;
-extern struct hal_percal_data adc_dc_cal_multi_sample;
-extern struct hal_percal_data adc_dc_cal_single_sample;
-extern struct hal_percal_data adc_init_dc_cal;
+#define ATH9K_CLOCK_RATE_CCK 22
+#define ATH9K_CLOCK_RATE_5GHZ_OFDM 40
+#define ATH9K_CLOCK_RATE_2GHZ_OFDM 44
-static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type);
-static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
+static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode);
-static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
+static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
struct ar5416_eeprom_def *pEepData,
u32 reg, u32 value);
-static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan);
-static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan);
+static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
+static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
/********************/
/* Helper Functions */
/********************/
-static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
+static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
{
- if (ah->ah_curchan != NULL)
- return clks / CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
- else
- return clks / CLOCK_RATE[ATH9K_MODE_11B];
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+ if (!ah->curchan) /* should really check for CCK instead */
+ return clks / ATH9K_CLOCK_RATE_CCK;
+ if (conf->channel->band == IEEE80211_BAND_2GHZ)
+ return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
+
+ return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
}
-static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
+static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
{
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
- if (chan && IS_CHAN_HT40(chan))
+ if (conf_is_ht40(conf))
return ath9k_hw_mac_usec(ah, clks) / 2;
else
return ath9k_hw_mac_usec(ah, clks);
}
-static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
+static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
{
- if (ah->ah_curchan != NULL)
- return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
- ah->ah_curchan)];
- else
- return usecs * CLOCK_RATE[ATH9K_MODE_11B];
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+ if (!ah->curchan) /* should really check for CCK instead */
+ return usecs *ATH9K_CLOCK_RATE_CCK;
+ if (conf->channel->band == IEEE80211_BAND_2GHZ)
+ return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
+ return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM;
}
-static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
+static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
{
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
- if (chan && IS_CHAN_HT40(chan))
+ if (conf_is_ht40(conf))
return ath9k_hw_mac_clks(ah, usecs) * 2;
else
return ath9k_hw_mac_clks(ah, usecs);
}
-enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
- const struct ath9k_channel *chan)
-{
- if (IS_CHAN_B(chan))
- return ATH9K_MODE_11B;
- if (IS_CHAN_G(chan))
- return ATH9K_MODE_11G;
-
- return ATH9K_MODE_11A;
-}
-
-bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val)
+bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
{
int i;
- for (i = 0; i < (AH_TIMEOUT / AH_TIME_QUANTUM); i++) {
+ BUG_ON(timeout < AH_TIME_QUANTUM);
+
+ for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) {
if ((REG_READ(ah, reg) & mask) == val)
return true;
@@ -106,8 +98,8 @@ bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val)
}
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
- "timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
- reg, REG_READ(ah, reg), mask, val);
+ "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
+ timeout, reg, REG_READ(ah, reg), mask, val);
return false;
}
@@ -124,11 +116,11 @@ u32 ath9k_hw_reverse_bits(u32 val, u32 n)
return retval;
}
-bool ath9k_get_channel_edges(struct ath_hal *ah,
+bool ath9k_get_channel_edges(struct ath_hw *ah,
u16 flags, u16 *low,
u16 *high)
{
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
if (flags & CHANNEL_5GHZ) {
*low = pCap->low_5ghz_chan;
@@ -143,7 +135,7 @@ bool ath9k_get_channel_edges(struct ath_hal *ah,
return false;
}
-u16 ath9k_hw_computetxtime(struct ath_hal *ah,
+u16 ath9k_hw_computetxtime(struct ath_hw *ah,
struct ath_rate_table *rates,
u32 frameLen, u16 rateix,
bool shortPreamble)
@@ -165,15 +157,15 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah,
txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
break;
case WLAN_RC_PHY_OFDM:
- if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
+ if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) {
bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
numBits = OFDM_PLCP_BITS + (frameLen << 3);
numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
txTime = OFDM_SIFS_TIME_QUARTER
+ OFDM_PREAMBLE_TIME_QUARTER
+ (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
- } else if (ah->ah_curchan &&
- IS_CHAN_HALF_RATE(ah->ah_curchan)) {
+ } else if (ah->curchan &&
+ IS_CHAN_HALF_RATE(ah->curchan)) {
bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
numBits = OFDM_PLCP_BITS + (frameLen << 3);
numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
@@ -199,52 +191,11 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah,
return txTime;
}
-u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
-{
- if (flags & CHANNEL_2GHZ) {
- if (freq == 2484)
- return 14;
- if (freq < 2484)
- return (freq - 2407) / 5;
- else
- return 15 + ((freq - 2512) / 20);
- } else if (flags & CHANNEL_5GHZ) {
- if (ath9k_regd_is_public_safety_sku(ah) &&
- IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
- return ((freq * 10) +
- (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
- } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
- return (freq - 4000) / 5;
- } else {
- return (freq - 5000) / 5;
- }
- } else {
- if (freq == 2484)
- return 14;
- if (freq < 2484)
- return (freq - 2407) / 5;
- if (freq < 5000) {
- if (ath9k_regd_is_public_safety_sku(ah)
- && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
- return ((freq * 10) +
- (((freq % 5) ==
- 2) ? 5 : 0) - 49400) / 5;
- } else if (freq > 4900) {
- return (freq - 4000) / 5;
- } else {
- return 15 + ((freq - 2512) / 20);
- }
- }
- return (freq - 5000) / 5;
- }
-}
-
-void ath9k_hw_get_channel_centers(struct ath_hal *ah,
+void ath9k_hw_get_channel_centers(struct ath_hw *ah,
struct ath9k_channel *chan,
struct chan_centers *centers)
{
int8_t extoff;
- struct ath_hal_5416 *ahp = AH5416(ah);
if (!IS_CHAN_HT40(chan)) {
centers->ctl_center = centers->ext_center =
@@ -267,16 +218,15 @@ void ath9k_hw_get_channel_centers(struct ath_hal *ah,
centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
centers->ext_center =
centers->synth_center + (extoff *
- ((ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
+ ((ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
HT40_CHANNEL_CENTER_SHIFT : 15));
-
}
/******************/
/* Chip Revisions */
/******************/
-static void ath9k_hw_read_revisions(struct ath_hal *ah)
+static void ath9k_hw_read_revisions(struct ath_hw *ah)
{
u32 val;
@@ -284,21 +234,22 @@ static void ath9k_hw_read_revisions(struct ath_hal *ah)
if (val == 0xFF) {
val = REG_READ(ah, AR_SREV);
- ah->ah_macVersion = (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
- ah->ah_macRev = MS(val, AR_SREV_REVISION2);
- ah->ah_isPciExpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
+ ah->hw_version.macVersion =
+ (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
+ ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
+ ah->is_pciexpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
} else {
if (!AR_SREV_9100(ah))
- ah->ah_macVersion = MS(val, AR_SREV_VERSION);
+ ah->hw_version.macVersion = MS(val, AR_SREV_VERSION);
- ah->ah_macRev = val & AR_SREV_REVISION;
+ ah->hw_version.macRev = val & AR_SREV_REVISION;
- if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE)
- ah->ah_isPciExpress = true;
+ if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)
+ ah->is_pciexpress = true;
}
}
-static int ath9k_hw_get_radiorev(struct ath_hal *ah)
+static int ath9k_hw_get_radiorev(struct ath_hw *ah)
{
u32 val;
int i;
@@ -317,9 +268,9 @@ static int ath9k_hw_get_radiorev(struct ath_hal *ah)
/* HW Attach, Detach, Init Routines */
/************************************/
-static void ath9k_hw_disablepcie(struct ath_hal *ah)
+static void ath9k_hw_disablepcie(struct ath_hw *ah)
{
- if (!AR_SREV_9100(ah))
+ if (AR_SREV_9100(ah))
return;
REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
@@ -335,7 +286,7 @@ static void ath9k_hw_disablepcie(struct ath_hal *ah)
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
}
-static bool ath9k_hw_chip_test(struct ath_hal *ah)
+static bool ath9k_hw_chip_test(struct ath_hw *ah)
{
u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
u32 regHold[2];
@@ -377,6 +328,7 @@ static bool ath9k_hw_chip_test(struct ath_hal *ah)
REG_WRITE(ah, regAddr[i], regHold[i]);
}
udelay(100);
+
return true;
}
@@ -389,6 +341,8 @@ static const char *ath9k_hw_devname(u16 devid)
return "Atheros 5418";
case AR9160_DEVID_PCI:
return "Atheros 9160";
+ case AR5416_AR9100_DEVID:
+ return "Atheros 9100";
case AR9280_DEVID_PCI:
case AR9280_DEVID_PCIE:
return "Atheros 9280";
@@ -399,99 +353,110 @@ static const char *ath9k_hw_devname(u16 devid)
return NULL;
}
-static void ath9k_hw_set_defaults(struct ath_hal *ah)
+static void ath9k_hw_set_defaults(struct ath_hw *ah)
{
int i;
- ah->ah_config.dma_beacon_response_time = 2;
- ah->ah_config.sw_beacon_response_time = 10;
- ah->ah_config.additional_swba_backoff = 0;
- ah->ah_config.ack_6mb = 0x0;
- ah->ah_config.cwm_ignore_extcca = 0;
- ah->ah_config.pcie_powersave_enable = 0;
- ah->ah_config.pcie_l1skp_enable = 0;
- ah->ah_config.pcie_clock_req = 0;
- ah->ah_config.pcie_power_reset = 0x100;
- ah->ah_config.pcie_restore = 0;
- ah->ah_config.pcie_waen = 0;
- ah->ah_config.analog_shiftreg = 1;
- ah->ah_config.ht_enable = 1;
- ah->ah_config.ofdm_trig_low = 200;
- ah->ah_config.ofdm_trig_high = 500;
- ah->ah_config.cck_trig_high = 200;
- ah->ah_config.cck_trig_low = 100;
- ah->ah_config.enable_ani = 1;
- ah->ah_config.noise_immunity_level = 4;
- ah->ah_config.ofdm_weaksignal_det = 1;
- ah->ah_config.cck_weaksignal_thr = 0;
- ah->ah_config.spur_immunity_level = 2;
- ah->ah_config.firstep_level = 0;
- ah->ah_config.rssi_thr_high = 40;
- ah->ah_config.rssi_thr_low = 7;
- ah->ah_config.diversity_control = 0;
- ah->ah_config.antenna_switch_swap = 0;
+ ah->config.dma_beacon_response_time = 2;
+ ah->config.sw_beacon_response_time = 10;
+ ah->config.additional_swba_backoff = 0;
+ ah->config.ack_6mb = 0x0;
+ ah->config.cwm_ignore_extcca = 0;
+ ah->config.pcie_powersave_enable = 0;
+ ah->config.pcie_l1skp_enable = 0;
+ ah->config.pcie_clock_req = 0;
+ ah->config.pcie_power_reset = 0x100;
+ ah->config.pcie_restore = 0;
+ ah->config.pcie_waen = 0;
+ ah->config.analog_shiftreg = 1;
+ ah->config.ht_enable = 1;
+ ah->config.ofdm_trig_low = 200;
+ ah->config.ofdm_trig_high = 500;
+ ah->config.cck_trig_high = 200;
+ ah->config.cck_trig_low = 100;
+ ah->config.enable_ani = 1;
+ ah->config.noise_immunity_level = 4;
+ ah->config.ofdm_weaksignal_det = 1;
+ ah->config.cck_weaksignal_thr = 0;
+ ah->config.spur_immunity_level = 2;
+ ah->config.firstep_level = 0;
+ ah->config.rssi_thr_high = 40;
+ ah->config.rssi_thr_low = 7;
+ ah->config.diversity_control = 0;
+ ah->config.antenna_switch_swap = 0;
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
- ah->ah_config.spurchans[i][0] = AR_NO_SPUR;
- ah->ah_config.spurchans[i][1] = AR_NO_SPUR;
+ ah->config.spurchans[i][0] = AR_NO_SPUR;
+ ah->config.spurchans[i][1] = AR_NO_SPUR;
}
- ah->ah_config.intr_mitigation = 1;
+ ah->config.intr_mitigation = 1;
+
+ /*
+ * We need this for PCI devices only (Cardbus, PCI, miniPCI)
+ * _and_ if on non-uniprocessor systems (Multiprocessor/HT).
+ * This means we use it for all AR5416 devices, and the few
+ * minor PCI AR9280 devices out there.
+ *
+ * Serialization is required because these devices do not handle
+ * well the case of two concurrent reads/writes due to the latency
+ * involved. During one read/write another read/write can be issued
+ * on another CPU while the previous read/write may still be working
+ * on our hardware, if we hit this case the hardware poops in a loop.
+ * We prevent this by serializing reads and writes.
+ *
+ * This issue is not present on PCI-Express devices or pre-AR5416
+ * devices (legacy, 802.11abg).
+ */
+ if (num_possible_cpus() > 1)
+ ah->config.serialize_regmode = SER_REG_MODE_AUTO;
}
-static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
- struct ath_softc *sc,
- void __iomem *mem,
- int *status)
+static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc,
+ int *status)
{
- static const u8 defbssidmask[ETH_ALEN] =
- { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- struct ath_hal_5416 *ahp;
- struct ath_hal *ah;
+ struct ath_hw *ah;
- ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL);
- if (ahp == NULL) {
+ ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
+ if (ah == NULL) {
DPRINTF(sc, ATH_DBG_FATAL,
"Cannot allocate memory for state block\n");
*status = -ENOMEM;
return NULL;
}
- ah = &ahp->ah;
ah->ah_sc = sc;
- ah->ah_sh = mem;
- ah->ah_magic = AR5416_MAGIC;
- ah->ah_countryCode = CTRY_DEFAULT;
- ah->ah_devid = devid;
- ah->ah_subvendorid = 0;
+ ah->hw_version.magic = AR5416_MAGIC;
+ ah->regulatory.country_code = CTRY_DEFAULT;
+ ah->hw_version.devid = devid;
+ ah->hw_version.subvendorid = 0;
ah->ah_flags = 0;
if ((devid == AR5416_AR9100_DEVID))
- ah->ah_macVersion = AR_SREV_VERSION_9100;
+ ah->hw_version.macVersion = AR_SREV_VERSION_9100;
if (!AR_SREV_9100(ah))
ah->ah_flags = AH_USE_EEPROM;
- ah->ah_powerLimit = MAX_RATE_POWER;
- ah->ah_tpScale = ATH9K_TP_SCALE_MAX;
- ahp->ah_atimWindow = 0;
- ahp->ah_diversityControl = ah->ah_config.diversity_control;
- ahp->ah_antennaSwitchSwap =
- ah->ah_config.antenna_switch_swap;
- ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
- ahp->ah_beaconInterval = 100;
- ahp->ah_enable32kHzClock = DONT_USE_32KHZ;
- ahp->ah_slottime = (u32) -1;
- ahp->ah_acktimeout = (u32) -1;
- ahp->ah_ctstimeout = (u32) -1;
- ahp->ah_globaltxtimeout = (u32) -1;
- memcpy(&ahp->ah_bssidmask, defbssidmask, ETH_ALEN);
-
- ahp->ah_gBeaconRate = 0;
+ ah->regulatory.power_limit = MAX_RATE_POWER;
+ ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX;
+ ah->atim_window = 0;
+ ah->diversity_control = ah->config.diversity_control;
+ ah->antenna_switch_swap =
+ ah->config.antenna_switch_swap;
+ ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
+ ah->beacon_interval = 100;
+ ah->enable_32kHz_clock = DONT_USE_32KHZ;
+ ah->slottime = (u32) -1;
+ ah->acktimeout = (u32) -1;
+ ah->ctstimeout = (u32) -1;
+ ah->globaltxtimeout = (u32) -1;
+
+ ah->gbeacon_rate = 0;
- return ahp;
+ return ah;
}
-static int ath9k_hw_rfattach(struct ath_hal *ah)
+static int ath9k_hw_rfattach(struct ath_hw *ah)
{
bool rfStatus = false;
int ecode = 0;
@@ -506,7 +471,7 @@ static int ath9k_hw_rfattach(struct ath_hal *ah)
return 0;
}
-static int ath9k_hw_rf_claim(struct ath_hal *ah)
+static int ath9k_hw_rf_claim(struct ath_hw *ah)
{
u32 val;
@@ -526,88 +491,87 @@ static int ath9k_hw_rf_claim(struct ath_hal *ah)
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"5G Radio Chip Rev 0x%02X is not "
"supported by this driver\n",
- ah->ah_analog5GhzRev);
+ ah->hw_version.analog5GhzRev);
return -EOPNOTSUPP;
}
- ah->ah_analog5GhzRev = val;
+ ah->hw_version.analog5GhzRev = val;
return 0;
}
-static int ath9k_hw_init_macaddr(struct ath_hal *ah)
+static int ath9k_hw_init_macaddr(struct ath_hw *ah)
{
u32 sum;
int i;
u16 eeval;
- struct ath_hal_5416 *ahp = AH5416(ah);
sum = 0;
for (i = 0; i < 3; i++) {
- eeval = ath9k_hw_get_eeprom(ah, AR_EEPROM_MAC(i));
+ eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i));
sum += eeval;
- ahp->ah_macaddr[2 * i] = eeval >> 8;
- ahp->ah_macaddr[2 * i + 1] = eeval & 0xff;
+ ah->macaddr[2 * i] = eeval >> 8;
+ ah->macaddr[2 * i + 1] = eeval & 0xff;
}
if (sum == 0 || sum == 0xffff * 3) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"mac address read failed: %pM\n",
- ahp->ah_macaddr);
+ ah->macaddr);
return -EADDRNOTAVAIL;
}
return 0;
}
-static void ath9k_hw_init_rxgain_ini(struct ath_hal *ah)
+static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah)
{
u32 rxgain_type;
- struct ath_hal_5416 *ahp = AH5416(ah);
- if (ath9k_hw_get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
- rxgain_type = ath9k_hw_get_eeprom(ah, EEP_RXGAIN_TYPE);
+ if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
+ rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
- INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9280Modes_backoff_13db_rxgain_9280_2,
ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
- INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9280Modes_backoff_23db_rxgain_9280_2,
ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
else
- INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9280Modes_original_rxgain_9280_2,
ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
- } else
- INIT_INI_ARRAY(&ahp->ah_iniModesRxGain,
+ } else {
+ INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9280Modes_original_rxgain_9280_2,
ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
+ }
}
-static void ath9k_hw_init_txgain_ini(struct ath_hal *ah)
+static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
{
u32 txgain_type;
- struct ath_hal_5416 *ahp = AH5416(ah);
- if (ath9k_hw_get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
- txgain_type = ath9k_hw_get_eeprom(ah, EEP_TXGAIN_TYPE);
+ if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
+ txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
- INIT_INI_ARRAY(&ahp->ah_iniModesTxGain,
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9280Modes_high_power_tx_gain_9280_2,
ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
else
- INIT_INI_ARRAY(&ahp->ah_iniModesTxGain,
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9280Modes_original_tx_gain_9280_2,
ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
- } else
- INIT_INI_ARRAY(&ahp->ah_iniModesTxGain,
+ } else {
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9280Modes_original_tx_gain_9280_2,
ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
+ }
}
-static int ath9k_hw_post_attach(struct ath_hal *ah)
+static int ath9k_hw_post_attach(struct ath_hw *ah)
{
int ecode;
@@ -624,6 +588,10 @@ static int ath9k_hw_post_attach(struct ath_hal *ah)
ecode = ath9k_hw_eeprom_attach(ah);
if (ecode != 0)
return ecode;
+
+ DPRINTF(ah->ah_sc, ATH_DBG_CONFIG, "Eeprom VER: %d, REV: %d\n",
+ ah->eep_ops->get_eeprom_ver(ah), ah->eep_ops->get_eeprom_rev(ah));
+
ecode = ath9k_hw_rfattach(ah);
if (ecode != 0)
return ecode;
@@ -636,237 +604,229 @@ static int ath9k_hw_post_attach(struct ath_hal *ah)
return 0;
}
-static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
- void __iomem *mem, int *status)
+static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
+ int *status)
{
- struct ath_hal_5416 *ahp;
- struct ath_hal *ah;
+ struct ath_hw *ah;
int ecode;
u32 i, j;
- ahp = ath9k_hw_newstate(devid, sc, mem, status);
- if (ahp == NULL)
+ ah = ath9k_hw_newstate(devid, sc, status);
+ if (ah == NULL)
return NULL;
- ah = &ahp->ah;
-
ath9k_hw_set_defaults(ah);
- if (ah->ah_config.intr_mitigation != 0)
- ahp->ah_intrMitigation = true;
+ if (ah->config.intr_mitigation != 0)
+ ah->intr_mitigation = true;
if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET, "Couldn't reset chip\n");
+ DPRINTF(sc, ATH_DBG_RESET, "Couldn't reset chip\n");
ecode = -EIO;
goto bad;
}
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET, "Couldn't wakeup chip\n");
+ DPRINTF(sc, ATH_DBG_RESET, "Couldn't wakeup chip\n");
ecode = -EIO;
goto bad;
}
- if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
- if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
- ah->ah_config.serialize_regmode =
+ if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
+ if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
+ (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
+ ah->config.serialize_regmode =
SER_REG_MODE_ON;
} else {
- ah->ah_config.serialize_regmode =
+ ah->config.serialize_regmode =
SER_REG_MODE_OFF;
}
}
- DPRINTF(ah->ah_sc, ATH_DBG_RESET,
- "serialize_regmode is %d\n",
- ah->ah_config.serialize_regmode);
+ DPRINTF(sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
+ ah->config.serialize_regmode);
- if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
- (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
- (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
+ if ((ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCI) &&
+ (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) &&
+ (ah->hw_version.macVersion != AR_SREV_VERSION_9160) &&
(!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+ DPRINTF(sc, ATH_DBG_RESET,
"Mac Chip Rev 0x%02x.%x is not supported by "
- "this driver\n", ah->ah_macVersion, ah->ah_macRev);
+ "this driver\n", ah->hw_version.macVersion,
+ ah->hw_version.macRev);
ecode = -EOPNOTSUPP;
goto bad;
}
if (AR_SREV_9100(ah)) {
- ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
- ahp->ah_suppCals = IQ_MISMATCH_CAL;
- ah->ah_isPciExpress = false;
+ ah->iq_caldata.calData = &iq_cal_multi_sample;
+ ah->supp_cals = IQ_MISMATCH_CAL;
+ ah->is_pciexpress = false;
}
- ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
+ ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
if (AR_SREV_9160_10_OR_LATER(ah)) {
if (AR_SREV_9280_10_OR_LATER(ah)) {
- ahp->ah_iqCalData.calData = &iq_cal_single_sample;
- ahp->ah_adcGainCalData.calData =
+ ah->iq_caldata.calData = &iq_cal_single_sample;
+ ah->adcgain_caldata.calData =
&adc_gain_cal_single_sample;
- ahp->ah_adcDcCalData.calData =
+ ah->adcdc_caldata.calData =
&adc_dc_cal_single_sample;
- ahp->ah_adcDcCalInitData.calData =
+ ah->adcdc_calinitdata.calData =
&adc_init_dc_cal;
} else {
- ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
- ahp->ah_adcGainCalData.calData =
+ ah->iq_caldata.calData = &iq_cal_multi_sample;
+ ah->adcgain_caldata.calData =
&adc_gain_cal_multi_sample;
- ahp->ah_adcDcCalData.calData =
+ ah->adcdc_caldata.calData =
&adc_dc_cal_multi_sample;
- ahp->ah_adcDcCalInitData.calData =
+ ah->adcdc_calinitdata.calData =
&adc_init_dc_cal;
}
- ahp->ah_suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
+ ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
}
- if (AR_SREV_9160(ah)) {
- ah->ah_config.enable_ani = 1;
- ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
- ATH9K_ANI_FIRSTEP_LEVEL);
- } else {
- ahp->ah_ani_function = ATH9K_ANI_ALL;
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- ahp->ah_ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
- }
- }
+ ah->ani_function = ATH9K_ANI_ALL;
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
- DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+ DPRINTF(sc, ATH_DBG_RESET,
"This Mac Chip Rev 0x%02x.%x is \n",
- ah->ah_macVersion, ah->ah_macRev);
+ ah->hw_version.macVersion, ah->hw_version.macRev);
if (AR_SREV_9285_12_OR_LATER(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285_1_2,
+
+ INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285_1_2,
+ INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
ARRAY_SIZE(ar9285Common_9285_1_2), 2);
- if (ah->ah_config.pcie_clock_req) {
- INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ if (ah->config.pcie_clock_req) {
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9285PciePhy_clkreq_off_L1_9285_1_2,
ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
} else {
- INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
2);
}
} else if (AR_SREV_9285_10_OR_LATER(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar9285Modes_9285,
+ INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
ARRAY_SIZE(ar9285Modes_9285), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9285Common_9285,
+ INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
ARRAY_SIZE(ar9285Common_9285), 2);
- if (ah->ah_config.pcie_clock_req) {
- INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ if (ah->config.pcie_clock_req) {
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9285PciePhy_clkreq_off_L1_9285,
ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
} else {
- INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9285PciePhy_clkreq_always_on_L1_9285,
ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
}
} else if (AR_SREV_9280_20_OR_LATER(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
+ INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
ARRAY_SIZE(ar9280Modes_9280_2), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
+ INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
ARRAY_SIZE(ar9280Common_9280_2), 2);
- if (ah->ah_config.pcie_clock_req) {
- INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ if (ah->config.pcie_clock_req) {
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9280PciePhy_clkreq_off_L1_9280,
ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2);
} else {
- INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
+ INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9280PciePhy_clkreq_always_on_L1_9280,
ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
}
- INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
+ INIT_INI_ARRAY(&ah->iniModesAdditional,
ar9280Modes_fast_clock_9280_2,
ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
} else if (AR_SREV_9280_10_OR_LATER(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
+ INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
ARRAY_SIZE(ar9280Modes_9280), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
+ INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
ARRAY_SIZE(ar9280Common_9280), 2);
} else if (AR_SREV_9160_10_OR_LATER(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
+ INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
ARRAY_SIZE(ar5416Modes_9160), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
+ INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
ARRAY_SIZE(ar5416Common_9160), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
+ INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
ARRAY_SIZE(ar5416Bank0_9160), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
+ INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
+ INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
ARRAY_SIZE(ar5416Bank1_9160), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
+ INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
ARRAY_SIZE(ar5416Bank2_9160), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
+ INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
ARRAY_SIZE(ar5416Bank3_9160), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
+ INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
ARRAY_SIZE(ar5416Bank6_9160), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
+ INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
+ INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
ARRAY_SIZE(ar5416Bank7_9160), 2);
if (AR_SREV_9160_11(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniAddac,
+ INIT_INI_ARRAY(&ah->iniAddac,
ar5416Addac_91601_1,
ARRAY_SIZE(ar5416Addac_91601_1), 2);
} else {
- INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
+ INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
ARRAY_SIZE(ar5416Addac_9160), 2);
}
} else if (AR_SREV_9100_OR_LATER(ah)) {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
+ INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
ARRAY_SIZE(ar5416Modes_9100), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
+ INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
ARRAY_SIZE(ar5416Common_9100), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
+ INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
ARRAY_SIZE(ar5416Bank0_9100), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
+ INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
+ INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
ARRAY_SIZE(ar5416Bank1_9100), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
+ INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
ARRAY_SIZE(ar5416Bank2_9100), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
+ INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
ARRAY_SIZE(ar5416Bank3_9100), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
+ INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
ARRAY_SIZE(ar5416Bank6_9100), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
+ INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
+ INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
ARRAY_SIZE(ar5416Bank7_9100), 2);
- INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
+ INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
ARRAY_SIZE(ar5416Addac_9100), 2);
} else {
- INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
+ INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
ARRAY_SIZE(ar5416Modes), 6);
- INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
+ INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
ARRAY_SIZE(ar5416Common), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
+ INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
ARRAY_SIZE(ar5416Bank0), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
+ INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
ARRAY_SIZE(ar5416BB_RfGain), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
+ INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
ARRAY_SIZE(ar5416Bank1), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
+ INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
ARRAY_SIZE(ar5416Bank2), 2);
- INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
+ INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
ARRAY_SIZE(ar5416Bank3), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
+ INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
ARRAY_SIZE(ar5416Bank6), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
+ INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
ARRAY_SIZE(ar5416Bank6TPC), 3);
- INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
+ INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
ARRAY_SIZE(ar5416Bank7), 2);
- INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
+ INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
ARRAY_SIZE(ar5416Addac), 2);
}
- if (ah->ah_isPciExpress)
+ if (ah->is_pciexpress)
ath9k_hw_configpcipowersave(ah, 0);
else
ath9k_hw_disablepcie(ah);
@@ -875,6 +835,22 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
if (ecode != 0)
goto bad;
+ if (AR_SREV_9285_12_OR_LATER(ah)) {
+ u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
+
+ /* txgain table */
+ if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9285Modes_high_power_tx_gain_9285_1_2,
+ ARRAY_SIZE(ar9285Modes_high_power_tx_gain_9285_1_2), 6);
+ } else {
+ INIT_INI_ARRAY(&ah->iniModesTxGain,
+ ar9285Modes_original_tx_gain_9285_1_2,
+ ARRAY_SIZE(ar9285Modes_original_tx_gain_9285_1_2), 6);
+ }
+
+ }
+
/* rxgain table */
if (AR_SREV_9280_20(ah))
ath9k_hw_init_rxgain_ini(ah);
@@ -883,53 +859,55 @@ static struct ath_hal *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
if (AR_SREV_9280_20(ah))
ath9k_hw_init_txgain_ini(ah);
- if (ah->ah_devid == AR9280_DEVID_PCI) {
- for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
- u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
+ if (!ath9k_hw_fill_cap_info(ah)) {
+ DPRINTF(sc, ATH_DBG_RESET, "failed ath9k_hw_fill_cap_info\n");
+ ecode = -EINVAL;
+ goto bad;
+ }
- for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
- u32 val = INI_RA(&ahp->ah_iniModes, i, j);
+ if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
+ test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
- INI_RA(&ahp->ah_iniModes, i, j) =
+ /* EEPROM Fixup */
+ for (i = 0; i < ah->iniModes.ia_rows; i++) {
+ u32 reg = INI_RA(&ah->iniModes, i, 0);
+
+ for (j = 1; j < ah->iniModes.ia_columns; j++) {
+ u32 val = INI_RA(&ah->iniModes, i, j);
+
+ INI_RA(&ah->iniModes, i, j) =
ath9k_hw_ini_fixup(ah,
- &ahp->ah_eeprom.def,
+ &ah->eeprom.def,
reg, val);
}
}
}
- if (!ath9k_hw_fill_cap_info(ah)) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET,
- "failed ath9k_hw_fill_cap_info\n");
- ecode = -EINVAL;
- goto bad;
- }
-
ecode = ath9k_hw_init_macaddr(ah);
if (ecode != 0) {
- DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+ DPRINTF(sc, ATH_DBG_RESET,
"failed initializing mac address\n");
goto bad;
}
if (AR_SREV_9285(ah))
- ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
+ ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
else
- ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
+ ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
ath9k_init_nfcal_hist_buffer(ah);
return ah;
bad:
- if (ahp)
- ath9k_hw_detach((struct ath_hal *) ahp);
+ if (ah)
+ ath9k_hw_detach(ah);
if (status)
*status = ecode;
return NULL;
}
-static void ath9k_hw_init_bb(struct ath_hal *ah,
+static void ath9k_hw_init_bb(struct ath_hw *ah,
struct ath9k_channel *chan)
{
u32 synthDelay;
@@ -945,7 +923,7 @@ static void ath9k_hw_init_bb(struct ath_hal *ah,
udelay(synthDelay + BASE_ACTIVATE_DELAY);
}
-static void ath9k_hw_init_qos(struct ath_hal *ah)
+static void ath9k_hw_init_qos(struct ath_hw *ah)
{
REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
@@ -962,7 +940,7 @@ static void ath9k_hw_init_qos(struct ath_hal *ah)
REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
}
-static void ath9k_hw_init_pll(struct ath_hal *ah,
+static void ath9k_hw_init_pll(struct ath_hw *ah,
struct ath9k_channel *chan)
{
u32 pll;
@@ -1023,27 +1001,26 @@ static void ath9k_hw_init_pll(struct ath_hal *ah,
pll |= SM(0xb, AR_RTC_PLL_DIV);
}
}
- REG_WRITE(ah, (u16) (AR_RTC_PLL_CONTROL), pll);
+ REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
udelay(RTC_PLL_SETTLE_DELAY);
REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
}
-static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
+static void ath9k_hw_init_chain_masks(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int rx_chainmask, tx_chainmask;
- rx_chainmask = ahp->ah_rxchainmask;
- tx_chainmask = ahp->ah_txchainmask;
+ rx_chainmask = ah->rxchainmask;
+ tx_chainmask = ah->txchainmask;
switch (rx_chainmask) {
case 0x5:
REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
AR_PHY_SWAP_ALT_CHAIN);
case 0x3:
- if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
+ if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) {
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
break;
@@ -1068,28 +1045,26 @@ static void ath9k_hw_init_chain_masks(struct ath_hal *ah)
REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
}
-static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
+static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
enum nl80211_iftype opmode)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- ahp->ah_maskReg = AR_IMR_TXERR |
+ ah->mask_reg = AR_IMR_TXERR |
AR_IMR_TXURN |
AR_IMR_RXERR |
AR_IMR_RXORN |
AR_IMR_BCNMISC;
- if (ahp->ah_intrMitigation)
- ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
+ if (ah->intr_mitigation)
+ ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
else
- ahp->ah_maskReg |= AR_IMR_RXOK;
+ ah->mask_reg |= AR_IMR_RXOK;
- ahp->ah_maskReg |= AR_IMR_TXOK;
+ ah->mask_reg |= AR_IMR_TXOK;
if (opmode == NL80211_IFTYPE_AP)
- ahp->ah_maskReg |= AR_IMR_MIB;
+ ah->mask_reg |= AR_IMR_MIB;
- REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
+ REG_WRITE(ah, AR_IMR, ah->mask_reg);
REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
if (!AR_SREV_9100(ah)) {
@@ -1099,72 +1074,64 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
}
}
-static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
+static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad ack timeout %u\n", us);
- ahp->ah_acktimeout = (u32) -1;
+ ah->acktimeout = (u32) -1;
return false;
} else {
REG_RMW_FIELD(ah, AR_TIME_OUT,
AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
- ahp->ah_acktimeout = us;
+ ah->acktimeout = us;
return true;
}
}
-static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
+static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad cts timeout %u\n", us);
- ahp->ah_ctstimeout = (u32) -1;
+ ah->ctstimeout = (u32) -1;
return false;
} else {
REG_RMW_FIELD(ah, AR_TIME_OUT,
AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
- ahp->ah_ctstimeout = us;
+ ah->ctstimeout = us;
return true;
}
}
-static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah, u32 tu)
+static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
if (tu > 0xFFFF) {
DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
"bad global tx timeout %u\n", tu);
- ahp->ah_globaltxtimeout = (u32) -1;
+ ah->globaltxtimeout = (u32) -1;
return false;
} else {
REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
- ahp->ah_globaltxtimeout = tu;
+ ah->globaltxtimeout = tu;
return true;
}
}
-static void ath9k_hw_init_user_settings(struct ath_hal *ah)
+static void ath9k_hw_init_user_settings(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
+ ah->misc_mode);
- DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ahp->ah_miscMode 0x%x\n",
- ahp->ah_miscMode);
-
- if (ahp->ah_miscMode != 0)
+ if (ah->misc_mode != 0)
REG_WRITE(ah, AR_PCU_MISC,
- REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
- if (ahp->ah_slottime != (u32) -1)
- ath9k_hw_setslottime(ah, ahp->ah_slottime);
- if (ahp->ah_acktimeout != (u32) -1)
- ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
- if (ahp->ah_ctstimeout != (u32) -1)
- ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
- if (ahp->ah_globaltxtimeout != (u32) -1)
- ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
+ REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
+ if (ah->slottime != (u32) -1)
+ ath9k_hw_setslottime(ah, ah->slottime);
+ if (ah->acktimeout != (u32) -1)
+ ath9k_hw_set_ack_timeout(ah, ah->acktimeout);
+ if (ah->ctstimeout != (u32) -1)
+ ath9k_hw_set_cts_timeout(ah, ah->ctstimeout);
+ if (ah->globaltxtimeout != (u32) -1)
+ ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
}
const char *ath9k_hw_probe(u16 vendorid, u16 devid)
@@ -1173,7 +1140,7 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid)
ath9k_hw_devname(devid) : NULL;
}
-void ath9k_hw_detach(struct ath_hal *ah)
+void ath9k_hw_detach(struct ath_hw *ah)
{
if (!AR_SREV_9100(ah))
ath9k_hw_ani_detach(ah);
@@ -1183,19 +1150,19 @@ void ath9k_hw_detach(struct ath_hal *ah)
kfree(ah);
}
-struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
- void __iomem *mem, int *error)
+struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error)
{
- struct ath_hal *ah = NULL;
+ struct ath_hw *ah = NULL;
switch (devid) {
case AR5416_DEVID_PCI:
case AR5416_DEVID_PCIE:
+ case AR5416_AR9100_DEVID:
case AR9160_DEVID_PCI:
case AR9280_DEVID_PCI:
case AR9280_DEVID_PCIE:
case AR9285_DEVID_PCIE:
- ah = ath9k_hw_do_attach(devid, sc, mem, error);
+ ah = ath9k_hw_do_attach(devid, sc, error);
break;
default:
*error = -ENXIO;
@@ -1209,7 +1176,7 @@ struct ath_hal *ath9k_hw_attach(u16 devid, struct ath_softc *sc,
/* INI */
/*******/
-static void ath9k_hw_override_ini(struct ath_hal *ah,
+static void ath9k_hw_override_ini(struct ath_hw *ah,
struct ath9k_channel *chan)
{
/*
@@ -1220,20 +1187,20 @@ static void ath9k_hw_override_ini(struct ath_hal *ah,
REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
- if (!AR_SREV_5416_V20_OR_LATER(ah) ||
+ if (!AR_SREV_5416_20_OR_LATER(ah) ||
AR_SREV_9280_10_OR_LATER(ah))
return;
REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
}
-static u32 ath9k_hw_def_ini_fixup(struct ath_hal *ah,
+static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
struct ar5416_eeprom_def *pEepData,
u32 reg, u32 value)
{
struct base_eep_header *pBase = &(pEepData->baseEepHeader);
- switch (ah->ah_devid) {
+ switch (ah->hw_version.devid) {
case AR9280_DEVID_PCI:
if (reg == 0x7894) {
DPRINTF(ah->ah_sc, ATH_DBG_ANY,
@@ -1261,24 +1228,33 @@ static u32 ath9k_hw_def_ini_fixup(struct ath_hal *ah,
return value;
}
-static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
+static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
struct ar5416_eeprom_def *pEepData,
u32 reg, u32 value)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- if (ahp->ah_eep_map == EEP_MAP_4KBITS)
+ if (ah->eep_map == EEP_MAP_4KBITS)
return value;
else
return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value);
}
-static int ath9k_hw_process_ini(struct ath_hal *ah,
+static void ath9k_olc_init(struct ath_hw *ah)
+{
+ u32 i;
+
+ for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
+ ah->originalGain[i] =
+ MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
+ AR_PHY_TX_GAIN);
+ ah->PDADCdelta = 0;
+}
+
+static int ath9k_hw_process_ini(struct ath_hw *ah,
struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode)
{
int i, regWrites = 0;
- struct ath_hal_5416 *ahp = AH5416(ah);
+ struct ieee80211_channel *channel = chan->chan;
u32 modesIndex, freqIndex;
int status;
@@ -1310,40 +1286,38 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
}
REG_WRITE(ah, AR_PHY(0), 0x00000007);
-
REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
+ ah->eep_ops->set_addac(ah, chan);
- ath9k_hw_set_addac(ah, chan);
-
- if (AR_SREV_5416_V22_OR_LATER(ah)) {
- REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
+ if (AR_SREV_5416_22_OR_LATER(ah)) {
+ REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
} else {
struct ar5416IniArray temp;
u32 addacSize =
- sizeof(u32) * ahp->ah_iniAddac.ia_rows *
- ahp->ah_iniAddac.ia_columns;
+ sizeof(u32) * ah->iniAddac.ia_rows *
+ ah->iniAddac.ia_columns;
- memcpy(ahp->ah_addac5416_21,
- ahp->ah_iniAddac.ia_array, addacSize);
+ memcpy(ah->addac5416_21,
+ ah->iniAddac.ia_array, addacSize);
- (ahp->ah_addac5416_21)[31 * ahp->ah_iniAddac.ia_columns + 1] = 0;
+ (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
- temp.ia_array = ahp->ah_addac5416_21;
- temp.ia_columns = ahp->ah_iniAddac.ia_columns;
- temp.ia_rows = ahp->ah_iniAddac.ia_rows;
+ temp.ia_array = ah->addac5416_21;
+ temp.ia_columns = ah->iniAddac.ia_columns;
+ temp.ia_rows = ah->iniAddac.ia_rows;
REG_WRITE_ARRAY(&temp, 1, regWrites);
}
REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
- for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
- u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
- u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
+ for (i = 0; i < ah->iniModes.ia_rows; i++) {
+ u32 reg = INI_RA(&ah->iniModes, i, 0);
+ u32 val = INI_RA(&ah->iniModes, i, modesIndex);
REG_WRITE(ah, reg, val);
if (reg >= 0x7800 && reg < 0x78a0
- && ah->ah_config.analog_shiftreg) {
+ && ah->config.analog_shiftreg) {
udelay(100);
}
@@ -1351,19 +1325,20 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
}
if (AR_SREV_9280(ah))
- REG_WRITE_ARRAY(&ahp->ah_iniModesRxGain, modesIndex, regWrites);
+ REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
- if (AR_SREV_9280(ah))
- REG_WRITE_ARRAY(&ahp->ah_iniModesTxGain, modesIndex, regWrites);
+ if (AR_SREV_9280(ah) || (AR_SREV_9285(ah) &&
+ AR_SREV_9285_12_OR_LATER(ah)))
+ REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
- for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
- u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
- u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
+ for (i = 0; i < ah->iniCommon.ia_rows; i++) {
+ u32 reg = INI_RA(&ah->iniCommon, i, 0);
+ u32 val = INI_RA(&ah->iniCommon, i, 1);
REG_WRITE(ah, reg, val);
if (reg >= 0x7800 && reg < 0x78a0
- && ah->ah_config.analog_shiftreg) {
+ && ah->config.analog_shiftreg) {
udelay(100);
}
@@ -1373,7 +1348,7 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
- REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
+ REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
regWrites);
}
@@ -1381,13 +1356,15 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
ath9k_hw_set_regs(ah, chan, macmode);
ath9k_hw_init_chain_masks(ah);
- status = ath9k_hw_set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
- ath9k_regd_get_antenna_allowed(ah,
- chan),
- chan->maxRegTxPower * 2,
- min((u32) MAX_RATE_POWER,
- (u32) ah->ah_powerLimit));
+ if (OLC_FOR_AR9280_20_LATER)
+ ath9k_olc_init(ah);
+
+ status = ah->eep_ops->set_txpower(ah, chan,
+ ath9k_regd_get_ctl(ah, chan),
+ channel->max_antenna_gain * 2,
+ channel->max_power * 2,
+ min((u32) MAX_RATE_POWER,
+ (u32) ah->regulatory.power_limit));
if (status != 0) {
DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
"error init'ing transmit power\n");
@@ -1407,7 +1384,7 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
/* Reset and Channel Switching Routines */
/****************************************/
-static void ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
+static void ath9k_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
{
u32 rfMode = 0;
@@ -1427,12 +1404,12 @@ static void ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
REG_WRITE(ah, AR_PHY_MODE, rfMode);
}
-static void ath9k_hw_mark_phy_inactive(struct ath_hal *ah)
+static void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
{
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
}
-static inline void ath9k_hw_set_dma(struct ath_hal *ah)
+static inline void ath9k_hw_set_dma(struct ath_hw *ah)
{
u32 regval;
@@ -1442,7 +1419,7 @@ static inline void ath9k_hw_set_dma(struct ath_hal *ah)
regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
- REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
+ REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
@@ -1458,7 +1435,7 @@ static inline void ath9k_hw_set_dma(struct ath_hal *ah)
}
}
-static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
+static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
{
u32 val;
@@ -1471,6 +1448,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
break;
case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
| AR_STA_ID1_KSRCH_MODE);
REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
@@ -1482,7 +1460,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
}
}
-static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
+static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah,
u32 coef_scaled,
u32 *coef_mantissa,
u32 *coef_exponent)
@@ -1501,7 +1479,7 @@ static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
*coef_exponent = coef_exp - 16;
}
-static void ath9k_hw_set_delta_slope(struct ath_hal *ah,
+static void ath9k_hw_set_delta_slope(struct ath_hw *ah,
struct ath9k_channel *chan)
{
u32 coef_scaled, ds_coef_exp, ds_coef_man;
@@ -1535,11 +1513,19 @@ static void ath9k_hw_set_delta_slope(struct ath_hal *ah,
AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
}
-static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
+static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
{
u32 rst_flags;
u32 tmpReg;
+ if (AR_SREV_9100(ah)) {
+ u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK);
+ val &= ~AR_RTC_DERIVED_CLK_PERIOD;
+ val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD);
+ REG_WRITE(ah, AR_RTC_DERIVED_CLK, val);
+ (void)REG_READ(ah, AR_RTC_DERIVED_CLK);
+ }
+
REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
AR_RTC_FORCE_WAKE_ON_INT);
@@ -1562,11 +1548,11 @@ static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
rst_flags |= AR_RTC_RC_MAC_COLD;
}
- REG_WRITE(ah, (u16) (AR_RTC_RC), rst_flags);
+ REG_WRITE(ah, AR_RTC_RC, rst_flags);
udelay(50);
- REG_WRITE(ah, (u16) (AR_RTC_RC), 0);
- if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) {
+ REG_WRITE(ah, AR_RTC_RC, 0);
+ if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET,
"RTC stuck in MAC reset\n");
return false;
@@ -1583,18 +1569,20 @@ static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
return true;
}
-static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
+static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
{
REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
AR_RTC_FORCE_WAKE_ON_INT);
- REG_WRITE(ah, (u16) (AR_RTC_RESET), 0);
- REG_WRITE(ah, (u16) (AR_RTC_RESET), 1);
+ REG_WRITE(ah, AR_RTC_RESET, 0);
+ udelay(2);
+ REG_WRITE(ah, AR_RTC_RESET, 1);
if (!ath9k_hw_wait(ah,
AR_RTC_STATUS,
AR_RTC_STATUS_M,
- AR_RTC_STATUS_ON)) {
+ AR_RTC_STATUS_ON,
+ AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, "RTC not waking up\n");
return false;
}
@@ -1604,7 +1592,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
}
-static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type)
+static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
{
REG_WRITE(ah, AR_RTC_FORCE_WAKE,
AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
@@ -1622,12 +1610,11 @@ static bool ath9k_hw_set_reset_reg(struct ath_hal *ah, u32 type)
}
}
-static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode)
{
u32 phymode;
u32 enableDacFifo = 0;
- struct ath_hal_5416 *ahp = AH5416(ah);
if (AR_SREV_9285_10_OR_LATER(ah))
enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
@@ -1643,7 +1630,7 @@ static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
(chan->chanmode == CHANNEL_G_HT40PLUS))
phymode |= AR_PHY_FC_DYN2040_PRI_CH;
- if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
+ if (ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
phymode |= AR_PHY_FC_DYN2040_EXT_CH;
}
REG_WRITE(ah, AR_PHY_TURBO, phymode);
@@ -1654,54 +1641,30 @@ static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
}
-static bool ath9k_hw_chip_reset(struct ath_hal *ah,
+static bool ath9k_hw_chip_reset(struct ath_hw *ah,
struct ath9k_channel *chan)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
+ if (OLC_FOR_AR9280_20_LATER) {
+ if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
+ return false;
+ } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
return false;
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
return false;
- ahp->ah_chipFullSleep = false;
-
+ ah->chip_fullsleep = false;
ath9k_hw_init_pll(ah, chan);
-
ath9k_hw_set_rfmode(ah, chan);
return true;
}
-static struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
- struct ath9k_channel *chan)
-{
- if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "invalid channel %u/0x%x; not marked as "
- "2GHz or 5GHz\n", chan->channel, chan->channelFlags);
- return NULL;
- }
-
- if (!IS_CHAN_OFDM(chan) &&
- !IS_CHAN_B(chan) &&
- !IS_CHAN_HT20(chan) &&
- !IS_CHAN_HT40(chan)) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "invalid channel %u/0x%x; not marked as "
- "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
- chan->channel, chan->channelFlags);
- return NULL;
- }
-
- return ath9k_regd_check_channel(ah, chan);
-}
-
-static bool ath9k_hw_channel_change(struct ath_hal *ah,
+static bool ath9k_hw_channel_change(struct ath_hw *ah,
struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode)
{
+ struct ieee80211_channel *channel = chan->chan;
u32 synthDelay, qnum;
for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
@@ -1714,7 +1677,7 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah,
REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
- AR_PHY_RFBUS_GRANT_EN)) {
+ AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) {
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
"Could not kill baseband RX\n");
return false;
@@ -1736,12 +1699,12 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah,
}
}
- if (ath9k_hw_set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
- ath9k_regd_get_antenna_allowed(ah, chan),
- chan->maxRegTxPower * 2,
- min((u32) MAX_RATE_POWER,
- (u32) ah->ah_powerLimit)) != 0) {
+ if (ah->eep_ops->set_txpower(ah, chan,
+ ath9k_regd_get_ctl(ah, chan),
+ channel->max_antenna_gain * 2,
+ channel->max_power * 2,
+ min((u32) MAX_RATE_POWER,
+ (u32) ah->regulatory.power_limit)) != 0) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"error init'ing transmit power\n");
return false;
@@ -1771,7 +1734,7 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah,
return true;
}
-static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan)
+static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
{
int bb_spur = AR_NO_SPUR;
int freq;
@@ -1805,9 +1768,9 @@ static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel
ath9k_hw_get_channel_centers(ah, chan, &centers);
freq = centers.synth_center;
- ah->ah_config.spurmode = SPUR_ENABLE_EEPROM;
+ ah->config.spurmode = SPUR_ENABLE_EEPROM;
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
- cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
+ cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
if (is2GHz)
cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
@@ -1918,9 +1881,9 @@ static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel
if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
/* workaround for gcc bug #37014 */
- volatile int tmp = abs(cur_vit_mask - bin);
+ volatile int tmp_v = abs(cur_vit_mask - bin);
- if (tmp < 75)
+ if (tmp_v < 75)
mask_amt = 1;
else
mask_amt = 0;
@@ -2021,7 +1984,7 @@ static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah, struct ath9k_channel
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
}
-static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *chan)
+static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
{
int bb_spur = AR_NO_SPUR;
int bin, cur_bin;
@@ -2050,7 +2013,7 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *cha
memset(&mask_p, 0, sizeof(int8_t) * 123);
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
- cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
+ cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
if (AR_NO_SPUR == cur_bb_spur)
break;
cur_bb_spur = cur_bb_spur - (chan->channel * 10);
@@ -2119,9 +2082,9 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *cha
if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
/* workaround for gcc bug #37014 */
- volatile int tmp = abs(cur_vit_mask - bin);
+ volatile int tmp_v = abs(cur_vit_mask - bin);
- if (tmp < 75)
+ if (tmp_v < 75)
mask_amt = 1;
else
mask_amt = 0;
@@ -2222,58 +2185,47 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah, struct ath9k_channel *cha
REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
}
-bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
- enum ath9k_ht_macmode macmode,
- u8 txchainmask, u8 rxchainmask,
- enum ath9k_ht_extprotspacing extprotspacing,
- bool bChannelChange, int *status)
+int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+ bool bChannelChange)
{
u32 saveLedState;
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_channel *curchan = ah->ah_curchan;
+ struct ath_softc *sc = ah->ah_sc;
+ struct ath9k_channel *curchan = ah->curchan;
u32 saveDefAntenna;
u32 macStaId1;
- int ecode;
- int i, rx_chainmask;
+ int i, rx_chainmask, r;
- ahp->ah_extprotspacing = extprotspacing;
- ahp->ah_txchainmask = txchainmask;
- ahp->ah_rxchainmask = rxchainmask;
+ ah->extprotspacing = sc->ht_extprotspacing;
+ ah->txchainmask = sc->tx_chainmask;
+ ah->rxchainmask = sc->rx_chainmask;
- if (AR_SREV_9280(ah)) {
- ahp->ah_txchainmask &= 0x3;
- ahp->ah_rxchainmask &= 0x3;
- }
-
- if (ath9k_hw_check_chan(ah, chan) == NULL) {
- DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
- "invalid channel %u/0x%x; no mapping\n",
- chan->channel, chan->channelFlags);
- ecode = -EINVAL;
- goto bad;
+ if (AR_SREV_9285(ah)) {
+ ah->txchainmask &= 0x1;
+ ah->rxchainmask &= 0x1;
+ } else if (AR_SREV_9280(ah)) {
+ ah->txchainmask &= 0x3;
+ ah->rxchainmask &= 0x3;
}
- if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
- ecode = -EIO;
- goto bad;
- }
+ if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+ return -EIO;
if (curchan)
ath9k_hw_getnf(ah, curchan);
if (bChannelChange &&
- (ahp->ah_chipFullSleep != true) &&
- (ah->ah_curchan != NULL) &&
- (chan->channel != ah->ah_curchan->channel) &&
+ (ah->chip_fullsleep != true) &&
+ (ah->curchan != NULL) &&
+ (chan->channel != ah->curchan->channel) &&
((chan->channelFlags & CHANNEL_ALL) ==
- (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
+ (ah->curchan->channelFlags & CHANNEL_ALL)) &&
(!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
- !IS_CHAN_A_5MHZ_SPACED(ah->ah_curchan)))) {
+ !IS_CHAN_A_5MHZ_SPACED(ah->curchan)))) {
- if (ath9k_hw_channel_change(ah, chan, macmode)) {
- ath9k_hw_loadnf(ah, ah->ah_curchan);
+ if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) {
+ ath9k_hw_loadnf(ah, ah->curchan);
ath9k_hw_start_nfcal(ah);
- return true;
+ return 0;
}
}
@@ -2291,28 +2243,32 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
if (!ath9k_hw_chip_reset(ah, chan)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n");
- ecode = -EINVAL;
- goto bad;
+ return -EINVAL;
}
- if (AR_SREV_9280(ah)) {
- REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
- AR_GPIO_JTAG_DISABLE);
+ if (AR_SREV_9280_10_OR_LATER(ah))
+ REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
- if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes)) {
- if (IS_CHAN_5GHZ(chan))
- ath9k_hw_set_gpio(ah, 9, 0);
- else
- ath9k_hw_set_gpio(ah, 9, 1);
- }
- ath9k_hw_cfg_output(ah, 9, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- }
+ r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width);
+ if (r)
+ return r;
- ecode = ath9k_hw_process_ini(ah, chan, macmode);
- if (ecode != 0) {
- ecode = -EINVAL;
- goto bad;
- }
+ /* Setup MFP options for CCMP */
+ if (AR_SREV_9280_20_OR_LATER(ah)) {
+ /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
+ * frames when constructing CCMP AAD. */
+ REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
+ 0xc7ff);
+ ah->sw_mgmt_crypto = false;
+ } else if (AR_SREV_9160_10_OR_LATER(ah)) {
+ /* Disable hardware crypto for management frames */
+ REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
+ AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
+ REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+ AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
+ ah->sw_mgmt_crypto = true;
+ } else
+ ah->sw_mgmt_crypto = true;
if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
ath9k_hw_set_delta_slope(ah, chan);
@@ -2322,61 +2278,52 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
else
ath9k_hw_spur_mitigate(ah, chan);
- if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
- DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
- "error setting board options\n");
- ecode = -EIO;
- goto bad;
- }
+ ah->eep_ops->set_board_values(ah, chan);
ath9k_hw_decrease_chain_power(ah, chan);
- REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
- REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
+ REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ah->macaddr));
+ REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ah->macaddr + 4)
| macStaId1
| AR_STA_ID1_RTS_USE_DEF
- | (ah->ah_config.
+ | (ah->config.
ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
- | ahp->ah_staId1Defaults);
- ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
+ | ah->sta_id1_defaults);
+ ath9k_hw_set_operating_mode(ah, ah->opmode);
- REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
- REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
+ REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
+ REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
- REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
- REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
- ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
+ REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
+ REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
+ ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
REG_WRITE(ah, AR_ISR, ~0);
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
if (AR_SREV_9280_10_OR_LATER(ah)) {
- if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
- ecode = -EIO;
- goto bad;
- }
+ if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
+ return -EIO;
} else {
- if (!(ath9k_hw_set_channel(ah, chan))) {
- ecode = -EIO;
- goto bad;
- }
+ if (!(ath9k_hw_set_channel(ah, chan)))
+ return -EIO;
}
for (i = 0; i < AR_NUM_DCU; i++)
REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
- ahp->ah_intrTxqs = 0;
- for (i = 0; i < ah->ah_caps.total_queues; i++)
+ ah->intr_txqs = 0;
+ for (i = 0; i < ah->caps.total_queues; i++)
ath9k_hw_resettxqueue(ah, i);
- ath9k_hw_init_interrupt_masks(ah, ah->ah_opmode);
+ ath9k_hw_init_interrupt_masks(ah, ah->opmode);
ath9k_hw_init_qos(ah);
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
ath9k_enable_rfkill(ah);
#endif
ath9k_hw_init_user_settings(ah);
@@ -2388,7 +2335,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_OBS, 8);
- if (ahp->ah_intrMitigation) {
+ if (ah->intr_mitigation) {
REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
@@ -2396,12 +2343,10 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
ath9k_hw_init_bb(ah, chan);
- if (!ath9k_hw_init_cal(ah, chan)){
- ecode = -EIO;;
- goto bad;
- }
+ if (!ath9k_hw_init_cal(ah, chan))
+ return -EIO;;
- rx_chainmask = ahp->ah_rxchainmask;
+ rx_chainmask = ah->rxchainmask;
if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
@@ -2428,22 +2373,18 @@ bool ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
#endif
}
- return true;
-bad:
- if (status)
- *status = ecode;
- return false;
+ return 0;
}
/************************/
/* Key Cache Management */
/************************/
-bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
+bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
{
u32 keyType;
- if (entry >= ah->ah_caps.keycache_size) {
+ if (entry >= ah->caps.keycache_size) {
DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
"entry %u out of range\n", entry);
return false;
@@ -2470,17 +2411,17 @@ bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
}
- if (ah->ah_curchan == NULL)
+ if (ah->curchan == NULL)
return true;
return true;
}
-bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac)
+bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
{
u32 macHi, macLo;
- if (entry >= ah->ah_caps.keycache_size) {
+ if (entry >= ah->caps.keycache_size) {
DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
"entry %u out of range\n", entry);
return false;
@@ -2504,17 +2445,13 @@ bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry, const u8 *mac)
return true;
}
-bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
+bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
const struct ath9k_keyval *k,
- const u8 *mac, int xorKey)
+ const u8 *mac)
{
- const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ const struct ath9k_hw_capabilities *pCap = &ah->caps;
u32 key0, key1, key2, key3, key4;
u32 keyType;
- u32 xorMask = xorKey ?
- (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
- | ATH9K_KEY_XOR) : 0;
- struct ath_hal_5416 *ahp = AH5416(ah);
if (entry >= pCap->keycache_size) {
DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
@@ -2530,7 +2467,7 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
"AES-CCM not supported by mac rev 0x%x\n",
- ah->ah_macRev);
+ ah->hw_version.macRev);
return false;
}
keyType = AR_KEYTABLE_TYPE_CCM;
@@ -2566,26 +2503,57 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
return false;
}
- key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
- key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
- key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
- key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
- key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
+ key0 = get_unaligned_le32(k->kv_val + 0);
+ key1 = get_unaligned_le16(k->kv_val + 4);
+ key2 = get_unaligned_le32(k->kv_val + 6);
+ key3 = get_unaligned_le16(k->kv_val + 10);
+ key4 = get_unaligned_le32(k->kv_val + 12);
if (k->kv_len <= LEN_WEP104)
key4 &= 0xff;
+ /*
+ * Note: Key cache registers access special memory area that requires
+ * two 32-bit writes to actually update the values in the internal
+ * memory. Consequently, the exact order and pairs used here must be
+ * maintained.
+ */
+
if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
u16 micentry = entry + 64;
+ /*
+ * Write inverted key[47:0] first to avoid Michael MIC errors
+ * on frames that could be sent or received at the same time.
+ * The correct key will be written in the end once everything
+ * else is ready.
+ */
REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
+
+ /* Write key[95:48] */
REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+
+ /* Write key[127:96] and key type */
REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+
+ /* Write MAC address for the entry */
(void) ath9k_hw_keysetmac(ah, entry, mac);
- if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
+ if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
+ /*
+ * TKIP uses two key cache entries:
+ * Michael MIC TX/RX keys in the same key cache entry
+ * (idx = main index + 64):
+ * key0 [31:0] = RX key [31:0]
+ * key1 [15:0] = TX key [31:16]
+ * key1 [31:16] = reserved
+ * key2 [31:0] = RX key [63:32]
+ * key3 [15:0] = TX key [15:0]
+ * key3 [31:16] = reserved
+ * key4 [31:0] = TX key [63:32]
+ */
u32 mic0, mic1, mic2, mic3, mic4;
mic0 = get_unaligned_le32(k->kv_mic + 0);
@@ -2593,51 +2561,90 @@ bool ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
mic4 = get_unaligned_le32(k->kv_txmic + 4);
+
+ /* Write RX[31:0] and TX[31:16] */
REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
+
+ /* Write RX[63:32] and TX[15:0] */
REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
+
+ /* Write TX[63:32] and keyType(reserved) */
REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
AR_KEYTABLE_TYPE_CLR);
} else {
+ /*
+ * TKIP uses four key cache entries (two for group
+ * keys):
+ * Michael MIC TX/RX keys are in different key cache
+ * entries (idx = main index + 64 for TX and
+ * main index + 32 + 96 for RX):
+ * key0 [31:0] = TX/RX MIC key [31:0]
+ * key1 [31:0] = reserved
+ * key2 [31:0] = TX/RX MIC key [63:32]
+ * key3 [31:0] = reserved
+ * key4 [31:0] = reserved
+ *
+ * Upper layer code will call this function separately
+ * for TX and RX keys when these registers offsets are
+ * used.
+ */
u32 mic0, mic2;
mic0 = get_unaligned_le32(k->kv_mic + 0);
mic2 = get_unaligned_le32(k->kv_mic + 4);
+
+ /* Write MIC key[31:0] */
REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
+
+ /* Write MIC key[63:32] */
REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
+
+ /* Write TX[63:32] and keyType(reserved) */
REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
AR_KEYTABLE_TYPE_CLR);
}
+
+ /* MAC address registers are reserved for the MIC entry */
REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
+
+ /*
+ * Write the correct (un-inverted) key[47:0] last to enable
+ * TKIP now that all other registers are set with correct
+ * values.
+ */
REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
} else {
+ /* Write key[47:0] */
REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+
+ /* Write key[95:48] */
REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+
+ /* Write key[127:96] and key type */
REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+ /* Write MAC address for the entry */
(void) ath9k_hw_keysetmac(ah, entry, mac);
}
- if (ah->ah_curchan == NULL)
- return true;
-
return true;
}
-bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
+bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry)
{
- if (entry < ah->ah_caps.keycache_size) {
+ if (entry < ah->caps.keycache_size) {
u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
if (val & AR_KEYTABLE_VALID)
return true;
@@ -2649,7 +2656,7 @@ bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
/* Power Management (Chipset) */
/******************************/
-static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
+static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
{
REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
if (setChip) {
@@ -2658,16 +2665,16 @@ static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
if (!AR_SREV_9100(ah))
REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
- REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
+ REG_CLR_BIT(ah, (AR_RTC_RESET),
AR_RTC_RESET_EN);
}
}
-static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
+static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
{
REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
if (setChip) {
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
REG_WRITE(ah, AR_RTC_FORCE_WAKE,
@@ -2679,8 +2686,7 @@ static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
}
}
-static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
- int setChip)
+static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
{
u32 val;
int i;
@@ -2721,20 +2727,18 @@ static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
return true;
}
-bool ath9k_hw_setpower(struct ath_hal *ah,
- enum ath9k_power_mode mode)
+bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
+ int status = true, setChip = true;
static const char *modes[] = {
"AWAKE",
"FULL-SLEEP",
"NETWORK SLEEP",
"UNDEFINED"
};
- int status = true, setChip = true;
DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n",
- modes[ahp->ah_powerMode], modes[mode],
+ modes[ah->power_mode], modes[mode],
setChip ? "set chip " : "");
switch (mode) {
@@ -2743,7 +2747,7 @@ bool ath9k_hw_setpower(struct ath_hal *ah,
break;
case ATH9K_PM_FULL_SLEEP:
ath9k_set_power_sleep(ah, setChip);
- ahp->ah_chipFullSleep = true;
+ ah->chip_fullsleep = true;
break;
case ATH9K_PM_NETWORK_SLEEP:
ath9k_set_power_network_sleep(ah, setChip);
@@ -2753,41 +2757,57 @@ bool ath9k_hw_setpower(struct ath_hal *ah,
"Unknown power mode %u\n", mode);
return false;
}
- ahp->ah_powerMode = mode;
+ ah->power_mode = mode;
return status;
}
-void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
+/*
+ * Helper for ASPM support.
+ *
+ * Disable PLL when in L0s as well as receiver clock when in L1.
+ * This power saving option must be enabled through the SerDes.
+ *
+ * Programming the SerDes must go through the same 288 bit serial shift
+ * register as the other analog registers. Hence the 9 writes.
+ */
+void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u8 i;
- if (ah->ah_isPciExpress != true)
+ if (ah->is_pciexpress != true)
return;
- if (ah->ah_config.pcie_powersave_enable == 2)
+ /* Do not touch SerDes registers */
+ if (ah->config.pcie_powersave_enable == 2)
return;
+ /* Nothing to do on restore for 11N */
if (restore)
return;
if (AR_SREV_9280_20_OR_LATER(ah)) {
- for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
- REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
- INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
+ /*
+ * AR9280 2.0 or later chips use SerDes values from the
+ * initvals.h initialized depending on chipset during
+ * ath9k_hw_do_attach()
+ */
+ for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
+ REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
+ INI_RA(&ah->iniPcieSerdes, i, 1));
}
- udelay(1000);
} else if (AR_SREV_9280(ah) &&
- (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
+ (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+ /* RX shut off when elecidle is asserted */
REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
- if (ah->ah_config.pcie_clock_req)
+ /* Shut off CLKREQ active in L1 */
+ if (ah->config.pcie_clock_req)
REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
else
REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
@@ -2796,42 +2816,59 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
+ /* Load the new settings */
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
- udelay(1000);
} else {
REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+
+ /* RX shut off when elecidle is asserted */
REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
+
+ /*
+ * Ignore ah->ah_config.pcie_clock_req setting for
+ * pre-AR9280 11n
+ */
REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
+
REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
+
+ /* Load the new settings */
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
}
+ udelay(1000);
+
+ /* set bit 19 to allow forcing of pcie core into L1 state */
REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
- if (ah->ah_config.pcie_waen) {
- REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
+ /* Several PCIe massages to ensure proper behaviour */
+ if (ah->config.pcie_waen) {
+ REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
} else {
if (AR_SREV_9285(ah))
REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
+ /*
+ * On AR9280 chips bit 22 of 0x4004 needs to be set to
+ * otherwise card may disappear.
+ */
else if (AR_SREV_9280(ah))
REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT);
else
REG_WRITE(ah, AR_WA, AR_WA_DEFAULT);
}
-
}
/**********************/
/* Interrupt Handling */
/**********************/
-bool ath9k_hw_intrpend(struct ath_hal *ah)
+bool ath9k_hw_intrpend(struct ath_hw *ah)
{
u32 host_isr;
@@ -2850,14 +2887,13 @@ bool ath9k_hw_intrpend(struct ath_hal *ah)
return false;
}
-bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
+bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
{
u32 isr = 0;
u32 mask2 = 0;
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
u32 sync_cause = 0;
bool fatal_int = false;
- struct ath_hal_5416 *ahp = AH5416(ah);
if (!AR_SREV_9100(ah)) {
if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
@@ -2895,6 +2931,8 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
mask2 |= ATH9K_INT_GTT;
if (isr2 & AR_ISR_S2_CST)
mask2 |= ATH9K_INT_CST;
+ if (isr2 & AR_ISR_S2_TSFOOR)
+ mask2 |= ATH9K_INT_TSFOOR;
}
isr = REG_READ(ah, AR_ISR_RAC);
@@ -2905,7 +2943,7 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
*masked = isr & ATH9K_INT_COMMON;
- if (ahp->ah_intrMitigation) {
+ if (ah->intr_mitigation) {
if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
*masked |= ATH9K_INT_RX;
}
@@ -2920,12 +2958,12 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
*masked |= ATH9K_INT_TX;
s0_s = REG_READ(ah, AR_ISR_S0_S);
- ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
- ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
+ ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
+ ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
s1_s = REG_READ(ah, AR_ISR_S1_S);
- ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
- ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
+ ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
+ ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
}
if (isr & AR_ISR_RXORN) {
@@ -2982,17 +3020,16 @@ bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
return true;
}
-enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
+enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah)
{
- return AH5416(ah)->ah_maskReg;
+ return ah->mask_reg;
}
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- u32 omask = ahp->ah_maskReg;
+ u32 omask = ah->mask_reg;
u32 mask, mask2;
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
@@ -3013,18 +3050,18 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
mask2 = 0;
if (ints & ATH9K_INT_TX) {
- if (ahp->ah_txOkInterruptMask)
+ if (ah->txok_interrupt_mask)
mask |= AR_IMR_TXOK;
- if (ahp->ah_txDescInterruptMask)
+ if (ah->txdesc_interrupt_mask)
mask |= AR_IMR_TXDESC;
- if (ahp->ah_txErrInterruptMask)
+ if (ah->txerr_interrupt_mask)
mask |= AR_IMR_TXERR;
- if (ahp->ah_txEolInterruptMask)
+ if (ah->txeol_interrupt_mask)
mask |= AR_IMR_TXEOL;
}
if (ints & ATH9K_INT_RX) {
mask |= AR_IMR_RXERR;
- if (ahp->ah_intrMitigation)
+ if (ah->intr_mitigation)
mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
else
mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
@@ -3041,7 +3078,9 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
if (ints & ATH9K_INT_DTIMSYNC)
mask2 |= AR_IMR_S2_DTIMSYNC;
if (ints & ATH9K_INT_CABEND)
- mask2 |= (AR_IMR_S2_CABEND);
+ mask2 |= AR_IMR_S2_CABEND;
+ if (ints & ATH9K_INT_TSFOOR)
+ mask2 |= AR_IMR_S2_TSFOOR;
}
if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
@@ -3062,7 +3101,7 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
AR_IMR_S2_TSFOOR |
AR_IMR_S2_GTT | AR_IMR_S2_CST);
REG_WRITE(ah, AR_IMR_S2, mask | mask2);
- ahp->ah_maskReg = ints;
+ ah->mask_reg = ints;
if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
if (ints & ATH9K_INT_TIM_TIMER)
@@ -3096,14 +3135,13 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
/* Beacon Handling */
/*******************/
-void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period)
+void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
int flags = 0;
- ahp->ah_beaconInterval = beacon_period;
+ ah->beacon_interval = beacon_period;
- switch (ah->ah_opmode) {
+ switch (ah->opmode) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_MONITOR:
REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
@@ -3112,22 +3150,23 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period)
flags |= AR_TBTT_TIMER_EN;
break;
case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
REG_SET_BIT(ah, AR_TXCFG,
AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
REG_WRITE(ah, AR_NEXT_NDP_TIMER,
TU_TO_USEC(next_beacon +
- (ahp->ah_atimWindow ? ahp->
- ah_atimWindow : 1)));
+ (ah->atim_window ? ah->
+ atim_window : 1)));
flags |= AR_NDP_TIMER_EN;
case NL80211_IFTYPE_AP:
REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
TU_TO_USEC(next_beacon -
- ah->ah_config.
+ ah->config.
dma_beacon_response_time));
REG_WRITE(ah, AR_NEXT_SWBA,
TU_TO_USEC(next_beacon -
- ah->ah_config.
+ ah->config.
sw_beacon_response_time));
flags |=
AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
@@ -3135,7 +3174,7 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period)
default:
DPRINTF(ah->ah_sc, ATH_DBG_BEACON,
"%s: unsupported opmode: %d\n",
- __func__, ah->ah_opmode);
+ __func__, ah->opmode);
return;
break;
}
@@ -3154,11 +3193,11 @@ void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period)
REG_SET_BIT(ah, AR_TIMER_MODE, flags);
}
-void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
+void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
const struct ath9k_beacon_state *bs)
{
u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
@@ -3212,43 +3251,46 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
AR_DTIM_TIMER_EN);
+ /* TSF Out of Range Threshold */
+ REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold);
}
/*******************/
/* HW Capabilities */
/*******************/
-bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
+bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
u16 capField = 0, eeval;
- eeval = ath9k_hw_get_eeprom(ah, EEP_REG_0);
+ eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
+ ah->regulatory.current_rd = eeval;
- ah->ah_currentRD = eeval;
-
- eeval = ath9k_hw_get_eeprom(ah, EEP_REG_1);
- ah->ah_currentRDExt = eeval;
-
- capField = ath9k_hw_get_eeprom(ah, EEP_OP_CAP);
-
- if (ah->ah_opmode != NL80211_IFTYPE_AP &&
- ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) {
- if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65)
- ah->ah_currentRD += 5;
- else if (ah->ah_currentRD == 0x41)
- ah->ah_currentRD = 0x43;
+ eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
+ if (AR_SREV_9285_10_OR_LATER(ah))
+ eeval |= AR9285_RDEXT_DEFAULT;
+ ah->regulatory.current_rd_ext = eeval;
+
+ capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
+
+ if (ah->opmode != NL80211_IFTYPE_AP &&
+ ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
+ if (ah->regulatory.current_rd == 0x64 ||
+ ah->regulatory.current_rd == 0x65)
+ ah->regulatory.current_rd += 5;
+ else if (ah->regulatory.current_rd == 0x41)
+ ah->regulatory.current_rd = 0x43;
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "regdomain mapped to 0x%x\n", ah->ah_currentRD);
+ "regdomain mapped to 0x%x\n", ah->regulatory.current_rd);
}
- eeval = ath9k_hw_get_eeprom(ah, EEP_OP_MODE);
+ eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
if (eeval & AR5416_OPFLAGS_11A) {
set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
- if (ah->ah_config.ht_enable) {
+ if (ah->config.ht_enable) {
if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
set_bit(ATH9K_MODE_11NA_HT20,
pCap->wireless_modes);
@@ -3264,7 +3306,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
if (eeval & AR5416_OPFLAGS_11G) {
set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
- if (ah->ah_config.ht_enable) {
+ if (ah->config.ht_enable) {
if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
set_bit(ATH9K_MODE_11NG_HT20,
pCap->wireless_modes);
@@ -3277,18 +3319,15 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
}
}
- pCap->tx_chainmask = ath9k_hw_get_eeprom(ah, EEP_TX_MASK);
- if ((ah->ah_isPciExpress)
- || (eeval & AR5416_OPFLAGS_11A)) {
- pCap->rx_chainmask =
- ath9k_hw_get_eeprom(ah, EEP_RX_MASK);
- } else {
- pCap->rx_chainmask =
- (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
- }
+ pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
+ if ((ah->hw_version.devid == AR5416_DEVID_PCI) &&
+ !(eeval & AR5416_OPFLAGS_11A))
+ pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
+ else
+ pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
- if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
- ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
+ if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0)))
+ ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
pCap->low_2ghz_chan = 2312;
pCap->high_2ghz_chan = 2732;
@@ -3306,7 +3345,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
- if (ah->ah_config.ht_enable)
+ if (ah->config.ht_enable)
pCap->hw_caps |= ATH9K_HW_CAP_HT;
else
pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
@@ -3332,7 +3371,9 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
pCap->num_mr_retries = 4;
pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
- if (AR_SREV_9280_10_OR_LATER(ah))
+ if (AR_SREV_9285_10_OR_LATER(ah))
+ pCap->num_gpio_pins = AR9285_NUM_GPIO;
+ else if (AR_SREV_9280_10_OR_LATER(ah))
pCap->num_gpio_pins = AR928X_NUM_GPIO;
else
pCap->num_gpio_pins = AR_NUM_GPIO;
@@ -3355,22 +3396,22 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- ah->ah_rfsilent = ath9k_hw_get_eeprom(ah, EEP_RF_SILENT);
- if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
- ah->ah_rfkill_gpio =
- MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
- ah->ah_rfkill_polarity =
- MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
+ ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
+ if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
+ ah->rfkill_gpio =
+ MS(ah->rfsilent, EEP_RFSILENT_GPIO_SEL);
+ ah->rfkill_polarity =
+ MS(ah->rfsilent, EEP_RFSILENT_POLARITY);
pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
}
#endif
- if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
- (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
- (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
- (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
- (ah->ah_macVersion == AR_SREV_VERSION_9280))
+ if ((ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) ||
+ (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) ||
+ (ah->hw_version.macVersion == AR_SREV_VERSION_9160) ||
+ (ah->hw_version.macVersion == AR_SREV_VERSION_9100) ||
+ (ah->hw_version.macVersion == AR_SREV_VERSION_9280))
pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
else
pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
@@ -3380,7 +3421,7 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
else
pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
- if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
+ if (ah->regulatory.current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) {
pCap->reg_cap =
AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
@@ -3395,19 +3436,22 @@ bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
pCap->num_antcfg_5ghz =
- ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
+ ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
pCap->num_antcfg_2ghz =
- ath9k_hw_get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
+ ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
+
+ if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) {
+ pCap->hw_caps |= ATH9K_HW_CAP_BT_COEX;
+ ah->btactive_gpio = 6;
+ ah->wlanactive_gpio = 5;
+ }
return true;
}
-bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
+bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
u32 capability, u32 *result)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
-
switch (type) {
case ATH9K_CAP_CIPHER:
switch (capability) {
@@ -3426,23 +3470,17 @@ bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
case 0:
return true;
case 1:
- return (ahp->ah_staId1Defaults &
+ return (ah->sta_id1_defaults &
AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
false;
}
case ATH9K_CAP_TKIP_SPLIT:
- return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
+ return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ?
false : true;
- case ATH9K_CAP_WME_TKIPMIC:
- return 0;
- case ATH9K_CAP_PHYCOUNTERS:
- return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
case ATH9K_CAP_DIVERSITY:
return (REG_READ(ah, AR_PHY_CCK_DETECT) &
AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
true : false;
- case ATH9K_CAP_PHYDIAG:
- return true;
case ATH9K_CAP_MCAST_KEYSRCH:
switch (capability) {
case 0:
@@ -3451,57 +3489,48 @@ bool ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
return false;
} else {
- return (ahp->ah_staId1Defaults &
+ return (ah->sta_id1_defaults &
AR_STA_ID1_MCAST_KSRCH) ? true :
false;
}
}
return false;
- case ATH9K_CAP_TSF_ADJUST:
- return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
- true : false;
- case ATH9K_CAP_RFSILENT:
- if (capability == 3)
- return false;
- case ATH9K_CAP_ANT_CFG_2GHZ:
- *result = pCap->num_antcfg_2ghz;
- return true;
- case ATH9K_CAP_ANT_CFG_5GHZ:
- *result = pCap->num_antcfg_5ghz;
- return true;
case ATH9K_CAP_TXPOW:
switch (capability) {
case 0:
return 0;
case 1:
- *result = ah->ah_powerLimit;
+ *result = ah->regulatory.power_limit;
return 0;
case 2:
- *result = ah->ah_maxPowerLevel;
+ *result = ah->regulatory.max_power_level;
return 0;
case 3:
- *result = ah->ah_tpScale;
+ *result = ah->regulatory.tp_scale;
return 0;
}
return false;
+ case ATH9K_CAP_DS:
+ return (AR_SREV_9280_20_OR_LATER(ah) &&
+ (ah->eep_ops->get_eeprom(ah, EEP_RC_CHAIN_MASK) == 1))
+ ? false : true;
default:
return false;
}
}
-bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
+bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
u32 capability, u32 setting, int *status)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 v;
switch (type) {
case ATH9K_CAP_TKIP_MIC:
if (setting)
- ahp->ah_staId1Defaults |=
+ ah->sta_id1_defaults |=
AR_STA_ID1_CRPT_MIC_ENABLE;
else
- ahp->ah_staId1Defaults &=
+ ah->sta_id1_defaults &=
~AR_STA_ID1_CRPT_MIC_ENABLE;
return true;
case ATH9K_CAP_DIVERSITY:
@@ -3514,15 +3543,9 @@ bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
return true;
case ATH9K_CAP_MCAST_KEYSRCH:
if (setting)
- ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
+ ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH;
else
- ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
- return true;
- case ATH9K_CAP_TSF_ADJUST:
- if (setting)
- ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
- else
- ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
+ ah->sta_id1_defaults &= ~AR_STA_ID1_MCAST_KSRCH;
return true;
default:
return false;
@@ -3533,7 +3556,7 @@ bool ath9k_hw_setcapability(struct ath_hal *ah, enum ath9k_capability_type type,
/* GPIO / RFKILL / Antennae */
/****************************/
-static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
+static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,
u32 gpio, u32 type)
{
int addr;
@@ -3561,11 +3584,11 @@ static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
}
}
-void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio)
+void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio)
{
u32 gpio_shift;
- ASSERT(gpio < ah->ah_caps.num_gpio_pins);
+ ASSERT(gpio < ah->caps.num_gpio_pins);
gpio_shift = gpio << 1;
@@ -3575,22 +3598,23 @@ void ath9k_hw_cfg_gpio_input(struct ath_hal *ah, u32 gpio)
(AR_GPIO_OE_OUT_DRV << gpio_shift));
}
-u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
{
- if (gpio >= ah->ah_caps.num_gpio_pins)
+#define MS_REG_READ(x, y) \
+ (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y)))
+
+ if (gpio >= ah->caps.num_gpio_pins)
return 0xffffffff;
- if (AR_SREV_9280_10_OR_LATER(ah)) {
- return (MS
- (REG_READ(ah, AR_GPIO_IN_OUT),
- AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
- } else {
- return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
- AR_GPIO_BIT(gpio)) != 0;
- }
+ if (AR_SREV_9285_10_OR_LATER(ah))
+ return MS_REG_READ(AR9285, gpio) != 0;
+ else if (AR_SREV_9280_10_OR_LATER(ah))
+ return MS_REG_READ(AR928X, gpio) != 0;
+ else
+ return MS_REG_READ(AR, gpio) != 0;
}
-void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
+void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
u32 ah_signal_type)
{
u32 gpio_shift;
@@ -3605,14 +3629,14 @@ void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
(AR_GPIO_OE_OUT_DRV << gpio_shift));
}
-void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val)
+void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
{
REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
AR_GPIO_BIT(gpio));
}
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-void ath9k_enable_rfkill(struct ath_hal *ah)
+void ath9k_enable_rfkill(struct ath_hw *ah)
{
REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
@@ -3620,50 +3644,28 @@ void ath9k_enable_rfkill(struct ath_hal *ah)
REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
AR_GPIO_INPUT_MUX2_RFSILENT);
- ath9k_hw_cfg_gpio_input(ah, ah->ah_rfkill_gpio);
+ ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
}
#endif
-int ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
-{
- struct ath9k_channel *chan = ah->ah_curchan;
- const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
- u16 ant_config;
- u32 halNumAntConfig;
-
- halNumAntConfig = IS_CHAN_2GHZ(chan) ?
- pCap->num_antcfg_2ghz : pCap->num_antcfg_5ghz;
-
- if (cfg < halNumAntConfig) {
- if (!ath9k_hw_get_eeprom_antenna_cfg(ah, chan,
- cfg, &ant_config)) {
- REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
+u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
{
return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
}
-void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
+void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
{
REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
}
-bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
+bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
enum ath9k_ant_setting settings,
struct ath9k_channel *chan,
u8 *tx_chainmask,
u8 *rx_chainmask,
u8 *antenna_cfgd)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
static u8 tx_chainmask_cfg, rx_chainmask_cfg;
if (AR_SREV_9280(ah)) {
@@ -3680,7 +3682,7 @@ bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
*antenna_cfgd = true;
break;
case ATH9K_ANT_FIXED_B:
- if (ah->ah_caps.tx_chainmask >
+ if (ah->caps.tx_chainmask >
ATH9K_ANTENNA1_CHAINMASK) {
*tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
}
@@ -3696,7 +3698,7 @@ bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
break;
}
} else {
- ahp->ah_diversityControl = settings;
+ ah->diversity_control = settings;
}
return true;
@@ -3706,7 +3708,7 @@ bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
/* General Operation */
/*********************/
-u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
+u32 ath9k_hw_getrxfilter(struct ath_hw *ah)
{
u32 bits = REG_READ(ah, AR_RX_FILTER);
u32 phybits = REG_READ(ah, AR_PHY_ERR);
@@ -3719,7 +3721,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
return bits;
}
-void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
+void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
{
u32 phybits;
@@ -3739,12 +3741,12 @@ void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
}
-bool ath9k_hw_phy_disable(struct ath_hal *ah)
+bool ath9k_hw_phy_disable(struct ath_hw *ah)
{
return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
}
-bool ath9k_hw_disable(struct ath_hal *ah)
+bool ath9k_hw_disable(struct ath_hw *ah)
{
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
return false;
@@ -3752,82 +3754,54 @@ bool ath9k_hw_disable(struct ath_hal *ah)
return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
}
-bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
+bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
{
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ath9k_channel *chan = ah->curchan;
+ struct ieee80211_channel *channel = chan->chan;
- ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
+ ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER);
- if (ath9k_hw_set_txpower(ah, chan,
- ath9k_regd_get_ctl(ah, chan),
- ath9k_regd_get_antenna_allowed(ah, chan),
- chan->maxRegTxPower * 2,
- min((u32) MAX_RATE_POWER,
- (u32) ah->ah_powerLimit)) != 0)
+ if (ah->eep_ops->set_txpower(ah, chan,
+ ath9k_regd_get_ctl(ah, chan),
+ channel->max_antenna_gain * 2,
+ channel->max_power * 2,
+ min((u32) MAX_RATE_POWER,
+ (u32) ah->regulatory.power_limit)) != 0)
return false;
return true;
}
-void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
-}
-
-bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
+void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
-
- return true;
+ memcpy(ah->macaddr, mac, ETH_ALEN);
}
-void ath9k_hw_setopmode(struct ath_hal *ah)
+void ath9k_hw_setopmode(struct ath_hw *ah)
{
- ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
+ ath9k_hw_set_operating_mode(ah, ah->opmode);
}
-void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0, u32 filter1)
+void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1)
{
REG_WRITE(ah, AR_MCAST_FIL0, filter0);
REG_WRITE(ah, AR_MCAST_FIL1, filter1);
}
-void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
+void ath9k_hw_setbssidmask(struct ath_softc *sc)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
+ REG_WRITE(sc->sc_ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
+ REG_WRITE(sc->sc_ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
}
-bool ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
+void ath9k_hw_write_associd(struct ath_softc *sc)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
-
- REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
- REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
-
- return true;
-}
-
-void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, u16 assocId)
-{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
- ahp->ah_assocId = assocId;
-
- REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
- REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
- ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
+ REG_WRITE(sc->sc_ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
+ REG_WRITE(sc->sc_ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
+ ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
}
-u64 ath9k_hw_gettsf64(struct ath_hal *ah)
+u64 ath9k_hw_gettsf64(struct ath_hw *ah)
{
u64 tsf;
@@ -3837,7 +3811,13 @@ u64 ath9k_hw_gettsf64(struct ath_hal *ah)
return tsf;
}
-void ath9k_hw_reset_tsf(struct ath_hal *ah)
+void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64)
+{
+ REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
+ REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
+}
+
+void ath9k_hw_reset_tsf(struct ath_hw *ah)
{
int count;
@@ -3854,42 +3834,65 @@ void ath9k_hw_reset_tsf(struct ath_hal *ah)
REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
}
-bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
+bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
if (setting)
- ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
+ ah->misc_mode |= AR_PCU_TX_ADD_TSF;
else
- ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
+ ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
return true;
}
-bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
+bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad slot time %u\n", us);
- ahp->ah_slottime = (u32) -1;
+ ah->slottime = (u32) -1;
return false;
} else {
REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
- ahp->ah_slottime = us;
+ ah->slottime = us;
return true;
}
}
-void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
+void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode)
{
u32 macmode;
if (mode == ATH9K_HT_MACMODE_2040 &&
- !ah->ah_config.cwm_ignore_extcca)
+ !ah->config.cwm_ignore_extcca)
macmode = AR_2040_JOINED_RX_CLEAR;
else
macmode = 0;
REG_WRITE(ah, AR_2040_MODE, macmode);
}
+
+/***************************/
+/* Bluetooth Coexistence */
+/***************************/
+
+void ath9k_hw_btcoex_enable(struct ath_hw *ah)
+{
+ /* connect bt_active to baseband */
+ REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+ (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
+ AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
+
+ REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+ AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
+
+ /* Set input mux for bt_active to gpio pin */
+ REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+ AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+ ah->btactive_gpio);
+
+ /* Configure the desired gpio port for input */
+ ath9k_hw_cfg_gpio_input(ah, ah->btactive_gpio);
+
+ /* Configure the desired GPIO port for TX_FRAME output */
+ ath9k_hw_cfg_output(ah, ah->wlanactive_gpio,
+ AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
+}
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h
index 91d8f594af81..0b594e0ee260 100644
--- a/drivers/net/wireless/ath9k/hw.h
+++ b/drivers/net/wireless/ath9k/hw.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -19,1062 +19,629 @@
#include <linux/if_ether.h>
#include <linux/delay.h>
+#include <linux/io.h>
+
+#include "mac.h"
+#include "ani.h"
+#include "eeprom.h"
+#include "calib.h"
+#include "regd.h"
+#include "reg.h"
+#include "phy.h"
+
+#define ATHEROS_VENDOR_ID 0x168c
+#define AR5416_DEVID_PCI 0x0023
+#define AR5416_DEVID_PCIE 0x0024
+#define AR9160_DEVID_PCI 0x0027
+#define AR9280_DEVID_PCI 0x0029
+#define AR9280_DEVID_PCIE 0x002a
+#define AR9285_DEVID_PCIE 0x002b
+#define AR5416_AR9100_DEVID 0x000b
+#define AR_SUBVENDOR_ID_NOG 0x0e11
+#define AR_SUBVENDOR_ID_NEW_A 0x7065
+#define AR5416_MAGIC 0x19641014
+
+/* Register read/write primitives */
+#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
+#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
+
+#define SM(_v, _f) (((_v) << _f##_S) & _f)
+#define MS(_v, _f) (((_v) & _f) >> _f##_S)
+#define REG_RMW(_a, _r, _set, _clr) \
+ REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
+#define REG_RMW_FIELD(_a, _r, _f, _v) \
+ REG_WRITE(_a, _r, \
+ (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
+#define REG_SET_BIT(_a, _r, _f) \
+ REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
+#define REG_CLR_BIT(_a, _r, _f) \
+ REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
-struct ar5416_desc {
- u32 ds_link;
- u32 ds_data;
- u32 ds_ctl0;
- u32 ds_ctl1;
- union {
- struct {
- u32 ctl2;
- u32 ctl3;
- u32 ctl4;
- u32 ctl5;
- u32 ctl6;
- u32 ctl7;
- u32 ctl8;
- u32 ctl9;
- u32 ctl10;
- u32 ctl11;
- u32 status0;
- u32 status1;
- u32 status2;
- u32 status3;
- u32 status4;
- u32 status5;
- u32 status6;
- u32 status7;
- u32 status8;
- u32 status9;
- } tx;
- struct {
- u32 status0;
- u32 status1;
- u32 status2;
- u32 status3;
- u32 status4;
- u32 status5;
- u32 status6;
- u32 status7;
- u32 status8;
- } rx;
- } u;
-} __packed;
-
-#define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds))
-#define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds))
-
-#define ds_ctl2 u.tx.ctl2
-#define ds_ctl3 u.tx.ctl3
-#define ds_ctl4 u.tx.ctl4
-#define ds_ctl5 u.tx.ctl5
-#define ds_ctl6 u.tx.ctl6
-#define ds_ctl7 u.tx.ctl7
-#define ds_ctl8 u.tx.ctl8
-#define ds_ctl9 u.tx.ctl9
-#define ds_ctl10 u.tx.ctl10
-#define ds_ctl11 u.tx.ctl11
-
-#define ds_txstatus0 u.tx.status0
-#define ds_txstatus1 u.tx.status1
-#define ds_txstatus2 u.tx.status2
-#define ds_txstatus3 u.tx.status3
-#define ds_txstatus4 u.tx.status4
-#define ds_txstatus5 u.tx.status5
-#define ds_txstatus6 u.tx.status6
-#define ds_txstatus7 u.tx.status7
-#define ds_txstatus8 u.tx.status8
-#define ds_txstatus9 u.tx.status9
-
-#define ds_rxstatus0 u.rx.status0
-#define ds_rxstatus1 u.rx.status1
-#define ds_rxstatus2 u.rx.status2
-#define ds_rxstatus3 u.rx.status3
-#define ds_rxstatus4 u.rx.status4
-#define ds_rxstatus5 u.rx.status5
-#define ds_rxstatus6 u.rx.status6
-#define ds_rxstatus7 u.rx.status7
-#define ds_rxstatus8 u.rx.status8
-
-#define AR_FrameLen 0x00000fff
-#define AR_VirtMoreFrag 0x00001000
-#define AR_TxCtlRsvd00 0x0000e000
-#define AR_XmitPower 0x003f0000
-#define AR_XmitPower_S 16
-#define AR_RTSEnable 0x00400000
-#define AR_VEOL 0x00800000
-#define AR_ClrDestMask 0x01000000
-#define AR_TxCtlRsvd01 0x1e000000
-#define AR_TxIntrReq 0x20000000
-#define AR_DestIdxValid 0x40000000
-#define AR_CTSEnable 0x80000000
-
-#define AR_BufLen 0x00000fff
-#define AR_TxMore 0x00001000
-#define AR_DestIdx 0x000fe000
-#define AR_DestIdx_S 13
-#define AR_FrameType 0x00f00000
-#define AR_FrameType_S 20
-#define AR_NoAck 0x01000000
-#define AR_InsertTS 0x02000000
-#define AR_CorruptFCS 0x04000000
-#define AR_ExtOnly 0x08000000
-#define AR_ExtAndCtl 0x10000000
-#define AR_MoreAggr 0x20000000
-#define AR_IsAggr 0x40000000
-
-#define AR_BurstDur 0x00007fff
-#define AR_BurstDur_S 0
-#define AR_DurUpdateEna 0x00008000
-#define AR_XmitDataTries0 0x000f0000
-#define AR_XmitDataTries0_S 16
-#define AR_XmitDataTries1 0x00f00000
-#define AR_XmitDataTries1_S 20
-#define AR_XmitDataTries2 0x0f000000
-#define AR_XmitDataTries2_S 24
-#define AR_XmitDataTries3 0xf0000000
-#define AR_XmitDataTries3_S 28
-
-#define AR_XmitRate0 0x000000ff
-#define AR_XmitRate0_S 0
-#define AR_XmitRate1 0x0000ff00
-#define AR_XmitRate1_S 8
-#define AR_XmitRate2 0x00ff0000
-#define AR_XmitRate2_S 16
-#define AR_XmitRate3 0xff000000
-#define AR_XmitRate3_S 24
-
-#define AR_PacketDur0 0x00007fff
-#define AR_PacketDur0_S 0
-#define AR_RTSCTSQual0 0x00008000
-#define AR_PacketDur1 0x7fff0000
-#define AR_PacketDur1_S 16
-#define AR_RTSCTSQual1 0x80000000
-
-#define AR_PacketDur2 0x00007fff
-#define AR_PacketDur2_S 0
-#define AR_RTSCTSQual2 0x00008000
-#define AR_PacketDur3 0x7fff0000
-#define AR_PacketDur3_S 16
-#define AR_RTSCTSQual3 0x80000000
-
-#define AR_AggrLen 0x0000ffff
-#define AR_AggrLen_S 0
-#define AR_TxCtlRsvd60 0x00030000
-#define AR_PadDelim 0x03fc0000
-#define AR_PadDelim_S 18
-#define AR_EncrType 0x0c000000
-#define AR_EncrType_S 26
-#define AR_TxCtlRsvd61 0xf0000000
-
-#define AR_2040_0 0x00000001
-#define AR_GI0 0x00000002
-#define AR_ChainSel0 0x0000001c
-#define AR_ChainSel0_S 2
-#define AR_2040_1 0x00000020
-#define AR_GI1 0x00000040
-#define AR_ChainSel1 0x00000380
-#define AR_ChainSel1_S 7
-#define AR_2040_2 0x00000400
-#define AR_GI2 0x00000800
-#define AR_ChainSel2 0x00007000
-#define AR_ChainSel2_S 12
-#define AR_2040_3 0x00008000
-#define AR_GI3 0x00010000
-#define AR_ChainSel3 0x000e0000
-#define AR_ChainSel3_S 17
-#define AR_RTSCTSRate 0x0ff00000
-#define AR_RTSCTSRate_S 20
-#define AR_TxCtlRsvd70 0xf0000000
-
-#define AR_TxRSSIAnt00 0x000000ff
-#define AR_TxRSSIAnt00_S 0
-#define AR_TxRSSIAnt01 0x0000ff00
-#define AR_TxRSSIAnt01_S 8
-#define AR_TxRSSIAnt02 0x00ff0000
-#define AR_TxRSSIAnt02_S 16
-#define AR_TxStatusRsvd00 0x3f000000
-#define AR_TxBaStatus 0x40000000
-#define AR_TxStatusRsvd01 0x80000000
-
-#define AR_FrmXmitOK 0x00000001
-#define AR_ExcessiveRetries 0x00000002
-#define AR_FIFOUnderrun 0x00000004
-#define AR_Filtered 0x00000008
-#define AR_RTSFailCnt 0x000000f0
-#define AR_RTSFailCnt_S 4
-#define AR_DataFailCnt 0x00000f00
-#define AR_DataFailCnt_S 8
-#define AR_VirtRetryCnt 0x0000f000
-#define AR_VirtRetryCnt_S 12
-#define AR_TxDelimUnderrun 0x00010000
-#define AR_TxDataUnderrun 0x00020000
-#define AR_DescCfgErr 0x00040000
-#define AR_TxTimerExpired 0x00080000
-#define AR_TxStatusRsvd10 0xfff00000
-
-#define AR_SendTimestamp ds_txstatus2
-#define AR_BaBitmapLow ds_txstatus3
-#define AR_BaBitmapHigh ds_txstatus4
-
-#define AR_TxRSSIAnt10 0x000000ff
-#define AR_TxRSSIAnt10_S 0
-#define AR_TxRSSIAnt11 0x0000ff00
-#define AR_TxRSSIAnt11_S 8
-#define AR_TxRSSIAnt12 0x00ff0000
-#define AR_TxRSSIAnt12_S 16
-#define AR_TxRSSICombined 0xff000000
-#define AR_TxRSSICombined_S 24
-
-#define AR_TxEVM0 ds_txstatus5
-#define AR_TxEVM1 ds_txstatus6
-#define AR_TxEVM2 ds_txstatus7
-
-#define AR_TxDone 0x00000001
-#define AR_SeqNum 0x00001ffe
-#define AR_SeqNum_S 1
-#define AR_TxStatusRsvd80 0x0001e000
-#define AR_TxOpExceeded 0x00020000
-#define AR_TxStatusRsvd81 0x001c0000
-#define AR_FinalTxIdx 0x00600000
-#define AR_FinalTxIdx_S 21
-#define AR_TxStatusRsvd82 0x01800000
-#define AR_PowerMgmt 0x02000000
-#define AR_TxStatusRsvd83 0xfc000000
-
-#define AR_RxCTLRsvd00 0xffffffff
-
-#define AR_BufLen 0x00000fff
-#define AR_RxCtlRsvd00 0x00001000
-#define AR_RxIntrReq 0x00002000
-#define AR_RxCtlRsvd01 0xffffc000
-
-#define AR_RxRSSIAnt00 0x000000ff
-#define AR_RxRSSIAnt00_S 0
-#define AR_RxRSSIAnt01 0x0000ff00
-#define AR_RxRSSIAnt01_S 8
-#define AR_RxRSSIAnt02 0x00ff0000
-#define AR_RxRSSIAnt02_S 16
-#define AR_RxRate 0xff000000
-#define AR_RxRate_S 24
-#define AR_RxStatusRsvd00 0xff000000
-
-#define AR_DataLen 0x00000fff
-#define AR_RxMore 0x00001000
-#define AR_NumDelim 0x003fc000
-#define AR_NumDelim_S 14
-#define AR_RxStatusRsvd10 0xff800000
-
-#define AR_RcvTimestamp ds_rxstatus2
-
-#define AR_GI 0x00000001
-#define AR_2040 0x00000002
-#define AR_Parallel40 0x00000004
-#define AR_Parallel40_S 2
-#define AR_RxStatusRsvd30 0x000000f8
-#define AR_RxAntenna 0xffffff00
-#define AR_RxAntenna_S 8
-
-#define AR_RxRSSIAnt10 0x000000ff
-#define AR_RxRSSIAnt10_S 0
-#define AR_RxRSSIAnt11 0x0000ff00
-#define AR_RxRSSIAnt11_S 8
-#define AR_RxRSSIAnt12 0x00ff0000
-#define AR_RxRSSIAnt12_S 16
-#define AR_RxRSSICombined 0xff000000
-#define AR_RxRSSICombined_S 24
-
-#define AR_RxEVM0 ds_rxstatus4
-#define AR_RxEVM1 ds_rxstatus5
-#define AR_RxEVM2 ds_rxstatus6
-
-#define AR_RxDone 0x00000001
-#define AR_RxFrameOK 0x00000002
-#define AR_CRCErr 0x00000004
-#define AR_DecryptCRCErr 0x00000008
-#define AR_PHYErr 0x00000010
-#define AR_MichaelErr 0x00000020
-#define AR_PreDelimCRCErr 0x00000040
-#define AR_RxStatusRsvd70 0x00000080
-#define AR_RxKeyIdxValid 0x00000100
-#define AR_KeyIdx 0x0000fe00
-#define AR_KeyIdx_S 9
-#define AR_PHYErrCode 0x0000ff00
-#define AR_PHYErrCode_S 8
-#define AR_RxMoreAggr 0x00010000
-#define AR_RxAggr 0x00020000
-#define AR_PostDelimCRCErr 0x00040000
-#define AR_RxStatusRsvd71 0x3ff80000
-#define AR_DecryptBusyErr 0x40000000
-#define AR_KeyMiss 0x80000000
-
-#define AR5416_MAGIC 0x19641014
-
-#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
- MS(ads->ds_rxstatus0, AR_RxRate) : \
- (ads->ds_rxstatus3 >> 2) & 0xFF)
-
-#define set11nTries(_series, _index) \
- (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
-
-#define set11nRate(_series, _index) \
- (SM((_series)[_index].Rate, AR_XmitRate##_index))
-
-#define set11nPktDurRTSCTS(_series, _index) \
- (SM((_series)[_index].PktDuration, AR_PacketDur##_index) | \
- ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS ? \
- AR_RTSCTSQual##_index : 0))
+#define DO_DELAY(x) do { \
+ if ((++(x) % 64) == 0) \
+ udelay(1); \
+ } while (0)
-#define set11nRateFlags(_series, _index) \
- (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \
- AR_2040_##_index : 0) \
- |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \
- AR_GI##_index : 0) \
- |SM((_series)[_index].ChSel, AR_ChainSel##_index))
+#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
+ int r; \
+ for (r = 0; r < ((iniarray)->ia_rows); r++) { \
+ REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
+ INI_RA((iniarray), r, (column))); \
+ DO_DELAY(regWr); \
+ } \
+ } while (0)
-#define AR_SREV_9100(ah) ((ah->ah_macVersion) == AR_SREV_VERSION_9100)
+#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2
+#define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME 3
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6
-#define INIT_CONFIG_STATUS 0x00000000
-#define INIT_RSSI_THR 0x00000700
-#define INIT_BCON_CNTRL_REG 0x00000000
+#define AR_GPIOD_MASK 0x00001FFF
+#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
-#define MIN_TX_FIFO_THRESHOLD 0x1
-#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1)
-#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD
+#define BASE_ACTIVATE_DELAY 100
+#define RTC_PLL_SETTLE_DELAY 1000
+#define COEF_SCALE_S 24
+#define HT40_CHANNEL_CENTER_SHIFT 10
-struct ar5416AniState {
- struct ath9k_channel c;
- u8 noiseImmunityLevel;
- u8 spurImmunityLevel;
- u8 firstepLevel;
- u8 ofdmWeakSigDetectOff;
- u8 cckWeakSigThreshold;
- u32 listenTime;
- u32 ofdmTrigHigh;
- u32 ofdmTrigLow;
- int32_t cckTrigHigh;
- int32_t cckTrigLow;
- int32_t rssiThrLow;
- int32_t rssiThrHigh;
- u32 noiseFloor;
- u32 txFrameCount;
- u32 rxFrameCount;
- u32 cycleCount;
- u32 ofdmPhyErrCount;
- u32 cckPhyErrCount;
- u32 ofdmPhyErrBase;
- u32 cckPhyErrBase;
- int16_t pktRssi[2];
- int16_t ofdmErrRssi[2];
- int16_t cckErrRssi[2];
+#define ATH9K_ANTENNA0_CHAINMASK 0x1
+#define ATH9K_ANTENNA1_CHAINMASK 0x2
+
+#define ATH9K_NUM_DMA_DEBUG_REGS 8
+#define ATH9K_NUM_QUEUES 10
+
+#define MAX_RATE_POWER 63
+#define AH_WAIT_TIMEOUT 100000 /* (us) */
+#define AH_TIME_QUANTUM 10
+#define AR_KEYTABLE_SIZE 128
+#define POWER_UP_TIME 200000
+#define SPUR_RSSI_THRESH 40
+
+#define CAB_TIMEOUT_VAL 10
+#define BEACON_TIMEOUT_VAL 10
+#define MIN_BEACON_TIMEOUT_VAL 1
+#define SLEEP_SLOP 3
+
+#define INIT_CONFIG_STATUS 0x00000000
+#define INIT_RSSI_THR 0x00000700
+#define INIT_BCON_CNTRL_REG 0x00000000
+
+#define TU_TO_USEC(_tu) ((_tu) << 10)
+
+enum wireless_mode {
+ ATH9K_MODE_11A = 0,
+ ATH9K_MODE_11B = 2,
+ ATH9K_MODE_11G = 3,
+ ATH9K_MODE_11NA_HT20 = 6,
+ ATH9K_MODE_11NG_HT20 = 7,
+ ATH9K_MODE_11NA_HT40PLUS = 8,
+ ATH9K_MODE_11NA_HT40MINUS = 9,
+ ATH9K_MODE_11NG_HT40PLUS = 10,
+ ATH9K_MODE_11NG_HT40MINUS = 11,
+ ATH9K_MODE_MAX
};
-#define HAL_PROCESS_ANI 0x00000001
-#define DO_ANI(ah) \
- ((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI))
-
-struct ar5416Stats {
- u32 ast_ani_niup;
- u32 ast_ani_nidown;
- u32 ast_ani_spurup;
- u32 ast_ani_spurdown;
- u32 ast_ani_ofdmon;
- u32 ast_ani_ofdmoff;
- u32 ast_ani_cckhigh;
- u32 ast_ani_ccklow;
- u32 ast_ani_stepup;
- u32 ast_ani_stepdown;
- u32 ast_ani_ofdmerrs;
- u32 ast_ani_cckerrs;
- u32 ast_ani_reset;
- u32 ast_ani_lzero;
- u32 ast_ani_lneg;
- struct ath9k_mib_stats ast_mibstats;
- struct ath9k_node_stats ast_nodestats;
+enum ath9k_hw_caps {
+ ATH9K_HW_CAP_CHAN_SPREAD = BIT(0),
+ ATH9K_HW_CAP_MIC_AESCCM = BIT(1),
+ ATH9K_HW_CAP_MIC_CKIP = BIT(2),
+ ATH9K_HW_CAP_MIC_TKIP = BIT(3),
+ ATH9K_HW_CAP_CIPHER_AESCCM = BIT(4),
+ ATH9K_HW_CAP_CIPHER_CKIP = BIT(5),
+ ATH9K_HW_CAP_CIPHER_TKIP = BIT(6),
+ ATH9K_HW_CAP_VEOL = BIT(7),
+ ATH9K_HW_CAP_BSSIDMASK = BIT(8),
+ ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(9),
+ ATH9K_HW_CAP_CHAN_HALFRATE = BIT(10),
+ ATH9K_HW_CAP_CHAN_QUARTERRATE = BIT(11),
+ ATH9K_HW_CAP_HT = BIT(12),
+ ATH9K_HW_CAP_GTT = BIT(13),
+ ATH9K_HW_CAP_FASTCC = BIT(14),
+ ATH9K_HW_CAP_RFSILENT = BIT(15),
+ ATH9K_HW_CAP_WOW = BIT(16),
+ ATH9K_HW_CAP_CST = BIT(17),
+ ATH9K_HW_CAP_ENHANCEDPM = BIT(18),
+ ATH9K_HW_CAP_AUTOSLEEP = BIT(19),
+ ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(20),
+ ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT = BIT(21),
+ ATH9K_HW_CAP_BT_COEX = BIT(22)
};
-#define AR5416_OPFLAGS_11A 0x01
-#define AR5416_OPFLAGS_11G 0x02
-#define AR5416_OPFLAGS_N_5G_HT40 0x04
-#define AR5416_OPFLAGS_N_2G_HT40 0x08
-#define AR5416_OPFLAGS_N_5G_HT20 0x10
-#define AR5416_OPFLAGS_N_2G_HT20 0x20
-
-#define EEP_RFSILENT_ENABLED 0x0001
-#define EEP_RFSILENT_ENABLED_S 0
-#define EEP_RFSILENT_POLARITY 0x0002
-#define EEP_RFSILENT_POLARITY_S 1
-#define EEP_RFSILENT_GPIO_SEL 0x001c
-#define EEP_RFSILENT_GPIO_SEL_S 2
-
-#define AR5416_EEP_NO_BACK_VER 0x1
-#define AR5416_EEP_VER 0xE
-#define AR5416_EEP_VER_MINOR_MASK 0x0FFF
-#define AR5416_EEP_MINOR_VER_2 0x2
-#define AR5416_EEP_MINOR_VER_3 0x3
-#define AR5416_EEP_MINOR_VER_7 0x7
-#define AR5416_EEP_MINOR_VER_9 0x9
-#define AR5416_EEP_MINOR_VER_16 0x10
-#define AR5416_EEP_MINOR_VER_17 0x11
-#define AR5416_EEP_MINOR_VER_19 0x13
-
-#define AR5416_NUM_5G_CAL_PIERS 8
-#define AR5416_NUM_2G_CAL_PIERS 4
-#define AR5416_NUM_5G_20_TARGET_POWERS 8
-#define AR5416_NUM_5G_40_TARGET_POWERS 8
-#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
-#define AR5416_NUM_2G_20_TARGET_POWERS 4
-#define AR5416_NUM_2G_40_TARGET_POWERS 4
-#define AR5416_NUM_CTLS 24
-#define AR5416_NUM_BAND_EDGES 8
-#define AR5416_NUM_PD_GAINS 4
-#define AR5416_PD_GAINS_IN_MASK 4
-#define AR5416_PD_GAIN_ICEPTS 5
-#define AR5416_EEPROM_MODAL_SPURS 5
-#define AR5416_MAX_RATE_POWER 63
-#define AR5416_NUM_PDADC_VALUES 128
-#define AR5416_BCHAN_UNUSED 0xFF
-#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
-#define AR5416_MAX_CHAINS 3
-#define AR5416_PWR_TABLE_OFFSET -5
-
-/* Rx gain type values */
-#define AR5416_EEP_RXGAIN_23DB_BACKOFF 0
-#define AR5416_EEP_RXGAIN_13DB_BACKOFF 1
-#define AR5416_EEP_RXGAIN_ORIG 2
-
-/* Tx gain type values */
-#define AR5416_EEP_TXGAIN_ORIGINAL 0
-#define AR5416_EEP_TXGAIN_HIGH_POWER 1
-
-#define AR5416_EEP4K_START_LOC 64
-#define AR5416_EEP4K_NUM_2G_CAL_PIERS 3
-#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
-#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS 3
-#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS 3
-#define AR5416_EEP4K_NUM_CTLS 12
-#define AR5416_EEP4K_NUM_BAND_EDGES 4
-#define AR5416_EEP4K_NUM_PD_GAINS 2
-#define AR5416_EEP4K_PD_GAINS_IN_MASK 4
-#define AR5416_EEP4K_PD_GAIN_ICEPTS 5
-#define AR5416_EEP4K_MAX_CHAINS 1
-
-enum eeprom_param {
- EEP_NFTHRESH_5,
- EEP_NFTHRESH_2,
- EEP_MAC_MSW,
- EEP_MAC_MID,
- EEP_MAC_LSW,
- EEP_REG_0,
- EEP_REG_1,
- EEP_OP_CAP,
- EEP_OP_MODE,
- EEP_RF_SILENT,
- EEP_OB_5,
- EEP_DB_5,
- EEP_OB_2,
- EEP_DB_2,
- EEP_MINOR_REV,
- EEP_TX_MASK,
- EEP_RX_MASK,
- EEP_RXGAIN_TYPE,
- EEP_TXGAIN_TYPE,
+enum ath9k_capability_type {
+ ATH9K_CAP_CIPHER = 0,
+ ATH9K_CAP_TKIP_MIC,
+ ATH9K_CAP_TKIP_SPLIT,
+ ATH9K_CAP_DIVERSITY,
+ ATH9K_CAP_TXPOW,
+ ATH9K_CAP_MCAST_KEYSRCH,
+ ATH9K_CAP_DS
};
-enum ar5416_rates {
- rate6mb, rate9mb, rate12mb, rate18mb,
- rate24mb, rate36mb, rate48mb, rate54mb,
- rate1l, rate2l, rate2s, rate5_5l,
- rate5_5s, rate11l, rate11s, rateXr,
- rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
- rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
- rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
- rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
- rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
- Ar5416RateSize
+struct ath9k_hw_capabilities {
+ u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
+ DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
+ u16 total_queues;
+ u16 keycache_size;
+ u16 low_5ghz_chan, high_5ghz_chan;
+ u16 low_2ghz_chan, high_2ghz_chan;
+ u16 num_mr_retries;
+ u16 rts_aggr_limit;
+ u8 tx_chainmask;
+ u8 rx_chainmask;
+ u16 tx_triglevel_max;
+ u16 reg_cap;
+ u8 num_gpio_pins;
+ u8 num_antcfg_2ghz;
+ u8 num_antcfg_5ghz;
};
-enum ath9k_hal_freq_band {
- ATH9K_HAL_FREQ_BAND_5GHZ = 0,
- ATH9K_HAL_FREQ_BAND_2GHZ = 1
+struct ath9k_ops_config {
+ int dma_beacon_response_time;
+ int sw_beacon_response_time;
+ int additional_swba_backoff;
+ int ack_6mb;
+ int cwm_ignore_extcca;
+ u8 pcie_powersave_enable;
+ u8 pcie_l1skp_enable;
+ u8 pcie_clock_req;
+ u32 pcie_waen;
+ int pcie_power_reset;
+ u8 pcie_restore;
+ u8 analog_shiftreg;
+ u8 ht_enable;
+ u32 ofdm_trig_low;
+ u32 ofdm_trig_high;
+ u32 cck_trig_high;
+ u32 cck_trig_low;
+ u32 enable_ani;
+ u8 noise_immunity_level;
+ u32 ofdm_weaksignal_det;
+ u32 cck_weaksignal_thr;
+ u8 spur_immunity_level;
+ u8 firstep_level;
+ int8_t rssi_thr_high;
+ int8_t rssi_thr_low;
+ u16 diversity_control;
+ u16 antenna_switch_swap;
+ int serialize_regmode;
+ int intr_mitigation;
+#define SPUR_DISABLE 0
+#define SPUR_ENABLE_IOCTL 1
+#define SPUR_ENABLE_EEPROM 2
+#define AR_EEPROM_MODAL_SPURS 5
+#define AR_SPUR_5413_1 1640
+#define AR_SPUR_5413_2 1200
+#define AR_NO_SPUR 0x8000
+#define AR_BASE_FREQ_2GHZ 2300
+#define AR_BASE_FREQ_5GHZ 4900
+#define AR_SPUR_FEEQ_BOUND_HT40 19
+#define AR_SPUR_FEEQ_BOUND_HT20 10
+ int spurmode;
+ u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
};
-struct base_eep_header {
- u16 length;
- u16 checksum;
- u16 version;
- u8 opCapFlags;
- u8 eepMisc;
- u16 regDmn[2];
- u8 macAddr[6];
- u8 rxMask;
- u8 txMask;
- u16 rfSilent;
- u16 blueToothOptions;
- u16 deviceCap;
- u32 binBuildNumber;
- u8 deviceType;
- u8 pwdclkind;
- u8 futureBase_1[2];
- u8 rxGainType;
- u8 futureBase_2[3];
- u8 txGainType;
- u8 futureBase_3[25];
-} __packed;
-
-struct base_eep_header_4k {
- u16 length;
- u16 checksum;
- u16 version;
- u8 opCapFlags;
- u8 eepMisc;
- u16 regDmn[2];
- u8 macAddr[6];
- u8 rxMask;
- u8 txMask;
- u16 rfSilent;
- u16 blueToothOptions;
- u16 deviceCap;
- u32 binBuildNumber;
- u8 deviceType;
- u8 futureBase[1];
-} __packed;
-
-
-struct spur_chan {
- u16 spurChan;
- u8 spurRangeLow;
- u8 spurRangeHigh;
-} __packed;
-
-struct modal_eep_header {
- u32 antCtrlChain[AR5416_MAX_CHAINS];
- u32 antCtrlCommon;
- u8 antennaGainCh[AR5416_MAX_CHAINS];
- u8 switchSettling;
- u8 txRxAttenCh[AR5416_MAX_CHAINS];
- u8 rxTxMarginCh[AR5416_MAX_CHAINS];
- u8 adcDesiredSize;
- u8 pgaDesiredSize;
- u8 xlnaGainCh[AR5416_MAX_CHAINS];
- u8 txEndToXpaOff;
- u8 txEndToRxOn;
- u8 txFrameToXpaOn;
- u8 thresh62;
- u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
- u8 xpdGain;
- u8 xpd;
- u8 iqCalICh[AR5416_MAX_CHAINS];
- u8 iqCalQCh[AR5416_MAX_CHAINS];
- u8 pdGainOverlap;
- u8 ob;
- u8 db;
- u8 xpaBiasLvl;
- u8 pwrDecreaseFor2Chain;
- u8 pwrDecreaseFor3Chain;
- u8 txFrameToDataStart;
- u8 txFrameToPaOn;
- u8 ht40PowerIncForPdadc;
- u8 bswAtten[AR5416_MAX_CHAINS];
- u8 bswMargin[AR5416_MAX_CHAINS];
- u8 swSettleHt40;
- u8 xatten2Db[AR5416_MAX_CHAINS];
- u8 xatten2Margin[AR5416_MAX_CHAINS];
- u8 ob_ch1;
- u8 db_ch1;
- u8 useAnt1:1,
- force_xpaon:1,
- local_bias:1,
- femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
- u8 futureModalar9280;
- u16 xpaBiasLvlFreq[3];
- u8 futureModal[6];
-
- struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
-} __packed;
-
-struct modal_eep_4k_header {
- u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
- u32 antCtrlCommon;
- u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
- u8 switchSettling;
- u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
- u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
- u8 adcDesiredSize;
- u8 pgaDesiredSize;
- u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
- u8 txEndToXpaOff;
- u8 txEndToRxOn;
- u8 txFrameToXpaOn;
- u8 thresh62;
- u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
- u8 xpdGain;
- u8 xpd;
- u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS];
- u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
- u8 pdGainOverlap;
- u8 ob_01;
- u8 db1_01;
- u8 xpaBiasLvl;
- u8 txFrameToDataStart;
- u8 txFrameToPaOn;
- u8 ht40PowerIncForPdadc;
- u8 bswAtten[AR5416_EEP4K_MAX_CHAINS];
- u8 bswMargin[AR5416_EEP4K_MAX_CHAINS];
- u8 swSettleHt40;
- u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS];
- u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
- u8 db2_01;
- u8 version;
- u16 ob_234;
- u16 db1_234;
- u16 db2_234;
- u8 futureModal[4];
-
- struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
-} __packed;
-
-
-struct cal_data_per_freq {
- u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
- u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-} __packed;
-
-struct cal_data_per_freq_4k {
- u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
- u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
-} __packed;
-
-struct cal_target_power_leg {
- u8 bChannel;
- u8 tPow2x[4];
-} __packed;
-
-struct cal_target_power_ht {
- u8 bChannel;
- u8 tPow2x[8];
-} __packed;
-
-
-#ifdef __BIG_ENDIAN_BITFIELD
-struct cal_ctl_edges {
- u8 bChannel;
- u8 flag:2, tPower:6;
-} __packed;
-#else
-struct cal_ctl_edges {
- u8 bChannel;
- u8 tPower:6, flag:2;
-} __packed;
-#endif
-
-struct cal_ctl_data {
- struct cal_ctl_edges
- ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
-} __packed;
-
-struct cal_ctl_data_4k {
- struct cal_ctl_edges
- ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
-} __packed;
-
-struct ar5416_eeprom_def {
- struct base_eep_header baseEepHeader;
- u8 custData[64];
- struct modal_eep_header modalHeader[2];
- u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
- u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
- struct cal_data_per_freq
- calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
- struct cal_data_per_freq
- calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
- struct cal_target_power_leg
- calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
- struct cal_target_power_ht
- calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
- struct cal_target_power_ht
- calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
- struct cal_target_power_leg
- calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
- struct cal_target_power_leg
- calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
- struct cal_target_power_ht
- calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
- struct cal_target_power_ht
- calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
- u8 ctlIndex[AR5416_NUM_CTLS];
- struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
- u8 padding;
-} __packed;
-
-struct ar5416_eeprom_4k {
- struct base_eep_header_4k baseEepHeader;
- u8 custData[20];
- struct modal_eep_4k_header modalHeader;
- u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
- struct cal_data_per_freq_4k
- calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
- struct cal_target_power_leg
- calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
- struct cal_target_power_leg
- calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
- struct cal_target_power_ht
- calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
- struct cal_target_power_ht
- calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
- u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
- struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
- u8 padding;
-} __packed;
-
-struct ar5416IniArray {
- u32 *ia_array;
- u32 ia_rows;
- u32 ia_columns;
+enum ath9k_int {
+ ATH9K_INT_RX = 0x00000001,
+ ATH9K_INT_RXDESC = 0x00000002,
+ ATH9K_INT_RXNOFRM = 0x00000008,
+ ATH9K_INT_RXEOL = 0x00000010,
+ ATH9K_INT_RXORN = 0x00000020,
+ ATH9K_INT_TX = 0x00000040,
+ ATH9K_INT_TXDESC = 0x00000080,
+ ATH9K_INT_TIM_TIMER = 0x00000100,
+ ATH9K_INT_TXURN = 0x00000800,
+ ATH9K_INT_MIB = 0x00001000,
+ ATH9K_INT_RXPHY = 0x00004000,
+ ATH9K_INT_RXKCM = 0x00008000,
+ ATH9K_INT_SWBA = 0x00010000,
+ ATH9K_INT_BMISS = 0x00040000,
+ ATH9K_INT_BNR = 0x00100000,
+ ATH9K_INT_TIM = 0x00200000,
+ ATH9K_INT_DTIM = 0x00400000,
+ ATH9K_INT_DTIMSYNC = 0x00800000,
+ ATH9K_INT_GPIO = 0x01000000,
+ ATH9K_INT_CABEND = 0x02000000,
+ ATH9K_INT_TSFOOR = 0x04000000,
+ ATH9K_INT_CST = 0x10000000,
+ ATH9K_INT_GTT = 0x20000000,
+ ATH9K_INT_FATAL = 0x40000000,
+ ATH9K_INT_GLOBAL = 0x80000000,
+ ATH9K_INT_BMISC = ATH9K_INT_TIM |
+ ATH9K_INT_DTIM |
+ ATH9K_INT_DTIMSYNC |
+ ATH9K_INT_TSFOOR |
+ ATH9K_INT_CABEND,
+ ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
+ ATH9K_INT_RXDESC |
+ ATH9K_INT_RXEOL |
+ ATH9K_INT_RXORN |
+ ATH9K_INT_TXURN |
+ ATH9K_INT_TXDESC |
+ ATH9K_INT_MIB |
+ ATH9K_INT_RXPHY |
+ ATH9K_INT_RXKCM |
+ ATH9K_INT_SWBA |
+ ATH9K_INT_BMISS |
+ ATH9K_INT_GPIO,
+ ATH9K_INT_NOCARD = 0xffffffff
};
-#define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \
- (iniarray)->ia_array = (u32 *)(array); \
- (iniarray)->ia_rows = (rows); \
- (iniarray)->ia_columns = (columns); \
- } while (0)
-
-#define INI_RA(iniarray, row, column) \
- (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)])
+#define CHANNEL_CW_INT 0x00002
+#define CHANNEL_CCK 0x00020
+#define CHANNEL_OFDM 0x00040
+#define CHANNEL_2GHZ 0x00080
+#define CHANNEL_5GHZ 0x00100
+#define CHANNEL_PASSIVE 0x00200
+#define CHANNEL_DYN 0x00400
+#define CHANNEL_HALF 0x04000
+#define CHANNEL_QUARTER 0x08000
+#define CHANNEL_HT20 0x10000
+#define CHANNEL_HT40PLUS 0x20000
+#define CHANNEL_HT40MINUS 0x40000
+
+#define CHANNEL_INTERFERENCE 0x01
+#define CHANNEL_DFS 0x02
+#define CHANNEL_4MS_LIMIT 0x04
+#define CHANNEL_DFS_CLEAR 0x08
+#define CHANNEL_DISALLOW_ADHOC 0x10
+#define CHANNEL_PER_11D_ADHOC 0x20
+
+#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
+#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
+#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
+#define CHANNEL_G_HT20 (CHANNEL_2GHZ|CHANNEL_HT20)
+#define CHANNEL_A_HT20 (CHANNEL_5GHZ|CHANNEL_HT20)
+#define CHANNEL_G_HT40PLUS (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
+#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
+#define CHANNEL_A_HT40PLUS (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
+#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
+#define CHANNEL_ALL \
+ (CHANNEL_OFDM| \
+ CHANNEL_CCK| \
+ CHANNEL_2GHZ | \
+ CHANNEL_5GHZ | \
+ CHANNEL_HT20 | \
+ CHANNEL_HT40PLUS | \
+ CHANNEL_HT40MINUS)
+
+struct ath9k_channel {
+ struct ieee80211_channel *chan;
+ u16 channel;
+ u32 channelFlags;
+ u32 chanmode;
+ int32_t CalValid;
+ bool oneTimeCalsDone;
+ int8_t iCoff;
+ int8_t qCoff;
+ int16_t rawNoiseFloor;
+};
-#define INIT_CAL(_perCal) do { \
- (_perCal)->calState = CAL_WAITING; \
- (_perCal)->calNext = NULL; \
- } while (0)
+#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
+ (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
+ (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
+ (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
+#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
+ (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
+ (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
+ (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
+#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
+#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
+#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
+#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
+#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
+#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
+#define IS_CHAN_A_5MHZ_SPACED(_c) \
+ ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \
+ (((_c)->channel % 20) != 0) && \
+ (((_c)->channel % 10) != 0))
+
+/* These macros check chanmode and not channelFlags */
+#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
+#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) || \
+ ((_c)->chanmode == CHANNEL_G_HT20))
+#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) || \
+ ((_c)->chanmode == CHANNEL_A_HT40MINUS) || \
+ ((_c)->chanmode == CHANNEL_G_HT40PLUS) || \
+ ((_c)->chanmode == CHANNEL_G_HT40MINUS))
+#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
+
+enum ath9k_power_mode {
+ ATH9K_PM_AWAKE = 0,
+ ATH9K_PM_FULL_SLEEP,
+ ATH9K_PM_NETWORK_SLEEP,
+ ATH9K_PM_UNDEFINED
+};
-#define INSERT_CAL(_ahp, _perCal) \
- do { \
- if ((_ahp)->ah_cal_list_last == NULL) { \
- (_ahp)->ah_cal_list = \
- (_ahp)->ah_cal_list_last = (_perCal); \
- ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
- } else { \
- ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
- (_ahp)->ah_cal_list_last = (_perCal); \
- (_perCal)->calNext = (_ahp)->ah_cal_list; \
- } \
- } while (0)
+enum ath9k_ant_setting {
+ ATH9K_ANT_VARIABLE = 0,
+ ATH9K_ANT_FIXED_A,
+ ATH9K_ANT_FIXED_B
+};
-enum hal_cal_types {
- ADC_DC_INIT_CAL = 0x1,
- ADC_GAIN_CAL = 0x2,
- ADC_DC_CAL = 0x4,
- IQ_MISMATCH_CAL = 0x8
+enum ath9k_tp_scale {
+ ATH9K_TP_SCALE_MAX = 0,
+ ATH9K_TP_SCALE_50,
+ ATH9K_TP_SCALE_25,
+ ATH9K_TP_SCALE_12,
+ ATH9K_TP_SCALE_MIN
};
-enum hal_cal_state {
- CAL_INACTIVE,
- CAL_WAITING,
- CAL_RUNNING,
- CAL_DONE
+enum ser_reg_mode {
+ SER_REG_MODE_OFF = 0,
+ SER_REG_MODE_ON = 1,
+ SER_REG_MODE_AUTO = 2,
};
-#define MIN_CAL_SAMPLES 1
-#define MAX_CAL_SAMPLES 64
-#define INIT_LOG_COUNT 5
-#define PER_MIN_LOG_COUNT 2
-#define PER_MAX_LOG_COUNT 10
+struct ath9k_beacon_state {
+ u32 bs_nexttbtt;
+ u32 bs_nextdtim;
+ u32 bs_intval;
+#define ATH9K_BEACON_PERIOD 0x0000ffff
+#define ATH9K_BEACON_ENA 0x00800000
+#define ATH9K_BEACON_RESET_TSF 0x01000000
+#define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */
+ u32 bs_dtimperiod;
+ u16 bs_cfpperiod;
+ u16 bs_cfpmaxduration;
+ u32 bs_cfpnext;
+ u16 bs_timoffset;
+ u16 bs_bmissthreshold;
+ u32 bs_sleepduration;
+ u32 bs_tsfoor_threshold;
+};
-struct hal_percal_data {
- enum hal_cal_types calType;
- u32 calNumSamples;
- u32 calCountMax;
- void (*calCollect) (struct ath_hal *);
- void (*calPostProc) (struct ath_hal *, u8);
+struct chan_centers {
+ u16 synth_center;
+ u16 ctl_center;
+ u16 ext_center;
};
-struct hal_cal_list {
- const struct hal_percal_data *calData;
- enum hal_cal_state calState;
- struct hal_cal_list *calNext;
+enum {
+ ATH9K_RESET_POWER_ON,
+ ATH9K_RESET_WARM,
+ ATH9K_RESET_COLD,
};
-/*
- * Enum to indentify the eeprom mappings
- */
-enum hal_eep_map {
- EEP_MAP_DEFAULT = 0x0,
- EEP_MAP_4KBITS,
- EEP_MAP_MAX
+struct ath9k_hw_version {
+ u32 magic;
+ u16 devid;
+ u16 subvendorid;
+ u32 macVersion;
+ u16 macRev;
+ u16 phyRev;
+ u16 analog5GhzRev;
+ u16 analog2GhzRev;
};
+struct ath_hw {
+ struct ath_softc *ah_sc;
+ struct ath9k_hw_version hw_version;
+ struct ath9k_ops_config config;
+ struct ath9k_hw_capabilities caps;
+ struct ath9k_regulatory regulatory;
+ struct ath9k_channel channels[38];
+ struct ath9k_channel *curchan;
-struct ath_hal_5416 {
- struct ath_hal ah;
union {
struct ar5416_eeprom_def def;
struct ar5416_eeprom_4k map4k;
- } ah_eeprom;
- struct ar5416Stats ah_stats;
- struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
- void __iomem *ah_cal_mem;
-
- u8 ah_macaddr[ETH_ALEN];
- u8 ah_bssid[ETH_ALEN];
- u8 ah_bssidmask[ETH_ALEN];
- u16 ah_assocId;
-
- int16_t ah_curchanRadIndex;
- u32 ah_maskReg;
- u32 ah_txOkInterruptMask;
- u32 ah_txErrInterruptMask;
- u32 ah_txDescInterruptMask;
- u32 ah_txEolInterruptMask;
- u32 ah_txUrnInterruptMask;
- bool ah_chipFullSleep;
- u32 ah_atimWindow;
- u16 ah_antennaSwitchSwap;
- enum ath9k_power_mode ah_powerMode;
- enum ath9k_ant_setting ah_diversityControl;
+ } eeprom;
+ const struct eeprom_ops *eep_ops;
+ enum ath9k_eep_map eep_map;
+
+ bool sw_mgmt_crypto;
+ bool is_pciexpress;
+ u8 macaddr[ETH_ALEN];
+ u16 tx_trig_level;
+ u16 rfsilent;
+ u32 rfkill_gpio;
+ u32 rfkill_polarity;
+ u32 btactive_gpio;
+ u32 wlanactive_gpio;
+ u32 ah_flags;
+
+ enum nl80211_iftype opmode;
+ enum ath9k_power_mode power_mode;
+ enum ath9k_power_mode restore_mode;
+
+ struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
+ struct ar5416Stats stats;
+ struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
+
+ int16_t curchan_rad_index;
+ u32 mask_reg;
+ u32 txok_interrupt_mask;
+ u32 txerr_interrupt_mask;
+ u32 txdesc_interrupt_mask;
+ u32 txeol_interrupt_mask;
+ u32 txurn_interrupt_mask;
+ bool chip_fullsleep;
+ u32 atim_window;
+ u16 antenna_switch_swap;
+ enum ath9k_ant_setting diversity_control;
/* Calibration */
- enum hal_cal_types ah_suppCals;
- struct hal_cal_list ah_iqCalData;
- struct hal_cal_list ah_adcGainCalData;
- struct hal_cal_list ah_adcDcCalInitData;
- struct hal_cal_list ah_adcDcCalData;
- struct hal_cal_list *ah_cal_list;
- struct hal_cal_list *ah_cal_list_last;
- struct hal_cal_list *ah_cal_list_curr;
-#define ah_totalPowerMeasI ah_Meas0.unsign
-#define ah_totalPowerMeasQ ah_Meas1.unsign
-#define ah_totalIqCorrMeas ah_Meas2.sign
-#define ah_totalAdcIOddPhase ah_Meas0.unsign
-#define ah_totalAdcIEvenPhase ah_Meas1.unsign
-#define ah_totalAdcQOddPhase ah_Meas2.unsign
-#define ah_totalAdcQEvenPhase ah_Meas3.unsign
-#define ah_totalAdcDcOffsetIOddPhase ah_Meas0.sign
-#define ah_totalAdcDcOffsetIEvenPhase ah_Meas1.sign
-#define ah_totalAdcDcOffsetQOddPhase ah_Meas2.sign
-#define ah_totalAdcDcOffsetQEvenPhase ah_Meas3.sign
+ enum hal_cal_types supp_cals;
+ struct hal_cal_list iq_caldata;
+ struct hal_cal_list adcgain_caldata;
+ struct hal_cal_list adcdc_calinitdata;
+ struct hal_cal_list adcdc_caldata;
+ struct hal_cal_list *cal_list;
+ struct hal_cal_list *cal_list_last;
+ struct hal_cal_list *cal_list_curr;
+#define totalPowerMeasI meas0.unsign
+#define totalPowerMeasQ meas1.unsign
+#define totalIqCorrMeas meas2.sign
+#define totalAdcIOddPhase meas0.unsign
+#define totalAdcIEvenPhase meas1.unsign
+#define totalAdcQOddPhase meas2.unsign
+#define totalAdcQEvenPhase meas3.unsign
+#define totalAdcDcOffsetIOddPhase meas0.sign
+#define totalAdcDcOffsetIEvenPhase meas1.sign
+#define totalAdcDcOffsetQOddPhase meas2.sign
+#define totalAdcDcOffsetQEvenPhase meas3.sign
union {
u32 unsign[AR5416_MAX_CHAINS];
int32_t sign[AR5416_MAX_CHAINS];
- } ah_Meas0;
+ } meas0;
union {
u32 unsign[AR5416_MAX_CHAINS];
int32_t sign[AR5416_MAX_CHAINS];
- } ah_Meas1;
+ } meas1;
union {
u32 unsign[AR5416_MAX_CHAINS];
int32_t sign[AR5416_MAX_CHAINS];
- } ah_Meas2;
+ } meas2;
union {
u32 unsign[AR5416_MAX_CHAINS];
int32_t sign[AR5416_MAX_CHAINS];
- } ah_Meas3;
- u16 ah_CalSamples;
+ } meas3;
+ u16 cal_samples;
- u32 ah_staId1Defaults;
- u32 ah_miscMode;
+ u32 sta_id1_defaults;
+ u32 misc_mode;
enum {
AUTO_32KHZ,
USE_32KHZ,
DONT_USE_32KHZ,
- } ah_enable32kHzClock;
+ } enable_32kHz_clock;
/* RF */
- u32 *ah_analogBank0Data;
- u32 *ah_analogBank1Data;
- u32 *ah_analogBank2Data;
- u32 *ah_analogBank3Data;
- u32 *ah_analogBank6Data;
- u32 *ah_analogBank6TPCData;
- u32 *ah_analogBank7Data;
- u32 *ah_addac5416_21;
- u32 *ah_bank6Temp;
-
- int16_t ah_txPowerIndexOffset;
- u32 ah_beaconInterval;
- u32 ah_slottime;
- u32 ah_acktimeout;
- u32 ah_ctstimeout;
- u32 ah_globaltxtimeout;
- u8 ah_gBeaconRate;
- u32 ah_gpioSelect;
- u32 ah_polarity;
- u32 ah_gpioBit;
+ u32 *analogBank0Data;
+ u32 *analogBank1Data;
+ u32 *analogBank2Data;
+ u32 *analogBank3Data;
+ u32 *analogBank6Data;
+ u32 *analogBank6TPCData;
+ u32 *analogBank7Data;
+ u32 *addac5416_21;
+ u32 *bank6Temp;
+
+ int16_t txpower_indexoffset;
+ u32 beacon_interval;
+ u32 slottime;
+ u32 acktimeout;
+ u32 ctstimeout;
+ u32 globaltxtimeout;
+ u8 gbeacon_rate;
/* ANI */
- u32 ah_procPhyErr;
- bool ah_hasHwPhyCounters;
- u32 ah_aniPeriod;
- struct ar5416AniState *ah_curani;
- struct ar5416AniState ah_ani[255];
- int ah_totalSizeDesired[5];
- int ah_coarseHigh[5];
- int ah_coarseLow[5];
- int ah_firpwr[5];
- enum ath9k_ani_cmd ah_ani_function;
-
- u32 ah_intrTxqs;
- bool ah_intrMitigation;
- enum ath9k_ht_extprotspacing ah_extprotspacing;
- u8 ah_txchainmask;
- u8 ah_rxchainmask;
-
- struct ar5416IniArray ah_iniModes;
- struct ar5416IniArray ah_iniCommon;
- struct ar5416IniArray ah_iniBank0;
- struct ar5416IniArray ah_iniBB_RfGain;
- struct ar5416IniArray ah_iniBank1;
- struct ar5416IniArray ah_iniBank2;
- struct ar5416IniArray ah_iniBank3;
- struct ar5416IniArray ah_iniBank6;
- struct ar5416IniArray ah_iniBank6TPC;
- struct ar5416IniArray ah_iniBank7;
- struct ar5416IniArray ah_iniAddac;
- struct ar5416IniArray ah_iniPcieSerdes;
- struct ar5416IniArray ah_iniModesAdditional;
- struct ar5416IniArray ah_iniModesRxGain;
- struct ar5416IniArray ah_iniModesTxGain;
- /* To indicate EEPROM mapping used */
- enum hal_eep_map ah_eep_map;
+ u32 proc_phyerr;
+ bool has_hw_phycounters;
+ u32 aniperiod;
+ struct ar5416AniState *curani;
+ struct ar5416AniState ani[255];
+ int totalSizeDesired[5];
+ int coarse_high[5];
+ int coarse_low[5];
+ int firpwr[5];
+ enum ath9k_ani_cmd ani_function;
+
+ u32 intr_txqs;
+ bool intr_mitigation;
+ enum ath9k_ht_extprotspacing extprotspacing;
+ u8 txchainmask;
+ u8 rxchainmask;
+
+ u32 originalGain[22];
+ int initPDADC;
+ int PDADCdelta;
+
+ struct ar5416IniArray iniModes;
+ struct ar5416IniArray iniCommon;
+ struct ar5416IniArray iniBank0;
+ struct ar5416IniArray iniBB_RfGain;
+ struct ar5416IniArray iniBank1;
+ struct ar5416IniArray iniBank2;
+ struct ar5416IniArray iniBank3;
+ struct ar5416IniArray iniBank6;
+ struct ar5416IniArray iniBank6TPC;
+ struct ar5416IniArray iniBank7;
+ struct ar5416IniArray iniAddac;
+ struct ar5416IniArray iniPcieSerdes;
+ struct ar5416IniArray iniModesAdditional;
+ struct ar5416IniArray iniModesRxGain;
+ struct ar5416IniArray iniModesTxGain;
};
-#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
-
-#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
-
-#define ar5416RfDetach(ah) do { \
- if (AH5416(ah)->ah_rfHal.rfDetach != NULL) \
- AH5416(ah)->ah_rfHal.rfDetach(ah); \
- } while (0)
-
-#define ath9k_hw_use_flash(_ah) \
- (!(_ah->ah_flags & AH_USE_EEPROM))
-
-
-#define DO_DELAY(x) do { \
- if ((++(x) % 64) == 0) \
- udelay(1); \
- } while (0)
-
-#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
- int r; \
- for (r = 0; r < ((iniarray)->ia_rows); r++) { \
- REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
- INI_RA((iniarray), r, (column))); \
- DO_DELAY(regWr); \
- } \
- } while (0)
-
-#define BASE_ACTIVATE_DELAY 100
-#define RTC_PLL_SETTLE_DELAY 1000
-#define COEF_SCALE_S 24
-#define HT40_CHANNEL_CENTER_SHIFT 10
-
-#define AR5416_EEPROM_MAGIC_OFFSET 0x0
-
-#define AR5416_EEPROM_S 2
-#define AR5416_EEPROM_OFFSET 0x2000
-#define AR5416_EEPROM_START_ADDR \
- (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
-#define AR5416_EEPROM_MAX 0xae0
-#define ar5416_get_eep_ver(_ahp) \
- (((_ahp)->ah_eeprom.def.baseEepHeader.version >> 12) & 0xF)
-#define ar5416_get_eep_rev(_ahp) \
- (((_ahp)->ah_eeprom.def.baseEepHeader.version) & 0xFFF)
-#define ar5416_get_ntxchains(_txchainmask) \
- (((_txchainmask >> 2) & 1) + \
- ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
-/* EEPROM 4K bit map definations */
-#define ar5416_get_eep4k_ver(_ahp) \
- (((_ahp)->ah_eeprom.map4k.baseEepHeader.version >> 12) & 0xF)
-#define ar5416_get_eep4k_rev(_ahp) \
- (((_ahp)->ah_eeprom.map4k.baseEepHeader.version) & 0xFFF)
-
-
-#ifdef __BIG_ENDIAN
-#define AR5416_EEPROM_MAGIC 0x5aa5
-#else
-#define AR5416_EEPROM_MAGIC 0xa55a
+/* Attach, Detach, Reset */
+const char *ath9k_hw_probe(u16 vendorid, u16 devid);
+void ath9k_hw_detach(struct ath_hw *ah);
+struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error);
+void ath9k_hw_rfdetach(struct ath_hw *ah);
+int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+ bool bChannelChange);
+bool ath9k_hw_fill_cap_info(struct ath_hw *ah);
+bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
+ u32 capability, u32 *result);
+bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
+ u32 capability, u32 setting, int *status);
+
+/* Key Cache Management */
+bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry);
+bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac);
+bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
+ const struct ath9k_keyval *k,
+ const u8 *mac);
+bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry);
+
+/* GPIO / RFKILL / Antennae */
+void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio);
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
+void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
+ u32 ah_signal_type);
+void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+void ath9k_enable_rfkill(struct ath_hw *ah);
#endif
-
-#define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
-
-#define ATH9K_ANTENNA0_CHAINMASK 0x1
-#define ATH9K_ANTENNA1_CHAINMASK 0x2
-
-#define ATH9K_NUM_DMA_DEBUG_REGS 8
-#define ATH9K_NUM_QUEUES 10
-
-#define HAL_NOISE_IMMUNE_MAX 4
-#define HAL_SPUR_IMMUNE_MAX 7
-#define HAL_FIRST_STEP_MAX 2
-
-#define ATH9K_ANI_OFDM_TRIG_HIGH 500
-#define ATH9K_ANI_OFDM_TRIG_LOW 200
-#define ATH9K_ANI_CCK_TRIG_HIGH 200
-#define ATH9K_ANI_CCK_TRIG_LOW 100
-#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
-#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
-#define ATH9K_ANI_CCK_WEAK_SIG_THR false
-#define ATH9K_ANI_SPUR_IMMUNE_LVL 7
-#define ATH9K_ANI_FIRSTEP_LVL 0
-#define ATH9K_ANI_RSSI_THR_HIGH 40
-#define ATH9K_ANI_RSSI_THR_LOW 7
-#define ATH9K_ANI_PERIOD 100
-
-#define AR_GPIOD_MASK 0x00001FFF
-#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
-
-#define HAL_EP_RND(x, mul) \
- ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
-#define BEACON_RSSI(ahp) \
- HAL_EP_RND(ahp->ah_stats.ast_nodestats.ns_avgbrssi, \
- ATH9K_RSSI_EP_MULTIPLIER)
-
-#define ah_mibStats ah_stats.ast_mibstats
-
-#define AH_TIMEOUT 100000
-#define AH_TIME_QUANTUM 10
-
-#define AR_KEYTABLE_SIZE 128
-#define POWER_UP_TIME 200000
-
-#define EXT_ADDITIVE (0x8000)
-#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
-#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
-#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
-
-#define SUB_NUM_CTL_MODES_AT_5G_40 2
-#define SUB_NUM_CTL_MODES_AT_2G_40 3
-#define SPUR_RSSI_THRESH 40
-
-#define TU_TO_USEC(_tu) ((_tu) << 10)
-
-#define CAB_TIMEOUT_VAL 10
-#define BEACON_TIMEOUT_VAL 10
-#define MIN_BEACON_TIMEOUT_VAL 1
-#define SLEEP_SLOP 3
-
-#define CCK_SIFS_TIME 10
-#define CCK_PREAMBLE_BITS 144
-#define CCK_PLCP_BITS 48
-
-#define OFDM_SIFS_TIME 16
-#define OFDM_PREAMBLE_TIME 20
-#define OFDM_PLCP_BITS 22
-#define OFDM_SYMBOL_TIME 4
-
-#define OFDM_SIFS_TIME_HALF 32
-#define OFDM_PREAMBLE_TIME_HALF 40
-#define OFDM_PLCP_BITS_HALF 22
-#define OFDM_SYMBOL_TIME_HALF 8
-
-#define OFDM_SIFS_TIME_QUARTER 64
-#define OFDM_PREAMBLE_TIME_QUARTER 80
-#define OFDM_PLCP_BITS_QUARTER 22
-#define OFDM_SYMBOL_TIME_QUARTER 16
-
-u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
- enum eeprom_param param);
+u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
+void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
+bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
+ enum ath9k_ant_setting settings,
+ struct ath9k_channel *chan,
+ u8 *tx_chainmask, u8 *rx_chainmask,
+ u8 *antenna_cfgd);
+
+/* General Operation */
+bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
+u32 ath9k_hw_reverse_bits(u32 val, u32 n);
+bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
+u16 ath9k_hw_computetxtime(struct ath_hw *ah, struct ath_rate_table *rates,
+ u32 frameLen, u16 rateix, bool shortPreamble);
+void ath9k_hw_get_channel_centers(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ struct chan_centers *centers);
+u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
+void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
+bool ath9k_hw_phy_disable(struct ath_hw *ah);
+bool ath9k_hw_disable(struct ath_hw *ah);
+bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
+void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac);
+void ath9k_hw_setopmode(struct ath_hw *ah);
+void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
+void ath9k_hw_setbssidmask(struct ath_softc *sc);
+void ath9k_hw_write_associd(struct ath_softc *sc);
+u64 ath9k_hw_gettsf64(struct ath_hw *ah);
+void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
+void ath9k_hw_reset_tsf(struct ath_hw *ah);
+bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
+bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
+void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode);
+void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
+void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
+ const struct ath9k_beacon_state *bs);
+bool ath9k_hw_setpower(struct ath_hw *ah,
+ enum ath9k_power_mode mode);
+void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
+
+/* Interrupt Handling */
+bool ath9k_hw_intrpend(struct ath_hw *ah);
+bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
+enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah);
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
+
+void ath9k_hw_btcoex_enable(struct ath_hw *ah);
#endif
diff --git a/drivers/net/wireless/ath9k/initvals.h b/drivers/net/wireless/ath9k/initvals.h
index f3cfa16525e4..e2f0a34b79a1 100644
--- a/drivers/net/wireless/ath9k/initvals.h
+++ b/drivers/net/wireless/ath9k/initvals.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,8 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* AR5416 to Fowl ar5146.ini */
-static const u32 ar5416Modes_9100[][6] = {
+static const u32 ar5416Modes[][6] = {
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -79,7 +78,7 @@ static const u32 ar5416Modes_9100[][6] = {
{ 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
};
-static const u32 ar5416Common_9100[][2] = {
+static const u32 ar5416Common[][2] = {
{ 0x0000000c, 0x00000000 },
{ 0x00000030, 0x00020015 },
{ 0x00000034, 0x00000005 },
@@ -457,12 +456,12 @@ static const u32 ar5416Common_9100[][2] = {
{ 0x0000a3e0, 0x000001ce },
};
-static const u32 ar5416Bank0_9100[][2] = {
+static const u32 ar5416Bank0[][2] = {
{ 0x000098b0, 0x1e5795e5 },
{ 0x000098e0, 0x02008020 },
};
-static const u32 ar5416BB_RfGain_9100[][3] = {
+static const u32 ar5416BB_RfGain[][3] = {
{ 0x00009a00, 0x00000000, 0x00000000 },
{ 0x00009a04, 0x00000040, 0x00000040 },
{ 0x00009a08, 0x00000080, 0x00000080 },
@@ -529,21 +528,21 @@ static const u32 ar5416BB_RfGain_9100[][3] = {
{ 0x00009afc, 0x000000f9, 0x000000f9 },
};
-static const u32 ar5416Bank1_9100[][2] = {
+static const u32 ar5416Bank1[][2] = {
{ 0x000098b0, 0x02108421 },
{ 0x000098ec, 0x00000008 },
};
-static const u32 ar5416Bank2_9100[][2] = {
+static const u32 ar5416Bank2[][2] = {
{ 0x000098b0, 0x0e73ff17 },
{ 0x000098e0, 0x00000420 },
};
-static const u32 ar5416Bank3_9100[][3] = {
+static const u32 ar5416Bank3[][3] = {
{ 0x000098f0, 0x01400018, 0x01c00018 },
};
-static const u32 ar5416Bank6_9100[][3] = {
+static const u32 ar5416Bank6[][3] = {
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
@@ -580,7 +579,7 @@ static const u32 ar5416Bank6_9100[][3] = {
{ 0x000098d0, 0x0000000f, 0x0010000f },
};
-static const u32 ar5416Bank6TPC_9100[][3] = {
+static const u32 ar5416Bank6TPC[][3] = {
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
@@ -616,13 +615,13 @@ static const u32 ar5416Bank6TPC_9100[][3] = {
{ 0x000098d0, 0x0000000f, 0x0010000f },
};
-static const u32 ar5416Bank7_9100[][2] = {
+static const u32 ar5416Bank7[][2] = {
{ 0x0000989c, 0x00000500 },
{ 0x0000989c, 0x00000800 },
{ 0x000098cc, 0x0000000e },
};
-static const u32 ar5416Addac_9100[][2] = {
+static const u32 ar5416Addac[][2] = {
{0x0000989c, 0x00000000 },
{0x0000989c, 0x00000003 },
{0x0000989c, 0x00000000 },
@@ -659,11 +658,10 @@ static const u32 ar5416Addac_9100[][2] = {
{0x0000989c, 0x00000000 },
{0x0000989c, 0x00000000 },
{0x0000989c, 0x00000000 },
- {0x000098c4, 0x00000000 },
+ {0x000098cc, 0x00000000 },
};
-/* ar5416 - howl ar5416_howl.ini */
-static const u32 ar5416Modes[][6] = {
+static const u32 ar5416Modes_9100[][6] = {
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
{ 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -737,7 +735,7 @@ static const u32 ar5416Modes[][6] = {
{ 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
};
-static const u32 ar5416Common[][2] = {
+static const u32 ar5416Common_9100[][2] = {
{ 0x0000000c, 0x00000000 },
{ 0x00000030, 0x00020015 },
{ 0x00000034, 0x00000005 },
@@ -1111,12 +1109,12 @@ static const u32 ar5416Common[][2] = {
{ 0x0000a3e0, 0x000001ce },
};
-static const u32 ar5416Bank0[][2] = {
+static const u32 ar5416Bank0_9100[][2] = {
{ 0x000098b0, 0x1e5795e5 },
{ 0x000098e0, 0x02008020 },
};
-static const u32 ar5416BB_RfGain[][3] = {
+static const u32 ar5416BB_RfGain_9100[][3] = {
{ 0x00009a00, 0x00000000, 0x00000000 },
{ 0x00009a04, 0x00000040, 0x00000040 },
{ 0x00009a08, 0x00000080, 0x00000080 },
@@ -1183,21 +1181,21 @@ static const u32 ar5416BB_RfGain[][3] = {
{ 0x00009afc, 0x000000f9, 0x000000f9 },
};
-static const u32 ar5416Bank1[][2] = {
+static const u32 ar5416Bank1_9100[][2] = {
{ 0x000098b0, 0x02108421},
{ 0x000098ec, 0x00000008},
};
-static const u32 ar5416Bank2[][2] = {
+static const u32 ar5416Bank2_9100[][2] = {
{ 0x000098b0, 0x0e73ff17},
{ 0x000098e0, 0x00000420},
};
-static const u32 ar5416Bank3[][3] = {
+static const u32 ar5416Bank3_9100[][3] = {
{ 0x000098f0, 0x01400018, 0x01c00018 },
};
-static const u32 ar5416Bank6[][3] = {
+static const u32 ar5416Bank6_9100[][3] = {
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
@@ -1235,7 +1233,7 @@ static const u32 ar5416Bank6[][3] = {
};
-static const u32 ar5416Bank6TPC[][3] = {
+static const u32 ar5416Bank6TPC_9100[][3] = {
{ 0x0000989c, 0x00000000, 0x00000000 },
{ 0x0000989c, 0x00000000, 0x00000000 },
@@ -1272,13 +1270,13 @@ static const u32 ar5416Bank6TPC[][3] = {
{ 0x000098d0, 0x0000000f, 0x0010000f },
};
-static const u32 ar5416Bank7[][2] = {
+static const u32 ar5416Bank7_9100[][2] = {
{ 0x0000989c, 0x00000500 },
{ 0x0000989c, 0x00000800 },
{ 0x000098cc, 0x0000000e },
};
-static const u32 ar5416Addac[][2] = {
+static const u32 ar5416Addac_9100[][2] = {
{0x0000989c, 0x00000000 },
{0x0000989c, 0x00000000 },
{0x0000989c, 0x00000000 },
@@ -1313,7 +1311,6 @@ static const u32 ar5416Addac[][2] = {
{0x000098cc, 0x00000000 },
};
-/* AR5416 9160 Sowl ar5416_sowl.ini */
static const u32 ar5416Modes_9160[][6] = {
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -2549,6 +2546,8 @@ static const u32 ar9280Modes_9280_2[][6] = {
{ 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
{ 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
{ 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
+ { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
+ { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
{ 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
{ 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
{ 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
@@ -2587,7 +2586,6 @@ static const u32 ar9280Modes_9280_2[][6] = {
{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
{ 0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000 },
- { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
{ 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
{ 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 },
@@ -2719,7 +2717,6 @@ static const u32 ar9280Common_9280_2[][2] = {
{ 0x00008110, 0x00000168 },
{ 0x00008118, 0x000100aa },
{ 0x0000811c, 0x00003210 },
- { 0x00008120, 0x08f04800 },
{ 0x00008124, 0x00000000 },
{ 0x00008128, 0x00000000 },
{ 0x0000812c, 0x00000000 },
@@ -2735,7 +2732,6 @@ static const u32 ar9280Common_9280_2[][2] = {
{ 0x00008178, 0x00000100 },
{ 0x0000817c, 0x00000000 },
{ 0x000081c0, 0x00000000 },
- { 0x000081d0, 0x00003210 },
{ 0x000081ec, 0x00000000 },
{ 0x000081f0, 0x00000000 },
{ 0x000081f4, 0x00000000 },
@@ -2817,7 +2813,7 @@ static const u32 ar9280Common_9280_2[][2] = {
{ 0x00009958, 0x2108ecff },
{ 0x00009940, 0x14750604 },
{ 0x0000c95c, 0x004b6a8e },
- { 0x00009968, 0x000003ce },
+ { 0x0000c968, 0x000003ce },
{ 0x00009970, 0x190fb515 },
{ 0x00009974, 0x00000000 },
{ 0x00009978, 0x00000001 },
@@ -2909,16 +2905,12 @@ static const u32 ar9280Common_9280_2[][2] = {
{ 0x0000780c, 0x21084210 },
{ 0x00007810, 0x6d801300 },
{ 0x00007818, 0x07e41000 },
- { 0x0000781c, 0x00392000 },
- { 0x00007820, 0x92592480 },
{ 0x00007824, 0x00040000 },
{ 0x00007828, 0xdb005012 },
{ 0x0000782c, 0x04924914 },
{ 0x00007830, 0x21084210 },
{ 0x00007834, 0x6d801300 },
{ 0x0000783c, 0x07e40000 },
- { 0x00007840, 0x00392000 },
- { 0x00007844, 0x92592480 },
{ 0x00007848, 0x00100000 },
{ 0x0000784c, 0x773f0567 },
{ 0x00007850, 0x54214514 },
@@ -2954,7 +2946,6 @@ static const u32 ar9280Modes_fast_clock_9280_2[][3] = {
{ 0x00009844, 0x03721821, 0x03721821 },
{ 0x00009914, 0x00000898, 0x00001130 },
{ 0x00009918, 0x0000000b, 0x00000016 },
- { 0x00009944, 0xdfbc1210, 0xdfbc1210 },
};
static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = {
@@ -3366,21 +3357,26 @@ static const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = {
{ 0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a },
{ 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211 },
{ 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 },
- { 0x0000a324, 0x00020092, 0x00020092, 0x00022411, 0x00022411, 0x00022411 },
- { 0x0000a328, 0x0002410a, 0x0002410a, 0x00025413, 0x00025413, 0x00025413 },
- { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00029811, 0x00029811, 0x00029811 },
- { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002c813, 0x0002c813, 0x0002c813 },
- { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030a14, 0x00030a14, 0x00030a14 },
- { 0x0000a338, 0x000321ec, 0x000321ec, 0x00035a50, 0x00035a50, 0x00035a50 },
- { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00039c4c, 0x00039c4c, 0x00039c4c },
- { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003de8a, 0x0003de8a, 0x0003de8a },
- { 0x0000a344, 0x000321ec, 0x000321ec, 0x00042e92, 0x00042e92, 0x00042e92 },
- { 0x0000a348, 0x000321ec, 0x000321ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 },
- { 0x0000a34c, 0x000321ec, 0x000321ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 },
- { 0x0000a350, 0x000321ec, 0x000321ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 },
- { 0x0000a354, 0x000321ec, 0x000321ec, 0x00053fd5, 0x00053fd5, 0x00053fd5 },
+ { 0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411 },
+ { 0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413 },
+ { 0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811 },
+ { 0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813 },
+ { 0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14 },
+ { 0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50 },
+ { 0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c },
+ { 0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a },
+ { 0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92 },
+ { 0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 },
+ { 0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 },
+ { 0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 },
+ { 0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5 },
{ 0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
{ 0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
+ { 0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
+ { 0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
+ { 0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
+ { 0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
+ { 0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
{ 0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce },
};
@@ -3409,6 +3405,11 @@ static const u32 ar9280Modes_original_tx_gain_9280_2[][6] = {
{ 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 },
{ 0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff },
{ 0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff },
+ { 0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
+ { 0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
+ { 0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
+ { 0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
+ { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
{ 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
};
@@ -4120,6 +4121,7 @@ static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = {
{0x00004044, 0x00000000 },
};
+/* AR9285 v1_2 PCI Register Writes. Created: 03/04/09 */
static const u_int32_t ar9285Modes_9285_1_2[][6] = {
{ 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
{ 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -4135,11 +4137,11 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
{ 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
{ 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
{ 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
- { 0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020, 0x037216a0 },
- { 0x00009848, 0x00001066, 0x00001066, 0x00000057, 0x00000057, 0x00001059 },
+ { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 },
+ { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
{ 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
{ 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
- { 0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e, 0x3139605e },
+ { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
{ 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 },
{ 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
{ 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
@@ -4154,291 +4156,272 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
{ 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
{ 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
{ 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
- { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
+ { 0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
{ 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
{ 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
{ 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
- { 0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
- { 0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
- { 0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
- { 0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
- { 0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
- { 0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
- { 0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
- { 0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
- { 0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114, 0x00000000 },
- { 0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
- { 0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
- { 0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
- { 0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
- { 0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
- { 0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
- { 0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
- { 0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
- { 0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
- { 0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284, 0x00000000 },
- { 0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288, 0x00000000 },
- { 0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220, 0x00000000 },
- { 0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
- { 0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
- { 0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304, 0x00000000 },
- { 0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
- { 0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
- { 0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380, 0x00000000 },
- { 0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384, 0x00000000 },
+ { 0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
+ { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
+ { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
+ { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
+ { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
+ { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
+ { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
+ { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
+ { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
+ { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
+ { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
+ { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
+ { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
+ { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
+ { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
+ { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
+ { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
+ { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
+ { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
+ { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
+ { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
+ { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
+ { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
+ { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
+ { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
+ { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
+ { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
+ { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
{ 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
{ 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
{ 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
{ 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
{ 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
{ 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
- { 0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04, 0x00000000 },
- { 0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
- { 0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
- { 0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c, 0x00000000 },
- { 0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80, 0x00000000 },
- { 0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84, 0x00000000 },
- { 0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88, 0x00000000 },
- { 0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c, 0x00000000 },
- { 0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90, 0x00000000 },
- { 0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80, 0x00000000 },
- { 0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
- { 0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
- { 0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c, 0x00000000 },
- { 0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90, 0x00000000 },
- { 0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c, 0x00000000 },
- { 0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310, 0x00000000 },
- { 0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
- { 0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
- { 0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324, 0x00000000 },
- { 0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704, 0x00000000 },
- { 0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4, 0x00000000 },
- { 0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8, 0x00000000 },
- { 0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
- { 0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
- { 0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720, 0x00000000 },
- { 0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724, 0x00000000 },
- { 0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728, 0x00000000 },
- { 0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c, 0x00000000 },
- { 0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0, 0x00000000 },
- { 0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4, 0x00000000 },
- { 0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
- { 0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
- { 0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4, 0x00000000 },
- { 0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
- { 0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
- { 0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
- { 0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad, 0x00000000 },
- { 0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
- { 0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
- { 0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9, 0x00000000 },
- { 0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5, 0x00000000 },
- { 0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
- { 0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
- { 0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5, 0x00000000 },
- { 0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
- { 0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
- { 0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
- { 0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
- { 0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
- { 0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
- { 0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
- { 0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7, 0x00000000 },
- { 0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
- { 0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf, 0x00000000 },
- { 0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7, 0x00000000 },
- { 0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
- { 0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
- { 0x0000aa04, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
- { 0x0000aa08, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
- { 0x0000aa0c, 0x00000000, 0x00000000, 0x00068080, 0x00068080, 0x00000000 },
- { 0x0000aa10, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
- { 0x0000aa14, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
- { 0x0000aa18, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
- { 0x0000aa1c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
- { 0x0000aa20, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
- { 0x0000aa24, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
- { 0x0000aa28, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
- { 0x0000aa2c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
- { 0x0000aa30, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
- { 0x0000aa34, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
- { 0x0000aa38, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
- { 0x0000aa3c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
- { 0x0000aa40, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
- { 0x0000aa44, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
- { 0x0000aa48, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
- { 0x0000aa4c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
- { 0x0000aa50, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
- { 0x0000aa54, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
- { 0x0000aa58, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac, 0x00000000 },
- { 0x0000aa5c, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c, 0x00000000 },
- { 0x0000aa60, 0x00000000, 0x00000000, 0x00068224, 0x00068224, 0x00000000 },
- { 0x0000aa64, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
- { 0x0000aa68, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
- { 0x0000aa6c, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
- { 0x0000aa70, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
- { 0x0000aa74, 0x00000000, 0x00000000, 0x00068310, 0x00068310, 0x00000000 },
- { 0x0000aa78, 0x00000000, 0x00000000, 0x00068788, 0x00068788, 0x00000000 },
- { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c, 0x00000000 },
- { 0x0000aa80, 0x00000000, 0x00000000, 0x00068790, 0x00068790, 0x00000000 },
- { 0x0000aa84, 0x00000000, 0x00000000, 0x00068794, 0x00068794, 0x00000000 },
- { 0x0000aa88, 0x00000000, 0x00000000, 0x00068798, 0x00068798, 0x00000000 },
- { 0x0000aa8c, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c, 0x00000000 },
- { 0x0000aa90, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89, 0x00000000 },
- { 0x0000aa94, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d, 0x00000000 },
- { 0x0000aa98, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91, 0x00000000 },
- { 0x0000aa9c, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95, 0x00000000 },
- { 0x0000aaa0, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99, 0x00000000 },
- { 0x0000aaa4, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5, 0x00000000 },
- { 0x0000aaa8, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9, 0x00000000 },
- { 0x0000aaac, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad, 0x00000000 },
- { 0x0000aab0, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c, 0x00000000 },
- { 0x0000aab4, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10, 0x00000000 },
- { 0x0000aab8, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14, 0x00000000 },
- { 0x0000aabc, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
- { 0x0000aac0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
- { 0x0000aac4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
- { 0x0000aac8, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380, 0x00000000 },
- { 0x0000aacc, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
- { 0x0000aad0, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
- { 0x0000aad4, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c, 0x00000000 },
- { 0x0000aad8, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394, 0x00000000 },
- { 0x0000aadc, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798, 0x00000000 },
- { 0x0000aae0, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c, 0x00000000 },
- { 0x0000aae4, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
- { 0x0000aae8, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
- { 0x0000aaec, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718, 0x00000000 },
- { 0x0000aaf0, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705, 0x00000000 },
- { 0x0000aaf4, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709, 0x00000000 },
- { 0x0000aaf8, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d, 0x00000000 },
- { 0x0000aafc, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711, 0x00000000 },
- { 0x0000ab00, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715, 0x00000000 },
- { 0x0000ab04, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719, 0x00000000 },
- { 0x0000ab08, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4, 0x00000000 },
- { 0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
- { 0x0000ab10, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
- { 0x0000ab14, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
- { 0x0000ab18, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
- { 0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
- { 0x0000ab20, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc, 0x00000000 },
- { 0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1, 0x00000000 },
- { 0x0000ab28, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
- { 0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
- { 0x0000ab30, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
- { 0x0000ab34, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
- { 0x0000ab38, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd, 0x00000000 },
- { 0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
- { 0x0000ab40, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd, 0x00000000 },
- { 0x0000ab44, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
- { 0x0000ab48, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
- { 0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2, 0x00000000 },
- { 0x0000ab50, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
- { 0x0000ab54, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
- { 0x0000ab58, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
- { 0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
- { 0x0000ab60, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
- { 0x0000ab64, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
- { 0x0000ab68, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
- { 0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
- { 0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+ { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
+ { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+ { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+ { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
+ { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
+ { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
+ { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
+ { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
+ { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
+ { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
+ { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
+ { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
+ { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
+ { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
+ { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
+ { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
+ { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
+ { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
+ { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
+ { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
+ { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
+ { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
+ { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
+ { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
+ { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
+ { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
+ { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
+ { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
+ { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
+ { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
+ { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
+ { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
+ { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
+ { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
+ { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
+ { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
+ { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
+ { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
+ { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
+ { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
+ { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
+ { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
+ { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
+ { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
+ { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
+ { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
+ { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
+ { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
+ { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
+ { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
+ { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
+ { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
+ { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
+ { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
+ { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
+ { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
+ { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
+ { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
+ { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
+ { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
+ { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
+ { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
+ { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
+ { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
+ { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
+ { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
+ { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
+ { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
+ { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
+ { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
+ { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
+ { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
+ { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
+ { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
+ { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
+ { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
+ { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
+ { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
+ { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
+ { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
+ { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
+ { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
+ { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
+ { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
+ { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
+ { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
+ { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
+ { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
+ { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
+ { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
+ { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+ { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+ { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
+ { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
+ { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
+ { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
+ { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
+ { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
+ { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
+ { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
+ { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
+ { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
+ { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
+ { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
+ { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
+ { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
+ { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
+ { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
+ { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
+ { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
+ { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
+ { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
+ { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
+ { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
+ { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
+ { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
+ { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
+ { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
+ { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
+ { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
+ { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
+ { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
+ { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
+ { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
+ { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
+ { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
+ { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
+ { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
+ { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
+ { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
+ { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
+ { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
+ { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
+ { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
+ { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
+ { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
+ { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
+ { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
+ { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
+ { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
+ { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
+ { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
+ { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
+ { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
+ { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+ { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
{ 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
- { 0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000, 0x0001f000 },
+ { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
{ 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
{ 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
{ 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
- { 0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652, 0x0a82a652 },
- { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
- { 0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
- { 0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408, 0x00000000 },
- { 0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a, 0x00000000 },
- { 0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818, 0x00000000 },
- { 0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858, 0x00000000 },
- { 0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859, 0x00000000 },
- { 0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b, 0x00000000 },
- { 0x0000a320, 0x00000000, 0x00000000, 0x0002b89a, 0x0002b89a, 0x00000000 },
- { 0x0000a324, 0x00000000, 0x00000000, 0x0002d89b, 0x0002d89b, 0x00000000 },
- { 0x0000a328, 0x00000000, 0x00000000, 0x0002f89c, 0x0002f89c, 0x00000000 },
- { 0x0000a32c, 0x00000000, 0x00000000, 0x0003189d, 0x0003189d, 0x00000000 },
- { 0x0000a330, 0x00000000, 0x00000000, 0x0003389e, 0x0003389e, 0x00000000 },
- { 0x0000a334, 0x00000000, 0x00000000, 0x000368de, 0x000368de, 0x00000000 },
- { 0x0000a338, 0x00000000, 0x00000000, 0x0003891e, 0x0003891e, 0x00000000 },
- { 0x0000a33c, 0x00000000, 0x00000000, 0x0003a95e, 0x0003a95e, 0x00000000 },
- { 0x0000a340, 0x00000000, 0x00000000, 0x0003e9df, 0x0003e9df, 0x00000000 },
- { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
{ 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
};
@@ -4568,7 +4551,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x00008110, 0x00000168 },
{ 0x00008118, 0x000100aa },
{ 0x0000811c, 0x00003210 },
- { 0x00008120, 0x08f04800 },
+ { 0x00008120, 0x08f04810 },
{ 0x00008124, 0x00000000 },
{ 0x00008128, 0x00000000 },
{ 0x0000812c, 0x00000000 },
@@ -4584,7 +4567,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x00008178, 0x00000100 },
{ 0x0000817c, 0x00000000 },
{ 0x000081c0, 0x00000000 },
- { 0x000081d0, 0x00003210 },
+ { 0x000081d0, 0x0000320a },
{ 0x000081ec, 0x00000000 },
{ 0x000081f0, 0x00000000 },
{ 0x000081f4, 0x00000000 },
@@ -4679,7 +4662,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x000099a0, 0x00000000 },
{ 0x000099a4, 0x00000001 },
{ 0x000099a8, 0x201fff00 },
- { 0x000099ac, 0x2def1000 },
+ { 0x000099ac, 0x2def0400 },
{ 0x000099b0, 0x03051000 },
{ 0x000099b4, 0x00000820 },
{ 0x000099dc, 0x00000000 },
@@ -4688,7 +4671,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x000099e8, 0x3c466478 },
{ 0x000099ec, 0x0cc80caa },
{ 0x000099f0, 0x00000000 },
- { 0x0000a208, 0x803e6788 },
+ { 0x0000a208, 0x803e68c8 },
{ 0x0000a210, 0x4080a333 },
{ 0x0000a214, 0x00206c10 },
{ 0x0000a218, 0x009c4060 },
@@ -4708,8 +4691,6 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x0000a268, 0x00000000 },
{ 0x0000a26c, 0x0ebae9e6 },
{ 0x0000d270, 0x0d820820 },
- { 0x0000a278, 0x318c6318 },
- { 0x0000a27c, 0x050c0318 },
{ 0x0000d35c, 0x07ffffef },
{ 0x0000d360, 0x0fffffe7 },
{ 0x0000d364, 0x17ffffe5 },
@@ -4724,8 +4705,6 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x0000a388, 0x0c000000 },
{ 0x0000a38c, 0x20202020 },
{ 0x0000a390, 0x20202020 },
- { 0x0000a394, 0x318c6318 },
- { 0x0000a398, 0x00000318 },
{ 0x0000a39c, 0x00000001 },
{ 0x0000a3a0, 0x00000000 },
{ 0x0000a3a4, 0x00000000 },
@@ -4740,8 +4719,6 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x0000a3cc, 0x20202020 },
{ 0x0000a3d0, 0x20202020 },
{ 0x0000a3d4, 0x20202020 },
- { 0x0000a3dc, 0x318c6318 },
- { 0x0000a3e0, 0x00000318 },
{ 0x0000a3e4, 0x00000000 },
{ 0x0000a3e8, 0x18c43433 },
{ 0x0000a3ec, 0x00f70081 },
@@ -4752,13 +4729,11 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x00007810, 0x71c0d388 },
{ 0x00007814, 0x924934a8 },
{ 0x0000781c, 0x00000000 },
- { 0x00007820, 0x00000c04 },
{ 0x00007824, 0x00d86fff },
{ 0x00007828, 0x26d2491b },
{ 0x0000782c, 0x6e36d97b },
{ 0x00007830, 0xedb6d96e },
{ 0x00007834, 0x71400087 },
- { 0x00007838, 0xfac68801 },
{ 0x0000783c, 0x0001fffe },
{ 0x00007840, 0xffeb1a20 },
{ 0x00007844, 0x000c0db6 },
@@ -4771,10 +4746,81 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
{ 0x00007860, 0x21084210 },
{ 0x00007864, 0xf7d7ffde },
{ 0x00007868, 0xc2034080 },
- { 0x0000786c, 0x48609eb4 },
{ 0x00007870, 0x10142c00 },
};
+static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
+ /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
+ { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000a304, 0x00000000, 0x00000000, 0x00005200, 0x00005200, 0x00000000 },
+ { 0x0000a308, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
+ { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 },
+ { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 },
+ { 0x0000a314, 0x00000000, 0x00000000, 0x0000f440, 0x0000f440, 0x00000000 },
+ { 0x0000a318, 0x00000000, 0x00000000, 0x00014640, 0x00014640, 0x00000000 },
+ { 0x0000a31c, 0x00000000, 0x00000000, 0x00018680, 0x00018680, 0x00000000 },
+ { 0x0000a320, 0x00000000, 0x00000000, 0x00019841, 0x00019841, 0x00000000 },
+ { 0x0000a324, 0x00000000, 0x00000000, 0x0001ca40, 0x0001ca40, 0x00000000 },
+ { 0x0000a328, 0x00000000, 0x00000000, 0x0001fa80, 0x0001fa80, 0x00000000 },
+ { 0x0000a32c, 0x00000000, 0x00000000, 0x00023ac0, 0x00023ac0, 0x00000000 },
+ { 0x0000a330, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
+ { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 },
+ { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
+ { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
+ { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 },
+ { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
+ { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
+ { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
+ { 0x0000a278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+ { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
+ { 0x0000a394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+ { 0x0000a398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
+ { 0x0000a3dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+ { 0x0000a3e0, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
+};
+
+static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
+ /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
+ { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
+ { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
+ { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
+ { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 },
+ { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 },
+ { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 },
+ { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 },
+ { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 },
+ { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 },
+ { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 },
+ { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 },
+ { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 },
+ { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 },
+ { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
+ { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
+ { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+ { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 },
+ { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
+ { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
+ { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
+ { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+ { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c },
+ { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+ { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
+ { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+ { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
+};
+
static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
{0x00004040, 0x9248fd00 },
{0x00004040, 0x24924924 },
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c
index af32d091dc38..e0a6dee45839 100644
--- a/drivers/net/wireless/ath9k/mac.c
+++ b/drivers/net/wireless/ath9k/mac.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,45 +14,40 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
-static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
+static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
struct ath9k_tx_queue_info *qi)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
"tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
- ahp->ah_txOkInterruptMask, ahp->ah_txErrInterruptMask,
- ahp->ah_txDescInterruptMask, ahp->ah_txEolInterruptMask,
- ahp->ah_txUrnInterruptMask);
+ ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
+ ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
+ ah->txurn_interrupt_mask);
REG_WRITE(ah, AR_IMR_S0,
- SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
- | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
+ SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
+ | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
REG_WRITE(ah, AR_IMR_S1,
- SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
- | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
+ SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
+ | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
REG_RMW_FIELD(ah, AR_IMR_S2,
- AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
+ AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask);
}
-u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
+u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
{
return REG_READ(ah, AR_QTXDP(q));
}
-bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp)
+bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
{
REG_WRITE(ah, AR_QTXDP(q), txdp);
return true;
}
-bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
+bool ath9k_hw_txstart(struct ath_hw *ah, u32 q)
{
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
@@ -61,7 +56,7 @@ bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
return true;
}
-u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
{
u32 npend;
@@ -75,16 +70,15 @@ u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
return npend;
}
-bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
+bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 txcfg, curLevel, newLevel;
enum ath9k_int omask;
- if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
+ if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD)
return false;
- omask = ath9k_hw_set_interrupts(ah, ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
+ omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL);
txcfg = REG_READ(ah, AR_TXCFG);
curLevel = MS(txcfg, AR_FTRIG);
@@ -100,21 +94,38 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
ath9k_hw_set_interrupts(ah, omask);
- ah->ah_txTrigLevel = newLevel;
+ ah->tx_trig_level = newLevel;
return newLevel != curLevel;
}
-bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
+bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
{
+#define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */
+#define ATH9K_TIME_QUANTUM 100 /* usec */
+
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
+ struct ath9k_tx_queue_info *qi;
u32 tsfLow, j, wait;
+ u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
+
+ if (q >= pCap->total_queues) {
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
+ return false;
+ }
+
+ qi = &ah->txq[q];
+ if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+ DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
+ return false;
+ }
REG_WRITE(ah, AR_Q_TXD, 1 << q);
- for (wait = 1000; wait != 0; wait--) {
+ for (wait = wait_time; wait != 0; wait--) {
if (ath9k_hw_numtxpending(ah, q) == 0)
break;
- udelay(100);
+ udelay(ATH9K_TIME_QUANTUM);
}
if (ath9k_hw_numtxpending(ah, q)) {
@@ -144,8 +155,7 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
udelay(200);
REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
- wait = 1000;
-
+ wait = wait_time;
while (ath9k_hw_numtxpending(ah, q)) {
if ((--wait) == 0) {
DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
@@ -153,18 +163,20 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
"msec after killing last frame\n");
break;
}
- udelay(100);
+ udelay(ATH9K_TIME_QUANTUM);
}
REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
}
REG_WRITE(ah, AR_Q_TXD, 0);
-
return wait != 0;
+
+#undef ATH9K_TX_STOP_DMA_TIMEOUT
+#undef ATH9K_TIME_QUANTUM
}
-bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
+bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 segLen, bool firstSeg,
bool lastSeg, const struct ath_desc *ds0)
{
@@ -192,7 +204,7 @@ bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
return true;
}
-void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -203,7 +215,7 @@ void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
}
-int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
+int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -273,19 +285,18 @@ int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
- ds->ds_txstat.ts_antenna = 1;
+ ds->ds_txstat.ts_antenna = 0;
return 0;
}
-void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
u32 keyIx, enum ath9k_key_type keyType, u32 flags)
{
struct ar5416_desc *ads = AR5416DESC(ds);
- struct ath_hal_5416 *ahp = AH5416(ah);
- txPower += ahp->ah_txPowerIndexOffset;
+ txPower += ah->txpower_indexoffset;
if (txPower > 63)
txPower = 63;
@@ -314,7 +325,7 @@ void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
}
}
-void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
struct ath_desc *lastds,
u32 durUpdateEn, u32 rtsctsRate,
u32 rtsctsDuration,
@@ -325,9 +336,6 @@ void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
struct ar5416_desc *last_ads = AR5416DESC(lastds);
u32 ds_ctl0;
- (void) nseries;
- (void) rtsctsDuration;
-
if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
ds_ctl0 = ads->ds_ctl0;
@@ -372,7 +380,7 @@ void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
last_ads->ds_ctl3 = ads->ds_ctl3;
}
-void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
u32 aggrLen)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -382,7 +390,7 @@ void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
}
-void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
u32 numDelims)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -396,7 +404,7 @@ void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl6 = ctl6;
}
-void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
+void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -405,14 +413,14 @@ void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
ads->ds_ctl6 &= ~AR_PadDelim;
}
-void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
+void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
{
struct ar5416_desc *ads = AR5416DESC(ds);
ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
}
-void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
u32 burstDuration)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -421,7 +429,7 @@ void ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
}
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
+void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
u32 vmf)
{
struct ar5416_desc *ads = AR5416DESC(ds);
@@ -432,20 +440,17 @@ void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
ads->ds_ctl0 &= ~AR_VirtMoreFrag;
}
-void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
+void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- *txqs &= ahp->ah_intrTxqs;
- ahp->ah_intrTxqs &= ~(*txqs);
+ *txqs &= ah->intr_txqs;
+ ah->intr_txqs &= ~(*txqs);
}
-bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
+bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
const struct ath9k_tx_queue_info *qinfo)
{
u32 cw;
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
@@ -453,7 +458,7 @@ bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
return false;
}
- qi = &ahp->ah_txq[q];
+ qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
return false;
@@ -509,11 +514,10 @@ bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
return true;
}
-bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
+bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
struct ath9k_tx_queue_info *qinfo)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
@@ -521,7 +525,7 @@ bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
return false;
}
- qi = &ahp->ah_txq[q];
+ qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
return false;
@@ -545,12 +549,11 @@ bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
return true;
}
-int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
const struct ath9k_tx_queue_info *qinfo)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
struct ath9k_tx_queue_info *qi;
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
int q;
switch (type) {
@@ -568,7 +571,7 @@ int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
break;
case ATH9K_TX_QUEUE_DATA:
for (q = 0; q < pCap->total_queues; q++)
- if (ahp->ah_txq[q].tqi_type ==
+ if (ah->txq[q].tqi_type ==
ATH9K_TX_QUEUE_INACTIVE)
break;
if (q == pCap->total_queues) {
@@ -584,7 +587,7 @@ int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
- qi = &ahp->ah_txq[q];
+ qi = &ah->txq[q];
if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
"tx queue %u already active\n", q);
@@ -611,17 +614,16 @@ int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
return q;
}
-bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
+bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
return false;
}
- qi = &ahp->ah_txq[q];
+ qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
return false;
@@ -630,21 +632,20 @@ bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q);
qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
- ahp->ah_txOkInterruptMask &= ~(1 << q);
- ahp->ah_txErrInterruptMask &= ~(1 << q);
- ahp->ah_txDescInterruptMask &= ~(1 << q);
- ahp->ah_txEolInterruptMask &= ~(1 << q);
- ahp->ah_txUrnInterruptMask &= ~(1 << q);
+ ah->txok_interrupt_mask &= ~(1 << q);
+ ah->txerr_interrupt_mask &= ~(1 << q);
+ ah->txdesc_interrupt_mask &= ~(1 << q);
+ ah->txeol_interrupt_mask &= ~(1 << q);
+ ah->txurn_interrupt_mask &= ~(1 << q);
ath9k_hw_set_txq_interrupts(ah, qi);
return true;
}
-bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
+bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
- struct ath9k_channel *chan = ah->ah_curchan;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
+ struct ath9k_channel *chan = ah->curchan;
struct ath9k_tx_queue_info *qi;
u32 cwMin, chanCwMin, value;
@@ -653,7 +654,7 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
return false;
}
- qi = &ahp->ah_txq[q];
+ qi = &ah->txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
return true;
@@ -741,9 +742,9 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
| AR_Q_MISC_CBR_INCR_DIS1
| AR_Q_MISC_CBR_INCR_DIS0);
value = (qi->tqi_readyTime -
- (ah->ah_config.sw_beacon_response_time -
- ah->ah_config.dma_beacon_response_time) -
- ah->ah_config.additional_swba_backoff) * 1024;
+ (ah->config.sw_beacon_response_time -
+ ah->config.dma_beacon_response_time) -
+ ah->config.additional_swba_backoff) * 1024;
REG_WRITE(ah, AR_QRDYTIMECFG(q),
value | AR_Q_RDYTIMECFG_EN);
REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
@@ -771,31 +772,31 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
}
if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
- ahp->ah_txOkInterruptMask |= 1 << q;
+ ah->txok_interrupt_mask |= 1 << q;
else
- ahp->ah_txOkInterruptMask &= ~(1 << q);
+ ah->txok_interrupt_mask &= ~(1 << q);
if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
- ahp->ah_txErrInterruptMask |= 1 << q;
+ ah->txerr_interrupt_mask |= 1 << q;
else
- ahp->ah_txErrInterruptMask &= ~(1 << q);
+ ah->txerr_interrupt_mask &= ~(1 << q);
if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
- ahp->ah_txDescInterruptMask |= 1 << q;
+ ah->txdesc_interrupt_mask |= 1 << q;
else
- ahp->ah_txDescInterruptMask &= ~(1 << q);
+ ah->txdesc_interrupt_mask &= ~(1 << q);
if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
- ahp->ah_txEolInterruptMask |= 1 << q;
+ ah->txeol_interrupt_mask |= 1 << q;
else
- ahp->ah_txEolInterruptMask &= ~(1 << q);
+ ah->txeol_interrupt_mask &= ~(1 << q);
if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
- ahp->ah_txUrnInterruptMask |= 1 << q;
+ ah->txurn_interrupt_mask |= 1 << q;
else
- ahp->ah_txUrnInterruptMask &= ~(1 << q);
+ ah->txurn_interrupt_mask &= ~(1 << q);
ath9k_hw_set_txq_interrupts(ah, qi);
return true;
}
-int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 pa, struct ath_desc *nds, u64 tsf)
{
struct ar5416_desc ads;
@@ -860,11 +861,11 @@ int ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
return 0;
}
-bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
+bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 size, u32 flags)
{
struct ar5416_desc *ads = AR5416DESC(ds);
- struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
ads->ds_ctl1 = size & AR_BufLen;
if (flags & ATH9K_RXDESC_INTREQ)
@@ -877,7 +878,7 @@ bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
return true;
}
-bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
+bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
{
u32 reg;
@@ -885,7 +886,8 @@ bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
REG_SET_BIT(ah, AR_DIAG_SW,
(AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
- if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
+ if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE,
+ 0, AH_WAIT_TIMEOUT)) {
REG_CLR_BIT(ah, AR_DIAG_SW,
(AR_DIAG_RX_DIS |
AR_DIAG_RX_ABORT));
@@ -904,17 +906,17 @@ bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
return true;
}
-void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
{
REG_WRITE(ah, AR_RXDP, rxdp);
}
-void ath9k_hw_rxena(struct ath_hal *ah)
+void ath9k_hw_rxena(struct ath_hw *ah)
{
REG_WRITE(ah, AR_CR, AR_CR_RXE);
}
-void ath9k_hw_startpcureceive(struct ath_hal *ah)
+void ath9k_hw_startpcureceive(struct ath_hw *ah)
{
ath9k_enable_mib_counters(ah);
@@ -923,24 +925,41 @@ void ath9k_hw_startpcureceive(struct ath_hal *ah)
REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
}
-void ath9k_hw_stoppcurecv(struct ath_hal *ah)
+void ath9k_hw_stoppcurecv(struct ath_hw *ah)
{
REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
ath9k_hw_disable_mib_counters(ah);
}
-bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
+bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
{
+#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
+#define AH_RX_TIME_QUANTUM 100 /* usec */
+
+ int i;
+
REG_WRITE(ah, AR_CR, AR_CR_RXD);
- if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
+ /* Wait for rx enable bit to go low */
+ for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) {
+ if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0)
+ break;
+ udelay(AH_TIME_QUANTUM);
+ }
+
+ if (i == 0) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
- "dma failed to stop in 10ms\n"
- "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
- REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
+ "dma failed to stop in %d ms "
+ "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
+ AH_RX_STOP_DMA_TIMEOUT / 1000,
+ REG_READ(ah, AR_CR),
+ REG_READ(ah, AR_DIAG_SW));
return false;
} else {
return true;
}
+
+#undef AH_RX_TIME_QUANTUM
+#undef AH_RX_STOP_DMA_TIMEOUT
}
diff --git a/drivers/net/wireless/ath9k/mac.h b/drivers/net/wireless/ath9k/mac.h
new file mode 100644
index 000000000000..1176bce8b76c
--- /dev/null
+++ b/drivers/net/wireless/ath9k/mac.h
@@ -0,0 +1,680 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef MAC_H
+#define MAC_H
+
+#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_20_OR_LATER(ah) ? \
+ MS(ads->ds_rxstatus0, AR_RxRate) : \
+ (ads->ds_rxstatus3 >> 2) & 0xFF)
+
+#define set11nTries(_series, _index) \
+ (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
+
+#define set11nRate(_series, _index) \
+ (SM((_series)[_index].Rate, AR_XmitRate##_index))
+
+#define set11nPktDurRTSCTS(_series, _index) \
+ (SM((_series)[_index].PktDuration, AR_PacketDur##_index) | \
+ ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS ? \
+ AR_RTSCTSQual##_index : 0))
+
+#define set11nRateFlags(_series, _index) \
+ (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \
+ AR_2040_##_index : 0) \
+ |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \
+ AR_GI##_index : 0) \
+ |SM((_series)[_index].ChSel, AR_ChainSel##_index))
+
+#define CCK_SIFS_TIME 10
+#define CCK_PREAMBLE_BITS 144
+#define CCK_PLCP_BITS 48
+
+#define OFDM_SIFS_TIME 16
+#define OFDM_PREAMBLE_TIME 20
+#define OFDM_PLCP_BITS 22
+#define OFDM_SYMBOL_TIME 4
+
+#define OFDM_SIFS_TIME_HALF 32
+#define OFDM_PREAMBLE_TIME_HALF 40
+#define OFDM_PLCP_BITS_HALF 22
+#define OFDM_SYMBOL_TIME_HALF 8
+
+#define OFDM_SIFS_TIME_QUARTER 64
+#define OFDM_PREAMBLE_TIME_QUARTER 80
+#define OFDM_PLCP_BITS_QUARTER 22
+#define OFDM_SYMBOL_TIME_QUARTER 16
+
+#define INIT_AIFS 2
+#define INIT_CWMIN 15
+#define INIT_CWMIN_11B 31
+#define INIT_CWMAX 1023
+#define INIT_SH_RETRY 10
+#define INIT_LG_RETRY 10
+#define INIT_SSH_RETRY 32
+#define INIT_SLG_RETRY 32
+
+#define ATH9K_SLOT_TIME_6 6
+#define ATH9K_SLOT_TIME_9 9
+#define ATH9K_SLOT_TIME_20 20
+
+#define ATH9K_TXERR_XRETRY 0x01
+#define ATH9K_TXERR_FILT 0x02
+#define ATH9K_TXERR_FIFO 0x04
+#define ATH9K_TXERR_XTXOP 0x08
+#define ATH9K_TXERR_TIMER_EXPIRED 0x10
+
+#define ATH9K_TX_BA 0x01
+#define ATH9K_TX_PWRMGMT 0x02
+#define ATH9K_TX_DESC_CFG_ERR 0x04
+#define ATH9K_TX_DATA_UNDERRUN 0x08
+#define ATH9K_TX_DELIM_UNDERRUN 0x10
+#define ATH9K_TX_SW_ABORTED 0x40
+#define ATH9K_TX_SW_FILTERED 0x80
+
+#define MIN_TX_FIFO_THRESHOLD 0x1
+#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1)
+#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD
+
+struct ath_tx_status {
+ u32 ts_tstamp;
+ u16 ts_seqnum;
+ u8 ts_status;
+ u8 ts_ratecode;
+ u8 ts_rateindex;
+ int8_t ts_rssi;
+ u8 ts_shortretry;
+ u8 ts_longretry;
+ u8 ts_virtcol;
+ u8 ts_antenna;
+ u8 ts_flags;
+ int8_t ts_rssi_ctl0;
+ int8_t ts_rssi_ctl1;
+ int8_t ts_rssi_ctl2;
+ int8_t ts_rssi_ext0;
+ int8_t ts_rssi_ext1;
+ int8_t ts_rssi_ext2;
+ u8 pad[3];
+ u32 ba_low;
+ u32 ba_high;
+ u32 evm0;
+ u32 evm1;
+ u32 evm2;
+};
+
+struct ath_rx_status {
+ u32 rs_tstamp;
+ u16 rs_datalen;
+ u8 rs_status;
+ u8 rs_phyerr;
+ int8_t rs_rssi;
+ u8 rs_keyix;
+ u8 rs_rate;
+ u8 rs_antenna;
+ u8 rs_more;
+ int8_t rs_rssi_ctl0;
+ int8_t rs_rssi_ctl1;
+ int8_t rs_rssi_ctl2;
+ int8_t rs_rssi_ext0;
+ int8_t rs_rssi_ext1;
+ int8_t rs_rssi_ext2;
+ u8 rs_isaggr;
+ u8 rs_moreaggr;
+ u8 rs_num_delims;
+ u8 rs_flags;
+ u32 evm0;
+ u32 evm1;
+ u32 evm2;
+};
+
+#define ATH9K_RXERR_CRC 0x01
+#define ATH9K_RXERR_PHY 0x02
+#define ATH9K_RXERR_FIFO 0x04
+#define ATH9K_RXERR_DECRYPT 0x08
+#define ATH9K_RXERR_MIC 0x10
+
+#define ATH9K_RX_MORE 0x01
+#define ATH9K_RX_MORE_AGGR 0x02
+#define ATH9K_RX_GI 0x04
+#define ATH9K_RX_2040 0x08
+#define ATH9K_RX_DELIM_CRC_PRE 0x10
+#define ATH9K_RX_DELIM_CRC_POST 0x20
+#define ATH9K_RX_DECRYPT_BUSY 0x40
+
+#define ATH9K_RXKEYIX_INVALID ((u8)-1)
+#define ATH9K_TXKEYIX_INVALID ((u32)-1)
+
+struct ath_desc {
+ u32 ds_link;
+ u32 ds_data;
+ u32 ds_ctl0;
+ u32 ds_ctl1;
+ u32 ds_hw[20];
+ union {
+ struct ath_tx_status tx;
+ struct ath_rx_status rx;
+ void *stats;
+ } ds_us;
+ void *ds_vdata;
+} __packed;
+
+#define ds_txstat ds_us.tx
+#define ds_rxstat ds_us.rx
+#define ds_stat ds_us.stats
+
+#define ATH9K_TXDESC_CLRDMASK 0x0001
+#define ATH9K_TXDESC_NOACK 0x0002
+#define ATH9K_TXDESC_RTSENA 0x0004
+#define ATH9K_TXDESC_CTSENA 0x0008
+/* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for
+ * the descriptor its marked on. We take a tx interrupt to reap
+ * descriptors when the h/w hits an EOL condition or
+ * when the descriptor is specifically marked to generate
+ * an interrupt with this flag. Descriptors should be
+ * marked periodically to insure timely replenishing of the
+ * supply needed for sending frames. Defering interrupts
+ * reduces system load and potentially allows more concurrent
+ * work to be done but if done to aggressively can cause
+ * senders to backup. When the hardware queue is left too
+ * large rate control information may also be too out of
+ * date. An Alternative for this is TX interrupt mitigation
+ * but this needs more testing. */
+#define ATH9K_TXDESC_INTREQ 0x0010
+#define ATH9K_TXDESC_VEOL 0x0020
+#define ATH9K_TXDESC_EXT_ONLY 0x0040
+#define ATH9K_TXDESC_EXT_AND_CTL 0x0080
+#define ATH9K_TXDESC_VMF 0x0100
+#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
+#define ATH9K_TXDESC_CAB 0x0400
+
+#define ATH9K_RXDESC_INTREQ 0x0020
+
+struct ar5416_desc {
+ u32 ds_link;
+ u32 ds_data;
+ u32 ds_ctl0;
+ u32 ds_ctl1;
+ union {
+ struct {
+ u32 ctl2;
+ u32 ctl3;
+ u32 ctl4;
+ u32 ctl5;
+ u32 ctl6;
+ u32 ctl7;
+ u32 ctl8;
+ u32 ctl9;
+ u32 ctl10;
+ u32 ctl11;
+ u32 status0;
+ u32 status1;
+ u32 status2;
+ u32 status3;
+ u32 status4;
+ u32 status5;
+ u32 status6;
+ u32 status7;
+ u32 status8;
+ u32 status9;
+ } tx;
+ struct {
+ u32 status0;
+ u32 status1;
+ u32 status2;
+ u32 status3;
+ u32 status4;
+ u32 status5;
+ u32 status6;
+ u32 status7;
+ u32 status8;
+ } rx;
+ } u;
+} __packed;
+
+#define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds))
+#define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds))
+
+#define ds_ctl2 u.tx.ctl2
+#define ds_ctl3 u.tx.ctl3
+#define ds_ctl4 u.tx.ctl4
+#define ds_ctl5 u.tx.ctl5
+#define ds_ctl6 u.tx.ctl6
+#define ds_ctl7 u.tx.ctl7
+#define ds_ctl8 u.tx.ctl8
+#define ds_ctl9 u.tx.ctl9
+#define ds_ctl10 u.tx.ctl10
+#define ds_ctl11 u.tx.ctl11
+
+#define ds_txstatus0 u.tx.status0
+#define ds_txstatus1 u.tx.status1
+#define ds_txstatus2 u.tx.status2
+#define ds_txstatus3 u.tx.status3
+#define ds_txstatus4 u.tx.status4
+#define ds_txstatus5 u.tx.status5
+#define ds_txstatus6 u.tx.status6
+#define ds_txstatus7 u.tx.status7
+#define ds_txstatus8 u.tx.status8
+#define ds_txstatus9 u.tx.status9
+
+#define ds_rxstatus0 u.rx.status0
+#define ds_rxstatus1 u.rx.status1
+#define ds_rxstatus2 u.rx.status2
+#define ds_rxstatus3 u.rx.status3
+#define ds_rxstatus4 u.rx.status4
+#define ds_rxstatus5 u.rx.status5
+#define ds_rxstatus6 u.rx.status6
+#define ds_rxstatus7 u.rx.status7
+#define ds_rxstatus8 u.rx.status8
+
+#define AR_FrameLen 0x00000fff
+#define AR_VirtMoreFrag 0x00001000
+#define AR_TxCtlRsvd00 0x0000e000
+#define AR_XmitPower 0x003f0000
+#define AR_XmitPower_S 16
+#define AR_RTSEnable 0x00400000
+#define AR_VEOL 0x00800000
+#define AR_ClrDestMask 0x01000000
+#define AR_TxCtlRsvd01 0x1e000000
+#define AR_TxIntrReq 0x20000000
+#define AR_DestIdxValid 0x40000000
+#define AR_CTSEnable 0x80000000
+
+#define AR_BufLen 0x00000fff
+#define AR_TxMore 0x00001000
+#define AR_DestIdx 0x000fe000
+#define AR_DestIdx_S 13
+#define AR_FrameType 0x00f00000
+#define AR_FrameType_S 20
+#define AR_NoAck 0x01000000
+#define AR_InsertTS 0x02000000
+#define AR_CorruptFCS 0x04000000
+#define AR_ExtOnly 0x08000000
+#define AR_ExtAndCtl 0x10000000
+#define AR_MoreAggr 0x20000000
+#define AR_IsAggr 0x40000000
+
+#define AR_BurstDur 0x00007fff
+#define AR_BurstDur_S 0
+#define AR_DurUpdateEna 0x00008000
+#define AR_XmitDataTries0 0x000f0000
+#define AR_XmitDataTries0_S 16
+#define AR_XmitDataTries1 0x00f00000
+#define AR_XmitDataTries1_S 20
+#define AR_XmitDataTries2 0x0f000000
+#define AR_XmitDataTries2_S 24
+#define AR_XmitDataTries3 0xf0000000
+#define AR_XmitDataTries3_S 28
+
+#define AR_XmitRate0 0x000000ff
+#define AR_XmitRate0_S 0
+#define AR_XmitRate1 0x0000ff00
+#define AR_XmitRate1_S 8
+#define AR_XmitRate2 0x00ff0000
+#define AR_XmitRate2_S 16
+#define AR_XmitRate3 0xff000000
+#define AR_XmitRate3_S 24
+
+#define AR_PacketDur0 0x00007fff
+#define AR_PacketDur0_S 0
+#define AR_RTSCTSQual0 0x00008000
+#define AR_PacketDur1 0x7fff0000
+#define AR_PacketDur1_S 16
+#define AR_RTSCTSQual1 0x80000000
+
+#define AR_PacketDur2 0x00007fff
+#define AR_PacketDur2_S 0
+#define AR_RTSCTSQual2 0x00008000
+#define AR_PacketDur3 0x7fff0000
+#define AR_PacketDur3_S 16
+#define AR_RTSCTSQual3 0x80000000
+
+#define AR_AggrLen 0x0000ffff
+#define AR_AggrLen_S 0
+#define AR_TxCtlRsvd60 0x00030000
+#define AR_PadDelim 0x03fc0000
+#define AR_PadDelim_S 18
+#define AR_EncrType 0x0c000000
+#define AR_EncrType_S 26
+#define AR_TxCtlRsvd61 0xf0000000
+
+#define AR_2040_0 0x00000001
+#define AR_GI0 0x00000002
+#define AR_ChainSel0 0x0000001c
+#define AR_ChainSel0_S 2
+#define AR_2040_1 0x00000020
+#define AR_GI1 0x00000040
+#define AR_ChainSel1 0x00000380
+#define AR_ChainSel1_S 7
+#define AR_2040_2 0x00000400
+#define AR_GI2 0x00000800
+#define AR_ChainSel2 0x00007000
+#define AR_ChainSel2_S 12
+#define AR_2040_3 0x00008000
+#define AR_GI3 0x00010000
+#define AR_ChainSel3 0x000e0000
+#define AR_ChainSel3_S 17
+#define AR_RTSCTSRate 0x0ff00000
+#define AR_RTSCTSRate_S 20
+#define AR_TxCtlRsvd70 0xf0000000
+
+#define AR_TxRSSIAnt00 0x000000ff
+#define AR_TxRSSIAnt00_S 0
+#define AR_TxRSSIAnt01 0x0000ff00
+#define AR_TxRSSIAnt01_S 8
+#define AR_TxRSSIAnt02 0x00ff0000
+#define AR_TxRSSIAnt02_S 16
+#define AR_TxStatusRsvd00 0x3f000000
+#define AR_TxBaStatus 0x40000000
+#define AR_TxStatusRsvd01 0x80000000
+
+#define AR_FrmXmitOK 0x00000001
+#define AR_ExcessiveRetries 0x00000002
+#define AR_FIFOUnderrun 0x00000004
+#define AR_Filtered 0x00000008
+#define AR_RTSFailCnt 0x000000f0
+#define AR_RTSFailCnt_S 4
+#define AR_DataFailCnt 0x00000f00
+#define AR_DataFailCnt_S 8
+#define AR_VirtRetryCnt 0x0000f000
+#define AR_VirtRetryCnt_S 12
+#define AR_TxDelimUnderrun 0x00010000
+#define AR_TxDataUnderrun 0x00020000
+#define AR_DescCfgErr 0x00040000
+#define AR_TxTimerExpired 0x00080000
+#define AR_TxStatusRsvd10 0xfff00000
+
+#define AR_SendTimestamp ds_txstatus2
+#define AR_BaBitmapLow ds_txstatus3
+#define AR_BaBitmapHigh ds_txstatus4
+
+#define AR_TxRSSIAnt10 0x000000ff
+#define AR_TxRSSIAnt10_S 0
+#define AR_TxRSSIAnt11 0x0000ff00
+#define AR_TxRSSIAnt11_S 8
+#define AR_TxRSSIAnt12 0x00ff0000
+#define AR_TxRSSIAnt12_S 16
+#define AR_TxRSSICombined 0xff000000
+#define AR_TxRSSICombined_S 24
+
+#define AR_TxEVM0 ds_txstatus5
+#define AR_TxEVM1 ds_txstatus6
+#define AR_TxEVM2 ds_txstatus7
+
+#define AR_TxDone 0x00000001
+#define AR_SeqNum 0x00001ffe
+#define AR_SeqNum_S 1
+#define AR_TxStatusRsvd80 0x0001e000
+#define AR_TxOpExceeded 0x00020000
+#define AR_TxStatusRsvd81 0x001c0000
+#define AR_FinalTxIdx 0x00600000
+#define AR_FinalTxIdx_S 21
+#define AR_TxStatusRsvd82 0x01800000
+#define AR_PowerMgmt 0x02000000
+#define AR_TxStatusRsvd83 0xfc000000
+
+#define AR_RxCTLRsvd00 0xffffffff
+
+#define AR_BufLen 0x00000fff
+#define AR_RxCtlRsvd00 0x00001000
+#define AR_RxIntrReq 0x00002000
+#define AR_RxCtlRsvd01 0xffffc000
+
+#define AR_RxRSSIAnt00 0x000000ff
+#define AR_RxRSSIAnt00_S 0
+#define AR_RxRSSIAnt01 0x0000ff00
+#define AR_RxRSSIAnt01_S 8
+#define AR_RxRSSIAnt02 0x00ff0000
+#define AR_RxRSSIAnt02_S 16
+#define AR_RxRate 0xff000000
+#define AR_RxRate_S 24
+#define AR_RxStatusRsvd00 0xff000000
+
+#define AR_DataLen 0x00000fff
+#define AR_RxMore 0x00001000
+#define AR_NumDelim 0x003fc000
+#define AR_NumDelim_S 14
+#define AR_RxStatusRsvd10 0xff800000
+
+#define AR_RcvTimestamp ds_rxstatus2
+
+#define AR_GI 0x00000001
+#define AR_2040 0x00000002
+#define AR_Parallel40 0x00000004
+#define AR_Parallel40_S 2
+#define AR_RxStatusRsvd30 0x000000f8
+#define AR_RxAntenna 0xffffff00
+#define AR_RxAntenna_S 8
+
+#define AR_RxRSSIAnt10 0x000000ff
+#define AR_RxRSSIAnt10_S 0
+#define AR_RxRSSIAnt11 0x0000ff00
+#define AR_RxRSSIAnt11_S 8
+#define AR_RxRSSIAnt12 0x00ff0000
+#define AR_RxRSSIAnt12_S 16
+#define AR_RxRSSICombined 0xff000000
+#define AR_RxRSSICombined_S 24
+
+#define AR_RxEVM0 ds_rxstatus4
+#define AR_RxEVM1 ds_rxstatus5
+#define AR_RxEVM2 ds_rxstatus6
+
+#define AR_RxDone 0x00000001
+#define AR_RxFrameOK 0x00000002
+#define AR_CRCErr 0x00000004
+#define AR_DecryptCRCErr 0x00000008
+#define AR_PHYErr 0x00000010
+#define AR_MichaelErr 0x00000020
+#define AR_PreDelimCRCErr 0x00000040
+#define AR_RxStatusRsvd70 0x00000080
+#define AR_RxKeyIdxValid 0x00000100
+#define AR_KeyIdx 0x0000fe00
+#define AR_KeyIdx_S 9
+#define AR_PHYErrCode 0x0000ff00
+#define AR_PHYErrCode_S 8
+#define AR_RxMoreAggr 0x00010000
+#define AR_RxAggr 0x00020000
+#define AR_PostDelimCRCErr 0x00040000
+#define AR_RxStatusRsvd71 0x3ff80000
+#define AR_DecryptBusyErr 0x40000000
+#define AR_KeyMiss 0x80000000
+
+enum ath9k_tx_queue {
+ ATH9K_TX_QUEUE_INACTIVE = 0,
+ ATH9K_TX_QUEUE_DATA,
+ ATH9K_TX_QUEUE_BEACON,
+ ATH9K_TX_QUEUE_CAB,
+ ATH9K_TX_QUEUE_UAPSD,
+ ATH9K_TX_QUEUE_PSPOLL
+};
+
+#define ATH9K_NUM_TX_QUEUES 10
+
+enum ath9k_tx_queue_subtype {
+ ATH9K_WME_AC_BK = 0,
+ ATH9K_WME_AC_BE,
+ ATH9K_WME_AC_VI,
+ ATH9K_WME_AC_VO,
+ ATH9K_WME_UPSD
+};
+
+enum ath9k_tx_queue_flags {
+ TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
+ TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
+ TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
+ TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
+ TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
+ TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
+ TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
+ TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
+ TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
+};
+
+#define ATH9K_TXQ_USEDEFAULT ((u32) -1)
+#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
+
+#define ATH9K_DECOMP_MASK_SIZE 128
+#define ATH9K_READY_TIME_LO_BOUND 50
+#define ATH9K_READY_TIME_HI_BOUND 96
+
+enum ath9k_pkt_type {
+ ATH9K_PKT_TYPE_NORMAL = 0,
+ ATH9K_PKT_TYPE_ATIM,
+ ATH9K_PKT_TYPE_PSPOLL,
+ ATH9K_PKT_TYPE_BEACON,
+ ATH9K_PKT_TYPE_PROBE_RESP,
+ ATH9K_PKT_TYPE_CHIRP,
+ ATH9K_PKT_TYPE_GRP_POLL,
+};
+
+struct ath9k_tx_queue_info {
+ u32 tqi_ver;
+ enum ath9k_tx_queue tqi_type;
+ enum ath9k_tx_queue_subtype tqi_subtype;
+ enum ath9k_tx_queue_flags tqi_qflags;
+ u32 tqi_priority;
+ u32 tqi_aifs;
+ u32 tqi_cwmin;
+ u32 tqi_cwmax;
+ u16 tqi_shretry;
+ u16 tqi_lgretry;
+ u32 tqi_cbrPeriod;
+ u32 tqi_cbrOverflowLimit;
+ u32 tqi_burstTime;
+ u32 tqi_readyTime;
+ u32 tqi_physCompBuf;
+ u32 tqi_intFlags;
+};
+
+enum ath9k_rx_filter {
+ ATH9K_RX_FILTER_UCAST = 0x00000001,
+ ATH9K_RX_FILTER_MCAST = 0x00000002,
+ ATH9K_RX_FILTER_BCAST = 0x00000004,
+ ATH9K_RX_FILTER_CONTROL = 0x00000008,
+ ATH9K_RX_FILTER_BEACON = 0x00000010,
+ ATH9K_RX_FILTER_PROM = 0x00000020,
+ ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
+ ATH9K_RX_FILTER_PHYERR = 0x00000100,
+ ATH9K_RX_FILTER_MYBEACON = 0x00000200,
+ ATH9K_RX_FILTER_PSPOLL = 0x00004000,
+ ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
+ ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000,
+};
+
+#define ATH9K_RATESERIES_RTS_CTS 0x0001
+#define ATH9K_RATESERIES_2040 0x0002
+#define ATH9K_RATESERIES_HALFGI 0x0004
+
+struct ath9k_11n_rate_series {
+ u32 Tries;
+ u32 Rate;
+ u32 PktDuration;
+ u32 ChSel;
+ u32 RateFlags;
+};
+
+struct ath9k_keyval {
+ u8 kv_type;
+ u8 kv_pad;
+ u16 kv_len;
+ u8 kv_val[16]; /* TK */
+ u8 kv_mic[8]; /* Michael MIC key */
+ u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
+ * supports both MIC keys in the same key cache entry;
+ * in that case, kv_mic is the RX key) */
+};
+
+enum ath9k_key_type {
+ ATH9K_KEY_TYPE_CLEAR,
+ ATH9K_KEY_TYPE_WEP,
+ ATH9K_KEY_TYPE_AES,
+ ATH9K_KEY_TYPE_TKIP,
+};
+
+enum ath9k_cipher {
+ ATH9K_CIPHER_WEP = 0,
+ ATH9K_CIPHER_AES_OCB = 1,
+ ATH9K_CIPHER_AES_CCM = 2,
+ ATH9K_CIPHER_CKIP = 3,
+ ATH9K_CIPHER_TKIP = 4,
+ ATH9K_CIPHER_CLR = 5,
+ ATH9K_CIPHER_MIC = 127
+};
+
+enum ath9k_ht_macmode {
+ ATH9K_HT_MACMODE_20 = 0,
+ ATH9K_HT_MACMODE_2040 = 1,
+};
+
+enum ath9k_ht_extprotspacing {
+ ATH9K_HT_EXTPROTSPACING_20 = 0,
+ ATH9K_HT_EXTPROTSPACING_25 = 1,
+};
+
+struct ath_hw;
+struct ath9k_channel;
+struct ath_rate_table;
+
+u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
+bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
+bool ath9k_hw_txstart(struct ath_hw *ah, u32 q);
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
+bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
+bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
+bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
+ u32 segLen, bool firstSeg,
+ bool lastSeg, const struct ath_desc *ds0);
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
+int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
+ u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
+ u32 keyIx, enum ath9k_key_type keyType, u32 flags);
+void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
+ struct ath_desc *lastds,
+ u32 durUpdateEn, u32 rtsctsRate,
+ u32 rtsctsDuration,
+ struct ath9k_11n_rate_series series[],
+ u32 nseries, u32 flags);
+void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
+ u32 aggrLen);
+void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
+ u32 numDelims);
+void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
+ u32 burstDuration);
+void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
+ u32 vmf);
+void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
+bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
+ const struct ath9k_tx_queue_info *qinfo);
+bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
+ struct ath9k_tx_queue_info *qinfo);
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
+ const struct ath9k_tx_queue_info *qinfo);
+bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
+bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
+ u32 pa, struct ath_desc *nds, u64 tsf);
+bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
+ u32 size, u32 flags);
+bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
+void ath9k_hw_rxena(struct ath_hw *ah);
+void ath9k_hw_startpcureceive(struct ath_hw *ah);
+void ath9k_hw_stoppcurecv(struct ath_hw *ah);
+bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
+
+#endif /* MAC_H */
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 0e80990d8e84..13d4e6756c99 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -15,9 +15,7 @@
*/
#include <linux/nl80211.h>
-#include "core.h"
-#include "reg.h"
-#include "hw.h"
+#include "ath9k.h"
#define ATH_PCI_VERSION "0.1"
@@ -28,84 +26,129 @@ MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
MODULE_LICENSE("Dual BSD/GPL");
-static struct pci_device_id ath_pci_id_table[] __devinitdata = {
- { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */
- { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
- { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */
- { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
- { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
- { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
- { 0 }
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
+
+/* We use the hw_value as an index into our private channel structure */
+
+#define CHAN2G(_freq, _idx) { \
+ .center_freq = (_freq), \
+ .hw_value = (_idx), \
+ .max_power = 30, \
+}
+
+#define CHAN5G(_freq, _idx) { \
+ .band = IEEE80211_BAND_5GHZ, \
+ .center_freq = (_freq), \
+ .hw_value = (_idx), \
+ .max_power = 30, \
+}
+
+/* Some 2 GHz radios are actually tunable on 2312-2732
+ * on 5 MHz steps, we support the channels which we know
+ * we have calibration data for all cards though to make
+ * this static */
+static struct ieee80211_channel ath9k_2ghz_chantable[] = {
+ CHAN2G(2412, 0), /* Channel 1 */
+ CHAN2G(2417, 1), /* Channel 2 */
+ CHAN2G(2422, 2), /* Channel 3 */
+ CHAN2G(2427, 3), /* Channel 4 */
+ CHAN2G(2432, 4), /* Channel 5 */
+ CHAN2G(2437, 5), /* Channel 6 */
+ CHAN2G(2442, 6), /* Channel 7 */
+ CHAN2G(2447, 7), /* Channel 8 */
+ CHAN2G(2452, 8), /* Channel 9 */
+ CHAN2G(2457, 9), /* Channel 10 */
+ CHAN2G(2462, 10), /* Channel 11 */
+ CHAN2G(2467, 11), /* Channel 12 */
+ CHAN2G(2472, 12), /* Channel 13 */
+ CHAN2G(2484, 13), /* Channel 14 */
};
-static void ath_detach(struct ath_softc *sc);
-
-/* return bus cachesize in 4B word units */
-
-static void bus_read_cachesize(struct ath_softc *sc, int *csz)
-{
- u8 u8tmp;
-
- pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, (u8 *)&u8tmp);
- *csz = (int)u8tmp;
-
- /*
- * This check was put in to avoid "unplesant" consequences if
- * the bootrom has not fully initialized all PCI devices.
- * Sometimes the cache line size register is not set
- */
-
- if (*csz == 0)
- *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
-}
-
-static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
-{
- sc->cur_rate_table = sc->hw_rate_table[mode];
- /*
- * All protection frames are transmited at 2Mb/s for
- * 11g, otherwise at 1Mb/s.
- * XXX select protection rate index from rate table.
- */
- sc->sc_protrix = (mode == ATH9K_MODE_11G ? 1 : 0);
-}
+/* Some 5 GHz radios are actually tunable on XXXX-YYYY
+ * on 5 MHz steps, we support the channels which we know
+ * we have calibration data for all cards though to make
+ * this static */
+static struct ieee80211_channel ath9k_5ghz_chantable[] = {
+ /* _We_ call this UNII 1 */
+ CHAN5G(5180, 14), /* Channel 36 */
+ CHAN5G(5200, 15), /* Channel 40 */
+ CHAN5G(5220, 16), /* Channel 44 */
+ CHAN5G(5240, 17), /* Channel 48 */
+ /* _We_ call this UNII 2 */
+ CHAN5G(5260, 18), /* Channel 52 */
+ CHAN5G(5280, 19), /* Channel 56 */
+ CHAN5G(5300, 20), /* Channel 60 */
+ CHAN5G(5320, 21), /* Channel 64 */
+ /* _We_ call this "Middle band" */
+ CHAN5G(5500, 22), /* Channel 100 */
+ CHAN5G(5520, 23), /* Channel 104 */
+ CHAN5G(5540, 24), /* Channel 108 */
+ CHAN5G(5560, 25), /* Channel 112 */
+ CHAN5G(5580, 26), /* Channel 116 */
+ CHAN5G(5600, 27), /* Channel 120 */
+ CHAN5G(5620, 28), /* Channel 124 */
+ CHAN5G(5640, 29), /* Channel 128 */
+ CHAN5G(5660, 30), /* Channel 132 */
+ CHAN5G(5680, 31), /* Channel 136 */
+ CHAN5G(5700, 32), /* Channel 140 */
+ /* _We_ call this UNII 3 */
+ CHAN5G(5745, 33), /* Channel 149 */
+ CHAN5G(5765, 34), /* Channel 153 */
+ CHAN5G(5785, 35), /* Channel 157 */
+ CHAN5G(5805, 36), /* Channel 161 */
+ CHAN5G(5825, 37), /* Channel 165 */
+};
-static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan)
+static void ath_cache_conf_rate(struct ath_softc *sc,
+ struct ieee80211_conf *conf)
{
- if (chan->chanmode == CHANNEL_A)
- return ATH9K_MODE_11A;
- else if (chan->chanmode == CHANNEL_G)
- return ATH9K_MODE_11G;
- else if (chan->chanmode == CHANNEL_B)
- return ATH9K_MODE_11B;
- else if (chan->chanmode == CHANNEL_A_HT20)
- return ATH9K_MODE_11NA_HT20;
- else if (chan->chanmode == CHANNEL_G_HT20)
- return ATH9K_MODE_11NG_HT20;
- else if (chan->chanmode == CHANNEL_A_HT40PLUS)
- return ATH9K_MODE_11NA_HT40PLUS;
- else if (chan->chanmode == CHANNEL_A_HT40MINUS)
- return ATH9K_MODE_11NA_HT40MINUS;
- else if (chan->chanmode == CHANNEL_G_HT40PLUS)
- return ATH9K_MODE_11NG_HT40PLUS;
- else if (chan->chanmode == CHANNEL_G_HT40MINUS)
- return ATH9K_MODE_11NG_HT40MINUS;
-
- WARN_ON(1); /* should not get here */
-
- return ATH9K_MODE_11B;
+ switch (conf->channel->band) {
+ case IEEE80211_BAND_2GHZ:
+ if (conf_is_ht20(conf))
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
+ else if (conf_is_ht40_minus(conf))
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
+ else if (conf_is_ht40_plus(conf))
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS];
+ else
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11G];
+ break;
+ case IEEE80211_BAND_5GHZ:
+ if (conf_is_ht20(conf))
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
+ else if (conf_is_ht40_minus(conf))
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS];
+ else if (conf_is_ht40_plus(conf))
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS];
+ else
+ sc->cur_rate_table =
+ sc->hw_rate_table[ATH9K_MODE_11A];
+ break;
+ default:
+ BUG_ON(1);
+ break;
+ }
}
static void ath_update_txpow(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
u32 txpow;
- if (sc->sc_curtxpow != sc->sc_config.txpowlimit) {
- ath9k_hw_set_txpowerlimit(ah, sc->sc_config.txpowlimit);
+ if (sc->curtxpow != sc->config.txpowlimit) {
+ ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
/* read back in case value is clamped */
ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
- sc->sc_curtxpow = txpow;
+ sc->curtxpow = txpow;
}
}
@@ -176,150 +219,87 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
for (i = 0; i < maxrates; i++) {
rate[i].bitrate = rate_table->info[i].ratekbps / 100;
rate[i].hw_value = rate_table->info[i].ratecode;
+ if (rate_table->info[i].short_preamble) {
+ rate[i].hw_value_short = rate_table->info[i].ratecode |
+ rate_table->info[i].short_preamble;
+ rate[i].flags = IEEE80211_RATE_SHORT_PREAMBLE;
+ }
sband->n_bitrates++;
+
DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n",
rate[i].bitrate / 10, rate[i].hw_value);
}
}
-static int ath_setup_channels(struct ath_softc *sc)
-{
- struct ath_hal *ah = sc->sc_ah;
- int nchan, i, a = 0, b = 0;
- u8 regclassids[ATH_REGCLASSIDS_MAX];
- u32 nregclass = 0;
- struct ieee80211_supported_band *band_2ghz;
- struct ieee80211_supported_band *band_5ghz;
- struct ieee80211_channel *chan_2ghz;
- struct ieee80211_channel *chan_5ghz;
- struct ath9k_channel *c;
-
- /* Fill in ah->ah_channels */
- if (!ath9k_regd_init_channels(ah, ATH_CHAN_MAX, (u32 *)&nchan,
- regclassids, ATH_REGCLASSIDS_MAX,
- &nregclass, CTRY_DEFAULT, false, 1)) {
- u32 rd = ah->ah_currentRD;
- DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to collect channel list; "
- "regdomain likely %u country code %u\n",
- rd, CTRY_DEFAULT);
- return -EINVAL;
- }
-
- band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ];
- band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ];
- chan_2ghz = sc->channels[IEEE80211_BAND_2GHZ];
- chan_5ghz = sc->channels[IEEE80211_BAND_5GHZ];
-
- for (i = 0; i < nchan; i++) {
- c = &ah->ah_channels[i];
- if (IS_CHAN_2GHZ(c)) {
- chan_2ghz[a].band = IEEE80211_BAND_2GHZ;
- chan_2ghz[a].center_freq = c->channel;
- chan_2ghz[a].max_power = c->maxTxPower;
-
- if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
- chan_2ghz[a].flags |= IEEE80211_CHAN_NO_IBSS;
- if (c->channelFlags & CHANNEL_PASSIVE)
- chan_2ghz[a].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-
- band_2ghz->n_channels = ++a;
-
- DPRINTF(sc, ATH_DBG_CONFIG, "2MHz channel: %d, "
- "channelFlags: 0x%x\n",
- c->channel, c->channelFlags);
- } else if (IS_CHAN_5GHZ(c)) {
- chan_5ghz[b].band = IEEE80211_BAND_5GHZ;
- chan_5ghz[b].center_freq = c->channel;
- chan_5ghz[b].max_power = c->maxTxPower;
-
- if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
- chan_5ghz[b].flags |= IEEE80211_CHAN_NO_IBSS;
- if (c->channelFlags & CHANNEL_PASSIVE)
- chan_5ghz[b].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-
- band_5ghz->n_channels = ++b;
-
- DPRINTF(sc, ATH_DBG_CONFIG, "5MHz channel: %d, "
- "channelFlags: 0x%x\n",
- c->channel, c->channelFlags);
- }
- }
-
- return 0;
-}
-
/*
* Set/change channels. If the channel is really being changed, it's done
* by reseting the chip. To accomplish this we must first cleanup any pending
* DMA, then restart stuff.
*/
-static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
+int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
+ struct ath9k_channel *hchan)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
bool fastcc = true, stopped;
+ struct ieee80211_channel *channel = hw->conf.channel;
+ int r;
if (sc->sc_flags & SC_OP_INVALID)
return -EIO;
- if (hchan->channel != sc->sc_ah->ah_curchan->channel ||
- hchan->channelFlags != sc->sc_ah->ah_curchan->channelFlags ||
- (sc->sc_flags & SC_OP_CHAINMASK_UPDATE) ||
- (sc->sc_flags & SC_OP_FULL_RESET)) {
- int status;
- /*
- * This is only performed if the channel settings have
- * actually changed.
- *
- * To switch channels clear any pending DMA operations;
- * wait long enough for the RX fifo to drain, reset the
- * hardware at the new frequency, and then re-enable
- * the relevant bits of the h/w.
- */
- ath9k_hw_set_interrupts(ah, 0);
- ath_draintxq(sc, false);
- stopped = ath_stoprecv(sc);
-
- /* XXX: do not flush receive queue here. We don't want
- * to flush data frames already in queue because of
- * changing channel. */
-
- if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
- fastcc = false;
-
- DPRINTF(sc, ATH_DBG_CONFIG,
- "(%u MHz) -> (%u MHz), cflags:%x, chanwidth: %d\n",
- sc->sc_ah->ah_curchan->channel,
- hchan->channel, hchan->channelFlags, sc->tx_chan_width);
-
- spin_lock_bh(&sc->sc_resetlock);
- if (!ath9k_hw_reset(ah, hchan, sc->tx_chan_width,
- sc->sc_tx_chainmask, sc->sc_rx_chainmask,
- sc->sc_ht_extprotspacing, fastcc, &status)) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to reset channel %u (%uMhz) "
- "flags 0x%x hal status %u\n",
- ath9k_hw_mhz2ieee(ah, hchan->channel,
- hchan->channelFlags),
- hchan->channel, hchan->channelFlags, status);
- spin_unlock_bh(&sc->sc_resetlock);
- return -EIO;
- }
- spin_unlock_bh(&sc->sc_resetlock);
+ ath9k_ps_wakeup(sc);
- sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE;
- sc->sc_flags &= ~SC_OP_FULL_RESET;
+ /*
+ * This is only performed if the channel settings have
+ * actually changed.
+ *
+ * To switch channels clear any pending DMA operations;
+ * wait long enough for the RX fifo to drain, reset the
+ * hardware at the new frequency, and then re-enable
+ * the relevant bits of the h/w.
+ */
+ ath9k_hw_set_interrupts(ah, 0);
+ ath_drain_all_txq(sc, false);
+ stopped = ath_stoprecv(sc);
- if (ath_startrecv(sc) != 0) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to restart recv logic\n");
- return -EIO;
- }
+ /* XXX: do not flush receive queue here. We don't want
+ * to flush data frames already in queue because of
+ * changing channel. */
+
+ if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
+ fastcc = false;
- ath_setcurmode(sc, ath_chan2mode(hchan));
- ath_update_txpow(sc);
- ath9k_hw_set_interrupts(ah, sc->sc_imask);
+ DPRINTF(sc, ATH_DBG_CONFIG,
+ "(%u MHz) -> (%u MHz), chanwidth: %d\n",
+ sc->sc_ah->curchan->channel,
+ channel->center_freq, sc->tx_chan_width);
+
+ spin_lock_bh(&sc->sc_resetlock);
+
+ r = ath9k_hw_reset(ah, hchan, fastcc);
+ if (r) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Unable to reset channel (%u Mhz) "
+ "reset status %u\n",
+ channel->center_freq, r);
+ spin_unlock_bh(&sc->sc_resetlock);
+ return r;
}
+ spin_unlock_bh(&sc->sc_resetlock);
+
+ sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE;
+ sc->sc_flags &= ~SC_OP_FULL_RESET;
+
+ if (ath_startrecv(sc) != 0) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Unable to restart recv logic\n");
+ return -EIO;
+ }
+
+ ath_cache_conf_rate(sc, &hw->conf);
+ ath_update_txpow(sc);
+ ath9k_hw_set_interrupts(ah, sc->imask);
+ ath9k_ps_restore(sc);
return 0;
}
@@ -332,123 +312,122 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
*/
static void ath_ani_calibrate(unsigned long data)
{
- struct ath_softc *sc;
- struct ath_hal *ah;
+ struct ath_softc *sc = (struct ath_softc *)data;
+ struct ath_hw *ah = sc->sc_ah;
bool longcal = false;
bool shortcal = false;
bool aniflag = false;
unsigned int timestamp = jiffies_to_msecs(jiffies);
- u32 cal_interval;
+ u32 cal_interval, short_cal_interval;
- sc = (struct ath_softc *)data;
- ah = sc->sc_ah;
+ short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
+ ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
/*
* don't calibrate when we're scanning.
* we are most likely not on our home channel.
*/
- if (sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC)
- return;
+ if (sc->sc_flags & SC_OP_SCANNING)
+ goto set_timer;
/* Long calibration runs independently of short calibration. */
- if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) {
+ if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
longcal = true;
DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
- sc->sc_ani.sc_longcal_timer = timestamp;
+ sc->ani.longcal_timer = timestamp;
}
- /* Short calibration applies only while sc_caldone is false */
- if (!sc->sc_ani.sc_caldone) {
- if ((timestamp - sc->sc_ani.sc_shortcal_timer) >=
- ATH_SHORT_CALINTERVAL) {
+ /* Short calibration applies only while caldone is false */
+ if (!sc->ani.caldone) {
+ if ((timestamp - sc->ani.shortcal_timer) >= short_cal_interval) {
shortcal = true;
DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies);
- sc->sc_ani.sc_shortcal_timer = timestamp;
- sc->sc_ani.sc_resetcal_timer = timestamp;
+ sc->ani.shortcal_timer = timestamp;
+ sc->ani.resetcal_timer = timestamp;
}
} else {
- if ((timestamp - sc->sc_ani.sc_resetcal_timer) >=
+ if ((timestamp - sc->ani.resetcal_timer) >=
ATH_RESTART_CALINTERVAL) {
- ath9k_hw_reset_calvalid(ah, ah->ah_curchan,
- &sc->sc_ani.sc_caldone);
- if (sc->sc_ani.sc_caldone)
- sc->sc_ani.sc_resetcal_timer = timestamp;
+ sc->ani.caldone = ath9k_hw_reset_calvalid(ah);
+ if (sc->ani.caldone)
+ sc->ani.resetcal_timer = timestamp;
}
}
/* Verify whether we must check ANI */
- if ((timestamp - sc->sc_ani.sc_checkani_timer) >=
- ATH_ANI_POLLINTERVAL) {
+ if ((timestamp - sc->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
aniflag = true;
- sc->sc_ani.sc_checkani_timer = timestamp;
+ sc->ani.checkani_timer = timestamp;
}
/* Skip all processing if there's nothing to do. */
if (longcal || shortcal || aniflag) {
/* Call ANI routine if necessary */
if (aniflag)
- ath9k_hw_ani_monitor(ah, &sc->sc_halstats,
- ah->ah_curchan);
+ ath9k_hw_ani_monitor(ah, &sc->nodestats, ah->curchan);
/* Perform calibration if necessary */
if (longcal || shortcal) {
bool iscaldone = false;
- if (ath9k_hw_calibrate(ah, ah->ah_curchan,
- sc->sc_rx_chainmask, longcal,
+ if (ath9k_hw_calibrate(ah, ah->curchan,
+ sc->rx_chainmask, longcal,
&iscaldone)) {
if (longcal)
- sc->sc_ani.sc_noise_floor =
+ sc->ani.noise_floor =
ath9k_hw_getchan_noise(ah,
- ah->ah_curchan);
+ ah->curchan);
DPRINTF(sc, ATH_DBG_ANI,
"calibrate chan %u/%x nf: %d\n",
- ah->ah_curchan->channel,
- ah->ah_curchan->channelFlags,
- sc->sc_ani.sc_noise_floor);
+ ah->curchan->channel,
+ ah->curchan->channelFlags,
+ sc->ani.noise_floor);
} else {
DPRINTF(sc, ATH_DBG_ANY,
"calibrate chan %u/%x failed\n",
- ah->ah_curchan->channel,
- ah->ah_curchan->channelFlags);
+ ah->curchan->channel,
+ ah->curchan->channelFlags);
}
- sc->sc_ani.sc_caldone = iscaldone;
+ sc->ani.caldone = iscaldone;
}
}
+set_timer:
/*
* Set timer interval based on previous results.
* The interval must be the shortest necessary to satisfy ANI,
* short calibration and long calibration.
*/
cal_interval = ATH_LONG_CALINTERVAL;
- if (sc->sc_ah->ah_config.enable_ani)
+ if (sc->sc_ah->config.enable_ani)
cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
- if (!sc->sc_ani.sc_caldone)
- cal_interval = min(cal_interval, (u32)ATH_SHORT_CALINTERVAL);
+ if (!sc->ani.caldone)
+ cal_interval = min(cal_interval, (u32)short_cal_interval);
- mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(cal_interval));
+ mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
}
/*
* Update tx/rx chainmask. For legacy association,
* hard code chainmask to 1x1, for 11n association, use
- * the chainmask configuration.
+ * the chainmask configuration, for bt coexistence, use
+ * the chainmask configuration even in legacy mode.
*/
-static void ath_update_chainmask(struct ath_softc *sc, int is_ht)
+void ath_update_chainmask(struct ath_softc *sc, int is_ht)
{
sc->sc_flags |= SC_OP_CHAINMASK_UPDATE;
- if (is_ht) {
- sc->sc_tx_chainmask = sc->sc_ah->ah_caps.tx_chainmask;
- sc->sc_rx_chainmask = sc->sc_ah->ah_caps.rx_chainmask;
+ if (is_ht ||
+ (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) {
+ sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
+ sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
} else {
- sc->sc_tx_chainmask = 1;
- sc->sc_rx_chainmask = 1;
+ sc->tx_chainmask = 1;
+ sc->rx_chainmask = 1;
}
DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n",
- sc->sc_tx_chainmask, sc->sc_rx_chainmask);
+ sc->tx_chainmask, sc->rx_chainmask);
}
static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
@@ -476,7 +455,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
static void ath9k_tasklet(unsigned long data)
{
struct ath_softc *sc = (struct ath_softc *)data;
- u32 status = sc->sc_intrstatus;
+ u32 status = sc->intrstatus;
if (status & ATH9K_INT_FATAL) {
/* need a chip reset */
@@ -496,13 +475,13 @@ static void ath9k_tasklet(unsigned long data)
}
/* re-enable hardware interrupt */
- ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask);
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
}
-static irqreturn_t ath_isr(int irq, void *dev)
+irqreturn_t ath_isr(int irq, void *dev)
{
struct ath_softc *sc = dev;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
enum ath9k_int status;
bool sched = false;
@@ -527,7 +506,7 @@ static irqreturn_t ath_isr(int irq, void *dev)
*/
ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
- status &= sc->sc_imask; /* discard unasked-for bits */
+ status &= sc->imask; /* discard unasked-for bits */
/*
* If there are no status bits set, then this interrupt was not
@@ -536,7 +515,8 @@ static irqreturn_t ath_isr(int irq, void *dev)
if (!status)
return IRQ_NONE;
- sc->sc_intrstatus = status;
+ sc->intrstatus = status;
+ ath9k_ps_wakeup(sc);
if (status & ATH9K_INT_FATAL) {
/* need a chip reset */
@@ -583,45 +563,39 @@ static irqreturn_t ath_isr(int irq, void *dev)
* it will clear whatever condition caused
* the interrupt.
*/
- ath9k_hw_procmibevent(ah, &sc->sc_halstats);
- ath9k_hw_set_interrupts(ah, sc->sc_imask);
+ ath9k_hw_procmibevent(ah, &sc->nodestats);
+ ath9k_hw_set_interrupts(ah, sc->imask);
}
if (status & ATH9K_INT_TIM_TIMER) {
- if (!(ah->ah_caps.hw_caps &
+ if (!(ah->caps.hw_caps &
ATH9K_HW_CAP_AUTOSLEEP)) {
/* Clear RxAbort bit so that we can
* receive frames */
+ ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
ath9k_hw_setrxabort(ah, 0);
sched = true;
+ sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
}
}
+ if (status & ATH9K_INT_TSFOOR) {
+ /* FIXME: Handle this interrupt for power save */
+ sched = true;
+ }
}
+ ath9k_ps_restore(sc);
} while (0);
ath_debug_stat_interrupt(sc, status);
if (sched) {
/* turn off every interrupt except SWBA */
- ath9k_hw_set_interrupts(ah, (sc->sc_imask & ATH9K_INT_SWBA));
+ ath9k_hw_set_interrupts(ah, (sc->imask & ATH9K_INT_SWBA));
tasklet_schedule(&sc->intr_tq);
}
return IRQ_HANDLED;
}
-static int ath_get_channel(struct ath_softc *sc,
- struct ieee80211_channel *chan)
-{
- int i;
-
- for (i = 0; i < sc->sc_ah->ah_nchan; i++) {
- if (sc->sc_ah->ah_channels[i].channel == chan->center_freq)
- return i;
- }
-
- return -1;
-}
-
static u32 ath_get_extchanmode(struct ath_softc *sc,
struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type)
@@ -664,20 +638,9 @@ static u32 ath_get_extchanmode(struct ath_softc *sc,
return chanmode;
}
-static int ath_keyset(struct ath_softc *sc, u16 keyix,
- struct ath9k_keyval *hk, const u8 mac[ETH_ALEN])
-{
- bool status;
-
- status = ath9k_hw_set_keycache_entry(sc->sc_ah,
- keyix, hk, mac, false);
-
- return status != false;
-}
-
static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
- struct ath9k_keyval *hk,
- const u8 *addr)
+ struct ath9k_keyval *hk, const u8 *addr,
+ bool authenticator)
{
const u8 *key_rxmic;
const u8 *key_txmic;
@@ -686,26 +649,33 @@ static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
if (addr == NULL) {
- /* Group key installation */
- memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
- return ath_keyset(sc, keyix, hk, addr);
- }
- if (!sc->sc_splitmic) {
/*
- * data key goes at first index,
- * the hal handles the MIC keys at index+64.
+ * Group key installation - only two key cache entries are used
+ * regardless of splitmic capability since group key is only
+ * used either for TX or RX.
*/
+ if (authenticator) {
+ memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
+ memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
+ } else {
+ memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+ memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
+ }
+ return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
+ }
+ if (!sc->splitmic) {
+ /* TX and RX keys share the same key cache entry. */
memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
- return ath_keyset(sc, keyix, hk, addr);
+ return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
}
- /*
- * TX key goes at first index, RX key at +32.
- * The hal handles the MIC keys at index+64.
- */
+
+ /* Separate key cache entries for TX and RX */
+
+ /* TX key goes at first index, RX key at +32. */
memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
- if (!ath_keyset(sc, keyix, hk, NULL)) {
- /* Txmic entry failed. No need to proceed further */
+ if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) {
+ /* TX MIC entry failed. No need to proceed further */
DPRINTF(sc, ATH_DBG_KEYCACHE,
"Setting TX MIC Key Failed\n");
return 0;
@@ -713,20 +683,20 @@ static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
/* XXX delete tx key on failure? */
- return ath_keyset(sc, keyix + 32, hk, addr);
+ return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix + 32, hk, addr);
}
static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc)
{
int i;
- for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) {
- if (test_bit(i, sc->sc_keymap) ||
- test_bit(i + 64, sc->sc_keymap))
+ for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
+ if (test_bit(i, sc->keymap) ||
+ test_bit(i + 64, sc->keymap))
continue; /* At least one part of TKIP key allocated */
- if (sc->sc_splitmic &&
- (test_bit(i + 32, sc->sc_keymap) ||
- test_bit(i + 64 + 32, sc->sc_keymap)))
+ if (sc->splitmic &&
+ (test_bit(i + 32, sc->keymap) ||
+ test_bit(i + 64 + 32, sc->keymap)))
continue; /* At least one part of TKIP key allocated */
/* Found a free slot for a TKIP key */
@@ -740,55 +710,55 @@ static int ath_reserve_key_cache_slot(struct ath_softc *sc)
int i;
/* First, try to find slots that would not be available for TKIP. */
- if (sc->sc_splitmic) {
- for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 4; i++) {
- if (!test_bit(i, sc->sc_keymap) &&
- (test_bit(i + 32, sc->sc_keymap) ||
- test_bit(i + 64, sc->sc_keymap) ||
- test_bit(i + 64 + 32, sc->sc_keymap)))
+ if (sc->splitmic) {
+ for (i = IEEE80211_WEP_NKID; i < sc->keymax / 4; i++) {
+ if (!test_bit(i, sc->keymap) &&
+ (test_bit(i + 32, sc->keymap) ||
+ test_bit(i + 64, sc->keymap) ||
+ test_bit(i + 64 + 32, sc->keymap)))
return i;
- if (!test_bit(i + 32, sc->sc_keymap) &&
- (test_bit(i, sc->sc_keymap) ||
- test_bit(i + 64, sc->sc_keymap) ||
- test_bit(i + 64 + 32, sc->sc_keymap)))
+ if (!test_bit(i + 32, sc->keymap) &&
+ (test_bit(i, sc->keymap) ||
+ test_bit(i + 64, sc->keymap) ||
+ test_bit(i + 64 + 32, sc->keymap)))
return i + 32;
- if (!test_bit(i + 64, sc->sc_keymap) &&
- (test_bit(i , sc->sc_keymap) ||
- test_bit(i + 32, sc->sc_keymap) ||
- test_bit(i + 64 + 32, sc->sc_keymap)))
+ if (!test_bit(i + 64, sc->keymap) &&
+ (test_bit(i , sc->keymap) ||
+ test_bit(i + 32, sc->keymap) ||
+ test_bit(i + 64 + 32, sc->keymap)))
return i + 64;
- if (!test_bit(i + 64 + 32, sc->sc_keymap) &&
- (test_bit(i, sc->sc_keymap) ||
- test_bit(i + 32, sc->sc_keymap) ||
- test_bit(i + 64, sc->sc_keymap)))
+ if (!test_bit(i + 64 + 32, sc->keymap) &&
+ (test_bit(i, sc->keymap) ||
+ test_bit(i + 32, sc->keymap) ||
+ test_bit(i + 64, sc->keymap)))
return i + 64 + 32;
}
} else {
- for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax / 2; i++) {
- if (!test_bit(i, sc->sc_keymap) &&
- test_bit(i + 64, sc->sc_keymap))
+ for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
+ if (!test_bit(i, sc->keymap) &&
+ test_bit(i + 64, sc->keymap))
return i;
- if (test_bit(i, sc->sc_keymap) &&
- !test_bit(i + 64, sc->sc_keymap))
+ if (test_bit(i, sc->keymap) &&
+ !test_bit(i + 64, sc->keymap))
return i + 64;
}
}
/* No partially used TKIP slots, pick any available slot */
- for (i = IEEE80211_WEP_NKID; i < sc->sc_keymax; i++) {
+ for (i = IEEE80211_WEP_NKID; i < sc->keymax; i++) {
/* Do not allow slots that could be needed for TKIP group keys
* to be used. This limitation could be removed if we know that
* TKIP will not be used. */
if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
continue;
- if (sc->sc_splitmic) {
+ if (sc->splitmic) {
if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
continue;
if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
continue;
}
- if (!test_bit(i, sc->sc_keymap))
+ if (!test_bit(i, sc->keymap))
return i; /* Found a free slot for a key */
}
@@ -797,7 +767,8 @@ static int ath_reserve_key_cache_slot(struct ath_softc *sc)
}
static int ath_key_config(struct ath_softc *sc,
- const u8 *addr,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
struct ath9k_keyval hk;
@@ -818,7 +789,7 @@ static int ath_key_config(struct ath_softc *sc,
hk.kv_type = ATH9K_CIPHER_AES_CCM;
break;
default:
- return -EINVAL;
+ return -EOPNOTSUPP;
}
hk.kv_len = key->keylen;
@@ -829,10 +800,10 @@ static int ath_key_config(struct ath_softc *sc,
* need to change with virtual interfaces. */
idx = key->keyidx;
} else if (key->keyidx) {
- struct ieee80211_vif *vif;
+ if (WARN_ON(!sta))
+ return -EOPNOTSUPP;
+ mac = sta->addr;
- mac = addr;
- vif = sc->sc_vaps[0];
if (vif->type != NL80211_IFTYPE_AP) {
/* Only keyidx 0 should be used with unicast key, but
* allow this for client mode for now. */
@@ -840,29 +811,33 @@ static int ath_key_config(struct ath_softc *sc,
} else
return -EIO;
} else {
- mac = addr;
+ if (WARN_ON(!sta))
+ return -EOPNOTSUPP;
+ mac = sta->addr;
+
if (key->alg == ALG_TKIP)
idx = ath_reserve_key_cache_slot_tkip(sc);
else
idx = ath_reserve_key_cache_slot(sc);
if (idx < 0)
- return -EIO; /* no free key cache entries */
+ return -ENOSPC; /* no free key cache entries */
}
if (key->alg == ALG_TKIP)
- ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac);
+ ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac,
+ vif->type == NL80211_IFTYPE_AP);
else
- ret = ath_keyset(sc, idx, &hk, mac);
+ ret = ath9k_hw_set_keycache_entry(sc->sc_ah, idx, &hk, mac);
if (!ret)
return -EIO;
- set_bit(idx, sc->sc_keymap);
+ set_bit(idx, sc->keymap);
if (key->alg == ALG_TKIP) {
- set_bit(idx + 64, sc->sc_keymap);
- if (sc->sc_splitmic) {
- set_bit(idx + 32, sc->sc_keymap);
- set_bit(idx + 64 + 32, sc->sc_keymap);
+ set_bit(idx + 64, sc->keymap);
+ if (sc->splitmic) {
+ set_bit(idx + 32, sc->keymap);
+ set_bit(idx + 64 + 32, sc->keymap);
}
}
@@ -875,18 +850,19 @@ static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
if (key->hw_key_idx < IEEE80211_WEP_NKID)
return;
- clear_bit(key->hw_key_idx, sc->sc_keymap);
+ clear_bit(key->hw_key_idx, sc->keymap);
if (key->alg != ALG_TKIP)
return;
- clear_bit(key->hw_key_idx + 64, sc->sc_keymap);
- if (sc->sc_splitmic) {
- clear_bit(key->hw_key_idx + 32, sc->sc_keymap);
- clear_bit(key->hw_key_idx + 64 + 32, sc->sc_keymap);
+ clear_bit(key->hw_key_idx + 64, sc->keymap);
+ if (sc->splitmic) {
+ clear_bit(key->hw_key_idx + 32, sc->keymap);
+ clear_bit(key->hw_key_idx + 64 + 32, sc->keymap);
}
}
-static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info)
+static void setup_ht_cap(struct ath_softc *sc,
+ struct ieee80211_sta_ht_cap *ht_info)
{
#define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */
#define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */
@@ -899,10 +875,23 @@ static void setup_ht_cap(struct ieee80211_sta_ht_cap *ht_info)
ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
+
/* set up supported mcs set */
memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
- ht_info->mcs.rx_mask[0] = 0xff;
- ht_info->mcs.rx_mask[1] = 0xff;
+
+ switch(sc->rx_chainmask) {
+ case 1:
+ ht_info->mcs.rx_mask[0] = 0xff;
+ break;
+ case 3:
+ case 5:
+ case 7:
+ default:
+ ht_info->mcs.rx_mask[0] = 0xff;
+ ht_info->mcs.rx_mask[1] = 0xff;
+ break;
+ }
+
ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
}
@@ -910,36 +899,33 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf)
{
- struct ath_vap *avp = (void *)vif->drv_priv;
+ struct ath_vif *avp = (void *)vif->drv_priv;
if (bss_conf->assoc) {
DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n",
- bss_conf->aid, sc->sc_curbssid);
+ bss_conf->aid, sc->curbssid);
/* New association, store aid */
if (avp->av_opmode == NL80211_IFTYPE_STATION) {
- sc->sc_curaid = bss_conf->aid;
- ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid,
- sc->sc_curaid);
+ sc->curaid = bss_conf->aid;
+ ath9k_hw_write_associd(sc);
}
/* Configure the beacon */
- ath_beacon_config(sc, 0);
- sc->sc_flags |= SC_OP_BEACONS;
+ ath_beacon_config(sc, vif);
/* Reset rssi stats */
- sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
- sc->sc_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
- sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
- sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
+ sc->nodestats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
+ sc->nodestats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
+ sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
+ sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
/* Start ANI */
- mod_timer(&sc->sc_ani.timer,
- jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
-
+ mod_timer(&sc->ani.timer,
+ jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
} else {
DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISSOC\n");
- sc->sc_curaid = 0;
+ sc->curaid = 0;
}
}
@@ -947,6 +933,39 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
/* LED functions */
/********************************/
+static void ath_led_blink_work(struct work_struct *work)
+{
+ struct ath_softc *sc = container_of(work, struct ath_softc,
+ ath_led_blink_work.work);
+
+ if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
+ return;
+
+ if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
+ (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
+ ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+ else
+ ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+ (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
+
+ queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work,
+ (sc->sc_flags & SC_OP_LED_ON) ?
+ msecs_to_jiffies(sc->led_off_duration) :
+ msecs_to_jiffies(sc->led_on_duration));
+
+ sc->led_on_duration = sc->led_on_cnt ?
+ max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
+ ATH_LED_ON_DURATION_IDLE;
+ sc->led_off_duration = sc->led_off_cnt ?
+ max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
+ ATH_LED_OFF_DURATION_IDLE;
+ sc->led_on_cnt = sc->led_off_cnt = 0;
+ if (sc->sc_flags & SC_OP_LED_ON)
+ sc->sc_flags &= ~SC_OP_LED_ON;
+ else
+ sc->sc_flags |= SC_OP_LED_ON;
+}
+
static void ath_led_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
@@ -956,16 +975,27 @@ static void ath_led_brightness(struct led_classdev *led_cdev,
switch (brightness) {
case LED_OFF:
if (led->led_type == ATH_LED_ASSOC ||
- led->led_type == ATH_LED_RADIO)
+ led->led_type == ATH_LED_RADIO) {
+ ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+ (led->led_type == ATH_LED_RADIO));
sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
- ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
- (led->led_type == ATH_LED_RADIO) ? 1 :
- !!(sc->sc_flags & SC_OP_LED_ASSOCIATED));
+ if (led->led_type == ATH_LED_RADIO)
+ sc->sc_flags &= ~SC_OP_LED_ON;
+ } else {
+ sc->led_off_cnt++;
+ }
break;
case LED_FULL:
- if (led->led_type == ATH_LED_ASSOC)
+ if (led->led_type == ATH_LED_ASSOC) {
sc->sc_flags |= SC_OP_LED_ASSOCIATED;
- ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+ queue_delayed_work(sc->hw->workqueue,
+ &sc->ath_led_blink_work, 0);
+ } else if (led->led_type == ATH_LED_RADIO) {
+ ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+ sc->sc_flags |= SC_OP_LED_ON;
+ } else {
+ sc->led_on_cnt++;
+ }
break;
default:
break;
@@ -1001,6 +1031,7 @@ static void ath_unregister_led(struct ath_led *led)
static void ath_deinit_leds(struct ath_softc *sc)
{
+ cancel_delayed_work_sync(&sc->ath_led_blink_work);
ath_unregister_led(&sc->assoc_led);
sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
ath_unregister_led(&sc->tx_led);
@@ -1020,9 +1051,11 @@ static void ath_init_leds(struct ath_softc *sc)
/* LED off, active low */
ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+ INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
+
trigger = ieee80211_get_radio_led_name(sc->hw);
snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
- "ath9k-%s:radio", wiphy_name(sc->hw->wiphy));
+ "ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->radio_led, trigger);
sc->radio_led.led_type = ATH_LED_RADIO;
if (ret)
@@ -1030,7 +1063,7 @@ static void ath_init_leds(struct ath_softc *sc)
trigger = ieee80211_get_assoc_led_name(sc->hw);
snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
- "ath9k-%s:assoc", wiphy_name(sc->hw->wiphy));
+ "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->assoc_led, trigger);
sc->assoc_led.led_type = ATH_LED_ASSOC;
if (ret)
@@ -1038,7 +1071,7 @@ static void ath_init_leds(struct ath_softc *sc)
trigger = ieee80211_get_tx_led_name(sc->hw);
snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
- "ath9k-%s:tx", wiphy_name(sc->hw->wiphy));
+ "ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->tx_led, trigger);
sc->tx_led.led_type = ATH_LED_TX;
if (ret)
@@ -1046,7 +1079,7 @@ static void ath_init_leds(struct ath_softc *sc)
trigger = ieee80211_get_rx_led_name(sc->hw);
snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
- "ath9k-%s:rx", wiphy_name(sc->hw->wiphy));
+ "ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->rx_led, trigger);
sc->rx_led.led_type = ATH_LED_RX;
if (ret)
@@ -1058,32 +1091,22 @@ fail:
ath_deinit_leds(sc);
}
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-
-/*******************/
-/* Rfkill */
-/*******************/
-
-static void ath_radio_enable(struct ath_softc *sc)
+void ath_radio_enable(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
- int status;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ieee80211_channel *channel = sc->hw->conf.channel;
+ int r;
+ ath9k_ps_wakeup(sc);
spin_lock_bh(&sc->sc_resetlock);
- if (!ath9k_hw_reset(ah, ah->ah_curchan,
- sc->tx_chan_width,
- sc->sc_tx_chainmask,
- sc->sc_rx_chainmask,
- sc->sc_ht_extprotspacing,
- false, &status)) {
+
+ r = ath9k_hw_reset(ah, ah->curchan, false);
+
+ if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to reset channel %u (%uMhz) "
- "flags 0x%x hal status %u\n",
- ath9k_hw_mhz2ieee(ah,
- ah->ah_curchan->channel,
- ah->ah_curchan->channelFlags),
- ah->ah_curchan->channel,
- ah->ah_curchan->channelFlags, status);
+ "Unable to reset channel %u (%uMhz) ",
+ "reset status %u\n",
+ channel->center_freq, r);
}
spin_unlock_bh(&sc->sc_resetlock);
@@ -1095,10 +1118,10 @@ static void ath_radio_enable(struct ath_softc *sc)
}
if (sc->sc_flags & SC_OP_BEACONS)
- ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */
+ ath_beacon_config(sc, NULL); /* restart beacons */
/* Re-Enable interrupts */
- ath9k_hw_set_interrupts(ah, sc->sc_imask);
+ ath9k_hw_set_interrupts(ah, sc->imask);
/* Enable LED */
ath9k_hw_cfg_output(ah, ATH_LED_PIN,
@@ -1106,14 +1129,16 @@ static void ath_radio_enable(struct ath_softc *sc)
ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0);
ieee80211_wake_queues(sc->hw);
+ ath9k_ps_restore(sc);
}
-static void ath_radio_disable(struct ath_softc *sc)
+void ath_radio_disable(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
- int status;
-
+ struct ath_hw *ah = sc->sc_ah;
+ struct ieee80211_channel *channel = sc->hw->conf.channel;
+ int r;
+ ath9k_ps_wakeup(sc);
ieee80211_stop_queues(sc->hw);
/* Disable LED */
@@ -1123,38 +1148,37 @@ static void ath_radio_disable(struct ath_softc *sc)
/* Disable interrupts */
ath9k_hw_set_interrupts(ah, 0);
- ath_draintxq(sc, false); /* clear pending tx frames */
+ ath_drain_all_txq(sc, false); /* clear pending tx frames */
ath_stoprecv(sc); /* turn off frame recv */
ath_flushrecv(sc); /* flush recv queue */
spin_lock_bh(&sc->sc_resetlock);
- if (!ath9k_hw_reset(ah, ah->ah_curchan,
- sc->tx_chan_width,
- sc->sc_tx_chainmask,
- sc->sc_rx_chainmask,
- sc->sc_ht_extprotspacing,
- false, &status)) {
+ r = ath9k_hw_reset(ah, ah->curchan, false);
+ if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to reset channel %u (%uMhz) "
- "flags 0x%x hal status %u\n",
- ath9k_hw_mhz2ieee(ah,
- ah->ah_curchan->channel,
- ah->ah_curchan->channelFlags),
- ah->ah_curchan->channel,
- ah->ah_curchan->channelFlags, status);
+ "reset status %u\n",
+ channel->center_freq, r);
}
spin_unlock_bh(&sc->sc_resetlock);
ath9k_hw_phy_disable(ah);
ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+ ath9k_ps_restore(sc);
}
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+
+/*******************/
+/* Rfkill */
+/*******************/
+
static bool ath_is_rfkill_set(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
- return ath9k_hw_gpio_get(ah, ah->ah_rfkill_gpio) ==
- ah->ah_rfkill_polarity;
+ return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
+ ah->rfkill_polarity;
}
/* h/w rfkill poll function */
@@ -1238,7 +1262,7 @@ static int ath_init_sw_rfkill(struct ath_softc *sc)
}
snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
- "ath9k-%s:rfkill", wiphy_name(sc->hw->wiphy));
+ "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy));
sc->rf_kill.rfkill->name = sc->rf_kill.rfkill_name;
sc->rf_kill.rfkill->data = sc;
sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio;
@@ -1251,7 +1275,7 @@ static int ath_init_sw_rfkill(struct ath_softc *sc)
/* Deinitialize rfkill */
static void ath_deinit_rfkill(struct ath_softc *sc)
{
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) {
@@ -1263,7 +1287,7 @@ static void ath_deinit_rfkill(struct ath_softc *sc)
static int ath_start_rfkill_poll(struct ath_softc *sc)
{
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
queue_delayed_work(sc->hw->workqueue,
&sc->rf_kill.rfkill_poll, 0);
@@ -1274,13 +1298,7 @@ static int ath_start_rfkill_poll(struct ath_softc *sc)
rfkill_free(sc->rf_kill.rfkill);
/* Deinitialize the device */
- ath_detach(sc);
- if (sc->pdev->irq)
- free_irq(sc->pdev->irq, sc);
- pci_iounmap(sc->pdev, sc->mem);
- pci_release_region(sc->pdev, 0);
- pci_disable_device(sc->pdev);
- ieee80211_free_hw(sc->hw);
+ ath_cleanup(sc);
return -EIO;
} else {
sc->sc_flags |= SC_OP_RFKILL_REGISTERED;
@@ -1291,18 +1309,39 @@ static int ath_start_rfkill_poll(struct ath_softc *sc)
}
#endif /* CONFIG_RFKILL */
-static void ath_detach(struct ath_softc *sc)
+void ath_cleanup(struct ath_softc *sc)
+{
+ ath_detach(sc);
+ free_irq(sc->irq, sc);
+ ath_bus_cleanup(sc);
+ kfree(sc->sec_wiphy);
+ ieee80211_free_hw(sc->hw);
+}
+
+void ath_detach(struct ath_softc *sc)
{
struct ieee80211_hw *hw = sc->hw;
int i = 0;
+ ath9k_ps_wakeup(sc);
+
DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n");
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
ath_deinit_rfkill(sc);
#endif
ath_deinit_leds(sc);
+ cancel_work_sync(&sc->chan_work);
+ cancel_delayed_work_sync(&sc->wiphy_work);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ struct ath_wiphy *aphy = sc->sec_wiphy[i];
+ if (aphy == NULL)
+ continue;
+ sc->sec_wiphy[i] = NULL;
+ ieee80211_unregister_hw(aphy->hw);
+ ieee80211_free_hw(aphy->hw);
+ }
ieee80211_unregister_hw(hw);
ath_rx_cleanup(sc);
ath_tx_cleanup(sc);
@@ -1320,11 +1359,12 @@ static void ath_detach(struct ath_softc *sc)
ath9k_hw_detach(sc->sc_ah);
ath9k_exit_debug(sc);
+ ath9k_ps_restore(sc);
}
static int ath_init(u16 devid, struct ath_softc *sc)
{
- struct ath_hal *ah = NULL;
+ struct ath_hw *ah = NULL;
int status;
int error = 0, i;
int csz = 0;
@@ -1335,54 +1375,52 @@ static int ath_init(u16 devid, struct ath_softc *sc)
if (ath9k_init_debug(sc) < 0)
printk(KERN_ERR "Unable to create debugfs files\n");
+ spin_lock_init(&sc->wiphy_lock);
spin_lock_init(&sc->sc_resetlock);
+ spin_lock_init(&sc->sc_serial_rw);
mutex_init(&sc->mutex);
tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
- tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
+ tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
(unsigned long)sc);
/*
* Cache line size is used to size and align various
* structures used to communicate with the hardware.
*/
- bus_read_cachesize(sc, &csz);
+ ath_read_cachesize(sc, &csz);
/* XXX assert csz is non-zero */
- sc->sc_cachelsz = csz << 2; /* convert to bytes */
+ sc->cachelsz = csz << 2; /* convert to bytes */
- ah = ath9k_hw_attach(devid, sc, sc->mem, &status);
+ ah = ath9k_hw_attach(devid, sc, &status);
if (ah == NULL) {
DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to attach hardware; HAL status %u\n", status);
+ "Unable to attach hardware; HAL status %d\n", status);
error = -ENXIO;
goto bad;
}
sc->sc_ah = ah;
/* Get the hardware key cache size. */
- sc->sc_keymax = ah->ah_caps.keycache_size;
- if (sc->sc_keymax > ATH_KEYMAX) {
+ sc->keymax = ah->caps.keycache_size;
+ if (sc->keymax > ATH_KEYMAX) {
DPRINTF(sc, ATH_DBG_KEYCACHE,
"Warning, using only %u entries in %u key cache\n",
- ATH_KEYMAX, sc->sc_keymax);
- sc->sc_keymax = ATH_KEYMAX;
+ ATH_KEYMAX, sc->keymax);
+ sc->keymax = ATH_KEYMAX;
}
/*
* Reset the key cache since some parts do not
* reset the contents on initial power up.
*/
- for (i = 0; i < sc->sc_keymax; i++)
+ for (i = 0; i < sc->keymax; i++)
ath9k_hw_keyreset(ah, (u16) i);
- /* Collect the channel list using the default country code */
-
- error = ath_setup_channels(sc);
- if (error)
+ if (ath9k_regd_init(sc->sc_ah))
goto bad;
/* default to MONITOR mode */
- sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR;
-
+ sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
/* Setup rate tables */
@@ -1411,7 +1449,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
goto bad2;
}
- sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME;
+ sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
ath_cabq_update(sc);
for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
@@ -1448,8 +1486,8 @@ static int ath_init(u16 devid, struct ath_softc *sc)
/* Initializes the noise floor to a reasonable default value.
* Later on this will be updated during ANI processing. */
- sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR;
- setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc);
+ sc->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
+ setup_timer(&sc->ani.timer, ath_ani_calibrate, (unsigned long)sc);
if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
ATH9K_CIPHER_TKIP, NULL)) {
@@ -1475,60 +1513,62 @@ static int ath_init(u16 devid, struct ath_softc *sc)
ATH9K_CIPHER_MIC, NULL)
&& ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT,
0, NULL))
- sc->sc_splitmic = 1;
+ sc->splitmic = 1;
/* turn on mcast key search if possible */
if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
(void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1,
1, NULL);
- sc->sc_config.txpowlimit = ATH_TXPOWER_MAX;
- sc->sc_config.txpowlimit_override = 0;
+ sc->config.txpowlimit = ATH_TXPOWER_MAX;
/* 11n Capabilities */
- if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
sc->sc_flags |= SC_OP_TXAGGR;
sc->sc_flags |= SC_OP_RXAGGR;
}
- sc->sc_tx_chainmask = ah->ah_caps.tx_chainmask;
- sc->sc_rx_chainmask = ah->ah_caps.rx_chainmask;
+ sc->tx_chainmask = ah->caps.tx_chainmask;
+ sc->rx_chainmask = ah->caps.rx_chainmask;
ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
sc->rx.defant = ath9k_hw_getdefantenna(ah);
- ath9k_hw_getmac(ah, sc->sc_myaddr);
- if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) {
- ath9k_hw_getbssidmask(ah, sc->sc_bssidmask);
- ATH_SET_VAP_BSSID_MASK(sc->sc_bssidmask);
- ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
- }
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+ memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */
/* initialize beacon slots */
- for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
- sc->beacon.bslot[i] = ATH_IF_ID_ANY;
+ for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+ sc->beacon.bslot[i] = NULL;
+ sc->beacon.bslot_aphy[i] = NULL;
+ }
/* save MISC configurations */
- sc->sc_config.swBeaconProcess = 1;
+ sc->config.swBeaconProcess = 1;
/* setup channels and rates */
- sc->sbands[IEEE80211_BAND_2GHZ].channels =
- sc->channels[IEEE80211_BAND_2GHZ];
+ sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
sc->rates[IEEE80211_BAND_2GHZ];
sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
+ sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
+ ARRAY_SIZE(ath9k_2ghz_chantable);
- if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) {
- sc->sbands[IEEE80211_BAND_5GHZ].channels =
- sc->channels[IEEE80211_BAND_5GHZ];
+ if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
+ sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
sc->rates[IEEE80211_BAND_5GHZ];
sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
+ sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
+ ARRAY_SIZE(ath9k_5ghz_chantable);
}
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)
+ ath9k_hw_btcoex_enable(sc->sc_ah);
+
return 0;
bad2:
/* cleanup tx queues */
@@ -1543,49 +1583,68 @@ bad:
return error;
}
-static int ath_attach(u16 devid, struct ath_softc *sc)
+void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
{
- struct ieee80211_hw *hw = sc->hw;
- int error = 0, i;
-
- DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
-
- error = ath_init(devid, sc);
- if (error != 0)
- return error;
-
- /* get mac address from hardware and set in mac80211 */
-
- SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr);
-
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
IEEE80211_HW_SIGNAL_DBM |
- IEEE80211_HW_AMPDU_AGGREGATION;
+ IEEE80211_HW_AMPDU_AGGREGATION |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK |
+ IEEE80211_HW_SPECTRUM_MGMT;
+
+ if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
+ hw->flags |= IEEE80211_HW_MFP_CAPABLE;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC);
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_MESH_POINT);
+
+ hw->wiphy->reg_notifier = ath9k_reg_notifier;
+ hw->wiphy->strict_regulatory = true;
hw->queues = 4;
hw->max_rates = 4;
+ hw->channel_change_time = 5000;
+ hw->max_listen_interval = 10;
hw->max_rate_tries = ATH_11N_TXMAXTRY;
hw->sta_data_size = sizeof(struct ath_node);
- hw->vif_data_size = sizeof(struct ath_vap);
+ hw->vif_data_size = sizeof(struct ath_vif);
hw->rate_control_algorithm = "ath9k_rate_control";
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
- setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
- if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes))
- setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
- }
-
- hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &sc->sbands[IEEE80211_BAND_2GHZ];
- if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes))
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+ &sc->sbands[IEEE80211_BAND_2GHZ];
+ if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&sc->sbands[IEEE80211_BAND_5GHZ];
+}
+
+int ath_attach(u16 devid, struct ath_softc *sc)
+{
+ struct ieee80211_hw *hw = sc->hw;
+ const struct ieee80211_regdomain *regd;
+ int error = 0, i;
+
+ DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
+
+ error = ath_init(devid, sc);
+ if (error != 0)
+ return error;
+
+ /* get mac address from hardware and set in mac80211 */
+
+ SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr);
+
+ ath_set_hw_capab(sc, hw);
+
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
+ setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
+ if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
+ setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
+ }
/* initialize tx/rx engine */
error = ath_tx_init(sc, ATH_TXBUF);
@@ -1598,7 +1657,7 @@ static int ath_attach(u16 devid, struct ath_softc *sc)
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
/* Initialze h/w Rfkill */
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll);
/* Initialize s/w rfkill */
@@ -1607,11 +1666,39 @@ static int ath_attach(u16 devid, struct ath_softc *sc)
goto error_attach;
#endif
+ if (ath9k_is_world_regd(sc->sc_ah)) {
+ /* Anything applied here (prior to wiphy registration) gets
+ * saved on the wiphy orig_* parameters */
+ regd = ath9k_world_regdomain(sc->sc_ah);
+ hw->wiphy->custom_regulatory = true;
+ hw->wiphy->strict_regulatory = false;
+ } else {
+ /* This gets applied in the case of the absense of CRDA,
+ * it's our own custom world regulatory domain, similar to
+ * cfg80211's but we enable passive scanning */
+ regd = ath9k_default_world_regdomain();
+ }
+ wiphy_apply_custom_regulatory(hw->wiphy, regd);
+ ath9k_reg_apply_radar_flags(hw->wiphy);
+ ath9k_reg_apply_world_flags(hw->wiphy, NL80211_REGDOM_SET_BY_DRIVER);
+
+ INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
+ INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
+ sc->wiphy_scheduler_int = msecs_to_jiffies(500);
+
error = ieee80211_register_hw(hw);
+ if (!ath9k_is_world_regd(sc->sc_ah)) {
+ error = regulatory_hint(hw->wiphy,
+ sc->sc_ah->regulatory.alpha2);
+ if (error)
+ goto error_attach;
+ }
+
/* Initialize LED control */
ath_init_leds(sc);
+
return 0;
error_attach:
@@ -1628,24 +1715,20 @@ error_attach:
int ath_reset(struct ath_softc *sc, bool retry_tx)
{
- struct ath_hal *ah = sc->sc_ah;
- int status;
- int error = 0;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ieee80211_hw *hw = sc->hw;
+ int r;
ath9k_hw_set_interrupts(ah, 0);
- ath_draintxq(sc, retry_tx);
+ ath_drain_all_txq(sc, retry_tx);
ath_stoprecv(sc);
ath_flushrecv(sc);
spin_lock_bh(&sc->sc_resetlock);
- if (!ath9k_hw_reset(ah, sc->sc_ah->ah_curchan,
- sc->tx_chan_width,
- sc->sc_tx_chainmask, sc->sc_rx_chainmask,
- sc->sc_ht_extprotspacing, false, &status)) {
+ r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
+ if (r)
DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to reset hardware; hal status %u\n", status);
- error = -EIO;
- }
+ "Unable to reset hardware; reset status %u\n", r);
spin_unlock_bh(&sc->sc_resetlock);
if (ath_startrecv(sc) != 0)
@@ -1656,14 +1739,14 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
* that changes the channel so update any state that
* might change as a result.
*/
- ath_setcurmode(sc, ath_chan2mode(sc->sc_ah->ah_curchan));
+ ath_cache_conf_rate(sc, &hw->conf);
ath_update_txpow(sc);
if (sc->sc_flags & SC_OP_BEACONS)
- ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */
+ ath_beacon_config(sc, NULL); /* restart beacons */
- ath9k_hw_set_interrupts(ah, sc->sc_imask);
+ ath9k_hw_set_interrupts(ah, sc->imask);
if (retry_tx) {
int i;
@@ -1676,7 +1759,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
}
}
- return error;
+ return r;
}
/*
@@ -1700,6 +1783,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
name, nbuf, ndesc);
+ INIT_LIST_HEAD(head);
/* ath_desc must be a multiple of DWORDs */
if ((sizeof(struct ath_desc) % 4) != 0) {
DPRINTF(sc, ATH_DBG_FATAL, "ath_desc not DWORD aligned\n");
@@ -1716,7 +1800,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
* descriptors that cross the 4K page boundary. Assume
* one skipped descriptor per 4K page.
*/
- if (!(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
+ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
u32 ndesc_skipped =
ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
u32 dma_len;
@@ -1730,9 +1814,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
}
/* allocate descriptors */
- dd->dd_desc = pci_alloc_consistent(sc->pdev,
- dd->dd_desc_len,
- &dd->dd_desc_paddr);
+ dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
+ &dd->dd_desc_paddr, GFP_KERNEL);
if (dd->dd_desc == NULL) {
error = -ENOMEM;
goto fail;
@@ -1744,20 +1827,18 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
/* allocate buffers */
bsize = sizeof(struct ath_buf) * nbuf;
- bf = kmalloc(bsize, GFP_KERNEL);
+ bf = kzalloc(bsize, GFP_KERNEL);
if (bf == NULL) {
error = -ENOMEM;
goto fail2;
}
- memset(bf, 0, bsize);
dd->dd_bufptr = bf;
- INIT_LIST_HEAD(head);
for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
bf->bf_desc = ds;
bf->bf_daddr = DS2PHYS(dd, ds);
- if (!(sc->sc_ah->ah_caps.hw_caps &
+ if (!(sc->sc_ah->caps.hw_caps &
ATH9K_HW_CAP_4KB_SPLITTRANS)) {
/*
* Skip descriptor addresses which can cause 4KB
@@ -1778,8 +1859,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
}
return 0;
fail2:
- pci_free_consistent(sc->pdev,
- dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr);
+ dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+ dd->dd_desc_paddr);
fail:
memset(dd, 0, sizeof(*dd));
return error;
@@ -1792,8 +1873,8 @@ void ath_descdma_cleanup(struct ath_softc *sc,
struct ath_descdma *dd,
struct list_head *head)
{
- pci_free_consistent(sc->pdev,
- dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr);
+ dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+ dd->dd_desc_paddr);
INIT_LIST_HEAD(head);
kfree(dd->dd_bufptr);
@@ -1850,33 +1931,81 @@ int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
return qnum;
}
+/* XXX: Remove me once we don't depend on ath9k_channel for all
+ * this redundant data */
+void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
+ struct ath9k_channel *ichan)
+{
+ struct ieee80211_channel *chan = hw->conf.channel;
+ struct ieee80211_conf *conf = &hw->conf;
+
+ ichan->channel = chan->center_freq;
+ ichan->chan = chan;
+
+ if (chan->band == IEEE80211_BAND_2GHZ) {
+ ichan->chanmode = CHANNEL_G;
+ ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
+ } else {
+ ichan->chanmode = CHANNEL_A;
+ ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
+ }
+
+ sc->tx_chan_width = ATH9K_HT_MACMODE_20;
+
+ if (conf_is_ht(conf)) {
+ if (conf_is_ht40(conf))
+ sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
+
+ ichan->chanmode = ath_get_extchanmode(sc, chan,
+ conf->channel_type);
+ }
+}
+
/**********************/
/* mac80211 callbacks */
/**********************/
static int ath9k_start(struct ieee80211_hw *hw)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
struct ieee80211_channel *curchan = hw->conf.channel;
struct ath9k_channel *init_channel;
- int error = 0, pos, status;
+ int r, pos;
DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with "
"initial channel: %d MHz\n", curchan->center_freq);
- /* setup initial channel */
+ mutex_lock(&sc->mutex);
- pos = ath_get_channel(sc, curchan);
- if (pos == -1) {
- DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq);
- error = -EINVAL;
- goto error;
+ if (ath9k_wiphy_started(sc)) {
+ if (sc->chan_idx == curchan->hw_value) {
+ /*
+ * Already on the operational channel, the new wiphy
+ * can be marked active.
+ */
+ aphy->state = ATH_WIPHY_ACTIVE;
+ ieee80211_wake_queues(hw);
+ } else {
+ /*
+ * Another wiphy is on another channel, start the new
+ * wiphy in paused state.
+ */
+ aphy->state = ATH_WIPHY_PAUSED;
+ ieee80211_stop_queues(hw);
+ }
+ mutex_unlock(&sc->mutex);
+ return 0;
}
+ aphy->state = ATH_WIPHY_ACTIVE;
- sc->tx_chan_width = ATH9K_HT_MACMODE_20;
- sc->sc_ah->ah_channels[pos].chanmode =
- (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A;
- init_channel = &sc->sc_ah->ah_channels[pos];
+ /* setup initial channel */
+
+ pos = curchan->hw_value;
+
+ sc->chan_idx = pos;
+ init_channel = &sc->sc_ah->channels[pos];
+ ath9k_update_ichannel(sc, hw, init_channel);
/* Reset SERDES registers */
ath9k_hw_configpcipowersave(sc->sc_ah, 0);
@@ -1889,17 +2018,14 @@ static int ath9k_start(struct ieee80211_hw *hw)
* and then setup of the interrupt mask.
*/
spin_lock_bh(&sc->sc_resetlock);
- if (!ath9k_hw_reset(sc->sc_ah, init_channel,
- sc->tx_chan_width,
- sc->sc_tx_chainmask, sc->sc_rx_chainmask,
- sc->sc_ht_extprotspacing, false, &status)) {
+ r = ath9k_hw_reset(sc->sc_ah, init_channel, false);
+ if (r) {
DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to reset hardware; hal status %u "
- "(freq %u flags 0x%x)\n", status,
- init_channel->channel, init_channel->channelFlags);
- error = -EIO;
+ "Unable to reset hardware; reset status %u "
+ "(freq %u MHz)\n", r,
+ curchan->center_freq);
spin_unlock_bh(&sc->sc_resetlock);
- goto error;
+ goto mutex_unlock;
}
spin_unlock_bh(&sc->sc_resetlock);
@@ -1919,66 +2045,56 @@ static int ath9k_start(struct ieee80211_hw *hw)
if (ath_startrecv(sc) != 0) {
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to start recv logic\n");
- error = -EIO;
- goto error;
+ r = -EIO;
+ goto mutex_unlock;
}
/* Setup our intr mask. */
- sc->sc_imask = ATH9K_INT_RX | ATH9K_INT_TX
+ sc->imask = ATH9K_INT_RX | ATH9K_INT_TX
| ATH9K_INT_RXEOL | ATH9K_INT_RXORN
| ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_GTT)
- sc->sc_imask |= ATH9K_INT_GTT;
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
+ sc->imask |= ATH9K_INT_GTT;
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
- sc->sc_imask |= ATH9K_INT_CST;
-
- /*
- * Enable MIB interrupts when there are hardware phy counters.
- * Note we only do this (at the moment) for station mode.
- */
- if (ath9k_hw_phycounters(sc->sc_ah) &&
- ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) ||
- (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)))
- sc->sc_imask |= ATH9K_INT_MIB;
- /*
- * Some hardware processes the TIM IE and fires an
- * interrupt when the TIM bit is set. For hardware
- * that does, if not overridden by configuration,
- * enable the TIM interrupt when operating as station.
- */
- if ((sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
- (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) &&
- !sc->sc_config.swBeaconProcess)
- sc->sc_imask |= ATH9K_INT_TIM;
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
+ sc->imask |= ATH9K_INT_CST;
- ath_setcurmode(sc, ath_chan2mode(init_channel));
+ ath_cache_conf_rate(sc, &hw->conf);
sc->sc_flags &= ~SC_OP_INVALID;
/* Disable BMISS interrupt when we're not associated */
- sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
- ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask);
+ sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
- ieee80211_wake_queues(sc->hw);
+ ieee80211_wake_queues(hw);
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- error = ath_start_rfkill_poll(sc);
+ r = ath_start_rfkill_poll(sc);
#endif
-error:
- return error;
+mutex_unlock:
+ mutex_unlock(&sc->mutex);
+
+ return r;
}
static int ath9k_tx(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
struct ath_tx_control txctl;
int hdrlen, padsize;
+ if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
+ printk(KERN_DEBUG "ath9k: %s: TX in unexpected wiphy state "
+ "%d\n", wiphy_name(hw->wiphy), aphy->state);
+ goto exit;
+ }
+
memset(&txctl, 0, sizeof(struct ath_tx_control));
/*
@@ -2012,7 +2128,7 @@ static int ath9k_tx(struct ieee80211_hw *hw,
DPRINTF(sc, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
- if (ath_tx_start(sc, skb, &txctl) != 0) {
+ if (ath_tx_start(hw, skb, &txctl) != 0) {
DPRINTF(sc, ATH_DBG_XMIT, "TX failed\n");
goto exit;
}
@@ -2025,30 +2141,38 @@ exit:
static void ath9k_stop(struct ieee80211_hw *hw)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ aphy->state = ATH_WIPHY_INACTIVE;
if (sc->sc_flags & SC_OP_INVALID) {
DPRINTF(sc, ATH_DBG_ANY, "Device not present\n");
return;
}
- DPRINTF(sc, ATH_DBG_CONFIG, "Cleaning up\n");
+ mutex_lock(&sc->mutex);
- ieee80211_stop_queues(sc->hw);
+ ieee80211_stop_queues(hw);
+
+ if (ath9k_wiphy_started(sc)) {
+ mutex_unlock(&sc->mutex);
+ return; /* another wiphy still in use */
+ }
/* make sure h/w will not generate any interrupt
* before setting the invalid flag. */
ath9k_hw_set_interrupts(sc->sc_ah, 0);
if (!(sc->sc_flags & SC_OP_INVALID)) {
- ath_draintxq(sc, false);
+ ath_drain_all_txq(sc, false);
ath_stoprecv(sc);
ath9k_hw_phy_disable(sc->sc_ah);
} else
sc->rx.rxlink = NULL;
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
#endif
/* disable HAL and put h/w to sleep */
@@ -2057,136 +2181,224 @@ static void ath9k_stop(struct ieee80211_hw *hw)
sc->sc_flags |= SC_OP_INVALID;
+ mutex_unlock(&sc->mutex);
+
DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n");
}
static int ath9k_add_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf)
{
- struct ath_softc *sc = hw->priv;
- struct ath_vap *avp = (void *)conf->vif->drv_priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_vif *avp = (void *)conf->vif->drv_priv;
enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
+ int ret = 0;
- /* Support only vap for now */
+ mutex_lock(&sc->mutex);
- if (sc->sc_nvaps)
- return -ENOBUFS;
+ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) &&
+ sc->nvifs > 0) {
+ ret = -ENOBUFS;
+ goto out;
+ }
switch (conf->type) {
case NL80211_IFTYPE_STATION:
ic_opmode = NL80211_IFTYPE_STATION;
break;
case NL80211_IFTYPE_ADHOC:
- ic_opmode = NL80211_IFTYPE_ADHOC;
- break;
case NL80211_IFTYPE_AP:
- ic_opmode = NL80211_IFTYPE_AP;
+ case NL80211_IFTYPE_MESH_POINT:
+ if (sc->nbcnvifs >= ATH_BCBUF) {
+ ret = -ENOBUFS;
+ goto out;
+ }
+ ic_opmode = conf->type;
break;
default:
DPRINTF(sc, ATH_DBG_FATAL,
"Interface type %d not yet supported\n", conf->type);
- return -EOPNOTSUPP;
+ ret = -EOPNOTSUPP;
+ goto out;
}
- DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VAP of type: %d\n", ic_opmode);
+ DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", ic_opmode);
- /* Set the VAP opmode */
+ /* Set the VIF opmode */
avp->av_opmode = ic_opmode;
avp->av_bslot = -1;
- if (ic_opmode == NL80211_IFTYPE_AP)
- ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
+ sc->nvifs++;
+
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+ ath9k_set_bssid_mask(hw);
- sc->sc_vaps[0] = conf->vif;
- sc->sc_nvaps++;
+ if (sc->nvifs > 1)
+ goto out; /* skip global settings for secondary vif */
+
+ if (ic_opmode == NL80211_IFTYPE_AP) {
+ ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
+ sc->sc_flags |= SC_OP_TSF_RESET;
+ }
/* Set the device opmode */
- sc->sc_ah->ah_opmode = ic_opmode;
+ sc->sc_ah->opmode = ic_opmode;
+
+ /*
+ * Enable MIB interrupts when there are hardware phy counters.
+ * Note we only do this (at the moment) for station mode.
+ */
+ if ((conf->type == NL80211_IFTYPE_STATION) ||
+ (conf->type == NL80211_IFTYPE_ADHOC) ||
+ (conf->type == NL80211_IFTYPE_MESH_POINT)) {
+ if (ath9k_hw_phycounters(sc->sc_ah))
+ sc->imask |= ATH9K_INT_MIB;
+ sc->imask |= ATH9K_INT_TSFOOR;
+ }
+
+ /*
+ * Some hardware processes the TIM IE and fires an
+ * interrupt when the TIM bit is set. For hardware
+ * that does, if not overridden by configuration,
+ * enable the TIM interrupt when operating as station.
+ */
+ if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
+ (conf->type == NL80211_IFTYPE_STATION) &&
+ !sc->config.swBeaconProcess)
+ sc->imask |= ATH9K_INT_TIM;
+
+ ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
if (conf->type == NL80211_IFTYPE_AP) {
/* TODO: is this a suitable place to start ANI for AP mode? */
/* Start ANI */
- mod_timer(&sc->sc_ani.timer,
+ mod_timer(&sc->ani.timer,
jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
}
- return 0;
+out:
+ mutex_unlock(&sc->mutex);
+ return ret;
}
static void ath9k_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf)
{
- struct ath_softc *sc = hw->priv;
- struct ath_vap *avp = (void *)conf->vif->drv_priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_vif *avp = (void *)conf->vif->drv_priv;
+ int i;
DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n");
+ mutex_lock(&sc->mutex);
+
/* Stop ANI */
- del_timer_sync(&sc->sc_ani.timer);
+ del_timer_sync(&sc->ani.timer);
/* Reclaim beacon resources */
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP ||
- sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) {
+ if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
+ (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
+ (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
ath_beacon_return(sc, avp);
}
sc->sc_flags &= ~SC_OP_BEACONS;
- sc->sc_vaps[0] = NULL;
- sc->sc_nvaps--;
+ for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+ if (sc->beacon.bslot[i] == conf->vif) {
+ printk(KERN_DEBUG "%s: vif had allocated beacon "
+ "slot\n", __func__);
+ sc->beacon.bslot[i] = NULL;
+ sc->beacon.bslot_aphy[i] = NULL;
+ }
+ }
+
+ sc->nvifs--;
+
+ mutex_unlock(&sc->mutex);
}
static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
struct ieee80211_conf *conf = &hw->conf;
mutex_lock(&sc->mutex);
- if (changed & (IEEE80211_CONF_CHANGE_CHANNEL |
- IEEE80211_CONF_CHANGE_HT)) {
- struct ieee80211_channel *curchan = hw->conf.channel;
- int pos;
-
- DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
- curchan->center_freq);
- pos = ath_get_channel(sc, curchan);
- if (pos == -1) {
- DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n",
- curchan->center_freq);
- mutex_unlock(&sc->mutex);
- return -EINVAL;
+ if (changed & IEEE80211_CONF_CHANGE_PS) {
+ if (conf->flags & IEEE80211_CONF_PS) {
+ if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
+ sc->imask |= ATH9K_INT_TIM_TIMER;
+ ath9k_hw_set_interrupts(sc->sc_ah,
+ sc->imask);
+ }
+ ath9k_hw_setrxabort(sc->sc_ah, 1);
+ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+ } else {
+ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+ ath9k_hw_setrxabort(sc->sc_ah, 0);
+ sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
+ if (sc->imask & ATH9K_INT_TIM_TIMER) {
+ sc->imask &= ~ATH9K_INT_TIM_TIMER;
+ ath9k_hw_set_interrupts(sc->sc_ah,
+ sc->imask);
+ }
}
+ }
- sc->tx_chan_width = ATH9K_HT_MACMODE_20;
- sc->sc_ah->ah_channels[pos].chanmode =
- (curchan->band == IEEE80211_BAND_2GHZ) ?
- CHANNEL_G : CHANNEL_A;
+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+ struct ieee80211_channel *curchan = hw->conf.channel;
+ int pos = curchan->hw_value;
- if (conf->ht.enabled) {
- if (conf->ht.channel_type == NL80211_CHAN_HT40PLUS ||
- conf->ht.channel_type == NL80211_CHAN_HT40MINUS)
- sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
+ aphy->chan_idx = pos;
+ aphy->chan_is_ht = conf_is_ht(conf);
- sc->sc_ah->ah_channels[pos].chanmode =
- ath_get_extchanmode(sc, curchan,
- conf->ht.channel_type);
+ if (aphy->state == ATH_WIPHY_SCAN ||
+ aphy->state == ATH_WIPHY_ACTIVE)
+ ath9k_wiphy_pause_all_forced(sc, aphy);
+ else {
+ /*
+ * Do not change operational channel based on a paused
+ * wiphy changes.
+ */
+ goto skip_chan_change;
}
- ath_update_chainmask(sc, conf->ht.enabled);
+ DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
+ curchan->center_freq);
+
+ /* XXX: remove me eventualy */
+ ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
+
+ ath_update_chainmask(sc, conf_is_ht(conf));
- if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0) {
+ if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n");
mutex_unlock(&sc->mutex);
return -EINVAL;
}
}
+skip_chan_change:
if (changed & IEEE80211_CONF_CHANGE_POWER)
- sc->sc_config.txpowlimit = 2 * conf->power_level;
+ sc->config.txpowlimit = 2 * conf->power_level;
+
+ /*
+ * The HW TSF has to be reset when the beacon interval changes.
+ * We set the flag here, and ath_beacon_config_ap() would take this
+ * into account when it gets called through the subsequent
+ * config_interface() call - with IFCC_BEACON in the changed field.
+ */
+
+ if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
+ sc->sc_flags |= SC_OP_TSF_RESET;
mutex_unlock(&sc->mutex);
+
return 0;
}
@@ -2194,19 +2406,24 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf)
{
- struct ath_softc *sc = hw->priv;
- struct ath_hal *ah = sc->sc_ah;
- struct ath_vap *avp = (void *)vif->drv_priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_vif *avp = (void *)vif->drv_priv;
u32 rfilt = 0;
int error, i;
+ mutex_lock(&sc->mutex);
+
/* TODO: Need to decide which hw opmode to use for multi-interface
* cases */
if (vif->type == NL80211_IFTYPE_AP &&
- ah->ah_opmode != NL80211_IFTYPE_AP) {
- ah->ah_opmode = NL80211_IFTYPE_STATION;
+ ah->opmode != NL80211_IFTYPE_AP) {
+ ah->opmode = NL80211_IFTYPE_STATION;
ath9k_hw_setopmode(ah);
- ath9k_hw_write_associd(ah, sc->sc_myaddr, 0);
+ memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
+ sc->curaid = 0;
+ ath9k_hw_write_associd(sc);
/* Request full reset to get hw opmode changed properly */
sc->sc_flags |= SC_OP_FULL_RESET;
}
@@ -2216,18 +2433,19 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
switch (vif->type) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
/* Set BSSID */
- memcpy(sc->sc_curbssid, conf->bssid, ETH_ALEN);
- sc->sc_curaid = 0;
- ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid,
- sc->sc_curaid);
+ memcpy(sc->curbssid, conf->bssid, ETH_ALEN);
+ memcpy(avp->bssid, conf->bssid, ETH_ALEN);
+ sc->curaid = 0;
+ ath9k_hw_write_associd(sc);
/* Set aggregation protection mode parameters */
- sc->sc_config.ath_aggr_prot = 0;
+ sc->config.ath_aggr_prot = 0;
DPRINTF(sc, ATH_DBG_CONFIG,
"RX filter 0x%x bssid %pM aid 0x%x\n",
- rfilt, sc->sc_curbssid, sc->sc_curaid);
+ rfilt, sc->curbssid, sc->curaid);
/* need to reconfigure the beacon */
sc->sc_flags &= ~SC_OP_BEACONS ;
@@ -2238,24 +2456,30 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
}
}
- if ((conf->changed & IEEE80211_IFCC_BEACON) &&
- ((vif->type == NL80211_IFTYPE_ADHOC) ||
- (vif->type == NL80211_IFTYPE_AP))) {
- /*
- * Allocate and setup the beacon frame.
- *
- * Stop any previous beacon DMA. This may be
- * necessary, for example, when an ibss merge
- * causes reconfiguration; we may be called
- * with beacon transmission active.
- */
- ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+ if ((vif->type == NL80211_IFTYPE_ADHOC) ||
+ (vif->type == NL80211_IFTYPE_AP) ||
+ (vif->type == NL80211_IFTYPE_MESH_POINT)) {
+ if ((conf->changed & IEEE80211_IFCC_BEACON) ||
+ (conf->changed & IEEE80211_IFCC_BEACON_ENABLED &&
+ conf->enable_beacon)) {
+ /*
+ * Allocate and setup the beacon frame.
+ *
+ * Stop any previous beacon DMA. This may be
+ * necessary, for example, when an ibss merge
+ * causes reconfiguration; we may be called
+ * with beacon transmission active.
+ */
+ ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
- error = ath_beacon_alloc(sc, 0);
- if (error != 0)
- return error;
+ error = ath_beacon_alloc(aphy, vif);
+ if (error != 0) {
+ mutex_unlock(&sc->mutex);
+ return error;
+ }
- ath_beacon_sync(sc, 0);
+ ath_beacon_config(sc, vif);
+ }
}
/* Check for WLAN_CAPABILITY_PRIVACY ? */
@@ -2264,13 +2488,15 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
ath9k_hw_keysetmac(sc->sc_ah,
(u16)i,
- sc->sc_curbssid);
+ sc->curbssid);
}
/* Only legacy IBSS for now */
if (vif->type == NL80211_IFTYPE_ADHOC)
ath_update_chainmask(sc, 0);
+ mutex_unlock(&sc->mutex);
+
return 0;
}
@@ -2289,7 +2515,8 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
int mc_count,
struct dev_mc_list *mclist)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
u32 rfilt;
changed_flags &= SUPPORTED_FILTERS;
@@ -2299,11 +2526,6 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
rfilt = ath_calcrxfilter(sc);
ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
- if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
- if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
- ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0);
- }
-
DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter);
}
@@ -2312,7 +2534,8 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw,
enum sta_notify_cmd cmd,
struct ieee80211_sta *sta)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
switch (cmd) {
case STA_NOTIFY_ADD:
@@ -2326,17 +2549,19 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw,
}
}
-static int ath9k_conf_tx(struct ieee80211_hw *hw,
- u16 queue,
+static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
struct ath9k_tx_queue_info qi;
int ret = 0, qnum;
if (queue >= WME_NUM_AC)
return 0;
+ mutex_lock(&sc->mutex);
+
qi.tqi_aifs = params->aifs;
qi.tqi_cwmin = params->cw_min;
qi.tqi_cwmax = params->cw_max;
@@ -2353,29 +2578,39 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw,
if (ret)
DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n");
+ mutex_unlock(&sc->mutex);
+
return ret;
}
static int ath9k_set_key(struct ieee80211_hw *hw,
enum set_key_cmd cmd,
- const u8 *local_addr,
- const u8 *addr,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
int ret = 0;
+ if (modparam_nohwcrypt)
+ return -ENOSPC;
+
+ mutex_lock(&sc->mutex);
+ ath9k_ps_wakeup(sc);
DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n");
switch (cmd) {
case SET_KEY:
- ret = ath_key_config(sc, addr, key);
+ ret = ath_key_config(sc, vif, sta, key);
if (ret >= 0) {
key->hw_key_idx = ret;
/* push IV and Michael MIC generation to stack */
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
if (key->alg == ALG_TKIP)
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+ if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
+ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
ret = 0;
}
break;
@@ -2386,6 +2621,9 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
ret = -EINVAL;
}
+ ath9k_ps_restore(sc);
+ mutex_unlock(&sc->mutex);
+
return ret;
}
@@ -2394,7 +2632,10 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf,
u32 changed)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ mutex_lock(&sc->mutex);
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
@@ -2420,33 +2661,50 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
bss_conf->assoc);
ath9k_bss_assoc_info(sc, vif, bss_conf);
}
+
+ mutex_unlock(&sc->mutex);
}
static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
{
u64 tsf;
- struct ath_softc *sc = hw->priv;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
- tsf = ath9k_hw_gettsf64(ah);
+ mutex_lock(&sc->mutex);
+ tsf = ath9k_hw_gettsf64(sc->sc_ah);
+ mutex_unlock(&sc->mutex);
return tsf;
}
+static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ mutex_lock(&sc->mutex);
+ ath9k_hw_settsf64(sc->sc_ah, tsf);
+ mutex_unlock(&sc->mutex);
+}
+
static void ath9k_reset_tsf(struct ieee80211_hw *hw)
{
- struct ath_softc *sc = hw->priv;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
- ath9k_hw_reset_tsf(ah);
+ mutex_lock(&sc->mutex);
+ ath9k_hw_reset_tsf(sc->sc_ah);
+ mutex_unlock(&sc->mutex);
}
static int ath9k_ampdu_action(struct ieee80211_hw *hw,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta,
- u16 tid, u16 *ssn)
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta,
+ u16 tid, u16 *ssn)
{
- struct ath_softc *sc = hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
int ret = 0;
switch (action) {
@@ -2472,7 +2730,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
break;
- case IEEE80211_AMPDU_TX_RESUME:
+ case IEEE80211_AMPDU_TX_OPERATIONAL:
ath_tx_aggr_resume(sc, sta, tid);
break;
default:
@@ -2482,7 +2740,41 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
return ret;
}
-static struct ieee80211_ops ath9k_ops = {
+static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ if (ath9k_wiphy_scanning(sc)) {
+ printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the "
+ "same time\n");
+ /*
+ * Do not allow the concurrent scanning state for now. This
+ * could be improved with scanning control moved into ath9k.
+ */
+ return;
+ }
+
+ aphy->state = ATH_WIPHY_SCAN;
+ ath9k_wiphy_pause_all_forced(sc, aphy);
+
+ mutex_lock(&sc->mutex);
+ sc->sc_flags |= SC_OP_SCANNING;
+ mutex_unlock(&sc->mutex);
+}
+
+static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ mutex_lock(&sc->mutex);
+ aphy->state = ATH_WIPHY_ACTIVE;
+ sc->sc_flags &= ~SC_OP_SCANNING;
+ mutex_unlock(&sc->mutex);
+}
+
+struct ieee80211_ops ath9k_ops = {
.tx = ath9k_tx,
.start = ath9k_start,
.stop = ath9k_stop,
@@ -2496,8 +2788,11 @@ static struct ieee80211_ops ath9k_ops = {
.bss_info_changed = ath9k_bss_info_changed,
.set_key = ath9k_set_key,
.get_tsf = ath9k_get_tsf,
+ .set_tsf = ath9k_set_tsf,
.reset_tsf = ath9k_reset_tsf,
.ampdu_action = ath9k_ampdu_action,
+ .sw_scan_start = ath9k_sw_scan_start,
+ .sw_scan_complete = ath9k_sw_scan_complete,
};
static struct {
@@ -2526,7 +2821,7 @@ static struct {
/*
* Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
*/
-static const char *
+const char *
ath_mac_bb_name(u32 mac_bb_version)
{
int i;
@@ -2543,7 +2838,7 @@ ath_mac_bb_name(u32 mac_bb_version)
/*
* Return the RF name. "????" is returned if the RF is unknown.
*/
-static const char *
+const char *
ath_rf_name(u16 rf_version)
{
int i;
@@ -2557,254 +2852,62 @@ ath_rf_name(u16 rf_version)
return "????";
}
-static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
- void __iomem *mem;
- struct ath_softc *sc;
- struct ieee80211_hw *hw;
- u8 csz;
- u32 val;
- int ret = 0;
- struct ath_hal *ah;
-
- if (pci_enable_device(pdev))
- return -EIO;
-
- ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
-
- if (ret) {
- printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
- goto bad;
- }
-
- ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
-
- if (ret) {
- printk(KERN_ERR "ath9k: 32-bit DMA consistent "
- "DMA enable failed\n");
- goto bad;
- }
-
- /*
- * Cache line size is used to size and align various
- * structures used to communicate with the hardware.
- */
- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
- if (csz == 0) {
- /*
- * Linux 2.4.18 (at least) writes the cache line size
- * register as a 16-bit wide register which is wrong.
- * We must have this setup properly for rx buffer
- * DMA to work so force a reasonable value here if it
- * comes up zero.
- */
- csz = L1_CACHE_BYTES / sizeof(u32);
- pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
- }
- /*
- * The default setting of latency timer yields poor results,
- * set it to the value used by other systems. It may be worth
- * tweaking this setting more.
- */
- pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
-
- pci_set_master(pdev);
-
- /*
- * Disable the RETRY_TIMEOUT register (0x41) to keep
- * PCI Tx retries from interfering with C3 CPU state.
- */
- pci_read_config_dword(pdev, 0x40, &val);
- if ((val & 0x0000ff00) != 0)
- pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
-
- ret = pci_request_region(pdev, 0, "ath9k");
- if (ret) {
- dev_err(&pdev->dev, "PCI memory region reserve error\n");
- ret = -ENODEV;
- goto bad;
- }
-
- mem = pci_iomap(pdev, 0, 0);
- if (!mem) {
- printk(KERN_ERR "PCI memory map error\n") ;
- ret = -EIO;
- goto bad1;
- }
-
- hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
- if (hw == NULL) {
- printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
- goto bad2;
- }
-
- SET_IEEE80211_DEV(hw, &pdev->dev);
- pci_set_drvdata(pdev, hw);
-
- sc = hw->priv;
- sc->hw = hw;
- sc->pdev = pdev;
- sc->mem = mem;
-
- if (ath_attach(id->device, sc) != 0) {
- ret = -ENODEV;
- goto bad3;
- }
-
- /* setup interrupt service routine */
-
- if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
- printk(KERN_ERR "%s: request_irq failed\n",
- wiphy_name(hw->wiphy));
- ret = -EIO;
- goto bad4;
- }
-
- ah = sc->sc_ah;
- printk(KERN_INFO
- "%s: Atheros AR%s MAC/BB Rev:%x "
- "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
- wiphy_name(hw->wiphy),
- ath_mac_bb_name(ah->ah_macVersion),
- ah->ah_macRev,
- ath_rf_name((ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR)),
- ah->ah_phyRev,
- (unsigned long)mem, pdev->irq);
-
- return 0;
-bad4:
- ath_detach(sc);
-bad3:
- ieee80211_free_hw(hw);
-bad2:
- pci_iounmap(pdev, mem);
-bad1:
- pci_release_region(pdev, 0);
-bad:
- pci_disable_device(pdev);
- return ret;
-}
-
-static void ath_pci_remove(struct pci_dev *pdev)
-{
- struct ieee80211_hw *hw = pci_get_drvdata(pdev);
- struct ath_softc *sc = hw->priv;
-
- ath_detach(sc);
- if (pdev->irq)
- free_irq(pdev->irq, sc);
- pci_iounmap(pdev, sc->mem);
- pci_release_region(pdev, 0);
- pci_disable_device(pdev);
- ieee80211_free_hw(hw);
-}
-
-#ifdef CONFIG_PM
-
-static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct ieee80211_hw *hw = pci_get_drvdata(pdev);
- struct ath_softc *sc = hw->priv;
-
- ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
- cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
-#endif
-
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, 3);
-
- return 0;
-}
-
-static int ath_pci_resume(struct pci_dev *pdev)
-{
- struct ieee80211_hw *hw = pci_get_drvdata(pdev);
- struct ath_softc *sc = hw->priv;
- u32 val;
- int err;
-
- err = pci_enable_device(pdev);
- if (err)
- return err;
- pci_restore_state(pdev);
- /*
- * Suspend/Resume resets the PCI configuration space, so we have to
- * re-disable the RETRY_TIMEOUT register (0x41) to keep
- * PCI Tx retries from interfering with C3 CPU state
- */
- pci_read_config_dword(pdev, 0x40, &val);
- if ((val & 0x0000ff00) != 0)
- pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
-
- /* Enable LED */
- ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
- AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
- /*
- * check the h/w rfkill state on resume
- * and start the rfkill poll timer
- */
- if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
- queue_delayed_work(sc->hw->workqueue,
- &sc->rf_kill.rfkill_poll, 0);
-#endif
-
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
-MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
-
-static struct pci_driver ath_pci_driver = {
- .name = "ath9k",
- .id_table = ath_pci_id_table,
- .probe = ath_pci_probe,
- .remove = ath_pci_remove,
-#ifdef CONFIG_PM
- .suspend = ath_pci_suspend,
- .resume = ath_pci_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init init_ath_pci(void)
+static int __init ath9k_init(void)
{
int error;
- printk(KERN_INFO "%s: %s\n", dev_info, ATH_PCI_VERSION);
-
/* Register rate control algorithm */
error = ath_rate_control_register();
if (error != 0) {
printk(KERN_ERR
- "Unable to register rate control algorithm: %d\n",
+ "ath9k: Unable to register rate control "
+ "algorithm: %d\n",
error);
- ath_rate_control_unregister();
- return error;
+ goto err_out;
}
- if (pci_register_driver(&ath_pci_driver) < 0) {
+ error = ath9k_debug_create_root();
+ if (error) {
printk(KERN_ERR
- "ath_pci: No devices found, driver not installed.\n");
- ath_rate_control_unregister();
- pci_unregister_driver(&ath_pci_driver);
- return -ENODEV;
+ "ath9k: Unable to create debugfs root: %d\n",
+ error);
+ goto err_rate_unregister;
+ }
+
+ error = ath_pci_init();
+ if (error < 0) {
+ printk(KERN_ERR
+ "ath9k: No PCI devices found, driver not installed.\n");
+ error = -ENODEV;
+ goto err_remove_root;
+ }
+
+ error = ath_ahb_init();
+ if (error < 0) {
+ error = -ENODEV;
+ goto err_pci_exit;
}
return 0;
+
+ err_pci_exit:
+ ath_pci_exit();
+
+ err_remove_root:
+ ath9k_debug_remove_root();
+ err_rate_unregister:
+ ath_rate_control_unregister();
+ err_out:
+ return error;
}
-module_init(init_ath_pci);
+module_init(ath9k_init);
-static void __exit exit_ath_pci(void)
+static void __exit ath9k_exit(void)
{
+ ath_ahb_exit();
+ ath_pci_exit();
+ ath9k_debug_remove_root();
ath_rate_control_unregister();
- pci_unregister_driver(&ath_pci_driver);
printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
}
-module_exit(exit_ath_pci);
+module_exit(ath9k_exit);
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath9k/pci.c
new file mode 100644
index 000000000000..6dbc58580abb
--- /dev/null
+++ b/drivers/net/wireless/ath9k/pci.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/nl80211.h>
+#include <linux/pci.h>
+#include "ath9k.h"
+
+static struct pci_device_id ath_pci_id_table[] __devinitdata = {
+ { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */
+ { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
+ { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */
+ { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
+ { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
+ { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
+ { 0 }
+};
+
+/* return bus cachesize in 4B word units */
+static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
+{
+ u8 u8tmp;
+
+ pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE,
+ (u8 *)&u8tmp);
+ *csz = (int)u8tmp;
+
+ /*
+ * This check was put in to avoid "unplesant" consequences if
+ * the bootrom has not fully initialized all PCI devices.
+ * Sometimes the cache line size register is not set
+ */
+
+ if (*csz == 0)
+ *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
+}
+
+static void ath_pci_cleanup(struct ath_softc *sc)
+{
+ struct pci_dev *pdev = to_pci_dev(sc->dev);
+
+ pci_iounmap(pdev, sc->mem);
+ pci_disable_device(pdev);
+ pci_release_region(pdev, 0);
+}
+
+static bool ath_pci_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
+{
+ (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
+
+ if (!ath9k_hw_wait(ah,
+ AR_EEPROM_STATUS_DATA,
+ AR_EEPROM_STATUS_DATA_BUSY |
+ AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
+ AH_WAIT_TIMEOUT)) {
+ return false;
+ }
+
+ *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
+ AR_EEPROM_STATUS_DATA_VAL);
+
+ return true;
+}
+
+static struct ath_bus_ops ath_pci_bus_ops = {
+ .read_cachesize = ath_pci_read_cachesize,
+ .cleanup = ath_pci_cleanup,
+ .eeprom_read = ath_pci_eeprom_read,
+};
+
+static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ void __iomem *mem;
+ struct ath_wiphy *aphy;
+ struct ath_softc *sc;
+ struct ieee80211_hw *hw;
+ u8 csz;
+ int ret = 0;
+ struct ath_hw *ah;
+
+ if (pci_enable_device(pdev))
+ return -EIO;
+
+ ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+
+ if (ret) {
+ printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
+ goto bad;
+ }
+
+ ret = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+
+ if (ret) {
+ printk(KERN_ERR "ath9k: 32-bit DMA consistent "
+ "DMA enable failed\n");
+ goto bad;
+ }
+
+ /*
+ * Cache line size is used to size and align various
+ * structures used to communicate with the hardware.
+ */
+ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
+ if (csz == 0) {
+ /*
+ * Linux 2.4.18 (at least) writes the cache line size
+ * register as a 16-bit wide register which is wrong.
+ * We must have this setup properly for rx buffer
+ * DMA to work so force a reasonable value here if it
+ * comes up zero.
+ */
+ csz = L1_CACHE_BYTES / sizeof(u32);
+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
+ }
+ /*
+ * The default setting of latency timer yields poor results,
+ * set it to the value used by other systems. It may be worth
+ * tweaking this setting more.
+ */
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
+
+ pci_set_master(pdev);
+
+ ret = pci_request_region(pdev, 0, "ath9k");
+ if (ret) {
+ dev_err(&pdev->dev, "PCI memory region reserve error\n");
+ ret = -ENODEV;
+ goto bad;
+ }
+
+ mem = pci_iomap(pdev, 0, 0);
+ if (!mem) {
+ printk(KERN_ERR "PCI memory map error\n") ;
+ ret = -EIO;
+ goto bad1;
+ }
+
+ hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
+ sizeof(struct ath_softc), &ath9k_ops);
+ if (hw == NULL) {
+ printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
+ goto bad2;
+ }
+
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+ pci_set_drvdata(pdev, hw);
+
+ aphy = hw->priv;
+ sc = (struct ath_softc *) (aphy + 1);
+ aphy->sc = sc;
+ aphy->hw = hw;
+ sc->pri_wiphy = aphy;
+ sc->hw = hw;
+ sc->dev = &pdev->dev;
+ sc->mem = mem;
+ sc->bus_ops = &ath_pci_bus_ops;
+
+ if (ath_attach(id->device, sc) != 0) {
+ ret = -ENODEV;
+ goto bad3;
+ }
+
+ /* setup interrupt service routine */
+
+ if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
+ printk(KERN_ERR "%s: request_irq failed\n",
+ wiphy_name(hw->wiphy));
+ ret = -EIO;
+ goto bad4;
+ }
+
+ sc->irq = pdev->irq;
+
+ ah = sc->sc_ah;
+ printk(KERN_INFO
+ "%s: Atheros AR%s MAC/BB Rev:%x "
+ "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
+ wiphy_name(hw->wiphy),
+ ath_mac_bb_name(ah->hw_version.macVersion),
+ ah->hw_version.macRev,
+ ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
+ ah->hw_version.phyRev,
+ (unsigned long)mem, pdev->irq);
+
+ return 0;
+bad4:
+ ath_detach(sc);
+bad3:
+ ieee80211_free_hw(hw);
+bad2:
+ pci_iounmap(pdev, mem);
+bad1:
+ pci_release_region(pdev, 0);
+bad:
+ pci_disable_device(pdev);
+ return ret;
+}
+
+static void ath_pci_remove(struct pci_dev *pdev)
+{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ ath_cleanup(sc);
+}
+
+#ifdef CONFIG_PM
+
+static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+
+ ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
+#endif
+
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ return 0;
+}
+
+static int ath_pci_resume(struct pci_dev *pdev)
+{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ int err;
+
+ err = pci_enable_device(pdev);
+ if (err)
+ return err;
+ pci_restore_state(pdev);
+
+ /* Enable LED */
+ ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+ /*
+ * check the h/w rfkill state on resume
+ * and start the rfkill poll timer
+ */
+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+ queue_delayed_work(sc->hw->workqueue,
+ &sc->rf_kill.rfkill_poll, 0);
+#endif
+
+ return 0;
+}
+
+#endif /* CONFIG_PM */
+
+MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
+
+static struct pci_driver ath_pci_driver = {
+ .name = "ath9k",
+ .id_table = ath_pci_id_table,
+ .probe = ath_pci_probe,
+ .remove = ath_pci_remove,
+#ifdef CONFIG_PM
+ .suspend = ath_pci_suspend,
+ .resume = ath_pci_resume,
+#endif /* CONFIG_PM */
+};
+
+int ath_pci_init(void)
+{
+ return pci_register_driver(&ath_pci_driver);
+}
+
+void ath_pci_exit(void)
+{
+ pci_unregister_driver(&ath_pci_driver);
+}
diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath9k/phy.c
index 766982a8196e..8bcba906929a 100644
--- a/drivers/net/wireless/ath9k/phy.c
+++ b/drivers/net/wireless/ath9k/phy.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,22 +14,17 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
-#include "hw.h"
-#include "reg.h"
-#include "phy.h"
+#include "ath9k.h"
void
-ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex, u32 freqIndex,
+ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
int regWrites)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- REG_WRITE_ARRAY(&ahp->ah_iniBB_RfGain, freqIndex, regWrites);
+ REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
}
bool
-ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan)
+ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
{
u32 channelSel = 0;
u32 bModeSynth = 0;
@@ -95,15 +90,14 @@ ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan)
REG_WRITE(ah, AR_PHY(0x37), reg32);
- ah->ah_curchan = chan;
-
- AH5416(ah)->ah_curchanRadIndex = -1;
+ ah->curchan = chan;
+ ah->curchan_rad_index = -1;
return true;
}
bool
-ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
+ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
struct ath9k_channel *chan)
{
u16 bMode, fracMode, aModeRefSel = 0;
@@ -138,20 +132,27 @@ ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
bMode = 0;
fracMode = 0;
- if ((freq % 20) == 0) {
- aModeRefSel = 3;
- } else if ((freq % 10) == 0) {
- aModeRefSel = 2;
- } else {
+ switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
+ case 0:
+ if ((freq % 20) == 0) {
+ aModeRefSel = 3;
+ } else if ((freq % 10) == 0) {
+ aModeRefSel = 2;
+ }
+ if (aModeRefSel)
+ break;
+ case 1:
+ default:
aModeRefSel = 0;
-
fracMode = 1;
refDivA = 1;
channelSel = (freq * 0x8000) / 15;
REG_RMW_FIELD(ah, AR_AN_SYNTH9,
AR_AN_SYNTH9_REFDIVA, refDivA);
+
}
+
if (!fracMode) {
ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
channelSel = ndiv & 0x1ff;
@@ -166,9 +167,8 @@ ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
- ah->ah_curchan = chan;
-
- AH5416(ah)->ah_curchanRadIndex = -1;
+ ah->curchan = chan;
+ ah->curchan_rad_index = -1;
return true;
}
@@ -201,11 +201,9 @@ ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
}
bool
-ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan,
+ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
u16 modesIndex)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
u32 eepMinorRev;
u32 ob5GHz = 0, db5GHz = 0;
u32 ob2GHz = 0, db2GHz = 0;
@@ -214,161 +212,156 @@ ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan,
if (AR_SREV_9280_10_OR_LATER(ah))
return true;
- eepMinorRev = ath9k_hw_get_eeprom(ah, EEP_MINOR_REV);
+ eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
- RF_BANK_SETUP(ahp->ah_analogBank0Data, &ahp->ah_iniBank0, 1);
+ RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
- RF_BANK_SETUP(ahp->ah_analogBank1Data, &ahp->ah_iniBank1, 1);
+ RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
- RF_BANK_SETUP(ahp->ah_analogBank2Data, &ahp->ah_iniBank2, 1);
+ RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
- RF_BANK_SETUP(ahp->ah_analogBank3Data, &ahp->ah_iniBank3,
+ RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
modesIndex);
{
int i;
- for (i = 0; i < ahp->ah_iniBank6TPC.ia_rows; i++) {
- ahp->ah_analogBank6Data[i] =
- INI_RA(&ahp->ah_iniBank6TPC, i, modesIndex);
+ for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) {
+ ah->analogBank6Data[i] =
+ INI_RA(&ah->iniBank6TPC, i, modesIndex);
}
}
if (eepMinorRev >= 2) {
if (IS_CHAN_2GHZ(chan)) {
- ob2GHz = ath9k_hw_get_eeprom(ah, EEP_OB_2);
- db2GHz = ath9k_hw_get_eeprom(ah, EEP_DB_2);
- ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+ ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
+ db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
+ ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
ob2GHz, 3, 197, 0);
- ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+ ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
db2GHz, 3, 194, 0);
} else {
- ob5GHz = ath9k_hw_get_eeprom(ah, EEP_OB_5);
- db5GHz = ath9k_hw_get_eeprom(ah, EEP_DB_5);
- ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+ ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
+ db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
+ ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
ob5GHz, 3, 203, 0);
- ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
+ ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
db5GHz, 3, 200, 0);
}
}
- RF_BANK_SETUP(ahp->ah_analogBank7Data, &ahp->ah_iniBank7, 1);
+ RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank0, ahp->ah_analogBank0Data,
+ REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
regWrites);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank1, ahp->ah_analogBank1Data,
+ REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
regWrites);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank2, ahp->ah_analogBank2Data,
+ REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data,
regWrites);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank3, ahp->ah_analogBank3Data,
+ REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data,
regWrites);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6TPC, ahp->ah_analogBank6Data,
+ REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data,
regWrites);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank7, ahp->ah_analogBank7Data,
+ REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data,
regWrites);
return true;
}
void
-ath9k_hw_rfdetach(struct ath_hal *ah)
+ath9k_hw_rfdetach(struct ath_hw *ah)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
- if (ahp->ah_analogBank0Data != NULL) {
- kfree(ahp->ah_analogBank0Data);
- ahp->ah_analogBank0Data = NULL;
+ if (ah->analogBank0Data != NULL) {
+ kfree(ah->analogBank0Data);
+ ah->analogBank0Data = NULL;
}
- if (ahp->ah_analogBank1Data != NULL) {
- kfree(ahp->ah_analogBank1Data);
- ahp->ah_analogBank1Data = NULL;
+ if (ah->analogBank1Data != NULL) {
+ kfree(ah->analogBank1Data);
+ ah->analogBank1Data = NULL;
}
- if (ahp->ah_analogBank2Data != NULL) {
- kfree(ahp->ah_analogBank2Data);
- ahp->ah_analogBank2Data = NULL;
+ if (ah->analogBank2Data != NULL) {
+ kfree(ah->analogBank2Data);
+ ah->analogBank2Data = NULL;
}
- if (ahp->ah_analogBank3Data != NULL) {
- kfree(ahp->ah_analogBank3Data);
- ahp->ah_analogBank3Data = NULL;
+ if (ah->analogBank3Data != NULL) {
+ kfree(ah->analogBank3Data);
+ ah->analogBank3Data = NULL;
}
- if (ahp->ah_analogBank6Data != NULL) {
- kfree(ahp->ah_analogBank6Data);
- ahp->ah_analogBank6Data = NULL;
+ if (ah->analogBank6Data != NULL) {
+ kfree(ah->analogBank6Data);
+ ah->analogBank6Data = NULL;
}
- if (ahp->ah_analogBank6TPCData != NULL) {
- kfree(ahp->ah_analogBank6TPCData);
- ahp->ah_analogBank6TPCData = NULL;
+ if (ah->analogBank6TPCData != NULL) {
+ kfree(ah->analogBank6TPCData);
+ ah->analogBank6TPCData = NULL;
}
- if (ahp->ah_analogBank7Data != NULL) {
- kfree(ahp->ah_analogBank7Data);
- ahp->ah_analogBank7Data = NULL;
+ if (ah->analogBank7Data != NULL) {
+ kfree(ah->analogBank7Data);
+ ah->analogBank7Data = NULL;
}
- if (ahp->ah_addac5416_21 != NULL) {
- kfree(ahp->ah_addac5416_21);
- ahp->ah_addac5416_21 = NULL;
+ if (ah->addac5416_21 != NULL) {
+ kfree(ah->addac5416_21);
+ ah->addac5416_21 = NULL;
}
- if (ahp->ah_bank6Temp != NULL) {
- kfree(ahp->ah_bank6Temp);
- ahp->ah_bank6Temp = NULL;
+ if (ah->bank6Temp != NULL) {
+ kfree(ah->bank6Temp);
+ ah->bank6Temp = NULL;
}
}
-bool ath9k_hw_init_rf(struct ath_hal *ah, int *status)
+bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
{
- struct ath_hal_5416 *ahp = AH5416(ah);
-
if (!AR_SREV_9280_10_OR_LATER(ah)) {
-
- ahp->ah_analogBank0Data =
+ ah->analogBank0Data =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank0.ia_rows), GFP_KERNEL);
- ahp->ah_analogBank1Data =
+ ah->iniBank0.ia_rows), GFP_KERNEL);
+ ah->analogBank1Data =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank1.ia_rows), GFP_KERNEL);
- ahp->ah_analogBank2Data =
+ ah->iniBank1.ia_rows), GFP_KERNEL);
+ ah->analogBank2Data =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank2.ia_rows), GFP_KERNEL);
- ahp->ah_analogBank3Data =
+ ah->iniBank2.ia_rows), GFP_KERNEL);
+ ah->analogBank3Data =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank3.ia_rows), GFP_KERNEL);
- ahp->ah_analogBank6Data =
+ ah->iniBank3.ia_rows), GFP_KERNEL);
+ ah->analogBank6Data =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank6.ia_rows), GFP_KERNEL);
- ahp->ah_analogBank6TPCData =
+ ah->iniBank6.ia_rows), GFP_KERNEL);
+ ah->analogBank6TPCData =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank6TPC.ia_rows), GFP_KERNEL);
- ahp->ah_analogBank7Data =
+ ah->iniBank6TPC.ia_rows), GFP_KERNEL);
+ ah->analogBank7Data =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank7.ia_rows), GFP_KERNEL);
-
- if (ahp->ah_analogBank0Data == NULL
- || ahp->ah_analogBank1Data == NULL
- || ahp->ah_analogBank2Data == NULL
- || ahp->ah_analogBank3Data == NULL
- || ahp->ah_analogBank6Data == NULL
- || ahp->ah_analogBank6TPCData == NULL
- || ahp->ah_analogBank7Data == NULL) {
+ ah->iniBank7.ia_rows), GFP_KERNEL);
+
+ if (ah->analogBank0Data == NULL
+ || ah->analogBank1Data == NULL
+ || ah->analogBank2Data == NULL
+ || ah->analogBank3Data == NULL
+ || ah->analogBank6Data == NULL
+ || ah->analogBank6TPCData == NULL
+ || ah->analogBank7Data == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"Cannot allocate RF banks\n");
*status = -ENOMEM;
return false;
}
- ahp->ah_addac5416_21 =
+ ah->addac5416_21 =
kzalloc((sizeof(u32) *
- ahp->ah_iniAddac.ia_rows *
- ahp->ah_iniAddac.ia_columns), GFP_KERNEL);
- if (ahp->ah_addac5416_21 == NULL) {
+ ah->iniAddac.ia_rows *
+ ah->iniAddac.ia_columns), GFP_KERNEL);
+ if (ah->addac5416_21 == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
- "Cannot allocate ah_addac5416_21\n");
+ "Cannot allocate addac5416_21\n");
*status = -ENOMEM;
return false;
}
- ahp->ah_bank6Temp =
+ ah->bank6Temp =
kzalloc((sizeof(u32) *
- ahp->ah_iniBank6.ia_rows), GFP_KERNEL);
- if (ahp->ah_bank6Temp == NULL) {
+ ah->iniBank6.ia_rows), GFP_KERNEL);
+ if (ah->bank6Temp == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
- "Cannot allocate ah_bank6Temp\n");
+ "Cannot allocate bank6Temp\n");
*status = -ENOMEM;
return false;
}
@@ -378,24 +371,23 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status)
}
void
-ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
+ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
{
int i, regWrites = 0;
- struct ath_hal_5416 *ahp = AH5416(ah);
u32 bank6SelMask;
- u32 *bank6Temp = ahp->ah_bank6Temp;
+ u32 *bank6Temp = ah->bank6Temp;
- switch (ahp->ah_diversityControl) {
+ switch (ah->diversity_control) {
case ATH9K_ANT_FIXED_A:
bank6SelMask =
- (ahp->
- ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
+ (ah->
+ antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
REDUCE_CHAIN_1;
break;
case ATH9K_ANT_FIXED_B:
bank6SelMask =
- (ahp->
- ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
+ (ah->
+ antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
REDUCE_CHAIN_0;
break;
case ATH9K_ANT_VARIABLE:
@@ -406,8 +398,8 @@ ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
break;
}
- for (i = 0; i < ahp->ah_iniBank6.ia_rows; i++)
- bank6Temp[i] = ahp->ah_analogBank6Data[i];
+ for (i = 0; i < ah->iniBank6.ia_rows; i++)
+ bank6Temp[i] = ah->analogBank6Data[i];
REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
@@ -421,7 +413,7 @@ ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
- REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6, bank6Temp, regWrites);
+ REG_WRITE_RF_ARRAY(&ah->iniBank6, bank6Temp, regWrites);
REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
#ifdef ALTER_SWITCH
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h
index 3a406a5c0593..0f7f8e0c9c95 100644
--- a/drivers/net/wireless/ath9k/phy.h
+++ b/drivers/net/wireless/ath9k/phy.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -17,19 +17,19 @@
#ifndef PHY_H
#define PHY_H
-bool ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
+bool ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
struct ath9k_channel
*chan);
-bool ath9k_hw_set_channel(struct ath_hal *ah,
+bool ath9k_hw_set_channel(struct ath_hw *ah,
struct ath9k_channel *chan);
-void ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex,
+void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
u32 freqIndex, int regWrites);
-bool ath9k_hw_set_rf_regs(struct ath_hal *ah,
+bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
struct ath9k_channel *chan,
u16 modesIndex);
-void ath9k_hw_decrease_chain_power(struct ath_hal *ah,
+void ath9k_hw_decrease_chain_power(struct ath_hw *ah,
struct ath9k_channel *chan);
-bool ath9k_hw_init_rf(struct ath_hal *ah,
+bool ath9k_hw_init_rf(struct ath_hw *ah,
int *status);
#define AR_PHY_BASE 0x9800
@@ -387,6 +387,8 @@ bool ath9k_hw_init_rf(struct ath_hal *ah,
#define AR_PHY_CCK_TX_CTRL 0xA204
#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000C
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2
#define AR_PHY_CCK_DETECT 0xA208
#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F
@@ -444,6 +446,32 @@ bool ath9k_hw_init_rf(struct ath_hal *ah,
#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000
#define AR_PHY_TPCRG1_PD_GAIN_3_S 20
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
+
+#define AR_PHY_TX_PWRCTRL4 0xa264
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001FE
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1
+
+#define AR_PHY_TX_PWRCTRL6_0 0xa270
+#define AR_PHY_TX_PWRCTRL6_1 0xb270
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24
+
+#define AR_PHY_TX_PWRCTRL7 0xa274
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19
+
+#define AR_PHY_TX_PWRCTRL9 0xa27C
+#define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00
+#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10
+
+#define AR_PHY_TX_GAIN_TBL1 0xa300
+#define AR_PHY_TX_GAIN 0x0007F000
+#define AR_PHY_TX_GAIN_S 12
+
#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
#define AR_PHY_MASK2_M_31_45 0xa3a4
#define AR_PHY_MASK2_M_16_30 0xa3a8
@@ -485,6 +513,11 @@ bool ath9k_hw_init_rf(struct ath_hal *ah,
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000
#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
+/* Carrier leak calibration control, do it after AGC calibration */
+#define AR_PHY_CL_CAL_CTL 0xA358
+#define AR_PHY_CL_CAL_ENABLE 0x00000002
+#define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001
+
#define AR_PHY_POWER_TX_RATE5 0xA38C
#define AR_PHY_POWER_TX_RATE6 0xA390
@@ -530,10 +563,8 @@ bool ath9k_hw_init_rf(struct ath_hal *ah,
} \
} while (0)
-#define ATH9K_KEY_XOR 0xaa
-
#define ATH9K_IS_MIC_ENABLED(ah) \
- (AH5416(ah)->ah_staId1Defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
+ ((ah)->sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
#define ANTSWAP_AB 0x0001
#define REDUCE_CHAIN_0 0x00000050
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index 1b71b934bb5e..824ccbb8b7b8 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2004 Video54 Technologies, Inc.
- * Copyright (c) 2004-2008 Atheros Communications, Inc.
+ * Copyright (c) 2004-2009 Atheros Communications, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -15,16 +15,15 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
+#include "ath9k.h"
static struct ath_rate_table ar5416_11na_ratetable = {
42,
- {0},
{
{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
5400, 0x0b, 0x00, 12,
0, 2, 1, 0, 0, 0, 0, 0 },
- { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+ { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
7800, 0x0f, 0x00, 18,
0, 3, 1, 1, 1, 1, 1, 0 },
{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
@@ -158,7 +157,6 @@ static struct ath_rate_table ar5416_11na_ratetable = {
static struct ath_rate_table ar5416_11ng_ratetable = {
46,
- {0},
{
{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
900, 0x1b, 0x00, 2,
@@ -306,7 +304,6 @@ static struct ath_rate_table ar5416_11ng_ratetable = {
static struct ath_rate_table ar5416_11a_ratetable = {
8,
- {0},
{
{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
5400, 0x0b, 0x00, (0x80|12),
@@ -340,7 +337,6 @@ static struct ath_rate_table ar5416_11a_ratetable = {
static struct ath_rate_table ar5416_11g_ratetable = {
12,
- {0},
{
{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
900, 0x1b, 0x00, 2,
@@ -386,7 +382,6 @@ static struct ath_rate_table ar5416_11g_ratetable = {
static struct ath_rate_table ar5416_11b_ratetable = {
4,
- {0},
{
{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
900, 0x1b, 0x00, (0x80|2),
@@ -636,8 +631,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
struct ath_rate_table *rate_table,
- int probe_allowed, int *is_probing,
- int is_retry)
+ int *is_probing)
{
u32 dt, best_thruput, this_thruput, now_msec;
u8 rate, next_rate, best_rate, maxindex, minindex;
@@ -719,13 +713,6 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
}
rate = best_rate;
-
- /* if we are retrying for more than half the number
- * of max retries, use the min rate for the next retry
- */
- if (is_retry)
- rate = ath_rc_priv->valid_rate_index[minindex];
-
ath_rc_priv->rssi_last_lookup = rssi_last;
/*
@@ -733,13 +720,12 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
* non-monoticity of 11g's rate table
*/
- if (rate >= ath_rc_priv->rate_max_phy && probe_allowed) {
+ if (rate >= ath_rc_priv->rate_max_phy) {
rate = ath_rc_priv->rate_max_phy;
/* Probe the next allowed phy state */
- /* FIXME:XXXX Check to make sure ratMax is checked properly */
if (ath_rc_get_nextvalid_txrate(rate_table,
- ath_rc_priv, rate, &next_rate) &&
+ ath_rc_priv, rate, &next_rate) &&
(now_msec - ath_rc_priv->probe_time >
rate_table->probe_interval) &&
(ath_rc_priv->hw_maxretry_pktcnt >= 1)) {
@@ -761,14 +747,17 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
return rate;
}
-static void ath_rc_rate_set_series(struct ath_rate_table *rate_table ,
+static void ath_rc_rate_set_series(struct ath_rate_table *rate_table,
struct ieee80211_tx_rate *rate,
+ struct ieee80211_tx_rate_control *txrc,
u8 tries, u8 rix, int rtsctsenable)
{
rate->count = tries;
rate->idx = rix;
- if (rtsctsenable)
+ if (txrc->short_preamble)
+ rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
+ if (txrc->rts || rtsctsenable)
rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
@@ -778,6 +767,43 @@ static void ath_rc_rate_set_series(struct ath_rate_table *rate_table ,
rate->flags |= IEEE80211_TX_RC_MCS;
}
+static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
+ struct ath_rate_table *rate_table,
+ struct ieee80211_tx_info *tx_info)
+{
+ struct ieee80211_tx_rate *rates = tx_info->control.rates;
+ int i = 0, rix = 0, cix, enable_g_protection = 0;
+
+ /* get the cix for the lowest valid rix */
+ for (i = 3; i >= 0; i--) {
+ if (rates[i].count && (rates[i].idx >= 0)) {
+ rix = rates[i].idx;
+ break;
+ }
+ }
+ cix = rate_table->info[rix].ctrl_rate;
+
+ /* All protection frames are transmited at 2Mb/s for 802.11g,
+ * otherwise we transmit them at 1Mb/s */
+ if (sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ &&
+ !conf_is_ht(&sc->hw->conf))
+ enable_g_protection = 1;
+
+ /*
+ * If 802.11g protection is enabled, determine whether to use RTS/CTS or
+ * just CTS. Note that this is only done for OFDM/HT unicast frames.
+ */
+ if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
+ !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+ (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
+ WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
+ rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
+ cix = rate_table->info[enable_g_protection].ctrl_rate;
+ }
+
+ tx_info->control.rts_cts_rate_idx = cix;
+}
+
static u8 ath_rc_rate_getidx(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
struct ath_rate_table *rate_table,
@@ -809,54 +835,58 @@ static u8 ath_rc_rate_getidx(struct ath_softc *sc,
static void ath_rc_ratefind(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
- int num_tries, int num_rates,
- struct ieee80211_tx_info *tx_info, int *is_probe,
- int is_retry)
+ struct ieee80211_tx_rate_control *txrc)
{
- u8 try_per_rate = 0, i = 0, rix, nrix;
struct ath_rate_table *rate_table;
+ struct sk_buff *skb = txrc->skb;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rates = tx_info->control.rates;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ __le16 fc = hdr->frame_control;
+ u8 try_per_rate = 0, i = 0, rix, nrix;
+ int is_probe = 0;
rate_table = sc->cur_rate_table;
- rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, 1,
- is_probe, is_retry);
+ rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, &is_probe);
nrix = rix;
- if (*is_probe) {
+ if (is_probe) {
/* set one try for probe rates. For the
* probes don't enable rts */
- ath_rc_rate_set_series(rate_table,
- &rates[i++], 1, nrix, 0);
+ ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+ 1, nrix, 0);
- try_per_rate = (num_tries/num_rates);
+ try_per_rate = (ATH_11N_TXMAXTRY/4);
/* Get the next tried/allowed rate. No RTS for the next series
* after the probe rate
*/
- nrix = ath_rc_rate_getidx(sc,
- ath_rc_priv, rate_table, nrix, 1, 0);
- ath_rc_rate_set_series(rate_table,
- &rates[i++], try_per_rate, nrix, 0);
+ nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
+ rate_table, nrix, 1, 0);
+ ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+ try_per_rate, nrix, 0);
+
+ tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
} else {
- try_per_rate = (num_tries/num_rates);
+ try_per_rate = (ATH_11N_TXMAXTRY/4);
/* Set the choosen rate. No RTS for first series entry. */
- ath_rc_rate_set_series(rate_table,
- &rates[i++], try_per_rate, nrix, 0);
+ ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+ try_per_rate, nrix, 0);
}
/* Fill in the other rates for multirate retry */
- for ( ; i < num_rates; i++) {
+ for ( ; i < 4; i++) {
u8 try_num;
u8 min_rate;
- try_num = ((i + 1) == num_rates) ?
- num_tries - (try_per_rate * i) : try_per_rate ;
- min_rate = (((i + 1) == num_rates) && 0);
+ try_num = ((i + 1) == 4) ?
+ ATH_11N_TXMAXTRY - (try_per_rate * i) : try_per_rate ;
+ min_rate = (((i + 1) == 4) && 0);
nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
rate_table, nrix, 1, min_rate);
/* All other rates in the series have RTS enabled */
- ath_rc_rate_set_series(rate_table,
- &rates[i], try_num, nrix, 1);
+ ath_rc_rate_set_series(rate_table, &rates[i], txrc,
+ try_num, nrix, 1);
}
/*
@@ -875,7 +905,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
* above conditions.
*/
if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
- (sc->hw->conf.ht.enabled)) {
+ (conf_is_ht(&sc->hw->conf))) {
u8 dot11rate = rate_table->info[rix].dot11rate;
u8 phy = rate_table->info[rix].phy;
if (i == 4 &&
@@ -885,6 +915,24 @@ static void ath_rc_ratefind(struct ath_softc *sc,
rates[3].flags = rates[2].flags;
}
}
+
+ /*
+ * Force hardware to use computed duration for next
+ * fragment by disabling multi-rate retry, which
+ * updates duration based on the multi-rate duration table.
+ *
+ * FIXME: Fix duration
+ */
+ if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+ (ieee80211_has_morefrags(fc) ||
+ (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG))) {
+ rates[1].count = rates[2].count = rates[3].count = 0;
+ rates[1].idx = rates[2].idx = rates[3].idx = 0;
+ rates[0].count = ATH_TXMAXTRY;
+ }
+
+ /* Setup RTS/CTS */
+ ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
}
static bool ath_rc_update_per(struct ath_softc *sc,
@@ -1221,6 +1269,9 @@ static void ath_rc_update_ht(struct ath_softc *sc,
ath_rc_priv->per_down_time = now_msec;
}
+ ath_debug_stat_retries(sc, tx_rate, xretries, retries,
+ ath_rc_priv->state[tx_rate].per);
+
#undef CHK_RSSI
}
@@ -1338,36 +1389,18 @@ static struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
static void ath_rc_init(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
struct ieee80211_supported_band *sband,
- struct ieee80211_sta *sta)
+ struct ieee80211_sta *sta,
+ struct ath_rate_table *rate_table)
{
- struct ath_rate_table *rate_table = NULL;
struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
u8 i, j, k, hi = 0, hthi = 0;
- /* FIXME: Adhoc */
- if ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) ||
- (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)) {
- bool is_cw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
- rate_table = ath_choose_rate_table(sc, sband->band,
- sta->ht_cap.ht_supported,
- is_cw_40);
- } else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
- /* cur_rate_table would be set on init through config() */
- rate_table = sc->cur_rate_table;
- }
-
if (!rate_table) {
DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n");
return;
}
- if (sta->ht_cap.ht_supported) {
- ath_rc_priv->ht_cap = (WLAN_RC_HT_FLAG | WLAN_RC_DS_FLAG);
- if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
- ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG;
- }
-
/* Initial rate table size. Will change depending
* on the working rate set */
ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
@@ -1387,7 +1420,7 @@ static void ath_rc_init(struct ath_softc *sc,
ath_rc_priv->valid_phy_rateidx[i][j] = 0;
ath_rc_priv->valid_phy_ratecnt[i] = 0;
}
- ath_rc_priv->rc_phy_mode = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG);
+ ath_rc_priv->rc_phy_mode = ath_rc_priv->ht_cap & WLAN_RC_40_FLAG;
/* Set stream capability */
ath_rc_priv->single_stream = (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? 0 : 1;
@@ -1395,16 +1428,16 @@ static void ath_rc_init(struct ath_softc *sc,
if (!rateset->rs_nrates) {
/* No working rate, just initialize valid rates */
hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
- ath_rc_priv->ht_cap);
+ ath_rc_priv->ht_cap);
} else {
/* Use intersection of working rates and valid rates */
hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table,
- rateset, ath_rc_priv->ht_cap);
+ rateset, ath_rc_priv->ht_cap);
if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
hthi = ath_rc_setvalid_htrates(ath_rc_priv,
- rate_table,
- ht_mcs,
- ath_rc_priv->ht_cap);
+ rate_table,
+ ht_mcs,
+ ath_rc_priv->ht_cap);
}
hi = A_MAX(hi, hthi);
}
@@ -1432,9 +1465,36 @@ static void ath_rc_init(struct ath_softc *sc,
ath_rc_sort_validrates(rate_table, ath_rc_priv);
ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
sc->cur_rate_table = rate_table;
+
+ DPRINTF(sc, ATH_DBG_CONFIG, "RC Initialized with capabilities: 0x%x\n",
+ ath_rc_priv->ht_cap);
+}
+
+static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
+ bool is_cw40, bool is_sgi40)
+{
+ u8 caps = 0;
+
+ if (sta->ht_cap.ht_supported) {
+ caps = WLAN_RC_HT_FLAG;
+ if (sc->sc_ah->caps.tx_chainmask != 1 &&
+ ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) {
+ if (sta->ht_cap.mcs.rx_mask[1])
+ caps |= WLAN_RC_DS_FLAG;
+ }
+ if (is_cw40)
+ caps |= WLAN_RC_40_FLAG;
+ if (is_sgi40)
+ caps |= WLAN_RC_SGI_FLAG;
+ }
+
+ return caps;
}
-/* Rate Control callbacks */
+/***********************************/
+/* mac80211 Rate Control callbacks */
+/***********************************/
+
static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta,
struct sk_buff *skb)
@@ -1467,7 +1527,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
*/
if (tx_info_priv->tx.ts_flags &
(ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) &&
- ((sc->sc_ah->ah_txTrigLevel) >= ath_rc_priv->tx_triglevel_max)) {
+ ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) {
tx_status = 1;
is_underrun = 1;
}
@@ -1480,6 +1540,23 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
(is_underrun) ? ATH_11N_TXMAXTRY :
tx_info_priv->tx.ts_longretry);
+ /* Check if aggregation has to be enabled for this tid */
+ if (conf_is_ht(&sc->hw->conf) &&
+ !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+ if (ieee80211_is_data_qos(fc)) {
+ u8 *qc, tid;
+ struct ath_node *an;
+
+ qc = ieee80211_get_qos_ctl(hdr);
+ tid = qc[0] & 0xf;
+ an = (struct ath_node *)sta->drv_priv;
+
+ if(ath_tx_aggr_check(sc, an, tid))
+ ieee80211_start_tx_ba_session(sc->hw, hdr->addr1, tid);
+ }
+ }
+
+ ath_debug_stat_rc(sc, skb);
exit:
kfree(tx_info_priv);
}
@@ -1490,11 +1567,9 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
struct ieee80211_supported_band *sband = txrc->sband;
struct sk_buff *skb = txrc->skb;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ath_softc *sc = priv;
- struct ieee80211_hw *hw = sc->hw;
struct ath_rate_priv *ath_rc_priv = priv_sta;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- int is_probe = 0;
__le16 fc = hdr->frame_control;
/* lowest rate for management and multicast/broadcast frames */
@@ -1507,23 +1582,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
}
/* Find tx rate for unicast frames */
- ath_rc_ratefind(sc, ath_rc_priv, ATH_11N_TXMAXTRY, 4,
- tx_info, &is_probe, false);
-
- /* Check if aggregation has to be enabled for this tid */
- if (hw->conf.ht.enabled) {
- if (ieee80211_is_data_qos(fc)) {
- u8 *qc, tid;
- struct ath_node *an;
-
- qc = ieee80211_get_qos_ctl(hdr);
- tid = qc[0] & 0xf;
- an = (struct ath_node *)sta->drv_priv;
-
- if(ath_tx_aggr_check(sc, an, tid))
- ieee80211_start_tx_ba_session(hw, hdr->addr1, tid);
- }
- }
+ ath_rc_ratefind(sc, ath_rc_priv, txrc);
}
static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
@@ -1531,6 +1590,8 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
{
struct ath_softc *sc = priv;
struct ath_rate_priv *ath_rc_priv = priv_sta;
+ struct ath_rate_table *rate_table = NULL;
+ bool is_cw40, is_sgi40;
int i, j = 0;
for (i = 0; i < sband->n_bitrates; i++) {
@@ -1552,12 +1613,71 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
ath_rc_priv->neg_ht_rates.rs_nrates = j;
}
- ath_rc_init(sc, priv_sta, sband, sta);
+ is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ is_sgi40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+
+ /* Choose rate table first */
+
+ if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
+ (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
+ (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
+ rate_table = ath_choose_rate_table(sc, sband->band,
+ sta->ht_cap.ht_supported,
+ is_cw40);
+ } else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
+ /* cur_rate_table would be set on init through config() */
+ rate_table = sc->cur_rate_table;
+ }
+
+ ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
+ ath_rc_init(sc, priv_sta, sband, sta, rate_table);
+}
+
+static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta,
+ u32 changed)
+{
+ struct ath_softc *sc = priv;
+ struct ath_rate_priv *ath_rc_priv = priv_sta;
+ struct ath_rate_table *rate_table = NULL;
+ bool oper_cw40 = false, oper_sgi40;
+ bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ?
+ true : false;
+ bool local_sgi40 = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ?
+ true : false;
+
+ /* FIXME: Handle AP mode later when we support CWM */
+
+ if (changed & IEEE80211_RC_HT_CHANGED) {
+ if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
+ return;
+
+ if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
+ sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
+ oper_cw40 = true;
+
+ oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+ true : false;
+
+ if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
+ rate_table = ath_choose_rate_table(sc, sband->band,
+ sta->ht_cap.ht_supported,
+ oper_cw40);
+ ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
+ oper_cw40, oper_sgi40);
+ ath_rc_init(sc, priv_sta, sband, sta, rate_table);
+
+ DPRINTF(sc, ATH_DBG_CONFIG,
+ "Operating HT Bandwidth changed to: %d\n",
+ sc->hw->conf.channel_type);
+ }
+ }
}
static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
{
- return hw->priv;
+ struct ath_wiphy *aphy = hw->priv;
+ return aphy->sc;
}
static void ath_rate_free(void *priv)
@@ -1578,7 +1698,7 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp
}
rate_priv->rssi_down_time = jiffies_to_msecs(jiffies);
- rate_priv->tx_triglevel_max = sc->sc_ah->ah_caps.tx_triglevel_max;
+ rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
return rate_priv;
}
@@ -1596,41 +1716,13 @@ static struct rate_control_ops ath_rate_ops = {
.tx_status = ath_tx_status,
.get_rate = ath_get_rate,
.rate_init = ath_rate_init,
+ .rate_update = ath_rate_update,
.alloc = ath_rate_alloc,
.free = ath_rate_free,
.alloc_sta = ath_rate_alloc_sta,
.free_sta = ath_rate_free_sta,
};
-static void ath_setup_rate_table(struct ath_softc *sc,
- struct ath_rate_table *rate_table)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- rate_table->rateCodeToIndex[i] = (u8)-1;
-
- for (i = 0; i < rate_table->rate_cnt; i++) {
- u8 code = rate_table->info[i].ratecode;
- u8 cix = rate_table->info[i].ctrl_rate;
- u8 sh = rate_table->info[i].short_preamble;
-
- rate_table->rateCodeToIndex[code] = i;
- rate_table->rateCodeToIndex[code | sh] = i;
-
- rate_table->info[i].lpAckDuration =
- ath9k_hw_computetxtime(sc->sc_ah, rate_table,
- WLAN_CTRL_FRAME_SIZE,
- cix,
- false);
- rate_table->info[i].spAckDuration =
- ath9k_hw_computetxtime(sc->sc_ah, rate_table,
- WLAN_CTRL_FRAME_SIZE,
- cix,
- true);
- }
-}
-
void ath_rate_attach(struct ath_softc *sc)
{
sc->hw_rate_table[ATH9K_MODE_11B] =
@@ -1651,12 +1743,6 @@ void ath_rate_attach(struct ath_softc *sc)
&ar5416_11ng_ratetable;
sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] =
&ar5416_11ng_ratetable;
-
- ath_setup_rate_table(sc, &ar5416_11b_ratetable);
- ath_setup_rate_table(sc, &ar5416_11a_ratetable);
- ath_setup_rate_table(sc, &ar5416_11g_ratetable);
- ath_setup_rate_table(sc, &ar5416_11na_ratetable);
- ath_setup_rate_table(sc, &ar5416_11ng_ratetable);
}
int ath_rate_control_register(void)
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h
index 97c60d12e8aa..199a3ce57d64 100644
--- a/drivers/net/wireless/ath9k/rc.h
+++ b/drivers/net/wireless/ath9k/rc.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2004 Sam Leffler, Errno Consulting
* Copyright (c) 2004 Video54 Technologies, Inc.
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -19,13 +19,12 @@
#ifndef RC_H
#define RC_H
-#include "ath9k.h"
-
struct ath_softc;
#define ATH_RATE_MAX 30
#define RATE_TABLE_SIZE 64
#define MAX_TX_RATE_PHY 48
+#define WLAN_CTRL_FRAME_SIZE (2+2+6+4)
/* VALID_ALL - valid for 20/40/Legacy,
* VALID - Legacy only,
@@ -39,6 +38,20 @@ struct ath_softc;
#define VALID_2040 (VALID_20|VALID_40)
#define VALID_ALL (VALID_2040|VALID)
+enum {
+ WLAN_RC_PHY_OFDM,
+ WLAN_RC_PHY_CCK,
+ WLAN_RC_PHY_HT_20_SS,
+ WLAN_RC_PHY_HT_20_DS,
+ WLAN_RC_PHY_HT_40_SS,
+ WLAN_RC_PHY_HT_40_DS,
+ WLAN_RC_PHY_HT_20_SS_HGI,
+ WLAN_RC_PHY_HT_20_DS_HGI,
+ WLAN_RC_PHY_HT_40_SS_HGI,
+ WLAN_RC_PHY_HT_40_DS_HGI,
+ WLAN_RC_PHY_MAX
+};
+
#define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \
|| (_phy == WLAN_RC_PHY_HT_40_DS) \
|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
@@ -90,7 +103,6 @@ struct ath_softc;
*/
struct ath_rate_table {
int rate_cnt;
- u8 rateCodeToIndex[256];
struct {
int valid;
int valid_single_stream;
@@ -108,8 +120,6 @@ struct ath_rate_table {
u8 sgi_index;
u8 ht_index;
u32 max_4ms_framelen;
- u16 lpAckDuration;
- u16 spAckDuration;
} info[RATE_TABLE_SIZE];
u32 probe_interval;
u32 rssi_reduce_interval;
@@ -184,11 +194,19 @@ struct ath_rate_priv {
struct ath_rate_softc *asc;
};
+enum ath9k_internal_frame_type {
+ ATH9K_NOT_INTERNAL,
+ ATH9K_INT_PAUSE,
+ ATH9K_INT_UNPAUSE
+};
+
struct ath_tx_info_priv {
+ struct ath_wiphy *aphy;
struct ath_tx_status tx;
int n_frames;
int n_bad_frames;
bool update_rc;
+ enum ath9k_internal_frame_type frame_type;
};
#define ATH_TX_INFO_PRIV(tx_info) \
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 462e08c3d09d..71cb18d6757d 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,28 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
+#include "ath9k.h"
+
+static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
+ struct ieee80211_hdr *hdr)
+{
+ struct ieee80211_hw *hw = sc->pri_wiphy->hw;
+ int i;
+
+ spin_lock_bh(&sc->wiphy_lock);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ struct ath_wiphy *aphy = sc->sec_wiphy[i];
+ if (aphy == NULL)
+ continue;
+ if (compare_ether_addr(hdr->addr1, aphy->hw->wiphy->perm_addr)
+ == 0) {
+ hw = aphy->hw;
+ break;
+ }
+ }
+ spin_unlock_bh(&sc->wiphy_lock);
+ return hw;
+}
/*
* Setup and link descriptors.
@@ -26,7 +47,7 @@
*/
static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath_desc *ds;
struct sk_buff *skb;
@@ -79,7 +100,7 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
return (tsf & ~0x7fff) | rstamp;
}
-static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len)
+static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask)
{
struct sk_buff *skb;
u32 off;
@@ -97,11 +118,11 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len)
* Unfortunately this means we may get 8 KB here from the
* kernel... and that is actually what is observed on some
* systems :( */
- skb = dev_alloc_skb(len + sc->sc_cachelsz - 1);
+ skb = __dev_alloc_skb(len + sc->cachelsz - 1, gfp_mask);
if (skb != NULL) {
- off = ((unsigned long) skb->data) % sc->sc_cachelsz;
+ off = ((unsigned long) skb->data) % sc->cachelsz;
if (off != 0)
- skb_reserve(skb, sc->sc_cachelsz - off);
+ skb_reserve(skb, sc->cachelsz - off);
} else {
DPRINTF(sc, ATH_DBG_FATAL,
"skbuff alloc of size %u failed\n", len);
@@ -123,10 +144,12 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
struct ieee80211_hdr *hdr;
u8 ratecode;
__le16 fc;
+ struct ieee80211_hw *hw;
hdr = (struct ieee80211_hdr *)skb->data;
fc = hdr->frame_control;
memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
+ hw = ath_get_virt_hw(sc, hdr);
if (ds->ds_rxstat.rs_more) {
/*
@@ -135,7 +158,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
* discard the frame. Enable this if you want to see
* error frames in Monitor mode.
*/
- if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_MONITOR)
+ if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR)
goto rx_next;
} else if (ds->ds_rxstat.rs_status != 0) {
if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
@@ -161,7 +184,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
* decryption and MIC failures. For monitor mode,
* we also ignore the CRC error.
*/
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR) {
+ if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) {
if (ds->ds_rxstat.rs_status &
~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
ATH9K_RXERR_CRC))
@@ -186,7 +209,6 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
rx_status->rate_idx = ratecode & 0x7f;
} else {
int i = 0, cur_band, n_rates;
- struct ieee80211_hw *hw = sc->hw;
cur_band = hw->conf.channel->band;
n_rates = sc->sbands[cur_band].n_bitrates;
@@ -208,9 +230,9 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
}
rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
- rx_status->band = sc->hw->conf.channel->band;
- rx_status->freq = sc->hw->conf.channel->center_freq;
- rx_status->noise = sc->sc_ani.sc_noise_floor;
+ rx_status->band = hw->conf.channel->band;
+ rx_status->freq = hw->conf.channel->center_freq;
+ rx_status->noise = sc->ani.noise_floor;
rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi;
rx_status->antenna = ds->ds_rxstat.rs_antenna;
@@ -233,7 +255,7 @@ rx_next:
static void ath_opmode_init(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
u32 rfilt, mfilt[2];
/* configure rx filter */
@@ -241,14 +263,14 @@ static void ath_opmode_init(struct ath_softc *sc)
ath9k_hw_setrxfilter(ah, rfilt);
/* configure bssid mask */
- if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
- ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+ ath9k_hw_setbssidmask(sc);
/* configure operational mode */
ath9k_hw_setopmode(ah);
/* Handle any link-level address change. */
- ath9k_hw_setmac(ah, sc->sc_myaddr);
+ ath9k_hw_setmac(ah, sc->sc_ah->macaddr);
/* calculate and install multicast filter */
mfilt[0] = mfilt[1] = ~0;
@@ -267,11 +289,11 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
spin_lock_init(&sc->rx.rxbuflock);
sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
- min(sc->sc_cachelsz,
+ min(sc->cachelsz,
(u16)64));
DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
- sc->sc_cachelsz, sc->rx.bufsize);
+ sc->cachelsz, sc->rx.bufsize);
/* Initialize rx descriptors */
@@ -284,22 +306,22 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
}
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
- skb = ath_rxbuf_alloc(sc, sc->rx.bufsize);
+ skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
if (skb == NULL) {
error = -ENOMEM;
break;
}
bf->bf_mpdu = skb;
- bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data,
+ bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
sc->rx.bufsize,
- PCI_DMA_FROMDEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev,
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(sc->dev,
bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
DPRINTF(sc, ATH_DBG_CONFIG,
- "pci_dma_mapping_error() on RX init\n");
+ "dma_mapping_error() on RX init\n");
error = -ENOMEM;
break;
}
@@ -322,8 +344,13 @@ void ath_rx_cleanup(struct ath_softc *sc)
list_for_each_entry(bf, &sc->rx.rxbuf, list) {
skb = bf->bf_mpdu;
- if (skb)
+ if (skb) {
+ dma_unmap_single(sc->dev,
+ bf->bf_buf_addr,
+ sc->rx.bufsize,
+ DMA_FROM_DEVICE);
dev_kfree_skb(skb);
+ }
}
if (sc->rx.rxdma.dd_desc_len != 0)
@@ -360,26 +387,39 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
| ATH9K_RX_FILTER_MCAST;
/* If not a STA, enable processing of Probe Requests */
- if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_STATION)
+ if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
rfilt |= ATH9K_RX_FILTER_PROBEREQ;
- /* Can't set HOSTAP into promiscous mode */
- if (((sc->sc_ah->ah_opmode != NL80211_IFTYPE_AP) &&
+ /*
+ * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station
+ * mode interface or when in monitor mode. AP mode does not need this
+ * since it receives all in-BSS frames anyway.
+ */
+ if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
(sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
- (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR)) {
+ (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR))
rfilt |= ATH9K_RX_FILTER_PROM;
- /* ??? To prevent from sending ACK */
- rfilt &= ~ATH9K_RX_FILTER_UCAST;
- }
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION ||
- sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)
+ if (sc->rx.rxfilter & FIF_CONTROL)
+ rfilt |= ATH9K_RX_FILTER_CONTROL;
+
+ if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
+ !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC))
+ rfilt |= ATH9K_RX_FILTER_MYBEACON;
+ else
rfilt |= ATH9K_RX_FILTER_BEACON;
- /* If in HOSTAP mode, want to enable reception of PSPOLL frames
- & beacon frames */
- if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP)
- rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL);
+ /* If in HOSTAP mode, want to enable reception of PSPOLL frames */
+ if (sc->sc_ah->opmode == NL80211_IFTYPE_AP)
+ rfilt |= ATH9K_RX_FILTER_PSPOLL;
+
+ if (sc->sec_wiphy) {
+ /* TODO: only needed if more than one BSSID is in use in
+ * station/adhoc mode */
+ /* TODO: for older chips, may need to add ATH9K_RX_FILTER_PROM
+ */
+ rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
+ }
return rfilt;
@@ -388,7 +428,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
int ath_startrecv(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath_buf *bf, *tbf;
spin_lock_bh(&sc->rx.rxbuflock);
@@ -418,13 +458,12 @@ start_recv:
bool ath_stoprecv(struct ath_softc *sc)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
bool stopped;
ath9k_hw_stoppcurecv(ah);
ath9k_hw_setrxfilter(ah, 0);
stopped = ath9k_hw_stopdmarecv(ah);
- mdelay(3); /* 3ms is long enough for 1 frame */
sc->rx.rxlink = NULL;
return stopped;
@@ -449,7 +488,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
struct ath_desc *ds;
struct sk_buff *skb = NULL, *requeue_skb;
struct ieee80211_rx_status rx_status;
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ieee80211_hdr *hdr;
int hdrlen, padsize, retval;
bool decrypt_error = false;
@@ -524,9 +563,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
* 1. accessing the frame
* 2. requeueing the same buffer to h/w
*/
- pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr,
+ dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
sc->rx.bufsize,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
/*
* If we're asked to flush receive queue, directly
@@ -547,7 +586,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
/* Ensure we always have an skb to requeue once we are done
* processing the current buffer's skb */
- requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize);
+ requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_ATOMIC);
/* If there is no memory we ignore the current RX'd frame,
* tell hardware it can give us a new frame using the old
@@ -557,9 +596,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
goto requeue;
/* Unmap the frame */
- pci_unmap_single(sc->pdev, bf->bf_buf_addr,
+ dma_unmap_single(sc->dev, bf->bf_buf_addr,
sc->rx.bufsize,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
skb_put(skb, ds->ds_rxstat.rs_datalen);
skb->protocol = cpu_to_be16(ETH_P_CONTROL);
@@ -590,24 +629,52 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
&& !decrypt_error && skb->len >= hdrlen + 4) {
keyix = skb->data[hdrlen + 3] >> 6;
- if (test_bit(keyix, sc->sc_keymap))
+ if (test_bit(keyix, sc->keymap))
rx_status.flag |= RX_FLAG_DECRYPTED;
}
+ if (ah->sw_mgmt_crypto &&
+ (rx_status.flag & RX_FLAG_DECRYPTED) &&
+ ieee80211_is_mgmt(hdr->frame_control)) {
+ /* Use software decrypt for management frames. */
+ rx_status.flag &= ~RX_FLAG_DECRYPTED;
+ }
/* Send the frame to mac80211 */
- __ieee80211_rx(sc->hw, skb, &rx_status);
+ if (hdr->addr1[5] & 0x01) {
+ int i;
+ /*
+ * Deliver broadcast/multicast frames to all suitable
+ * virtual wiphys.
+ */
+ /* TODO: filter based on channel configuration */
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ struct ath_wiphy *aphy = sc->sec_wiphy[i];
+ struct sk_buff *nskb;
+ if (aphy == NULL)
+ continue;
+ nskb = skb_copy(skb, GFP_ATOMIC);
+ if (nskb)
+ __ieee80211_rx(aphy->hw, nskb,
+ &rx_status);
+ }
+ __ieee80211_rx(sc->hw, skb, &rx_status);
+ } else {
+ /* Deliver unicast frames based on receiver address */
+ __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb,
+ &rx_status);
+ }
/* We will now give hardware our shiny new allocated skb */
bf->bf_mpdu = requeue_skb;
- bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data,
+ bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
sc->rx.bufsize,
- PCI_DMA_FROMDEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev,
+ DMA_FROM_DEVICE);
+ if (unlikely(dma_mapping_error(sc->dev,
bf->bf_buf_addr))) {
dev_kfree_skb_any(requeue_skb);
bf->bf_mpdu = NULL;
DPRINTF(sc, ATH_DBG_CONFIG,
- "pci_dma_mapping_error() on RX\n");
+ "dma_mapping_error() on RX\n");
break;
}
bf->bf_dmacontext = bf->bf_buf_addr;
@@ -622,6 +689,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
} else {
sc->rx.rxotherant = 0;
}
+
+ if (ieee80211_is_beacon(hdr->frame_control) &&
+ (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) {
+ sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
+ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+ }
requeue:
list_move_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_buf_link(sc, bf);
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath9k/reg.h
index 9fedb4911bc3..52605246679f 100644
--- a/drivers/net/wireless/ath9k/reg.h
+++ b/drivers/net/wireless/ath9k/reg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -67,7 +67,7 @@
#define AR_DMASIZE_512B 0x00000007
#define AR_TXCFG 0x0030
-#define AR_TXCFG_DMASZ_MASK 0x00000003
+#define AR_TXCFG_DMASZ_MASK 0x00000007
#define AR_TXCFG_DMASZ_4B 0
#define AR_TXCFG_DMASZ_8B 1
#define AR_TXCFG_DMASZ_16B 2
@@ -158,13 +158,6 @@
#define AR_CST_TIMEOUT_LIMIT 0xFFFF0000
#define AR_CST_TIMEOUT_LIMIT_S 16
-#define AR_SREV_VERSION_9100 0x014
-
-#define AR_SREV_5416_V20_OR_LATER(_ah) \
- (AR_SREV_9100((_ah)) || AR_SREV_5416_20_OR_LATER(_ah))
-#define AR_SREV_5416_V22_OR_LATER(_ah) \
- (AR_SREV_9100((_ah)) || AR_SREV_5416_22_OR_LATER(_ah))
-
#define AR_ISR 0x0080
#define AR_ISR_RXOK 0x00000001
#define AR_ISR_RXDESC 0x00000002
@@ -733,6 +726,7 @@
#define AR_SREV_REVISION_5416_10 0
#define AR_SREV_REVISION_5416_20 1
#define AR_SREV_REVISION_5416_22 2
+#define AR_SREV_VERSION_9100 0x14
#define AR_SREV_VERSION_9160 0x40
#define AR_SREV_REVISION_9160_10 0
#define AR_SREV_REVISION_9160_11 1
@@ -745,45 +739,60 @@
#define AR_SREV_REVISION_9285_11 1
#define AR_SREV_REVISION_9285_12 2
-#define AR_SREV_9100_OR_LATER(_ah) \
- (((_ah)->ah_macVersion >= AR_SREV_VERSION_5416_PCIE))
+#define AR_SREV_5416(_ah) \
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
+ ((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE))
#define AR_SREV_5416_20_OR_LATER(_ah) \
- (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \
- ((_ah)->ah_macRev >= AR_SREV_REVISION_5416_20))
+ (((AR_SREV_5416(_ah)) && \
+ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20)) || \
+ ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
#define AR_SREV_5416_22_OR_LATER(_ah) \
- (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \
- ((_ah)->ah_macRev >= AR_SREV_REVISION_5416_22))
+ (((AR_SREV_5416(_ah)) && \
+ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \
+ ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+
+#define AR_SREV_9100(ah) \
+ ((ah->hw_version.macVersion) == AR_SREV_VERSION_9100)
+#define AR_SREV_9100_OR_LATER(_ah) \
+ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+
#define AR_SREV_9160(_ah) \
- (((_ah)->ah_macVersion == AR_SREV_VERSION_9160))
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9160))
#define AR_SREV_9160_10_OR_LATER(_ah) \
- (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160))
+ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160))
#define AR_SREV_9160_11(_ah) \
- (AR_SREV_9160(_ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9160_11))
+ (AR_SREV_9160(_ah) && \
+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9160_11))
#define AR_SREV_9280(_ah) \
- (((_ah)->ah_macVersion == AR_SREV_VERSION_9280))
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280))
#define AR_SREV_9280_10_OR_LATER(_ah) \
- (((_ah)->ah_macVersion >= AR_SREV_VERSION_9280))
+ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9280))
#define AR_SREV_9280_20(_ah) \
- (((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \
- ((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20))
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
+ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20))
#define AR_SREV_9280_20_OR_LATER(_ah) \
- (((_ah)->ah_macVersion > AR_SREV_VERSION_9280) || \
- (((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \
- ((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20)))
+ (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9280) || \
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
+ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20)))
-#define AR_SREV_9285(_ah) (((_ah)->ah_macVersion == AR_SREV_VERSION_9285))
+#define AR_SREV_9285(_ah) \
+ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285))
#define AR_SREV_9285_10_OR_LATER(_ah) \
- (((_ah)->ah_macVersion >= AR_SREV_VERSION_9285))
+ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285))
#define AR_SREV_9285_11(_ah) \
- (AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_11))
+ (AR_SREV_9285(ah) && \
+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_11))
#define AR_SREV_9285_11_OR_LATER(_ah) \
- (((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \
- (AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_11)))
+ (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
+ (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
+ AR_SREV_REVISION_9285_11)))
#define AR_SREV_9285_12(_ah) \
- (AR_SREV_9280(ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9285_12))
+ (AR_SREV_9285(ah) && \
+ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_12))
#define AR_SREV_9285_12_OR_LATER(_ah) \
- (((_ah)->ah_macVersion > AR_SREV_VERSION_9285) || \
- (AR_SREV_9285(ah) && ((_ah)->ah_macRev >= AR_SREV_REVISION_9285_12)))
+ (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
+ (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
+ AR_SREV_REVISION_9285_12)))
#define AR_RADIO_SREV_MAJOR 0xf0
#define AR_RAD5133_SREV_MAJOR 0xc0
@@ -875,12 +884,15 @@ enum {
#define AR_NUM_GPIO 14
#define AR928X_NUM_GPIO 10
+#define AR9285_NUM_GPIO 12
#define AR_GPIO_IN_OUT 0x4048
#define AR_GPIO_IN_VAL 0x0FFFC000
#define AR_GPIO_IN_VAL_S 14
#define AR928X_GPIO_IN_VAL 0x000FFC00
#define AR928X_GPIO_IN_VAL_S 10
+#define AR9285_GPIO_IN_VAL 0x00FFF000
+#define AR9285_GPIO_IN_VAL_S 12
#define AR_GPIO_OE_OUT 0x404c
#define AR_GPIO_OE_OUT_DRV 0x3
@@ -894,14 +906,24 @@ enum {
#define AR_GPIO_INTR_POL_VAL_S 0
#define AR_GPIO_INPUT_EN_VAL 0x4054
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2
+#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008
+#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_S 3
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_DEF 0x00000010
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S 4
#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF 0x00000080
#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S 7
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB 0x00001000
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S 12
#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB 0x00008000
#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S 15
#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000
#define AR_GPIO_JTAG_DISABLE 0x00020000
#define AR_GPIO_INPUT_MUX1 0x4058
+#define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000
+#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16
#define AR_GPIO_INPUT_MUX2 0x405c
#define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f
@@ -940,7 +962,7 @@ enum {
#define AR_RTC_BASE 0x00020000
#define AR_RTC_RC \
- (AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000
+ ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000)
#define AR_RTC_RC_M 0x00000003
#define AR_RTC_RC_MAC_WARM 0x00000001
#define AR_RTC_RC_MAC_COLD 0x00000002
@@ -948,7 +970,7 @@ enum {
#define AR_RTC_RC_WARM_RESET 0x00000008
#define AR_RTC_PLL_CONTROL \
- (AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014
+ ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014)
#define AR_RTC_PLL_DIV 0x0000001f
#define AR_RTC_PLL_DIV_S 0
@@ -957,8 +979,6 @@ enum {
#define AR_RTC_PLL_CLKSEL 0x00000300
#define AR_RTC_PLL_CLKSEL_S 8
-
-
#define AR_RTC_RESET \
((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0040) : 0x7040)
#define AR_RTC_RESET_EN (0x00000001)
@@ -995,6 +1015,12 @@ enum {
#define AR_RTC_INTR_MASK \
((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0058) : 0x7058)
+/* RTC_DERIVED_* - only for AR9100 */
+
+#define AR_RTC_DERIVED_CLK (AR_RTC_BASE + 0x0038)
+#define AR_RTC_DERIVED_CLK_PERIOD 0x0000fffe
+#define AR_RTC_DERIVED_CLK_PERIOD_S 1
+
#define AR_SEQ_MASK 0x8060
#define AR_AN_RF2G1_CH0 0x7810
@@ -1021,6 +1047,10 @@ enum {
#define AR_AN_RF5G1_CH1_DB5 0x00380000
#define AR_AN_RF5G1_CH1_DB5_S 19
+#define AR_AN_TOP1 0x7890
+#define AR_AN_TOP1_DACIPMODE 0x00040000
+#define AR_AN_TOP1_DACIPMODE_S 18
+
#define AR_AN_TOP2 0x7894
#define AR_AN_TOP2_XPABIAS_LVL 0xC0000000
#define AR_AN_TOP2_XPABIAS_LVL_S 30
@@ -1181,18 +1211,7 @@ enum {
#define AR_CFP_VAL 0x0000FFFF
#define AR_RX_FILTER 0x803C
-#define AR_RX_FILTER_ALL 0x00000000
-#define AR_RX_UCAST 0x00000001
-#define AR_RX_MCAST 0x00000002
-#define AR_RX_BCAST 0x00000004
-#define AR_RX_CONTROL 0x00000008
-#define AR_RX_BEACON 0x00000010
-#define AR_RX_PROM 0x00000020
-#define AR_RX_PROBE_REQ 0x00000080
-#define AR_RX_MY_BEACON 0x00000200
#define AR_RX_COMPR_BAR 0x00000400
-#define AR_RX_COMPR_BA 0x00000800
-#define AR_RX_UNCOM_BA_BAR 0x00001000
#define AR_MCAST_FIL0 0x8040
#define AR_MCAST_FIL1 0x8044
@@ -1236,6 +1255,8 @@ enum {
#define AR_AES_MUTE_MASK1 0x8060
#define AR_AES_MUTE_MASK1_SEQ 0x0000FFFF
+#define AR_AES_MUTE_MASK1_FC_MGMT 0xFFFF0000
+#define AR_AES_MUTE_MASK1_FC_MGMT_S 16
#define AR_GATED_CLKS 0x8064
#define AR_GATED_CLKS_TX 0x00000002
@@ -1370,8 +1391,8 @@ enum {
#define AR_PHY_COUNTMAX (3 << 22)
#define AR_MIBCNT_INTRMASK (3 << 22)
-#define AR_TSF_THRESHOLD 0x813c
-#define AR_TSF_THRESHOLD_VAL 0x0000FFFF
+#define AR_TSFOOR_THRESHOLD 0x813c
+#define AR_TSFOOR_THRESHOLD_VAL 0x0000FFFF
#define AR_PHY_ERR_EIFS_MASK 8144
@@ -1460,6 +1481,10 @@ enum {
#define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700
#define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380
+#define AR_PCU_MISC_MODE2 0x8344
+#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE 0x00000002
+#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT 0x00000004
+
#define AR_KEYTABLE_0 0x8800
#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32))
#define AR_KEY_CACHE_SIZE 128
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c
index 64043e99facf..4ca625102291 100644
--- a/drivers/net/wireless/ath9k/regd.c
+++ b/drivers/net/wireless/ath9k/regd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -16,998 +16,504 @@
#include <linux/kernel.h>
#include <linux/slab.h>
-#include "core.h"
-#include "hw.h"
-#include "regd.h"
+#include "ath9k.h"
#include "regd_common.h"
-static int ath9k_regd_chansort(const void *a, const void *b)
-{
- const struct ath9k_channel *ca = a;
- const struct ath9k_channel *cb = b;
+/*
+ * This is a set of common rules used by our world regulatory domains.
+ * We have 12 world regulatory domains. To save space we consolidate
+ * the regulatory domains in 5 structures by frequency and change
+ * the flags on our reg_notifier() on a case by case basis.
+ */
- return (ca->channel == cb->channel) ?
- (ca->channelFlags & CHAN_FLAGS) -
- (cb->channelFlags & CHAN_FLAGS) : ca->channel - cb->channel;
+/* Only these channels all allow active scan on all world regulatory domains */
+#define ATH9K_2GHZ_CH01_11 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
+
+/* We enable active scan on these a case by case basis by regulatory domain */
+#define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\
+ NL80211_RRF_PASSIVE_SCAN)
+#define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\
+ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
+
+/* We allow IBSS on these on a case by case basis by regulatory domain */
+#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 40, 0, 30,\
+ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+#define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 40, 0, 30,\
+ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+#define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 40, 0, 30,\
+ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+
+#define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \
+ ATH9K_2GHZ_CH12_13, \
+ ATH9K_2GHZ_CH14
+
+#define ATH9K_5GHZ_ALL ATH9K_5GHZ_5150_5350, \
+ ATH9K_5GHZ_5470_5850
+/* This one skips what we call "mid band" */
+#define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \
+ ATH9K_5GHZ_5725_5850
+
+/* Can be used for:
+ * 0x60, 0x61, 0x62 */
+static const struct ieee80211_regdomain ath9k_world_regdom_60_61_62 = {
+ .n_reg_rules = 5,
+ .alpha2 = "99",
+ .reg_rules = {
+ ATH9K_2GHZ_ALL,
+ ATH9K_5GHZ_ALL,
+ }
+};
+
+/* Can be used by 0x63 and 0x65 */
+static const struct ieee80211_regdomain ath9k_world_regdom_63_65 = {
+ .n_reg_rules = 4,
+ .alpha2 = "99",
+ .reg_rules = {
+ ATH9K_2GHZ_CH01_11,
+ ATH9K_2GHZ_CH12_13,
+ ATH9K_5GHZ_NO_MIDBAND,
+ }
+};
+
+/* Can be used by 0x64 only */
+static const struct ieee80211_regdomain ath9k_world_regdom_64 = {
+ .n_reg_rules = 3,
+ .alpha2 = "99",
+ .reg_rules = {
+ ATH9K_2GHZ_CH01_11,
+ ATH9K_5GHZ_NO_MIDBAND,
+ }
+};
+
+/* Can be used by 0x66 and 0x69 */
+static const struct ieee80211_regdomain ath9k_world_regdom_66_69 = {
+ .n_reg_rules = 3,
+ .alpha2 = "99",
+ .reg_rules = {
+ ATH9K_2GHZ_CH01_11,
+ ATH9K_5GHZ_ALL,
+ }
+};
+
+/* Can be used by 0x67, 0x6A and 0x68 */
+static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = {
+ .n_reg_rules = 4,
+ .alpha2 = "99",
+ .reg_rules = {
+ ATH9K_2GHZ_CH01_11,
+ ATH9K_2GHZ_CH12_13,
+ ATH9K_5GHZ_ALL,
+ }
+};
+
+static inline bool is_wwr_sku(u16 regd)
+{
+ return ((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
+ (regd == WORLD);
}
-static void
-ath9k_regd_sort(void *a, u32 n, u32 size, ath_hal_cmp_t *cmp)
+static u16 ath9k_regd_get_eepromRD(struct ath_hw *ah)
{
- u8 *aa = a;
- u8 *ai, *t;
-
- for (ai = aa + size; --n >= 1; ai += size)
- for (t = ai; t > aa; t -= size) {
- u8 *u = t - size;
- if (cmp(u, t) <= 0)
- break;
- swap_array(u, t, size);
- }
+ return ah->regulatory.current_rd & ~WORLDWIDE_ROAMING_FLAG;
}
-static u16 ath9k_regd_get_eepromRD(struct ath_hal *ah)
+bool ath9k_is_world_regd(struct ath_hw *ah)
{
- return ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG;
+ return is_wwr_sku(ath9k_regd_get_eepromRD(ah));
}
-static bool ath9k_regd_is_chan_bm_zero(u64 *bitmask)
+const struct ieee80211_regdomain *ath9k_default_world_regdomain(void)
{
- int i;
-
- for (i = 0; i < BMLEN; i++) {
- if (bitmask[i] != 0)
- return false;
- }
- return true;
+ /* this is the most restrictive */
+ return &ath9k_world_regdom_64;
}
-static bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah)
+const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah)
{
- u16 rd = ath9k_regd_get_eepromRD(ah);
- int i;
-
- if (rd & COUNTRY_ERD_FLAG) {
- u16 cc = rd & ~COUNTRY_ERD_FLAG;
- for (i = 0; i < ARRAY_SIZE(allCountries); i++)
- if (allCountries[i].countryCode == cc)
- return true;
- } else {
- for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
- if (regDomainPairs[i].regDmnEnum == rd)
- return true;
+ switch (ah->regulatory.regpair->regDmnEnum) {
+ case 0x60:
+ case 0x61:
+ case 0x62:
+ return &ath9k_world_regdom_60_61_62;
+ case 0x63:
+ case 0x65:
+ return &ath9k_world_regdom_63_65;
+ case 0x64:
+ return &ath9k_world_regdom_64;
+ case 0x66:
+ case 0x69:
+ return &ath9k_world_regdom_66_69;
+ case 0x67:
+ case 0x68:
+ case 0x6A:
+ return &ath9k_world_regdom_67_68_6A;
+ default:
+ WARN_ON(1);
+ return ath9k_default_world_regdomain();
}
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "invalid regulatory domain/country code 0x%x\n", rd);
- return false;
}
-static bool ath9k_regd_is_fcc_midband_supported(struct ath_hal *ah)
+/* Frequency is one where radar detection is required */
+static bool ath9k_is_radar_freq(u16 center_freq)
{
- u32 regcap;
-
- regcap = ah->ah_caps.reg_cap;
-
- if (regcap & AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND)
- return true;
- else
- return false;
+ return (center_freq >= 5260 && center_freq <= 5700);
}
-static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah,
- u16 cc)
+/*
+ * N.B: These exception rules do not apply radar freqs.
+ *
+ * - We enable adhoc (or beaconing) if allowed by 11d
+ * - We enable active scan if the channel is allowed by 11d
+ * - If no country IE has been processed and a we determine we have
+ * received a beacon on a channel we can enable active scan and
+ * adhoc (or beaconing).
+ */
+static void ath9k_reg_apply_beaconing_flags(
+ struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator)
{
- u16 rd;
- int i;
+ enum ieee80211_band band;
+ struct ieee80211_supported_band *sband;
+ const struct ieee80211_reg_rule *reg_rule;
+ struct ieee80211_channel *ch;
+ unsigned int i;
+ u32 bandwidth = 0;
+ int r;
- if (cc == CTRY_DEFAULT)
- return true;
- if (cc == CTRY_DEBUG)
- return true;
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
- rd = ath9k_regd_get_eepromRD(ah);
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "EEPROM regdomain 0x%x\n", rd);
-
- if (rd & COUNTRY_ERD_FLAG) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "EEPROM setting is country code %u\n",
- rd & ~COUNTRY_ERD_FLAG);
- return cc == (rd & ~COUNTRY_ERD_FLAG);
- }
+ if (!wiphy->bands[band])
+ continue;
- for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
- if (cc == allCountries[i].countryCode) {
-#ifdef AH_SUPPORT_11D
- if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)
- return true;
-#endif
- if (allCountries[i].regDmnEnum == rd ||
- rd == DEBUG_REG_DMN || rd == NO_ENUMRD)
- return true;
+ sband = wiphy->bands[band];
+
+ for (i = 0; i < sband->n_channels; i++) {
+
+ ch = &sband->channels[i];
+
+ if (ath9k_is_radar_freq(ch->center_freq) ||
+ (ch->flags & IEEE80211_CHAN_RADAR))
+ continue;
+
+ if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+ r = freq_reg_info(wiphy, ch->center_freq,
+ &bandwidth, &reg_rule);
+ if (r)
+ continue;
+ /*
+ * If 11d had a rule for this channel ensure
+ * we enable adhoc/beaconing if it allows us to
+ * use it. Note that we would have disabled it
+ * by applying our static world regdomain by
+ * default during init, prior to calling our
+ * regulatory_hint().
+ */
+ if (!(reg_rule->flags &
+ NL80211_RRF_NO_IBSS))
+ ch->flags &=
+ ~IEEE80211_CHAN_NO_IBSS;
+ if (!(reg_rule->flags &
+ NL80211_RRF_PASSIVE_SCAN))
+ ch->flags &=
+ ~IEEE80211_CHAN_PASSIVE_SCAN;
+ } else {
+ if (ch->beacon_found)
+ ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN);
+ }
}
}
- return false;
-}
-
-static void
-ath9k_regd_get_wmodes_nreg(struct ath_hal *ah,
- struct country_code_to_enum_rd *country,
- struct regDomain *rd5GHz,
- unsigned long *modes_allowed)
-{
- bitmap_copy(modes_allowed, ah->ah_caps.wireless_modes, ATH9K_MODE_MAX);
-
- if (test_bit(ATH9K_MODE_11G, ah->ah_caps.wireless_modes) &&
- (!country->allow11g))
- clear_bit(ATH9K_MODE_11G, modes_allowed);
- if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes) &&
- (ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a)))
- clear_bit(ATH9K_MODE_11A, modes_allowed);
-
- if (test_bit(ATH9K_MODE_11NG_HT20, ah->ah_caps.wireless_modes)
- && (!country->allow11ng20))
- clear_bit(ATH9K_MODE_11NG_HT20, modes_allowed);
-
- if (test_bit(ATH9K_MODE_11NA_HT20, ah->ah_caps.wireless_modes)
- && (!country->allow11na20))
- clear_bit(ATH9K_MODE_11NA_HT20, modes_allowed);
-
- if (test_bit(ATH9K_MODE_11NG_HT40PLUS, ah->ah_caps.wireless_modes) &&
- (!country->allow11ng40))
- clear_bit(ATH9K_MODE_11NG_HT40PLUS, modes_allowed);
-
- if (test_bit(ATH9K_MODE_11NG_HT40MINUS, ah->ah_caps.wireless_modes) &&
- (!country->allow11ng40))
- clear_bit(ATH9K_MODE_11NG_HT40MINUS, modes_allowed);
-
- if (test_bit(ATH9K_MODE_11NA_HT40PLUS, ah->ah_caps.wireless_modes) &&
- (!country->allow11na40))
- clear_bit(ATH9K_MODE_11NA_HT40PLUS, modes_allowed);
-
- if (test_bit(ATH9K_MODE_11NA_HT40MINUS, ah->ah_caps.wireless_modes) &&
- (!country->allow11na40))
- clear_bit(ATH9K_MODE_11NA_HT40MINUS, modes_allowed);
}
-bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah)
+/* Allows active scan scan on Ch 12 and 13 */
+static void ath9k_reg_apply_active_scan_flags(
+ struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator)
{
- u16 rd;
-
- rd = ath9k_regd_get_eepromRD(ah);
-
- switch (rd) {
- case FCC4_FCCA:
- case (CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG):
- return true;
- case DEBUG_REG_DMN:
- case NO_ENUMRD:
- if (ah->ah_countryCode == CTRY_UNITED_STATES_FCC49)
- return true;
- break;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ const struct ieee80211_reg_rule *reg_rule;
+ u32 bandwidth = 0;
+ int r;
+
+ sband = wiphy->bands[IEEE80211_BAND_2GHZ];
+
+ /*
+ * If no country IE has been received always enable active scan
+ * on these channels. This is only done for specific regulatory SKUs
+ */
+ if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+ ch = &sband->channels[11]; /* CH 12 */
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ ch = &sband->channels[12]; /* CH 13 */
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+ return;
}
- return false;
-}
-static struct country_code_to_enum_rd*
-ath9k_regd_find_country(u16 countryCode)
-{
- int i;
+ /*
+ * If a country IE has been recieved check its rule for this
+ * channel first before enabling active scan. The passive scan
+ * would have been enforced by the initial processing of our
+ * custom regulatory domain.
+ */
- for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
- if (allCountries[i].countryCode == countryCode)
- return &allCountries[i];
+ ch = &sband->channels[11]; /* CH 12 */
+ r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
+ if (!r) {
+ if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
}
- return NULL;
-}
-
-static u16 ath9k_regd_get_default_country(struct ath_hal *ah)
-{
- u16 rd;
- int i;
-
- rd = ath9k_regd_get_eepromRD(ah);
- if (rd & COUNTRY_ERD_FLAG) {
- struct country_code_to_enum_rd *country = NULL;
- u16 cc = rd & ~COUNTRY_ERD_FLAG;
- country = ath9k_regd_find_country(cc);
- if (country != NULL)
- return cc;
+ ch = &sband->channels[12]; /* CH 13 */
+ r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
+ if (!r) {
+ if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+ ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
}
-
- for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
- if (regDomainPairs[i].regDmnEnum == rd) {
- if (regDomainPairs[i].singleCC != 0)
- return regDomainPairs[i].singleCC;
- else
- i = ARRAY_SIZE(regDomainPairs);
- }
- return CTRY_DEFAULT;
}
-static bool ath9k_regd_is_valid_reg_domain(int regDmn,
- struct regDomain *rd)
+/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
+void ath9k_reg_apply_radar_flags(struct wiphy *wiphy)
{
- int i;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_channel *ch;
+ unsigned int i;
- for (i = 0; i < ARRAY_SIZE(regDomains); i++) {
- if (regDomains[i].regDmnEnum == regDmn) {
- if (rd != NULL) {
- memcpy(rd, &regDomains[i],
- sizeof(struct regDomain));
- }
- return true;
- }
- }
- return false;
-}
+ if (!wiphy->bands[IEEE80211_BAND_5GHZ])
+ return;
-static bool ath9k_regd_is_valid_reg_domainPair(int regDmnPair)
-{
- int i;
+ sband = wiphy->bands[IEEE80211_BAND_5GHZ];
- if (regDmnPair == NO_ENUMRD)
- return false;
- for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
- if (regDomainPairs[i].regDmnEnum == regDmnPair)
- return true;
+ for (i = 0; i < sband->n_channels; i++) {
+ ch = &sband->channels[i];
+ if (!ath9k_is_radar_freq(ch->center_freq))
+ continue;
+ /* We always enable radar detection/DFS on this
+ * frequency range. Additionally we also apply on
+ * this frequency range:
+ * - If STA mode does not yet have DFS supports disable
+ * active scanning
+ * - If adhoc mode does not support DFS yet then
+ * disable adhoc in the frequency.
+ * - If AP mode does not yet support radar detection/DFS
+ * do not allow AP mode
+ */
+ if (!(ch->flags & IEEE80211_CHAN_DISABLED))
+ ch->flags |= IEEE80211_CHAN_RADAR |
+ IEEE80211_CHAN_NO_IBSS |
+ IEEE80211_CHAN_PASSIVE_SCAN;
}
- return false;
}
-static bool
-ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn,
- u16 channelFlag, struct regDomain *rd)
+void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator)
{
- int i, found;
- u64 flags = NO_REQ;
- struct reg_dmn_pair_mapping *regPair = NULL;
- int regOrg;
-
- regOrg = regDmn;
- if (regDmn == CTRY_DEFAULT) {
- u16 rdnum;
- rdnum = ath9k_regd_get_eepromRD(ah);
-
- if (!(rdnum & COUNTRY_ERD_FLAG)) {
- if (ath9k_regd_is_valid_reg_domain(rdnum, NULL) ||
- ath9k_regd_is_valid_reg_domainPair(rdnum)) {
- regDmn = rdnum;
- }
- }
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_hw *ah = sc->sc_ah;
+
+ switch (ah->regulatory.regpair->regDmnEnum) {
+ case 0x60:
+ case 0x63:
+ case 0x66:
+ case 0x67:
+ ath9k_reg_apply_beaconing_flags(wiphy, initiator);
+ break;
+ case 0x68:
+ ath9k_reg_apply_beaconing_flags(wiphy, initiator);
+ ath9k_reg_apply_active_scan_flags(wiphy, initiator);
+ break;
}
+ return;
+}
- if ((regDmn & MULTI_DOMAIN_MASK) == 0) {
- for (i = 0, found = 0;
- (i < ARRAY_SIZE(regDomainPairs)) && (!found); i++) {
- if (regDomainPairs[i].regDmnEnum == regDmn) {
- regPair = &regDomainPairs[i];
- found = 1;
- }
- }
- if (!found) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Failed to find reg domain pair %u\n", regDmn);
- return false;
- }
- if (!(channelFlag & CHANNEL_2GHZ)) {
- regDmn = regPair->regDmn5GHz;
- flags = regPair->flags5GHz;
- }
- if (channelFlag & CHANNEL_2GHZ) {
- regDmn = regPair->regDmn2GHz;
- flags = regPair->flags2GHz;
- }
- }
+int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+{
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
- found = ath9k_regd_is_valid_reg_domain(regDmn, rd);
- if (!found) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Failed to find unitary reg domain %u\n", regDmn);
- return false;
- } else {
- rd->pscan &= regPair->pscanMask;
- if (((regOrg & MULTI_DOMAIN_MASK) == 0) &&
- (flags != NO_REQ)) {
- rd->flags = flags;
- }
+ /* We always apply this */
+ ath9k_reg_apply_radar_flags(wiphy);
- rd->flags &= (channelFlag & CHANNEL_2GHZ) ?
- REG_DOMAIN_2GHZ_MASK : REG_DOMAIN_5GHZ_MASK;
- return true;
+ switch (request->initiator) {
+ case NL80211_REGDOM_SET_BY_DRIVER:
+ case NL80211_REGDOM_SET_BY_CORE:
+ case NL80211_REGDOM_SET_BY_USER:
+ break;
+ case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+ if (ath9k_is_world_regd(sc->sc_ah))
+ ath9k_reg_apply_world_flags(wiphy, request->initiator);
+ break;
}
-}
-static bool ath9k_regd_is_bit_set(int bit, u64 *bitmask)
-{
- int byteOffset, bitnum;
- u64 val;
-
- byteOffset = bit / 64;
- bitnum = bit - byteOffset * 64;
- val = ((u64) 1) << bitnum;
- if (bitmask[byteOffset] & val)
- return true;
- else
- return false;
+ return 0;
}
-static void
-ath9k_regd_add_reg_classid(u8 *regclassids, u32 maxregids,
- u32 *nregids, u8 regclassid)
+bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah)
{
+ u16 rd = ath9k_regd_get_eepromRD(ah);
int i;
- if (regclassid == 0)
- return;
-
- for (i = 0; i < maxregids; i++) {
- if (regclassids[i] == regclassid)
- return;
- if (regclassids[i] == 0)
- break;
- }
-
- if (i == maxregids)
- return;
- else {
- regclassids[i] = regclassid;
- *nregids += 1;
+ if (rd & COUNTRY_ERD_FLAG) {
+ /* EEPROM value is a country code */
+ u16 cc = rd & ~COUNTRY_ERD_FLAG;
+ for (i = 0; i < ARRAY_SIZE(allCountries); i++)
+ if (allCountries[i].countryCode == cc)
+ return true;
+ } else {
+ /* EEPROM value is a regpair value */
+ for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
+ if (regDomainPairs[i].regDmnEnum == rd)
+ return true;
}
-
- return;
+ DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
+ "invalid regulatory domain/country code 0x%x\n", rd);
+ return false;
}
-static bool
-ath9k_regd_get_eeprom_reg_ext_bits(struct ath_hal *ah,
- enum reg_ext_bitmap bit)
+/* EEPROM country code to regpair mapping */
+static struct country_code_to_enum_rd*
+ath9k_regd_find_country(u16 countryCode)
{
- return (ah->ah_currentRDExt & (1 << bit)) ? true : false;
-}
-
-#ifdef ATH_NF_PER_CHAN
+ int i;
-static void ath9k_regd_init_rf_buffer(struct ath9k_channel *ichans,
- int nchans)
-{
- int i, j, next;
-
- for (next = 0; next < nchans; next++) {
- for (i = 0; i < NUM_NF_READINGS; i++) {
- ichans[next].nfCalHist[i].currIndex = 0;
- ichans[next].nfCalHist[i].privNF =
- AR_PHY_CCA_MAX_GOOD_VALUE;
- ichans[next].nfCalHist[i].invalidNFcount =
- AR_PHY_CCA_FILTERWINDOW_LENGTH;
- for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
- ichans[next].nfCalHist[i].nfCalBuffer[j] =
- AR_PHY_CCA_MAX_GOOD_VALUE;
- }
- }
+ for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+ if (allCountries[i].countryCode == countryCode)
+ return &allCountries[i];
}
+ return NULL;
}
-#endif
-static int ath9k_regd_is_chan_present(struct ath_hal *ah,
- u16 c)
+/* EEPROM rd code to regpair mapping */
+static struct country_code_to_enum_rd*
+ath9k_regd_find_country_by_rd(int regdmn)
{
int i;
- for (i = 0; i < 150; i++) {
- if (!ah->ah_channels[i].channel)
- return -1;
- else if (ah->ah_channels[i].channel == c)
- return i;
+ for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+ if (allCountries[i].regDmnEnum == regdmn)
+ return &allCountries[i];
}
-
- return -1;
+ return NULL;
}
-static bool
-ath9k_regd_add_channel(struct ath_hal *ah,
- u16 c,
- u16 c_lo,
- u16 c_hi,
- u16 maxChan,
- u8 ctl,
- int pos,
- struct regDomain rd5GHz,
- struct RegDmnFreqBand *fband,
- struct regDomain *rd,
- const struct cmode *cm,
- struct ath9k_channel *ichans,
- bool enableExtendedChannels)
+/* Returns the map of the EEPROM set RD to a country code */
+static u16 ath9k_regd_get_default_country(u16 rd)
{
- struct ath9k_channel *chan;
- int ret;
- u32 channelFlags = 0;
- u8 privFlags = 0;
-
- if (!(c_lo <= c && c <= c_hi)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "c %u out of range [%u..%u]\n",
- c, c_lo, c_hi);
- return false;
- }
- if ((fband->channelBW == CHANNEL_HALF_BW) &&
- !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping %u half rate channel\n", c);
- return false;
- }
-
- if ((fband->channelBW == CHANNEL_QUARTER_BW) &&
- !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping %u quarter rate channel\n", c);
- return false;
- }
-
- if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "c %u > maxChan %u\n", c, maxChan);
- return false;
- }
-
- if ((fband->usePassScan & IS_ECM_CHAN) && !enableExtendedChannels) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping ecm channel\n");
- return false;
- }
-
- if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == NL80211_IFTYPE_AP)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping HOSTAP channel\n");
- return false;
- }
-
- if (IS_HT40_MODE(cm->mode) &&
- !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_FCC_DFS_HT40)) &&
- (fband->useDfs) &&
- (rd->conformanceTestLimit != MKK)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping HT40 channel (en_fcc_dfs_ht40 = 0)\n");
- return false;
- }
-
- if (IS_HT40_MODE(cm->mode) &&
- !(ath9k_regd_get_eeprom_reg_ext_bits(ah,
- REG_EXT_JAPAN_NONDFS_HT40)) &&
- !(fband->useDfs) && (rd->conformanceTestLimit == MKK)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping HT40 channel (en_jap_ht40 = 0)\n");
- return false;
- }
-
- if (IS_HT40_MODE(cm->mode) &&
- !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_JAPAN_DFS_HT40)) &&
- (fband->useDfs) &&
- (rd->conformanceTestLimit == MKK)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping HT40 channel (en_jap_dfs_ht40 = 0)\n");
- return false;
- }
-
- /* Calculate channel flags */
-
- channelFlags = cm->flags;
-
- switch (fband->channelBW) {
- case CHANNEL_HALF_BW:
- channelFlags |= CHANNEL_HALF;
- break;
- case CHANNEL_QUARTER_BW:
- channelFlags |= CHANNEL_QUARTER;
- break;
- }
-
- if (fband->usePassScan & rd->pscan)
- channelFlags |= CHANNEL_PASSIVE;
- else
- channelFlags &= ~CHANNEL_PASSIVE;
- if (fband->useDfs & rd->dfsMask)
- privFlags = CHANNEL_DFS;
- else
- privFlags = 0;
- if (rd->flags & LIMIT_FRAME_4MS)
- privFlags |= CHANNEL_4MS_LIMIT;
- if (privFlags & CHANNEL_DFS)
- privFlags |= CHANNEL_DISALLOW_ADHOC;
- if (rd->flags & ADHOC_PER_11D)
- privFlags |= CHANNEL_PER_11D_ADHOC;
-
- if (channelFlags & CHANNEL_PASSIVE) {
- if ((c < 2412) || (c > 2462)) {
- if (rd5GHz.regDmnEnum == MKK1 ||
- rd5GHz.regDmnEnum == MKK2) {
- u32 regcap = ah->ah_caps.reg_cap;
- if (!(regcap &
- (AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
- AR_EEPROM_EEREGCAP_EN_KK_U2 |
- AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) &&
- isUNII1OddChan(c)) {
- channelFlags &= ~CHANNEL_PASSIVE;
- } else {
- privFlags |= CHANNEL_DISALLOW_ADHOC;
- }
- } else {
- privFlags |= CHANNEL_DISALLOW_ADHOC;
- }
- }
- }
-
- if ((cm->mode == ATH9K_MODE_11A) ||
- (cm->mode == ATH9K_MODE_11NA_HT20) ||
- (cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
- (cm->mode == ATH9K_MODE_11NA_HT40MINUS)) {
- if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A))
- privFlags |= CHANNEL_DISALLOW_ADHOC;
- }
+ if (rd & COUNTRY_ERD_FLAG) {
+ struct country_code_to_enum_rd *country = NULL;
+ u16 cc = rd & ~COUNTRY_ERD_FLAG;
- /* Fill in channel details */
-
- ret = ath9k_regd_is_chan_present(ah, c);
- if (ret == -1) {
- chan = &ah->ah_channels[pos];
- chan->channel = c;
- chan->maxRegTxPower = fband->powerDfs;
- chan->antennaMax = fband->antennaMax;
- chan->regDmnFlags = rd->flags;
- chan->maxTxPower = AR5416_MAX_RATE_POWER;
- chan->minTxPower = AR5416_MAX_RATE_POWER;
- chan->channelFlags = channelFlags;
- chan->privFlags = privFlags;
- } else {
- chan = &ah->ah_channels[ret];
- chan->channelFlags |= channelFlags;
- chan->privFlags |= privFlags;
+ country = ath9k_regd_find_country(cc);
+ if (country != NULL)
+ return cc;
}
- /* Set CTLs */
-
- if ((cm->flags & CHANNEL_ALL) == CHANNEL_A)
- chan->conformanceTestLimit[0] = ctl;
- else if ((cm->flags & CHANNEL_ALL) == CHANNEL_B)
- chan->conformanceTestLimit[1] = ctl;
- else if ((cm->flags & CHANNEL_ALL) == CHANNEL_G)
- chan->conformanceTestLimit[2] = ctl;
-
- return (ret == -1) ? true : false;
+ return CTRY_DEFAULT;
}
-static bool ath9k_regd_japan_check(struct ath_hal *ah,
- int b,
- struct regDomain *rd5GHz)
+static struct reg_dmn_pair_mapping*
+ath9k_get_regpair(int regdmn)
{
- bool skipband = false;
int i;
- u32 regcap;
-
- for (i = 0; i < ARRAY_SIZE(j_bandcheck); i++) {
- if (j_bandcheck[i].freqbandbit == b) {
- regcap = ah->ah_caps.reg_cap;
- if ((j_bandcheck[i].eepromflagtocheck & regcap) == 0) {
- skipband = true;
- } else if ((regcap & AR_EEPROM_EEREGCAP_EN_KK_U2) ||
- (regcap & AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) {
- rd5GHz->dfsMask |= DFS_MKK4;
- rd5GHz->pscan |= PSCAN_MKK3;
- }
- break;
- }
- }
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Skipping %d freq band\n", j_bandcheck[i].freqbandbit);
-
- return skipband;
+ if (regdmn == NO_ENUMRD)
+ return NULL;
+ for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
+ if (regDomainPairs[i].regDmnEnum == regdmn)
+ return &regDomainPairs[i];
+ }
+ return NULL;
}
-bool
-ath9k_regd_init_channels(struct ath_hal *ah,
- u32 maxchans,
- u32 *nchans, u8 *regclassids,
- u32 maxregids, u32 *nregids, u16 cc,
- bool enableOutdoor,
- bool enableExtendedChannels)
+int ath9k_regd_init(struct ath_hw *ah)
{
- u16 maxChan = 7000;
struct country_code_to_enum_rd *country = NULL;
- struct regDomain rd5GHz, rd2GHz;
- const struct cmode *cm;
- struct ath9k_channel *ichans = &ah->ah_channels[0];
- int next = 0, b;
- u8 ctl;
- int regdmn;
- u16 chanSep;
- unsigned long *modes_avail;
- DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX);
-
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "cc %u %s %s\n", cc,
- enableOutdoor ? "Enable outdoor" : "",
- enableExtendedChannels ? "Enable ecm" : "");
-
- if (!ath9k_regd_is_ccode_valid(ah, cc)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Invalid country code %d\n", cc);
- return false;
- }
+ u16 regdmn;
if (!ath9k_regd_is_eeprom_valid(ah)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Invalid EEPROM contents\n");
- return false;
+ return -EINVAL;
}
- ah->ah_countryCode = ath9k_regd_get_default_country(ah);
+ regdmn = ath9k_regd_get_eepromRD(ah);
+ ah->regulatory.country_code = ath9k_regd_get_default_country(regdmn);
- if (ah->ah_countryCode == CTRY_DEFAULT) {
- ah->ah_countryCode = cc & COUNTRY_CODE_MASK;
- if ((ah->ah_countryCode == CTRY_DEFAULT) &&
- (ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT)) {
- ah->ah_countryCode = CTRY_UNITED_STATES;
- }
- }
+ if (ah->regulatory.country_code == CTRY_DEFAULT &&
+ regdmn == CTRY_DEFAULT)
+ ah->regulatory.country_code = CTRY_UNITED_STATES;
-#ifdef AH_SUPPORT_11D
- if (ah->ah_countryCode == CTRY_DEFAULT) {
- regdmn = ath9k_regd_get_eepromRD(ah);
+ if (ah->regulatory.country_code == CTRY_DEFAULT) {
country = NULL;
} else {
-#endif
- country = ath9k_regd_find_country(ah->ah_countryCode);
+ country = ath9k_regd_find_country(ah->regulatory.country_code);
if (country == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Country is NULL!!!!, cc= %d\n",
- ah->ah_countryCode);
- return false;
- } else {
+ ah->regulatory.country_code);
+ return -EINVAL;
+ } else
regdmn = country->regDmnEnum;
-#ifdef AH_SUPPORT_11D
- if (((ath9k_regd_get_eepromRD(ah) &
- WORLD_SKU_MASK) == WORLD_SKU_PREFIX) &&
- (cc == CTRY_UNITED_STATES)) {
- if (!isWwrSKU_NoMidband(ah)
- && ath9k_regd_is_fcc_midband_supported(ah))
- regdmn = FCC3_FCCA;
- else
- regdmn = FCC1_FCCA;
- }
-#endif
- }
-#ifdef AH_SUPPORT_11D
- }
-#endif
- if (!ath9k_regd_get_wmode_regdomain(ah,
- regdmn,
- ~CHANNEL_2GHZ,
- &rd5GHz)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Couldn't find unitary "
- "5GHz reg domain for country %u\n",
- ah->ah_countryCode);
- return false;
- }
- if (!ath9k_regd_get_wmode_regdomain(ah,
- regdmn,
- CHANNEL_2GHZ,
- &rd2GHz)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Couldn't find unitary 2GHz "
- "reg domain for country %u\n",
- ah->ah_countryCode);
- return false;
- }
-
- if (!isWwrSKU(ah) && ((rd5GHz.regDmnEnum == FCC1) ||
- (rd5GHz.regDmnEnum == FCC2))) {
- if (ath9k_regd_is_fcc_midband_supported(ah)) {
- if (!ath9k_regd_get_wmode_regdomain(ah,
- FCC3_FCCA,
- ~CHANNEL_2GHZ,
- &rd5GHz)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Couldn't find unitary 5GHz "
- "reg domain for country %u\n",
- ah->ah_countryCode);
- return false;
- }
- }
- }
-
- if (country == NULL) {
- modes_avail = ah->ah_caps.wireless_modes;
- } else {
- ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz, modes_allowed);
- modes_avail = modes_allowed;
-
- if (!enableOutdoor)
- maxChan = country->outdoorChanStart;
- }
-
- next = 0;
-
- if (maxchans > ARRAY_SIZE(ah->ah_channels))
- maxchans = ARRAY_SIZE(ah->ah_channels);
-
- for (cm = modes; cm < &modes[ARRAY_SIZE(modes)]; cm++) {
- u16 c, c_hi, c_lo;
- u64 *channelBM = NULL;
- struct regDomain *rd = NULL;
- struct RegDmnFreqBand *fband = NULL, *freqs;
- int8_t low_adj = 0, hi_adj = 0;
-
- if (!test_bit(cm->mode, modes_avail)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "!avail mode %d flags 0x%x\n",
- cm->mode, cm->flags);
- continue;
- }
- if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "channels 0x%x not supported "
- "by hardware\n", cm->flags);
- continue;
- }
-
- switch (cm->mode) {
- case ATH9K_MODE_11A:
- case ATH9K_MODE_11NA_HT20:
- case ATH9K_MODE_11NA_HT40PLUS:
- case ATH9K_MODE_11NA_HT40MINUS:
- rd = &rd5GHz;
- channelBM = rd->chan11a;
- freqs = &regDmn5GhzFreq[0];
- ctl = rd->conformanceTestLimit;
- break;
- case ATH9K_MODE_11B:
- rd = &rd2GHz;
- channelBM = rd->chan11b;
- freqs = &regDmn2GhzFreq[0];
- ctl = rd->conformanceTestLimit | CTL_11B;
- break;
- case ATH9K_MODE_11G:
- case ATH9K_MODE_11NG_HT20:
- case ATH9K_MODE_11NG_HT40PLUS:
- case ATH9K_MODE_11NG_HT40MINUS:
- rd = &rd2GHz;
- channelBM = rd->chan11g;
- freqs = &regDmn2Ghz11gFreq[0];
- ctl = rd->conformanceTestLimit | CTL_11G;
- break;
- default:
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "Unknown HAL mode 0x%x\n", cm->mode);
- continue;
- }
-
- if (ath9k_regd_is_chan_bm_zero(channelBM))
- continue;
-
- if ((cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
- (cm->mode == ATH9K_MODE_11NG_HT40PLUS)) {
- hi_adj = -20;
- }
-
- if ((cm->mode == ATH9K_MODE_11NA_HT40MINUS) ||
- (cm->mode == ATH9K_MODE_11NG_HT40MINUS)) {
- low_adj = 20;
- }
-
- /* XXX: Add a helper here instead */
- for (b = 0; b < 64 * BMLEN; b++) {
- if (ath9k_regd_is_bit_set(b, channelBM)) {
- fband = &freqs[b];
- if (rd5GHz.regDmnEnum == MKK1
- || rd5GHz.regDmnEnum == MKK2) {
- if (ath9k_regd_japan_check(ah,
- b,
- &rd5GHz))
- continue;
- }
-
- ath9k_regd_add_reg_classid(regclassids,
- maxregids,
- nregids,
- fband->
- regClassId);
-
- if (IS_HT40_MODE(cm->mode) && (rd == &rd5GHz)) {
- chanSep = 40;
- if (fband->lowChannel == 5280)
- low_adj += 20;
-
- if (fband->lowChannel == 5170)
- continue;
- } else
- chanSep = fband->channelSep;
-
- for (c = fband->lowChannel + low_adj;
- ((c <= (fband->highChannel + hi_adj)) &&
- (c >= (fband->lowChannel + low_adj)));
- c += chanSep) {
- if (next >= maxchans) {
- DPRINTF(ah->ah_sc,
- ATH_DBG_REGULATORY,
- "too many channels "
- "for channel table\n");
- goto done;
- }
- if (ath9k_regd_add_channel(ah,
- c, c_lo, c_hi,
- maxChan, ctl,
- next,
- rd5GHz,
- fband, rd, cm,
- ichans,
- enableExtendedChannels))
- next++;
- }
- if (IS_HT40_MODE(cm->mode) &&
- (fband->lowChannel == 5280)) {
- low_adj -= 20;
- }
- }
- }
}
-done:
- if (next != 0) {
- int i;
- if (next > ARRAY_SIZE(ah->ah_channels)) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "too many channels %u; truncating to %u\n",
- next, (int) ARRAY_SIZE(ah->ah_channels));
- next = ARRAY_SIZE(ah->ah_channels);
- }
-#ifdef ATH_NF_PER_CHAN
- ath9k_regd_init_rf_buffer(ichans, next);
-#endif
- ath9k_regd_sort(ichans, next,
- sizeof(struct ath9k_channel),
- ath9k_regd_chansort);
+ ah->regulatory.regpair = ath9k_get_regpair(regdmn);
- ah->ah_nchan = next;
-
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Channel list:\n");
- for (i = 0; i < next; i++) {
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "chan: %d flags: 0x%x\n",
- ah->ah_channels[i].channel,
- ah->ah_channels[i].channelFlags);
- }
+ if (!ah->regulatory.regpair) {
+ DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+ "No regulatory domain pair found, cannot continue\n");
+ return -EINVAL;
}
- *nchans = next;
- ah->ah_countryCode = ah->ah_countryCode;
+ if (!country)
+ country = ath9k_regd_find_country_by_rd(regdmn);
- ah->ah_currentRDInUse = regdmn;
- ah->ah_currentRD5G = rd5GHz.regDmnEnum;
- ah->ah_currentRD2G = rd2GHz.regDmnEnum;
- if (country == NULL) {
- ah->ah_iso[0] = 0;
- ah->ah_iso[1] = 0;
+ if (country) {
+ ah->regulatory.alpha2[0] = country->isoName[0];
+ ah->regulatory.alpha2[1] = country->isoName[1];
} else {
- ah->ah_iso[0] = country->isoName[0];
- ah->ah_iso[1] = country->isoName[1];
+ ah->regulatory.alpha2[0] = '0';
+ ah->regulatory.alpha2[1] = '0';
}
- return next != 0;
-}
-
-struct ath9k_channel*
-ath9k_regd_check_channel(struct ath_hal *ah,
- const struct ath9k_channel *c)
-{
- struct ath9k_channel *base, *cc;
-
- int flags = c->channelFlags & CHAN_FLAGS;
- int n, lim;
-
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "channel %u/0x%x (0x%x) requested\n",
- c->channel, c->channelFlags, flags);
-
- cc = ah->ah_curchan;
- if (cc != NULL && cc->channel == c->channel &&
- (cc->channelFlags & CHAN_FLAGS) == flags) {
- if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
- (cc->privFlags & CHANNEL_DFS))
- return NULL;
- else
- return cc;
- }
+ "Country alpha2 being used: %c%c\n"
+ "Regulatory.Regpair detected: 0x%0x\n",
+ ah->regulatory.alpha2[0], ah->regulatory.alpha2[1],
+ ah->regulatory.regpair->regDmnEnum);
- base = ah->ah_channels;
- n = ah->ah_nchan;
-
- for (lim = n; lim != 0; lim >>= 1) {
- int d;
- cc = &base[lim >> 1];
- d = c->channel - cc->channel;
- if (d == 0) {
- if ((cc->channelFlags & CHAN_FLAGS) == flags) {
- if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
- (cc->privFlags & CHANNEL_DFS))
- return NULL;
- else
- return cc;
- }
- d = flags - (cc->channelFlags & CHAN_FLAGS);
- }
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
- "channel %u/0x%x d %d\n",
- cc->channel, cc->channelFlags, d);
- if (d > 0) {
- base = cc + 1;
- lim--;
- }
- }
- DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "no match for %u/0x%x\n",
- c->channel, c->channelFlags);
- return NULL;
-}
-
-u32
-ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
- struct ath9k_channel *chan)
-{
- struct ath9k_channel *ichan = NULL;
-
- ichan = ath9k_regd_check_channel(ah, chan);
- if (!ichan)
- return 0;
-
- return ichan->antennaMax;
+ return 0;
}
-u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan)
+u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan)
{
u32 ctl = NO_CTL;
- struct ath9k_channel *ichan;
- if (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) {
+ if (!ah->regulatory.regpair ||
+ (ah->regulatory.country_code == CTRY_DEFAULT &&
+ is_wwr_sku(ath9k_regd_get_eepromRD(ah)))) {
if (IS_CHAN_B(chan))
ctl = SD_NO_CTL | CTL_11B;
else if (IS_CHAN_G(chan))
ctl = SD_NO_CTL | CTL_11G;
else
ctl = SD_NO_CTL | CTL_11A;
- } else {
- ichan = ath9k_regd_check_channel(ah, chan);
- if (ichan != NULL) {
- /* FIXME */
- if (IS_CHAN_A(ichan))
- ctl = ichan->conformanceTestLimit[0];
- else if (IS_CHAN_B(ichan))
- ctl = ichan->conformanceTestLimit[1];
- else if (IS_CHAN_G(ichan))
- ctl = ichan->conformanceTestLimit[2];
-
- if (IS_CHAN_G(chan) && (ctl & 0xf) == CTL_11B)
- ctl = (ctl & ~0xf) | CTL_11G;
- }
+ return ctl;
}
- return ctl;
-}
-void ath9k_regd_get_current_country(struct ath_hal *ah,
- struct ath9k_country_entry *ctry)
-{
- u16 rd = ath9k_regd_get_eepromRD(ah);
+ if (IS_CHAN_B(chan))
+ ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11B;
+ else if (IS_CHAN_G(chan))
+ ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11G;
+ else
+ ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11A;
- ctry->isMultidomain = false;
- if (rd == CTRY_DEFAULT)
- ctry->isMultidomain = true;
- else if (!(rd & COUNTRY_ERD_FLAG))
- ctry->isMultidomain = isWwrSKU(ah);
-
- ctry->countryCode = ah->ah_countryCode;
- ctry->regDmnEnum = ah->ah_currentRD;
- ctry->regDmn5G = ah->ah_currentRD5G;
- ctry->regDmn2G = ah->ah_currentRD2G;
- ctry->iso[0] = ah->ah_iso[0];
- ctry->iso[1] = ah->ah_iso[1];
- ctry->iso[2] = ah->ah_iso[2];
+ return ctl;
}
diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath9k/regd.h
index 512d990aa7ea..9f5fbd4eea7a 100644
--- a/drivers/net/wireless/ath9k/regd.h
+++ b/drivers/net/wireless/ath9k/regd.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -17,127 +17,8 @@
#ifndef REGD_H
#define REGD_H
-#include "ath9k.h"
-
-#define BMLEN 2
-#define BMZERO {(u64) 0, (u64) 0}
-
-#define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \
- {((((_fa >= 0) && (_fa < 64)) ? \
- (((u64) 1) << _fa) : (u64) 0) | \
- (((_fb >= 0) && (_fb < 64)) ? \
- (((u64) 1) << _fb) : (u64) 0) | \
- (((_fc >= 0) && (_fc < 64)) ? \
- (((u64) 1) << _fc) : (u64) 0) | \
- (((_fd >= 0) && (_fd < 64)) ? \
- (((u64) 1) << _fd) : (u64) 0) | \
- (((_fe >= 0) && (_fe < 64)) ? \
- (((u64) 1) << _fe) : (u64) 0) | \
- (((_ff >= 0) && (_ff < 64)) ? \
- (((u64) 1) << _ff) : (u64) 0) | \
- (((_fg >= 0) && (_fg < 64)) ? \
- (((u64) 1) << _fg) : (u64) 0) | \
- (((_fh >= 0) && (_fh < 64)) ? \
- (((u64) 1) << _fh) : (u64) 0) | \
- (((_fi >= 0) && (_fi < 64)) ? \
- (((u64) 1) << _fi) : (u64) 0) | \
- (((_fj >= 0) && (_fj < 64)) ? \
- (((u64) 1) << _fj) : (u64) 0) | \
- (((_fk >= 0) && (_fk < 64)) ? \
- (((u64) 1) << _fk) : (u64) 0) | \
- (((_fl >= 0) && (_fl < 64)) ? \
- (((u64) 1) << _fl) : (u64) 0) | \
- ((((_fa > 63) && (_fa < 128)) ? \
- (((u64) 1) << (_fa - 64)) : (u64) 0) | \
- (((_fb > 63) && (_fb < 128)) ? \
- (((u64) 1) << (_fb - 64)) : (u64) 0) | \
- (((_fc > 63) && (_fc < 128)) ? \
- (((u64) 1) << (_fc - 64)) : (u64) 0) | \
- (((_fd > 63) && (_fd < 128)) ? \
- (((u64) 1) << (_fd - 64)) : (u64) 0) | \
- (((_fe > 63) && (_fe < 128)) ? \
- (((u64) 1) << (_fe - 64)) : (u64) 0) | \
- (((_ff > 63) && (_ff < 128)) ? \
- (((u64) 1) << (_ff - 64)) : (u64) 0) | \
- (((_fg > 63) && (_fg < 128)) ? \
- (((u64) 1) << (_fg - 64)) : (u64) 0) | \
- (((_fh > 63) && (_fh < 128)) ? \
- (((u64) 1) << (_fh - 64)) : (u64) 0) | \
- (((_fi > 63) && (_fi < 128)) ? \
- (((u64) 1) << (_fi - 64)) : (u64) 0) | \
- (((_fj > 63) && (_fj < 128)) ? \
- (((u64) 1) << (_fj - 64)) : (u64) 0) | \
- (((_fk > 63) && (_fk < 128)) ? \
- (((u64) 1) << (_fk - 64)) : (u64) 0) | \
- (((_fl > 63) && (_fl < 128)) ? \
- (((u64) 1) << (_fl - 64)) : (u64) 0)))}
-
-#define DEF_REGDMN FCC1_FCCA
-#define DEF_DMN_5 FCC1
-#define DEF_DMN_2 FCCA
#define COUNTRY_ERD_FLAG 0x8000
#define WORLDWIDE_ROAMING_FLAG 0x4000
-#define SUPER_DOMAIN_MASK 0x0fff
-#define COUNTRY_CODE_MASK 0x3fff
-#define CF_INTERFERENCE (CHANNEL_CW_INT | CHANNEL_RADAR_INT)
-#define CHANNEL_14 (2484)
-#define IS_11G_CH14(_ch,_cf) \
- (((_ch) == CHANNEL_14) && ((_cf) == CHANNEL_G))
-
-#define NO_PSCAN 0x0ULL
-#define PSCAN_FCC 0x0000000000000001ULL
-#define PSCAN_FCC_T 0x0000000000000002ULL
-#define PSCAN_ETSI 0x0000000000000004ULL
-#define PSCAN_MKK1 0x0000000000000008ULL
-#define PSCAN_MKK2 0x0000000000000010ULL
-#define PSCAN_MKKA 0x0000000000000020ULL
-#define PSCAN_MKKA_G 0x0000000000000040ULL
-#define PSCAN_ETSIA 0x0000000000000080ULL
-#define PSCAN_ETSIB 0x0000000000000100ULL
-#define PSCAN_ETSIC 0x0000000000000200ULL
-#define PSCAN_WWR 0x0000000000000400ULL
-#define PSCAN_MKKA1 0x0000000000000800ULL
-#define PSCAN_MKKA1_G 0x0000000000001000ULL
-#define PSCAN_MKKA2 0x0000000000002000ULL
-#define PSCAN_MKKA2_G 0x0000000000004000ULL
-#define PSCAN_MKK3 0x0000000000008000ULL
-#define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL
-#define IS_ECM_CHAN 0x8000000000000000ULL
-
-#define isWwrSKU(_ah) \
- (((ath9k_regd_get_eepromRD((_ah)) & WORLD_SKU_MASK) == \
- WORLD_SKU_PREFIX) || \
- (ath9k_regd_get_eepromRD(_ah) == WORLD))
-
-#define isWwrSKU_NoMidband(_ah) \
- ((ath9k_regd_get_eepromRD((_ah)) == WOR3_WORLD) || \
- (ath9k_regd_get_eepromRD(_ah) == WOR4_WORLD) || \
- (ath9k_regd_get_eepromRD(_ah) == WOR5_ETSIC))
-
-#define isUNII1OddChan(ch) \
- ((ch == 5170) || (ch == 5190) || (ch == 5210) || (ch == 5230))
-
-#define IS_HT40_MODE(_mode) \
- (((_mode == ATH9K_MODE_11NA_HT40PLUS || \
- _mode == ATH9K_MODE_11NG_HT40PLUS || \
- _mode == ATH9K_MODE_11NA_HT40MINUS || \
- _mode == ATH9K_MODE_11NG_HT40MINUS) ? true : false))
-
-#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
-
-#define swap_array(_a, _b, _size) { \
- u8 *s = _b; \
- int i = _size; \
- do { \
- u8 tmp = *_a; \
- *_a++ = *s; \
- *s++ = tmp; \
- } while (--i); \
- _a -= _size; \
-}
-
-
-#define HALF_MAXCHANBW 10
#define MULTI_DOMAIN_MASK 0xFF00
@@ -147,81 +28,27 @@
#define CHANNEL_HALF_BW 10
#define CHANNEL_QUARTER_BW 5
-typedef int ath_hal_cmp_t(const void *, const void *);
-
struct reg_dmn_pair_mapping {
u16 regDmnEnum;
- u16 regDmn5GHz;
- u16 regDmn2GHz;
- u32 flags5GHz;
- u32 flags2GHz;
- u64 pscanMask;
- u16 singleCC;
-};
-
-struct ccmap {
- char isoName[3];
- u16 countryCode;
+ u16 reg_5ghz_ctl;
+ u16 reg_2ghz_ctl;
};
struct country_code_to_enum_rd {
u16 countryCode;
u16 regDmnEnum;
const char *isoName;
- const char *name;
- bool allow11g;
- bool allow11aTurbo;
- bool allow11gTurbo;
- bool allow11ng20;
- bool allow11ng40;
- bool allow11na20;
- bool allow11na40;
- u16 outdoorChanStart;
-};
-
-struct RegDmnFreqBand {
- u16 lowChannel;
- u16 highChannel;
- u8 powerDfs;
- u8 antennaMax;
- u8 channelBW;
- u8 channelSep;
- u64 useDfs;
- u64 usePassScan;
- u8 regClassId;
-};
-
-struct regDomain {
- u16 regDmnEnum;
- u8 conformanceTestLimit;
- u64 dfsMask;
- u64 pscan;
- u32 flags;
- u64 chan11a[BMLEN];
- u64 chan11a_turbo[BMLEN];
- u64 chan11a_dyn_turbo[BMLEN];
- u64 chan11b[BMLEN];
- u64 chan11g[BMLEN];
- u64 chan11g_turbo[BMLEN];
-};
-
-struct cmode {
- u32 mode;
- u32 flags;
-};
-
-#define YES true
-#define NO false
-
-struct japan_bandcheck {
- u16 freqbandbit;
- u32 eepromflagtocheck;
};
-struct common_mode_power {
- u16 lchan;
- u16 hchan;
- u8 pwrlvl;
+struct ath9k_regulatory {
+ char alpha2[2];
+ u16 country_code;
+ u16 max_power_level;
+ u32 tp_scale;
+ u16 current_rd;
+ u16 current_rd_ext;
+ int16_t power_limit;
+ struct reg_dmn_pair_mapping *regpair;
};
enum CountryCode {
@@ -406,7 +233,15 @@ enum CountryCode {
CTRY_BELGIUM2 = 5002
};
-void ath9k_regd_get_current_country(struct ath_hal *ah,
- struct ath9k_country_entry *ctry);
+bool ath9k_is_world_regd(struct ath_hw *ah);
+const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah);
+const struct ieee80211_regdomain *ath9k_default_world_regdomain(void);
+void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
+ enum nl80211_reg_initiator initiator);
+void ath9k_reg_apply_radar_flags(struct wiphy *wiphy);
+int ath9k_regd_init(struct ath_hw *ah);
+bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah);
+u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan);
+int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
#endif
diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath9k/regd_common.h
index 6df1b3b77c25..4d0e298cd1c7 100644
--- a/drivers/net/wireless/ath9k/regd_common.h
+++ b/drivers/net/wireless/ath9k/regd_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -150,1766 +150,324 @@ enum EnumRd {
MKK9_MKKC = 0xFE,
MKK9_MKKA2 = 0xFF,
- APL1 = 0x0150,
- APL2 = 0x0250,
- APL3 = 0x0350,
- APL4 = 0x0450,
- APL5 = 0x0550,
- APL6 = 0x0650,
- APL7 = 0x0750,
- APL8 = 0x0850,
- APL9 = 0x0950,
- APL10 = 0x1050,
-
- ETSI1 = 0x0130,
- ETSI2 = 0x0230,
- ETSI3 = 0x0330,
- ETSI4 = 0x0430,
- ETSI5 = 0x0530,
- ETSI6 = 0x0630,
- ETSIA = 0x0A30,
- ETSIB = 0x0B30,
- ETSIC = 0x0C30,
-
- FCC1 = 0x0110,
- FCC2 = 0x0120,
- FCC3 = 0x0160,
- FCC4 = 0x0165,
- FCC5 = 0x0510,
- FCC6 = 0x0610,
- FCCA = 0x0A10,
-
- APLD = 0x0D50,
-
- MKK1 = 0x0140,
- MKK2 = 0x0240,
- MKK3 = 0x0340,
- MKK4 = 0x0440,
- MKK5 = 0x0540,
- MKK6 = 0x0640,
- MKK7 = 0x0740,
- MKK8 = 0x0840,
- MKK9 = 0x0940,
- MKK10 = 0x0B40,
- MKK11 = 0x1140,
- MKK12 = 0x1240,
- MKK13 = 0x0C40,
- MKK14 = 0x1440,
- MKK15 = 0x1540,
- MKKA = 0x0A40,
- MKKC = 0x0A50,
-
- NULL1 = 0x0198,
WORLD = 0x0199,
DEBUG_REG_DMN = 0x01ff,
};
-enum {
- FCC = 0x10,
- MKK = 0x40,
- ETSI = 0x30,
-};
-
-enum {
- NO_REQ = 0x00000000,
- DISALLOW_ADHOC_11A = 0x00000001,
- DISALLOW_ADHOC_11A_TURB = 0x00000002,
- NEED_NFC = 0x00000004,
-
- ADHOC_PER_11D = 0x00000008,
- ADHOC_NO_11A = 0x00000010,
-
- PUBLIC_SAFETY_DOMAIN = 0x00000020,
- LIMIT_FRAME_4MS = 0x00000040,
-
- NO_HOSTAP = 0x00000080,
-
- REQ_MASK = 0x000000FF,
+enum ctl_group {
+ CTL_FCC = 0x10,
+ CTL_MKK = 0x40,
+ CTL_ETSI = 0x30,
};
-#define REG_DOMAIN_2GHZ_MASK (REQ_MASK & \
- (~(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB)))
-#define REG_DOMAIN_5GHZ_MASK REQ_MASK
-
+/* Regpair to CTL band mapping */
static struct reg_dmn_pair_mapping regDomainPairs[] = {
- {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ,
- PSCAN_DEFER, 0},
- {NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-
- {FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC4_FCCA, FCC4, FCCA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {FCC5_FCCA, FCC5, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC6_FCCA, FCC6, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC6_WORLD, FCC6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-
- {ETSI1_WORLD, ETSI1, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {ETSI2_WORLD, ETSI2, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {ETSI3_WORLD, ETSI3, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {ETSI4_WORLD, ETSI4, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {ETSI5_WORLD, ETSI5, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {ETSI6_WORLD, ETSI6, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
-
- {ETSI3_ETSIA, ETSI3, WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-
- {FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
-
- {APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER,},
-
- {MKK1_MKKA, MKK1, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN},
- {MKK1_MKKB, MKK1, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN1},
- {MKK1_FCCA, MKK1, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1, CTRY_JAPAN2},
- {MKK1_MKKA1, MKK1, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4},
- {MKK1_MKKA2, MKK1, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5},
- {MKK1_MKKC, MKK1, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1, CTRY_JAPAN6},
-
- {MKK2_MKKA, MKK2, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN3},
-
- {MKK3_MKKA, MKK3, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA, CTRY_JAPAN25},
- {MKK3_MKKB, MKK3, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN7},
- {MKK3_MKKA1, MKK3, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN26},
- {MKK3_MKKA2, MKK3, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8},
- {MKK3_MKKC, MKK3, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN9},
- {MKK3_FCCA, MKK3, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN27},
-
- {MKK4_MKKA, MKK4, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN36},
- {MKK4_MKKB, MKK4, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN10},
- {MKK4_MKKA1, MKK4, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN28},
- {MKK4_MKKA2, MKK4, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11},
- {MKK4_MKKC, MKK4, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN12},
- {MKK4_FCCA, MKK4, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN29},
-
- {MKK5_MKKB, MKK5, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN13},
- {MKK5_MKKA2, MKK5, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14},
- {MKK5_MKKC, MKK5, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN15},
-
- {MKK6_MKKB, MKK6, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN16},
- {MKK6_MKKA1, MKK6, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN30},
- {MKK6_MKKA2, MKK6, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17},
- {MKK6_MKKC, MKK6, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1, CTRY_JAPAN18},
- {MKK6_FCCA, MKK6, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN31},
-
- {MKK7_MKKB, MKK7, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN19},
- {MKK7_MKKA1, MKK7, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN32},
- {MKK7_MKKA2, MKK7, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
- CTRY_JAPAN20},
- {MKK7_MKKC, MKK7, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21},
- {MKK7_FCCA, MKK7, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN33},
-
- {MKK8_MKKB, MKK8, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN22},
- {MKK8_MKKA2, MKK8, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
- CTRY_JAPAN23},
- {MKK8_MKKC, MKK8, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN24},
-
- {MKK9_MKKA, MKK9, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK2 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN34},
- {MKK9_FCCA, MKK9, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN37},
- {MKK9_MKKA1, MKK9, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN38},
- {MKK9_MKKA2, MKK9, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN40},
- {MKK9_MKKC, MKK9, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN39},
-
- {MKK10_MKKA, MKK10, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKK3, CTRY_JAPAN35},
- {MKK10_FCCA, MKK10, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN41},
- {MKK10_MKKA1, MKK10, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN42},
- {MKK10_MKKA2, MKK10, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN44},
- {MKK10_MKKC, MKK10, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- NO_PSCAN, CTRY_JAPAN43},
-
- {MKK11_MKKA, MKK11, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN45},
- {MKK11_FCCA, MKK11, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN46},
- {MKK11_MKKA1, MKK11, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN47},
- {MKK11_MKKA2, MKK11, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN49},
- {MKK11_MKKC, MKK11, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK3, CTRY_JAPAN48},
-
- {MKK12_MKKA, MKK12, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN50},
- {MKK12_FCCA, MKK12, FCCA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN51},
- {MKK12_MKKA1, MKK12, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G,
- CTRY_JAPAN52},
- {MKK12_MKKA2, MKK12, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
- CTRY_JAPAN54},
- {MKK12_MKKC, MKK12, MKKC,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN53},
-
- {MKK13_MKKB, MKK13, MKKA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
- LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
- CTRY_JAPAN57},
-
- {MKK14_MKKA1, MKK14, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN58},
- {MKK15_MKKA1, MKK15, MKKA,
- DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
- PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN59},
-
- {WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
- 0},
- {WOR1_WORLD, WOR1_WORLD, WOR1_WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB,
- NO_REQ, PSCAN_DEFER, 0},
- {WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
- 0},
- {WOR4_WORLD, WOR4_WORLD, WOR4_WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ,
- PSCAN_DEFER, 0},
- {WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ,
- PSCAN_DEFER, 0},
- {EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
- {WOR9_WORLD, WOR9_WORLD, WOR9_WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {WORA_WORLD, WORA_WORLD, WORA_WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
- {WORB_WORLD, WORB_WORLD, WORB_WORLD,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
- 0},
+ /* regpair, 5 GHz CTL, 2 GHz CTL */
+ {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN},
+ {NULL1_WORLD, NO_CTL, CTL_ETSI},
+ {NULL1_ETSIB, NO_CTL, CTL_ETSI},
+ {NULL1_ETSIC, NO_CTL, CTL_ETSI},
+
+ {FCC2_FCCA, CTL_FCC, CTL_FCC},
+ {FCC2_WORLD, CTL_FCC, CTL_ETSI},
+ {FCC2_ETSIC, CTL_FCC, CTL_ETSI},
+ {FCC3_FCCA, CTL_FCC, CTL_FCC},
+ {FCC3_WORLD, CTL_FCC, CTL_ETSI},
+ {FCC4_FCCA, CTL_FCC, CTL_FCC},
+ {FCC5_FCCA, CTL_FCC, CTL_FCC},
+ {FCC6_FCCA, CTL_FCC, CTL_FCC},
+ {FCC6_WORLD, CTL_FCC, CTL_ETSI},
+
+ {ETSI1_WORLD, CTL_ETSI, CTL_ETSI},
+ {ETSI2_WORLD, CTL_ETSI, CTL_ETSI},
+ {ETSI3_WORLD, CTL_ETSI, CTL_ETSI},
+ {ETSI4_WORLD, CTL_ETSI, CTL_ETSI},
+ {ETSI5_WORLD, CTL_ETSI, CTL_ETSI},
+ {ETSI6_WORLD, CTL_ETSI, CTL_ETSI},
+
+ /* XXX: For ETSI3_ETSIA, Was NO_CTL meant for the 2 GHz band ? */
+ {ETSI3_ETSIA, CTL_ETSI, CTL_ETSI},
+ {FRANCE_RES, CTL_ETSI, CTL_ETSI},
+
+ {FCC1_WORLD, CTL_FCC, CTL_ETSI},
+ {FCC1_FCCA, CTL_FCC, CTL_FCC},
+ {APL1_WORLD, CTL_FCC, CTL_ETSI},
+ {APL2_WORLD, CTL_FCC, CTL_ETSI},
+ {APL3_WORLD, CTL_FCC, CTL_ETSI},
+ {APL4_WORLD, CTL_FCC, CTL_ETSI},
+ {APL5_WORLD, CTL_FCC, CTL_ETSI},
+ {APL6_WORLD, CTL_ETSI, CTL_ETSI},
+ {APL8_WORLD, CTL_ETSI, CTL_ETSI},
+ {APL9_WORLD, CTL_ETSI, CTL_ETSI},
+
+ {APL3_FCCA, CTL_FCC, CTL_FCC},
+ {APL1_ETSIC, CTL_FCC, CTL_ETSI},
+ {APL2_ETSIC, CTL_FCC, CTL_ETSI},
+ {APL2_APLD, CTL_FCC, NO_CTL},
+
+ {MKK1_MKKA, CTL_MKK, CTL_MKK},
+ {MKK1_MKKB, CTL_MKK, CTL_MKK},
+ {MKK1_FCCA, CTL_MKK, CTL_FCC},
+ {MKK1_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK1_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK1_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK2_MKKA, CTL_MKK, CTL_MKK},
+ {MKK3_MKKA, CTL_MKK, CTL_MKK},
+ {MKK3_MKKB, CTL_MKK, CTL_MKK},
+ {MKK3_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK3_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK3_MKKC, CTL_MKK, CTL_MKK},
+ {MKK3_FCCA, CTL_MKK, CTL_FCC},
+
+ {MKK4_MKKA, CTL_MKK, CTL_MKK},
+ {MKK4_MKKB, CTL_MKK, CTL_MKK},
+ {MKK4_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK4_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK4_MKKC, CTL_MKK, CTL_MKK},
+ {MKK4_FCCA, CTL_MKK, CTL_FCC},
+
+ {MKK5_MKKB, CTL_MKK, CTL_MKK},
+ {MKK5_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK5_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK6_MKKB, CTL_MKK, CTL_MKK},
+ {MKK6_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK6_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK6_MKKC, CTL_MKK, CTL_MKK},
+ {MKK6_FCCA, CTL_MKK, CTL_FCC},
+
+ {MKK7_MKKB, CTL_MKK, CTL_MKK},
+ {MKK7_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK7_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK7_MKKC, CTL_MKK, CTL_MKK},
+ {MKK7_FCCA, CTL_MKK, CTL_FCC},
+
+ {MKK8_MKKB, CTL_MKK, CTL_MKK},
+ {MKK8_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK8_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK9_MKKA, CTL_MKK, CTL_MKK},
+ {MKK9_FCCA, CTL_MKK, CTL_FCC},
+ {MKK9_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK9_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK9_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK10_MKKA, CTL_MKK, CTL_MKK},
+ {MKK10_FCCA, CTL_MKK, CTL_FCC},
+ {MKK10_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK10_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK10_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK11_MKKA, CTL_MKK, CTL_MKK},
+ {MKK11_FCCA, CTL_MKK, CTL_FCC},
+ {MKK11_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK11_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK11_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK12_MKKA, CTL_MKK, CTL_MKK},
+ {MKK12_FCCA, CTL_MKK, CTL_FCC},
+ {MKK12_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK12_MKKA2, CTL_MKK, CTL_MKK},
+ {MKK12_MKKC, CTL_MKK, CTL_MKK},
+
+ {MKK13_MKKB, CTL_MKK, CTL_MKK},
+ {MKK14_MKKA1, CTL_MKK, CTL_MKK},
+ {MKK15_MKKA1, CTL_MKK, CTL_MKK},
+
+ {WOR0_WORLD, NO_CTL, NO_CTL},
+ {WOR1_WORLD, NO_CTL, NO_CTL},
+ {WOR2_WORLD, NO_CTL, NO_CTL},
+ {WOR3_WORLD, NO_CTL, NO_CTL},
+ {WOR4_WORLD, NO_CTL, NO_CTL},
+ {WOR5_ETSIC, NO_CTL, NO_CTL},
+ {WOR01_WORLD, NO_CTL, NO_CTL},
+ {WOR02_WORLD, NO_CTL, NO_CTL},
+ {EU1_WORLD, NO_CTL, NO_CTL},
+ {WOR9_WORLD, NO_CTL, NO_CTL},
+ {WORA_WORLD, NO_CTL, NO_CTL},
+ {WORB_WORLD, NO_CTL, NO_CTL},
};
-#define NO_INTERSECT_REQ 0xFFFFFFFF
-#define NO_UNION_REQ 0
-
static struct country_code_to_enum_rd allCountries[] = {
- {CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET", YES, YES, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA", YES, NO, YES, YES, NO,
- NO, NO, 7000},
- {CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA", YES, NO, YES, YES, NO,
- NO, NO, 7000},
- {CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA", YES, NO, NO, YES,
- NO, YES, NO, 7000},
- {CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_AUSTRALIA, FCC2_WORLD, "AU", "AUSTRALIA", YES, YES, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_AUSTRALIA2, FCC6_WORLD, "AU", "AUSTRALIA2", YES, YES, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_AUSTRIA, ETSI1_WORLD, "AT", "AUSTRIA", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN", YES, YES, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN", YES, NO, YES, YES, YES,
- YES, NO, 7000},
- {CTRY_BELARUS, ETSI1_WORLD, "BY", "BELARUS", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_BELGIUM2, ETSI4_WORLD, "BL", "BELGIUM", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA", "BOSNIA_HERZGOWINA", YES, NO,
- YES, YES, YES, YES, NO, 7000},
- {CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL", YES, NO, NO, YES, NO,
- YES, NO, 7000},
- {CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN", "BRUNEI DARUSSALAM",
- YES, YES, YES, YES, YES, YES, YES, 7000},
- {CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_CANADA, FCC2_FCCA, "CA", "CANADA", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_CANADA2, FCC6_FCCA, "CA", "CANADA2", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_CHILE, APL6_WORLD, "CL", "CHILE", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_CHINA, APL1_WORLD, "CN", "CHINA", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA", YES, NO, YES, YES,
- YES, YES, NO, 7000},
- {CTRY_COSTA_RICA, FCC1_WORLD, "CR", "COSTA RICA", YES, NO, YES,
- YES, YES, YES, NO, 7000},
- {CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA", YES, NO, YES, YES,
- YES, YES, NO, 7000},
- {CTRY_CYPRUS, ETSI1_WORLD, "CY", "CYPRUS", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC", YES, NO, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO", "DOMINICAN REPUBLIC",
- YES, YES, YES, YES, YES, YES, YES, 7000},
- {CTRY_ECUADOR, FCC1_WORLD, "EC", "ECUADOR", YES, NO, NO, YES, YES,
- YES, NO, 7000},
- {CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT", YES, NO, YES, YES, YES,
- YES, NO, 7000},
- {CTRY_EL_SALVADOR, FCC1_WORLD, "SV", "EL SALVADOR", YES, NO, YES,
- YES, YES, YES, NO, 7000},
- {CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_FRANCE, ETSI1_WORLD, "FR", "FRANCE", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA", YES, YES, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA", YES, YES, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG", YES, YES, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_HUNGARY, ETSI1_WORLD, "HU", "HUNGARY", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_INDIA, APL6_WORLD, "IN", "INDIA", YES, NO, YES, YES, YES,
- YES, NO, 7000},
- {CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA", YES, NO, YES, YES,
- YES, YES, NO, 7000},
- {CTRY_IRAN, APL1_WORLD, "IR", "IRAN", YES, YES, YES, YES, YES, YES,
- YES, 7000},
- {CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_ISRAEL, NULL1_WORLD, "IL", "ISRAEL", YES, NO, YES, YES, YES,
- NO, NO, 7000},
- {CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_JAMAICA, ETSI1_WORLD, "JM", "JAMAICA", YES, NO, YES, YES,
- YES, YES, YES, 7000},
-
- {CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN", YES, NO, NO, YES, YES, YES,
- YES, 7000},
- {CTRY_JAPAN1, MKK1_MKKB, "JP", "JAPAN1", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN2, MKK1_FCCA, "JP", "JAPAN2", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN3, MKK2_MKKA, "JP", "JAPAN3", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN4, MKK1_MKKA1, "JP", "JAPAN4", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN5, MKK1_MKKA2, "JP", "JAPAN5", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN6, MKK1_MKKC, "JP", "JAPAN6", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN7, MKK3_MKKB, "JP", "JAPAN7", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN8, MKK3_MKKA2, "JP", "JAPAN8", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN9, MKK3_MKKC, "JP", "JAPAN9", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN10, MKK4_MKKB, "JP", "JAPAN10", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN11, MKK4_MKKA2, "JP", "JAPAN11", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN12, MKK4_MKKC, "JP", "JAPAN12", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN13, MKK5_MKKB, "JP", "JAPAN13", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN14", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN15", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN16, MKK6_MKKB, "JP", "JAPAN16", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN17, MKK6_MKKA2, "JP", "JAPAN17", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN18, MKK6_MKKC, "JP", "JAPAN18", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN19, MKK7_MKKB, "JP", "JAPAN19", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN20, MKK7_MKKA2, "JP", "JAPAN20", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN21, MKK7_MKKC, "JP", "JAPAN21", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN22, MKK8_MKKB, "JP", "JAPAN22", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN23, MKK8_MKKA2, "JP", "JAPAN23", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN24, MKK8_MKKC, "JP", "JAPAN24", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN25, MKK3_MKKA, "JP", "JAPAN25", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN26, MKK3_MKKA1, "JP", "JAPAN26", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN27, MKK3_FCCA, "JP", "JAPAN27", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN28, MKK4_MKKA1, "JP", "JAPAN28", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN29, MKK4_FCCA, "JP", "JAPAN29", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN30, MKK6_MKKA1, "JP", "JAPAN30", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN31, MKK6_FCCA, "JP", "JAPAN31", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN32, MKK7_MKKA1, "JP", "JAPAN32", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN33, MKK7_FCCA, "JP", "JAPAN33", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN34, MKK9_MKKA, "JP", "JAPAN34", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN35, MKK10_MKKA, "JP", "JAPAN35", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN36, MKK4_MKKA, "JP", "JAPAN36", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN37, MKK9_FCCA, "JP", "JAPAN37", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN38, MKK9_MKKA1, "JP", "JAPAN38", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN39, MKK9_MKKC, "JP", "JAPAN39", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN40, MKK9_MKKA2, "JP", "JAPAN40", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN41, MKK10_FCCA, "JP", "JAPAN41", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN42, MKK10_MKKA1, "JP", "JAPAN42", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN43, MKK10_MKKC, "JP", "JAPAN43", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN44, MKK10_MKKA2, "JP", "JAPAN44", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN45, MKK11_MKKA, "JP", "JAPAN45", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN46, MKK11_FCCA, "JP", "JAPAN46", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN47, MKK11_MKKA1, "JP", "JAPAN47", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN48, MKK11_MKKC, "JP", "JAPAN48", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN49, MKK11_MKKA2, "JP", "JAPAN49", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN50, MKK12_MKKA, "JP", "JAPAN50", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN51, MKK12_FCCA, "JP", "JAPAN51", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN52, MKK12_MKKA1, "JP", "JAPAN52", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN53, MKK12_MKKC, "JP", "JAPAN53", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN54, MKK12_MKKA2, "JP", "JAPAN54", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JAPAN57, MKK13_MKKB, "JP", "JAPAN57", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN58, MKK14_MKKA1, "JP", "JAPAN58", YES, NO, NO, YES, YES,
- YES, YES, 7000},
- {CTRY_JAPAN59, MKK15_MKKA1, "JP", "JAPAN59", YES, NO, NO, YES, YES,
- YES, YES, 7000},
-
- {CTRY_JORDAN, ETSI2_WORLD, "JO", "JORDAN", YES, NO, YES, YES, YES,
- YES, NO, 7000},
- {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN", YES, NO, YES,
- YES, YES, NO, NO, 7000},
- {CTRY_KOREA_NORTH, APL9_WORLD, "KP", "NORTH KOREA", YES, NO, NO,
- YES, YES, YES, YES, 7000},
- {CTRY_KOREA_ROC, APL9_WORLD, "KR", "KOREA REPUBLIC", YES, NO, NO,
- YES, NO, YES, NO, 7000},
- {CTRY_KOREA_ROC2, APL2_WORLD, "K2", "KOREA REPUBLIC2", YES, NO, NO,
- YES, NO, YES, NO, 7000},
- {CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3", YES, NO, NO,
- YES, NO, YES, NO, 7000},
- {CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT", YES, NO, YES, YES, YES,
- NO, NO, 7000},
- {CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI", "LIECHTENSTEIN", YES, NO,
- YES, YES, YES, YES, YES, 7000},
- {CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG", YES, NO, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_MACAU, FCC2_WORLD, "MO", "MACAU", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA", YES, NO, NO, YES, NO,
- YES, NO, 7000},
- {CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_NEPAL, APL1_WORLD, "NP", "NEPAL", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS", YES, NO, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN",
- "NETHERLANDS-ANTILLES", YES, NO, YES, YES, YES, YES, YES, 7000},
- {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND", YES, NO, YES,
- YES, YES, YES, NO, 7000},
- {CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_OMAN, APL6_WORLD, "OM", "OMAN", YES, NO, YES, YES, YES, YES,
- NO, 7000},
- {CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG", "PAPUA NEW GUINEA", YES,
- YES, YES, YES, YES, YES, YES, 7000},
- {CTRY_PERU, APL1_WORLD, "PE", "PERU", YES, NO, YES, YES, YES, YES,
- NO, 7000},
- {CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES", YES, YES, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO", YES, YES, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_QATAR, NULL1_WORLD, "QA", "QATAR", YES, NO, YES, YES, YES,
- NO, NO, 7000},
- {CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA", YES, NO, YES, YES, YES,
- NO, NO, 7000},
- {CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA", "SAUDI ARABIA", YES, NO,
- YES, YES, YES, NO, NO, 7000},
- {CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS", "SERBIA & MONTENEGRO",
- YES, NO, YES, YES, YES, YES, YES, 7000},
- {CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE", YES, YES, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC", YES, NO, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA", YES, NO, YES, YES,
- YES, YES, YES, 7000},
- {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", "SOUTH AFRICA", YES, NO, YES,
- YES, YES, YES, NO, 7000},
- {CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_SRI_LANKA, FCC3_WORLD, "LK", "SRI LANKA", YES, NO, YES, YES,
- YES, YES, NO, 7000},
- {CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN", YES, NO, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND", YES, NO, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA", YES, NO, YES, YES, YES,
- NO, NO, 7000},
- {CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN", YES, YES, YES, YES, YES,
- YES, YES, 7000},
- {CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT", "TRINIDAD & TOBAGO",
- YES, NO, YES, YES, YES, YES, NO, 7000},
- {CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA", YES, NO, YES, YES,
- YES, YES, NO, 7000},
- {CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY", YES, NO, YES, YES, YES,
- YES, NO, 7000},
- {CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES", YES, NO, YES,
- YES, YES, NO, NO, 7000},
- {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB", "UNITED KINGDOM", YES, NO,
- YES, YES, YES, YES, YES, 7000},
- {CTRY_UNITED_STATES, FCC3_FCCA, "US", "UNITED STATES", YES, YES,
- YES, YES, YES, YES, YES, 5825},
- {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS",
- "UNITED STATES (PUBLIC SAFETY)", YES, YES, YES, YES, YES, YES,
- YES, 7000},
- {CTRY_URUGUAY, APL2_WORLD, "UY", "URUGUAY", YES, NO, YES, YES, YES,
- YES, NO, 7000},
- {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN", YES, YES, YES,
- YES, YES, YES, YES, 7000},
- {CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA", YES, NO, YES, YES,
- YES, YES, NO, 7000},
- {CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM", YES, NO, YES, YES,
- YES, NO, NO, 7000},
- {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN", YES, NO, YES, YES, YES,
- NO, NO, 7000},
- {CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE", YES, NO, YES, YES,
- YES, NO, NO, 7000}
-};
-
-enum {
- NO_DFS = 0x0000000000000000ULL,
- DFS_FCC3 = 0x0000000000000001ULL,
- DFS_ETSI = 0x0000000000000002ULL,
- DFS_MKK4 = 0x0000000000000004ULL,
-};
-
-enum {
- F1_4915_4925,
- F1_4935_4945,
- F1_4920_4980,
- F1_4942_4987,
- F1_4945_4985,
- F1_4950_4980,
- F1_5035_5040,
- F1_5040_5080,
- F1_5055_5055,
-
- F1_5120_5240,
-
- F1_5170_5230,
- F2_5170_5230,
-
- F1_5180_5240,
- F2_5180_5240,
- F3_5180_5240,
- F4_5180_5240,
- F5_5180_5240,
- F6_5180_5240,
- F7_5180_5240,
- F8_5180_5240,
-
- F1_5180_5320,
-
- F1_5240_5280,
-
- F1_5260_5280,
-
- F1_5260_5320,
- F2_5260_5320,
- F3_5260_5320,
- F4_5260_5320,
- F5_5260_5320,
- F6_5260_5320,
-
- F1_5260_5700,
-
- F1_5280_5320,
-
- F1_5500_5580,
-
- F1_5500_5620,
-
- F1_5500_5700,
- F2_5500_5700,
- F3_5500_5700,
- F4_5500_5700,
- F5_5500_5700,
-
- F1_5660_5700,
-
- F1_5745_5805,
- F2_5745_5805,
- F3_5745_5805,
-
- F1_5745_5825,
- F2_5745_5825,
- F3_5745_5825,
- F4_5745_5825,
- F5_5745_5825,
- F6_5745_5825,
-
- W1_4920_4980,
- W1_5040_5080,
- W1_5170_5230,
- W1_5180_5240,
- W1_5260_5320,
- W1_5745_5825,
- W1_5500_5700,
- A_DEMO_ALL_CHANNELS
-};
-
-static struct RegDmnFreqBand regDmn5GhzFreq[] = {
- {4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
- {4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
- {4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7},
- {4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC, 0},
- {4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC, 0},
- {4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC, 0},
- {5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
- {5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2},
- {5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
-
- {5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-
- {5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
- {5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
-
- {5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
- {5180, 5240, 17, 6, 20, 20, NO_DFS, NO_PSCAN, 1},
- {5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
- {5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
- {5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
- {5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0},
- {5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK3, 0},
- {5180, 5240, 23, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-
- {5180, 5320, 20, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
-
- {5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0},
-
- {5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
- PSCAN_FCC | PSCAN_ETSI, 0},
-
- {5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
- PSCAN_FCC | PSCAN_ETSI, 0},
-
- {5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
- PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3, 0},
-
-
- {5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI,
- PSCAN_FCC | PSCAN_ETSI, 2},
- {5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2},
- {5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
- {5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
-
- {5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0},
-
- {5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
-
- {5500, 5580, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
-
- {5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
-
- {5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4},
- {5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
- PSCAN_FCC | PSCAN_ETSI, 0},
- {5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
- PSCAN_FCC | PSCAN_ETSI, 0},
- {5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
- PSCAN_MKK3 | PSCAN_FCC, 0},
- {5500, 5700, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
-
- {5660, 5700, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
-
- {5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
- {5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
- {5745, 5805, 30, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
- {5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
- {5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
- {5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
- {5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
- {5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3},
- {5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-
-
- {4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
- {5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
- {5170, 5230, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
- {5180, 5240, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
- {5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
- {5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
- {5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
- {4920, 6100, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
-};
-
-enum {
- T1_5130_5650,
- T1_5150_5670,
-
- T1_5200_5200,
- T2_5200_5200,
- T3_5200_5200,
- T4_5200_5200,
- T5_5200_5200,
- T6_5200_5200,
- T7_5200_5200,
- T8_5200_5200,
-
- T1_5200_5280,
- T2_5200_5280,
- T3_5200_5280,
- T4_5200_5280,
- T5_5200_5280,
- T6_5200_5280,
-
- T1_5200_5240,
- T1_5210_5210,
- T2_5210_5210,
- T3_5210_5210,
- T4_5210_5210,
- T5_5210_5210,
- T6_5210_5210,
- T7_5210_5210,
- T8_5210_5210,
- T9_5210_5210,
- T10_5210_5210,
- T1_5240_5240,
-
- T1_5210_5250,
- T1_5210_5290,
- T2_5210_5290,
- T3_5210_5290,
-
- T1_5280_5280,
- T2_5280_5280,
- T1_5290_5290,
- T2_5290_5290,
- T3_5290_5290,
- T1_5250_5290,
- T2_5250_5290,
- T3_5250_5290,
- T4_5250_5290,
-
- T1_5540_5660,
- T2_5540_5660,
- T3_5540_5660,
- T1_5760_5800,
- T2_5760_5800,
- T3_5760_5800,
- T4_5760_5800,
- T5_5760_5800,
- T6_5760_5800,
- T7_5760_5800,
-
- T1_5765_5805,
- T2_5765_5805,
- T3_5765_5805,
- T4_5765_5805,
- T5_5765_5805,
- T6_5765_5805,
- T7_5765_5805,
- T8_5765_5805,
- T9_5765_5805,
-
- WT1_5210_5250,
- WT1_5290_5290,
- WT1_5540_5660,
- WT1_5760_5800,
-};
-
-enum {
- F1_2312_2372,
- F2_2312_2372,
-
- F1_2412_2472,
- F2_2412_2472,
- F3_2412_2472,
-
- F1_2412_2462,
- F2_2412_2462,
-
- F1_2432_2442,
-
- F1_2457_2472,
-
- F1_2467_2472,
-
- F1_2484_2484,
- F2_2484_2484,
-
- F1_2512_2732,
-
- W1_2312_2372,
- W1_2412_2412,
- W1_2417_2432,
- W1_2437_2442,
- W1_2447_2457,
- W1_2462_2462,
- W1_2467_2467,
- W2_2467_2467,
- W1_2472_2472,
- W2_2472_2472,
- W1_2484_2484,
- W2_2484_2484,
-};
-
-static struct RegDmnFreqBand regDmn2GhzFreq[] = {
- {2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
- {2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
-
- {2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
-
- {2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2484, 2484, 20, 0, 20, 5, NO_DFS,
- PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0},
-
- {2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
- {2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
- {2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
- {2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
- {2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
- {2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
-};
-
-enum {
- G1_2312_2372,
- G2_2312_2372,
-
- G1_2412_2472,
- G2_2412_2472,
- G3_2412_2472,
-
- G1_2412_2462,
- G2_2412_2462,
-
- G1_2432_2442,
-
- G1_2457_2472,
-
- G1_2512_2732,
-
- G1_2467_2472,
-
- WG1_2312_2372,
- WG1_2412_2462,
- WG1_2467_2472,
- WG2_2467_2472,
- G_DEMO_ALL_CHANNELS
-};
-
-static struct RegDmnFreqBand regDmn2Ghz11gFreq[] = {
- {2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
- {2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
-
- {2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-
- {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
-
- {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2412, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
- {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
- {2467, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
- {2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
-};
-
-enum {
- T1_2312_2372,
- T1_2437_2437,
- T2_2437_2437,
- T3_2437_2437,
- T1_2512_2732
+ {CTRY_DEBUG, NO_ENUMRD, "DB"},
+ {CTRY_DEFAULT, FCC1_FCCA, "CO"},
+ {CTRY_ALBANIA, NULL1_WORLD, "AL"},
+ {CTRY_ALGERIA, NULL1_WORLD, "DZ"},
+ {CTRY_ARGENTINA, APL3_WORLD, "AR"},
+ {CTRY_ARMENIA, ETSI4_WORLD, "AM"},
+ {CTRY_AUSTRALIA, FCC2_WORLD, "AU"},
+ {CTRY_AUSTRALIA2, FCC6_WORLD, "AU"},
+ {CTRY_AUSTRIA, ETSI1_WORLD, "AT"},
+ {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ"},
+ {CTRY_BAHRAIN, APL6_WORLD, "BH"},
+ {CTRY_BELARUS, ETSI1_WORLD, "BY"},
+ {CTRY_BELGIUM, ETSI1_WORLD, "BE"},
+ {CTRY_BELGIUM2, ETSI4_WORLD, "BL"},
+ {CTRY_BELIZE, APL1_ETSIC, "BZ"},
+ {CTRY_BOLIVIA, APL1_ETSIC, "BO"},
+ {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA"},
+ {CTRY_BRAZIL, FCC3_WORLD, "BR"},
+ {CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN"},
+ {CTRY_BULGARIA, ETSI6_WORLD, "BG"},
+ {CTRY_CANADA, FCC2_FCCA, "CA"},
+ {CTRY_CANADA2, FCC6_FCCA, "CA"},
+ {CTRY_CHILE, APL6_WORLD, "CL"},
+ {CTRY_CHINA, APL1_WORLD, "CN"},
+ {CTRY_COLOMBIA, FCC1_FCCA, "CO"},
+ {CTRY_COSTA_RICA, FCC1_WORLD, "CR"},
+ {CTRY_CROATIA, ETSI3_WORLD, "HR"},
+ {CTRY_CYPRUS, ETSI1_WORLD, "CY"},
+ {CTRY_CZECH, ETSI3_WORLD, "CZ"},
+ {CTRY_DENMARK, ETSI1_WORLD, "DK"},
+ {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO"},
+ {CTRY_ECUADOR, FCC1_WORLD, "EC"},
+ {CTRY_EGYPT, ETSI3_WORLD, "EG"},
+ {CTRY_EL_SALVADOR, FCC1_WORLD, "SV"},
+ {CTRY_ESTONIA, ETSI1_WORLD, "EE"},
+ {CTRY_FINLAND, ETSI1_WORLD, "FI"},
+ {CTRY_FRANCE, ETSI1_WORLD, "FR"},
+ {CTRY_GEORGIA, ETSI4_WORLD, "GE"},
+ {CTRY_GERMANY, ETSI1_WORLD, "DE"},
+ {CTRY_GREECE, ETSI1_WORLD, "GR"},
+ {CTRY_GUATEMALA, FCC1_FCCA, "GT"},
+ {CTRY_HONDURAS, NULL1_WORLD, "HN"},
+ {CTRY_HONG_KONG, FCC2_WORLD, "HK"},
+ {CTRY_HUNGARY, ETSI1_WORLD, "HU"},
+ {CTRY_ICELAND, ETSI1_WORLD, "IS"},
+ {CTRY_INDIA, APL6_WORLD, "IN"},
+ {CTRY_INDONESIA, APL1_WORLD, "ID"},
+ {CTRY_IRAN, APL1_WORLD, "IR"},
+ {CTRY_IRELAND, ETSI1_WORLD, "IE"},
+ {CTRY_ISRAEL, NULL1_WORLD, "IL"},
+ {CTRY_ITALY, ETSI1_WORLD, "IT"},
+ {CTRY_JAMAICA, ETSI1_WORLD, "JM"},
+
+ {CTRY_JAPAN, MKK1_MKKA, "JP"},
+ {CTRY_JAPAN1, MKK1_MKKB, "JP"},
+ {CTRY_JAPAN2, MKK1_FCCA, "JP"},
+ {CTRY_JAPAN3, MKK2_MKKA, "JP"},
+ {CTRY_JAPAN4, MKK1_MKKA1, "JP"},
+ {CTRY_JAPAN5, MKK1_MKKA2, "JP"},
+ {CTRY_JAPAN6, MKK1_MKKC, "JP"},
+ {CTRY_JAPAN7, MKK3_MKKB, "JP"},
+ {CTRY_JAPAN8, MKK3_MKKA2, "JP"},
+ {CTRY_JAPAN9, MKK3_MKKC, "JP"},
+ {CTRY_JAPAN10, MKK4_MKKB, "JP"},
+ {CTRY_JAPAN11, MKK4_MKKA2, "JP"},
+ {CTRY_JAPAN12, MKK4_MKKC, "JP"},
+ {CTRY_JAPAN13, MKK5_MKKB, "JP"},
+ {CTRY_JAPAN14, MKK5_MKKA2, "JP"},
+ {CTRY_JAPAN15, MKK5_MKKC, "JP"},
+ {CTRY_JAPAN16, MKK6_MKKB, "JP"},
+ {CTRY_JAPAN17, MKK6_MKKA2, "JP"},
+ {CTRY_JAPAN18, MKK6_MKKC, "JP"},
+ {CTRY_JAPAN19, MKK7_MKKB, "JP"},
+ {CTRY_JAPAN20, MKK7_MKKA2, "JP"},
+ {CTRY_JAPAN21, MKK7_MKKC, "JP"},
+ {CTRY_JAPAN22, MKK8_MKKB, "JP"},
+ {CTRY_JAPAN23, MKK8_MKKA2, "JP"},
+ {CTRY_JAPAN24, MKK8_MKKC, "JP"},
+ {CTRY_JAPAN25, MKK3_MKKA, "JP"},
+ {CTRY_JAPAN26, MKK3_MKKA1, "JP"},
+ {CTRY_JAPAN27, MKK3_FCCA, "JP"},
+ {CTRY_JAPAN28, MKK4_MKKA1, "JP"},
+ {CTRY_JAPAN29, MKK4_FCCA, "JP"},
+ {CTRY_JAPAN30, MKK6_MKKA1, "JP"},
+ {CTRY_JAPAN31, MKK6_FCCA, "JP"},
+ {CTRY_JAPAN32, MKK7_MKKA1, "JP"},
+ {CTRY_JAPAN33, MKK7_FCCA, "JP"},
+ {CTRY_JAPAN34, MKK9_MKKA, "JP"},
+ {CTRY_JAPAN35, MKK10_MKKA, "JP"},
+ {CTRY_JAPAN36, MKK4_MKKA, "JP"},
+ {CTRY_JAPAN37, MKK9_FCCA, "JP"},
+ {CTRY_JAPAN38, MKK9_MKKA1, "JP"},
+ {CTRY_JAPAN39, MKK9_MKKC, "JP"},
+ {CTRY_JAPAN40, MKK9_MKKA2, "JP"},
+ {CTRY_JAPAN41, MKK10_FCCA, "JP"},
+ {CTRY_JAPAN42, MKK10_MKKA1, "JP"},
+ {CTRY_JAPAN43, MKK10_MKKC, "JP"},
+ {CTRY_JAPAN44, MKK10_MKKA2, "JP"},
+ {CTRY_JAPAN45, MKK11_MKKA, "JP"},
+ {CTRY_JAPAN46, MKK11_FCCA, "JP"},
+ {CTRY_JAPAN47, MKK11_MKKA1, "JP"},
+ {CTRY_JAPAN48, MKK11_MKKC, "JP"},
+ {CTRY_JAPAN49, MKK11_MKKA2, "JP"},
+ {CTRY_JAPAN50, MKK12_MKKA, "JP"},
+ {CTRY_JAPAN51, MKK12_FCCA, "JP"},
+ {CTRY_JAPAN52, MKK12_MKKA1, "JP"},
+ {CTRY_JAPAN53, MKK12_MKKC, "JP"},
+ {CTRY_JAPAN54, MKK12_MKKA2, "JP"},
+ {CTRY_JAPAN57, MKK13_MKKB, "JP"},
+ {CTRY_JAPAN58, MKK14_MKKA1, "JP"},
+ {CTRY_JAPAN59, MKK15_MKKA1, "JP"},
+
+ {CTRY_JORDAN, ETSI2_WORLD, "JO"},
+ {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ"},
+ {CTRY_KOREA_NORTH, APL9_WORLD, "KP"},
+ {CTRY_KOREA_ROC, APL9_WORLD, "KR"},
+ {CTRY_KOREA_ROC2, APL2_WORLD, "K2"},
+ {CTRY_KOREA_ROC3, APL9_WORLD, "K3"},
+ {CTRY_KUWAIT, NULL1_WORLD, "KW"},
+ {CTRY_LATVIA, ETSI1_WORLD, "LV"},
+ {CTRY_LEBANON, NULL1_WORLD, "LB"},
+ {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI"},
+ {CTRY_LITHUANIA, ETSI1_WORLD, "LT"},
+ {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU"},
+ {CTRY_MACAU, FCC2_WORLD, "MO"},
+ {CTRY_MACEDONIA, NULL1_WORLD, "MK"},
+ {CTRY_MALAYSIA, APL8_WORLD, "MY"},
+ {CTRY_MALTA, ETSI1_WORLD, "MT"},
+ {CTRY_MEXICO, FCC1_FCCA, "MX"},
+ {CTRY_MONACO, ETSI4_WORLD, "MC"},
+ {CTRY_MOROCCO, NULL1_WORLD, "MA"},
+ {CTRY_NEPAL, APL1_WORLD, "NP"},
+ {CTRY_NETHERLANDS, ETSI1_WORLD, "NL"},
+ {CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN"},
+ {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ"},
+ {CTRY_NORWAY, ETSI1_WORLD, "NO"},
+ {CTRY_OMAN, APL6_WORLD, "OM"},
+ {CTRY_PAKISTAN, NULL1_WORLD, "PK"},
+ {CTRY_PANAMA, FCC1_FCCA, "PA"},
+ {CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG"},
+ {CTRY_PERU, APL1_WORLD, "PE"},
+ {CTRY_PHILIPPINES, APL1_WORLD, "PH"},
+ {CTRY_POLAND, ETSI1_WORLD, "PL"},
+ {CTRY_PORTUGAL, ETSI1_WORLD, "PT"},
+ {CTRY_PUERTO_RICO, FCC1_FCCA, "PR"},
+ {CTRY_QATAR, NULL1_WORLD, "QA"},
+ {CTRY_ROMANIA, NULL1_WORLD, "RO"},
+ {CTRY_RUSSIA, NULL1_WORLD, "RU"},
+ {CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA"},
+ {CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS"},
+ {CTRY_SINGAPORE, APL6_WORLD, "SG"},
+ {CTRY_SLOVAKIA, ETSI1_WORLD, "SK"},
+ {CTRY_SLOVENIA, ETSI1_WORLD, "SI"},
+ {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA"},
+ {CTRY_SPAIN, ETSI1_WORLD, "ES"},
+ {CTRY_SRI_LANKA, FCC3_WORLD, "LK"},
+ {CTRY_SWEDEN, ETSI1_WORLD, "SE"},
+ {CTRY_SWITZERLAND, ETSI1_WORLD, "CH"},
+ {CTRY_SYRIA, NULL1_WORLD, "SY"},
+ {CTRY_TAIWAN, APL3_FCCA, "TW"},
+ {CTRY_THAILAND, NULL1_WORLD, "TH"},
+ {CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT"},
+ {CTRY_TUNISIA, ETSI3_WORLD, "TN"},
+ {CTRY_TURKEY, ETSI3_WORLD, "TR"},
+ {CTRY_UKRAINE, NULL1_WORLD, "UA"},
+ {CTRY_UAE, NULL1_WORLD, "AE"},
+ {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
+ {CTRY_UNITED_STATES, FCC3_FCCA, "US"},
+ /* This "PS" is for US public safety actually... to support this we
+ * would need to assign new special alpha2 to CRDA db as with the world
+ * regdomain and use another alpha2 */
+ {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS"},
+ {CTRY_URUGUAY, APL2_WORLD, "UY"},
+ {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ"},
+ {CTRY_VENEZUELA, APL2_ETSIC, "VE"},
+ {CTRY_VIET_NAM, NULL1_WORLD, "VN"},
+ {CTRY_YEMEN, NULL1_WORLD, "YE"},
+ {CTRY_ZIMBABWE, NULL1_WORLD, "ZW"},
};
-static struct regDomain regDomains[] = {
-
- {DEBUG_REG_DMN, FCC, DFS_FCC3, NO_PSCAN, NO_REQ,
- BM(A_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5130_5650, T1_5150_5670, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5200_5240, T1_5280_5280, T1_5540_5660, T1_5765_5805, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(F1_2312_2372, F1_2412_2472, F1_2484_2484, F1_2512_2732, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(G_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_2312_2372, T1_2437_2437, T1_2512_2732, -1, -1, -1, -1, -1,
- -1, -1, -1, -1)},
-
- {APL1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F1_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL3, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F1_5280_5320, F2_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5290_5290, T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL4, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F4_5180_5240, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5210_5210, T3_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5200_5200, T3_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F2_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T4_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T4_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL6, ETSI, DFS_ETSI, PSCAN_FCC_T | PSCAN_FCC, NO_REQ,
- BM(F4_5180_5240, F2_5260_5320, F3_5745_5825, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T2_5210_5210, T1_5250_5290, T1_5760_5800, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T1_5200_5280, T5_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL7, ETSI, DFS_ETSI, PSCAN_ETSI, NO_REQ,
- BM(F1_5280_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL8, ETSI, NO_DFS, NO_PSCAN,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F6_5260_5320, F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T2_5290_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL9, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F1_5180_5320, F1_5500_5620, F3_5745_5805, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {APL10, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F1_5180_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {ETSI1, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F4_5180_5240, F2_5260_5320, F2_5500_5700, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_5200_5280, T2_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {ETSI2, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F3_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {ETSI3, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {ETSI4, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F3_5180_5240, F1_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T2_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T3_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {ETSI5, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F1_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T4_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T3_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {ETSI6, ETSI, DFS_ETSI, PSCAN_ETSI,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F5_5180_5240, F1_5260_5280, F3_5500_5700, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T1_5210_5250, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T4_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {FCC1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F2_5180_5240, F4_5260_5320, F5_5745_5825, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T6_5210_5210, T2_5250_5290, T6_5760_5800, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T1_5200_5240, T2_5280_5280, T7_5765_5805, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {FCC2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F6_5180_5240, F5_5260_5320, F6_5745_5825, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {FCC3, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
- BM(F2_5180_5240, F3_5260_5320, F1_5500_5700, F5_5745_5825, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T4_5200_5200, T8_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {FCC4, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
- BM(F1_4942_4987, F1_4945_4985, F1_4950_4980, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T8_5210_5210, T4_5250_5290, T7_5760_5800, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T1_5200_5240, T1_5280_5280, T9_5765_5805, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {FCC5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BM(F2_5180_5240, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T8_5200_5200, T7_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {FCC6, FCC, DFS_FCC3, PSCAN_FCC, NO_REQ,
- BM(F8_5180_5240, F5_5260_5320, F1_5500_5580, F1_5660_5700,
- F6_5745_5825, -1, -1, -1, -1, -1, -1, -1),
- BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {MKK1, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
- BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
- {MKK2, MKK, NO_DFS, PSCAN_MKK2, DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
- F2_5260_5320, F4_5500_5700, -1, -1),
- BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK3, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
- BM(F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK4, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
- BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T10_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK5, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
- BM(F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK6, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
- BM(F2_5170_5230, F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK7, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
- DISALLOW_ADHOC_11A_TURB,
- BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T5_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK8, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
- DISALLOW_ADHOC_11A_TURB,
- BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK9, MKK, NO_DFS, PSCAN_MKK2 | PSCAN_MKK3,
- DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5055_5055, F1_5040_5080, F4_5180_5240, -1, -1, -1, -1, -1),
- BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK10, MKK, DFS_MKK4, PSCAN_MKK2 | PSCAN_MKK3,
- DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320, -1, -1,
- -1, -1),
- BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK11, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320,
- F4_5500_5700, -1, -1, -1),
- BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK12, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
- DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
- F2_5260_5320, F4_5500_5700, -1, -1),
- BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK13, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BM(F1_5170_5230, F7_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK14, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240, -1, -1,
- -1, -1),
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {MKK15, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
- BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
- F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240,
- F2_5260_5320, -1, -1, -1),
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO},
-
-
- {APLD, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F2_2312_2372, F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(G2_2312_2372, G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BMZERO},
-
- {ETSIA, NO_CTL, NO_DFS, PSCAN_ETSIA,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(G1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {ETSIB, ETSI, NO_DFS, PSCAN_ETSIB,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(G1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {ETSIC, ETSI, NO_DFS, PSCAN_ETSIC,
- DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(G3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {FCCA, FCC, NO_DFS, NO_PSCAN, NO_REQ,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(G1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {MKKA, MKK, NO_DFS,
- PSCAN_MKKA | PSCAN_MKKA_G | PSCAN_MKKA1 | PSCAN_MKKA1_G |
- PSCAN_MKKA2 | PSCAN_MKKA2_G, DISALLOW_ADHOC_11A_TURB,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F2_2412_2462, F1_2467_2472, F2_2484_2484, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(G2_2412_2462, G1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {MKKC, MKK, NO_DFS, NO_PSCAN, NO_REQ,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WORLD, ETSI, NO_DFS, NO_PSCAN, NO_REQ,
- BMZERO,
- BMZERO,
- BMZERO,
- BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR0_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
- W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
- -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR01_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
- ADHOC_PER_11D,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
- W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
- W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR02_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
- ADHOC_PER_11D,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
- W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {EU1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
- W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W2_2472_2472,
- W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
- W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
- -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR2_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
- W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
- -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR3_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
- BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR4_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
- W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR5_ETSIC, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WOR9_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
- -1, -1, -1, -1, -1),
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
- W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WORA_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
- -1, -1, -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {WORB_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
- BM(W1_5260_5320, W1_5180_5240, W1_5500_5700, -1, -1, -1, -1, -1,
- -1, -1, -1, -1),
- BMZERO,
- BMZERO,
- BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
- W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
- BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1),
- BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
-
- {NULL1, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO,
- BMZERO}
-};
-
-static const struct cmode modes[] = {
- {ATH9K_MODE_11A, CHANNEL_A},
- {ATH9K_MODE_11B, CHANNEL_B},
- {ATH9K_MODE_11G, CHANNEL_G},
- {ATH9K_MODE_11NG_HT20, CHANNEL_G_HT20},
- {ATH9K_MODE_11NG_HT40PLUS, CHANNEL_G_HT40PLUS},
- {ATH9K_MODE_11NG_HT40MINUS, CHANNEL_G_HT40MINUS},
- {ATH9K_MODE_11NA_HT20, CHANNEL_A_HT20},
- {ATH9K_MODE_11NA_HT40PLUS, CHANNEL_A_HT40PLUS},
- {ATH9K_MODE_11NA_HT40MINUS, CHANNEL_A_HT40MINUS},
-};
-
-static struct japan_bandcheck j_bandcheck[] = {
- {F1_5170_5230, AR_EEPROM_EEREGCAP_EN_KK_U1_ODD},
- {F4_5180_5240, AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN},
- {F2_5260_5320, AR_EEPROM_EEREGCAP_EN_KK_U2},
- {F4_5500_5700, AR_EEPROM_EEREGCAP_EN_KK_MIDBAND}
-};
-
-
#endif
diff --git a/drivers/net/wireless/ath9k/virtual.c b/drivers/net/wireless/ath9k/virtual.c
new file mode 100644
index 000000000000..1ff429b027d7
--- /dev/null
+++ b/drivers/net/wireless/ath9k/virtual.c
@@ -0,0 +1,662 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ath9k.h"
+
+struct ath9k_vif_iter_data {
+ int count;
+ u8 *addr;
+};
+
+static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+ struct ath9k_vif_iter_data *iter_data = data;
+ u8 *nbuf;
+
+ nbuf = krealloc(iter_data->addr, (iter_data->count + 1) * ETH_ALEN,
+ GFP_ATOMIC);
+ if (nbuf == NULL)
+ return;
+
+ memcpy(nbuf + iter_data->count * ETH_ALEN, mac, ETH_ALEN);
+ iter_data->addr = nbuf;
+ iter_data->count++;
+}
+
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath9k_vif_iter_data iter_data;
+ int i, j;
+ u8 mask[ETH_ALEN];
+
+ /*
+ * Add primary MAC address even if it is not in active use since it
+ * will be configured to the hardware as the starting point and the
+ * BSSID mask will need to be changed if another address is active.
+ */
+ iter_data.addr = kmalloc(ETH_ALEN, GFP_ATOMIC);
+ if (iter_data.addr) {
+ memcpy(iter_data.addr, sc->sc_ah->macaddr, ETH_ALEN);
+ iter_data.count = 1;
+ } else
+ iter_data.count = 0;
+
+ /* Get list of all active MAC addresses */
+ spin_lock_bh(&sc->wiphy_lock);
+ ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter,
+ &iter_data);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] == NULL)
+ continue;
+ ieee80211_iterate_active_interfaces_atomic(
+ sc->sec_wiphy[i]->hw, ath9k_vif_iter, &iter_data);
+ }
+ spin_unlock_bh(&sc->wiphy_lock);
+
+ /* Generate an address mask to cover all active addresses */
+ memset(mask, 0, ETH_ALEN);
+ for (i = 0; i < iter_data.count; i++) {
+ u8 *a1 = iter_data.addr + i * ETH_ALEN;
+ for (j = i + 1; j < iter_data.count; j++) {
+ u8 *a2 = iter_data.addr + j * ETH_ALEN;
+ mask[0] |= a1[0] ^ a2[0];
+ mask[1] |= a1[1] ^ a2[1];
+ mask[2] |= a1[2] ^ a2[2];
+ mask[3] |= a1[3] ^ a2[3];
+ mask[4] |= a1[4] ^ a2[4];
+ mask[5] |= a1[5] ^ a2[5];
+ }
+ }
+
+ kfree(iter_data.addr);
+
+ /* Invert the mask and configure hardware */
+ sc->bssidmask[0] = ~mask[0];
+ sc->bssidmask[1] = ~mask[1];
+ sc->bssidmask[2] = ~mask[2];
+ sc->bssidmask[3] = ~mask[3];
+ sc->bssidmask[4] = ~mask[4];
+ sc->bssidmask[5] = ~mask[5];
+
+ ath9k_hw_setbssidmask(sc);
+}
+
+int ath9k_wiphy_add(struct ath_softc *sc)
+{
+ int i, error;
+ struct ath_wiphy *aphy;
+ struct ieee80211_hw *hw;
+ u8 addr[ETH_ALEN];
+
+ hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy), &ath9k_ops);
+ if (hw == NULL)
+ return -ENOMEM;
+
+ spin_lock_bh(&sc->wiphy_lock);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] == NULL)
+ break;
+ }
+
+ if (i == sc->num_sec_wiphy) {
+ /* No empty slot available; increase array length */
+ struct ath_wiphy **n;
+ n = krealloc(sc->sec_wiphy,
+ (sc->num_sec_wiphy + 1) *
+ sizeof(struct ath_wiphy *),
+ GFP_ATOMIC);
+ if (n == NULL) {
+ spin_unlock_bh(&sc->wiphy_lock);
+ ieee80211_free_hw(hw);
+ return -ENOMEM;
+ }
+ n[i] = NULL;
+ sc->sec_wiphy = n;
+ sc->num_sec_wiphy++;
+ }
+
+ SET_IEEE80211_DEV(hw, sc->dev);
+
+ aphy = hw->priv;
+ aphy->sc = sc;
+ aphy->hw = hw;
+ sc->sec_wiphy[i] = aphy;
+ spin_unlock_bh(&sc->wiphy_lock);
+
+ memcpy(addr, sc->sc_ah->macaddr, ETH_ALEN);
+ addr[0] |= 0x02; /* Locally managed address */
+ /*
+ * XOR virtual wiphy index into the least significant bits to generate
+ * a different MAC address for each virtual wiphy.
+ */
+ addr[5] ^= i & 0xff;
+ addr[4] ^= (i & 0xff00) >> 8;
+ addr[3] ^= (i & 0xff0000) >> 16;
+
+ SET_IEEE80211_PERM_ADDR(hw, addr);
+
+ ath_set_hw_capab(sc, hw);
+
+ error = ieee80211_register_hw(hw);
+
+ if (error == 0) {
+ /* Make sure wiphy scheduler is started (if enabled) */
+ ath9k_wiphy_set_scheduler(sc, sc->wiphy_scheduler_int);
+ }
+
+ return error;
+}
+
+int ath9k_wiphy_del(struct ath_wiphy *aphy)
+{
+ struct ath_softc *sc = aphy->sc;
+ int i;
+
+ spin_lock_bh(&sc->wiphy_lock);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (aphy == sc->sec_wiphy[i]) {
+ sc->sec_wiphy[i] = NULL;
+ spin_unlock_bh(&sc->wiphy_lock);
+ ieee80211_unregister_hw(aphy->hw);
+ ieee80211_free_hw(aphy->hw);
+ return 0;
+ }
+ }
+ spin_unlock_bh(&sc->wiphy_lock);
+ return -ENOENT;
+}
+
+static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
+ struct ieee80211_vif *vif, const u8 *bssid,
+ int ps)
+{
+ struct ath_softc *sc = aphy->sc;
+ struct ath_tx_control txctl;
+ struct sk_buff *skb;
+ struct ieee80211_hdr *hdr;
+ __le16 fc;
+ struct ieee80211_tx_info *info;
+
+ skb = dev_alloc_skb(24);
+ if (skb == NULL)
+ return -ENOMEM;
+ hdr = (struct ieee80211_hdr *) skb_put(skb, 24);
+ memset(hdr, 0, 24);
+ fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
+ IEEE80211_FCTL_TODS);
+ if (ps)
+ fc |= cpu_to_le16(IEEE80211_FCTL_PM);
+ hdr->frame_control = fc;
+ memcpy(hdr->addr1, bssid, ETH_ALEN);
+ memcpy(hdr->addr2, aphy->hw->wiphy->perm_addr, ETH_ALEN);
+ memcpy(hdr->addr3, bssid, ETH_ALEN);
+
+ info = IEEE80211_SKB_CB(skb);
+ memset(info, 0, sizeof(*info));
+ info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS;
+ info->control.vif = vif;
+ info->control.rates[0].idx = 0;
+ info->control.rates[0].count = 4;
+ info->control.rates[1].idx = -1;
+
+ memset(&txctl, 0, sizeof(struct ath_tx_control));
+ txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]];
+ txctl.frame_type = ps ? ATH9K_INT_PAUSE : ATH9K_INT_UNPAUSE;
+
+ if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
+ goto exit;
+
+ return 0;
+exit:
+ dev_kfree_skb_any(skb);
+ return -1;
+}
+
+static bool __ath9k_wiphy_pausing(struct ath_softc *sc)
+{
+ int i;
+ if (sc->pri_wiphy->state == ATH_WIPHY_PAUSING)
+ return true;
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] &&
+ sc->sec_wiphy[i]->state == ATH_WIPHY_PAUSING)
+ return true;
+ }
+ return false;
+}
+
+static bool ath9k_wiphy_pausing(struct ath_softc *sc)
+{
+ bool ret;
+ spin_lock_bh(&sc->wiphy_lock);
+ ret = __ath9k_wiphy_pausing(sc);
+ spin_unlock_bh(&sc->wiphy_lock);
+ return ret;
+}
+
+static bool __ath9k_wiphy_scanning(struct ath_softc *sc)
+{
+ int i;
+ if (sc->pri_wiphy->state == ATH_WIPHY_SCAN)
+ return true;
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] &&
+ sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN)
+ return true;
+ }
+ return false;
+}
+
+bool ath9k_wiphy_scanning(struct ath_softc *sc)
+{
+ bool ret;
+ spin_lock_bh(&sc->wiphy_lock);
+ ret = __ath9k_wiphy_scanning(sc);
+ spin_unlock_bh(&sc->wiphy_lock);
+ return ret;
+}
+
+static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy);
+
+/* caller must hold wiphy_lock */
+static void __ath9k_wiphy_unpause_ch(struct ath_wiphy *aphy)
+{
+ if (aphy == NULL)
+ return;
+ if (aphy->chan_idx != aphy->sc->chan_idx)
+ return; /* wiphy not on the selected channel */
+ __ath9k_wiphy_unpause(aphy);
+}
+
+static void ath9k_wiphy_unpause_channel(struct ath_softc *sc)
+{
+ int i;
+ spin_lock_bh(&sc->wiphy_lock);
+ __ath9k_wiphy_unpause_ch(sc->pri_wiphy);
+ for (i = 0; i < sc->num_sec_wiphy; i++)
+ __ath9k_wiphy_unpause_ch(sc->sec_wiphy[i]);
+ spin_unlock_bh(&sc->wiphy_lock);
+}
+
+void ath9k_wiphy_chan_work(struct work_struct *work)
+{
+ struct ath_softc *sc = container_of(work, struct ath_softc, chan_work);
+ struct ath_wiphy *aphy = sc->next_wiphy;
+
+ if (aphy == NULL)
+ return;
+
+ /*
+ * All pending interfaces paused; ready to change
+ * channels.
+ */
+
+ /* Change channels */
+ mutex_lock(&sc->mutex);
+ /* XXX: remove me eventually */
+ ath9k_update_ichannel(sc, aphy->hw,
+ &sc->sc_ah->channels[sc->chan_idx]);
+ ath_update_chainmask(sc, sc->chan_is_ht);
+ if (ath_set_channel(sc, aphy->hw,
+ &sc->sc_ah->channels[sc->chan_idx]) < 0) {
+ printk(KERN_DEBUG "ath9k: Failed to set channel for new "
+ "virtual wiphy\n");
+ mutex_unlock(&sc->mutex);
+ return;
+ }
+ mutex_unlock(&sc->mutex);
+
+ ath9k_wiphy_unpause_channel(sc);
+}
+
+/*
+ * ath9k version of ieee80211_tx_status() for TX frames that are generated
+ * internally in the driver.
+ */
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+
+ if (tx_info_priv && tx_info_priv->frame_type == ATH9K_INT_PAUSE &&
+ aphy->state == ATH_WIPHY_PAUSING) {
+ if (!(info->flags & IEEE80211_TX_STAT_ACK)) {
+ printk(KERN_DEBUG "ath9k: %s: no ACK for pause "
+ "frame\n", wiphy_name(hw->wiphy));
+ /*
+ * The AP did not reply; ignore this to allow us to
+ * continue.
+ */
+ }
+ aphy->state = ATH_WIPHY_PAUSED;
+ if (!ath9k_wiphy_pausing(aphy->sc)) {
+ /*
+ * Drop from tasklet to work to allow mutex for channel
+ * change.
+ */
+ queue_work(aphy->sc->hw->workqueue,
+ &aphy->sc->chan_work);
+ }
+ }
+
+ kfree(tx_info_priv);
+ tx_info->rate_driver_data[0] = NULL;
+
+ dev_kfree_skb(skb);
+}
+
+static void ath9k_mark_paused(struct ath_wiphy *aphy)
+{
+ struct ath_softc *sc = aphy->sc;
+ aphy->state = ATH_WIPHY_PAUSED;
+ if (!__ath9k_wiphy_pausing(sc))
+ queue_work(sc->hw->workqueue, &sc->chan_work);
+}
+
+static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+ struct ath_wiphy *aphy = data;
+ struct ath_vif *avp = (void *) vif->drv_priv;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ if (!vif->bss_conf.assoc) {
+ ath9k_mark_paused(aphy);
+ break;
+ }
+ /* TODO: could avoid this if already in PS mode */
+ if (ath9k_send_nullfunc(aphy, vif, avp->bssid, 1)) {
+ printk(KERN_DEBUG "%s: failed to send PS nullfunc\n",
+ __func__);
+ ath9k_mark_paused(aphy);
+ }
+ break;
+ case NL80211_IFTYPE_AP:
+ /* Beacon transmission is paused by aphy->state change */
+ ath9k_mark_paused(aphy);
+ break;
+ default:
+ break;
+ }
+}
+
+/* caller must hold wiphy_lock */
+static int __ath9k_wiphy_pause(struct ath_wiphy *aphy)
+{
+ ieee80211_stop_queues(aphy->hw);
+ aphy->state = ATH_WIPHY_PAUSING;
+ /*
+ * TODO: handle PAUSING->PAUSED for the case where there are multiple
+ * active vifs (now we do it on the first vif getting ready; should be
+ * on the last)
+ */
+ ieee80211_iterate_active_interfaces_atomic(aphy->hw, ath9k_pause_iter,
+ aphy);
+ return 0;
+}
+
+int ath9k_wiphy_pause(struct ath_wiphy *aphy)
+{
+ int ret;
+ spin_lock_bh(&aphy->sc->wiphy_lock);
+ ret = __ath9k_wiphy_pause(aphy);
+ spin_unlock_bh(&aphy->sc->wiphy_lock);
+ return ret;
+}
+
+static void ath9k_unpause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+ struct ath_wiphy *aphy = data;
+ struct ath_vif *avp = (void *) vif->drv_priv;
+
+ switch (vif->type) {
+ case NL80211_IFTYPE_STATION:
+ if (!vif->bss_conf.assoc)
+ break;
+ ath9k_send_nullfunc(aphy, vif, avp->bssid, 0);
+ break;
+ case NL80211_IFTYPE_AP:
+ /* Beacon transmission is re-enabled by aphy->state change */
+ break;
+ default:
+ break;
+ }
+}
+
+/* caller must hold wiphy_lock */
+static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy)
+{
+ ieee80211_iterate_active_interfaces_atomic(aphy->hw,
+ ath9k_unpause_iter, aphy);
+ aphy->state = ATH_WIPHY_ACTIVE;
+ ieee80211_wake_queues(aphy->hw);
+ return 0;
+}
+
+int ath9k_wiphy_unpause(struct ath_wiphy *aphy)
+{
+ int ret;
+ spin_lock_bh(&aphy->sc->wiphy_lock);
+ ret = __ath9k_wiphy_unpause(aphy);
+ spin_unlock_bh(&aphy->sc->wiphy_lock);
+ return ret;
+}
+
+static void __ath9k_wiphy_mark_all_paused(struct ath_softc *sc)
+{
+ int i;
+ if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE)
+ sc->pri_wiphy->state = ATH_WIPHY_PAUSED;
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] &&
+ sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE)
+ sc->sec_wiphy[i]->state = ATH_WIPHY_PAUSED;
+ }
+}
+
+/* caller must hold wiphy_lock */
+static void __ath9k_wiphy_pause_all(struct ath_softc *sc)
+{
+ int i;
+ if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
+ __ath9k_wiphy_pause(sc->pri_wiphy);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] &&
+ sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
+ __ath9k_wiphy_pause(sc->sec_wiphy[i]);
+ }
+}
+
+int ath9k_wiphy_select(struct ath_wiphy *aphy)
+{
+ struct ath_softc *sc = aphy->sc;
+ bool now;
+
+ spin_lock_bh(&sc->wiphy_lock);
+ if (__ath9k_wiphy_scanning(sc)) {
+ /*
+ * For now, we are using mac80211 sw scan and it expects to
+ * have full control over channel changes, so avoid wiphy
+ * scheduling during a scan. This could be optimized if the
+ * scanning control were moved into the driver.
+ */
+ spin_unlock_bh(&sc->wiphy_lock);
+ return -EBUSY;
+ }
+ if (__ath9k_wiphy_pausing(sc)) {
+ if (sc->wiphy_select_failures == 0)
+ sc->wiphy_select_first_fail = jiffies;
+ sc->wiphy_select_failures++;
+ if (time_after(jiffies, sc->wiphy_select_first_fail + HZ / 2))
+ {
+ printk(KERN_DEBUG "ath9k: Previous wiphy select timed "
+ "out; disable/enable hw to recover\n");
+ __ath9k_wiphy_mark_all_paused(sc);
+ /*
+ * TODO: this workaround to fix hardware is unlikely to
+ * be specific to virtual wiphy changes. It can happen
+ * on normal channel change, too, and as such, this
+ * should really be made more generic. For example,
+ * tricker radio disable/enable on GTT interrupt burst
+ * (say, 10 GTT interrupts received without any TX
+ * frame being completed)
+ */
+ spin_unlock_bh(&sc->wiphy_lock);
+ ath_radio_disable(sc);
+ ath_radio_enable(sc);
+ queue_work(aphy->sc->hw->workqueue,
+ &aphy->sc->chan_work);
+ return -EBUSY; /* previous select still in progress */
+ }
+ spin_unlock_bh(&sc->wiphy_lock);
+ return -EBUSY; /* previous select still in progress */
+ }
+ sc->wiphy_select_failures = 0;
+
+ /* Store the new channel */
+ sc->chan_idx = aphy->chan_idx;
+ sc->chan_is_ht = aphy->chan_is_ht;
+ sc->next_wiphy = aphy;
+
+ __ath9k_wiphy_pause_all(sc);
+ now = !__ath9k_wiphy_pausing(aphy->sc);
+ spin_unlock_bh(&sc->wiphy_lock);
+
+ if (now) {
+ /* Ready to request channel change immediately */
+ queue_work(aphy->sc->hw->workqueue, &aphy->sc->chan_work);
+ }
+
+ /*
+ * wiphys will be unpaused in ath9k_tx_status() once channel has been
+ * changed if any wiphy needs time to become paused.
+ */
+
+ return 0;
+}
+
+bool ath9k_wiphy_started(struct ath_softc *sc)
+{
+ int i;
+ spin_lock_bh(&sc->wiphy_lock);
+ if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
+ spin_unlock_bh(&sc->wiphy_lock);
+ return true;
+ }
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] &&
+ sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) {
+ spin_unlock_bh(&sc->wiphy_lock);
+ return true;
+ }
+ }
+ spin_unlock_bh(&sc->wiphy_lock);
+ return false;
+}
+
+static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy,
+ struct ath_wiphy *selected)
+{
+ if (selected->state == ATH_WIPHY_SCAN) {
+ if (aphy == selected)
+ return;
+ /*
+ * Pause all other wiphys for the duration of the scan even if
+ * they are on the current channel now.
+ */
+ } else if (aphy->chan_idx == selected->chan_idx)
+ return;
+ aphy->state = ATH_WIPHY_PAUSED;
+ ieee80211_stop_queues(aphy->hw);
+}
+
+void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
+ struct ath_wiphy *selected)
+{
+ int i;
+ spin_lock_bh(&sc->wiphy_lock);
+ if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
+ ath9k_wiphy_pause_chan(sc->pri_wiphy, selected);
+ for (i = 0; i < sc->num_sec_wiphy; i++) {
+ if (sc->sec_wiphy[i] &&
+ sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
+ ath9k_wiphy_pause_chan(sc->sec_wiphy[i], selected);
+ }
+ spin_unlock_bh(&sc->wiphy_lock);
+}
+
+void ath9k_wiphy_work(struct work_struct *work)
+{
+ struct ath_softc *sc = container_of(work, struct ath_softc,
+ wiphy_work.work);
+ struct ath_wiphy *aphy = NULL;
+ bool first = true;
+
+ spin_lock_bh(&sc->wiphy_lock);
+
+ if (sc->wiphy_scheduler_int == 0) {
+ /* wiphy scheduler is disabled */
+ spin_unlock_bh(&sc->wiphy_lock);
+ return;
+ }
+
+try_again:
+ sc->wiphy_scheduler_index++;
+ while (sc->wiphy_scheduler_index <= sc->num_sec_wiphy) {
+ aphy = sc->sec_wiphy[sc->wiphy_scheduler_index - 1];
+ if (aphy && aphy->state != ATH_WIPHY_INACTIVE)
+ break;
+
+ sc->wiphy_scheduler_index++;
+ aphy = NULL;
+ }
+ if (aphy == NULL) {
+ sc->wiphy_scheduler_index = 0;
+ if (sc->pri_wiphy->state == ATH_WIPHY_INACTIVE) {
+ if (first) {
+ first = false;
+ goto try_again;
+ }
+ /* No wiphy is ready to be scheduled */
+ } else
+ aphy = sc->pri_wiphy;
+ }
+
+ spin_unlock_bh(&sc->wiphy_lock);
+
+ if (aphy &&
+ aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN &&
+ ath9k_wiphy_select(aphy)) {
+ printk(KERN_DEBUG "ath9k: Failed to schedule virtual wiphy "
+ "change\n");
+ }
+
+ queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
+ sc->wiphy_scheduler_int);
+}
+
+void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
+{
+ cancel_delayed_work_sync(&sc->wiphy_work);
+ sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int);
+ if (sc->wiphy_scheduler_int)
+ queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
+ sc->wiphy_scheduler_int);
+}
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index c92f0c6e4adc..689bdbf78808 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include "core.h"
+#include "ath9k.h"
#define BITS_PER_BYTE 8
#define OFDM_PLCP_BITS 22
@@ -55,94 +55,23 @@ static u32 bits_per_symbol[][2] = {
#define IS_HT_RATE(_rate) ((_rate) & 0x80)
-/*
- * Insert a chain of ath_buf (descriptors) on a txq and
- * assume the descriptors are already chained together by caller.
- * NB: must be called with txq lock held
- */
-
+static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid,
+ struct list_head *bf_head);
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+ struct list_head *bf_q,
+ int txok, int sendbar);
static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
- struct list_head *head)
-{
- struct ath_hal *ah = sc->sc_ah;
- struct ath_buf *bf;
-
- /*
- * Insert the frame on the outbound list and
- * pass it on to the hardware.
- */
-
- if (list_empty(head))
- return;
-
- bf = list_first_entry(head, struct ath_buf, list);
-
- list_splice_tail_init(head, &txq->axq_q);
- txq->axq_depth++;
- txq->axq_totalqueued++;
- txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
-
- DPRINTF(sc, ATH_DBG_QUEUE,
- "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
-
- if (txq->axq_link == NULL) {
- ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
- DPRINTF(sc, ATH_DBG_XMIT,
- "TXDP[%u] = %llx (%p)\n",
- txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
- } else {
- *txq->axq_link = bf->bf_daddr;
- DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
- txq->axq_qnum, txq->axq_link,
- ito64(bf->bf_daddr), bf->bf_desc);
- }
- txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
- ath9k_hw_txstart(ah, txq->axq_qnum);
-}
-
-static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
- struct ath_xmit_status *tx_status)
-{
- struct ieee80211_hw *hw = sc->hw;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
- int hdrlen, padsize;
-
- DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
-
- if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
- tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
- kfree(tx_info_priv);
- tx_info->rate_driver_data[0] = NULL;
- }
-
- if (tx_status->flags & ATH_TX_BAR) {
- tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
- tx_status->flags &= ~ATH_TX_BAR;
- }
-
- if (!(tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
- /* Frame was ACKed */
- tx_info->flags |= IEEE80211_TX_STAT_ACK;
- }
-
- tx_info->status.rates[0].count = tx_status->retries + 1;
-
- hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- padsize = hdrlen & 3;
- if (padsize && hdrlen >= 24) {
- /*
- * Remove MAC header padding before giving the frame back to
- * mac80211.
- */
- memmove(skb->data + padsize, skb->data, hdrlen);
- skb_pull(skb, padsize);
- }
-
- ieee80211_tx_status(hw, skb);
-}
+ struct list_head *head);
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf);
+static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
+ int txok);
+static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
+ int nbad, int txok, bool update_rc);
-/* Check if it's okay to send out aggregates */
+/*********************/
+/* Aggregation logic */
+/*********************/
static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno)
{
@@ -156,232 +85,19 @@ static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno)
return 0;
}
-static void ath_get_beaconconfig(struct ath_softc *sc, int if_id,
- struct ath_beacon_config *conf)
-{
- struct ieee80211_hw *hw = sc->hw;
-
- /* fill in beacon config data */
-
- conf->beacon_interval = hw->conf.beacon_int;
- conf->listen_interval = 100;
- conf->dtim_count = 1;
- conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
-}
-
-/* Calculate Atheros packet type from IEEE80211 packet header */
-
-static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr;
- enum ath9k_pkt_type htype;
- __le16 fc;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = hdr->frame_control;
-
- if (ieee80211_is_beacon(fc))
- htype = ATH9K_PKT_TYPE_BEACON;
- else if (ieee80211_is_probe_resp(fc))
- htype = ATH9K_PKT_TYPE_PROBE_RESP;
- else if (ieee80211_is_atim(fc))
- htype = ATH9K_PKT_TYPE_ATIM;
- else if (ieee80211_is_pspoll(fc))
- htype = ATH9K_PKT_TYPE_PSPOLL;
- else
- htype = ATH9K_PKT_TYPE_NORMAL;
-
- return htype;
-}
-
-static bool is_pae(struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr;
- __le16 fc;
-
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = hdr->frame_control;
-
- if (ieee80211_is_data(fc)) {
- if (ieee80211_is_nullfunc(fc) ||
- /* Port Access Entity (IEEE 802.1X) */
- (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
- return true;
- }
- }
-
- return false;
-}
-
-static int get_hw_crypto_keytype(struct sk_buff *skb)
-{
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-
- if (tx_info->control.hw_key) {
- if (tx_info->control.hw_key->alg == ALG_WEP)
- return ATH9K_KEY_TYPE_WEP;
- else if (tx_info->control.hw_key->alg == ALG_TKIP)
- return ATH9K_KEY_TYPE_TKIP;
- else if (tx_info->control.hw_key->alg == ALG_CCMP)
- return ATH9K_KEY_TYPE_AES;
- }
-
- return ATH9K_KEY_TYPE_CLEAR;
-}
-
-/* Called only when tx aggregation is enabled and HT is supported */
-
-static void assign_aggr_tid_seqno(struct sk_buff *skb,
- struct ath_buf *bf)
-{
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *hdr;
- struct ath_node *an;
- struct ath_atx_tid *tid;
- __le16 fc;
- u8 *qc;
-
- if (!tx_info->control.sta)
- return;
-
- an = (struct ath_node *)tx_info->control.sta->drv_priv;
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = hdr->frame_control;
-
- /* Get tidno */
-
- if (ieee80211_is_data_qos(fc)) {
- qc = ieee80211_get_qos_ctl(hdr);
- bf->bf_tidno = qc[0] & 0xf;
- }
-
- /* Get seqno */
- /* For HT capable stations, we save tidno for later use.
- * We also override seqno set by upper layer with the one
- * in tx aggregation state.
- *
- * If fragmentation is on, the sequence number is
- * not overridden, since it has been
- * incremented by the fragmentation routine.
- *
- * FIXME: check if the fragmentation threshold exceeds
- * IEEE80211 max.
- */
- tid = ATH_AN_2_TID(an, bf->bf_tidno);
- hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
- IEEE80211_SEQ_SEQ_SHIFT);
- bf->bf_seqno = tid->seq_next;
- INCR(tid->seq_next, IEEE80211_SEQ_MAX);
-}
-
-static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
- struct ath_txq *txq)
-{
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- int flags = 0;
-
- flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
- flags |= ATH9K_TXDESC_INTREQ;
-
- if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
- flags |= ATH9K_TXDESC_NOACK;
- if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
- flags |= ATH9K_TXDESC_RTSENA;
-
- return flags;
-}
-
-static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
-{
- struct ath_buf *bf = NULL;
-
- spin_lock_bh(&sc->tx.txbuflock);
-
- if (unlikely(list_empty(&sc->tx.txbuf))) {
- spin_unlock_bh(&sc->tx.txbuflock);
- return NULL;
- }
-
- bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
- list_del(&bf->list);
-
- spin_unlock_bh(&sc->tx.txbuflock);
-
- return bf;
-}
-
-/* To complete a chain of buffers associated a frame */
-
-static void ath_tx_complete_buf(struct ath_softc *sc,
- struct ath_buf *bf,
- struct list_head *bf_q,
- int txok, int sendbar)
-{
- struct sk_buff *skb = bf->bf_mpdu;
- struct ath_xmit_status tx_status;
- unsigned long flags;
-
- /*
- * Set retry information.
- * NB: Don't use the information in the descriptor, because the frame
- * could be software retried.
- */
- tx_status.retries = bf->bf_retries;
- tx_status.flags = 0;
-
- if (sendbar)
- tx_status.flags = ATH_TX_BAR;
-
- if (!txok) {
- tx_status.flags |= ATH_TX_ERROR;
-
- if (bf_isxretried(bf))
- tx_status.flags |= ATH_TX_XRETRY;
- }
-
- /* Unmap this frame */
- pci_unmap_single(sc->pdev,
- bf->bf_dmacontext,
- skb->len,
- PCI_DMA_TODEVICE);
- /* complete this frame */
- ath_tx_complete(sc, skb, &tx_status);
-
- /*
- * Return the list of ath_buf of this mpdu to free queue
- */
- spin_lock_irqsave(&sc->tx.txbuflock, flags);
- list_splice_tail_init(bf_q, &sc->tx.txbuf);
- spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
-}
-
-/*
- * queue up a dest/ac pair for tx scheduling
- * NB: must be called with txq lock held
- */
-
static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
{
struct ath_atx_ac *ac = tid->ac;
- /*
- * if tid is paused, hold off
- */
if (tid->paused)
return;
- /*
- * add tid to ac atmost once
- */
if (tid->sched)
return;
tid->sched = true;
list_add_tail(&tid->list, &ac->tid_q);
- /*
- * add node ac to txq atmost once
- */
if (ac->sched)
return;
@@ -389,22 +105,16 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
list_add_tail(&ac->list, &txq->axq_acq);
}
-/* pause a tid */
-
static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
spin_lock_bh(&txq->axq_lock);
-
tid->paused++;
-
spin_unlock_bh(&txq->axq_lock);
}
-/* resume a tid and schedule aggregate */
-
-void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
@@ -419,63 +129,39 @@ void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
if (list_empty(&tid->buf_q))
goto unlock;
- /*
- * Add this TID to scheduler and try to send out aggregates
- */
ath_tx_queue_tid(txq, tid);
ath_txq_schedule(sc, txq);
unlock:
spin_unlock_bh(&txq->axq_lock);
}
-/* Compute the number of bad frames */
-
-static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
- int txok)
+static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
- struct ath_buf *bf_last = bf->bf_lastbf;
- struct ath_desc *ds = bf_last->bf_desc;
- u16 seq_st = 0;
- u32 ba[WME_BA_BMP_SIZE >> 5];
- int ba_index;
- int nbad = 0;
- int isaggr = 0;
-
- if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
- return 0;
+ struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
+ struct ath_buf *bf;
+ struct list_head bf_head;
+ INIT_LIST_HEAD(&bf_head);
- isaggr = bf_isaggr(bf);
- if (isaggr) {
- seq_st = ATH_DS_BA_SEQ(ds);
- memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
- }
+ ASSERT(tid->paused > 0);
+ spin_lock_bh(&txq->axq_lock);
- while (bf) {
- ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
- if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
- nbad++;
+ tid->paused--;
- bf = bf->bf_next;
+ if (tid->paused > 0) {
+ spin_unlock_bh(&txq->axq_lock);
+ return;
}
- return nbad;
-}
-
-static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
-{
- struct sk_buff *skb;
- struct ieee80211_hdr *hdr;
-
- bf->bf_state.bf_type |= BUF_RETRY;
- bf->bf_retries++;
+ while (!list_empty(&tid->buf_q)) {
+ bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+ ASSERT(!bf_isretried(bf));
+ list_move_tail(&bf->list, &bf_head);
+ ath_tx_send_ht_normal(sc, txq, tid, &bf_head);
+ }
- skb = bf->bf_mpdu;
- hdr = (struct ieee80211_hdr *)skb->data;
- hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
+ spin_unlock_bh(&txq->axq_lock);
}
-/* Update block ack window */
-
static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
int seqno)
{
@@ -492,296 +178,150 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
}
}
-/*
- * ath_pkt_dur - compute packet duration (NB: not NAV)
- *
- * rix - rate index
- * pktlen - total bytes (delims + data + fcs + pads + pad delims)
- * width - 0 for 20 MHz, 1 for 40 MHz
- * half_gi - to use 4us v/s 3.6 us for symbol time
- */
-static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
- int width, int half_gi, bool shortPreamble)
+static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
+ struct ath_buf *bf)
{
- struct ath_rate_table *rate_table = sc->cur_rate_table;
- u32 nbits, nsymbits, duration, nsymbols;
- u8 rc;
- int streams, pktlen;
-
- pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
- rc = rate_table->info[rix].ratecode;
-
- /* for legacy rates, use old function to compute packet duration */
- if (!IS_HT_RATE(rc))
- return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen,
- rix, shortPreamble);
+ int index, cindex;
- /* find number of symbols: PLCP + data */
- nbits = (pktlen << 3) + OFDM_PLCP_BITS;
- nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
- nsymbols = (nbits + nsymbits - 1) / nsymbits;
+ if (bf_isretried(bf))
+ return;
- if (!half_gi)
- duration = SYMBOL_TIME(nsymbols);
- else
- duration = SYMBOL_TIME_HALFGI(nsymbols);
+ index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
+ cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
- /* addup duration for legacy/ht training and signal fields */
- streams = HT_RC_2_STREAMS(rc);
- duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
+ ASSERT(tid->tx_buf[cindex] == NULL);
+ tid->tx_buf[cindex] = bf;
- return duration;
+ if (index >= ((tid->baw_tail - tid->baw_head) &
+ (ATH_TID_MAX_BUFS - 1))) {
+ tid->baw_tail = cindex;
+ INCR(tid->baw_tail, ATH_TID_MAX_BUFS);
+ }
}
-/* Rate module function to set rate related fields in tx descriptor */
+/*
+ * TODO: For frame(s) that are in the retry state, we will reuse the
+ * sequence number(s) without setting the retry bit. The
+ * alternative is to give up on these and BAR the receiver's window
+ * forward.
+ */
+static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid)
-static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
{
- struct ath_hal *ah = sc->sc_ah;
- struct ath_rate_table *rt;
- struct ath_desc *ds = bf->bf_desc;
- struct ath_desc *lastds = bf->bf_lastbf->bf_desc;
- struct ath9k_11n_rate_series series[4];
- struct sk_buff *skb;
- struct ieee80211_tx_info *tx_info;
- struct ieee80211_tx_rate *rates;
- struct ieee80211_hdr *hdr;
- int i, flags, rtsctsena = 0;
- u32 ctsduration = 0;
- u8 rix = 0, cix, ctsrate = 0;
- __le16 fc;
-
- memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
-
- skb = (struct sk_buff *)bf->bf_mpdu;
- hdr = (struct ieee80211_hdr *)skb->data;
- fc = hdr->frame_control;
- tx_info = IEEE80211_SKB_CB(skb);
- rates = tx_info->control.rates;
-
- if (ieee80211_has_morefrags(fc) ||
- (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
- rates[1].count = rates[2].count = rates[3].count = 0;
- rates[1].idx = rates[2].idx = rates[3].idx = 0;
- rates[0].count = ATH_TXMAXTRY;
- }
+ struct ath_buf *bf;
+ struct list_head bf_head;
+ INIT_LIST_HEAD(&bf_head);
- /* get the cix for the lowest valid rix */
- rt = sc->cur_rate_table;
- for (i = 3; i >= 0; i--) {
- if (rates[i].count && (rates[i].idx >= 0)) {
- rix = rates[i].idx;
+ for (;;) {
+ if (list_empty(&tid->buf_q))
break;
- }
- }
-
- flags = (bf->bf_flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA));
- cix = rt->info[rix].ctrl_rate;
-
- /*
- * If 802.11g protection is enabled, determine whether to use RTS/CTS or
- * just CTS. Note that this is only done for OFDM/HT unicast frames.
- */
- if (sc->sc_protmode != PROT_M_NONE && !(bf->bf_flags & ATH9K_TXDESC_NOACK)
- && (rt->info[rix].phy == WLAN_RC_PHY_OFDM ||
- WLAN_RC_PHY_HT(rt->info[rix].phy))) {
- if (sc->sc_protmode == PROT_M_RTSCTS)
- flags = ATH9K_TXDESC_RTSENA;
- else if (sc->sc_protmode == PROT_M_CTSONLY)
- flags = ATH9K_TXDESC_CTSENA;
-
- cix = rt->info[sc->sc_protrix].ctrl_rate;
- rtsctsena = 1;
- }
-
- /* For 11n, the default behavior is to enable RTS for hw retried frames.
- * We enable the global flag here and let rate series flags determine
- * which rates will actually use RTS.
- */
- if ((ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) && bf_isdata(bf)) {
- /* 802.11g protection not needed, use our default behavior */
- if (!rtsctsena)
- flags = ATH9K_TXDESC_RTSENA;
- }
-
- /* Set protection if aggregate protection on */
- if (sc->sc_config.ath_aggr_prot &&
- (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
- flags = ATH9K_TXDESC_RTSENA;
- cix = rt->info[sc->sc_protrix].ctrl_rate;
- rtsctsena = 1;
- }
-
- /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
- if (bf_isaggr(bf) && (bf->bf_al > ah->ah_caps.rts_aggr_limit))
- flags &= ~(ATH9K_TXDESC_RTSENA);
- /*
- * CTS transmit rate is derived from the transmit rate by looking in the
- * h/w rate table. We must also factor in whether or not a short
- * preamble is to be used. NB: cix is set above where RTS/CTS is enabled
- */
- ctsrate = rt->info[cix].ratecode |
- (bf_isshpreamble(bf) ? rt->info[cix].short_preamble : 0);
-
- for (i = 0; i < 4; i++) {
- if (!rates[i].count || (rates[i].idx < 0))
- continue;
-
- rix = rates[i].idx;
-
- series[i].Rate = rt->info[rix].ratecode |
- (bf_isshpreamble(bf) ? rt->info[rix].short_preamble : 0);
-
- series[i].Tries = rates[i].count;
-
- series[i].RateFlags = (
- (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) ?
- ATH9K_RATESERIES_RTS_CTS : 0) |
- ((rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ?
- ATH9K_RATESERIES_2040 : 0) |
- ((rates[i].flags & IEEE80211_TX_RC_SHORT_GI) ?
- ATH9K_RATESERIES_HALFGI : 0);
-
- series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
- (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0,
- (rates[i].flags & IEEE80211_TX_RC_SHORT_GI),
- bf_isshpreamble(bf));
+ bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+ list_move_tail(&bf->list, &bf_head);
- series[i].ChSel = sc->sc_tx_chainmask;
+ if (bf_isretried(bf))
+ ath_tx_update_baw(sc, tid, bf->bf_seqno);
- if (rtsctsena)
- series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
+ spin_unlock(&txq->axq_lock);
+ ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+ spin_lock(&txq->axq_lock);
}
- /* set dur_update_en for l-sig computation except for PS-Poll frames */
- ath9k_hw_set11n_ratescenario(ah, ds, lastds, !bf_ispspoll(bf),
- ctsrate, ctsduration,
- series, 4, flags);
-
- if (sc->sc_config.ath_aggr_prot && flags)
- ath9k_hw_set11n_burstduration(ah, ds, 8192);
+ tid->seq_next = tid->seq_start;
+ tid->baw_tail = tid->baw_head;
}
-/*
- * Function to send a normal HT (non-AMPDU) frame
- * NB: must be called with txq lock held
- */
-static int ath_tx_send_normal(struct ath_softc *sc,
- struct ath_txq *txq,
- struct ath_atx_tid *tid,
- struct list_head *bf_head)
+static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
{
- struct ath_buf *bf;
-
- BUG_ON(list_empty(bf_head));
-
- bf = list_first_entry(bf_head, struct ath_buf, list);
- bf->bf_state.bf_type &= ~BUF_AMPDU; /* regular HT frame */
-
- /* update starting sequence number for subsequent ADDBA request */
- INCR(tid->seq_start, IEEE80211_SEQ_MAX);
+ struct sk_buff *skb;
+ struct ieee80211_hdr *hdr;
- /* Queue to h/w without aggregation */
- bf->bf_nframes = 1;
- bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */
- ath_buf_set_rate(sc, bf);
- ath_tx_txqaddbuf(sc, txq, bf_head);
+ bf->bf_state.bf_type |= BUF_RETRY;
+ bf->bf_retries++;
- return 0;
+ skb = bf->bf_mpdu;
+ hdr = (struct ieee80211_hdr *)skb->data;
+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
}
-/* flush tid's software queue and send frames as non-ampdu's */
-
-static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
{
- struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
- struct ath_buf *bf;
- struct list_head bf_head;
- INIT_LIST_HEAD(&bf_head);
+ struct ath_buf *tbf;
- ASSERT(tid->paused > 0);
- spin_lock_bh(&txq->axq_lock);
+ spin_lock_bh(&sc->tx.txbuflock);
+ ASSERT(!list_empty((&sc->tx.txbuf)));
+ tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+ list_del(&tbf->list);
+ spin_unlock_bh(&sc->tx.txbuflock);
- tid->paused--;
+ ATH_TXBUF_RESET(tbf);
- if (tid->paused > 0) {
- spin_unlock_bh(&txq->axq_lock);
- return;
- }
+ tbf->bf_mpdu = bf->bf_mpdu;
+ tbf->bf_buf_addr = bf->bf_buf_addr;
+ *(tbf->bf_desc) = *(bf->bf_desc);
+ tbf->bf_state = bf->bf_state;
+ tbf->bf_dmacontext = bf->bf_dmacontext;
- while (!list_empty(&tid->buf_q)) {
- bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
- ASSERT(!bf_isretried(bf));
- list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
- ath_tx_send_normal(sc, txq, tid, &bf_head);
- }
-
- spin_unlock_bh(&txq->axq_lock);
+ return tbf;
}
-/* Completion routine of an aggregate */
-
-static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
- struct ath_txq *txq,
- struct ath_buf *bf,
- struct list_head *bf_q,
- int txok)
+static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_buf *bf, struct list_head *bf_q,
+ int txok)
{
struct ath_node *an = NULL;
struct sk_buff *skb;
- struct ieee80211_tx_info *tx_info;
+ struct ieee80211_sta *sta;
+ struct ieee80211_hdr *hdr;
struct ath_atx_tid *tid = NULL;
- struct ath_buf *bf_last = bf->bf_lastbf;
+ struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
struct ath_desc *ds = bf_last->bf_desc;
- struct ath_buf *bf_next, *bf_lastq = NULL;
struct list_head bf_head, bf_pending;
- u16 seq_st = 0;
+ u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
u32 ba[WME_BA_BMP_SIZE >> 5];
- int isaggr, txfail, txpending, sendbar = 0, needreset = 0;
+ int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
+ bool rc_update = true;
skb = (struct sk_buff *)bf->bf_mpdu;
- tx_info = IEEE80211_SKB_CB(skb);
+ hdr = (struct ieee80211_hdr *)skb->data;
- if (tx_info->control.sta) {
- an = (struct ath_node *)tx_info->control.sta->drv_priv;
- tid = ATH_AN_2_TID(an, bf->bf_tidno);
+ rcu_read_lock();
+
+ sta = ieee80211_find_sta(sc->hw, hdr->addr1);
+ if (!sta) {
+ rcu_read_unlock();
+ return;
}
+ an = (struct ath_node *)sta->drv_priv;
+ tid = ATH_AN_2_TID(an, bf->bf_tidno);
+
isaggr = bf_isaggr(bf);
- if (isaggr) {
- if (txok) {
- if (ATH_DS_TX_BA(ds)) {
- /*
- * extract starting sequence and
- * block-ack bitmap
- */
- seq_st = ATH_DS_BA_SEQ(ds);
- memcpy(ba,
- ATH_DS_BA_BITMAP(ds),
- WME_BA_BMP_SIZE >> 3);
- } else {
- memset(ba, 0, WME_BA_BMP_SIZE >> 3);
+ memset(ba, 0, WME_BA_BMP_SIZE >> 3);
- /*
- * AR5416 can become deaf/mute when BA
- * issue happens. Chip needs to be reset.
- * But AP code may have sychronization issues
- * when perform internal reset in this routine.
- * Only enable reset in STA mode for now.
- */
- if (sc->sc_ah->ah_opmode ==
- NL80211_IFTYPE_STATION)
- needreset = 1;
- }
+ if (isaggr && txok) {
+ if (ATH_DS_TX_BA(ds)) {
+ seq_st = ATH_DS_BA_SEQ(ds);
+ memcpy(ba, ATH_DS_BA_BITMAP(ds),
+ WME_BA_BMP_SIZE >> 3);
} else {
- memset(ba, 0, WME_BA_BMP_SIZE >> 3);
+ /*
+ * AR5416 can become deaf/mute when BA
+ * issue happens. Chip needs to be reset.
+ * But AP code may have sychronization issues
+ * when perform internal reset in this routine.
+ * Only enable reset in STA mode for now.
+ */
+ if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION)
+ needreset = 1;
}
}
INIT_LIST_HEAD(&bf_pending);
INIT_LIST_HEAD(&bf_head);
+ nbad = ath_tx_num_badfrms(sc, bf, txok);
while (bf) {
txfail = txpending = 0;
bf_next = bf->bf_next;
@@ -789,10 +329,11 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
/* transmit completion, subframe is
* acked by block ack */
+ acked_cnt++;
} else if (!isaggr && txok) {
/* transmit completion */
+ acked_cnt++;
} else {
-
if (!(tid->state & AGGR_CLEANUP) &&
ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
@@ -802,6 +343,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
bf->bf_state.bf_type |= BUF_XRETRY;
txfail = 1;
sendbar = 1;
+ txfail_cnt++;
}
} else {
/*
@@ -811,37 +353,12 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
txfail = 1;
}
}
- /*
- * Remove ath_buf's of this sub-frame from aggregate queue.
- */
- if (bf_next == NULL) { /* last subframe in the aggregate */
- ASSERT(bf->bf_lastfrm == bf_last);
-
- /*
- * The last descriptor of the last sub frame could be
- * a holding descriptor for h/w. If that's the case,
- * bf->bf_lastfrm won't be in the bf_q.
- * Make sure we handle bf_q properly here.
- */
- if (!list_empty(bf_q)) {
- bf_lastq = list_entry(bf_q->prev,
- struct ath_buf, list);
- list_cut_position(&bf_head,
- bf_q, &bf_lastq->list);
- } else {
- /*
- * XXX: if the last subframe only has one
- * descriptor which is also being used as
- * a holding descriptor. Then the ath_buf
- * is not in the bf_q at all.
- */
- INIT_LIST_HEAD(&bf_head);
- }
+ if (bf_next == NULL) {
+ INIT_LIST_HEAD(&bf_head);
} else {
ASSERT(!list_empty(bf_q));
- list_cut_position(&bf_head,
- bf_q, &bf->bf_lastfrm->list);
+ list_move_tail(&bf->list, &bf_head);
}
if (!txpending) {
@@ -853,62 +370,29 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
ath_tx_update_baw(sc, tid, bf->bf_seqno);
spin_unlock_bh(&txq->axq_lock);
- /* complete this sub-frame */
+ if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
+ ath_tx_rc_status(bf, ds, nbad, txok, true);
+ rc_update = false;
+ } else {
+ ath_tx_rc_status(bf, ds, nbad, txok, false);
+ }
+
ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
} else {
- /*
- * retry the un-acked ones
- */
- /*
- * XXX: if the last descriptor is holding descriptor,
- * in order to requeue the frame to software queue, we
- * need to allocate a new descriptor and
- * copy the content of holding descriptor to it.
- */
+ /* retry the un-acked ones */
if (bf->bf_next == NULL &&
bf_last->bf_status & ATH_BUFSTATUS_STALE) {
struct ath_buf *tbf;
- /* allocate new descriptor */
- spin_lock_bh(&sc->tx.txbuflock);
- ASSERT(!list_empty((&sc->tx.txbuf)));
- tbf = list_first_entry(&sc->tx.txbuf,
- struct ath_buf, list);
- list_del(&tbf->list);
- spin_unlock_bh(&sc->tx.txbuflock);
-
- ATH_TXBUF_RESET(tbf);
-
- /* copy descriptor content */
- tbf->bf_mpdu = bf_last->bf_mpdu;
- tbf->bf_buf_addr = bf_last->bf_buf_addr;
- *(tbf->bf_desc) = *(bf_last->bf_desc);
-
- /* link it to the frame */
- if (bf_lastq) {
- bf_lastq->bf_desc->ds_link =
- tbf->bf_daddr;
- bf->bf_lastfrm = tbf;
- ath9k_hw_cleartxdesc(sc->sc_ah,
- bf->bf_lastfrm->bf_desc);
- } else {
- tbf->bf_state = bf_last->bf_state;
- tbf->bf_lastfrm = tbf;
- ath9k_hw_cleartxdesc(sc->sc_ah,
- tbf->bf_lastfrm->bf_desc);
-
- /* copy the DMA context */
- tbf->bf_dmacontext =
- bf_last->bf_dmacontext;
- }
+ tbf = ath_clone_txbuf(sc, bf_last);
+ ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
list_add_tail(&tbf->list, &bf_head);
} else {
/*
* Clear descriptor status words for
* software retry
*/
- ath9k_hw_cleartxdesc(sc->sc_ah,
- bf->bf_lastfrm->bf_desc);
+ ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc);
}
/*
@@ -922,332 +406,33 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
}
if (tid->state & AGGR_CLEANUP) {
- /* check to see if we're done with cleaning the h/w queue */
- spin_lock_bh(&txq->axq_lock);
-
if (tid->baw_head == tid->baw_tail) {
tid->state &= ~AGGR_ADDBA_COMPLETE;
tid->addba_exchangeattempts = 0;
- spin_unlock_bh(&txq->axq_lock);
-
tid->state &= ~AGGR_CLEANUP;
/* send buffered frames as singles */
ath_tx_flush_tid(sc, tid);
- } else
- spin_unlock_bh(&txq->axq_lock);
-
+ }
+ rcu_read_unlock();
return;
}
- /*
- * prepend un-acked frames to the beginning of the pending frame queue
- */
+ /* prepend un-acked frames to the beginning of the pending frame queue */
if (!list_empty(&bf_pending)) {
spin_lock_bh(&txq->axq_lock);
- /* Note: we _prepend_, we _do_not_ at to
- * the end of the queue ! */
list_splice(&bf_pending, &tid->buf_q);
ath_tx_queue_tid(txq, tid);
spin_unlock_bh(&txq->axq_lock);
}
+ rcu_read_unlock();
+
if (needreset)
ath_reset(sc, false);
-
- return;
-}
-
-static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, int nbad)
-{
- struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-
- tx_info_priv->update_rc = false;
- if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
- tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
-
- if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
- (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
- if (bf_isdata(bf)) {
- memcpy(&tx_info_priv->tx, &ds->ds_txstat,
- sizeof(tx_info_priv->tx));
- tx_info_priv->n_frames = bf->bf_nframes;
- tx_info_priv->n_bad_frames = nbad;
- tx_info_priv->update_rc = true;
- }
- }
-}
-
-/* Process completed xmit descriptors from the specified queue */
-
-static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
-{
- struct ath_hal *ah = sc->sc_ah;
- struct ath_buf *bf, *lastbf, *bf_held = NULL;
- struct list_head bf_head;
- struct ath_desc *ds;
- int txok, nbad = 0;
- int status;
-
- DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
- txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
- txq->axq_link);
-
- for (;;) {
- spin_lock_bh(&txq->axq_lock);
- if (list_empty(&txq->axq_q)) {
- txq->axq_link = NULL;
- txq->axq_linkbuf = NULL;
- spin_unlock_bh(&txq->axq_lock);
- break;
- }
- bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
-
- /*
- * There is a race condition that a BH gets scheduled
- * after sw writes TxE and before hw re-load the last
- * descriptor to get the newly chained one.
- * Software must keep the last DONE descriptor as a
- * holding descriptor - software does so by marking
- * it with the STALE flag.
- */
- bf_held = NULL;
- if (bf->bf_status & ATH_BUFSTATUS_STALE) {
- bf_held = bf;
- if (list_is_last(&bf_held->list, &txq->axq_q)) {
- /* FIXME:
- * The holding descriptor is the last
- * descriptor in queue. It's safe to remove
- * the last holding descriptor in BH context.
- */
- spin_unlock_bh(&txq->axq_lock);
- break;
- } else {
- /* Lets work with the next buffer now */
- bf = list_entry(bf_held->list.next,
- struct ath_buf, list);
- }
- }
-
- lastbf = bf->bf_lastbf;
- ds = lastbf->bf_desc; /* NB: last decriptor */
-
- status = ath9k_hw_txprocdesc(ah, ds);
- if (status == -EINPROGRESS) {
- spin_unlock_bh(&txq->axq_lock);
- break;
- }
- if (bf->bf_desc == txq->axq_lastdsWithCTS)
- txq->axq_lastdsWithCTS = NULL;
- if (ds == txq->axq_gatingds)
- txq->axq_gatingds = NULL;
-
- /*
- * Remove ath_buf's of the same transmit unit from txq,
- * however leave the last descriptor back as the holding
- * descriptor for hw.
- */
- lastbf->bf_status |= ATH_BUFSTATUS_STALE;
- INIT_LIST_HEAD(&bf_head);
-
- if (!list_is_singular(&lastbf->list))
- list_cut_position(&bf_head,
- &txq->axq_q, lastbf->list.prev);
-
- txq->axq_depth--;
-
- if (bf_isaggr(bf))
- txq->axq_aggr_depth--;
-
- txok = (ds->ds_txstat.ts_status == 0);
-
- spin_unlock_bh(&txq->axq_lock);
-
- if (bf_held) {
- list_del(&bf_held->list);
- spin_lock_bh(&sc->tx.txbuflock);
- list_add_tail(&bf_held->list, &sc->tx.txbuf);
- spin_unlock_bh(&sc->tx.txbuflock);
- }
-
- if (!bf_isampdu(bf)) {
- /*
- * This frame is sent out as a single frame.
- * Use hardware retry status for this frame.
- */
- bf->bf_retries = ds->ds_txstat.ts_longretry;
- if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
- bf->bf_state.bf_type |= BUF_XRETRY;
- nbad = 0;
- } else {
- nbad = ath_tx_num_badfrms(sc, bf, txok);
- }
-
- ath_tx_rc_status(bf, ds, nbad);
-
- /*
- * Complete this transmit unit
- */
- if (bf_isampdu(bf))
- ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, txok);
- else
- ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
-
- /* Wake up mac80211 queue */
-
- spin_lock_bh(&txq->axq_lock);
- if (txq->stopped && ath_txq_depth(sc, txq->axq_qnum) <=
- (ATH_TXBUF - 20)) {
- int qnum;
- qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
- if (qnum != -1) {
- ieee80211_wake_queue(sc->hw, qnum);
- txq->stopped = 0;
- }
-
- }
-
- /*
- * schedule any pending packets if aggregation is enabled
- */
- if (sc->sc_flags & SC_OP_TXAGGR)
- ath_txq_schedule(sc, txq);
- spin_unlock_bh(&txq->axq_lock);
- }
-}
-
-static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq)
-{
- struct ath_hal *ah = sc->sc_ah;
-
- (void) ath9k_hw_stoptxdma(ah, txq->axq_qnum);
- DPRINTF(sc, ATH_DBG_XMIT, "tx queue [%u] %x, link %p\n",
- txq->axq_qnum, ath9k_hw_gettxbuf(ah, txq->axq_qnum),
- txq->axq_link);
-}
-
-/* Drain only the data queues */
-
-static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
-{
- struct ath_hal *ah = sc->sc_ah;
- int i, status, npend = 0;
-
- if (!(sc->sc_flags & SC_OP_INVALID)) {
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
- if (ATH_TXQ_SETUP(sc, i)) {
- ath_tx_stopdma(sc, &sc->tx.txq[i]);
- /* The TxDMA may not really be stopped.
- * Double check the hal tx pending count */
- npend += ath9k_hw_numtxpending(ah,
- sc->tx.txq[i].axq_qnum);
- }
- }
- }
-
- if (npend) {
- /* TxDMA not stopped, reset the hal */
- DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
-
- spin_lock_bh(&sc->sc_resetlock);
- if (!ath9k_hw_reset(ah,
- sc->sc_ah->ah_curchan,
- sc->tx_chan_width,
- sc->sc_tx_chainmask, sc->sc_rx_chainmask,
- sc->sc_ht_extprotspacing, true, &status)) {
-
- DPRINTF(sc, ATH_DBG_FATAL,
- "Unable to reset hardware; hal status %u\n",
- status);
- }
- spin_unlock_bh(&sc->sc_resetlock);
- }
-
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
- if (ATH_TXQ_SETUP(sc, i))
- ath_tx_draintxq(sc, &sc->tx.txq[i], retry_tx);
- }
}
-/* Add a sub-frame to block ack window */
-
-static void ath_tx_addto_baw(struct ath_softc *sc,
- struct ath_atx_tid *tid,
- struct ath_buf *bf)
-{
- int index, cindex;
-
- if (bf_isretried(bf))
- return;
-
- index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
- cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
-
- ASSERT(tid->tx_buf[cindex] == NULL);
- tid->tx_buf[cindex] = bf;
-
- if (index >= ((tid->baw_tail - tid->baw_head) &
- (ATH_TID_MAX_BUFS - 1))) {
- tid->baw_tail = cindex;
- INCR(tid->baw_tail, ATH_TID_MAX_BUFS);
- }
-}
-
-/*
- * Function to send an A-MPDU
- * NB: must be called with txq lock held
- */
-static int ath_tx_send_ampdu(struct ath_softc *sc,
- struct ath_atx_tid *tid,
- struct list_head *bf_head,
- struct ath_tx_control *txctl)
-{
- struct ath_buf *bf;
-
- BUG_ON(list_empty(bf_head));
-
- bf = list_first_entry(bf_head, struct ath_buf, list);
- bf->bf_state.bf_type |= BUF_AMPDU;
-
- /*
- * Do not queue to h/w when any of the following conditions is true:
- * - there are pending frames in software queue
- * - the TID is currently paused for ADDBA/BAR request
- * - seqno is not within block-ack window
- * - h/w queue depth exceeds low water mark
- */
- if (!list_empty(&tid->buf_q) || tid->paused ||
- !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
- txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
- /*
- * Add this frame to software queue for scheduling later
- * for aggregation.
- */
- list_splice_tail_init(bf_head, &tid->buf_q);
- ath_tx_queue_tid(txctl->txq, tid);
- return 0;
- }
-
- /* Add sub-frame to BAW */
- ath_tx_addto_baw(sc, tid, bf);
-
- /* Queue to h/w without aggregation */
- bf->bf_nframes = 1;
- bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */
- ath_buf_set_rate(sc, bf);
- ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
-
- return 0;
-}
-
-/*
- * looks up the rate
- * returns aggr limit based on lowest of the rates
- */
-static u32 ath_lookup_rate(struct ath_softc *sc,
- struct ath_buf *bf,
+static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
struct ath_atx_tid *tid)
{
struct ath_rate_table *rate_table = sc->cur_rate_table;
@@ -1255,15 +440,14 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
struct ieee80211_tx_info *tx_info;
struct ieee80211_tx_rate *rates;
struct ath_tx_info_priv *tx_info_priv;
- u32 max_4ms_framelen, frame_length;
+ u32 max_4ms_framelen, frmlen;
u16 aggr_limit, legacy = 0, maxampdu;
int i;
skb = (struct sk_buff *)bf->bf_mpdu;
tx_info = IEEE80211_SKB_CB(skb);
rates = tx_info->control.rates;
- tx_info_priv =
- (struct ath_tx_info_priv *)tx_info->rate_driver_data[0];
+ tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0];
/*
* Find the lowest frame length among the rate series that will have a
@@ -1279,9 +463,8 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
break;
}
- frame_length =
- rate_table->info[rates[i].idx].max_4ms_framelen;
- max_4ms_framelen = min(max_4ms_framelen, frame_length);
+ frmlen = rate_table->info[rates[i].idx].max_4ms_framelen;
+ max_4ms_framelen = min(max_4ms_framelen, frmlen);
}
}
@@ -1293,8 +476,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
return 0;
- aggr_limit = min(max_4ms_framelen,
- (u32)ATH_AMPDU_LIMIT_DEFAULT);
+ aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_DEFAULT);
/*
* h/w can accept aggregates upto 16 bit lengths (65535).
@@ -1309,14 +491,12 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
}
/*
- * returns the number of delimiters to be added to
+ * Returns the number of delimiters to be added to
* meet the minimum required mpdudensity.
- * caller should make sure that the rate is HT rate .
+ * caller should make sure that the rate is HT rate .
*/
-static int ath_compute_num_delims(struct ath_softc *sc,
- struct ath_atx_tid *tid,
- struct ath_buf *bf,
- u16 frmlen)
+static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
+ struct ath_buf *bf, u16 frmlen)
{
struct ath_rate_table *rt = sc->cur_rate_table;
struct sk_buff *skb = bf->bf_mpdu;
@@ -1370,9 +550,7 @@ static int ath_compute_num_delims(struct ath_softc *sc,
nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
- /* Is frame shorter than required minimum length? */
if (frmlen < minlen) {
- /* Get the minimum number of delimiters required. */
mindelim = (minlen - frmlen) / ATH_AGGR_DELIM_SZ;
ndelim = max(mindelim, ndelim);
}
@@ -1380,37 +558,23 @@ static int ath_compute_num_delims(struct ath_softc *sc,
return ndelim;
}
-/*
- * For aggregation from software buffer queue.
- * NB: must be called with txq lock held
- */
static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
- struct ath_atx_tid *tid,
- struct list_head *bf_q,
- struct ath_buf **bf_last,
- struct aggr_rifs_param *param,
- int *prev_frames)
+ struct ath_atx_tid *tid,
+ struct list_head *bf_q)
{
#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
- struct ath_buf *bf, *tbf, *bf_first, *bf_prev = NULL;
- struct list_head bf_head;
- int rl = 0, nframes = 0, ndelim;
+ struct ath_buf *bf, *bf_first, *bf_prev = NULL;
+ int rl = 0, nframes = 0, ndelim, prev_al = 0;
u16 aggr_limit = 0, al = 0, bpad = 0,
al_delta, h_baw = tid->baw_size / 2;
enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
- int prev_al = 0;
- INIT_LIST_HEAD(&bf_head);
-
- BUG_ON(list_empty(&tid->buf_q));
bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
do {
bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
- /*
- * do not step over block-ack window
- */
+ /* do not step over block-ack window */
if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) {
status = ATH_AGGR_BAW_CLOSED;
break;
@@ -1421,29 +585,23 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
rl = 1;
}
- /*
- * do not exceed aggregation limit
- */
+ /* do not exceed aggregation limit */
al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen;
- if (nframes && (aggr_limit <
- (al + bpad + al_delta + prev_al))) {
+ if (nframes &&
+ (aggr_limit < (al + bpad + al_delta + prev_al))) {
status = ATH_AGGR_LIMITED;
break;
}
- /*
- * do not exceed subframe limit
- */
- if ((nframes + *prev_frames) >=
- min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) {
+ /* do not exceed subframe limit */
+ if (nframes >= min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) {
status = ATH_AGGR_LIMITED;
break;
}
+ nframes++;
- /*
- * add padding for previous frame to aggregation length
- */
+ /* add padding for previous frame to aggregation length */
al += bpad + al_delta;
/*
@@ -1451,69 +609,35 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
* density for this node.
*/
ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen);
-
bpad = PADBYTES(al_delta) + (ndelim << 2);
bf->bf_next = NULL;
- bf->bf_lastfrm->bf_desc->ds_link = 0;
+ bf->bf_desc->ds_link = 0;
- /*
- * this packet is part of an aggregate
- * - remove all descriptors belonging to this frame from
- * software queue
- * - add it to block ack window
- * - set up descriptors for aggregation
- */
- list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
+ /* link buffers of this frame to the aggregate */
ath_tx_addto_baw(sc, tid, bf);
-
- list_for_each_entry(tbf, &bf_head, list) {
- ath9k_hw_set11n_aggr_middle(sc->sc_ah,
- tbf->bf_desc, ndelim);
- }
-
- /*
- * link buffers of this frame to the aggregate
- */
- list_splice_tail_init(&bf_head, bf_q);
- nframes++;
-
+ ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
+ list_move_tail(&bf->list, bf_q);
if (bf_prev) {
bf_prev->bf_next = bf;
- bf_prev->bf_lastfrm->bf_desc->ds_link = bf->bf_daddr;
+ bf_prev->bf_desc->ds_link = bf->bf_daddr;
}
bf_prev = bf;
-
-#ifdef AGGR_NOSHORT
- /*
- * terminate aggregation on a small packet boundary
- */
- if (bf->bf_frmlen < ATH_AGGR_MINPLEN) {
- status = ATH_AGGR_SHORTPKT;
- break;
- }
-#endif
} while (!list_empty(&tid->buf_q));
bf_first->bf_al = al;
bf_first->bf_nframes = nframes;
- *bf_last = bf_prev;
+
return status;
#undef PADBYTES
}
-/*
- * process pending frames possibly doing a-mpdu aggregation
- * NB: must be called with txq lock held
- */
-static void ath_tx_sched_aggr(struct ath_softc *sc,
- struct ath_txq *txq, struct ath_atx_tid *tid)
+static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid)
{
- struct ath_buf *bf, *tbf, *bf_last, *bf_lastaggr = NULL;
+ struct ath_buf *bf;
enum ATH_AGGR_STATUS status;
struct list_head bf_q;
- struct aggr_rifs_param param = {0, 0, 0, 0, NULL};
- int prev_frames = 0;
do {
if (list_empty(&tid->buf_q))
@@ -1521,382 +645,169 @@ static void ath_tx_sched_aggr(struct ath_softc *sc,
INIT_LIST_HEAD(&bf_q);
- status = ath_tx_form_aggr(sc, tid, &bf_q, &bf_lastaggr, &param,
- &prev_frames);
+ status = ath_tx_form_aggr(sc, tid, &bf_q);
/*
- * no frames picked up to be aggregated; block-ack
- * window is not open
+ * no frames picked up to be aggregated;
+ * block-ack window is not open.
*/
if (list_empty(&bf_q))
break;
bf = list_first_entry(&bf_q, struct ath_buf, list);
- bf_last = list_entry(bf_q.prev, struct ath_buf, list);
- bf->bf_lastbf = bf_last;
+ bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
- /*
- * if only one frame, send as non-aggregate
- */
+ /* if only one frame, send as non-aggregate */
if (bf->bf_nframes == 1) {
- ASSERT(bf->bf_lastfrm == bf_last);
-
bf->bf_state.bf_type &= ~BUF_AGGR;
- /*
- * clear aggr bits for every descriptor
- * XXX TODO: is there a way to optimize it?
- */
- list_for_each_entry(tbf, &bf_q, list) {
- ath9k_hw_clr11n_aggr(sc->sc_ah, tbf->bf_desc);
- }
-
+ ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
ath_buf_set_rate(sc, bf);
ath_tx_txqaddbuf(sc, txq, &bf_q);
continue;
}
- /*
- * setup first desc with rate and aggr info
- */
+ /* setup first desc of aggregate */
bf->bf_state.bf_type |= BUF_AGGR;
ath_buf_set_rate(sc, bf);
ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al);
- /*
- * anchor last frame of aggregate correctly
- */
- ASSERT(bf_lastaggr);
- ASSERT(bf_lastaggr->bf_lastfrm == bf_last);
- tbf = bf_lastaggr;
- ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc);
-
- /* XXX: We don't enter into this loop, consider removing this */
- while (!list_empty(&bf_q) && !list_is_last(&tbf->list, &bf_q)) {
- tbf = list_entry(tbf->list.next, struct ath_buf, list);
- ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc);
- }
+ /* anchor last desc of aggregate */
+ ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
txq->axq_aggr_depth++;
-
- /*
- * Normal aggregate, queue to hardware
- */
ath_tx_txqaddbuf(sc, txq, &bf_q);
} while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
status != ATH_AGGR_BAW_CLOSED);
}
-/* Called with txq lock held */
-
-static void ath_tid_drain(struct ath_softc *sc,
- struct ath_txq *txq,
- struct ath_atx_tid *tid)
-
-{
- struct ath_buf *bf;
- struct list_head bf_head;
- INIT_LIST_HEAD(&bf_head);
-
- for (;;) {
- if (list_empty(&tid->buf_q))
- break;
- bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
-
- list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
-
- /* update baw for software retried frame */
- if (bf_isretried(bf))
- ath_tx_update_baw(sc, tid, bf->bf_seqno);
-
- /*
- * do not indicate packets while holding txq spinlock.
- * unlock is intentional here
- */
- spin_unlock(&txq->axq_lock);
-
- /* complete this sub-frame */
- ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
-
- spin_lock(&txq->axq_lock);
- }
-
- /*
- * TODO: For frame(s) that are in the retry state, we will reuse the
- * sequence number(s) without setting the retry bit. The
- * alternative is to give up on these and BAR the receiver's window
- * forward.
- */
- tid->seq_next = tid->seq_start;
- tid->baw_tail = tid->baw_head;
-}
-
-/*
- * Drain all pending buffers
- * NB: must be called with txq lock held
- */
-static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
- struct ath_txq *txq)
-{
- struct ath_atx_ac *ac, *ac_tmp;
- struct ath_atx_tid *tid, *tid_tmp;
-
- list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
- list_del(&ac->list);
- ac->sched = false;
- list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
- list_del(&tid->list);
- tid->sched = false;
- ath_tid_drain(sc, txq, tid);
- }
- }
-}
-
-static int ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf,
- struct sk_buff *skb,
- struct ath_tx_control *txctl)
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+ u16 tid, u16 *ssn)
{
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct ath_tx_info_priv *tx_info_priv;
- int hdrlen;
- __le16 fc;
-
- tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
- if (unlikely(!tx_info_priv))
- return -ENOMEM;
- tx_info->rate_driver_data[0] = tx_info_priv;
- hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- fc = hdr->frame_control;
-
- ATH_TXBUF_RESET(bf);
-
- /* Frame type */
-
- bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
-
- ieee80211_is_data(fc) ?
- (bf->bf_state.bf_type |= BUF_DATA) :
- (bf->bf_state.bf_type &= ~BUF_DATA);
- ieee80211_is_back_req(fc) ?
- (bf->bf_state.bf_type |= BUF_BAR) :
- (bf->bf_state.bf_type &= ~BUF_BAR);
- ieee80211_is_pspoll(fc) ?
- (bf->bf_state.bf_type |= BUF_PSPOLL) :
- (bf->bf_state.bf_type &= ~BUF_PSPOLL);
- (sc->sc_flags & SC_OP_PREAMBLE_SHORT) ?
- (bf->bf_state.bf_type |= BUF_SHORT_PREAMBLE) :
- (bf->bf_state.bf_type &= ~BUF_SHORT_PREAMBLE);
- (sc->hw->conf.ht.enabled && !is_pae(skb) &&
- (tx_info->flags & IEEE80211_TX_CTL_AMPDU)) ?
- (bf->bf_state.bf_type |= BUF_HT) :
- (bf->bf_state.bf_type &= ~BUF_HT);
-
- bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
-
- /* Crypto */
-
- bf->bf_keytype = get_hw_crypto_keytype(skb);
-
- if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
- bf->bf_frmlen += tx_info->control.hw_key->icv_len;
- bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
- } else {
- bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
- }
-
- /* Assign seqno, tidno */
-
- if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR))
- assign_aggr_tid_seqno(skb, bf);
+ struct ath_atx_tid *txtid;
+ struct ath_node *an;
- /* DMA setup */
- bf->bf_mpdu = skb;
+ an = (struct ath_node *)sta->drv_priv;
- bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data,
- skb->len, PCI_DMA_TODEVICE);
- if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_dmacontext))) {
- bf->bf_mpdu = NULL;
- DPRINTF(sc, ATH_DBG_CONFIG,
- "pci_dma_mapping_error() on TX\n");
- return -ENOMEM;
+ if (sc->sc_flags & SC_OP_TXAGGR) {
+ txtid = ATH_AN_2_TID(an, tid);
+ txtid->state |= AGGR_ADDBA_PROGRESS;
+ ath_tx_pause_tid(sc, txtid);
+ *ssn = txtid->seq_start;
}
- bf->bf_buf_addr = bf->bf_dmacontext;
return 0;
}
-/* FIXME: tx power */
-static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
- struct ath_tx_control *txctl)
+int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
{
- struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
- struct ath_node *an = NULL;
+ struct ath_node *an = (struct ath_node *)sta->drv_priv;
+ struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
+ struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
+ struct ath_buf *bf;
struct list_head bf_head;
- struct ath_desc *ds;
- struct ath_atx_tid *tid;
- struct ath_hal *ah = sc->sc_ah;
- int frm_type;
-
- frm_type = get_hw_packet_type(skb);
-
INIT_LIST_HEAD(&bf_head);
- list_add_tail(&bf->list, &bf_head);
-
- /* setup descriptor */
-
- ds = bf->bf_desc;
- ds->ds_link = 0;
- ds->ds_data = bf->bf_buf_addr;
- /* Formulate first tx descriptor with tx controls */
-
- ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
- bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
-
- ath9k_hw_filltxdesc(ah, ds,
- skb->len, /* segment length */
- true, /* first segment */
- true, /* last segment */
- ds); /* first descriptor */
-
- bf->bf_lastfrm = bf;
+ if (txtid->state & AGGR_CLEANUP)
+ return 0;
- spin_lock_bh(&txctl->txq->axq_lock);
+ if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
+ txtid->addba_exchangeattempts = 0;
+ return 0;
+ }
- if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
- tx_info->control.sta) {
- an = (struct ath_node *)tx_info->control.sta->drv_priv;
- tid = ATH_AN_2_TID(an, bf->bf_tidno);
+ ath_tx_pause_tid(sc, txtid);
- if (ath_aggr_query(sc, an, bf->bf_tidno)) {
- /*
- * Try aggregation if it's a unicast data frame
- * and the destination is HT capable.
- */
- ath_tx_send_ampdu(sc, tid, &bf_head, txctl);
- } else {
+ /* drop all software retried frames and mark this TID */
+ spin_lock_bh(&txq->axq_lock);
+ while (!list_empty(&txtid->buf_q)) {
+ bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
+ if (!bf_isretried(bf)) {
/*
- * Send this frame as regular when ADDBA
- * exchange is neither complete nor pending.
+ * NB: it's based on the assumption that
+ * software retried frame will always stay
+ * at the head of software queue.
*/
- ath_tx_send_normal(sc, txctl->txq,
- tid, &bf_head);
+ break;
}
- } else {
- bf->bf_lastbf = bf;
- bf->bf_nframes = 1;
+ list_move_tail(&bf->list, &bf_head);
+ ath_tx_update_baw(sc, txtid, bf->bf_seqno);
+ ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+ }
+ spin_unlock_bh(&txq->axq_lock);
- ath_buf_set_rate(sc, bf);
- ath_tx_txqaddbuf(sc, txctl->txq, &bf_head);
+ if (txtid->baw_head != txtid->baw_tail) {
+ txtid->state |= AGGR_CLEANUP;
+ } else {
+ txtid->state &= ~AGGR_ADDBA_COMPLETE;
+ txtid->addba_exchangeattempts = 0;
+ ath_tx_flush_tid(sc, txtid);
}
- spin_unlock_bh(&txctl->txq->axq_lock);
+ return 0;
}
-/* Upon failure caller should free skb */
-int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
- struct ath_tx_control *txctl)
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
{
- struct ath_buf *bf;
- int r;
-
- /* Check if a tx buffer is available */
-
- bf = ath_tx_get_buffer(sc);
- if (!bf) {
- DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n");
- return -1;
- }
-
- r = ath_tx_setup_buffer(sc, bf, skb, txctl);
- if (unlikely(r)) {
- struct ath_txq *txq = txctl->txq;
-
- DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n");
-
- /* upon ath_tx_processq() this TX queue will be resumed, we
- * guarantee this will happen by knowing beforehand that
- * we will at least have to run TX completionon one buffer
- * on the queue */
- spin_lock_bh(&txq->axq_lock);
- if (ath_txq_depth(sc, txq->axq_qnum) > 1) {
- ieee80211_stop_queue(sc->hw,
- skb_get_queue_mapping(skb));
- txq->stopped = 1;
- }
- spin_unlock_bh(&txq->axq_lock);
+ struct ath_atx_tid *txtid;
+ struct ath_node *an;
- spin_lock_bh(&sc->tx.txbuflock);
- list_add_tail(&bf->list, &sc->tx.txbuf);
- spin_unlock_bh(&sc->tx.txbuflock);
+ an = (struct ath_node *)sta->drv_priv;
- return r;
+ if (sc->sc_flags & SC_OP_TXAGGR) {
+ txtid = ATH_AN_2_TID(an, tid);
+ txtid->baw_size =
+ IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
+ txtid->state |= AGGR_ADDBA_COMPLETE;
+ txtid->state &= ~AGGR_ADDBA_PROGRESS;
+ ath_tx_resume_tid(sc, txtid);
}
-
- ath_tx_start_dma(sc, bf, txctl);
-
- return 0;
}
-/* Initialize TX queue and h/w */
-
-int ath_tx_init(struct ath_softc *sc, int nbufs)
+bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
{
- int error = 0;
+ struct ath_atx_tid *txtid;
- do {
- spin_lock_init(&sc->tx.txbuflock);
+ if (!(sc->sc_flags & SC_OP_TXAGGR))
+ return false;
- /* Setup tx descriptors */
- error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
- "tx", nbufs, 1);
- if (error != 0) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "Failed to allocate tx descriptors: %d\n",
- error);
- break;
- }
+ txtid = ATH_AN_2_TID(an, tidno);
- /* XXX allocate beacon state together with vap */
- error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
- "beacon", ATH_BCBUF, 1);
- if (error != 0) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "Failed to allocate beacon descriptors: %d\n",
- error);
- break;
+ if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
+ if (!(txtid->state & AGGR_ADDBA_PROGRESS) &&
+ (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
+ txtid->addba_exchangeattempts++;
+ return true;
}
+ }
- } while (0);
-
- if (error != 0)
- ath_tx_cleanup(sc);
-
- return error;
+ return false;
}
-/* Reclaim all tx queue resources */
+/********************/
+/* Queue Management */
+/********************/
-int ath_tx_cleanup(struct ath_softc *sc)
+static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
+ struct ath_txq *txq)
{
- /* cleanup beacon descriptors */
- if (sc->beacon.bdma.dd_desc_len != 0)
- ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
-
- /* cleanup tx descriptors */
- if (sc->tx.txdma.dd_desc_len != 0)
- ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
+ struct ath_atx_ac *ac, *ac_tmp;
+ struct ath_atx_tid *tid, *tid_tmp;
- return 0;
+ list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
+ list_del(&ac->list);
+ ac->sched = false;
+ list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
+ list_del(&tid->list);
+ tid->sched = false;
+ ath_tid_drain(sc, txq, tid);
+ }
+ }
}
-/* Setup a h/w transmit queue */
-
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
struct ath9k_tx_queue_info qi;
int qnum;
@@ -1959,43 +870,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
return &sc->tx.txq[qnum];
}
-/* Reclaim resources for a setup queue */
-
-void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
-{
- ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
- sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
-}
-
-/*
- * Setup a hardware data transmit queue for the specified
- * access control. The hal may not support all requested
- * queues in which case it will return a reference to a
- * previously setup queue. We record the mapping from ac's
- * to h/w queues for use by ath_tx_start and also track
- * the set of h/w queues being used to optimize work in the
- * transmit interrupt handler and related routines.
- */
-
-int ath_tx_setup(struct ath_softc *sc, int haltype)
-{
- struct ath_txq *txq;
-
- if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
- DPRINTF(sc, ATH_DBG_FATAL,
- "HAL AC %u out of range, max %zu!\n",
- haltype, ARRAY_SIZE(sc->tx.hwq_map));
- return 0;
- }
- txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
- if (txq != NULL) {
- sc->tx.hwq_map[haltype] = txq->axq_qnum;
- return 1;
- } else
- return 0;
-}
-
-int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
+static int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
{
int qnum;
@@ -2021,8 +896,6 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
return qnum;
}
-/* Get a transmit queue, if available */
-
struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
{
struct ath_txq *txq = NULL;
@@ -2033,9 +906,8 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
spin_lock_bh(&txq->axq_lock);
- /* Try to avoid running out of descriptors */
if (txq->axq_depth >= (ATH_TXBUF - 20)) {
- DPRINTF(sc, ATH_DBG_FATAL,
+ DPRINTF(sc, ATH_DBG_XMIT,
"TX queue: %d is full, depth: %d\n",
qnum, txq->axq_depth);
ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb));
@@ -2049,12 +921,10 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
return txq;
}
-/* Update parameters for a transmit queue */
-
int ath_txq_update(struct ath_softc *sc, int qnum,
struct ath9k_tx_queue_info *qinfo)
{
- struct ath_hal *ah = sc->sc_ah;
+ struct ath_hw *ah = sc->sc_ah;
int error = 0;
struct ath9k_tx_queue_info qi;
@@ -2082,7 +952,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
"Unable to update hardware queue %u!\n", qnum);
error = -EIO;
} else {
- ath9k_hw_resettxqueue(ah, qnum); /* push to h/w */
+ ath9k_hw_resettxqueue(ah, qnum);
}
return error;
@@ -2092,55 +962,36 @@ int ath_cabq_update(struct ath_softc *sc)
{
struct ath9k_tx_queue_info qi;
int qnum = sc->beacon.cabq->axq_qnum;
- struct ath_beacon_config conf;
ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
/*
* Ensure the readytime % is within the bounds.
*/
- if (sc->sc_config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
- sc->sc_config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
- else if (sc->sc_config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
- sc->sc_config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
-
- ath_get_beaconconfig(sc, ATH_IF_ID_ANY, &conf);
- qi.tqi_readyTime =
- (conf.beacon_interval * sc->sc_config.cabqReadytime) / 100;
+ if (sc->config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
+ sc->config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
+ else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
+ sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
+
+ qi.tqi_readyTime = (sc->hw->conf.beacon_int *
+ sc->config.cabqReadytime) / 100;
ath_txq_update(sc, qnum, &qi);
return 0;
}
-/* Deferred processing of transmit interrupt */
-
-void ath_tx_tasklet(struct ath_softc *sc)
-{
- int i;
- u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
-
- ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
-
- /*
- * Process each active queue.
- */
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
- if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
- ath_tx_processq(sc, &sc->tx.txq[i]);
- }
-}
-
-void ath_tx_draintxq(struct ath_softc *sc,
- struct ath_txq *txq, bool retry_tx)
+/*
+ * Drain a given TX queue (could be Beacon or Data)
+ *
+ * This assumes output has been stopped and
+ * we do not need to block ath_tx_tasklet.
+ */
+void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
{
struct ath_buf *bf, *lastbf;
struct list_head bf_head;
INIT_LIST_HEAD(&bf_head);
- /*
- * NB: this assumes output has been stopped and
- * we do not need to block ath_tx_tasklet
- */
for (;;) {
spin_lock_bh(&txq->axq_lock);
@@ -2175,7 +1026,7 @@ void ath_tx_draintxq(struct ath_softc *sc,
spin_unlock_bh(&txq->axq_lock);
if (bf_isampdu(bf))
- ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, 0);
+ ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0);
else
ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
}
@@ -2190,44 +1041,285 @@ void ath_tx_draintxq(struct ath_softc *sc,
}
}
-/* Drain the transmit queues and reclaim resources */
+void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_txq *txq;
+ int i, npend = 0;
+
+ if (sc->sc_flags & SC_OP_INVALID)
+ return;
+
+ /* Stop beacon queue */
+ ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-void ath_draintxq(struct ath_softc *sc, bool retry_tx)
+ /* Stop data queues */
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+ if (ATH_TXQ_SETUP(sc, i)) {
+ txq = &sc->tx.txq[i];
+ ath9k_hw_stoptxdma(ah, txq->axq_qnum);
+ npend += ath9k_hw_numtxpending(ah, txq->axq_qnum);
+ }
+ }
+
+ if (npend) {
+ int r;
+
+ DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
+
+ spin_lock_bh(&sc->sc_resetlock);
+ r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true);
+ if (r)
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Unable to reset hardware; reset status %u\n",
+ r);
+ spin_unlock_bh(&sc->sc_resetlock);
+ }
+
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+ if (ATH_TXQ_SETUP(sc, i))
+ ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
+ }
+}
+
+void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
+{
+ ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
+ sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
+}
+
+void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
{
- /* stop beacon queue. The beacon will be freed when
- * we go to INIT state */
- if (!(sc->sc_flags & SC_OP_INVALID)) {
- (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
- DPRINTF(sc, ATH_DBG_XMIT, "beacon queue %x\n",
- ath9k_hw_gettxbuf(sc->sc_ah, sc->beacon.beaconq));
+ struct ath_atx_ac *ac;
+ struct ath_atx_tid *tid;
+
+ if (list_empty(&txq->axq_acq))
+ return;
+
+ ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
+ list_del(&ac->list);
+ ac->sched = false;
+
+ do {
+ if (list_empty(&ac->tid_q))
+ return;
+
+ tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
+ list_del(&tid->list);
+ tid->sched = false;
+
+ if (tid->paused)
+ continue;
+
+ if ((txq->axq_depth % 2) == 0)
+ ath_tx_sched_aggr(sc, txq, tid);
+
+ /*
+ * add tid to round-robin queue if more frames
+ * are pending for the tid
+ */
+ if (!list_empty(&tid->buf_q))
+ ath_tx_queue_tid(txq, tid);
+
+ break;
+ } while (!list_empty(&ac->tid_q));
+
+ if (!list_empty(&ac->tid_q)) {
+ if (!ac->sched) {
+ ac->sched = true;
+ list_add_tail(&ac->list, &txq->axq_acq);
+ }
}
+}
+
+int ath_tx_setup(struct ath_softc *sc, int haltype)
+{
+ struct ath_txq *txq;
- ath_drain_txdataq(sc, retry_tx);
+ if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "HAL AC %u out of range, max %zu!\n",
+ haltype, ARRAY_SIZE(sc->tx.hwq_map));
+ return 0;
+ }
+ txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
+ if (txq != NULL) {
+ sc->tx.hwq_map[haltype] = txq->axq_qnum;
+ return 1;
+ } else
+ return 0;
}
-u32 ath_txq_depth(struct ath_softc *sc, int qnum)
+/***********/
+/* TX, DMA */
+/***********/
+
+/*
+ * Insert a chain of ath_buf (descriptors) on a txq and
+ * assume the descriptors are already chained together by caller.
+ */
+static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
+ struct list_head *head)
{
- return sc->tx.txq[qnum].axq_depth;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_buf *bf;
+
+ /*
+ * Insert the frame on the outbound list and
+ * pass it on to the hardware.
+ */
+
+ if (list_empty(head))
+ return;
+
+ bf = list_first_entry(head, struct ath_buf, list);
+
+ list_splice_tail_init(head, &txq->axq_q);
+ txq->axq_depth++;
+ txq->axq_totalqueued++;
+ txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
+
+ DPRINTF(sc, ATH_DBG_QUEUE,
+ "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
+
+ if (txq->axq_link == NULL) {
+ ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
+ DPRINTF(sc, ATH_DBG_XMIT,
+ "TXDP[%u] = %llx (%p)\n",
+ txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
+ } else {
+ *txq->axq_link = bf->bf_daddr;
+ DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
+ txq->axq_qnum, txq->axq_link,
+ ito64(bf->bf_daddr), bf->bf_desc);
+ }
+ txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
+ ath9k_hw_txstart(ah, txq->axq_qnum);
}
-u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum)
+static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
{
- return sc->tx.txq[qnum].axq_aggr_depth;
+ struct ath_buf *bf = NULL;
+
+ spin_lock_bh(&sc->tx.txbuflock);
+
+ if (unlikely(list_empty(&sc->tx.txbuf))) {
+ spin_unlock_bh(&sc->tx.txbuflock);
+ return NULL;
+ }
+
+ bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+ list_del(&bf->list);
+
+ spin_unlock_bh(&sc->tx.txbuflock);
+
+ return bf;
}
-bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
+static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
+ struct list_head *bf_head,
+ struct ath_tx_control *txctl)
{
- struct ath_atx_tid *txtid;
+ struct ath_buf *bf;
- if (!(sc->sc_flags & SC_OP_TXAGGR))
- return false;
+ bf = list_first_entry(bf_head, struct ath_buf, list);
+ bf->bf_state.bf_type |= BUF_AMPDU;
- txtid = ATH_AN_2_TID(an, tidno);
+ /*
+ * Do not queue to h/w when any of the following conditions is true:
+ * - there are pending frames in software queue
+ * - the TID is currently paused for ADDBA/BAR request
+ * - seqno is not within block-ack window
+ * - h/w queue depth exceeds low water mark
+ */
+ if (!list_empty(&tid->buf_q) || tid->paused ||
+ !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
+ txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
+ /*
+ * Add this frame to software queue for scheduling later
+ * for aggregation.
+ */
+ list_move_tail(&bf->list, &tid->buf_q);
+ ath_tx_queue_tid(txctl->txq, tid);
+ return;
+ }
- if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
- if (!(txtid->state & AGGR_ADDBA_PROGRESS) &&
- (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
- txtid->addba_exchangeattempts++;
+ /* Add sub-frame to BAW */
+ ath_tx_addto_baw(sc, tid, bf);
+
+ /* Queue to h/w without aggregation */
+ bf->bf_nframes = 1;
+ bf->bf_lastbf = bf;
+ ath_buf_set_rate(sc, bf);
+ ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
+}
+
+static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_atx_tid *tid,
+ struct list_head *bf_head)
+{
+ struct ath_buf *bf;
+
+ bf = list_first_entry(bf_head, struct ath_buf, list);
+ bf->bf_state.bf_type &= ~BUF_AMPDU;
+
+ /* update starting sequence number for subsequent ADDBA request */
+ INCR(tid->seq_start, IEEE80211_SEQ_MAX);
+
+ bf->bf_nframes = 1;
+ bf->bf_lastbf = bf;
+ ath_buf_set_rate(sc, bf);
+ ath_tx_txqaddbuf(sc, txq, bf_head);
+}
+
+static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+ struct list_head *bf_head)
+{
+ struct ath_buf *bf;
+
+ bf = list_first_entry(bf_head, struct ath_buf, list);
+
+ bf->bf_lastbf = bf;
+ bf->bf_nframes = 1;
+ ath_buf_set_rate(sc, bf);
+ ath_tx_txqaddbuf(sc, txq, bf_head);
+}
+
+static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr;
+ enum ath9k_pkt_type htype;
+ __le16 fc;
+
+ hdr = (struct ieee80211_hdr *)skb->data;
+ fc = hdr->frame_control;
+
+ if (ieee80211_is_beacon(fc))
+ htype = ATH9K_PKT_TYPE_BEACON;
+ else if (ieee80211_is_probe_resp(fc))
+ htype = ATH9K_PKT_TYPE_PROBE_RESP;
+ else if (ieee80211_is_atim(fc))
+ htype = ATH9K_PKT_TYPE_ATIM;
+ else if (ieee80211_is_pspoll(fc))
+ htype = ATH9K_PKT_TYPE_PSPOLL;
+ else
+ htype = ATH9K_PKT_TYPE_NORMAL;
+
+ return htype;
+}
+
+static bool is_pae(struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr;
+ __le16 fc;
+
+ hdr = (struct ieee80211_hdr *)skb->data;
+ fc = hdr->frame_control;
+
+ if (ieee80211_is_data(fc)) {
+ if (ieee80211_is_nullfunc(fc) ||
+ /* Port Access Entity (IEEE 802.1X) */
+ (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
return true;
}
}
@@ -2235,175 +1327,766 @@ bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
return false;
}
-/* Start TX aggregation */
+static int get_hw_crypto_keytype(struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
- u16 tid, u16 *ssn)
+ if (tx_info->control.hw_key) {
+ if (tx_info->control.hw_key->alg == ALG_WEP)
+ return ATH9K_KEY_TYPE_WEP;
+ else if (tx_info->control.hw_key->alg == ALG_TKIP)
+ return ATH9K_KEY_TYPE_TKIP;
+ else if (tx_info->control.hw_key->alg == ALG_CCMP)
+ return ATH9K_KEY_TYPE_AES;
+ }
+
+ return ATH9K_KEY_TYPE_CLEAR;
+}
+
+static void assign_aggr_tid_seqno(struct sk_buff *skb,
+ struct ath_buf *bf)
{
- struct ath_atx_tid *txtid;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr;
struct ath_node *an;
+ struct ath_atx_tid *tid;
+ __le16 fc;
+ u8 *qc;
- an = (struct ath_node *)sta->drv_priv;
+ if (!tx_info->control.sta)
+ return;
- if (sc->sc_flags & SC_OP_TXAGGR) {
- txtid = ATH_AN_2_TID(an, tid);
- txtid->state |= AGGR_ADDBA_PROGRESS;
- ath_tx_pause_tid(sc, txtid);
+ an = (struct ath_node *)tx_info->control.sta->drv_priv;
+ hdr = (struct ieee80211_hdr *)skb->data;
+ fc = hdr->frame_control;
+
+ if (ieee80211_is_data_qos(fc)) {
+ qc = ieee80211_get_qos_ctl(hdr);
+ bf->bf_tidno = qc[0] & 0xf;
}
- return 0;
+ /*
+ * For HT capable stations, we save tidno for later use.
+ * We also override seqno set by upper layer with the one
+ * in tx aggregation state.
+ *
+ * If fragmentation is on, the sequence number is
+ * not overridden, since it has been
+ * incremented by the fragmentation routine.
+ *
+ * FIXME: check if the fragmentation threshold exceeds
+ * IEEE80211 max.
+ */
+ tid = ATH_AN_2_TID(an, bf->bf_tidno);
+ hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
+ IEEE80211_SEQ_SEQ_SHIFT);
+ bf->bf_seqno = tid->seq_next;
+ INCR(tid->seq_next, IEEE80211_SEQ_MAX);
}
-/* Stop tx aggregation */
-
-int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
+ struct ath_txq *txq)
{
- struct ath_node *an = (struct ath_node *)sta->drv_priv;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ int flags = 0;
- ath_tx_aggr_teardown(sc, an, tid);
- return 0;
+ flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
+ flags |= ATH9K_TXDESC_INTREQ;
+
+ if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
+ flags |= ATH9K_TXDESC_NOACK;
+
+ return flags;
}
-/* Resume tx aggregation */
+/*
+ * rix - rate index
+ * pktlen - total bytes (delims + data + fcs + pads + pad delims)
+ * width - 0 for 20 MHz, 1 for 40 MHz
+ * half_gi - to use 4us v/s 3.6 us for symbol time
+ */
+static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
+ int width, int half_gi, bool shortPreamble)
+{
+ struct ath_rate_table *rate_table = sc->cur_rate_table;
+ u32 nbits, nsymbits, duration, nsymbols;
+ u8 rc;
+ int streams, pktlen;
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+ pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
+ rc = rate_table->info[rix].ratecode;
+
+ /* for legacy rates, use old function to compute packet duration */
+ if (!IS_HT_RATE(rc))
+ return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen,
+ rix, shortPreamble);
+
+ /* find number of symbols: PLCP + data */
+ nbits = (pktlen << 3) + OFDM_PLCP_BITS;
+ nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
+ nsymbols = (nbits + nsymbits - 1) / nsymbits;
+
+ if (!half_gi)
+ duration = SYMBOL_TIME(nsymbols);
+ else
+ duration = SYMBOL_TIME_HALFGI(nsymbols);
+
+ /* addup duration for legacy/ht training and signal fields */
+ streams = HT_RC_2_STREAMS(rc);
+ duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
+
+ return duration;
+}
+
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
{
- struct ath_atx_tid *txtid;
- struct ath_node *an;
+ struct ath_rate_table *rt = sc->cur_rate_table;
+ struct ath9k_11n_rate_series series[4];
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *tx_info;
+ struct ieee80211_tx_rate *rates;
+ struct ieee80211_hdr *hdr;
+ int i, flags = 0;
+ u8 rix = 0, ctsrate = 0;
+ bool is_pspoll;
- an = (struct ath_node *)sta->drv_priv;
+ memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
- if (sc->sc_flags & SC_OP_TXAGGR) {
- txtid = ATH_AN_2_TID(an, tid);
- txtid->baw_size =
- IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
- txtid->state |= AGGR_ADDBA_COMPLETE;
- txtid->state &= ~AGGR_ADDBA_PROGRESS;
- ath_tx_resume_tid(sc, txtid);
+ skb = (struct sk_buff *)bf->bf_mpdu;
+ tx_info = IEEE80211_SKB_CB(skb);
+ rates = tx_info->control.rates;
+ hdr = (struct ieee80211_hdr *)skb->data;
+ is_pspoll = ieee80211_is_pspoll(hdr->frame_control);
+
+ /*
+ * We check if Short Preamble is needed for the CTS rate by
+ * checking the BSS's global flag.
+ * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
+ */
+ if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
+ ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode |
+ rt->info[tx_info->control.rts_cts_rate_idx].short_preamble;
+ else
+ ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode;
+
+ /*
+ * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
+ * Check the first rate in the series to decide whether RTS/CTS
+ * or CTS-to-self has to be used.
+ */
+ if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
+ flags = ATH9K_TXDESC_CTSENA;
+ else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
+ flags = ATH9K_TXDESC_RTSENA;
+
+ /* FIXME: Handle aggregation protection */
+ if (sc->config.ath_aggr_prot &&
+ (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
+ flags = ATH9K_TXDESC_RTSENA;
+ }
+
+ /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
+ if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
+ flags &= ~(ATH9K_TXDESC_RTSENA);
+
+ for (i = 0; i < 4; i++) {
+ if (!rates[i].count || (rates[i].idx < 0))
+ continue;
+
+ rix = rates[i].idx;
+ series[i].Tries = rates[i].count;
+ series[i].ChSel = sc->tx_chainmask;
+
+ if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ series[i].Rate = rt->info[rix].ratecode |
+ rt->info[rix].short_preamble;
+ else
+ series[i].Rate = rt->info[rix].ratecode;
+
+ if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)
+ series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
+ if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ series[i].RateFlags |= ATH9K_RATESERIES_2040;
+ if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
+ series[i].RateFlags |= ATH9K_RATESERIES_HALFGI;
+
+ series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
+ (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0,
+ (rates[i].flags & IEEE80211_TX_RC_SHORT_GI),
+ (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE));
}
+
+ /* set dur_update_en for l-sig computation except for PS-Poll frames */
+ ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
+ bf->bf_lastbf->bf_desc,
+ !is_pspoll, ctsrate,
+ 0, series, 4, flags);
+
+ if (sc->config.ath_aggr_prot && flags)
+ ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
}
-/*
- * Performs transmit side cleanup when TID changes from aggregated to
- * unaggregated.
- * - Pause the TID and mark cleanup in progress
- * - Discard all retry frames from the s/w queue.
- */
+static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
+ struct sk_buff *skb,
+ struct ath_tx_control *txctl)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ath_tx_info_priv *tx_info_priv;
+ int hdrlen;
+ __le16 fc;
+
+ tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
+ if (unlikely(!tx_info_priv))
+ return -ENOMEM;
+ tx_info->rate_driver_data[0] = tx_info_priv;
+ tx_info_priv->aphy = aphy;
+ tx_info_priv->frame_type = txctl->frame_type;
+ hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+ fc = hdr->frame_control;
+
+ ATH_TXBUF_RESET(bf);
+
+ bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
+
+ if (conf_is_ht(&sc->hw->conf) && !is_pae(skb))
+ bf->bf_state.bf_type |= BUF_HT;
+
+ bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
+
+ bf->bf_keytype = get_hw_crypto_keytype(skb);
+ if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
+ bf->bf_frmlen += tx_info->control.hw_key->icv_len;
+ bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
+ } else {
+ bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
+ }
+
+ if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR))
+ assign_aggr_tid_seqno(skb, bf);
+
+ bf->bf_mpdu = skb;
+
+ bf->bf_dmacontext = dma_map_single(sc->dev, skb->data,
+ skb->len, DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
+ bf->bf_mpdu = NULL;
+ DPRINTF(sc, ATH_DBG_CONFIG,
+ "dma_mapping_error() on TX\n");
+ return -ENOMEM;
+ }
+
+ bf->bf_buf_addr = bf->bf_dmacontext;
+ return 0;
+}
-void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid)
+/* FIXME: tx power */
+static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
+ struct ath_tx_control *txctl)
{
- struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
- struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
- struct ath_buf *bf;
+ struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ath_node *an = NULL;
struct list_head bf_head;
+ struct ath_desc *ds;
+ struct ath_atx_tid *tid;
+ struct ath_hw *ah = sc->sc_ah;
+ int frm_type;
+ __le16 fc;
+
+ frm_type = get_hw_packet_type(skb);
+ fc = hdr->frame_control;
+
INIT_LIST_HEAD(&bf_head);
+ list_add_tail(&bf->list, &bf_head);
- if (txtid->state & AGGR_CLEANUP) /* cleanup is in progress */
- return;
+ ds = bf->bf_desc;
+ ds->ds_link = 0;
+ ds->ds_data = bf->bf_buf_addr;
- if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
- txtid->addba_exchangeattempts = 0;
- return;
- }
+ ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
+ bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
- /* TID must be paused first */
- ath_tx_pause_tid(sc, txtid);
+ ath9k_hw_filltxdesc(ah, ds,
+ skb->len, /* segment length */
+ true, /* first segment */
+ true, /* last segment */
+ ds); /* first descriptor */
- /* drop all software retried frames and mark this TID */
- spin_lock_bh(&txq->axq_lock);
- while (!list_empty(&txtid->buf_q)) {
- bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
- if (!bf_isretried(bf)) {
+ spin_lock_bh(&txctl->txq->axq_lock);
+
+ if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
+ tx_info->control.sta) {
+ an = (struct ath_node *)tx_info->control.sta->drv_priv;
+ tid = ATH_AN_2_TID(an, bf->bf_tidno);
+
+ if (!ieee80211_is_data_qos(fc)) {
+ ath_tx_send_normal(sc, txctl->txq, &bf_head);
+ goto tx_done;
+ }
+
+ if (ath_aggr_query(sc, an, bf->bf_tidno)) {
/*
- * NB: it's based on the assumption that
- * software retried frame will always stay
- * at the head of software queue.
+ * Try aggregation if it's a unicast data frame
+ * and the destination is HT capable.
*/
- break;
+ ath_tx_send_ampdu(sc, tid, &bf_head, txctl);
+ } else {
+ /*
+ * Send this frame as regular when ADDBA
+ * exchange is neither complete nor pending.
+ */
+ ath_tx_send_ht_normal(sc, txctl->txq,
+ tid, &bf_head);
}
- list_cut_position(&bf_head,
- &txtid->buf_q, &bf->bf_lastfrm->list);
- ath_tx_update_baw(sc, txtid, bf->bf_seqno);
+ } else {
+ ath_tx_send_normal(sc, txctl->txq, &bf_head);
+ }
- /* complete this sub-frame */
- ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+tx_done:
+ spin_unlock_bh(&txctl->txq->axq_lock);
+}
+
+/* Upon failure caller should free skb */
+int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
+ struct ath_tx_control *txctl)
+{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ struct ath_buf *bf;
+ int r;
+
+ bf = ath_tx_get_buffer(sc);
+ if (!bf) {
+ DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n");
+ return -1;
}
- if (txtid->baw_head != txtid->baw_tail) {
- spin_unlock_bh(&txq->axq_lock);
- txtid->state |= AGGR_CLEANUP;
- } else {
- txtid->state &= ~AGGR_ADDBA_COMPLETE;
- txtid->addba_exchangeattempts = 0;
+ r = ath_tx_setup_buffer(hw, bf, skb, txctl);
+ if (unlikely(r)) {
+ struct ath_txq *txq = txctl->txq;
+
+ DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n");
+
+ /* upon ath_tx_processq() this TX queue will be resumed, we
+ * guarantee this will happen by knowing beforehand that
+ * we will at least have to run TX completionon one buffer
+ * on the queue */
+ spin_lock_bh(&txq->axq_lock);
+ if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) {
+ ieee80211_stop_queue(sc->hw,
+ skb_get_queue_mapping(skb));
+ txq->stopped = 1;
+ }
spin_unlock_bh(&txq->axq_lock);
- ath_tx_flush_tid(sc, txtid);
+
+ spin_lock_bh(&sc->tx.txbuflock);
+ list_add_tail(&bf->list, &sc->tx.txbuf);
+ spin_unlock_bh(&sc->tx.txbuflock);
+
+ return r;
}
-}
-/*
- * Tx scheduling logic
- * NB: must be called with txq lock held
- */
+ ath_tx_start_dma(sc, bf, txctl);
-void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
+ return 0;
+}
+
+void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
{
- struct ath_atx_ac *ac;
- struct ath_atx_tid *tid;
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
+ int hdrlen, padsize;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ath_tx_control txctl;
- /* nothing to schedule */
- if (list_empty(&txq->axq_acq))
- return;
- /*
- * get the first node/ac pair on the queue
- */
- ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
- list_del(&ac->list);
- ac->sched = false;
+ memset(&txctl, 0, sizeof(struct ath_tx_control));
/*
- * process a single tid per destination
+ * As a temporary workaround, assign seq# here; this will likely need
+ * to be cleaned up to work better with Beacon transmission and virtual
+ * BSSes.
*/
- do {
- /* nothing to schedule */
- if (list_empty(&ac->tid_q))
+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+ sc->tx.seq_no += 0x10;
+ hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+ hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
+ }
+
+ /* Add the padding after the header if this is not already done */
+ hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+ if (hdrlen & 3) {
+ padsize = hdrlen % 4;
+ if (skb_headroom(skb) < padsize) {
+ DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n");
+ dev_kfree_skb_any(skb);
return;
+ }
+ skb_push(skb, padsize);
+ memmove(skb->data, skb->data + padsize, hdrlen);
+ }
- tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
- list_del(&tid->list);
- tid->sched = false;
+ txctl.txq = sc->beacon.cabq;
- if (tid->paused) /* check next tid to keep h/w busy */
- continue;
+ DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
- if ((txq->axq_depth % 2) == 0)
- ath_tx_sched_aggr(sc, txq, tid);
+ if (ath_tx_start(hw, skb, &txctl) != 0) {
+ DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n");
+ goto exit;
+ }
+ return;
+exit:
+ dev_kfree_skb_any(skb);
+}
+
+/*****************/
+/* TX Completion */
+/*****************/
+
+static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
+ int tx_flags)
+{
+ struct ieee80211_hw *hw = sc->hw;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+ int hdrlen, padsize;
+ int frame_type = ATH9K_NOT_INTERNAL;
+
+ DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
+
+ if (tx_info_priv) {
+ hw = tx_info_priv->aphy->hw;
+ frame_type = tx_info_priv->frame_type;
+ }
+
+ if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
+ tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
+ kfree(tx_info_priv);
+ tx_info->rate_driver_data[0] = NULL;
+ }
+
+ if (tx_flags & ATH_TX_BAR)
+ tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
+
+ if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
+ /* Frame was ACKed */
+ tx_info->flags |= IEEE80211_TX_STAT_ACK;
+ }
+
+ hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+ padsize = hdrlen & 3;
+ if (padsize && hdrlen >= 24) {
/*
- * add tid to round-robin queue if more frames
- * are pending for the tid
+ * Remove MAC header padding before giving the frame back to
+ * mac80211.
*/
- if (!list_empty(&tid->buf_q))
- ath_tx_queue_tid(txq, tid);
+ memmove(skb->data + padsize, skb->data, hdrlen);
+ skb_pull(skb, padsize);
+ }
- /* only schedule one TID at a time */
- break;
- } while (!list_empty(&ac->tid_q));
+ if (frame_type == ATH9K_NOT_INTERNAL)
+ ieee80211_tx_status(hw, skb);
+ else
+ ath9k_tx_status(hw, skb);
+}
+
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+ struct list_head *bf_q,
+ int txok, int sendbar)
+{
+ struct sk_buff *skb = bf->bf_mpdu;
+ unsigned long flags;
+ int tx_flags = 0;
+
+
+ if (sendbar)
+ tx_flags = ATH_TX_BAR;
+
+ if (!txok) {
+ tx_flags |= ATH_TX_ERROR;
+
+ if (bf_isxretried(bf))
+ tx_flags |= ATH_TX_XRETRY;
+ }
+
+ dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
+ ath_tx_complete(sc, skb, tx_flags);
/*
- * schedule AC if more TIDs need processing
+ * Return the list of ath_buf of this mpdu to free queue
*/
- if (!list_empty(&ac->tid_q)) {
+ spin_lock_irqsave(&sc->tx.txbuflock, flags);
+ list_splice_tail_init(bf_q, &sc->tx.txbuf);
+ spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
+}
+
+static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
+ int txok)
+{
+ struct ath_buf *bf_last = bf->bf_lastbf;
+ struct ath_desc *ds = bf_last->bf_desc;
+ u16 seq_st = 0;
+ u32 ba[WME_BA_BMP_SIZE >> 5];
+ int ba_index;
+ int nbad = 0;
+ int isaggr = 0;
+
+ if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
+ return 0;
+
+ isaggr = bf_isaggr(bf);
+ if (isaggr) {
+ seq_st = ATH_DS_BA_SEQ(ds);
+ memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
+ }
+
+ while (bf) {
+ ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
+ if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
+ nbad++;
+
+ bf = bf->bf_next;
+ }
+
+ return nbad;
+}
+
+static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
+ int nbad, int txok, bool update_rc)
+{
+ struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+ struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+ struct ieee80211_hw *hw = tx_info_priv->aphy->hw;
+ u8 i, tx_rateindex;
+
+ if (txok)
+ tx_info->status.ack_signal = ds->ds_txstat.ts_rssi;
+
+ tx_rateindex = ds->ds_txstat.ts_rateindex;
+ WARN_ON(tx_rateindex >= hw->max_rates);
+
+ tx_info_priv->update_rc = update_rc;
+ if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
+ tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+
+ if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
+ (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
+ if (ieee80211_is_data(hdr->frame_control)) {
+ memcpy(&tx_info_priv->tx, &ds->ds_txstat,
+ sizeof(tx_info_priv->tx));
+ tx_info_priv->n_frames = bf->bf_nframes;
+ tx_info_priv->n_bad_frames = nbad;
+ }
+ }
+
+ for (i = tx_rateindex + 1; i < hw->max_rates; i++)
+ tx_info->status.rates[i].count = 0;
+
+ tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1;
+}
+
+static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
+{
+ int qnum;
+
+ spin_lock_bh(&txq->axq_lock);
+ if (txq->stopped &&
+ sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) {
+ qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
+ if (qnum != -1) {
+ ieee80211_wake_queue(sc->hw, qnum);
+ txq->stopped = 0;
+ }
+ }
+ spin_unlock_bh(&txq->axq_lock);
+}
+
+static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_buf *bf, *lastbf, *bf_held = NULL;
+ struct list_head bf_head;
+ struct ath_desc *ds;
+ int txok;
+ int status;
+
+ DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
+ txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
+ txq->axq_link);
+
+ for (;;) {
+ spin_lock_bh(&txq->axq_lock);
+ if (list_empty(&txq->axq_q)) {
+ txq->axq_link = NULL;
+ txq->axq_linkbuf = NULL;
+ spin_unlock_bh(&txq->axq_lock);
+ break;
+ }
+ bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
+
/*
- * add dest ac to txq if not already added
+ * There is a race condition that a BH gets scheduled
+ * after sw writes TxE and before hw re-load the last
+ * descriptor to get the newly chained one.
+ * Software must keep the last DONE descriptor as a
+ * holding descriptor - software does so by marking
+ * it with the STALE flag.
*/
- if (!ac->sched) {
- ac->sched = true;
- list_add_tail(&ac->list, &txq->axq_acq);
+ bf_held = NULL;
+ if (bf->bf_status & ATH_BUFSTATUS_STALE) {
+ bf_held = bf;
+ if (list_is_last(&bf_held->list, &txq->axq_q)) {
+ txq->axq_link = NULL;
+ txq->axq_linkbuf = NULL;
+ spin_unlock_bh(&txq->axq_lock);
+
+ /*
+ * The holding descriptor is the last
+ * descriptor in queue. It's safe to remove
+ * the last holding descriptor in BH context.
+ */
+ spin_lock_bh(&sc->tx.txbuflock);
+ list_move_tail(&bf_held->list, &sc->tx.txbuf);
+ spin_unlock_bh(&sc->tx.txbuflock);
+
+ break;
+ } else {
+ bf = list_entry(bf_held->list.next,
+ struct ath_buf, list);
+ }
+ }
+
+ lastbf = bf->bf_lastbf;
+ ds = lastbf->bf_desc;
+
+ status = ath9k_hw_txprocdesc(ah, ds);
+ if (status == -EINPROGRESS) {
+ spin_unlock_bh(&txq->axq_lock);
+ break;
+ }
+ if (bf->bf_desc == txq->axq_lastdsWithCTS)
+ txq->axq_lastdsWithCTS = NULL;
+ if (ds == txq->axq_gatingds)
+ txq->axq_gatingds = NULL;
+
+ /*
+ * Remove ath_buf's of the same transmit unit from txq,
+ * however leave the last descriptor back as the holding
+ * descriptor for hw.
+ */
+ lastbf->bf_status |= ATH_BUFSTATUS_STALE;
+ INIT_LIST_HEAD(&bf_head);
+ if (!list_is_singular(&lastbf->list))
+ list_cut_position(&bf_head,
+ &txq->axq_q, lastbf->list.prev);
+
+ txq->axq_depth--;
+ if (bf_isaggr(bf))
+ txq->axq_aggr_depth--;
+
+ txok = (ds->ds_txstat.ts_status == 0);
+ spin_unlock_bh(&txq->axq_lock);
+
+ if (bf_held) {
+ spin_lock_bh(&sc->tx.txbuflock);
+ list_move_tail(&bf_held->list, &sc->tx.txbuf);
+ spin_unlock_bh(&sc->tx.txbuflock);
+ }
+
+ if (!bf_isampdu(bf)) {
+ /*
+ * This frame is sent out as a single frame.
+ * Use hardware retry status for this frame.
+ */
+ bf->bf_retries = ds->ds_txstat.ts_longretry;
+ if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
+ bf->bf_state.bf_type |= BUF_XRETRY;
+ ath_tx_rc_status(bf, ds, 0, txok, true);
}
+
+ if (bf_isampdu(bf))
+ ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok);
+ else
+ ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
+
+ ath_wake_mac80211_queue(sc, txq);
+
+ spin_lock_bh(&txq->axq_lock);
+ if (sc->sc_flags & SC_OP_TXAGGR)
+ ath_txq_schedule(sc, txq);
+ spin_unlock_bh(&txq->axq_lock);
+ }
+}
+
+
+void ath_tx_tasklet(struct ath_softc *sc)
+{
+ int i;
+ u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
+
+ ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
+
+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+ if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
+ ath_tx_processq(sc, &sc->tx.txq[i]);
}
}
-/* Initialize per-node transmit state */
+/*****************/
+/* Init, Cleanup */
+/*****************/
+
+int ath_tx_init(struct ath_softc *sc, int nbufs)
+{
+ int error = 0;
+
+ do {
+ spin_lock_init(&sc->tx.txbuflock);
+
+ error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
+ "tx", nbufs, 1);
+ if (error != 0) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Failed to allocate tx descriptors: %d\n",
+ error);
+ break;
+ }
+
+ error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
+ "beacon", ATH_BCBUF, 1);
+ if (error != 0) {
+ DPRINTF(sc, ATH_DBG_FATAL,
+ "Failed to allocate beacon descriptors: %d\n",
+ error);
+ break;
+ }
+
+ } while (0);
+
+ if (error != 0)
+ ath_tx_cleanup(sc);
+
+ return error;
+}
+
+int ath_tx_cleanup(struct ath_softc *sc)
+{
+ if (sc->beacon.bdma.dd_desc_len != 0)
+ ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
+
+ if (sc->tx.txdma.dd_desc_len != 0)
+ ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
+
+ return 0;
+}
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
{
@@ -2411,9 +2094,6 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
struct ath_atx_ac *ac;
int tidno, acno;
- /*
- * Init per tid tx state
- */
for (tidno = 0, tid = &an->tid[tidno];
tidno < WME_NUM_TID;
tidno++, tid++) {
@@ -2423,22 +2103,16 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
tid->baw_size = WME_MAX_BA;
tid->baw_head = tid->baw_tail = 0;
tid->sched = false;
- tid->paused = false;
+ tid->paused = false;
tid->state &= ~AGGR_CLEANUP;
INIT_LIST_HEAD(&tid->buf_q);
-
acno = TID_TO_WME_AC(tidno);
tid->ac = &an->ac[acno];
-
- /* ADDBA state */
tid->state &= ~AGGR_ADDBA_COMPLETE;
tid->state &= ~AGGR_ADDBA_PROGRESS;
tid->addba_exchangeattempts = 0;
}
- /*
- * Init per ac tx state
- */
for (acno = 0, ac = &an->ac[acno];
acno < WME_NUM_AC; acno++, ac++) {
ac->sched = false;
@@ -2465,14 +2139,13 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
}
}
-/* Cleanupthe pending buffers for the node. */
-
void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
{
int i;
struct ath_atx_ac *ac, *ac_tmp;
struct ath_atx_tid *tid, *tid_tmp;
struct ath_txq *txq;
+
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
if (ATH_TXQ_SETUP(sc, i)) {
txq = &sc->tx.txq[i];
@@ -2503,51 +2176,3 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
}
}
}
-
-void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
-{
- int hdrlen, padsize;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ath_tx_control txctl;
-
- memset(&txctl, 0, sizeof(struct ath_tx_control));
-
- /*
- * As a temporary workaround, assign seq# here; this will likely need
- * to be cleaned up to work better with Beacon transmission and virtual
- * BSSes.
- */
- if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
- sc->tx.seq_no += 0x10;
- hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
- hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
- }
-
- /* Add the padding after the header if this is not already done */
- hdrlen = ieee80211_get_hdrlen_from_skb(skb);
- if (hdrlen & 3) {
- padsize = hdrlen % 4;
- if (skb_headroom(skb) < padsize) {
- DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n");
- dev_kfree_skb_any(skb);
- return;
- }
- skb_push(skb, padsize);
- memmove(skb->data, skb->data + padsize, hdrlen);
- }
-
- txctl.txq = sc->beacon.cabq;
-
- DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
-
- if (ath_tx_start(sc, skb, &txctl) != 0) {
- DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n");
- goto exit;
- }
-
- return;
-exit:
- dev_kfree_skb_any(skb);
-}
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 4223672c4432..857d84148b1d 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -2,8 +2,8 @@
Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
- Copyright 2000-2001 ATMEL Corporation.
- Copyright 2003-2004 Simon Kelley.
+ Copyright 2000-2001 ATMEL Corporation.
+ Copyright 2003-2004 Simon Kelley.
This code was developed from version 2.1.1 of the Atmel drivers,
released by Atmel corp. under the GPL in December 2002. It also
@@ -89,15 +89,15 @@ static struct {
const char *fw_file;
const char *fw_file_ext;
} fw_table[] = {
- { ATMEL_FW_TYPE_502, "atmel_at76c502", "bin" },
- { ATMEL_FW_TYPE_502D, "atmel_at76c502d", "bin" },
- { ATMEL_FW_TYPE_502E, "atmel_at76c502e", "bin" },
- { ATMEL_FW_TYPE_502_3COM, "atmel_at76c502_3com", "bin" },
- { ATMEL_FW_TYPE_504, "atmel_at76c504", "bin" },
- { ATMEL_FW_TYPE_504_2958, "atmel_at76c504_2958", "bin" },
- { ATMEL_FW_TYPE_504A_2958,"atmel_at76c504a_2958","bin" },
- { ATMEL_FW_TYPE_506, "atmel_at76c506", "bin" },
- { ATMEL_FW_TYPE_NONE, NULL, NULL }
+ { ATMEL_FW_TYPE_502, "atmel_at76c502", "bin" },
+ { ATMEL_FW_TYPE_502D, "atmel_at76c502d", "bin" },
+ { ATMEL_FW_TYPE_502E, "atmel_at76c502e", "bin" },
+ { ATMEL_FW_TYPE_502_3COM, "atmel_at76c502_3com", "bin" },
+ { ATMEL_FW_TYPE_504, "atmel_at76c504", "bin" },
+ { ATMEL_FW_TYPE_504_2958, "atmel_at76c504_2958", "bin" },
+ { ATMEL_FW_TYPE_504A_2958, "atmel_at76c504a_2958", "bin" },
+ { ATMEL_FW_TYPE_506, "atmel_at76c506", "bin" },
+ { ATMEL_FW_TYPE_NONE, NULL, NULL }
};
#define MAX_SSID_LENGTH 32
@@ -106,60 +106,60 @@ static struct {
#define MAX_BSS_ENTRIES 64
/* registers */
-#define GCR 0x00 // (SIR0) General Configuration Register
-#define BSR 0x02 // (SIR1) Bank Switching Select Register
+#define GCR 0x00 /* (SIR0) General Configuration Register */
+#define BSR 0x02 /* (SIR1) Bank Switching Select Register */
#define AR 0x04
#define DR 0x08
-#define MR1 0x12 // Mirror Register 1
-#define MR2 0x14 // Mirror Register 2
-#define MR3 0x16 // Mirror Register 3
-#define MR4 0x18 // Mirror Register 4
+#define MR1 0x12 /* Mirror Register 1 */
+#define MR2 0x14 /* Mirror Register 2 */
+#define MR3 0x16 /* Mirror Register 3 */
+#define MR4 0x18 /* Mirror Register 4 */
#define GPR1 0x0c
#define GPR2 0x0e
#define GPR3 0x10
-//
-// Constants for the GCR register.
-//
-#define GCR_REMAP 0x0400 // Remap internal SRAM to 0
-#define GCR_SWRES 0x0080 // BIU reset (ARM and PAI are NOT reset)
-#define GCR_CORES 0x0060 // Core Reset (ARM and PAI are reset)
-#define GCR_ENINT 0x0002 // Enable Interrupts
-#define GCR_ACKINT 0x0008 // Acknowledge Interrupts
-
-#define BSS_SRAM 0x0200 // AMBA module selection --> SRAM
-#define BSS_IRAM 0x0100 // AMBA module selection --> IRAM
-//
-// Constants for the MR registers.
-//
-#define MAC_INIT_COMPLETE 0x0001 // MAC init has been completed
-#define MAC_BOOT_COMPLETE 0x0010 // MAC boot has been completed
-#define MAC_INIT_OK 0x0002 // MAC boot has been completed
+/*
+ * Constants for the GCR register.
+ */
+#define GCR_REMAP 0x0400 /* Remap internal SRAM to 0 */
+#define GCR_SWRES 0x0080 /* BIU reset (ARM and PAI are NOT reset) */
+#define GCR_CORES 0x0060 /* Core Reset (ARM and PAI are reset) */
+#define GCR_ENINT 0x0002 /* Enable Interrupts */
+#define GCR_ACKINT 0x0008 /* Acknowledge Interrupts */
+
+#define BSS_SRAM 0x0200 /* AMBA module selection --> SRAM */
+#define BSS_IRAM 0x0100 /* AMBA module selection --> IRAM */
+/*
+ *Constants for the MR registers.
+ */
+#define MAC_INIT_COMPLETE 0x0001 /* MAC init has been completed */
+#define MAC_BOOT_COMPLETE 0x0010 /* MAC boot has been completed */
+#define MAC_INIT_OK 0x0002 /* MAC boot has been completed */
#define MIB_MAX_DATA_BYTES 212
#define MIB_HEADER_SIZE 4 /* first four fields */
struct get_set_mib {
- u8 type;
- u8 size;
- u8 index;
- u8 reserved;
- u8 data[MIB_MAX_DATA_BYTES];
+ u8 type;
+ u8 size;
+ u8 index;
+ u8 reserved;
+ u8 data[MIB_MAX_DATA_BYTES];
};
struct rx_desc {
- u32 Next;
- u16 MsduPos;
- u16 MsduSize;
-
- u8 State;
- u8 Status;
- u8 Rate;
- u8 Rssi;
- u8 LinkQuality;
- u8 PreambleType;
- u16 Duration;
- u32 RxTime;
+ u32 Next;
+ u16 MsduPos;
+ u16 MsduSize;
+
+ u8 State;
+ u8 Status;
+ u8 Rate;
+ u8 Rssi;
+ u8 LinkQuality;
+ u8 PreambleType;
+ u16 Duration;
+ u32 RxTime;
};
#define RX_DESC_FLAG_VALID 0x80
@@ -192,7 +192,7 @@ struct tx_desc {
u8 KeyIndex;
u8 ChiperType;
u8 ChipreLength;
- u8 Reserved1;
+ u8 Reserved1;
u8 Reserved;
u8 PacketType;
@@ -212,9 +212,9 @@ struct tx_desc {
#define TX_DESC_PACKET_TYPE_OFFSET 17
#define TX_DESC_HOST_LENGTH_OFFSET 18
-///////////////////////////////////////////////////////
-// Host-MAC interface
-///////////////////////////////////////////////////////
+/*
+ * Host-MAC interface
+ */
#define TX_STATUS_SUCCESS 0x00
@@ -226,14 +226,14 @@ struct tx_desc {
#define TX_PACKET_TYPE_DATA 0x01
#define TX_PACKET_TYPE_MGMT 0x02
-#define ISR_EMPTY 0x00 // no bits set in ISR
-#define ISR_TxCOMPLETE 0x01 // packet transmitted
-#define ISR_RxCOMPLETE 0x02 // packet received
-#define ISR_RxFRAMELOST 0x04 // Rx Frame lost
-#define ISR_FATAL_ERROR 0x08 // Fatal error
-#define ISR_COMMAND_COMPLETE 0x10 // command completed
-#define ISR_OUT_OF_RANGE 0x20 // command completed
-#define ISR_IBSS_MERGE 0x40 // (4.1.2.30): IBSS merge
+#define ISR_EMPTY 0x00 /* no bits set in ISR */
+#define ISR_TxCOMPLETE 0x01 /* packet transmitted */
+#define ISR_RxCOMPLETE 0x02 /* packet received */
+#define ISR_RxFRAMELOST 0x04 /* Rx Frame lost */
+#define ISR_FATAL_ERROR 0x08 /* Fatal error */
+#define ISR_COMMAND_COMPLETE 0x10 /* command completed */
+#define ISR_OUT_OF_RANGE 0x20 /* command completed */
+#define ISR_IBSS_MERGE 0x40 /* (4.1.2.30): IBSS merge */
#define ISR_GENERIC_IRQ 0x80
#define Local_Mib_Type 0x01
@@ -311,22 +311,22 @@ struct tx_desc {
#define MAX_ENCRYPTION_KEYS 4
#define MAX_ENCRYPTION_KEY_SIZE 40
-///////////////////////////////////////////////////////////////////////////
-// 802.11 related definitions
-///////////////////////////////////////////////////////////////////////////
+/*
+ * 802.11 related definitions
+ */
-//
-// Regulatory Domains
-//
+/*
+ * Regulatory Domains
+ */
-#define REG_DOMAIN_FCC 0x10 //Channels 1-11 USA
-#define REG_DOMAIN_DOC 0x20 //Channel 1-11 Canada
-#define REG_DOMAIN_ETSI 0x30 //Channel 1-13 Europe (ex Spain/France)
-#define REG_DOMAIN_SPAIN 0x31 //Channel 10-11 Spain
-#define REG_DOMAIN_FRANCE 0x32 //Channel 10-13 France
-#define REG_DOMAIN_MKK 0x40 //Channel 14 Japan
-#define REG_DOMAIN_MKK1 0x41 //Channel 1-14 Japan(MKK1)
-#define REG_DOMAIN_ISRAEL 0x50 //Channel 3-9 ISRAEL
+#define REG_DOMAIN_FCC 0x10 /* Channels 1-11 USA */
+#define REG_DOMAIN_DOC 0x20 /* Channel 1-11 Canada */
+#define REG_DOMAIN_ETSI 0x30 /* Channel 1-13 Europe (ex Spain/France) */
+#define REG_DOMAIN_SPAIN 0x31 /* Channel 10-11 Spain */
+#define REG_DOMAIN_FRANCE 0x32 /* Channel 10-13 France */
+#define REG_DOMAIN_MKK 0x40 /* Channel 14 Japan */
+#define REG_DOMAIN_MKK1 0x41 /* Channel 1-14 Japan(MKK1) */
+#define REG_DOMAIN_ISRAEL 0x50 /* Channel 3-9 ISRAEL */
#define BSS_TYPE_AD_HOC 1
#define BSS_TYPE_INFRASTRUCTURE 2
@@ -364,13 +364,13 @@ struct tx_desc {
#define CIPHER_SUITE_CCX 4
#define CIPHER_SUITE_WEP_128 5
-//
-// IFACE MACROS & definitions
-//
-//
+/*
+ * IFACE MACROS & definitions
+ */
-// FuncCtrl field:
-//
+/*
+ * FuncCtrl field:
+ */
#define FUNC_CTRL_TxENABLE 0x10
#define FUNC_CTRL_RxENABLE 0x20
#define FUNC_CTRL_INIT_COMPLETE 0x01
@@ -378,48 +378,48 @@ struct tx_desc {
/* A stub firmware image which reads the MAC address from NVRAM on the card.
For copyright information and source see the end of this file. */
static u8 mac_reader[] = {
- 0x06,0x00,0x00,0xea,0x04,0x00,0x00,0xea,0x03,0x00,0x00,0xea,0x02,0x00,0x00,0xea,
- 0x01,0x00,0x00,0xea,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xea,0xfe,0xff,0xff,0xea,
- 0xd3,0x00,0xa0,0xe3,0x00,0xf0,0x21,0xe1,0x0e,0x04,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
- 0x81,0x11,0xa0,0xe1,0x00,0x10,0x81,0xe3,0x00,0x10,0x80,0xe5,0x1c,0x10,0x90,0xe5,
- 0x10,0x10,0xc1,0xe3,0x1c,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,0x08,0x10,0x80,0xe5,
- 0x02,0x03,0xa0,0xe3,0x00,0x10,0xa0,0xe3,0xb0,0x10,0xc0,0xe1,0xb4,0x10,0xc0,0xe1,
- 0xb8,0x10,0xc0,0xe1,0xbc,0x10,0xc0,0xe1,0x56,0xdc,0xa0,0xe3,0x21,0x00,0x00,0xeb,
- 0x0a,0x00,0xa0,0xe3,0x1a,0x00,0x00,0xeb,0x10,0x00,0x00,0xeb,0x07,0x00,0x00,0xeb,
- 0x02,0x03,0xa0,0xe3,0x02,0x14,0xa0,0xe3,0xb4,0x10,0xc0,0xe1,0x4c,0x10,0x9f,0xe5,
- 0xbc,0x10,0xc0,0xe1,0x10,0x10,0xa0,0xe3,0xb8,0x10,0xc0,0xe1,0xfe,0xff,0xff,0xea,
- 0x00,0x40,0x2d,0xe9,0x00,0x20,0xa0,0xe3,0x02,0x3c,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
- 0x28,0x00,0x9f,0xe5,0x37,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
- 0x00,0x40,0x2d,0xe9,0x12,0x2e,0xa0,0xe3,0x06,0x30,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
- 0x02,0x04,0xa0,0xe3,0x2f,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
- 0x00,0x02,0x00,0x02,0x80,0x01,0x90,0xe0,0x01,0x00,0x00,0x0a,0x01,0x00,0x50,0xe2,
- 0xfc,0xff,0xff,0xea,0x1e,0xff,0x2f,0xe1,0x80,0x10,0xa0,0xe3,0xf3,0x06,0xa0,0xe3,
- 0x00,0x10,0x80,0xe5,0x00,0x10,0xa0,0xe3,0x00,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,
- 0x04,0x10,0x80,0xe5,0x00,0x10,0x80,0xe5,0x0e,0x34,0xa0,0xe3,0x1c,0x10,0x93,0xe5,
- 0x02,0x1a,0x81,0xe3,0x1c,0x10,0x83,0xe5,0x58,0x11,0x9f,0xe5,0x30,0x10,0x80,0xe5,
- 0x54,0x11,0x9f,0xe5,0x34,0x10,0x80,0xe5,0x38,0x10,0x80,0xe5,0x3c,0x10,0x80,0xe5,
- 0x10,0x10,0x90,0xe5,0x08,0x00,0x90,0xe5,0x1e,0xff,0x2f,0xe1,0xf3,0x16,0xa0,0xe3,
- 0x08,0x00,0x91,0xe5,0x05,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,0x10,0x00,0x91,0xe5,
- 0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0xff,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,
- 0x10,0x00,0x91,0xe5,0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
- 0x10,0x00,0x91,0xe5,0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
- 0xff,0x00,0x00,0xe2,0x1e,0xff,0x2f,0xe1,0x30,0x40,0x2d,0xe9,0x00,0x50,0xa0,0xe1,
- 0x03,0x40,0xa0,0xe1,0xa2,0x02,0xa0,0xe1,0x08,0x00,0x00,0xe2,0x03,0x00,0x80,0xe2,
- 0xd8,0x10,0x9f,0xe5,0x00,0x00,0xc1,0xe5,0x01,0x20,0xc1,0xe5,0xe2,0xff,0xff,0xeb,
- 0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x1a,0x14,0x00,0xa0,0xe3,0xc4,0xff,0xff,0xeb,
- 0x04,0x20,0xa0,0xe1,0x05,0x10,0xa0,0xe1,0x02,0x00,0xa0,0xe3,0x01,0x00,0x00,0xeb,
- 0x30,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x70,0x40,0x2d,0xe9,0xf3,0x46,0xa0,0xe3,
- 0x00,0x30,0xa0,0xe3,0x00,0x00,0x50,0xe3,0x08,0x00,0x00,0x9a,0x8c,0x50,0x9f,0xe5,
- 0x03,0x60,0xd5,0xe7,0x0c,0x60,0x84,0xe5,0x10,0x60,0x94,0xe5,0x02,0x00,0x16,0xe3,
- 0xfc,0xff,0xff,0x0a,0x01,0x30,0x83,0xe2,0x00,0x00,0x53,0xe1,0xf7,0xff,0xff,0x3a,
- 0xff,0x30,0xa0,0xe3,0x0c,0x30,0x84,0xe5,0x08,0x00,0x94,0xe5,0x10,0x00,0x94,0xe5,
- 0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x94,0xe5,0x00,0x00,0xa0,0xe3,
- 0x00,0x00,0x52,0xe3,0x0b,0x00,0x00,0x9a,0x10,0x50,0x94,0xe5,0x02,0x00,0x15,0xe3,
- 0xfc,0xff,0xff,0x0a,0x0c,0x30,0x84,0xe5,0x10,0x50,0x94,0xe5,0x01,0x00,0x15,0xe3,
- 0xfc,0xff,0xff,0x0a,0x08,0x50,0x94,0xe5,0x01,0x50,0xc1,0xe4,0x01,0x00,0x80,0xe2,
- 0x02,0x00,0x50,0xe1,0xf3,0xff,0xff,0x3a,0xc8,0x00,0xa0,0xe3,0x98,0xff,0xff,0xeb,
- 0x70,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x01,0x0c,0x00,0x02,0x01,0x02,0x00,0x02,
- 0x00,0x01,0x00,0x02
+ 0x06, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea,
+ 0x01, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea,
+ 0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x0e, 0x04, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
+ 0x81, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x81, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x90, 0xe5,
+ 0x10, 0x10, 0xc1, 0xe3, 0x1c, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x08, 0x10, 0x80, 0xe5,
+ 0x02, 0x03, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0x10, 0xc0, 0xe1, 0xb4, 0x10, 0xc0, 0xe1,
+ 0xb8, 0x10, 0xc0, 0xe1, 0xbc, 0x10, 0xc0, 0xe1, 0x56, 0xdc, 0xa0, 0xe3, 0x21, 0x00, 0x00, 0xeb,
+ 0x0a, 0x00, 0xa0, 0xe3, 0x1a, 0x00, 0x00, 0xeb, 0x10, 0x00, 0x00, 0xeb, 0x07, 0x00, 0x00, 0xeb,
+ 0x02, 0x03, 0xa0, 0xe3, 0x02, 0x14, 0xa0, 0xe3, 0xb4, 0x10, 0xc0, 0xe1, 0x4c, 0x10, 0x9f, 0xe5,
+ 0xbc, 0x10, 0xc0, 0xe1, 0x10, 0x10, 0xa0, 0xe3, 0xb8, 0x10, 0xc0, 0xe1, 0xfe, 0xff, 0xff, 0xea,
+ 0x00, 0x40, 0x2d, 0xe9, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x3c, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
+ 0x28, 0x00, 0x9f, 0xe5, 0x37, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
+ 0x00, 0x40, 0x2d, 0xe9, 0x12, 0x2e, 0xa0, 0xe3, 0x06, 0x30, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
+ 0x02, 0x04, 0xa0, 0xe3, 0x2f, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
+ 0x00, 0x02, 0x00, 0x02, 0x80, 0x01, 0x90, 0xe0, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe2,
+ 0xfc, 0xff, 0xff, 0xea, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x10, 0xa0, 0xe3, 0xf3, 0x06, 0xa0, 0xe3,
+ 0x00, 0x10, 0x80, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
+ 0x04, 0x10, 0x80, 0xe5, 0x00, 0x10, 0x80, 0xe5, 0x0e, 0x34, 0xa0, 0xe3, 0x1c, 0x10, 0x93, 0xe5,
+ 0x02, 0x1a, 0x81, 0xe3, 0x1c, 0x10, 0x83, 0xe5, 0x58, 0x11, 0x9f, 0xe5, 0x30, 0x10, 0x80, 0xe5,
+ 0x54, 0x11, 0x9f, 0xe5, 0x34, 0x10, 0x80, 0xe5, 0x38, 0x10, 0x80, 0xe5, 0x3c, 0x10, 0x80, 0xe5,
+ 0x10, 0x10, 0x90, 0xe5, 0x08, 0x00, 0x90, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf3, 0x16, 0xa0, 0xe3,
+ 0x08, 0x00, 0x91, 0xe5, 0x05, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5, 0x10, 0x00, 0x91, 0xe5,
+ 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0xff, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5,
+ 0x10, 0x00, 0x91, 0xe5, 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
+ 0x10, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
+ 0xff, 0x00, 0x00, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1,
+ 0x03, 0x40, 0xa0, 0xe1, 0xa2, 0x02, 0xa0, 0xe1, 0x08, 0x00, 0x00, 0xe2, 0x03, 0x00, 0x80, 0xe2,
+ 0xd8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0xc1, 0xe5, 0x01, 0x20, 0xc1, 0xe5, 0xe2, 0xff, 0xff, 0xeb,
+ 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x14, 0x00, 0xa0, 0xe3, 0xc4, 0xff, 0xff, 0xeb,
+ 0x04, 0x20, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x01, 0x00, 0x00, 0xeb,
+ 0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9, 0xf3, 0x46, 0xa0, 0xe3,
+ 0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x00, 0x00, 0x9a, 0x8c, 0x50, 0x9f, 0xe5,
+ 0x03, 0x60, 0xd5, 0xe7, 0x0c, 0x60, 0x84, 0xe5, 0x10, 0x60, 0x94, 0xe5, 0x02, 0x00, 0x16, 0xe3,
+ 0xfc, 0xff, 0xff, 0x0a, 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x53, 0xe1, 0xf7, 0xff, 0xff, 0x3a,
+ 0xff, 0x30, 0xa0, 0xe3, 0x0c, 0x30, 0x84, 0xe5, 0x08, 0x00, 0x94, 0xe5, 0x10, 0x00, 0x94, 0xe5,
+ 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x94, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
+ 0x00, 0x00, 0x52, 0xe3, 0x0b, 0x00, 0x00, 0x9a, 0x10, 0x50, 0x94, 0xe5, 0x02, 0x00, 0x15, 0xe3,
+ 0xfc, 0xff, 0xff, 0x0a, 0x0c, 0x30, 0x84, 0xe5, 0x10, 0x50, 0x94, 0xe5, 0x01, 0x00, 0x15, 0xe3,
+ 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x50, 0x94, 0xe5, 0x01, 0x50, 0xc1, 0xe4, 0x01, 0x00, 0x80, 0xe2,
+ 0x02, 0x00, 0x50, 0xe1, 0xf3, 0xff, 0xff, 0x3a, 0xc8, 0x00, 0xa0, 0xe3, 0x98, 0xff, 0xff, 0xeb,
+ 0x70, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x0c, 0x00, 0x02, 0x01, 0x02, 0x00, 0x02,
+ 0x00, 0x01, 0x00, 0x02
};
struct atmel_private {
@@ -433,7 +433,7 @@ struct atmel_private {
struct net_device *dev;
struct device *sys_dev;
struct iw_statistics wstats;
- spinlock_t irqlock, timerlock; // spinlocks
+ spinlock_t irqlock, timerlock; /* spinlocks */
enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
enum {
CARD_TYPE_PARALLEL_FLASH,
@@ -541,7 +541,7 @@ struct atmel_private {
u8 rx_buf[MAX_WIRELESS_BODY];
};
-static u8 atmel_basic_rates[4] = {0x82,0x84,0x0b,0x16};
+static u8 atmel_basic_rates[4] = {0x82, 0x84, 0x0b, 0x16};
static const struct {
int reg_domain;
@@ -1283,17 +1283,17 @@ static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
static int atmel_change_mtu(struct net_device *dev, int new_mtu)
{
- if ((new_mtu < 68) || (new_mtu > 2312))
- return -EINVAL;
- dev->mtu = new_mtu;
- return 0;
+ if ((new_mtu < 68) || (new_mtu > 2312))
+ return -EINVAL;
+ dev->mtu = new_mtu;
+ return 0;
}
static int atmel_set_mac_address(struct net_device *dev, void *p)
{
struct sockaddr *addr = p;
- memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
+ memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
return atmel_open(dev);
}
@@ -1420,10 +1420,17 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
priv->firmware_id);
switch (priv->card_type) {
- case CARD_TYPE_PARALLEL_FLASH: c = "Parallel flash"; break;
- case CARD_TYPE_SPI_FLASH: c = "SPI flash\n"; break;
- case CARD_TYPE_EEPROM: c = "EEPROM"; break;
- default: c = "<unknown>";
+ case CARD_TYPE_PARALLEL_FLASH:
+ c = "Parallel flash";
+ break;
+ case CARD_TYPE_SPI_FLASH:
+ c = "SPI flash\n";
+ break;
+ case CARD_TYPE_EEPROM:
+ c = "EEPROM";
+ break;
+ default:
+ c = "<unknown>";
}
r = "<unknown>";
@@ -1439,16 +1446,33 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
priv->use_wpa ? "Yes" : "No");
}
- switch(priv->station_state) {
- case STATION_STATE_SCANNING: s = "Scanning"; break;
- case STATION_STATE_JOINNING: s = "Joining"; break;
- case STATION_STATE_AUTHENTICATING: s = "Authenticating"; break;
- case STATION_STATE_ASSOCIATING: s = "Associating"; break;
- case STATION_STATE_READY: s = "Ready"; break;
- case STATION_STATE_REASSOCIATING: s = "Reassociating"; break;
- case STATION_STATE_MGMT_ERROR: s = "Management error"; break;
- case STATION_STATE_DOWN: s = "Down"; break;
- default: s = "<unknown>";
+ switch (priv->station_state) {
+ case STATION_STATE_SCANNING:
+ s = "Scanning";
+ break;
+ case STATION_STATE_JOINNING:
+ s = "Joining";
+ break;
+ case STATION_STATE_AUTHENTICATING:
+ s = "Authenticating";
+ break;
+ case STATION_STATE_ASSOCIATING:
+ s = "Associating";
+ break;
+ case STATION_STATE_READY:
+ s = "Ready";
+ break;
+ case STATION_STATE_REASSOCIATING:
+ s = "Reassociating";
+ break;
+ case STATION_STATE_MGMT_ERROR:
+ s = "Management error";
+ break;
+ case STATION_STATE_DOWN:
+ s = "Down";
+ break;
+ default:
+ s = "<unknown>";
}
p += sprintf(p, "Current state:\t\t%s\n", s);
@@ -1458,16 +1482,30 @@ static int atmel_proc_output (char *buf, struct atmel_private *priv)
static int atmel_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
- struct atmel_private *priv = data;
+ struct atmel_private *priv = data;
int len = atmel_proc_output (page, priv);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ if (len <= off+count)
+ *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len > count)
+ len = count;
+ if (len < 0)
+ len = 0;
+ return len;
}
+static const struct net_device_ops atmel_netdev_ops = {
+ .ndo_open = atmel_open,
+ .ndo_stop = atmel_close,
+ .ndo_change_mtu = atmel_change_mtu,
+ .ndo_set_mac_address = atmel_set_mac_address,
+ .ndo_start_xmit = start_tx,
+ .ndo_do_ioctl = atmel_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
const AtmelFWType fw_type,
struct device *sys_dev,
@@ -1479,11 +1517,11 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
int rc;
/* Create the network device object. */
- dev = alloc_etherdev(sizeof(*priv));
- if (!dev) {
+ dev = alloc_etherdev(sizeof(*priv));
+ if (!dev) {
printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n");
return NULL;
- }
+ }
if (dev_alloc_name(dev, dev->name) < 0) {
printk(KERN_ERR "atmel: Couldn't get name!\n");
goto err_out_free;
@@ -1552,13 +1590,8 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
priv->management_timer.function = atmel_management_timer;
priv->management_timer.data = (unsigned long) dev;
- dev->open = atmel_open;
- dev->stop = atmel_close;
- dev->change_mtu = atmel_change_mtu;
- dev->set_mac_address = atmel_set_mac_address;
- dev->hard_start_xmit = start_tx;
- dev->wireless_handlers = (struct iw_handler_def *)&atmel_handler_def;
- dev->do_ioctl = atmel_ioctl;
+ dev->netdev_ops = &atmel_netdev_ops;
+ dev->wireless_handlers = &atmel_handler_def;
dev->irq = irq;
dev->base_addr = port;
@@ -1577,7 +1610,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
if (register_netdev(dev))
goto err_out_res;
- if (!probe_atmel_card(dev)){
+ if (!probe_atmel_card(dev)) {
unregister_netdev(dev);
goto err_out_res;
}
@@ -1594,7 +1627,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
return dev;
err_out_res:
- release_region( dev->base_addr, 32);
+ release_region(dev->base_addr, 32);
err_out_irq:
free_irq(dev->irq, dev);
err_out_free:
@@ -1632,7 +1665,7 @@ static int atmel_set_essid(struct net_device *dev,
struct atmel_private *priv = netdev_priv(dev);
/* Check if we asked for `any' */
- if(dwrq->flags == 0) {
+ if (dwrq->flags == 0) {
priv->connect_to_any_BSS = 1;
} else {
int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
@@ -1768,7 +1801,7 @@ static int atmel_set_encode(struct net_device *dev,
}
if (dwrq->flags & IW_ENCODE_RESTRICTED)
priv->exclude_unencrypted = 1;
- if(dwrq->flags & IW_ENCODE_OPEN)
+ if (dwrq->flags & IW_ENCODE_OPEN)
priv->exclude_unencrypted = 0;
return -EINPROGRESS; /* Call commit handler */
@@ -1797,7 +1830,7 @@ static int atmel_get_encode(struct net_device *dev,
/* Copy the key to the user buffer */
dwrq->length = priv->wep_key_len[index];
if (dwrq->length > 16) {
- dwrq->length=0;
+ dwrq->length = 0;
} else {
memset(extra, 0, 16);
memcpy(extra, priv->wep_keys[index], dwrq->length);
@@ -2013,11 +2046,20 @@ static int atmel_set_rate(struct net_device *dev,
} else {
/* Setting by frequency value */
switch (vwrq->value) {
- case 1000000: priv->tx_rate = 0; break;
- case 2000000: priv->tx_rate = 1; break;
- case 5500000: priv->tx_rate = 2; break;
- case 11000000: priv->tx_rate = 3; break;
- default: return -EINVAL;
+ case 1000000:
+ priv->tx_rate = 0;
+ break;
+ case 2000000:
+ priv->tx_rate = 1;
+ break;
+ case 5500000:
+ priv->tx_rate = 2;
+ break;
+ case 11000000:
+ priv->tx_rate = 3;
+ break;
+ default:
+ return -EINVAL;
}
}
}
@@ -2062,11 +2104,19 @@ static int atmel_get_rate(struct net_device *dev,
vwrq->value = 11000000;
} else {
vwrq->fixed = 1;
- switch(priv->tx_rate) {
- case 0: vwrq->value = 1000000; break;
- case 1: vwrq->value = 2000000; break;
- case 2: vwrq->value = 5500000; break;
- case 3: vwrq->value = 11000000; break;
+ switch (priv->tx_rate) {
+ case 0:
+ vwrq->value = 1000000;
+ break;
+ case 1:
+ vwrq->value = 2000000;
+ break;
+ case 2:
+ vwrq->value = 5500000;
+ break;
+ case 3:
+ vwrq->value = 11000000;
+ break;
}
}
return 0;
@@ -2204,9 +2254,6 @@ static int atmel_get_frag(struct net_device *dev,
return 0;
}
-static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
- 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
-
static int atmel_set_freq(struct net_device *dev,
struct iw_request_info *info,
struct iw_freq *fwrq,
@@ -2216,16 +2263,12 @@ static int atmel_set_freq(struct net_device *dev,
int rc = -EINPROGRESS; /* Call commit handler */
/* If setting by frequency, convert to a channel */
- if ((fwrq->e == 1) &&
- (fwrq->m >= (int) 241200000) &&
- (fwrq->m <= (int) 248700000)) {
+ if (fwrq->e == 1) {
int f = fwrq->m / 100000;
- int c = 0;
- while ((c < 14) && (f != frequency_list[c]))
- c++;
+
/* Hack to fall through... */
fwrq->e = 0;
- fwrq->m = c + 1;
+ fwrq->m = ieee80211_freq_to_dsss_chan(f);
}
/* Setting by channel number */
if ((fwrq->m > 1000) || (fwrq->e > 0))
@@ -2384,8 +2427,11 @@ static int atmel_get_range(struct net_device *dev,
if (range->num_channels != 0) {
for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
range->freq[k].i = i; /* List index */
- range->freq[k].m = frequency_list[i - 1] * 100000;
- range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
+
+ /* Values in MHz -> * 10^5 * 10 */
+ range->freq[k].m = (ieee80211_dsss_chan_to_freq(i) *
+ 100000);
+ range->freq[k++].e = 1;
}
range->num_frequency = k;
}
@@ -2580,8 +2626,7 @@ static const struct iw_priv_args atmel_private_args[] = {
},
};
-static const struct iw_handler_def atmel_handler_def =
-{
+static const struct iw_handler_def atmel_handler_def = {
.num_standard = ARRAY_SIZE(atmel_handler),
.num_private = ARRAY_SIZE(atmel_private_handler),
.num_private_args = ARRAY_SIZE(atmel_private_args),
@@ -2838,7 +2883,7 @@ static void send_authentication_request(struct atmel_private *priv, u16 system,
if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
/* no WEP for authentication frames with TrSeqNo 1 */
- header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+ header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
auth.alg = cpu_to_le16(system);
@@ -2973,7 +3018,7 @@ static void store_bss_info(struct atmel_private *priv,
if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0)
index = i;
- /* If we process a probe and an entry from this BSS exists
+ /* If we process a probe and an entry from this BSS exists
we will update the BSS entry with the info from this BSS.
If we process a beacon we will only update RSSI */
@@ -2999,7 +3044,7 @@ static void store_bss_info(struct atmel_private *priv,
if (capability & WLAN_CAPABILITY_IBSS)
priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
else if (capability & WLAN_CAPABILITY_ESS)
- priv->BSSinfo[index].BSStype =IW_MODE_INFRA;
+ priv->BSSinfo[index].BSStype = IW_MODE_INFRA;
priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
SHORT_PREAMBLE : LONG_PREAMBLE;
@@ -3046,7 +3091,7 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
}
if (should_associate) {
- if(priv->station_was_associated) {
+ if (priv->station_was_associated) {
atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
send_association_request(priv, 1);
return;
@@ -3067,8 +3112,8 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
priv->exclude_unencrypted = 1;
send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
return;
- } else if ( system == WLAN_AUTH_SHARED_KEY
- && priv->wep_is_on) {
+ } else if (system == WLAN_AUTH_SHARED_KEY
+ && priv->wep_is_on) {
priv->CurrentAuthentTransactionSeqNum = 0x001;
priv->exclude_unencrypted = 0;
send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
@@ -3256,11 +3301,11 @@ static void smooth_rssi(struct atmel_private *priv, u8 rssi)
u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
switch (priv->firmware_type) {
- case ATMEL_FW_TYPE_502E:
- max_rssi = 63; /* 502-rmfd-reve max by experiment */
- break;
- default:
- break;
+ case ATMEL_FW_TYPE_502E:
+ max_rssi = 63; /* 502-rmfd-reve max by experiment */
+ break;
+ default:
+ break;
}
rssi = rssi * 100 / max_rssi;
@@ -3477,8 +3522,7 @@ static void atmel_command_irq(struct atmel_private *priv)
status == CMD_STATUS_IN_PROGRESS)
return;
- switch (command){
-
+ switch (command) {
case CMD_Start:
if (status == CMD_STATUS_COMPLETE) {
priv->station_was_associated = priv->station_is_associated;
@@ -3713,7 +3757,7 @@ static int probe_atmel_card(struct net_device *dev)
if (rc) {
if (dev->dev_addr[0] == 0xFF) {
- u8 default_mac[] = {0x00,0x04, 0x25, 0x00, 0x00, 0x00};
+ u8 default_mac[] = {0x00, 0x04, 0x25, 0x00, 0x00, 0x00};
printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
memcpy(dev->dev_addr, default_mac, 6);
}
@@ -3807,7 +3851,7 @@ static void build_wpa_mib(struct atmel_private *priv)
} else {
mib.group_key = i;
priv->group_cipher_suite = priv->pairwise_cipher_suite;
- mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
+ mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
}
}
@@ -3917,7 +3961,7 @@ static int reset_atmel_card(struct net_device *dev)
len = fw_entry->size;
}
- if (len <= 0x6000) {
+ if (len <= 0x6000) {
atmel_write16(priv->dev, BSR, BSS_IRAM);
atmel_copy_to_card(priv->dev, 0, fw, len);
atmel_set_gcr(priv->dev, GCR_REMAP);
@@ -3946,7 +3990,7 @@ static int reset_atmel_card(struct net_device *dev)
priv->use_wpa = (priv->host_info.major_version == 4);
priv->radio_on_broken = (priv->host_info.major_version == 5);
- /* unmask all irq sources */
+ /* unmask all irq sources */
atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
/* int Tx system and enable Tx */
@@ -3979,7 +4023,7 @@ static int reset_atmel_card(struct net_device *dev)
CMD_STATUS_REJECTED_RADIO_OFF) {
printk(KERN_INFO "%s: cannot turn the radio on.\n",
dev->name);
- return -EIO;
+ return -EIO;
}
}
@@ -4003,8 +4047,7 @@ static int reset_atmel_card(struct net_device *dev)
else
build_wep_mib(priv);
- if (old_state == STATION_STATE_READY)
- {
+ if (old_state == STATION_STATE_READY) {
union iwreq_data wrqu;
wrqu.data.length = 0;
@@ -4281,24 +4324,24 @@ static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
.set NVRAM_LENGTH, 0x0200
.set MAC_ADDRESS_MIB, SRAM_BASE
.set MAC_ADDRESS_LENGTH, 6
- .set MAC_BOOT_FLAG, 0x10
+ .set MAC_BOOT_FLAG, 0x10
.set MR1, 0
.set MR2, 4
.set MR3, 8
.set MR4, 0xC
RESET_VECTOR:
- b RESET_HANDLER
+ b RESET_HANDLER
UNDEF_VECTOR:
- b HALT1
+ b HALT1
SWI_VECTOR:
- b HALT1
+ b HALT1
IABORT_VECTOR:
- b HALT1
+ b HALT1
DABORT_VECTOR:
RESERVED_VECTOR:
- b HALT1
+ b HALT1
IRQ_VECTOR:
- b HALT1
+ b HALT1
FIQ_VECTOR:
b HALT1
HALT1: b HALT1
@@ -4310,7 +4353,7 @@ RESET_HANDLER:
ldr r0, =SPI_CGEN_BASE
mov r1, #0
mov r1, r1, lsl #3
- orr r1,r1, #0
+ orr r1, r1, #0
str r1, [r0]
ldr r1, [r0, #28]
bic r1, r1, #16
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 1f81d36f87c5..aab71a70ba78 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -110,10 +110,18 @@ config B43_DEBUG
bool "Broadcom 43xx debugging"
depends on B43
---help---
- Broadcom 43xx debugging messages.
+ Broadcom 43xx debugging.
- Say Y, if you want to find out why the driver does not
- work for you.
+ This adds additional runtime sanity checks and statistics to the driver.
+ These checks and statistics might me expensive and hurt runtime performance
+ of your system.
+ This also adds the b43 debugfs interface.
+
+ Do not enable this, unless you are debugging the driver.
+
+ Say N, if you are a distributor or user building a release kernel
+ for production use.
+ Only say Y, if you are debugging a problem in the b43 driver sourcecode.
config B43_FORCE_PIO
bool "Force usage of PIO instead of DMA"
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 14a02b3aea53..281ef8310350 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -6,6 +6,7 @@ b43-y += phy_g.o
b43-y += phy_a.o
b43-$(CONFIG_B43_NPHY) += phy_n.o
b43-$(CONFIG_B43_PHY_LP) += phy_lp.o
+b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o
b43-y += sysfs.o
b43-y += xmit.o
b43-y += lo.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index a53c378e7484..beaf18d6e8a7 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -120,6 +120,9 @@
#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */
#define B43_MMIO_IFSCTL_USE_EDCF 0x0004
#define B43_MMIO_POWERUP_DELAY 0x6A8
+#define B43_MMIO_BTCOEX_CTL 0x6B4 /* Bluetooth Coexistence Control */
+#define B43_MMIO_BTCOEX_STAT 0x6B6 /* Bluetooth Coexistence Status */
+#define B43_MMIO_BTCOEX_TXCTL 0x6B8 /* Bluetooth Coexistence Transmit Control */
/* SPROM boardflags_lo values */
#define B43_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */
@@ -547,9 +550,6 @@ struct b43_noise_calculation {
struct b43_stats {
u8 link_noise;
- /* Store the last TX/RX times here for updating the leds. */
- unsigned long last_tx;
- unsigned long last_rx;
};
struct b43_key {
@@ -655,10 +655,39 @@ struct b43_wl {
struct work_struct txpower_adjust_work;
};
+/* The type of the firmware file. */
+enum b43_firmware_file_type {
+ B43_FWTYPE_PROPRIETARY,
+ B43_FWTYPE_OPENSOURCE,
+ B43_NR_FWTYPES,
+};
+
+/* Context data for fetching firmware. */
+struct b43_request_fw_context {
+ /* The device we are requesting the fw for. */
+ struct b43_wldev *dev;
+ /* The type of firmware to request. */
+ enum b43_firmware_file_type req_type;
+ /* Error messages for each firmware type. */
+ char errors[B43_NR_FWTYPES][128];
+ /* Temporary buffer for storing the firmware name. */
+ char fwname[64];
+ /* A fatal error occured while requesting. Firmware reqest
+ * can not continue, as any other reqest will also fail. */
+ int fatal_failure;
+};
+
/* In-memory representation of a cached microcode file. */
struct b43_firmware_file {
const char *filename;
const struct firmware *data;
+ /* Type of the firmware file name. Note that this does only indicate
+ * the type by the firmware name. NOT the file contents.
+ * If you want to check for proprietary vs opensource, use (struct b43_firmware)->opensource
+ * instead! The (struct b43_firmware)->opensource flag is derived from the actual firmware
+ * binary code, not just the filename.
+ */
+ enum b43_firmware_file_type type;
};
/* Pointers to the firmware data and meta information about it. */
@@ -677,7 +706,8 @@ struct b43_firmware {
/* Firmware patchlevel */
u16 patch;
- /* Set to true, if we are using an opensource firmware. */
+ /* Set to true, if we are using an opensource firmware.
+ * Use this to check for proprietary vs opensource. */
bool opensource;
/* Set to true, if the core needs a PCM firmware, but
* we failed to load one. This is always false for
@@ -848,12 +878,9 @@ void b43err(struct b43_wl *wl, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
void b43warn(struct b43_wl *wl, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
-#if B43_DEBUG
void b43dbg(struct b43_wl *wl, const char *fmt, ...)
__attribute__ ((format(printf, 2, 3)));
-#else /* DEBUG */
-# define b43dbg(wl, fmt...) do { /* nothing */ } while (0)
-#endif /* DEBUG */
+
/* A WARN_ON variant that vanishes when b43 debugging is disabled.
* This _also_ evaluates the arg with debugging disabled. */
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index e04fc91f569e..45e3d6af69f5 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -51,8 +51,8 @@ struct b43_debugfs_fops {
};
static inline
-struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev,
- const struct b43_debugfs_fops *dfops)
+struct b43_dfs_file *fops_to_dfs_file(struct b43_wldev *dev,
+ const struct b43_debugfs_fops *dfops)
{
void *p;
@@ -367,34 +367,6 @@ static int mmio32write__write_file(struct b43_wldev *dev,
return 0;
}
-/* wl->irq_lock is locked */
-static ssize_t tsf_read_file(struct b43_wldev *dev,
- char *buf, size_t bufsize)
-{
- ssize_t count = 0;
- u64 tsf;
-
- b43_tsf_read(dev, &tsf);
- fappend("0x%08x%08x\n",
- (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
- (unsigned int)(tsf & 0xFFFFFFFFULL));
-
- return count;
-}
-
-/* wl->irq_lock is locked */
-static int tsf_write_file(struct b43_wldev *dev,
- const char *buf, size_t count)
-{
- u64 tsf;
-
- if (sscanf(buf, "%llu", (unsigned long long *)(&tsf)) != 1)
- return -EINVAL;
- b43_tsf_write(dev, tsf);
-
- return 0;
-}
-
static ssize_t txstat_read_file(struct b43_wldev *dev,
char *buf, size_t bufsize)
{
@@ -691,15 +663,23 @@ B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1);
B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
-B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1);
B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0);
B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1);
B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0);
-int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
+bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
{
- return !!(dev->dfsentry && dev->dfsentry->dyn_debug[feature]);
+ bool enabled;
+
+ enabled = (dev->dfsentry && dev->dfsentry->dyn_debug[feature]);
+ if (unlikely(enabled)) {
+ /* Force full debugging messages, if the user enabled
+ * some dynamic debugging feature. */
+ b43_modparam_verbose = B43_VERBOSITY_MAX;
+ }
+
+ return enabled;
}
static void b43_remove_dynamic_debug(struct b43_wldev *dev)
@@ -805,7 +785,6 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
ADD_FILE(mmio16write, 0200);
ADD_FILE(mmio32read, 0600);
ADD_FILE(mmio32write, 0200);
- ADD_FILE(tsf, 0600);
ADD_FILE(txstat, 0400);
ADD_FILE(restart, 0200);
ADD_FILE(loctls, 0400);
@@ -834,7 +813,6 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
debugfs_remove(e->file_mmio16write.dentry);
debugfs_remove(e->file_mmio32read.dentry);
debugfs_remove(e->file_mmio32write.dentry);
- debugfs_remove(e->file_tsf.dentry);
debugfs_remove(e->file_txstat.dentry);
debugfs_remove(e->file_restart.dentry);
debugfs_remove(e->file_loctls.dentry);
diff --git a/drivers/net/wireless/b43/debugfs.h b/drivers/net/wireless/b43/debugfs.h
index 7886cbe2d1d1..b9d4de4a979c 100644
--- a/drivers/net/wireless/b43/debugfs.h
+++ b/drivers/net/wireless/b43/debugfs.h
@@ -46,7 +46,6 @@ struct b43_dfsentry {
struct b43_dfs_file file_mmio16write;
struct b43_dfs_file file_mmio32read;
struct b43_dfs_file file_mmio32write;
- struct b43_dfs_file file_tsf;
struct b43_dfs_file file_txstat;
struct b43_dfs_file file_txpower_g;
struct b43_dfs_file file_restart;
@@ -72,7 +71,7 @@ struct b43_dfsentry {
struct dentry *dyn_debug_dentries[__B43_NR_DYNDBG];
};
-int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature);
+bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature);
void b43_debugfs_init(void);
void b43_debugfs_exit(void);
@@ -83,7 +82,7 @@ void b43_debugfs_log_txstat(struct b43_wldev *dev,
#else /* CONFIG_B43_DEBUG */
-static inline int b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
+static inline bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
{
return 0;
}
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 6d65a02b7052..0cc804d0a214 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -41,6 +41,12 @@
#include <asm/div64.h>
+/* Required number of TX DMA slots per TX frame.
+ * This currently is 2, because we put the header and the ieee80211 frame
+ * into separate slots. */
+#define TX_SLOTS_PER_FRAME 2
+
+
/* 32bit DMA ops. */
static
struct b43_dmadesc_generic *op32_idx2desc(struct b43_dmaring *ring,
@@ -74,8 +80,7 @@ static void op32_fill_descriptor(struct b43_dmaring *ring,
addrext = (u32) (dmaaddr & SSB_DMA_TRANSLATION_MASK)
>> SSB_DMA_TRANSLATION_SHIFT;
addr |= ssb_dma_translation(ring->dev->dev);
- ctl = (bufsize - ring->frameoffset)
- & B43_DMA32_DCTL_BYTECNT;
+ ctl = bufsize & B43_DMA32_DCTL_BYTECNT;
if (slot == ring->nr_slots - 1)
ctl |= B43_DMA32_DCTL_DTABLEEND;
if (start)
@@ -177,8 +182,7 @@ static void op64_fill_descriptor(struct b43_dmaring *ring,
ctl0 |= B43_DMA64_DCTL0_FRAMEEND;
if (irq)
ctl0 |= B43_DMA64_DCTL0_IRQ;
- ctl1 |= (bufsize - ring->frameoffset)
- & B43_DMA64_DCTL1_BYTECNT;
+ ctl1 |= bufsize & B43_DMA64_DCTL1_BYTECNT;
ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT)
& B43_DMA64_DCTL1_ADDREXT_MASK;
@@ -576,12 +580,11 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
return -ENOMEM;
dmaaddr = map_descbuffer(ring, skb->data,
ring->rx_buffersize, 0);
- }
-
- if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
- b43err(ring->dev->wl, "RX DMA buffer allocation failed\n");
- dev_kfree_skb_any(skb);
- return -EIO;
+ if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
+ b43err(ring->dev->wl, "RX DMA buffer allocation failed\n");
+ dev_kfree_skb_any(skb);
+ return -EIO;
+ }
}
meta->skb = skb;
@@ -830,9 +833,6 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
if (ring->index == 0) {
ring->rx_buffersize = B43_DMA0_RX_BUFFERSIZE;
ring->frameoffset = B43_DMA0_RX_FRAMEOFFSET;
- } else if (ring->index == 3) {
- ring->rx_buffersize = B43_DMA3_RX_BUFFERSIZE;
- ring->frameoffset = B43_DMA3_RX_FRAMEOFFSET;
} else
B43_WARN_ON(1);
}
@@ -842,7 +842,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
#endif
if (for_tx) {
- ring->txhdr_cache = kcalloc(ring->nr_slots,
+ /* Assumption: B43_TXRING_SLOTS can be divided by TX_SLOTS_PER_FRAME */
+ BUILD_BUG_ON(B43_TXRING_SLOTS % TX_SLOTS_PER_FRAME != 0);
+
+ ring->txhdr_cache = kcalloc(ring->nr_slots / TX_SLOTS_PER_FRAME,
b43_txhdr_size(dev),
GFP_KERNEL);
if (!ring->txhdr_cache)
@@ -858,7 +861,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
b43_txhdr_size(dev), 1)) {
/* ugh realloc */
kfree(ring->txhdr_cache);
- ring->txhdr_cache = kcalloc(ring->nr_slots,
+ ring->txhdr_cache = kcalloc(ring->nr_slots / TX_SLOTS_PER_FRAME,
b43_txhdr_size(dev),
GFP_KERNEL | GFP_DMA);
if (!ring->txhdr_cache)
@@ -1149,7 +1152,10 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
u16 cookie;
size_t hdrsize = b43_txhdr_size(ring->dev);
-#define SLOTS_PER_PACKET 2
+ /* Important note: If the number of used DMA slots per TX frame
+ * is changed here, the TX_SLOTS_PER_FRAME definition at the top of
+ * the file has to be updated, too!
+ */
old_top_slot = ring->current_slot;
old_used_slots = ring->used_slots;
@@ -1159,7 +1165,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
desc = ops->idx2desc(ring, slot, &meta_hdr);
memset(meta_hdr, 0, sizeof(*meta_hdr));
- header = &(ring->txhdr_cache[slot * hdrsize]);
+ header = &(ring->txhdr_cache[(slot / TX_SLOTS_PER_FRAME) * hdrsize]);
cookie = generate_cookie(ring, slot);
err = b43_generate_txhdr(ring->dev, header,
skb->data, skb->len, info, cookie);
@@ -1254,8 +1260,8 @@ static inline int should_inject_overflow(struct b43_dmaring *ring)
}
/* Static mapping of mac80211's queues (priorities) to b43 DMA rings. */
-static struct b43_dmaring * select_ring_by_priority(struct b43_wldev *dev,
- u8 queue_prio)
+static struct b43_dmaring *select_ring_by_priority(struct b43_wldev *dev,
+ u8 queue_prio)
{
struct b43_dmaring *ring;
@@ -1306,17 +1312,19 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
}
spin_lock_irqsave(&ring->lock, flags);
+
B43_WARN_ON(!ring->tx);
- if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
- b43warn(dev->wl, "DMA queue overflow\n");
- err = -ENOSPC;
- goto out_unlock;
- }
/* Check if the queue was stopped in mac80211,
* but we got called nevertheless.
* That would be a mac80211 bug. */
B43_WARN_ON(ring->stopped);
+ if (unlikely(free_slots(ring) < TX_SLOTS_PER_FRAME)) {
+ b43warn(dev->wl, "DMA queue overflow\n");
+ err = -ENOSPC;
+ goto out_unlock;
+ }
+
/* Assign the queue number to the ring (if not already done before)
* so TX status handling can use it. The queue to ring mapping is
* static, so we don't need to store it per frame. */
@@ -1335,7 +1343,7 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
goto out_unlock;
}
ring->nr_tx_packets++;
- if ((free_slots(ring) < SLOTS_PER_PACKET) ||
+ if ((free_slots(ring) < TX_SLOTS_PER_FRAME) ||
should_inject_overflow(ring)) {
/* This TX ring is full. */
ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
@@ -1417,9 +1425,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
break;
slot = next_slot(ring, slot);
}
- dev->stats.last_tx = jiffies;
if (ring->stopped) {
- B43_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET);
+ B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);
ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);
ring->stopped = 0;
if (b43_debug(dev, B43_DBG_DMAVERBOSE)) {
@@ -1442,8 +1449,8 @@ void b43_dma_get_tx_stats(struct b43_wldev *dev,
ring = select_ring_by_priority(dev, i);
spin_lock_irqsave(&ring->lock, flags);
- stats[i].len = ring->used_slots / SLOTS_PER_PACKET;
- stats[i].limit = ring->nr_slots / SLOTS_PER_PACKET;
+ stats[i].len = ring->used_slots / TX_SLOTS_PER_FRAME;
+ stats[i].limit = ring->nr_slots / TX_SLOTS_PER_FRAME;
stats[i].count = ring->nr_tx_packets;
spin_unlock_irqrestore(&ring->lock, flags);
}
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index d1eb5c0848a5..05dde646d831 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -1,14 +1,12 @@
#ifndef B43_DMA_H_
#define B43_DMA_H_
-#include <linux/list.h>
+#include <linux/ieee80211.h>
#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include <linux/linkage.h>
-#include <asm/atomic.h>
#include "b43.h"
+
/* DMA-Interrupt reasons. */
#define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \
| (1 << 14) | (1 << 15))
@@ -161,14 +159,13 @@ struct b43_dmadesc_generic {
/* Misc DMA constants */
#define B43_DMA_RINGMEMSIZE PAGE_SIZE
-#define B43_DMA0_RX_FRAMEOFFSET 30
-#define B43_DMA3_RX_FRAMEOFFSET 0
+#define B43_DMA0_RX_FRAMEOFFSET 30
/* DMA engine tuning knobs */
-#define B43_TXRING_SLOTS 128
+#define B43_TXRING_SLOTS 256
#define B43_RXRING_SLOTS 64
-#define B43_DMA0_RX_BUFFERSIZE (2304 + 100)
-#define B43_DMA3_RX_BUFFERSIZE 16
+#define B43_DMA0_RX_BUFFERSIZE IEEE80211_MAX_FRAME_LEN
+
struct sk_buff;
struct b43_private;
@@ -215,7 +212,7 @@ struct b43_dmaring {
void *descbase;
/* Meta data about all descriptors. */
struct b43_dmadesc_meta *meta;
- /* Cache of TX headers for each slot.
+ /* Cache of TX headers for each TX frame.
* This is to avoid an allocation on each TX.
* This is NULL for an RX ring.
*/
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c
index 6a18a1470465..22d0fbd83a62 100644
--- a/drivers/net/wireless/b43/lo.c
+++ b/drivers/net/wireless/b43/lo.c
@@ -36,8 +36,8 @@
#include <linux/sched.h>
-static struct b43_lo_calib * b43_find_lo_calib(struct b43_txpower_lo_control *lo,
- const struct b43_bbatt *bbatt,
+static struct b43_lo_calib *b43_find_lo_calib(struct b43_txpower_lo_control *lo,
+ const struct b43_bbatt *bbatt,
const struct b43_rfatt *rfatt)
{
struct b43_lo_calib *c;
@@ -138,7 +138,7 @@ static u16 lo_measure_feedthrough(struct b43_wldev *dev,
* "pad_mix_gain" is the PAD Mixer Gain.
*/
static u16 lo_txctl_register_table(struct b43_wldev *dev,
- u16 * value, u16 * pad_mix_gain)
+ u16 *value, u16 *pad_mix_gain)
{
struct b43_phy *phy = &dev->phy;
u16 reg, v, padmix;
@@ -225,14 +225,12 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
radio_pctl_reg = tmp;
}
}
- b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
- & 0xFFF0) | radio_pctl_reg);
+ b43_radio_maskset(dev, 0x43, 0xFFF0, radio_pctl_reg);
b43_gphy_set_baseband_attenuation(dev, 2);
reg = lo_txctl_register_table(dev, &mask, NULL);
mask = ~mask;
- b43_radio_write16(dev, reg, b43_radio_read16(dev, reg)
- & mask);
+ b43_radio_mask(dev, reg, mask);
if (has_tx_magnification(phy)) {
int i, j;
@@ -242,14 +240,10 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
for (i = 0; i < ARRAY_SIZE(tx_magn_values); i++) {
tx_magn = tx_magn_values[i];
- b43_radio_write16(dev, 0x52,
- (b43_radio_read16(dev, 0x52)
- & 0xFF0F) | tx_magn);
+ b43_radio_maskset(dev, 0x52, 0xFF0F, tx_magn);
for (j = 0; j < ARRAY_SIZE(tx_bias_values); j++) {
tx_bias = tx_bias_values[j];
- b43_radio_write16(dev, 0x52,
- (b43_radio_read16(dev, 0x52)
- & 0xFFF0) | tx_bias);
+ b43_radio_maskset(dev, 0x52, 0xFFF0, tx_bias);
feedthrough =
lo_measure_feedthrough(dev, 0, pga,
trsw_rx);
@@ -269,8 +263,7 @@ static void lo_measure_txctl_values(struct b43_wldev *dev)
} else {
lo->tx_magn = 0;
lo->tx_bias = 0;
- b43_radio_write16(dev, 0x52, b43_radio_read16(dev, 0x52)
- & 0xFFF0); /* TX bias == 0 */
+ b43_radio_mask(dev, 0x52, 0xFFF0); /* TX bias == 0 */
}
lo->txctl_measured_time = jiffies;
}
@@ -406,18 +399,10 @@ static void lo_measure_setup(struct b43_wldev *dev,
sav->phy_cck_14 = b43_phy_read(dev, B43_PHY_CCK(0x14));
sav->phy_hpwr_tssictl = b43_phy_read(dev, B43_PHY_HPWR_TSSICTL);
- b43_phy_write(dev, B43_PHY_HPWR_TSSICTL,
- b43_phy_read(dev, B43_PHY_HPWR_TSSICTL)
- | 0x100);
- b43_phy_write(dev, B43_PHY_EXTG(0x01),
- b43_phy_read(dev, B43_PHY_EXTG(0x01))
- | 0x40);
- b43_phy_write(dev, B43_PHY_DACCTL,
- b43_phy_read(dev, B43_PHY_DACCTL)
- | 0x40);
- b43_phy_write(dev, B43_PHY_CCK(0x14),
- b43_phy_read(dev, B43_PHY_CCK(0x14))
- | 0x200);
+ b43_phy_set(dev, B43_PHY_HPWR_TSSICTL, 0x100);
+ b43_phy_set(dev, B43_PHY_EXTG(0x01), 0x40);
+ b43_phy_set(dev, B43_PHY_DACCTL, 0x40);
+ b43_phy_set(dev, B43_PHY_CCK(0x14), 0x200);
}
if (phy->type == B43_PHYTYPE_B &&
phy->radio_ver == 0x2050 && phy->radio_rev < 6) {
@@ -434,17 +419,10 @@ static void lo_measure_setup(struct b43_wldev *dev,
sav->phy_cck_3E = b43_phy_read(dev, B43_PHY_CCK(0x3E));
sav->phy_crs0 = b43_phy_read(dev, B43_PHY_CRS0);
- b43_phy_write(dev, B43_PHY_CLASSCTL,
- b43_phy_read(dev, B43_PHY_CLASSCTL)
- & 0xFFFC);
- b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
- & 0x7FFF);
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER)
- | 0x0003);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev, B43_PHY_ANALOGOVERVAL)
- & 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_CLASSCTL, 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_CRS0, 0x7FFF);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0003);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFC);
if (phy->type == B43_PHYTYPE_G) {
if ((phy->rev >= 7) &&
(sprom->boardflags_lo & B43_BFL_EXTLNA)) {
@@ -558,8 +536,7 @@ static void lo_measure_restore(struct b43_wldev *dev,
b43_radio_write16(dev, 0x7A, sav->radio_7A);
if (!has_tx_magnification(phy)) {
tmp = sav->radio_52;
- b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
- & 0xFF0F) | tmp);
+ b43_radio_maskset(dev, 0x52, 0xFF0F, tmp);
}
b43_write16(dev, 0x3E2, sav->reg_3E2);
if (phy->type == B43_PHYTYPE_B &&
@@ -754,9 +731,9 @@ static void lo_probe_loctls_statemachine(struct b43_wldev *dev,
}
static
-struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
- const struct b43_bbatt *bbatt,
- const struct b43_rfatt *rfatt)
+struct b43_lo_calib *b43_calibrate_lo_setting(struct b43_wldev *dev,
+ const struct b43_bbatt *bbatt,
+ const struct b43_rfatt *rfatt)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_g *gphy = phy->g;
@@ -778,12 +755,8 @@ struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
txctl_reg = lo_txctl_register_table(dev, &txctl_value, &pad_mix_gain);
- b43_radio_write16(dev, 0x43,
- (b43_radio_read16(dev, 0x43) & 0xFFF0)
- | rfatt->att);
- b43_radio_write16(dev, txctl_reg,
- (b43_radio_read16(dev, txctl_reg) & ~txctl_value)
- | (rfatt->with_padmix) ? txctl_value : 0);
+ b43_radio_maskset(dev, 0x43, 0xFFF0, rfatt->att);
+ b43_radio_maskset(dev, txctl_reg, ~txctl_value, (rfatt->with_padmix ? txctl_value :0));
max_rx_gain = rfatt->att * 2;
max_rx_gain += bbatt->att / 2;
@@ -824,9 +797,9 @@ struct b43_lo_calib * b43_calibrate_lo_setting(struct b43_wldev *dev,
/* Get a calibrated LO setting for the given attenuation values.
* Might return a NULL pointer under OOM! */
static
-struct b43_lo_calib * b43_get_calib_lo_settings(struct b43_wldev *dev,
- const struct b43_bbatt *bbatt,
- const struct b43_rfatt *rfatt)
+struct b43_lo_calib *b43_get_calib_lo_settings(struct b43_wldev *dev,
+ const struct b43_bbatt *bbatt,
+ const struct b43_rfatt *rfatt)
{
struct b43_txpower_lo_control *lo = dev->phy.g->lo_control;
struct b43_lo_calib *c;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index c788bad10661..4896e0831114 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4,7 +4,7 @@
Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>
Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it>
- Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de>
+ Copyright (c) 2005-2009 Michael Buesch <mb@bu3sch.de>
Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -88,6 +88,10 @@ static int modparam_btcoex = 1;
module_param_named(btcoex, modparam_btcoex, int, 0444);
MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistance (default on)");
+int b43_modparam_verbose = B43_VERBOSITY_DEFAULT;
+module_param_named(verbose, b43_modparam_verbose, int, 0644);
+MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug");
+
static const struct ssb_device_id b43_ssb_tbl[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
@@ -97,6 +101,8 @@ static const struct ssb_device_id b43_ssb_tbl[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
+ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15),
+ SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16),
SSB_DEVTABLE_END
};
@@ -298,6 +304,8 @@ void b43info(struct b43_wl *wl, const char *fmt, ...)
{
va_list args;
+ if (b43_modparam_verbose < B43_VERBOSITY_INFO)
+ return;
if (!b43_ratelimit(wl))
return;
va_start(args, fmt);
@@ -311,6 +319,8 @@ void b43err(struct b43_wl *wl, const char *fmt, ...)
{
va_list args;
+ if (b43_modparam_verbose < B43_VERBOSITY_ERROR)
+ return;
if (!b43_ratelimit(wl))
return;
va_start(args, fmt);
@@ -324,6 +334,8 @@ void b43warn(struct b43_wl *wl, const char *fmt, ...)
{
va_list args;
+ if (b43_modparam_verbose < B43_VERBOSITY_WARN)
+ return;
if (!b43_ratelimit(wl))
return;
va_start(args, fmt);
@@ -333,18 +345,18 @@ void b43warn(struct b43_wl *wl, const char *fmt, ...)
va_end(args);
}
-#if B43_DEBUG
void b43dbg(struct b43_wl *wl, const char *fmt, ...)
{
va_list args;
+ if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
+ return;
va_start(args, fmt);
printk(KERN_DEBUG "b43-%s debug: ",
(wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan");
vprintk(fmt, args);
va_end(args);
}
-#endif /* DEBUG */
static void b43_ram_write(struct b43_wldev *dev, u16 offset, u32 val)
{
@@ -500,7 +512,7 @@ void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
}
/* Read HostFlags */
-u64 b43_hf_read(struct b43_wldev * dev)
+u64 b43_hf_read(struct b43_wldev *dev)
{
u64 ret;
@@ -526,52 +538,20 @@ void b43_hf_write(struct b43_wldev *dev, u64 value)
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi);
}
-void b43_tsf_read(struct b43_wldev *dev, u64 * tsf)
+void b43_tsf_read(struct b43_wldev *dev, u64 *tsf)
{
- /* We need to be careful. As we read the TSF from multiple
- * registers, we should take care of register overflows.
- * In theory, the whole tsf read process should be atomic.
- * We try to be atomic here, by restaring the read process,
- * if any of the high registers changed (overflew).
- */
- if (dev->dev->id.revision >= 3) {
- u32 low, high, high2;
+ u32 low, high;
- do {
- high = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH);
- low = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_LOW);
- high2 = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH);
- } while (unlikely(high != high2));
-
- *tsf = high;
- *tsf <<= 32;
- *tsf |= low;
- } else {
- u64 tmp;
- u16 v0, v1, v2, v3;
- u16 test1, test2, test3;
+ B43_WARN_ON(dev->dev->id.revision < 3);
- do {
- v3 = b43_read16(dev, B43_MMIO_TSF_3);
- v2 = b43_read16(dev, B43_MMIO_TSF_2);
- v1 = b43_read16(dev, B43_MMIO_TSF_1);
- v0 = b43_read16(dev, B43_MMIO_TSF_0);
+ /* The hardware guarantees us an atomic read, if we
+ * read the low register first. */
+ low = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_LOW);
+ high = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH);
- test3 = b43_read16(dev, B43_MMIO_TSF_3);
- test2 = b43_read16(dev, B43_MMIO_TSF_2);
- test1 = b43_read16(dev, B43_MMIO_TSF_1);
- } while (v3 != test3 || v2 != test2 || v1 != test1);
-
- *tsf = v3;
- *tsf <<= 48;
- tmp = v2;
- tmp <<= 32;
- *tsf |= tmp;
- tmp = v1;
- tmp <<= 16;
- *tsf |= tmp;
- *tsf |= v0;
- }
+ *tsf = high;
+ *tsf <<= 32;
+ *tsf |= low;
}
static void b43_time_lock(struct b43_wldev *dev)
@@ -598,35 +578,18 @@ static void b43_time_unlock(struct b43_wldev *dev)
static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf)
{
- /* Be careful with the in-progress timer.
- * First zero out the low register, so we have a full
- * register-overflow duration to complete the operation.
- */
- if (dev->dev->id.revision >= 3) {
- u32 lo = (tsf & 0x00000000FFFFFFFFULL);
- u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32;
+ u32 low, high;
- b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, 0);
- mmiowb();
- b43_write32(dev, B43_MMIO_REV3PLUS_TSF_HIGH, hi);
- mmiowb();
- b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, lo);
- } else {
- u16 v0 = (tsf & 0x000000000000FFFFULL);
- u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16;
- u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32;
- u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48;
+ B43_WARN_ON(dev->dev->id.revision < 3);
- b43_write16(dev, B43_MMIO_TSF_0, 0);
- mmiowb();
- b43_write16(dev, B43_MMIO_TSF_3, v3);
- mmiowb();
- b43_write16(dev, B43_MMIO_TSF_2, v2);
- mmiowb();
- b43_write16(dev, B43_MMIO_TSF_1, v1);
- mmiowb();
- b43_write16(dev, B43_MMIO_TSF_0, v0);
- }
+ low = tsf;
+ high = (tsf >> 32);
+ /* The hardware guarantees us an atomic write, if we
+ * write the low register first. */
+ b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, low);
+ mmiowb();
+ b43_write32(dev, B43_MMIO_REV3PLUS_TSF_HIGH, high);
+ mmiowb();
}
void b43_tsf_write(struct b43_wldev *dev, u64 tsf)
@@ -637,7 +600,7 @@ void b43_tsf_write(struct b43_wldev *dev, u64 tsf)
}
static
-void b43_macfilter_set(struct b43_wldev *dev, u16 offset, const u8 * mac)
+void b43_macfilter_set(struct b43_wldev *dev, u16 offset, const u8 *mac)
{
static const u8 zero_addr[ETH_ALEN] = { 0 };
u16 data;
@@ -827,7 +790,7 @@ void b43_dummy_transmission(struct b43_wldev *dev)
}
static void key_write(struct b43_wldev *dev,
- u8 index, u8 algorithm, const u8 * key)
+ u8 index, u8 algorithm, const u8 *key)
{
unsigned int i;
u32 offset;
@@ -849,7 +812,7 @@ static void key_write(struct b43_wldev *dev,
}
}
-static void keymac_write(struct b43_wldev *dev, u8 index, const u8 * addr)
+static void keymac_write(struct b43_wldev *dev, u8 index, const u8 *addr)
{
u32 addrtmp[2] = { 0, 0, };
u8 per_sta_keys_start = 8;
@@ -899,7 +862,7 @@ static void keymac_write(struct b43_wldev *dev, u8 index, const u8 * addr)
static void do_key_write(struct b43_wldev *dev,
u8 index, u8 algorithm,
- const u8 * key, size_t key_len, const u8 * mac_addr)
+ const u8 *key, size_t key_len, const u8 *mac_addr)
{
u8 buf[B43_SEC_KEYSIZE] = { 0, };
u8 per_sta_keys_start = 8;
@@ -923,8 +886,8 @@ static void do_key_write(struct b43_wldev *dev,
static int b43_key_write(struct b43_wldev *dev,
int index, u8 algorithm,
- const u8 * key, size_t key_len,
- const u8 * mac_addr,
+ const u8 *key, size_t key_len,
+ const u8 *mac_addr,
struct ieee80211_key_conf *keyconf)
{
int i;
@@ -937,8 +900,7 @@ static int b43_key_write(struct b43_wldev *dev,
B43_WARN_ON(dev->key[i].keyconf == keyconf);
}
if (index < 0) {
- /* Either pairwise key or address is 00:00:00:00:00:00
- * for transmit-only keys. Search the index. */
+ /* Pairwise key. Get an empty slot for the key. */
if (b43_new_kidx_api(dev))
sta_keys_start = 4;
else
@@ -951,7 +913,7 @@ static int b43_key_write(struct b43_wldev *dev,
}
}
if (index < 0) {
- b43err(dev->wl, "Out of hardware key memory\n");
+ b43warn(dev->wl, "Out of hardware key memory\n");
return -ENOSPC;
}
} else
@@ -1324,7 +1286,7 @@ static void handle_irq_pmq(struct b43_wldev *dev)
}
static void b43_write_template_common(struct b43_wldev *dev,
- const u8 * data, u16 size,
+ const u8 *data, u16 size,
u16 ram_offset,
u16 shm_size_offset, u8 rate)
{
@@ -1514,9 +1476,9 @@ static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
* 2) Patching duration field
* 3) Stripping TIM
*/
-static const u8 * b43_generate_probe_resp(struct b43_wldev *dev,
- u16 *dest_size,
- struct ieee80211_rate *rate)
+static const u8 *b43_generate_probe_resp(struct b43_wldev *dev,
+ u16 *dest_size,
+ struct ieee80211_rate *rate)
{
const u8 *src_data;
u8 *dest_data;
@@ -1982,7 +1944,7 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
return ret;
}
-static void do_release_fw(struct b43_firmware_file *fw)
+void b43_do_release_fw(struct b43_firmware_file *fw)
{
release_firmware(fw->data);
fw->data = NULL;
@@ -1991,31 +1953,30 @@ static void do_release_fw(struct b43_firmware_file *fw)
static void b43_release_firmware(struct b43_wldev *dev)
{
- do_release_fw(&dev->fw.ucode);
- do_release_fw(&dev->fw.pcm);
- do_release_fw(&dev->fw.initvals);
- do_release_fw(&dev->fw.initvals_band);
+ b43_do_release_fw(&dev->fw.ucode);
+ b43_do_release_fw(&dev->fw.pcm);
+ b43_do_release_fw(&dev->fw.initvals);
+ b43_do_release_fw(&dev->fw.initvals_band);
}
static void b43_print_fw_helptext(struct b43_wl *wl, bool error)
{
- const char *text;
+ const char text[] =
+ "You must go to " \
+ "http://wireless.kernel.org/en/users/Drivers/b43#devicefirmware " \
+ "and download the correct firmware for this driver version. " \
+ "Please carefully read all instructions on this website.\n";
- text = "You must go to "
- "http://linuxwireless.org/en/users/Drivers/b43#devicefirmware "
- "and download the latest firmware (version 4).\n";
if (error)
b43err(wl, text);
else
b43warn(wl, text);
}
-static int do_request_fw(struct b43_wldev *dev,
- const char *name,
- struct b43_firmware_file *fw,
- bool silent)
+int b43_do_request_fw(struct b43_request_fw_context *ctx,
+ const char *name,
+ struct b43_firmware_file *fw)
{
- char path[sizeof(modparam_fwpostfix) + 32];
const struct firmware *blob;
struct b43_fw_header *hdr;
u32 size;
@@ -2023,29 +1984,49 @@ static int do_request_fw(struct b43_wldev *dev,
if (!name) {
/* Don't fetch anything. Free possibly cached firmware. */
- do_release_fw(fw);
+ /* FIXME: We should probably keep it anyway, to save some headache
+ * on suspend/resume with multiband devices. */
+ b43_do_release_fw(fw);
return 0;
}
if (fw->filename) {
- if (strcmp(fw->filename, name) == 0)
+ if ((fw->type == ctx->req_type) &&
+ (strcmp(fw->filename, name) == 0))
return 0; /* Already have this fw. */
/* Free the cached firmware first. */
- do_release_fw(fw);
+ /* FIXME: We should probably do this later after we successfully
+ * got the new fw. This could reduce headache with multiband devices.
+ * We could also redesign this to cache the firmware for all possible
+ * bands all the time. */
+ b43_do_release_fw(fw);
+ }
+
+ switch (ctx->req_type) {
+ case B43_FWTYPE_PROPRIETARY:
+ snprintf(ctx->fwname, sizeof(ctx->fwname),
+ "b43%s/%s.fw",
+ modparam_fwpostfix, name);
+ break;
+ case B43_FWTYPE_OPENSOURCE:
+ snprintf(ctx->fwname, sizeof(ctx->fwname),
+ "b43-open%s/%s.fw",
+ modparam_fwpostfix, name);
+ break;
+ default:
+ B43_WARN_ON(1);
+ return -ENOSYS;
}
-
- snprintf(path, ARRAY_SIZE(path),
- "b43%s/%s.fw",
- modparam_fwpostfix, name);
- err = request_firmware(&blob, path, dev->dev->dev);
+ err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev);
if (err == -ENOENT) {
- if (!silent) {
- b43err(dev->wl, "Firmware file \"%s\" not found\n",
- path);
- }
+ snprintf(ctx->errors[ctx->req_type],
+ sizeof(ctx->errors[ctx->req_type]),
+ "Firmware file \"%s\" not found\n", ctx->fwname);
return err;
} else if (err) {
- b43err(dev->wl, "Firmware file \"%s\" request failed (err=%d)\n",
- path, err);
+ snprintf(ctx->errors[ctx->req_type],
+ sizeof(ctx->errors[ctx->req_type]),
+ "Firmware file \"%s\" request failed (err=%d)\n",
+ ctx->fwname, err);
return err;
}
if (blob->size < sizeof(struct b43_fw_header))
@@ -2068,20 +2049,24 @@ static int do_request_fw(struct b43_wldev *dev,
fw->data = blob;
fw->filename = name;
+ fw->type = ctx->req_type;
return 0;
err_format:
- b43err(dev->wl, "Firmware file \"%s\" format error.\n", path);
+ snprintf(ctx->errors[ctx->req_type],
+ sizeof(ctx->errors[ctx->req_type]),
+ "Firmware file \"%s\" format error.\n", ctx->fwname);
release_firmware(blob);
return -EPROTO;
}
-static int b43_request_firmware(struct b43_wldev *dev)
+static int b43_try_request_fw(struct b43_request_fw_context *ctx)
{
- struct b43_firmware *fw = &dev->fw;
- const u8 rev = dev->dev->id.revision;
+ struct b43_wldev *dev = ctx->dev;
+ struct b43_firmware *fw = &ctx->dev->fw;
+ const u8 rev = ctx->dev->dev->id.revision;
const char *filename;
u32 tmshigh;
int err;
@@ -2096,7 +2081,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
filename = "ucode13";
else
goto err_no_ucode;
- err = do_request_fw(dev, filename, &fw->ucode, 0);
+ err = b43_do_request_fw(ctx, filename, &fw->ucode);
if (err)
goto err_load;
@@ -2108,7 +2093,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
else
goto err_no_pcm;
fw->pcm_request_failed = 0;
- err = do_request_fw(dev, filename, &fw->pcm, 1);
+ err = b43_do_request_fw(ctx, filename, &fw->pcm);
if (err == -ENOENT) {
/* We did not find a PCM file? Not fatal, but
* core rev <= 10 must do without hwcrypto then. */
@@ -2144,7 +2129,7 @@ static int b43_request_firmware(struct b43_wldev *dev)
default:
goto err_no_initvals;
}
- err = do_request_fw(dev, filename, &fw->initvals, 0);
+ err = b43_do_request_fw(ctx, filename, &fw->initvals);
if (err)
goto err_load;
@@ -2178,30 +2163,34 @@ static int b43_request_firmware(struct b43_wldev *dev)
default:
goto err_no_initvals;
}
- err = do_request_fw(dev, filename, &fw->initvals_band, 0);
+ err = b43_do_request_fw(ctx, filename, &fw->initvals_band);
if (err)
goto err_load;
return 0;
-err_load:
- b43_print_fw_helptext(dev->wl, 1);
- goto error;
-
err_no_ucode:
- err = -ENODEV;
- b43err(dev->wl, "No microcode available for core rev %u\n", rev);
+ err = ctx->fatal_failure = -EOPNOTSUPP;
+ b43err(dev->wl, "The driver does not know which firmware (ucode) "
+ "is required for your device (wl-core rev %u)\n", rev);
goto error;
err_no_pcm:
- err = -ENODEV;
- b43err(dev->wl, "No PCM available for core rev %u\n", rev);
+ err = ctx->fatal_failure = -EOPNOTSUPP;
+ b43err(dev->wl, "The driver does not know which firmware (PCM) "
+ "is required for your device (wl-core rev %u)\n", rev);
goto error;
err_no_initvals:
- err = -ENODEV;
- b43err(dev->wl, "No Initial Values firmware file for PHY %u, "
- "core rev %u\n", dev->phy.type, rev);
+ err = ctx->fatal_failure = -EOPNOTSUPP;
+ b43err(dev->wl, "The driver does not know which firmware (initvals) "
+ "is required for your device (wl-core rev %u)\n", rev);
+ goto error;
+
+err_load:
+ /* We failed to load this firmware image. The error message
+ * already is in ctx->errors. Return and let our caller decide
+ * what to do. */
goto error;
error:
@@ -2209,6 +2198,48 @@ error:
return err;
}
+static int b43_request_firmware(struct b43_wldev *dev)
+{
+ struct b43_request_fw_context *ctx;
+ unsigned int i;
+ int err;
+ const char *errmsg;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+ ctx->dev = dev;
+
+ ctx->req_type = B43_FWTYPE_PROPRIETARY;
+ err = b43_try_request_fw(ctx);
+ if (!err)
+ goto out; /* Successfully loaded it. */
+ err = ctx->fatal_failure;
+ if (err)
+ goto out;
+
+ ctx->req_type = B43_FWTYPE_OPENSOURCE;
+ err = b43_try_request_fw(ctx);
+ if (!err)
+ goto out; /* Successfully loaded it. */
+ err = ctx->fatal_failure;
+ if (err)
+ goto out;
+
+ /* Could not find a usable firmware. Print the errors. */
+ for (i = 0; i < B43_NR_FWTYPES; i++) {
+ errmsg = ctx->errors[i];
+ if (strlen(errmsg))
+ b43err(dev->wl, errmsg);
+ }
+ b43_print_fw_helptext(dev->wl, 1);
+ err = -ENOENT;
+
+out:
+ kfree(ctx);
+ return err;
+}
+
static int b43_upload_microcode(struct b43_wldev *dev)
{
const size_t hdr_len = sizeof(struct b43_fw_header);
@@ -2319,8 +2350,11 @@ static int b43_upload_microcode(struct b43_wldev *dev)
}
if (b43_is_old_txhdr_format(dev)) {
+ /* We're over the deadline, but we keep support for old fw
+ * until it turns out to be in major conflict with something new. */
b43warn(dev->wl, "You are using an old firmware image. "
- "Support for old firmware will be removed in July 2008.\n");
+ "Support for old firmware will be removed soon "
+ "(official deadline was July 2008).\n");
b43_print_fw_helptext(dev->wl, 0);
}
@@ -2946,7 +2980,7 @@ static void b43_security_init(struct b43_wldev *dev)
b43_clear_keys(dev);
}
-static int b43_rng_read(struct hwrng *rng, u32 * data)
+static int b43_rng_read(struct hwrng *rng, u32 *data)
{
struct b43_wl *wl = (struct b43_wl *)rng->priv;
unsigned long flags;
@@ -3221,6 +3255,43 @@ static int b43_op_get_stats(struct ieee80211_hw *hw,
return 0;
}
+static u64 b43_op_get_tsf(struct ieee80211_hw *hw)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev;
+ u64 tsf;
+
+ mutex_lock(&wl->mutex);
+ spin_lock_irq(&wl->irq_lock);
+ dev = wl->current_dev;
+
+ if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
+ b43_tsf_read(dev, &tsf);
+ else
+ tsf = 0;
+
+ spin_unlock_irq(&wl->irq_lock);
+ mutex_unlock(&wl->mutex);
+
+ return tsf;
+}
+
+static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev;
+
+ mutex_lock(&wl->mutex);
+ spin_lock_irq(&wl->irq_lock);
+ dev = wl->current_dev;
+
+ if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
+ b43_tsf_write(dev, tsf);
+
+ spin_unlock_irq(&wl->irq_lock);
+ mutex_unlock(&wl->mutex);
+}
+
static void b43_put_phy_into_reset(struct b43_wldev *dev)
{
struct ssb_device *sdev = dev->dev;
@@ -3240,7 +3311,7 @@ static void b43_put_phy_into_reset(struct b43_wldev *dev)
msleep(1);
}
-static const char * band_to_string(enum ieee80211_band band)
+static const char *band_to_string(enum ieee80211_band band)
{
switch (band) {
case IEEE80211_BAND_5GHZ:
@@ -3442,7 +3513,7 @@ out_unlock_mutex:
return err;
}
-static void b43_update_basic_rates(struct b43_wldev *dev, u64 brates)
+static void b43_update_basic_rates(struct b43_wldev *dev, u32 brates)
{
struct ieee80211_supported_band *sband =
dev->wl->hw->wiphy->bands[b43_current_band(dev->wl)];
@@ -3520,21 +3591,29 @@ out_unlock_mutex:
}
static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_addr, const u8 *addr,
- struct ieee80211_key_conf *key)
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
- unsigned long flags;
u8 algorithm;
u8 index;
int err;
+ static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
if (modparam_nohwcrypt)
return -ENOSPC; /* User disabled HW-crypto */
mutex_lock(&wl->mutex);
- spin_lock_irqsave(&wl->irq_lock, flags);
+ spin_lock_irq(&wl->irq_lock);
+ write_lock(&wl->tx_lock);
+ /* Why do we need all this locking here?
+ * mutex -> Every config operation must take it.
+ * irq_lock -> We modify the dev->key array, which is accessed
+ * in the IRQ handlers.
+ * tx_lock -> We modify the dev->key array, which is accessed
+ * in the TX handler.
+ */
dev = wl->current_dev;
err = -ENODEV;
@@ -3551,7 +3630,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
err = -EINVAL;
switch (key->alg) {
case ALG_WEP:
- if (key->keylen == 5)
+ if (key->keylen == LEN_WEP40)
algorithm = B43_SEC_ALGO_WEP40;
else
algorithm = B43_SEC_ALGO_WEP104;
@@ -3578,17 +3657,19 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
goto out_unlock;
}
- if (is_broadcast_ether_addr(addr)) {
- /* addr is FF:FF:FF:FF:FF:FF for default keys */
+ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+ if (WARN_ON(!sta)) {
+ err = -EOPNOTSUPP;
+ goto out_unlock;
+ }
+ /* Pairwise key with an assigned MAC address. */
+ err = b43_key_write(dev, -1, algorithm,
+ key->key, key->keylen,
+ sta->addr, key);
+ } else {
+ /* Group key */
err = b43_key_write(dev, index, algorithm,
key->key, key->keylen, NULL, key);
- } else {
- /*
- * either pairwise key or address is 00:00:00:00:00:00
- * for transmit-only keys
- */
- err = b43_key_write(dev, -1, algorithm,
- key->key, key->keylen, addr, key);
}
if (err)
goto out_unlock;
@@ -3617,10 +3698,11 @@ out_unlock:
b43dbg(wl, "%s hardware based encryption for keyidx: %d, "
"mac: %pM\n",
cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
- addr);
+ sta ? sta->addr : bcast_addr);
b43_dump_keymemory(dev);
}
- spin_unlock_irqrestore(&wl->irq_lock, flags);
+ write_unlock(&wl->tx_lock);
+ spin_unlock_irq(&wl->irq_lock);
mutex_unlock(&wl->mutex);
return err;
@@ -3796,6 +3878,12 @@ static int b43_phy_versioning(struct b43_wldev *dev)
break;
#ifdef CONFIG_B43_NPHY
case B43_PHYTYPE_N:
+ if (phy_rev > 4)
+ unsupported = 1;
+ break;
+#endif
+#ifdef CONFIG_B43_PHY_LP
+ case B43_PHYTYPE_LP:
if (phy_rev > 1)
unsupported = 1;
break;
@@ -3849,7 +3937,11 @@ static int b43_phy_versioning(struct b43_wldev *dev)
unsupported = 1;
break;
case B43_PHYTYPE_N:
- if (radio_ver != 0x2055)
+ if (radio_ver != 0x2055 && radio_ver != 0x2056)
+ unsupported = 1;
+ break;
+ case B43_PHYTYPE_LP:
+ if (radio_ver != 0x2062)
unsupported = 1;
break;
default:
@@ -3901,6 +3993,8 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev)
dev->irq_reason = 0;
memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
dev->irq_savedstate = B43_IRQ_MASKTEMPLATE;
+ if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
+ dev->irq_savedstate &= ~B43_IRQ_PHY_TXERR;
dev->mac_suspended = 1;
@@ -4078,11 +4172,21 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
hf |= B43_HF_GDCW;
if (sprom->boardflags_lo & B43_BFL_PACTRL)
hf |= B43_HF_OFDMPABOOST;
- } else if (phy->type == B43_PHYTYPE_B) {
- hf |= B43_HF_SYMW;
- if (phy->rev >= 2 && phy->radio_ver == 0x2050)
- hf &= ~B43_HF_GDCW;
}
+ if (phy->radio_ver == 0x2050) {
+ if (phy->radio_rev == 6)
+ hf |= B43_HF_4318TSSI;
+ if (phy->radio_rev < 6)
+ hf |= B43_HF_VCORECALC;
+ }
+ if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
+ hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
+#ifdef CONFIG_SSB_DRIVER_PCICORE
+ if ((bus->bustype == SSB_BUSTYPE_PCI) &&
+ (bus->pcicore.dev->id.revision <= 10))
+ hf |= B43_HF_PCISCW; /* PCI slow clock workaround. */
+#endif
+ hf &= ~B43_HF_SKCFPUP;
b43_hf_write(dev, hf);
b43_set_retry_limits(dev, B43_DEFAULT_SHORT_RETRY_LIMIT,
@@ -4121,7 +4225,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
b43_set_synth_pu_delay(dev, 1);
b43_bluetooth_coext_enable(dev);
- ssb_bus_powerup(bus, 1); /* Enable dynamic PCTL */
+ ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW));
b43_upload_card_macaddress(dev);
b43_security_init(dev);
if (!dev->suspend_in_progress)
@@ -4305,6 +4409,34 @@ static void b43_op_sta_notify(struct ieee80211_hw *hw,
B43_WARN_ON(!vif || wl->vif != vif);
}
+static void b43_op_sw_scan_start_notifier(struct ieee80211_hw *hw)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev;
+
+ mutex_lock(&wl->mutex);
+ dev = wl->current_dev;
+ if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) {
+ /* Disable CFP update during scan on other channels. */
+ b43_hf_write(dev, b43_hf_read(dev) | B43_HF_SKCFPUP);
+ }
+ mutex_unlock(&wl->mutex);
+}
+
+static void b43_op_sw_scan_complete_notifier(struct ieee80211_hw *hw)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev;
+
+ mutex_lock(&wl->mutex);
+ dev = wl->current_dev;
+ if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) {
+ /* Re-enable CFP update. */
+ b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_SKCFPUP);
+ }
+ mutex_unlock(&wl->mutex);
+}
+
static const struct ieee80211_ops b43_hw_ops = {
.tx = b43_op_tx,
.conf_tx = b43_op_conf_tx,
@@ -4317,10 +4449,14 @@ static const struct ieee80211_ops b43_hw_ops = {
.set_key = b43_op_set_key,
.get_stats = b43_op_get_stats,
.get_tx_stats = b43_op_get_tx_stats,
+ .get_tsf = b43_op_get_tsf,
+ .set_tsf = b43_op_set_tsf,
.start = b43_op_start,
.stop = b43_op_stop,
.set_tim = b43_op_beacon_set_tim,
.sta_notify = b43_op_sta_notify,
+ .sw_scan_start = b43_op_sw_scan_start_notifier,
+ .sw_scan_complete = b43_op_sw_scan_complete_notifier,
};
/* Hard-reset the chip. Do not call this directly.
@@ -4446,6 +4582,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
break;
case B43_PHYTYPE_G:
case B43_PHYTYPE_N:
+ case B43_PHYTYPE_LP:
have_2ghz_phy = 1;
break;
default:
@@ -4657,9 +4794,10 @@ static int b43_wireless_init(struct ssb_device *dev)
INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
ssb_set_devtypedata(dev, wl);
- b43info(wl, "Broadcom %04X WLAN found\n", dev->bus->chip_id);
+ b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n",
+ dev->bus->chip_id, dev->id.revision);
err = 0;
- out:
+out:
return err;
}
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index f871a252cb55..40abcf5d1b43 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -40,6 +40,24 @@
extern int b43_modparam_qos;
+extern int b43_modparam_verbose;
+
+/* Logmessage verbosity levels. Update the b43_modparam_verbose helptext, if
+ * you add or remove levels. */
+enum b43_verbosity {
+ B43_VERBOSITY_ERROR,
+ B43_VERBOSITY_WARN,
+ B43_VERBOSITY_INFO,
+ B43_VERBOSITY_DEBUG,
+ __B43_VERBOSITY_AFTERLAST, /* keep last */
+
+ B43_VERBOSITY_MAX = __B43_VERBOSITY_AFTERLAST - 1,
+#if B43_DEBUG
+ B43_VERBOSITY_DEFAULT = B43_VERBOSITY_DEBUG,
+#else
+ B43_VERBOSITY_DEFAULT = B43_VERBOSITY_INFO,
+#endif
+};
/* Lightweight function to convert a frequency (in Mhz) to a channel number. */
@@ -121,4 +139,11 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags);
void b43_mac_suspend(struct b43_wldev *dev);
void b43_mac_enable(struct b43_wldev *dev);
+
+struct b43_request_fw_context;
+int b43_do_request_fw(struct b43_request_fw_context *ctx,
+ const char *name,
+ struct b43_firmware_file *fw);
+void b43_do_release_fw(struct b43_firmware_file *fw);
+
#endif /* B43_MAIN_H_ */
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index 7fe9d1701624..c836c077d51d 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -121,27 +121,18 @@ static void aphy_channel_switch(struct b43_wldev *dev, unsigned int channel)
b43_radio_write16(dev, 0x0007, (r8 << 4) | r8);
b43_radio_write16(dev, 0x0020, (r8 << 4) | r8);
b43_radio_write16(dev, 0x0021, (r8 << 4) | r8);
- b43_radio_write16(dev, 0x0022, (b43_radio_read16(dev, 0x0022)
- & 0x000F) | (r8 << 4));
+ b43_radio_maskset(dev, 0x0022, 0x000F, (r8 << 4));
b43_radio_write16(dev, 0x002A, (r8 << 4));
b43_radio_write16(dev, 0x002B, (r8 << 4));
- b43_radio_write16(dev, 0x0008, (b43_radio_read16(dev, 0x0008)
- & 0x00F0) | (r8 << 4));
- b43_radio_write16(dev, 0x0029, (b43_radio_read16(dev, 0x0029)
- & 0xFF0F) | 0x00B0);
+ b43_radio_maskset(dev, 0x0008, 0x00F0, (r8 << 4));
+ b43_radio_maskset(dev, 0x0029, 0xFF0F, 0x00B0);
b43_radio_write16(dev, 0x0035, 0x00AA);
b43_radio_write16(dev, 0x0036, 0x0085);
- b43_radio_write16(dev, 0x003A, (b43_radio_read16(dev, 0x003A)
- & 0xFF20) |
- freq_r3A_value(freq));
- b43_radio_write16(dev, 0x003D,
- b43_radio_read16(dev, 0x003D) & 0x00FF);
- b43_radio_write16(dev, 0x0081, (b43_radio_read16(dev, 0x0081)
- & 0xFF7F) | 0x0080);
- b43_radio_write16(dev, 0x0035,
- b43_radio_read16(dev, 0x0035) & 0xFFEF);
- b43_radio_write16(dev, 0x0035, (b43_radio_read16(dev, 0x0035)
- & 0xFFEF) | 0x0010);
+ b43_radio_maskset(dev, 0x003A, 0xFF20, freq_r3A_value(freq));
+ b43_radio_mask(dev, 0x003D, 0x00FF);
+ b43_radio_maskset(dev, 0x0081, 0xFF7F, 0x0080);
+ b43_radio_mask(dev, 0x0035, 0xFFEF);
+ b43_radio_maskset(dev, 0x0035, 0xFFEF, 0x0010);
b43_radio_set_tx_iq(dev);
//TODO: TSSI2dbm workaround
//FIXME b43_phy_xmitpower(dev);
@@ -160,23 +151,20 @@ static void b43_radio_init2060(struct b43_wldev *dev)
b43_radio_write16(dev, 0x0082, 0x0080);
b43_radio_write16(dev, 0x0080, 0x0000);
b43_radio_write16(dev, 0x003F, 0x00DA);
- b43_radio_write16(dev, 0x0005, b43_radio_read16(dev, 0x0005) & ~0x0008);
- b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0010);
- b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0020);
- b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0020);
+ b43_radio_mask(dev, 0x0005, ~0x0008);
+ b43_radio_mask(dev, 0x0081, ~0x0010);
+ b43_radio_mask(dev, 0x0081, ~0x0020);
+ b43_radio_mask(dev, 0x0081, ~0x0020);
msleep(1); /* delay 400usec */
- b43_radio_write16(dev, 0x0081,
- (b43_radio_read16(dev, 0x0081) & ~0x0020) | 0x0010);
+ b43_radio_maskset(dev, 0x0081, ~0x0020, 0x0010);
msleep(1); /* delay 400usec */
- b43_radio_write16(dev, 0x0005,
- (b43_radio_read16(dev, 0x0005) & ~0x0008) | 0x0008);
- b43_radio_write16(dev, 0x0085, b43_radio_read16(dev, 0x0085) & ~0x0010);
- b43_radio_write16(dev, 0x0005, b43_radio_read16(dev, 0x0005) & ~0x0008);
- b43_radio_write16(dev, 0x0081, b43_radio_read16(dev, 0x0081) & ~0x0040);
- b43_radio_write16(dev, 0x0081,
- (b43_radio_read16(dev, 0x0081) & ~0x0040) | 0x0040);
+ b43_radio_maskset(dev, 0x0005, ~0x0008, 0x0008);
+ b43_radio_mask(dev, 0x0085, ~0x0010);
+ b43_radio_mask(dev, 0x0005, ~0x0008);
+ b43_radio_mask(dev, 0x0081, ~0x0040);
+ b43_radio_maskset(dev, 0x0081, ~0x0040, 0x0040);
b43_radio_write16(dev, 0x0005,
(b43_radio_read16(dev, 0x0081) & ~0x0008) | 0x0008);
b43_phy_write(dev, 0x0063, 0xDDC6);
@@ -224,22 +212,16 @@ static void b43_phy_ww(struct b43_wldev *dev)
u16 b, curr_s, best_s = 0xFFFF;
int i;
- b43_phy_write(dev, B43_PHY_CRS0,
- b43_phy_read(dev, B43_PHY_CRS0) & ~B43_PHY_CRS0_EN);
- b43_phy_write(dev, B43_PHY_OFDM(0x1B),
- b43_phy_read(dev, B43_PHY_OFDM(0x1B)) | 0x1000);
- b43_phy_write(dev, B43_PHY_OFDM(0x82),
- (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & 0xF0FF) | 0x0300);
- b43_radio_write16(dev, 0x0009,
- b43_radio_read16(dev, 0x0009) | 0x0080);
- b43_radio_write16(dev, 0x0012,
- (b43_radio_read16(dev, 0x0012) & 0xFFFC) | 0x0002);
+ b43_phy_mask(dev, B43_PHY_CRS0, ~B43_PHY_CRS0_EN);
+ b43_phy_set(dev, B43_PHY_OFDM(0x1B), 0x1000);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x82), 0xF0FF, 0x0300);
+ b43_radio_set(dev, 0x0009, 0x0080);
+ b43_radio_maskset(dev, 0x0012, 0xFFFC, 0x0002);
b43_wa_initgains(dev);
b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5);
b = b43_phy_read(dev, B43_PHY_PWRDOWN);
b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005);
- b43_radio_write16(dev, 0x0004,
- b43_radio_read16(dev, 0x0004) | 0x0004);
+ b43_radio_set(dev, 0x0004, 0x0004);
for (i = 0x10; i <= 0x20; i++) {
b43_radio_write16(dev, 0x0013, i);
curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF;
@@ -252,8 +234,7 @@ static void b43_phy_ww(struct b43_wldev *dev)
best_s = curr_s;
}
b43_phy_write(dev, B43_PHY_PWRDOWN, b);
- b43_radio_write16(dev, 0x0004,
- b43_radio_read16(dev, 0x0004) & 0xFFFB);
+ b43_radio_mask(dev, 0x0004, 0xFFFB);
b43_radio_write16(dev, 0x0013, best_s);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC);
b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80);
@@ -261,14 +242,10 @@ static void b43_phy_ww(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_OFDM(0xB5), 0x0EC0);
b43_phy_write(dev, B43_PHY_OFDM(0xB2), 0x00C0);
b43_phy_write(dev, B43_PHY_OFDM(0xB9), 0x1FFF);
- b43_phy_write(dev, B43_PHY_OFDM(0xBB),
- (b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053);
- b43_phy_write(dev, B43_PHY_OFDM61,
- (b43_phy_read(dev, B43_PHY_OFDM61) & 0xFE1F) | 0x0120);
- b43_phy_write(dev, B43_PHY_OFDM(0x13),
- (b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000);
- b43_phy_write(dev, B43_PHY_OFDM(0x14),
- (b43_phy_read(dev, B43_PHY_OFDM(0x14)) & 0x0FFF) | 0x3000);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xBB), 0xF000, 0x0053);
+ b43_phy_maskset(dev, B43_PHY_OFDM61, 0xFE1F, 0x0120);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x13), 0x0FFF, 0x3000);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x14), 0x0FFF, 0x3000);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017);
for (i = 0; i < 6; i++)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F);
@@ -276,8 +253,7 @@ static void b43_phy_ww(struct b43_wldev *dev)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0E, 0x0011);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0F, 0x0013);
b43_phy_write(dev, B43_PHY_OFDM(0x33), 0x5030);
- b43_phy_write(dev, B43_PHY_CRS0,
- b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
+ b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN);
}
static void hardware_pctl_init_aphy(struct b43_wldev *dev)
@@ -300,26 +276,21 @@ void b43_phy_inita(struct b43_wldev *dev)
if (phy->rev >= 6) {
if (phy->type == B43_PHYTYPE_A)
- b43_phy_write(dev, B43_PHY_OFDM(0x1B),
- b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x1000);
+ b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x1000);
if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
- b43_phy_write(dev, B43_PHY_ENCORE,
- b43_phy_read(dev, B43_PHY_ENCORE) | 0x0010);
+ b43_phy_set(dev, B43_PHY_ENCORE, 0x0010);
else
- b43_phy_write(dev, B43_PHY_ENCORE,
- b43_phy_read(dev, B43_PHY_ENCORE) & ~0x1010);
+ b43_phy_mask(dev, B43_PHY_ENCORE, ~0x1010);
}
b43_wa_all(dev);
if (phy->type == B43_PHYTYPE_A) {
if (phy->gmode && (phy->rev < 3))
- b43_phy_write(dev, 0x0034,
- b43_phy_read(dev, 0x0034) | 0x0001);
+ b43_phy_set(dev, 0x0034, 0x0001);
b43_phy_rssiagc(dev, 0);
- b43_phy_write(dev, B43_PHY_CRS0,
- b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
+ b43_phy_set(dev, B43_PHY_CRS0, B43_PHY_CRS0_EN);
b43_radio_init2060(dev);
@@ -339,9 +310,7 @@ void b43_phy_inita(struct b43_wldev *dev)
if ((phy->type == B43_PHYTYPE_G) &&
(dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) {
- b43_phy_write(dev, B43_PHY_OFDM(0x6E),
- (b43_phy_read(dev, B43_PHY_OFDM(0x6E))
- & 0xE000) | 0x3CF);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF);
}
}
@@ -520,14 +489,14 @@ static void b43_aphy_op_software_rfkill(struct b43_wldev *dev,
return;
b43_radio_write16(dev, 0x0004, 0x00C0);
b43_radio_write16(dev, 0x0005, 0x0008);
- b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) & 0xFFF7);
- b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) & 0xFFF7);
+ b43_phy_mask(dev, 0x0010, 0xFFF7);
+ b43_phy_mask(dev, 0x0011, 0xFFF7);
b43_radio_init2060(dev);
} else {
b43_radio_write16(dev, 0x0004, 0x00FF);
b43_radio_write16(dev, 0x0005, 0x00FB);
- b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) | 0x0008);
- b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) | 0x0008);
+ b43_phy_set(dev, 0x0010, 0x0008);
+ b43_phy_set(dev, 0x0011, 0x0008);
}
}
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index caac4a45f0bf..e7b98f013b0f 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -204,13 +204,9 @@ void b43_gphy_set_baseband_attenuation(struct b43_wldev *dev,
& 0xFFF0) |
baseband_attenuation);
} else if (phy->analog > 1) {
- b43_phy_write(dev, B43_PHY_DACCTL,
- (b43_phy_read(dev, B43_PHY_DACCTL)
- & 0xFFC3) | (baseband_attenuation << 2));
+ b43_phy_maskset(dev, B43_PHY_DACCTL, 0xFFC3, (baseband_attenuation << 2));
} else {
- b43_phy_write(dev, B43_PHY_DACCTL,
- (b43_phy_read(dev, B43_PHY_DACCTL)
- & 0xFF87) | (baseband_attenuation << 3));
+ b43_phy_maskset(dev, B43_PHY_DACCTL, 0xFF87, (baseband_attenuation << 3));
}
}
@@ -252,17 +248,13 @@ static void b43_set_txpower_g(struct b43_wldev *dev,
b43_radio_write16(dev, 0x43,
(rf & 0x000F) | (tx_control & 0x0070));
} else {
- b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
- & 0xFFF0) | (rf & 0x000F));
- b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
- & ~0x0070) | (tx_control &
- 0x0070));
+ b43_radio_maskset(dev, 0x43, 0xFFF0, (rf & 0x000F));
+ b43_radio_maskset(dev, 0x52, ~0x0070, (tx_control & 0x0070));
}
if (has_tx_magnification(phy)) {
b43_radio_write16(dev, 0x52, tx_magn | tx_bias);
} else {
- b43_radio_write16(dev, 0x52, (b43_radio_read16(dev, 0x52)
- & 0xFFF0) | (tx_bias & 0x000F));
+ b43_radio_maskset(dev, 0x52, 0xFFF0, (tx_bias & 0x000F));
}
b43_lo_g_adjust(dev);
}
@@ -337,12 +329,9 @@ static void b43_set_all_gains(struct b43_wldev *dev,
if (third != -1) {
tmp = ((u16) third << 14) | ((u16) third << 6);
- b43_phy_write(dev, 0x04A0,
- (b43_phy_read(dev, 0x04A0) & 0xBFBF) | tmp);
- b43_phy_write(dev, 0x04A1,
- (b43_phy_read(dev, 0x04A1) & 0xBFBF) | tmp);
- b43_phy_write(dev, 0x04A2,
- (b43_phy_read(dev, 0x04A2) & 0xBFBF) | tmp);
+ b43_phy_maskset(dev, 0x04A0, 0xBFBF, tmp);
+ b43_phy_maskset(dev, 0x04A1, 0xBFBF, tmp);
+ b43_phy_maskset(dev, 0x04A2, 0xBFBF, tmp);
}
b43_dummy_transmission(dev);
}
@@ -373,12 +362,9 @@ static void b43_set_original_gains(struct b43_wldev *dev)
for (i = start; i < end; i++)
b43_ofdmtab_write16(dev, table, i, i - start);
- b43_phy_write(dev, 0x04A0,
- (b43_phy_read(dev, 0x04A0) & 0xBFBF) | 0x4040);
- b43_phy_write(dev, 0x04A1,
- (b43_phy_read(dev, 0x04A1) & 0xBFBF) | 0x4040);
- b43_phy_write(dev, 0x04A2,
- (b43_phy_read(dev, 0x04A2) & 0xBFBF) | 0x4000);
+ b43_phy_maskset(dev, 0x04A0, 0xBFBF, 0x4040);
+ b43_phy_maskset(dev, 0x04A1, 0xBFBF, 0x4040);
+ b43_phy_maskset(dev, 0x04A2, 0xBFBF, 0x4000);
b43_dummy_transmission(dev);
}
@@ -454,13 +440,11 @@ static void b43_calc_nrssi_offset(struct b43_wldev *dev)
backup[10] = b43_radio_read16(dev, 0x007A);
backup[11] = b43_radio_read16(dev, 0x0043);
- b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) & 0x7FFF);
- b43_phy_write(dev, 0x0001,
- (b43_phy_read(dev, 0x0001) & 0x3FFF) | 0x4000);
- b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
- b43_phy_write(dev, 0x0812,
- (b43_phy_read(dev, 0x0812) & 0xFFF3) | 0x0004);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & ~(0x1 | 0x2));
+ b43_phy_mask(dev, 0x0429, 0x7FFF);
+ b43_phy_maskset(dev, 0x0001, 0x3FFF, 0x4000);
+ b43_phy_set(dev, 0x0811, 0x000C);
+ b43_phy_maskset(dev, 0x0812, 0xFFF3, 0x0004);
+ b43_phy_mask(dev, 0x0802, ~(0x1 | 0x2));
if (phy->rev >= 6) {
backup[12] = b43_phy_read(dev, 0x002E);
backup[13] = b43_phy_read(dev, 0x002F);
@@ -475,13 +459,13 @@ static void b43_calc_nrssi_offset(struct b43_wldev *dev)
b43_phy_write(dev, 0x002F, 0);
b43_phy_write(dev, 0x080F, 0);
b43_phy_write(dev, 0x0810, 0);
- b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478) | 0x0100);
- b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801) | 0x0040);
- b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) | 0x0040);
- b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014) | 0x0200);
+ b43_phy_set(dev, 0x0478, 0x0100);
+ b43_phy_set(dev, 0x0801, 0x0040);
+ b43_phy_set(dev, 0x0060, 0x0040);
+ b43_phy_set(dev, 0x0014, 0x0200);
}
- b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0070);
- b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0080);
+ b43_radio_set(dev, 0x007A, 0x0070);
+ b43_radio_set(dev, 0x007A, 0x0080);
udelay(30);
v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
@@ -501,40 +485,31 @@ static void b43_calc_nrssi_offset(struct b43_wldev *dev)
if (saved == 0xFFFF)
saved = 4;
} else {
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) & 0x007F);
+ b43_radio_mask(dev, 0x007A, 0x007F);
if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
- b43_phy_write(dev, 0x0814,
- b43_phy_read(dev, 0x0814) | 0x0001);
- b43_phy_write(dev, 0x0815,
- b43_phy_read(dev, 0x0815) & 0xFFFE);
+ b43_phy_set(dev, 0x0814, 0x0001);
+ b43_phy_mask(dev, 0x0815, 0xFFFE);
}
- b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x000C);
- b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x000C);
- b43_phy_write(dev, 0x0811, b43_phy_read(dev, 0x0811) | 0x0030);
- b43_phy_write(dev, 0x0812, b43_phy_read(dev, 0x0812) | 0x0030);
+ b43_phy_set(dev, 0x0811, 0x000C);
+ b43_phy_set(dev, 0x0812, 0x000C);
+ b43_phy_set(dev, 0x0811, 0x0030);
+ b43_phy_set(dev, 0x0812, 0x0030);
b43_phy_write(dev, 0x005A, 0x0480);
b43_phy_write(dev, 0x0059, 0x0810);
b43_phy_write(dev, 0x0058, 0x000D);
if (phy->rev == 0) {
b43_phy_write(dev, 0x0003, 0x0122);
} else {
- b43_phy_write(dev, 0x000A, b43_phy_read(dev, 0x000A)
- | 0x2000);
+ b43_phy_set(dev, 0x000A, 0x2000);
}
if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
- b43_phy_write(dev, 0x0814,
- b43_phy_read(dev, 0x0814) | 0x0004);
- b43_phy_write(dev, 0x0815,
- b43_phy_read(dev, 0x0815) & 0xFFFB);
+ b43_phy_set(dev, 0x0814, 0x0004);
+ b43_phy_mask(dev, 0x0815, 0xFFFB);
}
- b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003) & 0xFF9F)
- | 0x0040);
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x000F);
+ b43_phy_maskset(dev, 0x0003, 0xFF9F, 0x0040);
+ b43_radio_set(dev, 0x007A, 0x000F);
b43_set_all_gains(dev, 3, 0, 1);
- b43_radio_write16(dev, 0x0043, (b43_radio_read16(dev, 0x0043)
- & 0x00F0) | 0x000F);
+ b43_radio_maskset(dev, 0x0043, 0x00F0, 0x000F);
udelay(30);
v47F = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
if (v47F >= 0x20)
@@ -576,7 +551,7 @@ static void b43_calc_nrssi_offset(struct b43_wldev *dev)
b43_radio_write16(dev, 0x0043, backup[11]);
b43_radio_write16(dev, 0x007A, backup[10]);
b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x1 | 0x2);
- b43_phy_write(dev, 0x0429, b43_phy_read(dev, 0x0429) | 0x8000);
+ b43_phy_set(dev, 0x0429, 0x8000);
b43_set_original_gains(dev);
if (phy->rev >= 6) {
b43_phy_write(dev, 0x0801, backup[16]);
@@ -604,9 +579,8 @@ static void b43_calc_nrssi_slope(struct b43_wldev *dev)
if (phy->radio_rev == 8)
b43_calc_nrssi_offset(dev);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_G_CRS, 0x7FFF);
+ b43_phy_mask(dev, 0x0802, 0xFFFC);
backup[7] = b43_read16(dev, 0x03E2);
b43_write16(dev, 0x03E2, b43_read16(dev, 0x03E2) | 0x8000);
backup[0] = b43_radio_read16(dev, 0x007A);
@@ -633,66 +607,44 @@ static void b43_calc_nrssi_slope(struct b43_wldev *dev)
case 4:
case 6:
case 7:
- b43_phy_write(dev, 0x0478,
- b43_phy_read(dev, 0x0478)
- | 0x0100);
- b43_phy_write(dev, 0x0801,
- b43_phy_read(dev, 0x0801)
- | 0x0040);
+ b43_phy_set(dev, 0x0478, 0x0100);
+ b43_phy_set(dev, 0x0801, 0x0040);
break;
case 3:
case 5:
- b43_phy_write(dev, 0x0801,
- b43_phy_read(dev, 0x0801)
- & 0xFFBF);
+ b43_phy_mask(dev, 0x0801, 0xFFBF);
break;
}
- b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060)
- | 0x0040);
- b43_phy_write(dev, 0x0014, b43_phy_read(dev, 0x0014)
- | 0x0200);
+ b43_phy_set(dev, 0x0060, 0x0040);
+ b43_phy_set(dev, 0x0014, 0x0200);
}
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x0070);
+ b43_radio_set(dev, 0x007A, 0x0070);
b43_set_all_gains(dev, 0, 8, 0);
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) & 0x00F7);
+ b43_radio_mask(dev, 0x007A, 0x00F7);
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x0811,
- (b43_phy_read(dev, 0x0811) & 0xFFCF) |
- 0x0030);
- b43_phy_write(dev, 0x0812,
- (b43_phy_read(dev, 0x0812) & 0xFFCF) |
- 0x0010);
+ b43_phy_maskset(dev, 0x0811, 0xFFCF, 0x0030);
+ b43_phy_maskset(dev, 0x0812, 0xFFCF, 0x0010);
}
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x0080);
+ b43_radio_set(dev, 0x007A, 0x0080);
udelay(20);
nrssi0 = (s16) ((b43_phy_read(dev, 0x047F) >> 8) & 0x003F);
if (nrssi0 >= 0x0020)
nrssi0 -= 0x0040;
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) & 0x007F);
+ b43_radio_mask(dev, 0x007A, 0x007F);
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x0003, (b43_phy_read(dev, 0x0003)
- & 0xFF9F) | 0x0040);
+ b43_phy_maskset(dev, 0x0003, 0xFF9F, 0x0040);
}
b43_write16(dev, B43_MMIO_CHANNEL_EXT,
b43_read16(dev, B43_MMIO_CHANNEL_EXT)
| 0x2000);
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x000F);
+ b43_radio_set(dev, 0x007A, 0x000F);
b43_phy_write(dev, 0x0015, 0xF330);
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x0812,
- (b43_phy_read(dev, 0x0812) & 0xFFCF) |
- 0x0020);
- b43_phy_write(dev, 0x0811,
- (b43_phy_read(dev, 0x0811) & 0xFFCF) |
- 0x0020);
+ b43_phy_maskset(dev, 0x0812, 0xFFCF, 0x0020);
+ b43_phy_maskset(dev, 0x0811, 0xFFCF, 0x0020);
}
b43_set_all_gains(dev, 3, 0, 1);
@@ -726,10 +678,8 @@ static void b43_calc_nrssi_slope(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_G_LO_CONTROL, backup[13]);
}
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x0812,
- b43_phy_read(dev, 0x0812) & 0xFFCF);
- b43_phy_write(dev, 0x0811,
- b43_phy_read(dev, 0x0811) & 0xFFCF);
+ b43_phy_mask(dev, 0x0812, 0xFFCF);
+ b43_phy_mask(dev, 0x0811, 0xFFCF);
}
b43_radio_write16(dev, 0x007A, backup[0]);
@@ -743,11 +693,9 @@ static void b43_calc_nrssi_slope(struct b43_wldev *dev)
b43_phy_write(dev, 0x0059, backup[5]);
b43_phy_write(dev, 0x0058, backup[6]);
b43_synth_pu_workaround(dev, phy->channel);
- b43_phy_write(dev, 0x0802,
- b43_phy_read(dev, 0x0802) | (0x0001 | 0x0002));
+ b43_phy_set(dev, 0x0802, (0x0001 | 0x0002));
b43_set_original_gains(dev);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
+ b43_phy_set(dev, B43_PHY_G_CRS, 0x8000);
if (phy->rev >= 3) {
b43_phy_write(dev, 0x0801, backup[14]);
b43_phy_write(dev, 0x0060, backup[15]);
@@ -774,13 +722,9 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev)
if (tmp16 >= 0x20)
tmp16 -= 0x40;
if (tmp16 < 3) {
- b43_phy_write(dev, 0x048A,
- (b43_phy_read(dev, 0x048A)
- & 0xF000) | 0x09EB);
+ b43_phy_maskset(dev, 0x048A, 0xF000, 0x09EB);
} else {
- b43_phy_write(dev, 0x048A,
- (b43_phy_read(dev, 0x048A)
- & 0xF000) | 0x0AED);
+ b43_phy_maskset(dev, 0x048A, 0xF000, 0x0AED);
}
} else {
if (gphy->interfmode == B43_INTERFMODE_NONWLAN) {
@@ -823,7 +767,7 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev)
* interference mitigation code.
* It is save to restore values in random order.
*/
-static void _stack_save(u32 * _stackptr, size_t * stackidx,
+static void _stack_save(u32 *_stackptr, size_t *stackidx,
u8 id, u16 offset, u16 value)
{
u32 *stackptr = &(_stackptr[*stackidx]);
@@ -837,7 +781,7 @@ static void _stack_save(u32 * _stackptr, size_t * stackidx,
B43_WARN_ON(*stackidx >= B43_INTERFSTACK_SIZE);
}
-static u16 _stack_restore(u32 * stackptr, u8 id, u16 offset)
+static u16 _stack_restore(u32 *stackptr, u8 id, u16 offset)
{
size_t i;
@@ -901,11 +845,8 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
switch (mode) {
case B43_INTERFMODE_NONWLAN:
if (phy->rev != 1) {
- b43_phy_write(dev, 0x042B,
- b43_phy_read(dev, 0x042B) | 0x0800);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev,
- B43_PHY_G_CRS) & ~0x4000);
+ b43_phy_set(dev, 0x042B, 0x0800);
+ b43_phy_mask(dev, B43_PHY_G_CRS, ~0x4000);
break;
}
radio_stacksave(0x0078);
@@ -924,26 +865,19 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
phy_stacksave(0x0406);
b43_phy_write(dev, 0x0406, 0x7E28);
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x0800);
- b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
- b43_phy_read(dev,
- B43_PHY_RADIO_BITFIELD) | 0x1000);
+ b43_phy_set(dev, 0x042B, 0x0800);
+ b43_phy_set(dev, B43_PHY_RADIO_BITFIELD, 0x1000);
phy_stacksave(0x04A0);
- b43_phy_write(dev, 0x04A0,
- (b43_phy_read(dev, 0x04A0) & 0xC0C0) | 0x0008);
+ b43_phy_maskset(dev, 0x04A0, 0xC0C0, 0x0008);
phy_stacksave(0x04A1);
- b43_phy_write(dev, 0x04A1,
- (b43_phy_read(dev, 0x04A1) & 0xC0C0) | 0x0605);
+ b43_phy_maskset(dev, 0x04A1, 0xC0C0, 0x0605);
phy_stacksave(0x04A2);
- b43_phy_write(dev, 0x04A2,
- (b43_phy_read(dev, 0x04A2) & 0xC0C0) | 0x0204);
+ b43_phy_maskset(dev, 0x04A2, 0xC0C0, 0x0204);
phy_stacksave(0x04A8);
- b43_phy_write(dev, 0x04A8,
- (b43_phy_read(dev, 0x04A8) & 0xC0C0) | 0x0803);
+ b43_phy_maskset(dev, 0x04A8, 0xC0C0, 0x0803);
phy_stacksave(0x04AB);
- b43_phy_write(dev, 0x04AB,
- (b43_phy_read(dev, 0x04AB) & 0xC0C0) | 0x0605);
+ b43_phy_maskset(dev, 0x04AB, 0xC0C0, 0x0605);
phy_stacksave(0x04A7);
b43_phy_write(dev, 0x04A7, 0x0002);
@@ -999,12 +933,8 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
phy_stacksave(0x042B);
phy_stacksave(0x048C);
- b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
- b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
- & ~0x1000);
- b43_phy_write(dev, B43_PHY_G_CRS,
- (b43_phy_read(dev, B43_PHY_G_CRS)
- & 0xFFFC) | 0x0002);
+ b43_phy_mask(dev, B43_PHY_RADIO_BITFIELD, ~0x1000);
+ b43_phy_maskset(dev, B43_PHY_G_CRS, 0xFFFC, 0x0002);
b43_phy_write(dev, 0x0033, 0x0800);
b43_phy_write(dev, 0x04A3, 0x2027);
@@ -1013,8 +943,7 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
b43_phy_write(dev, 0x04AA, 0x1CA8);
b43_phy_write(dev, 0x04AC, 0x287A);
- b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
- & 0xFFC0) | 0x001A);
+ b43_phy_maskset(dev, 0x04A0, 0xFFC0, 0x001A);
b43_phy_write(dev, 0x04A7, 0x000D);
if (phy->rev < 2) {
@@ -1027,65 +956,41 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode)
b43_phy_write(dev, 0x04C1, 0x0059);
}
- b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
- & 0xC0FF) | 0x1800);
- b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
- & 0xFFC0) | 0x0015);
- b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
- & 0xCFFF) | 0x1000);
- b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
- & 0xF0FF) | 0x0A00);
- b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
- & 0xCFFF) | 0x1000);
- b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
- & 0xF0FF) | 0x0800);
- b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
- & 0xFFCF) | 0x0010);
- b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
- & 0xFFF0) | 0x0005);
- b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
- & 0xFFCF) | 0x0010);
- b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
- & 0xFFF0) | 0x0006);
- b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
- & 0xF0FF) | 0x0800);
- b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
- & 0xF0FF) | 0x0500);
- b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
- & 0xFFF0) | 0x000B);
+ b43_phy_maskset(dev, 0x04A1, 0xC0FF, 0x1800);
+ b43_phy_maskset(dev, 0x04A1, 0xFFC0, 0x0015);
+ b43_phy_maskset(dev, 0x04A8, 0xCFFF, 0x1000);
+ b43_phy_maskset(dev, 0x04A8, 0xF0FF, 0x0A00);
+ b43_phy_maskset(dev, 0x04AB, 0xCFFF, 0x1000);
+ b43_phy_maskset(dev, 0x04AB, 0xF0FF, 0x0800);
+ b43_phy_maskset(dev, 0x04AB, 0xFFCF, 0x0010);
+ b43_phy_maskset(dev, 0x04AB, 0xFFF0, 0x0005);
+ b43_phy_maskset(dev, 0x04A8, 0xFFCF, 0x0010);
+ b43_phy_maskset(dev, 0x04A8, 0xFFF0, 0x0006);
+ b43_phy_maskset(dev, 0x04A2, 0xF0FF, 0x0800);
+ b43_phy_maskset(dev, 0x04A0, 0xF0FF, 0x0500);
+ b43_phy_maskset(dev, 0x04A2, 0xFFF0, 0x000B);
if (phy->rev >= 3) {
- b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
- & ~0x8000);
- b43_phy_write(dev, 0x0415, (b43_phy_read(dev, 0x0415)
- & 0x8000) | 0x36D8);
- b43_phy_write(dev, 0x0416, (b43_phy_read(dev, 0x0416)
- & 0x8000) | 0x36D8);
- b43_phy_write(dev, 0x0417, (b43_phy_read(dev, 0x0417)
- & 0xFE00) | 0x016D);
+ b43_phy_mask(dev, 0x048A, (u16)~0x8000);
+ b43_phy_maskset(dev, 0x0415, 0x8000, 0x36D8);
+ b43_phy_maskset(dev, 0x0416, 0x8000, 0x36D8);
+ b43_phy_maskset(dev, 0x0417, 0xFE00, 0x016D);
} else {
- b43_phy_write(dev, 0x048A, b43_phy_read(dev, 0x048A)
- | 0x1000);
- b43_phy_write(dev, 0x048A, (b43_phy_read(dev, 0x048A)
- & 0x9FFF) | 0x2000);
+ b43_phy_set(dev, 0x048A, 0x1000);
+ b43_phy_maskset(dev, 0x048A, 0x9FFF, 0x2000);
b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ACIW);
}
if (phy->rev >= 2) {
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B)
- | 0x0800);
+ b43_phy_set(dev, 0x042B, 0x0800);
}
- b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C)
- & 0xF0FF) | 0x0200);
+ b43_phy_maskset(dev, 0x048C, 0xF0FF, 0x0200);
if (phy->rev == 2) {
- b43_phy_write(dev, 0x04AE, (b43_phy_read(dev, 0x04AE)
- & 0xFF00) | 0x007F);
- b43_phy_write(dev, 0x04AD, (b43_phy_read(dev, 0x04AD)
- & 0x00FF) | 0x1300);
+ b43_phy_maskset(dev, 0x04AE, 0xFF00, 0x007F);
+ b43_phy_maskset(dev, 0x04AD, 0x00FF, 0x1300);
} else if (phy->rev >= 6) {
b43_ofdmtab_write16(dev, 0x1A00, 0x3, 0x007F);
b43_ofdmtab_write16(dev, 0x1A00, 0x2, 0x007F);
- b43_phy_write(dev, 0x04AD, b43_phy_read(dev, 0x04AD)
- & 0x00FF);
+ b43_phy_mask(dev, 0x04AD, 0x00FF);
}
b43_calc_nrssi_slope(dev);
break;
@@ -1104,24 +1009,18 @@ b43_radio_interference_mitigation_disable(struct b43_wldev *dev, int mode)
switch (mode) {
case B43_INTERFMODE_NONWLAN:
if (phy->rev != 1) {
- b43_phy_write(dev, 0x042B,
- b43_phy_read(dev, 0x042B) & ~0x0800);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev,
- B43_PHY_G_CRS) | 0x4000);
+ b43_phy_mask(dev, 0x042B, ~0x0800);
+ b43_phy_set(dev, B43_PHY_G_CRS, 0x4000);
break;
}
radio_stackrestore(0x0078);
b43_calc_nrssi_threshold(dev);
phy_stackrestore(0x0406);
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) & ~0x0800);
+ b43_phy_mask(dev, 0x042B, ~0x0800);
if (!dev->bad_frames_preempt) {
- b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
- b43_phy_read(dev, B43_PHY_RADIO_BITFIELD)
- & ~(1 << 11));
+ b43_phy_mask(dev, B43_PHY_RADIO_BITFIELD, ~(1 << 11));
}
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) | 0x4000);
+ b43_phy_set(dev, B43_PHY_G_CRS, 0x4000);
phy_stackrestore(0x04A0);
phy_stackrestore(0x04A1);
phy_stackrestore(0x04A2);
@@ -1389,17 +1288,10 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
sav.phy_crs0 = b43_phy_read(dev, B43_PHY_CRS0);
sav.phy_classctl = b43_phy_read(dev, B43_PHY_CLASSCTL);
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER)
- | 0x0003);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev, B43_PHY_ANALOGOVERVAL)
- & 0xFFFC);
- b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
- & 0x7FFF);
- b43_phy_write(dev, B43_PHY_CLASSCTL,
- b43_phy_read(dev, B43_PHY_CLASSCTL)
- & 0xFFFC);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0003);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_CRS0, 0x7FFF);
+ b43_phy_mask(dev, B43_PHY_CLASSCTL, 0xFFFC);
if (has_loopback_gain(phy)) {
sav.phy_lo_mask = b43_phy_read(dev, B43_PHY_LO_MASK);
sav.phy_lo_ctl = b43_phy_read(dev, B43_PHY_LO_CTL);
@@ -1420,8 +1312,7 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
b43_write16(dev, 0x3E2, b43_read16(dev, 0x3E2) | 0x8000);
sav.phy_syncctl = b43_phy_read(dev, B43_PHY_SYNCCTL);
- b43_phy_write(dev, B43_PHY_SYNCCTL, b43_phy_read(dev, B43_PHY_SYNCCTL)
- & 0xFF7F);
+ b43_phy_mask(dev, B43_PHY_SYNCCTL, 0xFF7F);
sav.reg_3E6 = b43_read16(dev, 0x3E6);
sav.reg_3F4 = b43_read16(dev, 0x3F4);
@@ -1429,9 +1320,7 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
b43_write16(dev, 0x03E6, 0x0122);
} else {
if (phy->analog >= 2) {
- b43_phy_write(dev, B43_PHY_CCK(0x03),
- (b43_phy_read(dev, B43_PHY_CCK(0x03))
- & 0xFFBF) | 0x40);
+ b43_phy_maskset(dev, B43_PHY_CCK(0x03), 0xFFBF, 0x40);
}
b43_write16(dev, B43_MMIO_CHANNEL_EXT,
(b43_read16(dev, B43_MMIO_CHANNEL_EXT) | 0x2000));
@@ -1454,14 +1343,12 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
LPD(0, 0, 1)));
}
b43_phy_write(dev, B43_PHY_PGACTL, 0xBFA0);
- b43_radio_write16(dev, 0x51, b43_radio_read16(dev, 0x51)
- | 0x0004);
+ b43_radio_set(dev, 0x51, 0x0004);
if (phy->radio_rev == 8) {
b43_radio_write16(dev, 0x43, 0x1F);
} else {
b43_radio_write16(dev, 0x52, 0);
- b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
- & 0xFFF0) | 0x0009);
+ b43_radio_maskset(dev, 0x43, 0xFFF0, 0x0009);
}
b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
@@ -1610,8 +1497,7 @@ static void b43_phy_initb5(struct b43_wldev *dev)
u8 old_channel;
if (phy->analog == 1) {
- b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A)
- | 0x0050);
+ b43_radio_set(dev, 0x007A, 0x0050);
}
if ((bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM) &&
(bus->boardinfo.type != SSB_BOARD_BU4306)) {
@@ -1621,39 +1507,29 @@ static void b43_phy_initb5(struct b43_wldev *dev)
value += 0x202;
}
}
- b43_phy_write(dev, 0x0035, (b43_phy_read(dev, 0x0035) & 0xF0FF)
- | 0x0700);
+ b43_phy_maskset(dev, 0x0035, 0xF0FF, 0x0700);
if (phy->radio_ver == 0x2050)
b43_phy_write(dev, 0x0038, 0x0667);
if (phy->gmode || phy->rev >= 2) {
if (phy->radio_ver == 0x2050) {
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A)
- | 0x0020);
- b43_radio_write16(dev, 0x0051,
- b43_radio_read16(dev, 0x0051)
- | 0x0004);
+ b43_radio_set(dev, 0x007A, 0x0020);
+ b43_radio_set(dev, 0x0051, 0x0004);
}
b43_write16(dev, B43_MMIO_PHY_RADIO, 0x0000);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
+ b43_phy_set(dev, 0x0802, 0x0100);
+ b43_phy_set(dev, 0x042B, 0x2000);
b43_phy_write(dev, 0x001C, 0x186A);
- b43_phy_write(dev, 0x0013,
- (b43_phy_read(dev, 0x0013) & 0x00FF) | 0x1900);
- b43_phy_write(dev, 0x0035,
- (b43_phy_read(dev, 0x0035) & 0xFFC0) | 0x0064);
- b43_phy_write(dev, 0x005D,
- (b43_phy_read(dev, 0x005D) & 0xFF80) | 0x000A);
+ b43_phy_maskset(dev, 0x0013, 0x00FF, 0x1900);
+ b43_phy_maskset(dev, 0x0035, 0xFFC0, 0x0064);
+ b43_phy_maskset(dev, 0x005D, 0xFF80, 0x000A);
}
if (dev->bad_frames_preempt) {
- b43_phy_write(dev, B43_PHY_RADIO_BITFIELD,
- b43_phy_read(dev,
- B43_PHY_RADIO_BITFIELD) | (1 << 11));
+ b43_phy_set(dev, B43_PHY_RADIO_BITFIELD, (1 << 11));
}
if (phy->analog == 1) {
@@ -1695,7 +1571,7 @@ static void b43_phy_initb5(struct b43_wldev *dev)
b43_radio_write16(dev, 0x005B, 0x007B);
b43_radio_write16(dev, 0x005C, 0x00B0);
- b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) | 0x0007);
+ b43_radio_set(dev, 0x007A, 0x0007);
b43_gphy_channel_switch(dev, old_channel, 0);
@@ -1771,12 +1647,10 @@ static void b43_phy_initb6(struct b43_wldev *dev)
val += 0x0202;
}
if (phy->type == B43_PHYTYPE_G) {
- b43_radio_write16(dev, 0x007A,
- b43_radio_read16(dev, 0x007A) | 0x0020);
- b43_radio_write16(dev, 0x0051,
- b43_radio_read16(dev, 0x0051) | 0x0004);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) | 0x0100);
- b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x2000);
+ b43_radio_set(dev, 0x007A, 0x0020);
+ b43_radio_set(dev, 0x0051, 0x0004);
+ b43_phy_set(dev, 0x0802, 0x0100);
+ b43_phy_set(dev, 0x042B, 0x2000);
b43_phy_write(dev, 0x5B, 0);
b43_phy_write(dev, 0x5C, 0);
}
@@ -1801,8 +1675,7 @@ static void b43_phy_initb6(struct b43_wldev *dev)
b43_radio_write16(dev, 0x5B, 0x7B);
b43_radio_write16(dev, 0x5C, 0xB0);
}
- b43_radio_write16(dev, 0x007A,
- (b43_radio_read16(dev, 0x007A) & 0x00F8) | 0x0007);
+ b43_radio_maskset(dev, 0x007A, 0x00F8, 0x0007);
b43_gphy_channel_switch(dev, old_channel, 0);
@@ -1814,19 +1687,16 @@ static void b43_phy_initb6(struct b43_wldev *dev)
b43_phy_write(dev, 0x0038, 0x0668);
b43_set_txpower_g(dev, &gphy->bbatt, &gphy->rfatt, gphy->tx_control);
if (phy->radio_rev <= 5) {
- b43_phy_write(dev, 0x5D, (b43_phy_read(dev, 0x5D)
- & 0xFF80) | 0x0003);
+ b43_phy_maskset(dev, 0x5D, 0xFF80, 0x0003);
}
if (phy->radio_rev <= 2)
b43_radio_write16(dev, 0x005D, 0x000D);
if (phy->analog == 4) {
b43_write16(dev, 0x3E4, 9);
- b43_phy_write(dev, 0x61, b43_phy_read(dev, 0x61)
- & 0x0FFF);
+ b43_phy_mask(dev, 0x61, 0x0FFF);
} else {
- b43_phy_write(dev, 0x0002, (b43_phy_read(dev, 0x0002) & 0xFFC0)
- | 0x0004);
+ b43_phy_maskset(dev, 0x0002, 0xFFC0, 0x0004);
}
if (phy->type == B43_PHYTYPE_B)
B43_WARN_ON(1);
@@ -1868,63 +1738,39 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
backup_radio[1] = b43_radio_read16(dev, 0x43);
backup_radio[2] = b43_radio_read16(dev, 0x7A);
- b43_phy_write(dev, B43_PHY_CRS0,
- b43_phy_read(dev, B43_PHY_CRS0) & 0x3FFF);
- b43_phy_write(dev, B43_PHY_CCKBBANDCFG,
- b43_phy_read(dev, B43_PHY_CCKBBANDCFG) | 0x8000);
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x0002);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFD);
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x0001);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xFFFE);
+ b43_phy_mask(dev, B43_PHY_CRS0, 0x3FFF);
+ b43_phy_set(dev, B43_PHY_CCKBBANDCFG, 0x8000);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0002);
+ b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xFFFD);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0001);
+ b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xFFFE);
if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0001);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev,
- B43_PHY_ANALOGOVERVAL) & 0xFFFE);
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0002);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev,
- B43_PHY_ANALOGOVERVAL) & 0xFFFD);
- }
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x000C);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL) | 0x000C);
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x0030);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- (b43_phy_read(dev, B43_PHY_RFOVERVAL)
- & 0xFFCF) | 0x10);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0001);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFE);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0002);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFD);
+ }
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x000C);
+ b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x000C);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0030);
+ b43_phy_maskset(dev, B43_PHY_RFOVERVAL, 0xFFCF, 0x10);
b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0780);
b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
- b43_phy_write(dev, B43_PHY_CCK(0x0A),
- b43_phy_read(dev, B43_PHY_CCK(0x0A)) | 0x2000);
+ b43_phy_set(dev, B43_PHY_CCK(0x0A), 0x2000);
if (phy->rev != 1) { /* Not in specs, but needed to prevent PPC machine check */
- b43_phy_write(dev, B43_PHY_ANALOGOVER,
- b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0004);
- b43_phy_write(dev, B43_PHY_ANALOGOVERVAL,
- b43_phy_read(dev,
- B43_PHY_ANALOGOVERVAL) & 0xFFFB);
+ b43_phy_set(dev, B43_PHY_ANALOGOVER, 0x0004);
+ b43_phy_mask(dev, B43_PHY_ANALOGOVERVAL, 0xFFFB);
}
- b43_phy_write(dev, B43_PHY_CCK(0x03),
- (b43_phy_read(dev, B43_PHY_CCK(0x03))
- & 0xFF9F) | 0x40);
+ b43_phy_maskset(dev, B43_PHY_CCK(0x03), 0xFF9F, 0x40);
if (phy->radio_rev == 8) {
b43_radio_write16(dev, 0x43, 0x000F);
} else {
b43_radio_write16(dev, 0x52, 0);
- b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
- & 0xFFF0) | 0x9);
+ b43_radio_maskset(dev, 0x43, 0xFFF0, 0x9);
}
b43_gphy_set_baseband_attenuation(dev, 11);
@@ -1934,45 +1780,28 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_LO_MASK, 0x8020);
b43_phy_write(dev, B43_PHY_LO_CTL, 0);
- b43_phy_write(dev, B43_PHY_CCK(0x2B),
- (b43_phy_read(dev, B43_PHY_CCK(0x2B))
- & 0xFFC0) | 0x01);
- b43_phy_write(dev, B43_PHY_CCK(0x2B),
- (b43_phy_read(dev, B43_PHY_CCK(0x2B))
- & 0xC0FF) | 0x800);
+ b43_phy_maskset(dev, B43_PHY_CCK(0x2B), 0xFFC0, 0x01);
+ b43_phy_maskset(dev, B43_PHY_CCK(0x2B), 0xC0FF, 0x800);
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER) | 0x0100);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xCFFF);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0100);
+ b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF);
if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) {
if (phy->rev >= 7) {
- b43_phy_write(dev, B43_PHY_RFOVER,
- b43_phy_read(dev, B43_PHY_RFOVER)
- | 0x0800);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL)
- | 0x8000);
+ b43_phy_set(dev, B43_PHY_RFOVER, 0x0800);
+ b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000);
}
}
- b43_radio_write16(dev, 0x7A, b43_radio_read16(dev, 0x7A)
- & 0x00F7);
+ b43_radio_mask(dev, 0x7A, 0x00F7);
j = 0;
loop_i_max = (phy->radio_rev == 8) ? 15 : 9;
for (i = 0; i < loop_i_max; i++) {
for (j = 0; j < 16; j++) {
b43_radio_write16(dev, 0x43, i);
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- (b43_phy_read(dev, B43_PHY_RFOVERVAL)
- & 0xF0FF) | (j << 8));
- b43_phy_write(dev, B43_PHY_PGACTL,
- (b43_phy_read(dev, B43_PHY_PGACTL)
- & 0x0FFF) | 0xA000);
- b43_phy_write(dev, B43_PHY_PGACTL,
- b43_phy_read(dev, B43_PHY_PGACTL)
- | 0xF000);
+ b43_phy_maskset(dev, B43_PHY_RFOVERVAL, 0xF0FF, (j << 8));
+ b43_phy_maskset(dev, B43_PHY_PGACTL, 0x0FFF, 0xA000);
+ b43_phy_set(dev, B43_PHY_PGACTL, 0xF000);
udelay(20);
if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
goto exit_loop1;
@@ -1982,20 +1811,12 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
loop1_outer_done = i;
loop1_inner_done = j;
if (j >= 8) {
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- b43_phy_read(dev, B43_PHY_RFOVERVAL)
- | 0x30);
+ b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x30);
trsw_rx = 0x1B;
for (j = j - 8; j < 16; j++) {
- b43_phy_write(dev, B43_PHY_RFOVERVAL,
- (b43_phy_read(dev, B43_PHY_RFOVERVAL)
- & 0xF0FF) | (j << 8));
- b43_phy_write(dev, B43_PHY_PGACTL,
- (b43_phy_read(dev, B43_PHY_PGACTL)
- & 0x0FFF) | 0xA000);
- b43_phy_write(dev, B43_PHY_PGACTL,
- b43_phy_read(dev, B43_PHY_PGACTL)
- | 0xF000);
+ b43_phy_maskset(dev, B43_PHY_RFOVERVAL, 0xF0FF, (j << 8));
+ b43_phy_maskset(dev, B43_PHY_PGACTL, 0x0FFF, 0xA000);
+ b43_phy_set(dev, B43_PHY_PGACTL, 0xF000);
udelay(20);
trsw_rx -= 3;
if (b43_phy_read(dev, B43_PHY_LO_LEAKAGE) >= 0xDFC)
@@ -2046,34 +1867,24 @@ static void b43_hardware_pctl_early_init(struct b43_wldev *dev)
return;
}
- b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036) & 0xFEFF);
+ b43_phy_mask(dev, 0x0036, 0xFEFF);
b43_phy_write(dev, 0x002F, 0x0202);
- b43_phy_write(dev, 0x047C, b43_phy_read(dev, 0x047C) | 0x0002);
- b43_phy_write(dev, 0x047A, b43_phy_read(dev, 0x047A) | 0xF000);
+ b43_phy_set(dev, 0x047C, 0x0002);
+ b43_phy_set(dev, 0x047A, 0xF000);
if (phy->radio_ver == 0x2050 && phy->radio_rev == 8) {
- b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
- & 0xFF0F) | 0x0010);
- b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
- | 0x8000);
- b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
- & 0xFFC0) | 0x0010);
+ b43_phy_maskset(dev, 0x047A, 0xFF0F, 0x0010);
+ b43_phy_set(dev, 0x005D, 0x8000);
+ b43_phy_maskset(dev, 0x004E, 0xFFC0, 0x0010);
b43_phy_write(dev, 0x002E, 0xC07F);
- b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
- | 0x0400);
+ b43_phy_set(dev, 0x0036, 0x0400);
} else {
- b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
- | 0x0200);
- b43_phy_write(dev, 0x0036, b43_phy_read(dev, 0x0036)
- | 0x0400);
- b43_phy_write(dev, 0x005D, b43_phy_read(dev, 0x005D)
- & 0x7FFF);
- b43_phy_write(dev, 0x004F, b43_phy_read(dev, 0x004F)
- & 0xFFFE);
- b43_phy_write(dev, 0x004E, (b43_phy_read(dev, 0x004E)
- & 0xFFC0) | 0x0010);
+ b43_phy_set(dev, 0x0036, 0x0200);
+ b43_phy_set(dev, 0x0036, 0x0400);
+ b43_phy_mask(dev, 0x005D, 0x7FFF);
+ b43_phy_mask(dev, 0x004F, 0xFFFE);
+ b43_phy_maskset(dev, 0x004E, 0xFFC0, 0x0010);
b43_phy_write(dev, 0x002E, 0xC07F);
- b43_phy_write(dev, 0x047A, (b43_phy_read(dev, 0x047A)
- & 0xFF0F) | 0x0010);
+ b43_phy_maskset(dev, 0x047A, 0xFF0F, 0x0010);
}
}
@@ -2089,22 +1900,17 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev)
return;
}
- b43_phy_write(dev, 0x0036, (b43_phy_read(dev, 0x0036) & 0xFFC0)
- | (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
- b43_phy_write(dev, 0x0478, (b43_phy_read(dev, 0x0478) & 0xFF00)
- | (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
+ b43_phy_maskset(dev, 0x0036, 0xFFC0, (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
+ b43_phy_maskset(dev, 0x0478, 0xFF00, (gphy->tgt_idle_tssi - gphy->cur_idle_tssi));
b43_gphy_tssi_power_lt_init(dev);
b43_gphy_gain_lt_init(dev);
- b43_phy_write(dev, 0x0060, b43_phy_read(dev, 0x0060) & 0xFFBF);
+ b43_phy_mask(dev, 0x0060, 0xFFBF);
b43_phy_write(dev, 0x0014, 0x0000);
B43_WARN_ON(phy->rev < 6);
- b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
- | 0x0800);
- b43_phy_write(dev, 0x0478, b43_phy_read(dev, 0x0478)
- & 0xFEFF);
- b43_phy_write(dev, 0x0801, b43_phy_read(dev, 0x0801)
- & 0xFFBF);
+ b43_phy_set(dev, 0x0478, 0x0800);
+ b43_phy_mask(dev, 0x0478, 0xFEFF);
+ b43_phy_mask(dev, 0x0801, 0xFFBF);
b43_gphy_dc_lt_init(dev, 1);
@@ -2139,9 +1945,7 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
b43_hardware_pctl_early_init(dev);
if (gphy->cur_idle_tssi == 0) {
if (phy->radio_ver == 0x2050 && phy->analog == 0) {
- b43_radio_write16(dev, 0x0076,
- (b43_radio_read16(dev, 0x0076)
- & 0x00F7) | 0x0084);
+ b43_radio_maskset(dev, 0x0076, 0x00F7, 0x0084);
} else {
struct b43_rfatt rfatt;
struct b43_bbatt bbatt;
@@ -2174,9 +1978,7 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
}
}
if (phy->radio_ver == 0x2050 && phy->analog == 0) {
- b43_radio_write16(dev, 0x0076,
- b43_radio_read16(dev, 0x0076)
- & 0xFF7B);
+ b43_radio_mask(dev, 0x0076, 0xFF7B);
} else {
b43_set_txpower_g(dev, &old_bbatt,
&old_rfatt, old_tx_control);
@@ -2220,20 +2022,14 @@ static void b43_phy_initg(struct b43_wldev *dev)
b43_phy_write(dev, B43_PHY_OFDM(0xC3), 0x8006);
}
if (tmp == 5) {
- b43_phy_write(dev, B43_PHY_OFDM(0xCC),
- (b43_phy_read(dev, B43_PHY_OFDM(0xCC))
- & 0x00FF) | 0x1F00);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xCC), 0x00FF, 0x1F00);
}
}
if ((phy->rev <= 2 && phy->gmode) || phy->rev >= 2)
b43_phy_write(dev, B43_PHY_OFDM(0x7E), 0x78);
if (phy->radio_rev == 8) {
- b43_phy_write(dev, B43_PHY_EXTG(0x01),
- b43_phy_read(dev, B43_PHY_EXTG(0x01))
- | 0x80);
- b43_phy_write(dev, B43_PHY_OFDM(0x3E),
- b43_phy_read(dev, B43_PHY_OFDM(0x3E))
- | 0x4);
+ b43_phy_set(dev, B43_PHY_EXTG(0x01), 0x80);
+ b43_phy_set(dev, B43_PHY_OFDM(0x3E), 0x4);
}
if (has_loopback_gain(phy))
b43_calc_loopback_gain(dev);
@@ -2251,15 +2047,10 @@ static void b43_phy_initg(struct b43_wldev *dev)
| gphy->lo_control->tx_bias | gphy->
lo_control->tx_magn);
} else {
- b43_radio_write16(dev, 0x52,
- (b43_radio_read16(dev, 0x52) & 0xFFF0)
- | gphy->lo_control->tx_bias);
+ b43_radio_maskset(dev, 0x52, 0xFFF0, gphy->lo_control->tx_bias);
}
if (phy->rev >= 6) {
- b43_phy_write(dev, B43_PHY_CCK(0x36),
- (b43_phy_read(dev, B43_PHY_CCK(0x36))
- & 0x0FFF) | (gphy->lo_control->
- tx_bias << 12));
+ b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12));
}
if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
@@ -2298,11 +2089,8 @@ static void b43_phy_initg(struct b43_wldev *dev)
but OFDM is legal everywhere */
if ((dev->dev->bus->chip_id == 0x4306
&& dev->dev->bus->chip_package == 2) || 0) {
- b43_phy_write(dev, B43_PHY_CRS0, b43_phy_read(dev, B43_PHY_CRS0)
- & 0xBFFF);
- b43_phy_write(dev, B43_PHY_OFDM(0xC3),
- b43_phy_read(dev, B43_PHY_OFDM(0xC3))
- & 0x7FFF);
+ b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF);
+ b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF);
}
}
@@ -2504,9 +2292,8 @@ static u8 b43_gphy_aci_scan(struct b43_wldev *dev)
b43_phy_lock(dev);
b43_radio_lock(dev);
- b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) & 0x7FFF);
+ b43_phy_mask(dev, 0x0802, 0xFFFC);
+ b43_phy_mask(dev, B43_PHY_G_CRS, 0x7FFF);
b43_set_all_gains(dev, 3, 8, 1);
start = (channel - 5 > 0) ? channel - 5 : 1;
@@ -2517,11 +2304,9 @@ static u8 b43_gphy_aci_scan(struct b43_wldev *dev)
ret[i - 1] = b43_gphy_aci_detect(dev, i);
}
b43_switch_channel(dev, channel);
- b43_phy_write(dev, 0x0802,
- (b43_phy_read(dev, 0x0802) & 0xFFFC) | 0x0003);
- b43_phy_write(dev, 0x0403, b43_phy_read(dev, 0x0403) & 0xFFF8);
- b43_phy_write(dev, B43_PHY_G_CRS,
- b43_phy_read(dev, B43_PHY_G_CRS) | 0x8000);
+ b43_phy_maskset(dev, 0x0802, 0xFFFC, 0x0003);
+ b43_phy_mask(dev, 0x0403, 0xFFF8);
+ b43_phy_set(dev, B43_PHY_G_CRS, 0x8000);
b43_set_original_gains(dev);
for (i = 0; i < 13; i++) {
if (!ret[i])
@@ -2565,8 +2350,8 @@ static s8 b43_tssi2dbm_entry(s8 entry[], u8 index,
return 0;
}
-u8 * b43_generate_dyn_tssi2dbm_tab(struct b43_wldev *dev,
- s16 pab0, s16 pab1, s16 pab2)
+u8 *b43_generate_dyn_tssi2dbm_tab(struct b43_wldev *dev,
+ s16 pab0, s16 pab1, s16 pab2)
{
unsigned int i;
u8 *tab;
@@ -3191,6 +2976,7 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev,
* Baseband attennuation. Subtract it. */
bbatt_delta -= 4 * rfatt_delta;
+#if B43_DEBUG
if (b43_debug(dev, B43_DBG_XMITPOWER)) {
int dbm = pwr_adjust < 0 ? -pwr_adjust : pwr_adjust;
b43dbg(dev->wl,
@@ -3199,6 +2985,8 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev,
(pwr_adjust < 0 ? "-" : ""), Q52_ARG(dbm),
bbatt_delta, rfatt_delta);
}
+#endif /* DEBUG */
+
/* So do we finally need to adjust something in hardware? */
if ((rfatt_delta == 0) && (bbatt_delta == 0))
goto no_adjustment_needed;
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index c5d9dc3667c0..58e319d6b1ed 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -3,7 +3,7 @@
Broadcom B43 wireless driver
IEEE 802.11g LP-PHY driver
- Copyright (c) 2008 Michael Buesch <mb@bu3sch.de>
+ Copyright (c) 2008-2009 Michael Buesch <mb@bu3sch.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,8 +23,10 @@
*/
#include "b43.h"
+#include "main.h"
#include "phy_lp.h"
#include "phy_common.h"
+#include "tables_lpphy.h"
static int b43_lpphy_op_allocate(struct b43_wldev *dev)
@@ -57,9 +59,394 @@ static void b43_lpphy_op_free(struct b43_wldev *dev)
dev->phy.lp = NULL;
}
-static int b43_lpphy_op_init(struct b43_wldev *dev)
+static void lpphy_table_init(struct b43_wldev *dev)
+{
+ //TODO
+}
+
+static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
+{
+ B43_WARN_ON(1);//TODO rev < 2 not supported, yet.
+}
+
+static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
+{
+ struct ssb_bus *bus = dev->dev->bus;
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+
+ b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50);
+ b43_phy_write(dev, B43_LPPHY_AFE_CTL, 0x8800);
+ b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVR, 0);
+ b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0);
+ b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_0, 0);
+ b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2, 0);
+ b43_phy_write(dev, B43_PHY_OFDM(0xF9), 0);
+ b43_phy_write(dev, B43_LPPHY_TR_LOOKUP_1, 0);
+ b43_phy_set(dev, B43_LPPHY_ADC_COMPENSATION_CTL, 0x10);
+ b43_phy_maskset(dev, B43_LPPHY_OFDMSYNCTHRESH0, 0xFF00, 0x78);
+ b43_phy_maskset(dev, B43_LPPHY_DCOFFSETTRANSIENT, 0xF8FF, 0x200);
+ b43_phy_maskset(dev, B43_LPPHY_DCOFFSETTRANSIENT, 0xFF00, 0x7F);
+ b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xFF0F, 0x40);
+ b43_phy_maskset(dev, B43_LPPHY_PREAMBLECONFIRMTO, 0xFF00, 0x2);
+ b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x4000);
+ b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x2000);
+ b43_phy_set(dev, B43_PHY_OFDM(0x10A), 0x1);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x10);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xDF), 0xFF00, 0xF4);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xDF), 0x00FF, 0xF100);
+ b43_phy_write(dev, B43_LPPHY_CLIPTHRESH, 0x48);
+ b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0xFF00, 0x46);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xE4), 0xFF00, 0x10);
+ b43_phy_maskset(dev, B43_LPPHY_PWR_THRESH1, 0xFFF0, 0x9);
+ b43_phy_mask(dev, B43_LPPHY_GAINDIRECTMISMATCH, ~0xF);
+ b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0x00FF, 0x5500);
+ b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xF81F, 0xA0);
+ b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xE0FF, 0x300);
+ b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2A00);
+ if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
+ b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x2100);
+ b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xA);
+ } else {
+ b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x1E00);
+ b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xD);
+ }
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFE), 0xFFE0, 0x1F);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFF), 0xFFE0, 0xC);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x100), 0xFF00, 0x19);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFF), 0x03FF, 0x3C00);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFE), 0xFC1F, 0x3E0);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xFF), 0xFFE0, 0xC);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x100), 0x00FF, 0x1900);
+ b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0x83FF, 0x5800);
+ b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x12);
+ b43_phy_maskset(dev, B43_LPPHY_GAINMISMATCH, 0x0FFF, 0x9000);
+
+ b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0);
+ b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40);
+
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x40);
+ b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xF0FF, 0xB00);
+ b43_phy_maskset(dev, B43_LPPHY_SYNCPEAKCNT, 0xFFF8, 0x6);
+ b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0x00FF, 0x9D00);
+ b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0xFF00, 0xA1);
+ } else /* 5GHz */
+ b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x40);
+
+ b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0xFF00, 0xB3);
+ b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0x00FF, 0xAD00);
+ b43_phy_maskset(dev, B43_LPPHY_INPUT_PWRDB, 0xFF00, lpphy->rx_pwr_offset);
+ b43_phy_set(dev, B43_LPPHY_RESET_CTL, 0x44);
+ b43_phy_write(dev, B43_LPPHY_RESET_CTL, 0x80);
+ b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_0, 0xA954);
+ b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_1,
+ 0x2000 | ((u16)lpphy->rssi_gs << 10) |
+ ((u16)lpphy->rssi_vc << 4) | lpphy->rssi_vf);
+}
+
+static void lpphy_baseband_init(struct b43_wldev *dev)
+{
+ lpphy_table_init(dev);
+ if (dev->phy.rev >= 2)
+ lpphy_baseband_rev2plus_init(dev);
+ else
+ lpphy_baseband_rev0_1_init(dev);
+}
+
+struct b2062_freqdata {
+ u16 freq;
+ u8 data[6];
+};
+
+/* Initialize the 2062 radio. */
+static void lpphy_2062_init(struct b43_wldev *dev)
+{
+ struct ssb_bus *bus = dev->dev->bus;
+ u32 crystalfreq, pdiv, tmp, ref;
+ unsigned int i;
+ const struct b2062_freqdata *fd = NULL;
+
+ static const struct b2062_freqdata freqdata_tab[] = {
+ { .freq = 12000, .data[0] = 6, .data[1] = 6, .data[2] = 6,
+ .data[3] = 6, .data[4] = 10, .data[5] = 6, },
+ { .freq = 13000, .data[0] = 4, .data[1] = 4, .data[2] = 4,
+ .data[3] = 4, .data[4] = 11, .data[5] = 7, },
+ { .freq = 14400, .data[0] = 3, .data[1] = 3, .data[2] = 3,
+ .data[3] = 3, .data[4] = 12, .data[5] = 7, },
+ { .freq = 16200, .data[0] = 3, .data[1] = 3, .data[2] = 3,
+ .data[3] = 3, .data[4] = 13, .data[5] = 8, },
+ { .freq = 18000, .data[0] = 2, .data[1] = 2, .data[2] = 2,
+ .data[3] = 2, .data[4] = 14, .data[5] = 8, },
+ { .freq = 19200, .data[0] = 1, .data[1] = 1, .data[2] = 1,
+ .data[3] = 1, .data[4] = 14, .data[5] = 9, },
+ };
+
+ b2062_upload_init_table(dev);
+
+ b43_radio_write(dev, B2062_N_TX_CTL3, 0);
+ b43_radio_write(dev, B2062_N_TX_CTL4, 0);
+ b43_radio_write(dev, B2062_N_TX_CTL5, 0);
+ b43_radio_write(dev, B2062_N_PDN_CTL0, 0x40);
+ b43_radio_write(dev, B2062_N_PDN_CTL0, 0);
+ b43_radio_write(dev, B2062_N_CALIB_TS, 0x10);
+ b43_radio_write(dev, B2062_N_CALIB_TS, 0);
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+ b43_radio_set(dev, B2062_N_TSSI_CTL0, 0x1);
+ else
+ b43_radio_mask(dev, B2062_N_TSSI_CTL0, ~0x1);
+
+ /* Get the crystal freq, in Hz. */
+ crystalfreq = bus->chipco.pmu.crystalfreq * 1000;
+
+ B43_WARN_ON(!(bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU));
+ B43_WARN_ON(crystalfreq == 0);
+
+ if (crystalfreq >= 30000000) {
+ pdiv = 1;
+ b43_radio_mask(dev, B2062_S_RFPLL_CTL1, 0xFFFB);
+ } else {
+ pdiv = 2;
+ b43_radio_set(dev, B2062_S_RFPLL_CTL1, 0x4);
+ }
+
+ tmp = (800000000 * pdiv + crystalfreq) / (32000000 * pdiv);
+ tmp = (tmp - 1) & 0xFF;
+ b43_radio_write(dev, B2062_S_RFPLL_CTL18, tmp);
+
+ tmp = (2 * crystalfreq + 1000000 * pdiv) / (2000000 * pdiv);
+ tmp = ((tmp & 0xFF) - 1) & 0xFFFF;
+ b43_radio_write(dev, B2062_S_RFPLL_CTL19, tmp);
+
+ ref = (1000 * pdiv + 2 * crystalfreq) / (2000 * pdiv);
+ ref &= 0xFFFF;
+ for (i = 0; i < ARRAY_SIZE(freqdata_tab); i++) {
+ if (ref < freqdata_tab[i].freq) {
+ fd = &freqdata_tab[i];
+ break;
+ }
+ }
+ if (!fd)
+ fd = &freqdata_tab[ARRAY_SIZE(freqdata_tab) - 1];
+ b43dbg(dev->wl, "b2062: Using crystal tab entry %u kHz.\n",
+ fd->freq); /* FIXME: Keep this printk until the code is fully debugged. */
+
+ b43_radio_write(dev, B2062_S_RFPLL_CTL8,
+ ((u16)(fd->data[1]) << 4) | fd->data[0]);
+ b43_radio_write(dev, B2062_S_RFPLL_CTL9,
+ ((u16)(fd->data[3]) << 4) | fd->data[2]);
+ b43_radio_write(dev, B2062_S_RFPLL_CTL10, fd->data[4]);
+ b43_radio_write(dev, B2062_S_RFPLL_CTL11, fd->data[5]);
+}
+
+/* Initialize the 2063 radio. */
+static void lpphy_2063_init(struct b43_wldev *dev)
{
//TODO
+}
+
+static void lpphy_sync_stx(struct b43_wldev *dev)
+{
+ //TODO
+}
+
+static void lpphy_radio_init(struct b43_wldev *dev)
+{
+ /* The radio is attached through the 4wire bus. */
+ b43_phy_set(dev, B43_LPPHY_FOURWIRE_CTL, 0x2);
+ udelay(1);
+ b43_phy_mask(dev, B43_LPPHY_FOURWIRE_CTL, 0xFFFD);
+ udelay(1);
+
+ if (dev->phy.rev < 2) {
+ lpphy_2062_init(dev);
+ } else {
+ lpphy_2063_init(dev);
+ lpphy_sync_stx(dev);
+ b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80);
+ b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0);
+ //TODO Do something on the backplane
+ }
+}
+
+/* Read the TX power control mode from hardware. */
+static void lpphy_read_tx_pctl_mode_from_hardware(struct b43_wldev *dev)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ u16 ctl;
+
+ ctl = b43_phy_read(dev, B43_LPPHY_TX_PWR_CTL_CMD);
+ switch (ctl & B43_LPPHY_TX_PWR_CTL_CMD_MODE) {
+ case B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF:
+ lpphy->txpctl_mode = B43_LPPHY_TXPCTL_OFF;
+ break;
+ case B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW:
+ lpphy->txpctl_mode = B43_LPPHY_TXPCTL_SW;
+ break;
+ case B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW:
+ lpphy->txpctl_mode = B43_LPPHY_TXPCTL_HW;
+ break;
+ default:
+ lpphy->txpctl_mode = B43_LPPHY_TXPCTL_UNKNOWN;
+ B43_WARN_ON(1);
+ break;
+ }
+}
+
+/* Set the TX power control mode in hardware. */
+static void lpphy_write_tx_pctl_mode_to_hardware(struct b43_wldev *dev)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ u16 ctl;
+
+ switch (lpphy->txpctl_mode) {
+ case B43_LPPHY_TXPCTL_OFF:
+ ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF;
+ break;
+ case B43_LPPHY_TXPCTL_HW:
+ ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW;
+ break;
+ case B43_LPPHY_TXPCTL_SW:
+ ctl = B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW;
+ break;
+ default:
+ ctl = 0;
+ B43_WARN_ON(1);
+ }
+ b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
+ (u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE, ctl);
+}
+
+static void lpphy_set_tx_power_control(struct b43_wldev *dev,
+ enum b43_lpphy_txpctl_mode mode)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ enum b43_lpphy_txpctl_mode oldmode;
+
+ oldmode = lpphy->txpctl_mode;
+ lpphy_read_tx_pctl_mode_from_hardware(dev);
+ if (lpphy->txpctl_mode == mode)
+ return;
+ lpphy->txpctl_mode = mode;
+
+ if (oldmode == B43_LPPHY_TXPCTL_HW) {
+ //TODO Update TX Power NPT
+ //TODO Clear all TX Power offsets
+ } else {
+ if (mode == B43_LPPHY_TXPCTL_HW) {
+ //TODO Recalculate target TX power
+ b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
+ 0xFF80, lpphy->tssi_idx);
+ b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM,
+ 0x8FFF, ((u16)lpphy->tssi_npt << 16));
+ //TODO Set "TSSI Transmit Count" variable to total transmitted frame count
+ //TODO Disable TX gain override
+ lpphy->tx_pwr_idx_over = -1;
+ }
+ }
+ if (dev->phy.rev >= 2) {
+ if (mode == B43_LPPHY_TXPCTL_HW)
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xD0), 0xFD, 0x2);
+ else
+ b43_phy_maskset(dev, B43_PHY_OFDM(0xD0), 0xFD, 0);
+ }
+ lpphy_write_tx_pctl_mode_to_hardware(dev);
+}
+
+static void lpphy_set_tx_power_by_index(struct b43_wldev *dev, u8 index)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+
+ lpphy->tx_pwr_idx_over = index;
+ if (lpphy->txpctl_mode != B43_LPPHY_TXPCTL_OFF)
+ lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_SW);
+
+ //TODO
+}
+
+static void lpphy_btcoex_override(struct b43_wldev *dev)
+{
+ b43_write16(dev, B43_MMIO_BTCOEX_CTL, 0x3);
+ b43_write16(dev, B43_MMIO_BTCOEX_TXCTL, 0xFF);
+}
+
+static void lpphy_pr41573_workaround(struct b43_wldev *dev)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ u32 *saved_tab;
+ const unsigned int saved_tab_size = 256;
+ enum b43_lpphy_txpctl_mode txpctl_mode;
+ s8 tx_pwr_idx_over;
+ u16 tssi_npt, tssi_idx;
+
+ saved_tab = kcalloc(saved_tab_size, sizeof(saved_tab[0]), GFP_KERNEL);
+ if (!saved_tab) {
+ b43err(dev->wl, "PR41573 failed. Out of memory!\n");
+ return;
+ }
+
+ lpphy_read_tx_pctl_mode_from_hardware(dev);
+ txpctl_mode = lpphy->txpctl_mode;
+ tx_pwr_idx_over = lpphy->tx_pwr_idx_over;
+ tssi_npt = lpphy->tssi_npt;
+ tssi_idx = lpphy->tssi_idx;
+
+ if (dev->phy.rev < 2) {
+ b43_lptab_read_bulk(dev, B43_LPTAB32(10, 0x140),
+ saved_tab_size, saved_tab);
+ } else {
+ b43_lptab_read_bulk(dev, B43_LPTAB32(7, 0x140),
+ saved_tab_size, saved_tab);
+ }
+ //TODO
+
+ kfree(saved_tab);
+}
+
+static void lpphy_calibration(struct b43_wldev *dev)
+{
+ struct b43_phy_lp *lpphy = dev->phy.lp;
+ enum b43_lpphy_txpctl_mode saved_pctl_mode;
+
+ b43_mac_suspend(dev);
+
+ lpphy_btcoex_override(dev);
+ lpphy_read_tx_pctl_mode_from_hardware(dev);
+ saved_pctl_mode = lpphy->txpctl_mode;
+ lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
+ //TODO Perform transmit power table I/Q LO calibration
+ if ((dev->phy.rev == 0) && (saved_pctl_mode != B43_LPPHY_TXPCTL_OFF))
+ lpphy_pr41573_workaround(dev);
+ //TODO If a full calibration has not been performed on this channel yet, perform PAPD TX-power calibration
+ lpphy_set_tx_power_control(dev, saved_pctl_mode);
+ //TODO Perform I/Q calibration with a single control value set
+
+ b43_mac_enable(dev);
+}
+
+/* Initialize TX power control */
+static void lpphy_tx_pctl_init(struct b43_wldev *dev)
+{
+ if (0/*FIXME HWPCTL capable */) {
+ //TODO
+ } else { /* This device is only software TX power control capable. */
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ //TODO
+ } else {
+ //TODO
+ }
+ //TODO set BB multiplier to 0x0096
+ }
+}
+
+static int b43_lpphy_op_init(struct b43_wldev *dev)
+{
+ /* TODO: band SPROM */
+ lpphy_baseband_init(dev);
+ lpphy_radio_init(dev);
+ //TODO calibrate RC
+ //TODO set channel
+ lpphy_tx_pctl_init(dev);
+ //TODO full calib
return 0;
}
@@ -115,7 +502,9 @@ static int b43_lpphy_op_switch_channel(struct b43_wldev *dev,
static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev *dev)
{
- return 1; /* Default to channel 1 */
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+ return 1;
+ return 36;
}
static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
diff --git a/drivers/net/wireless/b43/phy_lp.h b/drivers/net/wireless/b43/phy_lp.h
index b0b5357abf93..18370b4ac38e 100644
--- a/drivers/net/wireless/b43/phy_lp.h
+++ b/drivers/net/wireless/b43/phy_lp.h
@@ -4,8 +4,285 @@
/* Definitions for the LP-PHY */
+/* The CCK PHY register range. */
+#define B43_LPPHY_B_VERSION B43_PHY_CCK(0x00) /* B PHY version */
+#define B43_LPPHY_B_BBCONFIG B43_PHY_CCK(0x01) /* B PHY BBConfig */
+#define B43_LPPHY_B_RX_STAT0 B43_PHY_CCK(0x04) /* B PHY RX Status0 */
+#define B43_LPPHY_B_RX_STAT1 B43_PHY_CCK(0x05) /* B PHY RX Status1 */
+#define B43_LPPHY_B_CRS_THRESH B43_PHY_CCK(0x06) /* B PHY CRS Thresh */
+#define B43_LPPHY_B_TXERROR B43_PHY_CCK(0x07) /* B PHY TxError */
+#define B43_LPPHY_B_CHANNEL B43_PHY_CCK(0x08) /* B PHY Channel */
+#define B43_LPPHY_B_WORKAROUND B43_PHY_CCK(0x09) /* B PHY workaround */
+#define B43_LPPHY_B_TEST B43_PHY_CCK(0x0A) /* B PHY Test */
+#define B43_LPPHY_B_FOURWIRE_ADDR B43_PHY_CCK(0x0B) /* B PHY Fourwire Address */
+#define B43_LPPHY_B_FOURWIRE_DATA_HI B43_PHY_CCK(0x0C) /* B PHY Fourwire Data Hi */
+#define B43_LPPHY_B_FOURWIRE_DATA_LO B43_PHY_CCK(0x0D) /* B PHY Fourwire Data Lo */
+#define B43_LPPHY_B_BIST_STAT B43_PHY_CCK(0x0E) /* B PHY Bist Status */
+#define B43_LPPHY_PA_RAMP_TX_TO B43_PHY_CCK(0x10) /* PA Ramp TX Timeout */
+#define B43_LPPHY_RF_SYNTH_DC_TIMER B43_PHY_CCK(0x11) /* RF Synth DC Timer */
+#define B43_LPPHY_PA_RAMP_TX_TIME_IN B43_PHY_CCK(0x12) /* PA ramp TX Time in */
+#define B43_LPPHY_RX_FILTER_TIME_IN B43_PHY_CCK(0x13) /* RX Filter Time in */
+#define B43_LPPHY_PLL_COEFF_S B43_PHY_CCK(0x18) /* PLL Coefficient(s) */
+#define B43_LPPHY_PLL_OUT B43_PHY_CCK(0x19) /* PLL Out */
+#define B43_LPPHY_RSSI_THRES B43_PHY_CCK(0x20) /* RSSI Threshold */
+#define B43_LPPHY_IQ_THRES_HH B43_PHY_CCK(0x21) /* IQ Threshold HH */
+#define B43_LPPHY_IQ_THRES_H B43_PHY_CCK(0x22) /* IQ Threshold H */
+#define B43_LPPHY_IQ_THRES_L B43_PHY_CCK(0x23) /* IQ Threshold L */
+#define B43_LPPHY_IQ_THRES_LL B43_PHY_CCK(0x24) /* IQ Threshold LL */
+#define B43_LPPHY_AGC_GAIN B43_PHY_CCK(0x25) /* AGC Gain */
+#define B43_LPPHY_LNA_GAIN_RANGE B43_PHY_CCK(0x26) /* LNA Gain Range */
+#define B43_LPPHY_JSSI B43_PHY_CCK(0x27) /* JSSI */
+#define B43_LPPHY_TSSI_CTL B43_PHY_CCK(0x28) /* TSSI Control */
+#define B43_LPPHY_TSSI B43_PHY_CCK(0x29) /* TSSI */
+#define B43_LPPHY_TR_LOSS B43_PHY_CCK(0x2A) /* TR Loss */
+#define B43_LPPHY_LO_LEAKAGE B43_PHY_CCK(0x2B) /* LO Leakage */
+#define B43_LPPHY_LO_RSSIACC B43_PHY_CCK(0x2C) /* LO RSSIAcc */
+#define B43_LPPHY_LO_IQ_MAG_ACC B43_PHY_CCK(0x2D) /* LO IQ Mag Acc */
+#define B43_LPPHY_TX_DCOFFSET1 B43_PHY_CCK(0x2E) /* TX DCOffset1 */
+#define B43_LPPHY_TX_DCOFFSET2 B43_PHY_CCK(0x2F) /* TX DCOffset2 */
+#define B43_LPPHY_SYNCPEAKCNT B43_PHY_CCK(0x30) /* SyncPeakCnt */
+#define B43_LPPHY_SYNCFREQ B43_PHY_CCK(0x31) /* SyncFreq */
+#define B43_LPPHY_SYNCDIVERSITYCTL B43_PHY_CCK(0x32) /* SyncDiversityControl */
+#define B43_LPPHY_PEAKENERGYL B43_PHY_CCK(0x33) /* PeakEnergyL */
+#define B43_LPPHY_PEAKENERGYH B43_PHY_CCK(0x34) /* PeakEnergyH */
+#define B43_LPPHY_SYNCCTL B43_PHY_CCK(0x35) /* SyncControl */
+#define B43_LPPHY_DSSSSTEP B43_PHY_CCK(0x38) /* DsssStep */
+#define B43_LPPHY_DSSSWARMUP B43_PHY_CCK(0x39) /* DsssWarmup */
+#define B43_LPPHY_DSSSSIGPOW B43_PHY_CCK(0x3D) /* DsssSigPow */
+#define B43_LPPHY_SFDDETECTBLOCKTIME B43_PHY_CCK(0x40) /* SfdDetectBlockTIme */
+#define B43_LPPHY_SFDTO B43_PHY_CCK(0x41) /* SFDTimeOut */
+#define B43_LPPHY_SFDCTL B43_PHY_CCK(0x42) /* SFDControl */
+#define B43_LPPHY_RXDBG B43_PHY_CCK(0x43) /* rxDebug */
+#define B43_LPPHY_RX_DELAYCOMP B43_PHY_CCK(0x44) /* RX DelayComp */
+#define B43_LPPHY_CRSDROPOUTTO B43_PHY_CCK(0x45) /* CRSDropoutTimeout */
+#define B43_LPPHY_PSEUDOSHORTTO B43_PHY_CCK(0x46) /* PseudoShortTimeout */
+#define B43_LPPHY_PR3931 B43_PHY_CCK(0x47) /* PR3931 */
+#define B43_LPPHY_DSSSCOEFF1 B43_PHY_CCK(0x48) /* DSSSCoeff1 */
+#define B43_LPPHY_DSSSCOEFF2 B43_PHY_CCK(0x49) /* DSSSCoeff2 */
+#define B43_LPPHY_CCKCOEFF1 B43_PHY_CCK(0x4A) /* CCKCoeff1 */
+#define B43_LPPHY_CCKCOEFF2 B43_PHY_CCK(0x4B) /* CCKCoeff2 */
+#define B43_LPPHY_TRCORR B43_PHY_CCK(0x4C) /* TRCorr */
+#define B43_LPPHY_ANGLESCALE B43_PHY_CCK(0x4D) /* AngleScale */
+#define B43_LPPHY_OPTIONALMODES2 B43_PHY_CCK(0x4F) /* OptionalModes2 */
+#define B43_LPPHY_CCKLMSSTEPSIZE B43_PHY_CCK(0x50) /* CCKLMSStepSize */
+#define B43_LPPHY_DFEBYPASS B43_PHY_CCK(0x51) /* DFEBypass */
+#define B43_LPPHY_CCKSTARTDELAYLONG B43_PHY_CCK(0x52) /* CCKStartDelayLong */
+#define B43_LPPHY_CCKSTARTDELAYSHORT B43_PHY_CCK(0x53) /* CCKStartDelayShort */
+#define B43_LPPHY_PPROCCHDELAY B43_PHY_CCK(0x54) /* PprocChDelay */
+#define B43_LPPHY_PPROCONOFF B43_PHY_CCK(0x55) /* PProcOnOff */
+#define B43_LPPHY_LNAGAINTWOBIT10 B43_PHY_CCK(0x5B) /* LNAGainTwoBit10 */
+#define B43_LPPHY_LNAGAINTWOBIT32 B43_PHY_CCK(0x5C) /* LNAGainTwoBit32 */
+#define B43_LPPHY_OPTIONALMODES B43_PHY_CCK(0x5D) /* OptionalModes */
+#define B43_LPPHY_B_RX_STAT2 B43_PHY_CCK(0x5E) /* B PHY RX Status2 */
+#define B43_LPPHY_B_RX_STAT3 B43_PHY_CCK(0x5F) /* B PHY RX Status3 */
+#define B43_LPPHY_PWDNDACDELAY B43_PHY_CCK(0x63) /* pwdnDacDelay */
+#define B43_LPPHY_FINEDIGIGAIN_CTL B43_PHY_CCK(0x67) /* FineDigiGain Control */
+#define B43_LPPHY_LG2GAINTBLLNA8 B43_PHY_CCK(0x68) /* Lg2GainTblLNA8 */
+#define B43_LPPHY_LG2GAINTBLLNA28 B43_PHY_CCK(0x69) /* Lg2GainTblLNA28 */
+#define B43_LPPHY_GAINTBLLNATRSW B43_PHY_CCK(0x6A) /* GainTblLNATrSw */
+#define B43_LPPHY_PEAKENERGY B43_PHY_CCK(0x6B) /* PeakEnergy */
+#define B43_LPPHY_LG2INITGAIN B43_PHY_CCK(0x6C) /* lg2InitGain */
+#define B43_LPPHY_BLANKCOUNTLNAPGA B43_PHY_CCK(0x6D) /* BlankCountLnaPga */
+#define B43_LPPHY_LNAGAINTWOBIT54 B43_PHY_CCK(0x6E) /* LNAGainTwoBit54 */
+#define B43_LPPHY_LNAGAINTWOBIT76 B43_PHY_CCK(0x6F) /* LNAGainTwoBit76 */
+#define B43_LPPHY_JSSICTL B43_PHY_CCK(0x70) /* JSSIControl */
+#define B43_LPPHY_LG2GAINTBLLNA44 B43_PHY_CCK(0x71) /* Lg2GainTblLNA44 */
+#define B43_LPPHY_LG2GAINTBLLNA62 B43_PHY_CCK(0x72) /* Lg2GainTblLNA62 */
+/* The OFDM PHY register range. */
+#define B43_LPPHY_VERSION B43_PHY_OFDM(0x00) /* Version */
+#define B43_LPPHY_BBCONFIG B43_PHY_OFDM(0x01) /* BBConfig */
+#define B43_LPPHY_RX_STAT0 B43_PHY_OFDM(0x04) /* RX Status0 */
+#define B43_LPPHY_RX_STAT1 B43_PHY_OFDM(0x05) /* RX Status1 */
+#define B43_LPPHY_TX_ERROR B43_PHY_OFDM(0x07) /* TX Error */
+#define B43_LPPHY_CHANNEL B43_PHY_OFDM(0x08) /* Channel */
+#define B43_LPPHY_WORKAROUND B43_PHY_OFDM(0x09) /* workaround */
+#define B43_LPPHY_FOURWIRE_ADDR B43_PHY_OFDM(0x0B) /* Fourwire Address */
+#define B43_LPPHY_FOURWIREDATAHI B43_PHY_OFDM(0x0C) /* FourwireDataHi */
+#define B43_LPPHY_FOURWIREDATALO B43_PHY_OFDM(0x0D) /* FourwireDataLo */
+#define B43_LPPHY_BISTSTAT0 B43_PHY_OFDM(0x0E) /* BistStatus0 */
+#define B43_LPPHY_BISTSTAT1 B43_PHY_OFDM(0x0F) /* BistStatus1 */
+#define B43_LPPHY_CRSGAIN_CTL B43_PHY_OFDM(0x10) /* crsgain Control */
+#define B43_LPPHY_OFDMPWR_THRESH0 B43_PHY_OFDM(0x11) /* ofdmPower Thresh0 */
+#define B43_LPPHY_OFDMPWR_THRESH1 B43_PHY_OFDM(0x12) /* ofdmPower Thresh1 */
+#define B43_LPPHY_OFDMPWR_THRESH2 B43_PHY_OFDM(0x13) /* ofdmPower Thresh2 */
+#define B43_LPPHY_DSSSPWR_THRESH0 B43_PHY_OFDM(0x14) /* dsssPower Thresh0 */
+#define B43_LPPHY_DSSSPWR_THRESH1 B43_PHY_OFDM(0x15) /* dsssPower Thresh1 */
+#define B43_LPPHY_MINPWR_LEVEL B43_PHY_OFDM(0x16) /* MinPower Level */
+#define B43_LPPHY_OFDMSYNCTHRESH0 B43_PHY_OFDM(0x17) /* ofdmSyncThresh0 */
+#define B43_LPPHY_OFDMSYNCTHRESH1 B43_PHY_OFDM(0x18) /* ofdmSyncThresh1 */
+#define B43_LPPHY_FINEFREQEST B43_PHY_OFDM(0x19) /* FineFreqEst */
+#define B43_LPPHY_IDLEAFTERPKTRXTO B43_PHY_OFDM(0x1A) /* IDLEafterPktRXTimeout */
+#define B43_LPPHY_LTRN_CTL B43_PHY_OFDM(0x1B) /* LTRN Control */
+#define B43_LPPHY_DCOFFSETTRANSIENT B43_PHY_OFDM(0x1C) /* DCOffsetTransient */
+#define B43_LPPHY_PREAMBLEINTO B43_PHY_OFDM(0x1D) /* PreambleInTimeout */
+#define B43_LPPHY_PREAMBLECONFIRMTO B43_PHY_OFDM(0x1E) /* PreambleConfirmTimeout */
+#define B43_LPPHY_CLIPTHRESH B43_PHY_OFDM(0x1F) /* ClipThresh */
+#define B43_LPPHY_CLIPCTRTHRESH B43_PHY_OFDM(0x20) /* ClipCtrThresh */
+#define B43_LPPHY_OFDMSYNCTIMER_CTL B43_PHY_OFDM(0x21) /* ofdmSyncTimer Control */
+#define B43_LPPHY_WAITFORPHYSELTO B43_PHY_OFDM(0x22) /* WaitforPHYSelTimeout */
+#define B43_LPPHY_HIGAINDB B43_PHY_OFDM(0x23) /* HiGainDB */
+#define B43_LPPHY_LOWGAINDB B43_PHY_OFDM(0x24) /* LowGainDB */
+#define B43_LPPHY_VERYLOWGAINDB B43_PHY_OFDM(0x25) /* VeryLowGainDB */
+#define B43_LPPHY_GAINMISMATCH B43_PHY_OFDM(0x26) /* gainMismatch */
+#define B43_LPPHY_GAINDIRECTMISMATCH B43_PHY_OFDM(0x27) /* gaindirectMismatch */
+#define B43_LPPHY_PWR_THRESH0 B43_PHY_OFDM(0x28) /* Power Thresh0 */
+#define B43_LPPHY_PWR_THRESH1 B43_PHY_OFDM(0x29) /* Power Thresh1 */
+#define B43_LPPHY_DETECTOR_DELAY_ADJUST B43_PHY_OFDM(0x2A) /* Detector Delay Adjust */
+#define B43_LPPHY_REDUCED_DETECTOR_DELAY B43_PHY_OFDM(0x2B) /* Reduced Detector Delay */
+#define B43_LPPHY_DATA_TO B43_PHY_OFDM(0x2C) /* data Timeout */
+#define B43_LPPHY_CORRELATOR_DIS_DELAY B43_PHY_OFDM(0x2D) /* correlator Dis Delay */
+#define B43_LPPHY_DIVERSITY_GAINBACK B43_PHY_OFDM(0x2E) /* Diversity GainBack */
+#define B43_LPPHY_DSSS_CONFIRM_CNT B43_PHY_OFDM(0x2F) /* DSSS Confirm Cnt */
+#define B43_LPPHY_DC_BLANK_INT B43_PHY_OFDM(0x30) /* DC Blank Interval */
+#define B43_LPPHY_GAIN_MISMATCH_LIMIT B43_PHY_OFDM(0x31) /* gain Mismatch Limit */
+#define B43_LPPHY_CRS_ED_THRESH B43_PHY_OFDM(0x32) /* crs ed thresh */
+#define B43_LPPHY_PHASE_SHIFT_CTL B43_PHY_OFDM(0x33) /* phase shift Control */
+#define B43_LPPHY_INPUT_PWRDB B43_PHY_OFDM(0x34) /* Input PowerDB */
+#define B43_LPPHY_OFDM_SYNC_CTL B43_PHY_OFDM(0x35) /* ofdm sync Control */
+#define B43_LPPHY_AFE_ADC_CTL_0 B43_PHY_OFDM(0x36) /* Afe ADC Control 0 */
+#define B43_LPPHY_AFE_ADC_CTL_1 B43_PHY_OFDM(0x37) /* Afe ADC Control 1 */
+#define B43_LPPHY_AFE_ADC_CTL_2 B43_PHY_OFDM(0x38) /* Afe ADC Control 2 */
+#define B43_LPPHY_AFE_DAC_CTL B43_PHY_OFDM(0x39) /* Afe DAC Control */
+#define B43_LPPHY_AFE_CTL B43_PHY_OFDM(0x3A) /* Afe Control */
+#define B43_LPPHY_AFE_CTL_OVR B43_PHY_OFDM(0x3B) /* Afe Control Ovr */
+#define B43_LPPHY_AFE_CTL_OVRVAL B43_PHY_OFDM(0x3C) /* Afe Control OvrVal */
+#define B43_LPPHY_AFE_RSSI_CTL_0 B43_PHY_OFDM(0x3D) /* Afe RSSI Control 0 */
+#define B43_LPPHY_AFE_RSSI_CTL_1 B43_PHY_OFDM(0x3E) /* Afe RSSI Control 1 */
+#define B43_LPPHY_AFE_RSSI_SEL B43_PHY_OFDM(0x3F) /* Afe RSSI Sel */
+#define B43_LPPHY_RADAR_THRESH B43_PHY_OFDM(0x40) /* Radar Thresh */
+#define B43_LPPHY_RADAR_BLANK_INT B43_PHY_OFDM(0x41) /* Radar blank Interval */
+#define B43_LPPHY_RADAR_MIN_FM_INT B43_PHY_OFDM(0x42) /* Radar min fm Interval */
+#define B43_LPPHY_RADAR_GAIN_TO B43_PHY_OFDM(0x43) /* Radar gain timeout */
+#define B43_LPPHY_RADAR_PULSE_TO B43_PHY_OFDM(0x44) /* Radar pulse timeout */
+#define B43_LPPHY_RADAR_DETECT_FM_CTL B43_PHY_OFDM(0x45) /* Radar detect FM Control */
+#define B43_LPPHY_RADAR_DETECT_EN B43_PHY_OFDM(0x46) /* Radar detect En */
+#define B43_LPPHY_RADAR_RD_DATA_REG B43_PHY_OFDM(0x47) /* Radar Rd Data Reg */
+#define B43_LPPHY_LP_PHY_CTL B43_PHY_OFDM(0x48) /* LP PHY Control */
+#define B43_LPPHY_CLASSIFIER_CTL B43_PHY_OFDM(0x49) /* classifier Control */
+#define B43_LPPHY_RESET_CTL B43_PHY_OFDM(0x4A) /* reset Control */
+#define B43_LPPHY_CLKEN_CTL B43_PHY_OFDM(0x4B) /* ClkEn Control */
+#define B43_LPPHY_RF_OVERRIDE_0 B43_PHY_OFDM(0x4C) /* RF Override 0 */
+#define B43_LPPHY_RF_OVERRIDE_VAL_0 B43_PHY_OFDM(0x4D) /* RF Override Val 0 */
+#define B43_LPPHY_TR_LOOKUP_1 B43_PHY_OFDM(0x4E) /* TR Lookup 1 */
+#define B43_LPPHY_TR_LOOKUP_2 B43_PHY_OFDM(0x4F) /* TR Lookup 2 */
+#define B43_LPPHY_RSSISELLOOKUP1 B43_PHY_OFDM(0x50) /* RssiSelLookup1 */
+#define B43_LPPHY_IQLO_CAL_CMD B43_PHY_OFDM(0x51) /* iqlo Cal Cmd */
+#define B43_LPPHY_IQLO_CAL_CMD_N_NUM B43_PHY_OFDM(0x52) /* iqlo Cal Cmd N num */
+#define B43_LPPHY_IQLO_CAL_CMD_G_CTL B43_PHY_OFDM(0x53) /* iqlo Cal Cmd G control */
+#define B43_LPPHY_MACINT_DBG_REGISTER B43_PHY_OFDM(0x54) /* macint Debug Register */
+#define B43_LPPHY_TABLE_ADDR B43_PHY_OFDM(0x55) /* Table Address */
+#define B43_LPPHY_TABLEDATALO B43_PHY_OFDM(0x56) /* TabledataLo */
+#define B43_LPPHY_TABLEDATAHI B43_PHY_OFDM(0x57) /* TabledataHi */
+#define B43_LPPHY_PHY_CRS_ENABLE_ADDR B43_PHY_OFDM(0x58) /* phy CRS Enable Address */
+#define B43_LPPHY_IDLETIME_CTL B43_PHY_OFDM(0x59) /* Idletime Control */
+#define B43_LPPHY_IDLETIME_CRS_ON_LO B43_PHY_OFDM(0x5A) /* Idletime CRS On Lo */
+#define B43_LPPHY_IDLETIME_CRS_ON_HI B43_PHY_OFDM(0x5B) /* Idletime CRS On Hi */
+#define B43_LPPHY_IDLETIME_MEAS_TIME_LO B43_PHY_OFDM(0x5C) /* Idletime Meas Time Lo */
+#define B43_LPPHY_IDLETIME_MEAS_TIME_HI B43_PHY_OFDM(0x5D) /* Idletime Meas Time Hi */
+#define B43_LPPHY_RESET_LEN_OFDM_TX_ADDR B43_PHY_OFDM(0x5E) /* Reset len Ofdm TX Address */
+#define B43_LPPHY_RESET_LEN_OFDM_RX_ADDR B43_PHY_OFDM(0x5F) /* Reset len Ofdm RX Address */
+#define B43_LPPHY_REG_CRS_ENABLE B43_PHY_OFDM(0x60) /* reg crs enable */
+#define B43_LPPHY_PLCP_TMT_STR0_CTR_MIN B43_PHY_OFDM(0x61) /* PLCP Tmt Str0 Ctr Min */
+#define B43_LPPHY_PKT_FSM_RESET_LEN_VAL B43_PHY_OFDM(0x62) /* Pkt fsm Reset Len Value */
+#define B43_LPPHY_READSYM2RESET_CTL B43_PHY_OFDM(0x63) /* readsym2reset Control */
+#define B43_LPPHY_DC_FILTER_DELAY1 B43_PHY_OFDM(0x64) /* Dc filter delay1 */
+#define B43_LPPHY_PACKET_RX_ACTIVE_TO B43_PHY_OFDM(0x65) /* packet rx Active timeout */
+#define B43_LPPHY_ED_TOVAL B43_PHY_OFDM(0x66) /* ed timeoutValue */
+#define B43_LPPHY_HOLD_CRS_ON_VAL B43_PHY_OFDM(0x67) /* hold CRS On Value */
+#define B43_LPPHY_OFDM_TX_PHY_CRS_DELAY_VAL B43_PHY_OFDM(0x69) /* ofdm tx phy CRS Delay Value */
+#define B43_LPPHY_CCK_TX_PHY_CRS_DELAY_VAL B43_PHY_OFDM(0x6A) /* cck tx phy CRS Delay Value */
+#define B43_LPPHY_ED_ON_CONFIRM_TIMER_VAL B43_PHY_OFDM(0x6B) /* Ed on confirm Timer Value */
+#define B43_LPPHY_ED_OFFSET_CONFIRM_TIMER_VAL B43_PHY_OFDM(0x6C) /* Ed offset confirm Timer Value */
+#define B43_LPPHY_PHY_CRS_OFFSET_TIMER_VAL B43_PHY_OFDM(0x6D) /* phy CRS offset Timer Value */
+#define B43_LPPHY_ADC_COMPENSATION_CTL B43_PHY_OFDM(0x70) /* ADC Compensation Control */
+#define B43_LPPHY_LOG2_RBPSK_ADDR B43_PHY_OFDM(0x71) /* log2 RBPSK Address */
+#define B43_LPPHY_LOG2_RQPSK_ADDR B43_PHY_OFDM(0x72) /* log2 RQPSK Address */
+#define B43_LPPHY_LOG2_R16QAM_ADDR B43_PHY_OFDM(0x73) /* log2 R16QAM Address */
+#define B43_LPPHY_LOG2_R64QAM_ADDR B43_PHY_OFDM(0x74) /* log2 R64QAM Address */
+#define B43_LPPHY_OFFSET_BPSK_ADDR B43_PHY_OFDM(0x75) /* offset BPSK Address */
+#define B43_LPPHY_OFFSET_QPSK_ADDR B43_PHY_OFDM(0x76) /* offset QPSK Address */
+#define B43_LPPHY_OFFSET_16QAM_ADDR B43_PHY_OFDM(0x77) /* offset 16QAM Address */
+#define B43_LPPHY_OFFSET_64QAM_ADDR B43_PHY_OFDM(0x78) /* offset 64QAM Address */
+#define B43_LPPHY_ALPHA1 B43_PHY_OFDM(0x79) /* Alpha1 */
+#define B43_LPPHY_ALPHA2 B43_PHY_OFDM(0x7A) /* Alpha2 */
+#define B43_LPPHY_BETA1 B43_PHY_OFDM(0x7B) /* Beta1 */
+#define B43_LPPHY_BETA2 B43_PHY_OFDM(0x7C) /* Beta2 */
+#define B43_LPPHY_LOOP_NUM_ADDR B43_PHY_OFDM(0x7D) /* Loop Num Address */
+#define B43_LPPHY_STR_COLLMAX_SMPL_ADDR B43_PHY_OFDM(0x7E) /* Str Collmax Sample Address */
+#define B43_LPPHY_MAX_SMPL_COARSE_FINE_ADDR B43_PHY_OFDM(0x7F) /* Max Sample Coarse/Fine Address */
+#define B43_LPPHY_MAX_SMPL_COARSE_STR0CTR_ADDR B43_PHY_OFDM(0x80) /* Max Sample Coarse/Str0Ctr Address */
+#define B43_LPPHY_IQ_ENABLE_WAIT_TIME_ADDR B43_PHY_OFDM(0x81) /* IQ Enable Wait Time Address */
+#define B43_LPPHY_IQ_NUM_SMPLS_ADDR B43_PHY_OFDM(0x82) /* IQ Num Samples Address */
+#define B43_LPPHY_IQ_ACC_HI_ADDR B43_PHY_OFDM(0x83) /* IQ Acc Hi Address */
+#define B43_LPPHY_IQ_ACC_LO_ADDR B43_PHY_OFDM(0x84) /* IQ Acc Lo Address */
+#define B43_LPPHY_IQ_I_PWR_ACC_HI_ADDR B43_PHY_OFDM(0x85) /* IQ I PWR Acc Hi Address */
+#define B43_LPPHY_IQ_I_PWR_ACC_LO_ADDR B43_PHY_OFDM(0x86) /* IQ I PWR Acc Lo Address */
+#define B43_LPPHY_IQ_Q_PWR_ACC_HI_ADDR B43_PHY_OFDM(0x87) /* IQ Q PWR Acc Hi Address */
+#define B43_LPPHY_IQ_Q_PWR_ACC_LO_ADDR B43_PHY_OFDM(0x88) /* IQ Q PWR Acc Lo Address */
+#define B43_LPPHY_MAXNUMSTEPS B43_PHY_OFDM(0x89) /* MaxNumsteps */
+#define B43_LPPHY_ROTORPHASE_ADDR B43_PHY_OFDM(0x8A) /* RotorPhase Address */
+#define B43_LPPHY_ADVANCEDRETARDROTOR_ADDR B43_PHY_OFDM(0x8B) /* AdvancedRetardRotor Address */
+#define B43_LPPHY_RSSIADCDELAY_CTL_ADDR B43_PHY_OFDM(0x8D) /* rssiAdcdelay Control Address */
+#define B43_LPPHY_TSSISTAT_ADDR B43_PHY_OFDM(0x8E) /* tssiStatus Address */
+#define B43_LPPHY_TEMPSENSESTAT_ADDR B43_PHY_OFDM(0x8F) /* tempsenseStatus Address */
+#define B43_LPPHY_TEMPSENSE_CTL_ADDR B43_PHY_OFDM(0x90) /* tempsense Control Address */
+#define B43_LPPHY_WRSSISTAT_ADDR B43_PHY_OFDM(0x91) /* wrssistatus Address */
+#define B43_LPPHY_MUFACTORADDR B43_PHY_OFDM(0x92) /* mufactoraddr */
+#define B43_LPPHY_SCRAMSTATE_ADDR B43_PHY_OFDM(0x93) /* scramstate Address */
+#define B43_LPPHY_TXHOLDOFFADDR B43_PHY_OFDM(0x94) /* txholdoffaddr */
+#define B43_LPPHY_PKTGAINVAL_ADDR B43_PHY_OFDM(0x95) /* pktgainval Address */
+#define B43_LPPHY_COARSEESTIM_ADDR B43_PHY_OFDM(0x96) /* Coarseestim Address */
+#define B43_LPPHY_STATE_TRANSITION_ADDR B43_PHY_OFDM(0x97) /* state Transition Address */
+#define B43_LPPHY_TRN_OFFSET_ADDR B43_PHY_OFDM(0x98) /* TRN offset Address */
+#define B43_LPPHY_NUM_ROTOR_ADDR B43_PHY_OFDM(0x99) /* Num Rotor Address */
+#define B43_LPPHY_VITERBI_OFFSET_ADDR B43_PHY_OFDM(0x9A) /* Viterbi Offset Address */
+#define B43_LPPHY_SMPL_COLLECT_WAIT_ADDR B43_PHY_OFDM(0x9B) /* Sample collect wait Address */
+#define B43_LPPHY_A_PHY_CTL_ADDR B43_PHY_OFDM(0x9C) /* A PHY Control Address */
+#define B43_LPPHY_NUM_PASS_THROUGH_ADDR B43_PHY_OFDM(0x9D) /* Num Pass Through Address */
+#define B43_LPPHY_RX_COMP_COEFF_S B43_PHY_OFDM(0x9E) /* RX Comp coefficient(s) */
+#define B43_LPPHY_CPAROTATEVAL B43_PHY_OFDM(0x9F) /* cpaRotateValue */
+#define B43_LPPHY_SMPL_PLAY_COUNT B43_PHY_OFDM(0xA0) /* Sample play count */
+#define B43_LPPHY_SMPL_PLAY_BUFFER_CTL B43_PHY_OFDM(0xA1) /* Sample play Buffer Control */
+#define B43_LPPHY_FOURWIRE_CTL B43_PHY_OFDM(0xA2) /* fourwire Control */
+#define B43_LPPHY_CPA_TAILCOUNT_VAL B43_PHY_OFDM(0xA3) /* CPA TailCount Value */
+#define B43_LPPHY_TX_PWR_CTL_CMD B43_PHY_OFDM(0xA4) /* TX Power Control Cmd */
+#define B43_LPPHY_TX_PWR_CTL_CMD_MODE 0xE000 /* TX power control mode mask */
+#define B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF 0x0000 /* TX power control is OFF */
+#define B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW 0x8000 /* TX power control is SOFTWARE */
+#define B43_LPPHY_TX_PWR_CTL_CMD_MODE_HW 0xE000 /* TX power control is HARDWARE */
+#define B43_LPPHY_TX_PWR_CTL_NNUM B43_PHY_OFDM(0xA5) /* TX Power Control Nnum */
+#define B43_LPPHY_TX_PWR_CTL_IDLETSSI B43_PHY_OFDM(0xA6) /* TX Power Control IdleTssi */
+#define B43_LPPHY_TX_PWR_CTL_TARGETPWR B43_PHY_OFDM(0xA7) /* TX Power Control TargetPower */
+#define B43_LPPHY_TX_PWR_CTL_DELTAPWR_LIMIT B43_PHY_OFDM(0xA8) /* TX Power Control DeltaPower Limit */
+#define B43_LPPHY_TX_PWR_CTL_BASEINDEX B43_PHY_OFDM(0xA9) /* TX Power Control BaseIndex */
+#define B43_LPPHY_TX_PWR_CTL_PWR_INDEX B43_PHY_OFDM(0xAA) /* TX Power Control Power Index */
+#define B43_LPPHY_TX_PWR_CTL_STAT B43_PHY_OFDM(0xAB) /* TX Power Control Status */
+#define B43_LPPHY_LP_RF_SIGNAL_LUT B43_PHY_OFDM(0xAC) /* LP RF signal LUT */
+#define B43_LPPHY_RX_RADIO_CTL_FILTER_STATE B43_PHY_OFDM(0xAD) /* RX Radio Control Filter State */
+#define B43_LPPHY_RX_RADIO_CTL B43_PHY_OFDM(0xAE) /* RX Radio Control */
+#define B43_LPPHY_NRSSI_STAT_ADDR B43_PHY_OFDM(0xAF) /* NRSSI status Address */
+#define B43_LPPHY_RF_OVERRIDE_2 B43_PHY_OFDM(0xB0) /* RF override 2 */
+#define B43_LPPHY_RF_OVERRIDE_2_VAL B43_PHY_OFDM(0xB1) /* RF override 2 val */
+#define B43_LPPHY_PS_CTL_OVERRIDE_VAL0 B43_PHY_OFDM(0xB2) /* PS Control override val0 */
+#define B43_LPPHY_PS_CTL_OVERRIDE_VAL1 B43_PHY_OFDM(0xB3) /* PS Control override val1 */
+#define B43_LPPHY_PS_CTL_OVERRIDE_VAL2 B43_PHY_OFDM(0xB4) /* PS Control override val2 */
+#define B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL B43_PHY_OFDM(0xB5) /* TX gain Control override val */
+#define B43_LPPHY_RX_GAIN_CTL_OVERRIDE_VAL B43_PHY_OFDM(0xB6) /* RX gain Control override val */
+#define B43_LPPHY_AFE_DDFS B43_PHY_OFDM(0xB7) /* AFE DDFS */
+#define B43_LPPHY_AFE_DDFS_POINTER_INIT B43_PHY_OFDM(0xB8) /* AFE DDFS pointer init */
+#define B43_LPPHY_AFE_DDFS_INCR_INIT B43_PHY_OFDM(0xB9) /* AFE DDFS incr init */
+#define B43_LPPHY_MRCNOISEREDUCTION B43_PHY_OFDM(0xBA) /* mrcNoiseReduction */
+#define B43_LPPHY_TRLOOKUP3 B43_PHY_OFDM(0xBB) /* TRLookup3 */
+#define B43_LPPHY_TRLOOKUP4 B43_PHY_OFDM(0xBC) /* TRLookup4 */
+#define B43_LPPHY_RADAR_FIFO_STAT B43_PHY_OFDM(0xBD) /* Radar FIFO Status */
+#define B43_LPPHY_GPIO_OUTEN B43_PHY_OFDM(0xBE) /* GPIO Out enable */
+#define B43_LPPHY_GPIO_SELECT B43_PHY_OFDM(0xBF) /* GPIO Select */
+#define B43_LPPHY_GPIO_OUT B43_PHY_OFDM(0xC0) /* GPIO Out */
+
+
+/* Radio register access decorators. */
#define B43_LP_RADIO(radio_reg) (radio_reg)
#define B43_LP_NORTH(radio_reg) B43_LP_RADIO(radio_reg)
#define B43_LP_SOUTH(radio_reg) B43_LP_RADIO((radio_reg) | 0x4000)
@@ -529,8 +806,58 @@
+enum b43_lpphy_txpctl_mode {
+ B43_LPPHY_TXPCTL_UNKNOWN = 0,
+ B43_LPPHY_TXPCTL_OFF, /* TX power control is OFF */
+ B43_LPPHY_TXPCTL_SW, /* TX power control is set to Software */
+ B43_LPPHY_TXPCTL_HW, /* TX power control is set to Hardware */
+};
+
struct b43_phy_lp {
- //TODO
+ /* Current TX power control mode. */
+ enum b43_lpphy_txpctl_mode txpctl_mode;
+
+ /* Transmit isolation medium band */
+ u8 tx_isolation_med_band; /* FIXME initial value? */
+ /* Transmit isolation low band */
+ u8 tx_isolation_low_band; /* FIXME initial value? */
+ /* Transmit isolation high band */
+ u8 tx_isolation_hi_band; /* FIXME initial value? */
+
+ /* Receive power offset */
+ u8 rx_pwr_offset; /* FIXME initial value? */
+
+ /* TSSI transmit count */
+ u16 tssi_tx_count;
+ /* TSSI index */
+ u16 tssi_idx; /* FIXME initial value? */
+ /* TSSI npt */
+ u16 tssi_npt; /* FIXME initial value? */
+
+ /* Target TX frequency */
+ u16 tgt_tx_freq; /* FIXME initial value? */
+
+ /* Transmit power index override */
+ s8 tx_pwr_idx_over; /* FIXME initial value? */
+
+ /* RSSI vf */
+ u8 rssi_vf; /* FIXME initial value? */
+ /* RSSI vc */
+ u8 rssi_vc; /* FIXME initial value? */
+ /* RSSI gs */
+ u8 rssi_gs; /* FIXME initial value? */
+
+ /* RC cap */
+ u8 rc_cap; /* FIXME initial value? */
+ /* BX arch */
+ u8 bx_arch; /* FIXME initial value? */
+
+ /* Full calibration channel */
+ u8 full_calib_chan; /* FIXME initial value? */
+
+ /* Transmit iqlocal best coeffs */
+ bool tx_iqloc_best_coeffs_valid;
+ u8 tx_iqloc_best_coeffs[11];
};
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 1036bef8c4cc..8cd9776752e6 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -55,8 +55,8 @@ static u16 generate_cookie(struct b43_pio_txqueue *q,
}
static
-struct b43_pio_txqueue * parse_cookie(struct b43_wldev *dev,
- u16 cookie,
+struct b43_pio_txqueue *parse_cookie(struct b43_wldev *dev,
+ u16 cookie,
struct b43_pio_txpacket **pack)
{
struct b43_pio *pio = &dev->pio;
@@ -134,8 +134,8 @@ static u16 pio_rxqueue_offset(struct b43_wldev *dev)
return 8;
}
-static struct b43_pio_txqueue * b43_setup_pioqueue_tx(struct b43_wldev *dev,
- unsigned int index)
+static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev,
+ unsigned int index)
{
struct b43_pio_txqueue *q;
struct b43_pio_txpacket *p;
@@ -171,8 +171,8 @@ static struct b43_pio_txqueue * b43_setup_pioqueue_tx(struct b43_wldev *dev,
return q;
}
-static struct b43_pio_rxqueue * b43_setup_pioqueue_rx(struct b43_wldev *dev,
- unsigned int index)
+static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev,
+ unsigned int index)
{
struct b43_pio_rxqueue *q;
@@ -308,8 +308,8 @@ err_destroy_bk:
}
/* Static mapping of mac80211's queues (priorities) to b43 PIO queues. */
-static struct b43_pio_txqueue * select_queue_by_priority(struct b43_wldev *dev,
- u8 queue_prio)
+static struct b43_pio_txqueue *select_queue_by_priority(struct b43_wldev *dev,
+ u8 queue_prio)
{
struct b43_pio_txqueue *q;
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index 713753781f40..afad42358693 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -113,7 +113,7 @@ out_unlock:
return err;
}
-char * b43_rfkill_led_name(struct b43_wldev *dev)
+char *b43_rfkill_led_name(struct b43_wldev *dev)
{
struct b43_rfkill *rfk = &(dev->wl->rfkill);
diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c
new file mode 100644
index 000000000000..4ea734dce218
--- /dev/null
+++ b/drivers/net/wireless/b43/tables_lpphy.c
@@ -0,0 +1,394 @@
+/*
+
+ Broadcom B43 wireless driver
+ IEEE 802.11g LP-PHY and radio device data tables
+
+ Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "tables_lpphy.h"
+#include "phy_common.h"
+#include "phy_lp.h"
+
+
+/* Entry of the 2062 radio init table */
+struct b2062_init_tab_entry {
+ u16 offset;
+ u16 value_a;
+ u16 value_g;
+ u8 flags;
+};
+#define B2062_FLAG_A 0x01 /* Flag: Init in A mode */
+#define B2062_FLAG_G 0x02 /* Flag: Init in G mode */
+
+static const struct b2062_init_tab_entry b2062_init_tab[] = {
+ /* { .offset = B2062_N_COMM1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = 0x0001, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_COMM4, .value_a = 0x0001, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_COMM5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM8, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM10, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM12, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM13, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM14, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_COMM15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_PDN_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_PDN_CTL1, .value_a = 0x0000, .value_g = 0x00CA, .flags = B2062_FLAG_G, },
+ /* { .offset = B2062_N_PDN_CTL2, .value_a = 0x0018, .value_g = 0x0018, .flags = 0, }, */
+ { .offset = B2062_N_PDN_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_PDN_CTL4, .value_a = 0x0015, .value_g = 0x002A, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_GEN_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_IQ_CALIB, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ { .offset = B2062_N_LGENC, .value_a = 0x00DB, .value_g = 0x00FF, .flags = B2062_FLAG_A, },
+ /* { .offset = B2062_N_LGENA_LPF, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_BIAS0, .value_a = 0x0041, .value_g = 0x0041, .flags = 0, }, */
+ /* { .offset = B2062_N_LGNEA_BIAS1, .value_a = 0x0002, .value_g = 0x0002, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL0, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_LGENA_TUNE0, .value_a = 0x00DD, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_LGENA_TUNE1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_LGENA_TUNE2, .value_a = 0x00DD, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_LGENA_TUNE3, .value_a = 0x0077, .value_g = 0x00B5, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_LGENA_CTL3, .value_a = 0x0000, .value_g = 0x00FF, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_LGENA_CTL4, .value_a = 0x001F, .value_g = 0x001F, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL5, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+ /* { .offset = B2062_N_LGENA_CTL6, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+ { .offset = B2062_N_LGENA_CTL7, .value_a = 0x0033, .value_g = 0x0033, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_RXA_CTL0, .value_a = 0x0009, .value_g = 0x0009, .flags = 0, }, */
+ { .offset = B2062_N_RXA_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_G, },
+ /* { .offset = B2062_N_RXA_CTL2, .value_a = 0x0018, .value_g = 0x0018, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL3, .value_a = 0x0027, .value_g = 0x0027, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL4, .value_a = 0x0028, .value_g = 0x0028, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL5, .value_a = 0x0007, .value_g = 0x0007, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXA_CTL7, .value_a = 0x0008, .value_g = 0x0008, .flags = 0, }, */
+ { .offset = B2062_N_RXBB_CTL0, .value_a = 0x0082, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_RXBB_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_GAIN0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_RXBB_GAIN1, .value_a = 0x0004, .value_g = 0x0004, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_RXBB_GAIN2, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_RXBB_GAIN3, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI0, .value_a = 0x0043, .value_g = 0x0043, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI1, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_CALIB0, .value_a = 0x0010, .value_g = 0x0010, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_CALIB1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_CALIB2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS0, .value_a = 0x0006, .value_g = 0x0006, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS1, .value_a = 0x002A, .value_g = 0x002A, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS2, .value_a = 0x00AA, .value_g = 0x00AA, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS3, .value_a = 0x0021, .value_g = 0x0021, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS4, .value_a = 0x00AA, .value_g = 0x00AA, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_BIAS5, .value_a = 0x0022, .value_g = 0x0022, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI2, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI3, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI4, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ /* { .offset = B2062_N_RXBB_RSSI5, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL0, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL2, .value_a = 0x0084, .value_g = 0x0084, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_N_TX_CTL4, .value_a = 0x0003, .value_g = 0x0003, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_N_TX_CTL5, .value_a = 0x0002, .value_g = 0x0002, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_TX_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL7, .value_a = 0x0058, .value_g = 0x0058, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL8, .value_a = 0x0082, .value_g = 0x0082, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_CTL_A, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_GC2G, .value_a = 0x00FF, .value_g = 0x00FF, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_GC5G, .value_a = 0x00FF, .value_g = 0x00FF, .flags = 0, }, */
+ { .offset = B2062_N_TX_TUNE, .value_a = 0x0088, .value_g = 0x001B, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_N_TX_PAD, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_PGA, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_PADAUX, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_N_TX_PGAAUX, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_N_TSSI_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TSSI_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TSSI_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_IQ_CALIB_CTL0, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_N_IQ_CALIB_CTL1, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_N_IQ_CALIB_CTL2, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_TS, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL1, .value_a = 0x0015, .value_g = 0x0015, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL2, .value_a = 0x000F, .value_g = 0x000F, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_CTL4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_DBG0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_DBG1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_DBG2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_CALIB_DBG3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_PSENSE_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_PSENSE_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_PSENSE_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_N_TEST_BUF0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RADIO_ID_CODE, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_COMM4, .value_a = 0x0001, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_COMM5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM8, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM10, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM12, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM13, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM14, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_COMM15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_PDS_CTL0, .value_a = 0x00FF, .value_g = 0x00FF, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_PDS_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_PDS_CTL2, .value_a = 0x008E, .value_g = 0x008E, .flags = 0, }, */
+ /* { .offset = B2062_S_PDS_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_BG_CTL0, .value_a = 0x0006, .value_g = 0x0006, .flags = 0, }, */
+ /* { .offset = B2062_S_BG_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_BG_CTL2, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
+ { .offset = B2062_S_LGENG_CTL0, .value_a = 0x00F8, .value_g = 0x00D8, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_LGENG_CTL1, .value_a = 0x003C, .value_g = 0x0024, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_LGENG_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL3, .value_a = 0x0041, .value_g = 0x0041, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL4, .value_a = 0x0002, .value_g = 0x0002, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL5, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL6, .value_a = 0x0022, .value_g = 0x0022, .flags = 0, }, */
+ /* { .offset = B2062_S_LGENG_CTL7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_LGENG_CTL8, .value_a = 0x0088, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_LGENG_CTL9, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+ { .offset = B2062_S_LGENG_CTL10, .value_a = 0x0088, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_LGENG_CTL11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL1, .value_a = 0x0007, .value_g = 0x0007, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL2, .value_a = 0x00AF, .value_g = 0x00AF, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL3, .value_a = 0x0012, .value_g = 0x0012, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL4, .value_a = 0x000B, .value_g = 0x000B, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL5, .value_a = 0x005F, .value_g = 0x005F, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL7, .value_a = 0x0040, .value_g = 0x0040, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL8, .value_a = 0x0052, .value_g = 0x0052, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL9, .value_a = 0x0026, .value_g = 0x0026, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL10, .value_a = 0x0003, .value_g = 0x0003, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL11, .value_a = 0x0036, .value_g = 0x0036, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL12, .value_a = 0x0057, .value_g = 0x0057, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL13, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL14, .value_a = 0x0075, .value_g = 0x0075, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL15, .value_a = 0x00B4, .value_g = 0x00B4, .flags = 0, }, */
+ /* { .offset = B2062_S_REFPLL_CTL16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL0, .value_a = 0x0098, .value_g = 0x0098, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL1, .value_a = 0x0010, .value_g = 0x0010, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL5, .value_a = 0x0043, .value_g = 0x0043, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL6, .value_a = 0x0047, .value_g = 0x0047, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL7, .value_a = 0x000C, .value_g = 0x000C, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL8, .value_a = 0x0011, .value_g = 0x0011, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL9, .value_a = 0x0011, .value_g = 0x0011, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL10, .value_a = 0x000E, .value_g = 0x000E, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL11, .value_a = 0x0008, .value_g = 0x0008, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL12, .value_a = 0x0033, .value_g = 0x0033, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL13, .value_a = 0x000A, .value_g = 0x000A, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL14, .value_a = 0x0006, .value_g = 0x0006, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL17, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL18, .value_a = 0x003E, .value_g = 0x003E, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL19, .value_a = 0x0013, .value_g = 0x0013, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL20, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL21, .value_a = 0x0062, .value_g = 0x0062, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL22, .value_a = 0x0007, .value_g = 0x0007, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL23, .value_a = 0x0016, .value_g = 0x0016, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL24, .value_a = 0x005C, .value_g = 0x005C, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL25, .value_a = 0x0095, .value_g = 0x0095, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL26, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL27, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL28, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RFPLL_CTL29, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL30, .value_a = 0x00A0, .value_g = 0x00A0, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL31, .value_a = 0x0004, .value_g = 0x0004, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RFPLL_CTL32, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ { .offset = B2062_S_RFPLL_CTL33, .value_a = 0x00CC, .value_g = 0x00CC, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ { .offset = B2062_S_RFPLL_CTL34, .value_a = 0x0007, .value_g = 0x0007, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+ /* { .offset = B2062_S_RXG_CNT0, .value_a = 0x0010, .value_g = 0x0010, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT5, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT6, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT7, .value_a = 0x0005, .value_g = 0x0005, .flags = 0, }, */
+ { .offset = B2062_S_RXG_CNT8, .value_a = 0x000F, .value_g = 0x000F, .flags = B2062_FLAG_A, },
+ /* { .offset = B2062_S_RXG_CNT9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT10, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT11, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT12, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT13, .value_a = 0x0044, .value_g = 0x0044, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT14, .value_a = 0x00A0, .value_g = 0x00A0, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT15, .value_a = 0x0004, .value_g = 0x0004, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+ /* { .offset = B2062_S_RXG_CNT17, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+};
+
+void b2062_upload_init_table(struct b43_wldev *dev)
+{
+ const struct b2062_init_tab_entry *e;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(b2062_init_tab); i++) {
+ e = &b2062_init_tab[i];
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ if (!(e->flags & B2062_FLAG_G))
+ continue;
+ b43_radio_write(dev, e->offset, e->value_g);
+ } else {
+ if (!(e->flags & B2062_FLAG_A))
+ continue;
+ b43_radio_write(dev, e->offset, e->value_a);
+ }
+ }
+}
+
+u32 b43_lptab_read(struct b43_wldev *dev, u32 offset)
+{
+ u32 type, value;
+
+ type = offset & B43_LPTAB_TYPEMASK;
+ offset &= ~B43_LPTAB_TYPEMASK;
+ B43_WARN_ON(offset > 0xFFFF);
+
+ switch (type) {
+ case B43_LPTAB_8BIT:
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ value = b43_phy_read(dev, B43_LPPHY_TABLEDATALO) & 0xFF;
+ break;
+ case B43_LPTAB_16BIT:
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ value = b43_phy_read(dev, B43_LPPHY_TABLEDATALO);
+ break;
+ case B43_LPTAB_32BIT:
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ value = b43_phy_read(dev, B43_LPPHY_TABLEDATAHI);
+ value <<= 16;
+ value |= b43_phy_read(dev, B43_LPPHY_TABLEDATALO);
+ break;
+ default:
+ B43_WARN_ON(1);
+ value = 0;
+ }
+
+ return value;
+}
+
+void b43_lptab_read_bulk(struct b43_wldev *dev, u32 offset,
+ unsigned int nr_elements, void *_data)
+{
+ u32 type, value;
+ u8 *data = _data;
+ unsigned int i;
+
+ type = offset & B43_LPTAB_TYPEMASK;
+ for (i = 0; i < nr_elements; i++) {
+ value = b43_lptab_read(dev, offset);
+ switch (type) {
+ case B43_LPTAB_8BIT:
+ *data = value;
+ data++;
+ break;
+ case B43_LPTAB_16BIT:
+ *((u16 *)data) = value;
+ data += 2;
+ break;
+ case B43_LPTAB_32BIT:
+ *((u32 *)data) = value;
+ data += 4;
+ break;
+ default:
+ B43_WARN_ON(1);
+ }
+ offset++;
+ }
+}
+
+void b43_lptab_write(struct b43_wldev *dev, u32 offset, u32 value)
+{
+ u32 type;
+
+ type = offset & B43_LPTAB_TYPEMASK;
+ offset &= ~B43_LPTAB_TYPEMASK;
+ B43_WARN_ON(offset > 0xFFFF);
+
+ switch (type) {
+ case B43_LPTAB_8BIT:
+ B43_WARN_ON(value & ~0xFF);
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
+ break;
+ case B43_LPTAB_16BIT:
+ B43_WARN_ON(value & ~0xFFFF);
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
+ break;
+ case B43_LPTAB_32BIT:
+ b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+ b43_phy_write(dev, B43_LPPHY_TABLEDATAHI, value >> 16);
+ b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
+ break;
+ default:
+ B43_WARN_ON(1);
+ }
+}
+
+void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset,
+ unsigned int nr_elements, const void *_data)
+{
+ u32 type, value;
+ const u8 *data = _data;
+ unsigned int i;
+
+ type = offset & B43_LPTAB_TYPEMASK;
+ for (i = 0; i < nr_elements; i++) {
+ switch (type) {
+ case B43_LPTAB_8BIT:
+ value = *data;
+ data++;
+ break;
+ case B43_LPTAB_16BIT:
+ value = *((u16 *)data);
+ data += 2;
+ break;
+ case B43_LPTAB_32BIT:
+ value = *((u32 *)data);
+ data += 4;
+ break;
+ default:
+ B43_WARN_ON(1);
+ value = 0;
+ }
+ b43_lptab_write(dev, offset, value);
+ offset++;
+ }
+}
diff --git a/drivers/net/wireless/b43/tables_lpphy.h b/drivers/net/wireless/b43/tables_lpphy.h
new file mode 100644
index 000000000000..0b8d02895a5d
--- /dev/null
+++ b/drivers/net/wireless/b43/tables_lpphy.h
@@ -0,0 +1,31 @@
+#ifndef B43_TABLES_LPPHY_H_
+#define B43_TABLES_LPPHY_H_
+
+
+#define B43_LPTAB_TYPEMASK 0xF0000000
+#define B43_LPTAB_8BIT 0x10000000
+#define B43_LPTAB_16BIT 0x20000000
+#define B43_LPTAB_32BIT 0x30000000
+#define B43_LPTAB8(table, offset) (((table) << 10) | (offset) | B43_LPTAB_8BIT)
+#define B43_LPTAB16(table, offset) (((table) << 10) | (offset) | B43_LPTAB_16BIT)
+#define B43_LPTAB32(table, offset) (((table) << 10) | (offset) | B43_LPTAB_32BIT)
+
+/* Table definitions */
+#define B43_LPTAB_TXPWR_R2PLUS B43_LPTAB32(0x07, 0) /* TX power lookup table (rev >= 2) */
+#define B43_LPTAB_TXPWR_R0_1 B43_LPTAB32(0xA0, 0) /* TX power lookup table (rev < 2) */
+
+u32 b43_lptab_read(struct b43_wldev *dev, u32 offset);
+void b43_lptab_write(struct b43_wldev *dev, u32 offset, u32 value);
+
+/* Bulk table access. Note that these functions return the bulk data in
+ * host endianness! The returned data is _not_ a bytearray, but an array
+ * consisting of nr_elements of the data type. */
+void b43_lptab_read_bulk(struct b43_wldev *dev, u32 offset,
+ unsigned int nr_elements, void *data);
+void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset,
+ unsigned int nr_elements, const void *data);
+
+void b2062_upload_init_table(struct b43_wldev *dev);
+
+
+#endif /* B43_TABLES_LPPHY_H_ */
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c
index 0c0fb15abb9f..e1e20f69f6d7 100644
--- a/drivers/net/wireless/b43/wa.c
+++ b/drivers/net/wireless/b43/wa.c
@@ -62,8 +62,7 @@ void b43_wa_initgains(struct b43_wldev *dev)
struct b43_phy *phy = &dev->phy;
b43_phy_write(dev, B43_PHY_LNAHPFCTL, 0x1FF9);
- b43_phy_write(dev, B43_PHY_LPFGAINCTL,
- b43_phy_read(dev, B43_PHY_LPFGAINCTL) & 0xFF0F);
+ b43_phy_mask(dev, B43_PHY_LPFGAINCTL, 0xFF0F);
if (phy->rev <= 2)
b43_ofdmtab_write16(dev, B43_OFDMTAB_LPFGAIN, 0, 0x1FBF);
b43_radio_write16(dev, 0x0002, 0x1FBF);
@@ -73,11 +72,9 @@ void b43_wa_initgains(struct b43_wldev *dev)
b43_phy_write(dev, 0x001D, 0x0F40);
b43_phy_write(dev, 0x001F, 0x1C00);
if (phy->rev <= 3)
- b43_phy_write(dev, 0x002A,
- (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x0400);
+ b43_phy_maskset(dev, 0x002A, 0x00FF, 0x0400);
else if (phy->rev == 5) {
- b43_phy_write(dev, 0x002A,
- (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x1A00);
+ b43_phy_maskset(dev, 0x002A, 0x00FF, 0x1A00);
b43_phy_write(dev, 0x00CC, 0x2121);
}
if (phy->rev >= 3)
@@ -86,7 +83,7 @@ void b43_wa_initgains(struct b43_wldev *dev)
static void b43_wa_divider(struct b43_wldev *dev)
{
- b43_phy_write(dev, 0x002B, b43_phy_read(dev, 0x002B) & ~0x0100);
+ b43_phy_mask(dev, 0x002B, ~0x0100);
b43_phy_write(dev, 0x008E, 0x58C1);
}
@@ -272,8 +269,7 @@ static void b43_wa_2060txlna_gain(struct b43_wldev *dev)
static void b43_wa_lms(struct b43_wldev *dev)
{
- b43_phy_write(dev, 0x0055,
- (b43_phy_read(dev, 0x0055) & 0xFFC0) | 0x0004);
+ b43_phy_maskset(dev, 0x0055, 0xFFC0, 0x0004);
}
static void b43_wa_mixedsignal(struct b43_wldev *dev)
@@ -318,23 +314,18 @@ static void b43_wa_crs_ed(struct b43_wldev *dev)
} else if (phy->rev == 2) {
b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x1861);
b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0271);
- b43_phy_write(dev, B43_PHY_ANTDWELL,
- b43_phy_read(dev, B43_PHY_ANTDWELL)
- | 0x0800);
+ b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800);
} else {
b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x0098);
b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0070);
b43_phy_write(dev, B43_PHY_OFDM(0xC9), 0x0080);
- b43_phy_write(dev, B43_PHY_ANTDWELL,
- b43_phy_read(dev, B43_PHY_ANTDWELL)
- | 0x0800);
+ b43_phy_set(dev, B43_PHY_ANTDWELL, 0x0800);
}
}
static void b43_wa_crs_thr(struct b43_wldev *dev)
{
- b43_phy_write(dev, B43_PHY_CRS0,
- (b43_phy_read(dev, B43_PHY_CRS0) & ~0x03C0) | 0xD000);
+ b43_phy_maskset(dev, B43_PHY_CRS0, ~0x03C0, 0xD000);
}
static void b43_wa_crs_blank(struct b43_wldev *dev)
@@ -391,72 +382,45 @@ static void b43_wa_altagc(struct b43_wldev *dev)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25);
}
- b43_phy_write(dev, B43_PHY_CCKSHIFTBITS_WA,
- (b43_phy_read(dev, B43_PHY_CCKSHIFTBITS_WA) & ~0xFF00) | 0x5700);
- b43_phy_write(dev, B43_PHY_OFDM(0x1A),
- (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x007F) | 0x000F);
- b43_phy_write(dev, B43_PHY_OFDM(0x1A),
- (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x3F80) | 0x2B80);
- b43_phy_write(dev, B43_PHY_ANTWRSETT,
- (b43_phy_read(dev, B43_PHY_ANTWRSETT) & 0xF0FF) | 0x0300);
- b43_radio_write16(dev, 0x7A,
- b43_radio_read16(dev, 0x7A) | 0x0008);
- b43_phy_write(dev, B43_PHY_N1P1GAIN,
- (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x000F) | 0x0008);
- b43_phy_write(dev, B43_PHY_P1P2GAIN,
- (b43_phy_read(dev, B43_PHY_P1P2GAIN) & ~0x0F00) | 0x0600);
- b43_phy_write(dev, B43_PHY_N1N2GAIN,
- (b43_phy_read(dev, B43_PHY_N1N2GAIN) & ~0x0F00) | 0x0700);
- b43_phy_write(dev, B43_PHY_N1P1GAIN,
- (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x0F00) | 0x0100);
+ b43_phy_maskset(dev, B43_PHY_CCKSHIFTBITS_WA, (u16)~0xFF00, 0x5700);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x007F, 0x000F);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x1A), ~0x3F80, 0x2B80);
+ b43_phy_maskset(dev, B43_PHY_ANTWRSETT, 0xF0FF, 0x0300);
+ b43_radio_set(dev, 0x7A, 0x0008);
+ b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x000F, 0x0008);
+ b43_phy_maskset(dev, B43_PHY_P1P2GAIN, ~0x0F00, 0x0600);
+ b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x0F00, 0x0700);
+ b43_phy_maskset(dev, B43_PHY_N1P1GAIN, ~0x0F00, 0x0100);
if (phy->rev == 1) {
- b43_phy_write(dev, B43_PHY_N1N2GAIN,
- (b43_phy_read(dev, B43_PHY_N1N2GAIN)
- & ~0x000F) | 0x0007);
+ b43_phy_maskset(dev, B43_PHY_N1N2GAIN, ~0x000F, 0x0007);
}
- b43_phy_write(dev, B43_PHY_OFDM(0x88),
- (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x00FF) | 0x001C);
- b43_phy_write(dev, B43_PHY_OFDM(0x88),
- (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x3F00) | 0x0200);
- b43_phy_write(dev, B43_PHY_OFDM(0x96),
- (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0x00FF) | 0x001C);
- b43_phy_write(dev, B43_PHY_OFDM(0x89),
- (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x00FF) | 0x0020);
- b43_phy_write(dev, B43_PHY_OFDM(0x89),
- (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x3F00) | 0x0200);
- b43_phy_write(dev, B43_PHY_OFDM(0x82),
- (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & ~0x00FF) | 0x002E);
- b43_phy_write(dev, B43_PHY_OFDM(0x96),
- (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0xFF00) | 0x1A00);
- b43_phy_write(dev, B43_PHY_OFDM(0x81),
- (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0x00FF) | 0x0028);
- b43_phy_write(dev, B43_PHY_OFDM(0x81),
- (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0xFF00) | 0x2C00);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x00FF, 0x001C);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x88), ~0x3F00, 0x0200);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x96), ~0x00FF, 0x001C);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x00FF, 0x0020);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x89), ~0x3F00, 0x0200);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x82), ~0x00FF, 0x002E);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x96), (u16)~0xFF00, 0x1A00);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x81), ~0x00FF, 0x0028);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x81), (u16)~0xFF00, 0x2C00);
if (phy->rev == 1) {
b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B);
- b43_phy_write(dev, B43_PHY_OFDM(0x1B),
- (b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E) | 0x0002);
+ b43_phy_maskset(dev, B43_PHY_OFDM(0x1B), ~0x001E, 0x0002);
} else {
- b43_phy_write(dev, B43_PHY_OFDM(0x1B),
- b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E);
+ b43_phy_mask(dev, B43_PHY_OFDM(0x1B), ~0x001E);
b43_phy_write(dev, B43_PHY_OFDM(0x1F), 0x287A);
- b43_phy_write(dev, B43_PHY_LPFGAINCTL,
- (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0x000F) | 0x0004);
+ b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, ~0x000F, 0x0004);
if (phy->rev >= 6) {
b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A);
- b43_phy_write(dev, B43_PHY_LPFGAINCTL,
- (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0xF000) | 0x3000);
+ b43_phy_maskset(dev, B43_PHY_LPFGAINCTL, (u16)~0xF000, 0x3000);
}
}
- b43_phy_write(dev, B43_PHY_DIVSRCHIDX,
- (b43_phy_read(dev, B43_PHY_DIVSRCHIDX) & 0x8080) | 0x7874);
+ b43_phy_maskset(dev, B43_PHY_DIVSRCHIDX, 0x8080, 0x7874);
b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x1C00);
if (phy->rev == 1) {
- b43_phy_write(dev, B43_PHY_DIVP1P2GAIN,
- (b43_phy_read(dev, B43_PHY_DIVP1P2GAIN) & ~0x0F00) | 0x0600);
+ b43_phy_maskset(dev, B43_PHY_DIVP1P2GAIN, ~0x0F00, 0x0600);
b43_phy_write(dev, B43_PHY_OFDM(0x8B), 0x005E);
- b43_phy_write(dev, B43_PHY_ANTWRSETT,
- (b43_phy_read(dev, B43_PHY_ANTWRSETT) & ~0x00FF) | 0x001E);
+ b43_phy_maskset(dev, B43_PHY_ANTWRSETT, ~0x00FF, 0x001E);
b43_phy_write(dev, B43_PHY_OFDM(0x8D), 0x0002);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 0, 0);
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 1, 7);
@@ -469,10 +433,8 @@ static void b43_wa_altagc(struct b43_wldev *dev)
b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 3, 28);
}
if (phy->rev >= 6) {
- b43_phy_write(dev, B43_PHY_OFDM(0x26),
- b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x0003);
- b43_phy_write(dev, B43_PHY_OFDM(0x26),
- b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x1000);
+ b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x0003);
+ b43_phy_mask(dev, B43_PHY_OFDM(0x26), ~0x1000);
}
b43_phy_read(dev, B43_PHY_VERSION_OFDM); /* Dummy read */
}
@@ -538,8 +500,7 @@ static void b43_wa_boards_g(struct b43_wldev *dev)
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001);
if ((bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
(phy->rev >= 7)) {
- b43_phy_write(dev, B43_PHY_EXTG(0x11),
- b43_phy_read(dev, B43_PHY_EXTG(0x11)) & 0xF7FF);
+ b43_phy_mask(dev, B43_PHY_EXTG(0x11), 0xF7FF);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0021, 0x0001);
b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0022, 0x0001);
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index eae9b8052658..a63d88841df8 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -50,7 +50,7 @@ static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
}
/* Extract the bitrate index out of an OFDM PLCP header. */
-static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
+static int b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
{
int base = aphy ? 0 : 4;
@@ -538,8 +538,14 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
chanstat = le16_to_cpu(rxhdr->channel);
phytype = chanstat & B43_RX_CHAN_PHYTYPE;
- if (macstat & B43_RX_MAC_FCSERR)
+ if (unlikely(macstat & B43_RX_MAC_FCSERR)) {
dev->wl->ieee_stats.dot11FCSErrorCount++;
+ status.flag |= RX_FLAG_FAILED_FCS_CRC;
+ }
+ if (unlikely(phystat0 & (B43_RX_PHYST0_PLCPHCF | B43_RX_PHYST0_PLCPFV)))
+ status.flag |= RX_FLAG_FAILED_PLCP_CRC;
+ if (phystat0 & B43_RX_PHYST0_SHORTPRMBL)
+ status.flag |= RX_FLAG_SHORTPRE;
if (macstat & B43_RX_MAC_DECERR) {
/* Decryption with the given key failed.
* Drop the packet. We also won't be able to decrypt it with
@@ -606,8 +612,12 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
phytype == B43_PHYTYPE_A);
else
status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
- if (unlikely(status.rate_idx == -1))
- goto drop;
+ if (unlikely(status.rate_idx == -1)) {
+ /* PLCP seems to be corrupted.
+ * Drop the frame, if we are not interested in corrupted frames. */
+ if (!(dev->wl->filter_flags & FIF_PLCPFAIL))
+ goto drop;
+ }
status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
/*
@@ -661,7 +671,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
goto drop;
}
- dev->stats.last_rx = jiffies;
ieee80211_rx_irqsafe(dev->wl->hw, skb, &status);
return;
diff --git a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c
index cacb786d9713..3ea55b18c700 100644
--- a/drivers/net/wireless/b43legacy/leds.c
+++ b/drivers/net/wireless/b43legacy/leds.c
@@ -146,12 +146,12 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev,
case B43legacy_LED_TRANSFER:
case B43legacy_LED_APTRANSFER:
snprintf(name, sizeof(name),
- "b43legacy-%s:tx", wiphy_name(hw->wiphy));
+ "b43legacy-%s::tx", wiphy_name(hw->wiphy));
b43legacy_register_led(dev, &dev->led_tx, name,
ieee80211_get_tx_led_name(hw),
led_index, activelow);
snprintf(name, sizeof(name),
- "b43legacy-%s:rx", wiphy_name(hw->wiphy));
+ "b43legacy-%s::rx", wiphy_name(hw->wiphy));
b43legacy_register_led(dev, &dev->led_rx, name,
ieee80211_get_rx_led_name(hw),
led_index, activelow);
@@ -161,7 +161,7 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev,
case B43legacy_LED_RADIO_B:
case B43legacy_LED_MODE_BG:
snprintf(name, sizeof(name),
- "b43legacy-%s:radio", wiphy_name(hw->wiphy));
+ "b43legacy-%s::radio", wiphy_name(hw->wiphy));
b43legacy_register_led(dev, &dev->led_radio, name,
b43legacy_rfkill_led_name(dev),
led_index, activelow);
@@ -172,7 +172,7 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev,
case B43legacy_LED_WEIRD:
case B43legacy_LED_ASSOC:
snprintf(name, sizeof(name),
- "b43legacy-%s:assoc", wiphy_name(hw->wiphy));
+ "b43legacy-%s::assoc", wiphy_name(hw->wiphy));
b43legacy_register_led(dev, &dev->led_assoc, name,
ieee80211_get_assoc_led_name(hw),
led_index, activelow);
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index fb996c27a19b..879edc786713 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2650,7 +2650,7 @@ out_unlock_mutex:
return err;
}
-static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u64 brates)
+static void b43legacy_update_basic_rates(struct b43legacy_wldev *dev, u32 brates)
{
struct ieee80211_supported_band *sband =
dev->wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index 2453deaa3e00..ce8721fbc10e 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -31,7 +31,7 @@ void hostap_dump_rx_header(const char *name,
void hostap_dump_tx_header(const char *name,
const struct hfa384x_tx_frame *tx);
extern const struct header_ops hostap_80211_ops;
-int hostap_80211_get_hdrlen(u16 fc);
+int hostap_80211_get_hdrlen(__le16 fc);
struct net_device_stats *hostap_get_stats(struct net_device *dev);
void hostap_setup_dev(struct net_device *dev, local_info_t *local,
int type);
diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h
index 3a9474d9a907..2e9fb0f383fc 100644
--- a/drivers/net/wireless/hostap/hostap_80211.h
+++ b/drivers/net/wireless/hostap/hostap_80211.h
@@ -2,7 +2,7 @@
#define HOSTAP_80211_H
#include <linux/types.h>
-#include <net/ieee80211.h>
+#include <linux/skbuff.h>
struct hostap_ieee80211_mgmt {
__le16 frame_control;
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index 19b1bf0478bd..3816df96a663 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -1,5 +1,6 @@
#include <linux/etherdevice.h>
#include <net/lib80211.h>
+#include <linux/if_arp.h>
#include "hostap_80211.h"
#include "hostap.h"
@@ -17,10 +18,10 @@ static unsigned char bridge_tunnel_header[] =
void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
u16 fc;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d "
"jiffies=%ld\n",
@@ -30,9 +31,10 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
if (skb->len < 2)
return;
- fc = le16_to_cpu(hdr->frame_ctl);
+ fc = le16_to_cpu(hdr->frame_control);
printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s",
- fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
+ fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
+ (fc & IEEE80211_FCTL_STYPE) >> 4,
fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
@@ -42,7 +44,7 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
}
printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
- le16_to_cpu(hdr->seq_ctl));
+ le16_to_cpu(hdr->seq_ctrl));
printk(KERN_DEBUG " A1=%pM", hdr->addr1);
printk(" A2=%pM", hdr->addr2);
@@ -63,7 +65,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
int hdrlen, phdrlen, head_need, tail_need;
u16 fc;
int prism_header, ret;
- struct ieee80211_hdr_4addr *fhdr;
+ struct ieee80211_hdr *fhdr;
iface = netdev_priv(dev);
local = iface->local;
@@ -84,8 +86,8 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
phdrlen = 0;
}
- fhdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(fhdr->frame_ctl);
+ fhdr = (struct ieee80211_hdr *) skb->data;
+ fc = le16_to_cpu(fhdr->frame_control);
if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
printk(KERN_DEBUG "%s: dropped management frame with header "
@@ -94,7 +96,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
return 0;
}
- hdrlen = hostap_80211_get_hdrlen(fc);
+ hdrlen = hostap_80211_get_hdrlen(fhdr->frame_control);
/* check if there is enough room for extra data; if not, expand skb
* buffer to be large enough for the changes */
@@ -193,7 +195,7 @@ hdr->f.status = s; hdr->f.len = l; hdr->f.data = d
if (prism_header)
skb_pull(skb, phdrlen);
skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = __constant_htons(ETH_P_802_2);
+ skb->protocol = cpu_to_be16(ETH_P_802_2);
memset(skb->cb, 0, sizeof(skb->cb));
netif_rx(skb);
@@ -205,13 +207,11 @@ hdr->f.status = s; hdr->f.len = l; hdr->f.data = d
static void monitor_rx(struct net_device *dev, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
- struct net_device_stats *stats;
int len;
len = prism2_rx_80211(dev, skb, rx_stats, PRISM2_RX_MONITOR);
- stats = hostap_get_stats(dev);
- stats->rx_packets++;
- stats->rx_bytes += len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += len;
}
@@ -247,21 +247,21 @@ prism2_frag_cache_find(local_info_t *local, unsigned int seq,
/* Called only as a tasklet (software IRQ) */
static struct sk_buff *
-prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
+prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
{
struct sk_buff *skb = NULL;
u16 sc;
unsigned int frag, seq;
struct prism2_frag_entry *entry;
- sc = le16_to_cpu(hdr->seq_ctl);
- frag = WLAN_GET_SEQ_FRAG(sc);
- seq = WLAN_GET_SEQ_SEQ(sc) >> 4;
+ sc = le16_to_cpu(hdr->seq_ctrl);
+ frag = sc & IEEE80211_SCTL_FRAG;
+ seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
if (frag == 0) {
/* Reserve enough space to fit maximum frame length */
skb = dev_alloc_skb(local->dev->mtu +
- sizeof(struct ieee80211_hdr_4addr) +
+ sizeof(struct ieee80211_hdr) +
8 /* LLC */ +
2 /* alignment */ +
8 /* WEP */ + ETH_ALEN /* WDS */);
@@ -299,14 +299,14 @@ prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
/* Called only as a tasklet (software IRQ) */
static int prism2_frag_cache_invalidate(local_info_t *local,
- struct ieee80211_hdr_4addr *hdr)
+ struct ieee80211_hdr *hdr)
{
u16 sc;
unsigned int seq;
struct prism2_frag_entry *entry;
- sc = le16_to_cpu(hdr->seq_ctl);
- seq = WLAN_GET_SEQ_SEQ(sc) >> 4;
+ sc = le16_to_cpu(hdr->seq_ctrl);
+ seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
entry = prism2_frag_cache_find(local, seq, -1, hdr->addr2, hdr->addr1);
@@ -472,10 +472,8 @@ hostap_rx_frame_mgmt(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats, u16 type,
u16 stype)
{
- if (local->iw_mode == IW_MODE_MASTER) {
- hostap_update_sta_ps(local, (struct ieee80211_hdr_4addr *)
- skb->data);
- }
+ if (local->iw_mode == IW_MODE_MASTER)
+ hostap_update_sta_ps(local, (struct ieee80211_hdr *) skb->data);
if (local->hostapd && type == IEEE80211_FTYPE_MGMT) {
if (stype == IEEE80211_STYPE_BEACON &&
@@ -552,8 +550,8 @@ static struct net_device *prism2_rx_get_wds(local_info_t *local,
static int
-hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
- u16 fc, struct net_device **wds)
+hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr, u16 fc,
+ struct net_device **wds)
{
/* FIX: is this really supposed to accept WDS frames only in Master
* mode? What about Repeater or Managed with WDS frames? */
@@ -611,14 +609,14 @@ static int hostap_is_eapol_frame(local_info_t *local, struct sk_buff *skb)
{
struct net_device *dev = local->dev;
u16 fc, ethertype;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
u8 *pos;
if (skb->len < 24)
return 0;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
+ hdr = (struct ieee80211_hdr *) skb->data;
+ fc = le16_to_cpu(hdr->frame_control);
/* check that the frame is unicast frame to us */
if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
@@ -651,14 +649,14 @@ static int
hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
struct lib80211_crypt_data *crypt)
{
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+ hdr = (struct ieee80211_hdr *) skb->data;
+ hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
if (local->tkip_countermeasures &&
strcmp(crypt->ops->name, "TKIP") == 0) {
@@ -689,14 +687,14 @@ static int
hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
int keyidx, struct lib80211_crypt_data *crypt)
{
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
int res, hdrlen;
if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
return 0;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+ hdr = (struct ieee80211_hdr *) skb->data;
+ hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
atomic_inc(&crypt->refcnt);
res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
@@ -720,11 +718,10 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
{
struct hostap_interface *iface;
local_info_t *local;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
size_t hdrlen;
u16 fc, type, stype, sc;
struct net_device *wds = NULL;
- struct net_device_stats *stats;
unsigned int frag;
u8 *payload;
struct sk_buff *skb2 = NULL;
@@ -747,18 +744,17 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
dev = local->ddev;
iface = netdev_priv(dev);
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- stats = hostap_get_stats(dev);
+ hdr = (struct ieee80211_hdr *) skb->data;
if (skb->len < 10)
goto rx_dropped;
- fc = le16_to_cpu(hdr->frame_ctl);
- type = WLAN_FC_GET_TYPE(fc);
- stype = WLAN_FC_GET_STYPE(fc);
- sc = le16_to_cpu(hdr->seq_ctl);
- frag = WLAN_GET_SEQ_FRAG(sc);
- hdrlen = hostap_80211_get_hdrlen(fc);
+ fc = le16_to_cpu(hdr->frame_control);
+ type = fc & IEEE80211_FCTL_FTYPE;
+ stype = fc & IEEE80211_FCTL_STYPE;
+ sc = le16_to_cpu(hdr->seq_ctrl);
+ frag = sc & IEEE80211_SCTL_FRAG;
+ hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
/* Put this code here so that we avoid duplicating it in all
* Rx paths. - Jean II */
@@ -866,10 +862,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
if (hostap_rx_frame_wds(local, hdr, fc, &wds))
goto rx_dropped;
- if (wds) {
+ if (wds)
skb->dev = dev = wds;
- stats = hostap_get_stats(dev);
- }
if (local->iw_mode == IW_MODE_MASTER && !wds &&
(fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
@@ -878,7 +872,6 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
memcmp(hdr->addr2, local->assoc_ap_addr, ETH_ALEN) == 0) {
/* Frame from BSSID of the AP for which we are a client */
skb->dev = dev = local->stadev;
- stats = hostap_get_stats(dev);
from_assoc_ap = 1;
}
@@ -918,7 +911,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
(keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
goto rx_dropped;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
/* skb: hdr + (possibly fragmented) plaintext payload */
@@ -931,7 +924,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
printk(KERN_DEBUG "%s: Rx cannot get skb from "
"fragment cache (morefrag=%d seq=%u frag=%u)\n",
dev->name, (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
- WLAN_GET_SEQ_SEQ(sc) >> 4, frag);
+ (sc & IEEE80211_SCTL_SEQ) >> 4, frag);
goto rx_dropped;
}
@@ -972,7 +965,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
/* this was the last fragment and the frame will be
* delivered, so remove skb from fragment cache */
skb = frag_skb;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
prism2_frag_cache_invalidate(local, hdr);
}
@@ -983,7 +976,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
goto rx_dropped;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !local->open_wep) {
if (local->ieee_802_1x &&
hostap_is_eapol_frame(local, skb)) {
@@ -1069,8 +1062,8 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
skb_trim(skb, skb->len - ETH_ALEN);
}
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
if (local->iw_mode == IW_MODE_MASTER && !wds &&
local->ap->bridge_packets) {
@@ -1094,7 +1087,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
if (skb2 != NULL) {
/* send to wireless media */
skb2->dev = dev;
- skb2->protocol = __constant_htons(ETH_P_802_3);
+ skb2->protocol = cpu_to_be16(ETH_P_802_3);
skb_reset_mac_header(skb2);
skb_reset_network_header(skb2);
/* skb2->network_header += ETH_HLEN; */
@@ -1115,7 +1108,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
rx_dropped:
dev_kfree_skb(skb);
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
goto rx_exit;
}
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 078a010f39a0..6693423f63fe 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -15,10 +15,10 @@ static unsigned char bridge_tunnel_header[] =
void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
{
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
u16 fc;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n",
name, skb->len, jiffies);
@@ -26,9 +26,10 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
if (skb->len < 2)
return;
- fc = le16_to_cpu(hdr->frame_ctl);
+ fc = le16_to_cpu(hdr->frame_control);
printk(KERN_DEBUG " FC=0x%04x (type=%d:%d)%s%s",
- fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
+ fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
+ (fc & IEEE80211_FCTL_STYPE) >> 4,
fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
fc & IEEE80211_FCTL_FROMDS ? " [FromDS]" : "");
@@ -38,7 +39,7 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
}
printk(" dur=0x%04x seq=0x%04x\n", le16_to_cpu(hdr->duration_id),
- le16_to_cpu(hdr->seq_ctl));
+ le16_to_cpu(hdr->seq_ctrl));
printk(KERN_DEBUG " A1=%pM", hdr->addr1);
printk(" A2=%pM", hdr->addr2);
@@ -57,7 +58,7 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct hostap_interface *iface;
local_info_t *local;
int need_headroom, need_tailroom = 0;
- struct ieee80211_hdr_4addr hdr;
+ struct ieee80211_hdr hdr;
u16 fc, ethertype = 0;
enum {
WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
@@ -201,7 +202,7 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
memcpy(&hdr.addr3, local->bssid, ETH_ALEN);
}
- hdr.frame_ctl = cpu_to_le16(fc);
+ hdr.frame_control = cpu_to_le16(fc);
skb_pull(skb, skip_header_bytes);
need_headroom = local->func->need_tx_headroom + hdr_len + encaps_len;
@@ -265,7 +266,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct hostap_interface *iface;
local_info_t *local;
struct hostap_skb_tx_data *meta;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
u16 fc;
iface = netdev_priv(dev);
@@ -287,10 +288,10 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
meta->iface = iface;
if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) {
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
- if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
- WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_DATA) {
+ hdr = (struct ieee80211_hdr *) skb->data;
+ fc = le16_to_cpu(hdr->frame_control);
+ if (ieee80211_is_data(hdr->frame_control) &&
+ (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DATA) {
u8 *pos = &skb->data[IEEE80211_DATA_HDR3_LEN +
sizeof(rfc1042_header)];
meta->ethertype = (pos[0] << 8) | pos[1];
@@ -310,8 +311,7 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
{
struct hostap_interface *iface;
local_info_t *local;
- struct ieee80211_hdr_4addr *hdr;
- u16 fc;
+ struct ieee80211_hdr *hdr;
int prefix_len, postfix_len, hdr_len, res;
iface = netdev_priv(skb->dev);
@@ -324,7 +324,7 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
if (local->tkip_countermeasures &&
strcmp(crypt->ops->name, "TKIP") == 0) {
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
"TX packet to %pM\n",
@@ -349,9 +349,8 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
return NULL;
}
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
- hdr_len = hostap_80211_get_hdrlen(fc);
+ hdr = (struct ieee80211_hdr *) skb->data;
+ hdr_len = hostap_80211_get_hdrlen(hdr->frame_control);
/* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
* call both MSDU and MPDU encryption functions from here. */
@@ -384,7 +383,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
ap_tx_ret tx_ret;
struct hostap_skb_tx_data *meta;
int no_encrypt = 0;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
iface = netdev_priv(dev);
local = iface->local;
@@ -427,14 +426,14 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_ret = hostap_handle_sta_tx(local, &tx);
skb = tx.skb;
meta = (struct hostap_skb_tx_data *) skb->cb;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
+ hdr = (struct ieee80211_hdr *) skb->data;
+ fc = le16_to_cpu(hdr->frame_control);
switch (tx_ret) {
case AP_TX_CONTINUE:
break;
case AP_TX_CONTINUE_NOT_AUTHORIZED:
if (local->ieee_802_1x &&
- WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
+ ieee80211_is_data(hdr->frame_control) &&
meta->ethertype != ETH_P_PAE &&
!(meta->flags & HOSTAP_TX_FLAGS_WDS)) {
printk(KERN_DEBUG "%s: dropped frame to unauthorized "
@@ -469,10 +468,10 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* remove special version from the frame header */
fc &= ~IEEE80211_FCTL_VERS;
- hdr->frame_ctl = cpu_to_le16(fc);
+ hdr->frame_control = cpu_to_le16(fc);
}
- if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_DATA) {
+ if (!ieee80211_is_data(hdr->frame_control)) {
no_encrypt = 1;
tx.crypt = NULL;
}
@@ -493,9 +492,9 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Add ISWEP flag both for firmware and host based encryption
*/
fc |= IEEE80211_FCTL_PROTECTED;
- hdr->frame_ctl = cpu_to_le16(fc);
+ hdr->frame_control = cpu_to_le16(fc);
} else if (local->drop_unencrypted &&
- WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
+ ieee80211_is_data(hdr->frame_control) &&
meta->ethertype != ETH_P_PAE) {
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: dropped unencrypted TX data "
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 0903db786d5f..a2a203c90ba3 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -19,6 +19,7 @@
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/random.h>
+#include <linux/if_arp.h>
#include "hostap_wlan.h"
#include "hostap.h"
@@ -588,28 +589,24 @@ void hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver)
static void hostap_ap_tx_cb(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
- u16 fc;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
if (!ap->local->hostapd || !ap->local->apdev) {
dev_kfree_skb(skb);
return;
}
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
-
/* Pass the TX callback frame to the hostapd; use 802.11 header version
* 1 to indicate failure (no ACK) and 2 success (frame ACKed) */
- fc &= ~IEEE80211_FCTL_VERS;
- fc |= ok ? BIT(1) : BIT(0);
- hdr->frame_ctl = cpu_to_le16(fc);
+ hdr = (struct ieee80211_hdr *) skb->data;
+ hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_VERS);
+ hdr->frame_control |= cpu_to_le16(ok ? BIT(1) : BIT(0));
skb->dev = ap->local->apdev;
- skb_pull(skb, hostap_80211_get_hdrlen(fc));
+ skb_pull(skb, hostap_80211_get_hdrlen(hdr->frame_control));
skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = __constant_htons(ETH_P_802_2);
+ skb->protocol = cpu_to_be16(ETH_P_802_2);
memset(skb->cb, 0, sizeof(skb->cb));
netif_rx(skb);
}
@@ -621,8 +618,8 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
struct net_device *dev = ap->local->dev;
- struct ieee80211_hdr_4addr *hdr;
- u16 fc, auth_alg, auth_transaction, status;
+ struct ieee80211_hdr *hdr;
+ u16 auth_alg, auth_transaction, status;
__le16 *pos;
struct sta_info *sta = NULL;
char *txt = NULL;
@@ -632,10 +629,8 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
return;
}
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
- if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
- WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_AUTH ||
+ hdr = (struct ieee80211_hdr *) skb->data;
+ if (!ieee80211_is_auth(hdr->frame_control) ||
skb->len < IEEE80211_MGMT_HDR_LEN + 6) {
printk(KERN_DEBUG "%s: hostap_ap_tx_cb_auth received invalid "
"frame\n", dev->name);
@@ -691,7 +686,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
struct net_device *dev = ap->local->dev;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
u16 fc, status;
__le16 *pos;
struct sta_info *sta = NULL;
@@ -702,11 +697,10 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
return;
}
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
- if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
- (WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_ASSOC_RESP &&
- WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_REASSOC_RESP) ||
+ hdr = (struct ieee80211_hdr *) skb->data;
+ fc = le16_to_cpu(hdr->frame_control);
+ if ((!ieee80211_is_assoc_resp(hdr->frame_control) &&
+ !ieee80211_is_reassoc_resp(hdr->frame_control)) ||
skb->len < IEEE80211_MGMT_HDR_LEN + 4) {
printk(KERN_DEBUG "%s: hostap_ap_tx_cb_assoc received invalid "
"frame\n", dev->name);
@@ -757,12 +751,12 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
{
struct ap_data *ap = data;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
struct sta_info *sta;
if (skb->len < 24)
goto fail;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
if (ok) {
spin_lock(&ap->sta_table_lock);
sta = ap_get_sta(ap, hdr->addr1);
@@ -917,7 +911,7 @@ static void prism2_send_mgmt(struct net_device *dev,
{
struct hostap_interface *iface;
local_info_t *local;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
u16 fc;
struct sk_buff *skb;
struct hostap_skb_tx_data *meta;
@@ -942,8 +936,8 @@ static void prism2_send_mgmt(struct net_device *dev,
}
fc = type_subtype;
- hdrlen = hostap_80211_get_hdrlen(fc);
- hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, hdrlen);
+ hdrlen = hostap_80211_get_hdrlen(cpu_to_le16(type_subtype));
+ hdr = (struct ieee80211_hdr *) skb_put(skb, hdrlen);
if (body)
memcpy(skb_put(skb, body_len), body, body_len);
@@ -954,11 +948,11 @@ static void prism2_send_mgmt(struct net_device *dev,
memcpy(hdr->addr1, addr, ETH_ALEN); /* DA / RA */
- if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) {
+ if (ieee80211_is_data(hdr->frame_control)) {
fc |= IEEE80211_FCTL_FROMDS;
memcpy(hdr->addr2, dev->dev_addr, ETH_ALEN); /* BSSID */
memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* SA */
- } else if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_CTL) {
+ } else if (ieee80211_is_ctl(hdr->frame_control)) {
/* control:ACK does not have addr2 or addr3 */
memset(hdr->addr2, 0, ETH_ALEN);
memset(hdr->addr3, 0, ETH_ALEN);
@@ -967,7 +961,7 @@ static void prism2_send_mgmt(struct net_device *dev,
memcpy(hdr->addr3, dev->dev_addr, ETH_ALEN); /* BSSID */
}
- hdr->frame_ctl = cpu_to_le16(fc);
+ hdr->frame_control = cpu_to_le16(fc);
meta = (struct hostap_skb_tx_data *) skb->cb;
memset(meta, 0, sizeof(*meta));
@@ -1284,22 +1278,21 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
size_t hdrlen;
struct ap_data *ap = local->ap;
char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
int len, olen;
u16 auth_alg, auth_transaction, status_code;
__le16 *pos;
- u16 resp = WLAN_STATUS_SUCCESS, fc;
+ u16 resp = WLAN_STATUS_SUCCESS;
struct sta_info *sta = NULL;
struct lib80211_crypt_data *crypt;
char *txt = "";
len = skb->len - IEEE80211_MGMT_HDR_LEN;
- fc = le16_to_cpu(hdr->frame_ctl);
- hdrlen = hostap_80211_get_hdrlen(fc);
+ hdrlen = hostap_80211_get_hdrlen(hdr->frame_control);
if (len < 6) {
PDEBUG(DEBUG_AP, "%s: handle_authen - too short payload "
@@ -1435,7 +1428,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
challenge == NULL ||
memcmp(sta->u.sta.challenge, challenge,
WLAN_AUTH_CHALLENGE_LEN) != 0 ||
- !(fc & IEEE80211_FCTL_PROTECTED)) {
+ !ieee80211_has_protected(hdr->frame_control)) {
txt = "challenge response incorrect";
resp = WLAN_STATUS_CHALLENGE_FAIL;
goto fail;
@@ -1488,7 +1481,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
"trans#=%d stat=%d len=%d fc=%04x) ==> %d (%s)\n",
dev->name, hdr->addr2,
auth_alg, auth_transaction, status_code, len,
- fc, resp, txt);
+ le16_to_cpu(hdr->frame_control), resp, txt);
}
}
@@ -1498,7 +1491,7 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats, int reassoc)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
char body[12], *p, *lpos;
int len, left;
__le16 *pos;
@@ -1707,7 +1700,7 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
int len;
u16 reason_code;
@@ -1749,7 +1742,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
- struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
int len;
u16 reason_code;
@@ -1788,7 +1781,7 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
/* Called only as a scheduled task for pending AP frames. */
static void ap_handle_data_nullfunc(local_info_t *local,
- struct ieee80211_hdr_4addr *hdr)
+ struct ieee80211_hdr *hdr)
{
struct net_device *dev = local->dev;
@@ -1805,7 +1798,7 @@ static void ap_handle_data_nullfunc(local_info_t *local,
/* Called only as a scheduled task for pending AP frames. */
static void ap_handle_dropped_data(local_info_t *local,
- struct ieee80211_hdr_4addr *hdr)
+ struct ieee80211_hdr *hdr)
{
struct net_device *dev = local->dev;
struct sta_info *sta;
@@ -1863,7 +1856,7 @@ static void pspoll_send_buffered(local_info_t *local, struct sta_info *sta,
/* Called only as a scheduled task for pending AP frames. */
static void handle_pspoll(local_info_t *local,
- struct ieee80211_hdr_4addr *hdr,
+ struct ieee80211_hdr *hdr,
struct hostap_80211_rx_status *rx_stats)
{
struct net_device *dev = local->dev;
@@ -1872,8 +1865,7 @@ static void handle_pspoll(local_info_t *local,
struct sk_buff *skb;
PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=%pM, TA=%pM PWRMGT=%d\n",
- hdr->addr1, hdr->addr2,
- !!(le16_to_cpu(hdr->frame_ctl) & IEEE80211_FCTL_PM));
+ hdr->addr1, hdr->addr2, !!ieee80211_has_pm(hdr->frame_control));
if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
PDEBUG(DEBUG_AP,
@@ -1984,7 +1976,7 @@ static void handle_wds_oper_queue(struct work_struct *work)
static void handle_beacon(local_info_t *local, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
{
- struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
int len, left;
u16 beacon_int, capability;
@@ -2143,14 +2135,14 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
struct net_device *dev = local->dev;
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
u16 fc, type, stype;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
/* FIX: should give skb->len to handler functions and check that the
* buffer is long enough */
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
- type = WLAN_FC_GET_TYPE(fc);
- stype = WLAN_FC_GET_STYPE(fc);
+ hdr = (struct ieee80211_hdr *) skb->data;
+ fc = le16_to_cpu(hdr->frame_control);
+ type = fc & IEEE80211_FCTL_FTYPE;
+ stype = fc & IEEE80211_FCTL_STYPE;
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
if (!local->hostapd && type == IEEE80211_FTYPE_DATA) {
@@ -2262,8 +2254,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
{
struct hostap_interface *iface;
local_info_t *local;
- u16 fc;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
iface = netdev_priv(dev);
local = iface->local;
@@ -2271,17 +2262,15 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
if (skb->len < 16)
goto drop;
- local->stats.rx_packets++;
+ dev->stats.rx_packets++;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
+ hdr = (struct ieee80211_hdr *) skb->data;
if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
- WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_MGMT &&
- WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_BEACON)
+ ieee80211_is_beacon(hdr->frame_control))
goto drop;
- skb->protocol = __constant_htons(ETH_P_HOSTAP);
+ skb->protocol = cpu_to_be16(ETH_P_HOSTAP);
handle_ap_item(local, skb, rx_stats);
return;
@@ -2294,7 +2283,7 @@ void hostap_rx(struct net_device *dev, struct sk_buff *skb,
static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
{
struct sk_buff *skb;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
struct hostap_80211_rx_status rx_stats;
if (skb_queue_empty(&sta->tx_buf))
@@ -2307,10 +2296,10 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
return;
}
- hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, 16);
+ hdr = (struct ieee80211_hdr *) skb_put(skb, 16);
/* Generate a fake pspoll frame to start packet delivery */
- hdr->frame_ctl = __constant_cpu_to_le16(
+ hdr->frame_control = cpu_to_le16(
IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
memcpy(hdr->addr1, local->dev->dev_addr, ETH_ALEN);
memcpy(hdr->addr2, sta->addr, ETH_ALEN);
@@ -2689,7 +2678,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
struct sta_info *sta = NULL;
struct sk_buff *skb = tx->skb;
int set_tim, ret;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
struct hostap_skb_tx_data *meta;
meta = (struct hostap_skb_tx_data *) skb->cb;
@@ -2698,7 +2687,7 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
meta->iface->type == HOSTAP_INTERFACE_STA)
goto out;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
if (hdr->addr1[0] & 0x01) {
/* broadcast/multicast frame - no AP related processing */
@@ -2753,8 +2742,8 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
if (meta->flags & HOSTAP_TX_FLAGS_ADD_MOREDATA) {
/* indicate to STA that more frames follow */
- hdr->frame_ctl |=
- __constant_cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+ hdr->frame_control |=
+ cpu_to_le16(IEEE80211_FCTL_MOREDATA);
}
if (meta->flags & HOSTAP_TX_FLAGS_BUFFERED_FRAME) {
@@ -2828,10 +2817,10 @@ void hostap_handle_sta_release(void *ptr)
void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
{
struct sta_info *sta;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
struct hostap_skb_tx_data *meta;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
meta = (struct hostap_skb_tx_data *) skb->cb;
spin_lock(&local->ap->sta_table_lock);
@@ -2898,8 +2887,8 @@ static void hostap_update_sta_ps2(local_info_t *local, struct sta_info *sta,
/* Called only as a tasklet (software IRQ). Called for each RX frame to update
- * STA power saving state. pwrmgt is a flag from 802.11 frame_ctl field. */
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
+ * STA power saving state. pwrmgt is a flag from 802.11 frame_control field. */
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr)
{
struct sta_info *sta;
u16 fc;
@@ -2913,9 +2902,10 @@ int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
if (!sta)
return -1;
- fc = le16_to_cpu(hdr->frame_ctl);
+ fc = le16_to_cpu(hdr->frame_control);
hostap_update_sta_ps2(local, sta, fc & IEEE80211_FCTL_PM,
- WLAN_FC_GET_TYPE(fc), WLAN_FC_GET_STYPE(fc));
+ fc & IEEE80211_FCTL_FTYPE,
+ fc & IEEE80211_FCTL_STYPE);
atomic_dec(&sta->users);
return 0;
@@ -2932,16 +2922,16 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
int ret;
struct sta_info *sta;
u16 fc, type, stype;
- struct ieee80211_hdr_4addr *hdr;
+ struct ieee80211_hdr *hdr;
if (local->ap == NULL)
return AP_RX_CONTINUE;
- hdr = (struct ieee80211_hdr_4addr *) skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
- type = WLAN_FC_GET_TYPE(fc);
- stype = WLAN_FC_GET_STYPE(fc);
+ fc = le16_to_cpu(hdr->frame_control);
+ type = fc & IEEE80211_FCTL_FTYPE;
+ stype = fc & IEEE80211_FCTL_STYPE;
spin_lock(&local->ap->sta_table_lock);
sta = ap_get_sta(local->ap, hdr->addr2);
@@ -3064,7 +3054,7 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
/* Called only as a tasklet (software IRQ) */
int hostap_handle_sta_crypto(local_info_t *local,
- struct ieee80211_hdr_4addr *hdr,
+ struct ieee80211_hdr *hdr,
struct lib80211_crypt_data **crypt,
void **sta_ptr)
{
@@ -3166,7 +3156,7 @@ int hostap_add_sta(struct ap_data *ap, u8 *sta_addr)
/* Called only as a tasklet (software IRQ) */
int hostap_update_rx_stats(struct ap_data *ap,
- struct ieee80211_hdr_4addr *hdr,
+ struct ieee80211_hdr *hdr,
struct hostap_80211_rx_status *rx_stats)
{
struct sta_info *sta;
diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h
index d36e4b175336..655ceeba9612 100644
--- a/drivers/net/wireless/hostap/hostap_ap.h
+++ b/drivers/net/wireless/hostap/hostap_ap.h
@@ -235,7 +235,7 @@ struct hostap_tx_data {
ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
void hostap_handle_sta_release(void *ptr);
void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr);
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr);
typedef enum {
AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
} ap_rx_ret;
@@ -243,13 +243,13 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats,
int wds);
-int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
+int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr,
struct lib80211_crypt_data **crypt,
void **sta_ptr);
int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
-int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr_4addr *hdr,
+int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr,
struct hostap_80211_rx_status *rx_stats);
void hostap_update_rates(local_info_t *local);
void hostap_add_wds_links(local_info_t *local);
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 0f27059bbe85..3dad1cf8f241 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -46,7 +46,6 @@
#include <linux/rtnetlink.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
-#include <net/ieee80211.h>
#include <net/lib80211.h>
#include <asm/irq.h>
@@ -1683,7 +1682,7 @@ static int prism2_get_txfid_idx(local_info_t *local)
PDEBUG(DEBUG_EXTRA2, "prism2_get_txfid_idx: no room in txfid buf: "
"packet dropped\n");
- local->stats.tx_dropped++;
+ local->dev->stats.tx_dropped++;
return -1;
}
@@ -1788,11 +1787,9 @@ static int prism2_transmit(struct net_device *dev, int idx)
prism2_transmit_cb, (long) idx);
if (res) {
- struct net_device_stats *stats;
printk(KERN_DEBUG "%s: prism2_transmit: CMDCODE_TRANSMIT "
"failed (res=%d)\n", dev->name, res);
- stats = hostap_get_stats(dev);
- stats->tx_dropped++;
+ dev->stats.tx_dropped++;
netif_wake_queue(dev);
return -1;
}
@@ -1840,8 +1837,8 @@ static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev)
hdr_len = 24;
skb_copy_from_linear_data(skb, &txdesc.frame_control, hdr_len);
fc = le16_to_cpu(txdesc.frame_control);
- if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
- (fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS) &&
+ if (ieee80211_is_data(txdesc.frame_control) &&
+ ieee80211_has_a4(txdesc.frame_control) &&
skb->len >= 30) {
/* Addr4 */
skb_copy_from_linear_data_offset(skb, hdr_len, txdesc.addr4,
@@ -1940,12 +1937,10 @@ static void prism2_rx(local_info_t *local)
struct net_device *dev = local->dev;
int res, rx_pending = 0;
u16 len, hdr_len, rxfid, status, macport;
- struct net_device_stats *stats;
struct hfa384x_rx_frame rxdesc;
struct sk_buff *skb = NULL;
prism2_callback(local, PRISM2_CALLBACK_RX_START);
- stats = hostap_get_stats(dev);
rxfid = prism2_read_fid_reg(dev, HFA384X_RXFID_OFF);
#ifndef final_version
@@ -2032,7 +2027,7 @@ static void prism2_rx(local_info_t *local)
return;
rx_dropped:
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
if (skb)
dev_kfree_skb(skb);
goto rx_exit;
@@ -2082,7 +2077,7 @@ static void hostap_rx_skb(local_info_t *local, struct sk_buff *skb)
stats.rate = rxdesc->rate;
/* Convert Prism2 RX structure into IEEE 802.11 header */
- hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(rxdesc->frame_control));
+ hdrlen = hostap_80211_get_hdrlen(rxdesc->frame_control);
if (hdrlen > rx_hdrlen)
hdrlen = rx_hdrlen;
@@ -2204,7 +2199,7 @@ static void hostap_tx_callback(local_info_t *local,
return;
}
- hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(txdesc->frame_control));
+ hdrlen = hostap_80211_get_hdrlen(txdesc->frame_control);
len = le16_to_cpu(txdesc->data_len);
skb = dev_alloc_skb(hdrlen + len);
if (skb == NULL) {
@@ -2315,8 +2310,7 @@ static void hostap_sta_tx_exc_tasklet(unsigned long data)
if (skb->len >= sizeof(*txdesc)) {
/* Convert Prism2 RX structure into IEEE 802.11 header
*/
- u16 fc = le16_to_cpu(txdesc->frame_control);
- int hdrlen = hostap_80211_get_hdrlen(fc);
+ int hdrlen = hostap_80211_get_hdrlen(txdesc->frame_control);
memmove(skb_pull(skb, sizeof(*txdesc) - hdrlen),
&txdesc->frame_control, hdrlen);
@@ -2337,7 +2331,7 @@ static void prism2_txexc(local_info_t *local)
struct hfa384x_tx_frame txdesc;
show_dump = local->frame_dump & PRISM2_DUMP_TXEXC_HDR;
- local->stats.tx_errors++;
+ dev->stats.tx_errors++;
res = hostap_tx_compl_read(local, 1, &txdesc, &payload);
HFA384X_OUTW(HFA384X_EV_TXEXC, HFA384X_EVACK_OFF);
@@ -2394,12 +2388,12 @@ static void prism2_txexc(local_info_t *local)
PDEBUG(DEBUG_EXTRA, " retry_count=%d tx_rate=%d fc=0x%04x "
"(%s%s%s::%d%s%s)\n",
txdesc.retry_count, txdesc.tx_rate, fc,
- WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_MGMT ? "Mgmt" : "",
- WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_CTL ? "Ctrl" : "",
- WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA ? "Data" : "",
- WLAN_FC_GET_STYPE(fc) >> 4,
- fc & IEEE80211_FCTL_TODS ? " ToDS" : "",
- fc & IEEE80211_FCTL_FROMDS ? " FromDS" : "");
+ ieee80211_is_mgmt(txdesc.frame_control) ? "Mgmt" : "",
+ ieee80211_is_ctl(txdesc.frame_control) ? "Ctrl" : "",
+ ieee80211_is_data(txdesc.frame_control) ? "Data" : "",
+ (fc & IEEE80211_FCTL_STYPE) >> 4,
+ ieee80211_has_tods(txdesc.frame_control) ? " ToDS" : "",
+ ieee80211_has_fromds(txdesc.frame_control) ? " FromDS" : "");
PDEBUG(DEBUG_EXTRA, " A1=%pM A2=%pM A3=%pM A4=%pM\n",
txdesc.addr1, txdesc.addr2,
txdesc.addr3, txdesc.addr4);
@@ -3228,7 +3222,6 @@ while (0)
hostap_setup_dev(dev, local, HOSTAP_INTERFACE_MASTER);
- dev->hard_start_xmit = hostap_master_start_xmit;
dev->type = ARPHRD_IEEE80211;
dev->header_ops = &hostap_80211_ops;
diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c
index 99b4cf41edf2..6fa14a4e4b53 100644
--- a/drivers/net/wireless/hostap/hostap_info.c
+++ b/drivers/net/wireless/hostap/hostap_info.c
@@ -1,5 +1,6 @@
/* Host AP driver Info Frame processing (part of hostap.o module) */
+#include <linux/if_arp.h>
#include "hostap_wlan.h"
#include "hostap.h"
#include "hostap_ap.h"
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index c40fdf4c79de..3f2bda881a4f 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -2,6 +2,7 @@
#include <linux/types.h>
#include <linux/ethtool.h>
+#include <linux/if_arp.h>
#include <net/lib80211.h>
#include "hostap_wlan.h"
@@ -1638,7 +1639,7 @@ static int prism2_request_hostscan(struct net_device *dev,
memset(&scan_req, 0, sizeof(scan_req));
scan_req.channel_list = cpu_to_le16(local->channel_mask &
local->scan_channel_mask);
- scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
+ scan_req.txrate = cpu_to_le16(HFA384X_RATES_1MBPS);
if (ssid) {
if (ssid_len > 32)
return -EINVAL;
@@ -1668,7 +1669,7 @@ static int prism2_request_scan(struct net_device *dev)
memset(&scan_req, 0, sizeof(scan_req));
scan_req.channel_list = cpu_to_le16(local->channel_mask &
local->scan_channel_mask);
- scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
+ scan_req.txrate = cpu_to_le16(HFA384X_RATES_1MBPS);
/* FIX:
* It seems to be enough to set roaming mode for a short moment to
@@ -2514,7 +2515,7 @@ static int prism2_ioctl_priv_prism2_param(struct net_device *dev,
u16 rate;
memset(&scan_req, 0, sizeof(scan_req));
- scan_req.channel_list = __constant_cpu_to_le16(0x3fff);
+ scan_req.channel_list = cpu_to_le16(0x3fff);
switch (value) {
case 1: rate = HFA384X_RATES_1MBPS; break;
case 2: rate = HFA384X_RATES_2MBPS; break;
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 02a312ca8607..6fe122f18c0d 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -26,7 +26,6 @@
#include <linux/etherdevice.h>
#include <net/net_namespace.h>
#include <net/iw_handler.h>
-#include <net/ieee80211.h>
#include <net/lib80211.h>
#include <asm/uaccess.h>
@@ -543,7 +542,8 @@ void hostap_dump_rx_header(const char *name, const struct hfa384x_rx_frame *rx)
fc = __le16_to_cpu(rx->frame_control);
printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x "
"data_len=%d%s%s\n",
- fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
+ fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
+ (fc & IEEE80211_FCTL_STYPE) >> 4,
__le16_to_cpu(rx->duration_id), __le16_to_cpu(rx->seq_ctrl),
__le16_to_cpu(rx->data_len),
fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
@@ -570,7 +570,8 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx)
fc = __le16_to_cpu(tx->frame_control);
printk(KERN_DEBUG " FC=0x%04x (type=%d:%d) dur=0x%04x seq=0x%04x "
"data_len=%d%s%s\n",
- fc, WLAN_FC_GET_TYPE(fc) >> 2, WLAN_FC_GET_STYPE(fc) >> 4,
+ fc, (fc & IEEE80211_FCTL_FTYPE) >> 2,
+ (fc & IEEE80211_FCTL_STYPE) >> 4,
__le16_to_cpu(tx->duration_id), __le16_to_cpu(tx->seq_ctrl),
__le16_to_cpu(tx->data_len),
fc & IEEE80211_FCTL_TODS ? " [ToDS]" : "",
@@ -593,37 +594,16 @@ static int hostap_80211_header_parse(const struct sk_buff *skb,
}
-int hostap_80211_get_hdrlen(u16 fc)
+int hostap_80211_get_hdrlen(__le16 fc)
{
- int hdrlen = 24;
-
- switch (WLAN_FC_GET_TYPE(fc)) {
- case IEEE80211_FTYPE_DATA:
- if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
- hdrlen = 30; /* Addr4 */
- break;
- case IEEE80211_FTYPE_CTL:
- switch (WLAN_FC_GET_STYPE(fc)) {
- case IEEE80211_STYPE_CTS:
- case IEEE80211_STYPE_ACK:
- hdrlen = 10;
- break;
- default:
- hdrlen = 16;
- break;
- }
- break;
- }
-
- return hdrlen;
-}
-
-
-struct net_device_stats *hostap_get_stats(struct net_device *dev)
-{
- struct hostap_interface *iface;
- iface = netdev_priv(dev);
- return &iface->stats;
+ if (ieee80211_is_data(fc) && ieee80211_has_a4 (fc))
+ return 30; /* Addr4 */
+ else if (ieee80211_is_cts(fc) || ieee80211_is_ack(fc))
+ return 10;
+ else if (ieee80211_is_ctl(fc))
+ return 16;
+
+ return 24;
}
@@ -835,6 +815,46 @@ const struct header_ops hostap_80211_ops = {
};
EXPORT_SYMBOL(hostap_80211_ops);
+
+static const struct net_device_ops hostap_netdev_ops = {
+ .ndo_start_xmit = hostap_data_start_xmit,
+
+ .ndo_open = prism2_open,
+ .ndo_stop = prism2_close,
+ .ndo_do_ioctl = hostap_ioctl,
+ .ndo_set_mac_address = prism2_set_mac_address,
+ .ndo_set_multicast_list = hostap_set_multicast_list,
+ .ndo_change_mtu = prism2_change_mtu,
+ .ndo_tx_timeout = prism2_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static const struct net_device_ops hostap_mgmt_netdev_ops = {
+ .ndo_start_xmit = hostap_mgmt_start_xmit,
+
+ .ndo_open = prism2_open,
+ .ndo_stop = prism2_close,
+ .ndo_do_ioctl = hostap_ioctl,
+ .ndo_set_mac_address = prism2_set_mac_address,
+ .ndo_set_multicast_list = hostap_set_multicast_list,
+ .ndo_change_mtu = prism2_change_mtu,
+ .ndo_tx_timeout = prism2_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static const struct net_device_ops hostap_master_ops = {
+ .ndo_start_xmit = hostap_master_start_xmit,
+
+ .ndo_open = prism2_open,
+ .ndo_stop = prism2_close,
+ .ndo_do_ioctl = hostap_ioctl,
+ .ndo_set_mac_address = prism2_set_mac_address,
+ .ndo_set_multicast_list = hostap_set_multicast_list,
+ .ndo_change_mtu = prism2_change_mtu,
+ .ndo_tx_timeout = prism2_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
void hostap_setup_dev(struct net_device *dev, local_info_t *local,
int type)
{
@@ -844,37 +864,31 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local,
ether_setup(dev);
/* kernel callbacks */
- dev->get_stats = hostap_get_stats;
if (iface) {
/* Currently, we point to the proper spy_data only on
* the main_dev. This could be fixed. Jean II */
iface->wireless_data.spy_data = &iface->spy_data;
dev->wireless_data = &iface->wireless_data;
}
- dev->wireless_handlers =
- (struct iw_handler_def *) &hostap_iw_handler_def;
- dev->do_ioctl = hostap_ioctl;
- dev->open = prism2_open;
- dev->stop = prism2_close;
- dev->set_mac_address = prism2_set_mac_address;
- dev->set_multicast_list = hostap_set_multicast_list;
- dev->change_mtu = prism2_change_mtu;
- dev->tx_timeout = prism2_tx_timeout;
+ dev->wireless_handlers = &hostap_iw_handler_def;
dev->watchdog_timeo = TX_TIMEOUT;
- if (type == HOSTAP_INTERFACE_AP) {
- dev->hard_start_xmit = hostap_mgmt_start_xmit;
+ switch(type) {
+ case HOSTAP_INTERFACE_AP:
+ dev->netdev_ops = &hostap_mgmt_netdev_ops;
dev->type = ARPHRD_IEEE80211;
dev->header_ops = &hostap_80211_ops;
- } else {
- dev->hard_start_xmit = hostap_data_start_xmit;
+ break;
+ case HOSTAP_INTERFACE_MASTER:
+ dev->tx_queue_len = 0; /* use main radio device queue */
+ dev->netdev_ops = &hostap_master_ops;
+ break;
+ default:
+ dev->netdev_ops = &hostap_netdev_ops;
}
dev->mtu = local->mtu;
- if (type != HOSTAP_INTERFACE_MASTER) {
- /* use main radio device queue */
- dev->tx_queue_len = 0;
- }
+
SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops);
@@ -1124,7 +1138,6 @@ EXPORT_SYMBOL(hostap_set_auth_algs);
EXPORT_SYMBOL(hostap_dump_rx_header);
EXPORT_SYMBOL(hostap_dump_tx_header);
EXPORT_SYMBOL(hostap_80211_get_hdrlen);
-EXPORT_SYMBOL(hostap_get_stats);
EXPORT_SYMBOL(hostap_setup_dev);
EXPORT_SYMBOL(hostap_set_multicast_list_queue);
EXPORT_SYMBOL(hostap_set_hostapd);
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
index 4d8d51a353cd..3d238917af07 100644
--- a/drivers/net/wireless/hostap/hostap_wlan.h
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -684,7 +684,6 @@ struct local_info {
u16 channel_mask; /* mask of allowed channels */
u16 scan_channel_mask; /* mask of channels to be scanned */
struct comm_tallies_sums comm_tallies;
- struct net_device_stats stats;
struct proc_dir_entry *proc;
int iw_mode; /* operating mode (IW_MODE_*) */
int pseudo_adhoc; /* 0: IW_MODE_ADHOC is real 802.11 compliant IBSS
diff --git a/drivers/net/wireless/ipw2x00/Kconfig b/drivers/net/wireless/ipw2x00/Kconfig
index 3d5cc4463d4d..85cc79995f6f 100644
--- a/drivers/net/wireless/ipw2x00/Kconfig
+++ b/drivers/net/wireless/ipw2x00/Kconfig
@@ -150,6 +150,7 @@ config IPW2200_DEBUG
config LIBIPW
tristate
+ depends on PCI && WLAN_80211
select WIRELESS_EXT
select CRYPTO
select CRYPTO_ARC4
@@ -185,7 +186,7 @@ config LIBIPW_DEBUG
% echo 0x00000FFO > /proc/net/ieee80211/debug_level
For a list of values you can assign to debug_level, you
- can look at the bit mask values in <net/ieee80211.h>
+ can look at the bit mask values in ieee80211.h
If you are not trying to debug or develop the libipw
component, you most likely want to say N here.
diff --git a/include/net/ieee80211.h b/drivers/net/wireless/ipw2x00/ieee80211.h
index adb7cf31f781..70755c1336d5 100644
--- a/include/net/ieee80211.h
+++ b/drivers/net/wireless/ipw2x00/ieee80211.h
@@ -54,65 +54,12 @@
#define MIN_FRAG_THRESHOLD 256U
#define MAX_FRAG_THRESHOLD 2346U
-/* Frame control field constants */
-#define IEEE80211_FCTL_VERS 0x0003
-#define IEEE80211_FCTL_FTYPE 0x000c
-#define IEEE80211_FCTL_STYPE 0x00f0
-#define IEEE80211_FCTL_TODS 0x0100
-#define IEEE80211_FCTL_FROMDS 0x0200
-#define IEEE80211_FCTL_MOREFRAGS 0x0400
-#define IEEE80211_FCTL_RETRY 0x0800
-#define IEEE80211_FCTL_PM 0x1000
-#define IEEE80211_FCTL_MOREDATA 0x2000
-#define IEEE80211_FCTL_PROTECTED 0x4000
-#define IEEE80211_FCTL_ORDER 0x8000
-
-#define IEEE80211_FTYPE_MGMT 0x0000
-#define IEEE80211_FTYPE_CTL 0x0004
-#define IEEE80211_FTYPE_DATA 0x0008
-
-/* management */
-#define IEEE80211_STYPE_ASSOC_REQ 0x0000
-#define IEEE80211_STYPE_ASSOC_RESP 0x0010
-#define IEEE80211_STYPE_REASSOC_REQ 0x0020
-#define IEEE80211_STYPE_REASSOC_RESP 0x0030
-#define IEEE80211_STYPE_PROBE_REQ 0x0040
-#define IEEE80211_STYPE_PROBE_RESP 0x0050
-#define IEEE80211_STYPE_BEACON 0x0080
-#define IEEE80211_STYPE_ATIM 0x0090
-#define IEEE80211_STYPE_DISASSOC 0x00A0
-#define IEEE80211_STYPE_AUTH 0x00B0
-#define IEEE80211_STYPE_DEAUTH 0x00C0
-#define IEEE80211_STYPE_ACTION 0x00D0
-
-/* control */
-#define IEEE80211_STYPE_PSPOLL 0x00A0
-#define IEEE80211_STYPE_RTS 0x00B0
-#define IEEE80211_STYPE_CTS 0x00C0
-#define IEEE80211_STYPE_ACK 0x00D0
-#define IEEE80211_STYPE_CFEND 0x00E0
-#define IEEE80211_STYPE_CFENDACK 0x00F0
-
-/* data */
-#define IEEE80211_STYPE_DATA 0x0000
-#define IEEE80211_STYPE_DATA_CFACK 0x0010
-#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
-#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
-#define IEEE80211_STYPE_NULLFUNC 0x0040
-#define IEEE80211_STYPE_CFACK 0x0050
-#define IEEE80211_STYPE_CFPOLL 0x0060
-#define IEEE80211_STYPE_CFACKPOLL 0x0070
-#define IEEE80211_STYPE_QOS_DATA 0x0080
-
-#define IEEE80211_SCTL_FRAG 0x000F
-#define IEEE80211_SCTL_SEQ 0xFFF0
-
/* QOS control */
#define IEEE80211_QCTL_TID 0x000F
/* debug macros */
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
extern u32 ieee80211_debug_level;
#define IEEE80211_DEBUG(level, fmt, args...) \
do { if (ieee80211_debug_level & (level)) \
@@ -128,7 +75,7 @@ static inline bool ieee80211_ratelimit_debug(u32 level)
{
return false;
}
-#endif /* CONFIG_IEEE80211_DEBUG */
+#endif /* CONFIG_LIBIPW_DEBUG */
/*
* To use the debug system:
@@ -152,7 +99,7 @@ static inline bool ieee80211_ratelimit_debug(u32 level)
* you simply need to add your entry to the ieee80211_debug_level array.
*
* If you do not see debug_level in /proc/net/ieee80211 then you do not have
- * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
+ * CONFIG_LIBIPW_DEBUG defined in your kernel configuration
*
*/
@@ -217,23 +164,6 @@ struct ieee80211_snap_hdr {
#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
#define WLAN_GET_SEQ_SEQ(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
-/* Action categories - 802.11h */
-enum ieee80211_actioncategories {
- WLAN_ACTION_SPECTRUM_MGMT = 0,
- /* Reserved 1-127 */
- /* Error 128-255 */
-};
-
-/* Action details - 802.11h */
-enum ieee80211_actiondetails {
- WLAN_ACTION_CATEGORY_MEASURE_REQUEST = 0,
- WLAN_ACTION_CATEGORY_MEASURE_REPORT = 1,
- WLAN_ACTION_CATEGORY_TPC_REQUEST = 2,
- WLAN_ACTION_CATEGORY_TPC_REPORT = 3,
- WLAN_ACTION_CATEGORY_CHANNEL_SWITCH = 4,
- /* 5 - 255 Reserved */
-};
-
#define IEEE80211_STATMASK_SIGNAL (1<<0)
#define IEEE80211_STATMASK_RSSI (1<<1)
#define IEEE80211_STATMASK_NOISE (1<<2)
@@ -411,37 +341,6 @@ Total: 28-2340 bytes
#define BEACON_PROBE_SSID_ID_POSITION 12
-/* Management Frame Information Element Types */
-enum ieee80211_mfie {
- MFIE_TYPE_SSID = 0,
- MFIE_TYPE_RATES = 1,
- MFIE_TYPE_FH_SET = 2,
- MFIE_TYPE_DS_SET = 3,
- MFIE_TYPE_CF_SET = 4,
- MFIE_TYPE_TIM = 5,
- MFIE_TYPE_IBSS_SET = 6,
- MFIE_TYPE_COUNTRY = 7,
- MFIE_TYPE_HOP_PARAMS = 8,
- MFIE_TYPE_HOP_TABLE = 9,
- MFIE_TYPE_REQUEST = 10,
- MFIE_TYPE_CHALLENGE = 16,
- MFIE_TYPE_POWER_CONSTRAINT = 32,
- MFIE_TYPE_POWER_CAPABILITY = 33,
- MFIE_TYPE_TPC_REQUEST = 34,
- MFIE_TYPE_TPC_REPORT = 35,
- MFIE_TYPE_SUPP_CHANNELS = 36,
- MFIE_TYPE_CSA = 37,
- MFIE_TYPE_MEASURE_REQUEST = 38,
- MFIE_TYPE_MEASURE_REPORT = 39,
- MFIE_TYPE_QUIET = 40,
- MFIE_TYPE_IBSS_DFS = 41,
- MFIE_TYPE_ERP_INFO = 42,
- MFIE_TYPE_RSN = 48,
- MFIE_TYPE_RATES_EX = 50,
- MFIE_TYPE_GENERIC = 221,
- MFIE_TYPE_QOS_PARAMETER = 222,
-};
-
struct ieee80211_hdr_1addr {
__le16 frame_ctl;
__le16 duration_id;
@@ -887,7 +786,6 @@ struct ieee80211_device {
struct ieee80211_security sec;
/* Bookkeeping structures */
- struct net_device_stats stats;
struct ieee80211_stats ieee_stats;
struct ieee80211_geo geo;
@@ -1118,6 +1016,10 @@ static inline int ieee80211_is_cck_rate(u8 rate)
/* ieee80211.c */
extern void free_ieee80211(struct net_device *dev);
extern struct net_device *alloc_ieee80211(int sizeof_priv);
+extern int ieee80211_change_mtu(struct net_device *dev, int new_mtu);
+
+extern void ieee80211_networks_age(struct ieee80211_device *ieee,
+ unsigned long age_secs);
extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 823c2bf5e31e..f4e963ba768b 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -1692,7 +1692,13 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
u32 lock;
u32 ord_len = sizeof(lock);
- /* Quite if manually disabled. */
+ /* Age scan list entries found before suspend */
+ if (priv->suspend_time) {
+ ieee80211_networks_age(priv->ieee, priv->suspend_time);
+ priv->suspend_time = 0;
+ }
+
+ /* Quiet if manually disabled. */
if (priv->status & STATUS_RF_KILL_SW) {
IPW_DEBUG_INFO("%s: Radio is disabled by Manual Disable "
"switch\n", priv->net_dev->name);
@@ -1910,7 +1916,8 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
{
#define MAC_ASSOCIATION_READ_DELAY (HZ)
- int ret, len, essid_len;
+ int ret;
+ unsigned int len, essid_len;
char essid[IW_ESSID_MAX_SIZE];
u32 txrate;
u32 chan;
@@ -2355,7 +2362,7 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
i * sizeof(struct ipw2100_status));
#ifdef IPW2100_DEBUG_C3
- /* Halt the fimrware so we can get a good image */
+ /* Halt the firmware so we can get a good image */
write_register(priv->net_dev, IPW_REG_RESET_REG,
IPW_AUX_HOST_RESET_REG_STOP_MASTER);
j = 5;
@@ -2384,13 +2391,14 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
#endif
priv->fatal_error = IPW2100_ERR_C3_CORRUPTION;
- priv->ieee->stats.rx_errors++;
+ priv->net_dev->stats.rx_errors++;
schedule_reset(priv);
}
static void isr_rx(struct ipw2100_priv *priv, int i,
struct ieee80211_rx_stats *stats)
{
+ struct net_device *dev = priv->net_dev;
struct ipw2100_status *status = &priv->status_queue.drv[i];
struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
@@ -2399,14 +2407,14 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
if (unlikely(status->frame_size > skb_tailroom(packet->skb))) {
IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
" Dropping.\n",
- priv->net_dev->name,
+ dev->name,
status->frame_size, skb_tailroom(packet->skb));
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
return;
}
- if (unlikely(!netif_running(priv->net_dev))) {
- priv->ieee->stats.rx_errors++;
+ if (unlikely(!netif_running(dev))) {
+ dev->stats.rx_errors++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
return;
@@ -2436,10 +2444,10 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
#ifdef IPW2100_RX_DEBUG
IPW_DEBUG_DROP("%s: Non consumed packet:\n",
- priv->net_dev->name);
+ dev->name);
printk_buf(IPW_DL_DROP, packet_data, status->frame_size);
#endif
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
/* ieee80211_rx failed, so it didn't free the SKB */
dev_kfree_skb_any(packet->skb);
@@ -2450,7 +2458,7 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
if (unlikely(ipw2100_alloc_skb(priv, packet))) {
printk(KERN_WARNING DRV_NAME ": "
"%s: Unable to allocate SKB onto RBD ring - disabling "
- "adapter.\n", priv->net_dev->name);
+ "adapter.\n", dev->name);
/* TODO: schedule adapter shutdown */
IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
}
@@ -2464,6 +2472,7 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
struct ieee80211_rx_stats *stats)
{
+ struct net_device *dev = priv->net_dev;
struct ipw2100_status *status = &priv->status_queue.drv[i];
struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
@@ -2481,15 +2490,15 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
sizeof(struct ipw_rt_hdr))) {
IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
" Dropping.\n",
- priv->net_dev->name,
+ dev->name,
status->frame_size,
skb_tailroom(packet->skb));
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
return;
}
- if (unlikely(!netif_running(priv->net_dev))) {
- priv->ieee->stats.rx_errors++;
+ if (unlikely(!netif_running(dev))) {
+ dev->stats.rx_errors++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
return;
@@ -2498,7 +2507,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
if (unlikely(priv->config & CFG_CRC_CHECK &&
status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
return;
}
@@ -2520,7 +2529,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
skb_put(packet->skb, status->frame_size + sizeof(struct ipw_rt_hdr));
if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
/* ieee80211_rx failed, so it didn't free the SKB */
dev_kfree_skb_any(packet->skb);
@@ -2531,7 +2540,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
if (unlikely(ipw2100_alloc_skb(priv, packet))) {
IPW_DEBUG_WARNING(
"%s: Unable to allocate SKB onto RBD ring - disabling "
- "adapter.\n", priv->net_dev->name);
+ "adapter.\n", dev->name);
/* TODO: schedule adapter shutdown */
IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
}
@@ -3333,7 +3342,7 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
if (!(priv->status & STATUS_ASSOCIATED)) {
IPW_DEBUG_INFO("Can not transmit when not connected.\n");
- priv->ieee->stats.tx_carrier_errors++;
+ priv->net_dev->stats.tx_carrier_errors++;
netif_stop_queue(dev);
goto fail_unlock;
}
@@ -4058,7 +4067,7 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
u8 bssid[ETH_ALEN];
u32 chan = 0;
char *out = buf;
- int length;
+ unsigned int length;
int ret;
if (priv->status & STATUS_RF_KILL_MASK)
@@ -5829,7 +5838,7 @@ static void ipw2100_tx_timeout(struct net_device *dev)
{
struct ipw2100_priv *priv = ieee80211_priv(dev);
- priv->ieee->stats.tx_errors++;
+ dev->stats.tx_errors++;
#ifdef CONFIG_IPW2100_MONITOR
if (priv->ieee->iw_mode == IW_MODE_MONITOR)
@@ -5999,6 +6008,17 @@ static void ipw2100_rf_kill(struct work_struct *work)
static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
+static const struct net_device_ops ipw2100_netdev_ops = {
+ .ndo_open = ipw2100_open,
+ .ndo_stop = ipw2100_close,
+ .ndo_start_xmit = ieee80211_xmit,
+ .ndo_change_mtu = ieee80211_change_mtu,
+ .ndo_init = ipw2100_net_init,
+ .ndo_tx_timeout = ipw2100_tx_timeout,
+ .ndo_set_mac_address = ipw2100_set_address,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/* Look into using netdev destructor to shutdown ieee80211? */
static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
@@ -6023,15 +6043,11 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
priv->ieee->perfect_rssi = -20;
priv->ieee->worst_rssi = -85;
- dev->open = ipw2100_open;
- dev->stop = ipw2100_close;
- dev->init = ipw2100_net_init;
+ dev->netdev_ops = &ipw2100_netdev_ops;
dev->ethtool_ops = &ipw2100_ethtool_ops;
- dev->tx_timeout = ipw2100_tx_timeout;
dev->wireless_handlers = &ipw2100_wx_handler_def;
priv->wireless_data.ieee80211 = priv->ieee;
dev->wireless_data = &priv->wireless_data;
- dev->set_mac_address = ipw2100_set_address;
dev->watchdog_timeo = 3 * HZ;
dev->irq = 0;
@@ -6414,6 +6430,8 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
pci_disable_device(pci_dev);
pci_set_power_state(pci_dev, PCI_D3hot);
+ priv->suspend_at = get_seconds();
+
mutex_unlock(&priv->action_mutex);
return 0;
@@ -6457,6 +6475,8 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
* the queue of needed */
netif_device_attach(dev);
+ priv->suspend_time = get_seconds() - priv->suspend_at;
+
/* Bring the device back up */
if (!(priv->status & STATUS_RF_KILL_SW))
ipw2100_up(priv, 0);
@@ -7122,7 +7142,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
{
struct ipw2100_priv *priv = ieee80211_priv(dev);
int val;
- int len = sizeof(val);
+ unsigned int len = sizeof(val);
int err = 0;
if (!(priv->status & STATUS_ENABLED) ||
@@ -8297,7 +8317,7 @@ static void ipw2100_wx_event_work(struct work_struct *work)
struct ipw2100_priv *priv =
container_of(work, struct ipw2100_priv, wx_event_work.work);
union iwreq_data wrqu;
- int len = ETH_ALEN;
+ unsigned int len = ETH_ALEN;
if (priv->status & STATUS_STOPPING)
return;
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.h b/drivers/net/wireless/ipw2x00/ipw2100.h
index bbf1ddcafba8..f183d951cd32 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.h
+++ b/drivers/net/wireless/ipw2x00/ipw2100.h
@@ -39,8 +39,6 @@
#include <linux/wireless.h>
#include <net/iw_handler.h> // new driver API
-#include <net/ieee80211.h>
-
#ifdef CONFIG_IPW2100_MONITOR
#include <net/ieee80211_radiotap.h>
#endif
@@ -48,6 +46,8 @@
#include <linux/workqueue.h>
#include <linux/mutex.h>
+#include "ieee80211.h"
+
struct ipw2100_priv;
struct ipw2100_tx_packet;
struct ipw2100_rx_packet;
@@ -591,6 +591,10 @@ struct ipw2100_priv {
int user_requested_scan;
+ /* Track time in suspend */
+ unsigned long suspend_at;
+ unsigned long suspend_time;
+
u32 interrupts;
int tx_interrupts;
int rx_interrupts;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 625f2cf99fa9..e17a4593e1f5 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -301,88 +301,102 @@ static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
}
/* 8-bit direct write (low 4K) */
-#define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
+static inline void _ipw_write8(struct ipw_priv *ipw, unsigned long ofs,
+ u8 val)
+{
+ writeb(val, ipw->hw_base + ofs);
+}
/* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
#define ipw_write8(ipw, ofs, val) do { \
- IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
- _ipw_write8(ipw, ofs, val); \
- } while (0)
+ IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, \
+ __LINE__, (u32)(ofs), (u32)(val)); \
+ _ipw_write8(ipw, ofs, val); \
+} while (0)
/* 16-bit direct write (low 4K) */
-#define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
+static inline void _ipw_write16(struct ipw_priv *ipw, unsigned long ofs,
+ u16 val)
+{
+ writew(val, ipw->hw_base + ofs);
+}
/* 16-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
-#define ipw_write16(ipw, ofs, val) \
- IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
- _ipw_write16(ipw, ofs, val)
+#define ipw_write16(ipw, ofs, val) do { \
+ IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, \
+ __LINE__, (u32)(ofs), (u32)(val)); \
+ _ipw_write16(ipw, ofs, val); \
+} while (0)
/* 32-bit direct write (low 4K) */
-#define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs))
+static inline void _ipw_write32(struct ipw_priv *ipw, unsigned long ofs,
+ u32 val)
+{
+ writel(val, ipw->hw_base + ofs);
+}
/* 32-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
-#define ipw_write32(ipw, ofs, val) \
- IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
- _ipw_write32(ipw, ofs, val)
+#define ipw_write32(ipw, ofs, val) do { \
+ IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, \
+ __LINE__, (u32)(ofs), (u32)(val)); \
+ _ipw_write32(ipw, ofs, val); \
+} while (0)
/* 8-bit direct read (low 4K) */
-#define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs))
-
-/* 8-bit direct read (low 4K), with debug wrapper */
-static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
+static inline u8 _ipw_read8(struct ipw_priv *ipw, unsigned long ofs)
{
- IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs));
- return _ipw_read8(ipw, ofs);
+ return readb(ipw->hw_base + ofs);
}
/* alias to 8-bit direct read (low 4K of SRAM/regs), with debug wrapper */
-#define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs)
+#define ipw_read8(ipw, ofs) ({ \
+ IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", __FILE__, __LINE__, \
+ (u32)(ofs)); \
+ _ipw_read8(ipw, ofs); \
+})
/* 16-bit direct read (low 4K) */
-#define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs))
-
-/* 16-bit direct read (low 4K), with debug wrapper */
-static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
+static inline u16 _ipw_read16(struct ipw_priv *ipw, unsigned long ofs)
{
- IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs));
- return _ipw_read16(ipw, ofs);
+ return readw(ipw->hw_base + ofs);
}
/* alias to 16-bit direct read (low 4K of SRAM/regs), with debug wrapper */
-#define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs)
+#define ipw_read16(ipw, ofs) ({ \
+ IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", __FILE__, __LINE__, \
+ (u32)(ofs)); \
+ _ipw_read16(ipw, ofs); \
+})
/* 32-bit direct read (low 4K) */
-#define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs))
-
-/* 32-bit direct read (low 4K), with debug wrapper */
-static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
+static inline u32 _ipw_read32(struct ipw_priv *ipw, unsigned long ofs)
{
- IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs));
- return _ipw_read32(ipw, ofs);
+ return readl(ipw->hw_base + ofs);
}
/* alias to 32-bit direct read (low 4K of SRAM/regs), with debug wrapper */
-#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
+#define ipw_read32(ipw, ofs) ({ \
+ IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", __FILE__, __LINE__, \
+ (u32)(ofs)); \
+ _ipw_read32(ipw, ofs); \
+})
-/* multi-byte read (above 4K), with debug wrapper */
static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
-static inline void __ipw_read_indirect(const char *f, int l,
- struct ipw_priv *a, u32 b, u8 * c, int d)
-{
- IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %d bytes\n", f, l, (u32) (b),
- d);
- _ipw_read_indirect(a, b, c, d);
-}
-
/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
-#define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
+#define ipw_read_indirect(a, b, c, d) ({ \
+ IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %u bytes\n", __FILE__, \
+ __LINE__, (u32)(b), (u32)(d)); \
+ _ipw_read_indirect(a, b, c, d); \
+})
/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */
static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
int num);
-#define ipw_write_indirect(a, b, c, d) \
- IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
- _ipw_write_indirect(a, b, c, d)
+#define ipw_write_indirect(a, b, c, d) do { \
+ IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %u bytes\n", __FILE__, \
+ __LINE__, (u32)(b), (u32)(d)); \
+ _ipw_write_indirect(a, b, c, d); \
+} while (0)
/* 32-bit indirect write (above 4K) */
static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
@@ -7717,22 +7731,23 @@ static void ipw_handle_data_packet(struct ipw_priv *priv,
struct ipw_rx_mem_buffer *rxb,
struct ieee80211_rx_stats *stats)
{
+ struct net_device *dev = priv->net_dev;
struct ieee80211_hdr_4addr *hdr;
struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
/* We received data from the HW, so stop the watchdog */
- priv->net_dev->trans_start = jiffies;
+ dev->trans_start = jiffies;
/* We only process data packets if the
* interface is open */
if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
skb_tailroom(rxb->skb))) {
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
return;
} else if (unlikely(!netif_running(priv->net_dev))) {
- priv->ieee->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
return;
@@ -7754,7 +7769,7 @@ static void ipw_handle_data_packet(struct ipw_priv *priv,
ipw_rebuild_decrypted_skb(priv, rxb->skb);
if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
else { /* ieee80211_rx succeeded, so it now owns the SKB */
rxb->skb = NULL;
__ipw_led_activity_on(priv);
@@ -7766,6 +7781,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
struct ipw_rx_mem_buffer *rxb,
struct ieee80211_rx_stats *stats)
{
+ struct net_device *dev = priv->net_dev;
struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
struct ipw_rx_frame *frame = &pkt->u.frame;
@@ -7783,18 +7799,18 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
short len = le16_to_cpu(pkt->u.frame.length);
/* We received data from the HW, so stop the watchdog */
- priv->net_dev->trans_start = jiffies;
+ dev->trans_start = jiffies;
/* We only process data packets if the
* interface is open */
if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
skb_tailroom(rxb->skb))) {
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
return;
} else if (unlikely(!netif_running(priv->net_dev))) {
- priv->ieee->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
return;
@@ -7804,7 +7820,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
* that now */
if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
/* FIXME: Should alloc bigger skb instead */
- priv->ieee->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
priv->wstats.discard.misc++;
IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
return;
@@ -7910,7 +7926,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
- priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
else { /* ieee80211_rx succeeded, so it now owns the SKB */
rxb->skb = NULL;
/* no LED during capture */
@@ -7942,6 +7958,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
struct ipw_rx_mem_buffer *rxb,
struct ieee80211_rx_stats *stats)
{
+ struct net_device *dev = priv->prom_net_dev;
struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
struct ipw_rx_frame *frame = &pkt->u.frame;
struct ipw_rt_hdr *ipw_rt;
@@ -7964,17 +7981,17 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
return;
/* We received data from the HW, so stop the watchdog */
- priv->prom_net_dev->trans_start = jiffies;
+ dev->trans_start = jiffies;
if (unlikely((len + IPW_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
- priv->prom_priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
return;
}
/* We only process data packets if the interface is open */
- if (unlikely(!netif_running(priv->prom_net_dev))) {
- priv->prom_priv->ieee->stats.rx_dropped++;
+ if (unlikely(!netif_running(dev))) {
+ dev->stats.rx_dropped++;
IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
return;
}
@@ -7983,7 +8000,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
* that now */
if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
/* FIXME: Should alloc bigger skb instead */
- priv->prom_priv->ieee->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
return;
}
@@ -8115,7 +8132,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
IPW_DEBUG_RX("Rx packet of %d bytes.\n", skb->len);
if (!ieee80211_rx(priv->prom_priv->ieee, skb, stats)) {
- priv->prom_priv->ieee->stats.rx_errors++;
+ dev->stats.rx_errors++;
dev_kfree_skb_any(skb);
}
}
@@ -8272,7 +8289,7 @@ static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
skb_reset_mac_header(skb);
skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = __constant_htons(ETH_P_80211_STATS);
+ skb->protocol = cpu_to_be16(ETH_P_80211_STATS);
memset(skb->cb, 0, sizeof(rxb->skb->cb));
netif_rx(skb);
rxb->skb = NULL;
@@ -8399,7 +8416,7 @@ static void ipw_rx(struct ipw_priv *priv)
IPW_DEBUG_DROP
("Received packet is too small. "
"Dropping.\n");
- priv->ieee->stats.rx_errors++;
+ priv->net_dev->stats.rx_errors++;
priv->wstats.discard.misc++;
break;
}
@@ -8827,7 +8844,7 @@ static int ipw_wx_set_mode(struct net_device *dev,
#endif /* CONFIG_IPW2200_MONITOR */
/* Free the existing firmware and reset the fw_loaded
- * flag so ipw_load() will bring in the new firmawre */
+ * flag so ipw_load() will bring in the new firmware */
free_firmware();
priv->ieee->iw_mode = wrqu->mode;
@@ -10470,15 +10487,6 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
return ret;
}
-static struct net_device_stats *ipw_net_get_stats(struct net_device *dev)
-{
- struct ipw_priv *priv = ieee80211_priv(dev);
-
- priv->ieee->stats.tx_packets = priv->tx_packets;
- priv->ieee->stats.rx_packets = priv->rx_packets;
- return &priv->ieee->stats;
-}
-
static void ipw_net_set_multicast_list(struct net_device *dev)
{
@@ -11224,6 +11232,12 @@ static int ipw_up(struct ipw_priv *priv)
{
int rc, i, j;
+ /* Age scan list entries found before suspend */
+ if (priv->suspend_time) {
+ ieee80211_networks_age(priv->ieee, priv->suspend_time);
+ priv->suspend_time = 0;
+ }
+
if (priv->status & STATUS_EXIT_PENDING)
return -EIO;
@@ -11515,11 +11529,14 @@ static int ipw_prom_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
return -EOPNOTSUPP;
}
-static struct net_device_stats *ipw_prom_get_stats(struct net_device *dev)
-{
- struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
- return &prom_priv->ieee->stats;
-}
+static const struct net_device_ops ipw_prom_netdev_ops = {
+ .ndo_open = ipw_prom_open,
+ .ndo_stop = ipw_prom_stop,
+ .ndo_start_xmit = ipw_prom_hard_start_xmit,
+ .ndo_change_mtu = ieee80211_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
static int ipw_prom_alloc(struct ipw_priv *priv)
{
@@ -11540,10 +11557,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
memcpy(priv->prom_net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
- priv->prom_net_dev->open = ipw_prom_open;
- priv->prom_net_dev->stop = ipw_prom_stop;
- priv->prom_net_dev->get_stats = ipw_prom_get_stats;
- priv->prom_net_dev->hard_start_xmit = ipw_prom_hard_start_xmit;
+ priv->prom_net_dev->netdev_ops = &ipw_prom_netdev_ops;
priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev);
@@ -11571,6 +11585,16 @@ static void ipw_prom_free(struct ipw_priv *priv)
#endif
+static const struct net_device_ops ipw_netdev_ops = {
+ .ndo_init = ipw_net_init,
+ .ndo_open = ipw_net_open,
+ .ndo_stop = ipw_net_stop,
+ .ndo_set_multicast_list = ipw_net_set_multicast_list,
+ .ndo_set_mac_address = ipw_net_set_mac_address,
+ .ndo_start_xmit = ieee80211_xmit,
+ .ndo_change_mtu = ieee80211_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
static int __devinit ipw_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -11672,12 +11696,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
priv->ieee->perfect_rssi = -20;
priv->ieee->worst_rssi = -85;
- net_dev->open = ipw_net_open;
- net_dev->stop = ipw_net_stop;
- net_dev->init = ipw_net_init;
- net_dev->get_stats = ipw_net_get_stats;
- net_dev->set_multicast_list = ipw_net_set_multicast_list;
- net_dev->set_mac_address = ipw_net_set_mac_address;
+ net_dev->netdev_ops = &ipw_netdev_ops;
priv->wireless_data.spy_data = &priv->ieee->spy_data;
net_dev->wireless_data = &priv->wireless_data;
net_dev->wireless_handlers = &ipw_wx_handler_def;
@@ -11824,6 +11843,8 @@ static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
+ priv->suspend_at = get_seconds();
+
return 0;
}
@@ -11859,6 +11880,8 @@ static int ipw_pci_resume(struct pci_dev *pdev)
* the queue of needed */
netif_device_attach(dev);
+ priv->suspend_time = get_seconds() - priv->suspend_at;
+
/* Bring the device back up */
queue_work(priv->workqueue, &priv->up);
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h
index 277b274d4be5..05e8ccf01c5f 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.h
+++ b/drivers/net/wireless/ipw2x00/ipw2200.h
@@ -49,13 +49,14 @@
#include <asm/io.h>
#include <net/lib80211.h>
-#include <net/ieee80211.h>
#include <net/ieee80211_radiotap.h>
#define DRV_NAME "ipw2200"
#include <linux/workqueue.h>
+#include "ieee80211.h"
+
/* Authentication and Association States */
enum connection_manager_assoc_states {
CMAS_INIT = 0,
@@ -1346,6 +1347,10 @@ struct ipw_priv {
s8 tx_power;
+ /* Track time in suspend */
+ unsigned long suspend_at;
+ unsigned long suspend_time;
+
#ifdef CONFIG_PM
u32 pm_state[16];
#endif
diff --git a/drivers/net/wireless/ipw2x00/libipw_geo.c b/drivers/net/wireless/ipw2x00/libipw_geo.c
index 960ad13f5e9f..9dfbb8760f67 100644
--- a/drivers/net/wireless/ipw2x00/libipw_geo.c
+++ b/drivers/net/wireless/ipw2x00/libipw_geo.c
@@ -41,7 +41,7 @@
#include <linux/etherdevice.h>
#include <asm/uaccess.h>
-#include <net/ieee80211.h>
+#include "ieee80211.h"
int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
{
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index a2f5616d5b09..92a26922e792 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -50,7 +50,7 @@
#include <net/net_namespace.h>
#include <net/arp.h>
-#include <net/ieee80211.h>
+#include "ieee80211.h"
#define DRV_DESCRIPTION "802.11 data/management/control stack"
#define DRV_NAME "ieee80211"
@@ -105,6 +105,21 @@ static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
ieee->networks = NULL;
}
+void ieee80211_networks_age(struct ieee80211_device *ieee,
+ unsigned long age_secs)
+{
+ struct ieee80211_network *network = NULL;
+ unsigned long flags;
+ unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
+
+ spin_lock_irqsave(&ieee->lock, flags);
+ list_for_each_entry(network, &ieee->network_list, list) {
+ network->last_scanned -= age_jiffies;
+ }
+ spin_unlock_irqrestore(&ieee->lock, flags);
+}
+EXPORT_SYMBOL(ieee80211_networks_age);
+
static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
{
int i;
@@ -116,20 +131,14 @@ static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
&ieee->network_free_list);
}
-static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
+int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
{
if ((new_mtu < 68) || (new_mtu > IEEE80211_DATA_LEN))
return -EINVAL;
dev->mtu = new_mtu;
return 0;
}
-
-static struct net_device_stats *ieee80211_generic_get_stats(
- struct net_device *dev)
-{
- struct ieee80211_device *ieee = netdev_priv(dev);
- return &ieee->stats;
-}
+EXPORT_SYMBOL(ieee80211_change_mtu);
struct net_device *alloc_ieee80211(int sizeof_priv)
{
@@ -145,12 +154,10 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
goto failed;
}
ieee = netdev_priv(dev);
+#ifdef CONFIG_COMPAT_NET_DEV_OPS
dev->hard_start_xmit = ieee80211_xmit;
dev->change_mtu = ieee80211_change_mtu;
-
- /* Drivers are free to override this if the generic implementation
- * does not meet their needs. */
- dev->get_stats = ieee80211_generic_get_stats;
+#endif
ieee->dev = dev;
@@ -206,7 +213,7 @@ void free_ieee80211(struct net_device *dev)
free_netdev(dev);
}
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
static int debug = 0;
u32 ieee80211_debug_level = 0;
@@ -237,11 +244,11 @@ static int store_debug_level(struct file *file, const char __user * buffer,
return strnlen(buf, len);
}
-#endif /* CONFIG_IEEE80211_DEBUG */
+#endif /* CONFIG_LIBIPW_DEBUG */
static int __init ieee80211_init(void)
{
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
struct proc_dir_entry *e;
ieee80211_debug_level = debug;
@@ -261,7 +268,7 @@ static int __init ieee80211_init(void)
e->read_proc = show_debug_level;
e->write_proc = store_debug_level;
e->data = NULL;
-#endif /* CONFIG_IEEE80211_DEBUG */
+#endif /* CONFIG_LIBIPW_DEBUG */
printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
@@ -271,20 +278,20 @@ static int __init ieee80211_init(void)
static void __exit ieee80211_exit(void)
{
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
if (ieee80211_proc) {
remove_proc_entry("debug_level", ieee80211_proc);
remove_proc_entry(DRV_NAME, init_net.proc_net);
ieee80211_proc = NULL;
}
-#endif /* CONFIG_IEEE80211_DEBUG */
+#endif /* CONFIG_LIBIPW_DEBUG */
}
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
#include <linux/moduleparam.h>
module_param(debug, int, 0444);
MODULE_PARM_DESC(debug, "debug output mask");
-#endif /* CONFIG_IEEE80211_DEBUG */
+#endif /* CONFIG_LIBIPW_DEBUG */
module_exit(ieee80211_exit);
module_init(ieee80211_init);
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
index 9c67dfae4320..dae4b8e4d8e9 100644
--- a/drivers/net/wireless/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -33,7 +33,8 @@
#include <linux/ctype.h>
#include <net/lib80211.h>
-#include <net/ieee80211.h>
+
+#include "ieee80211.h"
static void ieee80211_monitor_rx(struct ieee80211_device *ieee,
struct sk_buff *skb,
@@ -334,7 +335,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
struct ieee80211_hdr_4addr *hdr;
size_t hdrlen;
u16 fc, type, stype, sc;
- struct net_device_stats *stats;
unsigned int frag;
u8 *payload;
u16 ethertype;
@@ -353,8 +353,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
int can_be_decrypted = 0;
hdr = (struct ieee80211_hdr_4addr *)skb->data;
- stats = &ieee->stats;
-
if (skb->len < 10) {
printk(KERN_INFO "%s: SKB length < 10\n", dev->name);
goto rx_dropped;
@@ -411,8 +409,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
#endif
if (ieee->iw_mode == IW_MODE_MONITOR) {
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
ieee80211_monitor_rx(ieee, skb, rx_stats);
return 1;
}
@@ -768,8 +766,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
}
#endif
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
#ifdef NOT_YET
if (ieee->iw_mode == IW_MODE_MASTER && !wds && ieee->ap->bridge_packets) {
@@ -811,7 +809,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
* in our stats. */
IEEE80211_DEBUG_DROP
("RX: netif_rx dropped the packet\n");
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
}
}
@@ -823,7 +821,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
return 1;
rx_dropped:
- stats->rx_dropped++;
+ dev->stats.rx_dropped++;
/* Returning 0 indicates to caller that we have not handled the SKB--
* so it is still allocated and can be used again by underlying
@@ -918,7 +916,7 @@ void ieee80211_rx_any(struct ieee80211_device *ieee,
drop_free:
dev_kfree_skb_irq(skb);
- ieee->stats.rx_dropped++;
+ ieee->dev->stats.rx_dropped++;
return;
}
@@ -1079,37 +1077,37 @@ static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
return rc;
}
-#ifdef CONFIG_IEEE80211_DEBUG
-#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
+#ifdef CONFIG_LIBIPW_DEBUG
+#define MFIE_STRING(x) case WLAN_EID_ ##x: return #x
static const char *get_info_element_string(u16 id)
{
switch (id) {
MFIE_STRING(SSID);
- MFIE_STRING(RATES);
- MFIE_STRING(FH_SET);
- MFIE_STRING(DS_SET);
- MFIE_STRING(CF_SET);
+ MFIE_STRING(SUPP_RATES);
+ MFIE_STRING(FH_PARAMS);
+ MFIE_STRING(DS_PARAMS);
+ MFIE_STRING(CF_PARAMS);
MFIE_STRING(TIM);
- MFIE_STRING(IBSS_SET);
+ MFIE_STRING(IBSS_PARAMS);
MFIE_STRING(COUNTRY);
- MFIE_STRING(HOP_PARAMS);
- MFIE_STRING(HOP_TABLE);
+ MFIE_STRING(HP_PARAMS);
+ MFIE_STRING(HP_TABLE);
MFIE_STRING(REQUEST);
MFIE_STRING(CHALLENGE);
- MFIE_STRING(POWER_CONSTRAINT);
- MFIE_STRING(POWER_CAPABILITY);
+ MFIE_STRING(PWR_CONSTRAINT);
+ MFIE_STRING(PWR_CAPABILITY);
MFIE_STRING(TPC_REQUEST);
MFIE_STRING(TPC_REPORT);
- MFIE_STRING(SUPP_CHANNELS);
- MFIE_STRING(CSA);
+ MFIE_STRING(SUPPORTED_CHANNELS);
+ MFIE_STRING(CHANNEL_SWITCH);
MFIE_STRING(MEASURE_REQUEST);
MFIE_STRING(MEASURE_REPORT);
MFIE_STRING(QUIET);
MFIE_STRING(IBSS_DFS);
MFIE_STRING(ERP_INFO);
MFIE_STRING(RSN);
- MFIE_STRING(RATES_EX);
+ MFIE_STRING(EXT_SUPP_RATES);
MFIE_STRING(GENERIC);
MFIE_STRING(QOS_PARAMETER);
default:
@@ -1124,7 +1122,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
{
DECLARE_SSID_BUF(ssid);
u8 i;
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
char rates_str[64];
char *p;
#endif
@@ -1144,7 +1142,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
}
switch (info_element->id) {
- case MFIE_TYPE_SSID:
+ case WLAN_EID_SSID:
network->ssid_len = min(info_element->len,
(u8) IW_ESSID_MAX_SIZE);
memcpy(network->ssid, info_element->data,
@@ -1153,21 +1151,21 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
memset(network->ssid + network->ssid_len, 0,
IW_ESSID_MAX_SIZE - network->ssid_len);
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
+ IEEE80211_DEBUG_MGMT("WLAN_EID_SSID: '%s' len=%d.\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
network->ssid_len);
break;
- case MFIE_TYPE_RATES:
-#ifdef CONFIG_IEEE80211_DEBUG
+ case WLAN_EID_SUPP_RATES:
+#ifdef CONFIG_LIBIPW_DEBUG
p = rates_str;
#endif
network->rates_len = min(info_element->len,
MAX_RATES_LENGTH);
for (i = 0; i < network->rates_len; i++) {
network->rates[i] = info_element->data[i];
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
p += snprintf(p, sizeof(rates_str) -
(p - rates_str), "%02X ",
network->rates[i]);
@@ -1182,19 +1180,19 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
}
}
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
+ IEEE80211_DEBUG_MGMT("WLAN_EID_SUPP_RATES: '%s' (%d)\n",
rates_str, network->rates_len);
break;
- case MFIE_TYPE_RATES_EX:
-#ifdef CONFIG_IEEE80211_DEBUG
+ case WLAN_EID_EXT_SUPP_RATES:
+#ifdef CONFIG_LIBIPW_DEBUG
p = rates_str;
#endif
network->rates_ex_len = min(info_element->len,
MAX_RATES_EX_LENGTH);
for (i = 0; i < network->rates_ex_len; i++) {
network->rates_ex[i] = info_element->data[i];
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
p += snprintf(p, sizeof(rates_str) -
(p - rates_str), "%02X ",
network->rates[i]);
@@ -1209,49 +1207,49 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
}
}
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
+ IEEE80211_DEBUG_MGMT("WLAN_EID_EXT_SUPP_RATES: '%s' (%d)\n",
rates_str, network->rates_ex_len);
break;
- case MFIE_TYPE_DS_SET:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
+ case WLAN_EID_DS_PARAMS:
+ IEEE80211_DEBUG_MGMT("WLAN_EID_DS_PARAMS: %d\n",
info_element->data[0]);
network->channel = info_element->data[0];
break;
- case MFIE_TYPE_FH_SET:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
+ case WLAN_EID_FH_PARAMS:
+ IEEE80211_DEBUG_MGMT("WLAN_EID_FH_PARAMS: ignored\n");
break;
- case MFIE_TYPE_CF_SET:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
+ case WLAN_EID_CF_PARAMS:
+ IEEE80211_DEBUG_MGMT("WLAN_EID_CF_PARAMS: ignored\n");
break;
- case MFIE_TYPE_TIM:
+ case WLAN_EID_TIM:
network->tim.tim_count = info_element->data[0];
network->tim.tim_period = info_element->data[1];
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n");
+ IEEE80211_DEBUG_MGMT("WLAN_EID_TIM: partially ignored\n");
break;
- case MFIE_TYPE_ERP_INFO:
+ case WLAN_EID_ERP_INFO:
network->erp_value = info_element->data[0];
network->flags |= NETWORK_HAS_ERP_VALUE;
IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
network->erp_value);
break;
- case MFIE_TYPE_IBSS_SET:
+ case WLAN_EID_IBSS_PARAMS:
network->atim_window = info_element->data[0];
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
+ IEEE80211_DEBUG_MGMT("WLAN_EID_IBSS_PARAMS: %d\n",
network->atim_window);
break;
- case MFIE_TYPE_CHALLENGE:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
+ case WLAN_EID_CHALLENGE:
+ IEEE80211_DEBUG_MGMT("WLAN_EID_CHALLENGE: ignored\n");
break;
- case MFIE_TYPE_GENERIC:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
+ case WLAN_EID_GENERIC:
+ IEEE80211_DEBUG_MGMT("WLAN_EID_GENERIC: %d bytes\n",
info_element->len);
if (!ieee80211_parse_qos_info_param_IE(info_element,
network))
@@ -1269,8 +1267,8 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
}
break;
- case MFIE_TYPE_RSN:
- IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
+ case WLAN_EID_RSN:
+ IEEE80211_DEBUG_MGMT("WLAN_EID_RSN: %d bytes\n",
info_element->len);
network->rsn_ie_len = min(info_element->len + 2,
MAX_WPA_IE_LEN);
@@ -1278,22 +1276,22 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
network->rsn_ie_len);
break;
- case MFIE_TYPE_QOS_PARAMETER:
+ case WLAN_EID_QOS_PARAMETER:
printk(KERN_ERR
"QoS Error need to parse QOS_PARAMETER IE\n");
break;
/* 802.11h */
- case MFIE_TYPE_POWER_CONSTRAINT:
+ case WLAN_EID_PWR_CONSTRAINT:
network->power_constraint = info_element->data[0];
network->flags |= NETWORK_HAS_POWER_CONSTRAINT;
break;
- case MFIE_TYPE_CSA:
+ case WLAN_EID_CHANNEL_SWITCH:
network->power_constraint = info_element->data[0];
network->flags |= NETWORK_HAS_CSA;
break;
- case MFIE_TYPE_QUIET:
+ case WLAN_EID_QUIET:
network->quiet.count = info_element->data[0];
network->quiet.period = info_element->data[1];
network->quiet.duration = info_element->data[2];
@@ -1301,7 +1299,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
network->flags |= NETWORK_HAS_QUIET;
break;
- case MFIE_TYPE_IBSS_DFS:
+ case WLAN_EID_IBSS_DFS:
if (network->ibss_dfs)
break;
network->ibss_dfs = kmemdup(info_element->data,
@@ -1312,7 +1310,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
network->flags |= NETWORK_HAS_IBSS_DFS;
break;
- case MFIE_TYPE_TPC_REPORT:
+ case WLAN_EID_TPC_REPORT:
network->tpc_report.transmit_power =
info_element->data[0];
network->tpc_report.link_margin = info_element->data[1];
@@ -1561,7 +1559,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
};
struct ieee80211_network *target;
struct ieee80211_network *oldest = NULL;
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
struct ieee80211_info_element *info_element = beacon->info_element;
#endif
unsigned long flags;
@@ -1615,7 +1613,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
break;
if ((oldest == NULL) ||
- (target->last_scanned < oldest->last_scanned))
+ time_before(target->last_scanned, oldest->last_scanned))
oldest = target;
}
@@ -1639,7 +1637,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
list_del(ieee->network_free_list.next);
}
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
print_ssid(ssid, network.ssid,
network.ssid_len),
diff --git a/drivers/net/wireless/ipw2x00/libipw_tx.c b/drivers/net/wireless/ipw2x00/libipw_tx.c
index f78f57e8844a..65a8195b3d90 100644
--- a/drivers/net/wireless/ipw2x00/libipw_tx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_tx.c
@@ -41,7 +41,7 @@
#include <linux/etherdevice.h>
#include <asm/uaccess.h>
-#include <net/ieee80211.h>
+#include "ieee80211.h"
/*
@@ -260,7 +260,6 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
rts_required;
unsigned long flags;
- struct net_device_stats *stats = &ieee->stats;
int encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
__be16 ether_type;
int bytes, fc, hdr_len;
@@ -306,7 +305,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
if (!encrypt && ieee->ieee802_1x &&
ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) {
- stats->tx_dropped++;
+ dev->stats.tx_dropped++;
goto success;
}
@@ -526,8 +525,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
if (txb) {
int ret = (*ieee->hard_start_xmit) (txb, dev, priority);
if (ret == 0) {
- stats->tx_packets++;
- stats->tx_bytes += txb->payload_size;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += txb->payload_size;
return 0;
}
@@ -539,8 +538,9 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
failed:
spin_unlock_irqrestore(&ieee->lock, flags);
netif_stop_queue(dev);
- stats->tx_errors++;
+ dev->stats.tx_errors++;
return 1;
}
+EXPORT_SYMBOL(ieee80211_xmit);
EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c
index 31ea3abfc327..3c0812db030a 100644
--- a/drivers/net/wireless/ipw2x00/libipw_wx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_wx.c
@@ -35,13 +35,24 @@
#include <linux/jiffies.h>
#include <net/lib80211.h>
-#include <net/ieee80211.h>
#include <linux/wireless.h>
+#include "ieee80211.h"
+
static const char *ieee80211_modes[] = {
"?", "a", "b", "ab", "g", "ag", "bg", "abg"
};
+static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
+{
+ unsigned long end = jiffies;
+
+ if (end >= start)
+ return jiffies_to_msecs(end - start);
+
+ return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
+}
+
#define MAX_CUSTOM_LEN 64
static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
char *start, char *stop,
@@ -215,8 +226,8 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
iwe.cmd = IWEVCUSTOM;
p = custom;
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- " Last beacon: %dms ago",
- jiffies_to_msecs(jiffies - network->last_scanned));
+ " Last beacon: %ums ago",
+ elapsed_jiffies_msecs(network->last_scanned));
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
start = iwe_stream_add_point(info, start, stop, &iwe, custom);
@@ -276,15 +287,15 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
time_after(network->last_scanned + ieee->scan_age, jiffies))
ev = ieee80211_translate_scan(ieee, ev, stop, network,
info);
- else
+ else {
IEEE80211_DEBUG_SCAN("Not showing network '%s ("
- "%pM)' due to age (%dms).\n",
+ "%pM)' due to age (%ums).\n",
print_ssid(ssid, network->ssid,
network->ssid_len),
network->bssid,
- jiffies_to_msecs(jiffies -
- network->
- last_scanned));
+ elapsed_jiffies_msecs(
+ network->last_scanned));
+ }
}
spin_unlock_irqrestore(&ieee->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 47bee0ee0a7c..8304f6406a17 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -1,26 +1,29 @@
config IWLWIFI
- tristate
-
-config IWLCORE
- tristate "Intel Wireless Wifi Core"
+ tristate "Intel Wireless Wifi"
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
select LIB80211
- select IWLWIFI
+ select FW_LOADER
select MAC80211_LEDS if IWLWIFI_LEDS
select LEDS_CLASS if IWLWIFI_LEDS
select RFKILL if IWLWIFI_RFKILL
config IWLWIFI_LEDS
- bool
- default n
+ bool "Enable LED support in iwlagn and iwl3945 drivers"
+ depends on IWLWIFI
config IWLWIFI_RFKILL
- boolean "Iwlwifi RF kill support"
- depends on IWLCORE
+ bool "Enable RF kill support in iwlagn and iwl3945 drivers"
+ depends on IWLWIFI
+
+config IWLWIFI_SPECTRUM_MEASUREMENT
+ bool "Enable Spectrum Measurement in iwlagn driver"
+ depends on IWLWIFI
+ ---help---
+ This option will enable spectrum measurement for the iwlagn driver.
config IWLWIFI_DEBUG
- bool "Enable full debugging output in iwlagn driver"
- depends on IWLCORE
+ bool "Enable full debugging output in iwlagn and iwl3945 drivers"
+ depends on IWLWIFI
---help---
This option will enable debug tracing output for the iwlwifi drivers
@@ -44,16 +47,14 @@ config IWLWIFI_DEBUG
any problems you may encounter.
config IWLWIFI_DEBUGFS
- bool "Iwlwifi debugfs support"
- depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
+ bool "iwlagn debugfs support"
+ depends on IWLWIFI && IWLWIFI_DEBUG && MAC80211_DEBUGFS
---help---
Enable creation of debugfs files for the iwlwifi drivers.
config IWLAGN
- tristate "Intel Wireless WiFi Next Gen AGN"
- depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
- select FW_LOADER
- select IWLCORE
+ tristate "Intel Wireless WiFi Next Gen AGN (iwlagn)"
+ depends on IWLWIFI
---help---
Select to build the driver supporting the:
@@ -76,19 +77,6 @@ config IWLAGN
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwlagn.ko.
-config IWLAGN_SPECTRUM_MEASUREMENT
- bool "Enable Spectrum Measurement in iwlagn driver"
- depends on IWLAGN
- ---help---
- This option will enable spectrum measurement for the iwlagn driver.
-
-config IWLAGN_LEDS
- bool "Enable LEDS features in iwlagn driver"
- depends on IWLAGN
- select IWLWIFI_LEDS
- ---help---
- This option enables LEDS for the iwlagn drivers
-
config IWL4965
bool "Intel Wireless WiFi 4965AGN"
@@ -97,20 +85,14 @@ config IWL4965
This option enables support for Intel Wireless WiFi Link 4965AGN
config IWL5000
- bool "Intel Wireless WiFi 5000AGN"
+ bool "Intel Wireless WiFi 5000AGN; Intel WiFi Link 1000, 6000, and 6050 Series"
depends on IWLAGN
---help---
This option enables support for Intel Wireless WiFi Link 5000AGN Family
config IWL3945
- tristate "Intel PRO/Wireless 3945ABG/BG Network Connection"
- depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
- select FW_LOADER
- select LIB80211
- select IWLWIFI
- select MAC80211_LEDS if IWL3945_LEDS
- select LEDS_CLASS if IWL3945_LEDS
- select RFKILL if IWL3945_RFKILL
+ tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)"
+ depends on IWLWIFI
---help---
Select to build the driver supporting the:
@@ -133,45 +115,8 @@ config IWL3945
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl3945.ko.
-config IWL3945_RFKILL
- bool "Enable RF kill support in iwl3945 drivers"
- depends on IWL3945
-
config IWL3945_SPECTRUM_MEASUREMENT
- bool "Enable Spectrum Measurement in iwl3945 drivers"
+ bool "Enable Spectrum Measurement in iwl3945 driver"
depends on IWL3945
---help---
This option will enable spectrum measurement for the iwl3945 driver.
-
-config IWL3945_LEDS
- bool "Enable LEDS features in iwl3945 driver"
- depends on IWL3945
- ---help---
- This option enables LEDS for the iwl3945 driver.
-
-config IWL3945_DEBUG
- bool "Enable full debugging output in iwl3945 driver"
- depends on IWL3945
- ---help---
- This option will enable debug tracing output for the iwl3945
- driver.
-
- This will result in the kernel module being ~100k larger. You can
- control which debug output is sent to the kernel log by setting the
- value in
-
- /sys/bus/pci/drivers/${DRIVER}/debug_level
-
- This entry will only exist if this option is enabled.
-
- To set a value, simply echo an 8-byte hex value to the same file:
-
- % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level
-
- You can find the list of debug mask values in:
- drivers/net/wireless/iwlwifi/iwl-3945-debug.h
-
- If this is your first time using this driver, you should say Y here
- as the debug information can assist others in helping you resolve
- any problems you may encounter.
-
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 0be9e6b66aa0..d79d97ad61a5 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -1,20 +1,21 @@
-obj-$(CONFIG_IWLCORE) += iwlcore.o
+obj-$(CONFIG_IWLWIFI) += iwlcore.o
iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
iwlcore-objs += iwl-scan.o
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
-iwlcore-$(CONFIG_IWLAGN_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
+iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
obj-$(CONFIG_IWLAGN) += iwlagn.o
-iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-hcmd-check.o
+iwlagn-objs := iwl-agn.o iwl-agn-rs.o
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
+iwlagn-$(CONFIG_IWL5000) += iwl-6000.o
+iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
obj-$(CONFIG_IWL3945) += iwl3945.o
-iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o
-iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o
+iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
new file mode 100644
index 000000000000..7da52f1cc1d6
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -0,0 +1,73 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2008-2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <net/mac80211.h>
+#include <linux/etherdevice.h>
+#include <asm/unaligned.h>
+
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-sta.h"
+#include "iwl-helpers.h"
+#include "iwl-5000-hw.h"
+
+/* Highest firmware API version supported */
+#define IWL1000_UCODE_API_MAX 2
+
+/* Lowest firmware API version supported */
+#define IWL1000_UCODE_API_MIN 1
+
+#define IWL1000_FW_PRE "iwlwifi-1000-"
+#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
+#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api)
+
+struct iwl_cfg iwl1000_bgn_cfg = {
+ .name = "1000 Series BGN",
+ .fw_name_pre = IWL1000_FW_PRE,
+ .ucode_api_max = IWL1000_UCODE_API_MAX,
+ .ucode_api_min = IWL1000_UCODE_API_MIN,
+ .sku = IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl5000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = true,
+};
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
deleted file mode 100644
index c6f4eb54a2b1..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
+++ /dev/null
@@ -1,1702 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license. When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *****************************************************************************/
-/*
- * Please use this file (iwl-3945-commands.h) only for uCode API definitions.
- * Please use iwl-3945-hw.h for hardware-related definitions.
- * Please use iwl-3945.h for driver implementation definitions.
- */
-
-#ifndef __iwl_3945_commands_h__
-#define __iwl_3945_commands_h__
-
-/* uCode version contains 4 values: Major/Minor/API/Serial */
-#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24)
-#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16)
-#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8)
-#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF)
-
-enum {
- REPLY_ALIVE = 0x1,
- REPLY_ERROR = 0x2,
-
- /* RXON and QOS commands */
- REPLY_RXON = 0x10,
- REPLY_RXON_ASSOC = 0x11,
- REPLY_QOS_PARAM = 0x13,
- REPLY_RXON_TIMING = 0x14,
-
- /* Multi-Station support */
- REPLY_ADD_STA = 0x18,
- REPLY_REMOVE_STA = 0x19, /* not used */
- REPLY_REMOVE_ALL_STA = 0x1a, /* not used */
-
- /* RX, TX, LEDs */
- REPLY_3945_RX = 0x1b, /* 3945 only */
- REPLY_TX = 0x1c,
- REPLY_RATE_SCALE = 0x47, /* 3945 only */
- REPLY_LEDS_CMD = 0x48,
- REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */
-
- /* 802.11h related */
- RADAR_NOTIFICATION = 0x70, /* not used */
- REPLY_QUIET_CMD = 0x71, /* not used */
- REPLY_CHANNEL_SWITCH = 0x72,
- CHANNEL_SWITCH_NOTIFICATION = 0x73,
- REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74,
- SPECTRUM_MEASURE_NOTIFICATION = 0x75,
-
- /* Power Management */
- POWER_TABLE_CMD = 0x77,
- PM_SLEEP_NOTIFICATION = 0x7A,
- PM_DEBUG_STATISTIC_NOTIFIC = 0x7B,
-
- /* Scan commands and notifications */
- REPLY_SCAN_CMD = 0x80,
- REPLY_SCAN_ABORT_CMD = 0x81,
- SCAN_START_NOTIFICATION = 0x82,
- SCAN_RESULTS_NOTIFICATION = 0x83,
- SCAN_COMPLETE_NOTIFICATION = 0x84,
-
- /* IBSS/AP commands */
- BEACON_NOTIFICATION = 0x90,
- REPLY_TX_BEACON = 0x91,
- WHO_IS_AWAKE_NOTIFICATION = 0x94, /* not used */
-
- /* Miscellaneous commands */
- QUIET_NOTIFICATION = 0x96, /* not used */
- REPLY_TX_PWR_TABLE_CMD = 0x97,
- MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */
-
- /* Bluetooth device coexistence config command */
- REPLY_BT_CONFIG = 0x9b,
-
- /* Statistics */
- REPLY_STATISTICS_CMD = 0x9c,
- STATISTICS_NOTIFICATION = 0x9d,
-
- /* RF-KILL commands and notifications */
- REPLY_CARD_STATE_CMD = 0xa0,
- CARD_STATE_NOTIFICATION = 0xa1,
-
- /* Missed beacons notification */
- MISSED_BEACONS_NOTIFICATION = 0xa2,
-
- REPLY_MAX = 0xff
-};
-
-/******************************************************************************
- * (0)
- * Commonly used structures and definitions:
- * Command header, txpower
- *
- *****************************************************************************/
-
-/* iwl3945_cmd_header flags value */
-#define IWL_CMD_FAILED_MSK 0x40
-
-/**
- * struct iwl3945_cmd_header
- *
- * This header format appears in the beginning of each command sent from the
- * driver, and each response/notification received from uCode.
- */
-struct iwl3945_cmd_header {
- u8 cmd; /* Command ID: REPLY_RXON, etc. */
- u8 flags; /* IWL_CMD_* */
- /*
- * The driver sets up the sequence number to values of its choosing.
- * uCode does not use this value, but passes it back to the driver
- * when sending the response to each driver-originated command, so
- * the driver can match the response to the command. Since the values
- * don't get used by uCode, the driver may set up an arbitrary format.
- *
- * There is one exception: uCode sets bit 15 when it originates
- * the response/notification, i.e. when the response/notification
- * is not a direct response to a command sent by the driver. For
- * example, uCode issues REPLY_3945_RX when it sends a received frame
- * to the driver; it is not a direct response to any driver command.
- *
- * The Linux driver uses the following format:
- *
- * 0:7 index/position within Tx queue
- * 8:13 Tx queue selection
- * 14:14 driver sets this to indicate command is in the 'huge'
- * storage at the end of the command buffers, i.e. scan cmd
- * 15:15 uCode sets this in uCode-originated response/notification
- */
- __le16 sequence;
-
- /* command or response/notification data follows immediately */
- u8 data[0];
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_tx_power
- *
- * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH
- *
- * Each entry contains two values:
- * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained
- * linear value that multiplies the output of the digital signal processor,
- * before being sent to the analog radio.
- * 2) Radio gain. This sets the analog gain of the radio Tx path.
- * It is a coarser setting, and behaves in a logarithmic (dB) fashion.
- *
- * Driver obtains values from struct iwl3945_tx_power power_gain_table[][].
- */
-struct iwl3945_tx_power {
- u8 tx_gain; /* gain for analog radio */
- u8 dsp_atten; /* gain for DSP */
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_power_per_rate
- *
- * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
- */
-struct iwl3945_power_per_rate {
- u8 rate; /* plcp */
- struct iwl3945_tx_power tpc;
- u8 reserved;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (0a)
- * Alive and Error Commands & Responses:
- *
- *****************************************************************************/
-
-#define UCODE_VALID_OK cpu_to_le32(0x1)
-#define INITIALIZE_SUBTYPE (9)
-
-/*
- * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command)
- *
- * uCode issues this "initialize alive" notification once the initialization
- * uCode image has completed its work, and is ready to load the runtime image.
- * This is the *first* "alive" notification that the driver will receive after
- * rebooting uCode; the "initialize" alive is indicated by subtype field == 9.
- *
- * See comments documenting "BSM" (bootstrap state machine).
- */
-struct iwl3945_init_alive_resp {
- u8 ucode_minor;
- u8 ucode_major;
- __le16 reserved1;
- u8 sw_rev[8];
- u8 ver_type;
- u8 ver_subtype; /* "9" for initialize alive */
- __le16 reserved2;
- __le32 log_event_table_ptr;
- __le32 error_event_table_ptr;
- __le32 timestamp;
- __le32 is_valid;
-} __attribute__ ((packed));
-
-
-/**
- * REPLY_ALIVE = 0x1 (response only, not a command)
- *
- * uCode issues this "alive" notification once the runtime image is ready
- * to receive commands from the driver. This is the *second* "alive"
- * notification that the driver will receive after rebooting uCode;
- * this "alive" is indicated by subtype field != 9.
- *
- * See comments documenting "BSM" (bootstrap state machine).
- *
- * This response includes two pointers to structures within the device's
- * data SRAM (access via HBUS_TARG_MEM_* regs) that are useful for debugging:
- *
- * 1) log_event_table_ptr indicates base of the event log. This traces
- * a 256-entry history of uCode execution within a circular buffer.
- *
- * 2) error_event_table_ptr indicates base of the error log. This contains
- * information about any uCode error that occurs.
- *
- * The Linux driver can print both logs to the system log when a uCode error
- * occurs.
- */
-struct iwl3945_alive_resp {
- u8 ucode_minor;
- u8 ucode_major;
- __le16 reserved1;
- u8 sw_rev[8];
- u8 ver_type;
- u8 ver_subtype; /* not "9" for runtime alive */
- __le16 reserved2;
- __le32 log_event_table_ptr; /* SRAM address for event log */
- __le32 error_event_table_ptr; /* SRAM address for error log */
- __le32 timestamp;
- __le32 is_valid;
-} __attribute__ ((packed));
-
-union tsf {
- u8 byte[8];
- __le16 word[4];
- __le32 dw[2];
-};
-
-/*
- * REPLY_ERROR = 0x2 (response only, not a command)
- */
-struct iwl3945_error_resp {
- __le32 error_type;
- u8 cmd_id;
- u8 reserved1;
- __le16 bad_cmd_seq_num;
- __le16 reserved2;
- __le32 error_info;
- union tsf timestamp;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (1)
- * RXON Commands & Responses:
- *
- *****************************************************************************/
-
-/*
- * Rx config defines & structure
- */
-/* rx_config device types */
-enum {
- RXON_DEV_TYPE_AP = 1,
- RXON_DEV_TYPE_ESS = 3,
- RXON_DEV_TYPE_IBSS = 4,
- RXON_DEV_TYPE_SNIFFER = 6,
-};
-
-/* rx_config flags */
-/* band & modulation selection */
-#define RXON_FLG_BAND_24G_MSK cpu_to_le32(1 << 0)
-#define RXON_FLG_CCK_MSK cpu_to_le32(1 << 1)
-/* auto detection enable */
-#define RXON_FLG_AUTO_DETECT_MSK cpu_to_le32(1 << 2)
-/* TGg protection when tx */
-#define RXON_FLG_TGG_PROTECT_MSK cpu_to_le32(1 << 3)
-/* cck short slot & preamble */
-#define RXON_FLG_SHORT_SLOT_MSK cpu_to_le32(1 << 4)
-#define RXON_FLG_SHORT_PREAMBLE_MSK cpu_to_le32(1 << 5)
-/* antenna selection */
-#define RXON_FLG_DIS_DIV_MSK cpu_to_le32(1 << 7)
-#define RXON_FLG_ANT_SEL_MSK cpu_to_le32(0x0f00)
-#define RXON_FLG_ANT_A_MSK cpu_to_le32(1 << 8)
-#define RXON_FLG_ANT_B_MSK cpu_to_le32(1 << 9)
-/* radar detection enable */
-#define RXON_FLG_RADAR_DETECT_MSK cpu_to_le32(1 << 12)
-#define RXON_FLG_TGJ_NARROW_BAND_MSK cpu_to_le32(1 << 13)
-/* rx response to host with 8-byte TSF
-* (according to ON_AIR deassertion) */
-#define RXON_FLG_TSF2HOST_MSK cpu_to_le32(1 << 15)
-
-/* rx_config filter flags */
-/* accept all data frames */
-#define RXON_FILTER_PROMISC_MSK cpu_to_le32(1 << 0)
-/* pass control & management to host */
-#define RXON_FILTER_CTL2HOST_MSK cpu_to_le32(1 << 1)
-/* accept multi-cast */
-#define RXON_FILTER_ACCEPT_GRP_MSK cpu_to_le32(1 << 2)
-/* don't decrypt uni-cast frames */
-#define RXON_FILTER_DIS_DECRYPT_MSK cpu_to_le32(1 << 3)
-/* don't decrypt multi-cast frames */
-#define RXON_FILTER_DIS_GRP_DECRYPT_MSK cpu_to_le32(1 << 4)
-/* STA is associated */
-#define RXON_FILTER_ASSOC_MSK cpu_to_le32(1 << 5)
-/* transfer to host non bssid beacons in associated state */
-#define RXON_FILTER_BCON_AWARE_MSK cpu_to_le32(1 << 6)
-
-/**
- * REPLY_RXON = 0x10 (command, has simple generic response)
- *
- * RXON tunes the radio tuner to a service channel, and sets up a number
- * of parameters that are used primarily for Rx, but also for Tx operations.
- *
- * NOTE: When tuning to a new channel, driver must set the
- * RXON_FILTER_ASSOC_MSK to 0. This will clear station-dependent
- * info within the device, including the station tables, tx retry
- * rate tables, and txpower tables. Driver must build a new station
- * table and txpower table before transmitting anything on the RXON
- * channel.
- *
- * NOTE: All RXONs wipe clean the internal txpower table. Driver must
- * issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10),
- * regardless of whether RXON_FILTER_ASSOC_MSK is set.
- */
-struct iwl3945_rxon_cmd {
- u8 node_addr[6];
- __le16 reserved1;
- u8 bssid_addr[6];
- __le16 reserved2;
- u8 wlap_bssid_addr[6];
- __le16 reserved3;
- u8 dev_type;
- u8 air_propagation;
- __le16 reserved4;
- u8 ofdm_basic_rates;
- u8 cck_basic_rates;
- __le16 assoc_id;
- __le32 flags;
- __le32 filter_flags;
- __le16 channel;
- __le16 reserved5;
-} __attribute__ ((packed));
-
-/*
- * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
- */
-struct iwl3945_rxon_assoc_cmd {
- __le32 flags;
- __le32 filter_flags;
- u8 ofdm_basic_rates;
- u8 cck_basic_rates;
- __le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
- */
-struct iwl3945_rxon_time_cmd {
- union tsf timestamp;
- __le16 beacon_interval;
- __le16 atim_window;
- __le32 beacon_init_val;
- __le16 listen_interval;
- __le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
- */
-struct iwl3945_channel_switch_cmd {
- u8 band;
- u8 expect_beacon;
- __le16 channel;
- __le32 rxon_flags;
- __le32 rxon_filter_flags;
- __le32 switch_time;
- struct iwl3945_power_per_rate power[IWL_MAX_RATES];
-} __attribute__ ((packed));
-
-/*
- * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command)
- */
-struct iwl3945_csa_notification {
- __le16 band;
- __le16 channel;
- __le32 status; /* 0 - OK, 1 - fail */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (2)
- * Quality-of-Service (QOS) Commands & Responses:
- *
- *****************************************************************************/
-
-/**
- * struct iwl_ac_qos -- QOS timing params for REPLY_QOS_PARAM
- * One for each of 4 EDCA access categories in struct iwl_qosparam_cmd
- *
- * @cw_min: Contention window, start value in numbers of slots.
- * Should be a power-of-2, minus 1. Device's default is 0x0f.
- * @cw_max: Contention window, max value in numbers of slots.
- * Should be a power-of-2, minus 1. Device's default is 0x3f.
- * @aifsn: Number of slots in Arbitration Interframe Space (before
- * performing random backoff timing prior to Tx). Device default 1.
- * @edca_txop: Length of Tx opportunity, in uSecs. Device default is 0.
- *
- * Device will automatically increase contention window by (2*CW) + 1 for each
- * transmission retry. Device uses cw_max as a bit mask, ANDed with new CW
- * value, to cap the CW value.
- */
-struct iwl3945_ac_qos {
- __le16 cw_min;
- __le16 cw_max;
- u8 aifsn;
- u8 reserved1;
- __le16 edca_txop;
-} __attribute__ ((packed));
-
-/* QoS flags defines */
-#define QOS_PARAM_FLG_UPDATE_EDCA_MSK cpu_to_le32(0x01)
-#define QOS_PARAM_FLG_TGN_MSK cpu_to_le32(0x02)
-#define QOS_PARAM_FLG_TXOP_TYPE_MSK cpu_to_le32(0x10)
-
-/* Number of Access Categories (AC) (EDCA), queues 0..3 */
-#define AC_NUM 4
-
-/*
- * REPLY_QOS_PARAM = 0x13 (command, has simple generic response)
- *
- * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs
- * 0: Background, 1: Best Effort, 2: Video, 3: Voice.
- */
-struct iwl3945_qosparam_cmd {
- __le32 qos_flags;
- struct iwl3945_ac_qos ac[AC_NUM];
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (3)
- * Add/Modify Stations Commands & Responses:
- *
- *****************************************************************************/
-/*
- * Multi station support
- */
-
-/* Special, dedicated locations within device's station table */
-#define IWL_AP_ID 0
-#define IWL_MULTICAST_ID 1
-#define IWL_STA_ID 2
-#define IWL3945_BROADCAST_ID 24
-#define IWL3945_STATION_COUNT 25
-
-#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
-#define IWL_INVALID_STATION 255
-
-#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2);
-#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8);
-
-/* Use in mode field. 1: modify existing entry, 0: add new station entry */
-#define STA_CONTROL_MODIFY_MSK 0x01
-
-/* key flags __le16*/
-#define STA_KEY_FLG_ENCRYPT_MSK cpu_to_le16(0x0007)
-#define STA_KEY_FLG_NO_ENC cpu_to_le16(0x0000)
-#define STA_KEY_FLG_WEP cpu_to_le16(0x0001)
-#define STA_KEY_FLG_CCMP cpu_to_le16(0x0002)
-#define STA_KEY_FLG_TKIP cpu_to_le16(0x0003)
-
-#define STA_KEY_FLG_KEYID_POS 8
-#define STA_KEY_FLG_INVALID cpu_to_le16(0x0800)
-/* wep key is either from global key (0) or from station info array (1) */
-#define STA_KEY_FLG_WEP_KEY_MAP_MSK cpu_to_le16(0x0008)
-
-/* wep key in STA: 5-bytes (0) or 13-bytes (1) */
-#define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000)
-#define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000)
-
-/* Flags indicate whether to modify vs. don't change various station params */
-#define STA_MODIFY_KEY_MASK 0x01
-#define STA_MODIFY_TID_DISABLE_TX 0x02
-#define STA_MODIFY_TX_RATE_MSK 0x04
-
-/*
- * Antenna masks:
- * bit14:15 01 B inactive, A active
- * 10 B active, A inactive
- * 11 Both active
- */
-#define RATE_MCS_ANT_A_POS 14
-#define RATE_MCS_ANT_B_POS 15
-#define RATE_MCS_ANT_A_MSK 0x4000
-#define RATE_MCS_ANT_B_MSK 0x8000
-#define RATE_MCS_ANT_AB_MSK 0xc000
-
-struct iwl3945_keyinfo {
- __le16 key_flags;
- u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */
- u8 reserved1;
- __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */
- u8 key_offset;
- u8 reserved2;
- u8 key[16]; /* 16-byte unicast decryption key */
-} __attribute__ ((packed));
-
-/**
- * struct sta_id_modify
- * @addr[ETH_ALEN]: station's MAC address
- * @sta_id: index of station in uCode's station table
- * @modify_mask: STA_MODIFY_*, 1: modify, 0: don't change
- *
- * Driver selects unused table index when adding new station,
- * or the index to a pre-existing station entry when modifying that station.
- * Some indexes have special purposes (IWL_AP_ID, index 0, is for AP).
- *
- * modify_mask flags select which parameters to modify vs. leave alone.
- */
-struct sta_id_modify {
- u8 addr[ETH_ALEN];
- __le16 reserved1;
- u8 sta_id;
- u8 modify_mask;
- __le16 reserved2;
-} __attribute__ ((packed));
-
-/*
- * REPLY_ADD_STA = 0x18 (command)
- *
- * The device contains an internal table of per-station information,
- * with info on security keys, aggregation parameters, and Tx rates for
- * initial Tx attempt and any retries (4965 uses REPLY_TX_LINK_QUALITY_CMD,
- * 3945 uses REPLY_RATE_SCALE to set up rate tables).
- *
- * REPLY_ADD_STA sets up the table entry for one station, either creating
- * a new entry, or modifying a pre-existing one.
- *
- * NOTE: RXON command (without "associated" bit set) wipes the station table
- * clean. Moving into RF_KILL state does this also. Driver must set up
- * new station table before transmitting anything on the RXON channel
- * (except active scans or active measurements; those commands carry
- * their own txpower/rate setup data).
- *
- * When getting started on a new channel, driver must set up the
- * IWL_BROADCAST_ID entry (last entry in the table). For a client
- * station in a BSS, once an AP is selected, driver sets up the AP STA
- * in the IWL_AP_ID entry (1st entry in the table). BROADCAST and AP
- * are all that are needed for a BSS client station. If the device is
- * used as AP, or in an IBSS network, driver must set up station table
- * entries for all STAs in network, starting with index IWL_STA_ID.
- */
-struct iwl3945_addsta_cmd {
- u8 mode; /* 1: modify existing, 0: add new station */
- u8 reserved[3];
- struct sta_id_modify sta;
- struct iwl3945_keyinfo key;
- __le32 station_flags; /* STA_FLG_* */
- __le32 station_flags_msk; /* STA_FLG_* */
-
- /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
- * corresponding to bit (e.g. bit 5 controls TID 5).
- * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
- __le16 tid_disable_tx;
-
- __le16 rate_n_flags;
-
- /* TID for which to add block-ack support.
- * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
- u8 add_immediate_ba_tid;
-
- /* TID for which to remove block-ack support.
- * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
- u8 remove_immediate_ba_tid;
-
- /* Starting Sequence Number for added block-ack support.
- * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
- __le16 add_immediate_ba_ssn;
-} __attribute__ ((packed));
-
-#define ADD_STA_SUCCESS_MSK 0x1
-#define ADD_STA_NO_ROOM_IN_TABLE 0x2
-#define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4
-/*
- * REPLY_ADD_STA = 0x18 (response)
- */
-struct iwl3945_add_sta_resp {
- u8 status; /* ADD_STA_* */
-} __attribute__ ((packed));
-
-
-/******************************************************************************
- * (4)
- * Rx Responses:
- *
- *****************************************************************************/
-
-struct iwl3945_rx_frame_stats {
- u8 phy_count;
- u8 id;
- u8 rssi;
- u8 agc;
- __le16 sig_avg;
- __le16 noise_diff;
- u8 payload[0];
-} __attribute__ ((packed));
-
-struct iwl3945_rx_frame_hdr {
- __le16 channel;
- __le16 phy_flags;
- u8 reserved1;
- u8 rate;
- __le16 len;
- u8 payload[0];
-} __attribute__ ((packed));
-
-#define RX_RES_STATUS_NO_CRC32_ERROR cpu_to_le32(1 << 0)
-#define RX_RES_STATUS_NO_RXE_OVERFLOW cpu_to_le32(1 << 1)
-
-#define RX_RES_PHY_FLAGS_BAND_24_MSK cpu_to_le16(1 << 0)
-#define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1)
-#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2)
-#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3)
-#define RX_RES_PHY_FLAGS_ANTENNA_MSK cpu_to_le16(0xf0)
-
-#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8)
-#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8)
-#define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8)
-#define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8)
-#define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8)
-
-#define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11)
-#define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11)
-#define RX_RES_STATUS_DECRYPT_OK (0x3 << 11)
-#define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11)
-#define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11)
-
-struct iwl3945_rx_frame_end {
- __le32 status;
- __le64 timestamp;
- __le32 beacon_timestamp;
-} __attribute__ ((packed));
-
-/*
- * REPLY_3945_RX = 0x1b (response only, not a command)
- *
- * NOTE: DO NOT dereference from casts to this structure
- * It is provided only for calculating minimum data set size.
- * The actual offsets of the hdr and end are dynamic based on
- * stats.phy_count
- */
-struct iwl3945_rx_frame {
- struct iwl3945_rx_frame_stats stats;
- struct iwl3945_rx_frame_hdr hdr;
- struct iwl3945_rx_frame_end end;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (5)
- * Tx Commands & Responses:
- *
- * Driver must place each REPLY_TX command into one of the prioritized Tx
- * queues in host DRAM, shared between driver and device. When the device's
- * Tx scheduler and uCode are preparing to transmit, the device pulls the
- * Tx command over the PCI bus via one of the device's Tx DMA channels,
- * to fill an internal FIFO from which data will be transmitted.
- *
- * uCode handles all timing and protocol related to control frames
- * (RTS/CTS/ACK), based on flags in the Tx command.
- *
- * uCode handles retrying Tx when an ACK is expected but not received.
- * This includes trying lower data rates than the one requested in the Tx
- * command, as set up by the REPLY_RATE_SCALE (for 3945) or
- * REPLY_TX_LINK_QUALITY_CMD (4965).
- *
- * Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD.
- * This command must be executed after every RXON command, before Tx can occur.
- *****************************************************************************/
-
-/* REPLY_TX Tx flags field */
-
-/* 1: Use Request-To-Send protocol before this frame.
- * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */
-#define TX_CMD_FLG_RTS_MSK cpu_to_le32(1 << 1)
-
-/* 1: Transmit Clear-To-Send to self before this frame.
- * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames.
- * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */
-#define TX_CMD_FLG_CTS_MSK cpu_to_le32(1 << 2)
-
-/* 1: Expect ACK from receiving station
- * 0: Don't expect ACK (MAC header's duration field s/b 0)
- * Set this for unicast frames, but not broadcast/multicast. */
-#define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3)
-
-/* 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD).
- * Tx command's initial_rate_index indicates first rate to try;
- * uCode walks through table for additional Tx attempts.
- * 0: Use Tx rate/MCS from Tx command's rate_n_flags field.
- * This rate will be used for all Tx attempts; it will not be scaled. */
-#define TX_CMD_FLG_STA_RATE_MSK cpu_to_le32(1 << 4)
-
-/* 1: Expect immediate block-ack.
- * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */
-#define TX_CMD_FLG_IMM_BA_RSP_MASK cpu_to_le32(1 << 6)
-
-/* 1: Frame requires full Tx-Op protection.
- * Set this if either RTS or CTS Tx Flag gets set. */
-#define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7)
-
-/* Tx antenna selection field; used only for 3945, reserved (0) for 4965.
- * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */
-#define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00)
-#define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8)
-#define TX_CMD_FLG_ANT_B_MSK cpu_to_le32(1 << 9)
-
-/* 1: Ignore Bluetooth priority for this frame.
- * 0: Delay Tx until Bluetooth device is done (normal usage). */
-#define TX_CMD_FLG_BT_DIS_MSK cpu_to_le32(1 << 12)
-
-/* 1: uCode overrides sequence control field in MAC header.
- * 0: Driver provides sequence control field in MAC header.
- * Set this for management frames, non-QOS data frames, non-unicast frames,
- * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */
-#define TX_CMD_FLG_SEQ_CTL_MSK cpu_to_le32(1 << 13)
-
-/* 1: This frame is non-last MPDU; more fragments are coming.
- * 0: Last fragment, or not using fragmentation. */
-#define TX_CMD_FLG_MORE_FRAG_MSK cpu_to_le32(1 << 14)
-
-/* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame.
- * 0: No TSF required in outgoing frame.
- * Set this for transmitting beacons and probe responses. */
-#define TX_CMD_FLG_TSF_MSK cpu_to_le32(1 << 16)
-
-/* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword
- * alignment of frame's payload data field.
- * 0: No pad
- * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4
- * field (but not both). Driver must align frame data (i.e. data following
- * MAC header) to DWORD boundary. */
-#define TX_CMD_FLG_MH_PAD_MSK cpu_to_le32(1 << 20)
-
-/* HCCA-AP - disable duration overwriting. */
-#define TX_CMD_FLG_DUR_MSK cpu_to_le32(1 << 25)
-
-/*
- * TX command security control
- */
-#define TX_CMD_SEC_WEP 0x01
-#define TX_CMD_SEC_CCM 0x02
-#define TX_CMD_SEC_TKIP 0x03
-#define TX_CMD_SEC_MSK 0x03
-#define TX_CMD_SEC_SHIFT 6
-#define TX_CMD_SEC_KEY128 0x08
-
-/*
- * REPLY_TX = 0x1c (command)
- */
-struct iwl3945_tx_cmd {
- /*
- * MPDU byte count:
- * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
- * + 8 byte IV for CCM or TKIP (not used for WEP)
- * + Data payload
- * + 8-byte MIC (not used for CCM/WEP)
- * NOTE: Does not include Tx command bytes, post-MAC pad bytes,
- * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
- * Range: 14-2342 bytes.
- */
- __le16 len;
-
- /*
- * MPDU or MSDU byte count for next frame.
- * Used for fragmentation and bursting, but not 11n aggregation.
- * Same as "len", but for next frame. Set to 0 if not applicable.
- */
- __le16 next_frame_len;
-
- __le32 tx_flags; /* TX_CMD_FLG_* */
-
- u8 rate;
-
- /* Index of recipient station in uCode's station table */
- u8 sta_id;
- u8 tid_tspec;
- u8 sec_ctl;
- u8 key[16];
- union {
- u8 byte[8];
- __le16 word[4];
- __le32 dw[2];
- } tkip_mic;
- __le32 next_frame_info;
- union {
- __le32 life_time;
- __le32 attempt;
- } stop_time;
- u8 supp_rates[2];
- u8 rts_retry_limit; /*byte 50 */
- u8 data_retry_limit; /*byte 51 */
- union {
- __le16 pm_frame_timeout;
- __le16 attempt_duration;
- } timeout;
-
- /*
- * Duration of EDCA burst Tx Opportunity, in 32-usec units.
- * Set this if txop time is not specified by HCCA protocol (e.g. by AP).
- */
- __le16 driver_txop;
-
- /*
- * MAC header goes here, followed by 2 bytes padding if MAC header
- * length is 26 or 30 bytes, followed by payload data
- */
- u8 payload[0];
- struct ieee80211_hdr hdr[0];
-} __attribute__ ((packed));
-
-/* TX command response is sent after *all* transmission attempts.
- *
- * NOTES:
- *
- * TX_STATUS_FAIL_NEXT_FRAG
- *
- * If the fragment flag in the MAC header for the frame being transmitted
- * is set and there is insufficient time to transmit the next frame, the
- * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'.
- *
- * TX_STATUS_FIFO_UNDERRUN
- *
- * Indicates the host did not provide bytes to the FIFO fast enough while
- * a TX was in progress.
- *
- * TX_STATUS_FAIL_MGMNT_ABORT
- *
- * This status is only possible if the ABORT ON MGMT RX parameter was
- * set to true with the TX command.
- *
- * If the MSB of the status parameter is set then an abort sequence is
- * required. This sequence consists of the host activating the TX Abort
- * control line, and then waiting for the TX Abort command response. This
- * indicates that a the device is no longer in a transmit state, and that the
- * command FIFO has been cleared. The host must then deactivate the TX Abort
- * control line. Receiving is still allowed in this case.
- */
-enum {
- TX_STATUS_SUCCESS = 0x01,
- TX_STATUS_DIRECT_DONE = 0x02,
- TX_STATUS_FAIL_SHORT_LIMIT = 0x82,
- TX_STATUS_FAIL_LONG_LIMIT = 0x83,
- TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84,
- TX_STATUS_FAIL_MGMNT_ABORT = 0x85,
- TX_STATUS_FAIL_NEXT_FRAG = 0x86,
- TX_STATUS_FAIL_LIFE_EXPIRE = 0x87,
- TX_STATUS_FAIL_DEST_PS = 0x88,
- TX_STATUS_FAIL_ABORTED = 0x89,
- TX_STATUS_FAIL_BT_RETRY = 0x8a,
- TX_STATUS_FAIL_STA_INVALID = 0x8b,
- TX_STATUS_FAIL_FRAG_DROPPED = 0x8c,
- TX_STATUS_FAIL_TID_DISABLE = 0x8d,
- TX_STATUS_FAIL_FRAME_FLUSHED = 0x8e,
- TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
- TX_STATUS_FAIL_TX_LOCKED = 0x90,
- TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91,
-};
-
-#define TX_PACKET_MODE_REGULAR 0x0000
-#define TX_PACKET_MODE_BURST_SEQ 0x0100
-#define TX_PACKET_MODE_BURST_FIRST 0x0200
-
-enum {
- TX_POWER_PA_NOT_ACTIVE = 0x0,
-};
-
-enum {
- TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */
- TX_STATUS_DELAY_MSK = 0x00000040,
- TX_STATUS_ABORT_MSK = 0x00000080,
- TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */
- TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */
- TX_RESERVED = 0x00780000, /* bits 19:22 */
- TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */
- TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */
-};
-
-/*
- * REPLY_TX = 0x1c (response)
- */
-struct iwl3945_tx_resp {
- u8 failure_rts;
- u8 failure_frame;
- u8 bt_kill_count;
- u8 rate;
- __le32 wireless_media_time;
- __le32 status; /* TX status */
-} __attribute__ ((packed));
-
-/*
- * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response)
- */
-struct iwl3945_txpowertable_cmd {
- u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
- u8 reserved;
- __le16 channel;
- struct iwl3945_power_per_rate power[IWL_MAX_RATES];
-} __attribute__ ((packed));
-
-struct iwl3945_rate_scaling_info {
- __le16 rate_n_flags;
- u8 try_cnt;
- u8 next_rate_index;
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response
- *
- * REPLY_RATE_SCALE = 0x47 (command, has simple generic response)
- *
- * NOTE: The table of rates passed to the uCode via the
- * RATE_SCALE command sets up the corresponding order of
- * rates used for all related commands, including rate
- * masks, etc.
- *
- * For example, if you set 9MB (PLCP 0x0f) as the first
- * rate in the rate table, the bit mask for that rate
- * when passed through ofdm_basic_rates on the REPLY_RXON
- * command would be bit 0 (1 << 0)
- */
-struct iwl3945_rate_scaling_cmd {
- u8 table_id;
- u8 reserved[3];
- struct iwl3945_rate_scaling_info table[IWL_MAX_RATES];
-} __attribute__ ((packed));
-
-/*
- * REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
- *
- * 3945 and 4965 support hardware handshake with Bluetooth device on
- * same platform. Bluetooth device alerts wireless device when it will Tx;
- * wireless device can delay or kill its own Tx to accommodate.
- */
-struct iwl3945_bt_cmd {
- u8 flags;
- u8 lead_time;
- u8 max_kill;
- u8 reserved;
- __le32 kill_ack_mask;
- __le32 kill_cts_mask;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (6)
- * Spectrum Management (802.11h) Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/*
- * Spectrum Management
- */
-#define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK | \
- RXON_FILTER_CTL2HOST_MSK | \
- RXON_FILTER_ACCEPT_GRP_MSK | \
- RXON_FILTER_DIS_DECRYPT_MSK | \
- RXON_FILTER_DIS_GRP_DECRYPT_MSK | \
- RXON_FILTER_ASSOC_MSK | \
- RXON_FILTER_BCON_AWARE_MSK)
-
-struct iwl3945_measure_channel {
- __le32 duration; /* measurement duration in extended beacon
- * format */
- u8 channel; /* channel to measure */
- u8 type; /* see enum iwl3945_measure_type */
- __le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command)
- */
-struct iwl3945_spectrum_cmd {
- __le16 len; /* number of bytes starting from token */
- u8 token; /* token id */
- u8 id; /* measurement id -- 0 or 1 */
- u8 origin; /* 0 = TGh, 1 = other, 2 = TGk */
- u8 periodic; /* 1 = periodic */
- __le16 path_loss_timeout;
- __le32 start_time; /* start time in extended beacon format */
- __le32 reserved2;
- __le32 flags; /* rxon flags */
- __le32 filter_flags; /* rxon filter flags */
- __le16 channel_count; /* minimum 1, maximum 10 */
- __le16 reserved3;
- struct iwl3945_measure_channel channels[10];
-} __attribute__ ((packed));
-
-/*
- * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response)
- */
-struct iwl3945_spectrum_resp {
- u8 token;
- u8 id; /* id of the prior command replaced, or 0xff */
- __le16 status; /* 0 - command will be handled
- * 1 - cannot handle (conflicts with another
- * measurement) */
-} __attribute__ ((packed));
-
-enum iwl3945_measurement_state {
- IWL_MEASUREMENT_START = 0,
- IWL_MEASUREMENT_STOP = 1,
-};
-
-enum iwl3945_measurement_status {
- IWL_MEASUREMENT_OK = 0,
- IWL_MEASUREMENT_CONCURRENT = 1,
- IWL_MEASUREMENT_CSA_CONFLICT = 2,
- IWL_MEASUREMENT_TGH_CONFLICT = 3,
- /* 4-5 reserved */
- IWL_MEASUREMENT_STOPPED = 6,
- IWL_MEASUREMENT_TIMEOUT = 7,
- IWL_MEASUREMENT_PERIODIC_FAILED = 8,
-};
-
-#define NUM_ELEMENTS_IN_HISTOGRAM 8
-
-struct iwl3945_measurement_histogram {
- __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */
- __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 1usec counts */
-} __attribute__ ((packed));
-
-/* clear channel availability counters */
-struct iwl3945_measurement_cca_counters {
- __le32 ofdm;
- __le32 cck;
-} __attribute__ ((packed));
-
-enum iwl3945_measure_type {
- IWL_MEASURE_BASIC = (1 << 0),
- IWL_MEASURE_CHANNEL_LOAD = (1 << 1),
- IWL_MEASURE_HISTOGRAM_RPI = (1 << 2),
- IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3),
- IWL_MEASURE_FRAME = (1 << 4),
- /* bits 5:6 are reserved */
- IWL_MEASURE_IDLE = (1 << 7),
-};
-
-/*
- * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command)
- */
-struct iwl3945_spectrum_notification {
- u8 id; /* measurement id -- 0 or 1 */
- u8 token;
- u8 channel_index; /* index in measurement channel list */
- u8 state; /* 0 - start, 1 - stop */
- __le32 start_time; /* lower 32-bits of TSF */
- u8 band; /* 0 - 5.2GHz, 1 - 2.4GHz */
- u8 channel;
- u8 type; /* see enum iwl3945_measurement_type */
- u8 reserved1;
- /* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only
- * valid if applicable for measurement type requested. */
- __le32 cca_ofdm; /* cca fraction time in 40Mhz clock periods */
- __le32 cca_cck; /* cca fraction time in 44Mhz clock periods */
- __le32 cca_time; /* channel load time in usecs */
- u8 basic_type; /* 0 - bss, 1 - ofdm preamble, 2 -
- * unidentified */
- u8 reserved2[3];
- struct iwl3945_measurement_histogram histogram;
- __le32 stop_time; /* lower 32-bits of TSF */
- __le32 status; /* see iwl3945_measurement_status */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (7)
- * Power Management Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/**
- * struct iwl3945_powertable_cmd - Power Table Command
- * @flags: See below:
- *
- * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
- *
- * PM allow:
- * bit 0 - '0' Driver not allow power management
- * '1' Driver allow PM (use rest of parameters)
- * uCode send sleep notifications:
- * bit 1 - '0' Don't send sleep notification
- * '1' send sleep notification (SEND_PM_NOTIFICATION)
- * Sleep over DTIM
- * bit 2 - '0' PM have to walk up every DTIM
- * '1' PM could sleep over DTIM till listen Interval.
- * PCI power managed
- * bit 3 - '0' (PCI_LINK_CTRL & 0x1)
- * '1' !(PCI_LINK_CTRL & 0x1)
- * Force sleep Modes
- * bit 31/30- '00' use both mac/xtal sleeps
- * '01' force Mac sleep
- * '10' force xtal sleep
- * '11' Illegal set
- *
- * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then
- * ucode assume sleep over DTIM is allowed and we don't need to wakeup
- * for every DTIM.
- */
-#define IWL_POWER_VEC_SIZE 5
-
-#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le32(1 << 0)
-#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le32(1 << 2)
-#define IWL_POWER_PCI_PM_MSK cpu_to_le32(1 << 3)
-struct iwl3945_powertable_cmd {
- __le32 flags;
- __le32 rx_data_timeout;
- __le32 tx_data_timeout;
- __le32 sleep_interval[IWL_POWER_VEC_SIZE];
-} __attribute__((packed));
-
-/*
- * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command)
- * 3945 and 4965 identical.
- */
-struct iwl3945_sleep_notification {
- u8 pm_sleep_mode;
- u8 pm_wakeup_src;
- __le16 reserved;
- __le32 sleep_time;
- __le32 tsf_low;
- __le32 bcon_timer;
-} __attribute__ ((packed));
-
-/* Sleep states. 3945 and 4965 identical. */
-enum {
- IWL_PM_NO_SLEEP = 0,
- IWL_PM_SLP_MAC = 1,
- IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2,
- IWL_PM_SLP_FULL_MAC_CARD_STATE = 3,
- IWL_PM_SLP_PHY = 4,
- IWL_PM_SLP_REPENT = 5,
- IWL_PM_WAKEUP_BY_TIMER = 6,
- IWL_PM_WAKEUP_BY_DRIVER = 7,
- IWL_PM_WAKEUP_BY_RFKILL = 8,
- /* 3 reserved */
- IWL_PM_NUM_OF_MODES = 12,
-};
-
-/*
- * REPLY_CARD_STATE_CMD = 0xa0 (command, has simple generic response)
- */
-#define CARD_STATE_CMD_DISABLE 0x00 /* Put card to sleep */
-#define CARD_STATE_CMD_ENABLE 0x01 /* Wake up card */
-#define CARD_STATE_CMD_HALT 0x02 /* Power down permanently */
-struct iwl3945_card_state_cmd {
- __le32 status; /* CARD_STATE_CMD_* request new power state */
-} __attribute__ ((packed));
-
-/*
- * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command)
- */
-struct iwl3945_card_state_notif {
- __le32 flags;
-} __attribute__ ((packed));
-
-#define HW_CARD_DISABLED 0x01
-#define SW_CARD_DISABLED 0x02
-#define RF_CARD_DISABLED 0x04
-#define RXON_CARD_DISABLED 0x10
-
-struct iwl3945_ct_kill_config {
- __le32 reserved;
- __le32 critical_temperature_M;
- __le32 critical_temperature_R;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (8)
- * Scan Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/**
- * struct iwl3945_scan_channel - entry in REPLY_SCAN_CMD channel table
- *
- * One for each channel in the scan list.
- * Each channel can independently select:
- * 1) SSID for directed active scans
- * 2) Txpower setting (for rate specified within Tx command)
- * 3) How long to stay on-channel (behavior may be modified by quiet_time,
- * quiet_plcp_th, good_CRC_th)
- *
- * To avoid uCode errors, make sure the following are true (see comments
- * under struct iwl3945_scan_cmd about max_out_time and quiet_time):
- * 1) If using passive_dwell (i.e. passive_dwell != 0):
- * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
- * 2) quiet_time <= active_dwell
- * 3) If restricting off-channel time (i.e. max_out_time !=0):
- * passive_dwell < max_out_time
- * active_dwell < max_out_time
- */
-struct iwl3945_scan_channel {
- /*
- * type is defined as:
- * 0:0 1 = active, 0 = passive
- * 1:4 SSID direct bit map; if a bit is set, then corresponding
- * SSID IE is transmitted in probe request.
- * 5:7 reserved
- */
- u8 type;
- u8 channel; /* band is selected by iwl3945_scan_cmd "flags" field */
- struct iwl3945_tx_power tpc;
- __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */
- __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_ssid_ie - directed scan network information element
- *
- * Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field
- * in struct iwl3945_scan_channel; each channel may select different ssids from
- * among the 4 entries. SSID IEs get transmitted in reverse order of entry.
- */
-struct iwl3945_ssid_ie {
- u8 id;
- u8 len;
- u8 ssid[32];
-} __attribute__ ((packed));
-
-#define PROBE_OPTION_MAX 0x4
-#define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF)
-#define IWL_GOOD_CRC_TH cpu_to_le16(1)
-#define IWL_MAX_SCAN_SIZE 1024
-
-/*
- * REPLY_SCAN_CMD = 0x80 (command)
- *
- * The hardware scan command is very powerful; the driver can set it up to
- * maintain (relatively) normal network traffic while doing a scan in the
- * background. The max_out_time and suspend_time control the ratio of how
- * long the device stays on an associated network channel ("service channel")
- * vs. how long it's away from the service channel, tuned to other channels
- * for scanning.
- *
- * max_out_time is the max time off-channel (in usec), and suspend_time
- * is how long (in "extended beacon" format) that the scan is "suspended"
- * after returning to the service channel. That is, suspend_time is the
- * time that we stay on the service channel, doing normal work, between
- * scan segments. The driver may set these parameters differently to support
- * scanning when associated vs. not associated, and light vs. heavy traffic
- * loads when associated.
- *
- * After receiving this command, the device's scan engine does the following;
- *
- * 1) Sends SCAN_START notification to driver
- * 2) Checks to see if it has time to do scan for one channel
- * 3) Sends NULL packet, with power-save (PS) bit set to 1,
- * to tell AP that we're going off-channel
- * 4) Tunes to first channel in scan list, does active or passive scan
- * 5) Sends SCAN_RESULT notification to driver
- * 6) Checks to see if it has time to do scan on *next* channel in list
- * 7) Repeats 4-6 until it no longer has time to scan the next channel
- * before max_out_time expires
- * 8) Returns to service channel
- * 9) Sends NULL packet with PS=0 to tell AP that we're back
- * 10) Stays on service channel until suspend_time expires
- * 11) Repeats entire process 2-10 until list is complete
- * 12) Sends SCAN_COMPLETE notification
- *
- * For fast, efficient scans, the scan command also has support for staying on
- * a channel for just a short time, if doing active scanning and getting no
- * responses to the transmitted probe request. This time is controlled by
- * quiet_time, and the number of received packets below which a channel is
- * considered "quiet" is controlled by quiet_plcp_threshold.
- *
- * For active scanning on channels that have regulatory restrictions against
- * blindly transmitting, the scan can listen before transmitting, to make sure
- * that there is already legitimate activity on the channel. If enough
- * packets are cleanly received on the channel (controlled by good_CRC_th,
- * typical value 1), the scan engine starts transmitting probe requests.
- *
- * Driver must use separate scan commands for 2.4 vs. 5 GHz bands.
- *
- * To avoid uCode errors, see timing restrictions described under
- * struct iwl3945_scan_channel.
- */
-struct iwl3945_scan_cmd {
- __le16 len;
- u8 reserved0;
- u8 channel_count; /* # channels in channel list */
- __le16 quiet_time; /* dwell only this # millisecs on quiet channel
- * (only for active scan) */
- __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */
- __le16 good_CRC_th; /* passive -> active promotion threshold */
- __le16 reserved1;
- __le32 max_out_time; /* max usec to be away from associated (service)
- * channel */
- __le32 suspend_time; /* pause scan this long (in "extended beacon
- * format") when returning to service channel:
- * 3945; 31:24 # beacons, 19:0 additional usec,
- * 4965; 31:22 # beacons, 21:0 additional usec.
- */
- __le32 flags; /* RXON_FLG_* */
- __le32 filter_flags; /* RXON_FILTER_* */
-
- /* For active scans (set to all-0s for passive scans).
- * Does not include payload. Must specify Tx rate; no rate scaling. */
- struct iwl3945_tx_cmd tx_cmd;
-
- /* For directed active scans (set to all-0s otherwise) */
- struct iwl3945_ssid_ie direct_scan[PROBE_OPTION_MAX];
-
- /*
- * Probe request frame, followed by channel list.
- *
- * Size of probe request frame is specified by byte count in tx_cmd.
- * Channel list follows immediately after probe request frame.
- * Number of channels in list is specified by channel_count.
- * Each channel in list is of type:
- *
- * struct iwl3945_scan_channel channels[0];
- *
- * NOTE: Only one band of channels can be scanned per pass. You
- * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
- * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
- * before requesting another scan.
- */
- u8 data[0];
-} __attribute__ ((packed));
-
-/* Can abort will notify by complete notification with abort status. */
-#define CAN_ABORT_STATUS cpu_to_le32(0x1)
-/* complete notification statuses */
-#define ABORT_STATUS 0x2
-
-/*
- * REPLY_SCAN_CMD = 0x80 (response)
- */
-struct iwl3945_scanreq_notification {
- __le32 status; /* 1: okay, 2: cannot fulfill request */
-} __attribute__ ((packed));
-
-/*
- * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command)
- */
-struct iwl3945_scanstart_notification {
- __le32 tsf_low;
- __le32 tsf_high;
- __le32 beacon_timer;
- u8 channel;
- u8 band;
- u8 reserved[2];
- __le32 status;
-} __attribute__ ((packed));
-
-#define SCAN_OWNER_STATUS 0x1;
-#define MEASURE_OWNER_STATUS 0x2;
-
-#define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */
-/*
- * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command)
- */
-struct iwl3945_scanresults_notification {
- u8 channel;
- u8 band;
- u8 reserved[2];
- __le32 tsf_low;
- __le32 tsf_high;
- __le32 statistics[NUMBER_OF_STATISTICS];
-} __attribute__ ((packed));
-
-/*
- * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command)
- */
-struct iwl3945_scancomplete_notification {
- u8 scanned_channels;
- u8 status;
- u8 reserved;
- u8 last_channel;
- __le32 tsf_low;
- __le32 tsf_high;
-} __attribute__ ((packed));
-
-
-/******************************************************************************
- * (9)
- * IBSS/AP Commands and Notifications:
- *
- *****************************************************************************/
-
-/*
- * BEACON_NOTIFICATION = 0x90 (notification only, not a command)
- */
-struct iwl3945_beacon_notif {
- struct iwl3945_tx_resp beacon_notify_hdr;
- __le32 low_tsf;
- __le32 high_tsf;
- __le32 ibss_mgr_status;
-} __attribute__ ((packed));
-
-/*
- * REPLY_TX_BEACON = 0x91 (command, has simple generic response)
- */
-struct iwl3945_tx_beacon_cmd {
- struct iwl3945_tx_cmd tx;
- __le16 tim_idx;
- u8 tim_size;
- u8 reserved1;
- struct ieee80211_hdr frame[0]; /* beacon frame */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (10)
- * Statistics Commands and Notifications:
- *
- *****************************************************************************/
-
-#define IWL_TEMP_CONVERT 260
-
-#define SUP_RATE_11A_MAX_NUM_CHANNELS 8
-#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
-#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
-
-/* Used for passing to driver number of successes and failures per rate */
-struct rate_histogram {
- union {
- __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
- __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
- __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
- } success;
- union {
- __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
- __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
- __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
- } failed;
-} __attribute__ ((packed));
-
-/* statistics command response */
-
-struct statistics_rx_phy {
- __le32 ina_cnt;
- __le32 fina_cnt;
- __le32 plcp_err;
- __le32 crc32_err;
- __le32 overrun_err;
- __le32 early_overrun_err;
- __le32 crc32_good;
- __le32 false_alarm_cnt;
- __le32 fina_sync_err_cnt;
- __le32 sfd_timeout;
- __le32 fina_timeout;
- __le32 unresponded_rts;
- __le32 rxe_frame_limit_overrun;
- __le32 sent_ack_cnt;
- __le32 sent_cts_cnt;
-} __attribute__ ((packed));
-
-struct statistics_rx_non_phy {
- __le32 bogus_cts; /* CTS received when not expecting CTS */
- __le32 bogus_ack; /* ACK received when not expecting ACK */
- __le32 non_bssid_frames; /* number of frames with BSSID that
- * doesn't belong to the STA BSSID */
- __le32 filtered_frames; /* count frames that were dumped in the
- * filtering process */
- __le32 non_channel_beacons; /* beacons with our bss id but not on
- * our serving channel */
-} __attribute__ ((packed));
-
-struct statistics_rx {
- struct statistics_rx_phy ofdm;
- struct statistics_rx_phy cck;
- struct statistics_rx_non_phy general;
-} __attribute__ ((packed));
-
-struct statistics_tx {
- __le32 preamble_cnt;
- __le32 rx_detected_cnt;
- __le32 bt_prio_defer_cnt;
- __le32 bt_prio_kill_cnt;
- __le32 few_bytes_cnt;
- __le32 cts_timeout;
- __le32 ack_timeout;
- __le32 expected_ack_cnt;
- __le32 actual_ack_cnt;
-} __attribute__ ((packed));
-
-struct statistics_dbg {
- __le32 burst_check;
- __le32 burst_count;
- __le32 reserved[4];
-} __attribute__ ((packed));
-
-struct statistics_div {
- __le32 tx_on_a;
- __le32 tx_on_b;
- __le32 exec_time;
- __le32 probe_time;
-} __attribute__ ((packed));
-
-struct statistics_general {
- __le32 temperature;
- struct statistics_dbg dbg;
- __le32 sleep_time;
- __le32 slots_out;
- __le32 slots_idle;
- __le32 ttl_timestamp;
- struct statistics_div div;
-} __attribute__ ((packed));
-
-/*
- * REPLY_STATISTICS_CMD = 0x9c,
- * 3945 and 4965 identical.
- *
- * This command triggers an immediate response containing uCode statistics.
- * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below.
- *
- * If the CLEAR_STATS configuration flag is set, uCode will clear its
- * internal copy of the statistics (counters) after issuing the response.
- * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below).
- *
- * If the DISABLE_NOTIF configuration flag is set, uCode will not issue
- * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag
- * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself.
- */
-#define IWL_STATS_CONF_CLEAR_STATS cpu_to_le32(0x1) /* see above */
-#define IWL_STATS_CONF_DISABLE_NOTIF cpu_to_le32(0x2)/* see above */
-struct iwl3945_statistics_cmd {
- __le32 configuration_flags; /* IWL_STATS_CONF_* */
-} __attribute__ ((packed));
-
-/*
- * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
- *
- * By default, uCode issues this notification after receiving a beacon
- * while associated. To disable this behavior, set DISABLE_NOTIF flag in the
- * REPLY_STATISTICS_CMD 0x9c, above.
- *
- * Statistics counters continue to increment beacon after beacon, but are
- * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
- * 0x9c with CLEAR_STATS bit set (see above).
- *
- * uCode also issues this notification during scans. uCode clears statistics
- * appropriately so that each notification contains statistics for only the
- * one channel that has just been scanned.
- */
-#define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2)
-#define STATISTICS_REPLY_FLG_FAT_MODE_MSK cpu_to_le32(0x8)
-struct iwl3945_notif_statistics {
- __le32 flag;
- struct statistics_rx rx;
- struct statistics_tx tx;
- struct statistics_general general;
-} __attribute__ ((packed));
-
-
-/*
- * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
- */
-/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row,
- * then this notification will be sent. */
-#define CONSECUTIVE_MISSED_BCONS_TH 20
-
-struct iwl3945_missed_beacon_notif {
- __le32 consequtive_missed_beacons;
- __le32 total_missed_becons;
- __le32 num_expected_beacons;
- __le32 num_recvd_beacons;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (11)
- * Rx Calibration Commands:
- *
- *****************************************************************************/
-
-#define PHY_CALIBRATE_DIFF_GAIN_CMD (7)
-#define HD_TABLE_SIZE (11)
-
-struct iwl3945_sensitivity_cmd {
- __le16 control;
- __le16 table[HD_TABLE_SIZE];
-} __attribute__ ((packed));
-
-struct iwl3945_calibration_cmd {
- u8 opCode;
- u8 flags;
- __le16 reserved;
- s8 diff_gain_a;
- s8 diff_gain_b;
- s8 diff_gain_c;
- u8 reserved1;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (12)
- * Miscellaneous Commands:
- *
- *****************************************************************************/
-
-/*
- * LEDs Command & Response
- * REPLY_LEDS_CMD = 0x48 (command, has simple generic response)
- *
- * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field),
- * this command turns it on or off, or sets up a periodic blinking cycle.
- */
-struct iwl3945_led_cmd {
- __le32 interval; /* "interval" in uSec */
- u8 id; /* 1: Activity, 2: Link, 3: Tech */
- u8 off; /* # intervals off while blinking;
- * "0", with >0 "on" value, turns LED on */
- u8 on; /* # intervals on while blinking;
- * "0", regardless of "off", turns LED off */
- u8 reserved;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (13)
- * Union of all expected notifications/responses:
- *
- *****************************************************************************/
-
-struct iwl3945_rx_packet {
- __le32 len;
- struct iwl3945_cmd_header hdr;
- union {
- struct iwl3945_alive_resp alive_frame;
- struct iwl3945_rx_frame rx_frame;
- struct iwl3945_tx_resp tx_resp;
- struct iwl3945_spectrum_notification spectrum_notif;
- struct iwl3945_csa_notification csa_notif;
- struct iwl3945_error_resp err_resp;
- struct iwl3945_card_state_notif card_state_notif;
- struct iwl3945_beacon_notif beacon_status;
- struct iwl3945_add_sta_resp add_sta;
- struct iwl3945_sleep_notification sleep_notif;
- struct iwl3945_spectrum_resp spectrum;
- struct iwl3945_notif_statistics stats;
- __le32 status;
- u8 raw[0];
- } u;
-} __attribute__ ((packed));
-
-#define IWL_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame))
-
-#endif /* __iwl3945_3945_commands_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h b/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
deleted file mode 100644
index 85eb778f9df1..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl3945_debug_h__
-#define __iwl3945_debug_h__
-
-#ifdef CONFIG_IWL3945_DEBUG
-extern u32 iwl3945_debug_level;
-#define IWL_DEBUG(level, fmt, args...) \
-do { if (iwl3945_debug_level & (level)) \
- printk(KERN_ERR DRV_NAME": %c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-
-#define IWL_DEBUG_LIMIT(level, fmt, args...) \
-do { if ((iwl3945_debug_level & (level)) && net_ratelimit()) \
- printk(KERN_ERR DRV_NAME": %c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-
-static inline void iwl3945_print_hex_dump(int level, void *p, u32 len)
-{
- if (!(iwl3945_debug_level & level))
- return;
-
- print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
- p, len, 1);
-}
-#else
-static inline void IWL_DEBUG(int level, const char *fmt, ...)
-{
-}
-static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...)
-{
-}
-static inline void iwl3945_print_hex_dump(int level, void *p, u32 len)
-{
-}
-#endif /* CONFIG_IWL3945_DEBUG */
-
-
-
-/*
- * To use the debug system;
- *
- * If you are defining a new debug classification, simply add it to the #define
- * list here in the form of:
- *
- * #define IWL_DL_xxxx VALUE
- *
- * shifting value to the left one bit from the previous entry. xxxx should be
- * the name of the classification (for example, WEP)
- *
- * You then need to either add a IWL_xxxx_DEBUG() macro definition for your
- * classification, or use IWL_DEBUG(IWL_DL_xxxx, ...) whenever you want
- * to send output to that classification.
- *
- * To add your debug level to the list of levels seen when you perform
- *
- * % cat /proc/net/iwl/debug_level
- *
- * you simply need to add your entry to the iwl3945_debug_levels array.
- *
- * If you do not see debug_level in /proc/net/iwl then you do not have
- * CONFIG_IWL3945_DEBUG defined in your kernel configuration
- *
- */
-
-#define IWL_DL_INFO (1 << 0)
-#define IWL_DL_MAC80211 (1 << 1)
-#define IWL_DL_HOST_COMMAND (1 << 2)
-#define IWL_DL_STATE (1 << 3)
-
-#define IWL_DL_RADIO (1 << 7)
-#define IWL_DL_POWER (1 << 8)
-#define IWL_DL_TEMP (1 << 9)
-
-#define IWL_DL_NOTIF (1 << 10)
-#define IWL_DL_SCAN (1 << 11)
-#define IWL_DL_ASSOC (1 << 12)
-#define IWL_DL_DROP (1 << 13)
-
-#define IWL_DL_TXPOWER (1 << 14)
-
-#define IWL_DL_AP (1 << 15)
-
-#define IWL_DL_FW (1 << 16)
-#define IWL_DL_RF_KILL (1 << 17)
-#define IWL_DL_FW_ERRORS (1 << 18)
-
-#define IWL_DL_LED (1 << 19)
-
-#define IWL_DL_RATE (1 << 20)
-
-#define IWL_DL_CALIB (1 << 21)
-#define IWL_DL_WEP (1 << 22)
-#define IWL_DL_TX (1 << 23)
-#define IWL_DL_RX (1 << 24)
-#define IWL_DL_ISR (1 << 25)
-#define IWL_DL_HT (1 << 26)
-#define IWL_DL_IO (1 << 27)
-#define IWL_DL_11H (1 << 28)
-
-#define IWL_DL_STATS (1 << 29)
-#define IWL_DL_TX_REPLY (1 << 30)
-#define IWL_DL_QOS (1 << 31)
-
-#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
-#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
-#define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a)
-
-#define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a)
-#define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a)
-#define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a)
-#define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a)
-#define IWL_DEBUG_TX(f, a...) IWL_DEBUG(IWL_DL_TX, f, ## a)
-#define IWL_DEBUG_ISR(f, a...) IWL_DEBUG(IWL_DL_ISR, f, ## a)
-#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a)
-#define IWL_DEBUG_WEP(f, a...) IWL_DEBUG(IWL_DL_WEP, f, ## a)
-#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HOST_COMMAND, f, ## a)
-#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a)
-#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a)
-#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a)
-#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a)
-#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
-#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
-#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
-#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
- IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
-#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
-#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a)
-#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a)
-#define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a)
-#define IWL_DEBUG_11H(f, a...) IWL_DEBUG(IWL_DL_11H, f, ## a)
-
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
new file mode 100644
index 000000000000..08ce259a0e60
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h
@@ -0,0 +1,188 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#ifndef __iwl_3945_fh_h__
+#define __iwl_3945_fh_h__
+
+/************************************/
+/* iwl3945 Flow Handler Definitions */
+/************************************/
+
+/**
+ * This I/O area is directly read/writable by driver (e.g. Linux uses writel())
+ * Addresses are offsets from device's PCI hardware base address.
+ */
+#define FH39_MEM_LOWER_BOUND (0x0800)
+#define FH39_MEM_UPPER_BOUND (0x1000)
+
+#define FH39_CBCC_TABLE (FH39_MEM_LOWER_BOUND + 0x140)
+#define FH39_TFDB_TABLE (FH39_MEM_LOWER_BOUND + 0x180)
+#define FH39_RCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x400)
+#define FH39_RSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x4c0)
+#define FH39_TCSR_TABLE (FH39_MEM_LOWER_BOUND + 0x500)
+#define FH39_TSSR_TABLE (FH39_MEM_LOWER_BOUND + 0x680)
+
+/* TFDB (Transmit Frame Buffer Descriptor) */
+#define FH39_TFDB(_ch, buf) (FH39_TFDB_TABLE + \
+ ((_ch) * 2 + (buf)) * 0x28)
+#define FH39_TFDB_CHNL_BUF_CTRL_REG(_ch) (FH39_TFDB_TABLE + 0x50 * (_ch))
+
+/* CBCC channel is [0,2] */
+#define FH39_CBCC(_ch) (FH39_CBCC_TABLE + (_ch) * 0x8)
+#define FH39_CBCC_CTRL(_ch) (FH39_CBCC(_ch) + 0x00)
+#define FH39_CBCC_BASE(_ch) (FH39_CBCC(_ch) + 0x04)
+
+/* RCSR channel is [0,2] */
+#define FH39_RCSR(_ch) (FH39_RCSR_TABLE + (_ch) * 0x40)
+#define FH39_RCSR_CONFIG(_ch) (FH39_RCSR(_ch) + 0x00)
+#define FH39_RCSR_RBD_BASE(_ch) (FH39_RCSR(_ch) + 0x04)
+#define FH39_RCSR_WPTR(_ch) (FH39_RCSR(_ch) + 0x20)
+#define FH39_RCSR_RPTR_ADDR(_ch) (FH39_RCSR(_ch) + 0x24)
+
+#define FH39_RSCSR_CHNL0_WPTR (FH39_RCSR_WPTR(0))
+
+/* RSSR */
+#define FH39_RSSR_CTRL (FH39_RSSR_TABLE + 0x000)
+#define FH39_RSSR_STATUS (FH39_RSSR_TABLE + 0x004)
+
+/* TCSR */
+#define FH39_TCSR(_ch) (FH39_TCSR_TABLE + (_ch) * 0x20)
+#define FH39_TCSR_CONFIG(_ch) (FH39_TCSR(_ch) + 0x00)
+#define FH39_TCSR_CREDIT(_ch) (FH39_TCSR(_ch) + 0x04)
+#define FH39_TCSR_BUFF_STTS(_ch) (FH39_TCSR(_ch) + 0x08)
+
+/* TSSR */
+#define FH39_TSSR_CBB_BASE (FH39_TSSR_TABLE + 0x000)
+#define FH39_TSSR_MSG_CONFIG (FH39_TSSR_TABLE + 0x008)
+#define FH39_TSSR_TX_STATUS (FH39_TSSR_TABLE + 0x010)
+
+
+/* DBM */
+
+#define FH39_SRVC_CHNL (6)
+
+#define FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20)
+#define FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4)
+
+#define FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000)
+
+#define FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000)
+#define FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000)
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000)
+
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000)
+#define FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000)
+
+#define FH39_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000)
+
+#define FH39_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000)
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100)
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080)
+
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020)
+#define FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005)
+
+#define FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) (BIT(_ch) << 24)
+#define FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch) (BIT(_ch) << 16)
+
+#define FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_ch) \
+ (FH39_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_ch) | \
+ FH39_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_ch))
+
+#define FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000)
+
+struct iwl3945_tfd_tb {
+ __le32 addr;
+ __le32 len;
+} __attribute__ ((packed));
+
+struct iwl3945_tfd {
+ __le32 control_flags;
+ struct iwl3945_tfd_tb tbs[4];
+ u8 __pad[28];
+} __attribute__ ((packed));
+
+
+#endif /* __iwl_3945_fh_h__ */
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 94ea0e60c410..73f93a0ff2df 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -69,77 +69,26 @@
#ifndef __iwl_3945_hw__
#define __iwl_3945_hw__
+#include "iwl-eeprom.h"
+
/*
* uCode queue management definitions ...
* Queue #4 is the command queue for 3945 and 4965.
*/
-#define IWL_CMD_QUEUE_NUM 4
-
-/* Tx rates */
-#define IWL_CCK_RATES 4
-#define IWL_OFDM_RATES 8
-#define IWL_HT_RATES 0
-#define IWL_MAX_RATES (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES)
+#define IWL_CMD_QUEUE_NUM 4
/* Time constants */
#define SHORT_SLOT_TIME 9
#define LONG_SLOT_TIME 20
/* RSSI to dBm */
-#define IWL_RSSI_OFFSET 95
+#define IWL39_RSSI_OFFSET 95
/*
* EEPROM related constants, enums, and structures.
*/
-
-/*
- * EEPROM access time values:
- *
- * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG,
- * then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit
- * CSR_EEPROM_REG_BIT_CMD (0x2).
- * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1).
- * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec.
- * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG.
- */
-#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */
-
-/*
- * Regulatory channel usage flags in EEPROM struct iwl_eeprom_channel.flags.
- *
- * IBSS and/or AP operation is allowed *only* on those channels with
- * (VALID && IBSS && ACTIVE && !RADAR). This restriction is in place because
- * RADAR detection is not supported by the 3945 driver, but is a
- * requirement for establishing a new network for legal operation on channels
- * requiring RADAR detection or restricting ACTIVE scanning.
- *
- * NOTE: "WIDE" flag indicates that 20 MHz channel is supported;
- * 3945 does not support FAT 40 MHz-wide channels.
- *
- * NOTE: Using a channel inappropriately will result in a uCode error!
- */
-enum {
- EEPROM_CHANNEL_VALID = (1 << 0), /* usable for this SKU/geo */
- EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */
- /* Bit 2 Reserved */
- EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */
- EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */
- EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */
- /* Bit 6 Reserved (was Narrow Channel) */
- EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */
-};
-
-/* SKU Capabilities */
-#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0)
-#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1)
#define EEPROM_SKU_CAP_OP_MODE_MRC (1 << 7)
-/* *regulatory* channel data from eeprom, one for each channel */
-struct iwl3945_eeprom_channel {
- u8 flags; /* flags copied from EEPROM */
- s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */
-} __attribute__ ((packed));
-
/*
* Mapping of a Tx power level, at factory calibration temperature,
* to a radio/DSP gain table index.
@@ -233,7 +182,7 @@ struct iwl3945_eeprom {
* 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
*/
u16 band_1_count; /* abs.ofs: 196 */
- struct iwl3945_eeprom_channel band_1_channels[14]; /* abs.ofs: 196 */
+ struct iwl_eeprom_channel band_1_channels[14]; /* abs.ofs: 198 */
/*
* 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196,
@@ -241,28 +190,28 @@ struct iwl3945_eeprom {
* (4915-5080MHz) (none of these is ever supported)
*/
u16 band_2_count; /* abs.ofs: 226 */
- struct iwl3945_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */
+ struct iwl_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */
/*
* 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
* (5170-5320MHz)
*/
u16 band_3_count; /* abs.ofs: 254 */
- struct iwl3945_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */
+ struct iwl_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */
/*
* 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
* (5500-5700MHz)
*/
u16 band_4_count; /* abs.ofs: 280 */
- struct iwl3945_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */
+ struct iwl_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */
/*
* 5.7 GHz channels 145, 149, 153, 157, 161, 165
* (5725-5825MHz)
*/
u16 band_5_count; /* abs.ofs: 304 */
- struct iwl3945_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */
+ struct iwl_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */
u8 reserved9[194];
@@ -276,125 +225,15 @@ struct iwl3945_eeprom {
u8 reserved16[172]; /* fill out to full 1024 byte block */
} __attribute__ ((packed));
-#define IWL_EEPROM_IMAGE_SIZE 1024
+#define IWL3945_EEPROM_IMG_SIZE 1024
/* End of EEPROM */
-
-#include "iwl-3945-commands.h"
-
-#define PCI_LINK_CTRL 0x0F0
-#define PCI_POWER_SOURCE 0x0C8
-#define PCI_REG_WUM8 0x0E8
-#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000)
-
-/*=== FH (data Flow Handler) ===*/
-#define FH_BASE (0x800)
-
-#define FH_CBCC_TABLE (FH_BASE+0x140)
-#define FH_TFDB_TABLE (FH_BASE+0x180)
-#define FH_RCSR_TABLE (FH_BASE+0x400)
-#define FH_RSSR_TABLE (FH_BASE+0x4c0)
-#define FH_TCSR_TABLE (FH_BASE+0x500)
-#define FH_TSSR_TABLE (FH_BASE+0x680)
-
-/* TFDB (Transmit Frame Buffer Descriptor) */
-#define FH_TFDB(_channel, buf) \
- (FH_TFDB_TABLE+((_channel)*2+(buf))*0x28)
-#define ALM_FH_TFDB_CHNL_BUF_CTRL_REG(_channel) \
- (FH_TFDB_TABLE + 0x50 * _channel)
-/* CBCC _channel is [0,2] */
-#define FH_CBCC(_channel) (FH_CBCC_TABLE+(_channel)*0x8)
-#define FH_CBCC_CTRL(_channel) (FH_CBCC(_channel)+0x00)
-#define FH_CBCC_BASE(_channel) (FH_CBCC(_channel)+0x04)
-
-/* RCSR _channel is [0,2] */
-#define FH_RCSR(_channel) (FH_RCSR_TABLE+(_channel)*0x40)
-#define FH_RCSR_CONFIG(_channel) (FH_RCSR(_channel)+0x00)
-#define FH_RCSR_RBD_BASE(_channel) (FH_RCSR(_channel)+0x04)
-#define FH_RCSR_WPTR(_channel) (FH_RCSR(_channel)+0x20)
-#define FH_RCSR_RPTR_ADDR(_channel) (FH_RCSR(_channel)+0x24)
-
-#define FH_RSCSR_CHNL0_WPTR (FH_RCSR_WPTR(0))
-
-/* RSSR */
-#define FH_RSSR_CTRL (FH_RSSR_TABLE+0x000)
-#define FH_RSSR_STATUS (FH_RSSR_TABLE+0x004)
-#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000)
-/* TCSR */
-#define FH_TCSR(_channel) (FH_TCSR_TABLE+(_channel)*0x20)
-#define FH_TCSR_CONFIG(_channel) (FH_TCSR(_channel)+0x00)
-#define FH_TCSR_CREDIT(_channel) (FH_TCSR(_channel)+0x04)
-#define FH_TCSR_BUFF_STTS(_channel) (FH_TCSR(_channel)+0x08)
-/* TSSR */
-#define FH_TSSR_CBB_BASE (FH_TSSR_TABLE+0x000)
-#define FH_TSSR_MSG_CONFIG (FH_TSSR_TABLE+0x008)
-#define FH_TSSR_TX_STATUS (FH_TSSR_TABLE+0x010)
-
-
-/* DBM */
-
-#define ALM_FH_SRVC_CHNL (6)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20)
-#define ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000)
-
-#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000)
-
-#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005)
-
-#define ALM_TB_MAX_BYTES_COUNT (0xFFF0)
-
-#define ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) \
- ((1LU << _channel) << 24)
-#define ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel) \
- ((1LU << _channel) << 16)
-
-#define ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_channel) \
- (ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) | \
- ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel))
#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */
#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */
#define TFD_QUEUE_MIN 0
-#define TFD_QUEUE_MAX 6
-#define TFD_QUEUE_SIZE_MAX (256)
+#define TFD_QUEUE_MAX 5 /* 4 DATA + 1 CMD */
#define IWL_NUM_SCAN_RATES (2)
@@ -416,12 +255,6 @@ struct iwl3945_eeprom {
#define TFD_CTL_PAD_SET(n) (n << 28)
#define TFD_CTL_PAD_GET(ctl) (ctl >> 28)
-#define TFD_TX_CMD_SLOTS 256
-#define TFD_CMD_SLOTS 32
-
-#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \
- sizeof(struct iwl3945_cmd_meta))
-
/*
* RX related structures and functions
*/
@@ -430,45 +263,35 @@ struct iwl3945_eeprom {
/* Sizes and addresses for instruction and data memory (SRAM) in
* 3945's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */
-#define RTC_INST_LOWER_BOUND (0x000000)
-#define ALM_RTC_INST_UPPER_BOUND (0x014000)
+#define IWL39_RTC_INST_LOWER_BOUND (0x000000)
+#define IWL39_RTC_INST_UPPER_BOUND (0x014000)
-#define RTC_DATA_LOWER_BOUND (0x800000)
-#define ALM_RTC_DATA_UPPER_BOUND (0x808000)
+#define IWL39_RTC_DATA_LOWER_BOUND (0x800000)
+#define IWL39_RTC_DATA_UPPER_BOUND (0x808000)
-#define ALM_RTC_INST_SIZE (ALM_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
-#define ALM_RTC_DATA_SIZE (ALM_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+#define IWL39_RTC_INST_SIZE (IWL39_RTC_INST_UPPER_BOUND - \
+ IWL39_RTC_INST_LOWER_BOUND)
+#define IWL39_RTC_DATA_SIZE (IWL39_RTC_DATA_UPPER_BOUND - \
+ IWL39_RTC_DATA_LOWER_BOUND)
-#define IWL_MAX_INST_SIZE ALM_RTC_INST_SIZE
-#define IWL_MAX_DATA_SIZE ALM_RTC_DATA_SIZE
+#define IWL39_MAX_INST_SIZE IWL39_RTC_INST_SIZE
+#define IWL39_MAX_DATA_SIZE IWL39_RTC_DATA_SIZE
/* Size of uCode instruction memory in bootstrap state machine */
-#define IWL_MAX_BSM_SIZE ALM_RTC_INST_SIZE
+#define IWL39_MAX_BSM_SIZE IWL39_RTC_INST_SIZE
#define IWL39_MAX_NUM_QUEUES 8
static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr)
{
- return (addr >= RTC_DATA_LOWER_BOUND) &&
- (addr < ALM_RTC_DATA_UPPER_BOUND);
+ return (addr >= IWL39_RTC_DATA_LOWER_BOUND) &&
+ (addr < IWL39_RTC_DATA_UPPER_BOUND);
}
/* Base physical address of iwl3945_shared is provided to FH_TSSR_CBB_BASE
* and &iwl3945_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */
struct iwl3945_shared {
__le32 tx_base_ptr[8];
- __le32 rx_read_ptr[3];
-} __attribute__ ((packed));
-
-struct iwl3945_tfd_frame_data {
- __le32 addr;
- __le32 len;
-} __attribute__ ((packed));
-
-struct iwl3945_tfd_frame {
- __le32 control_flags;
- struct iwl3945_tfd_frame_data pa[4];
- u8 reserved[28];
} __attribute__ ((packed));
static inline u8 iwl3945_hw_get_rate(__le16 rate_n_flags)
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
deleted file mode 100644
index 2440fd664dd5..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-3945-io.h
+++ /dev/null
@@ -1,404 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl3945_io_h__
-#define __iwl3945_io_h__
-
-#include <linux/io.h>
-
-#include "iwl-3945-debug.h"
-
-/*
- * IO, register, and NIC memory access functions
- *
- * NOTE on naming convention and macro usage for these
- *
- * A single _ prefix before a an access function means that no state
- * check or debug information is printed when that function is called.
- *
- * A double __ prefix before an access function means that state is checked
- * and the current line number is printed in addition to any other debug output.
- *
- * The non-prefixed name is the #define that maps the caller into a
- * #define that provides the caller's __LINE__ to the double prefix version.
- *
- * If you wish to call the function without any debug or state checking,
- * you should use the single _ prefix version (as is used by dependent IO
- * routines, for example _iwl3945_read_direct32 calls the non-check version of
- * _iwl3945_read32.)
- *
- * These declarations are *extremely* useful in quickly isolating code deltas
- * which result in misconfiguration of the hardware I/O. In combination with
- * git-bisect and the IO debug level you can quickly determine the specific
- * commit which breaks the IO sequence to the hardware.
- *
- */
-
-#define _iwl3945_write32(priv, ofs, val) iowrite32((val), (priv)->hw_base + (ofs))
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *priv,
- u32 ofs, u32 val)
-{
- IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
- _iwl3945_write32(priv, ofs, val);
-}
-#define iwl3945_write32(priv, ofs, val) \
- __iwl3945_write32(__FILE__, __LINE__, priv, ofs, val)
-#else
-#define iwl3945_write32(priv, ofs, val) _iwl3945_write32(priv, ofs, val)
-#endif
-
-#define _iwl3945_read32(priv, ofs) ioread32((priv)->hw_base + (ofs))
-#ifdef CONFIG_IWL3945_DEBUG
-static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *priv, u32 ofs)
-{
- IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
- return _iwl3945_read32(priv, ofs);
-}
-#define iwl3945_read32(priv, ofs)__iwl3945_read32(__FILE__, __LINE__, priv, ofs)
-#else
-#define iwl3945_read32(p, o) _iwl3945_read32(p, o)
-#endif
-
-static inline int _iwl3945_poll_bit(struct iwl3945_priv *priv, u32 addr,
- u32 bits, u32 mask, int timeout)
-{
- int i = 0;
-
- do {
- if ((_iwl3945_read32(priv, addr) & mask) == (bits & mask))
- return i;
- udelay(10);
- i += 10;
- } while (i < timeout);
-
- return -ETIMEDOUT;
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline int __iwl3945_poll_bit(const char *f, u32 l,
- struct iwl3945_priv *priv, u32 addr,
- u32 bits, u32 mask, int timeout)
-{
- int ret = _iwl3945_poll_bit(priv, addr, bits, mask, timeout);
- IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
- addr, bits, mask,
- unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l);
- return ret;
-}
-#define iwl3945_poll_bit(priv, addr, bits, mask, timeout) \
- __iwl3945_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout)
-#else
-#define iwl3945_poll_bit(p, a, b, m, t) _iwl3945_poll_bit(p, a, b, m, t)
-#endif
-
-static inline void _iwl3945_set_bit(struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
- _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) | mask);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_set_bit(const char *f, u32 l,
- struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
- u32 val = _iwl3945_read32(priv, reg) | mask;
- IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
- _iwl3945_write32(priv, reg, val);
-}
-#define iwl3945_set_bit(p, r, m) __iwl3945_set_bit(__FILE__, __LINE__, p, r, m)
-#else
-#define iwl3945_set_bit(p, r, m) _iwl3945_set_bit(p, r, m)
-#endif
-
-static inline void _iwl3945_clear_bit(struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
- _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) & ~mask);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_clear_bit(const char *f, u32 l,
- struct iwl3945_priv *priv, u32 reg, u32 mask)
-{
- u32 val = _iwl3945_read32(priv, reg) & ~mask;
- IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
- _iwl3945_write32(priv, reg, val);
-}
-#define iwl3945_clear_bit(p, r, m) __iwl3945_clear_bit(__FILE__, __LINE__, p, r, m)
-#else
-#define iwl3945_clear_bit(p, r, m) _iwl3945_clear_bit(p, r, m)
-#endif
-
-static inline int _iwl3945_grab_nic_access(struct iwl3945_priv *priv)
-{
- int ret;
-#ifdef CONFIG_IWL3945_DEBUG
- if (atomic_read(&priv->restrict_refcnt))
- return 0;
-#endif
- /* this bit wakes up the NIC */
- _iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- ret = _iwl3945_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
- (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
- CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
- if (ret < 0) {
- IWL_ERROR("MAC is in deep sleep!\n");
- return -EIO;
- }
-
-#ifdef CONFIG_IWL3945_DEBUG
- atomic_inc(&priv->restrict_refcnt);
-#endif
- return 0;
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
-static inline int __iwl3945_grab_nic_access(const char *f, u32 l,
- struct iwl3945_priv *priv)
-{
- if (atomic_read(&priv->restrict_refcnt))
- IWL_DEBUG_INFO("Grabbing access while already held at "
- "line %d.\n", l);
-
- IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l);
- return _iwl3945_grab_nic_access(priv);
-}
-#define iwl3945_grab_nic_access(priv) \
- __iwl3945_grab_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl3945_grab_nic_access(priv) \
- _iwl3945_grab_nic_access(priv)
-#endif
-
-static inline void _iwl3945_release_nic_access(struct iwl3945_priv *priv)
-{
-#ifdef CONFIG_IWL3945_DEBUG
- if (atomic_dec_and_test(&priv->restrict_refcnt))
-#endif
- _iwl3945_clear_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_release_nic_access(const char *f, u32 l,
- struct iwl3945_priv *priv)
-{
- if (atomic_read(&priv->restrict_refcnt) <= 0)
- IWL_ERROR("Release unheld nic access at line %d.\n", l);
-
- IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l);
- _iwl3945_release_nic_access(priv);
-}
-#define iwl3945_release_nic_access(priv) \
- __iwl3945_release_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl3945_release_nic_access(priv) \
- _iwl3945_release_nic_access(priv)
-#endif
-
-static inline u32 _iwl3945_read_direct32(struct iwl3945_priv *priv, u32 reg)
-{
- return _iwl3945_read32(priv, reg);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline u32 __iwl3945_read_direct32(const char *f, u32 l,
- struct iwl3945_priv *priv, u32 reg)
-{
- u32 value = _iwl3945_read_direct32(priv, reg);
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s %d\n", f, l);
- IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
- f, l);
- return value;
-}
-#define iwl3945_read_direct32(priv, reg) \
- __iwl3945_read_direct32(__FILE__, __LINE__, priv, reg)
-#else
-#define iwl3945_read_direct32 _iwl3945_read_direct32
-#endif
-
-static inline void _iwl3945_write_direct32(struct iwl3945_priv *priv,
- u32 reg, u32 value)
-{
- _iwl3945_write32(priv, reg, value);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static void __iwl3945_write_direct32(u32 line,
- struct iwl3945_priv *priv, u32 reg, u32 value)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from line %d\n", line);
- _iwl3945_write_direct32(priv, reg, value);
-}
-#define iwl3945_write_direct32(priv, reg, value) \
- __iwl3945_write_direct32(__LINE__, priv, reg, value)
-#else
-#define iwl3945_write_direct32 _iwl3945_write_direct32
-#endif
-
-static inline void iwl3945_write_reg_buf(struct iwl3945_priv *priv,
- u32 reg, u32 len, u32 *values)
-{
- u32 count = sizeof(u32);
-
- if ((priv != NULL) && (values != NULL)) {
- for (; 0 < len; len -= count, reg += count, values++)
- _iwl3945_write_direct32(priv, reg, *values);
- }
-}
-
-static inline int _iwl3945_poll_direct_bit(struct iwl3945_priv *priv,
- u32 addr, u32 mask, int timeout)
-{
- return _iwl3945_poll_bit(priv, addr, mask, mask, timeout);
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
-static inline int __iwl3945_poll_direct_bit(const char *f, u32 l,
- struct iwl3945_priv *priv,
- u32 addr, u32 mask, int timeout)
-{
- int ret = _iwl3945_poll_direct_bit(priv, addr, mask, timeout);
-
- if (unlikely(ret == -ETIMEDOUT))
- IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - "
- "timedout - %s %d\n", addr, mask, f, l);
- else
- IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
- "- %s %d\n", addr, mask, ret, f, l);
- return ret;
-}
-#define iwl3945_poll_direct_bit(priv, addr, mask, timeout) \
- __iwl3945_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout)
-#else
-#define iwl3945_poll_direct_bit _iwl3945_poll_direct_bit
-#endif
-
-static inline u32 _iwl3945_read_prph(struct iwl3945_priv *priv, u32 reg)
-{
- _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
- rmb();
- return _iwl3945_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline u32 __iwl3945_read_prph(u32 line, struct iwl3945_priv *priv, u32 reg)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from line %d\n", line);
- return _iwl3945_read_prph(priv, reg);
-}
-
-#define iwl3945_read_prph(priv, reg) \
- __iwl3945_read_prph(__LINE__, priv, reg)
-#else
-#define iwl3945_read_prph _iwl3945_read_prph
-#endif
-
-static inline void _iwl3945_write_prph(struct iwl3945_priv *priv,
- u32 addr, u32 val)
-{
- _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
- ((addr & 0x0000FFFF) | (3 << 24)));
- wmb();
- _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
-}
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_write_prph(u32 line, struct iwl3945_priv *priv,
- u32 addr, u32 val)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access from line %d\n", line);
- _iwl3945_write_prph(priv, addr, val);
-}
-
-#define iwl3945_write_prph(priv, addr, val) \
- __iwl3945_write_prph(__LINE__, priv, addr, val);
-#else
-#define iwl3945_write_prph _iwl3945_write_prph
-#endif
-
-#define _iwl3945_set_bits_prph(priv, reg, mask) \
- _iwl3945_write_prph(priv, reg, (_iwl3945_read_prph(priv, reg) | mask))
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_set_bits_prph(u32 line, struct iwl3945_priv *priv,
- u32 reg, u32 mask)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from line %d\n", line);
-
- _iwl3945_set_bits_prph(priv, reg, mask);
-}
-#define iwl3945_set_bits_prph(priv, reg, mask) \
- __iwl3945_set_bits_prph(__LINE__, priv, reg, mask)
-#else
-#define iwl3945_set_bits_prph _iwl3945_set_bits_prph
-#endif
-
-#define _iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \
- _iwl3945_write_prph(priv, reg, ((_iwl3945_read_prph(priv, reg) & mask) | bits))
-
-#ifdef CONFIG_IWL3945_DEBUG
-static inline void __iwl3945_set_bits_mask_prph(u32 line,
- struct iwl3945_priv *priv, u32 reg, u32 bits, u32 mask)
-{
- if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from line %d\n", line);
- _iwl3945_set_bits_mask_prph(priv, reg, bits, mask);
-}
-#define iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \
- __iwl3945_set_bits_mask_prph(__LINE__, priv, reg, bits, mask)
-#else
-#define iwl3945_set_bits_mask_prph _iwl3945_set_bits_mask_prph
-#endif
-
-static inline void iwl3945_clear_bits_prph(struct iwl3945_priv
- *priv, u32 reg, u32 mask)
-{
- u32 val = _iwl3945_read_prph(priv, reg);
- _iwl3945_write_prph(priv, reg, (val & ~mask));
-}
-
-static inline u32 iwl3945_read_targ_mem(struct iwl3945_priv *priv, u32 addr)
-{
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
- rmb();
- return iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
-}
-
-static inline void iwl3945_write_targ_mem(struct iwl3945_priv *priv, u32 addr, u32 val)
-{
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
- wmb();
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
-}
-
-static inline void iwl3945_write_targ_mem_buf(struct iwl3945_priv *priv, u32 addr,
- u32 len, u32 *values)
-{
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
- wmb();
- for (; 0 < len; len -= sizeof(u32), values++)
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
-}
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index 4c638909a7db..ac22f59be9ef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -24,6 +24,7 @@
*
*****************************************************************************/
+#ifdef CONFIG_IWLWIFI_LEDS
#include <linux/kernel.h>
#include <linux/module.h>
@@ -38,8 +39,10 @@
#include <linux/etherdevice.h>
#include <asm/unaligned.h>
+#include "iwl-commands.h"
#include "iwl-3945.h"
-#include "iwl-helpers.h"
+#include "iwl-core.h"
+#include "iwl-dev.h"
static const struct {
@@ -67,8 +70,8 @@ static const struct {
#define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /*Exclude Solid on*/
#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
-static int iwl3945_led_cmd_callback(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
+static int iwl3945_led_cmd_callback(struct iwl_priv *priv,
+ struct iwl_cmd *cmd,
struct sk_buff *skb)
{
return 1;
@@ -80,27 +83,27 @@ static inline int iwl3945_brightness_to_idx(enum led_brightness brightness)
}
/* Send led command */
-static int iwl_send_led_cmd(struct iwl3945_priv *priv,
- struct iwl3945_led_cmd *led_cmd)
+static int iwl_send_led_cmd(struct iwl_priv *priv,
+ struct iwl_led_cmd *led_cmd)
{
- struct iwl3945_host_cmd cmd = {
+ struct iwl_host_cmd cmd = {
.id = REPLY_LEDS_CMD,
- .len = sizeof(struct iwl3945_led_cmd),
+ .len = sizeof(struct iwl_led_cmd),
.data = led_cmd,
.meta.flags = CMD_ASYNC,
.meta.u.callback = iwl3945_led_cmd_callback,
};
- return iwl3945_send_cmd(priv, &cmd);
+ return iwl_send_cmd(priv, &cmd);
}
/* Set led on command */
-static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id,
+static int iwl3945_led_pattern(struct iwl_priv *priv, int led_id,
unsigned int idx)
{
- struct iwl3945_led_cmd led_cmd = {
+ struct iwl_led_cmd led_cmd = {
.id = led_id,
.interval = IWL_DEF_LED_INTRVL
};
@@ -114,11 +117,10 @@ static int iwl3945_led_pattern(struct iwl3945_priv *priv, int led_id,
}
-#if 1
/* Set led on command */
-static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id)
+static int iwl3945_led_on(struct iwl_priv *priv, int led_id)
{
- struct iwl3945_led_cmd led_cmd = {
+ struct iwl_led_cmd led_cmd = {
.id = led_id,
.on = IWL_LED_SOLID,
.off = 0,
@@ -128,24 +130,22 @@ static int iwl3945_led_on(struct iwl3945_priv *priv, int led_id)
}
/* Set led off command */
-static int iwl3945_led_off(struct iwl3945_priv *priv, int led_id)
+static int iwl3945_led_off(struct iwl_priv *priv, int led_id)
{
- struct iwl3945_led_cmd led_cmd = {
+ struct iwl_led_cmd led_cmd = {
.id = led_id,
.on = 0,
.off = 0,
.interval = IWL_DEF_LED_INTRVL
};
- IWL_DEBUG_LED("led off %d\n", led_id);
+ IWL_DEBUG_LED(priv, "led off %d\n", led_id);
return iwl_send_led_cmd(priv, &led_cmd);
}
-#endif
-
/*
* brightness call back function for Tx/Rx LED
*/
-static int iwl3945_led_associated(struct iwl3945_priv *priv, int led_id)
+static int iwl3945_led_associated(struct iwl_priv *priv, int led_id)
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
!test_bit(STATUS_READY, &priv->status))
@@ -164,9 +164,9 @@ static int iwl3945_led_associated(struct iwl3945_priv *priv, int led_id)
static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
- struct iwl3945_led *led = container_of(led_cdev,
- struct iwl3945_led, led_dev);
- struct iwl3945_priv *priv = led->priv;
+ struct iwl_led *led = container_of(led_cdev,
+ struct iwl_led, led_dev);
+ struct iwl_priv *priv = led->priv;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -175,7 +175,7 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
case LED_FULL:
if (led->type == IWL_LED_TRG_ASSOC) {
priv->allow_blinking = 1;
- IWL_DEBUG_LED("MAC is associated\n");
+ IWL_DEBUG_LED(priv, "MAC is associated\n");
}
if (led->led_on)
led->led_on(priv, IWL_LED_LINK);
@@ -183,7 +183,7 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
case LED_OFF:
if (led->type == IWL_LED_TRG_ASSOC) {
priv->allow_blinking = 0;
- IWL_DEBUG_LED("MAC is disassociated\n");
+ IWL_DEBUG_LED(priv, "MAC is disassociated\n");
}
if (led->led_off)
led->led_off(priv, IWL_LED_LINK);
@@ -202,8 +202,8 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
/*
* Register led class with the system
*/
-static int iwl3945_led_register_led(struct iwl3945_priv *priv,
- struct iwl3945_led *led,
+static int iwl3945_led_register_led(struct iwl_priv *priv,
+ struct iwl_led *led,
enum led_type type, u8 set_led,
char *trigger)
{
@@ -219,7 +219,7 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv,
ret = led_classdev_register(device, &led->led_dev);
if (ret) {
- IWL_ERROR("Error: failed to register led handler.\n");
+ IWL_ERR(priv, "Error: failed to register led handler.\n");
return ret;
}
@@ -234,7 +234,7 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv,
/*
* calculate blink rate according to last 2 sec Tx/Rx activities
*/
-static inline u8 get_blink_rate(struct iwl3945_priv *priv)
+static inline u8 get_blink_rate(struct iwl_priv *priv)
{
int index;
u64 current_tpt = priv->rxtxpackets;
@@ -253,7 +253,7 @@ static inline u8 get_blink_rate(struct iwl3945_priv *priv)
return index;
}
-static inline int is_rf_kill(struct iwl3945_priv *priv)
+static inline int is_rf_kill(struct iwl_priv *priv)
{
return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
test_bit(STATUS_RF_KILL_SW, &priv->status);
@@ -264,7 +264,7 @@ static inline int is_rf_kill(struct iwl3945_priv *priv)
* happen very frequent we postpone led command to be called from
* REPLY handler so we know ucode is up
*/
-void iwl3945_led_background(struct iwl3945_priv *priv)
+void iwl3945_led_background(struct iwl_priv *priv)
{
u8 blink_idx;
@@ -304,7 +304,7 @@ void iwl3945_led_background(struct iwl3945_priv *priv)
/* Register all led handler */
-int iwl3945_led_register(struct iwl3945_priv *priv)
+int iwl3945_led_register(struct iwl_priv *priv)
{
char *trigger;
int ret;
@@ -317,7 +317,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
trigger = ieee80211_get_radio_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_RADIO].name,
- sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
+ sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
wiphy_name(priv->hw->wiphy));
priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
@@ -333,7 +333,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
trigger = ieee80211_get_assoc_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
- sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
+ sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc",
wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv,
@@ -350,7 +350,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
trigger = ieee80211_get_rx_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_RX].name,
- sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
+ sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s::RX",
wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv,
@@ -366,7 +366,7 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
trigger = ieee80211_get_tx_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_TX].name,
- sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
+ sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s::TX",
wiphy_name(priv->hw->wiphy));
ret = iwl3945_led_register_led(priv,
@@ -389,7 +389,7 @@ exit_fail:
/* unregister led class */
-static void iwl3945_led_unregister_led(struct iwl3945_led *led, u8 set_led)
+static void iwl3945_led_unregister_led(struct iwl_led *led, u8 set_led)
{
if (!led->registered)
return;
@@ -402,7 +402,7 @@ static void iwl3945_led_unregister_led(struct iwl3945_led *led, u8 set_led)
}
/* Unregister all led handlers */
-void iwl3945_led_unregister(struct iwl3945_priv *priv)
+void iwl3945_led_unregister(struct iwl_priv *priv)
{
iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_ASSOC], 0);
iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RX], 0);
@@ -410,3 +410,4 @@ void iwl3945_led_unregister(struct iwl3945_priv *priv)
iwl3945_led_unregister_led(&priv->led[IWL_LED_TRG_RADIO], 1);
}
+#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
index 749ac035fd6a..3b65642258ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -27,48 +27,20 @@
#ifndef IWL3945_LEDS_H
#define IWL3945_LEDS_H
-struct iwl3945_priv;
+struct iwl_priv;
-#ifdef CONFIG_IWL3945_LEDS
-#define IWL_LED_SOLID 11
-#define IWL_LED_NAME_LEN 31
-#define IWL_DEF_LED_INTRVL __constant_cpu_to_le32(1000)
+#ifdef CONFIG_IWLWIFI_LEDS
-#define IWL_LED_ACTIVITY (0<<1)
-#define IWL_LED_LINK (1<<1)
+#include "iwl-led.h"
-enum led_type {
- IWL_LED_TRG_TX,
- IWL_LED_TRG_RX,
- IWL_LED_TRG_ASSOC,
- IWL_LED_TRG_RADIO,
- IWL_LED_TRG_MAX,
-};
-
-#include <linux/leds.h>
-
-struct iwl3945_led {
- struct iwl3945_priv *priv;
- struct led_classdev led_dev;
- char name[32];
-
- int (*led_on) (struct iwl3945_priv *priv, int led_id);
- int (*led_off) (struct iwl3945_priv *priv, int led_id);
- int (*led_pattern) (struct iwl3945_priv *priv, int led_id,
- unsigned int idx);
-
- enum led_type type;
- unsigned int registered;
-};
-
-extern int iwl3945_led_register(struct iwl3945_priv *priv);
-extern void iwl3945_led_unregister(struct iwl3945_priv *priv);
-extern void iwl3945_led_background(struct iwl3945_priv *priv);
+extern int iwl3945_led_register(struct iwl_priv *priv);
+extern void iwl3945_led_unregister(struct iwl_priv *priv);
+extern void iwl3945_led_background(struct iwl_priv *priv);
#else
-static inline int iwl3945_led_register(struct iwl3945_priv *priv) { return 0; }
-static inline void iwl3945_led_unregister(struct iwl3945_priv *priv) {}
-static inline void iwl3945_led_background(struct iwl3945_priv *priv) {}
-#endif /* CONFIG_IWL3945_LEDS */
+static inline int iwl3945_led_register(struct iwl_priv *priv) { return 0; }
+static inline void iwl3945_led_unregister(struct iwl_priv *priv) {}
+static inline void iwl3945_led_background(struct iwl_priv *priv) {}
+#endif /* IWLWIFI_LEDS*/
#endif /* IWL3945_LEDS_H */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 21c841847d88..af6b9d444778 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -36,6 +36,7 @@
#include <linux/workqueue.h>
+#include "iwl-commands.h"
#include "iwl-3945.h"
#define RS_NAME "iwl-3945-rs"
@@ -51,6 +52,7 @@ struct iwl3945_rate_scale_data {
struct iwl3945_rs_sta {
spinlock_t lock;
+ struct iwl_priv *priv;
s32 *expected_tpt;
unsigned long last_partial_flush;
unsigned long last_flush;
@@ -62,7 +64,7 @@ struct iwl3945_rs_sta {
u8 start_rate;
u8 ibss_sta_added;
struct timer_list rate_scale_flush;
- struct iwl3945_rate_scale_data win[IWL_RATE_COUNT];
+ struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945];
#ifdef CONFIG_MAC80211_DEBUGFS
struct dentry *rs_sta_dbgfs_stats_table_file;
#endif
@@ -71,19 +73,19 @@ struct iwl3945_rs_sta {
int last_txrate_idx;
};
-static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT_3945] = {
7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202
};
-static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT_3945] = {
7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125
};
-static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT_3945] = {
0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186
};
-static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT_3945] = {
7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0
};
@@ -119,12 +121,13 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = {
#define IWL_RATE_MAX_WINDOW 62
#define IWL_RATE_FLUSH (3*HZ)
#define IWL_RATE_WIN_FLUSH (HZ/2)
-#define IWL_RATE_HIGH_TH 11520
+#define IWL39_RATE_HIGH_TH 11520
#define IWL_SUCCESS_UP_TH 8960
#define IWL_SUCCESS_DOWN_TH 10880
-#define IWL_RATE_MIN_FAILURE_TH 8
+#define IWL_RATE_MIN_FAILURE_TH 6
#define IWL_RATE_MIN_SUCCESS_TH 8
#define IWL_RATE_DECREASE_TH 1920
+#define IWL_RATE_RETRY_TH 15
static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, enum ieee80211_band band)
{
@@ -165,7 +168,7 @@ static void iwl3945_clear_window(struct iwl3945_rate_scale_data *window)
window->success_counter = 0;
window->success_ratio = -1;
window->counter = 0;
- window->average_tpt = IWL_INV_TPT;
+ window->average_tpt = IWL_INVALID_VALUE;
window->stamp = 0;
}
@@ -181,20 +184,21 @@ static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta)
int unflushed = 0;
int i;
unsigned long flags;
+ struct iwl_priv *priv __maybe_unused = rs_sta->priv;
/*
* For each rate, if we have collected data on that rate
* and it has been more than IWL_RATE_WIN_FLUSH
* since we flushed, clear out the gathered statistics
*/
- for (i = 0; i < IWL_RATE_COUNT; i++) {
+ for (i = 0; i < IWL_RATE_COUNT_3945; i++) {
if (!rs_sta->win[i].counter)
continue;
spin_lock_irqsave(&rs_sta->lock, flags);
if (time_after(jiffies, rs_sta->win[i].stamp +
IWL_RATE_WIN_FLUSH)) {
- IWL_DEBUG_RATE("flushing %d samples of rate "
+ IWL_DEBUG_RATE(priv, "flushing %d samples of rate "
"index %d\n",
rs_sta->win[i].counter, i);
iwl3945_clear_window(&rs_sta->win[i]);
@@ -213,11 +217,12 @@ static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta)
static void iwl3945_bg_rate_scale_flush(unsigned long data)
{
struct iwl3945_rs_sta *rs_sta = (void *)data;
+ struct iwl_priv *priv __maybe_unused = rs_sta->priv;
int unflushed = 0;
unsigned long flags;
u32 packet_count, duration, pps;
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
unflushed = iwl3945_rate_scale_flush_windows(rs_sta);
@@ -232,7 +237,7 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data)
duration =
jiffies_to_msecs(jiffies - rs_sta->last_partial_flush);
- IWL_DEBUG_RATE("Tx'd %d packets in %dms\n",
+ IWL_DEBUG_RATE(priv, "Tx'd %d packets in %dms\n",
packet_count, duration);
/* Determine packets per second */
@@ -252,7 +257,7 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data)
rs_sta->flush_time = msecs_to_jiffies(duration);
- IWL_DEBUG_RATE("new flush period: %d msec ave %d\n",
+ IWL_DEBUG_RATE(priv, "new flush period: %d msec ave %d\n",
duration, packet_count);
mod_timer(&rs_sta->rate_scale_flush, jiffies +
@@ -270,7 +275,7 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data)
spin_unlock_irqrestore(&rs_sta->lock, flags);
- IWL_DEBUG_RATE("leave\n");
+ IWL_DEBUG_RATE(priv, "leave\n");
}
/**
@@ -286,50 +291,70 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
{
unsigned long flags;
s32 fail_count;
+ struct iwl_priv *priv __maybe_unused = rs_sta->priv;
if (!retries) {
- IWL_DEBUG_RATE("leave: retries == 0 -- should be at least 1\n");
+ IWL_DEBUG_RATE(priv, "leave: retries == 0 -- should be at least 1\n");
return;
}
spin_lock_irqsave(&rs_sta->lock, flags);
- while (retries--) {
- /* If we have filled up the window then subtract one from the
- * success counter if the high-bit is counting toward
- * success */
- if (window->counter == IWL_RATE_MAX_WINDOW) {
- if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1)))
+ /*
+ * Keep track of only the latest 62 tx frame attempts in this rate's
+ * history window; anything older isn't really relevant any more.
+ * If we have filled up the sliding window, drop the oldest attempt;
+ * if the oldest attempt (highest bit in bitmap) shows "success",
+ * subtract "1" from the success counter (this is the main reason
+ * we keep these bitmaps!).
+ * */
+ while (retries > 0) {
+ if (window->counter >= IWL_RATE_MAX_WINDOW) {
+
+ /* remove earliest */
+ window->counter = IWL_RATE_MAX_WINDOW - 1;
+
+ if (window->data & (1ULL << (IWL_RATE_MAX_WINDOW - 1))) {
+ window->data &= ~(1ULL << (IWL_RATE_MAX_WINDOW - 1));
window->success_counter--;
- } else
- window->counter++;
+ }
+ }
- /* Slide the window to the left one bit */
- window->data = (window->data << 1);
+ /* Increment frames-attempted counter */
+ window->counter++;
- /* If this packet was a success then set the low bit high */
- if (success) {
+ /* Shift bitmap by one frame (throw away oldest history),
+ * OR in "1", and increment "success" if this
+ * frame was successful. */
+ window->data <<= 1;
+ if (success > 0) {
window->success_counter++;
- window->data |= 1;
+ window->data |= 0x1;
+ success--;
}
- /* window->counter can't be 0 -- it is either >0 or
- * IWL_RATE_MAX_WINDOW */
- window->success_ratio = 12800 * window->success_counter /
- window->counter;
-
- /* Tag this window as having been updated */
- window->stamp = jiffies;
-
+ retries--;
}
+ /* Calculate current success ratio, avoid divide-by-0! */
+ if (window->counter > 0)
+ window->success_ratio = 128 * (100 * window->success_counter)
+ / window->counter;
+ else
+ window->success_ratio = IWL_INVALID_VALUE;
+
fail_count = window->counter - window->success_counter;
+
+ /* Calculate average throughput, if we have enough history. */
if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
(window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
window->average_tpt = ((window->success_ratio *
rs_sta->expected_tpt[index] + 64) / 128);
else
- window->average_tpt = IWL_INV_TPT;
+ window->average_tpt = IWL_INVALID_VALUE;
+
+ /* Tag this window as having been updated */
+ window->stamp = jiffies;
spin_unlock_irqrestore(&rs_sta->lock, flags);
@@ -339,10 +364,10 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta)
{
struct iwl3945_rs_sta *rs_sta = priv_sta;
- struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
+ struct iwl_priv *priv = (struct iwl_priv *)priv_r;
int i;
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
/* TODO: what is a good starting rate for STA? About middle? Maybe not
* the lowest or the highest rate.. Could consider using RSSI from
@@ -365,7 +390,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
}
- IWL_DEBUG_RATE("leave\n");
+ IWL_DEBUG_RATE(priv, "leave\n");
}
static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -379,10 +404,11 @@ static void rs_free(void *priv)
return;
}
-static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
+static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
{
struct iwl3945_rs_sta *rs_sta;
struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
+ struct iwl_priv *priv = iwl_priv;
int i;
/*
@@ -390,11 +416,11 @@ static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
* as well just put all the information there.
*/
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
rs_sta = kzalloc(sizeof(struct iwl3945_rs_sta), gfp);
if (!rs_sta) {
- IWL_DEBUG_RATE("leave: ENOMEM\n");
+ IWL_DEBUG_RATE(priv, "leave: ENOMEM\n");
return NULL;
}
@@ -402,6 +428,8 @@ static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
spin_lock_init(&rs_sta->lock);
+ rs_sta->priv = priv;
+
rs_sta->start_rate = IWL_RATE_INVALID;
/* default to just 802.11b */
@@ -417,33 +445,34 @@ static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
rs_sta->rate_scale_flush.data = (unsigned long)rs_sta;
rs_sta->rate_scale_flush.function = &iwl3945_bg_rate_scale_flush;
- for (i = 0; i < IWL_RATE_COUNT; i++)
+ for (i = 0; i < IWL_RATE_COUNT_3945; i++)
iwl3945_clear_window(&rs_sta->win[i]);
- IWL_DEBUG_RATE("leave\n");
+ IWL_DEBUG_RATE(priv, "leave\n");
return rs_sta;
}
-static void rs_free_sta(void *priv, struct ieee80211_sta *sta,
+static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta,
void *priv_sta)
{
struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
struct iwl3945_rs_sta *rs_sta = priv_sta;
+ struct iwl_priv *priv __maybe_unused = rs_sta->priv;
psta->rs_sta = NULL;
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
del_timer_sync(&rs_sta->rate_scale_flush);
kfree(rs_sta);
- IWL_DEBUG_RATE("leave\n");
+ IWL_DEBUG_RATE(priv, "leave\n");
}
/**
* rs_tx_status - Update rate control values based on Tx results
*
- * NOTE: Uses iwl3945_priv->retry_rate for the # of retries attempted by
+ * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by
* the hardware for each rate.
*/
static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband,
@@ -453,22 +482,25 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
s8 retries = 0, current_count;
int scale_rate_index, first_index, last_index;
unsigned long flags;
- struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
+ struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
struct iwl3945_rs_sta *rs_sta = priv_sta;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
retries = info->status.rates[0].count;
+ /* Sanity Check for retries */
+ if (retries > IWL_RATE_RETRY_TH)
+ retries = IWL_RATE_RETRY_TH;
first_index = sband->bitrates[info->status.rates[0].idx].hw_value;
- if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
- IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index);
+ if ((first_index < 0) || (first_index >= IWL_RATE_COUNT_3945)) {
+ IWL_DEBUG_RATE(priv, "leave: Rate out of bounds: %d\n", first_index);
return;
}
if (!priv_sta) {
- IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
+ IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
return;
}
@@ -502,7 +534,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
iwl3945_collect_tx_data(rs_sta,
&rs_sta->win[scale_rate_index],
0, current_count, scale_rate_index);
- IWL_DEBUG_RATE("Update rate %d for %d retries.\n",
+ IWL_DEBUG_RATE(priv, "Update rate %d for %d retries.\n",
scale_rate_index, current_count);
retries -= current_count;
@@ -512,7 +544,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
/* Update the last index window with success/failure based on ACK */
- IWL_DEBUG_RATE("Update rate %d with %s.\n",
+ IWL_DEBUG_RATE(priv, "Update rate %d with %s.\n",
last_index,
(info->flags & IEEE80211_TX_STAT_ACK) ?
"success" : "failure");
@@ -537,7 +569,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
spin_unlock_irqrestore(&rs_sta->lock, flags);
- IWL_DEBUG_RATE("leave\n");
+ IWL_DEBUG_RATE(priv, "leave\n");
return;
}
@@ -547,6 +579,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
{
u8 high = IWL_RATE_INVALID;
u8 low = IWL_RATE_INVALID;
+ struct iwl_priv *priv __maybe_unused = rs_sta->priv;
/* 802.11A walks to the next literal adjacent rate in
* the rate table */
@@ -565,7 +598,8 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
/* Find the next rate that is in the rate mask */
i = index + 1;
- for (mask = (1 << i); i < IWL_RATE_COUNT; i++, mask <<= 1) {
+ for (mask = (1 << i); i < IWL_RATE_COUNT_3945;
+ i++, mask <<= 1) {
if (rate_mask & mask) {
high = i;
break;
@@ -585,7 +619,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
break;
if (rate_mask & (1 << low))
break;
- IWL_DEBUG_RATE("Skipping masked lower rate: %d\n", low);
+ IWL_DEBUG_RATE(priv, "Skipping masked lower rate: %d\n", low);
}
high = index;
@@ -598,7 +632,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
break;
if (rate_mask & (1 << high))
break;
- IWL_DEBUG_RATE("Skipping masked higher rate: %d\n", high);
+ IWL_DEBUG_RATE(priv, "Skipping masked higher rate: %d\n", high);
}
return (high << 8) | low;
@@ -631,19 +665,20 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
int index;
struct iwl3945_rs_sta *rs_sta = priv_sta;
struct iwl3945_rate_scale_data *window = NULL;
- int current_tpt = IWL_INV_TPT;
- int low_tpt = IWL_INV_TPT;
- int high_tpt = IWL_INV_TPT;
+ int current_tpt = IWL_INVALID_VALUE;
+ int low_tpt = IWL_INVALID_VALUE;
+ int high_tpt = IWL_INVALID_VALUE;
u32 fail_count;
s8 scale_action = 0;
unsigned long flags;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
u16 fc;
u16 rate_mask = 0;
- struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
+ s8 max_rate_idx = -1;
+ struct iwl_priv *priv = (struct iwl_priv *)priv_r;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
if (sta)
rate_mask = sta->supp_rates[sband->band];
@@ -654,7 +689,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
is_multicast_ether_addr(hdr->addr1) ||
!sta || !priv_sta) {
- IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
+ IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
if (!rate_mask)
info->control.rates[0].idx =
rate_lowest_index(sband, NULL);
@@ -664,7 +699,14 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
return;
}
- index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1);
+ /* get user max rate if set */
+ max_rate_idx = txrc->max_rate_idx;
+ if ((sband->band == IEEE80211_BAND_5GHZ) && (max_rate_idx != -1))
+ max_rate_idx += IWL_FIRST_OFDM_RATE;
+ if ((max_rate_idx < 0) || (max_rate_idx >= IWL_RATE_COUNT))
+ max_rate_idx = -1;
+
+ index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT_3945 - 1);
if (sband->band == IEEE80211_BAND_5GHZ)
rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
@@ -674,7 +716,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
u8 sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_RATE("LQ: ADD station %pm\n",
+ IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n",
hdr->addr1);
sta_id = iwl3945_add_station(priv,
hdr->addr1, 0, CMD_ASYNC);
@@ -695,21 +737,30 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
rs_sta->start_rate = IWL_RATE_INVALID;
}
+ /* force user max rate if set by user */
+ if ((max_rate_idx != -1) && (max_rate_idx < index)) {
+ if (rate_mask & (1 << max_rate_idx))
+ index = max_rate_idx;
+ }
+
window = &(rs_sta->win[index]);
fail_count = window->counter - window->success_counter;
- if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) &&
+ if (((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
(window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) {
spin_unlock_irqrestore(&rs_sta->lock, flags);
- IWL_DEBUG_RATE("Invalid average_tpt on rate %d: "
+ IWL_DEBUG_RATE(priv, "Invalid average_tpt on rate %d: "
"counter: %d, success_counter: %d, "
"expected_tpt is %sNULL\n",
index,
window->counter,
window->success_counter,
rs_sta->expected_tpt ? "not " : "");
+
+ /* Can't calculate this yet; not enough history */
+ window->average_tpt = IWL_INVALID_VALUE;
goto out;
}
@@ -721,6 +772,11 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
low = high_low & 0xff;
high = (high_low >> 8) & 0xff;
+ /* If user set max rate, dont allow higher than user constrain */
+ if ((max_rate_idx != -1) && (max_rate_idx < high))
+ high = IWL_RATE_INVALID;
+
+ /* Collect Measured throughputs of adjacent rates */
if (low != IWL_RATE_INVALID)
low_tpt = rs_sta->win[low].average_tpt;
@@ -729,56 +785,78 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
spin_unlock_irqrestore(&rs_sta->lock, flags);
- scale_action = 1;
+ scale_action = 0;
+ /* Low success ratio , need to drop the rate */
if ((window->success_ratio < IWL_RATE_DECREASE_TH) || !current_tpt) {
- IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
+ IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n");
scale_action = -1;
- } else if ((low_tpt == IWL_INV_TPT) && (high_tpt == IWL_INV_TPT))
- scale_action = 1;
- else if ((low_tpt != IWL_INV_TPT) && (high_tpt != IWL_INV_TPT) &&
+ /* No throughput measured yet for adjacent rates,
+ * try increase */
+ } else if ((low_tpt == IWL_INVALID_VALUE) &&
+ (high_tpt == IWL_INVALID_VALUE)) {
+
+ if (high != IWL_RATE_INVALID && window->success_ratio >= IWL_RATE_INCREASE_TH)
+ scale_action = 1;
+ else if (low != IWL_RATE_INVALID)
+ scale_action = 0;
+
+ /* Both adjacent throughputs are measured, but neither one has
+ * better throughput; we're using the best rate, don't change
+ * it! */
+ } else if ((low_tpt != IWL_INVALID_VALUE) &&
+ (high_tpt != IWL_INVALID_VALUE) &&
(low_tpt < current_tpt) && (high_tpt < current_tpt)) {
- IWL_DEBUG_RATE("No action -- low [%d] & high [%d] < "
+
+ IWL_DEBUG_RATE(priv, "No action -- low [%d] & high [%d] < "
"current_tpt [%d]\n",
low_tpt, high_tpt, current_tpt);
scale_action = 0;
+
+ /* At least one of the rates has better throughput */
} else {
- if (high_tpt != IWL_INV_TPT) {
- if (high_tpt > current_tpt)
+ if (high_tpt != IWL_INVALID_VALUE) {
+
+ /* High rate has better throughput, Increase
+ * rate */
+ if (high_tpt > current_tpt &&
+ window->success_ratio >= IWL_RATE_INCREASE_TH)
scale_action = 1;
else {
- IWL_DEBUG_RATE
- ("decrease rate because of high tpt\n");
- scale_action = -1;
+ IWL_DEBUG_RATE(priv,
+ "decrease rate because of high tpt\n");
+ scale_action = 0;
}
- } else if (low_tpt != IWL_INV_TPT) {
+ } else if (low_tpt != IWL_INVALID_VALUE) {
if (low_tpt > current_tpt) {
- IWL_DEBUG_RATE
- ("decrease rate because of low tpt\n");
+ IWL_DEBUG_RATE(priv,
+ "decrease rate because of low tpt\n");
scale_action = -1;
- } else
+ } else if (window->success_ratio >= IWL_RATE_INCREASE_TH) {
+ /* Lower rate has better
+ * throughput,decrease rate */
scale_action = 1;
+ }
}
}
- if (scale_action == -1) {
- if (window->success_ratio > IWL_SUCCESS_DOWN_TH)
- scale_action = 0;
- } else if (scale_action == 1) {
- if (window->success_ratio < IWL_SUCCESS_UP_TH) {
- IWL_DEBUG_RATE("No action -- success_ratio [%d] < "
- "SUCCESS UP\n", window->success_ratio);
- scale_action = 0;
- }
- }
+ /* Sanity check; asked for decrease, but success rate or throughput
+ * has been good at old rate. Don't change it. */
+ if ((scale_action == -1) && (low != IWL_RATE_INVALID) &&
+ ((window->success_ratio > IWL_RATE_HIGH_TH) ||
+ (current_tpt > (100 * rs_sta->expected_tpt[low]))))
+ scale_action = 0;
switch (scale_action) {
case -1:
+
+ /* Decrese rate */
if (low != IWL_RATE_INVALID)
index = low;
break;
case 1:
+ /* Increase rate */
if (high != IWL_RATE_INVALID)
index = high;
@@ -786,10 +864,11 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
case 0:
default:
+ /* No change */
break;
}
- IWL_DEBUG_RATE("Selected %d (action %d) - low %d high %d\n",
+ IWL_DEBUG_RATE(priv, "Selected %d (action %d) - low %d high %d\n",
index, scale_action, low, high);
out:
@@ -801,7 +880,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
else
info->control.rates[0].idx = rs_sta->last_txrate_idx;
- IWL_DEBUG_RATE("leave: %d\n", index);
+ IWL_DEBUG_RATE(priv, "leave: %d\n", index);
}
#ifdef CONFIG_MAC80211_DEBUGFS
@@ -815,24 +894,31 @@ static ssize_t iwl3945_sta_dbgfs_stats_table_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
- char buff[1024];
+ char *buff;
int desc = 0;
int j;
+ ssize_t ret;
struct iwl3945_rs_sta *lq_sta = file->private_data;
+ buff = kmalloc(1024, GFP_KERNEL);
+ if (!buff)
+ return -ENOMEM;
+
desc += sprintf(buff + desc, "tx packets=%d last rate index=%d\n"
"rate=0x%X flush time %d\n",
lq_sta->tx_packets,
lq_sta->last_txrate_idx,
lq_sta->start_rate, jiffies_to_msecs(lq_sta->flush_time));
- for (j = 0; j < IWL_RATE_COUNT; j++) {
+ for (j = 0; j < IWL_RATE_COUNT_3945; j++) {
desc += sprintf(buff+desc,
"counter=%d success=%d %%=%d\n",
lq_sta->win[j].counter,
lq_sta->win[j].success_counter,
lq_sta->win[j].success_ratio);
}
- return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ kfree(buff);
+ return ret;
}
static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
@@ -877,18 +963,18 @@ static struct rate_control_ops rs_ops = {
void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
s32 rssi = 0;
unsigned long flags;
struct iwl3945_rs_sta *rs_sta;
struct ieee80211_sta *sta;
struct iwl3945_sta_priv *psta;
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
rcu_read_lock();
- sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr);
+ sta = ieee80211_find_sta(hw, priv->stations_39[sta_id].sta.sta.addr);
if (!sta) {
rcu_read_unlock();
return;
@@ -924,11 +1010,11 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
if (rssi == 0)
rssi = IWL_MIN_RSSI_VAL;
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_RATE, "Network RSSI: %d\n", rssi);
+ IWL_DEBUG_RATE(priv, "Network RSSI: %d\n", rssi);
rs_sta->start_rate = iwl3945_get_rate_index_by_rssi(rssi, priv->band);
- IWL_DEBUG_RATE("leave: rssi %d assign rate index: "
+ IWL_DEBUG_RATE(priv, "leave: rssi %d assign rate index: "
"%d (plcp 0x%x)\n", rssi, rs_sta->start_rate,
iwl3945_rates[rs_sta->start_rate].plcp);
rcu_read_unlock();
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
deleted file mode 100644
index b5a66135dedd..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl_3945_rs_h__
-#define __iwl_3945_rs_h__
-
-struct iwl3945_rate_info {
- u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
- u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
- u8 prev_ieee; /* previous rate in IEEE speeds */
- u8 next_ieee; /* next rate in IEEE speeds */
- u8 prev_rs; /* previous rate used in rs algo */
- u8 next_rs; /* next rate used in rs algo */
- u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
- u8 next_rs_tgg; /* next rate used in TGG rs algo */
- u8 table_rs_index; /* index in rate scale table cmd */
- u8 prev_table_rs; /* prev in rate table cmd */
-};
-
-/*
- * These serve as indexes into
- * struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT];
- */
-enum {
- IWL_RATE_1M_INDEX = 0,
- IWL_RATE_2M_INDEX,
- IWL_RATE_5M_INDEX,
- IWL_RATE_11M_INDEX,
- IWL_RATE_6M_INDEX,
- IWL_RATE_9M_INDEX,
- IWL_RATE_12M_INDEX,
- IWL_RATE_18M_INDEX,
- IWL_RATE_24M_INDEX,
- IWL_RATE_36M_INDEX,
- IWL_RATE_48M_INDEX,
- IWL_RATE_54M_INDEX,
- IWL_RATE_COUNT,
- IWL_RATE_INVM_INDEX,
- IWL_RATE_INVALID = IWL_RATE_INVM_INDEX
-};
-
-enum {
- IWL_RATE_6M_INDEX_TABLE = 0,
- IWL_RATE_9M_INDEX_TABLE,
- IWL_RATE_12M_INDEX_TABLE,
- IWL_RATE_18M_INDEX_TABLE,
- IWL_RATE_24M_INDEX_TABLE,
- IWL_RATE_36M_INDEX_TABLE,
- IWL_RATE_48M_INDEX_TABLE,
- IWL_RATE_54M_INDEX_TABLE,
- IWL_RATE_1M_INDEX_TABLE,
- IWL_RATE_2M_INDEX_TABLE,
- IWL_RATE_5M_INDEX_TABLE,
- IWL_RATE_11M_INDEX_TABLE,
- IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX,
-};
-
-enum {
- IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
- IWL_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
- IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
- IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
-};
-
-/* #define vs. enum to keep from defaulting to 'large integer' */
-#define IWL_RATE_6M_MASK (1 << IWL_RATE_6M_INDEX)
-#define IWL_RATE_9M_MASK (1 << IWL_RATE_9M_INDEX)
-#define IWL_RATE_12M_MASK (1 << IWL_RATE_12M_INDEX)
-#define IWL_RATE_18M_MASK (1 << IWL_RATE_18M_INDEX)
-#define IWL_RATE_24M_MASK (1 << IWL_RATE_24M_INDEX)
-#define IWL_RATE_36M_MASK (1 << IWL_RATE_36M_INDEX)
-#define IWL_RATE_48M_MASK (1 << IWL_RATE_48M_INDEX)
-#define IWL_RATE_54M_MASK (1 << IWL_RATE_54M_INDEX)
-#define IWL_RATE_1M_MASK (1 << IWL_RATE_1M_INDEX)
-#define IWL_RATE_2M_MASK (1 << IWL_RATE_2M_INDEX)
-#define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX)
-#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX)
-
-/* 3945 uCode API values for (legacy) bit rates, both OFDM and CCK */
-enum {
- IWL_RATE_6M_PLCP = 13,
- IWL_RATE_9M_PLCP = 15,
- IWL_RATE_12M_PLCP = 5,
- IWL_RATE_18M_PLCP = 7,
- IWL_RATE_24M_PLCP = 9,
- IWL_RATE_36M_PLCP = 11,
- IWL_RATE_48M_PLCP = 1,
- IWL_RATE_54M_PLCP = 3,
- IWL_RATE_1M_PLCP = 10,
- IWL_RATE_2M_PLCP = 20,
- IWL_RATE_5M_PLCP = 55,
- IWL_RATE_11M_PLCP = 110,
-};
-
-/* MAC header values for bit rates */
-enum {
- IWL_RATE_6M_IEEE = 12,
- IWL_RATE_9M_IEEE = 18,
- IWL_RATE_12M_IEEE = 24,
- IWL_RATE_18M_IEEE = 36,
- IWL_RATE_24M_IEEE = 48,
- IWL_RATE_36M_IEEE = 72,
- IWL_RATE_48M_IEEE = 96,
- IWL_RATE_54M_IEEE = 108,
- IWL_RATE_1M_IEEE = 2,
- IWL_RATE_2M_IEEE = 4,
- IWL_RATE_5M_IEEE = 11,
- IWL_RATE_11M_IEEE = 22,
-};
-
-#define IWL_CCK_BASIC_RATES_MASK \
- (IWL_RATE_1M_MASK | \
- IWL_RATE_2M_MASK)
-
-#define IWL_CCK_RATES_MASK \
- (IWL_BASIC_RATES_MASK | \
- IWL_RATE_5M_MASK | \
- IWL_RATE_11M_MASK)
-
-#define IWL_OFDM_BASIC_RATES_MASK \
- (IWL_RATE_6M_MASK | \
- IWL_RATE_12M_MASK | \
- IWL_RATE_24M_MASK)
-
-#define IWL_OFDM_RATES_MASK \
- (IWL_OFDM_BASIC_RATES_MASK | \
- IWL_RATE_9M_MASK | \
- IWL_RATE_18M_MASK | \
- IWL_RATE_36M_MASK | \
- IWL_RATE_48M_MASK | \
- IWL_RATE_54M_MASK)
-
-#define IWL_BASIC_RATES_MASK \
- (IWL_OFDM_BASIC_RATES_MASK | \
- IWL_CCK_BASIC_RATES_MASK)
-
-#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
-
-#define IWL_INV_TPT -1
-
-#define IWL_MIN_RSSI_VAL -100
-#define IWL_MAX_RSSI_VAL 0
-
-extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT];
-
-static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
-{
- u8 rate = iwl3945_rates[rate_index].prev_ieee;
-
- if (rate == IWL_RATE_INVALID)
- rate = rate_index;
- return rate;
-}
-
-/**
- * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
- *
- * The specific throughput table used is based on the type of network
- * the associated with, including A, B, G, and G w/ TGG protection
- */
-extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
-
-/**
- * iwl3945_rate_control_register - Register the rate control algorithm callbacks
- *
- * Since the rate control algorithm is hardware specific, there is no need
- * or reason to place it as a stand alone module. The driver can call
- * iwl3945_rate_control_register in order to register the rate control callbacks
- * with the mac80211 subsystem. This should be performed prior to calling
- * ieee80211_register_hw
- *
- */
-extern int iwl3945_rate_control_register(void);
-
-/**
- * iwl3945_rate_control_unregister - Unregister the rate control callbacks
- *
- * This should be called after calling ieee80211_unregister_hw, but before
- * the driver is unloaded.
- */
-extern void iwl3945_rate_control_unregister(void);
-
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 45cfa1cf194a..2399328e8de7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -38,10 +38,15 @@
#include <asm/unaligned.h>
#include <net/mac80211.h>
-#include "iwl-3945-core.h"
+#include "iwl-fh.h"
+#include "iwl-3945-fh.h"
+#include "iwl-commands.h"
+#include "iwl-sta.h"
#include "iwl-3945.h"
+#include "iwl-eeprom.h"
#include "iwl-helpers.h"
-#include "iwl-3945-rs.h"
+#include "iwl-core.h"
+#include "iwl-agn-rs.h"
#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \
[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
@@ -63,7 +68,7 @@
* maps to IWL_RATE_INVALID
*
*/
-const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT] = {
+const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = {
IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2), /* 1mbps */
IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5), /* 2mbps */
IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11), /*5.5mbps */
@@ -91,7 +96,7 @@ const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT] = {
* Use for only special debugging. This function is just a placeholder as-is,
* you'll need to provide the special bits! ...
* ... and set IWL_EVT_DISABLE to 1. */
-void iwl3945_disable_events(struct iwl3945_priv *priv)
+void iwl3945_disable_events(struct iwl_priv *priv)
{
int ret;
int i;
@@ -150,34 +155,34 @@ void iwl3945_disable_events(struct iwl3945_priv *priv)
base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
if (!iwl3945_hw_valid_rtc_data_addr(base)) {
- IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
return;
}
- ret = iwl3945_grab_nic_access(priv);
+ ret = iwl_grab_nic_access(priv);
if (ret) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
- disable_ptr = iwl3945_read_targ_mem(priv, base + (4 * sizeof(u32)));
- array_size = iwl3945_read_targ_mem(priv, base + (5 * sizeof(u32)));
- iwl3945_release_nic_access(priv);
+ disable_ptr = iwl_read_targ_mem(priv, base + (4 * sizeof(u32)));
+ array_size = iwl_read_targ_mem(priv, base + (5 * sizeof(u32)));
+ iwl_release_nic_access(priv);
if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) {
- IWL_DEBUG_INFO("Disabling selected uCode log events at 0x%x\n",
+ IWL_DEBUG_INFO(priv, "Disabling selected uCode log events at 0x%x\n",
disable_ptr);
- ret = iwl3945_grab_nic_access(priv);
+ ret = iwl_grab_nic_access(priv);
for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++)
- iwl3945_write_targ_mem(priv,
+ iwl_write_targ_mem(priv,
disable_ptr + (i * sizeof(u32)),
evt_disable[i]);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
} else {
- IWL_DEBUG_INFO("Selected uCode log events may be disabled\n");
- IWL_DEBUG_INFO(" by writing \"1\"s into disable bitmap\n");
- IWL_DEBUG_INFO(" in SRAM at 0x%x, size %d u32s\n",
+ IWL_DEBUG_INFO(priv, "Selected uCode log events may be disabled\n");
+ IWL_DEBUG_INFO(priv, " by writing \"1\"s into disable bitmap\n");
+ IWL_DEBUG_INFO(priv, " in SRAM at 0x%x, size %d u32s\n",
disable_ptr, array_size);
}
@@ -193,40 +198,7 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
return -1;
}
-/**
- * iwl3945_get_antenna_flags - Get antenna flags for RXON command
- * @priv: eeprom and antenna fields are used to determine antenna flags
- *
- * priv->eeprom is used to determine if antenna AUX/MAIN are reversed
- * priv->antenna specifies the antenna diversity mode:
- *
- * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself
- * IWL_ANTENNA_MAIN - Force MAIN antenna
- * IWL_ANTENNA_AUX - Force AUX antenna
- */
-__le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv)
-{
- switch (priv->antenna) {
- case IWL_ANTENNA_DIVERSITY:
- return 0;
-
- case IWL_ANTENNA_MAIN:
- if (priv->eeprom.antenna_switch_type)
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
-
- case IWL_ANTENNA_AUX:
- if (priv->eeprom.antenna_switch_type)
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
- }
-
- /* bad antenna selector value */
- IWL_ERROR("Bad antenna selector value (0x%x)\n", priv->antenna);
- return 0; /* "diversity" is default if error */
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
static const char *iwl3945_get_tx_fail_reason(u32 status)
@@ -266,7 +238,7 @@ static inline const char *iwl3945_get_tx_fail_reason(u32 status)
* for A and B mode we need to overright prev
* value
*/
-int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
+int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate)
{
int next_rate = iwl3945_get_prev_ieee_rate(rate);
@@ -279,7 +251,7 @@ int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
break;
case IEEE80211_BAND_2GHZ:
if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
- iwl3945_is_associated(priv)) {
+ iwl_is_associated(priv)) {
if (rate == IWL_RATE_11M_INDEX)
next_rate = IWL_RATE_5M_INDEX;
}
@@ -300,12 +272,12 @@ int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
* need to be reclaimed. As result, some free space forms. If there is
* enough free space (> low mark), wake the stack that feeds us.
*/
-static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
+static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
int txq_id, int index)
{
- struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
- struct iwl3945_queue *q = &txq->q;
- struct iwl3945_tx_info *tx_info;
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
+ struct iwl_queue *q = &txq->q;
+ struct iwl_tx_info *tx_info;
BUG_ON(txq_id == IWL_CMD_QUEUE_NUM);
@@ -315,34 +287,34 @@ static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
tx_info = &txq->txb[txq->q.read_ptr];
ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]);
tx_info->skb[0] = NULL;
- iwl3945_hw_txq_free_tfd(priv, txq);
+ priv->cfg->ops->lib->txq_free_tfd(priv, txq);
}
- if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) &&
+ if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
(txq_id != IWL_CMD_QUEUE_NUM) &&
priv->mac80211_registered)
- ieee80211_wake_queue(priv->hw, txq_id);
+ iwl_wake_queue(priv, txq_id);
}
/**
* iwl3945_rx_reply_tx - Handle Tx response
*/
-static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
int txq_id = SEQ_TO_QUEUE(sequence);
int index = SEQ_TO_INDEX(sequence);
- struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
+ struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct ieee80211_tx_info *info;
struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
u32 status = le32_to_cpu(tx_resp->status);
int rate_idx;
int fail;
- if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+ if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
+ IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
"is out of range [0-%d] %d %d\n", txq_id,
index, txq->q.n_bd, txq->q.write_ptr,
txq->q.read_ptr);
@@ -366,15 +338,15 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
IEEE80211_TX_STAT_ACK : 0;
- IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
+ IWL_DEBUG_TX(priv, "Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
txq_id, iwl3945_get_tx_fail_reason(status), status,
tx_resp->rate, tx_resp->failure_frame);
- IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
+ IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index);
iwl3945_tx_queue_reclaim(priv, txq_id, index);
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
- IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
+ IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
}
@@ -387,14 +359,14 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
*
*****************************************************************************/
-void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
+void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
(int)sizeof(struct iwl3945_notif_statistics),
le32_to_cpu(pkt->len));
- memcpy(&priv->statistics, pkt->u.raw, sizeof(priv->statistics));
+ memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39));
iwl3945_led_background(priv);
@@ -406,7 +378,7 @@ void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_b
* Misc. internal state and helper functions
*
******************************************************************************/
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
/**
* iwl3945_report_frame - dump frame to syslog during debug sessions
@@ -415,8 +387,8 @@ void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_b
* including selective frame dumps.
* group100 parameter selects whether to show 1 out of 100 good frames.
*/
-static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
- struct iwl3945_rx_packet *pkt,
+static void _iwl3945_dbg_report_frame(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
struct ieee80211_hdr *header, int group100)
{
u32 to_us;
@@ -524,13 +496,13 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
* MAC addresses show just the last byte (for brevity),
* but you can hack it to show more, if you'd like to. */
if (dataframe)
- IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
+ IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
"len=%u, rssi=%d, chnl=%d, rate=%d, \n",
title, le16_to_cpu(fc), header->addr1[5],
length, rssi, channel, rate);
else {
/* src/dst addresses assume managed mode */
- IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
+ IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, "
"src=0x%02x, rssi=%u, tim=%lu usec, "
"phy=0x%02x, chnl=%d\n",
title, le16_to_cpu(fc), header->addr1[5],
@@ -540,18 +512,27 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
}
}
if (print_dump)
- iwl3945_print_hex_dump(IWL_DL_RX, data, length);
+ iwl_print_hex_dump(priv, IWL_DL_RX, data, length);
+}
+
+static void iwl3945_dbg_report_frame(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
+ struct ieee80211_hdr *header, int group100)
+{
+ if (priv->debug_level & IWL_DL_RX)
+ _iwl3945_dbg_report_frame(priv, pkt, header, group100);
}
+
#else
-static inline void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
- struct iwl3945_rx_packet *pkt,
+static inline void iwl3945_dbg_report_frame(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
struct ieee80211_hdr *header, int group100)
{
}
#endif
/* This is necessary only for a number of statistics, see the caller. */
-static int iwl3945_is_network_packet(struct iwl3945_priv *priv,
+static int iwl3945_is_network_packet(struct iwl_priv *priv,
struct ieee80211_hdr *header)
{
/* Filter incoming packets to determine if they are targeted toward
@@ -568,12 +549,12 @@ static int iwl3945_is_network_packet(struct iwl3945_priv *priv,
}
}
-static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb,
+static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb,
struct ieee80211_rx_status *stats)
{
- struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
-#ifdef CONFIG_IWL3945_LEDS
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+#ifdef CONFIG_IWLWIFI_LEDS
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
#endif
struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
@@ -581,15 +562,15 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
short len = le16_to_cpu(rx_hdr->len);
/* We received data from the HW, so stop the watchdog */
- if (unlikely((len + IWL_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
- IWL_DEBUG_DROP("Corruption detected!\n");
+ if (unlikely((len + IWL39_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
+ IWL_DEBUG_DROP(priv, "Corruption detected!\n");
return;
}
/* We only process data packets if the interface is open */
if (unlikely(!priv->is_open)) {
- IWL_DEBUG_DROP_LIMIT
- ("Dropping packet while interface is not open.\n");
+ IWL_DEBUG_DROP_LIMIT(priv,
+ "Dropping packet while interface is not open.\n");
return;
}
@@ -597,11 +578,12 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
/* Set the size of the skb to the size of the frame */
skb_put(rxb->skb, le16_to_cpu(rx_hdr->len));
- if (iwl3945_param_hwcrypto)
- iwl3945_set_decrypted_flag(priv, rxb->skb,
+ if (!iwl3945_mod_params.sw_crypto)
+ iwl_set_decrypted_flag(priv,
+ (struct ieee80211_hdr *)rxb->skb->data,
le32_to_cpu(rx_end->status), stats);
-#ifdef CONFIG_IWL3945_LEDS
+#ifdef CONFIG_IWLWIFI_LEDS
if (ieee80211_is_data(hdr->frame_control))
priv->rxtxpackets += len;
#endif
@@ -611,12 +593,12 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
-static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
struct ieee80211_hdr *header;
struct ieee80211_rx_status rx_status;
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
@@ -644,22 +626,21 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
rx_status.flag |= RX_FLAG_SHORTPRE;
if ((unlikely(rx_stats->phy_count > 20))) {
- IWL_DEBUG_DROP
- ("dsp size out of range [0,20]: "
- "%d/n", rx_stats->phy_count);
+ IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
+ rx_stats->phy_count);
return;
}
if (!(rx_end->status & RX_RES_STATUS_NO_CRC32_ERROR)
|| !(rx_end->status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
- IWL_DEBUG_RX("Bad CRC or FIFO: 0x%08X.\n", rx_end->status);
+ IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", rx_end->status);
return;
}
/* Convert 3945's rssi indicator to dBm */
- rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET;
+ rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET;
/* Set default noise value to -127 */
if (priv->last_rx_noise == 0)
@@ -691,7 +672,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
}
- IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n",
+ IWL_DEBUG_STATS(priv, "Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n",
rx_status.signal, rx_status.noise, rx_status.qual,
rx_stats_sig_avg, rx_stats_noise_diff);
@@ -699,17 +680,14 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
network_packet = iwl3945_is_network_packet(priv, header);
- IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n",
+ IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n",
network_packet ? '*' : ' ',
le16_to_cpu(rx_hdr->channel),
rx_status.signal, rx_status.signal,
rx_status.noise, rx_status.rate_idx);
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & (IWL_DL_RX))
- /* Set "1" to report good data frames in groups of 100 */
- iwl3945_dbg_report_frame(priv, pkt, header, 1);
-#endif
+ /* Set "1" to report good data frames in groups of 100 */
+ iwl3945_dbg_report_frame(priv, pkt, header, 1);
if (network_packet) {
priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
@@ -721,24 +699,31 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
}
-int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr,
- dma_addr_t addr, u16 len)
+int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len, u8 reset, u8 pad)
{
int count;
- u32 pad;
- struct iwl3945_tfd_frame *tfd = (struct iwl3945_tfd_frame *)ptr;
+ struct iwl_queue *q;
+ struct iwl3945_tfd *tfd, *tfd_tmp;
+
+ q = &txq->q;
+ tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
+ tfd = &tfd_tmp[q->write_ptr];
+
+ if (reset)
+ memset(tfd, 0, sizeof(*tfd));
count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));
- pad = TFD_CTL_PAD_GET(le32_to_cpu(tfd->control_flags));
if ((count >= NUM_TFD_CHUNKS) || (count < 0)) {
- IWL_ERROR("Error can not send more than %d chunks\n",
+ IWL_ERR(priv, "Error can not send more than %d chunks\n",
NUM_TFD_CHUNKS);
return -EINVAL;
}
- tfd->pa[count].addr = cpu_to_le32(addr);
- tfd->pa[count].len = cpu_to_le32(len);
+ tfd->tbs[count].addr = cpu_to_le32(addr);
+ tfd->tbs[count].len = cpu_to_le32(len);
count++;
@@ -753,32 +738,35 @@ int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr,
*
* Does NOT advance any indexes
*/
-int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
+void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
{
- struct iwl3945_tfd_frame *bd_tmp = (struct iwl3945_tfd_frame *)&txq->bd[0];
- struct iwl3945_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
+ struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
+ int index = txq->q.read_ptr;
+ struct iwl3945_tfd *tfd = &tfd_tmp[index];
struct pci_dev *dev = priv->pci_dev;
int i;
int counter;
- /* classify bd */
- if (txq->q.id == IWL_CMD_QUEUE_NUM)
- /* nothing to cleanup after for host commands */
- return 0;
-
/* sanity check */
- counter = TFD_CTL_COUNT_GET(le32_to_cpu(bd->control_flags));
+ counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));
if (counter > NUM_TFD_CHUNKS) {
- IWL_ERROR("Too many chunks: %i\n", counter);
+ IWL_ERR(priv, "Too many chunks: %i\n", counter);
/* @todo issue fatal error, it is quite serious situation */
- return 0;
+ return;
}
+ /* Unmap tx_cmd */
+ if (counter)
+ pci_unmap_single(dev,
+ pci_unmap_addr(&txq->cmd[index]->meta, mapping),
+ pci_unmap_len(&txq->cmd[index]->meta, len),
+ PCI_DMA_TODEVICE);
+
/* unmap chunks if any */
for (i = 1; i < counter; i++) {
- pci_unmap_single(dev, le32_to_cpu(bd->pa[i].addr),
- le32_to_cpu(bd->pa[i].len), PCI_DMA_TODEVICE);
+ pci_unmap_single(dev, le32_to_cpu(tfd->tbs[i].addr),
+ le32_to_cpu(tfd->tbs[i].len), PCI_DMA_TODEVICE);
if (txq->txb[txq->q.read_ptr].skb[0]) {
struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[0];
if (txq->txb[txq->q.read_ptr].skb[0]) {
@@ -788,10 +776,10 @@ int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *
}
}
}
- return 0;
+ return ;
}
-u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
+u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *addr)
{
int i, start = IWL_AP_ID;
int ret = IWL_INVALID_STATION;
@@ -802,18 +790,18 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
start = IWL_STA_ID;
if (is_broadcast_ether_addr(addr))
- return priv->hw_setting.bcast_sta_id;
+ return priv->hw_params.bcast_sta_id;
spin_lock_irqsave(&priv->sta_lock, flags);
- for (i = start; i < priv->hw_setting.max_stations; i++)
- if ((priv->stations[i].used) &&
+ for (i = start; i < priv->hw_params.max_stations; i++)
+ if ((priv->stations_39[i].used) &&
(!compare_ether_addr
- (priv->stations[i].sta.sta.addr, addr))) {
+ (priv->stations_39[i].sta.sta.addr, addr))) {
ret = i;
goto out;
}
- IWL_DEBUG_INFO("can not find STA %pM (total %d)\n",
+ IWL_DEBUG_INFO(priv, "can not find STA %pM (total %d)\n",
addr, priv->num_stations);
out:
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -824,12 +812,10 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
* iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
*
*/
-void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
+void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
struct ieee80211_tx_info *info,
struct ieee80211_hdr *hdr, int sta_id, int tx_id)
{
- unsigned long flags;
u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
u16 rate_mask;
@@ -838,25 +824,15 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
u8 data_retry_limit;
__le32 tx_flags;
__le16 fc = hdr->frame_control;
+ struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
rate = iwl3945_rates[rate_index].plcp;
- tx_flags = cmd->cmd.tx.tx_flags;
+ tx_flags = tx->tx_flags;
/* We need to figure out how to get the sta->supp_rates while
* in this running context */
rate_mask = IWL_RATES_MASK;
- spin_lock_irqsave(&priv->sta_lock, flags);
-
- priv->stations[sta_id].current_rate.rate_n_flags = rate;
-
- if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
- (sta_id != priv->hw_setting.bcast_sta_id) &&
- (sta_id != IWL_MULTICAST_ID))
- priv->stations[IWL_STA_ID].current_rate.rate_n_flags = rate;
-
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-
if (tx_id >= IWL_CMD_QUEUE_NUM)
rts_retry_limit = 3;
else
@@ -888,25 +864,25 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
}
}
- cmd->cmd.tx.rts_retry_limit = rts_retry_limit;
- cmd->cmd.tx.data_retry_limit = data_retry_limit;
- cmd->cmd.tx.rate = rate;
- cmd->cmd.tx.tx_flags = tx_flags;
+ tx->rts_retry_limit = rts_retry_limit;
+ tx->data_retry_limit = data_retry_limit;
+ tx->rate = rate;
+ tx->tx_flags = tx_flags;
/* OFDM */
- cmd->cmd.tx.supp_rates[0] =
+ tx->supp_rates[0] =
((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF;
/* CCK */
- cmd->cmd.tx.supp_rates[1] = (rate_mask & 0xF);
+ tx->supp_rates[1] = (rate_mask & 0xF);
- IWL_DEBUG_RATE("Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "
+ IWL_DEBUG_RATE(priv, "Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "
"cck/ofdm mask: 0x%x/0x%x\n", sta_id,
- cmd->cmd.tx.rate, le32_to_cpu(cmd->cmd.tx.tx_flags),
- cmd->cmd.tx.supp_rates[1], cmd->cmd.tx.supp_rates[0]);
+ tx->rate, le32_to_cpu(tx->tx_flags),
+ tx->supp_rates[1], tx->supp_rates[0]);
}
-u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, u16 tx_rate, u8 flags)
+u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
{
unsigned long flags_spin;
struct iwl3945_station_entry *station;
@@ -915,138 +891,133 @@ u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, u16 tx_rate, u8 flags
return IWL_INVALID_STATION;
spin_lock_irqsave(&priv->sta_lock, flags_spin);
- station = &priv->stations[sta_id];
+ station = &priv->stations_39[sta_id];
station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
station->sta.rate_n_flags = cpu_to_le16(tx_rate);
- station->current_rate.rate_n_flags = tx_rate;
station->sta.mode = STA_CONTROL_MODIFY_MSK;
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
- iwl3945_send_add_station(priv, &station->sta, flags);
- IWL_DEBUG_RATE("SCALE sync station %d to rate %d\n",
+ iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&station->sta, flags);
+ IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
sta_id, tx_rate);
return sta_id;
}
-static int iwl3945_nic_set_pwr_src(struct iwl3945_priv *priv, int pwr_max)
+static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
{
- int rc;
+ int ret;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
- if (rc) {
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
+ return ret;
}
- if (!pwr_max) {
- u32 val;
-
- rc = pci_read_config_dword(priv->pci_dev,
- PCI_POWER_SOURCE, &val);
- if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) {
- iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+ if (src == IWL_PWR_SRC_VAUX) {
+ if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) {
+ iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
~APMG_PS_CTRL_MSK_PWR_SRC);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
- iwl3945_poll_bit(priv, CSR_GPIO_IN,
+ iwl_poll_bit(priv, CSR_GPIO_IN,
CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
CSR_GPIO_IN_BIT_AUX_POWER, 5000);
- } else
- iwl3945_release_nic_access(priv);
+ } else {
+ iwl_release_nic_access(priv);
+ }
} else {
- iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
+ iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
~APMG_PS_CTRL_MSK_PWR_SRC);
- iwl3945_release_nic_access(priv);
- iwl3945_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
+ iwl_release_nic_access(priv);
+ iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */
}
spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
+ return ret;
}
-static int iwl3945_rx_init(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
+static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
{
int rc;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
- iwl3945_write_direct32(priv, FH_RCSR_RBD_BASE(0), rxq->dma_addr);
- iwl3945_write_direct32(priv, FH_RCSR_RPTR_ADDR(0),
- priv->hw_setting.shared_phys +
- offsetof(struct iwl3945_shared, rx_read_ptr[0]));
- iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), 0);
- iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0),
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE |
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE |
- ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN |
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 |
- (RX_QUEUE_SIZE_LOG << ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) |
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST |
- (1 << ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) |
- ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH);
+ iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->dma_addr);
+ iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma);
+ iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0);
+ iwl_write_direct32(priv, FH39_RCSR_CONFIG(0),
+ FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE |
+ FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE |
+ FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN |
+ FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 |
+ (RX_QUEUE_SIZE_LOG << FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) |
+ FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST |
+ (1 << FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) |
+ FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH);
/* fake read to flush all prev I/O */
- iwl3945_read_direct32(priv, FH_RSSR_CTRL);
+ iwl_read_direct32(priv, FH39_RSSR_CTRL);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
-static int iwl3945_tx_reset(struct iwl3945_priv *priv)
+static int iwl3945_tx_reset(struct iwl_priv *priv)
{
int rc;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
/* bypass mode */
- iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
+ iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
/* RA 0 is active */
- iwl3945_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01);
+ iwl_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01);
/* all 6 fifo are active */
- iwl3945_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f);
-
- iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000);
- iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002);
- iwl3945_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004);
- iwl3945_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
-
- iwl3945_write_direct32(priv, FH_TSSR_CBB_BASE,
- priv->hw_setting.shared_phys);
-
- iwl3945_write_direct32(priv, FH_TSSR_MSG_CONFIG,
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |
- ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);
-
- iwl3945_release_nic_access(priv);
+ iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f);
+
+ iwl_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000);
+ iwl_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002);
+ iwl_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004);
+ iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
+
+ iwl_write_direct32(priv, FH39_TSSR_CBB_BASE,
+ priv->shared_phys);
+
+ iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG,
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |
+ FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);
+
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
@@ -1057,7 +1028,7 @@ static int iwl3945_tx_reset(struct iwl3945_priv *priv)
*
* Destroys all DMA structures and initialize them again
*/
-static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv)
+static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
{
int rc;
int txq_id, slots_num;
@@ -1070,13 +1041,13 @@ static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv)
goto error;
/* Tx queue(s) */
- for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) {
+ for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++) {
slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
- rc = iwl3945_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
- txq_id);
+ rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
+ txq_id);
if (rc) {
- IWL_ERROR("Tx %d queue init failed\n", txq_id);
+ IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
goto error;
}
}
@@ -1088,111 +1059,140 @@ static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv)
return rc;
}
-int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
+static int iwl3945_apm_init(struct iwl_priv *priv)
{
- u8 rev_id;
- int rc;
- unsigned long flags;
- struct iwl3945_rx_queue *rxq = &priv->rxq;
+ int ret = 0;
- iwl3945_power_init_handle(priv);
+ iwl_power_initialize(priv);
- spin_lock_irqsave(&priv->lock, flags);
- iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, CSR39_ANA_PLL_CFG_VAL);
- iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
- CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
-
- iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- rc = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
- if (rc < 0) {
- spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("Failed to init the card\n");
- return rc;
- }
+ iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+ CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
- rc = iwl3945_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
+ /* disable L0s without affecting L1 :don't wait for ICH L0s bug W/A) */
+ iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+ CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
+
+ /* set "initialization complete" bit to move adapter
+ * D0U* --> D0A* state */
+ iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+ ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ if (ret < 0) {
+ IWL_DEBUG_INFO(priv, "Failed to init the card\n");
+ goto out;
}
- iwl3945_write_prph(priv, APMG_CLK_EN_REG,
- APMG_CLK_VAL_DMA_CLK_RQT |
- APMG_CLK_VAL_BSM_CLK_RQT);
+
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ goto out;
+
+ /* enable DMA */
+ iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
+ APMG_CLK_VAL_BSM_CLK_RQT);
+
udelay(20);
- iwl3945_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
- APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
- iwl3945_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
- /* Determine HW type */
- rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
- if (rc)
- return rc;
- IWL_DEBUG_INFO("HW Revision ID = 0x%X\n", rev_id);
+ /* disable L1-Active */
+ iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
+ APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
+
+ iwl_release_nic_access(priv);
+out:
+ return ret;
+}
+
+static void iwl3945_nic_config(struct iwl_priv *priv)
+{
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+ unsigned long flags;
+ u8 rev_id = 0;
- iwl3945_nic_set_pwr_src(priv, 1);
spin_lock_irqsave(&priv->lock, flags);
if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
- IWL_DEBUG_INFO("RTP type \n");
+ IWL_DEBUG_INFO(priv, "RTP type \n");
else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
- IWL_DEBUG_INFO("3945 RADIO-MB type\n");
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n");
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_3945_MB);
} else {
- IWL_DEBUG_INFO("3945 RADIO-MM type\n");
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ IWL_DEBUG_INFO(priv, "3945 RADIO-MM type\n");
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_3945_MM);
}
- if (EEPROM_SKU_CAP_OP_MODE_MRC == priv->eeprom.sku_cap) {
- IWL_DEBUG_INFO("SKU OP mode is mrc\n");
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ if (EEPROM_SKU_CAP_OP_MODE_MRC == eeprom->sku_cap) {
+ IWL_DEBUG_INFO(priv, "SKU OP mode is mrc\n");
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC);
} else
- IWL_DEBUG_INFO("SKU OP mode is basic\n");
+ IWL_DEBUG_INFO(priv, "SKU OP mode is basic\n");
- if ((priv->eeprom.board_revision & 0xF0) == 0xD0) {
- IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
- priv->eeprom.board_revision);
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ if ((eeprom->board_revision & 0xF0) == 0xD0) {
+ IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n",
+ eeprom->board_revision);
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
} else {
- IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
- priv->eeprom.board_revision);
- iwl3945_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+ IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n",
+ eeprom->board_revision);
+ iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
}
- if (priv->eeprom.almgor_m_version <= 1) {
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ if (eeprom->almgor_m_version <= 1) {
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A);
- IWL_DEBUG_INFO("Card M type A version is 0x%X\n",
- priv->eeprom.almgor_m_version);
+ IWL_DEBUG_INFO(priv, "Card M type A version is 0x%X\n",
+ eeprom->almgor_m_version);
} else {
- IWL_DEBUG_INFO("Card M type B version is 0x%X\n",
- priv->eeprom.almgor_m_version);
- iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+ IWL_DEBUG_INFO(priv, "Card M type B version is 0x%X\n",
+ eeprom->almgor_m_version);
+ iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B);
}
spin_unlock_irqrestore(&priv->lock, flags);
- if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
- IWL_DEBUG_RF_KILL("SW RF KILL supported in EEPROM.\n");
+ if (eeprom->sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
+ IWL_DEBUG_RF_KILL(priv, "SW RF KILL supported in EEPROM.\n");
+
+ if (eeprom->sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
+ IWL_DEBUG_RF_KILL(priv, "HW RF KILL supported in EEPROM.\n");
+}
+
+int iwl3945_hw_nic_init(struct iwl_priv *priv)
+{
+ u8 rev_id;
+ int rc;
+ unsigned long flags;
+ struct iwl_rx_queue *rxq = &priv->rxq;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->cfg->ops->lib->apm_ops.init(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ /* Determine HW type */
+ rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
+ if (rc)
+ return rc;
+ IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
+
+ rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
+ if (rc)
+ return rc;
- if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
- IWL_DEBUG_RF_KILL("HW RF KILL supported in EEPROM.\n");
+ priv->cfg->ops->lib->apm_ops.config(priv);
/* Allocate the RX queue, or reset if it is already allocated */
if (!rxq->bd) {
- rc = iwl3945_rx_queue_alloc(priv);
+ rc = iwl_rx_queue_alloc(priv);
if (rc) {
- IWL_ERROR("Unable to initialize Rx queue\n");
+ IWL_ERR(priv, "Unable to initialize Rx queue\n");
return -ENOMEM;
}
} else
- iwl3945_rx_queue_reset(priv, rxq);
+ iwl_rx_queue_reset(priv, rxq);
iwl3945_rx_replenish(priv);
@@ -1202,16 +1202,16 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
/* Look at using this instead:
rxq->need_update = 1;
- iwl3945_rx_queue_update_write_ptr(priv, rxq);
+ iwl_rx_queue_update_write_ptr(priv, rxq);
*/
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
- iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), rxq->write & ~7);
- iwl3945_release_nic_access(priv);
+ iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -1229,116 +1229,125 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
*
* Destroy all TX DMA queues and structures
*/
-void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv)
+void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
{
int txq_id;
/* Tx queues */
- for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++)
- iwl3945_tx_queue_free(priv, &priv->txq[txq_id]);
+ for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++)
+ if (txq_id == IWL_CMD_QUEUE_NUM)
+ iwl_cmd_queue_free(priv);
+ else
+ iwl_tx_queue_free(priv, txq_id);
+
}
-void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv)
+void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
{
- int queue;
+ int txq_id;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- if (iwl3945_grab_nic_access(priv)) {
+ if (iwl_grab_nic_access(priv)) {
spin_unlock_irqrestore(&priv->lock, flags);
iwl3945_hw_txq_ctx_free(priv);
return;
}
/* stop SCD */
- iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0);
+ iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
/* reset TFD queues */
- for (queue = TFD_QUEUE_MIN; queue < TFD_QUEUE_MAX; queue++) {
- iwl3945_write_direct32(priv, FH_TCSR_CONFIG(queue), 0x0);
- iwl3945_poll_direct_bit(priv, FH_TSSR_TX_STATUS,
- ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(queue),
+ for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++) {
+ iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0);
+ iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS,
+ FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
1000);
}
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
iwl3945_hw_txq_ctx_free(priv);
}
-int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv)
+static int iwl3945_apm_stop_master(struct iwl_priv *priv)
{
- int rc = 0;
- u32 reg_val;
+ int ret = 0;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
/* set stop master bit */
- iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+ iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
- reg_val = iwl3945_read32(priv, CSR_GP_CNTRL);
+ iwl_poll_direct_bit(priv, CSR_RESET,
+ CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
- if (CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE ==
- (reg_val & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE))
- IWL_DEBUG_INFO("Card in power save, master is already "
- "stopped\n");
- else {
- rc = iwl3945_poll_direct_bit(priv, CSR_RESET,
- CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
- if (rc < 0) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
- }
+ if (ret < 0)
+ goto out;
+out:
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("stop master\n");
+ IWL_DEBUG_INFO(priv, "stop master\n");
- return rc;
+ return ret;
+}
+
+static void iwl3945_apm_stop(struct iwl_priv *priv)
+{
+ unsigned long flags;
+
+ iwl3945_apm_stop_master(priv);
+
+ spin_lock_irqsave(&priv->lock, flags);
+
+ iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+
+ udelay(10);
+ /* clear "init complete" move adapter D0A* --> D0U state */
+ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ spin_unlock_irqrestore(&priv->lock, flags);
}
-int iwl3945_hw_nic_reset(struct iwl3945_priv *priv)
+static int iwl3945_apm_reset(struct iwl_priv *priv)
{
int rc;
unsigned long flags;
- iwl3945_hw_nic_stop_master(priv);
+ iwl3945_apm_stop_master(priv);
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+ iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+ udelay(10);
+
+ iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
+ iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (!rc) {
- iwl3945_write_prph(priv, APMG_CLK_CTRL_REG,
+ iwl_write_prph(priv, APMG_CLK_CTRL_REG,
APMG_CLK_VAL_BSM_CLK_RQT);
- udelay(10);
-
- iwl3945_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-
- iwl3945_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
- iwl3945_write_prph(priv, APMG_RTC_INT_STT_REG,
+ iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
+ iwl_write_prph(priv, APMG_RTC_INT_STT_REG,
0xFFFFFFFF);
/* enable DMA */
- iwl3945_write_prph(priv, APMG_CLK_EN_REG,
+ iwl_write_prph(priv, APMG_CLK_EN_REG,
APMG_CLK_VAL_DMA_CLK_RQT |
APMG_CLK_VAL_BSM_CLK_RQT);
udelay(10);
- iwl3945_set_bits_prph(priv, APMG_PS_CTRL_REG,
+ iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_RESET_REQ);
udelay(5);
- iwl3945_clear_bits_prph(priv, APMG_PS_CTRL_REG,
+ iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_RESET_REQ);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
}
/* Clear the 'host command active' bit... */
@@ -1367,33 +1376,34 @@ static inline int iwl3945_hw_reg_temp_out_of_range(int temperature)
return ((temperature < -260) || (temperature > 25)) ? 1 : 0;
}
-int iwl3945_hw_get_temperature(struct iwl3945_priv *priv)
+int iwl3945_hw_get_temperature(struct iwl_priv *priv)
{
- return iwl3945_read32(priv, CSR_UCODE_DRV_GP2);
+ return iwl_read32(priv, CSR_UCODE_DRV_GP2);
}
/**
* iwl3945_hw_reg_txpower_get_temperature
* get the current temperature by reading from NIC
*/
-static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv)
+static int iwl3945_hw_reg_txpower_get_temperature(struct iwl_priv *priv)
{
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
int temperature;
temperature = iwl3945_hw_get_temperature(priv);
/* driver's okay range is -260 to +25.
* human readable okay range is 0 to +285 */
- IWL_DEBUG_INFO("Temperature: %d\n", temperature + IWL_TEMP_CONVERT);
+ IWL_DEBUG_INFO(priv, "Temperature: %d\n", temperature + IWL_TEMP_CONVERT);
/* handle insane temp reading */
if (iwl3945_hw_reg_temp_out_of_range(temperature)) {
- IWL_ERROR("Error bad temperature value %d\n", temperature);
+ IWL_ERR(priv, "Error bad temperature value %d\n", temperature);
/* if really really hot(?),
* substitute the 3rd band/group's temp measured at factory */
if (priv->last_temperature > 100)
- temperature = priv->eeprom.groups[2].temperature;
+ temperature = eeprom->groups[2].temperature;
else /* else use most recent "sane" value from driver */
temperature = priv->last_temperature;
}
@@ -1412,7 +1422,7 @@ static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv)
* records new temperature in tx_mgr->temperature.
* replaces tx_mgr->last_temperature *only* if calib needed
* (assumes caller will actually do the calibration!). */
-static int is_temp_calib_needed(struct iwl3945_priv *priv)
+static int is_temp_calib_needed(struct iwl_priv *priv)
{
int temp_diff;
@@ -1421,20 +1431,20 @@ static int is_temp_calib_needed(struct iwl3945_priv *priv)
/* get absolute value */
if (temp_diff < 0) {
- IWL_DEBUG_POWER("Getting cooler, delta %d,\n", temp_diff);
+ IWL_DEBUG_POWER(priv, "Getting cooler, delta %d,\n", temp_diff);
temp_diff = -temp_diff;
} else if (temp_diff == 0)
- IWL_DEBUG_POWER("Same temp,\n");
+ IWL_DEBUG_POWER(priv, "Same temp,\n");
else
- IWL_DEBUG_POWER("Getting warmer, delta %d,\n", temp_diff);
+ IWL_DEBUG_POWER(priv, "Getting warmer, delta %d,\n", temp_diff);
/* if we don't need calibration, *don't* update last_temperature */
if (temp_diff < IWL_TEMPERATURE_LIMIT_TIMER) {
- IWL_DEBUG_POWER("Timed thermal calib not needed\n");
+ IWL_DEBUG_POWER(priv, "Timed thermal calib not needed\n");
return 0;
}
- IWL_DEBUG_POWER("Timed thermal calib needed\n");
+ IWL_DEBUG_POWER(priv, "Timed thermal calib needed\n");
/* assume that caller will actually do calib ...
* update the "last temperature" value */
@@ -1627,9 +1637,9 @@ static inline u8 iwl3945_hw_reg_fix_power_index(int index)
* Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK)
* or 6 Mbit (OFDM) rates.
*/
-static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tbl_index,
+static void iwl3945_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
s32 rate_index, const s8 *clip_pwrs,
- struct iwl3945_channel_info *ch_info,
+ struct iwl_channel_info *ch_info,
int band_index)
{
struct iwl3945_scan_power_info *scan_power_info;
@@ -1646,7 +1656,7 @@ static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tb
/* further limit to user's max power preference.
* FIXME: Other spectrum management power limitations do not
* seem to apply?? */
- power = min(power, priv->user_txpower_limit);
+ power = min(power, priv->tx_power_user_lmt);
scan_power_info->requested_power = power;
/* find difference between new scan *power* and current "normal"
@@ -1678,32 +1688,32 @@ static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tb
}
/**
- * iwl3945_hw_reg_send_txpower - fill in Tx Power command with gain settings
+ * iwl3945_send_tx_power - fill in Tx Power command with gain settings
*
* Configures power settings for all rates for the current channel,
* using values from channel info struct, and send to NIC
*/
-int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
+static int iwl3945_send_tx_power(struct iwl_priv *priv)
{
int rate_idx, i;
- const struct iwl3945_channel_info *ch_info = NULL;
+ const struct iwl_channel_info *ch_info = NULL;
struct iwl3945_txpowertable_cmd txpower = {
.channel = priv->active_rxon.channel,
};
txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
- ch_info = iwl3945_get_channel_info(priv,
+ ch_info = iwl_get_channel_info(priv,
priv->band,
le16_to_cpu(priv->active_rxon.channel));
if (!ch_info) {
- IWL_ERROR
- ("Failed to get channel info for channel %d [%d]\n",
- le16_to_cpu(priv->active_rxon.channel), priv->band);
+ IWL_ERR(priv,
+ "Failed to get channel info for channel %d [%d]\n",
+ le16_to_cpu(priv->active_rxon.channel), priv->band);
return -EINVAL;
}
if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_POWER("Not calling TX_PWR_TABLE_CMD on "
+ IWL_DEBUG_POWER(priv, "Not calling TX_PWR_TABLE_CMD on "
"non-Tx channel.\n");
return 0;
}
@@ -1711,12 +1721,12 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
/* fill cmd with power settings for all rates for current channel */
/* Fill OFDM rate */
for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0;
- rate_idx <= IWL_LAST_OFDM_RATE; rate_idx++, i++) {
+ rate_idx <= IWL39_LAST_OFDM_RATE; rate_idx++, i++) {
txpower.power[i].tpc = ch_info->power_info[i].tpc;
txpower.power[i].rate = iwl3945_rates[rate_idx].plcp;
- IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
+ IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
le16_to_cpu(txpower.channel),
txpower.band,
txpower.power[i].tpc.tx_gain,
@@ -1729,7 +1739,7 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
txpower.power[i].tpc = ch_info->power_info[i].tpc;
txpower.power[i].rate = iwl3945_rates[rate_idx].plcp;
- IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
+ IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
le16_to_cpu(txpower.channel),
txpower.band,
txpower.power[i].tpc.tx_gain,
@@ -1737,8 +1747,9 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
txpower.power[i].rate);
}
- return iwl3945_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
- sizeof(struct iwl3945_txpowertable_cmd), &txpower);
+ return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
+ sizeof(struct iwl3945_txpowertable_cmd),
+ &txpower);
}
@@ -1758,8 +1769,8 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
* properly fill out the scan powers, and actual h/w gain settings,
* and send changes to NIC
*/
-static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv,
- struct iwl3945_channel_info *ch_info)
+static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv,
+ struct iwl_channel_info *ch_info)
{
struct iwl3945_channel_power_info *power_info;
int power_changed = 0;
@@ -1768,7 +1779,7 @@ static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv,
int power;
/* Get this chnlgrp's rate-to-max/clip-powers table */
- clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
+ clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
/* Get this channel's rate-to-current-power settings table */
power_info = ch_info->power_info;
@@ -1821,7 +1832,7 @@ static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv,
* based strictly on regulatory (eeprom and spectrum mgt) limitations
* (no consideration for h/w clipping limitations).
*/
-static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl3945_channel_info *ch_info)
+static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info)
{
s8 max_power;
@@ -1849,9 +1860,10 @@ static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl3945_channel_info *ch_i
*
* If RxOn is "associated", this sends the new Txpower to NIC!
*/
-static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
+static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
{
- struct iwl3945_channel_info *ch_info = NULL;
+ struct iwl_channel_info *ch_info = NULL;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
int delta_index;
const s8 *clip_pwrs; /* array of h/w max power levels for each rate */
u8 a_band;
@@ -1867,7 +1879,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
a_band = is_channel_a_band(ch_info);
/* Get this chnlgrp's factory calibration temperature */
- ref_temp = (s16)priv->eeprom.groups[ch_info->group_index].
+ ref_temp = (s16)eeprom->groups[ch_info->group_index].
temperature;
/* get power index adjustment based on current and factory
@@ -1893,7 +1905,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
}
/* Get this chnlgrp's rate-to-max/clip-powers table */
- clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
+ clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
/* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */
for (scan_tbl_index = 0;
@@ -1907,24 +1919,24 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
}
/* send Txpower command for current channel to ucode */
- return iwl3945_hw_reg_send_txpower(priv);
+ return priv->cfg->ops->lib->send_tx_power(priv);
}
-int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power)
+int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
{
- struct iwl3945_channel_info *ch_info;
+ struct iwl_channel_info *ch_info;
s8 max_power;
u8 a_band;
u8 i;
- if (priv->user_txpower_limit == power) {
- IWL_DEBUG_POWER("Requested Tx power same as current "
+ if (priv->tx_power_user_lmt == power) {
+ IWL_DEBUG_POWER(priv, "Requested Tx power same as current "
"limit: %ddBm.\n", power);
return 0;
}
- IWL_DEBUG_POWER("Setting upper limit clamp to %ddBm.\n", power);
- priv->user_txpower_limit = power;
+ IWL_DEBUG_POWER(priv, "Setting upper limit clamp to %ddBm.\n", power);
+ priv->tx_power_user_lmt = power;
/* set up new Tx powers for each and every channel, 2.4 and 5.x */
@@ -1953,7 +1965,7 @@ int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power)
}
/* will add 3945 channel switch cmd handling later */
-int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel)
+int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
{
return 0;
}
@@ -1968,7 +1980,7 @@ int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel)
* -- send new set of gain settings to NIC
* NOTE: This should continue working, even when we're not associated,
* so we can keep our internal table of scan powers current. */
-void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv)
+void iwl3945_reg_txpower_periodic(struct iwl_priv *priv)
{
/* This will kick in the "brute force"
* iwl3945_hw_reg_comp_txpower_temp() below */
@@ -1987,7 +1999,7 @@ void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv)
static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
{
- struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv,
+ struct iwl_priv *priv = container_of(work, struct iwl_priv,
thermal_periodic.work);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -2009,10 +2021,11 @@ static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
* on A-band, EEPROM's "group frequency" entries represent the top
* channel in each group 1-4. Group 5 All B/G channels are in group 0.
*/
-static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv,
- const struct iwl3945_channel_info *ch_info)
+static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl_priv *priv,
+ const struct iwl_channel_info *ch_info)
{
- struct iwl3945_eeprom_txpower_group *ch_grp = &priv->eeprom.groups[0];
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+ struct iwl3945_eeprom_txpower_group *ch_grp = &eeprom->groups[0];
u8 group;
u16 group_index = 0; /* based on factory calib frequencies */
u8 grp_channel;
@@ -2032,7 +2045,7 @@ static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv,
} else
group_index = 0; /* 2.4 GHz, group 0 */
- IWL_DEBUG_POWER("Chnl %d mapped to grp %d\n", ch_info->channel,
+ IWL_DEBUG_POWER(priv, "Chnl %d mapped to grp %d\n", ch_info->channel,
group_index);
return group_index;
}
@@ -2043,11 +2056,12 @@ static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv,
* Interpolate to get nominal (i.e. at factory calibration temperature) index
* into radio/DSP gain settings table for requested power.
*/
-static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv,
+static int iwl3945_hw_reg_get_matched_power_index(struct iwl_priv *priv,
s8 requested_power,
s32 setting_index, s32 *new_index)
{
const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
s32 index0, index1;
s32 power = 2 * requested_power;
s32 i;
@@ -2056,7 +2070,7 @@ static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv,
s32 res;
s32 denominator;
- chnl_grp = &priv->eeprom.groups[setting_index];
+ chnl_grp = &eeprom->groups[setting_index];
samples = chnl_grp->samples;
for (i = 0; i < 5; i++) {
if (power == samples[i].power) {
@@ -2091,22 +2105,23 @@ static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv,
return 0;
}
-static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv)
+static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
{
u32 i;
s32 rate_index;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
const struct iwl3945_eeprom_txpower_group *group;
- IWL_DEBUG_POWER("Initializing factory calib info from EEPROM\n");
+ IWL_DEBUG_POWER(priv, "Initializing factory calib info from EEPROM\n");
for (i = 0; i < IWL_NUM_TX_CALIB_GROUPS; i++) {
s8 *clip_pwrs; /* table of power levels for each rate */
s8 satur_pwr; /* saturation power for each chnl group */
- group = &priv->eeprom.groups[i];
+ group = &eeprom->groups[i];
/* sanity check on factory saturation power value */
if (group->saturation_power < 40) {
- IWL_WARNING("Error: saturation power is %d, "
+ IWL_WARN(priv, "Error: saturation power is %d, "
"less than minimum expected 40\n",
group->saturation_power);
return;
@@ -2121,7 +2136,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv)
* power peaks, without too much distortion (clipping).
*/
/* we'll fill in this array with h/w max power levels */
- clip_pwrs = (s8 *) priv->clip_groups[i].clip_powers;
+ clip_pwrs = (s8 *) priv->clip39_groups[i].clip_powers;
/* divide factory saturation power by 2 to find -3dB level */
satur_pwr = (s8) (group->saturation_power >> 1);
@@ -2171,10 +2186,11 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv)
*
* This does *not* write values to NIC, just sets up our internal table.
*/
-int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
+int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
{
- struct iwl3945_channel_info *ch_info = NULL;
+ struct iwl_channel_info *ch_info = NULL;
struct iwl3945_channel_power_info *pwr_info;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
int delta_index;
u8 rate_index;
u8 scan_tbl_index;
@@ -2204,15 +2220,15 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
iwl3945_hw_reg_get_ch_grp_index(priv, ch_info);
/* Get this chnlgrp's rate->max/clip-powers table */
- clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
+ clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
/* calculate power index *adjustment* value according to
* diff between current temperature and factory temperature */
delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature,
- priv->eeprom.groups[ch_info->group_index].
+ eeprom->groups[ch_info->group_index].
temperature);
- IWL_DEBUG_POWER("Delta index for channel %d: %d [%d]\n",
+ IWL_DEBUG_POWER(priv, "Delta index for channel %d: %d [%d]\n",
ch_info->channel, delta_index, temperature +
IWL_TEMP_CONVERT);
@@ -2235,7 +2251,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
ch_info->group_index,
&power_idx);
if (rc) {
- IWL_ERROR("Invalid power index\n");
+ IWL_ERR(priv, "Invalid power index\n");
return rc;
}
pwr_info->base_power_index = (u8) power_idx;
@@ -2295,75 +2311,90 @@ int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
return 0;
}
-int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv)
+int iwl3945_hw_rxq_stop(struct iwl_priv *priv)
{
int rc;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
- iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), 0);
- rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS,
- FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
+ iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0);
+ rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS,
+ FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
if (rc < 0)
- IWL_ERROR("Can't stop Rx DMA.\n");
+ IWL_ERR(priv, "Can't stop Rx DMA.\n");
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
-int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
+int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
{
int rc;
unsigned long flags;
int txq_id = txq->q.id;
- struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt;
+ struct iwl3945_shared *shared_data = priv->shared_virt;
shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr);
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
- iwl3945_write_direct32(priv, FH_CBCC_CTRL(txq_id), 0);
- iwl3945_write_direct32(priv, FH_CBCC_BASE(txq_id), 0);
+ iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0);
+ iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0);
- iwl3945_write_direct32(priv, FH_TCSR_CONFIG(txq_id),
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT |
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF |
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |
- ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);
- iwl3945_release_nic_access(priv);
+ iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id),
+ FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT |
+ FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF |
+ FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
+ FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |
+ FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);
+ iwl_release_nic_access(priv);
/* fake read to flush all prev. writes */
- iwl3945_read32(priv, FH_TSSR_CBB_BASE);
+ iwl_read32(priv, FH39_TSSR_CBB_BASE);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
-int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv)
+/*
+ * HCMD utils
+ */
+static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len)
{
- struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt;
+ switch (cmd_id) {
+ case REPLY_RXON:
+ return sizeof(struct iwl3945_rxon_cmd);
+ case POWER_TABLE_CMD:
+ return sizeof(struct iwl3945_powertable_cmd);
+ default:
+ return len;
+ }
+}
- return le32_to_cpu(shared_data->rx_read_ptr[0]);
+static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
+{
+ u16 size = (u16)sizeof(struct iwl3945_addsta_cmd);
+ memcpy(data, cmd, size);
+ return size;
}
/**
* iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
*/
-int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
+int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
{
int rc, i, index, prev_index;
struct iwl3945_rate_scaling_cmd rate_cmd = {
@@ -2384,7 +2415,7 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
switch (priv->band) {
case IEEE80211_BAND_5GHZ:
- IWL_DEBUG_RATE("Select A mode rate scale\n");
+ IWL_DEBUG_RATE(priv, "Select A mode rate scale\n");
/* If one of the following CCK rates is used,
* have it fall back to the 6M OFDM rate */
for (i = IWL_RATE_1M_INDEX_TABLE;
@@ -2402,12 +2433,12 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
break;
case IEEE80211_BAND_2GHZ:
- IWL_DEBUG_RATE("Select B/G mode rate scale\n");
+ IWL_DEBUG_RATE(priv, "Select B/G mode rate scale\n");
/* If an OFDM rate is used, have it fall back to the
* 1M CCK rates */
if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
- iwl3945_is_associated(priv)) {
+ iwl_is_associated(priv)) {
index = IWL_FIRST_CCK_RATE;
for (i = IWL_RATE_6M_INDEX_TABLE;
@@ -2428,47 +2459,51 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
/* Update the rate scaling for control frame Tx */
rate_cmd.table_id = 0;
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
+ rc = iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
&rate_cmd);
if (rc)
return rc;
/* Update the rate scaling for data frame Tx */
rate_cmd.table_id = 1;
- return iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
+ return iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
&rate_cmd);
}
/* Called when initializing driver */
-int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv)
+int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
{
- memset((void *)&priv->hw_setting, 0,
- sizeof(struct iwl3945_driver_hw_info));
+ memset((void *)&priv->hw_params, 0,
+ sizeof(struct iwl_hw_params));
- priv->hw_setting.shared_virt =
+ priv->shared_virt =
pci_alloc_consistent(priv->pci_dev,
sizeof(struct iwl3945_shared),
- &priv->hw_setting.shared_phys);
+ &priv->shared_phys);
- if (!priv->hw_setting.shared_virt) {
- IWL_ERROR("failed to allocate pci memory\n");
+ if (!priv->shared_virt) {
+ IWL_ERR(priv, "failed to allocate pci memory\n");
mutex_unlock(&priv->mutex);
return -ENOMEM;
}
- priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE;
- priv->hw_setting.max_pkt_size = 2342;
- priv->hw_setting.tx_cmd_len = sizeof(struct iwl3945_tx_cmd);
- priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE;
- priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG;
- priv->hw_setting.max_stations = IWL3945_STATION_COUNT;
- priv->hw_setting.bcast_sta_id = IWL3945_BROADCAST_ID;
+ /* Assign number of Usable TX queues */
+ priv->hw_params.max_txq_num = TFD_QUEUE_MAX;
+
+ priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
+ priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K;
+ priv->hw_params.max_pkt_size = 2342;
+ priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
+ priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
+ priv->hw_params.max_stations = IWL3945_STATION_COUNT;
+ priv->hw_params.bcast_sta_id = IWL3945_BROADCAST_ID;
+
+ priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;
- priv->hw_setting.tx_ant_num = 2;
return 0;
}
-unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
+unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl3945_frame *frame, u8 rate)
{
struct iwl3945_tx_beacon_cmd *tx_beacon_cmd;
@@ -2477,7 +2512,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
- tx_beacon_cmd->tx.sta_id = priv->hw_setting.bcast_sta_id;
+ tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
frame_size = iwl3945_fill_beacon_frame(priv,
@@ -2501,37 +2536,262 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size;
}
-void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)
+void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv)
{
priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx;
priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx;
}
-void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv)
+void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv)
{
INIT_DELAYED_WORK(&priv->thermal_periodic,
iwl3945_bg_reg_txpower_periodic);
}
-void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv)
+void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv)
{
cancel_delayed_work(&priv->thermal_periodic);
}
-static struct iwl_3945_cfg iwl3945_bg_cfg = {
+/* check contents of special bootstrap uCode SRAM */
+static int iwl3945_verify_bsm(struct iwl_priv *priv)
+ {
+ __le32 *image = priv->ucode_boot.v_addr;
+ u32 len = priv->ucode_boot.len;
+ u32 reg;
+ u32 val;
+
+ IWL_DEBUG_INFO(priv, "Begin verify bsm\n");
+
+ /* verify BSM SRAM contents */
+ val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG);
+ for (reg = BSM_SRAM_LOWER_BOUND;
+ reg < BSM_SRAM_LOWER_BOUND + len;
+ reg += sizeof(u32), image++) {
+ val = iwl_read_prph(priv, reg);
+ if (val != le32_to_cpu(*image)) {
+ IWL_ERR(priv, "BSM uCode verification failed at "
+ "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
+ BSM_SRAM_LOWER_BOUND,
+ reg - BSM_SRAM_LOWER_BOUND, len,
+ val, le32_to_cpu(*image));
+ return -EIO;
+ }
+ }
+
+ IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n");
+
+ return 0;
+}
+
+
+/******************************************************************************
+ *
+ * EEPROM related functions
+ *
+ ******************************************************************************/
+
+/*
+ * Clear the OWNER_MSK, to establish driver (instead of uCode running on
+ * embedded controller) as EEPROM reader; each read is a series of pulses
+ * to/from the EEPROM chip, not a single event, so even reads could conflict
+ * if they weren't arbitrated by some ownership mechanism. Here, the driver
+ * simply claims ownership, which should be safe when this function is called
+ * (i.e. before loading uCode!).
+ */
+static int iwl3945_eeprom_acquire_semaphore(struct iwl_priv *priv)
+{
+ _iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
+ return 0;
+}
+
+
+static void iwl3945_eeprom_release_semaphore(struct iwl_priv *priv)
+{
+ return;
+}
+
+ /**
+ * iwl3945_load_bsm - Load bootstrap instructions
+ *
+ * BSM operation:
+ *
+ * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
+ * in special SRAM that does not power down during RFKILL. When powering back
+ * up after power-saving sleeps (or during initial uCode load), the BSM loads
+ * the bootstrap program into the on-board processor, and starts it.
+ *
+ * The bootstrap program loads (via DMA) instructions and data for a new
+ * program from host DRAM locations indicated by the host driver in the
+ * BSM_DRAM_* registers. Once the new program is loaded, it starts
+ * automatically.
+ *
+ * When initializing the NIC, the host driver points the BSM to the
+ * "initialize" uCode image. This uCode sets up some internal data, then
+ * notifies host via "initialize alive" that it is complete.
+ *
+ * The host then replaces the BSM_DRAM_* pointer values to point to the
+ * normal runtime uCode instructions and a backup uCode data cache buffer
+ * (filled initially with starting data values for the on-board processor),
+ * then triggers the "initialize" uCode to load and launch the runtime uCode,
+ * which begins normal operation.
+ *
+ * When doing a power-save shutdown, runtime uCode saves data SRAM into
+ * the backup data cache in DRAM before SRAM is powered down.
+ *
+ * When powering back up, the BSM loads the bootstrap program. This reloads
+ * the runtime uCode instructions and the backup data cache into SRAM,
+ * and re-launches the runtime uCode from where it left off.
+ */
+static int iwl3945_load_bsm(struct iwl_priv *priv)
+{
+ __le32 *image = priv->ucode_boot.v_addr;
+ u32 len = priv->ucode_boot.len;
+ dma_addr_t pinst;
+ dma_addr_t pdata;
+ u32 inst_len;
+ u32 data_len;
+ int rc;
+ int i;
+ u32 done;
+ u32 reg_offset;
+
+ IWL_DEBUG_INFO(priv, "Begin load bsm\n");
+
+ /* make sure bootstrap program is no larger than BSM's SRAM size */
+ if (len > IWL39_MAX_BSM_SIZE)
+ return -EINVAL;
+
+ /* Tell bootstrap uCode where to find the "Initialize" uCode
+ * in host DRAM ... host DRAM physical address bits 31:0 for 3945.
+ * NOTE: iwl3945_initialize_alive_start() will replace these values,
+ * after the "initialize" uCode has run, to point to
+ * runtime/protocol instructions and backup data cache. */
+ pinst = priv->ucode_init.p_addr;
+ pdata = priv->ucode_init_data.p_addr;
+ inst_len = priv->ucode_init.len;
+ data_len = priv->ucode_init_data.len;
+
+ rc = iwl_grab_nic_access(priv);
+ if (rc)
+ return rc;
+
+ iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+ iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+ iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
+ iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
+
+ /* Fill BSM memory with bootstrap instructions */
+ for (reg_offset = BSM_SRAM_LOWER_BOUND;
+ reg_offset < BSM_SRAM_LOWER_BOUND + len;
+ reg_offset += sizeof(u32), image++)
+ _iwl_write_prph(priv, reg_offset,
+ le32_to_cpu(*image));
+
+ rc = iwl3945_verify_bsm(priv);
+ if (rc) {
+ iwl_release_nic_access(priv);
+ return rc;
+ }
+
+ /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
+ iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
+ iwl_write_prph(priv, BSM_WR_MEM_DST_REG,
+ IWL39_RTC_INST_LOWER_BOUND);
+ iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
+
+ /* Load bootstrap code into instruction SRAM now,
+ * to prepare to load "initialize" uCode */
+ iwl_write_prph(priv, BSM_WR_CTRL_REG,
+ BSM_WR_CTRL_REG_BIT_START);
+
+ /* Wait for load of bootstrap uCode to finish */
+ for (i = 0; i < 100; i++) {
+ done = iwl_read_prph(priv, BSM_WR_CTRL_REG);
+ if (!(done & BSM_WR_CTRL_REG_BIT_START))
+ break;
+ udelay(10);
+ }
+ if (i < 100)
+ IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i);
+ else {
+ IWL_ERR(priv, "BSM write did not complete!\n");
+ return -EIO;
+ }
+
+ /* Enable future boot loads whenever power management unit triggers it
+ * (e.g. when powering back up after power-save shutdown) */
+ iwl_write_prph(priv, BSM_WR_CTRL_REG,
+ BSM_WR_CTRL_REG_BIT_START_EN);
+
+ iwl_release_nic_access(priv);
+
+ return 0;
+}
+
+static struct iwl_lib_ops iwl3945_lib = {
+ .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
+ .txq_free_tfd = iwl3945_hw_txq_free_tfd,
+ .txq_init = iwl3945_hw_tx_queue_init,
+ .load_ucode = iwl3945_load_bsm,
+ .apm_ops = {
+ .init = iwl3945_apm_init,
+ .reset = iwl3945_apm_reset,
+ .stop = iwl3945_apm_stop,
+ .config = iwl3945_nic_config,
+ .set_pwr_src = iwl3945_set_pwr_src,
+ },
+ .eeprom_ops = {
+ .regulatory_bands = {
+ EEPROM_REGULATORY_BAND_1_CHANNELS,
+ EEPROM_REGULATORY_BAND_2_CHANNELS,
+ EEPROM_REGULATORY_BAND_3_CHANNELS,
+ EEPROM_REGULATORY_BAND_4_CHANNELS,
+ EEPROM_REGULATORY_BAND_5_CHANNELS,
+ EEPROM_REGULATORY_BAND_NO_FAT,
+ EEPROM_REGULATORY_BAND_NO_FAT,
+ },
+ .verify_signature = iwlcore_eeprom_verify_signature,
+ .acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
+ .release_semaphore = iwl3945_eeprom_release_semaphore,
+ .query_addr = iwlcore_eeprom_query_addr,
+ },
+ .send_tx_power = iwl3945_send_tx_power,
+ .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr,
+};
+
+static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
+ .get_hcmd_size = iwl3945_get_hcmd_size,
+ .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
+};
+
+static struct iwl_ops iwl3945_ops = {
+ .lib = &iwl3945_lib,
+ .utils = &iwl3945_hcmd_utils,
+};
+
+static struct iwl_cfg iwl3945_bg_cfg = {
.name = "3945BG",
.fw_name_pre = IWL3945_FW_PRE,
.ucode_api_max = IWL3945_UCODE_API_MAX,
.ucode_api_min = IWL3945_UCODE_API_MIN,
.sku = IWL_SKU_G,
+ .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
+ .ops = &iwl3945_ops,
+ .mod_params = &iwl3945_mod_params
};
-static struct iwl_3945_cfg iwl3945_abg_cfg = {
+static struct iwl_cfg iwl3945_abg_cfg = {
.name = "3945ABG",
.fw_name_pre = IWL3945_FW_PRE,
.ucode_api_max = IWL3945_UCODE_API_MAX,
.ucode_api_min = IWL3945_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G,
+ .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
+ .ops = &iwl3945_ops,
+ .mod_params = &iwl3945_mod_params
};
struct pci_device_id iwl3945_hw_card_ids[] = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 2c0ddc5110c6..ab7aaf6872c7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -43,11 +43,13 @@
/* Hardware specific file defines the PCI IDs table for that hardware module */
extern struct pci_device_id iwl3945_hw_card_ids[];
-#define DRV_NAME "iwl3945"
#include "iwl-csr.h"
#include "iwl-prph.h"
+#include "iwl-fh.h"
#include "iwl-3945-hw.h"
-#include "iwl-3945-debug.h"
+#include "iwl-debug.h"
+#include "iwl-power.h"
+#include "iwl-dev.h"
#include "iwl-3945-led.h"
/* Highest firmware API version supported */
@@ -74,8 +76,7 @@ extern struct pci_device_id iwl3945_hw_card_ids[];
#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127)
/* Module parameters accessible from iwl-*.c */
-extern int iwl3945_param_hwcrypto;
-extern int iwl3945_param_queues_num;
+extern struct iwl_mod_params iwl3945_mod_params;
struct iwl3945_sta_priv {
struct iwl3945_rs_sta *rs_sta;
@@ -95,7 +96,6 @@ enum iwl3945_antenna {
* else RTS for data/management frames where MPDU is larger
* than RTS value.
*/
-#define IWL_RX_BUF_SIZE 3000U
#define DEFAULT_RTS_THRESHOLD 2347U
#define MIN_RTS_THRESHOLD 0U
#define MAX_RTS_THRESHOLD 2347U
@@ -105,136 +105,7 @@ enum iwl3945_antenna {
#define DEFAULT_SHORT_RETRY_LIMIT 7U
#define DEFAULT_LONG_RETRY_LIMIT 4U
-struct iwl3945_rx_mem_buffer {
- dma_addr_t dma_addr;
- struct sk_buff *skb;
- struct list_head list;
-};
-
-/*
- * Generic queue structure
- *
- * Contains common data for Rx and Tx queues
- */
-struct iwl3945_queue {
- int n_bd; /* number of BDs in this queue */
- int write_ptr; /* 1-st empty entry (index) host_w*/
- int read_ptr; /* last used entry (index) host_r*/
- dma_addr_t dma_addr; /* physical addr for BD's */
- int n_window; /* safe queue window */
- u32 id;
- int low_mark; /* low watermark, resume queue if free
- * space more than this */
- int high_mark; /* high watermark, stop queue if free
- * space less than this */
-} __attribute__ ((packed));
-
-int iwl3945_queue_space(const struct iwl3945_queue *q);
-int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i);
-
-#define MAX_NUM_OF_TBS (20)
-
-/* One for each TFD */
-struct iwl3945_tx_info {
- struct sk_buff *skb[MAX_NUM_OF_TBS];
-};
-
-/**
- * struct iwl3945_tx_queue - Tx Queue for DMA
- * @q: generic Rx/Tx queue descriptor
- * @bd: base of circular buffer of TFDs
- * @cmd: array of command/Tx buffers
- * @dma_addr_cmd: physical address of cmd/tx buffer array
- * @txb: array of per-TFD driver data
- * @need_update: indicates need to update read/write index
- *
- * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
- * descriptors) and required locking structures.
- */
-struct iwl3945_tx_queue {
- struct iwl3945_queue q;
- struct iwl3945_tfd_frame *bd;
- struct iwl3945_cmd *cmd;
- dma_addr_t dma_addr_cmd;
- struct iwl3945_tx_info *txb;
- int need_update;
- int active;
-};
-
-#define IWL_NUM_SCAN_RATES (2)
-
-struct iwl3945_channel_tgd_info {
- u8 type;
- s8 max_power;
-};
-
-struct iwl3945_channel_tgh_info {
- s64 last_radar_time;
-};
-
-/* current Tx power values to use, one for each rate for each channel.
- * requested power is limited by:
- * -- regulatory EEPROM limits for this channel
- * -- hardware capabilities (clip-powers)
- * -- spectrum management
- * -- user preference (e.g. iwconfig)
- * when requested power is set, base power index must also be set. */
-struct iwl3945_channel_power_info {
- struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
- s8 power_table_index; /* actual (compenst'd) index into gain table */
- s8 base_power_index; /* gain index for power at factory temp. */
- s8 requested_power; /* power (dBm) requested for this chnl/rate */
-};
-
-/* current scan Tx power values to use, one for each scan rate for each
- * channel. */
-struct iwl3945_scan_power_info {
- struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
- s8 power_table_index; /* actual (compenst'd) index into gain table */
- s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */
-};
-
-/*
- * One for each channel, holds all channel setup data
- * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
- * with one another!
- */
-#define IWL4965_MAX_RATE (33)
-
-struct iwl3945_channel_info {
- struct iwl3945_channel_tgd_info tgd;
- struct iwl3945_channel_tgh_info tgh;
- struct iwl3945_eeprom_channel eeprom; /* EEPROM regulatory limit */
- struct iwl3945_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for
- * FAT channel */
-
- u8 channel; /* channel number */
- u8 flags; /* flags copied from EEPROM */
- s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */
- s8 curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */
- s8 min_power; /* always 0 */
- s8 scan_power; /* (dBm) regul. eeprom, direct scans, any rate */
-
- u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */
- u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */
- enum ieee80211_band band;
-
- /* Radio/DSP gain settings for each "normal" data Tx rate.
- * These include, in addition to RF and DSP gain, a few fields for
- * remembering/modifying gain settings (indexes). */
- struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE];
-
- /* Radio/DSP gain settings for each scan rate, for directed scans. */
- struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
-};
-
-struct iwl3945_clip_group {
- /* maximum power level to prevent clipping for each rate, derived by
- * us from this band's saturation power in EEPROM */
- const s8 clip_powers[IWL_MAX_RATES];
-};
-
-#include "iwl-3945-rs.h"
+#include "iwl-agn-rs.h"
#define IWL_TX_FIFO_AC0 0
#define IWL_TX_FIFO_AC1 1
@@ -247,33 +118,6 @@ struct iwl3945_clip_group {
/* Minimum number of queues. MAX_NUM is defined in hw specific files */
#define IWL_MIN_NUM_QUEUES 4
-/* Power management (not Tx power) structures */
-
-struct iwl3945_power_vec_entry {
- struct iwl3945_powertable_cmd cmd;
- u8 no_dtim;
-};
-#define IWL_POWER_RANGE_0 (0)
-#define IWL_POWER_RANGE_1 (1)
-
-#define IWL_POWER_MODE_CAM 0x00 /* Continuously Aware Mode, always on */
-#define IWL_POWER_INDEX_3 0x03
-#define IWL_POWER_INDEX_5 0x05
-#define IWL_POWER_AC 0x06
-#define IWL_POWER_BATTERY 0x07
-#define IWL_POWER_LIMIT 0x07
-#define IWL_POWER_MASK 0x0F
-#define IWL_POWER_ENABLED 0x10
-#define IWL_POWER_LEVEL(x) ((x) & IWL_POWER_MASK)
-
-struct iwl3945_power_mgr {
- spinlock_t lock;
- struct iwl3945_power_vec_entry pwr_range_0[IWL_POWER_AC];
- struct iwl3945_power_vec_entry pwr_range_1[IWL_POWER_AC];
- u8 active_index;
- u32 dtim_val;
-};
-
#define IEEE80211_DATA_LEN 2304
#define IEEE80211_4ADDR_LEN 30
#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
@@ -289,81 +133,10 @@ struct iwl3945_frame {
struct list_head list;
};
-#define SEQ_TO_QUEUE(x) ((x >> 8) & 0xbf)
-#define QUEUE_TO_SEQ(x) ((x & 0xbf) << 8)
-#define SEQ_TO_INDEX(x) ((u8)(x & 0xff))
-#define INDEX_TO_SEQ(x) ((u8)(x & 0xff))
-#define SEQ_HUGE_FRAME (0x4000)
-#define SEQ_RX_FRAME __constant_cpu_to_le16(0x8000)
#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
-enum {
- /* CMD_SIZE_NORMAL = 0, */
- CMD_SIZE_HUGE = (1 << 0),
- /* CMD_SYNC = 0, */
- CMD_ASYNC = (1 << 1),
- /* CMD_NO_SKB = 0, */
- CMD_WANT_SKB = (1 << 2),
-};
-
-struct iwl3945_cmd;
-struct iwl3945_priv;
-
-struct iwl3945_cmd_meta {
- struct iwl3945_cmd_meta *source;
- union {
- struct sk_buff *skb;
- int (*callback)(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd, struct sk_buff *skb);
- } __attribute__ ((packed)) u;
-
- /* The CMD_SIZE_HUGE flag bit indicates that the command
- * structure is stored at the end of the shared queue memory. */
- u32 flags;
-
-} __attribute__ ((packed));
-
-/**
- * struct iwl3945_cmd
- *
- * For allocation of the command and tx queues, this establishes the overall
- * size of the largest command we send to uCode, except for a scan command
- * (which is relatively huge; space is allocated separately).
- */
-struct iwl3945_cmd {
- struct iwl3945_cmd_meta meta;
- struct iwl3945_cmd_header hdr;
- union {
- struct iwl3945_addsta_cmd addsta;
- struct iwl3945_led_cmd led;
- u32 flags;
- u8 val8;
- u16 val16;
- u32 val32;
- struct iwl3945_bt_cmd bt;
- struct iwl3945_rxon_time_cmd rxon_time;
- struct iwl3945_powertable_cmd powertable;
- struct iwl3945_qosparam_cmd qosparam;
- struct iwl3945_tx_cmd tx;
- struct iwl3945_tx_beacon_cmd tx_beacon;
- struct iwl3945_rxon_assoc_cmd rxon_assoc;
- u8 *indirect;
- u8 payload[360];
- } __attribute__ ((packed)) cmd;
-} __attribute__ ((packed));
-
-struct iwl3945_host_cmd {
- u8 id;
- u16 len;
- struct iwl3945_cmd_meta meta;
- const void *data;
-};
-
-#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \
- sizeof(struct iwl3945_cmd_meta))
-
/*
* RX related structures and functions
*/
@@ -374,33 +147,6 @@ struct iwl3945_host_cmd {
#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
-/**
- * struct iwl3945_rx_queue - Rx queue
- * @processed: Internal index to last handled Rx packet
- * @read: Shared index to newest available Rx buffer
- * @write: Shared index to oldest written Rx packet
- * @free_count: Number of pre-allocated buffers in rx_free
- * @rx_free: list of free SKBs for use
- * @rx_used: List of Rx buffers with no SKB
- * @need_update: flag to indicate we need to update read/write index
- *
- * NOTE: rx_free and rx_used are used as a FIFO for iwl3945_rx_mem_buffers
- */
-struct iwl3945_rx_queue {
- __le32 *bd;
- dma_addr_t dma_addr;
- struct iwl3945_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
- struct iwl3945_rx_mem_buffer *queue[RX_QUEUE_SIZE];
- u32 processed;
- u32 read;
- u32 write;
- u32 free_count;
- struct list_head rx_free;
- struct list_head rx_used;
- int need_update;
- spinlock_t lock;
-};
-
#define IWL_SUPPORTED_RATES_IE_LEN 8
#define SCAN_INTERVAL 100
@@ -430,87 +176,9 @@ struct iwl3945_rx_queue {
#define IWL_INVALID_RATE 0xFF
#define IWL_INVALID_VALUE -1
-struct iwl3945_tid_data {
- u16 seq_number;
-};
-
-struct iwl3945_hw_key {
- enum ieee80211_key_alg alg;
- int keylen;
- u8 key[32];
-};
-
-union iwl3945_ht_rate_supp {
- u16 rates;
- struct {
- u8 siso_rate;
- u8 mimo_rate;
- };
-};
-
-union iwl3945_qos_capabity {
- struct {
- u8 edca_count:4; /* bit 0-3 */
- u8 q_ack:1; /* bit 4 */
- u8 queue_request:1; /* bit 5 */
- u8 txop_request:1; /* bit 6 */
- u8 reserved:1; /* bit 7 */
- } q_AP;
- struct {
- u8 acvo_APSD:1; /* bit 0 */
- u8 acvi_APSD:1; /* bit 1 */
- u8 ac_bk_APSD:1; /* bit 2 */
- u8 ac_be_APSD:1; /* bit 3 */
- u8 q_ack:1; /* bit 4 */
- u8 max_len:2; /* bit 5-6 */
- u8 more_data_ack:1; /* bit 7 */
- } q_STA;
- u8 val;
-};
-
-/* QoS structures */
-struct iwl3945_qos_info {
- int qos_active;
- union iwl3945_qos_capabity qos_cap;
- struct iwl3945_qosparam_cmd def_qos_parm;
-};
-
#define STA_PS_STATUS_WAKE 0
#define STA_PS_STATUS_SLEEP 1
-struct iwl3945_station_entry {
- struct iwl3945_addsta_cmd sta;
- struct iwl3945_tid_data tid[MAX_TID_COUNT];
- union {
- struct {
- u8 rate;
- u8 flags;
- } s;
- u16 rate_n_flags;
- } current_rate;
- u8 used;
- u8 ps_status;
- struct iwl3945_hw_key keyinfo;
-};
-
-/* one for each uCode image (inst/data, boot/init/runtime) */
-struct fw_desc {
- void *v_addr; /* access by driver */
- dma_addr_t p_addr; /* access by card's busmaster DMA */
- u32 len; /* bytes */
-};
-
-/* uCode file layout */
-struct iwl3945_ucode {
- __le32 ver; /* major/minor/API/serial */
- __le32 inst_size; /* bytes of runtime instructions */
- __le32 data_size; /* bytes of runtime data */
- __le32 init_size; /* bytes of initialization instructions */
- __le32 init_data_size; /* bytes of initialization data */
- __le32 boot_size; /* bytes of bootstrap instructions */
- u8 data[0]; /* data in same order as "size" elements */
-};
-
struct iwl3945_ibss_seq {
u8 mac[ETH_ALEN];
u16 seq_num;
@@ -519,34 +187,6 @@ struct iwl3945_ibss_seq {
struct list_head list;
};
-/**
- * struct iwl3945_driver_hw_info
- * @max_txq_num: Max # Tx queues supported
- * @tx_cmd_len: Size of Tx command (but not including frame itself)
- * @tx_ant_num: Number of TX antennas
- * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
- * @rx_buf_size:
- * @max_pkt_size:
- * @max_rxq_log: Log-base-2 of max_rxq_size
- * @max_stations:
- * @bcast_sta_id:
- * @shared_virt: Pointer to driver/uCode shared Tx Byte Counts and Rx status
- * @shared_phys: Physical Pointer to Tx Byte Counts and Rx status
- */
-struct iwl3945_driver_hw_info {
- u16 max_txq_num;
- u16 tx_cmd_len;
- u16 tx_ant_num;
- u16 max_rxq_size;
- u32 rx_buf_size;
- u32 max_pkt_size;
- u16 max_rxq_log;
- u8 max_stations;
- u8 bcast_sta_id;
- void *shared_virt;
- dma_addr_t shared_phys;
-};
-
#define IWL_RX_HDR(x) ((struct iwl3945_rx_frame_hdr *)(\
x->u.rx_frame.stats.payload + \
x->u.rx_frame.stats.phy_count))
@@ -564,40 +204,30 @@ struct iwl3945_driver_hw_info {
*
*****************************************************************************/
struct iwl3945_addsta_cmd;
-extern int iwl3945_send_add_station(struct iwl3945_priv *priv,
+extern int iwl3945_send_add_station(struct iwl_priv *priv,
struct iwl3945_addsta_cmd *sta, u8 flags);
-extern u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *bssid,
+extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid,
int is_ap, u8 flags);
-extern int iwl3945_power_init_handle(struct iwl3945_priv *priv);
-extern int iwl3945_eeprom_init(struct iwl3945_priv *priv);
-extern int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv);
-extern void iwl3945_rx_queue_reset(struct iwl3945_priv *priv,
- struct iwl3945_rx_queue *rxq);
+extern int iwl3945_power_init_handle(struct iwl_priv *priv);
+extern int iwl3945_eeprom_init(struct iwl_priv *priv);
extern int iwl3945_calc_db_from_ratio(int sig_ratio);
extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm);
-extern int iwl3945_tx_queue_init(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq, int count, u32 id);
+extern int iwl3945_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq, int count, u32 id);
extern void iwl3945_rx_replenish(void *data);
-extern void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq);
-extern int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len,
+extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len,
const void *data);
-extern int __must_check iwl3945_send_cmd(struct iwl3945_priv *priv,
- struct iwl3945_host_cmd *cmd);
-extern unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
+extern int __must_check iwl3945_send_cmd(struct iwl_priv *priv,
+ struct iwl_host_cmd *cmd);
+extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,int left);
-extern int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv,
- struct iwl3945_rx_queue *q);
-extern int iwl3945_send_statistics_request(struct iwl3945_priv *priv);
-extern void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb,
- u32 decrypt_res,
- struct ieee80211_rx_status *stats);
-extern const u8 iwl3945_broadcast_addr[ETH_ALEN];
/*
* Currently used by iwl-3945-rs... look at restructuring so that it doesn't
* call this... todo... fix that.
*/
-extern u8 iwl3945_sync_station(struct iwl3945_priv *priv, int sta_id,
+extern u8 iwl3945_sync_station(struct iwl_priv *priv, int sta_id,
u16 tx_rate, u8 flags);
/******************************************************************************
@@ -616,36 +246,37 @@ extern u8 iwl3945_sync_station(struct iwl3945_priv *priv, int sta_id,
* iwl3945_mac_ <-- mac80211 callback
*
****************************************************************************/
-extern void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv);
-extern void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv);
-extern void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv);
-extern int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv);
-extern int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv);
-extern int iwl3945_hw_nic_init(struct iwl3945_priv *priv);
-extern int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv);
-extern void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv);
-extern void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv);
-extern int iwl3945_hw_nic_reset(struct iwl3945_priv *priv);
-extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *tfd,
- dma_addr_t addr, u16 len);
-extern int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq);
-extern int iwl3945_hw_get_temperature(struct iwl3945_priv *priv);
-extern int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq);
-extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
+extern void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv);
+extern void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv);
+extern void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv);
+extern int iwl3945_hw_rxq_stop(struct iwl_priv *priv);
+extern int iwl3945_hw_set_hw_params(struct iwl_priv *priv);
+extern int iwl3945_hw_nic_init(struct iwl_priv *priv);
+extern int iwl3945_hw_nic_stop_master(struct iwl_priv *priv);
+extern void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv);
+extern void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv);
+extern int iwl3945_hw_nic_reset(struct iwl_priv *priv);
+extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len,
+ u8 reset, u8 pad);
+extern void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
+extern int iwl3945_hw_get_temperature(struct iwl_priv *priv);
+extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
+extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl3945_frame *frame, u8 rate);
-extern int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv);
-extern void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
+void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
struct ieee80211_tx_info *info,
struct ieee80211_hdr *hdr,
int sta_id, int tx_id);
-extern int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv);
-extern int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power);
-extern void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb);
-extern void iwl3945_disable_events(struct iwl3945_priv *priv);
-extern int iwl4965_get_temperature(const struct iwl3945_priv *priv);
+extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv);
+extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);
+extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+extern void iwl3945_disable_events(struct iwl_priv *priv);
+extern int iwl4965_get_temperature(const struct iwl_priv *priv);
/**
* iwl3945_hw_find_station - Find station id for a given BSSID
@@ -655,302 +286,26 @@ extern int iwl4965_get_temperature(const struct iwl3945_priv *priv);
* not yet been merged into a single common layer for managing the
* station tables.
*/
-extern u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *bssid);
+extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
-extern int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel);
+extern int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel);
/*
* Forward declare iwl-3945.c functions for iwl-base.c
*/
-extern __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv);
-extern int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv);
-extern void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv);
-extern int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv);
-extern u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id,
+extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv);
+extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv);
+extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv);
+extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv);
+extern u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
u16 tx_rate, u8 flags);
+extern const struct iwl_channel_info *iwl3945_get_channel_info(
+ const struct iwl_priv *priv, enum ieee80211_band band, u16 channel);
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
-
-enum {
- MEASUREMENT_READY = (1 << 0),
- MEASUREMENT_ACTIVE = (1 << 1),
-};
-
-#endif
-
-#ifdef CONFIG_IWL3945_RFKILL
-struct iwl3945_priv;
-
-void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv);
-void iwl3945_rfkill_unregister(struct iwl3945_priv *priv);
-int iwl3945_rfkill_init(struct iwl3945_priv *priv);
-#else
-static inline void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv) {}
-static inline void iwl3945_rfkill_unregister(struct iwl3945_priv *priv) {}
-static inline int iwl3945_rfkill_init(struct iwl3945_priv *priv) { return 0; }
-#endif
-
-#define IWL_MAX_NUM_QUEUES IWL39_MAX_NUM_QUEUES
-
-struct iwl3945_priv {
-
- /* ieee device used by generic ieee processing code */
- struct ieee80211_hw *hw;
- struct ieee80211_channel *ieee_channels;
- struct ieee80211_rate *ieee_rates;
- struct iwl_3945_cfg *cfg; /* device configuration */
-
- /* temporary frame storage list */
- struct list_head free_frames;
- int frames_count;
-
- enum ieee80211_band band;
- int alloc_rxb_skb;
-
- void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb);
-
- struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
-
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
- /* spectrum measurement report caching */
- struct iwl3945_spectrum_notification measure_report;
- u8 measurement_status;
-#endif
- /* ucode beacon time */
- u32 ucode_beacon_time;
-
- /* we allocate array of iwl3945_channel_info for NIC's valid channels.
- * Access via channel # using indirect index array */
- struct iwl3945_channel_info *channel_info; /* channel info array */
- u8 channel_count; /* # of channels */
-
- /* each calibration channel group in the EEPROM has a derived
- * clip setting for each rate. */
- const struct iwl3945_clip_group clip_groups[5];
-
- /* thermal calibration */
- s32 temperature; /* degrees Kelvin */
- s32 last_temperature;
-
- /* Scan related variables */
- unsigned long last_scan_jiffies;
- unsigned long next_scan_jiffies;
- unsigned long scan_start;
- unsigned long scan_pass_start;
- unsigned long scan_start_tsf;
- int scan_bands;
- int one_direct_scan;
- u8 direct_ssid_len;
- u8 direct_ssid[IW_ESSID_MAX_SIZE];
- struct iwl3945_scan_cmd *scan;
-
- /* spinlock */
- spinlock_t lock; /* protect general shared data */
- spinlock_t hcmd_lock; /* protect hcmd */
- struct mutex mutex;
-
- /* basic pci-network driver stuff */
- struct pci_dev *pci_dev;
-
- /* pci hardware address support */
- void __iomem *hw_base;
-
- /* uCode images, save to reload in case of failure */
- u32 ucode_ver; /* ucode version, copy of
- iwl3945_ucode.ver */
- struct fw_desc ucode_code; /* runtime inst */
- struct fw_desc ucode_data; /* runtime data original */
- struct fw_desc ucode_data_backup; /* runtime data save/restore */
- struct fw_desc ucode_init; /* initialization inst */
- struct fw_desc ucode_init_data; /* initialization data */
- struct fw_desc ucode_boot; /* bootstrap inst */
-
-
- struct iwl3945_rxon_time_cmd rxon_timing;
-
- /* We declare this const so it can only be
- * changed via explicit cast within the
- * routines that actually update the physical
- * hardware */
- const struct iwl3945_rxon_cmd active_rxon;
- struct iwl3945_rxon_cmd staging_rxon;
-
- int error_recovering;
- struct iwl3945_rxon_cmd recovery_rxon;
-
- /* 1st responses from initialize and runtime uCode images.
- * 4965's initialize alive response contains some calibration data. */
- struct iwl3945_init_alive_resp card_alive_init;
- struct iwl3945_alive_resp card_alive;
-
-#ifdef CONFIG_IWL3945_RFKILL
- struct rfkill *rfkill;
-#endif
-
-#ifdef CONFIG_IWL3945_LEDS
- struct iwl3945_led led[IWL_LED_TRG_MAX];
- unsigned long last_blink_time;
- u8 last_blink_rate;
- u8 allow_blinking;
- unsigned int rxtxpackets;
- u64 led_tpt;
-#endif
-
-
- u16 active_rate;
- u16 active_rate_basic;
-
- u32 sta_supp_rates;
-
- u8 call_post_assoc_from_beacon;
- /* Rate scaling data */
- s8 data_retry_limit;
- u8 retry_rate;
-
- wait_queue_head_t wait_command_queue;
-
- int activity_timer_active;
-
- /* Rx and Tx DMA processing queues */
- struct iwl3945_rx_queue rxq;
- struct iwl3945_tx_queue txq[IWL_MAX_NUM_QUEUES];
-
- unsigned long status;
-
- int last_rx_rssi; /* From Rx packet statisitics */
- int last_rx_noise; /* From beacon statistics */
-
- struct iwl3945_power_mgr power_data;
-
- struct iwl3945_notif_statistics statistics;
- unsigned long last_statistics_time;
-
- /* context information */
- u16 rates_mask;
-
- u32 power_mode;
- u32 antenna;
- u8 bssid[ETH_ALEN];
- u16 rts_threshold;
- u8 mac_addr[ETH_ALEN];
-
- /*station table variables */
- spinlock_t sta_lock;
- int num_stations;
- struct iwl3945_station_entry stations[IWL_STATION_COUNT];
-
- /* Indication if ieee80211_ops->open has been called */
- u8 is_open;
+extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
- u8 mac80211_registered;
-
- /* Rx'd packet timing information */
- u32 last_beacon_time;
- u64 last_tsf;
-
- /* eeprom */
- struct iwl3945_eeprom eeprom;
-
- enum nl80211_iftype iw_mode;
-
- struct sk_buff *ibss_beacon;
-
- /* Last Rx'd beacon timestamp */
- u32 timestamp0;
- u32 timestamp1;
- u16 beacon_int;
- struct iwl3945_driver_hw_info hw_setting;
- struct ieee80211_vif *vif;
-
- /* Current association information needed to configure the
- * hardware */
- u16 assoc_id;
- u16 assoc_capability;
- u8 ps_mode;
-
- struct iwl3945_qos_info qos_data;
-
- struct workqueue_struct *workqueue;
-
- struct work_struct up;
- struct work_struct restart;
- struct work_struct calibrated_work;
- struct work_struct scan_completed;
- struct work_struct rx_replenish;
- struct work_struct rf_kill;
- struct work_struct abort_scan;
- struct work_struct update_link_led;
- struct work_struct auth_work;
- struct work_struct report_work;
- struct work_struct request_scan;
- struct work_struct beacon_update;
-
- struct tasklet_struct irq_tasklet;
-
- struct delayed_work init_alive_start;
- struct delayed_work alive_start;
- struct delayed_work activity_timer;
- struct delayed_work thermal_periodic;
- struct delayed_work gather_stats;
- struct delayed_work scan_check;
-
-#define IWL_DEFAULT_TX_POWER 0x0F
- s8 user_txpower_limit;
- s8 max_channel_txpower_limit;
-
-
-#ifdef CONFIG_IWL3945_DEBUG
- /* debugging info */
- u32 framecnt_to_us;
- atomic_t restrict_refcnt;
-#endif
-}; /*iwl3945_priv */
-
-static inline int iwl3945_is_associated(struct iwl3945_priv *priv)
-{
- return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
-}
-
-static inline int is_channel_valid(const struct iwl3945_channel_info *ch_info)
-{
- if (ch_info == NULL)
- return 0;
- return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0;
-}
-
-static inline int is_channel_radar(const struct iwl3945_channel_info *ch_info)
-{
- return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0;
-}
-
-static inline u8 is_channel_a_band(const struct iwl3945_channel_info *ch_info)
-{
- return ch_info->band == IEEE80211_BAND_5GHZ;
-}
-
-static inline u8 is_channel_bg_band(const struct iwl3945_channel_info *ch_info)
-{
- return ch_info->band == IEEE80211_BAND_2GHZ;
-}
-
-static inline int is_channel_passive(const struct iwl3945_channel_info *ch)
-{
- return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0;
-}
-
-static inline int is_channel_ibss(const struct iwl3945_channel_info *ch)
-{
- return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
-}
-
-extern const struct iwl3945_channel_info *iwl3945_get_channel_info(
- const struct iwl3945_priv *priv, enum ieee80211_band band, u16 channel);
-
-extern int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate);
-
-/* Requires full declaration of iwl3945_priv before including */
-#include "iwl-3945-io.h"
+/* Requires full declaration of iwl_priv before including */
+#include "iwl-io.h"
#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index 6649f7b55650..a71a489096ff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -89,64 +89,43 @@
#define LONG_SLOT_TIME 20
/* RSSI to dBm */
-#define IWL_RSSI_OFFSET 44
-
+#define IWL49_RSSI_OFFSET 44
/* PCI registers */
#define PCI_CFG_RETRY_TIMEOUT 0x041
-#define PCI_CFG_POWER_SOURCE 0x0C8
-#define PCI_REG_WUM8 0x0E8
-#define PCI_CFG_LINK_CTRL 0x0F0
/* PCI register values */
#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01
#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02
-#define PCI_CFG_CMD_REG_INT_DIS_MSK 0x04
-#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000)
-
#define IWL_NUM_SCAN_RATES (2)
#define IWL_DEFAULT_TX_RETRY 15
-#define RX_QUEUE_SIZE 256
-#define RX_QUEUE_MASK 255
-#define RX_QUEUE_SIZE_LOG 8
-
-#define TFD_TX_CMD_SLOTS 256
-#define TFD_CMD_SLOTS 32
-
-/*
- * RX related structures and functions
- */
-#define RX_FREE_BUFFERS 64
-#define RX_LOW_WATERMARK 8
-
-/* Size of one Rx buffer in host DRAM */
-#define IWL_RX_BUF_SIZE_4K (4 * 1024)
-#define IWL_RX_BUF_SIZE_8K (8 * 1024)
/* Sizes and addresses for instruction and data memory (SRAM) in
* 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */
-#define RTC_INST_LOWER_BOUND (0x000000)
+#define IWL49_RTC_INST_LOWER_BOUND (0x000000)
#define IWL49_RTC_INST_UPPER_BOUND (0x018000)
-#define RTC_DATA_LOWER_BOUND (0x800000)
+#define IWL49_RTC_DATA_LOWER_BOUND (0x800000)
#define IWL49_RTC_DATA_UPPER_BOUND (0x80A000)
-#define IWL49_RTC_INST_SIZE (IWL49_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
-#define IWL49_RTC_DATA_SIZE (IWL49_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+#define IWL49_RTC_INST_SIZE (IWL49_RTC_INST_UPPER_BOUND - \
+ IWL49_RTC_INST_LOWER_BOUND)
+#define IWL49_RTC_DATA_SIZE (IWL49_RTC_DATA_UPPER_BOUND - \
+ IWL49_RTC_DATA_LOWER_BOUND)
-#define IWL_MAX_INST_SIZE IWL49_RTC_INST_SIZE
-#define IWL_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE
+#define IWL49_MAX_INST_SIZE IWL49_RTC_INST_SIZE
+#define IWL49_MAX_DATA_SIZE IWL49_RTC_DATA_SIZE
/* Size of uCode instruction memory in bootstrap state machine */
-#define IWL_MAX_BSM_SIZE BSM_SRAM_SIZE
+#define IWL49_MAX_BSM_SIZE BSM_SRAM_SIZE
static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
{
- return (addr >= RTC_DATA_LOWER_BOUND) &&
+ return (addr >= IWL49_RTC_DATA_LOWER_BOUND) &&
(addr < IWL49_RTC_DATA_UPPER_BOUND);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 5a72bc0377de..847a6220c5e6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -76,7 +76,7 @@ static int iwl4965_verify_bsm(struct iwl_priv *priv)
u32 reg;
u32 val;
- IWL_DEBUG_INFO("Begin verify bsm\n");
+ IWL_DEBUG_INFO(priv, "Begin verify bsm\n");
/* verify BSM SRAM contents */
val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG);
@@ -85,7 +85,7 @@ static int iwl4965_verify_bsm(struct iwl_priv *priv)
reg += sizeof(u32), image++) {
val = iwl_read_prph(priv, reg);
if (val != le32_to_cpu(*image)) {
- IWL_ERROR("BSM uCode verification failed at "
+ IWL_ERR(priv, "BSM uCode verification failed at "
"addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
BSM_SRAM_LOWER_BOUND,
reg - BSM_SRAM_LOWER_BOUND, len,
@@ -94,7 +94,7 @@ static int iwl4965_verify_bsm(struct iwl_priv *priv)
}
}
- IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n");
+ IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n");
return 0;
}
@@ -144,12 +144,12 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
u32 reg_offset;
int ret;
- IWL_DEBUG_INFO("Begin load bsm\n");
+ IWL_DEBUG_INFO(priv, "Begin load bsm\n");
priv->ucode_type = UCODE_RT;
/* make sure bootstrap program is no larger than BSM's SRAM size */
- if (len > IWL_MAX_BSM_SIZE)
+ if (len > IWL49_MAX_BSM_SIZE)
return -EINVAL;
/* Tell bootstrap uCode where to find the "Initialize" uCode
@@ -186,7 +186,7 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
/* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
- iwl_write_prph(priv, BSM_WR_MEM_DST_REG, RTC_INST_LOWER_BOUND);
+ iwl_write_prph(priv, BSM_WR_MEM_DST_REG, IWL49_RTC_INST_LOWER_BOUND);
iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
/* Load bootstrap code into instruction SRAM now,
@@ -201,9 +201,9 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
udelay(10);
}
if (i < 100)
- IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i);
+ IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i);
else {
- IWL_ERROR("BSM write did not complete!\n");
+ IWL_ERR(priv, "BSM write did not complete!\n");
return -EIO;
}
@@ -257,7 +257,7 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("Runtime uCode pointers are set.\n");
+ IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n");
return ret;
}
@@ -279,7 +279,7 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv)
if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
/* We had an error bringing up the hardware, so take it
* all the way back down so we can try again */
- IWL_DEBUG_INFO("Initialize Alive failed.\n");
+ IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
goto restart;
}
@@ -289,7 +289,7 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv)
if (iwl_verify_ucode(priv)) {
/* Runtime instruction load was bad;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
+ IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
goto restart;
}
@@ -299,11 +299,11 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv)
/* Send pointers to protocol/runtime uCode image ... init code will
* load and launch runtime uCode, which will send us another "Alive"
* notification. */
- IWL_DEBUG_INFO("Initialization Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
if (iwl4965_set_ucode_ptrs(priv)) {
/* Runtime instruction load won't happen;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n");
+ IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n");
goto restart;
}
return;
@@ -354,7 +354,7 @@ static int iwl4965_apm_init(struct iwl_priv *priv)
ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
if (ret < 0) {
- IWL_DEBUG_INFO("Failed to init the card\n");
+ IWL_DEBUG_INFO(priv, "Failed to init the card\n");
goto out;
}
@@ -381,27 +381,20 @@ out:
static void iwl4965_nic_config(struct iwl_priv *priv)
{
unsigned long flags;
- u32 val;
u16 radio_cfg;
- u16 link;
+ u16 lctl;
spin_lock_irqsave(&priv->lock, flags);
- if ((priv->rev_id & 0x80) == 0x80 && (priv->rev_id & 0x7f) < 8) {
- pci_read_config_dword(priv->pci_dev, PCI_REG_WUM8, &val);
- /* Enable No Snoop field */
- pci_write_config_dword(priv->pci_dev, PCI_REG_WUM8,
- val & ~(1 << 11));
- }
-
- pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &link);
+ lctl = iwl_pcie_link_ctl(priv);
- /* L1 is enabled by BIOS */
- if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
- /* disable L0S disabled L1A enabled */
+ /* HW bug W/A - negligible power consumption */
+ /* L1-ASPM is enabled by BIOS */
+ if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
+ /* L1-ASPM enabled: disable L0S */
iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
else
- /* L0S enabled L1A disabled */
+ /* L1-ASPM disabled: enable L0S */
iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
@@ -437,7 +430,7 @@ static int iwl4965_apm_stop_master(struct iwl_priv *priv)
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("stop master\n");
+ IWL_DEBUG_INFO(priv, "stop master\n");
return 0;
}
@@ -523,9 +516,10 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
cmd.diff_gain_c = 0;
if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
sizeof(cmd), &cmd))
- IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
+ IWL_ERR(priv,
+ "Could not send REPLY_PHY_CALIBRATION_CMD\n");
data->state = IWL_CHAIN_NOISE_ACCUMULATE;
- IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
+ IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
}
}
@@ -557,7 +551,7 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
data->delta_gain_code[i] = 0;
}
}
- IWL_DEBUG_CALIB("delta_gain_codes: a %d b %d c %d\n",
+ IWL_DEBUG_CALIB(priv, "delta_gain_codes: a %d b %d c %d\n",
data->delta_gain_code[0],
data->delta_gain_code[1],
data->delta_gain_code[2]);
@@ -575,7 +569,7 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
sizeof(cmd), &cmd);
if (ret)
- IWL_DEBUG_CALIB("fail sending cmd "
+ IWL_DEBUG_CALIB(priv, "fail sending cmd "
"REPLY_PHY_CALIBRATION_CMD \n");
/* TODO we might want recalculate
@@ -668,7 +662,7 @@ static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
txq->sched_retry = scd_retry;
- IWL_DEBUG_INFO("%s %s Queue %d on AC %d\n",
+ IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n",
active ? "Activate" : "Deactivate",
scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
}
@@ -804,8 +798,9 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) ||
(priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
- IWL_ERROR("invalid queues_num, should be between %d and %d\n",
- IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES);
+ IWL_ERR(priv,
+ "invalid queues_num, should be between %d and %d\n",
+ IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES);
return -EINVAL;
}
@@ -813,6 +808,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size =
IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
+ priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWL4965_STATION_COUNT;
priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
@@ -820,6 +816,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
priv->hw_params.fat_channel = BIT(IEEE80211_BAND_5GHZ);
+ priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
+
priv->hw_params.tx_chains_num = 2;
priv->hw_params.rx_chains_num = 2;
priv->hw_params.valid_tx_ant = ANT_A | ANT_B;
@@ -902,7 +900,6 @@ static s32 iwl4965_get_tx_atten_grp(u16 channel)
channel <= CALIB_IWL_TX_ATTEN_GR4_LCH)
return CALIB_CH_GROUP_4;
- IWL_ERROR("Can't find txatten group for channel %d.\n", channel);
return -1;
}
@@ -956,7 +953,7 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
s = iwl4965_get_sub_band(priv, channel);
if (s >= EEPROM_TX_POWER_BANDS) {
- IWL_ERROR("Tx Power can not find channel %d\n", channel);
+ IWL_ERR(priv, "Tx Power can not find channel %d\n", channel);
return -1;
}
@@ -964,7 +961,7 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
ch_i2 = priv->calib_info->band_info[s].ch2.ch_num;
chan_info->ch_num = (u8) channel;
- IWL_DEBUG_TXPOWER("channel %d subband %d factory cal ch %d & %d\n",
+ IWL_DEBUG_TXPOWER(priv, "channel %d subband %d factory cal ch %d & %d\n",
channel, s, ch_i1, ch_i2);
for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) {
@@ -994,19 +991,19 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
m1->pa_det, ch_i2,
m2->pa_det);
- IWL_DEBUG_TXPOWER
- ("chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, m,
- m1->actual_pow, m2->actual_pow, omeas->actual_pow);
- IWL_DEBUG_TXPOWER
- ("chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, m,
- m1->gain_idx, m2->gain_idx, omeas->gain_idx);
- IWL_DEBUG_TXPOWER
- ("chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, m,
- m1->pa_det, m2->pa_det, omeas->pa_det);
- IWL_DEBUG_TXPOWER
- ("chain %d meas %d T1=%d T2=%d T=%d\n", c, m,
- m1->temperature, m2->temperature,
- omeas->temperature);
+ IWL_DEBUG_TXPOWER(priv,
+ "chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, m,
+ m1->actual_pow, m2->actual_pow, omeas->actual_pow);
+ IWL_DEBUG_TXPOWER(priv,
+ "chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, m,
+ m1->gain_idx, m2->gain_idx, omeas->gain_idx);
+ IWL_DEBUG_TXPOWER(priv,
+ "chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, m,
+ m1->pa_det, m2->pa_det, omeas->pa_det);
+ IWL_DEBUG_TXPOWER(priv,
+ "chain %d meas %d T1=%d T2=%d T=%d\n", c, m,
+ m1->temperature, m2->temperature,
+ omeas->temperature);
}
}
@@ -1303,12 +1300,12 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
s32 factory_actual_pwr[2];
s32 power_index;
- /* user_txpower_limit is in dBm, convert to half-dBm (half-dB units
+ /* tx_power_user_lmt is in dBm, convert to half-dBm (half-dB units
* are used for indexing into txpower table) */
user_target_power = 2 * priv->tx_power_user_lmt;
/* Get current (RXON) channel, band, width */
- IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band,
+ IWL_DEBUG_TXPOWER(priv, "chan %d band %d is_fat %d\n", channel, band,
is_fat);
ch_info = iwl_get_channel_info(priv, priv->band, channel);
@@ -1319,10 +1316,13 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
/* get txatten group, used to select 1) thermal txpower adjustment
* and 2) mimo txpower balance between Tx chains. */
txatten_grp = iwl4965_get_tx_atten_grp(channel);
- if (txatten_grp < 0)
+ if (txatten_grp < 0) {
+ IWL_ERR(priv, "Can't find txatten group for channel %d.\n",
+ channel);
return -EINVAL;
+ }
- IWL_DEBUG_TXPOWER("channel %d belongs to txatten group %d\n",
+ IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n",
channel, txatten_grp);
if (is_fat) {
@@ -1372,7 +1372,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
voltage_compensation =
iwl4965_get_voltage_compensation(voltage, init_voltage);
- IWL_DEBUG_TXPOWER("curr volt %d eeprom volt %d volt comp %d\n",
+ IWL_DEBUG_TXPOWER(priv, "curr volt %d eeprom volt %d volt comp %d\n",
init_voltage,
voltage, voltage_compensation);
@@ -1403,13 +1403,13 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
factory_gain_index[c] = measurement->gain_idx;
factory_actual_pwr[c] = measurement->actual_pow;
- IWL_DEBUG_TXPOWER("chain = %d\n", c);
- IWL_DEBUG_TXPOWER("fctry tmp %d, "
+ IWL_DEBUG_TXPOWER(priv, "chain = %d\n", c);
+ IWL_DEBUG_TXPOWER(priv, "fctry tmp %d, "
"curr tmp %d, comp %d steps\n",
factory_temp, current_temp,
temperature_comp[c]);
- IWL_DEBUG_TXPOWER("fctry idx %d, fctry pwr %d\n",
+ IWL_DEBUG_TXPOWER(priv, "fctry idx %d, fctry pwr %d\n",
factory_gain_index[c],
factory_actual_pwr[c]);
}
@@ -1442,7 +1442,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
if (target_power > power_limit)
target_power = power_limit;
- IWL_DEBUG_TXPOWER("rate %d sat %d reg %d usr %d tgt %d\n",
+ IWL_DEBUG_TXPOWER(priv, "rate %d sat %d reg %d usr %d tgt %d\n",
i, saturation_power - back_off_table[i],
current_regulatory, user_target_power,
target_power);
@@ -1466,7 +1466,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
voltage_compensation +
atten_value);
-/* IWL_DEBUG_TXPOWER("calculated txpower index %d\n",
+/* IWL_DEBUG_TXPOWER(priv, "calculated txpower index %d\n",
power_index); */
if (power_index < get_min_power_index(i, band))
@@ -1483,12 +1483,12 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
/* stay within the table! */
if (power_index > 107) {
- IWL_WARNING("txpower index %d > 107\n",
+ IWL_WARN(priv, "txpower index %d > 107\n",
power_index);
power_index = 107;
}
if (power_index < 0) {
- IWL_WARNING("txpower index %d < 0\n",
+ IWL_WARN(priv, "txpower index %d < 0\n",
power_index);
power_index = 0;
}
@@ -1499,7 +1499,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
tx_power.s.dsp_predis_atten[c] =
gain_table[band][power_index].dsp;
- IWL_DEBUG_TXPOWER("chain %d mimo %d index %d "
+ IWL_DEBUG_TXPOWER(priv, "chain %d mimo %d index %d "
"gain 0x%02x dsp %d\n",
c, atten_value, power_index,
tx_power.s.radio_tx_gain[c],
@@ -1531,7 +1531,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
/* If this gets hit a lot, switch it to a BUG() and catch
* the stack trace to find out who is calling this during
* a scan. */
- IWL_WARNING("TX Power requested while scanning!\n");
+ IWL_WARN(priv, "TX Power requested while scanning!\n");
return -EAGAIN;
}
@@ -1574,7 +1574,7 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
rxon2->ofdm_ht_dual_stream_basic_rates) &&
(rxon1->rx_chain == rxon2->rx_chain) &&
(rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
- IWL_DEBUG_INFO("Using current RXON_ASSOC. Not resending.\n");
+ IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
return 0;
}
@@ -1631,7 +1631,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_fat,
ctrl_chan_high, &cmd.tx_power);
if (rc) {
- IWL_DEBUG_11H("error:%d fill txpower_tbl\n", rc);
+ IWL_DEBUG_11H(priv, "error:%d fill txpower_tbl\n", rc);
return rc;
}
@@ -1696,13 +1696,13 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
if (test_bit(STATUS_TEMPERATURE, &priv->status) &&
(priv->statistics.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK)) {
- IWL_DEBUG_TEMP("Running FAT temperature calibration\n");
+ IWL_DEBUG_TEMP(priv, "Running FAT temperature calibration\n");
R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]);
R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]);
R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[1]);
R4 = le32_to_cpu(priv->card_alive_init.therm_r4[1]);
} else {
- IWL_DEBUG_TEMP("Running temperature calibration\n");
+ IWL_DEBUG_TEMP(priv, "Running temperature calibration\n");
R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[0]);
R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[0]);
R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[0]);
@@ -1722,10 +1722,10 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
vt = sign_extend(
le32_to_cpu(priv->statistics.general.temperature), 23);
- IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
+ IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
if (R3 == R1) {
- IWL_ERROR("Calibration conflict R1 == R3\n");
+ IWL_ERR(priv, "Calibration conflict R1 == R3\n");
return -1;
}
@@ -1735,7 +1735,7 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
temperature /= (R3 - R1);
temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET;
- IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n",
+ IWL_DEBUG_TEMP(priv, "Calibrated temperature: %dK, %dC\n",
temperature, KELVIN_TO_CELSIUS(temperature));
return temperature;
@@ -1758,7 +1758,7 @@ static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv)
int temp_diff;
if (!test_bit(STATUS_STATISTICS, &priv->status)) {
- IWL_DEBUG_TEMP("Temperature not updated -- no statistics.\n");
+ IWL_DEBUG_TEMP(priv, "Temperature not updated -- no statistics.\n");
return 0;
}
@@ -1766,19 +1766,19 @@ static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv)
/* get absolute value */
if (temp_diff < 0) {
- IWL_DEBUG_POWER("Getting cooler, delta %d, \n", temp_diff);
+ IWL_DEBUG_POWER(priv, "Getting cooler, delta %d, \n", temp_diff);
temp_diff = -temp_diff;
} else if (temp_diff == 0)
- IWL_DEBUG_POWER("Same temp, \n");
+ IWL_DEBUG_POWER(priv, "Same temp, \n");
else
- IWL_DEBUG_POWER("Getting warmer, delta %d, \n", temp_diff);
+ IWL_DEBUG_POWER(priv, "Getting warmer, delta %d, \n", temp_diff);
if (temp_diff < IWL_TEMPERATURE_THRESHOLD) {
- IWL_DEBUG_POWER("Thermal txpower calib not needed\n");
+ IWL_DEBUG_POWER(priv, "Thermal txpower calib not needed\n");
return 0;
}
- IWL_DEBUG_POWER("Thermal txpower calib needed\n");
+ IWL_DEBUG_POWER(priv, "Thermal txpower calib needed\n");
return 1;
}
@@ -1793,12 +1793,12 @@ static void iwl4965_temperature_calib(struct iwl_priv *priv)
if (priv->temperature != temp) {
if (priv->temperature)
- IWL_DEBUG_TEMP("Temperature changed "
+ IWL_DEBUG_TEMP(priv, "Temperature changed "
"from %dC to %dC\n",
KELVIN_TO_CELSIUS(priv->temperature),
KELVIN_TO_CELSIUS(temp));
else
- IWL_DEBUG_TEMP("Temperature "
+ IWL_DEBUG_TEMP(priv, "Temperature "
"initialized to %dC\n",
KELVIN_TO_CELSIUS(temp));
}
@@ -1837,7 +1837,8 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
- IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ IWL_WARN(priv,
+ "queue number out of range: %d, must be %d to %d\n",
txq_id, IWL49_FIRST_AMPDU_QUEUE,
IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
return -EINVAL;
@@ -1908,7 +1909,8 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
- IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ IWL_WARN(priv,
+ "queue number out of range: %d, must be %d to %d\n",
txq_id, IWL49_FIRST_AMPDU_QUEUE,
IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
return -EINVAL;
@@ -1986,8 +1988,8 @@ static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
- addsta->reserved1 = __constant_cpu_to_le16(0);
- addsta->reserved2 = __constant_cpu_to_le32(0);
+ addsta->reserved1 = cpu_to_le16(0);
+ addsta->reserved2 = cpu_to_le32(0);
return (u16)sizeof(struct iwl4965_addsta_cmd);
}
@@ -2013,7 +2015,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
int i, sh, idx;
u16 seq;
if (agg->wait_for_ba)
- IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
+ IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n");
agg->frame_count = tx_resp->frame_count;
agg->start_idx = start_idx;
@@ -2027,7 +2029,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
idx = start_idx;
/* FIXME: code repetition */
- IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
agg->frame_count, agg->start_idx, idx);
info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
@@ -2038,9 +2040,9 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
/* FIXME: code repetition end */
- IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
status & 0xff, tx_resp->failure_frame);
- IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
+ IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags);
agg->wait_for_ba = 0;
} else {
@@ -2060,21 +2062,21 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
AGG_TX_STATE_ABORT_MSK))
continue;
- IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n",
agg->frame_count, txq_id, idx);
hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
sc = le16_to_cpu(hdr->seq_ctrl);
if (idx != (SEQ_TO_SN(sc) & 0xff)) {
- IWL_ERROR("BUG_ON idx doesn't match seq control"
- " idx=%d, seq_idx=%d, seq=%d\n",
- idx, SEQ_TO_SN(sc),
- hdr->seq_ctrl);
+ IWL_ERR(priv,
+ "BUG_ON idx doesn't match seq control"
+ " idx=%d, seq_idx=%d, seq=%d\n",
+ idx, SEQ_TO_SN(sc), hdr->seq_ctrl);
return -1;
}
- IWL_DEBUG_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n",
i, idx, SEQ_TO_SN(sc));
sh = idx - start;
@@ -2092,13 +2094,13 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
sh = 0;
}
bitmap |= 1ULL << sh;
- IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
+ IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n",
start, (unsigned long long)bitmap);
}
agg->bitmap = bitmap;
agg->start_idx = start;
- IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
+ IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n",
agg->frame_count, agg->start_idx,
(unsigned long long)agg->bitmap);
@@ -2129,7 +2131,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
u8 *qc = NULL;
if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+ IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
"is out of range [0-%d] %d %d\n", txq_id,
index, txq->q.n_bd, txq->q.write_ptr,
txq->q.read_ptr);
@@ -2147,7 +2149,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
sta_id = iwl_get_ra_sta_id(priv, hdr);
if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
- IWL_ERROR("Station not known\n");
+ IWL_ERR(priv, "Station not known\n");
return;
}
@@ -2167,7 +2169,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
if (txq->q.read_ptr != (scd_ssn & 0xff)) {
index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
- IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
+ IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
"%d index %d\n", scd_ssn , index);
freed = iwl_tx_queue_reclaim(priv, txq_id, index);
priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
@@ -2176,10 +2178,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
(iwl_queue_space(&txq->q) > txq->q.low_mark) &&
(agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
if (agg->state == IWL_AGG_OFF)
- ieee80211_wake_queue(priv->hw, txq_id);
+ iwl_wake_queue(priv, txq_id);
else
- ieee80211_wake_queue(priv->hw,
- txq->swq_id);
+ iwl_wake_queue(priv, txq->swq_id);
}
}
} else {
@@ -2190,7 +2191,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
le32_to_cpu(tx_resp->rate_n_flags),
info);
- IWL_DEBUG_TX_REPLY("TXQ %d status %s (0x%08x) "
+ IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) "
"rate_n_flags 0x%x retries %d\n",
txq_id,
iwl_get_tx_fail_reason(status), status,
@@ -2203,14 +2204,14 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark))
- ieee80211_wake_queue(priv->hw, txq_id);
+ iwl_wake_queue(priv, txq_id);
}
if (qc && likely(sta_id != IWL_INVALID_STATION))
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
- IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
+ IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
}
static int iwl4965_calc_rssi(struct iwl_priv *priv,
@@ -2238,13 +2239,13 @@ static int iwl4965_calc_rssi(struct iwl_priv *priv,
if (valid_antennae & (1 << i))
max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
- IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
+ IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
max_rssi, agc);
/* dBm = max_rssi dB - agc dB - constant.
* Higher AGC (higher radio gain) means lower signal. */
- return max_rssi - agc - IWL_RSSI_OFFSET;
+ return max_rssi - agc - IWL49_RSSI_OFFSET;
}
@@ -2287,6 +2288,9 @@ static struct iwl_lib_ops iwl4965_lib = {
.txq_set_sched = iwl4965_txq_set_sched,
.txq_agg_enable = iwl4965_txq_agg_enable,
.txq_agg_disable = iwl4965_txq_agg_disable,
+ .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
+ .txq_free_tfd = iwl_hw_txq_free_tfd,
+ .txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwl4965_rx_handler_setup,
.setup_deferred_work = iwl4965_setup_deferred_work,
.cancel_deferred_work = iwl4965_cancel_deferred_work,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 82c3859ce0f8..15cac70e36e2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -68,10 +68,16 @@
#ifndef __iwl_5000_hw_h__
#define __iwl_5000_hw_h__
+#define IWL50_RTC_INST_LOWER_BOUND (0x000000)
#define IWL50_RTC_INST_UPPER_BOUND (0x020000)
+
+#define IWL50_RTC_DATA_LOWER_BOUND (0x800000)
#define IWL50_RTC_DATA_UPPER_BOUND (0x80C000)
-#define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
-#define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
+
+#define IWL50_RTC_INST_SIZE (IWL50_RTC_INST_UPPER_BOUND - \
+ IWL50_RTC_INST_LOWER_BOUND)
+#define IWL50_RTC_DATA_SIZE (IWL50_RTC_DATA_UPPER_BOUND - \
+ IWL50_RTC_DATA_LOWER_BOUND)
/* EEPROM */
#define IWL_5000_EEPROM_IMG_SIZE 2048
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 66d053d28a74..e5ca2511a81a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -43,10 +43,11 @@
#include "iwl-sta.h"
#include "iwl-helpers.h"
#include "iwl-5000-hw.h"
+#include "iwl-6000-hw.h"
/* Highest firmware API version supported */
#define IWL5000_UCODE_API_MAX 1
-#define IWL5150_UCODE_API_MAX 1
+#define IWL5150_UCODE_API_MAX 2
/* Lowest firmware API version supported */
#define IWL5000_UCODE_API_MIN 1
@@ -84,7 +85,7 @@ static int iwl5000_apm_stop_master(struct iwl_priv *priv)
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("stop master\n");
+ IWL_DEBUG_INFO(priv, "stop master\n");
return 0;
}
@@ -108,7 +109,8 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
- iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
+ if (priv->cfg->need_pll_cfg)
+ iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
/* set "initialization complete" bit to move adapter
* D0U* --> D0A* state */
@@ -118,7 +120,7 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
if (ret < 0) {
- IWL_DEBUG_INFO("Failed to init the card\n");
+ IWL_DEBUG_INFO(priv, "Failed to init the card\n");
return ret;
}
@@ -176,7 +178,8 @@ static int iwl5000_apm_reset(struct iwl_priv *priv)
/* FIXME: put here L1A -L0S w/a */
- iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
+ if (priv->cfg->need_pll_cfg)
+ iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
/* set "initialization complete" bit to move adapter
* D0U* --> D0A* state */
@@ -186,7 +189,7 @@ static int iwl5000_apm_reset(struct iwl_priv *priv)
ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
if (ret < 0) {
- IWL_DEBUG_INFO("Failed to init the card\n");
+ IWL_DEBUG_INFO(priv, "Failed to init the card\n");
goto out;
}
@@ -216,18 +219,19 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
{
unsigned long flags;
u16 radio_cfg;
- u16 link;
+ u16 lctl;
spin_lock_irqsave(&priv->lock, flags);
- pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &link);
+ lctl = iwl_pcie_link_ctl(priv);
- /* L1 is enabled by BIOS */
- if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
- /* disable L0S disabled L1A enabled */
+ /* HW bug W/A */
+ /* L1-ASPM is enabled by BIOS */
+ if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
+ /* L1-APSM enabled: disable L0S */
iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
else
- /* L0S enabled L1A disabled */
+ /* L1-ASPM disabled: enable L0S */
iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
@@ -289,7 +293,7 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
offset = iwl_eeprom_query16(priv, EEPROM_5000_LINK_OTHERS);
break;
default:
- IWL_ERROR("illegal indirect type: 0x%X\n",
+ IWL_ERR(priv, "illegal indirect type: 0x%X\n",
address & INDIRECT_TYPE_MSK);
break;
}
@@ -338,7 +342,7 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
data->delta_gain_code[i] |= (1 << 2);
}
- IWL_DEBUG_CALIB("Delta gains: ANT_B = %d ANT_C = %d\n",
+ IWL_DEBUG_CALIB(priv, "Delta gains: ANT_B = %d ANT_C = %d\n",
data->delta_gain_code[1], data->delta_gain_code[2]);
if (!data->radio_write) {
@@ -384,13 +388,14 @@ static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
sizeof(cmd), &cmd);
if (ret)
- IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
+ IWL_ERR(priv,
+ "Could not send REPLY_PHY_CALIBRATION_CMD\n");
data->state = IWL_CHAIN_NOISE_ACCUMULATE;
- IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
+ IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
}
}
-static void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
+void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
__le32 *tx_flags)
{
if ((info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
@@ -507,7 +512,7 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
index = IWL_CALIB_BASE_BAND;
break;
default:
- IWL_ERROR("Unknown calibration notification %d\n",
+ IWL_ERR(priv, "Unknown calibration notification %d\n",
hdr->op_code);
return;
}
@@ -517,7 +522,7 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
- IWL_DEBUG_INFO("Init. calibration is completed, restarting fw.\n");
+ IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n");
queue_work(priv->workqueue, &priv->restart);
}
@@ -580,40 +585,41 @@ static int iwl5000_load_given_ucode(struct iwl_priv *priv,
{
int ret = 0;
- ret = iwl5000_load_section(priv, inst_image, RTC_INST_LOWER_BOUND);
+ ret = iwl5000_load_section(priv, inst_image,
+ IWL50_RTC_INST_LOWER_BOUND);
if (ret)
return ret;
- IWL_DEBUG_INFO("INST uCode section being loaded...\n");
+ IWL_DEBUG_INFO(priv, "INST uCode section being loaded...\n");
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
priv->ucode_write_complete, 5 * HZ);
if (ret == -ERESTARTSYS) {
- IWL_ERROR("Could not load the INST uCode section due "
+ IWL_ERR(priv, "Could not load the INST uCode section due "
"to interrupt\n");
return ret;
}
if (!ret) {
- IWL_ERROR("Could not load the INST uCode section\n");
+ IWL_ERR(priv, "Could not load the INST uCode section\n");
return -ETIMEDOUT;
}
priv->ucode_write_complete = 0;
ret = iwl5000_load_section(
- priv, data_image, RTC_DATA_LOWER_BOUND);
+ priv, data_image, IWL50_RTC_DATA_LOWER_BOUND);
if (ret)
return ret;
- IWL_DEBUG_INFO("DATA uCode section being loaded...\n");
+ IWL_DEBUG_INFO(priv, "DATA uCode section being loaded...\n");
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
priv->ucode_write_complete, 5 * HZ);
if (ret == -ERESTARTSYS) {
- IWL_ERROR("Could not load the INST uCode section due "
+ IWL_ERR(priv, "Could not load the INST uCode section due "
"to interrupt\n");
return ret;
} else if (!ret) {
- IWL_ERROR("Could not load the DATA uCode section\n");
+ IWL_ERR(priv, "Could not load the DATA uCode section\n");
return -ETIMEDOUT;
} else
ret = 0;
@@ -629,20 +635,20 @@ static int iwl5000_load_ucode(struct iwl_priv *priv)
/* check whether init ucode should be loaded, or rather runtime ucode */
if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) {
- IWL_DEBUG_INFO("Init ucode found. Loading init ucode...\n");
+ IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n");
ret = iwl5000_load_given_ucode(priv,
&priv->ucode_init, &priv->ucode_init_data);
if (!ret) {
- IWL_DEBUG_INFO("Init ucode load complete.\n");
+ IWL_DEBUG_INFO(priv, "Init ucode load complete.\n");
priv->ucode_type = UCODE_INIT;
}
} else {
- IWL_DEBUG_INFO("Init ucode not found, or already loaded. "
+ IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. "
"Loading runtime ucode...\n");
ret = iwl5000_load_given_ucode(priv,
&priv->ucode_code, &priv->ucode_data);
if (!ret) {
- IWL_DEBUG_INFO("Runtime ucode load complete.\n");
+ IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n");
priv->ucode_type = UCODE_RT;
}
}
@@ -658,7 +664,7 @@ static void iwl5000_init_alive_start(struct iwl_priv *priv)
if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
/* We had an error bringing up the hardware, so take it
* all the way back down so we can try again */
- IWL_DEBUG_INFO("Initialize Alive failed.\n");
+ IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
goto restart;
}
@@ -668,14 +674,15 @@ static void iwl5000_init_alive_start(struct iwl_priv *priv)
if (iwl_verify_ucode(priv)) {
/* Runtime instruction load was bad;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
+ IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
goto restart;
}
iwl_clear_stations_table(priv);
ret = priv->cfg->ops->lib->alive_notify(priv);
if (ret) {
- IWL_WARNING("Could not complete ALIVE transition: %d\n", ret);
+ IWL_WARN(priv,
+ "Could not complete ALIVE transition: %d\n", ret);
goto restart;
}
@@ -710,7 +717,7 @@ static void iwl5000_tx_queue_set_status(struct iwl_priv *priv,
txq->sched_retry = scd_retry;
- IWL_DEBUG_INFO("%s %s Queue %d on AC %d\n",
+ IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n",
active ? "Activate" : "Deactivate",
scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
}
@@ -824,8 +831,9 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
{
if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) ||
(priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
- IWL_ERROR("invalid queues_num, should be between %d and %d\n",
- IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
+ IWL_ERR(priv,
+ "invalid queues_num, should be between %d and %d\n",
+ IWL_MIN_NUM_QUEUES, IWL50_NUM_QUEUES);
return -EINVAL;
}
@@ -833,70 +841,62 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size =
IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
+ priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
- priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
- priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
+
+ switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+ case CSR_HW_REV_TYPE_6x00:
+ case CSR_HW_REV_TYPE_6x50:
+ priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
+ priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
+ break;
+ default:
+ priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
+ priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE;
+ }
+
priv->hw_params.max_bsm_size = 0;
priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
+ priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
+
priv->hw_params.sens = &iwl5000_sensitivity;
- switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
- case CSR_HW_REV_TYPE_5100:
- priv->hw_params.tx_chains_num = 1;
- priv->hw_params.rx_chains_num = 2;
- priv->hw_params.valid_tx_ant = ANT_B;
- priv->hw_params.valid_rx_ant = ANT_AB;
- break;
- case CSR_HW_REV_TYPE_5150:
- priv->hw_params.tx_chains_num = 1;
- priv->hw_params.rx_chains_num = 2;
- priv->hw_params.valid_tx_ant = ANT_A;
- priv->hw_params.valid_rx_ant = ANT_AB;
- break;
- case CSR_HW_REV_TYPE_5300:
- case CSR_HW_REV_TYPE_5350:
- priv->hw_params.tx_chains_num = 3;
- priv->hw_params.rx_chains_num = 3;
- priv->hw_params.valid_tx_ant = ANT_ABC;
- priv->hw_params.valid_rx_ant = ANT_ABC;
- break;
- }
+ priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
+ priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
+ priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
+ priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
- case CSR_HW_REV_TYPE_5100:
- case CSR_HW_REV_TYPE_5300:
- case CSR_HW_REV_TYPE_5350:
- /* 5X00 and 5350 wants in Celsius */
- priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
- break;
case CSR_HW_REV_TYPE_5150:
/* 5150 wants in Kelvin */
priv->hw_params.ct_kill_threshold =
iwl5150_get_ct_threshold(priv);
break;
+ default:
+ /* all others want Celsius */
+ priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
+ break;
}
/* Set initial calibration set */
switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
- case CSR_HW_REV_TYPE_5100:
- case CSR_HW_REV_TYPE_5300:
- case CSR_HW_REV_TYPE_5350:
+ case CSR_HW_REV_TYPE_5150:
priv->hw_params.calib_init_cfg =
- BIT(IWL_CALIB_XTAL) |
+ BIT(IWL_CALIB_DC) |
BIT(IWL_CALIB_LO) |
BIT(IWL_CALIB_TX_IQ) |
- BIT(IWL_CALIB_TX_IQ_PERD) |
BIT(IWL_CALIB_BASE_BAND);
+
break;
- case CSR_HW_REV_TYPE_5150:
+ default:
priv->hw_params.calib_init_cfg =
- BIT(IWL_CALIB_DC) |
+ BIT(IWL_CALIB_XTAL) |
BIT(IWL_CALIB_LO) |
BIT(IWL_CALIB_TX_IQ) |
+ BIT(IWL_CALIB_TX_IQ_PERD) |
BIT(IWL_CALIB_BASE_BAND);
-
break;
}
@@ -1011,7 +1011,8 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
- IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ IWL_WARN(priv,
+ "queue number out of range: %d, must be %d to %d\n",
txq_id, IWL50_FIRST_AMPDU_QUEUE,
IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1);
return -EINVAL;
@@ -1076,7 +1077,8 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
(IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
- IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
+ IWL_ERR(priv,
+ "queue number out of range: %d, must be %d to %d\n",
txq_id, IWL50_FIRST_AMPDU_QUEUE,
IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES - 1);
return -EINVAL;
@@ -1104,7 +1106,7 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
return 0;
}
-static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
+u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
{
u16 size = (u16)sizeof(struct iwl_addsta_cmd);
memcpy(data, cmd, size);
@@ -1142,7 +1144,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
u16 seq;
if (agg->wait_for_ba)
- IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
+ IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n");
agg->frame_count = tx_resp->frame_count;
agg->start_idx = start_idx;
@@ -1156,7 +1158,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
idx = start_idx;
/* FIXME: code repetition */
- IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
agg->frame_count, agg->start_idx, idx);
info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
@@ -1168,9 +1170,9 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
/* FIXME: code repetition end */
- IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
status & 0xff, tx_resp->failure_frame);
- IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
+ IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags);
agg->wait_for_ba = 0;
} else {
@@ -1190,21 +1192,22 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
AGG_TX_STATE_ABORT_MSK))
continue;
- IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n",
agg->frame_count, txq_id, idx);
hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
sc = le16_to_cpu(hdr->seq_ctrl);
if (idx != (SEQ_TO_SN(sc) & 0xff)) {
- IWL_ERROR("BUG_ON idx doesn't match seq control"
- " idx=%d, seq_idx=%d, seq=%d\n",
+ IWL_ERR(priv,
+ "BUG_ON idx doesn't match seq control"
+ " idx=%d, seq_idx=%d, seq=%d\n",
idx, SEQ_TO_SN(sc),
hdr->seq_ctrl);
return -1;
}
- IWL_DEBUG_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n",
i, idx, SEQ_TO_SN(sc));
sh = idx - start;
@@ -1222,13 +1225,13 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
sh = 0;
}
bitmap |= 1ULL << sh;
- IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
+ IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n",
start, (unsigned long long)bitmap);
}
agg->bitmap = bitmap;
agg->start_idx = start;
- IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
+ IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n",
agg->frame_count, agg->start_idx,
(unsigned long long)agg->bitmap);
@@ -1254,7 +1257,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
int freed;
if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
+ IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
"is out of range [0-%d] %d %d\n", txq_id,
index, txq->q.n_bd, txq->q.write_ptr,
txq->q.read_ptr);
@@ -1281,7 +1284,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
if (txq->q.read_ptr != (scd_ssn & 0xff)) {
index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
- IWL_DEBUG_TX_REPLY("Retry scheduler reclaim "
+ IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim "
"scd_ssn=%d idx=%d txq=%d swq=%d\n",
scd_ssn , index, txq_id, txq->swq_id);
@@ -1292,10 +1295,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
(iwl_queue_space(&txq->q) > txq->q.low_mark) &&
(agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) {
if (agg->state == IWL_AGG_OFF)
- ieee80211_wake_queue(priv->hw, txq_id);
+ iwl_wake_queue(priv, txq_id);
else
- ieee80211_wake_queue(priv->hw,
- txq->swq_id);
+ iwl_wake_queue(priv, txq->swq_id);
}
}
} else {
@@ -1308,7 +1310,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
le32_to_cpu(tx_resp->rate_n_flags),
info);
- IWL_DEBUG_TX_REPLY("TXQ %d status %s (0x%08x) rate_n_flags "
+ IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
"0x%x retries %d\n",
txq_id,
iwl_get_tx_fail_reason(status), status,
@@ -1321,18 +1323,18 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark))
- ieee80211_wake_queue(priv->hw, txq_id);
+ iwl_wake_queue(priv, txq_id);
}
if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
- IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
+ IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
}
/* Currently 5000 is the superset of everything */
-static u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
+u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
{
return len;
}
@@ -1356,7 +1358,7 @@ static void iwl5000_rx_handler_setup(struct iwl_priv *priv)
static int iwl5000_hw_valid_rtc_data_addr(u32 addr)
{
- return (addr >= RTC_DATA_LOWER_BOUND) &&
+ return (addr >= IWL50_RTC_DATA_LOWER_BOUND) &&
(addr < IWL50_RTC_DATA_UPPER_BOUND);
}
@@ -1379,7 +1381,7 @@ static int iwl5000_send_rxon_assoc(struct iwl_priv *priv)
(rxon1->acquisition_data == rxon2->acquisition_data) &&
(rxon1->rx_chain == rxon2->rx_chain) &&
(rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
- IWL_DEBUG_INFO("Using current RXON_ASSOC. Not resending.\n");
+ IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
return 0;
}
@@ -1409,12 +1411,19 @@ static int iwl5000_send_rxon_assoc(struct iwl_priv *priv)
static int iwl5000_send_tx_power(struct iwl_priv *priv)
{
struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
+ u8 tx_ant_cfg_cmd;
/* half dBm need to multiply */
tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED;
tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
- return iwl_send_cmd_pdu_async(priv, REPLY_TX_POWER_DBM_CMD,
+
+ if (IWL_UCODE_API(priv->ucode_ver) == 1)
+ tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
+ else
+ tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
+
+ return iwl_send_cmd_pdu_async(priv, tx_ant_cfg_cmd,
sizeof(tx_power_cmd), &tx_power_cmd,
NULL);
}
@@ -1426,7 +1435,7 @@ static void iwl5000_temperature(struct iwl_priv *priv)
}
/* Calc max signal level (dBm) among 3 possible receivers */
-static int iwl5000_calc_rssi(struct iwl_priv *priv,
+int iwl5000_calc_rssi(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp)
{
/* data from PHY/DSP regarding signal strength, etc.,
@@ -1455,19 +1464,19 @@ static int iwl5000_calc_rssi(struct iwl_priv *priv,
max_rssi = max_t(u32, rssi_a, rssi_b);
max_rssi = max_t(u32, max_rssi, rssi_c);
- IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
+ IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
rssi_a, rssi_b, rssi_c, max_rssi, agc);
/* dBm = max_rssi dB - agc dB - constant.
* Higher AGC (higher radio gain) means lower signal. */
- return max_rssi - agc - IWL_RSSI_OFFSET;
+ return max_rssi - agc - IWL49_RSSI_OFFSET;
}
-static struct iwl_hcmd_ops iwl5000_hcmd = {
+struct iwl_hcmd_ops iwl5000_hcmd = {
.rxon_assoc = iwl5000_send_rxon_assoc,
};
-static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
+struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
.get_hcmd_size = iwl5000_get_hcmd_size,
.build_addsta_hcmd = iwl5000_build_addsta_hcmd,
.gain_computation = iwl5000_gain_computation,
@@ -1476,13 +1485,16 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
.calc_rssi = iwl5000_calc_rssi,
};
-static struct iwl_lib_ops iwl5000_lib = {
+struct iwl_lib_ops iwl5000_lib = {
.set_hw_params = iwl5000_hw_set_hw_params,
.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
.txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwl5000_txq_set_sched,
.txq_agg_enable = iwl5000_txq_agg_enable,
.txq_agg_disable = iwl5000_txq_agg_disable,
+ .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
+ .txq_free_tfd = iwl_hw_txq_free_tfd,
+ .txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwl5000_rx_handler_setup,
.setup_deferred_work = iwl5000_setup_deferred_work,
.is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
@@ -1517,13 +1529,13 @@ static struct iwl_lib_ops iwl5000_lib = {
},
};
-static struct iwl_ops iwl5000_ops = {
+struct iwl_ops iwl5000_ops = {
.lib = &iwl5000_lib,
.hcmd = &iwl5000_hcmd,
.utils = &iwl5000_hcmd_utils,
};
-static struct iwl_mod_params iwl50_mod_params = {
+struct iwl_mod_params iwl50_mod_params = {
.num_of_queues = IWL50_NUM_QUEUES,
.num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
.amsdu_size_8K = 1,
@@ -1543,6 +1555,9 @@ struct iwl_cfg iwl5300_agn_cfg = {
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_ABC,
+ .valid_rx_ant = ANT_ABC,
+ .need_pll_cfg = true,
};
struct iwl_cfg iwl5100_bg_cfg = {
@@ -1556,6 +1571,9 @@ struct iwl_cfg iwl5100_bg_cfg = {
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_B,
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = true,
};
struct iwl_cfg iwl5100_abg_cfg = {
@@ -1569,6 +1587,9 @@ struct iwl_cfg iwl5100_abg_cfg = {
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_B,
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = true,
};
struct iwl_cfg iwl5100_agn_cfg = {
@@ -1582,6 +1603,9 @@ struct iwl_cfg iwl5100_agn_cfg = {
.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_B,
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = true,
};
struct iwl_cfg iwl5350_agn_cfg = {
@@ -1595,6 +1619,9 @@ struct iwl_cfg iwl5350_agn_cfg = {
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_ABC,
+ .valid_rx_ant = ANT_ABC,
+ .need_pll_cfg = true,
};
struct iwl_cfg iwl5150_agn_cfg = {
@@ -1608,6 +1635,9 @@ struct iwl_cfg iwl5150_agn_cfg = {
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_A,
+ .valid_rx_ant = ANT_AB,
+ .need_pll_cfg = true,
};
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-core.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
index 6f463555402c..90185777d98b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -58,47 +58,24 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
*****************************************************************************/
+/*
+ * Please use this file (iwl-6000-hw.h) only for hardware-related definitions.
+ * Use iwl-5000-commands.h for uCode API definitions.
+ */
-#ifndef __iwl_3945_dev_h__
-#define __iwl_3945_dev_h__
-
-#define IWL_PCI_DEVICE(dev, subdev, cfg) \
- .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
- .subvendor = PCI_ANY_ID, .subdevice = (subdev), \
- .driver_data = (kernel_ulong_t)&(cfg)
+#ifndef __iwl_6000_hw_h__
+#define __iwl_6000_hw_h__
-#define IWL_SKU_G 0x1
-#define IWL_SKU_A 0x2
+#define IWL60_RTC_INST_LOWER_BOUND (0x000000)
+#define IWL60_RTC_INST_UPPER_BOUND (0x040000)
+#define IWL60_RTC_DATA_LOWER_BOUND (0x800000)
+#define IWL60_RTC_DATA_UPPER_BOUND (0x814000)
+#define IWL60_RTC_INST_SIZE \
+ (IWL60_RTC_INST_UPPER_BOUND - IWL60_RTC_INST_LOWER_BOUND)
+#define IWL60_RTC_DATA_SIZE \
+ (IWL60_RTC_DATA_UPPER_BOUND - IWL60_RTC_DATA_LOWER_BOUND)
-/**
- * struct iwl_3945_cfg
- * @fw_name_pre: Firmware filename prefix. The api version and extension
- * (.ucode) will be added to filename before loading from disk. The
- * filename is constructed as fw_name_pre<api>.ucode.
- * @ucode_api_max: Highest version of uCode API supported by driver.
- * @ucode_api_min: Lowest version of uCode API supported by driver.
- *
- * We enable the driver to be backward compatible wrt API version. The
- * driver specifies which APIs it supports (with @ucode_api_max being the
- * highest and @ucode_api_min the lowest). Firmware will only be loaded if
- * it has a supported API version. The firmware's API version will be
- * stored in @iwl_priv, enabling the driver to make runtime changes based
- * on firmware version used.
- *
- * For example,
- * if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
- * Driver interacts with Firmware API version >= 2.
- * } else {
- * Driver interacts with Firmware API version 1.
- * }
- */
-struct iwl_3945_cfg {
- const char *name;
- const char *fw_name_pre;
- const unsigned int ucode_api_max;
- const unsigned int ucode_api_min;
- unsigned int sku;
-};
+#endif /* __iwl_6000_hw_h__ */
-#endif /* __iwl_dev_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
new file mode 100644
index 000000000000..edfa5e149f71
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -0,0 +1,158 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2008-2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <net/mac80211.h>
+#include <linux/etherdevice.h>
+#include <asm/unaligned.h>
+
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-io.h"
+#include "iwl-sta.h"
+#include "iwl-helpers.h"
+#include "iwl-5000-hw.h"
+
+/* Highest firmware API version supported */
+#define IWL6000_UCODE_API_MAX 2
+#define IWL6050_UCODE_API_MAX 2
+
+/* Lowest firmware API version supported */
+#define IWL6000_UCODE_API_MIN 1
+#define IWL6050_UCODE_API_MIN 1
+
+#define IWL6000_FW_PRE "iwlwifi-6000-"
+#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode"
+#define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api)
+
+#define IWL6050_FW_PRE "iwlwifi-6050-"
+#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
+#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
+
+static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = {
+ .get_hcmd_size = iwl5000_get_hcmd_size,
+ .build_addsta_hcmd = iwl5000_build_addsta_hcmd,
+ .rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
+ .calc_rssi = iwl5000_calc_rssi,
+};
+
+static struct iwl_ops iwl6000_ops = {
+ .lib = &iwl5000_lib,
+ .hcmd = &iwl5000_hcmd,
+ .utils = &iwl6000_hcmd_utils,
+};
+
+struct iwl_cfg iwl6000_2ag_cfg = {
+ .name = "6000 Series 2x2 AG",
+ .fw_name_pre = IWL6000_FW_PRE,
+ .ucode_api_max = IWL6000_UCODE_API_MAX,
+ .ucode_api_min = IWL6000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G,
+ .ops = &iwl6000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_BC,
+ .valid_rx_ant = ANT_BC,
+ .need_pll_cfg = false,
+};
+
+struct iwl_cfg iwl6000_2agn_cfg = {
+ .name = "6000 Series 2x2 AGN",
+ .fw_name_pre = IWL6000_FW_PRE,
+ .ucode_api_max = IWL6000_UCODE_API_MAX,
+ .ucode_api_min = IWL6000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl6000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_BC,
+ .valid_rx_ant = ANT_BC,
+ .need_pll_cfg = false,
+};
+
+struct iwl_cfg iwl6050_2agn_cfg = {
+ .name = "6050 Series 2x2 AGN",
+ .fw_name_pre = IWL6050_FW_PRE,
+ .ucode_api_max = IWL6050_UCODE_API_MAX,
+ .ucode_api_min = IWL6050_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl6000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_BC,
+ .valid_rx_ant = ANT_BC,
+ .need_pll_cfg = false,
+};
+
+struct iwl_cfg iwl6000_3agn_cfg = {
+ .name = "6000 Series 3x3 AGN",
+ .fw_name_pre = IWL6000_FW_PRE,
+ .ucode_api_max = IWL6000_UCODE_API_MAX,
+ .ucode_api_min = IWL6000_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl6000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_ABC,
+ .valid_rx_ant = ANT_ABC,
+ .need_pll_cfg = false,
+};
+
+struct iwl_cfg iwl6050_3agn_cfg = {
+ .name = "6050 Series 3x3 AGN",
+ .fw_name_pre = IWL6050_FW_PRE,
+ .ucode_api_max = IWL6050_UCODE_API_MAX,
+ .ucode_api_min = IWL6050_UCODE_API_MIN,
+ .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
+ .ops = &iwl6000_ops,
+ .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
+ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
+ .mod_params = &iwl50_mod_params,
+ .valid_tx_ant = ANT_ABC,
+ .valid_rx_ant = ANT_ABC,
+ .need_pll_cfg = false,
+};
+
+MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c
deleted file mode 100644
index b8137eeae1db..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd-check.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/******************************************************************************
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- * Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *****************************************************************************/
-
-#include <linux/kernel.h>
-#include <net/mac80211.h>
-#include "iwl-dev.h"
-#include "iwl-debug.h"
-#include "iwl-commands.h"
-
-
-/**
- * iwl_check_rxon_cmd - validate RXON structure is valid
- *
- * NOTE: This is really only useful during development and can eventually
- * be #ifdef'd out once the driver is stable and folks aren't actively
- * making changes
- */
-int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
-{
- int error = 0;
- int counter = 1;
-
- if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
- error |= le32_to_cpu(rxon->flags &
- (RXON_FLG_TGJ_NARROW_BAND_MSK |
- RXON_FLG_RADAR_DETECT_MSK));
- if (error)
- IWL_WARNING("check 24G fields %d | %d\n",
- counter++, error);
- } else {
- error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
- 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
- if (error)
- IWL_WARNING("check 52 fields %d | %d\n",
- counter++, error);
- error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
- if (error)
- IWL_WARNING("check 52 CCK %d | %d\n",
- counter++, error);
- }
- error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
- if (error)
- IWL_WARNING("check mac addr %d | %d\n", counter++, error);
-
- /* make sure basic rates 6Mbps and 1Mbps are supported */
- error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
- ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
- if (error)
- IWL_WARNING("check basic rate %d | %d\n", counter++, error);
-
- error |= (le16_to_cpu(rxon->assoc_id) > 2007);
- if (error)
- IWL_WARNING("check assoc id %d | %d\n", counter++, error);
-
- error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
- == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
- if (error)
- IWL_WARNING("check CCK and short slot %d | %d\n",
- counter++, error);
-
- error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
- == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
- if (error)
- IWL_WARNING("check CCK & auto detect %d | %d\n",
- counter++, error);
-
- error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
- RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
- if (error)
- IWL_WARNING("check TGG and auto detect %d | %d\n",
- counter++, error);
-
- if (error)
- IWL_WARNING("Tuning to channel %d\n",
- le16_to_cpu(rxon->channel));
-
- if (error) {
- IWL_ERROR("Not a valid iwl4965_rxon_assoc_cmd field values\n");
- return -1;
- }
- return 0;
-}
-
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 27f50471aed8..cab7842a73aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -49,6 +49,8 @@
#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */
#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
+/* max allowed rate miss before sync LQ cmd */
+#define IWL_MISSED_RATE_MAX 15
/* max time to accum history 2 seconds */
#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ)
@@ -148,6 +150,8 @@ struct iwl_lq_sta {
u16 active_mimo2_rate;
u16 active_mimo3_rate;
u16 active_rate_basic;
+ s8 max_rate_idx; /* Max rate set by user */
+ u8 missed_rate_counter;
struct iwl_link_quality_cmd lq;
struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
@@ -356,7 +360,7 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
struct ieee80211_sta *sta)
{
if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
- IWL_DEBUG_HT("Starting Tx agg: STA: %pM tid: %d\n",
+ IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
sta->addr, tid);
ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid);
}
@@ -463,8 +467,9 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
* Fill uCode API rate_n_flags field, based on "search" or "active" table.
*/
/* FIXME:RS:remove this function and put the flags statically in the table */
-static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
- int index, u8 use_green)
+static u32 rate_n_flags_from_tbl(struct iwl_priv *priv,
+ struct iwl_scale_tbl_info *tbl,
+ int index, u8 use_green)
{
u32 rate_n_flags = 0;
@@ -475,7 +480,7 @@ static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
} else if (is_Ht(tbl->lq_type)) {
if (index > IWL_LAST_OFDM_RATE) {
- IWL_ERROR("invalid HT rate index %d\n", index);
+ IWL_ERR(priv, "Invalid HT rate index %d\n", index);
index = IWL_LAST_OFDM_RATE;
}
rate_n_flags = RATE_MCS_HT_MSK;
@@ -487,7 +492,7 @@ static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
else
rate_n_flags |= iwl_rates[index].plcp_mimo3;
} else {
- IWL_ERROR("Invalid tbl->lq_type %d\n", tbl->lq_type);
+ IWL_ERR(priv, "Invalid tbl->lq_type %d\n", tbl->lq_type);
}
rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) &
@@ -507,7 +512,7 @@ static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
rate_n_flags |= RATE_MCS_GF_MSK;
if (is_siso(tbl->lq_type) && tbl->is_SGI) {
rate_n_flags &= ~RATE_MCS_SGI_MSK;
- IWL_ERROR("GF was set with SGI:SISO\n");
+ IWL_ERR(priv, "GF was set with SGI:SISO\n");
}
}
}
@@ -688,7 +693,7 @@ static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask,
break;
if (rate_mask & (1 << low))
break;
- IWL_DEBUG_RATE("Skipping masked lower rate: %d\n", low);
+ IWL_DEBUG_RATE(priv, "Skipping masked lower rate: %d\n", low);
}
high = index;
@@ -698,7 +703,7 @@ static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask,
break;
if (rate_mask & (1 << high))
break;
- IWL_DEBUG_RATE("Skipping masked higher rate: %d\n", high);
+ IWL_DEBUG_RATE(priv, "Skipping masked higher rate: %d\n", high);
}
return (high << 8) | low;
@@ -758,7 +763,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
low = scale_index;
out:
- return rate_n_flags_from_tbl(tbl, low, is_green);
+ return rate_n_flags_from_tbl(lq_sta->drv, tbl, low, is_green);
}
/*
@@ -785,7 +790,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
u8 active_index = 0;
s32 tpt = 0;
- IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n");
+ IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
if (!ieee80211_is_data(hdr->frame_control) ||
is_multicast_ether_addr(hdr->addr1))
@@ -796,7 +801,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
!(info->flags & IEEE80211_TX_STAT_AMPDU))
return;
- retries = info->status.rates[0].count - 1;
+ if (info->flags & IEEE80211_TX_STAT_AMPDU)
+ retries = 0;
+ else
+ retries = info->status.rates[0].count - 1;
if (retries > 15)
retries = 15;
@@ -835,14 +843,19 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
(!!(tx_rate & RATE_MCS_GF_MSK) != !!(info->status.rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
(hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate !=
hw->wiphy->bands[info->band]->bitrates[info->status.rates[0].idx].bitrate)) {
- IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate);
+ IWL_DEBUG_RATE(priv, "initial rate does not match 0x%x\n", tx_rate);
/* the last LQ command could failed so the LQ in ucode not
* the same in driver sync up
*/
- iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
+ lq_sta->missed_rate_counter++;
+ if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
+ lq_sta->missed_rate_counter = 0;
+ iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
+ }
goto out;
}
+ lq_sta->missed_rate_counter = 0;
/* Update frame history window with "failure" for each Tx retry. */
while (retries) {
/* Look up the rate and other info used for each tx attempt.
@@ -903,7 +916,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
tpt = search_tbl->expected_tpt[rs_index];
else
tpt = 0;
- if (info->flags & IEEE80211_TX_CTL_AMPDU)
+ if (info->flags & IEEE80211_TX_STAT_AMPDU)
rs_collect_tx_data(search_win, rs_index, tpt,
info->status.ampdu_ack_len,
info->status.ampdu_ack_map);
@@ -919,7 +932,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
tpt = curr_tbl->expected_tpt[rs_index];
else
tpt = 0;
- if (info->flags & IEEE80211_TX_CTL_AMPDU)
+ if (info->flags & IEEE80211_TX_STAT_AMPDU)
rs_collect_tx_data(window, rs_index, tpt,
info->status.ampdu_ack_len,
info->status.ampdu_ack_map);
@@ -931,7 +944,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
/* If not searching for new mode, increment success/failed counter
* ... these help determine when to start searching again */
if (lq_sta->stay_in_tbl) {
- if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+ if (info->flags & IEEE80211_TX_STAT_AMPDU) {
lq_sta->total_success += info->status.ampdu_ack_map;
lq_sta->total_failed +=
(info->status.ampdu_ack_len - info->status.ampdu_ack_map);
@@ -961,7 +974,7 @@ out:
static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
struct iwl_lq_sta *lq_sta)
{
- IWL_DEBUG_RATE("we are staying in the same table\n");
+ IWL_DEBUG_RATE(priv, "we are staying in the same table\n");
lq_sta->stay_in_tbl = 1; /* only place this gets set */
if (is_legacy) {
lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;
@@ -1129,7 +1142,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
s32 rate;
s8 is_green = lq_sta->is_green;
- if (!conf->ht.enabled || !sta->ht_cap.ht_supported)
+ if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
@@ -1140,7 +1153,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
if (priv->hw_params.tx_chains_num < 2)
return -1;
- IWL_DEBUG_RATE("LQ: try to switch to MIMO2\n");
+ IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO2\n");
tbl->lq_type = LQ_MIMO2;
tbl->is_dup = lq_sta->is_dup;
@@ -1169,16 +1182,16 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
- IWL_DEBUG_RATE("LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask);
+ IWL_DEBUG_RATE(priv, "LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask);
if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
- IWL_DEBUG_RATE("Can't switch with index %d rate mask %x\n",
+ IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n",
rate, rate_mask);
return -1;
}
- tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green);
+ tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
- IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n",
+ IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",
tbl->current_rate, is_green);
return 0;
}
@@ -1196,10 +1209,10 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
u8 is_green = lq_sta->is_green;
s32 rate;
- if (!conf->ht.enabled || !sta->ht_cap.ht_supported)
+ if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
- IWL_DEBUG_RATE("LQ: try to switch to SISO\n");
+ IWL_DEBUG_RATE(priv, "LQ: try to switch to SISO\n");
tbl->is_dup = lq_sta->is_dup;
tbl->lq_type = LQ_SISO;
@@ -1230,14 +1243,14 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
rs_set_expected_tpt_table(lq_sta, tbl);
rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
- IWL_DEBUG_RATE("LQ: get best rate %d mask %X\n", rate, rate_mask);
+ IWL_DEBUG_RATE(priv, "LQ: get best rate %d mask %X\n", rate, rate_mask);
if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
- IWL_DEBUG_RATE("can not switch with index %d rate mask %x\n",
+ IWL_DEBUG_RATE(priv, "can not switch with index %d rate mask %x\n",
rate, rate_mask);
return -1;
}
- tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green);
- IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n",
+ tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
+ IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",
tbl->current_rate, is_green);
return 0;
}
@@ -1266,7 +1279,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
switch (tbl->action) {
case IWL_LEGACY_SWITCH_ANTENNA1:
case IWL_LEGACY_SWITCH_ANTENNA2:
- IWL_DEBUG_RATE("LQ: Legacy toggle Antenna\n");
+ IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n");
lq_sta->action_counter++;
@@ -1290,7 +1303,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
}
break;
case IWL_LEGACY_SWITCH_SISO:
- IWL_DEBUG_RATE("LQ: Legacy switch to SISO\n");
+ IWL_DEBUG_RATE(priv, "LQ: Legacy switch to SISO\n");
/* Set up search table to try SISO */
memcpy(search_tbl, tbl, sz);
@@ -1306,7 +1319,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
case IWL_LEGACY_SWITCH_MIMO2_AB:
case IWL_LEGACY_SWITCH_MIMO2_AC:
case IWL_LEGACY_SWITCH_MIMO2_BC:
- IWL_DEBUG_RATE("LQ: Legacy switch to MIMO2\n");
+ IWL_DEBUG_RATE(priv, "LQ: Legacy switch to MIMO2\n");
/* Set up search table to try MIMO */
memcpy(search_tbl, tbl, sz);
@@ -1375,7 +1388,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
switch (tbl->action) {
case IWL_SISO_SWITCH_ANTENNA1:
case IWL_SISO_SWITCH_ANTENNA2:
- IWL_DEBUG_RATE("LQ: SISO toggle Antenna\n");
+ IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n");
if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
tx_chains_num <= 1) ||
@@ -1394,7 +1407,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
case IWL_SISO_SWITCH_MIMO2_AB:
case IWL_SISO_SWITCH_MIMO2_AC:
case IWL_SISO_SWITCH_MIMO2_BC:
- IWL_DEBUG_RATE("LQ: SISO switch to MIMO2\n");
+ IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO2\n");
memcpy(search_tbl, tbl, sz);
search_tbl->is_SGI = 0;
@@ -1423,14 +1436,15 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
HT_SHORT_GI_40MHZ))
break;
- IWL_DEBUG_RATE("LQ: SISO toggle SGI/NGI\n");
+ IWL_DEBUG_RATE(priv, "LQ: SISO toggle SGI/NGI\n");
memcpy(search_tbl, tbl, sz);
if (is_green) {
if (!tbl->is_SGI)
break;
else
- IWL_ERROR("SGI was set in GF+SISO\n");
+ IWL_ERR(priv,
+ "SGI was set in GF+SISO\n");
}
search_tbl->is_SGI = !tbl->is_SGI;
rs_set_expected_tpt_table(lq_sta, search_tbl);
@@ -1439,8 +1453,9 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
if (tpt >= search_tbl->expected_tpt[index])
break;
}
- search_tbl->current_rate = rate_n_flags_from_tbl(
- search_tbl, index, is_green);
+ search_tbl->current_rate =
+ rate_n_flags_from_tbl(priv, search_tbl,
+ index, is_green);
goto out;
}
tbl->action++;
@@ -1486,7 +1501,7 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
switch (tbl->action) {
case IWL_MIMO2_SWITCH_ANTENNA1:
case IWL_MIMO2_SWITCH_ANTENNA2:
- IWL_DEBUG_RATE("LQ: MIMO toggle Antennas\n");
+ IWL_DEBUG_RATE(priv, "LQ: MIMO toggle Antennas\n");
if (tx_chains_num <= 2)
break;
@@ -1502,7 +1517,7 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
case IWL_MIMO2_SWITCH_SISO_A:
case IWL_MIMO2_SWITCH_SISO_B:
case IWL_MIMO2_SWITCH_SISO_C:
- IWL_DEBUG_RATE("LQ: MIMO2 switch to SISO\n");
+ IWL_DEBUG_RATE(priv, "LQ: MIMO2 switch to SISO\n");
/* Set up new search table for SISO */
memcpy(search_tbl, tbl, sz);
@@ -1534,7 +1549,7 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
HT_SHORT_GI_40MHZ))
break;
- IWL_DEBUG_RATE("LQ: MIMO toggle SGI/NGI\n");
+ IWL_DEBUG_RATE(priv, "LQ: MIMO toggle SGI/NGI\n");
/* Set up new search table for MIMO */
memcpy(search_tbl, tbl, sz);
@@ -1551,8 +1566,9 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
if (tpt >= search_tbl->expected_tpt[index])
break;
}
- search_tbl->current_rate = rate_n_flags_from_tbl(
- search_tbl, index, is_green);
+ search_tbl->current_rate =
+ rate_n_flags_from_tbl(priv, search_tbl,
+ index, is_green);
goto out;
}
@@ -1616,7 +1632,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
(lq_sta->total_success > lq_sta->max_success_limit) ||
((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)
&& (flush_interval_passed))) {
- IWL_DEBUG_RATE("LQ: stay is expired %d %d %d\n:",
+ IWL_DEBUG_RATE(priv, "LQ: stay is expired %d %d %d\n:",
lq_sta->total_failed,
lq_sta->total_success,
flush_interval_passed);
@@ -1639,7 +1655,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
lq_sta->table_count_limit) {
lq_sta->table_count = 0;
- IWL_DEBUG_RATE("LQ: stay in table clear win\n");
+ IWL_DEBUG_RATE(priv, "LQ: stay in table clear win\n");
for (i = 0; i < IWL_RATE_COUNT; i++)
rs_rate_scale_clear_window(
&(tbl->win[i]));
@@ -1687,8 +1703,9 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
u16 high_low;
s32 sr;
u8 tid = MAX_TID_COUNT;
+ struct iwl_tid_data *tid_data;
- IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");
+ IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
/* Send management frames and broadcast/multicast data using
* lowest rate. */
@@ -1720,13 +1737,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
/* current tx rate */
index = lq_sta->last_txrate_idx;
- IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index,
+ IWL_DEBUG_RATE(priv, "Rate scale index %d for type %d\n", index,
tbl->lq_type);
/* rates available for this association, and for modulation mode */
rate_mask = rs_get_supported_rates(lq_sta, hdr, tbl->lq_type);
- IWL_DEBUG_RATE("mask 0x%04X \n", rate_mask);
+ IWL_DEBUG_RATE(priv, "mask 0x%04X \n", rate_mask);
/* mask with station rate restriction */
if (is_legacy(tbl->lq_type)) {
@@ -1745,16 +1762,25 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
rate_scale_index_msk = rate_mask;
if (!((1 << index) & rate_scale_index_msk)) {
- IWL_ERROR("Current Rate is not valid\n");
+ IWL_ERR(priv, "Current Rate is not valid\n");
return;
}
/* Get expected throughput table and history window for current rate */
if (!tbl->expected_tpt) {
- IWL_ERROR("tbl->expected_tpt is NULL\n");
+ IWL_ERR(priv, "tbl->expected_tpt is NULL\n");
return;
}
+ /* force user max rate if set by user */
+ if ((lq_sta->max_rate_idx != -1) &&
+ (lq_sta->max_rate_idx < index)) {
+ index = lq_sta->max_rate_idx;
+ update_lq = 1;
+ window = &(tbl->win[index]);
+ goto lq_update;
+ }
+
window = &(tbl->win[index]);
/*
@@ -1767,7 +1793,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
fail_count = window->counter - window->success_counter;
if ((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
(window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) {
- IWL_DEBUG_RATE("LQ: still below TH. succ=%d total=%d "
+ IWL_DEBUG_RATE(priv, "LQ: still below TH. succ=%d total=%d "
"for index %d\n",
window->success_counter, window->counter, index);
@@ -1795,7 +1821,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
* continuing to use the setup that we've been trying. */
if (window->average_tpt > lq_sta->last_tpt) {
- IWL_DEBUG_RATE("LQ: SWITCHING TO NEW TABLE "
+ IWL_DEBUG_RATE(priv, "LQ: SWITCHING TO NEW TABLE "
"suc=%d cur-tpt=%d old-tpt=%d\n",
window->success_ratio,
window->average_tpt,
@@ -1811,7 +1837,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
/* Else poor success; go back to mode in "active" table */
} else {
- IWL_DEBUG_RATE("LQ: GOING BACK TO THE OLD TABLE "
+ IWL_DEBUG_RATE(priv, "LQ: GOING BACK TO THE OLD TABLE "
"suc=%d cur-tpt=%d old-tpt=%d\n",
window->success_ratio,
window->average_tpt,
@@ -1846,6 +1872,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
low = high_low & 0xff;
high = (high_low >> 8) & 0xff;
+ /* If user set max rate, dont allow higher than user constrain */
+ if ((lq_sta->max_rate_idx != -1) &&
+ (lq_sta->max_rate_idx < high))
+ high = IWL_RATE_INVALID;
+
sr = window->success_ratio;
/* Collect measured throughputs for current and adjacent rates */
@@ -1859,7 +1890,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
/* Too many failures, decrease rate */
if ((sr <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) {
- IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
+ IWL_DEBUG_RATE(priv, "decrease rate because of low success_ratio\n");
scale_action = -1;
/* No throughput measured yet for adjacent rates; try increase. */
@@ -1869,7 +1900,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH)
scale_action = 1;
else if (low != IWL_RATE_INVALID)
- scale_action = -1;
+ scale_action = 0;
}
/* Both adjacent throughputs are measured, but neither one has better
@@ -1890,17 +1921,15 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
sr >= IWL_RATE_INCREASE_TH) {
scale_action = 1;
} else {
- IWL_DEBUG_RATE
- ("decrease rate because of high tpt\n");
- scale_action = -1;
+ scale_action = 0;
}
/* Lower adjacent rate's throughput is measured */
} else if (low_tpt != IWL_INVALID_VALUE) {
/* Lower rate has better throughput */
if (low_tpt > current_tpt) {
- IWL_DEBUG_RATE
- ("decrease rate because of low tpt\n");
+ IWL_DEBUG_RATE(priv,
+ "decrease rate because of low tpt\n");
scale_action = -1;
} else if (sr >= IWL_RATE_INCREASE_TH) {
scale_action = 1;
@@ -1937,14 +1966,14 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
break;
}
- IWL_DEBUG_RATE("choose rate scale index %d action %d low %d "
+ IWL_DEBUG_RATE(priv, "choose rate scale index %d action %d low %d "
"high %d type %d\n",
index, scale_action, low, high, tbl->lq_type);
lq_update:
/* Replace uCode's rate table for the destination station. */
if (update_lq) {
- rate = rate_n_flags_from_tbl(tbl, index, is_green);
+ rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
rs_fill_link_cmd(priv, lq_sta, rate);
iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
}
@@ -1981,7 +2010,7 @@ lq_update:
/* Use new "search" start rate */
index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
- IWL_DEBUG_RATE("Switch current mcs: %X index: %d\n",
+ IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n",
tbl->current_rate, index);
rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
@@ -1993,10 +2022,10 @@ lq_update:
* stay with best antenna legacy modulation for a while
* before next round of mode comparisons. */
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
- if (is_legacy(tbl1->lq_type) && !conf->ht.enabled &&
+ if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) &&
lq_sta->action_counter >= 1) {
lq_sta->action_counter = 0;
- IWL_DEBUG_RATE("LQ: STAY in legacy table\n");
+ IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n");
rs_set_stay_in_table(priv, 1, lq_sta);
}
@@ -2008,8 +2037,15 @@ lq_update:
if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
(lq_sta->tx_agg_tid_en & (1 << tid)) &&
(tid != MAX_TID_COUNT)) {
- IWL_DEBUG_RATE("try to aggregate tid %d\n", tid);
- rs_tl_turn_on_agg(priv, tid, lq_sta, sta);
+ tid_data =
+ &priv->stations[lq_sta->lq.sta_id].tid[tid];
+ if (tid_data->agg.state == IWL_AGG_OFF) {
+ IWL_DEBUG_RATE(priv,
+ "try to aggregate tid %d\n",
+ tid);
+ rs_tl_turn_on_agg(priv, tid,
+ lq_sta, sta);
+ }
}
lq_sta->action_counter = 0;
rs_set_stay_in_table(priv, 0, lq_sta);
@@ -2028,7 +2064,7 @@ lq_update:
}
out:
- tbl->current_rate = rate_n_flags_from_tbl(tbl, index, is_green);
+ tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
i = index;
lq_sta->last_txrate_idx = i;
@@ -2081,7 +2117,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type))
rs_toggle_antenna(valid_tx_ant, &rate, tbl);
- rate = rate_n_flags_from_tbl(tbl, rate_idx, use_green);
+ rate = rate_n_flags_from_tbl(priv, tbl, rate_idx, use_green);
tbl->current_rate = rate;
rs_set_expected_tpt_table(lq_sta, tbl);
rs_fill_link_cmd(NULL, lq_sta, rate);
@@ -2104,7 +2140,18 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
int rate_idx;
u64 mask_bit = 0;
- IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
+ IWL_DEBUG_RATE_LIMIT(priv, "rate scale calculate new rate for skb\n");
+
+ /* Get max rate if user set max rate */
+ if (lq_sta) {
+ lq_sta->max_rate_idx = txrc->max_rate_idx;
+ if ((sband->band == IEEE80211_BAND_5GHZ) &&
+ (lq_sta->max_rate_idx != -1))
+ lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE;
+ if ((lq_sta->max_rate_idx < 0) ||
+ (lq_sta->max_rate_idx >= IWL_RATE_COUNT))
+ lq_sta->max_rate_idx = -1;
+ }
if (sta)
mask_bit = sta->supp_rates[sband->band];
@@ -2129,7 +2176,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
u8 sta_id = iwl_find_station(priv, hdr->addr1);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_RATE("LQ: ADD station %pM\n",
+ IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
hdr->addr1);
sta_id = iwl_add_station_flags(priv, hdr->addr1,
0, CMD_ASYNC, NULL);
@@ -2158,7 +2205,7 @@ static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
int i, j;
priv = (struct iwl_priv *)priv_rate;
- IWL_DEBUG_RATE("create station rate scale window\n");
+ IWL_DEBUG_RATE(priv, "create station rate scale window\n");
lq_sta = kzalloc(sizeof(struct iwl_lq_sta), gfp);
@@ -2182,6 +2229,8 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
struct ieee80211_conf *conf = &priv->hw->conf;
struct iwl_lq_sta *lq_sta = priv_sta;
u16 mask_bit = 0;
+ int count;
+ int start_rate = 0;
lq_sta->flush_timer = 0;
lq_sta->supp_rates = sta->supp_rates[sband->band];
@@ -2189,7 +2238,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
for (i = 0; i < IWL_RATE_COUNT; i++)
rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
- IWL_DEBUG_RATE("LQ: *** rate scale station global init ***\n");
+ IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init ***\n");
/* TODO: what is a good starting rate for STA? About middle? Maybe not
* the lowest or the highest rate.. Could consider using RSSI from
* previous packets? Need to have IEEE 802.1X auth succeed immediately
@@ -2200,10 +2249,10 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
u8 sta_id = iwl_find_station(priv, sta->addr);
/* for IBSS the call are from tasklet */
- IWL_DEBUG_RATE("LQ: ADD station %pM\n", sta->addr);
+ IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_RATE("LQ: ADD station %pM\n", sta->addr);
+ IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
sta_id = iwl_add_station_flags(priv, sta->addr,
0, CMD_ASYNC, NULL);
}
@@ -2216,6 +2265,8 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
}
lq_sta->is_dup = 0;
+ lq_sta->max_rate_idx = -1;
+ lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
lq_sta->is_green = rs_use_green(priv, conf);
lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
lq_sta->active_rate_basic = priv->active_rate_basic;
@@ -2240,7 +2291,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
lq_sta->active_mimo3_rate &= ~((u16)0x2);
lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
- IWL_DEBUG_RATE("SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n",
+ IWL_DEBUG_RATE(priv, "SISO-RATE=%X MIMO2-RATE=%X MIMO3-RATE=%X\n",
lq_sta->active_siso_rate,
lq_sta->active_mimo2_rate,
lq_sta->active_mimo3_rate);
@@ -2254,16 +2305,20 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
lq_sta->drv = priv;
/* Find highest tx rate supported by hardware and destination station */
- mask_bit = sta->supp_rates[sband->band] & lq_sta->active_legacy_rate;
- lq_sta->last_txrate_idx = 3;
- for (i = 0; i < sband->n_bitrates; i++)
+ mask_bit = sta->supp_rates[sband->band];
+ count = sband->n_bitrates;
+ if (sband->band == IEEE80211_BAND_5GHZ) {
+ count += IWL_FIRST_OFDM_RATE;
+ start_rate = IWL_FIRST_OFDM_RATE;
+ mask_bit <<= IWL_FIRST_OFDM_RATE;
+ }
+
+ mask_bit = mask_bit & lq_sta->active_legacy_rate;
+ lq_sta->last_txrate_idx = 4;
+ for (i = start_rate; i < count; i++)
if (mask_bit & BIT(i))
lq_sta->last_txrate_idx = i;
- /* For MODE_IEEE80211A, skip over cck rates in global rate table */
- if (sband->band == IEEE80211_BAND_5GHZ)
- lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
-
rs_initialize_lq(priv, conf, sta, lq_sta);
}
@@ -2402,9 +2457,9 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
struct iwl_lq_sta *lq_sta = priv_sta;
struct iwl_priv *priv __maybe_unused = priv_r;
- IWL_DEBUG_RATE("enter\n");
+ IWL_DEBUG_RATE(priv, "enter\n");
kfree(lq_sta);
- IWL_DEBUG_RATE("leave\n");
+ IWL_DEBUG_RATE(priv, "leave\n");
}
@@ -2418,20 +2473,27 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
u32 *rate_n_flags, int index)
{
struct iwl_priv *priv;
+ u8 valid_tx_ant;
+ u8 ant_sel_tx;
priv = lq_sta->drv;
+ valid_tx_ant = priv->hw_params.valid_tx_ant;
if (lq_sta->dbg_fixed_rate) {
- if (index < 12) {
+ ant_sel_tx =
+ ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK)
+ >> RATE_MCS_ANT_POS);
+ if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) {
*rate_n_flags = lq_sta->dbg_fixed_rate;
+ IWL_DEBUG_RATE(priv, "Fixed rate ON\n");
} else {
- if (lq_sta->band == IEEE80211_BAND_5GHZ)
- *rate_n_flags = 0x800D;
- else
- *rate_n_flags = 0x820A;
+ lq_sta->dbg_fixed_rate = 0;
+ IWL_ERR(priv,
+ "Invalid antenna selection 0x%X, Valid is 0x%X\n",
+ ant_sel_tx, valid_tx_ant);
+ IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");
}
- IWL_DEBUG_RATE("Fixed rate ON\n");
} else {
- IWL_DEBUG_RATE("Fixed rate OFF\n");
+ IWL_DEBUG_RATE(priv, "Fixed rate OFF\n");
}
}
@@ -2460,7 +2522,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
- IWL_DEBUG_RATE("sta_id %d rate 0x%X\n",
+ IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
if (lq_sta->dbg_fixed_rate) {
@@ -2474,11 +2536,19 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
char __user *user_buf, size_t count, loff_t *ppos)
{
- char buff[1024];
+ char *buff;
int desc = 0;
int i = 0;
+ ssize_t ret;
struct iwl_lq_sta *lq_sta = file->private_data;
+ struct iwl_priv *priv;
+ struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+
+ priv = lq_sta->drv;
+ buff = kmalloc(1024, GFP_KERNEL);
+ if (!buff)
+ return -ENOMEM;
desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
@@ -2486,6 +2556,20 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
lq_sta->active_legacy_rate);
desc += sprintf(buff+desc, "fixed rate 0x%X\n",
lq_sta->dbg_fixed_rate);
+ desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
+ (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "",
+ (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "",
+ (priv->hw_params.valid_tx_ant & ANT_C) ? "ANT_C" : "");
+ desc += sprintf(buff+desc, "lq type %s\n",
+ (is_legacy(tbl->lq_type)) ? "legacy" : "HT");
+ if (is_Ht(tbl->lq_type)) {
+ desc += sprintf(buff+desc, " %s",
+ (is_siso(tbl->lq_type)) ? "SISO" :
+ ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));
+ desc += sprintf(buff+desc, " %s",
+ (tbl->is_fat) ? "40MHz" : "20MHz");
+ desc += sprintf(buff+desc, " %s\n", (tbl->is_SGI) ? "SGI" : "");
+ }
desc += sprintf(buff+desc, "general:"
"flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
lq_sta->lq.general_params.flags,
@@ -2511,7 +2595,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
desc += sprintf(buff+desc, " rate[%d] 0x%X\n",
i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
- return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ kfree(buff);
+ return ret;
}
static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
@@ -2522,11 +2608,17 @@ static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
char __user *user_buf, size_t count, loff_t *ppos)
{
- char buff[1024];
+ char *buff;
int desc = 0;
int i, j;
+ ssize_t ret;
struct iwl_lq_sta *lq_sta = file->private_data;
+
+ buff = kmalloc(1024, GFP_KERNEL);
+ if (!buff)
+ return -ENOMEM;
+
for (i = 0; i < LQ_SIZE; i++) {
desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n"
"rate=0x%X\n",
@@ -2544,7 +2636,9 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
lq_sta->lq_info[i].win[j].success_ratio);
}
}
- return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+ kfree(buff);
+ return ret;
}
static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 78ee83adf742..ab59acc405d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -27,8 +27,6 @@
#ifndef __iwl_agn_rs_h__
#define __iwl_agn_rs_h__
-#include "iwl-dev.h"
-
struct iwl_rate_info {
u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
@@ -43,6 +41,19 @@ struct iwl_rate_info {
u8 next_rs_tgg; /* next rate used in TGG rs algo */
};
+struct iwl3945_rate_info {
+ u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
+ u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
+ u8 prev_ieee; /* previous rate in IEEE speeds */
+ u8 next_ieee; /* next rate in IEEE speeds */
+ u8 prev_rs; /* previous rate used in rs algo */
+ u8 next_rs; /* next rate used in rs algo */
+ u8 prev_rs_tgg; /* previous rate used in TGG rs algo */
+ u8 next_rs_tgg; /* next rate used in TGG rs algo */
+ u8 table_rs_index; /* index in rate scale table cmd */
+ u8 prev_table_rs; /* prev in rate table cmd */
+};
+
/*
* These serve as indexes into
* struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
@@ -62,12 +73,30 @@ enum {
IWL_RATE_54M_INDEX,
IWL_RATE_60M_INDEX,
IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/
+ IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1,
IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
IWL_RATE_INVALID = IWL_RATE_COUNT,
};
enum {
+ IWL_RATE_6M_INDEX_TABLE = 0,
+ IWL_RATE_9M_INDEX_TABLE,
+ IWL_RATE_12M_INDEX_TABLE,
+ IWL_RATE_18M_INDEX_TABLE,
+ IWL_RATE_24M_INDEX_TABLE,
+ IWL_RATE_36M_INDEX_TABLE,
+ IWL_RATE_48M_INDEX_TABLE,
+ IWL_RATE_54M_INDEX_TABLE,
+ IWL_RATE_1M_INDEX_TABLE,
+ IWL_RATE_2M_INDEX_TABLE,
+ IWL_RATE_5M_INDEX_TABLE,
+ IWL_RATE_11M_INDEX_TABLE,
+ IWL_RATE_INVM_INDEX_TABLE = IWL_RATE_INVM_INDEX - 1,
+};
+
+enum {
IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
+ IWL39_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX,
IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
@@ -202,7 +231,7 @@ enum {
#define IWL_RS_GOOD_RATIO 12800 /* 100% */
#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */
#define IWL_RATE_HIGH_TH 10880 /* 85% */
-#define IWL_RATE_INCREASE_TH 8960 /* 70% */
+#define IWL_RATE_INCREASE_TH 6400 /* 50% */
#define IWL_RATE_DECREASE_TH 1920 /* 15% */
/* possible actions when in legacy mode */
@@ -248,6 +277,7 @@ enum {
#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
+extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945];
enum iwl_table_type {
LQ_NONE,
@@ -303,6 +333,23 @@ static inline u8 iwl_get_prev_ieee_rate(u8 rate_index)
return rate;
}
+static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
+{
+ u8 rate = iwl3945_rates[rate_index].prev_ieee;
+
+ if (rate == IWL_RATE_INVALID)
+ rate = rate_index;
+ return rate;
+}
+
+/**
+ * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
+ *
+ * The specific throughput table used is based on the type of network
+ * the associated with, including A, B, G, and G w/ TGG protection
+ */
+extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
+
/**
* iwl_rate_control_register - Register the rate control algorithm callbacks
*
@@ -314,6 +361,7 @@ static inline u8 iwl_get_prev_ieee_rate(u8 rate_index)
*
*/
extern int iwlagn_rate_control_register(void);
+extern int iwl3945_rate_control_register(void);
/**
* iwl_rate_control_unregister - Unregister the rate control callbacks
@@ -322,5 +370,6 @@ extern int iwlagn_rate_control_register(void);
* the driver is unloaded.
*/
extern void iwlagn_rate_control_unregister(void);
+extern void iwl3945_rate_control_unregister(void);
#endif /* __iwl_agn__rs__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 129e2d330abb..3889158b359c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -44,6 +44,8 @@
#include <asm/div64.h>
+#define DRV_NAME "iwlagn"
+
#include "iwl-eeprom.h"
#include "iwl-dev.h"
#include "iwl-core.h"
@@ -61,9 +63,7 @@
/*
* module name, copyright, version, etc.
- * NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk
*/
-
#define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux"
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -72,7 +72,7 @@
#define VD
#endif
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
#define VS "s"
#else
#define VS
@@ -94,66 +94,6 @@ MODULE_ALIAS("iwl4965");
/**************************************************************/
-
-
-static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
-{
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
-
- if (hw_decrypt)
- rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
- else
- rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;
-
-}
-
-/**
- * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
- * @priv: staging_rxon is compared to active_rxon
- *
- * If the RXON structure is changing enough to require a new tune,
- * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
- * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
- */
-static int iwl_full_rxon_required(struct iwl_priv *priv)
-{
-
- /* These items are only settable from the full RXON command */
- if (!(iwl_is_associated(priv)) ||
- compare_ether_addr(priv->staging_rxon.bssid_addr,
- priv->active_rxon.bssid_addr) ||
- compare_ether_addr(priv->staging_rxon.node_addr,
- priv->active_rxon.node_addr) ||
- compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
- priv->active_rxon.wlap_bssid_addr) ||
- (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
- (priv->staging_rxon.channel != priv->active_rxon.channel) ||
- (priv->staging_rxon.air_propagation !=
- priv->active_rxon.air_propagation) ||
- (priv->staging_rxon.ofdm_ht_single_stream_basic_rates !=
- priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
- (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
- priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
- (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
- return 1;
-
- /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
- * be updated with the RXON_ASSOC command -- however only some
- * flag transitions are allowed using RXON_ASSOC */
-
- /* Check if we are not switching bands */
- if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
- (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
- return 1;
-
- /* Check if we are switching association toggle */
- if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
- (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
- return 1;
-
- return 0;
-}
-
/**
* iwl_commit_rxon - commit staging_rxon to hardware
*
@@ -179,9 +119,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
* 5000, but will not damage 4965 */
priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
- ret = iwl_agn_check_rxon_cmd(&priv->staging_rxon);
+ ret = iwl_check_rxon_cmd(priv);
if (ret) {
- IWL_ERROR("Invalid RXON configuration. Not committing.\n");
+ IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
return -EINVAL;
}
@@ -191,7 +131,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
if (!iwl_full_rxon_required(priv)) {
ret = iwl_send_rxon_assoc(priv);
if (ret) {
- IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret);
+ IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
return ret;
}
@@ -207,7 +147,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
* we must clear the associated from the active configuration
* before we apply the new config */
if (iwl_is_associated(priv) && new_assoc) {
- IWL_DEBUG_INFO("Toggling associated bit on current RXON\n");
+ IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
@@ -218,12 +158,12 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
* active_rxon back to what it was previously */
if (ret) {
active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
- IWL_ERROR("Error clearing ASSOC_MSK (%d)\n", ret);
+ IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
return ret;
}
}
- IWL_DEBUG_INFO("Sending RXON\n"
+ IWL_DEBUG_INFO(priv, "Sending RXON\n"
"* with%s RXON_FILTER_ASSOC_MSK\n"
"* channel = %d\n"
"* bssid = %pM\n",
@@ -242,7 +182,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
if (ret) {
- IWL_ERROR("Error setting new RXON (%d)\n", ret);
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
return ret;
}
memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
@@ -256,7 +196,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
/* Add the broadcast address so we can send broadcast frames */
if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
IWL_INVALID_STATION) {
- IWL_ERROR("Error adding BROADCAST address for transmit.\n");
+ IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
return -EIO;
}
@@ -267,13 +207,15 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
ret = iwl_rxon_add_station(priv,
priv->active_rxon.bssid_addr, 1);
if (ret == IWL_INVALID_STATION) {
- IWL_ERROR("Error adding AP address for TX.\n");
+ IWL_ERR(priv,
+ "Error adding AP address for TX.\n");
return -EIO;
}
priv->assoc_station_added = 1;
if (priv->default_wep_key &&
iwl_send_static_wepkey_cmd(priv, 0))
- IWL_ERROR("Could not send WEP static key.\n");
+ IWL_ERR(priv,
+ "Could not send WEP static key.\n");
}
/* Apply the new configuration
@@ -282,7 +224,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
if (ret) {
- IWL_ERROR("Error setting new RXON (%d)\n", ret);
+ IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
return ret;
}
memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
@@ -294,7 +236,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
* send a new TXPOWER command or we won't be able to Tx any frames */
ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
if (ret) {
- IWL_ERROR("Error sending TX power (%d)\n", ret);
+ IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
return ret;
}
@@ -308,25 +250,11 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
iwl_commit_rxon(priv);
}
-static int iwl_send_bt_config(struct iwl_priv *priv)
-{
- struct iwl_bt_cmd bt_cmd = {
- .flags = 3,
- .lead_time = 0xAA,
- .max_kill = 1,
- .kill_ack_mask = 0,
- .kill_cts_mask = 0,
- };
-
- return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
- sizeof(struct iwl_bt_cmd), &bt_cmd);
-}
-
static void iwl_clear_free_frames(struct iwl_priv *priv)
{
struct list_head *element;
- IWL_DEBUG_INFO("%d frames on pre-allocated heap on clear.\n",
+ IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
priv->frames_count);
while (!list_empty(&priv->free_frames)) {
@@ -337,7 +265,7 @@ static void iwl_clear_free_frames(struct iwl_priv *priv)
}
if (priv->frames_count) {
- IWL_WARNING("%d frames still in use. Did we lose one?\n",
+ IWL_WARN(priv, "%d frames still in use. Did we lose one?\n",
priv->frames_count);
priv->frames_count = 0;
}
@@ -350,7 +278,7 @@ static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv)
if (list_empty(&priv->free_frames)) {
frame = kzalloc(sizeof(*frame), GFP_KERNEL);
if (!frame) {
- IWL_ERROR("Could not allocate frame!\n");
+ IWL_ERR(priv, "Could not allocate frame!\n");
return NULL;
}
@@ -386,31 +314,6 @@ static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
return priv->ibss_beacon->len;
}
-static u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
-{
- int i;
- int rate_mask;
-
- /* Set rate mask*/
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
- rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
- else
- rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
-
- /* Find lowest valid rate */
- for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
- i = iwl_rates[i].next_ieee) {
- if (rate_mask & (1 << i))
- return iwl_rates[i].plcp;
- }
-
- /* No valid rate was found. Assign the lowest one */
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
- return IWL_RATE_1M_PLCP;
- else
- return IWL_RATE_6M_PLCP;
-}
-
static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl_frame *frame, u8 rate)
{
@@ -452,7 +355,7 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv)
frame = iwl_get_free_frame(priv);
if (!frame) {
- IWL_ERROR("Could not obtain free frame buffer for beacon "
+ IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
"command.\n");
return -ENOMEM;
}
@@ -469,6 +372,159 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv)
return rc;
}
+static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
+{
+ struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+
+ dma_addr_t addr = get_unaligned_le32(&tb->lo);
+ if (sizeof(dma_addr_t) > sizeof(u32))
+ addr |=
+ ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
+
+ return addr;
+}
+
+static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
+{
+ struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+
+ return le16_to_cpu(tb->hi_n_len) >> 4;
+}
+
+static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
+ dma_addr_t addr, u16 len)
+{
+ struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+ u16 hi_n_len = len << 4;
+
+ put_unaligned_le32(addr, &tb->lo);
+ if (sizeof(dma_addr_t) > sizeof(u32))
+ hi_n_len |= ((addr >> 16) >> 16) & 0xF;
+
+ tb->hi_n_len = cpu_to_le16(hi_n_len);
+
+ tfd->num_tbs = idx + 1;
+}
+
+static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
+{
+ return tfd->num_tbs & 0x1f;
+}
+
+/**
+ * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
+ * @priv - driver private data
+ * @txq - tx queue
+ *
+ * Does NOT advance any TFD circular buffer read/write indexes
+ * Does NOT free the TFD itself (which is within circular buffer)
+ */
+void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+{
+ struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds;
+ struct iwl_tfd *tfd;
+ struct pci_dev *dev = priv->pci_dev;
+ int index = txq->q.read_ptr;
+ int i;
+ int num_tbs;
+
+ tfd = &tfd_tmp[index];
+
+ /* Sanity check on number of chunks */
+ num_tbs = iwl_tfd_get_num_tbs(tfd);
+
+ if (num_tbs >= IWL_NUM_OF_TBS) {
+ IWL_ERR(priv, "Too many chunks: %i\n", num_tbs);
+ /* @todo issue fatal error, it is quite serious situation */
+ return;
+ }
+
+ /* Unmap tx_cmd */
+ if (num_tbs)
+ pci_unmap_single(dev,
+ pci_unmap_addr(&txq->cmd[index]->meta, mapping),
+ pci_unmap_len(&txq->cmd[index]->meta, len),
+ PCI_DMA_BIDIRECTIONAL);
+
+ /* Unmap chunks, if any. */
+ for (i = 1; i < num_tbs; i++) {
+ pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
+ iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
+
+ if (txq->txb) {
+ dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]);
+ txq->txb[txq->q.read_ptr].skb[i - 1] = NULL;
+ }
+ }
+}
+
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len,
+ u8 reset, u8 pad)
+{
+ struct iwl_queue *q;
+ struct iwl_tfd *tfd, *tfd_tmp;
+ u32 num_tbs;
+
+ q = &txq->q;
+ tfd_tmp = (struct iwl_tfd *)txq->tfds;
+ tfd = &tfd_tmp[q->write_ptr];
+
+ if (reset)
+ memset(tfd, 0, sizeof(*tfd));
+
+ num_tbs = iwl_tfd_get_num_tbs(tfd);
+
+ /* Each TFD can point to a maximum 20 Tx buffers */
+ if (num_tbs >= IWL_NUM_OF_TBS) {
+ IWL_ERR(priv, "Error can not send more than %d chunks\n",
+ IWL_NUM_OF_TBS);
+ return -EINVAL;
+ }
+
+ BUG_ON(addr & ~DMA_BIT_MASK(36));
+ if (unlikely(addr & ~IWL_TX_DMA_MASK))
+ IWL_ERR(priv, "Unaligned address = %llx\n",
+ (unsigned long long)addr);
+
+ iwl_tfd_set_tb(tfd, num_tbs, addr, len);
+
+ return 0;
+}
+
+/*
+ * Tell nic where to find circular buffer of Tx Frame Descriptors for
+ * given Tx queue, and enable the DMA channel used for that queue.
+ *
+ * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
+ * channels supported in hardware.
+ */
+int iwl_hw_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq)
+{
+ int ret;
+ unsigned long flags;
+ int txq_id = txq->q.id;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
+ }
+
+ /* Circular buffer (TFD queue in DRAM) physical base address */
+ iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
+ txq->q.dma_addr >> 8);
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+
/******************************************************************************
*
* Misc. internal state and helper functions
@@ -482,7 +538,7 @@ static void iwl_ht_conf(struct iwl_priv *priv,
struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
struct ieee80211_sta *sta;
- IWL_DEBUG_MAC80211("enter: \n");
+ IWL_DEBUG_MAC80211(priv, "enter: \n");
if (!iwl_conf->is_ht)
return;
@@ -520,9 +576,9 @@ static void iwl_ht_conf(struct iwl_priv *priv,
*/
iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
- if (priv->hw->conf.ht.channel_type == NL80211_CHAN_HT40MINUS)
+ if (conf_is_ht40_minus(&priv->hw->conf))
iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- else if(priv->hw->conf.ht.channel_type == NL80211_CHAN_HT40PLUS)
+ else if (conf_is_ht40_plus(&priv->hw->conf))
iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
/* If no above or below channel supplied disable FAT channel */
@@ -542,39 +598,7 @@ static void iwl_ht_conf(struct iwl_priv *priv,
rcu_read_unlock();
- IWL_DEBUG_MAC80211("leave\n");
-}
-
-/*
- * QoS support
-*/
-static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
-{
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- priv->qos_data.def_qos_parm.qos_flags = 0;
-
- if (priv->qos_data.qos_cap.q_AP.queue_request &&
- !priv->qos_data.qos_cap.q_AP.txop_request)
- priv->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_TXOP_TYPE_MSK;
- if (priv->qos_data.qos_active)
- priv->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_UPDATE_EDCA_MSK;
-
- if (priv->current_ht_config.is_ht)
- priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
-
- if (force || iwl_is_associated(priv)) {
- IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n",
- priv->qos_data.qos_active,
- priv->qos_data.def_qos_parm.qos_flags);
-
- iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
- sizeof(struct iwl_qosparam_cmd),
- &priv->qos_data.def_qos_parm, NULL);
- }
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
#define MAX_UCODE_BEACON_INTERVAL 4096
@@ -588,6 +612,9 @@ static u16 iwl_adjust_beacon_interval(u16 beacon_val)
/ MAX_UCODE_BEACON_INTERVAL;
new_val = beacon_val / beacon_factor;
+ if (!new_val)
+ new_val = MAX_UCODE_BEACON_INTERVAL;
+
return new_val;
}
@@ -624,117 +651,16 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_ASSOC("beacon interval %d beacon timer %d beacon tim %d\n",
+ IWL_DEBUG_ASSOC(priv, "beacon interval %d beacon timer %d beacon tim %d\n",
le16_to_cpu(priv->rxon_timing.beacon_interval),
le32_to_cpu(priv->rxon_timing.beacon_init_val),
le16_to_cpu(priv->rxon_timing.atim_window));
}
-static void iwl_set_flags_for_band(struct iwl_priv *priv,
- enum ieee80211_band band)
-{
- if (band == IEEE80211_BAND_5GHZ) {
- priv->staging_rxon.flags &=
- ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
- | RXON_FLG_CCK_MSK);
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
- } else {
- /* Copied from iwl_post_associate() */
- if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
- else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
- priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
- priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
- priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
- }
-}
-
-/*
- * initialize rxon structure with default values from eeprom
- */
-static void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
-{
- const struct iwl_channel_info *ch_info;
-
- memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
-
- switch (mode) {
- case NL80211_IFTYPE_AP:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
- break;
-
- case NL80211_IFTYPE_STATION:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
- priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
- break;
-
- case NL80211_IFTYPE_ADHOC:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
- priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
- priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
- RXON_FILTER_ACCEPT_GRP_MSK;
- break;
-
- case NL80211_IFTYPE_MONITOR:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
- priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
- RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
- break;
- default:
- IWL_ERROR("Unsupported interface type %d\n", mode);
- break;
- }
-
-#if 0
- /* TODO: Figure out when short_preamble would be set and cache from
- * that */
- if (!hw_to_local(priv->hw)->short_preamble)
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
-#endif
-
- ch_info = iwl_get_channel_info(priv, priv->band,
- le16_to_cpu(priv->active_rxon.channel));
-
- if (!ch_info)
- ch_info = &priv->channel_info[0];
-
- /*
- * in some case A channels are all non IBSS
- * in this case force B/G channel
- */
- if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
- !(is_channel_ibss(ch_info)))
- ch_info = &priv->channel_info[0];
-
- priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
- priv->band = ch_info->band;
-
- iwl_set_flags_for_band(priv, priv->band);
-
- priv->staging_rxon.ofdm_basic_rates =
- (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
- priv->staging_rxon.cck_basic_rates =
- (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
-
- priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
- RXON_FLG_CHANNEL_MODE_PURE_40_MSK);
- memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
- memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN);
- priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff;
- priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff;
- iwl_set_rxon_chain(priv);
-}
-
static int iwl_set_mode(struct iwl_priv *priv, int mode)
{
iwl_connection_init_rx_config(priv, mode);
+ iwl_set_rxon_chain(priv);
memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
iwl_clear_stations_table(priv);
@@ -745,8 +671,8 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode)
cancel_delayed_work(&priv->scan_check);
if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARNING("Aborted scan still in progress after 100ms\n");
- IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
+ IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
+ IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
return -EAGAIN;
}
@@ -755,54 +681,6 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode)
return 0;
}
-static void iwl_set_rate(struct iwl_priv *priv)
-{
- const struct ieee80211_supported_band *hw = NULL;
- struct ieee80211_rate *rate;
- int i;
-
- hw = iwl_get_hw_mode(priv, priv->band);
- if (!hw) {
- IWL_ERROR("Failed to set rate: unable to get hw mode\n");
- return;
- }
-
- priv->active_rate = 0;
- priv->active_rate_basic = 0;
-
- for (i = 0; i < hw->n_bitrates; i++) {
- rate = &(hw->bitrates[i]);
- if (rate->hw_value < IWL_RATE_COUNT)
- priv->active_rate |= (1 << rate->hw_value);
- }
-
- IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n",
- priv->active_rate, priv->active_rate_basic);
-
- /*
- * If a basic rate is configured, then use it (adding IWL_RATE_1M_MASK)
- * otherwise set it to the default of all CCK rates and 6, 12, 24 for
- * OFDM
- */
- if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
- priv->staging_rxon.cck_basic_rates =
- ((priv->active_rate_basic &
- IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
- else
- priv->staging_rxon.cck_basic_rates =
- (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
-
- if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
- priv->staging_rxon.ofdm_basic_rates =
- ((priv->active_rate_basic &
- (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
- IWL_FIRST_OFDM_RATE) & 0xFF;
- else
- priv->staging_rxon.ofdm_basic_rates =
- (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
-}
-
-
/******************************************************************************
*
* Generic RX handler implementations
@@ -817,19 +695,19 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
palive = &pkt->u.alive_frame;
- IWL_DEBUG_INFO("Alive ucode status 0x%08X revision "
+ IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
"0x%01X 0x%01X\n",
palive->is_valid, palive->ver_type,
palive->ver_subtype);
if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
- IWL_DEBUG_INFO("Initialization Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
memcpy(&priv->card_alive_init,
&pkt->u.alive_frame,
sizeof(struct iwl_init_alive_resp));
pwork = &priv->init_alive_start;
} else {
- IWL_DEBUG_INFO("Runtime Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
memcpy(&priv->card_alive, &pkt->u.alive_frame,
sizeof(struct iwl_alive_resp));
pwork = &priv->alive_start;
@@ -841,55 +719,7 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
queue_delayed_work(priv->workqueue, pwork,
msecs_to_jiffies(5));
else
- IWL_WARNING("uCode did not respond OK.\n");
-}
-
-static void iwl_rx_reply_error(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-{
- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
-
- IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) "
- "seq 0x%04X ser 0x%08X\n",
- le32_to_cpu(pkt->u.err_resp.error_type),
- get_cmd_string(pkt->u.err_resp.cmd_id),
- pkt->u.err_resp.cmd_id,
- le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
- le32_to_cpu(pkt->u.err_resp.error_info));
-}
-
-#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
-
-static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
-{
- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
- struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
- IWL_DEBUG_11H("CSA notif: channel %d, status %d\n",
- le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
- rxon->channel = csa->channel;
- priv->staging_rxon.channel = csa->channel;
-}
-
-static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-{
-#ifdef CONFIG_IWLWIFI_DEBUG
- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
- IWL_DEBUG_RX("sleep mode: %d, src: %d\n",
- sleep->pm_sleep_mode, sleep->pm_wakeup_src);
-#endif
-}
-
-static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-{
- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- IWL_DEBUG_RADIO("Dumping %d bytes of unhandled "
- "notification for %s:\n",
- le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
- iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+ IWL_WARN(priv, "uCode did not respond OK.\n");
}
static void iwl_bg_beacon_update(struct work_struct *work)
@@ -902,7 +732,7 @@ static void iwl_bg_beacon_update(struct work_struct *work)
beacon = ieee80211_beacon_get(priv->hw, priv->vif);
if (!beacon) {
- IWL_ERROR("update beacon failed\n");
+ IWL_ERR(priv, "update beacon failed\n");
return;
}
@@ -950,7 +780,7 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
(struct iwl4965_beacon_notif *)pkt->u.raw;
u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
- IWL_DEBUG_RX("beacon status %x retries %d iss %d "
+ IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
"tsf %d %d rate %d\n",
le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
beacon->beacon_notify_hdr.failure_frame,
@@ -973,7 +803,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
unsigned long status = priv->status;
- IWL_DEBUG_RF_KILL("Card state received: HW:%s SW:%s\n",
+ IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n",
(flags & HW_CARD_DISABLED) ? "Kill" : "On",
(flags & SW_CARD_DISABLED) ? "Kill" : "On");
@@ -1046,11 +876,7 @@ int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
goto err;
if (src == IWL_PWR_SRC_VAUX) {
- u32 val;
- ret = pci_read_config_dword(priv->pci_dev, PCI_CFG_POWER_SOURCE,
- &val);
-
- if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT)
+ if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
~APMG_PS_CTRL_MSK_PWR_SRC);
@@ -1135,7 +961,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
/* Rx interrupt, but nothing sent from uCode */
if (i == r)
- IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d\n", r, i);
+ IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
fill_rx = 1;
@@ -1175,12 +1001,12 @@ void iwl_rx_handle(struct iwl_priv *priv)
* handle those that need handling via function in
* rx_handlers table. See iwl_setup_rx_handlers() */
if (priv->rx_handlers[pkt->hdr.cmd]) {
- IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d, %s, 0x%02x\n", r,
+ IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
} else {
/* No handling needed */
- IWL_DEBUG(IWL_DL_RX,
+ IWL_DEBUG_RX(priv,
"r %d i %d No handler needed for %s, 0x%02x\n",
r, i, get_cmd_string(pkt->hdr.cmd),
pkt->hdr.cmd);
@@ -1193,7 +1019,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
if (rxb && rxb->skb)
iwl_tx_cmd_complete(priv, rxb);
else
- IWL_WARNING("Claim null rxb?\n");
+ IWL_WARN(priv, "Claim null rxb?\n");
}
/* For now we just don't re-use anything. We can tweak this
@@ -1229,27 +1055,6 @@ void iwl_rx_handle(struct iwl_priv *priv)
iwl_rx_queue_restock(priv);
}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
-{
- struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
-
- IWL_DEBUG_RADIO("RX CONFIG:\n");
- iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
- IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
- IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
- IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n",
- le32_to_cpu(rxon->filter_flags));
- IWL_DEBUG_RADIO("u8 dev_type: 0x%x\n", rxon->dev_type);
- IWL_DEBUG_RADIO("u8 ofdm_basic_rates: 0x%02x\n",
- rxon->ofdm_basic_rates);
- IWL_DEBUG_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
- IWL_DEBUG_RADIO("u8[6] node_addr: %pM\n", rxon->node_addr);
- IWL_DEBUG_RADIO("u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
- IWL_DEBUG_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
-}
-#endif
-
/* call this function to flush any scheduled tasklet */
static inline void iwl_synchronize_irq(struct iwl_priv *priv)
{
@@ -1258,45 +1063,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
tasklet_kill(&priv->irq_tasklet);
}
-/**
- * iwl_irq_handle_error - called for HW or SW error interrupt from card
- */
-static void iwl_irq_handle_error(struct iwl_priv *priv)
-{
- /* Set the FW error flag -- cleared on iwl_down */
- set_bit(STATUS_FW_ERROR, &priv->status);
-
- /* Cancel currently queued command. */
- clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-
-#ifdef CONFIG_IWLWIFI_DEBUG
- if (priv->debug_level & IWL_DL_FW_ERRORS) {
- iwl_dump_nic_error_log(priv);
- iwl_dump_nic_event_log(priv);
- iwl_print_rx_config_cmd(priv);
- }
-#endif
-
- wake_up_interruptible(&priv->wait_command_queue);
-
- /* Keep the restart process from trying to send host
- * commands by clearing the INIT status bit */
- clear_bit(STATUS_READY, &priv->status);
-
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG(IWL_DL_FW_ERRORS,
- "Restarting adapter due to uCode error.\n");
-
- if (iwl_is_associated(priv)) {
- memcpy(&priv->recovery_rxon, &priv->active_rxon,
- sizeof(priv->recovery_rxon));
- priv->error_recovering = 1;
- }
- if (priv->cfg->mod_params->restart_fw)
- queue_work(priv->workqueue, &priv->restart);
- }
-}
-
static void iwl_error_recovery(struct iwl_priv *priv)
{
unsigned long flags;
@@ -1341,7 +1107,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
if (priv->debug_level & IWL_DL_ISR) {
/* just for debug */
inta_mask = iwl_read32(priv, CSR_INT_MASK);
- IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
+ IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
inta, inta_mask, inta_fh);
}
#endif
@@ -1357,7 +1123,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Now service all interrupt bits discovered above. */
if (inta & CSR_INT_BIT_HW_ERR) {
- IWL_ERROR("Microcode HW error detected. Restarting.\n");
+ IWL_ERR(priv, "Microcode HW error detected. Restarting.\n");
/* Tell the device to stop sending interrupts */
iwl_disable_interrupts(priv);
@@ -1375,12 +1141,12 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
if (priv->debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
if (inta & CSR_INT_BIT_SCD)
- IWL_DEBUG_ISR("Scheduler finished to transmit "
+ IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
"the frame/frames.\n");
/* Alive notification via Rx interrupt will do the real work */
if (inta & CSR_INT_BIT_ALIVE)
- IWL_DEBUG_ISR("Alive interrupt\n");
+ IWL_DEBUG_ISR(priv, "Alive interrupt\n");
}
#endif
/* Safely ignore these bits for debug checks below */
@@ -1393,17 +1159,20 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
hw_rf_kill = 1;
- IWL_DEBUG(IWL_DL_RF_KILL, "RF_KILL bit toggled to %s.\n",
+ IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
hw_rf_kill ? "disable radio" : "enable radio");
/* driver only loads ucode once setting the interface up.
- * the driver as well won't allow loading if RFKILL is set
- * therefore no need to restart the driver from this handler
+ * the driver allows loading the ucode even if the radio
+ * is killed. Hence update the killswitch state here. The
+ * rfkill handler will care about restarting if needed.
*/
- if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) {
- clear_bit(STATUS_RF_KILL_HW, &priv->status);
- if (priv->is_open && !iwl_is_rfkill(priv))
- queue_work(priv->workqueue, &priv->up);
+ if (!test_bit(STATUS_ALIVE, &priv->status)) {
+ if (hw_rf_kill)
+ set_bit(STATUS_RF_KILL_HW, &priv->status);
+ else
+ clear_bit(STATUS_RF_KILL_HW, &priv->status);
+ queue_work(priv->workqueue, &priv->rf_kill);
}
handled |= CSR_INT_BIT_RF_KILL;
@@ -1411,21 +1180,21 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
/* Chip got too hot and stopped itself */
if (inta & CSR_INT_BIT_CT_KILL) {
- IWL_ERROR("Microcode CT kill error detected.\n");
+ IWL_ERR(priv, "Microcode CT kill error detected.\n");
handled |= CSR_INT_BIT_CT_KILL;
}
/* Error detected by uCode */
if (inta & CSR_INT_BIT_SW_ERR) {
- IWL_ERROR("Microcode SW error detected. Restarting 0x%X.\n",
- inta);
+ IWL_ERR(priv, "Microcode SW error detected. "
+ " Restarting 0x%X.\n", inta);
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
/* uCode wakes up after power-down sleep */
if (inta & CSR_INT_BIT_WAKEUP) {
- IWL_DEBUG_ISR("Wakeup interrupt\n");
+ IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
iwl_txq_update_write_ptr(priv, &priv->txq[0]);
iwl_txq_update_write_ptr(priv, &priv->txq[1]);
@@ -1446,7 +1215,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
}
if (inta & CSR_INT_BIT_FH_TX) {
- IWL_DEBUG_ISR("Tx interrupt\n");
+ IWL_DEBUG_ISR(priv, "Tx interrupt\n");
handled |= CSR_INT_BIT_FH_TX;
/* FH finished to write, send event */
priv->ucode_write_complete = 1;
@@ -1454,12 +1223,12 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
}
if (inta & ~handled)
- IWL_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
+ IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
if (inta & ~CSR_INI_SET_MASK) {
- IWL_WARNING("Disabled INTA bits 0x%08x were pending\n",
+ IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
inta & ~CSR_INI_SET_MASK);
- IWL_WARNING(" with FH_INT = 0x%08x\n", inta_fh);
+ IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh);
}
/* Re-enable all interrupts */
@@ -1472,71 +1241,13 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
inta = iwl_read32(priv, CSR_INT);
inta_mask = iwl_read32(priv, CSR_INT_MASK);
inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
- IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
+ IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
"flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
}
#endif
spin_unlock_irqrestore(&priv->lock, flags);
}
-static irqreturn_t iwl_isr(int irq, void *data)
-{
- struct iwl_priv *priv = data;
- u32 inta, inta_mask;
- u32 inta_fh;
- if (!priv)
- return IRQ_NONE;
-
- spin_lock(&priv->lock);
-
- /* Disable (but don't clear!) interrupts here to avoid
- * back-to-back ISRs and sporadic interrupts from our NIC.
- * If we have something to service, the tasklet will re-enable ints.
- * If we *don't* have something, we'll re-enable before leaving here. */
- inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
- iwl_write32(priv, CSR_INT_MASK, 0x00000000);
-
- /* Discover which interrupts are active/pending */
- inta = iwl_read32(priv, CSR_INT);
- inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
-
- /* Ignore interrupt if there's nothing in NIC to service.
- * This may be due to IRQ shared with another device,
- * or due to sporadic interrupts thrown from our NIC. */
- if (!inta && !inta_fh) {
- IWL_DEBUG_ISR("Ignore interrupt, inta == 0, inta_fh == 0\n");
- goto none;
- }
-
- if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
- /* Hardware disappeared. It might have already raised
- * an interrupt */
- IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta);
- goto unplugged;
- }
-
- IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
- inta, inta_mask, inta_fh);
-
- inta &= ~CSR_INT_BIT_SCD;
-
- /* iwl_irq_tasklet() will service interrupts and re-enable them */
- if (likely(inta || inta_fh))
- tasklet_schedule(&priv->irq_tasklet);
-
- unplugged:
- spin_unlock(&priv->lock);
- return IRQ_HANDLED;
-
- none:
- /* re-enable interrupts here since we don't have anything to service. */
- /* only Re-enable if diabled by irq */
- if (test_bit(STATUS_INT_ENABLED, &priv->status))
- iwl_enable_interrupts(priv);
- spin_unlock(&priv->lock);
- return IRQ_NONE;
-}
-
/******************************************************************************
*
* uCode download functions
@@ -1584,7 +1295,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
sprintf(buf, "%s%d%s", name_pre, index, ".ucode");
ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
if (ret < 0) {
- IWL_ERROR("%s firmware file req failed: Reason %d\n",
+ IWL_ERR(priv, "%s firmware file req failed: %d\n",
buf, ret);
if (ret == -ENOENT)
continue;
@@ -1592,9 +1303,12 @@ static int iwl_read_ucode(struct iwl_priv *priv)
goto error;
} else {
if (index < api_max)
- IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n",
+ IWL_ERR(priv, "Loaded firmware %s, "
+ "which is deprecated. "
+ "Please use API v%u instead.\n",
buf, api_max);
- IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
+
+ IWL_DEBUG_INFO(priv, "Got firmware '%s' file (%zd bytes) from disk\n",
buf, ucode_raw->size);
break;
}
@@ -1605,7 +1319,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
/* Make sure that we got at least our header! */
if (ucode_raw->size < sizeof(*ucode)) {
- IWL_ERROR("File size way too small!\n");
+ IWL_ERR(priv, "File size way too small!\n");
ret = -EINVAL;
goto err_release;
}
@@ -1623,10 +1337,10 @@ static int iwl_read_ucode(struct iwl_priv *priv)
/* api_ver should match the api version forming part of the
* firmware filename ... but we don't check for that and only rely
- * on the API version read from firware header from here on forward */
+ * on the API version read from firmware header from here on forward */
if (api_ver < api_min || api_ver > api_max) {
- IWL_ERROR("Driver unable to support your firmware API. "
+ IWL_ERR(priv, "Driver unable to support your firmware API. "
"Driver supports v%u, firmware is v%u.\n",
api_max, api_ver);
priv->ucode_ver = 0;
@@ -1634,28 +1348,28 @@ static int iwl_read_ucode(struct iwl_priv *priv)
goto err_release;
}
if (api_ver != api_max)
- IWL_ERROR("Firmware has old API version. Expected v%u, "
+ IWL_ERR(priv, "Firmware has old API version. Expected v%u, "
"got v%u. New firmware can be obtained "
"from http://www.intellinuxwireless.org.\n",
api_max, api_ver);
- printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n",
- IWL_UCODE_MAJOR(priv->ucode_ver),
- IWL_UCODE_MINOR(priv->ucode_ver),
- IWL_UCODE_API(priv->ucode_ver),
- IWL_UCODE_SERIAL(priv->ucode_ver));
+ IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n",
+ IWL_UCODE_MAJOR(priv->ucode_ver),
+ IWL_UCODE_MINOR(priv->ucode_ver),
+ IWL_UCODE_API(priv->ucode_ver),
+ IWL_UCODE_SERIAL(priv->ucode_ver));
- IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n",
+ IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
priv->ucode_ver);
- IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n",
+ IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
inst_size);
- IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n",
+ IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n",
data_size);
- IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n",
+ IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n",
init_size);
- IWL_DEBUG_INFO("f/w package hdr init data size = %u\n",
+ IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n",
init_data_size);
- IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n",
+ IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
boot_size);
/* Verify size of file vs. image size info in file's header */
@@ -1663,7 +1377,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
inst_size + data_size + init_size +
init_data_size + boot_size) {
- IWL_DEBUG_INFO("uCode file size %d too small\n",
+ IWL_DEBUG_INFO(priv, "uCode file size %d too small\n",
(int)ucode_raw->size);
ret = -EINVAL;
goto err_release;
@@ -1671,36 +1385,33 @@ static int iwl_read_ucode(struct iwl_priv *priv)
/* Verify that uCode images will fit in card's SRAM */
if (inst_size > priv->hw_params.max_inst_size) {
- IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n",
+ IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
inst_size);
ret = -EINVAL;
goto err_release;
}
if (data_size > priv->hw_params.max_data_size) {
- IWL_DEBUG_INFO("uCode data len %d too large to fit in\n",
+ IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
data_size);
ret = -EINVAL;
goto err_release;
}
if (init_size > priv->hw_params.max_inst_size) {
- IWL_DEBUG_INFO
- ("uCode init instr len %d too large to fit in\n",
- init_size);
+ IWL_INFO(priv, "uCode init instr len %d too large to fit in\n",
+ init_size);
ret = -EINVAL;
goto err_release;
}
if (init_data_size > priv->hw_params.max_data_size) {
- IWL_DEBUG_INFO
- ("uCode init data len %d too large to fit in\n",
+ IWL_INFO(priv, "uCode init data len %d too large to fit in\n",
init_data_size);
ret = -EINVAL;
goto err_release;
}
if (boot_size > priv->hw_params.max_bsm_size) {
- IWL_DEBUG_INFO
- ("uCode boot instr len %d too large to fit in\n",
- boot_size);
+ IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n",
+ boot_size);
ret = -EINVAL;
goto err_release;
}
@@ -1749,16 +1460,16 @@ static int iwl_read_ucode(struct iwl_priv *priv)
/* Runtime instructions (first block of data in file) */
src = &ucode->data[0];
len = priv->ucode_code.len;
- IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %Zd\n", len);
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len);
memcpy(priv->ucode_code.v_addr, src, len);
- IWL_DEBUG_INFO("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
+ IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
/* Runtime data (2nd block)
* NOTE: Copy into backup buffer will be done in iwl_up() */
src = &ucode->data[inst_size];
len = priv->ucode_data.len;
- IWL_DEBUG_INFO("Copying (but not loading) uCode data len %Zd\n", len);
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len);
memcpy(priv->ucode_data.v_addr, src, len);
memcpy(priv->ucode_data_backup.v_addr, src, len);
@@ -1766,7 +1477,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
if (init_size) {
src = &ucode->data[inst_size + data_size];
len = priv->ucode_init.len;
- IWL_DEBUG_INFO("Copying (but not loading) init instr len %Zd\n",
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
len);
memcpy(priv->ucode_init.v_addr, src, len);
}
@@ -1775,7 +1486,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
if (init_data_size) {
src = &ucode->data[inst_size + data_size + init_size];
len = priv->ucode_init_data.len;
- IWL_DEBUG_INFO("Copying (but not loading) init data len %Zd\n",
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
len);
memcpy(priv->ucode_init_data.v_addr, src, len);
}
@@ -1783,7 +1494,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
/* Bootstrap instructions (5th block) */
src = &ucode->data[inst_size + data_size + init_size + init_data_size];
len = priv->ucode_boot.len;
- IWL_DEBUG_INFO("Copying (but not loading) boot instr len %Zd\n", len);
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
memcpy(priv->ucode_boot.v_addr, src, len);
/* We have our copies now, allow OS release its copies */
@@ -1791,7 +1502,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
return 0;
err_pci_alloc:
- IWL_ERROR("failed to allocate pci memory\n");
+ IWL_ERR(priv, "failed to allocate pci memory\n");
ret = -ENOMEM;
iwl_dealloc_ucode_pci(priv);
@@ -1815,12 +1526,12 @@ static void iwl_alive_start(struct iwl_priv *priv)
{
int ret = 0;
- IWL_DEBUG_INFO("Runtime Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
if (priv->card_alive.is_valid != UCODE_VALID_OK) {
/* We had an error bringing up the hardware, so take it
* all the way back down so we can try again */
- IWL_DEBUG_INFO("Alive failed.\n");
+ IWL_DEBUG_INFO(priv, "Alive failed.\n");
goto restart;
}
@@ -1830,15 +1541,15 @@ static void iwl_alive_start(struct iwl_priv *priv)
if (iwl_verify_ucode(priv)) {
/* Runtime instruction load was bad;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Bad runtime uCode load.\n");
+ IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n");
goto restart;
}
iwl_clear_stations_table(priv);
ret = priv->cfg->ops->lib->alive_notify(priv);
if (ret) {
- IWL_WARNING("Could not complete ALIVE transition [ntf]: %d\n",
- ret);
+ IWL_WARN(priv,
+ "Could not complete ALIVE transition [ntf]: %d\n", ret);
goto restart;
}
@@ -1856,13 +1567,13 @@ static void iwl_alive_start(struct iwl_priv *priv)
if (iwl_is_associated(priv)) {
struct iwl_rxon_cmd *active_rxon =
(struct iwl_rxon_cmd *)&priv->active_rxon;
-
- memcpy(&priv->staging_rxon, &priv->active_rxon,
- sizeof(priv->staging_rxon));
+ /* apply any changes in staging */
+ priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
} else {
/* Initialize our rx_config data */
iwl_connection_init_rx_config(priv, priv->iw_mode);
+ iwl_set_rxon_chain(priv);
memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
}
@@ -1879,7 +1590,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl_leds_register(priv);
- IWL_DEBUG_INFO("ALIVE processing complete.\n");
+ IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
set_bit(STATUS_READY, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
@@ -1913,7 +1624,7 @@ static void __iwl_down(struct iwl_priv *priv)
unsigned long flags;
int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
- IWL_DEBUG_INFO(DRV_NAME " is going down\n");
+ IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
if (!exit_pending)
set_bit(STATUS_EXIT_PENDING, &priv->status);
@@ -2024,12 +1735,12 @@ static int __iwl_up(struct iwl_priv *priv)
int ret;
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_WARNING("Exit pending; will not bring the NIC up\n");
+ IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
return -EIO;
}
if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
- IWL_ERROR("ucode not available for device bringup\n");
+ IWL_ERR(priv, "ucode not available for device bringup\n");
return -EIO;
}
@@ -2041,7 +1752,7 @@ static int __iwl_up(struct iwl_priv *priv)
if (iwl_is_rfkill(priv)) {
iwl_enable_interrupts(priv);
- IWL_WARNING("Radio disabled by %s RF Kill switch\n",
+ IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n",
test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
return 0;
}
@@ -2050,7 +1761,7 @@ static int __iwl_up(struct iwl_priv *priv)
ret = iwl_hw_nic_init(priv);
if (ret) {
- IWL_ERROR("Unable to init nic\n");
+ IWL_ERR(priv, "Unable to init nic\n");
return ret;
}
@@ -2083,7 +1794,8 @@ static int __iwl_up(struct iwl_priv *priv)
ret = priv->cfg->ops->lib->load_ucode(priv);
if (ret) {
- IWL_ERROR("Unable to set up bootstrap uCode: %d\n", ret);
+ IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n",
+ ret);
continue;
}
@@ -2093,7 +1805,7 @@ static int __iwl_up(struct iwl_priv *priv)
/* start card; "initialize" will load runtime ucode */
iwl_nic_start(priv);
- IWL_DEBUG_INFO(DRV_NAME " is coming up\n");
+ IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
return 0;
}
@@ -2104,7 +1816,7 @@ static int __iwl_up(struct iwl_priv *priv)
/* tried to restart and config the device for as long as our
* patience could withstand */
- IWL_ERROR("Unable to initialize device after %d attempts.\n", i);
+ IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
return -EIO;
}
@@ -2141,40 +1853,6 @@ static void iwl_bg_alive_start(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-static void iwl_bg_rf_kill(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);
-
- wake_up_interruptible(&priv->wait_command_queue);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
-
- if (!iwl_is_rfkill(priv)) {
- IWL_DEBUG(IWL_DL_RF_KILL,
- "HW and/or SW RF Kill no longer active, restarting "
- "device\n");
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
- queue_work(priv->workqueue, &priv->restart);
- } else {
- /* make sure mac80211 stop sending Tx frame */
- if (priv->mac80211_registered)
- ieee80211_stop_queues(priv->hw);
-
- if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
- IWL_DEBUG_RF_KILL("Can not turn radio back on - "
- "disabled by SW switch\n");
- else
- IWL_WARNING("Radio Frequency Kill Switch is On:\n"
- "Kill switch must be turned off for "
- "wireless networking to work.\n");
- }
- mutex_unlock(&priv->mutex);
- iwl_rfkill_set_hw_state(priv);
-}
-
static void iwl_bg_run_time_calib_work(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv,
@@ -2244,11 +1922,11 @@ static void iwl_post_associate(struct iwl_priv *priv)
unsigned long flags;
if (priv->iw_mode == NL80211_IFTYPE_AP) {
- IWL_ERROR("%s Should not be called in AP mode\n", __func__);
+ IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
return;
}
- IWL_DEBUG_ASSOC("Associated as %d to: %pM\n",
+ IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
priv->assoc_id, priv->active_rxon.bssid_addr);
@@ -2271,7 +1949,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (ret)
- IWL_WARNING("REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
@@ -2281,7 +1959,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
iwl_set_rxon_chain(priv);
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
- IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n",
+ IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
priv->assoc_id, priv->beacon_int);
if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
@@ -2317,7 +1995,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
break;
default:
- IWL_ERROR("%s Should not be called in %d mode\n",
+ IWL_ERR(priv, "%s Should not be called in %d mode\n",
__func__, priv->iw_mode);
break;
}
@@ -2353,30 +2031,8 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
int ret;
- u16 pci_cmd;
- IWL_DEBUG_MAC80211("enter\n");
-
- if (pci_enable_device(priv->pci_dev)) {
- IWL_ERROR("Fail to pci_enable_device\n");
- return -ENODEV;
- }
- pci_restore_state(priv->pci_dev);
- pci_enable_msi(priv->pci_dev);
-
- /* enable interrupts if needed: hw bug w/a */
- pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
- if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
- pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
- pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
- }
-
- ret = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
- DRV_NAME, priv);
- if (ret) {
- IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq);
- goto out_disable_msi;
- }
+ IWL_DEBUG_MAC80211(priv, "enter\n");
/* we should be verifying the device is ready to be opened */
mutex_lock(&priv->mutex);
@@ -2388,9 +2044,9 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
if (!priv->ucode_code.len) {
ret = iwl_read_ucode(priv);
if (ret) {
- IWL_ERROR("Could not read microcode: %d\n", ret);
+ IWL_ERR(priv, "Could not read microcode: %d\n", ret);
mutex_unlock(&priv->mutex);
- goto out_release_irq;
+ return ret;
}
}
@@ -2401,12 +2057,12 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
iwl_rfkill_set_hw_state(priv);
if (ret)
- goto out_release_irq;
+ return ret;
if (iwl_is_rfkill(priv))
goto out;
- IWL_DEBUG_INFO("Start UP work done.\n");
+ IWL_DEBUG_INFO(priv, "Start UP work done.\n");
if (test_bit(STATUS_IN_SUSPEND, &priv->status))
return 0;
@@ -2418,36 +2074,26 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
UCODE_READY_TIMEOUT);
if (!ret) {
if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_ERROR("START_ALIVE timeout after %dms.\n",
+ IWL_ERR(priv, "START_ALIVE timeout after %dms.\n",
jiffies_to_msecs(UCODE_READY_TIMEOUT));
- ret = -ETIMEDOUT;
- goto out_release_irq;
+ return -ETIMEDOUT;
}
}
out:
priv->is_open = 1;
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
-
-out_release_irq:
- free_irq(priv->pci_dev->irq, priv);
-out_disable_msi:
- pci_disable_msi(priv->pci_dev);
- pci_disable_device(priv->pci_dev);
- priv->is_open = 0;
- IWL_DEBUG_MAC80211("leave - failed\n");
- return ret;
}
static void iwl_mac_stop(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
if (!priv->is_open) {
- IWL_DEBUG_MAC80211("leave - skip\n");
+ IWL_DEBUG_MAC80211(priv, "leave - skip\n");
return;
}
@@ -2465,27 +2111,27 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
iwl_down(priv);
flush_workqueue(priv->workqueue);
- free_irq(priv->pci_dev->irq, priv);
- pci_disable_msi(priv->pci_dev);
- pci_save_state(priv->pci_dev);
- pci_disable_device(priv->pci_dev);
- IWL_DEBUG_MAC80211("leave\n");
+ /* enable interrupts again in order to receive rfkill changes */
+ iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+ iwl_enable_interrupts(priv);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MACDUMP("enter\n");
+ IWL_DEBUG_MACDUMP(priv, "enter\n");
- IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
+ IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
if (iwl_tx_skb(priv, skb))
dev_kfree_skb_any(skb);
- IWL_DEBUG_MACDUMP("leave\n");
+ IWL_DEBUG_MACDUMP(priv, "leave\n");
return NETDEV_TX_OK;
}
@@ -2495,10 +2141,10 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw,
struct iwl_priv *priv = hw->priv;
unsigned long flags;
- IWL_DEBUG_MAC80211("enter: type %d\n", conf->type);
+ IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
if (priv->vif) {
- IWL_DEBUG_MAC80211("leave - vif != NULL\n");
+ IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
return -EOPNOTSUPP;
}
@@ -2511,7 +2157,7 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
if (conf->mac_addr) {
- IWL_DEBUG_MAC80211("Set %pM\n", conf->mac_addr);
+ IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
}
@@ -2521,7 +2167,7 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw,
mutex_unlock(&priv->mutex);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
@@ -2537,117 +2183,122 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
struct iwl_priv *priv = hw->priv;
const struct iwl_channel_info *ch_info;
struct ieee80211_conf *conf = &hw->conf;
- unsigned long flags;
+ unsigned long flags = 0;
int ret = 0;
- u16 channel;
+ u16 ch;
+ int scan_active = 0;
mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);
-
- priv->current_ht_config.is_ht = conf->ht.enabled;
+ IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
+ conf->channel->hw_value, changed);
- if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) {
- IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n");
- goto out;
+ if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
+ test_bit(STATUS_SCANNING, &priv->status))) {
+ scan_active = 1;
+ IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
}
- if (!conf->radio_enabled)
- iwl_radio_kill_sw_disable_radio(priv);
- if (!iwl_is_ready(priv)) {
- IWL_DEBUG_MAC80211("leave - not ready\n");
- ret = -EIO;
- goto out;
- }
+ /* during scanning mac80211 will delay channel setting until
+ * scan finish with changed = 0
+ */
+ if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
+ if (scan_active)
+ goto set_ch_out;
+
+ ch = ieee80211_frequency_to_channel(conf->channel->center_freq);
+ ch_info = iwl_get_channel_info(priv, conf->channel->band, ch);
+ if (!is_channel_valid(ch_info)) {
+ IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
+ ret = -EINVAL;
+ goto set_ch_out;
+ }
- if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
- test_bit(STATUS_SCANNING, &priv->status))) {
- IWL_DEBUG_MAC80211("leave - scanning\n");
- mutex_unlock(&priv->mutex);
- return 0;
- }
+ if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
+ !is_channel_ibss(ch_info)) {
+ IWL_ERR(priv, "channel %d in band %d not "
+ "IBSS channel\n",
+ conf->channel->hw_value, conf->channel->band);
+ ret = -EINVAL;
+ goto set_ch_out;
+ }
- channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
- ch_info = iwl_get_channel_info(priv, conf->channel->band, channel);
- if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_MAC80211("leave - invalid channel\n");
- ret = -EINVAL;
- goto out;
- }
+ priv->current_ht_config.is_ht = conf_is_ht(conf);
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
- !is_channel_ibss(ch_info)) {
- IWL_ERROR("channel %d in band %d not IBSS channel\n",
- conf->channel->hw_value, conf->channel->band);
- ret = -EINVAL;
- goto out;
- }
+ spin_lock_irqsave(&priv->lock, flags);
- spin_lock_irqsave(&priv->lock, flags);
+ /* if we are switching from ht to 2.4 clear flags
+ * from any ht related info since 2.4 does not
+ * support ht */
+ if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
+ priv->staging_rxon.flags = 0;
- /* if we are switching from ht to 2.4 clear flags
- * from any ht related info since 2.4 does not
- * support ht */
- if ((le16_to_cpu(priv->staging_rxon.channel) != channel)
-#ifdef IEEE80211_CONF_CHANNEL_SWITCH
- && !(conf->flags & IEEE80211_CONF_CHANNEL_SWITCH)
-#endif
- )
- priv->staging_rxon.flags = 0;
+ iwl_set_rxon_channel(priv, conf->channel);
- iwl_set_rxon_channel(priv, conf->channel);
+ iwl_set_flags_for_band(priv, conf->channel->band);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ set_ch_out:
+ /* The list of supported rates and rate mask can be different
+ * for each band; since the band may have changed, reset
+ * the rate mask to what mac80211 lists */
+ iwl_set_rate(priv);
+ }
- iwl_set_flags_for_band(priv, conf->channel->band);
+ if (changed & IEEE80211_CONF_CHANGE_PS) {
+ if (conf->flags & IEEE80211_CONF_PS)
+ ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3);
+ else
+ ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM);
+ if (ret)
+ IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
- /* The list of supported rates and rate mask can be different
- * for each band; since the band may have changed, reset
- * the rate mask to what mac80211 lists */
- iwl_set_rate(priv);
+ }
- spin_unlock_irqrestore(&priv->lock, flags);
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
+ IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
+ priv->tx_power_user_lmt, conf->power_level);
-#ifdef IEEE80211_CONF_CHANNEL_SWITCH
- if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
- iwl_hw_channel_switch(priv, conf->channel);
- goto out;
+ iwl_set_tx_power(priv, conf->power_level, false);
+ }
+
+ /* call to ensure that 4965 rx_chain is set properly in monitor mode */
+ iwl_set_rxon_chain(priv);
+
+ if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
+ if (conf->radio_enabled &&
+ iwl_radio_kill_sw_enable_radio(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
+ "waiting for uCode\n");
+ goto out;
+ }
+
+ if (!conf->radio_enabled)
+ iwl_radio_kill_sw_disable_radio(priv);
}
-#endif
if (!conf->radio_enabled) {
- IWL_DEBUG_MAC80211("leave - radio disabled\n");
+ IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
goto out;
}
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_MAC80211("leave - RF kill\n");
- ret = -EIO;
+ if (!iwl_is_ready(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
goto out;
}
- if (conf->flags & IEEE80211_CONF_PS)
- ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3);
- else
- ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM);
- if (ret)
- IWL_DEBUG_MAC80211("Error setting power level\n");
-
- IWL_DEBUG_MAC80211("TX Power old=%d new=%d\n",
- priv->tx_power_user_lmt, conf->power_level);
-
- iwl_set_tx_power(priv, conf->power_level, false);
-
- iwl_set_rate(priv);
+ if (scan_active)
+ goto out;
if (memcmp(&priv->active_rxon,
&priv->staging_rxon, sizeof(priv->staging_rxon)))
iwl_commit_rxon(priv);
else
- IWL_DEBUG_INFO("No re-sending same RXON configuration.\n");
+ IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n");
- IWL_DEBUG_MAC80211("leave\n");
out:
+ IWL_DEBUG_MAC80211(priv, "leave\n");
mutex_unlock(&priv->mutex);
return ret;
}
@@ -2672,7 +2323,7 @@ static void iwl_config_ap(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (ret)
- IWL_WARNING("REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
iwl_set_rxon_chain(priv);
@@ -2726,7 +2377,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
return -EIO;
if (priv->vif != vif) {
- IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
+ IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
return 0;
}
@@ -2748,7 +2399,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
if (conf->bssid)
- IWL_DEBUG_MAC80211("bssid: %pM\n", conf->bssid);
+ IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
/*
* very dubious code was here; the probe filtering flag is never set:
@@ -2761,7 +2412,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
if (!conf->bssid) {
conf->bssid = priv->mac_addr;
memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
- IWL_DEBUG_MAC80211("bssid was set to: %pM\n",
+ IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
conf->bssid);
}
if (priv->ibss_beacon)
@@ -2778,9 +2429,9 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
/* If there is currently a HW scan going on in the background
* then we need to cancel it else the RXON below will fail. */
if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARNING("Aborted scan still in progress "
+ IWL_WARN(priv, "Aborted scan still in progress "
"after 100ms\n");
- IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
+ IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
mutex_unlock(&priv->mutex);
return -EAGAIN;
}
@@ -2808,64 +2459,18 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
}
done:
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
mutex_unlock(&priv->mutex);
return 0;
}
-static void iwl_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- int mc_count, struct dev_addr_list *mc_list)
-{
- struct iwl_priv *priv = hw->priv;
- __le32 *filter_flags = &priv->staging_rxon.filter_flags;
-
- IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
- changed_flags, *total_flags);
-
- if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
- if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
- *filter_flags |= RXON_FILTER_PROMISC_MSK;
- else
- *filter_flags &= ~RXON_FILTER_PROMISC_MSK;
- }
- if (changed_flags & FIF_ALLMULTI) {
- if (*total_flags & FIF_ALLMULTI)
- *filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
- else
- *filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
- }
- if (changed_flags & FIF_CONTROL) {
- if (*total_flags & FIF_CONTROL)
- *filter_flags |= RXON_FILTER_CTL2HOST_MSK;
- else
- *filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
- }
- if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
- if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
- *filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
- else
- *filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
- }
-
- /* We avoid iwl_commit_rxon here to commit the new filter flags
- * since mac80211 will call ieee80211_hw_config immediately.
- * (mc_list is not supported at this time). Otherwise, we need to
- * queue a background iwl_commit_rxon work.
- */
-
- *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
- FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
-}
-
static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf)
{
struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
mutex_lock(&priv->mutex);
@@ -2880,7 +2485,7 @@ static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
}
mutex_unlock(&priv->mutex);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
@@ -2892,10 +2497,10 @@ static void iwl_bss_info_changed(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("changes = 0x%X\n", changes);
+ IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n",
+ IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
bss_conf->use_short_preamble);
if (bss_conf->use_short_preamble)
priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
@@ -2904,7 +2509,7 @@ static void iwl_bss_info_changed(struct ieee80211_hw *hw,
}
if (changes & BSS_CHANGED_ERP_CTS_PROT) {
- IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot);
+ IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
else
@@ -2917,7 +2522,7 @@ static void iwl_bss_info_changed(struct ieee80211_hw *hw,
}
if (changes & BSS_CHANGED_ASSOC) {
- IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->assoc);
+ IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
/* This should never happen as this function should
* never be called from interrupt context. */
if (WARN_ON_ONCE(in_interrupt()))
@@ -2939,108 +2544,49 @@ static void iwl_bss_info_changed(struct ieee80211_hw *hw,
mutex_unlock(&priv->mutex);
} else {
priv->assoc_id = 0;
- IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc);
+ IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc);
}
} else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
- IWL_DEBUG_MAC80211("Associated Changes %d\n", changes);
+ IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes);
iwl_send_rxon_assoc(priv);
}
}
-static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len)
-{
- unsigned long flags;
- struct iwl_priv *priv = hw->priv;
- int ret;
-
- IWL_DEBUG_MAC80211("enter\n");
-
- mutex_lock(&priv->mutex);
- spin_lock_irqsave(&priv->lock, flags);
-
- if (!iwl_is_ready_rf(priv)) {
- ret = -EIO;
- IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
- goto out_unlock;
- }
-
- /* We don't schedule scan within next_scan_jiffies period.
- * Avoid scanning during possible EAPOL exchange, return
- * success immediately.
- */
- if (priv->next_scan_jiffies &&
- time_after(priv->next_scan_jiffies, jiffies)) {
- IWL_DEBUG_SCAN("scan rejected: within next scan period\n");
- queue_work(priv->workqueue, &priv->scan_completed);
- ret = 0;
- goto out_unlock;
- }
-
- /* if we just finished scan ask for delay */
- if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
- time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
- IWL_DEBUG_SCAN("scan rejected: within previous scan period\n");
- queue_work(priv->workqueue, &priv->scan_completed);
- ret = 0;
- goto out_unlock;
- }
-
- if (ssid_len) {
- priv->one_direct_scan = 1;
- priv->direct_ssid_len = min_t(u8, ssid_len, IW_ESSID_MAX_SIZE);
- memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
- } else {
- priv->one_direct_scan = 0;
- }
-
- ret = iwl_scan_initiate(priv);
-
- IWL_DEBUG_MAC80211("leave\n");
-
-out_unlock:
- spin_unlock_irqrestore(&priv->lock, flags);
- mutex_unlock(&priv->mutex);
-
- return ret;
-}
-
static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
struct ieee80211_key_conf *keyconf, const u8 *addr,
u32 iv32, u16 *phase1key)
{
struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
iwl_update_tkip_key(priv, keyconf, addr, iv32, phase1key);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_addr, const u8 *addr,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
struct iwl_priv *priv = hw->priv;
- int ret = 0;
- u8 sta_id = IWL_INVALID_STATION;
- u8 is_default_wep_key = 0;
+ const u8 *addr;
+ int ret;
+ u8 sta_id;
+ bool is_default_wep_key = false;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
if (priv->hw_params.sw_crypto) {
- IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n");
+ IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
return -EOPNOTSUPP;
}
-
- if (is_zero_ether_addr(addr))
- /* only support pairwise keys */
- return -EOPNOTSUPP;
-
+ addr = sta ? sta->addr : iwl_bcast_addr;
sta_id = iwl_find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
+ IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
addr);
return -EINVAL;
@@ -3070,7 +2616,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
else
ret = iwl_set_dynamic_key(priv, key, sta_id);
- IWL_DEBUG_MAC80211("enable hwcrypto key\n");
+ IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
break;
case DISABLE_KEY:
if (is_default_wep_key)
@@ -3078,13 +2624,13 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
else
ret = iwl_remove_dynamic_key(priv, key, sta_id);
- IWL_DEBUG_MAC80211("disable hwcrypto key\n");
+ IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
break;
default:
ret = -EINVAL;
}
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return ret;
}
@@ -3096,15 +2642,15 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
unsigned long flags;
int q;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - RF not ready\n");
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
return -EIO;
}
if (queue >= AC_NUM) {
- IWL_DEBUG_MAC80211("leave - queue >= AC_NUM %d\n", queue);
+ IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
return 0;
}
@@ -3128,7 +2674,7 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
@@ -3137,8 +2683,9 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u16 tid, u16 *ssn)
{
struct iwl_priv *priv = hw->priv;
+ int ret;
- IWL_DEBUG_HT("A-MPDU action on addr %pM tid %d\n",
+ IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
sta->addr, tid);
if (!(priv->cfg->sku & IWL_SKU_N))
@@ -3146,19 +2693,27 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
switch (action) {
case IEEE80211_AMPDU_RX_START:
- IWL_DEBUG_HT("start Rx\n");
+ IWL_DEBUG_HT(priv, "start Rx\n");
return iwl_sta_rx_agg_start(priv, sta->addr, tid, *ssn);
case IEEE80211_AMPDU_RX_STOP:
- IWL_DEBUG_HT("stop Rx\n");
- return iwl_sta_rx_agg_stop(priv, sta->addr, tid);
+ IWL_DEBUG_HT(priv, "stop Rx\n");
+ ret = iwl_sta_rx_agg_stop(priv, sta->addr, tid);
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return 0;
+ else
+ return ret;
case IEEE80211_AMPDU_TX_START:
- IWL_DEBUG_HT("start Tx\n");
+ IWL_DEBUG_HT(priv, "start Tx\n");
return iwl_tx_agg_start(priv, sta->addr, tid, ssn);
case IEEE80211_AMPDU_TX_STOP:
- IWL_DEBUG_HT("stop Tx\n");
- return iwl_tx_agg_stop(priv, sta->addr, tid);
+ IWL_DEBUG_HT(priv, "stop Tx\n");
+ ret = iwl_tx_agg_stop(priv, sta->addr, tid);
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return 0;
+ else
+ return ret;
default:
- IWL_DEBUG_HT("unknown\n");
+ IWL_DEBUG_HT(priv, "unknown\n");
return -EINVAL;
break;
}
@@ -3174,10 +2729,10 @@ static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
struct iwl_queue *q;
unsigned long flags;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - RF not ready\n");
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
return -EIO;
}
@@ -3195,7 +2750,7 @@ static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
}
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
@@ -3206,8 +2761,8 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw,
struct iwl_priv *priv = hw->priv;
priv = hw->priv;
- IWL_DEBUG_MAC80211("enter\n");
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
@@ -3218,7 +2773,7 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
unsigned long flags;
mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
spin_lock_irqsave(&priv->lock, flags);
memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
@@ -3245,7 +2800,7 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
spin_unlock_irqrestore(&priv->lock, flags);
if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - not ready\n");
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
mutex_unlock(&priv->mutex);
return;
}
@@ -3274,7 +2829,7 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
IEEE80211_CHAN_RADAR))
iwl_power_disable_management(priv, 3000);
- IWL_DEBUG_MAC80211("leave - not in IBSS\n");
+ IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
mutex_unlock(&priv->mutex);
return;
}
@@ -3283,7 +2838,7 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
mutex_unlock(&priv->mutex);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
@@ -3292,15 +2847,15 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
unsigned long flags;
__le64 timestamp;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - RF not ready\n");
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
return -EIO;
}
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
- IWL_DEBUG_MAC80211("leave - not IBSS\n");
+ IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
return -EIO;
}
@@ -3315,7 +2870,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
priv->timestamp = le64_to_cpu(timestamp);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
spin_unlock_irqrestore(&priv->lock, flags);
iwl_reset_qos(priv);
@@ -3359,8 +2914,7 @@ static ssize_t store_debug_level(struct device *d,
ret = strict_strtoul(buf, 0, &val);
if (ret)
- printk(KERN_INFO DRV_NAME
- ": %s is not in hex or decimal form.\n", buf);
+ IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf);
else
priv->debug_level = val;
@@ -3439,8 +2993,7 @@ static ssize_t store_tx_power(struct device *d,
ret = strict_strtoul(buf, 10, &val);
if (ret)
- printk(KERN_INFO DRV_NAME
- ": %s is not in decimal form.\n", buf);
+ IWL_INFO(priv, "%s is not in decimal form.\n", buf);
else
iwl_set_tx_power(priv, val, false);
@@ -3473,9 +3026,9 @@ static ssize_t store_flags(struct device *d,
if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
/* Cancel any currently running scans... */
if (iwl_scan_cancel_timeout(priv, 100))
- IWL_WARNING("Could not cancel scan.\n");
+ IWL_WARN(priv, "Could not cancel scan.\n");
else {
- IWL_DEBUG_INFO("Commit rxon.flags = 0x%04X\n", flags);
+ IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags);
priv->staging_rxon.flags = cpu_to_le32(flags);
iwl_commit_rxon(priv);
}
@@ -3512,9 +3065,9 @@ static ssize_t store_filter_flags(struct device *d,
if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
/* Cancel any currently running scans... */
if (iwl_scan_cancel_timeout(priv, 100))
- IWL_WARNING("Could not cancel scan.\n");
+ IWL_WARN(priv, "Could not cancel scan.\n");
else {
- IWL_DEBUG_INFO("Committing rxon.filter_flags = "
+ IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = "
"0x%04X\n", filter_flags);
priv->staging_rxon.filter_flags =
cpu_to_le32(filter_flags);
@@ -3529,31 +3082,6 @@ static ssize_t store_filter_flags(struct device *d,
static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
store_filter_flags);
-static ssize_t store_retry_rate(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct iwl_priv *priv = dev_get_drvdata(d);
- long val;
- int ret = strict_strtol(buf, 10, &val);
- if (!ret)
- return ret;
-
- priv->retry_rate = (val > 0) ? val : 1;
-
- return count;
-}
-
-static ssize_t show_retry_rate(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwl_priv *priv = dev_get_drvdata(d);
- return sprintf(buf, "%d", priv->retry_rate);
-}
-
-static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate,
- store_retry_rate);
-
static ssize_t store_power_level(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -3565,18 +3093,13 @@ static ssize_t store_power_level(struct device *d,
mutex_lock(&priv->mutex);
- if (!iwl_is_ready(priv)) {
- ret = -EAGAIN;
- goto out;
- }
-
ret = strict_strtoul(buf, 10, &mode);
if (ret)
goto out;
ret = iwl_power_set_user_mode(priv, mode);
if (ret) {
- IWL_DEBUG_MAC80211("failed setting power mode.\n");
+ IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
goto out;
}
ret = count;
@@ -3656,16 +3179,6 @@ static ssize_t show_statistics(struct device *d,
static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
-static ssize_t show_status(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- if (!iwl_is_alive(priv))
- return -EAGAIN;
- return sprintf(buf, "0x%08x\n", (int)priv->status);
-}
-
-static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
/*****************************************************************************
*
@@ -3675,7 +3188,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
static void iwl_setup_deferred_work(struct iwl_priv *priv)
{
- priv->workqueue = create_workqueue(DRV_NAME);
+ priv->workqueue = create_singlethread_workqueue(DRV_NAME);
init_waitqueue_head(&priv->wait_command_queue);
@@ -3719,9 +3232,7 @@ static struct attribute *iwl_sysfs_entries[] = {
&dev_attr_flags.attr,
&dev_attr_filter_flags.attr,
&dev_attr_power_level.attr,
- &dev_attr_retry_rate.attr,
&dev_attr_statistics.attr,
- &dev_attr_status.attr,
&dev_attr_temperature.attr,
&dev_attr_tx_power.attr,
#ifdef CONFIG_IWLWIFI_DEBUG
@@ -3764,6 +3275,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct ieee80211_hw *hw;
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
unsigned long flags;
+ u16 pci_cmd;
/************************
* 1. Allocating HW data
@@ -3788,7 +3300,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
SET_IEEE80211_DEV(hw, &pdev->dev);
- IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
+ IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
priv->cfg = cfg;
priv->pci_dev = pdev;
@@ -3816,8 +3328,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
/* both attempts failed: */
if (err) {
- printk(KERN_WARNING "%s: No suitable DMA available.\n",
- DRV_NAME);
+ IWL_WARN(priv, "No suitable DMA available.\n");
goto out_pci_disable_device;
}
}
@@ -3838,13 +3349,12 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto out_pci_release_regions;
}
- IWL_DEBUG_INFO("pci_resource_len = 0x%08llx\n",
+ IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n",
(unsigned long long) pci_resource_len(pdev, 0));
- IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base);
+ IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base);
iwl_hw_detect(priv);
- printk(KERN_INFO DRV_NAME
- ": Detected Intel Wireless WiFi Link %s REV=0x%X\n",
+ IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n",
priv->cfg->name, priv->hw_rev);
/* We disable the RETRY_TIMEOUT register (0x41) to keep
@@ -3854,7 +3364,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* amp init */
err = priv->cfg->ops->lib->apm_ops.init(priv);
if (err < 0) {
- IWL_DEBUG_INFO("Failed to init APMG\n");
+ IWL_ERR(priv, "Failed to init APMG\n");
goto out_iounmap;
}
/*****************
@@ -3863,7 +3373,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Read the EEPROM */
err = iwl_eeprom_init(priv);
if (err) {
- IWL_ERROR("Unable to init EEPROM\n");
+ IWL_ERR(priv, "Unable to init EEPROM\n");
goto out_iounmap;
}
err = iwl_eeprom_check_version(priv);
@@ -3872,14 +3382,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* extract MAC Address */
iwl_eeprom_get_mac(priv, priv->mac_addr);
- IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr);
+ IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->mac_addr);
SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
/************************
* 5. Setup HW constants
************************/
if (iwl_set_hw_params(priv)) {
- IWL_ERROR("failed to set hw parameters\n");
+ IWL_ERR(priv, "failed to set hw parameters\n");
goto out_free_eeprom;
}
@@ -3899,7 +3409,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Disable radio (SW RF KILL) via parameter when loading driver */
if (priv->cfg->mod_params->disable) {
set_bit(STATUS_RF_KILL_SW, &priv->status);
- IWL_DEBUG_INFO("Radio disabled.\n");
+ IWL_DEBUG_INFO(priv, "Radio disabled.\n");
}
/********************
@@ -3909,38 +3419,57 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iwl_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags);
+ pci_enable_msi(priv->pci_dev);
+
+ err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
+ DRV_NAME, priv);
+ if (err) {
+ IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
+ goto out_disable_msi;
+ }
err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group);
if (err) {
- IWL_ERROR("failed to create sysfs device attributes\n");
- goto out_uninit_drv;
+ IWL_ERR(priv, "failed to create sysfs device attributes\n");
+ goto out_free_irq;
}
-
iwl_setup_deferred_work(priv);
iwl_setup_rx_handlers(priv);
- /********************
- * 9. Conclude
- ********************/
- pci_save_state(pdev);
- pci_disable_device(pdev);
-
/**********************************
- * 10. Setup and register mac80211
+ * 9. Setup and register mac80211
**********************************/
+ /* enable interrupts if needed: hw bug w/a */
+ pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
+ if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
+ pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
+ pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
+ }
+
+ iwl_enable_interrupts(priv);
+
err = iwl_setup_mac(priv);
if (err)
goto out_remove_sysfs;
err = iwl_dbgfs_register(priv, DRV_NAME);
if (err)
- IWL_ERROR("failed to create debugfs files\n");
+ IWL_ERR(priv, "failed to create debugfs files\n");
+
+ /* If platform's RF_KILL switch is NOT set to KILL */
+ if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
+ clear_bit(STATUS_RF_KILL_HW, &priv->status);
+ else
+ set_bit(STATUS_RF_KILL_HW, &priv->status);
err = iwl_rfkill_init(priv);
if (err)
- IWL_ERROR("Unable to initialize RFKILL system. "
+ IWL_ERR(priv, "Unable to initialize RFKILL system. "
"Ignoring error: %d\n", err);
+ else
+ iwl_rfkill_set_hw_state(priv);
+
iwl_power_initialize(priv);
return 0;
@@ -3948,7 +3477,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
- out_uninit_drv:
+ out_free_irq:
+ free_irq(priv->pci_dev->irq, priv);
+ out_disable_msi:
+ pci_disable_msi(priv->pci_dev);
iwl_uninit_drv(priv);
out_free_eeprom:
iwl_eeprom_free(priv);
@@ -3973,7 +3505,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
if (!priv)
return;
- IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
+ IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
iwl_dbgfs_unregister(priv);
sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
@@ -4019,6 +3551,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
+ free_irq(priv->pci_dev->irq, priv);
+ pci_disable_msi(priv->pci_dev);
pci_iounmap(pdev, priv->hw_base);
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -4044,19 +3578,8 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
priv->is_open = 1;
}
- /* pci driver assumes state will be saved in this function.
- * pci state is saved and device disabled when interface is
- * stopped, so at this time pci device will always be disabled -
- * whether interface was started or not. saving pci state now will
- * cause saved state be that of a disabled device, which will cause
- * problems during resume in that we will end up with a disabled device.
- *
- * indicate that the current saved state (from when interface was
- * stopped) is valid. if interface was never up at time of suspend
- * then the saved state will still be valid as it was saved during
- * .probe. */
- pdev->state_saved = true;
-
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
return 0;
@@ -4065,8 +3588,14 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
static int iwl_pci_resume(struct pci_dev *pdev)
{
struct iwl_priv *priv = pci_get_drvdata(pdev);
+ int ret;
pci_set_power_state(pdev, PCI_D0);
+ ret = pci_enable_device(pdev);
+ if (ret)
+ return ret;
+ pci_restore_state(pdev);
+ iwl_enable_interrupts(priv);
if (priv->is_open)
iwl_mac_start(priv->hw);
@@ -4107,6 +3636,21 @@ static struct pci_device_id iwl_hw_card_ids[] = {
/* 5150 Wifi/WiMax */
{IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)},
{IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)},
+/* 6000/6050 Series */
+ {IWL_PCI_DEVICE(0x0082, 0x1102, iwl6000_2ag_cfg)},
+ {IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)},
+ {IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)},
+ {IWL_PCI_DEVICE(0x0089, PCI_ANY_ID, iwl6050_2agn_cfg)},
+/* 1000 Series WiFi */
+ {IWL_PCI_DEVICE(0x0083, PCI_ANY_ID, iwl1000_bgn_cfg)},
+ {IWL_PCI_DEVICE(0x0084, PCI_ANY_ID, iwl1000_bgn_cfg)},
#endif /* CONFIG_IWL5000 */
{0}
@@ -4133,13 +3677,14 @@ static int __init iwl_init(void)
ret = iwlagn_rate_control_register();
if (ret) {
- IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
+ printk(KERN_ERR DRV_NAME
+ "Unable to register rate control algorithm: %d\n", ret);
return ret;
}
ret = pci_register_driver(&iwl_driver);
if (ret) {
- IWL_ERROR("Unable to initialize PCI module\n");
+ printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n");
goto error_register;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index f836ecc55758..735f3f19928c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -102,7 +102,7 @@ int iwl_send_calib_results(struct iwl_priv *priv)
return 0;
err:
- IWL_ERROR("Error %d iteration %d\n", ret, i);
+ IWL_ERR(priv, "Error %d iteration %d\n", ret, i);
return ret;
}
EXPORT_SYMBOL(iwl_send_calib_results);
@@ -202,7 +202,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
val = data->nrg_silence_rssi[i];
silence_ref = max(silence_ref, val);
}
- IWL_DEBUG_CALIB("silence a %u, b %u, c %u, 20-bcn max %u\n",
+ IWL_DEBUG_CALIB(priv, "silence a %u, b %u, c %u, 20-bcn max %u\n",
silence_rssi_a, silence_rssi_b, silence_rssi_c,
silence_ref);
@@ -226,7 +226,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
max_nrg_cck = (u32) max(max_nrg_cck, (data->nrg_value[i]));
max_nrg_cck += 6;
- IWL_DEBUG_CALIB("rx energy a %u, b %u, c %u, 10-bcn max/min %u\n",
+ IWL_DEBUG_CALIB(priv, "rx energy a %u, b %u, c %u, 10-bcn max/min %u\n",
rx_info->beacon_energy_a, rx_info->beacon_energy_b,
rx_info->beacon_energy_c, max_nrg_cck - 6);
@@ -236,15 +236,15 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
data->num_in_cck_no_fa++;
else
data->num_in_cck_no_fa = 0;
- IWL_DEBUG_CALIB("consecutive bcns with few false alarms = %u\n",
+ IWL_DEBUG_CALIB(priv, "consecutive bcns with few false alarms = %u\n",
data->num_in_cck_no_fa);
/* If we got too many false alarms this time, reduce sensitivity */
if ((false_alarms > max_false_alarms) &&
(data->auto_corr_cck > AUTO_CORR_MAX_TH_CCK)) {
- IWL_DEBUG_CALIB("norm FA %u > max FA %u\n",
+ IWL_DEBUG_CALIB(priv, "norm FA %u > max FA %u\n",
false_alarms, max_false_alarms);
- IWL_DEBUG_CALIB("... reducing sensitivity\n");
+ IWL_DEBUG_CALIB(priv, "... reducing sensitivity\n");
data->nrg_curr_state = IWL_FA_TOO_MANY;
/* Store for "fewer than desired" on later beacon */
data->nrg_silence_ref = silence_ref;
@@ -266,7 +266,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
data->nrg_auto_corr_silence_diff = (s32)data->nrg_silence_ref -
(s32)silence_ref;
- IWL_DEBUG_CALIB("norm FA %u < min FA %u, silence diff %d\n",
+ IWL_DEBUG_CALIB(priv, "norm FA %u < min FA %u, silence diff %d\n",
false_alarms, min_false_alarms,
data->nrg_auto_corr_silence_diff);
@@ -280,17 +280,17 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
((data->nrg_auto_corr_silence_diff > NRG_DIFF) ||
(data->num_in_cck_no_fa > MAX_NUMBER_CCK_NO_FA))) {
- IWL_DEBUG_CALIB("... increasing sensitivity\n");
+ IWL_DEBUG_CALIB(priv, "... increasing sensitivity\n");
/* Increase nrg value to increase sensitivity */
val = data->nrg_th_cck + NRG_STEP_CCK;
data->nrg_th_cck = min((u32)ranges->min_nrg_cck, val);
} else {
- IWL_DEBUG_CALIB("... but not changing sensitivity\n");
+ IWL_DEBUG_CALIB(priv, "... but not changing sensitivity\n");
}
/* Else we got a healthy number of false alarms, keep status quo */
} else {
- IWL_DEBUG_CALIB(" FA in safe zone\n");
+ IWL_DEBUG_CALIB(priv, " FA in safe zone\n");
data->nrg_curr_state = IWL_FA_GOOD_RANGE;
/* Store for use in "fewer than desired" with later beacon */
@@ -300,7 +300,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
* give it some extra margin by reducing sensitivity again
* (but don't go below measured energy of desired Rx) */
if (IWL_FA_TOO_MANY == data->nrg_prev_state) {
- IWL_DEBUG_CALIB("... increasing margin\n");
+ IWL_DEBUG_CALIB(priv, "... increasing margin\n");
if (data->nrg_th_cck > (max_nrg_cck + NRG_MARGIN))
data->nrg_th_cck -= NRG_MARGIN;
else
@@ -314,7 +314,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
* Lower value is higher energy, so we use max()!
*/
data->nrg_th_cck = max(max_nrg_cck, data->nrg_th_cck);
- IWL_DEBUG_CALIB("new nrg_th_cck %u\n", data->nrg_th_cck);
+ IWL_DEBUG_CALIB(priv, "new nrg_th_cck %u\n", data->nrg_th_cck);
data->nrg_prev_state = data->nrg_curr_state;
@@ -367,7 +367,7 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
/* If we got too many false alarms this time, reduce sensitivity */
if (false_alarms > max_false_alarms) {
- IWL_DEBUG_CALIB("norm FA %u > max FA %u)\n",
+ IWL_DEBUG_CALIB(priv, "norm FA %u > max FA %u)\n",
false_alarms, max_false_alarms);
val = data->auto_corr_ofdm + AUTO_CORR_STEP_OFDM;
@@ -390,7 +390,7 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
/* Else if we got fewer than desired, increase sensitivity */
else if (false_alarms < min_false_alarms) {
- IWL_DEBUG_CALIB("norm FA %u < min FA %u\n",
+ IWL_DEBUG_CALIB(priv, "norm FA %u < min FA %u\n",
false_alarms, min_false_alarms);
val = data->auto_corr_ofdm - AUTO_CORR_STEP_OFDM;
@@ -409,7 +409,7 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
data->auto_corr_ofdm_mrc_x1 =
max((u32)ranges->auto_corr_min_ofdm_mrc_x1, val);
} else {
- IWL_DEBUG_CALIB("min FA %u < norm FA %u < max FA %u OK\n",
+ IWL_DEBUG_CALIB(priv, "min FA %u < norm FA %u < max FA %u OK\n",
min_false_alarms, false_alarms, max_false_alarms);
}
return 0;
@@ -452,18 +452,18 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
cpu_to_le16((u16)data->nrg_th_ofdm);
cmd.table[HD_BARKER_CORR_TH_ADD_MIN_INDEX] =
- __constant_cpu_to_le16(190);
+ cpu_to_le16(190);
cmd.table[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] =
- __constant_cpu_to_le16(390);
+ cpu_to_le16(390);
cmd.table[HD_OFDM_ENERGY_TH_IN_INDEX] =
- __constant_cpu_to_le16(62);
+ cpu_to_le16(62);
- IWL_DEBUG_CALIB("ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n",
+ IWL_DEBUG_CALIB(priv, "ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n",
data->auto_corr_ofdm, data->auto_corr_ofdm_mrc,
data->auto_corr_ofdm_x1, data->auto_corr_ofdm_mrc_x1,
data->nrg_th_ofdm);
- IWL_DEBUG_CALIB("cck: ac %u mrc %u thresh %u\n",
+ IWL_DEBUG_CALIB(priv, "cck: ac %u mrc %u thresh %u\n",
data->auto_corr_cck, data->auto_corr_cck_mrc,
data->nrg_th_cck);
@@ -473,7 +473,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
/* Don't send command to uCode if nothing has changed */
if (!memcmp(&cmd.table[0], &(priv->sensitivity_tbl[0]),
sizeof(u16)*HD_TABLE_SIZE)) {
- IWL_DEBUG_CALIB("No change in SENSITIVITY_CMD\n");
+ IWL_DEBUG_CALIB(priv, "No change in SENSITIVITY_CMD\n");
return 0;
}
@@ -483,7 +483,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
ret = iwl_send_cmd(priv, &cmd_out);
if (ret)
- IWL_ERROR("SENSITIVITY_CMD failed\n");
+ IWL_ERR(priv, "SENSITIVITY_CMD failed\n");
return ret;
}
@@ -498,7 +498,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
if (priv->disable_sens_cal)
return;
- IWL_DEBUG_CALIB("Start iwl_init_sensitivity\n");
+ IWL_DEBUG_CALIB(priv, "Start iwl_init_sensitivity\n");
/* Clear driver's sensitivity algo data */
data = &(priv->sensitivity_data);
@@ -536,7 +536,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
data->last_fa_cnt_cck = 0;
ret |= iwl_sensitivity_write(priv);
- IWL_DEBUG_CALIB("<<return 0x%X\n", ret);
+ IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
}
EXPORT_SYMBOL(iwl_init_sensitivity);
@@ -562,13 +562,13 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
data = &(priv->sensitivity_data);
if (!iwl_is_associated(priv)) {
- IWL_DEBUG_CALIB("<< - not associated\n");
+ IWL_DEBUG_CALIB(priv, "<< - not associated\n");
return;
}
spin_lock_irqsave(&priv->lock, flags);
if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
- IWL_DEBUG_CALIB("<< invalid data.\n");
+ IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
spin_unlock_irqrestore(&priv->lock, flags);
return;
}
@@ -595,10 +595,10 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_CALIB("rx_enable_time = %u usecs\n", rx_enable_time);
+ IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time);
if (!rx_enable_time) {
- IWL_DEBUG_CALIB("<< RX Enable Time == 0! \n");
+ IWL_DEBUG_CALIB(priv, "<< RX Enable Time == 0! \n");
return;
}
@@ -637,7 +637,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
norm_fa_ofdm = fa_ofdm + bad_plcp_ofdm;
norm_fa_cck = fa_cck + bad_plcp_cck;
- IWL_DEBUG_CALIB("cck: fa %u badp %u ofdm: fa %u badp %u\n", fa_cck,
+ IWL_DEBUG_CALIB(priv, "cck: fa %u badp %u ofdm: fa %u badp %u\n", fa_cck,
bad_plcp_cck, fa_ofdm, bad_plcp_ofdm);
iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
@@ -690,13 +690,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
* then we're done forever. */
if (data->state != IWL_CHAIN_NOISE_ACCUMULATE) {
if (data->state == IWL_CHAIN_NOISE_ALIVE)
- IWL_DEBUG_CALIB("Wait for noise calib reset\n");
+ IWL_DEBUG_CALIB(priv, "Wait for noise calib reset\n");
return;
}
spin_lock_irqsave(&priv->lock, flags);
if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
- IWL_DEBUG_CALIB(" << Interference data unavailable\n");
+ IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
spin_unlock_irqrestore(&priv->lock, flags);
return;
}
@@ -709,7 +709,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
/* Make sure we accumulate data for just the associated channel
* (even if scanning). */
if ((rxon_chnum != stat_chnum) || (rxon_band24 != stat_band24)) {
- IWL_DEBUG_CALIB("Stats not from chan=%d, band24=%d\n",
+ IWL_DEBUG_CALIB(priv, "Stats not from chan=%d, band24=%d\n",
rxon_chnum, rxon_band24);
spin_unlock_irqrestore(&priv->lock, flags);
return;
@@ -739,11 +739,11 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
data->chain_signal_b = (chain_sig_b + data->chain_signal_b);
data->chain_signal_c = (chain_sig_c + data->chain_signal_c);
- IWL_DEBUG_CALIB("chan=%d, band24=%d, beacon=%d\n",
+ IWL_DEBUG_CALIB(priv, "chan=%d, band24=%d, beacon=%d\n",
rxon_chnum, rxon_band24, data->beacon_count);
- IWL_DEBUG_CALIB("chain_sig: a %d b %d c %d\n",
+ IWL_DEBUG_CALIB(priv, "chain_sig: a %d b %d c %d\n",
chain_sig_a, chain_sig_b, chain_sig_c);
- IWL_DEBUG_CALIB("chain_noise: a %d b %d c %d\n",
+ IWL_DEBUG_CALIB(priv, "chain_noise: a %d b %d c %d\n",
chain_noise_a, chain_noise_b, chain_noise_c);
/* If this is the 20th beacon, determine:
@@ -773,9 +773,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
active_chains = (1 << max_average_sig_antenna_i);
}
- IWL_DEBUG_CALIB("average_sig: a %d b %d c %d\n",
+ IWL_DEBUG_CALIB(priv, "average_sig: a %d b %d c %d\n",
average_sig[0], average_sig[1], average_sig[2]);
- IWL_DEBUG_CALIB("max_average_sig = %d, antenna %d\n",
+ IWL_DEBUG_CALIB(priv, "max_average_sig = %d, antenna %d\n",
max_average_sig, max_average_sig_antenna_i);
/* Compare signal strengths for all 3 receivers. */
@@ -789,7 +789,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
data->disconn_array[i] = 1;
else
active_chains |= (1 << i);
- IWL_DEBUG_CALIB("i = %d rssiDelta = %d "
+ IWL_DEBUG_CALIB(priv, "i = %d rssiDelta = %d "
"disconn_array[i] = %d\n",
i, rssi_delta, data->disconn_array[i]);
}
@@ -813,7 +813,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
* disconnected connect it anyway */
data->disconn_array[i] = 0;
active_chains |= ant_msk;
- IWL_DEBUG_CALIB("All Tx chains are disconnected W/A - "
+ IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected W/A - "
"declare %d as connected\n", i);
break;
}
@@ -821,7 +821,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
/* Save for use within RXON, TX, SCAN commands, etc. */
priv->chain_noise_data.active_chains = active_chains;
- IWL_DEBUG_CALIB("active_chains (bitwise) = 0x%x\n",
+ IWL_DEBUG_CALIB(priv, "active_chains (bitwise) = 0x%x\n",
active_chains);
/* Analyze noise for rx balance */
@@ -839,15 +839,16 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
}
}
- IWL_DEBUG_CALIB("average_noise: a %d b %d c %d\n",
+ IWL_DEBUG_CALIB(priv, "average_noise: a %d b %d c %d\n",
average_noise[0], average_noise[1],
average_noise[2]);
- IWL_DEBUG_CALIB("min_average_noise = %d, antenna %d\n",
+ IWL_DEBUG_CALIB(priv, "min_average_noise = %d, antenna %d\n",
min_average_noise, min_average_noise_antenna_i);
- priv->cfg->ops->utils->gain_computation(priv, average_noise,
- min_average_noise_antenna_i, min_average_noise);
+ if (priv->cfg->ops->utils->gain_computation)
+ priv->cfg->ops->utils->gain_computation(priv, average_noise,
+ min_average_noise_antenna_i, min_average_noise);
/* Some power changes may have been made during the calibration.
* Update and commit the RXON
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h
index 1abe84bb74ad..b6cef989a796 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index ba997204c8d4..29d40746da6a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -69,12 +69,20 @@
#ifndef __iwl_commands_h__
#define __iwl_commands_h__
+struct iwl_priv;
+
/* uCode version contains 4 values: Major/Minor/API/Serial */
#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24)
#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16)
#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8)
#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF)
+
+/* Tx rates */
+#define IWL_CCK_RATES 4
+#define IWL_OFDM_RATES 8
+#define IWL_MAX_RATES (IWL_CCK_RATES + IWL_OFDM_RATES)
+
enum {
REPLY_ALIVE = 0x1,
REPLY_ERROR = 0x2,
@@ -136,9 +144,11 @@ enum {
WHO_IS_AWAKE_NOTIFICATION = 0x94, /* not used */
/* Miscellaneous commands */
+ REPLY_TX_POWER_DBM_CMD = 0x95,
QUIET_NOTIFICATION = 0x96, /* not used */
REPLY_TX_PWR_TABLE_CMD = 0x97,
- REPLY_TX_POWER_DBM_CMD = 0x98,
+ REPLY_TX_POWER_DBM_CMD_V1 = 0x98, /* old version of API */
+ TX_ANT_CONFIGURATION_CMD = 0x98, /* not used */
MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */
/* Bluetooth device coexistence config command */
@@ -219,6 +229,37 @@ struct iwl_cmd_header {
u8 data[0];
} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_tx_power
+ *
+ * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH
+ *
+ * Each entry contains two values:
+ * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained
+ * linear value that multiplies the output of the digital signal processor,
+ * before being sent to the analog radio.
+ * 2) Radio gain. This sets the analog gain of the radio Tx path.
+ * It is a coarser setting, and behaves in a logarithmic (dB) fashion.
+ *
+ * Driver obtains values from struct iwl3945_tx_power power_gain_table[][].
+ */
+struct iwl3945_tx_power {
+ u8 tx_gain; /* gain for analog radio */
+ u8 dsp_atten; /* gain for DSP */
+} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_power_per_rate
+ *
+ * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
+ */
+struct iwl3945_power_per_rate {
+ u8 rate; /* plcp */
+ struct iwl3945_tx_power tpc;
+ u8 reserved;
+} __attribute__ ((packed));
+
/**
* iwlagn rate_n_flags bit fields
*
@@ -300,11 +341,12 @@ struct iwl_cmd_header {
* 5350 has 3 transmitters
* bit14:16
*/
-#define RATE_MCS_ANT_POS 14
-#define RATE_MCS_ANT_A_MSK 0x04000
-#define RATE_MCS_ANT_B_MSK 0x08000
-#define RATE_MCS_ANT_C_MSK 0x10000
-#define RATE_MCS_ANT_ABC_MSK 0x1C000
+#define RATE_MCS_ANT_POS 14
+#define RATE_MCS_ANT_A_MSK 0x04000
+#define RATE_MCS_ANT_B_MSK 0x08000
+#define RATE_MCS_ANT_C_MSK 0x10000
+#define RATE_MCS_ANT_AB_MSK (RATE_MCS_ANT_A_MSK | RATE_MCS_ANT_B_MSK)
+#define RATE_MCS_ANT_ABC_MSK (RATE_MCS_ANT_AB_MSK | RATE_MCS_ANT_C_MSK)
#define RATE_ANT_NUM 3
#define POWER_TABLE_NUM_ENTRIES 33
@@ -492,8 +534,6 @@ struct iwl_alive_resp {
__le32 is_valid;
} __attribute__ ((packed));
-
-
/*
* REPLY_ERROR = 0x2 (response only, not a command)
*/
@@ -525,6 +565,7 @@ enum {
#define RXON_RX_CHAIN_DRIVER_FORCE_MSK cpu_to_le16(0x1 << 0)
+#define RXON_RX_CHAIN_DRIVER_FORCE_POS (0)
#define RXON_RX_CHAIN_VALID_MSK cpu_to_le16(0x7 << 1)
#define RXON_RX_CHAIN_VALID_POS (1)
#define RXON_RX_CHAIN_FORCE_SEL_MSK cpu_to_le16(0x7 << 4)
@@ -611,6 +652,26 @@ enum {
* issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10),
* regardless of whether RXON_FILTER_ASSOC_MSK is set.
*/
+
+struct iwl3945_rxon_cmd {
+ u8 node_addr[6];
+ __le16 reserved1;
+ u8 bssid_addr[6];
+ __le16 reserved2;
+ u8 wlap_bssid_addr[6];
+ __le16 reserved3;
+ u8 dev_type;
+ u8 air_propagation;
+ __le16 reserved4;
+ u8 ofdm_basic_rates;
+ u8 cck_basic_rates;
+ __le16 assoc_id;
+ __le32 flags;
+ __le32 filter_flags;
+ __le16 channel;
+ __le16 reserved5;
+} __attribute__ ((packed));
+
struct iwl4965_rxon_cmd {
u8 node_addr[6];
__le16 reserved1;
@@ -656,33 +717,41 @@ struct iwl_rxon_cmd {
__le16 reserved6;
} __attribute__ ((packed));
-struct iwl5000_rxon_assoc_cmd {
+/*
+ * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
+ */
+struct iwl3945_rxon_assoc_cmd {
+ __le32 flags;
+ __le32 filter_flags;
+ u8 ofdm_basic_rates;
+ u8 cck_basic_rates;
+ __le16 reserved;
+} __attribute__ ((packed));
+
+struct iwl4965_rxon_assoc_cmd {
__le32 flags;
__le32 filter_flags;
u8 ofdm_basic_rates;
u8 cck_basic_rates;
- __le16 reserved1;
u8 ofdm_ht_single_stream_basic_rates;
u8 ofdm_ht_dual_stream_basic_rates;
- u8 ofdm_ht_triple_stream_basic_rates;
- u8 reserved2;
__le16 rx_chain_select_flags;
- __le16 acquisition_data;
- __le32 reserved3;
+ __le16 reserved;
} __attribute__ ((packed));
-/*
- * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
- */
-struct iwl4965_rxon_assoc_cmd {
+struct iwl5000_rxon_assoc_cmd {
__le32 flags;
__le32 filter_flags;
u8 ofdm_basic_rates;
u8 cck_basic_rates;
+ __le16 reserved1;
u8 ofdm_ht_single_stream_basic_rates;
u8 ofdm_ht_dual_stream_basic_rates;
+ u8 ofdm_ht_triple_stream_basic_rates;
+ u8 reserved2;
__le16 rx_chain_select_flags;
- __le16 reserved;
+ __le16 acquisition_data;
+ __le32 reserved3;
} __attribute__ ((packed));
#define IWL_CONN_MAX_LISTEN_INTERVAL 10
@@ -702,6 +771,16 @@ struct iwl_rxon_time_cmd {
/*
* REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
*/
+struct iwl3945_channel_switch_cmd {
+ u8 band;
+ u8 expect_beacon;
+ __le16 channel;
+ __le32 rxon_flags;
+ __le32 rxon_filter_flags;
+ __le32 switch_time;
+ struct iwl3945_power_per_rate power[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
struct iwl_channel_switch_cmd {
u8 band;
u8 expect_beacon;
@@ -783,6 +862,8 @@ struct iwl_qosparam_cmd {
#define IWL_AP_ID 0
#define IWL_MULTICAST_ID 1
#define IWL_STA_ID 2
+#define IWL3945_BROADCAST_ID 24
+#define IWL3945_STATION_COUNT 25
#define IWL4965_BROADCAST_ID 31
#define IWL4965_STATION_COUNT 32
#define IWL5000_BROADCAST_ID 15
@@ -791,6 +872,8 @@ struct iwl_qosparam_cmd {
#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
#define IWL_INVALID_STATION 255
+#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2);
+#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8);
#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8);
#define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17)
#define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18)
@@ -901,6 +984,35 @@ struct sta_id_modify {
* used as AP, or in an IBSS network, driver must set up station table
* entries for all STAs in network, starting with index IWL_STA_ID.
*/
+
+struct iwl3945_addsta_cmd {
+ u8 mode; /* 1: modify existing, 0: add new station */
+ u8 reserved[3];
+ struct sta_id_modify sta;
+ struct iwl4965_keyinfo key;
+ __le32 station_flags; /* STA_FLG_* */
+ __le32 station_flags_msk; /* STA_FLG_* */
+
+ /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
+ * corresponding to bit (e.g. bit 5 controls TID 5).
+ * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
+ __le16 tid_disable_tx;
+
+ __le16 rate_n_flags;
+
+ /* TID for which to add block-ack support.
+ * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+ u8 add_immediate_ba_tid;
+
+ /* TID for which to remove block-ack support.
+ * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
+ u8 remove_immediate_ba_tid;
+
+ /* Starting Sequence Number for added block-ack support.
+ * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+ __le16 add_immediate_ba_ssn;
+} __attribute__ ((packed));
+
struct iwl4965_addsta_cmd {
u8 mode; /* 1: modify existing, 0: add new station */
u8 reserved[3];
@@ -1054,6 +1166,48 @@ struct iwl_wep_cmd {
#define RX_MPDU_RES_STATUS_TTAK_OK (1 << 7)
#define RX_MPDU_RES_STATUS_DEC_DONE_MSK (0x800)
+
+struct iwl3945_rx_frame_stats {
+ u8 phy_count;
+ u8 id;
+ u8 rssi;
+ u8 agc;
+ __le16 sig_avg;
+ __le16 noise_diff;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct iwl3945_rx_frame_hdr {
+ __le16 channel;
+ __le16 phy_flags;
+ u8 reserved1;
+ u8 rate;
+ __le16 len;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct iwl3945_rx_frame_end {
+ __le32 status;
+ __le64 timestamp;
+ __le32 beacon_timestamp;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_3945_RX = 0x1b (response only, not a command)
+ *
+ * NOTE: DO NOT dereference from casts to this structure
+ * It is provided only for calculating minimum data set size.
+ * The actual offsets of the hdr and end are dynamic based on
+ * stats.phy_count
+ */
+struct iwl3945_rx_frame {
+ struct iwl3945_rx_frame_stats stats;
+ struct iwl3945_rx_frame_hdr hdr;
+ struct iwl3945_rx_frame_end end;
+} __attribute__ ((packed));
+
+#define IWL39_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame))
+
/* Fixed (non-configurable) rx data from phy */
#define IWL49_RX_RES_PHY_CNT 14
@@ -1234,6 +1388,84 @@ struct iwl4965_rx_mpdu_res_start {
#define TKIP_ICV_LEN 4
/*
+ * REPLY_TX = 0x1c (command)
+ */
+
+struct iwl3945_tx_cmd {
+ /*
+ * MPDU byte count:
+ * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
+ * + 8 byte IV for CCM or TKIP (not used for WEP)
+ * + Data payload
+ * + 8-byte MIC (not used for CCM/WEP)
+ * NOTE: Does not include Tx command bytes, post-MAC pad bytes,
+ * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
+ * Range: 14-2342 bytes.
+ */
+ __le16 len;
+
+ /*
+ * MPDU or MSDU byte count for next frame.
+ * Used for fragmentation and bursting, but not 11n aggregation.
+ * Same as "len", but for next frame. Set to 0 if not applicable.
+ */
+ __le16 next_frame_len;
+
+ __le32 tx_flags; /* TX_CMD_FLG_* */
+
+ u8 rate;
+
+ /* Index of recipient station in uCode's station table */
+ u8 sta_id;
+ u8 tid_tspec;
+ u8 sec_ctl;
+ u8 key[16];
+ union {
+ u8 byte[8];
+ __le16 word[4];
+ __le32 dw[2];
+ } tkip_mic;
+ __le32 next_frame_info;
+ union {
+ __le32 life_time;
+ __le32 attempt;
+ } stop_time;
+ u8 supp_rates[2];
+ u8 rts_retry_limit; /*byte 50 */
+ u8 data_retry_limit; /*byte 51 */
+ union {
+ __le16 pm_frame_timeout;
+ __le16 attempt_duration;
+ } timeout;
+
+ /*
+ * Duration of EDCA burst Tx Opportunity, in 32-usec units.
+ * Set this if txop time is not specified by HCCA protocol (e.g. by AP).
+ */
+ __le16 driver_txop;
+
+ /*
+ * MAC header goes here, followed by 2 bytes padding if MAC header
+ * length is 26 or 30 bytes, followed by payload data
+ */
+ u8 payload[0];
+ struct ieee80211_hdr hdr[0];
+} __attribute__ ((packed));
+
+/*
+ * REPLY_TX = 0x1c (response)
+ */
+struct iwl3945_tx_resp {
+ u8 failure_rts;
+ u8 failure_frame;
+ u8 bt_kill_count;
+ u8 rate;
+ __le32 wireless_media_time;
+ __le32 status; /* TX status */
+} __attribute__ ((packed));
+
+
+/*
* 4965 uCode updates these Tx attempt count values in host DRAM.
* Used for managing Tx retries when expecting block-acks.
* Driver should set these fields to 0.
@@ -1244,9 +1476,6 @@ struct iwl_dram_scratch {
__le16 reserved;
} __attribute__ ((packed));
-/*
- * REPLY_TX = 0x1c (command)
- */
struct iwl_tx_cmd {
/*
* MPDU byte count:
@@ -1584,6 +1813,14 @@ struct iwl_compressed_ba_resp {
*
* See details under "TXPOWER" in iwl-4965-hw.h.
*/
+
+struct iwl3945_txpowertable_cmd {
+ u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
+ u8 reserved;
+ __le16 channel;
+ struct iwl3945_power_per_rate power[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
struct iwl4965_txpowertable_cmd {
u8 band; /* 0: 5 GHz, 1: 2.4 GHz */
u8 reserved;
@@ -1591,6 +1828,35 @@ struct iwl4965_txpowertable_cmd {
struct iwl4965_tx_power_db tx_power;
} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response
+ *
+ * REPLY_RATE_SCALE = 0x47 (command, has simple generic response)
+ *
+ * NOTE: The table of rates passed to the uCode via the
+ * RATE_SCALE command sets up the corresponding order of
+ * rates used for all related commands, including rate
+ * masks, etc.
+ *
+ * For example, if you set 9MB (PLCP 0x0f) as the first
+ * rate in the rate table, the bit mask for that rate
+ * when passed through ofdm_basic_rates on the REPLY_RXON
+ * command would be bit 0 (1 << 0)
+ */
+struct iwl3945_rate_scaling_info {
+ __le16 rate_n_flags;
+ u8 try_cnt;
+ u8 next_rate_index;
+} __attribute__ ((packed));
+
+struct iwl3945_rate_scaling_cmd {
+ u8 table_id;
+ u8 reserved[3];
+ struct iwl3945_rate_scaling_info table[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
+
/*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */
#define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1 << 0)
@@ -2044,15 +2310,23 @@ struct iwl_spectrum_notification {
*/
#define IWL_POWER_VEC_SIZE 5
-#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(1 << 0)
-#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(1 << 2)
-#define IWL_POWER_PCI_PM_MSK cpu_to_le16(1 << 3)
-#define IWL_POWER_FAST_PD cpu_to_le16(1 << 4)
+#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0))
+#define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2))
+#define IWL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3))
+#define IWL_POWER_FAST_PD cpu_to_le16(BIT(4))
+
+struct iwl3945_powertable_cmd {
+ __le16 flags;
+ u8 reserved[2];
+ __le32 rx_data_timeout;
+ __le32 tx_data_timeout;
+ __le32 sleep_interval[IWL_POWER_VEC_SIZE];
+} __attribute__ ((packed));
struct iwl_powertable_cmd {
__le16 flags;
- u8 keep_alive_seconds;
- u8 debug_flags;
+ u8 keep_alive_seconds; /* 3945 reserved */
+ u8 debug_flags; /* 3945 reserved */
__le32 rx_data_timeout;
__le32 tx_data_timeout;
__le32 sleep_interval[IWL_POWER_VEC_SIZE];
@@ -2143,6 +2417,26 @@ struct iwl_ct_kill_config {
* passive_dwell < max_out_time
* active_dwell < max_out_time
*/
+
+/* FIXME: rename to AP1, remove tpc */
+struct iwl3945_scan_channel {
+ /*
+ * type is defined as:
+ * 0:0 1 = active, 0 = passive
+ * 1:4 SSID direct bit map; if a bit is set, then corresponding
+ * SSID IE is transmitted in probe request.
+ * 5:7 reserved
+ */
+ u8 type;
+ u8 channel; /* band is selected by iwl3945_scan_cmd "flags" field */
+ struct iwl3945_tx_power tpc;
+ __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */
+ __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
+} __attribute__ ((packed));
+
+/* set number of direct probes u8 type */
+#define IWL39_SCAN_PROBE_MASK(n) ((BIT(n) | (BIT(n) - BIT(1))))
+
struct iwl_scan_channel {
/*
* type is defined as:
@@ -2159,6 +2453,9 @@ struct iwl_scan_channel {
__le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
} __attribute__ ((packed));
+/* set number of direct probes __le32 type */
+#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
+
/**
* struct iwl_ssid_ie - directed scan network information element
*
@@ -2172,6 +2469,7 @@ struct iwl_ssid_ie {
u8 ssid[32];
} __attribute__ ((packed));
+#define PROBE_OPTION_MAX_API1 0x4
#define PROBE_OPTION_MAX 0x14
#define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF)
#define IWL_GOOD_CRC_TH cpu_to_le16(1)
@@ -2229,6 +2527,51 @@ struct iwl_ssid_ie {
* To avoid uCode errors, see timing restrictions described under
* struct iwl_scan_channel.
*/
+
+struct iwl3945_scan_cmd {
+ __le16 len;
+ u8 reserved0;
+ u8 channel_count; /* # channels in channel list */
+ __le16 quiet_time; /* dwell only this # millisecs on quiet channel
+ * (only for active scan) */
+ __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */
+ __le16 good_CRC_th; /* passive -> active promotion threshold */
+ __le16 reserved1;
+ __le32 max_out_time; /* max usec to be away from associated (service)
+ * channel */
+ __le32 suspend_time; /* pause scan this long (in "extended beacon
+ * format") when returning to service channel:
+ * 3945; 31:24 # beacons, 19:0 additional usec,
+ * 4965; 31:22 # beacons, 21:0 additional usec.
+ */
+ __le32 flags; /* RXON_FLG_* */
+ __le32 filter_flags; /* RXON_FILTER_* */
+
+ /* For active scans (set to all-0s for passive scans).
+ * Does not include payload. Must specify Tx rate; no rate scaling. */
+ struct iwl3945_tx_cmd tx_cmd;
+
+ /* For directed active scans (set to all-0s otherwise) */
+ struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_API1];
+
+ /*
+ * Probe request frame, followed by channel list.
+ *
+ * Size of probe request frame is specified by byte count in tx_cmd.
+ * Channel list follows immediately after probe request frame.
+ * Number of channels in list is specified by channel_count.
+ * Each channel in list is of type:
+ *
+ * struct iwl3945_scan_channel channels[0];
+ *
+ * NOTE: Only one band of channels can be scanned per pass. You
+ * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
+ * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
+ * before requesting another scan.
+ */
+ u8 data[0];
+} __attribute__ ((packed));
+
struct iwl_scan_cmd {
__le16 len;
u8 reserved0;
@@ -2336,6 +2679,14 @@ struct iwl_scancomplete_notification {
/*
* BEACON_NOTIFICATION = 0x90 (notification only, not a command)
*/
+
+struct iwl3945_beacon_notif {
+ struct iwl3945_tx_resp beacon_notify_hdr;
+ __le32 low_tsf;
+ __le32 high_tsf;
+ __le32 ibss_mgr_status;
+} __attribute__ ((packed));
+
struct iwl4965_beacon_notif {
struct iwl4965_tx_resp beacon_notify_hdr;
__le32 low_tsf;
@@ -2346,6 +2697,15 @@ struct iwl4965_beacon_notif {
/*
* REPLY_TX_BEACON = 0x91 (command, has simple generic response)
*/
+
+struct iwl3945_tx_beacon_cmd {
+ struct iwl3945_tx_cmd tx;
+ __le16 tim_idx;
+ u8 tim_size;
+ u8 reserved1;
+ struct ieee80211_hdr frame[0]; /* beacon frame */
+} __attribute__ ((packed));
+
struct iwl_tx_beacon_cmd {
struct iwl_tx_cmd tx;
__le16 tim_idx;
@@ -2382,6 +2742,76 @@ struct rate_histogram {
/* statistics command response */
+struct iwl39_statistics_rx_phy {
+ __le32 ina_cnt;
+ __le32 fina_cnt;
+ __le32 plcp_err;
+ __le32 crc32_err;
+ __le32 overrun_err;
+ __le32 early_overrun_err;
+ __le32 crc32_good;
+ __le32 false_alarm_cnt;
+ __le32 fina_sync_err_cnt;
+ __le32 sfd_timeout;
+ __le32 fina_timeout;
+ __le32 unresponded_rts;
+ __le32 rxe_frame_limit_overrun;
+ __le32 sent_ack_cnt;
+ __le32 sent_cts_cnt;
+} __attribute__ ((packed));
+
+struct iwl39_statistics_rx_non_phy {
+ __le32 bogus_cts; /* CTS received when not expecting CTS */
+ __le32 bogus_ack; /* ACK received when not expecting ACK */
+ __le32 non_bssid_frames; /* number of frames with BSSID that
+ * doesn't belong to the STA BSSID */
+ __le32 filtered_frames; /* count frames that were dumped in the
+ * filtering process */
+ __le32 non_channel_beacons; /* beacons with our bss id but not on
+ * our serving channel */
+} __attribute__ ((packed));
+
+struct iwl39_statistics_rx {
+ struct iwl39_statistics_rx_phy ofdm;
+ struct iwl39_statistics_rx_phy cck;
+ struct iwl39_statistics_rx_non_phy general;
+} __attribute__ ((packed));
+
+struct iwl39_statistics_tx {
+ __le32 preamble_cnt;
+ __le32 rx_detected_cnt;
+ __le32 bt_prio_defer_cnt;
+ __le32 bt_prio_kill_cnt;
+ __le32 few_bytes_cnt;
+ __le32 cts_timeout;
+ __le32 ack_timeout;
+ __le32 expected_ack_cnt;
+ __le32 actual_ack_cnt;
+} __attribute__ ((packed));
+
+struct statistics_dbg {
+ __le32 burst_check;
+ __le32 burst_count;
+ __le32 reserved[4];
+} __attribute__ ((packed));
+
+struct iwl39_statistics_div {
+ __le32 tx_on_a;
+ __le32 tx_on_b;
+ __le32 exec_time;
+ __le32 probe_time;
+} __attribute__ ((packed));
+
+struct iwl39_statistics_general {
+ __le32 temperature;
+ struct statistics_dbg dbg;
+ __le32 sleep_time;
+ __le32 slots_out;
+ __le32 slots_idle;
+ __le32 ttl_timestamp;
+ struct iwl39_statistics_div div;
+} __attribute__ ((packed));
+
struct statistics_rx_phy {
__le32 ina_cnt;
__le32 fina_cnt;
@@ -2418,7 +2848,7 @@ struct statistics_rx_ht_phy {
__le32 reserved2;
} __attribute__ ((packed));
-#define INTERFERENCE_DATA_AVAILABLE __constant_cpu_to_le32(1)
+#define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1)
struct statistics_rx_non_phy {
__le32 bogus_cts; /* CTS received when not expecting CTS */
@@ -2493,11 +2923,6 @@ struct statistics_tx {
struct statistics_tx_non_phy_agg agg;
} __attribute__ ((packed));
-struct statistics_dbg {
- __le32 burst_check;
- __le32 burst_count;
- __le32 reserved[4];
-} __attribute__ ((packed));
struct statistics_div {
__le32 tx_on_a;
@@ -2561,6 +2986,14 @@ struct iwl_statistics_cmd {
*/
#define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2)
#define STATISTICS_REPLY_FLG_FAT_MODE_MSK cpu_to_le32(0x8)
+
+struct iwl3945_notif_statistics {
+ __le32 flag;
+ struct iwl39_statistics_rx rx;
+ struct iwl39_statistics_tx tx;
+ struct iwl39_statistics_general general;
+} __attribute__ ((packed));
+
struct iwl_notif_statistics {
__le32 flag;
struct statistics_rx rx;
@@ -3012,6 +3445,10 @@ struct iwl_rx_packet {
__le32 len;
struct iwl_cmd_header hdr;
union {
+ struct iwl3945_rx_frame rx_frame;
+ struct iwl3945_tx_resp tx_resp;
+ struct iwl3945_beacon_notif beacon_status;
+
struct iwl_alive_resp alive_frame;
struct iwl_spectrum_notification spectrum_notif;
struct iwl_csa_notification csa_notif;
@@ -3029,6 +3466,6 @@ struct iwl_rx_packet {
} u;
} __attribute__ ((packed));
-int iwl_agn_check_rxon_cmd(struct iwl_rxon_cmd *rxon);
+int iwl_agn_check_rxon_cmd(struct iwl_priv *priv);
#endif /* __iwl_commands_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 73d7973707eb..c54fb93e9d72 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/etherdevice.h>
#include <net/mac80211.h>
#include "iwl-eeprom.h"
@@ -170,7 +171,8 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
struct ieee80211_hw *hw =
ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops);
if (hw == NULL) {
- IWL_ERROR("Can not allocate network device\n");
+ printk(KERN_ERR "%s: Can not allocate network device\n",
+ cfg->name);
goto out;
}
@@ -210,7 +212,7 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
if (!rxq->bd) {
ret = iwl_rx_queue_alloc(priv);
if (ret) {
- IWL_ERROR("Unable to initialize Rx queue\n");
+ IWL_ERR(priv, "Unable to initialize Rx queue\n");
return -ENOMEM;
}
} else
@@ -238,6 +240,39 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_hw_nic_init);
+/*
+ * QoS support
+*/
+void iwl_activate_qos(struct iwl_priv *priv, u8 force)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ priv->qos_data.def_qos_parm.qos_flags = 0;
+
+ if (priv->qos_data.qos_cap.q_AP.queue_request &&
+ !priv->qos_data.qos_cap.q_AP.txop_request)
+ priv->qos_data.def_qos_parm.qos_flags |=
+ QOS_PARAM_FLG_TXOP_TYPE_MSK;
+ if (priv->qos_data.qos_active)
+ priv->qos_data.def_qos_parm.qos_flags |=
+ QOS_PARAM_FLG_UPDATE_EDCA_MSK;
+
+ if (priv->current_ht_config.is_ht)
+ priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+
+ if (force || iwl_is_associated(priv)) {
+ IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
+ priv->qos_data.qos_active,
+ priv->qos_data.def_qos_parm.qos_flags);
+
+ iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
+ sizeof(struct iwl_qosparam_cmd),
+ &priv->qos_data.def_qos_parm, NULL);
+ }
+}
+EXPORT_SYMBOL(iwl_activate_qos);
+
void iwl_reset_qos(struct iwl_priv *priv)
{
u16 cw_min = 15;
@@ -321,7 +356,7 @@ void iwl_reset_qos(struct iwl_priv *priv)
priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
}
}
- IWL_DEBUG_QOS("set QoS to default \n");
+ IWL_DEBUG_QOS(priv, "set QoS to default \n");
spin_unlock_irqrestore(&priv->lock, flags);
}
@@ -402,10 +437,11 @@ static void iwlcore_init_hw_rates(struct iwl_priv *priv,
}
}
+
/**
* iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom
*/
-static int iwlcore_init_geos(struct iwl_priv *priv)
+int iwlcore_init_geos(struct iwl_priv *priv)
{
struct iwl_channel_info *ch;
struct ieee80211_supported_band *sband;
@@ -416,7 +452,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
- IWL_DEBUG_INFO("Geography modes already initialized.\n");
+ IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n");
set_bit(STATUS_GEO_CONFIGURED, &priv->status);
return 0;
}
@@ -457,8 +493,6 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
priv->ieee_channels = channels;
priv->ieee_rates = rates;
- iwlcore_init_hw_rates(priv, rates);
-
for (i = 0; i < priv->channel_count; i++) {
ch = &priv->channel_info[i];
@@ -500,7 +534,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
/* Save flags for reg domain usage */
geo_ch->orig_flags = geo_ch->flags;
- IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
+ IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
ch->channel, geo_ch->center_freq,
is_channel_a_band(ch) ? "5.2" : "2.4",
geo_ch->flags & IEEE80211_CHAN_DISABLED ?
@@ -510,33 +544,33 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
priv->cfg->sku & IWL_SKU_A) {
- printk(KERN_INFO DRV_NAME
- ": Incorrectly detected BG card as ABG. Please send "
- "your PCI ID 0x%04X:0x%04X to maintainer.\n",
- priv->pci_dev->device, priv->pci_dev->subsystem_device);
+ IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
+ "Please send your PCI ID 0x%04X:0x%04X to maintainer.\n",
+ priv->pci_dev->device,
+ priv->pci_dev->subsystem_device);
priv->cfg->sku &= ~IWL_SKU_A;
}
- printk(KERN_INFO DRV_NAME
- ": Tunable channels: %d 802.11bg, %d 802.11a channels\n",
- priv->bands[IEEE80211_BAND_2GHZ].n_channels,
- priv->bands[IEEE80211_BAND_5GHZ].n_channels);
-
+ IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
+ priv->bands[IEEE80211_BAND_2GHZ].n_channels,
+ priv->bands[IEEE80211_BAND_5GHZ].n_channels);
set_bit(STATUS_GEO_CONFIGURED, &priv->status);
return 0;
}
+EXPORT_SYMBOL(iwlcore_init_geos);
/*
* iwlcore_free_geos - undo allocations in iwlcore_init_geos
*/
-static void iwlcore_free_geos(struct iwl_priv *priv)
+void iwlcore_free_geos(struct iwl_priv *priv)
{
kfree(priv->ieee_channels);
kfree(priv->ieee_rates);
clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
}
+EXPORT_SYMBOL(iwlcore_free_geos);
static bool is_single_rx_stream(struct iwl_priv *priv)
{
@@ -587,6 +621,167 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
}
EXPORT_SYMBOL(iwl_is_fat_tx_allowed);
+void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
+{
+ struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+
+ if (hw_decrypt)
+ rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
+ else
+ rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;
+
+}
+EXPORT_SYMBOL(iwl_set_rxon_hwcrypto);
+
+/**
+ * iwl_check_rxon_cmd - validate RXON structure is valid
+ *
+ * NOTE: This is really only useful during development and can eventually
+ * be #ifdef'd out once the driver is stable and folks aren't actively
+ * making changes
+ */
+int iwl_check_rxon_cmd(struct iwl_priv *priv)
+{
+ int error = 0;
+ int counter = 1;
+ struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+
+ if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
+ error |= le32_to_cpu(rxon->flags &
+ (RXON_FLG_TGJ_NARROW_BAND_MSK |
+ RXON_FLG_RADAR_DETECT_MSK));
+ if (error)
+ IWL_WARN(priv, "check 24G fields %d | %d\n",
+ counter++, error);
+ } else {
+ error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
+ 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
+ if (error)
+ IWL_WARN(priv, "check 52 fields %d | %d\n",
+ counter++, error);
+ error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
+ if (error)
+ IWL_WARN(priv, "check 52 CCK %d | %d\n",
+ counter++, error);
+ }
+ error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
+ if (error)
+ IWL_WARN(priv, "check mac addr %d | %d\n", counter++, error);
+
+ /* make sure basic rates 6Mbps and 1Mbps are supported */
+ error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
+ ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
+ if (error)
+ IWL_WARN(priv, "check basic rate %d | %d\n", counter++, error);
+
+ error |= (le16_to_cpu(rxon->assoc_id) > 2007);
+ if (error)
+ IWL_WARN(priv, "check assoc id %d | %d\n", counter++, error);
+
+ error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
+ == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
+ if (error)
+ IWL_WARN(priv, "check CCK and short slot %d | %d\n",
+ counter++, error);
+
+ error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
+ == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
+ if (error)
+ IWL_WARN(priv, "check CCK & auto detect %d | %d\n",
+ counter++, error);
+
+ error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
+ RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
+ if (error)
+ IWL_WARN(priv, "check TGG and auto detect %d | %d\n",
+ counter++, error);
+
+ if (error)
+ IWL_WARN(priv, "Tuning to channel %d\n",
+ le16_to_cpu(rxon->channel));
+
+ if (error) {
+ IWL_ERR(priv, "Not a valid iwl_rxon_assoc_cmd field values\n");
+ return -1;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(iwl_check_rxon_cmd);
+
+/**
+ * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
+ * @priv: staging_rxon is compared to active_rxon
+ *
+ * If the RXON structure is changing enough to require a new tune,
+ * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
+ * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
+ */
+int iwl_full_rxon_required(struct iwl_priv *priv)
+{
+
+ /* These items are only settable from the full RXON command */
+ if (!(iwl_is_associated(priv)) ||
+ compare_ether_addr(priv->staging_rxon.bssid_addr,
+ priv->active_rxon.bssid_addr) ||
+ compare_ether_addr(priv->staging_rxon.node_addr,
+ priv->active_rxon.node_addr) ||
+ compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
+ priv->active_rxon.wlap_bssid_addr) ||
+ (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
+ (priv->staging_rxon.channel != priv->active_rxon.channel) ||
+ (priv->staging_rxon.air_propagation !=
+ priv->active_rxon.air_propagation) ||
+ (priv->staging_rxon.ofdm_ht_single_stream_basic_rates !=
+ priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
+ (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
+ priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
+ (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
+ return 1;
+
+ /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
+ * be updated with the RXON_ASSOC command -- however only some
+ * flag transitions are allowed using RXON_ASSOC */
+
+ /* Check if we are not switching bands */
+ if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
+ (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
+ return 1;
+
+ /* Check if we are switching association toggle */
+ if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
+ (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
+ return 1;
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_full_rxon_required);
+
+u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
+{
+ int i;
+ int rate_mask;
+
+ /* Set rate mask*/
+ if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+ rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
+ else
+ rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
+
+ /* Find lowest valid rate */
+ for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
+ i = iwl_rates[i].next_ieee) {
+ if (rate_mask & (1 << i))
+ return iwl_rates[i].plcp;
+ }
+
+ /* No valid rate was found. Assign the lowest one */
+ if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
+ return IWL_RATE_1M_PLCP;
+ else
+ return IWL_RATE_6M_PLCP;
+}
+EXPORT_SYMBOL(iwl_rate_get_lowest_plcp);
+
void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
{
struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
@@ -628,7 +823,7 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
iwl_set_rxon_chain(priv);
- IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X "
+ IWL_DEBUG_ASSOC(priv, "supported HT rate 0x%X 0x%X 0x%X "
"rxon flags 0x%X operation mode :0x%X "
"extension channel offset 0x%x\n",
ht_info->mcs.rx_mask[0],
@@ -679,7 +874,7 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
break;
case WLAN_HT_CAP_SM_PS_INVALID:
default:
- IWL_ERROR("invalid mimo ps mode %d\n",
+ IWL_ERR(priv, "invalid mimo ps mode %d\n",
priv->current_ht_config.sm_ps);
WARN_ON(1);
idle_cnt = -1;
@@ -700,6 +895,18 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
}
/**
+ * iwl_is_monitor_mode - Determine if interface in monitor mode
+ *
+ * priv->iw_mode is set in add_interface, but add_interface is
+ * never called for monitor mode. The only way mac80211 informs us about
+ * monitor mode is through configuring filters (call to configure_filter).
+ */
+static bool iwl_is_monitor_mode(struct iwl_priv *priv)
+{
+ return !!(priv->staging_rxon.filter_flags & RXON_FILTER_PROMISC_MSK);
+}
+
+/**
* iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
*
* Selects how many and which Rx receivers/antennas/chains to use.
@@ -742,6 +949,19 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
+ /* copied from 'iwl_bg_request_scan()' */
+ /* Force use of chains B and C (0x6) for Rx for 4965
+ * Avoid A (0x1) because of its off-channel reception on A-band.
+ * MIMO is not used here, but value is required */
+ if (iwl_is_monitor_mode(priv) &&
+ !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) &&
+ ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) {
+ rx_chain = 0x07 << RXON_RX_CHAIN_VALID_POS;
+ rx_chain |= 0x06 << RXON_RX_CHAIN_FORCE_SEL_POS;
+ rx_chain |= 0x07 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+ rx_chain |= 0x01 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
+ }
+
priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
@@ -749,7 +969,7 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
else
priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
- IWL_DEBUG_ASSOC("rx_chain=0x%X active=%d idle=%d\n",
+ IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
priv->staging_rxon.rx_chain,
active_rx_cnt, idle_rx_cnt);
@@ -774,7 +994,7 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
u16 channel = ieee80211_frequency_to_channel(ch->center_freq);
if (!iwl_get_channel_info(priv, band, channel)) {
- IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
+ IWL_DEBUG_INFO(priv, "Could not set channel to %d [%d]\n",
channel, band);
return -EINVAL;
}
@@ -791,12 +1011,283 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
priv->band = band;
- IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band);
+ IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band);
return 0;
}
EXPORT_SYMBOL(iwl_set_rxon_channel);
+void iwl_set_flags_for_band(struct iwl_priv *priv,
+ enum ieee80211_band band)
+{
+ if (band == IEEE80211_BAND_5GHZ) {
+ priv->staging_rxon.flags &=
+ ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
+ | RXON_FLG_CCK_MSK);
+ priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ } else {
+ /* Copied from iwl_post_associate() */
+ if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
+ priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ else
+ priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+
+ if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
+ priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+
+ priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
+ priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
+ priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
+ }
+}
+EXPORT_SYMBOL(iwl_set_flags_for_band);
+
+/*
+ * initialize rxon structure with default values from eeprom
+ */
+void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
+{
+ const struct iwl_channel_info *ch_info;
+
+ memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
+
+ switch (mode) {
+ case NL80211_IFTYPE_AP:
+ priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
+ break;
+
+ case NL80211_IFTYPE_STATION:
+ priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
+ priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
+ break;
+
+ case NL80211_IFTYPE_ADHOC:
+ priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
+ priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
+ priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
+ RXON_FILTER_ACCEPT_GRP_MSK;
+ break;
+
+ case NL80211_IFTYPE_MONITOR:
+ priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
+ priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
+ RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
+ break;
+ default:
+ IWL_ERR(priv, "Unsupported interface type %d\n", mode);
+ break;
+ }
+
+#if 0
+ /* TODO: Figure out when short_preamble would be set and cache from
+ * that */
+ if (!hw_to_local(priv->hw)->short_preamble)
+ priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ else
+ priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+#endif
+
+ ch_info = iwl_get_channel_info(priv, priv->band,
+ le16_to_cpu(priv->active_rxon.channel));
+
+ if (!ch_info)
+ ch_info = &priv->channel_info[0];
+
+ /*
+ * in some case A channels are all non IBSS
+ * in this case force B/G channel
+ */
+ if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
+ !(is_channel_ibss(ch_info)))
+ ch_info = &priv->channel_info[0];
+
+ priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
+ priv->band = ch_info->band;
+
+ iwl_set_flags_for_band(priv, priv->band);
+
+ priv->staging_rxon.ofdm_basic_rates =
+ (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
+ priv->staging_rxon.cck_basic_rates =
+ (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
+
+ priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
+ RXON_FLG_CHANNEL_MODE_PURE_40_MSK);
+ memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+ memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN);
+ priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff;
+ priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff;
+}
+EXPORT_SYMBOL(iwl_connection_init_rx_config);
+
+void iwl_set_rate(struct iwl_priv *priv)
+{
+ const struct ieee80211_supported_band *hw = NULL;
+ struct ieee80211_rate *rate;
+ int i;
+
+ hw = iwl_get_hw_mode(priv, priv->band);
+ if (!hw) {
+ IWL_ERR(priv, "Failed to set rate: unable to get hw mode\n");
+ return;
+ }
+
+ priv->active_rate = 0;
+ priv->active_rate_basic = 0;
+
+ for (i = 0; i < hw->n_bitrates; i++) {
+ rate = &(hw->bitrates[i]);
+ if (rate->hw_value < IWL_RATE_COUNT)
+ priv->active_rate |= (1 << rate->hw_value);
+ }
+
+ IWL_DEBUG_RATE(priv, "Set active_rate = %0x, active_rate_basic = %0x\n",
+ priv->active_rate, priv->active_rate_basic);
+
+ /*
+ * If a basic rate is configured, then use it (adding IWL_RATE_1M_MASK)
+ * otherwise set it to the default of all CCK rates and 6, 12, 24 for
+ * OFDM
+ */
+ if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
+ priv->staging_rxon.cck_basic_rates =
+ ((priv->active_rate_basic &
+ IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
+ else
+ priv->staging_rxon.cck_basic_rates =
+ (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
+
+ if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
+ priv->staging_rxon.ofdm_basic_rates =
+ ((priv->active_rate_basic &
+ (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
+ IWL_FIRST_OFDM_RATE) & 0xFF;
+ else
+ priv->staging_rxon.ofdm_basic_rates =
+ (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
+}
+EXPORT_SYMBOL(iwl_set_rate);
+
+void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
+ struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
+ IWL_DEBUG_11H(priv, "CSA notif: channel %d, status %d\n",
+ le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
+ rxon->channel = csa->channel;
+ priv->staging_rxon.channel = csa->channel;
+}
+EXPORT_SYMBOL(iwl_rx_csa);
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
+{
+ struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+
+ IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
+ iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
+ IWL_DEBUG_RADIO(priv, "u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
+ IWL_DEBUG_RADIO(priv, "u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
+ IWL_DEBUG_RADIO(priv, "u32 filter_flags: 0x%08x\n",
+ le32_to_cpu(rxon->filter_flags));
+ IWL_DEBUG_RADIO(priv, "u8 dev_type: 0x%x\n", rxon->dev_type);
+ IWL_DEBUG_RADIO(priv, "u8 ofdm_basic_rates: 0x%02x\n",
+ rxon->ofdm_basic_rates);
+ IWL_DEBUG_RADIO(priv, "u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
+ IWL_DEBUG_RADIO(priv, "u8[6] node_addr: %pM\n", rxon->node_addr);
+ IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
+ IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
+}
+#endif
+
+/**
+ * iwl_irq_handle_error - called for HW or SW error interrupt from card
+ */
+void iwl_irq_handle_error(struct iwl_priv *priv)
+{
+ /* Set the FW error flag -- cleared on iwl_down */
+ set_bit(STATUS_FW_ERROR, &priv->status);
+
+ /* Cancel currently queued command. */
+ clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & IWL_DL_FW_ERRORS) {
+ iwl_dump_nic_error_log(priv);
+ iwl_dump_nic_event_log(priv);
+ iwl_print_rx_config_cmd(priv);
+ }
+#endif
+
+ wake_up_interruptible(&priv->wait_command_queue);
+
+ /* Keep the restart process from trying to send host
+ * commands by clearing the INIT status bit */
+ clear_bit(STATUS_READY, &priv->status);
+
+ if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+ IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
+ "Restarting adapter due to uCode error.\n");
+
+ if (iwl_is_associated(priv)) {
+ memcpy(&priv->recovery_rxon, &priv->active_rxon,
+ sizeof(priv->recovery_rxon));
+ priv->error_recovering = 1;
+ }
+ if (priv->cfg->mod_params->restart_fw)
+ queue_work(priv->workqueue, &priv->restart);
+ }
+}
+EXPORT_SYMBOL(iwl_irq_handle_error);
+
+void iwl_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count, struct dev_addr_list *mc_list)
+{
+ struct iwl_priv *priv = hw->priv;
+ __le32 *filter_flags = &priv->staging_rxon.filter_flags;
+
+ IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
+ changed_flags, *total_flags);
+
+ if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
+ if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
+ *filter_flags |= RXON_FILTER_PROMISC_MSK;
+ else
+ *filter_flags &= ~RXON_FILTER_PROMISC_MSK;
+ }
+ if (changed_flags & FIF_ALLMULTI) {
+ if (*total_flags & FIF_ALLMULTI)
+ *filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
+ else
+ *filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
+ }
+ if (changed_flags & FIF_CONTROL) {
+ if (*total_flags & FIF_CONTROL)
+ *filter_flags |= RXON_FILTER_CTL2HOST_MSK;
+ else
+ *filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
+ }
+ if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+ if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
+ *filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
+ else
+ *filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
+ }
+
+ /* We avoid iwl_commit_rxon here to commit the new filter flags
+ * since mac80211 will call ieee80211_hw_config immediately.
+ * (mc_list is not supported at this time). Otherwise, we need to
+ * queue a background iwl_commit_rxon work.
+ */
+
+ *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
+ FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
+}
+EXPORT_SYMBOL(iwl_configure_filter);
+
int iwl_setup_mac(struct iwl_priv *priv)
{
int ret;
@@ -806,18 +1297,18 @@ int iwl_setup_mac(struct iwl_priv *priv)
/* Tell mac80211 our characteristics */
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM |
- IEEE80211_HW_AMPDU_AGGREGATION;
+ IEEE80211_HW_AMPDU_AGGREGATION |
+ IEEE80211_HW_SPECTRUM_MGMT |
+ IEEE80211_HW_SUPPORTS_PS;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
- hw->wiphy->fw_handles_regulatory = true;
+ hw->wiphy->custom_regulatory = true;
+ hw->wiphy->max_scan_ssids = 1;
/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
- /* queues to support 11n aggregation */
- if (priv->cfg->sku & IWL_SKU_N)
- hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues;
hw->conf.beacon_int = 100;
hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
@@ -831,7 +1322,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
ret = ieee80211_register_hw(priv->hw);
if (ret) {
- IWL_ERROR("Failed to register hw (error %d)\n", ret);
+ IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
return ret;
}
priv->mac80211_registered = 1;
@@ -863,7 +1354,6 @@ int iwl_init_drv(struct iwl_priv *priv)
{
int ret;
- priv->retry_rate = 1;
priv->ibss_beacon = NULL;
spin_lock_init(&priv->lock);
@@ -897,21 +1387,22 @@ int iwl_init_drv(struct iwl_priv *priv)
priv->qos_data.qos_cap.val = 0;
priv->rates_mask = IWL_RATES_MASK;
- /* If power management is turned on, default to AC mode */
- priv->power_mode = IWL_POWER_AC;
+ /* If power management is turned on, default to CAM mode */
+ priv->power_mode = IWL_POWER_MODE_CAM;
priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX;
ret = iwl_init_channel_map(priv);
if (ret) {
- IWL_ERROR("initializing regulatory failed: %d\n", ret);
+ IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
goto err;
}
ret = iwlcore_init_geos(priv);
if (ret) {
- IWL_ERROR("initializing geos failed: %d\n", ret);
+ IWL_ERR(priv, "initializing geos failed: %d\n", ret);
goto err_free_channel_map;
}
+ iwlcore_init_hw_rates(priv, priv->ieee_rates);
return 0;
@@ -926,14 +1417,16 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
{
int ret = 0;
if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) {
- IWL_WARNING("Requested user TXPOWER %d below limit.\n",
- priv->tx_power_user_lmt);
+ IWL_WARN(priv, "Requested user TXPOWER %d below lower limit %d.\n",
+ tx_power,
+ IWL_TX_POWER_TARGET_POWER_MIN);
return -EINVAL;
}
if (tx_power > IWL_TX_POWER_TARGET_POWER_MAX) {
- IWL_WARNING("Requested user TXPOWER %d above limit.\n",
- priv->tx_power_user_lmt);
+ IWL_WARN(priv, "Requested user TXPOWER %d above upper limit %d.\n",
+ tx_power,
+ IWL_TX_POWER_TARGET_POWER_MAX);
return -EINVAL;
}
@@ -942,6 +1435,10 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
priv->tx_power_user_lmt = tx_power;
+ /* if nic is not up don't send command */
+ if (!iwl_is_ready_rf(priv))
+ return ret;
+
if (force && priv->cfg->ops->lib->send_tx_power)
ret = priv->cfg->ops->lib->send_tx_power(priv);
@@ -970,18 +1467,92 @@ void iwl_disable_interrupts(struct iwl_priv *priv)
* from uCode or flow handler (Rx/Tx DMA) */
iwl_write32(priv, CSR_INT, 0xffffffff);
iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
- IWL_DEBUG_ISR("Disabled interrupts\n");
+ IWL_DEBUG_ISR(priv, "Disabled interrupts\n");
}
EXPORT_SYMBOL(iwl_disable_interrupts);
void iwl_enable_interrupts(struct iwl_priv *priv)
{
- IWL_DEBUG_ISR("Enabling interrupts\n");
+ IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
set_bit(STATUS_INT_ENABLED, &priv->status);
iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
}
EXPORT_SYMBOL(iwl_enable_interrupts);
+irqreturn_t iwl_isr(int irq, void *data)
+{
+ struct iwl_priv *priv = data;
+ u32 inta, inta_mask;
+ u32 inta_fh;
+ if (!priv)
+ return IRQ_NONE;
+
+ spin_lock(&priv->lock);
+
+ /* Disable (but don't clear!) interrupts here to avoid
+ * back-to-back ISRs and sporadic interrupts from our NIC.
+ * If we have something to service, the tasklet will re-enable ints.
+ * If we *don't* have something, we'll re-enable before leaving here. */
+ inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
+ iwl_write32(priv, CSR_INT_MASK, 0x00000000);
+
+ /* Discover which interrupts are active/pending */
+ inta = iwl_read32(priv, CSR_INT);
+ inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+
+ /* Ignore interrupt if there's nothing in NIC to service.
+ * This may be due to IRQ shared with another device,
+ * or due to sporadic interrupts thrown from our NIC. */
+ if (!inta && !inta_fh) {
+ IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0, inta_fh == 0\n");
+ goto none;
+ }
+
+ if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
+ /* Hardware disappeared. It might have already raised
+ * an interrupt */
+ IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
+ goto unplugged;
+ }
+
+ IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
+ inta, inta_mask, inta_fh);
+
+ inta &= ~CSR_INT_BIT_SCD;
+
+ /* iwl_irq_tasklet() will service interrupts and re-enable them */
+ if (likely(inta || inta_fh))
+ tasklet_schedule(&priv->irq_tasklet);
+
+ unplugged:
+ spin_unlock(&priv->lock);
+ return IRQ_HANDLED;
+
+ none:
+ /* re-enable interrupts here since we don't have anything to service. */
+ /* only Re-enable if diabled by irq */
+ if (test_bit(STATUS_INT_ENABLED, &priv->status))
+ iwl_enable_interrupts(priv);
+ spin_unlock(&priv->lock);
+ return IRQ_NONE;
+}
+EXPORT_SYMBOL(iwl_isr);
+
+int iwl_send_bt_config(struct iwl_priv *priv)
+{
+ struct iwl_bt_cmd bt_cmd = {
+ .flags = 3,
+ .lead_time = 0xAA,
+ .max_kill = 1,
+ .kill_ack_mask = 0,
+ .kill_cts_mask = 0,
+ };
+
+ return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+ sizeof(struct iwl_bt_cmd), &bt_cmd);
+}
+EXPORT_SYMBOL(iwl_send_bt_config);
+
int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
{
u32 stat_flags = 0;
@@ -1007,7 +1578,7 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
u32 errcnt = 0;
u32 i;
- IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+ IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
ret = iwl_grab_nic_access(priv);
if (ret)
@@ -1018,7 +1589,7 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
- i + RTC_INST_LOWER_BOUND);
+ i + IWL49_RTC_INST_LOWER_BOUND);
val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
ret = -EIO;
@@ -1045,13 +1616,14 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
int ret = 0;
u32 errcnt;
- IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+ IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
ret = iwl_grab_nic_access(priv);
if (ret)
return ret;
- iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
+ iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+ IWL49_RTC_INST_LOWER_BOUND);
errcnt = 0;
for (; len > 0; len -= sizeof(u32), image++) {
@@ -1060,7 +1632,7 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
* if IWL_DL_IO is set */
val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
- IWL_ERROR("uCode INST section is invalid at "
+ IWL_ERR(priv, "uCode INST section is invalid at "
"offset 0x%x, is 0x%x, s/b 0x%x\n",
save_len - len, val, le32_to_cpu(*image));
ret = -EIO;
@@ -1073,8 +1645,8 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
iwl_release_nic_access(priv);
if (!errcnt)
- IWL_DEBUG_INFO
- ("ucode image in INSTRUCTION memory is good\n");
+ IWL_DEBUG_INFO(priv,
+ "ucode image in INSTRUCTION memory is good\n");
return ret;
}
@@ -1094,7 +1666,7 @@ int iwl_verify_ucode(struct iwl_priv *priv)
len = priv->ucode_boot.len;
ret = iwlcore_verify_inst_sparse(priv, image, len);
if (!ret) {
- IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n");
+ IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
return 0;
}
@@ -1103,7 +1675,7 @@ int iwl_verify_ucode(struct iwl_priv *priv)
len = priv->ucode_init.len;
ret = iwlcore_verify_inst_sparse(priv, image, len);
if (!ret) {
- IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n");
+ IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
return 0;
}
@@ -1112,11 +1684,11 @@ int iwl_verify_ucode(struct iwl_priv *priv)
len = priv->ucode_code.len;
ret = iwlcore_verify_inst_sparse(priv, image, len);
if (!ret) {
- IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n");
+ IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
return 0;
}
- IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
+ IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
/* Since nothing seems to match, show first several data entries in
* instruction SRAM, so maybe visual inspection will give a clue.
@@ -1188,21 +1760,22 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
- IWL_ERROR("Not valid error log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
return;
}
ret = iwl_grab_nic_access(priv);
if (ret) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
count = iwl_read_targ_mem(priv, base);
if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
- IWL_ERROR("Start IWL Error Log Dump:\n");
- IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
+ IWL_ERR(priv, "Start IWL Error Log Dump:\n");
+ IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
+ priv->status, count);
}
desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
@@ -1215,12 +1788,12 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
- IWL_ERROR("Desc Time "
+ IWL_ERR(priv, "Desc Time "
"data1 data2 line\n");
- IWL_ERROR("%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
+ IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
desc_lookup(desc), desc, time, data1, data2, line);
- IWL_ERROR("blink1 blink2 ilink1 ilink2\n");
- IWL_ERROR("0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
+ IWL_ERR(priv, "blink1 blink2 ilink1 ilink2\n");
+ IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
ilink1, ilink2);
iwl_release_nic_access(priv);
@@ -1266,11 +1839,11 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
ptr += sizeof(u32);
if (mode == 0) {
/* data, ev */
- IWL_ERROR("EVT_LOG:0x%08x:%04u\n", time, ev);
+ IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
} else {
data = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- IWL_ERROR("EVT_LOGT:%010u:0x%08x:%04u\n",
+ IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
time, data, ev);
}
}
@@ -1292,13 +1865,13 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
- IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
return;
}
ret = iwl_grab_nic_access(priv);
if (ret) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
@@ -1312,12 +1885,12 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
/* bail out if nothing in log */
if (size == 0) {
- IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
+ IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
iwl_release_nic_access(priv);
return;
}
- IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
+ IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
size, num_wraps);
/* if uCode has wrapped back to top of log, start at the oldest entry,
@@ -1349,9 +1922,9 @@ void iwl_rf_kill_ct_config(struct iwl_priv *priv)
ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
sizeof(cmd), &cmd);
if (ret)
- IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n");
+ IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
else
- IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, "
+ IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD succeeded, "
"critical temperature is %d\n",
cmd.critical_temperature_R);
}
@@ -1368,7 +1941,7 @@ EXPORT_SYMBOL(iwl_rf_kill_ct_config);
* When in the 'halt' state, the card is shut down and must be fully
* restarted to come back on.
*/
-static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
+int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
{
struct iwl_host_cmd cmd = {
.id = REPLY_CARD_STATE_CMD,
@@ -1379,6 +1952,7 @@ static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
return iwl_send_cmd(priv, &cmd);
}
+EXPORT_SYMBOL(iwl_send_card_state);
void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv)
{
@@ -1387,7 +1961,7 @@ void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv)
if (test_bit(STATUS_RF_KILL_SW, &priv->status))
return;
- IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO OFF\n");
+ IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO OFF\n");
iwl_scan_cancel(priv);
/* FIXME: This is a workaround for AP */
@@ -1416,7 +1990,7 @@ int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
if (!test_bit(STATUS_RF_KILL_SW, &priv->status))
return 0;
- IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO ON\n");
+ IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO ON\n");
spin_lock_irqsave(&priv->lock, flags);
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
@@ -1441,7 +2015,7 @@ int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
- IWL_DEBUG_RF_KILL("Can not turn radio back on - "
+ IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - "
"disabled by HW switch\n");
return 0;
}
@@ -1463,3 +2037,78 @@ int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
return 1;
}
EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio);
+
+void iwl_bg_rf_kill(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);
+
+ wake_up_interruptible(&priv->wait_command_queue);
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ mutex_lock(&priv->mutex);
+
+ if (!iwl_is_rfkill(priv)) {
+ IWL_DEBUG_RF_KILL(priv,
+ "HW and/or SW RF Kill no longer active, restarting "
+ "device\n");
+ if (!test_bit(STATUS_EXIT_PENDING, &priv->status) &&
+ test_bit(STATUS_ALIVE, &priv->status))
+ queue_work(priv->workqueue, &priv->restart);
+ } else {
+ /* make sure mac80211 stop sending Tx frame */
+ if (priv->mac80211_registered)
+ ieee80211_stop_queues(priv->hw);
+
+ if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
+ IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - "
+ "disabled by SW switch\n");
+ else
+ IWL_WARN(priv, "Radio Frequency Kill Switch is On:\n"
+ "Kill switch must be turned off for "
+ "wireless networking to work.\n");
+ }
+ mutex_unlock(&priv->mutex);
+ iwl_rfkill_set_hw_state(priv);
+}
+EXPORT_SYMBOL(iwl_bg_rf_kill);
+
+void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
+ IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
+ sleep->pm_sleep_mode, sleep->pm_wakeup_src);
+#endif
+}
+EXPORT_SYMBOL(iwl_rx_pm_sleep_notif);
+
+void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
+ "notification for %s:\n",
+ le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
+ iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+}
+EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif);
+
+void iwl_rx_reply_error(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+
+ IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
+ "seq 0x%04X ser 0x%08X\n",
+ le32_to_cpu(pkt->u.err_resp.error_type),
+ get_cmd_string(pkt->u.err_resp.cmd_id),
+ pkt->u.err_resp.cmd_id,
+ le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
+ le32_to_cpu(pkt->u.err_resp.error_info));
+}
+EXPORT_SYMBOL(iwl_rx_reply_error);
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7c3a20a986bb..a8eac8c3c1fa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,7 @@ struct iwl_cmd;
#define IWLWIFI_VERSION "1.3.27k"
-#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
+#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
#define DRV_AUTHOR "<ilw@linux.intel.com>"
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -110,6 +110,14 @@ struct iwl_lib_ops {
void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv,
struct iwl_tx_queue *txq);
void (*txq_set_sched)(struct iwl_priv *priv, u32 mask);
+ int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr,
+ u16 len, u8 reset, u8 pad);
+ void (*txq_free_tfd)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
+ int (*txq_init)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
/* aggregations */
int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
int sta_id, int tid, u16 ssn_idx);
@@ -203,6 +211,9 @@ struct iwl_cfg {
u16 eeprom_calib_ver;
const struct iwl_ops *ops;
const struct iwl_mod_params *mod_params;
+ u8 valid_tx_ant;
+ u8 valid_rx_ant;
+ bool need_pll_cfg;
};
/***************************
@@ -213,11 +224,26 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
struct ieee80211_ops *hw_ops);
void iwl_hw_detect(struct iwl_priv *priv);
void iwl_reset_qos(struct iwl_priv *priv);
+void iwl_activate_qos(struct iwl_priv *priv, u8 force);
+void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
+int iwl_check_rxon_cmd(struct iwl_priv *priv);
+int iwl_full_rxon_required(struct iwl_priv *priv);
void iwl_set_rxon_chain(struct iwl_priv *priv);
int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info);
u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
struct ieee80211_sta_ht_cap *sta_ht_inf);
+void iwl_set_flags_for_band(struct iwl_priv *priv, enum ieee80211_band band);
+void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode);
+int iwl_set_decrypted_flag(struct iwl_priv *priv,
+ struct ieee80211_hdr *hdr,
+ u32 decrypt_res,
+ struct ieee80211_rx_status *stats);
+void iwl_irq_handle_error(struct iwl_priv *priv);
+void iwl_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count, struct dev_addr_list *mc_list);
int iwl_hw_nic_init(struct iwl_priv *priv);
int iwl_setup_mac(struct iwl_priv *priv);
int iwl_set_hw_params(struct iwl_priv *priv);
@@ -225,9 +251,20 @@ int iwl_init_drv(struct iwl_priv *priv);
void iwl_uninit_drv(struct iwl_priv *priv);
/*****************************************************
+ * RX handlers.
+ * **************************************************/
+void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_reply_error(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb);
+
+/*****************************************************
* RX
******************************************************/
void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
+void iwl_cmd_queue_free(struct iwl_priv *priv);
int iwl_rx_queue_alloc(struct iwl_priv *priv);
void iwl_rx_handle(struct iwl_priv *priv);
int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
@@ -245,6 +282,7 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
/* TX helpers */
@@ -252,9 +290,18 @@ void iwl_rx_statistics(struct iwl_priv *priv,
* TX
******************************************************/
int iwl_txq_ctx_reset(struct iwl_priv *priv);
+void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len, u8 reset, u8 pad);
int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
+int iwl_hw_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+ int slots_num, u32 txq_id);
+void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
@@ -267,7 +314,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
* RF -Kill - here and not in iwl-rfkill.h to be available when
* RF-kill subsystem is not compiled.
****************************************************/
-void iwl_rf_kill(struct iwl_priv *priv);
+void iwl_bg_rf_kill(struct work_struct *work);
void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv);
int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv);
@@ -279,6 +326,10 @@ void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
struct ieee80211_tx_info *info);
int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
+u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
+
+void iwl_set_rate(struct iwl_priv *priv);
+
u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx);
static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
@@ -306,8 +357,30 @@ void iwl_init_scan_params(struct iwl_priv *priv);
int iwl_scan_cancel(struct iwl_priv *priv);
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
int iwl_scan_initiate(struct iwl_priv *priv);
+int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
+u16 iwl_fill_probe_req(struct iwl_priv *priv, enum ieee80211_band band,
+ struct ieee80211_mgmt *frame, int left);
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
+u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 n_probes);
+u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band);
+void iwl_bg_scan_check(struct work_struct *data);
+void iwl_bg_abort_scan(struct work_struct *work);
+void iwl_bg_scan_completed(struct work_struct *work);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
+int iwl_send_scan_abort(struct iwl_priv *priv);
+
+/* For faster active scanning, scan will move to the next channel if fewer than
+ * PLCP_QUIET_THRESH packets are heard on this channel within
+ * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
+ * time if it's a quiet channel (nothing responded to our probe, and there's
+ * no other traffic).
+ * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
+#define IWL_ACTIVE_QUIET_TIME cpu_to_le16(10) /* msec */
+#define IWL_PLCP_QUIET_THRESH cpu_to_le16(1) /* packets */
+
/*******************************************************************************
* Calibrations - implemented in iwl-calib.c
@@ -319,7 +392,7 @@ void iwl_calib_free_results(struct iwl_priv *priv);
/*******************************************************************************
* Spectrum Measureemtns in iwl-spectrum.c
******************************************************************************/
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
void iwl_setup_spectrum_handlers(struct iwl_priv *priv);
#else
static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {}
@@ -342,11 +415,23 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
+int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
+ u8 meta_flag);
+
/*****************************************************
* PCI *
*****************************************************/
void iwl_disable_interrupts(struct iwl_priv *priv);
void iwl_enable_interrupts(struct iwl_priv *priv);
+irqreturn_t iwl_isr(int irq, void *data);
+static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
+{
+ int pos;
+ u16 pci_lnk_ctl;
+ pos = pci_find_capability(priv->pci_dev, PCI_CAP_ID_EXP);
+ pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
+ return pci_lnk_ctl;
+}
/*****************************************************
* Error Handling Debugging
@@ -354,6 +439,11 @@ void iwl_enable_interrupts(struct iwl_priv *priv);
void iwl_dump_nic_error_log(struct iwl_priv *priv);
void iwl_dump_nic_event_log(struct iwl_priv *priv);
+/*****************************************************
+* GEOS
+******************************************************/
+int iwlcore_init_geos(struct iwl_priv *priv);
+void iwlcore_free_geos(struct iwl_priv *priv);
/*************** DRIVER STATUS FUNCTIONS *****/
@@ -422,6 +512,7 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
}
extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
+extern int iwl_send_bt_config(struct iwl_priv *priv);
extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags);
extern int iwl_verify_ucode(struct iwl_priv *priv);
extern int iwl_send_lq_cmd(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index f34ede44ed10..2f1242447b3b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -211,6 +211,9 @@
#define CSR_HW_REV_TYPE_5350 (0x0000030)
#define CSR_HW_REV_TYPE_5100 (0x0000050)
#define CSR_HW_REV_TYPE_5150 (0x0000040)
+#define CSR_HW_REV_TYPE_1000 (0x0000060)
+#define CSR_HW_REV_TYPE_6x00 (0x0000070)
+#define CSR_HW_REV_TYPE_6x50 (0x0000080)
#define CSR_HW_REV_TYPE_NONE (0x00000F0)
/* EEPROM REG */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 56c13b458de7..65d1a7f2db9e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
@@ -29,16 +29,29 @@
#ifndef __iwl_debug_h__
#define __iwl_debug_h__
+struct iwl_priv;
+
+#define IWL_ERR(p, f, a...) dev_err(&((p)->pci_dev->dev), f, ## a)
+#define IWL_WARN(p, f, a...) dev_warn(&((p)->pci_dev->dev), f, ## a)
+#define IWL_INFO(p, f, a...) dev_info(&((p)->pci_dev->dev), f, ## a)
+#define IWL_CRIT(p, f, a...) dev_crit(&((p)->pci_dev->dev), f, ## a)
+
#ifdef CONFIG_IWLWIFI_DEBUG
-#define IWL_DEBUG(level, fmt, args...) \
-do { if (priv->debug_level & (level)) \
- dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
+#define IWL_DEBUG(__priv, level, fmt, args...) \
+do { \
+ if (__priv->debug_level & (level)) \
+ dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev), \
+ "%c %s " fmt, in_interrupt() ? 'I' : 'U', \
+ __func__ , ## args); \
+} while (0)
-#define IWL_DEBUG_LIMIT(level, fmt, args...) \
-do { if ((priv->debug_level & (level)) && net_ratelimit()) \
- dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
+#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) \
+do { \
+ if ((__priv->debug_level & (level)) && net_ratelimit()) \
+ dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev), \
+ "%c %s " fmt, in_interrupt() ? 'I' : 'U', \
+ __func__ , ## args); \
+} while (0)
#define iwl_print_hex_dump(priv, level, p, len) \
do { \
@@ -61,6 +74,7 @@ struct iwl_debugfs {
struct dentry *file_tx_statistics;
struct dentry *file_log_event;
struct dentry *file_channels;
+ struct dentry *file_status;
} dbgfs_data_files;
struct dir_rf_files {
struct dentry *file_disable_sensitivity;
@@ -76,8 +90,8 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv);
#endif
#else
-#define IWL_DEBUG(level, fmt, args...)
-#define IWL_DEBUG_LIMIT(level, fmt, args...)
+#define IWL_DEBUG(__priv, level, fmt, args...)
+#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
void *p, u32 len)
{}
@@ -117,84 +131,85 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
* when CONFIG_IWLWIFI_DEBUG=y.
*/
+/* 0x0000000F - 0x00000001 */
#define IWL_DL_INFO (1 << 0)
#define IWL_DL_MAC80211 (1 << 1)
#define IWL_DL_HCMD (1 << 2)
#define IWL_DL_STATE (1 << 3)
+/* 0x000000F0 - 0x00000010 */
#define IWL_DL_MACDUMP (1 << 4)
#define IWL_DL_HCMD_DUMP (1 << 5)
-#define IWL_DL_RADIO (1 << 7)
-#define IWL_DL_POWER (1 << 8)
-#define IWL_DL_TEMP (1 << 9)
-
-#define IWL_DL_NOTIF (1 << 10)
-#define IWL_DL_SCAN (1 << 11)
-#define IWL_DL_ASSOC (1 << 12)
-#define IWL_DL_DROP (1 << 13)
-
-#define IWL_DL_TXPOWER (1 << 14)
-
-#define IWL_DL_AP (1 << 15)
-
-#define IWL_DL_FW (1 << 16)
-#define IWL_DL_RF_KILL (1 << 17)
-#define IWL_DL_FW_ERRORS (1 << 18)
-
-#define IWL_DL_LED (1 << 19)
-
-#define IWL_DL_RATE (1 << 20)
-
-#define IWL_DL_CALIB (1 << 21)
-#define IWL_DL_WEP (1 << 22)
-#define IWL_DL_TX (1 << 23)
-#define IWL_DL_RX (1 << 24)
-#define IWL_DL_ISR (1 << 25)
-#define IWL_DL_HT (1 << 26)
-#define IWL_DL_IO (1 << 27)
-#define IWL_DL_11H (1 << 28)
-
-#define IWL_DL_STATS (1 << 29)
-#define IWL_DL_TX_REPLY (1 << 30)
-#define IWL_DL_QOS (1 << 31)
-
-#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
-#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
-#define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a)
-
-#define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a)
-#define IWL_DEBUG_MACDUMP(f, a...) IWL_DEBUG(IWL_DL_MACDUMP, f, ## a)
-#define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a)
-#define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a)
-#define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a)
-#define IWL_DEBUG_TX(f, a...) IWL_DEBUG(IWL_DL_TX, f, ## a)
-#define IWL_DEBUG_ISR(f, a...) IWL_DEBUG(IWL_DL_ISR, f, ## a)
-#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a)
-#define IWL_DEBUG_WEP(f, a...) IWL_DEBUG(IWL_DL_WEP, f, ## a)
-#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HCMD, f, ## a)
-#define IWL_DEBUG_HC_DUMP(f, a...) IWL_DEBUG(IWL_DL_HCMD_DUMP, f, ## a)
-#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a)
-#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a)
-#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a)
-#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a)
-#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
-#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
-#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
-#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
- IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
-#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
-#define IWL_DEBUG_TX_REPLY_LIMIT(f, a...) \
- IWL_DEBUG_LIMIT(IWL_DL_TX_REPLY, f, ## a)
-#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a)
-#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a)
-#define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a)
-#define IWL_DEBUG_11H(f, a...) IWL_DEBUG(IWL_DL_11H, f, ## a)
+#define IWL_DL_RADIO (1 << 7)
+/* 0x00000F00 - 0x00000100 */
+#define IWL_DL_POWER (1 << 8)
+#define IWL_DL_TEMP (1 << 9)
+#define IWL_DL_NOTIF (1 << 10)
+#define IWL_DL_SCAN (1 << 11)
+/* 0x0000F000 - 0x00001000 */
+#define IWL_DL_ASSOC (1 << 12)
+#define IWL_DL_DROP (1 << 13)
+#define IWL_DL_TXPOWER (1 << 14)
+#define IWL_DL_AP (1 << 15)
+/* 0x000F0000 - 0x00010000 */
+#define IWL_DL_FW (1 << 16)
+#define IWL_DL_RF_KILL (1 << 17)
+#define IWL_DL_FW_ERRORS (1 << 18)
+#define IWL_DL_LED (1 << 19)
+/* 0x00F00000 - 0x00100000 */
+#define IWL_DL_RATE (1 << 20)
+#define IWL_DL_CALIB (1 << 21)
+#define IWL_DL_WEP (1 << 22)
+#define IWL_DL_TX (1 << 23)
+/* 0x0F000000 - 0x01000000 */
+#define IWL_DL_RX (1 << 24)
+#define IWL_DL_ISR (1 << 25)
+#define IWL_DL_HT (1 << 26)
+#define IWL_DL_IO (1 << 27)
+/* 0xF0000000 - 0x10000000 */
+#define IWL_DL_11H (1 << 28)
+#define IWL_DL_STATS (1 << 29)
+#define IWL_DL_TX_REPLY (1 << 30)
+#define IWL_DL_QOS (1 << 31)
+
+#define IWL_DEBUG_INFO(p, f, a...) IWL_DEBUG(p, IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_MAC80211(p, f, a...) IWL_DEBUG(p, IWL_DL_MAC80211, f, ## a)
+#define IWL_DEBUG_MACDUMP(p, f, a...) IWL_DEBUG(p, IWL_DL_MACDUMP, f, ## a)
+#define IWL_DEBUG_TEMP(p, f, a...) IWL_DEBUG(p, IWL_DL_TEMP, f, ## a)
+#define IWL_DEBUG_SCAN(p, f, a...) IWL_DEBUG(p, IWL_DL_SCAN, f, ## a)
+#define IWL_DEBUG_RX(p, f, a...) IWL_DEBUG(p, IWL_DL_RX, f, ## a)
+#define IWL_DEBUG_TX(p, f, a...) IWL_DEBUG(p, IWL_DL_TX, f, ## a)
+#define IWL_DEBUG_ISR(p, f, a...) IWL_DEBUG(p, IWL_DL_ISR, f, ## a)
+#define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a)
+#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a)
+#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a)
+#define IWL_DEBUG_HC_DUMP(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD_DUMP, f, ## a)
+#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a)
+#define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a)
+#define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a)
+#define IWL_DEBUG_DROP(p, f, a...) IWL_DEBUG(p, IWL_DL_DROP, f, ## a)
+#define IWL_DEBUG_DROP_LIMIT(p, f, a...) \
+ IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a)
+#define IWL_DEBUG_AP(p, f, a...) IWL_DEBUG(p, IWL_DL_AP, f, ## a)
+#define IWL_DEBUG_TXPOWER(p, f, a...) IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a)
+#define IWL_DEBUG_IO(p, f, a...) IWL_DEBUG(p, IWL_DL_IO, f, ## a)
+#define IWL_DEBUG_RATE(p, f, a...) IWL_DEBUG(p, IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_RATE_LIMIT(p, f, a...) \
+ IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_NOTIF(p, f, a...) IWL_DEBUG(p, IWL_DL_NOTIF, f, ## a)
+#define IWL_DEBUG_ASSOC(p, f, a...) \
+ IWL_DEBUG(p, IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_ASSOC_LIMIT(p, f, a...) \
+ IWL_DEBUG_LIMIT(p, IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_HT(p, f, a...) IWL_DEBUG(p, IWL_DL_HT, f, ## a)
+#define IWL_DEBUG_STATS(p, f, a...) IWL_DEBUG(p, IWL_DL_STATS, f, ## a)
+#define IWL_DEBUG_STATS_LIMIT(p, f, a...) \
+ IWL_DEBUG_LIMIT(p, IWL_DL_STATS, f, ## a)
+#define IWL_DEBUG_TX_REPLY(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_REPLY, f, ## a)
+#define IWL_DEBUG_TX_REPLY_LIMIT(p, f, a...) \
+ IWL_DEBUG_LIMIT(p, IWL_DL_TX_REPLY, f, ## a)
+#define IWL_DEBUG_QOS(p, f, a...) IWL_DEBUG(p, IWL_DL_QOS, f, ## a)
+#define IWL_DEBUG_RADIO(p, f, a...) IWL_DEBUG(p, IWL_DL_RADIO, f, ## a)
+#define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a)
+#define IWL_DEBUG_11H(p, f, a...) IWL_DEBUG(p, IWL_DL_11H, f, ## a)
#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index d5253a179dec..64eb585f1578 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -63,6 +63,14 @@
goto err; \
} while (0)
+#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
+ dbgfs->dbgfs_##parent##_files.file_##name = \
+ debugfs_create_x32(#name, 0444, dbgfs->dir_##parent, ptr); \
+ if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \
+ || !dbgfs->dbgfs_##parent##_files.file_##name) \
+ goto err; \
+} while (0)
+
#define DEBUGFS_REMOVE(name) do { \
debugfs_remove(name); \
name = NULL; \
@@ -164,9 +172,6 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
const size_t bufsz = sizeof(buf);
- printk(KERN_DEBUG "offset is: 0x%x\tlen is: 0x%x\n",
- priv->dbgfs->sram_offset, priv->dbgfs->sram_len);
-
iwl_grab_nic_access(priv);
for (i = priv->dbgfs->sram_len; i > 0; i -= 4) {
val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \
@@ -301,14 +306,14 @@ static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
buf_size = 4 * eeprom_len + 256;
if (eeprom_len % 16) {
- IWL_ERROR("EEPROM size is not multiple of 16.\n");
+ IWL_ERR(priv, "EEPROM size is not multiple of 16.\n");
return -ENODATA;
}
/* 4 characters for byte 0xYY */
buf = kzalloc(buf_size, GFP_KERNEL);
if (!buf) {
- IWL_ERROR("Can not allocate Buffer\n");
+ IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM;
}
@@ -365,7 +370,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) {
- IWL_ERROR("Can not allocate Buffer\n");
+ IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM;
}
@@ -420,6 +425,55 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
return ret;
}
+static ssize_t iwl_dbgfs_status_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos) {
+
+ struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+ char buf[512];
+ int pos = 0;
+ const size_t bufsz = sizeof(buf);
+
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
+ test_bit(STATUS_HCMD_ACTIVE, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_SYNC_ACTIVE: %d\n",
+ test_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
+ test_bit(STATUS_INT_ENABLED, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
+ test_bit(STATUS_RF_KILL_HW, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_SW:\t %d\n",
+ test_bit(STATUS_RF_KILL_SW, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
+ test_bit(STATUS_INIT, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
+ test_bit(STATUS_ALIVE, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n",
+ test_bit(STATUS_READY, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n",
+ test_bit(STATUS_TEMPERATURE, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n",
+ test_bit(STATUS_GEO_CONFIGURED, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
+ test_bit(STATUS_EXIT_PENDING, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_IN_SUSPEND:\t %d\n",
+ test_bit(STATUS_IN_SUSPEND, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
+ test_bit(STATUS_STATISTICS, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
+ test_bit(STATUS_SCANNING, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n",
+ test_bit(STATUS_SCAN_ABORTING, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n",
+ test_bit(STATUS_SCAN_HW, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n",
+ test_bit(STATUS_POWER_PMI, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n",
+ test_bit(STATUS_FW_ERROR, &priv->status));
+ pos += scnprintf(buf + pos, bufsz - pos, "STATUS_MODE_PENDING:\t %d\n",
+ test_bit(STATUS_MODE_PENDING, &priv->status));
+ return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
DEBUGFS_READ_WRITE_FILE_OPS(sram);
DEBUGFS_WRITE_FILE_OPS(log_event);
@@ -428,6 +482,7 @@ DEBUGFS_READ_FILE_OPS(stations);
DEBUGFS_READ_FILE_OPS(rx_statistics);
DEBUGFS_READ_FILE_OPS(tx_statistics);
DEBUGFS_READ_FILE_OPS(channels);
+DEBUGFS_READ_FILE_OPS(status);
/*
* Create the debugfs files and directories
@@ -462,6 +517,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(rx_statistics, data);
DEBUGFS_ADD_FILE(tx_statistics, data);
DEBUGFS_ADD_FILE(channels, data);
+ DEBUGFS_ADD_FILE(status, data);
DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
&priv->disable_chain_noise_cal);
@@ -469,7 +525,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
return 0;
err:
- IWL_ERROR("Can't open the debugfs directory\n");
+ IWL_ERR(priv, "Can't open the debugfs directory\n");
iwl_dbgfs_unregister(priv);
return ret;
}
@@ -491,6 +547,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
+ DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
DEBUGFS_REMOVE(priv->dbgfs->dir_data);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 0468fcc1ea98..ec9a13846edd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -36,13 +36,15 @@
#include <linux/kernel.h>
#include <net/ieee80211_radiotap.h>
-#define DRV_NAME "iwlagn"
-#include "iwl-rfkill.h"
#include "iwl-eeprom.h"
-#include "iwl-4965-hw.h"
#include "iwl-csr.h"
#include "iwl-prph.h"
+#include "iwl-fh.h"
#include "iwl-debug.h"
+#include "iwl-rfkill.h"
+#include "iwl-4965-hw.h"
+#include "iwl-3945-hw.h"
+#include "iwl-3945-led.h"
#include "iwl-led.h"
#include "iwl-power.h"
#include "iwl-agn-rs.h"
@@ -55,6 +57,28 @@ extern struct iwl_cfg iwl5350_agn_cfg;
extern struct iwl_cfg iwl5100_bg_cfg;
extern struct iwl_cfg iwl5100_abg_cfg;
extern struct iwl_cfg iwl5150_agn_cfg;
+extern struct iwl_cfg iwl6000_2ag_cfg;
+extern struct iwl_cfg iwl6000_2agn_cfg;
+extern struct iwl_cfg iwl6000_3agn_cfg;
+extern struct iwl_cfg iwl6050_2agn_cfg;
+extern struct iwl_cfg iwl6050_3agn_cfg;
+extern struct iwl_cfg iwl1000_bgn_cfg;
+
+/* shared structures from iwl-5000.c */
+extern struct iwl_mod_params iwl50_mod_params;
+extern struct iwl_ops iwl5000_ops;
+extern struct iwl_lib_ops iwl5000_lib;
+extern struct iwl_hcmd_ops iwl5000_hcmd;
+extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils;
+
+/* shared functions from iwl-5000.c */
+extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len);
+extern u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd,
+ u8 *data);
+extern void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
+ __le32 *tx_flags);
+extern int iwl5000_calc_rssi(struct iwl_priv *priv,
+ struct iwl_rx_phy_res *rx_resp);
/* CT-KILL constants */
#define CT_KILL_THRESHOLD 110 /* in Celsius */
@@ -132,9 +156,12 @@ struct iwl_tx_info {
* A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
* descriptors) and required locking structures.
*/
+#define TFD_TX_CMD_SLOTS 256
+#define TFD_CMD_SLOTS 32
+
struct iwl_tx_queue {
struct iwl_queue q;
- struct iwl_tfd *tfds;
+ void *tfds;
struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
struct iwl_tx_info *txb;
u8 need_update;
@@ -154,6 +181,36 @@ struct iwl4965_channel_tgh_info {
s64 last_radar_time;
};
+#define IWL4965_MAX_RATE (33)
+
+struct iwl3945_clip_group {
+ /* maximum power level to prevent clipping for each rate, derived by
+ * us from this band's saturation power in EEPROM */
+ const s8 clip_powers[IWL_MAX_RATES];
+};
+
+/* current Tx power values to use, one for each rate for each channel.
+ * requested power is limited by:
+ * -- regulatory EEPROM limits for this channel
+ * -- hardware capabilities (clip-powers)
+ * -- spectrum management
+ * -- user preference (e.g. iwconfig)
+ * when requested power is set, base power index must also be set. */
+struct iwl3945_channel_power_info {
+ struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
+ s8 power_table_index; /* actual (compenst'd) index into gain table */
+ s8 base_power_index; /* gain index for power at factory temp. */
+ s8 requested_power; /* power (dBm) requested for this chnl/rate */
+};
+
+/* current scan Tx power values to use, one for each scan rate for each
+ * channel. */
+struct iwl3945_scan_power_info {
+ struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */
+ s8 power_table_index; /* actual (compenst'd) index into gain table */
+ s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */
+};
+
/*
* One for each channel, holds all channel setup data
* Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
@@ -184,8 +241,15 @@ struct iwl_channel_info {
s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */
u8 fat_flags; /* flags copied from EEPROM */
u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */
-};
+ /* Radio/DSP gain settings for each "normal" data Tx rate.
+ * These include, in addition to RF and DSP gain, a few fields for
+ * remembering/modifying gain settings (indexes). */
+ struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE];
+
+ /* Radio/DSP gain settings for each scan rate, for directed scans. */
+ struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
+};
#define IWL_TX_FIFO_AC0 0
#define IWL_TX_FIFO_AC1 1
@@ -370,7 +434,7 @@ struct iwl_hw_key {
u8 key[32];
};
-union iwl4965_ht_rate_supp {
+union iwl_ht_rate_supp {
u16 rates;
struct {
u8 siso_rate;
@@ -430,6 +494,24 @@ struct iwl_qos_info {
#define STA_PS_STATUS_WAKE 0
#define STA_PS_STATUS_SLEEP 1
+struct iwl3945_tid_data {
+ u16 seq_number;
+};
+
+struct iwl3945_hw_key {
+ enum ieee80211_key_alg alg;
+ int keylen;
+ u8 key[32];
+};
+
+struct iwl3945_station_entry {
+ struct iwl3945_addsta_cmd sta;
+ struct iwl3945_tid_data tid[MAX_TID_COUNT];
+ u8 used;
+ u8 ps_status;
+ struct iwl3945_hw_key keyinfo;
+};
+
struct iwl_station_entry {
struct iwl_addsta_cmd sta;
struct iwl_tid_data tid[MAX_TID_COUNT];
@@ -497,11 +579,13 @@ struct iwl_sensitivity_ranges {
* @max_txq_num: Max # Tx queues supported
* @dma_chnl_num: Number of Tx DMA/FIFO channels
* @scd_bc_tbls_size: size of scheduler byte count tables
+ * @tfd_size: TFD size
* @tx/rx_chains_num: Number of TX/RX chains
* @valid_tx/rx_ant: usable antennas
* @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
* @max_rxq_log: Log-base-2 of max_rxq_size
* @rx_buf_size: Rx buffer size
+ * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR
* @max_stations:
* @bcast_sta_id:
* @fat_channel: is 40MHz width possible in band 2.4
@@ -516,6 +600,7 @@ struct iwl_hw_params {
u8 max_txq_num;
u8 dma_chnl_num;
u16 scd_bc_tbls_size;
+ u32 tfd_size;
u8 tx_chains_num;
u8 rx_chains_num;
u8 valid_tx_ant;
@@ -523,6 +608,7 @@ struct iwl_hw_params {
u16 max_rxq_size;
u16 max_rxq_log;
u32 rx_buf_size;
+ u32 rx_wrt_ptr_reg;
u32 max_pkt_size;
u8 max_stations;
u8 bcast_sta_id;
@@ -755,7 +841,7 @@ struct iwl_priv {
struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
-#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
+#if defined(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) || defined(CONFIG_IWL3945_SPECTRUM_MEASUREMENT)
/* spectrum measurement report caching */
struct iwl_spectrum_notification measure_report;
u8 measurement_status;
@@ -768,6 +854,10 @@ struct iwl_priv {
struct iwl_channel_info *channel_info; /* channel info array */
u8 channel_count; /* # of channels */
+ /* each calibration channel group in the EEPROM has a derived
+ * clip setting for each rate. 3945 only.*/
+ const struct iwl3945_clip_group clip39_groups[5];
+
/* thermal calibration */
s32 temperature; /* degrees Kelvin */
s32 last_temperature;
@@ -781,7 +871,7 @@ struct iwl_priv {
unsigned long scan_start;
unsigned long scan_pass_start;
unsigned long scan_start_tsf;
- struct iwl_scan_cmd *scan;
+ void *scan;
int scan_bands;
int one_direct_scan;
u8 direct_ssid_len;
@@ -832,18 +922,18 @@ struct iwl_priv {
* 4965's initialize alive response contains some calibration data. */
struct iwl_init_alive_resp card_alive_init;
struct iwl_alive_resp card_alive;
-#ifdef CONFIG_IWLWIFI_RFKILL
+#if defined(CONFIG_IWLWIFI_RFKILL)
struct rfkill *rfkill;
#endif
#ifdef CONFIG_IWLWIFI_LEDS
- struct iwl_led led[IWL_LED_TRG_MAX];
unsigned long last_blink_time;
u8 last_blink_rate;
u8 allow_blinking;
u64 led_tpt;
+ struct iwl_led led[IWL_LED_TRG_MAX];
+ unsigned int rxtxpackets;
#endif
-
u16 active_rate;
u16 active_rate_basic;
@@ -893,7 +983,6 @@ struct iwl_priv {
u16 rates_mask;
u32 power_mode;
- u32 antenna;
u8 bssid[ETH_ALEN];
u16 rts_threshold;
u8 mac_addr[ETH_ALEN];
@@ -907,6 +996,12 @@ struct iwl_priv {
u8 key_mapping_key;
unsigned long ucode_key_table;
+ /* queue refcounts */
+#define IWL_MAX_HW_QUEUES 32
+ unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)];
+ /* for each AC */
+ atomic_t queue_stop_count[4];
+
/* Indication if ieee80211_ops->open has been called */
u8 is_open;
@@ -929,6 +1024,10 @@ struct iwl_priv {
u16 beacon_int;
struct ieee80211_vif *vif;
+ /*Added for 3945 */
+ void *shared_virt;
+ dma_addr_t shared_phys;
+ /*End*/
struct iwl_hw_params hw_params;
@@ -960,6 +1059,11 @@ struct iwl_priv {
struct delayed_work init_alive_start;
struct delayed_work alive_start;
struct delayed_work scan_check;
+
+ /*For 3945 only*/
+ struct delayed_work thermal_periodic;
+ struct delayed_work rfkill_poll;
+
/* TX Power */
s8 tx_power_user_lmt;
s8 tx_power_channel_lmt;
@@ -982,6 +1086,15 @@ struct iwl_priv {
u32 disable_tx_power_cal;
struct work_struct run_time_calib_work;
struct timer_list statistics_periodic;
+
+ /*For 3945*/
+#define IWL_DEFAULT_TX_POWER 0x0F
+
+ struct iwl3945_notif_statistics statistics_39;
+
+ struct iwl3945_station_entry stations_39[IWL_STATION_COUNT];
+
+ u32 sta_supp_rates;
}; /*iwl_priv */
static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index ce2f47306cea..75517d05df08 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -145,7 +145,7 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
{
u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
- IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
+ IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
return -ENOENT;
}
return 0;
@@ -173,7 +173,7 @@ int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
EEPROM_SEM_TIMEOUT);
if (ret >= 0) {
- IWL_DEBUG_IO("Acquired semaphore after %d tries.\n",
+ IWL_DEBUG_IO(priv, "Acquired semaphore after %d tries.\n",
count+1);
return ret;
}
@@ -223,7 +223,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
if (ret < 0) {
- IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
+ IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
ret = -ENOENT;
goto err;
}
@@ -231,7 +231,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
/* Make sure driver (instead of uCode) is allowed to read EEPROM */
ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv);
if (ret < 0) {
- IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
+ IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
ret = -ENOENT;
goto err;
}
@@ -247,7 +247,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
CSR_EEPROM_REG_READ_VALID_MSK,
IWL_EEPROM_ACCESS_TIMEOUT);
if (ret < 0) {
- IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
+ IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
goto done;
}
r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
@@ -285,7 +285,7 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
return 0;
err:
- IWL_ERROR("Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
+ IWL_ERR(priv, "Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
eeprom_ver, priv->cfg->eeprom_ver,
calib_ver, priv->cfg->eeprom_calib_ver);
return -EINVAL;
@@ -390,7 +390,7 @@ static int iwl_set_fat_chan_info(struct iwl_priv *priv,
if (!is_channel_valid(ch_info))
return -1;
- IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
+ IWL_DEBUG_INFO(priv, "FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
" Ad-Hoc %ssupported\n",
ch_info->channel,
is_channel_a_band(ch_info) ?
@@ -432,11 +432,11 @@ int iwl_init_channel_map(struct iwl_priv *priv)
struct iwl_channel_info *ch_info;
if (priv->channel_count) {
- IWL_DEBUG_INFO("Channel map already initialized.\n");
+ IWL_DEBUG_INFO(priv, "Channel map already initialized.\n");
return 0;
}
- IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n");
+ IWL_DEBUG_INFO(priv, "Initializing regulatory info from EEPROM\n");
priv->channel_count =
ARRAY_SIZE(iwl_eeprom_band_1) +
@@ -445,12 +445,12 @@ int iwl_init_channel_map(struct iwl_priv *priv)
ARRAY_SIZE(iwl_eeprom_band_4) +
ARRAY_SIZE(iwl_eeprom_band_5);
- IWL_DEBUG_INFO("Parsing data for %d channels.\n", priv->channel_count);
+ IWL_DEBUG_INFO(priv, "Parsing data for %d channels.\n", priv->channel_count);
priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) *
priv->channel_count, GFP_KERNEL);
if (!priv->channel_info) {
- IWL_ERROR("Could not allocate channel_info\n");
+ IWL_ERR(priv, "Could not allocate channel_info\n");
priv->channel_count = 0;
return -ENOMEM;
}
@@ -485,7 +485,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
IEEE80211_CHAN_NO_FAT_BELOW);
if (!(is_channel_valid(ch_info))) {
- IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - "
+ IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - "
"No traffic\n",
ch_info->channel,
ch_info->flags,
@@ -501,7 +501,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
ch_info->min_power = 0;
- IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):"
+ IWL_DEBUG_INFO(priv, "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):"
" Ad-Hoc %ssupported\n",
ch_info->channel,
is_channel_a_band(ch_info) ?
@@ -520,7 +520,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
flags & EEPROM_CHANNEL_RADAR))
? "" : "not ");
- /* Set the user_txpower_limit to the highest power
+ /* Set the tx_power_user_lmt to the highest power
* supported by any channel */
if (eeprom_ch_info[ch].max_power_avg >
priv->tx_power_user_lmt)
@@ -531,6 +531,13 @@ int iwl_init_channel_map(struct iwl_priv *priv)
}
}
+ /* Check if we do have FAT channels */
+ if (priv->cfg->ops->lib->eeprom_ops.regulatory_bands[5] ==
+ EEPROM_REGULATORY_BAND_NO_FAT &&
+ priv->cfg->ops->lib->eeprom_ops.regulatory_bands[6] ==
+ EEPROM_REGULATORY_BAND_NO_FAT)
+ return 0;
+
/* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */
for (band = 6; band <= 7; band++) {
enum ieee80211_band ieeeband;
@@ -582,6 +589,7 @@ void iwl_free_channel_map(struct iwl_priv *priv)
kfree(priv->channel_info);
priv->channel_count = 0;
}
+EXPORT_SYMBOL(iwl_free_channel_map);
/**
* iwl_get_channel_info - Find driver's private channel info
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 603c84bed630..3479153d96ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -118,6 +118,9 @@ struct iwl_eeprom_channel {
s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */
} __attribute__ ((packed));
+/* 3945 Specific */
+#define EEPROM_3945_EEPROM_VERSION (0x2f)
+
/* 4965 has two radio transmitters (and 3 radio receivers) */
#define EEPROM_TX_POWER_TX_CHAINS (2)
@@ -367,6 +370,8 @@ struct iwl_eeprom_calib_info {
*/
#define EEPROM_4965_REGULATORY_BAND_52_FAT_CHANNELS (2*0xA8) /* 22 bytes */
+#define EEPROM_REGULATORY_BAND_NO_FAT (0)
+
struct iwl_eeprom_ops {
const u32 regulatory_bands[7];
int (*verify_signature) (struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index d7da19864550..65fa8a69fd5a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -399,6 +399,21 @@
*/
#define FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN (0x00000002)
+#define RX_QUEUE_SIZE 256
+#define RX_QUEUE_MASK 255
+#define RX_QUEUE_SIZE_LOG 8
+
+/*
+ * RX related structures and functions
+ */
+#define RX_FREE_BUFFERS 64
+#define RX_LOW_WATERMARK 8
+
+/* Size of one Rx buffer in host DRAM */
+#define IWL_RX_BUF_SIZE_3K (3 * 1000) /* 3945 only */
+#define IWL_RX_BUF_SIZE_4K (4 * 1024)
+#define IWL_RX_BUF_SIZE_8K (8 * 1024)
+
/**
* struct iwl_rb_status - reseve buffer status
* host memory mapped FH registers
@@ -414,6 +429,7 @@ struct iwl_rb_status {
__le16 closed_fr_num;
__le16 finished_rb_num;
__le16 finished_fr_nam;
+ __le32 __unused; /* 3945 only */
} __attribute__ ((packed));
@@ -477,7 +493,6 @@ struct iwl_tfd {
__le32 __pad;
} __attribute__ ((packed));
-
/* Keep Warm Size */
#define IWL_KW_SIZE 0x1000 /* 4k */
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 4b35b30e493e..17d61ac8ed61 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -109,14 +109,14 @@ static int iwl_generic_cmd_callback(struct iwl_priv *priv,
struct iwl_rx_packet *pkt = NULL;
if (!skb) {
- IWL_ERROR("Error: Response NULL in %s.\n",
+ IWL_ERR(priv, "Error: Response NULL in %s.\n",
get_cmd_string(cmd->hdr.cmd));
return 1;
}
pkt = (struct iwl_rx_packet *)skb->data;
if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from %s (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from %s (0x%08X)\n",
get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
return 1;
}
@@ -125,11 +125,11 @@ static int iwl_generic_cmd_callback(struct iwl_priv *priv,
switch (cmd->hdr.cmd) {
case REPLY_TX_LINK_QUALITY_CMD:
case SENSITIVITY_CMD:
- IWL_DEBUG_HC_DUMP("back from %s (0x%08X)\n",
+ IWL_DEBUG_HC_DUMP(priv, "back from %s (0x%08X)\n",
get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
break;
default:
- IWL_DEBUG_HC("back from %s (0x%08X)\n",
+ IWL_DEBUG_HC(priv, "back from %s (0x%08X)\n",
get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
}
#endif
@@ -156,7 +156,7 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
ret = iwl_enqueue_hcmd(priv, cmd);
if (ret < 0) {
- IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
+ IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
get_cmd_string(cmd->id), ret);
return ret;
}
@@ -174,8 +174,9 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
BUG_ON(cmd->meta.u.callback != NULL);
if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
- IWL_ERROR("Error sending %s: Already sending a host command\n",
- get_cmd_string(cmd->id));
+ IWL_ERR(priv,
+ "Error sending %s: Already sending a host command\n",
+ get_cmd_string(cmd->id));
ret = -EBUSY;
goto out;
}
@@ -188,7 +189,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
cmd_idx = iwl_enqueue_hcmd(priv, cmd);
if (cmd_idx < 0) {
ret = cmd_idx;
- IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
+ IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
get_cmd_string(cmd->id), ret);
goto out;
}
@@ -198,9 +199,10 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
HOST_COMPLETE_TIMEOUT);
if (!ret) {
if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) {
- IWL_ERROR("Error sending %s: time out after %dms.\n",
- get_cmd_string(cmd->id),
- jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
+ IWL_ERR(priv,
+ "Error sending %s: time out after %dms.\n",
+ get_cmd_string(cmd->id),
+ jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
ret = -ETIMEDOUT;
@@ -209,19 +211,19 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
}
if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
- IWL_DEBUG_INFO("Command %s aborted: RF KILL Switch\n",
+ IWL_DEBUG_INFO(priv, "Command %s aborted: RF KILL Switch\n",
get_cmd_string(cmd->id));
ret = -ECANCELED;
goto fail;
}
if (test_bit(STATUS_FW_ERROR, &priv->status)) {
- IWL_DEBUG_INFO("Command %s failed: FW Error\n",
+ IWL_DEBUG_INFO(priv, "Command %s failed: FW Error\n",
get_cmd_string(cmd->id));
ret = -EIO;
goto fail;
}
if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) {
- IWL_ERROR("Error: Response NULL in '%s'\n",
+ IWL_ERR(priv, "Error: Response NULL in '%s'\n",
get_cmd_string(cmd->id));
ret = -EIO;
goto cancel;
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index ca4f638ab9d0..a1328c3c81ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -93,4 +93,56 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
return (desc->v_addr != NULL) ? 0 : -ENOMEM;
}
+/*
+ * we have 8 bits used like this:
+ *
+ * 7 6 5 4 3 2 1 0
+ * | | | | | | | |
+ * | | | | | | +-+-------- AC queue (0-3)
+ * | | | | | |
+ * | +-+-+-+-+------------ HW A-MPDU queue
+ * |
+ * +---------------------- indicates agg queue
+ */
+static inline u8 iwl_virtual_agg_queue_num(u8 ac, u8 hwq)
+{
+ BUG_ON(ac > 3); /* only have 2 bits */
+ BUG_ON(hwq > 31); /* only have 5 bits */
+
+ return 0x80 | (hwq << 2) | ac;
+}
+
+static inline void iwl_wake_queue(struct iwl_priv *priv, u8 queue)
+{
+ u8 ac = queue;
+ u8 hwq = queue;
+
+ if (queue & 0x80) {
+ ac = queue & 3;
+ hwq = (queue >> 2) & 0x1f;
+ }
+
+ if (test_and_clear_bit(hwq, priv->queue_stopped))
+ if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0)
+ ieee80211_wake_queue(priv->hw, ac);
+}
+
+static inline void iwl_stop_queue(struct iwl_priv *priv, u8 queue)
+{
+ u8 ac = queue;
+ u8 hwq = queue;
+
+ if (queue & 0x80) {
+ ac = queue & 3;
+ hwq = (queue >> 2) & 0x1f;
+ }
+
+ if (!test_and_set_bit(hwq, priv->queue_stopped))
+ if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0)
+ ieee80211_stop_queue(priv->hw, ac);
+}
+
+#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue
+#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue
+
#endif /* __iwl_helpers_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 0a92e7431ada..083ea1ffbe87 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project.
*
@@ -66,7 +66,7 @@
static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
u32 ofs, u32 val)
{
- IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
+ IWL_DEBUG_IO(priv, "write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
_iwl_write32(priv, ofs, val);
}
#define iwl_write32(priv, ofs, val) \
@@ -79,7 +79,7 @@ static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
#ifdef CONFIG_IWLWIFI_DEBUG
static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs)
{
- IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
+ IWL_DEBUG_IO(priv, "read_direct32(0x%08X) - %s %d\n", ofs, f, l);
return _iwl_read32(priv, ofs);
}
#define iwl_read32(priv, ofs) __iwl_read32(__FILE__, __LINE__, priv, ofs)
@@ -108,7 +108,7 @@ static inline int __iwl_poll_bit(const char *f, u32 l,
u32 bits, u32 mask, int timeout)
{
int ret = _iwl_poll_bit(priv, addr, bits, mask, timeout);
- IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
+ IWL_DEBUG_IO(priv, "poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
addr, bits, mask,
unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l);
return ret;
@@ -128,7 +128,7 @@ static inline void __iwl_set_bit(const char *f, u32 l,
struct iwl_priv *priv, u32 reg, u32 mask)
{
u32 val = _iwl_read32(priv, reg) | mask;
- IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
+ IWL_DEBUG_IO(priv, "set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
_iwl_write32(priv, reg, val);
}
#define iwl_set_bit(p, r, m) __iwl_set_bit(__FILE__, __LINE__, p, r, m)
@@ -145,7 +145,7 @@ static inline void __iwl_clear_bit(const char *f, u32 l,
struct iwl_priv *priv, u32 reg, u32 mask)
{
u32 val = _iwl_read32(priv, reg) & ~mask;
- IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
+ IWL_DEBUG_IO(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
_iwl_write32(priv, reg, val);
}
#define iwl_clear_bit(p, r, m) __iwl_clear_bit(__FILE__, __LINE__, p, r, m)
@@ -156,6 +156,7 @@ static inline void __iwl_clear_bit(const char *f, u32 l,
static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
{
int ret;
+ u32 val;
#ifdef CONFIG_IWLWIFI_DEBUG
if (atomic_read(&priv->restrict_refcnt))
return 0;
@@ -165,9 +166,10 @@ static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
(CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
- CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
+ CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
if (ret < 0) {
- IWL_ERROR("MAC is in deep sleep!\n");
+ val = _iwl_read32(priv, CSR_GP_CNTRL);
+ IWL_ERR(priv, "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
return -EIO;
}
@@ -182,9 +184,9 @@ static inline int __iwl_grab_nic_access(const char *f, u32 l,
struct iwl_priv *priv)
{
if (atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Grabbing access while already held %s %d.\n", f, l);
+ IWL_ERR(priv, "Grabbing access while already held %s %d.\n", f, l);
- IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l);
+ IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l);
return _iwl_grab_nic_access(priv);
}
#define iwl_grab_nic_access(priv) \
@@ -207,9 +209,9 @@ static inline void __iwl_release_nic_access(const char *f, u32 l,
struct iwl_priv *priv)
{
if (atomic_read(&priv->restrict_refcnt) <= 0)
- IWL_ERROR("Release unheld nic access at line %s %d.\n", f, l);
+ IWL_ERR(priv, "Release unheld nic access at line %s %d.\n", f, l);
- IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l);
+ IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l);
_iwl_release_nic_access(priv);
}
#define iwl_release_nic_access(priv) \
@@ -229,8 +231,8 @@ static inline u32 __iwl_read_direct32(const char *f, u32 l,
{
u32 value = _iwl_read_direct32(priv, reg);
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s %d\n", f, l);
- IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
+ IWL_ERR(priv, "Nic access not held from %s %d\n", f, l);
+ IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
f, l);
return value;
}
@@ -250,7 +252,7 @@ static void __iwl_write_direct32(const char *f , u32 line,
struct iwl_priv *priv, u32 reg, u32 value)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
_iwl_write_direct32(priv, reg, value);
}
#define iwl_write_direct32(priv, reg, value) \
@@ -284,10 +286,10 @@ static inline int __iwl_poll_direct_bit(const char *f, u32 l,
int ret = _iwl_poll_direct_bit(priv, addr, mask, timeout);
if (unlikely(ret == -ETIMEDOUT))
- IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - "
+ IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) - "
"timedout - %s %d\n", addr, mask, f, l);
else
- IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
+ IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
"- %s %d\n", addr, mask, ret, f, l);
return ret;
}
@@ -308,7 +310,7 @@ static inline u32 __iwl_read_prph(const char *f, u32 line,
struct iwl_priv *priv, u32 reg)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
return _iwl_read_prph(priv, reg);
}
@@ -331,7 +333,7 @@ static inline void __iwl_write_prph(const char *f, u32 line,
struct iwl_priv *priv, u32 addr, u32 val)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
_iwl_write_prph(priv, addr, val);
}
@@ -349,7 +351,7 @@ static inline void __iwl_set_bits_prph(const char *f, u32 line,
u32 reg, u32 mask)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
_iwl_set_bits_prph(priv, reg, mask);
}
@@ -367,7 +369,7 @@ static inline void __iwl_set_bits_mask_prph(const char *f, u32 line,
struct iwl_priv *priv, u32 reg, u32 bits, u32 mask)
{
if (!atomic_read(&priv->restrict_refcnt))
- IWL_ERROR("Nic access not held from %s line %d\n", f, line);
+ IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
_iwl_set_bits_mask_prph(priv, reg, bits, mask);
}
#define iwl_set_bits_mask_prph(priv, reg, bits, mask) \
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 11eccd7d268c..19680f72087f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -123,7 +123,7 @@ static int iwl4965_led_pattern(struct iwl_priv *priv, int led_id,
/* Set led register off */
static int iwl4965_led_on_reg(struct iwl_priv *priv, int led_id)
{
- IWL_DEBUG_LED("led on %d\n", led_id);
+ IWL_DEBUG_LED(priv, "led on %d\n", led_id);
iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
return 0;
}
@@ -150,7 +150,7 @@ int iwl4965_led_off(struct iwl_priv *priv, int led_id)
.off = 0,
.interval = IWL_DEF_LED_INTRVL
};
- IWL_DEBUG_LED("led off %d\n", led_id);
+ IWL_DEBUG_LED(priv, "led off %d\n", led_id);
return iwl_send_led_cmd(priv, &led_cmd);
}
#endif
@@ -159,7 +159,7 @@ int iwl4965_led_off(struct iwl_priv *priv, int led_id)
/* Set led register off */
static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id)
{
- IWL_DEBUG_LED("LED Reg off\n");
+ IWL_DEBUG_LED(priv, "LED Reg off\n");
iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
return 0;
}
@@ -169,7 +169,7 @@ static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id)
*/
static int iwl_led_associate(struct iwl_priv *priv, int led_id)
{
- IWL_DEBUG_LED("Associated\n");
+ IWL_DEBUG_LED(priv, "Associated\n");
priv->allow_blinking = 1;
return iwl4965_led_on_reg(priv, led_id);
}
@@ -213,7 +213,7 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev,
return;
- IWL_DEBUG_LED("Led type = %s brightness = %d\n",
+ IWL_DEBUG_LED(priv, "Led type = %s brightness = %d\n",
led_type_str[led->type], brightness);
switch (brightness) {
case LED_FULL:
@@ -254,7 +254,7 @@ static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led,
ret = led_classdev_register(device, &led->led_dev);
if (ret) {
- IWL_ERROR("Error: failed to register led handler.\n");
+ IWL_ERR(priv, "Error: failed to register led handler.\n");
return ret;
}
@@ -280,7 +280,7 @@ static int iwl_get_blink_rate(struct iwl_priv *priv)
if (tpt < 0) /* wraparound */
tpt = -tpt;
- IWL_DEBUG_LED("tpt %lld current_tpt %llu\n",
+ IWL_DEBUG_LED(priv, "tpt %lld current_tpt %llu\n",
(long long)tpt,
(unsigned long long)current_tpt);
priv->led_tpt = current_tpt;
@@ -292,7 +292,7 @@ static int iwl_get_blink_rate(struct iwl_priv *priv)
if (tpt > (blink_tbl[i].tpt * IWL_1MB_RATE))
break;
- IWL_DEBUG_LED("LED BLINK IDX=%d\n", i);
+ IWL_DEBUG_LED(priv, "LED BLINK IDX=%d\n", i);
return i;
}
@@ -352,7 +352,7 @@ int iwl_leds_register(struct iwl_priv *priv)
trigger = ieee80211_get_radio_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_RADIO].name,
- sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
+ sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
wiphy_name(priv->hw->wiphy));
priv->led[IWL_LED_TRG_RADIO].led_on = iwl4965_led_on_reg;
@@ -366,7 +366,7 @@ int iwl_leds_register(struct iwl_priv *priv)
trigger = ieee80211_get_assoc_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
- sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
+ sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s::assoc",
wiphy_name(priv->hw->wiphy));
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC],
@@ -382,7 +382,7 @@ int iwl_leds_register(struct iwl_priv *priv)
trigger = ieee80211_get_rx_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_RX].name,
- sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
+ sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s::RX",
wiphy_name(priv->hw->wiphy));
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX],
@@ -397,7 +397,7 @@ int iwl_leds_register(struct iwl_priv *priv)
trigger = ieee80211_get_tx_led_name(priv->hw);
snprintf(priv->led[IWL_LED_TRG_TX].name,
- sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
+ sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s::TX",
wiphy_name(priv->hw->wiphy));
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX],
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h
index 021e00bcd1be..ef9b174c37ff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.h
+++ b/drivers/net/wireless/iwlwifi/iwl-led.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -35,7 +35,7 @@ struct iwl_priv;
#define IWL_LED_SOLID 11
#define IWL_LED_NAME_LEN 31
-#define IWL_DEF_LED_INTRVL __constant_cpu_to_le32(1000)
+#define IWL_DEF_LED_INTRVL cpu_to_le32(1000)
#define IWL_LED_ACTIVITY (0<<1)
#define IWL_LED_LINK (1<<1)
@@ -47,7 +47,9 @@ enum led_type {
IWL_LED_TRG_RADIO,
IWL_LED_TRG_MAX,
};
+#endif
+#ifdef CONFIG_IWLWIFI_LEDS
struct iwl_led {
struct iwl_priv *priv;
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 75ca6a542174..47c894530eb5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -60,14 +60,6 @@
#define IWL_POWER_RANGE_1_MAX (10)
-#define NOSLP __constant_cpu_to_le16(0), 0, 0
-#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
-#define SLP_TOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)
-#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \
- __constant_cpu_to_le32(X1), \
- __constant_cpu_to_le32(X2), \
- __constant_cpu_to_le32(X3), \
- __constant_cpu_to_le32(X4)}
#define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_5
#define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM
@@ -110,6 +102,7 @@ static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
};
+
/* set card power command */
static int iwl_set_power(struct iwl_priv *priv, void *cmd)
{
@@ -134,13 +127,6 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
else
mode = IWL_POWER_ON_AC_DISASSOC;
break;
- /* FIXME: remove battery and ac from here */
- case IWL_POWER_BATTERY:
- mode = IWL_POWER_INDEX_3;
- break;
- case IWL_POWER_AC:
- mode = IWL_POWER_MODE_CAM;
- break;
default:
mode = priv->power_data.user_power_setting;
break;
@@ -149,17 +135,17 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
}
/* initialize to default */
-static int iwl_power_init_handle(struct iwl_priv *priv)
+static void iwl_power_init_handle(struct iwl_priv *priv)
{
struct iwl_power_mgr *pow_data;
int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
struct iwl_powertable_cmd *cmd;
int i;
- u16 pci_pm;
+ u16 lctl;
- IWL_DEBUG_POWER("Initialize power \n");
+ IWL_DEBUG_POWER(priv, "Initialize power \n");
- pow_data = &(priv->power_data);
+ pow_data = &priv->power_data;
memset(pow_data, 0, sizeof(*pow_data));
@@ -167,38 +153,37 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
memcpy(&pow_data->pwr_range_2[0], &range_2[0], size);
- pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &pci_pm);
+ lctl = iwl_pcie_link_ctl(priv);
- IWL_DEBUG_POWER("adjust power command flags\n");
+ IWL_DEBUG_POWER(priv, "adjust power command flags\n");
for (i = 0; i < IWL_POWER_MAX; i++) {
cmd = &pow_data->pwr_range_0[i].cmd;
- if (pci_pm & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
+ if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
else
cmd->flags |= IWL_POWER_PCI_PM_MSK;
}
- return 0;
}
/* adjust power command according to DTIM period and power level*/
-static int iwl_update_power_command(struct iwl_priv *priv,
- struct iwl_powertable_cmd *cmd,
- u16 mode)
+static int iwl_update_power_cmd(struct iwl_priv *priv,
+ struct iwl_powertable_cmd *cmd, u16 mode)
{
- int ret = 0, i;
- u8 skip;
- u32 max_sleep = 0;
struct iwl_power_vec_entry *range;
- u8 period = 0;
struct iwl_power_mgr *pow_data;
+ int i;
+ u32 max_sleep = 0;
+ u8 period;
+ bool skip;
if (mode > IWL_POWER_INDEX_5) {
- IWL_DEBUG_POWER("Error invalid power mode \n");
- return -1;
+ IWL_DEBUG_POWER(priv, "Error invalid power mode \n");
+ return -EINVAL;
}
- pow_data = &(priv->power_data);
+
+ pow_data = &priv->power_data;
if (pow_data->dtim_period <= IWL_POWER_RANGE_0_MAX)
range = &pow_data->pwr_range_0[0];
@@ -212,14 +197,12 @@ static int iwl_update_power_command(struct iwl_priv *priv,
if (period == 0) {
period = 1;
- skip = 0;
- } else
- skip = range[mode].no_dtim;
-
- if (skip == 0) {
- max_sleep = period;
- cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
+ skip = false;
} else {
+ skip = !!range[mode].no_dtim;
+ }
+
+ if (skip) {
__le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
max_sleep = le32_to_cpu(slp_itrvl);
if (max_sleep == 0xFF)
@@ -227,24 +210,26 @@ static int iwl_update_power_command(struct iwl_priv *priv,
else if (max_sleep > period)
max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
+ } else {
+ max_sleep = period;
+ cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
}
- for (i = 0; i < IWL_POWER_VEC_SIZE; i++) {
+ for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
- }
- IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags);
- IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
- IWL_DEBUG_POWER("Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
- IWL_DEBUG_POWER("Sleep interval vector = { %d , %d , %d , %d , %d }\n",
+ IWL_DEBUG_POWER(priv, "Flags value = 0x%08X\n", cmd->flags);
+ IWL_DEBUG_POWER(priv, "Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
+ IWL_DEBUG_POWER(priv, "Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
+ IWL_DEBUG_POWER(priv, "Sleep interval vector = { %d , %d , %d , %d , %d }\n",
le32_to_cpu(cmd->sleep_interval[0]),
le32_to_cpu(cmd->sleep_interval[1]),
le32_to_cpu(cmd->sleep_interval[2]),
le32_to_cpu(cmd->sleep_interval[3]),
le32_to_cpu(cmd->sleep_interval[4]));
- return ret;
+ return 0;
}
@@ -288,14 +273,14 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
if (priv->iw_mode != NL80211_IFTYPE_STATION)
final_mode = IWL_POWER_MODE_CAM;
- if (!iwl_is_rfkill(priv) && !setting->power_disabled &&
+ if (iwl_is_ready_rf(priv) && !setting->power_disabled &&
((setting->power_mode != final_mode) || force)) {
struct iwl_powertable_cmd cmd;
if (final_mode != IWL_POWER_MODE_CAM)
set_bit(STATUS_POWER_PMI, &priv->status);
- iwl_update_power_command(priv, &cmd, final_mode);
+ iwl_update_power_cmd(priv, &cmd, final_mode);
cmd.keep_alive_beacons = 0;
if (final_mode == IWL_POWER_INDEX_5)
@@ -311,7 +296,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
if (priv->cfg->ops->lib->update_chain_flags && update_chains)
priv->cfg->ops->lib->update_chain_flags(priv);
else
- IWL_DEBUG_POWER("Cannot update the power, chain noise "
+ IWL_DEBUG_POWER(priv, "Cannot update the power, chain noise "
"calibration running: %d\n",
priv->chain_noise_data.state);
if (!ret)
@@ -366,7 +351,7 @@ EXPORT_SYMBOL(iwl_power_enable_management);
/* set user_power_setting */
int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
{
- if (mode > IWL_POWER_LIMIT)
+ if (mode > IWL_POWER_MAX)
return -EINVAL;
priv->power_data.user_power_setting = mode;
@@ -380,11 +365,10 @@ EXPORT_SYMBOL(iwl_power_set_user_mode);
*/
int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)
{
- if (mode > IWL_POWER_LIMIT)
+ if (mode < IWL_POWER_SYS_MAX)
+ priv->power_data.system_power_setting = mode;
+ else
return -EINVAL;
-
- priv->power_data.system_power_setting = mode;
-
return iwl_power_update_mode(priv, 0);
}
EXPORT_SYMBOL(iwl_power_set_system_mode);
@@ -392,13 +376,11 @@ EXPORT_SYMBOL(iwl_power_set_system_mode);
/* initialize to default */
void iwl_power_initialize(struct iwl_priv *priv)
{
-
iwl_power_init_handle(priv);
priv->power_data.user_power_setting = IWL_POWER_AUTO;
- priv->power_data.power_disabled = 0;
priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO;
- priv->power_data.is_battery_active = 0;
priv->power_data.power_disabled = 0;
+ priv->power_data.is_battery_active = 0;
priv->power_data.critical_power_setting = 0;
}
EXPORT_SYMBOL(iwl_power_initialize);
@@ -407,8 +389,8 @@ EXPORT_SYMBOL(iwl_power_initialize);
int iwl_power_temperature_change(struct iwl_priv *priv)
{
int ret = 0;
- u16 new_critical = priv->power_data.critical_power_setting;
s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature);
+ u16 new_critical = priv->power_data.critical_power_setting;
if (temperature > IWL_CT_KILL_TEMPERATURE)
return 0;
@@ -434,7 +416,7 @@ static void iwl_bg_set_power_save(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work,
struct iwl_priv, set_power_save.work);
- IWL_DEBUG(IWL_DL_STATE, "update power\n");
+ IWL_DEBUG_POWER(priv, "update power\n");
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index fa098d8975ce..18963392121e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -42,22 +42,26 @@ enum {
IWL_POWER_INDEX_5,
IWL_POWER_AUTO,
IWL_POWER_MAX = IWL_POWER_AUTO,
- IWL_POWER_AC,
- IWL_POWER_BATTERY,
};
enum {
IWL_POWER_SYS_AUTO,
IWL_POWER_SYS_AC,
IWL_POWER_SYS_BATTERY,
+ IWL_POWER_SYS_MAX,
};
-#define IWL_POWER_LIMIT 0x08
-#define IWL_POWER_MASK 0x0F
-#define IWL_POWER_ENABLED 0x10
/* Power management (not Tx power) structures */
+#define NOSLP cpu_to_le16(0), 0, 0
+#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
+#define SLP_TOUT(T) cpu_to_le32((T) * MSEC_TO_USEC)
+#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \
+ cpu_to_le32(X1), \
+ cpu_to_le32(X2), \
+ cpu_to_le32(X3), \
+ cpu_to_le32(X4)}
struct iwl_power_vec_entry {
struct iwl_powertable_cmd cmd;
u8 no_dtim;
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index b7a5f23351c3..3b9cac3fd216 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,7 +30,7 @@
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
index 4b69da30665c..2ad9faf1508a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -47,7 +47,7 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return 0;
- IWL_DEBUG_RF_KILL("we received soft RFKILL set to state %d\n", state);
+ IWL_DEBUG_RF_KILL(priv, "we received soft RFKILL set to state %d\n", state);
mutex_lock(&priv->mutex);
switch (state) {
@@ -62,7 +62,8 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
iwl_radio_kill_sw_disable_radio(priv);
break;
default:
- IWL_WARNING("we received unexpected RFKILL state %d\n", state);
+ IWL_WARN(priv, "we received unexpected RFKILL state %d\n",
+ state);
break;
}
out_unlock:
@@ -78,10 +79,10 @@ int iwl_rfkill_init(struct iwl_priv *priv)
BUG_ON(device == NULL);
- IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
+ IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n");
priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
if (!priv->rfkill) {
- IWL_ERROR("Unable to allocate RFKILL device.\n");
+ IWL_ERR(priv, "Unable to allocate RFKILL device.\n");
ret = -ENOMEM;
goto error;
}
@@ -97,11 +98,11 @@ int iwl_rfkill_init(struct iwl_priv *priv)
ret = rfkill_register(priv->rfkill);
if (ret) {
- IWL_ERROR("Unable to register RFKILL: %d\n", ret);
+ IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret);
goto free_rfkill;
}
- IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
+ IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n");
return ret;
free_rfkill:
@@ -110,7 +111,7 @@ free_rfkill:
priv->rfkill = NULL;
error:
- IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
+ IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n");
return ret;
}
EXPORT_SYMBOL(iwl_rfkill_init);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
index 86dc055a2e94..633dafb4bf1b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index c5f1aa0feac8..8f65908f66f1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -125,9 +125,10 @@ EXPORT_SYMBOL(iwl_rx_queue_space);
*/
int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
{
- u32 reg = 0;
- int ret = 0;
unsigned long flags;
+ u32 rx_wrt_ptr_reg = priv->hw_params.rx_wrt_ptr_reg;
+ u32 reg;
+ int ret = 0;
spin_lock_irqsave(&q->lock, flags);
@@ -149,15 +150,14 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
goto exit_unlock;
/* Device expects a multiple of 8 */
- iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
- q->write & ~0x7);
+ iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write & ~0x7);
iwl_release_nic_access(priv);
/* Else device is assumed to be awake */
- } else
+ } else {
/* Device expects a multiple of 8 */
- iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
-
+ iwl_write32(priv, rx_wrt_ptr_reg, q->write & ~0x7);
+ }
q->need_update = 0;
@@ -262,8 +262,7 @@ void iwl_rx_allocate(struct iwl_priv *priv)
rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
GFP_KERNEL);
if (!rxb->skb) {
- printk(KERN_CRIT DRV_NAME
- "Can not allocate SKB buffers\n");
+ IWL_CRIT(priv, "Can not allocate SKB buffers\n");
/* We don't reschedule replenish work here -- we will
* call the restock method and if it still needs
* more buffers it will schedule replenish */
@@ -495,7 +494,7 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
missed_beacon = &pkt->u.missed_beacon;
if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) {
- IWL_DEBUG_CALIB("missed bcn cnsq %d totl %d rcd %d expctd %d\n",
+ IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
le32_to_cpu(missed_beacon->consequtive_missed_beacons),
le32_to_cpu(missed_beacon->total_missed_becons),
le32_to_cpu(missed_beacon->num_recvd_beacons),
@@ -542,7 +541,7 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
else
priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
- IWL_DEBUG_CALIB("inband silence a %u, b %u, c %u, dBm %d\n",
+ IWL_DEBUG_CALIB(priv, "inband silence a %u, b %u, c %u, dBm %d\n",
bcn_silence_a, bcn_silence_b, bcn_silence_c,
priv->last_rx_noise);
}
@@ -555,7 +554,7 @@ void iwl_rx_statistics(struct iwl_priv *priv,
int change;
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
+ IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
(int)sizeof(priv->statistics), pkt->len);
change = ((priv->statistics.general.temperature !=
@@ -742,13 +741,13 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
* MAC addresses show just the last byte (for brevity),
* but you can hack it to show more, if you'd like to. */
if (dataframe)
- IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
+ IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
"len=%u, rssi=%d, chnl=%d, rate=%u, \n",
title, le16_to_cpu(fc), header->addr1[5],
length, rssi, channel, bitrate);
else {
/* src/dst addresses assume managed mode */
- IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, src=0x%02x, "
+ IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, src=0x%02x, "
"len=%u, rssi=%d, tim=%lu usec, "
"phy=0x%02x, chnl=%d\n",
title, le16_to_cpu(fc), header->addr1[5],
@@ -773,10 +772,10 @@ static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len)
/*
* returns non-zero if packet should be dropped
*/
-static int iwl_set_decrypted_flag(struct iwl_priv *priv,
- struct ieee80211_hdr *hdr,
- u32 decrypt_res,
- struct ieee80211_rx_status *stats)
+int iwl_set_decrypted_flag(struct iwl_priv *priv,
+ struct ieee80211_hdr *hdr,
+ u32 decrypt_res,
+ struct ieee80211_rx_status *stats)
{
u16 fc = le16_to_cpu(hdr->frame_control);
@@ -786,7 +785,7 @@ static int iwl_set_decrypted_flag(struct iwl_priv *priv,
if (!(fc & IEEE80211_FCTL_PROTECTED))
return 0;
- IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
+ IWL_DEBUG_RX(priv, "decrypt_res:0x%x\n", decrypt_res);
switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
case RX_RES_STATUS_SEC_TYPE_TKIP:
/* The uCode has got a bad phase 1 Key, pushes the packet.
@@ -800,13 +799,13 @@ static int iwl_set_decrypted_flag(struct iwl_priv *priv,
RX_RES_STATUS_BAD_ICV_MIC) {
/* bad ICV, the packet is destroyed since the
* decryption is inplace, drop it */
- IWL_DEBUG_RX("Packet destroyed\n");
+ IWL_DEBUG_RX(priv, "Packet destroyed\n");
return -1;
}
case RX_RES_STATUS_SEC_TYPE_CCMP:
if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
RX_RES_STATUS_DECRYPT_OK) {
- IWL_DEBUG_RX("hw decrypt successfully!!!\n");
+ IWL_DEBUG_RX(priv, "hw decrypt successfully!!!\n");
stats->flag |= RX_FLAG_DECRYPTED;
}
break;
@@ -816,6 +815,7 @@ static int iwl_set_decrypted_flag(struct iwl_priv *priv,
}
return 0;
}
+EXPORT_SYMBOL(iwl_set_decrypted_flag);
static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
{
@@ -870,7 +870,7 @@ static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
break;
};
- IWL_DEBUG_RX("decrypt_in:0x%x decrypt_out = 0x%x\n",
+ IWL_DEBUG_RX(priv, "decrypt_in:0x%x decrypt_out = 0x%x\n",
decrypt_in, decrypt_out);
return decrypt_out;
@@ -895,7 +895,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
rx_start = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
if (!rx_start) {
- IWL_ERROR("MPDU frame without a PHY data\n");
+ IWL_ERR(priv, "MPDU frame without a PHY data\n");
return;
}
if (include_phy) {
@@ -934,8 +934,8 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
/* We only process data packets if the interface is open */
if (unlikely(!priv->is_open)) {
- IWL_DEBUG_DROP_LIMIT
- ("Dropping packet while interface is not open.\n");
+ IWL_DEBUG_DROP_LIMIT(priv,
+ "Dropping packet while interface is not open.\n");
return;
}
@@ -1007,7 +1007,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
/*rx_status.flag |= RX_FLAG_TSFT;*/
if ((unlikely(rx_start->cfg_phy_cnt > 20))) {
- IWL_DEBUG_DROP("dsp size out of range [0,20]: %d/n",
+ IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
rx_start->cfg_phy_cnt);
return;
}
@@ -1021,7 +1021,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
}
if (!rx_start) {
- IWL_ERROR("MPDU frame without a PHY data\n");
+ IWL_ERR(priv, "MPDU frame without a PHY data\n");
return;
}
@@ -1045,7 +1045,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
if (!(*rx_end & RX_RES_STATUS_NO_CRC32_ERROR) ||
!(*rx_end & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
- IWL_DEBUG_RX("Bad CRC or FIFO: 0x%08X.\n",
+ IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
le32_to_cpu(*rx_end));
return;
}
@@ -1078,7 +1078,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
if (unlikely(priv->debug_level & IWL_DL_RX))
iwl_dbg_report_frame(priv, rx_start, len, header, 1);
#endif
- IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
+ IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, qual %d, TSF %llu\n",
rx_status.signal, rx_status.noise, rx_status.signal,
(unsigned long long)rx_status.mactime);
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 3c803f6922ef..23644cf884f1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -2,7 +2,7 @@
*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -46,15 +46,6 @@
#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)
-/* For faster active scanning, scan will move to the next channel if fewer than
- * PLCP_QUIET_THRESH packets are heard on this channel within
- * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
- * time if it's a quiet channel (nothing responded to our probe, and there's
- * no other traffic).
- * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
-#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
-#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
-
/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
* Must be set longer than active dwell time.
* For the most reliable scan, set > AP beacon interval (typically 100msec). */
@@ -63,7 +54,6 @@
#define IWL_PASSIVE_DWELL_BASE (100)
#define IWL_CHANNEL_TUNE_TIME 5
-#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
/**
@@ -80,12 +70,12 @@ int iwl_scan_cancel(struct iwl_priv *priv)
if (test_bit(STATUS_SCANNING, &priv->status)) {
if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Queuing scan abort.\n");
+ IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n");
set_bit(STATUS_SCAN_ABORTING, &priv->status);
queue_work(priv->workqueue, &priv->abort_scan);
} else
- IWL_DEBUG_SCAN("Scan abort already in progress.\n");
+ IWL_DEBUG_SCAN(priv, "Scan abort already in progress.\n");
return test_bit(STATUS_SCANNING, &priv->status);
}
@@ -119,7 +109,7 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
}
EXPORT_SYMBOL(iwl_scan_cancel_timeout);
-static int iwl_send_scan_abort(struct iwl_priv *priv)
+int iwl_send_scan_abort(struct iwl_priv *priv)
{
int ret = 0;
struct iwl_rx_packet *res;
@@ -150,7 +140,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
* can occur if we send the scan abort before we
* the microcode has notified us that a scan is
* completed. */
- IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);
+ IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", res->u.status);
clear_bit(STATUS_SCAN_ABORTING, &priv->status);
clear_bit(STATUS_SCAN_HW, &priv->status);
}
@@ -160,7 +150,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
return ret;
}
-
+EXPORT_SYMBOL(iwl_send_scan_abort);
/* Service response to REPLY_SCAN_CMD (0x80) */
static void iwl_rx_reply_scan(struct iwl_priv *priv,
@@ -171,7 +161,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
struct iwl_scanreq_notification *notif =
(struct iwl_scanreq_notification *)pkt->u.raw;
- IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
+ IWL_DEBUG_RX(priv, "Scan request status = 0x%x\n", notif->status);
#endif
}
@@ -183,7 +173,7 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
struct iwl_scanstart_notification *notif =
(struct iwl_scanstart_notification *)pkt->u.raw;
priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
- IWL_DEBUG_SCAN("Scan start: "
+ IWL_DEBUG_SCAN(priv, "Scan start: "
"%d [802.11%s] "
"(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n",
notif->channel,
@@ -202,7 +192,7 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
struct iwl_scanresults_notification *notif =
(struct iwl_scanresults_notification *)pkt->u.raw;
- IWL_DEBUG_SCAN("Scan ch.res: "
+ IWL_DEBUG_SCAN(priv, "Scan ch.res: "
"%d [802.11%s] "
"(TSF: 0x%08X:%08X) - %d "
"elapsed=%lu usec (%dms since last)\n",
@@ -228,7 +218,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
- IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
+ IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
scan_notif->scanned_channels,
scan_notif->tsf_low,
scan_notif->tsf_high, scan_notif->status);
@@ -240,7 +230,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
/* The scan completion notification came in, so kill that timer... */
cancel_delayed_work(&priv->scan_check);
- IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
+ IWL_DEBUG_INFO(priv, "Scan pass on %sGHz took %dms\n",
(priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
"2.4" : "5.2",
jiffies_to_msecs(elapsed_jiffies
@@ -258,7 +248,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
* then we reset the scan state machine and terminate,
* re-queuing another scan if one has been requested */
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_INFO("Aborted scan completed.\n");
+ IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
clear_bit(STATUS_SCAN_ABORTING, &priv->status);
} else {
/* If there are more bands on this scan pass reschedule */
@@ -268,11 +258,11 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
priv->last_scan_jiffies = jiffies;
priv->next_scan_jiffies = 0;
- IWL_DEBUG_INFO("Setting scan to off\n");
+ IWL_DEBUG_INFO(priv, "Setting scan to off\n");
clear_bit(STATUS_SCANNING, &priv->status);
- IWL_DEBUG_INFO("Scan took %dms\n",
+ IWL_DEBUG_INFO(priv, "Scan took %dms\n",
jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
queue_work(priv->workqueue, &priv->scan_completed);
@@ -296,9 +286,9 @@ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_setup_rx_scan_handlers);
-static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band,
- u8 n_probes)
+inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 n_probes)
{
if (band == IEEE80211_BAND_5GHZ)
return IWL_ACTIVE_DWELL_TIME_52 +
@@ -307,9 +297,10 @@ static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
return IWL_ACTIVE_DWELL_TIME_24 +
IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
}
+EXPORT_SYMBOL(iwl_get_active_dwell_time);
-static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band)
+u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band)
{
u16 passive = (band == IEEE80211_BAND_2GHZ) ?
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
@@ -327,6 +318,7 @@ static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
return passive;
}
+EXPORT_SYMBOL(iwl_get_passive_dwell_time);
static int iwl_get_channels_for_scan(struct iwl_priv *priv,
enum ieee80211_band band,
@@ -363,7 +355,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
ch_info = iwl_get_channel_info(priv, band, channel);
if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
+ IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
channel);
continue;
}
@@ -392,7 +384,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
else
scan_ch->tx_gain = ((1 << 5) | (5 << 3));
- IWL_DEBUG_SCAN("Scanning ch=%d prob=0x%X [%s %d]\n",
+ IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
channel, le32_to_cpu(scan_ch->type),
(scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
"ACTIVE" : "PASSIVE",
@@ -403,7 +395,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
added++;
}
- IWL_DEBUG_SCAN("total channels to scan %d \n", added);
+ IWL_DEBUG_SCAN(priv, "total channels to scan %d \n", added);
return added;
}
@@ -419,21 +411,21 @@ void iwl_init_scan_params(struct iwl_priv *priv)
int iwl_scan_initiate(struct iwl_priv *priv)
{
if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
+ IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n");
return -EIO;
}
if (test_bit(STATUS_SCANNING, &priv->status)) {
- IWL_DEBUG_SCAN("Scan already in progress.\n");
+ IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
return -EAGAIN;
}
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Scan request while abort pending\n");
+ IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
return -EAGAIN;
}
- IWL_DEBUG_INFO("Starting scan...\n");
+ IWL_DEBUG_INFO(priv, "Starting scan...\n");
if (priv->cfg->sku & IWL_SKU_G)
priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
if (priv->cfg->sku & IWL_SKU_A)
@@ -448,9 +440,77 @@ int iwl_scan_initiate(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_scan_initiate);
+#define IWL_DELAY_NEXT_SCAN (HZ*2)
+
+int iwl_mac_hw_scan(struct ieee80211_hw *hw,
+ struct cfg80211_scan_request *req)
+{
+ unsigned long flags;
+ struct iwl_priv *priv = hw->priv;
+ int ret;
+ u8 *ssid = NULL;
+ size_t ssid_len = 0;
+
+ if (req->n_ssids) {
+ ssid = req->ssids[0].ssid;
+ ssid_len = req->ssids[0].ssid_len;
+ }
+
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ mutex_lock(&priv->mutex);
+ spin_lock_irqsave(&priv->lock, flags);
+
+ if (!iwl_is_ready_rf(priv)) {
+ ret = -EIO;
+ IWL_DEBUG_MAC80211(priv, "leave - not ready or exit pending\n");
+ goto out_unlock;
+ }
+
+ /* We don't schedule scan within next_scan_jiffies period.
+ * Avoid scanning during possible EAPOL exchange, return
+ * success immediately.
+ */
+ if (priv->next_scan_jiffies &&
+ time_after(priv->next_scan_jiffies, jiffies)) {
+ IWL_DEBUG_SCAN(priv, "scan rejected: within next scan period\n");
+ queue_work(priv->workqueue, &priv->scan_completed);
+ ret = 0;
+ goto out_unlock;
+ }
+
+ /* if we just finished scan ask for delay */
+ if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
+ time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
+ IWL_DEBUG_SCAN(priv, "scan rejected: within previous scan period\n");
+ queue_work(priv->workqueue, &priv->scan_completed);
+ ret = 0;
+ goto out_unlock;
+ }
+
+ if (ssid_len) {
+ priv->one_direct_scan = 1;
+ priv->direct_ssid_len = ssid_len;
+ memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
+ } else {
+ priv->one_direct_scan = 0;
+ }
+
+ ret = iwl_scan_initiate(priv);
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+
+out_unlock:
+ spin_unlock_irqrestore(&priv->lock, flags);
+ mutex_unlock(&priv->mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_mac_hw_scan);
+
#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
-static void iwl_bg_scan_check(struct work_struct *data)
+void iwl_bg_scan_check(struct work_struct *data)
{
struct iwl_priv *priv =
container_of(data, struct iwl_priv, scan_check.work);
@@ -461,7 +521,7 @@ static void iwl_bg_scan_check(struct work_struct *data)
mutex_lock(&priv->mutex);
if (test_bit(STATUS_SCANNING, &priv->status) ||
test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting "
+ IWL_DEBUG_SCAN(priv, "Scan completion watchdog resetting "
"adapter (%dms)\n",
jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
@@ -470,6 +530,8 @@ static void iwl_bg_scan_check(struct work_struct *data)
}
mutex_unlock(&priv->mutex);
}
+EXPORT_SYMBOL(iwl_bg_scan_check);
+
/**
* iwl_supported_rate_to_ie - fill in the supported rate in IE field
*
@@ -527,10 +589,10 @@ static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
* iwl_fill_probe_req - fill in all required fields and IE for probe request
*/
-static u16 iwl_fill_probe_req(struct iwl_priv *priv,
- enum ieee80211_band band,
- struct ieee80211_mgmt *frame,
- int left)
+u16 iwl_fill_probe_req(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ struct ieee80211_mgmt *frame,
+ int left)
{
int len = 0;
u8 *pos = NULL;
@@ -624,6 +686,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
return (u16)len;
}
+EXPORT_SYMBOL(iwl_fill_probe_req);
static void iwl_bg_request_scan(struct work_struct *data)
{
@@ -650,7 +713,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
mutex_lock(&priv->mutex);
if (!iwl_is_ready(priv)) {
- IWL_WARNING("request scan called when driver not ready.\n");
+ IWL_WARN(priv, "request scan called when driver not ready.\n");
goto done;
}
@@ -662,34 +725,34 @@ static void iwl_bg_request_scan(struct work_struct *data)
/* This should never be called or scheduled if there is currently
* a scan active in the hardware. */
if (test_bit(STATUS_SCAN_HW, &priv->status)) {
- IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. "
+ IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
"Ignoring second request.\n");
ret = -EIO;
goto done;
}
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n");
+ IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
goto done;
}
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n");
+ IWL_DEBUG_HC(priv, "Scan request while abort pending. Queuing.\n");
goto done;
}
if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
+ IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
goto done;
}
if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n");
+ IWL_DEBUG_HC(priv, "Scan request while uninitialized. Queuing.\n");
goto done;
}
if (!priv->scan_bands) {
- IWL_DEBUG_HC("Aborting scan due to no requested bands\n");
+ IWL_DEBUG_HC(priv, "Aborting scan due to no requested bands\n");
goto done;
}
@@ -714,7 +777,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
u32 scan_suspend_time = 100;
unsigned long flags;
- IWL_DEBUG_INFO("Scanning while associated...\n");
+ IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
spin_lock_irqsave(&priv->lock, flags);
interval = priv->beacon_int;
@@ -729,13 +792,13 @@ static void iwl_bg_request_scan(struct work_struct *data)
scan_suspend_time = (extra |
((suspend_time % interval) * 1024));
scan->suspend_time = cpu_to_le32(scan_suspend_time);
- IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n",
+ IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
scan_suspend_time, interval);
}
/* We should add the ability for user to lock to PASSIVE ONLY */
if (priv->one_direct_scan) {
- IWL_DEBUG_SCAN("Start direct scan for '%s'\n",
+ IWL_DEBUG_SCAN(priv, "Start direct scan for '%s'\n",
print_ssid(ssid, priv->direct_ssid,
priv->direct_ssid_len));
scan->direct_scan[0].id = WLAN_EID_SSID;
@@ -744,7 +807,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
priv->direct_ssid, priv->direct_ssid_len);
n_probes++;
} else {
- IWL_DEBUG_SCAN("Start indirect scan.\n");
+ IWL_DEBUG_SCAN(priv, "Start indirect scan.\n");
}
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
@@ -773,7 +836,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
rx_chain = 0x6;
} else {
- IWL_WARNING("Invalid scan band count\n");
+ IWL_WARN(priv, "Invalid scan band count\n");
goto done;
}
@@ -806,7 +869,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
if (scan->channel_count == 0) {
- IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count);
+ IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
goto done;
}
@@ -839,7 +902,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-static void iwl_bg_abort_scan(struct work_struct *work)
+void iwl_bg_abort_scan(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
@@ -853,18 +916,19 @@ static void iwl_bg_abort_scan(struct work_struct *work)
mutex_unlock(&priv->mutex);
}
+EXPORT_SYMBOL(iwl_bg_abort_scan);
-static void iwl_bg_scan_completed(struct work_struct *work)
+void iwl_bg_scan_completed(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, scan_completed);
- IWL_DEBUG_SCAN("SCAN complete scan\n");
+ IWL_DEBUG_SCAN(priv, "SCAN complete scan\n");
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- ieee80211_scan_completed(priv->hw);
+ ieee80211_scan_completed(priv->hw, false);
/* Since setting the TXPOWER may have been deferred while
* performing the scan, fire one off */
@@ -872,7 +936,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
mutex_unlock(&priv->mutex);
}
-
+EXPORT_SYMBOL(iwl_bg_scan_completed);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
index 836c3c80b69e..022bcf115731 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.c
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -146,7 +146,7 @@ static int iwl_get_measurement(struct iwl_priv *priv,
res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
+ IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
rc = -EIO;
}
@@ -154,9 +154,9 @@ static int iwl_get_measurement(struct iwl_priv *priv,
switch (spectrum_resp_status) {
case 0: /* Command will be handled */
if (res->u.spectrum.id != 0xff) {
- IWL_DEBUG_INFO
- ("Replaced existing measurement: %d\n",
- res->u.spectrum.id);
+ IWL_DEBUG_INFO(priv,
+ "Replaced existing measurement: %d\n",
+ res->u.spectrum.id);
priv->measurement_status &= ~MEASUREMENT_READY;
}
priv->measurement_status |= MEASUREMENT_ACTIVE;
@@ -181,7 +181,7 @@ static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
if (!report->state) {
- IWL_DEBUG(IWL_DL_11H,
+ IWL_DEBUG_11H(priv,
"Spectrum Measure Notification: Start\n");
return;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
index b7d7943e476b..a77c1e619062 100644
--- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h
+++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ieee80211 subsystem header files.
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 70a8b21ca39b..5798fe49c771 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -60,7 +60,7 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
goto out;
}
- IWL_DEBUG_ASSOC_LIMIT("can not find STA %pM total %d\n",
+ IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n",
addr, priv->num_stations);
out:
@@ -86,11 +86,13 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
spin_lock_irqsave(&priv->sta_lock, flags);
- if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
- IWL_ERROR("ACTIVATE a non DRIVER active station %d\n", sta_id);
+ if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
+ !(priv->stations_39[sta_id].used & IWL_STA_DRIVER_ACTIVE))
+ IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n",
+ sta_id);
priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE;
- IWL_DEBUG_ASSOC("Added STA to Ucode: %pM\n",
+ IWL_DEBUG_ASSOC(priv, "Added STA to Ucode: %pM\n",
priv->stations[sta_id].sta.sta.addr);
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -105,13 +107,13 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
u8 sta_id = addsta->sta.sta_id;
if (!skb) {
- IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
+ IWL_ERR(priv, "Error: Response NULL in REPLY_ADD_STA.\n");
return 1;
}
res = (struct iwl_rx_packet *)skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
res->hdr.flags);
return 1;
}
@@ -121,7 +123,7 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
iwl_sta_ucode_activate(priv, sta_id);
/* fall through */
default:
- IWL_DEBUG_HC("Received REPLY_ADD_STA:(0x%08X)\n",
+ IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
res->u.add_sta.status);
break;
}
@@ -130,7 +132,7 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
return 1;
}
-static int iwl_send_add_sta(struct iwl_priv *priv,
+int iwl_send_add_sta(struct iwl_priv *priv,
struct iwl_addsta_cmd *sta, u8 flags)
{
struct iwl_rx_packet *res = NULL;
@@ -155,7 +157,7 @@ static int iwl_send_add_sta(struct iwl_priv *priv,
res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
res->hdr.flags);
ret = -EIO;
}
@@ -164,11 +166,11 @@ static int iwl_send_add_sta(struct iwl_priv *priv,
switch (res->u.add_sta.status) {
case ADD_STA_SUCCESS_MSK:
iwl_sta_ucode_activate(priv, sta->sta.sta_id);
- IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n");
+ IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
break;
default:
ret = -EIO;
- IWL_WARNING("REPLY_ADD_STA failed\n");
+ IWL_WARN(priv, "REPLY_ADD_STA failed\n");
break;
}
}
@@ -178,6 +180,7 @@ static int iwl_send_add_sta(struct iwl_priv *priv,
return ret;
}
+EXPORT_SYMBOL(iwl_send_add_sta);
static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
struct ieee80211_sta_ht_cap *sta_ht_inf)
@@ -204,7 +207,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
case WLAN_HT_CAP_SM_PS_DISABLED:
break;
default:
- IWL_WARNING("Invalid MIMO PS mode %d\n", mimo_ps_mode);
+ IWL_WARN(priv, "Invalid MIMO PS mode %d\n", mimo_ps_mode);
break;
}
@@ -269,7 +272,7 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
station = &priv->stations[sta_id];
station->used = IWL_STA_DRIVER_ACTIVE;
- IWL_DEBUG_ASSOC("Add STA to driver ID %d: %pM\n",
+ IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n",
sta_id, addr);
priv->num_stations++;
@@ -301,13 +304,13 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
BUG_ON(sta_id == IWL_INVALID_STATION);
- IWL_DEBUG_ASSOC("Removed STA from Ucode: %pM\n", addr);
+ IWL_DEBUG_ASSOC(priv, "Removed STA from Ucode: %pM\n", addr);
spin_lock_irqsave(&priv->sta_lock, flags);
/* Ucode must be active and driver must be non active */
if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE)
- IWL_ERROR("removed non active STA %d\n", sta_id);
+ IWL_ERR(priv, "removed non active STA %d\n", sta_id);
priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
@@ -324,13 +327,13 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv,
const char *addr = rm_sta->addr;
if (!skb) {
- IWL_ERROR("Error: Response NULL in REPLY_REMOVE_STA.\n");
+ IWL_ERR(priv, "Error: Response NULL in REPLY_REMOVE_STA.\n");
return 1;
}
res = (struct iwl_rx_packet *)skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_REMOVE_STA (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
res->hdr.flags);
return 1;
}
@@ -340,7 +343,7 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv,
iwl_sta_ucode_deactivate(priv, addr);
break;
default:
- IWL_ERROR("REPLY_REMOVE_STA failed\n");
+ IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
break;
}
@@ -378,7 +381,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_REMOVE_STA (0x%08X)\n",
+ IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
res->hdr.flags);
ret = -EIO;
}
@@ -387,11 +390,11 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
switch (res->u.rem_sta.status) {
case REM_STA_SUCCESS_MSK:
iwl_sta_ucode_deactivate(priv, addr);
- IWL_DEBUG_ASSOC("REPLY_REMOVE_STA PASSED\n");
+ IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
break;
default:
ret = -EIO;
- IWL_ERROR("REPLY_REMOVE_STA failed\n");
+ IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
break;
}
}
@@ -429,17 +432,17 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
if (unlikely(sta_id == IWL_INVALID_STATION))
goto out;
- IWL_DEBUG_ASSOC("Removing STA from driver:%d %pM\n",
+ IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
sta_id, addr);
if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
- IWL_ERROR("Removing %pM but non DRIVER active\n",
+ IWL_ERR(priv, "Removing %pM but non DRIVER active\n",
addr);
goto out;
}
if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
- IWL_ERROR("Removing %pM but non UCODE active\n",
+ IWL_ERR(priv, "Removing %pM but non UCODE active\n",
addr);
goto out;
}
@@ -469,13 +472,14 @@ EXPORT_SYMBOL(iwl_remove_station);
void iwl_clear_stations_table(struct iwl_priv *priv)
{
unsigned long flags;
+ int i;
spin_lock_irqsave(&priv->sta_lock, flags);
if (iwl_is_alive(priv) &&
!test_bit(STATUS_EXIT_PENDING, &priv->status) &&
iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL))
- IWL_ERROR("Couldn't clear the station table\n");
+ IWL_ERR(priv, "Couldn't clear the station table\n");
priv->num_stations = 0;
memset(priv->stations, 0, sizeof(priv->stations));
@@ -483,11 +487,17 @@ void iwl_clear_stations_table(struct iwl_priv *priv)
/* clean ucode key table bit map */
priv->ucode_key_table = 0;
+ /* keep track of static keys */
+ for (i = 0; i < WEP_KEYS_MAX ; i++) {
+ if (priv->wep_keys[i].key_size)
+ test_and_set_bit(i, &priv->ucode_key_table);
+ }
+
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
EXPORT_SYMBOL(iwl_clear_stations_table);
-static int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
+int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{
int i;
@@ -497,6 +507,7 @@ static int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
return WEP_INVALID_OFFSET;
}
+EXPORT_SYMBOL(iwl_get_free_ucode_key_index);
int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
{
@@ -551,13 +562,13 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
spin_lock_irqsave(&priv->sta_lock, flags);
if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table))
- IWL_ERROR("index %d not used in uCode key table.\n",
+ IWL_ERR(priv, "index %d not used in uCode key table.\n",
keyconf->keyidx);
priv->default_wep_key--;
memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
ret = iwl_send_static_wepkey_cmd(priv, 1);
- IWL_DEBUG_WEP("Remove default WEP key: idx=%d ret=%d\n",
+ IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
keyconf->keyidx, ret);
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -573,7 +584,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
if (keyconf->keylen != WEP_KEY_LEN_128 &&
keyconf->keylen != WEP_KEY_LEN_64) {
- IWL_DEBUG_WEP("Bad WEP key length %d\n", keyconf->keylen);
+ IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen);
return -EINVAL;
}
@@ -585,7 +596,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
priv->default_wep_key++;
if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table))
- IWL_ERROR("index %d already used in uCode key table.\n",
+ IWL_ERR(priv, "index %d already used in uCode key table.\n",
keyconf->keyidx);
priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
@@ -593,7 +604,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
keyconf->keylen);
ret = iwl_send_static_wepkey_cmd(priv, 0);
- IWL_DEBUG_WEP("Set default WEP key: len=%d idx=%d ret=%d\n",
+ IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
keyconf->keylen, keyconf->keyidx, ret);
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -641,7 +652,7 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
* in uCode. */
WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
- "no space for new kew");
+ "no space for a new key");
priv->stations[sta_id].sta.key.key_flags = key_flags;
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
@@ -689,7 +700,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
* in uCode. */
WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
- "no space for new kew");
+ "no space for a new key");
priv->stations[sta_id].sta.key.key_flags = key_flags;
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
@@ -725,7 +736,7 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
* in uCode. */
WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
- "no space for new kew");
+ "no space for a new key");
/* This copy is acutally not needed: we get the key with each TX */
memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
@@ -749,7 +760,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
sta_id = iwl_find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
+ IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
addr);
return;
}
@@ -801,7 +812,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
- IWL_DEBUG_WEP("Remove dynamic key: idx=%d sta=%d\n",
+ IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n",
keyconf->keyidx, sta_id);
if (keyconf->keyidx != keyidx) {
@@ -815,7 +826,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
}
if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
- IWL_WARNING("Removing wrong key %d 0x%x\n",
+ IWL_WARN(priv, "Removing wrong key %d 0x%x\n",
keyconf->keyidx, key_flags);
spin_unlock_irqrestore(&priv->sta_lock, flags);
return 0;
@@ -823,7 +834,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
&priv->ucode_key_table))
- IWL_ERROR("index %d not used in uCode key table.\n",
+ IWL_ERR(priv, "index %d not used in uCode key table.\n",
priv->stations[sta_id].sta.key.key_offset);
memset(&priv->stations[sta_id].keyinfo, 0,
sizeof(struct iwl_hw_key));
@@ -860,11 +871,12 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id);
break;
default:
- IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
+ IWL_ERR(priv,
+ "Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
ret = -EINVAL;
}
- IWL_DEBUG_WEP("Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
+ IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
keyconf->alg, keyconf->keylen, keyconf->keyidx,
sta_id, ret);
@@ -877,13 +889,13 @@ static void iwl_dump_lq_cmd(struct iwl_priv *priv,
struct iwl_link_quality_cmd *lq)
{
int i;
- IWL_DEBUG_RATE("lq station id 0x%x\n", lq->sta_id);
- IWL_DEBUG_RATE("lq ant 0x%X 0x%X\n",
+ IWL_DEBUG_RATE(priv, "lq station id 0x%x\n", lq->sta_id);
+ IWL_DEBUG_RATE(priv, "lq ant 0x%X 0x%X\n",
lq->general_params.single_stream_ant_msk,
lq->general_params.dual_stream_ant_msk);
for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
- IWL_DEBUG_RATE("lq index %d 0x%X\n",
+ IWL_DEBUG_RATE(priv, "lq index %d 0x%X\n",
i, lq->rs_table[i].rate_n_flags);
}
#else
@@ -1060,7 +1072,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
if (sta_id != IWL_INVALID_STATION)
return sta_id;
- IWL_DEBUG_DROP("Station %pM not in station map. "
+ IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
"Defaulting to broadcast...\n",
hdr->addr1);
iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
@@ -1072,7 +1084,8 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
return priv->hw_params.bcast_sta_id;
default:
- IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
+ IWL_WARN(priv, "Unknown mode of operation: %d\n",
+ priv->iw_mode);
return priv->hw_params.bcast_sta_id;
}
}
@@ -1125,8 +1138,10 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid)
int sta_id;
sta_id = iwl_find_station(priv, addr);
- if (sta_id == IWL_INVALID_STATION)
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
return -ENXIO;
+ }
spin_lock_irqsave(&priv->sta_lock, flags);
priv->stations[sta_id].sta.station_flags_msk = 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 9bb7cefc1f3c..59a586b6b56c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -54,8 +54,11 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
void iwl_clear_stations_table(struct iwl_priv *priv);
+int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
+int iwl_send_add_sta(struct iwl_priv *priv,
+ struct iwl_addsta_cmd *sta, u8 flags);
u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr,
int is_ap, u8 flags,
struct ieee80211_sta_ht_cap *ht_info);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index ab13ff22a8c0..1f117a49c569 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -76,116 +76,6 @@ static inline void iwl_free_dma_ptr(struct iwl_priv *priv,
memset(ptr, 0, sizeof(*ptr));
}
-static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
-{
- struct iwl_tfd_tb *tb = &tfd->tbs[idx];
-
- dma_addr_t addr = get_unaligned_le32(&tb->lo);
- if (sizeof(dma_addr_t) > sizeof(u32))
- addr |=
- ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
-
- return addr;
-}
-
-static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
-{
- struct iwl_tfd_tb *tb = &tfd->tbs[idx];
-
- return le16_to_cpu(tb->hi_n_len) >> 4;
-}
-
-static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
- dma_addr_t addr, u16 len)
-{
- struct iwl_tfd_tb *tb = &tfd->tbs[idx];
- u16 hi_n_len = len << 4;
-
- put_unaligned_le32(addr, &tb->lo);
- if (sizeof(dma_addr_t) > sizeof(u32))
- hi_n_len |= ((addr >> 16) >> 16) & 0xF;
-
- tb->hi_n_len = cpu_to_le16(hi_n_len);
-
- tfd->num_tbs = idx + 1;
-}
-
-static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
-{
- return tfd->num_tbs & 0x1f;
-}
-
-/**
- * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
- * @priv - driver private data
- * @txq - tx queue
- *
- * Does NOT advance any TFD circular buffer read/write indexes
- * Does NOT free the TFD itself (which is within circular buffer)
- */
-static void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
-{
- struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)&txq->tfds[0];
- struct iwl_tfd *tfd;
- struct pci_dev *dev = priv->pci_dev;
- int index = txq->q.read_ptr;
- int i;
- int num_tbs;
-
- tfd = &tfd_tmp[index];
-
- /* Sanity check on number of chunks */
- num_tbs = iwl_tfd_get_num_tbs(tfd);
-
- if (num_tbs >= IWL_NUM_OF_TBS) {
- IWL_ERROR("Too many chunks: %i\n", num_tbs);
- /* @todo issue fatal error, it is quite serious situation */
- return;
- }
-
- /* Unmap tx_cmd */
- if (num_tbs)
- pci_unmap_single(dev,
- pci_unmap_addr(&txq->cmd[index]->meta, mapping),
- pci_unmap_len(&txq->cmd[index]->meta, len),
- PCI_DMA_BIDIRECTIONAL);
-
- /* Unmap chunks, if any. */
- for (i = 1; i < num_tbs; i++) {
- pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
- iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
-
- if (txq->txb) {
- dev_kfree_skb(txq->txb[txq->q.read_ptr].skb[i - 1]);
- txq->txb[txq->q.read_ptr].skb[i - 1] = NULL;
- }
- }
-}
-
-static int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
- struct iwl_tfd *tfd,
- dma_addr_t addr, u16 len)
-{
-
- u32 num_tbs = iwl_tfd_get_num_tbs(tfd);
-
- /* Each TFD can point to a maximum 20 Tx buffers */
- if (num_tbs >= IWL_NUM_OF_TBS) {
- IWL_ERROR("Error can not send more than %d chunks\n",
- IWL_NUM_OF_TBS);
- return -EINVAL;
- }
-
- BUG_ON(addr & ~DMA_BIT_MASK(36));
- if (unlikely(addr & ~IWL_TX_DMA_MASK))
- IWL_ERROR("Unaligned address = %llx\n",
- (unsigned long long)addr);
-
- iwl_tfd_set_tb(tfd, num_tbs, addr, len);
-
- return 0;
-}
-
/**
* iwl_txq_update_write_ptr - Send new write index to hardware
*/
@@ -206,7 +96,7 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg);
+ IWL_DEBUG_INFO(priv, "Requesting wakeup, GP1 = 0x%x\n", reg);
iwl_set_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
return ret;
@@ -241,7 +131,7 @@ EXPORT_SYMBOL(iwl_txq_update_write_ptr);
* Free all buffers.
* 0-fill, but do not free "txq" descriptor structure.
*/
-static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
+void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
{
struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct iwl_queue *q = &txq->q;
@@ -254,7 +144,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
/* first, empty all BD's */
for (; q->write_ptr != q->read_ptr;
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
- iwl_hw_txq_free_tfd(priv, txq);
+ priv->cfg->ops->lib->txq_free_tfd(priv, txq);
len = sizeof(struct iwl_cmd) * q->n_window;
@@ -264,7 +154,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
/* De-alloc circular buffer of TFDs */
if (txq->q.n_bd)
- pci_free_consistent(dev, sizeof(struct iwl_tfd) *
+ pci_free_consistent(dev, priv->hw_params.tfd_size *
txq->q.n_bd, txq->tfds, txq->q.dma_addr);
/* De-alloc array of per-TFD driver data */
@@ -274,7 +164,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
/* 0-fill queue descriptor structure */
memset(txq, 0, sizeof(*txq));
}
-
+EXPORT_SYMBOL(iwl_tx_queue_free);
/**
* iwl_cmd_queue_free - Deallocate DMA queue.
@@ -284,7 +174,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
* Free all buffers.
* 0-fill, but do not free "txq" descriptor structure.
*/
-static void iwl_cmd_queue_free(struct iwl_priv *priv)
+void iwl_cmd_queue_free(struct iwl_priv *priv)
{
struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
struct iwl_queue *q = &txq->q;
@@ -303,12 +193,14 @@ static void iwl_cmd_queue_free(struct iwl_priv *priv)
/* De-alloc circular buffer of TFDs */
if (txq->q.n_bd)
- pci_free_consistent(dev, sizeof(struct iwl_tfd) *
+ pci_free_consistent(dev, priv->hw_params.tfd_size *
txq->q.n_bd, txq->tfds, txq->q.dma_addr);
/* 0-fill queue descriptor structure */
memset(txq, 0, sizeof(*txq));
}
+EXPORT_SYMBOL(iwl_cmd_queue_free);
+
/*************** DMA-QUEUE-GENERAL-FUNCTIONS *****
* DMA services
*
@@ -388,6 +280,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
struct iwl_tx_queue *txq, u32 id)
{
struct pci_dev *dev = priv->pci_dev;
+ size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX;
/* Driver private data, only for Tx (not command) queues,
* not shared with device. */
@@ -395,22 +288,20 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
txq->txb = kmalloc(sizeof(txq->txb[0]) *
TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
if (!txq->txb) {
- IWL_ERROR("kmalloc for auxiliary BD "
+ IWL_ERR(priv, "kmalloc for auxiliary BD "
"structures failed\n");
goto error;
}
- } else
+ } else {
txq->txb = NULL;
+ }
/* Circular buffer of transmit frame descriptors (TFDs),
* shared with device */
- txq->tfds = pci_alloc_consistent(dev,
- sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX,
- &txq->q.dma_addr);
+ txq->tfds = pci_alloc_consistent(dev, tfd_sz, &txq->q.dma_addr);
if (!txq->tfds) {
- IWL_ERROR("pci_alloc_consistent(%zd) failed\n",
- sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX);
+ IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz);
goto error;
}
txq->q.id = id;
@@ -424,42 +315,11 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
return -ENOMEM;
}
-/*
- * Tell nic where to find circular buffer of Tx Frame Descriptors for
- * given Tx queue, and enable the DMA channel used for that queue.
- *
- * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
- * channels supported in hardware.
- */
-static int iwl_hw_tx_queue_init(struct iwl_priv *priv,
- struct iwl_tx_queue *txq)
-{
- int ret;
- unsigned long flags;
- int txq_id = txq->q.id;
-
- spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
- }
-
- /* Circular buffer (TFD queue in DRAM) physical base address */
- iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
- txq->q.dma_addr >> 8);
-
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-}
-
/**
* iwl_tx_queue_init - Allocate and initialize one tx/cmd queue
*/
-static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
- int slots_num, u32 txq_id)
+int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+ int slots_num, u32 txq_id)
{
int i, len;
int ret;
@@ -501,7 +361,7 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
/* Tell device where to find queue */
- iwl_hw_tx_queue_init(priv, txq);
+ priv->cfg->ops->lib->txq_init(priv, txq);
return 0;
err:
@@ -516,6 +376,8 @@ err:
}
return -ENOMEM;
}
+EXPORT_SYMBOL(iwl_tx_queue_init);
+
/**
* iwl_hw_txq_ctx_free - Free TXQ Context
*
@@ -557,13 +419,13 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
ret = iwl_alloc_dma_ptr(priv, &priv->scd_bc_tbls,
priv->hw_params.scd_bc_tbls_size);
if (ret) {
- IWL_ERROR("Scheduler BC Table allocation failed\n");
+ IWL_ERR(priv, "Scheduler BC Table allocation failed\n");
goto error_bc_tbls;
}
/* Alloc keep-warm buffer */
ret = iwl_alloc_dma_ptr(priv, &priv->kw, IWL_KW_SIZE);
if (ret) {
- IWL_ERROR("Keep Warm allocation failed\n");
+ IWL_ERR(priv, "Keep Warm allocation failed\n");
goto error_kw;
}
spin_lock_irqsave(&priv->lock, flags);
@@ -589,7 +451,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
txq_id);
if (ret) {
- IWL_ERROR("Tx %d queue init failed\n", txq_id);
+ IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
goto error;
}
}
@@ -778,14 +640,14 @@ static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
if (info->flags & IEEE80211_TX_CTL_AMPDU)
tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
- IWL_DEBUG_TX("tx_cmd with AES hwcrypto\n");
+ IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
break;
case ALG_TKIP:
tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
ieee80211_get_tkip_key(keyconf, skb_frag,
IEEE80211_TKIP_P2_KEY, tx_cmd->key);
- IWL_DEBUG_TX("tx_cmd with tkip hwcrypto\n");
+ IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
break;
case ALG_WEP:
@@ -797,12 +659,12 @@ static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
- IWL_DEBUG_TX("Configuring packet for WEP encryption "
+ IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
"with key %d\n", keyconf->keyidx);
break;
default:
- printk(KERN_ERR "Unknown encode alg %d\n", keyconf->alg);
+ IWL_ERR(priv, "Unknown encode alg %d\n", keyconf->alg);
break;
}
}
@@ -822,7 +684,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct iwl_tfd *tfd;
struct iwl_tx_queue *txq;
struct iwl_queue *q;
struct iwl_cmd *out_cmd;
@@ -844,13 +705,13 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
spin_lock_irqsave(&priv->lock, flags);
if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_DROP("Dropping - RF KILL\n");
+ IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
goto drop_unlock;
}
if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) ==
IWL_INVALID_RATE) {
- IWL_ERROR("ERROR: No TX rate available.\n");
+ IWL_ERR(priv, "ERROR: No TX rate available.\n");
goto drop_unlock;
}
@@ -858,11 +719,11 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
#ifdef CONFIG_IWLWIFI_DEBUG
if (ieee80211_is_auth(fc))
- IWL_DEBUG_TX("Sending AUTH frame\n");
+ IWL_DEBUG_TX(priv, "Sending AUTH frame\n");
else if (ieee80211_is_assoc_req(fc))
- IWL_DEBUG_TX("Sending ASSOC frame\n");
+ IWL_DEBUG_TX(priv, "Sending ASSOC frame\n");
else if (ieee80211_is_reassoc_req(fc))
- IWL_DEBUG_TX("Sending REASSOC frame\n");
+ IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
#endif
/* drop all data frame if we are not associated */
@@ -872,7 +733,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
(!iwl_is_associated(priv) ||
((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id) ||
!priv->assoc_station_added)) {
- IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n");
+ IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
goto drop_unlock;
}
@@ -883,12 +744,12 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Find (or create) index into station table for destination station */
sta_id = iwl_get_sta_id(priv, hdr);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_DROP("Dropping - INVALID STATION: %pM\n",
+ IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
goto drop;
}
- IWL_DEBUG_TX("station Id %d\n", sta_id);
+ IWL_DEBUG_TX(priv, "station Id %d\n", sta_id);
swq_id = skb_get_queue_mapping(skb);
txq_id = swq_id;
@@ -898,12 +759,14 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
seq_number = priv->stations[sta_id].tid[tid].seq_number;
seq_number &= IEEE80211_SCTL_SEQ;
hdr->seq_ctrl = hdr->seq_ctrl &
- __constant_cpu_to_le16(IEEE80211_SCTL_FRAG);
+ cpu_to_le16(IEEE80211_SCTL_FRAG);
hdr->seq_ctrl |= cpu_to_le16(seq_number);
seq_number += 0x10;
/* aggregation is on for this <sta,tid> */
- if (info->flags & IEEE80211_TX_CTL_AMPDU)
+ if (info->flags & IEEE80211_TX_CTL_AMPDU) {
txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
+ swq_id = iwl_virtual_agg_queue_num(swq_id, txq_id);
+ }
priv->stations[sta_id].tid[tid].tfds_in_queue++;
}
@@ -913,10 +776,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
spin_lock_irqsave(&priv->lock, flags);
- /* Set up first empty TFD within this queue's circular TFD buffer */
- tfd = &txq->tfds[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
-
/* Set up driver data for this TFD */
memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
txq->txb[q->write_ptr].skb[0] = skb;
@@ -970,7 +829,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */
txcmd_phys += offsetof(struct iwl_cmd, hdr);
- iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ txcmd_phys, len, 1, 0);
if (info->control.hw_key)
iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
@@ -981,7 +841,9 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (len) {
phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
len, PCI_DMA_TODEVICE);
- iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ phys_addr, len,
+ 0, 0);
}
/* Tell NIC about any 2-byte padding after MAC header */
@@ -1035,7 +897,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
iwl_txq_update_write_ptr(priv, txq);
spin_unlock_irqrestore(&priv->lock, flags);
} else {
- ieee80211_stop_queue(priv->hw, txq->swq_id);
+ iwl_stop_queue(priv, txq->swq_id);
}
}
@@ -1063,7 +925,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
{
struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
struct iwl_queue *q = &txq->q;
- struct iwl_tfd *tfd;
struct iwl_cmd *out_cmd;
dma_addr_t phys_addr;
unsigned long flags;
@@ -1081,21 +942,17 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
!(cmd->meta.flags & CMD_SIZE_HUGE));
if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_INFO("Not sending command - RF KILL");
+ IWL_DEBUG_INFO(priv, "Not sending command - RF KILL");
return -EIO;
}
if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
- IWL_ERROR("No space for Tx\n");
+ IWL_ERR(priv, "No space for Tx\n");
return -ENOSPC;
}
spin_lock_irqsave(&priv->hcmd_lock, flags);
- tfd = &txq->tfds[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
-
-
idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
out_cmd = txq->cmd[idx];
@@ -1120,13 +977,15 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
pci_unmap_len_set(&out_cmd->meta, len, len);
phys_addr += offsetof(struct iwl_cmd, hdr);
- iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ phys_addr, fix_size, 1,
+ U32_PAD(cmd->len));
#ifdef CONFIG_IWLWIFI_DEBUG
switch (out_cmd->hdr.cmd) {
case REPLY_TX_LINK_QUALITY_CMD:
case SENSITIVITY_CMD:
- IWL_DEBUG_HC_DUMP("Sending command %s (#%x), seq: 0x%04X, "
+ IWL_DEBUG_HC_DUMP(priv, "Sending command %s (#%x), seq: 0x%04X, "
"%d bytes at %d[%d]:%d\n",
get_cmd_string(out_cmd->hdr.cmd),
out_cmd->hdr.cmd,
@@ -1134,7 +993,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
break;
default:
- IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
+ IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, "
"%d bytes at %d[%d]:%d\n",
get_cmd_string(out_cmd->hdr.cmd),
out_cmd->hdr.cmd,
@@ -1144,8 +1003,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
#endif
txq->need_update = 1;
- /* Set up entry in queue's byte count circular buffer */
- priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
+ if (priv->cfg->ops->lib->txq_update_byte_cnt_tbl)
+ /* Set up entry in queue's byte count circular buffer */
+ priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
/* Increment and update queue's write index */
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -1163,7 +1023,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
int nfreed = 0;
if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
+ IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
"is out of range [0-%d] %d %d.\n", txq_id,
index, q->n_bd, q->write_ptr, q->read_ptr);
return 0;
@@ -1180,7 +1040,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
- iwl_hw_txq_free_tfd(priv, txq);
+ priv->cfg->ops->lib->txq_free_tfd(priv, txq);
nfreed++;
}
return nfreed;
@@ -1203,7 +1063,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
int nfreed = 0;
if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) {
- IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
+ IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
"is out of range [0-%d] %d %d.\n", txq_id,
idx, q->n_bd, q->write_ptr, q->read_ptr);
return;
@@ -1218,7 +1078,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
if (nfreed++ > 0) {
- IWL_ERROR("HCMD skipped: index (%d) %d %d\n", idx,
+ IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx,
q->write_ptr, q->read_ptr);
queue_work(priv->workqueue, &priv->restart);
}
@@ -1306,7 +1166,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
else
return -EINVAL;
- IWL_WARNING("%s on ra = %pM tid = %d\n",
+ IWL_WARN(priv, "%s on ra = %pM tid = %d\n",
__func__, ra, tid);
sta_id = iwl_find_station(priv, ra);
@@ -1314,7 +1174,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
return -ENXIO;
if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {
- IWL_ERROR("Start AGG when state is not IWL_AGG_OFF !\n");
+ IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n");
return -ENXIO;
}
@@ -1334,11 +1194,11 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
return ret;
if (tid_data->tfds_in_queue == 0) {
- printk(KERN_ERR "HW queue is empty\n");
+ IWL_ERR(priv, "HW queue is empty\n");
tid_data->agg.state = IWL_AGG_ON;
ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid);
} else {
- IWL_DEBUG_HT("HW queue is NOT empty: %d packets in HW queue\n",
+ IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n",
tid_data->tfds_in_queue);
tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
}
@@ -1354,7 +1214,7 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
unsigned long flags;
if (!ra) {
- IWL_ERROR("ra = NULL\n");
+ IWL_ERR(priv, "ra = NULL\n");
return -EINVAL;
}
@@ -1365,11 +1225,13 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
sta_id = iwl_find_station(priv, ra);
- if (sta_id == IWL_INVALID_STATION)
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
return -ENXIO;
+ }
if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
- IWL_WARNING("Stopping AGG while state not IWL_AGG_ON\n");
+ IWL_WARN(priv, "Stopping AGG while state not IWL_AGG_ON\n");
tid_data = &priv->stations[sta_id].tid[tid];
ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
@@ -1379,13 +1241,13 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
/* The queue is not empty */
if (write_ptr != read_ptr) {
- IWL_DEBUG_HT("Stopping a non empty AGG HW QUEUE\n");
+ IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n");
priv->stations[sta_id].tid[tid].agg.state =
IWL_EMPTYING_HW_QUEUE_DELBA;
return 0;
}
- IWL_DEBUG_HT("HW queue is empty\n");
+ IWL_DEBUG_HT(priv, "HW queue is empty\n");
priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
spin_lock_irqsave(&priv->lock, flags);
@@ -1416,7 +1278,7 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
(q->read_ptr == q->write_ptr)) {
u16 ssn = SEQ_TO_SN(tid_data->seq_number);
int tx_fifo = default_tid_to_tx_fifo[tid];
- IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n");
+ IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
ssn, tx_fifo);
tid_data->agg.state = IWL_AGG_OFF;
@@ -1426,7 +1288,7 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
case IWL_EMPTYING_HW_QUEUE_ADDBA:
/* We are reclaiming the last packet of the queue */
if (tid_data->tfds_in_queue == 0) {
- IWL_DEBUG_HT("HW queue empty: continue ADDBA flow\n");
+ IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n");
tid_data->agg.state = IWL_AGG_ON;
ieee80211_start_tx_ba_cb_irqsafe(priv->hw, addr, tid);
}
@@ -1455,13 +1317,13 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
struct ieee80211_tx_info *info;
if (unlikely(!agg->wait_for_ba)) {
- IWL_ERROR("Received BA when not expected\n");
+ IWL_ERR(priv, "Received BA when not expected\n");
return -EINVAL;
}
/* Mark that the expected block-ack response arrived */
agg->wait_for_ba = 0;
- IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
+ IWL_DEBUG_TX_REPLY(priv, "BA %d %d\n", agg->start_idx, ba_resp->seq_ctl);
/* Calculate shift to align block-ack bits with our Tx window bits */
sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
@@ -1472,7 +1334,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
if (agg->frame_count > (64 - sh)) {
- IWL_DEBUG_TX_REPLY("more frames than bitmap size");
+ IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
return -1;
}
@@ -1485,7 +1347,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
for (i = 0; i < agg->frame_count ; i++) {
ack = bitmap & (1ULL << i);
successes += !!ack;
- IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n",
+ IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
ack ? "ACK" : "NACK", i, (agg->start_idx + i) & 0xff,
agg->start_idx + i);
}
@@ -1498,7 +1360,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
info->status.ampdu_ack_len = agg->frame_count;
iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
- IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);
+ IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap);
return 0;
}
@@ -1528,7 +1390,8 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
if (scd_flow >= priv->hw_params.max_txq_num) {
- IWL_ERROR("BUG_ON scd_flow is bigger than number of queues\n");
+ IWL_ERR(priv,
+ "BUG_ON scd_flow is bigger than number of queues\n");
return;
}
@@ -1542,19 +1405,19 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
/* TODO: Need to get this copy more safely - now good for debug */
- IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d] Received from %pM, "
+ IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
"sta_id = %d\n",
agg->wait_for_ba,
(u8 *) &ba_resp->sta_addr_lo32,
ba_resp->sta_id);
- IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
+ IWL_DEBUG_TX_REPLY(priv, "TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = "
"%d, scd_ssn = %d\n",
ba_resp->tid,
ba_resp->seq_ctl,
(unsigned long long)le64_to_cpu(ba_resp->bitmap),
ba_resp->scd_flow,
ba_resp->scd_ssn);
- IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n",
+ IWL_DEBUG_TX_REPLY(priv, "DAT start_idx = %d, bitmap = 0x%llx \n",
agg->start_idx,
(unsigned long long)agg->bitmap);
@@ -1572,7 +1435,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
priv->mac80211_registered &&
(agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
- ieee80211_wake_queue(priv->hw, txq->swq_id);
+ iwl_wake_queue(priv, txq->swq_id);
iwl_txq_check_empty(priv, sta_id, tid, scd_flow);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 57dd34e256d8..9d5f97dd7c73 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -46,40 +46,25 @@
#include <asm/div64.h>
-#include "iwl-3945-core.h"
+#define DRV_NAME "iwl3945"
+
+#include "iwl-fh.h"
+#include "iwl-3945-fh.h"
+#include "iwl-commands.h"
+#include "iwl-sta.h"
#include "iwl-3945.h"
#include "iwl-helpers.h"
-
-#ifdef CONFIG_IWL3945_DEBUG
-u32 iwl3945_debug_level;
-#endif
-
-static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq);
-
-/******************************************************************************
- *
- * module boiler plate
- *
- ******************************************************************************/
-
-/* module parameters */
-static int iwl3945_param_disable_hw_scan; /* def: 0 = use 3945's h/w scan */
-static u32 iwl3945_param_debug; /* def: 0 = minimal debug log messages */
-static int iwl3945_param_disable; /* def: 0 = enable radio */
-static int iwl3945_param_antenna; /* def: 0 = both antennas (use diversity) */
-int iwl3945_param_hwcrypto; /* def: 0 = use software encryption */
-int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */
+#include "iwl-core.h"
+#include "iwl-dev.h"
/*
* module name, copyright, version, etc.
- * NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk
*/
#define DRV_DESCRIPTION \
"Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux"
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
#define VD "d"
#else
#define VD
@@ -91,10 +76,10 @@ int iwl3945_param_queues_num = IWL39_MAX_NUM_QUEUES; /* def: 8 Tx queues */
#define VS
#endif
-#define IWLWIFI_VERSION "1.2.26k" VD VS
-#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
+#define IWL39_VERSION "1.2.26k" VD VS
+#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
#define DRV_AUTHOR "<ilw@linux.intel.com>"
-#define DRV_VERSION IWLWIFI_VERSION
+#define DRV_VERSION IWL39_VERSION
MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -102,235 +87,13 @@ MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
MODULE_LICENSE("GPL");
-static const struct ieee80211_supported_band *iwl3945_get_band(
- struct iwl3945_priv *priv, enum ieee80211_band band)
-{
- return priv->hw->wiphy->bands[band];
-}
-
-/*************** DMA-QUEUE-GENERAL-FUNCTIONS *****
- * DMA services
- *
- * Theory of operation
- *
- * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer
- * of buffer descriptors, each of which points to one or more data buffers for
- * the device to read from or fill. Driver and device exchange status of each
- * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty
- * entries in each circular buffer, to protect against confusing empty and full
- * queue states.
- *
- * The device reads or writes the data in the queues via the device's several
- * DMA/FIFO channels. Each queue is mapped to a single DMA channel.
- *
- * For Tx queue, there are low mark and high mark limits. If, after queuing
- * the packet for Tx, free space become < low mark, Tx queue stopped. When
- * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
- * Tx queue resumed.
- *
- * The 3945 operates with six queues: One receive queue, one transmit queue
- * (#4) for sending commands to the device firmware, and four transmit queues
- * (#0-3) for data tx via EDCA. An additional 2 HCCA queues are unused.
- ***************************************************/
-
-int iwl3945_queue_space(const struct iwl3945_queue *q)
-{
- int s = q->read_ptr - q->write_ptr;
-
- if (q->read_ptr > q->write_ptr)
- s -= q->n_bd;
-
- if (s <= 0)
- s += q->n_window;
- /* keep some reserve to not confuse empty and full situations */
- s -= 2;
- if (s < 0)
- s = 0;
- return s;
-}
-
-int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i)
-{
- return q->write_ptr > q->read_ptr ?
- (i >= q->read_ptr && i < q->write_ptr) :
- !(i < q->read_ptr && i >= q->write_ptr);
-}
-
-
-static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge)
-{
- /* This is for scan command, the big buffer at end of command array */
- if (is_huge)
- return q->n_window; /* must be power of 2 */
-
- /* Otherwise, use normal size buffers */
- return index & (q->n_window - 1);
-}
-
-/**
- * iwl3945_queue_init - Initialize queue's high/low-water and read/write indexes
- */
-static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q,
- int count, int slots_num, u32 id)
-{
- q->n_bd = count;
- q->n_window = slots_num;
- q->id = id;
-
- /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
- * and iwl_queue_dec_wrap are broken. */
- BUG_ON(!is_power_of_2(count));
-
- /* slots_num must be power-of-two size, otherwise
- * get_cmd_index is broken. */
- BUG_ON(!is_power_of_2(slots_num));
-
- q->low_mark = q->n_window / 4;
- if (q->low_mark < 4)
- q->low_mark = 4;
-
- q->high_mark = q->n_window / 8;
- if (q->high_mark < 2)
- q->high_mark = 2;
-
- q->write_ptr = q->read_ptr = 0;
-
- return 0;
-}
-
-/**
- * iwl3945_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue
- */
-static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq, u32 id)
-{
- struct pci_dev *dev = priv->pci_dev;
-
- /* Driver private data, only for Tx (not command) queues,
- * not shared with device. */
- if (id != IWL_CMD_QUEUE_NUM) {
- txq->txb = kmalloc(sizeof(txq->txb[0]) *
- TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
- if (!txq->txb) {
- IWL_ERROR("kmalloc for auxiliary BD "
- "structures failed\n");
- goto error;
- }
- } else
- txq->txb = NULL;
-
- /* Circular buffer of transmit frame descriptors (TFDs),
- * shared with device */
- txq->bd = pci_alloc_consistent(dev,
- sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX,
- &txq->q.dma_addr);
-
- if (!txq->bd) {
- IWL_ERROR("pci_alloc_consistent(%zd) failed\n",
- sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX);
- goto error;
- }
- txq->q.id = id;
-
- return 0;
-
- error:
- kfree(txq->txb);
- txq->txb = NULL;
-
- return -ENOMEM;
-}
-
-/**
- * iwl3945_tx_queue_init - Allocate and initialize one tx/cmd queue
- */
-int iwl3945_tx_queue_init(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq, int slots_num, u32 txq_id)
-{
- struct pci_dev *dev = priv->pci_dev;
- int len;
- int rc = 0;
-
- /*
- * Alloc buffer array for commands (Tx or other types of commands).
- * For the command queue (#4), allocate command space + one big
- * command for scan, since scan command is very huge; the system will
- * not have two scans at the same time, so only one is needed.
- * For data Tx queues (all other queues), no super-size command
- * space is needed.
- */
- len = sizeof(struct iwl3945_cmd) * slots_num;
- if (txq_id == IWL_CMD_QUEUE_NUM)
- len += IWL_MAX_SCAN_SIZE;
- txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd);
- if (!txq->cmd)
- return -ENOMEM;
-
- /* Alloc driver data array and TFD circular buffer */
- rc = iwl3945_tx_queue_alloc(priv, txq, txq_id);
- if (rc) {
- pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
-
- return -ENOMEM;
- }
- txq->need_update = 0;
-
- /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
- * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
- BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
-
- /* Initialize queue high/low-water, head/tail indexes */
- iwl3945_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
-
- /* Tell device where to find queue, enable DMA channel. */
- iwl3945_hw_tx_queue_init(priv, txq);
-
- return 0;
-}
-
-/**
- * iwl3945_tx_queue_free - Deallocate DMA queue.
- * @txq: Transmit queue to deallocate.
- *
- * Empty queue by removing and destroying all BD's.
- * Free all buffers.
- * 0-fill, but do not free "txq" descriptor structure.
- */
-void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
-{
- struct iwl3945_queue *q = &txq->q;
- struct pci_dev *dev = priv->pci_dev;
- int len;
-
- if (q->n_bd == 0)
- return;
-
- /* first, empty all BD's */
- for (; q->write_ptr != q->read_ptr;
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
- iwl3945_hw_txq_free_tfd(priv, txq);
-
- len = sizeof(struct iwl3945_cmd) * q->n_window;
- if (q->id == IWL_CMD_QUEUE_NUM)
- len += IWL_MAX_SCAN_SIZE;
-
- /* De-alloc array of command/tx buffers */
- pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
-
- /* De-alloc circular buffer of TFDs */
- if (txq->q.n_bd)
- pci_free_consistent(dev, sizeof(struct iwl3945_tfd_frame) *
- txq->q.n_bd, txq->bd, txq->q.dma_addr);
-
- /* De-alloc array of per-TFD driver data */
- kfree(txq->txb);
- txq->txb = NULL;
-
- /* 0-fill queue descriptor structure */
- memset(txq, 0, sizeof(*txq));
-}
-
-const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+ /* module parameters */
+struct iwl_mod_params iwl3945_mod_params = {
+ .num_of_queues = IWL39_MAX_NUM_QUEUES,
+ .sw_crypto = 1,
+ .restart_fw = 1,
+ /* the rest are 0 by default */
+};
/*************** STATION TABLE MANAGEMENT ****
* mac80211 should be examined to determine if sta_info is duplicating
@@ -344,7 +107,7 @@ const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
*
* NOTE: This does not remove station from device's station table.
*/
-static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap)
+static u8 iwl3945_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
{
int index = IWL_INVALID_STATION;
int i;
@@ -355,11 +118,11 @@ static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int
if (is_ap)
index = IWL_AP_ID;
else if (is_broadcast_ether_addr(addr))
- index = priv->hw_setting.bcast_sta_id;
+ index = priv->hw_params.bcast_sta_id;
else
- for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++)
- if (priv->stations[i].used &&
- !compare_ether_addr(priv->stations[i].sta.sta.addr,
+ for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
+ if (priv->stations_39[i].used &&
+ !compare_ether_addr(priv->stations_39[i].sta.sta.addr,
addr)) {
index = i;
break;
@@ -368,8 +131,8 @@ static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int
if (unlikely(index == IWL_INVALID_STATION))
goto out;
- if (priv->stations[index].used) {
- priv->stations[index].used = 0;
+ if (priv->stations_39[index].used) {
+ priv->stations_39[index].used = 0;
priv->num_stations--;
}
@@ -386,14 +149,14 @@ out:
*
* NOTE: This does not clear or otherwise alter the device's station table.
*/
-static void iwl3945_clear_stations_table(struct iwl3945_priv *priv)
+static void iwl3945_clear_stations_table(struct iwl_priv *priv)
{
unsigned long flags;
spin_lock_irqsave(&priv->sta_lock, flags);
priv->num_stations = 0;
- memset(priv->stations, 0, sizeof(priv->stations));
+ memset(priv->stations_39, 0, sizeof(priv->stations_39));
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
@@ -401,7 +164,7 @@ static void iwl3945_clear_stations_table(struct iwl3945_priv *priv)
/**
* iwl3945_add_station - Add station to station tables in driver and device
*/
-u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 flags)
+u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
{
int i;
int index = IWL_INVALID_STATION;
@@ -413,16 +176,16 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
if (is_ap)
index = IWL_AP_ID;
else if (is_broadcast_ether_addr(addr))
- index = priv->hw_setting.bcast_sta_id;
+ index = priv->hw_params.bcast_sta_id;
else
- for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) {
- if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
+ for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
+ if (!compare_ether_addr(priv->stations_39[i].sta.sta.addr,
addr)) {
index = i;
break;
}
- if (!priv->stations[i].used &&
+ if (!priv->stations_39[i].used &&
index == IWL_INVALID_STATION)
index = i;
}
@@ -434,14 +197,14 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
return index;
}
- if (priv->stations[index].used &&
- !compare_ether_addr(priv->stations[index].sta.sta.addr, addr)) {
+ if (priv->stations_39[index].used &&
+ !compare_ether_addr(priv->stations_39[index].sta.sta.addr, addr)) {
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
return index;
}
- IWL_DEBUG_ASSOC("Add STA ID %d: %pM\n", index, addr);
- station = &priv->stations[index];
+ IWL_DEBUG_ASSOC(priv, "Add STA ID %d: %pM\n", index, addr);
+ station = &priv->stations_39[index];
station->used = 1;
priv->num_stations++;
@@ -460,531 +223,35 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8
/* Turn on both antennas for the station... */
station->sta.rate_n_flags =
iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
- station->current_rate.rate_n_flags =
- le16_to_cpu(station->sta.rate_n_flags);
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
/* Add station to device's station table */
- iwl3945_send_add_station(priv, &station->sta, flags);
+ iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&station->sta, flags);
return index;
}
-/*************** DRIVER STATUS FUNCTIONS *****/
-
-static inline int iwl3945_is_ready(struct iwl3945_priv *priv)
-{
- /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are
- * set but EXIT_PENDING is not */
- return test_bit(STATUS_READY, &priv->status) &&
- test_bit(STATUS_GEO_CONFIGURED, &priv->status) &&
- !test_bit(STATUS_EXIT_PENDING, &priv->status);
-}
-
-static inline int iwl3945_is_alive(struct iwl3945_priv *priv)
-{
- return test_bit(STATUS_ALIVE, &priv->status);
-}
-
-static inline int iwl3945_is_init(struct iwl3945_priv *priv)
-{
- return test_bit(STATUS_INIT, &priv->status);
-}
-
-static inline int iwl3945_is_rfkill_sw(struct iwl3945_priv *priv)
-{
- return test_bit(STATUS_RF_KILL_SW, &priv->status);
-}
-
-static inline int iwl3945_is_rfkill_hw(struct iwl3945_priv *priv)
-{
- return test_bit(STATUS_RF_KILL_HW, &priv->status);
-}
-
-static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv)
-{
- return iwl3945_is_rfkill_hw(priv) ||
- iwl3945_is_rfkill_sw(priv);
-}
-
-static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv)
-{
-
- if (iwl3945_is_rfkill(priv))
- return 0;
-
- return iwl3945_is_ready(priv);
-}
-
-/*************** HOST COMMAND QUEUE FUNCTIONS *****/
-
-#define IWL_CMD(x) case x: return #x
-
-static const char *get_cmd_string(u8 cmd)
-{
- switch (cmd) {
- IWL_CMD(REPLY_ALIVE);
- IWL_CMD(REPLY_ERROR);
- IWL_CMD(REPLY_RXON);
- IWL_CMD(REPLY_RXON_ASSOC);
- IWL_CMD(REPLY_QOS_PARAM);
- IWL_CMD(REPLY_RXON_TIMING);
- IWL_CMD(REPLY_ADD_STA);
- IWL_CMD(REPLY_REMOVE_STA);
- IWL_CMD(REPLY_REMOVE_ALL_STA);
- IWL_CMD(REPLY_3945_RX);
- IWL_CMD(REPLY_TX);
- IWL_CMD(REPLY_RATE_SCALE);
- IWL_CMD(REPLY_LEDS_CMD);
- IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
- IWL_CMD(RADAR_NOTIFICATION);
- IWL_CMD(REPLY_QUIET_CMD);
- IWL_CMD(REPLY_CHANNEL_SWITCH);
- IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
- IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD);
- IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION);
- IWL_CMD(POWER_TABLE_CMD);
- IWL_CMD(PM_SLEEP_NOTIFICATION);
- IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC);
- IWL_CMD(REPLY_SCAN_CMD);
- IWL_CMD(REPLY_SCAN_ABORT_CMD);
- IWL_CMD(SCAN_START_NOTIFICATION);
- IWL_CMD(SCAN_RESULTS_NOTIFICATION);
- IWL_CMD(SCAN_COMPLETE_NOTIFICATION);
- IWL_CMD(BEACON_NOTIFICATION);
- IWL_CMD(REPLY_TX_BEACON);
- IWL_CMD(WHO_IS_AWAKE_NOTIFICATION);
- IWL_CMD(QUIET_NOTIFICATION);
- IWL_CMD(REPLY_TX_PWR_TABLE_CMD);
- IWL_CMD(MEASURE_ABORT_NOTIFICATION);
- IWL_CMD(REPLY_BT_CONFIG);
- IWL_CMD(REPLY_STATISTICS_CMD);
- IWL_CMD(STATISTICS_NOTIFICATION);
- IWL_CMD(REPLY_CARD_STATE_CMD);
- IWL_CMD(CARD_STATE_NOTIFICATION);
- IWL_CMD(MISSED_BEACONS_NOTIFICATION);
- default:
- return "UNKNOWN";
-
- }
-}
-
-#define HOST_COMPLETE_TIMEOUT (HZ / 2)
-
-/**
- * iwl3945_enqueue_hcmd - enqueue a uCode command
- * @priv: device private data point
- * @cmd: a point to the ucode command structure
- *
- * The function returns < 0 values to indicate the operation is
- * failed. On success, it turns the index (> 0) of command in the
- * command queue.
- */
-static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
- struct iwl3945_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
- struct iwl3945_queue *q = &txq->q;
- struct iwl3945_tfd_frame *tfd;
- u32 *control_flags;
- struct iwl3945_cmd *out_cmd;
- u32 idx;
- u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
- dma_addr_t phys_addr;
- int pad;
- u16 count;
- int ret;
- unsigned long flags;
-
- /* If any of the command structures end up being larger than
- * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then
- * we will need to increase the size of the TFD entries */
- BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
- !(cmd->meta.flags & CMD_SIZE_HUGE));
-
-
- if (iwl3945_is_rfkill(priv)) {
- IWL_DEBUG_INFO("Not sending command - RF KILL");
- return -EIO;
- }
-
- if (iwl3945_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
- IWL_ERROR("No space for Tx\n");
- return -ENOSPC;
- }
-
- spin_lock_irqsave(&priv->hcmd_lock, flags);
-
- tfd = &txq->bd[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
-
- control_flags = (u32 *) tfd;
-
- idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
- out_cmd = &txq->cmd[idx];
-
- out_cmd->hdr.cmd = cmd->id;
- memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
- memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
-
- /* At this point, the out_cmd now has all of the incoming cmd
- * information */
-
- out_cmd->hdr.flags = 0;
- out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
- INDEX_TO_SEQ(q->write_ptr));
- if (out_cmd->meta.flags & CMD_SIZE_HUGE)
- out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
-
- phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx +
- offsetof(struct iwl3945_cmd, hdr);
- iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
-
- pad = U32_PAD(cmd->len);
- count = TFD_CTL_COUNT_GET(*control_flags);
- *control_flags = TFD_CTL_COUNT_SET(count) | TFD_CTL_PAD_SET(pad);
-
- IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
- "%d bytes at %d[%d]:%d\n",
- get_cmd_string(out_cmd->hdr.cmd),
- out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
- fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
-
- txq->need_update = 1;
-
- /* Increment and update queue's write index */
- q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
- ret = iwl3945_tx_queue_update_write_ptr(priv, txq);
-
- spin_unlock_irqrestore(&priv->hcmd_lock, flags);
- return ret ? ret : idx;
-}
-
-static int iwl3945_send_cmd_async(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
- int ret;
-
- BUG_ON(!(cmd->meta.flags & CMD_ASYNC));
-
- /* An asynchronous command can not expect an SKB to be set. */
- BUG_ON(cmd->meta.flags & CMD_WANT_SKB);
-
- /* An asynchronous command MUST have a callback. */
- BUG_ON(!cmd->meta.u.callback);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return -EBUSY;
-
- ret = iwl3945_enqueue_hcmd(priv, cmd);
- if (ret < 0) {
- IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n",
- get_cmd_string(cmd->id), ret);
- return ret;
- }
- return 0;
-}
-
-static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
- int cmd_idx;
- int ret;
-
- BUG_ON(cmd->meta.flags & CMD_ASYNC);
-
- /* A synchronous command can not have a callback set. */
- BUG_ON(cmd->meta.u.callback != NULL);
-
- if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
- IWL_ERROR("Error sending %s: Already sending a host command\n",
- get_cmd_string(cmd->id));
- ret = -EBUSY;
- goto out;
- }
-
- set_bit(STATUS_HCMD_ACTIVE, &priv->status);
-
- if (cmd->meta.flags & CMD_WANT_SKB)
- cmd->meta.source = &cmd->meta;
-
- cmd_idx = iwl3945_enqueue_hcmd(priv, cmd);
- if (cmd_idx < 0) {
- ret = cmd_idx;
- IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n",
- get_cmd_string(cmd->id), ret);
- goto out;
- }
-
- ret = wait_event_interruptible_timeout(priv->wait_command_queue,
- !test_bit(STATUS_HCMD_ACTIVE, &priv->status),
- HOST_COMPLETE_TIMEOUT);
- if (!ret) {
- if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) {
- IWL_ERROR("Error sending %s: time out after %dms.\n",
- get_cmd_string(cmd->id),
- jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
-
- clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
- ret = -ETIMEDOUT;
- goto cancel;
- }
- }
-
- if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
- IWL_DEBUG_INFO("Command %s aborted: RF KILL Switch\n",
- get_cmd_string(cmd->id));
- ret = -ECANCELED;
- goto fail;
- }
- if (test_bit(STATUS_FW_ERROR, &priv->status)) {
- IWL_DEBUG_INFO("Command %s failed: FW Error\n",
- get_cmd_string(cmd->id));
- ret = -EIO;
- goto fail;
- }
- if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) {
- IWL_ERROR("Error: Response NULL in '%s'\n",
- get_cmd_string(cmd->id));
- ret = -EIO;
- goto cancel;
- }
-
- ret = 0;
- goto out;
-
-cancel:
- if (cmd->meta.flags & CMD_WANT_SKB) {
- struct iwl3945_cmd *qcmd;
-
- /* Cancel the CMD_WANT_SKB flag for the cmd in the
- * TX cmd queue. Otherwise in case the cmd comes
- * in later, it will possibly set an invalid
- * address (cmd->meta.source). */
- qcmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
- qcmd->meta.flags &= ~CMD_WANT_SKB;
- }
-fail:
- if (cmd->meta.u.skb) {
- dev_kfree_skb_any(cmd->meta.u.skb);
- cmd->meta.u.skb = NULL;
- }
-out:
- clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
- return ret;
-}
-
-int iwl3945_send_cmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
-{
- if (cmd->meta.flags & CMD_ASYNC)
- return iwl3945_send_cmd_async(priv, cmd);
-
- return iwl3945_send_cmd_sync(priv, cmd);
-}
-
-int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len, const void *data)
-{
- struct iwl3945_host_cmd cmd = {
- .id = id,
- .len = len,
- .data = data,
- };
-
- return iwl3945_send_cmd_sync(priv, &cmd);
-}
-
-static int __must_check iwl3945_send_cmd_u32(struct iwl3945_priv *priv, u8 id, u32 val)
-{
- struct iwl3945_host_cmd cmd = {
- .id = id,
- .len = sizeof(val),
- .data = &val,
- };
-
- return iwl3945_send_cmd_sync(priv, &cmd);
-}
-
-int iwl3945_send_statistics_request(struct iwl3945_priv *priv)
-{
- return iwl3945_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0);
-}
-
-/**
- * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON
- * @band: 2.4 or 5 GHz band
- * @channel: Any channel valid for the requested band
-
- * In addition to setting the staging RXON, priv->band is also set.
- *
- * NOTE: Does not commit to the hardware; it sets appropriate bit fields
- * in the staging RXON flag structure based on the band
- */
-static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv,
- enum ieee80211_band band,
- u16 channel)
-{
- if (!iwl3945_get_channel_info(priv, band, channel)) {
- IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
- channel, band);
- return -EINVAL;
- }
-
- if ((le16_to_cpu(priv->staging_rxon.channel) == channel) &&
- (priv->band == band))
- return 0;
-
- priv->staging_rxon.channel = cpu_to_le16(channel);
- if (band == IEEE80211_BAND_5GHZ)
- priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK;
- else
- priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
-
- priv->band = band;
-
- IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band);
-
- return 0;
-}
-
-/**
- * iwl3945_check_rxon_cmd - validate RXON structure is valid
- *
- * NOTE: This is really only useful during development and can eventually
- * be #ifdef'd out once the driver is stable and folks aren't actively
- * making changes
- */
-static int iwl3945_check_rxon_cmd(struct iwl3945_rxon_cmd *rxon)
-{
- int error = 0;
- int counter = 1;
-
- if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
- error |= le32_to_cpu(rxon->flags &
- (RXON_FLG_TGJ_NARROW_BAND_MSK |
- RXON_FLG_RADAR_DETECT_MSK));
- if (error)
- IWL_WARNING("check 24G fields %d | %d\n",
- counter++, error);
- } else {
- error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
- 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
- if (error)
- IWL_WARNING("check 52 fields %d | %d\n",
- counter++, error);
- error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
- if (error)
- IWL_WARNING("check 52 CCK %d | %d\n",
- counter++, error);
- }
- error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
- if (error)
- IWL_WARNING("check mac addr %d | %d\n", counter++, error);
-
- /* make sure basic rates 6Mbps and 1Mbps are supported */
- error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
- ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
- if (error)
- IWL_WARNING("check basic rate %d | %d\n", counter++, error);
-
- error |= (le16_to_cpu(rxon->assoc_id) > 2007);
- if (error)
- IWL_WARNING("check assoc id %d | %d\n", counter++, error);
-
- error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
- == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
- if (error)
- IWL_WARNING("check CCK and short slot %d | %d\n",
- counter++, error);
-
- error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
- == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
- if (error)
- IWL_WARNING("check CCK & auto detect %d | %d\n",
- counter++, error);
-
- error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
- RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
- if (error)
- IWL_WARNING("check TGG and auto detect %d | %d\n",
- counter++, error);
-
- if ((rxon->flags & RXON_FLG_DIS_DIV_MSK))
- error |= ((rxon->flags & (RXON_FLG_ANT_B_MSK |
- RXON_FLG_ANT_A_MSK)) == 0);
- if (error)
- IWL_WARNING("check antenna %d %d\n", counter++, error);
-
- if (error)
- IWL_WARNING("Tuning to channel %d\n",
- le16_to_cpu(rxon->channel));
-
- if (error) {
- IWL_ERROR("Not a valid iwl3945_rxon_assoc_cmd field values\n");
- return -1;
- }
- return 0;
-}
-
-/**
- * iwl3945_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
- * @priv: staging_rxon is compared to active_rxon
- *
- * If the RXON structure is changing enough to require a new tune,
- * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
- * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
- */
-static int iwl3945_full_rxon_required(struct iwl3945_priv *priv)
-{
-
- /* These items are only settable from the full RXON command */
- if (!(iwl3945_is_associated(priv)) ||
- compare_ether_addr(priv->staging_rxon.bssid_addr,
- priv->active_rxon.bssid_addr) ||
- compare_ether_addr(priv->staging_rxon.node_addr,
- priv->active_rxon.node_addr) ||
- compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
- priv->active_rxon.wlap_bssid_addr) ||
- (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
- (priv->staging_rxon.channel != priv->active_rxon.channel) ||
- (priv->staging_rxon.air_propagation !=
- priv->active_rxon.air_propagation) ||
- (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
- return 1;
-
- /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
- * be updated with the RXON_ASSOC command -- however only some
- * flag transitions are allowed using RXON_ASSOC */
-
- /* Check if we are not switching bands */
- if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
- (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
- return 1;
-
- /* Check if we are switching association toggle */
- if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
- (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
- return 1;
-
- return 0;
-}
-
-static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
+static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
{
int rc = 0;
- struct iwl3945_rx_packet *res = NULL;
+ struct iwl_rx_packet *res = NULL;
struct iwl3945_rxon_assoc_cmd rxon_assoc;
- struct iwl3945_host_cmd cmd = {
+ struct iwl_host_cmd cmd = {
.id = REPLY_RXON_ASSOC,
.len = sizeof(rxon_assoc),
.meta.flags = CMD_WANT_SKB,
.data = &rxon_assoc,
};
- const struct iwl3945_rxon_cmd *rxon1 = &priv->staging_rxon;
- const struct iwl3945_rxon_cmd *rxon2 = &priv->active_rxon;
+ const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
+ const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
if ((rxon1->flags == rxon2->flags) &&
(rxon1->filter_flags == rxon2->filter_flags) &&
(rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
(rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
- IWL_DEBUG_INFO("Using current RXON_ASSOC. Not resending.\n");
+ IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
return 0;
}
@@ -994,13 +261,13 @@ static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
rxon_assoc.reserved = 0;
- rc = iwl3945_send_cmd_sync(priv, &cmd);
+ rc = iwl_send_cmd_sync(priv, &cmd);
if (rc)
return rc;
- res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_RXON_ASSOC command\n");
+ IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
rc = -EIO;
}
@@ -1011,6 +278,43 @@ static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
}
/**
+ * iwl3945_get_antenna_flags - Get antenna flags for RXON command
+ * @priv: eeprom and antenna fields are used to determine antenna flags
+ *
+ * priv->eeprom39 is used to determine if antenna AUX/MAIN are reversed
+ * iwl3945_mod_params.antenna specifies the antenna diversity mode:
+ *
+ * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself
+ * IWL_ANTENNA_MAIN - Force MAIN antenna
+ * IWL_ANTENNA_AUX - Force AUX antenna
+ */
+__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
+{
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+
+ switch (iwl3945_mod_params.antenna) {
+ case IWL_ANTENNA_DIVERSITY:
+ return 0;
+
+ case IWL_ANTENNA_MAIN:
+ if (eeprom->antenna_switch_type)
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
+
+ case IWL_ANTENNA_AUX:
+ if (eeprom->antenna_switch_type)
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
+ }
+
+ /* bad antenna selector value */
+ IWL_ERR(priv, "Bad antenna selector value (0x%x)\n",
+ iwl3945_mod_params.antenna);
+
+ return 0; /* "diversity" is default if error */
+}
+
+/**
* iwl3945_commit_rxon - commit staging_rxon to hardware
*
* The RXON command in staging_rxon is committed to the hardware and
@@ -1018,41 +322,44 @@ static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
* function correctly transitions out of the RXON_ASSOC_MSK state if
* a HW tune is required based on the RXON structure changes.
*/
-static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
+static int iwl3945_commit_rxon(struct iwl_priv *priv)
{
/* cast away the const for active_rxon in this function */
struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
+ struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
int rc = 0;
+ bool new_assoc =
+ !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -1;
/* always get timestamp with Rx frame */
- priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
+ staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
/* select antenna */
- priv->staging_rxon.flags &=
+ staging_rxon->flags &=
~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
- priv->staging_rxon.flags |= iwl3945_get_antenna_flags(priv);
+ staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
- rc = iwl3945_check_rxon_cmd(&priv->staging_rxon);
+ rc = iwl_check_rxon_cmd(priv);
if (rc) {
- IWL_ERROR("Invalid RXON configuration. Not committing.\n");
+ IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
return -EINVAL;
}
/* If we don't need to send a full RXON, we can use
* iwl3945_rxon_assoc_cmd which is used to reconfigure filter
* and other flags for the current radio configuration. */
- if (!iwl3945_full_rxon_required(priv)) {
+ if (!iwl_full_rxon_required(priv)) {
rc = iwl3945_send_rxon_assoc(priv);
if (rc) {
- IWL_ERROR("Error setting RXON_ASSOC "
+ IWL_ERR(priv, "Error setting RXON_ASSOC "
"configuration (%d).\n", rc);
return rc;
}
- memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
+ memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
return 0;
}
@@ -1061,12 +368,17 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
* an RXON_ASSOC and the new config wants the associated mask enabled,
* we must clear the associated from the active configuration
* before we apply the new config */
- if (iwl3945_is_associated(priv) &&
- (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) {
- IWL_DEBUG_INFO("Toggling associated bit on current RXON\n");
+ if (iwl_is_associated(priv) && new_assoc) {
+ IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
+ /*
+ * reserved4 and 5 could have been filled by the iwlcore code.
+ * Let's clear them before pushing to the 3945.
+ */
+ active_rxon->reserved4 = 0;
+ active_rxon->reserved5 = 0;
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
sizeof(struct iwl3945_rxon_cmd),
&priv->active_rxon);
@@ -1074,290 +386,213 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
* active_rxon back to what it was previously */
if (rc) {
active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
- IWL_ERROR("Error clearing ASSOC_MSK on current "
+ IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
"configuration (%d).\n", rc);
return rc;
}
}
- IWL_DEBUG_INFO("Sending RXON\n"
+ IWL_DEBUG_INFO(priv, "Sending RXON\n"
"* with%s RXON_FILTER_ASSOC_MSK\n"
"* channel = %d\n"
"* bssid = %pM\n",
- ((priv->staging_rxon.filter_flags &
- RXON_FILTER_ASSOC_MSK) ? "" : "out"),
- le16_to_cpu(priv->staging_rxon.channel),
- priv->staging_rxon.bssid_addr);
+ (new_assoc ? "" : "out"),
+ le16_to_cpu(staging_rxon->channel),
+ staging_rxon->bssid_addr);
+
+ /*
+ * reserved4 and 5 could have been filled by the iwlcore code.
+ * Let's clear them before pushing to the 3945.
+ */
+ staging_rxon->reserved4 = 0;
+ staging_rxon->reserved5 = 0;
+
+ iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
/* Apply the new configuration */
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl3945_rxon_cmd), &priv->staging_rxon);
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
+ sizeof(struct iwl3945_rxon_cmd),
+ staging_rxon);
if (rc) {
- IWL_ERROR("Error setting new configuration (%d).\n", rc);
+ IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
return rc;
}
- memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
+ memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
iwl3945_clear_stations_table(priv);
/* If we issue a new RXON command which required a tune then we must
* send a new TXPOWER command or we won't be able to Tx any frames */
- rc = iwl3945_hw_reg_send_txpower(priv);
+ rc = priv->cfg->ops->lib->send_tx_power(priv);
if (rc) {
- IWL_ERROR("Error setting Tx power (%d).\n", rc);
+ IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
return rc;
}
/* Add the broadcast address so we can send broadcast frames */
- if (iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0) ==
+ if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) ==
IWL_INVALID_STATION) {
- IWL_ERROR("Error adding BROADCAST address for transmit.\n");
+ IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
return -EIO;
}
/* If we have set the ASSOC_MSK and we are in BSS mode then
* add the IWL_AP_ID to the station rate table */
- if (iwl3945_is_associated(priv) &&
+ if (iwl_is_associated(priv) &&
(priv->iw_mode == NL80211_IFTYPE_STATION))
- if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, 1, 0)
+ if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr,
+ 1, 0)
== IWL_INVALID_STATION) {
- IWL_ERROR("Error adding AP address for transmit.\n");
+ IWL_ERR(priv, "Error adding AP address for transmit\n");
return -EIO;
}
/* Init the hardware's rate fallback order based on the band */
rc = iwl3945_init_hw_rate_table(priv);
if (rc) {
- IWL_ERROR("Error setting HW rate table: %02X\n", rc);
+ IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
return -EIO;
}
return 0;
}
-static int iwl3945_send_bt_config(struct iwl3945_priv *priv)
+static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
{
- struct iwl3945_bt_cmd bt_cmd = {
- .flags = 3,
- .lead_time = 0xAA,
- .max_kill = 1,
- .kill_ack_mask = 0,
- .kill_cts_mask = 0,
- };
+ unsigned long flags;
+ __le16 key_flags = 0;
+ int ret;
- return iwl3945_send_cmd_pdu(priv, REPLY_BT_CONFIG,
- sizeof(struct iwl3945_bt_cmd), &bt_cmd);
-}
+ key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
+ key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
-static int iwl3945_send_scan_abort(struct iwl3945_priv *priv)
-{
- int rc = 0;
- struct iwl3945_rx_packet *res;
- struct iwl3945_host_cmd cmd = {
- .id = REPLY_SCAN_ABORT_CMD,
- .meta.flags = CMD_WANT_SKB,
- };
+ if (sta_id == priv->hw_params.bcast_sta_id)
+ key_flags |= STA_KEY_MULTICAST_MSK;
- /* If there isn't a scan actively going on in the hardware
- * then we are in between scan bands and not actually
- * actively scanning, so don't send the abort command */
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return 0;
- }
+ keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ keyconf->hw_key_idx = keyconf->keyidx;
+ key_flags &= ~STA_KEY_FLG_INVALID;
- rc = iwl3945_send_cmd_sync(priv, &cmd);
- if (rc) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return rc;
- }
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations_39[sta_id].keyinfo.alg = keyconf->alg;
+ priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen;
+ memcpy(priv->stations_39[sta_id].keyinfo.key, keyconf->key,
+ keyconf->keylen);
- res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
- if (res->u.status != CAN_ABORT_STATUS) {
- /* The scan abort will return 1 for success or
- * 2 for "failure". A failure condition can be
- * due to simply not being in an active scan which
- * can occur if we send the scan abort before we
- * the microcode has notified us that a scan is
- * completed. */
- IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- clear_bit(STATUS_SCAN_HW, &priv->status);
- }
+ memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key,
+ keyconf->keylen);
- dev_kfree_skb_any(cmd.meta.u.skb);
+ if ((priv->stations_39[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+ == STA_KEY_FLG_NO_ENC)
+ priv->stations_39[sta_id].sta.key.key_offset =
+ iwl_get_free_ucode_key_index(priv);
+ /* else, we are overriding an existing key => no need to allocated room
+ * in uCode. */
- return rc;
-}
+ WARN(priv->stations_39[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+ "no space for a new key");
-static int iwl3945_card_state_sync_callback(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
- struct sk_buff *skb)
-{
- return 1;
-}
+ priv->stations_39[sta_id].sta.key.key_flags = key_flags;
+ priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+ priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-/*
- * CARD_STATE_CMD
- *
- * Use: Sets the device's internal card state to enable, disable, or halt
- *
- * When in the 'enable' state the card operates as normal.
- * When in the 'disable' state, the card enters into a low power mode.
- * When in the 'halt' state, the card is shut down and must be fully
- * restarted to come back on.
- */
-static int iwl3945_send_card_state(struct iwl3945_priv *priv, u32 flags, u8 meta_flag)
-{
- struct iwl3945_host_cmd cmd = {
- .id = REPLY_CARD_STATE_CMD,
- .len = sizeof(u32),
- .data = &flags,
- .meta.flags = meta_flag,
- };
+ IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n");
+
+ ret = iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, CMD_ASYNC);
- if (meta_flag & CMD_ASYNC)
- cmd.meta.u.callback = iwl3945_card_state_sync_callback;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
- return iwl3945_send_cmd(priv, &cmd);
+ return ret;
}
-static int iwl3945_add_sta_sync_callback(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd, struct sk_buff *skb)
+static int iwl3945_set_tkip_dynamic_key_info(struct iwl_priv *priv,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
{
- struct iwl3945_rx_packet *res = NULL;
-
- if (!skb) {
- IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
- return 1;
- }
-
- res = (struct iwl3945_rx_packet *)skb->data;
- if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
- res->hdr.flags);
- return 1;
- }
-
- switch (res->u.add_sta.status) {
- case ADD_STA_SUCCESS_MSK:
- break;
- default:
- break;
- }
-
- /* We didn't cache the SKB; let the caller free it */
- return 1;
+ return -EOPNOTSUPP;
}
-int iwl3945_send_add_station(struct iwl3945_priv *priv,
- struct iwl3945_addsta_cmd *sta, u8 flags)
+static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
{
- struct iwl3945_rx_packet *res = NULL;
- int rc = 0;
- struct iwl3945_host_cmd cmd = {
- .id = REPLY_ADD_STA,
- .len = sizeof(struct iwl3945_addsta_cmd),
- .meta.flags = flags,
- .data = sta,
- };
-
- if (flags & CMD_ASYNC)
- cmd.meta.u.callback = iwl3945_add_sta_sync_callback;
- else
- cmd.meta.flags |= CMD_WANT_SKB;
-
- rc = iwl3945_send_cmd(priv, &cmd);
-
- if (rc || (flags & CMD_ASYNC))
- return rc;
-
- res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
- if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
- res->hdr.flags);
- rc = -EIO;
- }
+ return -EOPNOTSUPP;
+}
- if (rc == 0) {
- switch (res->u.add_sta.status) {
- case ADD_STA_SUCCESS_MSK:
- IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n");
- break;
- default:
- rc = -EIO;
- IWL_WARNING("REPLY_ADD_STA failed\n");
- break;
- }
- }
+static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
+{
+ unsigned long flags;
- priv->alloc_rxb_skb--;
- dev_kfree_skb_any(cmd.meta.u.skb);
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ memset(&priv->stations_39[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key));
+ memset(&priv->stations_39[sta_id].sta.key, 0,
+ sizeof(struct iwl4965_keyinfo));
+ priv->stations_39[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
+ priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+ priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
- return rc;
+ IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
+ iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);
+ return 0;
}
-static int iwl3945_update_sta_key_info(struct iwl3945_priv *priv,
- struct ieee80211_key_conf *keyconf,
- u8 sta_id)
+static int iwl3945_set_dynamic_key(struct iwl_priv *priv,
+ struct ieee80211_key_conf *keyconf, u8 sta_id)
{
- unsigned long flags;
- __le16 key_flags = 0;
+ int ret = 0;
+
+ keyconf->hw_key_idx = HW_KEY_DYNAMIC;
switch (keyconf->alg) {
case ALG_CCMP:
- key_flags |= STA_KEY_FLG_CCMP;
- key_flags |= cpu_to_le16(
- keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
- key_flags &= ~STA_KEY_FLG_INVALID;
+ ret = iwl3945_set_ccmp_dynamic_key_info(priv, keyconf, sta_id);
break;
case ALG_TKIP:
+ ret = iwl3945_set_tkip_dynamic_key_info(priv, keyconf, sta_id);
+ break;
case ALG_WEP:
+ ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id);
+ break;
default:
- return -EINVAL;
+ IWL_ERR(priv, "Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
+ ret = -EINVAL;
}
- spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations[sta_id].keyinfo.alg = keyconf->alg;
- priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
- memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
- keyconf->keylen);
-
- memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
- keyconf->keylen);
- priv->stations[sta_id].sta.key.key_flags = key_flags;
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
+ IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
+ keyconf->alg, keyconf->keylen, keyconf->keyidx,
+ sta_id, ret);
- IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n");
- iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0);
- return 0;
+ return ret;
}
-static int iwl3945_clear_sta_key_info(struct iwl3945_priv *priv, u8 sta_id)
+static int iwl3945_remove_static_key(struct iwl_priv *priv)
{
- unsigned long flags;
+ int ret = -EOPNOTSUPP;
- spin_lock_irqsave(&priv->sta_lock, flags);
- memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key));
- memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl3945_keyinfo));
- priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
- priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
- priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return ret;
+}
- IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
- iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0);
- return 0;
+static int iwl3945_set_static_key(struct iwl_priv *priv,
+ struct ieee80211_key_conf *key)
+{
+ if (key->alg == ALG_WEP)
+ return -EOPNOTSUPP;
+
+ IWL_ERR(priv, "Static key invalid: alg %d\n", key->alg);
+ return -EINVAL;
}
-static void iwl3945_clear_free_frames(struct iwl3945_priv *priv)
+static void iwl3945_clear_free_frames(struct iwl_priv *priv)
{
struct list_head *element;
- IWL_DEBUG_INFO("%d frames on pre-allocated heap on clear.\n",
+ IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
priv->frames_count);
while (!list_empty(&priv->free_frames)) {
@@ -1368,20 +603,20 @@ static void iwl3945_clear_free_frames(struct iwl3945_priv *priv)
}
if (priv->frames_count) {
- IWL_WARNING("%d frames still in use. Did we lose one?\n",
+ IWL_WARN(priv, "%d frames still in use. Did we lose one?\n",
priv->frames_count);
priv->frames_count = 0;
}
}
-static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl3945_priv *priv)
+static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl_priv *priv)
{
struct iwl3945_frame *frame;
struct list_head *element;
if (list_empty(&priv->free_frames)) {
frame = kzalloc(sizeof(*frame), GFP_KERNEL);
if (!frame) {
- IWL_ERROR("Could not allocate frame!\n");
+ IWL_ERR(priv, "Could not allocate frame!\n");
return NULL;
}
@@ -1394,18 +629,18 @@ static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl3945_priv *priv)
return list_entry(element, struct iwl3945_frame, list);
}
-static void iwl3945_free_frame(struct iwl3945_priv *priv, struct iwl3945_frame *frame)
+static void iwl3945_free_frame(struct iwl_priv *priv, struct iwl3945_frame *frame)
{
memset(frame, 0, sizeof(*frame));
list_add(&frame->list, &priv->free_frames);
}
-unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
+unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,
int left)
{
- if (!iwl3945_is_associated(priv) || !priv->ibss_beacon ||
+ if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
((priv->iw_mode != NL80211_IFTYPE_ADHOC) &&
(priv->iw_mode != NL80211_IFTYPE_AP)))
return 0;
@@ -1418,31 +653,7 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
return priv->ibss_beacon->len;
}
-static u8 iwl3945_rate_get_lowest_plcp(struct iwl3945_priv *priv)
-{
- u8 i;
- int rate_mask;
-
- /* Set rate mask*/
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
- rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
- else
- rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
-
- for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
- i = iwl3945_rates[i].next_ieee) {
- if (rate_mask & (1 << i))
- return iwl3945_rates[i].plcp;
- }
-
- /* No valid rate was found. Assign the lowest one */
- if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
- return IWL_RATE_1M_PLCP;
- else
- return IWL_RATE_6M_PLCP;
-}
-
-static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
+static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
{
struct iwl3945_frame *frame;
unsigned int frame_size;
@@ -1452,16 +663,16 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
frame = iwl3945_get_free_frame(priv);
if (!frame) {
- IWL_ERROR("Could not obtain free frame buffer for beacon "
+ IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
"command.\n");
return -ENOMEM;
}
- rate = iwl3945_rate_get_lowest_plcp(priv);
+ rate = iwl_rate_get_lowest_plcp(priv);
frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
- rc = iwl3945_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
+ rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
&frame->u.cmd[0]);
iwl3945_free_frame(priv, frame);
@@ -1469,566 +680,17 @@ static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
return rc;
}
-/******************************************************************************
- *
- * EEPROM related functions
- *
- ******************************************************************************/
-
-static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac)
-{
- memcpy(mac, priv->eeprom.mac_address, 6);
-}
-
-/*
- * Clear the OWNER_MSK, to establish driver (instead of uCode running on
- * embedded controller) as EEPROM reader; each read is a series of pulses
- * to/from the EEPROM chip, not a single event, so even reads could conflict
- * if they weren't arbitrated by some ownership mechanism. Here, the driver
- * simply claims ownership, which should be safe when this function is called
- * (i.e. before loading uCode!).
- */
-static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
-{
- _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
- return 0;
-}
-
-/**
- * iwl3945_eeprom_init - read EEPROM contents
- *
- * Load the EEPROM contents from adapter into priv->eeprom
- *
- * NOTE: This routine uses the non-debug IO access functions.
- */
-int iwl3945_eeprom_init(struct iwl3945_priv *priv)
-{
- u16 *e = (u16 *)&priv->eeprom;
- u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP);
- int sz = sizeof(priv->eeprom);
- int ret;
- u16 addr;
-
- /* The EEPROM structure has several padding buffers within it
- * and when adding new EEPROM maps is subject to programmer errors
- * which may be very difficult to identify without explicitly
- * checking the resulting size of the eeprom map. */
- BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
-
- if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
- IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
- return -ENOENT;
- }
-
- /* Make sure driver (instead of uCode) is allowed to read EEPROM */
- ret = iwl3945_eeprom_acquire_semaphore(priv);
- if (ret < 0) {
- IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
- return -ENOENT;
- }
-
- /* eeprom is an array of 16bit values */
- for (addr = 0; addr < sz; addr += sizeof(u16)) {
- u32 r;
-
- _iwl3945_write32(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
- _iwl3945_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
- ret = iwl3945_poll_direct_bit(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_READ_VALID_MSK,
- IWL_EEPROM_ACCESS_TIMEOUT);
- if (ret < 0) {
- IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
- return ret;
- }
-
- r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG);
- e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
- }
-
- return 0;
-}
-
-static void iwl3945_unset_hw_setting(struct iwl3945_priv *priv)
+static void iwl3945_unset_hw_params(struct iwl_priv *priv)
{
- if (priv->hw_setting.shared_virt)
+ if (priv->shared_virt)
pci_free_consistent(priv->pci_dev,
sizeof(struct iwl3945_shared),
- priv->hw_setting.shared_virt,
- priv->hw_setting.shared_phys);
-}
-
-/**
- * iwl3945_supported_rate_to_ie - fill in the supported rate in IE field
- *
- * return : set the bit for each supported rate insert in ie
- */
-static u16 iwl3945_supported_rate_to_ie(u8 *ie, u16 supported_rate,
- u16 basic_rate, int *left)
-{
- u16 ret_rates = 0, bit;
- int i;
- u8 *cnt = ie;
- u8 *rates = ie + 1;
-
- for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
- if (bit & supported_rate) {
- ret_rates |= bit;
- rates[*cnt] = iwl3945_rates[i].ieee |
- ((bit & basic_rate) ? 0x80 : 0x00);
- (*cnt)++;
- (*left)--;
- if ((*left <= 0) ||
- (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
- break;
- }
- }
-
- return ret_rates;
-}
-
-/**
- * iwl3945_fill_probe_req - fill in all required fields and IE for probe request
- */
-static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv,
- struct ieee80211_mgmt *frame,
- int left)
-{
- int len = 0;
- u8 *pos = NULL;
- u16 active_rates, ret_rates, cck_rates;
-
- /* Make sure there is enough space for the probe request,
- * two mandatory IEs and the data */
- left -= 24;
- if (left < 0)
- return 0;
- len += 24;
-
- frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
- memcpy(frame->da, iwl3945_broadcast_addr, ETH_ALEN);
- memcpy(frame->sa, priv->mac_addr, ETH_ALEN);
- memcpy(frame->bssid, iwl3945_broadcast_addr, ETH_ALEN);
- frame->seq_ctrl = 0;
-
- /* fill in our indirect SSID IE */
- /* ...next IE... */
-
- left -= 2;
- if (left < 0)
- return 0;
- len += 2;
- pos = &(frame->u.probe_req.variable[0]);
- *pos++ = WLAN_EID_SSID;
- *pos++ = 0;
-
- /* fill in supported rate */
- /* ...next IE... */
- left -= 2;
- if (left < 0)
- return 0;
-
- /* ... fill it in... */
- *pos++ = WLAN_EID_SUPP_RATES;
- *pos = 0;
-
- priv->active_rate = priv->rates_mask;
- active_rates = priv->active_rate;
- priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
-
- cck_rates = IWL_CCK_RATES_MASK & active_rates;
- ret_rates = iwl3945_supported_rate_to_ie(pos, cck_rates,
- priv->active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- ret_rates = iwl3945_supported_rate_to_ie(pos, active_rates,
- priv->active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- len += 2 + *pos;
- pos += (*pos) + 1;
- if (active_rates == 0)
- goto fill_end;
-
- /* fill in supported extended rate */
- /* ...next IE... */
- left -= 2;
- if (left < 0)
- return 0;
- /* ... fill it in... */
- *pos++ = WLAN_EID_EXT_SUPP_RATES;
- *pos = 0;
- iwl3945_supported_rate_to_ie(pos, active_rates,
- priv->active_rate_basic, &left);
- if (*pos > 0)
- len += 2 + *pos;
-
- fill_end:
- return (u16)len;
-}
-
-/*
- * QoS support
-*/
-static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv,
- struct iwl3945_qosparam_cmd *qos)
-{
-
- return iwl3945_send_cmd_pdu(priv, REPLY_QOS_PARAM,
- sizeof(struct iwl3945_qosparam_cmd), qos);
-}
-
-static void iwl3945_reset_qos(struct iwl3945_priv *priv)
-{
- u16 cw_min = 15;
- u16 cw_max = 1023;
- u8 aifs = 2;
- u8 is_legacy = 0;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->qos_data.qos_active = 0;
-
- /* QoS always active in AP and ADHOC mode
- * In STA mode wait for association
- */
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
- priv->iw_mode == NL80211_IFTYPE_AP)
- priv->qos_data.qos_active = 1;
- else
- priv->qos_data.qos_active = 0;
-
-
- /* check for legacy mode */
- if ((priv->iw_mode == NL80211_IFTYPE_ADHOC &&
- (priv->active_rate & IWL_OFDM_RATES_MASK) == 0) ||
- (priv->iw_mode == NL80211_IFTYPE_STATION &&
- (priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) {
- cw_min = 31;
- is_legacy = 1;
- }
-
- if (priv->qos_data.qos_active)
- aifs = 3;
-
- priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);
- priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);
- priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;
- priv->qos_data.def_qos_parm.ac[0].edca_txop = 0;
- priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;
-
- if (priv->qos_data.qos_active) {
- i = 1;
- priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);
- priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);
- priv->qos_data.def_qos_parm.ac[i].aifsn = 7;
- priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
- priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
-
- i = 2;
- priv->qos_data.def_qos_parm.ac[i].cw_min =
- cpu_to_le16((cw_min + 1) / 2 - 1);
- priv->qos_data.def_qos_parm.ac[i].cw_max =
- cpu_to_le16(cw_max);
- priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
- if (is_legacy)
- priv->qos_data.def_qos_parm.ac[i].edca_txop =
- cpu_to_le16(6016);
- else
- priv->qos_data.def_qos_parm.ac[i].edca_txop =
- cpu_to_le16(3008);
- priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
-
- i = 3;
- priv->qos_data.def_qos_parm.ac[i].cw_min =
- cpu_to_le16((cw_min + 1) / 4 - 1);
- priv->qos_data.def_qos_parm.ac[i].cw_max =
- cpu_to_le16((cw_max + 1) / 2 - 1);
- priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
- priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
- if (is_legacy)
- priv->qos_data.def_qos_parm.ac[i].edca_txop =
- cpu_to_le16(3264);
- else
- priv->qos_data.def_qos_parm.ac[i].edca_txop =
- cpu_to_le16(1504);
- } else {
- for (i = 1; i < 4; i++) {
- priv->qos_data.def_qos_parm.ac[i].cw_min =
- cpu_to_le16(cw_min);
- priv->qos_data.def_qos_parm.ac[i].cw_max =
- cpu_to_le16(cw_max);
- priv->qos_data.def_qos_parm.ac[i].aifsn = aifs;
- priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
- priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
- }
- }
- IWL_DEBUG_QOS("set QoS to default \n");
-
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
-{
- unsigned long flags;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->qos_data.def_qos_parm.qos_flags = 0;
-
- if (priv->qos_data.qos_cap.q_AP.queue_request &&
- !priv->qos_data.qos_cap.q_AP.txop_request)
- priv->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_TXOP_TYPE_MSK;
-
- if (priv->qos_data.qos_active)
- priv->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_UPDATE_EDCA_MSK;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (force || iwl3945_is_associated(priv)) {
- IWL_DEBUG_QOS("send QoS cmd with QoS active %d \n",
- priv->qos_data.qos_active);
-
- iwl3945_send_qos_params_command(priv,
- &(priv->qos_data.def_qos_parm));
- }
-}
-
-/*
- * Power management (not Tx power!) functions
- */
-#define MSEC_TO_USEC 1024
-
-#define NOSLP __constant_cpu_to_le32(0)
-#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK
-#define SLP_TIMEOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)
-#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \
- __constant_cpu_to_le32(X1), \
- __constant_cpu_to_le32(X2), \
- __constant_cpu_to_le32(X3), \
- __constant_cpu_to_le32(X4)}
-
-
-/* default power management (not Tx power) table values */
-/* for TIM 0-10 */
-static struct iwl3945_power_vec_entry range_0[IWL_POWER_AC] = {
- {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100), SLP_VEC(2, 6, 9, 9, 10)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 10)}, 1},
- {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1}
-};
-
-/* for TIM > 10 */
-static struct iwl3945_power_vec_entry range_1[IWL_POWER_AC] = {
- {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500),
- SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300),
- SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100),
- SLP_VEC(2, 6, 9, 9, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
- {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25),
- SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
-};
-
-int iwl3945_power_init_handle(struct iwl3945_priv *priv)
-{
- int rc = 0, i;
- struct iwl3945_power_mgr *pow_data;
- int size = sizeof(struct iwl3945_power_vec_entry) * IWL_POWER_AC;
- u16 pci_pm;
-
- IWL_DEBUG_POWER("Initialize power \n");
-
- pow_data = &(priv->power_data);
-
- memset(pow_data, 0, sizeof(*pow_data));
-
- pow_data->active_index = IWL_POWER_RANGE_0;
- pow_data->dtim_val = 0xffff;
-
- memcpy(&pow_data->pwr_range_0[0], &range_0[0], size);
- memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
-
- rc = pci_read_config_word(priv->pci_dev, PCI_LINK_CTRL, &pci_pm);
- if (rc != 0)
- return 0;
- else {
- struct iwl3945_powertable_cmd *cmd;
-
- IWL_DEBUG_POWER("adjust power command flags\n");
-
- for (i = 0; i < IWL_POWER_AC; i++) {
- cmd = &pow_data->pwr_range_0[i].cmd;
-
- if (pci_pm & 0x1)
- cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
- else
- cmd->flags |= IWL_POWER_PCI_PM_MSK;
- }
- }
- return rc;
-}
-
-static int iwl3945_update_power_cmd(struct iwl3945_priv *priv,
- struct iwl3945_powertable_cmd *cmd, u32 mode)
-{
- int rc = 0, i;
- u8 skip;
- u32 max_sleep = 0;
- struct iwl3945_power_vec_entry *range;
- u8 period = 0;
- struct iwl3945_power_mgr *pow_data;
-
- if (mode > IWL_POWER_INDEX_5) {
- IWL_DEBUG_POWER("Error invalid power mode \n");
- return -1;
- }
- pow_data = &(priv->power_data);
-
- if (pow_data->active_index == IWL_POWER_RANGE_0)
- range = &pow_data->pwr_range_0[0];
- else
- range = &pow_data->pwr_range_1[1];
-
- memcpy(cmd, &range[mode].cmd, sizeof(struct iwl3945_powertable_cmd));
-
-#ifdef IWL_MAC80211_DISABLE
- if (priv->assoc_network != NULL) {
- unsigned long flags;
-
- period = priv->assoc_network->tim.tim_period;
- }
-#endif /*IWL_MAC80211_DISABLE */
- skip = range[mode].no_dtim;
-
- if (period == 0) {
- period = 1;
- skip = 0;
- }
-
- if (skip == 0) {
- max_sleep = period;
- cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
- } else {
- __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
- max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
- cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
- }
-
- for (i = 0; i < IWL_POWER_VEC_SIZE; i++) {
- if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
- cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
- }
-
- IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags);
- IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
- IWL_DEBUG_POWER("Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
- IWL_DEBUG_POWER("Sleep interval vector = { %d , %d , %d , %d , %d }\n",
- le32_to_cpu(cmd->sleep_interval[0]),
- le32_to_cpu(cmd->sleep_interval[1]),
- le32_to_cpu(cmd->sleep_interval[2]),
- le32_to_cpu(cmd->sleep_interval[3]),
- le32_to_cpu(cmd->sleep_interval[4]));
-
- return rc;
-}
-
-static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode)
-{
- u32 uninitialized_var(final_mode);
- int rc;
- struct iwl3945_powertable_cmd cmd;
-
- /* If on battery, set to 3,
- * if plugged into AC power, set to CAM ("continuously aware mode"),
- * else user level */
- switch (mode) {
- case IWL_POWER_BATTERY:
- final_mode = IWL_POWER_INDEX_3;
- break;
- case IWL_POWER_AC:
- final_mode = IWL_POWER_MODE_CAM;
- break;
- default:
- final_mode = mode;
- break;
- }
-
- iwl3945_update_power_cmd(priv, &cmd, final_mode);
-
- rc = iwl3945_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd);
-
- if (final_mode == IWL_POWER_MODE_CAM)
- clear_bit(STATUS_POWER_PMI, &priv->status);
- else
- set_bit(STATUS_POWER_PMI, &priv->status);
-
- return rc;
-}
-
-/**
- * iwl3945_scan_cancel - Cancel any currently executing HW scan
- *
- * NOTE: priv->mutex is not required before calling this function
- */
-static int iwl3945_scan_cancel(struct iwl3945_priv *priv)
-{
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCANNING, &priv->status);
- return 0;
- }
-
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Queuing scan abort.\n");
- set_bit(STATUS_SCAN_ABORTING, &priv->status);
- queue_work(priv->workqueue, &priv->abort_scan);
-
- } else
- IWL_DEBUG_SCAN("Scan abort already in progress.\n");
-
- return test_bit(STATUS_SCANNING, &priv->status);
- }
-
- return 0;
-}
-
-/**
- * iwl3945_scan_cancel_timeout - Cancel any currently executing HW scan
- * @ms: amount of time to wait (in milliseconds) for scan to abort
- *
- * NOTE: priv->mutex must be held before calling this function
- */
-static int iwl3945_scan_cancel_timeout(struct iwl3945_priv *priv, unsigned long ms)
-{
- unsigned long now = jiffies;
- int ret;
-
- ret = iwl3945_scan_cancel(priv);
- if (ret && ms) {
- mutex_unlock(&priv->mutex);
- while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
- test_bit(STATUS_SCANNING, &priv->status))
- msleep(1);
- mutex_lock(&priv->mutex);
-
- return test_bit(STATUS_SCANNING, &priv->status);
- }
-
- return ret;
+ priv->shared_virt,
+ priv->shared_phys);
}
#define MAX_UCODE_BEACON_INTERVAL 1024
-#define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA)
+#define INTEL_CONN_LISTEN_INTERVAL cpu_to_le16(0xA)
static __le16 iwl3945_adjust_beacon_interval(u16 beacon_val)
{
@@ -2043,7 +705,7 @@ static __le16 iwl3945_adjust_beacon_interval(u16 beacon_val)
return cpu_to_le16(new_val);
}
-static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
+static void iwl3945_setup_rxon_timing(struct iwl_priv *priv)
{
u64 interval_tm_unit;
u64 tsf, result;
@@ -2054,13 +716,10 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
conf = ieee80211_get_hw_conf(priv->hw);
spin_lock_irqsave(&priv->lock, flags);
- priv->rxon_timing.timestamp.dw[1] = cpu_to_le32(priv->timestamp1);
- priv->rxon_timing.timestamp.dw[0] = cpu_to_le32(priv->timestamp0);
-
+ priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL;
- tsf = priv->timestamp1;
- tsf = ((tsf << 32) | priv->timestamp0);
+ tsf = priv->timestamp;
beacon_int = priv->beacon_int;
spin_unlock_irqrestore(&priv->lock, flags);
@@ -2092,183 +751,41 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
priv->rxon_timing.beacon_init_val =
cpu_to_le32((u32) ((u64) interval_tm_unit - result));
- IWL_DEBUG_ASSOC
- ("beacon interval %d beacon timer %d beacon tim %d\n",
+ IWL_DEBUG_ASSOC(priv,
+ "beacon interval %d beacon timer %d beacon tim %d\n",
le16_to_cpu(priv->rxon_timing.beacon_interval),
le32_to_cpu(priv->rxon_timing.beacon_init_val),
le16_to_cpu(priv->rxon_timing.atim_window));
}
-static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
-{
- if (!iwl3945_is_ready_rf(priv)) {
- IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
- return -EIO;
- }
-
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- IWL_DEBUG_SCAN("Scan already in progress.\n");
- return -EAGAIN;
- }
-
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Scan request while abort pending. "
- "Queuing.\n");
- return -EAGAIN;
- }
-
- IWL_DEBUG_INFO("Starting scan...\n");
- if (priv->cfg->sku & IWL_SKU_G)
- priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
- if (priv->cfg->sku & IWL_SKU_A)
- priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
- set_bit(STATUS_SCANNING, &priv->status);
- priv->scan_start = jiffies;
- priv->scan_pass_start = priv->scan_start;
-
- queue_work(priv->workqueue, &priv->request_scan);
-
- return 0;
-}
-
-static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt)
-{
- struct iwl3945_rxon_cmd *rxon = &priv->staging_rxon;
-
- if (hw_decrypt)
- rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
- else
- rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;
-
- return 0;
-}
-
-static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv,
- enum ieee80211_band band)
-{
- if (band == IEEE80211_BAND_5GHZ) {
- priv->staging_rxon.flags &=
- ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
- | RXON_FLG_CCK_MSK);
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
- } else {
- /* Copied from iwl3945_bg_post_associate() */
- if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
- priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
- else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
- priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
- priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
- priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
- }
-}
-
-/*
- * initialize rxon structure with default values from eeprom
- */
-static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv,
- int mode)
-{
- const struct iwl3945_channel_info *ch_info;
-
- memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
-
- switch (mode) {
- case NL80211_IFTYPE_AP:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
- break;
-
- case NL80211_IFTYPE_STATION:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
- priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
- break;
-
- case NL80211_IFTYPE_ADHOC:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
- priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
- priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
- RXON_FILTER_ACCEPT_GRP_MSK;
- break;
-
- case NL80211_IFTYPE_MONITOR:
- priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
- priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
- RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
- break;
- default:
- IWL_ERROR("Unsupported interface type %d\n", mode);
- break;
- }
-
-#if 0
- /* TODO: Figure out when short_preamble would be set and cache from
- * that */
- if (!hw_to_local(priv->hw)->short_preamble)
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- else
- priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
-#endif
-
- ch_info = iwl3945_get_channel_info(priv, priv->band,
- le16_to_cpu(priv->active_rxon.channel));
-
- if (!ch_info)
- ch_info = &priv->channel_info[0];
-
- /*
- * in some case A channels are all non IBSS
- * in this case force B/G channel
- */
- if ((mode == NL80211_IFTYPE_ADHOC) && !(is_channel_ibss(ch_info)))
- ch_info = &priv->channel_info[0];
-
- priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
- if (is_channel_a_band(ch_info))
- priv->band = IEEE80211_BAND_5GHZ;
- else
- priv->band = IEEE80211_BAND_2GHZ;
-
- iwl3945_set_flags_for_phymode(priv, priv->band);
-
- priv->staging_rxon.ofdm_basic_rates =
- (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
- priv->staging_rxon.cck_basic_rates =
- (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
-}
-
-static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
+static int iwl3945_set_mode(struct iwl_priv *priv, int mode)
{
if (mode == NL80211_IFTYPE_ADHOC) {
- const struct iwl3945_channel_info *ch_info;
+ const struct iwl_channel_info *ch_info;
- ch_info = iwl3945_get_channel_info(priv,
+ ch_info = iwl_get_channel_info(priv,
priv->band,
le16_to_cpu(priv->staging_rxon.channel));
if (!ch_info || !is_channel_ibss(ch_info)) {
- IWL_ERROR("channel %d not IBSS channel\n",
+ IWL_ERR(priv, "channel %d not IBSS channel\n",
le16_to_cpu(priv->staging_rxon.channel));
return -EINVAL;
}
}
- iwl3945_connection_init_rx_config(priv, mode);
- memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+ iwl_connection_init_rx_config(priv, mode);
iwl3945_clear_stations_table(priv);
/* don't commit rxon if rf-kill is on*/
- if (!iwl3945_is_ready_rf(priv))
+ if (!iwl_is_ready_rf(priv))
return -EAGAIN;
cancel_delayed_work(&priv->scan_check);
- if (iwl3945_scan_cancel_timeout(priv, 100)) {
- IWL_WARNING("Aborted scan still in progress after 100ms\n");
- IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
+ if (iwl_scan_cancel_timeout(priv, 100)) {
+ IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
+ IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
return -EAGAIN;
}
@@ -2277,49 +794,41 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
return 0;
}
-static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
+static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
struct ieee80211_tx_info *info,
- struct iwl3945_cmd *cmd,
+ struct iwl_cmd *cmd,
struct sk_buff *skb_frag,
- int last_frag)
+ int sta_id)
{
+ struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
struct iwl3945_hw_key *keyinfo =
- &priv->stations[info->control.hw_key->hw_key_idx].keyinfo;
+ &priv->stations_39[sta_id].keyinfo;
switch (keyinfo->alg) {
case ALG_CCMP:
- cmd->cmd.tx.sec_ctl = TX_CMD_SEC_CCM;
- memcpy(cmd->cmd.tx.key, keyinfo->key, keyinfo->keylen);
- IWL_DEBUG_TX("tx_cmd with AES hwcrypto\n");
+ tx->sec_ctl = TX_CMD_SEC_CCM;
+ memcpy(tx->key, keyinfo->key, keyinfo->keylen);
+ IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
break;
case ALG_TKIP:
-#if 0
- cmd->cmd.tx.sec_ctl = TX_CMD_SEC_TKIP;
-
- if (last_frag)
- memcpy(cmd->cmd.tx.tkip_mic.byte, skb_frag->tail - 8,
- 8);
- else
- memset(cmd->cmd.tx.tkip_mic.byte, 0, 8);
-#endif
break;
case ALG_WEP:
- cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP |
+ tx->sec_ctl = TX_CMD_SEC_WEP |
(info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
if (keyinfo->keylen == 13)
- cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
+ tx->sec_ctl |= TX_CMD_SEC_KEY128;
- memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen);
+ memcpy(&tx->key[3], keyinfo->key, keyinfo->keylen);
- IWL_DEBUG_TX("Configuring packet for WEP encryption "
+ IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption "
"with key %d\n", info->control.hw_key->hw_key_idx);
break;
default:
- printk(KERN_ERR "Unknown encode alg %d\n", keyinfo->alg);
+ IWL_ERR(priv, "Unknown encode alg %d\n", keyinfo->alg);
break;
}
}
@@ -2327,17 +836,17 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
/*
* handle build REPLY_TX command notification.
*/
-static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
- struct iwl3945_cmd *cmd,
+static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
+ struct iwl_cmd *cmd,
struct ieee80211_tx_info *info,
- struct ieee80211_hdr *hdr,
- int is_unicast, u8 std_id)
+ struct ieee80211_hdr *hdr, u8 std_id)
{
+ struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
+ __le32 tx_flags = tx->tx_flags;
__le16 fc = hdr->frame_control;
- __le32 tx_flags = cmd->cmd.tx.tx_flags;
u8 rc_flags = info->control.rates[0].flags;
- cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
+ tx->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
tx_flags |= TX_CMD_FLG_ACK_MSK;
if (ieee80211_is_mgmt(fc))
@@ -2350,13 +859,13 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
}
- cmd->cmd.tx.sta_id = std_id;
+ tx->sta_id = std_id;
if (ieee80211_has_morefrags(fc))
tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
if (ieee80211_is_data_qos(fc)) {
u8 *qc = ieee80211_get_qos_ctl(hdr);
- cmd->cmd.tx.tid_tspec = qc[0] & 0xf;
+ tx->tid_tspec = qc[0] & 0xf;
tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
} else {
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
@@ -2376,25 +885,25 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
if (ieee80211_is_mgmt(fc)) {
if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
- cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);
+ tx->timeout.pm_frame_timeout = cpu_to_le16(3);
else
- cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);
+ tx->timeout.pm_frame_timeout = cpu_to_le16(2);
} else {
- cmd->cmd.tx.timeout.pm_frame_timeout = 0;
-#ifdef CONFIG_IWL3945_LEDS
+ tx->timeout.pm_frame_timeout = 0;
+#ifdef CONFIG_IWLWIFI_LEDS
priv->rxtxpackets += le16_to_cpu(cmd->cmd.tx.len);
#endif
}
- cmd->cmd.tx.driver_txop = 0;
- cmd->cmd.tx.tx_flags = tx_flags;
- cmd->cmd.tx.next_frame_len = 0;
+ tx->driver_txop = 0;
+ tx->tx_flags = tx_flags;
+ tx->next_frame_len = 0;
}
/**
* iwl3945_get_sta_id - Find station's index within station table
*/
-static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *hdr)
+static int iwl3945_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
{
int sta_id;
u16 fc = le16_to_cpu(hdr->frame_control);
@@ -2402,7 +911,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
/* If this frame is broadcast or management, use broadcast station id */
if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
is_multicast_ether_addr(hdr->addr1))
- return priv->hw_setting.bcast_sta_id;
+ return priv->hw_params.bcast_sta_id;
switch (priv->iw_mode) {
@@ -2416,7 +925,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
if (sta_id != IWL_INVALID_STATION)
return sta_id;
- return priv->hw_setting.bcast_sta_id;
+ return priv->hw_params.bcast_sta_id;
/* If this frame is going out to an IBSS network, find the station,
* or create a new station table entry */
@@ -2431,38 +940,38 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
if (sta_id != IWL_INVALID_STATION)
return sta_id;
- IWL_DEBUG_DROP("Station %pM not in station map. "
+ IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
"Defaulting to broadcast...\n",
hdr->addr1);
- iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
- return priv->hw_setting.bcast_sta_id;
+ iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
+ return priv->hw_params.bcast_sta_id;
}
/* If we are in monitor mode, use BCAST. This is required for
* packet injection. */
case NL80211_IFTYPE_MONITOR:
- return priv->hw_setting.bcast_sta_id;
+ return priv->hw_params.bcast_sta_id;
default:
- IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
- return priv->hw_setting.bcast_sta_id;
+ IWL_WARN(priv, "Unknown mode of operation: %d\n",
+ priv->iw_mode);
+ return priv->hw_params.bcast_sta_id;
}
}
/*
* start REPLY_TX command process
*/
-static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
+static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct iwl3945_tfd_frame *tfd;
- u32 *control_flags;
- int txq_id = skb_get_queue_mapping(skb);
- struct iwl3945_tx_queue *txq = NULL;
- struct iwl3945_queue *q = NULL;
+ struct iwl3945_tx_cmd *tx;
+ struct iwl_tx_queue *txq = NULL;
+ struct iwl_queue *q = NULL;
+ struct iwl_cmd *out_cmd = NULL;
dma_addr_t phys_addr;
dma_addr_t txcmd_phys;
- struct iwl3945_cmd *out_cmd = NULL;
+ int txq_id = skb_get_queue_mapping(skb);
u16 len, idx, len_org, hdr_len;
u8 id;
u8 unicast;
@@ -2476,13 +985,13 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
int rc;
spin_lock_irqsave(&priv->lock, flags);
- if (iwl3945_is_rfkill(priv)) {
- IWL_DEBUG_DROP("Dropping - RF KILL\n");
+ if (iwl_is_rfkill(priv)) {
+ IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
goto drop_unlock;
}
if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) {
- IWL_ERROR("ERROR: No TX rate available.\n");
+ IWL_ERR(priv, "ERROR: No TX rate available.\n");
goto drop_unlock;
}
@@ -2491,21 +1000,21 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
fc = hdr->frame_control;
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
if (ieee80211_is_auth(fc))
- IWL_DEBUG_TX("Sending AUTH frame\n");
+ IWL_DEBUG_TX(priv, "Sending AUTH frame\n");
else if (ieee80211_is_assoc_req(fc))
- IWL_DEBUG_TX("Sending ASSOC frame\n");
+ IWL_DEBUG_TX(priv, "Sending ASSOC frame\n");
else if (ieee80211_is_reassoc_req(fc))
- IWL_DEBUG_TX("Sending REASSOC frame\n");
+ IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
#endif
/* drop all data frame if we are not associated */
if (ieee80211_is_data(fc) &&
(priv->iw_mode != NL80211_IFTYPE_MONITOR) && /* packet injection */
- (!iwl3945_is_associated(priv) ||
+ (!iwl_is_associated(priv) ||
((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) {
- IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
+ IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
goto drop_unlock;
}
@@ -2516,21 +1025,21 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
/* Find (or create) index into station table for destination station */
sta_id = iwl3945_get_sta_id(priv, hdr);
if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_DROP("Dropping - INVALID STATION: %pM\n",
+ IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
goto drop;
}
- IWL_DEBUG_RATE("station Id %d\n", sta_id);
+ IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id);
if (ieee80211_is_data_qos(fc)) {
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
- seq_number = priv->stations[sta_id].tid[tid].seq_number &
+ seq_number = priv->stations_39[sta_id].tid[tid].seq_number &
IEEE80211_SCTL_SEQ;
hdr->seq_ctrl = cpu_to_le16(seq_number) |
(hdr->seq_ctrl &
- __constant_cpu_to_le16(IEEE80211_SCTL_FRAG));
+ cpu_to_le16(IEEE80211_SCTL_FRAG));
seq_number += 0x10;
}
@@ -2540,20 +1049,17 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
spin_lock_irqsave(&priv->lock, flags);
- /* Set up first empty TFD within this queue's circular TFD buffer */
- tfd = &txq->bd[q->write_ptr];
- memset(tfd, 0, sizeof(*tfd));
- control_flags = (u32 *) tfd;
idx = get_cmd_index(q, q->write_ptr, 0);
/* Set up driver data for this TFD */
- memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info));
+ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
txq->txb[q->write_ptr].skb[0] = skb;
/* Init first empty entry in queue's array of Tx/cmd buffers */
- out_cmd = &txq->cmd[idx];
+ out_cmd = txq->cmd[idx];
+ tx = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload;
memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
- memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx));
+ memset(tx, 0, sizeof(*tx));
/*
* Set up the Tx-command (not MAC!) header.
@@ -2566,7 +1072,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
INDEX_TO_SEQ(q->write_ptr)));
/* Copy MAC header from skb into command buffer */
- memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len);
+ memcpy(tx->hdr, hdr, hdr_len);
/*
* Use the first empty entry in this queue's command buffer array
@@ -2577,8 +1083,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
* of the MAC header (device reads on dword boundaries).
* We'll tell device about this padding later.
*/
- len = priv->hw_setting.tx_cmd_len +
- sizeof(struct iwl3945_cmd_header) + hdr_len;
+ len = sizeof(struct iwl3945_tx_cmd) +
+ sizeof(struct iwl_cmd_header) + hdr_len;
len_org = len;
len = (len + 3) & ~3;
@@ -2590,15 +1096,22 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
/* Physical address of this Tx command's header (not MAC header!),
* within command buffer array. */
- txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl3945_cmd) * idx +
- offsetof(struct iwl3945_cmd, hdr);
+ txcmd_phys = pci_map_single(priv->pci_dev,
+ out_cmd, sizeof(struct iwl_cmd),
+ PCI_DMA_TODEVICE);
+ pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
+ pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
+ /* Add buffer containing Tx command and MAC(!) header to TFD's
+ * first entry */
+ txcmd_phys += offsetof(struct iwl_cmd, hdr);
/* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */
- iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ txcmd_phys, len, 1, 0);
if (info->control.hw_key)
- iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0);
+ iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id);
/* Set up TFD's 2nd entry to point directly to remainder of skb,
* if any (802.11 null frames have no payload). */
@@ -2606,64 +1119,56 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
if (len) {
phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
len, PCI_DMA_TODEVICE);
- iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
+ priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
+ phys_addr, len,
+ 0, U32_PAD(len));
}
- if (!len)
- /* If there is no payload, then we use only one Tx buffer */
- *control_flags = TFD_CTL_COUNT_SET(1);
- else
- /* Else use 2 buffers.
- * Tell 3945 about any padding after MAC header */
- *control_flags = TFD_CTL_COUNT_SET(2) |
- TFD_CTL_PAD_SET(U32_PAD(len));
-
/* Total # bytes to be transmitted */
len = (u16)skb->len;
- out_cmd->cmd.tx.len = cpu_to_le16(len);
+ tx->len = cpu_to_le16(len);
/* TODO need this for burst mode later on */
- iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, unicast, sta_id);
+ iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id);
/* set is_hcca to 0; it probably will never be implemented */
iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);
- out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
- out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
+ tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
+ tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;
if (qc)
- priv->stations[sta_id].tid[tid].seq_number = seq_number;
+ priv->stations_39[sta_id].tid[tid].seq_number = seq_number;
} else {
wait_write_ptr = 1;
txq->need_update = 0;
}
- iwl3945_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload,
- sizeof(out_cmd->cmd.tx));
+ iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx));
- iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
+ iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr,
ieee80211_hdrlen(fc));
/* Tell device the write index *just past* this latest filled TFD */
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
- rc = iwl3945_tx_queue_update_write_ptr(priv, txq);
+ rc = iwl_txq_update_write_ptr(priv, txq);
spin_unlock_irqrestore(&priv->lock, flags);
if (rc)
return rc;
- if ((iwl3945_queue_space(q) < q->high_mark)
+ if ((iwl_queue_space(q) < q->high_mark)
&& priv->mac80211_registered) {
if (wait_write_ptr) {
spin_lock_irqsave(&priv->lock, flags);
txq->need_update = 1;
- iwl3945_tx_queue_update_write_ptr(priv, txq);
+ iwl_txq_update_write_ptr(priv, txq);
spin_unlock_irqrestore(&priv->lock, flags);
}
- ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb));
+ iwl_stop_queue(priv, skb_get_queue_mapping(skb));
}
return 0;
@@ -2674,142 +1179,6 @@ drop:
return -1;
}
-static void iwl3945_set_rate(struct iwl3945_priv *priv)
-{
- const struct ieee80211_supported_band *sband = NULL;
- struct ieee80211_rate *rate;
- int i;
-
- sband = iwl3945_get_band(priv, priv->band);
- if (!sband) {
- IWL_ERROR("Failed to set rate: unable to get hw mode\n");
- return;
- }
-
- priv->active_rate = 0;
- priv->active_rate_basic = 0;
-
- IWL_DEBUG_RATE("Setting rates for %s GHz\n",
- sband->band == IEEE80211_BAND_2GHZ ? "2.4" : "5");
-
- for (i = 0; i < sband->n_bitrates; i++) {
- rate = &sband->bitrates[i];
- if ((rate->hw_value < IWL_RATE_COUNT) &&
- !(rate->flags & IEEE80211_CHAN_DISABLED)) {
- IWL_DEBUG_RATE("Adding rate index %d (plcp %d)\n",
- rate->hw_value, iwl3945_rates[rate->hw_value].plcp);
- priv->active_rate |= (1 << rate->hw_value);
- }
- }
-
- IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n",
- priv->active_rate, priv->active_rate_basic);
-
- /*
- * If a basic rate is configured, then use it (adding IWL_RATE_1M_MASK)
- * otherwise set it to the default of all CCK rates and 6, 12, 24 for
- * OFDM
- */
- if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
- priv->staging_rxon.cck_basic_rates =
- ((priv->active_rate_basic &
- IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
- else
- priv->staging_rxon.cck_basic_rates =
- (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
-
- if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
- priv->staging_rxon.ofdm_basic_rates =
- ((priv->active_rate_basic &
- (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
- IWL_FIRST_OFDM_RATE) & 0xFF;
- else
- priv->staging_rxon.ofdm_basic_rates =
- (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
-}
-
-static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
-{
- unsigned long flags;
-
- if (!!disable_radio == test_bit(STATUS_RF_KILL_SW, &priv->status))
- return;
-
- IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO %s\n",
- disable_radio ? "OFF" : "ON");
-
- if (disable_radio) {
- iwl3945_scan_cancel(priv);
- /* FIXME: This is a workaround for AP */
- if (priv->iw_mode != NL80211_IFTYPE_AP) {
- spin_lock_irqsave(&priv->lock, flags);
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET,
- CSR_UCODE_SW_BIT_RFKILL);
- spin_unlock_irqrestore(&priv->lock, flags);
- iwl3945_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0);
- set_bit(STATUS_RF_KILL_SW, &priv->status);
- }
- return;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-
- clear_bit(STATUS_RF_KILL_SW, &priv->status);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- /* wake up ucode */
- msleep(10);
-
- spin_lock_irqsave(&priv->lock, flags);
- iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
- if (!iwl3945_grab_nic_access(priv))
- iwl3945_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
- IWL_DEBUG_RF_KILL("Can not turn radio back on - "
- "disabled by HW switch\n");
- return;
- }
-
- if (priv->is_open)
- queue_work(priv->workqueue, &priv->restart);
- return;
-}
-
-void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb,
- u32 decrypt_res, struct ieee80211_rx_status *stats)
-{
- u16 fc =
- le16_to_cpu(((struct ieee80211_hdr *)skb->data)->frame_control);
-
- if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
- return;
-
- if (!(fc & IEEE80211_FCTL_PROTECTED))
- return;
-
- IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
- switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
- case RX_RES_STATUS_SEC_TYPE_TKIP:
- if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
- RX_RES_STATUS_BAD_ICV_MIC)
- stats->flag |= RX_FLAG_MMIC_ERROR;
- case RX_RES_STATUS_SEC_TYPE_WEP:
- case RX_RES_STATUS_SEC_TYPE_CCMP:
- if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
- RX_RES_STATUS_DECRYPT_OK) {
- IWL_DEBUG_RX("hw decrypt successfully!!!\n");
- stats->flag |= RX_FLAG_DECRYPTED;
- }
- break;
-
- default:
- break;
- }
-}
-
#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
#include "iwl-spectrum.h"
@@ -2863,13 +1232,13 @@ static __le32 iwl3945_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
return cpu_to_le32(res);
}
-static int iwl3945_get_measurement(struct iwl3945_priv *priv,
+static int iwl3945_get_measurement(struct iwl_priv *priv,
struct ieee80211_measurement_params *params,
u8 type)
{
- struct iwl3945_spectrum_cmd spectrum;
- struct iwl3945_rx_packet *res;
- struct iwl3945_host_cmd cmd = {
+ struct iwl_spectrum_cmd spectrum;
+ struct iwl_rx_packet *res;
+ struct iwl_host_cmd cmd = {
.id = REPLY_SPECTRUM_MEASUREMENT_CMD,
.data = (void *)&spectrum,
.meta.flags = CMD_WANT_SKB,
@@ -2879,7 +1248,7 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
int spectrum_resp_status;
int duration = le16_to_cpu(params->duration);
- if (iwl3945_is_associated(priv))
+ if (iwl_is_associated(priv))
add_time =
iwl3945_usecs_to_beacons(
le64_to_cpu(params->start_time) - priv->last_tsf,
@@ -2894,7 +1263,7 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
cmd.len = sizeof(spectrum);
spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
- if (iwl3945_is_associated(priv))
+ if (iwl_is_associated(priv))
spectrum.start_time =
iwl3945_add_beacon_time(priv->last_beacon_time,
add_time,
@@ -2909,13 +1278,13 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
spectrum.flags |= RXON_FLG_BAND_24G_MSK |
RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
- rc = iwl3945_send_cmd_sync(priv, &cmd);
+ rc = iwl_send_cmd_sync(priv, &cmd);
if (rc)
return rc;
- res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
+ IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
rc = -EIO;
}
@@ -2923,7 +1292,7 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
switch (spectrum_resp_status) {
case 0: /* Command will be handled */
if (res->u.spectrum.id != 0xff) {
- IWL_DEBUG_INFO("Replaced existing measurement: %d\n",
+ IWL_DEBUG_INFO(priv, "Replaced existing measurement: %d\n",
res->u.spectrum.id);
priv->measurement_status &= ~MEASUREMENT_READY;
}
@@ -2942,30 +1311,29 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
}
#endif
-static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_alive(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_alive_resp *palive;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_alive_resp *palive;
struct delayed_work *pwork;
palive = &pkt->u.alive_frame;
- IWL_DEBUG_INFO("Alive ucode status 0x%08X revision "
+ IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
"0x%01X 0x%01X\n",
palive->is_valid, palive->ver_type,
palive->ver_subtype);
if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
- IWL_DEBUG_INFO("Initialization Alive received.\n");
- memcpy(&priv->card_alive_init,
- &pkt->u.alive_frame,
- sizeof(struct iwl3945_init_alive_resp));
+ IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
+ memcpy(&priv->card_alive_init, &pkt->u.alive_frame,
+ sizeof(struct iwl_alive_resp));
pwork = &priv->init_alive_start;
} else {
- IWL_DEBUG_INFO("Runtime Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
memcpy(&priv->card_alive, &pkt->u.alive_frame,
- sizeof(struct iwl3945_alive_resp));
+ sizeof(struct iwl_alive_resp));
pwork = &priv->alive_start;
iwl3945_disable_events(priv);
}
@@ -2976,95 +1344,31 @@ static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
queue_delayed_work(priv->workqueue, pwork,
msecs_to_jiffies(5));
else
- IWL_WARNING("uCode did not respond OK.\n");
-}
-
-static void iwl3945_rx_reply_add_sta(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-
- IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
- return;
-}
-
-static void iwl3945_rx_reply_error(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
-
- IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) "
- "seq 0x%04X ser 0x%08X\n",
- le32_to_cpu(pkt->u.err_resp.error_type),
- get_cmd_string(pkt->u.err_resp.cmd_id),
- pkt->u.err_resp.cmd_id,
- le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
- le32_to_cpu(pkt->u.err_resp.error_info));
-}
-
-#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
-
-static void iwl3945_rx_csa(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_rxon_cmd *rxon = (void *)&priv->active_rxon;
- struct iwl3945_csa_notification *csa = &(pkt->u.csa_notif);
- IWL_DEBUG_11H("CSA notif: channel %d, status %d\n",
- le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
- rxon->channel = csa->channel;
- priv->staging_rxon.channel = csa->channel;
-}
-
-static void iwl3945_rx_spectrum_measure_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
-#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_spectrum_notification *report = &(pkt->u.spectrum_notif);
-
- if (!report->state) {
- IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO,
- "Spectrum Measure Notification: Start\n");
- return;
- }
-
- memcpy(&priv->measure_report, report, sizeof(*report));
- priv->measurement_status |= MEASUREMENT_READY;
-#endif
+ IWL_WARN(priv, "uCode did not respond OK.\n");
}
-static void iwl3945_rx_pm_sleep_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_add_sta(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWL3945_DEBUG
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_sleep_notification *sleep = &(pkt->u.sleep_notif);
- IWL_DEBUG_RX("sleep mode: %d, src: %d\n",
- sleep->pm_sleep_mode, sleep->pm_wakeup_src);
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
#endif
-}
-static void iwl3945_rx_pm_debug_statistics_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- IWL_DEBUG_RADIO("Dumping %d bytes of unhandled "
- "notification for %s:\n",
- le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
- iwl3945_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+ IWL_DEBUG_RX(priv, "Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
+ return;
}
static void iwl3945_bg_beacon_update(struct work_struct *work)
{
- struct iwl3945_priv *priv =
- container_of(work, struct iwl3945_priv, beacon_update);
+ struct iwl_priv *priv =
+ container_of(work, struct iwl_priv, beacon_update);
struct sk_buff *beacon;
/* Pull updated AP beacon from mac80211. will fail if not in AP mode */
beacon = ieee80211_beacon_get(priv->hw, priv->vif);
if (!beacon) {
- IWL_ERROR("update beacon failed\n");
+ IWL_ERR(priv, "update beacon failed\n");
return;
}
@@ -3079,15 +1383,15 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
iwl3945_send_beacon_cmd(priv);
}
-static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_beacon_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWL3945_DEBUG
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status);
u8 rate = beacon->beacon_notify_hdr.rate;
- IWL_DEBUG_RX("beacon status %x retries %d iss %d "
+ IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
"tsf %d %d rate %d\n",
le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK,
beacon->beacon_notify_hdr.failure_frame,
@@ -3101,137 +1405,20 @@ static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv,
queue_work(priv->workqueue, &priv->beacon_update);
}
-/* Service response to REPLY_SCAN_CMD (0x80) */
-static void iwl3945_rx_reply_scan(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
-#ifdef CONFIG_IWL3945_DEBUG
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_scanreq_notification *notif =
- (struct iwl3945_scanreq_notification *)pkt->u.raw;
-
- IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
-#endif
-}
-
-/* Service SCAN_START_NOTIFICATION (0x82) */
-static void iwl3945_rx_scan_start_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_scanstart_notification *notif =
- (struct iwl3945_scanstart_notification *)pkt->u.raw;
- priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
- IWL_DEBUG_SCAN("Scan start: "
- "%d [802.11%s] "
- "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n",
- notif->channel,
- notif->band ? "bg" : "a",
- notif->tsf_high,
- notif->tsf_low, notif->status, notif->beacon_timer);
-}
-
-/* Service SCAN_RESULTS_NOTIFICATION (0x83) */
-static void iwl3945_rx_scan_results_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_scanresults_notification *notif =
- (struct iwl3945_scanresults_notification *)pkt->u.raw;
-
- IWL_DEBUG_SCAN("Scan ch.res: "
- "%d [802.11%s] "
- "(TSF: 0x%08X:%08X) - %d "
- "elapsed=%lu usec (%dms since last)\n",
- notif->channel,
- notif->band ? "bg" : "a",
- le32_to_cpu(notif->tsf_high),
- le32_to_cpu(notif->tsf_low),
- le32_to_cpu(notif->statistics[0]),
- le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf,
- jiffies_to_msecs(elapsed_jiffies
- (priv->last_scan_jiffies, jiffies)));
-
- priv->last_scan_jiffies = jiffies;
- priv->next_scan_jiffies = 0;
-}
-
-/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
-static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
- struct iwl3945_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
-
- IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
- scan_notif->scanned_channels,
- scan_notif->tsf_low,
- scan_notif->tsf_high, scan_notif->status);
-
- /* The HW is no longer scanning */
- clear_bit(STATUS_SCAN_HW, &priv->status);
-
- /* The scan completion notification came in, so kill that timer... */
- cancel_delayed_work(&priv->scan_check);
-
- IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
- (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
- "2.4" : "5.2",
- jiffies_to_msecs(elapsed_jiffies
- (priv->scan_pass_start, jiffies)));
-
- /* Remove this scanned band from the list of pending
- * bands to scan, band G precedes A in order of scanning
- * as seen in iwl3945_bg_request_scan */
- if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
- priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
- else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ))
- priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
-
- /* If a request to abort was given, or the scan did not succeed
- * then we reset the scan state machine and terminate,
- * re-queuing another scan if one has been requested */
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_INFO("Aborted scan completed.\n");
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- } else {
- /* If there are more bands on this scan pass reschedule */
- if (priv->scan_bands > 0)
- goto reschedule;
- }
-
- priv->last_scan_jiffies = jiffies;
- priv->next_scan_jiffies = 0;
- IWL_DEBUG_INFO("Setting scan to off\n");
-
- clear_bit(STATUS_SCANNING, &priv->status);
-
- IWL_DEBUG_INFO("Scan took %dms\n",
- jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
-
- queue_work(priv->workqueue, &priv->scan_completed);
-
- return;
-
-reschedule:
- priv->scan_pass_start = jiffies;
- queue_work(priv->workqueue, &priv->request_scan);
-}
-
/* Handle notification from uCode that card's power state is changing
* due to software, hardware, or critical temperature RFKILL */
-static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
+static void iwl3945_rx_card_state_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
unsigned long status = priv->status;
- IWL_DEBUG_RF_KILL("Card state received: HW:%s SW:%s\n",
+ IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n",
(flags & HW_CARD_DISABLED) ? "Kill" : "On",
(flags & SW_CARD_DISABLED) ? "Kill" : "On");
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET,
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
if (flags & HW_CARD_DISABLED)
@@ -3245,7 +1432,7 @@ static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv,
else
clear_bit(STATUS_RF_KILL_SW, &priv->status);
- iwl3945_scan_cancel(priv);
+ iwl_scan_cancel(priv);
if ((test_bit(STATUS_RF_KILL_HW, &status) !=
test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
@@ -3265,17 +1452,15 @@ static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv,
* This function chains into the hardware specific files for them to setup
* any hardware specific handlers as well.
*/
-static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv)
+static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
{
priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive;
priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
- priv->rx_handlers[REPLY_ERROR] = iwl3945_rx_reply_error;
- priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl3945_rx_csa;
- priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
- iwl3945_rx_spectrum_measure_notif;
- priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl3945_rx_pm_sleep_notif;
+ priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
+ priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
+ priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
- iwl3945_rx_pm_debug_statistics_notif;
+ iwl_rx_pm_debug_statistics_notif;
priv->rx_handlers[BEACON_NOTIFICATION] = iwl3945_rx_beacon_notif;
/*
@@ -3286,90 +1471,14 @@ static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv)
priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics;
priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
- priv->rx_handlers[REPLY_SCAN_CMD] = iwl3945_rx_reply_scan;
- priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl3945_rx_scan_start_notif;
- priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] =
- iwl3945_rx_scan_results_notif;
- priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
- iwl3945_rx_scan_complete_notif;
+ iwl_setup_spectrum_handlers(priv);
+ iwl_setup_rx_scan_handlers(priv);
priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
/* Set up hardware specific Rx handlers */
iwl3945_hw_rx_handler_setup(priv);
}
-/**
- * iwl3945_cmd_queue_reclaim - Reclaim CMD queue entries
- * When FW advances 'R' index, all entries between old and new 'R' index
- * need to be reclaimed.
- */
-static void iwl3945_cmd_queue_reclaim(struct iwl3945_priv *priv,
- int txq_id, int index)
-{
- struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
- struct iwl3945_queue *q = &txq->q;
- int nfreed = 0;
-
- if ((index >= q->n_bd) || (iwl3945_x2_queue_used(q, index) == 0)) {
- IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
- "is out of range [0-%d] %d %d.\n", txq_id,
- index, q->n_bd, q->write_ptr, q->read_ptr);
- return;
- }
-
- for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
- if (nfreed > 1) {
- IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
- q->write_ptr, q->read_ptr);
- queue_work(priv->workqueue, &priv->restart);
- break;
- }
- nfreed++;
- }
-}
-
-
-/**
- * iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
- * @rxb: Rx buffer to reclaim
- *
- * If an Rx buffer has an async callback associated with it the callback
- * will be executed. The attached skb (if present) will only be freed
- * if the callback returns 1
- */
-static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
- struct iwl3945_rx_mem_buffer *rxb)
-{
- struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
- u16 sequence = le16_to_cpu(pkt->hdr.sequence);
- int txq_id = SEQ_TO_QUEUE(sequence);
- int index = SEQ_TO_INDEX(sequence);
- int huge = sequence & SEQ_HUGE_FRAME;
- int cmd_index;
- struct iwl3945_cmd *cmd;
-
- BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
-
- cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
- cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
-
- /* Input error checking is done when commands are added to queue. */
- if (cmd->meta.flags & CMD_WANT_SKB) {
- cmd->meta.source->u.skb = rxb->skb;
- rxb->skb = NULL;
- } else if (cmd->meta.u.callback &&
- !cmd->meta.u.callback(priv, cmd, rxb->skb))
- rxb->skb = NULL;
-
- iwl3945_cmd_queue_reclaim(priv, txq_id, index);
-
- if (!(cmd->meta.flags & CMD_ASYNC)) {
- clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
- wake_up_interruptible(&priv->wait_command_queue);
- }
-}
-
/************************** RX-FUNCTIONS ****************************/
/*
* Rx theory of operation
@@ -3417,7 +1526,6 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
*
* Driver sequence:
*
- * iwl3945_rx_queue_alloc() Allocates rx_free
* iwl3945_rx_replenish() Replenishes rx_free list from rx_used, and calls
* iwl3945_rx_queue_restock
* iwl3945_rx_queue_restock() Moves available buffers from rx_free into Rx
@@ -3426,7 +1534,7 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
* are available, schedules iwl3945_rx_replenish
*
* -- enable interrupts --
- * ISR - iwl3945_rx() Detach iwl3945_rx_mem_buffers from pool up to the
+ * ISR - iwl3945_rx() Detach iwl_rx_mem_buffers from pool up to the
* READ INDEX, detaching the SKB from the pool.
* Moves the packet buffer from queue to rx_used.
* Calls iwl3945_rx_queue_restock to refill any empty
@@ -3436,70 +1544,9 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
*/
/**
- * iwl3945_rx_queue_space - Return number of free slots available in queue.
- */
-static int iwl3945_rx_queue_space(const struct iwl3945_rx_queue *q)
-{
- int s = q->read - q->write;
- if (s <= 0)
- s += RX_QUEUE_SIZE;
- /* keep some buffer to not confuse full and empty queue */
- s -= 2;
- if (s < 0)
- s = 0;
- return s;
-}
-
-/**
- * iwl3945_rx_queue_update_write_ptr - Update the write pointer for the RX queue
- */
-int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, struct iwl3945_rx_queue *q)
-{
- u32 reg = 0;
- int rc = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&q->lock, flags);
-
- if (q->need_update == 0)
- goto exit_unlock;
-
- /* If power-saving is in use, make sure device is awake */
- if (test_bit(STATUS_POWER_PMI, &priv->status)) {
- reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
-
- if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- iwl3945_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- goto exit_unlock;
- }
-
- rc = iwl3945_grab_nic_access(priv);
- if (rc)
- goto exit_unlock;
-
- /* Device expects a multiple of 8 */
- iwl3945_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
- q->write & ~0x7);
- iwl3945_release_nic_access(priv);
-
- /* Else device is assumed to be awake */
- } else
- /* Device expects a multiple of 8 */
- iwl3945_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
-
-
- q->need_update = 0;
-
- exit_unlock:
- spin_unlock_irqrestore(&q->lock, flags);
- return rc;
-}
-
-/**
* iwl3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
*/
-static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl3945_priv *priv,
+static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl_priv *priv,
dma_addr_t dma_addr)
{
return cpu_to_le32((u32)dma_addr);
@@ -3516,24 +1563,24 @@ static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl3945_priv *priv,
* also updates the memory address in the firmware to reference the new
* target buffer.
*/
-static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)
+static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
{
- struct iwl3945_rx_queue *rxq = &priv->rxq;
+ struct iwl_rx_queue *rxq = &priv->rxq;
struct list_head *element;
- struct iwl3945_rx_mem_buffer *rxb;
+ struct iwl_rx_mem_buffer *rxb;
unsigned long flags;
int write, rc;
spin_lock_irqsave(&rxq->lock, flags);
write = rxq->write & ~0x7;
- while ((iwl3945_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
+ while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
/* Get next free Rx buffer, remove from free list */
element = rxq->rx_free.next;
- rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list);
+ rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
list_del(element);
/* Point to Rx buffer via next RBD in circular buffer */
- rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->dma_addr);
+ rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->real_dma_addr);
rxq->queue[rxq->write] = rxb;
rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
rxq->free_count--;
@@ -3552,7 +1599,7 @@ static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)
spin_lock_irqsave(&rxq->lock, flags);
rxq->need_update = 1;
spin_unlock_irqrestore(&rxq->lock, flags);
- rc = iwl3945_rx_queue_update_write_ptr(priv, rxq);
+ rc = iwl_rx_queue_update_write_ptr(priv, rxq);
if (rc)
return rc;
}
@@ -3568,24 +1615,24 @@ static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)
* Also restock the Rx queue via iwl3945_rx_queue_restock.
* This is called as a scheduled work item (except for during initialization)
*/
-static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
+static void iwl3945_rx_allocate(struct iwl_priv *priv)
{
- struct iwl3945_rx_queue *rxq = &priv->rxq;
+ struct iwl_rx_queue *rxq = &priv->rxq;
struct list_head *element;
- struct iwl3945_rx_mem_buffer *rxb;
+ struct iwl_rx_mem_buffer *rxb;
unsigned long flags;
spin_lock_irqsave(&rxq->lock, flags);
while (!list_empty(&rxq->rx_used)) {
element = rxq->rx_used.next;
- rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list);
+ rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
/* Alloc a new receive buffer */
rxb->skb =
- alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC);
+ alloc_skb(priv->hw_params.rx_buf_size,
+ __GFP_NOWARN | GFP_ATOMIC);
if (!rxb->skb) {
if (net_ratelimit())
- printk(KERN_CRIT DRV_NAME
- ": Can not allocate SKB buffers\n");
+ IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
/* We don't reschedule replenish work here -- we will
* call the restock method and if it still needs
* more buffers it will schedule replenish */
@@ -3604,9 +1651,10 @@ static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
list_del(element);
/* Get physical address of RB/SKB */
- rxb->dma_addr =
- pci_map_single(priv->pci_dev, rxb->skb->data,
- IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ rxb->real_dma_addr = pci_map_single(priv->pci_dev,
+ rxb->skb->data,
+ priv->hw_params.rx_buf_size,
+ PCI_DMA_FROMDEVICE);
list_add_tail(&rxb->list, &rxq->rx_free);
rxq->free_count++;
}
@@ -3618,7 +1666,7 @@ static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
*/
static void __iwl3945_rx_replenish(void *data)
{
- struct iwl3945_priv *priv = data;
+ struct iwl_priv *priv = data;
iwl3945_rx_allocate(priv);
iwl3945_rx_queue_restock(priv);
@@ -3627,7 +1675,7 @@ static void __iwl3945_rx_replenish(void *data)
void iwl3945_rx_replenish(void *data)
{
- struct iwl3945_priv *priv = data;
+ struct iwl_priv *priv = data;
unsigned long flags;
iwl3945_rx_allocate(priv);
@@ -3637,84 +1685,6 @@ void iwl3945_rx_replenish(void *data)
spin_unlock_irqrestore(&priv->lock, flags);
}
-/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
- * If an SKB has been detached, the POOL needs to have its SKB set to NULL
- * This free routine walks the list of POOL entries and if SKB is set to
- * non NULL it is unmapped and freed
- */
-static void iwl3945_rx_queue_free(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
-{
- int i;
- for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
- if (rxq->pool[i].skb != NULL) {
- pci_unmap_single(priv->pci_dev,
- rxq->pool[i].dma_addr,
- IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
- dev_kfree_skb(rxq->pool[i].skb);
- }
- }
-
- pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
- rxq->dma_addr);
- rxq->bd = NULL;
-}
-
-int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv)
-{
- struct iwl3945_rx_queue *rxq = &priv->rxq;
- struct pci_dev *dev = priv->pci_dev;
- int i;
-
- spin_lock_init(&rxq->lock);
- INIT_LIST_HEAD(&rxq->rx_free);
- INIT_LIST_HEAD(&rxq->rx_used);
-
- /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
- rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
- if (!rxq->bd)
- return -ENOMEM;
-
- /* Fill the rx_used queue with _all_ of the Rx buffers */
- for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
- list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
-
- /* Set us so that we have processed and used all buffers, but have
- * not restocked the Rx queue with fresh buffers */
- rxq->read = rxq->write = 0;
- rxq->free_count = 0;
- rxq->need_update = 0;
- return 0;
-}
-
-void iwl3945_rx_queue_reset(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
-{
- unsigned long flags;
- int i;
- spin_lock_irqsave(&rxq->lock, flags);
- INIT_LIST_HEAD(&rxq->rx_free);
- INIT_LIST_HEAD(&rxq->rx_used);
- /* Fill the rx_used queue with _all_ of the Rx buffers */
- for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
- /* In the reset function, these buffers may have been allocated
- * to an SKB, so we need to unmap and free potential storage */
- if (rxq->pool[i].skb != NULL) {
- pci_unmap_single(priv->pci_dev,
- rxq->pool[i].dma_addr,
- IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
- priv->alloc_rxb_skb--;
- dev_kfree_skb(rxq->pool[i].skb);
- rxq->pool[i].skb = NULL;
- }
- list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
- }
-
- /* Set us so that we have processed and used all buffers, but have
- * not restocked the Rx queue with fresh buffers */
- rxq->read = rxq->write = 0;
- rxq->free_count = 0;
- spin_unlock_irqrestore(&rxq->lock, flags);
-}
-
/* Convert linear signal-to-noise ratio into dB */
static u8 ratio2dB[100] = {
/* 0 1 2 3 4 5 6 7 8 9 */
@@ -3800,11 +1770,11 @@ int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm)
* the appropriate handlers, including command responses,
* frame-received notifications, and other notifications.
*/
-static void iwl3945_rx_handle(struct iwl3945_priv *priv)
+static void iwl3945_rx_handle(struct iwl_priv *priv)
{
- struct iwl3945_rx_mem_buffer *rxb;
- struct iwl3945_rx_packet *pkt;
- struct iwl3945_rx_queue *rxq = &priv->rxq;
+ struct iwl_rx_mem_buffer *rxb;
+ struct iwl_rx_packet *pkt;
+ struct iwl_rx_queue *rxq = &priv->rxq;
u32 r, i;
int reclaim;
unsigned long flags;
@@ -3813,14 +1783,14 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
/* uCode's read index (stored in shared DRAM) indicates the last Rx
* buffer that the driver may process (last buffer filled by ucode). */
- r = iwl3945_hw_get_rx_read(priv);
+ r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
i = rxq->read;
- if (iwl3945_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+ if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
fill_rx = 1;
/* Rx interrupt, but nothing sent from uCode */
if (i == r)
- IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
+ IWL_DEBUG(priv, IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
while (i != r) {
rxb = rxq->queue[i];
@@ -3832,10 +1802,10 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
rxq->queue[i] = NULL;
- pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
- IWL_RX_BUF_SIZE,
+ pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->real_dma_addr,
+ priv->hw_params.rx_buf_size,
PCI_DMA_FROMDEVICE);
- pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
+ pkt = (struct iwl_rx_packet *)rxb->skb->data;
/* Reclaim a command buffer only if this packet is a response
* to a (driver-originated) command.
@@ -3851,13 +1821,13 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
* handle those that need handling via function in
* rx_handlers table. See iwl3945_setup_rx_handlers() */
if (priv->rx_handlers[pkt->hdr.cmd]) {
- IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
+ IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
"r = %d, i = %d, %s, 0x%02x\n", r, i,
get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
} else {
/* No handling needed */
- IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
+ IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
"r %d i %d No handler needed for %s, 0x%02x\n",
r, i, get_cmd_string(pkt->hdr.cmd),
pkt->hdr.cmd);
@@ -3865,12 +1835,12 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
if (reclaim) {
/* Invoke any callbacks, transfer the skb to caller, and
- * fire off the (possibly) blocking iwl3945_send_cmd()
+ * fire off the (possibly) blocking iwl_send_cmd()
* as we reclaim the driver command queue */
if (rxb && rxb->skb)
- iwl3945_tx_cmd_complete(priv, rxb);
+ iwl_tx_cmd_complete(priv, rxb);
else
- IWL_WARNING("Claim null rxb?\n");
+ IWL_WARN(priv, "Claim null rxb?\n");
}
/* For now we just don't re-use anything. We can tweak this
@@ -3882,8 +1852,9 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
rxb->skb = NULL;
}
- pci_unmap_single(priv->pci_dev, rxb->dma_addr,
- IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+ pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
+ priv->hw_params.rx_buf_size,
+ PCI_DMA_FROMDEVICE);
spin_lock_irqsave(&rxq->lock, flags);
list_add_tail(&rxb->list, &priv->rxq.rx_used);
spin_unlock_irqrestore(&rxq->lock, flags);
@@ -3905,102 +1876,14 @@ static void iwl3945_rx_handle(struct iwl3945_priv *priv)
iwl3945_rx_queue_restock(priv);
}
-/**
- * iwl3945_tx_queue_update_write_ptr - Send new write index to hardware
- */
-static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
- struct iwl3945_tx_queue *txq)
-{
- u32 reg = 0;
- int rc = 0;
- int txq_id = txq->q.id;
-
- if (txq->need_update == 0)
- return rc;
-
- /* if we're trying to save power */
- if (test_bit(STATUS_POWER_PMI, &priv->status)) {
- /* wake up nic if it's powered down ...
- * uCode will wake up, and interrupt us again, so next
- * time we'll skip this part. */
- reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
-
- if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg);
- iwl3945_set_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- return rc;
- }
-
- /* restore this queue's parameters in nic hardware. */
- rc = iwl3945_grab_nic_access(priv);
- if (rc)
- return rc;
- iwl3945_write_direct32(priv, HBUS_TARG_WRPTR,
- txq->q.write_ptr | (txq_id << 8));
- iwl3945_release_nic_access(priv);
-
- /* else not in power-save mode, uCode will never sleep when we're
- * trying to tx (during RFKILL, we're not trying to tx). */
- } else
- iwl3945_write32(priv, HBUS_TARG_WRPTR,
- txq->q.write_ptr | (txq_id << 8));
-
- txq->need_update = 0;
-
- return rc;
-}
-
-#ifdef CONFIG_IWL3945_DEBUG
-static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon)
-{
- IWL_DEBUG_RADIO("RX CONFIG:\n");
- iwl3945_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
- IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
- IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
- IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n",
- le32_to_cpu(rxon->filter_flags));
- IWL_DEBUG_RADIO("u8 dev_type: 0x%x\n", rxon->dev_type);
- IWL_DEBUG_RADIO("u8 ofdm_basic_rates: 0x%02x\n",
- rxon->ofdm_basic_rates);
- IWL_DEBUG_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
- IWL_DEBUG_RADIO("u8[6] node_addr: %pM\n", rxon->node_addr);
- IWL_DEBUG_RADIO("u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
- IWL_DEBUG_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
-}
-#endif
-
-static void iwl3945_enable_interrupts(struct iwl3945_priv *priv)
-{
- IWL_DEBUG_ISR("Enabling interrupts\n");
- set_bit(STATUS_INT_ENABLED, &priv->status);
- iwl3945_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
-}
-
-
/* call this function to flush any scheduled tasklet */
-static inline void iwl_synchronize_irq(struct iwl3945_priv *priv)
+static inline void iwl_synchronize_irq(struct iwl_priv *priv)
{
/* wait to make sure we flush pending tasklet*/
synchronize_irq(priv->pci_dev->irq);
tasklet_kill(&priv->irq_tasklet);
}
-
-static inline void iwl3945_disable_interrupts(struct iwl3945_priv *priv)
-{
- clear_bit(STATUS_INT_ENABLED, &priv->status);
-
- /* disable interrupts from uCode/NIC to host */
- iwl3945_write32(priv, CSR_INT_MASK, 0x00000000);
-
- /* acknowledge/clear/reset any interrupts still pending
- * from uCode or flow handler (Rx/Tx DMA) */
- iwl3945_write32(priv, CSR_INT, 0xffffffff);
- iwl3945_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
- IWL_DEBUG_ISR("Disabled interrupts\n");
-}
-
static const char *desc_lookup(int i)
{
switch (i) {
@@ -4024,7 +1907,7 @@ static const char *desc_lookup(int i)
#define ERROR_START_OFFSET (1 * sizeof(u32))
#define ERROR_ELEM_SIZE (7 * sizeof(u32))
-static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
+static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
{
u32 i;
u32 desc, time, count, base, data1;
@@ -4034,49 +1917,50 @@ static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
if (!iwl3945_hw_valid_rtc_data_addr(base)) {
- IWL_ERROR("Not valid error log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
return;
}
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
- count = iwl3945_read_targ_mem(priv, base);
+ count = iwl_read_targ_mem(priv, base);
if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
- IWL_ERROR("Start IWL Error Log Dump:\n");
- IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
+ IWL_ERR(priv, "Start IWL Error Log Dump:\n");
+ IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
+ priv->status, count);
}
- IWL_ERROR("Desc Time asrtPC blink2 "
+ IWL_ERR(priv, "Desc Time asrtPC blink2 "
"ilink1 nmiPC Line\n");
for (i = ERROR_START_OFFSET;
i < (count * ERROR_ELEM_SIZE) + ERROR_START_OFFSET;
i += ERROR_ELEM_SIZE) {
- desc = iwl3945_read_targ_mem(priv, base + i);
+ desc = iwl_read_targ_mem(priv, base + i);
time =
- iwl3945_read_targ_mem(priv, base + i + 1 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 1 * sizeof(u32));
blink1 =
- iwl3945_read_targ_mem(priv, base + i + 2 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 2 * sizeof(u32));
blink2 =
- iwl3945_read_targ_mem(priv, base + i + 3 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 3 * sizeof(u32));
ilink1 =
- iwl3945_read_targ_mem(priv, base + i + 4 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 4 * sizeof(u32));
ilink2 =
- iwl3945_read_targ_mem(priv, base + i + 5 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 5 * sizeof(u32));
data1 =
- iwl3945_read_targ_mem(priv, base + i + 6 * sizeof(u32));
+ iwl_read_targ_mem(priv, base + i + 6 * sizeof(u32));
- IWL_ERROR
- ("%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n",
- desc_lookup(desc), desc, time, blink1, blink2,
- ilink1, ilink2, data1);
+ IWL_ERR(priv,
+ "%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n",
+ desc_lookup(desc), desc, time, blink1, blink2,
+ ilink1, ilink2, data1);
}
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
}
@@ -4085,9 +1969,9 @@ static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
/**
* iwl3945_print_event_log - Dump error event log to syslog
*
- * NOTE: Must be called with iwl3945_grab_nic_access() already obtained!
+ * NOTE: Must be called with iwl_grab_nic_access() already obtained!
*/
-static void iwl3945_print_event_log(struct iwl3945_priv *priv, u32 start_idx,
+static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
u32 num_events, u32 mode)
{
u32 i;
@@ -4111,21 +1995,22 @@ static void iwl3945_print_event_log(struct iwl3945_priv *priv, u32 start_idx,
/* "time" is actually "data" for mode 0 (no timestamp).
* place event id # at far right for easier visual parsing. */
for (i = 0; i < num_events; i++) {
- ev = iwl3945_read_targ_mem(priv, ptr);
+ ev = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- time = iwl3945_read_targ_mem(priv, ptr);
+ time = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- if (mode == 0)
- IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */
- else {
- data = iwl3945_read_targ_mem(priv, ptr);
+ if (mode == 0) {
+ /* data, ev */
+ IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
+ } else {
+ data = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev);
+ IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev);
}
}
}
-static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv)
+static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
{
int rc;
u32 base; /* SRAM byte address of event log header */
@@ -4137,32 +2022,32 @@ static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv)
base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
if (!iwl3945_hw_valid_rtc_data_addr(base)) {
- IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
+ IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
return;
}
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
- IWL_WARNING("Can not read from adapter at this time.\n");
+ IWL_WARN(priv, "Can not read from adapter at this time.\n");
return;
}
/* event log header */
- capacity = iwl3945_read_targ_mem(priv, base);
- mode = iwl3945_read_targ_mem(priv, base + (1 * sizeof(u32)));
- num_wraps = iwl3945_read_targ_mem(priv, base + (2 * sizeof(u32)));
- next_entry = iwl3945_read_targ_mem(priv, base + (3 * sizeof(u32)));
+ capacity = iwl_read_targ_mem(priv, base);
+ mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
+ num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
+ next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
size = num_wraps ? capacity : next_entry;
/* bail out if nothing in log */
if (size == 0) {
- IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
- iwl3945_release_nic_access(priv);
+ IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
+ iwl_release_nic_access(priv);
return;
}
- IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
+ IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
size, num_wraps);
/* if uCode has wrapped back to top of log, start at the oldest entry,
@@ -4174,48 +2059,10 @@ static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv)
/* (then/else) start at top of log */
iwl3945_print_event_log(priv, 0, next_entry, mode);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
}
-/**
- * iwl3945_irq_handle_error - called for HW or SW error interrupt from card
- */
-static void iwl3945_irq_handle_error(struct iwl3945_priv *priv)
-{
- /* Set the FW error flag -- cleared on iwl3945_down */
- set_bit(STATUS_FW_ERROR, &priv->status);
-
- /* Cancel currently queued command. */
- clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & IWL_DL_FW_ERRORS) {
- iwl3945_dump_nic_error_log(priv);
- iwl3945_dump_nic_event_log(priv);
- iwl3945_print_rx_config_cmd(&priv->staging_rxon);
- }
-#endif
-
- wake_up_interruptible(&priv->wait_command_queue);
-
- /* Keep the restart process from trying to send host
- * commands by clearing the INIT status bit */
- clear_bit(STATUS_READY, &priv->status);
-
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_FW_ERRORS,
- "Restarting adapter due to uCode error.\n");
-
- if (iwl3945_is_associated(priv)) {
- memcpy(&priv->recovery_rxon, &priv->active_rxon,
- sizeof(priv->recovery_rxon));
- priv->error_recovering = 1;
- }
- queue_work(priv->workqueue, &priv->restart);
- }
-}
-
-static void iwl3945_error_recovery(struct iwl3945_priv *priv)
+static void iwl3945_error_recovery(struct iwl_priv *priv)
{
unsigned long flags;
@@ -4232,12 +2079,12 @@ static void iwl3945_error_recovery(struct iwl3945_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
}
-static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
+static void iwl3945_irq_tasklet(struct iwl_priv *priv)
{
u32 inta, handled = 0;
u32 inta_fh;
unsigned long flags;
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
u32 inta_mask;
#endif
@@ -4246,20 +2093,20 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
/* Ack/clear/reset pending uCode interrupts.
* Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
* and will clear only when CSR_FH_INT_STATUS gets cleared. */
- inta = iwl3945_read32(priv, CSR_INT);
- iwl3945_write32(priv, CSR_INT, inta);
+ inta = iwl_read32(priv, CSR_INT);
+ iwl_write32(priv, CSR_INT, inta);
/* Ack/clear/reset pending flow-handler (DMA) interrupts.
* Any new interrupts that happen after this, either while we're
* in this tasklet, or later, will show up in next ISR/tasklet. */
- inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
- iwl3945_write32(priv, CSR_FH_INT_STATUS, inta_fh);
+ inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+ iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & IWL_DL_ISR) {
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & IWL_DL_ISR) {
/* just for debug */
- inta_mask = iwl3945_read32(priv, CSR_INT_MASK);
- IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
+ inta_mask = iwl_read32(priv, CSR_INT_MASK);
+ IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
inta, inta_mask, inta_fh);
}
#endif
@@ -4275,12 +2122,12 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
/* Now service all interrupt bits discovered above. */
if (inta & CSR_INT_BIT_HW_ERR) {
- IWL_ERROR("Microcode HW error detected. Restarting.\n");
+ IWL_ERR(priv, "Microcode HW error detected. Restarting.\n");
/* Tell the device to stop sending interrupts */
- iwl3945_disable_interrupts(priv);
+ iwl_disable_interrupts(priv);
- iwl3945_irq_handle_error(priv);
+ iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_HW_ERR;
@@ -4289,16 +2136,16 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
return;
}
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & (IWL_DL_ISR)) {
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
if (inta & CSR_INT_BIT_SCD)
- IWL_DEBUG_ISR("Scheduler finished to transmit "
+ IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
"the frame/frames.\n");
/* Alive notification via Rx interrupt will do the real work */
if (inta & CSR_INT_BIT_ALIVE)
- IWL_DEBUG_ISR("Alive interrupt\n");
+ IWL_DEBUG_ISR(priv, "Alive interrupt\n");
}
#endif
/* Safely ignore these bits for debug checks below */
@@ -4306,22 +2153,22 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
/* Error detected by uCode */
if (inta & CSR_INT_BIT_SW_ERR) {
- IWL_ERROR("Microcode SW error detected. Restarting 0x%X.\n",
- inta);
- iwl3945_irq_handle_error(priv);
+ IWL_ERR(priv, "Microcode SW error detected. "
+ "Restarting 0x%X.\n", inta);
+ iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
/* uCode wakes up after power-down sleep */
if (inta & CSR_INT_BIT_WAKEUP) {
- IWL_DEBUG_ISR("Wakeup interrupt\n");
- iwl3945_rx_queue_update_write_ptr(priv, &priv->rxq);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[0]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[1]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[2]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[3]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[4]);
- iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[5]);
+ IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
+ iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
+ iwl_txq_update_write_ptr(priv, &priv->txq[0]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[1]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[2]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[3]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[4]);
+ iwl_txq_update_write_ptr(priv, &priv->txq[5]);
handled |= CSR_INT_BIT_WAKEUP;
}
@@ -4335,432 +2182,63 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
}
if (inta & CSR_INT_BIT_FH_TX) {
- IWL_DEBUG_ISR("Tx interrupt\n");
-
- iwl3945_write32(priv, CSR_FH_INT_STATUS, (1 << 6));
- if (!iwl3945_grab_nic_access(priv)) {
- iwl3945_write_direct32(priv,
- FH_TCSR_CREDIT
- (ALM_FH_SRVC_CHNL), 0x0);
- iwl3945_release_nic_access(priv);
+ IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+
+ iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6));
+ if (!iwl_grab_nic_access(priv)) {
+ iwl_write_direct32(priv, FH39_TCSR_CREDIT
+ (FH39_SRVC_CHNL), 0x0);
+ iwl_release_nic_access(priv);
}
handled |= CSR_INT_BIT_FH_TX;
}
if (inta & ~handled)
- IWL_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
+ IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
if (inta & ~CSR_INI_SET_MASK) {
- IWL_WARNING("Disabled INTA bits 0x%08x were pending\n",
+ IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
inta & ~CSR_INI_SET_MASK);
- IWL_WARNING(" with FH_INT = 0x%08x\n", inta_fh);
+ IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh);
}
/* Re-enable all interrupts */
/* only Re-enable if disabled by irq */
if (test_bit(STATUS_INT_ENABLED, &priv->status))
- iwl3945_enable_interrupts(priv);
-
-#ifdef CONFIG_IWL3945_DEBUG
- if (iwl3945_debug_level & (IWL_DL_ISR)) {
- inta = iwl3945_read32(priv, CSR_INT);
- inta_mask = iwl3945_read32(priv, CSR_INT_MASK);
- inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
- IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
+ iwl_enable_interrupts(priv);
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ if (priv->debug_level & (IWL_DL_ISR)) {
+ inta = iwl_read32(priv, CSR_INT);
+ inta_mask = iwl_read32(priv, CSR_INT_MASK);
+ inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+ IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
"flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
}
#endif
spin_unlock_irqrestore(&priv->lock, flags);
}
-static irqreturn_t iwl3945_isr(int irq, void *data)
-{
- struct iwl3945_priv *priv = data;
- u32 inta, inta_mask;
- u32 inta_fh;
- if (!priv)
- return IRQ_NONE;
-
- spin_lock(&priv->lock);
-
- /* Disable (but don't clear!) interrupts here to avoid
- * back-to-back ISRs and sporadic interrupts from our NIC.
- * If we have something to service, the tasklet will re-enable ints.
- * If we *don't* have something, we'll re-enable before leaving here. */
- inta_mask = iwl3945_read32(priv, CSR_INT_MASK); /* just for debug */
- iwl3945_write32(priv, CSR_INT_MASK, 0x00000000);
-
- /* Discover which interrupts are active/pending */
- inta = iwl3945_read32(priv, CSR_INT);
- inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
-
- /* Ignore interrupt if there's nothing in NIC to service.
- * This may be due to IRQ shared with another device,
- * or due to sporadic interrupts thrown from our NIC. */
- if (!inta && !inta_fh) {
- IWL_DEBUG_ISR("Ignore interrupt, inta == 0, inta_fh == 0\n");
- goto none;
- }
-
- if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
- /* Hardware disappeared */
- IWL_WARNING("HARDWARE GONE?? INTA == 0x%08x\n", inta);
- goto unplugged;
- }
-
- IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
- inta, inta_mask, inta_fh);
-
- inta &= ~CSR_INT_BIT_SCD;
-
- /* iwl3945_irq_tasklet() will service interrupts and re-enable them */
- if (likely(inta || inta_fh))
- tasklet_schedule(&priv->irq_tasklet);
-unplugged:
- spin_unlock(&priv->lock);
-
- return IRQ_HANDLED;
-
- none:
- /* re-enable interrupts here since we don't have anything to service. */
- /* only Re-enable if disabled by irq */
- if (test_bit(STATUS_INT_ENABLED, &priv->status))
- iwl3945_enable_interrupts(priv);
- spin_unlock(&priv->lock);
- return IRQ_NONE;
-}
-
-/************************** EEPROM BANDS ****************************
- *
- * The iwl3945_eeprom_band definitions below provide the mapping from the
- * EEPROM contents to the specific channel number supported for each
- * band.
- *
- * For example, iwl3945_priv->eeprom.band_3_channels[4] from the band_3
- * definition below maps to physical channel 42 in the 5.2GHz spectrum.
- * The specific geography and calibration information for that channel
- * is contained in the eeprom map itself.
- *
- * During init, we copy the eeprom information and channel map
- * information into priv->channel_info_24/52 and priv->channel_map_24/52
- *
- * channel_map_24/52 provides the index in the channel_info array for a
- * given channel. We have to have two separate maps as there is channel
- * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and
- * band_2
- *
- * A value of 0xff stored in the channel_map indicates that the channel
- * is not supported by the hardware at all.
- *
- * A value of 0xfe in the channel_map indicates that the channel is not
- * valid for Tx with the current hardware. This means that
- * while the system can tune and receive on a given channel, it may not
- * be able to associate or transmit any frames on that
- * channel. There is no corresponding channel information for that
- * entry.
- *
- *********************************************************************/
-
-/* 2.4 GHz */
-static const u8 iwl3945_eeprom_band_1[14] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
-};
-
-/* 5.2 GHz bands */
-static const u8 iwl3945_eeprom_band_2[] = { /* 4915-5080MHz */
- 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16
-};
-
-static const u8 iwl3945_eeprom_band_3[] = { /* 5170-5320MHz */
- 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
-};
-
-static const u8 iwl3945_eeprom_band_4[] = { /* 5500-5700MHz */
- 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
-};
-
-static const u8 iwl3945_eeprom_band_5[] = { /* 5725-5825MHz */
- 145, 149, 153, 157, 161, 165
-};
-
-static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int band,
- int *eeprom_ch_count,
- const struct iwl3945_eeprom_channel
- **eeprom_ch_info,
- const u8 **eeprom_ch_index)
-{
- switch (band) {
- case 1: /* 2.4GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_1);
- *eeprom_ch_info = priv->eeprom.band_1_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_1;
- break;
- case 2: /* 4.9GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_2);
- *eeprom_ch_info = priv->eeprom.band_2_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_2;
- break;
- case 3: /* 5.2GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_3);
- *eeprom_ch_info = priv->eeprom.band_3_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_3;
- break;
- case 4: /* 5.5GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_4);
- *eeprom_ch_info = priv->eeprom.band_4_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_4;
- break;
- case 5: /* 5.7GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_5);
- *eeprom_ch_info = priv->eeprom.band_5_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_5;
- break;
- default:
- BUG();
- return;
- }
-}
-
-/**
- * iwl3945_get_channel_info - Find driver's private channel info
- *
- * Based on band and channel number.
- */
-const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv,
- enum ieee80211_band band, u16 channel)
-{
- int i;
-
- switch (band) {
- case IEEE80211_BAND_5GHZ:
- for (i = 14; i < priv->channel_count; i++) {
- if (priv->channel_info[i].channel == channel)
- return &priv->channel_info[i];
- }
- break;
-
- case IEEE80211_BAND_2GHZ:
- if (channel >= 1 && channel <= 14)
- return &priv->channel_info[channel - 1];
- break;
- case IEEE80211_NUM_BANDS:
- WARN_ON(1);
- }
-
- return NULL;
-}
-
-#define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
- ? # x " " : "")
-
-/**
- * iwl3945_init_channel_map - Set up driver's info for all possible channels
- */
-static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
-{
- int eeprom_ch_count = 0;
- const u8 *eeprom_ch_index = NULL;
- const struct iwl3945_eeprom_channel *eeprom_ch_info = NULL;
- int band, ch;
- struct iwl3945_channel_info *ch_info;
-
- if (priv->channel_count) {
- IWL_DEBUG_INFO("Channel map already initialized.\n");
- return 0;
- }
-
- if (priv->eeprom.version < 0x2f) {
- IWL_WARNING("Unsupported EEPROM version: 0x%04X\n",
- priv->eeprom.version);
- return -EINVAL;
- }
-
- IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n");
-
- priv->channel_count =
- ARRAY_SIZE(iwl3945_eeprom_band_1) +
- ARRAY_SIZE(iwl3945_eeprom_band_2) +
- ARRAY_SIZE(iwl3945_eeprom_band_3) +
- ARRAY_SIZE(iwl3945_eeprom_band_4) +
- ARRAY_SIZE(iwl3945_eeprom_band_5);
-
- IWL_DEBUG_INFO("Parsing data for %d channels.\n", priv->channel_count);
-
- priv->channel_info = kzalloc(sizeof(struct iwl3945_channel_info) *
- priv->channel_count, GFP_KERNEL);
- if (!priv->channel_info) {
- IWL_ERROR("Could not allocate channel_info\n");
- priv->channel_count = 0;
- return -ENOMEM;
- }
-
- ch_info = priv->channel_info;
-
- /* Loop through the 5 EEPROM bands adding them in order to the
- * channel map we maintain (that contains additional information than
- * what just in the EEPROM) */
- for (band = 1; band <= 5; band++) {
-
- iwl3945_init_band_reference(priv, band, &eeprom_ch_count,
- &eeprom_ch_info, &eeprom_ch_index);
-
- /* Loop through each band adding each of the channels */
- for (ch = 0; ch < eeprom_ch_count; ch++) {
- ch_info->channel = eeprom_ch_index[ch];
- ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ :
- IEEE80211_BAND_5GHZ;
-
- /* permanently store EEPROM's channel regulatory flags
- * and max power in channel info database. */
- ch_info->eeprom = eeprom_ch_info[ch];
-
- /* Copy the run-time flags so they are there even on
- * invalid channels */
- ch_info->flags = eeprom_ch_info[ch].flags;
-
- if (!(is_channel_valid(ch_info))) {
- IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - "
- "No traffic\n",
- ch_info->channel,
- ch_info->flags,
- is_channel_a_band(ch_info) ?
- "5.2" : "2.4");
- ch_info++;
- continue;
- }
-
- /* Initialize regulatory-based run-time data */
- ch_info->max_power_avg = ch_info->curr_txpow =
- eeprom_ch_info[ch].max_power_avg;
- ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
- ch_info->min_power = 0;
-
- IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x"
- " %ddBm): Ad-Hoc %ssupported\n",
- ch_info->channel,
- is_channel_a_band(ch_info) ?
- "5.2" : "2.4",
- CHECK_AND_PRINT(VALID),
- CHECK_AND_PRINT(IBSS),
- CHECK_AND_PRINT(ACTIVE),
- CHECK_AND_PRINT(RADAR),
- CHECK_AND_PRINT(WIDE),
- CHECK_AND_PRINT(DFS),
- eeprom_ch_info[ch].flags,
- eeprom_ch_info[ch].max_power_avg,
- ((eeprom_ch_info[ch].
- flags & EEPROM_CHANNEL_IBSS)
- && !(eeprom_ch_info[ch].
- flags & EEPROM_CHANNEL_RADAR))
- ? "" : "not ");
-
- /* Set the user_txpower_limit to the highest power
- * supported by any channel */
- if (eeprom_ch_info[ch].max_power_avg >
- priv->user_txpower_limit)
- priv->user_txpower_limit =
- eeprom_ch_info[ch].max_power_avg;
-
- ch_info++;
- }
- }
-
- /* Set up txpower settings in driver for all channels */
- if (iwl3945_txpower_set_from_eeprom(priv))
- return -EIO;
-
- return 0;
-}
-
-/*
- * iwl3945_free_channel_map - undo allocations in iwl3945_init_channel_map
- */
-static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
-{
- kfree(priv->channel_info);
- priv->channel_count = 0;
-}
-
-/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
- * sending probe req. This should be set long enough to hear probe responses
- * from more than one AP. */
-#define IWL_ACTIVE_DWELL_TIME_24 (30) /* all times in msec */
-#define IWL_ACTIVE_DWELL_TIME_52 (20)
-
-#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
-#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)
-
-/* For faster active scanning, scan will move to the next channel if fewer than
- * PLCP_QUIET_THRESH packets are heard on this channel within
- * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
- * time if it's a quiet channel (nothing responded to our probe, and there's
- * no other traffic).
- * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
-#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
-#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
-
-/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
- * Must be set longer than active dwell time.
- * For the most reliable scan, set > AP beacon interval (typically 100msec). */
-#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */
-#define IWL_PASSIVE_DWELL_TIME_52 (10)
-#define IWL_PASSIVE_DWELL_BASE (100)
-#define IWL_CHANNEL_TUNE_TIME 5
-
-#define IWL_SCAN_PROBE_MASK(n) (BIT(n) | (BIT(n) - BIT(1)))
-
-static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
- enum ieee80211_band band,
- u8 n_probes)
-{
- if (band == IEEE80211_BAND_5GHZ)
- return IWL_ACTIVE_DWELL_TIME_52 +
- IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1);
- else
- return IWL_ACTIVE_DWELL_TIME_24 +
- IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
-}
-
-static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv,
- enum ieee80211_band band)
-{
- u16 passive = (band == IEEE80211_BAND_2GHZ) ?
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
-
- if (iwl3945_is_associated(priv)) {
- /* If we're associated, we clamp the maximum passive
- * dwell time to be 98% of the beacon interval (minus
- * 2 * channel tune time) */
- passive = priv->beacon_int;
- if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
- passive = IWL_PASSIVE_DWELL_BASE;
- passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
- }
-
- return passive;
-}
-
-static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
+static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
enum ieee80211_band band,
u8 is_active, u8 n_probes,
struct iwl3945_scan_channel *scan_ch)
{
const struct ieee80211_channel *channels = NULL;
const struct ieee80211_supported_band *sband;
- const struct iwl3945_channel_info *ch_info;
+ const struct iwl_channel_info *ch_info;
u16 passive_dwell = 0;
u16 active_dwell = 0;
int added, i;
- sband = iwl3945_get_band(priv, band);
+ sband = iwl_get_hw_mode(priv, band);
if (!sband)
return 0;
channels = sband->channels;
- active_dwell = iwl3945_get_active_dwell_time(priv, band, n_probes);
- passive_dwell = iwl3945_get_passive_dwell_time(priv, band);
+ active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
+ passive_dwell = iwl_get_passive_dwell_time(priv, band);
if (passive_dwell <= active_dwell)
passive_dwell = active_dwell + 1;
@@ -4771,9 +2249,9 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
scan_ch->channel = channels[i].hw_value;
- ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel);
+ ch_info = iwl_get_channel_info(priv, band, scan_ch->channel);
if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
+ IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
scan_ch->channel);
continue;
}
@@ -4798,12 +2276,12 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
* hearing clear Rx packet).*/
if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
if (n_probes)
- scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+ scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes);
} else {
/* uCode v1 does not allow setting direct probe bits on
* passive channel. */
if ((scan_ch->type & 1) && n_probes)
- scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+ scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes);
}
/* Set txpower levels to defaults */
@@ -4821,7 +2299,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
*/
}
- IWL_DEBUG_SCAN("Scanning %d [%s %d]\n",
+ IWL_DEBUG_SCAN(priv, "Scanning %d [%s %d]\n",
scan_ch->channel,
(scan_ch->type & 1) ? "ACTIVE" : "PASSIVE",
(scan_ch->type & 1) ?
@@ -4831,11 +2309,11 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
added++;
}
- IWL_DEBUG_SCAN("total channels to scan %d \n", added);
+ IWL_DEBUG_SCAN(priv, "total channels to scan %d \n", added);
return added;
}
-static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
+static void iwl3945_init_hw_rates(struct iwl_priv *priv,
struct ieee80211_rate *rates)
{
int i;
@@ -4845,7 +2323,7 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
rates[i].hw_value = i; /* Rate scaling will work on indexes */
rates[i].hw_value_short = i;
rates[i].flags = 0;
- if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) {
+ if ((i > IWL39_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) {
/*
* If CCK != 1M then set short preamble rate flag.
*/
@@ -4855,145 +2333,13 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
}
}
-/**
- * iwl3945_init_geos - Initialize mac80211's geo/channel info based from eeprom
- */
-static int iwl3945_init_geos(struct iwl3945_priv *priv)
-{
- struct iwl3945_channel_info *ch;
- struct ieee80211_supported_band *sband;
- struct ieee80211_channel *channels;
- struct ieee80211_channel *geo_ch;
- struct ieee80211_rate *rates;
- int i = 0;
-
- if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
- priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
- IWL_DEBUG_INFO("Geography modes already initialized.\n");
- set_bit(STATUS_GEO_CONFIGURED, &priv->status);
- return 0;
- }
-
- channels = kzalloc(sizeof(struct ieee80211_channel) *
- priv->channel_count, GFP_KERNEL);
- if (!channels)
- return -ENOMEM;
-
- rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
- GFP_KERNEL);
- if (!rates) {
- kfree(channels);
- return -ENOMEM;
- }
-
- /* 5.2GHz channels start after the 2.4GHz channels */
- sband = &priv->bands[IEEE80211_BAND_5GHZ];
- sband->channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)];
- /* just OFDM */
- sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
- sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
-
- sband = &priv->bands[IEEE80211_BAND_2GHZ];
- sband->channels = channels;
- /* OFDM & CCK */
- sband->bitrates = rates;
- sband->n_bitrates = IWL_RATE_COUNT;
-
- priv->ieee_channels = channels;
- priv->ieee_rates = rates;
-
- iwl3945_init_hw_rates(priv, rates);
-
- for (i = 0; i < priv->channel_count; i++) {
- ch = &priv->channel_info[i];
-
- /* FIXME: might be removed if scan is OK*/
- if (!is_channel_valid(ch))
- continue;
-
- if (is_channel_a_band(ch))
- sband = &priv->bands[IEEE80211_BAND_5GHZ];
- else
- sband = &priv->bands[IEEE80211_BAND_2GHZ];
-
- geo_ch = &sband->channels[sband->n_channels++];
-
- geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel);
- geo_ch->max_power = ch->max_power_avg;
- geo_ch->max_antenna_gain = 0xff;
- geo_ch->hw_value = ch->channel;
-
- if (is_channel_valid(ch)) {
- if (!(ch->flags & EEPROM_CHANNEL_IBSS))
- geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
-
- if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
- geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-
- if (ch->flags & EEPROM_CHANNEL_RADAR)
- geo_ch->flags |= IEEE80211_CHAN_RADAR;
-
- if (ch->max_power_avg > priv->max_channel_txpower_limit)
- priv->max_channel_txpower_limit =
- ch->max_power_avg;
- } else {
- geo_ch->flags |= IEEE80211_CHAN_DISABLED;
- }
-
- /* Save flags for reg domain usage */
- geo_ch->orig_flags = geo_ch->flags;
-
- IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n",
- ch->channel, geo_ch->center_freq,
- is_channel_a_band(ch) ? "5.2" : "2.4",
- geo_ch->flags & IEEE80211_CHAN_DISABLED ?
- "restricted" : "valid",
- geo_ch->flags);
- }
-
- if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
- priv->cfg->sku & IWL_SKU_A) {
- printk(KERN_INFO DRV_NAME
- ": Incorrectly detected BG card as ABG. Please send "
- "your PCI ID 0x%04X:0x%04X to maintainer.\n",
- priv->pci_dev->device, priv->pci_dev->subsystem_device);
- priv->cfg->sku &= ~IWL_SKU_A;
- }
-
- printk(KERN_INFO DRV_NAME
- ": Tunable channels: %d 802.11bg, %d 802.11a channels\n",
- priv->bands[IEEE80211_BAND_2GHZ].n_channels,
- priv->bands[IEEE80211_BAND_5GHZ].n_channels);
-
- if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
- priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
- &priv->bands[IEEE80211_BAND_2GHZ];
- if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
- priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
- &priv->bands[IEEE80211_BAND_5GHZ];
-
- set_bit(STATUS_GEO_CONFIGURED, &priv->status);
-
- return 0;
-}
-
-/*
- * iwl3945_free_geos - undo allocations in iwl3945_init_geos
- */
-static void iwl3945_free_geos(struct iwl3945_priv *priv)
-{
- kfree(priv->ieee_channels);
- kfree(priv->ieee_rates);
- clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
-}
-
/******************************************************************************
*
* uCode download functions
*
******************************************************************************/
-static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv)
+static void iwl3945_dealloc_ucode_pci(struct iwl_priv *priv)
{
iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code);
iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data);
@@ -5007,29 +2353,30 @@ static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv)
* iwl3945_verify_inst_full - verify runtime uCode image in card vs. host,
* looking at all data.
*/
-static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u32 len)
+static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 len)
{
u32 val;
u32 save_len = len;
int rc = 0;
u32 errcnt;
- IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+ IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc)
return rc;
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
+ iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+ IWL39_RTC_INST_LOWER_BOUND);
errcnt = 0;
for (; len > 0; len -= sizeof(u32), image++) {
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
- val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
- IWL_ERROR("uCode INST section is invalid at "
+ IWL_ERR(priv, "uCode INST section is invalid at "
"offset 0x%x, is 0x%x, s/b 0x%x\n",
save_len - len, val, le32_to_cpu(*image));
rc = -EIO;
@@ -5039,10 +2386,11 @@ static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u3
}
}
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
if (!errcnt)
- IWL_DEBUG_INFO("ucode image in INSTRUCTION memory is good\n");
+ IWL_DEBUG_INFO(priv,
+ "ucode image in INSTRUCTION memory is good\n");
return rc;
}
@@ -5053,16 +2401,16 @@ static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u3
* using sample data 100 bytes apart. If these sample points are good,
* it's a pretty good bet that everything between them is good, too.
*/
-static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image, u32 len)
+static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
{
u32 val;
int rc = 0;
u32 errcnt = 0;
u32 i;
- IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
+ IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc)
return rc;
@@ -5070,12 +2418,12 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image,
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
* if IWL_DL_IO is set */
- iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR,
- i + RTC_INST_LOWER_BOUND);
- val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
+ i + IWL39_RTC_INST_LOWER_BOUND);
+ val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (val != le32_to_cpu(*image)) {
#if 0 /* Enable this if you want to see details */
- IWL_ERROR("uCode INST section is invalid at "
+ IWL_ERR(priv, "uCode INST section is invalid at "
"offset 0x%x, is 0x%x, s/b 0x%x\n",
i, val, *image);
#endif
@@ -5086,7 +2434,7 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image,
}
}
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
return rc;
}
@@ -5096,7 +2444,7 @@ static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image,
* iwl3945_verify_ucode - determine which instruction image is in SRAM,
* and verify its contents
*/
-static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
+static int iwl3945_verify_ucode(struct iwl_priv *priv)
{
__le32 *image;
u32 len;
@@ -5107,7 +2455,7 @@ static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
len = priv->ucode_boot.len;
rc = iwl3945_verify_inst_sparse(priv, image, len);
if (rc == 0) {
- IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n");
+ IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
return 0;
}
@@ -5116,7 +2464,7 @@ static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
len = priv->ucode_init.len;
rc = iwl3945_verify_inst_sparse(priv, image, len);
if (rc == 0) {
- IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n");
+ IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
return 0;
}
@@ -5125,11 +2473,11 @@ static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
len = priv->ucode_code.len;
rc = iwl3945_verify_inst_sparse(priv, image, len);
if (rc == 0) {
- IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n");
+ IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
return 0;
}
- IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
+ IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
/* Since nothing seems to match, show first several data entries in
* instruction SRAM, so maybe visual inspection will give a clue.
@@ -5141,160 +2489,10 @@ static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
return rc;
}
-
-/* check contents of special bootstrap uCode SRAM */
-static int iwl3945_verify_bsm(struct iwl3945_priv *priv)
-{
- __le32 *image = priv->ucode_boot.v_addr;
- u32 len = priv->ucode_boot.len;
- u32 reg;
- u32 val;
-
- IWL_DEBUG_INFO("Begin verify bsm\n");
-
- /* verify BSM SRAM contents */
- val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG);
- for (reg = BSM_SRAM_LOWER_BOUND;
- reg < BSM_SRAM_LOWER_BOUND + len;
- reg += sizeof(u32), image++) {
- val = iwl3945_read_prph(priv, reg);
- if (val != le32_to_cpu(*image)) {
- IWL_ERROR("BSM uCode verification failed at "
- "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
- BSM_SRAM_LOWER_BOUND,
- reg - BSM_SRAM_LOWER_BOUND, len,
- val, le32_to_cpu(*image));
- return -EIO;
- }
- }
-
- IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n");
-
- return 0;
-}
-
-/**
- * iwl3945_load_bsm - Load bootstrap instructions
- *
- * BSM operation:
- *
- * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
- * in special SRAM that does not power down during RFKILL. When powering back
- * up after power-saving sleeps (or during initial uCode load), the BSM loads
- * the bootstrap program into the on-board processor, and starts it.
- *
- * The bootstrap program loads (via DMA) instructions and data for a new
- * program from host DRAM locations indicated by the host driver in the
- * BSM_DRAM_* registers. Once the new program is loaded, it starts
- * automatically.
- *
- * When initializing the NIC, the host driver points the BSM to the
- * "initialize" uCode image. This uCode sets up some internal data, then
- * notifies host via "initialize alive" that it is complete.
- *
- * The host then replaces the BSM_DRAM_* pointer values to point to the
- * normal runtime uCode instructions and a backup uCode data cache buffer
- * (filled initially with starting data values for the on-board processor),
- * then triggers the "initialize" uCode to load and launch the runtime uCode,
- * which begins normal operation.
- *
- * When doing a power-save shutdown, runtime uCode saves data SRAM into
- * the backup data cache in DRAM before SRAM is powered down.
- *
- * When powering back up, the BSM loads the bootstrap program. This reloads
- * the runtime uCode instructions and the backup data cache into SRAM,
- * and re-launches the runtime uCode from where it left off.
- */
-static int iwl3945_load_bsm(struct iwl3945_priv *priv)
-{
- __le32 *image = priv->ucode_boot.v_addr;
- u32 len = priv->ucode_boot.len;
- dma_addr_t pinst;
- dma_addr_t pdata;
- u32 inst_len;
- u32 data_len;
- int rc;
- int i;
- u32 done;
- u32 reg_offset;
-
- IWL_DEBUG_INFO("Begin load bsm\n");
-
- /* make sure bootstrap program is no larger than BSM's SRAM size */
- if (len > IWL_MAX_BSM_SIZE)
- return -EINVAL;
-
- /* Tell bootstrap uCode where to find the "Initialize" uCode
- * in host DRAM ... host DRAM physical address bits 31:0 for 3945.
- * NOTE: iwl3945_initialize_alive_start() will replace these values,
- * after the "initialize" uCode has run, to point to
- * runtime/protocol instructions and backup data cache. */
- pinst = priv->ucode_init.p_addr;
- pdata = priv->ucode_init_data.p_addr;
- inst_len = priv->ucode_init.len;
- data_len = priv->ucode_init_data.len;
-
- rc = iwl3945_grab_nic_access(priv);
- if (rc)
- return rc;
-
- iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
- iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
- iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
- iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
-
- /* Fill BSM memory with bootstrap instructions */
- for (reg_offset = BSM_SRAM_LOWER_BOUND;
- reg_offset < BSM_SRAM_LOWER_BOUND + len;
- reg_offset += sizeof(u32), image++)
- _iwl3945_write_prph(priv, reg_offset,
- le32_to_cpu(*image));
-
- rc = iwl3945_verify_bsm(priv);
- if (rc) {
- iwl3945_release_nic_access(priv);
- return rc;
- }
-
- /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
- iwl3945_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
- iwl3945_write_prph(priv, BSM_WR_MEM_DST_REG,
- RTC_INST_LOWER_BOUND);
- iwl3945_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
-
- /* Load bootstrap code into instruction SRAM now,
- * to prepare to load "initialize" uCode */
- iwl3945_write_prph(priv, BSM_WR_CTRL_REG,
- BSM_WR_CTRL_REG_BIT_START);
-
- /* Wait for load of bootstrap uCode to finish */
- for (i = 0; i < 100; i++) {
- done = iwl3945_read_prph(priv, BSM_WR_CTRL_REG);
- if (!(done & BSM_WR_CTRL_REG_BIT_START))
- break;
- udelay(10);
- }
- if (i < 100)
- IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i);
- else {
- IWL_ERROR("BSM write did not complete!\n");
- return -EIO;
- }
-
- /* Enable future boot loads whenever power management unit triggers it
- * (e.g. when powering back up after power-save shutdown) */
- iwl3945_write_prph(priv, BSM_WR_CTRL_REG,
- BSM_WR_CTRL_REG_BIT_START_EN);
-
- iwl3945_release_nic_access(priv);
-
- return 0;
-}
-
-static void iwl3945_nic_start(struct iwl3945_priv *priv)
+static void iwl3945_nic_start(struct iwl_priv *priv)
{
/* Remove all resets to allow NIC to operate */
- iwl3945_write32(priv, CSR_RESET, 0);
+ iwl_write32(priv, CSR_RESET, 0);
}
/**
@@ -5302,9 +2500,9 @@ static void iwl3945_nic_start(struct iwl3945_priv *priv)
*
* Copy into buffers for card to fetch via bus-mastering
*/
-static int iwl3945_read_ucode(struct iwl3945_priv *priv)
+static int iwl3945_read_ucode(struct iwl_priv *priv)
{
- struct iwl3945_ucode *ucode;
+ struct iwl_ucode *ucode;
int ret = -EINVAL, index;
const struct firmware *ucode_raw;
/* firmware file name contains uCode/driver compatibility version */
@@ -5322,7 +2520,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
sprintf(buf, "%s%u%s", name_pre, index, ".ucode");
ret = request_firmware(&ucode_raw, buf, &priv->pci_dev->dev);
if (ret < 0) {
- IWL_ERROR("%s firmware file req failed: Reason %d\n",
+ IWL_ERR(priv, "%s firmware file req failed: %d\n",
buf, ret);
if (ret == -ENOENT)
continue;
@@ -5330,9 +2528,12 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
goto error;
} else {
if (index < api_max)
- IWL_ERROR("Loaded firmware %s, which is deprecated. Please use API v%u instead.\n",
+ IWL_ERR(priv, "Loaded firmware %s, "
+ "which is deprecated. "
+ " Please use API v%u instead.\n",
buf, api_max);
- IWL_DEBUG_INFO("Got firmware '%s' file (%zd bytes) from disk\n",
+ IWL_DEBUG_INFO(priv, "Got firmware '%s' file "
+ "(%zd bytes) from disk\n",
buf, ucode_raw->size);
break;
}
@@ -5343,7 +2544,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
/* Make sure that we got at least our header! */
if (ucode_raw->size < sizeof(*ucode)) {
- IWL_ERROR("File size way too small!\n");
+ IWL_ERR(priv, "File size way too small!\n");
ret = -EINVAL;
goto err_release;
}
@@ -5361,10 +2562,10 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
/* api_ver should match the api version forming part of the
* firmware filename ... but we don't check for that and only rely
- * on the API version read from firware header from here on forward */
+ * on the API version read from firmware header from here on forward */
if (api_ver < api_min || api_ver > api_max) {
- IWL_ERROR("Driver unable to support your firmware API. "
+ IWL_ERR(priv, "Driver unable to support your firmware API. "
"Driver supports v%u, firmware is v%u.\n",
api_max, api_ver);
priv->ucode_ver = 0;
@@ -5372,23 +2573,29 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
goto err_release;
}
if (api_ver != api_max)
- IWL_ERROR("Firmware has old API version. Expected %u, "
+ IWL_ERR(priv, "Firmware has old API version. Expected %u, "
"got %u. New firmware can be obtained "
"from http://www.intellinuxwireless.org.\n",
api_max, api_ver);
- printk(KERN_INFO DRV_NAME " loaded firmware version %u.%u.%u.%u\n",
- IWL_UCODE_MAJOR(priv->ucode_ver),
- IWL_UCODE_MINOR(priv->ucode_ver),
- IWL_UCODE_API(priv->ucode_ver),
- IWL_UCODE_SERIAL(priv->ucode_ver));
- IWL_DEBUG_INFO("f/w package hdr ucode version raw = 0x%x\n",
+ IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n",
+ IWL_UCODE_MAJOR(priv->ucode_ver),
+ IWL_UCODE_MINOR(priv->ucode_ver),
+ IWL_UCODE_API(priv->ucode_ver),
+ IWL_UCODE_SERIAL(priv->ucode_ver));
+
+ IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
priv->ucode_ver);
- IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", inst_size);
- IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", data_size);
- IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n", init_size);
- IWL_DEBUG_INFO("f/w package hdr init data size = %u\n", init_data_size);
- IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n", boot_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
+ inst_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n",
+ data_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n",
+ init_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n",
+ init_data_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
+ boot_size);
/* Verify size of file vs. image size info in file's header */
@@ -5396,40 +2603,43 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
inst_size + data_size + init_size +
init_data_size + boot_size) {
- IWL_DEBUG_INFO("uCode file size %d too small\n",
- (int)ucode_raw->size);
+ IWL_DEBUG_INFO(priv, "uCode file size %zd too small\n",
+ ucode_raw->size);
ret = -EINVAL;
goto err_release;
}
/* Verify that uCode images will fit in card's SRAM */
- if (inst_size > IWL_MAX_INST_SIZE) {
- IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n",
+ if (inst_size > IWL39_MAX_INST_SIZE) {
+ IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
inst_size);
ret = -EINVAL;
goto err_release;
}
- if (data_size > IWL_MAX_DATA_SIZE) {
- IWL_DEBUG_INFO("uCode data len %d too large to fit in\n",
+ if (data_size > IWL39_MAX_DATA_SIZE) {
+ IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
data_size);
ret = -EINVAL;
goto err_release;
}
- if (init_size > IWL_MAX_INST_SIZE) {
- IWL_DEBUG_INFO("uCode init instr len %d too large to fit in\n",
+ if (init_size > IWL39_MAX_INST_SIZE) {
+ IWL_DEBUG_INFO(priv,
+ "uCode init instr len %d too large to fit in\n",
init_size);
ret = -EINVAL;
goto err_release;
}
- if (init_data_size > IWL_MAX_DATA_SIZE) {
- IWL_DEBUG_INFO("uCode init data len %d too large to fit in\n",
+ if (init_data_size > IWL39_MAX_DATA_SIZE) {
+ IWL_DEBUG_INFO(priv,
+ "uCode init data len %d too large to fit in\n",
init_data_size);
ret = -EINVAL;
goto err_release;
}
- if (boot_size > IWL_MAX_BSM_SIZE) {
- IWL_DEBUG_INFO("uCode boot instr len %d too large to fit in\n",
+ if (boot_size > IWL39_MAX_BSM_SIZE) {
+ IWL_DEBUG_INFO(priv,
+ "uCode boot instr len %d too large to fit in\n",
boot_size);
ret = -EINVAL;
goto err_release;
@@ -5479,16 +2689,18 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
/* Runtime instructions (first block of data in file) */
src = &ucode->data[0];
len = priv->ucode_code.len;
- IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %Zd\n", len);
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) uCode instr len %zd\n", len);
memcpy(priv->ucode_code.v_addr, src, len);
- IWL_DEBUG_INFO("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
+ IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
/* Runtime data (2nd block)
* NOTE: Copy into backup buffer will be done in iwl3945_up() */
src = &ucode->data[inst_size];
len = priv->ucode_data.len;
- IWL_DEBUG_INFO("Copying (but not loading) uCode data len %Zd\n", len);
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) uCode data len %zd\n", len);
memcpy(priv->ucode_data.v_addr, src, len);
memcpy(priv->ucode_data_backup.v_addr, src, len);
@@ -5496,8 +2708,8 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
if (init_size) {
src = &ucode->data[inst_size + data_size];
len = priv->ucode_init.len;
- IWL_DEBUG_INFO("Copying (but not loading) init instr len %Zd\n",
- len);
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) init instr len %zd\n", len);
memcpy(priv->ucode_init.v_addr, src, len);
}
@@ -5505,16 +2717,16 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
if (init_data_size) {
src = &ucode->data[inst_size + data_size + init_size];
len = priv->ucode_init_data.len;
- IWL_DEBUG_INFO("Copying (but not loading) init data len %d\n",
- (int)len);
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) init data len %zd\n", len);
memcpy(priv->ucode_init_data.v_addr, src, len);
}
/* Bootstrap instructions (5th block) */
src = &ucode->data[inst_size + data_size + init_size + init_data_size];
len = priv->ucode_boot.len;
- IWL_DEBUG_INFO("Copying (but not loading) boot instr len %d\n",
- (int)len);
+ IWL_DEBUG_INFO(priv,
+ "Copying (but not loading) boot instr len %zd\n", len);
memcpy(priv->ucode_boot.v_addr, src, len);
/* We have our copies now, allow OS release its copies */
@@ -5522,7 +2734,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
return 0;
err_pci_alloc:
- IWL_ERROR("failed to allocate pci memory\n");
+ IWL_ERR(priv, "failed to allocate pci memory\n");
ret = -ENOMEM;
iwl3945_dealloc_ucode_pci(priv);
@@ -5543,7 +2755,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv)
* We need to replace them to load runtime uCode inst and data,
* and to save runtime data when powering down.
*/
-static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv)
+static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv)
{
dma_addr_t pinst;
dma_addr_t pdata;
@@ -5555,28 +2767,28 @@ static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv)
pdata = priv->ucode_data_backup.p_addr;
spin_lock_irqsave(&priv->lock, flags);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
/* Tell bootstrap uCode where to find image to load */
- iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
- iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
- iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
+ iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+ iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+ iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
priv->ucode_data.len);
/* Inst byte count must be last to set up, bit 31 signals uCode
* that all new ptr/size info is in place */
- iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
+ iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
priv->ucode_code.len | BSM_DRAM_INST_LOAD);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_INFO("Runtime uCode pointers are set.\n");
+ IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n");
return rc;
}
@@ -5588,13 +2800,13 @@ static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv)
*
* Tell "initialize" uCode to go ahead and load the runtime uCode.
*/
-static void iwl3945_init_alive_start(struct iwl3945_priv *priv)
+static void iwl3945_init_alive_start(struct iwl_priv *priv)
{
/* Check alive response for "valid" sign from uCode */
if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
/* We had an error bringing up the hardware, so take it
* all the way back down so we can try again */
- IWL_DEBUG_INFO("Initialize Alive failed.\n");
+ IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
goto restart;
}
@@ -5604,18 +2816,18 @@ static void iwl3945_init_alive_start(struct iwl3945_priv *priv)
if (iwl3945_verify_ucode(priv)) {
/* Runtime instruction load was bad;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
+ IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
goto restart;
}
/* Send pointers to protocol/runtime uCode image ... init code will
* load and launch runtime uCode, which will send us another "Alive"
* notification. */
- IWL_DEBUG_INFO("Initialization Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
if (iwl3945_set_ucode_ptrs(priv)) {
/* Runtime instruction load won't happen;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n");
+ IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n");
goto restart;
}
return;
@@ -5634,18 +2846,18 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
* from protocol/runtime uCode (initialization uCode's
* Alive gets handled by iwl3945_init_alive_start()).
*/
-static void iwl3945_alive_start(struct iwl3945_priv *priv)
+static void iwl3945_alive_start(struct iwl_priv *priv)
{
int rc = 0;
int thermal_spin = 0;
u32 rfkill;
- IWL_DEBUG_INFO("Runtime Alive received.\n");
+ IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
if (priv->card_alive.is_valid != UCODE_VALID_OK) {
/* We had an error bringing up the hardware, so take it
* all the way back down so we can try again */
- IWL_DEBUG_INFO("Alive failed.\n");
+ IWL_DEBUG_INFO(priv, "Alive failed.\n");
goto restart;
}
@@ -5655,21 +2867,21 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
if (iwl3945_verify_ucode(priv)) {
/* Runtime instruction load was bad;
* take it all the way back down so we can try again */
- IWL_DEBUG_INFO("Bad runtime uCode load.\n");
+ IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n");
goto restart;
}
iwl3945_clear_stations_table(priv);
- rc = iwl3945_grab_nic_access(priv);
+ rc = iwl_grab_nic_access(priv);
if (rc) {
- IWL_WARNING("Can not read RFKILL status from adapter\n");
+ IWL_WARN(priv, "Can not read RFKILL status from adapter\n");
return;
}
- rfkill = iwl3945_read_prph(priv, APMG_RFKILL_REG);
- IWL_DEBUG_INFO("RFKILL status: 0x%x\n", rfkill);
- iwl3945_release_nic_access(priv);
+ rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);
+ IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill);
+ iwl_release_nic_access(priv);
if (rfkill & 0x1) {
clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -5681,7 +2893,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
}
if (thermal_spin)
- IWL_DEBUG_INFO("Thermal calibration took %dus\n",
+ IWL_DEBUG_INFO(priv, "Thermal calibration took %dus\n",
thermal_spin * 10);
} else
set_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -5692,7 +2904,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
/* Clear out the uCode error bit if it is set */
clear_bit(STATUS_FW_ERROR, &priv->status);
- if (iwl3945_is_rfkill(priv))
+ if (iwl_is_rfkill(priv))
return;
ieee80211_wake_queues(priv->hw);
@@ -5700,9 +2912,9 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
priv->active_rate = priv->rates_mask;
priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
- iwl3945_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode));
+ iwl_power_update_mode(priv, false);
- if (iwl3945_is_associated(priv)) {
+ if (iwl_is_associated(priv)) {
struct iwl3945_rxon_cmd *active_rxon =
(struct iwl3945_rxon_cmd *)(&priv->active_rxon);
@@ -5711,12 +2923,11 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
} else {
/* Initialize our rx_config data */
- iwl3945_connection_init_rx_config(priv, priv->iw_mode);
- memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+ iwl_connection_init_rx_config(priv, priv->iw_mode);
}
/* Configure Bluetooth device coexistence support */
- iwl3945_send_bt_config(priv);
+ iwl_send_bt_config(priv);
/* Configure the adapter for unassociated operation */
iwl3945_commit_rxon(priv);
@@ -5725,7 +2936,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
iwl3945_led_register(priv);
- IWL_DEBUG_INFO("ALIVE processing complete.\n");
+ IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
set_bit(STATUS_READY, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
@@ -5746,15 +2957,15 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
queue_work(priv->workqueue, &priv->restart);
}
-static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv);
+static void iwl3945_cancel_deferred_work(struct iwl_priv *priv);
-static void __iwl3945_down(struct iwl3945_priv *priv)
+static void __iwl3945_down(struct iwl_priv *priv)
{
unsigned long flags;
int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
struct ieee80211_conf *conf = NULL;
- IWL_DEBUG_INFO(DRV_NAME " is going down\n");
+ IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
conf = ieee80211_get_hw_conf(priv->hw);
@@ -5773,11 +2984,11 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
clear_bit(STATUS_EXIT_PENDING, &priv->status);
/* stop and reset the on-board processor */
- iwl3945_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+ iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
/* tell the device to stop sending interrupts */
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_disable_interrupts(priv);
+ iwl_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags);
iwl_synchronize_irq(priv);
@@ -5786,7 +2997,7 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
/* If we have not previously called iwl3945_init() then
* clear all bits but the RF Kill and SUSPEND bits and return */
- if (!iwl3945_is_init(priv)) {
+ if (!iwl_is_init(priv)) {
priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
test_bit(STATUS_RF_KILL_SW, &priv->status) <<
@@ -5815,29 +3026,31 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
STATUS_EXIT_PENDING;
+ priv->cfg->ops->lib->apm_ops.reset(priv);
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
spin_unlock_irqrestore(&priv->lock, flags);
iwl3945_hw_txq_ctx_stop(priv);
iwl3945_hw_rxq_stop(priv);
spin_lock_irqsave(&priv->lock, flags);
- if (!iwl3945_grab_nic_access(priv)) {
- iwl3945_write_prph(priv, APMG_CLK_DIS_REG,
+ if (!iwl_grab_nic_access(priv)) {
+ iwl_write_prph(priv, APMG_CLK_DIS_REG,
APMG_CLK_VAL_DMA_CLK_RQT);
- iwl3945_release_nic_access(priv);
+ iwl_release_nic_access(priv);
}
spin_unlock_irqrestore(&priv->lock, flags);
udelay(5);
- iwl3945_hw_nic_stop_master(priv);
- iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
- iwl3945_hw_nic_reset(priv);
+ if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+ priv->cfg->ops->lib->apm_ops.stop(priv);
+ else
+ priv->cfg->ops->lib->apm_ops.reset(priv);
exit:
- memset(&priv->card_alive, 0, sizeof(struct iwl3945_alive_resp));
+ memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
@@ -5847,7 +3060,7 @@ static void __iwl3945_down(struct iwl3945_priv *priv)
iwl3945_clear_free_frames(priv);
}
-static void iwl3945_down(struct iwl3945_priv *priv)
+static void iwl3945_down(struct iwl_priv *priv)
{
mutex_lock(&priv->mutex);
__iwl3945_down(priv);
@@ -5858,58 +3071,58 @@ static void iwl3945_down(struct iwl3945_priv *priv)
#define MAX_HW_RESTARTS 5
-static int __iwl3945_up(struct iwl3945_priv *priv)
+static int __iwl3945_up(struct iwl_priv *priv)
{
int rc, i;
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_WARNING("Exit pending; will not bring the NIC up\n");
+ IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
return -EIO;
}
if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
- IWL_WARNING("Radio disabled by SW RF kill (module "
+ IWL_WARN(priv, "Radio disabled by SW RF kill (module "
"parameter)\n");
return -ENODEV;
}
if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
- IWL_ERROR("ucode not available for device bring up\n");
+ IWL_ERR(priv, "ucode not available for device bring up\n");
return -EIO;
}
/* If platform's RF_KILL switch is NOT set to KILL */
- if (iwl3945_read32(priv, CSR_GP_CNTRL) &
+ if (iwl_read32(priv, CSR_GP_CNTRL) &
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
clear_bit(STATUS_RF_KILL_HW, &priv->status);
else {
set_bit(STATUS_RF_KILL_HW, &priv->status);
if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
- IWL_WARNING("Radio disabled by HW RF Kill switch\n");
+ IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
return -ENODEV;
}
}
- iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
+ iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
rc = iwl3945_hw_nic_init(priv);
if (rc) {
- IWL_ERROR("Unable to int nic\n");
+ IWL_ERR(priv, "Unable to int nic\n");
return rc;
}
/* make sure rfkill handshake bits are cleared */
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
/* clear (again), then enable host interrupts */
- iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
- iwl3945_enable_interrupts(priv);
+ iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+ iwl_enable_interrupts(priv);
/* really make sure rfkill handshake bits are cleared */
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
- iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
/* Copy original ucode data image from disk into backup cache.
* This will be used to initialize the on-board processor's
@@ -5928,17 +3141,18 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
/* load bootstrap state machine,
* load bootstrap program into processor's memory,
* prepare to load the "initialize" uCode */
- rc = iwl3945_load_bsm(priv);
+ priv->cfg->ops->lib->load_ucode(priv);
if (rc) {
- IWL_ERROR("Unable to set up bootstrap uCode: %d\n", rc);
+ IWL_ERR(priv,
+ "Unable to set up bootstrap uCode: %d\n", rc);
continue;
}
/* start card; "initialize" will load runtime ucode */
iwl3945_nic_start(priv);
- IWL_DEBUG_INFO(DRV_NAME " is coming up\n");
+ IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
return 0;
}
@@ -5949,7 +3163,7 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
/* tried to restart and config the device for as long as our
* patience could withstand */
- IWL_ERROR("Unable to initialize device after %d attempts.\n", i);
+ IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
return -EIO;
}
@@ -5962,8 +3176,8 @@ static int __iwl3945_up(struct iwl3945_priv *priv)
static void iwl3945_bg_init_alive_start(struct work_struct *data)
{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, init_alive_start.work);
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, init_alive_start.work);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -5975,8 +3189,8 @@ static void iwl3945_bg_init_alive_start(struct work_struct *data)
static void iwl3945_bg_alive_start(struct work_struct *data)
{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, alive_start.work);
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, alive_start.work);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -5986,66 +3200,31 @@ static void iwl3945_bg_alive_start(struct work_struct *data)
mutex_unlock(&priv->mutex);
}
-static void iwl3945_bg_rf_kill(struct work_struct *work)
+static void iwl3945_rfkill_poll(struct work_struct *data)
{
- struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, rf_kill);
-
- wake_up_interruptible(&priv->wait_command_queue);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, rfkill_poll.work);
+ unsigned long status = priv->status;
- mutex_lock(&priv->mutex);
+ if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
+ clear_bit(STATUS_RF_KILL_HW, &priv->status);
+ else
+ set_bit(STATUS_RF_KILL_HW, &priv->status);
- if (!iwl3945_is_rfkill(priv)) {
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL,
- "HW and/or SW RF Kill no longer active, restarting "
- "device\n");
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
- queue_work(priv->workqueue, &priv->restart);
- } else {
+ if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status))
+ queue_work(priv->workqueue, &priv->rf_kill);
- if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
- IWL_DEBUG_RF_KILL("Can not turn radio back on - "
- "disabled by SW switch\n");
- else
- IWL_WARNING("Radio Frequency Kill Switch is On:\n"
- "Kill switch must be turned off for "
- "wireless networking to work.\n");
- }
+ queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
+ round_jiffies_relative(2 * HZ));
- mutex_unlock(&priv->mutex);
- iwl3945_rfkill_set_hw_state(priv);
}
#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
-
-static void iwl3945_bg_scan_check(struct work_struct *data)
-{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, scan_check.work);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
- if (test_bit(STATUS_SCANNING, &priv->status) ||
- test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN,
- "Scan completion watchdog resetting adapter (%dms)\n",
- jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
-
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
- iwl3945_send_scan_abort(priv);
- }
- mutex_unlock(&priv->mutex);
-}
-
static void iwl3945_bg_request_scan(struct work_struct *data)
{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, request_scan);
- struct iwl3945_host_cmd cmd = {
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, request_scan);
+ struct iwl_host_cmd cmd = {
.id = REPLY_SCAN_CMD,
.len = sizeof(struct iwl3945_scan_cmd),
.meta.flags = CMD_SIZE_HUGE,
@@ -6061,8 +3240,8 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
mutex_lock(&priv->mutex);
- if (!iwl3945_is_ready(priv)) {
- IWL_WARNING("request scan called when driver not ready.\n");
+ if (!iwl_is_ready(priv)) {
+ IWL_WARN(priv, "request scan called when driver not ready.\n");
goto done;
}
@@ -6074,34 +3253,36 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
/* This should never be called or scheduled if there is currently
* a scan active in the hardware. */
if (test_bit(STATUS_SCAN_HW, &priv->status)) {
- IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. "
- "Ignoring second request.\n");
+ IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests "
+ "Ignoring second request.\n");
rc = -EIO;
goto done;
}
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n");
+ IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
goto done;
}
if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n");
+ IWL_DEBUG_HC(priv,
+ "Scan request while abort pending. Queuing.\n");
goto done;
}
- if (iwl3945_is_rfkill(priv)) {
- IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
+ if (iwl_is_rfkill(priv)) {
+ IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
goto done;
}
if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n");
+ IWL_DEBUG_HC(priv,
+ "Scan request while uninitialized. Queuing.\n");
goto done;
}
if (!priv->scan_bands) {
- IWL_DEBUG_HC("Aborting scan due to no requested bands\n");
+ IWL_DEBUG_HC(priv, "Aborting scan due to no requested bands\n");
goto done;
}
@@ -6119,14 +3300,14 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
- if (iwl3945_is_associated(priv)) {
+ if (iwl_is_associated(priv)) {
u16 interval = 0;
u32 extra;
u32 suspend_time = 100;
u32 scan_suspend_time = 100;
unsigned long flags;
- IWL_DEBUG_INFO("Scanning while associated...\n");
+ IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
spin_lock_irqsave(&priv->lock, flags);
interval = priv->beacon_int;
@@ -6148,15 +3329,14 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
(extra | ((suspend_time % interval) * 1024));
scan->suspend_time = cpu_to_le32(scan_suspend_time);
- IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n",
+ IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
scan_suspend_time, interval);
}
/* We should add the ability for user to lock to PASSIVE ONLY */
if (priv->one_direct_scan) {
- IWL_DEBUG_SCAN
- ("Kicking off one direct scan for '%s'\n",
- print_ssid(ssid, priv->direct_ssid,
+ IWL_DEBUG_SCAN(priv, "Kicking off one direct scan for '%s'\n",
+ print_ssid(ssid, priv->direct_ssid,
priv->direct_ssid_len));
scan->direct_scan[0].id = WLAN_EID_SSID;
scan->direct_scan[0].len = priv->direct_ssid_len;
@@ -6164,15 +3344,12 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
priv->direct_ssid, priv->direct_ssid_len);
n_probes++;
} else
- IWL_DEBUG_SCAN("Kicking off one indirect scan.\n");
+ IWL_DEBUG_SCAN(priv, "Kicking off one indirect scan.\n");
/* We don't build a direct scan probe request; the uCode will do
* that based on the direct_mask added to each channel entry */
- scan->tx_cmd.len = cpu_to_le16(
- iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(*scan)));
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
- scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
+ scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
/* flags + rate selection */
@@ -6187,10 +3364,15 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
scan->good_CRC_th = IWL_GOOD_CRC_TH;
band = IEEE80211_BAND_5GHZ;
} else {
- IWL_WARNING("Invalid scan band count\n");
+ IWL_WARN(priv, "Invalid scan band count\n");
goto done;
}
+ scan->tx_cmd.len = cpu_to_le16(
+ iwl_fill_probe_req(priv, band,
+ (struct ieee80211_mgmt *)scan->data,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan)));
+
/* select Rx antennas */
scan->flags |= iwl3945_get_antenna_flags(priv);
@@ -6203,7 +3385,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
if (scan->channel_count == 0) {
- IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count);
+ IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
goto done;
}
@@ -6213,7 +3395,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
scan->len = cpu_to_le16(cmd.len);
set_bit(STATUS_SCAN_HW, &priv->status);
- rc = iwl3945_send_cmd_sync(priv, &cmd);
+ rc = iwl_send_cmd_sync(priv, &cmd);
if (rc)
goto done;
@@ -6239,7 +3421,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
static void iwl3945_bg_up(struct work_struct *data)
{
- struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, up);
+ struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -6247,12 +3429,12 @@ static void iwl3945_bg_up(struct work_struct *data)
mutex_lock(&priv->mutex);
__iwl3945_up(priv);
mutex_unlock(&priv->mutex);
- iwl3945_rfkill_set_hw_state(priv);
+ iwl_rfkill_set_hw_state(priv);
}
static void iwl3945_bg_restart(struct work_struct *data)
{
- struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, restart);
+ struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -6263,8 +3445,8 @@ static void iwl3945_bg_restart(struct work_struct *data)
static void iwl3945_bg_rx_replenish(struct work_struct *data)
{
- struct iwl3945_priv *priv =
- container_of(data, struct iwl3945_priv, rx_replenish);
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, rx_replenish);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -6276,18 +3458,18 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
#define IWL_DELAY_NEXT_SCAN (HZ*2)
-static void iwl3945_post_associate(struct iwl3945_priv *priv)
+static void iwl3945_post_associate(struct iwl_priv *priv)
{
int rc = 0;
struct ieee80211_conf *conf = NULL;
if (priv->iw_mode == NL80211_IFTYPE_AP) {
- IWL_ERROR("%s Should not be called in AP mode\n", __func__);
+ IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
return;
}
- IWL_DEBUG_ASSOC("Associated as %d to: %pM\n",
+ IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
priv->assoc_id, priv->active_rxon.bssid_addr);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -6296,26 +3478,26 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv)
if (!priv->vif || !priv->is_open)
return;
- iwl3945_scan_cancel_timeout(priv, 200);
+ iwl_scan_cancel_timeout(priv, 200);
conf = ieee80211_get_hw_conf(priv->hw);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
- memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd));
+ memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
iwl3945_setup_rxon_timing(priv);
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING,
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (rc)
- IWL_WARNING("REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
- IWL_DEBUG_ASSOC("assoc id %d beacon interval %d\n",
+ IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
priv->assoc_id, priv->beacon_int);
if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
@@ -6355,56 +3537,19 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv)
break;
default:
- IWL_ERROR("%s Should not be called in %d mode\n",
+ IWL_ERR(priv, "%s Should not be called in %d mode\n",
__func__, priv->iw_mode);
break;
}
- iwl3945_activate_qos(priv, 0);
+ iwl_activate_qos(priv, 0);
/* we have just associated, don't start scan too early */
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
}
-static void iwl3945_bg_abort_scan(struct work_struct *work)
-{
- struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, abort_scan);
-
- if (!iwl3945_is_ready(priv))
- return;
-
- mutex_lock(&priv->mutex);
-
- set_bit(STATUS_SCAN_ABORTING, &priv->status);
- iwl3945_send_scan_abort(priv);
-
- mutex_unlock(&priv->mutex);
-}
-
static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);
-static void iwl3945_bg_scan_completed(struct work_struct *work)
-{
- struct iwl3945_priv *priv =
- container_of(work, struct iwl3945_priv, scan_completed);
-
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n");
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (test_bit(STATUS_CONF_PENDING, &priv->status))
- iwl3945_mac_config(priv->hw, 0);
-
- ieee80211_scan_completed(priv->hw);
-
- /* Since setting the TXPOWER may have been deferred while
- * performing the scan, fire one off */
- mutex_lock(&priv->mutex);
- iwl3945_hw_reg_send_txpower(priv);
- mutex_unlock(&priv->mutex);
-}
-
/*****************************************************************************
*
* mac80211 entry point functions
@@ -6415,36 +3560,22 @@ static void iwl3945_bg_scan_completed(struct work_struct *work)
static int iwl3945_mac_start(struct ieee80211_hw *hw)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
int ret;
- IWL_DEBUG_MAC80211("enter\n");
-
- if (pci_enable_device(priv->pci_dev)) {
- IWL_ERROR("Fail to pci_enable_device\n");
- return -ENODEV;
- }
- pci_restore_state(priv->pci_dev);
- pci_enable_msi(priv->pci_dev);
-
- ret = request_irq(priv->pci_dev->irq, iwl3945_isr, IRQF_SHARED,
- DRV_NAME, priv);
- if (ret) {
- IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq);
- goto out_disable_msi;
- }
+ IWL_DEBUG_MAC80211(priv, "enter\n");
/* we should be verifying the device is ready to be opened */
mutex_lock(&priv->mutex);
- memset(&priv->staging_rxon, 0, sizeof(struct iwl3945_rxon_cmd));
+ memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
/* fetch ucode file from disk, alloc and copy to bus-master buffers ...
* ucode filename and max sizes are card-specific. */
if (!priv->ucode_code.len) {
ret = iwl3945_read_ucode(priv);
if (ret) {
- IWL_ERROR("Could not read microcode: %d\n", ret);
+ IWL_ERR(priv, "Could not read microcode: %d\n", ret);
mutex_unlock(&priv->mutex);
goto out_release_irq;
}
@@ -6454,12 +3585,12 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
mutex_unlock(&priv->mutex);
- iwl3945_rfkill_set_hw_state(priv);
+ iwl_rfkill_set_hw_state(priv);
if (ret)
goto out_release_irq;
- IWL_DEBUG_INFO("Start UP work.\n");
+ IWL_DEBUG_INFO(priv, "Start UP work.\n");
if (test_bit(STATUS_IN_SUSPEND, &priv->status))
return 0;
@@ -6471,86 +3602,87 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
UCODE_READY_TIMEOUT);
if (!ret) {
if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_ERROR("Wait for START_ALIVE timeout after %dms.\n",
- jiffies_to_msecs(UCODE_READY_TIMEOUT));
+ IWL_ERR(priv,
+ "Wait for START_ALIVE timeout after %dms.\n",
+ jiffies_to_msecs(UCODE_READY_TIMEOUT));
ret = -ETIMEDOUT;
goto out_release_irq;
}
}
+ /* ucode is running and will send rfkill notifications,
+ * no need to poll the killswitch state anymore */
+ cancel_delayed_work(&priv->rfkill_poll);
+
priv->is_open = 1;
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
out_release_irq:
- free_irq(priv->pci_dev->irq, priv);
-out_disable_msi:
- pci_disable_msi(priv->pci_dev);
- pci_disable_device(priv->pci_dev);
priv->is_open = 0;
- IWL_DEBUG_MAC80211("leave - failed\n");
+ IWL_DEBUG_MAC80211(priv, "leave - failed\n");
return ret;
}
static void iwl3945_mac_stop(struct ieee80211_hw *hw)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
if (!priv->is_open) {
- IWL_DEBUG_MAC80211("leave - skip\n");
+ IWL_DEBUG_MAC80211(priv, "leave - skip\n");
return;
}
priv->is_open = 0;
- if (iwl3945_is_ready_rf(priv)) {
+ if (iwl_is_ready_rf(priv)) {
/* stop mac, cancel any scan request and clear
* RXON_FILTER_ASSOC_MSK BIT
*/
mutex_lock(&priv->mutex);
- iwl3945_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
mutex_unlock(&priv->mutex);
}
iwl3945_down(priv);
flush_workqueue(priv->workqueue);
- free_irq(priv->pci_dev->irq, priv);
- pci_disable_msi(priv->pci_dev);
- pci_save_state(priv->pci_dev);
- pci_disable_device(priv->pci_dev);
- IWL_DEBUG_MAC80211("leave\n");
+ /* start polling the killswitch state again */
+ queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
+ round_jiffies_relative(2 * HZ));
+
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
- IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
+ IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
if (iwl3945_tx_skb(priv, skb))
dev_kfree_skb_any(skb);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return NETDEV_TX_OK;
}
static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
unsigned long flags;
- IWL_DEBUG_MAC80211("enter: type %d\n", conf->type);
+ IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
if (priv->vif) {
- IWL_DEBUG_MAC80211("leave - vif != NULL\n");
+ IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
return -EOPNOTSUPP;
}
@@ -6563,16 +3695,16 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
if (conf->mac_addr) {
- IWL_DEBUG_MAC80211("Set: %pM\n", conf->mac_addr);
+ IWL_DEBUG_MAC80211(priv, "Set: %pM\n", conf->mac_addr);
memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
}
- if (iwl3945_is_ready(priv))
+ if (iwl_is_ready(priv))
iwl3945_set_mode(priv, conf->type);
mutex_unlock(&priv->mutex);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
@@ -6585,24 +3717,25 @@ static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
*/
static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
{
- struct iwl3945_priv *priv = hw->priv;
- const struct iwl3945_channel_info *ch_info;
+ struct iwl_priv *priv = hw->priv;
+ const struct iwl_channel_info *ch_info;
struct ieee80211_conf *conf = &hw->conf;
unsigned long flags;
int ret = 0;
mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);
+ IWL_DEBUG_MAC80211(priv, "enter to channel %d\n",
+ conf->channel->hw_value);
- if (!iwl3945_is_ready(priv)) {
- IWL_DEBUG_MAC80211("leave - not ready\n");
+ if (!iwl_is_ready(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
ret = -EIO;
goto out;
}
- if (unlikely(!iwl3945_param_disable_hw_scan &&
+ if (unlikely(!iwl3945_mod_params.disable_hw_scan &&
test_bit(STATUS_SCANNING, &priv->status))) {
- IWL_DEBUG_MAC80211("leave - scanning\n");
+ IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
set_bit(STATUS_CONF_PENDING, &priv->status);
mutex_unlock(&priv->mutex);
return 0;
@@ -6610,25 +3743,26 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
spin_lock_irqsave(&priv->lock, flags);
- ch_info = iwl3945_get_channel_info(priv, conf->channel->band,
- conf->channel->hw_value);
+ ch_info = iwl_get_channel_info(priv, conf->channel->band,
+ conf->channel->hw_value);
if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n",
- conf->channel->hw_value, conf->channel->band);
- IWL_DEBUG_MAC80211("leave - invalid channel\n");
+ IWL_DEBUG_SCAN(priv,
+ "Channel %d [%d] is INVALID for this band.\n",
+ conf->channel->hw_value, conf->channel->band);
+ IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
spin_unlock_irqrestore(&priv->lock, flags);
ret = -EINVAL;
goto out;
}
- iwl3945_set_rxon_channel(priv, conf->channel->band, conf->channel->hw_value);
+ iwl_set_rxon_channel(priv, conf->channel);
- iwl3945_set_flags_for_phymode(priv, conf->channel->band);
+ iwl_set_flags_for_band(priv, conf->channel->band);
/* The list of supported rates and rate mask can be different
* for each phymode; since the phymode may have changed, reset
* the rate mask to what mac80211 lists */
- iwl3945_set_rate(priv);
+ iwl_set_rate(priv);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -6639,28 +3773,36 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
}
#endif
- iwl3945_radio_kill_sw(priv, !conf->radio_enabled);
+ if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
+ if (conf->radio_enabled &&
+ iwl_radio_kill_sw_enable_radio(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
+ "waiting for uCode\n");
+ goto out;
+ }
- if (!conf->radio_enabled) {
- IWL_DEBUG_MAC80211("leave - radio disabled\n");
- goto out;
+ if (!conf->radio_enabled) {
+ iwl_radio_kill_sw_disable_radio(priv);
+ IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
+ goto out;
+ }
}
- if (iwl3945_is_rfkill(priv)) {
- IWL_DEBUG_MAC80211("leave - RF kill\n");
+ if (iwl_is_rfkill(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF kill\n");
ret = -EIO;
goto out;
}
- iwl3945_set_rate(priv);
+ iwl_set_rate(priv);
if (memcmp(&priv->active_rxon,
&priv->staging_rxon, sizeof(priv->staging_rxon)))
iwl3945_commit_rxon(priv);
else
- IWL_DEBUG_INFO("No re-sending same RXON configuration.\n");
+ IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration\n");
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
out:
clear_bit(STATUS_CONF_PENDING, &priv->status);
@@ -6668,7 +3810,7 @@ out:
return ret;
}
-static void iwl3945_config_ap(struct iwl3945_priv *priv)
+static void iwl3945_config_ap(struct iwl_priv *priv)
{
int rc = 0;
@@ -6676,19 +3818,20 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
return;
/* The following should be done only at AP bring up */
- if (!(iwl3945_is_associated(priv))) {
+ if (!(iwl_is_associated(priv))) {
/* RXON - unassoc (to set timing command) */
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
/* RXON Timing */
- memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd));
+ memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
iwl3945_setup_rxon_timing(priv);
- rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING,
- sizeof(priv->rxon_timing), &priv->rxon_timing);
+ rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
+ sizeof(priv->rxon_timing),
+ &priv->rxon_timing);
if (rc)
- IWL_WARNING("REPLY_RXON_TIMING failed - "
+ IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");
/* FIXME: what should be the assoc_id for AP? */
@@ -6716,7 +3859,7 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
- iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0);
+ iwl3945_add_station(priv, iwl_bcast_addr, 0, 0);
}
iwl3945_send_beacon_cmd(priv);
@@ -6727,16 +3870,16 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv)
static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
+ struct ieee80211_if_conf *conf)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
int rc;
if (conf == NULL)
return -EIO;
if (priv->vif != vif) {
- IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
+ IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
return 0;
}
@@ -6753,13 +3896,13 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
return rc;
}
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
mutex_lock(&priv->mutex);
if (conf->bssid)
- IWL_DEBUG_MAC80211("bssid: %pM\n", conf->bssid);
+ IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
/*
* very dubious code was here; the probe filtering flag is never set:
@@ -6772,7 +3915,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
if (!conf->bssid) {
conf->bssid = priv->mac_addr;
memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
- IWL_DEBUG_MAC80211("bssid was set to: %pM\n",
+ IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
conf->bssid);
}
if (priv->ibss_beacon)
@@ -6781,17 +3924,17 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
}
- if (iwl3945_is_rfkill(priv))
+ if (iwl_is_rfkill(priv))
goto done;
if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
!is_multicast_ether_addr(conf->bssid)) {
/* If there is currently a HW scan going on in the background
* then we need to cancel it else the RXON below will fail. */
- if (iwl3945_scan_cancel_timeout(priv, 100)) {
- IWL_WARNING("Aborted scan still in progress "
+ if (iwl_scan_cancel_timeout(priv, 100)) {
+ IWL_WARN(priv, "Aborted scan still in progress "
"after 100ms\n");
- IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
+ IWL_DEBUG_MAC80211(priv, "leaving:scan abort failed\n");
mutex_unlock(&priv->mutex);
return -EAGAIN;
}
@@ -6813,75 +3956,29 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
}
} else {
- iwl3945_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
}
done:
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
mutex_unlock(&priv->mutex);
return 0;
}
-static void iwl3945_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- int mc_count, struct dev_addr_list *mc_list)
-{
- struct iwl3945_priv *priv = hw->priv;
- __le32 *filter_flags = &priv->staging_rxon.filter_flags;
-
- IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
- changed_flags, *total_flags);
-
- if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
- if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
- *filter_flags |= RXON_FILTER_PROMISC_MSK;
- else
- *filter_flags &= ~RXON_FILTER_PROMISC_MSK;
- }
- if (changed_flags & FIF_ALLMULTI) {
- if (*total_flags & FIF_ALLMULTI)
- *filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
- else
- *filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
- }
- if (changed_flags & FIF_CONTROL) {
- if (*total_flags & FIF_CONTROL)
- *filter_flags |= RXON_FILTER_CTL2HOST_MSK;
- else
- *filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
- }
- if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
- if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
- *filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
- else
- *filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
- }
-
- /* We avoid iwl_commit_rxon here to commit the new filter flags
- * since mac80211 will call ieee80211_hw_config immediately.
- * (mc_list is not supported at this time). Otherwise, we need to
- * queue a background iwl_commit_rxon work.
- */
-
- *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
- FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
-}
-
static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
mutex_lock(&priv->mutex);
- if (iwl3945_is_ready_rf(priv)) {
- iwl3945_scan_cancel_timeout(priv, 100);
+ if (iwl_is_ready_rf(priv)) {
+ iwl_scan_cancel_timeout(priv, 100);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
}
@@ -6891,7 +3988,7 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
}
mutex_unlock(&priv->mutex);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
@@ -6901,21 +3998,23 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf,
u32 changes)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
- IWL_DEBUG_MAC80211("changes = 0x%X\n", changes);
+ IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n",
+ IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
bss_conf->use_short_preamble);
if (bss_conf->use_short_preamble)
priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ priv->staging_rxon.flags &=
+ ~RXON_FLG_SHORT_PREAMBLE_MSK;
}
if (changes & BSS_CHANGED_ERP_CTS_PROT) {
- IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot);
+ IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n",
+ bss_conf->use_cts_prot);
if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
else
@@ -6923,7 +4022,7 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
}
if (changes & BSS_CHANGED_ASSOC) {
- IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->assoc);
+ IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
/* This should never happen as this function should
* never be called from interrupt context. */
if (WARN_ON_ONCE(in_interrupt()))
@@ -6931,10 +4030,9 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
if (bss_conf->assoc) {
priv->assoc_id = bss_conf->aid;
priv->beacon_int = bss_conf->beacon_int;
- priv->timestamp0 = bss_conf->timestamp & 0xFFFFFFFF;
- priv->timestamp1 = (bss_conf->timestamp >> 32) &
- 0xFFFFFFFF;
+ priv->timestamp = bss_conf->timestamp;
priv->assoc_capability = bss_conf->assoc_capability;
+ priv->power_data.dtim_period = bss_conf->dtim_period;
priv->next_scan_jiffies = jiffies +
IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
mutex_lock(&priv->mutex);
@@ -6942,143 +4040,91 @@ static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
mutex_unlock(&priv->mutex);
} else {
priv->assoc_id = 0;
- IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc);
+ IWL_DEBUG_MAC80211(priv,
+ "DISASSOC %d\n", bss_conf->assoc);
}
- } else if (changes && iwl3945_is_associated(priv) && priv->assoc_id) {
- IWL_DEBUG_MAC80211("Associated Changes %d\n", changes);
+ } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
+ IWL_DEBUG_MAC80211(priv,
+ "Associated Changes %d\n", changes);
iwl3945_send_rxon_assoc(priv);
}
}
-static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
-{
- int rc = 0;
- unsigned long flags;
- struct iwl3945_priv *priv = hw->priv;
- DECLARE_SSID_BUF(ssid_buf);
-
- IWL_DEBUG_MAC80211("enter\n");
-
- mutex_lock(&priv->mutex);
- spin_lock_irqsave(&priv->lock, flags);
-
- if (!iwl3945_is_ready_rf(priv)) {
- rc = -EIO;
- IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
- goto out_unlock;
- }
-
- /* we don't schedule scan within next_scan_jiffies period */
- if (priv->next_scan_jiffies &&
- time_after(priv->next_scan_jiffies, jiffies)) {
- rc = -EAGAIN;
- goto out_unlock;
- }
- /* if we just finished scan ask for delay for a broadcast scan */
- if ((len == 0) && priv->last_scan_jiffies &&
- time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN,
- jiffies)) {
- rc = -EAGAIN;
- goto out_unlock;
- }
- if (len) {
- IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
- print_ssid(ssid_buf, ssid, len), (int)len);
-
- priv->one_direct_scan = 1;
- priv->direct_ssid_len = (u8)
- min((u8) len, (u8) IW_ESSID_MAX_SIZE);
- memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
- } else
- priv->one_direct_scan = 0;
-
- rc = iwl3945_scan_initiate(priv);
-
- IWL_DEBUG_MAC80211("leave\n");
-
-out_unlock:
- spin_unlock_irqrestore(&priv->lock, flags);
- mutex_unlock(&priv->mutex);
-
- return rc;
-}
-
static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_addr, const u8 *addr,
- struct ieee80211_key_conf *key)
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
- struct iwl3945_priv *priv = hw->priv;
- int rc = 0;
- u8 sta_id;
+ struct iwl_priv *priv = hw->priv;
+ const u8 *addr;
+ int ret = 0;
+ u8 sta_id = IWL_INVALID_STATION;
+ u8 static_key;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
- if (!iwl3945_param_hwcrypto) {
- IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n");
+ if (iwl3945_mod_params.sw_crypto) {
+ IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
return -EOPNOTSUPP;
}
- if (is_zero_ether_addr(addr))
- /* only support pairwise keys */
- return -EOPNOTSUPP;
+ addr = sta ? sta->addr : iwl_bcast_addr;
+ static_key = !iwl_is_associated(priv);
- sta_id = iwl3945_hw_find_station(priv, addr);
- if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211("leave - %pM not in station map.\n",
- addr);
- return -EINVAL;
+ if (!static_key) {
+ sta_id = iwl3945_hw_find_station(priv, addr);
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_DEBUG_MAC80211(priv, "leave - %pMnot in station map.\n",
+ addr);
+ return -EINVAL;
+ }
}
mutex_lock(&priv->mutex);
-
- iwl3945_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
+ mutex_unlock(&priv->mutex);
switch (cmd) {
- case SET_KEY:
- rc = iwl3945_update_sta_key_info(priv, key, sta_id);
- if (!rc) {
- iwl3945_set_rxon_hwcrypto(priv, 1);
- iwl3945_commit_rxon(priv);
- key->hw_key_idx = sta_id;
- IWL_DEBUG_MAC80211("set_key success, using hwcrypto\n");
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- }
+ case SET_KEY:
+ if (static_key)
+ ret = iwl3945_set_static_key(priv, key);
+ else
+ ret = iwl3945_set_dynamic_key(priv, key, sta_id);
+ IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
break;
case DISABLE_KEY:
- rc = iwl3945_clear_sta_key_info(priv, sta_id);
- if (!rc) {
- iwl3945_set_rxon_hwcrypto(priv, 0);
- iwl3945_commit_rxon(priv);
- IWL_DEBUG_MAC80211("disable hwcrypto key\n");
- }
+ if (static_key)
+ ret = iwl3945_remove_static_key(priv);
+ else
+ ret = iwl3945_clear_sta_key_info(priv, sta_id);
+ IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
break;
default:
- rc = -EINVAL;
+ ret = -EINVAL;
}
- IWL_DEBUG_MAC80211("leave\n");
- mutex_unlock(&priv->mutex);
+ IWL_DEBUG_MAC80211(priv, "leave\n");
- return rc;
+ return ret;
}
static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
unsigned long flags;
int q;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
- if (!iwl3945_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - RF not ready\n");
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
return -EIO;
}
if (queue >= AC_NUM) {
- IWL_DEBUG_MAC80211("leave - queue >= AC_NUM %d\n", queue);
+ IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
return 0;
}
@@ -7099,29 +4145,29 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
mutex_lock(&priv->mutex);
if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl3945_activate_qos(priv, 1);
- else if (priv->assoc_id && iwl3945_is_associated(priv))
- iwl3945_activate_qos(priv, 0);
+ iwl_activate_qos(priv, 1);
+ else if (priv->assoc_id && iwl_is_associated(priv))
+ iwl_activate_qos(priv, 0);
mutex_unlock(&priv->mutex);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
struct ieee80211_tx_queue_stats *stats)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
int i, avail;
- struct iwl3945_tx_queue *txq;
- struct iwl3945_queue *q;
+ struct iwl_tx_queue *txq;
+ struct iwl_queue *q;
unsigned long flags;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
- if (!iwl3945_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - RF not ready\n");
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
return -EIO;
}
@@ -7130,7 +4176,7 @@ static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
for (i = 0; i < AC_NUM; i++) {
txq = &priv->txq[i];
q = &txq->q;
- avail = iwl3945_queue_space(q);
+ avail = iwl_queue_space(q);
stats[i].len = q->n_window - avail;
stats[i].limit = q->n_window - q->high_mark;
@@ -7139,34 +4185,24 @@ static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
}
spin_unlock_irqrestore(&priv->lock, flags);
- IWL_DEBUG_MAC80211("leave\n");
-
- return 0;
-}
-
-static int iwl3945_mac_get_stats(struct ieee80211_hw *hw,
- struct ieee80211_low_level_stats *stats)
-{
- IWL_DEBUG_MAC80211("enter\n");
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
return 0;
}
static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
unsigned long flags;
mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
- iwl3945_reset_qos(priv);
+ iwl_reset_qos(priv);
spin_lock_irqsave(&priv->lock, flags);
priv->assoc_id = 0;
priv->assoc_capability = 0;
- priv->call_post_assoc_from_beacon = 0;
/* new association get rid of ibss beacon skb */
if (priv->ibss_beacon)
@@ -7175,15 +4211,14 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
priv->ibss_beacon = NULL;
priv->beacon_int = priv->hw->conf.beacon_int;
- priv->timestamp1 = 0;
- priv->timestamp0 = 0;
+ priv->timestamp = 0;
if ((priv->iw_mode == NL80211_IFTYPE_STATION))
priv->beacon_int = 0;
spin_unlock_irqrestore(&priv->lock, flags);
- if (!iwl3945_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - not ready\n");
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
mutex_unlock(&priv->mutex);
return;
}
@@ -7192,7 +4227,7 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
* clear RXON_FILTER_ASSOC_MSK bit
*/
if (priv->iw_mode != NL80211_IFTYPE_AP) {
- iwl3945_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
}
@@ -7200,33 +4235,34 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
/* Per mac80211.h: This is only used in IBSS mode... */
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
- IWL_DEBUG_MAC80211("leave - not in IBSS\n");
+ IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
mutex_unlock(&priv->mutex);
return;
}
- iwl3945_set_rate(priv);
+ iwl_set_rate(priv);
mutex_unlock(&priv->mutex);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
}
static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
{
- struct iwl3945_priv *priv = hw->priv;
+ struct iwl_priv *priv = hw->priv;
unsigned long flags;
+ __le64 timestamp;
- IWL_DEBUG_MAC80211("enter\n");
+ IWL_DEBUG_MAC80211(priv, "enter\n");
- if (!iwl3945_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211("leave - RF not ready\n");
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
return -EIO;
}
if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
- IWL_DEBUG_MAC80211("leave - not IBSS\n");
+ IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
return -EIO;
}
@@ -7238,11 +4274,13 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
priv->ibss_beacon = skb;
priv->assoc_id = 0;
+ timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+ priv->timestamp = le64_to_cpu(timestamp);
- IWL_DEBUG_MAC80211("leave\n");
+ IWL_DEBUG_MAC80211(priv, "leave\n");
spin_unlock_irqrestore(&priv->lock, flags);
- iwl3945_reset_qos(priv);
+ iwl_reset_qos(priv);
iwl3945_post_associate(priv);
@@ -7256,7 +4294,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
*
*****************************************************************************/
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
/*
* The following adds a new attribute to the sysfs representation
@@ -7265,38 +4303,41 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
*
* See the level definitions in iwl for details.
*/
-
-static ssize_t show_debug_level(struct device_driver *d, char *buf)
+static ssize_t show_debug_level(struct device *d,
+ struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "0x%08X\n", iwl3945_debug_level);
+ struct iwl_priv *priv = d->driver_data;
+
+ return sprintf(buf, "0x%08X\n", priv->debug_level);
}
-static ssize_t store_debug_level(struct device_driver *d,
+static ssize_t store_debug_level(struct device *d,
+ struct device_attribute *attr,
const char *buf, size_t count)
{
- char *p = (char *)buf;
- u32 val;
+ struct iwl_priv *priv = d->driver_data;
+ unsigned long val;
+ int ret;
- val = simple_strtoul(p, &p, 0);
- if (p == buf)
- printk(KERN_INFO DRV_NAME
- ": %s is not in hex or decimal form.\n", buf);
+ ret = strict_strtoul(buf, 0, &val);
+ if (ret)
+ IWL_INFO(priv, "%s is not in hex or decimal form.\n", buf);
else
- iwl3945_debug_level = val;
+ priv->debug_level = val;
return strnlen(buf, count);
}
-static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
- show_debug_level, store_debug_level);
+static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
+ show_debug_level, store_debug_level);
-#endif /* CONFIG_IWL3945_DEBUG */
+#endif /* CONFIG_IWLWIFI_DEBUG */
static ssize_t show_temperature(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
return sprintf(buf, "%d\n", iwl3945_hw_get_temperature(priv));
@@ -7307,22 +4348,21 @@ static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
static ssize_t show_tx_power(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
- return sprintf(buf, "%d\n", priv->user_txpower_limit);
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
}
static ssize_t store_tx_power(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
char *p = (char *)buf;
u32 val;
val = simple_strtoul(p, &p, 10);
if (p == buf)
- printk(KERN_INFO DRV_NAME
- ": %s is not in decimal form.\n", buf);
+ IWL_INFO(priv, ": %s is not in decimal form.\n", buf);
else
iwl3945_hw_reg_set_txpower(priv, val);
@@ -7334,7 +4374,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
static ssize_t show_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
}
@@ -7343,16 +4383,16 @@ static ssize_t store_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
u32 flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
/* Cancel any currently running scans... */
- if (iwl3945_scan_cancel_timeout(priv, 100))
- IWL_WARNING("Could not cancel scan.\n");
+ if (iwl_scan_cancel_timeout(priv, 100))
+ IWL_WARN(priv, "Could not cancel scan.\n");
else {
- IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n",
+ IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
flags);
priv->staging_rxon.flags = cpu_to_le32(flags);
iwl3945_commit_rxon(priv);
@@ -7368,7 +4408,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags);
static ssize_t show_filter_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
return sprintf(buf, "0x%04X\n",
le32_to_cpu(priv->active_rxon.filter_flags));
@@ -7378,16 +4418,16 @@ static ssize_t store_filter_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
u32 filter_flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
/* Cancel any currently running scans... */
- if (iwl3945_scan_cancel_timeout(priv, 100))
- IWL_WARNING("Could not cancel scan.\n");
+ if (iwl_scan_cancel_timeout(priv, 100))
+ IWL_WARN(priv, "Could not cancel scan.\n");
else {
- IWL_DEBUG_INFO("Committing rxon.filter_flags = "
+ IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = "
"0x%04X\n", filter_flags);
priv->staging_rxon.filter_flags =
cpu_to_le32(filter_flags);
@@ -7407,8 +4447,8 @@ static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
static ssize_t show_measurement(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
- struct iwl3945_spectrum_notification measure_report;
+ struct iwl_priv *priv = dev_get_drvdata(d);
+ struct iwl_spectrum_notification measure_report;
u32 size = sizeof(measure_report), len = 0, ofs = 0;
u8 *data = (u8 *)&measure_report;
unsigned long flags;
@@ -7440,7 +4480,7 @@ static ssize_t store_measurement(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
struct ieee80211_measurement_params params = {
.channel = le16_to_cpu(priv->active_rxon.channel),
.start_time = cpu_to_le64(priv->last_tsf),
@@ -7464,7 +4504,7 @@ static ssize_t store_measurement(struct device *d,
type = simple_strtoul(p + 1, NULL, 0);
}
- IWL_DEBUG_INFO("Invoking measurement of type %d on "
+ IWL_DEBUG_INFO(priv, "Invoking measurement of type %d on "
"channel %d (for '%s')\n", type, params.channel, buf);
iwl3945_get_measurement(priv, &params, type);
@@ -7479,7 +4519,7 @@ static ssize_t store_retry_rate(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
priv->retry_rate = simple_strtoul(buf, NULL, 0);
if (priv->retry_rate <= 0)
@@ -7491,50 +4531,72 @@ static ssize_t store_retry_rate(struct device *d,
static ssize_t show_retry_rate(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "%d", priv->retry_rate);
}
static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate,
store_retry_rate);
+
static ssize_t store_power_level(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
- int rc;
- int mode;
+ struct iwl_priv *priv = dev_get_drvdata(d);
+ int ret;
+ unsigned long mode;
+
- mode = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
- if (!iwl3945_is_ready(priv)) {
- rc = -EAGAIN;
+ ret = strict_strtoul(buf, 10, &mode);
+ if (ret)
goto out;
- }
-
- if ((mode < 1) || (mode > IWL_POWER_LIMIT) || (mode == IWL_POWER_AC))
- mode = IWL_POWER_AC;
- else
- mode |= IWL_POWER_ENABLED;
- if (mode != priv->power_mode) {
- rc = iwl3945_send_power_mode(priv, IWL_POWER_LEVEL(mode));
- if (rc) {
- IWL_DEBUG_MAC80211("failed setting power mode.\n");
- goto out;
- }
- priv->power_mode = mode;
+ ret = iwl_power_set_user_mode(priv, mode);
+ if (ret) {
+ IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
+ goto out;
}
-
- rc = count;
+ ret = count;
out:
mutex_unlock(&priv->mutex);
- return rc;
+ return ret;
}
+static ssize_t show_power_level(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct iwl_priv *priv = dev_get_drvdata(d);
+ int mode = priv->power_data.user_power_setting;
+ int system = priv->power_data.system_power_setting;
+ int level = priv->power_data.power_mode;
+ char *p = buf;
+
+ switch (system) {
+ case IWL_POWER_SYS_AUTO:
+ p += sprintf(p, "SYSTEM:auto");
+ break;
+ case IWL_POWER_SYS_AC:
+ p += sprintf(p, "SYSTEM:ac");
+ break;
+ case IWL_POWER_SYS_BATTERY:
+ p += sprintf(p, "SYSTEM:battery");
+ break;
+ }
+
+ p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
+ "fixed" : "auto");
+ p += sprintf(p, "\tINDEX:%d", level);
+ p += sprintf(p, "\n");
+ return p - buf + 1;
+}
+
+static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR,
+ show_power_level, store_power_level);
+
#define MAX_WX_STRING 80
/* Values are in microsecond */
@@ -7553,41 +4615,6 @@ static const s32 period_duration[] = {
1000000
};
-static ssize_t show_power_level(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
- int level = IWL_POWER_LEVEL(priv->power_mode);
- char *p = buf;
-
- p += sprintf(p, "%d ", level);
- switch (level) {
- case IWL_POWER_MODE_CAM:
- case IWL_POWER_AC:
- p += sprintf(p, "(AC)");
- break;
- case IWL_POWER_BATTERY:
- p += sprintf(p, "(BATTERY)");
- break;
- default:
- p += sprintf(p,
- "(Timeout %dms, Period %dms)",
- timeout_duration[level - 1] / 1000,
- period_duration[level - 1] / 1000);
- }
-
- if (!(priv->power_mode & IWL_POWER_ENABLED))
- p += sprintf(p, " OFF\n");
- else
- p += sprintf(p, " \n");
-
- return p - buf + 1;
-
-}
-
-static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
- store_power_level);
-
static ssize_t show_channels(struct device *d,
struct device_attribute *attr, char *buf)
{
@@ -7600,17 +4627,17 @@ static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
static ssize_t show_statistics(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
u32 size = sizeof(struct iwl3945_notif_statistics);
u32 len = 0, ofs = 0;
- u8 *data = (u8 *)&priv->statistics;
+ u8 *data = (u8 *)&priv->statistics_39;
int rc = 0;
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
mutex_lock(&priv->mutex);
- rc = iwl3945_send_statistics_request(priv);
+ rc = iwl_send_statistics_request(priv, 0);
mutex_unlock(&priv->mutex);
if (rc) {
@@ -7638,34 +4665,34 @@ static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
static ssize_t show_antenna(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = dev_get_drvdata(d);
+ struct iwl_priv *priv = dev_get_drvdata(d);
- if (!iwl3945_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
- return sprintf(buf, "%d\n", priv->antenna);
+ return sprintf(buf, "%d\n", iwl3945_mod_params.antenna);
}
static ssize_t store_antenna(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct iwl_priv *priv __maybe_unused = dev_get_drvdata(d);
int ant;
- struct iwl3945_priv *priv = dev_get_drvdata(d);
if (count == 0)
return 0;
if (sscanf(buf, "%1i", &ant) != 1) {
- IWL_DEBUG_INFO("not in hex or decimal form.\n");
+ IWL_DEBUG_INFO(priv, "not in hex or decimal form.\n");
return count;
}
if ((ant >= 0) && (ant <= 2)) {
- IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant);
- priv->antenna = (enum iwl3945_antenna)ant;
+ IWL_DEBUG_INFO(priv, "Setting antenna select to %d.\n", ant);
+ iwl3945_mod_params.antenna = (enum iwl3945_antenna)ant;
} else
- IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant);
+ IWL_DEBUG_INFO(priv, "Bad antenna select value %d.\n", ant);
return count;
@@ -7676,8 +4703,8 @@ static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna);
static ssize_t show_status(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
- if (!iwl3945_is_alive(priv))
+ struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ if (!iwl_is_alive(priv))
return -EAGAIN;
return sprintf(buf, "0x%08x\n", (int)priv->status);
}
@@ -7691,7 +4718,7 @@ static ssize_t dump_error_log(struct device *d,
char *p = (char *)buf;
if (p[0] == '1')
- iwl3945_dump_nic_error_log((struct iwl3945_priv *)d->driver_data);
+ iwl3945_dump_nic_error_log((struct iwl_priv *)d->driver_data);
return strnlen(buf, count);
}
@@ -7705,7 +4732,7 @@ static ssize_t dump_event_log(struct device *d,
char *p = (char *)buf;
if (p[0] == '1')
- iwl3945_dump_nic_event_log((struct iwl3945_priv *)d->driver_data);
+ iwl3945_dump_nic_event_log((struct iwl_priv *)d->driver_data);
return strnlen(buf, count);
}
@@ -7718,23 +4745,24 @@ static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
*
*****************************************************************************/
-static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
+static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
{
- priv->workqueue = create_workqueue(DRV_NAME);
+ priv->workqueue = create_singlethread_workqueue(DRV_NAME);
init_waitqueue_head(&priv->wait_command_queue);
INIT_WORK(&priv->up, iwl3945_bg_up);
INIT_WORK(&priv->restart, iwl3945_bg_restart);
INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
- INIT_WORK(&priv->scan_completed, iwl3945_bg_scan_completed);
- INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
- INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan);
- INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill);
+ INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
- INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check);
+ INIT_DELAYED_WORK(&priv->rfkill_poll, iwl3945_rfkill_poll);
+ INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
+ INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
+ INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
+ INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
iwl3945_hw_setup_deferred_work(priv);
@@ -7742,7 +4770,7 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
iwl3945_irq_tasklet, (unsigned long)priv);
}
-static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv)
+static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
{
iwl3945_hw_cancel_deferred_work(priv);
@@ -7768,7 +4796,9 @@ static struct attribute *iwl3945_sysfs_entries[] = {
&dev_attr_status.attr,
&dev_attr_temperature.attr,
&dev_attr_tx_power.attr,
-
+#ifdef CONFIG_IWLWIFI_DEBUG
+ &dev_attr_debug_level.attr,
+#endif
NULL
};
@@ -7785,83 +4815,179 @@ static struct ieee80211_ops iwl3945_hw_ops = {
.remove_interface = iwl3945_mac_remove_interface,
.config = iwl3945_mac_config,
.config_interface = iwl3945_mac_config_interface,
- .configure_filter = iwl3945_configure_filter,
+ .configure_filter = iwl_configure_filter,
.set_key = iwl3945_mac_set_key,
- .get_stats = iwl3945_mac_get_stats,
.get_tx_stats = iwl3945_mac_get_tx_stats,
.conf_tx = iwl3945_mac_conf_tx,
.reset_tsf = iwl3945_mac_reset_tsf,
.bss_info_changed = iwl3945_bss_info_changed,
- .hw_scan = iwl3945_mac_hw_scan
+ .hw_scan = iwl_mac_hw_scan
};
-static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int iwl3945_init_drv(struct iwl_priv *priv)
{
- int err = 0;
- struct iwl3945_priv *priv;
- struct ieee80211_hw *hw;
- struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data);
- unsigned long flags;
+ int ret;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
- /***********************
- * 1. Allocating HW data
- * ********************/
+ priv->retry_rate = 1;
+ priv->ibss_beacon = NULL;
- /* Disabling hardware scan means that mac80211 will perform scans
- * "the hard way", rather than using device's scan. */
- if (iwl3945_param_disable_hw_scan) {
- IWL_DEBUG_INFO("Disabling hw_scan\n");
- iwl3945_hw_ops.hw_scan = NULL;
+ spin_lock_init(&priv->lock);
+ spin_lock_init(&priv->power_data.lock);
+ spin_lock_init(&priv->sta_lock);
+ spin_lock_init(&priv->hcmd_lock);
+
+ INIT_LIST_HEAD(&priv->free_frames);
+
+ mutex_init(&priv->mutex);
+
+ /* Clear the driver's (not device's) station table */
+ iwl3945_clear_stations_table(priv);
+
+ priv->data_retry_limit = -1;
+ priv->ieee_channels = NULL;
+ priv->ieee_rates = NULL;
+ priv->band = IEEE80211_BAND_2GHZ;
+
+ priv->iw_mode = NL80211_IFTYPE_STATION;
+
+ iwl_reset_qos(priv);
+
+ priv->qos_data.qos_active = 0;
+ priv->qos_data.qos_cap.val = 0;
+
+ priv->rates_mask = IWL_RATES_MASK;
+ /* If power management is turned on, default to CAM mode */
+ priv->power_mode = IWL_POWER_MODE_CAM;
+ priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
+
+ if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
+ IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n",
+ eeprom->version);
+ ret = -EINVAL;
+ goto err;
+ }
+ ret = iwl_init_channel_map(priv);
+ if (ret) {
+ IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
+ goto err;
}
- if ((iwl3945_param_queues_num > IWL39_MAX_NUM_QUEUES) ||
- (iwl3945_param_queues_num < IWL_MIN_NUM_QUEUES)) {
- IWL_ERROR("invalid queues_num, should be between %d and %d\n",
- IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES);
- err = -EINVAL;
- goto out;
+ /* Set up txpower settings in driver for all channels */
+ if (iwl3945_txpower_set_from_eeprom(priv)) {
+ ret = -EIO;
+ goto err_free_channel_map;
}
- /* mac80211 allocates memory for this device instance, including
- * space for this driver's private structure */
- hw = ieee80211_alloc_hw(sizeof(struct iwl3945_priv), &iwl3945_hw_ops);
- if (hw == NULL) {
- IWL_ERROR("Can not allocate network device\n");
- err = -ENOMEM;
- goto out;
+ ret = iwlcore_init_geos(priv);
+ if (ret) {
+ IWL_ERR(priv, "initializing geos failed: %d\n", ret);
+ goto err_free_channel_map;
}
+ iwl3945_init_hw_rates(priv, priv->ieee_rates);
- SET_IEEE80211_DEV(hw, &pdev->dev);
+ return 0;
- priv = hw->priv;
- priv->hw = hw;
- priv->pci_dev = pdev;
- priv->cfg = cfg;
+err_free_channel_map:
+ iwl_free_channel_map(priv);
+err:
+ return ret;
+}
+
+static int iwl3945_setup_mac(struct iwl_priv *priv)
+{
+ int ret;
+ struct ieee80211_hw *hw = priv->hw;
- IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
hw->rate_control_algorithm = "iwl-3945-rs";
hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
- /* Select antenna (may be helpful if only one antenna is connected) */
- priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna;
-#ifdef CONFIG_IWL3945_DEBUG
- iwl3945_debug_level = iwl3945_param_debug;
- atomic_set(&priv->restrict_refcnt, 0);
-#endif
-
/* Tell mac80211 our characteristics */
hw->flags = IEEE80211_HW_SIGNAL_DBM |
- IEEE80211_HW_NOISE_DBM;
+ IEEE80211_HW_NOISE_DBM |
+ IEEE80211_HW_SPECTRUM_MGMT;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
- hw->wiphy->fw_handles_regulatory = true;
+ hw->wiphy->custom_regulatory = true;
- /* 4 EDCA QOS priorities */
+ /* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
+ hw->conf.beacon_int = 100;
+
+ if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
+ priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+ &priv->bands[IEEE80211_BAND_2GHZ];
+
+ if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
+ priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &priv->bands[IEEE80211_BAND_5GHZ];
+
+ ret = ieee80211_register_hw(priv->hw);
+ if (ret) {
+ IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
+ return ret;
+ }
+ priv->mac80211_registered = 1;
+
+ return 0;
+}
+
+static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ int err = 0;
+ struct iwl_priv *priv;
+ struct ieee80211_hw *hw;
+ struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
+ struct iwl3945_eeprom *eeprom;
+ unsigned long flags;
+
+ /***********************
+ * 1. Allocating HW data
+ * ********************/
+
+ /* mac80211 allocates memory for this device instance, including
+ * space for this driver's private structure */
+ hw = iwl_alloc_all(cfg, &iwl3945_hw_ops);
+ if (hw == NULL) {
+ printk(KERN_ERR DRV_NAME "Can not allocate network device\n");
+ err = -ENOMEM;
+ goto out;
+ }
+ priv = hw->priv;
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+
+ if ((iwl3945_mod_params.num_of_queues > IWL39_MAX_NUM_QUEUES) ||
+ (iwl3945_mod_params.num_of_queues < IWL_MIN_NUM_QUEUES)) {
+ IWL_ERR(priv,
+ "invalid queues_num, should be between %d and %d\n",
+ IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES);
+ err = -EINVAL;
+ goto out_ieee80211_free_hw;
+ }
+
+ /*
+ * Disabling hardware scan means that mac80211 will perform scans
+ * "the hard way", rather than using device's scan.
+ */
+ if (iwl3945_mod_params.disable_hw_scan) {
+ IWL_DEBUG_INFO(priv, "Disabling hw_scan\n");
+ iwl3945_hw_ops.hw_scan = NULL;
+ }
+
+
+ IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
+ priv->cfg = cfg;
+ priv->pci_dev = pdev;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+ priv->debug_level = iwl3945_mod_params.debug;
+ atomic_set(&priv->restrict_refcnt, 0);
+#endif
+
/***************************
* 2. Initializing PCI bus
* *************************/
@@ -7876,7 +5002,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
if (!err)
err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (err) {
- printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");
+ IWL_WARN(priv, "No suitable DMA available.\n");
goto out_pci_disable_device;
}
@@ -7894,98 +5020,58 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
goto out_pci_release_regions;
}
- IWL_DEBUG_INFO("pci_resource_len = 0x%08llx\n",
+ IWL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n",
(unsigned long long) pci_resource_len(pdev, 0));
- IWL_DEBUG_INFO("pci_resource_base = %p\n", priv->hw_base);
+ IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base);
/* We disable the RETRY_TIMEOUT register (0x41) to keep
* PCI Tx retries from interfering with C3 CPU state */
pci_write_config_byte(pdev, 0x41, 0x00);
- /* nic init */
- iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
- CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
- iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- err = iwl3945_poll_direct_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ /* amp init */
+ err = priv->cfg->ops->lib->apm_ops.init(priv);
if (err < 0) {
- IWL_DEBUG_INFO("Failed to init the card\n");
+ IWL_DEBUG_INFO(priv, "Failed to init the card\n");
goto out_iounmap;
}
/***********************
* 4. Read EEPROM
* ********************/
+
/* Read the EEPROM */
- err = iwl3945_eeprom_init(priv);
+ err = iwl_eeprom_init(priv);
if (err) {
- IWL_ERROR("Unable to init EEPROM\n");
+ IWL_ERR(priv, "Unable to init EEPROM\n");
goto out_iounmap;
}
/* MAC Address location in EEPROM same for 3945/4965 */
- get_eeprom_mac(priv, priv->mac_addr);
- IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr);
+ eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+ memcpy(priv->mac_addr, eeprom->mac_address, ETH_ALEN);
+ IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->mac_addr);
SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
/***********************
* 5. Setup HW Constants
* ********************/
/* Device-specific setup */
- if (iwl3945_hw_set_hw_setting(priv)) {
- IWL_ERROR("failed to set hw settings\n");
- goto out_iounmap;
+ if (iwl3945_hw_set_hw_params(priv)) {
+ IWL_ERR(priv, "failed to set hw settings\n");
+ goto out_eeprom_free;
}
/***********************
* 6. Setup priv
* ********************/
- priv->retry_rate = 1;
- priv->ibss_beacon = NULL;
-
- spin_lock_init(&priv->lock);
- spin_lock_init(&priv->power_data.lock);
- spin_lock_init(&priv->sta_lock);
- spin_lock_init(&priv->hcmd_lock);
- INIT_LIST_HEAD(&priv->free_frames);
- mutex_init(&priv->mutex);
-
- /* Clear the driver's (not device's) station table */
- iwl3945_clear_stations_table(priv);
-
- priv->data_retry_limit = -1;
- priv->ieee_channels = NULL;
- priv->ieee_rates = NULL;
- priv->band = IEEE80211_BAND_2GHZ;
-
- priv->iw_mode = NL80211_IFTYPE_STATION;
-
- iwl3945_reset_qos(priv);
-
- priv->qos_data.qos_active = 0;
- priv->qos_data.qos_cap.val = 0;
-
-
- priv->rates_mask = IWL_RATES_MASK;
- /* If power management is turned on, default to AC mode */
- priv->power_mode = IWL_POWER_AC;
- priv->user_txpower_limit = IWL_DEFAULT_TX_POWER;
-
- err = iwl3945_init_channel_map(priv);
+ err = iwl3945_init_drv(priv);
if (err) {
- IWL_ERROR("initializing regulatory failed: %d\n", err);
- goto out_unset_hw_setting;
+ IWL_ERR(priv, "initializing driver failed\n");
+ goto out_unset_hw_params;
}
- err = iwl3945_init_geos(priv);
- if (err) {
- IWL_ERROR("initializing geos failed: %d\n", err);
- goto out_free_channel_map;
- }
-
- printk(KERN_INFO DRV_NAME
- ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
+ IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n",
+ priv->cfg->name);
/***********************************
* 7. Initialize Module Parameters
@@ -7993,9 +5079,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/* Initialize module parameter values here */
/* Disable radio (SW RF KILL) via parameter when loading driver */
- if (iwl3945_param_disable) {
+ if (iwl3945_mod_params.disable) {
set_bit(STATUS_RF_KILL_SW, &priv->status);
- IWL_DEBUG_INFO("Radio disabled.\n");
+ IWL_DEBUG_INFO(priv, "Radio disabled.\n");
}
@@ -8004,43 +5090,49 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
* ********************/
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_disable_interrupts(priv);
+ iwl_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags);
+ pci_enable_msi(priv->pci_dev);
+
+ err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
+ DRV_NAME, priv);
+ if (err) {
+ IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
+ goto out_disable_msi;
+ }
+
err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group);
if (err) {
- IWL_ERROR("failed to create sysfs device attributes\n");
- goto out_free_geos;
+ IWL_ERR(priv, "failed to create sysfs device attributes\n");
+ goto out_release_irq;
}
- iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
+ iwl_set_rxon_channel(priv,
+ &priv->bands[IEEE80211_BAND_2GHZ].channels[5]);
iwl3945_setup_deferred_work(priv);
iwl3945_setup_rx_handlers(priv);
- /***********************
- * 9. Conclude
- * ********************/
- pci_save_state(pdev);
- pci_disable_device(pdev);
-
/*********************************
- * 10. Setup and Register mac80211
+ * 9. Setup and Register mac80211
* *******************************/
- err = ieee80211_register_hw(priv->hw);
- if (err) {
- IWL_ERROR("Failed to register network device (error %d)\n", err);
- goto out_remove_sysfs;
- }
-
- priv->hw->conf.beacon_int = 100;
- priv->mac80211_registered = 1;
+ iwl_enable_interrupts(priv);
+ err = iwl3945_setup_mac(priv);
+ if (err)
+ goto out_remove_sysfs;
- err = iwl3945_rfkill_init(priv);
+ err = iwl_rfkill_init(priv);
if (err)
- IWL_ERROR("Unable to initialize RFKILL system. "
+ IWL_ERR(priv, "Unable to initialize RFKILL system. "
"Ignoring error: %d\n", err);
+ else
+ iwl_rfkill_set_hw_state(priv);
+
+ /* Start monitoring the killswitch */
+ queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
+ 2 * HZ);
return 0;
@@ -8048,12 +5140,16 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
- out_free_geos:
- iwl3945_free_geos(priv);
- out_free_channel_map:
- iwl3945_free_channel_map(priv);
- out_unset_hw_setting:
- iwl3945_unset_hw_setting(priv);
+ out_release_irq:
+ free_irq(priv->pci_dev->irq, priv);
+ out_disable_msi:
+ pci_disable_msi(priv->pci_dev);
+ iwlcore_free_geos(priv);
+ iwl_free_channel_map(priv);
+ out_unset_hw_params:
+ iwl3945_unset_hw_params(priv);
+ out_eeprom_free:
+ iwl_eeprom_free(priv);
out_iounmap:
pci_iounmap(pdev, priv->hw_base);
out_pci_release_regions:
@@ -8069,42 +5165,46 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
{
- struct iwl3945_priv *priv = pci_get_drvdata(pdev);
+ struct iwl_priv *priv = pci_get_drvdata(pdev);
unsigned long flags;
if (!priv)
return;
- IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
+ IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
set_bit(STATUS_EXIT_PENDING, &priv->status);
- iwl3945_down(priv);
+ if (priv->mac80211_registered) {
+ ieee80211_unregister_hw(priv->hw);
+ priv->mac80211_registered = 0;
+ } else {
+ iwl3945_down(priv);
+ }
/* make sure we flush any pending irq or
* tasklet for the driver
*/
spin_lock_irqsave(&priv->lock, flags);
- iwl3945_disable_interrupts(priv);
+ iwl_disable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags);
iwl_synchronize_irq(priv);
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
- iwl3945_rfkill_unregister(priv);
+ iwl_rfkill_unregister(priv);
+ cancel_delayed_work(&priv->rfkill_poll);
+
iwl3945_dealloc_ucode_pci(priv);
if (priv->rxq.bd)
- iwl3945_rx_queue_free(priv, &priv->rxq);
+ iwl_rx_queue_free(priv, &priv->rxq);
iwl3945_hw_txq_ctx_free(priv);
- iwl3945_unset_hw_setting(priv);
+ iwl3945_unset_hw_params(priv);
iwl3945_clear_stations_table(priv);
- if (priv->mac80211_registered)
- ieee80211_unregister_hw(priv->hw);
-
/*netif_stop_queue(dev); */
flush_workqueue(priv->workqueue);
@@ -8114,13 +5214,16 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
+ free_irq(pdev->irq, priv);
+ pci_disable_msi(pdev);
+
pci_iounmap(pdev, priv->hw_base);
pci_release_regions(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
- iwl3945_free_channel_map(priv);
- iwl3945_free_geos(priv);
+ iwl_free_channel_map(priv);
+ iwlcore_free_geos(priv);
kfree(priv->scan);
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
@@ -8132,27 +5235,15 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
- struct iwl3945_priv *priv = pci_get_drvdata(pdev);
+ struct iwl_priv *priv = pci_get_drvdata(pdev);
if (priv->is_open) {
set_bit(STATUS_IN_SUSPEND, &priv->status);
iwl3945_mac_stop(priv->hw);
priv->is_open = 1;
}
-
- /* pci driver assumes state will be saved in this function.
- * pci state is saved and device disabled when interface is
- * stopped, so at this time pci device will always be disabled -
- * whether interface was started or not. saving pci state now will
- * cause saved state be that of a disabled device, which will cause
- * problems during resume in that we will end up with a disabled device.
- *
- * indicate that the current saved state (from when interface was
- * stopped) is valid. if interface was never up at time of suspend
- * then the saved state will still be valid as it was saved during
- * .probe. */
- pdev->state_saved = true;
-
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
pci_set_power_state(pdev, PCI_D3hot);
return 0;
@@ -8160,9 +5251,14 @@ static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
static int iwl3945_pci_resume(struct pci_dev *pdev)
{
- struct iwl3945_priv *priv = pci_get_drvdata(pdev);
+ struct iwl_priv *priv = pci_get_drvdata(pdev);
+ int ret;
pci_set_power_state(pdev, PCI_D0);
+ ret = pci_enable_device(pdev);
+ if (ret)
+ return ret;
+ pci_restore_state(pdev);
if (priv->is_open)
iwl3945_mac_start(priv->hw);
@@ -8173,114 +5269,6 @@ static int iwl3945_pci_resume(struct pci_dev *pdev)
#endif /* CONFIG_PM */
-/*************** RFKILL FUNCTIONS **********/
-#ifdef CONFIG_IWL3945_RFKILL
-/* software rf-kill from user */
-static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
-{
- struct iwl3945_priv *priv = data;
- int err = 0;
-
- if (!priv->rfkill)
- return 0;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return 0;
-
- IWL_DEBUG_RF_KILL("we received soft RFKILL set to state %d\n", state);
- mutex_lock(&priv->mutex);
-
- switch (state) {
- case RFKILL_STATE_UNBLOCKED:
- if (iwl3945_is_rfkill_hw(priv)) {
- err = -EBUSY;
- goto out_unlock;
- }
- iwl3945_radio_kill_sw(priv, 0);
- break;
- case RFKILL_STATE_SOFT_BLOCKED:
- iwl3945_radio_kill_sw(priv, 1);
- break;
- default:
- IWL_WARNING("we received unexpected RFKILL state %d\n", state);
- break;
- }
-out_unlock:
- mutex_unlock(&priv->mutex);
-
- return err;
-}
-
-int iwl3945_rfkill_init(struct iwl3945_priv *priv)
-{
- struct device *device = wiphy_dev(priv->hw->wiphy);
- int ret = 0;
-
- BUG_ON(device == NULL);
-
- IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
- priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
- if (!priv->rfkill) {
- IWL_ERROR("Unable to allocate rfkill device.\n");
- ret = -ENOMEM;
- goto error;
- }
-
- priv->rfkill->name = priv->cfg->name;
- priv->rfkill->data = priv;
- priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
- priv->rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill;
- priv->rfkill->user_claim_unsupported = 1;
-
- priv->rfkill->dev.class->suspend = NULL;
- priv->rfkill->dev.class->resume = NULL;
-
- ret = rfkill_register(priv->rfkill);
- if (ret) {
- IWL_ERROR("Unable to register rfkill: %d\n", ret);
- goto freed_rfkill;
- }
-
- IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
- return ret;
-
-freed_rfkill:
- if (priv->rfkill != NULL)
- rfkill_free(priv->rfkill);
- priv->rfkill = NULL;
-
-error:
- IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
- return ret;
-}
-
-void iwl3945_rfkill_unregister(struct iwl3945_priv *priv)
-{
- if (priv->rfkill)
- rfkill_unregister(priv->rfkill);
-
- priv->rfkill = NULL;
-}
-
-/* set rf-kill to the right state. */
-void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv)
-{
-
- if (!priv->rfkill)
- return;
-
- if (iwl3945_is_rfkill_hw(priv)) {
- rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
- return;
- }
-
- if (!iwl3945_is_rfkill_sw(priv))
- rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
- else
- rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
-}
-#endif
-
/*****************************************************************************
*
* driver and module entry point
@@ -8307,29 +5295,19 @@ static int __init iwl3945_init(void)
ret = iwl3945_rate_control_register();
if (ret) {
- IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
+ printk(KERN_ERR DRV_NAME
+ "Unable to register rate control algorithm: %d\n", ret);
return ret;
}
ret = pci_register_driver(&iwl3945_driver);
if (ret) {
- IWL_ERROR("Unable to initialize PCI module\n");
+ printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n");
goto error_register;
}
-#ifdef CONFIG_IWL3945_DEBUG
- ret = driver_create_file(&iwl3945_driver.driver, &driver_attr_debug_level);
- if (ret) {
- IWL_ERROR("Unable to create driver sysfs file\n");
- goto error_debug;
- }
-#endif
return ret;
-#ifdef CONFIG_IWL3945_DEBUG
-error_debug:
- pci_unregister_driver(&iwl3945_driver);
-#endif
error_register:
iwl3945_rate_control_unregister();
return ret;
@@ -8337,29 +5315,29 @@ error_register:
static void __exit iwl3945_exit(void)
{
-#ifdef CONFIG_IWL3945_DEBUG
- driver_remove_file(&iwl3945_driver.driver, &driver_attr_debug_level);
-#endif
pci_unregister_driver(&iwl3945_driver);
iwl3945_rate_control_unregister();
}
MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX));
-module_param_named(antenna, iwl3945_param_antenna, int, 0444);
+module_param_named(antenna, iwl3945_mod_params.antenna, int, 0444);
MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(disable, iwl3945_param_disable, int, 0444);
+module_param_named(disable, iwl3945_mod_params.disable, int, 0444);
MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
-module_param_named(hwcrypto, iwl3945_param_hwcrypto, int, 0444);
-MODULE_PARM_DESC(hwcrypto,
- "using hardware crypto engine (default 0 [software])\n");
-module_param_named(debug, iwl3945_param_debug, uint, 0444);
+module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444);
+MODULE_PARM_DESC(swcrypto,
+ "using software crypto (default 1 [software])\n");
+module_param_named(debug, iwl3945_mod_params.debug, uint, 0444);
MODULE_PARM_DESC(debug, "debug output mask");
-module_param_named(disable_hw_scan, iwl3945_param_disable_hw_scan, int, 0444);
+module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, int, 0444);
MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
-module_param_named(queues_num, iwl3945_param_queues_num, int, 0444);
+module_param_named(queues_num, iwl3945_mod_params.num_of_queues, int, 0444);
MODULE_PARM_DESC(queues_num, "number of hw queues.");
+module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, 0444);
+MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error");
+
module_exit(iwl3945_exit);
module_init(iwl3945_init);
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
index 02080a3682a9..0b6918584503 100644
--- a/drivers/net/wireless/libertas/Makefile
+++ b/drivers/net/wireless/libertas/Makefile
@@ -4,8 +4,10 @@ libertas-objs := main.o wext.o rx.o tx.o cmd.o cmdresp.o scan.o 11d.o \
usb8xxx-objs += if_usb.o
libertas_cs-objs += if_cs.o
libertas_sdio-objs += if_sdio.o
+libertas_spi-objs += if_spi.o
obj-$(CONFIG_LIBERTAS) += libertas.o
obj-$(CONFIG_LIBERTAS_USB) += usb8xxx.o
obj-$(CONFIG_LIBERTAS_CS) += libertas_cs.o
obj-$(CONFIG_LIBERTAS_SDIO) += libertas_sdio.o
+obj-$(CONFIG_LIBERTAS_SPI) += libertas_spi.o
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 639dd02d3d31..8c3605cdc64c 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1649,7 +1649,7 @@ static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
/**
* @brief This function executes next command in command
- * pending queue. It will put fimware back to PS mode
+ * pending queue. It will put firmware back to PS mode
* if applicable.
*
* @param priv A pointer to struct lbs_private structure
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index ec4efd7ff3c8..50e28a0cdfee 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -629,7 +629,7 @@ static ssize_t lbs_rdrf_write(struct file *file,
res = -EFAULT;
goto out_unlock;
}
- priv->rf_offset = simple_strtoul((char *)buf, NULL, 16);
+ priv->rf_offset = simple_strtoul(buf, NULL, 16);
res = count;
out_unlock:
free_page(addr);
@@ -680,12 +680,12 @@ out_unlock:
}
struct lbs_debugfs_files {
- char *name;
+ const char *name;
int perm;
struct file_operations fops;
};
-static struct lbs_debugfs_files debugfs_files[] = {
+static const struct lbs_debugfs_files debugfs_files[] = {
{ "info", 0444, FOPS(lbs_dev_info, write_file_dummy), },
{ "getscantable", 0444, FOPS(lbs_getscantable,
write_file_dummy), },
@@ -693,7 +693,7 @@ static struct lbs_debugfs_files debugfs_files[] = {
lbs_sleepparams_write), },
};
-static struct lbs_debugfs_files debugfs_events_files[] = {
+static const struct lbs_debugfs_files debugfs_events_files[] = {
{"low_rssi", 0644, FOPS(lbs_lowrssi_read,
lbs_lowrssi_write), },
{"low_snr", 0644, FOPS(lbs_lowsnr_read,
@@ -708,7 +708,7 @@ static struct lbs_debugfs_files debugfs_events_files[] = {
lbs_highsnr_write), },
};
-static struct lbs_debugfs_files debugfs_regs_files[] = {
+static const struct lbs_debugfs_files debugfs_regs_files[] = {
{"rdmac", 0644, FOPS(lbs_rdmac_read, lbs_rdmac_write), },
{"wrmac", 0600, FOPS(NULL, lbs_wrmac_write), },
{"rdbbp", 0644, FOPS(lbs_rdbbp_read, lbs_rdbbp_write), },
@@ -735,7 +735,7 @@ void lbs_debugfs_remove(void)
void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev)
{
int i;
- struct lbs_debugfs_files *files;
+ const struct lbs_debugfs_files *files;
if (!lbs_dir)
goto exit;
@@ -938,7 +938,7 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf,
return (ssize_t)cnt;
}
-static struct file_operations lbs_debug_fops = {
+static const struct file_operations lbs_debug_fops = {
.owner = THIS_MODULE,
.open = open_file_generic,
.write = lbs_debugfs_write,
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index c364e4c01d1b..e8dfde39abfc 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -41,6 +41,7 @@
#define LBS_DEB_HEX 0x00200000
#define LBS_DEB_SDIO 0x00400000
#define LBS_DEB_SYSFS 0x00800000
+#define LBS_DEB_SPI 0x01000000
extern unsigned int lbs_debug;
@@ -84,6 +85,7 @@ do { if ((lbs_debug & (grp)) == (grp)) \
#define lbs_deb_thread(fmt, args...) LBS_DEB_LL(LBS_DEB_THREAD, " thread", fmt, ##args)
#define lbs_deb_sdio(fmt, args...) LBS_DEB_LL(LBS_DEB_SDIO, " sdio", fmt, ##args)
#define lbs_deb_sysfs(fmt, args...) LBS_DEB_LL(LBS_DEB_SYSFS, " sysfs", fmt, ##args)
+#define lbs_deb_spi(fmt, args...) LBS_DEB_LL(LBS_DEB_SPI, " spi", fmt, ##args)
#define lbs_pr_info(format, args...) \
printk(KERN_INFO DRV_NAME": " format, ## args)
@@ -263,6 +265,7 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
#define CMD_F_HOSTCMD (1 << 0)
#define FW_CAPINFO_WPA (1 << 0)
+#define FW_CAPINFO_PS (1 << 1)
#define FW_CAPINFO_FIRMWARE_UPGRADE (1 << 13)
#define FW_CAPINFO_BOOT2_UPGRADE (1<<14)
#define FW_CAPINFO_PERSISTENT_CONFIG (1<<15)
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index dd682c4cfde8..27e81fd97c94 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -109,7 +109,6 @@ struct lbs_private {
void *card;
struct net_device *dev;
- struct net_device_stats stats;
struct net_device *mesh_dev; /* Virtual device */
struct net_device *rtap_net_dev;
diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h
index 277ff1975bde..d4457ef808a6 100644
--- a/drivers/net/wireless/libertas/host.h
+++ b/drivers/net/wireless/libertas/host.h
@@ -66,6 +66,7 @@
#define CMD_802_11_LED_GPIO_CTRL 0x004e
#define CMD_802_11_EEPROM_ACCESS 0x0059
#define CMD_802_11_BAND_CONFIG 0x0058
+#define CMD_GSPI_BUS_CONFIG 0x005a
#define CMD_802_11D_DOMAIN_INFO 0x005b
#define CMD_802_11_KEY_MATERIAL 0x005e
#define CMD_802_11_SLEEP_PARAMS 0x0066
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index f6a79a653b7b..a899aeb676bb 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -221,6 +221,14 @@ struct cmd_ds_mac_multicast_adr {
u8 maclist[ETH_ALEN * MRVDRV_MAX_MULTICAST_LIST_SIZE];
} __attribute__ ((packed));
+struct cmd_ds_gspi_bus_config {
+ struct cmd_header hdr;
+ __le16 action;
+ __le16 bus_delay_mode;
+ __le16 host_time_delay_to_read_port;
+ __le16 host_time_delay_to_read_register;
+} __attribute__ ((packed));
+
struct cmd_ds_802_11_authenticate {
u8 macaddr[ETH_ALEN];
u8 authtype;
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 842a08d1f106..cedeac6322fe 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -151,7 +151,7 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
for (i = 0; i < 100000; i++) {
u8 val = if_cs_read8(card, addr);
if (val == reg)
- return i;
+ return 0;
udelay(5);
}
return -ETIME;
@@ -421,7 +421,7 @@ static struct sk_buff *if_cs_receive_data(struct lbs_private *priv)
len = if_cs_read16(priv->card, IF_CS_READ_LEN);
if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", len);
- priv->stats.rx_dropped++;
+ priv->dev->stats.rx_dropped++;
goto dat_err;
}
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 4519d7314f47..76f4c653d641 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -95,6 +95,8 @@ struct if_sdio_card {
spinlock_t lock;
struct if_sdio_packet *packets;
+
+ struct workqueue_struct *workqueue;
struct work_struct packet_worker;
};
@@ -209,6 +211,9 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
event = sdio_readb(card->func, IF_SDIO_EVENT, &ret);
if (ret)
goto out;
+
+ /* right shift 3 bits to get the event id */
+ event >>= 3;
} else {
if (size < 4) {
lbs_deb_sdio("event packet too small (%d bytes)\n",
@@ -743,7 +748,7 @@ static int if_sdio_host_to_card(struct lbs_private *priv,
spin_unlock_irqrestore(&card->lock, flags);
- schedule_work(&card->packet_worker);
+ queue_work(card->workqueue, &card->packet_worker);
ret = 0;
@@ -833,6 +838,7 @@ static int if_sdio_probe(struct sdio_func *func,
card->func = func;
card->model = model;
spin_lock_init(&card->lock);
+ card->workqueue = create_workqueue("libertas_sdio");
INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) {
@@ -921,15 +927,17 @@ static int if_sdio_probe(struct sdio_func *func,
if (ret)
goto err_activate_card;
+ if (priv->fwcapinfo & FW_CAPINFO_PS)
+ priv->ps_supported = 1;
+
out:
lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
return ret;
err_activate_card:
- flush_scheduled_work();
- free_netdev(priv->dev);
- kfree(priv);
+ flush_workqueue(card->workqueue);
+ lbs_remove_card(priv);
reclaim:
sdio_claim_host(func);
release_int:
@@ -939,6 +947,7 @@ disable:
release:
sdio_release_host(func);
free:
+ destroy_workqueue(card->workqueue);
while (card->packets) {
packet = card->packets;
card->packets = card->packets->next;
@@ -965,7 +974,8 @@ static void if_sdio_remove(struct sdio_func *func)
lbs_stop_card(card->priv);
lbs_remove_card(card->priv);
- flush_scheduled_work();
+ flush_workqueue(card->workqueue);
+ destroy_workqueue(card->workqueue);
sdio_claim_host(func);
sdio_release_irq(func);
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
new file mode 100644
index 000000000000..07311e71af92
--- /dev/null
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -0,0 +1,1218 @@
+/*
+ * linux/drivers/net/wireless/libertas/if_spi.c
+ *
+ * Driver for Marvell SPI WLAN cards.
+ *
+ * Copyright 2008 Analog Devices Inc.
+ *
+ * Authors:
+ * Andrey Yurovsky <andrey@cozybit.com>
+ * Colin McCabe <colin@cozybit.com>
+ *
+ * Inspired by if_sdio.c, Copyright 2007-2008 Pierre Ossman
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <linux/gpio.h>
+#include <linux/jiffies.h>
+#include <linux/kthread.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/spi/libertas_spi.h>
+#include <linux/spi/spi.h>
+
+#include "host.h"
+#include "decl.h"
+#include "defs.h"
+#include "dev.h"
+#include "if_spi.h"
+
+struct if_spi_packet {
+ struct list_head list;
+ u16 blen;
+ u8 buffer[0] __attribute__((aligned(4)));
+};
+
+struct if_spi_card {
+ struct spi_device *spi;
+ struct lbs_private *priv;
+ struct libertas_spi_platform_data *pdata;
+
+ char helper_fw_name[FIRMWARE_NAME_MAX];
+ char main_fw_name[FIRMWARE_NAME_MAX];
+
+ /* The card ID and card revision, as reported by the hardware. */
+ u16 card_id;
+ u8 card_rev;
+
+ /* Pin number for our GPIO chip-select. */
+ /* TODO: Once the generic SPI layer has some additional features, we
+ * should take this out and use the normal chip select here.
+ * We need support for chip select delays, and not dropping chipselect
+ * after each word. */
+ int gpio_cs;
+
+ /* The last time that we initiated an SPU operation */
+ unsigned long prev_xfer_time;
+
+ int use_dummy_writes;
+ unsigned long spu_port_delay;
+ unsigned long spu_reg_delay;
+
+ /* Handles all SPI communication (except for FW load) */
+ struct task_struct *spi_thread;
+ int run_thread;
+
+ /* Used to wake up the spi_thread */
+ struct semaphore spi_ready;
+ struct semaphore spi_thread_terminated;
+
+ u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE];
+
+ /* A buffer of incoming packets from libertas core.
+ * Since we can't sleep in hw_host_to_card, we have to buffer
+ * them. */
+ struct list_head cmd_packet_list;
+ struct list_head data_packet_list;
+
+ /* Protects cmd_packet_list and data_packet_list */
+ spinlock_t buffer_lock;
+};
+
+static void free_if_spi_card(struct if_spi_card *card)
+{
+ struct list_head *cursor, *next;
+ struct if_spi_packet *packet;
+
+ BUG_ON(card->run_thread);
+ list_for_each_safe(cursor, next, &card->cmd_packet_list) {
+ packet = container_of(cursor, struct if_spi_packet, list);
+ list_del(&packet->list);
+ kfree(packet);
+ }
+ list_for_each_safe(cursor, next, &card->data_packet_list) {
+ packet = container_of(cursor, struct if_spi_packet, list);
+ list_del(&packet->list);
+ kfree(packet);
+ }
+ spi_set_drvdata(card->spi, NULL);
+ kfree(card);
+}
+
+static struct chip_ident chip_id_to_device_name[] = {
+ { .chip_id = 0x04, .name = 8385 },
+ { .chip_id = 0x0b, .name = 8686 },
+};
+
+/*
+ * SPI Interface Unit Routines
+ *
+ * The SPU sits between the host and the WLAN module.
+ * All communication with the firmware is through SPU transactions.
+ *
+ * First we have to put a SPU register name on the bus. Then we can
+ * either read from or write to that register.
+ *
+ * For 16-bit transactions, byte order on the bus is big-endian.
+ * We don't have to worry about that here, though.
+ * The translation takes place in the SPI routines.
+ */
+
+static void spu_transaction_init(struct if_spi_card *card)
+{
+ if (!time_after(jiffies, card->prev_xfer_time + 1)) {
+ /* Unfortunately, the SPU requires a delay between successive
+ * transactions. If our last transaction was more than a jiffy
+ * ago, we have obviously already delayed enough.
+ * If not, we have to busy-wait to be on the safe side. */
+ ndelay(400);
+ }
+ gpio_set_value(card->gpio_cs, 0); /* assert CS */
+}
+
+static void spu_transaction_finish(struct if_spi_card *card)
+{
+ gpio_set_value(card->gpio_cs, 1); /* drop CS */
+ card->prev_xfer_time = jiffies;
+}
+
+/* Write out a byte buffer to an SPI register,
+ * using a series of 16-bit transfers. */
+static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
+{
+ int err = 0;
+ u16 reg_out = reg | IF_SPI_WRITE_OPERATION_MASK;
+
+ /* You must give an even number of bytes to the SPU, even if it
+ * doesn't care about the last one. */
+ BUG_ON(len & 0x1);
+
+ spu_transaction_init(card);
+
+ /* write SPU register index */
+ err = spi_write(card->spi, (u8 *)&reg_out, sizeof(u16));
+ if (err)
+ goto out;
+
+ err = spi_write(card->spi, buf, len);
+
+out:
+ spu_transaction_finish(card);
+ return err;
+}
+
+static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val)
+{
+ return spu_write(card, reg, (u8 *)&val, sizeof(u16));
+}
+
+static inline int spu_write_u32(struct if_spi_card *card, u16 reg, u32 val)
+{
+ /* The lower 16 bits are written first. */
+ u16 out[2];
+ out[0] = val & 0xffff;
+ out[1] = (val & 0xffff0000) >> 16;
+ return spu_write(card, reg, (u8 *)&out, sizeof(u32));
+}
+
+static inline int spu_reg_is_port_reg(u16 reg)
+{
+ switch (reg) {
+ case IF_SPI_IO_RDWRPORT_REG:
+ case IF_SPI_CMD_RDWRPORT_REG:
+ case IF_SPI_DATA_RDWRPORT_REG:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
+{
+ unsigned int i, delay;
+ int err = 0;
+ u16 zero = 0;
+ u16 reg_out = reg | IF_SPI_READ_OPERATION_MASK;
+
+ /* You must take an even number of bytes from the SPU, even if you
+ * don't care about the last one. */
+ BUG_ON(len & 0x1);
+
+ spu_transaction_init(card);
+
+ /* write SPU register index */
+ err = spi_write(card->spi, (u8 *)&reg_out, sizeof(u16));
+ if (err)
+ goto out;
+
+ delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay :
+ card->spu_reg_delay;
+ if (card->use_dummy_writes) {
+ /* Clock in dummy cycles while the SPU fills the FIFO */
+ for (i = 0; i < delay / 16; ++i) {
+ err = spi_write(card->spi, (u8 *)&zero, sizeof(u16));
+ if (err)
+ return err;
+ }
+ } else {
+ /* Busy-wait while the SPU fills the FIFO */
+ ndelay(100 + (delay * 10));
+ }
+
+ /* read in data */
+ err = spi_read(card->spi, buf, len);
+
+out:
+ spu_transaction_finish(card);
+ return err;
+}
+
+/* Read 16 bits from an SPI register */
+static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
+{
+ return spu_read(card, reg, (u8 *)val, sizeof(u16));
+}
+
+/* Read 32 bits from an SPI register.
+ * The low 16 bits are read first. */
+static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
+{
+ u16 buf[2];
+ int err;
+ err = spu_read(card, reg, (u8 *)buf, sizeof(u32));
+ if (!err)
+ *val = buf[0] | (buf[1] << 16);
+ return err;
+}
+
+/* Keep reading 16 bits from an SPI register until you get the correct result.
+ *
+ * If mask = 0, the correct result is any non-zero number.
+ * If mask != 0, the correct result is any number where
+ * number & target_mask == target
+ *
+ * Returns -ETIMEDOUT if a second passes without the correct result. */
+static int spu_wait_for_u16(struct if_spi_card *card, u16 reg,
+ u16 target_mask, u16 target)
+{
+ int err;
+ unsigned long timeout = jiffies + 5*HZ;
+ while (1) {
+ u16 val;
+ err = spu_read_u16(card, reg, &val);
+ if (err)
+ return err;
+ if (target_mask) {
+ if ((val & target_mask) == target)
+ return 0;
+ } else {
+ if (val)
+ return 0;
+ }
+ udelay(100);
+ if (time_after(jiffies, timeout)) {
+ lbs_pr_err("%s: timeout with val=%02x, "
+ "target_mask=%02x, target=%02x\n",
+ __func__, val, target_mask, target);
+ return -ETIMEDOUT;
+ }
+ }
+}
+
+/* Read 16 bits from an SPI register until you receive a specific value.
+ * Returns -ETIMEDOUT if a 4 tries pass without success. */
+static int spu_wait_for_u32(struct if_spi_card *card, u32 reg, u32 target)
+{
+ int err, try;
+ for (try = 0; try < 4; ++try) {
+ u32 val = 0;
+ err = spu_read_u32(card, reg, &val);
+ if (err)
+ return err;
+ if (val == target)
+ return 0;
+ mdelay(100);
+ }
+ return -ETIMEDOUT;
+}
+
+static int spu_set_interrupt_mode(struct if_spi_card *card,
+ int suppress_host_int,
+ int auto_int)
+{
+ int err = 0;
+
+ /* We can suppress a host interrupt by clearing the appropriate
+ * bit in the "host interrupt status mask" register */
+ if (suppress_host_int) {
+ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0);
+ if (err)
+ return err;
+ } else {
+ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG,
+ IF_SPI_HISM_TX_DOWNLOAD_RDY |
+ IF_SPI_HISM_RX_UPLOAD_RDY |
+ IF_SPI_HISM_CMD_DOWNLOAD_RDY |
+ IF_SPI_HISM_CARDEVENT |
+ IF_SPI_HISM_CMD_UPLOAD_RDY);
+ if (err)
+ return err;
+ }
+
+ /* If auto-interrupts are on, the completion of certain transactions
+ * will trigger an interrupt automatically. If auto-interrupts
+ * are off, we need to set the "Card Interrupt Cause" register to
+ * trigger a card interrupt. */
+ if (auto_int) {
+ err = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG,
+ IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO |
+ IF_SPI_HICT_RX_UPLOAD_OVER_AUTO |
+ IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO |
+ IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO);
+ if (err)
+ return err;
+ } else {
+ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0);
+ if (err)
+ return err;
+ }
+ return err;
+}
+
+static int spu_get_chip_revision(struct if_spi_card *card,
+ u16 *card_id, u8 *card_rev)
+{
+ int err = 0;
+ u32 dev_ctrl;
+ err = spu_read_u32(card, IF_SPI_DEVICEID_CTRL_REG, &dev_ctrl);
+ if (err)
+ return err;
+ *card_id = IF_SPI_DEVICEID_CTRL_REG_TO_CARD_ID(dev_ctrl);
+ *card_rev = IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dev_ctrl);
+ return err;
+}
+
+static int spu_set_bus_mode(struct if_spi_card *card, u16 mode)
+{
+ int err = 0;
+ u16 rval;
+ /* set bus mode */
+ err = spu_write_u16(card, IF_SPI_SPU_BUS_MODE_REG, mode);
+ if (err)
+ return err;
+ /* Check that we were able to read back what we just wrote. */
+ err = spu_read_u16(card, IF_SPI_SPU_BUS_MODE_REG, &rval);
+ if (err)
+ return err;
+ if (rval != mode) {
+ lbs_pr_err("Can't read bus mode register.\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+static int spu_init(struct if_spi_card *card, int use_dummy_writes)
+{
+ int err = 0;
+ u32 delay;
+
+ /* We have to start up in timed delay mode so that we can safely
+ * read the Delay Read Register. */
+ card->use_dummy_writes = 0;
+ err = spu_set_bus_mode(card,
+ IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING |
+ IF_SPI_BUS_MODE_DELAY_METHOD_TIMED |
+ IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA);
+ if (err)
+ return err;
+ card->spu_port_delay = 1000;
+ card->spu_reg_delay = 1000;
+ err = spu_read_u32(card, IF_SPI_DELAY_READ_REG, &delay);
+ if (err)
+ return err;
+ card->spu_port_delay = delay & 0x0000ffff;
+ card->spu_reg_delay = (delay & 0xffff0000) >> 16;
+
+ /* If dummy clock delay mode has been requested, switch to it now */
+ if (use_dummy_writes) {
+ card->use_dummy_writes = 1;
+ err = spu_set_bus_mode(card,
+ IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING |
+ IF_SPI_BUS_MODE_DELAY_METHOD_DUMMY_CLOCK |
+ IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA);
+ if (err)
+ return err;
+ }
+
+ lbs_deb_spi("Initialized SPU unit. "
+ "spu_port_delay=0x%04lx, spu_reg_delay=0x%04lx\n",
+ card->spu_port_delay, card->spu_reg_delay);
+ return err;
+}
+
+/*
+ * Firmware Loading
+ */
+
+static int if_spi_prog_helper_firmware(struct if_spi_card *card)
+{
+ int err = 0;
+ const struct firmware *firmware = NULL;
+ int bytes_remaining;
+ const u8 *fw;
+ u8 temp[HELPER_FW_LOAD_CHUNK_SZ];
+ struct spi_device *spi = card->spi;
+
+ lbs_deb_enter(LBS_DEB_SPI);
+
+ err = spu_set_interrupt_mode(card, 1, 0);
+ if (err)
+ goto out;
+ /* Get helper firmware image */
+ err = request_firmware(&firmware, card->helper_fw_name, &spi->dev);
+ if (err) {
+ lbs_pr_err("request_firmware failed with err = %d\n", err);
+ goto out;
+ }
+ bytes_remaining = firmware->size;
+ fw = firmware->data;
+
+ /* Load helper firmware image */
+ while (bytes_remaining > 0) {
+ /* Scratch pad 1 should contain the number of bytes we
+ * want to download to the firmware */
+ err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG,
+ HELPER_FW_LOAD_CHUNK_SZ);
+ if (err)
+ goto release_firmware;
+
+ err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG,
+ IF_SPI_HIST_CMD_DOWNLOAD_RDY,
+ IF_SPI_HIST_CMD_DOWNLOAD_RDY);
+ if (err)
+ goto release_firmware;
+
+ /* Feed the data into the command read/write port reg
+ * in chunks of 64 bytes */
+ memset(temp, 0, sizeof(temp));
+ memcpy(temp, fw,
+ min(bytes_remaining, HELPER_FW_LOAD_CHUNK_SZ));
+ mdelay(10);
+ err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
+ temp, HELPER_FW_LOAD_CHUNK_SZ);
+ if (err)
+ goto release_firmware;
+
+ /* Interrupt the boot code */
+ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
+ if (err)
+ goto release_firmware;
+ err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
+ IF_SPI_CIC_CMD_DOWNLOAD_OVER);
+ if (err)
+ goto release_firmware;
+ bytes_remaining -= HELPER_FW_LOAD_CHUNK_SZ;
+ fw += HELPER_FW_LOAD_CHUNK_SZ;
+ }
+
+ /* Once the helper / single stage firmware download is complete,
+ * write 0 to scratch pad 1 and interrupt the
+ * bootloader. This completes the helper download. */
+ err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK);
+ if (err)
+ goto release_firmware;
+ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
+ if (err)
+ goto release_firmware;
+ err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG,
+ IF_SPI_CIC_CMD_DOWNLOAD_OVER);
+ goto release_firmware;
+
+ lbs_deb_spi("waiting for helper to boot...\n");
+
+release_firmware:
+ release_firmware(firmware);
+out:
+ if (err)
+ lbs_pr_err("failed to load helper firmware (err=%d)\n", err);
+ lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
+ return err;
+}
+
+/* Returns the length of the next packet the firmware expects us to send
+ * Sets crc_err if the previous transfer had a CRC error. */
+static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
+ int *crc_err)
+{
+ u16 len;
+ int err = 0;
+
+ /* wait until the host interrupt status register indicates
+ * that we are ready to download */
+ err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG,
+ IF_SPI_HIST_CMD_DOWNLOAD_RDY,
+ IF_SPI_HIST_CMD_DOWNLOAD_RDY);
+ if (err) {
+ lbs_pr_err("timed out waiting for host_int_status\n");
+ return err;
+ }
+
+ /* Ask the device how many bytes of firmware it wants. */
+ err = spu_read_u16(card, IF_SPI_SCRATCH_1_REG, &len);
+ if (err)
+ return err;
+
+ if (len > IF_SPI_CMD_BUF_SIZE) {
+ lbs_pr_err("firmware load device requested a larger "
+ "tranfer than we are prepared to "
+ "handle. (len = %d)\n", len);
+ return -EIO;
+ }
+ if (len & 0x1) {
+ lbs_deb_spi("%s: crc error\n", __func__);
+ len &= ~0x1;
+ *crc_err = 1;
+ } else
+ *crc_err = 0;
+
+ return len;
+}
+
+static int if_spi_prog_main_firmware(struct if_spi_card *card)
+{
+ int len, prev_len;
+ int bytes, crc_err = 0, err = 0;
+ const struct firmware *firmware = NULL;
+ const u8 *fw;
+ struct spi_device *spi = card->spi;
+ u16 num_crc_errs;
+
+ lbs_deb_enter(LBS_DEB_SPI);
+
+ err = spu_set_interrupt_mode(card, 1, 0);
+ if (err)
+ goto out;
+
+ /* Get firmware image */
+ err = request_firmware(&firmware, card->main_fw_name, &spi->dev);
+ if (err) {
+ lbs_pr_err("%s: can't get firmware '%s' from kernel. "
+ "err = %d\n", __func__, card->main_fw_name, err);
+ goto out;
+ }
+
+ err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0);
+ if (err) {
+ lbs_pr_err("%s: timed out waiting for initial "
+ "scratch reg = 0\n", __func__);
+ goto release_firmware;
+ }
+
+ num_crc_errs = 0;
+ prev_len = 0;
+ bytes = firmware->size;
+ fw = firmware->data;
+ while ((len = if_spi_prog_main_firmware_check_len(card, &crc_err))) {
+ if (len < 0) {
+ err = len;
+ goto release_firmware;
+ }
+ if (bytes < 0) {
+ /* If there are no more bytes left, we would normally
+ * expect to have terminated with len = 0 */
+ lbs_pr_err("Firmware load wants more bytes "
+ "than we have to offer.\n");
+ break;
+ }
+ if (crc_err) {
+ /* Previous transfer failed. */
+ if (++num_crc_errs > MAX_MAIN_FW_LOAD_CRC_ERR) {
+ lbs_pr_err("Too many CRC errors encountered "
+ "in firmware load.\n");
+ err = -EIO;
+ goto release_firmware;
+ }
+ } else {
+ /* Previous transfer succeeded. Advance counters. */
+ bytes -= prev_len;
+ fw += prev_len;
+ }
+ if (bytes < len) {
+ memset(card->cmd_buffer, 0, len);
+ memcpy(card->cmd_buffer, fw, bytes);
+ } else
+ memcpy(card->cmd_buffer, fw, len);
+
+ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0);
+ if (err)
+ goto release_firmware;
+ err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG,
+ card->cmd_buffer, len);
+ if (err)
+ goto release_firmware;
+ err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG ,
+ IF_SPI_CIC_CMD_DOWNLOAD_OVER);
+ if (err)
+ goto release_firmware;
+ prev_len = len;
+ }
+ if (bytes > prev_len) {
+ lbs_pr_err("firmware load wants fewer bytes than "
+ "we have to offer.\n");
+ }
+
+ /* Confirm firmware download */
+ err = spu_wait_for_u32(card, IF_SPI_SCRATCH_4_REG,
+ SUCCESSFUL_FW_DOWNLOAD_MAGIC);
+ if (err) {
+ lbs_pr_err("failed to confirm the firmware download\n");
+ goto release_firmware;
+ }
+
+release_firmware:
+ release_firmware(firmware);
+
+out:
+ if (err)
+ lbs_pr_err("failed to load firmware (err=%d)\n", err);
+ lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
+ return err;
+}
+
+/*
+ * SPI Transfer Thread
+ *
+ * The SPI thread handles all SPI transfers, so there is no need for a lock.
+ */
+
+/* Move a command from the card to the host */
+static int if_spi_c2h_cmd(struct if_spi_card *card)
+{
+ struct lbs_private *priv = card->priv;
+ unsigned long flags;
+ int err = 0;
+ u16 len;
+ u8 i;
+
+ /* We need a buffer big enough to handle whatever people send to
+ * hw_host_to_card */
+ BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE);
+ BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE);
+
+ /* It's just annoying if the buffer size isn't a multiple of 4, because
+ * then we might have len < IF_SPI_CMD_BUF_SIZE but
+ * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE */
+ BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0);
+
+ lbs_deb_enter(LBS_DEB_SPI);
+
+ /* How many bytes are there to read? */
+ err = spu_read_u16(card, IF_SPI_SCRATCH_2_REG, &len);
+ if (err)
+ goto out;
+ if (!len) {
+ lbs_pr_err("%s: error: card has no data for host\n",
+ __func__);
+ err = -EINVAL;
+ goto out;
+ } else if (len > IF_SPI_CMD_BUF_SIZE) {
+ lbs_pr_err("%s: error: response packet too large: "
+ "%d bytes, but maximum is %d\n",
+ __func__, len, IF_SPI_CMD_BUF_SIZE);
+ err = -EINVAL;
+ goto out;
+ }
+
+ /* Read the data from the WLAN module into our command buffer */
+ err = spu_read(card, IF_SPI_CMD_RDWRPORT_REG,
+ card->cmd_buffer, ALIGN(len, 4));
+ if (err)
+ goto out;
+
+ spin_lock_irqsave(&priv->driver_lock, flags);
+ i = (priv->resp_idx == 0) ? 1 : 0;
+ BUG_ON(priv->resp_len[i]);
+ priv->resp_len[i] = len;
+ memcpy(priv->resp_buf[i], card->cmd_buffer, len);
+ lbs_notify_command_response(priv, i);
+ spin_unlock_irqrestore(&priv->driver_lock, flags);
+
+out:
+ if (err)
+ lbs_pr_err("%s: err=%d\n", __func__, err);
+ lbs_deb_leave(LBS_DEB_SPI);
+ return err;
+}
+
+/* Move data from the card to the host */
+static int if_spi_c2h_data(struct if_spi_card *card)
+{
+ struct sk_buff *skb;
+ char *data;
+ u16 len;
+ int err = 0;
+
+ lbs_deb_enter(LBS_DEB_SPI);
+
+ /* How many bytes are there to read? */
+ err = spu_read_u16(card, IF_SPI_SCRATCH_1_REG, &len);
+ if (err)
+ goto out;
+ if (!len) {
+ lbs_pr_err("%s: error: card has no data for host\n",
+ __func__);
+ err = -EINVAL;
+ goto out;
+ } else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
+ lbs_pr_err("%s: error: card has %d bytes of data, but "
+ "our maximum skb size is %u\n",
+ __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
+ err = -EINVAL;
+ goto out;
+ }
+
+ /* TODO: should we allocate a smaller skb if we have less data? */
+ skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
+ if (!skb) {
+ err = -ENOBUFS;
+ goto out;
+ }
+ skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
+ data = skb_put(skb, len);
+
+ /* Read the data from the WLAN module into our skb... */
+ err = spu_read(card, IF_SPI_DATA_RDWRPORT_REG, data, ALIGN(len, 4));
+ if (err)
+ goto free_skb;
+
+ /* pass the SKB to libertas */
+ err = lbs_process_rxed_packet(card->priv, skb);
+ if (err)
+ goto free_skb;
+
+ /* success */
+ goto out;
+
+free_skb:
+ dev_kfree_skb(skb);
+out:
+ if (err)
+ lbs_pr_err("%s: err=%d\n", __func__, err);
+ lbs_deb_leave(LBS_DEB_SPI);
+ return err;
+}
+
+/* Move data or a command from the host to the card. */
+static void if_spi_h2c(struct if_spi_card *card,
+ struct if_spi_packet *packet, int type)
+{
+ int err = 0;
+ u16 int_type, port_reg;
+
+ switch (type) {
+ case MVMS_DAT:
+ int_type = IF_SPI_CIC_TX_DOWNLOAD_OVER;
+ port_reg = IF_SPI_DATA_RDWRPORT_REG;
+ break;
+ case MVMS_CMD:
+ int_type = IF_SPI_CIC_CMD_DOWNLOAD_OVER;
+ port_reg = IF_SPI_CMD_RDWRPORT_REG;
+ break;
+ default:
+ lbs_pr_err("can't transfer buffer of type %d\n", type);
+ err = -EINVAL;
+ goto out;
+ }
+
+ /* Write the data to the card */
+ err = spu_write(card, port_reg, packet->buffer, packet->blen);
+ if (err)
+ goto out;
+
+out:
+ kfree(packet);
+
+ if (err)
+ lbs_pr_err("%s: error %d\n", __func__, err);
+}
+
+/* Inform the host about a card event */
+static void if_spi_e2h(struct if_spi_card *card)
+{
+ int err = 0;
+ unsigned long flags;
+ u32 cause;
+ struct lbs_private *priv = card->priv;
+
+ err = spu_read_u32(card, IF_SPI_SCRATCH_3_REG, &cause);
+ if (err)
+ goto out;
+
+ spin_lock_irqsave(&priv->driver_lock, flags);
+ lbs_queue_event(priv, cause & 0xff);
+ spin_unlock_irqrestore(&priv->driver_lock, flags);
+
+out:
+ if (err)
+ lbs_pr_err("%s: error %d\n", __func__, err);
+}
+
+static int lbs_spi_thread(void *data)
+{
+ int err;
+ struct if_spi_card *card = data;
+ u16 hiStatus;
+ unsigned long flags;
+ struct if_spi_packet *packet;
+
+ while (1) {
+ /* Wait to be woken up by one of two things. First, our ISR
+ * could tell us that something happened on the WLAN.
+ * Secondly, libertas could call hw_host_to_card with more
+ * data, which we might be able to send.
+ */
+ do {
+ err = down_interruptible(&card->spi_ready);
+ if (!card->run_thread) {
+ up(&card->spi_thread_terminated);
+ do_exit(0);
+ }
+ } while (err == EINTR);
+
+ /* Read the host interrupt status register to see what we
+ * can do. */
+ err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG,
+ &hiStatus);
+ if (err) {
+ lbs_pr_err("I/O error\n");
+ goto err;
+ }
+
+ if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY)
+ err = if_spi_c2h_cmd(card);
+ if (err)
+ goto err;
+ if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY)
+ err = if_spi_c2h_data(card);
+ if (err)
+ goto err;
+ if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY) {
+ /* This means two things. First of all,
+ * if there was a previous command sent, the card has
+ * successfully received it.
+ * Secondly, it is now ready to download another
+ * command.
+ */
+ lbs_host_to_card_done(card->priv);
+
+ /* Do we have any command packets from the host to
+ * send? */
+ packet = NULL;
+ spin_lock_irqsave(&card->buffer_lock, flags);
+ if (!list_empty(&card->cmd_packet_list)) {
+ packet = (struct if_spi_packet *)(card->
+ cmd_packet_list.next);
+ list_del(&packet->list);
+ }
+ spin_unlock_irqrestore(&card->buffer_lock, flags);
+
+ if (packet)
+ if_spi_h2c(card, packet, MVMS_CMD);
+ }
+ if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) {
+ /* Do we have any data packets from the host to
+ * send? */
+ packet = NULL;
+ spin_lock_irqsave(&card->buffer_lock, flags);
+ if (!list_empty(&card->data_packet_list)) {
+ packet = (struct if_spi_packet *)(card->
+ data_packet_list.next);
+ list_del(&packet->list);
+ }
+ spin_unlock_irqrestore(&card->buffer_lock, flags);
+
+ if (packet)
+ if_spi_h2c(card, packet, MVMS_DAT);
+ }
+ if (hiStatus & IF_SPI_HIST_CARD_EVENT)
+ if_spi_e2h(card);
+
+err:
+ if (err)
+ lbs_pr_err("%s: got error %d\n", __func__, err);
+ }
+}
+
+/* Block until lbs_spi_thread thread has terminated */
+static void if_spi_terminate_spi_thread(struct if_spi_card *card)
+{
+ /* It would be nice to use kthread_stop here, but that function
+ * can't wake threads waiting for a semaphore. */
+ card->run_thread = 0;
+ up(&card->spi_ready);
+ down(&card->spi_thread_terminated);
+}
+
+/*
+ * Host to Card
+ *
+ * Called from Libertas to transfer some data to the WLAN device
+ * We can't sleep here. */
+static int if_spi_host_to_card(struct lbs_private *priv,
+ u8 type, u8 *buf, u16 nb)
+{
+ int err = 0;
+ unsigned long flags;
+ struct if_spi_card *card = priv->card;
+ struct if_spi_packet *packet;
+ u16 blen;
+
+ lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb);
+
+ if (nb == 0) {
+ lbs_pr_err("%s: invalid size requested: %d\n", __func__, nb);
+ err = -EINVAL;
+ goto out;
+ }
+ blen = ALIGN(nb, 4);
+ packet = kzalloc(sizeof(struct if_spi_packet) + blen, GFP_ATOMIC);
+ if (!packet) {
+ err = -ENOMEM;
+ goto out;
+ }
+ packet->blen = blen;
+ memcpy(packet->buffer, buf, nb);
+ memset(packet->buffer + nb, 0, blen - nb);
+
+ switch (type) {
+ case MVMS_CMD:
+ priv->dnld_sent = DNLD_CMD_SENT;
+ spin_lock_irqsave(&card->buffer_lock, flags);
+ list_add_tail(&packet->list, &card->cmd_packet_list);
+ spin_unlock_irqrestore(&card->buffer_lock, flags);
+ break;
+ case MVMS_DAT:
+ priv->dnld_sent = DNLD_DATA_SENT;
+ spin_lock_irqsave(&card->buffer_lock, flags);
+ list_add_tail(&packet->list, &card->data_packet_list);
+ spin_unlock_irqrestore(&card->buffer_lock, flags);
+ break;
+ default:
+ lbs_pr_err("can't transfer buffer of type %d", type);
+ err = -EINVAL;
+ break;
+ }
+
+ /* Wake up the spi thread */
+ up(&card->spi_ready);
+out:
+ lbs_deb_leave_args(LBS_DEB_SPI, "err=%d", err);
+ return err;
+}
+
+/*
+ * Host Interrupts
+ *
+ * Service incoming interrupts from the WLAN device. We can't sleep here, so
+ * don't try to talk on the SPI bus, just wake up the SPI thread.
+ */
+static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id)
+{
+ struct if_spi_card *card = dev_id;
+
+ up(&card->spi_ready);
+ return IRQ_HANDLED;
+}
+
+/*
+ * SPI callbacks
+ */
+
+static int if_spi_calculate_fw_names(u16 card_id,
+ char *helper_fw, char *main_fw)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(chip_id_to_device_name); ++i) {
+ if (card_id == chip_id_to_device_name[i].chip_id)
+ break;
+ }
+ if (i == ARRAY_SIZE(chip_id_to_device_name)) {
+ lbs_pr_err("Unsupported chip_id: 0x%02x\n", card_id);
+ return -EAFNOSUPPORT;
+ }
+ snprintf(helper_fw, FIRMWARE_NAME_MAX, "libertas/gspi%d_hlp.bin",
+ chip_id_to_device_name[i].name);
+ snprintf(main_fw, FIRMWARE_NAME_MAX, "libertas/gspi%d.bin",
+ chip_id_to_device_name[i].name);
+ return 0;
+}
+
+static int __devinit if_spi_probe(struct spi_device *spi)
+{
+ struct if_spi_card *card;
+ struct lbs_private *priv = NULL;
+ struct libertas_spi_platform_data *pdata = spi->dev.platform_data;
+ int err = 0;
+ u32 scratch;
+
+ lbs_deb_enter(LBS_DEB_SPI);
+
+ if (!pdata) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (pdata->setup) {
+ err = pdata->setup(spi);
+ if (err)
+ goto out;
+ }
+
+ /* Allocate card structure to represent this specific device */
+ card = kzalloc(sizeof(struct if_spi_card), GFP_KERNEL);
+ if (!card) {
+ err = -ENOMEM;
+ goto out;
+ }
+ spi_set_drvdata(spi, card);
+ card->pdata = pdata;
+ card->spi = spi;
+ card->gpio_cs = pdata->gpio_cs;
+ card->prev_xfer_time = jiffies;
+
+ sema_init(&card->spi_ready, 0);
+ sema_init(&card->spi_thread_terminated, 0);
+ INIT_LIST_HEAD(&card->cmd_packet_list);
+ INIT_LIST_HEAD(&card->data_packet_list);
+ spin_lock_init(&card->buffer_lock);
+
+ /* set up GPIO CS line. TODO: use regular CS line */
+ err = gpio_request(card->gpio_cs, "if_spi_gpio_chip_select");
+ if (err)
+ goto free_card;
+ err = gpio_direction_output(card->gpio_cs, 1);
+ if (err)
+ goto free_gpio;
+
+ /* Initialize the SPI Interface Unit */
+ err = spu_init(card, pdata->use_dummy_writes);
+ if (err)
+ goto free_gpio;
+ err = spu_get_chip_revision(card, &card->card_id, &card->card_rev);
+ if (err)
+ goto free_gpio;
+
+ /* Firmware load */
+ err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch);
+ if (err)
+ goto free_gpio;
+ if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC)
+ lbs_deb_spi("Firmware is already loaded for "
+ "Marvell WLAN 802.11 adapter\n");
+ else {
+ err = if_spi_calculate_fw_names(card->card_id,
+ card->helper_fw_name, card->main_fw_name);
+ if (err)
+ goto free_gpio;
+
+ lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter "
+ "(chip_id = 0x%04x, chip_rev = 0x%02x) "
+ "attached to SPI bus_num %d, chip_select %d. "
+ "spi->max_speed_hz=%d\n",
+ card->card_id, card->card_rev,
+ spi->master->bus_num, spi->chip_select,
+ spi->max_speed_hz);
+ err = if_spi_prog_helper_firmware(card);
+ if (err)
+ goto free_gpio;
+ err = if_spi_prog_main_firmware(card);
+ if (err)
+ goto free_gpio;
+ lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n");
+ }
+
+ err = spu_set_interrupt_mode(card, 0, 1);
+ if (err)
+ goto free_gpio;
+
+ /* Register our card with libertas.
+ * This will call alloc_etherdev */
+ priv = lbs_add_card(card, &spi->dev);
+ if (!priv) {
+ err = -ENOMEM;
+ goto free_gpio;
+ }
+ card->priv = priv;
+ priv->card = card;
+ priv->hw_host_to_card = if_spi_host_to_card;
+ priv->fw_ready = 1;
+ priv->ps_supported = 1;
+
+ /* Initialize interrupt handling stuff. */
+ card->run_thread = 1;
+ card->spi_thread = kthread_run(lbs_spi_thread, card, "lbs_spi_thread");
+ if (IS_ERR(card->spi_thread)) {
+ card->run_thread = 0;
+ err = PTR_ERR(card->spi_thread);
+ lbs_pr_err("error creating SPI thread: err=%d\n", err);
+ goto remove_card;
+ }
+ err = request_irq(spi->irq, if_spi_host_interrupt,
+ IRQF_TRIGGER_FALLING, "libertas_spi", card);
+ if (err) {
+ lbs_pr_err("can't get host irq line-- request_irq failed\n");
+ goto terminate_thread;
+ }
+
+ /* Start the card.
+ * This will call register_netdev, and we'll start
+ * getting interrupts... */
+ err = lbs_start_card(priv);
+ if (err)
+ goto release_irq;
+
+ lbs_deb_spi("Finished initializing WLAN module.\n");
+
+ /* successful exit */
+ goto out;
+
+release_irq:
+ free_irq(spi->irq, card);
+terminate_thread:
+ if_spi_terminate_spi_thread(card);
+remove_card:
+ lbs_remove_card(priv); /* will call free_netdev */
+free_gpio:
+ gpio_free(card->gpio_cs);
+free_card:
+ free_if_spi_card(card);
+out:
+ lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err);
+ return err;
+}
+
+static int __devexit libertas_spi_remove(struct spi_device *spi)
+{
+ struct if_spi_card *card = spi_get_drvdata(spi);
+ struct lbs_private *priv = card->priv;
+
+ lbs_deb_spi("libertas_spi_remove\n");
+ lbs_deb_enter(LBS_DEB_SPI);
+ priv->surpriseremoved = 1;
+
+ lbs_stop_card(priv);
+ free_irq(spi->irq, card);
+ if_spi_terminate_spi_thread(card);
+ lbs_remove_card(priv); /* will call free_netdev */
+ gpio_free(card->gpio_cs);
+ if (card->pdata->teardown)
+ card->pdata->teardown(spi);
+ free_if_spi_card(card);
+ lbs_deb_leave(LBS_DEB_SPI);
+ return 0;
+}
+
+static struct spi_driver libertas_spi_driver = {
+ .probe = if_spi_probe,
+ .remove = __devexit_p(libertas_spi_remove),
+ .driver = {
+ .name = "libertas_spi",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+};
+
+/*
+ * Module functions
+ */
+
+static int __init if_spi_init_module(void)
+{
+ int ret = 0;
+ lbs_deb_enter(LBS_DEB_SPI);
+ printk(KERN_INFO "libertas_spi: Libertas SPI driver\n");
+ ret = spi_register_driver(&libertas_spi_driver);
+ lbs_deb_leave(LBS_DEB_SPI);
+ return ret;
+}
+
+static void __exit if_spi_exit_module(void)
+{
+ lbs_deb_enter(LBS_DEB_SPI);
+ spi_unregister_driver(&libertas_spi_driver);
+ lbs_deb_leave(LBS_DEB_SPI);
+}
+
+module_init(if_spi_init_module);
+module_exit(if_spi_exit_module);
+
+MODULE_DESCRIPTION("Libertas SPI WLAN Driver");
+MODULE_AUTHOR("Andrey Yurovsky <andrey@cozybit.com>, "
+ "Colin McCabe <colin@cozybit.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/libertas/if_spi.h b/drivers/net/wireless/libertas/if_spi.h
new file mode 100644
index 000000000000..2103869cc5b0
--- /dev/null
+++ b/drivers/net/wireless/libertas/if_spi.h
@@ -0,0 +1,208 @@
+/*
+ * linux/drivers/net/wireless/libertas/if_spi.c
+ *
+ * Driver for Marvell SPI WLAN cards.
+ *
+ * Copyright 2008 Analog Devices Inc.
+ *
+ * Authors:
+ * Andrey Yurovsky <andrey@cozybit.com>
+ * Colin McCabe <colin@cozybit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef _LBS_IF_SPI_H_
+#define _LBS_IF_SPI_H_
+
+#define IPFIELD_ALIGN_OFFSET 2
+#define IF_SPI_CMD_BUF_SIZE 2400
+
+/***************** Firmware *****************/
+struct chip_ident {
+ u16 chip_id;
+ u16 name;
+};
+
+#define MAX_MAIN_FW_LOAD_CRC_ERR 10
+
+/* Chunk size when loading the helper firmware */
+#define HELPER_FW_LOAD_CHUNK_SZ 64
+
+/* Value to write to indicate end of helper firmware dnld */
+#define FIRMWARE_DNLD_OK 0x0000
+
+/* Value to check once the main firmware is downloaded */
+#define SUCCESSFUL_FW_DOWNLOAD_MAGIC 0x88888888
+
+/***************** SPI Interface Unit *****************/
+/* Masks used in SPI register read/write operations */
+#define IF_SPI_READ_OPERATION_MASK 0x0
+#define IF_SPI_WRITE_OPERATION_MASK 0x8000
+
+/* SPI register offsets. 4-byte aligned. */
+#define IF_SPI_DEVICEID_CTRL_REG 0x00 /* DeviceID controller reg */
+#define IF_SPI_IO_READBASE_REG 0x04 /* Read I/O base reg */
+#define IF_SPI_IO_WRITEBASE_REG 0x08 /* Write I/O base reg */
+#define IF_SPI_IO_RDWRPORT_REG 0x0C /* Read/Write I/O port reg */
+
+#define IF_SPI_CMD_READBASE_REG 0x10 /* Read command base reg */
+#define IF_SPI_CMD_WRITEBASE_REG 0x14 /* Write command base reg */
+#define IF_SPI_CMD_RDWRPORT_REG 0x18 /* Read/Write command port reg */
+
+#define IF_SPI_DATA_READBASE_REG 0x1C /* Read data base reg */
+#define IF_SPI_DATA_WRITEBASE_REG 0x20 /* Write data base reg */
+#define IF_SPI_DATA_RDWRPORT_REG 0x24 /* Read/Write data port reg */
+
+#define IF_SPI_SCRATCH_1_REG 0x28 /* Scratch reg 1 */
+#define IF_SPI_SCRATCH_2_REG 0x2C /* Scratch reg 2 */
+#define IF_SPI_SCRATCH_3_REG 0x30 /* Scratch reg 3 */
+#define IF_SPI_SCRATCH_4_REG 0x34 /* Scratch reg 4 */
+
+#define IF_SPI_TX_FRAME_SEQ_NUM_REG 0x38 /* Tx frame sequence number reg */
+#define IF_SPI_TX_FRAME_STATUS_REG 0x3C /* Tx frame status reg */
+
+#define IF_SPI_HOST_INT_CTRL_REG 0x40 /* Host interrupt controller reg */
+
+#define IF_SPI_CARD_INT_CAUSE_REG 0x44 /* Card interrupt cause reg */
+#define IF_SPI_CARD_INT_STATUS_REG 0x48 /* Card interupt status reg */
+#define IF_SPI_CARD_INT_EVENT_MASK_REG 0x4C /* Card interrupt event mask */
+#define IF_SPI_CARD_INT_STATUS_MASK_REG 0x50 /* Card interrupt status mask */
+
+#define IF_SPI_CARD_INT_RESET_SELECT_REG 0x54 /* Card interrupt reset select */
+
+#define IF_SPI_HOST_INT_CAUSE_REG 0x58 /* Host interrupt cause reg */
+#define IF_SPI_HOST_INT_STATUS_REG 0x5C /* Host interrupt status reg */
+#define IF_SPI_HOST_INT_EVENT_MASK_REG 0x60 /* Host interrupt event mask */
+#define IF_SPI_HOST_INT_STATUS_MASK_REG 0x64 /* Host interrupt status mask */
+#define IF_SPI_HOST_INT_RESET_SELECT_REG 0x68 /* Host interrupt reset select */
+
+#define IF_SPI_DELAY_READ_REG 0x6C /* Delay read reg */
+#define IF_SPI_SPU_BUS_MODE_REG 0x70 /* SPU BUS mode reg */
+
+/***************** IF_SPI_DEVICEID_CTRL_REG *****************/
+#define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_ID(dc) ((dc & 0xffff0000)>>16)
+#define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dc) (dc & 0x000000ff)
+
+/***************** IF_SPI_HOST_INT_CTRL_REG *****************/
+/** Host Interrupt Control bit : Wake up */
+#define IF_SPI_HICT_WAKE_UP (1<<0)
+/** Host Interrupt Control bit : WLAN ready */
+#define IF_SPI_HICT_WLAN_READY (1<<1)
+/*#define IF_SPI_HICT_FIFO_FIRST_HALF_EMPTY (1<<2) */
+/*#define IF_SPI_HICT_FIFO_SECOND_HALF_EMPTY (1<<3) */
+/*#define IF_SPI_HICT_IRQSRC_WLAN (1<<4) */
+/** Host Interrupt Control bit : Tx auto download */
+#define IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO (1<<5)
+/** Host Interrupt Control bit : Rx auto upload */
+#define IF_SPI_HICT_RX_UPLOAD_OVER_AUTO (1<<6)
+/** Host Interrupt Control bit : Command auto download */
+#define IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO (1<<7)
+/** Host Interrupt Control bit : Command auto upload */
+#define IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO (1<<8)
+
+/***************** IF_SPI_CARD_INT_CAUSE_REG *****************/
+/** Card Interrupt Case bit : Tx download over */
+#define IF_SPI_CIC_TX_DOWNLOAD_OVER (1<<0)
+/** Card Interrupt Case bit : Rx upload over */
+#define IF_SPI_CIC_RX_UPLOAD_OVER (1<<1)
+/** Card Interrupt Case bit : Command download over */
+#define IF_SPI_CIC_CMD_DOWNLOAD_OVER (1<<2)
+/** Card Interrupt Case bit : Host event */
+#define IF_SPI_CIC_HOST_EVENT (1<<3)
+/** Card Interrupt Case bit : Command upload over */
+#define IF_SPI_CIC_CMD_UPLOAD_OVER (1<<4)
+/** Card Interrupt Case bit : Power down */
+#define IF_SPI_CIC_POWER_DOWN (1<<5)
+
+/***************** IF_SPI_CARD_INT_STATUS_REG *****************/
+#define IF_SPI_CIS_TX_DOWNLOAD_OVER (1<<0)
+#define IF_SPI_CIS_RX_UPLOAD_OVER (1<<1)
+#define IF_SPI_CIS_CMD_DOWNLOAD_OVER (1<<2)
+#define IF_SPI_CIS_HOST_EVENT (1<<3)
+#define IF_SPI_CIS_CMD_UPLOAD_OVER (1<<4)
+#define IF_SPI_CIS_POWER_DOWN (1<<5)
+
+/***************** IF_SPI_HOST_INT_CAUSE_REG *****************/
+#define IF_SPI_HICU_TX_DOWNLOAD_RDY (1<<0)
+#define IF_SPI_HICU_RX_UPLOAD_RDY (1<<1)
+#define IF_SPI_HICU_CMD_DOWNLOAD_RDY (1<<2)
+#define IF_SPI_HICU_CARD_EVENT (1<<3)
+#define IF_SPI_HICU_CMD_UPLOAD_RDY (1<<4)
+#define IF_SPI_HICU_IO_WR_FIFO_OVERFLOW (1<<5)
+#define IF_SPI_HICU_IO_RD_FIFO_UNDERFLOW (1<<6)
+#define IF_SPI_HICU_DATA_WR_FIFO_OVERFLOW (1<<7)
+#define IF_SPI_HICU_DATA_RD_FIFO_UNDERFLOW (1<<8)
+#define IF_SPI_HICU_CMD_WR_FIFO_OVERFLOW (1<<9)
+#define IF_SPI_HICU_CMD_RD_FIFO_UNDERFLOW (1<<10)
+
+/***************** IF_SPI_HOST_INT_STATUS_REG *****************/
+/** Host Interrupt Status bit : Tx download ready */
+#define IF_SPI_HIST_TX_DOWNLOAD_RDY (1<<0)
+/** Host Interrupt Status bit : Rx upload ready */
+#define IF_SPI_HIST_RX_UPLOAD_RDY (1<<1)
+/** Host Interrupt Status bit : Command download ready */
+#define IF_SPI_HIST_CMD_DOWNLOAD_RDY (1<<2)
+/** Host Interrupt Status bit : Card event */
+#define IF_SPI_HIST_CARD_EVENT (1<<3)
+/** Host Interrupt Status bit : Command upload ready */
+#define IF_SPI_HIST_CMD_UPLOAD_RDY (1<<4)
+/** Host Interrupt Status bit : I/O write FIFO overflow */
+#define IF_SPI_HIST_IO_WR_FIFO_OVERFLOW (1<<5)
+/** Host Interrupt Status bit : I/O read FIFO underflow */
+#define IF_SPI_HIST_IO_RD_FIFO_UNDRFLOW (1<<6)
+/** Host Interrupt Status bit : Data write FIFO overflow */
+#define IF_SPI_HIST_DATA_WR_FIFO_OVERFLOW (1<<7)
+/** Host Interrupt Status bit : Data read FIFO underflow */
+#define IF_SPI_HIST_DATA_RD_FIFO_UNDERFLOW (1<<8)
+/** Host Interrupt Status bit : Command write FIFO overflow */
+#define IF_SPI_HIST_CMD_WR_FIFO_OVERFLOW (1<<9)
+/** Host Interrupt Status bit : Command read FIFO underflow */
+#define IF_SPI_HIST_CMD_RD_FIFO_UNDERFLOW (1<<10)
+
+/***************** IF_SPI_HOST_INT_STATUS_MASK_REG *****************/
+/** Host Interrupt Status Mask bit : Tx download ready */
+#define IF_SPI_HISM_TX_DOWNLOAD_RDY (1<<0)
+/** Host Interrupt Status Mask bit : Rx upload ready */
+#define IF_SPI_HISM_RX_UPLOAD_RDY (1<<1)
+/** Host Interrupt Status Mask bit : Command download ready */
+#define IF_SPI_HISM_CMD_DOWNLOAD_RDY (1<<2)
+/** Host Interrupt Status Mask bit : Card event */
+#define IF_SPI_HISM_CARDEVENT (1<<3)
+/** Host Interrupt Status Mask bit : Command upload ready */
+#define IF_SPI_HISM_CMD_UPLOAD_RDY (1<<4)
+/** Host Interrupt Status Mask bit : I/O write FIFO overflow */
+#define IF_SPI_HISM_IO_WR_FIFO_OVERFLOW (1<<5)
+/** Host Interrupt Status Mask bit : I/O read FIFO underflow */
+#define IF_SPI_HISM_IO_RD_FIFO_UNDERFLOW (1<<6)
+/** Host Interrupt Status Mask bit : Data write FIFO overflow */
+#define IF_SPI_HISM_DATA_WR_FIFO_OVERFLOW (1<<7)
+/** Host Interrupt Status Mask bit : Data write FIFO underflow */
+#define IF_SPI_HISM_DATA_RD_FIFO_UNDERFLOW (1<<8)
+/** Host Interrupt Status Mask bit : Command write FIFO overflow */
+#define IF_SPI_HISM_CMD_WR_FIFO_OVERFLOW (1<<9)
+/** Host Interrupt Status Mask bit : Command write FIFO underflow */
+#define IF_SPI_HISM_CMD_RD_FIFO_UNDERFLOW (1<<10)
+
+/***************** IF_SPI_SPU_BUS_MODE_REG *****************/
+/* SCK edge on which the WLAN module outputs data on MISO */
+#define IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_FALLING 0x8
+#define IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING 0x0
+
+/* In a SPU read operation, there is a delay between writing the SPU
+ * register name and getting back data from the WLAN module.
+ * This can be specified in terms of nanoseconds or in terms of dummy
+ * clock cycles which the master must output before receiving a response. */
+#define IF_SPI_BUS_MODE_DELAY_METHOD_DUMMY_CLOCK 0x4
+#define IF_SPI_BUS_MODE_DELAY_METHOD_TIMED 0x0
+
+/* Some different modes of SPI operation */
+#define IF_SPI_BUS_MODE_8_BIT_ADDRESS_16_BIT_DATA 0x00
+#define IF_SPI_BUS_MODE_8_BIT_ADDRESS_32_BIT_DATA 0x01
+#define IF_SPI_BUS_MODE_16_BIT_ADDRESS_16_BIT_DATA 0x02
+#define IF_SPI_BUS_MODE_16_BIT_ADDRESS_32_BIT_DATA 0x03
+
+#endif
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index f76623e0ff9a..8ae935ac32f1 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -582,20 +582,6 @@ void lbs_host_to_card_done(struct lbs_private *priv)
}
EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
-/**
- * @brief This function returns the network statistics
- *
- * @param dev A pointer to struct lbs_private structure
- * @return A pointer to net_device_stats structure
- */
-static struct net_device_stats *lbs_get_stats(struct net_device *dev)
-{
- struct lbs_private *priv = dev->ml_priv;
-
- lbs_deb_enter(LBS_DEB_NET);
- return &priv->stats;
-}
-
static int lbs_set_mac_address(struct net_device *dev, void *addr)
{
int ret = 0;
@@ -1006,9 +992,8 @@ void lbs_resume(struct lbs_private *priv)
EXPORT_SYMBOL_GPL(lbs_resume);
/**
- * @brief This function downloads firmware image, gets
- * HW spec from firmware and set basic parameters to
- * firmware.
+ * @brief This function gets the HW spec from the firmware and sets
+ * some basic parameters.
*
* @param priv A pointer to struct lbs_private structure
* @return 0 or -1
@@ -1163,6 +1148,17 @@ static void lbs_free_adapter(struct lbs_private *priv)
lbs_deb_leave(LBS_DEB_MAIN);
}
+static const struct net_device_ops lbs_netdev_ops = {
+ .ndo_open = lbs_dev_open,
+ .ndo_stop = lbs_eth_stop,
+ .ndo_start_xmit = lbs_hard_start_xmit,
+ .ndo_set_mac_address = lbs_set_mac_address,
+ .ndo_tx_timeout = lbs_tx_timeout,
+ .ndo_set_multicast_list = lbs_set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/**
* @brief This function adds the card. it will probe the
* card, allocate the lbs_priv and initialize the device.
@@ -1197,19 +1193,13 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
priv->infra_open = 0;
/* Setup the OS Interface to our functions */
- dev->open = lbs_dev_open;
- dev->hard_start_xmit = lbs_hard_start_xmit;
- dev->stop = lbs_eth_stop;
- dev->set_mac_address = lbs_set_mac_address;
- dev->tx_timeout = lbs_tx_timeout;
- dev->get_stats = lbs_get_stats;
+ dev->netdev_ops = &lbs_netdev_ops;
dev->watchdog_timeo = 5 * HZ;
dev->ethtool_ops = &lbs_ethtool_ops;
#ifdef WIRELESS_EXT
- dev->wireless_handlers = (struct iw_handler_def *)&lbs_handler_def;
+ dev->wireless_handlers = &lbs_handler_def;
#endif
dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
- dev->set_multicast_list = lbs_set_multicast_list;
SET_NETDEV_DEV(dev, dmdev);
@@ -1419,6 +1409,14 @@ out:
EXPORT_SYMBOL_GPL(lbs_stop_card);
+static const struct net_device_ops mesh_netdev_ops = {
+ .ndo_open = lbs_dev_open,
+ .ndo_stop = lbs_mesh_stop,
+ .ndo_start_xmit = lbs_hard_start_xmit,
+ .ndo_set_mac_address = lbs_set_mac_address,
+ .ndo_set_multicast_list = lbs_set_multicast_list,
+};
+
/**
* @brief This function adds mshX interface
*
@@ -1441,11 +1439,7 @@ static int lbs_add_mesh(struct lbs_private *priv)
mesh_dev->ml_priv = priv;
priv->mesh_dev = mesh_dev;
- mesh_dev->open = lbs_dev_open;
- mesh_dev->hard_start_xmit = lbs_hard_start_xmit;
- mesh_dev->stop = lbs_mesh_stop;
- mesh_dev->get_stats = lbs_get_stats;
- mesh_dev->set_mac_address = lbs_set_mac_address;
+ mesh_dev->netdev_ops = &mesh_netdev_ops;
mesh_dev->ethtool_ops = &lbs_ethtool_ops;
memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
sizeof(priv->dev->dev_addr));
@@ -1456,7 +1450,6 @@ static int lbs_add_mesh(struct lbs_private *priv)
mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
#endif
mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
- mesh_dev->set_multicast_list = lbs_set_multicast_list;
/* Register virtual mesh interface */
ret = register_netdev(mesh_dev);
if (ret) {
@@ -1649,14 +1642,6 @@ static int lbs_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_BUSY;
}
-static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev)
-{
- struct lbs_private *priv = dev->ml_priv;
- lbs_deb_enter(LBS_DEB_NET);
- return &priv->stats;
-}
-
-
static void lbs_remove_rtap(struct lbs_private *priv)
{
lbs_deb_enter(LBS_DEB_MAIN);
@@ -1669,6 +1654,12 @@ out:
lbs_deb_leave(LBS_DEB_MAIN);
}
+static const struct net_device_ops rtap_netdev_ops = {
+ .ndo_open = lbs_rtap_open,
+ .ndo_stop = lbs_rtap_stop,
+ .ndo_start_xmit = lbs_rtap_hard_start_xmit,
+};
+
static int lbs_add_rtap(struct lbs_private *priv)
{
int ret = 0;
@@ -1688,10 +1679,7 @@ static int lbs_add_rtap(struct lbs_private *priv)
memcpy(rtap_dev->dev_addr, priv->current_addr, ETH_ALEN);
rtap_dev->type = ARPHRD_IEEE80211_RADIOTAP;
- rtap_dev->open = lbs_rtap_open;
- rtap_dev->stop = lbs_rtap_stop;
- rtap_dev->get_stats = lbs_rtap_get_stats;
- rtap_dev->hard_start_xmit = lbs_rtap_hard_start_xmit;
+ rtap_dev->netdev_ops = &rtap_netdev_ops;
rtap_dev->ml_priv = priv;
SET_NETDEV_DEV(rtap_dev, priv->dev->dev.parent);
diff --git a/drivers/net/wireless/libertas/radiotap.h b/drivers/net/wireless/libertas/radiotap.h
index f8eb9097ff0a..d16b26416e82 100644
--- a/drivers/net/wireless/libertas/radiotap.h
+++ b/drivers/net/wireless/libertas/radiotap.h
@@ -33,22 +33,12 @@ struct rx_radiotap_hdr {
struct ieee80211_radiotap_header hdr;
u8 flags;
u8 rate;
- u16 chan_freq;
- u16 chan_flags;
- u8 antenna;
u8 antsignal;
- u16 rx_flags;
-#if 0
- u8 pad[IEEE80211_RADIOTAP_HDRLEN - 18];
-#endif
} __attribute__ ((packed));
#define RX_RADIOTAP_PRESENT ( \
(1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
- (1 << IEEE80211_RADIOTAP_CHANNEL) | \
- (1 << IEEE80211_RADIOTAP_ANTENNA) | \
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) |\
- (1 << IEEE80211_RADIOTAP_RX_FLAGS) | \
0)
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 079e6aa874dc..63d7e19ce9bd 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -168,7 +168,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
lbs_deb_rx("rx err: frame received with bad length\n");
- priv->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
ret = 0;
goto done;
}
@@ -179,7 +179,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
if (!(p_rx_pd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
lbs_deb_rx("rx err: frame received with bad status\n");
lbs_pr_alert("rxpd not ok\n");
- priv->stats.rx_errors++;
+ dev->stats.rx_errors++;
ret = 0;
goto done;
}
@@ -243,8 +243,8 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
lbs_compute_rssi(priv, p_rx_pd);
lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
- priv->stats.rx_bytes += skb->len;
- priv->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
skb->protocol = eth_type_trans(skb, dev);
if (in_interrupt())
@@ -311,7 +311,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
struct sk_buff *skb)
{
int ret = 0;
-
+ struct net_device *dev = priv->dev;
struct rx80211packethdr *p_rx_pkt;
struct rxpd *prxpd;
struct rx_radiotap_hdr radiotap_hdr;
@@ -326,7 +326,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
lbs_deb_rx("rx err: frame received with bad length\n");
- priv->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
ret = -EINVAL;
kfree_skb(skb);
goto done;
@@ -337,7 +337,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
*/
if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
//lbs_deb_rx("rx err: frame received with bad status\n");
- priv->stats.rx_errors++;
+ dev->stats.rx_errors++;
}
lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
@@ -351,19 +351,11 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
radiotap_hdr.hdr.it_pad = 0;
radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
- /* unknown values */
- radiotap_hdr.flags = 0;
- radiotap_hdr.chan_freq = 0;
- radiotap_hdr.chan_flags = 0;
- radiotap_hdr.antenna = 0;
- /* known values */
+ if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
+ radiotap_hdr.flags |= IEEE80211_RADIOTAP_F_BADFCS;
radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
/* XXX must check no carryout */
radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
- radiotap_hdr.rx_flags = 0;
- if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
- radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
- //memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18);
/* chop the rxpd */
skb_pull(skb, sizeof(struct rxpd));
@@ -389,8 +381,8 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
lbs_compute_rssi(priv, prxpd);
lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
- priv->stats.rx_bytes += skb->len;
- priv->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
skb->protocol = eth_type_trans(skb, priv->rtap_net_dev);
netif_rx(skb);
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 9014950f4328..8124db36aaff 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -692,7 +692,7 @@ static int lbs_process_bss(struct bss_descriptor *bss,
bss->wpa_ie_len);
} else if (pos[1] >= MARVELL_MESH_IE_LENGTH &&
pos[2] == 0x00 && pos[3] == 0x50 &&
- pos[4] == 0x43 && pos[4] == 0x04) {
+ pos[4] == 0x43 && pos[5] == 0x04) {
lbs_deb_scan("got mesh IE\n");
bss->mesh = 1;
} else {
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index 68bec31ae03b..f10aa39a6b68 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -82,8 +82,8 @@ int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
/* We'll never manage to send this one; drop it and return 'OK' */
- priv->stats.tx_dropped++;
- priv->stats.tx_errors++;
+ dev->stats.tx_dropped++;
+ dev->stats.tx_errors++;
goto free;
}
@@ -146,8 +146,8 @@ int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
lbs_deb_tx("%s lined up packet\n", __func__);
- priv->stats.tx_packets++;
- priv->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
dev->trans_start = jiffies;
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index f16d136ab4bb..8bc1907458b1 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -830,7 +830,7 @@ static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
quality = rssi_qual;
/* Quality by TX errors */
- priv->wstats.discard.retries = priv->stats.tx_errors;
+ priv->wstats.discard.retries = dev->stats.tx_errors;
memset(&log, 0, sizeof(log));
log.hdr.size = cpu_to_le16(sizeof(log));
diff --git a/drivers/net/wireless/libertas_tf/cmd.c b/drivers/net/wireless/libertas_tf/cmd.c
index 3d3914c83b14..28790e03dc43 100644
--- a/drivers/net/wireless/libertas_tf/cmd.c
+++ b/drivers/net/wireless/libertas_tf/cmd.c
@@ -286,7 +286,7 @@ void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode)
lbtf_cmd_async(priv, CMD_802_11_SET_MODE, &cmd.hdr, sizeof(cmd));
}
-void lbtf_set_bssid(struct lbtf_private *priv, bool activate, u8 *bssid)
+void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid)
{
struct cmd_ds_set_bssid cmd;
diff --git a/drivers/net/wireless/libertas_tf/libertas_tf.h b/drivers/net/wireless/libertas_tf/libertas_tf.h
index 8995cd7c29bf..4cc42dd5a005 100644
--- a/drivers/net/wireless/libertas_tf/libertas_tf.h
+++ b/drivers/net/wireless/libertas_tf/libertas_tf.h
@@ -463,7 +463,7 @@ int lbtf_set_radio_control(struct lbtf_private *priv);
int lbtf_update_hw_spec(struct lbtf_private *priv);
int lbtf_cmd_set_mac_multicast_addr(struct lbtf_private *priv);
void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode);
-void lbtf_set_bssid(struct lbtf_private *priv, bool activate, u8 *bssid);
+void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid);
int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr);
int lbtf_set_channel(struct lbtf_private *priv, u8 channel);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index f83d69e813d3..d4fdc8b7d7d8 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -10,7 +10,6 @@
/*
* TODO:
* - IBSS mode simulation (Beacon transmission with competition for "air time")
- * - IEEE 802.11a and 802.11n modes
* - RX filtering based on filter configuration (data->rx_filter)
*/
@@ -31,6 +30,112 @@ static int radios = 2;
module_param(radios, int, 0444);
MODULE_PARM_DESC(radios, "Number of simulated radios");
+/**
+ * enum hwsim_regtest - the type of regulatory tests we offer
+ *
+ * These are the different values you can use for the regtest
+ * module parameter. This is useful to help test world roaming
+ * and the driver regulatory_hint() call and combinations of these.
+ * If you want to do specific alpha2 regulatory domain tests simply
+ * use the userspace regulatory request as that will be respected as
+ * well without the need of this module parameter. This is designed
+ * only for testing the driver regulatory request, world roaming
+ * and all possible combinations.
+ *
+ * @HWSIM_REGTEST_DISABLED: No regulatory tests are performed,
+ * this is the default value.
+ * @HWSIM_REGTEST_DRIVER_REG_FOLLOW: Used for testing the driver regulatory
+ * hint, only one driver regulatory hint will be sent as such the
+ * secondary radios are expected to follow.
+ * @HWSIM_REGTEST_DRIVER_REG_ALL: Used for testing the driver regulatory
+ * request with all radios reporting the same regulatory domain.
+ * @HWSIM_REGTEST_DIFF_COUNTRY: Used for testing the drivers calling
+ * different regulatory domains requests. Expected behaviour is for
+ * an intersection to occur but each device will still use their
+ * respective regulatory requested domains. Subsequent radios will
+ * use the resulting intersection.
+ * @HWSIM_REGTEST_WORLD_ROAM: Used for testing the world roaming. We acomplish
+ * this by using a custom beacon-capable regulatory domain for the first
+ * radio. All other device world roam.
+ * @HWSIM_REGTEST_CUSTOM_WORLD: Used for testing the custom world regulatory
+ * domain requests. All radios will adhere to this custom world regulatory
+ * domain.
+ * @HWSIM_REGTEST_CUSTOM_WORLD_2: Used for testing 2 custom world regulatory
+ * domain requests. The first radio will adhere to the first custom world
+ * regulatory domain, the second one to the second custom world regulatory
+ * domain. All other devices will world roam.
+ * @HWSIM_REGTEST_STRICT_FOLLOW_: Used for testing strict regulatory domain
+ * settings, only the first radio will send a regulatory domain request
+ * and use strict settings. The rest of the radios are expected to follow.
+ * @HWSIM_REGTEST_STRICT_ALL: Used for testing strict regulatory domain
+ * settings. All radios will adhere to this.
+ * @HWSIM_REGTEST_STRICT_AND_DRIVER_REG: Used for testing strict regulatory
+ * domain settings, combined with secondary driver regulatory domain
+ * settings. The first radio will get a strict regulatory domain setting
+ * using the first driver regulatory request and the second radio will use
+ * non-strict settings using the second driver regulatory request. All
+ * other devices should follow the intersection created between the
+ * first two.
+ * @HWSIM_REGTEST_ALL: Used for testing every possible mix. You will need
+ * at least 6 radios for a complete test. We will test in this order:
+ * 1 - driver custom world regulatory domain
+ * 2 - second custom world regulatory domain
+ * 3 - first driver regulatory domain request
+ * 4 - second driver regulatory domain request
+ * 5 - strict regulatory domain settings using the third driver regulatory
+ * domain request
+ * 6 and on - should follow the intersection of the 3rd, 4rth and 5th radio
+ * regulatory requests.
+ */
+enum hwsim_regtest {
+ HWSIM_REGTEST_DISABLED = 0,
+ HWSIM_REGTEST_DRIVER_REG_FOLLOW = 1,
+ HWSIM_REGTEST_DRIVER_REG_ALL = 2,
+ HWSIM_REGTEST_DIFF_COUNTRY = 3,
+ HWSIM_REGTEST_WORLD_ROAM = 4,
+ HWSIM_REGTEST_CUSTOM_WORLD = 5,
+ HWSIM_REGTEST_CUSTOM_WORLD_2 = 6,
+ HWSIM_REGTEST_STRICT_FOLLOW = 7,
+ HWSIM_REGTEST_STRICT_ALL = 8,
+ HWSIM_REGTEST_STRICT_AND_DRIVER_REG = 9,
+ HWSIM_REGTEST_ALL = 10,
+};
+
+/* Set to one of the HWSIM_REGTEST_* values above */
+static int regtest = HWSIM_REGTEST_DISABLED;
+module_param(regtest, int, 0444);
+MODULE_PARM_DESC(regtest, "The type of regulatory test we want to run");
+
+static const char *hwsim_alpha2s[] = {
+ "FI",
+ "AL",
+ "US",
+ "DE",
+ "JP",
+ "AL",
+};
+
+static const struct ieee80211_regdomain hwsim_world_regdom_custom_01 = {
+ .n_reg_rules = 4,
+ .alpha2 = "99",
+ .reg_rules = {
+ REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
+ REG_RULE(2484-10, 2484+10, 40, 0, 20, 0),
+ REG_RULE(5150-10, 5240+10, 40, 0, 30, 0),
+ REG_RULE(5745-10, 5825+10, 40, 0, 30, 0),
+ }
+};
+
+static const struct ieee80211_regdomain hwsim_world_regdom_custom_02 = {
+ .n_reg_rules = 2,
+ .alpha2 = "99",
+ .reg_rules = {
+ REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
+ REG_RULE(5725-10, 5850+10, 40, 0, 30,
+ NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
+ }
+};
+
struct hwsim_vif_priv {
u32 magic;
u8 bssid[ETH_ALEN];
@@ -86,22 +191,65 @@ static struct class *hwsim_class;
static struct net_device *hwsim_mon; /* global monitor netdev */
+#define CHAN2G(_freq) { \
+ .band = IEEE80211_BAND_2GHZ, \
+ .center_freq = (_freq), \
+ .hw_value = (_freq), \
+ .max_power = 20, \
+}
+
+#define CHAN5G(_freq) { \
+ .band = IEEE80211_BAND_5GHZ, \
+ .center_freq = (_freq), \
+ .hw_value = (_freq), \
+ .max_power = 20, \
+}
-static const struct ieee80211_channel hwsim_channels[] = {
- { .center_freq = 2412 },
- { .center_freq = 2417 },
- { .center_freq = 2422 },
- { .center_freq = 2427 },
- { .center_freq = 2432 },
- { .center_freq = 2437 },
- { .center_freq = 2442 },
- { .center_freq = 2447 },
- { .center_freq = 2452 },
- { .center_freq = 2457 },
- { .center_freq = 2462 },
- { .center_freq = 2467 },
- { .center_freq = 2472 },
- { .center_freq = 2484 },
+static const struct ieee80211_channel hwsim_channels_2ghz[] = {
+ CHAN2G(2412), /* Channel 1 */
+ CHAN2G(2417), /* Channel 2 */
+ CHAN2G(2422), /* Channel 3 */
+ CHAN2G(2427), /* Channel 4 */
+ CHAN2G(2432), /* Channel 5 */
+ CHAN2G(2437), /* Channel 6 */
+ CHAN2G(2442), /* Channel 7 */
+ CHAN2G(2447), /* Channel 8 */
+ CHAN2G(2452), /* Channel 9 */
+ CHAN2G(2457), /* Channel 10 */
+ CHAN2G(2462), /* Channel 11 */
+ CHAN2G(2467), /* Channel 12 */
+ CHAN2G(2472), /* Channel 13 */
+ CHAN2G(2484), /* Channel 14 */
+};
+
+static const struct ieee80211_channel hwsim_channels_5ghz[] = {
+ CHAN5G(5180), /* Channel 36 */
+ CHAN5G(5200), /* Channel 40 */
+ CHAN5G(5220), /* Channel 44 */
+ CHAN5G(5240), /* Channel 48 */
+
+ CHAN5G(5260), /* Channel 52 */
+ CHAN5G(5280), /* Channel 56 */
+ CHAN5G(5300), /* Channel 60 */
+ CHAN5G(5320), /* Channel 64 */
+
+ CHAN5G(5500), /* Channel 100 */
+ CHAN5G(5520), /* Channel 104 */
+ CHAN5G(5540), /* Channel 108 */
+ CHAN5G(5560), /* Channel 112 */
+ CHAN5G(5580), /* Channel 116 */
+ CHAN5G(5600), /* Channel 120 */
+ CHAN5G(5620), /* Channel 124 */
+ CHAN5G(5640), /* Channel 128 */
+ CHAN5G(5660), /* Channel 132 */
+ CHAN5G(5680), /* Channel 136 */
+ CHAN5G(5700), /* Channel 140 */
+
+ CHAN5G(5745), /* Channel 149 */
+ CHAN5G(5765), /* Channel 153 */
+ CHAN5G(5785), /* Channel 157 */
+ CHAN5G(5805), /* Channel 161 */
+ CHAN5G(5825), /* Channel 165 */
};
static const struct ieee80211_rate hwsim_rates[] = {
@@ -126,8 +274,9 @@ struct mac80211_hwsim_data {
struct list_head list;
struct ieee80211_hw *hw;
struct device *dev;
- struct ieee80211_supported_band band;
- struct ieee80211_channel channels[ARRAY_SIZE(hwsim_channels)];
+ struct ieee80211_supported_band bands[2];
+ struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)];
+ struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
struct ieee80211_channel *channel;
@@ -590,10 +739,16 @@ static struct device_driver mac80211_hwsim_driver = {
.name = "mac80211_hwsim"
};
+static const struct net_device_ops hwsim_netdev_ops = {
+ .ndo_start_xmit = hwsim_mon_xmit,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
static void hwsim_mon_setup(struct net_device *dev)
{
- dev->hard_start_xmit = hwsim_mon_xmit;
+ dev->netdev_ops = &hwsim_netdev_ops;
dev->destructor = free_netdev;
ether_setup(dev);
dev->tx_queue_len = 0;
@@ -728,6 +883,7 @@ static int __init init_mac80211_hwsim(void)
u8 addr[ETH_ALEN];
struct mac80211_hwsim_data *data;
struct ieee80211_hw *hw;
+ enum ieee80211_band band;
if (radios < 1 || radios > 100)
return -EINVAL;
@@ -777,32 +933,116 @@ static int __init init_mac80211_hwsim(void)
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_MESH_POINT);
- hw->ampdu_queues = 1;
+
+ hw->flags = IEEE80211_HW_MFP_CAPABLE;
/* ask mac80211 to reserve space for magic */
hw->vif_data_size = sizeof(struct hwsim_vif_priv);
hw->sta_data_size = sizeof(struct hwsim_sta_priv);
- memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels));
+ memcpy(data->channels_2ghz, hwsim_channels_2ghz,
+ sizeof(hwsim_channels_2ghz));
+ memcpy(data->channels_5ghz, hwsim_channels_5ghz,
+ sizeof(hwsim_channels_5ghz));
memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
- data->band.channels = data->channels;
- data->band.n_channels = ARRAY_SIZE(hwsim_channels);
- data->band.bitrates = data->rates;
- data->band.n_bitrates = ARRAY_SIZE(hwsim_rates);
- data->band.ht_cap.ht_supported = true;
- data->band.ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
- IEEE80211_HT_CAP_GRN_FLD |
- IEEE80211_HT_CAP_SGI_40 |
- IEEE80211_HT_CAP_DSSSCCK40;
- data->band.ht_cap.ampdu_factor = 0x3;
- data->band.ht_cap.ampdu_density = 0x6;
- memset(&data->band.ht_cap.mcs, 0,
- sizeof(data->band.ht_cap.mcs));
- data->band.ht_cap.mcs.rx_mask[0] = 0xff;
- data->band.ht_cap.mcs.rx_mask[1] = 0xff;
- data->band.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
- hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band;
+ for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
+ struct ieee80211_supported_band *sband = &data->bands[band];
+ switch (band) {
+ case IEEE80211_BAND_2GHZ:
+ sband->channels = data->channels_2ghz;
+ sband->n_channels =
+ ARRAY_SIZE(hwsim_channels_2ghz);
+ break;
+ case IEEE80211_BAND_5GHZ:
+ sband->channels = data->channels_5ghz;
+ sband->n_channels =
+ ARRAY_SIZE(hwsim_channels_5ghz);
+ break;
+ default:
+ break;
+ }
+
+ sband->bitrates = data->rates;
+ sband->n_bitrates = ARRAY_SIZE(hwsim_rates);
+
+ sband->ht_cap.ht_supported = true;
+ sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+ IEEE80211_HT_CAP_GRN_FLD |
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_DSSSCCK40;
+ sband->ht_cap.ampdu_factor = 0x3;
+ sband->ht_cap.ampdu_density = 0x6;
+ memset(&sband->ht_cap.mcs, 0,
+ sizeof(sband->ht_cap.mcs));
+ sband->ht_cap.mcs.rx_mask[0] = 0xff;
+ sband->ht_cap.mcs.rx_mask[1] = 0xff;
+ sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+
+ hw->wiphy->bands[band] = sband;
+ }
+
+ /* Work to be done prior to ieee80211_register_hw() */
+ switch (regtest) {
+ case HWSIM_REGTEST_DISABLED:
+ case HWSIM_REGTEST_DRIVER_REG_FOLLOW:
+ case HWSIM_REGTEST_DRIVER_REG_ALL:
+ case HWSIM_REGTEST_DIFF_COUNTRY:
+ /*
+ * Nothing to be done for driver regulatory domain
+ * hints prior to ieee80211_register_hw()
+ */
+ break;
+ case HWSIM_REGTEST_WORLD_ROAM:
+ if (i == 0) {
+ hw->wiphy->custom_regulatory = true;
+ wiphy_apply_custom_regulatory(hw->wiphy,
+ &hwsim_world_regdom_custom_01);
+ }
+ break;
+ case HWSIM_REGTEST_CUSTOM_WORLD:
+ hw->wiphy->custom_regulatory = true;
+ wiphy_apply_custom_regulatory(hw->wiphy,
+ &hwsim_world_regdom_custom_01);
+ break;
+ case HWSIM_REGTEST_CUSTOM_WORLD_2:
+ if (i == 0) {
+ hw->wiphy->custom_regulatory = true;
+ wiphy_apply_custom_regulatory(hw->wiphy,
+ &hwsim_world_regdom_custom_01);
+ } else if (i == 1) {
+ hw->wiphy->custom_regulatory = true;
+ wiphy_apply_custom_regulatory(hw->wiphy,
+ &hwsim_world_regdom_custom_02);
+ }
+ break;
+ case HWSIM_REGTEST_STRICT_ALL:
+ hw->wiphy->strict_regulatory = true;
+ break;
+ case HWSIM_REGTEST_STRICT_FOLLOW:
+ case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
+ if (i == 0)
+ hw->wiphy->strict_regulatory = true;
+ break;
+ case HWSIM_REGTEST_ALL:
+ if (i == 0) {
+ hw->wiphy->custom_regulatory = true;
+ wiphy_apply_custom_regulatory(hw->wiphy,
+ &hwsim_world_regdom_custom_01);
+ } else if (i == 1) {
+ hw->wiphy->custom_regulatory = true;
+ wiphy_apply_custom_regulatory(hw->wiphy,
+ &hwsim_world_regdom_custom_02);
+ } else if (i == 4)
+ hw->wiphy->strict_regulatory = true;
+ break;
+ default:
+ break;
+ }
+
+ /* give the regulatory workqueue a chance to run */
+ if (regtest)
+ schedule_timeout_interruptible(1);
err = ieee80211_register_hw(hw);
if (err < 0) {
printk(KERN_DEBUG "mac80211_hwsim: "
@@ -810,6 +1050,52 @@ static int __init init_mac80211_hwsim(void)
goto failed_hw;
}
+ /* Work to be done after to ieee80211_register_hw() */
+ switch (regtest) {
+ case HWSIM_REGTEST_WORLD_ROAM:
+ case HWSIM_REGTEST_DISABLED:
+ break;
+ case HWSIM_REGTEST_DRIVER_REG_FOLLOW:
+ if (!i)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+ break;
+ case HWSIM_REGTEST_DRIVER_REG_ALL:
+ case HWSIM_REGTEST_STRICT_ALL:
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+ break;
+ case HWSIM_REGTEST_DIFF_COUNTRY:
+ if (i < ARRAY_SIZE(hwsim_alpha2s))
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[i]);
+ break;
+ case HWSIM_REGTEST_CUSTOM_WORLD:
+ case HWSIM_REGTEST_CUSTOM_WORLD_2:
+ /*
+ * Nothing to be done for custom world regulatory
+ * domains after to ieee80211_register_hw
+ */
+ break;
+ case HWSIM_REGTEST_STRICT_FOLLOW:
+ if (i == 0)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+ break;
+ case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
+ if (i == 0)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+ else if (i == 1)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[1]);
+ break;
+ case HWSIM_REGTEST_ALL:
+ if (i == 2)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[0]);
+ else if (i == 3)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[1]);
+ else if (i == 4)
+ regulatory_hint(hw->wiphy, hwsim_alpha2s[2]);
+ break;
+ default:
+ break;
+ }
+
printk(KERN_DEBUG "%s: hwaddr %pM registered\n",
wiphy_name(hw->wiphy),
hw->wiphy->perm_addr);
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
new file mode 100644
index 000000000000..57a0268d1bae
--- /dev/null
+++ b/drivers/net/wireless/mwl8k.c
@@ -0,0 +1,3789 @@
+/*
+ * drivers/net/wireless/mwl8k.c driver for Marvell TOPDOG 802.11 Wireless cards
+ *
+ * Copyright (C) 2008 Marvell Semiconductor Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <linux/workqueue.h>
+
+#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver"
+#define MWL8K_NAME KBUILD_MODNAME
+#define MWL8K_VERSION "0.9.1"
+
+MODULE_DESCRIPTION(MWL8K_DESC);
+MODULE_VERSION(MWL8K_VERSION);
+MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com>");
+MODULE_LICENSE("GPL");
+
+static DEFINE_PCI_DEVICE_TABLE(mwl8k_table) = {
+ { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = 8687, },
+ { PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = 8687, },
+ { }
+};
+MODULE_DEVICE_TABLE(pci, mwl8k_table);
+
+#define IEEE80211_ADDR_LEN ETH_ALEN
+
+/* Register definitions */
+#define MWL8K_HIU_GEN_PTR 0x00000c10
+#define MWL8K_MODE_STA 0x0000005a
+#define MWL8K_MODE_AP 0x000000a5
+#define MWL8K_HIU_INT_CODE 0x00000c14
+#define MWL8K_FWSTA_READY 0xf0f1f2f4
+#define MWL8K_FWAP_READY 0xf1f2f4a5
+#define MWL8K_INT_CODE_CMD_FINISHED 0x00000005
+#define MWL8K_HIU_SCRATCH 0x00000c40
+
+/* Host->device communications */
+#define MWL8K_HIU_H2A_INTERRUPT_EVENTS 0x00000c18
+#define MWL8K_HIU_H2A_INTERRUPT_STATUS 0x00000c1c
+#define MWL8K_HIU_H2A_INTERRUPT_MASK 0x00000c20
+#define MWL8K_HIU_H2A_INTERRUPT_CLEAR_SEL 0x00000c24
+#define MWL8K_HIU_H2A_INTERRUPT_STATUS_MASK 0x00000c28
+#define MWL8K_H2A_INT_DUMMY (1 << 20)
+#define MWL8K_H2A_INT_RESET (1 << 15)
+#define MWL8K_H2A_INT_PS (1 << 2)
+#define MWL8K_H2A_INT_DOORBELL (1 << 1)
+#define MWL8K_H2A_INT_PPA_READY (1 << 0)
+
+/* Device->host communications */
+#define MWL8K_HIU_A2H_INTERRUPT_EVENTS 0x00000c2c
+#define MWL8K_HIU_A2H_INTERRUPT_STATUS 0x00000c30
+#define MWL8K_HIU_A2H_INTERRUPT_MASK 0x00000c34
+#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL 0x00000c38
+#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK 0x00000c3c
+#define MWL8K_A2H_INT_DUMMY (1 << 20)
+#define MWL8K_A2H_INT_CHNL_SWITCHED (1 << 11)
+#define MWL8K_A2H_INT_QUEUE_EMPTY (1 << 10)
+#define MWL8K_A2H_INT_RADAR_DETECT (1 << 7)
+#define MWL8K_A2H_INT_RADIO_ON (1 << 6)
+#define MWL8K_A2H_INT_RADIO_OFF (1 << 5)
+#define MWL8K_A2H_INT_MAC_EVENT (1 << 3)
+#define MWL8K_A2H_INT_OPC_DONE (1 << 2)
+#define MWL8K_A2H_INT_RX_READY (1 << 1)
+#define MWL8K_A2H_INT_TX_DONE (1 << 0)
+
+#define MWL8K_A2H_EVENTS (MWL8K_A2H_INT_DUMMY | \
+ MWL8K_A2H_INT_CHNL_SWITCHED | \
+ MWL8K_A2H_INT_QUEUE_EMPTY | \
+ MWL8K_A2H_INT_RADAR_DETECT | \
+ MWL8K_A2H_INT_RADIO_ON | \
+ MWL8K_A2H_INT_RADIO_OFF | \
+ MWL8K_A2H_INT_MAC_EVENT | \
+ MWL8K_A2H_INT_OPC_DONE | \
+ MWL8K_A2H_INT_RX_READY | \
+ MWL8K_A2H_INT_TX_DONE)
+
+/* WME stream classes */
+#define WME_AC_BE 0 /* best effort */
+#define WME_AC_BK 1 /* background */
+#define WME_AC_VI 2 /* video */
+#define WME_AC_VO 3 /* voice */
+
+#define MWL8K_RX_QUEUES 1
+#define MWL8K_TX_QUEUES 4
+
+struct mwl8k_rx_queue {
+ int rx_desc_count;
+
+ /* hw receives here */
+ int rx_head;
+
+ /* refill descs here */
+ int rx_tail;
+
+ struct mwl8k_rx_desc *rx_desc_area;
+ dma_addr_t rx_desc_dma;
+ struct sk_buff **rx_skb;
+};
+
+struct mwl8k_skb {
+ /*
+ * The DMA engine requires a modification to the payload.
+ * If the skbuff is shared/cloned, it needs to be unshared.
+ * This method is used to ensure the stack always gets back
+ * the skbuff it sent for transmission.
+ */
+ struct sk_buff *clone;
+ struct sk_buff *skb;
+};
+
+struct mwl8k_tx_queue {
+ /* hw transmits here */
+ int tx_head;
+
+ /* sw appends here */
+ int tx_tail;
+
+ struct ieee80211_tx_queue_stats tx_stats;
+ struct mwl8k_tx_desc *tx_desc_area;
+ dma_addr_t tx_desc_dma;
+ struct mwl8k_skb *tx_skb;
+};
+
+/* Pointers to the firmware data and meta information about it. */
+struct mwl8k_firmware {
+ /* Microcode */
+ struct firmware *ucode;
+
+ /* Boot helper code */
+ struct firmware *helper;
+};
+
+struct mwl8k_priv {
+ void __iomem *regs;
+ struct ieee80211_hw *hw;
+
+ struct pci_dev *pdev;
+ u8 name[16];
+ /* firmware access lock */
+ spinlock_t fw_lock;
+
+ /* firmware files and meta data */
+ struct mwl8k_firmware fw;
+ u32 part_num;
+
+ /* lock held over TX and TX reap */
+ spinlock_t tx_lock;
+ u32 int_mask;
+
+ struct ieee80211_vif *vif;
+ struct list_head vif_list;
+
+ struct ieee80211_channel *current_channel;
+
+ /* power management status cookie from firmware */
+ u32 *cookie;
+ dma_addr_t cookie_dma;
+
+ u16 num_mcaddrs;
+ u16 region_code;
+ u8 hw_rev;
+ __le32 fw_rev;
+ u32 wep_enabled;
+
+ /*
+ * Running count of TX packets in flight, to avoid
+ * iterating over the transmit rings each time.
+ */
+ int pending_tx_pkts;
+
+ struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
+ struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES];
+
+ /* PHY parameters */
+ struct ieee80211_supported_band band;
+ struct ieee80211_channel channels[14];
+ struct ieee80211_rate rates[12];
+
+ /* RF preamble: Short, Long or Auto */
+ u8 radio_preamble;
+ u8 radio_state;
+
+ /* WMM MODE 1 for enabled; 0 for disabled */
+ bool wmm_mode;
+
+ /* Set if PHY config is in progress */
+ bool inconfig;
+
+ /* XXX need to convert this to handle multiple interfaces */
+ bool capture_beacon;
+ u8 capture_bssid[IEEE80211_ADDR_LEN];
+ struct sk_buff *beacon_skb;
+
+ /*
+ * This FJ worker has to be global as it is scheduled from the
+ * RX handler. At this point we don't know which interface it
+ * belongs to until the list of bssids waiting to complete join
+ * is checked.
+ */
+ struct work_struct finalize_join_worker;
+
+ /* Tasklet to reclaim TX descriptors and buffers after tx */
+ struct tasklet_struct tx_reclaim_task;
+
+ /* Work thread to serialize configuration requests */
+ struct workqueue_struct *config_wq;
+ struct completion *hostcmd_wait;
+ struct completion *tx_wait;
+};
+
+/* Per interface specific private data */
+struct mwl8k_vif {
+ struct list_head node;
+
+ /* backpointer to parent config block */
+ struct mwl8k_priv *priv;
+
+ /* BSS config of AP or IBSS from mac80211*/
+ struct ieee80211_bss_conf bss_info;
+
+ /* BSSID of AP or IBSS */
+ u8 bssid[IEEE80211_ADDR_LEN];
+ u8 mac_addr[IEEE80211_ADDR_LEN];
+
+ /*
+ * Subset of supported legacy rates.
+ * Intersection of AP and STA supported rates.
+ */
+ struct ieee80211_rate legacy_rates[12];
+
+ /* number of supported legacy rates */
+ u8 legacy_nrates;
+
+ /* Number of supported MCS rates. Work in progress */
+ u8 mcs_nrates;
+
+ /* Index into station database.Returned by update_sta_db call */
+ u8 peer_id;
+
+ /* Non AMPDU sequence number assigned by driver */
+ u16 seqno;
+
+ /* Note:There is no channel info,
+ * refer to the master channel info in priv
+ */
+};
+
+#define MWL8K_VIF(_vif) (struct mwl8k_vif *)(&((_vif)->drv_priv))
+
+static const struct ieee80211_channel mwl8k_channels[] = {
+ { .center_freq = 2412, .hw_value = 1, },
+ { .center_freq = 2417, .hw_value = 2, },
+ { .center_freq = 2422, .hw_value = 3, },
+ { .center_freq = 2427, .hw_value = 4, },
+ { .center_freq = 2432, .hw_value = 5, },
+ { .center_freq = 2437, .hw_value = 6, },
+ { .center_freq = 2442, .hw_value = 7, },
+ { .center_freq = 2447, .hw_value = 8, },
+ { .center_freq = 2452, .hw_value = 9, },
+ { .center_freq = 2457, .hw_value = 10, },
+ { .center_freq = 2462, .hw_value = 11, },
+};
+
+static const struct ieee80211_rate mwl8k_rates[] = {
+ { .bitrate = 10, .hw_value = 2, },
+ { .bitrate = 20, .hw_value = 4, },
+ { .bitrate = 55, .hw_value = 11, },
+ { .bitrate = 60, .hw_value = 12, },
+ { .bitrate = 90, .hw_value = 18, },
+ { .bitrate = 110, .hw_value = 22, },
+ { .bitrate = 120, .hw_value = 24, },
+ { .bitrate = 180, .hw_value = 36, },
+ { .bitrate = 240, .hw_value = 48, },
+ { .bitrate = 360, .hw_value = 72, },
+ { .bitrate = 480, .hw_value = 96, },
+ { .bitrate = 540, .hw_value = 108, },
+};
+
+/* Radio settings */
+#define MWL8K_RADIO_FORCE 0x2
+#define MWL8K_RADIO_ENABLE 0x1
+#define MWL8K_RADIO_DISABLE 0x0
+#define MWL8K_RADIO_AUTO_PREAMBLE 0x0005
+#define MWL8K_RADIO_SHORT_PREAMBLE 0x0003
+#define MWL8K_RADIO_LONG_PREAMBLE 0x0001
+
+/* WMM */
+#define MWL8K_WMM_ENABLE 1
+#define MWL8K_WMM_DISABLE 0
+
+#define MWL8K_RADIO_DEFAULT_PREAMBLE MWL8K_RADIO_LONG_PREAMBLE
+
+/* Slot time */
+
+/* Short Slot: 9us slot time */
+#define MWL8K_SHORT_SLOTTIME 1
+
+/* Long slot: 20us slot time */
+#define MWL8K_LONG_SLOTTIME 0
+
+/* Set or get info from Firmware */
+#define MWL8K_CMD_SET 0x0001
+#define MWL8K_CMD_GET 0x0000
+
+/* Firmware command codes */
+#define MWL8K_CMD_CODE_DNLD 0x0001
+#define MWL8K_CMD_GET_HW_SPEC 0x0003
+#define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010
+#define MWL8K_CMD_GET_STAT 0x0014
+#define MWL8K_CMD_RADIO_CONTROL 0x001C
+#define MWL8K_CMD_RF_TX_POWER 0x001E
+#define MWL8K_CMD_SET_PRE_SCAN 0x0107
+#define MWL8K_CMD_SET_POST_SCAN 0x0108
+#define MWL8K_CMD_SET_RF_CHANNEL 0x010A
+#define MWL8K_CMD_SET_SLOT 0x0114
+#define MWL8K_CMD_MIMO_CONFIG 0x0125
+#define MWL8K_CMD_ENABLE_SNIFFER 0x0150
+#define MWL8K_CMD_SET_WMM_MODE 0x0123
+#define MWL8K_CMD_SET_EDCA_PARAMS 0x0115
+#define MWL8K_CMD_SET_FINALIZE_JOIN 0x0111
+#define MWL8K_CMD_UPDATE_STADB 0x1123
+#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203
+#define MWL8K_CMD_SET_LINKADAPT_MODE 0x0129
+#define MWL8K_CMD_SET_AID 0x010d
+#define MWL8K_CMD_SET_RATE 0x0110
+#define MWL8K_CMD_USE_FIXED_RATE 0x0126
+#define MWL8K_CMD_RTS_THRESHOLD 0x0113
+#define MWL8K_CMD_ENCRYPTION 0x1122
+
+static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
+{
+#define MWL8K_CMDNAME(x) case MWL8K_CMD_##x: do {\
+ snprintf(buf, bufsize, "%s", #x);\
+ return buf;\
+ } while (0)
+ switch (cmd & (~0x8000)) {
+ MWL8K_CMDNAME(CODE_DNLD);
+ MWL8K_CMDNAME(GET_HW_SPEC);
+ MWL8K_CMDNAME(MAC_MULTICAST_ADR);
+ MWL8K_CMDNAME(GET_STAT);
+ MWL8K_CMDNAME(RADIO_CONTROL);
+ MWL8K_CMDNAME(RF_TX_POWER);
+ MWL8K_CMDNAME(SET_PRE_SCAN);
+ MWL8K_CMDNAME(SET_POST_SCAN);
+ MWL8K_CMDNAME(SET_RF_CHANNEL);
+ MWL8K_CMDNAME(SET_SLOT);
+ MWL8K_CMDNAME(MIMO_CONFIG);
+ MWL8K_CMDNAME(ENABLE_SNIFFER);
+ MWL8K_CMDNAME(SET_WMM_MODE);
+ MWL8K_CMDNAME(SET_EDCA_PARAMS);
+ MWL8K_CMDNAME(SET_FINALIZE_JOIN);
+ MWL8K_CMDNAME(UPDATE_STADB);
+ MWL8K_CMDNAME(SET_RATEADAPT_MODE);
+ MWL8K_CMDNAME(SET_LINKADAPT_MODE);
+ MWL8K_CMDNAME(SET_AID);
+ MWL8K_CMDNAME(SET_RATE);
+ MWL8K_CMDNAME(USE_FIXED_RATE);
+ MWL8K_CMDNAME(RTS_THRESHOLD);
+ MWL8K_CMDNAME(ENCRYPTION);
+ default:
+ snprintf(buf, bufsize, "0x%x", cmd);
+ }
+#undef MWL8K_CMDNAME
+
+ return buf;
+}
+
+/* Hardware and firmware reset */
+static void mwl8k_hw_reset(struct mwl8k_priv *priv)
+{
+ iowrite32(MWL8K_H2A_INT_RESET,
+ priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ iowrite32(MWL8K_H2A_INT_RESET,
+ priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ msleep(20);
+}
+
+/* Release fw image */
+static void mwl8k_release_fw(struct firmware **fw)
+{
+ if (*fw == NULL)
+ return;
+ release_firmware(*fw);
+ *fw = NULL;
+}
+
+static void mwl8k_release_firmware(struct mwl8k_priv *priv)
+{
+ mwl8k_release_fw(&priv->fw.ucode);
+ mwl8k_release_fw(&priv->fw.helper);
+}
+
+/* Request fw image */
+static int mwl8k_request_fw(struct mwl8k_priv *priv,
+ const char *fname, struct firmware **fw)
+{
+ /* release current image */
+ if (*fw != NULL)
+ mwl8k_release_fw(fw);
+
+ return request_firmware((const struct firmware **)fw,
+ fname, &priv->pdev->dev);
+}
+
+static int mwl8k_request_firmware(struct mwl8k_priv *priv, u32 part_num)
+{
+ u8 filename[64];
+ int rc;
+
+ priv->part_num = part_num;
+
+ snprintf(filename, sizeof(filename),
+ "mwl8k/helper_%u.fw", priv->part_num);
+
+ rc = mwl8k_request_fw(priv, filename, &priv->fw.helper);
+ if (rc) {
+ printk(KERN_ERR
+ "%s Error requesting helper firmware file %s\n",
+ pci_name(priv->pdev), filename);
+ return rc;
+ }
+
+ snprintf(filename, sizeof(filename),
+ "mwl8k/fmimage_%u.fw", priv->part_num);
+
+ rc = mwl8k_request_fw(priv, filename, &priv->fw.ucode);
+ if (rc) {
+ printk(KERN_ERR "%s Error requesting firmware file %s\n",
+ pci_name(priv->pdev), filename);
+ mwl8k_release_fw(&priv->fw.helper);
+ return rc;
+ }
+
+ return 0;
+}
+
+struct mwl8k_cmd_pkt {
+ __le16 code;
+ __le16 length;
+ __le16 seq_num;
+ __le16 result;
+ char payload[0];
+} __attribute__((packed));
+
+/*
+ * Firmware loading.
+ */
+static int
+mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
+{
+ void __iomem *regs = priv->regs;
+ dma_addr_t dma_addr;
+ int rc;
+ int loops;
+
+ dma_addr = pci_map_single(priv->pdev, data, length, PCI_DMA_TODEVICE);
+ if (pci_dma_mapping_error(priv->pdev, dma_addr))
+ return -ENOMEM;
+
+ iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
+ iowrite32(0, regs + MWL8K_HIU_INT_CODE);
+ iowrite32(MWL8K_H2A_INT_DOORBELL,
+ regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ iowrite32(MWL8K_H2A_INT_DUMMY,
+ regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+
+ rc = -ETIMEDOUT;
+ loops = 1000;
+ do {
+ u32 int_code;
+
+ int_code = ioread32(regs + MWL8K_HIU_INT_CODE);
+ if (int_code == MWL8K_INT_CODE_CMD_FINISHED) {
+ iowrite32(0, regs + MWL8K_HIU_INT_CODE);
+ rc = 0;
+ break;
+ }
+
+ udelay(1);
+ } while (--loops);
+
+ pci_unmap_single(priv->pdev, dma_addr, length, PCI_DMA_TODEVICE);
+
+ /*
+ * Clear 'command done' interrupt bit.
+ */
+ loops = 1000;
+ do {
+ u32 status;
+
+ status = ioread32(priv->regs +
+ MWL8K_HIU_A2H_INTERRUPT_STATUS);
+ if (status & MWL8K_A2H_INT_OPC_DONE) {
+ iowrite32(~MWL8K_A2H_INT_OPC_DONE,
+ priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+ ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+ break;
+ }
+
+ udelay(1);
+ } while (--loops);
+
+ return rc;
+}
+
+static int mwl8k_load_fw_image(struct mwl8k_priv *priv,
+ const u8 *data, size_t length)
+{
+ struct mwl8k_cmd_pkt *cmd;
+ int done;
+ int rc = 0;
+
+ cmd = kmalloc(sizeof(*cmd) + 256, GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD);
+ cmd->seq_num = 0;
+ cmd->result = 0;
+
+ done = 0;
+ while (length) {
+ int block_size = length > 256 ? 256 : length;
+
+ memcpy(cmd->payload, data + done, block_size);
+ cmd->length = cpu_to_le16(block_size);
+
+ rc = mwl8k_send_fw_load_cmd(priv, cmd,
+ sizeof(*cmd) + block_size);
+ if (rc)
+ break;
+
+ done += block_size;
+ length -= block_size;
+ }
+
+ if (!rc) {
+ cmd->length = 0;
+ rc = mwl8k_send_fw_load_cmd(priv, cmd, sizeof(*cmd));
+ }
+
+ kfree(cmd);
+
+ return rc;
+}
+
+static int mwl8k_feed_fw_image(struct mwl8k_priv *priv,
+ const u8 *data, size_t length)
+{
+ unsigned char *buffer;
+ int may_continue, rc = 0;
+ u32 done, prev_block_size;
+
+ buffer = kmalloc(1024, GFP_KERNEL);
+ if (buffer == NULL)
+ return -ENOMEM;
+
+ done = 0;
+ prev_block_size = 0;
+ may_continue = 1000;
+ while (may_continue > 0) {
+ u32 block_size;
+
+ block_size = ioread32(priv->regs + MWL8K_HIU_SCRATCH);
+ if (block_size & 1) {
+ block_size &= ~1;
+ may_continue--;
+ } else {
+ done += prev_block_size;
+ length -= prev_block_size;
+ }
+
+ if (block_size > 1024 || block_size > length) {
+ rc = -EOVERFLOW;
+ break;
+ }
+
+ if (length == 0) {
+ rc = 0;
+ break;
+ }
+
+ if (block_size == 0) {
+ rc = -EPROTO;
+ may_continue--;
+ udelay(1);
+ continue;
+ }
+
+ prev_block_size = block_size;
+ memcpy(buffer, data + done, block_size);
+
+ rc = mwl8k_send_fw_load_cmd(priv, buffer, block_size);
+ if (rc)
+ break;
+ }
+
+ if (!rc && length != 0)
+ rc = -EREMOTEIO;
+
+ kfree(buffer);
+
+ return rc;
+}
+
+static int mwl8k_load_firmware(struct mwl8k_priv *priv)
+{
+ int loops, rc;
+
+ const u8 *ucode = priv->fw.ucode->data;
+ size_t ucode_len = priv->fw.ucode->size;
+ const u8 *helper = priv->fw.helper->data;
+ size_t helper_len = priv->fw.helper->size;
+
+ if (!memcmp(ucode, "\x01\x00\x00\x00", 4)) {
+ rc = mwl8k_load_fw_image(priv, helper, helper_len);
+ if (rc) {
+ printk(KERN_ERR "%s: unable to load firmware "
+ "helper image\n", pci_name(priv->pdev));
+ return rc;
+ }
+ msleep(1);
+
+ rc = mwl8k_feed_fw_image(priv, ucode, ucode_len);
+ } else {
+ rc = mwl8k_load_fw_image(priv, ucode, ucode_len);
+ }
+
+ if (rc) {
+ printk(KERN_ERR "%s: unable to load firmware data\n",
+ pci_name(priv->pdev));
+ return rc;
+ }
+
+ iowrite32(MWL8K_MODE_STA, priv->regs + MWL8K_HIU_GEN_PTR);
+ msleep(1);
+
+ loops = 200000;
+ do {
+ if (ioread32(priv->regs + MWL8K_HIU_INT_CODE)
+ == MWL8K_FWSTA_READY)
+ break;
+ udelay(1);
+ } while (--loops);
+
+ return loops ? 0 : -ETIMEDOUT;
+}
+
+
+/*
+ * Defines shared between transmission and reception.
+ */
+/* HT control fields for firmware */
+struct ewc_ht_info {
+ __le16 control1;
+ __le16 control2;
+ __le16 control3;
+} __attribute__((packed));
+
+/* Firmware Station database operations */
+#define MWL8K_STA_DB_ADD_ENTRY 0
+#define MWL8K_STA_DB_MODIFY_ENTRY 1
+#define MWL8K_STA_DB_DEL_ENTRY 2
+#define MWL8K_STA_DB_FLUSH 3
+
+/* Peer Entry flags - used to define the type of the peer node */
+#define MWL8K_PEER_TYPE_ACCESSPOINT 2
+#define MWL8K_PEER_TYPE_ADHOC_STATION 4
+
+#define MWL8K_IEEE_LEGACY_DATA_RATES 12
+#define MWL8K_MCS_BITMAP_SIZE 16
+#define pad_size 16
+
+struct peer_capability_info {
+ /* Peer type - AP vs. STA. */
+ __u8 peer_type;
+
+ /* Basic 802.11 capabilities from assoc resp. */
+ __le16 basic_caps;
+
+ /* Set if peer supports 802.11n high throughput (HT). */
+ __u8 ht_support;
+
+ /* Valid if HT is supported. */
+ __le16 ht_caps;
+ __u8 extended_ht_caps;
+ struct ewc_ht_info ewc_info;
+
+ /* Legacy rate table. Intersection of our rates and peer rates. */
+ __u8 legacy_rates[MWL8K_IEEE_LEGACY_DATA_RATES];
+
+ /* HT rate table. Intersection of our rates and peer rates. */
+ __u8 ht_rates[MWL8K_MCS_BITMAP_SIZE];
+ __u8 pad[pad_size];
+
+ /* If set, interoperability mode, no proprietary extensions. */
+ __u8 interop;
+ __u8 pad2;
+ __u8 station_id;
+ __le16 amsdu_enabled;
+} __attribute__((packed));
+
+/* Inline functions to manipulate QoS field in data descriptor. */
+static inline u16 mwl8k_qos_setbit_tid(u16 qos, u8 tid)
+{
+ u16 val_mask = 0x000f;
+ u16 qos_mask = ~val_mask;
+
+ /* TID bits 0-3 */
+ return (qos & qos_mask) | (tid & val_mask);
+}
+
+static inline u16 mwl8k_qos_setbit_eosp(u16 qos)
+{
+ u16 val_mask = 1 << 4;
+
+ /* End of Service Period Bit 4 */
+ return qos | val_mask;
+}
+
+static inline u16 mwl8k_qos_setbit_ack(u16 qos, u8 ack_policy)
+{
+ u16 val_mask = 0x3;
+ u8 shift = 5;
+ u16 qos_mask = ~(val_mask << shift);
+
+ /* Ack Policy Bit 5-6 */
+ return (qos & qos_mask) | ((ack_policy & val_mask) << shift);
+}
+
+static inline u16 mwl8k_qos_setbit_amsdu(u16 qos)
+{
+ u16 val_mask = 1 << 7;
+
+ /* AMSDU present Bit 7 */
+ return qos | val_mask;
+}
+
+static inline u16 mwl8k_qos_setbit_qlen(u16 qos, u8 len)
+{
+ u16 val_mask = 0xff;
+ u8 shift = 8;
+ u16 qos_mask = ~(val_mask << shift);
+
+ /* Queue Length Bits 8-15 */
+ return (qos & qos_mask) | ((len & val_mask) << shift);
+}
+
+/* DMA header used by firmware and hardware. */
+struct mwl8k_dma_data {
+ __le16 fwlen;
+ struct ieee80211_hdr wh;
+} __attribute__((packed));
+
+/* Routines to add/remove DMA header from skb. */
+static inline int mwl8k_remove_dma_header(struct sk_buff *skb)
+{
+ struct mwl8k_dma_data *tr = (struct mwl8k_dma_data *)(skb->data);
+ void *dst, *src = &tr->wh;
+ __le16 fc = tr->wh.frame_control;
+ int hdrlen = ieee80211_hdrlen(fc);
+ u16 space = sizeof(struct mwl8k_dma_data) - hdrlen;
+
+ dst = (void *)tr + space;
+ if (dst != src) {
+ memmove(dst, src, hdrlen);
+ skb_pull(skb, space);
+ }
+
+ return 0;
+}
+
+static inline struct sk_buff *mwl8k_add_dma_header(struct sk_buff *skb)
+{
+ struct ieee80211_hdr *wh;
+ u32 hdrlen, pktlen;
+ struct mwl8k_dma_data *tr;
+
+ wh = (struct ieee80211_hdr *)skb->data;
+ hdrlen = ieee80211_hdrlen(wh->frame_control);
+ pktlen = skb->len;
+
+ /*
+ * Copy up/down the 802.11 header; the firmware requires
+ * we present a 2-byte payload length followed by a
+ * 4-address header (w/o QoS), followed (optionally) by
+ * any WEP/ExtIV header (but only filled in for CCMP).
+ */
+ if (hdrlen != sizeof(struct mwl8k_dma_data))
+ skb_push(skb, sizeof(struct mwl8k_dma_data) - hdrlen);
+
+ tr = (struct mwl8k_dma_data *)skb->data;
+ if (wh != &tr->wh)
+ memmove(&tr->wh, wh, hdrlen);
+
+ /* Clear addr4 */
+ memset(tr->wh.addr4, 0, IEEE80211_ADDR_LEN);
+
+ /*
+ * Firmware length is the length of the fully formed "802.11
+ * payload". That is, everything except for the 802.11 header.
+ * This includes all crypto material including the MIC.
+ */
+ tr->fwlen = cpu_to_le16(pktlen - hdrlen);
+
+ return skb;
+}
+
+
+/*
+ * Packet reception.
+ */
+#define MWL8K_RX_CTRL_KEY_INDEX_MASK 0x30
+#define MWL8K_RX_CTRL_OWNED_BY_HOST 0x02
+#define MWL8K_RX_CTRL_AMPDU 0x01
+
+struct mwl8k_rx_desc {
+ __le16 pkt_len;
+ __u8 link_quality;
+ __u8 noise_level;
+ __le32 pkt_phys_addr;
+ __le32 next_rx_desc_phys_addr;
+ __le16 qos_control;
+ __le16 rate_info;
+ __le32 pad0[4];
+ __u8 rssi;
+ __u8 channel;
+ __le16 pad1;
+ __u8 rx_ctrl;
+ __u8 rx_status;
+ __u8 pad2[2];
+} __attribute__((packed));
+
+#define MWL8K_RX_DESCS 256
+#define MWL8K_RX_MAXSZ 3800
+
+static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_rx_queue *rxq = priv->rxq + index;
+ int size;
+ int i;
+
+ rxq->rx_desc_count = 0;
+ rxq->rx_head = 0;
+ rxq->rx_tail = 0;
+
+ size = MWL8K_RX_DESCS * sizeof(struct mwl8k_rx_desc);
+
+ rxq->rx_desc_area =
+ pci_alloc_consistent(priv->pdev, size, &rxq->rx_desc_dma);
+ if (rxq->rx_desc_area == NULL) {
+ printk(KERN_ERR "%s: failed to alloc RX descriptors\n",
+ priv->name);
+ return -ENOMEM;
+ }
+ memset(rxq->rx_desc_area, 0, size);
+
+ rxq->rx_skb = kmalloc(MWL8K_RX_DESCS *
+ sizeof(*rxq->rx_skb), GFP_KERNEL);
+ if (rxq->rx_skb == NULL) {
+ printk(KERN_ERR "%s: failed to alloc RX skbuff list\n",
+ priv->name);
+ pci_free_consistent(priv->pdev, size,
+ rxq->rx_desc_area, rxq->rx_desc_dma);
+ return -ENOMEM;
+ }
+ memset(rxq->rx_skb, 0, MWL8K_RX_DESCS * sizeof(*rxq->rx_skb));
+
+ for (i = 0; i < MWL8K_RX_DESCS; i++) {
+ struct mwl8k_rx_desc *rx_desc;
+ int nexti;
+
+ rx_desc = rxq->rx_desc_area + i;
+ nexti = (i + 1) % MWL8K_RX_DESCS;
+
+ rx_desc->next_rx_desc_phys_addr =
+ cpu_to_le32(rxq->rx_desc_dma
+ + nexti * sizeof(*rx_desc));
+ rx_desc->rx_ctrl =
+ cpu_to_le32(MWL8K_RX_CTRL_OWNED_BY_HOST);
+ }
+
+ return 0;
+}
+
+static int rxq_refill(struct ieee80211_hw *hw, int index, int limit)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_rx_queue *rxq = priv->rxq + index;
+ int refilled;
+
+ refilled = 0;
+ while (rxq->rx_desc_count < MWL8K_RX_DESCS && limit--) {
+ struct sk_buff *skb;
+ int rx;
+
+ skb = dev_alloc_skb(MWL8K_RX_MAXSZ);
+ if (skb == NULL)
+ break;
+
+ rxq->rx_desc_count++;
+
+ rx = rxq->rx_tail;
+ rxq->rx_tail = (rx + 1) % MWL8K_RX_DESCS;
+
+ rxq->rx_desc_area[rx].pkt_phys_addr =
+ cpu_to_le32(pci_map_single(priv->pdev, skb->data,
+ MWL8K_RX_MAXSZ, DMA_FROM_DEVICE));
+
+ rxq->rx_desc_area[rx].pkt_len = cpu_to_le16(MWL8K_RX_MAXSZ);
+ rxq->rx_skb[rx] = skb;
+ wmb();
+ rxq->rx_desc_area[rx].rx_ctrl = 0;
+
+ refilled++;
+ }
+
+ return refilled;
+}
+
+/* Must be called only when the card's reception is completely halted */
+static void mwl8k_rxq_deinit(struct ieee80211_hw *hw, int index)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_rx_queue *rxq = priv->rxq + index;
+ int i;
+
+ for (i = 0; i < MWL8K_RX_DESCS; i++) {
+ if (rxq->rx_skb[i] != NULL) {
+ unsigned long addr;
+
+ addr = le32_to_cpu(rxq->rx_desc_area[i].pkt_phys_addr);
+ pci_unmap_single(priv->pdev, addr, MWL8K_RX_MAXSZ,
+ PCI_DMA_FROMDEVICE);
+ kfree_skb(rxq->rx_skb[i]);
+ rxq->rx_skb[i] = NULL;
+ }
+ }
+
+ kfree(rxq->rx_skb);
+ rxq->rx_skb = NULL;
+
+ pci_free_consistent(priv->pdev,
+ MWL8K_RX_DESCS * sizeof(struct mwl8k_rx_desc),
+ rxq->rx_desc_area, rxq->rx_desc_dma);
+ rxq->rx_desc_area = NULL;
+}
+
+
+/*
+ * Scan a list of BSSIDs to process for finalize join.
+ * Allows for extension to process multiple BSSIDs.
+ */
+static inline int
+mwl8k_capture_bssid(struct mwl8k_priv *priv, struct ieee80211_hdr *wh)
+{
+ return priv->capture_beacon &&
+ ieee80211_is_beacon(wh->frame_control) &&
+ !compare_ether_addr(wh->addr3, priv->capture_bssid);
+}
+
+static inline void mwl8k_save_beacon(struct mwl8k_priv *priv,
+ struct sk_buff *skb)
+{
+ priv->capture_beacon = false;
+ memset(priv->capture_bssid, 0, IEEE80211_ADDR_LEN);
+
+ /*
+ * Use GFP_ATOMIC as rxq_process is called from
+ * the primary interrupt handler, memory allocation call
+ * must not sleep.
+ */
+ priv->beacon_skb = skb_copy(skb, GFP_ATOMIC);
+ if (priv->beacon_skb != NULL)
+ queue_work(priv->config_wq,
+ &priv->finalize_join_worker);
+}
+
+static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_rx_queue *rxq = priv->rxq + index;
+ int processed;
+
+ processed = 0;
+ while (rxq->rx_desc_count && limit--) {
+ struct mwl8k_rx_desc *rx_desc;
+ struct sk_buff *skb;
+ struct ieee80211_rx_status status;
+ unsigned long addr;
+ struct ieee80211_hdr *wh;
+
+ rx_desc = rxq->rx_desc_area + rxq->rx_head;
+ if (!(rx_desc->rx_ctrl & MWL8K_RX_CTRL_OWNED_BY_HOST))
+ break;
+ rmb();
+
+ skb = rxq->rx_skb[rxq->rx_head];
+ rxq->rx_skb[rxq->rx_head] = NULL;
+
+ rxq->rx_head = (rxq->rx_head + 1) % MWL8K_RX_DESCS;
+ rxq->rx_desc_count--;
+
+ addr = le32_to_cpu(rx_desc->pkt_phys_addr);
+ pci_unmap_single(priv->pdev, addr,
+ MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
+
+ skb_put(skb, le16_to_cpu(rx_desc->pkt_len));
+ if (mwl8k_remove_dma_header(skb)) {
+ dev_kfree_skb(skb);
+ continue;
+ }
+
+ wh = (struct ieee80211_hdr *)skb->data;
+
+ /*
+ * Check for pending join operation. save a copy of
+ * the beacon and schedule a tasklet to send finalize
+ * join command to the firmware.
+ */
+ if (mwl8k_capture_bssid(priv, wh))
+ mwl8k_save_beacon(priv, skb);
+
+ memset(&status, 0, sizeof(status));
+ status.mactime = 0;
+ status.signal = -rx_desc->rssi;
+ status.noise = -rx_desc->noise_level;
+ status.qual = rx_desc->link_quality;
+ status.antenna = 1;
+ status.rate_idx = 1;
+ status.flag = 0;
+ status.band = IEEE80211_BAND_2GHZ;
+ status.freq = ieee80211_channel_to_frequency(rx_desc->channel);
+ ieee80211_rx_irqsafe(hw, skb, &status);
+
+ processed++;
+ }
+
+ return processed;
+}
+
+
+/*
+ * Packet transmission.
+ */
+
+/* Transmit queue assignment. */
+enum {
+ MWL8K_WME_AC_BK = 0, /* background access */
+ MWL8K_WME_AC_BE = 1, /* best effort access */
+ MWL8K_WME_AC_VI = 2, /* video access */
+ MWL8K_WME_AC_VO = 3, /* voice access */
+};
+
+/* Transmit packet ACK policy */
+#define MWL8K_TXD_ACK_POLICY_NORMAL 0
+#define MWL8K_TXD_ACK_POLICY_NONE 1
+#define MWL8K_TXD_ACK_POLICY_NO_EXPLICIT 2
+#define MWL8K_TXD_ACK_POLICY_BLOCKACK 3
+
+#define GET_TXQ(_ac) (\
+ ((_ac) == WME_AC_VO) ? MWL8K_WME_AC_VO : \
+ ((_ac) == WME_AC_VI) ? MWL8K_WME_AC_VI : \
+ ((_ac) == WME_AC_BK) ? MWL8K_WME_AC_BK : \
+ MWL8K_WME_AC_BE)
+
+#define MWL8K_TXD_STATUS_IDLE 0x00000000
+#define MWL8K_TXD_STATUS_USED 0x00000001
+#define MWL8K_TXD_STATUS_OK 0x00000001
+#define MWL8K_TXD_STATUS_OK_RETRY 0x00000002
+#define MWL8K_TXD_STATUS_OK_MORE_RETRY 0x00000004
+#define MWL8K_TXD_STATUS_MULTICAST_TX 0x00000008
+#define MWL8K_TXD_STATUS_BROADCAST_TX 0x00000010
+#define MWL8K_TXD_STATUS_FAILED_LINK_ERROR 0x00000020
+#define MWL8K_TXD_STATUS_FAILED_EXCEED_LIMIT 0x00000040
+#define MWL8K_TXD_STATUS_FAILED_AGING 0x00000080
+#define MWL8K_TXD_STATUS_HOST_CMD 0x40000000
+#define MWL8K_TXD_STATUS_FW_OWNED 0x80000000
+#define MWL8K_TXD_SOFTSTALE 0x80
+#define MWL8K_TXD_SOFTSTALE_MGMT_RETRY 0x01
+
+struct mwl8k_tx_desc {
+ __le32 status;
+ __u8 data_rate;
+ __u8 tx_priority;
+ __le16 qos_control;
+ __le32 pkt_phys_addr;
+ __le16 pkt_len;
+ __u8 dest_MAC_addr[IEEE80211_ADDR_LEN];
+ __le32 next_tx_desc_phys_addr;
+ __le32 reserved;
+ __le16 rate_info;
+ __u8 peer_id;
+ __u8 tx_frag_cnt;
+} __attribute__((packed));
+
+#define MWL8K_TX_DESCS 128
+
+static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_tx_queue *txq = priv->txq + index;
+ int size;
+ int i;
+
+ memset(&txq->tx_stats, 0,
+ sizeof(struct ieee80211_tx_queue_stats));
+ txq->tx_stats.limit = MWL8K_TX_DESCS;
+ txq->tx_head = 0;
+ txq->tx_tail = 0;
+
+ size = MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc);
+
+ txq->tx_desc_area =
+ pci_alloc_consistent(priv->pdev, size, &txq->tx_desc_dma);
+ if (txq->tx_desc_area == NULL) {
+ printk(KERN_ERR "%s: failed to alloc TX descriptors\n",
+ priv->name);
+ return -ENOMEM;
+ }
+ memset(txq->tx_desc_area, 0, size);
+
+ txq->tx_skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->tx_skb),
+ GFP_KERNEL);
+ if (txq->tx_skb == NULL) {
+ printk(KERN_ERR "%s: failed to alloc TX skbuff list\n",
+ priv->name);
+ pci_free_consistent(priv->pdev, size,
+ txq->tx_desc_area, txq->tx_desc_dma);
+ return -ENOMEM;
+ }
+ memset(txq->tx_skb, 0, MWL8K_TX_DESCS * sizeof(*txq->tx_skb));
+
+ for (i = 0; i < MWL8K_TX_DESCS; i++) {
+ struct mwl8k_tx_desc *tx_desc;
+ int nexti;
+
+ tx_desc = txq->tx_desc_area + i;
+ nexti = (i + 1) % MWL8K_TX_DESCS;
+
+ tx_desc->status = 0;
+ tx_desc->next_tx_desc_phys_addr =
+ cpu_to_le32(txq->tx_desc_dma +
+ nexti * sizeof(*tx_desc));
+ }
+
+ return 0;
+}
+
+static inline void mwl8k_tx_start(struct mwl8k_priv *priv)
+{
+ iowrite32(MWL8K_H2A_INT_PPA_READY,
+ priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ iowrite32(MWL8K_H2A_INT_DUMMY,
+ priv->regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ ioread32(priv->regs + MWL8K_HIU_INT_CODE);
+}
+
+static inline int mwl8k_txq_busy(struct mwl8k_priv *priv)
+{
+ return priv->pending_tx_pkts;
+}
+
+struct mwl8k_txq_info {
+ u32 fw_owned;
+ u32 drv_owned;
+ u32 unused;
+ u32 len;
+ u32 head;
+ u32 tail;
+};
+
+static int mwl8k_scan_tx_ring(struct mwl8k_priv *priv,
+ struct mwl8k_txq_info txinfo[],
+ u32 num_queues)
+{
+ int count, desc, status;
+ struct mwl8k_tx_queue *txq;
+ struct mwl8k_tx_desc *tx_desc;
+ int ndescs = 0;
+
+ memset(txinfo, 0, num_queues * sizeof(struct mwl8k_txq_info));
+ spin_lock_bh(&priv->tx_lock);
+ for (count = 0; count < num_queues; count++) {
+ txq = priv->txq + count;
+ txinfo[count].len = txq->tx_stats.len;
+ txinfo[count].head = txq->tx_head;
+ txinfo[count].tail = txq->tx_tail;
+ for (desc = 0; desc < MWL8K_TX_DESCS; desc++) {
+ tx_desc = txq->tx_desc_area + desc;
+ status = le32_to_cpu(tx_desc->status);
+
+ if (status & MWL8K_TXD_STATUS_FW_OWNED)
+ txinfo[count].fw_owned++;
+ else
+ txinfo[count].drv_owned++;
+
+ if (tx_desc->pkt_len == 0)
+ txinfo[count].unused++;
+ }
+ }
+ spin_unlock_bh(&priv->tx_lock);
+
+ return ndescs;
+}
+
+static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw, u32 delay_ms)
+{
+ u32 count = 0;
+ unsigned long timeout = 0;
+ struct mwl8k_priv *priv = hw->priv;
+ DECLARE_COMPLETION_ONSTACK(cmd_wait);
+
+ might_sleep();
+
+ if (priv->tx_wait != NULL)
+ printk(KERN_ERR "WARNING Previous TXWaitEmpty instance\n");
+
+ spin_lock_bh(&priv->tx_lock);
+ count = mwl8k_txq_busy(priv);
+ if (count) {
+ priv->tx_wait = &cmd_wait;
+ if (priv->radio_state)
+ mwl8k_tx_start(priv);
+ }
+ spin_unlock_bh(&priv->tx_lock);
+
+ if (count) {
+ struct mwl8k_txq_info txinfo[4];
+ int index;
+ int newcount;
+
+ timeout = wait_for_completion_timeout(&cmd_wait,
+ msecs_to_jiffies(delay_ms));
+ if (timeout)
+ return 0;
+
+ spin_lock_bh(&priv->tx_lock);
+ priv->tx_wait = NULL;
+ newcount = mwl8k_txq_busy(priv);
+ spin_unlock_bh(&priv->tx_lock);
+
+ printk(KERN_ERR "%s(%u) TIMEDOUT:%ums Pend:%u-->%u\n",
+ __func__, __LINE__, delay_ms, count, newcount);
+
+ mwl8k_scan_tx_ring(priv, txinfo, 4);
+ for (index = 0 ; index < 4; index++)
+ printk(KERN_ERR
+ "TXQ:%u L:%u H:%u T:%u FW:%u DRV:%u U:%u\n",
+ index,
+ txinfo[index].len,
+ txinfo[index].head,
+ txinfo[index].tail,
+ txinfo[index].fw_owned,
+ txinfo[index].drv_owned,
+ txinfo[index].unused);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+#define MWL8K_TXD_OK (MWL8K_TXD_STATUS_OK | \
+ MWL8K_TXD_STATUS_OK_RETRY | \
+ MWL8K_TXD_STATUS_OK_MORE_RETRY)
+#define MWL8K_TXD_SUCCESS(stat) ((stat) & MWL8K_TXD_OK)
+#define MWL8K_TXD_FAIL_RETRY(stat) \
+ ((stat) & (MWL8K_TXD_STATUS_FAILED_EXCEED_LIMIT))
+
+static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_tx_queue *txq = priv->txq + index;
+ int wake = 0;
+
+ while (txq->tx_stats.len > 0) {
+ int tx;
+ int rc;
+ struct mwl8k_tx_desc *tx_desc;
+ unsigned long addr;
+ size_t size;
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+ u32 status;
+
+ rc = 0;
+ tx = txq->tx_head;
+ tx_desc = txq->tx_desc_area + tx;
+
+ status = le32_to_cpu(tx_desc->status);
+
+ if (status & MWL8K_TXD_STATUS_FW_OWNED) {
+ if (!force)
+ break;
+ tx_desc->status &=
+ ~cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED);
+ }
+
+ txq->tx_head = (tx + 1) % MWL8K_TX_DESCS;
+ BUG_ON(txq->tx_stats.len == 0);
+ txq->tx_stats.len--;
+ priv->pending_tx_pkts--;
+
+ addr = le32_to_cpu(tx_desc->pkt_phys_addr);
+ size = (u32)(le16_to_cpu(tx_desc->pkt_len));
+ skb = txq->tx_skb[tx].skb;
+ txq->tx_skb[tx].skb = NULL;
+
+ BUG_ON(skb == NULL);
+ pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE);
+
+ rc = mwl8k_remove_dma_header(skb);
+
+ /* Mark descriptor as unused */
+ tx_desc->pkt_phys_addr = 0;
+ tx_desc->pkt_len = 0;
+
+ if (txq->tx_skb[tx].clone) {
+ /* Replace with original skb
+ * before returning to stack
+ * as buffer has been cloned
+ */
+ dev_kfree_skb(skb);
+ skb = txq->tx_skb[tx].clone;
+ txq->tx_skb[tx].clone = NULL;
+ }
+
+ if (rc) {
+ /* Something has gone wrong here.
+ * Failed to remove DMA header.
+ * Print error message and drop packet.
+ */
+ printk(KERN_ERR "%s: Error removing DMA header from "
+ "tx skb 0x%p.\n", priv->name, skb);
+
+ dev_kfree_skb(skb);
+ continue;
+ }
+
+ info = IEEE80211_SKB_CB(skb);
+ ieee80211_tx_info_clear_status(info);
+
+ /* Convert firmware status stuff into tx_status */
+ if (MWL8K_TXD_SUCCESS(status)) {
+ /* Transmit OK */
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ }
+
+ ieee80211_tx_status_irqsafe(hw, skb);
+
+ wake = !priv->inconfig && priv->radio_state;
+ }
+
+ if (wake)
+ ieee80211_wake_queue(hw, index);
+}
+
+/* must be called only when the card's transmit is completely halted */
+static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_tx_queue *txq = priv->txq + index;
+
+ mwl8k_txq_reclaim(hw, index, 1);
+
+ kfree(txq->tx_skb);
+ txq->tx_skb = NULL;
+
+ pci_free_consistent(priv->pdev,
+ MWL8K_TX_DESCS * sizeof(struct mwl8k_tx_desc),
+ txq->tx_desc_area, txq->tx_desc_dma);
+ txq->tx_desc_area = NULL;
+}
+
+static int
+mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct ieee80211_tx_info *tx_info;
+ struct ieee80211_hdr *wh;
+ struct mwl8k_tx_queue *txq;
+ struct mwl8k_tx_desc *tx;
+ struct mwl8k_dma_data *tr;
+ struct mwl8k_vif *mwl8k_vif;
+ struct sk_buff *org_skb = skb;
+ dma_addr_t dma;
+ u16 qos = 0;
+ bool qosframe = false, ampduframe = false;
+ bool mcframe = false, eapolframe = false;
+ bool amsduframe = false;
+ __le16 fc;
+
+ txq = priv->txq + index;
+ tx = txq->tx_desc_area + txq->tx_tail;
+
+ BUG_ON(txq->tx_skb[txq->tx_tail].skb != NULL);
+
+ /*
+ * Append HW DMA header to start of packet. Drop packet if
+ * there is not enough space or a failure to unshare/unclone
+ * the skb.
+ */
+ skb = mwl8k_add_dma_header(skb);
+
+ if (skb == NULL) {
+ printk(KERN_DEBUG "%s: failed to prepend HW DMA "
+ "header, dropping TX frame.\n", priv->name);
+ dev_kfree_skb(org_skb);
+ return NETDEV_TX_OK;
+ }
+
+ tx_info = IEEE80211_SKB_CB(skb);
+ mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
+ tr = (struct mwl8k_dma_data *)skb->data;
+ wh = &tr->wh;
+ fc = wh->frame_control;
+ qosframe = ieee80211_is_data_qos(fc);
+ mcframe = is_multicast_ether_addr(wh->addr1);
+ ampduframe = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
+
+ if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+ u16 seqno = mwl8k_vif->seqno;
+ wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+ wh->seq_ctrl |= cpu_to_le16(seqno << 4);
+ mwl8k_vif->seqno = seqno++ % 4096;
+ }
+
+ if (qosframe)
+ qos = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(wh)));
+
+ dma = pci_map_single(priv->pdev, skb->data,
+ skb->len, PCI_DMA_TODEVICE);
+
+ if (pci_dma_mapping_error(priv->pdev, dma)) {
+ printk(KERN_DEBUG "%s: failed to dma map skb, "
+ "dropping TX frame.\n", priv->name);
+
+ if (org_skb != NULL)
+ dev_kfree_skb(org_skb);
+ if (skb != NULL)
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ /* Set desc header, cpu bit order. */
+ tx->status = 0;
+ tx->data_rate = 0;
+ tx->tx_priority = index;
+ tx->qos_control = 0;
+ tx->rate_info = 0;
+ tx->peer_id = mwl8k_vif->peer_id;
+
+ amsduframe = !!(qos & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT);
+
+ /* Setup firmware control bit fields for each frame type. */
+ if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) {
+ tx->data_rate = 0;
+ qos = mwl8k_qos_setbit_eosp(qos);
+ /* Set Queue size to unspecified */
+ qos = mwl8k_qos_setbit_qlen(qos, 0xff);
+ } else if (ieee80211_is_data(fc)) {
+ tx->data_rate = 1;
+ if (mcframe)
+ tx->status |= MWL8K_TXD_STATUS_MULTICAST_TX;
+
+ /*
+ * Tell firmware to not send EAPOL pkts in an
+ * aggregate. Verify against mac80211 tx path. If
+ * stack turns off AMPDU for an EAPOL frame this
+ * check will be removed.
+ */
+ if (eapolframe) {
+ qos = mwl8k_qos_setbit_ack(qos,
+ MWL8K_TXD_ACK_POLICY_NORMAL);
+ } else {
+ /* Send pkt in an aggregate if AMPDU frame. */
+ if (ampduframe)
+ qos = mwl8k_qos_setbit_ack(qos,
+ MWL8K_TXD_ACK_POLICY_BLOCKACK);
+ else
+ qos = mwl8k_qos_setbit_ack(qos,
+ MWL8K_TXD_ACK_POLICY_NORMAL);
+
+ if (amsduframe)
+ qos = mwl8k_qos_setbit_amsdu(qos);
+ }
+ }
+
+ /* Convert to little endian */
+ tx->qos_control = cpu_to_le16(qos);
+ tx->status = cpu_to_le32(tx->status);
+ tx->pkt_phys_addr = cpu_to_le32(dma);
+ tx->pkt_len = cpu_to_le16(skb->len);
+
+ txq->tx_skb[txq->tx_tail].skb = skb;
+ txq->tx_skb[txq->tx_tail].clone =
+ skb == org_skb ? NULL : org_skb;
+
+ spin_lock_bh(&priv->tx_lock);
+
+ tx->status = cpu_to_le32(MWL8K_TXD_STATUS_OK |
+ MWL8K_TXD_STATUS_FW_OWNED);
+ wmb();
+ txq->tx_stats.len++;
+ priv->pending_tx_pkts++;
+ txq->tx_stats.count++;
+ txq->tx_tail++;
+
+ if (txq->tx_tail == MWL8K_TX_DESCS)
+ txq->tx_tail = 0;
+ if (txq->tx_head == txq->tx_tail)
+ ieee80211_stop_queue(hw, index);
+
+ if (priv->inconfig) {
+ /*
+ * Silently queue packet when we are in the middle of
+ * a config cycle. Notify firmware only if we are
+ * waiting for TXQs to empty. If a packet is sent
+ * before .config() is complete, perhaps it is better
+ * to drop the packet, as the channel is being changed
+ * and the packet will end up on the wrong channel.
+ */
+ printk(KERN_ERR "%s(): WARNING TX activity while "
+ "in config\n", __func__);
+
+ if (priv->tx_wait != NULL)
+ mwl8k_tx_start(priv);
+ } else
+ mwl8k_tx_start(priv);
+
+ spin_unlock_bh(&priv->tx_lock);
+
+ return NETDEV_TX_OK;
+}
+
+
+/*
+ * Command processing.
+ */
+
+/* Timeout firmware commands after 2000ms */
+#define MWL8K_CMD_TIMEOUT_MS 2000
+
+static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
+{
+ DECLARE_COMPLETION_ONSTACK(cmd_wait);
+ struct mwl8k_priv *priv = hw->priv;
+ void __iomem *regs = priv->regs;
+ dma_addr_t dma_addr;
+ unsigned int dma_size;
+ int rc;
+ u16 __iomem *result;
+ unsigned long timeout = 0;
+ u8 buf[32];
+
+ cmd->result = 0xFFFF;
+ dma_size = le16_to_cpu(cmd->length);
+ dma_addr = pci_map_single(priv->pdev, cmd, dma_size,
+ PCI_DMA_BIDIRECTIONAL);
+ if (pci_dma_mapping_error(priv->pdev, dma_addr))
+ return -ENOMEM;
+
+ if (priv->hostcmd_wait != NULL)
+ printk(KERN_ERR "WARNING host command in progress\n");
+
+ spin_lock_irq(&priv->fw_lock);
+ priv->hostcmd_wait = &cmd_wait;
+ iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
+ iowrite32(MWL8K_H2A_INT_DOORBELL,
+ regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ iowrite32(MWL8K_H2A_INT_DUMMY,
+ regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
+ spin_unlock_irq(&priv->fw_lock);
+
+ timeout = wait_for_completion_timeout(&cmd_wait,
+ msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS));
+
+ result = &cmd->result;
+ if (!timeout) {
+ spin_lock_irq(&priv->fw_lock);
+ priv->hostcmd_wait = NULL;
+ spin_unlock_irq(&priv->fw_lock);
+ printk(KERN_ERR "%s: Command %s timeout after %u ms\n",
+ priv->name,
+ mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
+ MWL8K_CMD_TIMEOUT_MS);
+ rc = -ETIMEDOUT;
+ } else {
+ rc = *result ? -EINVAL : 0;
+ if (rc)
+ printk(KERN_ERR "%s: Command %s error 0x%x\n",
+ priv->name,
+ mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
+ *result);
+ }
+
+ pci_unmap_single(priv->pdev, dma_addr, dma_size,
+ PCI_DMA_BIDIRECTIONAL);
+ return rc;
+}
+
+/*
+ * GET_HW_SPEC.
+ */
+struct mwl8k_cmd_get_hw_spec {
+ struct mwl8k_cmd_pkt header;
+ __u8 hw_rev;
+ __u8 host_interface;
+ __le16 num_mcaddrs;
+ __u8 perm_addr[IEEE80211_ADDR_LEN];
+ __le16 region_code;
+ __le32 fw_rev;
+ __le32 ps_cookie;
+ __le32 caps;
+ __u8 mcs_bitmap[16];
+ __le32 rx_queue_ptr;
+ __le32 num_tx_queues;
+ __le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
+ __le32 caps2;
+ __le32 num_tx_desc_per_queue;
+ __le32 total_rx_desc;
+} __attribute__((packed));
+
+static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_cmd_get_hw_spec *cmd;
+ int rc;
+ int i;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_HW_SPEC);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
+ cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
+ cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rx_desc_dma);
+ cmd->num_tx_queues = MWL8K_TX_QUEUES;
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].tx_desc_dma);
+ cmd->num_tx_desc_per_queue = MWL8K_TX_DESCS;
+ cmd->total_rx_desc = MWL8K_RX_DESCS;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+
+ if (!rc) {
+ SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
+ priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
+ priv->fw_rev = cmd->fw_rev;
+ priv->hw_rev = cmd->hw_rev;
+ priv->region_code = le16_to_cpu(cmd->region_code);
+ }
+
+ kfree(cmd);
+ return rc;
+}
+
+/*
+ * CMD_MAC_MULTICAST_ADR.
+ */
+struct mwl8k_cmd_mac_multicast_adr {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le16 numaddr;
+ __u8 addr[1][IEEE80211_ADDR_LEN];
+};
+
+#define MWL8K_ENABLE_RX_MULTICAST 0x000F
+static int mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw,
+ int mc_count,
+ struct dev_addr_list *mclist)
+{
+ struct mwl8k_cmd_mac_multicast_adr *cmd;
+ int index = 0;
+ int rc;
+ int size = sizeof(*cmd) + ((mc_count - 1) * IEEE80211_ADDR_LEN);
+ cmd = kzalloc(size, GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR);
+ cmd->header.length = cpu_to_le16(size);
+ cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST);
+ cmd->numaddr = cpu_to_le16(mc_count);
+ while ((index < mc_count) && mclist) {
+ if (mclist->da_addrlen != IEEE80211_ADDR_LEN) {
+ rc = -EINVAL;
+ goto mwl8k_cmd_mac_multicast_adr_exit;
+ }
+ memcpy(cmd->addr[index], mclist->da_addr, IEEE80211_ADDR_LEN);
+ index++;
+ mclist = mclist->next;
+ }
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+
+mwl8k_cmd_mac_multicast_adr_exit:
+ kfree(cmd);
+ return rc;
+}
+
+/*
+ * CMD_802_11_GET_STAT.
+ */
+struct mwl8k_cmd_802_11_get_stat {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le32 stats[64];
+} __attribute__((packed));
+
+#define MWL8K_STAT_ACK_FAILURE 9
+#define MWL8K_STAT_RTS_FAILURE 12
+#define MWL8K_STAT_FCS_ERROR 24
+#define MWL8K_STAT_RTS_SUCCESS 11
+
+static int mwl8k_cmd_802_11_get_stat(struct ieee80211_hw *hw,
+ struct ieee80211_low_level_stats *stats)
+{
+ struct mwl8k_cmd_802_11_get_stat *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_STAT);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_GET);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ if (!rc) {
+ stats->dot11ACKFailureCount =
+ le32_to_cpu(cmd->stats[MWL8K_STAT_ACK_FAILURE]);
+ stats->dot11RTSFailureCount =
+ le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_FAILURE]);
+ stats->dot11FCSErrorCount =
+ le32_to_cpu(cmd->stats[MWL8K_STAT_FCS_ERROR]);
+ stats->dot11RTSSuccessCount =
+ le32_to_cpu(cmd->stats[MWL8K_STAT_RTS_SUCCESS]);
+ }
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_802_11_RADIO_CONTROL.
+ */
+struct mwl8k_cmd_802_11_radio_control {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le16 control;
+ __le16 radio_on;
+} __attribute__((packed));
+
+static int mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, int enable)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_cmd_802_11_radio_control *cmd;
+ int rc;
+
+ if (((enable & MWL8K_RADIO_ENABLE) == priv->radio_state) &&
+ !(enable & MWL8K_RADIO_FORCE))
+ return 0;
+
+ enable &= MWL8K_RADIO_ENABLE;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_RADIO_CONTROL);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+ cmd->control = cpu_to_le16(priv->radio_preamble);
+ cmd->radio_on = cpu_to_le16(enable ? 0x0001 : 0x0000);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ if (!rc)
+ priv->radio_state = enable;
+
+ return rc;
+}
+
+static int
+mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
+{
+ struct mwl8k_priv *priv;
+
+ if (hw == NULL || hw->priv == NULL)
+ return -EINVAL;
+ priv = hw->priv;
+
+ priv->radio_preamble = (short_preamble ?
+ MWL8K_RADIO_SHORT_PREAMBLE :
+ MWL8K_RADIO_LONG_PREAMBLE);
+
+ return mwl8k_cmd_802_11_radio_control(hw,
+ MWL8K_RADIO_ENABLE | MWL8K_RADIO_FORCE);
+}
+
+/*
+ * CMD_802_11_RF_TX_POWER.
+ */
+#define MWL8K_TX_POWER_LEVEL_TOTAL 8
+
+struct mwl8k_cmd_802_11_rf_tx_power {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le16 support_level;
+ __le16 current_level;
+ __le16 reserved;
+ __le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
+} __attribute__((packed));
+
+static int mwl8k_cmd_802_11_rf_tx_power(struct ieee80211_hw *hw, int dBm)
+{
+ struct mwl8k_cmd_802_11_rf_tx_power *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_RF_TX_POWER);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+ cmd->support_level = cpu_to_le16(dBm);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_PRE_SCAN.
+ */
+struct mwl8k_cmd_set_pre_scan {
+ struct mwl8k_cmd_pkt header;
+} __attribute__((packed));
+
+static int mwl8k_cmd_set_pre_scan(struct ieee80211_hw *hw)
+{
+ struct mwl8k_cmd_set_pre_scan *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_PRE_SCAN);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_POST_SCAN.
+ */
+struct mwl8k_cmd_set_post_scan {
+ struct mwl8k_cmd_pkt header;
+ __le32 isibss;
+ __u8 bssid[IEEE80211_ADDR_LEN];
+} __attribute__((packed));
+
+static int
+mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 mac[IEEE80211_ADDR_LEN])
+{
+ struct mwl8k_cmd_set_post_scan *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_POST_SCAN);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->isibss = 0;
+ memcpy(cmd->bssid, mac, IEEE80211_ADDR_LEN);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_RF_CHANNEL.
+ */
+struct mwl8k_cmd_set_rf_channel {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __u8 current_channel;
+ __le32 channel_flags;
+} __attribute__((packed));
+
+static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
+ struct ieee80211_channel *channel)
+{
+ struct mwl8k_cmd_set_rf_channel *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RF_CHANNEL);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+ cmd->current_channel = channel->hw_value;
+ if (channel->band == IEEE80211_BAND_2GHZ)
+ cmd->channel_flags = cpu_to_le32(0x00000081);
+ else
+ cmd->channel_flags = cpu_to_le32(0x00000000);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_SLOT.
+ */
+struct mwl8k_cmd_set_slot {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __u8 short_slot;
+} __attribute__((packed));
+
+static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, int slot_time)
+{
+ struct mwl8k_cmd_set_slot *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+ cmd->short_slot = slot_time == MWL8K_SHORT_SLOTTIME ? 1 : 0;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_MIMO_CONFIG.
+ */
+struct mwl8k_cmd_mimo_config {
+ struct mwl8k_cmd_pkt header;
+ __le32 action;
+ __u8 rx_antenna_map;
+ __u8 tx_antenna_map;
+} __attribute__((packed));
+
+static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx)
+{
+ struct mwl8k_cmd_mimo_config *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_MIMO_CONFIG);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le32((u32)MWL8K_CMD_SET);
+ cmd->rx_antenna_map = rx;
+ cmd->tx_antenna_map = tx;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_ENABLE_SNIFFER.
+ */
+struct mwl8k_cmd_enable_sniffer {
+ struct mwl8k_cmd_pkt header;
+ __le32 action;
+} __attribute__((packed));
+
+static int mwl8k_enable_sniffer(struct ieee80211_hw *hw, bool enable)
+{
+ struct mwl8k_cmd_enable_sniffer *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = enable ? cpu_to_le32((u32)MWL8K_CMD_SET) : 0;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_RATE_ADAPT_MODE.
+ */
+struct mwl8k_cmd_set_rate_adapt_mode {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le16 mode;
+} __attribute__((packed));
+
+static int mwl8k_cmd_setrateadaptmode(struct ieee80211_hw *hw, __u16 mode)
+{
+ struct mwl8k_cmd_set_rate_adapt_mode *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATEADAPT_MODE);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(MWL8K_CMD_SET);
+ cmd->mode = cpu_to_le16(mode);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_WMM_MODE.
+ */
+struct mwl8k_cmd_set_wmm {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+} __attribute__((packed));
+
+static int mwl8k_set_wmm(struct ieee80211_hw *hw, bool enable)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_cmd_set_wmm *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = enable ? cpu_to_le16(MWL8K_CMD_SET) : 0;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ if (!rc)
+ priv->wmm_mode = enable;
+
+ return rc;
+}
+
+/*
+ * CMD_SET_RTS_THRESHOLD.
+ */
+struct mwl8k_cmd_rts_threshold {
+ struct mwl8k_cmd_pkt header;
+ __le16 action;
+ __le16 threshold;
+} __attribute__((packed));
+
+static int mwl8k_rts_threshold(struct ieee80211_hw *hw,
+ u16 action, u16 *threshold)
+{
+ struct mwl8k_cmd_rts_threshold *cmd;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->action = cpu_to_le16(action);
+ cmd->threshold = cpu_to_le16(*threshold);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_EDCA_PARAMS.
+ */
+struct mwl8k_cmd_set_edca_params {
+ struct mwl8k_cmd_pkt header;
+
+ /* See MWL8K_SET_EDCA_XXX below */
+ __le16 action;
+
+ /* TX opportunity in units of 32 us */
+ __le16 txop;
+
+ /* Log exponent of max contention period: 0...15*/
+ __u8 log_cw_max;
+
+ /* Log exponent of min contention period: 0...15 */
+ __u8 log_cw_min;
+
+ /* Adaptive interframe spacing in units of 32us */
+ __u8 aifs;
+
+ /* TX queue to configure */
+ __u8 txq;
+} __attribute__((packed));
+
+#define MWL8K_GET_EDCA_ALL 0
+#define MWL8K_SET_EDCA_CW 0x01
+#define MWL8K_SET_EDCA_TXOP 0x02
+#define MWL8K_SET_EDCA_AIFS 0x04
+
+#define MWL8K_SET_EDCA_ALL (MWL8K_SET_EDCA_CW | \
+ MWL8K_SET_EDCA_TXOP | \
+ MWL8K_SET_EDCA_AIFS)
+
+static int
+mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
+ __u16 cw_min, __u16 cw_max,
+ __u8 aifs, __u16 txop)
+{
+ struct mwl8k_cmd_set_edca_params *cmd;
+ u32 log_cw_min, log_cw_max;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ log_cw_min = ilog2(cw_min+1);
+ log_cw_max = ilog2(cw_max+1);
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL);
+ cmd->txop = cpu_to_le16(txop);
+ cmd->log_cw_max = (u8)log_cw_max;
+ cmd->log_cw_min = (u8)log_cw_min;
+ cmd->aifs = aifs;
+ cmd->txq = qnum;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_FINALIZE_JOIN.
+ */
+
+/* FJ beacon buffer size is compiled into the firmware. */
+#define MWL8K_FJ_BEACON_MAXLEN 128
+
+struct mwl8k_cmd_finalize_join {
+ struct mwl8k_cmd_pkt header;
+ __le32 sleep_interval; /* Number of beacon periods to sleep */
+ __u8 beacon_data[MWL8K_FJ_BEACON_MAXLEN];
+} __attribute__((packed));
+
+static int mwl8k_finalize_join(struct ieee80211_hw *hw, void *frame,
+ __u16 framelen, __u16 dtim)
+{
+ struct mwl8k_cmd_finalize_join *cmd;
+ struct ieee80211_mgmt *payload = frame;
+ u16 hdrlen;
+ u32 payload_len;
+ int rc;
+
+ if (frame == NULL)
+ return -EINVAL;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ if (dtim)
+ cmd->sleep_interval = cpu_to_le32(dtim);
+ else
+ cmd->sleep_interval = cpu_to_le32(1);
+
+ hdrlen = ieee80211_hdrlen(payload->frame_control);
+
+ payload_len = framelen > hdrlen ? framelen - hdrlen : 0;
+
+ /* XXX TBD Might just have to abort and return an error */
+ if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
+ printk(KERN_ERR "%s(): WARNING: Incomplete beacon "
+ "sent to firmware. Sz=%u MAX=%u\n", __func__,
+ payload_len, MWL8K_FJ_BEACON_MAXLEN);
+
+ payload_len = payload_len > MWL8K_FJ_BEACON_MAXLEN ?
+ MWL8K_FJ_BEACON_MAXLEN : payload_len;
+
+ if (payload && payload_len)
+ memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+ return rc;
+}
+
+/*
+ * CMD_UPDATE_STADB.
+ */
+struct mwl8k_cmd_update_sta_db {
+ struct mwl8k_cmd_pkt header;
+
+ /* See STADB_ACTION_TYPE */
+ __le32 action;
+
+ /* Peer MAC address */
+ __u8 peer_addr[IEEE80211_ADDR_LEN];
+
+ __le32 reserved;
+
+ /* Peer info - valid during add/update. */
+ struct peer_capability_info peer_info;
+} __attribute__((packed));
+
+static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif, __u32 action)
+{
+ struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
+ struct ieee80211_bss_conf *info = &mv_vif->bss_info;
+ struct mwl8k_cmd_update_sta_db *cmd;
+ struct peer_capability_info *peer_info;
+ struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
+ DECLARE_MAC_BUF(mac);
+ int rc;
+ __u8 count, *rates;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ cmd->action = cpu_to_le32(action);
+ peer_info = &cmd->peer_info;
+ memcpy(cmd->peer_addr, mv_vif->bssid, IEEE80211_ADDR_LEN);
+
+ switch (action) {
+ case MWL8K_STA_DB_ADD_ENTRY:
+ case MWL8K_STA_DB_MODIFY_ENTRY:
+ /* Build peer_info block */
+ peer_info->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
+ peer_info->basic_caps = cpu_to_le16(info->assoc_capability);
+ peer_info->interop = 1;
+ peer_info->amsdu_enabled = 0;
+
+ rates = peer_info->legacy_rates;
+ for (count = 0 ; count < mv_vif->legacy_nrates; count++)
+ rates[count] = bitrates[count].hw_value;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ if (rc == 0)
+ mv_vif->peer_id = peer_info->station_id;
+
+ break;
+
+ case MWL8K_STA_DB_DEL_ENTRY:
+ case MWL8K_STA_DB_FLUSH:
+ default:
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ if (rc == 0)
+ mv_vif->peer_id = 0;
+ break;
+ }
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_AID.
+ */
+#define IEEE80211_OPMODE_DISABLED 0x00
+#define IEEE80211_OPMODE_NON_MEMBER_PROT_MODE 0x01
+#define IEEE80211_OPMODE_ONE_20MHZ_STA_PROT_MODE 0x02
+#define IEEE80211_OPMODE_HTMIXED_PROT_MODE 0x03
+
+#define MWL8K_RATE_INDEX_MAX_ARRAY 14
+
+#define MWL8K_FRAME_PROT_DISABLED 0x00
+#define MWL8K_FRAME_PROT_11G 0x07
+#define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY 0x02
+#define MWL8K_FRAME_PROT_11N_HT_ALL 0x06
+#define MWL8K_FRAME_PROT_MASK 0x07
+
+struct mwl8k_cmd_update_set_aid {
+ struct mwl8k_cmd_pkt header;
+ __le16 aid;
+
+ /* AP's MAC address (BSSID) */
+ __u8 bssid[IEEE80211_ADDR_LEN];
+ __le16 protection_mode;
+ __u8 supp_rates[MWL8K_RATE_INDEX_MAX_ARRAY];
+} __attribute__((packed));
+
+static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
+ struct ieee80211_bss_conf *info = &mv_vif->bss_info;
+ struct mwl8k_cmd_update_set_aid *cmd;
+ struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
+ int count;
+ u16 prot_mode;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+ cmd->aid = cpu_to_le16(info->aid);
+
+ memcpy(cmd->bssid, mv_vif->bssid, IEEE80211_ADDR_LEN);
+
+ prot_mode = MWL8K_FRAME_PROT_DISABLED;
+
+ if (info->use_cts_prot) {
+ prot_mode = MWL8K_FRAME_PROT_11G;
+ } else {
+ switch (info->ht.operation_mode &
+ IEEE80211_HT_OP_MODE_PROTECTION) {
+ case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
+ prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY;
+ break;
+ case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
+ prot_mode = MWL8K_FRAME_PROT_11N_HT_ALL;
+ break;
+ default:
+ prot_mode = MWL8K_FRAME_PROT_DISABLED;
+ break;
+ }
+ }
+
+ cmd->protection_mode = cpu_to_le16(prot_mode);
+
+ for (count = 0; count < mv_vif->legacy_nrates; count++)
+ cmd->supp_rates[count] = bitrates[count].hw_value;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_SET_RATE.
+ */
+struct mwl8k_cmd_update_rateset {
+ struct mwl8k_cmd_pkt header;
+ __u8 legacy_rates[MWL8K_RATE_INDEX_MAX_ARRAY];
+
+ /* Bitmap for supported MCS codes. */
+ __u8 mcs_set[MWL8K_IEEE_LEGACY_DATA_RATES];
+ __u8 reserved[MWL8K_IEEE_LEGACY_DATA_RATES];
+} __attribute__((packed));
+
+static int mwl8k_update_rateset(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
+ struct mwl8k_cmd_update_rateset *cmd;
+ struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
+ int count;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ for (count = 0; count < mv_vif->legacy_nrates; count++)
+ cmd->legacy_rates[count] = bitrates[count].hw_value;
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+/*
+ * CMD_USE_FIXED_RATE.
+ */
+#define MWL8K_RATE_TABLE_SIZE 8
+#define MWL8K_UCAST_RATE 0
+#define MWL8K_MCAST_RATE 1
+#define MWL8K_BCAST_RATE 2
+
+#define MWL8K_USE_FIXED_RATE 0x0001
+#define MWL8K_USE_AUTO_RATE 0x0002
+
+struct mwl8k_rate_entry {
+ /* Set to 1 if HT rate, 0 if legacy. */
+ __le32 is_ht_rate;
+
+ /* Set to 1 to use retry_count field. */
+ __le32 enable_retry;
+
+ /* Specified legacy rate or MCS. */
+ __le32 rate;
+
+ /* Number of allowed retries. */
+ __le32 retry_count;
+} __attribute__((packed));
+
+struct mwl8k_rate_table {
+ /* 1 to allow specified rate and below */
+ __le32 allow_rate_drop;
+ __le32 num_rates;
+ struct mwl8k_rate_entry rate_entry[MWL8K_RATE_TABLE_SIZE];
+} __attribute__((packed));
+
+struct mwl8k_cmd_use_fixed_rate {
+ struct mwl8k_cmd_pkt header;
+ __le32 action;
+ struct mwl8k_rate_table rate_table;
+
+ /* Unicast, Broadcast or Multicast */
+ __le32 rate_type;
+ __le32 reserved1;
+ __le32 reserved2;
+} __attribute__((packed));
+
+static int mwl8k_cmd_use_fixed_rate(struct ieee80211_hw *hw,
+ u32 action, u32 rate_type, struct mwl8k_rate_table *rate_table)
+{
+ struct mwl8k_cmd_use_fixed_rate *cmd;
+ int count;
+ int rc;
+
+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
+ cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+ cmd->action = cpu_to_le32(action);
+ cmd->rate_type = cpu_to_le32(rate_type);
+
+ if (rate_table != NULL) {
+ /* Copy over each field manually so
+ * that bitflipping can be done
+ */
+ cmd->rate_table.allow_rate_drop =
+ cpu_to_le32(rate_table->allow_rate_drop);
+ cmd->rate_table.num_rates =
+ cpu_to_le32(rate_table->num_rates);
+
+ for (count = 0; count < rate_table->num_rates; count++) {
+ struct mwl8k_rate_entry *dst =
+ &cmd->rate_table.rate_entry[count];
+ struct mwl8k_rate_entry *src =
+ &rate_table->rate_entry[count];
+
+ dst->is_ht_rate = cpu_to_le32(src->is_ht_rate);
+ dst->enable_retry = cpu_to_le32(src->enable_retry);
+ dst->rate = cpu_to_le32(src->rate);
+ dst->retry_count = cpu_to_le32(src->retry_count);
+ }
+ }
+
+ rc = mwl8k_post_cmd(hw, &cmd->header);
+ kfree(cmd);
+
+ return rc;
+}
+
+
+/*
+ * Interrupt handling.
+ */
+static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
+{
+ struct ieee80211_hw *hw = dev_id;
+ struct mwl8k_priv *priv = hw->priv;
+ u32 status;
+
+ status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+ iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+
+ status &= priv->int_mask;
+ if (!status)
+ return IRQ_NONE;
+
+ if (status & MWL8K_A2H_INT_TX_DONE)
+ tasklet_schedule(&priv->tx_reclaim_task);
+
+ if (status & MWL8K_A2H_INT_RX_READY) {
+ while (rxq_process(hw, 0, 1))
+ rxq_refill(hw, 0, 1);
+ }
+
+ if (status & MWL8K_A2H_INT_OPC_DONE) {
+ if (priv->hostcmd_wait != NULL) {
+ complete(priv->hostcmd_wait);
+ priv->hostcmd_wait = NULL;
+ }
+ }
+
+ if (status & MWL8K_A2H_INT_QUEUE_EMPTY) {
+ if (!priv->inconfig &&
+ priv->radio_state &&
+ mwl8k_txq_busy(priv))
+ mwl8k_tx_start(priv);
+ }
+
+ return IRQ_HANDLED;
+}
+
+
+/*
+ * Core driver operations.
+ */
+static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ int index = skb_get_queue_mapping(skb);
+ int rc;
+
+ if (priv->current_channel == NULL) {
+ printk(KERN_DEBUG "%s: dropped TX frame since radio "
+ "disabled\n", priv->name);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
+ rc = mwl8k_txq_xmit(hw, index, skb);
+
+ return rc;
+}
+
+struct mwl8k_work_struct {
+ /* Initialized by mwl8k_queue_work(). */
+ struct work_struct wt;
+
+ /* Required field passed in to mwl8k_queue_work(). */
+ struct ieee80211_hw *hw;
+
+ /* Required field passed in to mwl8k_queue_work(). */
+ int (*wfunc)(struct work_struct *w);
+
+ /* Initialized by mwl8k_queue_work(). */
+ struct completion *cmd_wait;
+
+ /* Result code. */
+ int rc;
+
+ /*
+ * Optional field. Refer to explanation of MWL8K_WQ_XXX_XXX
+ * flags for explanation. Defaults to MWL8K_WQ_DEFAULT_OPTIONS.
+ */
+ u32 options;
+
+ /* Optional field. Defaults to MWL8K_CONFIG_TIMEOUT_MS. */
+ unsigned long timeout_ms;
+
+ /* Optional field. Defaults to MWL8K_WQ_TXWAIT_ATTEMPTS. */
+ u32 txwait_attempts;
+
+ /* Optional field. Defaults to MWL8K_TXWAIT_MS. */
+ u32 tx_timeout_ms;
+ u32 step;
+};
+
+/* Flags controlling behavior of config queue requests */
+
+/* Caller spins while waiting for completion. */
+#define MWL8K_WQ_SPIN 0x00000001
+
+/* Wait for TX queues to empty before proceeding with configuration. */
+#define MWL8K_WQ_TX_WAIT_EMPTY 0x00000002
+
+/* Queue request and return immediately. */
+#define MWL8K_WQ_POST_REQUEST 0x00000004
+
+/*
+ * Caller sleeps and waits for task complete notification.
+ * Do not use in atomic context.
+ */
+#define MWL8K_WQ_SLEEP 0x00000008
+
+/* Free work struct when task is done. */
+#define MWL8K_WQ_FREE_WORKSTRUCT 0x00000010
+
+/*
+ * Config request is queued and returns to caller imediately. Use
+ * this in atomic context. Work struct is freed by mwl8k_queue_work()
+ * when this flag is set.
+ */
+#define MWL8K_WQ_QUEUE_ONLY (MWL8K_WQ_POST_REQUEST | \
+ MWL8K_WQ_FREE_WORKSTRUCT)
+
+/* Default work queue behavior is to sleep and wait for tx completion. */
+#define MWL8K_WQ_DEFAULT_OPTIONS (MWL8K_WQ_SLEEP | MWL8K_WQ_TX_WAIT_EMPTY)
+
+/*
+ * Default config request timeout. Add adjustments to make sure the
+ * config thread waits long enough for both tx wait and cmd wait before
+ * timing out.
+ */
+
+/* Time to wait for all TXQs to drain. TX Doorbell is pressed each time. */
+#define MWL8K_TXWAIT_TIMEOUT_MS 1000
+
+/* Default number of TX wait attempts. */
+#define MWL8K_WQ_TXWAIT_ATTEMPTS 4
+
+/* Total time to wait for TXQ to drain. */
+#define MWL8K_TXWAIT_MS (MWL8K_TXWAIT_TIMEOUT_MS * \
+ MWL8K_WQ_TXWAIT_ATTEMPTS)
+
+/* Scheduling slop. */
+#define MWL8K_OS_SCHEDULE_OVERHEAD_MS 200
+
+#define MWL8K_CONFIG_TIMEOUT_MS (MWL8K_CMD_TIMEOUT_MS + \
+ MWL8K_TXWAIT_MS + \
+ MWL8K_OS_SCHEDULE_OVERHEAD_MS)
+
+static void mwl8k_config_thread(struct work_struct *wt)
+{
+ struct mwl8k_work_struct *worker = (struct mwl8k_work_struct *)wt;
+ struct ieee80211_hw *hw = worker->hw;
+ struct mwl8k_priv *priv = hw->priv;
+ int rc = 0;
+
+ spin_lock_irq(&priv->tx_lock);
+ priv->inconfig = true;
+ spin_unlock_irq(&priv->tx_lock);
+
+ ieee80211_stop_queues(hw);
+
+ /*
+ * Wait for host queues to drain before doing PHY
+ * reconfiguration. This avoids interrupting any in-flight
+ * DMA transfers to the hardware.
+ */
+ if (worker->options & MWL8K_WQ_TX_WAIT_EMPTY) {
+ u32 timeout;
+ u32 time_remaining;
+ u32 iter;
+ u32 tx_wait_attempts = worker->txwait_attempts;
+
+ time_remaining = worker->tx_timeout_ms;
+ if (!tx_wait_attempts)
+ tx_wait_attempts = 1;
+
+ timeout = worker->tx_timeout_ms/tx_wait_attempts;
+ if (!timeout)
+ timeout = 1;
+
+ iter = tx_wait_attempts;
+ do {
+ int wait_time;
+
+ if (time_remaining > timeout) {
+ time_remaining -= timeout;
+ wait_time = timeout;
+ } else
+ wait_time = time_remaining;
+
+ if (!wait_time)
+ wait_time = 1;
+
+ rc = mwl8k_tx_wait_empty(hw, wait_time);
+ if (rc)
+ printk(KERN_ERR "%s() txwait timeout=%ums "
+ "Retry:%u/%u\n", __func__, timeout,
+ tx_wait_attempts - iter + 1,
+ tx_wait_attempts);
+
+ } while (rc && --iter);
+
+ rc = iter ? 0 : -ETIMEDOUT;
+ }
+ if (!rc)
+ rc = worker->wfunc(wt);
+
+ spin_lock_irq(&priv->tx_lock);
+ priv->inconfig = false;
+ if (priv->pending_tx_pkts && priv->radio_state)
+ mwl8k_tx_start(priv);
+ spin_unlock_irq(&priv->tx_lock);
+ ieee80211_wake_queues(hw);
+
+ worker->rc = rc;
+ if (worker->options & MWL8K_WQ_SLEEP)
+ complete(worker->cmd_wait);
+
+ if (worker->options & MWL8K_WQ_FREE_WORKSTRUCT)
+ kfree(wt);
+}
+
+static int mwl8k_queue_work(struct ieee80211_hw *hw,
+ struct mwl8k_work_struct *worker,
+ struct workqueue_struct *wqueue,
+ int (*wfunc)(struct work_struct *w))
+{
+ unsigned long timeout = 0;
+ int rc = 0;
+
+ DECLARE_COMPLETION_ONSTACK(cmd_wait);
+
+ if (!worker->timeout_ms)
+ worker->timeout_ms = MWL8K_CONFIG_TIMEOUT_MS;
+
+ if (!worker->options)
+ worker->options = MWL8K_WQ_DEFAULT_OPTIONS;
+
+ if (!worker->txwait_attempts)
+ worker->txwait_attempts = MWL8K_WQ_TXWAIT_ATTEMPTS;
+
+ if (!worker->tx_timeout_ms)
+ worker->tx_timeout_ms = MWL8K_TXWAIT_MS;
+
+ worker->hw = hw;
+ worker->cmd_wait = &cmd_wait;
+ worker->rc = 1;
+ worker->wfunc = wfunc;
+
+ INIT_WORK(&worker->wt, mwl8k_config_thread);
+ queue_work(wqueue, &worker->wt);
+
+ if (worker->options & MWL8K_WQ_POST_REQUEST) {
+ rc = 0;
+ } else {
+ if (worker->options & MWL8K_WQ_SPIN) {
+ timeout = worker->timeout_ms;
+ while (timeout && (worker->rc > 0)) {
+ mdelay(1);
+ timeout--;
+ }
+ } else if (worker->options & MWL8K_WQ_SLEEP)
+ timeout = wait_for_completion_timeout(&cmd_wait,
+ msecs_to_jiffies(worker->timeout_ms));
+
+ if (timeout)
+ rc = worker->rc;
+ else {
+ cancel_work_sync(&worker->wt);
+ rc = -ETIMEDOUT;
+ }
+ }
+
+ return rc;
+}
+
+struct mwl8k_start_worker {
+ struct mwl8k_work_struct header;
+};
+
+static int mwl8k_start_wt(struct work_struct *wt)
+{
+ struct mwl8k_start_worker *worker = (struct mwl8k_start_worker *)wt;
+ struct ieee80211_hw *hw = worker->header.hw;
+ struct mwl8k_priv *priv = hw->priv;
+ int rc = 0;
+
+ if (priv->vif != NULL) {
+ rc = -EIO;
+ goto mwl8k_start_exit;
+ }
+
+ /* Turn on radio */
+ if (mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_ENABLE)) {
+ rc = -EIO;
+ goto mwl8k_start_exit;
+ }
+
+ /* Purge TX/RX HW queues */
+ if (mwl8k_cmd_set_pre_scan(hw)) {
+ rc = -EIO;
+ goto mwl8k_start_exit;
+ }
+
+ if (mwl8k_cmd_set_post_scan(hw, "\x00\x00\x00\x00\x00\x00")) {
+ rc = -EIO;
+ goto mwl8k_start_exit;
+ }
+
+ /* Enable firmware rate adaptation */
+ if (mwl8k_cmd_setrateadaptmode(hw, 0)) {
+ rc = -EIO;
+ goto mwl8k_start_exit;
+ }
+
+ /* Disable WMM. WMM gets enabled when stack sends WMM parms */
+ if (mwl8k_set_wmm(hw, MWL8K_WMM_DISABLE)) {
+ rc = -EIO;
+ goto mwl8k_start_exit;
+ }
+
+ /* Disable sniffer mode */
+ if (mwl8k_enable_sniffer(hw, 0))
+ rc = -EIO;
+
+mwl8k_start_exit:
+ return rc;
+}
+
+static int mwl8k_start(struct ieee80211_hw *hw)
+{
+ struct mwl8k_start_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+ int rc;
+
+ /* Enable tx reclaim tasklet */
+ tasklet_enable(&priv->tx_reclaim_task);
+
+ rc = request_irq(priv->pdev->irq, &mwl8k_interrupt,
+ IRQF_SHARED, MWL8K_NAME, hw);
+ if (rc) {
+ printk(KERN_ERR "%s: failed to register IRQ handler\n",
+ priv->name);
+ rc = -EIO;
+ goto mwl8k_start_disable_tasklet;
+ }
+
+ /* Enable interrupts */
+ iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL) {
+ rc = -ENOMEM;
+ goto mwl8k_start_disable_irq;
+ }
+
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq, mwl8k_start_wt);
+ kfree(worker);
+ if (!rc)
+ return rc;
+
+ if (rc == -ETIMEDOUT)
+ printk(KERN_ERR "%s() timed out\n", __func__);
+
+ rc = -EIO;
+
+mwl8k_start_disable_irq:
+ spin_lock_irq(&priv->tx_lock);
+ iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+ spin_unlock_irq(&priv->tx_lock);
+ free_irq(priv->pdev->irq, hw);
+
+mwl8k_start_disable_tasklet:
+ tasklet_disable(&priv->tx_reclaim_task);
+
+ return rc;
+}
+
+struct mwl8k_stop_worker {
+ struct mwl8k_work_struct header;
+};
+
+static int mwl8k_stop_wt(struct work_struct *wt)
+{
+ struct mwl8k_stop_worker *worker = (struct mwl8k_stop_worker *)wt;
+ struct ieee80211_hw *hw = worker->header.hw;
+ int rc;
+
+ rc = mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE);
+
+ return rc;
+}
+
+static void mwl8k_stop(struct ieee80211_hw *hw)
+{
+ int rc;
+ struct mwl8k_stop_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+ int i;
+
+ if (priv->vif != NULL)
+ return;
+
+ ieee80211_stop_queues(hw);
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL)
+ return;
+
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq, mwl8k_stop_wt);
+ kfree(worker);
+ if (rc == -ETIMEDOUT)
+ printk(KERN_ERR "%s() timed out\n", __func__);
+
+ /* Disable interrupts */
+ spin_lock_irq(&priv->tx_lock);
+ iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+ spin_unlock_irq(&priv->tx_lock);
+ free_irq(priv->pdev->irq, hw);
+
+ /* Stop finalize join worker */
+ cancel_work_sync(&priv->finalize_join_worker);
+ if (priv->beacon_skb != NULL)
+ dev_kfree_skb(priv->beacon_skb);
+
+ /* Stop tx reclaim tasklet */
+ tasklet_disable(&priv->tx_reclaim_task);
+
+ /* Stop config thread */
+ flush_workqueue(priv->config_wq);
+
+ /* Return all skbs to mac80211 */
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_reclaim(hw, i, 1);
+}
+
+static int mwl8k_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_vif *mwl8k_vif;
+
+ /*
+ * We only support one active interface at a time.
+ */
+ if (priv->vif != NULL)
+ return -EBUSY;
+
+ /*
+ * We only support managed interfaces for now.
+ */
+ if (conf->type != NL80211_IFTYPE_STATION &&
+ conf->type != NL80211_IFTYPE_MONITOR)
+ return -EINVAL;
+
+ /* Clean out driver private area */
+ mwl8k_vif = MWL8K_VIF(conf->vif);
+ memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
+
+ /* Save the mac address */
+ memcpy(mwl8k_vif->mac_addr, conf->mac_addr, IEEE80211_ADDR_LEN);
+
+ /* Back pointer to parent config block */
+ mwl8k_vif->priv = priv;
+
+ /* Setup initial PHY parameters */
+ memcpy(mwl8k_vif->legacy_rates ,
+ priv->rates, sizeof(mwl8k_vif->legacy_rates));
+ mwl8k_vif->legacy_nrates = ARRAY_SIZE(priv->rates);
+
+ /* Set Initial sequence number to zero */
+ mwl8k_vif->seqno = 0;
+
+ priv->vif = conf->vif;
+ priv->current_channel = NULL;
+
+ return 0;
+}
+
+static void mwl8k_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct mwl8k_priv *priv = hw->priv;
+
+ if (priv->vif == NULL)
+ return;
+
+ priv->vif = NULL;
+}
+
+struct mwl8k_config_worker {
+ struct mwl8k_work_struct header;
+ u32 changed;
+};
+
+static int mwl8k_config_wt(struct work_struct *wt)
+{
+ struct mwl8k_config_worker *worker =
+ (struct mwl8k_config_worker *)wt;
+ struct ieee80211_hw *hw = worker->header.hw;
+ struct ieee80211_conf *conf = &hw->conf;
+ struct mwl8k_priv *priv = hw->priv;
+ int rc = 0;
+
+ if (!conf->radio_enabled) {
+ mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE);
+ priv->current_channel = NULL;
+ rc = 0;
+ goto mwl8k_config_exit;
+ }
+
+ if (mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_ENABLE)) {
+ rc = -EINVAL;
+ goto mwl8k_config_exit;
+ }
+
+ priv->current_channel = conf->channel;
+
+ if (mwl8k_cmd_set_rf_channel(hw, conf->channel)) {
+ rc = -EINVAL;
+ goto mwl8k_config_exit;
+ }
+
+ if (conf->power_level > 18)
+ conf->power_level = 18;
+ if (mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level)) {
+ rc = -EINVAL;
+ goto mwl8k_config_exit;
+ }
+
+ if (mwl8k_cmd_mimo_config(hw, 0x7, 0x7))
+ rc = -EINVAL;
+
+mwl8k_config_exit:
+ return rc;
+}
+
+static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
+{
+ int rc = 0;
+ struct mwl8k_config_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL)
+ return -ENOMEM;
+
+ worker->changed = changed;
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq, mwl8k_config_wt);
+ if (rc == -ETIMEDOUT) {
+ printk(KERN_ERR "%s() timed out.\n", __func__);
+ rc = -EINVAL;
+ }
+
+ kfree(worker);
+
+ /*
+ * mac80211 will crash on anything other than -EINVAL on
+ * error. Looks like wireless extensions which calls mac80211
+ * may be the actual culprit...
+ */
+ return rc ? -EINVAL : 0;
+}
+
+static int mwl8k_config_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_if_conf *conf)
+{
+ struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
+ u32 changed = conf->changed;
+
+ if (changed & IEEE80211_IFCC_BSSID)
+ memcpy(mv_vif->bssid, conf->bssid, IEEE80211_ADDR_LEN);
+
+ return 0;
+}
+
+struct mwl8k_bss_info_changed_worker {
+ struct mwl8k_work_struct header;
+ struct ieee80211_vif *vif;
+ struct ieee80211_bss_conf *info;
+ u32 changed;
+};
+
+static int mwl8k_bss_info_changed_wt(struct work_struct *wt)
+{
+ struct mwl8k_bss_info_changed_worker *worker =
+ (struct mwl8k_bss_info_changed_worker *)wt;
+ struct ieee80211_hw *hw = worker->header.hw;
+ struct ieee80211_vif *vif = worker->vif;
+ struct ieee80211_bss_conf *info = worker->info;
+ u32 changed;
+ int rc;
+
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
+
+ changed = worker->changed;
+ priv->capture_beacon = false;
+
+ if (info->assoc) {
+ memcpy(&mwl8k_vif->bss_info, info,
+ sizeof(struct ieee80211_bss_conf));
+
+ /* Install rates */
+ if (mwl8k_update_rateset(hw, vif))
+ goto mwl8k_bss_info_changed_exit;
+
+ /* Turn on rate adaptation */
+ if (mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE,
+ MWL8K_UCAST_RATE, NULL))
+ goto mwl8k_bss_info_changed_exit;
+
+ /* Set radio preamble */
+ if (mwl8k_set_radio_preamble(hw,
+ info->use_short_preamble))
+ goto mwl8k_bss_info_changed_exit;
+
+ /* Set slot time */
+ if (mwl8k_cmd_set_slot(hw, info->use_short_slot ?
+ MWL8K_SHORT_SLOTTIME : MWL8K_LONG_SLOTTIME))
+ goto mwl8k_bss_info_changed_exit;
+
+ /* Update peer rate info */
+ if (mwl8k_cmd_update_sta_db(hw, vif,
+ MWL8K_STA_DB_MODIFY_ENTRY))
+ goto mwl8k_bss_info_changed_exit;
+
+ /* Set AID */
+ if (mwl8k_cmd_set_aid(hw, vif))
+ goto mwl8k_bss_info_changed_exit;
+
+ /*
+ * Finalize the join. Tell rx handler to process
+ * next beacon from our BSSID.
+ */
+ memcpy(priv->capture_bssid,
+ mwl8k_vif->bssid, IEEE80211_ADDR_LEN);
+ priv->capture_beacon = true;
+ } else {
+ mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
+ memset(&mwl8k_vif->bss_info, 0,
+ sizeof(struct ieee80211_bss_conf));
+ memset(mwl8k_vif->bssid, 0, IEEE80211_ADDR_LEN);
+ }
+
+mwl8k_bss_info_changed_exit:
+ rc = 0;
+ return rc;
+}
+
+static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u32 changed)
+{
+ struct mwl8k_bss_info_changed_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+ int rc;
+
+ if ((changed & BSS_CHANGED_ASSOC) == 0)
+ return;
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL)
+ return;
+
+ worker->vif = vif;
+ worker->info = info;
+ worker->changed = changed;
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq,
+ mwl8k_bss_info_changed_wt);
+ kfree(worker);
+ if (rc == -ETIMEDOUT)
+ printk(KERN_ERR "%s() timed out\n", __func__);
+}
+
+struct mwl8k_configure_filter_worker {
+ struct mwl8k_work_struct header;
+ unsigned int changed_flags;
+ unsigned int *total_flags;
+ int mc_count;
+ struct dev_addr_list *mclist;
+};
+
+#define MWL8K_SUPPORTED_IF_FLAGS FIF_BCN_PRBRESP_PROMISC
+
+static int mwl8k_configure_filter_wt(struct work_struct *wt)
+{
+ struct mwl8k_configure_filter_worker *worker =
+ (struct mwl8k_configure_filter_worker *)wt;
+
+ struct ieee80211_hw *hw = worker->header.hw;
+ unsigned int changed_flags = worker->changed_flags;
+ unsigned int *total_flags = worker->total_flags;
+ int mc_count = worker->mc_count;
+ struct dev_addr_list *mclist = worker->mclist;
+
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_vif *mv_vif;
+ int rc = 0;
+
+ if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+ if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
+ rc = mwl8k_cmd_set_pre_scan(hw);
+ else {
+ mv_vif = MWL8K_VIF(priv->vif);
+ rc = mwl8k_cmd_set_post_scan(hw, mv_vif->bssid);
+ }
+ }
+
+ if (rc)
+ goto mwl8k_configure_filter_exit;
+ if (mc_count) {
+ mc_count = mc_count < priv->num_mcaddrs ?
+ mc_count : priv->num_mcaddrs;
+ rc = mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist);
+ if (rc)
+ printk(KERN_ERR
+ "%s()Error setting multicast addresses\n",
+ __func__);
+ }
+
+mwl8k_configure_filter_exit:
+ return rc;
+}
+
+static void mwl8k_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count,
+ struct dev_addr_list *mclist)
+{
+
+ struct mwl8k_configure_filter_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+
+ /* Clear unsupported feature flags */
+ *total_flags &= MWL8K_SUPPORTED_IF_FLAGS;
+
+ if (!(changed_flags & MWL8K_SUPPORTED_IF_FLAGS) && !mc_count)
+ return;
+
+ worker = kzalloc(sizeof(*worker), GFP_ATOMIC);
+ if (worker == NULL)
+ return;
+
+ worker->header.options = MWL8K_WQ_QUEUE_ONLY | MWL8K_WQ_TX_WAIT_EMPTY;
+ worker->changed_flags = changed_flags;
+ worker->total_flags = total_flags;
+ worker->mc_count = mc_count;
+ worker->mclist = mclist;
+
+ mwl8k_queue_work(hw, &worker->header, priv->config_wq,
+ mwl8k_configure_filter_wt);
+}
+
+struct mwl8k_set_rts_threshold_worker {
+ struct mwl8k_work_struct header;
+ u32 value;
+};
+
+static int mwl8k_set_rts_threshold_wt(struct work_struct *wt)
+{
+ struct mwl8k_set_rts_threshold_worker *worker =
+ (struct mwl8k_set_rts_threshold_worker *)wt;
+
+ struct ieee80211_hw *hw = worker->header.hw;
+ u16 threshold = (u16)(worker->value);
+ int rc;
+
+ rc = mwl8k_rts_threshold(hw, MWL8K_CMD_SET, &threshold);
+
+ return rc;
+}
+
+static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+ int rc;
+ struct mwl8k_set_rts_threshold_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL)
+ return -ENOMEM;
+
+ worker->value = value;
+
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq,
+ mwl8k_set_rts_threshold_wt);
+ kfree(worker);
+
+ if (rc == -ETIMEDOUT) {
+ printk(KERN_ERR "%s() timed out\n", __func__);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+struct mwl8k_conf_tx_worker {
+ struct mwl8k_work_struct header;
+ u16 queue;
+ const struct ieee80211_tx_queue_params *params;
+};
+
+static int mwl8k_conf_tx_wt(struct work_struct *wt)
+{
+ struct mwl8k_conf_tx_worker *worker =
+ (struct mwl8k_conf_tx_worker *)wt;
+
+ struct ieee80211_hw *hw = worker->header.hw;
+ u16 queue = worker->queue;
+ const struct ieee80211_tx_queue_params *params = worker->params;
+
+ struct mwl8k_priv *priv = hw->priv;
+ int rc = 0;
+
+ if (priv->wmm_mode == MWL8K_WMM_DISABLE)
+ if (mwl8k_set_wmm(hw, MWL8K_WMM_ENABLE)) {
+ rc = -EINVAL;
+ goto mwl8k_conf_tx_exit;
+ }
+
+ if (mwl8k_set_edca_params(hw, GET_TXQ(queue), params->cw_min,
+ params->cw_max, params->aifs, params->txop))
+ rc = -EINVAL;
+mwl8k_conf_tx_exit:
+ return rc;
+}
+
+static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
+ const struct ieee80211_tx_queue_params *params)
+{
+ int rc;
+ struct mwl8k_conf_tx_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL)
+ return -ENOMEM;
+
+ worker->queue = queue;
+ worker->params = params;
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq, mwl8k_conf_tx_wt);
+ kfree(worker);
+ if (rc == -ETIMEDOUT) {
+ printk(KERN_ERR "%s() timed out\n", __func__);
+ rc = -EINVAL;
+ }
+ return rc;
+}
+
+static int mwl8k_get_tx_stats(struct ieee80211_hw *hw,
+ struct ieee80211_tx_queue_stats *stats)
+{
+ struct mwl8k_priv *priv = hw->priv;
+ struct mwl8k_tx_queue *txq;
+ int index;
+
+ spin_lock_bh(&priv->tx_lock);
+ for (index = 0; index < MWL8K_TX_QUEUES; index++) {
+ txq = priv->txq + index;
+ memcpy(&stats[index], &txq->tx_stats,
+ sizeof(struct ieee80211_tx_queue_stats));
+ }
+ spin_unlock_bh(&priv->tx_lock);
+ return 0;
+}
+
+struct mwl8k_get_stats_worker {
+ struct mwl8k_work_struct header;
+ struct ieee80211_low_level_stats *stats;
+};
+
+static int mwl8k_get_stats_wt(struct work_struct *wt)
+{
+ struct mwl8k_get_stats_worker *worker =
+ (struct mwl8k_get_stats_worker *)wt;
+
+ return mwl8k_cmd_802_11_get_stat(worker->header.hw, worker->stats);
+}
+
+static int mwl8k_get_stats(struct ieee80211_hw *hw,
+ struct ieee80211_low_level_stats *stats)
+{
+ int rc;
+ struct mwl8k_get_stats_worker *worker;
+ struct mwl8k_priv *priv = hw->priv;
+
+ worker = kzalloc(sizeof(*worker), GFP_KERNEL);
+ if (worker == NULL)
+ return -ENOMEM;
+
+ worker->stats = stats;
+ rc = mwl8k_queue_work(hw, &worker->header,
+ priv->config_wq, mwl8k_get_stats_wt);
+
+ kfree(worker);
+ if (rc == -ETIMEDOUT) {
+ printk(KERN_ERR "%s() timed out\n", __func__);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+static const struct ieee80211_ops mwl8k_ops = {
+ .tx = mwl8k_tx,
+ .start = mwl8k_start,
+ .stop = mwl8k_stop,
+ .add_interface = mwl8k_add_interface,
+ .remove_interface = mwl8k_remove_interface,
+ .config = mwl8k_config,
+ .config_interface = mwl8k_config_interface,
+ .bss_info_changed = mwl8k_bss_info_changed,
+ .configure_filter = mwl8k_configure_filter,
+ .set_rts_threshold = mwl8k_set_rts_threshold,
+ .conf_tx = mwl8k_conf_tx,
+ .get_tx_stats = mwl8k_get_tx_stats,
+ .get_stats = mwl8k_get_stats,
+};
+
+static void mwl8k_tx_reclaim_handler(unsigned long data)
+{
+ int i;
+ struct ieee80211_hw *hw = (struct ieee80211_hw *) data;
+ struct mwl8k_priv *priv = hw->priv;
+
+ spin_lock_bh(&priv->tx_lock);
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_reclaim(hw, i, 0);
+
+ if (priv->tx_wait != NULL) {
+ int count = mwl8k_txq_busy(priv);
+ if (count == 0) {
+ complete(priv->tx_wait);
+ priv->tx_wait = NULL;
+ }
+ }
+ spin_unlock_bh(&priv->tx_lock);
+}
+
+static void mwl8k_finalize_join_worker(struct work_struct *work)
+{
+ struct mwl8k_priv *priv =
+ container_of(work, struct mwl8k_priv, finalize_join_worker);
+ struct sk_buff *skb = priv->beacon_skb;
+ u8 dtim = (MWL8K_VIF(priv->vif))->bss_info.dtim_period;
+
+ mwl8k_finalize_join(priv->hw, skb->data, skb->len, dtim);
+ dev_kfree_skb(skb);
+
+ priv->beacon_skb = NULL;
+}
+
+static int __devinit mwl8k_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct ieee80211_hw *hw;
+ struct mwl8k_priv *priv;
+ DECLARE_MAC_BUF(mac);
+ int rc;
+ int i;
+ u8 *fw;
+
+ rc = pci_enable_device(pdev);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot enable new PCI device\n",
+ MWL8K_NAME);
+ return rc;
+ }
+
+ rc = pci_request_regions(pdev, MWL8K_NAME);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot obtain PCI resources\n",
+ MWL8K_NAME);
+ return rc;
+ }
+
+ pci_set_master(pdev);
+
+ hw = ieee80211_alloc_hw(sizeof(*priv), &mwl8k_ops);
+ if (hw == NULL) {
+ printk(KERN_ERR "%s: ieee80211 alloc failed\n", MWL8K_NAME);
+ rc = -ENOMEM;
+ goto err_free_reg;
+ }
+
+ priv = hw->priv;
+ priv->hw = hw;
+ priv->pdev = pdev;
+ priv->hostcmd_wait = NULL;
+ priv->tx_wait = NULL;
+ priv->inconfig = false;
+ priv->wep_enabled = 0;
+ priv->wmm_mode = false;
+ priv->pending_tx_pkts = 0;
+ strncpy(priv->name, MWL8K_NAME, sizeof(priv->name));
+
+ spin_lock_init(&priv->fw_lock);
+
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+ pci_set_drvdata(pdev, hw);
+
+ priv->regs = pci_iomap(pdev, 1, 0x10000);
+ if (priv->regs == NULL) {
+ printk(KERN_ERR "%s: Cannot map device memory\n", priv->name);
+ goto err_iounmap;
+ }
+
+ memcpy(priv->channels, mwl8k_channels, sizeof(mwl8k_channels));
+ priv->band.band = IEEE80211_BAND_2GHZ;
+ priv->band.channels = priv->channels;
+ priv->band.n_channels = ARRAY_SIZE(mwl8k_channels);
+ priv->band.bitrates = priv->rates;
+ priv->band.n_bitrates = ARRAY_SIZE(mwl8k_rates);
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
+
+ BUILD_BUG_ON(sizeof(priv->rates) != sizeof(mwl8k_rates));
+ memcpy(priv->rates, mwl8k_rates, sizeof(mwl8k_rates));
+
+ /*
+ * Extra headroom is the size of the required DMA header
+ * minus the size of the smallest 802.11 frame (CTS frame).
+ */
+ hw->extra_tx_headroom =
+ sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
+
+ hw->channel_change_time = 10;
+
+ hw->queues = MWL8K_TX_QUEUES;
+
+ hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_MONITOR);
+
+ /* Set rssi and noise values to dBm */
+ hw->flags |= (IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM);
+ hw->vif_data_size = sizeof(struct mwl8k_vif);
+ priv->vif = NULL;
+
+ /* Set default radio state and preamble */
+ priv->radio_preamble = MWL8K_RADIO_DEFAULT_PREAMBLE;
+ priv->radio_state = MWL8K_RADIO_DISABLE;
+
+ /* Finalize join worker */
+ INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
+
+ /* TX reclaim tasklet */
+ tasklet_init(&priv->tx_reclaim_task,
+ mwl8k_tx_reclaim_handler, (unsigned long)hw);
+ tasklet_disable(&priv->tx_reclaim_task);
+
+ /* Config workthread */
+ priv->config_wq = create_singlethread_workqueue("mwl8k_config");
+ if (priv->config_wq == NULL)
+ goto err_iounmap;
+
+ /* Power management cookie */
+ priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
+ if (priv->cookie == NULL)
+ goto err_iounmap;
+
+ rc = mwl8k_rxq_init(hw, 0);
+ if (rc)
+ goto err_iounmap;
+ rxq_refill(hw, 0, INT_MAX);
+
+ spin_lock_init(&priv->tx_lock);
+
+ for (i = 0; i < MWL8K_TX_QUEUES; i++) {
+ rc = mwl8k_txq_init(hw, i);
+ if (rc)
+ goto err_free_queues;
+ }
+
+ iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
+ priv->int_mask = 0;
+ iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+ iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
+ iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
+
+ rc = request_irq(priv->pdev->irq, &mwl8k_interrupt,
+ IRQF_SHARED, MWL8K_NAME, hw);
+ if (rc) {
+ printk(KERN_ERR "%s: failed to register IRQ handler\n",
+ priv->name);
+ goto err_free_queues;
+ }
+
+ /* Reset firmware and hardware */
+ mwl8k_hw_reset(priv);
+
+ /* Ask userland hotplug daemon for the device firmware */
+ rc = mwl8k_request_firmware(priv, (u32)id->driver_data);
+ if (rc) {
+ printk(KERN_ERR "%s: Firmware files not found\n", priv->name);
+ goto err_free_irq;
+ }
+
+ /* Load firmware into hardware */
+ rc = mwl8k_load_firmware(priv);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot start firmware\n", priv->name);
+ goto err_stop_firmware;
+ }
+
+ /* Reclaim memory once firmware is successfully loaded */
+ mwl8k_release_firmware(priv);
+
+ /*
+ * Temporarily enable interrupts. Initial firmware host
+ * commands use interrupts and avoids polling. Disable
+ * interrupts when done.
+ */
+ priv->int_mask |= MWL8K_A2H_EVENTS;
+
+ iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+
+ /* Get config data, mac addrs etc */
+ rc = mwl8k_cmd_get_hw_spec(hw);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot initialise firmware\n", priv->name);
+ goto err_stop_firmware;
+ }
+
+ /* Turn radio off */
+ rc = mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot disable\n", priv->name);
+ goto err_stop_firmware;
+ }
+
+ /* Disable interrupts */
+ spin_lock_irq(&priv->tx_lock);
+ iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+ spin_unlock_irq(&priv->tx_lock);
+ free_irq(priv->pdev->irq, hw);
+
+ rc = ieee80211_register_hw(hw);
+ if (rc) {
+ printk(KERN_ERR "%s: Cannot register device\n", priv->name);
+ goto err_stop_firmware;
+ }
+
+ fw = (u8 *)&priv->fw_rev;
+ printk(KERN_INFO "%s: 88W%u %s\n", priv->name, priv->part_num,
+ MWL8K_DESC);
+ printk(KERN_INFO "%s: Driver Ver:%s Firmware Ver:%u.%u.%u.%u\n",
+ priv->name, MWL8K_VERSION, fw[3], fw[2], fw[1], fw[0]);
+ printk(KERN_INFO "%s: MAC Address: %s\n", priv->name,
+ print_mac(mac, hw->wiphy->perm_addr));
+
+ return 0;
+
+err_stop_firmware:
+ mwl8k_hw_reset(priv);
+ mwl8k_release_firmware(priv);
+
+err_free_irq:
+ spin_lock_irq(&priv->tx_lock);
+ iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+ spin_unlock_irq(&priv->tx_lock);
+ free_irq(priv->pdev->irq, hw);
+
+err_free_queues:
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_deinit(hw, i);
+ mwl8k_rxq_deinit(hw, 0);
+
+err_iounmap:
+ if (priv->cookie != NULL)
+ pci_free_consistent(priv->pdev, 4,
+ priv->cookie, priv->cookie_dma);
+
+ if (priv->regs != NULL)
+ pci_iounmap(pdev, priv->regs);
+
+ if (priv->config_wq != NULL)
+ destroy_workqueue(priv->config_wq);
+
+ pci_set_drvdata(pdev, NULL);
+ ieee80211_free_hw(hw);
+
+err_free_reg:
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+
+ return rc;
+}
+
+static void __devexit mwl8k_remove(struct pci_dev *pdev)
+{
+ printk(KERN_ERR "===>%s(%u)\n", __func__, __LINE__);
+}
+
+static void __devexit mwl8k_shutdown(struct pci_dev *pdev)
+{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct mwl8k_priv *priv;
+ int i;
+
+ if (hw == NULL)
+ return;
+ priv = hw->priv;
+
+ ieee80211_stop_queues(hw);
+
+ /* Remove tx reclaim tasklet */
+ tasklet_kill(&priv->tx_reclaim_task);
+
+ /* Stop config thread */
+ destroy_workqueue(priv->config_wq);
+
+ /* Stop hardware */
+ mwl8k_hw_reset(priv);
+
+ /* Return all skbs to mac80211 */
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_reclaim(hw, i, 1);
+
+ ieee80211_unregister_hw(hw);
+
+ for (i = 0; i < MWL8K_TX_QUEUES; i++)
+ mwl8k_txq_deinit(hw, i);
+
+ mwl8k_rxq_deinit(hw, 0);
+
+ pci_free_consistent(priv->pdev, 4,
+ priv->cookie, priv->cookie_dma);
+
+ pci_iounmap(pdev, priv->regs);
+ pci_set_drvdata(pdev, NULL);
+ ieee80211_free_hw(hw);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+}
+
+static struct pci_driver mwl8k_driver = {
+ .name = MWL8K_NAME,
+ .id_table = mwl8k_table,
+ .probe = mwl8k_probe,
+ .remove = __devexit_p(mwl8k_remove),
+ .shutdown = __devexit_p(mwl8k_shutdown),
+};
+
+static int __init mwl8k_init(void)
+{
+ return pci_register_driver(&mwl8k_driver);
+}
+
+static void __exit mwl8k_exit(void)
+{
+ pci_unregister_driver(&mwl8k_driver);
+}
+
+module_init(mwl8k_init);
+module_exit(mwl8k_exit);
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 24caec6caf1f..d63c8992f229 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -210,10 +210,6 @@ static int netwave_rx( struct net_device *dev);
static irqreturn_t netwave_interrupt(int irq, void *dev_id);
static void netwave_watchdog(struct net_device *);
-/* Statistics */
-static void update_stats(struct net_device *dev);
-static struct net_device_stats *netwave_get_stats(struct net_device *dev);
-
/* Wireless extensions */
static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
@@ -275,14 +271,9 @@ typedef struct netwave_private {
int lastExec;
struct timer_list watchdog; /* To avoid blocking state */
struct site_survey nss;
- struct net_device_stats stats;
struct iw_statistics iw_stats; /* Wireless stats */
} netwave_private;
-#ifdef NETWAVE_STATS
-static struct net_device_stats *netwave_get_stats(struct net_device *dev);
-#endif
-
/*
* The Netwave card is little-endian, so won't work for big endian
* systems.
@@ -364,6 +355,17 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
return &priv->iw_stats;
}
+static const struct net_device_ops netwave_netdev_ops = {
+ .ndo_open = netwave_open,
+ .ndo_stop = netwave_close,
+ .ndo_start_xmit = netwave_start_xmit,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_tx_timeout = netwave_watchdog,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*
* Function netwave_attach (void)
*
@@ -412,17 +414,12 @@ static int netwave_probe(struct pcmcia_device *link)
spin_lock_init(&priv->spinlock);
/* Netwave specific entries in the device structure */
- dev->hard_start_xmit = &netwave_start_xmit;
- dev->get_stats = &netwave_get_stats;
- dev->set_multicast_list = &set_multicast_list;
+ dev->netdev_ops = &netwave_netdev_ops;
/* wireless extensions */
- dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def;
+ dev->wireless_handlers = &netwave_handler_def;
- dev->tx_timeout = &netwave_watchdog;
dev->watchdog_timeo = TX_TIMEOUT;
- dev->open = &netwave_open;
- dev->stop = &netwave_close;
link->irq.Instance = dev;
return netwave_pcmcia_config( link);
@@ -988,7 +985,7 @@ static int netwave_hw_xmit(unsigned char* data, int len,
return 1;
}
- priv->stats.tx_bytes += len;
+ dev->stats.tx_bytes += len;
DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
readb(ramBase + NETWAVE_EREG_SPCQ),
@@ -1107,11 +1104,11 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
rser = readb(ramBase + NETWAVE_EREG_RSER);
if (rser & 0x04) {
- ++priv->stats.rx_dropped;
- ++priv->stats.rx_crc_errors;
+ ++dev->stats.rx_dropped;
+ ++dev->stats.rx_crc_errors;
}
if (rser & 0x02)
- ++priv->stats.rx_frame_errors;
+ ++dev->stats.rx_frame_errors;
/* Clear the RxErr bit in RSER. RSER+4 is the
* write part. Also clear the RxCRC (0x04) and
@@ -1125,8 +1122,8 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
wait_WOC(iobase);
writeb(0x40, ramBase + NETWAVE_EREG_ASCC);
- /* Remember to count up priv->stats on error packets */
- ++priv->stats.rx_errors;
+ /* Remember to count up dev->stats on error packets */
+ ++dev->stats.rx_errors;
}
/* TxDN */
if (status & 0x20) {
@@ -1140,17 +1137,17 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
/* Transmitting was okay, clear bits */
wait_WOC(iobase);
writeb(0x2f, ramBase + NETWAVE_EREG_TSER + 4);
- ++priv->stats.tx_packets;
+ ++dev->stats.tx_packets;
}
if (txStatus & 0xd0) {
if (txStatus & 0x80) {
- ++priv->stats.collisions; /* Because of /proc/net/dev*/
- /* ++priv->stats.tx_aborted_errors; */
+ ++dev->stats.collisions; /* Because of /proc/net/dev*/
+ /* ++dev->stats.tx_aborted_errors; */
/* printk("Collision. %ld\n", jiffies - dev->trans_start); */
}
if (txStatus & 0x40)
- ++priv->stats.tx_carrier_errors;
+ ++dev->stats.tx_carrier_errors;
/* 0x80 TxGU Transmit giveup - nine times and no luck
* 0x40 TxNOAP No access point. Discarded packet.
* 0x10 TxErr Transmit error. Always set when
@@ -1163,7 +1160,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
/* Clear out TxGU, TxNOAP, TxErr and TxTrys */
wait_WOC(iobase);
writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
- ++priv->stats.tx_errors;
+ ++dev->stats.tx_errors;
}
DEBUG(3, "New status is TSER %x ASR %x\n",
readb(ramBase + NETWAVE_EREG_TSER),
@@ -1197,40 +1194,6 @@ static void netwave_watchdog(struct net_device *dev) {
netif_wake_queue(dev);
} /* netwave_watchdog */
-static struct net_device_stats *netwave_get_stats(struct net_device *dev) {
- netwave_private *priv = netdev_priv(dev);
-
- update_stats(dev);
-
- DEBUG(2, "netwave: SPCQ %x SPU %x LIF %x ISPLQ %x MHS %x rxtx %x"
- " %x tx %x %x %x %x\n",
- readb(priv->ramBase + NETWAVE_EREG_SPCQ),
- readb(priv->ramBase + NETWAVE_EREG_SPU),
- readb(priv->ramBase + NETWAVE_EREG_LIF),
- readb(priv->ramBase + NETWAVE_EREG_ISPLQ),
- readb(priv->ramBase + NETWAVE_EREG_MHS),
- readb(priv->ramBase + NETWAVE_EREG_EC + 0xe),
- readb(priv->ramBase + NETWAVE_EREG_EC + 0xf),
- readb(priv->ramBase + NETWAVE_EREG_EC + 0x18),
- readb(priv->ramBase + NETWAVE_EREG_EC + 0x19),
- readb(priv->ramBase + NETWAVE_EREG_EC + 0x1a),
- readb(priv->ramBase + NETWAVE_EREG_EC + 0x1b));
-
- return &priv->stats;
-}
-
-static void update_stats(struct net_device *dev) {
- //unsigned long flags;
-/* netwave_private *priv = netdev_priv(dev); */
-
- //spin_lock_irqsave(&priv->spinlock, flags);
-
-/* priv->stats.rx_packets = readb(priv->ramBase + 0x18e);
- priv->stats.tx_packets = readb(priv->ramBase + 0x18f); */
-
- //spin_unlock_irqrestore(&priv->spinlock, flags);
-}
-
static int netwave_rx(struct net_device *dev)
{
netwave_private *priv = netdev_priv(dev);
@@ -1274,7 +1237,7 @@ static int netwave_rx(struct net_device *dev)
if (skb == NULL) {
DEBUG(1, "netwave_rx: Could not allocate an sk_buff of "
"length %d\n", rcvLen);
- ++priv->stats.rx_dropped;
+ ++dev->stats.rx_dropped;
/* Tell the adapter to skip the packet */
wait_WOC(iobase);
writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
@@ -1307,8 +1270,8 @@ static int netwave_rx(struct net_device *dev)
/* Queue packet for network layer */
netif_rx(skb);
- priv->stats.rx_packets++;
- priv->stats.rx_bytes += rcvLen;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += rcvLen;
/* Got the packet, tell the adapter to skip it */
wait_WOC(iobase);
diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig
new file mode 100644
index 000000000000..44411eb4e91b
--- /dev/null
+++ b/drivers/net/wireless/orinoco/Kconfig
@@ -0,0 +1,120 @@
+config HERMES
+ tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
+ depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211
+ select WIRELESS_EXT
+ select FW_LOADER
+ select CRYPTO
+ select CRYPTO_MICHAEL_MIC
+ ---help---
+ A driver for 802.11b wireless cards based on the "Hermes" or
+ Intersil HFA384x (Prism 2) MAC controller. This includes the vast
+ majority of the PCMCIA 802.11b cards (which are nearly all rebadges)
+ - except for the Cisco/Aironet cards. Cards supported include the
+ Apple Airport (not a PCMCIA card), WavelanIEEE/Orinoco,
+ Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya,
+ IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear
+ MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel
+ IPW2011, and Symbol Spectrum24 High Rate amongst others.
+
+ This option includes the guts of the driver, but in order to
+ actually use a card you will also need to enable support for PCMCIA
+ Hermes cards, PLX9052 based PCI adaptors or the Apple Airport below.
+
+ You will also very likely also need the Wireless Tools in order to
+ configure your card and that /etc/pcmcia/wireless.opts works :
+ <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
+
+config HERMES_CACHE_FW_ON_INIT
+ bool "Cache Hermes firmware on driver initialisation"
+ depends on HERMES
+ default y
+ ---help---
+ Say Y to cache any firmware required by the Hermes drivers
+ on startup. The firmware will remain cached until the
+ driver is unloaded. The cache uses 64K of RAM.
+
+ Otherwise load the firmware from userspace as required. In
+ this case the driver should be unloaded and restarted
+ whenever the firmware is changed.
+
+ If you are not sure, say Y.
+
+config APPLE_AIRPORT
+ tristate "Apple Airport support (built-in)"
+ depends on PPC_PMAC && HERMES
+ help
+ Say Y here to support the Airport 802.11b wireless Ethernet hardware
+ built into the Macintosh iBook and other recent PowerPC-based
+ Macintosh machines. This is essentially a Lucent Orinoco card with
+ a non-standard interface.
+
+ This driver does not support the Airport Extreme (802.11b/g). Use
+ the BCM43xx driver for Airport Extreme cards.
+
+config PLX_HERMES
+ tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)"
+ depends on PCI && HERMES
+ help
+ Enable support for PCMCIA cards supported by the "Hermes" (aka
+ orinoco) driver when used in PLX9052 based PCI adaptors. These
+ adaptors are not a full PCMCIA controller but act as a more limited
+ PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
+ 802.11b PCMCIA cards can be used in desktop machines. The Netgear
+ MA301 is such an adaptor.
+
+config TMD_HERMES
+ tristate "Hermes in TMD7160 based PCI adaptor support"
+ depends on PCI && HERMES
+ help
+ Enable support for PCMCIA cards supported by the "Hermes" (aka
+ orinoco) driver when used in TMD7160 based PCI adaptors. These
+ adaptors are not a full PCMCIA controller but act as a more limited
+ PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
+ 802.11b PCMCIA cards can be used in desktop machines.
+
+config NORTEL_HERMES
+ tristate "Nortel emobility PCI adaptor support"
+ depends on PCI && HERMES
+ help
+ Enable support for PCMCIA cards supported by the "Hermes" (aka
+ orinoco) driver when used in Nortel emobility PCI adaptors. These
+ adaptors are not full PCMCIA controllers, but act as a more limited
+ PCI <-> PCMCIA bridge.
+
+config PCI_HERMES
+ tristate "Prism 2.5 PCI 802.11b adaptor support"
+ depends on PCI && HERMES
+ help
+ Enable support for PCI and mini-PCI 802.11b wireless NICs based on
+ the Prism 2.5 chipset. These are true PCI cards, not the 802.11b
+ PCMCIA cards bundled with PCI<->PCMCIA adaptors which are also
+ common. Some of the built-in wireless adaptors in laptops are of
+ this variety.
+
+config PCMCIA_HERMES
+ tristate "Hermes PCMCIA card support"
+ depends on PCMCIA && HERMES
+ ---help---
+ A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
+ as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
+ EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and
+ others). It should also be usable on various Prism II based cards
+ such as the Linksys, D-Link and Farallon Skyline. It should also
+ work on Symbol cards such as the 3Com AirConnect and Ericsson WLAN.
+
+ You will very likely need the Wireless Tools in order to
+ configure your card and that /etc/pcmcia/wireless.opts works:
+ <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
+
+config PCMCIA_SPECTRUM
+ tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
+ depends on PCMCIA && HERMES
+ ---help---
+
+ This is a driver for 802.11b cards using RAM-loadable Symbol
+ firmware, such as Symbol Wireless Networker LA4100, CompactFlash
+ cards by Socket Communications and Intel PRO/Wireless 2011B.
+
+ This driver requires firmware download on startup. Utilities
+ for downloading Symbol firmware are available at
+ <http://sourceforge.net/projects/orinoco/>
diff --git a/drivers/net/wireless/orinoco/Makefile b/drivers/net/wireless/orinoco/Makefile
index 791366e08c50..1fc7409d6699 100644
--- a/drivers/net/wireless/orinoco/Makefile
+++ b/drivers/net/wireless/orinoco/Makefile
@@ -1,8 +1,9 @@
#
# Makefile for the orinoco wireless device drivers.
#
+orinoco-objs := main.o fw.o hw.o mic.o scan.o wext.o hermes_dld.o hermes.o
-obj-$(CONFIG_HERMES) += orinoco.o hermes.o hermes_dld.o
+obj-$(CONFIG_HERMES) += orinoco.o
obj-$(CONFIG_PCMCIA_HERMES) += orinoco_cs.o
obj-$(CONFIG_APPLE_AIRPORT) += airport.o
obj-$(CONFIG_PLX_HERMES) += orinoco_plx.o
diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
index 28f1cae48439..8c4065f1b0d0 100644
--- a/drivers/net/wireless/orinoco/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
@@ -3,10 +3,10 @@
* A driver for "Hermes" chipset based Apple Airport wireless
* card.
*
- * Copyright notice & release notes in file orinoco.c
- *
+ * Copyright notice & release notes in file main.c
+ *
* Note specific to airport stub:
- *
+ *
* 0.05 : first version of the new split driver
* 0.06 : fix possible hang on powerup, add sleep support
*/
@@ -60,7 +60,8 @@ airport_suspend(struct macio_dev *mdev, pm_message_t state)
orinoco_unlock(priv, &flags);
disable_irq(dev->irq);
- pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0);
+ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+ macio_get_of_node(mdev), 0, 0);
return 0;
}
@@ -75,7 +76,8 @@ airport_resume(struct macio_dev *mdev)
printk(KERN_DEBUG "%s: Airport waking up\n", dev->name);
- pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
+ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+ macio_get_of_node(mdev), 0, 1);
msleep(200);
enable_irq(dev->irq);
@@ -93,7 +95,7 @@ airport_resume(struct macio_dev *mdev)
priv->hw_unavailable--;
- if (priv->open && (! priv->hw_unavailable)) {
+ if (priv->open && (!priv->hw_unavailable)) {
err = __orinoco_up(dev);
if (err)
printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n",
@@ -127,7 +129,8 @@ airport_detach(struct macio_dev *mdev)
macio_release_resource(mdev, 0);
- pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0);
+ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+ macio_get_of_node(mdev), 0, 0);
ssleep(1);
macio_set_drvdata(mdev, NULL);
@@ -153,9 +156,11 @@ static int airport_hard_reset(struct orinoco_private *priv)
* off. */
disable_irq(dev->irq);
- pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 0);
+ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+ macio_get_of_node(card->mdev), 0, 0);
ssleep(1);
- pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 1);
+ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+ macio_get_of_node(card->mdev), 0, 1);
ssleep(1);
enable_irq(dev->irq);
@@ -182,7 +187,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
/* Allocate space for private device-specific data */
dev = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev,
airport_hard_reset, NULL);
- if (! dev) {
+ if (!dev) {
printk(KERN_ERR PFX "Cannot allocate network device\n");
return -ENODEV;
}
@@ -214,9 +219,10 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
}
hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING);
-
+
/* Power up card */
- pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
+ pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
+ macio_get_of_node(mdev), 0, 1);
ssleep(1);
/* Reset it before we get the interrupt */
@@ -248,7 +254,7 @@ MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
MODULE_LICENSE("Dual MPL/GPL");
-static struct of_device_id airport_match[] =
+static struct of_device_id airport_match[] =
{
{
.name = "radio",
@@ -256,10 +262,9 @@ static struct of_device_id airport_match[] =
{},
};
-MODULE_DEVICE_TABLE (of, airport_match);
+MODULE_DEVICE_TABLE(of, airport_match);
-static struct macio_driver airport_driver =
-{
+static struct macio_driver airport_driver = {
.name = DRIVER_NAME,
.match_table = airport_match,
.probe = airport_attach,
diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c
new file mode 100644
index 000000000000..1084b43e04bc
--- /dev/null
+++ b/drivers/net/wireless/orinoco/fw.c
@@ -0,0 +1,390 @@
+/* Firmware file reading and download helpers
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/kernel.h>
+#include <linux/firmware.h>
+
+#include "hermes.h"
+#include "hermes_dld.h"
+#include "orinoco.h"
+
+#include "fw.h"
+
+/* End markers (for Symbol firmware only) */
+#define TEXT_END 0x1A /* End of text header */
+
+struct fw_info {
+ char *pri_fw;
+ char *sta_fw;
+ char *ap_fw;
+ u32 pda_addr;
+ u16 pda_size;
+};
+
+static const struct fw_info orinoco_fw[] = {
+ { NULL, "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
+ { NULL, "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
+ { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", NULL, 0x00003100, 512 }
+};
+
+/* Structure used to access fields in FW
+ * Make sure LE decoding macros are used
+ */
+struct orinoco_fw_header {
+ char hdr_vers[6]; /* ASCII string for header version */
+ __le16 headersize; /* Total length of header */
+ __le32 entry_point; /* NIC entry point */
+ __le32 blocks; /* Number of blocks to program */
+ __le32 block_offset; /* Offset of block data from eof header */
+ __le32 pdr_offset; /* Offset to PDR data from eof header */
+ __le32 pri_offset; /* Offset to primary plug data */
+ __le32 compat_offset; /* Offset to compatibility data*/
+ char signature[0]; /* FW signature length headersize-20 */
+} __attribute__ ((packed));
+
+/* Check the range of various header entries. Return a pointer to a
+ * description of the problem, or NULL if everything checks out. */
+static const char *validate_fw(const struct orinoco_fw_header *hdr, size_t len)
+{
+ u16 hdrsize;
+
+ if (len < sizeof(*hdr))
+ return "image too small";
+ if (memcmp(hdr->hdr_vers, "HFW", 3) != 0)
+ return "format not recognised";
+
+ hdrsize = le16_to_cpu(hdr->headersize);
+ if (hdrsize > len)
+ return "bad headersize";
+ if ((hdrsize + le32_to_cpu(hdr->block_offset)) > len)
+ return "bad block offset";
+ if ((hdrsize + le32_to_cpu(hdr->pdr_offset)) > len)
+ return "bad PDR offset";
+ if ((hdrsize + le32_to_cpu(hdr->pri_offset)) > len)
+ return "bad PRI offset";
+ if ((hdrsize + le32_to_cpu(hdr->compat_offset)) > len)
+ return "bad compat offset";
+
+ /* TODO: consider adding a checksum or CRC to the firmware format */
+ return NULL;
+}
+
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
+static inline const struct firmware *
+orinoco_cached_fw_get(struct orinoco_private *priv, bool primary)
+{
+ if (primary)
+ return priv->cached_pri_fw;
+ else
+ return priv->cached_fw;
+}
+#else
+#define orinoco_cached_fw_get(priv, primary) (NULL)
+#endif
+
+/* Download either STA or AP firmware into the card. */
+static int
+orinoco_dl_firmware(struct orinoco_private *priv,
+ const struct fw_info *fw,
+ int ap)
+{
+ /* Plug Data Area (PDA) */
+ __le16 *pda;
+
+ hermes_t *hw = &priv->hw;
+ const struct firmware *fw_entry;
+ const struct orinoco_fw_header *hdr;
+ const unsigned char *first_block;
+ const void *end;
+ const char *firmware;
+ const char *fw_err;
+ struct net_device *dev = priv->ndev;
+ int err = 0;
+
+ pda = kzalloc(fw->pda_size, GFP_KERNEL);
+ if (!pda)
+ return -ENOMEM;
+
+ if (ap)
+ firmware = fw->ap_fw;
+ else
+ firmware = fw->sta_fw;
+
+ printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
+ dev->name, firmware);
+
+ /* Read current plug data */
+ err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
+ printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
+ if (err)
+ goto free;
+
+ if (!orinoco_cached_fw_get(priv, false)) {
+ err = request_firmware(&fw_entry, firmware, priv->dev);
+
+ if (err) {
+ printk(KERN_ERR "%s: Cannot find firmware %s\n",
+ dev->name, firmware);
+ err = -ENOENT;
+ goto free;
+ }
+ } else
+ fw_entry = orinoco_cached_fw_get(priv, false);
+
+ hdr = (const struct orinoco_fw_header *) fw_entry->data;
+
+ fw_err = validate_fw(hdr, fw_entry->size);
+ if (fw_err) {
+ printk(KERN_WARNING "%s: Invalid firmware image detected (%s). "
+ "Aborting download\n",
+ dev->name, fw_err);
+ err = -EINVAL;
+ goto abort;
+ }
+
+ /* Enable aux port to allow programming */
+ err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
+ printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
+ if (err != 0)
+ goto abort;
+
+ /* Program data */
+ first_block = (fw_entry->data +
+ le16_to_cpu(hdr->headersize) +
+ le32_to_cpu(hdr->block_offset));
+ end = fw_entry->data + fw_entry->size;
+
+ err = hermes_program(hw, first_block, end);
+ printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
+ if (err != 0)
+ goto abort;
+
+ /* Update production data */
+ first_block = (fw_entry->data +
+ le16_to_cpu(hdr->headersize) +
+ le32_to_cpu(hdr->pdr_offset));
+
+ err = hermes_apply_pda_with_defaults(hw, first_block, end, pda,
+ &pda[fw->pda_size / sizeof(*pda)]);
+ printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
+ if (err)
+ goto abort;
+
+ /* Tell card we've finished */
+ err = hermesi_program_end(hw);
+ printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
+ if (err != 0)
+ goto abort;
+
+ /* Check if we're running */
+ printk(KERN_DEBUG "%s: hermes_present returned %d\n",
+ dev->name, hermes_present(hw));
+
+abort:
+ /* If we requested the firmware, release it. */
+ if (!orinoco_cached_fw_get(priv, false))
+ release_firmware(fw_entry);
+
+free:
+ kfree(pda);
+ return err;
+}
+
+/*
+ * Process a firmware image - stop the card, load the firmware, reset
+ * the card and make sure it responds. For the secondary firmware take
+ * care of the PDA - read it and then write it on top of the firmware.
+ */
+static int
+symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
+ const unsigned char *image, const void *end,
+ int secondary)
+{
+ hermes_t *hw = &priv->hw;
+ int ret = 0;
+ const unsigned char *ptr;
+ const unsigned char *first_block;
+
+ /* Plug Data Area (PDA) */
+ __le16 *pda = NULL;
+
+ /* Binary block begins after the 0x1A marker */
+ ptr = image;
+ while (*ptr++ != TEXT_END);
+ first_block = ptr;
+
+ /* Read the PDA from EEPROM */
+ if (secondary) {
+ pda = kzalloc(fw->pda_size, GFP_KERNEL);
+ if (!pda)
+ return -ENOMEM;
+
+ ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
+ if (ret)
+ goto free;
+ }
+
+ /* Stop the firmware, so that it can be safely rewritten */
+ if (priv->stop_fw) {
+ ret = priv->stop_fw(priv, 1);
+ if (ret)
+ goto free;
+ }
+
+ /* Program the adapter with new firmware */
+ ret = hermes_program(hw, first_block, end);
+ if (ret)
+ goto free;
+
+ /* Write the PDA to the adapter */
+ if (secondary) {
+ size_t len = hermes_blocks_length(first_block, end);
+ ptr = first_block + len;
+ ret = hermes_apply_pda(hw, ptr, end, pda,
+ &pda[fw->pda_size / sizeof(*pda)]);
+ kfree(pda);
+ if (ret)
+ return ret;
+ }
+
+ /* Run the firmware */
+ if (priv->stop_fw) {
+ ret = priv->stop_fw(priv, 0);
+ if (ret)
+ return ret;
+ }
+
+ /* Reset hermes chip and make sure it responds */
+ ret = hermes_init(hw);
+
+ /* hermes_reset() should return 0 with the secondary firmware */
+ if (secondary && ret != 0)
+ return -ENODEV;
+
+ /* And this should work with any firmware */
+ if (!hermes_present(hw))
+ return -ENODEV;
+
+ return 0;
+
+free:
+ kfree(pda);
+ return ret;
+}
+
+
+/*
+ * Download the firmware into the card, this also does a PCMCIA soft
+ * reset on the card, to make sure it's in a sane state.
+ */
+static int
+symbol_dl_firmware(struct orinoco_private *priv,
+ const struct fw_info *fw)
+{
+ struct net_device *dev = priv->ndev;
+ int ret;
+ const struct firmware *fw_entry;
+
+ if (!orinoco_cached_fw_get(priv, true)) {
+ if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
+ printk(KERN_ERR "%s: Cannot find firmware: %s\n",
+ dev->name, fw->pri_fw);
+ return -ENOENT;
+ }
+ } else
+ fw_entry = orinoco_cached_fw_get(priv, true);
+
+ /* Load primary firmware */
+ ret = symbol_dl_image(priv, fw, fw_entry->data,
+ fw_entry->data + fw_entry->size, 0);
+
+ if (!orinoco_cached_fw_get(priv, true))
+ release_firmware(fw_entry);
+ if (ret) {
+ printk(KERN_ERR "%s: Primary firmware download failed\n",
+ dev->name);
+ return ret;
+ }
+
+ if (!orinoco_cached_fw_get(priv, false)) {
+ if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
+ printk(KERN_ERR "%s: Cannot find firmware: %s\n",
+ dev->name, fw->sta_fw);
+ return -ENOENT;
+ }
+ } else
+ fw_entry = orinoco_cached_fw_get(priv, false);
+
+ /* Load secondary firmware */
+ ret = symbol_dl_image(priv, fw, fw_entry->data,
+ fw_entry->data + fw_entry->size, 1);
+ if (!orinoco_cached_fw_get(priv, false))
+ release_firmware(fw_entry);
+ if (ret) {
+ printk(KERN_ERR "%s: Secondary firmware download failed\n",
+ dev->name);
+ }
+
+ return ret;
+}
+
+int orinoco_download(struct orinoco_private *priv)
+{
+ int err = 0;
+ /* Reload firmware */
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE:
+ /* case FIRMWARE_TYPE_INTERSIL: */
+ err = orinoco_dl_firmware(priv,
+ &orinoco_fw[priv->firmware_type], 0);
+ break;
+
+ case FIRMWARE_TYPE_SYMBOL:
+ err = symbol_dl_firmware(priv,
+ &orinoco_fw[priv->firmware_type]);
+ break;
+ case FIRMWARE_TYPE_INTERSIL:
+ break;
+ }
+ /* TODO: if we fail we probably need to reinitialise
+ * the driver */
+
+ return err;
+}
+
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
+void orinoco_cache_fw(struct orinoco_private *priv, int ap)
+{
+ const struct firmware *fw_entry = NULL;
+ const char *pri_fw;
+ const char *fw;
+
+ pri_fw = orinoco_fw[priv->firmware_type].pri_fw;
+ if (ap)
+ fw = orinoco_fw[priv->firmware_type].ap_fw;
+ else
+ fw = orinoco_fw[priv->firmware_type].sta_fw;
+
+ if (pri_fw) {
+ if (request_firmware(&fw_entry, pri_fw, priv->dev) == 0)
+ priv->cached_pri_fw = fw_entry;
+ }
+
+ if (fw) {
+ if (request_firmware(&fw_entry, fw, priv->dev) == 0)
+ priv->cached_fw = fw_entry;
+ }
+}
+
+void orinoco_uncache_fw(struct orinoco_private *priv)
+{
+ if (priv->cached_pri_fw)
+ release_firmware(priv->cached_pri_fw);
+ if (priv->cached_fw)
+ release_firmware(priv->cached_fw);
+
+ priv->cached_pri_fw = NULL;
+ priv->cached_fw = NULL;
+}
+#endif
diff --git a/drivers/net/wireless/orinoco/fw.h b/drivers/net/wireless/orinoco/fw.h
new file mode 100644
index 000000000000..89fc26d25b06
--- /dev/null
+++ b/drivers/net/wireless/orinoco/fw.h
@@ -0,0 +1,21 @@
+/* Firmware file reading and download helpers
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_FW_H_
+#define _ORINOCO_FW_H_
+
+/* Forward declations */
+struct orinoco_private;
+
+int orinoco_download(struct orinoco_private *priv);
+
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
+void orinoco_cache_fw(struct orinoco_private *priv, int ap);
+void orinoco_uncache_fw(struct orinoco_private *priv);
+#else
+#define orinoco_cache_fw(priv, ap) do { } while(0)
+#define orinoco_uncache_fw(priv) do { } while (0)
+#endif
+
+#endif /* _ORINOCO_FW_H_ */
diff --git a/drivers/net/wireless/orinoco/hermes.c b/drivers/net/wireless/orinoco/hermes.c
index bfa375369df3..f2c918c2572d 100644
--- a/drivers/net/wireless/orinoco/hermes.c
+++ b/drivers/net/wireless/orinoco/hermes.c
@@ -15,7 +15,7 @@
*
* Copyright (C) 2000, David Gibson, Linuxcare Australia.
* (C) Copyright David Gibson, IBM Corp. 2001-2003.
- *
+ *
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License
@@ -45,11 +45,6 @@
#include "hermes.h"
-MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller");
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"
- " & David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_LICENSE("Dual MPL/GPL");
-
/* These are maximum timeouts. Most often, card wil react much faster */
#define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */
#define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */
@@ -61,13 +56,13 @@ MODULE_LICENSE("Dual MPL/GPL");
*/
#define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ %p: " , hw->iobase); \
- printk(stuff);} while (0)
+ printk(stuff); } while (0)
#undef HERMES_DEBUG
#ifdef HERMES_DEBUG
#include <stdarg.h>
-#define DEBUG(lvl, stuff...) if ( (lvl) <= HERMES_DEBUG) DMSG(stuff)
+#define DEBUG(lvl, stuff...) if ((lvl) <= HERMES_DEBUG) DMSG(stuff)
#else /* ! HERMES_DEBUG */
@@ -95,20 +90,19 @@ static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0,
/* First wait for the command register to unbusy */
reg = hermes_read_regn(hw, CMD);
- while ( (reg & HERMES_CMD_BUSY) && k ) {
+ while ((reg & HERMES_CMD_BUSY) && k) {
k--;
udelay(1);
reg = hermes_read_regn(hw, CMD);
}
- if (reg & HERMES_CMD_BUSY) {
+ if (reg & HERMES_CMD_BUSY)
return -EBUSY;
- }
hermes_write_regn(hw, PARAM2, param2);
hermes_write_regn(hw, PARAM1, param1);
hermes_write_regn(hw, PARAM0, param0);
hermes_write_regn(hw, CMD, cmd);
-
+
return 0;
}
@@ -191,23 +185,23 @@ int hermes_init(hermes_t *hw)
hermes_write_regn(hw, EVACK, 0xffff);
/* Normally it's a "can't happen" for the command register to
- be busy when we go to issue a command because we are
- serializing all commands. However we want to have some
- chance of resetting the card even if it gets into a stupid
- state, so we actually wait to see if the command register
- will unbusy itself here. */
+ be busy when we go to issue a command because we are
+ serializing all commands. However we want to have some
+ chance of resetting the card even if it gets into a stupid
+ state, so we actually wait to see if the command register
+ will unbusy itself here. */
k = CMD_BUSY_TIMEOUT;
reg = hermes_read_regn(hw, CMD);
while (k && (reg & HERMES_CMD_BUSY)) {
- if (reg == 0xffff) /* Special case - the card has probably been removed,
- so don't wait for the timeout */
+ if (reg == 0xffff) /* Special case - the card has probably been
+ removed, so don't wait for the timeout */
return -ENODEV;
k--;
udelay(1);
reg = hermes_read_regn(hw, CMD);
}
-
+
/* No need to explicitly handle the timeout - if we've timed
out hermes_issue_cmd() will probably return -EBUSY below */
@@ -228,7 +222,10 @@ EXPORT_SYMBOL(hermes_init);
/* Issue a command to the chip, and (busy!) wait for it to
* complete.
*
- * Returns: < 0 on internal error, 0 on success, > 0 on error returned by the firmware
+ * Returns:
+ * < 0 on internal error
+ * 0 on success
+ * > 0 on error returned by the firmware
*
* Callable from any context, but locking is your problem. */
int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
@@ -241,13 +238,13 @@ int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
err = hermes_issue_cmd(hw, cmd, parm0, 0, 0);
if (err) {
- if (! hermes_present(hw)) {
+ if (!hermes_present(hw)) {
if (net_ratelimit())
printk(KERN_WARNING "hermes @ %p: "
"Card removed while issuing command "
"0x%04x.\n", hw->iobase, cmd);
err = -ENODEV;
- } else
+ } else
if (net_ratelimit())
printk(KERN_ERR "hermes @ %p: "
"Error %d issuing command 0x%04x.\n",
@@ -257,21 +254,21 @@ int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
reg = hermes_read_regn(hw, EVSTAT);
k = CMD_COMPL_TIMEOUT;
- while ( (! (reg & HERMES_EV_CMD)) && k) {
+ while ((!(reg & HERMES_EV_CMD)) && k) {
k--;
udelay(10);
reg = hermes_read_regn(hw, EVSTAT);
}
- if (! hermes_present(hw)) {
+ if (!hermes_present(hw)) {
printk(KERN_WARNING "hermes @ %p: Card removed "
"while waiting for command 0x%04x completion.\n",
hw->iobase, cmd);
err = -ENODEV;
goto out;
}
-
- if (! (reg & HERMES_EV_CMD)) {
+
+ if (!(reg & HERMES_EV_CMD)) {
printk(KERN_ERR "hermes @ %p: Timeout waiting for "
"command 0x%04x completion.\n", hw->iobase, cmd);
err = -ETIMEDOUT;
@@ -301,31 +298,30 @@ int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
int err = 0;
int k;
u16 reg;
-
- if ( (size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX) )
+
+ if ((size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX))
return -EINVAL;
err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL);
- if (err) {
+ if (err)
return err;
- }
reg = hermes_read_regn(hw, EVSTAT);
k = ALLOC_COMPL_TIMEOUT;
- while ( (! (reg & HERMES_EV_ALLOC)) && k) {
+ while ((!(reg & HERMES_EV_ALLOC)) && k) {
k--;
udelay(10);
reg = hermes_read_regn(hw, EVSTAT);
}
-
- if (! hermes_present(hw)) {
+
+ if (!hermes_present(hw)) {
printk(KERN_WARNING "hermes @ %p: "
"Card removed waiting for frame allocation.\n",
hw->iobase);
return -ENODEV;
}
-
- if (! (reg & HERMES_EV_ALLOC)) {
+
+ if (!(reg & HERMES_EV_ALLOC)) {
printk(KERN_ERR "hermes @ %p: "
"Timeout waiting for frame allocation\n",
hw->iobase);
@@ -334,14 +330,17 @@ int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
*fid = hermes_read_regn(hw, ALLOCFID);
hermes_write_regn(hw, EVACK, HERMES_EV_ALLOC);
-
+
return 0;
}
EXPORT_SYMBOL(hermes_allocate);
/* Set up a BAP to read a particular chunk of data from card's internal buffer.
*
- * Returns: < 0 on internal failure (errno), 0 on success, >0 on error
+ * Returns:
+ * < 0 on internal failure (errno)
+ * 0 on success
+ * > 0 on error
* from firmware
*
* Callable from any context */
@@ -353,7 +352,7 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
u16 reg;
/* Paranoia.. */
- if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )
+ if ((offset > HERMES_BAP_OFFSET_MAX) || (offset % 2))
return -EINVAL;
k = HERMES_BAP_BUSY_TIMEOUT;
@@ -374,7 +373,7 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
/* Wait for the BAP to be ready */
k = HERMES_BAP_BUSY_TIMEOUT;
reg = hermes_read_reg(hw, oreg);
- while ( (reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
+ while ((reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
k--;
udelay(1);
reg = hermes_read_reg(hw, oreg);
@@ -386,9 +385,8 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
(reg & HERMES_OFFSET_BUSY) ? "timeout" : "error",
reg, id, offset);
- if (reg & HERMES_OFFSET_BUSY) {
+ if (reg & HERMES_OFFSET_BUSY)
return -ETIMEDOUT;
- }
return -EIO; /* error or wrong offset */
}
@@ -400,7 +398,10 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
* BAP. Synchronization/serialization is the caller's problem. len
* must be even.
*
- * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
+ * Returns:
+ * < 0 on internal failure (errno)
+ * 0 on success
+ * > 0 on error from firmware
*/
int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
u16 id, u16 offset)
@@ -408,7 +409,7 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
int err = 0;
- if ( (len < 0) || (len % 2) )
+ if ((len < 0) || (len % 2))
return -EINVAL;
err = hermes_bap_seek(hw, bap, id, offset);
@@ -426,7 +427,10 @@ EXPORT_SYMBOL(hermes_bap_pread);
/* Write a block of data to the chip's buffer, via the
* BAP. Synchronization/serialization is the caller's problem.
*
- * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
+ * Returns:
+ * < 0 on internal failure (errno)
+ * 0 on success
+ * > 0 on error from firmware
*/
int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
u16 id, u16 offset)
@@ -440,11 +444,11 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
err = hermes_bap_seek(hw, bap, id, offset);
if (err)
goto out;
-
+
/* Actually do the transfer */
hermes_write_bytes(hw, dreg, buf, len);
- out:
+ out:
return err;
}
EXPORT_SYMBOL(hermes_bap_pwrite);
@@ -465,7 +469,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
u16 rlength, rtype;
unsigned nwords;
- if ( (bufsize < 0) || (bufsize % 2) )
+ if ((bufsize < 0) || (bufsize % 2))
return -EINVAL;
err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL);
@@ -478,7 +482,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
rlength = hermes_read_reg(hw, dreg);
- if (! rlength)
+ if (!rlength)
return -ENODATA;
rtype = hermes_read_reg(hw, dreg);
@@ -503,7 +507,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
}
EXPORT_SYMBOL(hermes_read_ltv);
-int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
+int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
u16 length, const void *value)
{
int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -530,15 +534,3 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
return err;
}
EXPORT_SYMBOL(hermes_write_ltv);
-
-static int __init init_hermes(void)
-{
- return 0;
-}
-
-static void __exit exit_hermes(void)
-{
-}
-
-module_init(init_hermes);
-module_exit(exit_hermes);
diff --git a/drivers/net/wireless/orinoco/hermes.h b/drivers/net/wireless/orinoco/hermes.h
index 8b13c8fef3dc..c78c442a02c8 100644
--- a/drivers/net/wireless/orinoco/hermes.h
+++ b/drivers/net/wireless/orinoco/hermes.h
@@ -15,7 +15,8 @@
* Copyright (C) 2000, David Gibson, Linuxcare Australia.
* (C) Copyright David Gibson, IBM Corp. 2001-2003.
*
- * Portions taken from hfa384x.h, Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+ * Portions taken from hfa384x.h.
+ * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
*
* This file distributed under the GPL, version 2.
*/
@@ -31,7 +32,7 @@
*/
#include <linux/if_ether.h>
-#include <asm/io.h>
+#include <linux/io.h>
/*
* Limits and constants
@@ -203,7 +204,7 @@ struct hermes_tx_descriptor {
__le32 sw_support;
u8 retry_count;
u8 tx_rate;
- __le16 tx_control;
+ __le16 tx_control;
} __attribute__ ((packed));
#define HERMES_TXSTAT_RETRYERR (0x0001)
@@ -298,7 +299,7 @@ struct symbol_scan_apinfo {
/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
__le16 essid_len; /* ESSID length */
u8 essid[32]; /* ESSID of the network */
- __le16 rates[5]; /* Bit rate supported */
+ __le16 rates[5]; /* Bit rate supported */
__le16 basic_rates; /* Basic rates bitmask */
u8 unknown2[6]; /* Always FF:FF:FF:FF:00:00 */
u8 unknown3[8]; /* Always 0, appeared in f/w 3.91-68 */
@@ -344,14 +345,14 @@ struct agere_ext_scan_info {
u8 data[316];
} __attribute__ ((packed));
-#define HERMES_LINKSTATUS_NOT_CONNECTED (0x0000)
+#define HERMES_LINKSTATUS_NOT_CONNECTED (0x0000)
#define HERMES_LINKSTATUS_CONNECTED (0x0001)
#define HERMES_LINKSTATUS_DISCONNECTED (0x0002)
#define HERMES_LINKSTATUS_AP_CHANGE (0x0003)
#define HERMES_LINKSTATUS_AP_OUT_OF_RANGE (0x0004)
#define HERMES_LINKSTATUS_AP_IN_RANGE (0x0005)
#define HERMES_LINKSTATUS_ASSOC_FAILED (0x0006)
-
+
struct hermes_linkstatus {
__le16 linkstatus; /* Link status */
} __attribute__ ((packed));
@@ -384,11 +385,12 @@ typedef struct hermes {
/* Register access convenience macros */
#define hermes_read_reg(hw, off) \
- (ioread16((hw)->iobase + ( (off) << (hw)->reg_spacing )))
+ (ioread16((hw)->iobase + ((off) << (hw)->reg_spacing)))
#define hermes_write_reg(hw, off, val) \
(iowrite16((val), (hw)->iobase + ((off) << (hw)->reg_spacing)))
#define hermes_read_regn(hw, name) hermes_read_reg((hw), HERMES_##name)
-#define hermes_write_regn(hw, name, val) hermes_write_reg((hw), HERMES_##name, (val))
+#define hermes_write_regn(hw, name, val) \
+ hermes_write_reg((hw), HERMES_##name, (val))
/* Function prototypes */
void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing);
@@ -430,7 +432,7 @@ static inline int hermes_enable_port(hermes_t *hw, int port)
static inline int hermes_disable_port(hermes_t *hw, int port)
{
- return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8),
+ return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8),
0, NULL);
}
@@ -441,11 +443,12 @@ static inline int hermes_inquire(hermes_t *hw, u16 rid)
return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
}
-#define HERMES_BYTES_TO_RECLEN(n) ( (((n)+1)/2) + 1 )
-#define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 )
+#define HERMES_BYTES_TO_RECLEN(n) ((((n)+1)/2) + 1)
+#define HERMES_RECLEN_TO_BYTES(n) (((n)-1) * 2)
/* Note that for the next two, the count is in 16-bit words, not bytes */
-static inline void hermes_read_words(struct hermes *hw, int off, void *buf, unsigned count)
+static inline void hermes_read_words(struct hermes *hw, int off,
+ void *buf, unsigned count)
{
off = off << hw->reg_spacing;
ioread16_rep(hw->iobase + off, buf, count);
@@ -460,7 +463,8 @@ static inline void hermes_write_bytes(struct hermes *hw, int off,
iowrite8(buf[count - 1], hw->iobase + off);
}
-static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count)
+static inline void hermes_clear_words(struct hermes *hw, int off,
+ unsigned count)
{
unsigned i;
@@ -471,9 +475,10 @@ static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count
}
#define HERMES_READ_RECORD(hw, bap, rid, buf) \
- (hermes_read_ltv((hw),(bap),(rid), sizeof(*buf), NULL, (buf)))
+ (hermes_read_ltv((hw), (bap), (rid), sizeof(*buf), NULL, (buf)))
#define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
- (hermes_write_ltv((hw),(bap),(rid),HERMES_BYTES_TO_RECLEN(sizeof(*buf)),(buf)))
+ (hermes_write_ltv((hw), (bap), (rid), \
+ HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf)))
static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
{
diff --git a/drivers/net/wireless/orinoco/hermes_dld.c b/drivers/net/wireless/orinoco/hermes_dld.c
index d8c626e61a3a..a9ba195cdada 100644
--- a/drivers/net/wireless/orinoco/hermes_dld.c
+++ b/drivers/net/wireless/orinoco/hermes_dld.c
@@ -1,13 +1,7 @@
/*
- * Hermes download helper driver.
+ * Hermes download helper.
*
- * This could be entirely merged into hermes.c.
- *
- * I'm keeping it separate to minimise the amount of merging between
- * kernel upgrades. It also means the memory overhead for drivers that
- * don't need firmware download low.
- *
- * This driver:
+ * This helper:
* - is capable of writing to the volatile area of the hermes device
* - is currently not capable of writing to non-volatile areas
* - provide helpers to identify and update plugin data
@@ -50,10 +44,6 @@
#include "hermes.h"
#include "hermes_dld.h"
-MODULE_DESCRIPTION("Download helper for Lucent Hermes chipset");
-MODULE_AUTHOR("David Kilroy <kilroyd@gmail.com>");
-MODULE_LICENSE("Dual MPL/GPL");
-
#define PFX "hermes_dld: "
/*
@@ -81,18 +71,6 @@ MODULE_LICENSE("Dual MPL/GPL");
#define BLOCK_END 0xFFFFFFFF /* Last image block */
#define TEXT_END 0x1A /* End of text header */
-/*
- * PDA == Production Data Area
- *
- * In principle, the max. size of the PDA is is 4096 words. Currently,
- * however, only about 500 bytes of this area are used.
- *
- * Some USB implementations can't handle sizes in excess of 1016. Note
- * that PDA is not actually used in those USB environments, but may be
- * retrieved by common code.
- */
-#define MAX_PDA_SIZE 1000
-
/* Limit the amout we try to download in a single shot.
* Size is in bytes.
*/
@@ -228,13 +206,14 @@ hermes_aux_control(hermes_t *hw, int enabled)
* Scan PDR for the record with the specified RECORD_ID.
* If it's not found, return NULL.
*/
-static struct pdr *
-hermes_find_pdr(struct pdr *first_pdr, u32 record_id)
+static const struct pdr *
+hermes_find_pdr(const struct pdr *first_pdr, u32 record_id, const void *end)
{
- struct pdr *pdr = first_pdr;
- void *end = (void *)first_pdr + MAX_PDA_SIZE;
+ const struct pdr *pdr = first_pdr;
+
+ end -= sizeof(struct pdr);
- while (((void *)pdr < end) &&
+ while (((void *) pdr <= end) &&
(pdr_id(pdr) != PDI_END)) {
/*
* PDR area is currently not terminated by PDI_END.
@@ -254,12 +233,15 @@ hermes_find_pdr(struct pdr *first_pdr, u32 record_id)
}
/* Scan production data items for a particular entry */
-static struct pdi *
-hermes_find_pdi(struct pdi *first_pdi, u32 record_id)
+static const struct pdi *
+hermes_find_pdi(const struct pdi *first_pdi, u32 record_id, const void *end)
{
- struct pdi *pdi = first_pdi;
+ const struct pdi *pdi = first_pdi;
- while (pdi_id(pdi) != PDI_END) {
+ end -= sizeof(struct pdi);
+
+ while (((void *) pdi <= end) &&
+ (pdi_id(pdi) != PDI_END)) {
/* If the record ID matches, we are done */
if (pdi_id(pdi) == record_id)
@@ -272,12 +254,13 @@ hermes_find_pdi(struct pdi *first_pdi, u32 record_id)
/* Process one Plug Data Item - find corresponding PDR and plug it */
static int
-hermes_plug_pdi(hermes_t *hw, struct pdr *first_pdr, const struct pdi *pdi)
+hermes_plug_pdi(hermes_t *hw, const struct pdr *first_pdr,
+ const struct pdi *pdi, const void *pdr_end)
{
- struct pdr *pdr;
+ const struct pdr *pdr;
/* Find the PDR corresponding to this PDI */
- pdr = hermes_find_pdr(first_pdr, pdi_id(pdi));
+ pdr = hermes_find_pdr(first_pdr, pdi_id(pdi), pdr_end);
/* No match is found, safe to ignore */
if (!pdr)
@@ -347,7 +330,6 @@ int hermes_read_pda(hermes_t *hw,
return 0;
}
-EXPORT_SYMBOL(hermes_read_pda);
/* Parse PDA and write the records into the adapter
*
@@ -356,18 +338,22 @@ EXPORT_SYMBOL(hermes_read_pda);
*/
int hermes_apply_pda(hermes_t *hw,
const char *first_pdr,
- const __le16 *pda)
+ const void *pdr_end,
+ const __le16 *pda,
+ const void *pda_end)
{
int ret;
const struct pdi *pdi;
- struct pdr *pdr;
+ const struct pdr *pdr;
- pdr = (struct pdr *) first_pdr;
+ pdr = (const struct pdr *) first_pdr;
+ pda_end -= sizeof(struct pdi);
/* Go through every PDI and plug them into the adapter */
pdi = (const struct pdi *) (pda + 2);
- while (pdi_id(pdi) != PDI_END) {
- ret = hermes_plug_pdi(hw, pdr, pdi);
+ while (((void *) pdi <= pda_end) &&
+ (pdi_id(pdi) != PDI_END)) {
+ ret = hermes_plug_pdi(hw, pdr, pdi, pdr_end);
if (ret)
return ret;
@@ -376,21 +362,23 @@ int hermes_apply_pda(hermes_t *hw,
}
return 0;
}
-EXPORT_SYMBOL(hermes_apply_pda);
/* Identify the total number of bytes in all blocks
* including the header data.
*/
size_t
-hermes_blocks_length(const char *first_block)
+hermes_blocks_length(const char *first_block, const void *end)
{
const struct dblock *blk = (const struct dblock *) first_block;
int total_len = 0;
int len;
+ end -= sizeof(*blk);
+
/* Skip all blocks to locate Plug Data References
* (Spectrum CS) */
- while (dblock_addr(blk) != BLOCK_END) {
+ while (((void *) blk <= end) &&
+ (dblock_addr(blk) != BLOCK_END)) {
len = dblock_len(blk);
total_len += sizeof(*blk) + len;
blk = (struct dblock *) &blk->data[len];
@@ -398,7 +386,6 @@ hermes_blocks_length(const char *first_block)
return total_len;
}
-EXPORT_SYMBOL(hermes_blocks_length);
/*** Hermes programming ***/
@@ -452,7 +439,6 @@ int hermesi_program_init(hermes_t *hw, u32 offset)
return err;
}
-EXPORT_SYMBOL(hermesi_program_init);
/* Done programming data (Hermes I)
*
@@ -488,10 +474,9 @@ int hermesi_program_end(hermes_t *hw)
return rc ? rc : err;
}
-EXPORT_SYMBOL(hermesi_program_end);
/* Program the data blocks */
-int hermes_program(hermes_t *hw, const char *first_block, const char *end)
+int hermes_program(hermes_t *hw, const char *first_block, const void *end)
{
const struct dblock *blk;
u32 blkaddr;
@@ -503,14 +488,14 @@ int hermes_program(hermes_t *hw, const char *first_block, const char *end)
blk = (const struct dblock *) first_block;
- if ((const char *) blk > (end - sizeof(*blk)))
+ if ((void *) blk > (end - sizeof(*blk)))
return -EIO;
blkaddr = dblock_addr(blk);
blklen = dblock_len(blk);
while ((blkaddr != BLOCK_END) &&
- (((const char *) blk + blklen) <= end)) {
+ (((void *) blk + blklen) <= end)) {
printk(KERN_DEBUG PFX
"Programming block of length %d to address 0x%08x\n",
blklen, blkaddr);
@@ -542,7 +527,7 @@ int hermes_program(hermes_t *hw, const char *first_block, const char *end)
#endif
blk = (const struct dblock *) &blk->data[blklen];
- if ((const char *) blk > (end - sizeof(*blk)))
+ if ((void *) blk > (end - sizeof(*blk)))
return -EIO;
blkaddr = dblock_addr(blk);
@@ -550,19 +535,6 @@ int hermes_program(hermes_t *hw, const char *first_block, const char *end)
}
return 0;
}
-EXPORT_SYMBOL(hermes_program);
-
-static int __init init_hermes_dld(void)
-{
- return 0;
-}
-
-static void __exit exit_hermes_dld(void)
-{
-}
-
-module_init(init_hermes_dld);
-module_exit(exit_hermes_dld);
/*** Default plugging data for Hermes I ***/
/* Values from wl_lkm_718/hcf/dhf.c */
@@ -573,9 +545,9 @@ static const struct { \
__le16 id; \
u8 val[length]; \
} __attribute__ ((packed)) default_pdr_data_##pid = { \
- __constant_cpu_to_le16((sizeof(default_pdr_data_##pid)/ \
+ cpu_to_le16((sizeof(default_pdr_data_##pid)/ \
sizeof(__le16)) - 1), \
- __constant_cpu_to_le16(pid), \
+ cpu_to_le16(pid), \
data \
}
@@ -644,17 +616,20 @@ DEFINE_DEFAULT_PDR(0x0161, 256,
*/
int hermes_apply_pda_with_defaults(hermes_t *hw,
const char *first_pdr,
- const __le16 *pda)
+ const void *pdr_end,
+ const __le16 *pda,
+ const void *pda_end)
{
const struct pdr *pdr = (const struct pdr *) first_pdr;
- struct pdi *first_pdi = (struct pdi *) &pda[2];
- struct pdi *pdi;
- struct pdi *default_pdi = NULL;
- struct pdi *outdoor_pdi;
- void *end = (void *)first_pdr + MAX_PDA_SIZE;
+ const struct pdi *first_pdi = (const struct pdi *) &pda[2];
+ const struct pdi *pdi;
+ const struct pdi *default_pdi = NULL;
+ const struct pdi *outdoor_pdi;
int record_id;
- while (((void *)pdr < end) &&
+ pdr_end -= sizeof(struct pdr);
+
+ while (((void *) pdr <= pdr_end) &&
(pdr_id(pdr) != PDI_END)) {
/*
* For spectrum_cs firmwares,
@@ -666,7 +641,7 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
break;
record_id = pdr_id(pdr);
- pdi = hermes_find_pdi(first_pdi, record_id);
+ pdi = hermes_find_pdi(first_pdi, record_id, pda_end);
if (pdi)
printk(KERN_DEBUG PFX "Found record 0x%04x at %p\n",
record_id, pdi);
@@ -674,7 +649,8 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
switch (record_id) {
case 0x110: /* Modem REFDAC values */
case 0x120: /* Modem VGDAC values */
- outdoor_pdi = hermes_find_pdi(first_pdi, record_id + 1);
+ outdoor_pdi = hermes_find_pdi(first_pdi, record_id + 1,
+ pda_end);
default_pdi = NULL;
if (outdoor_pdi) {
pdi = outdoor_pdi;
@@ -715,7 +691,8 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
if (pdi) {
/* Lengths of the data in PDI and PDR must match */
- if (pdi_len(pdi) == pdr_len(pdr)) {
+ if ((pdi_len(pdi) == pdr_len(pdr)) &&
+ ((void *) pdi->data + pdi_len(pdi) < pda_end)) {
/* do the actual plugging */
hermes_aux_setaddr(hw, pdr_addr(pdr));
hermes_write_bytes(hw, HERMES_AUXDATA,
@@ -727,4 +704,3 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
}
return 0;
}
-EXPORT_SYMBOL(hermes_apply_pda_with_defaults);
diff --git a/drivers/net/wireless/orinoco/hermes_dld.h b/drivers/net/wireless/orinoco/hermes_dld.h
index 6fcb26277999..583a5bcf9175 100644
--- a/drivers/net/wireless/orinoco/hermes_dld.h
+++ b/drivers/net/wireless/orinoco/hermes_dld.h
@@ -29,7 +29,7 @@
int hermesi_program_init(hermes_t *hw, u32 offset);
int hermesi_program_end(hermes_t *hw);
-int hermes_program(hermes_t *hw, const char *first_block, const char *end);
+int hermes_program(hermes_t *hw, const char *first_block, const void *end);
int hermes_read_pda(hermes_t *hw,
__le16 *pda,
@@ -38,11 +38,15 @@ int hermes_read_pda(hermes_t *hw,
int use_eeprom);
int hermes_apply_pda(hermes_t *hw,
const char *first_pdr,
- const __le16 *pda);
+ const void *pdr_end,
+ const __le16 *pda,
+ const void *pda_end);
int hermes_apply_pda_with_defaults(hermes_t *hw,
const char *first_pdr,
- const __le16 *pda);
+ const void *pdr_end,
+ const __le16 *pda,
+ const void *pda_end);
-size_t hermes_blocks_length(const char *first_block);
+size_t hermes_blocks_length(const char *first_block, const void *end);
#endif /* _HERMES_DLD_H */
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
new file mode 100644
index 000000000000..081428d9409e
--- /dev/null
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -0,0 +1,586 @@
+/* Encapsulate basic setting changes and retrieval on Hermes hardware
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/kernel.h>
+#include <linux/if_arp.h>
+#include <linux/ieee80211.h>
+#include <linux/wireless.h>
+
+#include "hermes.h"
+#include "hermes_rid.h"
+#include "orinoco.h"
+
+#include "hw.h"
+
+/********************************************************************/
+/* Data tables */
+/********************************************************************/
+
+/* This tables gives the actual meanings of the bitrate IDs returned
+ * by the firmware. */
+static const struct {
+ int bitrate; /* in 100s of kilobits */
+ int automatic;
+ u16 agere_txratectrl;
+ u16 intersil_txratectrl;
+} bitrate_table[] = {
+ {110, 1, 3, 15}, /* Entry 0 is the default */
+ {10, 0, 1, 1},
+ {10, 1, 1, 1},
+ {20, 0, 2, 2},
+ {20, 1, 6, 3},
+ {55, 0, 4, 4},
+ {55, 1, 7, 7},
+ {110, 0, 5, 8},
+};
+#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
+
+int orinoco_get_bitratemode(int bitrate, int automatic)
+{
+ int ratemode = -1;
+ int i;
+
+ if ((bitrate != 10) && (bitrate != 20) &&
+ (bitrate != 55) && (bitrate != 110))
+ return ratemode;
+
+ for (i = 0; i < BITRATE_TABLE_SIZE; i++) {
+ if ((bitrate_table[i].bitrate == bitrate) &&
+ (bitrate_table[i].automatic == automatic)) {
+ ratemode = i;
+ break;
+ }
+ }
+ return ratemode;
+}
+
+void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic)
+{
+ BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
+
+ *bitrate = bitrate_table[ratemode].bitrate * 100000;
+ *automatic = bitrate_table[ratemode].automatic;
+}
+
+/* Get tsc from the firmware */
+int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc)
+{
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
+
+ if ((key < 0) || (key > 4))
+ return -EINVAL;
+
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
+ sizeof(tsc_arr), NULL, &tsc_arr);
+ if (!err)
+ memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0]));
+
+ return err;
+}
+
+int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
+{
+ hermes_t *hw = &priv->hw;
+ int ratemode = priv->bitratemode;
+ int err = 0;
+
+ if (ratemode >= BITRATE_TABLE_SIZE) {
+ printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
+ priv->ndev->name, ratemode);
+ return -EINVAL;
+ }
+
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE:
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFTXRATECONTROL,
+ bitrate_table[ratemode].agere_txratectrl);
+ break;
+ case FIRMWARE_TYPE_INTERSIL:
+ case FIRMWARE_TYPE_SYMBOL:
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFTXRATECONTROL,
+ bitrate_table[ratemode].intersil_txratectrl);
+ break;
+ default:
+ BUG();
+ }
+
+ return err;
+}
+
+int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate)
+{
+ hermes_t *hw = &priv->hw;
+ int i;
+ int err = 0;
+ u16 val;
+
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CURRENTTXRATE, &val);
+ if (err)
+ return err;
+
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
+ /* Note : in Lucent firmware, the return value of
+ * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
+ * and therefore is totally different from the
+ * encoding of HERMES_RID_CNFTXRATECONTROL.
+ * Don't forget that 6Mb/s is really 5.5Mb/s */
+ if (val == 6)
+ *bitrate = 5500000;
+ else
+ *bitrate = val * 1000000;
+ break;
+ case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
+ case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
+ for (i = 0; i < BITRATE_TABLE_SIZE; i++)
+ if (bitrate_table[i].intersil_txratectrl == val)
+ break;
+
+ if (i >= BITRATE_TABLE_SIZE)
+ printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
+ priv->ndev->name, val);
+
+ *bitrate = bitrate_table[i].bitrate * 100000;
+ break;
+ default:
+ BUG();
+ }
+
+ return err;
+}
+
+/* Set fixed AP address */
+int __orinoco_hw_set_wap(struct orinoco_private *priv)
+{
+ int roaming_flag;
+ int err = 0;
+ hermes_t *hw = &priv->hw;
+
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE:
+ /* not supported */
+ break;
+ case FIRMWARE_TYPE_INTERSIL:
+ if (priv->bssid_fixed)
+ roaming_flag = 2;
+ else
+ roaming_flag = 1;
+
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFROAMINGMODE,
+ roaming_flag);
+ break;
+ case FIRMWARE_TYPE_SYMBOL:
+ err = HERMES_WRITE_RECORD(hw, USER_BAP,
+ HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
+ &priv->desired_bssid);
+ break;
+ }
+ return err;
+}
+
+/* Change the WEP keys and/or the current keys. Can be called
+ * either from __orinoco_hw_setup_enc() or directly from
+ * orinoco_ioctl_setiwencode(). In the later case the association
+ * with the AP is not broken (if the firmware can handle it),
+ * which is needed for 802.1x implementations. */
+int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
+{
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE:
+ err = HERMES_WRITE_RECORD(hw, USER_BAP,
+ HERMES_RID_CNFWEPKEYS_AGERE,
+ &priv->keys);
+ if (err)
+ return err;
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFTXKEY_AGERE,
+ priv->tx_key);
+ if (err)
+ return err;
+ break;
+ case FIRMWARE_TYPE_INTERSIL:
+ case FIRMWARE_TYPE_SYMBOL:
+ {
+ int keylen;
+ int i;
+
+ /* Force uniform key length to work around
+ * firmware bugs */
+ keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
+
+ if (keylen > LARGE_KEY_SIZE) {
+ printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
+ priv->ndev->name, priv->tx_key, keylen);
+ return -E2BIG;
+ }
+
+ /* Write all 4 keys */
+ for (i = 0; i < ORINOCO_MAX_KEYS; i++) {
+ err = hermes_write_ltv(hw, USER_BAP,
+ HERMES_RID_CNFDEFAULTKEY0 + i,
+ HERMES_BYTES_TO_RECLEN(keylen),
+ priv->keys[i].data);
+ if (err)
+ return err;
+ }
+
+ /* Write the index of the key used in transmission */
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFWEPDEFAULTKEYID,
+ priv->tx_key);
+ if (err)
+ return err;
+ }
+ break;
+ }
+
+ return 0;
+}
+
+int __orinoco_hw_setup_enc(struct orinoco_private *priv)
+{
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ int master_wep_flag;
+ int auth_flag;
+ int enc_flag;
+
+ /* Setup WEP keys for WEP and WPA */
+ if (priv->encode_alg)
+ __orinoco_hw_setup_wepkeys(priv);
+
+ if (priv->wep_restrict)
+ auth_flag = HERMES_AUTH_SHARED_KEY;
+ else
+ auth_flag = HERMES_AUTH_OPEN;
+
+ if (priv->wpa_enabled)
+ enc_flag = 2;
+ else if (priv->encode_alg == IW_ENCODE_ALG_WEP)
+ enc_flag = 1;
+ else
+ enc_flag = 0;
+
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
+ if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
+ /* Enable the shared-key authentication. */
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFAUTHENTICATION_AGERE,
+ auth_flag);
+ }
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFWEPENABLED_AGERE,
+ enc_flag);
+ if (err)
+ return err;
+
+ if (priv->has_wpa) {
+ /* Set WPA key management */
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFSETWPAAUTHMGMTSUITE_AGERE,
+ priv->key_mgmt);
+ if (err)
+ return err;
+ }
+
+ break;
+
+ case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
+ case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
+ if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
+ if (priv->wep_restrict ||
+ (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
+ master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
+ HERMES_WEP_EXCL_UNENCRYPTED;
+ else
+ master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
+
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFAUTHENTICATION,
+ auth_flag);
+ if (err)
+ return err;
+ } else
+ master_wep_flag = 0;
+
+ if (priv->iw_mode == IW_MODE_MONITOR)
+ master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
+
+ /* Master WEP setting : on/off */
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFWEPFLAGS_INTERSIL,
+ master_wep_flag);
+ if (err)
+ return err;
+
+ break;
+ }
+
+ return 0;
+}
+
+/* key must be 32 bytes, including the tx and rx MIC keys.
+ * rsc must be 8 bytes
+ * tsc must be 8 bytes or NULL
+ */
+int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
+ u8 *key, u8 *rsc, u8 *tsc)
+{
+ struct {
+ __le16 idx;
+ u8 rsc[IW_ENCODE_SEQ_MAX_SIZE];
+ u8 key[TKIP_KEYLEN];
+ u8 tx_mic[MIC_KEYLEN];
+ u8 rx_mic[MIC_KEYLEN];
+ u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
+ } __attribute__ ((packed)) buf;
+ int ret;
+ int err;
+ int k;
+ u16 xmitting;
+
+ key_idx &= 0x3;
+
+ if (set_tx)
+ key_idx |= 0x8000;
+
+ buf.idx = cpu_to_le16(key_idx);
+ memcpy(buf.key, key,
+ sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));
+
+ if (rsc == NULL)
+ memset(buf.rsc, 0, sizeof(buf.rsc));
+ else
+ memcpy(buf.rsc, rsc, sizeof(buf.rsc));
+
+ if (tsc == NULL) {
+ memset(buf.tsc, 0, sizeof(buf.tsc));
+ buf.tsc[4] = 0x10;
+ } else {
+ memcpy(buf.tsc, tsc, sizeof(buf.tsc));
+ }
+
+ /* Wait upto 100ms for tx queue to empty */
+ k = 100;
+ do {
+ k--;
+ udelay(1000);
+ ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
+ &xmitting);
+ if (ret)
+ break;
+ } while ((k > 0) && xmitting);
+
+ if (k == 0)
+ ret = -ETIMEDOUT;
+
+ err = HERMES_WRITE_RECORD(hw, USER_BAP,
+ HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE,
+ &buf);
+
+ return ret ? ret : err;
+}
+
+int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx)
+{
+ hermes_t *hw = &priv->hw;
+ int err;
+
+ memset(&priv->tkip_key[key_idx], 0, sizeof(priv->tkip_key[key_idx]));
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE,
+ key_idx);
+ if (err)
+ printk(KERN_WARNING "%s: Error %d clearing TKIP key %d\n",
+ priv->ndev->name, err, key_idx);
+ return err;
+}
+
+int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
+ struct dev_addr_list *mc_list,
+ int mc_count, int promisc)
+{
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+
+ if (promisc != priv->promiscuous) {
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPROMISCUOUSMODE,
+ promisc);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
+ priv->ndev->name, err);
+ } else
+ priv->promiscuous = promisc;
+ }
+
+ /* If we're not in promiscuous mode, then we need to set the
+ * group address if either we want to multicast, or if we were
+ * multicasting and want to stop */
+ if (!promisc && (mc_count || priv->mc_count)) {
+ struct dev_mc_list *p = mc_list;
+ struct hermes_multicast mclist;
+ int i;
+
+ for (i = 0; i < mc_count; i++) {
+ /* paranoia: is list shorter than mc_count? */
+ BUG_ON(!p);
+ /* paranoia: bad address size in list? */
+ BUG_ON(p->dmi_addrlen != ETH_ALEN);
+
+ memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
+ p = p->next;
+ }
+
+ if (p)
+ printk(KERN_WARNING "%s: Multicast list is "
+ "longer than mc_count\n", priv->ndev->name);
+
+ err = hermes_write_ltv(hw, USER_BAP,
+ HERMES_RID_CNFGROUPADDRESSES,
+ HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
+ &mclist);
+ if (err)
+ printk(KERN_ERR "%s: Error %d setting multicast list.\n",
+ priv->ndev->name, err);
+ else
+ priv->mc_count = mc_count;
+ }
+ return err;
+}
+
+/* Return : < 0 -> error code ; >= 0 -> length */
+int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
+ char buf[IW_ESSID_MAX_SIZE+1])
+{
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ struct hermes_idstring essidbuf;
+ char *p = (char *)(&essidbuf.val);
+ int len;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if (strlen(priv->desired_essid) > 0) {
+ /* We read the desired SSID from the hardware rather
+ than from priv->desired_essid, just in case the
+ firmware is allowed to change it on us. I'm not
+ sure about this */
+ /* My guess is that the OWNSSID should always be whatever
+ * we set to the card, whereas CURRENT_SSID is the one that
+ * may change... - Jean II */
+ u16 rid;
+
+ *active = 1;
+
+ rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
+ HERMES_RID_CNFDESIREDSSID;
+
+ err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
+ NULL, &essidbuf);
+ if (err)
+ goto fail_unlock;
+ } else {
+ *active = 0;
+
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
+ sizeof(essidbuf), NULL, &essidbuf);
+ if (err)
+ goto fail_unlock;
+ }
+
+ len = le16_to_cpu(essidbuf.len);
+ BUG_ON(len > IW_ESSID_MAX_SIZE);
+
+ memset(buf, 0, IW_ESSID_MAX_SIZE);
+ memcpy(buf, p, len);
+ err = len;
+
+ fail_unlock:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+int orinoco_hw_get_freq(struct orinoco_private *priv)
+{
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ u16 channel;
+ int freq = 0;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL,
+ &channel);
+ if (err)
+ goto out;
+
+ /* Intersil firmware 1.3.5 returns 0 when the interface is down */
+ if (channel == 0) {
+ err = -EBUSY;
+ goto out;
+ }
+
+ if ((channel < 1) || (channel > NUM_CHANNELS)) {
+ printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
+ priv->ndev->name, channel);
+ err = -EBUSY;
+ goto out;
+
+ }
+ freq = ieee80211_dsss_chan_to_freq(channel);
+
+ out:
+ orinoco_unlock(priv, &flags);
+
+ if (err > 0)
+ err = -EBUSY;
+ return err ? err : freq;
+}
+
+int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
+ int *numrates, s32 *rates, int max)
+{
+ hermes_t *hw = &priv->hw;
+ struct hermes_idstring list;
+ unsigned char *p = (unsigned char *)&list.val;
+ int err = 0;
+ int num;
+ int i;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
+ sizeof(list), NULL, &list);
+ orinoco_unlock(priv, &flags);
+
+ if (err)
+ return err;
+
+ num = le16_to_cpu(list.len);
+ *numrates = num;
+ num = min(num, max);
+
+ for (i = 0; i < num; i++)
+ rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
+
+ return 0;
+}
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h
new file mode 100644
index 000000000000..dc3f23a9c1c7
--- /dev/null
+++ b/drivers/net/wireless/orinoco/hw.h
@@ -0,0 +1,47 @@
+/* Encapsulate basic setting changes on Hermes hardware
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_HW_H_
+#define _ORINOCO_HW_H_
+
+#include <linux/types.h>
+#include <linux/wireless.h>
+
+/* Hardware BAPs */
+#define USER_BAP 0
+#define IRQ_BAP 1
+
+/* WEP key sizes */
+#define SMALL_KEY_SIZE 5
+#define LARGE_KEY_SIZE 13
+
+/* Number of supported channels */
+#define NUM_CHANNELS 14
+
+/* Forward declarations */
+struct orinoco_private;
+struct dev_addr_list;
+
+int orinoco_get_bitratemode(int bitrate, int automatic);
+void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic);
+
+int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc);
+int __orinoco_hw_set_bitrate(struct orinoco_private *priv);
+int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate);
+int __orinoco_hw_set_wap(struct orinoco_private *priv);
+int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv);
+int __orinoco_hw_setup_enc(struct orinoco_private *priv);
+int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
+ u8 *key, u8 *rsc, u8 *tsc);
+int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx);
+int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
+ struct dev_addr_list *mc_list,
+ int mc_count, int promisc);
+int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
+ char buf[IW_ESSID_MAX_SIZE+1]);
+int orinoco_hw_get_freq(struct orinoco_private *priv);
+int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
+ int *numrates, s32 *rates, int max);
+
+#endif /* _ORINOCO_HW_H_ */
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
new file mode 100644
index 000000000000..345593c4accb
--- /dev/null
+++ b/drivers/net/wireless/orinoco/main.c
@@ -0,0 +1,2667 @@
+/* main.c - (formerly known as dldwd_cs.c, orinoco_cs.c and orinoco.c)
+ *
+ * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
+ * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
+ *
+ * Current maintainers (as of 29 September 2003) are:
+ * Pavel Roskin <proski AT gnu.org>
+ * and David Gibson <hermes AT gibson.dropbear.id.au>
+ *
+ * (C) Copyright David Gibson, IBM Corporation 2001-2003.
+ * Copyright (C) 2000 David Gibson, Linuxcare Australia.
+ * With some help from :
+ * Copyright (C) 2001 Jean Tourrilhes, HP Labs
+ * Copyright (C) 2001 Benjamin Herrenschmidt
+ *
+ * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
+ *
+ * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy
+ * AT fasta.fh-dortmund.de>
+ * http://www.stud.fh-dortmund.de/~andy/wvlan/
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dahinds AT users.sourceforge.net>. Portions created by David
+ * A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights
+ * Reserved.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL. If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL. */
+
+/*
+ * TODO
+ * o Handle de-encapsulation within network layer, provide 802.11
+ * headers (patch from Thomas 'Dent' Mirlacher)
+ * o Fix possible races in SPY handling.
+ * o Disconnect wireless extensions from fundamental configuration.
+ * o (maybe) Software WEP support (patch from Stano Meduna).
+ * o (maybe) Use multiple Tx buffers - driver handling queue
+ * rather than firmware.
+ */
+
+/* Locking and synchronization:
+ *
+ * The basic principle is that everything is serialized through a
+ * single spinlock, priv->lock. The lock is used in user, bh and irq
+ * context, so when taken outside hardirq context it should always be
+ * taken with interrupts disabled. The lock protects both the
+ * hardware and the struct orinoco_private.
+ *
+ * Another flag, priv->hw_unavailable indicates that the hardware is
+ * unavailable for an extended period of time (e.g. suspended, or in
+ * the middle of a hard reset). This flag is protected by the
+ * spinlock. All code which touches the hardware should check the
+ * flag after taking the lock, and if it is set, give up on whatever
+ * they are doing and drop the lock again. The orinoco_lock()
+ * function handles this (it unlocks and returns -EBUSY if
+ * hw_unavailable is non-zero).
+ */
+
+#define DRIVER_NAME "orinoco"
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/suspend.h>
+#include <linux/if_arp.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <net/iw_handler.h>
+
+#include "hermes_rid.h"
+#include "hermes_dld.h"
+#include "hw.h"
+#include "scan.h"
+#include "mic.h"
+#include "fw.h"
+#include "wext.h"
+#include "main.h"
+
+#include "orinoco.h"
+
+/********************************************************************/
+/* Module information */
+/********************************************************************/
+
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & "
+ "David Gibson <hermes@gibson.dropbear.id.au>");
+MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based "
+ "and similar wireless cards");
+MODULE_LICENSE("Dual MPL/GPL");
+
+/* Level of debugging. Used in the macros in orinoco.h */
+#ifdef ORINOCO_DEBUG
+int orinoco_debug = ORINOCO_DEBUG;
+EXPORT_SYMBOL(orinoco_debug);
+module_param(orinoco_debug, int, 0644);
+MODULE_PARM_DESC(orinoco_debug, "Debug level");
+#endif
+
+static int suppress_linkstatus; /* = 0 */
+module_param(suppress_linkstatus, bool, 0644);
+MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
+
+static int ignore_disconnect; /* = 0 */
+module_param(ignore_disconnect, int, 0644);
+MODULE_PARM_DESC(ignore_disconnect,
+ "Don't report lost link to the network layer");
+
+int force_monitor; /* = 0 */
+module_param(force_monitor, int, 0644);
+MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
+
+/********************************************************************/
+/* Internal constants */
+/********************************************************************/
+
+/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
+static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2)
+
+#define ORINOCO_MIN_MTU 256
+#define ORINOCO_MAX_MTU (IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
+
+#define SYMBOL_MAX_VER_LEN (14)
+#define MAX_IRQLOOPS_PER_IRQ 10
+#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of
+ * how many events the
+ * device could
+ * legitimately generate */
+#define TX_NICBUF_SIZE_BUG 1585 /* Bug in Symbol firmware */
+
+#define DUMMY_FID 0xFFFF
+
+/*#define MAX_MULTICAST(priv) (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
+ HERMES_MAX_MULTICAST : 0)*/
+#define MAX_MULTICAST(priv) (HERMES_MAX_MULTICAST)
+
+#define ORINOCO_INTEN (HERMES_EV_RX | HERMES_EV_ALLOC \
+ | HERMES_EV_TX | HERMES_EV_TXEXC \
+ | HERMES_EV_WTERR | HERMES_EV_INFO \
+ | HERMES_EV_INFDROP)
+
+static const struct ethtool_ops orinoco_ethtool_ops;
+
+/********************************************************************/
+/* Data types */
+/********************************************************************/
+
+/* Beginning of the Tx descriptor, used in TxExc handling */
+struct hermes_txexc_data {
+ struct hermes_tx_descriptor desc;
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+} __attribute__ ((packed));
+
+/* Rx frame header except compatibility 802.3 header */
+struct hermes_rx_descriptor {
+ /* Control */
+ __le16 status;
+ __le32 time;
+ u8 silence;
+ u8 signal;
+ u8 rate;
+ u8 rxflow;
+ __le32 reserved;
+
+ /* 802.11 header */
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 addr4[ETH_ALEN];
+
+ /* Data length */
+ __le16 data_len;
+} __attribute__ ((packed));
+
+struct orinoco_rx_data {
+ struct hermes_rx_descriptor *desc;
+ struct sk_buff *skb;
+ struct list_head list;
+};
+
+/********************************************************************/
+/* Function prototypes */
+/********************************************************************/
+
+static void __orinoco_set_multicast_list(struct net_device *dev);
+
+/********************************************************************/
+/* Internal helper functions */
+/********************************************************************/
+
+void set_port_type(struct orinoco_private *priv)
+{
+ switch (priv->iw_mode) {
+ case IW_MODE_INFRA:
+ priv->port_type = 1;
+ priv->createibss = 0;
+ break;
+ case IW_MODE_ADHOC:
+ if (priv->prefer_port3) {
+ priv->port_type = 3;
+ priv->createibss = 0;
+ } else {
+ priv->port_type = priv->ibss_port;
+ priv->createibss = 1;
+ }
+ break;
+ case IW_MODE_MONITOR:
+ priv->port_type = 3;
+ priv->createibss = 0;
+ break;
+ default:
+ printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
+ priv->ndev->name);
+ }
+}
+
+/********************************************************************/
+/* Device methods */
+/********************************************************************/
+
+static int orinoco_open(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int err;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = __orinoco_up(dev);
+
+ if (!err)
+ priv->open = 1;
+
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_stop(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = 0;
+
+ /* We mustn't use orinoco_lock() here, because we need to be
+ able to close the interface even if hw_unavailable is set
+ (e.g. as we're released after a PC Card removal) */
+ spin_lock_irq(&priv->lock);
+
+ priv->open = 0;
+
+ err = __orinoco_down(dev);
+
+ spin_unlock_irq(&priv->lock);
+
+ return err;
+}
+
+static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ return &priv->stats;
+}
+
+static void orinoco_set_multicast_list(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0) {
+ printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
+ "called when hw_unavailable\n", dev->name);
+ return;
+ }
+
+ __orinoco_set_multicast_list(dev);
+ orinoco_unlock(priv, &flags);
+}
+
+static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ if ((new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU))
+ return -EINVAL;
+
+ /* MTU + encapsulation + header length */
+ if ((new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) >
+ (priv->nicbuf_size - ETH_HLEN))
+ return -EINVAL;
+
+ dev->mtu = new_mtu;
+
+ return 0;
+}
+
+/********************************************************************/
+/* Tx path */
+/********************************************************************/
+
+static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ u16 txfid = priv->txfid;
+ struct ethhdr *eh;
+ int tx_control;
+ unsigned long flags;
+
+ if (!netif_running(dev)) {
+ printk(KERN_ERR "%s: Tx on stopped device!\n",
+ dev->name);
+ return NETDEV_TX_BUSY;
+ }
+
+ if (netif_queue_stopped(dev)) {
+ printk(KERN_DEBUG "%s: Tx while transmitter busy!\n",
+ dev->name);
+ return NETDEV_TX_BUSY;
+ }
+
+ if (orinoco_lock(priv, &flags) != 0) {
+ printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
+ dev->name);
+ return NETDEV_TX_BUSY;
+ }
+
+ if (!netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
+ /* Oops, the firmware hasn't established a connection,
+ silently drop the packet (this seems to be the
+ safest approach). */
+ goto drop;
+ }
+
+ /* Check packet length */
+ if (skb->len < ETH_HLEN)
+ goto drop;
+
+ tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
+
+ if (priv->encode_alg == IW_ENCODE_ALG_TKIP)
+ tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
+ HERMES_TXCTRL_MIC;
+
+ if (priv->has_alt_txcntl) {
+ /* WPA enabled firmwares have tx_cntl at the end of
+ * the 802.11 header. So write zeroed descriptor and
+ * 802.11 header at the same time
+ */
+ char desc[HERMES_802_3_OFFSET];
+ __le16 *txcntl = (__le16 *) &desc[HERMES_TXCNTL2_OFFSET];
+
+ memset(&desc, 0, sizeof(desc));
+
+ *txcntl = cpu_to_le16(tx_control);
+ err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
+ txfid, 0);
+ if (err) {
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: Error %d writing Tx "
+ "descriptor to BAP\n", dev->name, err);
+ goto busy;
+ }
+ } else {
+ struct hermes_tx_descriptor desc;
+
+ memset(&desc, 0, sizeof(desc));
+
+ desc.tx_control = cpu_to_le16(tx_control);
+ err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
+ txfid, 0);
+ if (err) {
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: Error %d writing Tx "
+ "descriptor to BAP\n", dev->name, err);
+ goto busy;
+ }
+
+ /* Clear the 802.11 header and data length fields - some
+ * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
+ * if this isn't done. */
+ hermes_clear_words(hw, HERMES_DATA0,
+ HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
+ }
+
+ eh = (struct ethhdr *)skb->data;
+
+ /* Encapsulate Ethernet-II frames */
+ if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
+ struct header_struct {
+ struct ethhdr eth; /* 802.3 header */
+ u8 encap[6]; /* 802.2 header */
+ } __attribute__ ((packed)) hdr;
+
+ /* Strip destination and source from the data */
+ skb_pull(skb, 2 * ETH_ALEN);
+
+ /* And move them to a separate header */
+ memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
+ hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
+ memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
+
+ /* Insert the SNAP header */
+ if (skb_headroom(skb) < sizeof(hdr)) {
+ printk(KERN_ERR
+ "%s: Not enough headroom for 802.2 headers %d\n",
+ dev->name, skb_headroom(skb));
+ goto drop;
+ }
+ eh = (struct ethhdr *) skb_push(skb, sizeof(hdr));
+ memcpy(eh, &hdr, sizeof(hdr));
+ }
+
+ err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
+ txfid, HERMES_802_3_OFFSET);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
+ dev->name, err);
+ goto busy;
+ }
+
+ /* Calculate Michael MIC */
+ if (priv->encode_alg == IW_ENCODE_ALG_TKIP) {
+ u8 mic_buf[MICHAEL_MIC_LEN + 1];
+ u8 *mic;
+ size_t offset;
+ size_t len;
+
+ if (skb->len % 2) {
+ /* MIC start is on an odd boundary */
+ mic_buf[0] = skb->data[skb->len - 1];
+ mic = &mic_buf[1];
+ offset = skb->len - 1;
+ len = MICHAEL_MIC_LEN + 1;
+ } else {
+ mic = &mic_buf[0];
+ offset = skb->len;
+ len = MICHAEL_MIC_LEN;
+ }
+
+ orinoco_mic(priv->tx_tfm_mic,
+ priv->tkip_key[priv->tx_key].tx_mic,
+ eh->h_dest, eh->h_source, 0 /* priority */,
+ skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
+
+ /* Write the MIC */
+ err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
+ txfid, HERMES_802_3_OFFSET + offset);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
+ dev->name, err);
+ goto busy;
+ }
+ }
+
+ /* Finally, we actually initiate the send */
+ netif_stop_queue(dev);
+
+ err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
+ txfid, NULL);
+ if (err) {
+ netif_start_queue(dev);
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: Error %d transmitting packet\n",
+ dev->name, err);
+ goto busy;
+ }
+
+ dev->trans_start = jiffies;
+ stats->tx_bytes += HERMES_802_3_OFFSET + skb->len;
+ goto ok;
+
+ drop:
+ stats->tx_errors++;
+ stats->tx_dropped++;
+
+ ok:
+ orinoco_unlock(priv, &flags);
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+
+ busy:
+ if (err == -EIO)
+ schedule_work(&priv->reset_work);
+ orinoco_unlock(priv, &flags);
+ return NETDEV_TX_BUSY;
+}
+
+static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ u16 fid = hermes_read_regn(hw, ALLOCFID);
+
+ if (fid != priv->txfid) {
+ if (fid != DUMMY_FID)
+ printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
+ dev->name, fid);
+ return;
+ }
+
+ hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
+}
+
+static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+
+ stats->tx_packets++;
+
+ netif_wake_queue(dev);
+
+ hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
+}
+
+static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+ u16 fid = hermes_read_regn(hw, TXCOMPLFID);
+ u16 status;
+ struct hermes_txexc_data hdr;
+ int err = 0;
+
+ if (fid == DUMMY_FID)
+ return; /* Nothing's really happened */
+
+ /* Read part of the frame header - we need status and addr1 */
+ err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
+ sizeof(struct hermes_txexc_data),
+ fid, 0);
+
+ hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
+ stats->tx_errors++;
+
+ if (err) {
+ printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
+ "(FID=%04X error %d)\n",
+ dev->name, fid, err);
+ return;
+ }
+
+ DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
+ err, fid);
+
+ /* We produce a TXDROP event only for retry or lifetime
+ * exceeded, because that's the only status that really mean
+ * that this particular node went away.
+ * Other errors means that *we* screwed up. - Jean II */
+ status = le16_to_cpu(hdr.desc.status);
+ if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
+ union iwreq_data wrqu;
+
+ /* Copy 802.11 dest address.
+ * We use the 802.11 header because the frame may
+ * not be 802.3 or may be mangled...
+ * In Ad-Hoc mode, it will be the node address.
+ * In managed mode, it will be most likely the AP addr
+ * User space will figure out how to convert it to
+ * whatever it needs (IP address or else).
+ * - Jean II */
+ memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
+ wrqu.addr.sa_family = ARPHRD_ETHER;
+
+ /* Send event to user space */
+ wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
+ }
+
+ netif_wake_queue(dev);
+}
+
+static void orinoco_tx_timeout(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+ struct hermes *hw = &priv->hw;
+
+ printk(KERN_WARNING "%s: Tx timeout! "
+ "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
+ dev->name, hermes_read_regn(hw, ALLOCFID),
+ hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
+
+ stats->tx_errors++;
+
+ schedule_work(&priv->reset_work);
+}
+
+/********************************************************************/
+/* Rx path (data frames) */
+/********************************************************************/
+
+/* Does the frame have a SNAP header indicating it should be
+ * de-encapsulated to Ethernet-II? */
+static inline int is_ethersnap(void *_hdr)
+{
+ u8 *hdr = _hdr;
+
+ /* We de-encapsulate all packets which, a) have SNAP headers
+ * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
+ * and where b) the OUI of the SNAP header is 00:00:00 or
+ * 00:00:f8 - we need both because different APs appear to use
+ * different OUIs for some reason */
+ return (memcmp(hdr, &encaps_hdr, 5) == 0)
+ && ((hdr[5] == 0x00) || (hdr[5] == 0xf8));
+}
+
+static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
+ int level, int noise)
+{
+ struct iw_quality wstats;
+ wstats.level = level - 0x95;
+ wstats.noise = noise - 0x95;
+ wstats.qual = (level > noise) ? (level - noise) : 0;
+ wstats.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+ /* Update spy records */
+ wireless_spy_update(dev, mac, &wstats);
+}
+
+static void orinoco_stat_gather(struct net_device *dev,
+ struct sk_buff *skb,
+ struct hermes_rx_descriptor *desc)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ /* Using spy support with lots of Rx packets, like in an
+ * infrastructure (AP), will really slow down everything, because
+ * the MAC address must be compared to each entry of the spy list.
+ * If the user really asks for it (set some address in the
+ * spy list), we do it, but he will pay the price.
+ * Note that to get here, you need both WIRELESS_SPY
+ * compiled in AND some addresses in the list !!!
+ */
+ /* Note : gcc will optimise the whole section away if
+ * WIRELESS_SPY is not defined... - Jean II */
+ if (SPY_NUMBER(priv)) {
+ orinoco_spy_gather(dev, skb_mac_header(skb) + ETH_ALEN,
+ desc->signal, desc->silence);
+ }
+}
+
+/*
+ * orinoco_rx_monitor - handle received monitor frames.
+ *
+ * Arguments:
+ * dev network device
+ * rxfid received FID
+ * desc rx descriptor of the frame
+ *
+ * Call context: interrupt
+ */
+static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
+ struct hermes_rx_descriptor *desc)
+{
+ u32 hdrlen = 30; /* return full header by default */
+ u32 datalen = 0;
+ u16 fc;
+ int err;
+ int len;
+ struct sk_buff *skb;
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+ hermes_t *hw = &priv->hw;
+
+ len = le16_to_cpu(desc->data_len);
+
+ /* Determine the size of the header and the data */
+ fc = le16_to_cpu(desc->frame_ctl);
+ switch (fc & IEEE80211_FCTL_FTYPE) {
+ case IEEE80211_FTYPE_DATA:
+ if ((fc & IEEE80211_FCTL_TODS)
+ && (fc & IEEE80211_FCTL_FROMDS))
+ hdrlen = 30;
+ else
+ hdrlen = 24;
+ datalen = len;
+ break;
+ case IEEE80211_FTYPE_MGMT:
+ hdrlen = 24;
+ datalen = len;
+ break;
+ case IEEE80211_FTYPE_CTL:
+ switch (fc & IEEE80211_FCTL_STYPE) {
+ case IEEE80211_STYPE_PSPOLL:
+ case IEEE80211_STYPE_RTS:
+ case IEEE80211_STYPE_CFEND:
+ case IEEE80211_STYPE_CFENDACK:
+ hdrlen = 16;
+ break;
+ case IEEE80211_STYPE_CTS:
+ case IEEE80211_STYPE_ACK:
+ hdrlen = 10;
+ break;
+ }
+ break;
+ default:
+ /* Unknown frame type */
+ break;
+ }
+
+ /* sanity check the length */
+ if (datalen > IEEE80211_MAX_DATA_LEN + 12) {
+ printk(KERN_DEBUG "%s: oversized monitor frame, "
+ "data length = %d\n", dev->name, datalen);
+ stats->rx_length_errors++;
+ goto update_stats;
+ }
+
+ skb = dev_alloc_skb(hdrlen + datalen);
+ if (!skb) {
+ printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
+ dev->name);
+ goto update_stats;
+ }
+
+ /* Copy the 802.11 header to the skb */
+ memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
+ skb_reset_mac_header(skb);
+
+ /* If any, copy the data from the card to the skb */
+ if (datalen > 0) {
+ err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
+ ALIGN(datalen, 2), rxfid,
+ HERMES_802_2_OFFSET);
+ if (err) {
+ printk(KERN_ERR "%s: error %d reading monitor frame\n",
+ dev->name, err);
+ goto drop;
+ }
+ }
+
+ skb->dev = dev;
+ skb->ip_summed = CHECKSUM_NONE;
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = cpu_to_be16(ETH_P_802_2);
+
+ stats->rx_packets++;
+ stats->rx_bytes += skb->len;
+
+ netif_rx(skb);
+ return;
+
+ drop:
+ dev_kfree_skb_irq(skb);
+ update_stats:
+ stats->rx_errors++;
+ stats->rx_dropped++;
+}
+
+static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+ struct iw_statistics *wstats = &priv->wstats;
+ struct sk_buff *skb = NULL;
+ u16 rxfid, status;
+ int length;
+ struct hermes_rx_descriptor *desc;
+ struct orinoco_rx_data *rx_data;
+ int err;
+
+ desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
+ if (!desc) {
+ printk(KERN_WARNING
+ "%s: Can't allocate space for RX descriptor\n",
+ dev->name);
+ goto update_stats;
+ }
+
+ rxfid = hermes_read_regn(hw, RXFID);
+
+ err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc),
+ rxfid, 0);
+ if (err) {
+ printk(KERN_ERR "%s: error %d reading Rx descriptor. "
+ "Frame dropped.\n", dev->name, err);
+ goto update_stats;
+ }
+
+ status = le16_to_cpu(desc->status);
+
+ if (status & HERMES_RXSTAT_BADCRC) {
+ DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
+ dev->name);
+ stats->rx_crc_errors++;
+ goto update_stats;
+ }
+
+ /* Handle frames in monitor mode */
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ orinoco_rx_monitor(dev, rxfid, desc);
+ goto out;
+ }
+
+ if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
+ DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
+ dev->name);
+ wstats->discard.code++;
+ goto update_stats;
+ }
+
+ length = le16_to_cpu(desc->data_len);
+
+ /* Sanity checks */
+ if (length < 3) { /* No for even an 802.2 LLC header */
+ /* At least on Symbol firmware with PCF we get quite a
+ lot of these legitimately - Poll frames with no
+ data. */
+ goto out;
+ }
+ if (length > IEEE80211_MAX_DATA_LEN) {
+ printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
+ dev->name, length);
+ stats->rx_length_errors++;
+ goto update_stats;
+ }
+
+ /* Payload size does not include Michael MIC. Increase payload
+ * size to read it together with the data. */
+ if (status & HERMES_RXSTAT_MIC)
+ length += MICHAEL_MIC_LEN;
+
+ /* We need space for the packet data itself, plus an ethernet
+ header, plus 2 bytes so we can align the IP header on a
+ 32bit boundary, plus 1 byte so we can read in odd length
+ packets from the card, which has an IO granularity of 16
+ bits */
+ skb = dev_alloc_skb(length+ETH_HLEN+2+1);
+ if (!skb) {
+ printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
+ dev->name);
+ goto update_stats;
+ }
+
+ /* We'll prepend the header, so reserve space for it. The worst
+ case is no decapsulation, when 802.3 header is prepended and
+ nothing is removed. 2 is for aligning the IP header. */
+ skb_reserve(skb, ETH_HLEN + 2);
+
+ err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
+ ALIGN(length, 2), rxfid,
+ HERMES_802_2_OFFSET);
+ if (err) {
+ printk(KERN_ERR "%s: error %d reading frame. "
+ "Frame dropped.\n", dev->name, err);
+ goto drop;
+ }
+
+ /* Add desc and skb to rx queue */
+ rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC);
+ if (!rx_data) {
+ printk(KERN_WARNING "%s: Can't allocate RX packet\n",
+ dev->name);
+ goto drop;
+ }
+ rx_data->desc = desc;
+ rx_data->skb = skb;
+ list_add_tail(&rx_data->list, &priv->rx_list);
+ tasklet_schedule(&priv->rx_tasklet);
+
+ return;
+
+drop:
+ dev_kfree_skb_irq(skb);
+update_stats:
+ stats->rx_errors++;
+ stats->rx_dropped++;
+out:
+ kfree(desc);
+}
+
+static void orinoco_rx(struct net_device *dev,
+ struct hermes_rx_descriptor *desc,
+ struct sk_buff *skb)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct net_device_stats *stats = &priv->stats;
+ u16 status, fc;
+ int length;
+ struct ethhdr *hdr;
+
+ status = le16_to_cpu(desc->status);
+ length = le16_to_cpu(desc->data_len);
+ fc = le16_to_cpu(desc->frame_ctl);
+
+ /* Calculate and check MIC */
+ if (status & HERMES_RXSTAT_MIC) {
+ int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >>
+ HERMES_MIC_KEY_ID_SHIFT);
+ u8 mic[MICHAEL_MIC_LEN];
+ u8 *rxmic;
+ u8 *src = (fc & IEEE80211_FCTL_FROMDS) ?
+ desc->addr3 : desc->addr2;
+
+ /* Extract Michael MIC from payload */
+ rxmic = skb->data + skb->len - MICHAEL_MIC_LEN;
+
+ skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
+ length -= MICHAEL_MIC_LEN;
+
+ orinoco_mic(priv->rx_tfm_mic,
+ priv->tkip_key[key_id].rx_mic,
+ desc->addr1,
+ src,
+ 0, /* priority or QoS? */
+ skb->data,
+ skb->len,
+ &mic[0]);
+
+ if (memcmp(mic, rxmic,
+ MICHAEL_MIC_LEN)) {
+ union iwreq_data wrqu;
+ struct iw_michaelmicfailure wxmic;
+
+ printk(KERN_WARNING "%s: "
+ "Invalid Michael MIC in data frame from %pM, "
+ "using key %i\n",
+ dev->name, src, key_id);
+
+ /* TODO: update stats */
+
+ /* Notify userspace */
+ memset(&wxmic, 0, sizeof(wxmic));
+ wxmic.flags = key_id & IW_MICFAILURE_KEY_ID;
+ wxmic.flags |= (desc->addr1[0] & 1) ?
+ IW_MICFAILURE_GROUP : IW_MICFAILURE_PAIRWISE;
+ wxmic.src_addr.sa_family = ARPHRD_ETHER;
+ memcpy(wxmic.src_addr.sa_data, src, ETH_ALEN);
+
+ (void) orinoco_hw_get_tkip_iv(priv, key_id,
+ &wxmic.tsc[0]);
+
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.length = sizeof(wxmic);
+ wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu,
+ (char *) &wxmic);
+
+ goto drop;
+ }
+ }
+
+ /* Handle decapsulation
+ * In most cases, the firmware tell us about SNAP frames.
+ * For some reason, the SNAP frames sent by LinkSys APs
+ * are not properly recognised by most firmwares.
+ * So, check ourselves */
+ if (length >= ENCAPS_OVERHEAD &&
+ (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
+ ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
+ is_ethersnap(skb->data))) {
+ /* These indicate a SNAP within 802.2 LLC within
+ 802.11 frame which we'll need to de-encapsulate to
+ the original EthernetII frame. */
+ hdr = (struct ethhdr *)skb_push(skb,
+ ETH_HLEN - ENCAPS_OVERHEAD);
+ } else {
+ /* 802.3 frame - prepend 802.3 header as is */
+ hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
+ hdr->h_proto = htons(length);
+ }
+ memcpy(hdr->h_dest, desc->addr1, ETH_ALEN);
+ if (fc & IEEE80211_FCTL_FROMDS)
+ memcpy(hdr->h_source, desc->addr3, ETH_ALEN);
+ else
+ memcpy(hdr->h_source, desc->addr2, ETH_ALEN);
+
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->ip_summed = CHECKSUM_NONE;
+ if (fc & IEEE80211_FCTL_TODS)
+ skb->pkt_type = PACKET_OTHERHOST;
+
+ /* Process the wireless stats if needed */
+ orinoco_stat_gather(dev, skb, desc);
+
+ /* Pass the packet to the networking stack */
+ netif_rx(skb);
+ stats->rx_packets++;
+ stats->rx_bytes += length;
+
+ return;
+
+ drop:
+ dev_kfree_skb(skb);
+ stats->rx_errors++;
+ stats->rx_dropped++;
+}
+
+static void orinoco_rx_isr_tasklet(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *) data;
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_rx_data *rx_data, *temp;
+ struct hermes_rx_descriptor *desc;
+ struct sk_buff *skb;
+ unsigned long flags;
+
+ /* orinoco_rx requires the driver lock, and we also need to
+ * protect priv->rx_list, so just hold the lock over the
+ * lot.
+ *
+ * If orinoco_lock fails, we've unplugged the card. In this
+ * case just abort. */
+ if (orinoco_lock(priv, &flags) != 0)
+ return;
+
+ /* extract desc and skb from queue */
+ list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
+ desc = rx_data->desc;
+ skb = rx_data->skb;
+ list_del(&rx_data->list);
+ kfree(rx_data);
+
+ orinoco_rx(dev, desc, skb);
+
+ kfree(desc);
+ }
+
+ orinoco_unlock(priv, &flags);
+}
+
+/********************************************************************/
+/* Rx path (info frames) */
+/********************************************************************/
+
+static void print_linkstatus(struct net_device *dev, u16 status)
+{
+ char *s;
+
+ if (suppress_linkstatus)
+ return;
+
+ switch (status) {
+ case HERMES_LINKSTATUS_NOT_CONNECTED:
+ s = "Not Connected";
+ break;
+ case HERMES_LINKSTATUS_CONNECTED:
+ s = "Connected";
+ break;
+ case HERMES_LINKSTATUS_DISCONNECTED:
+ s = "Disconnected";
+ break;
+ case HERMES_LINKSTATUS_AP_CHANGE:
+ s = "AP Changed";
+ break;
+ case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
+ s = "AP Out of Range";
+ break;
+ case HERMES_LINKSTATUS_AP_IN_RANGE:
+ s = "AP In Range";
+ break;
+ case HERMES_LINKSTATUS_ASSOC_FAILED:
+ s = "Association Failed";
+ break;
+ default:
+ s = "UNKNOWN";
+ }
+
+ printk(KERN_DEBUG "%s: New link status: %s (%04x)\n",
+ dev->name, s, status);
+}
+
+/* Search scan results for requested BSSID, join it if found */
+static void orinoco_join_ap(struct work_struct *work)
+{
+ struct orinoco_private *priv =
+ container_of(work, struct orinoco_private, join_work);
+ struct net_device *dev = priv->ndev;
+ struct hermes *hw = &priv->hw;
+ int err;
+ unsigned long flags;
+ struct join_req {
+ u8 bssid[ETH_ALEN];
+ __le16 channel;
+ } __attribute__ ((packed)) req;
+ const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
+ struct prism2_scan_apinfo *atom = NULL;
+ int offset = 4;
+ int found = 0;
+ u8 *buf;
+ u16 len;
+
+ /* Allocate buffer for scan results */
+ buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
+ if (!buf)
+ return;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ goto fail_lock;
+
+ /* Sanity checks in case user changed something in the meantime */
+ if (!priv->bssid_fixed)
+ goto out;
+
+ if (strlen(priv->desired_essid) == 0)
+ goto out;
+
+ /* Read scan results from the firmware */
+ err = hermes_read_ltv(hw, USER_BAP,
+ HERMES_RID_SCANRESULTSTABLE,
+ MAX_SCAN_LEN, &len, buf);
+ if (err) {
+ printk(KERN_ERR "%s: Cannot read scan results\n",
+ dev->name);
+ goto out;
+ }
+
+ len = HERMES_RECLEN_TO_BYTES(len);
+
+ /* Go through the scan results looking for the channel of the AP
+ * we were requested to join */
+ for (; offset + atom_len <= len; offset += atom_len) {
+ atom = (struct prism2_scan_apinfo *) (buf + offset);
+ if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ DEBUG(1, "%s: Requested AP not found in scan results\n",
+ dev->name);
+ goto out;
+ }
+
+ memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
+ req.channel = atom->channel; /* both are little-endian */
+ err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
+ &req);
+ if (err)
+ printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
+
+ out:
+ orinoco_unlock(priv, &flags);
+
+ fail_lock:
+ kfree(buf);
+}
+
+/* Send new BSSID to userspace */
+static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
+{
+ struct net_device *dev = priv->ndev;
+ struct hermes *hw = &priv->hw;
+ union iwreq_data wrqu;
+ int err;
+
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
+ ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
+ if (err != 0)
+ return;
+
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+
+ /* Send event to user space */
+ wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+}
+
+static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
+{
+ struct net_device *dev = priv->ndev;
+ struct hermes *hw = &priv->hw;
+ union iwreq_data wrqu;
+ int err;
+ u8 buf[88];
+ u8 *ie;
+
+ if (!priv->has_wpa)
+ return;
+
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
+ sizeof(buf), NULL, &buf);
+ if (err != 0)
+ return;
+
+ ie = orinoco_get_wpa_ie(buf, sizeof(buf));
+ if (ie) {
+ int rem = sizeof(buf) - (ie - &buf[0]);
+ wrqu.data.length = ie[1] + 2;
+ if (wrqu.data.length > rem)
+ wrqu.data.length = rem;
+
+ if (wrqu.data.length)
+ /* Send event to user space */
+ wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, ie);
+ }
+}
+
+static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
+{
+ struct net_device *dev = priv->ndev;
+ struct hermes *hw = &priv->hw;
+ union iwreq_data wrqu;
+ int err;
+ u8 buf[88]; /* TODO: verify max size or IW_GENERIC_IE_MAX */
+ u8 *ie;
+
+ if (!priv->has_wpa)
+ return;
+
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
+ sizeof(buf), NULL, &buf);
+ if (err != 0)
+ return;
+
+ ie = orinoco_get_wpa_ie(buf, sizeof(buf));
+ if (ie) {
+ int rem = sizeof(buf) - (ie - &buf[0]);
+ wrqu.data.length = ie[1] + 2;
+ if (wrqu.data.length > rem)
+ wrqu.data.length = rem;
+
+ if (wrqu.data.length)
+ /* Send event to user space */
+ wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
+ }
+}
+
+static void orinoco_send_wevents(struct work_struct *work)
+{
+ struct orinoco_private *priv =
+ container_of(work, struct orinoco_private, wevent_work);
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return;
+
+ orinoco_send_assocreqie_wevent(priv);
+ orinoco_send_assocrespie_wevent(priv);
+ orinoco_send_bssid_wevent(priv);
+
+ orinoco_unlock(priv, &flags);
+}
+
+static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ u16 infofid;
+ struct {
+ __le16 len;
+ __le16 type;
+ } __attribute__ ((packed)) info;
+ int len, type;
+ int err;
+
+ /* This is an answer to an INQUIRE command that we did earlier,
+ * or an information "event" generated by the card
+ * The controller return to us a pseudo frame containing
+ * the information in question - Jean II */
+ infofid = hermes_read_regn(hw, INFOFID);
+
+ /* Read the info frame header - don't try too hard */
+ err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
+ infofid, 0);
+ if (err) {
+ printk(KERN_ERR "%s: error %d reading info frame. "
+ "Frame dropped.\n", dev->name, err);
+ return;
+ }
+
+ len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
+ type = le16_to_cpu(info.type);
+
+ switch (type) {
+ case HERMES_INQ_TALLIES: {
+ struct hermes_tallies_frame tallies;
+ struct iw_statistics *wstats = &priv->wstats;
+
+ if (len > sizeof(tallies)) {
+ printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
+ dev->name, len);
+ len = sizeof(tallies);
+ }
+
+ err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
+ infofid, sizeof(info));
+ if (err)
+ break;
+
+ /* Increment our various counters */
+ /* wstats->discard.nwid - no wrong BSSID stuff */
+ wstats->discard.code +=
+ le16_to_cpu(tallies.RxWEPUndecryptable);
+ if (len == sizeof(tallies))
+ wstats->discard.code +=
+ le16_to_cpu(tallies.RxDiscards_WEPICVError) +
+ le16_to_cpu(tallies.RxDiscards_WEPExcluded);
+ wstats->discard.misc +=
+ le16_to_cpu(tallies.TxDiscardsWrongSA);
+ wstats->discard.fragment +=
+ le16_to_cpu(tallies.RxMsgInBadMsgFragments);
+ wstats->discard.retries +=
+ le16_to_cpu(tallies.TxRetryLimitExceeded);
+ /* wstats->miss.beacon - no match */
+ }
+ break;
+ case HERMES_INQ_LINKSTATUS: {
+ struct hermes_linkstatus linkstatus;
+ u16 newstatus;
+ int connected;
+
+ if (priv->iw_mode == IW_MODE_MONITOR)
+ break;
+
+ if (len != sizeof(linkstatus)) {
+ printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
+ dev->name, len);
+ break;
+ }
+
+ err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
+ infofid, sizeof(info));
+ if (err)
+ break;
+ newstatus = le16_to_cpu(linkstatus.linkstatus);
+
+ /* Symbol firmware uses "out of range" to signal that
+ * the hostscan frame can be requested. */
+ if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
+ priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
+ priv->has_hostscan && priv->scan_inprogress) {
+ hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
+ break;
+ }
+
+ connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
+ || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
+ || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
+
+ if (connected)
+ netif_carrier_on(dev);
+ else if (!ignore_disconnect)
+ netif_carrier_off(dev);
+
+ if (newstatus != priv->last_linkstatus) {
+ priv->last_linkstatus = newstatus;
+ print_linkstatus(dev, newstatus);
+ /* The info frame contains only one word which is the
+ * status (see hermes.h). The status is pretty boring
+ * in itself, that's why we export the new BSSID...
+ * Jean II */
+ schedule_work(&priv->wevent_work);
+ }
+ }
+ break;
+ case HERMES_INQ_SCAN:
+ if (!priv->scan_inprogress && priv->bssid_fixed &&
+ priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
+ schedule_work(&priv->join_work);
+ break;
+ }
+ /* fall through */
+ case HERMES_INQ_HOSTSCAN:
+ case HERMES_INQ_HOSTSCAN_SYMBOL: {
+ /* Result of a scanning. Contains information about
+ * cells in the vicinity - Jean II */
+ union iwreq_data wrqu;
+ unsigned char *buf;
+
+ /* Scan is no longer in progress */
+ priv->scan_inprogress = 0;
+
+ /* Sanity check */
+ if (len > 4096) {
+ printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
+ dev->name, len);
+ break;
+ }
+
+ /* Allocate buffer for results */
+ buf = kmalloc(len, GFP_ATOMIC);
+ if (buf == NULL)
+ /* No memory, so can't printk()... */
+ break;
+
+ /* Read scan data */
+ err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
+ infofid, sizeof(info));
+ if (err) {
+ kfree(buf);
+ break;
+ }
+
+#ifdef ORINOCO_DEBUG
+ {
+ int i;
+ printk(KERN_DEBUG "Scan result [%02X", buf[0]);
+ for (i = 1; i < (len * 2); i++)
+ printk(":%02X", buf[i]);
+ printk("]\n");
+ }
+#endif /* ORINOCO_DEBUG */
+
+ if (orinoco_process_scan_results(priv, buf, len) == 0) {
+ /* Send an empty event to user space.
+ * We don't send the received data on the event because
+ * it would require us to do complex transcoding, and
+ * we want to minimise the work done in the irq handler
+ * Use a request to extract the data - Jean II */
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+ }
+ kfree(buf);
+ }
+ break;
+ case HERMES_INQ_CHANNELINFO:
+ {
+ struct agere_ext_scan_info *bss;
+
+ if (!priv->scan_inprogress) {
+ printk(KERN_DEBUG "%s: Got chaninfo without scan, "
+ "len=%d\n", dev->name, len);
+ break;
+ }
+
+ /* An empty result indicates that the scan is complete */
+ if (len == 0) {
+ union iwreq_data wrqu;
+
+ /* Scan is no longer in progress */
+ priv->scan_inprogress = 0;
+
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+ break;
+ }
+
+ /* Sanity check */
+ else if (len > sizeof(*bss)) {
+ printk(KERN_WARNING
+ "%s: Ext scan results too large (%d bytes). "
+ "Truncating results to %zd bytes.\n",
+ dev->name, len, sizeof(*bss));
+ len = sizeof(*bss);
+ } else if (len < (offsetof(struct agere_ext_scan_info,
+ data) + 2)) {
+ /* Drop this result now so we don't have to
+ * keep checking later */
+ printk(KERN_WARNING
+ "%s: Ext scan results too short (%d bytes)\n",
+ dev->name, len);
+ break;
+ }
+
+ bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
+ if (bss == NULL)
+ break;
+
+ /* Read scan data */
+ err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
+ infofid, sizeof(info));
+ if (err) {
+ kfree(bss);
+ break;
+ }
+
+ orinoco_add_ext_scan_result(priv, bss);
+
+ kfree(bss);
+ break;
+ }
+ case HERMES_INQ_SEC_STAT_AGERE:
+ /* Security status (Agere specific) */
+ /* Ignore this frame for now */
+ if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
+ break;
+ /* fall through */
+ default:
+ printk(KERN_DEBUG "%s: Unknown information frame received: "
+ "type 0x%04x, length %d\n", dev->name, type, len);
+ /* We don't actually do anything about it */
+ break;
+ }
+}
+
+static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
+{
+ if (net_ratelimit())
+ printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
+}
+
+/********************************************************************/
+/* Internal hardware control routines */
+/********************************************************************/
+
+int __orinoco_up(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct hermes *hw = &priv->hw;
+ int err;
+
+ netif_carrier_off(dev); /* just to make sure */
+
+ err = __orinoco_program_rids(dev);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d configuring card\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Fire things up again */
+ hermes_set_irqmask(hw, ORINOCO_INTEN);
+ err = hermes_enable_port(hw, 0);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d enabling MAC port\n",
+ dev->name, err);
+ return err;
+ }
+
+ netif_start_queue(dev);
+
+ return 0;
+}
+EXPORT_SYMBOL(__orinoco_up);
+
+int __orinoco_down(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct hermes *hw = &priv->hw;
+ int err;
+
+ netif_stop_queue(dev);
+
+ if (!priv->hw_unavailable) {
+ if (!priv->broken_disableport) {
+ err = hermes_disable_port(hw, 0);
+ if (err) {
+ /* Some firmwares (e.g. Intersil 1.3.x) seem
+ * to have problems disabling the port, oh
+ * well, too bad. */
+ printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
+ dev->name, err);
+ priv->broken_disableport = 1;
+ }
+ }
+ hermes_set_irqmask(hw, 0);
+ hermes_write_regn(hw, EVACK, 0xffff);
+ }
+
+ /* firmware will have to reassociate */
+ netif_carrier_off(dev);
+ priv->last_linkstatus = 0xffff;
+
+ return 0;
+}
+EXPORT_SYMBOL(__orinoco_down);
+
+static int orinoco_allocate_fid(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct hermes *hw = &priv->hw;
+ int err;
+
+ err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+ if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
+ /* Try workaround for old Symbol firmware bug */
+ priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
+ err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+
+ printk(KERN_WARNING "%s: firmware ALLOC bug detected "
+ "(old Symbol firmware?). Work around %s\n",
+ dev->name, err ? "failed!" : "ok.");
+ }
+
+ return err;
+}
+
+int orinoco_reinit_firmware(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct hermes *hw = &priv->hw;
+ int err;
+
+ err = hermes_init(hw);
+ if (priv->do_fw_download && !err) {
+ err = orinoco_download(priv);
+ if (err)
+ priv->do_fw_download = 0;
+ }
+ if (!err)
+ err = orinoco_allocate_fid(dev);
+
+ return err;
+}
+EXPORT_SYMBOL(orinoco_reinit_firmware);
+
+int __orinoco_program_rids(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int err;
+ struct hermes_idstring idbuf;
+
+ /* Set the MAC address */
+ err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+ HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting MAC address\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Set up the link mode */
+ err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
+ priv->port_type);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting port type\n",
+ dev->name, err);
+ return err;
+ }
+ /* Set the channel/frequency */
+ if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFOWNCHANNEL,
+ priv->channel);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting channel %d\n",
+ dev->name, err, priv->channel);
+ return err;
+ }
+ }
+
+ if (priv->has_ibss) {
+ u16 createibss;
+
+ if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
+ printk(KERN_WARNING "%s: This firmware requires an "
+ "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
+ /* With wvlan_cs, in this case, we would crash.
+ * hopefully, this driver will behave better...
+ * Jean II */
+ createibss = 0;
+ } else {
+ createibss = priv->createibss;
+ }
+
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFCREATEIBSS,
+ createibss);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
+ dev->name, err);
+ return err;
+ }
+ }
+
+ /* Set the desired BSSID */
+ err = __orinoco_hw_set_wap(priv);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting AP address\n",
+ dev->name, err);
+ return err;
+ }
+ /* Set the desired ESSID */
+ idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
+ memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
+ /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
+ err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
+ HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+ &idbuf);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
+ dev->name, err);
+ return err;
+ }
+ err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
+ HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+ &idbuf);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Set the station name */
+ idbuf.len = cpu_to_le16(strlen(priv->nick));
+ memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
+ err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
+ HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
+ &idbuf);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting nickname\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Set AP density */
+ if (priv->has_sensitivity) {
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFSYSTEMSCALE,
+ priv->ap_density);
+ if (err) {
+ printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. "
+ "Disabling sensitivity control\n",
+ dev->name, err);
+
+ priv->has_sensitivity = 0;
+ }
+ }
+
+ /* Set RTS threshold */
+ err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
+ priv->rts_thresh);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Set fragmentation threshold or MWO robustness */
+ if (priv->has_mwo)
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMWOROBUST_AGERE,
+ priv->mwo_robust);
+ else
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+ priv->frag_thresh);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting fragmentation\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Set bitrate */
+ err = __orinoco_hw_set_bitrate(priv);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting bitrate\n",
+ dev->name, err);
+ return err;
+ }
+
+ /* Set power management */
+ if (priv->has_pm) {
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPMENABLED,
+ priv->pm_on);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting up PM\n",
+ dev->name, err);
+ return err;
+ }
+
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMULTICASTRECEIVE,
+ priv->pm_mcast);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting up PM\n",
+ dev->name, err);
+ return err;
+ }
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMAXSLEEPDURATION,
+ priv->pm_period);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting up PM\n",
+ dev->name, err);
+ return err;
+ }
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPMHOLDOVERDURATION,
+ priv->pm_timeout);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting up PM\n",
+ dev->name, err);
+ return err;
+ }
+ }
+
+ /* Set preamble - only for Symbol so far... */
+ if (priv->has_preamble) {
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPREAMBLE_SYMBOL,
+ priv->preamble);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d setting preamble\n",
+ dev->name, err);
+ return err;
+ }
+ }
+
+ /* Set up encryption */
+ if (priv->has_wep || priv->has_wpa) {
+ err = __orinoco_hw_setup_enc(priv);
+ if (err) {
+ printk(KERN_ERR "%s: Error %d activating encryption\n",
+ dev->name, err);
+ return err;
+ }
+ }
+
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ /* Enable monitor mode */
+ dev->type = ARPHRD_IEEE80211;
+ err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+ HERMES_TEST_MONITOR, 0, NULL);
+ } else {
+ /* Disable monitor mode */
+ dev->type = ARPHRD_ETHER;
+ err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+ HERMES_TEST_STOP, 0, NULL);
+ }
+ if (err)
+ return err;
+
+ /* Set promiscuity / multicast*/
+ priv->promiscuous = 0;
+ priv->mc_count = 0;
+
+ /* FIXME: what about netif_tx_lock */
+ __orinoco_set_multicast_list(dev);
+
+ return 0;
+}
+
+/* FIXME: return int? */
+static void
+__orinoco_set_multicast_list(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = 0;
+ int promisc, mc_count;
+
+ /* The Hermes doesn't seem to have an allmulti mode, so we go
+ * into promiscuous mode and let the upper levels deal. */
+ if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
+ (dev->mc_count > MAX_MULTICAST(priv))) {
+ promisc = 1;
+ mc_count = 0;
+ } else {
+ promisc = 0;
+ mc_count = dev->mc_count;
+ }
+
+ err = __orinoco_hw_set_multicast_list(priv, dev->mc_list, mc_count,
+ promisc);
+}
+
+/* This must be called from user context, without locks held - use
+ * schedule_work() */
+void orinoco_reset(struct work_struct *work)
+{
+ struct orinoco_private *priv =
+ container_of(work, struct orinoco_private, reset_work);
+ struct net_device *dev = priv->ndev;
+ struct hermes *hw = &priv->hw;
+ int err;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ /* When the hardware becomes available again, whatever
+ * detects that is responsible for re-initializing
+ * it. So no need for anything further */
+ return;
+
+ netif_stop_queue(dev);
+
+ /* Shut off interrupts. Depending on what state the hardware
+ * is in, this might not work, but we'll try anyway */
+ hermes_set_irqmask(hw, 0);
+ hermes_write_regn(hw, EVACK, 0xffff);
+
+ priv->hw_unavailable++;
+ priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
+ netif_carrier_off(dev);
+
+ orinoco_unlock(priv, &flags);
+
+ /* Scanning support: Cleanup of driver struct */
+ orinoco_clear_scan_results(priv, 0);
+ priv->scan_inprogress = 0;
+
+ if (priv->hard_reset) {
+ err = (*priv->hard_reset)(priv);
+ if (err) {
+ printk(KERN_ERR "%s: orinoco_reset: Error %d "
+ "performing hard reset\n", dev->name, err);
+ goto disable;
+ }
+ }
+
+ err = orinoco_reinit_firmware(dev);
+ if (err) {
+ printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
+ dev->name, err);
+ goto disable;
+ }
+
+ /* This has to be called from user context */
+ spin_lock_irq(&priv->lock);
+
+ priv->hw_unavailable--;
+
+ /* priv->open or priv->hw_unavailable might have changed while
+ * we dropped the lock */
+ if (priv->open && (!priv->hw_unavailable)) {
+ err = __orinoco_up(dev);
+ if (err) {
+ printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
+ dev->name, err);
+ } else
+ dev->trans_start = jiffies;
+ }
+
+ spin_unlock_irq(&priv->lock);
+
+ return;
+ disable:
+ hermes_set_irqmask(hw, 0);
+ netif_device_detach(dev);
+ printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
+}
+
+/********************************************************************/
+/* Interrupt handler */
+/********************************************************************/
+
+static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
+{
+ printk(KERN_DEBUG "%s: TICK\n", dev->name);
+}
+
+static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
+{
+ /* This seems to happen a fair bit under load, but ignoring it
+ seems to work fine...*/
+ printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
+ dev->name);
+}
+
+irqreturn_t orinoco_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int count = MAX_IRQLOOPS_PER_IRQ;
+ u16 evstat, events;
+ /* These are used to detect a runaway interrupt situation.
+ *
+ * If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
+ * we panic and shut down the hardware
+ */
+ /* jiffies value the last time we were called */
+ static int last_irq_jiffy; /* = 0 */
+ static int loops_this_jiffy; /* = 0 */
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0) {
+ /* If hw is unavailable - we don't know if the irq was
+ * for us or not */
+ return IRQ_HANDLED;
+ }
+
+ evstat = hermes_read_regn(hw, EVSTAT);
+ events = evstat & hw->inten;
+ if (!events) {
+ orinoco_unlock(priv, &flags);
+ return IRQ_NONE;
+ }
+
+ if (jiffies != last_irq_jiffy)
+ loops_this_jiffy = 0;
+ last_irq_jiffy = jiffies;
+
+ while (events && count--) {
+ if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
+ printk(KERN_WARNING "%s: IRQ handler is looping too "
+ "much! Resetting.\n", dev->name);
+ /* Disable interrupts for now */
+ hermes_set_irqmask(hw, 0);
+ schedule_work(&priv->reset_work);
+ break;
+ }
+
+ /* Check the card hasn't been removed */
+ if (!hermes_present(hw)) {
+ DEBUG(0, "orinoco_interrupt(): card removed\n");
+ break;
+ }
+
+ if (events & HERMES_EV_TICK)
+ __orinoco_ev_tick(dev, hw);
+ if (events & HERMES_EV_WTERR)
+ __orinoco_ev_wterr(dev, hw);
+ if (events & HERMES_EV_INFDROP)
+ __orinoco_ev_infdrop(dev, hw);
+ if (events & HERMES_EV_INFO)
+ __orinoco_ev_info(dev, hw);
+ if (events & HERMES_EV_RX)
+ __orinoco_ev_rx(dev, hw);
+ if (events & HERMES_EV_TXEXC)
+ __orinoco_ev_txexc(dev, hw);
+ if (events & HERMES_EV_TX)
+ __orinoco_ev_tx(dev, hw);
+ if (events & HERMES_EV_ALLOC)
+ __orinoco_ev_alloc(dev, hw);
+
+ hermes_write_regn(hw, EVACK, evstat);
+
+ evstat = hermes_read_regn(hw, EVSTAT);
+ events = evstat & hw->inten;
+ };
+
+ orinoco_unlock(priv, &flags);
+ return IRQ_HANDLED;
+}
+EXPORT_SYMBOL(orinoco_interrupt);
+
+/********************************************************************/
+/* Power management */
+/********************************************************************/
+#if defined(CONFIG_PM_SLEEP) && !defined(CONFIG_HERMES_CACHE_FW_ON_INIT)
+static int orinoco_pm_notifier(struct notifier_block *notifier,
+ unsigned long pm_event,
+ void *unused)
+{
+ struct orinoco_private *priv = container_of(notifier,
+ struct orinoco_private,
+ pm_notifier);
+
+ /* All we need to do is cache the firmware before suspend, and
+ * release it when we come out.
+ *
+ * Only need to do this if we're downloading firmware. */
+ if (!priv->do_fw_download)
+ return NOTIFY_DONE;
+
+ switch (pm_event) {
+ case PM_HIBERNATION_PREPARE:
+ case PM_SUSPEND_PREPARE:
+ orinoco_cache_fw(priv, 0);
+ break;
+
+ case PM_POST_RESTORE:
+ /* Restore from hibernation failed. We need to clean
+ * up in exactly the same way, so fall through. */
+ case PM_POST_HIBERNATION:
+ case PM_POST_SUSPEND:
+ orinoco_uncache_fw(priv);
+ break;
+
+ case PM_RESTORE_PREPARE:
+ default:
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static void orinoco_register_pm_notifier(struct orinoco_private *priv)
+{
+ priv->pm_notifier.notifier_call = orinoco_pm_notifier;
+ register_pm_notifier(&priv->pm_notifier);
+}
+
+static void orinoco_unregister_pm_notifier(struct orinoco_private *priv)
+{
+ unregister_pm_notifier(&priv->pm_notifier);
+}
+#else /* !PM_SLEEP || HERMES_CACHE_FW_ON_INIT */
+#define orinoco_register_pm_notifier(priv) do { } while(0)
+#define orinoco_unregister_pm_notifier(priv) do { } while(0)
+#endif
+
+/********************************************************************/
+/* Initialization */
+/********************************************************************/
+
+struct comp_id {
+ u16 id, variant, major, minor;
+} __attribute__ ((packed));
+
+static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
+{
+ if (nic_id->id < 0x8000)
+ return FIRMWARE_TYPE_AGERE;
+ else if (nic_id->id == 0x8000 && nic_id->major == 0)
+ return FIRMWARE_TYPE_SYMBOL;
+ else
+ return FIRMWARE_TYPE_INTERSIL;
+}
+
+/* Set priv->firmware type, determine firmware properties */
+static int determine_firmware(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int err;
+ struct comp_id nic_id, sta_id;
+ unsigned int firmver;
+ char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
+
+ /* Get the hardware version */
+ err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
+ if (err) {
+ printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
+ dev->name, err);
+ return err;
+ }
+
+ le16_to_cpus(&nic_id.id);
+ le16_to_cpus(&nic_id.variant);
+ le16_to_cpus(&nic_id.major);
+ le16_to_cpus(&nic_id.minor);
+ printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
+ dev->name, nic_id.id, nic_id.variant,
+ nic_id.major, nic_id.minor);
+
+ priv->firmware_type = determine_firmware_type(&nic_id);
+
+ /* Get the firmware version */
+ err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
+ if (err) {
+ printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
+ dev->name, err);
+ return err;
+ }
+
+ le16_to_cpus(&sta_id.id);
+ le16_to_cpus(&sta_id.variant);
+ le16_to_cpus(&sta_id.major);
+ le16_to_cpus(&sta_id.minor);
+ printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
+ dev->name, sta_id.id, sta_id.variant,
+ sta_id.major, sta_id.minor);
+
+ switch (sta_id.id) {
+ case 0x15:
+ printk(KERN_ERR "%s: Primary firmware is active\n",
+ dev->name);
+ return -ENODEV;
+ case 0x14b:
+ printk(KERN_ERR "%s: Tertiary firmware is active\n",
+ dev->name);
+ return -ENODEV;
+ case 0x1f: /* Intersil, Agere, Symbol Spectrum24 */
+ case 0x21: /* Symbol Spectrum24 Trilogy */
+ break;
+ default:
+ printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
+ dev->name);
+ break;
+ }
+
+ /* Default capabilities */
+ priv->has_sensitivity = 1;
+ priv->has_mwo = 0;
+ priv->has_preamble = 0;
+ priv->has_port3 = 1;
+ priv->has_ibss = 1;
+ priv->has_wep = 0;
+ priv->has_big_wep = 0;
+ priv->has_alt_txcntl = 0;
+ priv->has_ext_scan = 0;
+ priv->has_wpa = 0;
+ priv->do_fw_download = 0;
+
+ /* Determine capabilities from the firmware version */
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE:
+ /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
+ ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
+ snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+ "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
+
+ firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
+
+ priv->has_ibss = (firmver >= 0x60006);
+ priv->has_wep = (firmver >= 0x40020);
+ priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
+ Gold cards from the others? */
+ priv->has_mwo = (firmver >= 0x60000);
+ priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
+ priv->ibss_port = 1;
+ priv->has_hostscan = (firmver >= 0x8000a);
+ priv->do_fw_download = 1;
+ priv->broken_monitor = (firmver >= 0x80000);
+ priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
+ priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
+ priv->has_wpa = (firmver >= 0x9002a);
+ /* Tested with Agere firmware :
+ * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
+ * Tested CableTron firmware : 4.32 => Anton */
+ break;
+ case FIRMWARE_TYPE_SYMBOL:
+ /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
+ /* Intel MAC : 00:02:B3:* */
+ /* 3Com MAC : 00:50:DA:* */
+ memset(tmp, 0, sizeof(tmp));
+ /* Get the Symbol firmware version */
+ err = hermes_read_ltv(hw, USER_BAP,
+ HERMES_RID_SECONDARYVERSION_SYMBOL,
+ SYMBOL_MAX_VER_LEN, NULL, &tmp);
+ if (err) {
+ printk(KERN_WARNING
+ "%s: Error %d reading Symbol firmware info. "
+ "Wildly guessing capabilities...\n",
+ dev->name, err);
+ firmver = 0;
+ tmp[0] = '\0';
+ } else {
+ /* The firmware revision is a string, the format is
+ * something like : "V2.20-01".
+ * Quick and dirty parsing... - Jean II
+ */
+ firmver = ((tmp[1] - '0') << 16)
+ | ((tmp[3] - '0') << 12)
+ | ((tmp[4] - '0') << 8)
+ | ((tmp[6] - '0') << 4)
+ | (tmp[7] - '0');
+
+ tmp[SYMBOL_MAX_VER_LEN] = '\0';
+ }
+
+ snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+ "Symbol %s", tmp);
+
+ priv->has_ibss = (firmver >= 0x20000);
+ priv->has_wep = (firmver >= 0x15012);
+ priv->has_big_wep = (firmver >= 0x20000);
+ priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) ||
+ (firmver >= 0x29000 && firmver < 0x30000) ||
+ firmver >= 0x31000;
+ priv->has_preamble = (firmver >= 0x20000);
+ priv->ibss_port = 4;
+
+ /* Symbol firmware is found on various cards, but
+ * there has been no attempt to check firmware
+ * download on non-spectrum_cs based cards.
+ *
+ * Given that the Agere firmware download works
+ * differently, we should avoid doing a firmware
+ * download with the Symbol algorithm on non-spectrum
+ * cards.
+ *
+ * For now we can identify a spectrum_cs based card
+ * because it has a firmware reset function.
+ */
+ priv->do_fw_download = (priv->stop_fw != NULL);
+
+ priv->broken_disableport = (firmver == 0x25013) ||
+ (firmver >= 0x30000 && firmver <= 0x31000);
+ priv->has_hostscan = (firmver >= 0x31001) ||
+ (firmver >= 0x29057 && firmver < 0x30000);
+ /* Tested with Intel firmware : 0x20015 => Jean II */
+ /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
+ break;
+ case FIRMWARE_TYPE_INTERSIL:
+ /* D-Link, Linksys, Adtron, ZoomAir, and many others...
+ * Samsung, Compaq 100/200 and Proxim are slightly
+ * different and less well tested */
+ /* D-Link MAC : 00:40:05:* */
+ /* Addtron MAC : 00:90:D1:* */
+ snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+ "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
+ sta_id.variant);
+
+ firmver = ((unsigned long)sta_id.major << 16) |
+ ((unsigned long)sta_id.minor << 8) | sta_id.variant;
+
+ priv->has_ibss = (firmver >= 0x000700); /* FIXME */
+ priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
+ priv->has_pm = (firmver >= 0x000700);
+ priv->has_hostscan = (firmver >= 0x010301);
+
+ if (firmver >= 0x000800)
+ priv->ibss_port = 0;
+ else {
+ printk(KERN_NOTICE "%s: Intersil firmware earlier "
+ "than v0.8.x - several features not supported\n",
+ dev->name);
+ priv->ibss_port = 1;
+ }
+ break;
+ }
+ printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
+ priv->fw_name);
+
+ return 0;
+}
+
+static int orinoco_init(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ struct hermes_idstring nickbuf;
+ u16 reclen;
+ int len;
+
+ /* No need to lock, the hw_unavailable flag is already set in
+ * alloc_orinocodev() */
+ priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN;
+
+ /* Initialize the firmware */
+ err = hermes_init(hw);
+ if (err != 0) {
+ printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
+ dev->name, err);
+ goto out;
+ }
+
+ err = determine_firmware(dev);
+ if (err != 0) {
+ printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
+ dev->name);
+ goto out;
+ }
+
+ if (priv->do_fw_download) {
+#ifdef CONFIG_HERMES_CACHE_FW_ON_INIT
+ orinoco_cache_fw(priv, 0);
+#endif
+
+ err = orinoco_download(priv);
+ if (err)
+ priv->do_fw_download = 0;
+
+ /* Check firmware version again */
+ err = determine_firmware(dev);
+ if (err != 0) {
+ printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
+ dev->name);
+ goto out;
+ }
+ }
+
+ if (priv->has_port3)
+ printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n",
+ dev->name);
+ if (priv->has_ibss)
+ printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
+ dev->name);
+ if (priv->has_wep) {
+ printk(KERN_DEBUG "%s: WEP supported, %s-bit key\n", dev->name,
+ priv->has_big_wep ? "104" : "40");
+ }
+ if (priv->has_wpa) {
+ printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name);
+ if (orinoco_mic_init(priv)) {
+ printk(KERN_ERR "%s: Failed to setup MIC crypto "
+ "algorithm. Disabling WPA support\n", dev->name);
+ priv->has_wpa = 0;
+ }
+ }
+
+ /* Now we have the firmware capabilities, allocate appropiate
+ * sized scan buffers */
+ if (orinoco_bss_data_allocate(priv))
+ goto out;
+ orinoco_bss_data_init(priv);
+
+ /* Get the MAC address */
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+ ETH_ALEN, NULL, dev->dev_addr);
+ if (err) {
+ printk(KERN_WARNING "%s: failed to read MAC address!\n",
+ dev->name);
+ goto out;
+ }
+
+ printk(KERN_DEBUG "%s: MAC address %pM\n",
+ dev->name, dev->dev_addr);
+
+ /* Get the station name */
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
+ sizeof(nickbuf), &reclen, &nickbuf);
+ if (err) {
+ printk(KERN_ERR "%s: failed to read station name\n",
+ dev->name);
+ goto out;
+ }
+ if (nickbuf.len)
+ len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
+ else
+ len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
+ memcpy(priv->nick, &nickbuf.val, len);
+ priv->nick[len] = '\0';
+
+ printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
+
+ err = orinoco_allocate_fid(dev);
+ if (err) {
+ printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
+ dev->name);
+ goto out;
+ }
+
+ /* Get allowed channels */
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
+ &priv->channel_mask);
+ if (err) {
+ printk(KERN_ERR "%s: failed to read channel list!\n",
+ dev->name);
+ goto out;
+ }
+
+ /* Get initial AP density */
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
+ &priv->ap_density);
+ if (err || priv->ap_density < 1 || priv->ap_density > 3)
+ priv->has_sensitivity = 0;
+
+ /* Get initial RTS threshold */
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
+ &priv->rts_thresh);
+ if (err) {
+ printk(KERN_ERR "%s: failed to read RTS threshold!\n",
+ dev->name);
+ goto out;
+ }
+
+ /* Get initial fragmentation settings */
+ if (priv->has_mwo)
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMWOROBUST_AGERE,
+ &priv->mwo_robust);
+ else
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+ &priv->frag_thresh);
+ if (err) {
+ printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
+ dev->name);
+ goto out;
+ }
+
+ /* Power management setup */
+ if (priv->has_pm) {
+ priv->pm_on = 0;
+ priv->pm_mcast = 1;
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMAXSLEEPDURATION,
+ &priv->pm_period);
+ if (err) {
+ printk(KERN_ERR "%s: failed to read power management period!\n",
+ dev->name);
+ goto out;
+ }
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPMHOLDOVERDURATION,
+ &priv->pm_timeout);
+ if (err) {
+ printk(KERN_ERR "%s: failed to read power management timeout!\n",
+ dev->name);
+ goto out;
+ }
+ }
+
+ /* Preamble setup */
+ if (priv->has_preamble) {
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPREAMBLE_SYMBOL,
+ &priv->preamble);
+ if (err)
+ goto out;
+ }
+
+ /* Set up the default configuration */
+ priv->iw_mode = IW_MODE_INFRA;
+ /* By default use IEEE/IBSS ad-hoc mode if we have it */
+ priv->prefer_port3 = priv->has_port3 && (!priv->has_ibss);
+ set_port_type(priv);
+ priv->channel = 0; /* use firmware default */
+
+ priv->promiscuous = 0;
+ priv->encode_alg = IW_ENCODE_ALG_NONE;
+ priv->tx_key = 0;
+ priv->wpa_enabled = 0;
+ priv->tkip_cm_active = 0;
+ priv->key_mgmt = 0;
+ priv->wpa_ie_len = 0;
+ priv->wpa_ie = NULL;
+
+ /* Make the hardware available, as long as it hasn't been
+ * removed elsewhere (e.g. by PCMCIA hot unplug) */
+ spin_lock_irq(&priv->lock);
+ priv->hw_unavailable--;
+ spin_unlock_irq(&priv->lock);
+
+ printk(KERN_DEBUG "%s: ready\n", dev->name);
+
+ out:
+ return err;
+}
+
+static const struct net_device_ops orinoco_netdev_ops = {
+ .ndo_init = orinoco_init,
+ .ndo_open = orinoco_open,
+ .ndo_stop = orinoco_stop,
+ .ndo_start_xmit = orinoco_xmit,
+ .ndo_set_multicast_list = orinoco_set_multicast_list,
+ .ndo_change_mtu = orinoco_change_mtu,
+ .ndo_tx_timeout = orinoco_tx_timeout,
+ .ndo_get_stats = orinoco_get_stats,
+};
+
+struct net_device
+*alloc_orinocodev(int sizeof_card,
+ struct device *device,
+ int (*hard_reset)(struct orinoco_private *),
+ int (*stop_fw)(struct orinoco_private *, int))
+{
+ struct net_device *dev;
+ struct orinoco_private *priv;
+
+ dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
+ if (!dev)
+ return NULL;
+ priv = netdev_priv(dev);
+ priv->ndev = dev;
+ if (sizeof_card)
+ priv->card = (void *)((unsigned long)priv
+ + sizeof(struct orinoco_private));
+ else
+ priv->card = NULL;
+ priv->dev = device;
+
+ /* Setup / override net_device fields */
+ dev->netdev_ops = &orinoco_netdev_ops;
+ dev->watchdog_timeo = HZ; /* 1 second timeout */
+ dev->ethtool_ops = &orinoco_ethtool_ops;
+ dev->wireless_handlers = &orinoco_handler_def;
+#ifdef WIRELESS_SPY
+ priv->wireless_data.spy_data = &priv->spy_data;
+ dev->wireless_data = &priv->wireless_data;
+#endif
+ /* we use the default eth_mac_addr for setting the MAC addr */
+
+ /* Reserve space in skb for the SNAP header */
+ dev->hard_header_len += ENCAPS_OVERHEAD;
+
+ /* Set up default callbacks */
+ priv->hard_reset = hard_reset;
+ priv->stop_fw = stop_fw;
+
+ spin_lock_init(&priv->lock);
+ priv->open = 0;
+ priv->hw_unavailable = 1; /* orinoco_init() must clear this
+ * before anything else touches the
+ * hardware */
+ INIT_WORK(&priv->reset_work, orinoco_reset);
+ INIT_WORK(&priv->join_work, orinoco_join_ap);
+ INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
+
+ INIT_LIST_HEAD(&priv->rx_list);
+ tasklet_init(&priv->rx_tasklet, orinoco_rx_isr_tasklet,
+ (unsigned long) dev);
+
+ netif_carrier_off(dev);
+ priv->last_linkstatus = 0xffff;
+
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
+ priv->cached_pri_fw = NULL;
+ priv->cached_fw = NULL;
+#endif
+
+ /* Register PM notifiers */
+ orinoco_register_pm_notifier(priv);
+
+ return dev;
+}
+EXPORT_SYMBOL(alloc_orinocodev);
+
+void free_orinocodev(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_rx_data *rx_data, *temp;
+
+ /* If the tasklet is scheduled when we call tasklet_kill it
+ * will run one final time. However the tasklet will only
+ * drain priv->rx_list if the hw is still available. */
+ tasklet_kill(&priv->rx_tasklet);
+
+ /* Explicitly drain priv->rx_list */
+ list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
+ list_del(&rx_data->list);
+
+ dev_kfree_skb(rx_data->skb);
+ kfree(rx_data->desc);
+ kfree(rx_data);
+ }
+
+ orinoco_unregister_pm_notifier(priv);
+ orinoco_uncache_fw(priv);
+
+ priv->wpa_ie_len = 0;
+ kfree(priv->wpa_ie);
+ orinoco_mic_free(priv);
+ orinoco_bss_data_free(priv);
+ free_netdev(dev);
+}
+EXPORT_SYMBOL(free_orinocodev);
+
+static void orinoco_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
+ strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
+ strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
+ if (dev->dev.parent)
+ strncpy(info->bus_info, dev_name(dev->dev.parent),
+ sizeof(info->bus_info) - 1);
+ else
+ snprintf(info->bus_info, sizeof(info->bus_info) - 1,
+ "PCMCIA %p", priv->hw.iobase);
+}
+
+static const struct ethtool_ops orinoco_ethtool_ops = {
+ .get_drvinfo = orinoco_get_drvinfo,
+ .get_link = ethtool_op_get_link,
+};
+
+/********************************************************************/
+/* Module initialization */
+/********************************************************************/
+
+/* Can't be declared "const" or the whole __initdata section will
+ * become const */
+static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
+ " (David Gibson <hermes@gibson.dropbear.id.au>, "
+ "Pavel Roskin <proski@gnu.org>, et al)";
+
+static int __init init_orinoco(void)
+{
+ printk(KERN_DEBUG "%s\n", version);
+ return 0;
+}
+
+static void __exit exit_orinoco(void)
+{
+}
+
+module_init(init_orinoco);
+module_exit(exit_orinoco);
diff --git a/drivers/net/wireless/orinoco/main.h b/drivers/net/wireless/orinoco/main.h
new file mode 100644
index 000000000000..af2bae4fe395
--- /dev/null
+++ b/drivers/net/wireless/orinoco/main.h
@@ -0,0 +1,63 @@
+/* Exports from main to helper modules
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_MAIN_H_
+#define _ORINOCO_MAIN_H_
+
+#include <linux/ieee80211.h>
+#include "orinoco.h"
+
+/********************************************************************/
+/* Compile time configuration and compatibility stuff */
+/********************************************************************/
+
+/* We do this this way to avoid ifdefs in the actual code */
+#ifdef WIRELESS_SPY
+#define SPY_NUMBER(priv) (priv->spy_data.spy_number)
+#else
+#define SPY_NUMBER(priv) 0
+#endif /* WIRELESS_SPY */
+
+/********************************************************************/
+
+/* Export module parameter */
+extern int force_monitor;
+
+/* Forward declarations */
+struct net_device;
+struct work_struct;
+
+void set_port_type(struct orinoco_private *priv);
+int __orinoco_program_rids(struct net_device *dev);
+void orinoco_reset(struct work_struct *work);
+
+
+/* Information element helpers - find a home for these... */
+static inline u8 *orinoco_get_ie(u8 *data, size_t len,
+ enum ieee80211_eid eid)
+{
+ u8 *p = data;
+ while ((p + 2) < (data + len)) {
+ if (p[0] == eid)
+ return p;
+ p += p[1] + 2;
+ }
+ return NULL;
+}
+
+#define WPA_OUI_TYPE "\x00\x50\xF2\x01"
+#define WPA_SELECTOR_LEN 4
+static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
+{
+ u8 *p = data;
+ while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) {
+ if ((p[0] == WLAN_EID_GENERIC) &&
+ (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0))
+ return p;
+ p += p[1] + 2;
+ }
+ return NULL;
+}
+
+#endif /* _ORINOCO_MAIN_H_ */
diff --git a/drivers/net/wireless/orinoco/mic.c b/drivers/net/wireless/orinoco/mic.c
new file mode 100644
index 000000000000..c03e7f54d1b8
--- /dev/null
+++ b/drivers/net/wireless/orinoco/mic.c
@@ -0,0 +1,79 @@
+/* Orinoco MIC helpers
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/if_ether.h>
+#include <linux/scatterlist.h>
+#include <linux/crypto.h>
+
+#include "orinoco.h"
+#include "mic.h"
+
+/********************************************************************/
+/* Michael MIC crypto setup */
+/********************************************************************/
+int orinoco_mic_init(struct orinoco_private *priv)
+{
+ priv->tx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
+ if (IS_ERR(priv->tx_tfm_mic)) {
+ printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
+ "crypto API michael_mic\n");
+ priv->tx_tfm_mic = NULL;
+ return -ENOMEM;
+ }
+
+ priv->rx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
+ if (IS_ERR(priv->rx_tfm_mic)) {
+ printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
+ "crypto API michael_mic\n");
+ priv->rx_tfm_mic = NULL;
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+void orinoco_mic_free(struct orinoco_private *priv)
+{
+ if (priv->tx_tfm_mic)
+ crypto_free_hash(priv->tx_tfm_mic);
+ if (priv->rx_tfm_mic)
+ crypto_free_hash(priv->rx_tfm_mic);
+}
+
+int orinoco_mic(struct crypto_hash *tfm_michael, u8 *key,
+ u8 *da, u8 *sa, u8 priority,
+ u8 *data, size_t data_len, u8 *mic)
+{
+ struct hash_desc desc;
+ struct scatterlist sg[2];
+ u8 hdr[ETH_HLEN + 2]; /* size of header + padding */
+
+ if (tfm_michael == NULL) {
+ printk(KERN_WARNING "orinoco_mic: tfm_michael == NULL\n");
+ return -1;
+ }
+
+ /* Copy header into buffer. We need the padding on the end zeroed */
+ memcpy(&hdr[0], da, ETH_ALEN);
+ memcpy(&hdr[ETH_ALEN], sa, ETH_ALEN);
+ hdr[ETH_ALEN*2] = priority;
+ hdr[ETH_ALEN*2+1] = 0;
+ hdr[ETH_ALEN*2+2] = 0;
+ hdr[ETH_ALEN*2+3] = 0;
+
+ /* Use scatter gather to MIC header and data in one go */
+ sg_init_table(sg, 2);
+ sg_set_buf(&sg[0], hdr, sizeof(hdr));
+ sg_set_buf(&sg[1], data, data_len);
+
+ if (crypto_hash_setkey(tfm_michael, key, MIC_KEYLEN))
+ return -1;
+
+ desc.tfm = tfm_michael;
+ desc.flags = 0;
+ return crypto_hash_digest(&desc, sg, data_len + sizeof(hdr),
+ mic);
+}
diff --git a/drivers/net/wireless/orinoco/mic.h b/drivers/net/wireless/orinoco/mic.h
new file mode 100644
index 000000000000..04d05bc566d6
--- /dev/null
+++ b/drivers/net/wireless/orinoco/mic.h
@@ -0,0 +1,22 @@
+/* Orinoco MIC helpers
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_MIC_H_
+#define _ORINOCO_MIC_H_
+
+#include <linux/types.h>
+
+#define MICHAEL_MIC_LEN 8
+
+/* Forward declarations */
+struct orinoco_private;
+struct crypto_hash;
+
+int orinoco_mic_init(struct orinoco_private *priv);
+void orinoco_mic_free(struct orinoco_private *priv);
+int orinoco_mic(struct crypto_hash *tfm_michael, u8 *key,
+ u8 *da, u8 *sa, u8 priority,
+ u8 *data, size_t data_len, u8 *mic);
+
+#endif /* ORINOCO_MIC_H */
diff --git a/drivers/net/wireless/orinoco/orinoco.c b/drivers/net/wireless/orinoco/orinoco.c
deleted file mode 100644
index 067d1a9c728b..000000000000
--- a/drivers/net/wireless/orinoco/orinoco.c
+++ /dev/null
@@ -1,6159 +0,0 @@
-/* orinoco.c - (formerly known as dldwd_cs.c and orinoco_cs.c)
- *
- * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
- * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
- *
- * Current maintainers (as of 29 September 2003) are:
- * Pavel Roskin <proski AT gnu.org>
- * and David Gibson <hermes AT gibson.dropbear.id.au>
- *
- * (C) Copyright David Gibson, IBM Corporation 2001-2003.
- * Copyright (C) 2000 David Gibson, Linuxcare Australia.
- * With some help from :
- * Copyright (C) 2001 Jean Tourrilhes, HP Labs
- * Copyright (C) 2001 Benjamin Herrenschmidt
- *
- * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
- *
- * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy
- * AT fasta.fh-dortmund.de>
- * http://www.stud.fh-dortmund.de/~andy/wvlan/
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * The initial developer of the original code is David A. Hinds
- * <dahinds AT users.sourceforge.net>. Portions created by David
- * A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights
- * Reserved.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License version 2 (the "GPL"), in
- * which case the provisions of the GPL are applicable instead of the
- * above. If you wish to allow the use of your version of this file
- * only under the terms of the GPL and not to allow others to use your
- * version of this file under the MPL, indicate your decision by
- * deleting the provisions above and replace them with the notice and
- * other provisions required by the GPL. If you do not delete the
- * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL. */
-
-/*
- * TODO
- * o Handle de-encapsulation within network layer, provide 802.11
- * headers (patch from Thomas 'Dent' Mirlacher)
- * o Fix possible races in SPY handling.
- * o Disconnect wireless extensions from fundamental configuration.
- * o (maybe) Software WEP support (patch from Stano Meduna).
- * o (maybe) Use multiple Tx buffers - driver handling queue
- * rather than firmware.
- */
-
-/* Locking and synchronization:
- *
- * The basic principle is that everything is serialized through a
- * single spinlock, priv->lock. The lock is used in user, bh and irq
- * context, so when taken outside hardirq context it should always be
- * taken with interrupts disabled. The lock protects both the
- * hardware and the struct orinoco_private.
- *
- * Another flag, priv->hw_unavailable indicates that the hardware is
- * unavailable for an extended period of time (e.g. suspended, or in
- * the middle of a hard reset). This flag is protected by the
- * spinlock. All code which touches the hardware should check the
- * flag after taking the lock, and if it is set, give up on whatever
- * they are doing and drop the lock again. The orinoco_lock()
- * function handles this (it unlocks and returns -EBUSY if
- * hw_unavailable is non-zero).
- */
-
-#define DRIVER_NAME "orinoco"
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/firmware.h>
-#include <linux/suspend.h>
-#include <linux/if_arp.h>
-#include <linux/wireless.h>
-#include <linux/ieee80211.h>
-#include <net/iw_handler.h>
-
-#include <linux/scatterlist.h>
-#include <linux/crypto.h>
-
-#include "hermes_rid.h"
-#include "hermes_dld.h"
-#include "orinoco.h"
-
-/********************************************************************/
-/* Module information */
-/********************************************************************/
-
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
-MODULE_LICENSE("Dual MPL/GPL");
-
-/* Level of debugging. Used in the macros in orinoco.h */
-#ifdef ORINOCO_DEBUG
-int orinoco_debug = ORINOCO_DEBUG;
-module_param(orinoco_debug, int, 0644);
-MODULE_PARM_DESC(orinoco_debug, "Debug level");
-EXPORT_SYMBOL(orinoco_debug);
-#endif
-
-static int suppress_linkstatus; /* = 0 */
-module_param(suppress_linkstatus, bool, 0644);
-MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
-static int ignore_disconnect; /* = 0 */
-module_param(ignore_disconnect, int, 0644);
-MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
-
-static int force_monitor; /* = 0 */
-module_param(force_monitor, int, 0644);
-MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
-
-/********************************************************************/
-/* Compile time configuration and compatibility stuff */
-/********************************************************************/
-
-/* We do this this way to avoid ifdefs in the actual code */
-#ifdef WIRELESS_SPY
-#define SPY_NUMBER(priv) (priv->spy_data.spy_number)
-#else
-#define SPY_NUMBER(priv) 0
-#endif /* WIRELESS_SPY */
-
-/********************************************************************/
-/* Internal constants */
-/********************************************************************/
-
-/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
-static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
-#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2)
-
-#define ORINOCO_MIN_MTU 256
-#define ORINOCO_MAX_MTU (IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
-
-#define SYMBOL_MAX_VER_LEN (14)
-#define USER_BAP 0
-#define IRQ_BAP 1
-#define MAX_IRQLOOPS_PER_IRQ 10
-#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of
- * how many events the
- * device could
- * legitimately generate */
-#define SMALL_KEY_SIZE 5
-#define LARGE_KEY_SIZE 13
-#define TX_NICBUF_SIZE_BUG 1585 /* Bug in Symbol firmware */
-
-#define DUMMY_FID 0xFFFF
-
-/*#define MAX_MULTICAST(priv) (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
- HERMES_MAX_MULTICAST : 0)*/
-#define MAX_MULTICAST(priv) (HERMES_MAX_MULTICAST)
-
-#define ORINOCO_INTEN (HERMES_EV_RX | HERMES_EV_ALLOC \
- | HERMES_EV_TX | HERMES_EV_TXEXC \
- | HERMES_EV_WTERR | HERMES_EV_INFO \
- | HERMES_EV_INFDROP )
-
-#define MAX_RID_LEN 1024
-
-static const struct iw_handler_def orinoco_handler_def;
-static const struct ethtool_ops orinoco_ethtool_ops;
-
-/********************************************************************/
-/* Data tables */
-/********************************************************************/
-
-/* The frequency of each channel in MHz */
-static const long channel_frequency[] = {
- 2412, 2417, 2422, 2427, 2432, 2437, 2442,
- 2447, 2452, 2457, 2462, 2467, 2472, 2484
-};
-#define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
-
-/* This tables gives the actual meanings of the bitrate IDs returned
- * by the firmware. */
-static struct {
- int bitrate; /* in 100s of kilobits */
- int automatic;
- u16 agere_txratectrl;
- u16 intersil_txratectrl;
-} bitrate_table[] = {
- {110, 1, 3, 15}, /* Entry 0 is the default */
- {10, 0, 1, 1},
- {10, 1, 1, 1},
- {20, 0, 2, 2},
- {20, 1, 6, 3},
- {55, 0, 4, 4},
- {55, 1, 7, 7},
- {110, 0, 5, 8},
-};
-#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
-
-/********************************************************************/
-/* Data types */
-/********************************************************************/
-
-/* Beginning of the Tx descriptor, used in TxExc handling */
-struct hermes_txexc_data {
- struct hermes_tx_descriptor desc;
- __le16 frame_ctl;
- __le16 duration_id;
- u8 addr1[ETH_ALEN];
-} __attribute__ ((packed));
-
-/* Rx frame header except compatibility 802.3 header */
-struct hermes_rx_descriptor {
- /* Control */
- __le16 status;
- __le32 time;
- u8 silence;
- u8 signal;
- u8 rate;
- u8 rxflow;
- __le32 reserved;
-
- /* 802.11 header */
- __le16 frame_ctl;
- __le16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- __le16 seq_ctl;
- u8 addr4[ETH_ALEN];
-
- /* Data length */
- __le16 data_len;
-} __attribute__ ((packed));
-
-/********************************************************************/
-/* Function prototypes */
-/********************************************************************/
-
-static int __orinoco_program_rids(struct net_device *dev);
-static void __orinoco_set_multicast_list(struct net_device *dev);
-
-/********************************************************************/
-/* Michael MIC crypto setup */
-/********************************************************************/
-#define MICHAEL_MIC_LEN 8
-static int orinoco_mic_init(struct orinoco_private *priv)
-{
- priv->tx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
- if (IS_ERR(priv->tx_tfm_mic)) {
- printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
- "crypto API michael_mic\n");
- priv->tx_tfm_mic = NULL;
- return -ENOMEM;
- }
-
- priv->rx_tfm_mic = crypto_alloc_hash("michael_mic", 0, 0);
- if (IS_ERR(priv->rx_tfm_mic)) {
- printk(KERN_DEBUG "orinoco_mic_init: could not allocate "
- "crypto API michael_mic\n");
- priv->rx_tfm_mic = NULL;
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void orinoco_mic_free(struct orinoco_private *priv)
-{
- if (priv->tx_tfm_mic)
- crypto_free_hash(priv->tx_tfm_mic);
- if (priv->rx_tfm_mic)
- crypto_free_hash(priv->rx_tfm_mic);
-}
-
-static int michael_mic(struct crypto_hash *tfm_michael, u8 *key,
- u8 *da, u8 *sa, u8 priority,
- u8 *data, size_t data_len, u8 *mic)
-{
- struct hash_desc desc;
- struct scatterlist sg[2];
- u8 hdr[ETH_HLEN + 2]; /* size of header + padding */
-
- if (tfm_michael == NULL) {
- printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
- return -1;
- }
-
- /* Copy header into buffer. We need the padding on the end zeroed */
- memcpy(&hdr[0], da, ETH_ALEN);
- memcpy(&hdr[ETH_ALEN], sa, ETH_ALEN);
- hdr[ETH_ALEN*2] = priority;
- hdr[ETH_ALEN*2+1] = 0;
- hdr[ETH_ALEN*2+2] = 0;
- hdr[ETH_ALEN*2+3] = 0;
-
- /* Use scatter gather to MIC header and data in one go */
- sg_init_table(sg, 2);
- sg_set_buf(&sg[0], hdr, sizeof(hdr));
- sg_set_buf(&sg[1], data, data_len);
-
- if (crypto_hash_setkey(tfm_michael, key, MIC_KEYLEN))
- return -1;
-
- desc.tfm = tfm_michael;
- desc.flags = 0;
- return crypto_hash_digest(&desc, sg, data_len + sizeof(hdr),
- mic);
-}
-
-/********************************************************************/
-/* Internal helper functions */
-/********************************************************************/
-
-static inline void set_port_type(struct orinoco_private *priv)
-{
- switch (priv->iw_mode) {
- case IW_MODE_INFRA:
- priv->port_type = 1;
- priv->createibss = 0;
- break;
- case IW_MODE_ADHOC:
- if (priv->prefer_port3) {
- priv->port_type = 3;
- priv->createibss = 0;
- } else {
- priv->port_type = priv->ibss_port;
- priv->createibss = 1;
- }
- break;
- case IW_MODE_MONITOR:
- priv->port_type = 3;
- priv->createibss = 0;
- break;
- default:
- printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
- priv->ndev->name);
- }
-}
-
-#define ORINOCO_MAX_BSS_COUNT 64
-static int orinoco_bss_data_allocate(struct orinoco_private *priv)
-{
- if (priv->bss_xbss_data)
- return 0;
-
- if (priv->has_ext_scan)
- priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
- sizeof(struct xbss_element),
- GFP_KERNEL);
- else
- priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
- sizeof(struct bss_element),
- GFP_KERNEL);
-
- if (!priv->bss_xbss_data) {
- printk(KERN_WARNING "Out of memory allocating beacons");
- return -ENOMEM;
- }
- return 0;
-}
-
-static void orinoco_bss_data_free(struct orinoco_private *priv)
-{
- kfree(priv->bss_xbss_data);
- priv->bss_xbss_data = NULL;
-}
-
-#define PRIV_BSS ((struct bss_element *)priv->bss_xbss_data)
-#define PRIV_XBSS ((struct xbss_element *)priv->bss_xbss_data)
-static void orinoco_bss_data_init(struct orinoco_private *priv)
-{
- int i;
-
- INIT_LIST_HEAD(&priv->bss_free_list);
- INIT_LIST_HEAD(&priv->bss_list);
- if (priv->has_ext_scan)
- for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
- list_add_tail(&(PRIV_XBSS[i].list),
- &priv->bss_free_list);
- else
- for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
- list_add_tail(&(PRIV_BSS[i].list),
- &priv->bss_free_list);
-
-}
-
-static inline u8 *orinoco_get_ie(u8 *data, size_t len,
- enum ieee80211_eid eid)
-{
- u8 *p = data;
- while ((p + 2) < (data + len)) {
- if (p[0] == eid)
- return p;
- p += p[1] + 2;
- }
- return NULL;
-}
-
-#define WPA_OUI_TYPE "\x00\x50\xF2\x01"
-#define WPA_SELECTOR_LEN 4
-static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
-{
- u8 *p = data;
- while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) {
- if ((p[0] == WLAN_EID_GENERIC) &&
- (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0))
- return p;
- p += p[1] + 2;
- }
- return NULL;
-}
-
-
-/********************************************************************/
-/* Download functionality */
-/********************************************************************/
-
-struct fw_info {
- char *pri_fw;
- char *sta_fw;
- char *ap_fw;
- u32 pda_addr;
- u16 pda_size;
-};
-
-const static struct fw_info orinoco_fw[] = {
- { NULL, "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
- { NULL, "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
- { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", NULL, 0x00003100, 512 }
-};
-
-/* Structure used to access fields in FW
- * Make sure LE decoding macros are used
- */
-struct orinoco_fw_header {
- char hdr_vers[6]; /* ASCII string for header version */
- __le16 headersize; /* Total length of header */
- __le32 entry_point; /* NIC entry point */
- __le32 blocks; /* Number of blocks to program */
- __le32 block_offset; /* Offset of block data from eof header */
- __le32 pdr_offset; /* Offset to PDR data from eof header */
- __le32 pri_offset; /* Offset to primary plug data */
- __le32 compat_offset; /* Offset to compatibility data*/
- char signature[0]; /* FW signature length headersize-20 */
-} __attribute__ ((packed));
-
-/* Download either STA or AP firmware into the card. */
-static int
-orinoco_dl_firmware(struct orinoco_private *priv,
- const struct fw_info *fw,
- int ap)
-{
- /* Plug Data Area (PDA) */
- __le16 *pda;
-
- hermes_t *hw = &priv->hw;
- const struct firmware *fw_entry;
- const struct orinoco_fw_header *hdr;
- const unsigned char *first_block;
- const unsigned char *end;
- const char *firmware;
- struct net_device *dev = priv->ndev;
- int err = 0;
-
- pda = kzalloc(fw->pda_size, GFP_KERNEL);
- if (!pda)
- return -ENOMEM;
-
- if (ap)
- firmware = fw->ap_fw;
- else
- firmware = fw->sta_fw;
-
- printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
- dev->name, firmware);
-
- /* Read current plug data */
- err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
- printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
- if (err)
- goto free;
-
- if (!priv->cached_fw) {
- err = request_firmware(&fw_entry, firmware, priv->dev);
-
- if (err) {
- printk(KERN_ERR "%s: Cannot find firmware %s\n",
- dev->name, firmware);
- err = -ENOENT;
- goto free;
- }
- } else
- fw_entry = priv->cached_fw;
-
- hdr = (const struct orinoco_fw_header *) fw_entry->data;
-
- /* Enable aux port to allow programming */
- err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
- printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
- if (err != 0)
- goto abort;
-
- /* Program data */
- first_block = (fw_entry->data +
- le16_to_cpu(hdr->headersize) +
- le32_to_cpu(hdr->block_offset));
- end = fw_entry->data + fw_entry->size;
-
- err = hermes_program(hw, first_block, end);
- printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
- if (err != 0)
- goto abort;
-
- /* Update production data */
- first_block = (fw_entry->data +
- le16_to_cpu(hdr->headersize) +
- le32_to_cpu(hdr->pdr_offset));
-
- err = hermes_apply_pda_with_defaults(hw, first_block, pda);
- printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
- if (err)
- goto abort;
-
- /* Tell card we've finished */
- err = hermesi_program_end(hw);
- printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
- if (err != 0)
- goto abort;
-
- /* Check if we're running */
- printk(KERN_DEBUG "%s: hermes_present returned %d\n",
- dev->name, hermes_present(hw));
-
-abort:
- /* If we requested the firmware, release it. */
- if (!priv->cached_fw)
- release_firmware(fw_entry);
-
-free:
- kfree(pda);
- return err;
-}
-
-/* End markers */
-#define TEXT_END 0x1A /* End of text header */
-
-/*
- * Process a firmware image - stop the card, load the firmware, reset
- * the card and make sure it responds. For the secondary firmware take
- * care of the PDA - read it and then write it on top of the firmware.
- */
-static int
-symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
- const unsigned char *image, const unsigned char *end,
- int secondary)
-{
- hermes_t *hw = &priv->hw;
- int ret = 0;
- const unsigned char *ptr;
- const unsigned char *first_block;
-
- /* Plug Data Area (PDA) */
- __le16 *pda = NULL;
-
- /* Binary block begins after the 0x1A marker */
- ptr = image;
- while (*ptr++ != TEXT_END);
- first_block = ptr;
-
- /* Read the PDA from EEPROM */
- if (secondary) {
- pda = kzalloc(fw->pda_size, GFP_KERNEL);
- if (!pda)
- return -ENOMEM;
-
- ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
- if (ret)
- goto free;
- }
-
- /* Stop the firmware, so that it can be safely rewritten */
- if (priv->stop_fw) {
- ret = priv->stop_fw(priv, 1);
- if (ret)
- goto free;
- }
-
- /* Program the adapter with new firmware */
- ret = hermes_program(hw, first_block, end);
- if (ret)
- goto free;
-
- /* Write the PDA to the adapter */
- if (secondary) {
- size_t len = hermes_blocks_length(first_block);
- ptr = first_block + len;
- ret = hermes_apply_pda(hw, ptr, pda);
- kfree(pda);
- if (ret)
- return ret;
- }
-
- /* Run the firmware */
- if (priv->stop_fw) {
- ret = priv->stop_fw(priv, 0);
- if (ret)
- return ret;
- }
-
- /* Reset hermes chip and make sure it responds */
- ret = hermes_init(hw);
-
- /* hermes_reset() should return 0 with the secondary firmware */
- if (secondary && ret != 0)
- return -ENODEV;
-
- /* And this should work with any firmware */
- if (!hermes_present(hw))
- return -ENODEV;
-
- return 0;
-
-free:
- kfree(pda);
- return ret;
-}
-
-
-/*
- * Download the firmware into the card, this also does a PCMCIA soft
- * reset on the card, to make sure it's in a sane state.
- */
-static int
-symbol_dl_firmware(struct orinoco_private *priv,
- const struct fw_info *fw)
-{
- struct net_device *dev = priv->ndev;
- int ret;
- const struct firmware *fw_entry;
-
- if (!priv->cached_pri_fw) {
- if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
- printk(KERN_ERR "%s: Cannot find firmware: %s\n",
- dev->name, fw->pri_fw);
- return -ENOENT;
- }
- } else
- fw_entry = priv->cached_pri_fw;
-
- /* Load primary firmware */
- ret = symbol_dl_image(priv, fw, fw_entry->data,
- fw_entry->data + fw_entry->size, 0);
-
- if (!priv->cached_pri_fw)
- release_firmware(fw_entry);
- if (ret) {
- printk(KERN_ERR "%s: Primary firmware download failed\n",
- dev->name);
- return ret;
- }
-
- if (!priv->cached_fw) {
- if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
- printk(KERN_ERR "%s: Cannot find firmware: %s\n",
- dev->name, fw->sta_fw);
- return -ENOENT;
- }
- } else
- fw_entry = priv->cached_fw;
-
- /* Load secondary firmware */
- ret = symbol_dl_image(priv, fw, fw_entry->data,
- fw_entry->data + fw_entry->size, 1);
- if (!priv->cached_fw)
- release_firmware(fw_entry);
- if (ret) {
- printk(KERN_ERR "%s: Secondary firmware download failed\n",
- dev->name);
- }
-
- return ret;
-}
-
-static int orinoco_download(struct orinoco_private *priv)
-{
- int err = 0;
- /* Reload firmware */
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE:
- /* case FIRMWARE_TYPE_INTERSIL: */
- err = orinoco_dl_firmware(priv,
- &orinoco_fw[priv->firmware_type], 0);
- break;
-
- case FIRMWARE_TYPE_SYMBOL:
- err = symbol_dl_firmware(priv,
- &orinoco_fw[priv->firmware_type]);
- break;
- case FIRMWARE_TYPE_INTERSIL:
- break;
- }
- /* TODO: if we fail we probably need to reinitialise
- * the driver */
-
- return err;
-}
-
-#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
-static void orinoco_cache_fw(struct orinoco_private *priv, int ap)
-{
- const struct firmware *fw_entry = NULL;
- const char *pri_fw;
- const char *fw;
-
- pri_fw = orinoco_fw[priv->firmware_type].pri_fw;
- if (ap)
- fw = orinoco_fw[priv->firmware_type].ap_fw;
- else
- fw = orinoco_fw[priv->firmware_type].sta_fw;
-
- if (pri_fw) {
- if (request_firmware(&fw_entry, pri_fw, priv->dev) == 0)
- priv->cached_pri_fw = fw_entry;
- }
-
- if (fw) {
- if (request_firmware(&fw_entry, fw, priv->dev) == 0)
- priv->cached_fw = fw_entry;
- }
-}
-
-static void orinoco_uncache_fw(struct orinoco_private *priv)
-{
- if (priv->cached_pri_fw)
- release_firmware(priv->cached_pri_fw);
- if (priv->cached_fw)
- release_firmware(priv->cached_fw);
-
- priv->cached_pri_fw = NULL;
- priv->cached_fw = NULL;
-}
-#else
-#define orinoco_cache_fw(priv, ap)
-#define orinoco_uncache_fw(priv)
-#endif
-
-/********************************************************************/
-/* Device methods */
-/********************************************************************/
-
-static int orinoco_open(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int err;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = __orinoco_up(dev);
-
- if (! err)
- priv->open = 1;
-
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_stop(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = 0;
-
- /* We mustn't use orinoco_lock() here, because we need to be
- able to close the interface even if hw_unavailable is set
- (e.g. as we're released after a PC Card removal) */
- spin_lock_irq(&priv->lock);
-
- priv->open = 0;
-
- err = __orinoco_down(dev);
-
- spin_unlock_irq(&priv->lock);
-
- return err;
-}
-
-static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- return &priv->stats;
-}
-
-static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- struct iw_statistics *wstats = &priv->wstats;
- int err;
- unsigned long flags;
-
- if (! netif_device_present(dev)) {
- printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
- dev->name);
- return NULL; /* FIXME: Can we do better than this? */
- }
-
- /* If busy, return the old stats. Returning NULL may cause
- * the interface to disappear from /proc/net/wireless */
- if (orinoco_lock(priv, &flags) != 0)
- return wstats;
-
- /* We can't really wait for the tallies inquiry command to
- * complete, so we just use the previous results and trigger
- * a new tallies inquiry command for next time - Jean II */
- /* FIXME: Really we should wait for the inquiry to come back -
- * as it is the stats we give don't make a whole lot of sense.
- * Unfortunately, it's not clear how to do that within the
- * wireless extensions framework: I think we're in user
- * context, but a lock seems to be held by the time we get in
- * here so we're not safe to sleep here. */
- hermes_inquire(hw, HERMES_INQ_TALLIES);
-
- if (priv->iw_mode == IW_MODE_ADHOC) {
- memset(&wstats->qual, 0, sizeof(wstats->qual));
- /* If a spy address is defined, we report stats of the
- * first spy address - Jean II */
- if (SPY_NUMBER(priv)) {
- wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
- wstats->qual.level = priv->spy_data.spy_stat[0].level;
- wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
- wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
- }
- } else {
- struct {
- __le16 qual, signal, noise, unused;
- } __attribute__ ((packed)) cq;
-
- err = HERMES_READ_RECORD(hw, USER_BAP,
- HERMES_RID_COMMSQUALITY, &cq);
-
- if (!err) {
- wstats->qual.qual = (int)le16_to_cpu(cq.qual);
- wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
- wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
- wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
- }
- }
-
- orinoco_unlock(priv, &flags);
- return wstats;
-}
-
-static void orinoco_set_multicast_list(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0) {
- printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
- "called when hw_unavailable\n", dev->name);
- return;
- }
-
- __orinoco_set_multicast_list(dev);
- orinoco_unlock(priv, &flags);
-}
-
-static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
- return -EINVAL;
-
- /* MTU + encapsulation + header length */
- if ( (new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) >
- (priv->nicbuf_size - ETH_HLEN) )
- return -EINVAL;
-
- dev->mtu = new_mtu;
-
- return 0;
-}
-
-/********************************************************************/
-/* Tx path */
-/********************************************************************/
-
-static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
- hermes_t *hw = &priv->hw;
- int err = 0;
- u16 txfid = priv->txfid;
- struct ethhdr *eh;
- int tx_control;
- unsigned long flags;
-
- if (! netif_running(dev)) {
- printk(KERN_ERR "%s: Tx on stopped device!\n",
- dev->name);
- return NETDEV_TX_BUSY;
- }
-
- if (netif_queue_stopped(dev)) {
- printk(KERN_DEBUG "%s: Tx while transmitter busy!\n",
- dev->name);
- return NETDEV_TX_BUSY;
- }
-
- if (orinoco_lock(priv, &flags) != 0) {
- printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
- dev->name);
- return NETDEV_TX_BUSY;
- }
-
- if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
- /* Oops, the firmware hasn't established a connection,
- silently drop the packet (this seems to be the
- safest approach). */
- goto drop;
- }
-
- /* Check packet length */
- if (skb->len < ETH_HLEN)
- goto drop;
-
- tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
-
- if (priv->encode_alg == IW_ENCODE_ALG_TKIP)
- tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
- HERMES_TXCTRL_MIC;
-
- if (priv->has_alt_txcntl) {
- /* WPA enabled firmwares have tx_cntl at the end of
- * the 802.11 header. So write zeroed descriptor and
- * 802.11 header at the same time
- */
- char desc[HERMES_802_3_OFFSET];
- __le16 *txcntl = (__le16 *) &desc[HERMES_TXCNTL2_OFFSET];
-
- memset(&desc, 0, sizeof(desc));
-
- *txcntl = cpu_to_le16(tx_control);
- err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
- txfid, 0);
- if (err) {
- if (net_ratelimit())
- printk(KERN_ERR "%s: Error %d writing Tx "
- "descriptor to BAP\n", dev->name, err);
- goto busy;
- }
- } else {
- struct hermes_tx_descriptor desc;
-
- memset(&desc, 0, sizeof(desc));
-
- desc.tx_control = cpu_to_le16(tx_control);
- err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
- txfid, 0);
- if (err) {
- if (net_ratelimit())
- printk(KERN_ERR "%s: Error %d writing Tx "
- "descriptor to BAP\n", dev->name, err);
- goto busy;
- }
-
- /* Clear the 802.11 header and data length fields - some
- * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
- * if this isn't done. */
- hermes_clear_words(hw, HERMES_DATA0,
- HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
- }
-
- eh = (struct ethhdr *)skb->data;
-
- /* Encapsulate Ethernet-II frames */
- if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
- struct header_struct {
- struct ethhdr eth; /* 802.3 header */
- u8 encap[6]; /* 802.2 header */
- } __attribute__ ((packed)) hdr;
-
- /* Strip destination and source from the data */
- skb_pull(skb, 2 * ETH_ALEN);
-
- /* And move them to a separate header */
- memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
- hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
- memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
-
- /* Insert the SNAP header */
- if (skb_headroom(skb) < sizeof(hdr)) {
- printk(KERN_ERR
- "%s: Not enough headroom for 802.2 headers %d\n",
- dev->name, skb_headroom(skb));
- goto drop;
- }
- eh = (struct ethhdr *) skb_push(skb, sizeof(hdr));
- memcpy(eh, &hdr, sizeof(hdr));
- }
-
- err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
- txfid, HERMES_802_3_OFFSET);
- if (err) {
- printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
- dev->name, err);
- goto busy;
- }
-
- /* Calculate Michael MIC */
- if (priv->encode_alg == IW_ENCODE_ALG_TKIP) {
- u8 mic_buf[MICHAEL_MIC_LEN + 1];
- u8 *mic;
- size_t offset;
- size_t len;
-
- if (skb->len % 2) {
- /* MIC start is on an odd boundary */
- mic_buf[0] = skb->data[skb->len - 1];
- mic = &mic_buf[1];
- offset = skb->len - 1;
- len = MICHAEL_MIC_LEN + 1;
- } else {
- mic = &mic_buf[0];
- offset = skb->len;
- len = MICHAEL_MIC_LEN;
- }
-
- michael_mic(priv->tx_tfm_mic,
- priv->tkip_key[priv->tx_key].tx_mic,
- eh->h_dest, eh->h_source, 0 /* priority */,
- skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
-
- /* Write the MIC */
- err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
- txfid, HERMES_802_3_OFFSET + offset);
- if (err) {
- printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
- dev->name, err);
- goto busy;
- }
- }
-
- /* Finally, we actually initiate the send */
- netif_stop_queue(dev);
-
- err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
- txfid, NULL);
- if (err) {
- netif_start_queue(dev);
- if (net_ratelimit())
- printk(KERN_ERR "%s: Error %d transmitting packet\n",
- dev->name, err);
- goto busy;
- }
-
- dev->trans_start = jiffies;
- stats->tx_bytes += HERMES_802_3_OFFSET + skb->len;
- goto ok;
-
- drop:
- stats->tx_errors++;
- stats->tx_dropped++;
-
- ok:
- orinoco_unlock(priv, &flags);
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
-
- busy:
- if (err == -EIO)
- schedule_work(&priv->reset_work);
- orinoco_unlock(priv, &flags);
- return NETDEV_TX_BUSY;
-}
-
-static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- u16 fid = hermes_read_regn(hw, ALLOCFID);
-
- if (fid != priv->txfid) {
- if (fid != DUMMY_FID)
- printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
- dev->name, fid);
- return;
- }
-
- hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
-}
-
-static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
-
- stats->tx_packets++;
-
- netif_wake_queue(dev);
-
- hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
-}
-
-static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
- u16 fid = hermes_read_regn(hw, TXCOMPLFID);
- u16 status;
- struct hermes_txexc_data hdr;
- int err = 0;
-
- if (fid == DUMMY_FID)
- return; /* Nothing's really happened */
-
- /* Read part of the frame header - we need status and addr1 */
- err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
- sizeof(struct hermes_txexc_data),
- fid, 0);
-
- hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
- stats->tx_errors++;
-
- if (err) {
- printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
- "(FID=%04X error %d)\n",
- dev->name, fid, err);
- return;
- }
-
- DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
- err, fid);
-
- /* We produce a TXDROP event only for retry or lifetime
- * exceeded, because that's the only status that really mean
- * that this particular node went away.
- * Other errors means that *we* screwed up. - Jean II */
- status = le16_to_cpu(hdr.desc.status);
- if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
- union iwreq_data wrqu;
-
- /* Copy 802.11 dest address.
- * We use the 802.11 header because the frame may
- * not be 802.3 or may be mangled...
- * In Ad-Hoc mode, it will be the node address.
- * In managed mode, it will be most likely the AP addr
- * User space will figure out how to convert it to
- * whatever it needs (IP address or else).
- * - Jean II */
- memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
- wrqu.addr.sa_family = ARPHRD_ETHER;
-
- /* Send event to user space */
- wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
- }
-
- netif_wake_queue(dev);
-}
-
-static void orinoco_tx_timeout(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
- struct hermes *hw = &priv->hw;
-
- printk(KERN_WARNING "%s: Tx timeout! "
- "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
- dev->name, hermes_read_regn(hw, ALLOCFID),
- hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
-
- stats->tx_errors++;
-
- schedule_work(&priv->reset_work);
-}
-
-/********************************************************************/
-/* Rx path (data frames) */
-/********************************************************************/
-
-/* Does the frame have a SNAP header indicating it should be
- * de-encapsulated to Ethernet-II? */
-static inline int is_ethersnap(void *_hdr)
-{
- u8 *hdr = _hdr;
-
- /* We de-encapsulate all packets which, a) have SNAP headers
- * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
- * and where b) the OUI of the SNAP header is 00:00:00 or
- * 00:00:f8 - we need both because different APs appear to use
- * different OUIs for some reason */
- return (memcmp(hdr, &encaps_hdr, 5) == 0)
- && ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) );
-}
-
-static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
- int level, int noise)
-{
- struct iw_quality wstats;
- wstats.level = level - 0x95;
- wstats.noise = noise - 0x95;
- wstats.qual = (level > noise) ? (level - noise) : 0;
- wstats.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
- /* Update spy records */
- wireless_spy_update(dev, mac, &wstats);
-}
-
-static void orinoco_stat_gather(struct net_device *dev,
- struct sk_buff *skb,
- struct hermes_rx_descriptor *desc)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- /* Using spy support with lots of Rx packets, like in an
- * infrastructure (AP), will really slow down everything, because
- * the MAC address must be compared to each entry of the spy list.
- * If the user really asks for it (set some address in the
- * spy list), we do it, but he will pay the price.
- * Note that to get here, you need both WIRELESS_SPY
- * compiled in AND some addresses in the list !!!
- */
- /* Note : gcc will optimise the whole section away if
- * WIRELESS_SPY is not defined... - Jean II */
- if (SPY_NUMBER(priv)) {
- orinoco_spy_gather(dev, skb_mac_header(skb) + ETH_ALEN,
- desc->signal, desc->silence);
- }
-}
-
-/*
- * orinoco_rx_monitor - handle received monitor frames.
- *
- * Arguments:
- * dev network device
- * rxfid received FID
- * desc rx descriptor of the frame
- *
- * Call context: interrupt
- */
-static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
- struct hermes_rx_descriptor *desc)
-{
- u32 hdrlen = 30; /* return full header by default */
- u32 datalen = 0;
- u16 fc;
- int err;
- int len;
- struct sk_buff *skb;
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
- hermes_t *hw = &priv->hw;
-
- len = le16_to_cpu(desc->data_len);
-
- /* Determine the size of the header and the data */
- fc = le16_to_cpu(desc->frame_ctl);
- switch (fc & IEEE80211_FCTL_FTYPE) {
- case IEEE80211_FTYPE_DATA:
- if ((fc & IEEE80211_FCTL_TODS)
- && (fc & IEEE80211_FCTL_FROMDS))
- hdrlen = 30;
- else
- hdrlen = 24;
- datalen = len;
- break;
- case IEEE80211_FTYPE_MGMT:
- hdrlen = 24;
- datalen = len;
- break;
- case IEEE80211_FTYPE_CTL:
- switch (fc & IEEE80211_FCTL_STYPE) {
- case IEEE80211_STYPE_PSPOLL:
- case IEEE80211_STYPE_RTS:
- case IEEE80211_STYPE_CFEND:
- case IEEE80211_STYPE_CFENDACK:
- hdrlen = 16;
- break;
- case IEEE80211_STYPE_CTS:
- case IEEE80211_STYPE_ACK:
- hdrlen = 10;
- break;
- }
- break;
- default:
- /* Unknown frame type */
- break;
- }
-
- /* sanity check the length */
- if (datalen > IEEE80211_MAX_DATA_LEN + 12) {
- printk(KERN_DEBUG "%s: oversized monitor frame, "
- "data length = %d\n", dev->name, datalen);
- stats->rx_length_errors++;
- goto update_stats;
- }
-
- skb = dev_alloc_skb(hdrlen + datalen);
- if (!skb) {
- printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
- dev->name);
- goto update_stats;
- }
-
- /* Copy the 802.11 header to the skb */
- memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
- skb_reset_mac_header(skb);
-
- /* If any, copy the data from the card to the skb */
- if (datalen > 0) {
- err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
- ALIGN(datalen, 2), rxfid,
- HERMES_802_2_OFFSET);
- if (err) {
- printk(KERN_ERR "%s: error %d reading monitor frame\n",
- dev->name, err);
- goto drop;
- }
- }
-
- skb->dev = dev;
- skb->ip_summed = CHECKSUM_NONE;
- skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = __constant_htons(ETH_P_802_2);
-
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
-
- netif_rx(skb);
- return;
-
- drop:
- dev_kfree_skb_irq(skb);
- update_stats:
- stats->rx_errors++;
- stats->rx_dropped++;
-}
-
-/* Get tsc from the firmware */
-static int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key,
- u8 *tsc)
-{
- hermes_t *hw = &priv->hw;
- int err = 0;
- u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
-
- if ((key < 0) || (key > 4))
- return -EINVAL;
-
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
- sizeof(tsc_arr), NULL, &tsc_arr);
- if (!err)
- memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0]));
-
- return err;
-}
-
-static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
- struct iw_statistics *wstats = &priv->wstats;
- struct sk_buff *skb = NULL;
- u16 rxfid, status;
- int length;
- struct hermes_rx_descriptor *desc;
- struct orinoco_rx_data *rx_data;
- int err;
-
- desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
- if (!desc) {
- printk(KERN_WARNING
- "%s: Can't allocate space for RX descriptor\n",
- dev->name);
- goto update_stats;
- }
-
- rxfid = hermes_read_regn(hw, RXFID);
-
- err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc),
- rxfid, 0);
- if (err) {
- printk(KERN_ERR "%s: error %d reading Rx descriptor. "
- "Frame dropped.\n", dev->name, err);
- goto update_stats;
- }
-
- status = le16_to_cpu(desc->status);
-
- if (status & HERMES_RXSTAT_BADCRC) {
- DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
- dev->name);
- stats->rx_crc_errors++;
- goto update_stats;
- }
-
- /* Handle frames in monitor mode */
- if (priv->iw_mode == IW_MODE_MONITOR) {
- orinoco_rx_monitor(dev, rxfid, desc);
- goto out;
- }
-
- if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
- DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
- dev->name);
- wstats->discard.code++;
- goto update_stats;
- }
-
- length = le16_to_cpu(desc->data_len);
-
- /* Sanity checks */
- if (length < 3) { /* No for even an 802.2 LLC header */
- /* At least on Symbol firmware with PCF we get quite a
- lot of these legitimately - Poll frames with no
- data. */
- goto out;
- }
- if (length > IEEE80211_MAX_DATA_LEN) {
- printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
- dev->name, length);
- stats->rx_length_errors++;
- goto update_stats;
- }
-
- /* Payload size does not include Michael MIC. Increase payload
- * size to read it together with the data. */
- if (status & HERMES_RXSTAT_MIC)
- length += MICHAEL_MIC_LEN;
-
- /* We need space for the packet data itself, plus an ethernet
- header, plus 2 bytes so we can align the IP header on a
- 32bit boundary, plus 1 byte so we can read in odd length
- packets from the card, which has an IO granularity of 16
- bits */
- skb = dev_alloc_skb(length+ETH_HLEN+2+1);
- if (!skb) {
- printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
- dev->name);
- goto update_stats;
- }
-
- /* We'll prepend the header, so reserve space for it. The worst
- case is no decapsulation, when 802.3 header is prepended and
- nothing is removed. 2 is for aligning the IP header. */
- skb_reserve(skb, ETH_HLEN + 2);
-
- err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
- ALIGN(length, 2), rxfid,
- HERMES_802_2_OFFSET);
- if (err) {
- printk(KERN_ERR "%s: error %d reading frame. "
- "Frame dropped.\n", dev->name, err);
- goto drop;
- }
-
- /* Add desc and skb to rx queue */
- rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC);
- if (!rx_data) {
- printk(KERN_WARNING "%s: Can't allocate RX packet\n",
- dev->name);
- goto drop;
- }
- rx_data->desc = desc;
- rx_data->skb = skb;
- list_add_tail(&rx_data->list, &priv->rx_list);
- tasklet_schedule(&priv->rx_tasklet);
-
- return;
-
-drop:
- dev_kfree_skb_irq(skb);
-update_stats:
- stats->rx_errors++;
- stats->rx_dropped++;
-out:
- kfree(desc);
-}
-
-static void orinoco_rx(struct net_device *dev,
- struct hermes_rx_descriptor *desc,
- struct sk_buff *skb)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct net_device_stats *stats = &priv->stats;
- u16 status, fc;
- int length;
- struct ethhdr *hdr;
-
- status = le16_to_cpu(desc->status);
- length = le16_to_cpu(desc->data_len);
- fc = le16_to_cpu(desc->frame_ctl);
-
- /* Calculate and check MIC */
- if (status & HERMES_RXSTAT_MIC) {
- int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >>
- HERMES_MIC_KEY_ID_SHIFT);
- u8 mic[MICHAEL_MIC_LEN];
- u8 *rxmic;
- u8 *src = (fc & IEEE80211_FCTL_FROMDS) ?
- desc->addr3 : desc->addr2;
-
- /* Extract Michael MIC from payload */
- rxmic = skb->data + skb->len - MICHAEL_MIC_LEN;
-
- skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
- length -= MICHAEL_MIC_LEN;
-
- michael_mic(priv->rx_tfm_mic,
- priv->tkip_key[key_id].rx_mic,
- desc->addr1,
- src,
- 0, /* priority or QoS? */
- skb->data,
- skb->len,
- &mic[0]);
-
- if (memcmp(mic, rxmic,
- MICHAEL_MIC_LEN)) {
- union iwreq_data wrqu;
- struct iw_michaelmicfailure wxmic;
-
- printk(KERN_WARNING "%s: "
- "Invalid Michael MIC in data frame from %pM, "
- "using key %i\n",
- dev->name, src, key_id);
-
- /* TODO: update stats */
-
- /* Notify userspace */
- memset(&wxmic, 0, sizeof(wxmic));
- wxmic.flags = key_id & IW_MICFAILURE_KEY_ID;
- wxmic.flags |= (desc->addr1[0] & 1) ?
- IW_MICFAILURE_GROUP : IW_MICFAILURE_PAIRWISE;
- wxmic.src_addr.sa_family = ARPHRD_ETHER;
- memcpy(wxmic.src_addr.sa_data, src, ETH_ALEN);
-
- (void) orinoco_hw_get_tkip_iv(priv, key_id,
- &wxmic.tsc[0]);
-
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = sizeof(wxmic);
- wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu,
- (char *) &wxmic);
-
- goto drop;
- }
- }
-
- /* Handle decapsulation
- * In most cases, the firmware tell us about SNAP frames.
- * For some reason, the SNAP frames sent by LinkSys APs
- * are not properly recognised by most firmwares.
- * So, check ourselves */
- if (length >= ENCAPS_OVERHEAD &&
- (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
- ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
- is_ethersnap(skb->data))) {
- /* These indicate a SNAP within 802.2 LLC within
- 802.11 frame which we'll need to de-encapsulate to
- the original EthernetII frame. */
- hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN - ENCAPS_OVERHEAD);
- } else {
- /* 802.3 frame - prepend 802.3 header as is */
- hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
- hdr->h_proto = htons(length);
- }
- memcpy(hdr->h_dest, desc->addr1, ETH_ALEN);
- if (fc & IEEE80211_FCTL_FROMDS)
- memcpy(hdr->h_source, desc->addr3, ETH_ALEN);
- else
- memcpy(hdr->h_source, desc->addr2, ETH_ALEN);
-
- skb->protocol = eth_type_trans(skb, dev);
- skb->ip_summed = CHECKSUM_NONE;
- if (fc & IEEE80211_FCTL_TODS)
- skb->pkt_type = PACKET_OTHERHOST;
-
- /* Process the wireless stats if needed */
- orinoco_stat_gather(dev, skb, desc);
-
- /* Pass the packet to the networking stack */
- netif_rx(skb);
- stats->rx_packets++;
- stats->rx_bytes += length;
-
- return;
-
- drop:
- dev_kfree_skb(skb);
- stats->rx_errors++;
- stats->rx_dropped++;
-}
-
-static void orinoco_rx_isr_tasklet(unsigned long data)
-{
- struct net_device *dev = (struct net_device *) data;
- struct orinoco_private *priv = netdev_priv(dev);
- struct orinoco_rx_data *rx_data, *temp;
- struct hermes_rx_descriptor *desc;
- struct sk_buff *skb;
- unsigned long flags;
-
- /* orinoco_rx requires the driver lock, and we also need to
- * protect priv->rx_list, so just hold the lock over the
- * lot.
- *
- * If orinoco_lock fails, we've unplugged the card. In this
- * case just abort. */
- if (orinoco_lock(priv, &flags) != 0)
- return;
-
- /* extract desc and skb from queue */
- list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
- desc = rx_data->desc;
- skb = rx_data->skb;
- list_del(&rx_data->list);
- kfree(rx_data);
-
- orinoco_rx(dev, desc, skb);
-
- kfree(desc);
- }
-
- orinoco_unlock(priv, &flags);
-}
-
-/********************************************************************/
-/* Rx path (info frames) */
-/********************************************************************/
-
-static void print_linkstatus(struct net_device *dev, u16 status)
-{
- char * s;
-
- if (suppress_linkstatus)
- return;
-
- switch (status) {
- case HERMES_LINKSTATUS_NOT_CONNECTED:
- s = "Not Connected";
- break;
- case HERMES_LINKSTATUS_CONNECTED:
- s = "Connected";
- break;
- case HERMES_LINKSTATUS_DISCONNECTED:
- s = "Disconnected";
- break;
- case HERMES_LINKSTATUS_AP_CHANGE:
- s = "AP Changed";
- break;
- case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
- s = "AP Out of Range";
- break;
- case HERMES_LINKSTATUS_AP_IN_RANGE:
- s = "AP In Range";
- break;
- case HERMES_LINKSTATUS_ASSOC_FAILED:
- s = "Association Failed";
- break;
- default:
- s = "UNKNOWN";
- }
-
- printk(KERN_DEBUG "%s: New link status: %s (%04x)\n",
- dev->name, s, status);
-}
-
-/* Search scan results for requested BSSID, join it if found */
-static void orinoco_join_ap(struct work_struct *work)
-{
- struct orinoco_private *priv =
- container_of(work, struct orinoco_private, join_work);
- struct net_device *dev = priv->ndev;
- struct hermes *hw = &priv->hw;
- int err;
- unsigned long flags;
- struct join_req {
- u8 bssid[ETH_ALEN];
- __le16 channel;
- } __attribute__ ((packed)) req;
- const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
- struct prism2_scan_apinfo *atom = NULL;
- int offset = 4;
- int found = 0;
- u8 *buf;
- u16 len;
-
- /* Allocate buffer for scan results */
- buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
- if (! buf)
- return;
-
- if (orinoco_lock(priv, &flags) != 0)
- goto fail_lock;
-
- /* Sanity checks in case user changed something in the meantime */
- if (! priv->bssid_fixed)
- goto out;
-
- if (strlen(priv->desired_essid) == 0)
- goto out;
-
- /* Read scan results from the firmware */
- err = hermes_read_ltv(hw, USER_BAP,
- HERMES_RID_SCANRESULTSTABLE,
- MAX_SCAN_LEN, &len, buf);
- if (err) {
- printk(KERN_ERR "%s: Cannot read scan results\n",
- dev->name);
- goto out;
- }
-
- len = HERMES_RECLEN_TO_BYTES(len);
-
- /* Go through the scan results looking for the channel of the AP
- * we were requested to join */
- for (; offset + atom_len <= len; offset += atom_len) {
- atom = (struct prism2_scan_apinfo *) (buf + offset);
- if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
- found = 1;
- break;
- }
- }
-
- if (! found) {
- DEBUG(1, "%s: Requested AP not found in scan results\n",
- dev->name);
- goto out;
- }
-
- memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
- req.channel = atom->channel; /* both are little-endian */
- err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
- &req);
- if (err)
- printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
-
- out:
- orinoco_unlock(priv, &flags);
-
- fail_lock:
- kfree(buf);
-}
-
-/* Send new BSSID to userspace */
-static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
-{
- struct net_device *dev = priv->ndev;
- struct hermes *hw = &priv->hw;
- union iwreq_data wrqu;
- int err;
-
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
- ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
- if (err != 0)
- return;
-
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-
- /* Send event to user space */
- wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
-}
-
-static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
-{
- struct net_device *dev = priv->ndev;
- struct hermes *hw = &priv->hw;
- union iwreq_data wrqu;
- int err;
- u8 buf[88];
- u8 *ie;
-
- if (!priv->has_wpa)
- return;
-
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
- sizeof(buf), NULL, &buf);
- if (err != 0)
- return;
-
- ie = orinoco_get_wpa_ie(buf, sizeof(buf));
- if (ie) {
- int rem = sizeof(buf) - (ie - &buf[0]);
- wrqu.data.length = ie[1] + 2;
- if (wrqu.data.length > rem)
- wrqu.data.length = rem;
-
- if (wrqu.data.length)
- /* Send event to user space */
- wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, ie);
- }
-}
-
-static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
-{
- struct net_device *dev = priv->ndev;
- struct hermes *hw = &priv->hw;
- union iwreq_data wrqu;
- int err;
- u8 buf[88]; /* TODO: verify max size or IW_GENERIC_IE_MAX */
- u8 *ie;
-
- if (!priv->has_wpa)
- return;
-
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO,
- sizeof(buf), NULL, &buf);
- if (err != 0)
- return;
-
- ie = orinoco_get_wpa_ie(buf, sizeof(buf));
- if (ie) {
- int rem = sizeof(buf) - (ie - &buf[0]);
- wrqu.data.length = ie[1] + 2;
- if (wrqu.data.length > rem)
- wrqu.data.length = rem;
-
- if (wrqu.data.length)
- /* Send event to user space */
- wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, ie);
- }
-}
-
-static void orinoco_send_wevents(struct work_struct *work)
-{
- struct orinoco_private *priv =
- container_of(work, struct orinoco_private, wevent_work);
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return;
-
- orinoco_send_assocreqie_wevent(priv);
- orinoco_send_assocrespie_wevent(priv);
- orinoco_send_bssid_wevent(priv);
-
- orinoco_unlock(priv, &flags);
-}
-
-static inline void orinoco_clear_scan_results(struct orinoco_private *priv,
- unsigned long scan_age)
-{
- if (priv->has_ext_scan) {
- struct xbss_element *bss;
- struct xbss_element *tmp_bss;
-
- /* Blow away current list of scan results */
- list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
- if (!scan_age ||
- time_after(jiffies, bss->last_scanned + scan_age)) {
- list_move_tail(&bss->list,
- &priv->bss_free_list);
- /* Don't blow away ->list, just BSS data */
- memset(&bss->bss, 0, sizeof(bss->bss));
- bss->last_scanned = 0;
- }
- }
- } else {
- struct bss_element *bss;
- struct bss_element *tmp_bss;
-
- /* Blow away current list of scan results */
- list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
- if (!scan_age ||
- time_after(jiffies, bss->last_scanned + scan_age)) {
- list_move_tail(&bss->list,
- &priv->bss_free_list);
- /* Don't blow away ->list, just BSS data */
- memset(&bss->bss, 0, sizeof(bss->bss));
- bss->last_scanned = 0;
- }
- }
- }
-}
-
-static void orinoco_add_ext_scan_result(struct orinoco_private *priv,
- struct agere_ext_scan_info *atom)
-{
- struct xbss_element *bss = NULL;
- int found = 0;
-
- /* Try to update an existing bss first */
- list_for_each_entry(bss, &priv->bss_list, list) {
- if (compare_ether_addr(bss->bss.bssid, atom->bssid))
- continue;
- /* ESSID lengths */
- if (bss->bss.data[1] != atom->data[1])
- continue;
- if (memcmp(&bss->bss.data[2], &atom->data[2],
- atom->data[1]))
- continue;
- found = 1;
- break;
- }
-
- /* Grab a bss off the free list */
- if (!found && !list_empty(&priv->bss_free_list)) {
- bss = list_entry(priv->bss_free_list.next,
- struct xbss_element, list);
- list_del(priv->bss_free_list.next);
-
- list_add_tail(&bss->list, &priv->bss_list);
- }
-
- if (bss) {
- /* Always update the BSS to get latest beacon info */
- memcpy(&bss->bss, atom, sizeof(bss->bss));
- bss->last_scanned = jiffies;
- }
-}
-
-static int orinoco_process_scan_results(struct net_device *dev,
- unsigned char *buf,
- int len)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int offset; /* In the scan data */
- union hermes_scan_info *atom;
- int atom_len;
-
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE:
- atom_len = sizeof(struct agere_scan_apinfo);
- offset = 0;
- break;
- case FIRMWARE_TYPE_SYMBOL:
- /* Lack of documentation necessitates this hack.
- * Different firmwares have 68 or 76 byte long atoms.
- * We try modulo first. If the length divides by both,
- * we check what would be the channel in the second
- * frame for a 68-byte atom. 76-byte atoms have 0 there.
- * Valid channel cannot be 0. */
- if (len % 76)
- atom_len = 68;
- else if (len % 68)
- atom_len = 76;
- else if (len >= 1292 && buf[68] == 0)
- atom_len = 76;
- else
- atom_len = 68;
- offset = 0;
- break;
- case FIRMWARE_TYPE_INTERSIL:
- offset = 4;
- if (priv->has_hostscan) {
- atom_len = le16_to_cpup((__le16 *)buf);
- /* Sanity check for atom_len */
- if (atom_len < sizeof(struct prism2_scan_apinfo)) {
- printk(KERN_ERR "%s: Invalid atom_len in scan "
- "data: %d\n", dev->name, atom_len);
- return -EIO;
- }
- } else
- atom_len = offsetof(struct prism2_scan_apinfo, atim);
- break;
- default:
- return -EOPNOTSUPP;
- }
-
- /* Check that we got an whole number of atoms */
- if ((len - offset) % atom_len) {
- printk(KERN_ERR "%s: Unexpected scan data length %d, "
- "atom_len %d, offset %d\n", dev->name, len,
- atom_len, offset);
- return -EIO;
- }
-
- orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
-
- /* Read the entries one by one */
- for (; offset + atom_len <= len; offset += atom_len) {
- int found = 0;
- struct bss_element *bss = NULL;
-
- /* Get next atom */
- atom = (union hermes_scan_info *) (buf + offset);
-
- /* Try to update an existing bss first */
- list_for_each_entry(bss, &priv->bss_list, list) {
- if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
- continue;
- if (le16_to_cpu(bss->bss.a.essid_len) !=
- le16_to_cpu(atom->a.essid_len))
- continue;
- if (memcmp(bss->bss.a.essid, atom->a.essid,
- le16_to_cpu(atom->a.essid_len)))
- continue;
- found = 1;
- break;
- }
-
- /* Grab a bss off the free list */
- if (!found && !list_empty(&priv->bss_free_list)) {
- bss = list_entry(priv->bss_free_list.next,
- struct bss_element, list);
- list_del(priv->bss_free_list.next);
-
- list_add_tail(&bss->list, &priv->bss_list);
- }
-
- if (bss) {
- /* Always update the BSS to get latest beacon info */
- memcpy(&bss->bss, atom, sizeof(bss->bss));
- bss->last_scanned = jiffies;
- }
- }
-
- return 0;
-}
-
-static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- u16 infofid;
- struct {
- __le16 len;
- __le16 type;
- } __attribute__ ((packed)) info;
- int len, type;
- int err;
-
- /* This is an answer to an INQUIRE command that we did earlier,
- * or an information "event" generated by the card
- * The controller return to us a pseudo frame containing
- * the information in question - Jean II */
- infofid = hermes_read_regn(hw, INFOFID);
-
- /* Read the info frame header - don't try too hard */
- err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
- infofid, 0);
- if (err) {
- printk(KERN_ERR "%s: error %d reading info frame. "
- "Frame dropped.\n", dev->name, err);
- return;
- }
-
- len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
- type = le16_to_cpu(info.type);
-
- switch (type) {
- case HERMES_INQ_TALLIES: {
- struct hermes_tallies_frame tallies;
- struct iw_statistics *wstats = &priv->wstats;
-
- if (len > sizeof(tallies)) {
- printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
- dev->name, len);
- len = sizeof(tallies);
- }
-
- err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
- infofid, sizeof(info));
- if (err)
- break;
-
- /* Increment our various counters */
- /* wstats->discard.nwid - no wrong BSSID stuff */
- wstats->discard.code +=
- le16_to_cpu(tallies.RxWEPUndecryptable);
- if (len == sizeof(tallies))
- wstats->discard.code +=
- le16_to_cpu(tallies.RxDiscards_WEPICVError) +
- le16_to_cpu(tallies.RxDiscards_WEPExcluded);
- wstats->discard.misc +=
- le16_to_cpu(tallies.TxDiscardsWrongSA);
- wstats->discard.fragment +=
- le16_to_cpu(tallies.RxMsgInBadMsgFragments);
- wstats->discard.retries +=
- le16_to_cpu(tallies.TxRetryLimitExceeded);
- /* wstats->miss.beacon - no match */
- }
- break;
- case HERMES_INQ_LINKSTATUS: {
- struct hermes_linkstatus linkstatus;
- u16 newstatus;
- int connected;
-
- if (priv->iw_mode == IW_MODE_MONITOR)
- break;
-
- if (len != sizeof(linkstatus)) {
- printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
- dev->name, len);
- break;
- }
-
- err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
- infofid, sizeof(info));
- if (err)
- break;
- newstatus = le16_to_cpu(linkstatus.linkstatus);
-
- /* Symbol firmware uses "out of range" to signal that
- * the hostscan frame can be requested. */
- if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
- priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
- priv->has_hostscan && priv->scan_inprogress) {
- hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
- break;
- }
-
- connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
- || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
- || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
-
- if (connected)
- netif_carrier_on(dev);
- else if (!ignore_disconnect)
- netif_carrier_off(dev);
-
- if (newstatus != priv->last_linkstatus) {
- priv->last_linkstatus = newstatus;
- print_linkstatus(dev, newstatus);
- /* The info frame contains only one word which is the
- * status (see hermes.h). The status is pretty boring
- * in itself, that's why we export the new BSSID...
- * Jean II */
- schedule_work(&priv->wevent_work);
- }
- }
- break;
- case HERMES_INQ_SCAN:
- if (!priv->scan_inprogress && priv->bssid_fixed &&
- priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
- schedule_work(&priv->join_work);
- break;
- }
- /* fall through */
- case HERMES_INQ_HOSTSCAN:
- case HERMES_INQ_HOSTSCAN_SYMBOL: {
- /* Result of a scanning. Contains information about
- * cells in the vicinity - Jean II */
- union iwreq_data wrqu;
- unsigned char *buf;
-
- /* Scan is no longer in progress */
- priv->scan_inprogress = 0;
-
- /* Sanity check */
- if (len > 4096) {
- printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
- dev->name, len);
- break;
- }
-
- /* Allocate buffer for results */
- buf = kmalloc(len, GFP_ATOMIC);
- if (buf == NULL)
- /* No memory, so can't printk()... */
- break;
-
- /* Read scan data */
- err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
- infofid, sizeof(info));
- if (err) {
- kfree(buf);
- break;
- }
-
-#ifdef ORINOCO_DEBUG
- {
- int i;
- printk(KERN_DEBUG "Scan result [%02X", buf[0]);
- for(i = 1; i < (len * 2); i++)
- printk(":%02X", buf[i]);
- printk("]\n");
- }
-#endif /* ORINOCO_DEBUG */
-
- if (orinoco_process_scan_results(dev, buf, len) == 0) {
- /* Send an empty event to user space.
- * We don't send the received data on the event because
- * it would require us to do complex transcoding, and
- * we want to minimise the work done in the irq handler
- * Use a request to extract the data - Jean II */
- wrqu.data.length = 0;
- wrqu.data.flags = 0;
- wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
- }
- kfree(buf);
- }
- break;
- case HERMES_INQ_CHANNELINFO:
- {
- struct agere_ext_scan_info *bss;
-
- if (!priv->scan_inprogress) {
- printk(KERN_DEBUG "%s: Got chaninfo without scan, "
- "len=%d\n", dev->name, len);
- break;
- }
-
- /* An empty result indicates that the scan is complete */
- if (len == 0) {
- union iwreq_data wrqu;
-
- /* Scan is no longer in progress */
- priv->scan_inprogress = 0;
-
- wrqu.data.length = 0;
- wrqu.data.flags = 0;
- wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
- break;
- }
-
- /* Sanity check */
- else if (len > sizeof(*bss)) {
- printk(KERN_WARNING
- "%s: Ext scan results too large (%d bytes). "
- "Truncating results to %zd bytes.\n",
- dev->name, len, sizeof(*bss));
- len = sizeof(*bss);
- } else if (len < (offsetof(struct agere_ext_scan_info,
- data) + 2)) {
- /* Drop this result now so we don't have to
- * keep checking later */
- printk(KERN_WARNING
- "%s: Ext scan results too short (%d bytes)\n",
- dev->name, len);
- break;
- }
-
- bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
- if (bss == NULL)
- break;
-
- /* Read scan data */
- err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
- infofid, sizeof(info));
- if (err) {
- kfree(bss);
- break;
- }
-
- orinoco_add_ext_scan_result(priv, bss);
-
- kfree(bss);
- break;
- }
- case HERMES_INQ_SEC_STAT_AGERE:
- /* Security status (Agere specific) */
- /* Ignore this frame for now */
- if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
- break;
- /* fall through */
- default:
- printk(KERN_DEBUG "%s: Unknown information frame received: "
- "type 0x%04x, length %d\n", dev->name, type, len);
- /* We don't actually do anything about it */
- break;
- }
-}
-
-static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
-{
- if (net_ratelimit())
- printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
-}
-
-/********************************************************************/
-/* Internal hardware control routines */
-/********************************************************************/
-
-int __orinoco_up(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct hermes *hw = &priv->hw;
- int err;
-
- netif_carrier_off(dev); /* just to make sure */
-
- err = __orinoco_program_rids(dev);
- if (err) {
- printk(KERN_ERR "%s: Error %d configuring card\n",
- dev->name, err);
- return err;
- }
-
- /* Fire things up again */
- hermes_set_irqmask(hw, ORINOCO_INTEN);
- err = hermes_enable_port(hw, 0);
- if (err) {
- printk(KERN_ERR "%s: Error %d enabling MAC port\n",
- dev->name, err);
- return err;
- }
-
- netif_start_queue(dev);
-
- return 0;
-}
-
-int __orinoco_down(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct hermes *hw = &priv->hw;
- int err;
-
- netif_stop_queue(dev);
-
- if (! priv->hw_unavailable) {
- if (! priv->broken_disableport) {
- err = hermes_disable_port(hw, 0);
- if (err) {
- /* Some firmwares (e.g. Intersil 1.3.x) seem
- * to have problems disabling the port, oh
- * well, too bad. */
- printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
- dev->name, err);
- priv->broken_disableport = 1;
- }
- }
- hermes_set_irqmask(hw, 0);
- hermes_write_regn(hw, EVACK, 0xffff);
- }
-
- /* firmware will have to reassociate */
- netif_carrier_off(dev);
- priv->last_linkstatus = 0xffff;
-
- return 0;
-}
-
-static int orinoco_allocate_fid(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct hermes *hw = &priv->hw;
- int err;
-
- err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
- if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
- /* Try workaround for old Symbol firmware bug */
- printk(KERN_WARNING "%s: firmware ALLOC bug detected "
- "(old Symbol firmware?). Trying to work around... ",
- dev->name);
-
- priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
- err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
- if (err)
- printk("failed!\n");
- else
- printk("ok.\n");
- }
-
- return err;
-}
-
-int orinoco_reinit_firmware(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct hermes *hw = &priv->hw;
- int err;
-
- err = hermes_init(hw);
- if (priv->do_fw_download && !err) {
- err = orinoco_download(priv);
- if (err)
- priv->do_fw_download = 0;
- }
- if (!err)
- err = orinoco_allocate_fid(dev);
-
- return err;
-}
-
-static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
-{
- hermes_t *hw = &priv->hw;
- int err = 0;
-
- if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
- printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
- priv->ndev->name, priv->bitratemode);
- return -EINVAL;
- }
-
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE:
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFTXRATECONTROL,
- bitrate_table[priv->bitratemode].agere_txratectrl);
- break;
- case FIRMWARE_TYPE_INTERSIL:
- case FIRMWARE_TYPE_SYMBOL:
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFTXRATECONTROL,
- bitrate_table[priv->bitratemode].intersil_txratectrl);
- break;
- default:
- BUG();
- }
-
- return err;
-}
-
-/* Set fixed AP address */
-static int __orinoco_hw_set_wap(struct orinoco_private *priv)
-{
- int roaming_flag;
- int err = 0;
- hermes_t *hw = &priv->hw;
-
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE:
- /* not supported */
- break;
- case FIRMWARE_TYPE_INTERSIL:
- if (priv->bssid_fixed)
- roaming_flag = 2;
- else
- roaming_flag = 1;
-
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFROAMINGMODE,
- roaming_flag);
- break;
- case FIRMWARE_TYPE_SYMBOL:
- err = HERMES_WRITE_RECORD(hw, USER_BAP,
- HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
- &priv->desired_bssid);
- break;
- }
- return err;
-}
-
-/* Change the WEP keys and/or the current keys. Can be called
- * either from __orinoco_hw_setup_enc() or directly from
- * orinoco_ioctl_setiwencode(). In the later case the association
- * with the AP is not broken (if the firmware can handle it),
- * which is needed for 802.1x implementations. */
-static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
-{
- hermes_t *hw = &priv->hw;
- int err = 0;
-
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE:
- err = HERMES_WRITE_RECORD(hw, USER_BAP,
- HERMES_RID_CNFWEPKEYS_AGERE,
- &priv->keys);
- if (err)
- return err;
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFTXKEY_AGERE,
- priv->tx_key);
- if (err)
- return err;
- break;
- case FIRMWARE_TYPE_INTERSIL:
- case FIRMWARE_TYPE_SYMBOL:
- {
- int keylen;
- int i;
-
- /* Force uniform key length to work around firmware bugs */
- keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
-
- if (keylen > LARGE_KEY_SIZE) {
- printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
- priv->ndev->name, priv->tx_key, keylen);
- return -E2BIG;
- }
-
- /* Write all 4 keys */
- for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
- err = hermes_write_ltv(hw, USER_BAP,
- HERMES_RID_CNFDEFAULTKEY0 + i,
- HERMES_BYTES_TO_RECLEN(keylen),
- priv->keys[i].data);
- if (err)
- return err;
- }
-
- /* Write the index of the key used in transmission */
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFWEPDEFAULTKEYID,
- priv->tx_key);
- if (err)
- return err;
- }
- break;
- }
-
- return 0;
-}
-
-static int __orinoco_hw_setup_enc(struct orinoco_private *priv)
-{
- hermes_t *hw = &priv->hw;
- int err = 0;
- int master_wep_flag;
- int auth_flag;
- int enc_flag;
-
- /* Setup WEP keys for WEP and WPA */
- if (priv->encode_alg)
- __orinoco_hw_setup_wepkeys(priv);
-
- if (priv->wep_restrict)
- auth_flag = HERMES_AUTH_SHARED_KEY;
- else
- auth_flag = HERMES_AUTH_OPEN;
-
- if (priv->wpa_enabled)
- enc_flag = 2;
- else if (priv->encode_alg == IW_ENCODE_ALG_WEP)
- enc_flag = 1;
- else
- enc_flag = 0;
-
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
- if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
- /* Enable the shared-key authentication. */
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFAUTHENTICATION_AGERE,
- auth_flag);
- }
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFWEPENABLED_AGERE,
- enc_flag);
- if (err)
- return err;
-
- if (priv->has_wpa) {
- /* Set WPA key management */
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFSETWPAAUTHMGMTSUITE_AGERE,
- priv->key_mgmt);
- if (err)
- return err;
- }
-
- break;
-
- case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
- case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
- if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
- if (priv->wep_restrict ||
- (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
- master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
- HERMES_WEP_EXCL_UNENCRYPTED;
- else
- master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
-
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFAUTHENTICATION,
- auth_flag);
- if (err)
- return err;
- } else
- master_wep_flag = 0;
-
- if (priv->iw_mode == IW_MODE_MONITOR)
- master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
-
- /* Master WEP setting : on/off */
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFWEPFLAGS_INTERSIL,
- master_wep_flag);
- if (err)
- return err;
-
- break;
- }
-
- return 0;
-}
-
-/* key must be 32 bytes, including the tx and rx MIC keys.
- * rsc must be 8 bytes
- * tsc must be 8 bytes or NULL
- */
-static int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
- u8 *key, u8 *rsc, u8 *tsc)
-{
- struct {
- __le16 idx;
- u8 rsc[IW_ENCODE_SEQ_MAX_SIZE];
- u8 key[TKIP_KEYLEN];
- u8 tx_mic[MIC_KEYLEN];
- u8 rx_mic[MIC_KEYLEN];
- u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
- } __attribute__ ((packed)) buf;
- int ret;
- int err;
- int k;
- u16 xmitting;
-
- key_idx &= 0x3;
-
- if (set_tx)
- key_idx |= 0x8000;
-
- buf.idx = cpu_to_le16(key_idx);
- memcpy(buf.key, key,
- sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));
-
- if (rsc == NULL)
- memset(buf.rsc, 0, sizeof(buf.rsc));
- else
- memcpy(buf.rsc, rsc, sizeof(buf.rsc));
-
- if (tsc == NULL) {
- memset(buf.tsc, 0, sizeof(buf.tsc));
- buf.tsc[4] = 0x10;
- } else {
- memcpy(buf.tsc, tsc, sizeof(buf.tsc));
- }
-
- /* Wait upto 100ms for tx queue to empty */
- k = 100;
- do {
- k--;
- udelay(1000);
- ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
- &xmitting);
- if (ret)
- break;
- } while ((k > 0) && xmitting);
-
- if (k == 0)
- ret = -ETIMEDOUT;
-
- err = HERMES_WRITE_RECORD(hw, USER_BAP,
- HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE,
- &buf);
-
- return ret ? ret : err;
-}
-
-static int orinoco_clear_tkip_key(struct orinoco_private *priv,
- int key_idx)
-{
- hermes_t *hw = &priv->hw;
- int err;
-
- memset(&priv->tkip_key[key_idx], 0, sizeof(priv->tkip_key[key_idx]));
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE,
- key_idx);
- if (err)
- printk(KERN_WARNING "%s: Error %d clearing TKIP key %d\n",
- priv->ndev->name, err, key_idx);
- return err;
-}
-
-static int __orinoco_program_rids(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err;
- struct hermes_idstring idbuf;
-
- /* Set the MAC address */
- err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
- HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting MAC address\n",
- dev->name, err);
- return err;
- }
-
- /* Set up the link mode */
- err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
- priv->port_type);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting port type\n",
- dev->name, err);
- return err;
- }
- /* Set the channel/frequency */
- if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFOWNCHANNEL,
- priv->channel);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting channel %d\n",
- dev->name, err, priv->channel);
- return err;
- }
- }
-
- if (priv->has_ibss) {
- u16 createibss;
-
- if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
- printk(KERN_WARNING "%s: This firmware requires an "
- "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
- /* With wvlan_cs, in this case, we would crash.
- * hopefully, this driver will behave better...
- * Jean II */
- createibss = 0;
- } else {
- createibss = priv->createibss;
- }
-
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFCREATEIBSS,
- createibss);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
- dev->name, err);
- return err;
- }
- }
-
- /* Set the desired BSSID */
- err = __orinoco_hw_set_wap(priv);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting AP address\n",
- dev->name, err);
- return err;
- }
- /* Set the desired ESSID */
- idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
- memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
- /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
- err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
- HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
- &idbuf);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
- dev->name, err);
- return err;
- }
- err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
- HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
- &idbuf);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
- dev->name, err);
- return err;
- }
-
- /* Set the station name */
- idbuf.len = cpu_to_le16(strlen(priv->nick));
- memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
- err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
- HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
- &idbuf);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting nickname\n",
- dev->name, err);
- return err;
- }
-
- /* Set AP density */
- if (priv->has_sensitivity) {
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFSYSTEMSCALE,
- priv->ap_density);
- if (err) {
- printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. "
- "Disabling sensitivity control\n",
- dev->name, err);
-
- priv->has_sensitivity = 0;
- }
- }
-
- /* Set RTS threshold */
- err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
- priv->rts_thresh);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
- dev->name, err);
- return err;
- }
-
- /* Set fragmentation threshold or MWO robustness */
- if (priv->has_mwo)
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMWOROBUST_AGERE,
- priv->mwo_robust);
- else
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
- priv->frag_thresh);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting fragmentation\n",
- dev->name, err);
- return err;
- }
-
- /* Set bitrate */
- err = __orinoco_hw_set_bitrate(priv);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting bitrate\n",
- dev->name, err);
- return err;
- }
-
- /* Set power management */
- if (priv->has_pm) {
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFPMENABLED,
- priv->pm_on);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting up PM\n",
- dev->name, err);
- return err;
- }
-
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMULTICASTRECEIVE,
- priv->pm_mcast);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting up PM\n",
- dev->name, err);
- return err;
- }
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMAXSLEEPDURATION,
- priv->pm_period);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting up PM\n",
- dev->name, err);
- return err;
- }
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFPMHOLDOVERDURATION,
- priv->pm_timeout);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting up PM\n",
- dev->name, err);
- return err;
- }
- }
-
- /* Set preamble - only for Symbol so far... */
- if (priv->has_preamble) {
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFPREAMBLE_SYMBOL,
- priv->preamble);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting preamble\n",
- dev->name, err);
- return err;
- }
- }
-
- /* Set up encryption */
- if (priv->has_wep || priv->has_wpa) {
- err = __orinoco_hw_setup_enc(priv);
- if (err) {
- printk(KERN_ERR "%s: Error %d activating encryption\n",
- dev->name, err);
- return err;
- }
- }
-
- if (priv->iw_mode == IW_MODE_MONITOR) {
- /* Enable monitor mode */
- dev->type = ARPHRD_IEEE80211;
- err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
- HERMES_TEST_MONITOR, 0, NULL);
- } else {
- /* Disable monitor mode */
- dev->type = ARPHRD_ETHER;
- err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
- HERMES_TEST_STOP, 0, NULL);
- }
- if (err)
- return err;
-
- /* Set promiscuity / multicast*/
- priv->promiscuous = 0;
- priv->mc_count = 0;
-
- /* FIXME: what about netif_tx_lock */
- __orinoco_set_multicast_list(dev);
-
- return 0;
-}
-
-/* FIXME: return int? */
-static void
-__orinoco_set_multicast_list(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err = 0;
- int promisc, mc_count;
-
- /* The Hermes doesn't seem to have an allmulti mode, so we go
- * into promiscuous mode and let the upper levels deal. */
- if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
- (dev->mc_count > MAX_MULTICAST(priv)) ) {
- promisc = 1;
- mc_count = 0;
- } else {
- promisc = 0;
- mc_count = dev->mc_count;
- }
-
- if (promisc != priv->promiscuous) {
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFPROMISCUOUSMODE,
- promisc);
- if (err) {
- printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
- dev->name, err);
- } else
- priv->promiscuous = promisc;
- }
-
- /* If we're not in promiscuous mode, then we need to set the
- * group address if either we want to multicast, or if we were
- * multicasting and want to stop */
- if (! promisc && (mc_count || priv->mc_count) ) {
- struct dev_mc_list *p = dev->mc_list;
- struct hermes_multicast mclist;
- int i;
-
- for (i = 0; i < mc_count; i++) {
- /* paranoia: is list shorter than mc_count? */
- BUG_ON(! p);
- /* paranoia: bad address size in list? */
- BUG_ON(p->dmi_addrlen != ETH_ALEN);
-
- memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
- p = p->next;
- }
-
- if (p)
- printk(KERN_WARNING "%s: Multicast list is "
- "longer than mc_count\n", dev->name);
-
- err = hermes_write_ltv(hw, USER_BAP,
- HERMES_RID_CNFGROUPADDRESSES,
- HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
- &mclist);
- if (err)
- printk(KERN_ERR "%s: Error %d setting multicast list.\n",
- dev->name, err);
- else
- priv->mc_count = mc_count;
- }
-}
-
-/* This must be called from user context, without locks held - use
- * schedule_work() */
-static void orinoco_reset(struct work_struct *work)
-{
- struct orinoco_private *priv =
- container_of(work, struct orinoco_private, reset_work);
- struct net_device *dev = priv->ndev;
- struct hermes *hw = &priv->hw;
- int err;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- /* When the hardware becomes available again, whatever
- * detects that is responsible for re-initializing
- * it. So no need for anything further */
- return;
-
- netif_stop_queue(dev);
-
- /* Shut off interrupts. Depending on what state the hardware
- * is in, this might not work, but we'll try anyway */
- hermes_set_irqmask(hw, 0);
- hermes_write_regn(hw, EVACK, 0xffff);
-
- priv->hw_unavailable++;
- priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
- netif_carrier_off(dev);
-
- orinoco_unlock(priv, &flags);
-
- /* Scanning support: Cleanup of driver struct */
- orinoco_clear_scan_results(priv, 0);
- priv->scan_inprogress = 0;
-
- if (priv->hard_reset) {
- err = (*priv->hard_reset)(priv);
- if (err) {
- printk(KERN_ERR "%s: orinoco_reset: Error %d "
- "performing hard reset\n", dev->name, err);
- goto disable;
- }
- }
-
- err = orinoco_reinit_firmware(dev);
- if (err) {
- printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
- dev->name, err);
- goto disable;
- }
-
- spin_lock_irq(&priv->lock); /* This has to be called from user context */
-
- priv->hw_unavailable--;
-
- /* priv->open or priv->hw_unavailable might have changed while
- * we dropped the lock */
- if (priv->open && (! priv->hw_unavailable)) {
- err = __orinoco_up(dev);
- if (err) {
- printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
- dev->name, err);
- } else
- dev->trans_start = jiffies;
- }
-
- spin_unlock_irq(&priv->lock);
-
- return;
- disable:
- hermes_set_irqmask(hw, 0);
- netif_device_detach(dev);
- printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
-}
-
-/********************************************************************/
-/* Interrupt handler */
-/********************************************************************/
-
-static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
-{
- printk(KERN_DEBUG "%s: TICK\n", dev->name);
-}
-
-static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
-{
- /* This seems to happen a fair bit under load, but ignoring it
- seems to work fine...*/
- printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
- dev->name);
-}
-
-irqreturn_t orinoco_interrupt(int irq, void *dev_id)
-{
- struct net_device *dev = dev_id;
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int count = MAX_IRQLOOPS_PER_IRQ;
- u16 evstat, events;
- /* These are used to detect a runaway interrupt situation */
- /* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
- * we panic and shut down the hardware */
- static int last_irq_jiffy = 0; /* jiffies value the last time
- * we were called */
- static int loops_this_jiffy = 0;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0) {
- /* If hw is unavailable - we don't know if the irq was
- * for us or not */
- return IRQ_HANDLED;
- }
-
- evstat = hermes_read_regn(hw, EVSTAT);
- events = evstat & hw->inten;
- if (! events) {
- orinoco_unlock(priv, &flags);
- return IRQ_NONE;
- }
-
- if (jiffies != last_irq_jiffy)
- loops_this_jiffy = 0;
- last_irq_jiffy = jiffies;
-
- while (events && count--) {
- if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
- printk(KERN_WARNING "%s: IRQ handler is looping too "
- "much! Resetting.\n", dev->name);
- /* Disable interrupts for now */
- hermes_set_irqmask(hw, 0);
- schedule_work(&priv->reset_work);
- break;
- }
-
- /* Check the card hasn't been removed */
- if (! hermes_present(hw)) {
- DEBUG(0, "orinoco_interrupt(): card removed\n");
- break;
- }
-
- if (events & HERMES_EV_TICK)
- __orinoco_ev_tick(dev, hw);
- if (events & HERMES_EV_WTERR)
- __orinoco_ev_wterr(dev, hw);
- if (events & HERMES_EV_INFDROP)
- __orinoco_ev_infdrop(dev, hw);
- if (events & HERMES_EV_INFO)
- __orinoco_ev_info(dev, hw);
- if (events & HERMES_EV_RX)
- __orinoco_ev_rx(dev, hw);
- if (events & HERMES_EV_TXEXC)
- __orinoco_ev_txexc(dev, hw);
- if (events & HERMES_EV_TX)
- __orinoco_ev_tx(dev, hw);
- if (events & HERMES_EV_ALLOC)
- __orinoco_ev_alloc(dev, hw);
-
- hermes_write_regn(hw, EVACK, evstat);
-
- evstat = hermes_read_regn(hw, EVSTAT);
- events = evstat & hw->inten;
- };
-
- orinoco_unlock(priv, &flags);
- return IRQ_HANDLED;
-}
-
-/********************************************************************/
-/* Power management */
-/********************************************************************/
-#if defined(CONFIG_PM_SLEEP) && !defined(CONFIG_HERMES_CACHE_FW_ON_INIT)
-static int orinoco_pm_notifier(struct notifier_block *notifier,
- unsigned long pm_event,
- void *unused)
-{
- struct orinoco_private *priv = container_of(notifier,
- struct orinoco_private,
- pm_notifier);
-
- /* All we need to do is cache the firmware before suspend, and
- * release it when we come out.
- *
- * Only need to do this if we're downloading firmware. */
- if (!priv->do_fw_download)
- return NOTIFY_DONE;
-
- switch (pm_event) {
- case PM_HIBERNATION_PREPARE:
- case PM_SUSPEND_PREPARE:
- orinoco_cache_fw(priv, 0);
- break;
-
- case PM_POST_RESTORE:
- /* Restore from hibernation failed. We need to clean
- * up in exactly the same way, so fall through. */
- case PM_POST_HIBERNATION:
- case PM_POST_SUSPEND:
- orinoco_uncache_fw(priv);
- break;
-
- case PM_RESTORE_PREPARE:
- default:
- break;
- }
-
- return NOTIFY_DONE;
-}
-
-static void orinoco_register_pm_notifier(struct orinoco_private *priv)
-{
- priv->pm_notifier.notifier_call = orinoco_pm_notifier;
- register_pm_notifier(&priv->pm_notifier);
-}
-
-static void orinoco_unregister_pm_notifier(struct orinoco_private *priv)
-{
- unregister_pm_notifier(&priv->pm_notifier);
-}
-#else /* !PM_SLEEP || HERMES_CACHE_FW_ON_INIT */
-#define orinoco_register_pm_notifier(priv) do { } while(0)
-#define orinoco_unregister_pm_notifier(priv) do { } while(0)
-#endif
-
-/********************************************************************/
-/* Initialization */
-/********************************************************************/
-
-struct comp_id {
- u16 id, variant, major, minor;
-} __attribute__ ((packed));
-
-static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
-{
- if (nic_id->id < 0x8000)
- return FIRMWARE_TYPE_AGERE;
- else if (nic_id->id == 0x8000 && nic_id->major == 0)
- return FIRMWARE_TYPE_SYMBOL;
- else
- return FIRMWARE_TYPE_INTERSIL;
-}
-
-/* Set priv->firmware type, determine firmware properties */
-static int determine_firmware(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err;
- struct comp_id nic_id, sta_id;
- unsigned int firmver;
- char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
-
- /* Get the hardware version */
- err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
- if (err) {
- printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
- dev->name, err);
- return err;
- }
-
- le16_to_cpus(&nic_id.id);
- le16_to_cpus(&nic_id.variant);
- le16_to_cpus(&nic_id.major);
- le16_to_cpus(&nic_id.minor);
- printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
- dev->name, nic_id.id, nic_id.variant,
- nic_id.major, nic_id.minor);
-
- priv->firmware_type = determine_firmware_type(&nic_id);
-
- /* Get the firmware version */
- err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
- if (err) {
- printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
- dev->name, err);
- return err;
- }
-
- le16_to_cpus(&sta_id.id);
- le16_to_cpus(&sta_id.variant);
- le16_to_cpus(&sta_id.major);
- le16_to_cpus(&sta_id.minor);
- printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
- dev->name, sta_id.id, sta_id.variant,
- sta_id.major, sta_id.minor);
-
- switch (sta_id.id) {
- case 0x15:
- printk(KERN_ERR "%s: Primary firmware is active\n",
- dev->name);
- return -ENODEV;
- case 0x14b:
- printk(KERN_ERR "%s: Tertiary firmware is active\n",
- dev->name);
- return -ENODEV;
- case 0x1f: /* Intersil, Agere, Symbol Spectrum24 */
- case 0x21: /* Symbol Spectrum24 Trilogy */
- break;
- default:
- printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
- dev->name);
- break;
- }
-
- /* Default capabilities */
- priv->has_sensitivity = 1;
- priv->has_mwo = 0;
- priv->has_preamble = 0;
- priv->has_port3 = 1;
- priv->has_ibss = 1;
- priv->has_wep = 0;
- priv->has_big_wep = 0;
- priv->has_alt_txcntl = 0;
- priv->has_ext_scan = 0;
- priv->has_wpa = 0;
- priv->do_fw_download = 0;
-
- /* Determine capabilities from the firmware version */
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE:
- /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
- ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
- snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
- "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
-
- firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
-
- priv->has_ibss = (firmver >= 0x60006);
- priv->has_wep = (firmver >= 0x40020);
- priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
- Gold cards from the others? */
- priv->has_mwo = (firmver >= 0x60000);
- priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
- priv->ibss_port = 1;
- priv->has_hostscan = (firmver >= 0x8000a);
- priv->do_fw_download = 1;
- priv->broken_monitor = (firmver >= 0x80000);
- priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
- priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
- priv->has_wpa = (firmver >= 0x9002a);
- /* Tested with Agere firmware :
- * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
- * Tested CableTron firmware : 4.32 => Anton */
- break;
- case FIRMWARE_TYPE_SYMBOL:
- /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
- /* Intel MAC : 00:02:B3:* */
- /* 3Com MAC : 00:50:DA:* */
- memset(tmp, 0, sizeof(tmp));
- /* Get the Symbol firmware version */
- err = hermes_read_ltv(hw, USER_BAP,
- HERMES_RID_SECONDARYVERSION_SYMBOL,
- SYMBOL_MAX_VER_LEN, NULL, &tmp);
- if (err) {
- printk(KERN_WARNING
- "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
- dev->name, err);
- firmver = 0;
- tmp[0] = '\0';
- } else {
- /* The firmware revision is a string, the format is
- * something like : "V2.20-01".
- * Quick and dirty parsing... - Jean II
- */
- firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)
- | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)
- | (tmp[7] - '0');
-
- tmp[SYMBOL_MAX_VER_LEN] = '\0';
- }
-
- snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
- "Symbol %s", tmp);
-
- priv->has_ibss = (firmver >= 0x20000);
- priv->has_wep = (firmver >= 0x15012);
- priv->has_big_wep = (firmver >= 0x20000);
- priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) ||
- (firmver >= 0x29000 && firmver < 0x30000) ||
- firmver >= 0x31000;
- priv->has_preamble = (firmver >= 0x20000);
- priv->ibss_port = 4;
-
- /* Symbol firmware is found on various cards, but
- * there has been no attempt to check firmware
- * download on non-spectrum_cs based cards.
- *
- * Given that the Agere firmware download works
- * differently, we should avoid doing a firmware
- * download with the Symbol algorithm on non-spectrum
- * cards.
- *
- * For now we can identify a spectrum_cs based card
- * because it has a firmware reset function.
- */
- priv->do_fw_download = (priv->stop_fw != NULL);
-
- priv->broken_disableport = (firmver == 0x25013) ||
- (firmver >= 0x30000 && firmver <= 0x31000);
- priv->has_hostscan = (firmver >= 0x31001) ||
- (firmver >= 0x29057 && firmver < 0x30000);
- /* Tested with Intel firmware : 0x20015 => Jean II */
- /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
- break;
- case FIRMWARE_TYPE_INTERSIL:
- /* D-Link, Linksys, Adtron, ZoomAir, and many others...
- * Samsung, Compaq 100/200 and Proxim are slightly
- * different and less well tested */
- /* D-Link MAC : 00:40:05:* */
- /* Addtron MAC : 00:90:D1:* */
- snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
- "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
- sta_id.variant);
-
- firmver = ((unsigned long)sta_id.major << 16) |
- ((unsigned long)sta_id.minor << 8) | sta_id.variant;
-
- priv->has_ibss = (firmver >= 0x000700); /* FIXME */
- priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
- priv->has_pm = (firmver >= 0x000700);
- priv->has_hostscan = (firmver >= 0x010301);
-
- if (firmver >= 0x000800)
- priv->ibss_port = 0;
- else {
- printk(KERN_NOTICE "%s: Intersil firmware earlier "
- "than v0.8.x - several features not supported\n",
- dev->name);
- priv->ibss_port = 1;
- }
- break;
- }
- printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
- priv->fw_name);
-
- return 0;
-}
-
-static int orinoco_init(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err = 0;
- struct hermes_idstring nickbuf;
- u16 reclen;
- int len;
-
- /* No need to lock, the hw_unavailable flag is already set in
- * alloc_orinocodev() */
- priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN;
-
- /* Initialize the firmware */
- err = hermes_init(hw);
- if (err != 0) {
- printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
- dev->name, err);
- goto out;
- }
-
- err = determine_firmware(dev);
- if (err != 0) {
- printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
- dev->name);
- goto out;
- }
-
- if (priv->do_fw_download) {
-#ifdef CONFIG_HERMES_CACHE_FW_ON_INIT
- orinoco_cache_fw(priv, 0);
-#endif
-
- err = orinoco_download(priv);
- if (err)
- priv->do_fw_download = 0;
-
- /* Check firmware version again */
- err = determine_firmware(dev);
- if (err != 0) {
- printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
- dev->name);
- goto out;
- }
- }
-
- if (priv->has_port3)
- printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
- if (priv->has_ibss)
- printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
- dev->name);
- if (priv->has_wep) {
- printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
- if (priv->has_big_wep)
- printk("104-bit key\n");
- else
- printk("40-bit key\n");
- }
- if (priv->has_wpa) {
- printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name);
- if (orinoco_mic_init(priv)) {
- printk(KERN_ERR "%s: Failed to setup MIC crypto "
- "algorithm. Disabling WPA support\n", dev->name);
- priv->has_wpa = 0;
- }
- }
-
- /* Now we have the firmware capabilities, allocate appropiate
- * sized scan buffers */
- if (orinoco_bss_data_allocate(priv))
- goto out;
- orinoco_bss_data_init(priv);
-
- /* Get the MAC address */
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
- ETH_ALEN, NULL, dev->dev_addr);
- if (err) {
- printk(KERN_WARNING "%s: failed to read MAC address!\n",
- dev->name);
- goto out;
- }
-
- printk(KERN_DEBUG "%s: MAC address %pM\n",
- dev->name, dev->dev_addr);
-
- /* Get the station name */
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
- sizeof(nickbuf), &reclen, &nickbuf);
- if (err) {
- printk(KERN_ERR "%s: failed to read station name\n",
- dev->name);
- goto out;
- }
- if (nickbuf.len)
- len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
- else
- len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
- memcpy(priv->nick, &nickbuf.val, len);
- priv->nick[len] = '\0';
-
- printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
-
- err = orinoco_allocate_fid(dev);
- if (err) {
- printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
- dev->name);
- goto out;
- }
-
- /* Get allowed channels */
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
- &priv->channel_mask);
- if (err) {
- printk(KERN_ERR "%s: failed to read channel list!\n",
- dev->name);
- goto out;
- }
-
- /* Get initial AP density */
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
- &priv->ap_density);
- if (err || priv->ap_density < 1 || priv->ap_density > 3) {
- priv->has_sensitivity = 0;
- }
-
- /* Get initial RTS threshold */
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
- &priv->rts_thresh);
- if (err) {
- printk(KERN_ERR "%s: failed to read RTS threshold!\n",
- dev->name);
- goto out;
- }
-
- /* Get initial fragmentation settings */
- if (priv->has_mwo)
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMWOROBUST_AGERE,
- &priv->mwo_robust);
- else
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
- &priv->frag_thresh);
- if (err) {
- printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
- dev->name);
- goto out;
- }
-
- /* Power management setup */
- if (priv->has_pm) {
- priv->pm_on = 0;
- priv->pm_mcast = 1;
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMAXSLEEPDURATION,
- &priv->pm_period);
- if (err) {
- printk(KERN_ERR "%s: failed to read power management period!\n",
- dev->name);
- goto out;
- }
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFPMHOLDOVERDURATION,
- &priv->pm_timeout);
- if (err) {
- printk(KERN_ERR "%s: failed to read power management timeout!\n",
- dev->name);
- goto out;
- }
- }
-
- /* Preamble setup */
- if (priv->has_preamble) {
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFPREAMBLE_SYMBOL,
- &priv->preamble);
- if (err)
- goto out;
- }
-
- /* Set up the default configuration */
- priv->iw_mode = IW_MODE_INFRA;
- /* By default use IEEE/IBSS ad-hoc mode if we have it */
- priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
- set_port_type(priv);
- priv->channel = 0; /* use firmware default */
-
- priv->promiscuous = 0;
- priv->encode_alg = IW_ENCODE_ALG_NONE;
- priv->tx_key = 0;
- priv->wpa_enabled = 0;
- priv->tkip_cm_active = 0;
- priv->key_mgmt = 0;
- priv->wpa_ie_len = 0;
- priv->wpa_ie = NULL;
-
- /* Make the hardware available, as long as it hasn't been
- * removed elsewhere (e.g. by PCMCIA hot unplug) */
- spin_lock_irq(&priv->lock);
- priv->hw_unavailable--;
- spin_unlock_irq(&priv->lock);
-
- printk(KERN_DEBUG "%s: ready\n", dev->name);
-
- out:
- return err;
-}
-
-struct net_device
-*alloc_orinocodev(int sizeof_card,
- struct device *device,
- int (*hard_reset)(struct orinoco_private *),
- int (*stop_fw)(struct orinoco_private *, int))
-{
- struct net_device *dev;
- struct orinoco_private *priv;
-
- dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
- if (! dev)
- return NULL;
- priv = netdev_priv(dev);
- priv->ndev = dev;
- if (sizeof_card)
- priv->card = (void *)((unsigned long)priv
- + sizeof(struct orinoco_private));
- else
- priv->card = NULL;
- priv->dev = device;
-
- /* Setup / override net_device fields */
- dev->init = orinoco_init;
- dev->hard_start_xmit = orinoco_xmit;
- dev->tx_timeout = orinoco_tx_timeout;
- dev->watchdog_timeo = HZ; /* 1 second timeout */
- dev->get_stats = orinoco_get_stats;
- dev->ethtool_ops = &orinoco_ethtool_ops;
- dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
-#ifdef WIRELESS_SPY
- priv->wireless_data.spy_data = &priv->spy_data;
- dev->wireless_data = &priv->wireless_data;
-#endif
- dev->change_mtu = orinoco_change_mtu;
- dev->set_multicast_list = orinoco_set_multicast_list;
- /* we use the default eth_mac_addr for setting the MAC addr */
-
- /* Reserve space in skb for the SNAP header */
- dev->hard_header_len += ENCAPS_OVERHEAD;
-
- /* Set up default callbacks */
- dev->open = orinoco_open;
- dev->stop = orinoco_stop;
- priv->hard_reset = hard_reset;
- priv->stop_fw = stop_fw;
-
- spin_lock_init(&priv->lock);
- priv->open = 0;
- priv->hw_unavailable = 1; /* orinoco_init() must clear this
- * before anything else touches the
- * hardware */
- INIT_WORK(&priv->reset_work, orinoco_reset);
- INIT_WORK(&priv->join_work, orinoco_join_ap);
- INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
-
- INIT_LIST_HEAD(&priv->rx_list);
- tasklet_init(&priv->rx_tasklet, orinoco_rx_isr_tasklet,
- (unsigned long) dev);
-
- netif_carrier_off(dev);
- priv->last_linkstatus = 0xffff;
-
- priv->cached_pri_fw = NULL;
- priv->cached_fw = NULL;
-
- /* Register PM notifiers */
- orinoco_register_pm_notifier(priv);
-
- return dev;
-}
-
-void free_orinocodev(struct net_device *dev)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct orinoco_rx_data *rx_data, *temp;
-
- /* If the tasklet is scheduled when we call tasklet_kill it
- * will run one final time. However the tasklet will only
- * drain priv->rx_list if the hw is still available. */
- tasklet_kill(&priv->rx_tasklet);
-
- /* Explicitly drain priv->rx_list */
- list_for_each_entry_safe(rx_data, temp, &priv->rx_list, list) {
- list_del(&rx_data->list);
-
- dev_kfree_skb(rx_data->skb);
- kfree(rx_data->desc);
- kfree(rx_data);
- }
-
- orinoco_unregister_pm_notifier(priv);
- orinoco_uncache_fw(priv);
-
- priv->wpa_ie_len = 0;
- kfree(priv->wpa_ie);
- orinoco_mic_free(priv);
- orinoco_bss_data_free(priv);
- free_netdev(dev);
-}
-
-/********************************************************************/
-/* Wireless extensions */
-/********************************************************************/
-
-/* Return : < 0 -> error code ; >= 0 -> length */
-static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
- char buf[IW_ESSID_MAX_SIZE+1])
-{
- hermes_t *hw = &priv->hw;
- int err = 0;
- struct hermes_idstring essidbuf;
- char *p = (char *)(&essidbuf.val);
- int len;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if (strlen(priv->desired_essid) > 0) {
- /* We read the desired SSID from the hardware rather
- than from priv->desired_essid, just in case the
- firmware is allowed to change it on us. I'm not
- sure about this */
- /* My guess is that the OWNSSID should always be whatever
- * we set to the card, whereas CURRENT_SSID is the one that
- * may change... - Jean II */
- u16 rid;
-
- *active = 1;
-
- rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
- HERMES_RID_CNFDESIREDSSID;
-
- err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
- NULL, &essidbuf);
- if (err)
- goto fail_unlock;
- } else {
- *active = 0;
-
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
- sizeof(essidbuf), NULL, &essidbuf);
- if (err)
- goto fail_unlock;
- }
-
- len = le16_to_cpu(essidbuf.len);
- BUG_ON(len > IW_ESSID_MAX_SIZE);
-
- memset(buf, 0, IW_ESSID_MAX_SIZE);
- memcpy(buf, p, len);
- err = len;
-
- fail_unlock:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static long orinoco_hw_get_freq(struct orinoco_private *priv)
-{
-
- hermes_t *hw = &priv->hw;
- int err = 0;
- u16 channel;
- long freq = 0;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
- if (err)
- goto out;
-
- /* Intersil firmware 1.3.5 returns 0 when the interface is down */
- if (channel == 0) {
- err = -EBUSY;
- goto out;
- }
-
- if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
- printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
- priv->ndev->name, channel);
- err = -EBUSY;
- goto out;
-
- }
- freq = channel_frequency[channel-1] * 100000;
-
- out:
- orinoco_unlock(priv, &flags);
-
- if (err > 0)
- err = -EBUSY;
- return err ? err : freq;
-}
-
-static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
- int *numrates, s32 *rates, int max)
-{
- hermes_t *hw = &priv->hw;
- struct hermes_idstring list;
- unsigned char *p = (unsigned char *)&list.val;
- int err = 0;
- int num;
- int i;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
- sizeof(list), NULL, &list);
- orinoco_unlock(priv, &flags);
-
- if (err)
- return err;
-
- num = le16_to_cpu(list.len);
- *numrates = num;
- num = min(num, max);
-
- for (i = 0; i < num; i++) {
- rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
- }
-
- return 0;
-}
-
-static int orinoco_ioctl_getname(struct net_device *dev,
- struct iw_request_info *info,
- char *name,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int numrates;
- int err;
-
- err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
-
- if (!err && (numrates > 2))
- strcpy(name, "IEEE 802.11b");
- else
- strcpy(name, "IEEE 802.11-DS");
-
- return 0;
-}
-
-static int orinoco_ioctl_setwap(struct net_device *dev,
- struct iw_request_info *info,
- struct sockaddr *ap_addr,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = -EINPROGRESS; /* Call commit handler */
- unsigned long flags;
- static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- /* Enable automatic roaming - no sanity checks are needed */
- if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
- memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
- priv->bssid_fixed = 0;
- memset(priv->desired_bssid, 0, ETH_ALEN);
-
- /* "off" means keep existing connection */
- if (ap_addr->sa_data[0] == 0) {
- __orinoco_hw_set_wap(priv);
- err = 0;
- }
- goto out;
- }
-
- if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
- printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
- "support manual roaming\n",
- dev->name);
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if (priv->iw_mode != IW_MODE_INFRA) {
- printk(KERN_WARNING "%s: Manual roaming supported only in "
- "managed mode\n", dev->name);
- err = -EOPNOTSUPP;
- goto out;
- }
-
- /* Intersil firmware hangs without Desired ESSID */
- if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
- strlen(priv->desired_essid) == 0) {
- printk(KERN_WARNING "%s: Desired ESSID must be set for "
- "manual roaming\n", dev->name);
- err = -EOPNOTSUPP;
- goto out;
- }
-
- /* Finally, enable manual roaming */
- priv->bssid_fixed = 1;
- memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
-
- out:
- orinoco_unlock(priv, &flags);
- return err;
-}
-
-static int orinoco_ioctl_getwap(struct net_device *dev,
- struct iw_request_info *info,
- struct sockaddr *ap_addr,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- hermes_t *hw = &priv->hw;
- int err = 0;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- ap_addr->sa_family = ARPHRD_ETHER;
- err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
- ETH_ALEN, NULL, ap_addr->sa_data);
-
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_setmode(struct net_device *dev,
- struct iw_request_info *info,
- u32 *mode,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = -EINPROGRESS; /* Call commit handler */
- unsigned long flags;
-
- if (priv->iw_mode == *mode)
- return 0;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- switch (*mode) {
- case IW_MODE_ADHOC:
- if (!priv->has_ibss && !priv->has_port3)
- err = -EOPNOTSUPP;
- break;
-
- case IW_MODE_INFRA:
- break;
-
- case IW_MODE_MONITOR:
- if (priv->broken_monitor && !force_monitor) {
- printk(KERN_WARNING "%s: Monitor mode support is "
- "buggy in this firmware, not enabling\n",
- dev->name);
- err = -EOPNOTSUPP;
- }
- break;
-
- default:
- err = -EOPNOTSUPP;
- break;
- }
-
- if (err == -EINPROGRESS) {
- priv->iw_mode = *mode;
- set_port_type(priv);
- }
-
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_getmode(struct net_device *dev,
- struct iw_request_info *info,
- u32 *mode,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- *mode = priv->iw_mode;
- return 0;
-}
-
-static int orinoco_ioctl_getiwrange(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *rrq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = 0;
- struct iw_range *range = (struct iw_range *) extra;
- int numrates;
- int i, k;
-
- rrq->length = sizeof(struct iw_range);
- memset(range, 0, sizeof(struct iw_range));
-
- range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = 22;
-
- /* Set available channels/frequencies */
- range->num_channels = NUM_CHANNELS;
- k = 0;
- for (i = 0; i < NUM_CHANNELS; i++) {
- if (priv->channel_mask & (1 << i)) {
- range->freq[k].i = i + 1;
- range->freq[k].m = channel_frequency[i] * 100000;
- range->freq[k].e = 1;
- k++;
- }
-
- if (k >= IW_MAX_FREQUENCIES)
- break;
- }
- range->num_frequency = k;
- range->sensitivity = 3;
-
- if (priv->has_wep) {
- range->max_encoding_tokens = ORINOCO_MAX_KEYS;
- range->encoding_size[0] = SMALL_KEY_SIZE;
- range->num_encoding_sizes = 1;
-
- if (priv->has_big_wep) {
- range->encoding_size[1] = LARGE_KEY_SIZE;
- range->num_encoding_sizes = 2;
- }
- }
-
- if (priv->has_wpa)
- range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
-
- if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
- /* Quality stats meaningless in ad-hoc mode */
- } else {
- range->max_qual.qual = 0x8b - 0x2f;
- range->max_qual.level = 0x2f - 0x95 - 1;
- range->max_qual.noise = 0x2f - 0x95 - 1;
- /* Need to get better values */
- range->avg_qual.qual = 0x24;
- range->avg_qual.level = 0xC2;
- range->avg_qual.noise = 0x9E;
- }
-
- err = orinoco_hw_get_bitratelist(priv, &numrates,
- range->bitrate, IW_MAX_BITRATES);
- if (err)
- return err;
- range->num_bitrates = numrates;
-
- /* Set an indication of the max TCP throughput in bit/s that we can
- * expect using this interface. May be use for QoS stuff...
- * Jean II */
- if (numrates > 2)
- range->throughput = 5 * 1000 * 1000; /* ~5 Mb/s */
- else
- range->throughput = 1.5 * 1000 * 1000; /* ~1.5 Mb/s */
-
- range->min_rts = 0;
- range->max_rts = 2347;
- range->min_frag = 256;
- range->max_frag = 2346;
-
- range->min_pmp = 0;
- range->max_pmp = 65535000;
- range->min_pmt = 0;
- range->max_pmt = 65535 * 1000; /* ??? */
- range->pmp_flags = IW_POWER_PERIOD;
- range->pmt_flags = IW_POWER_TIMEOUT;
- range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
-
- range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
- range->retry_flags = IW_RETRY_LIMIT;
- range->r_time_flags = IW_RETRY_LIFETIME;
- range->min_retry = 0;
- range->max_retry = 65535; /* ??? */
- range->min_r_time = 0;
- range->max_r_time = 65535 * 1000; /* ??? */
-
- if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
- range->scan_capa = IW_SCAN_CAPA_ESSID;
- else
- range->scan_capa = IW_SCAN_CAPA_NONE;
-
- /* Event capability (kernel) */
- IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
- /* Event capability (driver) */
- IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
- IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
- IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
- IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
-
- return 0;
-}
-
-static int orinoco_ioctl_setiwencode(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq,
- char *keybuf)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int index = (erq->flags & IW_ENCODE_INDEX) - 1;
- int setindex = priv->tx_key;
- int encode_alg = priv->encode_alg;
- int restricted = priv->wep_restrict;
- u16 xlen = 0;
- int err = -EINPROGRESS; /* Call commit handler */
- unsigned long flags;
-
- if (! priv->has_wep)
- return -EOPNOTSUPP;
-
- if (erq->pointer) {
- /* We actually have a key to set - check its length */
- if (erq->length > LARGE_KEY_SIZE)
- return -E2BIG;
-
- if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
- return -E2BIG;
- }
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- /* Clear any TKIP key we have */
- if ((priv->has_wpa) && (priv->encode_alg == IW_ENCODE_ALG_TKIP))
- (void) orinoco_clear_tkip_key(priv, setindex);
-
- if (erq->length > 0) {
- if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
- index = priv->tx_key;
-
- /* Adjust key length to a supported value */
- if (erq->length > SMALL_KEY_SIZE) {
- xlen = LARGE_KEY_SIZE;
- } else if (erq->length > 0) {
- xlen = SMALL_KEY_SIZE;
- } else
- xlen = 0;
-
- /* Switch on WEP if off */
- if ((encode_alg != IW_ENCODE_ALG_WEP) && (xlen > 0)) {
- setindex = index;
- encode_alg = IW_ENCODE_ALG_WEP;
- }
- } else {
- /* Important note : if the user do "iwconfig eth0 enc off",
- * we will arrive there with an index of -1. This is valid
- * but need to be taken care off... Jean II */
- if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
- if((index != -1) || (erq->flags == 0)) {
- err = -EINVAL;
- goto out;
- }
- } else {
- /* Set the index : Check that the key is valid */
- if(priv->keys[index].len == 0) {
- err = -EINVAL;
- goto out;
- }
- setindex = index;
- }
- }
-
- if (erq->flags & IW_ENCODE_DISABLED)
- encode_alg = IW_ENCODE_ALG_NONE;
- if (erq->flags & IW_ENCODE_OPEN)
- restricted = 0;
- if (erq->flags & IW_ENCODE_RESTRICTED)
- restricted = 1;
-
- if (erq->pointer && erq->length > 0) {
- priv->keys[index].len = cpu_to_le16(xlen);
- memset(priv->keys[index].data, 0,
- sizeof(priv->keys[index].data));
- memcpy(priv->keys[index].data, keybuf, erq->length);
- }
- priv->tx_key = setindex;
-
- /* Try fast key change if connected and only keys are changed */
- if ((priv->encode_alg == encode_alg) &&
- (priv->wep_restrict == restricted) &&
- netif_carrier_ok(dev)) {
- err = __orinoco_hw_setup_wepkeys(priv);
- /* No need to commit if successful */
- goto out;
- }
-
- priv->encode_alg = encode_alg;
- priv->wep_restrict = restricted;
-
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_getiwencode(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq,
- char *keybuf)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int index = (erq->flags & IW_ENCODE_INDEX) - 1;
- u16 xlen = 0;
- unsigned long flags;
-
- if (! priv->has_wep)
- return -EOPNOTSUPP;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
- index = priv->tx_key;
-
- erq->flags = 0;
- if (!priv->encode_alg)
- erq->flags |= IW_ENCODE_DISABLED;
- erq->flags |= index + 1;
-
- if (priv->wep_restrict)
- erq->flags |= IW_ENCODE_RESTRICTED;
- else
- erq->flags |= IW_ENCODE_OPEN;
-
- xlen = le16_to_cpu(priv->keys[index].len);
-
- erq->length = xlen;
-
- memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
-
- orinoco_unlock(priv, &flags);
- return 0;
-}
-
-static int orinoco_ioctl_setessid(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq,
- char *essidbuf)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
-
- /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
- * anyway... - Jean II */
-
- /* Hum... Should not use Wireless Extension constant (may change),
- * should use our own... - Jean II */
- if (erq->length > IW_ESSID_MAX_SIZE)
- return -E2BIG;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
- memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
-
- /* If not ANY, get the new ESSID */
- if (erq->flags) {
- memcpy(priv->desired_essid, essidbuf, erq->length);
- }
-
- orinoco_unlock(priv, &flags);
-
- return -EINPROGRESS; /* Call commit handler */
-}
-
-static int orinoco_ioctl_getessid(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq,
- char *essidbuf)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int active;
- int err = 0;
- unsigned long flags;
-
- if (netif_running(dev)) {
- err = orinoco_hw_get_essid(priv, &active, essidbuf);
- if (err < 0)
- return err;
- erq->length = err;
- } else {
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
- memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
- erq->length = strlen(priv->desired_essid);
- orinoco_unlock(priv, &flags);
- }
-
- erq->flags = 1;
-
- return 0;
-}
-
-static int orinoco_ioctl_setnick(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *nrq,
- char *nickbuf)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
-
- if (nrq->length > IW_ESSID_MAX_SIZE)
- return -E2BIG;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- memset(priv->nick, 0, sizeof(priv->nick));
- memcpy(priv->nick, nickbuf, nrq->length);
-
- orinoco_unlock(priv, &flags);
-
- return -EINPROGRESS; /* Call commit handler */
-}
-
-static int orinoco_ioctl_getnick(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *nrq,
- char *nickbuf)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
- orinoco_unlock(priv, &flags);
-
- nrq->length = strlen(priv->nick);
-
- return 0;
-}
-
-static int orinoco_ioctl_setfreq(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_freq *frq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int chan = -1;
- unsigned long flags;
- int err = -EINPROGRESS; /* Call commit handler */
-
- /* In infrastructure mode the AP sets the channel */
- if (priv->iw_mode == IW_MODE_INFRA)
- return -EBUSY;
-
- if ( (frq->e == 0) && (frq->m <= 1000) ) {
- /* Setting by channel number */
- chan = frq->m;
- } else {
- /* Setting by frequency - search the table */
- int mult = 1;
- int i;
-
- for (i = 0; i < (6 - frq->e); i++)
- mult *= 10;
-
- for (i = 0; i < NUM_CHANNELS; i++)
- if (frq->m == (channel_frequency[i] * mult))
- chan = i+1;
- }
-
- if ( (chan < 1) || (chan > NUM_CHANNELS) ||
- ! (priv->channel_mask & (1 << (chan-1)) ) )
- return -EINVAL;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- priv->channel = chan;
- if (priv->iw_mode == IW_MODE_MONITOR) {
- /* Fast channel change - no commit if successful */
- hermes_t *hw = &priv->hw;
- err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
- HERMES_TEST_SET_CHANNEL,
- chan, NULL);
- }
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_getfreq(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_freq *frq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int tmp;
-
- /* Locking done in there */
- tmp = orinoco_hw_get_freq(priv);
- if (tmp < 0) {
- return tmp;
- }
-
- frq->m = tmp;
- frq->e = 1;
-
- return 0;
-}
-
-static int orinoco_ioctl_getsens(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *srq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- u16 val;
- int err;
- unsigned long flags;
-
- if (!priv->has_sensitivity)
- return -EOPNOTSUPP;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFSYSTEMSCALE, &val);
- orinoco_unlock(priv, &flags);
-
- if (err)
- return err;
-
- srq->value = val;
- srq->fixed = 0; /* auto */
-
- return 0;
-}
-
-static int orinoco_ioctl_setsens(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *srq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int val = srq->value;
- unsigned long flags;
-
- if (!priv->has_sensitivity)
- return -EOPNOTSUPP;
-
- if ((val < 1) || (val > 3))
- return -EINVAL;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
- priv->ap_density = val;
- orinoco_unlock(priv, &flags);
-
- return -EINPROGRESS; /* Call commit handler */
-}
-
-static int orinoco_ioctl_setrts(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rrq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int val = rrq->value;
- unsigned long flags;
-
- if (rrq->disabled)
- val = 2347;
-
- if ( (val < 0) || (val > 2347) )
- return -EINVAL;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- priv->rts_thresh = val;
- orinoco_unlock(priv, &flags);
-
- return -EINPROGRESS; /* Call commit handler */
-}
-
-static int orinoco_ioctl_getrts(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rrq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- rrq->value = priv->rts_thresh;
- rrq->disabled = (rrq->value == 2347);
- rrq->fixed = 1;
-
- return 0;
-}
-
-static int orinoco_ioctl_setfrag(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = -EINPROGRESS; /* Call commit handler */
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if (priv->has_mwo) {
- if (frq->disabled)
- priv->mwo_robust = 0;
- else {
- if (frq->fixed)
- printk(KERN_WARNING "%s: Fixed fragmentation is "
- "not supported on this firmware. "
- "Using MWO robust instead.\n", dev->name);
- priv->mwo_robust = 1;
- }
- } else {
- if (frq->disabled)
- priv->frag_thresh = 2346;
- else {
- if ( (frq->value < 256) || (frq->value > 2346) )
- err = -EINVAL;
- else
- priv->frag_thresh = frq->value & ~0x1; /* must be even */
- }
- }
-
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_getfrag(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err;
- u16 val;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if (priv->has_mwo) {
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMWOROBUST_AGERE,
- &val);
- if (err)
- val = 0;
-
- frq->value = val ? 2347 : 0;
- frq->disabled = ! val;
- frq->fixed = 0;
- } else {
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
- &val);
- if (err)
- val = 0;
-
- frq->value = val;
- frq->disabled = (val >= 2346);
- frq->fixed = 1;
- }
-
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_setrate(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rrq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int ratemode = -1;
- int bitrate; /* 100s of kilobits */
- int i;
- unsigned long flags;
-
- /* As the user space doesn't know our highest rate, it uses -1
- * to ask us to set the highest rate. Test it using "iwconfig
- * ethX rate auto" - Jean II */
- if (rrq->value == -1)
- bitrate = 110;
- else {
- if (rrq->value % 100000)
- return -EINVAL;
- bitrate = rrq->value / 100000;
- }
-
- if ( (bitrate != 10) && (bitrate != 20) &&
- (bitrate != 55) && (bitrate != 110) )
- return -EINVAL;
-
- for (i = 0; i < BITRATE_TABLE_SIZE; i++)
- if ( (bitrate_table[i].bitrate == bitrate) &&
- (bitrate_table[i].automatic == ! rrq->fixed) ) {
- ratemode = i;
- break;
- }
-
- if (ratemode == -1)
- return -EINVAL;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
- priv->bitratemode = ratemode;
- orinoco_unlock(priv, &flags);
-
- return -EINPROGRESS;
-}
-
-static int orinoco_ioctl_getrate(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rrq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err = 0;
- int ratemode;
- int i;
- u16 val;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- ratemode = priv->bitratemode;
-
- BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
-
- rrq->value = bitrate_table[ratemode].bitrate * 100000;
- rrq->fixed = ! bitrate_table[ratemode].automatic;
- rrq->disabled = 0;
-
- /* If the interface is running we try to find more about the
- current mode */
- if (netif_running(dev)) {
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CURRENTTXRATE, &val);
- if (err)
- goto out;
-
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
- /* Note : in Lucent firmware, the return value of
- * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
- * and therefore is totally different from the
- * encoding of HERMES_RID_CNFTXRATECONTROL.
- * Don't forget that 6Mb/s is really 5.5Mb/s */
- if (val == 6)
- rrq->value = 5500000;
- else
- rrq->value = val * 1000000;
- break;
- case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
- case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
- for (i = 0; i < BITRATE_TABLE_SIZE; i++)
- if (bitrate_table[i].intersil_txratectrl == val) {
- ratemode = i;
- break;
- }
- if (i >= BITRATE_TABLE_SIZE)
- printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
- dev->name, val);
-
- rrq->value = bitrate_table[ratemode].bitrate * 100000;
- break;
- default:
- BUG();
- }
- }
-
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_setpower(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *prq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = -EINPROGRESS; /* Call commit handler */
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if (prq->disabled) {
- priv->pm_on = 0;
- } else {
- switch (prq->flags & IW_POWER_MODE) {
- case IW_POWER_UNICAST_R:
- priv->pm_mcast = 0;
- priv->pm_on = 1;
- break;
- case IW_POWER_ALL_R:
- priv->pm_mcast = 1;
- priv->pm_on = 1;
- break;
- case IW_POWER_ON:
- /* No flags : but we may have a value - Jean II */
- break;
- default:
- err = -EINVAL;
- goto out;
- }
-
- if (prq->flags & IW_POWER_TIMEOUT) {
- priv->pm_on = 1;
- priv->pm_timeout = prq->value / 1000;
- }
- if (prq->flags & IW_POWER_PERIOD) {
- priv->pm_on = 1;
- priv->pm_period = prq->value / 1000;
- }
- /* It's valid to not have a value if we are just toggling
- * the flags... Jean II */
- if(!priv->pm_on) {
- err = -EINVAL;
- goto out;
- }
- }
-
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_getpower(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *prq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err = 0;
- u16 enable, period, timeout, mcast;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
- if (err)
- goto out;
-
- err = hermes_read_wordrec(hw, USER_BAP,
- HERMES_RID_CNFMAXSLEEPDURATION, &period);
- if (err)
- goto out;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
- if (err)
- goto out;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
- if (err)
- goto out;
-
- prq->disabled = !enable;
- /* Note : by default, display the period */
- if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
- prq->flags = IW_POWER_TIMEOUT;
- prq->value = timeout * 1000;
- } else {
- prq->flags = IW_POWER_PERIOD;
- prq->value = period * 1000;
- }
- if (mcast)
- prq->flags |= IW_POWER_ALL_R;
- else
- prq->flags |= IW_POWER_UNICAST_R;
-
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_set_encodeext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, alg = ext->alg, set_key = 1;
- unsigned long flags;
- int err = -EINVAL;
- u16 key_len;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- /* Determine and validate the key index */
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx) {
- if ((idx < 1) || (idx > 4))
- goto out;
- idx--;
- } else
- idx = priv->tx_key;
-
- if (encoding->flags & IW_ENCODE_DISABLED)
- alg = IW_ENCODE_ALG_NONE;
-
- if (priv->has_wpa && (alg != IW_ENCODE_ALG_TKIP)) {
- /* Clear any TKIP TX key we had */
- (void) orinoco_clear_tkip_key(priv, priv->tx_key);
- }
-
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- priv->tx_key = idx;
- set_key = ((alg == IW_ENCODE_ALG_TKIP) ||
- (ext->key_len > 0)) ? 1 : 0;
- }
-
- if (set_key) {
- /* Set the requested key first */
- switch (alg) {
- case IW_ENCODE_ALG_NONE:
- priv->encode_alg = alg;
- priv->keys[idx].len = 0;
- break;
-
- case IW_ENCODE_ALG_WEP:
- if (ext->key_len > SMALL_KEY_SIZE)
- key_len = LARGE_KEY_SIZE;
- else if (ext->key_len > 0)
- key_len = SMALL_KEY_SIZE;
- else
- goto out;
-
- priv->encode_alg = alg;
- priv->keys[idx].len = cpu_to_le16(key_len);
-
- key_len = min(ext->key_len, key_len);
-
- memset(priv->keys[idx].data, 0, ORINOCO_MAX_KEY_SIZE);
- memcpy(priv->keys[idx].data, ext->key, key_len);
- break;
-
- case IW_ENCODE_ALG_TKIP:
- {
- hermes_t *hw = &priv->hw;
- u8 *tkip_iv = NULL;
-
- if (!priv->has_wpa ||
- (ext->key_len > sizeof(priv->tkip_key[0])))
- goto out;
-
- priv->encode_alg = alg;
- memset(&priv->tkip_key[idx], 0,
- sizeof(priv->tkip_key[idx]));
- memcpy(&priv->tkip_key[idx], ext->key, ext->key_len);
-
- if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
- tkip_iv = &ext->rx_seq[0];
-
- err = __orinoco_hw_set_tkip_key(hw, idx,
- ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
- (u8 *) &priv->tkip_key[idx],
- tkip_iv, NULL);
- if (err)
- printk(KERN_ERR "%s: Error %d setting TKIP key"
- "\n", dev->name, err);
-
- goto out;
- }
- default:
- goto out;
- }
- }
- err = -EINPROGRESS;
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_get_encodeext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int idx, max_key_len;
- unsigned long flags;
- int err;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = -EINVAL;
- max_key_len = encoding->length - sizeof(*ext);
- if (max_key_len < 0)
- goto out;
-
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx) {
- if ((idx < 1) || (idx > 4))
- goto out;
- idx--;
- } else
- idx = priv->tx_key;
-
- encoding->flags = idx + 1;
- memset(ext, 0, sizeof(*ext));
-
- ext->alg = priv->encode_alg;
- switch (priv->encode_alg) {
- case IW_ENCODE_ALG_NONE:
- ext->key_len = 0;
- encoding->flags |= IW_ENCODE_DISABLED;
- break;
- case IW_ENCODE_ALG_WEP:
- ext->key_len = min_t(u16, le16_to_cpu(priv->keys[idx].len),
- max_key_len);
- memcpy(ext->key, priv->keys[idx].data, ext->key_len);
- encoding->flags |= IW_ENCODE_ENABLED;
- break;
- case IW_ENCODE_ALG_TKIP:
- ext->key_len = min_t(u16, sizeof(struct orinoco_tkip_key),
- max_key_len);
- memcpy(ext->key, &priv->tkip_key[idx], ext->key_len);
- encoding->flags |= IW_ENCODE_ENABLED;
- break;
- }
-
- err = 0;
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_set_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- struct iw_param *param = &wrqu->param;
- unsigned long flags;
- int ret = -EINPROGRESS;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- switch (param->flags & IW_AUTH_INDEX) {
- case IW_AUTH_WPA_VERSION:
- case IW_AUTH_CIPHER_PAIRWISE:
- case IW_AUTH_CIPHER_GROUP:
- case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- case IW_AUTH_PRIVACY_INVOKED:
- case IW_AUTH_DROP_UNENCRYPTED:
- /*
- * orinoco does not use these parameters
- */
- break;
-
- case IW_AUTH_KEY_MGMT:
- /* wl_lkm implies value 2 == PSK for Hermes I
- * which ties in with WEXT
- * no other hints tho :(
- */
- priv->key_mgmt = param->value;
- break;
-
- case IW_AUTH_TKIP_COUNTERMEASURES:
- /* When countermeasures are enabled, shut down the
- * card; when disabled, re-enable the card. This must
- * take effect immediately.
- *
- * TODO: Make sure that the EAPOL message is getting
- * out before card disabled
- */
- if (param->value) {
- priv->tkip_cm_active = 1;
- ret = hermes_enable_port(hw, 0);
- } else {
- priv->tkip_cm_active = 0;
- ret = hermes_disable_port(hw, 0);
- }
- break;
-
- case IW_AUTH_80211_AUTH_ALG:
- if (param->value & IW_AUTH_ALG_SHARED_KEY)
- priv->wep_restrict = 1;
- else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
- priv->wep_restrict = 0;
- else
- ret = -EINVAL;
- break;
-
- case IW_AUTH_WPA_ENABLED:
- if (priv->has_wpa) {
- priv->wpa_enabled = param->value ? 1 : 0;
- } else {
- if (param->value)
- ret = -EOPNOTSUPP;
- /* else silently accept disable of WPA */
- priv->wpa_enabled = 0;
- }
- break;
-
- default:
- ret = -EOPNOTSUPP;
- }
-
- orinoco_unlock(priv, &flags);
- return ret;
-}
-
-static int orinoco_ioctl_get_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct iw_param *param = &wrqu->param;
- unsigned long flags;
- int ret = 0;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- switch (param->flags & IW_AUTH_INDEX) {
- case IW_AUTH_KEY_MGMT:
- param->value = priv->key_mgmt;
- break;
-
- case IW_AUTH_TKIP_COUNTERMEASURES:
- param->value = priv->tkip_cm_active;
- break;
-
- case IW_AUTH_80211_AUTH_ALG:
- if (priv->wep_restrict)
- param->value = IW_AUTH_ALG_SHARED_KEY;
- else
- param->value = IW_AUTH_ALG_OPEN_SYSTEM;
- break;
-
- case IW_AUTH_WPA_ENABLED:
- param->value = priv->wpa_enabled;
- break;
-
- default:
- ret = -EOPNOTSUPP;
- }
-
- orinoco_unlock(priv, &flags);
- return ret;
-}
-
-static int orinoco_ioctl_set_genie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- u8 *buf;
- unsigned long flags;
-
- /* cut off at IEEE80211_MAX_DATA_LEN */
- if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
- (wrqu->data.length && (extra == NULL)))
- return -EINVAL;
-
- if (wrqu->data.length) {
- buf = kmalloc(wrqu->data.length, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- memcpy(buf, extra, wrqu->data.length);
- } else
- buf = NULL;
-
- if (orinoco_lock(priv, &flags) != 0) {
- kfree(buf);
- return -EBUSY;
- }
-
- kfree(priv->wpa_ie);
- priv->wpa_ie = buf;
- priv->wpa_ie_len = wrqu->data.length;
-
- if (priv->wpa_ie) {
- /* Looks like wl_lkm wants to check the auth alg, and
- * somehow pass it to the firmware.
- * Instead it just calls the key mgmt rid
- * - we do this in set auth.
- */
- }
-
- orinoco_unlock(priv, &flags);
- return 0;
-}
-
-static int orinoco_ioctl_get_genie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int err = 0;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if ((priv->wpa_ie_len == 0) || (priv->wpa_ie == NULL)) {
- wrqu->data.length = 0;
- goto out;
- }
-
- if (wrqu->data.length < priv->wpa_ie_len) {
- err = -E2BIG;
- goto out;
- }
-
- wrqu->data.length = priv->wpa_ie_len;
- memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
-
-out:
- orinoco_unlock(priv, &flags);
- return err;
-}
-
-static int orinoco_ioctl_set_mlme(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- struct iw_mlme *mlme = (struct iw_mlme *)extra;
- unsigned long flags;
- int ret = 0;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- switch (mlme->cmd) {
- case IW_MLME_DEAUTH:
- /* silently ignore */
- break;
-
- case IW_MLME_DISASSOC:
- {
- struct {
- u8 addr[ETH_ALEN];
- __le16 reason_code;
- } __attribute__ ((packed)) buf;
-
- memcpy(buf.addr, mlme->addr.sa_data, ETH_ALEN);
- buf.reason_code = cpu_to_le16(mlme->reason_code);
- ret = HERMES_WRITE_RECORD(hw, USER_BAP,
- HERMES_RID_CNFDISASSOCIATE,
- &buf);
- break;
- }
- default:
- ret = -EOPNOTSUPP;
- }
-
- orinoco_unlock(priv, &flags);
- return ret;
-}
-
-static int orinoco_ioctl_getretry(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rrq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int err = 0;
- u16 short_limit, long_limit, lifetime;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
- &short_limit);
- if (err)
- goto out;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
- &long_limit);
- if (err)
- goto out;
-
- err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
- &lifetime);
- if (err)
- goto out;
-
- rrq->disabled = 0; /* Can't be disabled */
-
- /* Note : by default, display the retry number */
- if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
- rrq->flags = IW_RETRY_LIFETIME;
- rrq->value = lifetime * 1000; /* ??? */
- } else {
- /* By default, display the min number */
- if ((rrq->flags & IW_RETRY_LONG)) {
- rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
- rrq->value = long_limit;
- } else {
- rrq->flags = IW_RETRY_LIMIT;
- rrq->value = short_limit;
- if(short_limit != long_limit)
- rrq->flags |= IW_RETRY_SHORT;
- }
- }
-
- out:
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_reset(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- if (! capable(CAP_NET_ADMIN))
- return -EPERM;
-
- if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
- printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
-
- /* Firmware reset */
- orinoco_reset(&priv->reset_work);
- } else {
- printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
-
- schedule_work(&priv->reset_work);
- }
-
- return 0;
-}
-
-static int orinoco_ioctl_setibssport(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int val = *( (int *) extra );
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- priv->ibss_port = val ;
-
- /* Actually update the mode we are using */
- set_port_type(priv);
-
- orinoco_unlock(priv, &flags);
- return -EINPROGRESS; /* Call commit handler */
-}
-
-static int orinoco_ioctl_getibssport(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int *val = (int *) extra;
-
- *val = priv->ibss_port;
- return 0;
-}
-
-static int orinoco_ioctl_setport3(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int val = *( (int *) extra );
- int err = 0;
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- switch (val) {
- case 0: /* Try to do IEEE ad-hoc mode */
- if (! priv->has_ibss) {
- err = -EINVAL;
- break;
- }
- priv->prefer_port3 = 0;
-
- break;
-
- case 1: /* Try to do Lucent proprietary ad-hoc mode */
- if (! priv->has_port3) {
- err = -EINVAL;
- break;
- }
- priv->prefer_port3 = 1;
- break;
-
- default:
- err = -EINVAL;
- }
-
- if (! err) {
- /* Actually update the mode we are using */
- set_port_type(priv);
- err = -EINPROGRESS;
- }
-
- orinoco_unlock(priv, &flags);
-
- return err;
-}
-
-static int orinoco_ioctl_getport3(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int *val = (int *) extra;
-
- *val = priv->prefer_port3;
- return 0;
-}
-
-static int orinoco_ioctl_setpreamble(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- unsigned long flags;
- int val;
-
- if (! priv->has_preamble)
- return -EOPNOTSUPP;
-
- /* 802.11b has recently defined some short preamble.
- * Basically, the Phy header has been reduced in size.
- * This increase performance, especially at high rates
- * (the preamble is transmitted at 1Mb/s), unfortunately
- * this give compatibility troubles... - Jean II */
- val = *( (int *) extra );
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if (val)
- priv->preamble = 1;
- else
- priv->preamble = 0;
-
- orinoco_unlock(priv, &flags);
-
- return -EINPROGRESS; /* Call commit handler */
-}
-
-static int orinoco_ioctl_getpreamble(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int *val = (int *) extra;
-
- if (! priv->has_preamble)
- return -EOPNOTSUPP;
-
- *val = priv->preamble;
- return 0;
-}
-
-/* ioctl interface to hermes_read_ltv()
- * To use with iwpriv, pass the RID as the token argument, e.g.
- * iwpriv get_rid [0xfc00]
- * At least Wireless Tools 25 is required to use iwpriv.
- * For Wireless Tools 25 and 26 append "dummy" are the end. */
-static int orinoco_ioctl_getrid(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *data,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- int rid = data->flags;
- u16 length;
- int err;
- unsigned long flags;
-
- /* It's a "get" function, but we don't want users to access the
- * WEP key and other raw firmware data */
- if (! capable(CAP_NET_ADMIN))
- return -EPERM;
-
- if (rid < 0xfc00 || rid > 0xffff)
- return -EINVAL;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
- extra);
- if (err)
- goto out;
-
- data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
- MAX_RID_LEN);
-
- out:
- orinoco_unlock(priv, &flags);
- return err;
-}
-
-/* Trigger a scan (look for other cells in the vicinity) */
-static int orinoco_ioctl_setscan(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *srq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- hermes_t *hw = &priv->hw;
- struct iw_scan_req *si = (struct iw_scan_req *) extra;
- int err = 0;
- unsigned long flags;
-
- /* Note : you may have realised that, as this is a SET operation,
- * this is privileged and therefore a normal user can't
- * perform scanning.
- * This is not an error, while the device perform scanning,
- * traffic doesn't flow, so it's a perfect DoS...
- * Jean II */
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- /* Scanning with port 0 disabled would fail */
- if (!netif_running(dev)) {
- err = -ENETDOWN;
- goto out;
- }
-
- /* In monitor mode, the scan results are always empty.
- * Probe responses are passed to the driver as received
- * frames and could be processed in software. */
- if (priv->iw_mode == IW_MODE_MONITOR) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- /* Note : because we don't lock out the irq handler, the way
- * we access scan variables in priv is critical.
- * o scan_inprogress : not touched by irq handler
- * o scan_mode : not touched by irq handler
- * Before modifying anything on those variables, please think hard !
- * Jean II */
-
- /* Save flags */
- priv->scan_mode = srq->flags;
-
- /* Always trigger scanning, even if it's in progress.
- * This way, if the info frame get lost, we will recover somewhat
- * gracefully - Jean II */
-
- if (priv->has_hostscan) {
- switch (priv->firmware_type) {
- case FIRMWARE_TYPE_SYMBOL:
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFHOSTSCAN_SYMBOL,
- HERMES_HOSTSCAN_SYMBOL_ONCE |
- HERMES_HOSTSCAN_SYMBOL_BCAST);
- break;
- case FIRMWARE_TYPE_INTERSIL: {
- __le16 req[3];
-
- req[0] = cpu_to_le16(0x3fff); /* All channels */
- req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */
- req[2] = 0; /* Any ESSID */
- err = HERMES_WRITE_RECORD(hw, USER_BAP,
- HERMES_RID_CNFHOSTSCAN, &req);
- }
- break;
- case FIRMWARE_TYPE_AGERE:
- if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
- struct hermes_idstring idbuf;
- size_t len = min(sizeof(idbuf.val),
- (size_t) si->essid_len);
- idbuf.len = cpu_to_le16(len);
- memcpy(idbuf.val, si->essid, len);
-
- err = hermes_write_ltv(hw, USER_BAP,
- HERMES_RID_CNFSCANSSID_AGERE,
- HERMES_BYTES_TO_RECLEN(len + 2),
- &idbuf);
- } else
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFSCANSSID_AGERE,
- 0); /* Any ESSID */
- if (err)
- break;
-
- if (priv->has_ext_scan) {
- /* Clear scan results at the start of
- * an extended scan */
- orinoco_clear_scan_results(priv,
- msecs_to_jiffies(15000));
-
- /* TODO: Is this available on older firmware?
- * Can we use it to scan specific channels
- * for IW_SCAN_THIS_FREQ? */
- err = hermes_write_wordrec(hw, USER_BAP,
- HERMES_RID_CNFSCANCHANNELS2GHZ,
- 0x7FFF);
- if (err)
- goto out;
-
- err = hermes_inquire(hw,
- HERMES_INQ_CHANNELINFO);
- } else
- err = hermes_inquire(hw, HERMES_INQ_SCAN);
- break;
- }
- } else
- err = hermes_inquire(hw, HERMES_INQ_SCAN);
-
- /* One more client */
- if (! err)
- priv->scan_inprogress = 1;
-
- out:
- orinoco_unlock(priv, &flags);
- return err;
-}
-
-#define MAX_CUSTOM_LEN 64
-
-/* Translate scan data returned from the card to a card independant
- * format that the Wireless Tools will understand - Jean II */
-static inline char *orinoco_translate_scan(struct net_device *dev,
- struct iw_request_info *info,
- char *current_ev,
- char *end_buf,
- union hermes_scan_info *bss,
- unsigned long last_scanned)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- u16 capabilities;
- u16 channel;
- struct iw_event iwe; /* Temporary buffer */
- char custom[MAX_CUSTOM_LEN];
-
- memset(&iwe, 0, sizeof(iwe));
-
- /* First entry *MUST* be the AP MAC address */
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_ADDR_LEN);
-
- /* Other entries will be displayed in the order we give them */
-
- /* Add the ESSID */
- iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
- if (iwe.u.data.length > 32)
- iwe.u.data.length = 32;
- iwe.cmd = SIOCGIWESSID;
- iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, bss->a.essid);
-
- /* Add mode */
- iwe.cmd = SIOCGIWMODE;
- capabilities = le16_to_cpu(bss->a.capabilities);
- if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
- if (capabilities & WLAN_CAPABILITY_ESS)
- iwe.u.mode = IW_MODE_MASTER;
- else
- iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_UINT_LEN);
- }
-
- channel = bss->s.channel;
- if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
- /* Add channel and frequency */
- iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = channel;
- iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_FREQ_LEN);
-
- iwe.u.freq.m = channel_frequency[channel-1] * 100000;
- iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_FREQ_LEN);
- }
-
- /* Add quality statistics. level and noise in dB. No link quality */
- iwe.cmd = IWEVQUAL;
- iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
- iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
- iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
- /* Wireless tools prior to 27.pre22 will show link quality
- * anyway, so we provide a reasonable value. */
- if (iwe.u.qual.level > iwe.u.qual.noise)
- iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
- else
- iwe.u.qual.qual = 0;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_QUAL_LEN);
-
- /* Add encryption capability */
- iwe.cmd = SIOCGIWENCODE;
- if (capabilities & WLAN_CAPABILITY_PRIVACY)
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- else
- iwe.u.data.flags = IW_ENCODE_DISABLED;
- iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, NULL);
-
- /* Bit rate is not available in Lucent/Agere firmwares */
- if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
- char *current_val = current_ev + iwe_stream_lcp_len(info);
- int i;
- int step;
-
- if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
- step = 2;
- else
- step = 1;
-
- iwe.cmd = SIOCGIWRATE;
- /* Those two flags are ignored... */
- iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
- /* Max 10 values */
- for (i = 0; i < 10; i += step) {
- /* NULL terminated */
- if (bss->p.rates[i] == 0x0)
- break;
- /* Bit rate given in 500 kb/s units (+ 0x80) */
- iwe.u.bitrate.value =
- ((bss->p.rates[i] & 0x7f) * 500000);
- current_val = iwe_stream_add_value(info, current_ev,
- current_val,
- end_buf, &iwe,
- IW_EV_PARAM_LEN);
- }
- /* Check if we added any event */
- if ((current_val - current_ev) > iwe_stream_lcp_len(info))
- current_ev = current_val;
- }
-
- /* Beacon interval */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
- "bcn_int=%d",
- le16_to_cpu(bss->a.beacon_interv));
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- /* Capabilites */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
- "capab=0x%04x",
- capabilities);
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- /* Add EXTRA: Age to display seconds since last beacon/probe response
- * for given network. */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
- " Last beacon: %dms ago",
- jiffies_to_msecs(jiffies - last_scanned));
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- return current_ev;
-}
-
-static inline char *orinoco_translate_ext_scan(struct net_device *dev,
- struct iw_request_info *info,
- char *current_ev,
- char *end_buf,
- struct agere_ext_scan_info *bss,
- unsigned long last_scanned)
-{
- u16 capabilities;
- u16 channel;
- struct iw_event iwe; /* Temporary buffer */
- char custom[MAX_CUSTOM_LEN];
- u8 *ie;
-
- memset(&iwe, 0, sizeof(iwe));
-
- /* First entry *MUST* be the AP MAC address */
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_ADDR_LEN);
-
- /* Other entries will be displayed in the order we give them */
-
- /* Add the ESSID */
- ie = bss->data;
- iwe.u.data.length = ie[1];
- if (iwe.u.data.length) {
- if (iwe.u.data.length > 32)
- iwe.u.data.length = 32;
- iwe.cmd = SIOCGIWESSID;
- iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, &ie[2]);
- }
-
- /* Add mode */
- capabilities = le16_to_cpu(bss->capabilities);
- if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
- iwe.cmd = SIOCGIWMODE;
- if (capabilities & WLAN_CAPABILITY_ESS)
- iwe.u.mode = IW_MODE_MASTER;
- else
- iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_UINT_LEN);
- }
-
- ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_DS_PARAMS);
- channel = ie ? ie[2] : 0;
- if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
- /* Add channel and frequency */
- iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = channel;
- iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_FREQ_LEN);
-
- iwe.u.freq.m = channel_frequency[channel-1] * 100000;
- iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_FREQ_LEN);
- }
-
- /* Add quality statistics. level and noise in dB. No link quality */
- iwe.cmd = IWEVQUAL;
- iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
- iwe.u.qual.level = bss->level - 0x95;
- iwe.u.qual.noise = bss->noise - 0x95;
- /* Wireless tools prior to 27.pre22 will show link quality
- * anyway, so we provide a reasonable value. */
- if (iwe.u.qual.level > iwe.u.qual.noise)
- iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
- else
- iwe.u.qual.qual = 0;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf,
- &iwe, IW_EV_QUAL_LEN);
-
- /* Add encryption capability */
- iwe.cmd = SIOCGIWENCODE;
- if (capabilities & WLAN_CAPABILITY_PRIVACY)
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- else
- iwe.u.data.flags = IW_ENCODE_DISABLED;
- iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, NULL);
-
- /* WPA IE */
- ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
- if (ie) {
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = ie[1] + 2;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, ie);
- }
-
- /* RSN IE */
- ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_RSN);
- if (ie) {
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = ie[1] + 2;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, ie);
- }
-
- ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_SUPP_RATES);
- if (ie) {
- char *p = current_ev + iwe_stream_lcp_len(info);
- int i;
-
- iwe.cmd = SIOCGIWRATE;
- /* Those two flags are ignored... */
- iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-
- for (i = 2; i < (ie[1] + 2); i++) {
- iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
- p = iwe_stream_add_value(info, current_ev, p, end_buf,
- &iwe, IW_EV_PARAM_LEN);
- }
- /* Check if we added any event */
- if (p > (current_ev + iwe_stream_lcp_len(info)))
- current_ev = p;
- }
-
- /* Timestamp */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length =
- snprintf(custom, MAX_CUSTOM_LEN, "tsf=%016llx",
- (unsigned long long) le64_to_cpu(bss->timestamp));
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- /* Beacon interval */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
- "bcn_int=%d",
- le16_to_cpu(bss->beacon_interval));
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- /* Capabilites */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
- "capab=0x%04x",
- capabilities);
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- /* Add EXTRA: Age to display seconds since last beacon/probe response
- * for given network. */
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
- " Last beacon: %dms ago",
- jiffies_to_msecs(jiffies - last_scanned));
- if (iwe.u.data.length)
- current_ev = iwe_stream_add_point(info, current_ev, end_buf,
- &iwe, custom);
-
- return current_ev;
-}
-
-/* Return results of a scan */
-static int orinoco_ioctl_getscan(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *srq,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- int err = 0;
- unsigned long flags;
- char *current_ev = extra;
-
- if (orinoco_lock(priv, &flags) != 0)
- return -EBUSY;
-
- if (priv->scan_inprogress) {
- /* Important note : we don't want to block the caller
- * until results are ready for various reasons.
- * First, managing wait queues is complex and racy.
- * Second, we grab some rtnetlink lock before comming
- * here (in dev_ioctl()).
- * Third, we generate an Wireless Event, so the
- * caller can wait itself on that - Jean II */
- err = -EAGAIN;
- goto out;
- }
-
- if (priv->has_ext_scan) {
- struct xbss_element *bss;
-
- list_for_each_entry(bss, &priv->bss_list, list) {
- /* Translate this entry to WE format */
- current_ev =
- orinoco_translate_ext_scan(dev, info,
- current_ev,
- extra + srq->length,
- &bss->bss,
- bss->last_scanned);
-
- /* Check if there is space for one more entry */
- if ((extra + srq->length - current_ev)
- <= IW_EV_ADDR_LEN) {
- /* Ask user space to try again with a
- * bigger buffer */
- err = -E2BIG;
- goto out;
- }
- }
-
- } else {
- struct bss_element *bss;
-
- list_for_each_entry(bss, &priv->bss_list, list) {
- /* Translate this entry to WE format */
- current_ev = orinoco_translate_scan(dev, info,
- current_ev,
- extra + srq->length,
- &bss->bss,
- bss->last_scanned);
-
- /* Check if there is space for one more entry */
- if ((extra + srq->length - current_ev)
- <= IW_EV_ADDR_LEN) {
- /* Ask user space to try again with a
- * bigger buffer */
- err = -E2BIG;
- goto out;
- }
- }
- }
-
- srq->length = (current_ev - extra);
- srq->flags = (__u16) priv->scan_mode;
-
-out:
- orinoco_unlock(priv, &flags);
- return err;
-}
-
-/* Commit handler, called after set operations */
-static int orinoco_ioctl_commit(struct net_device *dev,
- struct iw_request_info *info,
- void *wrqu,
- char *extra)
-{
- struct orinoco_private *priv = netdev_priv(dev);
- struct hermes *hw = &priv->hw;
- unsigned long flags;
- int err = 0;
-
- if (!priv->open)
- return 0;
-
- if (priv->broken_disableport) {
- orinoco_reset(&priv->reset_work);
- return 0;
- }
-
- if (orinoco_lock(priv, &flags) != 0)
- return err;
-
- err = hermes_disable_port(hw, 0);
- if (err) {
- printk(KERN_WARNING "%s: Unable to disable port "
- "while reconfiguring card\n", dev->name);
- priv->broken_disableport = 1;
- goto out;
- }
-
- err = __orinoco_program_rids(dev);
- if (err) {
- printk(KERN_WARNING "%s: Unable to reconfigure card\n",
- dev->name);
- goto out;
- }
-
- err = hermes_enable_port(hw, 0);
- if (err) {
- printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
- dev->name);
- goto out;
- }
-
- out:
- if (err) {
- printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
- schedule_work(&priv->reset_work);
- err = 0;
- }
-
- orinoco_unlock(priv, &flags);
- return err;
-}
-
-static const struct iw_priv_args orinoco_privtab[] = {
- { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
- { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
- { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "set_port3" },
- { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_port3" },
- { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "set_preamble" },
- { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_preamble" },
- { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- 0, "set_ibssport" },
- { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
- "get_ibssport" },
- { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
- "get_rid" },
-};
-
-
-/*
- * Structures to export the Wireless Handlers
- */
-
-#define STD_IW_HANDLER(id, func) \
- [IW_IOCTL_IDX(id)] = (iw_handler) func
-static const iw_handler orinoco_handler[] = {
- STD_IW_HANDLER(SIOCSIWCOMMIT, orinoco_ioctl_commit),
- STD_IW_HANDLER(SIOCGIWNAME, orinoco_ioctl_getname),
- STD_IW_HANDLER(SIOCSIWFREQ, orinoco_ioctl_setfreq),
- STD_IW_HANDLER(SIOCGIWFREQ, orinoco_ioctl_getfreq),
- STD_IW_HANDLER(SIOCSIWMODE, orinoco_ioctl_setmode),
- STD_IW_HANDLER(SIOCGIWMODE, orinoco_ioctl_getmode),
- STD_IW_HANDLER(SIOCSIWSENS, orinoco_ioctl_setsens),
- STD_IW_HANDLER(SIOCGIWSENS, orinoco_ioctl_getsens),
- STD_IW_HANDLER(SIOCGIWRANGE, orinoco_ioctl_getiwrange),
- STD_IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
- STD_IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
- STD_IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
- STD_IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
- STD_IW_HANDLER(SIOCSIWAP, orinoco_ioctl_setwap),
- STD_IW_HANDLER(SIOCGIWAP, orinoco_ioctl_getwap),
- STD_IW_HANDLER(SIOCSIWSCAN, orinoco_ioctl_setscan),
- STD_IW_HANDLER(SIOCGIWSCAN, orinoco_ioctl_getscan),
- STD_IW_HANDLER(SIOCSIWESSID, orinoco_ioctl_setessid),
- STD_IW_HANDLER(SIOCGIWESSID, orinoco_ioctl_getessid),
- STD_IW_HANDLER(SIOCSIWNICKN, orinoco_ioctl_setnick),
- STD_IW_HANDLER(SIOCGIWNICKN, orinoco_ioctl_getnick),
- STD_IW_HANDLER(SIOCSIWRATE, orinoco_ioctl_setrate),
- STD_IW_HANDLER(SIOCGIWRATE, orinoco_ioctl_getrate),
- STD_IW_HANDLER(SIOCSIWRTS, orinoco_ioctl_setrts),
- STD_IW_HANDLER(SIOCGIWRTS, orinoco_ioctl_getrts),
- STD_IW_HANDLER(SIOCSIWFRAG, orinoco_ioctl_setfrag),
- STD_IW_HANDLER(SIOCGIWFRAG, orinoco_ioctl_getfrag),
- STD_IW_HANDLER(SIOCGIWRETRY, orinoco_ioctl_getretry),
- STD_IW_HANDLER(SIOCSIWENCODE, orinoco_ioctl_setiwencode),
- STD_IW_HANDLER(SIOCGIWENCODE, orinoco_ioctl_getiwencode),
- STD_IW_HANDLER(SIOCSIWPOWER, orinoco_ioctl_setpower),
- STD_IW_HANDLER(SIOCGIWPOWER, orinoco_ioctl_getpower),
- STD_IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie),
- STD_IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie),
- STD_IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme),
- STD_IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth),
- STD_IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth),
- STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
- STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
-};
-
-
-/*
- Added typecasting since we no longer use iwreq_data -- Moustafa
- */
-static const iw_handler orinoco_private_handler[] = {
- [0] = (iw_handler) orinoco_ioctl_reset,
- [1] = (iw_handler) orinoco_ioctl_reset,
- [2] = (iw_handler) orinoco_ioctl_setport3,
- [3] = (iw_handler) orinoco_ioctl_getport3,
- [4] = (iw_handler) orinoco_ioctl_setpreamble,
- [5] = (iw_handler) orinoco_ioctl_getpreamble,
- [6] = (iw_handler) orinoco_ioctl_setibssport,
- [7] = (iw_handler) orinoco_ioctl_getibssport,
- [9] = (iw_handler) orinoco_ioctl_getrid,
-};
-
-static const struct iw_handler_def orinoco_handler_def = {
- .num_standard = ARRAY_SIZE(orinoco_handler),
- .num_private = ARRAY_SIZE(orinoco_private_handler),
- .num_private_args = ARRAY_SIZE(orinoco_privtab),
- .standard = orinoco_handler,
- .private = orinoco_private_handler,
- .private_args = orinoco_privtab,
- .get_wireless_stats = orinoco_get_wireless_stats,
-};
-
-static void orinoco_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- struct orinoco_private *priv = netdev_priv(dev);
-
- strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
- strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
- strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
- if (dev->dev.parent)
- strncpy(info->bus_info, dev_name(dev->dev.parent),
- sizeof(info->bus_info) - 1);
- else
- snprintf(info->bus_info, sizeof(info->bus_info) - 1,
- "PCMCIA %p", priv->hw.iobase);
-}
-
-static const struct ethtool_ops orinoco_ethtool_ops = {
- .get_drvinfo = orinoco_get_drvinfo,
- .get_link = ethtool_op_get_link,
-};
-
-/********************************************************************/
-/* Module initialization */
-/********************************************************************/
-
-EXPORT_SYMBOL(alloc_orinocodev);
-EXPORT_SYMBOL(free_orinocodev);
-
-EXPORT_SYMBOL(__orinoco_up);
-EXPORT_SYMBOL(__orinoco_down);
-EXPORT_SYMBOL(orinoco_reinit_firmware);
-
-EXPORT_SYMBOL(orinoco_interrupt);
-
-/* Can't be declared "const" or the whole __initdata section will
- * become const */
-static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
- " (David Gibson <hermes@gibson.dropbear.id.au>, "
- "Pavel Roskin <proski@gnu.org>, et al)";
-
-static int __init init_orinoco(void)
-{
- printk(KERN_DEBUG "%s\n", version);
- return 0;
-}
-
-static void __exit exit_orinoco(void)
-{
-}
-
-module_init(init_orinoco);
-module_exit(exit_orinoco);
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 00750c8ba7db..8e5a72cc297f 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -1,5 +1,5 @@
/* orinoco.h
- *
+ *
* Common definitions to all pieces of the various orinoco
* drivers
*/
@@ -18,9 +18,9 @@
#include "hermes.h"
/* To enable debug messages */
-//#define ORINOCO_DEBUG 3
+/*#define ORINOCO_DEBUG 3*/
-#define WIRELESS_SPY // enable iwspy support
+#define WIRELESS_SPY /* enable iwspy support */
#define MAX_SCAN_LEN 4096
@@ -59,14 +59,6 @@ struct xbss_element {
struct list_head list;
};
-struct hermes_rx_descriptor;
-
-struct orinoco_rx_data {
- struct hermes_rx_descriptor *desc;
- struct sk_buff *skb;
- struct list_head list;
-};
-
struct firmware;
struct orinoco_private {
@@ -83,7 +75,6 @@ struct orinoco_private {
/* Interrupt tasklets */
struct tasklet_struct rx_tasklet;
struct list_head rx_list;
- struct orinoco_rx_data *rx_data;
/* driver state */
int open;
@@ -130,7 +121,7 @@ struct orinoco_private {
u16 encode_alg, wep_restrict, tx_key;
struct orinoco_key keys[ORINOCO_MAX_KEYS];
int bitratemode;
- char nick[IW_ESSID_MAX_SIZE+1];
+ char nick[IW_ESSID_MAX_SIZE+1];
char desired_essid[IW_ESSID_MAX_SIZE+1];
char desired_bssid[ETH_ALEN];
int bssid_fixed;
@@ -140,7 +131,7 @@ struct orinoco_private {
u16 pm_on, pm_mcast, pm_period, pm_timeout;
u16 preamble;
#ifdef WIRELESS_SPY
- struct iw_spy_data spy_data; /* iwspy support */
+ struct iw_spy_data spy_data; /* iwspy support */
struct iw_public_data wireless_data;
#endif
@@ -168,16 +159,21 @@ struct orinoco_private {
unsigned int tkip_cm_active:1;
unsigned int key_mgmt:3;
+#if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
/* Cached in memory firmware to use during ->resume. */
const struct firmware *cached_pri_fw;
const struct firmware *cached_fw;
+#endif
struct notifier_block pm_notifier;
};
#ifdef ORINOCO_DEBUG
extern int orinoco_debug;
-#define DEBUG(n, args...) do { if (orinoco_debug>(n)) printk(KERN_DEBUG args); } while(0)
+#define DEBUG(n, args...) do { \
+ if (orinoco_debug > (n)) \
+ printk(KERN_DEBUG args); \
+} while (0)
#else
#define DEBUG(n, args...) do { } while (0)
#endif /* ORINOCO_DEBUG */
@@ -194,7 +190,7 @@ extern void free_orinocodev(struct net_device *dev);
extern int __orinoco_up(struct net_device *dev);
extern int __orinoco_down(struct net_device *dev);
extern int orinoco_reinit_firmware(struct net_device *dev);
-extern irqreturn_t orinoco_interrupt(int irq, void * dev_id);
+extern irqreturn_t orinoco_interrupt(int irq, void *dev_id);
/********************************************************************/
/* Locking and synchronization functions */
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index 0b32215d3f5d..b381aed24d73 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -6,8 +6,8 @@
* It should also be usable on various Prism II based cards such as the
* Linksys, D-Link and Farallon Skyline. It should also work on Symbol
* cards such as the 3Com AirConnect and Ericsson WLAN.
- *
- * Copyright notice & release notes in file orinoco.c
+ *
+ * Copyright notice & release notes in file main.c
*/
#define DRIVER_NAME "orinoco_cs"
@@ -30,7 +30,8 @@
/********************************************************************/
MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
-MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards");
+MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco,"
+ " Prism II based and similar wireless cards");
MODULE_LICENSE("Dual MPL/GPL");
/* Module parameters */
@@ -53,8 +54,8 @@ struct orinoco_pccard {
/* Used to handle hard reset */
/* yuck, we need this hack to work around the insanity of the
- * PCMCIA layer */
- unsigned long hard_reset_in_progress;
+ * PCMCIA layer */
+ unsigned long hard_reset_in_progress;
};
@@ -98,7 +99,7 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)
* This creates an "instance" of the driver, allocating local data
* structures for one device. The device is registered with Card
* Services.
- *
+ *
* The dev_link structure is initialized, but we don't actually
* configure the card at this point -- we wait until we receive a card
* insertion event. */
@@ -111,7 +112,7 @@ orinoco_cs_probe(struct pcmcia_device *link)
dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
orinoco_cs_hard_reset, NULL);
- if (! dev)
+ if (!dev)
return -ENOMEM;
priv = netdev_priv(dev);
card = priv->card;
@@ -124,7 +125,7 @@ orinoco_cs_probe(struct pcmcia_device *link)
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = orinoco_interrupt;
- link->irq.Instance = dev;
+ link->irq.Instance = dev;
/* General socket configuration defaults can go here. In this
* client, we assume very little, and rely on the CIS for
@@ -162,8 +163,10 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
*/
#define CS_CHECK(fn, ret) do { \
- last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \
- } while (0)
+ last_fn = (fn); \
+ if ((last_ret = (ret)) != 0) \
+ goto cs_failed; \
+} while (0)
static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
cistpl_cftable_entry_t *cfg,
@@ -307,8 +310,8 @@ orinoco_cs_config(struct pcmcia_device *link)
* initialized and arranged in a linked list at link->dev_node. */
strcpy(card->node.dev_name, dev->name);
link->dev_node = &card->node; /* link->dev_node being non-NULL is also
- used to indicate that the
- net_device has been registered */
+ * used to indicate that the
+ * net_device has been registered */
/* Finally, report what we've done */
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
@@ -359,7 +362,7 @@ static int orinoco_cs_suspend(struct pcmcia_device *link)
/* This is probably racy, but I can't think of
a better way, short of rewriting the PCMCIA
layer to not suck :-( */
- if (! test_bit(0, &card->hard_reset_in_progress)) {
+ if (!test_bit(0, &card->hard_reset_in_progress)) {
spin_lock_irqsave(&priv->lock, flags);
err = __orinoco_down(dev);
@@ -384,7 +387,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
int err = 0;
unsigned long flags;
- if (! test_bit(0, &card->hard_reset_in_progress)) {
+ if (!test_bit(0, &card->hard_reset_in_progress)) {
err = orinoco_reinit_firmware(dev);
if (err) {
printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
@@ -397,7 +400,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
netif_device_attach(dev);
priv->hw_unavailable--;
- if (priv->open && ! priv->hw_unavailable) {
+ if (priv->open && !priv->hw_unavailable) {
err = __orinoco_up(dev);
if (err)
printk(KERN_ERR "%s: Error %d restarting card\n",
diff --git a/drivers/net/wireless/orinoco/orinoco_nortel.c b/drivers/net/wireless/orinoco/orinoco_nortel.c
index 2fc86596302e..b01726255c6f 100644
--- a/drivers/net/wireless/orinoco/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco/orinoco_nortel.c
@@ -9,12 +9,12 @@
*
* Some of this code is borrowed from orinoco_plx.c
* Copyright (C) 2001 Daniel Barlow
- * Some of this code is borrowed from orinoco_pci.c
+ * Some of this code is borrowed from orinoco_pci.c
* Copyright (C) 2001 Jean Tourrilhes
* Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
* has been copied from it. linux-wlan-ng-0.1.10 is originally :
* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
- *
+ *
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License
@@ -103,9 +103,8 @@ static int orinoco_nortel_hw_init(struct orinoco_pci_card *card)
iowrite16(0x8, card->bridge_io + 2);
for (i = 0; i < 30; i++) {
mdelay(30);
- if (ioread16(card->bridge_io) & 0x10) {
+ if (ioread16(card->bridge_io) & 0x10)
break;
- }
}
if (i == 30) {
printk(KERN_ERR PFX "brg1 timed out\n");
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c
index 4ebd638a073e..78cafff1fb2e 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco/orinoco_pci.c
@@ -1,5 +1,5 @@
/* orinoco_pci.c
- *
+ *
* Driver for Prism 2.5/3 devices that have a direct PCI interface
* (i.e. these are not PCMCIA cards in a PCMCIA-to-PCI bridge).
* The card contains only one PCI region, which contains all the usual
@@ -237,7 +237,8 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
" (Pavel Roskin <proski@gnu.org>,"
" David Gibson <hermes@gibson.dropbear.id.au> &"
" Jean Tourrilhes <jt@hpl.hp.com>)";
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> &"
+ " David Gibson <hermes@gibson.dropbear.id.au>");
MODULE_DESCRIPTION("Driver for wireless LAN cards using direct PCI interface");
MODULE_LICENSE("Dual MPL/GPL");
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.h b/drivers/net/wireless/orinoco/orinoco_pci.h
index f4e5e06760c1..c655b4a3de16 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.h
+++ b/drivers/net/wireless/orinoco/orinoco_pci.h
@@ -1,10 +1,10 @@
/* orinoco_pci.h
- *
+ *
* Common code for all Orinoco drivers for PCI devices, including
* both native PCI and PCMCIA-to-PCI bridges.
*
* Copyright (C) 2005, Pavel Roskin.
- * See orinoco.c for license.
+ * See main.c for license.
*/
#ifndef _ORINOCO_PCI_H
@@ -37,11 +37,11 @@ static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
if (err)
printk(KERN_WARNING "%s: error %d bringing interface down "
"for suspend\n", dev->name, err);
-
+
netif_device_detach(dev);
priv->hw_unavailable++;
-
+
orinoco_unlock(priv, &flags);
free_irq(pdev->irq, dev);
@@ -90,13 +90,13 @@ static int orinoco_pci_resume(struct pci_dev *pdev)
priv->hw_unavailable--;
- if (priv->open && (! priv->hw_unavailable)) {
+ if (priv->open && (!priv->hw_unavailable)) {
err = __orinoco_up(dev);
if (err)
printk(KERN_ERR "%s: Error %d restarting card on resume\n",
dev->name, err);
}
-
+
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
diff --git a/drivers/net/wireless/orinoco/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c
index ef761857bb38..a2a4471c0337 100644
--- a/drivers/net/wireless/orinoco/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco/orinoco_plx.c
@@ -146,9 +146,8 @@ static int orinoco_plx_hw_init(struct orinoco_pci_card *card)
};
printk(KERN_DEBUG PFX "CIS: ");
- for (i = 0; i < 16; i++) {
+ for (i = 0; i < 16; i++)
printk("%02X:", ioread8(card->attr_io + (i << 1)));
- }
printk("\n");
/* Verify whether a supported PC card is present */
diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c
index ede24ec309c0..cda0e6e4d7a1 100644
--- a/drivers/net/wireless/orinoco/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco/orinoco_tmd.c
@@ -1,7 +1,7 @@
/* orinoco_tmd.c
*
* Driver for Prism II devices which would usually be driven by orinoco_cs,
- * but are connected to the PCI bus by a TMD7160.
+ * but are connected to the PCI bus by a TMD7160.
*
* Copyright (C) 2003 Joerg Dorchain <joerg AT dorchain.net>
* based heavily upon orinoco_plx.c Copyright (C) 2001 Daniel Barlow
@@ -27,7 +27,7 @@
* provisions above, a recipient may use your version of this file
* under either the MPL or the GPL.
*
- * The actual driving is done by orinoco.c, this is just resource
+ * The actual driving is done by main.c, this is just resource
* allocation stuff.
*
* This driver is modeled after the orinoco_plx driver. The main
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c
new file mode 100644
index 000000000000..89d699d4dfe6
--- /dev/null
+++ b/drivers/net/wireless/orinoco/scan.c
@@ -0,0 +1,233 @@
+/* Helpers for managing scan queues
+ *
+ * See copyright notice in main.c
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/etherdevice.h>
+
+#include "hermes.h"
+#include "orinoco.h"
+
+#include "scan.h"
+
+#define ORINOCO_MAX_BSS_COUNT 64
+
+#define PRIV_BSS ((struct bss_element *)priv->bss_xbss_data)
+#define PRIV_XBSS ((struct xbss_element *)priv->bss_xbss_data)
+
+int orinoco_bss_data_allocate(struct orinoco_private *priv)
+{
+ if (priv->bss_xbss_data)
+ return 0;
+
+ if (priv->has_ext_scan)
+ priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
+ sizeof(struct xbss_element),
+ GFP_KERNEL);
+ else
+ priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
+ sizeof(struct bss_element),
+ GFP_KERNEL);
+
+ if (!priv->bss_xbss_data) {
+ printk(KERN_WARNING "Out of memory allocating beacons");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+void orinoco_bss_data_free(struct orinoco_private *priv)
+{
+ kfree(priv->bss_xbss_data);
+ priv->bss_xbss_data = NULL;
+}
+
+void orinoco_bss_data_init(struct orinoco_private *priv)
+{
+ int i;
+
+ INIT_LIST_HEAD(&priv->bss_free_list);
+ INIT_LIST_HEAD(&priv->bss_list);
+ if (priv->has_ext_scan)
+ for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
+ list_add_tail(&(PRIV_XBSS[i].list),
+ &priv->bss_free_list);
+ else
+ for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
+ list_add_tail(&(PRIV_BSS[i].list),
+ &priv->bss_free_list);
+
+}
+
+void orinoco_clear_scan_results(struct orinoco_private *priv,
+ unsigned long scan_age)
+{
+ if (priv->has_ext_scan) {
+ struct xbss_element *bss;
+ struct xbss_element *tmp_bss;
+
+ /* Blow away current list of scan results */
+ list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
+ if (!scan_age ||
+ time_after(jiffies, bss->last_scanned + scan_age)) {
+ list_move_tail(&bss->list,
+ &priv->bss_free_list);
+ /* Don't blow away ->list, just BSS data */
+ memset(&bss->bss, 0, sizeof(bss->bss));
+ bss->last_scanned = 0;
+ }
+ }
+ } else {
+ struct bss_element *bss;
+ struct bss_element *tmp_bss;
+
+ /* Blow away current list of scan results */
+ list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
+ if (!scan_age ||
+ time_after(jiffies, bss->last_scanned + scan_age)) {
+ list_move_tail(&bss->list,
+ &priv->bss_free_list);
+ /* Don't blow away ->list, just BSS data */
+ memset(&bss->bss, 0, sizeof(bss->bss));
+ bss->last_scanned = 0;
+ }
+ }
+ }
+}
+
+void orinoco_add_ext_scan_result(struct orinoco_private *priv,
+ struct agere_ext_scan_info *atom)
+{
+ struct xbss_element *bss = NULL;
+ int found = 0;
+
+ /* Try to update an existing bss first */
+ list_for_each_entry(bss, &priv->bss_list, list) {
+ if (compare_ether_addr(bss->bss.bssid, atom->bssid))
+ continue;
+ /* ESSID lengths */
+ if (bss->bss.data[1] != atom->data[1])
+ continue;
+ if (memcmp(&bss->bss.data[2], &atom->data[2],
+ atom->data[1]))
+ continue;
+ found = 1;
+ break;
+ }
+
+ /* Grab a bss off the free list */
+ if (!found && !list_empty(&priv->bss_free_list)) {
+ bss = list_entry(priv->bss_free_list.next,
+ struct xbss_element, list);
+ list_del(priv->bss_free_list.next);
+
+ list_add_tail(&bss->list, &priv->bss_list);
+ }
+
+ if (bss) {
+ /* Always update the BSS to get latest beacon info */
+ memcpy(&bss->bss, atom, sizeof(bss->bss));
+ bss->last_scanned = jiffies;
+ }
+}
+
+int orinoco_process_scan_results(struct orinoco_private *priv,
+ unsigned char *buf,
+ int len)
+{
+ int offset; /* In the scan data */
+ union hermes_scan_info *atom;
+ int atom_len;
+
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_AGERE:
+ atom_len = sizeof(struct agere_scan_apinfo);
+ offset = 0;
+ break;
+ case FIRMWARE_TYPE_SYMBOL:
+ /* Lack of documentation necessitates this hack.
+ * Different firmwares have 68 or 76 byte long atoms.
+ * We try modulo first. If the length divides by both,
+ * we check what would be the channel in the second
+ * frame for a 68-byte atom. 76-byte atoms have 0 there.
+ * Valid channel cannot be 0. */
+ if (len % 76)
+ atom_len = 68;
+ else if (len % 68)
+ atom_len = 76;
+ else if (len >= 1292 && buf[68] == 0)
+ atom_len = 76;
+ else
+ atom_len = 68;
+ offset = 0;
+ break;
+ case FIRMWARE_TYPE_INTERSIL:
+ offset = 4;
+ if (priv->has_hostscan) {
+ atom_len = le16_to_cpup((__le16 *)buf);
+ /* Sanity check for atom_len */
+ if (atom_len < sizeof(struct prism2_scan_apinfo)) {
+ printk(KERN_ERR "%s: Invalid atom_len in scan "
+ "data: %d\n", priv->ndev->name,
+ atom_len);
+ return -EIO;
+ }
+ } else
+ atom_len = offsetof(struct prism2_scan_apinfo, atim);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ /* Check that we got an whole number of atoms */
+ if ((len - offset) % atom_len) {
+ printk(KERN_ERR "%s: Unexpected scan data length %d, "
+ "atom_len %d, offset %d\n", priv->ndev->name, len,
+ atom_len, offset);
+ return -EIO;
+ }
+
+ orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
+
+ /* Read the entries one by one */
+ for (; offset + atom_len <= len; offset += atom_len) {
+ int found = 0;
+ struct bss_element *bss = NULL;
+
+ /* Get next atom */
+ atom = (union hermes_scan_info *) (buf + offset);
+
+ /* Try to update an existing bss first */
+ list_for_each_entry(bss, &priv->bss_list, list) {
+ if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
+ continue;
+ if (le16_to_cpu(bss->bss.a.essid_len) !=
+ le16_to_cpu(atom->a.essid_len))
+ continue;
+ if (memcmp(bss->bss.a.essid, atom->a.essid,
+ le16_to_cpu(atom->a.essid_len)))
+ continue;
+ found = 1;
+ break;
+ }
+
+ /* Grab a bss off the free list */
+ if (!found && !list_empty(&priv->bss_free_list)) {
+ bss = list_entry(priv->bss_free_list.next,
+ struct bss_element, list);
+ list_del(priv->bss_free_list.next);
+
+ list_add_tail(&bss->list, &priv->bss_list);
+ }
+
+ if (bss) {
+ /* Always update the BSS to get latest beacon info */
+ memcpy(&bss->bss, atom, sizeof(bss->bss));
+ bss->last_scanned = jiffies;
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/net/wireless/orinoco/scan.h b/drivers/net/wireless/orinoco/scan.h
new file mode 100644
index 000000000000..f319f7466af1
--- /dev/null
+++ b/drivers/net/wireless/orinoco/scan.h
@@ -0,0 +1,29 @@
+/* Helpers for managing scan queues
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_SCAN_H_
+#define _ORINOCO_SCAN_H_
+
+/* Forward declarations */
+struct orinoco_private;
+struct agere_ext_scan_info;
+
+/* Setup and free memory for scan results */
+int orinoco_bss_data_allocate(struct orinoco_private *priv);
+void orinoco_bss_data_free(struct orinoco_private *priv);
+void orinoco_bss_data_init(struct orinoco_private *priv);
+
+/* Add scan results */
+void orinoco_add_ext_scan_result(struct orinoco_private *priv,
+ struct agere_ext_scan_info *atom);
+int orinoco_process_scan_results(struct orinoco_private *dev,
+ unsigned char *buf,
+ int len);
+
+/* Clear scan results */
+void orinoco_clear_scan_results(struct orinoco_private *priv,
+ unsigned long scan_age);
+
+
+#endif /* _ORINOCO_SCAN_H_ */
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index b2ca2e39c2cb..38e5198e44c7 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -4,7 +4,7 @@
* Communications and Intel PRO/Wireless 2011B.
*
* The driver implements Symbol firmware download. The rest is handled
- * in hermes.c and orinoco.c.
+ * in hermes.c and main.c.
*
* Utilities for downloading the Symbol firmware are available at
* http://sourceforge.net/projects/orinoco/
@@ -15,7 +15,7 @@
* Portions based on Spectrum24tDnld.c from original spectrum24 driver:
* Copyright (C) Symbol Technologies.
*
- * See copyright notice in file orinoco.c.
+ * See copyright notice in file main.c.
*/
#define DRIVER_NAME "spectrum_cs"
@@ -133,7 +133,7 @@ spectrum_reset(struct pcmcia_device *link, int idle)
udelay(1000);
return 0;
- cs_failed:
+cs_failed:
cs_error(link, last_fn, last_ret);
return -ENODEV;
}
@@ -171,7 +171,7 @@ spectrum_cs_stop_firmware(struct orinoco_private *priv, int idle)
* This creates an "instance" of the driver, allocating local data
* structures for one device. The device is registered with Card
* Services.
- *
+ *
* The dev_link structure is initialized, but we don't actually
* configure the card at this point -- we wait until we receive a card
* insertion event. */
@@ -185,7 +185,7 @@ spectrum_cs_probe(struct pcmcia_device *link)
dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
spectrum_cs_hard_reset,
spectrum_cs_stop_firmware);
- if (! dev)
+ if (!dev)
return -ENOMEM;
priv = netdev_priv(dev);
card = priv->card;
@@ -198,7 +198,7 @@ spectrum_cs_probe(struct pcmcia_device *link)
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
link->irq.Handler = orinoco_interrupt;
- link->irq.Instance = dev;
+ link->irq.Instance = dev;
/* General socket configuration defaults can go here. In this
* client, we assume very little, and rely on the CIS for
@@ -367,9 +367,8 @@ spectrum_cs_config(struct pcmcia_device *link)
card->node.major = card->node.minor = 0;
/* Reset card */
- if (spectrum_cs_hard_reset(priv) != 0) {
+ if (spectrum_cs_hard_reset(priv) != 0)
goto failed;
- }
SET_NETDEV_DEV(dev, &handle_to_dev(link));
/* Tell the stack we exist */
@@ -382,8 +381,8 @@ spectrum_cs_config(struct pcmcia_device *link)
* initialized and arranged in a linked list at link->dev_node. */
strcpy(card->node.dev_name, dev->name);
link->dev_node = &card->node; /* link->dev_node being non-NULL is also
- used to indicate that the
- net_device has been registered */
+ * used to indicate that the
+ * net_device has been registered */
/* Finally, report what we've done */
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
new file mode 100644
index 000000000000..3f0814234392
--- /dev/null
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -0,0 +1,2325 @@
+/* Wireless extensions support.
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/kernel.h>
+#include <linux/if_arp.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <net/iw_handler.h>
+
+#include "hermes.h"
+#include "hermes_rid.h"
+#include "orinoco.h"
+
+#include "hw.h"
+#include "mic.h"
+#include "scan.h"
+#include "main.h"
+
+#include "wext.h"
+
+#define MAX_RID_LEN 1024
+
+static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ struct iw_statistics *wstats = &priv->wstats;
+ int err;
+ unsigned long flags;
+
+ if (!netif_device_present(dev)) {
+ printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
+ dev->name);
+ return NULL; /* FIXME: Can we do better than this? */
+ }
+
+ /* If busy, return the old stats. Returning NULL may cause
+ * the interface to disappear from /proc/net/wireless */
+ if (orinoco_lock(priv, &flags) != 0)
+ return wstats;
+
+ /* We can't really wait for the tallies inquiry command to
+ * complete, so we just use the previous results and trigger
+ * a new tallies inquiry command for next time - Jean II */
+ /* FIXME: Really we should wait for the inquiry to come back -
+ * as it is the stats we give don't make a whole lot of sense.
+ * Unfortunately, it's not clear how to do that within the
+ * wireless extensions framework: I think we're in user
+ * context, but a lock seems to be held by the time we get in
+ * here so we're not safe to sleep here. */
+ hermes_inquire(hw, HERMES_INQ_TALLIES);
+
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ memset(&wstats->qual, 0, sizeof(wstats->qual));
+ /* If a spy address is defined, we report stats of the
+ * first spy address - Jean II */
+ if (SPY_NUMBER(priv)) {
+ wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
+ wstats->qual.level = priv->spy_data.spy_stat[0].level;
+ wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
+ wstats->qual.updated =
+ priv->spy_data.spy_stat[0].updated;
+ }
+ } else {
+ struct {
+ __le16 qual, signal, noise, unused;
+ } __attribute__ ((packed)) cq;
+
+ err = HERMES_READ_RECORD(hw, USER_BAP,
+ HERMES_RID_COMMSQUALITY, &cq);
+
+ if (!err) {
+ wstats->qual.qual = (int)le16_to_cpu(cq.qual);
+ wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
+ wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
+ wstats->qual.updated =
+ IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+ }
+ }
+
+ orinoco_unlock(priv, &flags);
+ return wstats;
+}
+
+/********************************************************************/
+/* Wireless extensions */
+/********************************************************************/
+
+static int orinoco_ioctl_getname(struct net_device *dev,
+ struct iw_request_info *info,
+ char *name,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int numrates;
+ int err;
+
+ err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
+
+ if (!err && (numrates > 2))
+ strcpy(name, "IEEE 802.11b");
+ else
+ strcpy(name, "IEEE 802.11-DS");
+
+ return 0;
+}
+
+static int orinoco_ioctl_setwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = -EINPROGRESS; /* Call commit handler */
+ unsigned long flags;
+ static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ /* Enable automatic roaming - no sanity checks are needed */
+ if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
+ memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
+ priv->bssid_fixed = 0;
+ memset(priv->desired_bssid, 0, ETH_ALEN);
+
+ /* "off" means keep existing connection */
+ if (ap_addr->sa_data[0] == 0) {
+ __orinoco_hw_set_wap(priv);
+ err = 0;
+ }
+ goto out;
+ }
+
+ if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
+ printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
+ "support manual roaming\n",
+ dev->name);
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (priv->iw_mode != IW_MODE_INFRA) {
+ printk(KERN_WARNING "%s: Manual roaming supported only in "
+ "managed mode\n", dev->name);
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ /* Intersil firmware hangs without Desired ESSID */
+ if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
+ strlen(priv->desired_essid) == 0) {
+ printk(KERN_WARNING "%s: Desired ESSID must be set for "
+ "manual roaming\n", dev->name);
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ /* Finally, enable manual roaming */
+ priv->bssid_fixed = 1;
+ memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
+
+ out:
+ orinoco_unlock(priv, &flags);
+ return err;
+}
+
+static int orinoco_ioctl_getwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ ap_addr->sa_family = ARPHRD_ETHER;
+ err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
+ ETH_ALEN, NULL, ap_addr->sa_data);
+
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_setmode(struct net_device *dev,
+ struct iw_request_info *info,
+ u32 *mode,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = -EINPROGRESS; /* Call commit handler */
+ unsigned long flags;
+
+ if (priv->iw_mode == *mode)
+ return 0;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ switch (*mode) {
+ case IW_MODE_ADHOC:
+ if (!priv->has_ibss && !priv->has_port3)
+ err = -EOPNOTSUPP;
+ break;
+
+ case IW_MODE_INFRA:
+ break;
+
+ case IW_MODE_MONITOR:
+ if (priv->broken_monitor && !force_monitor) {
+ printk(KERN_WARNING "%s: Monitor mode support is "
+ "buggy in this firmware, not enabling\n",
+ dev->name);
+ err = -EOPNOTSUPP;
+ }
+ break;
+
+ default:
+ err = -EOPNOTSUPP;
+ break;
+ }
+
+ if (err == -EINPROGRESS) {
+ priv->iw_mode = *mode;
+ set_port_type(priv);
+ }
+
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_getmode(struct net_device *dev,
+ struct iw_request_info *info,
+ u32 *mode,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ *mode = priv->iw_mode;
+ return 0;
+}
+
+static int orinoco_ioctl_getiwrange(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *rrq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = 0;
+ struct iw_range *range = (struct iw_range *) extra;
+ int numrates;
+ int i, k;
+
+ rrq->length = sizeof(struct iw_range);
+ memset(range, 0, sizeof(struct iw_range));
+
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = 22;
+
+ /* Set available channels/frequencies */
+ range->num_channels = NUM_CHANNELS;
+ k = 0;
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ if (priv->channel_mask & (1 << i)) {
+ range->freq[k].i = i + 1;
+ range->freq[k].m = (ieee80211_dsss_chan_to_freq(i + 1) *
+ 100000);
+ range->freq[k].e = 1;
+ k++;
+ }
+
+ if (k >= IW_MAX_FREQUENCIES)
+ break;
+ }
+ range->num_frequency = k;
+ range->sensitivity = 3;
+
+ if (priv->has_wep) {
+ range->max_encoding_tokens = ORINOCO_MAX_KEYS;
+ range->encoding_size[0] = SMALL_KEY_SIZE;
+ range->num_encoding_sizes = 1;
+
+ if (priv->has_big_wep) {
+ range->encoding_size[1] = LARGE_KEY_SIZE;
+ range->num_encoding_sizes = 2;
+ }
+ }
+
+ if (priv->has_wpa)
+ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
+
+ if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))) {
+ /* Quality stats meaningless in ad-hoc mode */
+ } else {
+ range->max_qual.qual = 0x8b - 0x2f;
+ range->max_qual.level = 0x2f - 0x95 - 1;
+ range->max_qual.noise = 0x2f - 0x95 - 1;
+ /* Need to get better values */
+ range->avg_qual.qual = 0x24;
+ range->avg_qual.level = 0xC2;
+ range->avg_qual.noise = 0x9E;
+ }
+
+ err = orinoco_hw_get_bitratelist(priv, &numrates,
+ range->bitrate, IW_MAX_BITRATES);
+ if (err)
+ return err;
+ range->num_bitrates = numrates;
+
+ /* Set an indication of the max TCP throughput in bit/s that we can
+ * expect using this interface. May be use for QoS stuff...
+ * Jean II */
+ if (numrates > 2)
+ range->throughput = 5 * 1000 * 1000; /* ~5 Mb/s */
+ else
+ range->throughput = 1.5 * 1000 * 1000; /* ~1.5 Mb/s */
+
+ range->min_rts = 0;
+ range->max_rts = 2347;
+ range->min_frag = 256;
+ range->max_frag = 2346;
+
+ range->min_pmp = 0;
+ range->max_pmp = 65535000;
+ range->min_pmt = 0;
+ range->max_pmt = 65535 * 1000; /* ??? */
+ range->pmp_flags = IW_POWER_PERIOD;
+ range->pmt_flags = IW_POWER_TIMEOUT;
+ range->pm_capa = (IW_POWER_PERIOD | IW_POWER_TIMEOUT |
+ IW_POWER_UNICAST_R);
+
+ range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
+ range->retry_flags = IW_RETRY_LIMIT;
+ range->r_time_flags = IW_RETRY_LIFETIME;
+ range->min_retry = 0;
+ range->max_retry = 65535; /* ??? */
+ range->min_r_time = 0;
+ range->max_r_time = 65535 * 1000; /* ??? */
+
+ if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
+ range->scan_capa = IW_SCAN_CAPA_ESSID;
+ else
+ range->scan_capa = IW_SCAN_CAPA_NONE;
+
+ /* Event capability (kernel) */
+ IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+ /* Event capability (driver) */
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+ IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+ IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
+
+ return 0;
+}
+
+static int orinoco_ioctl_setiwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq,
+ char *keybuf)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int index = (erq->flags & IW_ENCODE_INDEX) - 1;
+ int setindex = priv->tx_key;
+ int encode_alg = priv->encode_alg;
+ int restricted = priv->wep_restrict;
+ u16 xlen = 0;
+ int err = -EINPROGRESS; /* Call commit handler */
+ unsigned long flags;
+
+ if (!priv->has_wep)
+ return -EOPNOTSUPP;
+
+ if (erq->pointer) {
+ /* We actually have a key to set - check its length */
+ if (erq->length > LARGE_KEY_SIZE)
+ return -E2BIG;
+
+ if ((erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep)
+ return -E2BIG;
+ }
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ /* Clear any TKIP key we have */
+ if ((priv->has_wpa) && (priv->encode_alg == IW_ENCODE_ALG_TKIP))
+ (void) orinoco_clear_tkip_key(priv, setindex);
+
+ if (erq->length > 0) {
+ if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
+ index = priv->tx_key;
+
+ /* Adjust key length to a supported value */
+ if (erq->length > SMALL_KEY_SIZE)
+ xlen = LARGE_KEY_SIZE;
+ else if (erq->length > 0)
+ xlen = SMALL_KEY_SIZE;
+ else
+ xlen = 0;
+
+ /* Switch on WEP if off */
+ if ((encode_alg != IW_ENCODE_ALG_WEP) && (xlen > 0)) {
+ setindex = index;
+ encode_alg = IW_ENCODE_ALG_WEP;
+ }
+ } else {
+ /* Important note : if the user do "iwconfig eth0 enc off",
+ * we will arrive there with an index of -1. This is valid
+ * but need to be taken care off... Jean II */
+ if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
+ if ((index != -1) || (erq->flags == 0)) {
+ err = -EINVAL;
+ goto out;
+ }
+ } else {
+ /* Set the index : Check that the key is valid */
+ if (priv->keys[index].len == 0) {
+ err = -EINVAL;
+ goto out;
+ }
+ setindex = index;
+ }
+ }
+
+ if (erq->flags & IW_ENCODE_DISABLED)
+ encode_alg = IW_ENCODE_ALG_NONE;
+ if (erq->flags & IW_ENCODE_OPEN)
+ restricted = 0;
+ if (erq->flags & IW_ENCODE_RESTRICTED)
+ restricted = 1;
+
+ if (erq->pointer && erq->length > 0) {
+ priv->keys[index].len = cpu_to_le16(xlen);
+ memset(priv->keys[index].data, 0,
+ sizeof(priv->keys[index].data));
+ memcpy(priv->keys[index].data, keybuf, erq->length);
+ }
+ priv->tx_key = setindex;
+
+ /* Try fast key change if connected and only keys are changed */
+ if ((priv->encode_alg == encode_alg) &&
+ (priv->wep_restrict == restricted) &&
+ netif_carrier_ok(dev)) {
+ err = __orinoco_hw_setup_wepkeys(priv);
+ /* No need to commit if successful */
+ goto out;
+ }
+
+ priv->encode_alg = encode_alg;
+ priv->wep_restrict = restricted;
+
+ out:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_getiwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq,
+ char *keybuf)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int index = (erq->flags & IW_ENCODE_INDEX) - 1;
+ u16 xlen = 0;
+ unsigned long flags;
+
+ if (!priv->has_wep)
+ return -EOPNOTSUPP;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
+ index = priv->tx_key;
+
+ erq->flags = 0;
+ if (!priv->encode_alg)
+ erq->flags |= IW_ENCODE_DISABLED;
+ erq->flags |= index + 1;
+
+ if (priv->wep_restrict)
+ erq->flags |= IW_ENCODE_RESTRICTED;
+ else
+ erq->flags |= IW_ENCODE_OPEN;
+
+ xlen = le16_to_cpu(priv->keys[index].len);
+
+ erq->length = xlen;
+
+ memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
+
+ orinoco_unlock(priv, &flags);
+ return 0;
+}
+
+static int orinoco_ioctl_setessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq,
+ char *essidbuf)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
+ * anyway... - Jean II */
+
+ /* Hum... Should not use Wireless Extension constant (may change),
+ * should use our own... - Jean II */
+ if (erq->length > IW_ESSID_MAX_SIZE)
+ return -E2BIG;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
+ memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
+
+ /* If not ANY, get the new ESSID */
+ if (erq->flags)
+ memcpy(priv->desired_essid, essidbuf, erq->length);
+
+ orinoco_unlock(priv, &flags);
+
+ return -EINPROGRESS; /* Call commit handler */
+}
+
+static int orinoco_ioctl_getessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq,
+ char *essidbuf)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int active;
+ int err = 0;
+ unsigned long flags;
+
+ if (netif_running(dev)) {
+ err = orinoco_hw_get_essid(priv, &active, essidbuf);
+ if (err < 0)
+ return err;
+ erq->length = err;
+ } else {
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+ memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
+ erq->length = strlen(priv->desired_essid);
+ orinoco_unlock(priv, &flags);
+ }
+
+ erq->flags = 1;
+
+ return 0;
+}
+
+static int orinoco_ioctl_setnick(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *nrq,
+ char *nickbuf)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ if (nrq->length > IW_ESSID_MAX_SIZE)
+ return -E2BIG;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ memset(priv->nick, 0, sizeof(priv->nick));
+ memcpy(priv->nick, nickbuf, nrq->length);
+
+ orinoco_unlock(priv, &flags);
+
+ return -EINPROGRESS; /* Call commit handler */
+}
+
+static int orinoco_ioctl_getnick(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *nrq,
+ char *nickbuf)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
+ orinoco_unlock(priv, &flags);
+
+ nrq->length = strlen(priv->nick);
+
+ return 0;
+}
+
+static int orinoco_ioctl_setfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *frq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int chan = -1;
+ unsigned long flags;
+ int err = -EINPROGRESS; /* Call commit handler */
+
+ /* In infrastructure mode the AP sets the channel */
+ if (priv->iw_mode == IW_MODE_INFRA)
+ return -EBUSY;
+
+ if ((frq->e == 0) && (frq->m <= 1000)) {
+ /* Setting by channel number */
+ chan = frq->m;
+ } else {
+ /* Setting by frequency */
+ int denom = 1;
+ int i;
+
+ /* Calculate denominator to rescale to MHz */
+ for (i = 0; i < (6 - frq->e); i++)
+ denom *= 10;
+
+ chan = ieee80211_freq_to_dsss_chan(frq->m / denom);
+ }
+
+ if ((chan < 1) || (chan > NUM_CHANNELS) ||
+ !(priv->channel_mask & (1 << (chan-1))))
+ return -EINVAL;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ priv->channel = chan;
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ /* Fast channel change - no commit if successful */
+ hermes_t *hw = &priv->hw;
+ err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+ HERMES_TEST_SET_CHANNEL,
+ chan, NULL);
+ }
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_getfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *frq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int tmp;
+
+ /* Locking done in there */
+ tmp = orinoco_hw_get_freq(priv);
+ if (tmp < 0)
+ return tmp;
+
+ frq->m = tmp * 100000;
+ frq->e = 1;
+
+ return 0;
+}
+
+static int orinoco_ioctl_getsens(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *srq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ u16 val;
+ int err;
+ unsigned long flags;
+
+ if (!priv->has_sensitivity)
+ return -EOPNOTSUPP;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFSYSTEMSCALE, &val);
+ orinoco_unlock(priv, &flags);
+
+ if (err)
+ return err;
+
+ srq->value = val;
+ srq->fixed = 0; /* auto */
+
+ return 0;
+}
+
+static int orinoco_ioctl_setsens(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *srq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int val = srq->value;
+ unsigned long flags;
+
+ if (!priv->has_sensitivity)
+ return -EOPNOTSUPP;
+
+ if ((val < 1) || (val > 3))
+ return -EINVAL;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+ priv->ap_density = val;
+ orinoco_unlock(priv, &flags);
+
+ return -EINPROGRESS; /* Call commit handler */
+}
+
+static int orinoco_ioctl_setrts(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int val = rrq->value;
+ unsigned long flags;
+
+ if (rrq->disabled)
+ val = 2347;
+
+ if ((val < 0) || (val > 2347))
+ return -EINVAL;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ priv->rts_thresh = val;
+ orinoco_unlock(priv, &flags);
+
+ return -EINPROGRESS; /* Call commit handler */
+}
+
+static int orinoco_ioctl_getrts(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ rrq->value = priv->rts_thresh;
+ rrq->disabled = (rrq->value == 2347);
+ rrq->fixed = 1;
+
+ return 0;
+}
+
+static int orinoco_ioctl_setfrag(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *frq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = -EINPROGRESS; /* Call commit handler */
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if (priv->has_mwo) {
+ if (frq->disabled)
+ priv->mwo_robust = 0;
+ else {
+ if (frq->fixed)
+ printk(KERN_WARNING "%s: Fixed fragmentation "
+ "is not supported on this firmware. "
+ "Using MWO robust instead.\n",
+ dev->name);
+ priv->mwo_robust = 1;
+ }
+ } else {
+ if (frq->disabled)
+ priv->frag_thresh = 2346;
+ else {
+ if ((frq->value < 256) || (frq->value > 2346))
+ err = -EINVAL;
+ else
+ /* must be even */
+ priv->frag_thresh = frq->value & ~0x1;
+ }
+ }
+
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_getfrag(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *frq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int err;
+ u16 val;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if (priv->has_mwo) {
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMWOROBUST_AGERE,
+ &val);
+ if (err)
+ val = 0;
+
+ frq->value = val ? 2347 : 0;
+ frq->disabled = !val;
+ frq->fixed = 0;
+ } else {
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+ &val);
+ if (err)
+ val = 0;
+
+ frq->value = val;
+ frq->disabled = (val >= 2346);
+ frq->fixed = 1;
+ }
+
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_setrate(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int ratemode;
+ int bitrate; /* 100s of kilobits */
+ unsigned long flags;
+
+ /* As the user space doesn't know our highest rate, it uses -1
+ * to ask us to set the highest rate. Test it using "iwconfig
+ * ethX rate auto" - Jean II */
+ if (rrq->value == -1)
+ bitrate = 110;
+ else {
+ if (rrq->value % 100000)
+ return -EINVAL;
+ bitrate = rrq->value / 100000;
+ }
+
+ ratemode = orinoco_get_bitratemode(bitrate, !rrq->fixed);
+
+ if (ratemode == -1)
+ return -EINVAL;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+ priv->bitratemode = ratemode;
+ orinoco_unlock(priv, &flags);
+
+ return -EINPROGRESS;
+}
+
+static int orinoco_ioctl_getrate(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = 0;
+ int bitrate, automatic;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ orinoco_get_ratemode_cfg(priv->bitratemode, &bitrate, &automatic);
+
+ /* If the interface is running we try to find more about the
+ current mode */
+ if (netif_running(dev))
+ err = orinoco_hw_get_act_bitrate(priv, &bitrate);
+
+ orinoco_unlock(priv, &flags);
+
+ rrq->value = bitrate;
+ rrq->fixed = !automatic;
+ rrq->disabled = 0;
+
+ return err;
+}
+
+static int orinoco_ioctl_setpower(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *prq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = -EINPROGRESS; /* Call commit handler */
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if (prq->disabled) {
+ priv->pm_on = 0;
+ } else {
+ switch (prq->flags & IW_POWER_MODE) {
+ case IW_POWER_UNICAST_R:
+ priv->pm_mcast = 0;
+ priv->pm_on = 1;
+ break;
+ case IW_POWER_ALL_R:
+ priv->pm_mcast = 1;
+ priv->pm_on = 1;
+ break;
+ case IW_POWER_ON:
+ /* No flags : but we may have a value - Jean II */
+ break;
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (prq->flags & IW_POWER_TIMEOUT) {
+ priv->pm_on = 1;
+ priv->pm_timeout = prq->value / 1000;
+ }
+ if (prq->flags & IW_POWER_PERIOD) {
+ priv->pm_on = 1;
+ priv->pm_period = prq->value / 1000;
+ }
+ /* It's valid to not have a value if we are just toggling
+ * the flags... Jean II */
+ if (!priv->pm_on) {
+ err = -EINVAL;
+ goto out;
+ }
+ }
+
+ out:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_getpower(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *prq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ u16 enable, period, timeout, mcast;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPMENABLED, &enable);
+ if (err)
+ goto out;
+
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMAXSLEEPDURATION, &period);
+ if (err)
+ goto out;
+
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
+ if (err)
+ goto out;
+
+ err = hermes_read_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
+ if (err)
+ goto out;
+
+ prq->disabled = !enable;
+ /* Note : by default, display the period */
+ if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+ prq->flags = IW_POWER_TIMEOUT;
+ prq->value = timeout * 1000;
+ } else {
+ prq->flags = IW_POWER_PERIOD;
+ prq->value = period * 1000;
+ }
+ if (mcast)
+ prq->flags |= IW_POWER_ALL_R;
+ else
+ prq->flags |= IW_POWER_UNICAST_R;
+
+ out:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_set_encodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int idx, alg = ext->alg, set_key = 1;
+ unsigned long flags;
+ int err = -EINVAL;
+ u16 key_len;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ /* Determine and validate the key index */
+ idx = encoding->flags & IW_ENCODE_INDEX;
+ if (idx) {
+ if ((idx < 1) || (idx > 4))
+ goto out;
+ idx--;
+ } else
+ idx = priv->tx_key;
+
+ if (encoding->flags & IW_ENCODE_DISABLED)
+ alg = IW_ENCODE_ALG_NONE;
+
+ if (priv->has_wpa && (alg != IW_ENCODE_ALG_TKIP)) {
+ /* Clear any TKIP TX key we had */
+ (void) orinoco_clear_tkip_key(priv, priv->tx_key);
+ }
+
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+ priv->tx_key = idx;
+ set_key = ((alg == IW_ENCODE_ALG_TKIP) ||
+ (ext->key_len > 0)) ? 1 : 0;
+ }
+
+ if (set_key) {
+ /* Set the requested key first */
+ switch (alg) {
+ case IW_ENCODE_ALG_NONE:
+ priv->encode_alg = alg;
+ priv->keys[idx].len = 0;
+ break;
+
+ case IW_ENCODE_ALG_WEP:
+ if (ext->key_len > SMALL_KEY_SIZE)
+ key_len = LARGE_KEY_SIZE;
+ else if (ext->key_len > 0)
+ key_len = SMALL_KEY_SIZE;
+ else
+ goto out;
+
+ priv->encode_alg = alg;
+ priv->keys[idx].len = cpu_to_le16(key_len);
+
+ key_len = min(ext->key_len, key_len);
+
+ memset(priv->keys[idx].data, 0, ORINOCO_MAX_KEY_SIZE);
+ memcpy(priv->keys[idx].data, ext->key, key_len);
+ break;
+
+ case IW_ENCODE_ALG_TKIP:
+ {
+ hermes_t *hw = &priv->hw;
+ u8 *tkip_iv = NULL;
+
+ if (!priv->has_wpa ||
+ (ext->key_len > sizeof(priv->tkip_key[0])))
+ goto out;
+
+ priv->encode_alg = alg;
+ memset(&priv->tkip_key[idx], 0,
+ sizeof(priv->tkip_key[idx]));
+ memcpy(&priv->tkip_key[idx], ext->key, ext->key_len);
+
+ if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
+ tkip_iv = &ext->rx_seq[0];
+
+ err = __orinoco_hw_set_tkip_key(hw, idx,
+ ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
+ (u8 *) &priv->tkip_key[idx],
+ tkip_iv, NULL);
+ if (err)
+ printk(KERN_ERR "%s: Error %d setting TKIP key"
+ "\n", dev->name, err);
+
+ goto out;
+ }
+ default:
+ goto out;
+ }
+ }
+ err = -EINPROGRESS;
+ out:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_get_encodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int idx, max_key_len;
+ unsigned long flags;
+ int err;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = -EINVAL;
+ max_key_len = encoding->length - sizeof(*ext);
+ if (max_key_len < 0)
+ goto out;
+
+ idx = encoding->flags & IW_ENCODE_INDEX;
+ if (idx) {
+ if ((idx < 1) || (idx > 4))
+ goto out;
+ idx--;
+ } else
+ idx = priv->tx_key;
+
+ encoding->flags = idx + 1;
+ memset(ext, 0, sizeof(*ext));
+
+ ext->alg = priv->encode_alg;
+ switch (priv->encode_alg) {
+ case IW_ENCODE_ALG_NONE:
+ ext->key_len = 0;
+ encoding->flags |= IW_ENCODE_DISABLED;
+ break;
+ case IW_ENCODE_ALG_WEP:
+ ext->key_len = min_t(u16, le16_to_cpu(priv->keys[idx].len),
+ max_key_len);
+ memcpy(ext->key, priv->keys[idx].data, ext->key_len);
+ encoding->flags |= IW_ENCODE_ENABLED;
+ break;
+ case IW_ENCODE_ALG_TKIP:
+ ext->key_len = min_t(u16, sizeof(struct orinoco_tkip_key),
+ max_key_len);
+ memcpy(ext->key, &priv->tkip_key[idx], ext->key_len);
+ encoding->flags |= IW_ENCODE_ENABLED;
+ break;
+ }
+
+ err = 0;
+ out:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_set_auth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ struct iw_param *param = &wrqu->param;
+ unsigned long flags;
+ int ret = -EINPROGRESS;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ case IW_AUTH_CIPHER_PAIRWISE:
+ case IW_AUTH_CIPHER_GROUP:
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ case IW_AUTH_PRIVACY_INVOKED:
+ case IW_AUTH_DROP_UNENCRYPTED:
+ /*
+ * orinoco does not use these parameters
+ */
+ break;
+
+ case IW_AUTH_KEY_MGMT:
+ /* wl_lkm implies value 2 == PSK for Hermes I
+ * which ties in with WEXT
+ * no other hints tho :(
+ */
+ priv->key_mgmt = param->value;
+ break;
+
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ /* When countermeasures are enabled, shut down the
+ * card; when disabled, re-enable the card. This must
+ * take effect immediately.
+ *
+ * TODO: Make sure that the EAPOL message is getting
+ * out before card disabled
+ */
+ if (param->value) {
+ priv->tkip_cm_active = 1;
+ ret = hermes_enable_port(hw, 0);
+ } else {
+ priv->tkip_cm_active = 0;
+ ret = hermes_disable_port(hw, 0);
+ }
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ if (param->value & IW_AUTH_ALG_SHARED_KEY)
+ priv->wep_restrict = 1;
+ else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
+ priv->wep_restrict = 0;
+ else
+ ret = -EINVAL;
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ if (priv->has_wpa) {
+ priv->wpa_enabled = param->value ? 1 : 0;
+ } else {
+ if (param->value)
+ ret = -EOPNOTSUPP;
+ /* else silently accept disable of WPA */
+ priv->wpa_enabled = 0;
+ }
+ break;
+
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ orinoco_unlock(priv, &flags);
+ return ret;
+}
+
+static int orinoco_ioctl_get_auth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct iw_param *param = &wrqu->param;
+ unsigned long flags;
+ int ret = 0;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_KEY_MGMT:
+ param->value = priv->key_mgmt;
+ break;
+
+ case IW_AUTH_TKIP_COUNTERMEASURES:
+ param->value = priv->tkip_cm_active;
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ if (priv->wep_restrict)
+ param->value = IW_AUTH_ALG_SHARED_KEY;
+ else
+ param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ param->value = priv->wpa_enabled;
+ break;
+
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ orinoco_unlock(priv, &flags);
+ return ret;
+}
+
+static int orinoco_ioctl_set_genie(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ u8 *buf;
+ unsigned long flags;
+
+ /* cut off at IEEE80211_MAX_DATA_LEN */
+ if ((wrqu->data.length > IEEE80211_MAX_DATA_LEN) ||
+ (wrqu->data.length && (extra == NULL)))
+ return -EINVAL;
+
+ if (wrqu->data.length) {
+ buf = kmalloc(wrqu->data.length, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ memcpy(buf, extra, wrqu->data.length);
+ } else
+ buf = NULL;
+
+ if (orinoco_lock(priv, &flags) != 0) {
+ kfree(buf);
+ return -EBUSY;
+ }
+
+ kfree(priv->wpa_ie);
+ priv->wpa_ie = buf;
+ priv->wpa_ie_len = wrqu->data.length;
+
+ if (priv->wpa_ie) {
+ /* Looks like wl_lkm wants to check the auth alg, and
+ * somehow pass it to the firmware.
+ * Instead it just calls the key mgmt rid
+ * - we do this in set auth.
+ */
+ }
+
+ orinoco_unlock(priv, &flags);
+ return 0;
+}
+
+static int orinoco_ioctl_get_genie(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int err = 0;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if ((priv->wpa_ie_len == 0) || (priv->wpa_ie == NULL)) {
+ wrqu->data.length = 0;
+ goto out;
+ }
+
+ if (wrqu->data.length < priv->wpa_ie_len) {
+ err = -E2BIG;
+ goto out;
+ }
+
+ wrqu->data.length = priv->wpa_ie_len;
+ memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
+
+out:
+ orinoco_unlock(priv, &flags);
+ return err;
+}
+
+static int orinoco_ioctl_set_mlme(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ struct iw_mlme *mlme = (struct iw_mlme *)extra;
+ unsigned long flags;
+ int ret = 0;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ switch (mlme->cmd) {
+ case IW_MLME_DEAUTH:
+ /* silently ignore */
+ break;
+
+ case IW_MLME_DISASSOC:
+ {
+ struct {
+ u8 addr[ETH_ALEN];
+ __le16 reason_code;
+ } __attribute__ ((packed)) buf;
+
+ memcpy(buf.addr, mlme->addr.sa_data, ETH_ALEN);
+ buf.reason_code = cpu_to_le16(mlme->reason_code);
+ ret = HERMES_WRITE_RECORD(hw, USER_BAP,
+ HERMES_RID_CNFDISASSOCIATE,
+ &buf);
+ break;
+ }
+ default:
+ ret = -EOPNOTSUPP;
+ }
+
+ orinoco_unlock(priv, &flags);
+ return ret;
+}
+
+static int orinoco_ioctl_getretry(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int err = 0;
+ u16 short_limit, long_limit, lifetime;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
+ &short_limit);
+ if (err)
+ goto out;
+
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
+ &long_limit);
+ if (err)
+ goto out;
+
+ err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
+ &lifetime);
+ if (err)
+ goto out;
+
+ rrq->disabled = 0; /* Can't be disabled */
+
+ /* Note : by default, display the retry number */
+ if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
+ rrq->flags = IW_RETRY_LIFETIME;
+ rrq->value = lifetime * 1000; /* ??? */
+ } else {
+ /* By default, display the min number */
+ if ((rrq->flags & IW_RETRY_LONG)) {
+ rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
+ rrq->value = long_limit;
+ } else {
+ rrq->flags = IW_RETRY_LIMIT;
+ rrq->value = short_limit;
+ if (short_limit != long_limit)
+ rrq->flags |= IW_RETRY_SHORT;
+ }
+ }
+
+ out:
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_reset(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
+ printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
+
+ /* Firmware reset */
+ orinoco_reset(&priv->reset_work);
+ } else {
+ printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
+
+ schedule_work(&priv->reset_work);
+ }
+
+ return 0;
+}
+
+static int orinoco_ioctl_setibssport(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int val = *((int *) extra);
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ priv->ibss_port = val ;
+
+ /* Actually update the mode we are using */
+ set_port_type(priv);
+
+ orinoco_unlock(priv, &flags);
+ return -EINPROGRESS; /* Call commit handler */
+}
+
+static int orinoco_ioctl_getibssport(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int *val = (int *) extra;
+
+ *val = priv->ibss_port;
+ return 0;
+}
+
+static int orinoco_ioctl_setport3(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int val = *((int *) extra);
+ int err = 0;
+ unsigned long flags;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ switch (val) {
+ case 0: /* Try to do IEEE ad-hoc mode */
+ if (!priv->has_ibss) {
+ err = -EINVAL;
+ break;
+ }
+ priv->prefer_port3 = 0;
+
+ break;
+
+ case 1: /* Try to do Lucent proprietary ad-hoc mode */
+ if (!priv->has_port3) {
+ err = -EINVAL;
+ break;
+ }
+ priv->prefer_port3 = 1;
+ break;
+
+ default:
+ err = -EINVAL;
+ }
+
+ if (!err) {
+ /* Actually update the mode we are using */
+ set_port_type(priv);
+ err = -EINPROGRESS;
+ }
+
+ orinoco_unlock(priv, &flags);
+
+ return err;
+}
+
+static int orinoco_ioctl_getport3(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int *val = (int *) extra;
+
+ *val = priv->prefer_port3;
+ return 0;
+}
+
+static int orinoco_ioctl_setpreamble(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ int val;
+
+ if (!priv->has_preamble)
+ return -EOPNOTSUPP;
+
+ /* 802.11b has recently defined some short preamble.
+ * Basically, the Phy header has been reduced in size.
+ * This increase performance, especially at high rates
+ * (the preamble is transmitted at 1Mb/s), unfortunately
+ * this give compatibility troubles... - Jean II */
+ val = *((int *) extra);
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if (val)
+ priv->preamble = 1;
+ else
+ priv->preamble = 0;
+
+ orinoco_unlock(priv, &flags);
+
+ return -EINPROGRESS; /* Call commit handler */
+}
+
+static int orinoco_ioctl_getpreamble(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int *val = (int *) extra;
+
+ if (!priv->has_preamble)
+ return -EOPNOTSUPP;
+
+ *val = priv->preamble;
+ return 0;
+}
+
+/* ioctl interface to hermes_read_ltv()
+ * To use with iwpriv, pass the RID as the token argument, e.g.
+ * iwpriv get_rid [0xfc00]
+ * At least Wireless Tools 25 is required to use iwpriv.
+ * For Wireless Tools 25 and 26 append "dummy" are the end. */
+static int orinoco_ioctl_getrid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ int rid = data->flags;
+ u16 length;
+ int err;
+ unsigned long flags;
+
+ /* It's a "get" function, but we don't want users to access the
+ * WEP key and other raw firmware data */
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (rid < 0xfc00 || rid > 0xffff)
+ return -EINVAL;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
+ extra);
+ if (err)
+ goto out;
+
+ data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
+ MAX_RID_LEN);
+
+ out:
+ orinoco_unlock(priv, &flags);
+ return err;
+}
+
+/* Trigger a scan (look for other cells in the vicinity) */
+static int orinoco_ioctl_setscan(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *srq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ hermes_t *hw = &priv->hw;
+ struct iw_scan_req *si = (struct iw_scan_req *) extra;
+ int err = 0;
+ unsigned long flags;
+
+ /* Note : you may have realised that, as this is a SET operation,
+ * this is privileged and therefore a normal user can't
+ * perform scanning.
+ * This is not an error, while the device perform scanning,
+ * traffic doesn't flow, so it's a perfect DoS...
+ * Jean II */
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ /* Scanning with port 0 disabled would fail */
+ if (!netif_running(dev)) {
+ err = -ENETDOWN;
+ goto out;
+ }
+
+ /* In monitor mode, the scan results are always empty.
+ * Probe responses are passed to the driver as received
+ * frames and could be processed in software. */
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ /* Note : because we don't lock out the irq handler, the way
+ * we access scan variables in priv is critical.
+ * o scan_inprogress : not touched by irq handler
+ * o scan_mode : not touched by irq handler
+ * Before modifying anything on those variables, please think hard !
+ * Jean II */
+
+ /* Save flags */
+ priv->scan_mode = srq->flags;
+
+ /* Always trigger scanning, even if it's in progress.
+ * This way, if the info frame get lost, we will recover somewhat
+ * gracefully - Jean II */
+
+ if (priv->has_hostscan) {
+ switch (priv->firmware_type) {
+ case FIRMWARE_TYPE_SYMBOL:
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFHOSTSCAN_SYMBOL,
+ HERMES_HOSTSCAN_SYMBOL_ONCE |
+ HERMES_HOSTSCAN_SYMBOL_BCAST);
+ break;
+ case FIRMWARE_TYPE_INTERSIL: {
+ __le16 req[3];
+
+ req[0] = cpu_to_le16(0x3fff); /* All channels */
+ req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */
+ req[2] = 0; /* Any ESSID */
+ err = HERMES_WRITE_RECORD(hw, USER_BAP,
+ HERMES_RID_CNFHOSTSCAN, &req);
+ }
+ break;
+ case FIRMWARE_TYPE_AGERE:
+ if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
+ struct hermes_idstring idbuf;
+ size_t len = min(sizeof(idbuf.val),
+ (size_t) si->essid_len);
+ idbuf.len = cpu_to_le16(len);
+ memcpy(idbuf.val, si->essid, len);
+
+ err = hermes_write_ltv(hw, USER_BAP,
+ HERMES_RID_CNFSCANSSID_AGERE,
+ HERMES_BYTES_TO_RECLEN(len + 2),
+ &idbuf);
+ } else
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFSCANSSID_AGERE,
+ 0); /* Any ESSID */
+ if (err)
+ break;
+
+ if (priv->has_ext_scan) {
+ /* Clear scan results at the start of
+ * an extended scan */
+ orinoco_clear_scan_results(priv,
+ msecs_to_jiffies(15000));
+
+ /* TODO: Is this available on older firmware?
+ * Can we use it to scan specific channels
+ * for IW_SCAN_THIS_FREQ? */
+ err = hermes_write_wordrec(hw, USER_BAP,
+ HERMES_RID_CNFSCANCHANNELS2GHZ,
+ 0x7FFF);
+ if (err)
+ goto out;
+
+ err = hermes_inquire(hw,
+ HERMES_INQ_CHANNELINFO);
+ } else
+ err = hermes_inquire(hw, HERMES_INQ_SCAN);
+ break;
+ }
+ } else
+ err = hermes_inquire(hw, HERMES_INQ_SCAN);
+
+ /* One more client */
+ if (!err)
+ priv->scan_inprogress = 1;
+
+ out:
+ orinoco_unlock(priv, &flags);
+ return err;
+}
+
+#define MAX_CUSTOM_LEN 64
+
+/* Translate scan data returned from the card to a card independant
+ * format that the Wireless Tools will understand - Jean II */
+static inline char *orinoco_translate_scan(struct net_device *dev,
+ struct iw_request_info *info,
+ char *current_ev,
+ char *end_buf,
+ union hermes_scan_info *bss,
+ unsigned long last_scanned)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ u16 capabilities;
+ u16 channel;
+ struct iw_event iwe; /* Temporary buffer */
+ char custom[MAX_CUSTOM_LEN];
+
+ memset(&iwe, 0, sizeof(iwe));
+
+ /* First entry *MUST* be the AP MAC address */
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
+
+ /* Other entries will be displayed in the order we give them */
+
+ /* Add the ESSID */
+ iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
+ if (iwe.u.data.length > 32)
+ iwe.u.data.length = 32;
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.flags = 1;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->a.essid);
+
+ /* Add mode */
+ iwe.cmd = SIOCGIWMODE;
+ capabilities = le16_to_cpu(bss->a.capabilities);
+ if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
+ if (capabilities & WLAN_CAPABILITY_ESS)
+ iwe.u.mode = IW_MODE_MASTER;
+ else
+ iwe.u.mode = IW_MODE_ADHOC;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
+ }
+
+ channel = bss->s.channel;
+ if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
+ /* Add channel and frequency */
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.m = channel;
+ iwe.u.freq.e = 0;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
+
+ iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
+ iwe.u.freq.e = 1;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
+ }
+
+ /* Add quality statistics. level and noise in dB. No link quality */
+ iwe.cmd = IWEVQUAL;
+ iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
+ iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
+ iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
+ /* Wireless tools prior to 27.pre22 will show link quality
+ * anyway, so we provide a reasonable value. */
+ if (iwe.u.qual.level > iwe.u.qual.noise)
+ iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
+ else
+ iwe.u.qual.qual = 0;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
+
+ /* Add encryption capability */
+ iwe.cmd = SIOCGIWENCODE;
+ if (capabilities & WLAN_CAPABILITY_PRIVACY)
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+ iwe.u.data.length = 0;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, NULL);
+
+ /* Bit rate is not available in Lucent/Agere firmwares */
+ if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
+ char *current_val = current_ev + iwe_stream_lcp_len(info);
+ int i;
+ int step;
+
+ if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
+ step = 2;
+ else
+ step = 1;
+
+ iwe.cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+ /* Max 10 values */
+ for (i = 0; i < 10; i += step) {
+ /* NULL terminated */
+ if (bss->p.rates[i] == 0x0)
+ break;
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe.u.bitrate.value =
+ ((bss->p.rates[i] & 0x7f) * 500000);
+ current_val = iwe_stream_add_value(info, current_ev,
+ current_val,
+ end_buf, &iwe,
+ IW_EV_PARAM_LEN);
+ }
+ /* Check if we added any event */
+ if ((current_val - current_ev) > iwe_stream_lcp_len(info))
+ current_ev = current_val;
+ }
+
+ /* Beacon interval */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+ "bcn_int=%d",
+ le16_to_cpu(bss->a.beacon_interv));
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ /* Capabilites */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+ "capab=0x%04x",
+ capabilities);
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ /* Add EXTRA: Age to display seconds since last beacon/probe response
+ * for given network. */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+ " Last beacon: %dms ago",
+ jiffies_to_msecs(jiffies - last_scanned));
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ return current_ev;
+}
+
+static inline char *orinoco_translate_ext_scan(struct net_device *dev,
+ struct iw_request_info *info,
+ char *current_ev,
+ char *end_buf,
+ struct agere_ext_scan_info *bss,
+ unsigned long last_scanned)
+{
+ u16 capabilities;
+ u16 channel;
+ struct iw_event iwe; /* Temporary buffer */
+ char custom[MAX_CUSTOM_LEN];
+ u8 *ie;
+
+ memset(&iwe, 0, sizeof(iwe));
+
+ /* First entry *MUST* be the AP MAC address */
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
+
+ /* Other entries will be displayed in the order we give them */
+
+ /* Add the ESSID */
+ ie = bss->data;
+ iwe.u.data.length = ie[1];
+ if (iwe.u.data.length) {
+ if (iwe.u.data.length > 32)
+ iwe.u.data.length = 32;
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.flags = 1;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, &ie[2]);
+ }
+
+ /* Add mode */
+ capabilities = le16_to_cpu(bss->capabilities);
+ if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
+ iwe.cmd = SIOCGIWMODE;
+ if (capabilities & WLAN_CAPABILITY_ESS)
+ iwe.u.mode = IW_MODE_MASTER;
+ else
+ iwe.u.mode = IW_MODE_ADHOC;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
+ }
+
+ ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_DS_PARAMS);
+ channel = ie ? ie[2] : 0;
+ if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
+ /* Add channel and frequency */
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.m = channel;
+ iwe.u.freq.e = 0;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
+
+ iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
+ iwe.u.freq.e = 1;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
+ }
+
+ /* Add quality statistics. level and noise in dB. No link quality */
+ iwe.cmd = IWEVQUAL;
+ iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
+ iwe.u.qual.level = bss->level - 0x95;
+ iwe.u.qual.noise = bss->noise - 0x95;
+ /* Wireless tools prior to 27.pre22 will show link quality
+ * anyway, so we provide a reasonable value. */
+ if (iwe.u.qual.level > iwe.u.qual.noise)
+ iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
+ else
+ iwe.u.qual.qual = 0;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
+
+ /* Add encryption capability */
+ iwe.cmd = SIOCGIWENCODE;
+ if (capabilities & WLAN_CAPABILITY_PRIVACY)
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+ iwe.u.data.length = 0;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, NULL);
+
+ /* WPA IE */
+ ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
+ if (ie) {
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = ie[1] + 2;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, ie);
+ }
+
+ /* RSN IE */
+ ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_RSN);
+ if (ie) {
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = ie[1] + 2;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, ie);
+ }
+
+ ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_SUPP_RATES);
+ if (ie) {
+ char *p = current_ev + iwe_stream_lcp_len(info);
+ int i;
+
+ iwe.cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+
+ for (i = 2; i < (ie[1] + 2); i++) {
+ iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
+ p = iwe_stream_add_value(info, current_ev, p, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
+ }
+ /* Check if we added any event */
+ if (p > (current_ev + iwe_stream_lcp_len(info)))
+ current_ev = p;
+ }
+
+ /* Timestamp */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length =
+ snprintf(custom, MAX_CUSTOM_LEN, "tsf=%016llx",
+ (unsigned long long) le64_to_cpu(bss->timestamp));
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ /* Beacon interval */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+ "bcn_int=%d",
+ le16_to_cpu(bss->beacon_interval));
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ /* Capabilites */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+ "capab=0x%04x",
+ capabilities);
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ /* Add EXTRA: Age to display seconds since last beacon/probe response
+ * for given network. */
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
+ " Last beacon: %dms ago",
+ jiffies_to_msecs(jiffies - last_scanned));
+ if (iwe.u.data.length)
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, custom);
+
+ return current_ev;
+}
+
+/* Return results of a scan */
+static int orinoco_ioctl_getscan(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *srq,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ int err = 0;
+ unsigned long flags;
+ char *current_ev = extra;
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return -EBUSY;
+
+ if (priv->scan_inprogress) {
+ /* Important note : we don't want to block the caller
+ * until results are ready for various reasons.
+ * First, managing wait queues is complex and racy.
+ * Second, we grab some rtnetlink lock before comming
+ * here (in dev_ioctl()).
+ * Third, we generate an Wireless Event, so the
+ * caller can wait itself on that - Jean II */
+ err = -EAGAIN;
+ goto out;
+ }
+
+ if (priv->has_ext_scan) {
+ struct xbss_element *bss;
+
+ list_for_each_entry(bss, &priv->bss_list, list) {
+ /* Translate this entry to WE format */
+ current_ev =
+ orinoco_translate_ext_scan(dev, info,
+ current_ev,
+ extra + srq->length,
+ &bss->bss,
+ bss->last_scanned);
+
+ /* Check if there is space for one more entry */
+ if ((extra + srq->length - current_ev)
+ <= IW_EV_ADDR_LEN) {
+ /* Ask user space to try again with a
+ * bigger buffer */
+ err = -E2BIG;
+ goto out;
+ }
+ }
+
+ } else {
+ struct bss_element *bss;
+
+ list_for_each_entry(bss, &priv->bss_list, list) {
+ /* Translate this entry to WE format */
+ current_ev = orinoco_translate_scan(dev, info,
+ current_ev,
+ extra + srq->length,
+ &bss->bss,
+ bss->last_scanned);
+
+ /* Check if there is space for one more entry */
+ if ((extra + srq->length - current_ev)
+ <= IW_EV_ADDR_LEN) {
+ /* Ask user space to try again with a
+ * bigger buffer */
+ err = -E2BIG;
+ goto out;
+ }
+ }
+ }
+
+ srq->length = (current_ev - extra);
+ srq->flags = (__u16) priv->scan_mode;
+
+out:
+ orinoco_unlock(priv, &flags);
+ return err;
+}
+
+/* Commit handler, called after set operations */
+static int orinoco_ioctl_commit(struct net_device *dev,
+ struct iw_request_info *info,
+ void *wrqu,
+ char *extra)
+{
+ struct orinoco_private *priv = netdev_priv(dev);
+ struct hermes *hw = &priv->hw;
+ unsigned long flags;
+ int err = 0;
+
+ if (!priv->open)
+ return 0;
+
+ if (priv->broken_disableport) {
+ orinoco_reset(&priv->reset_work);
+ return 0;
+ }
+
+ if (orinoco_lock(priv, &flags) != 0)
+ return err;
+
+ err = hermes_disable_port(hw, 0);
+ if (err) {
+ printk(KERN_WARNING "%s: Unable to disable port "
+ "while reconfiguring card\n", dev->name);
+ priv->broken_disableport = 1;
+ goto out;
+ }
+
+ err = __orinoco_program_rids(dev);
+ if (err) {
+ printk(KERN_WARNING "%s: Unable to reconfigure card\n",
+ dev->name);
+ goto out;
+ }
+
+ err = hermes_enable_port(hw, 0);
+ if (err) {
+ printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
+ dev->name);
+ goto out;
+ }
+
+ out:
+ if (err) {
+ printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
+ schedule_work(&priv->reset_work);
+ err = 0;
+ }
+
+ orinoco_unlock(priv, &flags);
+ return err;
+}
+
+static const struct iw_priv_args orinoco_privtab[] = {
+ { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
+ { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
+ { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "set_port3" },
+ { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_port3" },
+ { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "set_preamble" },
+ { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_preamble" },
+ { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0, "set_ibssport" },
+ { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ "get_ibssport" },
+ { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
+ "get_rid" },
+};
+
+
+/*
+ * Structures to export the Wireless Handlers
+ */
+
+#define STD_IW_HANDLER(id, func) \
+ [IW_IOCTL_IDX(id)] = (iw_handler) func
+static const iw_handler orinoco_handler[] = {
+ STD_IW_HANDLER(SIOCSIWCOMMIT, orinoco_ioctl_commit),
+ STD_IW_HANDLER(SIOCGIWNAME, orinoco_ioctl_getname),
+ STD_IW_HANDLER(SIOCSIWFREQ, orinoco_ioctl_setfreq),
+ STD_IW_HANDLER(SIOCGIWFREQ, orinoco_ioctl_getfreq),
+ STD_IW_HANDLER(SIOCSIWMODE, orinoco_ioctl_setmode),
+ STD_IW_HANDLER(SIOCGIWMODE, orinoco_ioctl_getmode),
+ STD_IW_HANDLER(SIOCSIWSENS, orinoco_ioctl_setsens),
+ STD_IW_HANDLER(SIOCGIWSENS, orinoco_ioctl_getsens),
+ STD_IW_HANDLER(SIOCGIWRANGE, orinoco_ioctl_getiwrange),
+ STD_IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
+ STD_IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
+ STD_IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
+ STD_IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
+ STD_IW_HANDLER(SIOCSIWAP, orinoco_ioctl_setwap),
+ STD_IW_HANDLER(SIOCGIWAP, orinoco_ioctl_getwap),
+ STD_IW_HANDLER(SIOCSIWSCAN, orinoco_ioctl_setscan),
+ STD_IW_HANDLER(SIOCGIWSCAN, orinoco_ioctl_getscan),
+ STD_IW_HANDLER(SIOCSIWESSID, orinoco_ioctl_setessid),
+ STD_IW_HANDLER(SIOCGIWESSID, orinoco_ioctl_getessid),
+ STD_IW_HANDLER(SIOCSIWNICKN, orinoco_ioctl_setnick),
+ STD_IW_HANDLER(SIOCGIWNICKN, orinoco_ioctl_getnick),
+ STD_IW_HANDLER(SIOCSIWRATE, orinoco_ioctl_setrate),
+ STD_IW_HANDLER(SIOCGIWRATE, orinoco_ioctl_getrate),
+ STD_IW_HANDLER(SIOCSIWRTS, orinoco_ioctl_setrts),
+ STD_IW_HANDLER(SIOCGIWRTS, orinoco_ioctl_getrts),
+ STD_IW_HANDLER(SIOCSIWFRAG, orinoco_ioctl_setfrag),
+ STD_IW_HANDLER(SIOCGIWFRAG, orinoco_ioctl_getfrag),
+ STD_IW_HANDLER(SIOCGIWRETRY, orinoco_ioctl_getretry),
+ STD_IW_HANDLER(SIOCSIWENCODE, orinoco_ioctl_setiwencode),
+ STD_IW_HANDLER(SIOCGIWENCODE, orinoco_ioctl_getiwencode),
+ STD_IW_HANDLER(SIOCSIWPOWER, orinoco_ioctl_setpower),
+ STD_IW_HANDLER(SIOCGIWPOWER, orinoco_ioctl_getpower),
+ STD_IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie),
+ STD_IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie),
+ STD_IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme),
+ STD_IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth),
+ STD_IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth),
+ STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
+ STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
+};
+
+
+/*
+ Added typecasting since we no longer use iwreq_data -- Moustafa
+ */
+static const iw_handler orinoco_private_handler[] = {
+ [0] = (iw_handler) orinoco_ioctl_reset,
+ [1] = (iw_handler) orinoco_ioctl_reset,
+ [2] = (iw_handler) orinoco_ioctl_setport3,
+ [3] = (iw_handler) orinoco_ioctl_getport3,
+ [4] = (iw_handler) orinoco_ioctl_setpreamble,
+ [5] = (iw_handler) orinoco_ioctl_getpreamble,
+ [6] = (iw_handler) orinoco_ioctl_setibssport,
+ [7] = (iw_handler) orinoco_ioctl_getibssport,
+ [9] = (iw_handler) orinoco_ioctl_getrid,
+};
+
+const struct iw_handler_def orinoco_handler_def = {
+ .num_standard = ARRAY_SIZE(orinoco_handler),
+ .num_private = ARRAY_SIZE(orinoco_private_handler),
+ .num_private_args = ARRAY_SIZE(orinoco_privtab),
+ .standard = orinoco_handler,
+ .private = orinoco_private_handler,
+ .private_args = orinoco_privtab,
+ .get_wireless_stats = orinoco_get_wireless_stats,
+};
diff --git a/drivers/net/wireless/orinoco/wext.h b/drivers/net/wireless/orinoco/wext.h
new file mode 100644
index 000000000000..1479f4e26dde
--- /dev/null
+++ b/drivers/net/wireless/orinoco/wext.h
@@ -0,0 +1,13 @@
+/* Wireless extensions support.
+ *
+ * See copyright notice in main.c
+ */
+#ifndef _ORINOCO_WEXT_H_
+#define _ORINOCO_WEXT_H_
+
+#include <net/iw_handler.h>
+
+/* Structure defining all our WEXT handlers */
+extern const struct iw_handler_def orinoco_handler_def;
+
+#endif /* _ORINOCO_WEXT_H_ */
diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig
index d3469d08f966..b45d6a4ed1e8 100644
--- a/drivers/net/wireless/p54/Kconfig
+++ b/drivers/net/wireless/p54/Kconfig
@@ -1,9 +1,10 @@
config P54_COMMON
tristate "Softmac Prism54 support"
- depends on MAC80211 && WLAN_80211 && FW_LOADER && EXPERIMENTAL
+ depends on MAC80211 && WLAN_80211 && EXPERIMENTAL
+ select FW_LOADER
---help---
- This is common code for isl38xx based cards.
- This module does nothing by itself - the USB/PCI frontends
+ This is common code for isl38xx/stlc45xx based modules.
+ This module does nothing by itself - the USB/PCI/SPI front-ends
also need to be enabled in order to support any devices.
These devices require softmac firmware which can be found at
@@ -17,31 +18,6 @@ config P54_USB
select CRC32
---help---
This driver is for USB isl38xx based wireless cards.
- These are USB based adapters found in devices such as:
-
- 3COM 3CRWE254G72
- SMC 2862W-G
- Accton 802.11g WN4501 USB
- Siemens Gigaset USB
- Netgear WG121
- Netgear WG111
- Medion 40900, Roper Europe
- Shuttle PN15, Airvast WM168g, IOGear GWU513
- Linksys WUSB54G
- Linksys WUSB54G Portable
- DLink DWL-G120 Spinnaker
- DLink DWL-G122
- Belkin F5D7050 ver 1000
- Cohiba Proto board
- SMC 2862W-G version 2
- U.S. Robotics U5 802.11g Adapter
- FUJITSU E-5400 USB D1700
- Sagem XG703A
- DLink DWL-G120 Cohiba
- Spinnaker Proto board
- Linksys WUSB54AG
- Inventel UR054G
- Spinnaker DUT
These devices require softmac firmware which can be found at
http://prism54.org/
@@ -61,3 +37,18 @@ config P54_PCI
http://prism54.org/
If you choose to build a module, it'll be called p54pci.
+
+config P54_SPI
+ tristate "Prism54 SPI (stlc45xx) support"
+ depends on P54_COMMON && SPI_MASTER && GENERIC_HARDIRQS
+ ---help---
+ This driver is for stlc4550 or stlc4560 based wireless chips.
+ This driver is experimental, untested and will probably only work on
+ Nokia's N800/N810 Portable Internet Tablet.
+
+ If you choose to build a module, it'll be called p54spi.
+
+config P54_LEDS
+ bool
+ depends on P54_COMMON && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = P54_COMMON)
+ default y
diff --git a/drivers/net/wireless/p54/Makefile b/drivers/net/wireless/p54/Makefile
index 4fa9ce717360..c2050dee6293 100644
--- a/drivers/net/wireless/p54/Makefile
+++ b/drivers/net/wireless/p54/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_P54_COMMON) += p54common.o
obj-$(CONFIG_P54_USB) += p54usb.o
obj-$(CONFIG_P54_PCI) += p54pci.o
+obj-$(CONFIG_P54_SPI) += p54spi.o
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index ab79e32f0b27..2dda5fe418b6 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -14,6 +14,10 @@
* published by the Free Software Foundation.
*/
+#ifdef CONFIG_MAC80211_LEDS
+#include <linux/leds.h>
+#endif /* CONFIG_MAC80211_LEDS */
+
enum p54_control_frame_types {
P54_CONTROL_TYPE_SETUP = 0,
P54_CONTROL_TYPE_SCAN,
@@ -44,6 +48,18 @@ enum p54_control_frame_types {
P54_CONTROL_TYPE_BT_OPTIONS = 35
};
+/* provide 16 bytes for the transport back-end */
+#define P54_TX_INFO_DATA_SIZE 16
+
+/* stored in ieee80211_tx_info's rate_driver_data */
+struct p54_tx_info {
+ u32 start_addr;
+ u32 end_addr;
+ void *data[P54_TX_INFO_DATA_SIZE / sizeof(void *)];
+};
+
+#define P54_MAX_CTRL_FRAME_LEN 0x1000
+
#define P54_HDR_FLAG_CONTROL BIT(15)
#define P54_HDR_FLAG_CONTROL_OPSET (BIT(15) + BIT(0))
@@ -75,6 +91,14 @@ struct p54_rssi_linear_approximation {
s16 longbow_unk2;
};
+struct p54_cal_database {
+ size_t entries;
+ size_t entry_size;
+ size_t offset;
+ size_t len;
+ u8 data[0];
+};
+
#define EEPROM_READBACK_LEN 0x3fc
#define ISL38XX_DEV_FIRMWARE_ADDR 0x20000
@@ -84,6 +108,29 @@ struct p54_rssi_linear_approximation {
#define FW_LM87 0x4c4d3837
#define FW_LM20 0x4c4d3230
+enum fw_state {
+ FW_STATE_OFF,
+ FW_STATE_BOOTING,
+ FW_STATE_READY,
+ FW_STATE_RESET,
+ FW_STATE_RESETTING,
+};
+
+#ifdef CONFIG_MAC80211_LEDS
+
+#define P54_LED_MAX_NAME_LEN 31
+
+struct p54_led_dev {
+ struct ieee80211_hw *hw_dev;
+ struct led_classdev led_dev;
+ char name[P54_LED_MAX_NAME_LEN + 1];
+
+ unsigned int index;
+ unsigned int registered;
+};
+
+#endif /* CONFIG_MAC80211_LEDS */
+
struct p54_common {
struct ieee80211_hw *hw;
u32 rx_start;
@@ -99,11 +146,12 @@ struct p54_common {
struct mutex conf_mutex;
u8 mac_addr[ETH_ALEN];
u8 bssid[ETH_ALEN];
+ u8 rx_diversity_mask;
+ u8 tx_diversity_mask;
struct pda_iq_autocal_entry *iq_autocal;
unsigned int iq_autocal_len;
- struct pda_channel_output_limit *output_limit;
- unsigned int output_limit_len;
- struct pda_pa_curve_data *curve_data;
+ struct p54_cal_database *output_limit;
+ struct p54_cal_database *curve_data;
struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
unsigned int filter_flags;
bool use_short_slot;
@@ -115,7 +163,7 @@ struct p54_common {
unsigned int output_power;
u32 tsf_low32;
u32 tsf_high32;
- u64 basic_rate_mask;
+ u32 basic_rate_mask;
u16 wakeup_timer;
u16 aid;
struct ieee80211_tx_queue_stats tx_stats[8];
@@ -128,13 +176,21 @@ struct p54_common {
struct completion eeprom_comp;
u8 privacy_caps;
u8 rx_keycache_size;
+ /* LED management */
+ #ifdef CONFIG_MAC80211_LEDS
+ struct p54_led_dev assoc_led;
+ struct p54_led_dev tx_led;
+ #endif /* CONFIG_MAC80211_LEDS */
+ u16 softled_state; /* bit field of glowing LEDs */
};
int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb);
int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw);
+int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len);
int p54_read_eeprom(struct ieee80211_hw *dev);
struct ieee80211_hw *p54_init_common(size_t priv_data_len);
+int p54_register_common(struct ieee80211_hw *dev, struct device *pdev);
void p54_free_common(struct ieee80211_hw *dev);
#endif /* P54_H */
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index f170106bf0ae..0c1b0577d4ee 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -21,6 +21,9 @@
#include <linux/etherdevice.h>
#include <net/mac80211.h>
+#ifdef CONFIG_P54_LEDS
+#include <linux/leds.h>
+#endif /* CONFIG_P54_LEDS */
#include "p54.h"
#include "p54common.h"
@@ -239,11 +242,11 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
if (priv->fw_var >= 0x300) {
/* Firmware supports QoS, use it! */
- priv->tx_stats[4].limit = 3; /* AC_VO */
- priv->tx_stats[5].limit = 4; /* AC_VI */
- priv->tx_stats[6].limit = 3; /* AC_BE */
- priv->tx_stats[7].limit = 2; /* AC_BK */
- dev->queues = 4;
+ priv->tx_stats[P54_QUEUE_AC_VO].limit = 3;
+ priv->tx_stats[P54_QUEUE_AC_VI].limit = 4;
+ priv->tx_stats[P54_QUEUE_AC_BE].limit = 3;
+ priv->tx_stats[P54_QUEUE_AC_BK].limit = 2;
+ dev->queues = P54_QUEUE_AC_NUM;
}
if (!modparam_nohwcrypt)
@@ -272,13 +275,19 @@ static int p54_convert_rev0(struct ieee80211_hw *dev,
unsigned int i, j;
void *source, *target;
- priv->curve_data = kmalloc(cd_len, GFP_KERNEL);
+ priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len,
+ GFP_KERNEL);
if (!priv->curve_data)
return -ENOMEM;
- memcpy(priv->curve_data, curve_data, sizeof(*curve_data));
+ priv->curve_data->entries = curve_data->channels;
+ priv->curve_data->entry_size = sizeof(__le16) +
+ sizeof(*dst) * curve_data->points_per_channel;
+ priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
+ priv->curve_data->len = cd_len;
+ memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
source = curve_data->data;
- target = priv->curve_data->data;
+ target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
for (i = 0; i < curve_data->channels; i++) {
__le16 *freq = source;
source += sizeof(__le16);
@@ -318,13 +327,19 @@ static int p54_convert_rev1(struct ieee80211_hw *dev,
unsigned int i, j;
void *source, *target;
- priv->curve_data = kmalloc(cd_len, GFP_KERNEL);
+ priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data),
+ GFP_KERNEL);
if (!priv->curve_data)
return -ENOMEM;
- memcpy(priv->curve_data, curve_data, sizeof(*curve_data));
+ priv->curve_data->entries = curve_data->channels;
+ priv->curve_data->entry_size = sizeof(__le16) +
+ sizeof(*dst) * curve_data->points_per_channel;
+ priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
+ priv->curve_data->len = cd_len;
+ memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
source = curve_data->data;
- target = priv->curve_data->data;
+ target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
for (i = 0; i < curve_data->channels; i++) {
__le16 *freq = source;
source += sizeof(__le16);
@@ -376,7 +391,102 @@ static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len,
}
}
-static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
+static void p54_parse_default_country(struct ieee80211_hw *dev,
+ void *data, int len)
+{
+ struct pda_country *country;
+
+ if (len != sizeof(*country)) {
+ printk(KERN_ERR "%s: found possible invalid default country "
+ "eeprom entry. (entry size: %d)\n",
+ wiphy_name(dev->wiphy), len);
+
+ print_hex_dump_bytes("country:", DUMP_PREFIX_NONE,
+ data, len);
+
+ printk(KERN_ERR "%s: please report this issue.\n",
+ wiphy_name(dev->wiphy));
+ return;
+ }
+
+ country = (struct pda_country *) data;
+ if (country->flags == PDR_COUNTRY_CERT_CODE_PSEUDO)
+ regulatory_hint(dev->wiphy, country->alpha2);
+ else {
+ /* TODO:
+ * write a shared/common function that converts
+ * "Regulatory domain codes" (802.11-2007 14.8.2.2)
+ * into ISO/IEC 3166-1 alpha2 for regulatory_hint.
+ */
+ }
+}
+
+static int p54_convert_output_limits(struct ieee80211_hw *dev,
+ u8 *data, size_t len)
+{
+ struct p54_common *priv = dev->priv;
+
+ if (len < 2)
+ return -EINVAL;
+
+ if (data[0] != 0) {
+ printk(KERN_ERR "%s: unknown output power db revision:%x\n",
+ wiphy_name(dev->wiphy), data[0]);
+ return -EINVAL;
+ }
+
+ if (2 + data[1] * sizeof(struct pda_channel_output_limit) > len)
+ return -EINVAL;
+
+ priv->output_limit = kmalloc(data[1] *
+ sizeof(struct pda_channel_output_limit) +
+ sizeof(*priv->output_limit), GFP_KERNEL);
+
+ if (!priv->output_limit)
+ return -ENOMEM;
+
+ priv->output_limit->offset = 0;
+ priv->output_limit->entries = data[1];
+ priv->output_limit->entry_size =
+ sizeof(struct pda_channel_output_limit);
+ priv->output_limit->len = priv->output_limit->entry_size *
+ priv->output_limit->entries +
+ priv->output_limit->offset;
+
+ memcpy(priv->output_limit->data, &data[2],
+ data[1] * sizeof(struct pda_channel_output_limit));
+
+ return 0;
+}
+
+static struct p54_cal_database *p54_convert_db(struct pda_custom_wrapper *src,
+ size_t total_len)
+{
+ struct p54_cal_database *dst;
+ size_t payload_len, entries, entry_size, offset;
+
+ payload_len = le16_to_cpu(src->len);
+ entries = le16_to_cpu(src->entries);
+ entry_size = le16_to_cpu(src->entry_size);
+ offset = le16_to_cpu(src->offset);
+ if (((entries * entry_size + offset) != payload_len) ||
+ (payload_len + sizeof(*src) != total_len))
+ return NULL;
+
+ dst = kmalloc(sizeof(*dst) + payload_len, GFP_KERNEL);
+ if (!dst)
+ return NULL;
+
+ dst->entries = entries;
+ dst->entry_size = entry_size;
+ dst->offset = offset;
+ dst->len = payload_len;
+
+ memcpy(dst->data, src->data, payload_len);
+ return dst;
+}
+
+int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
{
struct p54_common *priv = dev->priv;
struct eeprom_pda_wrap *wrap = NULL;
@@ -401,30 +511,17 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
switch (le16_to_cpu(entry->code)) {
case PDR_MAC_ADDRESS:
+ if (data_len != ETH_ALEN)
+ break;
SET_IEEE80211_PERM_ADDR(dev, entry->data);
break;
case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS:
- if (data_len < 2) {
- err = -EINVAL;
- goto err;
- }
-
- if (2 + entry->data[1]*sizeof(*priv->output_limit) > data_len) {
- err = -EINVAL;
- goto err;
- }
-
- priv->output_limit = kmalloc(entry->data[1] *
- sizeof(*priv->output_limit), GFP_KERNEL);
-
- if (!priv->output_limit) {
- err = -ENOMEM;
+ if (priv->output_limit)
+ break;
+ err = p54_convert_output_limits(dev, entry->data,
+ data_len);
+ if (err)
goto err;
- }
-
- memcpy(priv->output_limit, &entry->data[2],
- entry->data[1]*sizeof(*priv->output_limit));
- priv->output_limit_len = entry->data[1];
break;
case PDR_PRISM_PA_CAL_CURVE_DATA: {
struct pda_pa_curve_data *curve_data =
@@ -463,6 +560,9 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
memcpy(priv->iq_autocal, entry->data, data_len);
priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry);
break;
+ case PDR_DEFAULT_COUNTRY:
+ p54_parse_default_country(dev, entry->data, data_len);
+ break;
case PDR_INTERFACE_LIST:
tmp = entry->data;
while ((u8 *)tmp < entry->data + data_len) {
@@ -473,6 +573,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
}
break;
case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
+ if (data_len < 2)
+ break;
priv->version = *(u8 *)(entry->data + 1);
break;
case PDR_RSSI_LINEAR_APPROXIMATION:
@@ -481,6 +583,34 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
p54_parse_rssical(dev, entry->data, data_len,
le16_to_cpu(entry->code));
break;
+ case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM: {
+ __le16 *src = (void *) entry->data;
+ s16 *dst = (void *) &priv->rssical_db;
+ int i;
+
+ if (data_len != sizeof(priv->rssical_db)) {
+ err = -EINVAL;
+ goto err;
+ }
+ for (i = 0; i < sizeof(priv->rssical_db) /
+ sizeof(*src); i++)
+ *(dst++) = (s16) le16_to_cpu(*(src++));
+ }
+ break;
+ case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: {
+ struct pda_custom_wrapper *pda = (void *) entry->data;
+ if (priv->output_limit || data_len < sizeof(*pda))
+ break;
+ priv->output_limit = p54_convert_db(pda, data_len);
+ }
+ break;
+ case PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM: {
+ struct pda_custom_wrapper *pda = (void *) entry->data;
+ if (priv->curve_data || data_len < sizeof(*pda))
+ break;
+ priv->curve_data = p54_convert_db(pda, data_len);
+ }
+ break;
case PDR_END:
/* make it overrun */
entry_len = len;
@@ -497,7 +627,6 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
case PDR_UTF8_OEM_NAME:
case PDR_UTF8_PRODUCT_NAME:
case PDR_COUNTRY_LIST:
- case PDR_DEFAULT_COUNTRY:
case PDR_ANTENNA_GAIN:
case PDR_PRISM_INDIGO_PA_CALIBRATION_DATA:
case PDR_REGULATORY_POWER_LIMITS:
@@ -525,12 +654,16 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
}
priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
- if (priv->rxhw == 4)
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW)
p54_init_xbow_synth(dev);
if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
if (!(synth & PDR_SYNTH_5_GHZ_DISABLED))
dev->wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5GHz;
+ if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED)
+ priv->rx_diversity_mask = 3;
+ if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED)
+ priv->tx_diversity_mask = 3;
if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
u8 perm_addr[ETH_ALEN];
@@ -568,13 +701,21 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
wiphy_name(dev->wiphy));
return err;
}
+EXPORT_SYMBOL_GPL(p54_parse_eeprom);
static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
{
struct p54_common *priv = dev->priv;
int band = dev->conf.channel->band;
- return ((rssi * priv->rssical_db[band].mul) / 64 +
+ if (priv->rxhw != PDR_SYNTH_FRONTEND_LONGBOW)
+ return ((rssi * priv->rssical_db[band].mul) / 64 +
+ priv->rssical_db[band].add) / 4;
+ else
+ /*
+ * TODO: find the correct formula
+ */
+ return ((rssi * priv->rssical_db[band].mul) / 64 +
priv->rssical_db[band].add) / 4;
}
@@ -597,10 +738,7 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
return 0;
if (!(hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_IN_FCS_GOOD))) {
- if (priv->filter_flags & FIF_FCSFAIL)
- rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
- else
- return 0;
+ return 0;
}
if (hdr->decrypt_status == P54_DECRYPT_OK)
@@ -655,7 +793,8 @@ static void inline p54_wake_free_queues(struct ieee80211_hw *dev)
return ;
for (i = 0; i < dev->queues; i++)
- if (priv->tx_stats[i + 4].len < priv->tx_stats[i + 4].limit)
+ if (priv->tx_stats[i + P54_QUEUE_DATA].len <
+ priv->tx_stats[i + P54_QUEUE_DATA].limit)
ieee80211_wake_queue(dev, i);
}
@@ -663,7 +802,7 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct p54_common *priv = dev->priv;
struct ieee80211_tx_info *info;
- struct memrecord *range;
+ struct p54_tx_info *range;
unsigned long flags;
u32 freed = 0, last_addr = priv->rx_start;
@@ -681,18 +820,18 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
range = (void *)info->rate_driver_data;
if (skb->prev != (struct sk_buff *)&priv->tx_queue) {
struct ieee80211_tx_info *ni;
- struct memrecord *mr;
+ struct p54_tx_info *mr;
ni = IEEE80211_SKB_CB(skb->prev);
- mr = (struct memrecord *)ni->rate_driver_data;
+ mr = (struct p54_tx_info *)ni->rate_driver_data;
last_addr = mr->end_addr;
}
if (skb->next != (struct sk_buff *)&priv->tx_queue) {
struct ieee80211_tx_info *ni;
- struct memrecord *mr;
+ struct p54_tx_info *mr;
ni = IEEE80211_SKB_CB(skb->next);
- mr = (struct memrecord *)ni->rate_driver_data;
+ mr = (struct p54_tx_info *)ni->rate_driver_data;
freed = mr->start_addr - last_addr;
} else
freed = priv->rx_end - last_addr;
@@ -735,7 +874,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
struct p54_frame_sent *payload = (struct p54_frame_sent *) hdr->data;
struct sk_buff *entry;
u32 addr = le32_to_cpu(hdr->req_id) - priv->headroom;
- struct memrecord *range = NULL;
+ struct p54_tx_info *range = NULL;
u32 freed = 0;
u32 last_addr = priv->rx_start;
unsigned long flags;
@@ -758,10 +897,10 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
if (entry->next != (struct sk_buff *)&priv->tx_queue) {
struct ieee80211_tx_info *ni;
- struct memrecord *mr;
+ struct p54_tx_info *mr;
ni = IEEE80211_SKB_CB(entry->next);
- mr = (struct memrecord *)ni->rate_driver_data;
+ mr = (struct p54_tx_info *)ni->rate_driver_data;
freed = mr->start_addr - last_addr;
} else
freed = priv->rx_end - last_addr;
@@ -776,9 +915,16 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
priv->tx_stats[entry_data->hw_queue].len--;
priv->stats.dot11ACKFailureCount += payload->tries - 1;
- if (unlikely(entry == priv->cached_beacon)) {
+ /*
+ * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are
+ * generated by the driver. Therefore tx_status is bogus
+ * and we don't want to confuse the mac80211 stack.
+ */
+ if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) {
+ if (entry_data->hw_queue == P54_QUEUE_BEACON)
+ priv->cached_beacon = NULL;
+
kfree_skb(entry);
- priv->cached_beacon = NULL;
goto out;
}
@@ -971,8 +1117,8 @@ EXPORT_SYMBOL_GPL(p54_rx);
* can find some unused memory to upload our packets to. However, data that we
* want the card to TX needs to stay intact until the card has told us that
* it is done with it. This function finds empty places we can upload to and
- * marks allocated areas as reserved if necessary. p54_rx_frame_sent frees
- * allocated areas.
+ * marks allocated areas as reserved if necessary. p54_rx_frame_sent or
+ * p54_free_skb frees allocated areas.
*/
static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
struct p54_hdr *data, u32 len)
@@ -981,7 +1127,7 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
struct sk_buff *entry;
struct sk_buff *target_skb = NULL;
struct ieee80211_tx_info *info;
- struct memrecord *range;
+ struct p54_tx_info *range;
u32 last_addr = priv->rx_start;
u32 largest_hole = 0;
u32 target_addr = priv->rx_start;
@@ -1063,25 +1209,29 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
return 0;
}
-static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev,
- u16 hdr_flags, u16 len, u16 type, gfp_t memflags)
+static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev, u16 hdr_flags,
+ u16 payload_len, u16 type, gfp_t memflags)
{
struct p54_common *priv = dev->priv;
struct p54_hdr *hdr;
struct sk_buff *skb;
+ size_t frame_len = sizeof(*hdr) + payload_len;
+
+ if (frame_len > P54_MAX_CTRL_FRAME_LEN)
+ return NULL;
- skb = __dev_alloc_skb(len + priv->tx_hdr_len, memflags);
+ skb = __dev_alloc_skb(priv->tx_hdr_len + frame_len, memflags);
if (!skb)
return NULL;
skb_reserve(skb, priv->tx_hdr_len);
hdr = (struct p54_hdr *) skb_put(skb, sizeof(*hdr));
hdr->flags = cpu_to_le16(hdr_flags);
- hdr->len = cpu_to_le16(len - sizeof(*hdr));
+ hdr->len = cpu_to_le16(payload_len);
hdr->type = cpu_to_le16(type);
hdr->tries = hdr->rts_tries = 0;
- if (unlikely(p54_assign_address(dev, skb, hdr, len))) {
+ if (p54_assign_address(dev, skb, hdr, frame_len)) {
kfree_skb(skb);
return NULL;
}
@@ -1091,7 +1241,6 @@ static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev,
int p54_read_eeprom(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
- struct p54_hdr *hdr = NULL;
struct p54_eeprom_lm86 *eeprom_hdr;
struct sk_buff *skb;
size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
@@ -1104,9 +1253,9 @@ int p54_read_eeprom(struct ieee80211_hw *dev)
else
maxblocksize -= 0x4;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*hdr) +
- sizeof(*eeprom_hdr) + maxblocksize,
- P54_CONTROL_TYPE_EEPROM_READBACK, GFP_KERNEL);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*eeprom_hdr) +
+ maxblocksize, P54_CONTROL_TYPE_EEPROM_READBACK,
+ GFP_KERNEL);
if (!skb)
goto free;
priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL);
@@ -1162,9 +1311,8 @@ static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
struct sk_buff *skb;
struct p54_tim *tim;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
- sizeof(struct p54_hdr) + sizeof(*tim),
- P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*tim),
+ P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -1181,9 +1329,8 @@ static int p54_sta_unlock(struct ieee80211_hw *dev, u8 *addr)
struct sk_buff *skb;
struct p54_sta_unlock *sta;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
- sizeof(struct p54_hdr) + sizeof(*sta),
- P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*sta),
+ P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -1223,9 +1370,8 @@ static int p54_tx_cancel(struct ieee80211_hw *dev, struct sk_buff *entry)
struct p54_hdr *hdr;
struct p54_txcancel *cancel;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET,
- sizeof(struct p54_hdr) + sizeof(*cancel),
- P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*cancel),
+ P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -1242,46 +1388,73 @@ static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb,
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct p54_common *priv = dev->priv;
- int ret = 0;
-
- if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
- if (ieee80211_is_beacon(hdr->frame_control)) {
- *aid = 0;
- *queue = 0;
- *extra_len = IEEE80211_MAX_TIM_LEN;
- *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
- return 0;
- } else if (ieee80211_is_probe_resp(hdr->frame_control)) {
- *aid = 0;
- *queue = 2;
- *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
- P54_HDR_FLAG_DATA_OUT_NOCANCEL;
- return 0;
- } else {
- *queue = 2;
- ret = 0;
- }
- } else {
- *queue += 4;
- ret = 1;
- }
+ int ret = 1;
switch (priv->mode) {
+ case NL80211_IFTYPE_MONITOR:
+ /*
+ * We have to set P54_HDR_FLAG_DATA_OUT_PROMISC for
+ * every frame in promiscuous/monitor mode.
+ * see STSW45x0C LMAC API - page 12.
+ */
+ *aid = 0;
+ *flags = P54_HDR_FLAG_DATA_OUT_PROMISC;
+ *queue += P54_QUEUE_DATA;
+ break;
case NL80211_IFTYPE_STATION:
*aid = 1;
+ if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
+ *queue = P54_QUEUE_MGMT;
+ ret = 0;
+ } else
+ *queue += P54_QUEUE_DATA;
break;
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_MESH_POINT:
if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
*aid = 0;
- *queue = 3;
+ *queue = P54_QUEUE_CAB;
return 0;
}
+
+ if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
+ if (ieee80211_is_probe_resp(hdr->frame_control)) {
+ *aid = 0;
+ *queue = P54_QUEUE_MGMT;
+ *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
+ P54_HDR_FLAG_DATA_OUT_NOCANCEL;
+ return 0;
+ } else if (ieee80211_is_beacon(hdr->frame_control)) {
+ *aid = 0;
+
+ if (info->flags & IEEE80211_TX_CTL_INJECTED) {
+ /*
+ * Injecting beacons on top of a AP is
+ * not a good idea... nevertheless,
+ * it should be doable.
+ */
+
+ *queue += P54_QUEUE_DATA;
+ return 1;
+ }
+
+ *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
+ *queue = P54_QUEUE_BEACON;
+ *extra_len = IEEE80211_MAX_TIM_LEN;
+ return 0;
+ } else {
+ *queue = P54_QUEUE_MGMT;
+ ret = 0;
+ }
+ } else
+ *queue += P54_QUEUE_DATA;
+
if (info->control.sta)
*aid = info->control.sta->aid;
else
*flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
+ break;
}
return ret;
}
@@ -1303,7 +1476,7 @@ static u8 p54_convert_algo(enum ieee80211_key_alg alg)
static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_tx_queue_stats *current_queue = NULL;
+ struct ieee80211_tx_queue_stats *current_queue;
struct p54_common *priv = dev->priv;
struct p54_hdr *hdr;
struct p54_tx_data *txhdr;
@@ -1446,15 +1619,17 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
}
txhdr->crypt_offset = crypt_offset;
txhdr->hw_queue = queue;
- if (current_queue)
- txhdr->backlog = current_queue->len;
- else
- txhdr->backlog = 0;
+ txhdr->backlog = current_queue->len;
memset(txhdr->durations, 0, sizeof(txhdr->durations));
- txhdr->tx_antenna = (info->antenna_sel_tx == 0) ?
- 2 : info->antenna_sel_tx - 1;
- txhdr->output_power = priv->output_power;
- txhdr->cts_rate = cts_rate;
+ txhdr->tx_antenna = ((info->antenna_sel_tx == 0) ?
+ 2 : info->antenna_sel_tx - 1) & priv->tx_diversity_mask;
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+ txhdr->longbow.cts_rate = cts_rate;
+ txhdr->longbow.output_power = cpu_to_le16(priv->output_power);
+ } else {
+ txhdr->normal.output_power = priv->output_power;
+ txhdr->normal.cts_rate = cts_rate;
+ }
if (padding)
txhdr->align[0] = padding;
@@ -1467,14 +1642,12 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
queue_delayed_work(dev->workqueue, &priv->work,
msecs_to_jiffies(P54_TX_FRAME_LIFETIME));
- return 0;
+ return NETDEV_TX_OK;
err:
skb_pull(skb, sizeof(*hdr) + sizeof(*txhdr) + padding);
- if (current_queue) {
- current_queue->len--;
- current_queue->count--;
- }
+ current_queue->len--;
+ current_queue->count--;
return NETDEV_TX_BUSY;
}
@@ -1485,9 +1658,8 @@ static int p54_setup_mac(struct ieee80211_hw *dev)
struct p54_setup_mac *setup;
u16 mode;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup) +
- sizeof(struct p54_hdr), P54_CONTROL_TYPE_SETUP,
- GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup),
+ P54_CONTROL_TYPE_SETUP, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -1504,19 +1676,29 @@ static int p54_setup_mac(struct ieee80211_hw *dev)
case NL80211_IFTYPE_MESH_POINT:
mode = P54_FILTER_TYPE_IBSS;
break;
+ case NL80211_IFTYPE_MONITOR:
+ mode = P54_FILTER_TYPE_PROMISCUOUS;
+ break;
default:
- mode = P54_FILTER_TYPE_NONE;
+ mode = P54_FILTER_TYPE_HIBERNATE;
break;
}
- if (priv->filter_flags & FIF_PROMISC_IN_BSS)
+
+ /*
+ * "TRANSPARENT and PROMISCUOUS are mutually exclusive"
+ * STSW45X0C LMAC API - page 12
+ */
+ if (((priv->filter_flags & FIF_PROMISC_IN_BSS) ||
+ (priv->filter_flags & FIF_OTHER_BSS)) &&
+ (mode != P54_FILTER_TYPE_PROMISCUOUS))
mode |= P54_FILTER_TYPE_TRANSPARENT;
} else
- mode = P54_FILTER_TYPE_RX_DISABLED;
+ mode = P54_FILTER_TYPE_HIBERNATE;
setup->mac_mode = cpu_to_le16(mode);
memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN);
memcpy(setup->bssid, priv->bssid, ETH_ALEN);
- setup->rx_antenna = 2; /* automatic */
+ setup->rx_antenna = 2 & priv->rx_diversity_mask; /* automatic */
setup->rx_align = 0;
if (priv->fw_var < 0x500) {
setup->v1.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
@@ -1549,79 +1731,137 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
{
struct p54_common *priv = dev->priv;
struct sk_buff *skb;
- struct p54_scan *chan;
+ struct p54_hdr *hdr;
+ struct p54_scan_head *head;
+ struct p54_iq_autocal_entry *iq_autocal;
+ union p54_scan_body_union *body;
+ struct p54_scan_tail_rate *rate;
+ struct pda_rssi_cal_entry *rssi;
unsigned int i;
void *entry;
- __le16 freq = cpu_to_le16(dev->conf.channel->center_freq);
int band = dev->conf.channel->band;
+ __le16 freq = cpu_to_le16(dev->conf.channel->center_freq);
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*chan) +
- sizeof(struct p54_hdr), P54_CONTROL_TYPE_SCAN,
- GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
+ 2 + sizeof(*iq_autocal) + sizeof(*body) +
+ sizeof(*rate) + 2 * sizeof(*rssi),
+ P54_CONTROL_TYPE_SCAN, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
- chan = (struct p54_scan *) skb_put(skb, sizeof(*chan));
- memset(chan->padding1, 0, sizeof(chan->padding1));
- chan->mode = cpu_to_le16(mode);
- chan->dwell = cpu_to_le16(dwell);
+ head = (struct p54_scan_head *) skb_put(skb, sizeof(*head));
+ memset(head->scan_params, 0, sizeof(head->scan_params));
+ head->mode = cpu_to_le16(mode);
+ head->dwell = cpu_to_le16(dwell);
+ head->freq = freq;
+
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+ __le16 *pa_power_points = (__le16 *) skb_put(skb, 2);
+ *pa_power_points = cpu_to_le16(0x0c);
+ }
+ iq_autocal = (void *) skb_put(skb, sizeof(*iq_autocal));
for (i = 0; i < priv->iq_autocal_len; i++) {
if (priv->iq_autocal[i].freq != freq)
continue;
- memcpy(&chan->iq_autocal, &priv->iq_autocal[i],
- sizeof(*priv->iq_autocal));
+ memcpy(iq_autocal, &priv->iq_autocal[i].params,
+ sizeof(struct p54_iq_autocal_entry));
break;
}
if (i == priv->iq_autocal_len)
goto err;
- for (i = 0; i < priv->output_limit_len; i++) {
- if (priv->output_limit[i].freq != freq)
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW)
+ body = (void *) skb_put(skb, sizeof(body->longbow));
+ else
+ body = (void *) skb_put(skb, sizeof(body->normal));
+
+ for (i = 0; i < priv->output_limit->entries; i++) {
+ __le16 *entry_freq = (void *) (priv->output_limit->data +
+ priv->output_limit->entry_size * i);
+
+ if (*entry_freq != freq)
continue;
- chan->val_barker = 0x38;
- chan->val_bpsk = chan->dup_bpsk =
- priv->output_limit[i].val_bpsk;
- chan->val_qpsk = chan->dup_qpsk =
- priv->output_limit[i].val_qpsk;
- chan->val_16qam = chan->dup_16qam =
- priv->output_limit[i].val_16qam;
- chan->val_64qam = chan->dup_64qam =
- priv->output_limit[i].val_64qam;
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+ memcpy(&body->longbow.power_limits,
+ (void *) entry_freq + sizeof(__le16),
+ priv->output_limit->entry_size);
+ } else {
+ struct pda_channel_output_limit *limits =
+ (void *) entry_freq;
+
+ body->normal.val_barker = 0x38;
+ body->normal.val_bpsk = body->normal.dup_bpsk =
+ limits->val_bpsk;
+ body->normal.val_qpsk = body->normal.dup_qpsk =
+ limits->val_qpsk;
+ body->normal.val_16qam = body->normal.dup_16qam =
+ limits->val_16qam;
+ body->normal.val_64qam = body->normal.dup_64qam =
+ limits->val_64qam;
+ }
break;
}
- if (i == priv->output_limit_len)
+ if (i == priv->output_limit->entries)
goto err;
- entry = priv->curve_data->data;
- for (i = 0; i < priv->curve_data->channels; i++) {
+ entry = (void *)(priv->curve_data->data + priv->curve_data->offset);
+ for (i = 0; i < priv->curve_data->entries; i++) {
if (*((__le16 *)entry) != freq) {
- entry += sizeof(__le16);
- entry += sizeof(struct p54_pa_curve_data_sample) *
- priv->curve_data->points_per_channel;
+ entry += priv->curve_data->entry_size;
continue;
}
- entry += sizeof(__le16);
- chan->pa_points_per_curve = 8;
- memset(chan->curve_data, 0, sizeof(*chan->curve_data));
- memcpy(chan->curve_data, entry,
- sizeof(struct p54_pa_curve_data_sample) *
- min((u8)8, priv->curve_data->points_per_channel));
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+ memcpy(&body->longbow.curve_data,
+ (void *) entry + sizeof(__le16),
+ priv->curve_data->entry_size);
+ } else {
+ struct p54_scan_body *chan = &body->normal;
+ struct pda_pa_curve_data *curve_data =
+ (void *) priv->curve_data->data;
+
+ entry += sizeof(__le16);
+ chan->pa_points_per_curve = 8;
+ memset(chan->curve_data, 0, sizeof(*chan->curve_data));
+ memcpy(chan->curve_data, entry,
+ sizeof(struct p54_pa_curve_data_sample) *
+ min((u8)8, curve_data->points_per_channel));
+ }
break;
}
+ if (i == priv->curve_data->entries)
+ goto err;
- if (priv->fw_var < 0x500) {
- chan->v1_rssi.mul = cpu_to_le16(priv->rssical_db[band].mul);
- chan->v1_rssi.add = cpu_to_le16(priv->rssical_db[band].add);
- } else {
- chan->v2.rssi.mul = cpu_to_le16(priv->rssical_db[band].mul);
- chan->v2.rssi.add = cpu_to_le16(priv->rssical_db[band].add);
- chan->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
- memset(chan->v2.rts_rates, 0, 8);
+ if ((priv->fw_var >= 0x500) && (priv->fw_var < 0x509)) {
+ rate = (void *) skb_put(skb, sizeof(*rate));
+ rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
+ for (i = 0; i < sizeof(rate->rts_rates); i++)
+ rate->rts_rates[i] = i;
+ }
+
+ rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi));
+ rssi->mul = cpu_to_le16(priv->rssical_db[band].mul);
+ rssi->add = cpu_to_le16(priv->rssical_db[band].add);
+ if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+ /* Longbow frontend needs ever more */
+ rssi = (void *) skb_put(skb, sizeof(*rssi));
+ rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn);
+ rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2);
+ }
+
+ if (priv->fw_var >= 0x509) {
+ rate = (void *) skb_put(skb, sizeof(*rate));
+ rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
+ for (i = 0; i < sizeof(rate->rts_rates); i++)
+ rate->rts_rates[i] = i;
}
+
+ hdr = (struct p54_hdr *) skb->data;
+ hdr->len = cpu_to_le16(skb->len - sizeof(*hdr));
+
priv->tx(dev, skb);
return 0;
@@ -1631,23 +1871,22 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
return -EINVAL;
}
-static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
+static int p54_set_leds(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
struct sk_buff *skb;
struct p54_led *led;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led) +
- sizeof(struct p54_hdr), P54_CONTROL_TYPE_LED,
- GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led),
+ P54_CONTROL_TYPE_LED, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
- led = (struct p54_led *)skb_put(skb, sizeof(*led));
- led->mode = cpu_to_le16(mode);
- led->led_permanent = cpu_to_le16(link);
- led->led_temporary = cpu_to_le16(act);
- led->duration = cpu_to_le16(1000);
+ led = (struct p54_led *) skb_put(skb, sizeof(*led));
+ led->flags = cpu_to_le16(0x0003);
+ led->mask[0] = led->mask[1] = cpu_to_le16(priv->softled_state);
+ led->delay[0] = cpu_to_le16(1);
+ led->delay[1] = cpu_to_le16(0);
priv->tx(dev, skb);
return 0;
}
@@ -1666,9 +1905,8 @@ static int p54_set_edcf(struct ieee80211_hw *dev)
struct sk_buff *skb;
struct p54_edcf *edcf;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf) +
- sizeof(struct p54_hdr), P54_CONTROL_TYPE_DCFINIT,
- GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf),
+ P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -1692,6 +1930,42 @@ static int p54_set_edcf(struct ieee80211_hw *dev)
return 0;
}
+static int p54_set_ps(struct ieee80211_hw *dev)
+{
+ struct p54_common *priv = dev->priv;
+ struct sk_buff *skb;
+ struct p54_psm *psm;
+ u16 mode;
+ int i;
+
+ if (dev->conf.flags & IEEE80211_CONF_PS)
+ mode = P54_PSM | P54_PSM_DTIM | P54_PSM_MCBC;
+ else
+ mode = P54_PSM_CAM;
+
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*psm),
+ P54_CONTROL_TYPE_PSM, GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ psm = (struct p54_psm *)skb_put(skb, sizeof(*psm));
+ psm->mode = cpu_to_le16(mode);
+ psm->aid = cpu_to_le16(priv->aid);
+ for (i = 0; i < ARRAY_SIZE(psm->intervals); i++) {
+ psm->intervals[i].interval =
+ cpu_to_le16(dev->conf.listen_interval);
+ psm->intervals[i].periods = cpu_to_le16(1);
+ }
+
+ psm->beacon_rssi_skip_max = 60;
+ psm->rssi_delta_threshold = 0;
+ psm->nr = 0;
+
+ priv->tx(dev, skb);
+
+ return 0;
+}
+
static int p54_beacon_tim(struct sk_buff *skb)
{
/*
@@ -1796,6 +2070,9 @@ static int p54_start(struct ieee80211_hw *dev)
queue_delayed_work(dev->workqueue, &priv->work, 0);
+ priv->softled_state = 0;
+ err = p54_set_leds(dev);
+
out:
mutex_unlock(&priv->conf_mutex);
return err;
@@ -1808,6 +2085,9 @@ static void p54_stop(struct ieee80211_hw *dev)
mutex_lock(&priv->conf_mutex);
priv->mode = NL80211_IFTYPE_UNSPECIFIED;
+ priv->softled_state = 0;
+ p54_set_leds(dev);
+
cancel_delayed_work_sync(&priv->work);
if (priv->cached_beacon)
p54_tx_cancel(dev, priv->cached_beacon);
@@ -1845,7 +2125,6 @@ static int p54_add_interface(struct ieee80211_hw *dev,
memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
p54_setup_mac(dev);
- p54_set_leds(dev, 1, 0, 0);
mutex_unlock(&priv->conf_mutex);
return 0;
}
@@ -1884,6 +2163,11 @@ static int p54_config(struct ieee80211_hw *dev, u32 changed)
if (ret)
goto out;
}
+ if (changed & IEEE80211_CONF_CHANGE_PS) {
+ ret = p54_set_ps(dev);
+ if (ret)
+ goto out;
+ }
out:
mutex_unlock(&priv->conf_mutex);
@@ -1920,8 +2204,6 @@ static int p54_config_interface(struct ieee80211_hw *dev,
goto out;
}
- ret = p54_set_leds(dev, 1, !is_multicast_ether_addr(priv->bssid), 0);
-
out:
mutex_unlock(&priv->conf_mutex);
return ret;
@@ -1935,12 +2217,11 @@ static void p54_configure_filter(struct ieee80211_hw *dev,
struct p54_common *priv = dev->priv;
*total_flags &= FIF_PROMISC_IN_BSS |
- (*total_flags & FIF_PROMISC_IN_BSS) ?
- FIF_FCSFAIL : 0;
+ FIF_OTHER_BSS;
priv->filter_flags = *total_flags;
- if (changed_flags & FIF_PROMISC_IN_BSS)
+ if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS))
p54_setup_mac(dev);
}
@@ -1967,10 +2248,8 @@ static int p54_init_xbow_synth(struct ieee80211_hw *dev)
struct sk_buff *skb;
struct p54_xbow_synth *xbow;
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow) +
- sizeof(struct p54_hdr),
- P54_CONTROL_TYPE_XBOW_SYNTH_CFG,
- GFP_KERNEL);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow),
+ P54_CONTROL_TYPE_XBOW_SYNTH_CFG, GFP_KERNEL);
if (!skb)
return -ENOMEM;
@@ -1999,7 +2278,7 @@ static void p54_work(struct work_struct *work)
* 2. cancel stuck frames / reset the device if necessary.
*/
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(struct p54_hdr) +
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL,
sizeof(struct p54_statistics),
P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL);
if (!skb)
@@ -2022,8 +2301,8 @@ static int p54_get_tx_stats(struct ieee80211_hw *dev,
{
struct p54_common *priv = dev->priv;
- memcpy(stats, &priv->tx_stats[4], sizeof(stats[0]) * dev->queues);
-
+ memcpy(stats, &priv->tx_stats[P54_QUEUE_DATA],
+ sizeof(stats[0]) * dev->queues);
return 0;
}
@@ -2059,7 +2338,7 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
}
static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
struct p54_common *priv = dev->priv;
@@ -2110,9 +2389,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
}
mutex_lock(&priv->conf_mutex);
- skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey) +
- sizeof(struct p54_hdr), P54_CONTROL_TYPE_RX_KEYCACHE,
- GFP_ATOMIC);
+ skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey),
+ P54_CONTROL_TYPE_RX_KEYCACHE, GFP_ATOMIC);
if (!skb) {
mutex_unlock(&priv->conf_mutex);
return -ENOMEM;
@@ -2123,8 +2401,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
rxkey->entry = key->keyidx;
rxkey->key_id = key->keyidx;
rxkey->key_type = algo;
- if (address)
- memcpy(rxkey->mac, address, ETH_ALEN);
+ if (sta)
+ memcpy(rxkey->mac, sta->addr, ETH_ALEN);
else
memset(rxkey->mac, ~0, ETH_ALEN);
if (key->alg != ALG_TKIP) {
@@ -2142,6 +2420,96 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
return 0;
}
+#ifdef CONFIG_P54_LEDS
+static void p54_led_brightness_set(struct led_classdev *led_dev,
+ enum led_brightness brightness)
+{
+ struct p54_led_dev *led = container_of(led_dev, struct p54_led_dev,
+ led_dev);
+ struct ieee80211_hw *dev = led->hw_dev;
+ struct p54_common *priv = dev->priv;
+ int err;
+
+ /* Don't toggle the LED, when the device is down. */
+ if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+ return ;
+
+ if (brightness != LED_OFF)
+ priv->softled_state |= BIT(led->index);
+ else
+ priv->softled_state &= ~BIT(led->index);
+
+ err = p54_set_leds(dev);
+ if (err && net_ratelimit())
+ printk(KERN_ERR "%s: failed to update %s LED.\n",
+ wiphy_name(dev->wiphy), led_dev->name);
+}
+
+static int p54_register_led(struct ieee80211_hw *dev,
+ struct p54_led_dev *led,
+ unsigned int led_index,
+ char *name, char *trigger)
+{
+ int err;
+
+ if (led->registered)
+ return -EEXIST;
+
+ snprintf(led->name, sizeof(led->name), "p54-%s::%s",
+ wiphy_name(dev->wiphy), name);
+ led->hw_dev = dev;
+ led->index = led_index;
+ led->led_dev.name = led->name;
+ led->led_dev.default_trigger = trigger;
+ led->led_dev.brightness_set = p54_led_brightness_set;
+
+ err = led_classdev_register(wiphy_dev(dev->wiphy), &led->led_dev);
+ if (err)
+ printk(KERN_ERR "%s: Failed to register %s LED.\n",
+ wiphy_name(dev->wiphy), name);
+ else
+ led->registered = 1;
+
+ return err;
+}
+
+static int p54_init_leds(struct ieee80211_hw *dev)
+{
+ struct p54_common *priv = dev->priv;
+ int err;
+
+ /*
+ * TODO:
+ * Figure out if the EEPROM contains some hints about the number
+ * of available/programmable LEDs of the device.
+ * But for now, we can assume that we have two programmable LEDs.
+ */
+
+ err = p54_register_led(dev, &priv->assoc_led, 0, "assoc",
+ ieee80211_get_assoc_led_name(dev));
+ if (err)
+ return err;
+
+ err = p54_register_led(dev, &priv->tx_led, 1, "tx",
+ ieee80211_get_tx_led_name(dev));
+ if (err)
+ return err;
+
+ err = p54_set_leds(dev);
+ return err;
+}
+
+static void p54_unregister_leds(struct ieee80211_hw *dev)
+{
+ struct p54_common *priv = dev->priv;
+
+ if (priv->tx_led.registered)
+ led_classdev_unregister(&priv->tx_led.led_dev);
+ if (priv->assoc_led.registered)
+ led_classdev_unregister(&priv->assoc_led.led_dev);
+}
+#endif /* CONFIG_P54_LEDS */
+
static const struct ieee80211_ops p54_ops = {
.tx = p54_tx,
.start = p54_start,
@@ -2175,6 +2543,8 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
priv->basic_rate_mask = 0x15f;
skb_queue_head_init(&priv->tx_queue);
dev->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK |
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM;
@@ -2184,11 +2554,11 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
BIT(NL80211_IFTYPE_MESH_POINT);
dev->channel_change_time = 1000; /* TODO: find actual value */
- priv->tx_stats[0].limit = 1; /* Beacon queue */
- priv->tx_stats[1].limit = 1; /* Probe queue for HW scan */
- priv->tx_stats[2].limit = 3; /* queue for MLMEs */
- priv->tx_stats[3].limit = 3; /* Broadcast / MC queue */
- priv->tx_stats[4].limit = 5; /* Data */
+ priv->tx_stats[P54_QUEUE_BEACON].limit = 1;
+ priv->tx_stats[P54_QUEUE_FWSCAN].limit = 1;
+ priv->tx_stats[P54_QUEUE_MGMT].limit = 3;
+ priv->tx_stats[P54_QUEUE_CAB].limit = 3;
+ priv->tx_stats[P54_QUEUE_DATA].limit = 5;
dev->queues = 1;
priv->noise = -94;
/*
@@ -2212,12 +2582,37 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
}
EXPORT_SYMBOL_GPL(p54_init_common);
+int p54_register_common(struct ieee80211_hw *dev, struct device *pdev)
+{
+ int err;
+
+ err = ieee80211_register_hw(dev);
+ if (err) {
+ dev_err(pdev, "Cannot register device (%d).\n", err);
+ return err;
+ }
+
+#ifdef CONFIG_P54_LEDS
+ err = p54_init_leds(dev);
+ if (err)
+ return err;
+#endif /* CONFIG_P54_LEDS */
+
+ dev_info(pdev, "is registered as '%s'\n", wiphy_name(dev->wiphy));
+ return 0;
+}
+EXPORT_SYMBOL_GPL(p54_register_common);
+
void p54_free_common(struct ieee80211_hw *dev)
{
struct p54_common *priv = dev->priv;
kfree(priv->iq_autocal);
kfree(priv->output_limit);
kfree(priv->curve_data);
+
+#ifdef CONFIG_P54_LEDS
+ p54_unregister_leds(dev);
+#endif /* CONFIG_P54_LEDS */
}
EXPORT_SYMBOL_GPL(p54_free_common);
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
index f5729de83fe1..75ead7a150fc 100644
--- a/drivers/net/wireless/p54/p54common.h
+++ b/drivers/net/wireless/p54/p54common.h
@@ -26,12 +26,17 @@ struct bootrec {
} __attribute__((packed));
#define PDR_SYNTH_FRONTEND_MASK 0x0007
+#define PDR_SYNTH_FRONTEND_DUETTE3 0x0001
+#define PDR_SYNTH_FRONTEND_DUETTE2 0x0002
+#define PDR_SYNTH_FRONTEND_FRISBEE 0x0003
+#define PDR_SYNTH_FRONTEND_XBOW 0x0004
+#define PDR_SYNTH_FRONTEND_LONGBOW 0x0005
#define PDR_SYNTH_IQ_CAL_MASK 0x0018
#define PDR_SYNTH_IQ_CAL_PA_DETECTOR 0x0000
#define PDR_SYNTH_IQ_CAL_DISABLED 0x0008
#define PDR_SYNTH_IQ_CAL_ZIF 0x0010
#define PDR_SYNTH_FAA_SWITCH_MASK 0x0020
-#define PDR_SYNTH_FAA_SWITCH_ENABLED 0x0001
+#define PDR_SYNTH_FAA_SWITCH_ENABLED 0x0020
#define PDR_SYNTH_24_GHZ_MASK 0x0040
#define PDR_SYNTH_24_GHZ_DISABLED 0x0040
#define PDR_SYNTH_5_GHZ_MASK 0x0080
@@ -125,9 +130,13 @@ struct eeprom_pda_wrap {
u8 data[0];
} __attribute__ ((packed));
+struct p54_iq_autocal_entry {
+ __le16 iq_param[4];
+} __attribute__ ((packed));
+
struct pda_iq_autocal_entry {
__le16 freq;
- __le16 iq_param[4];
+ struct p54_iq_autocal_entry params;
} __attribute__ ((packed));
struct pda_channel_output_limit {
@@ -180,6 +189,35 @@ struct pda_rssi_cal_entry {
__le16 add;
} __attribute__ ((packed));
+struct pda_country {
+ u8 regdomain;
+ u8 alpha2[2];
+ u8 flags;
+} __attribute__ ((packed));
+
+/*
+ * Warning: Longbow's structures are bogus.
+ */
+struct p54_channel_output_limit_longbow {
+ __le16 rf_power_points[12];
+} __attribute__ ((packed));
+
+struct p54_pa_curve_data_sample_longbow {
+ __le16 rf_power;
+ __le16 pa_detector;
+ struct {
+ __le16 data[4];
+ } points[3] __attribute__ ((packed));
+} __attribute__ ((packed));
+
+struct pda_custom_wrapper {
+ __le16 entries;
+ __le16 entry_size;
+ __le16 offset;
+ __le16 len;
+ u8 data[0];
+} __attribute__ ((packed));
+
/*
* this defines the PDR codes used to build PDAs as defined in document
* number 553155. The current implementation mirrors version 1.1 of the
@@ -225,8 +263,13 @@ struct pda_rssi_cal_entry {
/* reserved range (0x2000 - 0x7fff) */
/* customer range (0x8000 - 0xffff) */
-#define PDR_BASEBAND_REGISTERS 0x8000
-#define PDR_PER_CHANNEL_BASEBAND_REGISTERS 0x8001
+#define PDR_BASEBAND_REGISTERS 0x8000
+#define PDR_PER_CHANNEL_BASEBAND_REGISTERS 0x8001
+
+/* used by our modificated eeprom image */
+#define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM 0xDEAD
+#define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM 0xBEEF
+#define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM 0xB05D
/* PDR definitions for default country & country list */
#define PDR_COUNTRY_CERT_CODE 0x80
@@ -241,12 +284,6 @@ struct pda_rssi_cal_entry {
#define PDR_COUNTRY_CERT_IODOOR_OUTDOOR 0x30
#define PDR_COUNTRY_CERT_INDEX 0x0F
-/* stored in skb->cb */
-struct memrecord {
- u32 start_addr;
- u32 end_addr;
-};
-
struct p54_eeprom_lm86 {
union {
struct {
@@ -329,7 +366,7 @@ struct p54_frame_sent {
u8 padding;
} __attribute__ ((packed));
-enum p54_tx_data_crypt {
+enum p54_tx_data_crypt {
P54_CRYPTO_NONE = 0,
P54_CRYPTO_WEP,
P54_CRYPTO_TKIP,
@@ -340,6 +377,23 @@ enum p54_tx_data_crypt {
P54_CRYPTO_AESCCMP
};
+enum p54_tx_data_queue {
+ P54_QUEUE_BEACON = 0,
+ P54_QUEUE_FWSCAN = 1,
+ P54_QUEUE_MGMT = 2,
+ P54_QUEUE_CAB = 3,
+ P54_QUEUE_DATA = 4,
+
+ P54_QUEUE_AC_NUM = 4,
+ P54_QUEUE_AC_VO = 4,
+ P54_QUEUE_AC_VI = 5,
+ P54_QUEUE_AC_BE = 6,
+ P54_QUEUE_AC_BK = 7,
+
+ /* keep last */
+ P54_QUEUE_NUM = 8,
+};
+
struct p54_tx_data {
u8 rateset[8];
u8 rts_rate_idx;
@@ -351,9 +405,18 @@ struct p54_tx_data {
u8 backlog;
__le16 durations[4];
u8 tx_antenna;
- u8 output_power;
- u8 cts_rate;
- u8 unalloc2[3];
+ union {
+ struct {
+ u8 cts_rate;
+ __le16 output_power;
+ } __attribute__((packed)) longbow;
+ struct {
+ u8 output_power;
+ u8 cts_rate;
+ u8 unalloc;
+ } __attribute__ ((packed)) normal;
+ } __attribute__ ((packed));
+ u8 unalloc2[2];
u8 align[0];
} __attribute__ ((packed));
@@ -414,11 +477,14 @@ struct p54_setup_mac {
#define P54_SCAN_ACTIVE BIT(2)
#define P54_SCAN_FILTER BIT(3)
-struct p54_scan {
+struct p54_scan_head {
__le16 mode;
__le16 dwell;
- u8 padding1[20];
- struct pda_iq_autocal_entry iq_autocal;
+ u8 scan_params[20];
+ __le16 freq;
+} __attribute__ ((packed));
+
+struct p54_scan_body {
u8 pa_points_per_curve;
u8 val_barker;
u8 val_bpsk;
@@ -430,25 +496,28 @@ struct p54_scan {
u8 dup_qpsk;
u8 dup_16qam;
u8 dup_64qam;
- union {
- struct pda_rssi_cal_entry v1_rssi;
+} __attribute__ ((packed));
- struct {
- __le32 basic_rate_mask;
- u8 rts_rates[8];
- struct pda_rssi_cal_entry rssi;
- } v2 __attribute__ ((packed));
- } __attribute__ ((packed));
+struct p54_scan_body_longbow {
+ struct p54_channel_output_limit_longbow power_limits;
+ struct p54_pa_curve_data_sample_longbow curve_data[8];
+ __le16 unkn[6]; /* maybe more power_limits or rate_mask */
} __attribute__ ((packed));
-#define P54_SCAN_V1_LEN 0x70
-#define P54_SCAN_V2_LEN 0x7c
+union p54_scan_body_union {
+ struct p54_scan_body normal;
+ struct p54_scan_body_longbow longbow;
+} __attribute__ ((packed));
+
+struct p54_scan_tail_rate {
+ __le32 basic_rate_mask;
+ u8 rts_rates[8];
+} __attribute__ ((packed));
struct p54_led {
- __le16 mode;
- __le16 led_temporary;
- __le16 led_permanent;
- __le16 duration;
+ __le16 flags;
+ __le16 mask[2];
+ __le16 delay[2];
} __attribute__ ((packed));
struct p54_edcf {
@@ -511,6 +580,7 @@ struct p54_psm_interval {
__le16 periods;
} __attribute__ ((packed));
+#define P54_PSM_CAM 0
#define P54_PSM BIT(0)
#define P54_PSM_DTIM BIT(1)
#define P54_PSM_MCBC BIT(2)
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index aa367a0ddc49..e3569a0a952d 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -79,6 +79,12 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev)
if (err)
return err;
+ if (priv->common.fw_interface != FW_LM86) {
+ dev_err(&priv->pdev->dev, "wrong firmware, "
+ "please get a LM86(PCI) firmware a try again.\n");
+ return -EINVAL;
+ }
+
data = (__le32 *) priv->firmware->data;
remains = priv->firmware->size;
device_addr = ISL38XX_DEV_FIRMWARE_ADDR;
@@ -407,8 +413,7 @@ static int p54p_open(struct ieee80211_hw *dev)
err = request_irq(priv->pdev->irq, &p54p_interrupt,
IRQF_SHARED, "p54pci", dev);
if (err) {
- printk(KERN_ERR "%s: failed to register IRQ handler\n",
- wiphy_name(dev->wiphy));
+ dev_err(&priv->pdev->dev, "failed to register IRQ handler\n");
return err;
}
@@ -470,30 +475,26 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
err = pci_enable_device(pdev);
if (err) {
- printk(KERN_ERR "%s (p54pci): Cannot enable new PCI device\n",
- pci_name(pdev));
+ dev_err(&pdev->dev, "Cannot enable new PCI device\n");
return err;
}
mem_addr = pci_resource_start(pdev, 0);
mem_len = pci_resource_len(pdev, 0);
if (mem_len < sizeof(struct p54p_csr)) {
- printk(KERN_ERR "%s (p54pci): Too short PCI resources\n",
- pci_name(pdev));
+ dev_err(&pdev->dev, "Too short PCI resources\n");
goto err_disable_dev;
}
err = pci_request_regions(pdev, "p54pci");
if (err) {
- printk(KERN_ERR "%s (p54pci): Cannot obtain PCI resources\n",
- pci_name(pdev));
+ dev_err(&pdev->dev, "Cannot obtain PCI resources\n");
goto err_disable_dev;
}
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
- printk(KERN_ERR "%s (p54pci): No suitable DMA available\n",
- pci_name(pdev));
+ dev_err(&pdev->dev, "No suitable DMA available\n");
goto err_free_reg;
}
@@ -505,8 +506,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
dev = p54_init_common(sizeof(*priv));
if (!dev) {
- printk(KERN_ERR "%s (p54pci): ieee80211 alloc failed\n",
- pci_name(pdev));
+ dev_err(&pdev->dev, "ieee80211 alloc failed\n");
err = -ENOMEM;
goto err_free_reg;
}
@@ -519,17 +519,15 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
priv->map = ioremap(mem_addr, mem_len);
if (!priv->map) {
- printk(KERN_ERR "%s (p54pci): Cannot map device memory\n",
- pci_name(pdev));
- err = -EINVAL; // TODO: use a better error code?
+ dev_err(&pdev->dev, "Cannot map device memory\n");
+ err = -ENOMEM;
goto err_free_dev;
}
priv->ring_control = pci_alloc_consistent(pdev, sizeof(*priv->ring_control),
&priv->ring_control_dma);
if (!priv->ring_control) {
- printk(KERN_ERR "%s (p54pci): Cannot allocate rings\n",
- pci_name(pdev));
+ dev_err(&pdev->dev, "Cannot allocate rings\n");
err = -ENOMEM;
goto err_iounmap;
}
@@ -543,8 +541,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
err = request_firmware(&priv->firmware, "isl3886pci",
&priv->pdev->dev);
if (err) {
- printk(KERN_ERR "%s (p54pci): cannot find firmware "
- "(isl3886pci)\n", pci_name(priv->pdev));
+ dev_err(&pdev->dev, "Cannot find firmware (isl3886pci)\n");
err = request_firmware(&priv->firmware, "isl3886",
&priv->pdev->dev);
if (err)
@@ -559,12 +556,9 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
if (err)
goto err_free_common;
- err = ieee80211_register_hw(dev);
- if (err) {
- printk(KERN_ERR "%s (p54pci): Cannot register netdevice\n",
- pci_name(pdev));
+ err = p54_register_common(dev, &pdev->dev);
+ if (err)
goto err_free_common;
- }
return 0;
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
new file mode 100644
index 000000000000..2b222aaa6f0a
--- /dev/null
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -0,0 +1,765 @@
+/*
+ * Copyright (C) 2008 Christian Lamparter <chunkeey@web.de>
+ * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This driver is a port from stlc45xx:
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+#include <linux/etherdevice.h>
+#include <linux/gpio.h>
+
+#include "p54spi.h"
+#include "p54spi_eeprom.h"
+#include "p54.h"
+
+#include "p54common.h"
+
+MODULE_FIRMWARE("3826.arm");
+MODULE_ALIAS("stlc45xx");
+
+/*
+ * gpios should be handled in board files and provided via platform data,
+ * but because it's currently impossible for p54spi to have a header file
+ * in include/linux, let's use module paramaters for now
+ */
+
+static int p54spi_gpio_power = 97;
+module_param(p54spi_gpio_power, int, 0444);
+MODULE_PARM_DESC(p54spi_gpio_power, "gpio number for power line");
+
+static int p54spi_gpio_irq = 87;
+module_param(p54spi_gpio_irq, int, 0444);
+MODULE_PARM_DESC(p54spi_gpio_irq, "gpio number for irq line");
+
+static void p54spi_spi_read(struct p54s_priv *priv, u8 address,
+ void *buf, size_t len)
+{
+ struct spi_transfer t[2];
+ struct spi_message m;
+ __le16 addr;
+
+ /* We first push the address */
+ addr = cpu_to_le16(address << 8 | SPI_ADRS_READ_BIT_15);
+
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
+
+ t[0].tx_buf = &addr;
+ t[0].len = sizeof(addr);
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].rx_buf = buf;
+ t[1].len = len;
+ spi_message_add_tail(&t[1], &m);
+
+ spi_sync(priv->spi, &m);
+}
+
+
+static void p54spi_spi_write(struct p54s_priv *priv, u8 address,
+ const void *buf, size_t len)
+{
+ struct spi_transfer t[3];
+ struct spi_message m;
+ __le16 addr;
+
+ /* We first push the address */
+ addr = cpu_to_le16(address << 8);
+
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
+
+ t[0].tx_buf = &addr;
+ t[0].len = sizeof(addr);
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].tx_buf = buf;
+ t[1].len = len;
+ spi_message_add_tail(&t[1], &m);
+
+ if (len % 2) {
+ __le16 last_word;
+ last_word = cpu_to_le16(((u8 *)buf)[len - 1]);
+
+ t[2].tx_buf = &last_word;
+ t[2].len = sizeof(last_word);
+ spi_message_add_tail(&t[2], &m);
+ }
+
+ spi_sync(priv->spi, &m);
+}
+
+static u16 p54spi_read16(struct p54s_priv *priv, u8 addr)
+{
+ __le16 val;
+
+ p54spi_spi_read(priv, addr, &val, sizeof(val));
+
+ return le16_to_cpu(val);
+}
+
+static u32 p54spi_read32(struct p54s_priv *priv, u8 addr)
+{
+ __le32 val;
+
+ p54spi_spi_read(priv, addr, &val, sizeof(val));
+
+ return le32_to_cpu(val);
+}
+
+static inline void p54spi_write16(struct p54s_priv *priv, u8 addr, __le16 val)
+{
+ p54spi_spi_write(priv, addr, &val, sizeof(val));
+}
+
+static inline void p54spi_write32(struct p54s_priv *priv, u8 addr, __le32 val)
+{
+ p54spi_spi_write(priv, addr, &val, sizeof(val));
+}
+
+struct p54spi_spi_reg {
+ u16 address; /* __le16 ? */
+ u16 length;
+ char *name;
+};
+
+static const struct p54spi_spi_reg p54spi_registers_array[] =
+{
+ { SPI_ADRS_ARM_INTERRUPTS, 32, "ARM_INT " },
+ { SPI_ADRS_ARM_INT_EN, 32, "ARM_INT_ENA " },
+ { SPI_ADRS_HOST_INTERRUPTS, 32, "HOST_INT " },
+ { SPI_ADRS_HOST_INT_EN, 32, "HOST_INT_ENA" },
+ { SPI_ADRS_HOST_INT_ACK, 32, "HOST_INT_ACK" },
+ { SPI_ADRS_GEN_PURP_1, 32, "GP1_COMM " },
+ { SPI_ADRS_GEN_PURP_2, 32, "GP2_COMM " },
+ { SPI_ADRS_DEV_CTRL_STAT, 32, "DEV_CTRL_STA" },
+ { SPI_ADRS_DMA_DATA, 16, "DMA_DATA " },
+ { SPI_ADRS_DMA_WRITE_CTRL, 16, "DMA_WR_CTRL " },
+ { SPI_ADRS_DMA_WRITE_LEN, 16, "DMA_WR_LEN " },
+ { SPI_ADRS_DMA_WRITE_BASE, 32, "DMA_WR_BASE " },
+ { SPI_ADRS_DMA_READ_CTRL, 16, "DMA_RD_CTRL " },
+ { SPI_ADRS_DMA_READ_LEN, 16, "DMA_RD_LEN " },
+ { SPI_ADRS_DMA_WRITE_BASE, 32, "DMA_RD_BASE " }
+};
+
+static int p54spi_wait_bit(struct p54s_priv *priv, u16 reg, __le32 bits)
+{
+ int i;
+ __le32 buffer;
+
+ for (i = 0; i < 2000; i++) {
+ p54spi_spi_read(priv, reg, &buffer, sizeof(buffer));
+ if (buffer == bits)
+ return 1;
+
+ msleep(1);
+ }
+ return 0;
+}
+
+static int p54spi_request_firmware(struct ieee80211_hw *dev)
+{
+ struct p54s_priv *priv = dev->priv;
+ int ret;
+
+ /* FIXME: should driver use it's own struct device? */
+ ret = request_firmware(&priv->firmware, "3826.arm", &priv->spi->dev);
+
+ if (ret < 0) {
+ dev_err(&priv->spi->dev, "request_firmware() failed: %d", ret);
+ return ret;
+ }
+
+ ret = p54_parse_firmware(dev, priv->firmware);
+ if (ret) {
+ release_firmware(priv->firmware);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int p54spi_request_eeprom(struct ieee80211_hw *dev)
+{
+ struct p54s_priv *priv = dev->priv;
+ const struct firmware *eeprom;
+ int ret;
+
+ /*
+ * allow users to customize their eeprom.
+ */
+
+ ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev);
+ if (ret < 0) {
+ dev_info(&priv->spi->dev, "loading default eeprom...\n");
+ ret = p54_parse_eeprom(dev, (void *) p54spi_eeprom,
+ sizeof(p54spi_eeprom));
+ } else {
+ dev_info(&priv->spi->dev, "loading user eeprom...\n");
+ ret = p54_parse_eeprom(dev, (void *) eeprom->data,
+ (int)eeprom->size);
+ release_firmware(eeprom);
+ }
+ return ret;
+}
+
+static int p54spi_upload_firmware(struct ieee80211_hw *dev)
+{
+ struct p54s_priv *priv = dev->priv;
+ unsigned long fw_len, fw_addr;
+ long _fw_len;
+
+ /* stop the device */
+ p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
+ SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET |
+ SPI_CTRL_STAT_START_HALTED));
+
+ msleep(TARGET_BOOT_SLEEP);
+
+ p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
+ SPI_CTRL_STAT_HOST_OVERRIDE |
+ SPI_CTRL_STAT_START_HALTED));
+
+ msleep(TARGET_BOOT_SLEEP);
+
+ fw_addr = ISL38XX_DEV_FIRMWARE_ADDR;
+ fw_len = priv->firmware->size;
+
+ while (fw_len > 0) {
+ _fw_len = min_t(long, fw_len, SPI_MAX_PACKET_SIZE);
+
+ p54spi_write16(priv, SPI_ADRS_DMA_WRITE_CTRL,
+ cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE));
+
+ if (p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL,
+ cpu_to_le32(HOST_ALLOWED)) == 0) {
+ dev_err(&priv->spi->dev, "fw_upload not allowed "
+ "to DMA write.");
+ return -EAGAIN;
+ }
+
+ p54spi_write16(priv, SPI_ADRS_DMA_WRITE_LEN,
+ cpu_to_le16(_fw_len));
+ p54spi_write32(priv, SPI_ADRS_DMA_WRITE_BASE,
+ cpu_to_le32(fw_addr));
+
+ p54spi_spi_write(priv, SPI_ADRS_DMA_DATA,
+ &priv->firmware->data, _fw_len);
+
+ fw_len -= _fw_len;
+ fw_addr += _fw_len;
+
+ /* FIXME: I think this doesn't work if firmware is large,
+ * this loop goes to second round. fw->data is not
+ * increased at all! */
+ }
+
+ BUG_ON(fw_len != 0);
+
+ /* enable host interrupts */
+ p54spi_write32(priv, SPI_ADRS_HOST_INT_EN,
+ cpu_to_le32(SPI_HOST_INTS_DEFAULT));
+
+ /* boot the device */
+ p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
+ SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET |
+ SPI_CTRL_STAT_RAM_BOOT));
+
+ msleep(TARGET_BOOT_SLEEP);
+
+ p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
+ SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT));
+ msleep(TARGET_BOOT_SLEEP);
+ return 0;
+}
+
+static void p54spi_power_off(struct p54s_priv *priv)
+{
+ disable_irq(gpio_to_irq(p54spi_gpio_irq));
+ gpio_set_value(p54spi_gpio_power, 0);
+}
+
+static void p54spi_power_on(struct p54s_priv *priv)
+{
+ gpio_set_value(p54spi_gpio_power, 1);
+ enable_irq(gpio_to_irq(p54spi_gpio_irq));
+
+ /*
+ * need to wait a while before device can be accessed, the lenght
+ * is just a guess
+ */
+ msleep(10);
+}
+
+static inline void p54spi_int_ack(struct p54s_priv *priv, u32 val)
+{
+ p54spi_write32(priv, SPI_ADRS_HOST_INT_ACK, cpu_to_le32(val));
+}
+
+static void p54spi_wakeup(struct p54s_priv *priv)
+{
+ unsigned long timeout;
+ u32 ints;
+
+ /* wake the chip */
+ p54spi_write32(priv, SPI_ADRS_ARM_INTERRUPTS,
+ cpu_to_le32(SPI_TARGET_INT_WAKEUP));
+
+ /* And wait for the READY interrupt */
+ timeout = jiffies + HZ;
+
+ ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+ while (!(ints & SPI_HOST_INT_READY)) {
+ if (time_after(jiffies, timeout))
+ goto out;
+ ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+ }
+
+ p54spi_int_ack(priv, SPI_HOST_INT_READY);
+
+out:
+ return;
+}
+
+static inline void p54spi_sleep(struct p54s_priv *priv)
+{
+ p54spi_write32(priv, SPI_ADRS_ARM_INTERRUPTS,
+ cpu_to_le32(SPI_TARGET_INT_SLEEP));
+}
+
+static void p54spi_int_ready(struct p54s_priv *priv)
+{
+ p54spi_write32(priv, SPI_ADRS_HOST_INT_EN, cpu_to_le32(
+ SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE));
+
+ switch (priv->fw_state) {
+ case FW_STATE_BOOTING:
+ priv->fw_state = FW_STATE_READY;
+ complete(&priv->fw_comp);
+ break;
+ case FW_STATE_RESETTING:
+ priv->fw_state = FW_STATE_READY;
+ /* TODO: reinitialize state */
+ break;
+ default:
+ break;
+ }
+}
+
+static int p54spi_rx(struct p54s_priv *priv)
+{
+ struct sk_buff *skb;
+ u16 len;
+
+ p54spi_wakeup(priv);
+
+ /* dummy read to flush SPI DMA controller bug */
+ p54spi_read16(priv, SPI_ADRS_GEN_PURP_1);
+
+ len = p54spi_read16(priv, SPI_ADRS_DMA_DATA);
+
+ if (len == 0) {
+ dev_err(&priv->spi->dev, "rx request of zero bytes");
+ return 0;
+ }
+
+ skb = dev_alloc_skb(len);
+ if (!skb) {
+ dev_err(&priv->spi->dev, "could not alloc skb");
+ return 0;
+ }
+
+ p54spi_spi_read(priv, SPI_ADRS_DMA_DATA, skb_put(skb, len), len);
+ p54spi_sleep(priv);
+
+ if (p54_rx(priv->hw, skb) == 0)
+ dev_kfree_skb(skb);
+
+ return 0;
+}
+
+
+static irqreturn_t p54spi_interrupt(int irq, void *config)
+{
+ struct spi_device *spi = config;
+ struct p54s_priv *priv = dev_get_drvdata(&spi->dev);
+
+ queue_work(priv->hw->workqueue, &priv->work);
+
+ return IRQ_HANDLED;
+}
+
+static int p54spi_tx_frame(struct p54s_priv *priv, struct sk_buff *skb)
+{
+ struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
+ struct p54s_dma_regs dma_regs;
+ unsigned long timeout;
+ int ret = 0;
+ u32 ints;
+
+ p54spi_wakeup(priv);
+
+ dma_regs.cmd = cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE);
+ dma_regs.len = cpu_to_le16(skb->len);
+ dma_regs.addr = hdr->req_id;
+
+ p54spi_spi_write(priv, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs,
+ sizeof(dma_regs));
+
+ p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, skb->data, skb->len);
+
+ timeout = jiffies + 2 * HZ;
+ ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+ while (!(ints & SPI_HOST_INT_WR_READY)) {
+ if (time_after(jiffies, timeout)) {
+ dev_err(&priv->spi->dev, "WR_READY timeout");
+ ret = -1;
+ goto out;
+ }
+ ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+ }
+
+ p54spi_int_ack(priv, SPI_HOST_INT_WR_READY);
+ p54spi_sleep(priv);
+
+out:
+ if (FREE_AFTER_TX(skb))
+ p54_free_skb(priv->hw, skb);
+ return ret;
+}
+
+static int p54spi_wq_tx(struct p54s_priv *priv)
+{
+ struct p54s_tx_info *entry;
+ struct sk_buff *skb;
+ struct ieee80211_tx_info *info;
+ struct p54_tx_info *minfo;
+ struct p54s_tx_info *dinfo;
+ int ret = 0;
+
+ spin_lock_bh(&priv->tx_lock);
+
+ while (!list_empty(&priv->tx_pending)) {
+ entry = list_entry(priv->tx_pending.next,
+ struct p54s_tx_info, tx_list);
+
+ list_del_init(&entry->tx_list);
+
+ spin_unlock_bh(&priv->tx_lock);
+
+ dinfo = container_of((void *) entry, struct p54s_tx_info,
+ tx_list);
+ minfo = container_of((void *) dinfo, struct p54_tx_info,
+ data);
+ info = container_of((void *) minfo, struct ieee80211_tx_info,
+ rate_driver_data);
+ skb = container_of((void *) info, struct sk_buff, cb);
+
+ ret = p54spi_tx_frame(priv, skb);
+
+ spin_lock_bh(&priv->tx_lock);
+
+ if (ret < 0) {
+ p54_free_skb(priv->hw, skb);
+ goto out;
+ }
+ }
+
+out:
+ spin_unlock_bh(&priv->tx_lock);
+ return ret;
+}
+
+static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
+{
+ struct p54s_priv *priv = dev->priv;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct p54_tx_info *mi = (struct p54_tx_info *) info->rate_driver_data;
+ struct p54s_tx_info *di = (struct p54s_tx_info *) mi->data;
+
+ BUILD_BUG_ON(sizeof(*di) > sizeof((mi->data)));
+
+ spin_lock_bh(&priv->tx_lock);
+ list_add_tail(&di->tx_list, &priv->tx_pending);
+ spin_unlock_bh(&priv->tx_lock);
+
+ queue_work(priv->hw->workqueue, &priv->work);
+}
+
+static void p54spi_work(struct work_struct *work)
+{
+ struct p54s_priv *priv = container_of(work, struct p54s_priv, work);
+ u32 ints;
+ int ret;
+
+ mutex_lock(&priv->mutex);
+
+ if (priv->fw_state == FW_STATE_OFF &&
+ priv->fw_state == FW_STATE_RESET)
+ goto out;
+
+ ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+
+ if (ints & SPI_HOST_INT_READY) {
+ p54spi_int_ready(priv);
+ p54spi_int_ack(priv, SPI_HOST_INT_READY);
+ }
+
+ if (priv->fw_state != FW_STATE_READY)
+ goto out;
+
+ if (ints & SPI_HOST_INT_UPDATE) {
+ p54spi_int_ack(priv, SPI_HOST_INT_UPDATE);
+ ret = p54spi_rx(priv);
+ if (ret < 0)
+ goto out;
+ }
+ if (ints & SPI_HOST_INT_SW_UPDATE) {
+ p54spi_int_ack(priv, SPI_HOST_INT_SW_UPDATE);
+ ret = p54spi_rx(priv);
+ if (ret < 0)
+ goto out;
+ }
+
+ ret = p54spi_wq_tx(priv);
+ if (ret < 0)
+ goto out;
+
+ ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+
+out:
+ mutex_unlock(&priv->mutex);
+}
+
+static int p54spi_op_start(struct ieee80211_hw *dev)
+{
+ struct p54s_priv *priv = dev->priv;
+ unsigned long timeout;
+ int ret = 0;
+
+ if (mutex_lock_interruptible(&priv->mutex)) {
+ ret = -EINTR;
+ goto out;
+ }
+
+ priv->fw_state = FW_STATE_BOOTING;
+
+ p54spi_power_on(priv);
+
+ ret = p54spi_upload_firmware(dev);
+ if (ret < 0) {
+ p54spi_power_off(priv);
+ goto out_unlock;
+ }
+
+ mutex_unlock(&priv->mutex);
+
+ timeout = msecs_to_jiffies(2000);
+ timeout = wait_for_completion_interruptible_timeout(&priv->fw_comp,
+ timeout);
+ if (!timeout) {
+ dev_err(&priv->spi->dev, "firmware boot failed");
+ p54spi_power_off(priv);
+ ret = -1;
+ goto out;
+ }
+
+ if (mutex_lock_interruptible(&priv->mutex)) {
+ ret = -EINTR;
+ p54spi_power_off(priv);
+ goto out;
+ }
+
+ WARN_ON(priv->fw_state != FW_STATE_READY);
+
+out_unlock:
+ mutex_unlock(&priv->mutex);
+
+out:
+ return ret;
+}
+
+static void p54spi_op_stop(struct ieee80211_hw *dev)
+{
+ struct p54s_priv *priv = dev->priv;
+
+ if (mutex_lock_interruptible(&priv->mutex)) {
+ /* FIXME: how to handle this error? */
+ return;
+ }
+
+ WARN_ON(priv->fw_state != FW_STATE_READY);
+
+ cancel_work_sync(&priv->work);
+
+ p54spi_power_off(priv);
+ spin_lock_bh(&priv->tx_lock);
+ INIT_LIST_HEAD(&priv->tx_pending);
+ spin_unlock_bh(&priv->tx_lock);
+
+ priv->fw_state = FW_STATE_OFF;
+ mutex_unlock(&priv->mutex);
+}
+
+static int __devinit p54spi_probe(struct spi_device *spi)
+{
+ struct p54s_priv *priv = NULL;
+ struct ieee80211_hw *hw;
+ int ret = -EINVAL;
+
+ hw = p54_init_common(sizeof(*priv));
+ if (!hw) {
+ dev_err(&priv->spi->dev, "could not alloc ieee80211_hw");
+ return -ENOMEM;
+ }
+
+ priv = hw->priv;
+ priv->hw = hw;
+ dev_set_drvdata(&spi->dev, priv);
+ priv->spi = spi;
+
+ spi->bits_per_word = 16;
+ spi->max_speed_hz = 24000000;
+
+ ret = spi_setup(spi);
+ if (ret < 0) {
+ dev_err(&priv->spi->dev, "spi_setup failed");
+ goto err_free_common;
+ }
+
+ ret = gpio_request(p54spi_gpio_power, "p54spi power");
+ if (ret < 0) {
+ dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret);
+ goto err_free_common;
+ }
+
+ ret = gpio_request(p54spi_gpio_irq, "p54spi irq");
+ if (ret < 0) {
+ dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret);
+ goto err_free_common;
+ }
+
+ gpio_direction_output(p54spi_gpio_power, 0);
+ gpio_direction_input(p54spi_gpio_irq);
+
+ ret = request_irq(gpio_to_irq(p54spi_gpio_irq),
+ p54spi_interrupt, IRQF_DISABLED, "p54spi",
+ priv->spi);
+ if (ret < 0) {
+ dev_err(&priv->spi->dev, "request_irq() failed");
+ goto err_free_common;
+ }
+
+ set_irq_type(gpio_to_irq(p54spi_gpio_irq),
+ IRQ_TYPE_EDGE_RISING);
+
+ disable_irq(gpio_to_irq(p54spi_gpio_irq));
+
+ INIT_WORK(&priv->work, p54spi_work);
+ init_completion(&priv->fw_comp);
+ INIT_LIST_HEAD(&priv->tx_pending);
+ mutex_init(&priv->mutex);
+ SET_IEEE80211_DEV(hw, &spi->dev);
+ priv->common.open = p54spi_op_start;
+ priv->common.stop = p54spi_op_stop;
+ priv->common.tx = p54spi_op_tx;
+
+ ret = p54spi_request_firmware(hw);
+ if (ret < 0)
+ goto err_free_common;
+
+ ret = p54spi_request_eeprom(hw);
+ if (ret)
+ goto err_free_common;
+
+ ret = p54_register_common(hw, &priv->spi->dev);
+ if (ret)
+ goto err_free_common;
+
+ return 0;
+
+err_free_common:
+ p54_free_common(priv->hw);
+ return ret;
+}
+
+static int __devexit p54spi_remove(struct spi_device *spi)
+{
+ struct p54s_priv *priv = dev_get_drvdata(&spi->dev);
+
+ ieee80211_unregister_hw(priv->hw);
+
+ free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
+
+ gpio_free(p54spi_gpio_power);
+ gpio_free(p54spi_gpio_irq);
+ release_firmware(priv->firmware);
+
+ mutex_destroy(&priv->mutex);
+
+ p54_free_common(priv->hw);
+ ieee80211_free_hw(priv->hw);
+
+ return 0;
+}
+
+
+static struct spi_driver p54spi_driver = {
+ .driver = {
+ /* use cx3110x name because board-n800.c uses that for the
+ * SPI port */
+ .name = "cx3110x",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = p54spi_probe,
+ .remove = __devexit_p(p54spi_remove),
+};
+
+static int __init p54spi_init(void)
+{
+ int ret;
+
+ ret = spi_register_driver(&p54spi_driver);
+ if (ret < 0) {
+ printk(KERN_ERR "failed to register SPI driver: %d", ret);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void __exit p54spi_exit(void)
+{
+ spi_unregister_driver(&p54spi_driver);
+}
+
+module_init(p54spi_init);
+module_exit(p54spi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
diff --git a/drivers/net/wireless/p54/p54spi.h b/drivers/net/wireless/p54/p54spi.h
new file mode 100644
index 000000000000..7fbe8d8fc67c
--- /dev/null
+++ b/drivers/net/wireless/p54/p54spi.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2008 Christian Lamparter <chunkeey@web.de>
+ *
+ * This driver is a port from stlc45xx:
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef P54SPI_H
+#define P54SPI_H
+
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <net/mac80211.h>
+
+#include "p54.h"
+
+/* Bit 15 is read/write bit; ON = READ, OFF = WRITE */
+#define SPI_ADRS_READ_BIT_15 0x8000
+
+#define SPI_ADRS_ARM_INTERRUPTS 0x00
+#define SPI_ADRS_ARM_INT_EN 0x04
+
+#define SPI_ADRS_HOST_INTERRUPTS 0x08
+#define SPI_ADRS_HOST_INT_EN 0x0c
+#define SPI_ADRS_HOST_INT_ACK 0x10
+
+#define SPI_ADRS_GEN_PURP_1 0x14
+#define SPI_ADRS_GEN_PURP_2 0x18
+
+#define SPI_ADRS_DEV_CTRL_STAT 0x26 /* high word */
+
+#define SPI_ADRS_DMA_DATA 0x28
+
+#define SPI_ADRS_DMA_WRITE_CTRL 0x2c
+#define SPI_ADRS_DMA_WRITE_LEN 0x2e
+#define SPI_ADRS_DMA_WRITE_BASE 0x30
+
+#define SPI_ADRS_DMA_READ_CTRL 0x34
+#define SPI_ADRS_DMA_READ_LEN 0x36
+#define SPI_ADRS_DMA_READ_BASE 0x38
+
+#define SPI_CTRL_STAT_HOST_OVERRIDE 0x8000
+#define SPI_CTRL_STAT_START_HALTED 0x4000
+#define SPI_CTRL_STAT_RAM_BOOT 0x2000
+#define SPI_CTRL_STAT_HOST_RESET 0x1000
+#define SPI_CTRL_STAT_HOST_CPU_EN 0x0800
+
+#define SPI_DMA_WRITE_CTRL_ENABLE 0x0001
+#define SPI_DMA_READ_CTRL_ENABLE 0x0001
+#define HOST_ALLOWED (1 << 7)
+
+#define SPI_TIMEOUT 100 /* msec */
+
+#define SPI_MAX_TX_PACKETS 32
+
+#define SPI_MAX_PACKET_SIZE 32767
+
+#define SPI_TARGET_INT_WAKEUP 0x00000001
+#define SPI_TARGET_INT_SLEEP 0x00000002
+#define SPI_TARGET_INT_RDDONE 0x00000004
+
+#define SPI_TARGET_INT_CTS 0x00004000
+#define SPI_TARGET_INT_DR 0x00008000
+
+#define SPI_HOST_INT_READY 0x00000001
+#define SPI_HOST_INT_WR_READY 0x00000002
+#define SPI_HOST_INT_SW_UPDATE 0x00000004
+#define SPI_HOST_INT_UPDATE 0x10000000
+
+/* clear to send */
+#define SPI_HOST_INT_CR 0x00004000
+
+/* data ready */
+#define SPI_HOST_INT_DR 0x00008000
+
+#define SPI_HOST_INTS_DEFAULT \
+ (SPI_HOST_INT_READY | SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE)
+
+#define TARGET_BOOT_SLEEP 50
+
+struct p54s_dma_regs {
+ __le16 cmd;
+ __le16 len;
+ __le32 addr;
+} __attribute__ ((packed));
+
+struct p54s_tx_info {
+ struct list_head tx_list;
+};
+
+struct p54s_priv {
+ /* p54_common has to be the first entry */
+ struct p54_common common;
+ struct ieee80211_hw *hw;
+ struct spi_device *spi;
+
+ struct work_struct work;
+
+ struct mutex mutex;
+ struct completion fw_comp;
+
+ spinlock_t tx_lock;
+
+ /* protected by tx_lock */
+ struct list_head tx_pending;
+
+ enum fw_state fw_state;
+ const struct firmware *firmware;
+};
+
+#endif /* P54SPI_H */
diff --git a/drivers/net/wireless/p54/p54spi_eeprom.h b/drivers/net/wireless/p54/p54spi_eeprom.h
new file mode 100644
index 000000000000..1ea1050911d9
--- /dev/null
+++ b/drivers/net/wireless/p54/p54spi_eeprom.h
@@ -0,0 +1,678 @@
+/*
+ * Copyright (C) 2003 Conexant Americas Inc. All Rights Reserved.
+ * Copyright (C) 2004, 2005, 2006 Nokia Corporation
+ * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2008 Christian Lamparter <chunkeey@web.de>
+ *
+ * based on:
+ * - cx3110x's pda.h from Nokia
+ * - cx3110-transfer.log by Johannes Berg
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef P54SPI_EEPROM_H
+#define P54SPI_EEPROM_H
+
+static unsigned char p54spi_eeprom[] = {
+
+/* struct eeprom_pda_wrap */
+0x47, 0x4d, 0x55, 0xaa, /* magic */
+0x00, 0x00, /* pad */
+0x00, 0x00, /* eeprom_pda_data_wrap length */
+0x00, 0x00, 0x00, 0x00, /* arm opcode */
+
+/* bogus MAC address */
+0x04, 0x00, 0x01, 0x01, /* PDR_MAC_ADDRESS */
+ 0x00, 0x02, 0xee, 0xc0, 0xff, 0xee,
+
+/* struct bootrec_exp_if */
+0x06, 0x00, 0x01, 0x10, /* PDR_INTERFACE_LIST */
+ 0x00, 0x00, /* role */
+ 0x0f, 0x00, /* if_id */
+ 0x85, 0x00, /* variant = Longbow RF, 2GHz */
+ 0x01, 0x00, /* btm_compat */
+ 0x1f, 0x00, /* top_compat */
+
+0x03, 0x00, 0x02, 0x10, /* PDR_HARDWARE_PLATFORM_COMPONENT_ID */
+ 0x03, 0x20, 0x00, 0x43,
+
+/* struct pda_country[6] */
+0x0d, 0x00, 0x07, 0x10, /* PDR_COUNTRY_LIST */
+ 0x10, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00,
+ 0x31, 0x00, 0x00, 0x00,
+ 0x32, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00,
+
+/* struct pda_country */
+0x03, 0x00, 0x08, 0x10, /* PDR_DEFAULT_COUNTRY */
+ 0x30, 0x00, 0x00, 0x00, /* ETSI */
+
+0x03, 0x00, 0x00, 0x11, /* PDR_ANTENNA_GAIN */
+ 0x08, 0x08, 0x08, 0x08,
+
+0x09, 0x00, 0xad, 0xde, /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM */
+ 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+/* struct pda_custom_wrapper */
+0x10, 0x06, 0x5d, 0xb0, /* PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM */
+ 0x0d, 0x00, 0xee, 0x00, /* 13 entries, 238 bytes per entry */
+ 0x00, 0x00, 0x16, 0x0c, /* no offset, 3094 total len */
+ /* 2412 MHz */
+ 0x6c, 0x09,
+ 0x10, 0x01, 0x9a, 0x84,
+ 0xaa, 0x8a, 0xaa, 0x8a, 0xaa, 0x8a, 0xaa, 0x8a,
+ 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6,
+ 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6, 0x3c, 0xb6,
+ 0xf0, 0x00, 0x94, 0x6c,
+ 0x99, 0x82, 0x99, 0x82, 0x99, 0x82, 0x99, 0x82,
+ 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae,
+ 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae, 0x2b, 0xae,
+ 0xd0, 0x00, 0xaa, 0x5a,
+ 0x88, 0x7a, 0x88, 0x7a, 0x88, 0x7a, 0x88, 0x7a,
+ 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6,
+ 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6, 0x1a, 0xa6,
+ 0xa0, 0x00, 0xf3, 0x47,
+ 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
+ 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a,
+ 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a,
+ 0x50, 0x00, 0x59, 0x36,
+ 0x43, 0x5a, 0x43, 0x5a, 0x43, 0x5a, 0x43, 0x5a,
+ 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85,
+ 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85, 0xd5, 0x85,
+ 0x00, 0x00, 0xe4, 0x2d,
+ 0x18, 0x46, 0x18, 0x46, 0x18, 0x46, 0x18, 0x46,
+ 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71,
+ 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71, 0xaa, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2417 MHz */
+ 0x71, 0x09,
+ 0x10, 0x01, 0xb9, 0x83,
+ 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a,
+ 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6,
+ 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6,
+ 0xf0, 0x00, 0x2e, 0x6c,
+ 0x68, 0x82, 0x68, 0x82, 0x68, 0x82, 0x68, 0x82,
+ 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad,
+ 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad,
+ 0xd0, 0x00, 0x8d, 0x5a,
+ 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a,
+ 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5,
+ 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5,
+ 0xa0, 0x00, 0x0a, 0x48,
+ 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e,
+ 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99,
+ 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99,
+ 0x50, 0x00, 0x7c, 0x36,
+ 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59,
+ 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85,
+ 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85,
+ 0x00, 0x00, 0xf5, 0x2d,
+ 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45,
+ 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71,
+ 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2422 MHz */
+ 0x76, 0x09,
+ 0x10, 0x01, 0xb9, 0x83,
+ 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a, 0x7d, 0x8a,
+ 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6,
+ 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6, 0x0f, 0xb6,
+ 0xf0, 0x00, 0x2e, 0x6c,
+ 0x68, 0x82, 0x68, 0x82, 0x68, 0x82, 0x68, 0x82,
+ 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad,
+ 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0xad,
+ 0xd0, 0x00, 0x8d, 0x5a,
+ 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a, 0x52, 0x7a,
+ 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5,
+ 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5, 0xe4, 0xa5,
+ 0xa0, 0x00, 0x0a, 0x48,
+ 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e, 0x32, 0x6e,
+ 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99,
+ 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99, 0xc4, 0x99,
+ 0x50, 0x00, 0x7c, 0x36,
+ 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59, 0xfc, 0x59,
+ 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85,
+ 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85, 0x8e, 0x85,
+ 0x00, 0x00, 0xf5, 0x2d,
+ 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45, 0xc6, 0x45,
+ 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71,
+ 0x58, 0x71, 0x58, 0x71, 0x58, 0x71, 0x58, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2427 MHz */
+ 0x7b, 0x09,
+ 0x10, 0x01, 0x48, 0x83,
+ 0x67, 0x8a, 0x67, 0x8a, 0x67, 0x8a, 0x67, 0x8a,
+ 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5,
+ 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5, 0xf9, 0xb5,
+ 0xf0, 0x00, 0xfb, 0x6b,
+ 0x50, 0x82, 0x50, 0x82, 0x50, 0x82, 0x50, 0x82,
+ 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad,
+ 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad, 0xe2, 0xad,
+ 0xd0, 0x00, 0x7e, 0x5a,
+ 0x38, 0x7a, 0x38, 0x7a, 0x38, 0x7a, 0x38, 0x7a,
+ 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5,
+ 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5, 0xca, 0xa5,
+ 0xa0, 0x00, 0x15, 0x48,
+ 0x14, 0x6e, 0x14, 0x6e, 0x14, 0x6e, 0x14, 0x6e,
+ 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99,
+ 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99, 0xa6, 0x99,
+ 0x50, 0x00, 0x8e, 0x36,
+ 0xd9, 0x59, 0xd9, 0x59, 0xd9, 0x59, 0xd9, 0x59,
+ 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85,
+ 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85, 0x6b, 0x85,
+ 0x00, 0x00, 0xfe, 0x2d,
+ 0x9d, 0x45, 0x9d, 0x45, 0x9d, 0x45, 0x9d, 0x45,
+ 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71,
+ 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71, 0x2f, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2432 MHz */
+ 0x80, 0x09,
+ 0x10, 0x01, 0xd7, 0x82,
+ 0x51, 0x8a, 0x51, 0x8a, 0x51, 0x8a, 0x51, 0x8a,
+ 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5,
+ 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5, 0xe3, 0xb5,
+ 0xf0, 0x00, 0xc8, 0x6b,
+ 0x37, 0x82, 0x37, 0x82, 0x37, 0x82, 0x37, 0x82,
+ 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad,
+ 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad, 0xc9, 0xad,
+ 0xd0, 0x00, 0x6f, 0x5a,
+ 0x1d, 0x7a, 0x1d, 0x7a, 0x1d, 0x7a, 0x1d, 0x7a,
+ 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5,
+ 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5, 0xaf, 0xa5,
+ 0xa0, 0x00, 0x20, 0x48,
+ 0xf6, 0x6d, 0xf6, 0x6d, 0xf6, 0x6d, 0xf6, 0x6d,
+ 0x88, 0x99, 0x88, 0x99, 0x88, 0x99, 0x88, 0x99,
+ 0x88, 0x99, 0x88, 0x99, 0x88, 0x99, 0x88, 0x99,
+ 0x50, 0x00, 0x9f, 0x36,
+ 0xb5, 0x59, 0xb5, 0x59, 0xb5, 0x59, 0xb5, 0x59,
+ 0x47, 0x85, 0x47, 0x85, 0x47, 0x85, 0x47, 0x85,
+ 0x47, 0x85, 0x47, 0x85, 0x47, 0x85, 0x47, 0x85,
+ 0x00, 0x00, 0x06, 0x2e,
+ 0x74, 0x45, 0x74, 0x45, 0x74, 0x45, 0x74, 0x45,
+ 0x06, 0x71, 0x06, 0x71, 0x06, 0x71, 0x06, 0x71,
+ 0x06, 0x71, 0x06, 0x71, 0x06, 0x71, 0x06, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2437 MHz */
+ 0x85, 0x09,
+ 0x10, 0x01, 0x67, 0x82,
+ 0x3a, 0x8a, 0x3a, 0x8a, 0x3a, 0x8a, 0x3a, 0x8a,
+ 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5,
+ 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5, 0xcc, 0xb5,
+ 0xf0, 0x00, 0x95, 0x6b,
+ 0x1f, 0x82, 0x1f, 0x82, 0x1f, 0x82, 0x1f, 0x82,
+ 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad,
+ 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad, 0xb1, 0xad,
+ 0xd0, 0x00, 0x61, 0x5a,
+ 0x02, 0x7a, 0x02, 0x7a, 0x02, 0x7a, 0x02, 0x7a,
+ 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5,
+ 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5, 0x94, 0xa5,
+ 0xa0, 0x00, 0x2c, 0x48,
+ 0xd8, 0x6d, 0xd8, 0x6d, 0xd8, 0x6d, 0xd8, 0x6d,
+ 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99,
+ 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99, 0x6a, 0x99,
+ 0x50, 0x00, 0xb1, 0x36,
+ 0x92, 0x59, 0x92, 0x59, 0x92, 0x59, 0x92, 0x59,
+ 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85,
+ 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85,
+ 0x00, 0x00, 0x0f, 0x2e,
+ 0x4b, 0x45, 0x4b, 0x45, 0x4b, 0x45, 0x4b, 0x45,
+ 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70,
+ 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70, 0xdd, 0x70,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2442 MHz */
+ 0x8a, 0x09,
+ 0x10, 0x01, 0xf6, 0x81,
+ 0x24, 0x8a, 0x24, 0x8a, 0x24, 0x8a, 0x24, 0x8a,
+ 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5,
+ 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5, 0xb6, 0xb5,
+ 0xf0, 0x00, 0x62, 0x6b,
+ 0x06, 0x82, 0x06, 0x82, 0x06, 0x82, 0x06, 0x82,
+ 0x98, 0xad, 0x98, 0xad, 0x98, 0xad, 0x98, 0xad,
+ 0x98, 0xad, 0x98, 0xad, 0x98, 0xad, 0x98, 0xad,
+ 0xd0, 0x00, 0x52, 0x5a,
+ 0xe7, 0x79, 0xe7, 0x79, 0xe7, 0x79, 0xe7, 0x79,
+ 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5,
+ 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5, 0x79, 0xa5,
+ 0xa0, 0x00, 0x37, 0x48,
+ 0xba, 0x6d, 0xba, 0x6d, 0xba, 0x6d, 0xba, 0x6d,
+ 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99,
+ 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99, 0x4c, 0x99,
+ 0x50, 0x00, 0xc2, 0x36,
+ 0x6e, 0x59, 0x6e, 0x59, 0x6e, 0x59, 0x6e, 0x59,
+ 0x00, 0x85, 0x00, 0x85, 0x00, 0x85, 0x00, 0x85,
+ 0x00, 0x85, 0x00, 0x85, 0x00, 0x85, 0x00, 0x85,
+ 0x00, 0x00, 0x17, 0x2e,
+ 0x22, 0x45, 0x22, 0x45, 0x22, 0x45, 0x22, 0x45,
+ 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70,
+ 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70, 0xb4, 0x70,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2447 MHz */
+ 0x8f, 0x09,
+ 0x10, 0x01, 0x75, 0x83,
+ 0x61, 0x8a, 0x61, 0x8a, 0x61, 0x8a, 0x61, 0x8a,
+ 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5,
+ 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5, 0xf3, 0xb5,
+ 0xf0, 0x00, 0x4b, 0x6c,
+ 0x3f, 0x82, 0x3f, 0x82, 0x3f, 0x82, 0x3f, 0x82,
+ 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad,
+ 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad, 0xd1, 0xad,
+ 0xd0, 0x00, 0xda, 0x5a,
+ 0x1c, 0x7a, 0x1c, 0x7a, 0x1c, 0x7a, 0x1c, 0x7a,
+ 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5,
+ 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5, 0xae, 0xa5,
+ 0xa0, 0x00, 0x6d, 0x48,
+ 0xe9, 0x6d, 0xe9, 0x6d, 0xe9, 0x6d, 0xe9, 0x6d,
+ 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99,
+ 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99, 0x7b, 0x99,
+ 0x50, 0x00, 0xc6, 0x36,
+ 0x92, 0x59, 0x92, 0x59, 0x92, 0x59, 0x92, 0x59,
+ 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85,
+ 0x24, 0x85, 0x24, 0x85, 0x24, 0x85, 0x24, 0x85,
+ 0x00, 0x00, 0x15, 0x2e,
+ 0x3c, 0x45, 0x3c, 0x45, 0x3c, 0x45, 0x3c, 0x45,
+ 0xce, 0x70, 0xce, 0x70, 0xce, 0x70, 0xce, 0x70,
+ 0xce, 0x70, 0xce, 0x70, 0xce, 0x70, 0xce, 0x70,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2452 MHz */
+ 0x94, 0x09,
+ 0x10, 0x01, 0xf4, 0x84,
+ 0x9e, 0x8a, 0x9e, 0x8a, 0x9e, 0x8a, 0x9e, 0x8a,
+ 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6,
+ 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6, 0x30, 0xb6,
+ 0xf0, 0x00, 0x34, 0x6d,
+ 0x77, 0x82, 0x77, 0x82, 0x77, 0x82, 0x77, 0x82,
+ 0x09, 0xae, 0x09, 0xae, 0x09, 0xae, 0x09, 0xae,
+ 0x09, 0xae, 0x09, 0xae, 0x09, 0xae, 0x09, 0xae,
+ 0xd0, 0x00, 0x62, 0x5b,
+ 0x50, 0x7a, 0x50, 0x7a, 0x50, 0x7a, 0x50, 0x7a,
+ 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5,
+ 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5, 0xe2, 0xa5,
+ 0xa0, 0x00, 0xa2, 0x48,
+ 0x17, 0x6e, 0x17, 0x6e, 0x17, 0x6e, 0x17, 0x6e,
+ 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99,
+ 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99, 0xa9, 0x99,
+ 0x50, 0x00, 0xc9, 0x36,
+ 0xb7, 0x59, 0xb7, 0x59, 0xb7, 0x59, 0xb7, 0x59,
+ 0x49, 0x85, 0x49, 0x85, 0x49, 0x85, 0x49, 0x85,
+ 0x49, 0x85, 0x49, 0x85, 0x49, 0x85, 0x49, 0x85,
+ 0x00, 0x00, 0x12, 0x2e,
+ 0x57, 0x45, 0x57, 0x45, 0x57, 0x45, 0x57, 0x45,
+ 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70,
+ 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70, 0xe9, 0x70,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2452 MHz */
+ 0x99, 0x09,
+ 0x10, 0x01, 0x74, 0x86,
+ 0xdb, 0x8a, 0xdb, 0x8a, 0xdb, 0x8a, 0xdb, 0x8a,
+ 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6,
+ 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6, 0x6d, 0xb6,
+ 0xf0, 0x00, 0x1e, 0x6e,
+ 0xb0, 0x82, 0xb0, 0x82, 0xb0, 0x82, 0xb0, 0x82,
+ 0x42, 0xae, 0x42, 0xae, 0x42, 0xae, 0x42, 0xae,
+ 0x42, 0xae, 0x42, 0xae, 0x42, 0xae, 0x42, 0xae,
+ 0xd0, 0x00, 0xeb, 0x5b,
+ 0x85, 0x7a, 0x85, 0x7a, 0x85, 0x7a, 0x85, 0x7a,
+ 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6,
+ 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6, 0x17, 0xa6,
+ 0xa0, 0x00, 0xd8, 0x48,
+ 0x46, 0x6e, 0x46, 0x6e, 0x46, 0x6e, 0x46, 0x6e,
+ 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99,
+ 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99, 0xd8, 0x99,
+ 0x50, 0x00, 0xcd, 0x36,
+ 0xdb, 0x59, 0xdb, 0x59, 0xdb, 0x59, 0xdb, 0x59,
+ 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85,
+ 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85, 0x6d, 0x85,
+ 0x00, 0x00, 0x10, 0x2e,
+ 0x71, 0x45, 0x71, 0x45, 0x71, 0x45, 0x71, 0x45,
+ 0x03, 0x71, 0x03, 0x71, 0x03, 0x71, 0x03, 0x71,
+ 0x03, 0x71, 0x03, 0x71, 0x03, 0x71, 0x03, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2557 MHz */
+ 0x9e, 0x09,
+ 0x10, 0x01, 0xf3, 0x87,
+ 0x17, 0x8b, 0x17, 0x8b, 0x17, 0x8b, 0x17, 0x8b,
+ 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6,
+ 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6, 0xa9, 0xb6,
+ 0xf0, 0x00, 0x07, 0x6f,
+ 0xe9, 0x82, 0xe9, 0x82, 0xe9, 0x82, 0xe9, 0x82,
+ 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae,
+ 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae, 0x7b, 0xae,
+ 0xd0, 0x00, 0x73, 0x5c,
+ 0xba, 0x7a, 0xba, 0x7a, 0xba, 0x7a, 0xba, 0x7a,
+ 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6,
+ 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6, 0x4c, 0xa6,
+ 0xa0, 0x00, 0x0d, 0x49,
+ 0x74, 0x6e, 0x74, 0x6e, 0x74, 0x6e, 0x74, 0x6e,
+ 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a,
+ 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a, 0x06, 0x9a,
+ 0x50, 0x00, 0xd1, 0x36,
+ 0xff, 0x59, 0xff, 0x59, 0xff, 0x59, 0xff, 0x59,
+ 0x91, 0x85, 0x91, 0x85, 0x91, 0x85, 0x91, 0x85,
+ 0x91, 0x85, 0x91, 0x85, 0x91, 0x85, 0x91, 0x85,
+ 0x00, 0x00, 0x0e, 0x2e,
+ 0x8b, 0x45, 0x8b, 0x45, 0x8b, 0x45, 0x8b, 0x45,
+ 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71,
+ 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71, 0x1d, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2562 MHz */
+ 0xa3, 0x09,
+ 0x10, 0x01, 0x72, 0x89,
+ 0x54, 0x8b, 0x54, 0x8b, 0x54, 0x8b, 0x54, 0x8b,
+ 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6,
+ 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6, 0xe6, 0xb6,
+ 0xf0, 0x00, 0xf0, 0x6f,
+ 0x21, 0x83, 0x21, 0x83, 0x21, 0x83, 0x21, 0x83,
+ 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae,
+ 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae, 0xb3, 0xae,
+ 0xd0, 0x00, 0xfb, 0x5c,
+ 0xee, 0x7a, 0xee, 0x7a, 0xee, 0x7a, 0xee, 0x7a,
+ 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6,
+ 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6, 0x80, 0xa6,
+ 0xa0, 0x00, 0x43, 0x49,
+ 0xa3, 0x6e, 0xa3, 0x6e, 0xa3, 0x6e, 0xa3, 0x6e,
+ 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a,
+ 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a, 0x35, 0x9a,
+ 0x50, 0x00, 0xd4, 0x36,
+ 0x24, 0x5a, 0x24, 0x5a, 0x24, 0x5a, 0x24, 0x5a,
+ 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85,
+ 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85, 0xb6, 0x85,
+ 0x00, 0x00, 0x0b, 0x2e,
+ 0xa6, 0x45, 0xa6, 0x45, 0xa6, 0x45, 0xa6, 0x45,
+ 0x38, 0x71, 0x38, 0x71, 0x38, 0x71, 0x38, 0x71,
+ 0x38, 0x71, 0x38, 0x71, 0x38, 0x71, 0x38, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+ /* 2572 MHz */
+ 0xa8, 0x09,
+ 0x10, 0x01, 0xf1, 0x8a,
+ 0x91, 0x8b, 0x91, 0x8b, 0x91, 0x8b, 0x91, 0x8b,
+ 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7,
+ 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7, 0x23, 0xb7,
+ 0xf0, 0x00, 0xd9, 0x70,
+ 0x5a, 0x83, 0x5a, 0x83, 0x5a, 0x83, 0x5a, 0x83,
+ 0xec, 0xae, 0xec, 0xae, 0xec, 0xae, 0xec, 0xae,
+ 0xec, 0xae, 0xec, 0xae, 0xec, 0xae, 0xec, 0xae,
+ 0xd0, 0x00, 0x83, 0x5d,
+ 0x23, 0x7b, 0x23, 0x7b, 0x23, 0x7b, 0x23, 0x7b,
+ 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6,
+ 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6, 0xb5, 0xa6,
+ 0xa0, 0x00, 0x78, 0x49,
+ 0xd1, 0x6e, 0xd1, 0x6e, 0xd1, 0x6e, 0xd1, 0x6e,
+ 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a,
+ 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a, 0x63, 0x9a,
+ 0x50, 0x00, 0xd8, 0x36,
+ 0x48, 0x5a, 0x48, 0x5a, 0x48, 0x5a, 0x48, 0x5a,
+ 0xda, 0x85, 0xda, 0x85, 0xda, 0x85, 0xda, 0x85,
+ 0xda, 0x85, 0xda, 0x85, 0xda, 0x85, 0xda, 0x85,
+ 0x00, 0x00, 0x09, 0x2e,
+ 0xc0, 0x45, 0xc0, 0x45, 0xc0, 0x45, 0xc0, 0x45,
+ 0x52, 0x71, 0x52, 0x71, 0x52, 0x71, 0x52, 0x71,
+ 0x52, 0x71, 0x52, 0x71, 0x52, 0x71, 0x52, 0x71,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+
+/*
+ * Not really sure if this is actually the power_limit database,
+ * it looks a bit "related" to PDR_PRISM_ZIF_TX_IQ_CALIBRATION
+ */
+/* struct pda_custom_wrapper */
+0xae, 0x00, 0xef, 0xbe, /* PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM */
+ 0x0d, 0x00, 0x1a, 0x00, /* 13 entries, 26 bytes per entry */
+ 0x00, 0x00, 0x52, 0x01, /* no offset, 338 bytes total */
+
+ /* 2412 MHz */
+ 0x6c, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2417 MHz */
+ 0x71, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2422 MHz */
+ 0x76, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2427 MHz */
+ 0x7b, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2432 MHz */
+ 0x80, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2437 MHz */
+ 0x85, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2442 MHz */
+ 0x8a, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2447 MHz */
+ 0x8f, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2452 MHz */
+ 0x94, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2457 MHz */
+ 0x99, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2462 MHz */
+ 0x9e, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2467 MHz */
+ 0xa3, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+ /* 2472 MHz */
+ 0xa8, 0x09,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+
+/* struct pda_iq_autocal_entry[13] */
+0x42, 0x00, 0x06, 0x19, /* PDR_PRISM_ZIF_TX_IQ_CALIBRATION */
+ /* 2412 MHz */
+ 0x6c, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2417 MHz */
+ 0x71, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2422 MHz */
+ 0x76, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2427 MHz */
+ 0x7b, 0x09, 0x26, 0x00, 0xf8, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2432 MHz */
+ 0x80, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2437 MHz */
+ 0x85, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2442 MHz */
+ 0x8a, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2447 MHz */
+ 0x8f, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2452 MHz */
+ 0x94, 0x09, 0x25, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xff, 0x00,
+ /* 2457 MHz */
+ 0x99, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
+ /* 2462 MHz */
+ 0x9e, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
+ /* 2467 MHz */
+ 0xa3, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
+ /* 2472 MHz */
+ 0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
+
+0x02, 0x00, 0x00, 0x00, /* PDR_END */
+ 0xa8, 0xf5 /* bogus data */
+};
+
+#endif /* P54SPI_EEPROM_H */
+
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 5de2ebfb28c7..da6640afc835 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -424,9 +424,46 @@ static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
data, len, &alen, 2000);
}
+static const char p54u_romboot_3887[] = "~~~~";
+static const char p54u_firmware_upload_3887[] = "<\r";
+
+static int p54u_device_reset_3887(struct ieee80211_hw *dev)
+{
+ struct p54u_priv *priv = dev->priv;
+ int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING);
+ u8 buf[4];
+
+ if (lock) {
+ ret = usb_lock_device_for_reset(priv->udev, priv->intf);
+ if (ret < 0) {
+ dev_err(&priv->udev->dev, "(p54usb) unable to lock "
+ " device for reset: %d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = usb_reset_device(priv->udev);
+ if (lock)
+ usb_unlock_device(priv->udev);
+
+ if (ret) {
+ dev_err(&priv->udev->dev, "(p54usb) unable to reset "
+ "device: %d\n", ret);
+ return ret;
+ }
+
+ memcpy(&buf, p54u_romboot_3887, sizeof(buf));
+ ret = p54u_bulk_msg(priv, P54U_PIPE_DATA,
+ buf, sizeof(buf));
+ if (ret)
+ dev_err(&priv->udev->dev, "(p54usb) unable to jump to "
+ "boot ROM: %d\n", ret);
+
+ return ret;
+}
+
static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
{
- static char start_string[] = "~~~~<\r";
struct p54u_priv *priv = dev->priv;
const struct firmware *fw_entry = NULL;
int err, alen;
@@ -445,12 +482,9 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
goto err_bufalloc;
}
- memcpy(buf, start_string, 4);
- err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4);
- if (err) {
- dev_err(&priv->udev->dev, "(p54usb) reset failed! (%d)\n", err);
+ err = p54u_device_reset_3887(dev);
+ if (err)
goto err_reset;
- }
err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev);
if (err) {
@@ -466,15 +500,22 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
if (err)
goto err_upload_failed;
+ if (priv->common.fw_interface != FW_LM87) {
+ dev_err(&priv->udev->dev, "wrong firmware, "
+ "please get a LM87 firmware and try again.\n");
+ err = -EINVAL;
+ goto err_upload_failed;
+ }
+
left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
- strcpy(buf, start_string);
- left -= strlen(start_string);
- tmp += strlen(start_string);
+ strcpy(buf, p54u_firmware_upload_3887);
+ left -= strlen(p54u_firmware_upload_3887);
+ tmp += strlen(p54u_firmware_upload_3887);
data = fw_entry->data;
remains = fw_entry->size;
- hdr = (struct x2_header *)(buf + strlen(start_string));
+ hdr = (struct x2_header *)(buf + strlen(p54u_firmware_upload_3887));
memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
hdr->fw_length = cpu_to_le32(fw_entry->size);
@@ -616,6 +657,14 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
return err;
}
+ if (priv->common.fw_interface != FW_LM86) {
+ dev_err(&priv->udev->dev, "wrong firmware, "
+ "please get a LM86(USB) firmware and try again.\n");
+ kfree(buf);
+ release_firmware(fw_entry);
+ return -EINVAL;
+ }
+
#define P54U_WRITE(type, addr, data) \
do {\
err = p54u_write(priv, buf, type,\
@@ -876,6 +925,9 @@ static int __devinit p54u_probe(struct usb_interface *intf,
SET_IEEE80211_DEV(dev, &intf->dev);
usb_set_intfdata(intf, dev);
priv->udev = udev;
+ priv->intf = intf;
+ skb_queue_head_init(&priv->rx_queue);
+ init_usb_anchor(&priv->submitted);
usb_get_dev(udev);
@@ -918,20 +970,15 @@ static int __devinit p54u_probe(struct usb_interface *intf,
if (err)
goto err_free_dev;
- skb_queue_head_init(&priv->rx_queue);
- init_usb_anchor(&priv->submitted);
-
p54u_open(dev);
err = p54_read_eeprom(dev);
p54u_stop(dev);
if (err)
goto err_free_dev;
- err = ieee80211_register_hw(dev);
- if (err) {
- dev_err(&udev->dev, "(p54usb) Cannot register netdevice\n");
+ err = p54_register_common(dev, &udev->dev);
+ if (err)
goto err_free_dev;
- }
return 0;
@@ -958,11 +1005,24 @@ static void __devexit p54u_disconnect(struct usb_interface *intf)
ieee80211_free_hw(dev);
}
+static int p54u_pre_reset(struct usb_interface *intf)
+{
+ return 0;
+}
+
+static int p54u_post_reset(struct usb_interface *intf)
+{
+ return 0;
+}
+
static struct usb_driver p54u_driver = {
.name = "p54usb",
.id_table = p54u_table,
.probe = p54u_probe,
.disconnect = p54u_disconnect,
+ .pre_reset = p54u_pre_reset,
+ .post_reset = p54u_post_reset,
+ .soft_unbind = 1,
};
static int __init p54u_init(void)
diff --git a/drivers/net/wireless/p54/p54usb.h b/drivers/net/wireless/p54/p54usb.h
index 54ee738bf2af..8bc58982d8dd 100644
--- a/drivers/net/wireless/p54/p54usb.h
+++ b/drivers/net/wireless/p54/p54usb.h
@@ -126,6 +126,7 @@ struct p54u_rx_info {
struct p54u_priv {
struct p54_common common;
struct usb_device *udev;
+ struct usb_interface *intf;
enum {
P54U_NET2280 = 0,
P54U_3887
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 57a150a22de5..4c97c6ad6f5d 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -2981,7 +2981,8 @@ prism54_set_spy(struct net_device *ndev,
union iwreq_data *uwrq, char *extra)
{
islpci_private *priv = netdev_priv(ndev);
- u32 u, oid = OID_INL_CONFIG;
+ u32 u;
+ enum oid_num_t oid = OID_INL_CONFIG;
down_write(&priv->mib_sem);
mgt_get(priv, OID_INL_CONFIG, &u);
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 9196825ed1b5..e26d7b3ceab5 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -43,7 +43,6 @@
static int prism54_bring_down(islpci_private *);
static int islpci_alloc_memory(islpci_private *);
-static struct net_device_stats *islpci_statistics(struct net_device *);
/* Temporary dummy MAC address to use until firmware is loaded.
* The idea there is that some tools (such as nameif) may query
@@ -614,18 +613,6 @@ islpci_reset(islpci_private *priv, int reload_firmware)
return rc;
}
-static struct net_device_stats *
-islpci_statistics(struct net_device *ndev)
-{
- islpci_private *priv = netdev_priv(ndev);
-
-#if VERBOSE > SHOW_ERROR_MESSAGES
- DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics\n");
-#endif
-
- return &priv->statistics;
-}
-
/******************************************************************************
Network device configuration functions
******************************************************************************/
@@ -804,10 +791,21 @@ static void islpci_ethtool_get_drvinfo(struct net_device *dev,
strcpy(info->version, DRV_VERSION);
}
-static struct ethtool_ops islpci_ethtool_ops = {
+static const struct ethtool_ops islpci_ethtool_ops = {
.get_drvinfo = islpci_ethtool_get_drvinfo,
};
+static const struct net_device_ops islpci_netdev_ops = {
+ .ndo_open = islpci_open,
+ .ndo_stop = islpci_close,
+ .ndo_do_ioctl = prism54_ioctl,
+ .ndo_start_xmit = islpci_eth_transmit,
+ .ndo_tx_timeout = islpci_eth_tx_timeout,
+ .ndo_set_mac_address = prism54_set_mac_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
struct net_device *
islpci_setup(struct pci_dev *pdev)
{
@@ -827,25 +825,16 @@ islpci_setup(struct pci_dev *pdev)
ndev->irq = pdev->irq;
/* initialize the function pointers */
- ndev->open = &islpci_open;
- ndev->stop = &islpci_close;
- ndev->get_stats = &islpci_statistics;
- ndev->do_ioctl = &prism54_ioctl;
- ndev->wireless_handlers =
- (struct iw_handler_def *) &prism54_handler_def;
+ ndev->netdev_ops = &islpci_netdev_ops;
+ ndev->wireless_handlers = &prism54_handler_def;
ndev->ethtool_ops = &islpci_ethtool_ops;
- ndev->hard_start_xmit = &islpci_eth_transmit;
/* ndev->set_multicast_list = &islpci_set_multicast_list; */
ndev->addr_len = ETH_ALEN;
- ndev->set_mac_address = &prism54_set_mac_address;
/* Get a non-zero dummy MAC address for nameif. Jean II */
memcpy(ndev->dev_addr, dummy_mac, 6);
-#ifdef HAVE_TX_TIMEOUT
ndev->watchdog_timeo = ISLPCI_TX_TIMEOUT;
- ndev->tx_timeout = &islpci_eth_tx_timeout;
-#endif
/* allocate a private device structure to the network device */
priv = netdev_priv(ndev);
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index 8e55a5fcffae..c4d0f19b7cbc 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -158,9 +158,6 @@ typedef struct {
dma_addr_t pci_map_tx_address[ISL38XX_CB_TX_QSIZE];
dma_addr_t pci_map_rx_address[ISL38XX_CB_RX_QSIZE];
- /* driver network interface members */
- struct net_device_stats statistics;
-
/* wait for a reset interrupt */
wait_queue_head_t reset_done;
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index e43bae97ed8f..ef3ef4551b31 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -23,6 +23,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
+#include <asm/byteorder.h>
#include "prismcompat.h"
#include "isl_38xx.h"
@@ -230,8 +231,8 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
/* set the transmission time */
ndev->trans_start = jiffies;
- priv->statistics.tx_packets++;
- priv->statistics.tx_bytes += skb->len;
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += skb->len;
/* trigger the device */
islpci_trigger(priv);
@@ -242,7 +243,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
return 0;
drop_free:
- priv->statistics.tx_dropped++;
+ ndev->stats.tx_dropped++;
spin_unlock_irqrestore(&priv->slock, flags);
dev_kfree_skb(skb);
return err;
@@ -407,8 +408,8 @@ islpci_eth_receive(islpci_private *priv)
skb->protocol = eth_type_trans(skb, ndev);
}
skb->ip_summed = CHECKSUM_NONE;
- priv->statistics.rx_packets++;
- priv->statistics.rx_bytes += size;
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += size;
/* deliver the skb to the network layer */
#ifdef ISLPCI_ETH_DEBUG
@@ -471,8 +472,8 @@ islpci_eth_receive(islpci_private *priv)
wmb();
/* increment the driver read pointer */
- add_le32p(&control_block->
- driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
+ le32_add_cpu(&control_block->
+ driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
}
/* trigger the device */
@@ -496,10 +497,9 @@ void
islpci_eth_tx_timeout(struct net_device *ndev)
{
islpci_private *priv = netdev_priv(ndev);
- struct net_device_stats *statistics = &priv->statistics;
/* increment the transmit error counter */
- statistics->tx_errors++;
+ ndev->stats.tx_errors++;
if (!priv->reset_task_pending) {
printk(KERN_WARNING
diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h
index f91a88fc1e35..87a1734663da 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.h
+++ b/drivers/net/wireless/prism54/islpci_mgt.h
@@ -85,12 +85,6 @@ extern int pc_debug;
#define PIMFOR_FLAG_APPLIC_ORIGIN 0x01
#define PIMFOR_FLAG_LITTLE_ENDIAN 0x02
-static inline void
-add_le32p(__le32 * le_number, u32 add)
-{
- *le_number = cpu_to_le32(le32_to_cpup(le_number) + add);
-}
-
void display_buffer(char *, int);
/*
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index 57a4ac34bed6..1187e6112a64 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -698,7 +698,7 @@ int
mgt_commit(islpci_private *priv)
{
int rvalue;
- u32 u;
+ enum oid_num_t u;
if (islpci_get_state(priv) < PRV_STATE_INIT)
return 0;
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 99ec7d622518..fa90d1d8d82e 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -8,7 +8,7 @@
* Copyright (c) 1998 Corey Thomas (corey@world.std.com)
*
* This driver is free software; you can redistribute it and/or modify
- * it under the terms of version 2 only of the GNU General Public License as
+ * it under the terms of version 2 only of the GNU General Public License as
* published by the Free Software Foundation.
*
* It is distributed in the hope that it will be useful,
@@ -27,7 +27,7 @@
*
* Daniele Bellucci <bellucda@tiscali.it> - 07/10/2003
* - Audit copy_to_user in ioctl(SIOCGIWESSID)
- *
+ *
=============================================================================*/
#include <linux/module.h>
@@ -65,8 +65,8 @@
/* Warning : these stuff will slow down the driver... */
#define WIRELESS_SPY /* Enable spying addresses */
/* Definitions we need for spy */
-typedef struct iw_statistics iw_stats;
-typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */
+typedef struct iw_statistics iw_stats;
+typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */
#include "rayctl.h"
#include "ray_cs.h"
@@ -86,7 +86,7 @@ static int ray_debug;
static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0);
/* #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); */
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(args);
+#define DEBUG(n, args...) if (pc_debug > (n)) printk(args);
#else
#define DEBUG(n, args...)
#endif
@@ -108,12 +108,12 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
static void ray_update_multi_list(struct net_device *dev, int all);
static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
- unsigned char *data, int len);
-static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type,
- unsigned char *data);
+ unsigned char *data, int len);
+static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx,
+ UCHAR msg_type, unsigned char *data);
static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len);
-static iw_stats * ray_get_wireless_stats(struct net_device * dev);
-static const struct iw_handler_def ray_handler_def;
+static iw_stats *ray_get_wireless_stats(struct net_device *dev);
+static const struct iw_handler_def ray_handler_def;
/***** Prototypes for raylink functions **************************************/
static int asc_to_int(char a);
@@ -124,7 +124,7 @@ static int get_free_ccs(ray_dev_t *local);
static int get_free_tx_ccs(ray_dev_t *local);
static void init_startup_params(ray_dev_t *local);
static int parse_addr(char *in_str, UCHAR *out);
-static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, UCHAR type);
+static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev, UCHAR type);
static int ray_init(struct net_device *dev);
static int interrupt_ecf(ray_dev_t *local, int ccs);
static void ray_reset(struct net_device *dev);
@@ -132,17 +132,17 @@ static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, i
static void verify_dl_startup(u_long);
/* Prototypes for interrpt time functions **********************************/
-static irqreturn_t ray_interrupt (int reg, void *dev_id);
+static irqreturn_t ray_interrupt(int reg, void *dev_id);
static void clear_interrupt(ray_dev_t *local);
-static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
- unsigned int pkt_addr, int rx_len);
+static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
+ unsigned int pkt_addr, int rx_len);
static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len);
static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs __iomem *prcs);
static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs);
static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
- unsigned int pkt_addr, int rx_len);
-static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned int pkt_addr,
- int rx_len);
+ unsigned int pkt_addr, int rx_len);
+static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
+ unsigned int pkt_addr, int rx_len);
static void associate(ray_dev_t *local);
/* Card command functions */
@@ -219,82 +219,97 @@ module_param(phy_addr, charp, 0);
module_param(ray_mem_speed, int, 0);
static UCHAR b5_default_startup_parms[] = {
- 0, 0, /* Adhoc station */
- 'L','I','N','U','X', 0, 0, 0, /* 32 char ESSID */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, /* Active scan, CA Mode */
- 0, 0, 0, 0, 0, 0, /* No default MAC addr */
- 0x7f, 0xff, /* Frag threshold */
- 0x00, 0x80, /* Hop time 128 Kus*/
- 0x01, 0x00, /* Beacon period 256 Kus */
- 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout*/
- 0x1d, 0x82, 0x4e, /* SIFS, DIFS, PIFS */
- 0x7f, 0xff, /* RTS threshold */
- 0x04, 0xe2, 0x38, 0xA4, /* scan_dwell, max_scan_dwell */
- 0x05, /* assoc resp timeout thresh */
- 0x08, 0x02, 0x08, /* adhoc, infra, super cycle max*/
- 0, /* Promiscuous mode */
- 0x0c, 0x0bd, /* Unique word */
- 0x32, /* Slot time */
- 0xff, 0xff, /* roam-low snr, low snr count */
- 0x05, 0xff, /* Infra, adhoc missed bcn thresh */
- 0x01, 0x0b, 0x4f, /* USA, hop pattern, hop pat length */
+ 0, 0, /* Adhoc station */
+ 'L', 'I', 'N', 'U', 'X', 0, 0, 0, /* 32 char ESSID */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, /* Active scan, CA Mode */
+ 0, 0, 0, 0, 0, 0, /* No default MAC addr */
+ 0x7f, 0xff, /* Frag threshold */
+ 0x00, 0x80, /* Hop time 128 Kus */
+ 0x01, 0x00, /* Beacon period 256 Kus */
+ 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout */
+ 0x1d, 0x82, 0x4e, /* SIFS, DIFS, PIFS */
+ 0x7f, 0xff, /* RTS threshold */
+ 0x04, 0xe2, 0x38, 0xA4, /* scan_dwell, max_scan_dwell */
+ 0x05, /* assoc resp timeout thresh */
+ 0x08, 0x02, 0x08, /* adhoc, infra, super cycle max */
+ 0, /* Promiscuous mode */
+ 0x0c, 0x0bd, /* Unique word */
+ 0x32, /* Slot time */
+ 0xff, 0xff, /* roam-low snr, low snr count */
+ 0x05, 0xff, /* Infra, adhoc missed bcn thresh */
+ 0x01, 0x0b, 0x4f, /* USA, hop pattern, hop pat length */
/* b4 - b5 differences start here */
- 0x00, 0x3f, /* CW max */
- 0x00, 0x0f, /* CW min */
- 0x04, 0x08, /* Noise gain, limit offset */
- 0x28, 0x28, /* det rssi, med busy offsets */
- 7, /* det sync thresh */
- 0, 2, 2, /* test mode, min, max */
- 0, /* allow broadcast SSID probe resp */
- 0, 0, /* privacy must start, can join */
- 2, 0, 0, 0, 0, 0, 0, 0 /* basic rate set */
+ 0x00, 0x3f, /* CW max */
+ 0x00, 0x0f, /* CW min */
+ 0x04, 0x08, /* Noise gain, limit offset */
+ 0x28, 0x28, /* det rssi, med busy offsets */
+ 7, /* det sync thresh */
+ 0, 2, 2, /* test mode, min, max */
+ 0, /* allow broadcast SSID probe resp */
+ 0, 0, /* privacy must start, can join */
+ 2, 0, 0, 0, 0, 0, 0, 0 /* basic rate set */
};
static UCHAR b4_default_startup_parms[] = {
- 0, 0, /* Adhoc station */
- 'L','I','N','U','X', 0, 0, 0, /* 32 char ESSID */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, /* Active scan, CA Mode */
- 0, 0, 0, 0, 0, 0, /* No default MAC addr */
- 0x7f, 0xff, /* Frag threshold */
- 0x02, 0x00, /* Hop time */
- 0x00, 0x01, /* Beacon period */
- 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout*/
- 0x1d, 0x82, 0xce, /* SIFS, DIFS, PIFS */
- 0x7f, 0xff, /* RTS threshold */
- 0xfb, 0x1e, 0xc7, 0x5c, /* scan_dwell, max_scan_dwell */
- 0x05, /* assoc resp timeout thresh */
- 0x04, 0x02, 0x4, /* adhoc, infra, super cycle max*/
- 0, /* Promiscuous mode */
- 0x0c, 0x0bd, /* Unique word */
- 0x4e, /* Slot time (TBD seems wrong)*/
- 0xff, 0xff, /* roam-low snr, low snr count */
- 0x05, 0xff, /* Infra, adhoc missed bcn thresh */
- 0x01, 0x0b, 0x4e, /* USA, hop pattern, hop pat length */
+ 0, 0, /* Adhoc station */
+ 'L', 'I', 'N', 'U', 'X', 0, 0, 0, /* 32 char ESSID */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, /* Active scan, CA Mode */
+ 0, 0, 0, 0, 0, 0, /* No default MAC addr */
+ 0x7f, 0xff, /* Frag threshold */
+ 0x02, 0x00, /* Hop time */
+ 0x00, 0x01, /* Beacon period */
+ 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout */
+ 0x1d, 0x82, 0xce, /* SIFS, DIFS, PIFS */
+ 0x7f, 0xff, /* RTS threshold */
+ 0xfb, 0x1e, 0xc7, 0x5c, /* scan_dwell, max_scan_dwell */
+ 0x05, /* assoc resp timeout thresh */
+ 0x04, 0x02, 0x4, /* adhoc, infra, super cycle max */
+ 0, /* Promiscuous mode */
+ 0x0c, 0x0bd, /* Unique word */
+ 0x4e, /* Slot time (TBD seems wrong) */
+ 0xff, 0xff, /* roam-low snr, low snr count */
+ 0x05, 0xff, /* Infra, adhoc missed bcn thresh */
+ 0x01, 0x0b, 0x4e, /* USA, hop pattern, hop pat length */
/* b4 - b5 differences start here */
- 0x3f, 0x0f, /* CW max, min */
- 0x04, 0x08, /* Noise gain, limit offset */
- 0x28, 0x28, /* det rssi, med busy offsets */
- 7, /* det sync thresh */
- 0, 2, 2 /* test mode, min, max*/
+ 0x3f, 0x0f, /* CW max, min */
+ 0x04, 0x08, /* Noise gain, limit offset */
+ 0x28, 0x28, /* det rssi, med busy offsets */
+ 7, /* det sync thresh */
+ 0, 2, 2 /* test mode, min, max */
};
+
/*===========================================================================*/
-static unsigned char eth2_llc[] = {0xaa, 0xaa, 3, 0, 0, 0};
+static unsigned char eth2_llc[] = { 0xaa, 0xaa, 3, 0, 0, 0 };
static char hop_pattern_length[] = { 1,
- USA_HOP_MOD, EUROPE_HOP_MOD,
- JAPAN_HOP_MOD, KOREA_HOP_MOD,
- SPAIN_HOP_MOD, FRANCE_HOP_MOD,
- ISRAEL_HOP_MOD, AUSTRALIA_HOP_MOD,
- JAPAN_TEST_HOP_MOD
+ USA_HOP_MOD, EUROPE_HOP_MOD,
+ JAPAN_HOP_MOD, KOREA_HOP_MOD,
+ SPAIN_HOP_MOD, FRANCE_HOP_MOD,
+ ISRAEL_HOP_MOD, AUSTRALIA_HOP_MOD,
+ JAPAN_TEST_HOP_MOD
};
-static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
+static char rcsid[] =
+ "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
+
+static const struct net_device_ops ray_netdev_ops = {
+ .ndo_init = ray_dev_init,
+ .ndo_open = ray_open,
+ .ndo_stop = ray_dev_close,
+ .ndo_start_xmit = ray_dev_start_xmit,
+ .ndo_set_config = ray_dev_config,
+ .ndo_get_stats = ray_get_stats,
+ .ndo_set_multicast_list = set_multicast_list,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
/*=============================================================================
ray_attach() creates an "instance" of the driver, allocating
@@ -306,71 +321,66 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.
=============================================================================*/
static int ray_probe(struct pcmcia_device *p_dev)
{
- ray_dev_t *local;
- struct net_device *dev;
-
- DEBUG(1, "ray_attach()\n");
-
- /* Allocate space for private device-specific data */
- dev = alloc_etherdev(sizeof(ray_dev_t));
- if (!dev)
- goto fail_alloc_dev;
-
- local = netdev_priv(dev);
- local->finder = p_dev;
-
- /* The io structure describes IO port mapping. None used here */
- p_dev->io.NumPorts1 = 0;
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- p_dev->io.IOAddrLines = 5;
-
- /* Interrupt setup. For PCMCIA, driver takes what's given */
- p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
- p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
- p_dev->irq.Handler = &ray_interrupt;
-
- /* General socket configuration */
- p_dev->conf.Attributes = CONF_ENABLE_IRQ;
- p_dev->conf.IntType = INT_MEMORY_AND_IO;
- p_dev->conf.ConfigIndex = 1;
-
- p_dev->priv = dev;
- p_dev->irq.Instance = dev;
-
- local->finder = p_dev;
- local->card_status = CARD_INSERTED;
- local->authentication_state = UNAUTHENTICATED;
- local->num_multi = 0;
- DEBUG(2,"ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n",
- p_dev,dev,local,&ray_interrupt);
-
- /* Raylink entries in the device structure */
- dev->hard_start_xmit = &ray_dev_start_xmit;
- dev->set_config = &ray_dev_config;
- dev->get_stats = &ray_get_stats;
- SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
- dev->wireless_handlers = &ray_handler_def;
+ ray_dev_t *local;
+ struct net_device *dev;
+
+ DEBUG(1, "ray_attach()\n");
+
+ /* Allocate space for private device-specific data */
+ dev = alloc_etherdev(sizeof(ray_dev_t));
+ if (!dev)
+ goto fail_alloc_dev;
+
+ local = netdev_priv(dev);
+ local->finder = p_dev;
+
+ /* The io structure describes IO port mapping. None used here */
+ p_dev->io.NumPorts1 = 0;
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = 5;
+
+ /* Interrupt setup. For PCMCIA, driver takes what's given */
+ p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
+ p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ p_dev->irq.Handler = &ray_interrupt;
+
+ /* General socket configuration */
+ p_dev->conf.Attributes = CONF_ENABLE_IRQ;
+ p_dev->conf.IntType = INT_MEMORY_AND_IO;
+ p_dev->conf.ConfigIndex = 1;
+
+ p_dev->priv = dev;
+ p_dev->irq.Instance = dev;
+
+ local->finder = p_dev;
+ local->card_status = CARD_INSERTED;
+ local->authentication_state = UNAUTHENTICATED;
+ local->num_multi = 0;
+ DEBUG(2, "ray_attach p_dev = %p, dev = %p, local = %p, intr = %p\n",
+ p_dev, dev, local, &ray_interrupt);
+
+ /* Raylink entries in the device structure */
+ dev->netdev_ops = &ray_netdev_ops;
+ SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
+ dev->wireless_handlers = &ray_handler_def;
#ifdef WIRELESS_SPY
- local->wireless_data.spy_data = &local->spy_data;
- dev->wireless_data = &local->wireless_data;
-#endif /* WIRELESS_SPY */
+ local->wireless_data.spy_data = &local->spy_data;
+ dev->wireless_data = &local->wireless_data;
+#endif /* WIRELESS_SPY */
- dev->set_multicast_list = &set_multicast_list;
- DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");
- dev->init = &ray_dev_init;
- dev->open = &ray_open;
- dev->stop = &ray_dev_close;
- netif_stop_queue(dev);
+ DEBUG(2, "ray_cs ray_attach calling ether_setup.)\n");
+ netif_stop_queue(dev);
- init_timer(&local->timer);
+ init_timer(&local->timer);
- this_device = p_dev;
- return ray_config(p_dev);
+ this_device = p_dev;
+ return ray_config(p_dev);
fail_alloc_dev:
- return -ENOMEM;
+ return -ENOMEM;
} /* ray_attach */
+
/*=============================================================================
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
@@ -379,25 +389,27 @@ fail_alloc_dev:
=============================================================================*/
static void ray_detach(struct pcmcia_device *link)
{
- struct net_device *dev;
- ray_dev_t *local;
+ struct net_device *dev;
+ ray_dev_t *local;
- DEBUG(1, "ray_detach(0x%p)\n", link);
+ DEBUG(1, "ray_detach(0x%p)\n", link);
- this_device = NULL;
- dev = link->priv;
+ this_device = NULL;
+ dev = link->priv;
- ray_release(link);
+ ray_release(link);
- local = netdev_priv(dev);
- del_timer(&local->timer);
+ local = netdev_priv(dev);
+ del_timer(&local->timer);
- if (link->priv) {
- if (link->dev_node) unregister_netdev(dev);
- free_netdev(dev);
- }
- DEBUG(2,"ray_cs ray_detach ending\n");
+ if (link->priv) {
+ if (link->dev_node)
+ unregister_netdev(dev);
+ free_netdev(dev);
+ }
+ DEBUG(2, "ray_cs ray_detach ending\n");
} /* ray_detach */
+
/*=============================================================================
ray_config() is run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
@@ -408,92 +420,101 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
#define MAX_TUPLE_SIZE 128
static int ray_config(struct pcmcia_device *link)
{
- int last_fn = 0, last_ret = 0;
- int i;
- win_req_t req;
- memreq_t mem;
- struct net_device *dev = (struct net_device *)link->priv;
- ray_dev_t *local = netdev_priv(dev);
-
- DEBUG(1, "ray_config(0x%p)\n", link);
-
- /* Determine card type and firmware version */
- printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n",
- link->prod_id[0] ? link->prod_id[0] : " ",
- link->prod_id[1] ? link->prod_id[1] : " ",
- link->prod_id[2] ? link->prod_id[2] : " ",
- link->prod_id[3] ? link->prod_id[3] : " ");
-
- /* Now allocate an interrupt line. Note that this does not
- actually assign a handler to the interrupt.
- */
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- dev->irq = link->irq.AssignedIRQ;
-
- /* This actually configures the PCMCIA socket -- setting up
- the I/O windows and the interrupt mapping.
- */
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ int last_fn = 0, last_ret = 0;
+ int i;
+ win_req_t req;
+ memreq_t mem;
+ struct net_device *dev = (struct net_device *)link->priv;
+ ray_dev_t *local = netdev_priv(dev);
+
+ DEBUG(1, "ray_config(0x%p)\n", link);
+
+ /* Determine card type and firmware version */
+ printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n",
+ link->prod_id[0] ? link->prod_id[0] : " ",
+ link->prod_id[1] ? link->prod_id[1] : " ",
+ link->prod_id[2] ? link->prod_id[2] : " ",
+ link->prod_id[3] ? link->prod_id[3] : " ");
+
+ /* Now allocate an interrupt line. Note that this does not
+ actually assign a handler to the interrupt.
+ */
+ CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+ dev->irq = link->irq.AssignedIRQ;
+
+ /* This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping.
+ */
+ CS_CHECK(RequestConfiguration,
+ pcmcia_request_configuration(link, &link->conf));
/*** Set up 32k window for shared memory (transmit and control) ************/
- req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
- req.Base = 0;
- req.Size = 0x8000;
- req.AccessSpeed = ray_mem_speed;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
- mem.CardOffset = 0x0000; mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
- local->sram = ioremap(req.Base,req.Size);
+ req.Attributes =
+ WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
+ req.Base = 0;
+ req.Size = 0x8000;
+ req.AccessSpeed = ray_mem_speed;
+ CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+ mem.CardOffset = 0x0000;
+ mem.Page = 0;
+ CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+ local->sram = ioremap(req.Base, req.Size);
/*** Set up 16k window for shared memory (receive buffer) ***************/
- req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
- req.Base = 0;
- req.Size = 0x4000;
- req.AccessSpeed = ray_mem_speed;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->rmem_handle));
- mem.CardOffset = 0x8000; mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
- local->rmem = ioremap(req.Base,req.Size);
+ req.Attributes =
+ WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
+ req.Base = 0;
+ req.Size = 0x4000;
+ req.AccessSpeed = ray_mem_speed;
+ CS_CHECK(RequestWindow,
+ pcmcia_request_window(&link, &req, &local->rmem_handle));
+ mem.CardOffset = 0x8000;
+ mem.Page = 0;
+ CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
+ local->rmem = ioremap(req.Base, req.Size);
/*** Set up window for attribute memory ***********************************/
- req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT;
- req.Base = 0;
- req.Size = 0x1000;
- req.AccessSpeed = ray_mem_speed;
- CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &local->amem_handle));
- mem.CardOffset = 0x0000; mem.Page = 0;
- CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
- local->amem = ioremap(req.Base,req.Size);
-
- DEBUG(3,"ray_config sram=%p\n",local->sram);
- DEBUG(3,"ray_config rmem=%p\n",local->rmem);
- DEBUG(3,"ray_config amem=%p\n",local->amem);
- if (ray_init(dev) < 0) {
- ray_release(link);
- return -ENODEV;
- }
-
- SET_NETDEV_DEV(dev, &handle_to_dev(link));
- i = register_netdev(dev);
- if (i != 0) {
- printk("ray_config register_netdev() failed\n");
- ray_release(link);
- return i;
- }
-
- strcpy(local->node.dev_name, dev->name);
- link->dev_node = &local->node;
-
- printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %pM\n",
- dev->name, dev->irq, dev->dev_addr);
-
- return 0;
+ req.Attributes =
+ WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT;
+ req.Base = 0;
+ req.Size = 0x1000;
+ req.AccessSpeed = ray_mem_speed;
+ CS_CHECK(RequestWindow,
+ pcmcia_request_window(&link, &req, &local->amem_handle));
+ mem.CardOffset = 0x0000;
+ mem.Page = 0;
+ CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
+ local->amem = ioremap(req.Base, req.Size);
+
+ DEBUG(3, "ray_config sram=%p\n", local->sram);
+ DEBUG(3, "ray_config rmem=%p\n", local->rmem);
+ DEBUG(3, "ray_config amem=%p\n", local->amem);
+ if (ray_init(dev) < 0) {
+ ray_release(link);
+ return -ENODEV;
+ }
+
+ SET_NETDEV_DEV(dev, &handle_to_dev(link));
+ i = register_netdev(dev);
+ if (i != 0) {
+ printk("ray_config register_netdev() failed\n");
+ ray_release(link);
+ return i;
+ }
+
+ strcpy(local->node.dev_name, dev->name);
+ link->dev_node = &local->node;
+
+ printk(KERN_INFO "%s: RayLink, irq %d, hw_addr %pM\n",
+ dev->name, dev->irq, dev->dev_addr);
+
+ return 0;
cs_failed:
- cs_error(link, last_fn, last_ret);
+ cs_error(link, last_fn, last_ret);
- ray_release(link);
- return -ENODEV;
+ ray_release(link);
+ return -ENODEV;
} /* ray_config */
static inline struct ccs __iomem *ccs_base(ray_dev_t *dev)
@@ -516,267 +537,278 @@ static inline struct rcs __iomem *rcs_base(ray_dev_t *dev)
/*===========================================================================*/
static int ray_init(struct net_device *dev)
{
- int i;
- UCHAR *p;
- struct ccs __iomem *pccs;
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- DEBUG(1, "ray_init(0x%p)\n", dev);
- if (!(pcmcia_dev_present(link))) {
- DEBUG(0,"ray_init - device not present\n");
- return -1;
- }
-
- local->net_type = net_type;
- local->sta_type = TYPE_STA;
-
- /* Copy the startup results to local memory */
- memcpy_fromio(&local->startup_res, local->sram + ECF_TO_HOST_BASE,\
- sizeof(struct startup_res_6));
-
- /* Check Power up test status and get mac address from card */
- if (local->startup_res.startup_word != 0x80) {
- printk(KERN_INFO "ray_init ERROR card status = %2x\n",
- local->startup_res.startup_word);
- local->card_status = CARD_INIT_ERROR;
- return -1;
- }
-
- local->fw_ver = local->startup_res.firmware_version[0];
- local->fw_bld = local->startup_res.firmware_version[1];
- local->fw_var = local->startup_res.firmware_version[2];
- DEBUG(1,"ray_init firmware version %d.%d \n",local->fw_ver, local->fw_bld);
-
- local->tib_length = 0x20;
- if ((local->fw_ver == 5) && (local->fw_bld >= 30))
- local->tib_length = local->startup_res.tib_length;
- DEBUG(2,"ray_init tib_length = 0x%02x\n", local->tib_length);
- /* Initialize CCS's to buffer free state */
- pccs = ccs_base(local);
- for (i=0; i<NUMBER_OF_CCS; i++) {
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- }
- init_startup_params(local);
-
- /* copy mac address to startup parameters */
- if (parse_addr(phy_addr, local->sparm.b4.a_mac_addr))
- {
- p = local->sparm.b4.a_mac_addr;
- }
- else
- {
- memcpy(&local->sparm.b4.a_mac_addr,
- &local->startup_res.station_addr, ADDRLEN);
- p = local->sparm.b4.a_mac_addr;
- }
-
- clear_interrupt(local); /* Clear any interrupt from the card */
- local->card_status = CARD_AWAITING_PARAM;
- DEBUG(2,"ray_init ending\n");
- return 0;
+ int i;
+ UCHAR *p;
+ struct ccs __iomem *pccs;
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ DEBUG(1, "ray_init(0x%p)\n", dev);
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(0, "ray_init - device not present\n");
+ return -1;
+ }
+
+ local->net_type = net_type;
+ local->sta_type = TYPE_STA;
+
+ /* Copy the startup results to local memory */
+ memcpy_fromio(&local->startup_res, local->sram + ECF_TO_HOST_BASE,
+ sizeof(struct startup_res_6));
+
+ /* Check Power up test status and get mac address from card */
+ if (local->startup_res.startup_word != 0x80) {
+ printk(KERN_INFO "ray_init ERROR card status = %2x\n",
+ local->startup_res.startup_word);
+ local->card_status = CARD_INIT_ERROR;
+ return -1;
+ }
+
+ local->fw_ver = local->startup_res.firmware_version[0];
+ local->fw_bld = local->startup_res.firmware_version[1];
+ local->fw_var = local->startup_res.firmware_version[2];
+ DEBUG(1, "ray_init firmware version %d.%d \n", local->fw_ver,
+ local->fw_bld);
+
+ local->tib_length = 0x20;
+ if ((local->fw_ver == 5) && (local->fw_bld >= 30))
+ local->tib_length = local->startup_res.tib_length;
+ DEBUG(2, "ray_init tib_length = 0x%02x\n", local->tib_length);
+ /* Initialize CCS's to buffer free state */
+ pccs = ccs_base(local);
+ for (i = 0; i < NUMBER_OF_CCS; i++) {
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ }
+ init_startup_params(local);
+
+ /* copy mac address to startup parameters */
+ if (parse_addr(phy_addr, local->sparm.b4.a_mac_addr)) {
+ p = local->sparm.b4.a_mac_addr;
+ } else {
+ memcpy(&local->sparm.b4.a_mac_addr,
+ &local->startup_res.station_addr, ADDRLEN);
+ p = local->sparm.b4.a_mac_addr;
+ }
+
+ clear_interrupt(local); /* Clear any interrupt from the card */
+ local->card_status = CARD_AWAITING_PARAM;
+ DEBUG(2, "ray_init ending\n");
+ return 0;
} /* ray_init */
+
/*===========================================================================*/
/* Download startup parameters to the card and command it to read them */
static int dl_startup_params(struct net_device *dev)
{
- int ccsindex;
- ray_dev_t *local = netdev_priv(dev);
- struct ccs __iomem *pccs;
- struct pcmcia_device *link = local->finder;
-
- DEBUG(1,"dl_startup_params entered\n");
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs dl_startup_params - device not present\n");
- return -1;
- }
-
- /* Copy parameters to host to ECF area */
- if (local->fw_ver == 0x55)
- memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b4,
- sizeof(struct b4_startup_params));
- else
- memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b5,
- sizeof(struct b5_startup_params));
-
-
- /* Fill in the CCS fields for the ECF */
- if ((ccsindex = get_free_ccs(local)) < 0) return -1;
- local->dl_param_ccs = ccsindex;
- pccs = ccs_base(local) + ccsindex;
- writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd);
- DEBUG(2,"dl_startup_params start ccsindex = %d\n", local->dl_param_ccs);
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- printk(KERN_INFO "ray dl_startup_params failed - "
- "ECF not ready for intr\n");
- local->card_status = CARD_DL_PARAM_ERROR;
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- return -2;
- }
- local->card_status = CARD_DL_PARAM;
- /* Start kernel timer to wait for dl startup to complete. */
- local->timer.expires = jiffies + HZ/2;
- local->timer.data = (long)local;
- local->timer.function = &verify_dl_startup;
- add_timer(&local->timer);
- DEBUG(2,"ray_cs dl_startup_params started timer for verify_dl_startup\n");
- return 0;
+ int ccsindex;
+ ray_dev_t *local = netdev_priv(dev);
+ struct ccs __iomem *pccs;
+ struct pcmcia_device *link = local->finder;
+
+ DEBUG(1, "dl_startup_params entered\n");
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs dl_startup_params - device not present\n");
+ return -1;
+ }
+
+ /* Copy parameters to host to ECF area */
+ if (local->fw_ver == 0x55)
+ memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b4,
+ sizeof(struct b4_startup_params));
+ else
+ memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b5,
+ sizeof(struct b5_startup_params));
+
+ /* Fill in the CCS fields for the ECF */
+ if ((ccsindex = get_free_ccs(local)) < 0)
+ return -1;
+ local->dl_param_ccs = ccsindex;
+ pccs = ccs_base(local) + ccsindex;
+ writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd);
+ DEBUG(2, "dl_startup_params start ccsindex = %d\n",
+ local->dl_param_ccs);
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ printk(KERN_INFO "ray dl_startup_params failed - "
+ "ECF not ready for intr\n");
+ local->card_status = CARD_DL_PARAM_ERROR;
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ return -2;
+ }
+ local->card_status = CARD_DL_PARAM;
+ /* Start kernel timer to wait for dl startup to complete. */
+ local->timer.expires = jiffies + HZ / 2;
+ local->timer.data = (long)local;
+ local->timer.function = &verify_dl_startup;
+ add_timer(&local->timer);
+ DEBUG(2,
+ "ray_cs dl_startup_params started timer for verify_dl_startup\n");
+ return 0;
} /* dl_startup_params */
+
/*===========================================================================*/
static void init_startup_params(ray_dev_t *local)
{
- int i;
-
- if (country > JAPAN_TEST) country = USA;
- else
- if (country < USA) country = USA;
- /* structure for hop time and beacon period is defined here using
- * New 802.11D6.1 format. Card firmware is still using old format
- * until version 6.
- * Before After
- * a_hop_time ms byte a_hop_time ms byte
- * a_hop_time 2s byte a_hop_time ls byte
- * a_hop_time ls byte a_beacon_period ms byte
- * a_beacon_period a_beacon_period ls byte
- *
- * a_hop_time = uS a_hop_time = KuS
- * a_beacon_period = hops a_beacon_period = KuS
- */ /* 64ms = 010000 */
- if (local->fw_ver == 0x55) {
- memcpy((UCHAR *)&local->sparm.b4, b4_default_startup_parms,
- sizeof(struct b4_startup_params));
- /* Translate sane kus input values to old build 4/5 format */
- /* i = hop time in uS truncated to 3 bytes */
- i = (hop_dwell * 1024) & 0xffffff;
- local->sparm.b4.a_hop_time[0] = (i >> 16) & 0xff;
- local->sparm.b4.a_hop_time[1] = (i >> 8) & 0xff;
- local->sparm.b4.a_beacon_period[0] = 0;
- local->sparm.b4.a_beacon_period[1] =
- ((beacon_period/hop_dwell) - 1) & 0xff;
- local->sparm.b4.a_curr_country_code = country;
- local->sparm.b4.a_hop_pattern_length =
- hop_pattern_length[(int)country] - 1;
- if (bc)
- {
- local->sparm.b4.a_ack_timeout = 0x50;
- local->sparm.b4.a_sifs = 0x3f;
- }
- }
- else { /* Version 5 uses real kus values */
- memcpy((UCHAR *)&local->sparm.b5, b5_default_startup_parms,
- sizeof(struct b5_startup_params));
-
- local->sparm.b5.a_hop_time[0] = (hop_dwell >> 8) & 0xff;
- local->sparm.b5.a_hop_time[1] = hop_dwell & 0xff;
- local->sparm.b5.a_beacon_period[0] = (beacon_period >> 8) & 0xff;
- local->sparm.b5.a_beacon_period[1] = beacon_period & 0xff;
- if (psm)
- local->sparm.b5.a_power_mgt_state = 1;
- local->sparm.b5.a_curr_country_code = country;
- local->sparm.b5.a_hop_pattern_length =
- hop_pattern_length[(int)country];
- }
-
- local->sparm.b4.a_network_type = net_type & 0x01;
- local->sparm.b4.a_acting_as_ap_status = TYPE_STA;
-
- if (essid != NULL)
- strncpy(local->sparm.b4.a_current_ess_id, essid, ESSID_SIZE);
-} /* init_startup_params */
+ int i;
+
+ if (country > JAPAN_TEST)
+ country = USA;
+ else if (country < USA)
+ country = USA;
+ /* structure for hop time and beacon period is defined here using
+ * New 802.11D6.1 format. Card firmware is still using old format
+ * until version 6.
+ * Before After
+ * a_hop_time ms byte a_hop_time ms byte
+ * a_hop_time 2s byte a_hop_time ls byte
+ * a_hop_time ls byte a_beacon_period ms byte
+ * a_beacon_period a_beacon_period ls byte
+ *
+ * a_hop_time = uS a_hop_time = KuS
+ * a_beacon_period = hops a_beacon_period = KuS
+ *//* 64ms = 010000 */
+ if (local->fw_ver == 0x55) {
+ memcpy((UCHAR *) &local->sparm.b4, b4_default_startup_parms,
+ sizeof(struct b4_startup_params));
+ /* Translate sane kus input values to old build 4/5 format */
+ /* i = hop time in uS truncated to 3 bytes */
+ i = (hop_dwell * 1024) & 0xffffff;
+ local->sparm.b4.a_hop_time[0] = (i >> 16) & 0xff;
+ local->sparm.b4.a_hop_time[1] = (i >> 8) & 0xff;
+ local->sparm.b4.a_beacon_period[0] = 0;
+ local->sparm.b4.a_beacon_period[1] =
+ ((beacon_period / hop_dwell) - 1) & 0xff;
+ local->sparm.b4.a_curr_country_code = country;
+ local->sparm.b4.a_hop_pattern_length =
+ hop_pattern_length[(int)country] - 1;
+ if (bc) {
+ local->sparm.b4.a_ack_timeout = 0x50;
+ local->sparm.b4.a_sifs = 0x3f;
+ }
+ } else { /* Version 5 uses real kus values */
+ memcpy((UCHAR *) &local->sparm.b5, b5_default_startup_parms,
+ sizeof(struct b5_startup_params));
+
+ local->sparm.b5.a_hop_time[0] = (hop_dwell >> 8) & 0xff;
+ local->sparm.b5.a_hop_time[1] = hop_dwell & 0xff;
+ local->sparm.b5.a_beacon_period[0] =
+ (beacon_period >> 8) & 0xff;
+ local->sparm.b5.a_beacon_period[1] = beacon_period & 0xff;
+ if (psm)
+ local->sparm.b5.a_power_mgt_state = 1;
+ local->sparm.b5.a_curr_country_code = country;
+ local->sparm.b5.a_hop_pattern_length =
+ hop_pattern_length[(int)country];
+ }
+
+ local->sparm.b4.a_network_type = net_type & 0x01;
+ local->sparm.b4.a_acting_as_ap_status = TYPE_STA;
+
+ if (essid != NULL)
+ strncpy(local->sparm.b4.a_current_ess_id, essid, ESSID_SIZE);
+} /* init_startup_params */
+
/*===========================================================================*/
static void verify_dl_startup(u_long data)
{
- ray_dev_t *local = (ray_dev_t *)data;
- struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
- UCHAR status;
- struct pcmcia_device *link = local->finder;
+ ray_dev_t *local = (ray_dev_t *) data;
+ struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
+ UCHAR status;
+ struct pcmcia_device *link = local->finder;
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs verify_dl_startup - device not present\n");
- return;
- }
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs verify_dl_startup - device not present\n");
+ return;
+ }
#ifdef PCMCIA_DEBUG
- if (pc_debug > 2) {
- int i;
- printk(KERN_DEBUG "verify_dl_startup parameters sent via ccs %d:\n",
- local->dl_param_ccs);
- for (i=0; i<sizeof(struct b5_startup_params); i++) {
- printk(" %2x", (unsigned int) readb(local->sram + HOST_TO_ECF_BASE + i));
- }
- printk("\n");
- }
+ if (pc_debug > 2) {
+ int i;
+ printk(KERN_DEBUG
+ "verify_dl_startup parameters sent via ccs %d:\n",
+ local->dl_param_ccs);
+ for (i = 0; i < sizeof(struct b5_startup_params); i++) {
+ printk(" %2x",
+ (unsigned int)readb(local->sram +
+ HOST_TO_ECF_BASE + i));
+ }
+ printk("\n");
+ }
#endif
- status = readb(&pccs->buffer_status);
- if (status!= CCS_BUFFER_FREE)
- {
- printk(KERN_INFO "Download startup params failed. Status = %d\n",
- status);
- local->card_status = CARD_DL_PARAM_ERROR;
- return;
- }
- if (local->sparm.b4.a_network_type == ADHOC)
- start_net((u_long)local);
- else
- join_net((u_long)local);
-
- return;
+ status = readb(&pccs->buffer_status);
+ if (status != CCS_BUFFER_FREE) {
+ printk(KERN_INFO
+ "Download startup params failed. Status = %d\n",
+ status);
+ local->card_status = CARD_DL_PARAM_ERROR;
+ return;
+ }
+ if (local->sparm.b4.a_network_type == ADHOC)
+ start_net((u_long) local);
+ else
+ join_net((u_long) local);
+
+ return;
} /* end verify_dl_startup */
+
/*===========================================================================*/
/* Command card to start a network */
static void start_net(u_long data)
{
- ray_dev_t *local = (ray_dev_t *)data;
- struct ccs __iomem *pccs;
- int ccsindex;
- struct pcmcia_device *link = local->finder;
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs start_net - device not present\n");
- return;
- }
- /* Fill in the CCS fields for the ECF */
- if ((ccsindex = get_free_ccs(local)) < 0) return;
- pccs = ccs_base(local) + ccsindex;
- writeb(CCS_START_NETWORK, &pccs->cmd);
- writeb(0, &pccs->var.start_network.update_param);
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1,"ray start net failed - card not ready for intr\n");
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- return;
- }
- local->card_status = CARD_DOING_ACQ;
- return;
+ ray_dev_t *local = (ray_dev_t *) data;
+ struct ccs __iomem *pccs;
+ int ccsindex;
+ struct pcmcia_device *link = local->finder;
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs start_net - device not present\n");
+ return;
+ }
+ /* Fill in the CCS fields for the ECF */
+ if ((ccsindex = get_free_ccs(local)) < 0)
+ return;
+ pccs = ccs_base(local) + ccsindex;
+ writeb(CCS_START_NETWORK, &pccs->cmd);
+ writeb(0, &pccs->var.start_network.update_param);
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(1, "ray start net failed - card not ready for intr\n");
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ return;
+ }
+ local->card_status = CARD_DOING_ACQ;
+ return;
} /* end start_net */
+
/*===========================================================================*/
/* Command card to join a network */
static void join_net(u_long data)
{
- ray_dev_t *local = (ray_dev_t *)data;
-
- struct ccs __iomem *pccs;
- int ccsindex;
- struct pcmcia_device *link = local->finder;
-
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs join_net - device not present\n");
- return;
- }
- /* Fill in the CCS fields for the ECF */
- if ((ccsindex = get_free_ccs(local)) < 0) return;
- pccs = ccs_base(local) + ccsindex;
- writeb(CCS_JOIN_NETWORK, &pccs->cmd);
- writeb(0, &pccs->var.join_network.update_param);
- writeb(0, &pccs->var.join_network.net_initiated);
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1,"ray join net failed - card not ready for intr\n");
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- return;
- }
- local->card_status = CARD_DOING_ACQ;
- return;
+ ray_dev_t *local = (ray_dev_t *) data;
+
+ struct ccs __iomem *pccs;
+ int ccsindex;
+ struct pcmcia_device *link = local->finder;
+
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs join_net - device not present\n");
+ return;
+ }
+ /* Fill in the CCS fields for the ECF */
+ if ((ccsindex = get_free_ccs(local)) < 0)
+ return;
+ pccs = ccs_base(local) + ccsindex;
+ writeb(CCS_JOIN_NETWORK, &pccs->cmd);
+ writeb(0, &pccs->var.join_network.update_param);
+ writeb(0, &pccs->var.join_network.net_initiated);
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(1, "ray join net failed - card not ready for intr\n");
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ return;
+ }
+ local->card_status = CARD_DOING_ACQ;
+ return;
}
+
/*============================================================================
After a card is removed, ray_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
@@ -784,25 +816,27 @@ static void join_net(u_long data)
=============================================================================*/
static void ray_release(struct pcmcia_device *link)
{
- struct net_device *dev = link->priv;
- ray_dev_t *local = netdev_priv(dev);
- int i;
-
- DEBUG(1, "ray_release(0x%p)\n", link);
-
- del_timer(&local->timer);
-
- iounmap(local->sram);
- iounmap(local->rmem);
- iounmap(local->amem);
- /* Do bother checking to see if these succeed or not */
- i = pcmcia_release_window(local->amem_handle);
- if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
- i = pcmcia_release_window(local->rmem_handle);
- if ( i != 0 ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
- pcmcia_disable_device(link);
-
- DEBUG(2,"ray_release ending\n");
+ struct net_device *dev = link->priv;
+ ray_dev_t *local = netdev_priv(dev);
+ int i;
+
+ DEBUG(1, "ray_release(0x%p)\n", link);
+
+ del_timer(&local->timer);
+
+ iounmap(local->sram);
+ iounmap(local->rmem);
+ iounmap(local->amem);
+ /* Do bother checking to see if these succeed or not */
+ i = pcmcia_release_window(local->amem_handle);
+ if (i != 0)
+ DEBUG(0, "ReleaseWindow(local->amem) ret = %x\n", i);
+ i = pcmcia_release_window(local->rmem_handle);
+ if (i != 0)
+ DEBUG(0, "ReleaseWindow(local->rmem) ret = %x\n", i);
+ pcmcia_disable_device(link);
+
+ DEBUG(2, "ray_release ending\n");
}
static int ray_suspend(struct pcmcia_device *link)
@@ -831,237 +865,243 @@ static int ray_resume(struct pcmcia_device *link)
static int ray_dev_init(struct net_device *dev)
{
#ifdef RAY_IMMEDIATE_INIT
- int i;
-#endif /* RAY_IMMEDIATE_INIT */
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
-
- DEBUG(1,"ray_dev_init(dev=%p)\n",dev);
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_dev_init - device not present\n");
- return -1;
- }
+ int i;
+#endif /* RAY_IMMEDIATE_INIT */
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+
+ DEBUG(1, "ray_dev_init(dev=%p)\n", dev);
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_dev_init - device not present\n");
+ return -1;
+ }
#ifdef RAY_IMMEDIATE_INIT
- /* Download startup parameters */
- if ( (i = dl_startup_params(dev)) < 0)
- {
- printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
- "returns 0x%x\n",i);
- return -1;
- }
-#else /* RAY_IMMEDIATE_INIT */
- /* Postpone the card init so that we can still configure the card,
- * for example using the Wireless Extensions. The init will happen
- * in ray_open() - Jean II */
- DEBUG(1,"ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
- local->card_status);
-#endif /* RAY_IMMEDIATE_INIT */
-
- /* copy mac and broadcast addresses to linux device */
- memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
- memset(dev->broadcast, 0xff, ETH_ALEN);
-
- DEBUG(2,"ray_dev_init ending\n");
- return 0;
+ /* Download startup parameters */
+ if ((i = dl_startup_params(dev)) < 0) {
+ printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
+ "returns 0x%x\n", i);
+ return -1;
+ }
+#else /* RAY_IMMEDIATE_INIT */
+ /* Postpone the card init so that we can still configure the card,
+ * for example using the Wireless Extensions. The init will happen
+ * in ray_open() - Jean II */
+ DEBUG(1,
+ "ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
+ local->card_status);
+#endif /* RAY_IMMEDIATE_INIT */
+
+ /* copy mac and broadcast addresses to linux device */
+ memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
+ memset(dev->broadcast, 0xff, ETH_ALEN);
+
+ DEBUG(2, "ray_dev_init ending\n");
+ return 0;
}
+
/*===========================================================================*/
static int ray_dev_config(struct net_device *dev, struct ifmap *map)
{
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- /* Dummy routine to satisfy device structure */
- DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map);
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_dev_config - device not present\n");
- return -1;
- }
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ /* Dummy routine to satisfy device structure */
+ DEBUG(1, "ray_dev_config(dev=%p,ifmap=%p)\n", dev, map);
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_dev_config - device not present\n");
+ return -1;
+ }
- return 0;
+ return 0;
}
+
/*===========================================================================*/
static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- short length = skb->len;
-
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_dev_start_xmit - device not present\n");
- return -1;
- }
- DEBUG(3,"ray_dev_start_xmit(skb=%p, dev=%p)\n",skb,dev);
- if (local->authentication_state == NEED_TO_AUTH) {
- DEBUG(0,"ray_cs Sending authentication request.\n");
- if (!build_auth_frame (local, local->auth_id, OPEN_AUTH_REQUEST)) {
- local->authentication_state = AUTHENTICATED;
- netif_stop_queue(dev);
- return 1;
- }
- }
-
- if (length < ETH_ZLEN)
- {
- if (skb_padto(skb, ETH_ZLEN))
- return 0;
- length = ETH_ZLEN;
- }
- switch (ray_hw_xmit( skb->data, length, dev, DATA_TYPE)) {
- case XMIT_NO_CCS:
- case XMIT_NEED_AUTH:
- netif_stop_queue(dev);
- return 1;
- case XMIT_NO_INTR:
- case XMIT_MSG_BAD:
- case XMIT_OK:
- default:
- dev->trans_start = jiffies;
- dev_kfree_skb(skb);
- return 0;
- }
- return 0;
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ short length = skb->len;
+
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_dev_start_xmit - device not present\n");
+ return -1;
+ }
+ DEBUG(3, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev);
+ if (local->authentication_state == NEED_TO_AUTH) {
+ DEBUG(0, "ray_cs Sending authentication request.\n");
+ if (!build_auth_frame(local, local->auth_id, OPEN_AUTH_REQUEST)) {
+ local->authentication_state = AUTHENTICATED;
+ netif_stop_queue(dev);
+ return 1;
+ }
+ }
+
+ if (length < ETH_ZLEN) {
+ if (skb_padto(skb, ETH_ZLEN))
+ return 0;
+ length = ETH_ZLEN;
+ }
+ switch (ray_hw_xmit(skb->data, length, dev, DATA_TYPE)) {
+ case XMIT_NO_CCS:
+ case XMIT_NEED_AUTH:
+ netif_stop_queue(dev);
+ return 1;
+ case XMIT_NO_INTR:
+ case XMIT_MSG_BAD:
+ case XMIT_OK:
+ default:
+ dev->trans_start = jiffies;
+ dev_kfree_skb(skb);
+ return 0;
+ }
+ return 0;
} /* ray_dev_start_xmit */
+
/*===========================================================================*/
-static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev,
- UCHAR msg_type)
-{
- ray_dev_t *local = netdev_priv(dev);
- struct ccs __iomem *pccs;
- int ccsindex;
- int offset;
- struct tx_msg __iomem *ptx; /* Address of xmit buffer in PC space */
- short int addr; /* Address of xmit buffer in card space */
-
- DEBUG(3,"ray_hw_xmit(data=%p, len=%d, dev=%p)\n",data,len,dev);
- if (len + TX_HEADER_LENGTH > TX_BUF_SIZE)
- {
- printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",len);
- return XMIT_MSG_BAD;
- }
+static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev,
+ UCHAR msg_type)
+{
+ ray_dev_t *local = netdev_priv(dev);
+ struct ccs __iomem *pccs;
+ int ccsindex;
+ int offset;
+ struct tx_msg __iomem *ptx; /* Address of xmit buffer in PC space */
+ short int addr; /* Address of xmit buffer in card space */
+
+ DEBUG(3, "ray_hw_xmit(data=%p, len=%d, dev=%p)\n", data, len, dev);
+ if (len + TX_HEADER_LENGTH > TX_BUF_SIZE) {
+ printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",
+ len);
+ return XMIT_MSG_BAD;
+ }
switch (ccsindex = get_free_tx_ccs(local)) {
case ECCSBUSY:
- DEBUG(2,"ray_hw_xmit tx_ccs table busy\n");
+ DEBUG(2, "ray_hw_xmit tx_ccs table busy\n");
case ECCSFULL:
- DEBUG(2,"ray_hw_xmit No free tx ccs\n");
+ DEBUG(2, "ray_hw_xmit No free tx ccs\n");
case ECARDGONE:
- netif_stop_queue(dev);
- return XMIT_NO_CCS;
+ netif_stop_queue(dev);
+ return XMIT_NO_CCS;
default:
break;
}
- addr = TX_BUF_BASE + (ccsindex << 11);
-
- if (msg_type == DATA_TYPE) {
- local->stats.tx_bytes += len;
- local->stats.tx_packets++;
- }
-
- ptx = local->sram + addr;
-
- ray_build_header(local, ptx, msg_type, data);
- if (translate) {
- offset = translate_frame(local, ptx, data, len);
- }
- else { /* Encapsulate frame */
- /* TBD TIB length will move address of ptx->var */
- memcpy_toio(&ptx->var, data, len);
- offset = 0;
- }
-
- /* fill in the CCS */
- pccs = ccs_base(local) + ccsindex;
- len += TX_HEADER_LENGTH + offset;
- writeb(CCS_TX_REQUEST, &pccs->cmd);
- writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]);
- writeb(local->tib_length, &pccs->var.tx_request.tx_data_ptr[1]);
- writeb(len >> 8, &pccs->var.tx_request.tx_data_length[0]);
- writeb(len & 0xff, &pccs->var.tx_request.tx_data_length[1]);
+ addr = TX_BUF_BASE + (ccsindex << 11);
+
+ if (msg_type == DATA_TYPE) {
+ local->stats.tx_bytes += len;
+ local->stats.tx_packets++;
+ }
+
+ ptx = local->sram + addr;
+
+ ray_build_header(local, ptx, msg_type, data);
+ if (translate) {
+ offset = translate_frame(local, ptx, data, len);
+ } else { /* Encapsulate frame */
+ /* TBD TIB length will move address of ptx->var */
+ memcpy_toio(&ptx->var, data, len);
+ offset = 0;
+ }
+
+ /* fill in the CCS */
+ pccs = ccs_base(local) + ccsindex;
+ len += TX_HEADER_LENGTH + offset;
+ writeb(CCS_TX_REQUEST, &pccs->cmd);
+ writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]);
+ writeb(local->tib_length, &pccs->var.tx_request.tx_data_ptr[1]);
+ writeb(len >> 8, &pccs->var.tx_request.tx_data_length[0]);
+ writeb(len & 0xff, &pccs->var.tx_request.tx_data_length[1]);
/* TBD still need psm_cam? */
- writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode);
- writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate);
- writeb(0, &pccs->var.tx_request.antenna);
- DEBUG(3,"ray_hw_xmit default_tx_rate = 0x%x\n",\
- local->net_default_tx_rate);
-
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(2,"ray_hw_xmit failed - ECF not ready for intr\n");
+ writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode);
+ writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate);
+ writeb(0, &pccs->var.tx_request.antenna);
+ DEBUG(3, "ray_hw_xmit default_tx_rate = 0x%x\n",
+ local->net_default_tx_rate);
+
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(2, "ray_hw_xmit failed - ECF not ready for intr\n");
/* TBD very inefficient to copy packet to buffer, and then not
send it, but the alternative is to queue the messages and that
won't be done for a while. Maybe set tbusy until a CCS is free?
*/
- writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
- return XMIT_NO_INTR;
- }
- return XMIT_OK;
+ writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
+ return XMIT_NO_INTR;
+ }
+ return XMIT_OK;
} /* end ray_hw_xmit */
+
/*===========================================================================*/
-static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, unsigned char *data,
- int len)
-{
- __be16 proto = ((struct ethhdr *)data)->h_proto;
- if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
- DEBUG(3,"ray_cs translate_frame DIX II\n");
- /* Copy LLC header to card buffer */
- memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc));
- memcpy_toio( ((void __iomem *)&ptx->var) + sizeof(eth2_llc), (UCHAR *)&proto, 2);
- if (proto == htons(ETH_P_AARP) || proto == htons(ETH_P_IPX)) {
- /* This is the selective translation table, only 2 entries */
- writeb(0xf8, &((struct snaphdr_t __iomem *)ptx->var)->org[3]);
- }
- /* Copy body of ethernet packet without ethernet header */
- memcpy_toio((void __iomem *)&ptx->var + sizeof(struct snaphdr_t), \
- data + ETH_HLEN, len - ETH_HLEN);
- return (int) sizeof(struct snaphdr_t) - ETH_HLEN;
- }
- else { /* already 802 type, and proto is length */
- DEBUG(3,"ray_cs translate_frame 802\n");
- if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */
- DEBUG(3,"ray_cs translate_frame evil IPX\n");
- memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
- return 0 - ETH_HLEN;
- }
- memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
- return 0 - ETH_HLEN;
- }
- /* TBD do other frame types */
+static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
+ unsigned char *data, int len)
+{
+ __be16 proto = ((struct ethhdr *)data)->h_proto;
+ if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
+ DEBUG(3, "ray_cs translate_frame DIX II\n");
+ /* Copy LLC header to card buffer */
+ memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc));
+ memcpy_toio(((void __iomem *)&ptx->var) + sizeof(eth2_llc),
+ (UCHAR *) &proto, 2);
+ if (proto == htons(ETH_P_AARP) || proto == htons(ETH_P_IPX)) {
+ /* This is the selective translation table, only 2 entries */
+ writeb(0xf8,
+ &((struct snaphdr_t __iomem *)ptx->var)->org[3]);
+ }
+ /* Copy body of ethernet packet without ethernet header */
+ memcpy_toio((void __iomem *)&ptx->var +
+ sizeof(struct snaphdr_t), data + ETH_HLEN,
+ len - ETH_HLEN);
+ return (int)sizeof(struct snaphdr_t) - ETH_HLEN;
+ } else { /* already 802 type, and proto is length */
+ DEBUG(3, "ray_cs translate_frame 802\n");
+ if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */
+ DEBUG(3, "ray_cs translate_frame evil IPX\n");
+ memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
+ return 0 - ETH_HLEN;
+ }
+ memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
+ return 0 - ETH_HLEN;
+ }
+ /* TBD do other frame types */
} /* end translate_frame */
+
/*===========================================================================*/
-static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type,
- unsigned char *data)
+static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx,
+ UCHAR msg_type, unsigned char *data)
{
- writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1);
+ writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1);
/*** IEEE 802.11 Address field assignments *************
- TODS FROMDS addr_1 addr_2 addr_3 addr_4
-Adhoc 0 0 dest src (terminal) BSSID N/A
-AP to Terminal 0 1 dest AP(BSSID) source N/A
-Terminal to AP 1 0 AP(BSSID) src (terminal) dest N/A
-AP to AP 1 1 dest AP src AP dest source
+ TODS FROMDS addr_1 addr_2 addr_3 addr_4
+Adhoc 0 0 dest src (terminal) BSSID N/A
+AP to Terminal 0 1 dest AP(BSSID) source N/A
+Terminal to AP 1 0 AP(BSSID) src (terminal) dest N/A
+AP to AP 1 1 dest AP src AP dest source
*******************************************************/
- if (local->net_type == ADHOC) {
- writeb(0, &ptx->mac.frame_ctl_2);
- memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, 2 * ADDRLEN);
- memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
- }
- else /* infrastructure */
- {
- if (local->sparm.b4.a_acting_as_ap_status)
- {
- writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);
- memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, ADDRLEN);
- memcpy_toio(ptx->mac.addr_2, local->bss_id, 6);
- memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_source, ADDRLEN);
- }
- else /* Terminal */
- {
- writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2);
- memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN);
- memcpy_toio(ptx->mac.addr_2, ((struct ethhdr *)data)->h_source, ADDRLEN);
- memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_dest, ADDRLEN);
- }
- }
+ if (local->net_type == ADHOC) {
+ writeb(0, &ptx->mac.frame_ctl_2);
+ memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest,
+ 2 * ADDRLEN);
+ memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
+ } else { /* infrastructure */
+
+ if (local->sparm.b4.a_acting_as_ap_status) {
+ writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);
+ memcpy_toio(ptx->mac.addr_1,
+ ((struct ethhdr *)data)->h_dest, ADDRLEN);
+ memcpy_toio(ptx->mac.addr_2, local->bss_id, 6);
+ memcpy_toio(ptx->mac.addr_3,
+ ((struct ethhdr *)data)->h_source, ADDRLEN);
+ } else { /* Terminal */
+
+ writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2);
+ memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN);
+ memcpy_toio(ptx->mac.addr_2,
+ ((struct ethhdr *)data)->h_source, ADDRLEN);
+ memcpy_toio(ptx->mac.addr_3,
+ ((struct ethhdr *)data)->h_dest, ADDRLEN);
+ }
+ }
} /* end encapsulate_frame */
-
/*===========================================================================*/
static void netdev_get_drvinfo(struct net_device *dev,
@@ -1071,7 +1111,7 @@ static void netdev_get_drvinfo(struct net_device *dev,
}
static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = netdev_get_drvinfo,
+ .get_drvinfo = netdev_get_drvinfo,
};
/*====================================================================*/
@@ -1081,9 +1121,7 @@ static const struct ethtool_ops netdev_ethtool_ops = {
* Wireless Handler : get protocol name
*/
static int ray_get_name(struct net_device *dev,
- struct iw_request_info *info,
- char *cwrq,
- char *extra)
+ struct iw_request_info *info, char *cwrq, char *extra)
{
strcpy(cwrq, "IEEE 802.11-FH");
return 0;
@@ -1095,14 +1133,13 @@ static int ray_get_name(struct net_device *dev,
*/
static int ray_set_freq(struct net_device *dev,
struct iw_request_info *info,
- struct iw_freq *fwrq,
- char *extra)
+ struct iw_freq *fwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
- int err = -EINPROGRESS; /* Call commit handler */
+ int err = -EINPROGRESS; /* Call commit handler */
/* Reject if card is already initialised */
- if(local->card_status != CARD_AWAITING_PARAM)
+ if (local->card_status != CARD_AWAITING_PARAM)
return -EBUSY;
/* Setting by channel number */
@@ -1113,15 +1150,14 @@ static int ray_set_freq(struct net_device *dev,
return err;
}
-
+
/*------------------------------------------------------------------*/
/*
* Wireless Handler : get frequency
*/
static int ray_get_freq(struct net_device *dev,
struct iw_request_info *info,
- struct iw_freq *fwrq,
- char *extra)
+ struct iw_freq *fwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
@@ -1136,22 +1172,21 @@ static int ray_get_freq(struct net_device *dev,
*/
static int ray_set_essid(struct net_device *dev,
struct iw_request_info *info,
- struct iw_point *dwrq,
- char *extra)
+ struct iw_point *dwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
/* Reject if card is already initialised */
- if(local->card_status != CARD_AWAITING_PARAM)
+ if (local->card_status != CARD_AWAITING_PARAM)
return -EBUSY;
/* Check if we asked for `any' */
- if(dwrq->flags == 0) {
+ if (dwrq->flags == 0) {
/* Corey : can you do that ? */
return -EOPNOTSUPP;
} else {
/* Check the size of the string */
- if(dwrq->length > IW_ESSID_MAX_SIZE) {
+ if (dwrq->length > IW_ESSID_MAX_SIZE) {
return -E2BIG;
}
@@ -1160,7 +1195,7 @@ static int ray_set_essid(struct net_device *dev,
memcpy(local->sparm.b5.a_current_ess_id, extra, dwrq->length);
}
- return -EINPROGRESS; /* Call commit handler */
+ return -EINPROGRESS; /* Call commit handler */
}
/*------------------------------------------------------------------*/
@@ -1169,8 +1204,7 @@ static int ray_set_essid(struct net_device *dev,
*/
static int ray_get_essid(struct net_device *dev,
struct iw_request_info *info,
- struct iw_point *dwrq,
- char *extra)
+ struct iw_point *dwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
@@ -1179,7 +1213,7 @@ static int ray_get_essid(struct net_device *dev,
/* Push it out ! */
dwrq->length = strlen(extra);
- dwrq->flags = 1; /* active */
+ dwrq->flags = 1; /* active */
return 0;
}
@@ -1189,9 +1223,8 @@ static int ray_get_essid(struct net_device *dev,
* Wireless Handler : get AP address
*/
static int ray_get_wap(struct net_device *dev,
- struct iw_request_info *info,
- struct sockaddr *awrq,
- char *extra)
+ struct iw_request_info *info,
+ struct sockaddr *awrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
@@ -1207,25 +1240,24 @@ static int ray_get_wap(struct net_device *dev,
*/
static int ray_set_rate(struct net_device *dev,
struct iw_request_info *info,
- struct iw_param *vwrq,
- char *extra)
+ struct iw_param *vwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
/* Reject if card is already initialised */
- if(local->card_status != CARD_AWAITING_PARAM)
+ if (local->card_status != CARD_AWAITING_PARAM)
return -EBUSY;
/* Check if rate is in range */
- if((vwrq->value != 1000000) && (vwrq->value != 2000000))
+ if ((vwrq->value != 1000000) && (vwrq->value != 2000000))
return -EINVAL;
/* Hack for 1.5 Mb/s instead of 2 Mb/s */
- if((local->fw_ver == 0x55) && /* Please check */
- (vwrq->value == 2000000))
+ if ((local->fw_ver == 0x55) && /* Please check */
+ (vwrq->value == 2000000))
local->net_default_tx_rate = 3;
else
- local->net_default_tx_rate = vwrq->value/500000;
+ local->net_default_tx_rate = vwrq->value / 500000;
return 0;
}
@@ -1236,16 +1268,15 @@ static int ray_set_rate(struct net_device *dev,
*/
static int ray_get_rate(struct net_device *dev,
struct iw_request_info *info,
- struct iw_param *vwrq,
- char *extra)
+ struct iw_param *vwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
- if(local->net_default_tx_rate == 3)
- vwrq->value = 2000000; /* Hum... */
+ if (local->net_default_tx_rate == 3)
+ vwrq->value = 2000000; /* Hum... */
else
vwrq->value = local->net_default_tx_rate * 500000;
- vwrq->fixed = 0; /* We are in auto mode */
+ vwrq->fixed = 0; /* We are in auto mode */
return 0;
}
@@ -1256,43 +1287,40 @@ static int ray_get_rate(struct net_device *dev,
*/
static int ray_set_rts(struct net_device *dev,
struct iw_request_info *info,
- struct iw_param *vwrq,
- char *extra)
+ struct iw_param *vwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
int rthr = vwrq->value;
/* Reject if card is already initialised */
- if(local->card_status != CARD_AWAITING_PARAM)
+ if (local->card_status != CARD_AWAITING_PARAM)
return -EBUSY;
/* if(wrq->u.rts.fixed == 0) we should complain */
- if(vwrq->disabled)
+ if (vwrq->disabled)
rthr = 32767;
else {
- if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */
+ if ((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */
return -EINVAL;
}
local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF;
local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF;
- return -EINPROGRESS; /* Call commit handler */
+ return -EINPROGRESS; /* Call commit handler */
}
-
/*------------------------------------------------------------------*/
/*
* Wireless Handler : get RTS threshold
*/
static int ray_get_rts(struct net_device *dev,
struct iw_request_info *info,
- struct iw_param *vwrq,
- char *extra)
+ struct iw_param *vwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
vwrq->value = (local->sparm.b5.a_rts_threshold[0] << 8)
- + local->sparm.b5.a_rts_threshold[1];
+ + local->sparm.b5.a_rts_threshold[1];
vwrq->disabled = (vwrq->value == 32767);
vwrq->fixed = 1;
@@ -1305,27 +1333,26 @@ static int ray_get_rts(struct net_device *dev,
*/
static int ray_set_frag(struct net_device *dev,
struct iw_request_info *info,
- struct iw_param *vwrq,
- char *extra)
+ struct iw_param *vwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
int fthr = vwrq->value;
/* Reject if card is already initialised */
- if(local->card_status != CARD_AWAITING_PARAM)
+ if (local->card_status != CARD_AWAITING_PARAM)
return -EBUSY;
/* if(wrq->u.frag.fixed == 0) should complain */
- if(vwrq->disabled)
+ if (vwrq->disabled)
fthr = 32767;
else {
- if((fthr < 256) || (fthr > 2347)) /* To check out ! */
+ if ((fthr < 256) || (fthr > 2347)) /* To check out ! */
return -EINVAL;
}
local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF;
local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF;
- return -EINPROGRESS; /* Call commit handler */
+ return -EINPROGRESS; /* Call commit handler */
}
/*------------------------------------------------------------------*/
@@ -1334,13 +1361,12 @@ static int ray_set_frag(struct net_device *dev,
*/
static int ray_get_frag(struct net_device *dev,
struct iw_request_info *info,
- struct iw_param *vwrq,
- char *extra)
+ struct iw_param *vwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
vwrq->value = (local->sparm.b5.a_frag_threshold[0] << 8)
- + local->sparm.b5.a_frag_threshold[1];
+ + local->sparm.b5.a_frag_threshold[1];
vwrq->disabled = (vwrq->value == 32767);
vwrq->fixed = 1;
@@ -1352,23 +1378,20 @@ static int ray_get_frag(struct net_device *dev,
* Wireless Handler : set Mode of Operation
*/
static int ray_set_mode(struct net_device *dev,
- struct iw_request_info *info,
- __u32 *uwrq,
- char *extra)
+ struct iw_request_info *info, __u32 *uwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
- int err = -EINPROGRESS; /* Call commit handler */
+ int err = -EINPROGRESS; /* Call commit handler */
char card_mode = 1;
/* Reject if card is already initialised */
- if(local->card_status != CARD_AWAITING_PARAM)
+ if (local->card_status != CARD_AWAITING_PARAM)
return -EBUSY;
- switch (*uwrq)
- {
+ switch (*uwrq) {
case IW_MODE_ADHOC:
card_mode = 0;
- // Fall through
+ /* Fall through */
case IW_MODE_INFRA:
local->sparm.b5.a_network_type = card_mode;
break;
@@ -1384,13 +1407,11 @@ static int ray_set_mode(struct net_device *dev,
* Wireless Handler : get Mode of Operation
*/
static int ray_get_mode(struct net_device *dev,
- struct iw_request_info *info,
- __u32 *uwrq,
- char *extra)
+ struct iw_request_info *info, __u32 *uwrq, char *extra)
{
ray_dev_t *local = netdev_priv(dev);
- if(local->sparm.b5.a_network_type)
+ if (local->sparm.b5.a_network_type)
*uwrq = IW_MODE_INFRA;
else
*uwrq = IW_MODE_ADHOC;
@@ -1404,12 +1425,11 @@ static int ray_get_mode(struct net_device *dev,
*/
static int ray_get_range(struct net_device *dev,
struct iw_request_info *info,
- struct iw_point *dwrq,
- char *extra)
+ struct iw_point *dwrq, char *extra)
{
- struct iw_range *range = (struct iw_range *) extra;
+ struct iw_range *range = (struct iw_range *)extra;
- memset((char *) range, 0, sizeof(struct iw_range));
+ memset((char *)range, 0, sizeof(struct iw_range));
/* Set the length (very important for backward compatibility) */
dwrq->length = sizeof(struct iw_range);
@@ -1420,7 +1440,7 @@ static int ray_get_range(struct net_device *dev,
/* Set information in the range struct */
range->throughput = 1.1 * 1000 * 1000; /* Put the right number here */
- range->num_channels = hop_pattern_length[(int)country];
+ range->num_channels = hop_pattern_length[(int)country];
range->num_frequency = 0;
range->max_qual.qual = 0;
range->max_qual.level = 255; /* What's the correct value ? */
@@ -1437,8 +1457,7 @@ static int ray_get_range(struct net_device *dev,
*/
static int ray_set_framing(struct net_device *dev,
struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ union iwreq_data *wrqu, char *extra)
{
translate = *(extra); /* Set framing mode */
@@ -1451,8 +1470,7 @@ static int ray_set_framing(struct net_device *dev,
*/
static int ray_get_framing(struct net_device *dev,
struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ union iwreq_data *wrqu, char *extra)
{
*(extra) = translate;
@@ -1465,8 +1483,7 @@ static int ray_get_framing(struct net_device *dev,
*/
static int ray_get_country(struct net_device *dev,
struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+ union iwreq_data *wrqu, char *extra)
{
*(extra) = country;
@@ -1477,11 +1494,10 @@ static int ray_get_country(struct net_device *dev,
/*
* Commit handler : called after a bunch of SET operations
*/
-static int ray_commit(struct net_device *dev,
- struct iw_request_info *info, /* NULL */
- void *zwrq, /* NULL */
- char *extra) /* NULL */
-{
+static int ray_commit(struct net_device *dev, struct iw_request_info *info, /* NULL */
+ void *zwrq, /* NULL */
+ char *extra)
+{ /* NULL */
return 0;
}
@@ -1489,33 +1505,34 @@ static int ray_commit(struct net_device *dev,
/*
* Stats handler : return Wireless Stats
*/
-static iw_stats * ray_get_wireless_stats(struct net_device * dev)
+static iw_stats *ray_get_wireless_stats(struct net_device *dev)
{
- ray_dev_t * local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- struct status __iomem *p = local->sram + STATUS_BASE;
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ struct status __iomem *p = local->sram + STATUS_BASE;
- if(local == (ray_dev_t *) NULL)
- return (iw_stats *) NULL;
+ if (local == (ray_dev_t *) NULL)
+ return (iw_stats *) NULL;
- local->wstats.status = local->card_status;
+ local->wstats.status = local->card_status;
#ifdef WIRELESS_SPY
- if((local->spy_data.spy_number > 0) && (local->sparm.b5.a_network_type == 0))
- {
- /* Get it from the first node in spy list */
- local->wstats.qual.qual = local->spy_data.spy_stat[0].qual;
- local->wstats.qual.level = local->spy_data.spy_stat[0].level;
- local->wstats.qual.noise = local->spy_data.spy_stat[0].noise;
- local->wstats.qual.updated = local->spy_data.spy_stat[0].updated;
- }
+ if ((local->spy_data.spy_number > 0)
+ && (local->sparm.b5.a_network_type == 0)) {
+ /* Get it from the first node in spy list */
+ local->wstats.qual.qual = local->spy_data.spy_stat[0].qual;
+ local->wstats.qual.level = local->spy_data.spy_stat[0].level;
+ local->wstats.qual.noise = local->spy_data.spy_stat[0].noise;
+ local->wstats.qual.updated =
+ local->spy_data.spy_stat[0].updated;
+ }
#endif /* WIRELESS_SPY */
- if(pcmcia_dev_present(link)) {
- local->wstats.qual.noise = readb(&p->rxnoise);
- local->wstats.qual.updated |= 4;
- }
+ if (pcmcia_dev_present(link)) {
+ local->wstats.qual.noise = readb(&p->rxnoise);
+ local->wstats.qual.updated |= 4;
+ }
- return &local->wstats;
+ return &local->wstats;
} /* end ray_get_wireless_stats */
/*------------------------------------------------------------------*/
@@ -1523,1159 +1540,1264 @@ static iw_stats * ray_get_wireless_stats(struct net_device * dev)
* Structures to export the Wireless Handlers
*/
-static const iw_handler ray_handler[] = {
- [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) ray_commit,
- [SIOCGIWNAME -SIOCIWFIRST] = (iw_handler) ray_get_name,
- [SIOCSIWFREQ -SIOCIWFIRST] = (iw_handler) ray_set_freq,
- [SIOCGIWFREQ -SIOCIWFIRST] = (iw_handler) ray_get_freq,
- [SIOCSIWMODE -SIOCIWFIRST] = (iw_handler) ray_set_mode,
- [SIOCGIWMODE -SIOCIWFIRST] = (iw_handler) ray_get_mode,
- [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) ray_get_range,
+static const iw_handler ray_handler[] = {
+ [SIOCSIWCOMMIT - SIOCIWFIRST] = (iw_handler) ray_commit,
+ [SIOCGIWNAME - SIOCIWFIRST] = (iw_handler) ray_get_name,
+ [SIOCSIWFREQ - SIOCIWFIRST] = (iw_handler) ray_set_freq,
+ [SIOCGIWFREQ - SIOCIWFIRST] = (iw_handler) ray_get_freq,
+ [SIOCSIWMODE - SIOCIWFIRST] = (iw_handler) ray_set_mode,
+ [SIOCGIWMODE - SIOCIWFIRST] = (iw_handler) ray_get_mode,
+ [SIOCGIWRANGE - SIOCIWFIRST] = (iw_handler) ray_get_range,
#ifdef WIRELESS_SPY
- [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
- [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
- [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
- [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
-#endif /* WIRELESS_SPY */
- [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) ray_get_wap,
- [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) ray_set_essid,
- [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) ray_get_essid,
- [SIOCSIWRATE -SIOCIWFIRST] = (iw_handler) ray_set_rate,
- [SIOCGIWRATE -SIOCIWFIRST] = (iw_handler) ray_get_rate,
- [SIOCSIWRTS -SIOCIWFIRST] = (iw_handler) ray_set_rts,
- [SIOCGIWRTS -SIOCIWFIRST] = (iw_handler) ray_get_rts,
- [SIOCSIWFRAG -SIOCIWFIRST] = (iw_handler) ray_set_frag,
- [SIOCGIWFRAG -SIOCIWFIRST] = (iw_handler) ray_get_frag,
+ [SIOCSIWSPY - SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
+ [SIOCGIWSPY - SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
+ [SIOCSIWTHRSPY - SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
+ [SIOCGIWTHRSPY - SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
+#endif /* WIRELESS_SPY */
+ [SIOCGIWAP - SIOCIWFIRST] = (iw_handler) ray_get_wap,
+ [SIOCSIWESSID - SIOCIWFIRST] = (iw_handler) ray_set_essid,
+ [SIOCGIWESSID - SIOCIWFIRST] = (iw_handler) ray_get_essid,
+ [SIOCSIWRATE - SIOCIWFIRST] = (iw_handler) ray_set_rate,
+ [SIOCGIWRATE - SIOCIWFIRST] = (iw_handler) ray_get_rate,
+ [SIOCSIWRTS - SIOCIWFIRST] = (iw_handler) ray_set_rts,
+ [SIOCGIWRTS - SIOCIWFIRST] = (iw_handler) ray_get_rts,
+ [SIOCSIWFRAG - SIOCIWFIRST] = (iw_handler) ray_set_frag,
+ [SIOCGIWFRAG - SIOCIWFIRST] = (iw_handler) ray_get_frag,
};
-#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */
+#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */
#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1 /* Get framing mode */
#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */
-static const iw_handler ray_private_handler[] = {
+static const iw_handler ray_private_handler[] = {
[0] = (iw_handler) ray_set_framing,
[1] = (iw_handler) ray_get_framing,
[3] = (iw_handler) ray_get_country,
};
-static const struct iw_priv_args ray_private_args[] = {
+static const struct iw_priv_args ray_private_args[] = {
/* cmd, set_args, get_args, name */
-{ SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" },
-{ SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" },
-{ SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" },
+ {SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0,
+ "set_framing"},
+ {SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
+ "get_framing"},
+ {SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
+ "get_country"},
};
-static const struct iw_handler_def ray_handler_def =
-{
- .num_standard = ARRAY_SIZE(ray_handler),
- .num_private = ARRAY_SIZE(ray_private_handler),
+static const struct iw_handler_def ray_handler_def = {
+ .num_standard = ARRAY_SIZE(ray_handler),
+ .num_private = ARRAY_SIZE(ray_private_handler),
.num_private_args = ARRAY_SIZE(ray_private_args),
- .standard = ray_handler,
- .private = ray_private_handler,
- .private_args = ray_private_args,
+ .standard = ray_handler,
+ .private = ray_private_handler,
+ .private_args = ray_private_args,
.get_wireless_stats = ray_get_wireless_stats,
};
/*===========================================================================*/
static int ray_open(struct net_device *dev)
{
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link;
- link = local->finder;
-
- DEBUG(1, "ray_open('%s')\n", dev->name);
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link;
+ link = local->finder;
- if (link->open == 0)
- local->num_multi = 0;
- link->open++;
+ DEBUG(1, "ray_open('%s')\n", dev->name);
- /* If the card is not started, time to start it ! - Jean II */
- if(local->card_status == CARD_AWAITING_PARAM) {
- int i;
+ if (link->open == 0)
+ local->num_multi = 0;
+ link->open++;
- DEBUG(1,"ray_open: doing init now !\n");
+ /* If the card is not started, time to start it ! - Jean II */
+ if (local->card_status == CARD_AWAITING_PARAM) {
+ int i;
- /* Download startup parameters */
- if ( (i = dl_startup_params(dev)) < 0)
- {
- printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
- "returns 0x%x\n",i);
- return -1;
- }
- }
-
- if (sniffer) netif_stop_queue(dev);
- else netif_start_queue(dev);
-
- DEBUG(2,"ray_open ending\n");
- return 0;
+ DEBUG(1, "ray_open: doing init now !\n");
+
+ /* Download startup parameters */
+ if ((i = dl_startup_params(dev)) < 0) {
+ printk(KERN_INFO
+ "ray_dev_init dl_startup_params failed - "
+ "returns 0x%x\n", i);
+ return -1;
+ }
+ }
+
+ if (sniffer)
+ netif_stop_queue(dev);
+ else
+ netif_start_queue(dev);
+
+ DEBUG(2, "ray_open ending\n");
+ return 0;
} /* end ray_open */
+
/*===========================================================================*/
static int ray_dev_close(struct net_device *dev)
{
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link;
- link = local->finder;
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link;
+ link = local->finder;
- DEBUG(1, "ray_dev_close('%s')\n", dev->name);
+ DEBUG(1, "ray_dev_close('%s')\n", dev->name);
- link->open--;
- netif_stop_queue(dev);
+ link->open--;
+ netif_stop_queue(dev);
- /* In here, we should stop the hardware (stop card from beeing active)
- * and set local->card_status to CARD_AWAITING_PARAM, so that while the
- * card is closed we can chage its configuration.
- * Probably also need a COR reset to get sane state - Jean II */
+ /* In here, we should stop the hardware (stop card from beeing active)
+ * and set local->card_status to CARD_AWAITING_PARAM, so that while the
+ * card is closed we can chage its configuration.
+ * Probably also need a COR reset to get sane state - Jean II */
- return 0;
+ return 0;
} /* end ray_dev_close */
+
/*===========================================================================*/
-static void ray_reset(struct net_device *dev) {
- DEBUG(1,"ray_reset entered\n");
- return;
+static void ray_reset(struct net_device *dev)
+{
+ DEBUG(1, "ray_reset entered\n");
+ return;
}
+
/*===========================================================================*/
/* Cause a firmware interrupt if it is ready for one */
/* Return nonzero if not ready */
static int interrupt_ecf(ray_dev_t *local, int ccs)
{
- int i = 50;
- struct pcmcia_device *link = local->finder;
-
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs interrupt_ecf - device not present\n");
- return -1;
- }
- DEBUG(2,"interrupt_ecf(local=%p, ccs = 0x%x\n",local,ccs);
-
- while ( i &&
- (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) & ECF_INTR_SET))
- i--;
- if (i == 0) {
- DEBUG(2,"ray_cs interrupt_ecf card not ready for interrupt\n");
- return -1;
- }
+ int i = 50;
+ struct pcmcia_device *link = local->finder;
+
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs interrupt_ecf - device not present\n");
+ return -1;
+ }
+ DEBUG(2, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs);
+
+ while (i &&
+ (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) &
+ ECF_INTR_SET))
+ i--;
+ if (i == 0) {
+ DEBUG(2, "ray_cs interrupt_ecf card not ready for interrupt\n");
+ return -1;
+ }
/* Fill the mailbox, then kick the card */
- writeb(ccs, local->sram + SCB_BASE);
- writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET);
- return 0;
+ writeb(ccs, local->sram + SCB_BASE);
+ writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET);
+ return 0;
} /* interrupt_ecf */
+
/*===========================================================================*/
/* Get next free transmit CCS */
/* Return - index of current tx ccs */
static int get_free_tx_ccs(ray_dev_t *local)
{
- int i;
- struct ccs __iomem *pccs = ccs_base(local);
- struct pcmcia_device *link = local->finder;
+ int i;
+ struct ccs __iomem *pccs = ccs_base(local);
+ struct pcmcia_device *link = local->finder;
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n");
- return ECARDGONE;
- }
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs get_free_tx_ccs - device not present\n");
+ return ECARDGONE;
+ }
- if (test_and_set_bit(0,&local->tx_ccs_lock)) {
- DEBUG(1,"ray_cs tx_ccs_lock busy\n");
- return ECCSBUSY;
- }
+ if (test_and_set_bit(0, &local->tx_ccs_lock)) {
+ DEBUG(1, "ray_cs tx_ccs_lock busy\n");
+ return ECCSBUSY;
+ }
- for (i=0; i < NUMBER_OF_TX_CCS; i++) {
- if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) {
- writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status);
- writeb(CCS_END_LIST, &(pccs+i)->link);
+ for (i = 0; i < NUMBER_OF_TX_CCS; i++) {
+ if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
+ writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
+ writeb(CCS_END_LIST, &(pccs + i)->link);
local->tx_ccs_lock = 0;
- return i;
- }
- }
+ return i;
+ }
+ }
local->tx_ccs_lock = 0;
- DEBUG(2,"ray_cs ERROR no free tx CCS for raylink card\n");
- return ECCSFULL;
+ DEBUG(2, "ray_cs ERROR no free tx CCS for raylink card\n");
+ return ECCSFULL;
} /* get_free_tx_ccs */
+
/*===========================================================================*/
/* Get next free CCS */
/* Return - index of current ccs */
static int get_free_ccs(ray_dev_t *local)
{
- int i;
- struct ccs __iomem *pccs = ccs_base(local);
- struct pcmcia_device *link = local->finder;
-
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs get_free_ccs - device not present\n");
- return ECARDGONE;
- }
- if (test_and_set_bit(0,&local->ccs_lock)) {
- DEBUG(1,"ray_cs ccs_lock busy\n");
- return ECCSBUSY;
- }
-
- for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) {
- if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) {
- writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status);
- writeb(CCS_END_LIST, &(pccs+i)->link);
+ int i;
+ struct ccs __iomem *pccs = ccs_base(local);
+ struct pcmcia_device *link = local->finder;
+
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs get_free_ccs - device not present\n");
+ return ECARDGONE;
+ }
+ if (test_and_set_bit(0, &local->ccs_lock)) {
+ DEBUG(1, "ray_cs ccs_lock busy\n");
+ return ECCSBUSY;
+ }
+
+ for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) {
+ if (readb(&(pccs + i)->buffer_status) == CCS_BUFFER_FREE) {
+ writeb(CCS_BUFFER_BUSY, &(pccs + i)->buffer_status);
+ writeb(CCS_END_LIST, &(pccs + i)->link);
local->ccs_lock = 0;
- return i;
- }
- }
+ return i;
+ }
+ }
local->ccs_lock = 0;
- DEBUG(1,"ray_cs ERROR no free CCS for raylink card\n");
- return ECCSFULL;
+ DEBUG(1, "ray_cs ERROR no free CCS for raylink card\n");
+ return ECCSFULL;
} /* get_free_ccs */
+
/*===========================================================================*/
static void authenticate_timeout(u_long data)
{
- ray_dev_t *local = (ray_dev_t *)data;
- del_timer(&local->timer);
- printk(KERN_INFO "ray_cs Authentication with access point failed"
- " - timeout\n");
- join_net((u_long)local);
+ ray_dev_t *local = (ray_dev_t *) data;
+ del_timer(&local->timer);
+ printk(KERN_INFO "ray_cs Authentication with access point failed"
+ " - timeout\n");
+ join_net((u_long) local);
}
+
/*===========================================================================*/
static int asc_to_int(char a)
{
- if (a < '0') return -1;
- if (a <= '9') return (a - '0');
- if (a < 'A') return -1;
- if (a <= 'F') return (10 + a - 'A');
- if (a < 'a') return -1;
- if (a <= 'f') return (10 + a - 'a');
- return -1;
+ if (a < '0')
+ return -1;
+ if (a <= '9')
+ return (a - '0');
+ if (a < 'A')
+ return -1;
+ if (a <= 'F')
+ return (10 + a - 'A');
+ if (a < 'a')
+ return -1;
+ if (a <= 'f')
+ return (10 + a - 'a');
+ return -1;
}
+
/*===========================================================================*/
static int parse_addr(char *in_str, UCHAR *out)
{
- int len;
- int i,j,k;
- int status;
-
- if (in_str == NULL) return 0;
- if ((len = strlen(in_str)) < 2) return 0;
- memset(out, 0, ADDRLEN);
-
- status = 1;
- j = len - 1;
- if (j > 12) j = 12;
- i = 5;
-
- while (j > 0)
- {
- if ((k = asc_to_int(in_str[j--])) != -1) out[i] = k;
- else return 0;
-
- if (j == 0) break;
- if ((k = asc_to_int(in_str[j--])) != -1) out[i] += k << 4;
- else return 0;
- if (!i--) break;
- }
- return status;
+ int len;
+ int i, j, k;
+ int status;
+
+ if (in_str == NULL)
+ return 0;
+ if ((len = strlen(in_str)) < 2)
+ return 0;
+ memset(out, 0, ADDRLEN);
+
+ status = 1;
+ j = len - 1;
+ if (j > 12)
+ j = 12;
+ i = 5;
+
+ while (j > 0) {
+ if ((k = asc_to_int(in_str[j--])) != -1)
+ out[i] = k;
+ else
+ return 0;
+
+ if (j == 0)
+ break;
+ if ((k = asc_to_int(in_str[j--])) != -1)
+ out[i] += k << 4;
+ else
+ return 0;
+ if (!i--)
+ break;
+ }
+ return status;
}
+
/*===========================================================================*/
static struct net_device_stats *ray_get_stats(struct net_device *dev)
{
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- struct status __iomem *p = local->sram + STATUS_BASE;
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs net_device_stats - device not present\n");
- return &local->stats;
- }
- if (readb(&p->mrx_overflow_for_host))
- {
- local->stats.rx_over_errors += swab16(readw(&p->mrx_overflow));
- writeb(0,&p->mrx_overflow);
- writeb(0,&p->mrx_overflow_for_host);
- }
- if (readb(&p->mrx_checksum_error_for_host))
- {
- local->stats.rx_crc_errors += swab16(readw(&p->mrx_checksum_error));
- writeb(0,&p->mrx_checksum_error);
- writeb(0,&p->mrx_checksum_error_for_host);
- }
- if (readb(&p->rx_hec_error_for_host))
- {
- local->stats.rx_frame_errors += swab16(readw(&p->rx_hec_error));
- writeb(0,&p->rx_hec_error);
- writeb(0,&p->rx_hec_error_for_host);
- }
- return &local->stats;
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ struct status __iomem *p = local->sram + STATUS_BASE;
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs net_device_stats - device not present\n");
+ return &local->stats;
+ }
+ if (readb(&p->mrx_overflow_for_host)) {
+ local->stats.rx_over_errors += swab16(readw(&p->mrx_overflow));
+ writeb(0, &p->mrx_overflow);
+ writeb(0, &p->mrx_overflow_for_host);
+ }
+ if (readb(&p->mrx_checksum_error_for_host)) {
+ local->stats.rx_crc_errors +=
+ swab16(readw(&p->mrx_checksum_error));
+ writeb(0, &p->mrx_checksum_error);
+ writeb(0, &p->mrx_checksum_error_for_host);
+ }
+ if (readb(&p->rx_hec_error_for_host)) {
+ local->stats.rx_frame_errors += swab16(readw(&p->rx_hec_error));
+ writeb(0, &p->rx_hec_error);
+ writeb(0, &p->rx_hec_error_for_host);
+ }
+ return &local->stats;
}
+
/*===========================================================================*/
-static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len)
-{
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- int ccsindex;
- int i;
- struct ccs __iomem *pccs;
-
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_update_parm - device not present\n");
- return;
- }
-
- if ((ccsindex = get_free_ccs(local)) < 0)
- {
- DEBUG(0,"ray_update_parm - No free ccs\n");
- return;
- }
- pccs = ccs_base(local) + ccsindex;
- writeb(CCS_UPDATE_PARAMS, &pccs->cmd);
- writeb(objid, &pccs->var.update_param.object_id);
- writeb(1, &pccs->var.update_param.number_objects);
- writeb(0, &pccs->var.update_param.failure_cause);
- for (i=0; i<len; i++) {
- writeb(value[i], local->sram + HOST_TO_ECF_BASE);
- }
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(0,"ray_cs associate failed - ECF not ready for intr\n");
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- }
+static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value,
+ int len)
+{
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ int ccsindex;
+ int i;
+ struct ccs __iomem *pccs;
+
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_update_parm - device not present\n");
+ return;
+ }
+
+ if ((ccsindex = get_free_ccs(local)) < 0) {
+ DEBUG(0, "ray_update_parm - No free ccs\n");
+ return;
+ }
+ pccs = ccs_base(local) + ccsindex;
+ writeb(CCS_UPDATE_PARAMS, &pccs->cmd);
+ writeb(objid, &pccs->var.update_param.object_id);
+ writeb(1, &pccs->var.update_param.number_objects);
+ writeb(0, &pccs->var.update_param.failure_cause);
+ for (i = 0; i < len; i++) {
+ writeb(value[i], local->sram + HOST_TO_ECF_BASE);
+ }
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(0, "ray_cs associate failed - ECF not ready for intr\n");
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ }
}
+
/*===========================================================================*/
static void ray_update_multi_list(struct net_device *dev, int all)
{
- struct dev_mc_list *dmi, **dmip;
- int ccsindex;
- struct ccs __iomem *pccs;
- int i = 0;
- ray_dev_t *local = netdev_priv(dev);
- struct pcmcia_device *link = local->finder;
- void __iomem *p = local->sram + HOST_TO_ECF_BASE;
-
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_update_multi_list - device not present\n");
- return;
- }
- else
- DEBUG(2,"ray_update_multi_list(%p)\n",dev);
- if ((ccsindex = get_free_ccs(local)) < 0)
- {
- DEBUG(1,"ray_update_multi - No free ccs\n");
- return;
- }
- pccs = ccs_base(local) + ccsindex;
- writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);
-
- if (all) {
- writeb(0xff, &pccs->var);
- local->num_multi = 0xff;
- }
- else {
- /* Copy the kernel's list of MC addresses to card */
- for (dmip=&dev->mc_list; (dmi=*dmip)!=NULL; dmip=&dmi->next) {
- memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);
- DEBUG(1,"ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",dmi->dmi_addr[0],dmi->dmi_addr[1],dmi->dmi_addr[2],dmi->dmi_addr[3],dmi->dmi_addr[4],dmi->dmi_addr[5]);
- p += ETH_ALEN;
- i++;
- }
- if (i > 256/ADDRLEN) i = 256/ADDRLEN;
- writeb((UCHAR)i, &pccs->var);
- DEBUG(1,"ray_cs update_multi %d addresses in list\n", i);
- /* Interrupt the firmware to process the command */
- local->num_multi = i;
- }
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1,"ray_cs update_multi failed - ECF not ready for intr\n");
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- }
+ struct dev_mc_list *dmi, **dmip;
+ int ccsindex;
+ struct ccs __iomem *pccs;
+ int i = 0;
+ ray_dev_t *local = netdev_priv(dev);
+ struct pcmcia_device *link = local->finder;
+ void __iomem *p = local->sram + HOST_TO_ECF_BASE;
+
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_update_multi_list - device not present\n");
+ return;
+ } else
+ DEBUG(2, "ray_update_multi_list(%p)\n", dev);
+ if ((ccsindex = get_free_ccs(local)) < 0) {
+ DEBUG(1, "ray_update_multi - No free ccs\n");
+ return;
+ }
+ pccs = ccs_base(local) + ccsindex;
+ writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);
+
+ if (all) {
+ writeb(0xff, &pccs->var);
+ local->num_multi = 0xff;
+ } else {
+ /* Copy the kernel's list of MC addresses to card */
+ for (dmip = &dev->mc_list; (dmi = *dmip) != NULL;
+ dmip = &dmi->next) {
+ memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);
+ DEBUG(1,
+ "ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",
+ dmi->dmi_addr[0], dmi->dmi_addr[1],
+ dmi->dmi_addr[2], dmi->dmi_addr[3],
+ dmi->dmi_addr[4], dmi->dmi_addr[5]);
+ p += ETH_ALEN;
+ i++;
+ }
+ if (i > 256 / ADDRLEN)
+ i = 256 / ADDRLEN;
+ writeb((UCHAR) i, &pccs->var);
+ DEBUG(1, "ray_cs update_multi %d addresses in list\n", i);
+ /* Interrupt the firmware to process the command */
+ local->num_multi = i;
+ }
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(1,
+ "ray_cs update_multi failed - ECF not ready for intr\n");
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ }
} /* end ray_update_multi_list */
+
/*===========================================================================*/
static void set_multicast_list(struct net_device *dev)
{
- ray_dev_t *local = netdev_priv(dev);
- UCHAR promisc;
-
- DEBUG(2,"ray_cs set_multicast_list(%p)\n",dev);
-
- if (dev->flags & IFF_PROMISC)
- {
- if (local->sparm.b5.a_promiscuous_mode == 0) {
- DEBUG(1,"ray_cs set_multicast_list promisc on\n");
- local->sparm.b5.a_promiscuous_mode = 1;
- promisc = 1;
- ray_update_parm(dev, OBJID_promiscuous_mode, \
- &promisc, sizeof(promisc));
- }
- }
- else {
- if (local->sparm.b5.a_promiscuous_mode == 1) {
- DEBUG(1,"ray_cs set_multicast_list promisc off\n");
- local->sparm.b5.a_promiscuous_mode = 0;
- promisc = 0;
- ray_update_parm(dev, OBJID_promiscuous_mode, \
- &promisc, sizeof(promisc));
- }
- }
-
- if (dev->flags & IFF_ALLMULTI) ray_update_multi_list(dev, 1);
- else
- {
- if (local->num_multi != dev->mc_count) ray_update_multi_list(dev, 0);
- }
+ ray_dev_t *local = netdev_priv(dev);
+ UCHAR promisc;
+
+ DEBUG(2, "ray_cs set_multicast_list(%p)\n", dev);
+
+ if (dev->flags & IFF_PROMISC) {
+ if (local->sparm.b5.a_promiscuous_mode == 0) {
+ DEBUG(1, "ray_cs set_multicast_list promisc on\n");
+ local->sparm.b5.a_promiscuous_mode = 1;
+ promisc = 1;
+ ray_update_parm(dev, OBJID_promiscuous_mode,
+ &promisc, sizeof(promisc));
+ }
+ } else {
+ if (local->sparm.b5.a_promiscuous_mode == 1) {
+ DEBUG(1, "ray_cs set_multicast_list promisc off\n");
+ local->sparm.b5.a_promiscuous_mode = 0;
+ promisc = 0;
+ ray_update_parm(dev, OBJID_promiscuous_mode,
+ &promisc, sizeof(promisc));
+ }
+ }
+
+ if (dev->flags & IFF_ALLMULTI)
+ ray_update_multi_list(dev, 1);
+ else {
+ if (local->num_multi != dev->mc_count)
+ ray_update_multi_list(dev, 0);
+ }
} /* end set_multicast_list */
+
/*=============================================================================
* All routines below here are run at interrupt time.
=============================================================================*/
static irqreturn_t ray_interrupt(int irq, void *dev_id)
{
- struct net_device *dev = (struct net_device *)dev_id;
- struct pcmcia_device *link;
- ray_dev_t *local;
- struct ccs __iomem *pccs;
- struct rcs __iomem *prcs;
- UCHAR rcsindex;
- UCHAR tmp;
- UCHAR cmd;
- UCHAR status;
-
- if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */
- return IRQ_NONE;
-
- DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev);
-
- local = netdev_priv(dev);
- link = (struct pcmcia_device *)local->finder;
- if (!pcmcia_dev_present(link)) {
- DEBUG(2,"ray_cs interrupt from device not present or suspended.\n");
- return IRQ_NONE;
- }
- rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index);
-
- if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS))
- {
- DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex);
- clear_interrupt(local);
- return IRQ_HANDLED;
- }
- if (rcsindex < NUMBER_OF_CCS) /* If it's a returned CCS */
- {
- pccs = ccs_base(local) + rcsindex;
- cmd = readb(&pccs->cmd);
- status = readb(&pccs->buffer_status);
- switch (cmd)
- {
- case CCS_DOWNLOAD_STARTUP_PARAMS: /* Happens in firmware someday */
- del_timer(&local->timer);
- if (status == CCS_COMMAND_COMPLETE) {
- DEBUG(1,"ray_cs interrupt download_startup_parameters OK\n");
- }
- else {
- DEBUG(1,"ray_cs interrupt download_startup_parameters fail\n");
- }
- break;
- case CCS_UPDATE_PARAMS:
- DEBUG(1,"ray_cs interrupt update params done\n");
- if (status != CCS_COMMAND_COMPLETE) {
- tmp = readb(&pccs->var.update_param.failure_cause);
- DEBUG(0,"ray_cs interrupt update params failed - reason %d\n",tmp);
- }
- break;
- case CCS_REPORT_PARAMS:
- DEBUG(1,"ray_cs interrupt report params done\n");
- break;
- case CCS_UPDATE_MULTICAST_LIST: /* Note that this CCS isn't returned */
- DEBUG(1,"ray_cs interrupt CCS Update Multicast List done\n");
- break;
- case CCS_UPDATE_POWER_SAVINGS_MODE:
- DEBUG(1,"ray_cs interrupt update power save mode done\n");
- break;
- case CCS_START_NETWORK:
- case CCS_JOIN_NETWORK:
- if (status == CCS_COMMAND_COMPLETE) {
- if (readb(&pccs->var.start_network.net_initiated) == 1) {
- DEBUG(0,"ray_cs interrupt network \"%s\" started\n",\
- local->sparm.b4.a_current_ess_id);
- }
- else {
- DEBUG(0,"ray_cs interrupt network \"%s\" joined\n",\
- local->sparm.b4.a_current_ess_id);
- }
- memcpy_fromio(&local->bss_id,pccs->var.start_network.bssid,ADDRLEN);
-
- if (local->fw_ver == 0x55) local->net_default_tx_rate = 3;
- else local->net_default_tx_rate =
- readb(&pccs->var.start_network.net_default_tx_rate);
- local->encryption = readb(&pccs->var.start_network.encryption);
- if (!sniffer && (local->net_type == INFRA)
- && !(local->sparm.b4.a_acting_as_ap_status)) {
- authenticate(local);
- }
- local->card_status = CARD_ACQ_COMPLETE;
- }
- else {
- local->card_status = CARD_ACQ_FAILED;
-
- del_timer(&local->timer);
- local->timer.expires = jiffies + HZ*5;
- local->timer.data = (long)local;
- if (status == CCS_START_NETWORK) {
- DEBUG(0,"ray_cs interrupt network \"%s\" start failed\n",\
- local->sparm.b4.a_current_ess_id);
- local->timer.function = &start_net;
- }
- else {
- DEBUG(0,"ray_cs interrupt network \"%s\" join failed\n",\
- local->sparm.b4.a_current_ess_id);
- local->timer.function = &join_net;
- }
- add_timer(&local->timer);
- }
- break;
- case CCS_START_ASSOCIATION:
- if (status == CCS_COMMAND_COMPLETE) {
- local->card_status = CARD_ASSOC_COMPLETE;
- DEBUG(0,"ray_cs association successful\n");
- }
- else
- {
- DEBUG(0,"ray_cs association failed,\n");
- local->card_status = CARD_ASSOC_FAILED;
- join_net((u_long)local);
- }
- break;
- case CCS_TX_REQUEST:
- if (status == CCS_COMMAND_COMPLETE) {
- DEBUG(3,"ray_cs interrupt tx request complete\n");
- }
- else {
- DEBUG(1,"ray_cs interrupt tx request failed\n");
- }
- if (!sniffer) netif_start_queue(dev);
- netif_wake_queue(dev);
- break;
- case CCS_TEST_MEMORY:
- DEBUG(1,"ray_cs interrupt mem test done\n");
- break;
- case CCS_SHUTDOWN:
- DEBUG(1,"ray_cs interrupt Unexpected CCS returned - Shutdown\n");
- break;
- case CCS_DUMP_MEMORY:
- DEBUG(1,"ray_cs interrupt dump memory done\n");
- break;
- case CCS_START_TIMER:
- DEBUG(2,"ray_cs interrupt DING - raylink timer expired\n");
- break;
- default:
- DEBUG(1,"ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",\
- rcsindex, cmd);
- }
- writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
- }
- else /* It's an RCS */
- {
- prcs = rcs_base(local) + rcsindex;
-
- switch (readb(&prcs->interrupt_id))
- {
- case PROCESS_RX_PACKET:
- ray_rx(dev, local, prcs);
- break;
- case REJOIN_NET_COMPLETE:
- DEBUG(1,"ray_cs interrupt rejoin net complete\n");
- local->card_status = CARD_ACQ_COMPLETE;
- /* do we need to clear tx buffers CCS's? */
- if (local->sparm.b4.a_network_type == ADHOC) {
- if (!sniffer) netif_start_queue(dev);
- }
- else {
- memcpy_fromio(&local->bss_id, prcs->var.rejoin_net_complete.bssid, ADDRLEN);
- DEBUG(1,"ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",\
- local->bss_id[0], local->bss_id[1], local->bss_id[2],\
- local->bss_id[3], local->bss_id[4], local->bss_id[5]);
- if (!sniffer) authenticate(local);
- }
- break;
- case ROAMING_INITIATED:
- DEBUG(1,"ray_cs interrupt roaming initiated\n");
- netif_stop_queue(dev);
- local->card_status = CARD_DOING_ACQ;
- break;
- case JAPAN_CALL_SIGN_RXD:
- DEBUG(1,"ray_cs interrupt japan call sign rx\n");
- break;
- default:
- DEBUG(1,"ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",\
- rcsindex, (unsigned int) readb(&prcs->interrupt_id));
- break;
- }
- writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
- }
- clear_interrupt(local);
- return IRQ_HANDLED;
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct pcmcia_device *link;
+ ray_dev_t *local;
+ struct ccs __iomem *pccs;
+ struct rcs __iomem *prcs;
+ UCHAR rcsindex;
+ UCHAR tmp;
+ UCHAR cmd;
+ UCHAR status;
+
+ if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */
+ return IRQ_NONE;
+
+ DEBUG(4, "ray_cs: interrupt for *dev=%p\n", dev);
+
+ local = netdev_priv(dev);
+ link = (struct pcmcia_device *)local->finder;
+ if (!pcmcia_dev_present(link)) {
+ DEBUG(2,
+ "ray_cs interrupt from device not present or suspended.\n");
+ return IRQ_NONE;
+ }
+ rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index);
+
+ if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
+ DEBUG(1, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex);
+ clear_interrupt(local);
+ return IRQ_HANDLED;
+ }
+ if (rcsindex < NUMBER_OF_CCS) { /* If it's a returned CCS */
+ pccs = ccs_base(local) + rcsindex;
+ cmd = readb(&pccs->cmd);
+ status = readb(&pccs->buffer_status);
+ switch (cmd) {
+ case CCS_DOWNLOAD_STARTUP_PARAMS: /* Happens in firmware someday */
+ del_timer(&local->timer);
+ if (status == CCS_COMMAND_COMPLETE) {
+ DEBUG(1,
+ "ray_cs interrupt download_startup_parameters OK\n");
+ } else {
+ DEBUG(1,
+ "ray_cs interrupt download_startup_parameters fail\n");
+ }
+ break;
+ case CCS_UPDATE_PARAMS:
+ DEBUG(1, "ray_cs interrupt update params done\n");
+ if (status != CCS_COMMAND_COMPLETE) {
+ tmp =
+ readb(&pccs->var.update_param.
+ failure_cause);
+ DEBUG(0,
+ "ray_cs interrupt update params failed - reason %d\n",
+ tmp);
+ }
+ break;
+ case CCS_REPORT_PARAMS:
+ DEBUG(1, "ray_cs interrupt report params done\n");
+ break;
+ case CCS_UPDATE_MULTICAST_LIST: /* Note that this CCS isn't returned */
+ DEBUG(1,
+ "ray_cs interrupt CCS Update Multicast List done\n");
+ break;
+ case CCS_UPDATE_POWER_SAVINGS_MODE:
+ DEBUG(1,
+ "ray_cs interrupt update power save mode done\n");
+ break;
+ case CCS_START_NETWORK:
+ case CCS_JOIN_NETWORK:
+ if (status == CCS_COMMAND_COMPLETE) {
+ if (readb
+ (&pccs->var.start_network.net_initiated) ==
+ 1) {
+ DEBUG(0,
+ "ray_cs interrupt network \"%s\" started\n",
+ local->sparm.b4.a_current_ess_id);
+ } else {
+ DEBUG(0,
+ "ray_cs interrupt network \"%s\" joined\n",
+ local->sparm.b4.a_current_ess_id);
+ }
+ memcpy_fromio(&local->bss_id,
+ pccs->var.start_network.bssid,
+ ADDRLEN);
+
+ if (local->fw_ver == 0x55)
+ local->net_default_tx_rate = 3;
+ else
+ local->net_default_tx_rate =
+ readb(&pccs->var.start_network.
+ net_default_tx_rate);
+ local->encryption =
+ readb(&pccs->var.start_network.encryption);
+ if (!sniffer && (local->net_type == INFRA)
+ && !(local->sparm.b4.a_acting_as_ap_status)) {
+ authenticate(local);
+ }
+ local->card_status = CARD_ACQ_COMPLETE;
+ } else {
+ local->card_status = CARD_ACQ_FAILED;
+
+ del_timer(&local->timer);
+ local->timer.expires = jiffies + HZ * 5;
+ local->timer.data = (long)local;
+ if (status == CCS_START_NETWORK) {
+ DEBUG(0,
+ "ray_cs interrupt network \"%s\" start failed\n",
+ local->sparm.b4.a_current_ess_id);
+ local->timer.function = &start_net;
+ } else {
+ DEBUG(0,
+ "ray_cs interrupt network \"%s\" join failed\n",
+ local->sparm.b4.a_current_ess_id);
+ local->timer.function = &join_net;
+ }
+ add_timer(&local->timer);
+ }
+ break;
+ case CCS_START_ASSOCIATION:
+ if (status == CCS_COMMAND_COMPLETE) {
+ local->card_status = CARD_ASSOC_COMPLETE;
+ DEBUG(0, "ray_cs association successful\n");
+ } else {
+ DEBUG(0, "ray_cs association failed,\n");
+ local->card_status = CARD_ASSOC_FAILED;
+ join_net((u_long) local);
+ }
+ break;
+ case CCS_TX_REQUEST:
+ if (status == CCS_COMMAND_COMPLETE) {
+ DEBUG(3,
+ "ray_cs interrupt tx request complete\n");
+ } else {
+ DEBUG(1,
+ "ray_cs interrupt tx request failed\n");
+ }
+ if (!sniffer)
+ netif_start_queue(dev);
+ netif_wake_queue(dev);
+ break;
+ case CCS_TEST_MEMORY:
+ DEBUG(1, "ray_cs interrupt mem test done\n");
+ break;
+ case CCS_SHUTDOWN:
+ DEBUG(1,
+ "ray_cs interrupt Unexpected CCS returned - Shutdown\n");
+ break;
+ case CCS_DUMP_MEMORY:
+ DEBUG(1, "ray_cs interrupt dump memory done\n");
+ break;
+ case CCS_START_TIMER:
+ DEBUG(2,
+ "ray_cs interrupt DING - raylink timer expired\n");
+ break;
+ default:
+ DEBUG(1,
+ "ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",
+ rcsindex, cmd);
+ }
+ writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
+ } else { /* It's an RCS */
+
+ prcs = rcs_base(local) + rcsindex;
+
+ switch (readb(&prcs->interrupt_id)) {
+ case PROCESS_RX_PACKET:
+ ray_rx(dev, local, prcs);
+ break;
+ case REJOIN_NET_COMPLETE:
+ DEBUG(1, "ray_cs interrupt rejoin net complete\n");
+ local->card_status = CARD_ACQ_COMPLETE;
+ /* do we need to clear tx buffers CCS's? */
+ if (local->sparm.b4.a_network_type == ADHOC) {
+ if (!sniffer)
+ netif_start_queue(dev);
+ } else {
+ memcpy_fromio(&local->bss_id,
+ prcs->var.rejoin_net_complete.
+ bssid, ADDRLEN);
+ DEBUG(1,
+ "ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",
+ local->bss_id[0], local->bss_id[1],
+ local->bss_id[2], local->bss_id[3],
+ local->bss_id[4], local->bss_id[5]);
+ if (!sniffer)
+ authenticate(local);
+ }
+ break;
+ case ROAMING_INITIATED:
+ DEBUG(1, "ray_cs interrupt roaming initiated\n");
+ netif_stop_queue(dev);
+ local->card_status = CARD_DOING_ACQ;
+ break;
+ case JAPAN_CALL_SIGN_RXD:
+ DEBUG(1, "ray_cs interrupt japan call sign rx\n");
+ break;
+ default:
+ DEBUG(1,
+ "ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",
+ rcsindex,
+ (unsigned int)readb(&prcs->interrupt_id));
+ break;
+ }
+ writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
+ }
+ clear_interrupt(local);
+ return IRQ_HANDLED;
} /* ray_interrupt */
+
/*===========================================================================*/
-static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs __iomem *prcs)
-{
- int rx_len;
- unsigned int pkt_addr;
- void __iomem *pmsg;
- DEBUG(4,"ray_rx process rx packet\n");
-
- /* Calculate address of packet within Rx buffer */
- pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
- + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END;
- /* Length of first packet fragment */
- rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8)
- + readb(&prcs->var.rx_packet.rx_data_length[1]);
-
- local->last_rsl = readb(&prcs->var.rx_packet.rx_sig_lev);
- pmsg = local->rmem + pkt_addr;
- switch(readb(pmsg))
- {
- case DATA_TYPE:
- DEBUG(4,"ray_rx data type\n");
- rx_data(dev, prcs, pkt_addr, rx_len);
- break;
- case AUTHENTIC_TYPE:
- DEBUG(4,"ray_rx authentic type\n");
- if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
- else rx_authenticate(local, prcs, pkt_addr, rx_len);
- break;
- case DEAUTHENTIC_TYPE:
- DEBUG(4,"ray_rx deauth type\n");
- if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
- else rx_deauthenticate(local, prcs, pkt_addr, rx_len);
- break;
- case NULL_MSG_TYPE:
- DEBUG(3,"ray_cs rx NULL msg\n");
- break;
- case BEACON_TYPE:
- DEBUG(4,"ray_rx beacon type\n");
- if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
-
- copy_from_rx_buff(local, (UCHAR *)&local->last_bcn, pkt_addr,
- rx_len < sizeof(struct beacon_rx) ?
- rx_len : sizeof(struct beacon_rx));
-
- local->beacon_rxed = 1;
- /* Get the statistics so the card counters never overflow */
- ray_get_stats(dev);
- break;
- default:
- DEBUG(0,"ray_cs unknown pkt type %2x\n", (unsigned int) readb(pmsg));
- break;
- }
+static void ray_rx(struct net_device *dev, ray_dev_t *local,
+ struct rcs __iomem *prcs)
+{
+ int rx_len;
+ unsigned int pkt_addr;
+ void __iomem *pmsg;
+ DEBUG(4, "ray_rx process rx packet\n");
+
+ /* Calculate address of packet within Rx buffer */
+ pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
+ + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END;
+ /* Length of first packet fragment */
+ rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8)
+ + readb(&prcs->var.rx_packet.rx_data_length[1]);
+
+ local->last_rsl = readb(&prcs->var.rx_packet.rx_sig_lev);
+ pmsg = local->rmem + pkt_addr;
+ switch (readb(pmsg)) {
+ case DATA_TYPE:
+ DEBUG(4, "ray_rx data type\n");
+ rx_data(dev, prcs, pkt_addr, rx_len);
+ break;
+ case AUTHENTIC_TYPE:
+ DEBUG(4, "ray_rx authentic type\n");
+ if (sniffer)
+ rx_data(dev, prcs, pkt_addr, rx_len);
+ else
+ rx_authenticate(local, prcs, pkt_addr, rx_len);
+ break;
+ case DEAUTHENTIC_TYPE:
+ DEBUG(4, "ray_rx deauth type\n");
+ if (sniffer)
+ rx_data(dev, prcs, pkt_addr, rx_len);
+ else
+ rx_deauthenticate(local, prcs, pkt_addr, rx_len);
+ break;
+ case NULL_MSG_TYPE:
+ DEBUG(3, "ray_cs rx NULL msg\n");
+ break;
+ case BEACON_TYPE:
+ DEBUG(4, "ray_rx beacon type\n");
+ if (sniffer)
+ rx_data(dev, prcs, pkt_addr, rx_len);
+
+ copy_from_rx_buff(local, (UCHAR *) &local->last_bcn, pkt_addr,
+ rx_len < sizeof(struct beacon_rx) ?
+ rx_len : sizeof(struct beacon_rx));
+
+ local->beacon_rxed = 1;
+ /* Get the statistics so the card counters never overflow */
+ ray_get_stats(dev);
+ break;
+ default:
+ DEBUG(0, "ray_cs unknown pkt type %2x\n",
+ (unsigned int)readb(pmsg));
+ break;
+ }
} /* end ray_rx */
+
/*===========================================================================*/
-static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned int pkt_addr,
- int rx_len)
-{
- struct sk_buff *skb = NULL;
- struct rcs __iomem *prcslink = prcs;
- ray_dev_t *local = netdev_priv(dev);
- UCHAR *rx_ptr;
- int total_len;
- int tmp;
+static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
+ unsigned int pkt_addr, int rx_len)
+{
+ struct sk_buff *skb = NULL;
+ struct rcs __iomem *prcslink = prcs;
+ ray_dev_t *local = netdev_priv(dev);
+ UCHAR *rx_ptr;
+ int total_len;
+ int tmp;
#ifdef WIRELESS_SPY
- int siglev = local->last_rsl;
- u_char linksrcaddr[ETH_ALEN]; /* Other end of the wireless link */
+ int siglev = local->last_rsl;
+ u_char linksrcaddr[ETH_ALEN]; /* Other end of the wireless link */
#endif
- if (!sniffer) {
- if (translate) {
+ if (!sniffer) {
+ if (translate) {
/* TBD length needs fixing for translated header */
- if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
- rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN))
- {
- DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len);
- return;
- }
- }
- else /* encapsulated ethernet */ {
- if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
- rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN))
- {
- DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len);
- return;
- }
- }
- }
- DEBUG(4,"ray_cs rx_data packet\n");
- /* If fragmented packet, verify sizes of fragments add up */
- if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
- DEBUG(1,"ray_cs rx'ed fragment\n");
- tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
- + readb(&prcs->var.rx_packet.totalpacketlength[1]);
- total_len = tmp;
- prcslink = prcs;
- do {
- tmp -= (readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8)
- + readb(&prcslink->var.rx_packet.rx_data_length[1]);
- if (readb(&prcslink->var.rx_packet.next_frag_rcs_index) == 0xFF
- || tmp < 0) break;
- prcslink = rcs_base(local)
- + readb(&prcslink->link_field);
- } while (1);
-
- if (tmp < 0)
- {
- DEBUG(0,"ray_cs rx_data fragment lengths don't add up\n");
- local->stats.rx_dropped++;
- release_frag_chain(local, prcs);
- return;
- }
- }
- else { /* Single unfragmented packet */
- total_len = rx_len;
- }
-
- skb = dev_alloc_skb( total_len+5 );
- if (skb == NULL)
- {
- DEBUG(0,"ray_cs rx_data could not allocate skb\n");
- local->stats.rx_dropped++;
- if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
- release_frag_chain(local, prcs);
- return;
- }
- skb_reserve( skb, 2); /* Align IP on 16 byte (TBD check this)*/
-
- DEBUG(4,"ray_cs rx_data total_len = %x, rx_len = %x\n",total_len,rx_len);
+ if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
+ rx_len >
+ (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
+ FCS_LEN)) {
+ DEBUG(0,
+ "ray_cs invalid packet length %d received \n",
+ rx_len);
+ return;
+ }
+ } else { /* encapsulated ethernet */
+
+ if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
+ rx_len >
+ (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
+ FCS_LEN)) {
+ DEBUG(0,
+ "ray_cs invalid packet length %d received \n",
+ rx_len);
+ return;
+ }
+ }
+ }
+ DEBUG(4, "ray_cs rx_data packet\n");
+ /* If fragmented packet, verify sizes of fragments add up */
+ if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
+ DEBUG(1, "ray_cs rx'ed fragment\n");
+ tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
+ + readb(&prcs->var.rx_packet.totalpacketlength[1]);
+ total_len = tmp;
+ prcslink = prcs;
+ do {
+ tmp -=
+ (readb(&prcslink->var.rx_packet.rx_data_length[0])
+ << 8)
+ + readb(&prcslink->var.rx_packet.rx_data_length[1]);
+ if (readb(&prcslink->var.rx_packet.next_frag_rcs_index)
+ == 0xFF || tmp < 0)
+ break;
+ prcslink = rcs_base(local)
+ + readb(&prcslink->link_field);
+ } while (1);
+
+ if (tmp < 0) {
+ DEBUG(0,
+ "ray_cs rx_data fragment lengths don't add up\n");
+ local->stats.rx_dropped++;
+ release_frag_chain(local, prcs);
+ return;
+ }
+ } else { /* Single unfragmented packet */
+ total_len = rx_len;
+ }
+
+ skb = dev_alloc_skb(total_len + 5);
+ if (skb == NULL) {
+ DEBUG(0, "ray_cs rx_data could not allocate skb\n");
+ local->stats.rx_dropped++;
+ if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
+ release_frag_chain(local, prcs);
+ return;
+ }
+ skb_reserve(skb, 2); /* Align IP on 16 byte (TBD check this) */
+
+ DEBUG(4, "ray_cs rx_data total_len = %x, rx_len = %x\n", total_len,
+ rx_len);
/************************/
- /* Reserve enough room for the whole damn packet. */
- rx_ptr = skb_put( skb, total_len);
- /* Copy the whole packet to sk_buff */
- rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
- /* Get source address */
+ /* Reserve enough room for the whole damn packet. */
+ rx_ptr = skb_put(skb, total_len);
+ /* Copy the whole packet to sk_buff */
+ rx_ptr +=
+ copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
+ /* Get source address */
#ifdef WIRELESS_SPY
- skb_copy_from_linear_data_offset(skb, offsetof(struct mac_header, addr_2),
- linksrcaddr, ETH_ALEN);
+ skb_copy_from_linear_data_offset(skb,
+ offsetof(struct mac_header, addr_2),
+ linksrcaddr, ETH_ALEN);
#endif
- /* Now, deal with encapsulation/translation/sniffer */
- if (!sniffer) {
- if (!translate) {
- /* Encapsulated ethernet, so just lop off 802.11 MAC header */
+ /* Now, deal with encapsulation/translation/sniffer */
+ if (!sniffer) {
+ if (!translate) {
+ /* Encapsulated ethernet, so just lop off 802.11 MAC header */
/* TBD reserve skb_reserve( skb, RX_MAC_HEADER_LENGTH); */
- skb_pull( skb, RX_MAC_HEADER_LENGTH);
- }
- else {
- /* Do translation */
- untranslate(local, skb, total_len);
- }
- }
- else
- { /* sniffer mode, so just pass whole packet */ };
+ skb_pull(skb, RX_MAC_HEADER_LENGTH);
+ } else {
+ /* Do translation */
+ untranslate(local, skb, total_len);
+ }
+ } else { /* sniffer mode, so just pass whole packet */
+ };
/************************/
- /* Now pick up the rest of the fragments if any */
- tmp = 17;
- if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
- prcslink = prcs;
- DEBUG(1,"ray_cs rx_data in fragment loop\n");
- do {
- prcslink = rcs_base(local)
- + readb(&prcslink->var.rx_packet.next_frag_rcs_index);
- rx_len = (( readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8)
- + readb(&prcslink->var.rx_packet.rx_data_length[1]))
- & RX_BUFF_END;
- pkt_addr = (( readb(&prcslink->var.rx_packet.rx_data_ptr[0]) << 8)
- + readb(&prcslink->var.rx_packet.rx_data_ptr[1]))
- & RX_BUFF_END;
-
- rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len);
-
- } while (tmp-- &&
- readb(&prcslink->var.rx_packet.next_frag_rcs_index) != 0xFF);
- release_frag_chain(local, prcs);
- }
-
- skb->protocol = eth_type_trans(skb,dev);
- netif_rx(skb);
- local->stats.rx_packets++;
- local->stats.rx_bytes += total_len;
-
- /* Gather signal strength per address */
+ /* Now pick up the rest of the fragments if any */
+ tmp = 17;
+ if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
+ prcslink = prcs;
+ DEBUG(1, "ray_cs rx_data in fragment loop\n");
+ do {
+ prcslink = rcs_base(local)
+ +
+ readb(&prcslink->var.rx_packet.next_frag_rcs_index);
+ rx_len =
+ ((readb(&prcslink->var.rx_packet.rx_data_length[0])
+ << 8)
+ +
+ readb(&prcslink->var.rx_packet.rx_data_length[1]))
+ & RX_BUFF_END;
+ pkt_addr =
+ ((readb(&prcslink->var.rx_packet.rx_data_ptr[0]) <<
+ 8)
+ + readb(&prcslink->var.rx_packet.rx_data_ptr[1]))
+ & RX_BUFF_END;
+
+ rx_ptr +=
+ copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len);
+
+ } while (tmp-- &&
+ readb(&prcslink->var.rx_packet.next_frag_rcs_index) !=
+ 0xFF);
+ release_frag_chain(local, prcs);
+ }
+
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+ local->stats.rx_packets++;
+ local->stats.rx_bytes += total_len;
+
+ /* Gather signal strength per address */
#ifdef WIRELESS_SPY
- /* For the Access Point or the node having started the ad-hoc net
- * note : ad-hoc work only in some specific configurations, but we
- * kludge in ray_get_wireless_stats... */
- if(!memcmp(linksrcaddr, local->bss_id, ETH_ALEN))
- {
- /* Update statistics */
- /*local->wstats.qual.qual = none ? */
- local->wstats.qual.level = siglev;
- /*local->wstats.qual.noise = none ? */
- local->wstats.qual.updated = 0x2;
- }
- /* Now, update the spy stuff */
- {
- struct iw_quality wstats;
- wstats.level = siglev;
- /* wstats.noise = none ? */
- /* wstats.qual = none ? */
- wstats.updated = 0x2;
- /* Update spy records */
- wireless_spy_update(dev, linksrcaddr, &wstats);
- }
-#endif /* WIRELESS_SPY */
+ /* For the Access Point or the node having started the ad-hoc net
+ * note : ad-hoc work only in some specific configurations, but we
+ * kludge in ray_get_wireless_stats... */
+ if (!memcmp(linksrcaddr, local->bss_id, ETH_ALEN)) {
+ /* Update statistics */
+ /*local->wstats.qual.qual = none ? */
+ local->wstats.qual.level = siglev;
+ /*local->wstats.qual.noise = none ? */
+ local->wstats.qual.updated = 0x2;
+ }
+ /* Now, update the spy stuff */
+ {
+ struct iw_quality wstats;
+ wstats.level = siglev;
+ /* wstats.noise = none ? */
+ /* wstats.qual = none ? */
+ wstats.updated = 0x2;
+ /* Update spy records */
+ wireless_spy_update(dev, linksrcaddr, &wstats);
+ }
+#endif /* WIRELESS_SPY */
} /* end rx_data */
+
/*===========================================================================*/
static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
{
- snaphdr_t *psnap = (snaphdr_t *)(skb->data + RX_MAC_HEADER_LENGTH);
- struct ieee80211_hdr *pmac = (struct ieee80211_hdr *)skb->data;
- __be16 type = *(__be16 *)psnap->ethertype;
- int delta;
- struct ethhdr *peth;
- UCHAR srcaddr[ADDRLEN];
- UCHAR destaddr[ADDRLEN];
- static UCHAR org_bridge[3] = {0, 0, 0xf8};
- static UCHAR org_1042[3] = {0, 0, 0};
+ snaphdr_t *psnap = (snaphdr_t *) (skb->data + RX_MAC_HEADER_LENGTH);
+ struct ieee80211_hdr *pmac = (struct ieee80211_hdr *)skb->data;
+ __be16 type = *(__be16 *) psnap->ethertype;
+ int delta;
+ struct ethhdr *peth;
+ UCHAR srcaddr[ADDRLEN];
+ UCHAR destaddr[ADDRLEN];
+ static UCHAR org_bridge[3] = { 0, 0, 0xf8 };
+ static UCHAR org_1042[3] = { 0, 0, 0 };
- memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
- memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
+ memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
+ memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
#ifdef PCMCIA_DEBUG
- if (pc_debug > 3) {
- int i;
- printk(KERN_DEBUG "skb->data before untranslate");
- for (i=0;i<64;i++)
- printk("%02x ",skb->data[i]);
- printk("\n" KERN_DEBUG "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
- ntohs(type),
- psnap->dsap, psnap->ssap, psnap->ctrl,
- psnap->org[0], psnap->org[1], psnap->org[2]);
- printk(KERN_DEBUG "untranslate skb->data = %p\n",skb->data);
- }
+ if (pc_debug > 3) {
+ int i;
+ printk(KERN_DEBUG "skb->data before untranslate");
+ for (i = 0; i < 64; i++)
+ printk("%02x ", skb->data[i]);
+ printk("\n" KERN_DEBUG
+ "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
+ ntohs(type), psnap->dsap, psnap->ssap, psnap->ctrl,
+ psnap->org[0], psnap->org[1], psnap->org[2]);
+ printk(KERN_DEBUG "untranslate skb->data = %p\n", skb->data);
+ }
#endif
- if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
- /* not a snap type so leave it alone */
- DEBUG(3,"ray_cs untranslate NOT SNAP %02x %02x %02x\n",
- psnap->dsap, psnap->ssap, psnap->ctrl);
-
- delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
- peth = (struct ethhdr *)(skb->data + delta);
- peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
- }
- else { /* Its a SNAP */
- if (memcmp(psnap->org, org_bridge, 3) == 0) { /* EtherII and nuke the LLC */
- DEBUG(3,"ray_cs untranslate Bridge encap\n");
- delta = RX_MAC_HEADER_LENGTH
- + sizeof(struct snaphdr_t) - ETH_HLEN;
- peth = (struct ethhdr *)(skb->data + delta);
- peth->h_proto = type;
- } else if (memcmp(psnap->org, org_1042, 3) == 0) {
- switch (ntohs(type)) {
- case ETH_P_IPX:
- case ETH_P_AARP:
- DEBUG(3,"ray_cs untranslate RFC IPX/AARP\n");
- delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
- peth = (struct ethhdr *)(skb->data + delta);
- peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
- break;
- default:
- DEBUG(3,"ray_cs untranslate RFC default\n");
- delta = RX_MAC_HEADER_LENGTH +
- sizeof(struct snaphdr_t) - ETH_HLEN;
- peth = (struct ethhdr *)(skb->data + delta);
- peth->h_proto = type;
- break;
- }
- } else {
- printk("ray_cs untranslate very confused by packet\n");
- delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
- peth = (struct ethhdr *)(skb->data + delta);
- peth->h_proto = type;
+ if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
+ /* not a snap type so leave it alone */
+ DEBUG(3, "ray_cs untranslate NOT SNAP %02x %02x %02x\n",
+ psnap->dsap, psnap->ssap, psnap->ctrl);
+
+ delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
+ peth = (struct ethhdr *)(skb->data + delta);
+ peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
+ } else { /* Its a SNAP */
+ if (memcmp(psnap->org, org_bridge, 3) == 0) {
+ /* EtherII and nuke the LLC */
+ DEBUG(3, "ray_cs untranslate Bridge encap\n");
+ delta = RX_MAC_HEADER_LENGTH
+ + sizeof(struct snaphdr_t) - ETH_HLEN;
+ peth = (struct ethhdr *)(skb->data + delta);
+ peth->h_proto = type;
+ } else if (memcmp(psnap->org, org_1042, 3) == 0) {
+ switch (ntohs(type)) {
+ case ETH_P_IPX:
+ case ETH_P_AARP:
+ DEBUG(3, "ray_cs untranslate RFC IPX/AARP\n");
+ delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
+ peth = (struct ethhdr *)(skb->data + delta);
+ peth->h_proto =
+ htons(len - RX_MAC_HEADER_LENGTH);
+ break;
+ default:
+ DEBUG(3, "ray_cs untranslate RFC default\n");
+ delta = RX_MAC_HEADER_LENGTH +
+ sizeof(struct snaphdr_t) - ETH_HLEN;
+ peth = (struct ethhdr *)(skb->data + delta);
+ peth->h_proto = type;
+ break;
+ }
+ } else {
+ printk("ray_cs untranslate very confused by packet\n");
+ delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
+ peth = (struct ethhdr *)(skb->data + delta);
+ peth->h_proto = type;
+ }
}
- }
/* TBD reserve skb_reserve(skb, delta); */
- skb_pull(skb, delta);
- DEBUG(3,"untranslate after skb_pull(%d), skb->data = %p\n",delta,skb->data);
- memcpy(peth->h_dest, destaddr, ADDRLEN);
- memcpy(peth->h_source, srcaddr, ADDRLEN);
+ skb_pull(skb, delta);
+ DEBUG(3, "untranslate after skb_pull(%d), skb->data = %p\n", delta,
+ skb->data);
+ memcpy(peth->h_dest, destaddr, ADDRLEN);
+ memcpy(peth->h_source, srcaddr, ADDRLEN);
#ifdef PCMCIA_DEBUG
- if (pc_debug > 3) {
- int i;
- printk(KERN_DEBUG "skb->data after untranslate:");
- for (i=0;i<64;i++)
- printk("%02x ",skb->data[i]);
- printk("\n");
- }
+ if (pc_debug > 3) {
+ int i;
+ printk(KERN_DEBUG "skb->data after untranslate:");
+ for (i = 0; i < 64; i++)
+ printk("%02x ", skb->data[i]);
+ printk("\n");
+ }
#endif
} /* end untranslate */
+
/*===========================================================================*/
/* Copy data from circular receive buffer to PC memory.
* dest = destination address in PC memory
* pkt_addr = source address in receive buffer
* len = length of packet to copy
*/
-static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int length)
-{
- int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1);
- if (wrap_bytes <= 0)
- {
- memcpy_fromio(dest,local->rmem + pkt_addr,length);
- }
- else /* Packet wrapped in circular buffer */
- {
- memcpy_fromio(dest,local->rmem+pkt_addr,length - wrap_bytes);
- memcpy_fromio(dest + length - wrap_bytes, local->rmem, wrap_bytes);
- }
- return length;
+static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr,
+ int length)
+{
+ int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1);
+ if (wrap_bytes <= 0) {
+ memcpy_fromio(dest, local->rmem + pkt_addr, length);
+ } else { /* Packet wrapped in circular buffer */
+
+ memcpy_fromio(dest, local->rmem + pkt_addr,
+ length - wrap_bytes);
+ memcpy_fromio(dest + length - wrap_bytes, local->rmem,
+ wrap_bytes);
+ }
+ return length;
}
+
/*===========================================================================*/
-static void release_frag_chain(ray_dev_t *local, struct rcs __iomem * prcs)
-{
- struct rcs __iomem *prcslink = prcs;
- int tmp = 17;
- unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index);
-
- while (tmp--) {
- writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
- if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
- DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex);
- break;
- }
- prcslink = rcs_base(local) + rcsindex;
- rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index);
- }
- writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
+static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs)
+{
+ struct rcs __iomem *prcslink = prcs;
+ int tmp = 17;
+ unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index);
+
+ while (tmp--) {
+ writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
+ if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
+ DEBUG(1, "ray_cs interrupt bad rcsindex = 0x%x\n",
+ rcsindex);
+ break;
+ }
+ prcslink = rcs_base(local) + rcsindex;
+ rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index);
+ }
+ writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
}
+
/*===========================================================================*/
static void authenticate(ray_dev_t *local)
{
- struct pcmcia_device *link = local->finder;
- DEBUG(0,"ray_cs Starting authentication.\n");
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs authenticate - device not present\n");
- return;
- }
-
- del_timer(&local->timer);
- if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
- local->timer.function = &join_net;
- }
- else {
- local->timer.function = &authenticate_timeout;
- }
- local->timer.expires = jiffies + HZ*2;
- local->timer.data = (long)local;
- add_timer(&local->timer);
- local->authentication_state = AWAITING_RESPONSE;
+ struct pcmcia_device *link = local->finder;
+ DEBUG(0, "ray_cs Starting authentication.\n");
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs authenticate - device not present\n");
+ return;
+ }
+
+ del_timer(&local->timer);
+ if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
+ local->timer.function = &join_net;
+ } else {
+ local->timer.function = &authenticate_timeout;
+ }
+ local->timer.expires = jiffies + HZ * 2;
+ local->timer.data = (long)local;
+ add_timer(&local->timer);
+ local->authentication_state = AWAITING_RESPONSE;
} /* end authenticate */
+
/*===========================================================================*/
static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
- unsigned int pkt_addr, int rx_len)
-{
- UCHAR buff[256];
- struct rx_msg *msg = (struct rx_msg *)buff;
-
- del_timer(&local->timer);
-
- copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
- /* if we are trying to get authenticated */
- if (local->sparm.b4.a_network_type == ADHOC) {
- DEBUG(1,"ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n", msg->var[0],msg->var[1],msg->var[2],msg->var[3],msg->var[4],msg->var[5]);
- if (msg->var[2] == 1) {
- DEBUG(0,"ray_cs Sending authentication response.\n");
- if (!build_auth_frame (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
- local->authentication_state = NEED_TO_AUTH;
- memcpy(local->auth_id, msg->mac.addr_2, ADDRLEN);
- }
- }
- }
- else /* Infrastructure network */
- {
- if (local->authentication_state == AWAITING_RESPONSE) {
- /* Verify authentication sequence #2 and success */
- if (msg->var[2] == 2) {
- if ((msg->var[3] | msg->var[4]) == 0) {
- DEBUG(1,"Authentication successful\n");
- local->card_status = CARD_AUTH_COMPLETE;
- associate(local);
- local->authentication_state = AUTHENTICATED;
- }
- else {
- DEBUG(0,"Authentication refused\n");
- local->card_status = CARD_AUTH_REFUSED;
- join_net((u_long)local);
- local->authentication_state = UNAUTHENTICATED;
- }
- }
- }
- }
+ unsigned int pkt_addr, int rx_len)
+{
+ UCHAR buff[256];
+ struct rx_msg *msg = (struct rx_msg *)buff;
+
+ del_timer(&local->timer);
+
+ copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
+ /* if we are trying to get authenticated */
+ if (local->sparm.b4.a_network_type == ADHOC) {
+ DEBUG(1, "ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n",
+ msg->var[0], msg->var[1], msg->var[2], msg->var[3],
+ msg->var[4], msg->var[5]);
+ if (msg->var[2] == 1) {
+ DEBUG(0, "ray_cs Sending authentication response.\n");
+ if (!build_auth_frame
+ (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
+ local->authentication_state = NEED_TO_AUTH;
+ memcpy(local->auth_id, msg->mac.addr_2,
+ ADDRLEN);
+ }
+ }
+ } else { /* Infrastructure network */
+
+ if (local->authentication_state == AWAITING_RESPONSE) {
+ /* Verify authentication sequence #2 and success */
+ if (msg->var[2] == 2) {
+ if ((msg->var[3] | msg->var[4]) == 0) {
+ DEBUG(1, "Authentication successful\n");
+ local->card_status = CARD_AUTH_COMPLETE;
+ associate(local);
+ local->authentication_state =
+ AUTHENTICATED;
+ } else {
+ DEBUG(0, "Authentication refused\n");
+ local->card_status = CARD_AUTH_REFUSED;
+ join_net((u_long) local);
+ local->authentication_state =
+ UNAUTHENTICATED;
+ }
+ }
+ }
+ }
} /* end rx_authenticate */
+
/*===========================================================================*/
static void associate(ray_dev_t *local)
{
- struct ccs __iomem *pccs;
- struct pcmcia_device *link = local->finder;
- struct net_device *dev = link->priv;
- int ccsindex;
- if (!(pcmcia_dev_present(link))) {
- DEBUG(2,"ray_cs associate - device not present\n");
- return;
- }
- /* If no tx buffers available, return*/
- if ((ccsindex = get_free_ccs(local)) < 0)
- {
+ struct ccs __iomem *pccs;
+ struct pcmcia_device *link = local->finder;
+ struct net_device *dev = link->priv;
+ int ccsindex;
+ if (!(pcmcia_dev_present(link))) {
+ DEBUG(2, "ray_cs associate - device not present\n");
+ return;
+ }
+ /* If no tx buffers available, return */
+ if ((ccsindex = get_free_ccs(local)) < 0) {
/* TBD should never be here but... what if we are? */
- DEBUG(1,"ray_cs associate - No free ccs\n");
- return;
- }
- DEBUG(1,"ray_cs Starting association with access point\n");
- pccs = ccs_base(local) + ccsindex;
- /* fill in the CCS */
- writeb(CCS_START_ASSOCIATION, &pccs->cmd);
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1,"ray_cs associate failed - ECF not ready for intr\n");
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
-
- del_timer(&local->timer);
- local->timer.expires = jiffies + HZ*2;
- local->timer.data = (long)local;
- local->timer.function = &join_net;
- add_timer(&local->timer);
- local->card_status = CARD_ASSOC_FAILED;
- return;
- }
- if (!sniffer) netif_start_queue(dev);
+ DEBUG(1, "ray_cs associate - No free ccs\n");
+ return;
+ }
+ DEBUG(1, "ray_cs Starting association with access point\n");
+ pccs = ccs_base(local) + ccsindex;
+ /* fill in the CCS */
+ writeb(CCS_START_ASSOCIATION, &pccs->cmd);
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(1, "ray_cs associate failed - ECF not ready for intr\n");
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+
+ del_timer(&local->timer);
+ local->timer.expires = jiffies + HZ * 2;
+ local->timer.data = (long)local;
+ local->timer.function = &join_net;
+ add_timer(&local->timer);
+ local->card_status = CARD_ASSOC_FAILED;
+ return;
+ }
+ if (!sniffer)
+ netif_start_queue(dev);
} /* end associate */
+
/*===========================================================================*/
-static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
- unsigned int pkt_addr, int rx_len)
+static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
+ unsigned int pkt_addr, int rx_len)
{
/* UCHAR buff[256];
struct rx_msg *msg = (struct rx_msg *)buff;
*/
- DEBUG(0,"Deauthentication frame received\n");
- local->authentication_state = UNAUTHENTICATED;
- /* Need to reauthenticate or rejoin depending on reason code */
+ DEBUG(0, "Deauthentication frame received\n");
+ local->authentication_state = UNAUTHENTICATED;
+ /* Need to reauthenticate or rejoin depending on reason code */
/* copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
*/
}
+
/*===========================================================================*/
static void clear_interrupt(ray_dev_t *local)
{
- writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET);
+ writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET);
}
+
/*===========================================================================*/
#ifdef CONFIG_PROC_FS
#define MAXDATA (PAGE_SIZE - 80)
static char *card_status[] = {
- "Card inserted - uninitialized", /* 0 */
- "Card not downloaded", /* 1 */
- "Waiting for download parameters", /* 2 */
- "Card doing acquisition", /* 3 */
- "Acquisition complete", /* 4 */
- "Authentication complete", /* 5 */
- "Association complete", /* 6 */
- "???", "???", "???", "???", /* 7 8 9 10 undefined */
- "Card init error", /* 11 */
- "Download parameters error", /* 12 */
- "???", /* 13 */
- "Acquisition failed", /* 14 */
- "Authentication refused", /* 15 */
- "Association failed" /* 16 */
+ "Card inserted - uninitialized", /* 0 */
+ "Card not downloaded", /* 1 */
+ "Waiting for download parameters", /* 2 */
+ "Card doing acquisition", /* 3 */
+ "Acquisition complete", /* 4 */
+ "Authentication complete", /* 5 */
+ "Association complete", /* 6 */
+ "???", "???", "???", "???", /* 7 8 9 10 undefined */
+ "Card init error", /* 11 */
+ "Download parameters error", /* 12 */
+ "???", /* 13 */
+ "Acquisition failed", /* 14 */
+ "Authentication refused", /* 15 */
+ "Association failed" /* 16 */
};
-static char *nettype[] = {"Adhoc", "Infra "};
-static char *framing[] = {"Encapsulation", "Translation"}
+static char *nettype[] = { "Adhoc", "Infra " };
+static char *framing[] = { "Encapsulation", "Translation" }
+
;
/*===========================================================================*/
static int ray_cs_proc_show(struct seq_file *m, void *v)
{
/* Print current values which are not available via other means
- * eg ifconfig
+ * eg ifconfig
*/
- int i;
- struct pcmcia_device *link;
- struct net_device *dev;
- ray_dev_t *local;
- UCHAR *p;
- struct freq_hop_element *pfh;
- UCHAR c[33];
-
- link = this_device;
- if (!link)
- return 0;
- dev = (struct net_device *)link->priv;
- if (!dev)
- return 0;
- local = netdev_priv(dev);
- if (!local)
- return 0;
-
- seq_puts(m, "Raylink Wireless LAN driver status\n");
- seq_printf(m, "%s\n", rcsid);
- /* build 4 does not report version, and field is 0x55 after memtest */
- seq_puts(m, "Firmware version = ");
- if (local->fw_ver == 0x55)
- seq_puts(m, "4 - Use dump_cis for more details\n");
- else
- seq_printf(m, "%2d.%02d.%02d\n",
- local->fw_ver, local->fw_bld, local->fw_var);
-
- for (i=0; i<32; i++) c[i] = local->sparm.b5.a_current_ess_id[i];
- c[32] = 0;
- seq_printf(m, "%s network ESSID = \"%s\"\n",
- nettype[local->sparm.b5.a_network_type], c);
-
- p = local->bss_id;
- seq_printf(m, "BSSID = %pM\n", p);
-
- seq_printf(m, "Country code = %d\n",
- local->sparm.b5.a_curr_country_code);
-
- i = local->card_status;
- if (i < 0) i = 10;
- if (i > 16) i = 10;
- seq_printf(m, "Card status = %s\n", card_status[i]);
-
- seq_printf(m, "Framing mode = %s\n",framing[translate]);
-
- seq_printf(m, "Last pkt signal lvl = %d\n", local->last_rsl);
-
- if (local->beacon_rxed) {
- /* Pull some fields out of last beacon received */
- seq_printf(m, "Beacon Interval = %d Kus\n",
- local->last_bcn.beacon_intvl[0]
- + 256 * local->last_bcn.beacon_intvl[1]);
-
- p = local->last_bcn.elements;
- if (p[0] == C_ESSID_ELEMENT_ID) p += p[1] + 2;
- else {
- seq_printf(m, "Parse beacon failed at essid element id = %d\n",p[0]);
- return 0;
- }
-
- if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
- seq_puts(m, "Supported rate codes = ");
- for (i=2; i<p[1] + 2; i++)
- seq_printf(m, "0x%02x ", p[i]);
- seq_putc(m, '\n');
- p += p[1] + 2;
- }
- else {
- seq_puts(m, "Parse beacon failed at rates element\n");
- return 0;
- }
-
- if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
- pfh = (struct freq_hop_element *)p;
- seq_printf(m, "Hop dwell = %d Kus\n",
- pfh->dwell_time[0] + 256 * pfh->dwell_time[1]);
- seq_printf(m, "Hop set = %d \n", pfh->hop_set);
- seq_printf(m, "Hop pattern = %d \n", pfh->hop_pattern);
- seq_printf(m, "Hop index = %d \n", pfh->hop_index);
- p += p[1] + 2;
- }
- else {
- seq_puts(m, "Parse beacon failed at FH param element\n");
- return 0;
+ int i;
+ struct pcmcia_device *link;
+ struct net_device *dev;
+ ray_dev_t *local;
+ UCHAR *p;
+ struct freq_hop_element *pfh;
+ UCHAR c[33];
+
+ link = this_device;
+ if (!link)
+ return 0;
+ dev = (struct net_device *)link->priv;
+ if (!dev)
+ return 0;
+ local = netdev_priv(dev);
+ if (!local)
+ return 0;
+
+ seq_puts(m, "Raylink Wireless LAN driver status\n");
+ seq_printf(m, "%s\n", rcsid);
+ /* build 4 does not report version, and field is 0x55 after memtest */
+ seq_puts(m, "Firmware version = ");
+ if (local->fw_ver == 0x55)
+ seq_puts(m, "4 - Use dump_cis for more details\n");
+ else
+ seq_printf(m, "%2d.%02d.%02d\n",
+ local->fw_ver, local->fw_bld, local->fw_var);
+
+ for (i = 0; i < 32; i++)
+ c[i] = local->sparm.b5.a_current_ess_id[i];
+ c[32] = 0;
+ seq_printf(m, "%s network ESSID = \"%s\"\n",
+ nettype[local->sparm.b5.a_network_type], c);
+
+ p = local->bss_id;
+ seq_printf(m, "BSSID = %pM\n", p);
+
+ seq_printf(m, "Country code = %d\n",
+ local->sparm.b5.a_curr_country_code);
+
+ i = local->card_status;
+ if (i < 0)
+ i = 10;
+ if (i > 16)
+ i = 10;
+ seq_printf(m, "Card status = %s\n", card_status[i]);
+
+ seq_printf(m, "Framing mode = %s\n", framing[translate]);
+
+ seq_printf(m, "Last pkt signal lvl = %d\n", local->last_rsl);
+
+ if (local->beacon_rxed) {
+ /* Pull some fields out of last beacon received */
+ seq_printf(m, "Beacon Interval = %d Kus\n",
+ local->last_bcn.beacon_intvl[0]
+ + 256 * local->last_bcn.beacon_intvl[1]);
+
+ p = local->last_bcn.elements;
+ if (p[0] == C_ESSID_ELEMENT_ID)
+ p += p[1] + 2;
+ else {
+ seq_printf(m,
+ "Parse beacon failed at essid element id = %d\n",
+ p[0]);
+ return 0;
+ }
+
+ if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
+ seq_puts(m, "Supported rate codes = ");
+ for (i = 2; i < p[1] + 2; i++)
+ seq_printf(m, "0x%02x ", p[i]);
+ seq_putc(m, '\n');
+ p += p[1] + 2;
+ } else {
+ seq_puts(m, "Parse beacon failed at rates element\n");
+ return 0;
+ }
+
+ if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
+ pfh = (struct freq_hop_element *)p;
+ seq_printf(m, "Hop dwell = %d Kus\n",
+ pfh->dwell_time[0] +
+ 256 * pfh->dwell_time[1]);
+ seq_printf(m, "Hop set = %d \n",
+ pfh->hop_set);
+ seq_printf(m, "Hop pattern = %d \n",
+ pfh->hop_pattern);
+ seq_printf(m, "Hop index = %d \n",
+ pfh->hop_index);
+ p += p[1] + 2;
+ } else {
+ seq_puts(m,
+ "Parse beacon failed at FH param element\n");
+ return 0;
+ }
+ } else {
+ seq_puts(m, "No beacons received\n");
}
- } else {
- seq_puts(m, "No beacons received\n");
- }
- return 0;
+ return 0;
}
static int ray_cs_proc_open(struct inode *inode, struct file *file)
@@ -2684,74 +2806,77 @@ static int ray_cs_proc_open(struct inode *inode, struct file *file)
}
static const struct file_operations ray_cs_proc_fops = {
- .owner = THIS_MODULE,
- .open = ray_cs_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
+ .owner = THIS_MODULE,
+ .open = ray_cs_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
#endif
/*===========================================================================*/
static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
{
- int addr;
- struct ccs __iomem *pccs;
- struct tx_msg __iomem *ptx;
- int ccsindex;
-
- /* If no tx buffers available, return */
- if ((ccsindex = get_free_tx_ccs(local)) < 0)
- {
- DEBUG(1,"ray_cs send authenticate - No free tx ccs\n");
- return -1;
- }
-
- pccs = ccs_base(local) + ccsindex;
-
- /* Address in card space */
- addr = TX_BUF_BASE + (ccsindex << 11);
- /* fill in the CCS */
- writeb(CCS_TX_REQUEST, &pccs->cmd);
- writeb(addr >> 8, pccs->var.tx_request.tx_data_ptr);
- writeb(0x20, pccs->var.tx_request.tx_data_ptr + 1);
- writeb(TX_AUTHENTICATE_LENGTH_MSB, pccs->var.tx_request.tx_data_length);
- writeb(TX_AUTHENTICATE_LENGTH_LSB,pccs->var.tx_request.tx_data_length + 1);
- writeb(0, &pccs->var.tx_request.pow_sav_mode);
-
- ptx = local->sram + addr;
- /* fill in the mac header */
- writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1);
- writeb(0, &ptx->mac.frame_ctl_2);
-
- memcpy_toio(ptx->mac.addr_1, dest, ADDRLEN);
- memcpy_toio(ptx->mac.addr_2, local->sparm.b4.a_mac_addr, ADDRLEN);
- memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
-
- /* Fill in msg body with protocol 00 00, sequence 01 00 ,status 00 00 */
- memset_io(ptx->var, 0, 6);
- writeb(auth_type & 0xff, ptx->var + 2);
-
- /* Interrupt the firmware to process the command */
- if (interrupt_ecf(local, ccsindex)) {
- DEBUG(1,"ray_cs send authentication request failed - ECF not ready for intr\n");
- writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
- return -1;
- }
- return 0;
+ int addr;
+ struct ccs __iomem *pccs;
+ struct tx_msg __iomem *ptx;
+ int ccsindex;
+
+ /* If no tx buffers available, return */
+ if ((ccsindex = get_free_tx_ccs(local)) < 0) {
+ DEBUG(1, "ray_cs send authenticate - No free tx ccs\n");
+ return -1;
+ }
+
+ pccs = ccs_base(local) + ccsindex;
+
+ /* Address in card space */
+ addr = TX_BUF_BASE + (ccsindex << 11);
+ /* fill in the CCS */
+ writeb(CCS_TX_REQUEST, &pccs->cmd);
+ writeb(addr >> 8, pccs->var.tx_request.tx_data_ptr);
+ writeb(0x20, pccs->var.tx_request.tx_data_ptr + 1);
+ writeb(TX_AUTHENTICATE_LENGTH_MSB, pccs->var.tx_request.tx_data_length);
+ writeb(TX_AUTHENTICATE_LENGTH_LSB,
+ pccs->var.tx_request.tx_data_length + 1);
+ writeb(0, &pccs->var.tx_request.pow_sav_mode);
+
+ ptx = local->sram + addr;
+ /* fill in the mac header */
+ writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1);
+ writeb(0, &ptx->mac.frame_ctl_2);
+
+ memcpy_toio(ptx->mac.addr_1, dest, ADDRLEN);
+ memcpy_toio(ptx->mac.addr_2, local->sparm.b4.a_mac_addr, ADDRLEN);
+ memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
+
+ /* Fill in msg body with protocol 00 00, sequence 01 00 ,status 00 00 */
+ memset_io(ptx->var, 0, 6);
+ writeb(auth_type & 0xff, ptx->var + 2);
+
+ /* Interrupt the firmware to process the command */
+ if (interrupt_ecf(local, ccsindex)) {
+ DEBUG(1,
+ "ray_cs send authentication request failed - ECF not ready for intr\n");
+ writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
+ return -1;
+ }
+ return 0;
} /* End build_auth_frame */
/*===========================================================================*/
#ifdef CONFIG_PROC_FS
static void raycs_write(const char *name, write_proc_t *w, void *data)
{
- struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
+ struct proc_dir_entry *entry =
+ create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
if (entry) {
entry->write_proc = w;
entry->data = data;
}
}
-static int write_essid(struct file *file, const char __user *buffer, unsigned long count, void *data)
+static int write_essid(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
{
static char proc_essid[33];
int len = count;
@@ -2765,7 +2890,8 @@ static int write_essid(struct file *file, const char __user *buffer, unsigned lo
return count;
}
-static int write_int(struct file *file, const char __user *buffer, unsigned long count, void *data)
+static int write_int(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
{
static char proc_number[10];
char *p;
@@ -2785,7 +2911,7 @@ static int write_int(struct file *file, const char __user *buffer, unsigned long
unsigned int c = *p - '0';
if (c > 9)
return -EINVAL;
- nr = nr*10 + c;
+ nr = nr * 10 + c;
p++;
} while (--len);
*(int *)data = nr;
@@ -2797,55 +2923,58 @@ static struct pcmcia_device_id ray_ids[] = {
PCMCIA_DEVICE_MANF_CARD(0x01a6, 0x0000),
PCMCIA_DEVICE_NULL,
};
+
MODULE_DEVICE_TABLE(pcmcia, ray_ids);
static struct pcmcia_driver ray_driver = {
- .owner = THIS_MODULE,
- .drv = {
- .name = "ray_cs",
- },
- .probe = ray_probe,
- .remove = ray_detach,
- .id_table = ray_ids,
- .suspend = ray_suspend,
- .resume = ray_resume,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = "ray_cs",
+ },
+ .probe = ray_probe,
+ .remove = ray_detach,
+ .id_table = ray_ids,
+ .suspend = ray_suspend,
+ .resume = ray_resume,
};
static int __init init_ray_cs(void)
{
- int rc;
-
- DEBUG(1, "%s\n", rcsid);
- rc = pcmcia_register_driver(&ray_driver);
- DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",rc);
+ int rc;
+
+ DEBUG(1, "%s\n", rcsid);
+ rc = pcmcia_register_driver(&ray_driver);
+ DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",
+ rc);
#ifdef CONFIG_PROC_FS
- proc_mkdir("driver/ray_cs", NULL);
+ proc_mkdir("driver/ray_cs", NULL);
- proc_create("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_fops);
- raycs_write("driver/ray_cs/essid", write_essid, NULL);
- raycs_write("driver/ray_cs/net_type", write_int, &net_type);
- raycs_write("driver/ray_cs/translate", write_int, &translate);
+ proc_create("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_fops);
+ raycs_write("driver/ray_cs/essid", write_essid, NULL);
+ raycs_write("driver/ray_cs/net_type", write_int, &net_type);
+ raycs_write("driver/ray_cs/translate", write_int, &translate);
#endif
- if (translate != 0) translate = 1;
- return 0;
+ if (translate != 0)
+ translate = 1;
+ return 0;
} /* init_ray_cs */
/*===========================================================================*/
static void __exit exit_ray_cs(void)
{
- DEBUG(0, "ray_cs: cleanup_module\n");
+ DEBUG(0, "ray_cs: cleanup_module\n");
#ifdef CONFIG_PROC_FS
- remove_proc_entry("driver/ray_cs/ray_cs", NULL);
- remove_proc_entry("driver/ray_cs/essid", NULL);
- remove_proc_entry("driver/ray_cs/net_type", NULL);
- remove_proc_entry("driver/ray_cs/translate", NULL);
- remove_proc_entry("driver/ray_cs", NULL);
+ remove_proc_entry("driver/ray_cs/ray_cs", NULL);
+ remove_proc_entry("driver/ray_cs/essid", NULL);
+ remove_proc_entry("driver/ray_cs/net_type", NULL);
+ remove_proc_entry("driver/ray_cs/translate", NULL);
+ remove_proc_entry("driver/ray_cs", NULL);
#endif
- pcmcia_unregister_driver(&ray_driver);
+ pcmcia_unregister_driver(&ray_driver);
} /* exit_ray_cs */
module_init(init_ray_cs);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index ed93ac41297f..db91db776508 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -90,44 +90,44 @@ MODULE_PARM_DESC(workaround_interval,
/* various RNDIS OID defs */
-#define OID_GEN_LINK_SPEED ccpu2(0x00010107)
-#define OID_GEN_RNDIS_CONFIG_PARAMETER ccpu2(0x0001021b)
-
-#define OID_GEN_XMIT_OK ccpu2(0x00020101)
-#define OID_GEN_RCV_OK ccpu2(0x00020102)
-#define OID_GEN_XMIT_ERROR ccpu2(0x00020103)
-#define OID_GEN_RCV_ERROR ccpu2(0x00020104)
-#define OID_GEN_RCV_NO_BUFFER ccpu2(0x00020105)
-
-#define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101)
-#define OID_802_3_CURRENT_ADDRESS ccpu2(0x01010102)
-#define OID_802_3_MULTICAST_LIST ccpu2(0x01010103)
-#define OID_802_3_MAXIMUM_LIST_SIZE ccpu2(0x01010104)
-
-#define OID_802_11_BSSID ccpu2(0x0d010101)
-#define OID_802_11_SSID ccpu2(0x0d010102)
-#define OID_802_11_INFRASTRUCTURE_MODE ccpu2(0x0d010108)
-#define OID_802_11_ADD_WEP ccpu2(0x0d010113)
-#define OID_802_11_REMOVE_WEP ccpu2(0x0d010114)
-#define OID_802_11_DISASSOCIATE ccpu2(0x0d010115)
-#define OID_802_11_AUTHENTICATION_MODE ccpu2(0x0d010118)
-#define OID_802_11_PRIVACY_FILTER ccpu2(0x0d010119)
-#define OID_802_11_BSSID_LIST_SCAN ccpu2(0x0d01011a)
-#define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b)
-#define OID_802_11_ADD_KEY ccpu2(0x0d01011d)
-#define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e)
-#define OID_802_11_ASSOCIATION_INFORMATION ccpu2(0x0d01011f)
-#define OID_802_11_PMKID ccpu2(0x0d010123)
-#define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203)
-#define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204)
-#define OID_802_11_TX_POWER_LEVEL ccpu2(0x0d010205)
-#define OID_802_11_RSSI ccpu2(0x0d010206)
-#define OID_802_11_RSSI_TRIGGER ccpu2(0x0d010207)
-#define OID_802_11_FRAGMENTATION_THRESHOLD ccpu2(0x0d010209)
-#define OID_802_11_RTS_THRESHOLD ccpu2(0x0d01020a)
-#define OID_802_11_SUPPORTED_RATES ccpu2(0x0d01020e)
-#define OID_802_11_CONFIGURATION ccpu2(0x0d010211)
-#define OID_802_11_BSSID_LIST ccpu2(0x0d010217)
+#define OID_GEN_LINK_SPEED cpu_to_le32(0x00010107)
+#define OID_GEN_RNDIS_CONFIG_PARAMETER cpu_to_le32(0x0001021b)
+
+#define OID_GEN_XMIT_OK cpu_to_le32(0x00020101)
+#define OID_GEN_RCV_OK cpu_to_le32(0x00020102)
+#define OID_GEN_XMIT_ERROR cpu_to_le32(0x00020103)
+#define OID_GEN_RCV_ERROR cpu_to_le32(0x00020104)
+#define OID_GEN_RCV_NO_BUFFER cpu_to_le32(0x00020105)
+
+#define OID_802_3_PERMANENT_ADDRESS cpu_to_le32(0x01010101)
+#define OID_802_3_CURRENT_ADDRESS cpu_to_le32(0x01010102)
+#define OID_802_3_MULTICAST_LIST cpu_to_le32(0x01010103)
+#define OID_802_3_MAXIMUM_LIST_SIZE cpu_to_le32(0x01010104)
+
+#define OID_802_11_BSSID cpu_to_le32(0x0d010101)
+#define OID_802_11_SSID cpu_to_le32(0x0d010102)
+#define OID_802_11_INFRASTRUCTURE_MODE cpu_to_le32(0x0d010108)
+#define OID_802_11_ADD_WEP cpu_to_le32(0x0d010113)
+#define OID_802_11_REMOVE_WEP cpu_to_le32(0x0d010114)
+#define OID_802_11_DISASSOCIATE cpu_to_le32(0x0d010115)
+#define OID_802_11_AUTHENTICATION_MODE cpu_to_le32(0x0d010118)
+#define OID_802_11_PRIVACY_FILTER cpu_to_le32(0x0d010119)
+#define OID_802_11_BSSID_LIST_SCAN cpu_to_le32(0x0d01011a)
+#define OID_802_11_ENCRYPTION_STATUS cpu_to_le32(0x0d01011b)
+#define OID_802_11_ADD_KEY cpu_to_le32(0x0d01011d)
+#define OID_802_11_REMOVE_KEY cpu_to_le32(0x0d01011e)
+#define OID_802_11_ASSOCIATION_INFORMATION cpu_to_le32(0x0d01011f)
+#define OID_802_11_PMKID cpu_to_le32(0x0d010123)
+#define OID_802_11_NETWORK_TYPES_SUPPORTED cpu_to_le32(0x0d010203)
+#define OID_802_11_NETWORK_TYPE_IN_USE cpu_to_le32(0x0d010204)
+#define OID_802_11_TX_POWER_LEVEL cpu_to_le32(0x0d010205)
+#define OID_802_11_RSSI cpu_to_le32(0x0d010206)
+#define OID_802_11_RSSI_TRIGGER cpu_to_le32(0x0d010207)
+#define OID_802_11_FRAGMENTATION_THRESHOLD cpu_to_le32(0x0d010209)
+#define OID_802_11_RTS_THRESHOLD cpu_to_le32(0x0d01020a)
+#define OID_802_11_SUPPORTED_RATES cpu_to_le32(0x0d01020e)
+#define OID_802_11_CONFIGURATION cpu_to_le32(0x0d010211)
+#define OID_802_11_BSSID_LIST cpu_to_le32(0x0d010217)
/* Typical noise/maximum signal level values taken from ndiswrapper iw_ndis.h */
@@ -144,8 +144,8 @@ MODULE_PARM_DESC(workaround_interval,
/* codes for "status" field of completion messages */
-#define RNDIS_STATUS_ADAPTER_NOT_READY ccpu2(0xc0010011)
-#define RNDIS_STATUS_ADAPTER_NOT_OPEN ccpu2(0xc0010012)
+#define RNDIS_STATUS_ADAPTER_NOT_READY cpu_to_le32(0xc0010011)
+#define RNDIS_STATUS_ADAPTER_NOT_OPEN cpu_to_le32(0xc0010012)
/* NDIS data structures. Taken from wpa_supplicant driver_ndis.c
@@ -369,9 +369,6 @@ struct rndis_wext_private {
};
-static const int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
- 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
-
static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 };
static const int bcm4320_power_output[4] = { 25, 50, 75, 100 };
@@ -445,7 +442,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
memset(u.get, 0, sizeof *u.get);
u.get->msg_type = RNDIS_MSG_QUERY;
- u.get->msg_len = ccpu2(sizeof *u.get);
+ u.get->msg_len = cpu_to_le32(sizeof *u.get);
u.get->oid = oid;
ret = rndis_command(dev, u.header, buflen);
@@ -494,8 +491,8 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
u.set->msg_len = cpu_to_le32(sizeof(*u.set) + len);
u.set->oid = oid;
u.set->len = cpu_to_le32(len);
- u.set->offset = ccpu2(sizeof(*u.set) - 8);
- u.set->handle = ccpu2(0);
+ u.set->offset = cpu_to_le32(sizeof(*u.set) - 8);
+ u.set->handle = cpu_to_le32(0);
memcpy(u.buf + sizeof(*u.set), data, len);
ret = rndis_command(dev, u.header, buflen);
@@ -640,8 +637,8 @@ static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq)
static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
{
if (freq->m < 1000 && freq->e == 0) {
- if (freq->m >= 1 && freq->m <= ARRAY_SIZE(freq_chan))
- *dsconfig = freq_chan[freq->m - 1] * 1000;
+ if (freq->m >= 1 && freq->m <= 14)
+ *dsconfig = ieee80211_dsss_chan_to_freq(freq->m) * 1000;
else
return -1;
} else {
@@ -1178,11 +1175,11 @@ static int rndis_iw_get_range(struct net_device *dev,
range->throughput = 11 * 1000 * 1000 / 2;
}
- range->num_channels = ARRAY_SIZE(freq_chan);
+ range->num_channels = 14;
- for (i = 0; i < ARRAY_SIZE(freq_chan) && i < IW_MAX_FREQUENCIES; i++) {
+ for (i = 0; (i < 14) && (i < IW_MAX_FREQUENCIES); i++) {
range->freq[i].i = i + 1;
- range->freq[i].m = freq_chan[i] * 100000;
+ range->freq[i].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
range->freq[i].e = 1;
}
range->num_frequency = i;
@@ -1633,7 +1630,7 @@ static int rndis_iw_set_scan(struct net_device *dev,
devdbg(usbdev, "SIOCSIWSCAN");
if (wrqu->data.flags == 0) {
- tmp = ccpu2(1);
+ tmp = cpu_to_le32(1);
ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
sizeof(tmp));
evt.data.flags = 0;
@@ -2431,7 +2428,7 @@ static void rndis_update_wireless_stats(struct work_struct *work)
/* Send scan OID. Use of both OIDs is required to get device
* working.
*/
- tmp = ccpu2(1);
+ tmp = cpu_to_le32(1);
rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
sizeof(tmp));
@@ -2527,6 +2524,17 @@ static int bcm4320_early_init(struct usbnet *usbdev)
return 0;
}
+/* same as rndis_netdev_ops but with local multicast handler */
+static const struct net_device_ops rndis_wext_netdev_ops = {
+ .ndo_open = usbnet_open,
+ .ndo_stop = usbnet_stop,
+ .ndo_start_xmit = usbnet_start_xmit,
+ .ndo_tx_timeout = usbnet_tx_timeout,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = rndis_wext_set_multicast_list,
+};
+
static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
{
@@ -2562,7 +2570,8 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
* rndis_host wants to avoid all OID as much as possible
* so do promisc/multicast handling in rndis_wext.
*/
- usbdev->net->set_multicast_list = rndis_wext_set_multicast_list;
+ usbdev->net->netdev_ops = &rndis_wext_netdev_ops;
+
tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp,
sizeof(tmp));
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 178b313293b4..bfc5d9cf716e 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -97,10 +97,11 @@ config RT2X00_LIB_CRYPTO
config RT2X00_LIB_RFKILL
boolean
- default y if (RT2X00_LIB=y && RFKILL=y) || (RT2X00_LIB=m && RFKILL!=n)
+ default y if (RT2X00_LIB=y && INPUT=y) || (RT2X00_LIB=m && INPUT!=n)
+ select INPUT_POLLDEV
-comment "rt2x00 rfkill support disabled due to modularized RFKILL and built-in rt2x00"
- depends on RT2X00_LIB=y && RFKILL=m
+comment "rt2x00 rfkill support disabled due to modularized INPUT and built-in rt2x00"
+ depends on RT2X00_LIB=y && INPUT=m
config RT2X00_LIB_LEDS
boolean
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile
index 917cb4f3b038..f22d808d8c51 100644
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile
@@ -2,6 +2,7 @@ rt2x00lib-y += rt2x00dev.o
rt2x00lib-y += rt2x00mac.o
rt2x00lib-y += rt2x00config.o
rt2x00lib-y += rt2x00queue.o
+rt2x00lib-y += rt2x00link.o
rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) += rt2x00debug.o
rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO) += rt2x00crypto.o
rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 6a977679124d..0f08773328c6 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -114,9 +114,6 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
- if (!word)
- return;
-
mutex_lock(&rt2x00dev->csr_mutex);
/*
@@ -524,6 +521,32 @@ static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, CSR12, reg);
}
+static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf)
+{
+ enum dev_state state =
+ (libconf->conf->flags & IEEE80211_CONF_PS) ?
+ STATE_SLEEP : STATE_AWAKE;
+ u32 reg;
+
+ if (state == STATE_SLEEP) {
+ rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
+ rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
+ (libconf->conf->beacon_int - 20) * 16);
+ rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
+ libconf->conf->listen_interval - 1);
+
+ /* We must first disable autowake before it can be enabled */
+ rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
+ rt2x00pci_register_write(rt2x00dev, CSR20, reg);
+
+ rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
+ rt2x00pci_register_write(rt2x00dev, CSR20, reg);
+ }
+
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+}
+
static void rt2400pci_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int flags)
@@ -537,6 +560,8 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev,
rt2400pci_config_retry_limit(rt2x00dev, libconf);
if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
rt2400pci_config_duration(rt2x00dev, libconf);
+ if (flags & IEEE80211_CONF_CHANGE_PS)
+ rt2400pci_config_ps(rt2x00dev, libconf);
}
static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev,
@@ -572,35 +597,37 @@ static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = bbp;
}
-static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static inline void rt2400pci_set_vgc(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, u8 vgc_level)
{
- rt2400pci_bbp_write(rt2x00dev, 13, 0x08);
- rt2x00dev->link.vgc_level = 0x08;
+ rt2400pci_bbp_write(rt2x00dev, 13, vgc_level);
+ qual->vgc_level = vgc_level;
+ qual->vgc_level_reg = vgc_level;
}
-static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
- u8 reg;
+ rt2400pci_set_vgc(rt2x00dev, qual, 0x08);
+}
+static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, const u32 count)
+{
/*
* The link tuner should not run longer then 60 seconds,
* and should run once every 2 seconds.
*/
- if (rt2x00dev->link.count > 60 || !(rt2x00dev->link.count & 1))
+ if (count > 60 || !(count & 1))
return;
/*
* Base r13 link tuning on the false cca count.
*/
- rt2400pci_bbp_read(rt2x00dev, 13, &reg);
-
- if (rt2x00dev->link.qual.false_cca > 512 && reg < 0x20) {
- rt2400pci_bbp_write(rt2x00dev, 13, ++reg);
- rt2x00dev->link.vgc_level = reg;
- } else if (rt2x00dev->link.qual.false_cca < 100 && reg > 0x08) {
- rt2400pci_bbp_write(rt2x00dev, 13, --reg);
- rt2x00dev->link.vgc_level = reg;
- }
+ if ((qual->false_cca > 512) && (qual->vgc_level < 0x20))
+ rt2400pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level);
+ else if ((qual->false_cca < 100) && (qual->vgc_level > 0x08))
+ rt2400pci_set_vgc(rt2x00dev, qual, --qual->vgc_level);
}
/*
@@ -904,21 +931,10 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev)
static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev)
{
- u32 reg;
-
- rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
-
- /*
- * Disable synchronisation.
- */
- rt2x00pci_register_write(rt2x00dev, CSR14, 0);
-
/*
- * Cancel RX and TX.
+ * Disable power
*/
- rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
- rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
}
static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
@@ -1115,6 +1131,20 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
}
+static void rt2400pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid)
+{
+ u32 reg;
+
+ if (qid == QID_BEACON) {
+ rt2x00pci_register_write(rt2x00dev, CSR14, 0);
+ } else {
+ rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+ rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ }
+}
+
/*
* RX control handlers
*/
@@ -1365,7 +1395,9 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
- if (value == LED_MODE_TXRX_ACTIVITY)
+ if (value == LED_MODE_TXRX_ACTIVITY ||
+ value == LED_MODE_DEFAULT ||
+ value == LED_MODE_ASUS)
rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
LED_TYPE_ACTIVITY);
#endif /* CONFIG_RT2X00_LIB_LEDS */
@@ -1419,7 +1451,9 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
* Initialize all hw fields.
*/
rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK;
rt2x00dev->hw->extra_tx_headroom = 0;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
@@ -1572,6 +1606,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
.write_tx_data = rt2x00pci_write_tx_data,
.write_beacon = rt2400pci_write_beacon,
.kick_tx_queue = rt2400pci_kick_tx_queue,
+ .kill_tx_queue = rt2400pci_kill_tx_queue,
.fill_rxdone = rt2400pci_fill_rxdone,
.config_filter = rt2400pci_config_filter,
.config_intf = rt2400pci_config_intf,
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index 9aefda4ab3c2..ec3b004ddc3c 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -48,8 +48,8 @@
#define EEPROM_SIZE 0x0100
#define BBP_BASE 0x0000
#define BBP_SIZE 0x0020
-#define RF_BASE 0x0000
-#define RF_SIZE 0x0010
+#define RF_BASE 0x0004
+#define RF_SIZE 0x000c
/*
* Number of TX queues.
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index d3bc218ec85c..276a8232aaa0 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -114,9 +114,6 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
- if (!word)
- return;
-
mutex_lock(&rt2x00dev->csr_mutex);
/*
@@ -573,6 +570,32 @@ static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, CSR12, reg);
}
+static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf)
+{
+ enum dev_state state =
+ (libconf->conf->flags & IEEE80211_CONF_PS) ?
+ STATE_SLEEP : STATE_AWAKE;
+ u32 reg;
+
+ if (state == STATE_SLEEP) {
+ rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
+ rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
+ (libconf->conf->beacon_int - 20) * 16);
+ rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
+ libconf->conf->listen_interval - 1);
+
+ /* We must first disable autowake before it can be enabled */
+ rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 0);
+ rt2x00pci_register_write(rt2x00dev, CSR20, reg);
+
+ rt2x00_set_field32(&reg, CSR20_AUTOWAKE, 1);
+ rt2x00pci_register_write(rt2x00dev, CSR20, reg);
+ }
+
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+}
+
static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int flags)
@@ -588,6 +611,8 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
rt2500pci_config_retry_limit(rt2x00dev, libconf);
if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
rt2500pci_config_duration(rt2x00dev, libconf);
+ if (flags & IEEE80211_CONF_CHANGE_PS)
+ rt2500pci_config_ps(rt2x00dev, libconf);
}
/*
@@ -611,29 +636,33 @@ static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
}
-static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, u8 vgc_level)
{
- rt2500pci_bbp_write(rt2x00dev, 17, 0x48);
- rt2x00dev->link.vgc_level = 0x48;
+ if (qual->vgc_level_reg != vgc_level) {
+ rt2500pci_bbp_write(rt2x00dev, 17, vgc_level);
+ qual->vgc_level_reg = vgc_level;
+ }
}
-static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
- int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
- u8 r17;
+ rt2500pci_set_vgc(rt2x00dev, qual, 0x48);
+}
+static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, const u32 count)
+{
/*
* To prevent collisions with MAC ASIC on chipsets
* up to version C the link tuning should halt after 20
* seconds while being associated.
*/
if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
- rt2x00dev->intf_associated &&
- rt2x00dev->link.count > 20)
+ rt2x00dev->intf_associated && count > 20)
return;
- rt2500pci_bbp_read(rt2x00dev, 17, &r17);
-
/*
* Chipset versions C and lower should directly continue
* to the dynamic CCA tuning. Chipset version D and higher
@@ -649,29 +678,25 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* then corrupt the R17 tuning. To remidy this the tuning should
* be stopped (While making sure the R17 value will not exceed limits)
*/
- if (rssi < -80 && rt2x00dev->link.count > 20) {
- if (r17 >= 0x41) {
- r17 = rt2x00dev->link.vgc_level;
- rt2500pci_bbp_write(rt2x00dev, 17, r17);
- }
+ if (qual->rssi < -80 && count > 20) {
+ if (qual->vgc_level_reg >= 0x41)
+ rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level);
return;
}
/*
* Special big-R17 for short distance
*/
- if (rssi >= -58) {
- if (r17 != 0x50)
- rt2500pci_bbp_write(rt2x00dev, 17, 0x50);
+ if (qual->rssi >= -58) {
+ rt2500pci_set_vgc(rt2x00dev, qual, 0x50);
return;
}
/*
* Special mid-R17 for middle distance
*/
- if (rssi >= -74) {
- if (r17 != 0x41)
- rt2500pci_bbp_write(rt2x00dev, 17, 0x41);
+ if (qual->rssi >= -74) {
+ rt2500pci_set_vgc(rt2x00dev, qual, 0x41);
return;
}
@@ -679,8 +704,8 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* Leave short or middle distance condition, restore r17
* to the dynamic tuning range.
*/
- if (r17 >= 0x41) {
- rt2500pci_bbp_write(rt2x00dev, 17, rt2x00dev->link.vgc_level);
+ if (qual->vgc_level_reg >= 0x41) {
+ rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level);
return;
}
@@ -690,12 +715,12 @@ dynamic_cca_tune:
* R17 is inside the dynamic tuning range,
* start tuning the link based on the false cca counter.
*/
- if (rt2x00dev->link.qual.false_cca > 512 && r17 < 0x40) {
- rt2500pci_bbp_write(rt2x00dev, 17, ++r17);
- rt2x00dev->link.vgc_level = r17;
- } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > 0x32) {
- rt2500pci_bbp_write(rt2x00dev, 17, --r17);
- rt2x00dev->link.vgc_level = r17;
+ if (qual->false_cca > 512 && qual->vgc_level_reg < 0x40) {
+ rt2500pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level_reg);
+ qual->vgc_level = qual->vgc_level_reg;
+ } else if (qual->false_cca < 100 && qual->vgc_level_reg > 0x32) {
+ rt2500pci_set_vgc(rt2x00dev, qual, --qual->vgc_level_reg);
+ qual->vgc_level = qual->vgc_level_reg;
}
}
@@ -1065,21 +1090,10 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev)
static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev)
{
- u32 reg;
-
- rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
-
- /*
- * Disable synchronisation.
- */
- rt2x00pci_register_write(rt2x00dev, CSR14, 0);
-
/*
- * Cancel RX and TX.
+ * Disable power
*/
- rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
- rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
- rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0);
}
static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev,
@@ -1205,7 +1219,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_OFDM,
- test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
+ (txdesc->rate_mode == RATE_MODE_OFDM));
rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1);
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
@@ -1275,6 +1289,20 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
}
+static void rt2500pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid)
+{
+ u32 reg;
+
+ if (qid == QID_BEACON) {
+ rt2x00pci_register_write(rt2x00dev, CSR14, 0);
+ } else {
+ rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
+ rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
+ rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
+ }
+}
+
/*
* RX control handlers
*/
@@ -1524,7 +1552,9 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
- if (value == LED_MODE_TXRX_ACTIVITY)
+ if (value == LED_MODE_TXRX_ACTIVITY ||
+ value == LED_MODE_DEFAULT ||
+ value == LED_MODE_ASUS)
rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
LED_TYPE_ACTIVITY);
#endif /* CONFIG_RT2X00_LIB_LEDS */
@@ -1721,7 +1751,9 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
* Initialize all hw fields.
*/
rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK;
rt2x00dev->hw->extra_tx_headroom = 0;
@@ -1873,6 +1905,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
.write_tx_data = rt2x00pci_write_tx_data,
.write_beacon = rt2500pci_write_beacon,
.kick_tx_queue = rt2500pci_kick_tx_queue,
+ .kill_tx_queue = rt2500pci_kill_tx_queue,
.fill_rxdone = rt2500pci_fill_rxdone,
.config_filter = rt2500pci_config_filter,
.config_intf = rt2500pci_config_intf,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index e135247f7f89..ce2f065c7486 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -59,8 +59,8 @@
#define EEPROM_SIZE 0x0200
#define BBP_BASE 0x0000
#define BBP_SIZE 0x0040
-#define RF_BASE 0x0000
-#define RF_SIZE 0x0014
+#define RF_BASE 0x0004
+#define RF_SIZE 0x0010
/*
* Number of TX queues.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 3e2ac2bbb12f..9e630e70fc97 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -204,9 +204,6 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
{
u16 reg;
- if (!word)
- return;
-
mutex_lock(&rt2x00dev->csr_mutex);
/*
@@ -280,6 +277,18 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = {
};
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+ u16 reg;
+
+ rt2500usb_register_read(rt2x00dev, MAC_CSR19, &reg);
+ return rt2x00_get_field32(reg, MAC_CSR19_BIT7);
+}
+#else
+#define rt2500usb_rfkill_poll NULL
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
#ifdef CONFIG_RT2X00_LIB_LEDS
static void rt2500usb_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
@@ -634,6 +643,32 @@ static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev,
rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
}
+static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf)
+{
+ enum dev_state state =
+ (libconf->conf->flags & IEEE80211_CONF_PS) ?
+ STATE_SLEEP : STATE_AWAKE;
+ u16 reg;
+
+ if (state == STATE_SLEEP) {
+ rt2500usb_register_read(rt2x00dev, MAC_CSR18, &reg);
+ rt2x00_set_field16(&reg, MAC_CSR18_DELAY_AFTER_BEACON,
+ libconf->conf->beacon_int - 20);
+ rt2x00_set_field16(&reg, MAC_CSR18_BEACONS_BEFORE_WAKEUP,
+ libconf->conf->listen_interval - 1);
+
+ /* We must first disable autowake before it can be enabled */
+ rt2x00_set_field16(&reg, MAC_CSR18_AUTO_WAKE, 0);
+ rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg);
+
+ rt2x00_set_field16(&reg, MAC_CSR18_AUTO_WAKE, 1);
+ rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg);
+ }
+
+ rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+}
+
static void rt2500usb_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int flags)
@@ -647,6 +682,8 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev,
libconf->conf->power_level);
if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
rt2500usb_config_duration(rt2x00dev, libconf);
+ if (flags & IEEE80211_CONF_CHANGE_PS)
+ rt2500usb_config_ps(rt2x00dev, libconf);
}
/*
@@ -670,7 +707,8 @@ static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR);
}
-static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
u16 eeprom;
u16 value;
@@ -691,7 +729,7 @@ static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
value = rt2x00_get_field16(eeprom, EEPROM_BBPTUNE_VGCUPPER);
rt2500usb_bbp_write(rt2x00dev, 17, value);
- rt2x00dev->link.vgc_level = value;
+ qual->vgc_level = value;
}
/*
@@ -1176,7 +1214,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_OFDM,
- test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
+ (txdesc->rate_mode == RATE_MODE_OFDM));
rt2x00_set_field32(&word, TXD_W0_NEW_SEQ,
test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
@@ -1562,12 +1600,22 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
- if (value == LED_MODE_TXRX_ACTIVITY)
+ if (value == LED_MODE_TXRX_ACTIVITY ||
+ value == LED_MODE_DEFAULT ||
+ value == LED_MODE_ASUS)
rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_qual,
LED_TYPE_ACTIVITY);
#endif /* CONFIG_RT2X00_LIB_LEDS */
/*
+ * Detect if this device has an hardware controlled radio.
+ */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
+ __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
+ /*
* Check if the BBP tuning should be disabled.
*/
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
@@ -1752,7 +1800,9 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
rt2x00dev->hw->flags =
IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK;
rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
@@ -1839,7 +1889,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
if (!modparam_nohwcrypt) {
__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
- __set_bit(CONFIG_CRYPTO_COPY_IV, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags);
}
__set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags);
@@ -1873,6 +1923,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
.uninitialize = rt2x00usb_uninitialize,
.clear_entry = rt2x00usb_clear_entry,
.set_device_state = rt2500usb_set_device_state,
+ .rfkill_poll = rt2500usb_rfkill_poll,
.link_stats = rt2500usb_link_stats,
.reset_tuner = rt2500usb_reset_tuner,
.link_tuner = rt2500usb_link_tuner,
@@ -1881,6 +1932,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
.write_beacon = rt2500usb_write_beacon,
.get_tx_data_len = rt2500usb_get_tx_data_len,
.kick_tx_queue = rt2500usb_kick_tx_queue,
+ .kill_tx_queue = rt2x00usb_kill_tx_queue,
.fill_rxdone = rt2500usb_fill_rxdone,
.config_shared_key = rt2500usb_config_key,
.config_pairwise_key = rt2500usb_config_key,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index 4347dfdabcd4..5bc46fe72179 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -59,8 +59,8 @@
#define EEPROM_SIZE 0x006a
#define BBP_BASE 0x0000
#define BBP_SIZE 0x0060
-#define RF_BASE 0x0000
-#define RF_SIZE 0x0014
+#define RF_BASE 0x0004
+#define RF_SIZE 0x0010
/*
* Number of TX queues.
@@ -189,6 +189,14 @@
* MAC_CSR19: GPIO control register.
*/
#define MAC_CSR19 0x0426
+#define MAC_CSR19_BIT0 FIELD32(0x0001)
+#define MAC_CSR19_BIT1 FIELD32(0x0002)
+#define MAC_CSR19_BIT2 FIELD32(0x0004)
+#define MAC_CSR19_BIT3 FIELD32(0x0008)
+#define MAC_CSR19_BIT4 FIELD32(0x0010)
+#define MAC_CSR19_BIT5 FIELD32(0x0020)
+#define MAC_CSR19_BIT6 FIELD32(0x0040)
+#define MAC_CSR19_BIT7 FIELD32(0x0080)
/*
* MAC_CSR20: LED control register.
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 39ecf3b82ca1..84bd6f19acb0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -33,6 +33,7 @@
#include <linux/leds.h>
#include <linux/mutex.h>
#include <linux/etherdevice.h>
+#include <linux/input-polldev.h>
#include <net/mac80211.h>
@@ -44,7 +45,7 @@
/*
* Module information.
*/
-#define DRV_VERSION "2.2.3"
+#define DRV_VERSION "2.3.0"
#define DRV_PROJECT "http://rt2x00.serialmonkey.com"
/*
@@ -177,52 +178,41 @@ struct antenna_setup {
*/
struct link_qual {
/*
- * Statistics required for Link tuning.
- * For the average RSSI value we use the "Walking average" approach.
- * When adding RSSI to the average value the following calculation
- * is needed:
- *
- * avg_rssi = ((avg_rssi * 7) + rssi) / 8;
- *
- * The advantage of this approach is that we only need 1 variable
- * to store the average in (No need for a count and a total).
- * But more importantly, normal average values will over time
- * move less and less towards newly added values this results
- * that with link tuning, the device can have a very good RSSI
- * for a few minutes but when the device is moved away from the AP
- * the average will not decrease fast enough to compensate.
- * The walking average compensates this and will move towards
- * the new values correctly allowing a effective link tuning.
+ * Statistics required for Link tuning by driver
+ * The rssi value is provided by rt2x00lib during the
+ * link_tuner() callback function.
+ * The false_cca field is filled during the link_stats()
+ * callback function and could be used during the
+ * link_tuner() callback function.
*/
- int avg_rssi;
+ int rssi;
int false_cca;
/*
- * Statistics required for Signal quality calculation.
- * For calculating the Signal quality we have to determine
- * the total number of success and failed RX and TX frames.
- * After that we also use the average RSSI value to help
- * determining the signal quality.
- * For the calculation we will use the following algorithm:
- *
- * rssi_percentage = (avg_rssi * 100) / rssi_offset
- * rx_percentage = (rx_success * 100) / rx_total
- * tx_percentage = (tx_success * 100) / tx_total
- * avg_signal = ((WEIGHT_RSSI * avg_rssi) +
- * (WEIGHT_TX * tx_percentage) +
- * (WEIGHT_RX * rx_percentage)) / 100
+ * VGC levels
+ * Hardware driver will tune the VGC level during each call
+ * to the link_tuner() callback function. This vgc_level is
+ * is determined based on the link quality statistics like
+ * average RSSI and the false CCA count.
*
- * This value should then be checked to not be greated then 100.
+ * In some cases the drivers need to differentiate between
+ * the currently "desired" VGC level and the level configured
+ * in the hardware. The latter is important to reduce the
+ * number of BBP register reads to reduce register access
+ * overhead. For this reason we store both values here.
+ */
+ u8 vgc_level;
+ u8 vgc_level_reg;
+
+ /*
+ * Statistics required for Signal quality calculation.
+ * These fields might be changed during the link_stats()
+ * callback function.
*/
- int rx_percentage;
int rx_success;
int rx_failed;
- int tx_percentage;
int tx_success;
int tx_failed;
-#define WEIGHT_RSSI 20
-#define WEIGHT_RX 40
-#define WEIGHT_TX 40
};
/*
@@ -286,9 +276,16 @@ struct link {
struct link_ant ant;
/*
- * Active VGC level
+ * Currently active average RSSI value
*/
- int vgc_level;
+ int avg_rssi;
+
+ /*
+ * Currently precalculated percentages of successful
+ * TX and RX frames.
+ */
+ int rx_percentage;
+ int tx_percentage;
/*
* Work structure for scheduling periodic link tuning.
@@ -297,55 +294,6 @@ struct link {
};
/*
- * Small helper macro to work with moving/walking averages.
- */
-#define MOVING_AVERAGE(__avg, __val, __samples) \
- ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) )
-
-/*
- * When we lack RSSI information return something less then -80 to
- * tell the driver to tune the device to maximum sensitivity.
- */
-#define DEFAULT_RSSI ( -128 )
-
-/*
- * Link quality access functions.
- */
-static inline int rt2x00_get_link_rssi(struct link *link)
-{
- if (link->qual.avg_rssi && link->qual.rx_success)
- return link->qual.avg_rssi;
- return DEFAULT_RSSI;
-}
-
-static inline int rt2x00_get_link_ant_rssi(struct link *link)
-{
- if (link->ant.rssi_ant && link->qual.rx_success)
- return link->ant.rssi_ant;
- return DEFAULT_RSSI;
-}
-
-static inline void rt2x00_reset_link_ant_rssi(struct link *link)
-{
- link->ant.rssi_ant = 0;
-}
-
-static inline int rt2x00_get_link_ant_rssi_history(struct link *link,
- enum antenna ant)
-{
- if (link->ant.rssi_history[ant - ANTENNA_A])
- return link->ant.rssi_history[ant - ANTENNA_A];
- return DEFAULT_RSSI;
-}
-
-static inline int rt2x00_update_ant_rssi(struct link *link, int rssi)
-{
- int old_rssi = link->ant.rssi_history[link->ant.active.rx - ANTENNA_A];
- link->ant.rssi_history[link->ant.active.rx - ANTENNA_A] = rssi;
- return old_rssi;
-}
-
-/*
* Interface structure
* Per interface configuration details, this structure
* is allocated as the private data for ieee80211_vif.
@@ -448,7 +396,7 @@ struct rt2x00lib_erp {
int ack_timeout;
int ack_consume_time;
- u64 basic_rates;
+ u32 basic_rates;
int slot_time;
@@ -520,9 +468,10 @@ struct rt2x00lib_ops {
*/
int (*probe_hw) (struct rt2x00_dev *rt2x00dev);
char *(*get_firmware_name) (struct rt2x00_dev *rt2x00dev);
- u16 (*get_firmware_crc) (const void *data, const size_t len);
- int (*load_firmware) (struct rt2x00_dev *rt2x00dev, const void *data,
- const size_t len);
+ int (*check_firmware) (struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len);
+ int (*load_firmware) (struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len);
/*
* Device initialization/deinitialization handlers.
@@ -544,8 +493,10 @@ struct rt2x00lib_ops {
int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev);
void (*link_stats) (struct rt2x00_dev *rt2x00dev,
struct link_qual *qual);
- void (*reset_tuner) (struct rt2x00_dev *rt2x00dev);
- void (*link_tuner) (struct rt2x00_dev *rt2x00dev);
+ void (*reset_tuner) (struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual);
+ void (*link_tuner) (struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, const u32 count);
/*
* TX control handlers
@@ -558,6 +509,8 @@ struct rt2x00lib_ops {
int (*get_tx_data_len) (struct queue_entry *entry);
void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
const enum data_queue_qid queue);
+ void (*kill_tx_queue) (struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid queue);
/*
* RX control handlers
@@ -625,7 +578,6 @@ enum rt2x00_flags {
DEVICE_STATE_REGISTERED_HW,
DEVICE_STATE_INITIALIZED,
DEVICE_STATE_STARTED,
- DEVICE_STATE_STARTED_SUSPEND,
DEVICE_STATE_ENABLED_RADIO,
DEVICE_STATE_DISABLED_RADIO_HW,
@@ -637,6 +589,7 @@ enum rt2x00_flags {
DRIVER_REQUIRE_ATIM_QUEUE,
DRIVER_REQUIRE_SCHEDULED,
DRIVER_REQUIRE_DMA,
+ DRIVER_REQUIRE_COPY_IV,
/*
* Driver features
@@ -653,7 +606,6 @@ enum rt2x00_flags {
CONFIG_EXTERNAL_LNA_BG,
CONFIG_DOUBLE_ANTENNA,
CONFIG_DISABLE_LINK_TUNING,
- CONFIG_CRYPTO_COPY_IV,
};
/*
@@ -689,8 +641,8 @@ struct rt2x00_dev {
unsigned long rfkill_state;
#define RFKILL_STATE_ALLOCATED 1
#define RFKILL_STATE_REGISTERED 2
- struct rfkill *rfkill;
- struct delayed_work rfkill_work;
+#define RFKILL_STATE_BLOCKED 3
+ struct input_polled_dev *rfkill_poll_dev;
#endif /* CONFIG_RT2X00_LIB_RFKILL */
/*
@@ -918,7 +870,7 @@ static inline char rt2x00_rf(const struct rt2x00_chip *chipset, const u16 chip)
return (chipset->rf == chip);
}
-static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset)
+static inline u32 rt2x00_rev(const struct rt2x00_chip *chipset)
{
return chipset->rev;
}
@@ -982,7 +934,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
int mc_count, struct dev_addr_list *mc_list);
#ifdef CONFIG_RT2X00_LIB_CRYPTO
int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key);
#else
#define rt2x00mac_set_key NULL
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index e66fb316cd61..9c2f5517af2a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -32,7 +32,7 @@
void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf,
enum nl80211_iftype type,
- u8 *mac, u8 *bssid)
+ const u8 *mac, const u8 *bssid)
{
struct rt2x00intf_conf conf;
unsigned int flags = 0;
@@ -42,6 +42,8 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
switch (type) {
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_AP:
+ case NL80211_IFTYPE_MESH_POINT:
+ case NL80211_IFTYPE_WDS:
conf.sync = TSF_SYNC_BEACON;
break;
case NL80211_IFTYPE_STATION:
@@ -152,8 +154,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
*/
rt2x00dev->ops->lib->config_ant(rt2x00dev, ant);
- rt2x00lib_reset_link_tuner(rt2x00dev);
- rt2x00_reset_link_ant_rssi(&rt2x00dev->link);
+ rt2x00link_reset_tuner(rt2x00dev, true);
memcpy(active, ant, sizeof(*ant));
@@ -191,7 +192,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
* which means we need to reset the link tuner.
*/
if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL)
- rt2x00lib_reset_link_tuner(rt2x00dev);
+ rt2x00link_reset_tuner(rt2x00dev, false);
rt2x00dev->curr_band = conf->channel->band;
rt2x00dev->tx_power = conf->power_level;
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index aee9cba13eb3..0b41845d9543 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -49,9 +49,14 @@ enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key)
void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
+ if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) ||
+ !hw_key || entry->skb->do_not_encrypt)
+ return;
+
__set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags);
txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key);
@@ -69,11 +74,17 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
__set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags);
}
-unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info)
+unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
+ struct sk_buff *skb)
{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_key_conf *key = tx_info->control.hw_key;
unsigned int overhead = 0;
+ if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) ||
+ !key || skb->do_not_encrypt)
+ return overhead;
+
/*
* Extend frame length to include IV/EIV/ICV/MMIC,
* note that these lengths should only be added when
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 54dd10060bf1..07d378ef0b46 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -130,9 +130,11 @@ struct rt2x00debug_intf {
};
void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
- enum cipher cipher, enum rx_crypto status)
+ struct rxdone_entry_desc *rxdesc)
{
struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
+ enum cipher cipher = rxdesc->cipher;
+ enum rx_crypto status = rxdesc->cipher_status;
if (cipher == CIPHER_TKIP_NO_MIC)
cipher = CIPHER_TKIP;
@@ -433,11 +435,12 @@ static ssize_t rt2x00debug_read_##__name(struct file *file, \
if (index >= debug->__name.word_count) \
return -EINVAL; \
\
+ index += (debug->__name.word_base / \
+ debug->__name.word_size); \
+ \
if (debug->__name.flags & RT2X00DEBUGFS_OFFSET) \
index *= debug->__name.word_size; \
\
- index += debug->__name.word_base; \
- \
debug->__name.read(intf->rt2x00dev, index, &value); \
\
size = sprintf(line, __format, value); \
@@ -474,11 +477,12 @@ static ssize_t rt2x00debug_write_##__name(struct file *file, \
size = strlen(line); \
value = simple_strtoul(line, NULL, 0); \
\
+ index += (debug->__name.word_base / \
+ debug->__name.word_size); \
+ \
if (debug->__name.flags & RT2X00DEBUGFS_OFFSET) \
index *= debug->__name.word_size; \
\
- index += debug->__name.word_base; \
- \
debug->__name.write(intf->rt2x00dev, index, value); \
\
*offset += size; \
@@ -543,9 +547,9 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name,
return NULL;
blob->data = data;
- data += sprintf(data, "driver: %s\n", intf->rt2x00dev->ops->name);
- data += sprintf(data, "version: %s\n", DRV_VERSION);
- data += sprintf(data, "compiled: %s %s\n", __DATE__, __TIME__);
+ data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name);
+ data += sprintf(data, "version:\t%s\n", DRV_VERSION);
+ data += sprintf(data, "compiled:\t%s %s\n", __DATE__, __TIME__);
blob->size = strlen(blob->data);
return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
@@ -566,14 +570,27 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name,
return NULL;
blob->data = data;
- data += sprintf(data, "rt chip: %04x\n", intf->rt2x00dev->chip.rt);
- data += sprintf(data, "rf chip: %04x\n", intf->rt2x00dev->chip.rf);
- data += sprintf(data, "revision:%08x\n", intf->rt2x00dev->chip.rev);
+ data += sprintf(data, "rt chip:\t%04x\n", intf->rt2x00dev->chip.rt);
+ data += sprintf(data, "rf chip:\t%04x\n", intf->rt2x00dev->chip.rf);
+ data += sprintf(data, "revision:\t%08x\n", intf->rt2x00dev->chip.rev);
data += sprintf(data, "\n");
- data += sprintf(data, "csr length: %d\n", debug->csr.word_count);
- data += sprintf(data, "eeprom length: %d\n", debug->eeprom.word_count);
- data += sprintf(data, "bbp length: %d\n", debug->bbp.word_count);
- data += sprintf(data, "rf length: %d\n", debug->rf.word_count);
+ data += sprintf(data, "register\tbase\twords\twordsize\n");
+ data += sprintf(data, "csr\t%d\t%d\t%d\n",
+ debug->csr.word_base,
+ debug->csr.word_count,
+ debug->csr.word_size);
+ data += sprintf(data, "eeprom\t%d\t%d\t%d\n",
+ debug->eeprom.word_base,
+ debug->eeprom.word_count,
+ debug->eeprom.word_size);
+ data += sprintf(data, "bbp\t%d\t%d\t%d\n",
+ debug->bbp.word_base,
+ debug->bbp.word_count,
+ debug->bbp.word_size);
+ data += sprintf(data, "rf\t%d\t%d\t%d\n",
+ debug->rf.word_base,
+ debug->rf.word_count,
+ debug->rf.word_size);
blob->size = strlen(blob->data);
return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.h b/drivers/net/wireless/rt2x00/rt2x00debug.h
index a92104dfee9a..035cbc98c593 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.h
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 87c0f2c83077..05f94e21b423 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -30,60 +30,6 @@
#include "rt2x00lib.h"
/*
- * Link tuning handlers
- */
-void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev)
-{
- if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
- return;
-
- /*
- * Reset link information.
- * Both the currently active vgc level as well as
- * the link tuner counter should be reset. Resetting
- * the counter is important for devices where the
- * device should only perform link tuning during the
- * first minute after being enabled.
- */
- rt2x00dev->link.count = 0;
- rt2x00dev->link.vgc_level = 0;
-
- /*
- * Reset the link tuner.
- */
- rt2x00dev->ops->lib->reset_tuner(rt2x00dev);
-}
-
-static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
-{
- /*
- * Clear all (possibly) pre-existing quality statistics.
- */
- memset(&rt2x00dev->link.qual, 0, sizeof(rt2x00dev->link.qual));
-
- /*
- * The RX and TX percentage should start at 50%
- * this will assure we will get at least get some
- * decent value when the link tuner starts.
- * The value will be dropped and overwritten with
- * the correct (measured )value anyway during the
- * first run of the link tuner.
- */
- rt2x00dev->link.qual.rx_percentage = 50;
- rt2x00dev->link.qual.tx_percentage = 50;
-
- rt2x00lib_reset_link_tuner(rt2x00dev);
-
- queue_delayed_work(rt2x00dev->hw->workqueue,
- &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
-}
-
-static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev)
-{
- cancel_delayed_work_sync(&rt2x00dev->link.work);
-}
-
-/*
* Radio control handlers.
*/
int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
@@ -137,9 +83,10 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
return;
/*
- * Stop the TX queues.
+ * Stop the TX queues in mac80211.
*/
ieee80211_stop_queues(rt2x00dev->hw);
+ rt2x00queue_stop_queues(rt2x00dev);
/*
* Disable RX.
@@ -161,238 +108,15 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
* When we are disabling the RX, we should also stop the link tuner.
*/
if (state == STATE_RADIO_RX_OFF)
- rt2x00lib_stop_link_tuner(rt2x00dev);
+ rt2x00link_stop_tuner(rt2x00dev);
rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
/*
* When we are enabling the RX, we should also start the link tuner.
*/
- if (state == STATE_RADIO_RX_ON &&
- (rt2x00dev->intf_ap_count || rt2x00dev->intf_sta_count))
- rt2x00lib_start_link_tuner(rt2x00dev);
-}
-
-static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
-{
- struct antenna_setup ant;
- int sample_a =
- rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_A);
- int sample_b =
- rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_B);
-
- memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant));
-
- /*
- * We are done sampling. Now we should evaluate the results.
- */
- rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE;
-
- /*
- * During the last period we have sampled the RSSI
- * from both antenna's. It now is time to determine
- * which antenna demonstrated the best performance.
- * When we are already on the antenna with the best
- * performance, then there really is nothing for us
- * left to do.
- */
- if (sample_a == sample_b)
- return;
-
- if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
- ant.rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
-
- if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
- ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
-
- rt2x00lib_config_antenna(rt2x00dev, &ant);
-}
-
-static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
-{
- struct antenna_setup ant;
- int rssi_curr = rt2x00_get_link_ant_rssi(&rt2x00dev->link);
- int rssi_old = rt2x00_update_ant_rssi(&rt2x00dev->link, rssi_curr);
-
- memcpy(&ant, &rt2x00dev->link.ant.active, sizeof(ant));
-
- /*
- * Legacy driver indicates that we should swap antenna's
- * when the difference in RSSI is greater that 5. This
- * also should be done when the RSSI was actually better
- * then the previous sample.
- * When the difference exceeds the threshold we should
- * sample the rssi from the other antenna to make a valid
- * comparison between the 2 antennas.
- */
- if (abs(rssi_curr - rssi_old) < 5)
- return;
-
- rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE;
-
- if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
- ant.rx = (ant.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
-
- if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
- ant.tx = (ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
-
- rt2x00lib_config_antenna(rt2x00dev, &ant);
-}
-
-static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev)
-{
- /*
- * Determine if software diversity is enabled for
- * either the TX or RX antenna (or both).
- * Always perform this check since within the link
- * tuner interval the configuration might have changed.
- */
- rt2x00dev->link.ant.flags &= ~ANTENNA_RX_DIVERSITY;
- rt2x00dev->link.ant.flags &= ~ANTENNA_TX_DIVERSITY;
-
- if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
- rt2x00dev->link.ant.flags |= ANTENNA_RX_DIVERSITY;
- if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
- rt2x00dev->link.ant.flags |= ANTENNA_TX_DIVERSITY;
-
- if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) &&
- !(rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)) {
- rt2x00dev->link.ant.flags = 0;
- return;
- }
-
- /*
- * If we have only sampled the data over the last period
- * we should now harvest the data. Otherwise just evaluate
- * the data. The latter should only be performed once
- * every 2 seconds.
- */
- if (rt2x00dev->link.ant.flags & ANTENNA_MODE_SAMPLE)
- rt2x00lib_evaluate_antenna_sample(rt2x00dev);
- else if (rt2x00dev->link.count & 1)
- rt2x00lib_evaluate_antenna_eval(rt2x00dev);
-}
-
-static void rt2x00lib_update_link_stats(struct link *link, int rssi)
-{
- int avg_rssi = rssi;
-
- /*
- * Update global RSSI
- */
- if (link->qual.avg_rssi)
- avg_rssi = MOVING_AVERAGE(link->qual.avg_rssi, rssi, 8);
- link->qual.avg_rssi = avg_rssi;
-
- /*
- * Update antenna RSSI
- */
- if (link->ant.rssi_ant)
- rssi = MOVING_AVERAGE(link->ant.rssi_ant, rssi, 8);
- link->ant.rssi_ant = rssi;
-}
-
-static void rt2x00lib_precalculate_link_signal(struct link_qual *qual)
-{
- if (qual->rx_failed || qual->rx_success)
- qual->rx_percentage =
- (qual->rx_success * 100) /
- (qual->rx_failed + qual->rx_success);
- else
- qual->rx_percentage = 50;
-
- if (qual->tx_failed || qual->tx_success)
- qual->tx_percentage =
- (qual->tx_success * 100) /
- (qual->tx_failed + qual->tx_success);
- else
- qual->tx_percentage = 50;
-
- qual->rx_success = 0;
- qual->rx_failed = 0;
- qual->tx_success = 0;
- qual->tx_failed = 0;
-}
-
-static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev,
- int rssi)
-{
- int rssi_percentage = 0;
- int signal;
-
- /*
- * We need a positive value for the RSSI.
- */
- if (rssi < 0)
- rssi += rt2x00dev->rssi_offset;
-
- /*
- * Calculate the different percentages,
- * which will be used for the signal.
- */
- if (rt2x00dev->rssi_offset)
- rssi_percentage = (rssi * 100) / rt2x00dev->rssi_offset;
-
- /*
- * Add the individual percentages and use the WEIGHT
- * defines to calculate the current link signal.
- */
- signal = ((WEIGHT_RSSI * rssi_percentage) +
- (WEIGHT_TX * rt2x00dev->link.qual.tx_percentage) +
- (WEIGHT_RX * rt2x00dev->link.qual.rx_percentage)) / 100;
-
- return (signal > 100) ? 100 : signal;
-}
-
-static void rt2x00lib_link_tuner(struct work_struct *work)
-{
- struct rt2x00_dev *rt2x00dev =
- container_of(work, struct rt2x00_dev, link.work.work);
-
- /*
- * When the radio is shutting down we should
- * immediately cease all link tuning.
- */
- if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
- return;
-
- /*
- * Update statistics.
- */
- rt2x00dev->ops->lib->link_stats(rt2x00dev, &rt2x00dev->link.qual);
- rt2x00dev->low_level_stats.dot11FCSErrorCount +=
- rt2x00dev->link.qual.rx_failed;
-
- /*
- * Only perform the link tuning when Link tuning
- * has been enabled (This could have been disabled from the EEPROM).
- */
- if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags))
- rt2x00dev->ops->lib->link_tuner(rt2x00dev);
-
- /*
- * Precalculate a portion of the link signal which is
- * in based on the tx/rx success/failure counters.
- */
- rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual);
-
- /*
- * Send a signal to the led to update the led signal strength.
- */
- rt2x00leds_led_quality(rt2x00dev, rt2x00dev->link.qual.avg_rssi);
-
- /*
- * Evaluate antenna setup, make this the last step since this could
- * possibly reset some statistics.
- */
- rt2x00lib_evaluate_antenna(rt2x00dev);
-
- /*
- * Increase tuner counter, and reschedule the next link tuner run.
- */
- rt2x00dev->link.count++;
- queue_delayed_work(rt2x00dev->hw->workqueue,
- &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
+ if (state == STATE_RADIO_RX_ON)
+ rt2x00link_start_tuner(rt2x00dev);
}
static void rt2x00lib_packetfilter_scheduled(struct work_struct *work)
@@ -434,7 +158,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
return;
if (delayed_flags & DELAYED_UPDATE_BEACON)
- rt2x00queue_update_beacon(rt2x00dev, vif);
+ rt2x00queue_update_beacon(rt2x00dev, vif, true);
if (delayed_flags & DELAYED_CONFIG_ERP)
rt2x00lib_config_erp(rt2x00dev, intf, &conf);
@@ -467,7 +191,9 @@ static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
struct rt2x00_intf *intf = vif_to_intf(vif);
if (vif->type != NL80211_IFTYPE_AP &&
- vif->type != NL80211_IFTYPE_ADHOC)
+ vif->type != NL80211_IFTYPE_ADHOC &&
+ vif->type != NL80211_IFTYPE_MESH_POINT &&
+ vif->type != NL80211_IFTYPE_WDS)
return;
/*
@@ -490,7 +216,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
rt2x00lib_beacondone_iter,
rt2x00dev);
- schedule_work(&rt2x00dev->intf_work);
+ queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
}
EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
@@ -597,7 +323,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb;
struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
struct ieee80211_supported_band *sband;
- struct ieee80211_hdr *hdr;
const struct rt2x00_rate *rate;
unsigned int header_length;
unsigned int align;
@@ -668,30 +393,22 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
if (idx < 0) {
WARNING(rt2x00dev, "Frame received with unrecognized signal,"
- "signal=0x%.2x, plcp=%d.\n", rxdesc.signal,
- !!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP));
+ "signal=0x%.2x, type=%d.\n", rxdesc.signal,
+ (rxdesc.dev_flags & RXDONE_SIGNAL_MASK));
idx = 0;
}
/*
- * Only update link status if this is a beacon frame carrying our bssid.
+ * Update extra components
*/
- hdr = (struct ieee80211_hdr *)entry->skb->data;
- if (ieee80211_is_beacon(hdr->frame_control) &&
- (rxdesc.dev_flags & RXDONE_MY_BSS))
- rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc.rssi);
-
- rt2x00debug_update_crypto(rt2x00dev,
- rxdesc.cipher,
- rxdesc.cipher_status);
-
- rt2x00dev->link.qual.rx_success++;
+ rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc);
+ rt2x00debug_update_crypto(rt2x00dev, &rxdesc);
rx_status->mactime = rxdesc.timestamp;
rx_status->rate_idx = idx;
- rx_status->qual =
- rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi);
+ rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi);
rx_status->signal = rxdesc.rssi;
+ rx_status->noise = rxdesc.noise;
rx_status->flag = rxdesc.flags;
rx_status->antenna = rt2x00dev->link.ant.active.rx;
@@ -1067,7 +784,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
if (rt2x00dev->ops->bcn->entry_num > 0)
rt2x00dev->hw->wiphy->interface_modes |=
BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_AP);
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_MESH_POINT) |
+ BIT(NL80211_IFTYPE_WDS);
/*
* Let the driver probe the device to detect the capabilities.
@@ -1083,7 +802,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
*/
INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled);
- INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner);
/*
* Allocate queue array.
@@ -1104,6 +822,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
/*
* Register extra components.
*/
+ rt2x00link_register(rt2x00dev);
rt2x00leds_register(rt2x00dev);
rt2x00rfkill_allocate(rt2x00dev);
rt2x00debug_register(rt2x00dev);
@@ -1163,23 +882,17 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
#ifdef CONFIG_PM
int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
{
- int retval;
-
NOTICE(rt2x00dev, "Going to sleep.\n");
/*
- * Only continue if mac80211 has open interfaces.
+ * Prevent mac80211 from accessing driver while suspended.
*/
- if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
- !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
- goto exit;
-
- set_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags);
+ if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+ return 0;
/*
- * Disable radio.
+ * Cleanup as much as possible.
*/
- rt2x00lib_stop(rt2x00dev);
rt2x00lib_uninitialize(rt2x00dev);
/*
@@ -1188,7 +901,6 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
rt2x00leds_suspend(rt2x00dev);
rt2x00debug_deregister(rt2x00dev);
-exit:
/*
* Set device mode to sleep for power management,
* on some hardware this call seems to consistently fail.
@@ -1200,8 +912,7 @@ exit:
* the radio and the other components already disabled the
* device is as good as disabled.
*/
- retval = rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP);
- if (retval)
+ if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP))
WARNING(rt2x00dev, "Device failed to enter sleep state, "
"continue suspending.\n");
@@ -1209,32 +920,8 @@ exit:
}
EXPORT_SYMBOL_GPL(rt2x00lib_suspend);
-static void rt2x00lib_resume_intf(void *data, u8 *mac,
- struct ieee80211_vif *vif)
-{
- struct rt2x00_dev *rt2x00dev = data;
- struct rt2x00_intf *intf = vif_to_intf(vif);
-
- spin_lock(&intf->lock);
-
- rt2x00lib_config_intf(rt2x00dev, intf,
- vif->type, intf->mac, intf->bssid);
-
-
- /*
- * Master or Ad-hoc mode require a new beacon update.
- */
- if (vif->type == NL80211_IFTYPE_AP ||
- vif->type == NL80211_IFTYPE_ADHOC)
- intf->delayed_flags |= DELAYED_UPDATE_BEACON;
-
- spin_unlock(&intf->lock);
-}
-
int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
{
- int retval;
-
NOTICE(rt2x00dev, "Waking up.\n");
/*
@@ -1244,60 +931,11 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
rt2x00leds_resume(rt2x00dev);
/*
- * Only continue if mac80211 had open interfaces.
- */
- if (!test_and_clear_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags))
- return 0;
-
- /*
- * Reinitialize device and all active interfaces.
- */
- retval = rt2x00lib_start(rt2x00dev);
- if (retval)
- goto exit;
-
- /*
- * Reconfigure device.
- */
- retval = rt2x00mac_config(rt2x00dev->hw, ~0);
- if (retval)
- goto exit;
-
- /*
- * Iterator over each active interface to
- * reconfigure the hardware.
- */
- ieee80211_iterate_active_interfaces(rt2x00dev->hw,
- rt2x00lib_resume_intf, rt2x00dev);
-
- /*
* We are ready again to receive requests from mac80211.
*/
set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
- /*
- * It is possible that during that mac80211 has attempted
- * to send frames while we were suspending or resuming.
- * In that case we have disabled the TX queue and should
- * now enable it again
- */
- ieee80211_wake_queues(rt2x00dev->hw);
-
- /*
- * During interface iteration we might have changed the
- * delayed_flags, time to handles the event by calling
- * the work handler directly.
- */
- rt2x00lib_intf_scheduled(&rt2x00dev->intf_work);
-
return 0;
-
-exit:
- rt2x00lib_stop(rt2x00dev);
- rt2x00lib_uninitialize(rt2x00dev);
- rt2x00debug_deregister(rt2x00dev);
-
- return retval;
}
EXPORT_SYMBOL_GPL(rt2x00lib_resume);
#endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h
index 7169c222a486..fdedb5122928 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dump.h
+++ b/drivers/net/wireless/rt2x00/rt2x00dump.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c
index bab05a56e7a0..d2deea2f2679 100644
--- a/drivers/net/wireless/rt2x00/rt2x00firmware.c
+++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -35,7 +35,6 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
const struct firmware *fw;
char *fw_name;
int retval;
- u16 crc;
/*
* Read correct firmware from harddisk.
@@ -61,16 +60,26 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
return -ENOENT;
}
- crc = rt2x00dev->ops->lib->get_firmware_crc(fw->data, fw->size);
- if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) {
- ERROR(rt2x00dev, "Firmware checksum error.\n");
- retval = -ENOENT;
- goto exit;
- }
-
INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n",
fw->data[fw->size - 4], fw->data[fw->size - 3]);
+ retval = rt2x00dev->ops->lib->check_firmware(rt2x00dev, fw->data, fw->size);
+ switch (retval) {
+ case FW_OK:
+ break;
+ case FW_BAD_CRC:
+ ERROR(rt2x00dev, "Firmware checksum error.\n");
+ goto exit;
+ case FW_BAD_LENGTH:
+ ERROR(rt2x00dev,
+ "Invalid firmware file length (len=%zu)\n", fw->size);
+ goto exit;
+ case FW_BAD_VERSION:
+ ERROR(rt2x00dev,
+ "Current firmware does not support detected chipset.\n");
+ goto exit;
+ };
+
rt2x00dev->fw = fw;
return 0;
@@ -78,7 +87,7 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev)
exit:
release_firmware(fw);
- return retval;
+ return -ENOENT;
}
int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c
index a0cd35b6beb5..49671fed91d7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00leds.c
+++ b/drivers/net/wireless/rt2x00/rt2x00leds.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -134,7 +134,7 @@ void rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
rt2x00dev->ops->name, wiphy_name(rt2x00dev->hw->wiphy));
if (rt2x00dev->led_radio.flags & LED_INITIALIZED) {
- snprintf(name, sizeof(name), "%s:radio", dev_name);
+ snprintf(name, sizeof(name), "%s::radio", dev_name);
retval = rt2x00leds_register_led(rt2x00dev,
&rt2x00dev->led_radio,
@@ -144,7 +144,7 @@ void rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
}
if (rt2x00dev->led_assoc.flags & LED_INITIALIZED) {
- snprintf(name, sizeof(name), "%s:assoc", dev_name);
+ snprintf(name, sizeof(name), "%s::assoc", dev_name);
retval = rt2x00leds_register_led(rt2x00dev,
&rt2x00dev->led_assoc,
@@ -154,7 +154,7 @@ void rt2x00leds_register(struct rt2x00_dev *rt2x00dev)
}
if (rt2x00dev->led_qual.flags & LED_INITIALIZED) {
- snprintf(name, sizeof(name), "%s:quality", dev_name);
+ snprintf(name, sizeof(name), "%s::quality", dev_name);
retval = rt2x00leds_register_led(rt2x00dev,
&rt2x00dev->led_qual,
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.h b/drivers/net/wireless/rt2x00/rt2x00leds.h
index 9df4a49bdcad..1046977e6a12 100644
--- a/drivers/net/wireless/rt2x00/rt2x00leds.h
+++ b/drivers/net/wireless/rt2x00/rt2x00leds.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 86cd26fbf769..a631613177d0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -33,7 +33,7 @@
* Both the link tuner as the rfkill will be called once per second.
*/
#define LINK_TUNE_INTERVAL ( round_jiffies_relative(HZ) )
-#define RFKILL_POLL_INTERVAL ( round_jiffies_relative(HZ) )
+#define RFKILL_POLL_INTERVAL ( 1000 )
/*
* rt2x00_rate: Per rate device information
@@ -63,7 +63,6 @@ static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value)
int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state);
-void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev);
/*
* Initialization handlers.
@@ -77,7 +76,7 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf,
enum nl80211_iftype type,
- u8 *mac, u8 *bssid);
+ const u8 *mac, const u8 *bssid);
void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf,
struct ieee80211_bss_conf *conf);
@@ -124,9 +123,11 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb);
* rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware
* @rt2x00dev: Pointer to &struct rt2x00_dev.
* @vif: Interface for which the beacon should be updated.
+ * @enable_beacon: Enable beaconing
*/
int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_vif *vif);
+ struct ieee80211_vif *vif,
+ const bool enable_beacon);
/**
* rt2x00queue_index_inc - Index incrementation function
@@ -140,6 +141,15 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
/**
+ * rt2x00queue_stop_queues - Halt all data queues
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * This function will loop through all available queues to stop
+ * any pending outgoing frames.
+ */
+void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev);
+
+/**
* rt2x00queue_init_queues - Initialize all data queues
* @rt2x00dev: Pointer to &struct rt2x00_dev.
*
@@ -154,6 +164,81 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev);
int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev);
void rt2x00queue_free(struct rt2x00_dev *rt2x00dev);
+/**
+ * rt2x00link_update_stats - Update link statistics from RX frame
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @skb: Received frame
+ * @rxdesc: Received frame descriptor
+ *
+ * Update link statistics based on the information from the
+ * received frame descriptor.
+ */
+void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
+ struct sk_buff *skb,
+ struct rxdone_entry_desc *rxdesc);
+
+/**
+ * rt2x00link_calculate_signal - Calculate signal quality
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @rssi: RX Frame RSSI
+ *
+ * Calculate the signal quality of a frame based on the rssi
+ * measured during the receiving of the frame and the global
+ * link quality statistics measured since the start of the
+ * link tuning. The result is a value between 0 and 100 which
+ * is an indication of the signal quality.
+ */
+int rt2x00link_calculate_signal(struct rt2x00_dev *rt2x00dev, int rssi);
+
+/**
+ * rt2x00link_start_tuner - Start periodic link tuner work
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * This start the link tuner periodic work, this work will
+ * be executed periodically until &rt2x00link_stop_tuner has
+ * been called.
+ */
+void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00link_stop_tuner - Stop periodic link tuner work
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * After this function completed the link tuner will not
+ * be running until &rt2x00link_start_tuner is called.
+ */
+void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00link_reset_tuner - Reset periodic link tuner work
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ * @antenna: Should the antenna tuning also be reset
+ *
+ * The VGC limit configured in the hardware will be reset to 0
+ * which forces the driver to rediscover the correct value for
+ * the current association. This is needed when configuration
+ * options have changed which could drastically change the
+ * SNR level or link quality (i.e. changing the antenna setting).
+ *
+ * Resetting the link tuner will also cause the periodic work counter
+ * to be reset. Any driver which has a fixed limit on the number
+ * of rounds the link tuner is supposed to work will accept the
+ * tuner actions again if this limit was previously reached.
+ *
+ * If @antenna is set to true a the software antenna diversity
+ * tuning will also be reset.
+ */
+void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna);
+
+/**
+ * rt2x00link_register - Initialize link tuning functionality
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ *
+ * Initialize work structure and all link tuning related
+ * paramters. This will not start the link tuning process itself.
+ */
+void rt2x00link_register(struct rt2x00_dev *rt2x00dev);
+
/*
* Firmware handlers.
*/
@@ -179,7 +264,7 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev);
void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
enum rt2x00_dump_type type, struct sk_buff *skb);
void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
- enum cipher cipher, enum rx_crypto status);
+ struct rxdone_entry_desc *rxdesc);
#else
static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
{
@@ -196,8 +281,7 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
}
static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
- enum cipher cipher,
- enum rx_crypto status)
+ struct rxdone_entry_desc *rxdesc)
{
}
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
@@ -209,7 +293,8 @@ static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key);
void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc);
-unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info);
+unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
+ struct sk_buff *skb);
void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len);
void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len);
void rt2x00crypto_tx_insert_iv(struct sk_buff *skb);
@@ -227,7 +312,8 @@ static inline void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
{
}
-static inline unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info)
+static inline unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
+ struct sk_buff *skb)
{
return 0;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
new file mode 100644
index 000000000000..7eb5cd7e5f32
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -0,0 +1,471 @@
+/*
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+ <http://rt2x00.serialmonkey.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ Module: rt2x00lib
+ Abstract: rt2x00 generic link tuning routines.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "rt2x00.h"
+#include "rt2x00lib.h"
+
+/*
+ * When we lack RSSI information return something less then -80 to
+ * tell the driver to tune the device to maximum sensitivity.
+ */
+#define DEFAULT_RSSI -128
+
+/*
+ * When no TX/RX percentage could be calculated due to lack of
+ * frames on the air, we fallback to a percentage of 50%.
+ * This will assure we will get at least get some decent value
+ * when the link tuner starts.
+ * The value will be dropped and overwritten with the correct (measured)
+ * value anyway during the first run of the link tuner.
+ */
+#define DEFAULT_PERCENTAGE 50
+
+/*
+ * Small helper macro to work with moving/walking averages.
+ * When adding a value to the average value the following calculation
+ * is needed:
+ *
+ * avg_rssi = ((avg_rssi * 7) + rssi) / 8;
+ *
+ * The advantage of this approach is that we only need 1 variable
+ * to store the average in (No need for a count and a total).
+ * But more importantly, normal average values will over time
+ * move less and less towards newly added values this results
+ * that with link tuning, the device can have a very good RSSI
+ * for a few minutes but when the device is moved away from the AP
+ * the average will not decrease fast enough to compensate.
+ * The walking average compensates this and will move towards
+ * the new values correctly allowing a effective link tuning.
+ */
+#define MOVING_AVERAGE(__avg, __val, __samples) \
+ ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) )
+
+/*
+ * Small helper macro for percentage calculation
+ * This is a very simple macro with the only catch that it will
+ * produce a default value in case no total value was provided.
+ */
+#define PERCENTAGE(__value, __total) \
+ ( (__total) ? (((__value) * 100) / (__total)) : (DEFAULT_PERCENTAGE) )
+
+/*
+ * For calculating the Signal quality we have determined
+ * the total number of success and failed RX and TX frames.
+ * With the addition of the average RSSI value we can determine
+ * the link quality using the following algorithm:
+ *
+ * rssi_percentage = (avg_rssi * 100) / rssi_offset
+ * rx_percentage = (rx_success * 100) / rx_total
+ * tx_percentage = (tx_success * 100) / tx_total
+ * avg_signal = ((WEIGHT_RSSI * avg_rssi) +
+ * (WEIGHT_TX * tx_percentage) +
+ * (WEIGHT_RX * rx_percentage)) / 100
+ *
+ * This value should then be checked to not be greater then 100.
+ * This means the values of WEIGHT_RSSI, WEIGHT_RX, WEIGHT_TX must
+ * sum up to 100 as well.
+ */
+#define WEIGHT_RSSI 20
+#define WEIGHT_RX 40
+#define WEIGHT_TX 40
+
+static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev)
+{
+ struct link_ant *ant = &rt2x00dev->link.ant;
+
+ if (ant->rssi_ant && rt2x00dev->link.qual.rx_success)
+ return ant->rssi_ant;
+ return DEFAULT_RSSI;
+}
+
+static int rt2x00link_antenna_get_rssi_history(struct rt2x00_dev *rt2x00dev,
+ enum antenna antenna)
+{
+ struct link_ant *ant = &rt2x00dev->link.ant;
+
+ if (ant->rssi_history[antenna - ANTENNA_A])
+ return ant->rssi_history[antenna - ANTENNA_A];
+ return DEFAULT_RSSI;
+}
+/* Small wrapper for rt2x00link_antenna_get_rssi_history() */
+#define rt2x00link_antenna_get_rssi_rx_history(__dev) \
+ rt2x00link_antenna_get_rssi_history((__dev), \
+ (__dev)->link.ant.active.rx)
+#define rt2x00link_antenna_get_rssi_tx_history(__dev) \
+ rt2x00link_antenna_get_rssi_history((__dev), \
+ (__dev)->link.ant.active.tx)
+
+static void rt2x00link_antenna_update_rssi_history(struct rt2x00_dev *rt2x00dev,
+ enum antenna antenna,
+ int rssi)
+{
+ struct link_ant *ant = &rt2x00dev->link.ant;
+ ant->rssi_history[ant->active.rx - ANTENNA_A] = rssi;
+}
+/* Small wrapper for rt2x00link_antenna_get_rssi_history() */
+#define rt2x00link_antenna_update_rssi_rx_history(__dev, __rssi) \
+ rt2x00link_antenna_update_rssi_history((__dev), \
+ (__dev)->link.ant.active.rx, \
+ (__rssi))
+#define rt2x00link_antenna_update_rssi_tx_history(__dev, __rssi) \
+ rt2x00link_antenna_update_rssi_history((__dev), \
+ (__dev)->link.ant.active.tx, \
+ (__rssi))
+
+static void rt2x00link_antenna_reset(struct rt2x00_dev *rt2x00dev)
+{
+ rt2x00dev->link.ant.rssi_ant = 0;
+}
+
+static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev)
+{
+ struct link_ant *ant = &rt2x00dev->link.ant;
+ struct antenna_setup new_ant;
+ int sample_a = rt2x00link_antenna_get_rssi_history(rt2x00dev, ANTENNA_A);
+ int sample_b = rt2x00link_antenna_get_rssi_history(rt2x00dev, ANTENNA_B);
+
+ memcpy(&new_ant, &ant->active, sizeof(new_ant));
+
+ /*
+ * We are done sampling. Now we should evaluate the results.
+ */
+ ant->flags &= ~ANTENNA_MODE_SAMPLE;
+
+ /*
+ * During the last period we have sampled the RSSI
+ * from both antenna's. It now is time to determine
+ * which antenna demonstrated the best performance.
+ * When we are already on the antenna with the best
+ * performance, then there really is nothing for us
+ * left to do.
+ */
+ if (sample_a == sample_b)
+ return;
+
+ if (ant->flags & ANTENNA_RX_DIVERSITY)
+ new_ant.rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
+
+ if (ant->flags & ANTENNA_TX_DIVERSITY)
+ new_ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
+
+ rt2x00lib_config_antenna(rt2x00dev, &new_ant);
+}
+
+static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev)
+{
+ struct link_ant *ant = &rt2x00dev->link.ant;
+ struct antenna_setup new_ant;
+ int rssi_curr;
+ int rssi_old;
+
+ memcpy(&new_ant, &ant->active, sizeof(new_ant));
+
+ /*
+ * Get current RSSI value along with the historical value,
+ * after that update the history with the current value.
+ */
+ rssi_curr = rt2x00link_antenna_get_link_rssi(rt2x00dev);
+ rssi_old = rt2x00link_antenna_get_rssi_rx_history(rt2x00dev);
+ rt2x00link_antenna_update_rssi_rx_history(rt2x00dev, rssi_curr);
+
+ /*
+ * Legacy driver indicates that we should swap antenna's
+ * when the difference in RSSI is greater that 5. This
+ * also should be done when the RSSI was actually better
+ * then the previous sample.
+ * When the difference exceeds the threshold we should
+ * sample the rssi from the other antenna to make a valid
+ * comparison between the 2 antennas.
+ */
+ if (abs(rssi_curr - rssi_old) < 5)
+ return;
+
+ ant->flags |= ANTENNA_MODE_SAMPLE;
+
+ if (ant->flags & ANTENNA_RX_DIVERSITY)
+ new_ant.rx = (new_ant.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
+
+ if (ant->flags & ANTENNA_TX_DIVERSITY)
+ new_ant.tx = (new_ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
+
+ rt2x00lib_config_antenna(rt2x00dev, &new_ant);
+}
+
+static void rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
+{
+ struct link_ant *ant = &rt2x00dev->link.ant;
+
+ /*
+ * Determine if software diversity is enabled for
+ * either the TX or RX antenna (or both).
+ * Always perform this check since within the link
+ * tuner interval the configuration might have changed.
+ */
+ ant->flags &= ~ANTENNA_RX_DIVERSITY;
+ ant->flags &= ~ANTENNA_TX_DIVERSITY;
+
+ if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
+ ant->flags |= ANTENNA_RX_DIVERSITY;
+ if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
+ ant->flags |= ANTENNA_TX_DIVERSITY;
+
+ if (!(ant->flags & ANTENNA_RX_DIVERSITY) &&
+ !(ant->flags & ANTENNA_TX_DIVERSITY)) {
+ ant->flags = 0;
+ return;
+ }
+
+ /*
+ * If we have only sampled the data over the last period
+ * we should now harvest the data. Otherwise just evaluate
+ * the data. The latter should only be performed once
+ * every 2 seconds.
+ */
+ if (ant->flags & ANTENNA_MODE_SAMPLE)
+ rt2x00lib_antenna_diversity_sample(rt2x00dev);
+ else if (rt2x00dev->link.count & 1)
+ rt2x00lib_antenna_diversity_eval(rt2x00dev);
+}
+
+void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
+ struct sk_buff *skb,
+ struct rxdone_entry_desc *rxdesc)
+{
+ struct link *link = &rt2x00dev->link;
+ struct link_qual *qual = &rt2x00dev->link.qual;
+ struct link_ant *ant = &rt2x00dev->link.ant;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ int avg_rssi = rxdesc->rssi;
+ int ant_rssi = rxdesc->rssi;
+
+ /*
+ * Frame was received successfully since non-succesfull
+ * frames would have been dropped by the hardware.
+ */
+ qual->rx_success++;
+
+ /*
+ * We are only interested in quality statistics from
+ * beacons which came from the BSS which we are
+ * associated with.
+ */
+ if (!ieee80211_is_beacon(hdr->frame_control) ||
+ !(rxdesc->dev_flags & RXDONE_MY_BSS))
+ return;
+
+ /*
+ * Update global RSSI
+ */
+ if (link->avg_rssi)
+ avg_rssi = MOVING_AVERAGE(link->avg_rssi, rxdesc->rssi, 8);
+ link->avg_rssi = avg_rssi;
+
+ /*
+ * Update antenna RSSI
+ */
+ if (ant->rssi_ant)
+ ant_rssi = MOVING_AVERAGE(ant->rssi_ant, rxdesc->rssi, 8);
+ ant->rssi_ant = ant_rssi;
+}
+
+static void rt2x00link_precalculate_signal(struct rt2x00_dev *rt2x00dev)
+{
+ struct link *link = &rt2x00dev->link;
+ struct link_qual *qual = &rt2x00dev->link.qual;
+
+ link->rx_percentage =
+ PERCENTAGE(qual->rx_success, qual->rx_failed + qual->rx_success);
+ link->tx_percentage =
+ PERCENTAGE(qual->tx_success, qual->tx_failed + qual->tx_success);
+}
+
+int rt2x00link_calculate_signal(struct rt2x00_dev *rt2x00dev, int rssi)
+{
+ struct link *link = &rt2x00dev->link;
+ int rssi_percentage = 0;
+ int signal;
+
+ /*
+ * We need a positive value for the RSSI.
+ */
+ if (rssi < 0)
+ rssi += rt2x00dev->rssi_offset;
+
+ /*
+ * Calculate the different percentages,
+ * which will be used for the signal.
+ */
+ rssi_percentage = PERCENTAGE(rssi, rt2x00dev->rssi_offset);
+
+ /*
+ * Add the individual percentages and use the WEIGHT
+ * defines to calculate the current link signal.
+ */
+ signal = ((WEIGHT_RSSI * rssi_percentage) +
+ (WEIGHT_TX * link->tx_percentage) +
+ (WEIGHT_RX * link->rx_percentage)) / 100;
+
+ return max_t(int, signal, 100);
+}
+
+void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev)
+{
+ struct link *link = &rt2x00dev->link;
+
+ /*
+ * Link tuning should only be performed when
+ * an active sta or master interface exists.
+ * Single monitor mode interfaces should never have
+ * work with link tuners.
+ */
+ if (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)
+ return;
+
+ link->rx_percentage = DEFAULT_PERCENTAGE;
+ link->tx_percentage = DEFAULT_PERCENTAGE;
+
+ rt2x00link_reset_tuner(rt2x00dev, false);
+
+ queue_delayed_work(rt2x00dev->hw->workqueue,
+ &link->work, LINK_TUNE_INTERVAL);
+}
+
+void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev)
+{
+ cancel_delayed_work_sync(&rt2x00dev->link.work);
+}
+
+void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna)
+{
+ struct link_qual *qual = &rt2x00dev->link.qual;
+
+ if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+ return;
+
+ /*
+ * Reset link information.
+ * Both the currently active vgc level as well as
+ * the link tuner counter should be reset. Resetting
+ * the counter is important for devices where the
+ * device should only perform link tuning during the
+ * first minute after being enabled.
+ */
+ rt2x00dev->link.count = 0;
+ memset(qual, 0, sizeof(*qual));
+
+ /*
+ * Reset the link tuner.
+ */
+ rt2x00dev->ops->lib->reset_tuner(rt2x00dev, qual);
+
+ if (antenna)
+ rt2x00link_antenna_reset(rt2x00dev);
+}
+
+void rt2x00link_reset_qual(struct rt2x00_dev *rt2x00dev)
+{
+ struct link_qual *qual = &rt2x00dev->link.qual;
+
+ qual->rx_success = 0;
+ qual->rx_failed = 0;
+ qual->tx_success = 0;
+ qual->tx_failed = 0;
+}
+
+static void rt2x00link_tuner(struct work_struct *work)
+{
+ struct rt2x00_dev *rt2x00dev =
+ container_of(work, struct rt2x00_dev, link.work.work);
+ struct link *link = &rt2x00dev->link;
+ struct link_qual *qual = &rt2x00dev->link.qual;
+
+ /*
+ * When the radio is shutting down we should
+ * immediately cease all link tuning.
+ */
+ if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+ return;
+
+ /*
+ * Update statistics.
+ */
+ rt2x00dev->ops->lib->link_stats(rt2x00dev, qual);
+ rt2x00dev->low_level_stats.dot11FCSErrorCount += qual->rx_failed;
+
+ /*
+ * Update quality RSSI for link tuning,
+ * when we have received some frames and we managed to
+ * collect the RSSI data we could use this. Otherwise we
+ * must fallback to the default RSSI value.
+ */
+ if (!link->avg_rssi || !qual->rx_success)
+ qual->rssi = DEFAULT_RSSI;
+ else
+ qual->rssi = link->avg_rssi;
+
+ /*
+ * Only perform the link tuning when Link tuning
+ * has been enabled (This could have been disabled from the EEPROM).
+ */
+ if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags))
+ rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count);
+
+ /*
+ * Precalculate a portion of the link signal which is
+ * in based on the tx/rx success/failure counters.
+ */
+ rt2x00link_precalculate_signal(rt2x00dev);
+
+ /*
+ * Send a signal to the led to update the led signal strength.
+ */
+ rt2x00leds_led_quality(rt2x00dev, link->avg_rssi);
+
+ /*
+ * Evaluate antenna setup, make this the last step since this could
+ * possibly reset some statistics.
+ */
+ rt2x00lib_antenna_diversity(rt2x00dev);
+
+ /*
+ * Reset the quality counters which recounted during each period.
+ */
+ rt2x00link_reset_qual(rt2x00dev);
+
+ /*
+ * Increase tuner counter, and reschedule the next link tuner run.
+ */
+ link->count++;
+ queue_delayed_work(rt2x00dev->hw->workqueue,
+ &link->work, LINK_TUNE_INTERVAL);
+}
+
+void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
+{
+ INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner);
+}
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 38edee5fe168..c41a0b9e473d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -79,8 +79,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
* RTS/CTS frame should use the length of the frame plus any
* encryption overhead that will be added by the hardware.
*/
- if (!frag_skb->do_not_encrypt)
- data_length += rt2x00crypto_tx_overhead(tx_info);
+ data_length += rt2x00crypto_tx_overhead(rt2x00dev, skb);
if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif,
@@ -226,6 +225,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
break;
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
+ case NL80211_IFTYPE_WDS:
/*
* We don't support mixed combinations of
* sta and ap interfaces.
@@ -430,8 +431,10 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
/*
* Update the beacon.
*/
- if (conf->changed & IEEE80211_IFCC_BEACON)
- status = rt2x00queue_update_beacon(rt2x00dev, vif);
+ if (conf->changed & (IEEE80211_IFCC_BEACON |
+ IEEE80211_IFCC_BEACON_ENABLED))
+ status = rt2x00queue_update_beacon(rt2x00dev, vif,
+ conf->enable_beacon);
return status;
}
@@ -482,16 +485,36 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
#ifdef CONFIG_RT2X00_LIB_CRYPTO
+static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len)
+{
+ if (key_len > NL80211_TKIP_DATA_OFFSET_ENCR_KEY)
+ memcpy(&crypto->key,
+ &key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY],
+ sizeof(crypto->key));
+
+ if (key_len > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
+ memcpy(&crypto->tx_mic,
+ &key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
+ sizeof(crypto->tx_mic));
+
+ if (key_len > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY)
+ memcpy(&crypto->rx_mic,
+ &key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
+ sizeof(crypto->rx_mic));
+}
+
int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
- struct ieee80211_sta *sta;
+ struct rt2x00_intf *intf = vif_to_intf(vif);
int (*set_key) (struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_crypto *crypto,
struct ieee80211_key_conf *key);
struct rt2x00lib_crypto crypto;
+ static const u8 bcast_addr[ETH_ALEN] =
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, };
if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
return 0;
@@ -509,45 +532,25 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (rt2x00dev->intf_sta_count)
crypto.bssidx = 0;
else
- crypto.bssidx =
- local_address[5] & (rt2x00dev->ops->max_ap_intf - 1);
+ crypto.bssidx = intf->mac[5] & (rt2x00dev->ops->max_ap_intf - 1);
crypto.cipher = rt2x00crypto_key_to_cipher(key);
if (crypto.cipher == CIPHER_NONE)
return -EOPNOTSUPP;
crypto.cmd = cmd;
- crypto.address = address;
-
- if (crypto.cipher == CIPHER_TKIP) {
- if (key->keylen > NL80211_TKIP_DATA_OFFSET_ENCR_KEY)
- memcpy(&crypto.key,
- &key->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY],
- sizeof(crypto.key));
-
- if (key->keylen > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
- memcpy(&crypto.tx_mic,
- &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
- sizeof(crypto.tx_mic));
-
- if (key->keylen > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY)
- memcpy(&crypto.rx_mic,
- &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
- sizeof(crypto.rx_mic));
- } else
- memcpy(&crypto.key, &key->key[0], key->keylen);
- /*
- * Discover the Association ID from mac80211.
- * Some drivers need this information when updating the
- * hardware key (either adding or removing).
- */
- rcu_read_lock();
- sta = ieee80211_find_sta(hw, address);
- if (sta)
+ if (sta) {
+ /* some drivers need the AID */
crypto.aid = sta->aid;
- rcu_read_unlock();
+ crypto.address = sta->addr;
+ } else
+ crypto.address = bcast_addr;
+ if (crypto.cipher == CIPHER_TKIP)
+ memcpy_tkip(&crypto, &key->key[0], key->keylen);
+ else
+ memcpy(&crypto.key, &key->key[0], key->keylen);
/*
* Each BSS has a maximum of 4 shared keys.
* Shared key index values:
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index d52b22b82d1f..e616c20d4a78 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 9c0a4d77bc1b..15a12487e04b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 0709decec9c2..a5664bd8493e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -148,20 +148,105 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
dev_kfree_skb_any(skb);
}
+static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
+ struct txentry_desc *txdesc)
+{
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
+ struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
+ unsigned long irqflags;
+
+ if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) ||
+ unlikely(!tx_info->control.vif))
+ return;
+
+ /*
+ * Hardware should insert sequence counter.
+ * FIXME: We insert a software sequence counter first for
+ * hardware that doesn't support hardware sequence counting.
+ *
+ * This is wrong because beacons are not getting sequence
+ * numbers assigned properly.
+ *
+ * A secondary problem exists for drivers that cannot toggle
+ * sequence counting per-frame, since those will override the
+ * sequence counter given by mac80211.
+ */
+ spin_lock_irqsave(&intf->seqlock, irqflags);
+
+ if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
+ intf->seqno += 0x10;
+ hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+ hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
+
+ spin_unlock_irqrestore(&intf->seqlock, irqflags);
+
+ __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
+}
+
+static void rt2x00queue_create_tx_descriptor_plcp(struct queue_entry *entry,
+ struct txentry_desc *txdesc,
+ const struct rt2x00_rate *hwrate)
+{
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+ struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
+ unsigned int data_length;
+ unsigned int duration;
+ unsigned int residual;
+
+ /* Data length + CRC + Crypto overhead (IV/EIV/ICV/MIC) */
+ data_length = entry->skb->len + 4;
+ data_length += rt2x00crypto_tx_overhead(rt2x00dev, entry->skb);
+
+ /*
+ * PLCP setup
+ * Length calculation depends on OFDM/CCK rate.
+ */
+ txdesc->signal = hwrate->plcp;
+ txdesc->service = 0x04;
+
+ if (hwrate->flags & DEV_RATE_OFDM) {
+ txdesc->length_high = (data_length >> 6) & 0x3f;
+ txdesc->length_low = data_length & 0x3f;
+ } else {
+ /*
+ * Convert length to microseconds.
+ */
+ residual = GET_DURATION_RES(data_length, hwrate->bitrate);
+ duration = GET_DURATION(data_length, hwrate->bitrate);
+
+ if (residual != 0) {
+ duration++;
+
+ /*
+ * Check if we need to set the Length Extension
+ */
+ if (hwrate->bitrate == 110 && residual <= 30)
+ txdesc->service |= 0x80;
+ }
+
+ txdesc->length_high = (duration >> 8) & 0xff;
+ txdesc->length_low = duration & 0xff;
+
+ /*
+ * When preamble is enabled we should set the
+ * preamble bit for the signal.
+ */
+ if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ txdesc->signal |= 0x08;
+ }
+}
+
static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
struct txentry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
- struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
struct ieee80211_rate *rate =
ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);
const struct rt2x00_rate *hwrate;
- unsigned int data_length;
- unsigned int duration;
- unsigned int residual;
- unsigned long irqflags;
memset(txdesc, 0, sizeof(*txdesc));
@@ -173,27 +258,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
txdesc->cw_max = entry->queue->cw_max;
txdesc->aifs = entry->queue->aifs;
- /* Data length + CRC */
- data_length = entry->skb->len + 4;
-
/*
* Check whether this frame is to be acked.
*/
if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK))
__set_bit(ENTRY_TXD_ACK, &txdesc->flags);
- if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) &&
- !entry->skb->do_not_encrypt) {
- /* Apply crypto specific descriptor information */
- rt2x00crypto_create_tx_descriptor(entry, txdesc);
-
- /*
- * Extend frame length to include all encryption overhead
- * that will be added by the hardware.
- */
- data_length += rt2x00crypto_tx_overhead(tx_info);
- }
-
/*
* Check if this is a RTS/CTS frame
*/
@@ -237,86 +307,27 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
* Set ifs to IFS_SIFS when the this is not the first fragment,
* or this fragment came after RTS/CTS.
*/
- if (test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) {
- txdesc->ifs = IFS_SIFS;
- } else if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) {
+ if ((tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) &&
+ !test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)) {
__set_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags);
txdesc->ifs = IFS_BACKOFF;
- } else {
+ } else
txdesc->ifs = IFS_SIFS;
- }
/*
- * Hardware should insert sequence counter.
- * FIXME: We insert a software sequence counter first for
- * hardware that doesn't support hardware sequence counting.
- *
- * This is wrong because beacons are not getting sequence
- * numbers assigned properly.
- *
- * A secondary problem exists for drivers that cannot toggle
- * sequence counting per-frame, since those will override the
- * sequence counter given by mac80211.
+ * Determine rate modulation.
*/
- if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
- if (likely(tx_info->control.vif)) {
- struct rt2x00_intf *intf;
-
- intf = vif_to_intf(tx_info->control.vif);
-
- spin_lock_irqsave(&intf->seqlock, irqflags);
-
- if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
- intf->seqno += 0x10;
- hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
- hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
-
- spin_unlock_irqrestore(&intf->seqlock, irqflags);
-
- __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
- }
- }
+ hwrate = rt2x00_get_rate(rate->hw_value);
+ txdesc->rate_mode = RATE_MODE_CCK;
+ if (hwrate->flags & DEV_RATE_OFDM)
+ txdesc->rate_mode = RATE_MODE_OFDM;
/*
- * PLCP setup
- * Length calculation depends on OFDM/CCK rate.
+ * Apply TX descriptor handling by components
*/
- hwrate = rt2x00_get_rate(rate->hw_value);
- txdesc->signal = hwrate->plcp;
- txdesc->service = 0x04;
-
- if (hwrate->flags & DEV_RATE_OFDM) {
- __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags);
-
- txdesc->length_high = (data_length >> 6) & 0x3f;
- txdesc->length_low = data_length & 0x3f;
- } else {
- /*
- * Convert length to microseconds.
- */
- residual = GET_DURATION_RES(data_length, hwrate->bitrate);
- duration = GET_DURATION(data_length, hwrate->bitrate);
-
- if (residual != 0) {
- duration++;
-
- /*
- * Check if we need to set the Length Extension
- */
- if (hwrate->bitrate == 110 && residual <= 30)
- txdesc->service |= 0x80;
- }
-
- txdesc->length_high = (duration >> 8) & 0xff;
- txdesc->length_low = duration & 0xff;
-
- /*
- * When preamble is enabled we should set the
- * preamble bit for the signal.
- */
- if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
- txdesc->signal |= 0x08;
- }
+ rt2x00crypto_create_tx_descriptor(entry, txdesc);
+ rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
+ rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
}
static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
@@ -403,7 +414,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
*/
if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
- if (test_bit(CONFIG_CRYPTO_COPY_IV, &queue->rt2x00dev->flags))
+ if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags))
rt2x00crypto_tx_copy_iv(skb, iv_len);
else
rt2x00crypto_tx_remove_iv(skb, iv_len);
@@ -432,7 +443,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
}
int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_vif *vif)
+ struct ieee80211_vif *vif,
+ const bool enable_beacon)
{
struct rt2x00_intf *intf = vif_to_intf(vif);
struct skb_frame_desc *skbdesc;
@@ -442,6 +454,11 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
if (unlikely(!intf->beacon))
return -ENOBUFS;
+ if (!enable_beacon) {
+ rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_BEACON);
+ return 0;
+ }
+
intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif);
if (!intf->beacon->skb)
return -ENOMEM;
@@ -490,6 +507,9 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
{
int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
+ if (queue == QID_RX)
+ return rt2x00dev->rx;
+
if (queue < rt2x00dev->ops->tx_queues && rt2x00dev->tx)
return &rt2x00dev->tx[queue];
@@ -566,6 +586,14 @@ static void rt2x00queue_reset(struct data_queue *queue)
spin_unlock_irqrestore(&queue->lock, irqflags);
}
+void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue;
+
+ txall_queue_for_each(rt2x00dev, queue)
+ rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, queue->qid);
+}
+
void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
{
struct data_queue *queue;
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 282937153408..97e2ab08f080 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -158,6 +158,14 @@ enum rxdone_entry_desc_flags {
};
/**
+ * RXDONE_SIGNAL_MASK - Define to mask off all &rxdone_entry_desc_flags flags
+ * except for the RXDONE_SIGNAL_* flags. This is useful to convert the dev_flags
+ * from &rxdone_entry_desc to a signal value type.
+ */
+#define RXDONE_SIGNAL_MASK \
+ ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE )
+
+/**
* struct rxdone_entry_desc: RX Entry descriptor
*
* Summary of information that has been read from the RX frame descriptor.
@@ -165,6 +173,7 @@ enum rxdone_entry_desc_flags {
* @timestamp: RX Timestamp
* @signal: Signal of the received frame.
* @rssi: RSSI of the received frame.
+ * @noise: Measured noise during frame reception.
* @size: Data size of the received frame.
* @flags: MAC80211 receive flags (See &enum mac80211_rx_flags).
* @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags).
@@ -177,6 +186,7 @@ struct rxdone_entry_desc {
u64 timestamp;
int signal;
int rssi;
+ int noise;
int size;
int flags;
int dev_flags;
@@ -222,7 +232,6 @@ struct txdone_entry_desc {
*
* @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame.
* @ENTRY_TXD_CTS_FRAME: This frame is a CTS-to-self frame.
- * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate.
* @ENTRY_TXD_GENERATE_SEQ: This frame requires sequence counter.
* @ENTRY_TXD_FIRST_FRAGMENT: This is the first frame.
* @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment.
@@ -238,7 +247,6 @@ struct txdone_entry_desc {
enum txentry_desc_flags {
ENTRY_TXD_RTS_FRAME,
ENTRY_TXD_CTS_FRAME,
- ENTRY_TXD_OFDM_RATE,
ENTRY_TXD_GENERATE_SEQ,
ENTRY_TXD_FIRST_FRAGMENT,
ENTRY_TXD_MORE_FRAG,
@@ -263,6 +271,7 @@ enum txentry_desc_flags {
* @length_low: PLCP length low word.
* @signal: PLCP signal.
* @service: PLCP service.
+ * @rate_mode: Rate mode (See @enum rate_modulation).
* @retry_limit: Max number of retries.
* @aifs: AIFS value.
* @ifs: IFS value.
@@ -282,6 +291,8 @@ struct txentry_desc {
u16 signal;
u16 service;
+ u16 rate_mode;
+
short retry_limit;
short aifs;
short ifs;
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index c2fba7c9f05c..861322d97fce 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -125,6 +125,26 @@ enum cipher {
};
/*
+ * Rate modulations
+ */
+enum rate_modulation {
+ RATE_MODE_CCK = 0,
+ RATE_MODE_OFDM = 1,
+ RATE_MODE_HT_MIX = 2,
+ RATE_MODE_HT_GREENFIELD = 3,
+};
+
+/*
+ * Firmware validation error codes
+ */
+enum firmware_errors {
+ FW_OK,
+ FW_BAD_CRC,
+ FW_BAD_LENGTH,
+ FW_BAD_VERSION,
+};
+
+/*
* Register handlers.
* We store the position of a register field inside a field structure,
* This will simplify the process of setting and reading a certain field
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index 3298cae1e12d..b6d4c6700bf3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -25,73 +25,30 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/rfkill.h>
#include "rt2x00.h"
#include "rt2x00lib.h"
-static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
+static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev)
{
- struct rt2x00_dev *rt2x00dev = data;
- int retval = 0;
-
- if (unlikely(!rt2x00dev))
- return 0;
-
- /*
- * Only continue if there are enabled interfaces.
- */
- if (!test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
- return 0;
-
- if (state == RFKILL_STATE_UNBLOCKED) {
- INFO(rt2x00dev, "RFKILL event: enabling radio.\n");
- clear_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags);
- retval = rt2x00lib_enable_radio(rt2x00dev);
- } else if (state == RFKILL_STATE_SOFT_BLOCKED) {
- INFO(rt2x00dev, "RFKILL event: disabling radio.\n");
- set_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags);
- rt2x00lib_disable_radio(rt2x00dev);
- } else {
- WARNING(rt2x00dev, "RFKILL event: unknown state %d.\n", state);
- }
-
- return retval;
-}
-
-static int rt2x00rfkill_get_state(void *data, enum rfkill_state *state)
-{
- struct rt2x00_dev *rt2x00dev = data;
-
- /*
- * rfkill_poll reports 1 when the key has been pressed and the
- * radio should be blocked.
- */
- *state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ?
- RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED;
-
- return 0;
-}
-
-static void rt2x00rfkill_poll(struct work_struct *work)
-{
- struct rt2x00_dev *rt2x00dev =
- container_of(work, struct rt2x00_dev, rfkill_work.work);
- enum rfkill_state state;
+ struct rt2x00_dev *rt2x00dev = poll_dev->private;
+ int state, old_state;
if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state) ||
!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
return;
/*
- * Poll latest state and report it to rfkill who should sort
- * out if the state should be toggled or not.
+ * Poll latest state, if the state is different then the previous state,
+ * we should generate an input event.
*/
- if (!rt2x00rfkill_get_state(rt2x00dev, &state))
- rfkill_force_state(rt2x00dev->rfkill, state);
+ state = !!rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
+ old_state = !!test_bit(RFKILL_STATE_BLOCKED, &rt2x00dev->rfkill_state);
- queue_delayed_work(rt2x00dev->hw->workqueue,
- &rt2x00dev->rfkill_work, RFKILL_POLL_INTERVAL);
+ if (old_state != state) {
+ input_report_switch(poll_dev->input, SW_RFKILL_ALL, state);
+ change_bit(RFKILL_STATE_BLOCKED, &rt2x00dev->rfkill_state);
+ }
}
void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
@@ -100,8 +57,8 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
return;
- if (rfkill_register(rt2x00dev->rfkill)) {
- ERROR(rt2x00dev, "Failed to register rfkill handler.\n");
+ if (input_register_polled_device(rt2x00dev->rfkill_poll_dev)) {
+ ERROR(rt2x00dev, "Failed to register polled device.\n");
return;
}
@@ -109,10 +66,10 @@ void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
/*
* Force initial poll which will detect the initial device state,
- * and correctly sends the signal to the rfkill layer about this
+ * and correctly sends the signal to the input layer about this
* state.
*/
- rt2x00rfkill_poll(&rt2x00dev->rfkill_work.work);
+ rt2x00rfkill_poll(rt2x00dev->rfkill_poll_dev);
}
void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
@@ -121,52 +78,50 @@ void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
return;
- cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
-
- rfkill_unregister(rt2x00dev->rfkill);
+ input_unregister_polled_device(rt2x00dev->rfkill_poll_dev);
__clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
}
void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
{
- struct device *dev = wiphy_dev(rt2x00dev->hw->wiphy);
+ struct input_polled_dev *poll_dev;
- if (test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
+ if (test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state) ||
+ !test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
return;
- rt2x00dev->rfkill = rfkill_allocate(dev, RFKILL_TYPE_WLAN);
- if (!rt2x00dev->rfkill) {
- ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n");
+ poll_dev = input_allocate_polled_device();
+ if (!poll_dev) {
+ ERROR(rt2x00dev, "Failed to allocate polled device.\n");
return;
}
- __set_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state);
+ poll_dev->private = rt2x00dev;
+ poll_dev->poll = rt2x00rfkill_poll;
+ poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
- rt2x00dev->rfkill->name = rt2x00dev->ops->name;
- rt2x00dev->rfkill->data = rt2x00dev;
- rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
- if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) {
- rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state;
- rt2x00dev->rfkill->state =
- rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ?
- RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED;
- } else {
- rt2x00dev->rfkill->state = RFKILL_STATE_UNBLOCKED;
- }
+ poll_dev->input->name = rt2x00dev->ops->name;
+ poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy);
+ poll_dev->input->id.bustype = BUS_HOST;
+ poll_dev->input->id.vendor = 0x1814;
+ poll_dev->input->id.product = rt2x00dev->chip.rt;
+ poll_dev->input->id.version = rt2x00dev->chip.rev;
+ poll_dev->input->dev.parent = wiphy_dev(rt2x00dev->hw->wiphy);
+ poll_dev->input->evbit[0] = BIT(EV_SW);
+ poll_dev->input->swbit[0] = BIT(SW_RFKILL_ALL);
- INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll);
+ rt2x00dev->rfkill_poll_dev = poll_dev;
- return;
+ __set_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state);
}
void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
{
- if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state))
+ if (!__test_and_clear_bit(RFKILL_STATE_ALLOCATED,
+ &rt2x00dev->rfkill_state))
return;
- cancel_delayed_work_sync(&rt2x00dev->rfkill_work);
-
- rfkill_free(rt2x00dev->rfkill);
- rt2x00dev->rfkill = NULL;
+ input_free_polled_device(rt2x00dev->rfkill_poll_dev);
+ rt2x00dev->rfkill_poll_dev = NULL;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 0b29d767a258..7d50ca82375e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -296,6 +296,41 @@ void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
}
EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);
+void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid)
+{
+ struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid);
+ struct queue_entry_priv_usb *entry_priv;
+ struct queue_entry_priv_usb_bcn *bcn_priv;
+ unsigned int i;
+ bool kill_guard;
+
+ /*
+ * When killing the beacon queue, we must also kill
+ * the beacon guard byte.
+ */
+ kill_guard =
+ (qid == QID_BEACON) &&
+ (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags));
+
+ /*
+ * Cancel all entries.
+ */
+ for (i = 0; i < queue->limit; i++) {
+ entry_priv = queue->entries[i].priv_data;
+ usb_kill_urb(entry_priv->urb);
+
+ /*
+ * Kill guardian urb (if required by driver).
+ */
+ if (kill_guard) {
+ bcn_priv = queue->entries[i].priv_data;
+ usb_kill_urb(bcn_priv->guardian_urb);
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue);
+
/*
* RX data handlers.
*/
@@ -338,35 +373,14 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
*/
void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
{
- struct queue_entry_priv_usb *entry_priv;
- struct queue_entry_priv_usb_bcn *bcn_priv;
- struct data_queue *queue;
- unsigned int i;
-
rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0,
REGISTER_TIMEOUT);
/*
- * Cancel all queues.
+ * The USB version of kill_tx_queue also works
+ * on the RX queue.
*/
- queue_for_each(rt2x00dev, queue) {
- for (i = 0; i < queue->limit; i++) {
- entry_priv = queue->entries[i].priv_data;
- usb_kill_urb(entry_priv->urb);
- }
- }
-
- /*
- * Kill guardian urb (if required by driver).
- */
- if (!test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
- return;
-
- for (i = 0; i < rt2x00dev->bcn->limit; i++) {
- bcn_priv = rt2x00dev->bcn->entries[i].priv_data;
- if (bcn_priv->guardian_urb)
- usb_kill_urb(bcn_priv->guardian_urb);
- }
+ rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_RX);
}
EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 2bd4ac855f52..bd2d59c85f1b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -419,6 +419,17 @@ struct queue_entry_priv_usb_bcn {
void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
const enum data_queue_qid qid);
+/**
+ * rt2x00usb_kill_tx_queue - Kill data queue
+ * @rt2x00dev: Pointer to &struct rt2x00_dev
+ * @qid: Data queue to kill
+ *
+ * This will walk through all entries of the queue and kill all
+ * previously kicked frames before they can be send.
+ */
+void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid);
+
/*
* Device initialization handlers.
*/
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 987e89009f74..2ca8b7a9722c 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -123,9 +123,6 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
- if (!word)
- return;
-
mutex_lock(&rt2x00dev->csr_mutex);
/*
@@ -146,12 +143,6 @@ static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
mutex_unlock(&rt2x00dev->csr_mutex);
}
-#ifdef CONFIG_RT2X00_LIB_LEDS
-/*
- * This function is only called from rt61pci_led_brightness()
- * make gcc happy by placing this function inside the
- * same ifdef statement as the caller.
- */
static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
const u8 command, const u8 token,
const u8 arg0, const u8 arg1)
@@ -180,7 +171,6 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
mutex_unlock(&rt2x00dev->csr_mutex);
}
-#endif /* CONFIG_RT2X00_LIB_LEDS */
static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
{
@@ -967,6 +957,50 @@ static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
}
+static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf)
+{
+ enum dev_state state =
+ (libconf->conf->flags & IEEE80211_CONF_PS) ?
+ STATE_SLEEP : STATE_AWAKE;
+ u32 reg;
+
+ if (state == STATE_SLEEP) {
+ rt2x00pci_register_read(rt2x00dev, MAC_CSR11, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
+ libconf->conf->beacon_int - 10);
+ rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
+ libconf->conf->listen_interval - 1);
+ rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
+
+ /* We must first disable autowake before it can be enabled */
+ rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg);
+
+ rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 1);
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg);
+
+ rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000005);
+ rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x0000001c);
+ rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000060);
+
+ rt61pci_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 0);
+ } else {
+ rt2x00pci_register_read(rt2x00dev, MAC_CSR11, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 0);
+ rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0);
+ rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+ rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 0);
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR11, reg);
+
+ rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000007);
+ rt2x00pci_register_write(rt2x00dev, IO_CNTL_CSR, 0x00000018);
+ rt2x00pci_register_write(rt2x00dev, PCI_USEC_CSR, 0x00000020);
+
+ rt61pci_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
+ }
+}
+
static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int flags)
@@ -984,6 +1018,8 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
rt61pci_config_retry_limit(rt2x00dev, libconf);
if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
rt61pci_config_duration(rt2x00dev, libconf);
+ if (flags & IEEE80211_CONF_CHANGE_PS)
+ rt61pci_config_ps(rt2x00dev, libconf);
}
/*
@@ -1007,21 +1043,28 @@ static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
}
-static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static inline void rt61pci_set_vgc(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, u8 vgc_level)
+{
+ if (qual->vgc_level != vgc_level) {
+ rt61pci_bbp_write(rt2x00dev, 17, vgc_level);
+ qual->vgc_level = vgc_level;
+ qual->vgc_level_reg = vgc_level;
+ }
+}
+
+static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
- rt61pci_bbp_write(rt2x00dev, 17, 0x20);
- rt2x00dev->link.vgc_level = 0x20;
+ rt61pci_set_vgc(rt2x00dev, qual, 0x20);
}
-static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, const u32 count)
{
- int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
- u8 r17;
u8 up_bound;
u8 low_bound;
- rt61pci_bbp_read(rt2x00dev, 17, &r17);
-
/*
* Determine r17 bounds.
*/
@@ -1051,38 +1094,32 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
/*
* Special big-R17 for very short distance
*/
- if (rssi >= -35) {
- if (r17 != 0x60)
- rt61pci_bbp_write(rt2x00dev, 17, 0x60);
+ if (qual->rssi >= -35) {
+ rt61pci_set_vgc(rt2x00dev, qual, 0x60);
return;
}
/*
* Special big-R17 for short distance
*/
- if (rssi >= -58) {
- if (r17 != up_bound)
- rt61pci_bbp_write(rt2x00dev, 17, up_bound);
+ if (qual->rssi >= -58) {
+ rt61pci_set_vgc(rt2x00dev, qual, up_bound);
return;
}
/*
* Special big-R17 for middle-short distance
*/
- if (rssi >= -66) {
- low_bound += 0x10;
- if (r17 != low_bound)
- rt61pci_bbp_write(rt2x00dev, 17, low_bound);
+ if (qual->rssi >= -66) {
+ rt61pci_set_vgc(rt2x00dev, qual, low_bound + 0x10);
return;
}
/*
* Special mid-R17 for middle distance
*/
- if (rssi >= -74) {
- low_bound += 0x08;
- if (r17 != low_bound)
- rt61pci_bbp_write(rt2x00dev, 17, low_bound);
+ if (qual->rssi >= -74) {
+ rt61pci_set_vgc(rt2x00dev, qual, low_bound + 0x08);
return;
}
@@ -1090,12 +1127,12 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special case: Change up_bound based on the rssi.
* Lower up_bound when rssi is weaker then -74 dBm.
*/
- up_bound -= 2 * (-74 - rssi);
+ up_bound -= 2 * (-74 - qual->rssi);
if (low_bound > up_bound)
up_bound = low_bound;
- if (r17 > up_bound) {
- rt61pci_bbp_write(rt2x00dev, 17, up_bound);
+ if (qual->vgc_level > up_bound) {
+ rt61pci_set_vgc(rt2x00dev, qual, up_bound);
return;
}
@@ -1105,15 +1142,10 @@ dynamic_cca_tune:
* r17 does not yet exceed upper limit, continue and base
* the r17 tuning on the false CCA count.
*/
- if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
- if (++r17 > up_bound)
- r17 = up_bound;
- rt61pci_bbp_write(rt2x00dev, 17, r17);
- } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
- if (--r17 < low_bound)
- r17 = low_bound;
- rt61pci_bbp_write(rt2x00dev, 17, r17);
- }
+ if ((qual->false_cca > 512) && (qual->vgc_level < up_bound))
+ rt61pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level);
+ else if ((qual->false_cca < 100) && (qual->vgc_level > low_bound))
+ rt61pci_set_vgc(rt2x00dev, qual, --qual->vgc_level);
}
/*
@@ -1141,25 +1173,37 @@ static char *rt61pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
return fw_name;
}
-static u16 rt61pci_get_firmware_crc(const void *data, const size_t len)
+static int rt61pci_check_firmware(struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len)
{
+ u16 fw_crc;
u16 crc;
/*
- * Use the crc itu-t algorithm.
+ * Only support 8kb firmware files.
+ */
+ if (len != 8192)
+ return FW_BAD_LENGTH;
+
+ /*
* The last 2 bytes in the firmware array are the crc checksum itself,
* this means that we should never pass those 2 bytes to the crc
* algorithm.
*/
+ fw_crc = (data[len - 2] << 8 | data[len - 1]);
+
+ /*
+ * Use the crc itu-t algorithm.
+ */
crc = crc_itu_t(0, data, len - 2);
crc = crc_itu_t_byte(crc, 0);
crc = crc_itu_t_byte(crc, 0);
- return crc;
+ return (fw_crc == crc) ? FW_OK : FW_BAD_CRC;
}
-static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
- const size_t len)
+static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len)
{
int i;
u32 reg;
@@ -1656,24 +1700,10 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev)
static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev)
{
- u32 reg;
-
- rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818);
-
/*
- * Disable synchronisation.
+ * Disable power
*/
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
-
- /*
- * Cancel RX and TX.
- */
- rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, 1);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, 1);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, 1);
- rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, 1);
- rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+ rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818);
}
static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
@@ -1812,7 +1842,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_OFDM,
- test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
+ (txdesc->rate_mode == RATE_MODE_OFDM));
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
@@ -1896,6 +1926,24 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
}
+static void rt61pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev,
+ const enum data_queue_qid qid)
+{
+ u32 reg;
+
+ if (qid == QID_BEACON) {
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
+ return;
+ }
+
+ rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC0, (qid == QID_AC_BE));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC1, (qid == QID_AC_BK));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC2, (qid == QID_AC_VI));
+ rt2x00_set_field32(&reg, TX_CNTL_CSR_ABORT_TX_AC3, (qid == QID_AC_VO));
+ rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
+}
+
/*
* RX control handlers
*/
@@ -2195,7 +2243,8 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
if (word == 0xffff) {
rt2x00_set_field16(&word, EEPROM_NIC_ENABLE_DIVERSITY, 0);
rt2x00_set_field16(&word, EEPROM_NIC_TX_DIVERSITY, 0);
- rt2x00_set_field16(&word, EEPROM_NIC_TX_RX_FIXED, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_RX_FIXED, 0);
+ rt2x00_set_field16(&word, EEPROM_NIC_TX_FIXED, 0);
rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0);
rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0);
@@ -2339,24 +2388,10 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
*/
if (rt2x00_rf(&rt2x00dev->chip, RF2529) &&
!test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) {
- switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
- case 0:
- rt2x00dev->default_ant.tx = ANTENNA_B;
- rt2x00dev->default_ant.rx = ANTENNA_A;
- break;
- case 1:
- rt2x00dev->default_ant.tx = ANTENNA_B;
- rt2x00dev->default_ant.rx = ANTENNA_B;
- break;
- case 2:
- rt2x00dev->default_ant.tx = ANTENNA_A;
- rt2x00dev->default_ant.rx = ANTENNA_A;
- break;
- case 3:
- rt2x00dev->default_ant.tx = ANTENNA_A;
- rt2x00dev->default_ant.rx = ANTENNA_B;
- break;
- }
+ rt2x00dev->default_ant.rx =
+ ANTENNA_A + rt2x00_get_field16(eeprom, EEPROM_NIC_RX_FIXED);
+ rt2x00dev->default_ant.tx =
+ ANTENNA_B - rt2x00_get_field16(eeprom, EEPROM_NIC_TX_FIXED);
if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY))
rt2x00dev->default_ant.tx = ANTENNA_SW_DIVERSITY;
@@ -2534,7 +2569,9 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->hw->flags =
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK;
rt2x00dev->hw->extra_tx_headroom = 0;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
@@ -2633,6 +2670,7 @@ static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
struct rt2x00_field32 field;
int retval;
u32 reg;
+ u32 offset;
/*
* First pass the configuration through rt2x00lib, that will
@@ -2644,24 +2682,23 @@ static int rt61pci_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
if (retval)
return retval;
+ /*
+ * We only need to perform additional register initialization
+ * for WMM queues/
+ */
+ if (queue_idx >= 4)
+ return 0;
+
queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
/* Update WMM TXOP register */
- if (queue_idx < 2) {
- field.bit_offset = queue_idx * 16;
- field.bit_mask = 0xffff << field.bit_offset;
-
- rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR0, &reg);
- rt2x00_set_field32(&reg, field, queue->txop);
- rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
- } else if (queue_idx < 4) {
- field.bit_offset = (queue_idx - 2) * 16;
- field.bit_mask = 0xffff << field.bit_offset;
-
- rt2x00pci_register_read(rt2x00dev, AC_TXOP_CSR1, &reg);
- rt2x00_set_field32(&reg, field, queue->txop);
- rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
- }
+ offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2)));
+ field.bit_offset = (queue_idx & 1) * 16;
+ field.bit_mask = 0xffff << field.bit_offset;
+
+ rt2x00pci_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, field, queue->txop);
+ rt2x00pci_register_write(rt2x00dev, offset, reg);
/* Update WMM registers */
field.bit_offset = queue_idx * 4;
@@ -2717,7 +2754,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
.irq_handler = rt61pci_interrupt,
.probe_hw = rt61pci_probe_hw,
.get_firmware_name = rt61pci_get_firmware_name,
- .get_firmware_crc = rt61pci_get_firmware_crc,
+ .check_firmware = rt61pci_check_firmware,
.load_firmware = rt61pci_load_firmware,
.initialize = rt2x00pci_initialize,
.uninitialize = rt2x00pci_uninitialize,
@@ -2732,6 +2769,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
.write_tx_data = rt2x00pci_write_tx_data,
.write_beacon = rt61pci_write_beacon,
.kick_tx_queue = rt61pci_kick_tx_queue,
+ .kill_tx_queue = rt61pci_kill_tx_queue,
.fill_rxdone = rt61pci_fill_rxdone,
.config_shared_key = rt61pci_config_shared_key,
.config_pairwise_key = rt61pci_config_pairwise_key,
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 65fe3332364a..41e8959919f6 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -50,8 +50,8 @@
#define EEPROM_SIZE 0x0100
#define BBP_BASE 0x0000
#define BBP_SIZE 0x0080
-#define RF_BASE 0x0000
-#define RF_SIZE 0x0014
+#define RF_BASE 0x0004
+#define RF_SIZE 0x0010
/*
* Number of TX queues.
@@ -88,8 +88,10 @@
/*
* SOFT_RESET_CSR
+ * FORCE_CLOCK_ON: Host force MAC clock ON
*/
#define SOFT_RESET_CSR 0x0010
+#define SOFT_RESET_CSR_FORCE_CLOCK_ON FIELD32(0x00000002)
/*
* MCU_INT_SOURCE_CSR: MCU interrupt source/mask register.
@@ -1054,8 +1056,10 @@ struct hw_pairwise_ta_entry {
/*
* IO_CNTL_CSR
+ * RF_PS: Set RF interface value to power save
*/
#define IO_CNTL_CSR 0x3498
+#define IO_CNTL_CSR_RF_PS FIELD32(0x00000004)
/*
* UART_INT_SOURCE_CSR
@@ -1186,7 +1190,8 @@ struct hw_pairwise_ta_entry {
#define EEPROM_NIC 0x0011
#define EEPROM_NIC_ENABLE_DIVERSITY FIELD16(0x0001)
#define EEPROM_NIC_TX_DIVERSITY FIELD16(0x0002)
-#define EEPROM_NIC_TX_RX_FIXED FIELD16(0x000c)
+#define EEPROM_NIC_RX_FIXED FIELD16(0x0004)
+#define EEPROM_NIC_TX_FIXED FIELD16(0x0008)
#define EEPROM_NIC_EXTERNAL_LNA_BG FIELD16(0x0010)
#define EEPROM_NIC_CARDBUS_ACCEL FIELD16(0x0020)
#define EEPROM_NIC_EXTERNAL_LNA_A FIELD16(0x0040)
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index cefee1b26cd8..420fff42c0dd 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -122,9 +122,6 @@ static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
{
u32 reg;
- if (!word)
- return;
-
mutex_lock(&rt2x00dev->csr_mutex);
/*
@@ -186,6 +183,18 @@ static const struct rt2x00debug rt73usb_rt2x00debug = {
};
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+ u32 reg;
+
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR13, &reg);
+ return rt2x00_get_field32(reg, MAC_CSR13_BIT7);
+}
+#else
+#define rt73usb_rfkill_poll NULL
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
#ifdef CONFIG_RT2X00_LIB_LEDS
static void rt73usb_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
@@ -844,6 +853,44 @@ static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
}
+static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
+ struct rt2x00lib_conf *libconf)
+{
+ enum dev_state state =
+ (libconf->conf->flags & IEEE80211_CONF_PS) ?
+ STATE_SLEEP : STATE_AWAKE;
+ u32 reg;
+
+ if (state == STATE_SLEEP) {
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
+ libconf->conf->beacon_int - 10);
+ rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
+ libconf->conf->listen_interval - 1);
+ rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
+
+ /* We must first disable autowake before it can be enabled */
+ rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+ rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
+
+ rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 1);
+ rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
+
+ rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+ USB_MODE_SLEEP, REGISTER_TIMEOUT);
+ } else {
+ rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+ USB_MODE_WAKEUP, REGISTER_TIMEOUT);
+
+ rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
+ rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 0);
+ rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 0);
+ rt2x00_set_field32(&reg, MAC_CSR11_AUTOWAKE, 0);
+ rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 0);
+ rt2x00usb_register_write(rt2x00dev, MAC_CSR11, reg);
+ }
+}
+
static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf,
const unsigned int flags)
@@ -861,6 +908,8 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
rt73usb_config_retry_limit(rt2x00dev, libconf);
if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
rt73usb_config_duration(rt2x00dev, libconf);
+ if (flags & IEEE80211_CONF_CHANGE_PS)
+ rt73usb_config_ps(rt2x00dev, libconf);
}
/*
@@ -884,21 +933,28 @@ static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev,
qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
}
-static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
+static inline void rt73usb_set_vgc(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, u8 vgc_level)
+{
+ if (qual->vgc_level != vgc_level) {
+ rt73usb_bbp_write(rt2x00dev, 17, vgc_level);
+ qual->vgc_level = vgc_level;
+ qual->vgc_level_reg = vgc_level;
+ }
+}
+
+static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual)
{
- rt73usb_bbp_write(rt2x00dev, 17, 0x20);
- rt2x00dev->link.vgc_level = 0x20;
+ rt73usb_set_vgc(rt2x00dev, qual, 0x20);
}
-static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
+static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev,
+ struct link_qual *qual, const u32 count)
{
- int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
- u8 r17;
u8 up_bound;
u8 low_bound;
- rt73usb_bbp_read(rt2x00dev, 17, &r17);
-
/*
* Determine r17 bounds.
*/
@@ -911,10 +967,10 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
up_bound += 0x10;
}
} else {
- if (rssi > -82) {
+ if (qual->rssi > -82) {
low_bound = 0x1c;
up_bound = 0x40;
- } else if (rssi > -84) {
+ } else if (qual->rssi > -84) {
low_bound = 0x1c;
up_bound = 0x20;
} else {
@@ -938,37 +994,32 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
/*
* Special big-R17 for very short distance
*/
- if (rssi > -35) {
- if (r17 != 0x60)
- rt73usb_bbp_write(rt2x00dev, 17, 0x60);
+ if (qual->rssi > -35) {
+ rt73usb_set_vgc(rt2x00dev, qual, 0x60);
return;
}
/*
* Special big-R17 for short distance
*/
- if (rssi >= -58) {
- if (r17 != up_bound)
- rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+ if (qual->rssi >= -58) {
+ rt73usb_set_vgc(rt2x00dev, qual, up_bound);
return;
}
/*
* Special big-R17 for middle-short distance
*/
- if (rssi >= -66) {
- low_bound += 0x10;
- if (r17 != low_bound)
- rt73usb_bbp_write(rt2x00dev, 17, low_bound);
+ if (qual->rssi >= -66) {
+ rt73usb_set_vgc(rt2x00dev, qual, low_bound + 0x10);
return;
}
/*
* Special mid-R17 for middle distance
*/
- if (rssi >= -74) {
- if (r17 != (low_bound + 0x10))
- rt73usb_bbp_write(rt2x00dev, 17, low_bound + 0x08);
+ if (qual->rssi >= -74) {
+ rt73usb_set_vgc(rt2x00dev, qual, low_bound + 0x08);
return;
}
@@ -976,12 +1027,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
* Special case: Change up_bound based on the rssi.
* Lower up_bound when rssi is weaker then -74 dBm.
*/
- up_bound -= 2 * (-74 - rssi);
+ up_bound -= 2 * (-74 - qual->rssi);
if (low_bound > up_bound)
up_bound = low_bound;
- if (r17 > up_bound) {
- rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+ if (qual->vgc_level > up_bound) {
+ rt73usb_set_vgc(rt2x00dev, qual, up_bound);
return;
}
@@ -991,17 +1042,12 @@ dynamic_cca_tune:
* r17 does not yet exceed upper limit, continue and base
* the r17 tuning on the false CCA count.
*/
- if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
- r17 += 4;
- if (r17 > up_bound)
- r17 = up_bound;
- rt73usb_bbp_write(rt2x00dev, 17, r17);
- } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
- r17 -= 4;
- if (r17 < low_bound)
- r17 = low_bound;
- rt73usb_bbp_write(rt2x00dev, 17, r17);
- }
+ if ((qual->false_cca > 512) && (qual->vgc_level < up_bound))
+ rt73usb_set_vgc(rt2x00dev, qual,
+ min_t(u8, qual->vgc_level + 4, up_bound));
+ else if ((qual->false_cca < 100) && (qual->vgc_level > low_bound))
+ rt73usb_set_vgc(rt2x00dev, qual,
+ max_t(u8, qual->vgc_level - 4, low_bound));
}
/*
@@ -1012,25 +1058,37 @@ static char *rt73usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
return FIRMWARE_RT2571;
}
-static u16 rt73usb_get_firmware_crc(const void *data, const size_t len)
+static int rt73usb_check_firmware(struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len)
{
+ u16 fw_crc;
u16 crc;
/*
- * Use the crc itu-t algorithm.
+ * Only support 2kb firmware files.
+ */
+ if (len != 2048)
+ return FW_BAD_LENGTH;
+
+ /*
* The last 2 bytes in the firmware array are the crc checksum itself,
* this means that we should never pass those 2 bytes to the crc
* algorithm.
*/
+ fw_crc = (data[len - 2] << 8 | data[len - 1]);
+
+ /*
+ * Use the crc itu-t algorithm.
+ */
crc = crc_itu_t(0, data, len - 2);
crc = crc_itu_t_byte(crc, 0);
crc = crc_itu_t_byte(crc, 0);
- return crc;
+ return (fw_crc == crc) ? FW_OK : FW_BAD_CRC;
}
-static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
- const size_t len)
+static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev,
+ const u8 *data, const size_t len)
{
unsigned int i;
int status;
@@ -1449,7 +1507,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W0_OFDM,
- test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags));
+ (txdesc->rate_mode == RATE_MODE_OFDM));
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
@@ -1816,6 +1874,14 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
__set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
/*
+ * Detect if this device has an hardware controlled radio.
+ */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
+ __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
+ /*
* Read frequency offset.
*/
rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
@@ -2020,7 +2086,9 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->hw->flags =
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_SIGNAL_DBM;
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK;
rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
@@ -2121,6 +2189,7 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
struct rt2x00_field32 field;
int retval;
u32 reg;
+ u32 offset;
/*
* First pass the configuration through rt2x00lib, that will
@@ -2132,24 +2201,23 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
if (retval)
return retval;
+ /*
+ * We only need to perform additional register initialization
+ * for WMM queues/
+ */
+ if (queue_idx >= 4)
+ return 0;
+
queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
/* Update WMM TXOP register */
- if (queue_idx < 2) {
- field.bit_offset = queue_idx * 16;
- field.bit_mask = 0xffff << field.bit_offset;
-
- rt2x00usb_register_read(rt2x00dev, AC_TXOP_CSR0, &reg);
- rt2x00_set_field32(&reg, field, queue->txop);
- rt2x00usb_register_write(rt2x00dev, AC_TXOP_CSR0, reg);
- } else if (queue_idx < 4) {
- field.bit_offset = (queue_idx - 2) * 16;
- field.bit_mask = 0xffff << field.bit_offset;
-
- rt2x00usb_register_read(rt2x00dev, AC_TXOP_CSR1, &reg);
- rt2x00_set_field32(&reg, field, queue->txop);
- rt2x00usb_register_write(rt2x00dev, AC_TXOP_CSR1, reg);
- }
+ offset = AC_TXOP_CSR0 + (sizeof(u32) * (!!(queue_idx & 2)));
+ field.bit_offset = (queue_idx & 1) * 16;
+ field.bit_mask = 0xffff << field.bit_offset;
+
+ rt2x00usb_register_read(rt2x00dev, offset, &reg);
+ rt2x00_set_field32(&reg, field, queue->txop);
+ rt2x00usb_register_write(rt2x00dev, offset, reg);
/* Update WMM registers */
field.bit_offset = queue_idx * 4;
@@ -2170,13 +2238,6 @@ static int rt73usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
return 0;
}
-#if 0
-/*
- * Mac80211 demands get_tsf must be atomic.
- * This is not possible for rt73usb since all register access
- * functions require sleeping. Untill mac80211 no longer needs
- * get_tsf to be atomic, this function should be disabled.
- */
static u64 rt73usb_get_tsf(struct ieee80211_hw *hw)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -2190,9 +2251,6 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw)
return tsf;
}
-#else
-#define rt73usb_get_tsf NULL
-#endif
static const struct ieee80211_ops rt73usb_mac80211_ops = {
.tx = rt2x00mac_tx,
@@ -2214,12 +2272,13 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.probe_hw = rt73usb_probe_hw,
.get_firmware_name = rt73usb_get_firmware_name,
- .get_firmware_crc = rt73usb_get_firmware_crc,
+ .check_firmware = rt73usb_check_firmware,
.load_firmware = rt73usb_load_firmware,
.initialize = rt2x00usb_initialize,
.uninitialize = rt2x00usb_uninitialize,
.clear_entry = rt2x00usb_clear_entry,
.set_device_state = rt73usb_set_device_state,
+ .rfkill_poll = rt73usb_rfkill_poll,
.link_stats = rt73usb_link_stats,
.reset_tuner = rt73usb_reset_tuner,
.link_tuner = rt73usb_link_tuner,
@@ -2228,6 +2287,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.write_beacon = rt73usb_write_beacon,
.get_tx_data_len = rt73usb_get_tx_data_len,
.kick_tx_queue = rt73usb_kick_tx_queue,
+ .kill_tx_queue = rt2x00usb_kill_tx_queue,
.fill_rxdone = rt73usb_fill_rxdone,
.config_shared_key = rt73usb_config_shared_key,
.config_pairwise_key = rt73usb_config_pairwise_key,
@@ -2365,6 +2425,8 @@ static struct usb_device_id rt73usb_device_table[] = {
{ USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) },
/* Surecom */
{ USB_DEVICE(0x0769, 0x31f3), USB_DEVICE_DATA(&rt73usb_ops) },
+ /* Tilgin */
+ { USB_DEVICE(0x6933, 0x5001), USB_DEVICE_DATA(&rt73usb_ops) },
/* Philips */
{ USB_DEVICE(0x0471, 0x200a), USB_DEVICE_DATA(&rt73usb_ops) },
/* Planex */
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 46e1405eb0e2..c8016f65b4bd 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2004 - 2008 rt2x00 SourceForge Project
+ Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
<http://rt2x00.serialmonkey.com>
This program is free software; you can redistribute it and/or modify
@@ -50,8 +50,8 @@
#define EEPROM_SIZE 0x0100
#define BBP_BASE 0x0000
#define BBP_SIZE 0x0080
-#define RF_BASE 0x0000
-#define RF_SIZE 0x0014
+#define RF_BASE 0x0004
+#define RF_SIZE 0x0010
/*
* Number of TX queues.
@@ -267,6 +267,19 @@ struct hw_pairwise_ta_entry {
* MAC_CSR13: GPIO.
*/
#define MAC_CSR13 0x3034
+#define MAC_CSR13_BIT0 FIELD32(0x00000001)
+#define MAC_CSR13_BIT1 FIELD32(0x00000002)
+#define MAC_CSR13_BIT2 FIELD32(0x00000004)
+#define MAC_CSR13_BIT3 FIELD32(0x00000008)
+#define MAC_CSR13_BIT4 FIELD32(0x00000010)
+#define MAC_CSR13_BIT5 FIELD32(0x00000020)
+#define MAC_CSR13_BIT6 FIELD32(0x00000040)
+#define MAC_CSR13_BIT7 FIELD32(0x00000080)
+#define MAC_CSR13_BIT8 FIELD32(0x00000100)
+#define MAC_CSR13_BIT9 FIELD32(0x00000200)
+#define MAC_CSR13_BIT10 FIELD32(0x00000400)
+#define MAC_CSR13_BIT11 FIELD32(0x00000800)
+#define MAC_CSR13_BIT12 FIELD32(0x00001000)
/*
* MAC_CSR14: LED control register.
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h
index 3b1e1c2aad26..9718f61809cf 100644
--- a/drivers/net/wireless/rtl818x/rtl8187.h
+++ b/drivers/net/wireless/rtl818x/rtl8187.h
@@ -100,6 +100,8 @@ struct rtl8187_priv {
struct usb_device *udev;
u32 rx_conf;
struct usb_anchor anchored;
+ struct delayed_work work;
+ struct ieee80211_hw *dev;
u16 txpwr_base;
u8 asic_rev;
u8 is_rtl8187b;
@@ -117,7 +119,7 @@ struct rtl8187_priv {
struct {
__le64 buf;
struct sk_buff_head queue;
- } b_tx_status;
+ } b_tx_status; /* This queue is used by both -b and non-b devices */
};
void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index f4747a1134ba..fd81884b9c7d 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -189,25 +189,33 @@ static void rtl8187_tx_cb(struct urb *urb)
sizeof(struct rtl8187_tx_hdr));
ieee80211_tx_info_clear_status(info);
- if (!urb->status &&
- !(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
- priv->is_rtl8187b) {
- skb_queue_tail(&priv->b_tx_status.queue, skb);
+ if (!(urb->status) && !(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+ if (priv->is_rtl8187b) {
+ skb_queue_tail(&priv->b_tx_status.queue, skb);
- /* queue is "full", discard last items */
- while (skb_queue_len(&priv->b_tx_status.queue) > 5) {
- struct sk_buff *old_skb;
+ /* queue is "full", discard last items */
+ while (skb_queue_len(&priv->b_tx_status.queue) > 5) {
+ struct sk_buff *old_skb;
- dev_dbg(&priv->udev->dev,
- "transmit status queue full\n");
+ dev_dbg(&priv->udev->dev,
+ "transmit status queue full\n");
- old_skb = skb_dequeue(&priv->b_tx_status.queue);
- ieee80211_tx_status_irqsafe(hw, old_skb);
- }
- } else {
- if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && !urb->status)
+ old_skb = skb_dequeue(&priv->b_tx_status.queue);
+ ieee80211_tx_status_irqsafe(hw, old_skb);
+ }
+ return;
+ } else {
info->flags |= IEEE80211_TX_STAT_ACK;
+ }
+ }
+ if (priv->is_rtl8187b)
ieee80211_tx_status_irqsafe(hw, skb);
+ else {
+ /* Retry information for the RTI8187 is only available by
+ * reading a register in the device. We are in interrupt mode
+ * here, thus queue the skb and finish on a work queue. */
+ skb_queue_tail(&priv->b_tx_status.queue, skb);
+ queue_delayed_work(hw->workqueue, &priv->work, 0);
}
}
@@ -403,7 +411,7 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
struct rtl8187_rx_info *info;
int ret = 0;
- while (skb_queue_len(&priv->rx_queue) < 8) {
+ while (skb_queue_len(&priv->rx_queue) < 16) {
skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
if (!skb) {
ret = -ENOMEM;
@@ -657,7 +665,7 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
- rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81);
+ rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0);
// TODO: set RESP_RATE and BRSR properly
rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
@@ -777,9 +785,6 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
rtl818x_iowrite16_idx(priv, (__le16 *)0xFFE0, 0x0FFF, 1);
- reg = rtl818x_ioread8(priv, &priv->map->RATE_FALLBACK);
- reg |= RTL818X_RATE_FALLBACK_ENABLE;
- rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, reg);
rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
rtl818x_iowrite16(priv, &priv->map->ATIM_WND, 2);
@@ -867,6 +872,34 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
return 0;
}
+static void rtl8187_work(struct work_struct *work)
+{
+ /* The RTL8187 returns the retry count through register 0xFFFA. In
+ * addition, it appears to be a cumulative retry count, not the
+ * value for the current TX packet. When multiple TX entries are
+ * queued, the retry count will be valid for the last one in the queue.
+ * The "error" should not matter for purposes of rate setting. */
+ struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
+ work.work);
+ struct ieee80211_tx_info *info;
+ struct ieee80211_hw *dev = priv->dev;
+ static u16 retry;
+ u16 tmp;
+
+ mutex_lock(&priv->conf_mutex);
+ tmp = rtl818x_ioread16(priv, (__le16 *)0xFFFA);
+ while (skb_queue_len(&priv->b_tx_status.queue) > 0) {
+ struct sk_buff *old_skb;
+
+ old_skb = skb_dequeue(&priv->b_tx_status.queue);
+ info = IEEE80211_SKB_CB(old_skb);
+ info->status.rates[0].count = tmp - retry + 1;
+ ieee80211_tx_status_irqsafe(dev, old_skb);
+ }
+ retry = tmp;
+ mutex_unlock(&priv->conf_mutex);
+}
+
static int rtl8187_start(struct ieee80211_hw *dev)
{
struct rtl8187_priv *priv = dev->priv;
@@ -881,6 +914,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
mutex_lock(&priv->conf_mutex);
init_usb_anchor(&priv->anchored);
+ priv->dev = dev;
if (priv->is_rtl8187b) {
reg = RTL818X_RX_CONF_MGMT |
@@ -948,6 +982,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
reg |= RTL818X_CMD_TX_ENABLE;
reg |= RTL818X_CMD_RX_ENABLE;
rtl818x_iowrite8(priv, &priv->map->CMD, reg);
+ INIT_DELAYED_WORK(&priv->work, rtl8187_work);
mutex_unlock(&priv->conf_mutex);
return 0;
@@ -978,6 +1013,8 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
dev_kfree_skb_any(skb);
usb_kill_anchored_urbs(&priv->anchored);
+ if (!priv->is_rtl8187b)
+ cancel_delayed_work_sync(&priv->work);
mutex_unlock(&priv->conf_mutex);
}
@@ -986,19 +1023,21 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
{
struct rtl8187_priv *priv = dev->priv;
int i;
+ int ret = -EOPNOTSUPP;
+ mutex_lock(&priv->conf_mutex);
if (priv->mode != NL80211_IFTYPE_MONITOR)
- return -EOPNOTSUPP;
+ goto exit;
switch (conf->type) {
case NL80211_IFTYPE_STATION:
priv->mode = conf->type;
break;
default:
- return -EOPNOTSUPP;
+ goto exit;
}
- mutex_lock(&priv->conf_mutex);
+ ret = 0;
priv->vif = conf->vif;
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
@@ -1007,8 +1046,9 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
((u8 *)conf->mac_addr)[i]);
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+exit:
mutex_unlock(&priv->conf_mutex);
- return 0;
+ return ret;
}
static void rtl8187_remove_interface(struct ieee80211_hw *dev,
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 7015f2480550..f95204632690 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -950,6 +950,7 @@ static struct strip *strip_get_idx(loff_t pos)
}
static void *strip_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
rcu_read_lock();
return *pos ? strip_get_idx(*pos - 1) : SEQ_START_TOKEN;
@@ -973,6 +974,7 @@ static void *strip_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void strip_seq_stop(struct seq_file *seq, void *v)
+ __releases(RCU)
{
rcu_read_unlock();
}
@@ -1125,7 +1127,7 @@ static int strip_seq_show(struct seq_file *seq, void *v)
}
-static struct seq_operations strip_seq_ops = {
+static const struct seq_operations strip_seq_ops = {
.start = strip_seq_start,
.next = strip_seq_next,
.stop = strip_seq_stop,
@@ -2475,6 +2477,16 @@ static const struct header_ops strip_header_ops = {
.rebuild = strip_rebuild_header,
};
+
+static const struct net_device_ops strip_netdev_ops = {
+ .ndo_open = strip_open_low,
+ .ndo_stop = strip_close_low,
+ .ndo_start_xmit = strip_xmit,
+ .ndo_set_mac_address = strip_set_mac_address,
+ .ndo_get_stats = strip_get_stats,
+ .ndo_change_mtu = strip_change_mtu,
+};
+
/*
* This routine is called by DDI when the
* (dynamically assigned) device is registered
@@ -2501,18 +2513,8 @@ static void strip_dev_setup(struct net_device *dev)
dev->dev_addr[0] = 0;
dev->addr_len = sizeof(MetricomAddress);
- /*
- * Pointers to interface service routines.
- */
-
- dev->open = strip_open_low;
- dev->stop = strip_close_low;
- dev->hard_start_xmit = strip_xmit;
- dev->header_ops = &strip_header_ops;
-
- dev->set_mac_address = strip_set_mac_address;
- dev->get_stats = strip_get_stats;
- dev->change_mtu = strip_change_mtu;
+ dev->header_ops = &strip_header_ops,
+ dev->netdev_ops = &strip_netdev_ops;
}
/*
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index 832679396b6c..3ab3eb957189 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -40,11 +40,11 @@ static u8 wv_irq_to_psa(int irq)
*/
static int __init wv_psa_to_irq(u8 irqval)
{
- int irq;
+ int i;
- for (irq = 0; irq < ARRAY_SIZE(irqvals); irq++)
- if (irqvals[irq] == irqval)
- return irq;
+ for (i = 0; i < ARRAY_SIZE(irqvals); i++)
+ if (irqvals[i] == irqval)
+ return i;
return -1;
}
@@ -735,9 +735,9 @@ if (lp->tx_n_in_use > 0)
if (tx_status & AC_SFLD_OK) {
int ncollisions;
- lp->stats.tx_packets++;
+ dev->stats.tx_packets++;
ncollisions = tx_status & AC_SFLD_MAXCOL;
- lp->stats.collisions += ncollisions;
+ dev->stats.collisions += ncollisions;
#ifdef DEBUG_TX_INFO
if (ncollisions > 0)
printk(KERN_DEBUG
@@ -745,9 +745,9 @@ if (lp->tx_n_in_use > 0)
dev->name, ncollisions);
#endif
} else {
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
if (tx_status & AC_SFLD_S10) {
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
#ifdef DEBUG_TX_FAIL
printk(KERN_DEBUG
"%s: wv_complete(): tx error: no CS.\n",
@@ -755,7 +755,7 @@ if (lp->tx_n_in_use > 0)
#endif
}
if (tx_status & AC_SFLD_S9) {
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
#ifdef DEBUG_TX_FAIL
printk(KERN_DEBUG
"%s: wv_complete(): tx error: lost CTS.\n",
@@ -763,7 +763,7 @@ if (lp->tx_n_in_use > 0)
#endif
}
if (tx_status & AC_SFLD_S8) {
- lp->stats.tx_fifo_errors++;
+ dev->stats.tx_fifo_errors++;
#ifdef DEBUG_TX_FAIL
printk(KERN_DEBUG
"%s: wv_complete(): tx error: slow DMA.\n",
@@ -771,7 +771,7 @@ if (lp->tx_n_in_use > 0)
#endif
}
if (tx_status & AC_SFLD_S6) {
- lp->stats.tx_heartbeat_errors++;
+ dev->stats.tx_heartbeat_errors++;
#ifdef DEBUG_TX_FAIL
printk(KERN_DEBUG
"%s: wv_complete(): tx error: heart beat.\n",
@@ -779,7 +779,7 @@ if (lp->tx_n_in_use > 0)
#endif
}
if (tx_status & AC_SFLD_S5) {
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
#ifdef DEBUG_TX_FAIL
printk(KERN_DEBUG
"%s: wv_complete(): tx error: too many collisions.\n",
@@ -1346,20 +1346,6 @@ static void wv_init_info(struct net_device * dev)
* or wireless extensions
*/
-/*------------------------------------------------------------------*/
-/*
- * Get the current Ethernet statistics. This may be called with the
- * card open or closed.
- * Used when the user read /proc/net/dev
- */
-static en_stats *wavelan_get_stats(struct net_device * dev)
-{
-#ifdef DEBUG_IOCTL_TRACE
- printk(KERN_DEBUG "%s: <>wavelan_get_stats()\n", dev->name);
-#endif
-
- return &((net_local *)netdev_priv(dev))->stats;
-}
/*------------------------------------------------------------------*/
/*
@@ -2466,7 +2452,7 @@ wv_packet_read(struct net_device * dev, u16 buf_off, int sksize)
"%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC).\n",
dev->name, sksize);
#endif
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
return;
}
@@ -2526,8 +2512,8 @@ wv_packet_read(struct net_device * dev, u16 buf_off, int sksize)
netif_rx(skb);
/* Keep statistics up to date */
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += sksize;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += sksize;
#ifdef DEBUG_RX_TRACE
printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
@@ -2608,7 +2594,7 @@ static void wv_receive(struct net_device * dev)
#endif
} else { /* If reception was no successful */
- lp->stats.rx_errors++;
+ dev->stats.rx_errors++;
#ifdef DEBUG_RX_INFO
printk(KERN_DEBUG
@@ -2624,7 +2610,7 @@ static void wv_receive(struct net_device * dev)
#endif
if ((fd.fd_status & FD_STATUS_S7) != 0) {
- lp->stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
#ifdef DEBUG_RX_FAIL
printk(KERN_DEBUG
"%s: wv_receive(): frame too short.\n",
@@ -2633,7 +2619,7 @@ static void wv_receive(struct net_device * dev)
}
if ((fd.fd_status & FD_STATUS_S8) != 0) {
- lp->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
#ifdef DEBUG_RX_FAIL
printk(KERN_DEBUG
"%s: wv_receive(): rx DMA overrun.\n",
@@ -2642,7 +2628,7 @@ static void wv_receive(struct net_device * dev)
}
if ((fd.fd_status & FD_STATUS_S9) != 0) {
- lp->stats.rx_fifo_errors++;
+ dev->stats.rx_fifo_errors++;
#ifdef DEBUG_RX_FAIL
printk(KERN_DEBUG
"%s: wv_receive(): ran out of resources.\n",
@@ -2651,7 +2637,7 @@ static void wv_receive(struct net_device * dev)
}
if ((fd.fd_status & FD_STATUS_S10) != 0) {
- lp->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
#ifdef DEBUG_RX_FAIL
printk(KERN_DEBUG
"%s: wv_receive(): alignment error.\n",
@@ -2660,7 +2646,7 @@ static void wv_receive(struct net_device * dev)
}
if ((fd.fd_status & FD_STATUS_S11) != 0) {
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
#ifdef DEBUG_RX_FAIL
printk(KERN_DEBUG
"%s: wv_receive(): CRC error.\n",
@@ -2826,7 +2812,7 @@ static int wv_packet_write(struct net_device * dev, void *buf, short length)
dev->trans_start = jiffies;
/* Keep stats up to date. */
- lp->stats.tx_bytes += length;
+ dev->stats.tx_bytes += length;
if (lp->tx_first_in_use == I82586NULL)
lp->tx_first_in_use = txblock;
@@ -4038,6 +4024,22 @@ static int wavelan_close(struct net_device * dev)
return 0;
}
+static const struct net_device_ops wavelan_netdev_ops = {
+ .ndo_open = wavelan_open,
+ .ndo_stop = wavelan_close,
+ .ndo_start_xmit = wavelan_packet_xmit,
+ .ndo_set_multicast_list = wavelan_set_multicast_list,
+ .ndo_tx_timeout = wavelan_watchdog,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef SET_MAC_ADDRESS
+ .ndo_set_mac_address = wavelan_set_mac_address
+#else
+ .ndo_set_mac_address = eth_mac_addr,
+#endif
+};
+
+
/*------------------------------------------------------------------*/
/*
* Probe an I/O address, and if the WaveLAN is there configure the
@@ -4130,17 +4132,8 @@ static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr)
/* Init spinlock */
spin_lock_init(&lp->spinlock);
- dev->open = wavelan_open;
- dev->stop = wavelan_close;
- dev->hard_start_xmit = wavelan_packet_xmit;
- dev->get_stats = wavelan_get_stats;
- dev->set_multicast_list = &wavelan_set_multicast_list;
- dev->tx_timeout = &wavelan_watchdog;
- dev->watchdog_timeo = WATCHDOG_JIFFIES;
-#ifdef SET_MAC_ADDRESS
- dev->set_mac_address = &wavelan_set_mac_address;
-#endif /* SET_MAC_ADDRESS */
-
+ dev->netdev_ops = &wavelan_netdev_ops;
+ dev->watchdog_timeo = WATCHDOG_JIFFIES;
dev->wireless_handlers = &wavelan_handler_def;
lp->wireless_data.spy_data = &lp->spy_data;
dev->wireless_data = &lp->wireless_data;
@@ -4281,8 +4274,7 @@ int __init init_module(void)
/* Loop on all possible base addresses. */
- i = -1;
- while ((io[++i] != 0) && (i < ARRAY_SIZE(io))) {
+ for (i = 0; i < ARRAY_SIZE(io) && io[i] != 0; i++) {
struct net_device *dev = alloc_etherdev(sizeof(net_local));
if (!dev)
break;
diff --git a/drivers/net/wireless/wavelan.p.h b/drivers/net/wireless/wavelan.p.h
index 44d31bbf39e4..2daa0210d789 100644
--- a/drivers/net/wireless/wavelan.p.h
+++ b/drivers/net/wireless/wavelan.p.h
@@ -459,11 +459,9 @@ static const char *version = "wavelan.c : v24 (SMP + wireless extensions) 11/12/
/****************************** TYPES ******************************/
/* Shortcuts */
-typedef struct net_device_stats en_stats;
typedef struct iw_statistics iw_stats;
typedef struct iw_quality iw_qual;
-typedef struct iw_freq iw_freq;
-typedef struct net_local net_local;
+typedef struct iw_freq iw_freq;typedef struct net_local net_local;
typedef struct timer_list timer_list;
/* Basic types */
@@ -475,15 +473,12 @@ typedef u_char mac_addr[WAVELAN_ADDR_SIZE]; /* Hardware address */
* For each network interface, Linux keeps data in two structures: "device"
* keeps the generic data (same format for everybody) and "net_local" keeps
* additional specific data.
- * Note that some of this specific data is in fact generic (en_stats, for
- * example).
*/
struct net_local
{
net_local * next; /* linked list of the devices */
struct net_device * dev; /* reverse link */
spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
- en_stats stats; /* Ethernet interface statistics */
int nresets; /* number of hardware resets */
u_char reconfig_82586; /* We need to reconfigure the controller. */
u_char promiscuous; /* promiscuous mode */
@@ -601,8 +596,6 @@ static void
static inline void
wv_init_info(struct net_device *); /* display startup info */
/* ------------------- IOCTL, STATS & RECONFIG ------------------- */
-static en_stats *
- wavelan_get_stats(struct net_device *); /* Give stats /proc/net/dev */
static iw_stats *
wavelan_get_wireless_stats(struct net_device *);
static void
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index de717f8ffd61..e55b33961aeb 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -838,9 +838,8 @@ wv_82593_cmd(struct net_device * dev,
}
while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
- /* If the interrupt hasn't be posted */
- if(spin <= 0)
- {
+ /* If the interrupt hasn't been posted */
+ if (spin < 0) {
#ifdef DEBUG_INTERRUPT_ERROR
printk(KERN_INFO "wv_82593_cmd: %s timeout (previous command), status 0x%02x\n",
str, status);
@@ -1353,21 +1352,6 @@ wv_init_info(struct net_device * dev)
* or wireless extensions
*/
-/*------------------------------------------------------------------*/
-/*
- * Get the current ethernet statistics. This may be called with the
- * card open or closed.
- * Used when the user read /proc/net/dev
- */
-static en_stats *
-wavelan_get_stats(struct net_device * dev)
-{
-#ifdef DEBUG_IOCTL_TRACE
- printk(KERN_DEBUG "%s: <>wavelan_get_stats()\n", dev->name);
-#endif
-
- return(&((net_local *)netdev_priv(dev))->stats);
-}
/*------------------------------------------------------------------*/
/*
@@ -2818,7 +2802,7 @@ wv_packet_read(struct net_device * dev,
printk(KERN_INFO "%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC)\n",
dev->name, sksize);
#endif
- lp->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
/*
* Not only do we want to return here, but we also need to drop the
* packet on the floor to clear the interrupt.
@@ -2878,8 +2862,8 @@ wv_packet_read(struct net_device * dev,
netif_rx(skb);
/* Keep stats up to date */
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += sksize;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += sksize;
#ifdef DEBUG_RX_TRACE
printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
@@ -2981,13 +2965,13 @@ wv_packet_rcv(struct net_device * dev)
/* Check status */
if((status & RX_RCV_OK) != RX_RCV_OK)
{
- lp->stats.rx_errors++;
+ dev->stats.rx_errors++;
if(status & RX_NO_SFD)
- lp->stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if(status & RX_CRC_ERR)
- lp->stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
if(status & RX_OVRRUN)
- lp->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
#ifdef DEBUG_RX_FAIL
printk(KERN_DEBUG "%s: wv_packet_rcv(): packet not received ok, status = 0x%x\n",
@@ -3074,7 +3058,7 @@ wv_packet_write(struct net_device * dev,
dev->trans_start = jiffies;
/* Keep stats up to date */
- lp->stats.tx_bytes += length;
+ dev->stats.tx_bytes += length;
spin_unlock_irqrestore(&lp->spinlock, flags);
@@ -4107,7 +4091,7 @@ wavelan_interrupt(int irq,
printk(KERN_INFO "%s: wv_interrupt(): receive buffer overflow\n",
dev->name);
#endif
- lp->stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
lp->overrunning = 1;
}
@@ -4156,7 +4140,7 @@ wavelan_interrupt(int irq,
/* Check for possible errors */
if((tx_status & TX_OK) != TX_OK)
{
- lp->stats.tx_errors++;
+ dev->stats.tx_errors++;
if(tx_status & TX_FRTL)
{
@@ -4171,14 +4155,14 @@ wavelan_interrupt(int irq,
printk(KERN_DEBUG "%s: wv_interrupt(): DMA underrun\n",
dev->name);
#endif
- lp->stats.tx_aborted_errors++;
+ dev->stats.tx_aborted_errors++;
}
if(tx_status & TX_LOST_CTS)
{
#ifdef DEBUG_TX_FAIL
printk(KERN_DEBUG "%s: wv_interrupt(): no CTS\n", dev->name);
#endif
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
}
if(tx_status & TX_LOST_CRS)
{
@@ -4186,14 +4170,14 @@ wavelan_interrupt(int irq,
printk(KERN_DEBUG "%s: wv_interrupt(): no carrier\n",
dev->name);
#endif
- lp->stats.tx_carrier_errors++;
+ dev->stats.tx_carrier_errors++;
}
if(tx_status & TX_HRT_BEAT)
{
#ifdef DEBUG_TX_FAIL
printk(KERN_DEBUG "%s: wv_interrupt(): heart beat\n", dev->name);
#endif
- lp->stats.tx_heartbeat_errors++;
+ dev->stats.tx_heartbeat_errors++;
}
if(tx_status & TX_DEFER)
{
@@ -4217,14 +4201,14 @@ wavelan_interrupt(int irq,
#endif
if(!(tx_status & TX_NCOL_MASK))
{
- lp->stats.collisions += 0x10;
+ dev->stats.collisions += 0x10;
}
}
}
} /* if(!(tx_status & TX_OK)) */
- lp->stats.collisions += (tx_status & TX_NCOL_MASK);
- lp->stats.tx_packets++;
+ dev->stats.collisions += (tx_status & TX_NCOL_MASK);
+ dev->stats.tx_packets++;
netif_wake_queue(dev);
outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); /* Acknowledge the interrupt */
@@ -4452,6 +4436,19 @@ wavelan_close(struct net_device * dev)
return 0;
}
+static const struct net_device_ops wavelan_netdev_ops = {
+ .ndo_open = wavelan_open,
+ .ndo_stop = wavelan_close,
+ .ndo_start_xmit = wavelan_packet_xmit,
+ .ndo_set_multicast_list = wavelan_set_multicast_list,
+#ifdef SET_MAC_ADDRESS
+ .ndo_set_mac_address = wavelan_set_mac_address,
+#endif
+ .ndo_tx_timeout = wavelan_watchdog,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/*------------------------------------------------------------------*/
/*
* wavelan_attach() creates an "instance" of the driver, allocating
@@ -4512,17 +4509,7 @@ wavelan_probe(struct pcmcia_device *p_dev)
lp->dev = dev;
/* wavelan NET3 callbacks */
- dev->open = &wavelan_open;
- dev->stop = &wavelan_close;
- dev->hard_start_xmit = &wavelan_packet_xmit;
- dev->get_stats = &wavelan_get_stats;
- dev->set_multicast_list = &wavelan_set_multicast_list;
-#ifdef SET_MAC_ADDRESS
- dev->set_mac_address = &wavelan_set_mac_address;
-#endif /* SET_MAC_ADDRESS */
-
- /* Set the watchdog timer */
- dev->tx_timeout = &wavelan_watchdog;
+ dev->netdev_ops = &wavelan_netdev_ops;
dev->watchdog_timeo = WATCHDOG_JIFFIES;
SET_ETHTOOL_OPS(dev, &ops);
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index 628192d7248f..706fd3007d21 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -576,7 +576,6 @@ struct wavepoint_table
/****************************** TYPES ******************************/
/* Shortcuts */
-typedef struct net_device_stats en_stats;
typedef struct iw_statistics iw_stats;
typedef struct iw_quality iw_qual;
typedef struct iw_freq iw_freq;
@@ -592,8 +591,6 @@ typedef u_char mac_addr[WAVELAN_ADDR_SIZE]; /* Hardware address */
* For each network interface, Linux keep data in two structure. "device"
* keep the generic data (same format for everybody) and "net_local" keep
* the additional specific data.
- * Note that some of this specific data is in fact generic (en_stats, for
- * example).
*/
struct net_local
{
@@ -601,7 +598,6 @@ struct net_local
struct net_device * dev; /* Reverse link... */
spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
struct pcmcia_device * link; /* pcmcia structure */
- en_stats stats; /* Ethernet interface statistics */
int nresets; /* Number of hw resets */
u_char configured; /* If it is configured */
u_char reconfig_82593; /* Need to reconfigure the controller */
@@ -694,8 +690,6 @@ static void
static void
wv_init_info(struct net_device *); /* display startup info */
/* ------------------- IOCTL, STATS & RECONFIG ------------------- */
-static en_stats *
- wavelan_get_stats(struct net_device *); /* Give stats /proc/net/dev */
static iw_stats *
wavelan_get_wireless_stats(struct net_device *);
/* ----------------------- PACKET RECEPTION ----------------------- */
diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
index 59bb3a55ab48..8bce1a550a22 100644
--- a/drivers/net/wireless/wl3501.h
+++ b/drivers/net/wireless/wl3501.h
@@ -606,7 +606,7 @@ struct wl3501_card {
u8 reg_domain;
u8 version[2];
struct wl3501_scan_confirm bss_set[20];
- struct net_device_stats stats;
+
struct iw_statistics wstats;
struct iw_spy_data spy_data;
struct iw_public_data wireless_data;
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index c99a1b6b948f..1f64d6033ab5 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -44,6 +44,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/wireless.h>
+#include <linux/ieee80211.h>
#include <net/iw_handler.h>
@@ -111,12 +112,6 @@ static void wl3501_release(struct pcmcia_device *link);
*/
static dev_info_t wl3501_dev_info = "wl3501_cs";
-static int wl3501_chan2freq[] = {
- [0] = 2412, [1] = 2417, [2] = 2422, [3] = 2427, [4] = 2432,
- [5] = 2437, [6] = 2442, [7] = 2447, [8] = 2452, [9] = 2457,
- [10] = 2462, [11] = 2467, [12] = 2472, [13] = 2477,
-};
-
static const struct {
int reg_domain;
int min, max, deflt;
@@ -1005,7 +1000,7 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
if (!skb) {
printk(KERN_WARNING "%s: Can't alloc a sk_buff of size %d.\n",
dev->name, pkt_len);
- this->stats.rx_dropped++;
+ dev->stats.rx_dropped++;
} else {
skb->dev = dev;
skb_reserve(skb, 2); /* IP headers on 16 bytes boundaries */
@@ -1013,8 +1008,8 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
wl3501_receive(this, skb->data, pkt_len);
skb_put(skb, pkt_len);
skb->protocol = eth_type_trans(skb, dev);
- this->stats.rx_packets++;
- this->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
netif_rx(skb);
}
}
@@ -1316,7 +1311,7 @@ out:
static void wl3501_tx_timeout(struct net_device *dev)
{
struct wl3501_card *this = netdev_priv(dev);
- struct net_device_stats *stats = &this->stats;
+ struct net_device_stats *stats = &dev->stats;
unsigned long flags;
int rc;
@@ -1351,11 +1346,11 @@ static int wl3501_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (enabled)
wl3501_unblock_interrupt(this);
if (rc) {
- ++this->stats.tx_dropped;
+ ++dev->stats.tx_dropped;
netif_stop_queue(dev);
} else {
- ++this->stats.tx_packets;
- this->stats.tx_bytes += skb->len;
+ ++dev->stats.tx_packets;
+ dev->stats.tx_bytes += skb->len;
kfree_skb(skb);
if (this->tx_buffer_cnt < 2)
@@ -1405,13 +1400,6 @@ fail:
goto out;
}
-static struct net_device_stats *wl3501_get_stats(struct net_device *dev)
-{
- struct wl3501_card *this = netdev_priv(dev);
-
- return &this->stats;
-}
-
static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev)
{
struct wl3501_card *this = netdev_priv(dev);
@@ -1510,7 +1498,7 @@ static int wl3501_get_freq(struct net_device *dev, struct iw_request_info *info,
{
struct wl3501_card *this = netdev_priv(dev);
- wrqu->freq.m = wl3501_chan2freq[this->chan - 1] * 100000;
+ wrqu->freq.m = ieee80211_dsss_chan_to_freq(this->chan) * 100000;
wrqu->freq.e = 1;
return 0;
}
@@ -1895,6 +1883,16 @@ static const struct iw_handler_def wl3501_handler_def = {
.get_wireless_stats = wl3501_get_wireless_stats,
};
+static const struct net_device_ops wl3501_netdev_ops = {
+ .ndo_open = wl3501_open,
+ .ndo_stop = wl3501_close,
+ .ndo_start_xmit = wl3501_hard_start_xmit,
+ .ndo_tx_timeout = wl3501_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/**
* wl3501_attach - creates an "instance" of the driver
*
@@ -1927,17 +1925,16 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
dev = alloc_etherdev(sizeof(struct wl3501_card));
if (!dev)
goto out_link;
- dev->open = wl3501_open;
- dev->stop = wl3501_close;
- dev->hard_start_xmit = wl3501_hard_start_xmit;
- dev->tx_timeout = wl3501_tx_timeout;
+
+
+ dev->netdev_ops = &wl3501_netdev_ops;
dev->watchdog_timeo = 5 * HZ;
- dev->get_stats = wl3501_get_stats;
+
this = netdev_priv(dev);
this->wireless_data.spy_data = &this->spy_data;
this->p_dev = p_dev;
dev->wireless_data = &this->wireless_data;
- dev->wireless_handlers = (struct iw_handler_def *)&wl3501_handler_def;
+ dev->wireless_handlers = &wl3501_handler_def;
SET_ETHTOOL_OPS(dev, &ops);
netif_stop_queue(dev);
p_dev->priv = p_dev->irq.Instance = dev;
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index b45c27d42fd8..5fabd9c0f07a 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -328,8 +328,8 @@ static void zd1201_usbrx(struct urb *urb)
memcpy(skb_put(skb, 2), &data[datalen-24], 2);
memcpy(skb_put(skb, len), data, len);
skb->protocol = eth_type_trans(skb, zd->dev);
- zd->stats.rx_packets++;
- zd->stats.rx_bytes += skb->len;
+ zd->dev->stats.rx_packets++;
+ zd->dev->stats.rx_bytes += skb->len;
netif_rx(skb);
goto resubmit;
}
@@ -384,8 +384,8 @@ static void zd1201_usbrx(struct urb *urb)
memcpy(skb_put(skb, len), data+8, len);
}
skb->protocol = eth_type_trans(skb, zd->dev);
- zd->stats.rx_packets++;
- zd->stats.rx_bytes += skb->len;
+ zd->dev->stats.rx_packets++;
+ zd->dev->stats.rx_bytes += skb->len;
netif_rx(skb);
}
resubmit:
@@ -787,7 +787,7 @@ static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct urb *urb = zd->tx_urb;
if (!zd->mac_enabled || zd->monitor) {
- zd->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
kfree_skb(skb);
return 0;
}
@@ -817,12 +817,12 @@ static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
err = usb_submit_urb(zd->tx_urb, GFP_ATOMIC);
if (err) {
- zd->stats.tx_errors++;
+ dev->stats.tx_errors++;
netif_start_queue(dev);
return err;
}
- zd->stats.tx_packets++;
- zd->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
dev->trans_start = jiffies;
kfree_skb(skb);
@@ -838,7 +838,7 @@ static void zd1201_tx_timeout(struct net_device *dev)
dev_warn(&zd->usb->dev, "%s: TX timeout, shooting down urb\n",
dev->name);
usb_unlink_urb(zd->tx_urb);
- zd->stats.tx_errors++;
+ dev->stats.tx_errors++;
/* Restart the timeout to quiet the watchdog: */
dev->trans_start = jiffies;
}
@@ -861,13 +861,6 @@ static int zd1201_set_mac_address(struct net_device *dev, void *p)
return zd1201_mac_reset(zd);
}
-static struct net_device_stats *zd1201_get_stats(struct net_device *dev)
-{
- struct zd1201 *zd = netdev_priv(dev);
-
- return &zd->stats;
-}
-
static struct iw_statistics *zd1201_get_wireless_stats(struct net_device *dev)
{
struct zd1201 *zd = netdev_priv(dev);
@@ -919,10 +912,9 @@ static int zd1201_set_freq(struct net_device *dev,
if (freq->e == 0)
channel = freq->m;
else {
- if (freq->m >= 2482)
- channel = 14;
- if (freq->m >= 2407)
- channel = (freq->m-2407)/5;
+ channel = ieee80211_freq_to_dsss_chan(freq->m);
+ if (channel < 0)
+ channel = 0;
}
err = zd1201_setconfig16(zd, ZD1201_RID_CNFOWNCHANNEL, channel);
@@ -1725,6 +1717,17 @@ static const struct iw_handler_def zd1201_iw_handlers = {
.get_wireless_stats = zd1201_get_wireless_stats,
};
+static const struct net_device_ops zd1201_netdev_ops = {
+ .ndo_open = zd1201_net_open,
+ .ndo_stop = zd1201_net_stop,
+ .ndo_start_xmit = zd1201_hard_start_xmit,
+ .ndo_tx_timeout = zd1201_tx_timeout,
+ .ndo_set_multicast_list = zd1201_set_multicast,
+ .ndo_set_mac_address = zd1201_set_mac_address,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
static int zd1201_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
@@ -1777,16 +1780,9 @@ static int zd1201_probe(struct usb_interface *interface,
if (err)
goto err_start;
- dev->open = zd1201_net_open;
- dev->stop = zd1201_net_stop;
- dev->get_stats = zd1201_get_stats;
- dev->wireless_handlers =
- (struct iw_handler_def *)&zd1201_iw_handlers;
- dev->hard_start_xmit = zd1201_hard_start_xmit;
+ dev->netdev_ops = &zd1201_netdev_ops;
+ dev->wireless_handlers = &zd1201_iw_handlers;
dev->watchdog_timeo = ZD1201_TX_TIMEOUT;
- dev->tx_timeout = zd1201_tx_timeout;
- dev->set_multicast_list = zd1201_set_multicast;
- dev->set_mac_address = zd1201_set_mac_address;
strcpy(dev->name, "wlan%d");
err = zd1201_getconfig(zd, ZD1201_RID_CNFOWNMACADDR,
diff --git a/drivers/net/wireless/zd1201.h b/drivers/net/wireless/zd1201.h
index 235f0ee34b24..dd7ea1f35bef 100644
--- a/drivers/net/wireless/zd1201.h
+++ b/drivers/net/wireless/zd1201.h
@@ -26,7 +26,6 @@ struct zd1201 {
struct usb_device *usb;
int removed;
struct net_device *dev;
- struct net_device_stats stats;
struct iw_statistics iwstats;
int endp_in;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index f1519143f8a6..2c813d87092c 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -1616,3 +1616,24 @@ int zd_chip_set_multicast_hash(struct zd_chip *chip,
return zd_iowrite32a(chip, ioreqs, ARRAY_SIZE(ioreqs));
}
+
+u64 zd_chip_get_tsf(struct zd_chip *chip)
+{
+ int r;
+ static const zd_addr_t aw_pt_bi_addr[] =
+ { CR_TSF_LOW_PART, CR_TSF_HIGH_PART };
+ u32 values[2];
+ u64 tsf;
+
+ mutex_lock(&chip->mutex);
+ r = zd_ioread32v_locked(chip, values, (const zd_addr_t *)aw_pt_bi_addr,
+ ARRAY_SIZE(aw_pt_bi_addr));
+ mutex_unlock(&chip->mutex);
+ if (r)
+ return 0;
+
+ tsf = values[1];
+ tsf = (tsf << 32) | values[0];
+
+ return tsf;
+}
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index f8c061a9b6ec..ee42751d5cb0 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -950,4 +950,6 @@ static inline void zd_mc_add_addr(struct zd_mc_hash *hash, u8 *addr)
int zd_chip_set_multicast_hash(struct zd_chip *chip,
struct zd_mc_hash *hash);
+u64 zd_chip_get_tsf(struct zd_chip *chip);
+
#endif /* _ZD_CHIP_H */
diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h
index 5200db405610..6ac597ffd3b9 100644
--- a/drivers/net/wireless/zd1211rw/zd_def.h
+++ b/drivers/net/wireless/zd1211rw/zd_def.h
@@ -33,8 +33,13 @@ typedef u16 __nocast zd_addr_t;
#ifdef DEBUG
# define dev_dbg_f(dev, fmt, args...) \
dev_printk_f(KERN_DEBUG, dev, fmt, ## args)
+# define dev_dbg_f_limit(dev, fmt, args...) do { \
+ if (net_ratelimit()) \
+ dev_printk_f(KERN_DEBUG, dev, fmt, ## args); \
+} while (0)
#else
# define dev_dbg_f(dev, fmt, args...) do { (void)(dev); } while (0)
+# define dev_dbg_f_limit(dev, fmt, args...) do { (void)(dev); } while (0)
#endif /* DEBUG */
#ifdef DEBUG
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index a611ad857983..c3a51266de20 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -170,10 +170,10 @@ int zd_mac_init_hw(struct ieee80211_hw *hw)
goto disable_int;
r = zd_reg2alpha2(mac->regdomain, alpha2);
- if (!r)
- regulatory_hint(hw->wiphy, alpha2);
+ if (r)
+ goto disable_int;
- r = 0;
+ r = regulatory_hint(hw->wiphy, alpha2);
disable_int:
zd_chip_disable_int(chip);
out:
@@ -575,13 +575,17 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
r = fill_ctrlset(mac, skb);
if (r)
- return r;
+ goto fail;
info->rate_driver_data[0] = hw;
r = zd_usb_tx(&mac->chip.usb, skb);
if (r)
- return r;
+ goto fail;
+ return 0;
+
+fail:
+ dev_kfree_skb(skb);
return 0;
}
@@ -768,13 +772,23 @@ static int zd_op_config_interface(struct ieee80211_hw *hw,
if (!beacon)
return -ENOMEM;
r = zd_mac_config_beacon(hw, beacon);
+ kfree_skb(beacon);
+
if (r < 0)
return r;
- r = zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS |
- hw->conf.beacon_int);
+ }
+
+ if (conf->changed & IEEE80211_IFCC_BEACON_ENABLED) {
+ u32 interval;
+
+ if (conf->enable_beacon)
+ interval = BCN_MODE_IBSS | hw->conf.beacon_int;
+ else
+ interval = 0;
+
+ r = zd_set_beacon_interval(&mac->chip, interval);
if (r < 0)
return r;
- kfree_skb(beacon);
}
} else
associated = is_valid_ether_addr(conf->bssid);
@@ -793,10 +807,9 @@ static void zd_process_intr(struct work_struct *work)
struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4));
- if (int_status & INT_CFG_NEXT_BCN) {
- if (net_ratelimit())
- dev_dbg_f(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
- } else
+ if (int_status & INT_CFG_NEXT_BCN)
+ dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
+ else
dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
zd_chip_enable_hwint(&mac->chip);
@@ -926,6 +939,12 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
}
}
+static u64 zd_op_get_tsf(struct ieee80211_hw *hw)
+{
+ struct zd_mac *mac = zd_hw_mac(hw);
+ return zd_chip_get_tsf(&mac->chip);
+}
+
static const struct ieee80211_ops zd_ops = {
.tx = zd_op_tx,
.start = zd_op_start,
@@ -936,6 +955,7 @@ static const struct ieee80211_ops zd_ops = {
.config_interface = zd_op_config_interface,
.configure_filter = zd_op_configure_filter,
.bss_info_changed = zd_op_bss_info_changed,
+ .get_tsf = zd_op_get_tsf,
};
struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
@@ -967,7 +987,7 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_SIGNAL_DB;
+ IEEE80211_HW_SIGNAL_UNSPEC;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_MESH_POINT) |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index cd6184ee08ee..f67325387902 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -196,7 +196,7 @@ static void rx_refill_timeout(unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
struct netfront_info *np = netdev_priv(dev);
- netif_rx_schedule(&np->napi);
+ napi_schedule(&np->napi);
}
static int netfront_tx_slot_available(struct netfront_info *np)
@@ -328,7 +328,7 @@ static int xennet_open(struct net_device *dev)
xennet_alloc_rx_buffers(dev);
np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
- netif_rx_schedule(&np->napi);
+ napi_schedule(&np->napi);
}
spin_unlock_bh(&np->rx_lock);
@@ -979,7 +979,7 @@ err:
RING_FINAL_CHECK_FOR_RESPONSES(&np->rx, more_to_do);
if (!more_to_do)
- __netif_rx_complete(napi);
+ __napi_complete(napi);
local_irq_restore(flags);
}
@@ -1317,7 +1317,7 @@ static irqreturn_t xennet_interrupt(int irq, void *dev_id)
xennet_tx_buf_gc(dev);
/* Under tx_lock: protects access to rx shared-ring indexes. */
if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
- netif_rx_schedule(&np->napi);
+ napi_schedule(&np->napi);
}
spin_unlock_irqrestore(&np->tx_lock, flags);
@@ -1511,7 +1511,7 @@ static int xennet_set_tso(struct net_device *dev, u32 data)
static void xennet_set_features(struct net_device *dev)
{
/* Turn off all GSO bits except ROBUST. */
- dev->features &= (1 << NETIF_F_GSO_SHIFT) - 1;
+ dev->features &= ~NETIF_F_GSO_MASK;
dev->features |= NETIF_F_GSO_ROBUST;
xennet_set_sg(dev, 0);
diff --git a/drivers/net/xtsonic.c b/drivers/net/xtsonic.c
index 03a3f34e9039..a12a7211c982 100644
--- a/drivers/net/xtsonic.c
+++ b/drivers/net/xtsonic.c
@@ -183,7 +183,7 @@ static int __init sonic_probe1(struct net_device *dev)
if (lp->descriptors == NULL) {
printk(KERN_ERR "%s: couldn't alloc DMA memory for "
- " descriptors.\n", lp->device->bus_id);
+ " descriptors.\n", dev_name(lp->device));
goto out;
}
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 2f1645dcb8c8..7477ffdcddb4 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -107,9 +107,9 @@ static int gx_fix;
#include <asm/io.h>
/* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
-KERN_INFO DRV_NAME ".c:v1.05 1/09/2001 Written by Donald Becker <becker@scyld.com>\n"
-KERN_INFO " (unofficial 2.4.x port, " DRV_VERSION ", " DRV_RELDATE ")\n";
+static const char version[] __devinitconst =
+ KERN_INFO DRV_NAME ".c:v1.05 1/09/2001 Written by Donald Becker <becker@scyld.com>\n"
+ KERN_INFO " (unofficial 2.4.x port, " DRV_VERSION ", " DRV_RELDATE ")\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver");
diff --git a/drivers/net/znet.c b/drivers/net/znet.c
index f0b15c9347d0..0a6992d8611b 100644
--- a/drivers/net/znet.c
+++ b/drivers/net/znet.c
@@ -358,6 +358,17 @@ static void znet_set_multicast_list (struct net_device *dev)
* multicast address configured isn't equal to IFF_ALLMULTI */
}
+static const struct net_device_ops znet_netdev_ops = {
+ .ndo_open = znet_open,
+ .ndo_stop = znet_close,
+ .ndo_start_xmit = znet_send_packet,
+ .ndo_set_multicast_list = znet_set_multicast_list,
+ .ndo_tx_timeout = znet_tx_timeout,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
/* The Z-Note probe is pretty easy. The NETIDBLK exists in the safe-to-probe
BIOS area. We just scan for the signature, and pull the vital parameters
out of the structure. */
@@ -440,11 +451,7 @@ static int __init znet_probe (void)
znet->tx_end = znet->tx_start + znet->tx_buf_len;
/* The ZNET-specific entries in the device structure. */
- dev->open = &znet_open;
- dev->hard_start_xmit = &znet_send_packet;
- dev->stop = &znet_close;
- dev->set_multicast_list = &znet_set_multicast_list;
- dev->tx_timeout = znet_tx_timeout;
+ dev->netdev_ops = &znet_netdev_ops;
dev->watchdog_timeo = TX_TIMEOUT;
err = register_netdev(dev);
if (err)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index cd17092b82bd..41c5dfd85358 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -446,6 +446,7 @@ struct of_modalias_table {
};
static struct of_modalias_table of_modalias_table[] = {
{ "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" },
+ { "mmc-spi-slot", "mmc_spi" },
};
/**
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index c3ea5fa7d05a..8574622e36a5 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -154,6 +154,10 @@ int sync_start(void)
{
int err;
+ if (!alloc_cpumask_var(&marked_cpus, GFP_KERNEL))
+ return -ENOMEM;
+ cpumask_clear(marked_cpus);
+
start_cpu_work();
err = task_handoff_register(&task_free_nb);
@@ -179,6 +183,7 @@ out2:
task_handoff_unregister(&task_free_nb);
out1:
end_sync();
+ free_cpumask_var(marked_cpus);
goto out;
}
@@ -190,6 +195,7 @@ void sync_stop(void)
profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
task_handoff_unregister(&task_free_nb);
end_sync();
+ free_cpumask_var(marked_cpus);
}
@@ -565,20 +571,6 @@ void sync_buffer(int cpu)
mutex_unlock(&buffer_mutex);
}
-int __init buffer_sync_init(void)
-{
- if (!alloc_cpumask_var(&marked_cpus, GFP_KERNEL))
- return -ENOMEM;
-
- cpumask_clear(marked_cpus);
- return 0;
-}
-
-void __exit buffer_sync_cleanup(void)
-{
- free_cpumask_var(marked_cpus);
-}
-
/* The function can be used to add a buffer worth of data directly to
* the kernel buffer. The buffer is assumed to be a circular buffer.
* Take the entries from index start and end at index end, wrapping
diff --git a/drivers/oprofile/buffer_sync.h b/drivers/oprofile/buffer_sync.h
index 0ebf5db62679..3110732c1835 100644
--- a/drivers/oprofile/buffer_sync.h
+++ b/drivers/oprofile/buffer_sync.h
@@ -19,8 +19,4 @@ void sync_stop(void);
/* sync the given CPU's buffer */
void sync_buffer(int cpu);
-/* initialize/destroy the buffer system. */
-int buffer_sync_init(void);
-void buffer_sync_cleanup(void);
-
#endif /* OPROFILE_BUFFER_SYNC_H */
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
index ced39f602292..3cffce90f82a 100644
--- a/drivers/oprofile/oprof.c
+++ b/drivers/oprofile/oprof.c
@@ -183,10 +183,6 @@ static int __init oprofile_init(void)
{
int err;
- err = buffer_sync_init();
- if (err)
- return err;
-
err = oprofile_arch_init(&oprofile_ops);
if (err < 0 || timer) {
@@ -195,10 +191,8 @@ static int __init oprofile_init(void)
}
err = oprofilefs_register();
- if (err) {
+ if (err)
oprofile_arch_exit();
- buffer_sync_cleanup();
- }
return err;
}
@@ -208,7 +202,6 @@ static void __exit oprofile_exit(void)
{
oprofilefs_unregister();
oprofile_arch_exit();
- buffer_sync_cleanup();
}
diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c
index 7931133526c4..9ca21098b146 100644
--- a/drivers/parisc/asp.c
+++ b/drivers/parisc/asp.c
@@ -81,7 +81,7 @@ static int __init asp_init_chip(struct parisc_device *dev)
asp.hpa = ASP_INTERRUPT_ADDR;
printk(KERN_INFO "%s version %d at 0x%lx found.\n",
- asp.name, asp.version, dev->hpa.start);
+ asp.name, asp.version, (unsigned long)dev->hpa.start);
/* the IRQ ASP should use */
ret = -EBUSY;
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index cd4dd7ed2c06..5d610cbcfe80 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -406,8 +406,6 @@ resource_found:
}
ioc->avg_search[ioc->avg_idx++] = cr_start;
ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1;
-#endif
-#ifdef CCIO_COLLECT_STATS
ioc->used_pages += pages_needed;
#endif
/*
@@ -453,10 +451,10 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped)
unsigned long mask = ~(~0UL >> pages_mapped);
CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 8);
#else
- CCIO_FREE_MAPPINGS(ioc, res_idx, 0xff, 8);
+ CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffUL, 8);
#endif
} else if(pages_mapped <= 16) {
- CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffff, 16);
+ CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffffUL, 16);
} else if(pages_mapped <= 32) {
CCIO_FREE_MAPPINGS(ioc, res_idx, ~(unsigned int)0, 32);
#ifdef __LP64__
@@ -1028,8 +1026,10 @@ static int ccio_proc_info(struct seq_file *m, void *p)
while (ioc != NULL) {
unsigned int total_pages = ioc->res_size << 3;
+#ifdef CCIO_COLLECT_STATS
unsigned long avg = 0, min, max;
int j;
+#endif
len += seq_printf(m, "%s\n", ioc->name);
@@ -1060,8 +1060,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
avg /= CCIO_SEARCH_SAMPLE;
len += seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
min, avg, max);
-#endif
-#ifdef CCIO_COLLECT_STATS
+
len += seq_printf(m, "pci_map_single(): %8ld calls %8ld pages (avg %d/1000)\n",
ioc->msingle_calls, ioc->msingle_pages,
(int)((ioc->msingle_pages * 1000)/ioc->msingle_calls));
@@ -1400,7 +1399,7 @@ ccio_init_resource(struct resource *res, char *name, void __iomem *ioaddr)
result = insert_resource(&iomem_resource, res);
if (result < 0) {
printk(KERN_ERR "%s() failed to claim CCIO bus address space (%08lx,%08lx)\n",
- __func__, res->start, res->end);
+ __func__, (unsigned long)res->start, (unsigned long)res->end);
}
}
@@ -1551,7 +1550,8 @@ static int __init ccio_probe(struct parisc_device *dev)
ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
- printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa.start);
+ printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name,
+ (unsigned long)dev->hpa.start);
for (i = 0; i < ioc_count; i++) {
ioc_p = &(*ioc_p)->next;
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index bb5a1c9597cb..52ae0b1d470c 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -819,7 +819,9 @@ dino_bridge_init(struct dino_device *dino_dev, const char *name)
result = ccio_request_resource(dino_dev->hba.dev, &res[i]);
if (result < 0) {
- printk(KERN_ERR "%s: failed to claim PCI Bus address space %d (0x%lx-0x%lx)!\n", name, i, res[i].start, res[i].end);
+ printk(KERN_ERR "%s: failed to claim PCI Bus address "
+ "space %d (0x%lx-0x%lx)!\n", name, i,
+ (unsigned long)res[i].start, (unsigned long)res[i].end);
return result;
}
}
@@ -899,7 +901,8 @@ static int __init dino_common_init(struct parisc_device *dev,
if (request_resource(&ioport_resource, res) < 0) {
printk(KERN_ERR "%s: request I/O Port region failed "
"0x%lx/%lx (hpa 0x%p)\n",
- name, res->start, res->end, dino_dev->hba.base_addr);
+ name, (unsigned long)res->start, (unsigned long)res->end,
+ dino_dev->hba.base_addr);
return 1;
}
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 7891db50c483..f415fdd9a885 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -314,7 +314,7 @@ static int __init eisa_probe(struct parisc_device *dev)
char *name = is_mongoose(dev) ? "Mongoose" : "Wax";
printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n",
- name, dev->hpa.start);
+ name, (unsigned long)dev->hpa.start);
eisa_dev.hba.dev = dev;
eisa_dev.hba.iommu = ccio_get_iommu(dev);
diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c
index 6d8aae003f6c..c709ecc2b7f7 100644
--- a/drivers/parisc/eisa_enumerator.c
+++ b/drivers/parisc/eisa_enumerator.c
@@ -98,7 +98,7 @@ static int configure_memory(const unsigned char *buf,
res->start = mem_parent->start + get_24(buf+len+2);
res->end = res->start + get_16(buf+len+5)*1024;
res->flags = IORESOURCE_MEM;
- printk("memory %lx-%lx ", res->start, res->end);
+ printk("memory %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
result = request_resource(mem_parent, res);
if (result < 0) {
printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
@@ -188,7 +188,7 @@ static int configure_port(const unsigned char *buf, struct resource *io_parent,
res->start = get_16(buf+len+1);
res->end = get_16(buf+len+1)+(c&HPEE_PORT_SIZE_MASK)+1;
res->flags = IORESOURCE_IO;
- printk("ioports %lx-%lx ", res->start, res->end);
+ printk("ioports %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
result = request_resource(io_parent, res);
if (result < 0) {
printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 501aaf1f253f..73348c4047e9 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -714,7 +714,7 @@ static void iosapic_set_affinity_irq(unsigned int irq,
if (dest_cpu < 0)
return;
- irq_desc[irq].affinity = cpumask_of_cpu(dest_cpu);
+ cpumask_copy(irq_desc[irq].affinity, cpumask_of(dest_cpu));
vi->txn_addr = txn_affinity_addr(irq, dest_cpu);
spin_lock_irqsave(&iosapic_lock, flags);
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index 454b6532e409..9581d3619450 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -3,7 +3,7 @@
*
* (c) Copyright 2000 Red Hat Software
* (c) Copyright 2000 Helge Deller <hdeller@redhat.com>
- * (c) Copyright 2001-2005 Helge Deller <deller@gmx.de>
+ * (c) Copyright 2001-2009 Helge Deller <deller@gmx.de>
* (c) Copyright 2001 Randolph Chung <tausq@debian.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -243,13 +243,11 @@ static int __init led_create_procfs(void)
proc_pdc_root = proc_mkdir("pdc", 0);
if (!proc_pdc_root) return -1;
- proc_pdc_root->owner = THIS_MODULE;
ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
if (!ent) return -1;
ent->data = (void *)LED_NOLCD; /* LED */
ent->read_proc = led_proc_read;
ent->write_proc = led_proc_write;
- ent->owner = THIS_MODULE;
if (led_type == LED_HASLCD)
{
@@ -258,7 +256,6 @@ static int __init led_create_procfs(void)
ent->data = (void *)LED_HASLCD; /* LCD */
ent->read_proc = led_proc_read;
ent->write_proc = led_proc_write;
- ent->owner = THIS_MODULE;
}
return 0;
@@ -463,9 +460,20 @@ static void led_work_func (struct work_struct *unused)
if (likely(led_lanrxtx)) currentleds |= led_get_net_activity();
if (likely(led_diskio)) currentleds |= led_get_diskio_activity();
- /* blink all LEDs twice a second if we got an Oops (HPMC) */
- if (unlikely(oops_in_progress))
- currentleds = (count_HZ<=(HZ/2)) ? 0 : 0xff;
+ /* blink LEDs if we got an Oops (HPMC) */
+ if (unlikely(oops_in_progress)) {
+ if (boot_cpu_data.cpu_type >= pcxl2) {
+ /* newer machines don't have loadavg. LEDs, so we
+ * let all LEDs blink twice per second instead */
+ currentleds = (count_HZ <= (HZ/2)) ? 0 : 0xff;
+ } else {
+ /* old machines: blink loadavg. LEDs twice per second */
+ if (count_HZ <= (HZ/2))
+ currentleds &= ~(LED4|LED5|LED6|LED7);
+ else
+ currentleds |= (LED4|LED5|LED6|LED7);
+ }
+ }
if (currentleds != lastleds)
{
@@ -511,7 +519,7 @@ static int led_halt(struct notifier_block *nb, unsigned long event, void *buf)
/* Cancel the work item and delete the queue */
if (led_wq) {
- cancel_rearming_delayed_workqueue(led_wq, &led_task);
+ cancel_delayed_work_sync(&led_task);
destroy_workqueue(led_wq);
led_wq = NULL;
}
@@ -630,7 +638,7 @@ int lcd_print( const char *str )
/* temporarily disable the led work task */
if (led_wq)
- cancel_rearming_delayed_workqueue(led_wq, &led_task);
+ cancel_delayed_work_sync(&led_task);
/* copy display string to buffer for procfs */
strlcpy(lcd_text, str, sizeof(lcd_text));
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 032db815b0f9..f3492110b1ad 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -30,6 +30,7 @@ enum parport_pc_pci_cards {
titan_210l,
netmos_9xx5_combo,
netmos_9855,
+ netmos_9855_2p,
avlab_1s1p,
avlab_1s2p,
avlab_2s1p,
@@ -62,7 +63,7 @@ struct parport_pc_pci {
struct parport_pc_pci *card, int failed);
};
-static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *card, int autoirq, int autodma)
+static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *par, int autoirq, int autodma)
{
/* the rule described below doesn't hold for this device */
if (dev->device == PCI_DEVICE_ID_NETMOS_9835 &&
@@ -74,9 +75,17 @@ static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc
* and serial ports. The form is 0x00PS, where <P> is the number of
* parallel ports and <S> is the number of serial ports.
*/
- card->numports = (dev->subsystem_device & 0xf0) >> 4;
- if (card->numports > ARRAY_SIZE(card->addr))
- card->numports = ARRAY_SIZE(card->addr);
+ par->numports = (dev->subsystem_device & 0xf0) >> 4;
+ if (par->numports > ARRAY_SIZE(par->addr))
+ par->numports = ARRAY_SIZE(par->addr);
+ /*
+ * This function is currently only called for cards with up to
+ * one parallel port.
+ * Parallel port BAR is either before or after serial ports BARS;
+ * hence, lo should be either 0 or equal to the number of serial ports.
+ */
+ if (par->addr[0].lo != 0)
+ par->addr[0].lo = dev->subsystem_device & 0xf;
return 0;
}
@@ -84,7 +93,8 @@ static struct parport_pc_pci cards[] __devinitdata = {
/* titan_110l */ { 1, { { 3, -1 }, } },
/* titan_210l */ { 1, { { 3, -1 }, } },
/* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init },
- /* netmos_9855 */ { 1, { { 2, -1 }, }, netmos_parallel_init },
+ /* netmos_9855 */ { 1, { { 0, -1 }, }, netmos_parallel_init },
+ /* netmos_9855_2p */ { 2, { { 0, -1 }, { 2, -1 }, } },
/* avlab_1s1p */ { 1, { { 1, 2}, } },
/* avlab_1s2p */ { 2, { { 1, 2}, { 3, 4 },} },
/* avlab_2s1p */ { 1, { { 2, 3}, } },
@@ -110,6 +120,10 @@ static struct pci_device_id parport_serial_pci_tbl[] = {
{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
+ 0x1000, 0x0020, 0, 0, netmos_9855_2p },
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
+ 0x1000, 0x0022, 0, 0, netmos_9855_2p },
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
/* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
{ PCI_VENDOR_ID_AFAVLAB, 0x2110,
@@ -192,6 +206,12 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = {
.uart_offset = 8,
},
[netmos_9855] = {
+ .flags = FL_BASE2 | FL_BASE_BARS,
+ .num_ports = 1,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [netmos_9855_2p] = {
.flags = FL_BASE4 | FL_BASE_BARS,
.num_ports = 1,
.base_baud = 115200,
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 2a4501dd2515..fdc864f9cf23 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -59,3 +59,13 @@ config HT_IRQ
This allows native hypertransport devices to use interrupts.
If unsure say Y.
+
+config PCI_IOV
+ bool "PCI IOV support"
+ depends on PCI
+ help
+ I/O Virtualization is a PCI feature supported by some devices
+ which allows them to create virtual devices which share their
+ physical resources.
+
+ If unsure, say N.
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 3d07ce24f6a8..ba6af162fd39 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -29,6 +29,8 @@ obj-$(CONFIG_DMAR) += dmar.o iova.o intel-iommu.o
obj-$(CONFIG_INTR_REMAP) += dmar.o intr_remapping.o
+obj-$(CONFIG_PCI_IOV) += iov.o
+
#
# Some architectures use the generic PCI setup functions
#
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 52b54f053be0..68f91a252595 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -133,7 +133,7 @@ int pci_bus_add_child(struct pci_bus *bus)
*
* Call hotplug for each new devices.
*/
-void pci_bus_add_devices(struct pci_bus *bus)
+void pci_bus_add_devices(const struct pci_bus *bus)
{
struct pci_dev *dev;
struct pci_bus *child;
@@ -184,8 +184,10 @@ void pci_enable_bridges(struct pci_bus *bus)
list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->subordinate) {
- retval = pci_enable_device(dev);
- pci_set_master(dev);
+ if (atomic_read(&dev->enable_cnt) == 0) {
+ retval = pci_enable_device(dev);
+ pci_set_master(dev);
+ }
pci_enable_bridges(dev->subordinate);
}
}
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 5f333403c2ea..25a00ce4f24d 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -31,6 +31,8 @@
#include <linux/iova.h>
#include <linux/intel-iommu.h>
#include <linux/timer.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
#undef PREFIX
#define PREFIX "DMAR:"
@@ -178,6 +180,7 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
dmaru->hdr = header;
drhd = (struct acpi_dmar_hardware_unit *)header;
dmaru->reg_base_addr = drhd->address;
+ dmaru->segment = drhd->segment;
dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
ret = alloc_iommu(dmaru);
@@ -509,6 +512,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
return -ENOMEM;
iommu->seq_id = iommu_allocated++;
+ sprintf (iommu->name, "dmar%d", iommu->seq_id);
iommu->reg = ioremap(drhd->reg_base_addr, VTD_PAGE_SIZE);
if (!iommu->reg) {
@@ -751,14 +755,77 @@ int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
}
/*
+ * Disable Queued Invalidation interface.
+ */
+void dmar_disable_qi(struct intel_iommu *iommu)
+{
+ unsigned long flags;
+ u32 sts;
+ cycles_t start_time = get_cycles();
+
+ if (!ecap_qis(iommu->ecap))
+ return;
+
+ spin_lock_irqsave(&iommu->register_lock, flags);
+
+ sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
+ if (!(sts & DMA_GSTS_QIES))
+ goto end;
+
+ /*
+ * Give a chance to HW to complete the pending invalidation requests.
+ */
+ while ((readl(iommu->reg + DMAR_IQT_REG) !=
+ readl(iommu->reg + DMAR_IQH_REG)) &&
+ (DMAR_OPERATION_TIMEOUT > (get_cycles() - start_time)))
+ cpu_relax();
+
+ iommu->gcmd &= ~DMA_GCMD_QIE;
+
+ writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
+
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl,
+ !(sts & DMA_GSTS_QIES), sts);
+end:
+ spin_unlock_irqrestore(&iommu->register_lock, flags);
+}
+
+/*
+ * Enable queued invalidation.
+ */
+static void __dmar_enable_qi(struct intel_iommu *iommu)
+{
+ u32 cmd, sts;
+ unsigned long flags;
+ struct q_inval *qi = iommu->qi;
+
+ qi->free_head = qi->free_tail = 0;
+ qi->free_cnt = QI_LENGTH;
+
+ spin_lock_irqsave(&iommu->register_lock, flags);
+
+ /* write zero to the tail reg */
+ writel(0, iommu->reg + DMAR_IQT_REG);
+
+ dmar_writeq(iommu->reg + DMAR_IQA_REG, virt_to_phys(qi->desc));
+
+ cmd = iommu->gcmd | DMA_GCMD_QIE;
+ iommu->gcmd |= DMA_GCMD_QIE;
+ writel(cmd, iommu->reg + DMAR_GCMD_REG);
+
+ /* Make sure hardware complete it */
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_QIES), sts);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flags);
+}
+
+/*
* Enable Queued Invalidation interface. This is a must to support
* interrupt-remapping. Also used by DMA-remapping, which replaces
* register based IOTLB invalidation.
*/
int dmar_enable_qi(struct intel_iommu *iommu)
{
- u32 cmd, sts;
- unsigned long flags;
struct q_inval *qi;
if (!ecap_qis(iommu->ecap))
@@ -770,20 +837,20 @@ int dmar_enable_qi(struct intel_iommu *iommu)
if (iommu->qi)
return 0;
- iommu->qi = kmalloc(sizeof(*qi), GFP_KERNEL);
+ iommu->qi = kmalloc(sizeof(*qi), GFP_ATOMIC);
if (!iommu->qi)
return -ENOMEM;
qi = iommu->qi;
- qi->desc = (void *)(get_zeroed_page(GFP_KERNEL));
+ qi->desc = (void *)(get_zeroed_page(GFP_ATOMIC));
if (!qi->desc) {
kfree(qi);
iommu->qi = 0;
return -ENOMEM;
}
- qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_KERNEL);
+ qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC);
if (!qi->desc_status) {
free_page((unsigned long) qi->desc);
kfree(qi);
@@ -796,19 +863,283 @@ int dmar_enable_qi(struct intel_iommu *iommu)
spin_lock_init(&qi->q_lock);
- spin_lock_irqsave(&iommu->register_lock, flags);
- /* write zero to the tail reg */
- writel(0, iommu->reg + DMAR_IQT_REG);
+ __dmar_enable_qi(iommu);
- dmar_writeq(iommu->reg + DMAR_IQA_REG, virt_to_phys(qi->desc));
+ return 0;
+}
- cmd = iommu->gcmd | DMA_GCMD_QIE;
- iommu->gcmd |= DMA_GCMD_QIE;
- writel(cmd, iommu->reg + DMAR_GCMD_REG);
+/* iommu interrupt handling. Most stuff are MSI-like. */
- /* Make sure hardware complete it */
- IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_QIES), sts);
- spin_unlock_irqrestore(&iommu->register_lock, flags);
+enum faulttype {
+ DMA_REMAP,
+ INTR_REMAP,
+ UNKNOWN,
+};
+
+static const char *dma_remap_fault_reasons[] =
+{
+ "Software",
+ "Present bit in root entry is clear",
+ "Present bit in context entry is clear",
+ "Invalid context entry",
+ "Access beyond MGAW",
+ "PTE Write access is not set",
+ "PTE Read access is not set",
+ "Next page table ptr is invalid",
+ "Root table address invalid",
+ "Context table ptr is invalid",
+ "non-zero reserved fields in RTP",
+ "non-zero reserved fields in CTP",
+ "non-zero reserved fields in PTE",
+};
+
+static const char *intr_remap_fault_reasons[] =
+{
+ "Detected reserved fields in the decoded interrupt-remapped request",
+ "Interrupt index exceeded the interrupt-remapping table size",
+ "Present field in the IRTE entry is clear",
+ "Error accessing interrupt-remapping table pointed by IRTA_REG",
+ "Detected reserved fields in the IRTE entry",
+ "Blocked a compatibility format interrupt request",
+ "Blocked an interrupt request due to source-id verification failure",
+};
+
+#define MAX_FAULT_REASON_IDX (ARRAY_SIZE(fault_reason_strings) - 1)
+
+const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
+{
+ if (fault_reason >= 0x20 && (fault_reason <= 0x20 +
+ ARRAY_SIZE(intr_remap_fault_reasons))) {
+ *fault_type = INTR_REMAP;
+ return intr_remap_fault_reasons[fault_reason - 0x20];
+ } else if (fault_reason < ARRAY_SIZE(dma_remap_fault_reasons)) {
+ *fault_type = DMA_REMAP;
+ return dma_remap_fault_reasons[fault_reason];
+ } else {
+ *fault_type = UNKNOWN;
+ return "Unknown";
+ }
+}
+
+void dmar_msi_unmask(unsigned int irq)
+{
+ struct intel_iommu *iommu = get_irq_data(irq);
+ unsigned long flag;
+
+ /* unmask it */
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ writel(0, iommu->reg + DMAR_FECTL_REG);
+ /* Read a reg to force flush the post write */
+ readl(iommu->reg + DMAR_FECTL_REG);
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_mask(unsigned int irq)
+{
+ unsigned long flag;
+ struct intel_iommu *iommu = get_irq_data(irq);
+
+ /* mask it */
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG);
+ /* Read a reg to force flush the post write */
+ readl(iommu->reg + DMAR_FECTL_REG);
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_write(int irq, struct msi_msg *msg)
+{
+ struct intel_iommu *iommu = get_irq_data(irq);
+ unsigned long flag;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ writel(msg->data, iommu->reg + DMAR_FEDATA_REG);
+ writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG);
+ writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG);
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_read(int irq, struct msi_msg *msg)
+{
+ struct intel_iommu *iommu = get_irq_data(irq);
+ unsigned long flag;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ msg->data = readl(iommu->reg + DMAR_FEDATA_REG);
+ msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG);
+ msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG);
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+static int dmar_fault_do_one(struct intel_iommu *iommu, int type,
+ u8 fault_reason, u16 source_id, unsigned long long addr)
+{
+ const char *reason;
+ int fault_type;
+
+ reason = dmar_get_fault_reason(fault_reason, &fault_type);
+
+ if (fault_type == INTR_REMAP)
+ printk(KERN_ERR "INTR-REMAP: Request device [[%02x:%02x.%d] "
+ "fault index %llx\n"
+ "INTR-REMAP:[fault reason %02d] %s\n",
+ (source_id >> 8), PCI_SLOT(source_id & 0xFF),
+ PCI_FUNC(source_id & 0xFF), addr >> 48,
+ fault_reason, reason);
+ else
+ printk(KERN_ERR
+ "DMAR:[%s] Request device [%02x:%02x.%d] "
+ "fault addr %llx \n"
+ "DMAR:[fault reason %02d] %s\n",
+ (type ? "DMA Read" : "DMA Write"),
+ (source_id >> 8), PCI_SLOT(source_id & 0xFF),
+ PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
+ return 0;
+}
+
+#define PRIMARY_FAULT_REG_LEN (16)
+irqreturn_t dmar_fault(int irq, void *dev_id)
+{
+ struct intel_iommu *iommu = dev_id;
+ int reg, fault_index;
+ u32 fault_status;
+ unsigned long flag;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ fault_status = readl(iommu->reg + DMAR_FSTS_REG);
+ if (fault_status)
+ printk(KERN_ERR "DRHD: handling fault status reg %x\n",
+ fault_status);
+
+ /* TBD: ignore advanced fault log currently */
+ if (!(fault_status & DMA_FSTS_PPF))
+ goto clear_rest;
+
+ fault_index = dma_fsts_fault_record_index(fault_status);
+ reg = cap_fault_reg_offset(iommu->cap);
+ while (1) {
+ u8 fault_reason;
+ u16 source_id;
+ u64 guest_addr;
+ int type;
+ u32 data;
+
+ /* highest 32 bits */
+ data = readl(iommu->reg + reg +
+ fault_index * PRIMARY_FAULT_REG_LEN + 12);
+ if (!(data & DMA_FRCD_F))
+ break;
+
+ fault_reason = dma_frcd_fault_reason(data);
+ type = dma_frcd_type(data);
+
+ data = readl(iommu->reg + reg +
+ fault_index * PRIMARY_FAULT_REG_LEN + 8);
+ source_id = dma_frcd_source_id(data);
+
+ guest_addr = dmar_readq(iommu->reg + reg +
+ fault_index * PRIMARY_FAULT_REG_LEN);
+ guest_addr = dma_frcd_page_addr(guest_addr);
+ /* clear the fault */
+ writel(DMA_FRCD_F, iommu->reg + reg +
+ fault_index * PRIMARY_FAULT_REG_LEN + 12);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+
+ dmar_fault_do_one(iommu, type, fault_reason,
+ source_id, guest_addr);
+
+ fault_index++;
+ if (fault_index > cap_num_fault_regs(iommu->cap))
+ fault_index = 0;
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ }
+clear_rest:
+ /* clear all the other faults */
+ fault_status = readl(iommu->reg + DMAR_FSTS_REG);
+ writel(fault_status, iommu->reg + DMAR_FSTS_REG);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+ return IRQ_HANDLED;
+}
+
+int dmar_set_interrupt(struct intel_iommu *iommu)
+{
+ int irq, ret;
+
+ /*
+ * Check if the fault interrupt is already initialized.
+ */
+ if (iommu->irq)
+ return 0;
+
+ irq = create_irq();
+ if (!irq) {
+ printk(KERN_ERR "IOMMU: no free vectors\n");
+ return -EINVAL;
+ }
+
+ set_irq_data(irq, iommu);
+ iommu->irq = irq;
+
+ ret = arch_setup_dmar_msi(irq);
+ if (ret) {
+ set_irq_data(irq, NULL);
+ iommu->irq = 0;
+ destroy_irq(irq);
+ return 0;
+ }
+
+ ret = request_irq(irq, dmar_fault, 0, iommu->name, iommu);
+ if (ret)
+ printk(KERN_ERR "IOMMU: can't request irq\n");
+ return ret;
+}
+
+int __init enable_drhd_fault_handling(void)
+{
+ struct dmar_drhd_unit *drhd;
+
+ /*
+ * Enable fault control interrupt.
+ */
+ for_each_drhd_unit(drhd) {
+ int ret;
+ struct intel_iommu *iommu = drhd->iommu;
+ ret = dmar_set_interrupt(iommu);
+
+ if (ret) {
+ printk(KERN_ERR "DRHD %Lx: failed to enable fault, "
+ " interrupt, ret %d\n",
+ (unsigned long long)drhd->reg_base_addr, ret);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Re-enable Queued Invalidation interface.
+ */
+int dmar_reenable_qi(struct intel_iommu *iommu)
+{
+ if (!ecap_qis(iommu->ecap))
+ return -ENOENT;
+
+ if (!iommu->qi)
+ return -ENOENT;
+
+ /*
+ * First disable queued invalidation.
+ */
+ dmar_disable_qi(iommu);
+ /*
+ * Then enable queued invalidation again. Since there is no pending
+ * invalidation requests now, it's safe to re-enable queued
+ * invalidation.
+ */
+ __dmar_enable_qi(iommu);
return 0;
}
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index 1c1141801060..fbc63d5e459f 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -30,9 +30,8 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
+#include <linux/acpi.h>
#include <linux/pci-acpi.h>
-#include <acpi/acpi.h>
-#include <acpi/acpi_bus.h>
#define MY_NAME "acpi_pcihp"
@@ -333,19 +332,14 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
{
acpi_status status = AE_NOT_FOUND;
acpi_handle handle, phandle;
- struct pci_bus *pbus = bus;
- struct pci_dev *pdev;
-
- do {
- pdev = pbus->self;
- if (!pdev) {
- handle = acpi_get_pci_rootbridge_handle(
- pci_domain_nr(pbus), pbus->number);
+ struct pci_bus *pbus;
+
+ handle = NULL;
+ for (pbus = bus; pbus; pbus = pbus->parent) {
+ handle = acpi_pci_get_bridge_handle(pbus);
+ if (handle)
break;
- }
- handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
- pbus = pbus->parent;
- } while (!handle);
+ }
/*
* _HPP settings apply to all child buses, until another _HPP is
@@ -378,12 +372,10 @@ EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware);
*
* Attempt to take hotplug control from firmware.
*/
-int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
+int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)
{
acpi_status status;
acpi_handle chandle, handle;
- struct pci_dev *pdev = dev;
- struct pci_bus *parent;
struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL |
@@ -408,33 +400,25 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
dbg("Trying to get hotplug control for %s\n",
(char *)string.pointer);
- status = pci_osc_control_set(handle, flags);
+ status = acpi_pci_osc_control_set(handle, flags);
if (ACPI_SUCCESS(status))
goto got_one;
kfree(string.pointer);
string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL };
}
- pdev = dev;
- handle = DEVICE_ACPI_HANDLE(&dev->dev);
- while (!handle) {
+ handle = DEVICE_ACPI_HANDLE(&pdev->dev);
+ if (!handle) {
/*
* This hotplug controller was not listed in the ACPI name
* space at all. Try to get acpi handle of parent pci bus.
*/
- if (!pdev || !pdev->bus->parent)
- break;
- parent = pdev->bus->parent;
- dbg("Could not find %s in acpi namespace, trying parent\n",
- pci_name(pdev));
- if (!parent->self)
- /* Parent must be a host bridge */
- handle = acpi_get_pci_rootbridge_handle(
- pci_domain_nr(parent),
- parent->number);
- else
- handle = DEVICE_ACPI_HANDLE(&(parent->self->dev));
- pdev = parent->self;
+ struct pci_bus *pbus;
+ for (pbus = pdev->bus; pbus; pbus = pbus->parent) {
+ handle = acpi_pci_get_bridge_handle(pbus);
+ if (handle)
+ break;
+ }
}
while (handle) {
@@ -453,13 +437,13 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
}
dbg("Cannot get control of hotplug hardware for pci %s\n",
- pci_name(dev));
+ pci_name(pdev));
kfree(string.pointer);
return -ENODEV;
got_one:
- dbg("Gained control for hotplug HW for pci %s (%s)\n", pci_name(dev),
- (char *)string.pointer);
+ dbg("Gained control for hotplug HW for pci %s (%s)\n",
+ pci_name(pdev), (char *)string.pointer);
kfree(string.pointer);
return 0;
}
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
index a13abf55d784..8450f4a6568a 100644
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -225,7 +225,8 @@ void cpqhp_shutdown_debugfs(void)
void cpqhp_create_debugfs_files(struct controller *ctrl)
{
- ctrl->dentry = debugfs_create_file(ctrl->pci_dev->dev.bus_id, S_IRUGO, root, ctrl, &debug_ops);
+ ctrl->dentry = debugfs_create_file(dev_name(&ctrl->pci_dev->dev),
+ S_IRUGO, root, ctrl, &debug_ops);
}
void cpqhp_remove_debugfs_files(struct controller *ctrl)
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
index d8649e127298..6151389fd903 100644
--- a/drivers/pci/hotplug/fakephp.c
+++ b/drivers/pci/hotplug/fakephp.c
@@ -1,395 +1,163 @@
-/*
- * Fake PCI Hot Plug Controller Driver
+/* Works like the fakephp driver used to, except a little better.
*
- * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (C) 2003 IBM Corp.
- * Copyright (C) 2003 Rolf Eike Beer <eike-kernel@sf-tec.de>
+ * - It's possible to remove devices with subordinate busses.
+ * - New PCI devices that appear via any method, not just a fakephp triggered
+ * rescan, will be noticed.
+ * - Devices that are removed via any method, not just a fakephp triggered
+ * removal, will also be noticed.
*
- * Based on ideas and code from:
- * Vladimir Kondratiev <vladimir.kondratiev@intel.com>
- * Rolf Eike Beer <eike-kernel@sf-tec.de>
+ * Uses nothing from the pci-hotplug subsystem.
*
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2 of the License.
- *
- * Send feedback to <greg@kroah.com>
*/
-/*
- *
- * This driver will "emulate" removing PCI devices from the system. If
- * the "power" file is written to with "0" then the specified PCI device
- * will be completely removed from the kernel.
- *
- * WARNING, this does NOT turn off the power to the PCI device. This is
- * a "logical" removal, not a physical or electrical removal.
- *
- * Use this module at your own risk, you have been warned!
- *
- * Enabling PCI devices is left as an exercise for the reader...
- *
- */
-#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/pci_hotplug.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
+#include <linux/pci.h>
+#include <linux/device.h>
#include "../pci.h"
-#if !defined(MODULE)
- #define MY_NAME "fakephp"
-#else
- #define MY_NAME THIS_MODULE->name
-#endif
-
-#define dbg(format, arg...) \
- do { \
- if (debug) \
- printk(KERN_DEBUG "%s: " format, \
- MY_NAME , ## arg); \
- } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
-
-#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
-#define DRIVER_DESC "Fake PCI Hot Plug Controller Driver"
-
-struct dummy_slot {
- struct list_head node;
- struct hotplug_slot *slot;
- struct pci_dev *dev;
- struct work_struct remove_work;
- unsigned long removed;
+struct legacy_slot {
+ struct kobject kobj;
+ struct pci_dev *dev;
+ struct list_head list;
};
-static int debug;
-static int dup_slots;
-static LIST_HEAD(slot_list);
-static struct workqueue_struct *dummyphp_wq;
-
-static void pci_rescan_worker(struct work_struct *work);
-static DECLARE_WORK(pci_rescan_work, pci_rescan_worker);
-
-static int enable_slot (struct hotplug_slot *slot);
-static int disable_slot (struct hotplug_slot *slot);
+static LIST_HEAD(legacy_list);
-static struct hotplug_slot_ops dummy_hotplug_slot_ops = {
- .owner = THIS_MODULE,
- .enable_slot = enable_slot,
- .disable_slot = disable_slot,
-};
-
-static void dummy_release(struct hotplug_slot *slot)
+static ssize_t legacy_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
{
- struct dummy_slot *dslot = slot->private;
-
- list_del(&dslot->node);
- kfree(dslot->slot->info);
- kfree(dslot->slot);
- pci_dev_put(dslot->dev);
- kfree(dslot);
+ struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
+ strcpy(buf, "1\n");
+ return 2;
}
-#define SLOT_NAME_SIZE 8
-
-static int add_slot(struct pci_dev *dev)
+static void remove_callback(void *data)
{
- struct dummy_slot *dslot;
- struct hotplug_slot *slot;
- char name[SLOT_NAME_SIZE];
- int retval = -ENOMEM;
- static int count = 1;
-
- slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
- if (!slot)
- goto error;
-
- slot->info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
- if (!slot->info)
- goto error_slot;
-
- slot->info->power_status = 1;
- slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
- slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
-
- dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL);
- if (!dslot)
- goto error_info;
-
- if (dup_slots)
- snprintf(name, SLOT_NAME_SIZE, "fake");
- else
- snprintf(name, SLOT_NAME_SIZE, "fake%d", count++);
- dbg("slot->name = %s\n", name);
- slot->ops = &dummy_hotplug_slot_ops;
- slot->release = &dummy_release;
- slot->private = dslot;
-
- retval = pci_hp_register(slot, dev->bus, PCI_SLOT(dev->devfn), name);
- if (retval) {
- err("pci_hp_register failed with error %d\n", retval);
- goto error_dslot;
- }
-
- dbg("slot->name = %s\n", hotplug_slot_name(slot));
- dslot->slot = slot;
- dslot->dev = pci_dev_get(dev);
- list_add (&dslot->node, &slot_list);
- return retval;
-
-error_dslot:
- kfree(dslot);
-error_info:
- kfree(slot->info);
-error_slot:
- kfree(slot);
-error:
- return retval;
+ pci_remove_bus_device((struct pci_dev *)data);
}
-static int __init pci_scan_buses(void)
+static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr,
+ const char *buf, size_t len)
{
- struct pci_dev *dev = NULL;
- int lastslot = 0;
+ struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
+ unsigned long val;
- while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- if (PCI_FUNC(dev->devfn) > 0 &&
- lastslot == PCI_SLOT(dev->devfn))
- continue;
- lastslot = PCI_SLOT(dev->devfn);
- add_slot(dev);
- }
+ if (strict_strtoul(buf, 0, &val) < 0)
+ return -EINVAL;
- return 0;
+ if (val)
+ pci_rescan_bus(slot->dev->bus);
+ else
+ sysfs_schedule_callback(&slot->dev->dev.kobj, remove_callback,
+ slot->dev, THIS_MODULE);
+ return len;
}
-static void remove_slot(struct dummy_slot *dslot)
-{
- int retval;
-
- dbg("removing slot %s\n", hotplug_slot_name(dslot->slot));
- retval = pci_hp_deregister(dslot->slot);
- if (retval)
- err("Problem unregistering a slot %s\n",
- hotplug_slot_name(dslot->slot));
-}
+static struct attribute *legacy_attrs[] = {
+ &(struct attribute){ .name = "power", .mode = 0644 },
+ NULL,
+};
-/* called from the single-threaded workqueue handler to remove a slot */
-static void remove_slot_worker(struct work_struct *work)
+static void legacy_release(struct kobject *kobj)
{
- struct dummy_slot *dslot =
- container_of(work, struct dummy_slot, remove_work);
- remove_slot(dslot);
-}
+ struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
-/**
- * pci_rescan_slot - Rescan slot
- * @temp: Device template. Should be set: bus and devfn.
- *
- * Tries hard not to re-enable already existing devices;
- * also handles scanning of subfunctions.
- */
-static int pci_rescan_slot(struct pci_dev *temp)
-{
- struct pci_bus *bus = temp->bus;
- struct pci_dev *dev;
- int func;
- u8 hdr_type;
- int count = 0;
-
- if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
- temp->hdr_type = hdr_type & 0x7f;
- if ((dev = pci_get_slot(bus, temp->devfn)) != NULL)
- pci_dev_put(dev);
- else {
- dev = pci_scan_single_device(bus, temp->devfn);
- if (dev) {
- dbg("New device on %s function %x:%x\n",
- bus->name, temp->devfn >> 3,
- temp->devfn & 7);
- count++;
- }
- }
- /* multifunction device? */
- if (!(hdr_type & 0x80))
- return count;
-
- /* continue scanning for other functions */
- for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
- if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
- continue;
- temp->hdr_type = hdr_type & 0x7f;
-
- if ((dev = pci_get_slot(bus, temp->devfn)) != NULL)
- pci_dev_put(dev);
- else {
- dev = pci_scan_single_device(bus, temp->devfn);
- if (dev) {
- dbg("New device on %s function %x:%x\n",
- bus->name, temp->devfn >> 3,
- temp->devfn & 7);
- count++;
- }
- }
- }
- }
-
- return count;
+ pci_dev_put(slot->dev);
+ kfree(slot);
}
+static struct kobj_type legacy_ktype = {
+ .sysfs_ops = &(struct sysfs_ops){
+ .store = legacy_store, .show = legacy_show
+ },
+ .release = &legacy_release,
+ .default_attrs = legacy_attrs,
+};
-/**
- * pci_rescan_bus - Rescan PCI bus
- * @bus: the PCI bus to rescan
- *
- * Call pci_rescan_slot for each possible function of the bus.
- */
-static void pci_rescan_bus(const struct pci_bus *bus)
+static int legacy_add_slot(struct pci_dev *pdev)
{
- unsigned int devfn;
- struct pci_dev *dev;
- int retval;
- int found = 0;
- dev = alloc_pci_dev();
- if (!dev)
- return;
+ struct legacy_slot *slot = kzalloc(sizeof(*slot), GFP_KERNEL);
- dev->bus = (struct pci_bus*)bus;
- dev->sysdata = bus->sysdata;
- for (devfn = 0; devfn < 0x100; devfn += 8) {
- dev->devfn = devfn;
- found += pci_rescan_slot(dev);
- }
-
- if (found) {
- pci_bus_assign_resources(bus);
- list_for_each_entry(dev, &bus->devices, bus_list) {
- /* Skip already-added devices */
- if (dev->is_added)
- continue;
- retval = pci_bus_add_device(dev);
- if (retval)
- dev_err(&dev->dev,
- "Error adding device, continuing\n");
- else
- add_slot(dev);
- }
- pci_bus_add_devices(bus);
- }
- kfree(dev);
-}
+ if (!slot)
+ return -ENOMEM;
-/* recursively scan all buses */
-static void pci_rescan_buses(const struct list_head *list)
-{
- const struct list_head *l;
- list_for_each(l,list) {
- const struct pci_bus *b = pci_bus_b(l);
- pci_rescan_bus(b);
- pci_rescan_buses(&b->children);
+ if (kobject_init_and_add(&slot->kobj, &legacy_ktype,
+ &pci_slots_kset->kobj, "%s",
+ dev_name(&pdev->dev))) {
+ dev_warn(&pdev->dev, "Failed to created legacy fake slot\n");
+ return -EINVAL;
}
-}
+ slot->dev = pci_dev_get(pdev);
-/* initiate rescan of all pci buses */
-static inline void pci_rescan(void) {
- pci_rescan_buses(&pci_root_buses);
-}
-
-/* called from the single-threaded workqueue handler to rescan all pci buses */
-static void pci_rescan_worker(struct work_struct *work)
-{
- pci_rescan();
-}
+ list_add(&slot->list, &legacy_list);
-static int enable_slot(struct hotplug_slot *hotplug_slot)
-{
- /* mis-use enable_slot for rescanning of the pci bus */
- cancel_work_sync(&pci_rescan_work);
- queue_work(dummyphp_wq, &pci_rescan_work);
return 0;
}
-static int disable_slot(struct hotplug_slot *slot)
+static int legacy_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
{
- struct dummy_slot *dslot;
- struct pci_dev *dev;
- int func;
-
- if (!slot)
- return -ENODEV;
- dslot = slot->private;
-
- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(slot));
+ struct pci_dev *pdev = to_pci_dev(data);
- for (func = 7; func >= 0; func--) {
- dev = pci_get_slot(dslot->dev->bus, dslot->dev->devfn + func);
- if (!dev)
- continue;
+ if (action == BUS_NOTIFY_ADD_DEVICE) {
+ legacy_add_slot(pdev);
+ } else if (action == BUS_NOTIFY_DEL_DEVICE) {
+ struct legacy_slot *slot;
- if (test_and_set_bit(0, &dslot->removed)) {
- dbg("Slot already scheduled for removal\n");
- pci_dev_put(dev);
- return -ENODEV;
- }
+ list_for_each_entry(slot, &legacy_list, list)
+ if (slot->dev == pdev)
+ goto found;
- /* remove the device from the pci core */
- pci_remove_bus_device(dev);
-
- /* queue work item to blow away this sysfs entry and other
- * parts.
- */
- INIT_WORK(&dslot->remove_work, remove_slot_worker);
- queue_work(dummyphp_wq, &dslot->remove_work);
-
- pci_dev_put(dev);
+ dev_warn(&pdev->dev, "Missing legacy fake slot?");
+ return -ENODEV;
+found:
+ kobject_del(&slot->kobj);
+ list_del(&slot->list);
+ kobject_put(&slot->kobj);
}
+
return 0;
}
-static void cleanup_slots (void)
-{
- struct list_head *tmp;
- struct list_head *next;
- struct dummy_slot *dslot;
-
- destroy_workqueue(dummyphp_wq);
- list_for_each_safe (tmp, next, &slot_list) {
- dslot = list_entry (tmp, struct dummy_slot, node);
- remove_slot(dslot);
- }
-
-}
+static struct notifier_block legacy_notifier = {
+ .notifier_call = legacy_notify
+};
-static int __init dummyphp_init(void)
+static int __init init_legacy(void)
{
- info(DRIVER_DESC "\n");
+ struct pci_dev *pdev = NULL;
- dummyphp_wq = create_singlethread_workqueue(MY_NAME);
- if (!dummyphp_wq)
- return -ENOMEM;
+ /* Add existing devices */
+ while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)))
+ legacy_add_slot(pdev);
- return pci_scan_buses();
+ /* Be alerted of any new ones */
+ bus_register_notifier(&pci_bus_type, &legacy_notifier);
+ return 0;
}
+module_init(init_legacy);
-
-static void __exit dummyphp_exit(void)
+static void __exit remove_legacy(void)
{
- cleanup_slots();
+ struct legacy_slot *slot, *tmp;
+
+ bus_unregister_notifier(&pci_bus_type, &legacy_notifier);
+
+ list_for_each_entry_safe(slot, tmp, &legacy_list, list) {
+ list_del(&slot->list);
+ kobject_del(&slot->kobj);
+ kobject_put(&slot->kobj);
+ }
}
+module_exit(remove_legacy);
-module_init(dummyphp_init);
-module_exit(dummyphp_exit);
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Trent Piepho <xyzzy@speakeasy.org>");
+MODULE_DESCRIPTION("Legacy version of the fakephp interface");
MODULE_LICENSE("GPL");
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
-module_param(dup_slots, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(dup_slots, "Force duplicate slot names for debugging");
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 39ae37589fda..0a368547e633 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -46,10 +46,10 @@ extern int pciehp_force;
extern struct workqueue_struct *pciehp_wq;
#define dbg(format, arg...) \
- do { \
- if (pciehp_debug) \
- printk("%s: " format, MY_NAME , ## arg); \
- } while (0)
+do { \
+ if (pciehp_debug) \
+ printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); \
+} while (0)
#define err(format, arg...) \
printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
#define info(format, arg...) \
@@ -60,7 +60,7 @@ extern struct workqueue_struct *pciehp_wq;
#define ctrl_dbg(ctrl, format, arg...) \
do { \
if (pciehp_debug) \
- dev_printk(, &ctrl->pcie->device, \
+ dev_printk(KERN_DEBUG, &ctrl->pcie->device, \
format, ## arg); \
} while (0)
#define ctrl_err(ctrl, format, arg...) \
@@ -108,10 +108,11 @@ struct controller {
u32 slot_cap;
u8 cap_base;
struct timer_list poll_timer;
- int cmd_busy;
+ unsigned int cmd_busy:1;
unsigned int no_cmd_complete:1;
unsigned int link_active_reporting:1;
unsigned int notification_enabled:1;
+ unsigned int power_fault_detected;
};
#define INT_BUTTON_IGNORE 0
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index 438d795f9fe3..96048010e7d9 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -67,37 +67,27 @@ static int __init parse_detect_mode(void)
return PCIEHP_DETECT_DEFAULT;
}
-static struct pcie_port_service_id __initdata port_pci_ids[] = {
- {
- .vendor = PCI_ANY_ID,
- .device = PCI_ANY_ID,
- .port_type = PCIE_ANY_PORT,
- .service_type = PCIE_PORT_SERVICE_HP,
- .driver_data = 0,
- }, { /* end: all zeroes */ }
-};
-
static int __initdata dup_slot_id;
static int __initdata acpi_slot_detected;
static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots);
/* Dummy driver for dumplicate name detection */
-static int __init dummy_probe(struct pcie_device *dev,
- const struct pcie_port_service_id *id)
+static int __init dummy_probe(struct pcie_device *dev)
{
int pos;
u32 slot_cap;
struct slot *slot, *tmp;
struct pci_dev *pdev = dev->port;
struct pci_bus *pbus = pdev->subordinate;
- if (!(slot = kzalloc(sizeof(*slot), GFP_KERNEL)))
- return -ENOMEM;
/* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */
if (pciehp_get_hp_hw_control_from_firmware(pdev))
return -ENODEV;
if (!(pos = pci_find_capability(pdev, PCI_CAP_ID_EXP)))
return -ENODEV;
pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap);
+ slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+ if (!slot)
+ return -ENOMEM;
slot->number = slot_cap >> 19;
list_for_each_entry(tmp, &dummy_slots, slot_list) {
if (tmp->number == slot->number)
@@ -111,7 +101,8 @@ static int __init dummy_probe(struct pcie_device *dev,
static struct pcie_port_service_driver __initdata dummy_driver = {
.name = "pciehp_dummy",
- .id_table = port_pci_ids,
+ .port_type = PCIE_ANY_PORT,
+ .service = PCIE_PORT_SERVICE_HP,
.probe = dummy_probe,
};
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 681e3912b821..fb254b2454de 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -401,7 +401,7 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
return 0;
}
-static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_id *id)
+static int pciehp_probe(struct pcie_device *dev)
{
int rc;
struct controller *ctrl;
@@ -475,7 +475,7 @@ static void pciehp_remove (struct pcie_device *dev)
}
#ifdef CONFIG_PM
-static int pciehp_suspend (struct pcie_device *dev, pm_message_t state)
+static int pciehp_suspend (struct pcie_device *dev)
{
dev_info(&dev->device, "%s ENTRY\n", __func__);
return 0;
@@ -503,20 +503,12 @@ static int pciehp_resume (struct pcie_device *dev)
}
return 0;
}
-#endif
-
-static struct pcie_port_service_id port_pci_ids[] = { {
- .vendor = PCI_ANY_ID,
- .device = PCI_ANY_ID,
- .port_type = PCIE_ANY_PORT,
- .service_type = PCIE_PORT_SERVICE_HP,
- .driver_data = 0,
- }, { /* end: all zeroes */ }
-};
+#endif /* PM */
static struct pcie_port_service_driver hpdriver_portdrv = {
.name = PCIE_MODULE_NAME,
- .id_table = &port_pci_ids[0],
+ .port_type = PCIE_ANY_PORT,
+ .service = PCIE_PORT_SERVICE_HP,
.probe = pciehp_probe,
.remove = pciehp_remove,
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 7a16c6897bb9..07bd32151146 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -548,23 +548,21 @@ static int hpc_power_on_slot(struct slot * slot)
slot_cmd = POWER_ON;
cmd_mask = PCI_EXP_SLTCTL_PCC;
- /* Enable detection that we turned off at slot power-off time */
if (!pciehp_poll_mode) {
- slot_cmd |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
- PCI_EXP_SLTCTL_PDCE);
- cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
- PCI_EXP_SLTCTL_PDCE);
+ /* Enable power fault detection turned off at power off time */
+ slot_cmd |= PCI_EXP_SLTCTL_PFDE;
+ cmd_mask |= PCI_EXP_SLTCTL_PFDE;
}
retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-
if (retval) {
ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd);
- return -1;
+ return retval;
}
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+ ctrl->power_fault_detected = 0;
return retval;
}
@@ -621,18 +619,10 @@ static int hpc_power_off_slot(struct slot * slot)
slot_cmd = POWER_OFF;
cmd_mask = PCI_EXP_SLTCTL_PCC;
- /*
- * If we get MRL or presence detect interrupts now, the isr
- * will notice the sticky power-fault bit too and issue power
- * indicator change commands. This will lead to an endless loop
- * of command completions, since the power-fault bit remains on
- * till the slot is powered on again.
- */
if (!pciehp_poll_mode) {
- slot_cmd &= ~(PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
- PCI_EXP_SLTCTL_PDCE);
- cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
- PCI_EXP_SLTCTL_PDCE);
+ /* Disable power fault detection */
+ slot_cmd &= ~PCI_EXP_SLTCTL_PFDE;
+ cmd_mask |= PCI_EXP_SLTCTL_PFDE;
}
retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
@@ -672,10 +662,11 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC |
PCI_EXP_SLTSTA_CC);
+ detected &= ~intr_loc;
intr_loc |= detected;
if (!intr_loc)
return IRQ_NONE;
- if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, detected)) {
+ if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, intr_loc)) {
ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n",
__func__);
return IRQ_NONE;
@@ -709,9 +700,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
pciehp_handle_presence_change(p_slot);
/* Check Power Fault Detected */
- if (intr_loc & PCI_EXP_SLTSTA_PFD)
+ if ((intr_loc & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
+ ctrl->power_fault_detected = 1;
pciehp_handle_power_fault(p_slot);
-
+ }
return IRQ_HANDLED;
}
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 6aba0b6cf2e0..974e924ca96d 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -48,10 +48,10 @@ extern int shpchp_debug;
extern struct workqueue_struct *shpchp_wq;
#define dbg(format, arg...) \
- do { \
- if (shpchp_debug) \
- printk("%s: " format, MY_NAME , ## arg); \
- } while (0)
+do { \
+ if (shpchp_debug) \
+ printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); \
+} while (0)
#define err(format, arg...) \
printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
#define info(format, arg...) \
@@ -62,7 +62,7 @@ extern struct workqueue_struct *shpchp_wq;
#define ctrl_dbg(ctrl, format, arg...) \
do { \
if (shpchp_debug) \
- dev_printk(, &ctrl->pci_dev->dev, \
+ dev_printk(KERN_DEBUG, &ctrl->pci_dev->dev, \
format, ## arg); \
} while (0)
#define ctrl_err(ctrl, format, arg...) \
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index 138f161becc0..aa315e52529b 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -137,7 +137,7 @@ int __ref shpchp_configure_device(struct slot *p_slot)
busnr))
break;
}
- if (busnr >= end) {
+ if (busnr > end) {
ctrl_err(ctrl,
"No free bus for hot-added bridge\n");
pci_dev_put(dev);
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index f3f686581a90..dcda5212f3bb 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -36,6 +36,7 @@
#include <linux/iova.h>
#include <linux/iommu.h>
#include <linux/intel-iommu.h>
+#include <linux/sysdev.h>
#include <asm/cacheflush.h>
#include <asm/iommu.h>
#include "pci.h"
@@ -164,7 +165,8 @@ static inline void context_clear_entry(struct context_entry *context)
* 1: writable
* 2-6: reserved
* 7: super page
- * 8-11: available
+ * 8-10: available
+ * 11: snoop behavior
* 12-63: Host physcial address
*/
struct dma_pte {
@@ -186,6 +188,11 @@ static inline void dma_set_pte_writable(struct dma_pte *pte)
pte->val |= DMA_PTE_WRITE;
}
+static inline void dma_set_pte_snp(struct dma_pte *pte)
+{
+ pte->val |= DMA_PTE_SNP;
+}
+
static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot)
{
pte->val = (pte->val & ~3) | (prot & 3);
@@ -231,6 +238,7 @@ struct dmar_domain {
int flags; /* flags to find out type of domain */
int iommu_coherency;/* indicate coherency of iommu access */
+ int iommu_snooping; /* indicate snooping control feature*/
int iommu_count; /* reference count of iommu */
spinlock_t iommu_lock; /* protect iommu set in domain */
u64 max_addr; /* maximum mapped address */
@@ -240,7 +248,8 @@ struct dmar_domain {
struct device_domain_info {
struct list_head link; /* link to domain siblings */
struct list_head global; /* link to global list */
- u8 bus; /* PCI bus numer */
+ int segment; /* PCI domain */
+ u8 bus; /* PCI bus number */
u8 devfn; /* PCI devfn number */
struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */
struct dmar_domain *domain; /* pointer to domain */
@@ -421,7 +430,6 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
return g_iommus[iommu_id];
}
-/* "Coherency" capability may be different across iommus */
static void domain_update_iommu_coherency(struct dmar_domain *domain)
{
int i;
@@ -438,7 +446,30 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain)
}
}
-static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn)
+static void domain_update_iommu_snooping(struct dmar_domain *domain)
+{
+ int i;
+
+ domain->iommu_snooping = 1;
+
+ i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus);
+ for (; i < g_num_of_iommus; ) {
+ if (!ecap_sc_support(g_iommus[i]->ecap)) {
+ domain->iommu_snooping = 0;
+ break;
+ }
+ i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1);
+ }
+}
+
+/* Some capabilities may be different across iommus */
+static void domain_update_iommu_cap(struct dmar_domain *domain)
+{
+ domain_update_iommu_coherency(domain);
+ domain_update_iommu_snooping(domain);
+}
+
+static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn)
{
struct dmar_drhd_unit *drhd = NULL;
int i;
@@ -446,12 +477,20 @@ static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn)
for_each_drhd_unit(drhd) {
if (drhd->ignored)
continue;
+ if (segment != drhd->segment)
+ continue;
- for (i = 0; i < drhd->devices_cnt; i++)
+ for (i = 0; i < drhd->devices_cnt; i++) {
if (drhd->devices[i] &&
drhd->devices[i]->bus->number == bus &&
drhd->devices[i]->devfn == devfn)
return drhd->iommu;
+ if (drhd->devices[i] &&
+ drhd->devices[i]->subordinate &&
+ drhd->devices[i]->subordinate->number <= bus &&
+ drhd->devices[i]->subordinate->subordinate >= bus)
+ return drhd->iommu;
+ }
if (drhd->include_all)
return drhd->iommu;
@@ -689,15 +728,17 @@ static void dma_pte_clear_one(struct dmar_domain *domain, u64 addr)
static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end)
{
int addr_width = agaw_to_width(domain->agaw);
+ int npages;
start &= (((u64)1) << addr_width) - 1;
end &= (((u64)1) << addr_width) - 1;
/* in case it's partial page */
start = PAGE_ALIGN(start);
end &= PAGE_MASK;
+ npages = (end - start) / VTD_PAGE_SIZE;
/* we don't need lock here, nobody else touches the iova range */
- while (start < end) {
+ while (npages--) {
dma_pte_clear_one(domain, start);
start += VTD_PAGE_SIZE;
}
@@ -1004,194 +1045,6 @@ static int iommu_disable_translation(struct intel_iommu *iommu)
return 0;
}
-/* iommu interrupt handling. Most stuff are MSI-like. */
-
-static const char *fault_reason_strings[] =
-{
- "Software",
- "Present bit in root entry is clear",
- "Present bit in context entry is clear",
- "Invalid context entry",
- "Access beyond MGAW",
- "PTE Write access is not set",
- "PTE Read access is not set",
- "Next page table ptr is invalid",
- "Root table address invalid",
- "Context table ptr is invalid",
- "non-zero reserved fields in RTP",
- "non-zero reserved fields in CTP",
- "non-zero reserved fields in PTE",
-};
-#define MAX_FAULT_REASON_IDX (ARRAY_SIZE(fault_reason_strings) - 1)
-
-const char *dmar_get_fault_reason(u8 fault_reason)
-{
- if (fault_reason > MAX_FAULT_REASON_IDX)
- return "Unknown";
- else
- return fault_reason_strings[fault_reason];
-}
-
-void dmar_msi_unmask(unsigned int irq)
-{
- struct intel_iommu *iommu = get_irq_data(irq);
- unsigned long flag;
-
- /* unmask it */
- spin_lock_irqsave(&iommu->register_lock, flag);
- writel(0, iommu->reg + DMAR_FECTL_REG);
- /* Read a reg to force flush the post write */
- readl(iommu->reg + DMAR_FECTL_REG);
- spin_unlock_irqrestore(&iommu->register_lock, flag);
-}
-
-void dmar_msi_mask(unsigned int irq)
-{
- unsigned long flag;
- struct intel_iommu *iommu = get_irq_data(irq);
-
- /* mask it */
- spin_lock_irqsave(&iommu->register_lock, flag);
- writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG);
- /* Read a reg to force flush the post write */
- readl(iommu->reg + DMAR_FECTL_REG);
- spin_unlock_irqrestore(&iommu->register_lock, flag);
-}
-
-void dmar_msi_write(int irq, struct msi_msg *msg)
-{
- struct intel_iommu *iommu = get_irq_data(irq);
- unsigned long flag;
-
- spin_lock_irqsave(&iommu->register_lock, flag);
- writel(msg->data, iommu->reg + DMAR_FEDATA_REG);
- writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG);
- writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG);
- spin_unlock_irqrestore(&iommu->register_lock, flag);
-}
-
-void dmar_msi_read(int irq, struct msi_msg *msg)
-{
- struct intel_iommu *iommu = get_irq_data(irq);
- unsigned long flag;
-
- spin_lock_irqsave(&iommu->register_lock, flag);
- msg->data = readl(iommu->reg + DMAR_FEDATA_REG);
- msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG);
- msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG);
- spin_unlock_irqrestore(&iommu->register_lock, flag);
-}
-
-static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type,
- u8 fault_reason, u16 source_id, unsigned long long addr)
-{
- const char *reason;
-
- reason = dmar_get_fault_reason(fault_reason);
-
- printk(KERN_ERR
- "DMAR:[%s] Request device [%02x:%02x.%d] "
- "fault addr %llx \n"
- "DMAR:[fault reason %02d] %s\n",
- (type ? "DMA Read" : "DMA Write"),
- (source_id >> 8), PCI_SLOT(source_id & 0xFF),
- PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
- return 0;
-}
-
-#define PRIMARY_FAULT_REG_LEN (16)
-static irqreturn_t iommu_page_fault(int irq, void *dev_id)
-{
- struct intel_iommu *iommu = dev_id;
- int reg, fault_index;
- u32 fault_status;
- unsigned long flag;
-
- spin_lock_irqsave(&iommu->register_lock, flag);
- fault_status = readl(iommu->reg + DMAR_FSTS_REG);
-
- /* TBD: ignore advanced fault log currently */
- if (!(fault_status & DMA_FSTS_PPF))
- goto clear_overflow;
-
- fault_index = dma_fsts_fault_record_index(fault_status);
- reg = cap_fault_reg_offset(iommu->cap);
- while (1) {
- u8 fault_reason;
- u16 source_id;
- u64 guest_addr;
- int type;
- u32 data;
-
- /* highest 32 bits */
- data = readl(iommu->reg + reg +
- fault_index * PRIMARY_FAULT_REG_LEN + 12);
- if (!(data & DMA_FRCD_F))
- break;
-
- fault_reason = dma_frcd_fault_reason(data);
- type = dma_frcd_type(data);
-
- data = readl(iommu->reg + reg +
- fault_index * PRIMARY_FAULT_REG_LEN + 8);
- source_id = dma_frcd_source_id(data);
-
- guest_addr = dmar_readq(iommu->reg + reg +
- fault_index * PRIMARY_FAULT_REG_LEN);
- guest_addr = dma_frcd_page_addr(guest_addr);
- /* clear the fault */
- writel(DMA_FRCD_F, iommu->reg + reg +
- fault_index * PRIMARY_FAULT_REG_LEN + 12);
-
- spin_unlock_irqrestore(&iommu->register_lock, flag);
-
- iommu_page_fault_do_one(iommu, type, fault_reason,
- source_id, guest_addr);
-
- fault_index++;
- if (fault_index > cap_num_fault_regs(iommu->cap))
- fault_index = 0;
- spin_lock_irqsave(&iommu->register_lock, flag);
- }
-clear_overflow:
- /* clear primary fault overflow */
- fault_status = readl(iommu->reg + DMAR_FSTS_REG);
- if (fault_status & DMA_FSTS_PFO)
- writel(DMA_FSTS_PFO, iommu->reg + DMAR_FSTS_REG);
-
- spin_unlock_irqrestore(&iommu->register_lock, flag);
- return IRQ_HANDLED;
-}
-
-int dmar_set_interrupt(struct intel_iommu *iommu)
-{
- int irq, ret;
-
- irq = create_irq();
- if (!irq) {
- printk(KERN_ERR "IOMMU: no free vectors\n");
- return -EINVAL;
- }
-
- set_irq_data(irq, iommu);
- iommu->irq = irq;
-
- ret = arch_setup_dmar_msi(irq);
- if (ret) {
- set_irq_data(irq, NULL);
- iommu->irq = 0;
- destroy_irq(irq);
- return 0;
- }
-
- /* Force fault register is cleared */
- iommu_page_fault(irq, iommu);
-
- ret = request_irq(irq, iommu_page_fault, 0, iommu->name, iommu);
- if (ret)
- printk(KERN_ERR "IOMMU: can't request irq\n");
- return ret;
-}
static int iommu_init_domains(struct intel_iommu *iommu)
{
@@ -1429,6 +1282,11 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
else
domain->iommu_coherency = 0;
+ if (ecap_sc_support(iommu->ecap))
+ domain->iommu_snooping = 1;
+ else
+ domain->iommu_snooping = 0;
+
domain->iommu_count = 1;
/* always allocate the top pgd */
@@ -1464,7 +1322,7 @@ static void domain_exit(struct dmar_domain *domain)
}
static int domain_context_mapping_one(struct dmar_domain *domain,
- u8 bus, u8 devfn)
+ int segment, u8 bus, u8 devfn)
{
struct context_entry *context;
unsigned long flags;
@@ -1479,7 +1337,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
BUG_ON(!domain->pgd);
- iommu = device_to_iommu(bus, devfn);
+ iommu = device_to_iommu(segment, bus, devfn);
if (!iommu)
return -ENODEV;
@@ -1557,7 +1415,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
spin_lock_irqsave(&domain->iommu_lock, flags);
if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) {
domain->iommu_count++;
- domain_update_iommu_coherency(domain);
+ domain_update_iommu_cap(domain);
}
spin_unlock_irqrestore(&domain->iommu_lock, flags);
return 0;
@@ -1569,8 +1427,8 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
int ret;
struct pci_dev *tmp, *parent;
- ret = domain_context_mapping_one(domain, pdev->bus->number,
- pdev->devfn);
+ ret = domain_context_mapping_one(domain, pci_domain_nr(pdev->bus),
+ pdev->bus->number, pdev->devfn);
if (ret)
return ret;
@@ -1581,18 +1439,23 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
/* Secondary interface's bus number and devfn 0 */
parent = pdev->bus->self;
while (parent != tmp) {
- ret = domain_context_mapping_one(domain, parent->bus->number,
- parent->devfn);
+ ret = domain_context_mapping_one(domain,
+ pci_domain_nr(parent->bus),
+ parent->bus->number,
+ parent->devfn);
if (ret)
return ret;
parent = parent->bus->self;
}
if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
return domain_context_mapping_one(domain,
- tmp->subordinate->number, 0);
+ pci_domain_nr(tmp->subordinate),
+ tmp->subordinate->number, 0);
else /* this is a legacy PCI bridge */
return domain_context_mapping_one(domain,
- tmp->bus->number, tmp->devfn);
+ pci_domain_nr(tmp->bus),
+ tmp->bus->number,
+ tmp->devfn);
}
static int domain_context_mapped(struct pci_dev *pdev)
@@ -1601,12 +1464,12 @@ static int domain_context_mapped(struct pci_dev *pdev)
struct pci_dev *tmp, *parent;
struct intel_iommu *iommu;
- iommu = device_to_iommu(pdev->bus->number, pdev->devfn);
+ iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
+ pdev->devfn);
if (!iommu)
return -ENODEV;
- ret = device_context_mapped(iommu,
- pdev->bus->number, pdev->devfn);
+ ret = device_context_mapped(iommu, pdev->bus->number, pdev->devfn);
if (!ret)
return ret;
/* dependent device mapping */
@@ -1617,17 +1480,17 @@ static int domain_context_mapped(struct pci_dev *pdev)
parent = pdev->bus->self;
while (parent != tmp) {
ret = device_context_mapped(iommu, parent->bus->number,
- parent->devfn);
+ parent->devfn);
if (!ret)
return ret;
parent = parent->bus->self;
}
if (tmp->is_pcie)
- return device_context_mapped(iommu,
- tmp->subordinate->number, 0);
+ return device_context_mapped(iommu, tmp->subordinate->number,
+ 0);
else
- return device_context_mapped(iommu,
- tmp->bus->number, tmp->devfn);
+ return device_context_mapped(iommu, tmp->bus->number,
+ tmp->devfn);
}
static int
@@ -1657,6 +1520,8 @@ domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova,
BUG_ON(dma_pte_addr(pte));
dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT);
dma_set_pte_prot(pte, prot);
+ if (prot & DMA_PTE_SNP)
+ dma_set_pte_snp(pte);
domain_flush_cache(domain, pte, sizeof(*pte));
start_pfn++;
index++;
@@ -1692,7 +1557,7 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
info->dev->dev.archdata.iommu = NULL;
spin_unlock_irqrestore(&device_domain_lock, flags);
- iommu = device_to_iommu(info->bus, info->devfn);
+ iommu = device_to_iommu(info->segment, info->bus, info->devfn);
iommu_detach_dev(iommu, info->bus, info->devfn);
free_devinfo_mem(info);
@@ -1727,11 +1592,14 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
struct pci_dev *dev_tmp;
unsigned long flags;
int bus = 0, devfn = 0;
+ int segment;
domain = find_domain(pdev);
if (domain)
return domain;
+ segment = pci_domain_nr(pdev->bus);
+
dev_tmp = pci_find_upstream_pcie_bridge(pdev);
if (dev_tmp) {
if (dev_tmp->is_pcie) {
@@ -1743,7 +1611,8 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
}
spin_lock_irqsave(&device_domain_lock, flags);
list_for_each_entry(info, &device_domain_list, global) {
- if (info->bus == bus && info->devfn == devfn) {
+ if (info->segment == segment &&
+ info->bus == bus && info->devfn == devfn) {
found = info->domain;
break;
}
@@ -1781,6 +1650,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
domain_exit(domain);
goto error;
}
+ info->segment = segment;
info->bus = bus;
info->devfn = devfn;
info->dev = NULL;
@@ -1792,7 +1662,8 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
found = NULL;
spin_lock_irqsave(&device_domain_lock, flags);
list_for_each_entry(tmp, &device_domain_list, global) {
- if (tmp->bus == bus && tmp->devfn == devfn) {
+ if (tmp->segment == segment &&
+ tmp->bus == bus && tmp->devfn == devfn) {
found = tmp->domain;
break;
}
@@ -1812,6 +1683,7 @@ found_domain:
info = alloc_devinfo_mem();
if (!info)
goto error;
+ info->segment = segment;
info->bus = pdev->bus->number;
info->devfn = pdev->devfn;
info->dev = pdev;
@@ -1970,7 +1842,7 @@ static inline void iommu_prepare_isa(void)
ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024);
if (ret)
- printk("IOMMU: Failed to create 0-64M identity map, "
+ printk(KERN_ERR "IOMMU: Failed to create 0-64M identity map, "
"floppy might not work\n");
}
@@ -1987,7 +1859,7 @@ static int __init init_dmars(void)
struct dmar_rmrr_unit *rmrr;
struct pci_dev *pdev;
struct intel_iommu *iommu;
- int i, ret, unit = 0;
+ int i, ret;
/*
* for each drhd
@@ -2043,11 +1915,40 @@ static int __init init_dmars(void)
}
}
+ /*
+ * Start from the sane iommu hardware state.
+ */
+ for_each_drhd_unit(drhd) {
+ if (drhd->ignored)
+ continue;
+
+ iommu = drhd->iommu;
+
+ /*
+ * If the queued invalidation is already initialized by us
+ * (for example, while enabling interrupt-remapping) then
+ * we got the things already rolling from a sane state.
+ */
+ if (iommu->qi)
+ continue;
+
+ /*
+ * Clear any previous faults.
+ */
+ dmar_fault(-1, iommu);
+ /*
+ * Disable queued invalidation if supported and already enabled
+ * before OS handover.
+ */
+ dmar_disable_qi(iommu);
+ }
+
for_each_drhd_unit(drhd) {
if (drhd->ignored)
continue;
iommu = drhd->iommu;
+
if (dmar_enable_qi(iommu)) {
/*
* Queued Invalidate not enabled, use Register Based
@@ -2067,6 +1968,15 @@ static int __init init_dmars(void)
}
}
+#ifdef CONFIG_INTR_REMAP
+ if (!intr_remapping_enabled) {
+ ret = enable_intr_remapping(0);
+ if (ret)
+ printk(KERN_ERR
+ "IOMMU: enable interrupt remapping failed\n");
+ }
+#endif
+
/*
* For each rmrr
* for each dev attached to rmrr
@@ -2109,7 +2019,6 @@ static int __init init_dmars(void)
if (drhd->ignored)
continue;
iommu = drhd->iommu;
- sprintf (iommu->name, "dmar%d", unit++);
iommu_flush_write_buffer(iommu);
@@ -2279,16 +2188,18 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr,
error:
if (iova)
__free_iova(&domain->iovad, iova);
- printk(KERN_ERR"Device %s request: %lx@%llx dir %d --- failed\n",
+ printk(KERN_ERR"Device %s request: %zx@%llx dir %d --- failed\n",
pci_name(pdev), size, (unsigned long long)paddr, dir);
return 0;
}
-dma_addr_t intel_map_single(struct device *hwdev, phys_addr_t paddr,
- size_t size, int dir)
+static dma_addr_t intel_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
- return __intel_map_single(hwdev, paddr, size, dir,
- to_pci_dev(hwdev)->dma_mask);
+ return __intel_map_single(dev, page_to_phys(page) + offset, size,
+ dir, to_pci_dev(dev)->dma_mask);
}
static void flush_unmaps(void)
@@ -2352,8 +2263,9 @@ static void add_unmap(struct dmar_domain *dom, struct iova *iova)
spin_unlock_irqrestore(&async_umap_flush_lock, flags);
}
-void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
- int dir)
+static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct dmar_domain *domain;
@@ -2375,7 +2287,7 @@ void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
start_addr = iova->pfn_lo << PAGE_SHIFT;
size = aligned_size((u64)dev_addr, size);
- pr_debug("Device %s unmapping: %lx@%llx\n",
+ pr_debug("Device %s unmapping: %zx@%llx\n",
pci_name(pdev), size, (unsigned long long)start_addr);
/* clear the whole page */
@@ -2397,8 +2309,14 @@ void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
}
}
-void *intel_alloc_coherent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, gfp_t flags)
+static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
+ int dir)
+{
+ intel_unmap_page(dev, dev_addr, size, dir, NULL);
+}
+
+static void *intel_alloc_coherent(struct device *hwdev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flags)
{
void *vaddr;
int order;
@@ -2421,8 +2339,8 @@ void *intel_alloc_coherent(struct device *hwdev, size_t size,
return NULL;
}
-void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
- dma_addr_t dma_handle)
+static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
+ dma_addr_t dma_handle)
{
int order;
@@ -2433,10 +2351,9 @@ void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
free_pages((unsigned long)vaddr, order);
}
-#define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg)))
-
-void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
- int nelems, int dir)
+static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
+ int nelems, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
int i;
struct pci_dev *pdev = to_pci_dev(hwdev);
@@ -2444,7 +2361,7 @@ void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
unsigned long start_addr;
struct iova *iova;
size_t size = 0;
- void *addr;
+ phys_addr_t addr;
struct scatterlist *sg;
struct intel_iommu *iommu;
@@ -2460,7 +2377,7 @@ void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
if (!iova)
return;
for_each_sg(sglist, sg, nelems, i) {
- addr = SG_ENT_VIRT_ADDRESS(sg);
+ addr = page_to_phys(sg_page(sg)) + sg->offset;
size += aligned_size((u64)addr, sg->length);
}
@@ -2487,16 +2404,16 @@ static int intel_nontranslate_map_sg(struct device *hddev,
for_each_sg(sglist, sg, nelems, i) {
BUG_ON(!sg_page(sg));
- sg->dma_address = virt_to_bus(SG_ENT_VIRT_ADDRESS(sg));
+ sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
sg->dma_length = sg->length;
}
return nelems;
}
-int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
- int dir)
+static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
{
- void *addr;
+ phys_addr_t addr;
int i;
struct pci_dev *pdev = to_pci_dev(hwdev);
struct dmar_domain *domain;
@@ -2520,8 +2437,7 @@ int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
iommu = domain_get_iommu(domain);
for_each_sg(sglist, sg, nelems, i) {
- addr = SG_ENT_VIRT_ADDRESS(sg);
- addr = (void *)virt_to_phys(addr);
+ addr = page_to_phys(sg_page(sg)) + sg->offset;
size += aligned_size((u64)addr, sg->length);
}
@@ -2544,8 +2460,7 @@ int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
start_addr = iova->pfn_lo << PAGE_SHIFT;
offset = 0;
for_each_sg(sglist, sg, nelems, i) {
- addr = SG_ENT_VIRT_ADDRESS(sg);
- addr = (void *)virt_to_phys(addr);
+ addr = page_to_phys(sg_page(sg)) + sg->offset;
size = aligned_size((u64)addr, sg->length);
ret = domain_page_mapping(domain, start_addr + offset,
((u64)addr) & PAGE_MASK,
@@ -2574,13 +2489,19 @@ int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
return nelems;
}
-static struct dma_mapping_ops intel_dma_ops = {
+static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return !dma_addr;
+}
+
+struct dma_map_ops intel_dma_ops = {
.alloc_coherent = intel_alloc_coherent,
.free_coherent = intel_free_coherent,
- .map_single = intel_map_single,
- .unmap_single = intel_unmap_single,
.map_sg = intel_map_sg,
.unmap_sg = intel_unmap_sg,
+ .map_page = intel_map_page,
+ .unmap_page = intel_unmap_page,
+ .mapping_error = intel_mapping_error,
};
static inline int iommu_domain_cache_init(void)
@@ -2707,6 +2628,150 @@ static void __init init_no_remapping_devices(void)
}
}
+#ifdef CONFIG_SUSPEND
+static int init_iommu_hw(void)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu = NULL;
+
+ for_each_active_iommu(iommu, drhd)
+ if (iommu->qi)
+ dmar_reenable_qi(iommu);
+
+ for_each_active_iommu(iommu, drhd) {
+ iommu_flush_write_buffer(iommu);
+
+ iommu_set_root_entry(iommu);
+
+ iommu->flush.flush_context(iommu, 0, 0, 0,
+ DMA_CCMD_GLOBAL_INVL, 0);
+ iommu->flush.flush_iotlb(iommu, 0, 0, 0,
+ DMA_TLB_GLOBAL_FLUSH, 0);
+ iommu_disable_protect_mem_regions(iommu);
+ iommu_enable_translation(iommu);
+ }
+
+ return 0;
+}
+
+static void iommu_flush_all(void)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu;
+
+ for_each_active_iommu(iommu, drhd) {
+ iommu->flush.flush_context(iommu, 0, 0, 0,
+ DMA_CCMD_GLOBAL_INVL, 0);
+ iommu->flush.flush_iotlb(iommu, 0, 0, 0,
+ DMA_TLB_GLOBAL_FLUSH, 0);
+ }
+}
+
+static int iommu_suspend(struct sys_device *dev, pm_message_t state)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu = NULL;
+ unsigned long flag;
+
+ for_each_active_iommu(iommu, drhd) {
+ iommu->iommu_state = kzalloc(sizeof(u32) * MAX_SR_DMAR_REGS,
+ GFP_ATOMIC);
+ if (!iommu->iommu_state)
+ goto nomem;
+ }
+
+ iommu_flush_all();
+
+ for_each_active_iommu(iommu, drhd) {
+ iommu_disable_translation(iommu);
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+
+ iommu->iommu_state[SR_DMAR_FECTL_REG] =
+ readl(iommu->reg + DMAR_FECTL_REG);
+ iommu->iommu_state[SR_DMAR_FEDATA_REG] =
+ readl(iommu->reg + DMAR_FEDATA_REG);
+ iommu->iommu_state[SR_DMAR_FEADDR_REG] =
+ readl(iommu->reg + DMAR_FEADDR_REG);
+ iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
+ readl(iommu->reg + DMAR_FEUADDR_REG);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+ }
+ return 0;
+
+nomem:
+ for_each_active_iommu(iommu, drhd)
+ kfree(iommu->iommu_state);
+
+ return -ENOMEM;
+}
+
+static int iommu_resume(struct sys_device *dev)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu = NULL;
+ unsigned long flag;
+
+ if (init_iommu_hw()) {
+ WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
+ return -EIO;
+ }
+
+ for_each_active_iommu(iommu, drhd) {
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+
+ writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
+ iommu->reg + DMAR_FECTL_REG);
+ writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
+ iommu->reg + DMAR_FEDATA_REG);
+ writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
+ iommu->reg + DMAR_FEADDR_REG);
+ writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
+ iommu->reg + DMAR_FEUADDR_REG);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+ }
+
+ for_each_active_iommu(iommu, drhd)
+ kfree(iommu->iommu_state);
+
+ return 0;
+}
+
+static struct sysdev_class iommu_sysclass = {
+ .name = "iommu",
+ .resume = iommu_resume,
+ .suspend = iommu_suspend,
+};
+
+static struct sys_device device_iommu = {
+ .cls = &iommu_sysclass,
+};
+
+static int __init init_iommu_sysfs(void)
+{
+ int error;
+
+ error = sysdev_class_register(&iommu_sysclass);
+ if (error)
+ return error;
+
+ error = sysdev_register(&device_iommu);
+ if (error)
+ sysdev_class_unregister(&iommu_sysclass);
+
+ return error;
+}
+
+#else
+static int __init init_iommu_sysfs(void)
+{
+ return 0;
+}
+#endif /* CONFIG_PM */
+
int __init intel_iommu_init(void)
{
int ret = 0;
@@ -2742,6 +2807,7 @@ int __init intel_iommu_init(void)
init_timer(&unmap_timer);
force_iommu = 1;
dma_ops = &intel_dma_ops;
+ init_iommu_sysfs();
register_iommu(&intel_iommu_ops);
@@ -2758,6 +2824,7 @@ static int vm_domain_add_dev_info(struct dmar_domain *domain,
if (!info)
return -ENOMEM;
+ info->segment = pci_domain_nr(pdev->bus);
info->bus = pdev->bus->number;
info->devfn = pdev->devfn;
info->dev = pdev;
@@ -2772,6 +2839,33 @@ static int vm_domain_add_dev_info(struct dmar_domain *domain,
return 0;
}
+static void iommu_detach_dependent_devices(struct intel_iommu *iommu,
+ struct pci_dev *pdev)
+{
+ struct pci_dev *tmp, *parent;
+
+ if (!iommu || !pdev)
+ return;
+
+ /* dependent device detach */
+ tmp = pci_find_upstream_pcie_bridge(pdev);
+ /* Secondary interface's bus number and devfn 0 */
+ if (tmp) {
+ parent = pdev->bus->self;
+ while (parent != tmp) {
+ iommu_detach_dev(iommu, parent->bus->number,
+ parent->devfn);
+ parent = parent->bus->self;
+ }
+ if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
+ iommu_detach_dev(iommu,
+ tmp->subordinate->number, 0);
+ else /* this is a legacy PCI bridge */
+ iommu_detach_dev(iommu, tmp->bus->number,
+ tmp->devfn);
+ }
+}
+
static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
struct pci_dev *pdev)
{
@@ -2781,13 +2875,15 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
int found = 0;
struct list_head *entry, *tmp;
- iommu = device_to_iommu(pdev->bus->number, pdev->devfn);
+ iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
+ pdev->devfn);
if (!iommu)
return;
spin_lock_irqsave(&device_domain_lock, flags);
list_for_each_safe(entry, tmp, &domain->devices) {
info = list_entry(entry, struct device_domain_info, link);
+ /* No need to compare PCI domain; it has to be the same */
if (info->bus == pdev->bus->number &&
info->devfn == pdev->devfn) {
list_del(&info->link);
@@ -2797,6 +2893,7 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
spin_unlock_irqrestore(&device_domain_lock, flags);
iommu_detach_dev(iommu, info->bus, info->devfn);
+ iommu_detach_dependent_devices(iommu, pdev);
free_devinfo_mem(info);
spin_lock_irqsave(&device_domain_lock, flags);
@@ -2811,7 +2908,8 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
* owned by this domain, clear this iommu in iommu_bmp
* update iommu count and coherency
*/
- if (device_to_iommu(info->bus, info->devfn) == iommu)
+ if (iommu == device_to_iommu(info->segment, info->bus,
+ info->devfn))
found = 1;
}
@@ -2820,7 +2918,7 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
spin_lock_irqsave(&domain->iommu_lock, tmp_flags);
clear_bit(iommu->seq_id, &domain->iommu_bmp);
domain->iommu_count--;
- domain_update_iommu_coherency(domain);
+ domain_update_iommu_cap(domain);
spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
}
@@ -2844,17 +2942,18 @@ static void vm_domain_remove_all_dev_info(struct dmar_domain *domain)
spin_unlock_irqrestore(&device_domain_lock, flags1);
- iommu = device_to_iommu(info->bus, info->devfn);
+ iommu = device_to_iommu(info->segment, info->bus, info->devfn);
iommu_detach_dev(iommu, info->bus, info->devfn);
+ iommu_detach_dependent_devices(iommu, info->dev);
/* clear this iommu in iommu_bmp, update iommu count
- * and coherency
+ * and capabilities
*/
spin_lock_irqsave(&domain->iommu_lock, flags2);
if (test_and_clear_bit(iommu->seq_id,
&domain->iommu_bmp)) {
domain->iommu_count--;
- domain_update_iommu_coherency(domain);
+ domain_update_iommu_cap(domain);
}
spin_unlock_irqrestore(&domain->iommu_lock, flags2);
@@ -3031,7 +3130,8 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
}
}
- iommu = device_to_iommu(pdev->bus->number, pdev->devfn);
+ iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
+ pdev->devfn);
if (!iommu)
return -ENODEV;
@@ -3077,6 +3177,8 @@ static int intel_iommu_map_range(struct iommu_domain *domain,
prot |= DMA_PTE_READ;
if (iommu_prot & IOMMU_WRITE)
prot |= DMA_PTE_WRITE;
+ if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
+ prot |= DMA_PTE_SNP;
max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size);
if (dmar_domain->max_addr < max_addr) {
@@ -3130,6 +3232,17 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
return phys;
}
+static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap)
+{
+ struct dmar_domain *dmar_domain = domain->priv;
+
+ if (cap == IOMMU_CAP_CACHE_COHERENCY)
+ return dmar_domain->iommu_snooping;
+
+ return 0;
+}
+
static struct iommu_ops intel_iommu_ops = {
.domain_init = intel_iommu_domain_init,
.domain_destroy = intel_iommu_domain_destroy,
@@ -3138,6 +3251,7 @@ static struct iommu_ops intel_iommu_ops = {
.map = intel_iommu_map_range,
.unmap = intel_iommu_unmap_range,
.iova_to_phys = intel_iommu_iova_to_phys,
+ .domain_has_cap = intel_iommu_domain_has_cap,
};
static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index 8e44db040db7..f5e0ea724a6f 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -9,6 +9,7 @@
#include <asm/cpu.h>
#include <linux/intel-iommu.h>
#include "intr_remapping.h"
+#include <acpi/acpi.h>
static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
static int ir_ioapic_num;
@@ -21,7 +22,7 @@ struct irq_2_iommu {
u8 irte_mask;
};
-#ifdef CONFIG_SPARSE_IRQ
+#ifdef CONFIG_GENERIC_HARDIRQS
static struct irq_2_iommu *get_one_free_irq_2_iommu(int cpu)
{
struct irq_2_iommu *iommu;
@@ -117,21 +118,22 @@ int get_irte(int irq, struct irte *entry)
{
int index;
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
if (!entry)
return -1;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return -1;
}
index = irq_iommu->irte_index + irq_iommu->sub_handle;
*entry = *(irq_iommu->iommu->ir_table->base + index);
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return 0;
}
@@ -141,6 +143,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
struct irq_2_iommu *irq_iommu;
u16 index, start_index;
unsigned int mask = 0;
+ unsigned long flags;
int i;
if (!count)
@@ -170,7 +173,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
return -1;
}
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
do {
for (i = index; i < index + count; i++)
if (table->base[i].present)
@@ -182,7 +185,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
index = (index + count) % INTR_REMAP_TABLE_ENTRIES;
if (index == start_index) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
printk(KERN_ERR "can't allocate an IRTE\n");
return -1;
}
@@ -193,7 +196,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
irq_iommu = irq_2_iommu_alloc(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
printk(KERN_ERR "can't allocate irq_2_iommu\n");
return -1;
}
@@ -203,7 +206,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
irq_iommu->sub_handle = 0;
irq_iommu->irte_mask = mask;
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return index;
}
@@ -223,30 +226,32 @@ int map_irq_to_irte_handle(int irq, u16 *sub_handle)
{
int index;
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return -1;
}
*sub_handle = irq_iommu->sub_handle;
index = irq_iommu->irte_index;
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return index;
}
int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
{
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = irq_2_iommu_alloc(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
printk(KERN_ERR "can't allocate irq_2_iommu\n");
return -1;
}
@@ -256,7 +261,7 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
irq_iommu->sub_handle = subhandle;
irq_iommu->irte_mask = 0;
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return 0;
}
@@ -264,11 +269,12 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
{
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return -1;
}
@@ -277,7 +283,7 @@ int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
irq_iommu->sub_handle = 0;
irq_2_iommu(irq)->irte_mask = 0;
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return 0;
}
@@ -289,11 +295,12 @@ int modify_irte(int irq, struct irte *irte_modified)
struct irte *irte;
struct intel_iommu *iommu;
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return -1;
}
@@ -302,11 +309,11 @@ int modify_irte(int irq, struct irte *irte_modified)
index = irq_iommu->irte_index + irq_iommu->sub_handle;
irte = &iommu->ir_table->base[index];
- set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1));
+ set_64bit((unsigned long *)irte, irte_modified->low);
__iommu_flush_cache(iommu, irte, sizeof(*irte));
rc = qi_flush_iec(iommu, index, 0);
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return rc;
}
@@ -317,11 +324,12 @@ int flush_irte(int irq)
int index;
struct intel_iommu *iommu;
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return -1;
}
@@ -330,7 +338,7 @@ int flush_irte(int irq)
index = irq_iommu->irte_index + irq_iommu->sub_handle;
rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask);
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return rc;
}
@@ -363,11 +371,12 @@ int free_irte(int irq)
struct irte *irte;
struct intel_iommu *iommu;
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return -1;
}
@@ -378,7 +387,7 @@ int free_irte(int irq)
if (!irq_iommu->sub_handle) {
for (i = 0; i < (1 << irq_iommu->irte_mask); i++)
- set_64bit((unsigned long *)irte, 0);
+ set_64bit((unsigned long *)(irte + i), 0);
rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask);
}
@@ -387,7 +396,7 @@ int free_irte(int irq)
irq_iommu->sub_handle = 0;
irq_iommu->irte_mask = 0;
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return rc;
}
@@ -407,12 +416,27 @@ static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
/* Set interrupt-remapping table pointer */
cmd = iommu->gcmd | DMA_GCMD_SIRTP;
+ iommu->gcmd |= DMA_GCMD_SIRTP;
writel(cmd, iommu->reg + DMAR_GCMD_REG);
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
readl, (sts & DMA_GSTS_IRTPS), sts);
spin_unlock_irqrestore(&iommu->register_lock, flags);
+ if (mode == 0) {
+ spin_lock_irqsave(&iommu->register_lock, flags);
+
+ /* enable comaptiblity format interrupt pass through */
+ cmd = iommu->gcmd | DMA_GCMD_CFI;
+ iommu->gcmd |= DMA_GCMD_CFI;
+ writel(cmd, iommu->reg + DMAR_GCMD_REG);
+
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+ readl, (sts & DMA_GSTS_CFIS), sts);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flags);
+ }
+
/*
* global invalidation of interrupt entry cache before enabling
* interrupt-remapping.
@@ -439,12 +463,12 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode)
struct page *pages;
ir_table = iommu->ir_table = kzalloc(sizeof(struct ir_table),
- GFP_KERNEL);
+ GFP_ATOMIC);
if (!iommu->ir_table)
return -ENOMEM;
- pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, INTR_REMAP_PAGE_ORDER);
+ pages = alloc_pages(GFP_ATOMIC | __GFP_ZERO, INTR_REMAP_PAGE_ORDER);
if (!pages) {
printk(KERN_ERR "failed to allocate pages of order %d\n",
@@ -459,11 +483,68 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode)
return 0;
}
+/*
+ * Disable Interrupt Remapping.
+ */
+static void iommu_disable_intr_remapping(struct intel_iommu *iommu)
+{
+ unsigned long flags;
+ u32 sts;
+
+ if (!ecap_ir_support(iommu->ecap))
+ return;
+
+ /*
+ * global invalidation of interrupt entry cache before disabling
+ * interrupt-remapping.
+ */
+ qi_global_iec(iommu);
+
+ spin_lock_irqsave(&iommu->register_lock, flags);
+
+ sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
+ if (!(sts & DMA_GSTS_IRES))
+ goto end;
+
+ iommu->gcmd &= ~DMA_GCMD_IRE;
+ writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
+
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+ readl, !(sts & DMA_GSTS_IRES), sts);
+
+end:
+ spin_unlock_irqrestore(&iommu->register_lock, flags);
+}
+
int __init enable_intr_remapping(int eim)
{
struct dmar_drhd_unit *drhd;
int setup = 0;
+ for_each_drhd_unit(drhd) {
+ struct intel_iommu *iommu = drhd->iommu;
+
+ /*
+ * If the queued invalidation is already initialized,
+ * shouldn't disable it.
+ */
+ if (iommu->qi)
+ continue;
+
+ /*
+ * Clear previous faults.
+ */
+ dmar_fault(-1, iommu);
+
+ /*
+ * Disable intr remapping and queued invalidation, if already
+ * enabled prior to OS handover.
+ */
+ iommu_disable_intr_remapping(iommu);
+
+ dmar_disable_qi(iommu);
+ }
+
/*
* check for the Interrupt-remapping support
*/
@@ -587,3 +668,54 @@ int __init parse_ioapics_under_ir(void)
return ir_supported;
}
+
+void disable_intr_remapping(void)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu = NULL;
+
+ /*
+ * Disable Interrupt-remapping for all the DRHD's now.
+ */
+ for_each_iommu(iommu, drhd) {
+ if (!ecap_ir_support(iommu->ecap))
+ continue;
+
+ iommu_disable_intr_remapping(iommu);
+ }
+}
+
+int reenable_intr_remapping(int eim)
+{
+ struct dmar_drhd_unit *drhd;
+ int setup = 0;
+ struct intel_iommu *iommu = NULL;
+
+ for_each_iommu(iommu, drhd)
+ if (iommu->qi)
+ dmar_reenable_qi(iommu);
+
+ /*
+ * Setup Interrupt-remapping for all the DRHD's now.
+ */
+ for_each_iommu(iommu, drhd) {
+ if (!ecap_ir_support(iommu->ecap))
+ continue;
+
+ /* Set up interrupt remapping for iommu.*/
+ iommu_set_intr_remapping(iommu, eim);
+ setup = 1;
+ }
+
+ if (!setup)
+ goto error;
+
+ return 0;
+
+error:
+ /*
+ * handle error condition gracefully here!
+ */
+ return -1;
+}
+
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
new file mode 100644
index 000000000000..7227efc760db
--- /dev/null
+++ b/drivers/pci/iov.c
@@ -0,0 +1,680 @@
+/*
+ * drivers/pci/iov.c
+ *
+ * Copyright (C) 2009 Intel Corporation, Yu Zhao <yu.zhao@intel.com>
+ *
+ * PCI Express I/O Virtualization (IOV) support.
+ * Single Root IOV 1.0
+ */
+
+#include <linux/pci.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include "pci.h"
+
+#define VIRTFN_ID_LEN 16
+
+static inline u8 virtfn_bus(struct pci_dev *dev, int id)
+{
+ return dev->bus->number + ((dev->devfn + dev->sriov->offset +
+ dev->sriov->stride * id) >> 8);
+}
+
+static inline u8 virtfn_devfn(struct pci_dev *dev, int id)
+{
+ return (dev->devfn + dev->sriov->offset +
+ dev->sriov->stride * id) & 0xff;
+}
+
+static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
+{
+ int rc;
+ struct pci_bus *child;
+
+ if (bus->number == busnr)
+ return bus;
+
+ child = pci_find_bus(pci_domain_nr(bus), busnr);
+ if (child)
+ return child;
+
+ child = pci_add_new_bus(bus, NULL, busnr);
+ if (!child)
+ return NULL;
+
+ child->subordinate = busnr;
+ child->dev.parent = bus->bridge;
+ rc = pci_bus_add_child(child);
+ if (rc) {
+ pci_remove_bus(child);
+ return NULL;
+ }
+
+ return child;
+}
+
+static void virtfn_remove_bus(struct pci_bus *bus, int busnr)
+{
+ struct pci_bus *child;
+
+ if (bus->number == busnr)
+ return;
+
+ child = pci_find_bus(pci_domain_nr(bus), busnr);
+ BUG_ON(!child);
+
+ if (list_empty(&child->devices))
+ pci_remove_bus(child);
+}
+
+static int virtfn_add(struct pci_dev *dev, int id, int reset)
+{
+ int i;
+ int rc;
+ u64 size;
+ char buf[VIRTFN_ID_LEN];
+ struct pci_dev *virtfn;
+ struct resource *res;
+ struct pci_sriov *iov = dev->sriov;
+
+ virtfn = alloc_pci_dev();
+ if (!virtfn)
+ return -ENOMEM;
+
+ mutex_lock(&iov->dev->sriov->lock);
+ virtfn->bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id));
+ if (!virtfn->bus) {
+ kfree(virtfn);
+ mutex_unlock(&iov->dev->sriov->lock);
+ return -ENOMEM;
+ }
+ virtfn->devfn = virtfn_devfn(dev, id);
+ virtfn->vendor = dev->vendor;
+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device);
+ pci_setup_device(virtfn);
+ virtfn->dev.parent = dev->dev.parent;
+
+ for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+ res = dev->resource + PCI_IOV_RESOURCES + i;
+ if (!res->parent)
+ continue;
+ virtfn->resource[i].name = pci_name(virtfn);
+ virtfn->resource[i].flags = res->flags;
+ size = resource_size(res);
+ do_div(size, iov->total);
+ virtfn->resource[i].start = res->start + size * id;
+ virtfn->resource[i].end = virtfn->resource[i].start + size - 1;
+ rc = request_resource(res, &virtfn->resource[i]);
+ BUG_ON(rc);
+ }
+
+ if (reset)
+ pci_execute_reset_function(virtfn);
+
+ pci_device_add(virtfn, virtfn->bus);
+ mutex_unlock(&iov->dev->sriov->lock);
+
+ virtfn->physfn = pci_dev_get(dev);
+ virtfn->is_virtfn = 1;
+
+ rc = pci_bus_add_device(virtfn);
+ if (rc)
+ goto failed1;
+ sprintf(buf, "virtfn%u", id);
+ rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
+ if (rc)
+ goto failed1;
+ rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn");
+ if (rc)
+ goto failed2;
+
+ kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE);
+
+ return 0;
+
+failed2:
+ sysfs_remove_link(&dev->dev.kobj, buf);
+failed1:
+ pci_dev_put(dev);
+ mutex_lock(&iov->dev->sriov->lock);
+ pci_remove_bus_device(virtfn);
+ virtfn_remove_bus(dev->bus, virtfn_bus(dev, id));
+ mutex_unlock(&iov->dev->sriov->lock);
+
+ return rc;
+}
+
+static void virtfn_remove(struct pci_dev *dev, int id, int reset)
+{
+ char buf[VIRTFN_ID_LEN];
+ struct pci_bus *bus;
+ struct pci_dev *virtfn;
+ struct pci_sriov *iov = dev->sriov;
+
+ bus = pci_find_bus(pci_domain_nr(dev->bus), virtfn_bus(dev, id));
+ if (!bus)
+ return;
+
+ virtfn = pci_get_slot(bus, virtfn_devfn(dev, id));
+ if (!virtfn)
+ return;
+
+ pci_dev_put(virtfn);
+
+ if (reset) {
+ device_release_driver(&virtfn->dev);
+ pci_execute_reset_function(virtfn);
+ }
+
+ sprintf(buf, "virtfn%u", id);
+ sysfs_remove_link(&dev->dev.kobj, buf);
+ sysfs_remove_link(&virtfn->dev.kobj, "physfn");
+
+ mutex_lock(&iov->dev->sriov->lock);
+ pci_remove_bus_device(virtfn);
+ virtfn_remove_bus(dev->bus, virtfn_bus(dev, id));
+ mutex_unlock(&iov->dev->sriov->lock);
+
+ pci_dev_put(dev);
+}
+
+static int sriov_migration(struct pci_dev *dev)
+{
+ u16 status;
+ struct pci_sriov *iov = dev->sriov;
+
+ if (!iov->nr_virtfn)
+ return 0;
+
+ if (!(iov->cap & PCI_SRIOV_CAP_VFM))
+ return 0;
+
+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_STATUS, &status);
+ if (!(status & PCI_SRIOV_STATUS_VFM))
+ return 0;
+
+ schedule_work(&iov->mtask);
+
+ return 1;
+}
+
+static void sriov_migration_task(struct work_struct *work)
+{
+ int i;
+ u8 state;
+ u16 status;
+ struct pci_sriov *iov = container_of(work, struct pci_sriov, mtask);
+
+ for (i = iov->initial; i < iov->nr_virtfn; i++) {
+ state = readb(iov->mstate + i);
+ if (state == PCI_SRIOV_VFM_MI) {
+ writeb(PCI_SRIOV_VFM_AV, iov->mstate + i);
+ state = readb(iov->mstate + i);
+ if (state == PCI_SRIOV_VFM_AV)
+ virtfn_add(iov->self, i, 1);
+ } else if (state == PCI_SRIOV_VFM_MO) {
+ virtfn_remove(iov->self, i, 1);
+ writeb(PCI_SRIOV_VFM_UA, iov->mstate + i);
+ state = readb(iov->mstate + i);
+ if (state == PCI_SRIOV_VFM_AV)
+ virtfn_add(iov->self, i, 0);
+ }
+ }
+
+ pci_read_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, &status);
+ status &= ~PCI_SRIOV_STATUS_VFM;
+ pci_write_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, status);
+}
+
+static int sriov_enable_migration(struct pci_dev *dev, int nr_virtfn)
+{
+ int bir;
+ u32 table;
+ resource_size_t pa;
+ struct pci_sriov *iov = dev->sriov;
+
+ if (nr_virtfn <= iov->initial)
+ return 0;
+
+ pci_read_config_dword(dev, iov->pos + PCI_SRIOV_VFM, &table);
+ bir = PCI_SRIOV_VFM_BIR(table);
+ if (bir > PCI_STD_RESOURCE_END)
+ return -EIO;
+
+ table = PCI_SRIOV_VFM_OFFSET(table);
+ if (table + nr_virtfn > pci_resource_len(dev, bir))
+ return -EIO;
+
+ pa = pci_resource_start(dev, bir) + table;
+ iov->mstate = ioremap(pa, nr_virtfn);
+ if (!iov->mstate)
+ return -ENOMEM;
+
+ INIT_WORK(&iov->mtask, sriov_migration_task);
+
+ iov->ctrl |= PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR;
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+
+ return 0;
+}
+
+static void sriov_disable_migration(struct pci_dev *dev)
+{
+ struct pci_sriov *iov = dev->sriov;
+
+ iov->ctrl &= ~(PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR);
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+
+ cancel_work_sync(&iov->mtask);
+ iounmap(iov->mstate);
+}
+
+static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
+{
+ int rc;
+ int i, j;
+ int nres;
+ u16 offset, stride, initial;
+ struct resource *res;
+ struct pci_dev *pdev;
+ struct pci_sriov *iov = dev->sriov;
+
+ if (!nr_virtfn)
+ return 0;
+
+ if (iov->nr_virtfn)
+ return -EINVAL;
+
+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_INITIAL_VF, &initial);
+ if (initial > iov->total ||
+ (!(iov->cap & PCI_SRIOV_CAP_VFM) && (initial != iov->total)))
+ return -EIO;
+
+ if (nr_virtfn < 0 || nr_virtfn > iov->total ||
+ (!(iov->cap & PCI_SRIOV_CAP_VFM) && (nr_virtfn > initial)))
+ return -EINVAL;
+
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, nr_virtfn);
+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_OFFSET, &offset);
+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_STRIDE, &stride);
+ if (!offset || (nr_virtfn > 1 && !stride))
+ return -EIO;
+
+ nres = 0;
+ for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+ res = dev->resource + PCI_IOV_RESOURCES + i;
+ if (res->parent)
+ nres++;
+ }
+ if (nres != iov->nres) {
+ dev_err(&dev->dev, "not enough MMIO resources for SR-IOV\n");
+ return -ENOMEM;
+ }
+
+ iov->offset = offset;
+ iov->stride = stride;
+
+ if (virtfn_bus(dev, nr_virtfn - 1) > dev->bus->subordinate) {
+ dev_err(&dev->dev, "SR-IOV: bus number out of range\n");
+ return -ENOMEM;
+ }
+
+ if (iov->link != dev->devfn) {
+ pdev = pci_get_slot(dev->bus, iov->link);
+ if (!pdev)
+ return -ENODEV;
+
+ pci_dev_put(pdev);
+
+ if (!pdev->is_physfn)
+ return -ENODEV;
+
+ rc = sysfs_create_link(&dev->dev.kobj,
+ &pdev->dev.kobj, "dep_link");
+ if (rc)
+ return rc;
+ }
+
+ iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
+ pci_block_user_cfg_access(dev);
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+ msleep(100);
+ pci_unblock_user_cfg_access(dev);
+
+ iov->initial = initial;
+ if (nr_virtfn < initial)
+ initial = nr_virtfn;
+
+ for (i = 0; i < initial; i++) {
+ rc = virtfn_add(dev, i, 0);
+ if (rc)
+ goto failed;
+ }
+
+ if (iov->cap & PCI_SRIOV_CAP_VFM) {
+ rc = sriov_enable_migration(dev, nr_virtfn);
+ if (rc)
+ goto failed;
+ }
+
+ kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE);
+ iov->nr_virtfn = nr_virtfn;
+
+ return 0;
+
+failed:
+ for (j = 0; j < i; j++)
+ virtfn_remove(dev, j, 0);
+
+ iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
+ pci_block_user_cfg_access(dev);
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+ ssleep(1);
+ pci_unblock_user_cfg_access(dev);
+
+ if (iov->link != dev->devfn)
+ sysfs_remove_link(&dev->dev.kobj, "dep_link");
+
+ return rc;
+}
+
+static void sriov_disable(struct pci_dev *dev)
+{
+ int i;
+ struct pci_sriov *iov = dev->sriov;
+
+ if (!iov->nr_virtfn)
+ return;
+
+ if (iov->cap & PCI_SRIOV_CAP_VFM)
+ sriov_disable_migration(dev);
+
+ for (i = 0; i < iov->nr_virtfn; i++)
+ virtfn_remove(dev, i, 0);
+
+ iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
+ pci_block_user_cfg_access(dev);
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+ ssleep(1);
+ pci_unblock_user_cfg_access(dev);
+
+ if (iov->link != dev->devfn)
+ sysfs_remove_link(&dev->dev.kobj, "dep_link");
+
+ iov->nr_virtfn = 0;
+}
+
+static int sriov_init(struct pci_dev *dev, int pos)
+{
+ int i;
+ int rc;
+ int nres;
+ u32 pgsz;
+ u16 ctrl, total, offset, stride;
+ struct pci_sriov *iov;
+ struct resource *res;
+ struct pci_dev *pdev;
+
+ if (dev->pcie_type != PCI_EXP_TYPE_RC_END &&
+ dev->pcie_type != PCI_EXP_TYPE_ENDPOINT)
+ return -ENODEV;
+
+ pci_read_config_word(dev, pos + PCI_SRIOV_CTRL, &ctrl);
+ if (ctrl & PCI_SRIOV_CTRL_VFE) {
+ pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, 0);
+ ssleep(1);
+ }
+
+ pci_read_config_word(dev, pos + PCI_SRIOV_TOTAL_VF, &total);
+ if (!total)
+ return 0;
+
+ ctrl = 0;
+ list_for_each_entry(pdev, &dev->bus->devices, bus_list)
+ if (pdev->is_physfn)
+ goto found;
+
+ pdev = NULL;
+ if (pci_ari_enabled(dev->bus))
+ ctrl |= PCI_SRIOV_CTRL_ARI;
+
+found:
+ pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, ctrl);
+ pci_write_config_word(dev, pos + PCI_SRIOV_NUM_VF, total);
+ pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset);
+ pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride);
+ if (!offset || (total > 1 && !stride))
+ return -EIO;
+
+ pci_read_config_dword(dev, pos + PCI_SRIOV_SUP_PGSIZE, &pgsz);
+ i = PAGE_SHIFT > 12 ? PAGE_SHIFT - 12 : 0;
+ pgsz &= ~((1 << i) - 1);
+ if (!pgsz)
+ return -EIO;
+
+ pgsz &= ~(pgsz - 1);
+ pci_write_config_dword(dev, pos + PCI_SRIOV_SYS_PGSIZE, pgsz);
+
+ nres = 0;
+ for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+ res = dev->resource + PCI_IOV_RESOURCES + i;
+ i += __pci_read_base(dev, pci_bar_unknown, res,
+ pos + PCI_SRIOV_BAR + i * 4);
+ if (!res->flags)
+ continue;
+ if (resource_size(res) & (PAGE_SIZE - 1)) {
+ rc = -EIO;
+ goto failed;
+ }
+ res->end = res->start + resource_size(res) * total - 1;
+ nres++;
+ }
+
+ iov = kzalloc(sizeof(*iov), GFP_KERNEL);
+ if (!iov) {
+ rc = -ENOMEM;
+ goto failed;
+ }
+
+ iov->pos = pos;
+ iov->nres = nres;
+ iov->ctrl = ctrl;
+ iov->total = total;
+ iov->offset = offset;
+ iov->stride = stride;
+ iov->pgsz = pgsz;
+ iov->self = dev;
+ pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap);
+ pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
+
+ if (pdev)
+ iov->dev = pci_dev_get(pdev);
+ else {
+ iov->dev = dev;
+ mutex_init(&iov->lock);
+ }
+
+ dev->sriov = iov;
+ dev->is_physfn = 1;
+
+ return 0;
+
+failed:
+ for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+ res = dev->resource + PCI_IOV_RESOURCES + i;
+ res->flags = 0;
+ }
+
+ return rc;
+}
+
+static void sriov_release(struct pci_dev *dev)
+{
+ BUG_ON(dev->sriov->nr_virtfn);
+
+ if (dev == dev->sriov->dev)
+ mutex_destroy(&dev->sriov->lock);
+ else
+ pci_dev_put(dev->sriov->dev);
+
+ kfree(dev->sriov);
+ dev->sriov = NULL;
+}
+
+static void sriov_restore_state(struct pci_dev *dev)
+{
+ int i;
+ u16 ctrl;
+ struct pci_sriov *iov = dev->sriov;
+
+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_CTRL, &ctrl);
+ if (ctrl & PCI_SRIOV_CTRL_VFE)
+ return;
+
+ for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++)
+ pci_update_resource(dev, i);
+
+ pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz);
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, iov->nr_virtfn);
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+ if (iov->ctrl & PCI_SRIOV_CTRL_VFE)
+ msleep(100);
+}
+
+/**
+ * pci_iov_init - initialize the IOV capability
+ * @dev: the PCI device
+ *
+ * Returns 0 on success, or negative on failure.
+ */
+int pci_iov_init(struct pci_dev *dev)
+{
+ int pos;
+
+ if (!dev->is_pcie)
+ return -ENODEV;
+
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
+ if (pos)
+ return sriov_init(dev, pos);
+
+ return -ENODEV;
+}
+
+/**
+ * pci_iov_release - release resources used by the IOV capability
+ * @dev: the PCI device
+ */
+void pci_iov_release(struct pci_dev *dev)
+{
+ if (dev->is_physfn)
+ sriov_release(dev);
+}
+
+/**
+ * pci_iov_resource_bar - get position of the SR-IOV BAR
+ * @dev: the PCI device
+ * @resno: the resource number
+ * @type: the BAR type to be filled in
+ *
+ * Returns position of the BAR encapsulated in the SR-IOV capability.
+ */
+int pci_iov_resource_bar(struct pci_dev *dev, int resno,
+ enum pci_bar_type *type)
+{
+ if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END)
+ return 0;
+
+ BUG_ON(!dev->is_physfn);
+
+ *type = pci_bar_unknown;
+
+ return dev->sriov->pos + PCI_SRIOV_BAR +
+ 4 * (resno - PCI_IOV_RESOURCES);
+}
+
+/**
+ * pci_restore_iov_state - restore the state of the IOV capability
+ * @dev: the PCI device
+ */
+void pci_restore_iov_state(struct pci_dev *dev)
+{
+ if (dev->is_physfn)
+ sriov_restore_state(dev);
+}
+
+/**
+ * pci_iov_bus_range - find bus range used by Virtual Function
+ * @bus: the PCI bus
+ *
+ * Returns max number of buses (exclude current one) used by Virtual
+ * Functions.
+ */
+int pci_iov_bus_range(struct pci_bus *bus)
+{
+ int max = 0;
+ u8 busnr;
+ struct pci_dev *dev;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ if (!dev->is_physfn)
+ continue;
+ busnr = virtfn_bus(dev, dev->sriov->total - 1);
+ if (busnr > max)
+ max = busnr;
+ }
+
+ return max ? max - bus->number : 0;
+}
+
+/**
+ * pci_enable_sriov - enable the SR-IOV capability
+ * @dev: the PCI device
+ *
+ * Returns 0 on success, or negative on failure.
+ */
+int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn)
+{
+ might_sleep();
+
+ if (!dev->is_physfn)
+ return -ENODEV;
+
+ return sriov_enable(dev, nr_virtfn);
+}
+EXPORT_SYMBOL_GPL(pci_enable_sriov);
+
+/**
+ * pci_disable_sriov - disable the SR-IOV capability
+ * @dev: the PCI device
+ */
+void pci_disable_sriov(struct pci_dev *dev)
+{
+ might_sleep();
+
+ if (!dev->is_physfn)
+ return;
+
+ sriov_disable(dev);
+}
+EXPORT_SYMBOL_GPL(pci_disable_sriov);
+
+/**
+ * pci_sriov_migration - notify SR-IOV core of Virtual Function Migration
+ * @dev: the PCI device
+ *
+ * Returns IRQ_HANDLED if the IRQ is handled, or IRQ_NONE if not.
+ *
+ * Physical Function driver is responsible to register IRQ handler using
+ * VF Migration Interrupt Message Number, and call this function when the
+ * interrupt is generated by the hardware.
+ */
+irqreturn_t pci_sriov_migration(struct pci_dev *dev)
+{
+ if (!dev->is_physfn)
+ return IRQ_NONE;
+
+ return sriov_migration(dev) ? IRQ_HANDLED : IRQ_NONE;
+}
+EXPORT_SYMBOL_GPL(pci_sriov_migration);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index baba2eb5367d..6f2e6295e773 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -27,48 +27,53 @@ static int pci_msi_enable = 1;
/* Arch hooks */
-int __attribute__ ((weak))
-arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
+#ifndef arch_msi_check_device
+int arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
{
return 0;
}
+#endif
-int __attribute__ ((weak))
-arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry)
-{
- return 0;
-}
-
-int __attribute__ ((weak))
-arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+#ifndef arch_setup_msi_irqs
+int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *entry;
int ret;
+ /*
+ * If an architecture wants to support multiple MSI, it needs to
+ * override arch_setup_msi_irqs()
+ */
+ if (type == PCI_CAP_ID_MSI && nvec > 1)
+ return 1;
+
list_for_each_entry(entry, &dev->msi_list, list) {
ret = arch_setup_msi_irq(dev, entry);
- if (ret)
+ if (ret < 0)
return ret;
+ if (ret > 0)
+ return -ENOSPC;
}
return 0;
}
+#endif
-void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq)
-{
- return;
-}
-
-void __attribute__ ((weak))
-arch_teardown_msi_irqs(struct pci_dev *dev)
+#ifndef arch_teardown_msi_irqs
+void arch_teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *entry;
list_for_each_entry(entry, &dev->msi_list, list) {
- if (entry->irq != 0)
- arch_teardown_msi_irq(entry->irq);
+ int i, nvec;
+ if (entry->irq == 0)
+ continue;
+ nvec = 1 << entry->msi_attrib.multiple;
+ for (i = 0; i < nvec; i++)
+ arch_teardown_msi_irq(entry->irq + i);
}
}
+#endif
static void __msi_set_enable(struct pci_dev *dev, int pos, int enable)
{
@@ -111,27 +116,14 @@ static inline __attribute_const__ u32 msi_mask(unsigned x)
return (1 << (1 << x)) - 1;
}
-static void msix_flush_writes(struct irq_desc *desc)
+static inline __attribute_const__ u32 msi_capable_mask(u16 control)
{
- struct msi_desc *entry;
+ return msi_mask((control >> 1) & 7);
+}
- entry = get_irq_desc_msi(desc);
- BUG_ON(!entry || !entry->dev);
- switch (entry->msi_attrib.type) {
- case PCI_CAP_ID_MSI:
- /* nothing to do */
- break;
- case PCI_CAP_ID_MSIX:
- {
- int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
- PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
- readl(entry->mask_base + offset);
- break;
- }
- default:
- BUG();
- break;
- }
+static inline __attribute_const__ u32 msi_enabled_mask(u16 control)
+{
+ return msi_mask((control >> 4) & 7);
}
/*
@@ -143,49 +135,71 @@ static void msix_flush_writes(struct irq_desc *desc)
* Returns 1 if it succeeded in masking the interrupt and 0 if the device
* doesn't support MSI masking.
*/
-static int msi_set_mask_bits(struct irq_desc *desc, u32 mask, u32 flag)
+static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
{
- struct msi_desc *entry;
+ u32 mask_bits = desc->masked;
- entry = get_irq_desc_msi(desc);
- BUG_ON(!entry || !entry->dev);
- switch (entry->msi_attrib.type) {
- case PCI_CAP_ID_MSI:
- if (entry->msi_attrib.maskbit) {
- int pos;
- u32 mask_bits;
-
- pos = (long)entry->mask_base;
- pci_read_config_dword(entry->dev, pos, &mask_bits);
- mask_bits &= ~(mask);
- mask_bits |= flag & mask;
- pci_write_config_dword(entry->dev, pos, mask_bits);
- } else {
- return 0;
- }
- break;
- case PCI_CAP_ID_MSIX:
- {
- int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
- PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
- writel(flag, entry->mask_base + offset);
- readl(entry->mask_base + offset);
- break;
- }
- default:
- BUG();
- break;
+ if (!desc->msi_attrib.maskbit)
+ return;
+
+ mask_bits &= ~mask;
+ mask_bits |= flag;
+ pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits);
+ desc->masked = mask_bits;
+}
+
+/*
+ * This internal function does not flush PCI writes to the device.
+ * All users must ensure that they read from the device before either
+ * assuming that the device state is up to date, or returning out of this
+ * file. This saves a few milliseconds when initialising devices with lots
+ * of MSI-X interrupts.
+ */
+static void msix_mask_irq(struct msi_desc *desc, u32 flag)
+{
+ u32 mask_bits = desc->masked;
+ unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
+ PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
+ mask_bits &= ~1;
+ mask_bits |= flag;
+ writel(mask_bits, desc->mask_base + offset);
+ desc->masked = mask_bits;
+}
+
+static void msi_set_mask_bit(unsigned irq, u32 flag)
+{
+ struct msi_desc *desc = get_irq_msi(irq);
+
+ if (desc->msi_attrib.is_msix) {
+ msix_mask_irq(desc, flag);
+ readl(desc->mask_base); /* Flush write to device */
+ } else {
+ unsigned offset = irq - desc->dev->irq;
+ msi_mask_irq(desc, 1 << offset, flag << offset);
}
- entry->msi_attrib.masked = !!flag;
- return 1;
+}
+
+void mask_msi_irq(unsigned int irq)
+{
+ msi_set_mask_bit(irq, 1);
+}
+
+void unmask_msi_irq(unsigned int irq)
+{
+ msi_set_mask_bit(irq, 0);
}
void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
{
struct msi_desc *entry = get_irq_desc_msi(desc);
- switch(entry->msi_attrib.type) {
- case PCI_CAP_ID_MSI:
- {
+ if (entry->msi_attrib.is_msix) {
+ void __iomem *base = entry->mask_base +
+ entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
+
+ msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
+ msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
+ msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET);
+ } else {
struct pci_dev *dev = entry->dev;
int pos = entry->msi_attrib.pos;
u16 data;
@@ -201,21 +215,6 @@ void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
pci_read_config_word(dev, msi_data_reg(pos, 0), &data);
}
msg->data = data;
- break;
- }
- case PCI_CAP_ID_MSIX:
- {
- void __iomem *base;
- base = entry->mask_base +
- entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
-
- msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
- msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
- msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET);
- break;
- }
- default:
- BUG();
}
}
@@ -229,11 +228,25 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg)
void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
{
struct msi_desc *entry = get_irq_desc_msi(desc);
- switch (entry->msi_attrib.type) {
- case PCI_CAP_ID_MSI:
- {
+ if (entry->msi_attrib.is_msix) {
+ void __iomem *base;
+ base = entry->mask_base +
+ entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
+
+ writel(msg->address_lo,
+ base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
+ writel(msg->address_hi,
+ base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
+ writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
+ } else {
struct pci_dev *dev = entry->dev;
int pos = entry->msi_attrib.pos;
+ u16 msgctl;
+
+ pci_read_config_word(dev, msi_control_reg(pos), &msgctl);
+ msgctl &= ~PCI_MSI_FLAGS_QSIZE;
+ msgctl |= entry->msi_attrib.multiple << 4;
+ pci_write_config_word(dev, msi_control_reg(pos), msgctl);
pci_write_config_dword(dev, msi_lower_address_reg(pos),
msg->address_lo);
@@ -246,23 +259,6 @@ void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
pci_write_config_word(dev, msi_data_reg(pos, 0),
msg->data);
}
- break;
- }
- case PCI_CAP_ID_MSIX:
- {
- void __iomem *base;
- base = entry->mask_base +
- entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
-
- writel(msg->address_lo,
- base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
- writel(msg->address_hi,
- base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
- writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
- break;
- }
- default:
- BUG();
}
entry->msg = *msg;
}
@@ -274,37 +270,18 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg)
write_msi_msg_desc(desc, msg);
}
-void mask_msi_irq(unsigned int irq)
-{
- struct irq_desc *desc = irq_to_desc(irq);
-
- msi_set_mask_bits(desc, 1, 1);
- msix_flush_writes(desc);
-}
-
-void unmask_msi_irq(unsigned int irq)
-{
- struct irq_desc *desc = irq_to_desc(irq);
-
- msi_set_mask_bits(desc, 1, 0);
- msix_flush_writes(desc);
-}
-
static int msi_free_irqs(struct pci_dev* dev);
-static struct msi_desc* alloc_msi_entry(void)
+static struct msi_desc *alloc_msi_entry(struct pci_dev *dev)
{
- struct msi_desc *entry;
-
- entry = kzalloc(sizeof(struct msi_desc), GFP_KERNEL);
- if (!entry)
+ struct msi_desc *desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+ if (!desc)
return NULL;
- INIT_LIST_HEAD(&entry->list);
- entry->irq = 0;
- entry->dev = NULL;
+ INIT_LIST_HEAD(&desc->list);
+ desc->dev = dev;
- return entry;
+ return desc;
}
static void pci_intx_for_msi(struct pci_dev *dev, int enable)
@@ -328,15 +305,11 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
pci_intx_for_msi(dev, 0);
msi_set_enable(dev, 0);
write_msi_msg(dev->irq, &entry->msg);
- if (entry->msi_attrib.maskbit) {
- struct irq_desc *desc = irq_to_desc(dev->irq);
- msi_set_mask_bits(desc, entry->msi_attrib.maskbits_mask,
- entry->msi_attrib.masked);
- }
pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
+ msi_mask_irq(entry, msi_capable_mask(control), entry->masked);
control &= ~PCI_MSI_FLAGS_QSIZE;
- control |= PCI_MSI_FLAGS_ENABLE;
+ control |= (entry->msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE;
pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
}
@@ -354,9 +327,8 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
msix_set_enable(dev, 0);
list_for_each_entry(entry, &dev->msi_list, list) {
- struct irq_desc *desc = irq_to_desc(entry->irq);
write_msi_msg(entry->irq, &entry->msg);
- msi_set_mask_bits(desc, 1, entry->msi_attrib.masked);
+ msix_mask_irq(entry, entry->masked);
}
BUG_ON(list_empty(&dev->msi_list));
@@ -378,52 +350,48 @@ EXPORT_SYMBOL_GPL(pci_restore_msi_state);
/**
* msi_capability_init - configure device's MSI capability structure
* @dev: pointer to the pci_dev data structure of MSI device function
+ * @nvec: number of interrupts to allocate
*
- * Setup the MSI capability structure of device function with a single
- * MSI irq, regardless of device function is capable of handling
- * multiple messages. A return of zero indicates the successful setup
- * of an entry zero with the new MSI irq or non-zero for otherwise.
- **/
-static int msi_capability_init(struct pci_dev *dev)
+ * Setup the MSI capability structure of the device with the requested
+ * number of interrupts. A return value of zero indicates the successful
+ * setup of an entry with the new MSI irq. A negative return value indicates
+ * an error, and a positive return value indicates the number of interrupts
+ * which could have been allocated.
+ */
+static int msi_capability_init(struct pci_dev *dev, int nvec)
{
struct msi_desc *entry;
int pos, ret;
u16 control;
+ unsigned mask;
msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */
pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
pci_read_config_word(dev, msi_control_reg(pos), &control);
/* MSI Entry Initialization */
- entry = alloc_msi_entry();
+ entry = alloc_msi_entry(dev);
if (!entry)
return -ENOMEM;
- entry->msi_attrib.type = PCI_CAP_ID_MSI;
+ entry->msi_attrib.is_msix = 0;
entry->msi_attrib.is_64 = is_64bit_address(control);
entry->msi_attrib.entry_nr = 0;
entry->msi_attrib.maskbit = is_mask_bit_support(control);
- entry->msi_attrib.masked = 1;
entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
entry->msi_attrib.pos = pos;
- entry->dev = dev;
- if (entry->msi_attrib.maskbit) {
- unsigned int base, maskbits, temp;
-
- base = msi_mask_bits_reg(pos, entry->msi_attrib.is_64);
- entry->mask_base = (void __iomem *)(long)base;
-
- /* All MSIs are unmasked by default, Mask them all */
- pci_read_config_dword(dev, base, &maskbits);
- temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1);
- maskbits |= temp;
- pci_write_config_dword(dev, base, maskbits);
- entry->msi_attrib.maskbits_mask = temp;
- }
+
+ entry->mask_pos = msi_mask_bits_reg(pos, entry->msi_attrib.is_64);
+ /* All MSIs are unmasked by default, Mask them all */
+ if (entry->msi_attrib.maskbit)
+ pci_read_config_dword(dev, entry->mask_pos, &entry->masked);
+ mask = msi_capable_mask(control);
+ msi_mask_irq(entry, mask, mask);
+
list_add_tail(&entry->list, &dev->msi_list);
/* Configure MSI capability structure */
- ret = arch_setup_msi_irqs(dev, 1, PCI_CAP_ID_MSI);
+ ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
if (ret) {
msi_free_irqs(dev);
return ret;
@@ -476,26 +444,28 @@ static int msix_capability_init(struct pci_dev *dev,
/* MSI-X Table Initialization */
for (i = 0; i < nvec; i++) {
- entry = alloc_msi_entry();
+ entry = alloc_msi_entry(dev);
if (!entry)
break;
j = entries[i].entry;
- entry->msi_attrib.type = PCI_CAP_ID_MSIX;
+ entry->msi_attrib.is_msix = 1;
entry->msi_attrib.is_64 = 1;
entry->msi_attrib.entry_nr = j;
- entry->msi_attrib.maskbit = 1;
- entry->msi_attrib.masked = 1;
entry->msi_attrib.default_irq = dev->irq;
entry->msi_attrib.pos = pos;
- entry->dev = dev;
entry->mask_base = base;
+ entry->masked = readl(base + j * PCI_MSIX_ENTRY_SIZE +
+ PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+ msix_mask_irq(entry, 1);
list_add_tail(&entry->list, &dev->msi_list);
}
ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
- if (ret) {
+ if (ret < 0) {
+ /* If we had some success report the number of irqs
+ * we succeeded in setting up. */
int avail = 0;
list_for_each_entry(entry, &dev->msi_list, list) {
if (entry->irq != 0) {
@@ -503,14 +473,13 @@ static int msix_capability_init(struct pci_dev *dev,
}
}
- msi_free_irqs(dev);
+ if (avail != 0)
+ ret = avail;
+ }
- /* If we had some success report the number of irqs
- * we succeeded in setting up.
- */
- if (avail == 0)
- avail = ret;
- return avail;
+ if (ret) {
+ msi_free_irqs(dev);
+ return ret;
}
i = 0;
@@ -575,39 +544,54 @@ static int pci_msi_check_device(struct pci_dev* dev, int nvec, int type)
}
/**
- * pci_enable_msi - configure device's MSI capability structure
- * @dev: pointer to the pci_dev data structure of MSI device function
+ * pci_enable_msi_block - configure device's MSI capability structure
+ * @dev: device to configure
+ * @nvec: number of interrupts to configure
*
- * Setup the MSI capability structure of device function with
- * a single MSI irq upon its software driver call to request for
- * MSI mode enabled on its hardware device function. A return of zero
- * indicates the successful setup of an entry zero with the new MSI
- * irq or non-zero for otherwise.
- **/
-int pci_enable_msi(struct pci_dev* dev)
+ * Allocate IRQs for a device with the MSI capability.
+ * This function returns a negative errno if an error occurs. If it
+ * is unable to allocate the number of interrupts requested, it returns
+ * the number of interrupts it might be able to allocate. If it successfully
+ * allocates at least the number of interrupts requested, it returns 0 and
+ * updates the @dev's irq member to the lowest new interrupt number; the
+ * other interrupt numbers allocated to this device are consecutive.
+ */
+int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec)
{
- int status;
+ int status, pos, maxvec;
+ u16 msgctl;
- status = pci_msi_check_device(dev, 1, PCI_CAP_ID_MSI);
+ pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+ if (!pos)
+ return -EINVAL;
+ pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl);
+ maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1);
+ if (nvec > maxvec)
+ return maxvec;
+
+ status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSI);
if (status)
return status;
WARN_ON(!!dev->msi_enabled);
- /* Check whether driver already requested for MSI-X irqs */
+ /* Check whether driver already requested MSI-X irqs */
if (dev->msix_enabled) {
dev_info(&dev->dev, "can't enable MSI "
"(MSI-X already enabled)\n");
return -EINVAL;
}
- status = msi_capability_init(dev);
+
+ status = msi_capability_init(dev, nvec);
return status;
}
-EXPORT_SYMBOL(pci_enable_msi);
+EXPORT_SYMBOL(pci_enable_msi_block);
-void pci_msi_shutdown(struct pci_dev* dev)
+void pci_msi_shutdown(struct pci_dev *dev)
{
- struct msi_desc *entry;
+ struct msi_desc *desc;
+ u32 mask;
+ u16 ctrl;
if (!pci_msi_enable || !dev || !dev->msi_enabled)
return;
@@ -617,19 +601,15 @@ void pci_msi_shutdown(struct pci_dev* dev)
dev->msi_enabled = 0;
BUG_ON(list_empty(&dev->msi_list));
- entry = list_entry(dev->msi_list.next, struct msi_desc, list);
- /* Return the the pci reset with msi irqs unmasked */
- if (entry->msi_attrib.maskbit) {
- u32 mask = entry->msi_attrib.maskbits_mask;
- struct irq_desc *desc = irq_to_desc(dev->irq);
- msi_set_mask_bits(desc, mask, ~mask);
- }
- if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI)
- return;
+ desc = list_first_entry(&dev->msi_list, struct msi_desc, list);
+ pci_read_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS, &ctrl);
+ mask = msi_capable_mask(ctrl);
+ msi_mask_irq(desc, mask, ~mask);
/* Restore dev->irq to its default pin-assertion irq */
- dev->irq = entry->msi_attrib.default_irq;
+ dev->irq = desc->msi_attrib.default_irq;
}
+
void pci_disable_msi(struct pci_dev* dev)
{
struct msi_desc *entry;
@@ -640,7 +620,7 @@ void pci_disable_msi(struct pci_dev* dev)
pci_msi_shutdown(dev);
entry = list_entry(dev->msi_list.next, struct msi_desc, list);
- if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI)
+ if (entry->msi_attrib.is_msix)
return;
msi_free_irqs(dev);
@@ -652,14 +632,18 @@ static int msi_free_irqs(struct pci_dev* dev)
struct msi_desc *entry, *tmp;
list_for_each_entry(entry, &dev->msi_list, list) {
- if (entry->irq)
- BUG_ON(irq_has_action(entry->irq));
+ int i, nvec;
+ if (!entry->irq)
+ continue;
+ nvec = 1 << entry->msi_attrib.multiple;
+ for (i = 0; i < nvec; i++)
+ BUG_ON(irq_has_action(entry->irq + i));
}
arch_teardown_msi_irqs(dev);
list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
- if (entry->msi_attrib.type == PCI_CAP_ID_MSIX) {
+ if (entry->msi_attrib.is_msix) {
writel(1, entry->mask_base + entry->msi_attrib.entry_nr
* PCI_MSIX_ENTRY_SIZE
+ PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
@@ -675,6 +659,23 @@ static int msi_free_irqs(struct pci_dev* dev)
}
/**
+ * pci_msix_table_size - return the number of device's MSI-X table entries
+ * @dev: pointer to the pci_dev data structure of MSI-X device function
+ */
+int pci_msix_table_size(struct pci_dev *dev)
+{
+ int pos;
+ u16 control;
+
+ pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+ if (!pos)
+ return 0;
+
+ pci_read_config_word(dev, msi_control_reg(pos), &control);
+ return multi_msix_capable(control);
+}
+
+/**
* pci_enable_msix - configure device's MSI-X capability structure
* @dev: pointer to the pci_dev data structure of MSI-X device function
* @entries: pointer to an array of MSI-X entries
@@ -691,9 +692,8 @@ static int msi_free_irqs(struct pci_dev* dev)
**/
int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
{
- int status, pos, nr_entries;
+ int status, nr_entries;
int i, j;
- u16 control;
if (!entries)
return -EINVAL;
@@ -702,9 +702,7 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
if (status)
return status;
- pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
- pci_read_config_word(dev, msi_control_reg(pos), &control);
- nr_entries = multi_msix_capable(control);
+ nr_entries = pci_msix_table_size(dev);
if (nvec > nr_entries)
return -EINVAL;
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
index 3898f5237144..71f4df2ef654 100644
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -20,14 +20,8 @@
#define msi_mask_bits_reg(base, is64bit) \
( (is64bit == 1) ? base+PCI_MSI_MASK_BIT : base+PCI_MSI_MASK_BIT-4)
#define msi_disable(control) control &= ~PCI_MSI_FLAGS_ENABLE
-#define multi_msi_capable(control) \
- (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1))
-#define multi_msi_enable(control, num) \
- control |= (((num >> 1) << 4) & PCI_MSI_FLAGS_QSIZE);
#define is_64bit_address(control) (!!(control & PCI_MSI_FLAGS_64BIT))
#define is_mask_bit_support(control) (!!(control & PCI_MSI_FLAGS_MASKBIT))
-#define msi_enable(control, num) multi_msi_enable(control, num); \
- control |= PCI_MSI_FLAGS_ENABLE
#define msix_table_offset_reg(base) (base + 0x04)
#define msix_pba_offset_reg(base) (base + 0x08)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index deea8a187eb8..ea15b0537457 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -18,221 +18,6 @@
#include <linux/pci-acpi.h>
#include "pci.h"
-struct acpi_osc_data {
- acpi_handle handle;
- u32 support_set;
- u32 control_set;
- u32 control_query;
- int is_queried;
- struct list_head sibiling;
-};
-static LIST_HEAD(acpi_osc_data_list);
-
-struct acpi_osc_args {
- u32 capbuf[3];
-};
-
-static DEFINE_MUTEX(pci_acpi_lock);
-
-static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle)
-{
- struct acpi_osc_data *data;
-
- list_for_each_entry(data, &acpi_osc_data_list, sibiling) {
- if (data->handle == handle)
- return data;
- }
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data)
- return NULL;
- INIT_LIST_HEAD(&data->sibiling);
- data->handle = handle;
- list_add_tail(&data->sibiling, &acpi_osc_data_list);
- return data;
-}
-
-static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40,
- 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
-
-static acpi_status acpi_run_osc(acpi_handle handle,
- struct acpi_osc_args *osc_args, u32 *retval)
-{
- acpi_status status;
- struct acpi_object_list input;
- union acpi_object in_params[4];
- struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
- union acpi_object *out_obj;
- u32 errors, flags = osc_args->capbuf[OSC_QUERY_TYPE];
-
- /* Setting up input parameters */
- input.count = 4;
- input.pointer = in_params;
- in_params[0].type = ACPI_TYPE_BUFFER;
- in_params[0].buffer.length = 16;
- in_params[0].buffer.pointer = OSC_UUID;
- in_params[1].type = ACPI_TYPE_INTEGER;
- in_params[1].integer.value = 1;
- in_params[2].type = ACPI_TYPE_INTEGER;
- in_params[2].integer.value = 3;
- in_params[3].type = ACPI_TYPE_BUFFER;
- in_params[3].buffer.length = 12;
- in_params[3].buffer.pointer = (u8 *)osc_args->capbuf;
-
- status = acpi_evaluate_object(handle, "_OSC", &input, &output);
- if (ACPI_FAILURE(status))
- return status;
-
- if (!output.length)
- return AE_NULL_OBJECT;
-
- out_obj = output.pointer;
- if (out_obj->type != ACPI_TYPE_BUFFER) {
- printk(KERN_DEBUG "Evaluate _OSC returns wrong type\n");
- status = AE_TYPE;
- goto out_kfree;
- }
- /* Need to ignore the bit0 in result code */
- errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
- if (errors) {
- if (errors & OSC_REQUEST_ERROR)
- printk(KERN_DEBUG "_OSC request fails\n");
- if (errors & OSC_INVALID_UUID_ERROR)
- printk(KERN_DEBUG "_OSC invalid UUID\n");
- if (errors & OSC_INVALID_REVISION_ERROR)
- printk(KERN_DEBUG "_OSC invalid revision\n");
- if (errors & OSC_CAPABILITIES_MASK_ERROR) {
- if (flags & OSC_QUERY_ENABLE)
- goto out_success;
- printk(KERN_DEBUG "_OSC FW not grant req. control\n");
- status = AE_SUPPORT;
- goto out_kfree;
- }
- status = AE_ERROR;
- goto out_kfree;
- }
-out_success:
- *retval = *((u32 *)(out_obj->buffer.pointer + 8));
- status = AE_OK;
-
-out_kfree:
- kfree(output.pointer);
- return status;
-}
-
-static acpi_status __acpi_query_osc(u32 flags, struct acpi_osc_data *osc_data)
-{
- acpi_status status;
- u32 support_set, result;
- struct acpi_osc_args osc_args;
-
- /* do _OSC query for all possible controls */
- support_set = osc_data->support_set | (flags & OSC_SUPPORT_MASKS);
- osc_args.capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
- osc_args.capbuf[OSC_SUPPORT_TYPE] = support_set;
- osc_args.capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
-
- status = acpi_run_osc(osc_data->handle, &osc_args, &result);
- if (ACPI_SUCCESS(status)) {
- osc_data->support_set = support_set;
- osc_data->control_query = result;
- osc_data->is_queried = 1;
- }
-
- return status;
-}
-
-/*
- * pci_acpi_osc_support: Invoke _OSC indicating support for the given feature
- * @flags: Bitmask of flags to support
- *
- * See the ACPI spec for the definition of the flags
- */
-int pci_acpi_osc_support(acpi_handle handle, u32 flags)
-{
- acpi_status status;
- acpi_handle tmp;
- struct acpi_osc_data *osc_data;
- int rc = 0;
-
- status = acpi_get_handle(handle, "_OSC", &tmp);
- if (ACPI_FAILURE(status))
- return -ENOTTY;
-
- mutex_lock(&pci_acpi_lock);
- osc_data = acpi_get_osc_data(handle);
- if (!osc_data) {
- printk(KERN_ERR "acpi osc data array is full\n");
- rc = -ENOMEM;
- goto out;
- }
-
- __acpi_query_osc(flags, osc_data);
-out:
- mutex_unlock(&pci_acpi_lock);
- return rc;
-}
-
-/**
- * pci_osc_control_set - commit requested control to Firmware
- * @handle: acpi_handle for the target ACPI object
- * @flags: driver's requested control bits
- *
- * Attempt to take control from Firmware on requested control bits.
- **/
-acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
-{
- acpi_status status;
- u32 control_req, control_set, result;
- acpi_handle tmp;
- struct acpi_osc_data *osc_data;
- struct acpi_osc_args osc_args;
-
- status = acpi_get_handle(handle, "_OSC", &tmp);
- if (ACPI_FAILURE(status))
- return status;
-
- mutex_lock(&pci_acpi_lock);
- osc_data = acpi_get_osc_data(handle);
- if (!osc_data) {
- printk(KERN_ERR "acpi osc data array is full\n");
- status = AE_ERROR;
- goto out;
- }
-
- control_req = (flags & OSC_CONTROL_MASKS);
- if (!control_req) {
- status = AE_TYPE;
- goto out;
- }
-
- /* No need to evaluate _OSC if the control was already granted. */
- if ((osc_data->control_set & control_req) == control_req)
- goto out;
-
- if (!osc_data->is_queried) {
- status = __acpi_query_osc(osc_data->support_set, osc_data);
- if (ACPI_FAILURE(status))
- goto out;
- }
-
- if ((osc_data->control_query & control_req) != control_req) {
- status = AE_SUPPORT;
- goto out;
- }
-
- control_set = osc_data->control_set | control_req;
- osc_args.capbuf[OSC_QUERY_TYPE] = 0;
- osc_args.capbuf[OSC_SUPPORT_TYPE] = osc_data->support_set;
- osc_args.capbuf[OSC_CONTROL_TYPE] = control_set;
- status = acpi_run_osc(handle, &osc_args, &result);
- if (ACPI_SUCCESS(status))
- osc_data->control_set = result;
-out:
- mutex_unlock(&pci_acpi_lock);
- return status;
-}
-EXPORT_SYMBOL(pci_osc_control_set);
-
/*
* _SxD returns the D-state with the highest power
* (lowest D-state number) supported in the S-state "x".
@@ -386,12 +171,12 @@ static int __init acpi_pci_init(void)
{
int ret;
- if (acpi_gbl_FADT.boot_flags & BAF_MSI_NOT_SUPPORTED) {
+ if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) {
printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n");
pci_no_msi();
}
- if (acpi_gbl_FADT.boot_flags & BAF_PCIE_ASPM_CONTROL) {
+ if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
pcie_no_aspm();
}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 93eac1423585..d76c4c85367e 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -99,6 +99,52 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
}
static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
+/**
+ * store_remove_id - remove a PCI device ID from this driver
+ * @driver: target device driver
+ * @buf: buffer for scanning device ID data
+ * @count: input size
+ *
+ * Removes a dynamic pci device ID to this driver.
+ */
+static ssize_t
+store_remove_id(struct device_driver *driver, const char *buf, size_t count)
+{
+ struct pci_dynid *dynid, *n;
+ struct pci_driver *pdrv = to_pci_driver(driver);
+ __u32 vendor, device, subvendor = PCI_ANY_ID,
+ subdevice = PCI_ANY_ID, class = 0, class_mask = 0;
+ int fields = 0;
+ int retval = -ENODEV;
+
+ fields = sscanf(buf, "%x %x %x %x %x %x",
+ &vendor, &device, &subvendor, &subdevice,
+ &class, &class_mask);
+ if (fields < 2)
+ return -EINVAL;
+
+ spin_lock(&pdrv->dynids.lock);
+ list_for_each_entry_safe(dynid, n, &pdrv->dynids.list, node) {
+ struct pci_device_id *id = &dynid->id;
+ if ((id->vendor == vendor) &&
+ (id->device == device) &&
+ (subvendor == PCI_ANY_ID || id->subvendor == subvendor) &&
+ (subdevice == PCI_ANY_ID || id->subdevice == subdevice) &&
+ !((id->class ^ class) & class_mask)) {
+ list_del(&dynid->node);
+ kfree(dynid);
+ retval = 0;
+ break;
+ }
+ }
+ spin_unlock(&pdrv->dynids.lock);
+
+ if (retval)
+ return retval;
+ return count;
+}
+static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id);
+
static void
pci_free_dynids(struct pci_driver *drv)
{
@@ -125,6 +171,20 @@ static void pci_remove_newid_file(struct pci_driver *drv)
{
driver_remove_file(&drv->driver, &driver_attr_new_id);
}
+
+static int
+pci_create_removeid_file(struct pci_driver *drv)
+{
+ int error = 0;
+ if (drv->probe != NULL)
+ error = driver_create_file(&drv->driver,&driver_attr_remove_id);
+ return error;
+}
+
+static void pci_remove_removeid_file(struct pci_driver *drv)
+{
+ driver_remove_file(&drv->driver, &driver_attr_remove_id);
+}
#else /* !CONFIG_HOTPLUG */
static inline void pci_free_dynids(struct pci_driver *drv) {}
static inline int pci_create_newid_file(struct pci_driver *drv)
@@ -132,6 +192,11 @@ static inline int pci_create_newid_file(struct pci_driver *drv)
return 0;
}
static inline void pci_remove_newid_file(struct pci_driver *drv) {}
+static inline int pci_create_removeid_file(struct pci_driver *drv)
+{
+ return 0;
+}
+static inline void pci_remove_removeid_file(struct pci_driver *drv) {}
#endif
/**
@@ -212,10 +277,9 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
node = dev_to_node(&dev->dev);
if (node >= 0) {
int cpu;
- node_to_cpumask_ptr(nodecpumask, node);
get_online_cpus();
- cpu = cpumask_any_and(nodecpumask, cpu_online_mask);
+ cpu = cpumask_any_and(cpumask_of_node(node), cpu_online_mask);
if (cpu < nr_cpu_ids)
error = work_on_cpu(cpu, local_pci_probe, &ddi);
else
@@ -352,53 +416,60 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
- int i = 0;
+
+ pci_dev->state_saved = false;
if (drv && drv->suspend) {
pci_power_t prev = pci_dev->current_state;
+ int error;
- pci_dev->state_saved = false;
-
- i = drv->suspend(pci_dev, state);
- suspend_report_result(drv->suspend, i);
- if (i)
- return i;
-
- if (pci_dev->state_saved)
- goto Fixup;
+ error = drv->suspend(pci_dev, state);
+ suspend_report_result(drv->suspend, error);
+ if (error)
+ return error;
- if (pci_dev->current_state != PCI_D0
+ if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
&& pci_dev->current_state != PCI_UNKNOWN) {
WARN_ONCE(pci_dev->current_state != prev,
"PCI PM: Device state not saved by %pF\n",
drv->suspend);
- goto Fixup;
}
}
- pci_save_state(pci_dev);
- /*
- * This is for compatibility with existing code with legacy PM support.
- */
- pci_pm_set_unknown_state(pci_dev);
-
- Fixup:
pci_fixup_device(pci_fixup_suspend, pci_dev);
- return i;
+ return 0;
}
static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
- int i = 0;
if (drv && drv->suspend_late) {
- i = drv->suspend_late(pci_dev, state);
- suspend_report_result(drv->suspend_late, i);
+ pci_power_t prev = pci_dev->current_state;
+ int error;
+
+ error = drv->suspend_late(pci_dev, state);
+ suspend_report_result(drv->suspend_late, error);
+ if (error)
+ return error;
+
+ if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
+ && pci_dev->current_state != PCI_UNKNOWN) {
+ WARN_ONCE(pci_dev->current_state != prev,
+ "PCI PM: Device state not saved by %pF\n",
+ drv->suspend_late);
+ return 0;
+ }
}
- return i;
+
+ if (!pci_dev->state_saved)
+ pci_save_state(pci_dev);
+
+ pci_pm_set_unknown_state(pci_dev);
+
+ return 0;
}
static int pci_legacy_resume_early(struct device *dev)
@@ -423,6 +494,23 @@ static int pci_legacy_resume(struct device *dev)
/* Auxiliary functions used by the new power management framework */
+/**
+ * pci_restore_standard_config - restore standard config registers of PCI device
+ * @pci_dev: PCI device to handle
+ */
+static int pci_restore_standard_config(struct pci_dev *pci_dev)
+{
+ pci_update_current_state(pci_dev, PCI_UNKNOWN);
+
+ if (pci_dev->current_state != PCI_D0) {
+ int error = pci_set_power_state(pci_dev, PCI_D0);
+ if (error)
+ return error;
+ }
+
+ return pci_dev->state_saved ? pci_restore_state(pci_dev) : 0;
+}
+
static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
{
pci_restore_standard_config(pci_dev);
@@ -443,7 +531,6 @@ static void pci_pm_default_suspend(struct pci_dev *pci_dev)
/* Disable non-bridge devices without PM support */
if (!pci_is_bridge(pci_dev))
pci_disable_enabled_device(pci_dev);
- pci_save_state(pci_dev);
}
static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
@@ -493,13 +580,13 @@ static int pci_pm_suspend(struct device *dev)
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_SUSPEND);
+ pci_dev->state_saved = false;
+
if (!pm) {
pci_pm_default_suspend(pci_dev);
goto Fixup;
}
- pci_dev->state_saved = false;
-
if (pm->suspend) {
pci_power_t prev = pci_dev->current_state;
int error;
@@ -509,24 +596,14 @@ static int pci_pm_suspend(struct device *dev)
if (error)
return error;
- if (pci_dev->state_saved)
- goto Fixup;
-
- if (pci_dev->current_state != PCI_D0
+ if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
&& pci_dev->current_state != PCI_UNKNOWN) {
WARN_ONCE(pci_dev->current_state != prev,
"PCI PM: State of device not saved by %pF\n",
pm->suspend);
- goto Fixup;
}
}
- if (!pci_dev->state_saved) {
- pci_save_state(pci_dev);
- if (!pci_is_bridge(pci_dev))
- pci_prepare_to_sleep(pci_dev);
- }
-
Fixup:
pci_fixup_device(pci_fixup_suspend, pci_dev);
@@ -536,21 +613,43 @@ static int pci_pm_suspend(struct device *dev)
static int pci_pm_suspend_noirq(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
- int error = 0;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend_late(dev, PMSG_SUSPEND);
- if (drv && drv->pm && drv->pm->suspend_noirq) {
- error = drv->pm->suspend_noirq(dev);
- suspend_report_result(drv->pm->suspend_noirq, error);
+ if (!pm) {
+ pci_save_state(pci_dev);
+ return 0;
}
- if (!error)
- pci_pm_set_unknown_state(pci_dev);
+ if (pm->suspend_noirq) {
+ pci_power_t prev = pci_dev->current_state;
+ int error;
- return error;
+ error = pm->suspend_noirq(dev);
+ suspend_report_result(pm->suspend_noirq, error);
+ if (error)
+ return error;
+
+ if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
+ && pci_dev->current_state != PCI_UNKNOWN) {
+ WARN_ONCE(pci_dev->current_state != prev,
+ "PCI PM: State of device not saved by %pF\n",
+ pm->suspend_noirq);
+ return 0;
+ }
+ }
+
+ if (!pci_dev->state_saved) {
+ pci_save_state(pci_dev);
+ if (!pci_is_bridge(pci_dev))
+ pci_prepare_to_sleep(pci_dev);
+ }
+
+ pci_pm_set_unknown_state(pci_dev);
+
+ return 0;
}
static int pci_pm_resume_noirq(struct device *dev)
@@ -617,13 +716,13 @@ static int pci_pm_freeze(struct device *dev)
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_FREEZE);
+ pci_dev->state_saved = false;
+
if (!pm) {
pci_pm_default_suspend(pci_dev);
return 0;
}
- pci_dev->state_saved = false;
-
if (pm->freeze) {
int error;
@@ -633,9 +732,6 @@ static int pci_pm_freeze(struct device *dev)
return error;
}
- if (!pci_dev->state_saved)
- pci_save_state(pci_dev);
-
return 0;
}
@@ -643,20 +739,25 @@ static int pci_pm_freeze_noirq(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
struct device_driver *drv = dev->driver;
- int error = 0;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend_late(dev, PMSG_FREEZE);
if (drv && drv->pm && drv->pm->freeze_noirq) {
+ int error;
+
error = drv->pm->freeze_noirq(dev);
suspend_report_result(drv->pm->freeze_noirq, error);
+ if (error)
+ return error;
}
- if (!error)
- pci_pm_set_unknown_state(pci_dev);
+ if (!pci_dev->state_saved)
+ pci_save_state(pci_dev);
- return error;
+ pci_pm_set_unknown_state(pci_dev);
+
+ return 0;
}
static int pci_pm_thaw_noirq(struct device *dev)
@@ -699,46 +800,56 @@ static int pci_pm_poweroff(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
- int error = 0;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_HIBERNATE);
+ pci_dev->state_saved = false;
+
if (!pm) {
pci_pm_default_suspend(pci_dev);
goto Fixup;
}
- pci_dev->state_saved = false;
-
if (pm->poweroff) {
+ int error;
+
error = pm->poweroff(dev);
suspend_report_result(pm->poweroff, error);
+ if (error)
+ return error;
}
- if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
- pci_prepare_to_sleep(pci_dev);
-
Fixup:
pci_fixup_device(pci_fixup_suspend, pci_dev);
- return error;
+ return 0;
}
static int pci_pm_poweroff_noirq(struct device *dev)
{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
struct device_driver *drv = dev->driver;
- int error = 0;
if (pci_has_legacy_pm_support(to_pci_dev(dev)))
return pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
- if (drv && drv->pm && drv->pm->poweroff_noirq) {
+ if (!drv || !drv->pm)
+ return 0;
+
+ if (drv->pm->poweroff_noirq) {
+ int error;
+
error = drv->pm->poweroff_noirq(dev);
suspend_report_result(drv->pm->poweroff_noirq, error);
+ if (error)
+ return error;
}
- return error;
+ if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
+ pci_prepare_to_sleep(pci_dev);
+
+ return 0;
}
static int pci_pm_restore_noirq(struct device *dev)
@@ -852,13 +963,23 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner,
/* register with core */
error = driver_register(&drv->driver);
if (error)
- return error;
+ goto out;
error = pci_create_newid_file(drv);
if (error)
- driver_unregister(&drv->driver);
+ goto out_newid;
+ error = pci_create_removeid_file(drv);
+ if (error)
+ goto out_removeid;
+out:
return error;
+
+out_removeid:
+ pci_remove_newid_file(drv);
+out_newid:
+ driver_unregister(&drv->driver);
+ goto out;
}
/**
@@ -874,6 +995,7 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner,
void
pci_unregister_driver(struct pci_driver *drv)
{
+ pci_remove_removeid_file(drv);
pci_remove_newid_file(drv);
driver_unregister(&drv->driver);
pci_free_dynids(drv);
@@ -973,6 +1095,7 @@ struct bus_type pci_bus_type = {
.remove = pci_device_remove,
.shutdown = pci_device_shutdown,
.dev_attrs = pci_dev_attrs,
+ .bus_attrs = pci_bus_attrs,
.pm = PCI_PM_OPS_PTR,
};
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index dfc4e0ddf241..e9a8706a6401 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -219,6 +219,83 @@ msi_bus_store(struct device *dev, struct device_attribute *attr,
return count;
}
+#ifdef CONFIG_HOTPLUG
+static DEFINE_MUTEX(pci_remove_rescan_mutex);
+static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf,
+ size_t count)
+{
+ unsigned long val;
+ struct pci_bus *b = NULL;
+
+ if (strict_strtoul(buf, 0, &val) < 0)
+ return -EINVAL;
+
+ if (val) {
+ mutex_lock(&pci_remove_rescan_mutex);
+ while ((b = pci_find_next_bus(b)) != NULL)
+ pci_rescan_bus(b);
+ mutex_unlock(&pci_remove_rescan_mutex);
+ }
+ return count;
+}
+
+struct bus_attribute pci_bus_attrs[] = {
+ __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, bus_rescan_store),
+ __ATTR_NULL
+};
+
+static ssize_t
+dev_rescan_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long val;
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ if (strict_strtoul(buf, 0, &val) < 0)
+ return -EINVAL;
+
+ if (val) {
+ mutex_lock(&pci_remove_rescan_mutex);
+ pci_rescan_bus(pdev->bus);
+ mutex_unlock(&pci_remove_rescan_mutex);
+ }
+ return count;
+}
+
+static void remove_callback(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ mutex_lock(&pci_remove_rescan_mutex);
+ pci_remove_bus_device(pdev);
+ mutex_unlock(&pci_remove_rescan_mutex);
+}
+
+static ssize_t
+remove_store(struct device *dev, struct device_attribute *dummy,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ unsigned long val;
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ if (strict_strtoul(buf, 0, &val) < 0)
+ return -EINVAL;
+
+ if (pci_is_root_bus(pdev->bus))
+ return -EBUSY;
+
+ /* An attribute cannot be unregistered by one of its own methods,
+ * so we have to use this roundabout approach.
+ */
+ if (val)
+ ret = device_schedule_callback(dev, remove_callback);
+ if (ret)
+ count = ret;
+ return count;
+}
+#endif
+
struct device_attribute pci_dev_attrs[] = {
__ATTR_RO(resource),
__ATTR_RO(vendor),
@@ -237,10 +314,25 @@ struct device_attribute pci_dev_attrs[] = {
__ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
broken_parity_status_show,broken_parity_status_store),
__ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
+#ifdef CONFIG_HOTPLUG
+ __ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store),
+ __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store),
+#endif
__ATTR_NULL,
};
static ssize_t
+boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ return sprintf(buf, "%u\n",
+ !!(pdev->resource[PCI_ROM_RESOURCE].flags &
+ IORESOURCE_ROM_SHADOW));
+}
+struct device_attribute vga_attr = __ATTR_RO(boot_vga);
+
+static ssize_t
pci_read_config(struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
@@ -493,6 +585,19 @@ pci_mmap_legacy_io(struct kobject *kobj, struct bin_attribute *attr,
}
/**
+ * pci_adjust_legacy_attr - adjustment of legacy file attributes
+ * @b: bus to create files under
+ * @mmap_type: I/O port or memory
+ *
+ * Stub implementation. Can be overridden by arch if necessary.
+ */
+void __weak
+pci_adjust_legacy_attr(struct pci_bus *b, enum pci_mmap_state mmap_type)
+{
+ return;
+}
+
+/**
* pci_create_legacy_files - create legacy I/O port and memory files
* @b: bus to create files under
*
@@ -518,6 +623,7 @@ void pci_create_legacy_files(struct pci_bus *b)
b->legacy_io->read = pci_read_legacy_io;
b->legacy_io->write = pci_write_legacy_io;
b->legacy_io->mmap = pci_mmap_legacy_io;
+ pci_adjust_legacy_attr(b, pci_mmap_io);
error = device_create_bin_file(&b->dev, b->legacy_io);
if (error)
goto legacy_io_err;
@@ -528,6 +634,7 @@ void pci_create_legacy_files(struct pci_bus *b)
b->legacy_mem->size = 1024*1024;
b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
b->legacy_mem->mmap = pci_mmap_legacy_mem;
+ pci_adjust_legacy_attr(b, pci_mmap_mem);
error = device_create_bin_file(&b->dev, b->legacy_mem);
if (error)
goto legacy_mem_err;
@@ -719,8 +826,8 @@ static int pci_create_resource_files(struct pci_dev *pdev)
return 0;
}
#else /* !HAVE_PCI_MMAP */
-static inline int pci_create_resource_files(struct pci_dev *dev) { return 0; }
-static inline void pci_remove_resource_files(struct pci_dev *dev) { return; }
+int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
+void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
#endif /* HAVE_PCI_MMAP */
/**
@@ -884,18 +991,27 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
pdev->rom_attr = attr;
}
+ if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
+ retval = device_create_file(&pdev->dev, &vga_attr);
+ if (retval)
+ goto err_rom_file;
+ }
+
/* add platform-specific attributes */
retval = pcibios_add_platform_entries(pdev);
if (retval)
- goto err_rom_file;
+ goto err_vga_file;
/* add sysfs entries for various capabilities */
retval = pci_create_capabilities_sysfs(pdev);
if (retval)
- goto err_rom_file;
+ goto err_vga_file;
return 0;
+err_vga_file:
+ if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
+ device_remove_file(&pdev->dev, &vga_attr);
err_rom_file:
if (rom_size) {
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6d6120007af4..445fb6f7ea3f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -20,6 +20,8 @@
#include <linux/pm_wakeup.h>
#include <linux/interrupt.h>
#include <asm/dma.h> /* isa_dma_bridge_buggy */
+#include <linux/device.h>
+#include <asm/setup.h>
#include "pci.h"
unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT;
@@ -426,7 +428,6 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
* given PCI device
* @dev: PCI device to handle.
* @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
- * @wait: If 'true', wait for the device to change its power state
*
* RETURN VALUE:
* -EINVAL if the requested state is invalid.
@@ -435,12 +436,15 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
* 0 if device already is in the requested state.
* 0 if device's power state has been successfully changed.
*/
-static int
-pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
+static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
{
u16 pmcsr;
bool need_restore = false;
+ /* Check if we're already there */
+ if (dev->current_state == state)
+ return 0;
+
if (!dev->pm_cap)
return -EIO;
@@ -451,10 +455,7 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
* Can enter D0 from any state, but if we can only go deeper
* to sleep if we're already in a low power state
*/
- if (dev->current_state == state) {
- /* we're already there */
- return 0;
- } else if (state != PCI_D0 && dev->current_state <= PCI_D3cold
+ if (state != PCI_D0 && dev->current_state <= PCI_D3cold
&& dev->current_state > state) {
dev_err(&dev->dev, "invalid power transition "
"(from state %d to %d)\n", dev->current_state, state);
@@ -481,10 +482,8 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
break;
case PCI_UNKNOWN: /* Boot-up */
if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
- && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) {
+ && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
need_restore = true;
- wait = true;
- }
/* Fall-through: force to D0 */
default:
pmcsr = 0;
@@ -494,9 +493,6 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
/* enter specified state */
pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
- if (!wait)
- return 0;
-
/* Mandatory power management transition delays */
/* see PCI PM 1.1 5.6.1 table 18 */
if (state == PCI_D3hot || dev->current_state == PCI_D3hot)
@@ -521,7 +517,7 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
if (need_restore)
pci_restore_bars(dev);
- if (wait && dev->bus->self)
+ if (dev->bus->self)
pcie_aspm_pm_state_change(dev->bus->self);
return 0;
@@ -546,11 +542,58 @@ void pci_update_current_state(struct pci_dev *dev, pci_power_t state)
}
/**
+ * pci_platform_power_transition - Use platform to change device power state
+ * @dev: PCI device to handle.
+ * @state: State to put the device into.
+ */
+static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state)
+{
+ int error;
+
+ if (platform_pci_power_manageable(dev)) {
+ error = platform_pci_set_power_state(dev, state);
+ if (!error)
+ pci_update_current_state(dev, state);
+ } else {
+ error = -ENODEV;
+ /* Fall back to PCI_D0 if native PM is not supported */
+ pci_update_current_state(dev, PCI_D0);
+ }
+
+ return error;
+}
+
+/**
+ * __pci_start_power_transition - Start power transition of a PCI device
+ * @dev: PCI device to handle.
+ * @state: State to put the device into.
+ */
+static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state)
+{
+ if (state == PCI_D0)
+ pci_platform_power_transition(dev, PCI_D0);
+}
+
+/**
+ * __pci_complete_power_transition - Complete power transition of a PCI device
+ * @dev: PCI device to handle.
+ * @state: State to put the device into.
+ *
+ * This function should not be called directly by device drivers.
+ */
+int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state)
+{
+ return state > PCI_D0 ?
+ pci_platform_power_transition(dev, state) : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(__pci_complete_power_transition);
+
+/**
* pci_set_power_state - Set the power state of a PCI device
* @dev: PCI device to handle.
* @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
*
- * Transition a device to a new power state, using the platform formware and/or
+ * Transition a device to a new power state, using the platform firmware and/or
* the device's PCI PM registers.
*
* RETURN VALUE:
@@ -577,30 +620,21 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
*/
return 0;
- if (state == PCI_D0 && platform_pci_power_manageable(dev)) {
- /*
- * Allow the platform to change the state, for example via ACPI
- * _PR0, _PS0 and some such, but do not trust it.
- */
- int ret = platform_pci_set_power_state(dev, PCI_D0);
- if (!ret)
- pci_update_current_state(dev, PCI_D0);
- }
+ /* Check if we're already there */
+ if (dev->current_state == state)
+ return 0;
+
+ __pci_start_power_transition(dev, state);
+
/* This device is quirked not to be put into D3, so
don't put it in D3 */
if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3))
return 0;
- error = pci_raw_set_power_state(dev, state, true);
+ error = pci_raw_set_power_state(dev, state);
- if (state > PCI_D0 && platform_pci_power_manageable(dev)) {
- /* Allow the platform to finalize the transition */
- int ret = platform_pci_set_power_state(dev, state);
- if (!ret) {
- pci_update_current_state(dev, state);
- error = 0;
- }
- }
+ if (!__pci_complete_power_transition(dev, state))
+ error = 0;
return error;
}
@@ -645,6 +679,8 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
EXPORT_SYMBOL(pci_choose_state);
+#define PCI_EXP_SAVE_REGS 7
+
static int pci_save_pcie_state(struct pci_dev *dev)
{
int pos, i = 0;
@@ -657,7 +693,7 @@ static int pci_save_pcie_state(struct pci_dev *dev)
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
if (!save_state) {
- dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__);
+ dev_err(&dev->dev, "buffer not found in %s\n", __func__);
return -ENOMEM;
}
cap = (u16 *)&save_state->data[0];
@@ -666,6 +702,9 @@ static int pci_save_pcie_state(struct pci_dev *dev)
pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]);
pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
+ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]);
+ pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]);
+ pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]);
return 0;
}
@@ -686,6 +725,9 @@ static void pci_restore_pcie_state(struct pci_dev *dev)
pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]);
pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);
+ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]);
+ pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]);
+ pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]);
}
@@ -700,7 +742,7 @@ static int pci_save_pcix_state(struct pci_dev *dev)
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
if (!save_state) {
- dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__);
+ dev_err(&dev->dev, "buffer not found in %s\n", __func__);
return -ENOMEM;
}
@@ -773,6 +815,7 @@ pci_restore_state(struct pci_dev *dev)
}
pci_restore_pcix_state(dev);
pci_restore_msi_state(dev);
+ pci_restore_iov_state(dev);
return 0;
}
@@ -1231,7 +1274,7 @@ int pci_prepare_to_sleep(struct pci_dev *dev)
if (target_state == PCI_POWER_ERROR)
return -EIO;
- pci_enable_wake(dev, target_state, true);
+ pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev));
error = pci_set_power_state(dev, target_state);
@@ -1369,7 +1412,8 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev)
{
int error;
- error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_EXP, 4 * sizeof(u16));
+ error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_EXP,
+ PCI_EXP_SAVE_REGS * sizeof(u16));
if (error)
dev_err(&dev->dev,
"unable to preallocate PCI Express save buffer\n");
@@ -1381,50 +1425,6 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev)
}
/**
- * pci_restore_standard_config - restore standard config registers of PCI device
- * @dev: PCI device to handle
- *
- * This function assumes that the device's configuration space is accessible.
- * If the device needs to be powered up, the function will wait for it to
- * change the state.
- */
-int pci_restore_standard_config(struct pci_dev *dev)
-{
- pci_power_t prev_state;
- int error;
-
- pci_update_current_state(dev, PCI_D0);
-
- prev_state = dev->current_state;
- if (prev_state == PCI_D0)
- goto Restore;
-
- error = pci_raw_set_power_state(dev, PCI_D0, false);
- if (error)
- return error;
-
- /*
- * This assumes that we won't get a bus in B2 or B3 from the BIOS, but
- * we've made this assumption forever and it appears to be universally
- * satisfied.
- */
- switch(prev_state) {
- case PCI_D3cold:
- case PCI_D3hot:
- mdelay(pci_pm_d3_delay);
- break;
- case PCI_D2:
- udelay(PCI_PM_D2_DELAY);
- break;
- }
-
- pci_update_current_state(dev, PCI_D0);
-
- Restore:
- return dev->state_saved ? pci_restore_state(dev) : 0;
-}
-
-/**
* pci_enable_ari - enable ARI forwarding if hardware support it
* @dev: the PCI device
*/
@@ -1484,7 +1484,7 @@ pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
if (!pin)
return -1;
- while (dev->bus->self) {
+ while (dev->bus->parent) {
pin = pci_swizzle_interrupt_pin(dev, pin);
dev = dev->bus->self;
}
@@ -1504,7 +1504,7 @@ u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp)
{
u8 pin = *pinp;
- while (dev->bus->self) {
+ while (dev->bus->parent) {
pin = pci_swizzle_interrupt_pin(dev, pin);
dev = dev->bus->self;
}
@@ -2028,18 +2028,24 @@ static int __pcie_flr(struct pci_dev *dev, int probe)
pci_block_user_cfg_access(dev);
/* Wait for Transaction Pending bit clean */
+ pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
+ if (!(status & PCI_EXP_DEVSTA_TRPND))
+ goto transaction_done;
+
msleep(100);
pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
- if (status & PCI_EXP_DEVSTA_TRPND) {
- dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
+ if (!(status & PCI_EXP_DEVSTA_TRPND))
+ goto transaction_done;
+
+ dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
"sleeping for 1 second\n");
- ssleep(1);
- pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
- if (status & PCI_EXP_DEVSTA_TRPND)
- dev_info(&dev->dev, "Still busy after 1s; "
+ ssleep(1);
+ pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
+ if (status & PCI_EXP_DEVSTA_TRPND)
+ dev_info(&dev->dev, "Still busy after 1s; "
"proceeding with reset anyway\n");
- }
+transaction_done:
pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL,
PCI_EXP_DEVCTL_BCR_FLR);
mdelay(100);
@@ -2066,18 +2072,24 @@ static int __pci_af_flr(struct pci_dev *dev, int probe)
pci_block_user_cfg_access(dev);
/* Wait for Transaction Pending bit clean */
+ pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
+ if (!(status & PCI_AF_STATUS_TP))
+ goto transaction_done;
+
msleep(100);
pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
- if (status & PCI_AF_STATUS_TP) {
- dev_info(&dev->dev, "Busy after 100ms while trying to"
- " reset; sleeping for 1 second\n");
- ssleep(1);
- pci_read_config_byte(dev,
- cappos + PCI_AF_STATUS, &status);
- if (status & PCI_AF_STATUS_TP)
- dev_info(&dev->dev, "Still busy after 1s; "
- "proceeding with reset anyway\n");
- }
+ if (!(status & PCI_AF_STATUS_TP))
+ goto transaction_done;
+
+ dev_info(&dev->dev, "Busy after 100ms while trying to"
+ " reset; sleeping for 1 second\n");
+ ssleep(1);
+ pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
+ if (status & PCI_AF_STATUS_TP)
+ dev_info(&dev->dev, "Still busy after 1s; "
+ "proceeding with reset anyway\n");
+
+transaction_done:
pci_write_config_byte(dev, cappos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
mdelay(100);
@@ -2346,18 +2358,140 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags)
*/
int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
{
+ int reg;
+
if (resno < PCI_ROM_RESOURCE) {
*type = pci_bar_unknown;
return PCI_BASE_ADDRESS_0 + 4 * resno;
} else if (resno == PCI_ROM_RESOURCE) {
*type = pci_bar_mem32;
return dev->rom_base_reg;
+ } else if (resno < PCI_BRIDGE_RESOURCES) {
+ /* device specific resource */
+ reg = pci_iov_resource_bar(dev, resno, type);
+ if (reg)
+ return reg;
}
dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno);
return 0;
}
+#define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE
+static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0};
+spinlock_t resource_alignment_lock = SPIN_LOCK_UNLOCKED;
+
+/**
+ * pci_specified_resource_alignment - get resource alignment specified by user.
+ * @dev: the PCI device to get
+ *
+ * RETURNS: Resource alignment if it is specified.
+ * Zero if it is not specified.
+ */
+resource_size_t pci_specified_resource_alignment(struct pci_dev *dev)
+{
+ int seg, bus, slot, func, align_order, count;
+ resource_size_t align = 0;
+ char *p;
+
+ spin_lock(&resource_alignment_lock);
+ p = resource_alignment_param;
+ while (*p) {
+ count = 0;
+ if (sscanf(p, "%d%n", &align_order, &count) == 1 &&
+ p[count] == '@') {
+ p += count + 1;
+ } else {
+ align_order = -1;
+ }
+ if (sscanf(p, "%x:%x:%x.%x%n",
+ &seg, &bus, &slot, &func, &count) != 4) {
+ seg = 0;
+ if (sscanf(p, "%x:%x.%x%n",
+ &bus, &slot, &func, &count) != 3) {
+ /* Invalid format */
+ printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n",
+ p);
+ break;
+ }
+ }
+ p += count;
+ if (seg == pci_domain_nr(dev->bus) &&
+ bus == dev->bus->number &&
+ slot == PCI_SLOT(dev->devfn) &&
+ func == PCI_FUNC(dev->devfn)) {
+ if (align_order == -1) {
+ align = PAGE_SIZE;
+ } else {
+ align = 1 << align_order;
+ }
+ /* Found */
+ break;
+ }
+ if (*p != ';' && *p != ',') {
+ /* End of param or invalid format */
+ break;
+ }
+ p++;
+ }
+ spin_unlock(&resource_alignment_lock);
+ return align;
+}
+
+/**
+ * pci_is_reassigndev - check if specified PCI is target device to reassign
+ * @dev: the PCI device to check
+ *
+ * RETURNS: non-zero for PCI device is a target device to reassign,
+ * or zero is not.
+ */
+int pci_is_reassigndev(struct pci_dev *dev)
+{
+ return (pci_specified_resource_alignment(dev) != 0);
+}
+
+ssize_t pci_set_resource_alignment_param(const char *buf, size_t count)
+{
+ if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1)
+ count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1;
+ spin_lock(&resource_alignment_lock);
+ strncpy(resource_alignment_param, buf, count);
+ resource_alignment_param[count] = '\0';
+ spin_unlock(&resource_alignment_lock);
+ return count;
+}
+
+ssize_t pci_get_resource_alignment_param(char *buf, size_t size)
+{
+ size_t count;
+ spin_lock(&resource_alignment_lock);
+ count = snprintf(buf, size, "%s", resource_alignment_param);
+ spin_unlock(&resource_alignment_lock);
+ return count;
+}
+
+static ssize_t pci_resource_alignment_show(struct bus_type *bus, char *buf)
+{
+ return pci_get_resource_alignment_param(buf, PAGE_SIZE);
+}
+
+static ssize_t pci_resource_alignment_store(struct bus_type *bus,
+ const char *buf, size_t count)
+{
+ return pci_set_resource_alignment_param(buf, count);
+}
+
+BUS_ATTR(resource_alignment, 0644, pci_resource_alignment_show,
+ pci_resource_alignment_store);
+
+static int __init pci_resource_alignment_sysfs_init(void)
+{
+ return bus_create_file(&pci_bus_type,
+ &bus_attr_resource_alignment);
+}
+
+late_initcall(pci_resource_alignment_sysfs_init);
+
static void __devinit pci_no_domains(void)
{
#ifdef CONFIG_PCI_DOMAINS
@@ -2406,6 +2540,9 @@ static int __init pci_setup(char *str)
pci_cardbus_io_size = memparse(str + 9, &str);
} else if (!strncmp(str, "cbmemsize=", 10)) {
pci_cardbus_mem_size = memparse(str + 10, &str);
+ } else if (!strncmp(str, "resource_alignment=", 19)) {
+ pci_set_resource_alignment_param(str + 19,
+ strlen(str + 19));
} else {
printk(KERN_ERR "PCI: Unknown option `%s'\n",
str);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 07c0aa5275e6..d03f6b99f292 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -1,6 +1,8 @@
#ifndef DRIVERS_PCI_H
#define DRIVERS_PCI_H
+#include <linux/workqueue.h>
+
#define PCI_CFG_SPACE_SIZE 256
#define PCI_CFG_SPACE_EXP_SIZE 4096
@@ -49,7 +51,6 @@ extern void pci_disable_enabled_device(struct pci_dev *dev);
extern void pci_pm_init(struct pci_dev *dev);
extern void platform_pci_wakeup_init(struct pci_dev *dev);
extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
-extern int pci_restore_standard_config(struct pci_dev *dev);
static inline bool pci_is_bridge(struct pci_dev *pci_dev)
{
@@ -136,6 +137,12 @@ extern int pcie_mch_quirk;
extern struct device_attribute pci_dev_attrs[];
extern struct device_attribute dev_attr_cpuaffinity;
extern struct device_attribute dev_attr_cpulistaffinity;
+#ifdef CONFIG_HOTPLUG
+extern struct bus_attribute pci_bus_attrs[];
+#else
+#define pci_bus_attrs NULL
+#endif
+
/**
* pci_match_one_device - Tell if a PCI device structure has a matching
@@ -178,6 +185,7 @@ enum pci_bar_type {
pci_bar_mem64, /* A 64-bit memory BAR */
};
+extern int pci_setup_device(struct pci_dev *dev);
extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
struct resource *res, unsigned int reg);
extern int pci_resource_bar(struct pci_dev *dev, int resno,
@@ -195,4 +203,60 @@ static inline int pci_ari_enabled(struct pci_bus *bus)
return bus->self && bus->self->ari_enabled;
}
+#ifdef CONFIG_PCI_QUIRKS
+extern int pci_is_reassigndev(struct pci_dev *dev);
+resource_size_t pci_specified_resource_alignment(struct pci_dev *dev);
+extern void pci_disable_bridge_window(struct pci_dev *dev);
+#endif
+
+/* Single Root I/O Virtualization */
+struct pci_sriov {
+ int pos; /* capability position */
+ int nres; /* number of resources */
+ u32 cap; /* SR-IOV Capabilities */
+ u16 ctrl; /* SR-IOV Control */
+ u16 total; /* total VFs associated with the PF */
+ u16 initial; /* initial VFs associated with the PF */
+ u16 nr_virtfn; /* number of VFs available */
+ u16 offset; /* first VF Routing ID offset */
+ u16 stride; /* following VF stride */
+ u32 pgsz; /* page size for BAR alignment */
+ u8 link; /* Function Dependency Link */
+ struct pci_dev *dev; /* lowest numbered PF */
+ struct pci_dev *self; /* this PF */
+ struct mutex lock; /* lock for VF bus */
+ struct work_struct mtask; /* VF Migration task */
+ u8 __iomem *mstate; /* VF Migration State Array */
+};
+
+#ifdef CONFIG_PCI_IOV
+extern int pci_iov_init(struct pci_dev *dev);
+extern void pci_iov_release(struct pci_dev *dev);
+extern int pci_iov_resource_bar(struct pci_dev *dev, int resno,
+ enum pci_bar_type *type);
+extern void pci_restore_iov_state(struct pci_dev *dev);
+extern int pci_iov_bus_range(struct pci_bus *bus);
+#else
+static inline int pci_iov_init(struct pci_dev *dev)
+{
+ return -ENODEV;
+}
+static inline void pci_iov_release(struct pci_dev *dev)
+
+{
+}
+static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno,
+ enum pci_bar_type *type)
+{
+ return 0;
+}
+static inline void pci_restore_iov_state(struct pci_dev *dev)
+{
+}
+static inline int pci_iov_bus_range(struct pci_bus *bus)
+{
+ return 0;
+}
+#endif /* CONFIG_PCI_IOV */
+
#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index e390707661dd..32ade5af927e 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -38,30 +38,13 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-static int __devinit aer_probe (struct pcie_device *dev,
- const struct pcie_port_service_id *id );
+static int __devinit aer_probe (struct pcie_device *dev);
static void aer_remove(struct pcie_device *dev);
-static int aer_suspend(struct pcie_device *dev, pm_message_t state)
-{return 0;}
-static int aer_resume(struct pcie_device *dev) {return 0;}
static pci_ers_result_t aer_error_detected(struct pci_dev *dev,
enum pci_channel_state error);
static void aer_error_resume(struct pci_dev *dev);
static pci_ers_result_t aer_root_reset(struct pci_dev *dev);
-/*
- * PCI Express bus's AER Root service driver data structure
- */
-static struct pcie_port_service_id aer_id[] = {
- {
- .vendor = PCI_ANY_ID,
- .device = PCI_ANY_ID,
- .port_type = PCIE_RC_PORT,
- .service_type = PCIE_PORT_SERVICE_AER,
- },
- { /* end: all zeroes */ }
-};
-
static struct pci_error_handlers aer_error_handlers = {
.error_detected = aer_error_detected,
.resume = aer_error_resume,
@@ -69,14 +52,12 @@ static struct pci_error_handlers aer_error_handlers = {
static struct pcie_port_service_driver aerdriver = {
.name = "aer",
- .id_table = &aer_id[0],
+ .port_type = PCIE_ANY_PORT,
+ .service = PCIE_PORT_SERVICE_AER,
.probe = aer_probe,
.remove = aer_remove,
- .suspend = aer_suspend,
- .resume = aer_resume,
-
.err_handler = &aer_error_handlers,
.reset_link = aer_root_reset,
@@ -207,8 +188,7 @@ static void aer_remove(struct pcie_device *dev)
*
* Invoked when PCI Express bus loads AER service driver.
**/
-static int __devinit aer_probe (struct pcie_device *dev,
- const struct pcie_port_service_id *id )
+static int __devinit aer_probe (struct pcie_device *dev)
{
int status;
struct aer_rpc *rpc;
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index ebce26c37049..8edb2f300e8f 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -38,7 +38,7 @@ int aer_osc_setup(struct pcie_device *pciedev)
handle = acpi_find_root_bridge_handle(pdev);
if (handle) {
- status = pci_osc_control_set(handle,
+ status = acpi_pci_osc_control_set(handle,
OSC_PCI_EXPRESS_AER_CONTROL |
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
}
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 382575007382..307452f30035 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -351,21 +351,21 @@ static int find_aer_service_iter(struct device *device, void *data)
{
struct device_driver *driver;
struct pcie_port_service_driver *service_driver;
- struct pcie_device *pcie_dev;
struct find_aer_service_data *result;
result = (struct find_aer_service_data *) data;
if (device->bus == &pcie_port_bus_type) {
- pcie_dev = to_pcie_device(device);
- if (pcie_dev->id.port_type == PCIE_SW_DOWNSTREAM_PORT)
+ struct pcie_port_data *port_data;
+
+ port_data = pci_get_drvdata(to_pcie_device(device)->port);
+ if (port_data->port_type == PCIE_SW_DOWNSTREAM_PORT)
result->is_downstream = 1;
driver = device->driver;
if (driver) {
service_driver = to_service_driver(driver);
- if (service_driver->id_table->service_type ==
- PCIE_PORT_SERVICE_AER) {
+ if (service_driver->service == PCIE_PORT_SERVICE_AER) {
result->aer_driver = service_driver;
return 1;
}
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
index 2529f3f2ea5a..17ad53868f9f 100644
--- a/drivers/pci/pcie/portdrv.h
+++ b/drivers/pci/pcie/portdrv.h
@@ -25,19 +25,21 @@
#define PCIE_CAPABILITIES_REG 0x2
#define PCIE_SLOT_CAPABILITIES_REG 0x14
#define PCIE_PORT_DEVICE_MAXSERVICES 4
+#define PCIE_PORT_MSI_VECTOR_MASK 0x1f
+/*
+ * According to the PCI Express Base Specification 2.0, the indices of the MSI-X
+ * table entires used by port services must not exceed 31
+ */
+#define PCIE_PORT_MAX_MSIX_ENTRIES 32
#define get_descriptor_id(type, service) (((type - 4) << 4) | service)
-struct pcie_port_device_ext {
- int interrupt_mode; /* [0:INTx | 1:MSI | 2:MSI-X] */
-};
-
extern struct bus_type pcie_port_bus_type;
extern int pcie_port_device_probe(struct pci_dev *dev);
extern int pcie_port_device_register(struct pci_dev *dev);
#ifdef CONFIG_PM
-extern int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state);
-extern int pcie_port_device_resume(struct pci_dev *dev);
+extern int pcie_port_device_suspend(struct device *dev);
+extern int pcie_port_device_resume(struct device *dev);
#endif
extern void pcie_port_device_remove(struct pci_dev *dev);
extern int __must_check pcie_port_bus_register(void);
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
index eec89b767f9f..ef3a4eeaebb4 100644
--- a/drivers/pci/pcie/portdrv_bus.c
+++ b/drivers/pci/pcie/portdrv_bus.c
@@ -26,20 +26,22 @@ EXPORT_SYMBOL_GPL(pcie_port_bus_type);
static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
{
struct pcie_device *pciedev;
+ struct pcie_port_data *port_data;
struct pcie_port_service_driver *driver;
if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type)
return 0;
-
+
pciedev = to_pcie_device(dev);
driver = to_service_driver(drv);
- if ( (driver->id_table->vendor != PCI_ANY_ID &&
- driver->id_table->vendor != pciedev->id.vendor) ||
- (driver->id_table->device != PCI_ANY_ID &&
- driver->id_table->device != pciedev->id.device) ||
- (driver->id_table->port_type != PCIE_ANY_PORT &&
- driver->id_table->port_type != pciedev->id.port_type) ||
- driver->id_table->service_type != pciedev->id.service_type )
+
+ if (driver->service != pciedev->service)
+ return 0;
+
+ port_data = pci_get_drvdata(pciedev->port);
+
+ if (driver->port_type != PCIE_ANY_PORT
+ && driver->port_type != port_data->port_type)
return 0;
return 1;
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 8b3f8c18032f..e39982503863 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -15,10 +15,9 @@
#include <linux/slab.h>
#include <linux/pcieport_if.h>
+#include "../pci.h"
#include "portdrv.h"
-extern int pcie_mch_quirk; /* MSI-quirk Indicator */
-
/**
* release_pcie_device - free PCI Express port service device structure
* @dev: Port service device to release
@@ -31,26 +30,150 @@ static void release_pcie_device(struct device *dev)
kfree(to_pcie_device(dev));
}
-static int is_msi_quirked(struct pci_dev *dev)
+/**
+ * pcie_port_msix_add_entry - add entry to given array of MSI-X entries
+ * @entries: Array of MSI-X entries
+ * @new_entry: Index of the entry to add to the array
+ * @nr_entries: Number of entries aleady in the array
+ *
+ * Return value: Position of the added entry in the array
+ */
+static int pcie_port_msix_add_entry(
+ struct msix_entry *entries, int new_entry, int nr_entries)
{
- int port_type, quirk = 0;
+ int j;
+
+ for (j = 0; j < nr_entries; j++)
+ if (entries[j].entry == new_entry)
+ return j;
+
+ entries[j].entry = new_entry;
+ return j;
+}
+
+/**
+ * pcie_port_enable_msix - try to set up MSI-X as interrupt mode for given port
+ * @dev: PCI Express port to handle
+ * @vectors: Array of interrupt vectors to populate
+ * @mask: Bitmask of port capabilities returned by get_port_device_capability()
+ *
+ * Return value: 0 on success, error code on failure
+ */
+static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask)
+{
+ struct msix_entry *msix_entries;
+ int idx[PCIE_PORT_DEVICE_MAXSERVICES];
+ int nr_entries, status, pos, i, nvec;
u16 reg16;
+ u32 reg32;
- pci_read_config_word(dev,
- pci_find_capability(dev, PCI_CAP_ID_EXP) +
- PCIE_CAPABILITIES_REG, &reg16);
- port_type = (reg16 >> 4) & PORT_TYPE_MASK;
- switch(port_type) {
- case PCIE_RC_PORT:
- if (pcie_mch_quirk == 1)
- quirk = 1;
- break;
- case PCIE_SW_UPSTREAM_PORT:
- case PCIE_SW_DOWNSTREAM_PORT:
- default:
- break;
+ nr_entries = pci_msix_table_size(dev);
+ if (!nr_entries)
+ return -EINVAL;
+ if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES)
+ nr_entries = PCIE_PORT_MAX_MSIX_ENTRIES;
+
+ msix_entries = kzalloc(sizeof(*msix_entries) * nr_entries, GFP_KERNEL);
+ if (!msix_entries)
+ return -ENOMEM;
+
+ /*
+ * Allocate as many entries as the port wants, so that we can check
+ * which of them will be useful. Moreover, if nr_entries is correctly
+ * equal to the number of entries this port actually uses, we'll happily
+ * go through without any tricks.
+ */
+ for (i = 0; i < nr_entries; i++)
+ msix_entries[i].entry = i;
+
+ status = pci_enable_msix(dev, msix_entries, nr_entries);
+ if (status)
+ goto Exit;
+
+ for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
+ idx[i] = -1;
+ status = -EIO;
+ nvec = 0;
+
+ if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP)) {
+ int entry;
+
+ /*
+ * The code below follows the PCI Express Base Specification 2.0
+ * stating in Section 6.1.6 that "PME and Hot-Plug Event
+ * interrupts (when both are implemented) always share the same
+ * MSI or MSI-X vector, as indicated by the Interrupt Message
+ * Number field in the PCI Express Capabilities register", where
+ * according to Section 7.8.2 of the specification "For MSI-X,
+ * the value in this field indicates which MSI-X Table entry is
+ * used to generate the interrupt message."
+ */
+ pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+ pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);
+ entry = (reg16 >> 9) & PCIE_PORT_MSI_VECTOR_MASK;
+ if (entry >= nr_entries)
+ goto Error;
+
+ i = pcie_port_msix_add_entry(msix_entries, entry, nvec);
+ if (i == nvec)
+ nvec++;
+
+ idx[PCIE_PORT_SERVICE_PME_SHIFT] = i;
+ idx[PCIE_PORT_SERVICE_HP_SHIFT] = i;
+ }
+
+ if (mask & PCIE_PORT_SERVICE_AER) {
+ int entry;
+
+ /*
+ * The code below follows Section 7.10.10 of the PCI Express
+ * Base Specification 2.0 stating that bits 31-27 of the Root
+ * Error Status Register contain a value indicating which of the
+ * MSI/MSI-X vectors assigned to the port is going to be used
+ * for AER, where "For MSI-X, the value in this register
+ * indicates which MSI-X Table entry is used to generate the
+ * interrupt message."
+ */
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+ pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &reg32);
+ entry = reg32 >> 27;
+ if (entry >= nr_entries)
+ goto Error;
+
+ i = pcie_port_msix_add_entry(msix_entries, entry, nvec);
+ if (i == nvec)
+ nvec++;
+
+ idx[PCIE_PORT_SERVICE_AER_SHIFT] = i;
}
- return quirk;
+
+ /*
+ * If nvec is equal to the allocated number of entries, we can just use
+ * what we have. Otherwise, the port has some extra entries not for the
+ * services we know and we need to work around that.
+ */
+ if (nvec == nr_entries) {
+ status = 0;
+ } else {
+ /* Drop the temporary MSI-X setup */
+ pci_disable_msix(dev);
+
+ /* Now allocate the MSI-X vectors for real */
+ status = pci_enable_msix(dev, msix_entries, nvec);
+ if (status)
+ goto Exit;
+ }
+
+ for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
+ vectors[i] = idx[i] >= 0 ? msix_entries[idx[i]].vector : -1;
+
+ Exit:
+ kfree(msix_entries);
+ return status;
+
+ Error:
+ pci_disable_msix(dev);
+ goto Exit;
}
/**
@@ -64,47 +187,32 @@ static int is_msi_quirked(struct pci_dev *dev)
*/
static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
{
- int i, pos, nvec, status = -EINVAL;
- int interrupt_mode = PCIE_PORT_INTx_MODE;
+ struct pcie_port_data *port_data = pci_get_drvdata(dev);
+ int irq, interrupt_mode = PCIE_PORT_NO_IRQ;
+ int i;
- /* Set INTx as default */
- for (i = 0, nvec = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
- if (mask & (1 << i))
- nvec++;
- vectors[i] = dev->irq;
- }
-
/* Check MSI quirk */
- if (is_msi_quirked(dev))
- return interrupt_mode;
-
- /* Select MSI-X over MSI if supported */
- pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
- if (pos) {
- struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] =
- {{0, 0}, {0, 1}, {0, 2}, {0, 3}};
- status = pci_enable_msix(dev, msix_entries, nvec);
- if (!status) {
- int j = 0;
-
- interrupt_mode = PCIE_PORT_MSIX_MODE;
- for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
- if (mask & (1 << i))
- vectors[i] = msix_entries[j++].vector;
- }
- }
- }
- if (status) {
- pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
- if (pos) {
- status = pci_enable_msi(dev);
- if (!status) {
- interrupt_mode = PCIE_PORT_MSI_MODE;
- for (i = 0;i < PCIE_PORT_DEVICE_MAXSERVICES;i++)
- vectors[i] = dev->irq;
- }
- }
- }
+ if (port_data->port_type == PCIE_RC_PORT && pcie_mch_quirk)
+ goto Fallback;
+
+ /* Try to use MSI-X if supported */
+ if (!pcie_port_enable_msix(dev, vectors, mask))
+ return PCIE_PORT_MSIX_MODE;
+
+ /* We're not going to use MSI-X, so try MSI and fall back to INTx */
+ if (!pci_enable_msi(dev))
+ interrupt_mode = PCIE_PORT_MSI_MODE;
+
+ Fallback:
+ if (interrupt_mode == PCIE_PORT_NO_IRQ && dev->pin)
+ interrupt_mode = PCIE_PORT_INTx_MODE;
+
+ irq = interrupt_mode != PCIE_PORT_NO_IRQ ? dev->irq : -1;
+ for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
+ vectors[i] = irq;
+
+ vectors[PCIE_PORT_SERVICE_VC_SHIFT] = -1;
+
return interrupt_mode;
}
@@ -132,13 +240,11 @@ static int get_port_device_capability(struct pci_dev *dev)
pos + PCIE_SLOT_CAPABILITIES_REG, &reg32);
if (reg32 & SLOT_HP_CAPABLE_MASK)
services |= PCIE_PORT_SERVICE_HP;
- }
- /* PME Capable - root port capability */
- if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT)
- services |= PCIE_PORT_SERVICE_PME;
-
+ }
+ /* AER capable */
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
services |= PCIE_PORT_SERVICE_AER;
+ /* VC support */
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
services |= PCIE_PORT_SERVICE_VC;
@@ -152,20 +258,17 @@ static int get_port_device_capability(struct pci_dev *dev)
* @port_type: Type of the port
* @service_type: Type of service to associate with the service device
* @irq: Interrupt vector to associate with the service device
- * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
*/
static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
- int port_type, int service_type, int irq, int irq_mode)
+ int service_type, int irq)
{
+ struct pcie_port_data *port_data = pci_get_drvdata(parent);
struct device *device;
+ int port_type = port_data->port_type;
dev->port = parent;
- dev->interrupt_mode = irq_mode;
dev->irq = irq;
- dev->id.vendor = parent->vendor;
- dev->id.device = parent->device;
- dev->id.port_type = port_type;
- dev->id.service_type = (1 << service_type);
+ dev->service = service_type;
/* Initialize generic device interface */
device = &dev->device;
@@ -185,10 +288,9 @@ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
* @port_type: Type of the port
* @service_type: Type of service to associate with the service device
* @irq: Interrupt vector to associate with the service device
- * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
*/
static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
- int port_type, int service_type, int irq, int irq_mode)
+ int service_type, int irq)
{
struct pcie_device *device;
@@ -196,7 +298,7 @@ static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
if (!device)
return NULL;
- pcie_device_init(parent, device, port_type, service_type, irq,irq_mode);
+ pcie_device_init(parent, device, service_type, irq);
return device;
}
@@ -230,63 +332,90 @@ int pcie_port_device_probe(struct pci_dev *dev)
*/
int pcie_port_device_register(struct pci_dev *dev)
{
- struct pcie_port_device_ext *p_ext;
- int status, type, capabilities, irq_mode, i;
+ struct pcie_port_data *port_data;
+ int status, capabilities, irq_mode, i, nr_serv;
int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
u16 reg16;
- /* Allocate port device extension */
- if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL)))
+ port_data = kzalloc(sizeof(*port_data), GFP_KERNEL);
+ if (!port_data)
return -ENOMEM;
-
- pci_set_drvdata(dev, p_ext);
+ pci_set_drvdata(dev, port_data);
/* Get port type */
pci_read_config_word(dev,
pci_find_capability(dev, PCI_CAP_ID_EXP) +
PCIE_CAPABILITIES_REG, &reg16);
- type = (reg16 >> 4) & PORT_TYPE_MASK;
+ port_data->port_type = (reg16 >> 4) & PORT_TYPE_MASK;
- /* Now get port services */
capabilities = get_port_device_capability(dev);
+ /* Root ports are capable of generating PME too */
+ if (port_data->port_type == PCIE_RC_PORT)
+ capabilities |= PCIE_PORT_SERVICE_PME;
+
irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
- p_ext->interrupt_mode = irq_mode;
+ if (irq_mode == PCIE_PORT_NO_IRQ) {
+ /*
+ * Don't use service devices that require interrupts if there is
+ * no way to generate them.
+ */
+ if (!(capabilities & PCIE_PORT_SERVICE_VC)) {
+ status = -ENODEV;
+ goto Error;
+ }
+ capabilities = PCIE_PORT_SERVICE_VC;
+ }
+ port_data->port_irq_mode = irq_mode;
+
+ status = pci_enable_device(dev);
+ if (status)
+ goto Error;
+ pci_set_master(dev);
/* Allocate child services if any */
- for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
+ for (i = 0, nr_serv = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
struct pcie_device *child;
+ int service = 1 << i;
+
+ if (!(capabilities & service))
+ continue;
- if (capabilities & (1 << i)) {
- child = alloc_pcie_device(
- dev, /* parent */
- type, /* port type */
- i, /* service type */
- vectors[i], /* irq */
- irq_mode /* interrupt mode */);
- if (child) {
- status = device_register(&child->device);
- if (status) {
- kfree(child);
- continue;
- }
- get_device(&child->device);
- }
+ child = alloc_pcie_device(dev, service, vectors[i]);
+ if (!child)
+ continue;
+
+ status = device_register(&child->device);
+ if (status) {
+ kfree(child);
+ continue;
}
+
+ get_device(&child->device);
+ nr_serv++;
+ }
+ if (!nr_serv) {
+ pci_disable_device(dev);
+ status = -ENODEV;
+ goto Error;
}
+
return 0;
+
+ Error:
+ kfree(port_data);
+ return status;
}
#ifdef CONFIG_PM
static int suspend_iter(struct device *dev, void *data)
{
struct pcie_port_service_driver *service_driver;
- pm_message_t state = * (pm_message_t *) data;
if ((dev->bus == &pcie_port_bus_type) &&
(dev->driver)) {
service_driver = to_service_driver(dev->driver);
if (service_driver->suspend)
- service_driver->suspend(to_pcie_device(dev), state);
+ service_driver->suspend(to_pcie_device(dev));
}
return 0;
}
@@ -294,11 +423,10 @@ static int suspend_iter(struct device *dev, void *data)
/**
* pcie_port_device_suspend - suspend port services associated with a PCIe port
* @dev: PCI Express port to handle
- * @state: Representation of system power management transition in progress
*/
-int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state)
+int pcie_port_device_suspend(struct device *dev)
{
- return device_for_each_child(&dev->dev, &state, suspend_iter);
+ return device_for_each_child(dev, NULL, suspend_iter);
}
static int resume_iter(struct device *dev, void *data)
@@ -318,24 +446,17 @@ static int resume_iter(struct device *dev, void *data)
* pcie_port_device_suspend - resume port services associated with a PCIe port
* @dev: PCI Express port to handle
*/
-int pcie_port_device_resume(struct pci_dev *dev)
+int pcie_port_device_resume(struct device *dev)
{
- return device_for_each_child(&dev->dev, NULL, resume_iter);
+ return device_for_each_child(dev, NULL, resume_iter);
}
-#endif
+#endif /* PM */
static int remove_iter(struct device *dev, void *data)
{
- struct pcie_port_service_driver *service_driver;
-
if (dev->bus == &pcie_port_bus_type) {
- if (dev->driver) {
- service_driver = to_service_driver(dev->driver);
- if (service_driver->remove)
- service_driver->remove(to_pcie_device(dev));
- }
- *(unsigned long*)data = (unsigned long)dev;
- return 1;
+ put_device(dev);
+ device_unregister(dev);
}
return 0;
}
@@ -349,25 +470,21 @@ static int remove_iter(struct device *dev, void *data)
*/
void pcie_port_device_remove(struct pci_dev *dev)
{
- struct device *device;
- unsigned long device_addr;
- int interrupt_mode = PCIE_PORT_INTx_MODE;
- int status;
+ struct pcie_port_data *port_data = pci_get_drvdata(dev);
- do {
- status = device_for_each_child(&dev->dev, &device_addr, remove_iter);
- if (status) {
- device = (struct device*)device_addr;
- interrupt_mode = (to_pcie_device(device))->interrupt_mode;
- put_device(device);
- device_unregister(device);
- }
- } while (status);
- /* Switch to INTx by default if MSI enabled */
- if (interrupt_mode == PCIE_PORT_MSIX_MODE)
+ device_for_each_child(&dev->dev, NULL, remove_iter);
+ pci_disable_device(dev);
+
+ switch (port_data->port_irq_mode) {
+ case PCIE_PORT_MSIX_MODE:
pci_disable_msix(dev);
- else if (interrupt_mode == PCIE_PORT_MSI_MODE)
+ break;
+ case PCIE_PORT_MSI_MODE:
pci_disable_msi(dev);
+ break;
+ }
+
+ kfree(port_data);
}
/**
@@ -392,7 +509,7 @@ static int pcie_port_probe_service(struct device *dev)
return -ENODEV;
pciedev = to_pcie_device(dev);
- status = driver->probe(pciedev, driver->id_table);
+ status = driver->probe(pciedev);
if (!status) {
dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n",
driver->name);
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 5ea566e20b37..b924e2463f85 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -32,11 +32,6 @@ MODULE_LICENSE("GPL");
/* global data */
static const char device_name[] = "pcieport-driver";
-static int pcie_portdrv_save_config(struct pci_dev *dev)
-{
- return pci_save_state(dev);
-}
-
static int pcie_portdrv_restore_config(struct pci_dev *dev)
{
int retval;
@@ -49,21 +44,21 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev)
}
#ifdef CONFIG_PM
-static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state)
-{
- return pcie_port_device_suspend(dev, state);
+static struct dev_pm_ops pcie_portdrv_pm_ops = {
+ .suspend = pcie_port_device_suspend,
+ .resume = pcie_port_device_resume,
+ .freeze = pcie_port_device_suspend,
+ .thaw = pcie_port_device_resume,
+ .poweroff = pcie_port_device_suspend,
+ .restore = pcie_port_device_resume,
+};
-}
+#define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops)
-static int pcie_portdrv_resume(struct pci_dev *dev)
-{
- pci_set_master(dev);
- return pcie_port_device_resume(dev);
-}
-#else
-#define pcie_portdrv_suspend NULL
-#define pcie_portdrv_resume NULL
-#endif
+#else /* !PM */
+
+#define PCIE_PORTDRV_PM_OPS NULL
+#endif /* !PM */
/*
* pcie_portdrv_probe - Probe PCI-Express port devices
@@ -82,20 +77,15 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
if (status)
return status;
- if (pci_enable_device(dev) < 0)
- return -ENODEV;
-
- pci_set_master(dev);
if (!dev->irq && dev->pin) {
dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; "
"check vendor BIOS\n", dev->vendor, dev->device);
}
- if (pcie_port_device_register(dev)) {
- pci_disable_device(dev);
- return -ENOMEM;
- }
+ status = pcie_port_device_register(dev);
+ if (status)
+ return status;
- pcie_portdrv_save_config(dev);
+ pci_save_state(dev);
return 0;
}
@@ -104,7 +94,6 @@ static void pcie_portdrv_remove (struct pci_dev *dev)
{
pcie_port_device_remove(dev);
pci_disable_device(dev);
- kfree(pci_get_drvdata(dev));
}
static int error_detected_iter(struct device *device, void *data)
@@ -278,10 +267,9 @@ static struct pci_driver pcie_portdriver = {
.probe = pcie_portdrv_probe,
.remove = pcie_portdrv_remove,
- .suspend = pcie_portdrv_suspend,
- .resume = pcie_portdrv_resume,
-
.err_handler = &pcie_portdrv_err_handler,
+
+ .driver.pm = PCIE_PORTDRV_PM_OPS,
};
static int __init pcie_portdrv_init(void)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 55ec44a27e89..e2f3dd098cfa 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -287,7 +287,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
struct resource *res;
int i;
- if (!dev) /* It's a host bus, nothing to read */
+ if (!child->parent) /* It's a host bus, nothing to read */
return;
if (dev->transparent) {
@@ -511,21 +511,21 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
/*
* If we already got to this bus through a different bridge,
- * ignore it. This can happen with the i450NX chipset.
+ * don't re-add it. This can happen with the i450NX chipset.
+ *
+ * However, we continue to descend down the hierarchy and
+ * scan remaining child buses.
*/
- if (pci_find_bus(pci_domain_nr(bus), busnr)) {
- dev_info(&dev->dev, "bus %04x:%02x already known\n",
- pci_domain_nr(bus), busnr);
- goto out;
+ child = pci_find_bus(pci_domain_nr(bus), busnr);
+ if (!child) {
+ child = pci_add_new_bus(bus, dev, busnr);
+ if (!child)
+ goto out;
+ child->primary = buses & 0xFF;
+ child->subordinate = (buses >> 16) & 0xFF;
+ child->bridge_ctl = bctl;
}
- child = pci_add_new_bus(bus, dev, busnr);
- if (!child)
- goto out;
- child->primary = buses & 0xFF;
- child->subordinate = (buses >> 16) & 0xFF;
- child->bridge_ctl = bctl;
-
cmax = pci_scan_child_bus(child);
if (cmax > max)
max = cmax;
@@ -674,6 +674,19 @@ static void pci_read_irq(struct pci_dev *dev)
dev->irq = irq;
}
+static void set_pcie_port_type(struct pci_dev *pdev)
+{
+ int pos;
+ u16 reg16;
+
+ pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+ if (!pos)
+ return;
+ pdev->is_pcie = 1;
+ pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
+ pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
+}
+
#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
/**
@@ -683,12 +696,33 @@ static void pci_read_irq(struct pci_dev *dev)
* Initialize the device structure with information about the device's
* vendor,class,memory and IO-space addresses,IRQ lines etc.
* Called at initialisation of the PCI subsystem and by CardBus services.
- * Returns 0 on success and -1 if unknown type of device (not normal, bridge
- * or CardBus).
+ * Returns 0 on success and negative if unknown type of device (not normal,
+ * bridge or CardBus).
*/
-static int pci_setup_device(struct pci_dev * dev)
+int pci_setup_device(struct pci_dev *dev)
{
u32 class;
+ u8 hdr_type;
+ struct pci_slot *slot;
+
+ if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
+ return -EIO;
+
+ dev->sysdata = dev->bus->sysdata;
+ dev->dev.parent = dev->bus->bridge;
+ dev->dev.bus = &pci_bus_type;
+ dev->hdr_type = hdr_type & 0x7f;
+ dev->multifunction = !!(hdr_type & 0x80);
+ dev->error_state = pci_channel_io_normal;
+ set_pcie_port_type(dev);
+
+ list_for_each_entry(slot, &dev->bus->slots, list)
+ if (PCI_SLOT(dev->devfn) == slot->number)
+ dev->slot = slot;
+
+ /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
+ set this higher, assuming the system even supports it. */
+ dev->dma_mask = 0xffffffff;
dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
dev->bus->number, PCI_SLOT(dev->devfn),
@@ -703,12 +737,14 @@ static int pci_setup_device(struct pci_dev * dev)
dev_dbg(&dev->dev, "found [%04x:%04x] class %06x header type %02x\n",
dev->vendor, dev->device, class, dev->hdr_type);
+ /* need to have dev->class ready */
+ dev->cfg_size = pci_cfg_space_size(dev);
+
/* "Unknown power state" */
dev->current_state = PCI_UNKNOWN;
/* Early fixups, before probing the BARs */
pci_fixup_device(pci_fixup_early, dev);
- class = dev->class >> 8;
switch (dev->hdr_type) { /* header type */
case PCI_HEADER_TYPE_NORMAL: /* standard header */
@@ -770,7 +806,7 @@ static int pci_setup_device(struct pci_dev * dev)
default: /* unknown header */
dev_err(&dev->dev, "unknown header type %02x, "
"ignoring device\n", dev->hdr_type);
- return -1;
+ return -EIO;
bad:
dev_err(&dev->dev, "ignoring class %02x (doesn't match header "
@@ -785,6 +821,7 @@ static int pci_setup_device(struct pci_dev * dev)
static void pci_release_capabilities(struct pci_dev *dev)
{
pci_vpd_release(dev);
+ pci_iov_release(dev);
}
/**
@@ -803,19 +840,6 @@ static void pci_release_dev(struct device *dev)
kfree(pci_dev);
}
-static void set_pcie_port_type(struct pci_dev *pdev)
-{
- int pos;
- u16 reg16;
-
- pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- if (!pos)
- return;
- pdev->is_pcie = 1;
- pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
- pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
-}
-
/**
* pci_cfg_space_size - get the configuration space size of the PCI device.
* @dev: PCI device
@@ -847,6 +871,11 @@ int pci_cfg_space_size(struct pci_dev *dev)
{
int pos;
u32 status;
+ u16 class;
+
+ class = dev->class >> 8;
+ if (class == PCI_CLASS_BRIDGE_HOST)
+ return pci_cfg_space_size_ext(dev);
pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (!pos) {
@@ -891,9 +920,7 @@ EXPORT_SYMBOL(alloc_pci_dev);
static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
{
struct pci_dev *dev;
- struct pci_slot *slot;
u32 l;
- u8 hdr_type;
int delay = 1;
if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
@@ -920,34 +947,16 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
}
}
- if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type))
- return NULL;
-
dev = alloc_pci_dev();
if (!dev)
return NULL;
dev->bus = bus;
- dev->sysdata = bus->sysdata;
- dev->dev.parent = bus->bridge;
- dev->dev.bus = &pci_bus_type;
dev->devfn = devfn;
- dev->hdr_type = hdr_type & 0x7f;
- dev->multifunction = !!(hdr_type & 0x80);
dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff;
- dev->cfg_size = pci_cfg_space_size(dev);
- dev->error_state = pci_channel_io_normal;
- set_pcie_port_type(dev);
-
- list_for_each_entry(slot, &bus->slots, list)
- if (PCI_SLOT(devfn) == slot->number)
- dev->slot = slot;
- /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
- set this higher, assuming the system even supports it. */
- dev->dma_mask = 0xffffffff;
- if (pci_setup_device(dev) < 0) {
+ if (pci_setup_device(dev)) {
kfree(dev);
return NULL;
}
@@ -972,6 +981,9 @@ static void pci_init_capabilities(struct pci_dev *dev)
/* Alternative Routing-ID Forwarding */
pci_enable_ari(dev);
+
+ /* Single Root I/O Virtualization */
+ pci_iov_init(dev);
}
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
@@ -1006,6 +1018,12 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
{
struct pci_dev *dev;
+ dev = pci_get_slot(bus, devfn);
+ if (dev) {
+ pci_dev_put(dev);
+ return dev;
+ }
+
dev = pci_scan_device(bus, devfn);
if (!dev)
return NULL;
@@ -1024,35 +1042,27 @@ EXPORT_SYMBOL(pci_scan_single_device);
* Scan a PCI slot on the specified PCI bus for devices, adding
* discovered devices to the @bus->devices list. New devices
* will not have is_added set.
+ *
+ * Returns the number of new devices found.
*/
int pci_scan_slot(struct pci_bus *bus, int devfn)
{
- int func, nr = 0;
- int scan_all_fns;
-
- scan_all_fns = pcibios_scan_all_fns(bus, devfn);
-
- for (func = 0; func < 8; func++, devfn++) {
- struct pci_dev *dev;
-
- dev = pci_scan_single_device(bus, devfn);
- if (dev) {
- nr++;
+ int fn, nr = 0;
+ struct pci_dev *dev;
- /*
- * If this is a single function device,
- * don't scan past the first function.
- */
- if (!dev->multifunction) {
- if (func > 0) {
- dev->multifunction = 1;
- } else {
- break;
- }
+ dev = pci_scan_single_device(bus, devfn);
+ if (dev && !dev->is_added) /* new device? */
+ nr++;
+
+ if ((dev && dev->multifunction) ||
+ (!dev && pcibios_scan_all_fns(bus, devfn))) {
+ for (fn = 1; fn < 8; fn++) {
+ dev = pci_scan_single_device(bus, devfn + fn);
+ if (dev) {
+ if (!dev->is_added)
+ nr++;
+ dev->multifunction = 1;
}
- } else {
- if (func == 0 && !scan_all_fns)
- break;
}
}
@@ -1074,12 +1084,21 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
for (devfn = 0; devfn < 0x100; devfn += 8)
pci_scan_slot(bus, devfn);
+ /* Reserve buses for SR-IOV capability. */
+ max += pci_iov_bus_range(bus);
+
/*
* After performing arch-dependent fixup of the bus, look behind
* all PCI-to-PCI bridges on this bus.
*/
- pr_debug("PCI: Fixups for bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
- pcibios_fixup_bus(bus);
+ if (!bus->is_added) {
+ pr_debug("PCI: Fixups for bus %04x:%02x\n",
+ pci_domain_nr(bus), bus->number);
+ pcibios_fixup_bus(bus);
+ if (pci_is_root_bus(bus))
+ bus->is_added = 1;
+ }
+
for (pass=0; pass < 2; pass++)
list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
@@ -1114,7 +1133,7 @@ struct pci_bus * pci_create_bus(struct device *parent,
if (!b)
return NULL;
- dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev){
kfree(b);
return NULL;
@@ -1133,7 +1152,6 @@ struct pci_bus * pci_create_bus(struct device *parent,
list_add_tail(&b->node, &pci_root_buses);
up_write(&pci_bus_sem);
- memset(dev, 0, sizeof(*dev));
dev->parent = parent;
dev->release = pci_release_bus_bridge_dev;
dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus);
@@ -1193,6 +1211,38 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
EXPORT_SYMBOL(pci_scan_bus_parented);
#ifdef CONFIG_HOTPLUG
+/**
+ * pci_rescan_bus - scan a PCI bus for devices.
+ * @bus: PCI bus to scan
+ *
+ * Scan a PCI bus and child buses for new devices, adds them,
+ * and enables them.
+ *
+ * Returns the max number of subordinate bus discovered.
+ */
+unsigned int __devinit pci_rescan_bus(struct pci_bus *bus)
+{
+ unsigned int max;
+ struct pci_dev *dev;
+
+ max = pci_scan_child_bus(bus);
+
+ down_read(&pci_bus_sem);
+ list_for_each_entry(dev, &bus->devices, bus_list)
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+ dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+ if (dev->subordinate)
+ pci_bus_size_bridges(dev->subordinate);
+ up_read(&pci_bus_sem);
+
+ pci_bus_assign_resources(bus);
+ pci_enable_bridges(bus);
+ pci_bus_add_devices(bus);
+
+ return max;
+}
+EXPORT_SYMBOL_GPL(pci_rescan_bus);
+
EXPORT_SYMBOL(pci_add_new_bus);
EXPORT_SYMBOL(pci_scan_slot);
EXPORT_SYMBOL(pci_scan_bridge);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 92b9efe9bcaf..9b2f0d96900d 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -24,6 +24,7 @@
#include <linux/kallsyms.h>
#include <linux/dmi.h>
#include <linux/pci-aspm.h>
+#include <linux/ioport.h>
#include "pci.h"
int isa_dma_bridge_buggy;
@@ -34,6 +35,65 @@ int pcie_mch_quirk;
EXPORT_SYMBOL(pcie_mch_quirk);
#ifdef CONFIG_PCI_QUIRKS
+/*
+ * This quirk function disables the device and releases resources
+ * which is specified by kernel's boot parameter 'pci=resource_alignment='.
+ * It also rounds up size to specified alignment.
+ * Later on, the kernel will assign page-aligned memory resource back
+ * to that device.
+ */
+static void __devinit quirk_resource_alignment(struct pci_dev *dev)
+{
+ int i;
+ struct resource *r;
+ resource_size_t align, size;
+
+ if (!pci_is_reassigndev(dev))
+ return;
+
+ if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
+ dev_warn(&dev->dev,
+ "Can't reassign resources to host bridge.\n");
+ return;
+ }
+
+ dev_info(&dev->dev, "Disabling device and release resources.\n");
+ pci_disable_device(dev);
+
+ align = pci_specified_resource_alignment(dev);
+ for (i=0; i < PCI_BRIDGE_RESOURCES; i++) {
+ r = &dev->resource[i];
+ if (!(r->flags & IORESOURCE_MEM))
+ continue;
+ size = resource_size(r);
+ if (size < align) {
+ size = align;
+ dev_info(&dev->dev,
+ "Rounding up size of resource #%d to %#llx.\n",
+ i, (unsigned long long)size);
+ }
+ r->end = size - 1;
+ r->start = 0;
+ }
+ /* Need to disable bridge's resource window,
+ * to enable the kernel to reassign new resource
+ * window later on.
+ */
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+ for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
+ r = &dev->resource[i];
+ if (!(r->flags & IORESOURCE_MEM))
+ continue;
+ r->end = resource_size(r) - 1;
+ r->start = 0;
+ }
+ pci_disable_bridge_window(dev);
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment);
+
/* The Mellanox Tavor device gives false positive parity errors
* Mark this device with a broken_parity_status, to allow
* PCI scanning code to "skip" this now blacklisted device.
@@ -1126,10 +1186,15 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
* its on-board VGA controller */
asus_hides_smbus = 1;
}
- else if (dev->device == PCI_DEVICE_ID_INTEL_82845G_IG)
+ else if (dev->device == PCI_DEVICE_ID_INTEL_82801DB_2)
switch(dev->subsystem_device) {
case 0x00b8: /* Compaq Evo D510 CMT */
case 0x00b9: /* Compaq Evo D510 SFF */
+ /* Motherboard doesn't have Host bridge
+ * subvendor/subdevice IDs and on-board VGA
+ * controller is disabled if an AGP card is
+ * inserted, therefore checking USB UHCI
+ * Controller #1 */
asus_hides_smbus = 1;
}
else if (dev->device == PCI_DEVICE_ID_INTEL_82815_CGC)
@@ -1154,7 +1219,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, as
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3, asus_hides_smbus_hostbridge);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG, asus_hides_smbus_hostbridge);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_2, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC, asus_hides_smbus_hostbridge);
static void asus_hides_smbus_lpc(struct pci_dev *dev)
@@ -1664,9 +1729,13 @@ static void __devinit quirk_netmos(struct pci_dev *dev)
* of parallel ports and <S> is the number of serial ports.
*/
switch (dev->device) {
+ case PCI_DEVICE_ID_NETMOS_9835:
+ /* Well, this rule doesn't hold for the following 9835 device */
+ if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
+ dev->subsystem_device == 0x0299)
+ return;
case PCI_DEVICE_ID_NETMOS_9735:
case PCI_DEVICE_ID_NETMOS_9745:
- case PCI_DEVICE_ID_NETMOS_9835:
case PCI_DEVICE_ID_NETMOS_9845:
case PCI_DEVICE_ID_NETMOS_9855:
if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_SERIAL &&
@@ -2078,6 +2147,92 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA,
PCI_DEVICE_ID_NVIDIA_NVENET_15,
nvenet_msi_disable);
+static int __devinit ht_check_msi_mapping(struct pci_dev *dev)
+{
+ int pos, ttl = 48;
+ int found = 0;
+
+ /* check if there is HT MSI cap or enabled on this device */
+ pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
+ while (pos && ttl--) {
+ u8 flags;
+
+ if (found < 1)
+ found = 1;
+ if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
+ &flags) == 0) {
+ if (flags & HT_MSI_FLAGS_ENABLE) {
+ if (found < 2) {
+ found = 2;
+ break;
+ }
+ }
+ }
+ pos = pci_find_next_ht_capability(dev, pos,
+ HT_CAPTYPE_MSI_MAPPING);
+ }
+
+ return found;
+}
+
+static int __devinit host_bridge_with_leaf(struct pci_dev *host_bridge)
+{
+ struct pci_dev *dev;
+ int pos;
+ int i, dev_no;
+ int found = 0;
+
+ dev_no = host_bridge->devfn >> 3;
+ for (i = dev_no + 1; i < 0x20; i++) {
+ dev = pci_get_slot(host_bridge->bus, PCI_DEVFN(i, 0));
+ if (!dev)
+ continue;
+
+ /* found next host bridge ?*/
+ pos = pci_find_ht_capability(dev, HT_CAPTYPE_SLAVE);
+ if (pos != 0) {
+ pci_dev_put(dev);
+ break;
+ }
+
+ if (ht_check_msi_mapping(dev)) {
+ found = 1;
+ pci_dev_put(dev);
+ break;
+ }
+ pci_dev_put(dev);
+ }
+
+ return found;
+}
+
+#define PCI_HT_CAP_SLAVE_CTRL0 4 /* link control */
+#define PCI_HT_CAP_SLAVE_CTRL1 8 /* link control to */
+
+static int __devinit is_end_of_ht_chain(struct pci_dev *dev)
+{
+ int pos, ctrl_off;
+ int end = 0;
+ u16 flags, ctrl;
+
+ pos = pci_find_ht_capability(dev, HT_CAPTYPE_SLAVE);
+
+ if (!pos)
+ goto out;
+
+ pci_read_config_word(dev, pos + PCI_CAP_FLAGS, &flags);
+
+ ctrl_off = ((flags >> 10) & 1) ?
+ PCI_HT_CAP_SLAVE_CTRL0 : PCI_HT_CAP_SLAVE_CTRL1;
+ pci_read_config_word(dev, pos + ctrl_off, &ctrl);
+
+ if (ctrl & (1 << 6))
+ end = 1;
+
+out:
+ return end;
+}
+
static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev)
{
struct pci_dev *host_bridge;
@@ -2102,6 +2257,11 @@ static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev)
if (!found)
return;
+ /* don't enable end_device/host_bridge with leaf directly here */
+ if (host_bridge == dev && is_end_of_ht_chain(host_bridge) &&
+ host_bridge_with_leaf(host_bridge))
+ goto out;
+
/* root did that ! */
if (msi_ht_cap_enabled(host_bridge))
goto out;
@@ -2132,44 +2292,12 @@ static void __devinit ht_disable_msi_mapping(struct pci_dev *dev)
}
}
-static int __devinit ht_check_msi_mapping(struct pci_dev *dev)
-{
- int pos, ttl = 48;
- int found = 0;
-
- /* check if there is HT MSI cap or enabled on this device */
- pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
- while (pos && ttl--) {
- u8 flags;
-
- if (found < 1)
- found = 1;
- if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
- &flags) == 0) {
- if (flags & HT_MSI_FLAGS_ENABLE) {
- if (found < 2) {
- found = 2;
- break;
- }
- }
- }
- pos = pci_find_next_ht_capability(dev, pos,
- HT_CAPTYPE_MSI_MAPPING);
- }
-
- return found;
-}
-
-static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
+static void __devinit __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all)
{
struct pci_dev *host_bridge;
int pos;
int found;
- /* Enabling HT MSI mapping on this device breaks MCP51 */
- if (dev->device == 0x270)
- return;
-
/* check if there is HT MSI cap or enabled on this device */
found = ht_check_msi_mapping(dev);
@@ -2193,7 +2321,10 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
/* Host bridge is to HT */
if (found == 1) {
/* it is not enabled, try to enable it */
- nv_ht_enable_msi_mapping(dev);
+ if (all)
+ ht_enable_msi_mapping(dev);
+ else
+ nv_ht_enable_msi_mapping(dev);
}
return;
}
@@ -2205,8 +2336,20 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
/* Host bridge is not to HT, disable HT MSI mapping on this device */
ht_disable_msi_mapping(dev);
}
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk);
+
+static void __devinit nv_msi_ht_cap_quirk_all(struct pci_dev *dev)
+{
+ return __nv_msi_ht_cap_quirk(dev, 1);
+}
+
+static void __devinit nv_msi_ht_cap_quirk_leaf(struct pci_dev *dev)
+{
+ return __nv_msi_ht_cap_quirk(dev, 0);
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk_leaf);
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk_all);
static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
{
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 042e08924421..86503c14ce7e 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -71,6 +71,9 @@ void pci_remove_bus(struct pci_bus *pci_bus)
down_write(&pci_bus_sem);
list_del(&pci_bus->node);
up_write(&pci_bus_sem);
+ if (!pci_bus->is_added)
+ return;
+
pci_remove_legacy_files(pci_bus);
device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity);
device_remove_file(&pci_bus->dev, &dev_attr_cpulistaffinity);
@@ -92,6 +95,7 @@ EXPORT_SYMBOL(pci_remove_bus);
*/
void pci_remove_bus_device(struct pci_dev *dev)
{
+ pci_stop_bus_device(dev);
if (dev->subordinate) {
struct pci_bus *b = dev->subordinate;
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 5af8bd538149..710d4ea69568 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -29,7 +29,7 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
if (pdev->is_pcie)
return NULL;
while (1) {
- if (!pdev->bus->self)
+ if (!pdev->bus->parent)
break;
pdev = pdev->bus->self;
/* a p2p bridge */
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 704608945780..334285a8e237 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -27,7 +27,7 @@
#include <linux/slab.h>
-static void pbus_assign_resources_sorted(struct pci_bus *bus)
+static void pbus_assign_resources_sorted(const struct pci_bus *bus)
{
struct pci_dev *dev;
struct resource *res;
@@ -144,6 +144,9 @@ static void pci_setup_bridge(struct pci_bus *bus)
struct pci_bus_region region;
u32 l, bu, lu, io_upper16;
+ if (!pci_is_root_bus(bus) && bus->is_added)
+ return;
+
dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n",
pci_domain_nr(bus), bus->number);
@@ -495,7 +498,7 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
}
EXPORT_SYMBOL(pci_bus_size_bridges);
-void __ref pci_bus_assign_resources(struct pci_bus *bus)
+void __ref pci_bus_assign_resources(const struct pci_bus *bus)
{
struct pci_bus *b;
struct pci_dev *dev;
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 32e8d88a4619..3039fcb86afc 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -120,6 +120,21 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
return err;
}
+#ifdef CONFIG_PCI_QUIRKS
+void pci_disable_bridge_window(struct pci_dev *dev)
+{
+ dev_dbg(&dev->dev, "Disabling bridge window.\n");
+
+ /* MMIO Base/Limit */
+ pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);
+
+ /* Prefetchable MMIO Base/Limit */
+ pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
+ pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0);
+ pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff);
+}
+#endif /* CONFIG_PCI_QUIRKS */
+
int pci_assign_resource(struct pci_dev *dev, int resno)
{
struct pci_bus *bus = dev->bus;
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index 5a8ccb4f604d..21189447e545 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -1,8 +1,8 @@
/*
* drivers/pci/slot.c
* Copyright (C) 2006 Matthew Wilcox <matthew@wil.cx>
- * Copyright (C) 2006-2008 Hewlett-Packard Development Company, L.P.
- * Alex Chiang <achiang@hp.com>
+ * Copyright (C) 2006-2009 Hewlett-Packard Development Company, L.P.
+ * Alex Chiang <achiang@hp.com>
*/
#include <linux/kobject.h>
@@ -52,8 +52,8 @@ static void pci_slot_release(struct kobject *kobj)
struct pci_dev *dev;
struct pci_slot *slot = to_pci_slot(kobj);
- pr_debug("%s: releasing pci_slot on %x:%d\n", __func__,
- slot->bus->number, slot->number);
+ dev_dbg(&slot->bus->dev, "dev %02x, released physical slot %s\n",
+ slot->number, pci_slot_name(slot));
list_for_each_entry(dev, &slot->bus->devices, bus_list)
if (PCI_SLOT(dev->devfn) == slot->number)
@@ -248,9 +248,8 @@ placeholder:
if (PCI_SLOT(dev->devfn) == slot_nr)
dev->slot = slot;
- /* Don't care if debug printk has a -1 for slot_nr */
- pr_debug("%s: created pci_slot on %04x:%02x:%02x\n",
- __func__, pci_domain_nr(parent), parent->number, slot_nr);
+ dev_dbg(&parent->dev, "dev %02x, created physical slot %s\n",
+ slot_nr, pci_slot_name(slot));
out:
kfree(slot_name);
@@ -299,9 +298,8 @@ EXPORT_SYMBOL_GPL(pci_renumber_slot);
*/
void pci_destroy_slot(struct pci_slot *slot)
{
- pr_debug("%s: dec refcount to %d on %04x:%02x:%02x\n", __func__,
- atomic_read(&slot->kobj.kref.refcount) - 1,
- pci_domain_nr(slot->bus), slot->bus->number, slot->number);
+ dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n",
+ slot->number, atomic_read(&slot->kobj.kref.refcount) - 1);
down_write(&pci_bus_sem);
kobject_put(&slot->kobj);
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index fc1de46fd20a..90013341cd5f 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -468,13 +468,13 @@ out:
return ret;
}
-int au1x00_drv_pcmcia_remove(struct device *dev)
+int au1x00_drv_pcmcia_remove(struct platform_device *dev)
{
- struct skt_dev_info *sinfo = dev_get_drvdata(dev);
+ struct skt_dev_info *sinfo = platform_get_drvdata(dev);
int i;
mutex_lock(&pcmcia_sockets_lock);
- dev_set_drvdata(dev, NULL);
+ platform_set_drvdata(dev, NULL);
for (i = 0; i < sinfo->nskt; i++) {
struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
@@ -498,13 +498,13 @@ int au1x00_drv_pcmcia_remove(struct device *dev)
* PCMCIA "Driver" API
*/
-static int au1x00_drv_pcmcia_probe(struct device *dev)
+static int au1x00_drv_pcmcia_probe(struct platform_device *dev)
{
int i, ret = -ENODEV;
mutex_lock(&pcmcia_sockets_lock);
for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) {
- ret = au1x00_pcmcia_hw_init[i](dev);
+ ret = au1x00_pcmcia_hw_init[i](&dev->dev);
if (ret == 0)
break;
}
@@ -512,14 +512,26 @@ static int au1x00_drv_pcmcia_probe(struct device *dev)
return ret;
}
+static int au1x00_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int au1x00_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
-static struct device_driver au1x00_pcmcia_driver = {
+static struct platform_driver au1x00_pcmcia_driver = {
+ .driver = {
+ .name = "au1x00-pcmcia",
+ .owner = THIS_MODULE,
+ },
.probe = au1x00_drv_pcmcia_probe,
.remove = au1x00_drv_pcmcia_remove,
- .name = "au1x00-pcmcia",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+ .suspend = au1x00_drv_pcmcia_suspend,
+ .resume = au1x00_drv_pcmcia_resume,
};
@@ -533,8 +545,7 @@ static struct device_driver au1x00_pcmcia_driver = {
static int __init au1x00_pcmcia_init(void)
{
int error = 0;
- if ((error = driver_register(&au1x00_pcmcia_driver)))
- return error;
+ error = platform_driver_register(&au1x00_pcmcia_driver);
return error;
}
@@ -544,7 +555,7 @@ static int __init au1x00_pcmcia_init(void)
*/
static void __exit au1x00_pcmcia_exit(void)
{
- driver_unregister(&au1x00_pcmcia_driver);
+ platform_driver_unregister(&au1x00_pcmcia_driver);
}
module_init(au1x00_pcmcia_init);
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 71653ab84890..40d4953e4b12 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1238,6 +1238,16 @@ static int pcic_init(struct pcmcia_socket *s)
return 0;
}
+static int i82365_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int i82365_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
static struct pccard_operations pcic_operations = {
.init = pcic_init,
.get_status = pcic_get_status,
@@ -1248,11 +1258,13 @@ static struct pccard_operations pcic_operations = {
/*====================================================================*/
-static struct device_driver i82365_driver = {
- .name = "i82365",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver i82365_driver = {
+ .driver = {
+ .name = "i82365",
+ .owner = THIS_MODULE,
+ },
+ .suspend = i82365_drv_pcmcia_suspend,
+ .resume = i82365_drv_pcmcia_resume,
};
static struct platform_device *i82365_device;
@@ -1261,7 +1273,7 @@ static int __init init_i82365(void)
{
int i, ret;
- ret = driver_register(&i82365_driver);
+ ret = platform_driver_register(&i82365_driver);
if (ret)
goto err_out;
@@ -1337,7 +1349,7 @@ err_dev_unregister:
pnp_disable_dev(i82365_pnpdev);
#endif
err_driver_unregister:
- driver_unregister(&i82365_driver);
+ platform_driver_unregister(&i82365_driver);
err_out:
return ret;
} /* init_i82365 */
@@ -1365,7 +1377,7 @@ static void __exit exit_i82365(void)
if (i82365_pnpdev)
pnp_disable_dev(i82365_pnpdev);
#endif
- driver_unregister(&i82365_driver);
+ platform_driver_unregister(&i82365_driver);
} /* exit_i82365 */
module_init(init_i82365);
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 2ab4f22c21de..62b4ecc97c46 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -696,13 +696,25 @@ static struct pccard_operations pcc_operations = {
.set_mem_map = pcc_set_mem_map,
};
+static int cfc_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int cfc_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
/*====================================================================*/
-static struct device_driver pcc_driver = {
- .name = "cfc",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver pcc_driver = {
+ .driver = {
+ .name = "cfc",
+ .owner = THIS_MODULE,
+ },
+ .suspend = cfc_drv_pcmcia_suspend,
+ .resume = cfc_drv_pcmcia_resume,
};
static struct platform_device pcc_device = {
@@ -716,13 +728,13 @@ static int __init init_m32r_pcc(void)
{
int i, ret;
- ret = driver_register(&pcc_driver);
+ ret = platform_driver_register(&pcc_driver);
if (ret)
return ret;
ret = platform_device_register(&pcc_device);
if (ret){
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return ret;
}
@@ -754,7 +766,7 @@ static int __init init_m32r_pcc(void)
if (pcc_sockets == 0) {
printk("socket is not found.\n");
platform_device_unregister(&pcc_device);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return -ENODEV;
}
@@ -802,7 +814,7 @@ static void __exit exit_m32r_pcc(void)
if (poll_interval != 0)
del_timer_sync(&poll_timer);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
} /* exit_m32r_pcc */
module_init(init_m32r_pcc);
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 2f108c23dbd9..12034b41d196 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -672,13 +672,25 @@ static struct pccard_operations pcc_operations = {
.set_mem_map = pcc_set_mem_map,
};
+static int pcc_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int pcc_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
/*====================================================================*/
-static struct device_driver pcc_driver = {
- .name = "pcc",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver pcc_driver = {
+ .driver = {
+ .name = "pcc",
+ .owner = THIS_MODULE,
+ },
+ .suspend = pcc_drv_pcmcia_suspend,
+ .resume = pcc_drv_pcmcia_resume,
};
static struct platform_device pcc_device = {
@@ -692,13 +704,13 @@ static int __init init_m32r_pcc(void)
{
int i, ret;
- ret = driver_register(&pcc_driver);
+ ret = platform_driver_register(&pcc_driver);
if (ret)
return ret;
ret = platform_device_register(&pcc_device);
if (ret){
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return ret;
}
@@ -715,7 +727,7 @@ static int __init init_m32r_pcc(void)
if (pcc_sockets == 0) {
printk("socket is not found.\n");
platform_device_unregister(&pcc_device);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
return -ENODEV;
}
@@ -763,7 +775,7 @@ static void __exit exit_m32r_pcc(void)
if (poll_interval != 0)
del_timer_sync(&poll_timer);
- driver_unregister(&pcc_driver);
+ platform_driver_unregister(&pcc_driver);
} /* exit_m32r_pcc */
module_init(init_m32r_pcc);
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index bb9ddb9532e3..c49a7269f6d1 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -28,7 +28,6 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
-#include <mach/pxa-regs.h>
#include <mach/pxa2xx-regs.h>
#include <asm/mach-types.h>
@@ -39,6 +38,44 @@
#include "soc_common.h"
#include "pxa2xx_base.h"
+/*
+ * Personal Computer Memory Card International Association (PCMCIA) sockets
+ */
+
+#define PCMCIAPrtSp 0x04000000 /* PCMCIA Partition Space [byte] */
+#define PCMCIASp (4*PCMCIAPrtSp) /* PCMCIA Space [byte] */
+#define PCMCIAIOSp PCMCIAPrtSp /* PCMCIA I/O Space [byte] */
+#define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */
+#define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */
+
+#define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */
+#define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */
+#define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */
+#define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */
+
+#define PCMCIA1Sp PCMCIASp /* PCMCIA 1 Space [byte] */
+#define PCMCIA1IOSp PCMCIAIOSp /* PCMCIA 1 I/O Space [byte] */
+#define PCMCIA1AttrSp PCMCIAAttrSp /* PCMCIA 1 Attribute Space [byte] */
+#define PCMCIA1MemSp PCMCIAMemSp /* PCMCIA 1 Memory Space [byte] */
+
+#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \
+ (0x20000000 + (Nb) * PCMCIASp)
+#define _PCMCIAIO(Nb) _PCMCIA(Nb) /* PCMCIA I/O [0..1] */
+#define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \
+ (_PCMCIA(Nb) + 2 * PCMCIAPrtSp)
+#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \
+ (_PCMCIA(Nb) + 3 * PCMCIAPrtSp)
+
+#define _PCMCIA0 _PCMCIA(0) /* PCMCIA 0 */
+#define _PCMCIA0IO _PCMCIAIO(0) /* PCMCIA 0 I/O */
+#define _PCMCIA0Attr _PCMCIAAttr(0) /* PCMCIA 0 Attribute */
+#define _PCMCIA0Mem _PCMCIAMem(0) /* PCMCIA 0 Memory */
+
+#define _PCMCIA1 _PCMCIA(1) /* PCMCIA 1 */
+#define _PCMCIA1IO _PCMCIAIO(1) /* PCMCIA 1 I/O */
+#define _PCMCIA1Attr _PCMCIAAttr(1) /* PCMCIA 1 Attribute */
+#define _PCMCIA1Mem _PCMCIAMem(1) /* PCMCIA 1 Memory */
+
#define MCXX_SETUP_MASK (0x7f)
#define MCXX_ASST_MASK (0x1f)
@@ -177,29 +214,73 @@ static void pxa2xx_configure_sockets(struct device *dev)
MECR |= MECR_CIT;
/* Set MECR:NOS (Number Of Sockets) */
- if (ops->nr > 1 || machine_is_viper())
+ if ((ops->first + ops->nr) > 1 || machine_is_viper())
MECR |= MECR_NOS;
else
MECR &= ~MECR_NOS;
}
+static const char *skt_names[] = {
+ "PCMCIA socket 0",
+ "PCMCIA socket 1",
+};
+
+#define SKT_DEV_INFO_SIZE(n) \
+ (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
+
int __pxa2xx_drv_pcmcia_probe(struct device *dev)
{
- int ret;
+ int i, ret;
struct pcmcia_low_level *ops;
+ struct skt_dev_info *sinfo;
+ struct soc_pcmcia_socket *skt;
if (!dev || !dev->platform_data)
return -ENODEV;
ops = (struct pcmcia_low_level *)dev->platform_data;
+ sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL);
+ if (!sinfo)
+ return -ENOMEM;
+
+ sinfo->nskt = ops->nr;
+
+ /* Initialize processor specific parameters */
+ for (i = 0; i < ops->nr; i++) {
+ skt = &sinfo->skt[i];
+
+ skt->nr = ops->first + i;
+ skt->irq = NO_IRQ;
+
+ skt->res_skt.start = _PCMCIA(skt->nr);
+ skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
+ skt->res_skt.name = skt_names[skt->nr];
+ skt->res_skt.flags = IORESOURCE_MEM;
+
+ skt->res_io.start = _PCMCIAIO(skt->nr);
+ skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
+ skt->res_io.name = "io";
+ skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+ skt->res_mem.start = _PCMCIAMem(skt->nr);
+ skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
+ skt->res_mem.name = "memory";
+ skt->res_mem.flags = IORESOURCE_MEM;
+
+ skt->res_attr.start = _PCMCIAAttr(skt->nr);
+ skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
+ skt->res_attr.name = "attribute";
+ skt->res_attr.flags = IORESOURCE_MEM;
+ }
+
/* Provide our PXA2xx specific timing routines. */
ops->set_timing = pxa2xx_pcmcia_set_timing;
#ifdef CONFIG_CPU_FREQ
ops->frequency_change = pxa2xx_pcmcia_frequency_change;
#endif
- ret = soc_common_drv_pcmcia_probe(dev, ops, ops->first, ops->nr);
+ ret = soc_common_drv_pcmcia_probe(dev, ops, sinfo);
if (!ret)
pxa2xx_configure_sockets(dev);
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c
index 7c8bcb476622..5143a760153b 100644
--- a/drivers/pcmcia/pxa2xx_cm_x255.c
+++ b/drivers/pcmcia/pxa2xx_cm_x255.c
@@ -16,7 +16,6 @@
#include <linux/gpio.h>
#include <asm/mach-types.h>
-#include <mach/pxa-regs.h>
#include "soc_common.h"
@@ -64,7 +63,7 @@ static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
- int rdy = skt->nr ? GPIO_PCMCIA_S0_RDYINT : GPIO_PCMCIA_S1_RDYINT;
+ int rdy = skt->nr ? GPIO_PCMCIA_S1_RDYINT : GPIO_PCMCIA_S0_RDYINT;
state->detect = !gpio_get_value(cd);
state->ready = !!gpio_get_value(rdy);
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c
index 6c3aac377126..a7b943d01e34 100644
--- a/drivers/pcmcia/pxa2xx_cm_x270.c
+++ b/drivers/pcmcia/pxa2xx_cm_x270.c
@@ -16,7 +16,6 @@
#include <linux/gpio.h>
#include <asm/mach-types.h>
-#include <mach/pxa-regs.h>
#include "soc_common.h"
diff --git a/drivers/pcmcia/pxa2xx_e740.c b/drivers/pcmcia/pxa2xx_e740.c
index f663a011bf4a..d09c0dc4a31a 100644
--- a/drivers/pcmcia/pxa2xx_e740.c
+++ b/drivers/pcmcia/pxa2xx_e740.c
@@ -16,8 +16,6 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
#include <mach/eseries-gpio.h>
#include <asm/irq.h>
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c
index 37ec55df086e..6cbb1b1f7cfd 100644
--- a/drivers/pcmcia/pxa2xx_lubbock.c
+++ b/drivers/pcmcia/pxa2xx_lubbock.c
@@ -24,7 +24,6 @@
#include <mach/hardware.h>
#include <asm/hardware/sa1111.h>
#include <asm/mach-types.h>
-#include <mach/pxa-regs.h>
#include <mach/lubbock.h>
#include "sa1111_generic.h"
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 877001db4916..1138551ba8f6 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -21,11 +21,10 @@
#include <pcmcia/ss.h>
-#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa2xx-regs.h>
#include <mach/mainstone.h>
#include "soc_common.h"
diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c
index 1736c67e547e..5ba9b3664a00 100644
--- a/drivers/pcmcia/pxa2xx_palmld.c
+++ b/drivers/pcmcia/pxa2xx_palmld.c
@@ -98,8 +98,8 @@ static void palmld_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
static struct pcmcia_low_level palmld_pcmcia_ops = {
.owner = THIS_MODULE,
- .first = 0,
- .nr = 2,
+ .first = 1,
+ .nr = 1,
.hw_init = palmld_pcmcia_hw_init,
.hw_shutdown = palmld_pcmcia_hw_shutdown,
diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c
index 36c7a0b324d2..e0e5cb339b4a 100644
--- a/drivers/pcmcia/pxa2xx_trizeps4.c
+++ b/drivers/pcmcia/pxa2xx_trizeps4.c
@@ -22,8 +22,7 @@
#include <asm/mach-types.h>
#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
+#include <mach/pxa2xx-regs.h>
#include <mach/trizeps4.h>
#include "soc_common.h"
diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c
index dd10481be7bf..17871360fe99 100644
--- a/drivers/pcmcia/pxa2xx_viper.c
+++ b/drivers/pcmcia/pxa2xx_viper.c
@@ -26,7 +26,6 @@
#include <asm/irq.h>
-#include <mach/pxa-regs.h>
#include <mach/viper.h>
#include <asm/mach-types.h>
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index c0e2afc79e3e..e592e0e0d7ed 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -153,7 +153,7 @@ static struct resource *iodyn_find_io_region(unsigned long base, int num,
unsigned long align, struct pcmcia_socket *s)
{
struct resource *res = make_resource(0, num, IORESOURCE_IO,
- s->dev.bus_id);
+ dev_name(&s->dev));
struct pcmcia_align_data data;
unsigned long min = base;
int ret;
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index c5b2a44b4c37..d8da5ac844e9 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -65,7 +65,7 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
#endif
};
-static int sa11x0_drv_pcmcia_probe(struct device *dev)
+static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
{
int i, ret = -ENODEV;
@@ -73,7 +73,7 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev)
* Initialise any "on-board" PCMCIA sockets.
*/
for (i = 0; i < ARRAY_SIZE(sa11x0_pcmcia_hw_init); i++) {
- ret = sa11x0_pcmcia_hw_init[i](dev);
+ ret = sa11x0_pcmcia_hw_init[i](&dev->dev);
if (ret == 0)
break;
}
@@ -81,13 +81,31 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev)
return ret;
}
-static struct device_driver sa11x0_pcmcia_driver = {
+static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
+{
+ return soc_common_drv_pcmcia_remove(&dev->dev);
+}
+
+static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int sa11x0_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
+
+static struct platform_driver sa11x0_pcmcia_driver = {
+ .driver = {
+ .name = "sa11x0-pcmcia",
+ .owner = THIS_MODULE,
+ },
.probe = sa11x0_drv_pcmcia_probe,
- .remove = soc_common_drv_pcmcia_remove,
- .name = "sa11x0-pcmcia",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+ .remove = sa11x0_drv_pcmcia_remove,
+ .suspend = sa11x0_drv_pcmcia_suspend,
+ .resume = sa11x0_drv_pcmcia_resume,
};
/* sa11x0_pcmcia_init()
@@ -100,7 +118,7 @@ static struct device_driver sa11x0_pcmcia_driver = {
*/
static int __init sa11x0_pcmcia_init(void)
{
- return driver_register(&sa11x0_pcmcia_driver);
+ return platform_driver_register(&sa11x0_pcmcia_driver);
}
/* sa11x0_pcmcia_exit()
@@ -110,7 +128,7 @@ static int __init sa11x0_pcmcia_init(void)
*/
static void __exit sa11x0_pcmcia_exit(void)
{
- driver_unregister(&sa11x0_pcmcia_driver);
+ platform_driver_unregister(&sa11x0_pcmcia_driver);
}
MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
diff --git a/drivers/pcmcia/sa1100_h3600.c b/drivers/pcmcia/sa1100_h3600.c
index 6de4e1b41d60..0cc3748f3758 100644
--- a/drivers/pcmcia/sa1100_h3600.c
+++ b/drivers/pcmcia/sa1100_h3600.c
@@ -37,9 +37,9 @@ static void h3600_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
/* Disable CF bus: */
- clr_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
- clr_h3600_egpio(IPAQ_EGPIO_OPT_ON);
- set_h3600_egpio(IPAQ_EGPIO_OPT_RESET);
+ assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 0);
+ assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 0);
+ assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 1);
}
static void
@@ -79,10 +79,7 @@ h3600_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_
return -1;
}
- if (state->flags & SS_RESET)
- set_h3600_egpio(IPAQ_EGPIO_CARD_RESET);
- else
- clr_h3600_egpio(IPAQ_EGPIO_CARD_RESET);
+ assign_h3600_egpio(IPAQ_EGPIO_CARD_RESET, !!(state->flags & SS_RESET));
/* Silently ignore Vpp, output enable, speaker enable. */
@@ -92,9 +89,9 @@ h3600_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_
static void h3600_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
{
/* Enable CF bus: */
- set_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
- set_h3600_egpio(IPAQ_EGPIO_OPT_ON);
- clr_h3600_egpio(IPAQ_EGPIO_OPT_RESET);
+ assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 1);
+ assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 1);
+ assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 0);
msleep(10);
@@ -112,10 +109,10 @@ static void h3600_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
* socket 0 then socket 1.
*/
if (skt->nr == 1) {
- clr_h3600_egpio(IPAQ_EGPIO_OPT_ON);
- clr_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON);
+ assign_h3600_egpio(IPAQ_EGPIO_OPT_ON, 0);
+ assign_h3600_egpio(IPAQ_EGPIO_OPT_NVRAM_ON, 0);
/* hmm, does this suck power? */
- set_h3600_egpio(IPAQ_EGPIO_OPT_RESET);
+ assign_h3600_egpio(IPAQ_EGPIO_OPT_RESET, 1);
}
}
diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c
index 6924d0ea8d32..401052a21ce8 100644
--- a/drivers/pcmcia/sa1111_generic.c
+++ b/drivers/pcmcia/sa1111_generic.c
@@ -11,12 +11,12 @@
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/init.h>
+#include <linux/io.h>
#include <pcmcia/ss.h>
#include <mach/hardware.h>
#include <asm/hardware/sa1111.h>
-#include <asm/io.h>
#include <asm/irq.h>
#include "sa1111_generic.h"
diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c
index 7cb1273202cc..e15d59f2d8a9 100644
--- a/drivers/pcmcia/sa11xx_base.c
+++ b/drivers/pcmcia/sa11xx_base.c
@@ -36,9 +36,9 @@
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
+#include <linux/io.h>
#include <mach/hardware.h>
-#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
@@ -163,9 +163,55 @@ sa1100_pcmcia_show_timing(struct soc_pcmcia_socket *skt, char *buf)
return p - buf;
}
+static const char *skt_names[] = {
+ "PCMCIA socket 0",
+ "PCMCIA socket 1",
+};
+
+#define SKT_DEV_INFO_SIZE(n) \
+ (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
+
int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
int first, int nr)
{
+ struct skt_dev_info *sinfo;
+ struct soc_pcmcia_socket *skt;
+ int i;
+
+ sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
+ if (!sinfo)
+ return -ENOMEM;
+
+ sinfo->nskt = nr;
+
+ /* Initiliaze processor specific parameters */
+ for (i = 0; i < nr; i++) {
+ skt = &sinfo->skt[i];
+
+ skt->nr = first + i;
+ skt->irq = NO_IRQ;
+
+ skt->res_skt.start = _PCMCIA(skt->nr);
+ skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
+ skt->res_skt.name = skt_names[skt->nr];
+ skt->res_skt.flags = IORESOURCE_MEM;
+
+ skt->res_io.start = _PCMCIAIO(skt->nr);
+ skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
+ skt->res_io.name = "io";
+ skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+ skt->res_mem.start = _PCMCIAMem(skt->nr);
+ skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
+ skt->res_mem.name = "memory";
+ skt->res_mem.flags = IORESOURCE_MEM;
+
+ skt->res_attr.start = _PCMCIAAttr(skt->nr);
+ skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
+ skt->res_attr.name = "attribute";
+ skt->res_attr.flags = IORESOURCE_MEM;
+ }
+
/*
* set default MECR calculation if the board specific
* code did not specify one...
@@ -180,7 +226,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
ops->frequency_change = sa1100_pcmcia_frequency_change;
#endif
- return soc_common_drv_pcmcia_probe(dev, ops, first, nr);
+ return soc_common_drv_pcmcia_probe(dev, ops, sinfo);
}
EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index f49ac6666153..163cf98e2386 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -49,11 +49,6 @@
#include "soc_common.h"
-/* FIXME: platform dependent resource declaration has to move out of this file */
-#ifdef CONFIG_ARCH_PXA
-#include <mach/pxa-regs.h>
-#endif
-
#ifdef CONFIG_PCMCIA_DEBUG
static int pc_debug;
@@ -581,19 +576,6 @@ EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
LIST_HEAD(soc_pcmcia_sockets);
static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
-static const char *skt_names[] = {
- "PCMCIA socket 0",
- "PCMCIA socket 1",
-};
-
-struct skt_dev_info {
- int nskt;
- struct soc_pcmcia_socket skt[0];
-};
-
-#define SKT_DEV_INFO_SIZE(n) \
- (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
-
#ifdef CONFIG_CPU_FREQ
static int
soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
@@ -637,26 +619,18 @@ static int soc_pcmcia_cpufreq_register(void) { return 0; }
static void soc_pcmcia_cpufreq_unregister(void) {}
#endif
-int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
+int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
+ struct skt_dev_info *sinfo)
{
- struct skt_dev_info *sinfo;
struct soc_pcmcia_socket *skt;
int ret, i;
mutex_lock(&soc_pcmcia_sockets_lock);
- sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
- if (!sinfo) {
- ret = -ENOMEM;
- goto out;
- }
-
- sinfo->nskt = nr;
-
/*
* Initialise the per-socket structure.
*/
- for (i = 0; i < nr; i++) {
+ for (i = 0; i < sinfo->nskt; i++) {
skt = &sinfo->skt[i];
skt->socket.ops = &soc_common_pcmcia_operations;
@@ -668,43 +642,21 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
skt->poll_timer.data = (unsigned long)skt;
skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
- skt->nr = first + i;
- skt->irq = NO_IRQ;
skt->dev = dev;
skt->ops = ops;
- skt->res_skt.start = _PCMCIA(skt->nr);
- skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
- skt->res_skt.name = skt_names[skt->nr];
- skt->res_skt.flags = IORESOURCE_MEM;
-
ret = request_resource(&iomem_resource, &skt->res_skt);
if (ret)
goto out_err_1;
- skt->res_io.start = _PCMCIAIO(skt->nr);
- skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
- skt->res_io.name = "io";
- skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-
ret = request_resource(&skt->res_skt, &skt->res_io);
if (ret)
goto out_err_2;
- skt->res_mem.start = _PCMCIAMem(skt->nr);
- skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
- skt->res_mem.name = "memory";
- skt->res_mem.flags = IORESOURCE_MEM;
-
ret = request_resource(&skt->res_skt, &skt->res_mem);
if (ret)
goto out_err_3;
- skt->res_attr.start = _PCMCIAAttr(skt->nr);
- skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
- skt->res_attr.name = "attribute";
- skt->res_attr.flags = IORESOURCE_MEM;
-
ret = request_resource(&skt->res_skt, &skt->res_attr);
if (ret)
goto out_err_4;
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
index 38c67375f363..290e143839ee 100644
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -58,6 +58,11 @@ struct soc_pcmcia_socket {
struct list_head node;
};
+struct skt_dev_info {
+ int nskt;
+ struct soc_pcmcia_socket skt[0];
+};
+
struct pcmcia_state {
unsigned detect: 1,
ready: 1,
@@ -132,7 +137,7 @@ extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_
extern struct list_head soc_pcmcia_sockets;
-extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr);
+extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, struct skt_dev_info *sinfo);
extern int soc_common_drv_pcmcia_remove(struct device *dev);
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index 2a613e920fd4..9ad97ea836e8 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -363,13 +363,25 @@ static int __init get_tcic_id(void)
return id;
}
+static int tcic_drv_pcmcia_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int tcic_drv_pcmcia_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
/*====================================================================*/
-static struct device_driver tcic_driver = {
- .name = "tcic-pcmcia",
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static struct platform_driver tcic_driver = {
+ .driver = {
+ .name = "tcic-pcmcia",
+ .owner = THIS_MODULE,
+ },
+ .suspend = tcic_drv_pcmcia_suspend,
+ .resume = tcic_drv_pcmcia_resume,
};
static struct platform_device tcic_device = {
@@ -383,7 +395,7 @@ static int __init init_tcic(void)
int i, sock, ret = 0;
u_int mask, scan;
- if (driver_register(&tcic_driver))
+ if (platform_driver_register(&tcic_driver))
return -1;
printk(KERN_INFO "Databook TCIC-2 PCMCIA probe: ");
@@ -391,7 +403,7 @@ static int __init init_tcic(void)
if (!request_region(tcic_base, 16, "tcic-2")) {
printk("could not allocate ports,\n ");
- driver_unregister(&tcic_driver);
+ platform_driver_unregister(&tcic_driver);
return -ENODEV;
}
else {
@@ -414,7 +426,7 @@ static int __init init_tcic(void)
if (sock == 0) {
printk("not found.\n");
release_region(tcic_base, 16);
- driver_unregister(&tcic_driver);
+ platform_driver_unregister(&tcic_driver);
return -ENODEV;
}
@@ -542,7 +554,7 @@ static void __exit exit_tcic(void)
}
platform_device_unregister(&tcic_device);
- driver_unregister(&tcic_driver);
+ platform_driver_unregister(&tcic_driver);
} /* exit_tcic */
/*====================================================================*/
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index b2c412419059..659421d0ca46 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -704,24 +704,37 @@ static int __devinit vrc4171_card_setup(char *options)
__setup("vrc4171_card=", vrc4171_card_setup);
-static struct device_driver vrc4171_card_driver = {
- .name = vrc4171_card_name,
- .bus = &platform_bus_type,
- .suspend = pcmcia_socket_dev_suspend,
- .resume = pcmcia_socket_dev_resume,
+static int vrc4171_card_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int vrc4171_card_resume(struct platform_device *dev)
+{
+ return pcmcia_socket_dev_resume(&dev->dev);
+}
+
+static struct platform_driver vrc4171_card_driver = {
+ .driver = {
+ .name = vrc4171_card_name,
+ .owner = THIS_MODULE,
+ },
+ .suspend = vrc4171_card_suspend,
+ .resume = vrc4171_card_resume,
};
static int __devinit vrc4171_card_init(void)
{
int retval;
- retval = driver_register(&vrc4171_card_driver);
+ retval = platform_driver_register(&vrc4171_card_driver);
if (retval < 0)
return retval;
retval = platform_device_register(&vrc4171_card_device);
if (retval < 0) {
- driver_unregister(&vrc4171_card_driver);
+ platform_driver_unregister(&vrc4171_card_driver);
return retval;
}
@@ -735,11 +748,12 @@ static int __devinit vrc4171_card_init(void)
if (retval < 0) {
vrc4171_remove_sockets();
platform_device_unregister(&vrc4171_card_device);
- driver_unregister(&vrc4171_card_driver);
+ platform_driver_unregister(&vrc4171_card_driver);
return retval;
}
- printk(KERN_INFO "%s, connected to IRQ %d\n", vrc4171_card_driver.name, vrc4171_irq);
+ printk(KERN_INFO "%s, connected to IRQ %d\n",
+ vrc4171_card_driver.driver.name, vrc4171_irq);
return 0;
}
@@ -749,7 +763,7 @@ static void __devexit vrc4171_card_exit(void)
free_irq(vrc4171_irq, vrc4171_sockets);
vrc4171_remove_sockets();
platform_device_unregister(&vrc4171_card_device);
- driver_unregister(&vrc4171_card_driver);
+ platform_driver_unregister(&vrc4171_card_driver);
}
module_init(vrc4171_card_init);
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 3608081bc3e0..284ebaca6e45 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -67,6 +67,16 @@ config DELL_LAPTOP
This driver adds support for rfkill and backlight control to Dell
laptops.
+config DELL_WMI
+ tristate "Dell WMI extras"
+ depends on ACPI_WMI
+ depends on INPUT
+ ---help---
+ Say Y here if you want to support WMI-based hotkeys on Dell laptops.
+
+ To compile this driver as a module, choose M here: the module will
+ be called dell-wmi.
+
config FUJITSU_LAPTOP
tristate "Fujitsu Laptop Extras"
depends on ACPI
@@ -165,6 +175,7 @@ config SONY_LAPTOP
depends on ACPI
select BACKLIGHT_CLASS_DEVICE
depends on INPUT
+ depends on RFKILL
---help---
This mini-driver drives the SNC and SPIC devices present in the ACPI
BIOS of the Sony Vaio laptops.
@@ -226,6 +237,30 @@ config THINKPAD_ACPI_DEBUG
If you are not sure, say N here.
+config THINKPAD_ACPI_UNSAFE_LEDS
+ bool "Allow control of important LEDs (unsafe)"
+ depends on THINKPAD_ACPI
+ default n
+ ---help---
+ Overriding LED state on ThinkPads can mask important
+ firmware alerts (like critical battery condition), or misled
+ the user into damaging the hardware (undocking or ejecting
+ the bay while buses are still active), etc.
+
+ LED control on the ThinkPad is write-only (with very few
+ exceptions on very ancient models), which makes it
+ impossible to know beforehand if important information will
+ be lost when one changes LED state.
+
+ Users that know what they are doing can enable this option
+ and the driver will allow control of every LED, including
+ the ones on the dock stations.
+
+ Never enable this option on a distribution kernel.
+
+ Say N here, unless you are building a kernel for your own
+ use, and need to control the important firmware LEDs.
+
config THINKPAD_ACPI_DOCK
bool "Legacy Docking Station Support"
depends on THINKPAD_ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index e29065120be9..e40c7bd1b87e 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
+obj-$(CONFIG_DELL_WMI) += dell-wmi.o
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
obj-$(CONFIG_HP_WMI) += hp-wmi.o
obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index a6a42e8c060b..0f6e43bf4fc2 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -1,7 +1,7 @@
/*
* Acer WMI Laptop Extras
*
- * Copyright (C) 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
+ * Copyright (C) 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk>
*
* Based on acer_acpi:
* Copyright (C) 2005-2007 E.M. Smith
@@ -225,6 +225,25 @@ static struct quirk_entry quirk_fujitsu_amilo_li_1718 = {
.wireless = 2,
};
+/* The Aspire One has a dummy ACPI-WMI interface - disable it */
+static struct dmi_system_id __devinitdata acer_blacklist[] = {
+ {
+ .ident = "Acer Aspire One (SSD)",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
+ },
+ },
+ {
+ .ident = "Acer Aspire One (HDD)",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
+ },
+ },
+ {}
+};
+
static struct dmi_system_id acer_quirks[] = {
{
.callback = dmi_matched,
@@ -1117,11 +1136,17 @@ static int __devinit acer_platform_probe(struct platform_device *device)
}
err = acer_rfkill_init(&device->dev);
+ if (err)
+ goto error_rfkill;
return err;
+error_rfkill:
+ if (has_cap(ACER_CAP_BRIGHTNESS))
+ acer_backlight_exit();
error_brightness:
- acer_led_exit();
+ if (has_cap(ACER_CAP_MAILLED))
+ acer_led_exit();
error_mailled:
return err;
}
@@ -1254,6 +1279,12 @@ static int __init acer_wmi_init(void)
printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n");
+ if (dmi_check_system(acer_blacklist)) {
+ printk(ACER_INFO "Blacklisted hardware detected - "
+ "not loading\n");
+ return -ENODEV;
+ }
+
find_quirks();
/*
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c
index d63f26e666a4..ba1f7497e4b9 100644
--- a/drivers/platform/x86/asus_acpi.c
+++ b/drivers/platform/x86/asus_acpi.c
@@ -987,7 +987,6 @@ asus_proc_add(char *name, proc_writefunc *writefunc,
proc->write_proc = writefunc;
proc->read_proc = readfunc;
proc->data = acpi_driver_data(device);
- proc->owner = THIS_MODULE;
proc->uid = asus_uid;
proc->gid = asus_gid;
return 0;
@@ -1020,7 +1019,6 @@ static int asus_hotk_add_fs(struct acpi_device *device)
if (proc) {
proc->read_proc = proc_read_info;
proc->data = acpi_driver_data(device);
- proc->owner = THIS_MODULE;
proc->uid = asus_uid;
proc->gid = asus_gid;
} else {
@@ -1436,7 +1434,6 @@ static int __init asus_acpi_init(void)
printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n");
return -ENODEV;
}
- asus_proc_dir->owner = THIS_MODULE;
result = acpi_bus_register_driver(&asus_hotk_driver);
if (result < 0) {
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 16e11c2ee19a..af9f43021172 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -103,7 +103,7 @@ static void parse_da_table(const struct dmi_header *dm)
da_num_tokens += tokens;
}
-static void find_tokens(const struct dmi_header *dm)
+static void find_tokens(const struct dmi_header *dm, void *dummy)
{
switch (dm->type) {
case 0xd4: /* Indexed IO */
@@ -356,7 +356,7 @@ static int __init dell_init(void)
if (!dmi_check_system(dell_device_table))
return -ENODEV;
- dmi_walk(find_tokens);
+ dmi_walk(find_tokens, NULL);
if (!da_tokens) {
printk(KERN_INFO "dell-laptop: Unable to find dmi tokens\n");
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
new file mode 100644
index 000000000000..2fab94162147
--- /dev/null
+++ b/drivers/platform/x86/dell-wmi.c
@@ -0,0 +1,210 @@
+/*
+ * Dell WMI hotkeys
+ *
+ * Copyright (C) 2008 Red Hat <mjg@redhat.com>
+ *
+ * Portions based on wistron_btns.c:
+ * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
+ * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
+ * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
+#include <linux/string.h>
+
+MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
+MODULE_DESCRIPTION("Dell laptop WMI hotkeys driver");
+MODULE_LICENSE("GPL");
+
+#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
+
+MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
+
+struct key_entry {
+ char type; /* See KE_* below */
+ u16 code;
+ u16 keycode;
+};
+
+enum { KE_KEY, KE_SW, KE_END };
+
+static struct key_entry dell_wmi_keymap[] = {
+ {KE_KEY, 0xe045, KEY_PROG1},
+ {KE_END, 0}
+};
+
+static struct input_dev *dell_wmi_input_dev;
+
+static struct key_entry *dell_wmi_get_entry_by_scancode(int code)
+{
+ struct key_entry *key;
+
+ for (key = dell_wmi_keymap; key->type != KE_END; key++)
+ if (code == key->code)
+ return key;
+
+ return NULL;
+}
+
+static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode)
+{
+ struct key_entry *key;
+
+ for (key = dell_wmi_keymap; key->type != KE_END; key++)
+ if (key->type == KE_KEY && keycode == key->keycode)
+ return key;
+
+ return NULL;
+}
+
+static int dell_wmi_getkeycode(struct input_dev *dev, int scancode,
+ int *keycode)
+{
+ struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode);
+
+ if (key && key->type == KE_KEY) {
+ *keycode = key->keycode;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int dell_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
+{
+ struct key_entry *key;
+ int old_keycode;
+
+ if (keycode < 0 || keycode > KEY_MAX)
+ return -EINVAL;
+
+ key = dell_wmi_get_entry_by_scancode(scancode);
+ if (key && key->type == KE_KEY) {
+ old_keycode = key->keycode;
+ key->keycode = keycode;
+ set_bit(keycode, dev->keybit);
+ if (!dell_wmi_get_entry_by_keycode(old_keycode))
+ clear_bit(old_keycode, dev->keybit);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static void dell_wmi_notify(u32 value, void *context)
+{
+ struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+ static struct key_entry *key;
+ union acpi_object *obj;
+
+ wmi_get_event_data(value, &response);
+
+ obj = (union acpi_object *)response.pointer;
+
+ if (obj && obj->type == ACPI_TYPE_BUFFER) {
+ int *buffer = (int *)obj->buffer.pointer;
+ key = dell_wmi_get_entry_by_scancode(buffer[1]);
+ if (key) {
+ input_report_key(dell_wmi_input_dev, key->keycode, 1);
+ input_sync(dell_wmi_input_dev);
+ input_report_key(dell_wmi_input_dev, key->keycode, 0);
+ input_sync(dell_wmi_input_dev);
+ } else
+ printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n",
+ buffer[1]);
+ }
+}
+
+static int __init dell_wmi_input_setup(void)
+{
+ struct key_entry *key;
+ int err;
+
+ dell_wmi_input_dev = input_allocate_device();
+
+ if (!dell_wmi_input_dev)
+ return -ENOMEM;
+
+ dell_wmi_input_dev->name = "Dell WMI hotkeys";
+ dell_wmi_input_dev->phys = "wmi/input0";
+ dell_wmi_input_dev->id.bustype = BUS_HOST;
+ dell_wmi_input_dev->getkeycode = dell_wmi_getkeycode;
+ dell_wmi_input_dev->setkeycode = dell_wmi_setkeycode;
+
+ for (key = dell_wmi_keymap; key->type != KE_END; key++) {
+ switch (key->type) {
+ case KE_KEY:
+ set_bit(EV_KEY, dell_wmi_input_dev->evbit);
+ set_bit(key->keycode, dell_wmi_input_dev->keybit);
+ break;
+ case KE_SW:
+ set_bit(EV_SW, dell_wmi_input_dev->evbit);
+ set_bit(key->keycode, dell_wmi_input_dev->swbit);
+ break;
+ }
+ }
+
+ err = input_register_device(dell_wmi_input_dev);
+
+ if (err) {
+ input_free_device(dell_wmi_input_dev);
+ return err;
+ }
+
+ return 0;
+}
+
+static int __init dell_wmi_init(void)
+{
+ int err;
+
+ if (wmi_has_guid(DELL_EVENT_GUID)) {
+ err = dell_wmi_input_setup();
+
+ if (err)
+ return err;
+
+ err = wmi_install_notify_handler(DELL_EVENT_GUID,
+ dell_wmi_notify, NULL);
+ if (err) {
+ input_unregister_device(dell_wmi_input_dev);
+ printk(KERN_ERR "dell-wmi: Unable to register"
+ " notify handler - %d\n", err);
+ return err;
+ }
+
+ } else
+ printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n");
+
+ return 0;
+}
+
+static void __exit dell_wmi_exit(void)
+{
+ if (wmi_has_guid(DELL_EVENT_GUID)) {
+ wmi_remove_notify_handler(DELL_EVENT_GUID);
+ input_unregister_device(dell_wmi_input_dev);
+ }
+}
+
+module_init(dell_wmi_init);
+module_exit(dell_wmi_exit);
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index f41135f2fb29..50d9019de2be 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -53,6 +53,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
static int __init hp_wmi_bios_setup(struct platform_device *device);
static int __exit hp_wmi_bios_remove(struct platform_device *device);
+static int hp_wmi_resume_handler(struct platform_device *device);
struct bios_args {
u32 signature;
@@ -101,6 +102,7 @@ static struct platform_driver hp_wmi_driver = {
},
.probe = hp_wmi_bios_setup,
.remove = hp_wmi_bios_remove,
+ .resume = hp_wmi_resume_handler,
};
static int hp_wmi_perform_query(int query, int write, int value)
@@ -487,6 +489,29 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device)
return 0;
}
+static int hp_wmi_resume_handler(struct platform_device *device)
+{
+ struct key_entry *key;
+
+ /*
+ * Docking state may have changed while suspended, so trigger
+ * an input event for the current state. As this is a switch,
+ * the input layer will only actually pass it on if the state
+ * changed.
+ */
+ for (key = hp_wmi_keymap; key->type != KE_END; key++) {
+ switch (key->type) {
+ case KE_SW:
+ input_report_switch(hp_wmi_input_dev, key->keycode,
+ hp_wmi_dock_state());
+ input_sync(hp_wmi_input_dev);
+ break;
+ }
+ }
+
+ return 0;
+}
+
static int __init hp_wmi_init(void)
{
int err;
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c
index 27b7662955bb..29432a50be45 100644
--- a/drivers/platform/x86/intel_menlow.c
+++ b/drivers/platform/x86/intel_menlow.c
@@ -57,8 +57,8 @@ MODULE_LICENSE("GPL");
* In that case max_cstate would be n-1
* GTHS returning '0' would mean that no bandwidth control states are supported
*/
-static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
- unsigned long *max_state)
+static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
+ unsigned long *max_state)
{
struct acpi_device *device = cdev->devdata;
acpi_handle handle = device->handle;
@@ -83,22 +83,12 @@ static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
return 0;
}
-static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
- char *buf)
-{
- unsigned long value;
- if (memory_get_int_max_bandwidth(cdev, &value))
- return -EINVAL;
-
- return sprintf(buf, "%ld\n", value);
-}
-
static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
- char *buf)
+ unsigned long *value)
{
struct acpi_device *device = cdev->devdata;
acpi_handle handle = device->handle;
- unsigned long long value;
+ unsigned long long result;
struct acpi_object_list arg_list;
union acpi_object arg;
acpi_status status = AE_OK;
@@ -108,15 +98,16 @@ static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = MEMORY_ARG_CUR_BANDWIDTH;
status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH,
- &arg_list, &value);
+ &arg_list, &result);
if (ACPI_FAILURE(status))
return -EFAULT;
- return sprintf(buf, "%llu\n", value);
+ *value = result;
+ return 0;
}
static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
- unsigned int state)
+ unsigned long state)
{
struct acpi_device *device = cdev->devdata;
acpi_handle handle = device->handle;
@@ -126,7 +117,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
unsigned long long temp;
unsigned long max_state;
- if (memory_get_int_max_bandwidth(cdev, &max_state))
+ if (memory_get_max_bandwidth(cdev, &max_state))
return -EFAULT;
if (state > max_state)
@@ -142,7 +133,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
&temp);
printk(KERN_INFO
- "Bandwidth value was %d: status is %d\n", state, status);
+ "Bandwidth value was %ld: status is %d\n", state, status);
if (ACPI_FAILURE(status))
return -EFAULT;
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index c47a44dcb702..a5ce4bc202e3 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -184,6 +184,7 @@ static const struct acpi_device_id pcc_device_ids[] = {
{ "MAT0019", 0},
{ "", 0},
};
+MODULE_DEVICE_TABLE(acpi, pcc_device_ids);
static struct acpi_driver acpi_pcc_driver = {
.name = ACPI_PCC_DRIVER_NAME,
@@ -366,7 +367,7 @@ static ssize_t show_numbatt(struct device *dev, struct device_attribute *attr,
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
return -EIO;
- return sprintf(buf, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]);
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]);
}
static ssize_t show_lcdtype(struct device *dev, struct device_attribute *attr,
@@ -378,7 +379,7 @@ static ssize_t show_lcdtype(struct device *dev, struct device_attribute *attr,
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
return -EIO;
- return sprintf(buf, "%u\n", pcc->sinf[SINF_LCD_TYPE]);
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_LCD_TYPE]);
}
static ssize_t show_mute(struct device *dev, struct device_attribute *attr,
@@ -390,7 +391,7 @@ static ssize_t show_mute(struct device *dev, struct device_attribute *attr,
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
return -EIO;
- return sprintf(buf, "%u\n", pcc->sinf[SINF_MUTE]);
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_MUTE]);
}
static ssize_t show_sticky(struct device *dev, struct device_attribute *attr,
@@ -402,7 +403,7 @@ static ssize_t show_sticky(struct device *dev, struct device_attribute *attr,
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
return -EIO;
- return sprintf(buf, "%u\n", pcc->sinf[SINF_STICKY_KEY]);
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_STICKY_KEY]);
}
static ssize_t set_sticky(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 537959d07148..a90ec5cb2f20 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -2,7 +2,7 @@
* ACPI Sony Notebook Control Driver (SNC and SPIC)
*
* Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net>
- * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
+ * Copyright (C) 2007-2009 Mattia Dongili <malattia@linux.it>
*
* Parts of this driver inspired from asus_acpi.c and ibm_acpi.c
* which are copyrighted by their respective authors.
@@ -46,7 +46,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/backlight.h>
#include <linux/platform_device.h>
@@ -64,6 +63,7 @@
#include <asm/uaccess.h>
#include <linux/sonypi.h>
#include <linux/sony-laptop.h>
+#include <linux/rfkill.h>
#ifdef CONFIG_SONYPI_COMPAT
#include <linux/poll.h>
#include <linux/miscdevice.h>
@@ -123,6 +123,18 @@ MODULE_PARM_DESC(minor,
"default is -1 (automatic)");
#endif
+enum sony_nc_rfkill {
+ SONY_WIFI,
+ SONY_BLUETOOTH,
+ SONY_WWAN,
+ SONY_WIMAX,
+ SONY_RFKILL_MAX,
+};
+
+static struct rfkill *sony_rfkill_devices[SONY_RFKILL_MAX];
+static int sony_rfkill_address[SONY_RFKILL_MAX] = {0x300, 0x500, 0x700, 0x900};
+static void sony_nc_rfkill_update(void);
+
/*********** Input Devices ***********/
#define SONY_LAPTOP_BUF_SIZE 128
@@ -134,6 +146,7 @@ struct sony_laptop_input_s {
spinlock_t fifo_lock;
struct workqueue_struct *wq;
};
+
static struct sony_laptop_input_s sony_laptop_input = {
.users = ATOMIC_INIT(0),
};
@@ -211,6 +224,14 @@ static int sony_laptop_input_index[] = {
48, /* 61 SONYPI_EVENT_WIRELESS_OFF */
49, /* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */
50, /* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+ 51, /* 64 SONYPI_EVENT_CD_EJECT_PRESSED */
+ 52, /* 65 SONYPI_EVENT_MODEKEY_PRESSED */
+ 53, /* 66 SONYPI_EVENT_PKEY_P4 */
+ 54, /* 67 SONYPI_EVENT_PKEY_P5 */
+ 55, /* 68 SONYPI_EVENT_SETTINGKEY_PRESSED */
+ 56, /* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */
+ 57, /* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */
+ -1, /* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */
};
static int sony_laptop_input_keycode_map[] = {
@@ -264,7 +285,14 @@ static int sony_laptop_input_keycode_map[] = {
KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */
KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */
KEY_ZOOMIN, /* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */
- KEY_ZOOMOUT /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+ KEY_ZOOMOUT, /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+ KEY_EJECTCD, /* 51 SONYPI_EVENT_CD_EJECT_PRESSED */
+ KEY_F13, /* 52 SONYPI_EVENT_MODEKEY_PRESSED */
+ KEY_PROG4, /* 53 SONYPI_EVENT_PKEY_P4 */
+ KEY_F14, /* 54 SONYPI_EVENT_PKEY_P5 */
+ KEY_F15, /* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */
+ KEY_VOLUMEUP, /* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */
+ KEY_VOLUMEDOWN, /* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */
};
/* release buttons after a short delay if pressed */
@@ -369,7 +397,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device)
sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop");
if (!sony_laptop_input.wq) {
printk(KERN_ERR DRV_PFX
- "Unabe to create workqueue.\n");
+ "Unable to create workqueue.\n");
error = -ENXIO;
goto err_free_kfifo;
}
@@ -689,6 +717,31 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
return -1;
}
+static int sony_find_snc_handle(int handle)
+{
+ int i;
+ int result;
+
+ for (i = 0x20; i < 0x30; i++) {
+ acpi_callsetfunc(sony_nc_acpi_handle, "SN00", i, &result);
+ if (result == handle)
+ return i-0x20;
+ }
+
+ return -1;
+}
+
+static int sony_call_snc_handle(int handle, int argument, int *result)
+{
+ int offset = sony_find_snc_handle(handle);
+
+ if (offset < 0)
+ return -1;
+
+ return acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument,
+ result);
+}
+
/*
* sony_nc_values input/output validate functions
*/
@@ -809,87 +862,53 @@ struct sony_nc_event {
u8 event;
};
-static struct sony_nc_event *sony_nc_events;
-
-/* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence
- * for Fn keys
- */
-static int sony_nc_C_enable(const struct dmi_system_id *id)
-{
- int result = 0;
-
- printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident);
-
- sony_nc_events = id->driver_data;
-
- if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) {
- printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some "
- "functionalities may be missing\n");
- return 1;
- }
- return 0;
-}
-
-static struct sony_nc_event sony_C_events[] = {
+static struct sony_nc_event sony_100_events[] = {
+ { 0x90, SONYPI_EVENT_PKEY_P1 },
+ { 0x10, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x91, SONYPI_EVENT_PKEY_P2 },
+ { 0x11, SONYPI_EVENT_ANYBUTTON_RELEASED },
{ 0x81, SONYPI_EVENT_FNKEY_F1 },
{ 0x01, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x82, SONYPI_EVENT_FNKEY_F2 },
+ { 0x02, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x83, SONYPI_EVENT_FNKEY_F3 },
+ { 0x03, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x84, SONYPI_EVENT_FNKEY_F4 },
+ { 0x04, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x85, SONYPI_EVENT_FNKEY_F5 },
{ 0x05, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x86, SONYPI_EVENT_FNKEY_F6 },
{ 0x06, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x87, SONYPI_EVENT_FNKEY_F7 },
{ 0x07, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x89, SONYPI_EVENT_FNKEY_F9 },
+ { 0x09, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x8A, SONYPI_EVENT_FNKEY_F10 },
{ 0x0A, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x8C, SONYPI_EVENT_FNKEY_F12 },
{ 0x0C, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED },
+ { 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED },
{ 0, 0 },
};
-/* SNC-only model map */
-static const struct dmi_system_id sony_nc_ids[] = {
- {
- .ident = "Sony Vaio FE Series",
- .callback = sony_nc_C_enable,
- .driver_data = sony_C_events,
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"),
- },
- },
- {
- .ident = "Sony Vaio FZ Series",
- .callback = sony_nc_C_enable,
- .driver_data = sony_C_events,
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"),
- },
- },
- {
- .ident = "Sony Vaio C Series",
- .callback = sony_nc_C_enable,
- .driver_data = sony_C_events,
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"),
- },
- },
- {
- .ident = "Sony Vaio N Series",
- .callback = sony_nc_C_enable,
- .driver_data = sony_C_events,
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-N"),
- },
- },
- { }
+static struct sony_nc_event sony_127_events[] = {
+ { 0x81, SONYPI_EVENT_MODEKEY_PRESSED },
+ { 0x01, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x82, SONYPI_EVENT_PKEY_P1 },
+ { 0x02, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x83, SONYPI_EVENT_PKEY_P2 },
+ { 0x03, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x84, SONYPI_EVENT_PKEY_P3 },
+ { 0x04, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x85, SONYPI_EVENT_PKEY_P4 },
+ { 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x86, SONYPI_EVENT_PKEY_P5 },
+ { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED },
+ { 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0, 0 },
};
/*
@@ -897,38 +916,59 @@ static const struct dmi_system_id sony_nc_ids[] = {
*/
static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
{
- struct sony_nc_event *evmap;
u32 ev = event;
- int result;
- if (ev == 0x92) {
- /* read the key pressed from EC.GECR
- * A call to SN07 with 0x0202 will do it as well respecting
- * the current protocol on different OSes
- *
- * Note: the path for GECR may be
- * \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends)
- * \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR)
- *
- * TODO: we may want to do the same for the older GHKE -need
- * dmi list- so this snippet may become one more callback.
- */
- if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0)
- dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev);
- else
- ev = result & 0xFF;
- }
+ if (ev >= 0x90) {
+ /* New-style event */
+ int result;
+ int key_handle = 0;
+ ev -= 0x90;
+
+ if (sony_find_snc_handle(0x100) == ev)
+ key_handle = 0x100;
+ if (sony_find_snc_handle(0x127) == ev)
+ key_handle = 0x127;
+
+ if (key_handle) {
+ struct sony_nc_event *key_event;
+
+ if (sony_call_snc_handle(key_handle, 0x200, &result)) {
+ dprintk("sony_acpi_notify, unable to decode"
+ " event 0x%.2x 0x%.2x\n", key_handle,
+ ev);
+ /* restore the original event */
+ ev = event;
+ } else {
+ ev = result & 0xFF;
+
+ if (key_handle == 0x100)
+ key_event = sony_100_events;
+ else
+ key_event = sony_127_events;
+
+ for (; key_event->data; key_event++) {
+ if (key_event->data == ev) {
+ ev = key_event->event;
+ break;
+ }
+ }
- if (sony_nc_events)
- for (evmap = sony_nc_events; evmap->event; evmap++) {
- if (evmap->data == ev) {
- ev = evmap->event;
- break;
+ if (!key_event->data)
+ printk(KERN_INFO DRV_PFX
+ "Unknown event: 0x%x 0x%x\n",
+ key_handle,
+ ev);
+ else
+ sony_laptop_report_input_event(ev);
}
+ } else if (sony_find_snc_handle(0x124) == ev) {
+ sony_nc_rfkill_update();
+ return;
}
+ } else
+ sony_laptop_report_input_event(ev);
dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);
- sony_laptop_report_input_event(ev);
acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev);
}
@@ -953,9 +993,25 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
/*
* ACPI device
*/
+static int sony_nc_function_setup(struct acpi_device *device)
+{
+ int result;
+
+ /* Enable all events */
+ acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0xffff, &result);
+
+ /* Setup hotkeys */
+ sony_call_snc_handle(0x0100, 0, &result);
+ sony_call_snc_handle(0x0101, 0, &result);
+ sony_call_snc_handle(0x0102, 0x100, &result);
+
+ return 0;
+}
+
static int sony_nc_resume(struct acpi_device *device)
{
struct sony_nc_value *item;
+ acpi_handle handle;
for (item = sony_nc_values; item->name; item++) {
int ret;
@@ -970,13 +1026,188 @@ static int sony_nc_resume(struct acpi_device *device)
}
}
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
+ &handle))) {
+ if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
+ dprintk("ECON Method failed\n");
+ }
+
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
+ &handle))) {
+ dprintk("Doing SNC setup\n");
+ sony_nc_function_setup(device);
+ }
+
/* set the last requested brightness level */
if (sony_backlight_device &&
!sony_backlight_update_status(sony_backlight_device))
printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
- /* re-initialize models with specific requirements */
- dmi_check_system(sony_nc_ids);
+ return 0;
+}
+
+static void sony_nc_rfkill_cleanup(void)
+{
+ int i;
+
+ for (i = 0; i < SONY_RFKILL_MAX; i++) {
+ if (sony_rfkill_devices[i])
+ rfkill_unregister(sony_rfkill_devices[i]);
+ }
+}
+
+static int sony_nc_rfkill_get(void *data, enum rfkill_state *state)
+{
+ int result;
+ int argument = sony_rfkill_address[(long) data];
+
+ sony_call_snc_handle(0x124, 0x200, &result);
+ if (result & 0x1) {
+ sony_call_snc_handle(0x124, argument, &result);
+ if (result & 0xf)
+ *state = RFKILL_STATE_UNBLOCKED;
+ else
+ *state = RFKILL_STATE_SOFT_BLOCKED;
+ } else {
+ *state = RFKILL_STATE_HARD_BLOCKED;
+ }
+
+ return 0;
+}
+
+static int sony_nc_rfkill_set(void *data, enum rfkill_state state)
+{
+ int result;
+ int argument = sony_rfkill_address[(long) data] + 0x100;
+
+ if (state == RFKILL_STATE_UNBLOCKED)
+ argument |= 0xff0000;
+
+ return sony_call_snc_handle(0x124, argument, &result);
+}
+
+static int sony_nc_setup_wifi_rfkill(struct acpi_device *device)
+{
+ int err = 0;
+ struct rfkill *sony_wifi_rfkill;
+
+ sony_wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN);
+ if (!sony_wifi_rfkill)
+ return -1;
+ sony_wifi_rfkill->name = "sony-wifi";
+ sony_wifi_rfkill->toggle_radio = sony_nc_rfkill_set;
+ sony_wifi_rfkill->get_state = sony_nc_rfkill_get;
+ sony_wifi_rfkill->user_claim_unsupported = 1;
+ sony_wifi_rfkill->data = (void *)SONY_WIFI;
+ err = rfkill_register(sony_wifi_rfkill);
+ if (err)
+ rfkill_free(sony_wifi_rfkill);
+ else
+ sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill;
+ return err;
+}
+
+static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device)
+{
+ int err = 0;
+ struct rfkill *sony_bluetooth_rfkill;
+
+ sony_bluetooth_rfkill = rfkill_allocate(&device->dev,
+ RFKILL_TYPE_BLUETOOTH);
+ if (!sony_bluetooth_rfkill)
+ return -1;
+ sony_bluetooth_rfkill->name = "sony-bluetooth";
+ sony_bluetooth_rfkill->toggle_radio = sony_nc_rfkill_set;
+ sony_bluetooth_rfkill->get_state = sony_nc_rfkill_get;
+ sony_bluetooth_rfkill->user_claim_unsupported = 1;
+ sony_bluetooth_rfkill->data = (void *)SONY_BLUETOOTH;
+ err = rfkill_register(sony_bluetooth_rfkill);
+ if (err)
+ rfkill_free(sony_bluetooth_rfkill);
+ else
+ sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill;
+ return err;
+}
+
+static int sony_nc_setup_wwan_rfkill(struct acpi_device *device)
+{
+ int err = 0;
+ struct rfkill *sony_wwan_rfkill;
+
+ sony_wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN);
+ if (!sony_wwan_rfkill)
+ return -1;
+ sony_wwan_rfkill->name = "sony-wwan";
+ sony_wwan_rfkill->toggle_radio = sony_nc_rfkill_set;
+ sony_wwan_rfkill->get_state = sony_nc_rfkill_get;
+ sony_wwan_rfkill->user_claim_unsupported = 1;
+ sony_wwan_rfkill->data = (void *)SONY_WWAN;
+ err = rfkill_register(sony_wwan_rfkill);
+ if (err)
+ rfkill_free(sony_wwan_rfkill);
+ else
+ sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill;
+ return err;
+}
+
+static int sony_nc_setup_wimax_rfkill(struct acpi_device *device)
+{
+ int err = 0;
+ struct rfkill *sony_wimax_rfkill;
+
+ sony_wimax_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WIMAX);
+ if (!sony_wimax_rfkill)
+ return -1;
+ sony_wimax_rfkill->name = "sony-wimax";
+ sony_wimax_rfkill->toggle_radio = sony_nc_rfkill_set;
+ sony_wimax_rfkill->get_state = sony_nc_rfkill_get;
+ sony_wimax_rfkill->user_claim_unsupported = 1;
+ sony_wimax_rfkill->data = (void *)SONY_WIMAX;
+ err = rfkill_register(sony_wimax_rfkill);
+ if (err)
+ rfkill_free(sony_wimax_rfkill);
+ else
+ sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill;
+ return err;
+}
+
+static void sony_nc_rfkill_update()
+{
+ int i;
+ enum rfkill_state state;
+
+ for (i = 0; i < SONY_RFKILL_MAX; i++) {
+ if (sony_rfkill_devices[i]) {
+ sony_rfkill_devices[i]->
+ get_state(sony_rfkill_devices[i]->data,
+ &state);
+ rfkill_force_state(sony_rfkill_devices[i], state);
+ }
+ }
+}
+
+static int sony_nc_rfkill_setup(struct acpi_device *device)
+{
+ int result, ret;
+
+ if (sony_find_snc_handle(0x124) == -1)
+ return -1;
+
+ ret = sony_call_snc_handle(0x124, 0xb00, &result);
+ if (ret) {
+ printk(KERN_INFO DRV_PFX
+ "Unable to enumerate rfkill devices: %x\n", ret);
+ return ret;
+ }
+
+ if (result & 0x1)
+ sony_nc_setup_wifi_rfkill(device);
+ if (result & 0x2)
+ sony_nc_setup_bluetooth_rfkill(device);
+ if (result & 0x1c)
+ sony_nc_setup_wwan_rfkill(device);
+ if (result & 0x20)
+ sony_nc_setup_wimax_rfkill(device);
return 0;
}
@@ -1024,11 +1255,24 @@ static int sony_nc_add(struct acpi_device *device)
dprintk("_INI Method failed\n");
}
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
+ &handle))) {
+ if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
+ dprintk("ECON Method failed\n");
+ }
+
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
+ &handle))) {
+ dprintk("Doing SNC setup\n");
+ sony_nc_function_setup(device);
+ sony_nc_rfkill_setup(device);
+ }
+
/* setup input devices and helper fifo */
result = sony_laptop_setup_input(device);
if (result) {
printk(KERN_ERR DRV_PFX
- "Unabe to create input devices.\n");
+ "Unable to create input devices.\n");
goto outwalk;
}
@@ -1063,9 +1307,6 @@ static int sony_nc_add(struct acpi_device *device)
}
- /* initialize models with specific requirements */
- dmi_check_system(sony_nc_ids);
-
result = sony_pf_add();
if (result)
goto outbacklight;
@@ -1131,6 +1372,7 @@ static int sony_nc_add(struct acpi_device *device)
sony_laptop_remove_input();
outwalk:
+ sony_nc_rfkill_cleanup();
return result;
}
@@ -1156,6 +1398,7 @@ static int sony_nc_remove(struct acpi_device *device, int type)
sony_pf_remove();
sony_laptop_remove_input();
+ sony_nc_rfkill_cleanup();
dprintk(SONY_NC_DRIVER_NAME " removed.\n");
return 0;
@@ -1195,7 +1438,6 @@ static struct acpi_driver sony_nc_driver = {
#define SONYPI_TYPE1_OFFSET 0x04
#define SONYPI_TYPE2_OFFSET 0x12
#define SONYPI_TYPE3_OFFSET 0x12
-#define SONYPI_TYPE4_OFFSET 0x12
struct sony_pic_ioport {
struct acpi_resource_io io1;
@@ -1328,6 +1570,7 @@ static struct sonypi_event sonypi_pkeyev[] = {
{ 0x01, SONYPI_EVENT_PKEY_P1 },
{ 0x02, SONYPI_EVENT_PKEY_P2 },
{ 0x04, SONYPI_EVENT_PKEY_P3 },
+ { 0x20, SONYPI_EVENT_PKEY_P1 },
{ 0, 0 }
};
@@ -1371,6 +1614,7 @@ static struct sonypi_event sonypi_zoomev[] = {
{ 0x39, SONYPI_EVENT_ZOOM_PRESSED },
{ 0x10, SONYPI_EVENT_ZOOM_IN_PRESSED },
{ 0x20, SONYPI_EVENT_ZOOM_OUT_PRESSED },
+ { 0x04, SONYPI_EVENT_ZOOM_PRESSED },
{ 0, 0 }
};
@@ -1401,6 +1645,19 @@ static struct sonypi_event sonypi_batteryev[] = {
{ 0, 0 }
};
+/* The set of possible volume events */
+static struct sonypi_event sonypi_volumeev[] = {
+ { 0x01, SONYPI_EVENT_VOLUME_INC_PRESSED },
+ { 0x02, SONYPI_EVENT_VOLUME_DEC_PRESSED },
+ { 0, 0 }
+};
+
+/* The set of possible brightness events */
+static struct sonypi_event sonypi_brightnessev[] = {
+ { 0x80, SONYPI_EVENT_BRIGHTNESS_PRESSED },
+ { 0, 0 }
+};
+
static struct sonypi_eventtypes type1_events[] = {
{ 0, 0xffffffff, sonypi_releaseev },
{ 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
@@ -1438,17 +1695,11 @@ static struct sonypi_eventtypes type3_events[] = {
{ 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
{ 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
{ 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
- { 0 },
-};
-static struct sonypi_eventtypes type4_events[] = {
- { 0, 0xffffffff, sonypi_releaseev },
- { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
- { 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
- { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
- { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
{ 0x05, SONYPI_PKEY_MASK, sonypi_pkeyev },
{ 0x05, SONYPI_ZOOM_MASK, sonypi_zoomev },
{ 0x05, SONYPI_CAPTURE_MASK, sonypi_captureev },
+ { 0x05, SONYPI_PKEY_MASK, sonypi_volumeev },
+ { 0x05, SONYPI_PKEY_MASK, sonypi_brightnessev },
{ 0 },
};
@@ -1511,11 +1762,11 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v)
/*
* minidrivers for SPIC models
*/
-static int type4_handle_irq(const u8 data_mask, const u8 ev)
+static int type3_handle_irq(const u8 data_mask, const u8 ev)
{
/*
* 0x31 could mean we have to take some extra action and wait for
- * the next irq for some Type4 models, it will generate a new
+ * the next irq for some Type3 models, it will generate a new
* irq and we can read new data from the device:
* - 0x5c and 0x5f requires 0xA0
* - 0x61 requires 0xB3
@@ -1545,16 +1796,10 @@ static struct device_ctrl spic_types[] = {
},
{
.model = SONYPI_DEVICE_TYPE3,
- .handle_irq = NULL,
+ .handle_irq = type3_handle_irq,
.evport_offset = SONYPI_TYPE3_OFFSET,
.event_types = type3_events,
},
- {
- .model = SONYPI_DEVICE_TYPE4,
- .handle_irq = type4_handle_irq,
- .evport_offset = SONYPI_TYPE4_OFFSET,
- .event_types = type4_events,
- },
};
static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
@@ -1578,14 +1823,21 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_ICH7_1, NULL);
if (pcidev) {
- dev->control = &spic_types[3];
+ dev->control = &spic_types[2];
goto out;
}
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_ICH8_4, NULL);
if (pcidev) {
- dev->control = &spic_types[3];
+ dev->control = &spic_types[2];
+ goto out;
+ }
+
+ pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_ICH9_1, NULL);
+ if (pcidev) {
+ dev->control = &spic_types[2];
goto out;
}
@@ -1598,8 +1850,7 @@ out:
printk(KERN_INFO DRV_PFX "detected Type%d model\n",
dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 :
- dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 :
- dev->control->model == SONYPI_DEVICE_TYPE3 ? 3 : 4);
+ dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
}
/* camera tests and poweron/poweroff */
@@ -1754,17 +2005,14 @@ int sony_pic_camera_command(int command, u8 value)
EXPORT_SYMBOL(sony_pic_camera_command);
/* gprs/edge modem (SZ460N and SZ210P), thanks to Joshua Wise */
-static void sony_pic_set_wwanpower(u8 state)
+static void __sony_pic_set_wwanpower(u8 state)
{
state = !!state;
- mutex_lock(&spic_dev.lock);
- if (spic_dev.wwan_power == state) {
- mutex_unlock(&spic_dev.lock);
+ if (spic_dev.wwan_power == state)
return;
- }
sony_pic_call2(0xB0, state);
+ sony_pic_call1(0x82);
spic_dev.wwan_power = state;
- mutex_unlock(&spic_dev.lock);
}
static ssize_t sony_pic_wwanpower_store(struct device *dev,
@@ -1776,7 +2024,9 @@ static ssize_t sony_pic_wwanpower_store(struct device *dev,
return -EINVAL;
value = simple_strtoul(buffer, NULL, 10);
- sony_pic_set_wwanpower(value);
+ mutex_lock(&spic_dev.lock);
+ __sony_pic_set_wwanpower(value);
+ mutex_unlock(&spic_dev.lock);
return count;
}
@@ -1917,12 +2167,7 @@ static struct sonypi_compat_s sonypi_compat = {
static int sonypi_misc_fasync(int fd, struct file *filp, int on)
{
- int retval;
-
- retval = fasync_helper(fd, filp, on, &sonypi_compat.fifo_async);
- if (retval < 0)
- return retval;
- return 0;
+ return fasync_helper(fd, filp, on, &sonypi_compat.fifo_async);
}
static int sonypi_misc_release(struct inode *inode, struct file *file)
@@ -1934,10 +2179,15 @@ static int sonypi_misc_release(struct inode *inode, struct file *file)
static int sonypi_misc_open(struct inode *inode, struct file *file)
{
/* Flush input queue on first open */
- lock_kernel();
+ unsigned long flags;
+
+ spin_lock_irqsave(sonypi_compat.fifo->lock, flags);
+
if (atomic_inc_return(&sonypi_compat.open_count) == 1)
- kfifo_reset(sonypi_compat.fifo);
- unlock_kernel();
+ __kfifo_reset(sonypi_compat.fifo);
+
+ spin_unlock_irqrestore(sonypi_compat.fifo->lock, flags);
+
return 0;
}
@@ -1990,8 +2240,8 @@ static int ec_read16(u8 addr, u16 *value)
return 0;
}
-static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
- unsigned int cmd, unsigned long arg)
+static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd,
+ unsigned long arg)
{
int ret = 0;
void __user *argp = (void __user *)arg;
@@ -2125,7 +2375,7 @@ static const struct file_operations sonypi_misc_fops = {
.open = sonypi_misc_open,
.release = sonypi_misc_release,
.fasync = sonypi_misc_fasync,
- .ioctl = sonypi_misc_ioctl,
+ .unlocked_ioctl = sonypi_misc_ioctl,
};
static struct miscdevice sonypi_misc_device = {
@@ -2566,7 +2816,7 @@ static int sony_pic_add(struct acpi_device *device)
result = sony_pic_possible_resources(device);
if (result) {
printk(KERN_ERR DRV_PFX
- "Unabe to read possible resources.\n");
+ "Unable to read possible resources.\n");
goto err_free_resources;
}
@@ -2574,7 +2824,7 @@ static int sony_pic_add(struct acpi_device *device)
result = sony_laptop_setup_input(device);
if (result) {
printk(KERN_ERR DRV_PFX
- "Unabe to create input devices.\n");
+ "Unable to create input devices.\n");
goto err_free_resources;
}
diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c
index b4a4aa9ee482..44166003d4ef 100644
--- a/drivers/platform/x86/tc1100-wmi.c
+++ b/drivers/platform/x86/tc1100-wmi.c
@@ -94,9 +94,8 @@ static int get_state(u32 *out, u8 instance)
return -ENODEV;
obj = (union acpi_object *) result.pointer;
- if (obj && obj->type == ACPI_TYPE_BUFFER &&
- obj->buffer.length == sizeof(u32)) {
- tmp = *((u32 *) obj->buffer.pointer);
+ if (obj && obj->type == ACPI_TYPE_INTEGER) {
+ tmp = obj->integer.value;
} else {
tmp = 0;
}
@@ -109,7 +108,7 @@ static int get_state(u32 *out, u8 instance)
*out = (tmp == 3) ? 1 : 0;
return 0;
case TC1100_INSTANCE_JOGDIAL:
- *out = (tmp == 1) ? 1 : 0;
+ *out = (tmp == 1) ? 0 : 1;
return 0;
default:
return -ENODEV;
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index d2433204a40c..a40b075743d9 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -3,7 +3,7 @@
*
*
* Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
- * Copyright (C) 2006-2008 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+ * Copyright (C) 2006-2009 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
*/
#define TPACPI_VERSION "0.22"
-#define TPACPI_SYSFS_VERSION 0x020200
+#define TPACPI_SYSFS_VERSION 0x020300
/*
* Changelog:
@@ -54,6 +54,7 @@
#include <linux/string.h>
#include <linux/list.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/delay.h>
@@ -172,29 +173,26 @@ enum {
TPACPI_RFK_UWB_SW_ID,
};
-/* Debugging */
+/* printk headers */
#define TPACPI_LOG TPACPI_FILE ": "
-#define TPACPI_ALERT KERN_ALERT TPACPI_LOG
-#define TPACPI_CRIT KERN_CRIT TPACPI_LOG
-#define TPACPI_ERR KERN_ERR TPACPI_LOG
-#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
-#define TPACPI_INFO KERN_INFO TPACPI_LOG
-#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG
-
+#define TPACPI_EMERG KERN_EMERG TPACPI_LOG
+#define TPACPI_ALERT KERN_ALERT TPACPI_LOG
+#define TPACPI_CRIT KERN_CRIT TPACPI_LOG
+#define TPACPI_ERR KERN_ERR TPACPI_LOG
+#define TPACPI_WARN KERN_WARNING TPACPI_LOG
+#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
+#define TPACPI_INFO KERN_INFO TPACPI_LOG
+#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG
+
+/* Debugging printk groups */
#define TPACPI_DBG_ALL 0xffff
+#define TPACPI_DBG_DISCLOSETASK 0x8000
#define TPACPI_DBG_INIT 0x0001
#define TPACPI_DBG_EXIT 0x0002
-#define dbg_printk(a_dbg_level, format, arg...) \
- do { if (dbg_level & a_dbg_level) \
- printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
- } while (0)
-#ifdef CONFIG_THINKPAD_ACPI_DEBUG
-#define vdbg_printk(a_dbg_level, format, arg...) \
- dbg_printk(a_dbg_level, format, ## arg)
-static const char *str_supported(int is_supported);
-#else
-#define vdbg_printk(a_dbg_level, format, arg...)
-#endif
+#define TPACPI_DBG_RFKILL 0x0004
+#define TPACPI_DBG_HKEY 0x0008
+#define TPACPI_DBG_FAN 0x0010
+#define TPACPI_DBG_BRGHT 0x0020
#define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off")
#define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
@@ -277,7 +275,6 @@ static struct {
static struct {
u16 hotkey_mask_ff:1;
- u16 bright_cmos_ec_unsync:1;
} tp_warned;
struct thinkpad_id_data {
@@ -326,6 +323,39 @@ static int tpacpi_uwb_emulstate;
#endif
+/*************************************************************************
+ * Debugging helpers
+ */
+
+#define dbg_printk(a_dbg_level, format, arg...) \
+ do { if (dbg_level & (a_dbg_level)) \
+ printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
+ } while (0)
+
+#ifdef CONFIG_THINKPAD_ACPI_DEBUG
+#define vdbg_printk dbg_printk
+static const char *str_supported(int is_supported);
+#else
+#define vdbg_printk(a_dbg_level, format, arg...) \
+ do { } while (0)
+#endif
+
+static void tpacpi_log_usertask(const char * const what)
+{
+ printk(TPACPI_DEBUG "%s: access by process with PID %d\n",
+ what, task_tgid_vnr(current));
+}
+
+#define tpacpi_disclose_usertask(what, format, arg...) \
+ do { \
+ if (unlikely( \
+ (dbg_level & TPACPI_DBG_DISCLOSETASK) && \
+ (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \
+ printk(TPACPI_DEBUG "%s: PID %d: " format, \
+ what, task_tgid_vnr(current), ## arg); \
+ } \
+ } while (0)
+
/****************************************************************************
****************************************************************************
*
@@ -989,10 +1019,13 @@ static int __init tpacpi_new_rfkill(const unsigned int id,
/* try to set the initial state as the default for the rfkill
* type, since we ask the firmware to preserve it across S5 in
* NVRAM */
- rfkill_set_default(rfktype,
+ if (rfkill_set_default(rfktype,
(initial_state == RFKILL_STATE_UNBLOCKED) ?
RFKILL_STATE_UNBLOCKED :
- RFKILL_STATE_SOFT_BLOCKED);
+ RFKILL_STATE_SOFT_BLOCKED) == -EPERM)
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "Default state for %s cannot be changed\n",
+ name);
}
*rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype);
@@ -1020,6 +1053,21 @@ static int __init tpacpi_new_rfkill(const unsigned int id,
return 0;
}
+static void printk_deprecated_attribute(const char * const what,
+ const char * const details)
+{
+ tpacpi_log_usertask("deprecated sysfs attribute");
+ printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and "
+ "will be removed. %s\n",
+ what, details);
+}
+
+static void printk_deprecated_rfkill_attribute(const char * const what)
+{
+ printk_deprecated_attribute(what,
+ "Please switch to generic rfkill before year 2010");
+}
+
/*************************************************************************
* thinkpad-acpi driver attributes
*/
@@ -1382,7 +1430,6 @@ static enum { /* Reasons for waking up */
static int hotkey_autosleep_ack;
-static int hotkey_orig_status;
static u32 hotkey_orig_mask;
static u32 hotkey_all_mask;
static u32 hotkey_reserved_mask;
@@ -1529,9 +1576,9 @@ static int hotkey_status_get(int *status)
return 0;
}
-static int hotkey_status_set(int status)
+static int hotkey_status_set(bool enable)
{
- if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
+ if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", enable ? 1 : 0))
return -EIO;
return 0;
@@ -1847,6 +1894,9 @@ static ssize_t hotkey_enable_show(struct device *dev,
{
int res, status;
+ printk_deprecated_attribute("hotkey_enable",
+ "Hotkey reporting is always enabled");
+
res = hotkey_status_get(&status);
if (res)
return res;
@@ -1859,14 +1909,17 @@ static ssize_t hotkey_enable_store(struct device *dev,
const char *buf, size_t count)
{
unsigned long t;
- int res;
+
+ printk_deprecated_attribute("hotkey_enable",
+ "Hotkeys can be disabled through hotkey_mask");
if (parse_strtoul(buf, 1, &t))
return -EINVAL;
- res = hotkey_status_set(t);
+ if (t == 0)
+ return -EPERM;
- return (res) ? res : count;
+ return count;
}
static struct device_attribute dev_attr_hotkey_enable =
@@ -1910,6 +1963,8 @@ static ssize_t hotkey_mask_store(struct device *dev,
mutex_unlock(&hotkey_mutex);
+ tpacpi_disclose_usertask("hotkey_mask", "set to 0x%08lx\n", t);
+
return (res) ? res : count;
}
@@ -1922,7 +1977,7 @@ static ssize_t hotkey_bios_enabled_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status);
+ return sprintf(buf, "0\n");
}
static struct device_attribute dev_attr_hotkey_bios_enabled =
@@ -1996,6 +2051,8 @@ static ssize_t hotkey_source_mask_store(struct device *dev,
mutex_unlock(&hotkey_mutex);
+ tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);
+
return count;
}
@@ -2028,6 +2085,8 @@ static ssize_t hotkey_poll_freq_store(struct device *dev,
hotkey_poll_setup(1);
mutex_unlock(&hotkey_mutex);
+ tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t);
+
return count;
}
@@ -2197,11 +2256,11 @@ static void hotkey_exit(void)
kfree(hotkey_keycode_map);
if (tp_features.hotkey) {
- dbg_printk(TPACPI_DBG_EXIT,
+ dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,
"restoring original hot key mask\n");
/* no short-circuit boolean operator below! */
if ((hotkey_mask_set(hotkey_orig_mask) |
- hotkey_status_set(hotkey_orig_status)) != 0)
+ hotkey_status_set(false)) != 0)
printk(TPACPI_ERR
"failed to restore hot key mask "
"to BIOS defaults\n");
@@ -2327,7 +2386,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
int status;
int hkeyv;
- vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "initializing hotkey subdriver\n");
BUG_ON(!tpacpi_inputdev);
BUG_ON(tpacpi_inputdev->open != NULL ||
@@ -2344,7 +2404,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
/* hotkey not supported on 570 */
tp_features.hotkey = hkey_handle != NULL;
- vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "hotkeys are %s\n",
str_supported(tp_features.hotkey));
if (!tp_features.hotkey)
@@ -2376,10 +2437,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
* T4x, X31, and later
*/
tp_features.hotkey_mask = 1;
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "firmware HKEY interface version: 0x%x\n",
+ hkeyv);
}
}
- vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "hotkey masks are %s\n",
str_supported(tp_features.hotkey_mask));
if (tp_features.hotkey_mask) {
@@ -2396,10 +2461,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
/* hotkey_source_mask *must* be zero for
* the first hotkey_mask_get */
- res = hotkey_status_get(&hotkey_orig_status);
- if (res)
- goto err_exit;
-
if (tp_features.hotkey_mask) {
res = hotkey_mask_get();
if (res)
@@ -2422,7 +2483,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK;
}
- vdbg_printk(TPACPI_DBG_INIT,
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"hotkey source mask 0x%08x, polling freq %d\n",
hotkey_source_mask, hotkey_poll_freq);
#endif
@@ -2476,12 +2537,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
}
if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"using Lenovo default hot key map\n");
memcpy(hotkey_keycode_map, &lenovo_keycode_map,
TPACPI_HOTKEY_MAP_SIZE);
} else {
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"using IBM default hot key map\n");
memcpy(hotkey_keycode_map, &ibm_keycode_map,
TPACPI_HOTKEY_MAP_SIZE);
@@ -2538,8 +2599,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
| (1 << TP_ACPI_HOTKEYSCAN_FNEND);
}
- dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n");
- res = hotkey_status_set(1);
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "enabling firmware HKEY event interface...\n");
+ res = hotkey_status_set(true);
if (res) {
hotkey_exit();
return res;
@@ -2552,8 +2614,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
return res;
}
- dbg_printk(TPACPI_DBG_INIT,
- "legacy hot key reporting over procfs %s\n",
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "legacy ibm/hotkey event reporting over procfs %s\n",
(hotkey_report_mode < 2) ?
"enabled" : "disabled");
@@ -2884,9 +2946,17 @@ static int hotkey_read(char *p)
return len;
}
+static void hotkey_enabledisable_warn(void)
+{
+ tpacpi_log_usertask("procfs hotkey enable/disable");
+ WARN(1, TPACPI_WARN
+ "hotkey enable/disable functionality has been "
+ "removed from the driver. Hotkeys are always enabled.\n");
+}
+
static int hotkey_write(char *buf)
{
- int res, status;
+ int res;
u32 mask;
char *cmd;
@@ -2896,17 +2966,16 @@ static int hotkey_write(char *buf)
if (mutex_lock_killable(&hotkey_mutex))
return -ERESTARTSYS;
- status = -1;
mask = hotkey_mask;
res = 0;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) {
- status = 1;
+ hotkey_enabledisable_warn();
} else if (strlencmp(cmd, "disable") == 0) {
- status = 0;
+ hotkey_enabledisable_warn();
+ res = -EPERM;
} else if (strlencmp(cmd, "reset") == 0) {
- status = hotkey_orig_status;
mask = hotkey_orig_mask;
} else if (sscanf(cmd, "0x%x", &mask) == 1) {
/* mask set */
@@ -2917,8 +2986,10 @@ static int hotkey_write(char *buf)
goto errexit;
}
}
- if (status != -1)
- res = hotkey_status_set(status);
+
+ if (!res)
+ tpacpi_disclose_usertask("procfs hotkey",
+ "set mask to 0x%08x\n", mask);
if (!res && mask != hotkey_mask)
res = hotkey_mask_set(mask);
@@ -2971,13 +3042,17 @@ enum {
TP_ACPI_BLTH_SAVE_STATE = 0x05, /* Save state for S4/S5 */
};
+#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"
+
static struct rfkill *tpacpi_bluetooth_rfkill;
static void bluetooth_suspend(pm_message_t state)
{
/* Try to make sure radio will resume powered off */
- acpi_evalf(NULL, NULL, "\\BLTH", "vd",
- TP_ACPI_BLTH_PWR_OFF_ON_RESUME);
+ if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
+ TP_ACPI_BLTH_PWR_OFF_ON_RESUME))
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "bluetooth power down on resume request failed\n");
}
static int bluetooth_get_radiosw(void)
@@ -3015,6 +3090,10 @@ static void bluetooth_update_rfk(void)
if (status < 0)
return;
rfkill_force_state(tpacpi_bluetooth_rfkill, status);
+
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "forced rfkill state to %d\n",
+ status);
}
static int bluetooth_set_radiosw(int radio_on, int update_rfk)
@@ -3030,6 +3109,9 @@ static int bluetooth_set_radiosw(int radio_on, int update_rfk)
&& radio_on)
return -EPERM;
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "will %s bluetooth\n", radio_on ? "enable" : "disable");
+
#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
if (dbg_bluetoothemul) {
tpacpi_bluetooth_emulstate = !!radio_on;
@@ -3060,6 +3142,8 @@ static ssize_t bluetooth_enable_show(struct device *dev,
{
int status;
+ printk_deprecated_rfkill_attribute("bluetooth_enable");
+
status = bluetooth_get_radiosw();
if (status < 0)
return status;
@@ -3075,9 +3159,13 @@ static ssize_t bluetooth_enable_store(struct device *dev,
unsigned long t;
int res;
+ printk_deprecated_rfkill_attribute("bluetooth_enable");
+
if (parse_strtoul(buf, 1, &t))
return -EINVAL;
+ tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t);
+
res = bluetooth_set_radiosw(t, 1);
return (res) ? res : count;
@@ -3111,6 +3199,8 @@ static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state)
static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
{
+ dbg_printk(TPACPI_DBG_RFKILL,
+ "request to change radio state to %d\n", state);
return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
}
@@ -3121,6 +3211,9 @@ static void bluetooth_shutdown(void)
TP_ACPI_BLTH_SAVE_STATE))
printk(TPACPI_NOTICE
"failed to save bluetooth state to NVRAM\n");
+ else
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "bluestooth state saved to NVRAM\n");
}
static void bluetooth_exit(void)
@@ -3139,7 +3232,8 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
int res;
int status = 0;
- vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "initializing bluetooth subdriver\n");
TPACPI_ACPIHANDLE_INIT(hkey);
@@ -3148,7 +3242,8 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
tp_features.bluetooth = hkey_handle &&
acpi_evalf(hkey_handle, &status, "GBDC", "qd");
- vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "bluetooth is %s, status 0x%02x\n",
str_supported(tp_features.bluetooth),
status);
@@ -3163,7 +3258,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
!(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
/* no bluetooth hardware present in system */
tp_features.bluetooth = 0;
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
"bluetooth hardware not installed\n");
}
@@ -3178,7 +3273,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
&tpacpi_bluetooth_rfkill,
RFKILL_TYPE_BLUETOOTH,
- "tpacpi_bluetooth_sw",
+ TPACPI_RFK_BLUETOOTH_SW_NAME,
true,
tpacpi_bluetooth_rfk_set,
tpacpi_bluetooth_rfk_get);
@@ -3211,19 +3306,27 @@ static int bluetooth_read(char *p)
static int bluetooth_write(char *buf)
{
char *cmd;
+ int state = -1;
if (!tp_features.bluetooth)
return -ENODEV;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) {
- bluetooth_set_radiosw(1, 1);
+ state = 1;
} else if (strlencmp(cmd, "disable") == 0) {
- bluetooth_set_radiosw(0, 1);
+ state = 0;
} else
return -EINVAL;
}
+ if (state != -1) {
+ tpacpi_disclose_usertask("procfs bluetooth",
+ "attempt to %s\n",
+ state ? "enable" : "disable");
+ bluetooth_set_radiosw(state, 1);
+ }
+
return 0;
}
@@ -3248,13 +3351,17 @@ enum {
off / last state */
};
+#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
+
static struct rfkill *tpacpi_wan_rfkill;
static void wan_suspend(pm_message_t state)
{
/* Try to make sure radio will resume powered off */
- acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
- TP_ACPI_WGSV_PWR_OFF_ON_RESUME);
+ if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
+ TP_ACPI_WGSV_PWR_OFF_ON_RESUME))
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "WWAN power down on resume request failed\n");
}
static int wan_get_radiosw(void)
@@ -3292,6 +3399,10 @@ static void wan_update_rfk(void)
if (status < 0)
return;
rfkill_force_state(tpacpi_wan_rfkill, status);
+
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "forced rfkill state to %d\n",
+ status);
}
static int wan_set_radiosw(int radio_on, int update_rfk)
@@ -3307,6 +3418,9 @@ static int wan_set_radiosw(int radio_on, int update_rfk)
&& radio_on)
return -EPERM;
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "will %s WWAN\n", radio_on ? "enable" : "disable");
+
#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
if (dbg_wwanemul) {
tpacpi_wwan_emulstate = !!radio_on;
@@ -3337,6 +3451,8 @@ static ssize_t wan_enable_show(struct device *dev,
{
int status;
+ printk_deprecated_rfkill_attribute("wwan_enable");
+
status = wan_get_radiosw();
if (status < 0)
return status;
@@ -3352,9 +3468,13 @@ static ssize_t wan_enable_store(struct device *dev,
unsigned long t;
int res;
+ printk_deprecated_rfkill_attribute("wwan_enable");
+
if (parse_strtoul(buf, 1, &t))
return -EINVAL;
+ tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t);
+
res = wan_set_radiosw(t, 1);
return (res) ? res : count;
@@ -3388,6 +3508,8 @@ static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state)
static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
{
+ dbg_printk(TPACPI_DBG_RFKILL,
+ "request to change radio state to %d\n", state);
return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
}
@@ -3398,6 +3520,9 @@ static void wan_shutdown(void)
TP_ACPI_WGSV_SAVE_STATE))
printk(TPACPI_NOTICE
"failed to save WWAN state to NVRAM\n");
+ else
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "WWAN state saved to NVRAM\n");
}
static void wan_exit(void)
@@ -3416,14 +3541,16 @@ static int __init wan_init(struct ibm_init_struct *iibm)
int res;
int status = 0;
- vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "initializing wan subdriver\n");
TPACPI_ACPIHANDLE_INIT(hkey);
tp_features.wan = hkey_handle &&
acpi_evalf(hkey_handle, &status, "GWAN", "qd");
- vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "wan is %s, status 0x%02x\n",
str_supported(tp_features.wan),
status);
@@ -3438,7 +3565,7 @@ static int __init wan_init(struct ibm_init_struct *iibm)
!(status & TP_ACPI_WANCARD_HWPRESENT)) {
/* no wan hardware present in system */
tp_features.wan = 0;
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
"wan hardware not installed\n");
}
@@ -3453,7 +3580,7 @@ static int __init wan_init(struct ibm_init_struct *iibm)
res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
&tpacpi_wan_rfkill,
RFKILL_TYPE_WWAN,
- "tpacpi_wwan_sw",
+ TPACPI_RFK_WWAN_SW_NAME,
true,
tpacpi_wan_rfk_set,
tpacpi_wan_rfk_get);
@@ -3471,6 +3598,8 @@ static int wan_read(char *p)
int len = 0;
int status = wan_get_radiosw();
+ tpacpi_disclose_usertask("procfs wan", "read");
+
if (!tp_features.wan)
len += sprintf(p + len, "status:\t\tnot supported\n");
else {
@@ -3486,19 +3615,27 @@ static int wan_read(char *p)
static int wan_write(char *buf)
{
char *cmd;
+ int state = -1;
if (!tp_features.wan)
return -ENODEV;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) {
- wan_set_radiosw(1, 1);
+ state = 1;
} else if (strlencmp(cmd, "disable") == 0) {
- wan_set_radiosw(0, 1);
+ state = 0;
} else
return -EINVAL;
}
+ if (state != -1) {
+ tpacpi_disclose_usertask("procfs wan",
+ "attempt to %s\n",
+ state ? "enable" : "disable");
+ wan_set_radiosw(state, 1);
+ }
+
return 0;
}
@@ -3521,6 +3658,8 @@ enum {
TP_ACPI_UWB_RADIOSSW = 0x02, /* UWB radio enabled */
};
+#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw"
+
static struct rfkill *tpacpi_uwb_rfkill;
static int uwb_get_radiosw(void)
@@ -3558,6 +3697,10 @@ static void uwb_update_rfk(void)
if (status < 0)
return;
rfkill_force_state(tpacpi_uwb_rfkill, status);
+
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "forced rfkill state to %d\n",
+ status);
}
static int uwb_set_radiosw(int radio_on, int update_rfk)
@@ -3573,6 +3716,9 @@ static int uwb_set_radiosw(int radio_on, int update_rfk)
&& radio_on)
return -EPERM;
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "will %s UWB\n", radio_on ? "enable" : "disable");
+
#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
if (dbg_uwbemul) {
tpacpi_uwb_emulstate = !!radio_on;
@@ -3607,6 +3753,8 @@ static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state)
static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state)
{
+ dbg_printk(TPACPI_DBG_RFKILL,
+ "request to change radio state to %d\n", state);
return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
}
@@ -3621,14 +3769,16 @@ static int __init uwb_init(struct ibm_init_struct *iibm)
int res;
int status = 0;
- vdbg_printk(TPACPI_DBG_INIT, "initializing uwb subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "initializing uwb subdriver\n");
TPACPI_ACPIHANDLE_INIT(hkey);
tp_features.uwb = hkey_handle &&
acpi_evalf(hkey_handle, &status, "GUWB", "qd");
- vdbg_printk(TPACPI_DBG_INIT, "uwb is %s, status 0x%02x\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "uwb is %s, status 0x%02x\n",
str_supported(tp_features.uwb),
status);
@@ -3653,7 +3803,7 @@ static int __init uwb_init(struct ibm_init_struct *iibm)
res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
&tpacpi_uwb_rfkill,
RFKILL_TYPE_UWB,
- "tpacpi_uwb_sw",
+ TPACPI_RFK_UWB_SW_NAME,
false,
tpacpi_uwb_rfk_set,
tpacpi_uwb_rfk_get);
@@ -4602,6 +4752,16 @@ static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
"tpacpi::unknown_led",
"tpacpi::standby",
};
+#define TPACPI_SAFE_LEDS 0x0081U
+
+static inline bool tpacpi_is_led_restricted(const unsigned int led)
+{
+#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
+ return false;
+#else
+ return (TPACPI_SAFE_LEDS & (1 << led)) == 0;
+#endif
+}
static int led_get_status(const unsigned int led)
{
@@ -4639,16 +4799,20 @@ static int led_set_status(const unsigned int led,
switch (led_supported) {
case TPACPI_LED_570:
/* 570 */
- if (led > 7)
+ if (unlikely(led > 7))
return -EINVAL;
+ if (unlikely(tpacpi_is_led_restricted(led)))
+ return -EPERM;
if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
(1 << led), led_sled_arg1[ledstatus]))
rc = -EIO;
break;
case TPACPI_LED_OLD:
/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
- if (led > 7)
+ if (unlikely(led > 7))
return -EINVAL;
+ if (unlikely(tpacpi_is_led_restricted(led)))
+ return -EPERM;
rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led));
if (rc >= 0)
rc = ec_write(TPACPI_LED_EC_HLBL,
@@ -4659,6 +4823,10 @@ static int led_set_status(const unsigned int led,
break;
case TPACPI_LED_NEW:
/* all others */
+ if (unlikely(led >= TPACPI_LED_NUMLEDS))
+ return -EINVAL;
+ if (unlikely(tpacpi_is_led_restricted(led)))
+ return -EPERM;
if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
led, led_led_arg1[ledstatus]))
rc = -EIO;
@@ -4751,6 +4919,30 @@ static void led_exit(void)
kfree(tpacpi_leds);
}
+static int __init tpacpi_init_led(unsigned int led)
+{
+ int rc;
+
+ tpacpi_leds[led].led = led;
+
+ tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set;
+ tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set;
+ if (led_supported == TPACPI_LED_570)
+ tpacpi_leds[led].led_classdev.brightness_get =
+ &led_sysfs_get;
+
+ tpacpi_leds[led].led_classdev.name = tpacpi_led_names[led];
+
+ INIT_WORK(&tpacpi_leds[led].work, led_set_status_worker);
+
+ rc = led_classdev_register(&tpacpi_pdev->dev,
+ &tpacpi_leds[led].led_classdev);
+ if (rc < 0)
+ tpacpi_leds[led].led_classdev.name = NULL;
+
+ return rc;
+}
+
static int __init led_init(struct ibm_init_struct *iibm)
{
unsigned int i;
@@ -4784,27 +4976,21 @@ static int __init led_init(struct ibm_init_struct *iibm)
}
for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
- tpacpi_leds[i].led = i;
-
- tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set;
- tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set;
- if (led_supported == TPACPI_LED_570)
- tpacpi_leds[i].led_classdev.brightness_get =
- &led_sysfs_get;
-
- tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i];
-
- INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker);
-
- rc = led_classdev_register(&tpacpi_pdev->dev,
- &tpacpi_leds[i].led_classdev);
- if (rc < 0) {
- tpacpi_leds[i].led_classdev.name = NULL;
- led_exit();
- return rc;
+ if (!tpacpi_is_led_restricted(i)) {
+ rc = tpacpi_init_led(i);
+ if (rc < 0) {
+ led_exit();
+ return rc;
+ }
}
}
+#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
+ if (led_supported != TPACPI_LED_NONE)
+ printk(TPACPI_NOTICE
+ "warning: userspace override of important "
+ "firmware LEDs is enabled\n");
+#endif
return (led_supported != TPACPI_LED_NONE)? 0 : 1;
}
@@ -5340,6 +5526,20 @@ static struct ibm_struct ecdump_driver_data = {
#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
+/*
+ * ThinkPads can read brightness from two places: EC HBRV (0x31), or
+ * CMOS NVRAM byte 0x5E, bits 0-3.
+ *
+ * EC HBRV (0x31) has the following layout
+ * Bit 7: unknown function
+ * Bit 6: unknown function
+ * Bit 5: Z: honour scale changes, NZ: ignore scale changes
+ * Bit 4: must be set to zero to avoid problems
+ * Bit 3-0: backlight brightness level
+ *
+ * brightness_get_raw returns status data in the HBRV layout
+ */
+
enum {
TP_EC_BACKLIGHT = 0x31,
@@ -5349,108 +5549,164 @@ enum {
TP_EC_BACKLIGHT_MAPSW = 0x20,
};
+enum tpacpi_brightness_access_mode {
+ TPACPI_BRGHT_MODE_AUTO = 0, /* Not implemented yet */
+ TPACPI_BRGHT_MODE_EC, /* EC control */
+ TPACPI_BRGHT_MODE_UCMS_STEP, /* UCMS step-based control */
+ TPACPI_BRGHT_MODE_ECNVRAM, /* EC control w/ NVRAM store */
+ TPACPI_BRGHT_MODE_MAX
+};
+
static struct backlight_device *ibm_backlight_device;
-static int brightness_mode;
+
+static enum tpacpi_brightness_access_mode brightness_mode =
+ TPACPI_BRGHT_MODE_MAX;
+
static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
static struct mutex brightness_mutex;
-/*
- * ThinkPads can read brightness from two places: EC 0x31, or
- * CMOS NVRAM byte 0x5E, bits 0-3.
- *
- * EC 0x31 has the following layout
- * Bit 7: unknown function
- * Bit 6: unknown function
- * Bit 5: Z: honour scale changes, NZ: ignore scale changes
- * Bit 4: must be set to zero to avoid problems
- * Bit 3-0: backlight brightness level
- *
- * brightness_get_raw returns status data in the EC 0x31 layout
- */
-static int brightness_get_raw(int *status)
+/* NVRAM brightness access,
+ * call with brightness_mutex held! */
+static unsigned int tpacpi_brightness_nvram_get(void)
{
- u8 lec = 0, lcmos = 0, level = 0;
+ u8 lnvram;
- if (brightness_mode & 1) {
- if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec))
- return -EIO;
- level = lec & TP_EC_BACKLIGHT_LVLMSK;
- };
- if (brightness_mode & 2) {
- lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
- & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
- >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
- lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07;
- level = lcmos;
- }
-
- if (brightness_mode == 3) {
- *status = lec; /* Prefer EC, CMOS is just a backing store */
- lec &= TP_EC_BACKLIGHT_LVLMSK;
- if (lec == lcmos)
- tp_warned.bright_cmos_ec_unsync = 0;
- else {
- if (!tp_warned.bright_cmos_ec_unsync) {
- printk(TPACPI_ERR
- "CMOS NVRAM (%u) and EC (%u) do not "
- "agree on display brightness level\n",
- (unsigned int) lcmos,
- (unsigned int) lec);
- tp_warned.bright_cmos_ec_unsync = 1;
- }
+ lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
+ & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
+ >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
+ lnvram &= (tp_features.bright_16levels) ? 0x0f : 0x07;
+
+ return lnvram;
+}
+
+static void tpacpi_brightness_checkpoint_nvram(void)
+{
+ u8 lec = 0;
+ u8 b_nvram;
+
+ if (brightness_mode != TPACPI_BRGHT_MODE_ECNVRAM)
+ return;
+
+ vdbg_printk(TPACPI_DBG_BRGHT,
+ "trying to checkpoint backlight level to NVRAM...\n");
+
+ if (mutex_lock_killable(&brightness_mutex) < 0)
+ return;
+
+ if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
+ goto unlock;
+ lec &= TP_EC_BACKLIGHT_LVLMSK;
+ b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
+
+ if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
+ >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
+ /* NVRAM needs update */
+ b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
+ TP_NVRAM_POS_LEVEL_BRIGHTNESS);
+ b_nvram |= lec;
+ nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
+ dbg_printk(TPACPI_DBG_BRGHT,
+ "updated NVRAM backlight level to %u (0x%02x)\n",
+ (unsigned int) lec, (unsigned int) b_nvram);
+ } else
+ vdbg_printk(TPACPI_DBG_BRGHT,
+ "NVRAM backlight level already is %u (0x%02x)\n",
+ (unsigned int) lec, (unsigned int) b_nvram);
+
+unlock:
+ mutex_unlock(&brightness_mutex);
+}
+
+
+/* call with brightness_mutex held! */
+static int tpacpi_brightness_get_raw(int *status)
+{
+ u8 lec = 0;
+
+ switch (brightness_mode) {
+ case TPACPI_BRGHT_MODE_UCMS_STEP:
+ *status = tpacpi_brightness_nvram_get();
+ return 0;
+ case TPACPI_BRGHT_MODE_EC:
+ case TPACPI_BRGHT_MODE_ECNVRAM:
+ if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
return -EIO;
- }
- } else {
- *status = level;
+ *status = lec;
+ return 0;
+ default:
+ return -ENXIO;
}
+}
+
+/* call with brightness_mutex held! */
+/* do NOT call with illegal backlight level value */
+static int tpacpi_brightness_set_ec(unsigned int value)
+{
+ u8 lec = 0;
+
+ if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
+ return -EIO;
+
+ if (unlikely(!acpi_ec_write(TP_EC_BACKLIGHT,
+ (lec & TP_EC_BACKLIGHT_CMDMSK) |
+ (value & TP_EC_BACKLIGHT_LVLMSK))))
+ return -EIO;
+
+ return 0;
+}
+
+/* call with brightness_mutex held! */
+static int tpacpi_brightness_set_ucmsstep(unsigned int value)
+{
+ int cmos_cmd, inc;
+ unsigned int current_value, i;
+
+ current_value = tpacpi_brightness_nvram_get();
+
+ if (value == current_value)
+ return 0;
+
+ cmos_cmd = (value > current_value) ?
+ TP_CMOS_BRIGHTNESS_UP :
+ TP_CMOS_BRIGHTNESS_DOWN;
+ inc = (value > current_value) ? 1 : -1;
+
+ for (i = current_value; i != value; i += inc)
+ if (issue_thinkpad_cmos_command(cmos_cmd))
+ return -EIO;
return 0;
}
/* May return EINTR which can always be mapped to ERESTARTSYS */
-static int brightness_set(int value)
+static int brightness_set(unsigned int value)
{
- int cmos_cmd, inc, i, res;
- int current_value;
- int command_bits;
+ int res;
if (value > ((tp_features.bright_16levels)? 15 : 7) ||
value < 0)
return -EINVAL;
+ vdbg_printk(TPACPI_DBG_BRGHT,
+ "set backlight level to %d\n", value);
+
res = mutex_lock_killable(&brightness_mutex);
if (res < 0)
return res;
- res = brightness_get_raw(&current_value);
- if (res < 0)
- goto errout;
-
- command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK;
- current_value &= TP_EC_BACKLIGHT_LVLMSK;
-
- cmos_cmd = value > current_value ?
- TP_CMOS_BRIGHTNESS_UP :
- TP_CMOS_BRIGHTNESS_DOWN;
- inc = (value > current_value)? 1 : -1;
-
- res = 0;
- for (i = current_value; i != value; i += inc) {
- if ((brightness_mode & 2) &&
- issue_thinkpad_cmos_command(cmos_cmd)) {
- res = -EIO;
- goto errout;
- }
- if ((brightness_mode & 1) &&
- !acpi_ec_write(TP_EC_BACKLIGHT,
- (i + inc) | command_bits)) {
- res = -EIO;
- goto errout;;
- }
+ switch (brightness_mode) {
+ case TPACPI_BRGHT_MODE_EC:
+ case TPACPI_BRGHT_MODE_ECNVRAM:
+ res = tpacpi_brightness_set_ec(value);
+ break;
+ case TPACPI_BRGHT_MODE_UCMS_STEP:
+ res = tpacpi_brightness_set_ucmsstep(value);
+ break;
+ default:
+ res = -ENXIO;
}
-errout:
mutex_unlock(&brightness_mutex);
return res;
}
@@ -5459,21 +5715,34 @@ errout:
static int brightness_update_status(struct backlight_device *bd)
{
- /* it is the backlight class's job (caller) to handle
- * EINTR and other errors properly */
- return brightness_set(
+ unsigned int level =
(bd->props.fb_blank == FB_BLANK_UNBLANK &&
bd->props.power == FB_BLANK_UNBLANK) ?
- bd->props.brightness : 0);
+ bd->props.brightness : 0;
+
+ dbg_printk(TPACPI_DBG_BRGHT,
+ "backlight: attempt to set level to %d\n",
+ level);
+
+ /* it is the backlight class's job (caller) to handle
+ * EINTR and other errors properly */
+ return brightness_set(level);
}
static int brightness_get(struct backlight_device *bd)
{
int status, res;
- res = brightness_get_raw(&status);
+ res = mutex_lock_killable(&brightness_mutex);
if (res < 0)
- return 0; /* FIXME: teach backlight about error handling */
+ return 0;
+
+ res = tpacpi_brightness_get_raw(&status);
+
+ mutex_unlock(&brightness_mutex);
+
+ if (res < 0)
+ return 0;
return status & TP_EC_BACKLIGHT_LVLMSK;
}
@@ -5523,7 +5792,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
}
if (!brightness_enable) {
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
"brightness support disabled by "
"module parameter\n");
return 1;
@@ -5538,20 +5807,38 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
if (b == 16)
tp_features.bright_16levels = 1;
- if (!brightness_mode) {
- if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
- brightness_mode = 2;
- else
- brightness_mode = 3;
+ /*
+ * Check for module parameter bogosity, note that we
+ * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be
+ * able to detect "unspecified"
+ */
+ if (brightness_mode > TPACPI_BRGHT_MODE_MAX)
+ return -EINVAL;
- dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n",
- brightness_mode);
- }
+ /* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */
+ if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||
+ brightness_mode == TPACPI_BRGHT_MODE_MAX) {
+ if (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) {
+ /*
+ * IBM models that define HBRV probably have
+ * EC-based backlight level control
+ */
+ if (acpi_evalf(ec_handle, NULL, "HBRV", "qd"))
+ /* T40-T43, R50-R52, R50e, R51e, X31-X41 */
+ brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
+ else
+ /* all other IBM ThinkPads */
+ brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
+ } else
+ /* All Lenovo ThinkPads */
+ brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
- if (brightness_mode > 3)
- return -EINVAL;
+ dbg_printk(TPACPI_DBG_BRGHT,
+ "selected brightness_mode=%d\n",
+ brightness_mode);
+ }
- if (brightness_get_raw(&b) < 0)
+ if (tpacpi_brightness_get_raw(&b) < 0)
return 1;
if (tp_features.bright_16levels)
@@ -5565,7 +5852,8 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
printk(TPACPI_ERR "Could not register backlight device\n");
return PTR_ERR(ibm_backlight_device);
}
- vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
+ "brightness is supported\n");
ibm_backlight_device->props.max_brightness =
(tp_features.bright_16levels)? 15 : 7;
@@ -5575,13 +5863,25 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
return 0;
}
+static void brightness_suspend(pm_message_t state)
+{
+ tpacpi_brightness_checkpoint_nvram();
+}
+
+static void brightness_shutdown(void)
+{
+ tpacpi_brightness_checkpoint_nvram();
+}
+
static void brightness_exit(void)
{
if (ibm_backlight_device) {
- vdbg_printk(TPACPI_DBG_EXIT,
+ vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_BRGHT,
"calling backlight_device_unregister()\n");
backlight_device_unregister(ibm_backlight_device);
}
+
+ tpacpi_brightness_checkpoint_nvram();
}
static int brightness_read(char *p)
@@ -5628,6 +5928,9 @@ static int brightness_write(char *buf)
return -EINVAL;
}
+ tpacpi_disclose_usertask("procfs brightness",
+ "set level to %d\n", level);
+
/*
* Now we know what the final level should be, so we try to set it.
* Doing it this way makes the syscall restartable in case of EINTR
@@ -5641,6 +5944,8 @@ static struct ibm_struct brightness_driver_data = {
.read = brightness_read,
.write = brightness_write,
.exit = brightness_exit,
+ .suspend = brightness_suspend,
+ .shutdown = brightness_shutdown,
};
/*************************************************************************
@@ -5811,7 +6116,7 @@ static struct ibm_struct volume_driver_data = {
* ThinkPads from this same time period (and earlier) probably lack the
* tachometer as well.
*
- * Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare
+ * Unfortunately a lot of ThinkPads with new-style ECs but whose firmware
* was never fixed by IBM to report the EC firmware version string
* probably support the tachometer (like the early X models), so
* detecting it is quite hard. We need more data to know for sure.
@@ -6086,6 +6391,9 @@ static int fan_set_level(int level)
default:
return -ENXIO;
}
+
+ vdbg_printk(TPACPI_DBG_FAN,
+ "fan control: set fan control register to 0x%02x\n", level);
return 0;
}
@@ -6163,6 +6471,11 @@ static int fan_set_enable(void)
}
mutex_unlock(&fan_mutex);
+
+ if (!rc)
+ vdbg_printk(TPACPI_DBG_FAN,
+ "fan control: set fan control register to 0x%02x\n",
+ s);
return rc;
}
@@ -6199,6 +6512,9 @@ static int fan_set_disable(void)
rc = -ENXIO;
}
+ if (!rc)
+ vdbg_printk(TPACPI_DBG_FAN,
+ "fan control: set fan control register to 0\n");
mutex_unlock(&fan_mutex);
return rc;
@@ -6327,6 +6643,9 @@ static ssize_t fan_pwm1_enable_store(struct device *dev,
if (parse_strtoul(buf, 2, &t))
return -EINVAL;
+ tpacpi_disclose_usertask("hwmon pwm1_enable",
+ "set fan mode to %lu\n", t);
+
switch (t) {
case 0:
level = TP_EC_FAN_FULLSPEED;
@@ -6392,6 +6711,9 @@ static ssize_t fan_pwm1_store(struct device *dev,
if (parse_strtoul(buf, 255, &s))
return -EINVAL;
+ tpacpi_disclose_usertask("hwmon pwm1",
+ "set fan speed to %lu\n", s);
+
/* scale down from 0-255 to 0-7 */
newlevel = (s >> 5) & 0x07;
@@ -6458,6 +6780,8 @@ static ssize_t fan_fan_watchdog_store(struct device_driver *drv,
fan_watchdog_maxinterval = t;
fan_watchdog_reset();
+ tpacpi_disclose_usertask("fan_watchdog", "set to %lu\n", t);
+
return count;
}
@@ -6479,7 +6803,8 @@ static int __init fan_init(struct ibm_init_struct *iibm)
{
int rc;
- vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
+ "initializing fan subdriver\n");
mutex_init(&fan_mutex);
fan_status_access_mode = TPACPI_FAN_NONE;
@@ -6538,7 +6863,8 @@ static int __init fan_init(struct ibm_init_struct *iibm)
}
}
- vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
+ "fan is %s, modes %d, %d\n",
str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
fan_control_access_mode != TPACPI_FAN_WR_NONE),
fan_status_access_mode, fan_control_access_mode);
@@ -6547,7 +6873,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
if (!fan_control_allowed) {
fan_control_access_mode = TPACPI_FAN_WR_NONE;
fan_control_commands = 0;
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
"fan control features disabled by parameter\n");
}
@@ -6576,7 +6902,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
static void fan_exit(void)
{
- vdbg_printk(TPACPI_DBG_EXIT,
+ vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_FAN,
"cancelling any pending fan watchdog tasks\n");
/* FIXME: can we really do this unconditionally? */
@@ -6757,6 +7083,9 @@ static int fan_write_cmd_level(const char *cmd, int *rc)
if (*rc == -ENXIO)
printk(TPACPI_ERR "level command accepted for unsupported "
"access mode %d", fan_control_access_mode);
+ else if (!*rc)
+ tpacpi_disclose_usertask("procfs fan",
+ "set level to %d\n", level);
return 1;
}
@@ -6770,6 +7099,8 @@ static int fan_write_cmd_enable(const char *cmd, int *rc)
if (*rc == -ENXIO)
printk(TPACPI_ERR "enable command accepted for unsupported "
"access mode %d", fan_control_access_mode);
+ else if (!*rc)
+ tpacpi_disclose_usertask("procfs fan", "enable\n");
return 1;
}
@@ -6783,6 +7114,8 @@ static int fan_write_cmd_disable(const char *cmd, int *rc)
if (*rc == -ENXIO)
printk(TPACPI_ERR "disable command accepted for unsupported "
"access mode %d", fan_control_access_mode);
+ else if (!*rc)
+ tpacpi_disclose_usertask("procfs fan", "disable\n");
return 1;
}
@@ -6801,6 +7134,9 @@ static int fan_write_cmd_speed(const char *cmd, int *rc)
if (*rc == -ENXIO)
printk(TPACPI_ERR "speed command accepted for unsupported "
"access mode %d", fan_control_access_mode);
+ else if (!*rc)
+ tpacpi_disclose_usertask("procfs fan",
+ "set speed to %d\n", speed);
return 1;
}
@@ -6814,8 +7150,12 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc)
if (interval < 0 || interval > 120)
*rc = -EINVAL;
- else
+ else {
fan_watchdog_maxinterval = interval;
+ tpacpi_disclose_usertask("procfs fan",
+ "set watchdog timer to %d\n",
+ interval);
+ }
return 1;
}
@@ -6992,7 +7332,6 @@ static int __init ibm_init(struct ibm_init_struct *iibm)
ret = -ENODEV;
goto err_out;
}
- entry->owner = THIS_MODULE;
entry->data = ibm;
entry->read_proc = &dispatch_procfs_read;
if (ibm->write)
@@ -7244,10 +7583,10 @@ module_param_named(fan_control, fan_control_allowed, bool, 0);
MODULE_PARM_DESC(fan_control,
"Enables setting fan parameters features when true");
-module_param_named(brightness_mode, brightness_mode, int, 0);
+module_param_named(brightness_mode, brightness_mode, uint, 0);
MODULE_PARM_DESC(brightness_mode,
"Selects brightness control strategy: "
- "0=auto, 1=EC, 2=CMOS, 3=both");
+ "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM");
module_param(brightness_enable, uint, 0);
MODULE_PARM_DESC(brightness_enable,
@@ -7405,7 +7744,6 @@ static int __init thinkpad_acpi_module_init(void)
thinkpad_acpi_module_exit();
return -ENODEV;
}
- proc_dir->owner = THIS_MODULE;
ret = platform_driver_register(&tpacpi_pdriver);
if (ret) {
@@ -7517,9 +7855,6 @@ static int __init thinkpad_acpi_module_init(void)
return 0;
}
-/* Please remove this in year 2009 */
-MODULE_ALIAS("ibm_acpi");
-
MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
/*
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 40e60fc2e596..9f187265db8e 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -679,8 +679,6 @@ static acpi_status __init add_device(void)
toshiba_proc_dir,
(read_proc_t *) dispatch_read,
item);
- if (proc)
- proc->owner = THIS_MODULE;
if (proc && item->write_func)
proc->write_proc = (write_proc_t *) dispatch_write;
}
@@ -772,7 +770,6 @@ static int __init toshiba_acpi_init(void)
toshiba_acpi_exit();
return -ENODEV;
} else {
- toshiba_proc_dir->owner = THIS_MODULE;
status = add_device();
if (ACPI_FAILURE(status)) {
toshiba_acpi_exit();
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 2834846a185d..9a3a682c6981 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -83,7 +83,6 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
acpi_handle handle = dev->data;
struct acpi_buffer buffer;
int ret;
- acpi_status status;
pnp_dbg(&dev->dev, "set resources\n");
ret = pnpacpi_build_resource_template(dev, &buffer);
@@ -94,21 +93,31 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
kfree(buffer.pointer);
return ret;
}
- status = acpi_set_current_resources(handle, &buffer);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(acpi_set_current_resources(handle, &buffer)))
ret = -EINVAL;
+ else if (acpi_bus_power_manageable(handle))
+ ret = acpi_bus_set_power(handle, ACPI_STATE_D0);
kfree(buffer.pointer);
return ret;
}
static int pnpacpi_disable_resources(struct pnp_dev *dev)
{
- acpi_status status;
+ acpi_handle handle = dev->data;
+ int ret;
+
+ dev_dbg(&dev->dev, "disable resources\n");
/* acpi_unregister_gsi(pnp_irq(dev, 0)); */
- status = acpi_evaluate_object((acpi_handle) dev->data,
- "_DIS", NULL, NULL);
- return ACPI_FAILURE(status) ? -ENODEV : 0;
+ ret = 0;
+ if (acpi_bus_power_manageable(handle)) {
+ ret = acpi_bus_set_power(handle, ACPI_STATE_D3);
+ if (ret)
+ return ret;
+ }
+ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL)))
+ ret = -ENODEV;
+ return ret;
}
#ifdef CONFIG_ACPI_SLEEP
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 996f64838079..cfe86853feb2 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -94,7 +94,6 @@ struct pnp_dev_node_info node_info;
#ifdef CONFIG_HOTPLUG
-static int unloading = 0;
static struct completion unload_sem;
/*
@@ -158,7 +157,7 @@ static int pnp_dock_thread(void *unused)
int docked = -1, d = 0;
set_freezable();
- while (!unloading) {
+ while (1) {
int status;
/*
@@ -575,8 +574,6 @@ fs_initcall(pnpbios_init);
static int __init pnpbios_thread_init(void)
{
- struct task_struct *task;
-
#if defined(CONFIG_PPC)
if (check_legacy_ioport(PNPBIOS_BASE))
return 0;
@@ -584,10 +581,13 @@ static int __init pnpbios_thread_init(void)
if (pnpbios_disabled)
return 0;
#ifdef CONFIG_HOTPLUG
- init_completion(&unload_sem);
- task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd");
- if (!IS_ERR(task))
- unloading = 0;
+ {
+ struct task_struct *task;
+ init_completion(&unload_sem);
+ task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd");
+ if (IS_ERR(task))
+ return PTR_ERR(task);
+ }
#endif
return 0;
}
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 0c056fcc01ce..62bb98124e26 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -83,7 +83,7 @@ static int bq27x00_read(u8 reg, int *rt_value, int b_single,
}
/*
- * Return the battery temperature in Celcius degrees
+ * Return the battery temperature in Celsius degrees
* Or < 0 if something fails.
*/
static int bq27x00_battery_temperature(struct bq27x00_device_info *di)
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index ac01e06817fb..da73591017f9 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -93,6 +93,8 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(voltage_avg),
POWER_SUPPLY_ATTR(current_now),
POWER_SUPPLY_ATTR(current_avg),
+ POWER_SUPPLY_ATTR(power_now),
+ POWER_SUPPLY_ATTR(power_avg),
POWER_SUPPLY_ATTR(charge_full_design),
POWER_SUPPLY_ATTR(charge_empty_design),
POWER_SUPPLY_ATTR(charge_full),
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 5324978b73fb..235e87fcb49f 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -838,7 +838,7 @@ static int ps3av_get_hw_conf(struct ps3av *ps3av)
}
/* set mode using id */
-int ps3av_set_video_mode(u32 id)
+int ps3av_set_video_mode(int id)
{
int size;
u32 option;
@@ -940,7 +940,7 @@ EXPORT_SYMBOL_GPL(ps3av_audio_mute);
static int ps3av_probe(struct ps3_system_bus_device *dev)
{
int res;
- u32 id;
+ int id;
dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
dev_dbg(&dev->core, " timeout=%d\n", timeout);
@@ -962,8 +962,10 @@ static int ps3av_probe(struct ps3_system_bus_device *dev)
init_completion(&ps3av->done);
complete(&ps3av->done);
ps3av->wq = create_singlethread_workqueue("ps3avd");
- if (!ps3av->wq)
+ if (!ps3av->wq) {
+ res = -ENOMEM;
goto fail;
+ }
switch (ps3_os_area_get_av_multi_out()) {
case PS3_PARAM_AV_MULTI_OUT_NTSC:
@@ -994,6 +996,12 @@ static int ps3av_probe(struct ps3_system_bus_device *dev)
safe_mode = 1;
#endif /* CONFIG_FB */
id = ps3av_auto_videomode(&ps3av->av_hw_conf);
+ if (id < 0) {
+ printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
+ res = -EINVAL;
+ goto fail;
+ }
+
safe_mode = 0;
mutex_lock(&ps3av->mutex);
@@ -1007,7 +1015,7 @@ static int ps3av_probe(struct ps3_system_bus_device *dev)
fail:
kfree(ps3av);
ps3av = NULL;
- return -ENOMEM;
+ return res;
}
static int ps3av_remove(struct ps3_system_bus_device *dev)
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index addb87cf44d9..3222fa3c808c 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -193,7 +193,7 @@ static int rio_match_bus(struct device *dev, struct device_driver *drv)
}
static struct device rio_bus = {
- .bus_id = "rapidio",
+ .init_name = "rapidio",
};
struct bus_type rio_bus_type = {
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index e7e0cf102d6d..e58c0ce65aa6 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -29,8 +29,12 @@ config REGULATOR_DEBUG
Say yes here to enable debugging support.
config REGULATOR_FIXED_VOLTAGE
- tristate
+ tristate "Fixed voltage regulator support"
default n
+ help
+ This driver provides support for fixed voltage regulators,
+ useful for systems which use a combination of software
+ managed regulators and simple non-configurable regulators.
config REGULATOR_VIRTUAL_CONSUMER
tristate "Virtual regulator consumer support"
@@ -52,6 +56,13 @@ config REGULATOR_BQ24022
charging select between 100 mA and 500 mA charging current
limit.
+config REGULATOR_TWL4030
+ bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
+ depends on TWL4030_CORE
+ help
+ This driver supports the voltage regulators provided by
+ this family of companion chips.
+
config REGULATOR_WM8350
tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC"
depends on MFD_WM8350
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 61b30c6ddecc..bac133afc061 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
+obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c
index c175e38a4cd5..7ecb820ceebc 100644
--- a/drivers/regulator/bq24022.c
+++ b/drivers/regulator/bq24022.c
@@ -105,7 +105,8 @@ static int __init bq24022_probe(struct platform_device *pdev)
ret = gpio_direction_output(pdata->gpio_iset2, 0);
ret = gpio_direction_output(pdata->gpio_nce, 1);
- bq24022 = regulator_register(&bq24022_desc, &pdev->dev, pdata);
+ bq24022 = regulator_register(&bq24022_desc, &pdev->dev,
+ pdata->init_data, pdata);
if (IS_ERR(bq24022)) {
dev_dbg(&pdev->dev, "couldn't register regulator\n");
ret = PTR_ERR(bq24022);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index f511a406fcaa..01f7702a805d 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -28,33 +28,7 @@
static DEFINE_MUTEX(regulator_list_mutex);
static LIST_HEAD(regulator_list);
static LIST_HEAD(regulator_map_list);
-
-/*
- * struct regulator_dev
- *
- * Voltage / Current regulator class device. One for each regulator.
- */
-struct regulator_dev {
- struct regulator_desc *desc;
- int use_count;
-
- /* lists we belong to */
- struct list_head list; /* list of all regulators */
- struct list_head slist; /* list of supplied regulators */
-
- /* lists we own */
- struct list_head consumer_list; /* consumers we supply */
- struct list_head supply_list; /* regulators we supply */
-
- struct blocking_notifier_head notifier;
- struct mutex mutex; /* consumer lock */
- struct module *owner;
- struct device dev;
- struct regulation_constraints *constraints;
- struct regulator_dev *supply; /* for tree */
-
- void *reg_data; /* regulator_dev data */
-};
+static int has_full_constraints;
/*
* struct regulator_map
@@ -79,7 +53,6 @@ struct regulator {
int uA_load;
int min_uV;
int max_uV;
- int enabled; /* count of client enables */
char *supply_name;
struct device_attribute dev_attr;
struct regulator_dev *rdev;
@@ -312,6 +285,47 @@ static ssize_t regulator_state_show(struct device *dev,
}
static DEVICE_ATTR(state, 0444, regulator_state_show, NULL);
+static ssize_t regulator_status_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
+ int status;
+ char *label;
+
+ status = rdev->desc->ops->get_status(rdev);
+ if (status < 0)
+ return status;
+
+ switch (status) {
+ case REGULATOR_STATUS_OFF:
+ label = "off";
+ break;
+ case REGULATOR_STATUS_ON:
+ label = "on";
+ break;
+ case REGULATOR_STATUS_ERROR:
+ label = "error";
+ break;
+ case REGULATOR_STATUS_FAST:
+ label = "fast";
+ break;
+ case REGULATOR_STATUS_NORMAL:
+ label = "normal";
+ break;
+ case REGULATOR_STATUS_IDLE:
+ label = "idle";
+ break;
+ case REGULATOR_STATUS_STANDBY:
+ label = "standby";
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ return sprintf(buf, "%s\n", label);
+}
+static DEVICE_ATTR(status, 0444, regulator_status_show, NULL);
+
static ssize_t regulator_min_uA_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -678,6 +692,73 @@ static int set_machine_constraints(struct regulator_dev *rdev,
else
name = "regulator";
+ /* constrain machine-level voltage specs to fit
+ * the actual range supported by this regulator.
+ */
+ if (ops->list_voltage && rdev->desc->n_voltages) {
+ int count = rdev->desc->n_voltages;
+ int i;
+ int min_uV = INT_MAX;
+ int max_uV = INT_MIN;
+ int cmin = constraints->min_uV;
+ int cmax = constraints->max_uV;
+
+ /* it's safe to autoconfigure fixed-voltage supplies */
+ if (count == 1 && !cmin) {
+ cmin = INT_MIN;
+ cmax = INT_MAX;
+ }
+
+ /* voltage constraints are optional */
+ if ((cmin == 0) && (cmax == 0))
+ goto out;
+
+ /* else require explicit machine-level constraints */
+ if (cmin <= 0 || cmax <= 0 || cmax < cmin) {
+ pr_err("%s: %s '%s' voltage constraints\n",
+ __func__, "invalid", name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* initial: [cmin..cmax] valid, [min_uV..max_uV] not */
+ for (i = 0; i < count; i++) {
+ int value;
+
+ value = ops->list_voltage(rdev, i);
+ if (value <= 0)
+ continue;
+
+ /* maybe adjust [min_uV..max_uV] */
+ if (value >= cmin && value < min_uV)
+ min_uV = value;
+ if (value <= cmax && value > max_uV)
+ max_uV = value;
+ }
+
+ /* final: [min_uV..max_uV] valid iff constraints valid */
+ if (max_uV < min_uV) {
+ pr_err("%s: %s '%s' voltage constraints\n",
+ __func__, "unsupportable", name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* use regulator's subset of machine constraints */
+ if (constraints->min_uV < min_uV) {
+ pr_debug("%s: override '%s' %s, %d -> %d\n",
+ __func__, name, "min_uV",
+ constraints->min_uV, min_uV);
+ constraints->min_uV = min_uV;
+ }
+ if (constraints->max_uV > max_uV) {
+ pr_debug("%s: override '%s' %s, %d -> %d\n",
+ __func__, name, "max_uV",
+ constraints->max_uV, max_uV);
+ constraints->max_uV = max_uV;
+ }
+ }
+
rdev->constraints = constraints;
/* do we need to apply the constraint voltage */
@@ -695,10 +776,6 @@ static int set_machine_constraints(struct regulator_dev *rdev,
}
}
- /* are we enabled at boot time by firmware / bootloader */
- if (rdev->constraints->boot_on)
- rdev->use_count = 1;
-
/* do we need to setup our suspend state */
if (constraints->initial_state) {
ret = suspend_prepare(rdev, constraints->initial_state);
@@ -710,11 +787,27 @@ static int set_machine_constraints(struct regulator_dev *rdev,
}
}
- /* if always_on is set then turn the regulator on if it's not
- * already on. */
- if (constraints->always_on && ops->enable &&
- ((ops->is_enabled && !ops->is_enabled(rdev)) ||
- (!ops->is_enabled && !constraints->boot_on))) {
+ if (constraints->initial_mode) {
+ if (!ops->set_mode) {
+ printk(KERN_ERR "%s: no set_mode operation for %s\n",
+ __func__, name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = ops->set_mode(rdev, constraints->initial_mode);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "%s: failed to set initial mode for %s: %d\n",
+ __func__, name, ret);
+ goto out;
+ }
+ }
+
+ /* If the constraints say the regulator should be on at this point
+ * and we have control then make sure it is enabled.
+ */
+ if ((constraints->always_on || constraints->boot_on) && ops->enable) {
ret = ops->enable(rdev);
if (ret < 0) {
printk(KERN_ERR "%s: failed to enable %s\n",
@@ -817,6 +910,19 @@ static void unset_consumer_device_supply(struct regulator_dev *rdev,
}
}
+static void unset_regulator_supplies(struct regulator_dev *rdev)
+{
+ struct regulator_map *node, *n;
+
+ list_for_each_entry_safe(node, n, &regulator_map_list, list) {
+ if (rdev == node->regulator) {
+ list_del(&node->list);
+ kfree(node);
+ return;
+ }
+ }
+}
+
#define REG_STR_SIZE 32
static struct regulator *create_regulator(struct regulator_dev *rdev,
@@ -898,9 +1004,12 @@ overflow_err:
* @id: Supply name or regulator ID.
*
* Returns a struct regulator corresponding to the regulator producer,
- * or IS_ERR() condition containing errno. Use of supply names
- * configured via regulator_set_device_supply() is strongly
- * encouraged.
+ * or IS_ERR() condition containing errno.
+ *
+ * Use of supply names configured via regulator_set_device_supply() is
+ * strongly encouraged. It is recommended that the supply name used
+ * should match the name used for the supply and/or the relevant
+ * device pins in the datasheet.
*/
struct regulator *regulator_get(struct device *dev, const char *id)
{
@@ -922,8 +1031,6 @@ struct regulator *regulator_get(struct device *dev, const char *id)
goto found;
}
}
- printk(KERN_ERR "regulator: Unable to get requested regulator: %s\n",
- id);
mutex_unlock(&regulator_list_mutex);
return regulator;
@@ -961,10 +1068,6 @@ void regulator_put(struct regulator *regulator)
mutex_lock(&regulator_list_mutex);
rdev = regulator->rdev;
- if (WARN(regulator->enabled, "Releasing supply %s while enabled\n",
- regulator->supply_name))
- _regulator_disable(rdev);
-
/* remove any sysfs entries */
if (regulator->dev) {
sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
@@ -1039,12 +1142,7 @@ int regulator_enable(struct regulator *regulator)
int ret = 0;
mutex_lock(&rdev->mutex);
- if (regulator->enabled == 0)
- ret = _regulator_enable(rdev);
- else if (regulator->enabled < 0)
- ret = -EIO;
- if (ret == 0)
- regulator->enabled++;
+ ret = _regulator_enable(rdev);
mutex_unlock(&rdev->mutex);
return ret;
}
@@ -1055,6 +1153,11 @@ static int _regulator_disable(struct regulator_dev *rdev)
{
int ret = 0;
+ if (WARN(rdev->use_count <= 0,
+ "unbalanced disables for %s\n",
+ rdev->desc->name))
+ return -EIO;
+
/* are we the last user and permitted to disable ? */
if (rdev->use_count == 1 && !rdev->constraints->always_on) {
@@ -1103,16 +1206,7 @@ int regulator_disable(struct regulator *regulator)
int ret = 0;
mutex_lock(&rdev->mutex);
- if (regulator->enabled == 1) {
- ret = _regulator_disable(rdev);
- if (ret == 0)
- regulator->uA_load = 0;
- } else if (WARN(regulator->enabled <= 0,
- "unbalanced disables for supply %s\n",
- regulator->supply_name))
- ret = -EIO;
- if (ret == 0)
- regulator->enabled--;
+ ret = _regulator_disable(rdev);
mutex_unlock(&rdev->mutex);
return ret;
}
@@ -1159,7 +1253,6 @@ int regulator_force_disable(struct regulator *regulator)
int ret;
mutex_lock(&regulator->rdev->mutex);
- regulator->enabled = 0;
regulator->uA_load = 0;
ret = _regulator_force_disable(regulator->rdev);
mutex_unlock(&regulator->rdev->mutex);
@@ -1204,6 +1297,56 @@ int regulator_is_enabled(struct regulator *regulator)
EXPORT_SYMBOL_GPL(regulator_is_enabled);
/**
+ * regulator_count_voltages - count regulator_list_voltage() selectors
+ * @regulator: regulator source
+ *
+ * Returns number of selectors, or negative errno. Selectors are
+ * numbered starting at zero, and typically correspond to bitfields
+ * in hardware registers.
+ */
+int regulator_count_voltages(struct regulator *regulator)
+{
+ struct regulator_dev *rdev = regulator->rdev;
+
+ return rdev->desc->n_voltages ? : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(regulator_count_voltages);
+
+/**
+ * regulator_list_voltage - enumerate supported voltages
+ * @regulator: regulator source
+ * @selector: identify voltage to list
+ * Context: can sleep
+ *
+ * Returns a voltage that can be passed to @regulator_set_voltage(),
+ * zero if this selector code can't be used on this sytem, or a
+ * negative errno.
+ */
+int regulator_list_voltage(struct regulator *regulator, unsigned selector)
+{
+ struct regulator_dev *rdev = regulator->rdev;
+ struct regulator_ops *ops = rdev->desc->ops;
+ int ret;
+
+ if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
+ return -EINVAL;
+
+ mutex_lock(&rdev->mutex);
+ ret = ops->list_voltage(rdev, selector);
+ mutex_unlock(&rdev->mutex);
+
+ if (ret > 0) {
+ if (ret < rdev->constraints->min_uV)
+ ret = 0;
+ else if (ret > rdev->constraints->max_uV)
+ ret = 0;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_list_voltage);
+
+/**
* regulator_set_voltage - set regulator output voltage
* @regulator: regulator source
* @min_uV: Minimum required voltage in uV
@@ -1243,6 +1386,7 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV);
out:
+ _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, NULL);
mutex_unlock(&rdev->mutex);
return ret;
}
@@ -1543,20 +1687,23 @@ int regulator_unregister_notifier(struct regulator *regulator,
}
EXPORT_SYMBOL_GPL(regulator_unregister_notifier);
-/* notify regulator consumers and downstream regulator consumers */
+/* notify regulator consumers and downstream regulator consumers.
+ * Note mutex must be held by caller.
+ */
static void _notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data)
{
struct regulator_dev *_rdev;
/* call rdev chain first */
- mutex_lock(&rdev->mutex);
blocking_notifier_call_chain(&rdev->notifier, event, NULL);
- mutex_unlock(&rdev->mutex);
/* now notify regulator we supply */
- list_for_each_entry(_rdev, &rdev->supply_list, slist)
- _notifier_call_chain(_rdev, event, data);
+ list_for_each_entry(_rdev, &rdev->supply_list, slist) {
+ mutex_lock(&_rdev->mutex);
+ _notifier_call_chain(_rdev, event, data);
+ mutex_unlock(&_rdev->mutex);
+ }
}
/**
@@ -1703,6 +1850,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free);
*
* Called by regulator drivers to notify clients a regulator event has
* occurred. We also notify regulator clients downstream.
+ * Note lock must be held by caller.
*/
int regulator_notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data)
@@ -1744,6 +1892,11 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
if (status < 0)
return status;
}
+ if (ops->get_status) {
+ status = device_create_file(dev, &dev_attr_status);
+ if (status < 0)
+ return status;
+ }
/* some attributes are type-specific */
if (rdev->desc->type == REGULATOR_CURRENT) {
@@ -1828,17 +1981,18 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
* regulator_register - register regulator
* @regulator_desc: regulator to register
* @dev: struct device for the regulator
+ * @init_data: platform provided init data, passed through by driver
* @driver_data: private regulator data
*
* Called by regulator drivers to register a regulator.
* Returns 0 on success.
*/
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
- struct device *dev, void *driver_data)
+ struct device *dev, struct regulator_init_data *init_data,
+ void *driver_data)
{
static atomic_t regulator_no = ATOMIC_INIT(0);
struct regulator_dev *rdev;
- struct regulator_init_data *init_data = dev->platform_data;
int ret, i;
if (regulator_desc == NULL)
@@ -1945,6 +2099,7 @@ void regulator_unregister(struct regulator_dev *rdev)
return;
mutex_lock(&regulator_list_mutex);
+ unset_regulator_supplies(rdev);
list_del(&rdev->list);
if (rdev->supply)
sysfs_remove_link(&rdev->dev.kobj, "supply");
@@ -1989,6 +2144,23 @@ out:
EXPORT_SYMBOL_GPL(regulator_suspend_prepare);
/**
+ * regulator_has_full_constraints - the system has fully specified constraints
+ *
+ * Calling this function will cause the regulator API to disable all
+ * regulators which have a zero use count and don't have an always_on
+ * constraint in a late_initcall.
+ *
+ * The intention is that this will become the default behaviour in a
+ * future kernel release so users are encouraged to use this facility
+ * now.
+ */
+void regulator_has_full_constraints(void)
+{
+ has_full_constraints = 1;
+}
+EXPORT_SYMBOL_GPL(regulator_has_full_constraints);
+
+/**
* rdev_get_drvdata - get rdev regulator driver data
* @rdev: regulator
*
@@ -2055,3 +2227,77 @@ static int __init regulator_init(void)
/* init early to allow our consumers to complete system booting */
core_initcall(regulator_init);
+
+static int __init regulator_init_complete(void)
+{
+ struct regulator_dev *rdev;
+ struct regulator_ops *ops;
+ struct regulation_constraints *c;
+ int enabled, ret;
+ const char *name;
+
+ mutex_lock(&regulator_list_mutex);
+
+ /* If we have a full configuration then disable any regulators
+ * which are not in use or always_on. This will become the
+ * default behaviour in the future.
+ */
+ list_for_each_entry(rdev, &regulator_list, list) {
+ ops = rdev->desc->ops;
+ c = rdev->constraints;
+
+ if (c->name)
+ name = c->name;
+ else if (rdev->desc->name)
+ name = rdev->desc->name;
+ else
+ name = "regulator";
+
+ if (!ops->disable || c->always_on)
+ continue;
+
+ mutex_lock(&rdev->mutex);
+
+ if (rdev->use_count)
+ goto unlock;
+
+ /* If we can't read the status assume it's on. */
+ if (ops->is_enabled)
+ enabled = ops->is_enabled(rdev);
+ else
+ enabled = 1;
+
+ if (!enabled)
+ goto unlock;
+
+ if (has_full_constraints) {
+ /* We log since this may kill the system if it
+ * goes wrong. */
+ printk(KERN_INFO "%s: disabling %s\n",
+ __func__, name);
+ ret = ops->disable(rdev);
+ if (ret != 0) {
+ printk(KERN_ERR
+ "%s: couldn't disable %s: %d\n",
+ __func__, name, ret);
+ }
+ } else {
+ /* The intention is that in future we will
+ * assume that full constraints are provided
+ * so warn even if we aren't going to do
+ * anything here.
+ */
+ printk(KERN_WARNING
+ "%s: incomplete constraints, leaving %s on\n",
+ __func__, name);
+ }
+
+unlock:
+ mutex_unlock(&rdev->mutex);
+ }
+
+ mutex_unlock(&regulator_list_mutex);
+
+ return 0;
+}
+late_initcall(regulator_init_complete);
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c
index fe77730a7edb..72b15495183c 100644
--- a/drivers/regulator/da903x.c
+++ b/drivers/regulator/da903x.c
@@ -471,7 +471,8 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)
if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
ri->desc.ops = &da9030_regulator_ldo1_15_ops;
- rdev = regulator_register(&ri->desc, &pdev->dev, ri);
+ rdev = regulator_register(&ri->desc, &pdev->dev,
+ pdev->dev.platform_data, ri);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name);
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index d31db3e14913..23d554628a76 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -73,7 +73,8 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
drvdata->microvolts = config->microvolts;
- drvdata->dev = regulator_register(&drvdata->desc, drvdata);
+ drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
+ config->init_data, drvdata);
if (IS_ERR(drvdata->dev)) {
ret = PTR_ERR(drvdata->dev);
goto err_name;
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
index 4cc85ec6e120..cd761d85c8fd 100644
--- a/drivers/regulator/pcf50633-regulator.c
+++ b/drivers/regulator/pcf50633-regulator.c
@@ -284,7 +284,8 @@ static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
/* Already set by core driver */
pcf = platform_get_drvdata(pdev);
- rdev = regulator_register(&regulators[pdev->id], &pdev->dev, pcf);
+ rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
+ pdev->dev.platform_data, pcf);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
diff --git a/drivers/regulator/twl4030-regulator.c b/drivers/regulator/twl4030-regulator.c
new file mode 100644
index 000000000000..e2032fb60b55
--- /dev/null
+++ b/drivers/regulator/twl4030-regulator.c
@@ -0,0 +1,500 @@
+/*
+ * twl4030-regulator.c -- support regulators in twl4030 family chips
+ *
+ * Copyright (C) 2008 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl4030.h>
+
+
+/*
+ * The TWL4030/TW5030/TPS659x0 family chips include power management, a
+ * USB OTG transceiver, an RTC, ADC, PWM, and lots more. Some versions
+ * include an audio codec, battery charger, and more voltage regulators.
+ * These chips are often used in OMAP-based systems.
+ *
+ * This driver implements software-based resource control for various
+ * voltage regulators. This is usually augmented with state machine
+ * based control.
+ */
+
+struct twlreg_info {
+ /* start of regulator's PM_RECEIVER control register bank */
+ u8 base;
+
+ /* twl4030 resource ID, for resource control state machine */
+ u8 id;
+
+ /* voltage in mV = table[VSEL]; table_len must be a power-of-two */
+ u8 table_len;
+ const u16 *table;
+
+ /* chip constraints on regulator behavior */
+ u16 min_mV;
+
+ /* used by regulator core */
+ struct regulator_desc desc;
+};
+
+
+/* LDO control registers ... offset is from the base of its register bank.
+ * The first three registers of all power resource banks help hardware to
+ * manage the various resource groups.
+ */
+#define VREG_GRP 0
+#define VREG_TYPE 1
+#define VREG_REMAP 2
+#define VREG_DEDICATED 3 /* LDO control */
+
+
+static inline int
+twl4030reg_read(struct twlreg_info *info, unsigned offset)
+{
+ u8 value;
+ int status;
+
+ status = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER,
+ &value, info->base + offset);
+ return (status < 0) ? status : value;
+}
+
+static inline int
+twl4030reg_write(struct twlreg_info *info, unsigned offset, u8 value)
+{
+ return twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+ value, info->base + offset);
+}
+
+/*----------------------------------------------------------------------*/
+
+/* generic power resource operations, which work on all regulators */
+
+static int twl4030reg_grp(struct regulator_dev *rdev)
+{
+ return twl4030reg_read(rdev_get_drvdata(rdev), VREG_GRP);
+}
+
+/*
+ * Enable/disable regulators by joining/leaving the P1 (processor) group.
+ * We assume nobody else is updating the DEV_GRP registers.
+ */
+
+#define P3_GRP BIT(7) /* "peripherals" */
+#define P2_GRP BIT(6) /* secondary processor, modem, etc */
+#define P1_GRP BIT(5) /* CPU/Linux */
+
+static int twl4030reg_is_enabled(struct regulator_dev *rdev)
+{
+ int state = twl4030reg_grp(rdev);
+
+ if (state < 0)
+ return state;
+
+ return (state & P1_GRP) != 0;
+}
+
+static int twl4030reg_enable(struct regulator_dev *rdev)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int grp;
+
+ grp = twl4030reg_read(info, VREG_GRP);
+ if (grp < 0)
+ return grp;
+
+ grp |= P1_GRP;
+ return twl4030reg_write(info, VREG_GRP, grp);
+}
+
+static int twl4030reg_disable(struct regulator_dev *rdev)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int grp;
+
+ grp = twl4030reg_read(info, VREG_GRP);
+ if (grp < 0)
+ return grp;
+
+ grp &= ~P1_GRP;
+ return twl4030reg_write(info, VREG_GRP, grp);
+}
+
+static int twl4030reg_get_status(struct regulator_dev *rdev)
+{
+ int state = twl4030reg_grp(rdev);
+
+ if (state < 0)
+ return state;
+ state &= 0x0f;
+
+ /* assume state != WARM_RESET; we'd not be running... */
+ if (!state)
+ return REGULATOR_STATUS_OFF;
+ return (state & BIT(3))
+ ? REGULATOR_STATUS_NORMAL
+ : REGULATOR_STATUS_STANDBY;
+}
+
+static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ unsigned message;
+ int status;
+
+ /* We can only set the mode through state machine commands... */
+ switch (mode) {
+ case REGULATOR_MODE_NORMAL:
+ message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_ACTIVE);
+ break;
+ case REGULATOR_MODE_STANDBY:
+ message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_SLEEP);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Ensure the resource is associated with some group */
+ status = twl4030reg_grp(rdev);
+ if (status < 0)
+ return status;
+ if (!(status & (P3_GRP | P2_GRP | P1_GRP)))
+ return -EACCES;
+
+ status = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ message >> 8, 0x15 /* PB_WORD_MSB */ );
+ if (status >= 0)
+ return status;
+
+ return twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ message, 0x16 /* PB_WORD_LSB */ );
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Support for adjustable-voltage LDOs uses a four bit (or less) voltage
+ * select field in its control register. We use tables indexed by VSEL
+ * to record voltages in milliVolts. (Accuracy is about three percent.)
+ *
+ * Note that VSEL values for VAUX2 changed in twl5030 and newer silicon;
+ * currently handled by listing two slightly different VAUX2 regulators,
+ * only one of which will be configured.
+ *
+ * VSEL values documented as "TI cannot support these values" are flagged
+ * in these tables as UNSUP() values; we normally won't assign them.
+ *
+ * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported.
+ * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting.
+ */
+#ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED
+#define UNSUP_MASK 0x0000
+#else
+#define UNSUP_MASK 0x8000
+#endif
+
+#define UNSUP(x) (UNSUP_MASK | (x))
+#define IS_UNSUP(x) (UNSUP_MASK & (x))
+#define LDO_MV(x) (~UNSUP_MASK & (x))
+
+
+static const u16 VAUX1_VSEL_table[] = {
+ UNSUP(1500), UNSUP(1800), 2500, 2800,
+ 3000, 3000, 3000, 3000,
+};
+static const u16 VAUX2_4030_VSEL_table[] = {
+ UNSUP(1000), UNSUP(1000), UNSUP(1200), 1300,
+ 1500, 1800, UNSUP(1850), 2500,
+ UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
+ UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VAUX2_VSEL_table[] = {
+ 1700, 1700, 1900, 1300,
+ 1500, 1800, 2000, 2500,
+ 2100, 2800, 2200, 2300,
+ 2400, 2400, 2400, 2400,
+};
+static const u16 VAUX3_VSEL_table[] = {
+ 1500, 1800, 2500, 2800,
+ 3000, 3000, 3000, 3000,
+};
+static const u16 VAUX4_VSEL_table[] = {
+ 700, 1000, 1200, UNSUP(1300),
+ 1500, 1800, UNSUP(1850), 2500,
+ UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
+ UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VMMC1_VSEL_table[] = {
+ 1850, 2850, 3000, 3150,
+};
+static const u16 VMMC2_VSEL_table[] = {
+ UNSUP(1000), UNSUP(1000), UNSUP(1200), UNSUP(1300),
+ UNSUP(1500), UNSUP(1800), 1850, UNSUP(2500),
+ 2600, 2800, 2850, 3000,
+ 3150, 3150, 3150, 3150,
+};
+static const u16 VPLL1_VSEL_table[] = {
+ 1000, 1200, 1300, 1800,
+ UNSUP(2800), UNSUP(3000), UNSUP(3000), UNSUP(3000),
+};
+static const u16 VPLL2_VSEL_table[] = {
+ 700, 1000, 1200, 1300,
+ UNSUP(1500), 1800, UNSUP(1850), UNSUP(2500),
+ UNSUP(2600), UNSUP(2800), UNSUP(2850), UNSUP(3000),
+ UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VSIM_VSEL_table[] = {
+ UNSUP(1000), UNSUP(1200), UNSUP(1300), 1800,
+ 2800, 3000, 3000, 3000,
+};
+static const u16 VDAC_VSEL_table[] = {
+ 1200, 1300, 1800, 1800,
+};
+
+
+static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int mV = info->table[index];
+
+ return IS_UNSUP(mV) ? 0 : (LDO_MV(mV) * 1000);
+}
+
+static int
+twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int vsel;
+
+ for (vsel = 0; vsel < info->table_len; vsel++) {
+ int mV = info->table[vsel];
+ int uV;
+
+ if (IS_UNSUP(mV))
+ continue;
+ uV = LDO_MV(mV) * 1000;
+
+ /* REVISIT for VAUX2, first match may not be best/lowest */
+
+ /* use the first in-range value */
+ if (min_uV <= uV && uV <= max_uV)
+ return twl4030reg_write(info, VREG_DEDICATED, vsel);
+ }
+
+ return -EDOM;
+}
+
+static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int vsel = twl4030reg_read(info, VREG_DEDICATED);
+
+ if (vsel < 0)
+ return vsel;
+
+ vsel &= info->table_len - 1;
+ return LDO_MV(info->table[vsel]) * 1000;
+}
+
+static struct regulator_ops twl4030ldo_ops = {
+ .list_voltage = twl4030ldo_list_voltage,
+
+ .set_voltage = twl4030ldo_set_voltage,
+ .get_voltage = twl4030ldo_get_voltage,
+
+ .enable = twl4030reg_enable,
+ .disable = twl4030reg_disable,
+ .is_enabled = twl4030reg_is_enabled,
+
+ .set_mode = twl4030reg_set_mode,
+
+ .get_status = twl4030reg_get_status,
+};
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Fixed voltage LDOs don't have a VSEL field to update.
+ */
+static int twl4030fixed_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+
+ return info->min_mV * 1000;
+}
+
+static int twl4030fixed_get_voltage(struct regulator_dev *rdev)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+
+ return info->min_mV * 1000;
+}
+
+static struct regulator_ops twl4030fixed_ops = {
+ .list_voltage = twl4030fixed_list_voltage,
+
+ .get_voltage = twl4030fixed_get_voltage,
+
+ .enable = twl4030reg_enable,
+ .disable = twl4030reg_disable,
+ .is_enabled = twl4030reg_is_enabled,
+
+ .set_mode = twl4030reg_set_mode,
+
+ .get_status = twl4030reg_get_status,
+};
+
+/*----------------------------------------------------------------------*/
+
+#define TWL_ADJUSTABLE_LDO(label, offset, num) { \
+ .base = offset, \
+ .id = num, \
+ .table_len = ARRAY_SIZE(label##_VSEL_table), \
+ .table = label##_VSEL_table, \
+ .desc = { \
+ .name = #label, \
+ .id = TWL4030_REG_##label, \
+ .n_voltages = ARRAY_SIZE(label##_VSEL_table), \
+ .ops = &twl4030ldo_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ }, \
+ }
+
+#define TWL_FIXED_LDO(label, offset, mVolts, num) { \
+ .base = offset, \
+ .id = num, \
+ .min_mV = mVolts, \
+ .desc = { \
+ .name = #label, \
+ .id = TWL4030_REG_##label, \
+ .n_voltages = 1, \
+ .ops = &twl4030fixed_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ }, \
+ }
+
+/*
+ * We list regulators here if systems need some level of
+ * software control over them after boot.
+ */
+static struct twlreg_info twl4030_regs[] = {
+ TWL_ADJUSTABLE_LDO(VAUX1, 0x17, 1),
+ TWL_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2),
+ TWL_ADJUSTABLE_LDO(VAUX2, 0x1b, 2),
+ TWL_ADJUSTABLE_LDO(VAUX3, 0x1f, 3),
+ TWL_ADJUSTABLE_LDO(VAUX4, 0x23, 4),
+ TWL_ADJUSTABLE_LDO(VMMC1, 0x27, 5),
+ TWL_ADJUSTABLE_LDO(VMMC2, 0x2b, 6),
+ /*
+ TWL_ADJUSTABLE_LDO(VPLL1, 0x2f, 7),
+ */
+ TWL_ADJUSTABLE_LDO(VPLL2, 0x33, 8),
+ TWL_ADJUSTABLE_LDO(VSIM, 0x37, 9),
+ TWL_ADJUSTABLE_LDO(VDAC, 0x3b, 10),
+ /*
+ TWL_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11),
+ TWL_ADJUSTABLE_LDO(VINTANA2, 0x43, 12),
+ TWL_ADJUSTABLE_LDO(VINTDIG, 0x47, 13),
+ TWL_SMPS(VIO, 0x4b, 14),
+ TWL_SMPS(VDD1, 0x55, 15),
+ TWL_SMPS(VDD2, 0x63, 16),
+ */
+ TWL_FIXED_LDO(VUSB1V5, 0x71, 1500, 17),
+ TWL_FIXED_LDO(VUSB1V8, 0x74, 1800, 18),
+ TWL_FIXED_LDO(VUSB3V1, 0x77, 3100, 19),
+ /* VUSBCP is managed *only* by the USB subchip */
+};
+
+static int twl4030reg_probe(struct platform_device *pdev)
+{
+ int i;
+ struct twlreg_info *info;
+ struct regulator_init_data *initdata;
+ struct regulation_constraints *c;
+ struct regulator_dev *rdev;
+
+ for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) {
+ if (twl4030_regs[i].desc.id != pdev->id)
+ continue;
+ info = twl4030_regs + i;
+ break;
+ }
+ if (!info)
+ return -ENODEV;
+
+ initdata = pdev->dev.platform_data;
+ if (!initdata)
+ return -EINVAL;
+
+ /* Constrain board-specific capabilities according to what
+ * this driver and the chip itself can actually do.
+ */
+ c = &initdata->constraints;
+ c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
+ c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS;
+
+ rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "can't register %s, %ld\n",
+ info->desc.name, PTR_ERR(rdev));
+ return PTR_ERR(rdev);
+ }
+ platform_set_drvdata(pdev, rdev);
+
+ /* NOTE: many regulators support short-circuit IRQs (presentable
+ * as REGULATOR_OVER_CURRENT notifications?) configured via:
+ * - SC_CONFIG
+ * - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
+ * - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
+ * - IT_CONFIG
+ */
+
+ return 0;
+}
+
+static int __devexit twl4030reg_remove(struct platform_device *pdev)
+{
+ regulator_unregister(platform_get_drvdata(pdev));
+ return 0;
+}
+
+MODULE_ALIAS("platform:twl4030_reg");
+
+static struct platform_driver twl4030reg_driver = {
+ .probe = twl4030reg_probe,
+ .remove = __devexit_p(twl4030reg_remove),
+ /* NOTE: short name, to work around driver model truncation of
+ * "twl4030_regulator.12" (and friends) to "twl4030_regulator.1".
+ */
+ .driver.name = "twl4030_reg",
+ .driver.owner = THIS_MODULE,
+};
+
+static int __init twl4030reg_init(void)
+{
+ return platform_driver_register(&twl4030reg_driver);
+}
+subsys_initcall(twl4030reg_init);
+
+static void __exit twl4030reg_exit(void)
+{
+ platform_driver_unregister(&twl4030reg_driver);
+}
+module_exit(twl4030reg_exit)
+
+MODULE_DESCRIPTION("TWL4030 regulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c
index 5ddb464b1c3f..3d08348584e1 100644
--- a/drivers/regulator/virtual.c
+++ b/drivers/regulator/virtual.c
@@ -226,13 +226,17 @@ static ssize_t set_mode(struct device *dev, struct device_attribute *attr,
unsigned int mode;
int ret;
- if (strncmp(buf, "fast", strlen("fast")) == 0)
+ /*
+ * sysfs_streq() doesn't need the \n's, but we add them so the strings
+ * will be shared with show_mode(), above.
+ */
+ if (sysfs_streq(buf, "fast\n") == 0)
mode = REGULATOR_MODE_FAST;
- else if (strncmp(buf, "normal", strlen("normal")) == 0)
+ else if (sysfs_streq(buf, "normal\n") == 0)
mode = REGULATOR_MODE_NORMAL;
- else if (strncmp(buf, "idle", strlen("idle")) == 0)
+ else if (sysfs_streq(buf, "idle\n") == 0)
mode = REGULATOR_MODE_IDLE;
- else if (strncmp(buf, "standby", strlen("standby")) == 0)
+ else if (sysfs_streq(buf, "standby\n") == 0)
mode = REGULATOR_MODE_STANDBY;
else {
dev_err(dev, "Configuring invalid mode\n");
@@ -256,7 +260,7 @@ static DEVICE_ATTR(min_microamps, 0666, show_min_uA, set_min_uA);
static DEVICE_ATTR(max_microamps, 0666, show_max_uA, set_max_uA);
static DEVICE_ATTR(mode, 0666, show_mode, set_mode);
-struct device_attribute *attributes[] = {
+static struct device_attribute *attributes[] = {
&dev_attr_min_microvolts,
&dev_attr_max_microvolts,
&dev_attr_min_microamps,
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 5056e23e4414..771eca1066b5 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -24,6 +24,9 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
+/* Maximum value possible for VSEL */
+#define WM8350_DCDC_MAX_VSEL 0x66
+
/* Microamps */
static const int isink_cur[] = {
4,
@@ -385,6 +388,14 @@ static int wm8350_dcdc_get_voltage(struct regulator_dev *rdev)
return wm8350_dcdc_val_to_mvolts(val) * 1000;
}
+static int wm8350_dcdc_list_voltage(struct regulator_dev *rdev,
+ unsigned selector)
+{
+ if (selector > WM8350_DCDC_MAX_VSEL)
+ return -EINVAL;
+ return wm8350_dcdc_val_to_mvolts(selector) * 1000;
+}
+
static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV)
{
struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
@@ -775,6 +786,14 @@ static int wm8350_ldo_get_voltage(struct regulator_dev *rdev)
return wm8350_ldo_val_to_mvolts(val) * 1000;
}
+static int wm8350_ldo_list_voltage(struct regulator_dev *rdev,
+ unsigned selector)
+{
+ if (selector > WM8350_LDO1_VSEL_MASK)
+ return -EINVAL;
+ return wm8350_ldo_val_to_mvolts(selector) * 1000;
+}
+
int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start,
u16 stop, u16 fault)
{
@@ -1031,18 +1050,30 @@ static unsigned int wm8350_dcdc_get_mode(struct regulator_dev *rdev)
int dcdc = rdev_get_id(rdev);
u16 mask, sleep, active, force;
int mode = REGULATOR_MODE_NORMAL;
+ int reg;
- if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6)
- return -EINVAL;
-
- if (dcdc == WM8350_DCDC_2 || dcdc == WM8350_DCDC_5)
+ switch (dcdc) {
+ case WM8350_DCDC_1:
+ reg = WM8350_DCDC1_FORCE_PWM;
+ break;
+ case WM8350_DCDC_3:
+ reg = WM8350_DCDC3_FORCE_PWM;
+ break;
+ case WM8350_DCDC_4:
+ reg = WM8350_DCDC4_FORCE_PWM;
+ break;
+ case WM8350_DCDC_6:
+ reg = WM8350_DCDC6_FORCE_PWM;
+ break;
+ default:
return -EINVAL;
+ }
mask = 1 << (dcdc - WM8350_DCDC_1);
active = wm8350_reg_read(wm8350, WM8350_DCDC_ACTIVE_OPTIONS) & mask;
+ force = wm8350_reg_read(wm8350, reg) & WM8350_DCDC1_FORCE_PWM_ENA;
sleep = wm8350_reg_read(wm8350, WM8350_DCDC_SLEEP_OPTIONS) & mask;
- force = wm8350_reg_read(wm8350, WM8350_DCDC1_FORCE_PWM)
- & WM8350_DCDC1_FORCE_PWM_ENA;
+
dev_dbg(wm8350->dev, "mask %x active %x sleep %x force %x",
mask, active, sleep, force);
@@ -1150,6 +1181,7 @@ static int wm8350_ldo_is_enabled(struct regulator_dev *rdev)
static struct regulator_ops wm8350_dcdc_ops = {
.set_voltage = wm8350_dcdc_set_voltage,
.get_voltage = wm8350_dcdc_get_voltage,
+ .list_voltage = wm8350_dcdc_list_voltage,
.enable = wm8350_dcdc_enable,
.disable = wm8350_dcdc_disable,
.get_mode = wm8350_dcdc_get_mode,
@@ -1173,6 +1205,7 @@ static struct regulator_ops wm8350_dcdc2_5_ops = {
static struct regulator_ops wm8350_ldo_ops = {
.set_voltage = wm8350_ldo_set_voltage,
.get_voltage = wm8350_ldo_get_voltage,
+ .list_voltage = wm8350_ldo_list_voltage,
.enable = wm8350_ldo_enable,
.disable = wm8350_ldo_disable,
.is_enabled = wm8350_ldo_is_enabled,
@@ -1197,6 +1230,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC1,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE,
},
{
@@ -1213,6 +1247,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC3,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE,
},
{
@@ -1221,6 +1256,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC4,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE,
},
{
@@ -1237,6 +1273,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC6,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE,
},
{
@@ -1245,6 +1282,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO1,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_LDO1_VSEL_MASK + 1,
.owner = THIS_MODULE,
},
{
@@ -1253,6 +1291,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO2,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_LDO2_VSEL_MASK + 1,
.owner = THIS_MODULE,
},
{
@@ -1261,6 +1300,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO3,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_LDO3_VSEL_MASK + 1,
.owner = THIS_MODULE,
},
{
@@ -1269,6 +1309,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO4,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_LDO4_VSEL_MASK + 1,
.owner = THIS_MODULE,
},
{
@@ -1293,6 +1334,7 @@ static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data)
{
struct regulator_dev *rdev = (struct regulator_dev *)data;
+ mutex_lock(&rdev->mutex);
if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_REGULATION_OUT,
@@ -1301,6 +1343,7 @@ static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data)
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_UNDER_VOLTAGE,
wm8350);
+ mutex_unlock(&rdev->mutex);
}
static int wm8350_regulator_probe(struct platform_device *pdev)
@@ -1333,9 +1376,9 @@ static int wm8350_regulator_probe(struct platform_device *pdev)
break;
}
-
/* register regulator */
rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev,
+ pdev->dev.platform_data,
dev_get_drvdata(&pdev->dev));
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register %s\n",
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c
index 56e23d44ba59..157426029071 100644
--- a/drivers/regulator/wm8400-regulator.c
+++ b/drivers/regulator/wm8400-regulator.c
@@ -43,6 +43,18 @@ static int wm8400_ldo_disable(struct regulator_dev *dev)
WM8400_LDO1_ENA, 0);
}
+static int wm8400_ldo_list_voltage(struct regulator_dev *dev,
+ unsigned selector)
+{
+ if (selector > WM8400_LDO1_VSEL_MASK)
+ return -EINVAL;
+
+ if (selector < 15)
+ return 900000 + (selector * 50000);
+ else
+ return 1600000 + ((selector - 14) * 100000);
+}
+
static int wm8400_ldo_get_voltage(struct regulator_dev *dev)
{
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
@@ -51,10 +63,7 @@ static int wm8400_ldo_get_voltage(struct regulator_dev *dev)
val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev));
val &= WM8400_LDO1_VSEL_MASK;
- if (val < 15)
- return 900000 + (val * 50000);
- else
- return 1600000 + ((val - 14) * 100000);
+ return wm8400_ldo_list_voltage(dev, val);
}
static int wm8400_ldo_set_voltage(struct regulator_dev *dev,
@@ -92,6 +101,7 @@ static struct regulator_ops wm8400_ldo_ops = {
.is_enabled = wm8400_ldo_is_enabled,
.enable = wm8400_ldo_enable,
.disable = wm8400_ldo_disable,
+ .list_voltage = wm8400_ldo_list_voltage,
.get_voltage = wm8400_ldo_get_voltage,
.set_voltage = wm8400_ldo_set_voltage,
};
@@ -124,6 +134,15 @@ static int wm8400_dcdc_disable(struct regulator_dev *dev)
WM8400_DC1_ENA, 0);
}
+static int wm8400_dcdc_list_voltage(struct regulator_dev *dev,
+ unsigned selector)
+{
+ if (selector > WM8400_DC1_VSEL_MASK)
+ return -EINVAL;
+
+ return 850000 + (selector * 25000);
+}
+
static int wm8400_dcdc_get_voltage(struct regulator_dev *dev)
{
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
@@ -237,6 +256,7 @@ static struct regulator_ops wm8400_dcdc_ops = {
.is_enabled = wm8400_dcdc_is_enabled,
.enable = wm8400_dcdc_enable,
.disable = wm8400_dcdc_disable,
+ .list_voltage = wm8400_dcdc_list_voltage,
.get_voltage = wm8400_dcdc_get_voltage,
.set_voltage = wm8400_dcdc_set_voltage,
.get_mode = wm8400_dcdc_get_mode,
@@ -249,6 +269,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO1",
.id = WM8400_LDO1,
.ops = &wm8400_ldo_ops,
+ .n_voltages = WM8400_LDO1_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -256,6 +277,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO2",
.id = WM8400_LDO2,
.ops = &wm8400_ldo_ops,
+ .n_voltages = WM8400_LDO2_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -263,6 +285,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO3",
.id = WM8400_LDO3,
.ops = &wm8400_ldo_ops,
+ .n_voltages = WM8400_LDO3_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -270,6 +293,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO4",
.id = WM8400_LDO4,
.ops = &wm8400_ldo_ops,
+ .n_voltages = WM8400_LDO4_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -277,6 +301,7 @@ static struct regulator_desc regulators[] = {
.name = "DCDC1",
.id = WM8400_DCDC1,
.ops = &wm8400_dcdc_ops,
+ .n_voltages = WM8400_DC1_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -284,6 +309,7 @@ static struct regulator_desc regulators[] = {
.name = "DCDC2",
.id = WM8400_DCDC2,
.ops = &wm8400_dcdc_ops,
+ .n_voltages = WM8400_DC2_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -294,7 +320,7 @@ static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
struct regulator_dev *rdev;
rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
- pdev->dev.driver_data);
+ pdev->dev.platform_data, pdev->dev.driver_data);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 81450fbd8b12..ffe34a12f446 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -129,13 +129,14 @@ comment "I2C RTC drivers"
if I2C
config RTC_DRV_DS1307
- tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00"
+ tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025"
help
If you say yes here you get support for various compatible RTC
chips (often with battery backup) connected with I2C. This driver
should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
- and probably other chips. In some cases the RTC must already
- have been initialized (by manufacturing or a bootloader).
+ EPSON RX-8025 and probably other chips. In some cases the RTC
+ must already have been initialized (by manufacturing or a
+ bootloader).
The first seven registers on these chips hold an RTC, and other
registers may add features such as NVRAM, a trickle charger for
@@ -224,11 +225,11 @@ config RTC_DRV_PCF8583
will be called rtc-pcf8583.
config RTC_DRV_M41T80
- tristate "ST M41T65/M41T80/81/82/83/84/85/87"
+ tristate "ST M41T62/65/M41T80/81/82/83/84/85/87"
help
If you say Y here you will get support for the ST M41T60
and M41T80 RTC chips series. Currently, the following chips are
- supported: M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84,
+ supported: M41T62, M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84,
M41ST85, and M41ST87.
This driver can also be built as a module. If so, the module
@@ -440,6 +441,16 @@ config RTC_DRV_DS1742
This driver can also be built as a module. If so, the module
will be called rtc-ds1742.
+config RTC_DRV_EFI
+ tristate "EFI RTC"
+ depends on IA64
+ help
+ If you say yes here you will get support for the EFI
+ Real Time Clock.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-efi.
+
config RTC_DRV_STK17TA8
tristate "Simtek STK17TA8"
depends on RTC_CLASS
@@ -677,22 +688,16 @@ config RTC_DRV_RS5C313
help
If you say yes here you get support for the Ricoh RS5C313 RTC chips.
-config RTC_DRV_PARISC
- tristate "PA-RISC firmware RTC support"
- depends on PARISC
+config RTC_DRV_GENERIC
+ tristate "Generic RTC support"
+ # Please consider writing a new RTC driver instead of using the generic
+ # RTC abstraction
+ depends on PARISC || M68K || PPC
help
- Say Y or M here to enable RTC support on PA-RISC systems using
- firmware calls. If you do not know what you are doing, you should
+ Say Y or M here to enable RTC support on systems using the generic
+ RTC abstraction. If you do not know what you are doing, you should
just say Y.
-config RTC_DRV_PPC
- tristate "PowerPC machine dependent RTC support"
- depends on PPC
- help
- The PowerPC kernel has machine-specific functions for accessing
- the RTC. This exposes that functionality through the generic RTC
- class.
-
config RTC_DRV_PXA
tristate "PXA27x/PXA3xx"
depends on ARCH_PXA
@@ -736,4 +741,13 @@ config RTC_DRV_MV
This driver can also be built as a module. If so, the module
will be called rtc-mv.
+config RTC_DRV_PS3
+ tristate "PS3 RTC"
+ depends on PPC_PS3
+ help
+ If you say yes here you will get support for the RTC on PS3.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ps3.
+
endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 0e697aa51caa..6c0639a14f09 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o
+obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o
obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
@@ -55,8 +56,7 @@ obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o
obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
-obj-$(CONFIG_RTC_DRV_PARISC) += rtc-parisc.o
-obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o
+obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o
obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o
obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
@@ -76,3 +76,4 @@ obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
+obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index d5e4e637ddec..86c61f143515 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -351,7 +351,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
/* register irq handler after we know what name we'll use */
ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt,
IRQF_DISABLED | IRQF_SHARED,
- rtc->rtcdev->dev.bus_id, rtc);
+ dev_name(&rtc->rtcdev->dev), rtc);
if (ret) {
dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);
rtc_device_unregister(rtc->rtcdev);
@@ -366,7 +366,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
if (gpbr_readl(rtc) == 0)
dev_warn(&pdev->dev, "%s: SET TIME!\n",
- rtc->rtcdev->dev.bus_id);
+ dev_name(&rtc->rtcdev->dev));
return 0;
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 7e5155e88ac7..2c4a65302a9d 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2005 James Chapman (ds1337 core)
* Copyright (C) 2006 David Brownell
+ * Copyright (C) 2009 Matthias Fuchs (rx8025 support)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -31,6 +32,7 @@ enum ds_type {
ds_1339,
ds_1340,
m41t00,
+ rx_8025,
// rs5c372 too? different address...
};
@@ -83,6 +85,12 @@ enum ds_type {
#define DS1339_REG_ALARM1_SECS 0x07
#define DS1339_REG_TRICKLE 0x10
+#define RX8025_REG_CTRL1 0x0e
+# define RX8025_BIT_2412 0x20
+#define RX8025_REG_CTRL2 0x0f
+# define RX8025_BIT_PON 0x10
+# define RX8025_BIT_VDET 0x40
+# define RX8025_BIT_XST 0x20
struct ds1307 {
@@ -94,6 +102,10 @@ struct ds1307 {
struct i2c_client *client;
struct rtc_device *rtc;
struct work_struct work;
+ s32 (*read_block_data)(struct i2c_client *client, u8 command,
+ u8 length, u8 *values);
+ s32 (*write_block_data)(struct i2c_client *client, u8 command,
+ u8 length, const u8 *values);
};
struct chip_desc {
@@ -117,6 +129,8 @@ static const struct chip_desc chips[] = {
[ds_1340] = {
},
[m41t00] = {
+},
+[rx_8025] = {
}, };
static const struct i2c_device_id ds1307_id[] = {
@@ -126,12 +140,86 @@ static const struct i2c_device_id ds1307_id[] = {
{ "ds1339", ds_1339 },
{ "ds1340", ds_1340 },
{ "m41t00", m41t00 },
+ { "rx8025", rx_8025 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ds1307_id);
/*----------------------------------------------------------------------*/
+#define BLOCK_DATA_MAX_TRIES 10
+
+static s32 ds1307_read_block_data_once(struct i2c_client *client, u8 command,
+ u8 length, u8 *values)
+{
+ s32 i, data;
+
+ for (i = 0; i < length; i++) {
+ data = i2c_smbus_read_byte_data(client, command + i);
+ if (data < 0)
+ return data;
+ values[i] = data;
+ }
+ return i;
+}
+
+static s32 ds1307_read_block_data(struct i2c_client *client, u8 command,
+ u8 length, u8 *values)
+{
+ u8 oldvalues[I2C_SMBUS_BLOCK_MAX];
+ s32 ret;
+ int tries = 0;
+
+ dev_dbg(&client->dev, "ds1307_read_block_data (length=%d)\n", length);
+ ret = ds1307_read_block_data_once(client, command, length, values);
+ if (ret < 0)
+ return ret;
+ do {
+ if (++tries > BLOCK_DATA_MAX_TRIES) {
+ dev_err(&client->dev,
+ "ds1307_read_block_data failed\n");
+ return -EIO;
+ }
+ memcpy(oldvalues, values, length);
+ ret = ds1307_read_block_data_once(client, command, length,
+ values);
+ if (ret < 0)
+ return ret;
+ } while (memcmp(oldvalues, values, length));
+ return length;
+}
+
+static s32 ds1307_write_block_data(struct i2c_client *client, u8 command,
+ u8 length, const u8 *values)
+{
+ u8 currvalues[I2C_SMBUS_BLOCK_MAX];
+ int tries = 0;
+
+ dev_dbg(&client->dev, "ds1307_write_block_data (length=%d)\n", length);
+ do {
+ s32 i, ret;
+
+ if (++tries > BLOCK_DATA_MAX_TRIES) {
+ dev_err(&client->dev,
+ "ds1307_write_block_data failed\n");
+ return -EIO;
+ }
+ for (i = 0; i < length; i++) {
+ ret = i2c_smbus_write_byte_data(client, command + i,
+ values[i]);
+ if (ret < 0)
+ return ret;
+ }
+ ret = ds1307_read_block_data_once(client, command, length,
+ currvalues);
+ if (ret < 0)
+ return ret;
+ } while (memcmp(currvalues, values, length));
+ return length;
+}
+
+/*----------------------------------------------------------------------*/
+
/*
* The IRQ logic includes a "real" handler running in IRQ context just
* long enough to schedule this workqueue entry. We need a task context
@@ -202,7 +290,7 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
int tmp;
/* read the RTC date and time registers all at once */
- tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+ tmp = ds1307->read_block_data(ds1307->client,
DS1307_REG_SECS, 7, ds1307->regs);
if (tmp != 7) {
dev_err(dev, "%s error %d\n", "read", tmp);
@@ -279,7 +367,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
"write", buf[0], buf[1], buf[2], buf[3],
buf[4], buf[5], buf[6]);
- result = i2c_smbus_write_i2c_block_data(ds1307->client, 0, 7, buf);
+ result = ds1307->write_block_data(ds1307->client, 0, 7, buf);
if (result < 0) {
dev_err(dev, "%s error %d\n", "write", result);
return result;
@@ -297,7 +385,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
return -EINVAL;
/* read all ALARM1, ALARM2, and status registers at once */
- ret = i2c_smbus_read_i2c_block_data(client,
+ ret = ds1307->read_block_data(client,
DS1339_REG_ALARM1_SECS, 9, ds1307->regs);
if (ret != 9) {
dev_err(dev, "%s error %d\n", "alarm read", ret);
@@ -356,7 +444,7 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
t->enabled, t->pending);
/* read current status of both alarms and the chip */
- ret = i2c_smbus_read_i2c_block_data(client,
+ ret = ds1307->read_block_data(client,
DS1339_REG_ALARM1_SECS, 9, buf);
if (ret != 9) {
dev_err(dev, "%s error %d\n", "alarm write", ret);
@@ -391,7 +479,7 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
}
buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
- ret = i2c_smbus_write_i2c_block_data(client,
+ ret = ds1307->write_block_data(client,
DS1339_REG_ALARM1_SECS, 9, buf);
if (ret < 0) {
dev_err(dev, "can't set alarm time\n");
@@ -479,7 +567,7 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr,
if (unlikely(!count))
return count;
- result = i2c_smbus_read_i2c_block_data(client, 8 + off, count, buf);
+ result = ds1307->read_block_data(client, 8 + off, count, buf);
if (result < 0)
dev_err(&client->dev, "%s error %d\n", "nvram read", result);
return result;
@@ -490,9 +578,11 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{
struct i2c_client *client;
+ struct ds1307 *ds1307;
int result;
client = kobj_to_i2c_client(kobj);
+ ds1307 = i2c_get_clientdata(client);
if (unlikely(off >= NVRAM_SIZE))
return -EFBIG;
@@ -501,7 +591,7 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr,
if (unlikely(!count))
return count;
- result = i2c_smbus_write_i2c_block_data(client, 8 + off, count, buf);
+ result = ds1307->write_block_data(client, 8 + off, count, buf);
if (result < 0) {
dev_err(&client->dev, "%s error %d\n", "nvram write", result);
return result;
@@ -535,9 +625,8 @@ static int __devinit ds1307_probe(struct i2c_client *client,
int want_irq = false;
unsigned char *buf;
- if (!i2c_check_functionality(adapter,
- I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
- I2C_FUNC_SMBUS_I2C_BLOCK))
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)
+ && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
return -EIO;
if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL)))
@@ -547,6 +636,13 @@ static int __devinit ds1307_probe(struct i2c_client *client,
i2c_set_clientdata(client, ds1307);
ds1307->type = id->driver_data;
buf = ds1307->regs;
+ if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
+ ds1307->read_block_data = i2c_smbus_read_i2c_block_data;
+ ds1307->write_block_data = i2c_smbus_write_i2c_block_data;
+ } else {
+ ds1307->read_block_data = ds1307_read_block_data;
+ ds1307->write_block_data = ds1307_write_block_data;
+ }
switch (ds1307->type) {
case ds_1337:
@@ -557,7 +653,7 @@ static int __devinit ds1307_probe(struct i2c_client *client,
want_irq = true;
}
/* get registers that the "rtc" read below won't read... */
- tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+ tmp = ds1307->read_block_data(ds1307->client,
DS1337_REG_CONTROL, 2, buf);
if (tmp != 2) {
pr_debug("read error %d\n", tmp);
@@ -589,13 +685,79 @@ static int __devinit ds1307_probe(struct i2c_client *client,
dev_warn(&client->dev, "SET TIME!\n");
}
break;
+
+ case rx_8025:
+ tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+ RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
+ if (tmp != 2) {
+ pr_debug("read error %d\n", tmp);
+ err = -EIO;
+ goto exit_free;
+ }
+
+ /* oscillator off? turn it on, so clock can tick. */
+ if (!(ds1307->regs[1] & RX8025_BIT_XST)) {
+ ds1307->regs[1] |= RX8025_BIT_XST;
+ i2c_smbus_write_byte_data(client,
+ RX8025_REG_CTRL2 << 4 | 0x08,
+ ds1307->regs[1]);
+ dev_warn(&client->dev,
+ "oscillator stop detected - SET TIME!\n");
+ }
+
+ if (ds1307->regs[1] & RX8025_BIT_PON) {
+ ds1307->regs[1] &= ~RX8025_BIT_PON;
+ i2c_smbus_write_byte_data(client,
+ RX8025_REG_CTRL2 << 4 | 0x08,
+ ds1307->regs[1]);
+ dev_warn(&client->dev, "power-on detected\n");
+ }
+
+ if (ds1307->regs[1] & RX8025_BIT_VDET) {
+ ds1307->regs[1] &= ~RX8025_BIT_VDET;
+ i2c_smbus_write_byte_data(client,
+ RX8025_REG_CTRL2 << 4 | 0x08,
+ ds1307->regs[1]);
+ dev_warn(&client->dev, "voltage drop detected\n");
+ }
+
+ /* make sure we are running in 24hour mode */
+ if (!(ds1307->regs[0] & RX8025_BIT_2412)) {
+ u8 hour;
+
+ /* switch to 24 hour mode */
+ i2c_smbus_write_byte_data(client,
+ RX8025_REG_CTRL1 << 4 | 0x08,
+ ds1307->regs[0] |
+ RX8025_BIT_2412);
+
+ tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+ RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
+ if (tmp != 2) {
+ pr_debug("read error %d\n", tmp);
+ err = -EIO;
+ goto exit_free;
+ }
+
+ /* correct hour */
+ hour = bcd2bin(ds1307->regs[DS1307_REG_HOUR]);
+ if (hour == 12)
+ hour = 0;
+ if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
+ hour += 12;
+
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_HOUR << 4 | 0x08,
+ hour);
+ }
+ break;
default:
break;
}
read_rtc:
/* read RTC registers */
- tmp = i2c_smbus_read_i2c_block_data(ds1307->client, 0, 8, buf);
+ tmp = ds1307->read_block_data(ds1307->client, 0, 8, buf);
if (tmp != 8) {
pr_debug("read error %d\n", tmp);
err = -EIO;
@@ -649,6 +811,7 @@ read_rtc:
dev_warn(&client->dev, "SET TIME!\n");
}
break;
+ case rx_8025:
case ds_1337:
case ds_1339:
break;
@@ -662,6 +825,8 @@ read_rtc:
* systems that will run through year 2100.
*/
break;
+ case rx_8025:
+ break;
default:
if (!(tmp & DS1307_BIT_12HR))
break;
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index a5b0fc09f0c6..4d32e328f6cd 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -222,16 +222,16 @@ static int ds1374_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
rtc_tm_to_time(&alarm->time, &new_alarm);
rtc_tm_to_time(&now, &itime);
- new_alarm -= itime;
-
/* This can happen due to races, in addition to dates that are
* truly in the past. To avoid requiring the caller to check for
* races, dates in the past are assumed to be in the recent past
* (i.e. not something that we'd rather the caller know about via
* an error), and the alarm is set to go off as soon as possible.
*/
- if (new_alarm <= 0)
+ if (time_before_eq(new_alarm, itime))
new_alarm = 1;
+ else
+ new_alarm -= itime;
mutex_lock(&ds1374->mutex);
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c
new file mode 100644
index 000000000000..550292304b0f
--- /dev/null
+++ b/drivers/rtc/rtc-efi.c
@@ -0,0 +1,235 @@
+/*
+ * rtc-efi: RTC Class Driver for EFI-based systems
+ *
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * Author: dann frazier <dannf@hp.com>
+ * Based on efirtc.c by Stephane Eranian
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/efi.h>
+
+#define EFI_ISDST (EFI_TIME_ADJUST_DAYLIGHT|EFI_TIME_IN_DAYLIGHT)
+/*
+ * EFI Epoch is 1/1/1998
+ */
+#define EFI_RTC_EPOCH 1998
+
+/*
+ * returns day of the year [0-365]
+ */
+static inline int
+compute_yday(efi_time_t *eft)
+{
+ /* efi_time_t.month is in the [1-12] so, we need -1 */
+ return rtc_year_days(eft->day - 1, eft->month - 1, eft->year);
+}
+/*
+ * returns day of the week [0-6] 0=Sunday
+ *
+ * Don't try to provide a year that's before 1998, please !
+ */
+static int
+compute_wday(efi_time_t *eft)
+{
+ int y;
+ int ndays = 0;
+
+ if (eft->year < 1998) {
+ printk(KERN_ERR "efirtc: EFI year < 1998, invalid date\n");
+ return -1;
+ }
+
+ for (y = EFI_RTC_EPOCH; y < eft->year; y++)
+ ndays += 365 + (is_leap_year(y) ? 1 : 0);
+
+ ndays += compute_yday(eft);
+
+ /*
+ * 4=1/1/1998 was a Thursday
+ */
+ return (ndays + 4) % 7;
+}
+
+static void
+convert_to_efi_time(struct rtc_time *wtime, efi_time_t *eft)
+{
+ eft->year = wtime->tm_year + 1900;
+ eft->month = wtime->tm_mon + 1;
+ eft->day = wtime->tm_mday;
+ eft->hour = wtime->tm_hour;
+ eft->minute = wtime->tm_min;
+ eft->second = wtime->tm_sec;
+ eft->nanosecond = 0;
+ eft->daylight = wtime->tm_isdst ? EFI_ISDST : 0;
+ eft->timezone = EFI_UNSPECIFIED_TIMEZONE;
+}
+
+static void
+convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime)
+{
+ memset(wtime, 0, sizeof(*wtime));
+ wtime->tm_sec = eft->second;
+ wtime->tm_min = eft->minute;
+ wtime->tm_hour = eft->hour;
+ wtime->tm_mday = eft->day;
+ wtime->tm_mon = eft->month - 1;
+ wtime->tm_year = eft->year - 1900;
+
+ /* day of the week [0-6], Sunday=0 */
+ wtime->tm_wday = compute_wday(eft);
+
+ /* day in the year [1-365]*/
+ wtime->tm_yday = compute_yday(eft);
+
+
+ switch (eft->daylight & EFI_ISDST) {
+ case EFI_ISDST:
+ wtime->tm_isdst = 1;
+ break;
+ case EFI_TIME_ADJUST_DAYLIGHT:
+ wtime->tm_isdst = 0;
+ break;
+ default:
+ wtime->tm_isdst = -1;
+ }
+}
+
+static int efi_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+ efi_time_t eft;
+ efi_status_t status;
+
+ /*
+ * As of EFI v1.10, this call always returns an unsupported status
+ */
+ status = efi.get_wakeup_time((efi_bool_t *)&wkalrm->enabled,
+ (efi_bool_t *)&wkalrm->pending, &eft);
+
+ if (status != EFI_SUCCESS)
+ return -EINVAL;
+
+ convert_from_efi_time(&eft, &wkalrm->time);
+
+ return rtc_valid_tm(&wkalrm->time);
+}
+
+static int efi_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+ efi_time_t eft;
+ efi_status_t status;
+
+ convert_to_efi_time(&wkalrm->time, &eft);
+
+ /*
+ * XXX Fixme:
+ * As of EFI 0.92 with the firmware I have on my
+ * machine this call does not seem to work quite
+ * right
+ *
+ * As of v1.10, this call always returns an unsupported status
+ */
+ status = efi.set_wakeup_time((efi_bool_t)wkalrm->enabled, &eft);
+
+ printk(KERN_WARNING "write status is %d\n", (int)status);
+
+ return status == EFI_SUCCESS ? 0 : -EINVAL;
+}
+
+static int efi_read_time(struct device *dev, struct rtc_time *tm)
+{
+ efi_status_t status;
+ efi_time_t eft;
+ efi_time_cap_t cap;
+
+ status = efi.get_time(&eft, &cap);
+
+ if (status != EFI_SUCCESS) {
+ /* should never happen */
+ printk(KERN_ERR "efitime: can't read time\n");
+ return -EINVAL;
+ }
+
+ convert_from_efi_time(&eft, tm);
+
+ return rtc_valid_tm(tm);
+}
+
+static int efi_set_time(struct device *dev, struct rtc_time *tm)
+{
+ efi_status_t status;
+ efi_time_t eft;
+
+ convert_to_efi_time(tm, &eft);
+
+ status = efi.set_time(&eft);
+
+ return status == EFI_SUCCESS ? 0 : -EINVAL;
+}
+
+static const struct rtc_class_ops efi_rtc_ops = {
+ .read_time = efi_read_time,
+ .set_time = efi_set_time,
+ .read_alarm = efi_read_alarm,
+ .set_alarm = efi_set_alarm,
+};
+
+static int __init efi_rtc_probe(struct platform_device *dev)
+{
+ struct rtc_device *rtc;
+
+ rtc = rtc_device_register("rtc-efi", &dev->dev, &efi_rtc_ops,
+ THIS_MODULE);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
+
+ platform_set_drvdata(dev, rtc);
+
+ return 0;
+}
+
+static int __exit efi_rtc_remove(struct platform_device *dev)
+{
+ struct rtc_device *rtc = platform_get_drvdata(dev);
+
+ rtc_device_unregister(rtc);
+
+ return 0;
+}
+
+static struct platform_driver efi_rtc_driver = {
+ .driver = {
+ .name = "rtc-efi",
+ .owner = THIS_MODULE,
+ },
+ .probe = efi_rtc_probe,
+ .remove = __exit_p(efi_rtc_remove),
+};
+
+static int __init efi_rtc_init(void)
+{
+ return platform_driver_probe(&efi_rtc_driver, efi_rtc_probe);
+}
+
+static void __exit efi_rtc_exit(void)
+{
+ platform_driver_unregister(&efi_rtc_driver);
+}
+
+module_init(efi_rtc_init);
+module_exit(efi_rtc_exit);
+
+MODULE_AUTHOR("dann frazier <dannf@hp.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("EFI RTC driver");
diff --git a/drivers/rtc/rtc-generic.c b/drivers/rtc/rtc-generic.c
new file mode 100644
index 000000000000..98322004ad2e
--- /dev/null
+++ b/drivers/rtc/rtc-generic.c
@@ -0,0 +1,84 @@
+/* rtc-generic: RTC driver using the generic RTC abstraction
+ *
+ * Copyright (C) 2008 Kyle McMartin <kyle@mcmartin.ca>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#include <asm/rtc.h>
+
+static int generic_get_time(struct device *dev, struct rtc_time *tm)
+{
+ unsigned int ret = get_rtc_time(tm);
+
+ if (ret & RTC_BATT_BAD)
+ return -EOPNOTSUPP;
+
+ return rtc_valid_tm(tm);
+}
+
+static int generic_set_time(struct device *dev, struct rtc_time *tm)
+{
+ if (set_rtc_time(tm) < 0)
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+
+static const struct rtc_class_ops generic_rtc_ops = {
+ .read_time = generic_get_time,
+ .set_time = generic_set_time,
+};
+
+static int __init generic_rtc_probe(struct platform_device *dev)
+{
+ struct rtc_device *rtc;
+
+ rtc = rtc_device_register("rtc-generic", &dev->dev, &generic_rtc_ops,
+ THIS_MODULE);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
+
+ platform_set_drvdata(dev, rtc);
+
+ return 0;
+}
+
+static int __exit generic_rtc_remove(struct platform_device *dev)
+{
+ struct rtc_device *rtc = platform_get_drvdata(dev);
+
+ rtc_device_unregister(rtc);
+
+ return 0;
+}
+
+static struct platform_driver generic_rtc_driver = {
+ .driver = {
+ .name = "rtc-generic",
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(generic_rtc_remove),
+};
+
+static int __init generic_rtc_init(void)
+{
+ return platform_driver_probe(&generic_rtc_driver, generic_rtc_probe);
+}
+
+static void __exit generic_rtc_fini(void)
+{
+ platform_driver_unregister(&generic_rtc_driver);
+}
+
+module_init(generic_rtc_init);
+module_exit(generic_rtc_fini);
+
+MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic RTC driver");
+MODULE_ALIAS("platform:rtc-generic");
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index dd70bf73ce9d..773851f338b8 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -26,14 +26,13 @@ static const unsigned short rtc_ydays[2][13] = {
};
#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
-#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400))
/*
* The number of days in the month.
*/
int rtc_month_days(unsigned int month, unsigned int year)
{
- return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1);
+ return rtc_days_in_month[month] + (is_leap_year(year) && month == 1);
}
EXPORT_SYMBOL(rtc_month_days);
@@ -42,7 +41,7 @@ EXPORT_SYMBOL(rtc_month_days);
*/
int rtc_year_days(unsigned int day, unsigned int month, unsigned int year)
{
- return rtc_ydays[LEAP_YEAR(year)][month] + day-1;
+ return rtc_ydays[is_leap_year(year)][month] + day-1;
}
EXPORT_SYMBOL(rtc_year_days);
@@ -66,7 +65,7 @@ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
- LEAPS_THRU_END_OF(1970 - 1);
if (days < 0) {
year -= 1;
- days += 365 + LEAP_YEAR(year);
+ days += 365 + is_leap_year(year);
}
tm->tm_year = year - 1900;
tm->tm_yday = days + 1;
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 893f7dece239..60fe266f0f49 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -64,10 +64,12 @@
#define M41T80_FEATURE_BL (1 << 1) /* Battery low indicator */
#define M41T80_FEATURE_SQ (1 << 2) /* Squarewave feature */
#define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */
+#define M41T80_FEATURE_SQ_ALT (1 << 4) /* RSx bits are in reg 4 */
#define DRV_VERSION "0.05"
static const struct i2c_device_id m41t80_id[] = {
+ { "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT },
{ "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD },
{ "m41t80", M41T80_FEATURE_SQ },
{ "m41t81", M41T80_FEATURE_HT | M41T80_FEATURE_SQ},
@@ -393,12 +395,15 @@ static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
{
struct i2c_client *client = to_i2c_client(dev);
struct m41t80_data *clientdata = i2c_get_clientdata(client);
- int val;
+ int val, reg_sqw;
if (!(clientdata->features & M41T80_FEATURE_SQ))
return -EINVAL;
- val = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
+ reg_sqw = M41T80_REG_SQW;
+ if (clientdata->features & M41T80_FEATURE_SQ_ALT)
+ reg_sqw = M41T80_REG_WDAY;
+ val = i2c_smbus_read_byte_data(client, reg_sqw);
if (val < 0)
return -EIO;
val = (val >> 4) & 0xf;
@@ -419,7 +424,7 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
{
struct i2c_client *client = to_i2c_client(dev);
struct m41t80_data *clientdata = i2c_get_clientdata(client);
- int almon, sqw;
+ int almon, sqw, reg_sqw;
int val = simple_strtoul(buf, NULL, 0);
if (!(clientdata->features & M41T80_FEATURE_SQ))
@@ -440,13 +445,16 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
almon = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
if (almon < 0)
return -EIO;
- sqw = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
+ reg_sqw = M41T80_REG_SQW;
+ if (clientdata->features & M41T80_FEATURE_SQ_ALT)
+ reg_sqw = M41T80_REG_WDAY;
+ sqw = i2c_smbus_read_byte_data(client, reg_sqw);
if (sqw < 0)
return -EIO;
sqw = (sqw & 0x0f) | (val << 4);
if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
almon & ~M41T80_ALMON_SQWE) < 0 ||
- i2c_smbus_write_byte_data(client, M41T80_REG_SQW, sqw) < 0)
+ i2c_smbus_write_byte_data(client, reg_sqw, sqw) < 0)
return -EIO;
if (val && i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
almon | M41T80_ALMON_SQWE) < 0)
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index 45f12dcd3716..e0263d2005ee 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -12,6 +12,7 @@
#include <linux/bcd.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <linux/delay.h>
#define RTC_TIME_REG_OFFS 0
@@ -119,6 +120,16 @@ static int __init mv_rtc_probe(struct platform_device *pdev)
return -EINVAL;
}
+ /* make sure it is actually functional */
+ if (rtc_time == 0x01000000) {
+ ssleep(1);
+ rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
+ if (rtc_time == 0x01000000) {
+ dev_err(&pdev->dev, "internal RTC not ticking\n");
+ return -ENODEV;
+ }
+ }
+
platform_set_drvdata(pdev, pdata);
pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
&mv_rtc_ops, THIS_MODULE);
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 2cbeb0794f14..bd1ce8e2bc18 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -377,13 +377,13 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
/* handle periodic and alarm irqs */
if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED,
- rtc->dev.bus_id, rtc)) {
+ dev_name(&rtc->dev), rtc)) {
pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_timer);
goto fail0;
}
if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
- rtc->dev.bus_id, rtc)) {
+ dev_name(&rtc->dev), rtc)) {
pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
pdev->name, omap_rtc_alarm);
goto fail1;
diff --git a/drivers/rtc/rtc-parisc.c b/drivers/rtc/rtc-parisc.c
deleted file mode 100644
index c6bfa6fe1a2a..000000000000
--- a/drivers/rtc/rtc-parisc.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* rtc-parisc: RTC for HP PA-RISC firmware
- *
- * Copyright (C) 2008 Kyle McMartin <kyle@mcmartin.ca>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/time.h>
-#include <linux/platform_device.h>
-
-#include <asm/rtc.h>
-
-/* as simple as can be, and no simpler. */
-struct parisc_rtc {
- struct rtc_device *rtc;
- spinlock_t lock;
-};
-
-static int parisc_get_time(struct device *dev, struct rtc_time *tm)
-{
- struct parisc_rtc *p = dev_get_drvdata(dev);
- unsigned long flags, ret;
-
- spin_lock_irqsave(&p->lock, flags);
- ret = get_rtc_time(tm);
- spin_unlock_irqrestore(&p->lock, flags);
-
- if (ret & RTC_BATT_BAD)
- return -EOPNOTSUPP;
-
- return 0;
-}
-
-static int parisc_set_time(struct device *dev, struct rtc_time *tm)
-{
- struct parisc_rtc *p = dev_get_drvdata(dev);
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&p->lock, flags);
- ret = set_rtc_time(tm);
- spin_unlock_irqrestore(&p->lock, flags);
-
- if (ret < 0)
- return -EOPNOTSUPP;
-
- return 0;
-}
-
-static const struct rtc_class_ops parisc_rtc_ops = {
- .read_time = parisc_get_time,
- .set_time = parisc_set_time,
-};
-
-static int __devinit parisc_rtc_probe(struct platform_device *dev)
-{
- struct parisc_rtc *p;
-
- p = kzalloc(sizeof (*p), GFP_KERNEL);
- if (!p)
- return -ENOMEM;
-
- spin_lock_init(&p->lock);
-
- p->rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops,
- THIS_MODULE);
- if (IS_ERR(p->rtc)) {
- int err = PTR_ERR(p->rtc);
- kfree(p);
- return err;
- }
-
- platform_set_drvdata(dev, p);
-
- return 0;
-}
-
-static int __devexit parisc_rtc_remove(struct platform_device *dev)
-{
- struct parisc_rtc *p = platform_get_drvdata(dev);
-
- rtc_device_unregister(p->rtc);
- kfree(p);
-
- return 0;
-}
-
-static struct platform_driver parisc_rtc_driver = {
- .driver = {
- .name = "rtc-parisc",
- .owner = THIS_MODULE,
- },
- .probe = parisc_rtc_probe,
- .remove = __devexit_p(parisc_rtc_remove),
-};
-
-static int __init parisc_rtc_init(void)
-{
- return platform_driver_register(&parisc_rtc_driver);
-}
-
-static void __exit parisc_rtc_fini(void)
-{
- platform_driver_unregister(&parisc_rtc_driver);
-}
-
-module_init(parisc_rtc_init);
-module_exit(parisc_rtc_fini);
-
-MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("HP PA-RISC RTC driver");
diff --git a/drivers/rtc/rtc-ppc.c b/drivers/rtc/rtc-ppc.c
deleted file mode 100644
index c8e97e25ef7e..000000000000
--- a/drivers/rtc/rtc-ppc.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * RTC driver for ppc_md RTC functions
- *
- * © 2007 Red Hat, Inc.
- *
- * Author: David Woodhouse <dwmw2@infradead.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/rtc.h>
-#include <linux/platform_device.h>
-#include <asm/machdep.h>
-
-static int ppc_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- ppc_md.get_rtc_time(tm);
- return 0;
-}
-
-static int ppc_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- return ppc_md.set_rtc_time(tm);
-}
-
-static const struct rtc_class_ops ppc_rtc_ops = {
- .set_time = ppc_rtc_set_time,
- .read_time = ppc_rtc_read_time,
-};
-
-static struct rtc_device *rtc;
-static struct platform_device *ppc_rtc_pdev;
-
-static int __init ppc_rtc_init(void)
-{
- if (!ppc_md.get_rtc_time || !ppc_md.set_rtc_time)
- return -ENODEV;
-
- ppc_rtc_pdev = platform_device_register_simple("ppc-rtc", 0, NULL, 0);
- if (IS_ERR(ppc_rtc_pdev))
- return PTR_ERR(ppc_rtc_pdev);
-
- rtc = rtc_device_register("ppc_md", &ppc_rtc_pdev->dev,
- &ppc_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc)) {
- platform_device_unregister(ppc_rtc_pdev);
- return PTR_ERR(rtc);
- }
-
- return 0;
-}
-
-static void __exit ppc_rtc_exit(void)
-{
- rtc_device_unregister(rtc);
- platform_device_unregister(ppc_rtc_pdev);
-}
-
-module_init(ppc_rtc_init);
-module_exit(ppc_rtc_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("Generic RTC class driver for PowerPC");
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c
index 0c6257a034ff..c086fc30a84c 100644
--- a/drivers/rtc/rtc-proc.c
+++ b/drivers/rtc/rtc-proc.c
@@ -105,14 +105,8 @@ static const struct file_operations rtc_proc_fops = {
void rtc_proc_add_device(struct rtc_device *rtc)
{
- if (rtc->id == 0) {
- struct proc_dir_entry *ent;
-
- ent = proc_create_data("driver/rtc", 0, NULL,
- &rtc_proc_fops, rtc);
- if (ent)
- ent->owner = rtc->owner;
- }
+ if (rtc->id == 0)
+ proc_create_data("driver/rtc", 0, NULL, &rtc_proc_fops, rtc);
}
void rtc_proc_del_device(struct rtc_device *rtc)
diff --git a/drivers/rtc/rtc-ps3.c b/drivers/rtc/rtc-ps3.c
new file mode 100644
index 000000000000..968133ce1ee8
--- /dev/null
+++ b/drivers/rtc/rtc-ps3.c
@@ -0,0 +1,104 @@
+/*
+ * PS3 RTC Driver
+ *
+ * Copyright 2009 Sony Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#include <asm/lv1call.h>
+#include <asm/ps3.h>
+
+
+static u64 read_rtc(void)
+{
+ int result;
+ u64 rtc_val;
+ u64 tb_val;
+
+ result = lv1_get_rtc(&rtc_val, &tb_val);
+ BUG_ON(result);
+
+ return rtc_val;
+}
+
+static int ps3_get_time(struct device *dev, struct rtc_time *tm)
+{
+ rtc_time_to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm);
+ return rtc_valid_tm(tm);
+}
+
+static int ps3_set_time(struct device *dev, struct rtc_time *tm)
+{
+ unsigned long now;
+
+ rtc_tm_to_time(tm, &now);
+ ps3_os_area_set_rtc_diff(now - read_rtc());
+ return 0;
+}
+
+static const struct rtc_class_ops ps3_rtc_ops = {
+ .read_time = ps3_get_time,
+ .set_time = ps3_set_time,
+};
+
+static int __init ps3_rtc_probe(struct platform_device *dev)
+{
+ struct rtc_device *rtc;
+
+ rtc = rtc_device_register("rtc-ps3", &dev->dev, &ps3_rtc_ops,
+ THIS_MODULE);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
+
+ platform_set_drvdata(dev, rtc);
+ return 0;
+}
+
+static int __exit ps3_rtc_remove(struct platform_device *dev)
+{
+ rtc_device_unregister(platform_get_drvdata(dev));
+ return 0;
+}
+
+static struct platform_driver ps3_rtc_driver = {
+ .driver = {
+ .name = "rtc-ps3",
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(ps3_rtc_remove),
+};
+
+static int __init ps3_rtc_init(void)
+{
+ return platform_driver_probe(&ps3_rtc_driver, ps3_rtc_probe);
+}
+
+static void __exit ps3_rtc_fini(void)
+{
+ platform_driver_unregister(&ps3_rtc_driver);
+}
+
+module_init(ps3_rtc_init);
+module_exit(ps3_rtc_fini);
+
+MODULE_AUTHOR("Sony Corporation");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ps3 RTC driver");
+MODULE_ALIAS("platform:rtc-ps3");
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index d26a5f82aaba..4f247e4dd3f9 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -35,7 +35,8 @@
#include <asm/irq.h>
#ifdef CONFIG_ARCH_PXA
-#include <mach/pxa-regs.h>
+#include <mach/regs-rtc.h>
+#include <mach/regs-ost.h>
#endif
#define RTC_DEF_DIVIDER 32768 - 1
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 1c3fc6b428e9..9b1ff12bf947 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -28,7 +28,7 @@
#include <asm/rtc.h>
#define DRV_NAME "sh-rtc"
-#define DRV_VERSION "0.2.0"
+#define DRV_VERSION "0.2.1"
#define RTC_REG(r) ((r) * rtc_reg_size)
@@ -99,56 +99,51 @@ struct sh_rtc {
unsigned short periodic_freq;
};
-static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
+static int __sh_rtc_interrupt(struct sh_rtc *rtc)
{
- struct sh_rtc *rtc = dev_id;
- unsigned int tmp;
-
- spin_lock(&rtc->lock);
+ unsigned int tmp, pending;
tmp = readb(rtc->regbase + RCR1);
+ pending = tmp & RCR1_CF;
tmp &= ~RCR1_CF;
writeb(tmp, rtc->regbase + RCR1);
/* Users have requested One x Second IRQ */
- if (rtc->periodic_freq & PF_OXS)
+ if (pending && rtc->periodic_freq & PF_OXS)
rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
- spin_unlock(&rtc->lock);
-
- return IRQ_HANDLED;
+ return pending;
}
-static irqreturn_t sh_rtc_alarm(int irq, void *dev_id)
+static int __sh_rtc_alarm(struct sh_rtc *rtc)
{
- struct sh_rtc *rtc = dev_id;
- unsigned int tmp;
-
- spin_lock(&rtc->lock);
+ unsigned int tmp, pending;
tmp = readb(rtc->regbase + RCR1);
+ pending = tmp & RCR1_AF;
tmp &= ~(RCR1_AF | RCR1_AIE);
- writeb(tmp, rtc->regbase + RCR1);
-
- rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
+ writeb(tmp, rtc->regbase + RCR1);
- spin_unlock(&rtc->lock);
+ if (pending)
+ rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
- return IRQ_HANDLED;
+ return pending;
}
-static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
+static int __sh_rtc_periodic(struct sh_rtc *rtc)
{
- struct sh_rtc *rtc = dev_id;
struct rtc_device *rtc_dev = rtc->rtc_dev;
- unsigned int tmp;
-
- spin_lock(&rtc->lock);
+ struct rtc_task *irq_task;
+ unsigned int tmp, pending;
tmp = readb(rtc->regbase + RCR2);
+ pending = tmp & RCR2_PEF;
tmp &= ~RCR2_PEF;
writeb(tmp, rtc->regbase + RCR2);
+ if (!pending)
+ return 0;
+
/* Half period enabled than one skipped and the next notified */
if ((rtc->periodic_freq & PF_HP) && (rtc->periodic_freq & PF_COUNT))
rtc->periodic_freq &= ~PF_COUNT;
@@ -157,16 +152,65 @@ static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
rtc->periodic_freq |= PF_COUNT;
if (rtc->periodic_freq & PF_KOU) {
spin_lock(&rtc_dev->irq_task_lock);
- if (rtc_dev->irq_task)
- rtc_dev->irq_task->func(rtc_dev->irq_task->private_data);
+ irq_task = rtc_dev->irq_task;
+ if (irq_task)
+ irq_task->func(irq_task->private_data);
spin_unlock(&rtc_dev->irq_task_lock);
} else
rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF);
}
+ return pending;
+}
+
+static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
+{
+ struct sh_rtc *rtc = dev_id;
+ int ret;
+
+ spin_lock(&rtc->lock);
+ ret = __sh_rtc_interrupt(rtc);
+ spin_unlock(&rtc->lock);
+
+ return IRQ_RETVAL(ret);
+}
+
+static irqreturn_t sh_rtc_alarm(int irq, void *dev_id)
+{
+ struct sh_rtc *rtc = dev_id;
+ int ret;
+
+ spin_lock(&rtc->lock);
+ ret = __sh_rtc_alarm(rtc);
+ spin_unlock(&rtc->lock);
+
+ return IRQ_RETVAL(ret);
+}
+
+static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
+{
+ struct sh_rtc *rtc = dev_id;
+ int ret;
+
+ spin_lock(&rtc->lock);
+ ret = __sh_rtc_periodic(rtc);
spin_unlock(&rtc->lock);
- return IRQ_HANDLED;
+ return IRQ_RETVAL(ret);
+}
+
+static irqreturn_t sh_rtc_shared(int irq, void *dev_id)
+{
+ struct sh_rtc *rtc = dev_id;
+ int ret;
+
+ spin_lock(&rtc->lock);
+ ret = __sh_rtc_interrupt(rtc);
+ ret |= __sh_rtc_alarm(rtc);
+ ret |= __sh_rtc_periodic(rtc);
+ spin_unlock(&rtc->lock);
+
+ return IRQ_RETVAL(ret);
}
static inline void sh_rtc_setpie(struct device *dev, unsigned int enable)
@@ -275,6 +319,25 @@ static int sh_rtc_proc(struct device *dev, struct seq_file *seq)
return 0;
}
+static inline void sh_rtc_setcie(struct device *dev, unsigned int enable)
+{
+ struct sh_rtc *rtc = dev_get_drvdata(dev);
+ unsigned int tmp;
+
+ spin_lock_irq(&rtc->lock);
+
+ tmp = readb(rtc->regbase + RCR1);
+
+ if (!enable)
+ tmp &= ~RCR1_CIE;
+ else
+ tmp |= RCR1_CIE;
+
+ writeb(tmp, rtc->regbase + RCR1);
+
+ spin_unlock_irq(&rtc->lock);
+}
+
static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct sh_rtc *rtc = dev_get_drvdata(dev);
@@ -291,9 +354,11 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
break;
case RTC_UIE_OFF:
rtc->periodic_freq &= ~PF_OXS;
+ sh_rtc_setcie(dev, 0);
break;
case RTC_UIE_ON:
rtc->periodic_freq |= PF_OXS;
+ sh_rtc_setcie(dev, 1);
break;
case RTC_IRQP_READ:
ret = put_user(rtc->rtc_dev->irq_freq,
@@ -356,18 +421,17 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_sec--;
#endif
+ /* only keep the carry interrupt enabled if UIE is on */
+ if (!(rtc->periodic_freq & PF_OXS))
+ sh_rtc_setcie(dev, 0);
+
dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
__func__,
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
- if (rtc_valid_tm(tm) < 0) {
- dev_err(dev, "invalid date\n");
- rtc_time_to_tm(0, tm);
- }
-
- return 0;
+ return rtc_valid_tm(tm);
}
static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -572,7 +636,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
{
struct sh_rtc *rtc;
struct resource *res;
- unsigned int tmp;
+ struct rtc_time r;
int ret;
rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL);
@@ -585,26 +649,12 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
ret = platform_get_irq(pdev, 0);
if (unlikely(ret <= 0)) {
ret = -ENOENT;
- dev_err(&pdev->dev, "No IRQ for period\n");
+ dev_err(&pdev->dev, "No IRQ resource\n");
goto err_badres;
}
rtc->periodic_irq = ret;
-
- ret = platform_get_irq(pdev, 1);
- if (unlikely(ret <= 0)) {
- ret = -ENOENT;
- dev_err(&pdev->dev, "No IRQ for carry\n");
- goto err_badres;
- }
- rtc->carry_irq = ret;
-
- ret = platform_get_irq(pdev, 2);
- if (unlikely(ret <= 0)) {
- ret = -ENOENT;
- dev_err(&pdev->dev, "No IRQ for alarm\n");
- goto err_badres;
- }
- rtc->alarm_irq = ret;
+ rtc->carry_irq = platform_get_irq(pdev, 1);
+ rtc->alarm_irq = platform_get_irq(pdev, 2);
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (unlikely(res == NULL)) {
@@ -646,47 +696,66 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
}
rtc->rtc_dev->max_user_freq = 256;
- rtc->rtc_dev->irq_freq = 1;
- rtc->periodic_freq = 0x60;
platform_set_drvdata(pdev, rtc);
- /* register periodic/carry/alarm irqs */
- ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED,
- "sh-rtc period", rtc);
- if (unlikely(ret)) {
- dev_err(&pdev->dev,
- "request period IRQ failed with %d, IRQ %d\n", ret,
- rtc->periodic_irq);
- goto err_unmap;
- }
+ if (rtc->carry_irq <= 0) {
+ /* register shared periodic/carry/alarm irq */
+ ret = request_irq(rtc->periodic_irq, sh_rtc_shared,
+ IRQF_DISABLED, "sh-rtc", rtc);
+ if (unlikely(ret)) {
+ dev_err(&pdev->dev,
+ "request IRQ failed with %d, IRQ %d\n", ret,
+ rtc->periodic_irq);
+ goto err_unmap;
+ }
+ } else {
+ /* register periodic/carry/alarm irqs */
+ ret = request_irq(rtc->periodic_irq, sh_rtc_periodic,
+ IRQF_DISABLED, "sh-rtc period", rtc);
+ if (unlikely(ret)) {
+ dev_err(&pdev->dev,
+ "request period IRQ failed with %d, IRQ %d\n",
+ ret, rtc->periodic_irq);
+ goto err_unmap;
+ }
- ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED,
- "sh-rtc carry", rtc);
- if (unlikely(ret)) {
- dev_err(&pdev->dev,
- "request carry IRQ failed with %d, IRQ %d\n", ret,
- rtc->carry_irq);
- free_irq(rtc->periodic_irq, rtc);
- goto err_unmap;
- }
+ ret = request_irq(rtc->carry_irq, sh_rtc_interrupt,
+ IRQF_DISABLED, "sh-rtc carry", rtc);
+ if (unlikely(ret)) {
+ dev_err(&pdev->dev,
+ "request carry IRQ failed with %d, IRQ %d\n",
+ ret, rtc->carry_irq);
+ free_irq(rtc->periodic_irq, rtc);
+ goto err_unmap;
+ }
- ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED,
- "sh-rtc alarm", rtc);
- if (unlikely(ret)) {
- dev_err(&pdev->dev,
- "request alarm IRQ failed with %d, IRQ %d\n", ret,
- rtc->alarm_irq);
- free_irq(rtc->carry_irq, rtc);
- free_irq(rtc->periodic_irq, rtc);
- goto err_unmap;
+ ret = request_irq(rtc->alarm_irq, sh_rtc_alarm,
+ IRQF_DISABLED, "sh-rtc alarm", rtc);
+ if (unlikely(ret)) {
+ dev_err(&pdev->dev,
+ "request alarm IRQ failed with %d, IRQ %d\n",
+ ret, rtc->alarm_irq);
+ free_irq(rtc->carry_irq, rtc);
+ free_irq(rtc->periodic_irq, rtc);
+ goto err_unmap;
+ }
}
- tmp = readb(rtc->regbase + RCR1);
- tmp &= ~RCR1_CF;
- tmp |= RCR1_CIE;
- writeb(tmp, rtc->regbase + RCR1);
+ /* everything disabled by default */
+ rtc->periodic_freq = 0;
+ rtc->rtc_dev->irq_freq = 0;
+ sh_rtc_setpie(&pdev->dev, 0);
+ sh_rtc_setaie(&pdev->dev, 0);
+ sh_rtc_setcie(&pdev->dev, 0);
+ /* reset rtc to epoch 0 if time is invalid */
+ if (rtc_read_time(rtc->rtc_dev, &r) < 0) {
+ rtc_time_to_tm(0, &r);
+ rtc_set_time(rtc->rtc_dev, &r);
+ }
+
+ device_init_wakeup(&pdev->dev, 1);
return 0;
err_unmap:
@@ -708,10 +777,13 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
sh_rtc_setpie(&pdev->dev, 0);
sh_rtc_setaie(&pdev->dev, 0);
+ sh_rtc_setcie(&pdev->dev, 0);
- free_irq(rtc->carry_irq, rtc);
free_irq(rtc->periodic_irq, rtc);
- free_irq(rtc->alarm_irq, rtc);
+ if (rtc->carry_irq > 0) {
+ free_irq(rtc->carry_irq, rtc);
+ free_irq(rtc->alarm_irq, rtc);
+ }
release_resource(rtc->res);
@@ -723,10 +795,46 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
return 0;
}
+
+static void sh_rtc_set_irq_wake(struct device *dev, int enabled)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct sh_rtc *rtc = platform_get_drvdata(pdev);
+
+ set_irq_wake(rtc->periodic_irq, enabled);
+ if (rtc->carry_irq > 0) {
+ set_irq_wake(rtc->carry_irq, enabled);
+ set_irq_wake(rtc->alarm_irq, enabled);
+ }
+
+}
+
+static int sh_rtc_suspend(struct device *dev)
+{
+ if (device_may_wakeup(dev))
+ sh_rtc_set_irq_wake(dev, 1);
+
+ return 0;
+}
+
+static int sh_rtc_resume(struct device *dev)
+{
+ if (device_may_wakeup(dev))
+ sh_rtc_set_irq_wake(dev, 0);
+
+ return 0;
+}
+
+static struct dev_pm_ops sh_rtc_dev_pm_ops = {
+ .suspend = sh_rtc_suspend,
+ .resume = sh_rtc_resume,
+};
+
static struct platform_driver sh_rtc_platform_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+ .pm = &sh_rtc_dev_pm_ops,
},
.probe = sh_rtc_probe,
.remove = __devexit_p(sh_rtc_remove),
diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c
index ad35f76c46b7..a6341e4f9a0f 100644
--- a/drivers/rtc/rtc-twl4030.c
+++ b/drivers/rtc/rtc-twl4030.c
@@ -426,7 +426,7 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev)
ret = request_irq(irq, twl4030_rtc_interrupt,
IRQF_TRIGGER_RISING,
- rtc->dev.bus_id, rtc);
+ dev_name(&rtc->dev), rtc);
if (ret < 0) {
dev_err(&pdev->dev, "IRQ is not free.\n");
goto out1;
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index 14d4f036a768..ad164056feb6 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -27,17 +27,162 @@
#include <linux/bcd.h>
#include <linux/rtc-v3020.h>
#include <linux/delay.h>
+#include <linux/gpio.h>
-#include <asm/io.h>
+#include <linux/io.h>
#undef DEBUG
+struct v3020;
+
+struct v3020_chip_ops {
+ int (*map_io)(struct v3020 *chip, struct platform_device *pdev,
+ struct v3020_platform_data *pdata);
+ void (*unmap_io)(struct v3020 *chip);
+ unsigned char (*read_bit)(struct v3020 *chip);
+ void (*write_bit)(struct v3020 *chip, unsigned char bit);
+};
+
+#define V3020_CS 0
+#define V3020_WR 1
+#define V3020_RD 2
+#define V3020_IO 3
+
+struct v3020_gpio {
+ const char *name;
+ unsigned int gpio;
+};
+
struct v3020 {
+ /* MMIO access */
void __iomem *ioaddress;
int leftshift;
+
+ /* GPIO access */
+ struct v3020_gpio *gpio;
+
+ struct v3020_chip_ops *ops;
+
struct rtc_device *rtc;
};
+
+static int v3020_mmio_map(struct v3020 *chip, struct platform_device *pdev,
+ struct v3020_platform_data *pdata)
+{
+ if (pdev->num_resources != 1)
+ return -EBUSY;
+
+ if (pdev->resource[0].flags != IORESOURCE_MEM)
+ return -EBUSY;
+
+ chip->leftshift = pdata->leftshift;
+ chip->ioaddress = ioremap(pdev->resource[0].start, 1);
+ if (chip->ioaddress == NULL)
+ return -EBUSY;
+
+ return 0;
+}
+
+static void v3020_mmio_unmap(struct v3020 *chip)
+{
+ iounmap(chip->ioaddress);
+}
+
+static void v3020_mmio_write_bit(struct v3020 *chip, unsigned char bit)
+{
+ writel(bit << chip->leftshift, chip->ioaddress);
+}
+
+static unsigned char v3020_mmio_read_bit(struct v3020 *chip)
+{
+ return readl(chip->ioaddress) & (1 << chip->leftshift);
+}
+
+static struct v3020_chip_ops v3020_mmio_ops = {
+ .map_io = v3020_mmio_map,
+ .unmap_io = v3020_mmio_unmap,
+ .read_bit = v3020_mmio_read_bit,
+ .write_bit = v3020_mmio_write_bit,
+};
+
+static struct v3020_gpio v3020_gpio[] = {
+ { "RTC CS", 0 },
+ { "RTC WR", 0 },
+ { "RTC RD", 0 },
+ { "RTC IO", 0 },
+};
+
+static int v3020_gpio_map(struct v3020 *chip, struct platform_device *pdev,
+ struct v3020_platform_data *pdata)
+{
+ int i, err;
+
+ v3020_gpio[V3020_CS].gpio = pdata->gpio_cs;
+ v3020_gpio[V3020_WR].gpio = pdata->gpio_wr;
+ v3020_gpio[V3020_RD].gpio = pdata->gpio_rd;
+ v3020_gpio[V3020_IO].gpio = pdata->gpio_io;
+
+ for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++) {
+ err = gpio_request(v3020_gpio[i].gpio, v3020_gpio[i].name);
+ if (err)
+ goto err_request;
+
+ gpio_direction_output(v3020_gpio[i].gpio, 1);
+ }
+
+ chip->gpio = v3020_gpio;
+
+ return 0;
+
+err_request:
+ while (--i >= 0)
+ gpio_free(v3020_gpio[i].gpio);
+
+ return err;
+}
+
+static void v3020_gpio_unmap(struct v3020 *chip)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++)
+ gpio_free(v3020_gpio[i].gpio);
+}
+
+static void v3020_gpio_write_bit(struct v3020 *chip, unsigned char bit)
+{
+ gpio_direction_output(chip->gpio[V3020_IO].gpio, bit);
+ gpio_set_value(chip->gpio[V3020_CS].gpio, 0);
+ gpio_set_value(chip->gpio[V3020_WR].gpio, 0);
+ udelay(1);
+ gpio_set_value(chip->gpio[V3020_WR].gpio, 1);
+ gpio_set_value(chip->gpio[V3020_CS].gpio, 1);
+}
+
+static unsigned char v3020_gpio_read_bit(struct v3020 *chip)
+{
+ int bit;
+
+ gpio_direction_input(chip->gpio[V3020_IO].gpio);
+ gpio_set_value(chip->gpio[V3020_CS].gpio, 0);
+ gpio_set_value(chip->gpio[V3020_RD].gpio, 0);
+ udelay(1);
+ bit = !!gpio_get_value(chip->gpio[V3020_IO].gpio);
+ udelay(1);
+ gpio_set_value(chip->gpio[V3020_RD].gpio, 1);
+ gpio_set_value(chip->gpio[V3020_CS].gpio, 1);
+
+ return bit;
+}
+
+static struct v3020_chip_ops v3020_gpio_ops = {
+ .map_io = v3020_gpio_map,
+ .unmap_io = v3020_gpio_unmap,
+ .read_bit = v3020_gpio_read_bit,
+ .write_bit = v3020_gpio_write_bit,
+};
+
static void v3020_set_reg(struct v3020 *chip, unsigned char address,
unsigned char data)
{
@@ -46,7 +191,7 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address,
tmp = address;
for (i = 0; i < 4; i++) {
- writel((tmp & 1) << chip->leftshift, chip->ioaddress);
+ chip->ops->write_bit(chip, (tmp & 1));
tmp >>= 1;
udelay(1);
}
@@ -54,7 +199,7 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address,
/* Commands dont have data */
if (!V3020_IS_COMMAND(address)) {
for (i = 0; i < 8; i++) {
- writel((data & 1) << chip->leftshift, chip->ioaddress);
+ chip->ops->write_bit(chip, (data & 1));
data >>= 1;
udelay(1);
}
@@ -63,18 +208,18 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address,
static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address)
{
- unsigned int data=0;
+ unsigned int data = 0;
int i;
for (i = 0; i < 4; i++) {
- writel((address & 1) << chip->leftshift, chip->ioaddress);
+ chip->ops->write_bit(chip, (address & 1));
address >>= 1;
udelay(1);
}
for (i = 0; i < 8; i++) {
data >>= 1;
- if (readl(chip->ioaddress) & (1 << chip->leftshift))
+ if (chip->ops->read_bit(chip))
data |= 0x80;
udelay(1);
}
@@ -106,16 +251,14 @@ static int v3020_read_time(struct device *dev, struct rtc_time *dt)
tmp = v3020_get_reg(chip, V3020_YEAR);
dt->tm_year = bcd2bin(tmp)+100;
-#ifdef DEBUG
- printk("\n%s : Read RTC values\n",__func__);
- printk("tm_hour: %i\n",dt->tm_hour);
- printk("tm_min : %i\n",dt->tm_min);
- printk("tm_sec : %i\n",dt->tm_sec);
- printk("tm_year: %i\n",dt->tm_year);
- printk("tm_mon : %i\n",dt->tm_mon);
- printk("tm_mday: %i\n",dt->tm_mday);
- printk("tm_wday: %i\n",dt->tm_wday);
-#endif
+ dev_dbg(dev, "\n%s : Read RTC values\n", __func__);
+ dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
+ dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
+ dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
+ dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
+ dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
+ dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
+ dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
return 0;
}
@@ -125,15 +268,13 @@ static int v3020_set_time(struct device *dev, struct rtc_time *dt)
{
struct v3020 *chip = dev_get_drvdata(dev);
-#ifdef DEBUG
- printk("\n%s : Setting RTC values\n",__func__);
- printk("tm_sec : %i\n",dt->tm_sec);
- printk("tm_min : %i\n",dt->tm_min);
- printk("tm_hour: %i\n",dt->tm_hour);
- printk("tm_mday: %i\n",dt->tm_mday);
- printk("tm_wday: %i\n",dt->tm_wday);
- printk("tm_year: %i\n",dt->tm_year);
-#endif
+ dev_dbg(dev, "\n%s : Setting RTC values\n", __func__);
+ dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
+ dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
+ dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
+ dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
+ dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
+ dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
/* Write all the values to ram... */
v3020_set_reg(chip, V3020_SECONDS, bin2bcd(dt->tm_sec));
@@ -168,30 +309,28 @@ static int rtc_probe(struct platform_device *pdev)
int i;
int temp;
- if (pdev->num_resources != 1)
- return -EBUSY;
-
- if (pdev->resource[0].flags != IORESOURCE_MEM)
- return -EBUSY;
-
chip = kzalloc(sizeof *chip, GFP_KERNEL);
if (!chip)
return -ENOMEM;
- chip->leftshift = pdata->leftshift;
- chip->ioaddress = ioremap(pdev->resource[0].start, 1);
- if (chip->ioaddress == NULL)
+ if (pdata->use_gpio)
+ chip->ops = &v3020_gpio_ops;
+ else
+ chip->ops = &v3020_mmio_ops;
+
+ retval = chip->ops->map_io(chip, pdev, pdata);
+ if (retval)
goto err_chip;
/* Make sure the v3020 expects a communication cycle
* by reading 8 times */
for (i = 0; i < 8; i++)
- temp = readl(chip->ioaddress);
+ temp = chip->ops->read_bit(chip);
/* Test chip by doing a write/read sequence
* to the chip ram */
v3020_set_reg(chip, V3020_SECONDS, 0x33);
- if(v3020_get_reg(chip, V3020_SECONDS) != 0x33) {
+ if (v3020_get_reg(chip, V3020_SECONDS) != 0x33) {
retval = -ENODEV;
goto err_io;
}
@@ -200,10 +339,17 @@ static int rtc_probe(struct platform_device *pdev)
* are all disabled */
v3020_set_reg(chip, V3020_STATUS_0, 0x0);
- dev_info(&pdev->dev, "Chip available at physical address 0x%llx,"
- "data connected to D%d\n",
- (unsigned long long)pdev->resource[0].start,
- chip->leftshift);
+ if (pdata->use_gpio)
+ dev_info(&pdev->dev, "Chip available at GPIOs "
+ "%d, %d, %d, %d\n",
+ chip->gpio[V3020_CS].gpio, chip->gpio[V3020_WR].gpio,
+ chip->gpio[V3020_RD].gpio, chip->gpio[V3020_IO].gpio);
+ else
+ dev_info(&pdev->dev, "Chip available at "
+ "physical address 0x%llx,"
+ "data connected to D%d\n",
+ (unsigned long long)pdev->resource[0].start,
+ chip->leftshift);
platform_set_drvdata(pdev, chip);
@@ -218,7 +364,7 @@ static int rtc_probe(struct platform_device *pdev)
return 0;
err_io:
- iounmap(chip->ioaddress);
+ chip->ops->unmap_io(chip);
err_chip:
kfree(chip);
@@ -233,7 +379,7 @@ static int rtc_remove(struct platform_device *dev)
if (rtc)
rtc_device_unregister(rtc);
- iounmap(chip->ioaddress);
+ chip->ops->unmap_io(chip);
kfree(chip);
return 0;
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c
index 5c5e3aa91385..c91edc572eb6 100644
--- a/drivers/rtc/rtc-wm8350.c
+++ b/drivers/rtc/rtc-wm8350.c
@@ -122,7 +122,7 @@ static int wm8350_rtc_settime(struct device *dev, struct rtc_time *tm)
do {
rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
schedule_timeout_uninterruptible(msecs_to_jiffies(1));
- } while (retries-- && !(rtc_ctrl & WM8350_RTC_STS));
+ } while (--retries && !(rtc_ctrl & WM8350_RTC_STS));
if (!retries) {
dev_err(dev, "timed out on set confirmation\n");
@@ -236,6 +236,17 @@ static int wm8350_rtc_start_alarm(struct wm8350 *wm8350)
return 0;
}
+static int wm8350_rtc_alarm_irq_enable(struct device *dev,
+ unsigned int enabled)
+{
+ struct wm8350 *wm8350 = dev_get_drvdata(dev);
+
+ if (enabled)
+ return wm8350_rtc_start_alarm(wm8350);
+ else
+ return wm8350_rtc_stop_alarm(wm8350);
+}
+
static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct wm8350 *wm8350 = dev_get_drvdata(dev);
@@ -291,30 +302,15 @@ static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
return ret;
}
-/*
- * Handle commands from user-space
- */
-static int wm8350_rtc_ioctl(struct device *dev, unsigned int cmd,
- unsigned long arg)
+static int wm8350_rtc_update_irq_enable(struct device *dev,
+ unsigned int enabled)
{
struct wm8350 *wm8350 = dev_get_drvdata(dev);
- switch (cmd) {
- case RTC_AIE_OFF:
- return wm8350_rtc_stop_alarm(wm8350);
- case RTC_AIE_ON:
- return wm8350_rtc_start_alarm(wm8350);
-
- case RTC_UIE_OFF:
- wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
- break;
- case RTC_UIE_ON:
+ if (enabled)
wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC);
- break;
-
- default:
- return -ENOIOCTLCMD;
- }
+ else
+ wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
return 0;
}
@@ -345,11 +341,12 @@ static void wm8350_rtc_update_handler(struct wm8350 *wm8350, int irq,
}
static const struct rtc_class_ops wm8350_rtc_ops = {
- .ioctl = wm8350_rtc_ioctl,
.read_time = wm8350_rtc_readtime,
.set_time = wm8350_rtc_settime,
.read_alarm = wm8350_rtc_readalarm,
.set_alarm = wm8350_rtc_setalarm,
+ .alarm_irq_enable = wm8350_rtc_alarm_irq_enable,
+ .update_irq_enable = wm8350_rtc_update_irq_enable,
};
#ifdef CONFIG_PM
@@ -440,7 +437,7 @@ static int wm8350_rtc_probe(struct platform_device *pdev)
do {
timectl = wm8350_reg_read(wm8350,
WM8350_RTC_TIME_CONTROL);
- } while (timectl & WM8350_RTC_STS && retries--);
+ } while (timectl & WM8350_RTC_STS && --retries);
if (retries == 0) {
dev_err(&pdev->dev, "failed to start: timeout\n");
diff --git a/drivers/s390/Makefile b/drivers/s390/Makefile
index d0eae59bc366..95bccfd3f169 100644
--- a/drivers/s390/Makefile
+++ b/drivers/s390/Makefile
@@ -2,9 +2,6 @@
# Makefile for the S/390 specific device drivers
#
-CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
-
-obj-y += s390mach.o sysinfo.o
obj-y += cio/ block/ char/ crypto/ net/ scsi/ kvm/
drivers-y += drivers/s390/built-in.o
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 08c23a921012..0570794ccf1c 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -9,6 +9,9 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -22,6 +25,7 @@
#include <asm/ebcdic.h>
#include <asm/idals.h>
#include <asm/todclk.h>
+#include <asm/itcw.h>
/* This is ugly... */
#define PRINTK_HEADER "dasd:"
@@ -221,7 +225,7 @@ static int dasd_state_known_to_basic(struct dasd_device *device)
return rc;
}
/* register 'device' debug area, used for all DBF_DEV_XXX calls */
- device->debug_area = debug_register(dev_name(&device->cdev->dev), 1, 1,
+ device->debug_area = debug_register(dev_name(&device->cdev->dev), 4, 1,
8 * sizeof(long));
debug_register_view(device->debug_area, &debug_sprintf_view);
debug_set_level(device->debug_area, DBF_WARNING);
@@ -762,7 +766,7 @@ static inline int dasd_check_cqr(struct dasd_ccw_req *cqr)
return -EINVAL;
device = cqr->startdev;
if (strncmp((char *) &cqr->magic, device->discipline->ebcname, 4)) {
- DEV_MESSAGE(KERN_WARNING, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
" dasd_ccw_req 0x%08x magic doesn't match"
" discipline 0x%08x",
cqr->magic,
@@ -782,6 +786,7 @@ int dasd_term_IO(struct dasd_ccw_req *cqr)
{
struct dasd_device *device;
int retries, rc;
+ char errorstring[ERRORLENGTH];
/* Check the cqr */
rc = dasd_check_cqr(cqr);
@@ -815,10 +820,10 @@ int dasd_term_IO(struct dasd_ccw_req *cqr)
"device busy, retry later");
break;
default:
- DEV_MESSAGE(KERN_ERR, device,
- "line %d unknown RC=%d, please "
- "report to linux390@de.ibm.com",
- __LINE__, rc);
+ /* internal error 10 - unknown rc*/
+ snprintf(errorstring, ERRORLENGTH, "10 %d", rc);
+ dev_err(&device->cdev->dev, "An error occurred in the "
+ "DASD device driver, reason=%s\n", errorstring);
BUG();
break;
}
@@ -836,6 +841,7 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
{
struct dasd_device *device;
int rc;
+ char errorstring[ERRORLENGTH];
/* Check the cqr */
rc = dasd_check_cqr(cqr);
@@ -843,17 +849,23 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
return rc;
device = (struct dasd_device *) cqr->startdev;
if (cqr->retries < 0) {
- DEV_MESSAGE(KERN_DEBUG, device,
- "start_IO: request %p (%02x/%i) - no retry left.",
- cqr, cqr->status, cqr->retries);
+ /* internal error 14 - start_IO run out of retries */
+ sprintf(errorstring, "14 %p", cqr);
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", errorstring);
cqr->status = DASD_CQR_ERROR;
return -EIO;
}
cqr->startclk = get_clock();
cqr->starttime = jiffies;
cqr->retries--;
- rc = ccw_device_start(device->cdev, cqr->cpaddr, (long) cqr,
- cqr->lpm, 0);
+ if (cqr->cpmode == 1) {
+ rc = ccw_device_tm_start(device->cdev, cqr->cpaddr,
+ (long) cqr, cqr->lpm);
+ } else {
+ rc = ccw_device_start(device->cdev, cqr->cpaddr,
+ (long) cqr, cqr->lpm, 0);
+ }
switch (rc) {
case 0:
cqr->status = DASD_CQR_IN_IO;
@@ -862,11 +874,11 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
cqr);
break;
case -EBUSY:
- DBF_DEV_EVENT(DBF_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"start_IO: device busy, retry later");
break;
case -ETIMEDOUT:
- DBF_DEV_EVENT(DBF_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"start_IO: request timeout, retry later");
break;
case -EACCES:
@@ -876,19 +888,24 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
* Do a retry with all available pathes.
*/
cqr->lpm = LPM_ANYPATH;
- DBF_DEV_EVENT(DBF_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"start_IO: selected pathes gone,"
" retry on all pathes");
break;
case -ENODEV:
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+ "start_IO: -ENODEV device gone, retry");
+ break;
case -EIO:
- DBF_DEV_EVENT(DBF_ERR, device, "%s",
- "start_IO: device gone, retry");
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
+ "start_IO: -EIO device gone, retry");
break;
default:
- DEV_MESSAGE(KERN_ERR, device,
- "line %d unknown RC=%d, please report"
- " to linux390@de.ibm.com", __LINE__, rc);
+ /* internal error 11 - unknown rc */
+ snprintf(errorstring, ERRORLENGTH, "11 %d", rc);
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", errorstring);
BUG();
break;
}
@@ -945,7 +962,7 @@ static void dasd_handle_killed_request(struct ccw_device *cdev,
return;
cqr = (struct dasd_ccw_req *) intparm;
if (cqr->status != DASD_CQR_IN_IO) {
- MESSAGE(KERN_DEBUG,
+ DBF_EVENT(DBF_DEBUG,
"invalid status in handle_killed_request: "
"bus_id %s, status %02x",
dev_name(&cdev->dev), cqr->status);
@@ -956,8 +973,8 @@ static void dasd_handle_killed_request(struct ccw_device *cdev,
if (device == NULL ||
device != dasd_device_from_cdev_locked(cdev) ||
strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
- MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s",
- dev_name(&cdev->dev));
+ DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
+ "bus_id %s", dev_name(&cdev->dev));
return;
}
@@ -996,11 +1013,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
case -EIO:
break;
case -ETIMEDOUT:
- printk(KERN_WARNING"%s(%s): request timed out\n",
+ DBF_EVENT(DBF_WARNING, "%s(%s): request timed out\n",
__func__, dev_name(&cdev->dev));
break;
default:
- printk(KERN_WARNING"%s(%s): unknown error %ld\n",
+ DBF_EVENT(DBF_WARNING, "%s(%s): unknown error %ld\n",
__func__, dev_name(&cdev->dev), PTR_ERR(irb));
}
dasd_handle_killed_request(cdev, intparm);
@@ -1009,15 +1026,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
now = get_clock();
- DBF_EVENT(DBF_ERR, "Interrupt: bus_id %s CS/DS %04x ip %08x",
- dev_name(&cdev->dev), ((irb->scsw.cmd.cstat << 8) |
- irb->scsw.cmd.dstat), (unsigned int) intparm);
-
/* check for unsolicited interrupts */
cqr = (struct dasd_ccw_req *) intparm;
- if (!cqr || ((irb->scsw.cmd.cc == 1) &&
- (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
- (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND))) {
+ if (!cqr || ((scsw_cc(&irb->scsw) == 1) &&
+ (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
+ (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))) {
if (cqr && cqr->status == DASD_CQR_IN_IO)
cqr->status = DASD_CQR_QUEUED;
device = dasd_device_from_cdev_locked(cdev);
@@ -1033,14 +1046,14 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
device = (struct dasd_device *) cqr->startdev;
if (!device ||
strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
- MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s",
- dev_name(&cdev->dev));
+ DBF_DEV_EVENT(DBF_DEBUG, device, "invalid device in request: "
+ "bus_id %s", dev_name(&cdev->dev));
return;
}
/* Check for clear pending */
if (cqr->status == DASD_CQR_CLEAR_PENDING &&
- irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC) {
+ scsw_fctl(&irb->scsw) & SCSW_FCTL_CLEAR_FUNC) {
cqr->status = DASD_CQR_CLEARED;
dasd_device_clear_timer(device);
wake_up(&dasd_flush_wq);
@@ -1048,19 +1061,17 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
return;
}
- /* check status - the request might have been killed by dyn detach */
+ /* check status - the request might have been killed by dyn detach */
if (cqr->status != DASD_CQR_IN_IO) {
- MESSAGE(KERN_DEBUG,
- "invalid status: bus_id %s, status %02x",
- dev_name(&cdev->dev), cqr->status);
+ DBF_DEV_EVENT(DBF_DEBUG, device, "invalid status: bus_id %s, "
+ "status %02x", dev_name(&cdev->dev), cqr->status);
return;
}
- DBF_DEV_EVENT(DBF_DEBUG, device, "Int: CS/DS 0x%04x for cqr %p",
- ((irb->scsw.cmd.cstat << 8) | irb->scsw.cmd.dstat), cqr);
+
next = NULL;
expires = 0;
- if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
- irb->scsw.cmd.cstat == 0 && !irb->esw.esw0.erw.cons) {
+ if (scsw_dstat(&irb->scsw) == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
+ scsw_cstat(&irb->scsw) == 0) {
/* request was completed successfully */
cqr->status = DASD_CQR_SUCCESS;
cqr->stopclk = now;
@@ -1071,18 +1082,23 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
}
} else { /* error */
memcpy(&cqr->irb, irb, sizeof(struct irb));
+ /* log sense for every failed I/O to s390 debugfeature */
+ dasd_log_sense_dbf(cqr, irb);
if (device->features & DASD_FEATURE_ERPLOG) {
dasd_log_sense(cqr, irb);
}
+
/*
* If we don't want complex ERP for this request, then just
* reset this and retry it in the fastpath
*/
if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags) &&
cqr->retries > 0) {
- DEV_MESSAGE(KERN_DEBUG, device,
- "default ERP in fastpath (%i retries left)",
- cqr->retries);
+ if (cqr->lpm == LPM_ANYPATH)
+ DBF_DEV_EVENT(DBF_DEBUG, device,
+ "default ERP in fastpath "
+ "(%i retries left)",
+ cqr->retries);
cqr->lpm = LPM_ANYPATH;
cqr->status = DASD_CQR_QUEUED;
next = cqr;
@@ -1093,10 +1109,6 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
(!device->stopped)) {
if (device->discipline->start_IO(next) == 0)
expires = next->expires;
- else
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
- "Interrupt fastpath "
- "failed!");
}
if (expires != 0)
dasd_device_set_timer(device, expires);
@@ -1169,6 +1181,7 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
struct dasd_block *block;
void (*callback)(struct dasd_ccw_req *, void *data);
void *callback_data;
+ char errorstring[ERRORLENGTH];
list_for_each_safe(l, n, final_queue) {
cqr = list_entry(l, struct dasd_ccw_req, devlist);
@@ -1189,10 +1202,11 @@ static void __dasd_device_process_final_queue(struct dasd_device *device,
cqr->status = DASD_CQR_TERMINATED;
break;
default:
- DEV_MESSAGE(KERN_ERR, device,
- "wrong cqr status in __dasd_process_final_queue "
- "for cqr %p, status %x",
- cqr, cqr->status);
+ /* internal error 12 - wrong cqr status*/
+ snprintf(errorstring, ERRORLENGTH, "12 %p %x02", cqr, cqr->status);
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", errorstring);
BUG();
}
if (cqr->callback != NULL)
@@ -1217,18 +1231,17 @@ static void __dasd_device_check_expire(struct dasd_device *device)
(time_after_eq(jiffies, cqr->expires + cqr->starttime))) {
if (device->discipline->term_IO(cqr) != 0) {
/* Hmpf, try again in 5 sec */
- DEV_MESSAGE(KERN_ERR, device,
- "internal error - timeout (%is) expired "
- "for cqr %p, termination failed, "
- "retrying in 5s",
- (cqr->expires/HZ), cqr);
+ dev_err(&device->cdev->dev,
+ "cqr %p timed out (%is) but cannot be "
+ "ended, retrying in 5 s\n",
+ cqr, (cqr->expires/HZ));
cqr->expires += 5*HZ;
dasd_device_set_timer(device, 5*HZ);
} else {
- DEV_MESSAGE(KERN_ERR, device,
- "internal error - timeout (%is) expired "
- "for cqr %p (%i retries left)",
- (cqr->expires/HZ), cqr, cqr->retries);
+ dev_err(&device->cdev->dev,
+ "cqr %p timed out (%is), %i retries "
+ "remaining\n", cqr, (cqr->expires/HZ),
+ cqr->retries);
}
}
}
@@ -1290,10 +1303,9 @@ int dasd_flush_device_queue(struct dasd_device *device)
rc = device->discipline->term_IO(cqr);
if (rc) {
/* unable to terminate requeust */
- DEV_MESSAGE(KERN_ERR, device,
- "dasd flush ccw_queue is unable "
- " to terminate request %p",
- cqr);
+ dev_err(&device->cdev->dev,
+ "Flushing the DASD request queue "
+ "failed for request %p\n", cqr);
/* stop flush processing */
goto finished;
}
@@ -1537,10 +1549,9 @@ int dasd_cancel_req(struct dasd_ccw_req *cqr)
/* request in IO - terminate IO and release again */
rc = device->discipline->term_IO(cqr);
if (rc) {
- DEV_MESSAGE(KERN_ERR, device,
- "dasd_cancel_req is unable "
- " to terminate request %p, rc = %d",
- cqr, rc);
+ dev_err(&device->cdev->dev,
+ "Cancelling request %p failed with rc=%d\n",
+ cqr, rc);
} else {
cqr->stopclk = get_clock();
rc = 1;
@@ -1617,7 +1628,7 @@ static inline void __dasd_block_process_erp(struct dasd_block *block,
if (cqr->status == DASD_CQR_DONE)
DBF_DEV_EVENT(DBF_NOTICE, device, "%s", "ERP successful");
else
- DEV_MESSAGE(KERN_ERR, device, "%s", "ERP unsuccessful");
+ dev_err(&device->cdev->dev, "ERP failed for the DASD\n");
erp_fn = device->discipline->erp_postaction(cqr);
erp_fn(cqr);
}
@@ -1991,8 +2002,11 @@ static void dasd_setup_queue(struct dasd_block *block)
blk_queue_max_sectors(block->request_queue, max);
blk_queue_max_phys_segments(block->request_queue, -1L);
blk_queue_max_hw_segments(block->request_queue, -1L);
- blk_queue_max_segment_size(block->request_queue, -1L);
- blk_queue_segment_boundary(block->request_queue, -1L);
+ /* with page sized segments we can translate each segement into
+ * one idaw/tidaw
+ */
+ blk_queue_max_segment_size(block->request_queue, PAGE_SIZE);
+ blk_queue_segment_boundary(block->request_queue, PAGE_SIZE - 1);
blk_queue_ordered(block->request_queue, QUEUE_ORDERED_DRAIN, NULL);
}
@@ -2043,8 +2057,9 @@ static int dasd_open(struct block_device *bdev, fmode_t mode)
}
if (dasd_probeonly) {
- DEV_MESSAGE(KERN_INFO, base, "%s",
- "No access to device due to probeonly mode");
+ dev_info(&base->cdev->dev,
+ "Accessing the DASD failed because it is in "
+ "probeonly mode\n");
rc = -EPERM;
goto out;
}
@@ -2101,7 +2116,8 @@ dasd_device_operations = {
.owner = THIS_MODULE,
.open = dasd_open,
.release = dasd_release,
- .locked_ioctl = dasd_ioctl,
+ .ioctl = dasd_ioctl,
+ .compat_ioctl = dasd_ioctl,
.getgeo = dasd_getgeo,
};
@@ -2143,14 +2159,14 @@ int dasd_generic_probe(struct ccw_device *cdev,
ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
if (ret) {
- printk(KERN_WARNING
+ DBF_EVENT(DBF_WARNING,
"dasd_generic_probe: could not set ccw-device options "
"for %s\n", dev_name(&cdev->dev));
return ret;
}
ret = dasd_add_sysfs_files(cdev);
if (ret) {
- printk(KERN_WARNING
+ DBF_EVENT(DBF_WARNING,
"dasd_generic_probe: could not add sysfs entries "
"for %s\n", dev_name(&cdev->dev));
return ret;
@@ -2166,9 +2182,7 @@ int dasd_generic_probe(struct ccw_device *cdev,
(dasd_autodetect && dasd_busid_known(dev_name(&cdev->dev)) != 0))
ret = ccw_device_set_online(cdev);
if (ret)
- printk(KERN_WARNING
- "dasd_generic_probe: could not initially "
- "online ccw-device %s; return code: %d\n",
+ pr_warning("%s: Setting the DASD online failed with rc=%d\n",
dev_name(&cdev->dev), ret);
return 0;
}
@@ -2232,10 +2246,9 @@ int dasd_generic_set_online(struct ccw_device *cdev,
discipline = base_discipline;
if (device->features & DASD_FEATURE_USEDIAG) {
if (!dasd_diag_discipline_pointer) {
- printk (KERN_WARNING
- "dasd_generic couldn't online device %s "
- "- discipline DIAG not available\n",
- dev_name(&cdev->dev));
+ pr_warning("%s Setting the DASD online failed because "
+ "of missing DIAG discipline\n",
+ dev_name(&cdev->dev));
dasd_delete_device(device);
return -ENODEV;
}
@@ -2256,10 +2269,9 @@ int dasd_generic_set_online(struct ccw_device *cdev,
/* check_device will allocate block device if necessary */
rc = discipline->check_device(device);
if (rc) {
- printk (KERN_WARNING
- "dasd_generic couldn't online device %s "
- "with discipline %s rc=%i\n",
- dev_name(&cdev->dev), discipline->name, rc);
+ pr_warning("%s Setting the DASD online with discipline %s "
+ "failed with rc=%i\n",
+ dev_name(&cdev->dev), discipline->name, rc);
module_put(discipline->owner);
module_put(base_discipline->owner);
dasd_delete_device(device);
@@ -2268,9 +2280,8 @@ int dasd_generic_set_online(struct ccw_device *cdev,
dasd_set_target_state(device, DASD_STATE_ONLINE);
if (device->state <= DASD_STATE_KNOWN) {
- printk (KERN_WARNING
- "dasd_generic discipline not found for %s\n",
- dev_name(&cdev->dev));
+ pr_warning("%s Setting the DASD online failed because of a "
+ "missing discipline\n", dev_name(&cdev->dev));
rc = -ENODEV;
dasd_set_target_state(device, DASD_STATE_NEW);
if (device->block)
@@ -2314,13 +2325,13 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
open_count = atomic_read(&device->block->open_count);
if (open_count > max_count) {
if (open_count > 0)
- printk(KERN_WARNING "Can't offline dasd "
- "device with open count = %i.\n",
- open_count);
+ pr_warning("%s: The DASD cannot be set offline "
+ "with open count %i\n",
+ dev_name(&cdev->dev), open_count);
else
- printk(KERN_WARNING "%s",
- "Can't offline dasd device due "
- "to internal use\n");
+ pr_warning("%s: The DASD cannot be set offline "
+ "while it is in use\n",
+ dev_name(&cdev->dev));
clear_bit(DASD_FLAG_OFFLINE, &device->flags);
dasd_put_device(device);
return -EBUSY;
@@ -2352,6 +2363,7 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
ret = 0;
switch (event) {
case CIO_GONE:
+ case CIO_BOXED:
case CIO_NO_PATH:
/* First of all call extended error reporting. */
dasd_eer_write(device, NULL, DASD_EER_NOPATH);
@@ -2393,8 +2405,10 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Could not allocate RDC request");
+ /* internal error 13 - Allocating the RDC request failed*/
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "13");
return cqr;
}
@@ -2431,6 +2445,40 @@ int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic,
}
EXPORT_SYMBOL_GPL(dasd_generic_read_dev_chars);
+/*
+ * In command mode and transport mode we need to look for sense
+ * data in different places. The sense data itself is allways
+ * an array of 32 bytes, so we can unify the sense data access
+ * for both modes.
+ */
+char *dasd_get_sense(struct irb *irb)
+{
+ struct tsb *tsb = NULL;
+ char *sense = NULL;
+
+ if (scsw_is_tm(&irb->scsw) && (irb->scsw.tm.fcxs == 0x01)) {
+ if (irb->scsw.tm.tcw)
+ tsb = tcw_get_tsb((struct tcw *)(unsigned long)
+ irb->scsw.tm.tcw);
+ if (tsb && tsb->length == 64 && tsb->flags)
+ switch (tsb->flags & 0x07) {
+ case 1: /* tsa_iostat */
+ sense = tsb->tsa.iostat.sense;
+ break;
+ case 2: /* tsa_ddpc */
+ sense = tsb->tsa.ddpc.sense;
+ break;
+ default:
+ /* currently we don't use interrogate data */
+ break;
+ }
+ } else if (irb->esw.esw0.erw.cons) {
+ sense = irb->ecw;
+ }
+ return sense;
+}
+EXPORT_SYMBOL_GPL(dasd_get_sense);
+
static int __init dasd_init(void)
{
int rc;
@@ -2472,7 +2520,7 @@ static int __init dasd_init(void)
return 0;
failed:
- MESSAGE(KERN_INFO, "%s", "initialization not performed due to errors");
+ pr_info("The DASD device driver could not be initialized\n");
dasd_exit();
return rc;
}
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index d82aad5224f0..27991b692056 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -7,6 +7,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/timer.h>
#include <linux/slab.h>
#include <asm/idals.h>
@@ -75,7 +77,7 @@ dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires)
struct dasd_device *device = erp->startdev;
unsigned long flags;
- DEV_MESSAGE(KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"blocking request queue for %is", expires/HZ);
spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
@@ -114,9 +116,9 @@ dasd_3990_erp_int_req(struct dasd_ccw_req * erp)
} else {
/* issue a message and wait for 'device ready' interrupt */
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ dev_err(&device->cdev->dev,
"is offline or not installed - "
- "INTERVENTION REQUIRED!!");
+ "INTERVENTION REQUIRED!!\n");
dasd_3990_erp_block_queue(erp, 60*HZ);
}
@@ -158,7 +160,7 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
if ((erp->lpm & opm) != 0x00) {
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
"try alternate lpm=%x (lpum=%x / opm=%x)",
erp->lpm, erp->irb.esw.esw0.sublog.lpum, opm);
@@ -166,10 +168,9 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
erp->status = DASD_CQR_FILLED;
erp->retries = 10;
} else {
- DEV_MESSAGE(KERN_ERR, device,
- "No alternate channel path left (lpum=%x / "
- "opm=%x) -> permanent error",
- erp->irb.esw.esw0.sublog.lpum, opm);
+ dev_err(&device->cdev->dev,
+ "The DASD cannot be reached on any path (lpum=%x"
+ "/opm=%x)\n", erp->irb.esw.esw0.sublog.lpum, opm);
/* post request with permanent error */
erp->status = DASD_CQR_FAILED;
@@ -204,8 +205,8 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier)
sizeof(struct DCTL_data),
device);
if (IS_ERR(dctl_cqr)) {
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Unable to allocate DCTL-CQR");
+ dev_err(&device->cdev->dev,
+ "Unable to allocate DCTL-CQR\n");
erp->status = DASD_CQR_FAILED;
return erp;
}
@@ -294,7 +295,7 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
/* interrupt (this enables easier enqueing of the cqr) */
if (erp->function != dasd_3990_erp_action_4) {
- DEV_MESSAGE(KERN_INFO, device, "%s",
+ DBF_DEV_EVENT(DBF_INFO, device, "%s",
"dasd_3990_erp_action_4: first time retry");
erp->retries = 256;
@@ -303,7 +304,7 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
} else {
if (sense && (sense[25] == 0x1D)) { /* state change pending */
- DEV_MESSAGE(KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"waiting for state change pending "
"interrupt, %d retries left",
erp->retries);
@@ -311,15 +312,14 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
dasd_3990_erp_block_queue(erp, 30*HZ);
} else if (sense && (sense[25] == 0x1E)) { /* busy */
- DEV_MESSAGE(KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"busy - redriving request later, "
"%d retries left",
erp->retries);
dasd_3990_erp_block_queue(erp, HZ);
} else {
-
/* no state change pending - retry */
- DEV_MESSAGE (KERN_INFO, device,
+ DBF_DEV_EVENT(DBF_INFO, device,
"redriving request immediately, "
"%d retries left",
erp->retries);
@@ -384,6 +384,7 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
struct dasd_device *device = erp->startdev;
char msg_format = (sense[7] & 0xF0);
char msg_no = (sense[7] & 0x0F);
+ char errorstring[ERRORLENGTH];
switch (msg_format) {
case 0x00: /* Format 0 - Program or System Checks */
@@ -394,95 +395,97 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
case 0x00: /* No Message */
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Invalid Command");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Invalid Command\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Invalid Command "
- "Sequence");
+ "Sequence\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - CCW Count less than "
- "required");
+ "required\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Invalid Parameter");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Invalid Parameter\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Diagnostic of Sepecial"
- " Command Violates File Mask");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Diagnostic of Special"
+ " Command Violates File Mask\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Channel Returned with "
- "Incorrect retry CCW");
+ "Incorrect retry CCW\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reset Notification");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reset Notification\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Storage Path Restart");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Storage Path Restart\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device,
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Channel requested "
- "... %02x", sense[8]);
+ "... %02x\n", sense[8]);
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Invalid Defective/"
- "Alternate Track Pointer");
+ "Alternate Track Pointer\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - DPS Installation "
- "Check");
+ "Check\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Command Invalid on "
- "Secondary Address");
+ "Secondary Address\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device,
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Status Not As "
- "Required: reason %02x", sense[8]);
+ "Required: reason %02x\n",
+ sense[8]);
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reseved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reserved\n");
}
} else {
switch (msg_no) {
case 0x00: /* No Message */
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Device Error Source");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Device Error "
+ "Source\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reserved\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device,
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Device Fenced - "
- "device = %02x", sense[4]);
+ "device = %02x\n", sense[4]);
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 0 - Data Pinned for "
- "Device");
+ "Device\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 0 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 0 - Reserved\n");
}
}
break;
@@ -492,348 +495,352 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
case 0x00: /* No Message */
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Device Status 1 not as "
- "expected");
+ "expected\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Index missing");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Index missing\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Interruption cannot be reset");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Interruption cannot be "
+ "reset\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Device did not respond to "
- "selection");
+ "selection\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Device check-2 error or Set "
- "Sector is not complete");
+ "Sector is not complete\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Head address does not "
- "compare");
+ "compare\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Device status 1 not valid");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Device status 1 not valid\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Device not ready");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Device not ready\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Track physical address did "
- "not compare");
+ "not compare\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Missing device address bit");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Missing device address bit\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Drive motor switch is off");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Drive motor switch is off\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Seek incomplete");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Seek incomplete\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Cylinder address did not "
- "compare");
+ "compare\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 1 - Offset active cannot be "
- "reset");
+ "reset\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 1 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 1 - Reserved\n");
}
break;
case 0x20: /* Format 2 - 3990 Equipment Checks */
switch (msg_no) {
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 2 - 3990 check-2 error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - 3990 check-2 error\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 2 - Support facility errors");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - Support facility errors\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device,
- "FORMAT 2 - Microcode detected error %02x",
- sense[8]);
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - Microcode detected error "
+ "%02x\n",
+ sense[8]);
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 2 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 2 - Reserved\n");
}
break;
case 0x30: /* Format 3 - 3990 Control Checks */
switch (msg_no) {
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 3 - Allegiance terminated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 3 - Allegiance terminated\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 3 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 3 - Reserved\n");
}
break;
case 0x40: /* Format 4 - Data Checks */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Home address area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Home address area error\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Count area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Count area error\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Key area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Key area error\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Data area error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Data area error\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in home address "
- "area");
+ "area\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in count address "
- "area");
+ "area\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - No sync byte in key area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - No sync byte in key area\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - No sync byte in data area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - No sync byte in data area\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Home address area error; "
- "offset active");
+ "offset active\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Count area error; offset "
- "active");
+ "active\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Key area error; offset "
- "active");
+ "active\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - Data area error; "
- "offset active");
+ "offset active\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in home "
- "address area; offset active");
+ "address area; offset active\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No syn byte in count "
- "address area; offset active");
+ "address area; offset active\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No sync byte in key area; "
- "offset active");
+ "offset active\n");
break;
case 0x0F:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 4 - No syn byte in data area; "
- "offset active");
+ "offset active\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 4 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 4 - Reserved\n");
}
break;
case 0x50: /* Format 5 - Data Check with displacement information */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the "
- "home address area");
+ "home address area\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Data Check in the count area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Data Check in the count "
+ "area\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Data Check in the key area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Data Check in the key area\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Data Check in the data area");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Data Check in the data "
+ "area\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the "
- "home address area; offset active");
+ "home address area; offset active\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the count area; "
- "offset active");
+ "offset active\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the key area; "
- "offset active");
+ "offset active\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 5 - Data Check in the data area; "
- "offset active");
+ "offset active\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 5 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 5 - Reserved\n");
}
break;
case 0x60: /* Format 6 - Usage Statistics/Overrun Errors */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel A");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel A\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel B");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel B\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel C");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel C\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel D");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel D\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel E");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel E\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel F");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel F\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel G");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel G\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Overrun on channel H");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Overrun on channel H\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 6 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 6 - Reserved\n");
}
break;
case 0x70: /* Format 7 - Device Connection Control Checks */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - RCC initiated by a connection "
- "check alert");
+ "check alert\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - RCC 1 sequence not "
- "successful");
+ "successful\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - RCC 1 and RCC 2 sequences not "
- "successful");
+ "successful\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid tag-in during "
- "selection sequence");
+ "selection sequence\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 7 - extra RCC required");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 7 - extra RCC required\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid DCC selection "
- "response or timeout");
+ "response or timeout\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Missing end operation; device "
- "transfer complete");
+ "transfer complete\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Missing end operation; device "
- "transfer incomplete");
+ "transfer incomplete\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid tag-in for an "
- "immediate command sequence");
+ "immediate command sequence\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Invalid tag-in for an "
- "extended command sequence");
+ "extended command sequence\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - 3990 microcode time out when "
- "stopping selection");
+ "stopping selection\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - No response to selection "
- "after a poll interruption");
+ "after a poll interruption\n");
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - Permanent path error (DASD "
- "controller not available)");
+ "controller not available)\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 7 - DASD controller not available"
- " on disconnected command chain");
+ " on disconnected command chain\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 7 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 7 - Reserved\n");
}
break;
@@ -841,52 +848,52 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
switch (msg_no) {
case 0x00: /* No Message */
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - Error correction code "
- "hardware fault");
+ "hardware fault\n");
break;
case 0x03:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - Unexpected end operation "
- "response code");
+ "response code\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - End operation with transfer "
- "count not zero");
+ "count not zero\n");
break;
case 0x05:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - End operation with transfer "
- "count zero");
+ "count zero\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - DPS checks after a system "
- "reset or selective reset");
+ "reset or selective reset\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 8 - DPS cannot be filled");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 8 - DPS cannot be filled\n");
break;
case 0x08:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - Short busy time-out during "
- "device selection");
+ "device selection\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - DASD controller failed to "
- "set or reset the long busy latch");
+ "set or reset the long busy latch\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 8 - No interruption from device "
- "during a command chain");
+ "during a command chain\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 8 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 8 - Reserved\n");
}
break;
@@ -895,97 +902,100 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
case 0x00:
break; /* No Message */
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 9 - Device check-2 error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 9 - Device check-2 error\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 9 - Head address did not compare");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 9 - Head address did not "
+ "compare\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 9 - Track physical address did "
- "not compare while oriented");
+ "not compare while oriented\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT 9 - Cylinder address did not "
- "compare");
+ "compare\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT 9 - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT 9 - Reserved\n");
}
break;
case 0xF0: /* Format F - Cache Storage Checks */
switch (msg_no) {
case 0x00:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Operation Terminated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Operation Terminated\n");
break;
case 0x01:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Subsystem Processing Error");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Subsystem Processing Error\n");
break;
case 0x02:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Cache or nonvolatile storage "
- "equipment failure");
+ "equipment failure\n");
break;
case 0x04:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Caching terminated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Caching terminated\n");
break;
case 0x06:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Cache fast write access not "
- "authorized");
+ "authorized\n");
break;
case 0x07:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Track format incorrect");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Track format incorrect\n");
break;
case 0x09:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Caching reinitiated");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Caching reinitiated\n");
break;
case 0x0A:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Nonvolatile storage "
- "terminated");
+ "terminated\n");
break;
case 0x0B:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Volume is suspended duplex");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Volume is suspended duplex\n");
/* call extended error reporting (EER) */
dasd_eer_write(device, erp->refers,
DASD_EER_PPRCSUSPEND);
break;
case 0x0C:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - Subsystem status connot be "
- "determined");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - Subsystem status cannot be "
+ "determined\n");
break;
case 0x0D:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ dev_warn(&device->cdev->dev,
"FORMAT F - Caching status reset to "
- "default");
+ "default\n");
break;
case 0x0E:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT F - DASD Fast Write inhibited");
+ dev_warn(&device->cdev->dev,
+ "FORMAT F - DASD Fast Write inhibited\n");
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "FORMAT D - Reserved");
+ dev_warn(&device->cdev->dev,
+ "FORMAT D - Reserved\n");
}
break;
- default: /* unknown message format - should not happen */
- DEV_MESSAGE (KERN_WARNING, device,
- "unknown message format %02x",
- msg_format);
+ default: /* unknown message format - should not happen
+ internal error 03 - unknown message format */
+ snprintf(errorstring, ERRORLENGTH, "03 %x02", msg_format);
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", errorstring);
break;
} /* end switch message format */
@@ -1015,7 +1025,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
/* env data present (ACTION 10 - retry should work) */
if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Command Reject - environmental data present");
dasd_3990_handle_env_data(erp, sense);
@@ -1023,9 +1033,10 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
erp->retries = 5;
} else {
- /* fatal error - set status to FAILED */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Command Reject - Fatal error");
+ /* fatal error - set status to FAILED
+ internal error 09 - Command Reject */
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "09");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
}
@@ -1061,7 +1072,7 @@ dasd_3990_erp_bus_out(struct dasd_ccw_req * erp)
} else {
/* issue a message and wait for 'device ready' interrupt */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"bus out parity error or BOPC requested by "
"channel");
@@ -1093,21 +1104,19 @@ dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
erp->function = dasd_3990_erp_equip_check;
if (sense[1] & SNS1_WRITE_INHIBITED) {
+ dev_info(&device->cdev->dev,
+ "Write inhibited path encountered\n");
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
- "Write inhibited path encountered");
-
- /* vary path offline */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Path should be varied off-line. "
- "This is not implemented yet \n - please report "
- "to linux390@de.ibm.com");
+ /* vary path offline
+ internal error 04 - Path should be varied off-line.*/
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "04");
erp = dasd_3990_erp_action_1(erp);
} else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Equipment Check - " "environmental data present");
dasd_3990_handle_env_data(erp, sense);
@@ -1116,7 +1125,7 @@ dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
} else if (sense[1] & SNS1_PERM_ERR) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Equipment Check - retry exhausted or "
"undesirable");
@@ -1125,7 +1134,7 @@ dasd_3990_erp_equip_check(struct dasd_ccw_req * erp, char *sense)
} else {
/* all other equipment checks - Action 5 */
/* rest is done when retries == 0 */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Equipment check or processing error");
erp = dasd_3990_erp_action_5(erp);
@@ -1156,9 +1165,9 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
if (sense[2] & SNS2_CORRECTABLE) { /* correctable data check */
/* issue message that the data has been corrected */
- DEV_MESSAGE(KERN_EMERG, device, "%s",
+ dev_emerg(&device->cdev->dev,
"Data recovered during retry with PCI "
- "fetch mode active");
+ "fetch mode active\n");
/* not possible to handle this situation in Linux */
panic("No way to inform application about the possibly "
@@ -1166,7 +1175,7 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
} else if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Uncorrectable data check recovered secondary "
"addr of duplex pair");
@@ -1174,7 +1183,7 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
} else if (sense[1] & SNS1_PERM_ERR) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Uncorrectable data check with internal "
"retry exhausted");
@@ -1182,7 +1191,7 @@ dasd_3990_erp_data_check(struct dasd_ccw_req * erp, char *sense)
} else {
/* all other data checks */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Uncorrectable data check with retry count "
"exhausted...");
@@ -1212,7 +1221,7 @@ dasd_3990_erp_overrun(struct dasd_ccw_req * erp, char *sense)
erp->function = dasd_3990_erp_overrun;
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Overrun - service overrun or overrun"
" error requested by channel");
@@ -1243,7 +1252,7 @@ dasd_3990_erp_inv_format(struct dasd_ccw_req * erp, char *sense)
if (sense[2] & SNS2_ENV_DATA_PRESENT) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Track format error when destaging or "
"staging data");
@@ -1252,8 +1261,10 @@ dasd_3990_erp_inv_format(struct dasd_ccw_req * erp, char *sense)
erp = dasd_3990_erp_action_4(erp, sense);
} else {
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Invalid Track Format - Fatal error");
+ /* internal error 06 - The track format is not valid*/
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "06");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
}
@@ -1279,8 +1290,8 @@ dasd_3990_erp_EOC(struct dasd_ccw_req * default_erp, char *sense)
struct dasd_device *device = default_erp->startdev;
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "End-of-Cylinder - must never happen");
+ dev_err(&device->cdev->dev,
+ "The cylinder data for accessing the DASD is inconsistent\n");
/* implement action 7 - BUG */
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
@@ -1306,7 +1317,7 @@ dasd_3990_erp_env_data(struct dasd_ccw_req * erp, char *sense)
erp->function = dasd_3990_erp_env_data;
- DEV_MESSAGE(KERN_DEBUG, device, "%s", "Environmental data present");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Environmental data present");
dasd_3990_handle_env_data(erp, sense);
@@ -1339,8 +1350,8 @@ dasd_3990_erp_no_rec(struct dasd_ccw_req * default_erp, char *sense)
struct dasd_device *device = default_erp->startdev;
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "No Record Found - Fatal error ");
+ dev_err(&device->cdev->dev,
+ "The specified record was not found\n");
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
@@ -1365,7 +1376,8 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp)
struct dasd_device *device = erp->startdev;
- DEV_MESSAGE(KERN_ERR, device, "%s", "File Protected");
+ dev_err(&device->cdev->dev, "Accessing the DASD failed because of "
+ "a hardware error\n");
return dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
@@ -1394,7 +1406,7 @@ static struct dasd_ccw_req *dasd_3990_erp_inspect_alias(
if (cqr->block &&
(cqr->block->base != cqr->startdev)) {
if (cqr->startdev->features & DASD_FEATURE_ERPLOG) {
- DEV_MESSAGE(KERN_ERR, cqr->startdev,
+ DBF_DEV_EVENT(DBF_ERR, cqr->startdev,
"ERP on alias device for request %p,"
" recover on base device %s", cqr,
dev_name(&cqr->block->base->cdev->dev));
@@ -1511,7 +1523,7 @@ dasd_3990_erp_action_10_32(struct dasd_ccw_req * erp, char *sense)
erp->retries = 256;
erp->function = dasd_3990_erp_action_10_32;
- DEV_MESSAGE(KERN_DEBUG, device, "%s", "Perform logging requested");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Perform logging requested");
return erp;
@@ -1549,7 +1561,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
char *LO_data; /* LO_eckd_data_t */
struct ccw1 *ccw, *oldccw;
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Write not finished because of unexpected condition");
default_erp->function = dasd_3990_erp_action_1B_32;
@@ -1561,10 +1573,16 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
cqr = cqr->refers;
}
+ if (scsw_is_tm(&cqr->irb.scsw)) {
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "32 bit sense, action 1B is not defined"
+ " in transport mode - just retry");
+ return default_erp;
+ }
+
/* for imprecise ending just do default erp */
if (sense[1] & 0x01) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Imprecise ending is set - just retry");
return default_erp;
@@ -1575,8 +1593,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
cpa = default_erp->refers->irb.scsw.cmd.cpa;
if (cpa == 0) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Unable to determine address of the CCW "
"to be restarted");
@@ -1590,7 +1607,9 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
sizeof(struct LO_eckd_data), device);
if (IS_ERR(erp)) {
- DEV_MESSAGE(KERN_ERR, device, "%s", "Unable to allocate ERP");
+ /* internal error 01 - Unable to allocate ERP */
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "01");
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
}
@@ -1599,7 +1618,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
oldccw = cqr->cpaddr;
if (oldccw->cmd_code == DASD_ECKD_CCW_PFX) {
PFX_data = cqr->data;
- memcpy(DE_data, &PFX_data->define_extend,
+ memcpy(DE_data, &PFX_data->define_extent,
sizeof(struct DE_eckd_data));
} else
memcpy(DE_data, cqr->data, sizeof(struct DE_eckd_data));
@@ -1608,10 +1627,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
LO_data = erp->data + sizeof(struct DE_eckd_data);
if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "BUG - this should not happen");
-
+ /* should not */
return dasd_3990_erp_cleanup(default_erp, DASD_CQR_FAILED);
}
@@ -1701,7 +1717,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
char *LO_data; /* struct LO_eckd_data */
struct ccw1 *ccw;
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Write not finished because of unexpected condition"
" - follow on");
@@ -1712,10 +1728,16 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
cqr = cqr->refers;
}
+ if (scsw_is_tm(&cqr->irb.scsw)) {
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "32 bit sense, action 1B, update,"
+ " in transport mode - just retry");
+ return previous_erp;
+ }
+
/* for imprecise ending just do default erp */
if (sense[1] & 0x01) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Imprecise ending is set - just retry");
previous_erp->status = DASD_CQR_FILLED;
@@ -1728,10 +1750,10 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
cpa = previous_erp->irb.scsw.cmd.cpa;
if (cpa == 0) {
-
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
- "Unable to determine address of the CCW "
- "to be restarted");
+ /* internal error 02 -
+ Unable to determine address of the CCW to be restarted */
+ dev_err(&device->cdev->dev, "An error occurred in the DASD "
+ "device driver, reason=%s\n", "02");
previous_erp->status = DASD_CQR_FAILED;
@@ -1744,10 +1766,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
LO_data = erp->data + sizeof(struct DE_eckd_data);
if ((sense[3] == 0x01) && (LO_data[1] & 0x01)) {
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "BUG - this should not happen");
-
+ /* should not happen */
previous_erp->status = DASD_CQR_FAILED;
return previous_erp;
@@ -1935,14 +1954,13 @@ dasd_3990_erp_compound_config(struct dasd_ccw_req * erp, char *sense)
if ((sense[25] & DASD_SENSE_BIT_1) && (sense[26] & DASD_SENSE_BIT_2)) {
- /* set to suspended duplex state then restart */
+ /* set to suspended duplex state then restart
+ internal error 05 - Set device to suspended duplex state
+ should be done */
struct dasd_device *device = erp->startdev;
-
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Set device to suspended duplex state should be "
- "done!\n"
- "This is not implemented yet (for compound ERP)"
- " - please report to linux390@de.ibm.com");
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "05");
}
@@ -2012,15 +2030,14 @@ dasd_3990_erp_handle_sim(struct dasd_device *device, char *sense)
{
/* print message according to log or message to operator mode */
if ((sense[24] & DASD_SIM_MSG_TO_OP) || (sense[1] & 0x10)) {
-
/* print SIM SRC from RefCode */
- DEV_MESSAGE(KERN_ERR, device, "SIM - SRC: "
- "%02x%02x%02x%02x", sense[22],
+ dev_err(&device->cdev->dev, "SIM - SRC: "
+ "%02x%02x%02x%02x\n", sense[22],
sense[23], sense[11], sense[12]);
} else if (sense[24] & DASD_SIM_LOG) {
/* print SIM SRC Refcode */
- DEV_MESSAGE(KERN_WARNING, device, "SIM - SRC: "
- "%02x%02x%02x%02x", sense[22],
+ dev_warn(&device->cdev->dev, "log SIM - SRC: "
+ "%02x%02x%02x%02x\n", sense[22],
sense[23], sense[11], sense[12]);
}
}
@@ -2063,14 +2080,14 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
switch (sense[25]) {
case 0x00: /* success - use default ERP for retries */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
"ERP called for successful request"
" - just retry");
break;
case 0x01: /* fatal error */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "Retry not recommended - Fatal error");
+ dev_err(&device->cdev->dev,
+ "ERP failed for the DASD\n");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
break;
@@ -2080,13 +2097,10 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
erp = dasd_3990_erp_int_req(erp);
break;
- case 0x0F: /* length mismatch during update write command */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "update write command error - should not "
- "happen;\n"
- "Please send this message together with "
- "the above sense data to linux390@de."
- "ibm.com");
+ case 0x0F: /* length mismatch during update write command
+ internal error 08 - update write command error*/
+ dev_err(&device->cdev->dev, "An error occurred in the "
+ "DASD device driver, reason=%s\n", "08");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
break;
@@ -2095,13 +2109,12 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
erp = dasd_3990_erp_action_10_32(erp, sense);
break;
- case 0x15: /* next track outside defined extend */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "next track outside defined extend - "
- "should not happen;\n"
- "Please send this message together with "
- "the above sense data to linux390@de."
- "ibm.com");
+ case 0x15: /* next track outside defined extend
+ internal error 07 - The next track is not
+ within the defined storage extent */
+ dev_err(&device->cdev->dev,
+ "An error occurred in the DASD device driver, "
+ "reason=%s\n", "07");
erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED);
break;
@@ -2112,9 +2125,9 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
break;
case 0x1C: /* invalid data */
- DEV_MESSAGE(KERN_EMERG, device, "%s",
+ dev_emerg(&device->cdev->dev,
"Data recovered during retry with PCI "
- "fetch mode active");
+ "fetch mode active\n");
/* not possible to handle this situation in Linux */
panic
@@ -2123,7 +2136,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
break;
case 0x1D: /* state-change pending */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"A State change pending condition exists "
"for the subsystem or device");
@@ -2131,7 +2144,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
break;
case 0x1E: /* busy */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Busy condition exists "
"for the subsystem or device");
erp = dasd_3990_erp_action_4(erp, sense);
@@ -2171,9 +2184,9 @@ dasd_3990_erp_control_check(struct dasd_ccw_req *erp)
{
struct dasd_device *device = erp->startdev;
- if (erp->refers->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK
+ if (scsw_cstat(&erp->refers->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK
| SCHN_STAT_CHN_CTRL_CHK)) {
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"channel or interface control check");
erp = dasd_3990_erp_action_4(erp, NULL);
}
@@ -2193,21 +2206,23 @@ dasd_3990_erp_control_check(struct dasd_ccw_req *erp)
* erp_new contens was possibly modified
*/
static struct dasd_ccw_req *
-dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
+dasd_3990_erp_inspect(struct dasd_ccw_req *erp)
{
struct dasd_ccw_req *erp_new = NULL;
- /* sense data are located in the refers record of the */
- /* already set up new ERP ! */
- char *sense = erp->refers->irb.ecw;
+ char *sense;
/* if this problem occured on an alias retry on base */
erp_new = dasd_3990_erp_inspect_alias(erp);
if (erp_new)
return erp_new;
- /* check if no concurrent sens is available */
- if (!erp->refers->irb.esw.esw0.erw.cons)
+ /* sense data are located in the refers record of the
+ * already set up new ERP !
+ * check if concurrent sens is available
+ */
+ sense = dasd_get_sense(&erp->refers->irb);
+ if (!sense)
erp_new = dasd_3990_erp_control_check(erp);
/* distinguish between 24 and 32 byte sense data */
else if (sense[27] & DASD_SENSE_BIT_0) {
@@ -2231,7 +2246,11 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
* DESCRIPTION
* This funtion adds an additional request block (ERP) to the head of
* the given cqr (or erp).
- * This erp is initialized as an default erp (retry TIC)
+ * For a command mode cqr the erp is initialized as an default erp
+ * (retry TIC).
+ * For transport mode we make a copy of the original TCW (points to
+ * the original TCCB, TIDALs, etc.) but give it a fresh
+ * TSB so the original sense data will not be changed.
*
* PARAMETER
* cqr head of the current ERP-chain (or single cqr if
@@ -2239,25 +2258,35 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
* RETURN VALUES
* erp pointer to new ERP-chain head
*/
-static struct dasd_ccw_req *
-dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
+static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
{
struct dasd_device *device = cqr->startdev;
struct ccw1 *ccw;
-
- /* allocate additional request block */
struct dasd_ccw_req *erp;
+ int cplength, datasize;
+ struct tcw *tcw;
+ struct tsb *tsb;
+
+ if (cqr->cpmode == 1) {
+ cplength = 0;
+ datasize = sizeof(struct tcw) + sizeof(struct tsb);
+ } else {
+ cplength = 2;
+ datasize = 0;
+ }
- erp = dasd_alloc_erp_request((char *) &cqr->magic, 2, 0, device);
+ /* allocate additional request block */
+ erp = dasd_alloc_erp_request((char *) &cqr->magic,
+ cplength, datasize, device);
if (IS_ERR(erp)) {
if (cqr->retries <= 0) {
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_ERR, device, "%s",
"Unable to allocate ERP request");
cqr->status = DASD_CQR_FAILED;
cqr->stopclk = get_clock ();
} else {
- DEV_MESSAGE (KERN_ERR, device,
+ DBF_DEV_EVENT(DBF_ERR, device,
"Unable to allocate ERP request "
"(%i retries left)",
cqr->retries);
@@ -2266,13 +2295,24 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
return cqr;
}
- /* initialize request with default TIC to current ERP/CQR */
- ccw = erp->cpaddr;
- ccw->cmd_code = CCW_CMD_NOOP;
- ccw->flags = CCW_FLAG_CC;
- ccw++;
- ccw->cmd_code = CCW_CMD_TIC;
- ccw->cda = (long)(cqr->cpaddr);
+ if (cqr->cpmode == 1) {
+ /* make a shallow copy of the original tcw but set new tsb */
+ erp->cpmode = 1;
+ erp->cpaddr = erp->data;
+ tcw = erp->data;
+ tsb = (struct tsb *) &tcw[1];
+ *tcw = *((struct tcw *)cqr->cpaddr);
+ tcw->tsb = (long)tsb;
+ } else {
+ /* initialize request with default TIC to current ERP/CQR */
+ ccw = erp->cpaddr;
+ ccw->cmd_code = CCW_CMD_NOOP;
+ ccw->flags = CCW_FLAG_CC;
+ ccw++;
+ ccw->cmd_code = CCW_CMD_TIC;
+ ccw->cda = (long)(cqr->cpaddr);
+ }
+
erp->function = dasd_3990_erp_add_erp;
erp->refers = cqr;
erp->startdev = device;
@@ -2282,7 +2322,6 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
erp->expires = 0;
erp->retries = 256;
erp->buildclk = get_clock();
-
erp->status = DASD_CQR_FILLED;
return erp;
@@ -2340,28 +2379,33 @@ dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr)
* match 'boolean' for match found
* returns 1 if match found, otherwise 0.
*/
-static int
-dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2)
+static int dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1,
+ struct dasd_ccw_req *cqr2)
{
+ char *sense1, *sense2;
if (cqr1->startdev != cqr2->startdev)
return 0;
- if (cqr1->irb.esw.esw0.erw.cons != cqr2->irb.esw.esw0.erw.cons)
- return 0;
+ sense1 = dasd_get_sense(&cqr1->irb);
+ sense2 = dasd_get_sense(&cqr2->irb);
- if ((cqr1->irb.esw.esw0.erw.cons == 0) &&
- (cqr2->irb.esw.esw0.erw.cons == 0)) {
- if ((cqr1->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
- SCHN_STAT_CHN_CTRL_CHK)) ==
- (cqr2->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK |
- SCHN_STAT_CHN_CTRL_CHK)))
+ /* one request has sense data, the other not -> no match, return 0 */
+ if (!sense1 != !sense2)
+ return 0;
+ /* no sense data in both cases -> check cstat for IFCC */
+ if (!sense1 && !sense2) {
+ if ((scsw_cstat(&cqr1->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK |
+ SCHN_STAT_CHN_CTRL_CHK)) ==
+ (scsw_cstat(&cqr2->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK |
+ SCHN_STAT_CHN_CTRL_CHK)))
return 1; /* match with ifcc*/
}
/* check sense data; byte 0-2,25,27 */
- if (!((memcmp (cqr1->irb.ecw, cqr2->irb.ecw, 3) == 0) &&
- (cqr1->irb.ecw[27] == cqr2->irb.ecw[27]) &&
- (cqr1->irb.ecw[25] == cqr2->irb.ecw[25]))) {
+ if (!(sense1 && sense2 &&
+ (memcmp(sense1, sense2, 3) == 0) &&
+ (sense1[27] == sense2[27]) &&
+ (sense1[25] == sense2[25]))) {
return 0; /* sense doesn't match */
}
@@ -2434,7 +2478,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
{
struct dasd_device *device = erp->startdev;
- char *sense = erp->irb.ecw;
+ char *sense = dasd_get_sense(&erp->irb);
/* check for 24 byte sense ERP */
if ((erp->function == dasd_3990_erp_bus_out) ||
@@ -2449,7 +2493,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
/* prepare erp for retry on different channel path */
erp = dasd_3990_erp_action_1(erp);
- if (!(sense[2] & DASD_SENSE_BIT_0)) {
+ if (sense && !(sense[2] & DASD_SENSE_BIT_0)) {
/* issue a Diagnostic Control command with an
* Inhibit Write subcommand */
@@ -2471,7 +2515,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
break;
}
default:
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
"invalid subcommand modifier 0x%x "
"for Diagnostic Control Command",
sense[25]);
@@ -2479,19 +2523,21 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
}
/* check for 32 byte sense ERP */
- } else if ((erp->function == dasd_3990_erp_compound_retry) ||
- (erp->function == dasd_3990_erp_compound_path) ||
- (erp->function == dasd_3990_erp_compound_code) ||
- (erp->function == dasd_3990_erp_compound_config)) {
+ } else if (sense &&
+ ((erp->function == dasd_3990_erp_compound_retry) ||
+ (erp->function == dasd_3990_erp_compound_path) ||
+ (erp->function == dasd_3990_erp_compound_code) ||
+ (erp->function == dasd_3990_erp_compound_config))) {
erp = dasd_3990_erp_compound(erp, sense);
} else {
- /* No retry left and no additional special handling */
- /*necessary */
- DEV_MESSAGE(KERN_ERR, device,
- "no retries left for erp %p - "
- "set status to FAILED", erp);
+ /*
+ * No retry left and no additional special handling
+ * necessary
+ */
+ dev_err(&device->cdev->dev,
+ "ERP %p has run out of retries and failed\n", erp);
erp->status = DASD_CQR_FAILED;
}
@@ -2548,24 +2594,25 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head,
if (erp->retries > 0) {
- char *sense = erp->refers->irb.ecw;
+ char *sense = dasd_get_sense(&erp->refers->irb);
/* check for special retries */
- if (erp->function == dasd_3990_erp_action_4) {
+ if (sense && erp->function == dasd_3990_erp_action_4) {
erp = dasd_3990_erp_action_4(erp, sense);
- } else if (erp->function == dasd_3990_erp_action_1B_32) {
+ } else if (sense &&
+ erp->function == dasd_3990_erp_action_1B_32) {
erp = dasd_3990_update_1B(erp, sense);
- } else if (erp->function == dasd_3990_erp_int_req) {
+ } else if (sense && erp->function == dasd_3990_erp_int_req) {
erp = dasd_3990_erp_int_req(erp);
} else {
/* simple retry */
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_DEBUG, device,
"%i retries left for erp %p",
erp->retries, erp);
@@ -2609,24 +2656,24 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
if (device->features & DASD_FEATURE_ERPLOG) {
/* print current erp_chain */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "ERP chain at BEGINNING of ERP-ACTION");
+ dev_err(&device->cdev->dev,
+ "ERP chain at BEGINNING of ERP-ACTION\n");
for (temp_erp = cqr;
temp_erp != NULL; temp_erp = temp_erp->refers) {
- DEV_MESSAGE(KERN_ERR, device,
- " erp %p (%02x) refers to %p",
+ dev_err(&device->cdev->dev,
+ "ERP %p (%02x) refers to %p\n",
temp_erp, temp_erp->status,
temp_erp->refers);
}
}
/* double-check if current erp/cqr was successful */
- if ((cqr->irb.scsw.cmd.cstat == 0x00) &&
- (cqr->irb.scsw.cmd.dstat ==
+ if ((scsw_cstat(&cqr->irb.scsw) == 0x00) &&
+ (scsw_dstat(&cqr->irb.scsw) ==
(DEV_STAT_CHN_END | DEV_STAT_DEV_END))) {
- DEV_MESSAGE(KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_DEBUG, device,
"ERP called for successful request %p"
" - NO ERP necessary", cqr);
@@ -2648,13 +2695,13 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
if (device->features & DASD_FEATURE_ERPLOG) {
/* print current erp_chain */
- DEV_MESSAGE(KERN_ERR, device, "%s",
- "ERP chain at END of ERP-ACTION");
+ dev_err(&device->cdev->dev,
+ "ERP chain at END of ERP-ACTION\n");
for (temp_erp = erp;
temp_erp != NULL; temp_erp = temp_erp->refers) {
- DEV_MESSAGE(KERN_ERR, device,
- " erp %p (%02x) refers to %p",
+ dev_err(&device->cdev->dev,
+ "ERP %p (%02x) refers to %p\n",
temp_erp, temp_erp->status,
temp_erp->refers);
}
@@ -2667,6 +2714,8 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
list_add_tail(&erp->blocklist, &cqr->blocklist);
}
+
+
return erp;
} /* end dasd_3990_erp_action */
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
index 20676cdef4a5..5b7bbc87593b 100644
--- a/drivers/s390/block/dasd_alias.c
+++ b/drivers/s390/block/dasd_alias.c
@@ -5,6 +5,8 @@
* Author(s): Stefan Weinhuber <wein@de.ibm.com>
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/list.h>
#include <asm/ebcdic.h>
#include "dasd_int.h"
@@ -503,7 +505,7 @@ static void lcu_update_work(struct work_struct *work)
*/
spin_lock_irqsave(&lcu->lock, flags);
if (rc || (lcu->flags & NEED_UAC_UPDATE)) {
- DEV_MESSAGE(KERN_WARNING, device, "could not update"
+ DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
" alias data in lcu (rc = %d), retry later", rc);
schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
} else {
@@ -646,14 +648,16 @@ static int reset_summary_unit_check(struct alias_lcu *lcu,
{
struct dasd_ccw_req *cqr;
int rc = 0;
+ struct ccw1 *ccw;
cqr = lcu->rsu_cqr;
strncpy((char *) &cqr->magic, "ECKD", 4);
ASCEBC((char *) &cqr->magic, 4);
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RSCK;
- cqr->cpaddr->flags = 0 ;
- cqr->cpaddr->count = 16;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_RSCK;
+ ccw->flags = 0 ;
+ ccw->count = 16;
+ ccw->cda = (__u32)(addr_t) cqr->data;
((char *)cqr->data)[0] = reason;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -855,16 +859,25 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
struct alias_lcu *lcu;
char reason;
struct dasd_eckd_private *private;
+ char *sense;
private = (struct dasd_eckd_private *) device->private;
- reason = irb->ecw[8];
- DEV_MESSAGE(KERN_WARNING, device, "%s %x",
- "eckd handle summary unit check: reason", reason);
+ sense = dasd_get_sense(irb);
+ if (sense) {
+ reason = sense[8];
+ DBF_DEV_EVENT(DBF_NOTICE, device, "%s %x",
+ "eckd handle summary unit check: reason", reason);
+ } else {
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "eckd handle summary unit check:"
+ " no reason code available");
+ return;
+ }
lcu = private->lcu;
if (!lcu) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"device not ready to handle summary"
" unit check (no lcu structure)");
return;
@@ -877,7 +890,7 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
* the next interrupt on a different device
*/
if (list_empty(&device->alias_list)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"device is in offline processing,"
" don't do summary unit check handling");
spin_unlock(&lcu->lock);
@@ -885,7 +898,7 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
}
if (lcu->suc_data.device) {
/* already scheduled or running */
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"previous instance of summary unit check worker"
" still pending");
spin_unlock(&lcu->lock);
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 34339902efb9..e77666c8e6c0 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -13,6 +13,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -67,6 +69,8 @@ int dasd_probeonly = 0; /* is true, when probeonly mode is active */
int dasd_autodetect = 0; /* is true, when autodetection is active */
int dasd_nopav = 0; /* is true, when PAV is disabled */
EXPORT_SYMBOL_GPL(dasd_nopav);
+int dasd_nofcx; /* disable High Performance Ficon */
+EXPORT_SYMBOL_GPL(dasd_nofcx);
/*
* char *dasd[] is intended to hold the ranges supplied by the dasd= statement
@@ -125,6 +129,7 @@ __setup ("dasd=", dasd_call_setup);
* Read a device busid/devno from a string.
*/
static int
+
dasd_busid(char **str, int *id0, int *id1, int *devno)
{
int val, old_style;
@@ -132,8 +137,7 @@ dasd_busid(char **str, int *id0, int *id1, int *devno)
/* Interpret ipldev busid */
if (strncmp(DASD_IPLDEV, *str, strlen(DASD_IPLDEV)) == 0) {
if (ipl_info.type != IPL_TYPE_CCW) {
- MESSAGE(KERN_ERR, "%s", "ipl device is not a ccw "
- "device");
+ pr_err("The IPL device is not a CCW device\n");
return -EINVAL;
}
*id0 = 0;
@@ -209,9 +213,8 @@ dasd_feature_list(char *str, char **endp)
else if (len == 8 && !strncmp(str, "failfast", 8))
features |= DASD_FEATURE_FAILFAST;
else {
- MESSAGE(KERN_WARNING,
- "unsupported feature: %*s, "
- "ignoring setting", len, str);
+ pr_warning("%*s is not a supported device option\n",
+ len, str);
rc = -EINVAL;
}
str += len;
@@ -220,8 +223,8 @@ dasd_feature_list(char *str, char **endp)
str++;
}
if (*str != ')') {
- MESSAGE(KERN_WARNING, "%s",
- "missing ')' in dasd parameter string\n");
+ pr_warning("A closing parenthesis ')' is missing in the "
+ "dasd= parameter\n");
rc = -EINVAL;
} else
str++;
@@ -253,25 +256,29 @@ dasd_parse_keyword( char *parsestring ) {
}
if (strncmp("autodetect", parsestring, length) == 0) {
dasd_autodetect = 1;
- MESSAGE (KERN_INFO, "%s",
- "turning to autodetection mode");
+ pr_info("The autodetection mode has been activated\n");
return residual_str;
}
if (strncmp("probeonly", parsestring, length) == 0) {
dasd_probeonly = 1;
- MESSAGE(KERN_INFO, "%s",
- "turning to probeonly mode");
+ pr_info("The probeonly mode has been activated\n");
return residual_str;
}
if (strncmp("nopav", parsestring, length) == 0) {
if (MACHINE_IS_VM)
- MESSAGE(KERN_INFO, "%s", "'nopav' not supported on VM");
+ pr_info("'nopav' is not supported on z/VM\n");
else {
dasd_nopav = 1;
- MESSAGE(KERN_INFO, "%s", "disable PAV mode");
+ pr_info("PAV support has be deactivated\n");
}
return residual_str;
}
+ if (strncmp("nofcx", parsestring, length) == 0) {
+ dasd_nofcx = 1;
+ pr_info("High Performance FICON support has been "
+ "deactivated\n");
+ return residual_str;
+ }
if (strncmp("fixedbuffers", parsestring, length) == 0) {
if (dasd_page_cache)
return residual_str;
@@ -280,10 +287,10 @@ dasd_parse_keyword( char *parsestring ) {
PAGE_SIZE, SLAB_CACHE_DMA,
NULL);
if (!dasd_page_cache)
- MESSAGE(KERN_WARNING, "%s", "Failed to create slab, "
+ DBF_EVENT(DBF_WARNING, "%s", "Failed to create slab, "
"fixed buffer mode disabled.");
else
- MESSAGE (KERN_INFO, "%s",
+ DBF_EVENT(DBF_INFO, "%s",
"turning on fixed buffer mode");
return residual_str;
}
@@ -321,7 +328,7 @@ dasd_parse_range( char *parsestring ) {
(from_id0 != to_id0 || from_id1 != to_id1 || from > to))
rc = -EINVAL;
if (rc) {
- MESSAGE(KERN_ERR, "Invalid device range %s", parsestring);
+ pr_err("%s is not a valid device range\n", parsestring);
return ERR_PTR(rc);
}
features = dasd_feature_list(str, &str);
@@ -340,8 +347,8 @@ dasd_parse_range( char *parsestring ) {
return str + 1;
if (*str == '\0')
return str;
- MESSAGE(KERN_WARNING,
- "junk at end of dasd parameter string: %s\n", str);
+ pr_warning("The dasd= parameter value %s has an invalid ending\n",
+ str);
return ERR_PTR(-EINVAL);
}
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index ef2a56952054..b9a7f7733446 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -8,6 +8,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -144,8 +146,8 @@ dasd_diag_erp(struct dasd_device *device)
mdsk_term_io(device);
rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
if (rc)
- DEV_MESSAGE(KERN_WARNING, device, "DIAG ERP unsuccessful, "
- "rc=%d", rc);
+ dev_warn(&device->cdev->dev, "DIAG ERP failed with "
+ "rc=%d\n", rc);
}
/* Start a given request at the device. Return zero on success, non-zero
@@ -160,7 +162,7 @@ dasd_start_diag(struct dasd_ccw_req * cqr)
device = cqr->startdev;
if (cqr->retries < 0) {
- DEV_MESSAGE(KERN_WARNING, device, "DIAG start_IO: request %p "
+ DBF_DEV_EVENT(DBF_ERR, device, "DIAG start_IO: request %p "
"- no retry left)", cqr);
cqr->status = DASD_CQR_ERROR;
return -EIO;
@@ -195,7 +197,7 @@ dasd_start_diag(struct dasd_ccw_req * cqr)
break;
default: /* Error condition */
cqr->status = DASD_CQR_QUEUED;
- DEV_MESSAGE(KERN_WARNING, device, "dia250 returned rc=%d", rc);
+ DBF_DEV_EVENT(DBF_WARNING, device, "dia250 returned rc=%d", rc);
dasd_diag_erp(device);
rc = -EIO;
break;
@@ -243,13 +245,14 @@ dasd_ext_handler(__u16 code)
return;
}
if (!ip) { /* no intparm: unsolicited interrupt */
- MESSAGE(KERN_DEBUG, "%s", "caught unsolicited interrupt");
+ DBF_EVENT(DBF_NOTICE, "%s", "caught unsolicited "
+ "interrupt");
return;
}
cqr = (struct dasd_ccw_req *) ip;
device = (struct dasd_device *) cqr->startdev;
if (strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
- DEV_MESSAGE(KERN_WARNING, device,
+ DBF_DEV_EVENT(DBF_WARNING, device,
" magic number of dasd_ccw_req 0x%08X doesn't"
" match discipline 0x%08X",
cqr->magic, *(int *) (&device->discipline->name));
@@ -281,15 +284,11 @@ dasd_ext_handler(__u16 code)
rc = dasd_start_diag(next);
if (rc == 0)
expires = next->expires;
- else if (rc != -EACCES)
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Interrupt fastpath "
- "failed!");
}
}
} else {
cqr->status = DASD_CQR_QUEUED;
- DEV_MESSAGE(KERN_WARNING, device, "interrupt status for "
+ DBF_DEV_EVENT(DBF_DEBUG, device, "interrupt status for "
"request %p was %d (%d retries left)", cqr, status,
cqr->retries);
dasd_diag_erp(device);
@@ -322,8 +321,9 @@ dasd_diag_check_device(struct dasd_device *device)
if (private == NULL) {
private = kzalloc(sizeof(struct dasd_diag_private),GFP_KERNEL);
if (private == NULL) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "memory allocation failed for private data");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "Allocating memory for private DASD data "
+ "failed\n");
return -ENOMEM;
}
ccw_device_get_id(device->cdev, &private->dev_id);
@@ -331,7 +331,7 @@ dasd_diag_check_device(struct dasd_device *device)
}
block = dasd_alloc_block();
if (IS_ERR(block)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"could not allocate dasd block structure");
device->private = NULL;
kfree(private);
@@ -347,7 +347,7 @@ dasd_diag_check_device(struct dasd_device *device)
rc = diag210((struct diag210 *) rdc_data);
if (rc) {
- DEV_MESSAGE(KERN_WARNING, device, "failed to retrieve device "
+ DBF_DEV_EVENT(DBF_WARNING, device, "failed to retrieve device "
"information (rc=%d)", rc);
rc = -EOPNOTSUPP;
goto out;
@@ -362,8 +362,8 @@ dasd_diag_check_device(struct dasd_device *device)
private->pt_block = 2;
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "unsupported device class "
- "(class=%d)", private->rdc_data.vdev_class);
+ dev_warn(&device->cdev->dev, "Device type %d is not supported "
+ "in DIAG mode\n", private->rdc_data.vdev_class);
rc = -EOPNOTSUPP;
goto out;
}
@@ -380,7 +380,7 @@ dasd_diag_check_device(struct dasd_device *device)
/* figure out blocksize of device */
label = (struct vtoc_cms_label *) get_zeroed_page(GFP_KERNEL);
if (label == NULL) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"No memory to allocate initialization request");
rc = -ENOMEM;
goto out;
@@ -404,8 +404,8 @@ dasd_diag_check_device(struct dasd_device *device)
private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
rc = dia250(&private->iob, RW_BIO);
if (rc == 3) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "DIAG call failed");
+ dev_warn(&device->cdev->dev,
+ "A 64-bit DIAG call failed\n");
rc = -EOPNOTSUPP;
goto out_label;
}
@@ -414,8 +414,8 @@ dasd_diag_check_device(struct dasd_device *device)
break;
}
if (bsize > PAGE_SIZE) {
- DEV_MESSAGE(KERN_WARNING, device, "device access failed "
- "(rc=%d)", rc);
+ dev_warn(&device->cdev->dev, "Accessing the DASD failed because"
+ " of an incorrect format (rc=%d)\n", rc);
rc = -EIO;
goto out_label;
}
@@ -433,15 +433,15 @@ dasd_diag_check_device(struct dasd_device *device)
block->s2b_shift++;
rc = mdsk_init_io(device, block->bp_block, 0, NULL);
if (rc) {
- DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization "
- "failed (rc=%d)", rc);
+ dev_warn(&device->cdev->dev, "DIAG initialization "
+ "failed with rc=%d\n", rc);
rc = -EIO;
} else {
- DEV_MESSAGE(KERN_INFO, device,
- "(%ld B/blk): %ldkB",
- (unsigned long) block->bp_block,
- (unsigned long) (block->blocks <<
- block->s2b_shift) >> 1);
+ dev_info(&device->cdev->dev,
+ "New DASD with %ld byte/block, total size %ld KB\n",
+ (unsigned long) block->bp_block,
+ (unsigned long) (block->blocks <<
+ block->s2b_shift) >> 1);
}
out_label:
free_page((long) label);
@@ -595,7 +595,7 @@ static void
dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
struct irb *stat)
{
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"dump sense not available for DIAG data");
}
@@ -621,10 +621,8 @@ static int __init
dasd_diag_init(void)
{
if (!MACHINE_IS_VM) {
- MESSAGE_LOG(KERN_INFO,
- "Machine is not VM: %s "
- "discipline not initializing",
- dasd_diag_discipline.name);
+ pr_info("Discipline %s cannot be used without z/VM\n",
+ dasd_diag_discipline.name);
return -ENODEV;
}
ASCEBC(dasd_diag_discipline.ebcname, 4);
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index bdb87998f364..21254793c604 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -11,6 +11,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -27,9 +29,12 @@
#include <asm/uaccess.h>
#include <asm/cio.h>
#include <asm/ccwdev.h>
+#include <asm/itcw.h>
#include "dasd_int.h"
#include "dasd_eckd.h"
+#include "../cio/chsc.h"
+
#ifdef PRINTK_HEADER
#undef PRINTK_HEADER
@@ -84,7 +89,7 @@ dasd_eckd_probe (struct ccw_device *cdev)
/* set ECKD specific ccw-device options */
ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
if (ret) {
- printk(KERN_WARNING
+ DBF_EVENT(DBF_WARNING,
"dasd_eckd_probe: could not set ccw-device options "
"for %s\n", dev_name(&cdev->dev));
return ret;
@@ -159,6 +164,14 @@ recs_per_track(struct dasd_eckd_characteristics * rdc,
return 0;
}
+static void set_ch_t(struct ch_t *geo, __u32 cyl, __u8 head)
+{
+ geo->cyl = (__u16) cyl;
+ geo->head = cyl >> 16;
+ geo->head <<= 4;
+ geo->head |= head;
+}
+
static int
check_XRC (struct ccw1 *de_ccw,
struct DE_eckd_data *data,
@@ -186,11 +199,12 @@ check_XRC (struct ccw1 *de_ccw,
}
static int
-define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
- int totrk, int cmd, struct dasd_device * device)
+define_extent(struct ccw1 *ccw, struct DE_eckd_data *data, unsigned int trk,
+ unsigned int totrk, int cmd, struct dasd_device *device)
{
struct dasd_eckd_private *private;
- struct ch_t geo, beg, end;
+ u32 begcyl, endcyl;
+ u16 heads, beghead, endhead;
int rc = 0;
private = (struct dasd_eckd_private *) device->private;
@@ -236,7 +250,8 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
rc = check_XRC (ccw, data, device);
break;
default:
- DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
+ dev_err(&device->cdev->dev,
+ "0x%x is not a known command\n", cmd);
break;
}
@@ -248,27 +263,24 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
&& !(private->uses_cdl && trk < 2))
data->ga_extended |= 0x40; /* Regular Data Format Mode */
- geo.cyl = private->rdc_data.no_cyl;
- geo.head = private->rdc_data.trk_per_cyl;
- beg.cyl = trk / geo.head;
- beg.head = trk % geo.head;
- end.cyl = totrk / geo.head;
- end.head = totrk % geo.head;
+ heads = private->rdc_data.trk_per_cyl;
+ begcyl = trk / heads;
+ beghead = trk % heads;
+ endcyl = totrk / heads;
+ endhead = totrk % heads;
/* check for sequential prestage - enhance cylinder range */
if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
data->attributes.operation == DASD_SEQ_ACCESS) {
- if (end.cyl + private->attrib.nr_cyl < geo.cyl)
- end.cyl += private->attrib.nr_cyl;
+ if (endcyl + private->attrib.nr_cyl < private->real_cyl)
+ endcyl += private->attrib.nr_cyl;
else
- end.cyl = (geo.cyl - 1);
+ endcyl = (private->real_cyl - 1);
}
- data->beg_ext.cyl = beg.cyl;
- data->beg_ext.head = beg.head;
- data->end_ext.cyl = end.cyl;
- data->end_ext.head = end.head;
+ set_ch_t(&data->beg_ext, begcyl, beghead);
+ set_ch_t(&data->end_ext, endcyl, endhead);
return rc;
}
@@ -283,29 +295,145 @@ static int check_XRC_on_prefix(struct PFX_eckd_data *pfxdata,
return 0;
/* switch on System Time Stamp - needed for XRC Support */
- pfxdata->define_extend.ga_extended |= 0x08; /* 'Time Stamp Valid' */
- pfxdata->define_extend.ga_extended |= 0x02; /* 'Extended Parameter' */
+ pfxdata->define_extent.ga_extended |= 0x08; /* 'Time Stamp Valid' */
+ pfxdata->define_extent.ga_extended |= 0x02; /* 'Extended Parameter' */
pfxdata->validity.time_stamp = 1; /* 'Time Stamp Valid' */
- rc = get_sync_clock(&pfxdata->define_extend.ep_sys_time);
+ rc = get_sync_clock(&pfxdata->define_extent.ep_sys_time);
/* Ignore return code if sync clock is switched off. */
if (rc == -ENOSYS || rc == -EACCES)
rc = 0;
return rc;
}
-static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk,
- int totrk, int cmd, struct dasd_device *basedev,
- struct dasd_device *startdev)
+static void fill_LRE_data(struct LRE_eckd_data *data, unsigned int trk,
+ unsigned int rec_on_trk, int count, int cmd,
+ struct dasd_device *device, unsigned int reclen,
+ unsigned int tlf)
+{
+ struct dasd_eckd_private *private;
+ int sector;
+ int dn, d;
+
+ private = (struct dasd_eckd_private *) device->private;
+
+ memset(data, 0, sizeof(*data));
+ sector = 0;
+ if (rec_on_trk) {
+ switch (private->rdc_data.dev_type) {
+ case 0x3390:
+ dn = ceil_quot(reclen + 6, 232);
+ d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34);
+ sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
+ break;
+ case 0x3380:
+ d = 7 + ceil_quot(reclen + 12, 32);
+ sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
+ break;
+ }
+ }
+ data->sector = sector;
+ /* note: meaning of count depends on the operation
+ * for record based I/O it's the number of records, but for
+ * track based I/O it's the number of tracks
+ */
+ data->count = count;
+ switch (cmd) {
+ case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
+ data->operation.orientation = 0x3;
+ data->operation.operation = 0x03;
+ break;
+ case DASD_ECKD_CCW_READ_HOME_ADDRESS:
+ data->operation.orientation = 0x3;
+ data->operation.operation = 0x16;
+ break;
+ case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
+ data->operation.orientation = 0x1;
+ data->operation.operation = 0x03;
+ data->count++;
+ break;
+ case DASD_ECKD_CCW_READ_RECORD_ZERO:
+ data->operation.orientation = 0x3;
+ data->operation.operation = 0x16;
+ data->count++;
+ break;
+ case DASD_ECKD_CCW_WRITE:
+ case DASD_ECKD_CCW_WRITE_MT:
+ case DASD_ECKD_CCW_WRITE_KD:
+ case DASD_ECKD_CCW_WRITE_KD_MT:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x01;
+ break;
+ case DASD_ECKD_CCW_WRITE_CKD:
+ case DASD_ECKD_CCW_WRITE_CKD_MT:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x03;
+ break;
+ case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen; /* not tlf, as one might think */
+ data->operation.operation = 0x3F;
+ data->extended_operation = 0x23;
+ break;
+ case DASD_ECKD_CCW_READ:
+ case DASD_ECKD_CCW_READ_MT:
+ case DASD_ECKD_CCW_READ_KD:
+ case DASD_ECKD_CCW_READ_KD_MT:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x06;
+ break;
+ case DASD_ECKD_CCW_READ_CKD:
+ case DASD_ECKD_CCW_READ_CKD_MT:
+ data->auxiliary.length_valid = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x16;
+ break;
+ case DASD_ECKD_CCW_READ_COUNT:
+ data->operation.operation = 0x06;
+ break;
+ case DASD_ECKD_CCW_READ_TRACK_DATA:
+ data->auxiliary.length_valid = 0x1;
+ data->length = tlf;
+ data->operation.operation = 0x0C;
+ break;
+ case DASD_ECKD_CCW_ERASE:
+ data->length = reclen;
+ data->auxiliary.length_valid = 0x1;
+ data->operation.operation = 0x0b;
+ break;
+ default:
+ DBF_DEV_EVENT(DBF_ERR, device,
+ "fill LRE unknown opcode 0x%x", cmd);
+ BUG();
+ }
+ set_ch_t(&data->seek_addr,
+ trk / private->rdc_data.trk_per_cyl,
+ trk % private->rdc_data.trk_per_cyl);
+ data->search_arg.cyl = data->seek_addr.cyl;
+ data->search_arg.head = data->seek_addr.head;
+ data->search_arg.record = rec_on_trk;
+}
+
+static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
+ unsigned int trk, unsigned int totrk, int cmd,
+ struct dasd_device *basedev, struct dasd_device *startdev,
+ unsigned char format, unsigned int rec_on_trk, int count,
+ unsigned int blksize, unsigned int tlf)
{
struct dasd_eckd_private *basepriv, *startpriv;
- struct DE_eckd_data *data;
- struct ch_t geo, beg, end;
+ struct DE_eckd_data *dedata;
+ struct LRE_eckd_data *lredata;
+ u32 begcyl, endcyl;
+ u16 heads, beghead, endhead;
int rc = 0;
basepriv = (struct dasd_eckd_private *) basedev->private;
startpriv = (struct dasd_eckd_private *) startdev->private;
- data = &pfxdata->define_extend;
+ dedata = &pfxdata->define_extent;
+ lredata = &pfxdata->locate_record;
ccw->cmd_code = DASD_ECKD_CCW_PFX;
ccw->flags = 0;
@@ -314,10 +442,16 @@ static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk,
memset(pfxdata, 0, sizeof(*pfxdata));
/* prefix data */
- pfxdata->format = 0;
+ if (format > 1) {
+ DBF_DEV_EVENT(DBF_ERR, basedev,
+ "PFX LRE unknown format 0x%x", format);
+ BUG();
+ return -EINVAL;
+ }
+ pfxdata->format = format;
pfxdata->base_address = basepriv->ned->unit_addr;
pfxdata->base_lss = basepriv->ned->ID;
- pfxdata->validity.define_extend = 1;
+ pfxdata->validity.define_extent = 1;
/* private uid is kept up to date, conf_data may be outdated */
if (startpriv->uid.type != UA_BASE_DEVICE) {
@@ -337,70 +471,94 @@ static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk,
case DASD_ECKD_CCW_READ_KD:
case DASD_ECKD_CCW_READ_KD_MT:
case DASD_ECKD_CCW_READ_COUNT:
- data->mask.perm = 0x1;
- data->attributes.operation = basepriv->attrib.operation;
+ dedata->mask.perm = 0x1;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ break;
+ case DASD_ECKD_CCW_READ_TRACK_DATA:
+ dedata->mask.perm = 0x1;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ dedata->blk_size = 0;
break;
case DASD_ECKD_CCW_WRITE:
case DASD_ECKD_CCW_WRITE_MT:
case DASD_ECKD_CCW_WRITE_KD:
case DASD_ECKD_CCW_WRITE_KD_MT:
- data->mask.perm = 0x02;
- data->attributes.operation = basepriv->attrib.operation;
+ dedata->mask.perm = 0x02;
+ dedata->attributes.operation = basepriv->attrib.operation;
rc = check_XRC_on_prefix(pfxdata, basedev);
break;
case DASD_ECKD_CCW_WRITE_CKD:
case DASD_ECKD_CCW_WRITE_CKD_MT:
- data->attributes.operation = DASD_BYPASS_CACHE;
+ dedata->attributes.operation = DASD_BYPASS_CACHE;
rc = check_XRC_on_prefix(pfxdata, basedev);
break;
case DASD_ECKD_CCW_ERASE:
case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
- data->mask.perm = 0x3;
- data->mask.auth = 0x1;
- data->attributes.operation = DASD_BYPASS_CACHE;
+ dedata->mask.perm = 0x3;
+ dedata->mask.auth = 0x1;
+ dedata->attributes.operation = DASD_BYPASS_CACHE;
rc = check_XRC_on_prefix(pfxdata, basedev);
break;
- default:
- DEV_MESSAGE(KERN_ERR, basedev, "unknown opcode 0x%x", cmd);
+ case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+ dedata->mask.perm = 0x02;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ dedata->blk_size = blksize;
+ rc = check_XRC_on_prefix(pfxdata, basedev);
break;
+ default:
+ DBF_DEV_EVENT(DBF_ERR, basedev,
+ "PFX LRE unknown opcode 0x%x", cmd);
+ BUG();
+ return -EINVAL;
}
- data->attributes.mode = 0x3; /* ECKD */
+ dedata->attributes.mode = 0x3; /* ECKD */
if ((basepriv->rdc_data.cu_type == 0x2105 ||
basepriv->rdc_data.cu_type == 0x2107 ||
basepriv->rdc_data.cu_type == 0x1750)
&& !(basepriv->uses_cdl && trk < 2))
- data->ga_extended |= 0x40; /* Regular Data Format Mode */
+ dedata->ga_extended |= 0x40; /* Regular Data Format Mode */
- geo.cyl = basepriv->rdc_data.no_cyl;
- geo.head = basepriv->rdc_data.trk_per_cyl;
- beg.cyl = trk / geo.head;
- beg.head = trk % geo.head;
- end.cyl = totrk / geo.head;
- end.head = totrk % geo.head;
+ heads = basepriv->rdc_data.trk_per_cyl;
+ begcyl = trk / heads;
+ beghead = trk % heads;
+ endcyl = totrk / heads;
+ endhead = totrk % heads;
/* check for sequential prestage - enhance cylinder range */
- if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
- data->attributes.operation == DASD_SEQ_ACCESS) {
+ if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
+ dedata->attributes.operation == DASD_SEQ_ACCESS) {
- if (end.cyl + basepriv->attrib.nr_cyl < geo.cyl)
- end.cyl += basepriv->attrib.nr_cyl;
+ if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
+ endcyl += basepriv->attrib.nr_cyl;
else
- end.cyl = (geo.cyl - 1);
+ endcyl = (basepriv->real_cyl - 1);
+ }
+
+ set_ch_t(&dedata->beg_ext, begcyl, beghead);
+ set_ch_t(&dedata->end_ext, endcyl, endhead);
+
+ if (format == 1) {
+ fill_LRE_data(lredata, trk, rec_on_trk, count, cmd,
+ basedev, blksize, tlf);
}
- data->beg_ext.cyl = beg.cyl;
- data->beg_ext.head = beg.head;
- data->end_ext.cyl = end.cyl;
- data->end_ext.head = end.head;
return rc;
}
+static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
+ unsigned int trk, unsigned int totrk, int cmd,
+ struct dasd_device *basedev, struct dasd_device *startdev)
+{
+ return prefix_LRE(ccw, pfxdata, trk, totrk, cmd, basedev, startdev,
+ 0, 0, 0, 0, 0);
+}
+
static void
-locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
- int rec_on_trk, int no_rec, int cmd,
+locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, unsigned int trk,
+ unsigned int rec_on_trk, int no_rec, int cmd,
struct dasd_device * device, int reclen)
{
struct dasd_eckd_private *private;
@@ -491,12 +649,14 @@ locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
data->operation.operation = 0x0b;
break;
default:
- DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
- }
- data->seek_addr.cyl = data->search_arg.cyl =
- trk / private->rdc_data.trk_per_cyl;
- data->seek_addr.head = data->search_arg.head =
- trk % private->rdc_data.trk_per_cyl;
+ DBF_DEV_EVENT(DBF_ERR, device, "unknown locate record "
+ "opcode 0x%x", cmd);
+ }
+ set_ch_t(&data->seek_addr,
+ trk / private->rdc_data.trk_per_cyl,
+ trk % private->rdc_data.trk_per_cyl);
+ data->search_arg.cyl = data->seek_addr.cyl;
+ data->search_arg.head = data->seek_addr.head;
data->search_arg.record = rec_on_trk;
}
@@ -585,8 +745,8 @@ static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device,
cqr = dasd_smalloc_request("ECKD", 1 /* RCD */, ciw->count, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Could not allocate RCD request");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "Could not allocate RCD request");
return cqr;
}
@@ -736,14 +896,16 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
rc = dasd_eckd_read_conf_lpm(device, &conf_data,
&conf_len, lpm);
if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */
- MESSAGE(KERN_WARNING,
- "Read configuration data returned "
- "error %d", rc);
+ DBF_EVENT(DBF_WARNING,
+ "Read configuration data returned "
+ "error %d for device: %s", rc,
+ dev_name(&device->cdev->dev));
return rc;
}
if (conf_data == NULL) {
- MESSAGE(KERN_WARNING, "%s", "No configuration "
- "data retrieved");
+ DBF_EVENT(DBF_WARNING, "No configuration "
+ "data retrieved for device: %s",
+ dev_name(&device->cdev->dev));
continue; /* no error */
}
/* save first valid configuration data */
@@ -790,8 +952,9 @@ static int dasd_eckd_read_features(struct dasd_device *device)
sizeof(struct dasd_rssd_features)),
device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Could not allocate initialization request");
+ DBF_EVENT(DBF_WARNING, "Could not allocate initialization "
+ "request for device: %s",
+ dev_name(&device->cdev->dev));
return PTR_ERR(cqr);
}
cqr->startdev = device;
@@ -840,7 +1003,8 @@ static int dasd_eckd_read_features(struct dasd_device *device)
/*
* Build CP for Perform Subsystem Function - SSC.
*/
-static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device)
+static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device,
+ int enable_pav)
{
struct dasd_ccw_req *cqr;
struct dasd_psf_ssc_data *psf_ssc_data;
@@ -851,15 +1015,17 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device)
device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate PSF-SSC request");
return cqr;
}
psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
psf_ssc_data->order = PSF_ORDER_SSC;
- psf_ssc_data->suborder = 0x88;
- psf_ssc_data->reserved[0] = 0x88;
-
+ psf_ssc_data->suborder = 0x40;
+ if (enable_pav) {
+ psf_ssc_data->suborder |= 0x88;
+ psf_ssc_data->reserved[0] = 0x88;
+ }
ccw = cqr->cpaddr;
ccw->cmd_code = DASD_ECKD_CCW_PSF;
ccw->cda = (__u32)(addr_t)psf_ssc_data;
@@ -880,12 +1046,12 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device)
* call might change behaviour of DASD devices.
*/
static int
-dasd_eckd_psf_ssc(struct dasd_device *device)
+dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
{
struct dasd_ccw_req *cqr;
int rc;
- cqr = dasd_eckd_build_psf_ssc(device);
+ cqr = dasd_eckd_build_psf_ssc(device, enable_pav);
if (IS_ERR(cqr))
return PTR_ERR(cqr);
@@ -904,19 +1070,20 @@ static int dasd_eckd_validate_server(struct dasd_device *device)
{
int rc;
struct dasd_eckd_private *private;
+ int enable_pav;
- /* Currently PAV is the only reason to 'validate' server on LPAR */
if (dasd_nopav || MACHINE_IS_VM)
- return 0;
-
- rc = dasd_eckd_psf_ssc(device);
+ enable_pav = 0;
+ else
+ enable_pav = 1;
+ rc = dasd_eckd_psf_ssc(device, enable_pav);
/* may be requested feature is not available on server,
* therefore just report error and go ahead */
private = (struct dasd_eckd_private *) device->private;
- DEV_MESSAGE(KERN_INFO, device,
- "PSF-SSC on storage subsystem %s.%s.%04x returned rc=%d",
- private->uid.vendor, private->uid.serial,
- private->uid.ssid, rc);
+ DBF_EVENT(DBF_WARNING, "PSF-SSC on storage subsystem %s.%s.%04x "
+ "returned rc=%d for device: %s",
+ private->uid.vendor, private->uid.serial,
+ private->uid.ssid, rc, dev_name(&device->cdev->dev));
/* RE-Read Configuration Data */
return dasd_eckd_read_conf(device);
}
@@ -938,9 +1105,9 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
private = kzalloc(sizeof(struct dasd_eckd_private),
GFP_KERNEL | GFP_DMA);
if (private == NULL) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "memory allocation failed for private "
- "data");
+ dev_warn(&device->cdev->dev,
+ "Allocating memory for private DASD data "
+ "failed\n");
return -ENOMEM;
}
device->private = (void *) private;
@@ -965,8 +1132,9 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
if (private->uid.type == UA_BASE_DEVICE) {
block = dasd_alloc_block();
if (IS_ERR(block)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "could not allocate dasd block structure");
+ DBF_EVENT(DBF_WARNING, "could not allocate dasd "
+ "block structure for device: %s",
+ dev_name(&device->cdev->dev));
rc = PTR_ERR(block);
goto out_err1;
}
@@ -997,20 +1165,27 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
memset(rdc_data, 0, sizeof(rdc_data));
rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64);
if (rc) {
- DEV_MESSAGE(KERN_WARNING, device,
- "Read device characteristics returned "
- "rc=%d", rc);
+ DBF_EVENT(DBF_WARNING,
+ "Read device characteristics failed, rc=%d for "
+ "device: %s", rc, dev_name(&device->cdev->dev));
goto out_err3;
}
- DEV_MESSAGE(KERN_INFO, device,
- "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
- private->rdc_data.dev_type,
- private->rdc_data.dev_model,
- private->rdc_data.cu_type,
- private->rdc_data.cu_model.model,
- private->rdc_data.no_cyl,
- private->rdc_data.trk_per_cyl,
- private->rdc_data.sec_per_trk);
+ /* find the vaild cylinder size */
+ if (private->rdc_data.no_cyl == LV_COMPAT_CYL &&
+ private->rdc_data.long_no_cyl)
+ private->real_cyl = private->rdc_data.long_no_cyl;
+ else
+ private->real_cyl = private->rdc_data.no_cyl;
+
+ dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) "
+ "with %d cylinders, %d heads, %d sectors\n",
+ private->rdc_data.dev_type,
+ private->rdc_data.dev_model,
+ private->rdc_data.cu_type,
+ private->rdc_data.cu_model.model,
+ private->real_cyl,
+ private->rdc_data.trk_per_cyl,
+ private->rdc_data.sec_per_trk);
return 0;
out_err3:
@@ -1151,14 +1326,12 @@ dasd_eckd_end_analysis(struct dasd_block *block)
status = private->init_cqr_status;
private->init_cqr_status = -1;
if (status != DASD_CQR_DONE) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "volume analysis returned unformatted disk");
+ dev_warn(&device->cdev->dev,
+ "The DASD is not formatted\n");
return -EMEDIUMTYPE;
}
private->uses_cdl = 1;
- /* Calculate number of blocks/records per track. */
- blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
/* Check Track 0 for Compatible Disk Layout */
count_area = NULL;
for (i = 0; i < 3; i++) {
@@ -1182,8 +1355,8 @@ dasd_eckd_end_analysis(struct dasd_block *block)
count_area = &private->count_area[0];
} else {
if (private->count_area[3].record == 1)
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Trk 0: no records after VTOC!");
+ dev_warn(&device->cdev->dev,
+ "Track 0 has no records following the VTOC\n");
}
if (count_area != NULL && count_area->kl == 0) {
/* we found notthing violating our disk layout */
@@ -1191,8 +1364,8 @@ dasd_eckd_end_analysis(struct dasd_block *block)
block->bp_block = count_area->dl;
}
if (block->bp_block == 0) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "Volume has incompatible disk layout");
+ dev_warn(&device->cdev->dev,
+ "The disk layout of the DASD is not supported\n");
return -EMEDIUMTYPE;
}
block->s2b_shift = 0; /* bits to shift 512 to get a block */
@@ -1200,19 +1373,19 @@ dasd_eckd_end_analysis(struct dasd_block *block)
block->s2b_shift++;
blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
- block->blocks = (private->rdc_data.no_cyl *
+ block->blocks = (private->real_cyl *
private->rdc_data.trk_per_cyl *
blk_per_trk);
- DEV_MESSAGE(KERN_INFO, device,
- "(%dkB blks): %dkB at %dkB/trk %s",
- (block->bp_block >> 10),
- ((private->rdc_data.no_cyl *
- private->rdc_data.trk_per_cyl *
- blk_per_trk * (block->bp_block >> 9)) >> 1),
- ((blk_per_trk * block->bp_block) >> 10),
- private->uses_cdl ?
- "compatible disk layout" : "linux disk layout");
+ dev_info(&device->cdev->dev,
+ "DASD with %d KB/block, %d KB total size, %d KB/track, "
+ "%s\n", (block->bp_block >> 10),
+ ((private->real_cyl *
+ private->rdc_data.trk_per_cyl *
+ blk_per_trk * (block->bp_block >> 9)) >> 1),
+ ((blk_per_trk * block->bp_block) >> 10),
+ private->uses_cdl ?
+ "compatible disk layout" : "linux disk layout");
return 0;
}
@@ -1262,31 +1435,35 @@ dasd_eckd_format_device(struct dasd_device * device,
struct eckd_count *ect;
struct ccw1 *ccw;
void *data;
- int rpt, cyl, head;
+ int rpt;
+ struct ch_t address;
int cplength, datasize;
int i;
+ int intensity = 0;
+ int r0_perm;
private = (struct dasd_eckd_private *) device->private;
rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize);
- cyl = fdata->start_unit / private->rdc_data.trk_per_cyl;
- head = fdata->start_unit % private->rdc_data.trk_per_cyl;
+ set_ch_t(&address,
+ fdata->start_unit / private->rdc_data.trk_per_cyl,
+ fdata->start_unit % private->rdc_data.trk_per_cyl);
/* Sanity checks. */
if (fdata->start_unit >=
- (private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl)) {
- DEV_MESSAGE(KERN_INFO, device, "Track no %d too big!",
- fdata->start_unit);
+ (private->real_cyl * private->rdc_data.trk_per_cyl)) {
+ dev_warn(&device->cdev->dev, "Start track number %d used in "
+ "formatting is too big\n", fdata->start_unit);
return ERR_PTR(-EINVAL);
}
if (fdata->start_unit > fdata->stop_unit) {
- DEV_MESSAGE(KERN_INFO, device, "Track %d reached! ending.",
- fdata->start_unit);
+ dev_warn(&device->cdev->dev, "Start track %d used in "
+ "formatting exceeds end track\n", fdata->start_unit);
return ERR_PTR(-EINVAL);
}
if (dasd_check_blocksize(fdata->blksize) != 0) {
- DEV_MESSAGE(KERN_WARNING, device,
- "Invalid blocksize %d...terminating!",
- fdata->blksize);
+ dev_warn(&device->cdev->dev,
+ "The DASD cannot be formatted with block size %d\n",
+ fdata->blksize);
return ERR_PTR(-EINVAL);
}
@@ -1296,9 +1473,17 @@ dasd_eckd_format_device(struct dasd_device * device,
* Bit 1: write home address, currently not supported
* Bit 2: invalidate tracks
* Bit 3: use OS/390 compatible disk layout (cdl)
+ * Bit 4: do not allow storage subsystem to modify record zero
* Only some bit combinations do make sense.
*/
- switch (fdata->intensity) {
+ if (fdata->intensity & 0x10) {
+ r0_perm = 0;
+ intensity = fdata->intensity & ~0x10;
+ } else {
+ r0_perm = 1;
+ intensity = fdata->intensity;
+ }
+ switch (intensity) {
case 0x00: /* Normal format */
case 0x08: /* Normal format, use cdl. */
cplength = 2 + rpt;
@@ -1322,8 +1507,8 @@ dasd_eckd_format_device(struct dasd_device * device,
sizeof(struct eckd_count);
break;
default:
- DEV_MESSAGE(KERN_WARNING, device, "Invalid flags 0x%x.",
- fdata->intensity);
+ dev_warn(&device->cdev->dev, "An I/O control call used "
+ "incorrect flags 0x%x\n", fdata->intensity);
return ERR_PTR(-EINVAL);
}
/* Allocate the format ccw request. */
@@ -1335,11 +1520,14 @@ dasd_eckd_format_device(struct dasd_device * device,
data = fcp->data;
ccw = fcp->cpaddr;
- switch (fdata->intensity & ~0x08) {
+ switch (intensity & ~0x08) {
case 0x00: /* Normal format. */
define_extent(ccw++, (struct DE_eckd_data *) data,
fdata->start_unit, fdata->start_unit,
DASD_ECKD_CCW_WRITE_CKD, device);
+ /* grant subsystem permission to format R0 */
+ if (r0_perm)
+ ((struct DE_eckd_data *)data)->ga_extended |= 0x04;
data += sizeof(struct DE_eckd_data);
ccw[-1].flags |= CCW_FLAG_CC;
locate_record(ccw++, (struct LO_eckd_data *) data,
@@ -1373,11 +1561,11 @@ dasd_eckd_format_device(struct dasd_device * device,
data += sizeof(struct LO_eckd_data);
break;
}
- if (fdata->intensity & 0x01) { /* write record zero */
+ if (intensity & 0x01) { /* write record zero */
ect = (struct eckd_count *) data;
data += sizeof(struct eckd_count);
- ect->cyl = cyl;
- ect->head = head;
+ ect->cyl = address.cyl;
+ ect->head = address.head;
ect->record = 0;
ect->kl = 0;
ect->dl = 8;
@@ -1388,11 +1576,11 @@ dasd_eckd_format_device(struct dasd_device * device,
ccw->cda = (__u32)(addr_t) ect;
ccw++;
}
- if ((fdata->intensity & ~0x08) & 0x04) { /* erase track */
+ if ((intensity & ~0x08) & 0x04) { /* erase track */
ect = (struct eckd_count *) data;
data += sizeof(struct eckd_count);
- ect->cyl = cyl;
- ect->head = head;
+ ect->cyl = address.cyl;
+ ect->head = address.head;
ect->record = 1;
ect->kl = 0;
ect->dl = 0;
@@ -1405,20 +1593,20 @@ dasd_eckd_format_device(struct dasd_device * device,
for (i = 0; i < rpt; i++) {
ect = (struct eckd_count *) data;
data += sizeof(struct eckd_count);
- ect->cyl = cyl;
- ect->head = head;
+ ect->cyl = address.cyl;
+ ect->head = address.head;
ect->record = i + 1;
ect->kl = 0;
ect->dl = fdata->blksize;
/* Check for special tracks 0-1 when formatting CDL */
- if ((fdata->intensity & 0x08) &&
+ if ((intensity & 0x08) &&
fdata->start_unit == 0) {
if (i < 3) {
ect->kl = 4;
ect->dl = sizes_trk0[i] - 4;
}
}
- if ((fdata->intensity & 0x08) &&
+ if ((intensity & 0x08) &&
fdata->start_unit == 1) {
ect->kl = 44;
ect->dl = LABEL_SIZE - 44;
@@ -1479,57 +1667,69 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
struct irb *irb)
{
char mask;
+ char *sense = NULL;
/* first of all check for state change pending interrupt */
mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
- if ((irb->scsw.cmd.dstat & mask) == mask) {
+ if ((scsw_dstat(&irb->scsw) & mask) == mask) {
dasd_generic_handle_state_change(device);
return;
}
/* summary unit check */
- if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
+ if ((scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) &&
(irb->ecw[7] == 0x0D)) {
dasd_alias_handle_summary_unit_check(device, irb);
return;
}
-
+ sense = dasd_get_sense(irb);
/* service information message SIM */
- if (irb->esw.esw0.erw.cons && !(irb->ecw[27] & DASD_SENSE_BIT_0) &&
- ((irb->ecw[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
- dasd_3990_erp_handle_sim(device, irb->ecw);
+ if (sense && !(sense[27] & DASD_SENSE_BIT_0) &&
+ ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
+ dasd_3990_erp_handle_sim(device, sense);
dasd_schedule_device_bh(device);
return;
}
- if ((irb->scsw.cmd.cc == 1) &&
- (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) &&
- (irb->scsw.cmd.actl & SCSW_ACTL_START_PEND) &&
- (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND)) {
+ if ((scsw_cc(&irb->scsw) == 1) &&
+ (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
+ (scsw_actl(&irb->scsw) & SCSW_ACTL_START_PEND) &&
+ (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND)) {
/* fake irb do nothing, they are handled elsewhere */
dasd_schedule_device_bh(device);
return;
}
- if (!(irb->esw.esw0.erw.cons)) {
+ if (!sense) {
/* just report other unsolicited interrupts */
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_ERR, device, "%s",
"unsolicited interrupt received");
} else {
- DEV_MESSAGE(KERN_ERR, device, "%s",
+ DBF_DEV_EVENT(DBF_ERR, device, "%s",
"unsolicited interrupt received "
"(sense available)");
- device->discipline->dump_sense(device, NULL, irb);
+ device->discipline->dump_sense_dbf(device, NULL, irb,
+ "unsolicited");
}
dasd_schedule_device_bh(device);
return;
};
-static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
+
+static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
+ struct dasd_device *startdev,
struct dasd_block *block,
- struct request *req)
+ struct request *req,
+ sector_t first_rec,
+ sector_t last_rec,
+ sector_t first_trk,
+ sector_t last_trk,
+ unsigned int first_offs,
+ unsigned int last_offs,
+ unsigned int blk_per_trk,
+ unsigned int blksize)
{
struct dasd_eckd_private *private;
unsigned long *idaws;
@@ -1539,11 +1739,9 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
struct req_iterator iter;
struct bio_vec *bv;
char *dst;
- unsigned int blksize, blk_per_trk, off;
+ unsigned int off;
int count, cidaw, cplength, datasize;
- sector_t recid, first_rec, last_rec;
- sector_t first_trk, last_trk;
- unsigned int first_offs, last_offs;
+ sector_t recid;
unsigned char cmd, rcmd;
int use_prefix;
struct dasd_device *basedev;
@@ -1556,15 +1754,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
cmd = DASD_ECKD_CCW_WRITE_MT;
else
return ERR_PTR(-EINVAL);
- /* Calculate number of blocks/records per track. */
- blksize = block->bp_block;
- blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
- /* Calculate record id of first and last block. */
- first_rec = first_trk = req->sector >> block->s2b_shift;
- first_offs = sector_div(first_trk, blk_per_trk);
- last_rec = last_trk =
- (req->sector + req->nr_sectors - 1) >> block->s2b_shift;
- last_offs = sector_div(last_trk, blk_per_trk);
+
/* Check struct bio and count the number of blocks for the request. */
count = 0;
cidaw = 0;
@@ -1714,6 +1904,497 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
return cqr;
}
+static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
+ struct dasd_device *startdev,
+ struct dasd_block *block,
+ struct request *req,
+ sector_t first_rec,
+ sector_t last_rec,
+ sector_t first_trk,
+ sector_t last_trk,
+ unsigned int first_offs,
+ unsigned int last_offs,
+ unsigned int blk_per_trk,
+ unsigned int blksize)
+{
+ struct dasd_eckd_private *private;
+ unsigned long *idaws;
+ struct dasd_ccw_req *cqr;
+ struct ccw1 *ccw;
+ struct req_iterator iter;
+ struct bio_vec *bv;
+ char *dst, *idaw_dst;
+ unsigned int cidaw, cplength, datasize;
+ unsigned int tlf;
+ sector_t recid;
+ unsigned char cmd;
+ struct dasd_device *basedev;
+ unsigned int trkcount, count, count_to_trk_end;
+ unsigned int idaw_len, seg_len, part_len, len_to_track_end;
+ unsigned char new_track, end_idaw;
+ sector_t trkid;
+ unsigned int recoffs;
+
+ basedev = block->base;
+ private = (struct dasd_eckd_private *) basedev->private;
+ if (rq_data_dir(req) == READ)
+ cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
+ else if (rq_data_dir(req) == WRITE)
+ cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
+ else
+ return ERR_PTR(-EINVAL);
+
+ /* Track based I/O needs IDAWs for each page, and not just for
+ * 64 bit addresses. We need additional idals for pages
+ * that get filled from two tracks, so we use the number
+ * of records as upper limit.
+ */
+ cidaw = last_rec - first_rec + 1;
+ trkcount = last_trk - first_trk + 1;
+
+ /* 1x prefix + one read/write ccw per track */
+ cplength = 1 + trkcount;
+
+ /* on 31-bit we need space for two 32 bit addresses per page
+ * on 64-bit one 64 bit address
+ */
+ datasize = sizeof(struct PFX_eckd_data) +
+ cidaw * sizeof(unsigned long long);
+
+ /* Allocate the ccw request. */
+ cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
+ cplength, datasize, startdev);
+ if (IS_ERR(cqr))
+ return cqr;
+ ccw = cqr->cpaddr;
+ /* transfer length factor: how many bytes to read from the last track */
+ if (first_trk == last_trk)
+ tlf = last_offs - first_offs + 1;
+ else
+ tlf = last_offs + 1;
+ tlf *= blksize;
+
+ if (prefix_LRE(ccw++, cqr->data, first_trk,
+ last_trk, cmd, basedev, startdev,
+ 1 /* format */, first_offs + 1,
+ trkcount, blksize,
+ tlf) == -EAGAIN) {
+ /* Clock not in sync and XRC is enabled.
+ * Try again later.
+ */
+ dasd_sfree_request(cqr, startdev);
+ return ERR_PTR(-EAGAIN);
+ }
+
+ /*
+ * The translation of request into ccw programs must meet the
+ * following conditions:
+ * - all idaws but the first and the last must address full pages
+ * (or 2K blocks on 31-bit)
+ * - the scope of a ccw and it's idal ends with the track boundaries
+ */
+ idaws = (unsigned long *) (cqr->data + sizeof(struct PFX_eckd_data));
+ recid = first_rec;
+ new_track = 1;
+ end_idaw = 0;
+ len_to_track_end = 0;
+ idaw_dst = 0;
+ idaw_len = 0;
+ rq_for_each_segment(bv, req, iter) {
+ dst = page_address(bv->bv_page) + bv->bv_offset;
+ seg_len = bv->bv_len;
+ while (seg_len) {
+ if (new_track) {
+ trkid = recid;
+ recoffs = sector_div(trkid, blk_per_trk);
+ count_to_trk_end = blk_per_trk - recoffs;
+ count = min((last_rec - recid + 1),
+ (sector_t)count_to_trk_end);
+ len_to_track_end = count * blksize;
+ ccw[-1].flags |= CCW_FLAG_CC;
+ ccw->cmd_code = cmd;
+ ccw->count = len_to_track_end;
+ ccw->cda = (__u32)(addr_t)idaws;
+ ccw->flags = CCW_FLAG_IDA;
+ ccw++;
+ recid += count;
+ new_track = 0;
+ }
+ /* If we start a new idaw, everything is fine and the
+ * start of the new idaw is the start of this segment.
+ * If we continue an idaw, we must make sure that the
+ * current segment begins where the so far accumulated
+ * idaw ends
+ */
+ if (!idaw_dst)
+ idaw_dst = dst;
+ if ((idaw_dst + idaw_len) != dst) {
+ dasd_sfree_request(cqr, startdev);
+ return ERR_PTR(-ERANGE);
+ }
+ part_len = min(seg_len, len_to_track_end);
+ seg_len -= part_len;
+ dst += part_len;
+ idaw_len += part_len;
+ len_to_track_end -= part_len;
+ /* collected memory area ends on an IDA_BLOCK border,
+ * -> create an idaw
+ * idal_create_words will handle cases where idaw_len
+ * is larger then IDA_BLOCK_SIZE
+ */
+ if (!(__pa(idaw_dst + idaw_len) & (IDA_BLOCK_SIZE-1)))
+ end_idaw = 1;
+ /* We also need to end the idaw at track end */
+ if (!len_to_track_end) {
+ new_track = 1;
+ end_idaw = 1;
+ }
+ if (end_idaw) {
+ idaws = idal_create_words(idaws, idaw_dst,
+ idaw_len);
+ idaw_dst = 0;
+ idaw_len = 0;
+ end_idaw = 0;
+ }
+ }
+ }
+
+ if (blk_noretry_request(req) ||
+ block->base->features & DASD_FEATURE_FAILFAST)
+ set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+ cqr->startdev = startdev;
+ cqr->memdev = startdev;
+ cqr->block = block;
+ cqr->expires = 5 * 60 * HZ; /* 5 minutes */
+ cqr->lpm = private->path_data.ppm;
+ cqr->retries = 256;
+ cqr->buildclk = get_clock();
+ cqr->status = DASD_CQR_FILLED;
+ return cqr;
+}
+
+static int prepare_itcw(struct itcw *itcw,
+ unsigned int trk, unsigned int totrk, int cmd,
+ struct dasd_device *basedev,
+ struct dasd_device *startdev,
+ unsigned int rec_on_trk, int count,
+ unsigned int blksize,
+ unsigned int total_data_size,
+ unsigned int tlf,
+ unsigned int blk_per_trk)
+{
+ struct PFX_eckd_data pfxdata;
+ struct dasd_eckd_private *basepriv, *startpriv;
+ struct DE_eckd_data *dedata;
+ struct LRE_eckd_data *lredata;
+ struct dcw *dcw;
+
+ u32 begcyl, endcyl;
+ u16 heads, beghead, endhead;
+ u8 pfx_cmd;
+
+ int rc = 0;
+ int sector = 0;
+ int dn, d;
+
+
+ /* setup prefix data */
+ basepriv = (struct dasd_eckd_private *) basedev->private;
+ startpriv = (struct dasd_eckd_private *) startdev->private;
+ dedata = &pfxdata.define_extent;
+ lredata = &pfxdata.locate_record;
+
+ memset(&pfxdata, 0, sizeof(pfxdata));
+ pfxdata.format = 1; /* PFX with LRE */
+ pfxdata.base_address = basepriv->ned->unit_addr;
+ pfxdata.base_lss = basepriv->ned->ID;
+ pfxdata.validity.define_extent = 1;
+
+ /* private uid is kept up to date, conf_data may be outdated */
+ if (startpriv->uid.type != UA_BASE_DEVICE) {
+ pfxdata.validity.verify_base = 1;
+ if (startpriv->uid.type == UA_HYPER_PAV_ALIAS)
+ pfxdata.validity.hyper_pav = 1;
+ }
+
+ switch (cmd) {
+ case DASD_ECKD_CCW_READ_TRACK_DATA:
+ dedata->mask.perm = 0x1;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ dedata->blk_size = blksize;
+ dedata->ga_extended |= 0x42;
+ lredata->operation.orientation = 0x0;
+ lredata->operation.operation = 0x0C;
+ lredata->auxiliary.check_bytes = 0x01;
+ pfx_cmd = DASD_ECKD_CCW_PFX_READ;
+ break;
+ case DASD_ECKD_CCW_WRITE_TRACK_DATA:
+ dedata->mask.perm = 0x02;
+ dedata->attributes.operation = basepriv->attrib.operation;
+ dedata->blk_size = blksize;
+ rc = check_XRC_on_prefix(&pfxdata, basedev);
+ dedata->ga_extended |= 0x42;
+ lredata->operation.orientation = 0x0;
+ lredata->operation.operation = 0x3F;
+ lredata->extended_operation = 0x23;
+ lredata->auxiliary.check_bytes = 0x2;
+ pfx_cmd = DASD_ECKD_CCW_PFX;
+ break;
+ default:
+ DBF_DEV_EVENT(DBF_ERR, basedev,
+ "prepare itcw, unknown opcode 0x%x", cmd);
+ BUG();
+ break;
+ }
+ if (rc)
+ return rc;
+
+ dedata->attributes.mode = 0x3; /* ECKD */
+
+ heads = basepriv->rdc_data.trk_per_cyl;
+ begcyl = trk / heads;
+ beghead = trk % heads;
+ endcyl = totrk / heads;
+ endhead = totrk % heads;
+
+ /* check for sequential prestage - enhance cylinder range */
+ if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
+ dedata->attributes.operation == DASD_SEQ_ACCESS) {
+
+ if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
+ endcyl += basepriv->attrib.nr_cyl;
+ else
+ endcyl = (basepriv->real_cyl - 1);
+ }
+
+ set_ch_t(&dedata->beg_ext, begcyl, beghead);
+ set_ch_t(&dedata->end_ext, endcyl, endhead);
+
+ dedata->ep_format = 0x20; /* records per track is valid */
+ dedata->ep_rec_per_track = blk_per_trk;
+
+ if (rec_on_trk) {
+ switch (basepriv->rdc_data.dev_type) {
+ case 0x3390:
+ dn = ceil_quot(blksize + 6, 232);
+ d = 9 + ceil_quot(blksize + 6 * (dn + 1), 34);
+ sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
+ break;
+ case 0x3380:
+ d = 7 + ceil_quot(blksize + 12, 32);
+ sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
+ break;
+ }
+ }
+
+ lredata->auxiliary.length_valid = 1;
+ lredata->auxiliary.length_scope = 1;
+ lredata->auxiliary.imbedded_ccw_valid = 1;
+ lredata->length = tlf;
+ lredata->imbedded_ccw = cmd;
+ lredata->count = count;
+ lredata->sector = sector;
+ set_ch_t(&lredata->seek_addr, begcyl, beghead);
+ lredata->search_arg.cyl = lredata->seek_addr.cyl;
+ lredata->search_arg.head = lredata->seek_addr.head;
+ lredata->search_arg.record = rec_on_trk;
+
+ dcw = itcw_add_dcw(itcw, pfx_cmd, 0,
+ &pfxdata, sizeof(pfxdata), total_data_size);
+
+ return rc;
+}
+
+static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
+ struct dasd_device *startdev,
+ struct dasd_block *block,
+ struct request *req,
+ sector_t first_rec,
+ sector_t last_rec,
+ sector_t first_trk,
+ sector_t last_trk,
+ unsigned int first_offs,
+ unsigned int last_offs,
+ unsigned int blk_per_trk,
+ unsigned int blksize)
+{
+ struct dasd_eckd_private *private;
+ struct dasd_ccw_req *cqr;
+ struct req_iterator iter;
+ struct bio_vec *bv;
+ char *dst;
+ unsigned int trkcount, ctidaw;
+ unsigned char cmd;
+ struct dasd_device *basedev;
+ unsigned int tlf;
+ struct itcw *itcw;
+ struct tidaw *last_tidaw = NULL;
+ int itcw_op;
+ size_t itcw_size;
+
+ basedev = block->base;
+ private = (struct dasd_eckd_private *) basedev->private;
+ if (rq_data_dir(req) == READ) {
+ cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
+ itcw_op = ITCW_OP_READ;
+ } else if (rq_data_dir(req) == WRITE) {
+ cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
+ itcw_op = ITCW_OP_WRITE;
+ } else
+ return ERR_PTR(-EINVAL);
+
+ /* trackbased I/O needs address all memory via TIDAWs,
+ * not just for 64 bit addresses. This allows us to map
+ * each segment directly to one tidaw.
+ */
+ trkcount = last_trk - first_trk + 1;
+ ctidaw = 0;
+ rq_for_each_segment(bv, req, iter) {
+ ++ctidaw;
+ }
+
+ /* Allocate the ccw request. */
+ itcw_size = itcw_calc_size(0, ctidaw, 0);
+ cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
+ 0, itcw_size, startdev);
+ if (IS_ERR(cqr))
+ return cqr;
+
+ cqr->cpmode = 1;
+ cqr->startdev = startdev;
+ cqr->memdev = startdev;
+ cqr->block = block;
+ cqr->expires = 100*HZ;
+ cqr->buildclk = get_clock();
+ cqr->status = DASD_CQR_FILLED;
+ cqr->retries = 10;
+
+ /* transfer length factor: how many bytes to read from the last track */
+ if (first_trk == last_trk)
+ tlf = last_offs - first_offs + 1;
+ else
+ tlf = last_offs + 1;
+ tlf *= blksize;
+
+ itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
+ cqr->cpaddr = itcw_get_tcw(itcw);
+
+ if (prepare_itcw(itcw, first_trk, last_trk,
+ cmd, basedev, startdev,
+ first_offs + 1,
+ trkcount, blksize,
+ (last_rec - first_rec + 1) * blksize,
+ tlf, blk_per_trk) == -EAGAIN) {
+ /* Clock not in sync and XRC is enabled.
+ * Try again later.
+ */
+ dasd_sfree_request(cqr, startdev);
+ return ERR_PTR(-EAGAIN);
+ }
+
+ /*
+ * A tidaw can address 4k of memory, but must not cross page boundaries
+ * We can let the block layer handle this by setting
+ * blk_queue_segment_boundary to page boundaries and
+ * blk_max_segment_size to page size when setting up the request queue.
+ */
+ rq_for_each_segment(bv, req, iter) {
+ dst = page_address(bv->bv_page) + bv->bv_offset;
+ last_tidaw = itcw_add_tidaw(itcw, 0x00, dst, bv->bv_len);
+ if (IS_ERR(last_tidaw))
+ return (struct dasd_ccw_req *)last_tidaw;
+ }
+
+ last_tidaw->flags |= 0x80;
+ itcw_finalize(itcw);
+
+ if (blk_noretry_request(req) ||
+ block->base->features & DASD_FEATURE_FAILFAST)
+ set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
+ cqr->startdev = startdev;
+ cqr->memdev = startdev;
+ cqr->block = block;
+ cqr->expires = 5 * 60 * HZ; /* 5 minutes */
+ cqr->lpm = private->path_data.ppm;
+ cqr->retries = 256;
+ cqr->buildclk = get_clock();
+ cqr->status = DASD_CQR_FILLED;
+ return cqr;
+}
+
+static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
+ struct dasd_block *block,
+ struct request *req)
+{
+ int tpm, cmdrtd, cmdwtd;
+ int use_prefix;
+
+ struct dasd_eckd_private *private;
+ int fcx_in_css, fcx_in_gneq, fcx_in_features;
+ struct dasd_device *basedev;
+ sector_t first_rec, last_rec;
+ sector_t first_trk, last_trk;
+ unsigned int first_offs, last_offs;
+ unsigned int blk_per_trk, blksize;
+ int cdlspecial;
+ struct dasd_ccw_req *cqr;
+
+ basedev = block->base;
+ private = (struct dasd_eckd_private *) basedev->private;
+
+ /* Calculate number of blocks/records per track. */
+ blksize = block->bp_block;
+ blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
+ /* Calculate record id of first and last block. */
+ first_rec = first_trk = req->sector >> block->s2b_shift;
+ first_offs = sector_div(first_trk, blk_per_trk);
+ last_rec = last_trk =
+ (req->sector + req->nr_sectors - 1) >> block->s2b_shift;
+ last_offs = sector_div(last_trk, blk_per_trk);
+ cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);
+
+ /* is transport mode supported ? */
+ fcx_in_css = css_general_characteristics.fcx;
+ fcx_in_gneq = private->gneq->reserved2[7] & 0x04;
+ fcx_in_features = private->features.feature[40] & 0x80;
+ tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
+
+ /* is read track data and write track data in command mode supported? */
+ cmdrtd = private->features.feature[9] & 0x20;
+ cmdwtd = private->features.feature[12] & 0x40;
+ use_prefix = private->features.feature[8] & 0x01;
+
+ cqr = NULL;
+ if (cdlspecial || dasd_page_cache) {
+ /* do nothing, just fall through to the cmd mode single case */
+ } else if (!dasd_nofcx && tpm && (first_trk == last_trk)) {
+ cqr = dasd_eckd_build_cp_tpm_track(startdev, block, req,
+ first_rec, last_rec,
+ first_trk, last_trk,
+ first_offs, last_offs,
+ blk_per_trk, blksize);
+ if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
+ cqr = NULL;
+ } else if (use_prefix &&
+ (((rq_data_dir(req) == READ) && cmdrtd) ||
+ ((rq_data_dir(req) == WRITE) && cmdwtd))) {
+ cqr = dasd_eckd_build_cp_cmd_track(startdev, block, req,
+ first_rec, last_rec,
+ first_trk, last_trk,
+ first_offs, last_offs,
+ blk_per_trk, blksize);
+ if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
+ cqr = NULL;
+ }
+ if (!cqr)
+ cqr = dasd_eckd_build_cp_cmd_single(startdev, block, req,
+ first_rec, last_rec,
+ first_trk, last_trk,
+ first_offs, last_offs,
+ blk_per_trk, blksize);
+ return cqr;
+}
+
static int
dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
{
@@ -1767,7 +2448,7 @@ out:
}
/*
- * Modify ccw chain in cqr so it can be started on a base device.
+ * Modify ccw/tcw in cqr so it can be started on a base device.
*
* Note that this is not enough to restart the cqr!
* Either reset cqr->startdev as well (summary unit check handling)
@@ -1777,13 +2458,24 @@ void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *cqr)
{
struct ccw1 *ccw;
struct PFX_eckd_data *pfxdata;
-
- ccw = cqr->cpaddr;
- pfxdata = cqr->data;
-
- if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {
+ struct tcw *tcw;
+ struct tccb *tccb;
+ struct dcw *dcw;
+
+ if (cqr->cpmode == 1) {
+ tcw = cqr->cpaddr;
+ tccb = tcw_get_tccb(tcw);
+ dcw = (struct dcw *)&tccb->tca[0];
+ pfxdata = (struct PFX_eckd_data *)&dcw->cd[0];
pfxdata->validity.verify_base = 0;
pfxdata->validity.hyper_pav = 0;
+ } else {
+ ccw = cqr->cpaddr;
+ pfxdata = cqr->data;
+ if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {
+ pfxdata->validity.verify_base = 0;
+ pfxdata->validity.hyper_pav = 0;
+ }
}
}
@@ -1861,6 +2553,7 @@ dasd_eckd_release(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
int rc;
+ struct ccw1 *ccw;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -1868,14 +2561,15 @@ dasd_eckd_release(struct dasd_device *device)
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1, 32, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
return PTR_ERR(cqr);
}
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE;
- cqr->cpaddr->flags |= CCW_FLAG_SLI;
- cqr->cpaddr->count = 32;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_RELEASE;
+ ccw->flags |= CCW_FLAG_SLI;
+ ccw->count = 32;
+ ccw->cda = (__u32)(addr_t) cqr->data;
cqr->startdev = device;
cqr->memdev = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1902,6 +2596,7 @@ dasd_eckd_reserve(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
int rc;
+ struct ccw1 *ccw;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -1909,14 +2604,15 @@ dasd_eckd_reserve(struct dasd_device *device)
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1, 32, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
return PTR_ERR(cqr);
}
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE;
- cqr->cpaddr->flags |= CCW_FLAG_SLI;
- cqr->cpaddr->count = 32;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_RESERVE;
+ ccw->flags |= CCW_FLAG_SLI;
+ ccw->count = 32;
+ ccw->cda = (__u32)(addr_t) cqr->data;
cqr->startdev = device;
cqr->memdev = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1942,6 +2638,7 @@ dasd_eckd_steal_lock(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
int rc;
+ struct ccw1 *ccw;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
@@ -1949,14 +2646,15 @@ dasd_eckd_steal_lock(struct dasd_device *device)
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1, 32, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
return PTR_ERR(cqr);
}
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK;
- cqr->cpaddr->flags |= CCW_FLAG_SLI;
- cqr->cpaddr->count = 32;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_SLCK;
+ ccw->flags |= CCW_FLAG_SLI;
+ ccw->count = 32;
+ ccw->cda = (__u32)(addr_t) cqr->data;
cqr->startdev = device;
cqr->memdev = device;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1990,7 +2688,7 @@ dasd_eckd_performance(struct dasd_device *device, void __user *argp)
sizeof(struct dasd_rssd_perf_stats_t)),
device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
return PTR_ERR(cqr);
}
@@ -2080,9 +2778,9 @@ dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp)
return -EFAULT;
private->attrib = attrib;
- DEV_MESSAGE(KERN_INFO, device,
- "cache operation mode set to %x (%i cylinder prestage)",
- private->attrib.operation, private->attrib.nr_cyl);
+ dev_info(&device->cdev->dev,
+ "The DASD cache mode was set to %x (%i cylinder prestage)\n",
+ private->attrib.operation, private->attrib.nr_cyl);
return 0;
}
@@ -2133,7 +2831,7 @@ static int dasd_symm_io(struct dasd_device *device, void __user *argp)
/* setup CCWs for PSF + RSSD */
cqr = dasd_smalloc_request("ECKD", 2 , 0, device);
if (IS_ERR(cqr)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"Could not allocate initialization request");
rc = PTR_ERR(cqr);
goto out_free;
@@ -2242,11 +2940,54 @@ dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
return len;
}
+static void
+dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req,
+ struct irb *irb, char *reason)
+{
+ u64 *sense;
+ int sl;
+ struct tsb *tsb;
+
+ sense = NULL;
+ tsb = NULL;
+ if (req && scsw_is_tm(&req->irb.scsw)) {
+ if (irb->scsw.tm.tcw)
+ tsb = tcw_get_tsb(
+ (struct tcw *)(unsigned long)irb->scsw.tm.tcw);
+ if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
+ switch (tsb->flags & 0x07) {
+ case 1: /* tsa_iostat */
+ sense = (u64 *)tsb->tsa.iostat.sense;
+ break;
+ case 2: /* ts_ddpc */
+ sense = (u64 *)tsb->tsa.ddpc.sense;
+ break;
+ case 3: /* tsa_intrg */
+ break;
+ }
+ }
+ } else {
+ if (irb->esw.esw0.erw.cons)
+ sense = (u64 *)irb->ecw;
+ }
+ if (sense) {
+ for (sl = 0; sl < 4; sl++) {
+ DBF_DEV_EVENT(DBF_EMERG, device,
+ "%s: %016llx %016llx %016llx %016llx",
+ reason, sense[0], sense[1], sense[2],
+ sense[3]);
+ }
+ } else {
+ DBF_DEV_EVENT(DBF_EMERG, device, "%s",
+ "SORRY - NO VALID SENSE AVAILABLE\n");
+ }
+}
+
/*
* Print sense data and related channel program.
* Parts are printed because printk buffer is only 1024 bytes.
*/
-static void dasd_eckd_dump_sense(struct dasd_device *device,
+static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
struct dasd_ccw_req *req, struct irb *irb)
{
char *page;
@@ -2255,8 +2996,8 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
page = (char *) get_zeroed_page(GFP_ATOMIC);
if (page == NULL) {
- DEV_MESSAGE(KERN_ERR, device, " %s",
- "No memory to dump sense data");
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+ "No memory to dump sense data\n");
return;
}
/* dump the sense data */
@@ -2265,7 +3006,7 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
dev_name(&device->cdev->dev));
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" in req: %p CS: 0x%02X DS: 0x%02X\n", req,
- irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
+ scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw));
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" device %s: Failing CCW: %p\n",
dev_name(&device->cdev->dev),
@@ -2341,6 +3082,147 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
free_page((unsigned long) page);
}
+
+/*
+ * Print sense data from a tcw.
+ */
+static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
+ struct dasd_ccw_req *req, struct irb *irb)
+{
+ char *page;
+ int len, sl, sct, residual;
+
+ struct tsb *tsb;
+ u8 *sense;
+
+
+ page = (char *) get_zeroed_page(GFP_ATOMIC);
+ if (page == NULL) {
+ DBF_DEV_EVENT(DBF_WARNING, device, " %s",
+ "No memory to dump sense data");
+ return;
+ }
+ /* dump the sense data */
+ len = sprintf(page, KERN_ERR PRINTK_HEADER
+ " I/O status report for device %s:\n",
+ dev_name(&device->cdev->dev));
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " in req: %p CS: 0x%02X DS: 0x%02X "
+ "fcxs: 0x%02X schxs: 0x%02X\n", req,
+ scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
+ irb->scsw.tm.fcxs, irb->scsw.tm.schxs);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " device %s: Failing TCW: %p\n",
+ dev_name(&device->cdev->dev),
+ (void *) (addr_t) irb->scsw.tm.tcw);
+
+ tsb = NULL;
+ sense = NULL;
+ if (irb->scsw.tm.tcw)
+ tsb = tcw_get_tsb(
+ (struct tcw *)(unsigned long)irb->scsw.tm.tcw);
+
+ if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->length %d\n", tsb->length);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->flags %x\n", tsb->flags);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->dcw_offset %d\n", tsb->dcw_offset);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->count %d\n", tsb->count);
+ residual = tsb->count - 28;
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " residual %d\n", residual);
+
+ switch (tsb->flags & 0x07) {
+ case 1: /* tsa_iostat */
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.dev_time %d\n",
+ tsb->tsa.iostat.dev_time);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.def_time %d\n",
+ tsb->tsa.iostat.def_time);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.queue_time %d\n",
+ tsb->tsa.iostat.queue_time);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.dev_busy_time %d\n",
+ tsb->tsa.iostat.dev_busy_time);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.iostat.dev_act_time %d\n",
+ tsb->tsa.iostat.dev_act_time);
+ sense = tsb->tsa.iostat.sense;
+ break;
+ case 2: /* ts_ddpc */
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc);
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.ddpc.rcq: ");
+ for (sl = 0; sl < 16; sl++) {
+ for (sct = 0; sct < 8; sct++) {
+ len += sprintf(page + len, " %02x",
+ tsb->tsa.ddpc.rcq[sl]);
+ }
+ len += sprintf(page + len, "\n");
+ }
+ sense = tsb->tsa.ddpc.sense;
+ break;
+ case 3: /* tsa_intrg */
+ len += sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " tsb->tsa.intrg.: not supportet yet \n");
+ break;
+ }
+
+ if (sense) {
+ for (sl = 0; sl < 4; sl++) {
+ len += sprintf(page + len,
+ KERN_ERR PRINTK_HEADER
+ " Sense(hex) %2d-%2d:",
+ (8 * sl), ((8 * sl) + 7));
+ for (sct = 0; sct < 8; sct++) {
+ len += sprintf(page + len, " %02x",
+ sense[8 * sl + sct]);
+ }
+ len += sprintf(page + len, "\n");
+ }
+
+ if (sense[27] & DASD_SENSE_BIT_0) {
+ /* 24 Byte Sense Data */
+ sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " 24 Byte: %x MSG %x, "
+ "%s MSGb to SYSOP\n",
+ sense[7] >> 4, sense[7] & 0x0f,
+ sense[1] & 0x10 ? "" : "no");
+ } else {
+ /* 32 Byte Sense Data */
+ sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " 32 Byte: Format: %x "
+ "Exception class %x\n",
+ sense[6] & 0x0f, sense[22] >> 4);
+ }
+ } else {
+ sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " SORRY - NO VALID SENSE AVAILABLE\n");
+ }
+ } else {
+ sprintf(page + len, KERN_ERR PRINTK_HEADER
+ " SORRY - NO TSB DATA AVAILABLE\n");
+ }
+ printk("%s", page);
+ free_page((unsigned long) page);
+}
+
+static void dasd_eckd_dump_sense(struct dasd_device *device,
+ struct dasd_ccw_req *req, struct irb *irb)
+{
+ if (req && scsw_is_tm(&req->irb.scsw))
+ dasd_eckd_dump_sense_tcw(device, req, irb);
+ else
+ dasd_eckd_dump_sense_ccw(device, req, irb);
+}
+
+
/*
* max_blocks is dependent on the amount of storage that is available
* in the static io buffer for each device. Currently each device has
@@ -2375,6 +3257,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
.build_cp = dasd_eckd_build_alias_cp,
.free_cp = dasd_eckd_free_alias_cp,
.dump_sense = dasd_eckd_dump_sense,
+ .dump_sense_dbf = dasd_eckd_dump_sense_dbf,
.fill_info = dasd_eckd_fill_info,
.ioctl = dasd_eckd_ioctl,
};
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index 2476f87d21d0..ad45bcac3ce4 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -38,8 +38,11 @@
#define DASD_ECKD_CCW_RELEASE 0x94
#define DASD_ECKD_CCW_READ_CKD_MT 0x9e
#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
+#define DASD_ECKD_CCW_WRITE_TRACK_DATA 0xA5
+#define DASD_ECKD_CCW_READ_TRACK_DATA 0xA6
#define DASD_ECKD_CCW_RESERVE 0xB4
#define DASD_ECKD_CCW_PFX 0xE7
+#define DASD_ECKD_CCW_PFX_READ 0xEA
#define DASD_ECKD_CCW_RSCK 0xF9
/*
@@ -48,6 +51,11 @@
#define PSF_ORDER_PRSSD 0x18
#define PSF_ORDER_SSC 0x1D
+/*
+ * Size that is reportet for large volumes in the old 16-bit no_cyl field
+ */
+#define LV_COMPAT_CYL 0xFFFE
+
/*****************************************************************************
* SECTION: Type Definitions
****************************************************************************/
@@ -118,7 +126,9 @@ struct DE_eckd_data {
unsigned long long ep_sys_time; /* Ext Parameter - System Time Stamp */
__u8 ep_format; /* Extended Parameter format byte */
__u8 ep_prio; /* Extended Parameter priority I/O byte */
- __u8 ep_reserved[6]; /* Extended Parameter Reserved */
+ __u8 ep_reserved1; /* Extended Parameter Reserved */
+ __u8 ep_rec_per_track; /* Number of records on a track */
+ __u8 ep_reserved[4]; /* Extended Parameter Reserved */
} __attribute__ ((packed));
struct LO_eckd_data {
@@ -139,11 +149,37 @@ struct LO_eckd_data {
__u16 length;
} __attribute__ ((packed));
+struct LRE_eckd_data {
+ struct {
+ unsigned char orientation:2;
+ unsigned char operation:6;
+ } __attribute__ ((packed)) operation;
+ struct {
+ unsigned char length_valid:1;
+ unsigned char length_scope:1;
+ unsigned char imbedded_ccw_valid:1;
+ unsigned char check_bytes:2;
+ unsigned char imbedded_count_valid:1;
+ unsigned char reserved:1;
+ unsigned char read_count_suffix:1;
+ } __attribute__ ((packed)) auxiliary;
+ __u8 imbedded_ccw;
+ __u8 count;
+ struct ch_t seek_addr;
+ struct chr_t search_arg;
+ __u8 sector;
+ __u16 length;
+ __u8 imbedded_count;
+ __u8 extended_operation;
+ __u16 extended_parameter_length;
+ __u8 extended_parameter[0];
+} __attribute__ ((packed));
+
/* Prefix data for format 0x00 and 0x01 */
struct PFX_eckd_data {
unsigned char format;
struct {
- unsigned char define_extend:1;
+ unsigned char define_extent:1;
unsigned char time_stamp:1;
unsigned char verify_base:1;
unsigned char hyper_pav:1;
@@ -153,9 +189,8 @@ struct PFX_eckd_data {
__u8 aux;
__u8 base_lss;
__u8 reserved[7];
- struct DE_eckd_data define_extend;
- struct LO_eckd_data locate_record;
- __u8 LO_extended_data[4];
+ struct DE_eckd_data define_extent;
+ struct LRE_eckd_data locate_record;
} __attribute__ ((packed));
struct dasd_eckd_characteristics {
@@ -228,7 +263,8 @@ struct dasd_eckd_characteristics {
__u8 factor7;
__u8 factor8;
__u8 reserved2[3];
- __u8 reserved3[10];
+ __u8 reserved3[6];
+ __u32 long_no_cyl;
} __attribute__ ((packed));
/* elements of the configuration data */
@@ -406,6 +442,7 @@ struct dasd_eckd_private {
int uses_cdl;
struct attrib_data_t attrib; /* e.g. cache operations */
struct dasd_rssd_features features;
+ u32 real_cyl;
/* alias managemnet */
struct dasd_uid uid;
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index f8e05ce98621..c24c8c30380d 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -6,6 +6,8 @@
* Author(s): Stefan Weinhuber <wein@de.ibm.com>
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/kernel.h>
@@ -297,11 +299,12 @@ static void dasd_eer_write_standard_trigger(struct dasd_device *device,
struct dasd_eer_header header;
unsigned long flags;
struct eerbuffer *eerb;
+ char *sense;
/* go through cqr chain and count the valid sense data sets */
data_size = 0;
for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
- if (temp_cqr->irb.esw.esw0.erw.cons)
+ if (dasd_get_sense(&temp_cqr->irb))
data_size += 32;
header.total_size = sizeof(header) + data_size + 4; /* "EOR" */
@@ -316,9 +319,11 @@ static void dasd_eer_write_standard_trigger(struct dasd_device *device,
list_for_each_entry(eerb, &bufferlist, list) {
dasd_eer_start_record(eerb, header.total_size);
dasd_eer_write_buffer(eerb, (char *) &header, sizeof(header));
- for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
- if (temp_cqr->irb.esw.esw0.erw.cons)
- dasd_eer_write_buffer(eerb, cqr->irb.ecw, 32);
+ for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers) {
+ sense = dasd_get_sense(&temp_cqr->irb);
+ if (sense)
+ dasd_eer_write_buffer(eerb, sense, 32);
+ }
dasd_eer_write_buffer(eerb, "EOR", 4);
}
spin_unlock_irqrestore(&bufferlock, flags);
@@ -451,6 +456,7 @@ int dasd_eer_enable(struct dasd_device *device)
{
struct dasd_ccw_req *cqr;
unsigned long flags;
+ struct ccw1 *ccw;
if (device->eer_cqr)
return 0;
@@ -468,10 +474,11 @@ int dasd_eer_enable(struct dasd_device *device)
cqr->expires = 10 * HZ;
clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SNSS;
- cqr->cpaddr->count = SNSS_DATA_SIZE;
- cqr->cpaddr->flags = 0;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_SNSS;
+ ccw->count = SNSS_DATA_SIZE;
+ ccw->flags = 0;
+ ccw->cda = (__u32)(addr_t) cqr->data;
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
@@ -534,7 +541,7 @@ static int dasd_eer_open(struct inode *inp, struct file *filp)
if (eerb->buffer_page_count < 1 ||
eerb->buffer_page_count > INT_MAX / PAGE_SIZE) {
kfree(eerb);
- MESSAGE(KERN_WARNING, "can't open device since module "
+ DBF_EVENT(DBF_WARNING, "can't open device since module "
"parameter eer_pages is smaller than 1 or"
" bigger than %d", (int)(INT_MAX / PAGE_SIZE));
unlock_kernel();
@@ -687,7 +694,7 @@ int __init dasd_eer_init(void)
if (rc) {
kfree(dasd_eer_dev);
dasd_eer_dev = NULL;
- MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not "
+ DBF_EVENT(DBF_ERR, "%s", "dasd_eer_init could not "
"register misc device");
return rc;
}
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
index 8f10000851a3..d970ce2814be 100644
--- a/drivers/s390/block/dasd_erp.c
+++ b/drivers/s390/block/dasd_erp.c
@@ -9,6 +9,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/ctype.h>
#include <linux/init.h>
@@ -91,14 +93,14 @@ dasd_default_erp_action(struct dasd_ccw_req *cqr)
/* just retry - there is nothing to save ... I got no sense data.... */
if (cqr->retries > 0) {
- DEV_MESSAGE (KERN_DEBUG, device,
+ DBF_DEV_EVENT(DBF_DEBUG, device,
"default ERP called (%i retries left)",
cqr->retries);
cqr->lpm = LPM_ANYPATH;
cqr->status = DASD_CQR_FILLED;
} else {
- DEV_MESSAGE (KERN_WARNING, device, "%s",
- "default ERP called (NO retry left)");
+ dev_err(&device->cdev->dev,
+ "default ERP has run out of retries and failed\n");
cqr->status = DASD_CQR_FAILED;
cqr->stopclk = get_clock();
}
@@ -162,8 +164,21 @@ dasd_log_sense(struct dasd_ccw_req *cqr, struct irb *irb)
device->discipline->dump_sense(device, cqr, irb);
}
+void
+dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb)
+{
+ struct dasd_device *device;
+
+ device = cqr->startdev;
+ /* dump sense data to s390 debugfeature*/
+ if (device->discipline && device->discipline->dump_sense_dbf)
+ device->discipline->dump_sense_dbf(device, cqr, irb, "log");
+}
+EXPORT_SYMBOL(dasd_log_sense_dbf);
+
EXPORT_SYMBOL(dasd_default_erp_action);
EXPORT_SYMBOL(dasd_default_erp_postaction);
EXPORT_SYMBOL(dasd_alloc_erp_request);
EXPORT_SYMBOL(dasd_free_erp_request);
EXPORT_SYMBOL(dasd_log_sense);
+
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index f1d176021694..a3eb6fd14673 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -6,6 +6,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <asm/debug.h>
@@ -128,17 +130,18 @@ dasd_fba_check_characteristics(struct dasd_device *device)
private = kzalloc(sizeof(struct dasd_fba_private),
GFP_KERNEL | GFP_DMA);
if (private == NULL) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "memory allocation failed for private "
- "data");
+ dev_warn(&device->cdev->dev,
+ "Allocating memory for private DASD "
+ "data failed\n");
return -ENOMEM;
}
device->private = (void *) private;
}
block = dasd_alloc_block();
if (IS_ERR(block)) {
- DEV_MESSAGE(KERN_WARNING, device, "%s",
- "could not allocate dasd block structure");
+ DBF_EVENT(DBF_WARNING, "could not allocate dasd block "
+ "structure for device: %s",
+ dev_name(&device->cdev->dev));
device->private = NULL;
kfree(private);
return PTR_ERR(block);
@@ -150,9 +153,9 @@ dasd_fba_check_characteristics(struct dasd_device *device)
rdc_data = (void *) &(private->rdc_data);
rc = dasd_generic_read_dev_chars(device, "FBA ", &rdc_data, 32);
if (rc) {
- DEV_MESSAGE(KERN_WARNING, device,
- "Read device characteristics returned error %d",
- rc);
+ DBF_EVENT(DBF_WARNING, "Read device characteristics returned "
+ "error %d for device: %s",
+ rc, dev_name(&device->cdev->dev));
device->block = NULL;
dasd_free_block(block);
device->private = NULL;
@@ -160,15 +163,16 @@ dasd_fba_check_characteristics(struct dasd_device *device)
return rc;
}
- DEV_MESSAGE(KERN_INFO, device,
- "%04X/%02X(CU:%04X/%02X) %dMB at(%d B/blk)",
- cdev->id.dev_type,
- cdev->id.dev_model,
- cdev->id.cu_type,
- cdev->id.cu_model,
- ((private->rdc_data.blk_bdsa *
- (private->rdc_data.blk_size >> 9)) >> 11),
- private->rdc_data.blk_size);
+ dev_info(&device->cdev->dev,
+ "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB "
+ "and %d B/blk\n",
+ cdev->id.dev_type,
+ cdev->id.dev_model,
+ cdev->id.cu_type,
+ cdev->id.cu_model,
+ ((private->rdc_data.blk_bdsa *
+ (private->rdc_data.blk_size >> 9)) >> 11),
+ private->rdc_data.blk_size);
return 0;
}
@@ -180,7 +184,7 @@ static int dasd_fba_do_analysis(struct dasd_block *block)
private = (struct dasd_fba_private *) block->base->private;
rc = dasd_check_blocksize(private->rdc_data.blk_size);
if (rc) {
- DEV_MESSAGE(KERN_INFO, block->base, "unknown blocksize %d",
+ DBF_DEV_EVENT(DBF_WARNING, block->base, "unknown blocksize %d",
private->rdc_data.blk_size);
return rc;
}
@@ -215,7 +219,7 @@ dasd_fba_erp_postaction(struct dasd_ccw_req * cqr)
if (cqr->function == dasd_default_erp_action)
return dasd_default_erp_postaction;
- DEV_MESSAGE(KERN_WARNING, cqr->startdev, "unknown ERP action %p",
+ DBF_DEV_EVENT(DBF_WARNING, cqr->startdev, "unknown ERP action %p",
cqr->function);
return NULL;
}
@@ -233,9 +237,9 @@ static void dasd_fba_handle_unsolicited_interrupt(struct dasd_device *device,
}
/* check for unsolicited interrupts */
- DEV_MESSAGE(KERN_DEBUG, device, "%s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"unsolicited interrupt received");
- device->discipline->dump_sense(device, NULL, irb);
+ device->discipline->dump_sense_dbf(device, NULL, irb, "unsolicited");
dasd_schedule_device_bh(device);
return;
};
@@ -437,6 +441,25 @@ dasd_fba_fill_info(struct dasd_device * device,
}
static void
+dasd_fba_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req,
+ struct irb *irb, char *reason)
+{
+ int sl;
+ if (irb->esw.esw0.erw.cons) {
+ for (sl = 0; sl < 4; sl++) {
+ DBF_DEV_EVENT(DBF_EMERG, device,
+ "%s: %08x %08x %08x %08x",
+ reason, irb->ecw[8 * 0], irb->ecw[8 * 1],
+ irb->ecw[8 * 2], irb->ecw[8 * 3]);
+ }
+ } else {
+ DBF_DEV_EVENT(DBF_EMERG, device, "%s",
+ "SORRY - NO VALID SENSE AVAILABLE\n");
+ }
+}
+
+
+static void
dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
struct irb *irb)
{
@@ -446,7 +469,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
page = (char *) get_zeroed_page(GFP_ATOMIC);
if (page == NULL) {
- DEV_MESSAGE(KERN_ERR, device, " %s",
+ DBF_DEV_EVENT(DBF_WARNING, device, "%s",
"No memory to dump sense data");
return;
}
@@ -476,8 +499,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
len += sprintf(page + len, KERN_ERR PRINTK_HEADER
" SORRY - NO VALID SENSE AVAILABLE\n");
}
- MESSAGE_LOG(KERN_ERR, "%s",
- page + sizeof(KERN_ERR PRINTK_HEADER));
+ printk(KERN_ERR "%s", page);
/* dump the Channel Program */
/* print first CCWs (maximum 8) */
@@ -498,8 +520,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
len += sprintf(page + len, "\n");
act++;
}
- MESSAGE_LOG(KERN_ERR, "%s",
- page + sizeof(KERN_ERR PRINTK_HEADER));
+ printk(KERN_ERR "%s", page);
/* print failing CCW area */
@@ -540,8 +561,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
act++;
}
if (len > 0)
- MESSAGE_LOG(KERN_ERR, "%s",
- page + sizeof(KERN_ERR PRINTK_HEADER));
+ printk(KERN_ERR "%s", page);
free_page((unsigned long) page);
}
@@ -576,6 +596,7 @@ static struct dasd_discipline dasd_fba_discipline = {
.build_cp = dasd_fba_build_cp,
.free_cp = dasd_fba_free_cp,
.dump_sense = dasd_fba_dump_sense,
+ .dump_sense_dbf = dasd_fba_dump_sense_dbf,
.fill_info = dasd_fba_fill_info,
};
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index e99d566b69cc..d3198303b93c 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -11,6 +11,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/blkpg.h>
@@ -163,9 +165,8 @@ int dasd_gendisk_init(void)
/* Register to static dasd major 94 */
rc = register_blkdev(DASD_MAJOR, "dasd");
if (rc != 0) {
- MESSAGE(KERN_WARNING,
- "Couldn't register successfully to "
- "major no %d", DASD_MAJOR);
+ pr_warning("Registering the device driver with major number "
+ "%d failed\n", DASD_MAJOR);
return rc;
}
return 0;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 4a39084d9c95..c1e487f774c6 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -112,6 +112,9 @@ do { \
d_data); \
} while(0)
+/* limit size for an errorstring */
+#define ERRORLENGTH 30
+
/* definition of dbf debug levels */
#define DBF_EMERG 0 /* system is unusable */
#define DBF_ALERT 1 /* action must be taken immediately */
@@ -157,7 +160,8 @@ struct dasd_ccw_req {
struct dasd_block *block; /* the originating block device */
struct dasd_device *memdev; /* the device used to allocate this */
struct dasd_device *startdev; /* device the request is started on */
- struct ccw1 *cpaddr; /* address of channel program */
+ void *cpaddr; /* address of ccw or tcw */
+ unsigned char cpmode; /* 0 = cmd mode, 1 = itcw */
char status; /* status of this request */
short retries; /* A retry counter */
unsigned long flags; /* flags of this request */
@@ -280,6 +284,8 @@ struct dasd_discipline {
dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *);
void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *,
struct irb *);
+ void (*dump_sense_dbf) (struct dasd_device *, struct dasd_ccw_req *,
+ struct irb *, char *);
void (*handle_unsolicited_interrupt) (struct dasd_device *,
struct irb *);
@@ -378,7 +384,7 @@ struct dasd_block {
struct block_device *bdev;
atomic_t open_count;
- unsigned long blocks; /* size of volume in blocks */
+ unsigned long long blocks; /* size of volume in blocks */
unsigned int bp_block; /* bytes per block */
unsigned int s2b_shift; /* log2 (bp_block/512) */
@@ -573,12 +579,14 @@ int dasd_generic_notify(struct ccw_device *, int);
void dasd_generic_handle_state_change(struct dasd_device *);
int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int);
+char *dasd_get_sense(struct irb *);
/* externals in dasd_devmap.c */
extern int dasd_max_devindex;
extern int dasd_probeonly;
extern int dasd_autodetect;
extern int dasd_nopav;
+extern int dasd_nofcx;
int dasd_devmap_init(void);
void dasd_devmap_exit(void);
@@ -623,6 +631,7 @@ struct dasd_ccw_req *dasd_alloc_erp_request(char *, int, int,
struct dasd_device *);
void dasd_free_erp_request(struct dasd_ccw_req *, struct dasd_device *);
void dasd_log_sense(struct dasd_ccw_req *, struct irb *);
+void dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb);
/* externals in dasd_3990_erp.c */
struct dasd_ccw_req *dasd_3990_erp_action(struct dasd_ccw_req *);
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index b82d816d9ef7..4ce3f72ee1c1 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -9,6 +9,9 @@
*
* i/o controls for the dasd driver.
*/
+
+#define KMSG_COMPONENT "dasd"
+
#include <linux/interrupt.h>
#include <linux/major.h>
#include <linux/fs.h>
@@ -94,7 +97,8 @@ static int dasd_ioctl_quiesce(struct dasd_block *block)
if (!capable (CAP_SYS_ADMIN))
return -EACCES;
- DEV_MESSAGE(KERN_DEBUG, base, "%s", "Quiesce IO on device");
+ dev_info(&base->cdev->dev, "The DASD has been put in the quiesce "
+ "state\n");
spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
base->stopped |= DASD_STOPPED_QUIESCE;
spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
@@ -103,7 +107,7 @@ static int dasd_ioctl_quiesce(struct dasd_block *block)
/*
- * Quiesce device.
+ * Resume device.
*/
static int dasd_ioctl_resume(struct dasd_block *block)
{
@@ -114,7 +118,8 @@ static int dasd_ioctl_resume(struct dasd_block *block)
if (!capable (CAP_SYS_ADMIN))
return -EACCES;
- DEV_MESSAGE(KERN_DEBUG, base, "%s", "resume IO on device");
+ dev_info(&base->cdev->dev, "I/O operations have been resumed "
+ "on the DASD\n");
spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags);
base->stopped &= ~DASD_STOPPED_QUIESCE;
spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags);
@@ -140,13 +145,13 @@ static int dasd_format(struct dasd_block *block, struct format_data_t *fdata)
return -EPERM;
if (base->state != DASD_STATE_BASIC) {
- DEV_MESSAGE(KERN_WARNING, base, "%s",
- "dasd_format: device is not disabled! ");
+ dev_warn(&base->cdev->dev,
+ "The DASD cannot be formatted while it is enabled\n");
return -EBUSY;
}
DBF_DEV_EVENT(DBF_NOTICE, base,
- "formatting units %d to %d (%d B blocks) flags %d",
+ "formatting units %u to %u (%u B blocks) flags %u",
fdata->start_unit,
fdata->stop_unit, fdata->blksize, fdata->intensity);
@@ -169,10 +174,9 @@ static int dasd_format(struct dasd_block *block, struct format_data_t *fdata)
dasd_sfree_request(cqr, cqr->memdev);
if (rc) {
if (rc != -ERESTARTSYS)
- DEV_MESSAGE(KERN_ERR, base,
- " Formatting of unit %d failed "
- "with rc = %d",
- fdata->start_unit, rc);
+ dev_err(&base->cdev->dev,
+ "Formatting unit %d failed with "
+ "rc=%d\n", fdata->start_unit, rc);
return rc;
}
fdata->start_unit++;
@@ -199,8 +203,9 @@ dasd_ioctl_format(struct block_device *bdev, void __user *argp)
if (copy_from_user(&fdata, argp, sizeof(struct format_data_t)))
return -EFAULT;
if (bdev != bdev->bd_contains) {
- DEV_MESSAGE(KERN_WARNING, block->base, "%s",
- "Cannot low-level format a partition");
+ dev_warn(&block->base->cdev->dev,
+ "The specified DASD is a partition and cannot be "
+ "formatted\n");
return -EINVAL;
}
return dasd_format(block, &fdata);
@@ -365,9 +370,9 @@ static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd,
return ret;
}
-int
-dasd_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
+static int
+dasd_do_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
{
struct dasd_block *block = bdev->bd_disk->private_data;
void __user *argp = (void __user *)arg;
@@ -420,3 +425,14 @@ dasd_ioctl(struct block_device *bdev, fmode_t mode,
return -EINVAL;
}
}
+
+int dasd_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+{
+ int rc;
+
+ lock_kernel();
+ rc = dasd_do_ioctl(bdev, mode, cmd, arg);
+ unlock_kernel();
+ return rc;
+}
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index bf6fd348f20e..654daa3cdfda 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -11,6 +11,8 @@
*
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/ctype.h>
#include <linux/seq_file.h>
#include <linux/vmalloc.h>
@@ -112,7 +114,7 @@ dasd_devices_show(struct seq_file *m, void *v)
seq_printf(m, "n/f ");
else
seq_printf(m,
- "at blocksize: %d, %ld blocks, %ld MB",
+ "at blocksize: %d, %lld blocks, %lld MB",
block->bp_block, block->blocks,
((block->bp_block >> 9) *
block->blocks) >> 11);
@@ -267,7 +269,7 @@ dasd_statistics_write(struct file *file, const char __user *user_buf,
buffer = dasd_get_user_string(user_buf, user_len);
if (IS_ERR(buffer))
return PTR_ERR(buffer);
- MESSAGE_LOG(KERN_INFO, "/proc/dasd/statictics: '%s'", buffer);
+ DBF_EVENT(DBF_DEBUG, "/proc/dasd/statictics: '%s'\n", buffer);
/* check for valid verbs */
for (str = buffer; isspace(*str); str++);
@@ -277,33 +279,33 @@ dasd_statistics_write(struct file *file, const char __user *user_buf,
if (strcmp(str, "on") == 0) {
/* switch on statistics profiling */
dasd_profile_level = DASD_PROFILE_ON;
- MESSAGE(KERN_INFO, "%s", "Statistics switched on");
+ pr_info("The statistics feature has been switched "
+ "on\n");
} else if (strcmp(str, "off") == 0) {
/* switch off and reset statistics profiling */
memset(&dasd_global_profile,
0, sizeof (struct dasd_profile_info_t));
dasd_profile_level = DASD_PROFILE_OFF;
- MESSAGE(KERN_INFO, "%s", "Statistics switched off");
+ pr_info("The statistics feature has been switched "
+ "off\n");
} else
goto out_error;
} else if (strncmp(str, "reset", 5) == 0) {
/* reset the statistics */
memset(&dasd_global_profile, 0,
sizeof (struct dasd_profile_info_t));
- MESSAGE(KERN_INFO, "%s", "Statistics reset");
+ pr_info("The statistics have been reset\n");
} else
goto out_error;
kfree(buffer);
return user_len;
out_error:
- MESSAGE(KERN_WARNING, "%s",
- "/proc/dasd/statistics: only 'set on', 'set off' "
- "and 'reset' are supported verbs");
+ pr_warning("%s is not a supported value for /proc/dasd/statistics\n",
+ str);
kfree(buffer);
return -EINVAL;
#else
- MESSAGE(KERN_WARNING, "%s",
- "/proc/dasd/statistics: is not activated in this kernel");
+ pr_warning("/proc/dasd/statistics: is not activated in this kernel\n");
return user_len;
#endif /* CONFIG_DASD_PROFILE */
}
@@ -318,7 +320,6 @@ dasd_proc_init(void)
dasd_proc_root_entry = proc_mkdir("dasd", NULL);
if (!dasd_proc_root_entry)
goto out_nodasd;
- dasd_proc_root_entry->owner = THIS_MODULE;
dasd_devices_entry = proc_create("devices",
S_IFREG | S_IRUGO | S_IWUSR,
dasd_proc_root_entry,
@@ -332,7 +333,6 @@ dasd_proc_init(void)
goto out_nostatistics;
dasd_statistics_entry->read_proc = dasd_statistics_read;
dasd_statistics_entry->write_proc = dasd_statistics_write;
- dasd_statistics_entry->owner = THIS_MODULE;
return 0;
out_nostatistics:
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index d0d565a05dfe..c07809c8016a 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -324,8 +324,6 @@ static inline void tape_proc_cleanup (void) {;}
#endif
/* a function for dumping device sense info */
-extern void tape_dump_sense(struct tape_device *, struct tape_request *,
- struct irb *);
extern void tape_dump_sense_dbf(struct tape_device *, struct tape_request *,
struct irb *);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 22ca34361ed7..807ded5eb049 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -8,6 +8,8 @@
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
+#define KMSG_COMPONENT "tape"
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bio.h>
@@ -18,8 +20,6 @@
#include "tape.h"
#include "tape_std.h"
-#define PRINTK_HEADER "TAPE_34XX: "
-
/*
* Pointer to debug area.
*/
@@ -203,8 +203,7 @@ tape_34xx_unsolicited_irq(struct tape_device *device, struct irb *irb)
tape_34xx_schedule_work(device, TO_MSEN);
} else {
DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
- PRINT_WARN("Unsolicited IRQ (Device End) caught.\n");
- tape_dump_sense(device, NULL, irb);
+ tape_dump_sense_dbf(device, NULL, irb);
}
return TAPE_IO_SUCCESS;
}
@@ -226,9 +225,7 @@ tape_34xx_erp_read_opposite(struct tape_device *device,
tape_std_read_backward(device, request);
return tape_34xx_erp_retry(request);
}
- if (request->op != TO_RBA)
- PRINT_ERR("read_opposite called with state:%s\n",
- tape_op_verbose[request->op]);
+
/*
* We tried to read forward and backward, but hat no
* success -> failed.
@@ -241,13 +238,9 @@ tape_34xx_erp_bug(struct tape_device *device, struct tape_request *request,
struct irb *irb, int no)
{
if (request->op != TO_ASSIGN) {
- PRINT_WARN("An unexpected condition #%d was caught in "
- "tape error recovery.\n", no);
- PRINT_WARN("Please report this incident.\n");
- if (request)
- PRINT_WARN("Operation of tape:%s\n",
- tape_op_verbose[request->op]);
- tape_dump_sense(device, request, irb);
+ dev_err(&device->cdev->dev, "An unexpected condition %d "
+ "occurred in tape error recovery\n", no);
+ tape_dump_sense_dbf(device, request, irb);
}
return tape_34xx_erp_failed(request, -EIO);
}
@@ -261,9 +254,8 @@ tape_34xx_erp_overrun(struct tape_device *device, struct tape_request *request,
struct irb *irb)
{
if (irb->ecw[3] == 0x40) {
- PRINT_WARN ("Data overrun error between control-unit "
- "and drive. Use a faster channel connection, "
- "if possible! \n");
+ dev_warn (&device->cdev->dev, "A data overrun occurred between"
+ " the control unit and tape unit\n");
return tape_34xx_erp_failed(request, -EIO);
}
return tape_34xx_erp_bug(device, request, irb, -1);
@@ -280,7 +272,8 @@ tape_34xx_erp_sequence(struct tape_device *device,
/*
* cu detected incorrect block-id sequence on tape.
*/
- PRINT_WARN("Illegal block-id sequence found!\n");
+ dev_warn (&device->cdev->dev, "The block ID sequence on the "
+ "tape is incorrect\n");
return tape_34xx_erp_failed(request, -EIO);
}
/*
@@ -393,8 +386,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
/* Writing at physical end of volume */
return tape_34xx_erp_failed(request, -ENOSPC);
default:
- PRINT_ERR("Invalid op in %s:%i\n",
- __func__, __LINE__);
return tape_34xx_erp_failed(request, 0);
}
}
@@ -420,7 +411,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
irb, -4);
/* data check is permanent, CU recovery has failed */
- PRINT_WARN("Permanent read error\n");
+ dev_warn (&device->cdev->dev, "A read error occurred "
+ "that cannot be recovered\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x25:
// a write data check occurred
@@ -433,22 +425,26 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
irb, -5);
// data check is permanent, cu-recovery has failed
- PRINT_WARN("Permanent write error\n");
+ dev_warn (&device->cdev->dev, "A write error on the "
+ "tape cannot be recovered\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x26:
/* Data Check (read opposite) occurred. */
return tape_34xx_erp_read_opposite(device, request);
case 0x28:
/* ID-Mark at tape start couldn't be written */
- PRINT_WARN("ID-Mark could not be written.\n");
+ dev_warn (&device->cdev->dev, "Writing the ID-mark "
+ "failed\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x31:
/* Tape void. Tried to read beyond end of device. */
- PRINT_WARN("Read beyond end of recorded area.\n");
+ dev_warn (&device->cdev->dev, "Reading the tape beyond"
+ " the end of the recorded area failed\n");
return tape_34xx_erp_failed(request, -ENOSPC);
case 0x41:
/* Record sequence error. */
- PRINT_WARN("Invalid block-id sequence found.\n");
+ dev_warn (&device->cdev->dev, "The tape contains an "
+ "incorrect block ID sequence\n");
return tape_34xx_erp_failed(request, -EIO);
default:
/* all data checks for 3480 should result in one of
@@ -470,16 +466,12 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
switch (sense[3]) {
case 0x00:
/* Unit check with erpa code 0. Report and ignore. */
- PRINT_WARN("Non-error sense was found. "
- "Unit-check will be ignored.\n");
return TAPE_IO_SUCCESS;
case 0x21:
/*
* Data streaming not operational. CU will switch to
* interlock mode. Reissue the command.
*/
- PRINT_WARN("Data streaming not operational. "
- "Switching to interlock-mode.\n");
return tape_34xx_erp_retry(request);
case 0x22:
/*
@@ -487,11 +479,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* error on the lower interface, internal path not usable,
* or error during cartridge load.
*/
- PRINT_WARN("A path equipment check occurred. One of the "
- "following conditions occurred:\n");
- PRINT_WARN("drive adapter error, buffer error on the lower "
- "interface, internal path not usable, error "
- "during cartridge load.\n");
+ dev_warn (&device->cdev->dev, "A path equipment check occurred"
+ " for the tape device\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x24:
/*
@@ -514,7 +503,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* but the hardware isn't capable to do idrc, or a perform
* subsystem func is issued and the CU is not on-line.
*/
- PRINT_WARN ("Function incompatible. Try to switch off idrc\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x2a:
/*
@@ -552,23 +540,26 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* reading the format id mark or that that format specified
* is not supported by the drive.
*/
- PRINT_WARN("Drive not capable processing the tape format!\n");
+ dev_warn (&device->cdev->dev, "The tape unit cannot process "
+ "the tape format\n");
return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
case 0x30:
/* The medium is write protected. */
- PRINT_WARN("Medium is write protected!\n");
+ dev_warn (&device->cdev->dev, "The tape medium is write-"
+ "protected\n");
return tape_34xx_erp_failed(request, -EACCES);
case 0x32:
// Tension loss. We cannot recover this, it's an I/O error.
- PRINT_WARN("The drive lost tape tension.\n");
+ dev_warn (&device->cdev->dev, "The tape does not have the "
+ "required tape tension\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x33:
/*
* Load Failure. The cartridge was not inserted correctly or
* the tape is not threaded correctly.
*/
- PRINT_WARN("Cartridge load failure. Reload the cartridge "
- "and try again.\n");
+ dev_warn (&device->cdev->dev, "The tape unit failed to load"
+ " the cartridge\n");
tape_34xx_delete_sbid_from(device, 0);
return tape_34xx_erp_failed(request, -EIO);
case 0x34:
@@ -576,8 +567,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* Unload failure. The drive cannot maintain tape tension
* and control tape movement during an unload operation.
*/
- PRINT_WARN("Failure during cartridge unload. "
- "Please try manually.\n");
+ dev_warn (&device->cdev->dev, "Automatic unloading of the tape"
+ " cartridge failed\n");
if (request->op == TO_RUN)
return tape_34xx_erp_failed(request, -EIO);
return tape_34xx_erp_bug(device, request, irb, sense[3]);
@@ -589,8 +580,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* - the cartridge loader does not respond correctly
* - a failure occurs during an index, load, or unload cycle
*/
- PRINT_WARN("Equipment check! Please check the drive and "
- "the cartridge loader.\n");
+ dev_warn (&device->cdev->dev, "An equipment check has occurred"
+ " on the tape unit\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x36:
if (device->cdev->id.driver_info == tape_3490)
@@ -603,7 +594,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* Tape length error. The tape is shorter than reported in
* the beginning-of-tape data.
*/
- PRINT_WARN("Tape length error.\n");
+ dev_warn (&device->cdev->dev, "The tape information states an"
+ " incorrect length\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x38:
/*
@@ -620,12 +612,12 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
return tape_34xx_erp_failed(request, -EIO);
case 0x3a:
/* Drive switched to not ready. */
- PRINT_WARN("Drive not ready. Turn the ready/not ready switch "
- "to ready position and try again.\n");
+ dev_warn (&device->cdev->dev, "The tape unit is not ready\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x3b:
/* Manual rewind or unload. This causes an I/O error. */
- PRINT_WARN("Medium was rewound or unloaded manually.\n");
+ dev_warn (&device->cdev->dev, "The tape medium has been "
+ "rewound or unloaded manually\n");
tape_34xx_delete_sbid_from(device, 0);
return tape_34xx_erp_failed(request, -EIO);
case 0x42:
@@ -633,7 +625,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* Degraded mode. A condition that can cause degraded
* performance is detected.
*/
- PRINT_WARN("Subsystem is running in degraded mode.\n");
+ dev_warn (&device->cdev->dev, "The tape subsystem is running "
+ "in degraded mode\n");
return tape_34xx_erp_retry(request);
case 0x43:
/* Drive not ready. */
@@ -652,7 +645,6 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
break;
}
}
- PRINT_WARN("The drive is not ready.\n");
return tape_34xx_erp_failed(request, -ENOMEDIUM);
case 0x44:
/* Locate Block unsuccessful. */
@@ -663,7 +655,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
return tape_34xx_erp_failed(request, -EIO);
case 0x45:
/* The drive is assigned to a different channel path. */
- PRINT_WARN("The drive is assigned elsewhere.\n");
+ dev_warn (&device->cdev->dev, "The tape unit is already "
+ "assigned\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x46:
/*
@@ -671,11 +664,12 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* the power supply may be switched off or
* the drive address may not be set correctly.
*/
- PRINT_WARN("The drive is not on-line.");
+ dev_warn (&device->cdev->dev, "The tape unit is not online\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x47:
/* Volume fenced. CU reports volume integrity is lost. */
- PRINT_WARN("Volume fenced. The volume integrity is lost.\n");
+ dev_warn (&device->cdev->dev, "The control unit has fenced "
+ "access to the tape volume\n");
tape_34xx_delete_sbid_from(device, 0);
return tape_34xx_erp_failed(request, -EIO);
case 0x48:
@@ -683,20 +677,21 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
return tape_34xx_erp_retry(request);
case 0x49:
/* Bus out check. A parity check error on the bus was found. */
- PRINT_WARN("Bus out check. A data transfer over the bus "
- "has been corrupted.\n");
+ dev_warn (&device->cdev->dev, "A parity error occurred on the "
+ "tape bus\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x4a:
/* Control unit erp failed. */
- PRINT_WARN("The control unit I/O error recovery failed.\n");
+ dev_warn (&device->cdev->dev, "I/O error recovery failed on "
+ "the tape control unit\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x4b:
/*
* CU and drive incompatible. The drive requests micro-program
* patches, which are not available on the CU.
*/
- PRINT_WARN("The drive needs microprogram patches from the "
- "control unit, which are not available.\n");
+ dev_warn (&device->cdev->dev, "The tape unit requires a "
+ "firmware update\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x4c:
/*
@@ -721,8 +716,8 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* the block to be written is larger than allowed for
* buffered mode.
*/
- PRINT_WARN("Maximum block size for buffered "
- "mode exceeded.\n");
+ dev_warn (&device->cdev->dev, "The maximum block size"
+ " for buffered mode is exceeded\n");
return tape_34xx_erp_failed(request, -ENOBUFS);
}
/* This erpa is reserved for 3480. */
@@ -759,22 +754,20 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
return tape_34xx_erp_retry(request);
case 0x55:
/* Channel interface recovery (permanent). */
- PRINT_WARN("A permanent channel interface error occurred.\n");
+ dev_warn (&device->cdev->dev, "A channel interface error cannot be"
+ " recovered\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x56:
/* Channel protocol error. */
- PRINT_WARN("A channel protocol error occurred.\n");
+ dev_warn (&device->cdev->dev, "A channel protocol error "
+ "occurred\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x57:
if (device->cdev->id.driver_info == tape_3480) {
/* Attention intercept. */
- PRINT_WARN("An attention intercept occurred, "
- "which will be recovered.\n");
return tape_34xx_erp_retry(request);
} else {
/* Global status intercept. */
- PRINT_WARN("An global status intercept was received, "
- "which will be recovered.\n");
return tape_34xx_erp_retry(request);
}
case 0x5a:
@@ -782,42 +775,31 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,
* Tape length incompatible. The tape inserted is too long,
* which could cause damage to the tape or the drive.
*/
- PRINT_WARN("Tape Length Incompatible\n");
- PRINT_WARN("Tape length exceeds IBM enhanced capacity "
- "cartdridge length or a medium\n");
- PRINT_WARN("with EC-CST identification mark has been mounted "
- "in a device that writes\n");
- PRINT_WARN("3480 or 3480 XF format.\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support "
+ "the tape length\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x5b:
/* Format 3480 XF incompatible */
if (sense[1] & SENSE_BEGINNING_OF_TAPE)
/* The tape will get overwritten. */
return tape_34xx_erp_retry(request);
- PRINT_WARN("Format 3480 XF Incompatible\n");
- PRINT_WARN("Medium has been created in 3480 format. "
- "To change the format writes\n");
- PRINT_WARN("must be issued at BOT.\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support"
+ " format 3480 XF\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x5c:
/* Format 3480-2 XF incompatible */
- PRINT_WARN("Format 3480-2 XF Incompatible\n");
- PRINT_WARN("Device can only read 3480 or 3480 XF format.\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support tape "
+ "format 3480-2 XF\n");
return tape_34xx_erp_failed(request, -EIO);
case 0x5d:
/* Tape length violation. */
- PRINT_WARN("Tape Length Violation\n");
- PRINT_WARN("The mounted tape exceeds IBM Enhanced Capacity "
- "Cartdridge System Tape length.\n");
- PRINT_WARN("This may cause damage to the drive or tape when "
- "processing to the EOV\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support"
+ " the current tape length\n");
return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
case 0x5e:
/* Compaction algorithm incompatible. */
- PRINT_WARN("Compaction Algorithm Incompatible\n");
- PRINT_WARN("The volume is recorded using an incompatible "
- "compaction algorithm,\n");
- PRINT_WARN("which is not supported by the device.\n");
+ dev_warn (&device->cdev->dev, "The tape unit does not support"
+ " the compaction algorithm\n");
return tape_34xx_erp_failed(request, -EMEDIUMTYPE);
/* The following erpas should have been covered earlier. */
@@ -848,7 +830,6 @@ tape_34xx_irq(struct tape_device *device, struct tape_request *request,
(irb->scsw.cmd.dstat & DEV_STAT_DEV_END) &&
(request->op == TO_WRI)) {
/* Write at end of volume */
- PRINT_INFO("End of volume\n"); /* XXX */
return tape_34xx_erp_failed(request, -ENOSPC);
}
@@ -869,9 +850,7 @@ tape_34xx_irq(struct tape_device *device, struct tape_request *request,
}
DBF_EVENT(6, "xunknownirq\n");
- PRINT_ERR("Unexpected interrupt.\n");
- PRINT_ERR("Current op is: %s", tape_op_verbose[request->op]);
- tape_dump_sense(device, request, irb);
+ tape_dump_sense_dbf(device, request, irb);
return TAPE_IO_STOP;
}
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index 71605a179d65..fc1d91294143 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -8,12 +8,15 @@
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
+#define KMSG_COMPONENT "tape"
+
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bio.h>
#include <asm/ebcdic.h>
#define TAPE_DBF_AREA tape_3590_dbf
+#define BUFSIZE 512 /* size of buffers for dynamic generated messages */
#include "tape.h"
#include "tape_std.h"
@@ -36,7 +39,7 @@ EXPORT_SYMBOL(TAPE_DBF_AREA);
* - Read Alternate: implemented
*******************************************************************/
-#define PRINTK_HEADER "TAPE_3590: "
+#define KMSG_COMPONENT "tape"
static const char *tape_3590_msg[TAPE_3590_MAX_MSG] = {
[0x00] = "",
@@ -661,8 +664,7 @@ tape_3590_bread(struct tape_device *device, struct request *req)
ccw++;
dst += TAPEBLOCK_HSEC_SIZE;
}
- if (off > bv->bv_len)
- BUG();
+ BUG_ON(off > bv->bv_len);
}
ccw = tape_ccw_end(ccw, NOP, 0, NULL);
DBF_EVENT(6, "xBREDccwg\n");
@@ -726,7 +728,7 @@ static void tape_3590_med_state_set(struct tape_device *device,
}
c_info->medium_status |= TAPE390_MEDIUM_LOADED_MASK;
if (sense->flags & MSENSE_CRYPT_MASK) {
- PRINT_INFO("Medium is encrypted (%04x)\n", sense->flags);
+ DBF_EVENT(6, "Medium is encrypted (%04x)\n", sense->flags);
c_info->medium_status |= TAPE390_MEDIUM_ENCRYPTED_MASK;
} else {
DBF_EVENT(6, "Medium is not encrypted %04x\n", sense->flags);
@@ -847,8 +849,7 @@ tape_3590_unsolicited_irq(struct tape_device *device, struct irb *irb)
tape_3590_schedule_work(device, TO_READ_ATTMSG);
} else {
DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);
- PRINT_WARN("Unsolicited IRQ (Device End) caught.\n");
- tape_dump_sense(device, NULL, irb);
+ tape_dump_sense_dbf(device, NULL, irb);
}
/* check medium state */
tape_3590_schedule_work(device, TO_MSEN);
@@ -876,8 +877,6 @@ tape_3590_erp_basic(struct tape_device *device, struct tape_request *request,
case SENSE_BRA_DRE:
return tape_3590_erp_failed(device, request, irb, rc);
default:
- PRINT_ERR("Unknown BRA %x - This should not happen!\n",
- sense->bra);
BUG();
return TAPE_IO_STOP;
}
@@ -910,7 +909,8 @@ tape_3590_erp_swap(struct tape_device *device, struct tape_request *request,
* should proceed with the new tape... this
* should probably be done in user space!
*/
- PRINT_WARN("(%s): Swap Tape Device!\n", dev_name(&device->cdev->dev));
+ dev_warn (&device->cdev->dev, "The tape medium must be loaded into a "
+ "different tape unit\n");
return tape_3590_erp_basic(device, request, irb, -EIO);
}
@@ -985,8 +985,6 @@ tape_3590_erp_read_opposite(struct tape_device *device,
return tape_3590_erp_failed(device, request, irb, -EIO);
break;
default:
- PRINT_WARN("read_opposite_recovery_called_with_op: %s\n",
- tape_op_verbose[request->op]);
return tape_3590_erp_failed(device, request, irb, -EIO);
}
}
@@ -998,50 +996,61 @@ static void
tape_3590_print_mim_msg_f0(struct tape_device *device, struct irb *irb)
{
struct tape_3590_sense *sense;
+ char *exception, *service;
+
+ exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+ service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+ if (!exception || !service)
+ goto out_nomem;
sense = (struct tape_3590_sense *) irb->ecw;
/* Exception Message */
switch (sense->fmt.f70.emc) {
case 0x02:
- PRINT_WARN("(%s): Data degraded\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Data degraded");
break;
case 0x03:
- PRINT_WARN("(%s): Data degraded in partion %i\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.mp);
+ snprintf(exception, BUFSIZE, "Data degraded in partion %i",
+ sense->fmt.f70.mp);
break;
case 0x04:
- PRINT_WARN("(%s): Medium degraded\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Medium degraded");
break;
case 0x05:
- PRINT_WARN("(%s): Medium degraded in partition %i\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.mp);
+ snprintf(exception, BUFSIZE, "Medium degraded in partition %i",
+ sense->fmt.f70.mp);
break;
case 0x06:
- PRINT_WARN("(%s): Block 0 Error\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Block 0 Error");
break;
case 0x07:
- PRINT_WARN("(%s): Medium Exception 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.md);
+ snprintf(exception, BUFSIZE, "Medium Exception 0x%02x",
+ sense->fmt.f70.md);
break;
default:
- PRINT_WARN("(%s): MIM ExMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.emc);
+ snprintf(exception, BUFSIZE, "0x%02x",
+ sense->fmt.f70.emc);
break;
}
/* Service Message */
switch (sense->fmt.f70.smc) {
case 0x02:
- PRINT_WARN("(%s): Reference Media maintenance procedure %i\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.md);
+ snprintf(service, BUFSIZE, "Reference Media maintenance "
+ "procedure %i", sense->fmt.f70.md);
break;
default:
- PRINT_WARN("(%s): MIM ServiceMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f70.smc);
+ snprintf(service, BUFSIZE, "0x%02x",
+ sense->fmt.f70.smc);
break;
}
+
+ dev_warn (&device->cdev->dev, "Tape media information: exception %s, "
+ "service %s\n", exception, service);
+
+out_nomem:
+ kfree(exception);
+ kfree(service);
}
/*
@@ -1051,108 +1060,108 @@ static void
tape_3590_print_io_sim_msg_f1(struct tape_device *device, struct irb *irb)
{
struct tape_3590_sense *sense;
+ char *exception, *service;
+
+ exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+ service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+ if (!exception || !service)
+ goto out_nomem;
sense = (struct tape_3590_sense *) irb->ecw;
/* Exception Message */
switch (sense->fmt.f71.emc) {
case 0x01:
- PRINT_WARN("(%s): Effect of failure is unknown\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Effect of failure is unknown");
break;
case 0x02:
- PRINT_WARN("(%s): CU Exception - no performance impact\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "CU Exception - no performance "
+ "impact");
break;
case 0x03:
- PRINT_WARN("(%s): CU Exception on channel interface 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on channel "
+ "interface 0x%02x", sense->fmt.f71.md[0]);
break;
case 0x04:
- PRINT_WARN("(%s): CU Exception on device path 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on device path "
+ "0x%02x", sense->fmt.f71.md[0]);
break;
case 0x05:
- PRINT_WARN("(%s): CU Exception on library path 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on library path "
+ "0x%02x", sense->fmt.f71.md[0]);
break;
case 0x06:
- PRINT_WARN("(%s): CU Exception on node 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on node 0x%02x",
+ sense->fmt.f71.md[0]);
break;
case 0x07:
- PRINT_WARN("(%s): CU Exception on partition 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "CU Exception on partition "
+ "0x%02x", sense->fmt.f71.md[0]);
break;
default:
- PRINT_WARN("(%s): SIM ExMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.emc);
+ snprintf(exception, BUFSIZE, "0x%02x",
+ sense->fmt.f71.emc);
}
/* Service Message */
switch (sense->fmt.f71.smc) {
case 0x01:
- PRINT_WARN("(%s): Repair impact is unknown\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair impact is unknown");
break;
case 0x02:
- PRINT_WARN("(%s): Repair will not impact cu performance\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair will not impact cu "
+ "performance");
break;
case 0x03:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable node "
- "0x%x on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable node "
+ "0x%x on CU", sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable nodes "
- "(0x%x-0x%x) on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "nodes (0x%x-0x%x) on CU", sense->fmt.f71.md[1],
+ sense->fmt.f71.md[2]);
break;
case 0x04:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable cannel path "
- "0x%x on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "channel path 0x%x on CU",
+ sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable cannel paths "
- "(0x%x-0x%x) on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable cannel"
+ " paths (0x%x-0x%x) on CU",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x05:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable device path "
- "0x%x on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable device"
+ " path 0x%x on CU", sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable device paths "
- "(0x%x-0x%x) on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable device"
+ " paths (0x%x-0x%x) on CU",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x06:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable library path "
- "0x%x on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "library path 0x%x on CU",
+ sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable library paths "
- "(0x%x-0x%x) on CU\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "library paths (0x%x-0x%x) on CU",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x07:
- PRINT_WARN("(%s): Repair will disable access to CU\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair will disable access to CU");
break;
default:
- PRINT_WARN("(%s): SIM ServiceMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.smc);
+ snprintf(service, BUFSIZE, "0x%02x",
+ sense->fmt.f71.smc);
}
+
+ dev_warn (&device->cdev->dev, "I/O subsystem information: exception"
+ " %s, service %s\n", exception, service);
+out_nomem:
+ kfree(exception);
+ kfree(service);
}
/*
@@ -1162,111 +1171,109 @@ static void
tape_3590_print_dev_sim_msg_f2(struct tape_device *device, struct irb *irb)
{
struct tape_3590_sense *sense;
+ char *exception, *service;
+
+ exception = kmalloc(BUFSIZE, GFP_ATOMIC);
+ service = kmalloc(BUFSIZE, GFP_ATOMIC);
+
+ if (!exception || !service)
+ goto out_nomem;
sense = (struct tape_3590_sense *) irb->ecw;
/* Exception Message */
switch (sense->fmt.f71.emc) {
case 0x01:
- PRINT_WARN("(%s): Effect of failure is unknown\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "Effect of failure is unknown");
break;
case 0x02:
- PRINT_WARN("(%s): DV Exception - no performance impact\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "DV Exception - no performance"
+ " impact");
break;
case 0x03:
- PRINT_WARN("(%s): DV Exception on channel interface 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "DV Exception on channel "
+ "interface 0x%02x", sense->fmt.f71.md[0]);
break;
case 0x04:
- PRINT_WARN("(%s): DV Exception on loader 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "DV Exception on loader 0x%02x",
+ sense->fmt.f71.md[0]);
break;
case 0x05:
- PRINT_WARN("(%s): DV Exception on message display 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.md[0]);
+ snprintf(exception, BUFSIZE, "DV Exception on message display"
+ " 0x%02x", sense->fmt.f71.md[0]);
break;
case 0x06:
- PRINT_WARN("(%s): DV Exception in tape path\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "DV Exception in tape path");
break;
case 0x07:
- PRINT_WARN("(%s): DV Exception in drive\n",
- dev_name(&device->cdev->dev));
+ snprintf(exception, BUFSIZE, "DV Exception in drive");
break;
default:
- PRINT_WARN("(%s): DSIM ExMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.emc);
+ snprintf(exception, BUFSIZE, "0x%02x",
+ sense->fmt.f71.emc);
}
/* Service Message */
switch (sense->fmt.f71.smc) {
case 0x01:
- PRINT_WARN("(%s): Repair impact is unknown\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair impact is unknown");
break;
case 0x02:
- PRINT_WARN("(%s): Repair will not impact device performance\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair will not impact device "
+ "performance");
break;
case 0x03:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable channel path "
- "0x%x on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "channel path 0x%x on DV",
+ sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable channel path "
- "(0x%x-0x%x) on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "channel path (0x%x-0x%x) on DV",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x04:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable interface 0x%x "
- "on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "interface 0x%x on DV", sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable interfaces "
- "(0x%x-0x%x) on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "interfaces (0x%x-0x%x) on DV",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x05:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable loader 0x%x "
- "on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable loader"
+ " 0x%x on DV", sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable loader "
- "(0x%x-0x%x) on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable loader"
+ " (0x%x-0x%x) on DV",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x07:
- PRINT_WARN("(%s): Repair will disable access to DV\n",
- dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Repair will disable access to DV");
break;
case 0x08:
if (sense->fmt.f71.mdf == 0)
- PRINT_WARN("(%s): Repair will disable message "
- "display 0x%x on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "message display 0x%x on DV",
+ sense->fmt.f71.md[1]);
else
- PRINT_WARN("(%s): Repair will disable message "
- "displays (0x%x-0x%x) on DV\n",
- dev_name(&device->cdev->dev),
- sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
+ snprintf(service, BUFSIZE, "Repair will disable "
+ "message displays (0x%x-0x%x) on DV",
+ sense->fmt.f71.md[1], sense->fmt.f71.md[2]);
break;
case 0x09:
- PRINT_WARN("(%s): Clean DV\n", dev_name(&device->cdev->dev));
+ snprintf(service, BUFSIZE, "Clean DV");
break;
default:
- PRINT_WARN("(%s): DSIM ServiceMsg: 0x%02x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.smc);
+ snprintf(service, BUFSIZE, "0x%02x",
+ sense->fmt.f71.smc);
}
+
+ dev_warn (&device->cdev->dev, "Device subsystem information: exception"
+ " %s, service %s\n", exception, service);
+out_nomem:
+ kfree(exception);
+ kfree(service);
}
/*
@@ -1282,46 +1289,44 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
return;
if ((sense->mc > 0) && (sense->mc < TAPE_3590_MAX_MSG)) {
if (tape_3590_msg[sense->mc] != NULL)
- PRINT_WARN("(%s): %s\n", dev_name(&device->cdev->dev),
- tape_3590_msg[sense->mc]);
- else {
- PRINT_WARN("(%s): Message Code 0x%x\n",
- dev_name(&device->cdev->dev), sense->mc);
- }
+ dev_warn (&device->cdev->dev, "The tape unit has "
+ "issued sense message %s\n",
+ tape_3590_msg[sense->mc]);
+ else
+ dev_warn (&device->cdev->dev, "The tape unit has "
+ "issued an unknown sense message code 0x%x\n",
+ sense->mc);
return;
}
if (sense->mc == 0xf0) {
/* Standard Media Information Message */
- PRINT_WARN("(%s): MIM SEV=%i, MC=%02x, ES=%x/%x, "
- "RC=%02x-%04x-%02x\n", dev_name(&device->cdev->dev),
- sense->fmt.f70.sev, sense->mc,
- sense->fmt.f70.emc, sense->fmt.f70.smc,
- sense->fmt.f70.refcode, sense->fmt.f70.mid,
- sense->fmt.f70.fid);
+ dev_warn (&device->cdev->dev, "MIM SEV=%i, MC=%02x, ES=%x/%x, "
+ "RC=%02x-%04x-%02x\n", sense->fmt.f70.sev, sense->mc,
+ sense->fmt.f70.emc, sense->fmt.f70.smc,
+ sense->fmt.f70.refcode, sense->fmt.f70.mid,
+ sense->fmt.f70.fid);
tape_3590_print_mim_msg_f0(device, irb);
return;
}
if (sense->mc == 0xf1) {
/* Standard I/O Subsystem Service Information Message */
- PRINT_WARN("(%s): IOSIM SEV=%i, DEVTYPE=3590/%02x, "
- "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.sev,
- device->cdev->id.dev_model,
- sense->mc, sense->fmt.f71.emc,
- sense->fmt.f71.smc, sense->fmt.f71.refcode1,
- sense->fmt.f71.refcode2, sense->fmt.f71.refcode3);
+ dev_warn (&device->cdev->dev, "IOSIM SEV=%i, DEVTYPE=3590/%02x,"
+ " MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
+ sense->fmt.f71.sev, device->cdev->id.dev_model,
+ sense->mc, sense->fmt.f71.emc, sense->fmt.f71.smc,
+ sense->fmt.f71.refcode1, sense->fmt.f71.refcode2,
+ sense->fmt.f71.refcode3);
tape_3590_print_io_sim_msg_f1(device, irb);
return;
}
if (sense->mc == 0xf2) {
/* Standard Device Service Information Message */
- PRINT_WARN("(%s): DEVSIM SEV=%i, DEVTYPE=3590/%02x, "
- "MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
- dev_name(&device->cdev->dev), sense->fmt.f71.sev,
- device->cdev->id.dev_model,
- sense->mc, sense->fmt.f71.emc,
- sense->fmt.f71.smc, sense->fmt.f71.refcode1,
- sense->fmt.f71.refcode2, sense->fmt.f71.refcode3);
+ dev_warn (&device->cdev->dev, "DEVSIM SEV=%i, DEVTYPE=3590/%02x"
+ ", MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n",
+ sense->fmt.f71.sev, device->cdev->id.dev_model,
+ sense->mc, sense->fmt.f71.emc, sense->fmt.f71.smc,
+ sense->fmt.f71.refcode1, sense->fmt.f71.refcode2,
+ sense->fmt.f71.refcode3);
tape_3590_print_dev_sim_msg_f2(device, irb);
return;
}
@@ -1329,8 +1334,8 @@ tape_3590_print_era_msg(struct tape_device *device, struct irb *irb)
/* Standard Library Service Information Message */
return;
}
- PRINT_WARN("(%s): Device Message(%x)\n",
- dev_name(&device->cdev->dev), sense->mc);
+ dev_warn (&device->cdev->dev, "The tape unit has issued an unknown "
+ "sense message code %x\n", sense->mc);
}
static int tape_3590_crypt_error(struct tape_device *device,
@@ -1355,9 +1360,8 @@ static int tape_3590_crypt_error(struct tape_device *device,
/* No connection to EKM */
return tape_3590_erp_basic(device, request, irb, -ENOTCONN);
- PRINT_ERR("(%s): Unable to get encryption key from EKM\n", bus_id);
- PRINT_ERR("(%s): CU=%02X DRIVE=%06X EKM=%02X:%04X\n", bus_id, cu_rc,
- drv_rc, ekm_rc1, ekm_rc2);
+ dev_err (&device->cdev->dev, "The tape unit failed to obtain the "
+ "encryption key from EKM\n");
return tape_3590_erp_basic(device, request, irb, -ENOKEY);
}
@@ -1443,8 +1447,6 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
* print additional msg since default msg
* "device intervention" is not very meaningfull
*/
- PRINT_WARN("(%s): Tape operation when medium not loaded\n",
- dev_name(&device->cdev->dev));
tape_med_state_set(device, MS_UNLOADED);
tape_3590_schedule_work(device, TO_CRYPT_OFF);
return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
@@ -1490,19 +1492,13 @@ tape_3590_unit_check(struct tape_device *device, struct tape_request *request,
return tape_3590_erp_basic(device, request, irb, -ENOMEDIUM);
case 0x6020:
- PRINT_WARN("(%s): Cartridge of wrong type ?\n",
- dev_name(&device->cdev->dev));
return tape_3590_erp_basic(device, request, irb, -EMEDIUMTYPE);
case 0x8011:
- PRINT_WARN("(%s): Another host has reserved the tape device\n",
- dev_name(&device->cdev->dev));
return tape_3590_erp_basic(device, request, irb, -EPERM);
case 0x8013:
- PRINT_WARN("(%s): Another host has privileged access to the "
- "tape device\n", dev_name(&device->cdev->dev));
- PRINT_WARN("(%s): To solve the problem unload the current "
- "cartridge!\n", dev_name(&device->cdev->dev));
+ dev_warn (&device->cdev->dev, "A different host has privileged"
+ " access to the tape unit\n");
return tape_3590_erp_basic(device, request, irb, -EPERM);
default:
return tape_3590_erp_basic(device, request, irb, -EIO);
@@ -1552,9 +1548,7 @@ tape_3590_irq(struct tape_device *device, struct tape_request *request,
}
DBF_EVENT(6, "xunknownirq\n");
- PRINT_ERR("Unexpected interrupt.\n");
- PRINT_ERR("Current op is: %s", tape_op_verbose[request->op]);
- tape_dump_sense(device, request, irb);
+ tape_dump_sense_dbf(device, request, irb);
return TAPE_IO_STOP;
}
@@ -1609,7 +1603,6 @@ tape_3590_setup_device(struct tape_device *device)
if (rc)
goto fail_rdc_data;
if (rdc_data->data[31] == 0x13) {
- PRINT_INFO("Device has crypto support\n");
data->crypt_info.capability |= TAPE390_CRYPT_SUPPORTED_MASK;
tape_3592_disable_crypt(device);
} else {
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index ae18baf59f06..f32e89e7c4f2 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -10,6 +10,8 @@
* Stefan Bader <shbader@de.ibm.com>
*/
+#define KMSG_COMPONENT "tape"
+
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/blkdev.h>
@@ -23,8 +25,6 @@
#include "tape.h"
-#define PRINTK_HEADER "TAPE_BLOCK: "
-
#define TAPEBLOCK_MAX_SEC 100
#define TAPEBLOCK_MIN_REQUEUE 3
@@ -279,8 +279,6 @@ tapeblock_cleanup_device(struct tape_device *device)
tape_put_device(device);
if (!device->blk_data.disk) {
- PRINT_ERR("(%s): No gendisk to clean up!\n",
- dev_name(&device->cdev->dev));
goto cleanup_queue;
}
@@ -314,7 +312,8 @@ tapeblock_revalidate_disk(struct gendisk *disk)
if (!device->blk_data.medium_changed)
return 0;
- PRINT_INFO("Detecting media size...\n");
+ dev_info(&device->cdev->dev, "Determining the size of the recorded "
+ "area...\n");
rc = tape_mtop(device, MTFSFM, 1);
if (rc)
return rc;
@@ -341,7 +340,8 @@ tapeblock_revalidate_disk(struct gendisk *disk)
device->bof = rc;
nr_of_blks -= rc;
- PRINT_INFO("Found %i blocks on media\n", nr_of_blks);
+ dev_info(&device->cdev->dev, "The size of the recorded area is %i "
+ "blocks\n", nr_of_blks);
set_capacity(device->blk_data.disk,
nr_of_blks*(TAPEBLOCK_HSEC_SIZE/512));
@@ -376,8 +376,8 @@ tapeblock_open(struct block_device *bdev, fmode_t mode)
if (device->required_tapemarks) {
DBF_EVENT(2, "TBLOCK: missing tapemarks\n");
- PRINT_ERR("TBLOCK: Refusing to open tape with missing"
- " end of file marks.\n");
+ dev_warn(&device->cdev->dev, "Opening the tape failed because"
+ " of missing end-of-file marks\n");
rc = -EPERM;
goto put_device;
}
@@ -452,7 +452,6 @@ tapeblock_ioctl(
rc = -EINVAL;
break;
default:
- PRINT_WARN("invalid ioctl 0x%x\n", command);
rc = -EINVAL;
}
@@ -474,7 +473,6 @@ tapeblock_init(void)
if (tapeblock_major == 0)
tapeblock_major = rc;
- PRINT_INFO("tape gets major %d for block device\n", tapeblock_major);
return 0;
}
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index be0ce2215c8d..31566c55adfe 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -24,8 +24,6 @@
#include "tape_std.h"
#include "tape_class.h"
-#define PRINTK_HEADER "TAPE_CHAR: "
-
#define TAPECHAR_MAJOR 0 /* get dynamic major */
/*
@@ -102,8 +100,6 @@ tapechar_check_idalbuffer(struct tape_device *device, size_t block_size)
if (block_size > MAX_BLOCKSIZE) {
DBF_EVENT(3, "Invalid blocksize (%zd > %d)\n",
block_size, MAX_BLOCKSIZE);
- PRINT_ERR("Invalid blocksize (%zd> %d)\n",
- block_size, MAX_BLOCKSIZE);
return -EINVAL;
}
@@ -485,7 +481,6 @@ tapechar_init (void)
return -1;
tapechar_major = MAJOR(dev);
- PRINT_INFO("tape gets major %d for character devices\n", MAJOR(dev));
return 0;
}
@@ -496,7 +491,5 @@ tapechar_init (void)
void
tapechar_exit(void)
{
- PRINT_INFO("tape releases major %d for character devices\n",
- tapechar_major);
unregister_chrdev_region(MKDEV(tapechar_major, 0), 256);
}
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index f9bb51fa7f5b..08c09d3503cf 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -11,6 +11,7 @@
* Stefan Bader <shbader@de.ibm.com>
*/
+#define KMSG_COMPONENT "tape"
#include <linux/module.h>
#include <linux/init.h> // for kernel parameters
#include <linux/kmod.h> // for requesting modules
@@ -25,7 +26,6 @@
#include "tape.h"
#include "tape_std.h"
-#define PRINTK_HEADER "TAPE_CORE: "
#define LONG_BUSY_TIMEOUT 180 /* seconds */
static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *);
@@ -214,13 +214,13 @@ tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
switch(newstate){
case MS_UNLOADED:
device->tape_generic_status |= GMT_DR_OPEN(~0);
- PRINT_INFO("(%s): Tape is unloaded\n",
- dev_name(&device->cdev->dev));
+ dev_info(&device->cdev->dev, "The tape cartridge has been "
+ "successfully unloaded\n");
break;
case MS_LOADED:
device->tape_generic_status &= ~GMT_DR_OPEN(~0);
- PRINT_INFO("(%s): Tape has been mounted\n",
- dev_name(&device->cdev->dev));
+ dev_info(&device->cdev->dev, "A tape cartridge has been "
+ "mounted\n");
break;
default:
// print nothing
@@ -333,7 +333,6 @@ tape_generic_online(struct tape_device *device,
/* Let the discipline have a go at the device. */
device->discipline = discipline;
if (!try_module_get(discipline->owner)) {
- PRINT_ERR("Cannot get module. Module gone.\n");
return -EINVAL;
}
@@ -391,7 +390,6 @@ int
tape_generic_offline(struct tape_device *device)
{
if (!device) {
- PRINT_ERR("tape_generic_offline: no such device\n");
return -ENODEV;
}
@@ -413,9 +411,6 @@ tape_generic_offline(struct tape_device *device)
DBF_EVENT(3, "(%08x): Set offline failed "
"- drive in use.\n",
device->cdev_id);
- PRINT_WARN("(%s): Set offline failed "
- "- drive in use.\n",
- dev_name(&device->cdev->dev));
spin_unlock_irq(get_ccwdev_lock(device->cdev));
return -EBUSY;
}
@@ -435,14 +430,11 @@ tape_alloc_device(void)
device = kzalloc(sizeof(struct tape_device), GFP_KERNEL);
if (device == NULL) {
DBF_EXCEPTION(2, "ti:no mem\n");
- PRINT_INFO ("can't allocate memory for "
- "tape info structure\n");
return ERR_PTR(-ENOMEM);
}
device->modeset_byte = kmalloc(1, GFP_KERNEL | GFP_DMA);
if (device->modeset_byte == NULL) {
DBF_EXCEPTION(2, "ti:no mem\n");
- PRINT_INFO("can't allocate memory for modeset byte\n");
kfree(device);
return ERR_PTR(-ENOMEM);
}
@@ -490,7 +482,6 @@ tape_put_device(struct tape_device *device)
} else {
if (remain < 0) {
DBF_EVENT(4, "put device without reference\n");
- PRINT_ERR("put device without reference\n");
} else {
DBF_EVENT(4, "tape_free_device(%p)\n", device);
kfree(device->modeset_byte);
@@ -538,8 +529,6 @@ tape_generic_probe(struct ccw_device *cdev)
ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
if (ret) {
tape_put_device(device);
- PRINT_ERR("probe failed for tape device %s\n",
- dev_name(&cdev->dev));
return ret;
}
cdev->dev.driver_data = device;
@@ -547,7 +536,6 @@ tape_generic_probe(struct ccw_device *cdev)
device->cdev = cdev;
ccw_device_get_id(cdev, &dev_id);
device->cdev_id = devid_to_int(&dev_id);
- PRINT_INFO("tape device %s found\n", dev_name(&cdev->dev));
return ret;
}
@@ -584,7 +572,6 @@ tape_generic_remove(struct ccw_device *cdev)
device = cdev->dev.driver_data;
if (!device) {
- PRINT_ERR("No device pointer in tape_generic_remove!\n");
return;
}
DBF_LH(3, "(%08x): tape_generic_remove(%p)\n", device->cdev_id, cdev);
@@ -615,10 +602,8 @@ tape_generic_remove(struct ccw_device *cdev)
*/
DBF_EVENT(3, "(%08x): Drive in use vanished!\n",
device->cdev_id);
- PRINT_WARN("(%s): Drive in use vanished - "
- "expect trouble!\n",
- dev_name(&device->cdev->dev));
- PRINT_WARN("State was %i\n", device->tape_state);
+ dev_warn(&device->cdev->dev, "A tape unit was detached"
+ " while in use\n");
tape_state_set(device, TS_NOT_OPER);
__tape_discard_requests(device);
spin_unlock_irq(get_ccwdev_lock(device->cdev));
@@ -639,8 +624,7 @@ tape_alloc_request(int cplength, int datasize)
{
struct tape_request *request;
- if (datasize > PAGE_SIZE || (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
- BUG();
+ BUG_ON(datasize > PAGE_SIZE || (cplength*sizeof(struct ccw1)) > PAGE_SIZE);
DBF_LH(6, "tape_alloc_request(%d, %d)\n", cplength, datasize);
@@ -797,8 +781,7 @@ static void tape_long_busy_timeout(unsigned long data)
device = (struct tape_device *) data;
spin_lock_irq(get_ccwdev_lock(device->cdev));
request = list_entry(device->req_queue.next, struct tape_request, list);
- if (request->status != TAPE_REQUEST_LONG_BUSY)
- BUG();
+ BUG_ON(request->status != TAPE_REQUEST_LONG_BUSY);
DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id);
__tape_start_next_request(device);
device->lb_timeout.data = (unsigned long) tape_put_device(device);
@@ -830,30 +813,6 @@ __tape_end_request(
}
/*
- * Write sense data to console/dbf
- */
-void
-tape_dump_sense(struct tape_device* device, struct tape_request *request,
- struct irb *irb)
-{
- unsigned int *sptr;
-
- PRINT_INFO("-------------------------------------------------\n");
- PRINT_INFO("DSTAT : %02x CSTAT: %02x CPA: %04x\n",
- irb->scsw.cmd.dstat, irb->scsw.cmd.cstat, irb->scsw.cmd.cpa);
- PRINT_INFO("DEVICE: %s\n", dev_name(&device->cdev->dev));
- if (request != NULL)
- PRINT_INFO("OP : %s\n", tape_op_verbose[request->op]);
-
- sptr = (unsigned int *) irb->ecw;
- PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
- sptr[0], sptr[1], sptr[2], sptr[3]);
- PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
- sptr[4], sptr[5], sptr[6], sptr[7]);
- PRINT_INFO("--------------------------------------------------\n");
-}
-
-/*
* Write sense data to dbf
*/
void
@@ -1051,8 +1010,6 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
device = (struct tape_device *) cdev->dev.driver_data;
if (device == NULL) {
- PRINT_ERR("could not get device structure for %s "
- "in interrupt\n", dev_name(&cdev->dev));
return;
}
request = (struct tape_request *) intparm;
@@ -1064,13 +1021,13 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
/* FIXME: What to do with the request? */
switch (PTR_ERR(irb)) {
case -ETIMEDOUT:
- PRINT_WARN("(%s): Request timed out\n",
+ DBF_LH(1, "(%s): Request timed out\n",
dev_name(&cdev->dev));
case -EIO:
__tape_end_request(device, request, -EIO);
break;
default:
- PRINT_ERR("(%s): Unexpected i/o error %li\n",
+ DBF_LH(1, "(%s): Unexpected i/o error %li\n",
dev_name(&cdev->dev),
PTR_ERR(irb));
}
@@ -1182,8 +1139,6 @@ __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
default:
if (rc > 0) {
DBF_EVENT(6, "xunknownrc\n");
- PRINT_ERR("Invalid return code from discipline "
- "interrupt function.\n");
__tape_end_request(device, request, -EIO);
} else {
__tape_end_request(device, request, rc);
@@ -1323,7 +1278,6 @@ EXPORT_SYMBOL(tape_state_set);
EXPORT_SYMBOL(tape_med_state_set);
EXPORT_SYMBOL(tape_alloc_request);
EXPORT_SYMBOL(tape_free_request);
-EXPORT_SYMBOL(tape_dump_sense);
EXPORT_SYMBOL(tape_dump_sense_dbf);
EXPORT_SYMBOL(tape_do_io);
EXPORT_SYMBOL(tape_do_io_async);
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c
index 8a376af926a7..202f42132939 100644
--- a/drivers/s390/char/tape_proc.c
+++ b/drivers/s390/char/tape_proc.c
@@ -20,8 +20,6 @@
#include "tape.h"
-#define PRINTK_HEADER "TAPE_PROC: "
-
static const char *tape_med_st_verbose[MS_SIZE] =
{
[MS_UNKNOWN] = "UNKNOWN ",
@@ -128,7 +126,6 @@ tape_proc_init(void)
proc_create("tapedevices", S_IFREG | S_IRUGO | S_IWUSR, NULL,
&tape_proc_ops);
if (tape_proc_devices == NULL) {
- PRINT_WARN("tape: Cannot register procfs entry tapedevices\n");
return;
}
}
diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c
index 5bd573d144d6..1a9420ba518d 100644
--- a/drivers/s390/char/tape_std.c
+++ b/drivers/s390/char/tape_std.c
@@ -26,8 +26,6 @@
#include "tape.h"
#include "tape_std.h"
-#define PRINTK_HEADER "TAPE_STD: "
-
/*
* tape_std_assign
*/
@@ -39,16 +37,15 @@ tape_std_assign_timeout(unsigned long data)
int rc;
request = (struct tape_request *) data;
- if ((device = request->device) == NULL)
- BUG();
+ device = request->device;
+ BUG_ON(!device);
DBF_EVENT(3, "%08x: Assignment timeout. Device busy.\n",
device->cdev_id);
rc = tape_cancel_io(device, request);
if(rc)
- PRINT_ERR("(%s): Assign timeout: Cancel failed with rc = %i\n",
+ DBF_EVENT(3, "(%s): Assign timeout: Cancel failed with rc = %i\n",
dev_name(&device->cdev->dev), rc);
-
}
int
@@ -82,8 +79,6 @@ tape_std_assign(struct tape_device *device)
del_timer(&timeout);
if (rc != 0) {
- PRINT_WARN("%s: assign failed - device might be busy\n",
- dev_name(&device->cdev->dev));
DBF_EVENT(3, "%08x: assign failed - device might be busy\n",
device->cdev_id);
} else {
@@ -105,8 +100,6 @@ tape_std_unassign (struct tape_device *device)
if (device->tape_state == TS_NOT_OPER) {
DBF_EVENT(3, "(%08x): Can't unassign device\n",
device->cdev_id);
- PRINT_WARN("(%s): Can't unassign device - device gone\n",
- dev_name(&device->cdev->dev));
return -EIO;
}
@@ -120,8 +113,6 @@ tape_std_unassign (struct tape_device *device)
if ((rc = tape_do_io(device, request)) != 0) {
DBF_EVENT(3, "%08x: Unassign failed\n", device->cdev_id);
- PRINT_WARN("%s: Unassign failed\n",
- dev_name(&device->cdev->dev));
} else {
DBF_EVENT(3, "%08x: Tape unassigned\n", device->cdev_id);
}
@@ -242,8 +233,6 @@ tape_std_mtsetblk(struct tape_device *device, int count)
if (count > MAX_BLOCKSIZE) {
DBF_EVENT(3, "Invalid block size (%d > %d) given.\n",
count, MAX_BLOCKSIZE);
- PRINT_ERR("Invalid block size (%d > %d) given.\n",
- count, MAX_BLOCKSIZE);
return -EINVAL;
}
@@ -633,14 +622,6 @@ tape_std_mtcompression(struct tape_device *device, int mt_count)
if (mt_count < 0 || mt_count > 1) {
DBF_EXCEPTION(6, "xcom parm\n");
- if (*device->modeset_byte & 0x08)
- PRINT_INFO("(%s) Compression is currently on\n",
- dev_name(&device->cdev->dev));
- else
- PRINT_INFO("(%s) Compression is currently off\n",
- dev_name(&device->cdev->dev));
- PRINT_INFO("Use 1 to switch compression on, 0 to "
- "switch it off\n");
return -EINVAL;
}
request = tape_alloc_request(2, 0);
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index eefc6611412e..1bbae433fbd8 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -5,7 +5,7 @@
*
* For more information please refer to Documentation/s390/zfcpdump.txt
*
- * Copyright IBM Corp. 2003,2007
+ * Copyright IBM Corp. 2003,2008
* Author(s): Michael Holzheu
*/
@@ -24,6 +24,7 @@
#include <asm/debug.h>
#include <asm/processor.h>
#include <asm/irqflags.h>
+#include <asm/checksum.h>
#include "sclp.h"
#define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x)
@@ -48,12 +49,19 @@ struct sys_info {
union save_area lc_mask;
};
+struct ipib_info {
+ unsigned long ipib;
+ u32 checksum;
+} __attribute__((packed));
+
static struct sys_info sys_info;
static struct debug_info *zcore_dbf;
static int hsa_available;
static struct dentry *zcore_dir;
static struct dentry *zcore_file;
static struct dentry *zcore_memmap_file;
+static struct dentry *zcore_reipl_file;
+static struct ipl_parameter_block *ipl_block;
/*
* Copy memory from HSA to kernel or user memory (not reentrant):
@@ -527,6 +535,33 @@ static const struct file_operations zcore_memmap_fops = {
.release = zcore_memmap_release,
};
+static ssize_t zcore_reipl_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ if (ipl_block) {
+ diag308(DIAG308_SET, ipl_block);
+ diag308(DIAG308_IPL, NULL);
+ }
+ return count;
+}
+
+static int zcore_reipl_open(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static int zcore_reipl_release(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static const struct file_operations zcore_reipl_fops = {
+ .owner = THIS_MODULE,
+ .write = zcore_reipl_write,
+ .open = zcore_reipl_open,
+ .release = zcore_reipl_release,
+};
+
static void __init set_s390_lc_mask(union save_area *map)
{
@@ -645,6 +680,40 @@ static int __init zcore_header_init(int arch, struct zcore_header *hdr)
return 0;
}
+/*
+ * Provide IPL parameter information block from either HSA or memory
+ * for future reipl
+ */
+static int __init zcore_reipl_init(void)
+{
+ struct ipib_info ipib_info;
+ int rc;
+
+ rc = memcpy_hsa_kernel(&ipib_info, __LC_DUMP_REIPL, sizeof(ipib_info));
+ if (rc)
+ return rc;
+ if (ipib_info.ipib == 0)
+ return 0;
+ ipl_block = (void *) __get_free_page(GFP_KERNEL);
+ if (!ipl_block)
+ return -ENOMEM;
+ if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE)
+ rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
+ else
+ rc = memcpy_real(ipl_block, ipib_info.ipib, PAGE_SIZE);
+ if (rc) {
+ free_page((unsigned long) ipl_block);
+ return rc;
+ }
+ if (csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
+ ipib_info.checksum) {
+ TRACE("Checksum does not match\n");
+ free_page((unsigned long) ipl_block);
+ ipl_block = NULL;
+ }
+ return 0;
+}
+
static int __init zcore_init(void)
{
unsigned char arch;
@@ -690,6 +759,10 @@ static int __init zcore_init(void)
if (rc)
goto fail;
+ rc = zcore_reipl_init();
+ if (rc)
+ goto fail;
+
zcore_dir = debugfs_create_dir("zcore" , NULL);
if (!zcore_dir) {
rc = -ENOMEM;
@@ -707,9 +780,17 @@ static int __init zcore_init(void)
rc = -ENOMEM;
goto fail_file;
}
+ zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir,
+ NULL, &zcore_reipl_fops);
+ if (!zcore_reipl_file) {
+ rc = -ENOMEM;
+ goto fail_memmap_file;
+ }
hsa_available = 1;
return 0;
+fail_memmap_file:
+ debugfs_remove(zcore_memmap_file);
fail_file:
debugfs_remove(zcore_file);
fail_dir:
@@ -723,10 +804,15 @@ static void __exit zcore_exit(void)
{
debug_unregister(zcore_dbf);
sclp_sdias_exit();
+ free_page((unsigned long) ipl_block);
+ debugfs_remove(zcore_reipl_file);
+ debugfs_remove(zcore_memmap_file);
+ debugfs_remove(zcore_file);
+ debugfs_remove(zcore_dir);
diag308(DIAG308_REL_HSA, NULL);
}
-MODULE_AUTHOR("Copyright IBM Corp. 2003,2007");
+MODULE_AUTHOR("Copyright IBM Corp. 2003,2008");
MODULE_DESCRIPTION("zcore module for zfcpdump support");
MODULE_LICENSE("GPL");
diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile
index bd79bd165396..adb3dd301528 100644
--- a/drivers/s390/cio/Makefile
+++ b/drivers/s390/cio/Makefile
@@ -3,7 +3,7 @@
#
obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o scsw.o \
- fcx.o itcw.o
+ fcx.o itcw.o crw.o
ccw_device-objs += device.o device_fsm.o device_ops.o
ccw_device-objs += device_id.o device_pgid.o device_status.o
obj-y += ccw_device.o cmf.o
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c
index fe6cea15bbaf..65d2e769dfa1 100644
--- a/drivers/s390/cio/airq.c
+++ b/drivers/s390/cio/airq.c
@@ -34,8 +34,8 @@ struct airq_t {
void *drv_data;
};
-static union indicator_t indicators[MAX_ISC];
-static struct airq_t *airqs[MAX_ISC][NR_AIRQS];
+static union indicator_t indicators[MAX_ISC+1];
+static struct airq_t *airqs[MAX_ISC+1][NR_AIRQS];
static int register_airq(struct airq_t *airq, u8 isc)
{
@@ -133,6 +133,8 @@ void do_adapter_IO(u8 isc)
while (word) {
if (word & INDICATOR_MASK) {
airq = airqs[isc][i];
+ /* Make sure gcc reads from airqs only once. */
+ barrier();
if (likely(airq))
airq->handler(&indicators[isc].byte[i],
airq->drv_data);
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index fe00be3675cd..6565f027791e 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -336,8 +336,7 @@ cio_ignore_write(struct file *file, const char __user *user_buf,
size_t user_len, loff_t *offset)
{
char *buf;
- size_t i;
- ssize_t rc, ret;
+ ssize_t rc, ret, i;
if (*offset)
return -EINVAL;
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 918e6fce2573..22ce765d537e 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -104,8 +104,9 @@ ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const
rc = device_schedule_callback(dev, ccwgroup_ungroup_callback);
out:
if (rc) {
- /* Release onoff "lock" when ungrouping failed. */
- atomic_set(&gdev->onoff, 0);
+ if (rc != -EAGAIN)
+ /* Release onoff "lock" when ungrouping failed. */
+ atomic_set(&gdev->onoff, 0);
return rc;
}
return count;
@@ -314,16 +315,32 @@ error:
}
EXPORT_SYMBOL(ccwgroup_create_from_string);
-static int __init
-init_ccwgroup (void)
+static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
+ void *data);
+
+static struct notifier_block ccwgroup_nb = {
+ .notifier_call = ccwgroup_notifier
+};
+
+static int __init init_ccwgroup(void)
{
- return bus_register (&ccwgroup_bus_type);
+ int ret;
+
+ ret = bus_register(&ccwgroup_bus_type);
+ if (ret)
+ return ret;
+
+ ret = bus_register_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
+ if (ret)
+ bus_unregister(&ccwgroup_bus_type);
+
+ return ret;
}
-static void __exit
-cleanup_ccwgroup (void)
+static void __exit cleanup_ccwgroup(void)
{
- bus_unregister (&ccwgroup_bus_type);
+ bus_unregister_notifier(&ccwgroup_bus_type, &ccwgroup_nb);
+ bus_unregister(&ccwgroup_bus_type);
}
module_init(init_ccwgroup);
@@ -391,27 +408,28 @@ ccwgroup_online_store (struct device *dev, struct device_attribute *attr, const
unsigned long value;
int ret;
- gdev = to_ccwgroupdev(dev);
if (!dev->driver)
- return count;
+ return -ENODEV;
+
+ gdev = to_ccwgroupdev(dev);
+ gdrv = to_ccwgroupdrv(dev->driver);
- gdrv = to_ccwgroupdrv (gdev->dev.driver);
if (!try_module_get(gdrv->owner))
return -EINVAL;
ret = strict_strtoul(buf, 0, &value);
if (ret)
goto out;
- ret = count;
+
if (value == 1)
- ccwgroup_set_online(gdev);
+ ret = ccwgroup_set_online(gdev);
else if (value == 0)
- ccwgroup_set_offline(gdev);
+ ret = ccwgroup_set_offline(gdev);
else
ret = -EINVAL;
out:
module_put(gdrv->owner);
- return ret;
+ return (ret == 0) ? count : ret;
}
static ssize_t
@@ -453,13 +471,18 @@ ccwgroup_remove (struct device *dev)
struct ccwgroup_device *gdev;
struct ccwgroup_driver *gdrv;
+ device_remove_file(dev, &dev_attr_online);
+ device_remove_file(dev, &dev_attr_ungroup);
+
+ if (!dev->driver)
+ return 0;
+
gdev = to_ccwgroupdev(dev);
gdrv = to_ccwgroupdrv(dev->driver);
- device_remove_file(dev, &dev_attr_online);
-
- if (gdrv && gdrv->remove)
+ if (gdrv->remove)
gdrv->remove(gdev);
+
return 0;
}
@@ -468,9 +491,13 @@ static void ccwgroup_shutdown(struct device *dev)
struct ccwgroup_device *gdev;
struct ccwgroup_driver *gdrv;
+ if (!dev->driver)
+ return;
+
gdev = to_ccwgroupdev(dev);
gdrv = to_ccwgroupdrv(dev->driver);
- if (gdrv && gdrv->shutdown)
+
+ if (gdrv->shutdown)
gdrv->shutdown(gdev);
}
@@ -483,6 +510,19 @@ static struct bus_type ccwgroup_bus_type = {
.shutdown = ccwgroup_shutdown,
};
+
+static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ struct device *dev = data;
+
+ if (action == BUS_NOTIFY_UNBIND_DRIVER)
+ device_schedule_callback(dev, ccwgroup_ungroup_callback);
+
+ return NOTIFY_OK;
+}
+
+
/**
* ccwgroup_driver_register() - register a ccw group driver
* @cdriver: driver to be registered
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 1246f61a5338..3e5f304ad88f 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -17,8 +17,8 @@
#include <linux/errno.h>
#include <asm/chpid.h>
#include <asm/sclp.h>
+#include <asm/crw.h>
-#include "../s390mach.h"
#include "cio.h"
#include "css.h"
#include "ioasm.h"
@@ -706,12 +706,12 @@ static int __init chp_init(void)
struct chp_id chpid;
int ret;
- ret = s390_register_crw_handler(CRW_RSC_CPATH, chp_process_crw);
+ ret = crw_register_handler(CRW_RSC_CPATH, chp_process_crw);
if (ret)
return ret;
chp_wq = create_singlethread_workqueue("cio_chp");
if (!chp_wq) {
- s390_unregister_crw_handler(CRW_RSC_CPATH);
+ crw_unregister_handler(CRW_RSC_CPATH);
return -ENOMEM;
}
INIT_WORK(&cfg_work, cfg_func);
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index ebab6ea4659b..883f16f96f22 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -19,8 +19,8 @@
#include <asm/cio.h>
#include <asm/chpid.h>
#include <asm/chsc.h>
+#include <asm/crw.h>
-#include "../s390mach.h"
#include "css.h"
#include "cio.h"
#include "cio_debug.h"
@@ -589,6 +589,7 @@ __chsc_do_secm(struct channel_subsystem *css, int enable, void *page)
case 0x0102:
case 0x0103:
ret = -EINVAL;
+ break;
default:
ret = chsc_error_from_response(secm_area->response.code);
}
@@ -820,7 +821,7 @@ int __init chsc_alloc_sei_area(void)
"chsc machine checks!\n");
return -ENOMEM;
}
- ret = s390_register_crw_handler(CRW_RSC_CSS, chsc_process_crw);
+ ret = crw_register_handler(CRW_RSC_CSS, chsc_process_crw);
if (ret)
kfree(sei_page);
return ret;
@@ -828,7 +829,7 @@ int __init chsc_alloc_sei_area(void)
void __init chsc_free_sei_area(void)
{
- s390_unregister_crw_handler(CRW_RSC_CSS);
+ crw_unregister_handler(CRW_RSC_CSS);
kfree(sei_page);
}
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index 0a2f2edafc03..93eca1731b81 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -84,8 +84,8 @@ static int chsc_subchannel_probe(struct subchannel *sch)
kfree(private);
} else {
sch->private = private;
- if (sch->dev.uevent_suppress) {
- sch->dev.uevent_suppress = 0;
+ if (dev_get_uevent_suppress(&sch->dev)) {
+ dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
}
}
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 659f8a791656..2aebb9823044 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -30,6 +30,8 @@
#include <asm/isc.h>
#include <asm/cpu.h>
#include <asm/fcx.h>
+#include <asm/nmi.h>
+#include <asm/crw.h>
#include "cio.h"
#include "css.h"
#include "chsc.h"
@@ -38,7 +40,6 @@
#include "blacklist.h"
#include "cio_debug.h"
#include "chp.h"
-#include "../s390mach.h"
debug_info_t *cio_debug_msg_id;
debug_info_t *cio_debug_trace_id;
@@ -471,6 +472,7 @@ EXPORT_SYMBOL_GPL(cio_enable_subchannel);
int cio_disable_subchannel(struct subchannel *sch)
{
char dbf_txt[15];
+ int retry;
int ret;
CIO_TRACE_EVENT (2, "dissch");
@@ -481,16 +483,17 @@ int cio_disable_subchannel(struct subchannel *sch)
if (cio_update_schib(sch))
return -ENODEV;
- if (scsw_actl(&sch->schib.scsw) != 0)
- /*
- * the disable function must not be called while there are
- * requests pending for completion !
- */
- return -EBUSY;
-
sch->config.ena = 0;
- ret = cio_commit_config(sch);
+ for (retry = 0; retry < 3; retry++) {
+ ret = cio_commit_config(sch);
+ if (ret == -EBUSY) {
+ struct irb irb;
+ if (tsch(sch->schid, &irb) != 0)
+ break;
+ } else
+ break;
+ }
sprintf (dbf_txt, "ret:%d", ret);
CIO_TRACE_EVENT (2, dbf_txt);
return ret;
diff --git a/drivers/s390/cio/crw.c b/drivers/s390/cio/crw.c
new file mode 100644
index 000000000000..d157665d0e76
--- /dev/null
+++ b/drivers/s390/cio/crw.c
@@ -0,0 +1,159 @@
+/*
+ * Channel report handling code
+ *
+ * Copyright IBM Corp. 2000,2009
+ * Author(s): Ingo Adlung <adlung@de.ibm.com>,
+ * Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ * Cornelia Huck <cornelia.huck@de.ibm.com>,
+ * Heiko Carstens <heiko.carstens@de.ibm.com>,
+ */
+
+#include <linux/semaphore.h>
+#include <linux/mutex.h>
+#include <linux/kthread.h>
+#include <linux/init.h>
+#include <asm/crw.h>
+
+static struct semaphore crw_semaphore;
+static DEFINE_MUTEX(crw_handler_mutex);
+static crw_handler_t crw_handlers[NR_RSCS];
+
+/**
+ * crw_register_handler() - register a channel report word handler
+ * @rsc: reporting source code to handle
+ * @handler: handler to be registered
+ *
+ * Returns %0 on success and a negative error value otherwise.
+ */
+int crw_register_handler(int rsc, crw_handler_t handler)
+{
+ int rc = 0;
+
+ if ((rsc < 0) || (rsc >= NR_RSCS))
+ return -EINVAL;
+ mutex_lock(&crw_handler_mutex);
+ if (crw_handlers[rsc])
+ rc = -EBUSY;
+ else
+ crw_handlers[rsc] = handler;
+ mutex_unlock(&crw_handler_mutex);
+ return rc;
+}
+
+/**
+ * crw_unregister_handler() - unregister a channel report word handler
+ * @rsc: reporting source code to handle
+ */
+void crw_unregister_handler(int rsc)
+{
+ if ((rsc < 0) || (rsc >= NR_RSCS))
+ return;
+ mutex_lock(&crw_handler_mutex);
+ crw_handlers[rsc] = NULL;
+ mutex_unlock(&crw_handler_mutex);
+}
+
+/*
+ * Retrieve CRWs and call function to handle event.
+ */
+static int crw_collect_info(void *unused)
+{
+ struct crw crw[2];
+ int ccode;
+ unsigned int chain;
+ int ignore;
+
+repeat:
+ ignore = down_interruptible(&crw_semaphore);
+ chain = 0;
+ while (1) {
+ crw_handler_t handler;
+
+ if (unlikely(chain > 1)) {
+ struct crw tmp_crw;
+
+ printk(KERN_WARNING"%s: Code does not support more "
+ "than two chained crws; please report to "
+ "linux390@de.ibm.com!\n", __func__);
+ ccode = stcrw(&tmp_crw);
+ printk(KERN_WARNING"%s: crw reports slct=%d, oflw=%d, "
+ "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
+ __func__, tmp_crw.slct, tmp_crw.oflw,
+ tmp_crw.chn, tmp_crw.rsc, tmp_crw.anc,
+ tmp_crw.erc, tmp_crw.rsid);
+ printk(KERN_WARNING"%s: This was crw number %x in the "
+ "chain\n", __func__, chain);
+ if (ccode != 0)
+ break;
+ chain = tmp_crw.chn ? chain + 1 : 0;
+ continue;
+ }
+ ccode = stcrw(&crw[chain]);
+ if (ccode != 0)
+ break;
+ printk(KERN_DEBUG "crw_info : CRW reports slct=%d, oflw=%d, "
+ "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
+ crw[chain].slct, crw[chain].oflw, crw[chain].chn,
+ crw[chain].rsc, crw[chain].anc, crw[chain].erc,
+ crw[chain].rsid);
+ /* Check for overflows. */
+ if (crw[chain].oflw) {
+ int i;
+
+ pr_debug("%s: crw overflow detected!\n", __func__);
+ mutex_lock(&crw_handler_mutex);
+ for (i = 0; i < NR_RSCS; i++) {
+ if (crw_handlers[i])
+ crw_handlers[i](NULL, NULL, 1);
+ }
+ mutex_unlock(&crw_handler_mutex);
+ chain = 0;
+ continue;
+ }
+ if (crw[0].chn && !chain) {
+ chain++;
+ continue;
+ }
+ mutex_lock(&crw_handler_mutex);
+ handler = crw_handlers[crw[chain].rsc];
+ if (handler)
+ handler(&crw[0], chain ? &crw[1] : NULL, 0);
+ mutex_unlock(&crw_handler_mutex);
+ /* chain is always 0 or 1 here. */
+ chain = crw[chain].chn ? chain + 1 : 0;
+ }
+ goto repeat;
+ return 0;
+}
+
+void crw_handle_channel_report(void)
+{
+ up(&crw_semaphore);
+}
+
+/*
+ * Separate initcall needed for semaphore initialization since
+ * crw_handle_channel_report might be called before crw_machine_check_init.
+ */
+static int __init crw_init_semaphore(void)
+{
+ init_MUTEX_LOCKED(&crw_semaphore);
+ return 0;
+}
+pure_initcall(crw_init_semaphore);
+
+/*
+ * Machine checks for the channel subsystem must be enabled
+ * after the channel subsystem is initialized
+ */
+static int __init crw_machine_check_init(void)
+{
+ struct task_struct *task;
+
+ task = kthread_run(crw_collect_info, NULL, "kmcheck");
+ if (IS_ERR(task))
+ return PTR_ERR(task);
+ ctl_set_bit(14, 28); /* enable channel report MCH */
+ return 0;
+}
+device_initcall(crw_machine_check_init);
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 8019288bc6de..0085d8901792 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -18,8 +18,8 @@
#include <linux/list.h>
#include <linux/reboot.h>
#include <asm/isc.h>
+#include <asm/crw.h>
-#include "../s390mach.h"
#include "css.h"
#include "cio.h"
#include "cio_debug.h"
@@ -83,6 +83,25 @@ static int call_fn_unknown_sch(struct subchannel_id schid, void *data)
return rc;
}
+static int call_fn_all_sch(struct subchannel_id schid, void *data)
+{
+ struct cb_data *cb = data;
+ struct subchannel *sch;
+ int rc = 0;
+
+ sch = get_subchannel_by_schid(schid);
+ if (sch) {
+ if (cb->fn_known_sch)
+ rc = cb->fn_known_sch(sch, cb->data);
+ put_device(&sch->dev);
+ } else {
+ if (cb->fn_unknown_sch)
+ rc = cb->fn_unknown_sch(schid, cb->data);
+ }
+
+ return rc;
+}
+
int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
int (*fn_unknown)(struct subchannel_id,
void *), void *data)
@@ -90,13 +109,17 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
struct cb_data cb;
int rc;
- cb.set = idset_sch_new();
- if (!cb.set)
- return -ENOMEM;
- idset_fill(cb.set);
cb.data = data;
cb.fn_known_sch = fn_known;
cb.fn_unknown_sch = fn_unknown;
+
+ cb.set = idset_sch_new();
+ if (!cb.set)
+ /* fall back to brute force scanning in case of oom */
+ return for_each_subchannel(call_fn_all_sch, &cb);
+
+ idset_fill(cb.set);
+
/* Process registered subchannels. */
rc = bus_for_each_dev(&css_bus_type, NULL, &cb, call_fn_known_sch);
if (rc)
@@ -272,7 +295,7 @@ static int css_register_subchannel(struct subchannel *sch)
* the subchannel driver can decide itself when it wants to inform
* userspace of its existence.
*/
- sch->dev.uevent_suppress = 1;
+ dev_set_uevent_suppress(&sch->dev, 1);
css_update_ssd_info(sch);
/* make it known to the system */
ret = css_sch_device_register(sch);
@@ -287,7 +310,7 @@ static int css_register_subchannel(struct subchannel *sch)
* a fitting driver module may be loaded based on the
* modalias.
*/
- sch->dev.uevent_suppress = 0;
+ dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
}
return ret;
@@ -510,6 +533,17 @@ static int reprobe_subchannel(struct subchannel_id schid, void *data)
return ret;
}
+static void reprobe_after_idle(struct work_struct *unused)
+{
+ /* Make sure initial subchannel scan is done. */
+ wait_event(ccw_device_init_wq,
+ atomic_read(&ccw_device_init_count) == 0);
+ if (need_reprobe)
+ css_schedule_reprobe();
+}
+
+static DECLARE_WORK(reprobe_idle_work, reprobe_after_idle);
+
/* Work function used to reprobe all unregistered subchannels. */
static void reprobe_all(struct work_struct *unused)
{
@@ -517,10 +551,12 @@ static void reprobe_all(struct work_struct *unused)
CIO_MSG_EVENT(4, "reprobe start\n");
- need_reprobe = 0;
/* Make sure initial subchannel scan is done. */
- wait_event(ccw_device_init_wq,
- atomic_read(&ccw_device_init_count) == 0);
+ if (atomic_read(&ccw_device_init_count) != 0) {
+ queue_work(ccw_device_work, &reprobe_idle_work);
+ return;
+ }
+ need_reprobe = 0;
ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL);
CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,
@@ -619,7 +655,7 @@ css_generate_pgid(struct channel_subsystem *css, u32 tod_high)
css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid;
} else {
#ifdef CONFIG_SMP
- css->global_pgid.pgid_high.cpu_addr = hard_smp_processor_id();
+ css->global_pgid.pgid_high.cpu_addr = stap();
#else
css->global_pgid.pgid_high.cpu_addr = 0;
#endif
@@ -765,7 +801,7 @@ init_channel_subsystem (void)
if (ret)
goto out;
- ret = s390_register_crw_handler(CRW_RSC_SCH, css_process_crw);
+ ret = crw_register_handler(CRW_RSC_SCH, css_process_crw);
if (ret)
goto out;
@@ -845,7 +881,7 @@ out_unregister:
out_bus:
bus_unregister(&css_bus_type);
out:
- s390_unregister_crw_handler(CRW_RSC_CSS);
+ crw_unregister_handler(CRW_RSC_CSS);
chsc_free_sei_area();
kfree(slow_subchannel_set);
pr_alert("The CSS device driver initialization failed with "
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 23d5752349b5..35441fa16be1 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -310,8 +310,6 @@ static void ccw_device_remove_orphan_cb(struct work_struct *work)
put_device(&cdev->dev);
}
-static void ccw_device_call_sch_unregister(struct work_struct *work);
-
static void
ccw_device_remove_disconnected(struct ccw_device *cdev)
{
@@ -335,11 +333,10 @@ ccw_device_remove_disconnected(struct ccw_device *cdev)
spin_unlock_irqrestore(cdev->ccwlock, flags);
PREPARE_WORK(&cdev->private->kick_work,
ccw_device_remove_orphan_cb);
+ queue_work(slow_path_wq, &cdev->private->kick_work);
} else
/* Deregister subchannel, which will kill the ccw device. */
- PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_call_sch_unregister);
- queue_work(slow_path_wq, &cdev->private->kick_work);
+ ccw_device_schedule_sch_unregister(cdev);
}
/**
@@ -457,12 +454,13 @@ int ccw_device_set_online(struct ccw_device *cdev)
return (ret == 0) ? -ENODEV : ret;
}
-static void online_store_handle_offline(struct ccw_device *cdev)
+static int online_store_handle_offline(struct ccw_device *cdev)
{
if (cdev->private->state == DEV_STATE_DISCONNECTED)
ccw_device_remove_disconnected(cdev);
- else if (cdev->drv && cdev->drv->set_offline)
- ccw_device_set_offline(cdev);
+ else if (cdev->online && cdev->drv && cdev->drv->set_offline)
+ return ccw_device_set_offline(cdev);
+ return 0;
}
static int online_store_recog_and_online(struct ccw_device *cdev)
@@ -470,7 +468,7 @@ static int online_store_recog_and_online(struct ccw_device *cdev)
int ret;
/* Do device recognition, if needed. */
- if (cdev->id.cu_type == 0) {
+ if (cdev->private->state == DEV_STATE_BOXED) {
ret = ccw_device_recognition(cdev);
if (ret) {
CIO_MSG_EVENT(0, "Couldn't start recognition "
@@ -481,17 +479,21 @@ static int online_store_recog_and_online(struct ccw_device *cdev)
}
wait_event(cdev->private->wait_q,
cdev->private->flags.recog_done);
+ if (cdev->private->state != DEV_STATE_OFFLINE)
+ /* recognition failed */
+ return -EAGAIN;
}
if (cdev->drv && cdev->drv->set_online)
ccw_device_set_online(cdev);
return 0;
}
+
static int online_store_handle_online(struct ccw_device *cdev, int force)
{
int ret;
ret = online_store_recog_and_online(cdev);
- if (ret)
+ if (ret && !force)
return ret;
if (force && cdev->private->state == DEV_STATE_BOXED) {
ret = ccw_device_stlck(cdev);
@@ -499,7 +501,9 @@ static int online_store_handle_online(struct ccw_device *cdev, int force)
return ret;
if (cdev->id.cu_type == 0)
cdev->private->state = DEV_STATE_NOT_OPER;
- online_store_recog_and_online(cdev);
+ ret = online_store_recog_and_online(cdev);
+ if (ret)
+ return ret;
}
return 0;
}
@@ -511,7 +515,11 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr,
int force, ret;
unsigned long i;
- if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
+ if ((cdev->private->state != DEV_STATE_OFFLINE &&
+ cdev->private->state != DEV_STATE_ONLINE &&
+ cdev->private->state != DEV_STATE_BOXED &&
+ cdev->private->state != DEV_STATE_DISCONNECTED) ||
+ atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
return -EAGAIN;
if (cdev->drv && !try_module_get(cdev->drv->owner)) {
@@ -530,13 +538,10 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr,
goto out;
switch (i) {
case 0:
- online_store_handle_offline(cdev);
- ret = count;
+ ret = online_store_handle_offline(cdev);
break;
case 1:
ret = online_store_handle_online(cdev, force);
- if (!ret)
- ret = count;
break;
default:
ret = -EINVAL;
@@ -545,7 +550,7 @@ out:
if (cdev->drv)
module_put(cdev->drv->owner);
atomic_set(&cdev->private->onoff, 0);
- return ret;
+ return (ret < 0) ? ret : count;
}
static ssize_t
@@ -681,35 +686,22 @@ get_orphaned_ccwdev_by_dev_id(struct channel_subsystem *css,
return dev ? to_ccwdev(dev) : NULL;
}
-static void
-ccw_device_add_changed(struct work_struct *work)
-{
- struct ccw_device_private *priv;
- struct ccw_device *cdev;
-
- priv = container_of(work, struct ccw_device_private, kick_work);
- cdev = priv->cdev;
- if (device_add(&cdev->dev)) {
- put_device(&cdev->dev);
- return;
- }
- set_bit(1, &cdev->private->registered);
-}
-
-void ccw_device_do_unreg_rereg(struct work_struct *work)
+void ccw_device_do_unbind_bind(struct work_struct *work)
{
struct ccw_device_private *priv;
struct ccw_device *cdev;
struct subchannel *sch;
+ int ret;
priv = container_of(work, struct ccw_device_private, kick_work);
cdev = priv->cdev;
sch = to_subchannel(cdev->dev.parent);
- ccw_device_unregister(cdev);
- PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_add_changed);
- queue_work(ccw_device_work, &cdev->private->kick_work);
+ if (test_bit(1, &cdev->private->registered)) {
+ device_release_driver(&cdev->dev);
+ ret = device_attach(&cdev->dev);
+ WARN_ON(ret == -ENODEV);
+ }
}
static void
@@ -799,7 +791,7 @@ static void sch_attach_disconnected_device(struct subchannel *sch,
return;
other_sch = to_subchannel(cdev->dev.parent);
/* Note: device_move() changes cdev->dev.parent */
- ret = device_move(&cdev->dev, &sch->dev);
+ ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
if (ret) {
CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed "
"(ret=%d)!\n", cdev->private->dev_id.ssid,
@@ -830,7 +822,7 @@ static void sch_attach_orphaned_device(struct subchannel *sch,
* Try to move the ccw device to its new subchannel.
* Note: device_move() changes cdev->dev.parent
*/
- ret = device_move(&cdev->dev, &sch->dev);
+ ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
if (ret) {
CIO_MSG_EVENT(0, "Moving device 0.%x.%04x from orphanage "
"failed (ret=%d)!\n",
@@ -897,7 +889,8 @@ void ccw_device_move_to_orphanage(struct work_struct *work)
* ccw device can take its place on the subchannel.
* Note: device_move() changes cdev->dev.parent
*/
- ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev);
+ ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev,
+ DPM_ORDER_NONE);
if (ret) {
CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to orphanage failed "
"(ret=%d)!\n", cdev->private->dev_id.ssid,
@@ -981,7 +974,7 @@ io_subchannel_register(struct work_struct *work)
* Now we know this subchannel will stay, we can throw
* our delayed uevent.
*/
- sch->dev.uevent_suppress = 0;
+ dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
/* make it known to the system */
ret = ccw_device_register(cdev);
@@ -1028,33 +1021,35 @@ static void ccw_device_call_sch_unregister(struct work_struct *work)
put_device(&sch->dev);
}
+void ccw_device_schedule_sch_unregister(struct ccw_device *cdev)
+{
+ PREPARE_WORK(&cdev->private->kick_work,
+ ccw_device_call_sch_unregister);
+ queue_work(slow_path_wq, &cdev->private->kick_work);
+}
+
/*
* subchannel recognition done. Called from the state machine.
*/
void
io_subchannel_recog_done(struct ccw_device *cdev)
{
- struct subchannel *sch;
-
if (css_init_done == 0) {
cdev->private->flags.recog_done = 1;
return;
}
switch (cdev->private->state) {
+ case DEV_STATE_BOXED:
+ /* Device did not respond in time. */
case DEV_STATE_NOT_OPER:
cdev->private->flags.recog_done = 1;
/* Remove device found not operational. */
if (!get_device(&cdev->dev))
break;
- sch = to_subchannel(cdev->dev.parent);
- PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_call_sch_unregister);
- queue_work(slow_path_wq, &cdev->private->kick_work);
+ ccw_device_schedule_sch_unregister(cdev);
if (atomic_dec_and_test(&ccw_device_init_count))
wake_up(&ccw_device_init_wq);
break;
- case DEV_STATE_BOXED:
- /* Device did not respond in time. */
case DEV_STATE_OFFLINE:
/*
* We can't register the device in interrupt context so
@@ -1129,7 +1124,7 @@ static void ccw_device_move_to_sch(struct work_struct *work)
* Try to move the ccw device to its new subchannel.
* Note: device_move() changes cdev->dev.parent
*/
- rc = device_move(&cdev->dev, &sch->dev);
+ rc = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV);
mutex_unlock(&sch->reg_mutex);
if (rc) {
CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel "
@@ -1243,7 +1238,7 @@ static int io_subchannel_probe(struct subchannel *sch)
* the ccw_device and exit. This happens for all early
* devices, e.g. the console.
*/
- sch->dev.uevent_suppress = 0;
+ dev_set_uevent_suppress(&sch->dev, 0);
kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
cdev->dev.groups = ccwdev_attr_groups;
device_initialize(&cdev->dev);
@@ -1568,8 +1563,7 @@ static int purge_fn(struct device *dev, void *data)
goto out;
CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid,
priv->dev_id.devno);
- PREPARE_WORK(&cdev->private->kick_work, ccw_device_call_sch_unregister);
- queue_work(slow_path_wq, &cdev->private->kick_work);
+ ccw_device_schedule_sch_unregister(cdev);
out:
/* Abort loop in case of pending signal. */
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 0f2e63ea48de..f1cbbd94ad4e 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -80,13 +80,14 @@ void io_subchannel_init_config(struct subchannel *sch);
int ccw_device_cancel_halt_clear(struct ccw_device *);
-void ccw_device_do_unreg_rereg(struct work_struct *);
+void ccw_device_do_unbind_bind(struct work_struct *);
void ccw_device_move_to_orphanage(struct work_struct *);
int ccw_device_is_orphan(struct ccw_device *);
int ccw_device_recognition(struct ccw_device *);
int ccw_device_online(struct ccw_device *);
int ccw_device_offline(struct ccw_device *);
+void ccw_device_schedule_sch_unregister(struct ccw_device *);
int ccw_purge_blacklisted(void);
/* Function prototypes for device status and basic sense stuff. */
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 8df5eaafc5ab..e46049261561 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -194,7 +194,7 @@ ccw_device_handle_oper(struct ccw_device *cdev)
cdev->id.dev_type != cdev->private->senseid.dev_type ||
cdev->id.dev_model != cdev->private->senseid.dev_model) {
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_do_unreg_rereg);
+ ccw_device_do_unbind_bind);
queue_work(ccw_device_work, &cdev->private->kick_work);
return 0;
}
@@ -256,13 +256,12 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
old_lpm = 0;
if (sch->lpm != old_lpm)
__recover_lost_chpids(sch, old_lpm);
- if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
- if (state == DEV_STATE_NOT_OPER) {
- cdev->private->flags.recog_done = 1;
- cdev->private->state = DEV_STATE_DISCONNECTED;
- return;
- }
- /* Boxed devices don't need extra treatment. */
+ if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID &&
+ (state == DEV_STATE_NOT_OPER || state == DEV_STATE_BOXED)) {
+ cdev->private->flags.recog_done = 1;
+ cdev->private->state = DEV_STATE_DISCONNECTED;
+ wake_up(&cdev->private->wait_q);
+ return;
}
notify = 0;
same_dev = 0; /* Keep the compiler quiet... */
@@ -274,7 +273,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
sch->schid.ssid, sch->schid.sch_no);
break;
case DEV_STATE_OFFLINE:
- if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
+ if (cdev->online) {
same_dev = ccw_device_handle_oper(cdev);
notify = 1;
}
@@ -307,12 +306,17 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
" subchannel 0.%x.%04x\n",
cdev->private->dev_id.devno,
sch->schid.ssid, sch->schid.sch_no);
+ if (cdev->id.cu_type != 0) { /* device was recognized before */
+ cdev->private->flags.recog_done = 1;
+ cdev->private->state = DEV_STATE_BOXED;
+ wake_up(&cdev->private->wait_q);
+ return;
+ }
break;
}
cdev->private->state = state;
io_subchannel_recog_done(cdev);
- if (state != DEV_STATE_NOT_OPER)
- wake_up(&cdev->private->wait_q);
+ wake_up(&cdev->private->wait_q);
}
/*
@@ -366,7 +370,7 @@ static void ccw_device_oper_notify(struct ccw_device *cdev)
}
/* Driver doesn't want device back. */
ccw_device_set_notoper(cdev);
- PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unreg_rereg);
+ PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unbind_bind);
queue_work(ccw_device_work, &cdev->private->kick_work);
}
@@ -390,10 +394,13 @@ ccw_device_done(struct ccw_device *cdev, int state)
cdev->private->state = state;
-
- if (state == DEV_STATE_BOXED)
+ if (state == DEV_STATE_BOXED) {
CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
cdev->private->dev_id.devno, sch->schid.sch_no);
+ if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED))
+ ccw_device_schedule_sch_unregister(cdev);
+ cdev->private->flags.donotify = 0;
+ }
if (cdev->private->flags.donotify) {
cdev->private->flags.donotify = 0;
@@ -728,7 +735,7 @@ static void ccw_device_generic_notoper(struct ccw_device *cdev,
{
struct subchannel *sch;
- cdev->private->state = DEV_STATE_NOT_OPER;
+ ccw_device_set_notoper(cdev);
sch = to_subchannel(cdev->dev.parent);
css_schedule_eval(sch->schid);
}
@@ -1052,7 +1059,7 @@ ccw_device_offline_irq(struct ccw_device *cdev, enum dev_event dev_event)
sch = to_subchannel(cdev->dev.parent);
/*
* An interrupt in state offline means a previous disable was not
- * successful. Try again.
+ * successful - should not happen, but we try to disable again.
*/
cio_disable_subchannel(sch);
}
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index eabcc42d63df..151754d54745 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -680,7 +680,7 @@ int ccw_device_tm_intrg(struct ccw_device *cdev)
if (cdev->private->state != DEV_STATE_ONLINE)
return -EIO;
if (!scsw_is_tm(&sch->schib.scsw) ||
- !(scsw_actl(&sch->schib.scsw) | SCSW_ACTL_START_PEND))
+ !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_START_PEND))
return -EINVAL;
return cio_tm_intrg(sch);
}
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 42f2b09631b6..13bcb8114388 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -186,6 +186,9 @@ struct qdio_input_q {
/* input buffer acknowledgement flag */
int polling;
+ /* first ACK'ed buffer */
+ int ack_start;
+
/* how much sbals are acknowledged with qebsm */
int ack_count;
@@ -234,7 +237,7 @@ struct qdio_q {
int first_to_check;
/* first_to_check of the last time */
- int last_move_ftc;
+ int last_move;
/* beginning position for calling the program */
int first_to_kick;
@@ -244,7 +247,6 @@ struct qdio_q {
struct qdio_irq *irq_ptr;
struct tasklet_struct tasklet;
- spinlock_t lock;
/* error condition during a data transfer */
unsigned int qdio_error;
@@ -354,7 +356,7 @@ int get_buf_state(struct qdio_q *q, unsigned int bufnr, unsigned char *state,
int auto_ack);
void qdio_check_outbound_after_thinint(struct qdio_q *q);
int qdio_inbound_q_moved(struct qdio_q *q);
-void qdio_kick_inbound_handler(struct qdio_q *q);
+void qdio_kick_handler(struct qdio_q *q);
void qdio_stop_polling(struct qdio_q *q);
int qdio_siga_sync_q(struct qdio_q *q);
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index da7afb04e71f..e3434b34f86c 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -63,8 +63,9 @@ static int qstat_show(struct seq_file *m, void *v)
seq_printf(m, "device state indicator: %d\n", *(u32 *)q->irq_ptr->dsci);
seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used));
seq_printf(m, "ftc: %d\n", q->first_to_check);
- seq_printf(m, "last_move_ftc: %d\n", q->last_move_ftc);
+ seq_printf(m, "last_move: %d\n", q->last_move);
seq_printf(m, "polling: %d\n", q->u.in.polling);
+ seq_printf(m, "ack start: %d\n", q->u.in.ack_start);
seq_printf(m, "ack count: %d\n", q->u.in.ack_count);
seq_printf(m, "slsb buffer states:\n");
seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 10cb0f8726e5..9e8a2914259b 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -380,11 +380,11 @@ inline void qdio_stop_polling(struct qdio_q *q)
/* show the card that we are not polling anymore */
if (is_qebsm(q)) {
- set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT,
+ set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
q->u.in.ack_count);
q->u.in.ack_count = 0;
} else
- set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
+ set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
}
static void announce_buffer_error(struct qdio_q *q, int count)
@@ -419,15 +419,15 @@ static inline void inbound_primed(struct qdio_q *q, int count)
if (!q->u.in.polling) {
q->u.in.polling = 1;
q->u.in.ack_count = count;
- q->last_move_ftc = q->first_to_check;
+ q->u.in.ack_start = q->first_to_check;
return;
}
/* delete the previous ACK's */
- set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT,
+ set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
q->u.in.ack_count);
q->u.in.ack_count = count;
- q->last_move_ftc = q->first_to_check;
+ q->u.in.ack_start = q->first_to_check;
return;
}
@@ -439,14 +439,13 @@ static inline void inbound_primed(struct qdio_q *q, int count)
if (q->u.in.polling) {
/* reset the previous ACK but first set the new one */
set_buf_state(q, new, SLSB_P_INPUT_ACK);
- set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
- }
- else {
+ set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
+ } else {
q->u.in.polling = 1;
- set_buf_state(q, q->first_to_check, SLSB_P_INPUT_ACK);
+ set_buf_state(q, new, SLSB_P_INPUT_ACK);
}
- q->last_move_ftc = new;
+ q->u.in.ack_start = new;
count--;
if (!count)
return;
@@ -455,7 +454,7 @@ static inline void inbound_primed(struct qdio_q *q, int count)
* Need to change all PRIMED buffers to NOT_INIT, otherwise
* we're loosing initiative in the thinint code.
*/
- set_buf_states(q, next_buf(q->first_to_check), SLSB_P_INPUT_NOT_INIT,
+ set_buf_states(q, q->first_to_check, SLSB_P_INPUT_NOT_INIT,
count);
}
@@ -523,7 +522,8 @@ int qdio_inbound_q_moved(struct qdio_q *q)
bufnr = get_inbound_buffer_frontier(q);
- if ((bufnr != q->last_move_ftc) || q->qdio_error) {
+ if ((bufnr != q->last_move) || q->qdio_error) {
+ q->last_move = bufnr;
if (!need_siga_sync(q) && !pci_out_supported(q))
q->u.in.timestamp = get_usecs();
@@ -570,29 +570,30 @@ static int qdio_inbound_q_done(struct qdio_q *q)
}
}
-void qdio_kick_inbound_handler(struct qdio_q *q)
+void qdio_kick_handler(struct qdio_q *q)
{
- int count, start, end;
-
- qdio_perf_stat_inc(&perf_stats.inbound_handler);
-
- start = q->first_to_kick;
- end = q->first_to_check;
- if (end >= start)
- count = end - start;
- else
- count = end + QDIO_MAX_BUFFERS_PER_Q - start;
-
- DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%3d c:%3d", start, count);
+ int start = q->first_to_kick;
+ int end = q->first_to_check;
+ int count;
if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
return;
- q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr,
- start, count, q->irq_ptr->int_parm);
+ count = sub_buf(end, start);
+
+ if (q->is_input_q) {
+ qdio_perf_stat_inc(&perf_stats.inbound_handler);
+ DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%3d c:%3d", start, count);
+ } else {
+ DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: nr:%1d", q->nr);
+ DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "s:%3d c:%3d", start, count);
+ }
+
+ q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
+ q->irq_ptr->int_parm);
/* for the next time */
- q->first_to_kick = q->first_to_check;
+ q->first_to_kick = end;
q->qdio_error = 0;
}
@@ -603,7 +604,7 @@ again:
if (!qdio_inbound_q_moved(q))
return;
- qdio_kick_inbound_handler(q);
+ qdio_kick_handler(q);
if (!qdio_inbound_q_done(q))
/* means poll time is not yet over */
@@ -698,21 +699,21 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q)
bufnr = get_outbound_buffer_frontier(q);
- if ((bufnr != q->last_move_ftc) || q->qdio_error) {
- q->last_move_ftc = bufnr;
+ if ((bufnr != q->last_move) || q->qdio_error) {
+ q->last_move = bufnr;
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
return 1;
} else
return 0;
}
-static void qdio_kick_outbound_q(struct qdio_q *q)
+static int qdio_kick_outbound_q(struct qdio_q *q)
{
unsigned int busy_bit;
int cc;
if (!need_siga_out(q))
- return;
+ return 0;
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr);
qdio_perf_stat_inc(&perf_stats.siga_out);
@@ -724,75 +725,37 @@ static void qdio_kick_outbound_q(struct qdio_q *q)
case 2:
if (busy_bit) {
DBF_ERROR("%4x cc2 REP:%1d", SCH_NO(q), q->nr);
- q->qdio_error = cc | QDIO_ERROR_SIGA_BUSY;
- } else {
- DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d",
- q->nr);
- q->qdio_error = cc;
- }
+ cc |= QDIO_ERROR_SIGA_BUSY;
+ } else
+ DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr);
break;
case 1:
case 3:
DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc);
- q->qdio_error = cc;
break;
}
-}
-
-static void qdio_kick_outbound_handler(struct qdio_q *q)
-{
- int start, end, count;
-
- start = q->first_to_kick;
- end = q->last_move_ftc;
- if (end >= start)
- count = end - start;
- else
- count = end + QDIO_MAX_BUFFERS_PER_Q - start;
-
- DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kickouth: %1d", q->nr);
- DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "s:%3d c:%3d", start, count);
-
- if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
- return;
-
- q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
- q->irq_ptr->int_parm);
-
- /* for the next time: */
- q->first_to_kick = q->last_move_ftc;
- q->qdio_error = 0;
+ return cc;
}
static void __qdio_outbound_processing(struct qdio_q *q)
{
- unsigned long flags;
-
qdio_perf_stat_inc(&perf_stats.tasklet_outbound);
- spin_lock_irqsave(&q->lock, flags);
-
BUG_ON(atomic_read(&q->nr_buf_used) < 0);
if (qdio_outbound_q_moved(q))
- qdio_kick_outbound_handler(q);
-
- spin_unlock_irqrestore(&q->lock, flags);
+ qdio_kick_handler(q);
- if (queue_type(q) == QDIO_ZFCP_QFMT) {
+ if (queue_type(q) == QDIO_ZFCP_QFMT)
if (!pci_out_supported(q) && !qdio_outbound_q_done(q))
- tasklet_schedule(&q->tasklet);
- return;
- }
+ goto sched;
/* bail out for HiperSockets unicast queues */
if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q))
return;
if ((queue_type(q) == QDIO_IQDIO_QFMT) &&
- (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL) {
- tasklet_schedule(&q->tasklet);
- return;
- }
+ (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL)
+ goto sched;
if (q->u.out.pci_out_enabled)
return;
@@ -810,6 +773,12 @@ static void __qdio_outbound_processing(struct qdio_q *q)
qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer);
}
}
+ return;
+
+sched:
+ if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+ return;
+ tasklet_schedule(&q->tasklet);
}
/* outbound tasklet */
@@ -822,6 +791,9 @@ void qdio_outbound_processing(unsigned long data)
void qdio_outbound_timer(unsigned long data)
{
struct qdio_q *q = (struct qdio_q *)data;
+
+ if (unlikely(q->irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+ return;
tasklet_schedule(&q->tasklet);
}
@@ -863,6 +835,9 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
int i;
struct qdio_q *q;
+ if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED))
+ return;
+
qdio_perf_stat_inc(&perf_stats.pci_int);
for_each_input_queue(irq_ptr, q, i)
@@ -1065,8 +1040,9 @@ EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc);
* @cdev: associated ccw device
* @how: use halt or clear to shutdown
*
- * This function calls qdio_shutdown() for @cdev with method @how
- * and on success qdio_free() for @cdev.
+ * This function calls qdio_shutdown() for @cdev with method @how.
+ * and qdio_free(). The qdio_free() return value is ignored since
+ * !irq_ptr is already checked.
*/
int qdio_cleanup(struct ccw_device *cdev, int how)
{
@@ -1077,8 +1053,8 @@ int qdio_cleanup(struct ccw_device *cdev, int how)
return -ENODEV;
rc = qdio_shutdown(cdev, how);
- if (rc == 0)
- rc = qdio_free(cdev);
+
+ qdio_free(cdev);
return rc;
}
EXPORT_SYMBOL_GPL(qdio_cleanup);
@@ -1090,11 +1066,11 @@ static void qdio_shutdown_queues(struct ccw_device *cdev)
int i;
for_each_input_queue(irq_ptr, q, i)
- tasklet_disable(&q->tasklet);
+ tasklet_kill(&q->tasklet);
for_each_output_queue(irq_ptr, q, i) {
- tasklet_disable(&q->tasklet);
del_timer(&q->u.out.timer);
+ tasklet_kill(&q->tasklet);
}
}
@@ -1112,6 +1088,7 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
if (!irq_ptr)
return -ENODEV;
+ BUG_ON(irqs_disabled());
DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no);
mutex_lock(&irq_ptr->setup_mutex);
@@ -1124,6 +1101,12 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
return 0;
}
+ /*
+ * Indicate that the device is going down. Scheduling the queue
+ * tasklets is forbidden from here on.
+ */
+ qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
+
tiqdio_remove_input_queues(irq_ptr);
qdio_shutdown_queues(cdev);
qdio_shutdown_debug_entries(irq_ptr, cdev);
@@ -1403,9 +1386,8 @@ int qdio_activate(struct ccw_device *cdev)
switch (irq_ptr->state) {
case QDIO_IRQ_STATE_STOPPED:
case QDIO_IRQ_STATE_ERR:
- mutex_unlock(&irq_ptr->setup_mutex);
- qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
- return -EIO;
+ rc = -EIO;
+ break;
default:
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ACTIVE);
rc = 0;
@@ -1442,10 +1424,10 @@ static inline int buf_in_between(int bufnr, int start, int count)
* @bufnr: first buffer to process
* @count: how many buffers are emptied
*/
-static void handle_inbound(struct qdio_q *q, unsigned int callflags,
- int bufnr, int count)
+static int handle_inbound(struct qdio_q *q, unsigned int callflags,
+ int bufnr, int count)
{
- int used, cc, diff;
+ int used, diff;
if (!q->u.in.polling)
goto set;
@@ -1456,19 +1438,18 @@ static void handle_inbound(struct qdio_q *q, unsigned int callflags,
q->u.in.polling = 0;
q->u.in.ack_count = 0;
goto set;
- } else if (buf_in_between(q->last_move_ftc, bufnr, count)) {
+ } else if (buf_in_between(q->u.in.ack_start, bufnr, count)) {
if (is_qebsm(q)) {
- /* partial overwrite, just update last_move_ftc */
+ /* partial overwrite, just update ack_start */
diff = add_buf(bufnr, count);
- diff = sub_buf(diff, q->last_move_ftc);
+ diff = sub_buf(diff, q->u.in.ack_start);
q->u.in.ack_count -= diff;
if (q->u.in.ack_count <= 0) {
q->u.in.polling = 0;
q->u.in.ack_count = 0;
- /* TODO: must we set last_move_ftc to something meaningful? */
goto set;
}
- q->last_move_ftc = add_buf(q->last_move_ftc, diff);
+ q->u.in.ack_start = add_buf(q->u.in.ack_start, diff);
}
else
/* the only ACK will be deleted, so stop polling */
@@ -1483,13 +1464,11 @@ set:
/* no need to signal as long as the adapter had free buffers */
if (used)
- return;
+ return 0;
- if (need_siga_in(q)) {
- cc = qdio_siga_input(q);
- if (cc)
- q->qdio_error = cc;
- }
+ if (need_siga_in(q))
+ return qdio_siga_input(q);
+ return 0;
}
/**
@@ -1499,11 +1478,11 @@ set:
* @bufnr: first buffer to process
* @count: how many buffers are filled
*/
-static void handle_outbound(struct qdio_q *q, unsigned int callflags,
- int bufnr, int count)
+static int handle_outbound(struct qdio_q *q, unsigned int callflags,
+ int bufnr, int count)
{
unsigned char state;
- int used;
+ int used, rc = 0;
qdio_perf_stat_inc(&perf_stats.outbound_handler);
@@ -1518,27 +1497,26 @@ static void handle_outbound(struct qdio_q *q, unsigned int callflags,
if (queue_type(q) == QDIO_IQDIO_QFMT) {
if (multicast_outbound(q))
- qdio_kick_outbound_q(q);
+ rc = qdio_kick_outbound_q(q);
else
if ((q->irq_ptr->ssqd_desc.mmwc > 1) &&
(count > 1) &&
(count <= q->irq_ptr->ssqd_desc.mmwc)) {
/* exploit enhanced SIGA */
q->u.out.use_enh_siga = 1;
- qdio_kick_outbound_q(q);
+ rc = qdio_kick_outbound_q(q);
} else {
/*
* One siga-w per buffer required for unicast
* HiperSockets.
*/
q->u.out.use_enh_siga = 0;
- while (count--)
- qdio_kick_outbound_q(q);
+ while (count--) {
+ rc = qdio_kick_outbound_q(q);
+ if (rc)
+ goto out;
+ }
}
-
- /* report CC=2 conditions synchronously */
- if (q->qdio_error)
- __qdio_outbound_processing(q);
goto out;
}
@@ -1550,14 +1528,14 @@ static void handle_outbound(struct qdio_q *q, unsigned int callflags,
/* try to fast requeue buffers */
get_buf_state(q, prev_buf(bufnr), &state, 0);
if (state != SLSB_CU_OUTPUT_PRIMED)
- qdio_kick_outbound_q(q);
+ rc = qdio_kick_outbound_q(q);
else {
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "fast-req");
qdio_perf_stat_inc(&perf_stats.fast_requeue);
}
out:
- /* Fixme: could wait forever if called from process context */
tasklet_schedule(&q->tasklet);
+ return rc;
}
/**
@@ -1596,14 +1574,12 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
return -EBUSY;
if (callflags & QDIO_FLAG_SYNC_INPUT)
- handle_inbound(irq_ptr->input_qs[q_nr], callflags, bufnr,
- count);
+ return handle_inbound(irq_ptr->input_qs[q_nr],
+ callflags, bufnr, count);
else if (callflags & QDIO_FLAG_SYNC_OUTPUT)
- handle_outbound(irq_ptr->output_qs[q_nr], callflags, bufnr,
- count);
- else
- return -EINVAL;
- return 0;
+ return handle_outbound(irq_ptr->output_qs[q_nr],
+ callflags, bufnr, count);
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(do_QDIO);
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index c08356b95bf5..18d54fc21ce9 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -117,7 +117,6 @@ static void setup_queues_misc(struct qdio_q *q, struct qdio_irq *irq_ptr,
q->mask = 1 << (31 - i);
q->nr = i;
q->handler = handler;
- spin_lock_init(&q->lock);
}
static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr,
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 8e90e147b746..c655d011a78d 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -31,6 +31,7 @@
/* list of thin interrupt input queues */
static LIST_HEAD(tiq_list);
+DEFINE_MUTEX(tiq_list_lock);
/* adapter local summary indicator */
static unsigned char *tiqdio_alsi;
@@ -95,12 +96,11 @@ void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
if (!css_qdio_omit_svs && irq_ptr->siga_flag.sync)
css_qdio_omit_svs = 1;
- for_each_input_queue(irq_ptr, q, i) {
+ mutex_lock(&tiq_list_lock);
+ for_each_input_queue(irq_ptr, q, i)
list_add_rcu(&q->entry, &tiq_list);
- synchronize_rcu();
- }
+ mutex_unlock(&tiq_list_lock);
xchg(irq_ptr->dsci, 1);
- tasklet_schedule(&tiqdio_tasklet);
}
/*
@@ -118,7 +118,10 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
/* if establish triggered an error */
if (!q || !q->entry.prev || !q->entry.next)
continue;
+
+ mutex_lock(&tiq_list_lock);
list_del_rcu(&q->entry);
+ mutex_unlock(&tiq_list_lock);
synchronize_rcu();
}
}
@@ -155,15 +158,15 @@ static void __tiqdio_inbound_processing(struct qdio_q *q)
*/
qdio_check_outbound_after_thinint(q);
-again:
if (!qdio_inbound_q_moved(q))
return;
- qdio_kick_inbound_handler(q);
+ qdio_kick_handler(q);
if (!tiqdio_inbound_q_done(q)) {
qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop);
- goto again;
+ if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+ tasklet_schedule(&q->tasklet);
}
qdio_stop_polling(q);
@@ -173,7 +176,8 @@ again:
*/
if (!tiqdio_inbound_q_done(q)) {
qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2);
- goto again;
+ if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+ tasklet_schedule(&q->tasklet);
}
}
@@ -366,10 +370,11 @@ void qdio_shutdown_thinint(struct qdio_irq *irq_ptr)
void __exit tiqdio_unregister_thinints(void)
{
- tasklet_disable(&tiqdio_tasklet);
+ WARN_ON(!list_empty(&tiq_list));
if (tiqdio_alsi) {
s390_unregister_adapter_interrupt(tiqdio_alsi, QDIO_AIRQ_ISC);
isc_unregister(QDIO_AIRQ_ISC);
}
+ tasklet_kill(&tiqdio_tasklet);
}
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index cb22b97944b8..65b6a96afe6b 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -128,8 +128,7 @@ static void __zcrypt_increase_preference(struct zcrypt_device *zdev)
if (l == zdev->list.prev)
return;
/* Move zdev behind l */
- list_del(&zdev->list);
- list_add(&zdev->list, l);
+ list_move(&zdev->list, l);
}
/**
@@ -157,8 +156,7 @@ static void __zcrypt_decrease_preference(struct zcrypt_device *zdev)
if (l == zdev->list.next)
return;
/* Move zdev before l */
- list_del(&zdev->list);
- list_add_tail(&zdev->list, l);
+ list_move_tail(&zdev->list, l);
}
static void zcrypt_device_release(struct kref *kref)
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index e7a1e22e77ac..c20d4790258e 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -781,8 +781,7 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev,
/* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
out_free:
- memset(ap_msg.message, 0x0, ap_msg.length);
- kfree(ap_msg.message);
+ kzfree(ap_msg.message);
return rc;
}
diff --git a/drivers/s390/ebcdic.c b/drivers/s390/ebcdic.c
deleted file mode 100644
index 99c98da15473..000000000000
--- a/drivers/s390/ebcdic.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * arch/s390/kernel/ebcdic.c
- * ECBDIC -> ASCII, ASCII -> ECBDIC conversion tables.
- *
- * S390 version
- * Copyright (C) 1998 IBM Corporation
- * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
-
-#include <asm/types.h>
-
-/*
- * ASCII -> EBCDIC
- */
-__u8 _ascebc[256] =
-{
- /*00 NL SH SX EX ET NQ AK BL */
- 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
- /*08 BS HT LF VT FF CR SO SI */
- 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /*10 DL D1 D2 D3 D4 NK SN EB */
- 0x10, 0x11, 0x12, 0x13, 0x3C, 0x15, 0x32, 0x26,
- /*18 CN EM SB EC FS GS RS US */
- 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
- /*20 SP ! " # $ % & ' */
- 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
- /*28 ( ) * + , - . / */
- 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
- /*30 0 1 2 3 4 5 6 7 */
- 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- /*38 8 9 : ; < = > ? */
- 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
- /*40 @ A B C D E F G */
- 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
- /*48 H I J K L M N O */
- 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
- /*50 P Q R S T U V W */
- 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
- /*58 X Y Z [ \ ] ^ _ */
- 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
- /*60 ` a b c d e f g */
- 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- /*68 h i j k l m n o */
- 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
- /*70 p q r s t u v w */
- 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
- /*78 x y z { | } ~ DL */
- 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFF
-};
-
-/*
- * EBCDIC -> ASCII
- */
-__u8 _ebcasc[256] =
-{
- /* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */
- 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
- /* 0x08 -GE -SPS -RPT VT FF CR SO SI */
- 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC
- -ENP ->LF */
- 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
- /* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB
- -IUS */
- 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC
- -INP */
- 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
- /* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL
- -SW */
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
- /* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */
- 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
- /* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */
- 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
- /* 0x40 SP RSP ---- */
- 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
- /* 0x48 . < ( + | */
- 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
- /* 0x50 & ---- */
- 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
- /* 0x58 ! $ * ) ; */
- 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
- /* 0x60 - / ---- ---- ---- ---- */
- 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
- /* 0x68 ---- , % _ > ? */
- 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
- /* 0x70 ---- ---- ---- ---- ---- ---- ---- */
- 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x78 * ` : # @ ' = " */
- 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
- /* 0x80 * a b c d e f g */
- 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- /* 0x88 h i ---- ---- ---- */
- 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
- /* 0x90 j k l m n o p */
- 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
- /* 0x98 q r ---- ---- */
- 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
- /* 0xA0 ~ s t u v w x */
- 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- /* 0xA8 y z ---- ---- ---- ---- */
- 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
- /* 0xB0 ^ ---- ---- */
- 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
- /* 0xB8 ---- [ ] ---- ---- ---- ---- */
- 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
- /* 0xC0 { A B C D E F G */
- 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /* 0xC8 H I ---- ---- */
- 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
- /* 0xD0 } J K L M N O P */
- 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
- /* 0xD8 Q R ---- */
- 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
- /* 0xE0 \ S T U V W X */
- 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- /* 0xE8 Y Z ---- ---- ---- ---- */
- 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
- /* 0xF0 0 1 2 3 4 5 6 7 */
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- /* 0xF8 8 9 ---- ---- ---- ---- ---- */
- 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
-};
-
-/*
- * EBCDIC (capitals) -> ASCII (small case)
- */
-__u8 _ebcasc_reduce_case[256] =
-{
- /* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */
- 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
-
- /* 0x08 -GE -SPS -RPT VT FF CR SO SI */
- 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-
- /* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC
- -ENP ->LF */
- 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
-
- /* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB
- -IUS */
- 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-
- /* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC
- -INP */
- 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
-
- /* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL
- -SW */
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
-
- /* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */
- 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
-
- /* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */
- 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
-
- /* 0x40 SP RSP ---- */
- 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
-
- /* 0x48 . < ( + | */
- 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
-
- /* 0x50 & ---- */
- 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
-
- /* 0x58 ! $ * ) ; */
- 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
-
- /* 0x60 - / ---- ---- ---- ---- */
- 0x2D, 0x2F, 0x07, 0x84, 0x07, 0x07, 0x07, 0x8F,
-
- /* 0x68 ---- , % _ > ? */
- 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
-
- /* 0x70 ---- ---- ---- ---- ---- ---- ---- */
- 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
-
- /* 0x78 * ` : # @ ' = " */
- 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
-
- /* 0x80 * a b c d e f g */
- 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-
- /* 0x88 h i ---- ---- ---- */
- 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
-
- /* 0x90 j k l m n o p */
- 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
-
- /* 0x98 q r ---- ---- */
- 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
-
- /* 0xA0 ~ s t u v w x */
- 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-
- /* 0xA8 y z ---- ---- ---- ---- */
- 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
-
- /* 0xB0 ^ ---- ---- */
- 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
-
- /* 0xB8 ---- [ ] ---- ---- ---- ---- */
- 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
-
- /* 0xC0 { A B C D E F G */
- 0x7B, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-
- /* 0xC8 H I ---- ---- */
- 0x68, 0x69, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
-
- /* 0xD0 } J K L M N O P */
- 0x7D, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
-
- /* 0xD8 Q R ---- */
- 0x71, 0x72, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
-
- /* 0xE0 \ S T U V W X */
- 0x5C, 0xF6, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-
- /* 0xE8 Y Z ---- ---- ---- ---- */
- 0x79, 0x7A, 0xFD, 0x07, 0x94, 0x07, 0x07, 0x07,
-
- /* 0xF0 0 1 2 3 4 5 6 7 */
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-
- /* 0xF8 8 9 ---- ---- ---- ---- ---- */
- 0x38, 0x39, 0x07, 0x07, 0x81, 0x07, 0x07, 0x07
-};
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
index 6382c04d2bdf..96eddb3b1d08 100644
--- a/drivers/s390/net/Makefile
+++ b/drivers/s390/net/Makefile
@@ -8,7 +8,7 @@ obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
obj-$(CONFIG_SMSGIUCV) += smsgiucv.o
obj-$(CONFIG_LCS) += lcs.o cu3088.o
obj-$(CONFIG_CLAW) += claw.o cu3088.o
-qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o qeth_core_offl.o
+qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o
obj-$(CONFIG_QETH) += qeth.o
qeth_l2-y += qeth_l2_main.o
obj-$(CONFIG_QETH_L2) += qeth_l2.o
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index f5e618562c5f..30a43cc79e76 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -60,6 +60,9 @@
* 1.25 Added Packing support
* 1.5
*/
+
+#define KMSG_COMPONENT "claw"
+
#include <asm/ccwdev.h>
#include <asm/ccwgroup.h>
#include <asm/debug.h>
@@ -94,7 +97,7 @@
CLAW uses the s390dbf file system see claw_trace and claw_setup
*/
-
+static char version[] __initdata = "CLAW driver";
static char debug_buffer[255];
/**
* Debug Facility Stuff
@@ -206,20 +209,30 @@ static struct net_device_stats *claw_stats(struct net_device *dev);
static int pages_to_order_of_mag(int num_of_pages);
static struct sk_buff *claw_pack_skb(struct claw_privbk *privptr);
/* sysfs Functions */
-static ssize_t claw_hname_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_hname_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_hname_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t claw_hname_write(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t count);
-static ssize_t claw_adname_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_adname_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_adname_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t claw_adname_write(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t count);
-static ssize_t claw_apname_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_apname_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_apname_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t claw_apname_write(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t count);
-static ssize_t claw_wbuff_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_wbuff_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_wbuff_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t claw_wbuff_write(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t count);
-static ssize_t claw_rbuff_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t claw_rbuff_write(struct device *dev, struct device_attribute *attr,
+static ssize_t claw_rbuff_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+static ssize_t claw_rbuff_write(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t count);
static int claw_add_files(struct device *dev);
static void claw_remove_files(struct device *dev);
@@ -298,8 +311,8 @@ claw_probe(struct ccwgroup_device *cgdev)
if (rc) {
probe_error(cgdev);
put_device(&cgdev->dev);
- printk(KERN_WARNING "add_files failed %s %s Exit Line %d \n",
- dev_name(&cgdev->cdev[0]->dev), __func__, __LINE__);
+ dev_err(&cgdev->dev, "Creating the /proc files for a new"
+ " CLAW device failed\n");
CLAW_DBF_TEXT_(2, setup, "probex%d", rc);
return rc;
}
@@ -335,6 +348,8 @@ claw_tx(struct sk_buff *skb, struct net_device *dev)
rc=claw_hw_tx( skb, dev, 1 );
spin_unlock_irqrestore(get_ccwdev_lock(p_ch->cdev), saveflags);
CLAW_DBF_TEXT_(4, trace, "clawtx%d", rc);
+ if (rc)
+ rc = NETDEV_TX_BUSY;
return rc;
} /* end of claw_tx */
@@ -496,7 +511,8 @@ claw_open(struct net_device *dev)
~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) ||
(((privptr->channel[READ].flag |
privptr->channel[WRITE].flag) & CLAW_TIMER) != 0x00)) {
- printk(KERN_INFO "%s: remote side is not ready\n", dev->name);
+ dev_info(&privptr->channel[READ].cdev->dev,
+ "%s: remote side is not ready\n", dev->name);
CLAW_DBF_TEXT(2, trace, "notrdy");
for ( i = 0; i < 2; i++) {
@@ -582,10 +598,9 @@ claw_irq_handler(struct ccw_device *cdev,
CLAW_DBF_TEXT(4, trace, "clawirq");
/* Bypass all 'unsolicited interrupts' */
if (!cdev->dev.driver_data) {
- printk(KERN_WARNING "claw: unsolicited interrupt for device:"
- "%s received c-%02x d-%02x\n",
- dev_name(&cdev->dev), irb->scsw.cmd.cstat,
- irb->scsw.cmd.dstat);
+ dev_warn(&cdev->dev, "An uninitialized CLAW device received an"
+ " IRQ, c-%02x d-%02x\n",
+ irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
CLAW_DBF_TEXT(2, trace, "badirq");
return;
}
@@ -597,8 +612,7 @@ claw_irq_handler(struct ccw_device *cdev,
else if (privptr->channel[WRITE].cdev == cdev)
p_ch = &privptr->channel[WRITE];
else {
- printk(KERN_WARNING "claw: Can't determine channel for "
- "interrupt, device %s\n", dev_name(&cdev->dev));
+ dev_warn(&cdev->dev, "The device is not a CLAW device\n");
CLAW_DBF_TEXT(2, trace, "badchan");
return;
}
@@ -612,7 +626,8 @@ claw_irq_handler(struct ccw_device *cdev,
/* Check for good subchannel return code, otherwise info message */
if (irb->scsw.cmd.cstat && !(irb->scsw.cmd.cstat & SCHN_STAT_PCI)) {
- printk(KERN_INFO "%s: subchannel check for device: %04x -"
+ dev_info(&cdev->dev,
+ "%s: subchannel check for device: %04x -"
" Sch Stat %02x Dev Stat %02x CPA - %04x\n",
dev->name, p_ch->devno,
irb->scsw.cmd.cstat, irb->scsw.cmd.dstat,
@@ -651,7 +666,7 @@ claw_irq_handler(struct ccw_device *cdev,
wake_up(&p_ch->wait); /* wake claw_open (READ)*/
} else if (p_ch->flag == CLAW_WRITE) {
p_ch->claw_state = CLAW_START_WRITE;
- /* send SYSTEM_VALIDATE */
+ /* send SYSTEM_VALIDATE */
claw_strt_read(dev, LOCK_NO);
claw_send_control(dev,
SYSTEM_VALIDATE_REQUEST,
@@ -659,10 +674,9 @@ claw_irq_handler(struct ccw_device *cdev,
p_env->host_name,
p_env->adapter_name);
} else {
- printk(KERN_WARNING "claw: unsolicited "
- "interrupt for device:"
- "%s received c-%02x d-%02x\n",
- dev_name(&cdev->dev),
+ dev_warn(&cdev->dev, "The CLAW device received"
+ " an unexpected IRQ, "
+ "c-%02x d-%02x\n",
irb->scsw.cmd.cstat,
irb->scsw.cmd.dstat);
return;
@@ -677,8 +691,8 @@ claw_irq_handler(struct ccw_device *cdev,
(p_ch->irb->ecw[0] & 0x40) == 0x40 ||
(p_ch->irb->ecw[0]) == 0) {
privptr->stats.rx_errors++;
- printk(KERN_INFO "%s: Restart is "
- "required after remote "
+ dev_info(&cdev->dev,
+ "%s: Restart is required after remote "
"side recovers \n",
dev->name);
}
@@ -713,11 +727,13 @@ claw_irq_handler(struct ccw_device *cdev,
return;
case CLAW_START_WRITE:
if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
- printk(KERN_INFO "%s: Unit Check Occured in "
+ dev_info(&cdev->dev,
+ "%s: Unit Check Occured in "
"write channel\n", dev->name);
clear_bit(0, (void *)&p_ch->IO_active);
if (p_ch->irb->ecw[0] & 0x80) {
- printk(KERN_INFO "%s: Resetting Event "
+ dev_info(&cdev->dev,
+ "%s: Resetting Event "
"occurred:\n", dev->name);
init_timer(&p_ch->timer);
p_ch->timer.function =
@@ -725,7 +741,8 @@ claw_irq_handler(struct ccw_device *cdev,
p_ch->timer.data = (unsigned long)p_ch;
p_ch->timer.expires = jiffies + 10*HZ;
add_timer(&p_ch->timer);
- printk(KERN_INFO "%s: write connection "
+ dev_info(&cdev->dev,
+ "%s: write connection "
"restarting\n", dev->name);
}
CLAW_DBF_TEXT(4, trace, "rstrtwrt");
@@ -733,9 +750,10 @@ claw_irq_handler(struct ccw_device *cdev,
}
if (p_ch->irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) {
clear_bit(0, (void *)&p_ch->IO_active);
- printk(KERN_INFO "%s: Unit Exception "
- "Occured in write channel\n",
- dev->name);
+ dev_info(&cdev->dev,
+ "%s: Unit Exception "
+ "occurred in write channel\n",
+ dev->name);
}
if (!((p_ch->irb->scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS) ||
(p_ch->irb->scsw.cmd.stctl == SCSW_STCTL_STATUS_PEND) ||
@@ -757,8 +775,9 @@ claw_irq_handler(struct ccw_device *cdev,
CLAW_DBF_TEXT(4, trace, "StWtExit");
return;
default:
- printk(KERN_WARNING "%s: wrong selection code - irq "
- "state=%d\n", dev->name, p_ch->claw_state);
+ dev_warn(&cdev->dev,
+ "The CLAW device for %s received an unexpected IRQ\n",
+ dev->name);
CLAW_DBF_TEXT(2, trace, "badIRQ");
return;
}
@@ -910,8 +929,10 @@ claw_release(struct net_device *dev)
if (((privptr->channel[READ].last_dstat |
privptr->channel[WRITE].last_dstat) &
~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) {
- printk(KERN_WARNING "%s: channel problems during close - "
- "read: %02x - write: %02x\n",
+ dev_warn(&privptr->channel[READ].cdev->dev,
+ "Deactivating %s completed with incorrect"
+ " subchannel status "
+ "(read %02x, write %02x)\n",
dev->name,
privptr->channel[READ].last_dstat,
privptr->channel[WRITE].last_dstat);
@@ -1012,7 +1033,7 @@ static int
pages_to_order_of_mag(int num_of_pages)
{
int order_of_mag=1; /* assume 2 pages */
- int nump=2;
+ int nump;
CLAW_DBF_TEXT_(5, trace, "pages%d", num_of_pages);
if (num_of_pages == 1) {return 0; } /* magnitude of 0 = 1 page */
@@ -1076,8 +1097,8 @@ add_claw_reads(struct net_device *dev, struct ccwbk* p_first,
}
if ( privptr-> p_read_active_first ==NULL ) {
- privptr-> p_read_active_first= p_first; /* set new first */
- privptr-> p_read_active_last = p_last; /* set new last */
+ privptr->p_read_active_first = p_first; /* set new first */
+ privptr->p_read_active_last = p_last; /* set new last */
}
else {
@@ -1113,7 +1134,7 @@ add_claw_reads(struct net_device *dev, struct ccwbk* p_first,
privptr->p_read_active_last->r_TIC_2.cda=
(__u32)__pa(&p_first->read);
}
- /* chain in new set of blocks */
+ /* chain in new set of blocks */
privptr->p_read_active_last->next = p_first;
privptr->p_read_active_last=p_last;
} /* end of if ( privptr-> p_read_active_first ==NULL) */
@@ -1135,21 +1156,18 @@ ccw_check_return_code(struct ccw_device *cdev, int return_code)
case -EBUSY: /* BUSY is a transient state no action needed */
break;
case -ENODEV:
- printk(KERN_EMERG "%s: Missing device called "
- "for IO ENODEV\n", dev_name(&cdev->dev));
- break;
- case -EIO:
- printk(KERN_EMERG "%s: Status pending... EIO \n",
- dev_name(&cdev->dev));
+ dev_err(&cdev->dev, "The remote channel adapter is not"
+ " available\n");
break;
case -EINVAL:
- printk(KERN_EMERG "%s: Invalid Dev State EINVAL \n",
- dev_name(&cdev->dev));
+ dev_err(&cdev->dev,
+ "The status of the remote channel adapter"
+ " is not valid\n");
break;
default:
- printk(KERN_EMERG "%s: Unknown error in "
- "Do_IO %d\n", dev_name(&cdev->dev),
- return_code);
+ dev_err(&cdev->dev, "The common device layer"
+ " returned error code %d\n",
+ return_code);
}
}
CLAW_DBF_TEXT(4, trace, "ccwret");
@@ -1163,42 +1181,37 @@ static void
ccw_check_unit_check(struct chbk * p_ch, unsigned char sense )
{
struct net_device *ndev = p_ch->ndev;
+ struct device *dev = &p_ch->cdev->dev;
CLAW_DBF_TEXT(4, trace, "unitchek");
- printk(KERN_INFO "%s: Unit Check with sense byte:0x%04x\n",
- ndev->name, sense);
-
- if (sense & 0x40) {
- if (sense & 0x01) {
- printk(KERN_WARNING "%s: Interface disconnect or "
- "Selective reset "
- "occurred (remote side)\n", ndev->name);
- }
- else {
- printk(KERN_WARNING "%s: System reset occured"
- " (remote side)\n", ndev->name);
- }
- }
- else if (sense & 0x20) {
- if (sense & 0x04) {
- printk(KERN_WARNING "%s: Data-streaming "
- "timeout)\n", ndev->name);
- }
- else {
- printk(KERN_WARNING "%s: Data-transfer parity"
- " error\n", ndev->name);
- }
- }
- else if (sense & 0x10) {
- if (sense & 0x20) {
- printk(KERN_WARNING "%s: Hardware malfunction "
- "(remote side)\n", ndev->name);
- }
- else {
- printk(KERN_WARNING "%s: read-data parity error "
- "(remote side)\n", ndev->name);
- }
- }
+ dev_warn(dev, "The communication peer of %s disconnected\n",
+ ndev->name);
+
+ if (sense & 0x40) {
+ if (sense & 0x01) {
+ dev_warn(dev, "The remote channel adapter for"
+ " %s has been reset\n",
+ ndev->name);
+ }
+ } else if (sense & 0x20) {
+ if (sense & 0x04) {
+ dev_warn(dev, "A data streaming timeout occurred"
+ " for %s\n",
+ ndev->name);
+ } else if (sense & 0x10) {
+ dev_warn(dev, "The remote channel adapter for %s"
+ " is faulty\n",
+ ndev->name);
+ } else {
+ dev_warn(dev, "A data transfer parity error occurred"
+ " for %s\n",
+ ndev->name);
+ }
+ } else if (sense & 0x10) {
+ dev_warn(dev, "A read data parity error occurred"
+ " for %s\n",
+ ndev->name);
+ }
} /* end of ccw_check_unit_check */
@@ -1235,7 +1248,7 @@ find_link(struct net_device *dev, char *host_name, char *ws_name )
break;
}
- return 0;
+ return rc;
} /* end of find_link */
/*-------------------------------------------------------------------*
@@ -1347,7 +1360,10 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
privptr->p_write_free_chain=p_this_ccw->next;
p_this_ccw->next=NULL;
--privptr->write_free_count; /* -1 */
- bytesInThisBuffer=len_of_data;
+ if (len_of_data >= privptr->p_env->write_size)
+ bytesInThisBuffer = privptr->p_env->write_size;
+ else
+ bytesInThisBuffer = len_of_data;
memcpy( p_this_ccw->p_buffer,pDataAddress, bytesInThisBuffer);
len_of_data-=bytesInThisBuffer;
pDataAddress+=(unsigned long)bytesInThisBuffer;
@@ -1375,7 +1391,7 @@ claw_hw_tx(struct sk_buff *skb, struct net_device *dev, long linkid)
*/
if (p_first_ccw!=NULL) {
- /* setup ending ccw sequence for this segment */
+ /* setup ending ccw sequence for this segment */
pEnd=privptr->p_end_ccw;
if (pEnd->write1) {
pEnd->write1=0x00; /* second end ccw is now active */
@@ -1697,10 +1713,11 @@ init_ccw_bk(struct net_device *dev)
p_buf-> w_TIC_1.flags = 0;
p_buf-> w_TIC_1.count = 0;
- if (((unsigned long)p_buff+privptr->p_env->write_size) >=
+ if (((unsigned long)p_buff +
+ privptr->p_env->write_size) >=
((unsigned long)(p_buff+2*
- (privptr->p_env->write_size) -1) & PAGE_MASK)) {
- p_buff= p_buff+privptr->p_env->write_size;
+ (privptr->p_env->write_size) - 1) & PAGE_MASK)) {
+ p_buff = p_buff+privptr->p_env->write_size;
}
}
}
@@ -1840,15 +1857,16 @@ init_ccw_bk(struct net_device *dev)
p_buf->header.opcode=0xff;
p_buf->header.flag=CLAW_PENDING;
- if (((unsigned long)p_buff+privptr->p_env->read_size) >=
- ((unsigned long)(p_buff+2*(privptr->p_env->read_size) -1)
- & PAGE_MASK) ) {
+ if (((unsigned long)p_buff+privptr->p_env->read_size) >=
+ ((unsigned long)(p_buff+2*(privptr->p_env->read_size)
+ -1)
+ & PAGE_MASK)) {
p_buff= p_buff+privptr->p_env->read_size;
}
else {
p_buff=
(void *)((unsigned long)
- (p_buff+2*(privptr->p_env->read_size) -1)
+ (p_buff+2*(privptr->p_env->read_size)-1)
& PAGE_MASK) ;
}
} /* for read_buffers */
@@ -1856,24 +1874,28 @@ init_ccw_bk(struct net_device *dev)
else { /* read Size >= PAGE_SIZE */
for (i=0 ; i< privptr->p_env->read_buffers ; i++) {
p_buff = (void *)__get_free_pages(__GFP_DMA,
- (int)pages_to_order_of_mag(privptr->p_buff_pages_perread) );
+ (int)pages_to_order_of_mag(
+ privptr->p_buff_pages_perread));
if (p_buff==NULL) {
free_pages((unsigned long)privptr->p_buff_ccw,
- (int)pages_to_order_of_mag(privptr->p_buff_ccw_num));
+ (int)pages_to_order_of_mag(privptr->
+ p_buff_ccw_num));
/* free the write pages */
p_buf=privptr->p_buff_write;
while (p_buf!=NULL) {
- free_pages((unsigned long)p_buf->p_buffer,
- (int)pages_to_order_of_mag(
- privptr->p_buff_pages_perwrite ));
+ free_pages(
+ (unsigned long)p_buf->p_buffer,
+ (int)pages_to_order_of_mag(
+ privptr->p_buff_pages_perwrite));
p_buf=p_buf->next;
}
/* free any read pages already alloc */
p_buf=privptr->p_buff_read;
while (p_buf!=NULL) {
- free_pages((unsigned long)p_buf->p_buffer,
- (int)pages_to_order_of_mag(
- privptr->p_buff_pages_perread ));
+ free_pages(
+ (unsigned long)p_buf->p_buffer,
+ (int)pages_to_order_of_mag(
+ privptr->p_buff_pages_perread));
p_buf=p_buf->next;
}
privptr->p_buff_ccw=NULL;
@@ -2003,7 +2025,7 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
tdev = &privptr->channel[READ].cdev->dev;
memcpy( &temp_host_name, p_env->host_name, 8);
memcpy( &temp_ws_name, p_env->adapter_name , 8);
- printk(KERN_INFO "%s: CLAW device %.8s: "
+ dev_info(tdev, "%s: CLAW device %.8s: "
"Received Control Packet\n",
dev->name, temp_ws_name);
if (privptr->release_pend==1) {
@@ -2022,32 +2044,30 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
if (p_ctlbk->version != CLAW_VERSION_ID) {
claw_snd_sys_validate_rsp(dev, p_ctlbk,
CLAW_RC_WRONG_VERSION);
- printk("%s: %d is wrong version id. "
- "Expected %d\n",
- dev->name, p_ctlbk->version,
- CLAW_VERSION_ID);
+ dev_warn(tdev, "The communication peer of %s"
+ " uses an incorrect API version %d\n",
+ dev->name, p_ctlbk->version);
}
p_sysval = (struct sysval *)&(p_ctlbk->data);
- printk("%s: Recv Sys Validate Request: "
- "Vers=%d,link_id=%d,Corr=%d,WS name=%."
- "8s,Host name=%.8s\n",
- dev->name, p_ctlbk->version,
- p_ctlbk->linkid,
- p_ctlbk->correlator,
- p_sysval->WS_name,
- p_sysval->host_name);
+ dev_info(tdev, "%s: Recv Sys Validate Request: "
+ "Vers=%d,link_id=%d,Corr=%d,WS name=%.8s,"
+ "Host name=%.8s\n",
+ dev->name, p_ctlbk->version,
+ p_ctlbk->linkid,
+ p_ctlbk->correlator,
+ p_sysval->WS_name,
+ p_sysval->host_name);
if (memcmp(temp_host_name, p_sysval->host_name, 8)) {
claw_snd_sys_validate_rsp(dev, p_ctlbk,
CLAW_RC_NAME_MISMATCH);
CLAW_DBF_TEXT(2, setup, "HSTBAD");
CLAW_DBF_TEXT_(2, setup, "%s", p_sysval->host_name);
CLAW_DBF_TEXT_(2, setup, "%s", temp_host_name);
- printk(KERN_INFO "%s: Host name mismatch\n",
- dev->name);
- printk(KERN_INFO "%s: Received :%s: "
- "expected :%s: \n",
- dev->name,
+ dev_warn(tdev,
+ "Host name %s for %s does not match the"
+ " remote adapter name %s\n",
p_sysval->host_name,
+ dev->name,
temp_host_name);
}
if (memcmp(temp_ws_name, p_sysval->WS_name, 8)) {
@@ -2056,35 +2076,38 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
CLAW_DBF_TEXT(2, setup, "WSNBAD");
CLAW_DBF_TEXT_(2, setup, "%s", p_sysval->WS_name);
CLAW_DBF_TEXT_(2, setup, "%s", temp_ws_name);
- printk(KERN_INFO "%s: WS name mismatch\n",
- dev->name);
- printk(KERN_INFO "%s: Received :%s: "
- "expected :%s: \n",
- dev->name,
- p_sysval->WS_name,
- temp_ws_name);
+ dev_warn(tdev, "Adapter name %s for %s does not match"
+ " the remote host name %s\n",
+ p_sysval->WS_name,
+ dev->name,
+ temp_ws_name);
}
if ((p_sysval->write_frame_size < p_env->write_size) &&
(p_env->packing == 0)) {
claw_snd_sys_validate_rsp(dev, p_ctlbk,
CLAW_RC_HOST_RCV_TOO_SMALL);
- printk(KERN_INFO "%s: host write size is too "
- "small\n", dev->name);
+ dev_warn(tdev,
+ "The local write buffer is smaller than the"
+ " remote read buffer\n");
CLAW_DBF_TEXT(2, setup, "wrtszbad");
}
if ((p_sysval->read_frame_size < p_env->read_size) &&
(p_env->packing == 0)) {
claw_snd_sys_validate_rsp(dev, p_ctlbk,
CLAW_RC_HOST_RCV_TOO_SMALL);
- printk(KERN_INFO "%s: host read size is too "
- "small\n", dev->name);
+ dev_warn(tdev,
+ "The local read buffer is smaller than the"
+ " remote write buffer\n");
CLAW_DBF_TEXT(2, setup, "rdsizbad");
}
claw_snd_sys_validate_rsp(dev, p_ctlbk, 0);
- printk(KERN_INFO "%s: CLAW device %.8s: System validate "
- "completed.\n", dev->name, temp_ws_name);
- printk("%s: sys Validate Rsize:%d Wsize:%d\n", dev->name,
- p_sysval->read_frame_size, p_sysval->write_frame_size);
+ dev_info(tdev,
+ "CLAW device %.8s: System validate"
+ " completed.\n", temp_ws_name);
+ dev_info(tdev,
+ "%s: sys Validate Rsize:%d Wsize:%d\n",
+ dev->name, p_sysval->read_frame_size,
+ p_sysval->write_frame_size);
privptr->system_validate_comp = 1;
if (strncmp(p_env->api_type, WS_APPL_NAME_PACKED, 6) == 0)
p_env->packing = PACKING_ASK;
@@ -2092,8 +2115,10 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
break;
case SYSTEM_VALIDATE_RESPONSE:
p_sysval = (struct sysval *)&(p_ctlbk->data);
- printk("%s: Recv Sys Validate Resp: Vers=%d,Corr=%d,RC=%d,"
- "WS name=%.8s,Host name=%.8s\n",
+ dev_info(tdev,
+ "Settings for %s validated (version=%d, "
+ "remote device=%d, rc=%d, adapter name=%.8s, "
+ "host name=%.8s)\n",
dev->name,
p_ctlbk->version,
p_ctlbk->correlator,
@@ -2102,41 +2127,39 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
p_sysval->host_name);
switch (p_ctlbk->rc) {
case 0:
- printk(KERN_INFO "%s: CLAW device "
- "%.8s: System validate "
- "completed.\n",
- dev->name, temp_ws_name);
+ dev_info(tdev, "%s: CLAW device "
+ "%.8s: System validate completed.\n",
+ dev->name, temp_ws_name);
if (privptr->system_validate_comp == 0)
claw_strt_conn_req(dev);
privptr->system_validate_comp = 1;
break;
case CLAW_RC_NAME_MISMATCH:
- printk(KERN_INFO "%s: Sys Validate "
- "Resp : Host, WS name is "
- "mismatch\n",
- dev->name);
+ dev_warn(tdev, "Validating %s failed because of"
+ " a host or adapter name mismatch\n",
+ dev->name);
break;
case CLAW_RC_WRONG_VERSION:
- printk(KERN_INFO "%s: Sys Validate "
- "Resp : Wrong version\n",
+ dev_warn(tdev, "Validating %s failed because of a"
+ " version conflict\n",
dev->name);
break;
case CLAW_RC_HOST_RCV_TOO_SMALL:
- printk(KERN_INFO "%s: Sys Validate "
- "Resp : bad frame size\n",
+ dev_warn(tdev, "Validating %s failed because of a"
+ " frame size conflict\n",
dev->name);
break;
default:
- printk(KERN_INFO "%s: Sys Validate "
- "error code=%d \n",
- dev->name, p_ctlbk->rc);
+ dev_warn(tdev, "The communication peer of %s rejected"
+ " the connection\n",
+ dev->name);
break;
}
break;
case CONNECTION_REQUEST:
p_connect = (struct conncmd *)&(p_ctlbk->data);
- printk(KERN_INFO "%s: Recv Conn Req: Vers=%d,link_id=%d,"
+ dev_info(tdev, "%s: Recv Conn Req: Vers=%d,link_id=%d,"
"Corr=%d,HOST appl=%.8s,WS appl=%.8s\n",
dev->name,
p_ctlbk->version,
@@ -2146,21 +2169,21 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
p_connect->WS_name);
if (privptr->active_link_ID != 0) {
claw_snd_disc(dev, p_ctlbk);
- printk(KERN_INFO "%s: Conn Req error : "
- "already logical link is active \n",
+ dev_info(tdev, "%s rejected a connection request"
+ " because it is already active\n",
dev->name);
}
if (p_ctlbk->linkid != 1) {
claw_snd_disc(dev, p_ctlbk);
- printk(KERN_INFO "%s: Conn Req error : "
- "req logical link id is not 1\n",
+ dev_info(tdev, "%s rejected a request to open multiple"
+ " connections\n",
dev->name);
}
rc = find_link(dev, p_connect->host_name, p_connect->WS_name);
if (rc != 0) {
claw_snd_disc(dev, p_ctlbk);
- printk(KERN_INFO "%s: Conn Resp error: "
- "req appl name does not match\n",
+ dev_info(tdev, "%s rejected a connection request"
+ " because of a type mismatch\n",
dev->name);
}
claw_send_control(dev,
@@ -2172,7 +2195,7 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
p_env->packing = PACK_SEND;
claw_snd_conn_req(dev, 0);
}
- printk(KERN_INFO "%s: CLAW device %.8s: Connection "
+ dev_info(tdev, "%s: CLAW device %.8s: Connection "
"completed link_id=%d.\n",
dev->name, temp_ws_name,
p_ctlbk->linkid);
@@ -2182,7 +2205,7 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
break;
case CONNECTION_RESPONSE:
p_connect = (struct conncmd *)&(p_ctlbk->data);
- printk(KERN_INFO "%s: Revc Conn Resp: Vers=%d,link_id=%d,"
+ dev_info(tdev, "%s: Recv Conn Resp: Vers=%d,link_id=%d,"
"Corr=%d,RC=%d,Host appl=%.8s, WS appl=%.8s\n",
dev->name,
p_ctlbk->version,
@@ -2193,16 +2216,18 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
p_connect->WS_name);
if (p_ctlbk->rc != 0) {
- printk(KERN_INFO "%s: Conn Resp error: rc=%d \n",
- dev->name, p_ctlbk->rc);
+ dev_warn(tdev, "The communication peer of %s rejected"
+ " a connection request\n",
+ dev->name);
return 1;
}
rc = find_link(dev,
p_connect->host_name, p_connect->WS_name);
if (rc != 0) {
claw_snd_disc(dev, p_ctlbk);
- printk(KERN_INFO "%s: Conn Resp error: "
- "req appl name does not match\n",
+ dev_warn(tdev, "The communication peer of %s"
+ " rejected a connection "
+ "request because of a type mismatch\n",
dev->name);
}
/* should be until CONNECTION_CONFIRM */
@@ -2210,7 +2235,8 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
break;
case CONNECTION_CONFIRM:
p_connect = (struct conncmd *)&(p_ctlbk->data);
- printk(KERN_INFO "%s: Recv Conn Confirm:Vers=%d,link_id=%d,"
+ dev_info(tdev,
+ "%s: Recv Conn Confirm:Vers=%d,link_id=%d,"
"Corr=%d,Host appl=%.8s,WS appl=%.8s\n",
dev->name,
p_ctlbk->version,
@@ -2221,21 +2247,21 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
if (p_ctlbk->linkid == -(privptr->active_link_ID)) {
privptr->active_link_ID = p_ctlbk->linkid;
if (p_env->packing > PACKING_ASK) {
- printk(KERN_INFO "%s: Confirmed Now packing\n",
- dev->name);
+ dev_info(tdev,
+ "%s: Confirmed Now packing\n", dev->name);
p_env->packing = DO_PACKED;
}
p_ch = &privptr->channel[WRITE];
wake_up(&p_ch->wait);
} else {
- printk(KERN_INFO "%s: Conn confirm: "
- "unexpected linkid=%d \n",
+ dev_warn(tdev, "Activating %s failed because of"
+ " an incorrect link ID=%d\n",
dev->name, p_ctlbk->linkid);
claw_snd_disc(dev, p_ctlbk);
}
break;
case DISCONNECT:
- printk(KERN_INFO "%s: Disconnect: "
+ dev_info(tdev, "%s: Disconnect: "
"Vers=%d,link_id=%d,Corr=%d\n",
dev->name, p_ctlbk->version,
p_ctlbk->linkid, p_ctlbk->correlator);
@@ -2247,12 +2273,13 @@ claw_process_control( struct net_device *dev, struct ccwbk * p_ccw)
privptr->active_link_ID = 0;
break;
case CLAW_ERROR:
- printk(KERN_INFO "%s: CLAW ERROR detected\n",
+ dev_warn(tdev, "The communication peer of %s failed\n",
dev->name);
break;
default:
- printk(KERN_INFO "%s: Unexpected command code=%d \n",
- dev->name, p_ctlbk->command);
+ dev_warn(tdev, "The communication peer of %s sent"
+ " an unknown command code\n",
+ dev->name);
break;
}
@@ -2294,12 +2321,14 @@ claw_send_control(struct net_device *dev, __u8 type, __u8 link,
memcpy(&p_sysval->host_name, local_name, 8);
memcpy(&p_sysval->WS_name, remote_name, 8);
if (privptr->p_env->packing > 0) {
- p_sysval->read_frame_size=DEF_PACK_BUFSIZE;
- p_sysval->write_frame_size=DEF_PACK_BUFSIZE;
+ p_sysval->read_frame_size = DEF_PACK_BUFSIZE;
+ p_sysval->write_frame_size = DEF_PACK_BUFSIZE;
} else {
/* how big is the biggest group of packets */
- p_sysval->read_frame_size=privptr->p_env->read_size;
- p_sysval->write_frame_size=privptr->p_env->write_size;
+ p_sysval->read_frame_size =
+ privptr->p_env->read_size;
+ p_sysval->write_frame_size =
+ privptr->p_env->write_size;
}
memset(&p_sysval->reserved, 0x00, 4);
break;
@@ -2485,7 +2514,6 @@ unpack_read(struct net_device *dev )
p_dev = &privptr->channel[READ].cdev->dev;
p_env = privptr->p_env;
p_this_ccw=privptr->p_read_active_first;
- i=0;
while (p_this_ccw!=NULL && p_this_ccw->header.flag!=CLAW_PENDING) {
pack_off = 0;
p = 0;
@@ -2511,8 +2539,10 @@ unpack_read(struct net_device *dev )
mtc_this_frm=1;
if (p_this_ccw->header.length!=
privptr->p_env->read_size ) {
- printk(KERN_INFO " %s: Invalid frame detected "
- "length is %02x\n" ,
+ dev_warn(p_dev,
+ "The communication peer of %s"
+ " sent a faulty"
+ " frame of length %02x\n",
dev->name, p_this_ccw->header.length);
}
}
@@ -2544,7 +2574,7 @@ unpack_next:
goto NextFrame;
p_packd = p_this_ccw->p_buffer+pack_off;
p_packh = (struct clawph *) p_packd;
- if ((p_packh->len == 0) || /* all done with this frame? */
+ if ((p_packh->len == 0) || /* done with this frame? */
(p_packh->flag != 0))
goto NextFrame;
bytes_to_mov = p_packh->len;
@@ -2594,9 +2624,9 @@ unpack_next:
netif_rx(skb);
}
else {
+ dev_info(p_dev, "Allocating a buffer for"
+ " incoming data failed\n");
privptr->stats.rx_dropped++;
- printk(KERN_WARNING "%s: %s() low on memory\n",
- dev->name,__func__);
}
privptr->mtc_offset=0;
privptr->mtc_logical_link=-1;
@@ -2720,8 +2750,8 @@ claw_strt_out_IO( struct net_device *dev )
if (test_and_set_bit(0, (void *)&p_ch->IO_active) == 0) {
parm = (unsigned long) p_ch;
CLAW_DBF_TEXT(2, trace, "StWrtIO");
- rc = ccw_device_start (p_ch->cdev,&p_first_ccw->write, parm,
- 0xff, 0);
+ rc = ccw_device_start(p_ch->cdev, &p_first_ccw->write, parm,
+ 0xff, 0);
if (rc != 0) {
ccw_check_return_code(p_ch->cdev, rc);
}
@@ -2816,22 +2846,26 @@ claw_free_netdevice(struct net_device * dev, int free_dev)
* Initialize everything of the net device except the name and the
* channel structs.
*/
+static const struct net_device_ops claw_netdev_ops = {
+ .ndo_open = claw_open,
+ .ndo_stop = claw_release,
+ .ndo_get_stats = claw_stats,
+ .ndo_start_xmit = claw_tx,
+ .ndo_change_mtu = claw_change_mtu,
+};
+
static void
claw_init_netdevice(struct net_device * dev)
{
CLAW_DBF_TEXT(2, setup, "init_dev");
CLAW_DBF_TEXT_(2, setup, "%s", dev->name);
dev->mtu = CLAW_DEFAULT_MTU_SIZE;
- dev->hard_start_xmit = claw_tx;
- dev->open = claw_open;
- dev->stop = claw_release;
- dev->get_stats = claw_stats;
- dev->change_mtu = claw_change_mtu;
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->type = ARPHRD_SLIP;
dev->tx_queue_len = 1300;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+ dev->netdev_ops = &claw_netdev_ops;
CLAW_DBF_TEXT(2, setup, "initok");
return;
}
@@ -2880,8 +2914,8 @@ claw_new_device(struct ccwgroup_device *cgdev)
int ret;
struct ccw_dev_id dev_id;
- printk(KERN_INFO "claw: add for %s\n",
- dev_name(&cgdev->cdev[READ]->dev));
+ dev_info(&cgdev->dev, "add for %s\n",
+ dev_name(&cgdev->cdev[READ]->dev));
CLAW_DBF_TEXT(2, setup, "new_dev");
privptr = cgdev->dev.driver_data;
cgdev->cdev[READ]->dev.driver_data = privptr;
@@ -2897,29 +2931,28 @@ claw_new_device(struct ccwgroup_device *cgdev)
if (ret == 0)
ret = add_channel(cgdev->cdev[1],1,privptr);
if (ret != 0) {
- printk(KERN_WARNING
- "add channel failed with ret = %d\n", ret);
+ dev_warn(&cgdev->dev, "Creating a CLAW group device"
+ " failed with error code %d\n", ret);
goto out;
}
ret = ccw_device_set_online(cgdev->cdev[READ]);
if (ret != 0) {
- printk(KERN_WARNING
- "claw: ccw_device_set_online %s READ failed "
- "with ret = %d\n", dev_name(&cgdev->cdev[READ]->dev),
- ret);
+ dev_warn(&cgdev->dev,
+ "Setting the read subchannel online"
+ " failed with error code %d\n", ret);
goto out;
}
ret = ccw_device_set_online(cgdev->cdev[WRITE]);
if (ret != 0) {
- printk(KERN_WARNING
- "claw: ccw_device_set_online %s WRITE failed "
- "with ret = %d\n", dev_name(&cgdev->cdev[WRITE]->dev),
- ret);
+ dev_warn(&cgdev->dev,
+ "Setting the write subchannel online "
+ "failed with error code %d\n", ret);
goto out;
}
dev = alloc_netdev(0,"claw%d",claw_init_netdevice);
if (!dev) {
- printk(KERN_WARNING "%s:alloc_netdev failed\n",__func__);
+ dev_warn(&cgdev->dev,
+ "Activating the CLAW device failed\n");
goto out;
}
dev->ml_priv = privptr;
@@ -2947,13 +2980,13 @@ claw_new_device(struct ccwgroup_device *cgdev)
privptr->channel[WRITE].ndev = dev;
privptr->p_env->ndev = dev;
- printk(KERN_INFO "%s:readsize=%d writesize=%d "
+ dev_info(&cgdev->dev, "%s:readsize=%d writesize=%d "
"readbuffer=%d writebuffer=%d read=0x%04x write=0x%04x\n",
dev->name, p_env->read_size,
p_env->write_size, p_env->read_buffers,
p_env->write_buffers, p_env->devno[READ],
p_env->devno[WRITE]);
- printk(KERN_INFO "%s:host_name:%.8s, adapter_name "
+ dev_info(&cgdev->dev, "%s:host_name:%.8s, adapter_name "
":%.8s api_type: %.8s\n",
dev->name, p_env->host_name,
p_env->adapter_name , p_env->api_type);
@@ -2997,8 +3030,8 @@ claw_shutdown_device(struct ccwgroup_device *cgdev)
ndev = priv->channel[READ].ndev;
if (ndev) {
/* Close the device */
- printk(KERN_INFO
- "%s: shuting down \n",ndev->name);
+ dev_info(&cgdev->dev, "%s: shutting down \n",
+ ndev->name);
if (ndev->flags & IFF_RUNNING)
ret = claw_release(ndev);
ndev->flags &=~IFF_RUNNING;
@@ -3023,8 +3056,7 @@ claw_remove_device(struct ccwgroup_device *cgdev)
CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev));
priv = cgdev->dev.driver_data;
BUG_ON(!priv);
- printk(KERN_INFO "claw: %s() called %s will be removed.\n",
- __func__, dev_name(&cgdev->cdev[0]->dev));
+ dev_info(&cgdev->dev, " will be removed.\n");
if (cgdev->state == CCWGROUP_ONLINE)
claw_shutdown_device(cgdev);
claw_remove_files(&cgdev->dev);
@@ -3063,7 +3095,8 @@ claw_hname_show(struct device *dev, struct device_attribute *attr, char *buf)
}
static ssize_t
-claw_hname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_hname_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -3100,7 +3133,8 @@ claw_adname_show(struct device *dev, struct device_attribute *attr, char *buf)
}
static ssize_t
-claw_adname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_adname_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -3138,7 +3172,8 @@ claw_apname_show(struct device *dev, struct device_attribute *attr, char *buf)
}
static ssize_t
-claw_apname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_apname_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -3185,7 +3220,8 @@ claw_wbuff_show(struct device *dev, struct device_attribute *attr, char *buf)
}
static ssize_t
-claw_wbuff_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_wbuff_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env * p_env;
@@ -3226,7 +3262,8 @@ claw_rbuff_show(struct device *dev, struct device_attribute *attr, char *buf)
}
static ssize_t
-claw_rbuff_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+claw_rbuff_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct claw_privbk *priv;
struct claw_env *p_env;
@@ -3289,7 +3326,7 @@ claw_cleanup(void)
{
unregister_cu3088_discipline(&claw_group_driver);
claw_unregister_debug_facility();
- printk(KERN_INFO "claw: Driver unloaded\n");
+ pr_info("Driver unloaded\n");
}
@@ -3303,12 +3340,12 @@ static int __init
claw_init(void)
{
int ret = 0;
- printk(KERN_INFO "claw: starting driver\n");
+ pr_info("Loading %s\n", version);
ret = claw_register_debug_facility();
if (ret) {
- printk(KERN_WARNING "claw: %s() debug_register failed %d\n",
- __func__,ret);
+ pr_err("Registering with the S/390 debug feature"
+ " failed with error code %d\n", ret);
return ret;
}
CLAW_DBF_TEXT(2, setup, "init_mod");
@@ -3316,8 +3353,8 @@ claw_init(void)
if (ret) {
CLAW_DBF_TEXT(2, setup, "init_bad");
claw_unregister_debug_facility();
- printk(KERN_WARNING "claw; %s() cu3088 register failed %d\n",
- __func__,ret);
+ pr_err("Registering with the cu3088 device driver failed "
+ "with error code %d\n", ret);
}
return ret;
}
diff --git a/drivers/s390/net/ctcm_fsms.c b/drivers/s390/net/ctcm_fsms.c
index f29c7086fc19..4ded9ac2c5ef 100644
--- a/drivers/s390/net/ctcm_fsms.c
+++ b/drivers/s390/net/ctcm_fsms.c
@@ -410,9 +410,8 @@ static void chx_rx(fsm_instance *fi, int event, void *arg)
priv->stats.rx_length_errors++;
goto again;
}
- block_len -= 2;
- if (block_len > 0) {
- *((__u16 *)skb->data) = block_len;
+ if (block_len > 2) {
+ *((__u16 *)skb->data) = block_len - 2;
ctcm_unpack_skb(ch, skb);
}
again:
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 2678573becec..77f4033a0f4f 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -105,7 +105,8 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
return;
}
pskb->protocol = ntohs(header->type);
- if (header->length <= LL_HEADER_LENGTH) {
+ if ((header->length <= LL_HEADER_LENGTH) ||
+ (len <= LL_HEADER_LENGTH)) {
if (!(ch->logflags & LOG_FLAG_ILLEGALSIZE)) {
CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
"%s(%s): Illegal packet size %d(%d,%d)"
@@ -167,11 +168,9 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
if (len > 0) {
skb_pull(pskb, header->length);
if (skb_tailroom(pskb) < LL_HEADER_LENGTH) {
- if (!(ch->logflags & LOG_FLAG_OVERRUN)) {
- CTCM_DBF_DEV_NAME(TRACE, dev,
- "Overrun in ctcm_unpack_skb");
- ch->logflags |= LOG_FLAG_OVERRUN;
- }
+ CTCM_DBF_DEV_NAME(TRACE, dev,
+ "Overrun in ctcm_unpack_skb");
+ ch->logflags |= LOG_FLAG_OVERRUN;
return;
}
skb_put(pskb, LL_HEADER_LENGTH);
@@ -906,11 +905,11 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
}
if (ctcm_test_and_set_busy(dev))
- return -EBUSY;
+ return NETDEV_TX_BUSY;
dev->trans_start = jiffies;
if (ctcm_transmit_skb(priv->channel[WRITE], skb) != 0)
- return 1;
+ return NETDEV_TX_BUSY;
return 0;
}
@@ -1099,12 +1098,24 @@ static void ctcm_free_netdevice(struct net_device *dev)
struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv);
+static const struct net_device_ops ctcm_netdev_ops = {
+ .ndo_open = ctcm_open,
+ .ndo_stop = ctcm_close,
+ .ndo_get_stats = ctcm_stats,
+ .ndo_change_mtu = ctcm_change_mtu,
+ .ndo_start_xmit = ctcm_tx,
+};
+
+static const struct net_device_ops ctcm_mpc_netdev_ops = {
+ .ndo_open = ctcm_open,
+ .ndo_stop = ctcm_close,
+ .ndo_get_stats = ctcm_stats,
+ .ndo_change_mtu = ctcm_change_mtu,
+ .ndo_start_xmit = ctcmpc_tx,
+};
+
void static ctcm_dev_setup(struct net_device *dev)
{
- dev->open = ctcm_open;
- dev->stop = ctcm_close;
- dev->get_stats = ctcm_stats;
- dev->change_mtu = ctcm_change_mtu;
dev->type = ARPHRD_SLIP;
dev->tx_queue_len = 100;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
@@ -1157,12 +1168,12 @@ static struct net_device *ctcm_init_netdevice(struct ctcm_priv *priv)
dev->mtu = MPC_BUFSIZE_DEFAULT -
TH_HEADER_LENGTH - PDU_HEADER_LENGTH;
- dev->hard_start_xmit = ctcmpc_tx;
+ dev->netdev_ops = &ctcm_mpc_netdev_ops;
dev->hard_header_len = TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
priv->buffer_size = MPC_BUFSIZE_DEFAULT;
} else {
dev->mtu = CTCM_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2;
- dev->hard_start_xmit = ctcm_tx;
+ dev->netdev_ops = &ctcm_netdev_ops;
dev->hard_header_len = LL_HEADER_LENGTH + 2;
}
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c
index 3db5f846bbf6..781e18be7e8f 100644
--- a/drivers/s390/net/ctcm_mpc.c
+++ b/drivers/s390/net/ctcm_mpc.c
@@ -393,7 +393,6 @@ int ctc_mpc_alloc_channel(int port_num, void (*callback)(int, int))
} else {
/* there are problems...bail out */
/* there may be a state mismatch so restart */
- grp->port_persist = 1;
fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
grp->allocchan_callback_retries = 0;
}
@@ -699,11 +698,9 @@ static void ctcmpc_send_sweep_resp(struct channel *rch)
return;
done:
- if (rc != 0) {
- grp->in_sweep = 0;
- ctcm_clear_busy_do(dev);
- fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
- }
+ grp->in_sweep = 0;
+ ctcm_clear_busy_do(dev);
+ fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
return;
}
@@ -1118,7 +1115,6 @@ static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb)
if (unlikely(fsm_getstate(grp->fsm) != MPCG_STATE_READY))
goto done;
- pdu_last_seen = 0;
while ((pskb->len > 0) && !pdu_last_seen) {
curr_pdu = (struct pdu *)pskb->data;
@@ -1396,8 +1392,7 @@ static void mpc_action_go_inop(fsm_instance *fi, int event, void *arg)
CTCM_FUNTAIL, dev->name);
if ((grp->saved_state != MPCG_STATE_RESET) ||
/* dealloc_channel has been called */
- ((grp->saved_state == MPCG_STATE_RESET) &&
- (grp->port_persist == 0)))
+ (grp->port_persist == 0))
fsm_deltimer(&priv->restart_timer);
wch = priv->channel[WRITE];
@@ -1917,10 +1912,8 @@ static void mpc_action_doxid7(fsm_instance *fsm, int event, void *arg)
if (priv)
grp = priv->mpcg;
- if (grp == NULL) {
- fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
+ if (grp == NULL)
return;
- }
for (direction = READ; direction <= WRITE; direction++) {
struct channel *ch = priv->channel[direction];
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 49c3bfa1afd7..a45bc24eb5f9 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -39,6 +39,7 @@
#include <linux/in.h>
#include <linux/igmp.h>
#include <linux/delay.h>
+#include <linux/kthread.h>
#include <net/arp.h>
#include <net/ip.h>
@@ -1259,7 +1260,6 @@ lcs_register_mc_addresses(void *data)
struct in_device *in4_dev;
card = (struct lcs_card *) data;
- daemonize("regipm");
if (!lcs_do_run_thread(card, LCS_SET_MC_THREAD))
return 0;
@@ -1562,7 +1562,7 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
if (skb == NULL) {
card->stats.tx_dropped++;
card->stats.tx_errors++;
- return -EIO;
+ return 0;
}
if (card->state != DEV_STATE_UP) {
dev_kfree_skb(skb);
@@ -1587,7 +1587,7 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
card->tx_buffer = lcs_get_buffer(&card->write);
if (card->tx_buffer == NULL) {
card->stats.tx_dropped++;
- rc = -EBUSY;
+ rc = NETDEV_TX_BUSY;
goto out;
}
card->tx_buffer->callback = lcs_txbuffer_cb;
@@ -1753,11 +1753,10 @@ lcs_start_kernel_thread(struct work_struct *work)
struct lcs_card *card = container_of(work, struct lcs_card, kernel_thread_starter);
LCS_DBF_TEXT(5, trace, "krnthrd");
if (lcs_do_start_thread(card, LCS_RECOVERY_THREAD))
- kernel_thread(lcs_recovery, (void *) card, SIGCHLD);
+ kthread_run(lcs_recovery, card, "lcs_recover");
#ifdef CONFIG_IP_MULTICAST
if (lcs_do_start_thread(card, LCS_SET_MC_THREAD))
- kernel_thread(lcs_register_mc_addresses,
- (void *) card, SIGCHLD);
+ kthread_run(lcs_register_mc_addresses, card, "regipm");
#endif
}
@@ -2101,6 +2100,20 @@ lcs_register_netdev(struct ccwgroup_device *ccwgdev)
/**
* lcs_new_device will be called by setting the group device online.
*/
+static const struct net_device_ops lcs_netdev_ops = {
+ .ndo_open = lcs_open_device,
+ .ndo_stop = lcs_stop_device,
+ .ndo_get_stats = lcs_getstats,
+ .ndo_start_xmit = lcs_start_xmit,
+};
+
+static const struct net_device_ops lcs_mc_netdev_ops = {
+ .ndo_open = lcs_open_device,
+ .ndo_stop = lcs_stop_device,
+ .ndo_get_stats = lcs_getstats,
+ .ndo_start_xmit = lcs_start_xmit,
+ .ndo_set_multicast_list = lcs_set_multicast_list,
+};
static int
lcs_new_device(struct ccwgroup_device *ccwgdev)
@@ -2168,14 +2181,11 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
goto out;
card->dev = dev;
card->dev->ml_priv = card;
- card->dev->open = lcs_open_device;
- card->dev->stop = lcs_stop_device;
- card->dev->hard_start_xmit = lcs_start_xmit;
- card->dev->get_stats = lcs_getstats;
+ card->dev->netdev_ops = &lcs_netdev_ops;
memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH);
#ifdef CONFIG_IP_MULTICAST
if (!lcs_check_multicast_support(card))
- card->dev->set_multicast_list = lcs_set_multicast_list;
+ card->dev->netdev_ops = &lcs_mc_netdev_ops;
#endif
netdev_out:
lcs_set_allowed_threads(card,0xffffffff);
@@ -2258,7 +2268,6 @@ lcs_recovery(void *ptr)
int rc;
card = (struct lcs_card *) ptr;
- daemonize("lcs_recover");
LCS_DBF_TEXT(4, trace, "recover1");
if (!lcs_do_run_thread(card, LCS_RECOVERY_THREAD))
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index 930e2fc2a011..be716e45f7ac 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1312,7 +1312,7 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
if (netiucv_test_and_set_busy(dev)) {
IUCV_DBF_TEXT(data, 2, "EBUSY from netiucv_tx\n");
- return -EBUSY;
+ return NETDEV_TX_BUSY;
}
dev->trans_start = jiffies;
rc = netiucv_transmit_skb(privptr->conn, skb) != 0;
@@ -1876,20 +1876,24 @@ static void netiucv_free_netdevice(struct net_device *dev)
/**
* Initialize a net device. (Called from kernel in alloc_netdev())
*/
+static const struct net_device_ops netiucv_netdev_ops = {
+ .ndo_open = netiucv_open,
+ .ndo_stop = netiucv_close,
+ .ndo_get_stats = netiucv_stats,
+ .ndo_start_xmit = netiucv_tx,
+ .ndo_change_mtu = netiucv_change_mtu,
+};
+
static void netiucv_setup_netdevice(struct net_device *dev)
{
dev->mtu = NETIUCV_MTU_DEFAULT;
- dev->hard_start_xmit = netiucv_tx;
- dev->open = netiucv_open;
- dev->stop = netiucv_close;
- dev->get_stats = netiucv_stats;
- dev->change_mtu = netiucv_change_mtu;
dev->destructor = netiucv_free_netdevice;
dev->hard_header_len = NETIUCV_HDRLEN;
dev->addr_len = 0;
dev->type = ARPHRD_SLIP;
dev->tx_queue_len = NETIUCV_QUEUELEN_DEFAULT;
dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+ dev->netdev_ops = &netiucv_netdev_ops;
}
/**
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index e0c45574b0c8..447e1d19581a 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -134,6 +134,7 @@ struct qeth_perf_stats {
unsigned int sg_skbs_rx;
unsigned int sg_frags_rx;
unsigned int sg_alloc_page_rx;
+ unsigned int tx_csum;
};
/* Routing stuff */
@@ -403,7 +404,6 @@ struct qeth_qdio_q {
/* possible types of qeth large_send support */
enum qeth_large_send_types {
QETH_LARGE_SEND_NO,
- QETH_LARGE_SEND_EDDP,
QETH_LARGE_SEND_TSO,
};
@@ -838,11 +838,9 @@ int qeth_get_cast_type(struct qeth_card *, struct sk_buff *);
int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int);
int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int);
int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *,
- struct sk_buff *, struct qeth_hdr *, int,
- struct qeth_eddp_context *, int, int);
+ struct sk_buff *, struct qeth_hdr *, int, int, int);
int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *,
- struct sk_buff *, struct qeth_hdr *,
- int, struct qeth_eddp_context *);
+ struct sk_buff *, struct qeth_hdr *, int);
int qeth_core_get_stats_count(struct net_device *);
void qeth_core_get_ethtool_stats(struct net_device *,
struct ethtool_stats *, u64 *);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index d1b5bebea7fb..c827d69b5a91 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -17,7 +17,6 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/ip.h>
-#include <linux/ipv6.h>
#include <linux/tcp.h>
#include <linux/mii.h>
#include <linux/kthread.h>
@@ -26,7 +25,6 @@
#include <asm/io.h>
#include "qeth_core.h"
-#include "qeth_core_offl.h"
struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS] = {
/* define dbf - Name, Pages, Areas, Maxlen, Level, View, Handle */
@@ -285,17 +283,6 @@ int qeth_set_large_send(struct qeth_card *card,
netif_tx_disable(card->dev);
card->options.large_send = type;
switch (card->options.large_send) {
- case QETH_LARGE_SEND_EDDP:
- if (card->info.type != QETH_CARD_TYPE_IQD) {
- card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
- NETIF_F_HW_CSUM;
- } else {
- card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
- NETIF_F_HW_CSUM);
- card->options.large_send = QETH_LARGE_SEND_NO;
- rc = -EOPNOTSUPP;
- }
- break;
case QETH_LARGE_SEND_TSO:
if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
@@ -956,7 +943,6 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
dev_kfree_skb_any(skb);
skb = skb_dequeue(&buf->skb_list);
}
- qeth_eddp_buf_release_contexts(buf);
for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i) {
if (buf->buffer->element[i].addr && buf->is_header[i])
kmem_cache_free(qeth_core_header_cache,
@@ -1690,7 +1676,7 @@ int qeth_send_control_data(struct qeth_card *card, int len,
int rc;
unsigned long flags;
struct qeth_reply *reply = NULL;
- unsigned long timeout;
+ unsigned long timeout, event_timeout;
struct qeth_ipa_cmd *cmd;
QETH_DBF_TEXT(TRACE, 2, "sendctl");
@@ -1715,9 +1701,10 @@ int qeth_send_control_data(struct qeth_card *card, int len,
qeth_prepare_control_data(card, len, iob);
if (IS_IPA(iob->data))
- timeout = jiffies + QETH_IPA_TIMEOUT;
+ event_timeout = QETH_IPA_TIMEOUT;
else
- timeout = jiffies + QETH_TIMEOUT;
+ event_timeout = QETH_TIMEOUT;
+ timeout = jiffies + event_timeout;
QETH_DBF_TEXT(TRACE, 6, "noirqpnd");
spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
@@ -1745,7 +1732,7 @@ int qeth_send_control_data(struct qeth_card *card, int len,
if ((cmd->hdr.command == IPA_CMD_SETIP) &&
(cmd->hdr.prot_version == QETH_PROT_IPV4)) {
if (!wait_event_timeout(reply->wait_q,
- atomic_read(&reply->received), timeout))
+ atomic_read(&reply->received), event_timeout))
goto time_err;
} else {
while (!atomic_read(&reply->received)) {
@@ -2693,40 +2680,21 @@ static int qeth_handle_send_error(struct qeth_card *card,
struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err)
{
int sbalf15 = buffer->buffer->element[15].flags & 0xff;
- int cc = qdio_err & 3;
QETH_DBF_TEXT(TRACE, 6, "hdsnderr");
qeth_check_qdio_errors(buffer->buffer, qdio_err, "qouterr");
- switch (cc) {
- case 0:
- if (qdio_err) {
- QETH_DBF_TEXT(TRACE, 1, "lnkfail");
- QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
- QETH_DBF_TEXT_(TRACE, 1, "%04x %02x",
- (u16)qdio_err, (u8)sbalf15);
- return QETH_SEND_ERROR_LINK_FAILURE;
- }
+
+ if (!qdio_err)
return QETH_SEND_ERROR_NONE;
- case 2:
- if (qdio_err & QDIO_ERROR_SIGA_BUSY) {
- QETH_DBF_TEXT(TRACE, 1, "SIGAcc2B");
- QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
- return QETH_SEND_ERROR_KICK_IT;
- }
- if ((sbalf15 >= 15) && (sbalf15 <= 31))
- return QETH_SEND_ERROR_RETRY;
- return QETH_SEND_ERROR_LINK_FAILURE;
- /* look at qdio_error and sbalf 15 */
- case 1:
- QETH_DBF_TEXT(TRACE, 1, "SIGAcc1");
- QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
- return QETH_SEND_ERROR_LINK_FAILURE;
- case 3:
- default:
- QETH_DBF_TEXT(TRACE, 1, "SIGAcc3");
- QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
- return QETH_SEND_ERROR_KICK_IT;
- }
+
+ if ((sbalf15 >= 15) && (sbalf15 <= 31))
+ return QETH_SEND_ERROR_RETRY;
+
+ QETH_DBF_TEXT(TRACE, 1, "lnkfail");
+ QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
+ QETH_DBF_TEXT_(TRACE, 1, "%04x %02x",
+ (u16)qdio_err, (u8)sbalf15);
+ return QETH_SEND_ERROR_LINK_FAILURE;
}
/*
@@ -2862,10 +2830,14 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
qeth_get_micros() -
queue->card->perf_stats.outbound_do_qdio_start_time;
if (rc) {
+ queue->card->stats.tx_errors += count;
+ /* ignore temporary SIGA errors without busy condition */
+ if (rc == QDIO_ERROR_SIGA_TARGET)
+ return;
QETH_DBF_TEXT(TRACE, 2, "flushbuf");
QETH_DBF_TEXT_(TRACE, 2, " err%d", rc);
QETH_DBF_TEXT_(TRACE, 2, "%s", CARD_DDEV_ID(queue->card));
- queue->card->stats.tx_errors += count;
+
/* this must not happen under normal circumstances. if it
* happens something is really wrong -> recover */
qeth_schedule_recovery(queue->card);
@@ -2940,13 +2912,7 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
}
for (i = first_element; i < (first_element + count); ++i) {
buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
- /*we only handle the KICK_IT error by doing a recovery */
- if (qeth_handle_send_error(card, buffer, qdio_error)
- == QETH_SEND_ERROR_KICK_IT){
- netif_stop_queue(card->dev);
- qeth_schedule_recovery(card);
- return;
- }
+ qeth_handle_send_error(card, buffer, qdio_error);
qeth_clear_output_buffer(queue, buffer);
}
atomic_sub(count, &queue->used_buffers);
@@ -3187,11 +3153,9 @@ static inline int qeth_fill_buffer(struct qeth_qdio_out_q *queue,
int qeth_do_send_packet_fast(struct qeth_card *card,
struct qeth_qdio_out_q *queue, struct sk_buff *skb,
struct qeth_hdr *hdr, int elements_needed,
- struct qeth_eddp_context *ctx, int offset, int hd_len)
+ int offset, int hd_len)
{
struct qeth_qdio_out_buffer *buffer;
- int buffers_needed = 0;
- int flush_cnt = 0;
int index;
/* spin until we get the queue ... */
@@ -3206,27 +3170,11 @@ int qeth_do_send_packet_fast(struct qeth_card *card,
*/
if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY)
goto out;
- if (ctx == NULL)
- queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
+ queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
QDIO_MAX_BUFFERS_PER_Q;
- else {
- buffers_needed = qeth_eddp_check_buffers_for_context(queue,
- ctx);
- if (buffers_needed < 0)
- goto out;
- queue->next_buf_to_fill =
- (queue->next_buf_to_fill + buffers_needed) %
- QDIO_MAX_BUFFERS_PER_Q;
- }
atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
- if (ctx == NULL) {
- qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
- qeth_flush_buffers(queue, index, 1);
- } else {
- flush_cnt = qeth_eddp_fill_buffer(queue, ctx, index);
- WARN_ON(buffers_needed != flush_cnt);
- qeth_flush_buffers(queue, index, flush_cnt);
- }
+ qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
+ qeth_flush_buffers(queue, index, 1);
return 0;
out:
atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
@@ -3236,7 +3184,7 @@ EXPORT_SYMBOL_GPL(qeth_do_send_packet_fast);
int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
struct sk_buff *skb, struct qeth_hdr *hdr,
- int elements_needed, struct qeth_eddp_context *ctx)
+ int elements_needed)
{
struct qeth_qdio_out_buffer *buffer;
int start_index;
@@ -3262,53 +3210,32 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
qeth_switch_to_packing_if_needed(queue);
if (queue->do_pack) {
do_pack = 1;
- if (ctx == NULL) {
- /* does packet fit in current buffer? */
- if ((QETH_MAX_BUFFER_ELEMENTS(card) -
- buffer->next_element_to_fill) < elements_needed) {
- /* ... no -> set state PRIMED */
- atomic_set(&buffer->state,
- QETH_QDIO_BUF_PRIMED);
- flush_count++;
- queue->next_buf_to_fill =
- (queue->next_buf_to_fill + 1) %
- QDIO_MAX_BUFFERS_PER_Q;
- buffer = &queue->bufs[queue->next_buf_to_fill];
- /* we did a step forward, so check buffer state
- * again */
- if (atomic_read(&buffer->state) !=
- QETH_QDIO_BUF_EMPTY){
- qeth_flush_buffers(queue, start_index,
+ /* does packet fit in current buffer? */
+ if ((QETH_MAX_BUFFER_ELEMENTS(card) -
+ buffer->next_element_to_fill) < elements_needed) {
+ /* ... no -> set state PRIMED */
+ atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
+ flush_count++;
+ queue->next_buf_to_fill =
+ (queue->next_buf_to_fill + 1) %
+ QDIO_MAX_BUFFERS_PER_Q;
+ buffer = &queue->bufs[queue->next_buf_to_fill];
+ /* we did a step forward, so check buffer state
+ * again */
+ if (atomic_read(&buffer->state) !=
+ QETH_QDIO_BUF_EMPTY) {
+ qeth_flush_buffers(queue, start_index,
flush_count);
- atomic_set(&queue->state,
+ atomic_set(&queue->state,
QETH_OUT_Q_UNLOCKED);
- return -EBUSY;
- }
- }
- } else {
- /* check if we have enough elements (including following
- * free buffers) to handle eddp context */
- if (qeth_eddp_check_buffers_for_context(queue, ctx)
- < 0) {
- rc = -EBUSY;
- goto out;
+ return -EBUSY;
}
}
}
- if (ctx == NULL)
- tmp = qeth_fill_buffer(queue, buffer, skb, hdr, -1, 0);
- else {
- tmp = qeth_eddp_fill_buffer(queue, ctx,
- queue->next_buf_to_fill);
- if (tmp < 0) {
- rc = -EBUSY;
- goto out;
- }
- }
+ tmp = qeth_fill_buffer(queue, buffer, skb, hdr, -1, 0);
queue->next_buf_to_fill = (queue->next_buf_to_fill + tmp) %
QDIO_MAX_BUFFERS_PER_Q;
flush_count += tmp;
-out:
if (flush_count)
qeth_flush_buffers(queue, start_index, flush_count);
else if (!atomic_read(&queue->set_pci_flags_count))
@@ -4327,6 +4254,7 @@ static struct {
/* 30 */{"tx count"},
{"tx do_QDIO time"},
{"tx do_QDIO count"},
+ {"tx csum"},
};
int qeth_core_get_stats_count(struct net_device *dev)
@@ -4378,6 +4306,7 @@ void qeth_core_get_ethtool_stats(struct net_device *dev,
data[30] = card->perf_stats.outbound_cnt;
data[31] = card->perf_stats.outbound_do_qdio_time;
data[32] = card->perf_stats.outbound_do_qdio_cnt;
+ data[33] = card->perf_stats.tx_csum;
}
EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats);
diff --git a/drivers/s390/net/qeth_core_offl.c b/drivers/s390/net/qeth_core_offl.c
deleted file mode 100644
index 4080126ca48c..000000000000
--- a/drivers/s390/net/qeth_core_offl.c
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * drivers/s390/net/qeth_core_offl.c
- *
- * Copyright IBM Corp. 2007
- * Author(s): Thomas Spatzier <tspat@de.ibm.com>,
- * Frank Blaschka <frank.blaschka@de.ibm.com>
- */
-
-#include <linux/errno.h>
-#include <linux/ip.h>
-#include <linux/inetdevice.h>
-#include <linux/netdevice.h>
-#include <linux/kernel.h>
-#include <linux/tcp.h>
-#include <net/tcp.h>
-#include <linux/skbuff.h>
-
-#include <net/ip.h>
-#include <net/ip6_checksum.h>
-
-#include "qeth_core.h"
-#include "qeth_core_mpc.h"
-#include "qeth_core_offl.h"
-
-int qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *queue,
- struct qeth_eddp_context *ctx)
-{
- int index = queue->next_buf_to_fill;
- int elements_needed = ctx->num_elements;
- int elements_in_buffer;
- int skbs_in_buffer;
- int buffers_needed = 0;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpcbfc");
- while (elements_needed > 0) {
- buffers_needed++;
- if (atomic_read(&queue->bufs[index].state) !=
- QETH_QDIO_BUF_EMPTY)
- return -EBUSY;
-
- elements_in_buffer = QETH_MAX_BUFFER_ELEMENTS(queue->card) -
- queue->bufs[index].next_element_to_fill;
- skbs_in_buffer = elements_in_buffer / ctx->elements_per_skb;
- elements_needed -= skbs_in_buffer * ctx->elements_per_skb;
- index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
- }
- return buffers_needed;
-}
-
-static void qeth_eddp_free_context(struct qeth_eddp_context *ctx)
-{
- int i;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpfctx");
- for (i = 0; i < ctx->num_pages; ++i)
- free_page((unsigned long)ctx->pages[i]);
- kfree(ctx->pages);
- kfree(ctx->elements);
- kfree(ctx);
-}
-
-
-static void qeth_eddp_get_context(struct qeth_eddp_context *ctx)
-{
- atomic_inc(&ctx->refcnt);
-}
-
-void qeth_eddp_put_context(struct qeth_eddp_context *ctx)
-{
- if (atomic_dec_return(&ctx->refcnt) == 0)
- qeth_eddp_free_context(ctx);
-}
-EXPORT_SYMBOL_GPL(qeth_eddp_put_context);
-
-void qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
-{
- struct qeth_eddp_context_reference *ref;
-
- QETH_DBF_TEXT(TRACE, 6, "eddprctx");
- while (!list_empty(&buf->ctx_list)) {
- ref = list_entry(buf->ctx_list.next,
- struct qeth_eddp_context_reference, list);
- qeth_eddp_put_context(ref->ctx);
- list_del(&ref->list);
- kfree(ref);
- }
-}
-
-static int qeth_eddp_buf_ref_context(struct qeth_qdio_out_buffer *buf,
- struct qeth_eddp_context *ctx)
-{
- struct qeth_eddp_context_reference *ref;
-
- QETH_DBF_TEXT(TRACE, 6, "eddprfcx");
- ref = kmalloc(sizeof(struct qeth_eddp_context_reference), GFP_ATOMIC);
- if (ref == NULL)
- return -ENOMEM;
- qeth_eddp_get_context(ctx);
- ref->ctx = ctx;
- list_add_tail(&ref->list, &buf->ctx_list);
- return 0;
-}
-
-int qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
- struct qeth_eddp_context *ctx, int index)
-{
- struct qeth_qdio_out_buffer *buf = NULL;
- struct qdio_buffer *buffer;
- int elements = ctx->num_elements;
- int element = 0;
- int flush_cnt = 0;
- int must_refcnt = 1;
- int i;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpfibu");
- while (elements > 0) {
- buf = &queue->bufs[index];
- if (atomic_read(&buf->state) != QETH_QDIO_BUF_EMPTY) {
- /* normally this should not happen since we checked for
- * available elements in qeth_check_elements_for_context
- */
- if (element == 0)
- return -EBUSY;
- else {
- QETH_DBF_MESSAGE(2, "could only partially fill"
- "eddp buffer!\n");
- goto out;
- }
- }
- /* check if the whole next skb fits into current buffer */
- if ((QETH_MAX_BUFFER_ELEMENTS(queue->card) -
- buf->next_element_to_fill)
- < ctx->elements_per_skb){
- /* no -> go to next buffer */
- atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
- index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
- flush_cnt++;
- /* new buffer, so we have to add ctx to buffer'ctx_list
- * and increment ctx's refcnt */
- must_refcnt = 1;
- continue;
- }
- if (must_refcnt) {
- must_refcnt = 0;
- if (qeth_eddp_buf_ref_context(buf, ctx)) {
- goto out_check;
- }
- }
- buffer = buf->buffer;
- /* fill one skb into buffer */
- for (i = 0; i < ctx->elements_per_skb; ++i) {
- if (ctx->elements[element].length != 0) {
- buffer->element[buf->next_element_to_fill].
- addr = ctx->elements[element].addr;
- buffer->element[buf->next_element_to_fill].
- length = ctx->elements[element].length;
- buffer->element[buf->next_element_to_fill].
- flags = ctx->elements[element].flags;
- buf->next_element_to_fill++;
- }
- element++;
- elements--;
- }
- }
-out_check:
- if (!queue->do_pack) {
- QETH_DBF_TEXT(TRACE, 6, "fillbfnp");
- /* set state to PRIMED -> will be flushed */
- if (buf->next_element_to_fill > 0) {
- atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
- flush_cnt++;
- }
- } else {
- if (queue->card->options.performance_stats)
- queue->card->perf_stats.skbs_sent_pack++;
- QETH_DBF_TEXT(TRACE, 6, "fillbfpa");
- if (buf->next_element_to_fill >=
- QETH_MAX_BUFFER_ELEMENTS(queue->card)) {
- /*
- * packed buffer if full -> set state PRIMED
- * -> will be flushed
- */
- atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
- flush_cnt++;
- }
- }
-out:
- return flush_cnt;
-}
-
-static void qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
- struct qeth_eddp_data *eddp, int data_len)
-{
- u8 *page;
- int page_remainder;
- int page_offset;
- int pkt_len;
- struct qeth_eddp_element *element;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpcrsh");
- page = ctx->pages[ctx->offset >> PAGE_SHIFT];
- page_offset = ctx->offset % PAGE_SIZE;
- element = &ctx->elements[ctx->num_elements];
- pkt_len = eddp->nhl + eddp->thl + data_len;
- /* FIXME: layer2 and VLAN !!! */
- if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
- pkt_len += ETH_HLEN;
- if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
- pkt_len += VLAN_HLEN;
- /* does complete packet fit in current page ? */
- page_remainder = PAGE_SIZE - page_offset;
- if (page_remainder < (sizeof(struct qeth_hdr) + pkt_len)) {
- /* no -> go to start of next page */
- ctx->offset += page_remainder;
- page = ctx->pages[ctx->offset >> PAGE_SHIFT];
- page_offset = 0;
- }
- memcpy(page + page_offset, &eddp->qh, sizeof(struct qeth_hdr));
- element->addr = page + page_offset;
- element->length = sizeof(struct qeth_hdr);
- ctx->offset += sizeof(struct qeth_hdr);
- page_offset += sizeof(struct qeth_hdr);
- /* add mac header (?) */
- if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
- memcpy(page + page_offset, &eddp->mac, ETH_HLEN);
- element->length += ETH_HLEN;
- ctx->offset += ETH_HLEN;
- page_offset += ETH_HLEN;
- }
- /* add VLAN tag */
- if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) {
- memcpy(page + page_offset, &eddp->vlan, VLAN_HLEN);
- element->length += VLAN_HLEN;
- ctx->offset += VLAN_HLEN;
- page_offset += VLAN_HLEN;
- }
- /* add network header */
- memcpy(page + page_offset, (u8 *)&eddp->nh, eddp->nhl);
- element->length += eddp->nhl;
- eddp->nh_in_ctx = page + page_offset;
- ctx->offset += eddp->nhl;
- page_offset += eddp->nhl;
- /* add transport header */
- memcpy(page + page_offset, (u8 *)&eddp->th, eddp->thl);
- element->length += eddp->thl;
- eddp->th_in_ctx = page + page_offset;
- ctx->offset += eddp->thl;
-}
-
-static void qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp,
- int len, __wsum *hcsum)
-{
- struct skb_frag_struct *frag;
- int left_in_frag;
- int copy_len;
- u8 *src;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpcdtc");
- if (skb_shinfo(eddp->skb)->nr_frags == 0) {
- skb_copy_from_linear_data_offset(eddp->skb, eddp->skb_offset,
- dst, len);
- *hcsum = csum_partial(eddp->skb->data + eddp->skb_offset, len,
- *hcsum);
- eddp->skb_offset += len;
- } else {
- while (len > 0) {
- if (eddp->frag < 0) {
- /* we're in skb->data */
- left_in_frag = (eddp->skb->len -
- eddp->skb->data_len)
- - eddp->skb_offset;
- src = eddp->skb->data + eddp->skb_offset;
- } else {
- frag = &skb_shinfo(eddp->skb)->frags[
- eddp->frag];
- left_in_frag = frag->size - eddp->frag_offset;
- src = (u8 *)((page_to_pfn(frag->page) <<
- PAGE_SHIFT) + frag->page_offset +
- eddp->frag_offset);
- }
- if (left_in_frag <= 0) {
- eddp->frag++;
- eddp->frag_offset = 0;
- continue;
- }
- copy_len = min(left_in_frag, len);
- memcpy(dst, src, copy_len);
- *hcsum = csum_partial(src, copy_len, *hcsum);
- dst += copy_len;
- eddp->frag_offset += copy_len;
- eddp->skb_offset += copy_len;
- len -= copy_len;
- }
- }
-}
-
-static void qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
- struct qeth_eddp_data *eddp, int data_len, __wsum hcsum)
-{
- u8 *page;
- int page_remainder;
- int page_offset;
- struct qeth_eddp_element *element;
- int first_lap = 1;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpcsdt");
- page = ctx->pages[ctx->offset >> PAGE_SHIFT];
- page_offset = ctx->offset % PAGE_SIZE;
- element = &ctx->elements[ctx->num_elements];
- while (data_len) {
- page_remainder = PAGE_SIZE - page_offset;
- if (page_remainder < data_len) {
- qeth_eddp_copy_data_tcp(page + page_offset, eddp,
- page_remainder, &hcsum);
- element->length += page_remainder;
- if (first_lap)
- element->flags = SBAL_FLAGS_FIRST_FRAG;
- else
- element->flags = SBAL_FLAGS_MIDDLE_FRAG;
- ctx->num_elements++;
- element++;
- data_len -= page_remainder;
- ctx->offset += page_remainder;
- page = ctx->pages[ctx->offset >> PAGE_SHIFT];
- page_offset = 0;
- element->addr = page + page_offset;
- } else {
- qeth_eddp_copy_data_tcp(page + page_offset, eddp,
- data_len, &hcsum);
- element->length += data_len;
- if (!first_lap)
- element->flags = SBAL_FLAGS_LAST_FRAG;
- ctx->num_elements++;
- ctx->offset += data_len;
- data_len = 0;
- }
- first_lap = 0;
- }
- ((struct tcphdr *)eddp->th_in_ctx)->check = csum_fold(hcsum);
-}
-
-static __wsum qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp,
- int data_len)
-{
- __wsum phcsum; /* pseudo header checksum */
-
- QETH_DBF_TEXT(TRACE, 5, "eddpckt4");
- eddp->th.tcp.h.check = 0;
- /* compute pseudo header checksum */
- phcsum = csum_tcpudp_nofold(eddp->nh.ip4.h.saddr, eddp->nh.ip4.h.daddr,
- eddp->thl + data_len, IPPROTO_TCP, 0);
- /* compute checksum of tcp header */
- return csum_partial(&eddp->th, eddp->thl, phcsum);
-}
-
-static __wsum qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp,
- int data_len)
-{
- __be32 proto;
- __wsum phcsum; /* pseudo header checksum */
-
- QETH_DBF_TEXT(TRACE, 5, "eddpckt6");
- eddp->th.tcp.h.check = 0;
- /* compute pseudo header checksum */
- phcsum = csum_partial(&eddp->nh.ip6.h.saddr,
- sizeof(struct in6_addr), 0);
- phcsum = csum_partial(&eddp->nh.ip6.h.daddr,
- sizeof(struct in6_addr), phcsum);
- proto = htonl(IPPROTO_TCP);
- phcsum = csum_partial(&proto, sizeof(u32), phcsum);
- return phcsum;
-}
-
-static struct qeth_eddp_data *qeth_eddp_create_eddp_data(struct qeth_hdr *qh,
- u8 *nh, u8 nhl, u8 *th, u8 thl)
-{
- struct qeth_eddp_data *eddp;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpcrda");
- eddp = kzalloc(sizeof(struct qeth_eddp_data), GFP_ATOMIC);
- if (eddp) {
- eddp->nhl = nhl;
- eddp->thl = thl;
- memcpy(&eddp->qh, qh, sizeof(struct qeth_hdr));
- memcpy(&eddp->nh, nh, nhl);
- memcpy(&eddp->th, th, thl);
- eddp->frag = -1; /* initially we're in skb->data */
- }
- return eddp;
-}
-
-static void __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
- struct qeth_eddp_data *eddp)
-{
- struct tcphdr *tcph;
- int data_len;
- __wsum hcsum;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpftcp");
- eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl;
- if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
- eddp->skb_offset += sizeof(struct ethhdr);
- if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
- eddp->skb_offset += VLAN_HLEN;
- }
- tcph = tcp_hdr(eddp->skb);
- while (eddp->skb_offset < eddp->skb->len) {
- data_len = min((int)skb_shinfo(eddp->skb)->gso_size,
- (int)(eddp->skb->len - eddp->skb_offset));
- /* prepare qdio hdr */
- if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
- eddp->qh.hdr.l2.pkt_length = data_len + ETH_HLEN +
- eddp->nhl + eddp->thl;
- if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
- eddp->qh.hdr.l2.pkt_length += VLAN_HLEN;
- } else
- eddp->qh.hdr.l3.length = data_len + eddp->nhl +
- eddp->thl;
- /* prepare ip hdr */
- if (eddp->skb->protocol == htons(ETH_P_IP)) {
- eddp->nh.ip4.h.tot_len = htons(data_len + eddp->nhl +
- eddp->thl);
- eddp->nh.ip4.h.check = 0;
- eddp->nh.ip4.h.check =
- ip_fast_csum((u8 *)&eddp->nh.ip4.h,
- eddp->nh.ip4.h.ihl);
- } else
- eddp->nh.ip6.h.payload_len = htons(data_len +
- eddp->thl);
- /* prepare tcp hdr */
- if (data_len == (eddp->skb->len - eddp->skb_offset)) {
- /* last segment -> set FIN and PSH flags */
- eddp->th.tcp.h.fin = tcph->fin;
- eddp->th.tcp.h.psh = tcph->psh;
- }
- if (eddp->skb->protocol == htons(ETH_P_IP))
- hcsum = qeth_eddp_check_tcp4_hdr(eddp, data_len);
- else
- hcsum = qeth_eddp_check_tcp6_hdr(eddp, data_len);
- /* fill the next segment into the context */
- qeth_eddp_create_segment_hdrs(ctx, eddp, data_len);
- qeth_eddp_create_segment_data_tcp(ctx, eddp, data_len, hcsum);
- if (eddp->skb_offset >= eddp->skb->len)
- break;
- /* prepare headers for next round */
- if (eddp->skb->protocol == htons(ETH_P_IP))
- eddp->nh.ip4.h.id = htons(ntohs(eddp->nh.ip4.h.id) + 1);
- eddp->th.tcp.h.seq = htonl(ntohl(eddp->th.tcp.h.seq) +
- data_len);
- }
-}
-
-static int qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
- struct sk_buff *skb, struct qeth_hdr *qhdr)
-{
- struct qeth_eddp_data *eddp = NULL;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpficx");
- /* create our segmentation headers and copy original headers */
- if (skb->protocol == htons(ETH_P_IP))
- eddp = qeth_eddp_create_eddp_data(qhdr,
- skb_network_header(skb),
- ip_hdrlen(skb),
- skb_transport_header(skb),
- tcp_hdrlen(skb));
- else
- eddp = qeth_eddp_create_eddp_data(qhdr,
- skb_network_header(skb),
- sizeof(struct ipv6hdr),
- skb_transport_header(skb),
- tcp_hdrlen(skb));
-
- if (eddp == NULL) {
- QETH_DBF_TEXT(TRACE, 2, "eddpfcnm");
- return -ENOMEM;
- }
- if (qhdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
- skb_set_mac_header(skb, sizeof(struct qeth_hdr));
- memcpy(&eddp->mac, eth_hdr(skb), ETH_HLEN);
- if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) {
- eddp->vlan[0] = skb->protocol;
- eddp->vlan[1] = htons(vlan_tx_tag_get(skb));
- }
- }
- /* the next flags will only be set on the last segment */
- eddp->th.tcp.h.fin = 0;
- eddp->th.tcp.h.psh = 0;
- eddp->skb = skb;
- /* begin segmentation and fill context */
- __qeth_eddp_fill_context_tcp(ctx, eddp);
- kfree(eddp);
- return 0;
-}
-
-static void qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx,
- struct sk_buff *skb, int hdr_len)
-{
- int skbs_per_page;
-
- QETH_DBF_TEXT(TRACE, 5, "eddpcanp");
- /* can we put multiple skbs in one page? */
- skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len);
- if (skbs_per_page > 1) {
- ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) /
- skbs_per_page + 1;
- ctx->elements_per_skb = 1;
- } else {
- /* no -> how many elements per skb? */
- ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len +
- PAGE_SIZE) >> PAGE_SHIFT;
- ctx->num_pages = ctx->elements_per_skb *
- (skb_shinfo(skb)->gso_segs + 1);
- }
- ctx->num_elements = ctx->elements_per_skb *
- (skb_shinfo(skb)->gso_segs + 1);
-}
-
-static struct qeth_eddp_context *qeth_eddp_create_context_generic(
- struct qeth_card *card, struct sk_buff *skb, int hdr_len)
-{
- struct qeth_eddp_context *ctx = NULL;
- u8 *addr;
- int i;
-
- QETH_DBF_TEXT(TRACE, 5, "creddpcg");
- /* create the context and allocate pages */
- ctx = kzalloc(sizeof(struct qeth_eddp_context), GFP_ATOMIC);
- if (ctx == NULL) {
- QETH_DBF_TEXT(TRACE, 2, "ceddpcn1");
- return NULL;
- }
- ctx->type = QETH_LARGE_SEND_EDDP;
- qeth_eddp_calc_num_pages(ctx, skb, hdr_len);
- if (ctx->elements_per_skb > QETH_MAX_BUFFER_ELEMENTS(card)) {
- QETH_DBF_TEXT(TRACE, 2, "ceddpcis");
- kfree(ctx);
- return NULL;
- }
- ctx->pages = kcalloc(ctx->num_pages, sizeof(u8 *), GFP_ATOMIC);
- if (ctx->pages == NULL) {
- QETH_DBF_TEXT(TRACE, 2, "ceddpcn2");
- kfree(ctx);
- return NULL;
- }
- for (i = 0; i < ctx->num_pages; ++i) {
- addr = (u8 *)get_zeroed_page(GFP_ATOMIC);
- if (addr == NULL) {
- QETH_DBF_TEXT(TRACE, 2, "ceddpcn3");
- ctx->num_pages = i;
- qeth_eddp_free_context(ctx);
- return NULL;
- }
- ctx->pages[i] = addr;
- }
- ctx->elements = kcalloc(ctx->num_elements,
- sizeof(struct qeth_eddp_element), GFP_ATOMIC);
- if (ctx->elements == NULL) {
- QETH_DBF_TEXT(TRACE, 2, "ceddpcn4");
- qeth_eddp_free_context(ctx);
- return NULL;
- }
- /* reset num_elements; will be incremented again in fill_buffer to
- * reflect number of actually used elements */
- ctx->num_elements = 0;
- return ctx;
-}
-
-static struct qeth_eddp_context *qeth_eddp_create_context_tcp(
- struct qeth_card *card, struct sk_buff *skb,
- struct qeth_hdr *qhdr)
-{
- struct qeth_eddp_context *ctx = NULL;
-
- QETH_DBF_TEXT(TRACE, 5, "creddpct");
- if (skb->protocol == htons(ETH_P_IP))
- ctx = qeth_eddp_create_context_generic(card, skb,
- (sizeof(struct qeth_hdr) +
- ip_hdrlen(skb) +
- tcp_hdrlen(skb)));
- else if (skb->protocol == htons(ETH_P_IPV6))
- ctx = qeth_eddp_create_context_generic(card, skb,
- sizeof(struct qeth_hdr) + sizeof(struct ipv6hdr) +
- tcp_hdrlen(skb));
- else
- QETH_DBF_TEXT(TRACE, 2, "cetcpinv");
-
- if (ctx == NULL) {
- QETH_DBF_TEXT(TRACE, 2, "creddpnl");
- return NULL;
- }
- if (qeth_eddp_fill_context_tcp(ctx, skb, qhdr)) {
- QETH_DBF_TEXT(TRACE, 2, "ceddptfe");
- qeth_eddp_free_context(ctx);
- return NULL;
- }
- atomic_set(&ctx->refcnt, 1);
- return ctx;
-}
-
-struct qeth_eddp_context *qeth_eddp_create_context(struct qeth_card *card,
- struct sk_buff *skb, struct qeth_hdr *qhdr,
- unsigned char sk_protocol)
-{
- QETH_DBF_TEXT(TRACE, 5, "creddpc");
- switch (sk_protocol) {
- case IPPROTO_TCP:
- return qeth_eddp_create_context_tcp(card, skb, qhdr);
- default:
- QETH_DBF_TEXT(TRACE, 2, "eddpinvp");
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(qeth_eddp_create_context);
-
-void qeth_tso_fill_header(struct qeth_card *card, struct qeth_hdr *qhdr,
- struct sk_buff *skb)
-{
- struct qeth_hdr_tso *hdr = (struct qeth_hdr_tso *)qhdr;
- struct tcphdr *tcph = tcp_hdr(skb);
- struct iphdr *iph = ip_hdr(skb);
- struct ipv6hdr *ip6h = ipv6_hdr(skb);
-
- QETH_DBF_TEXT(TRACE, 5, "tsofhdr");
-
- /*fix header to TSO values ...*/
- hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO;
- /*set values which are fix for the first approach ...*/
- hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
- hdr->ext.imb_hdr_no = 1;
- hdr->ext.hdr_type = 1;
- hdr->ext.hdr_version = 1;
- hdr->ext.hdr_len = 28;
- /*insert non-fix values */
- hdr->ext.mss = skb_shinfo(skb)->gso_size;
- hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
- hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
- sizeof(struct qeth_hdr_tso));
- tcph->check = 0;
- if (skb->protocol == ETH_P_IPV6) {
- ip6h->payload_len = 0;
- tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
- 0, IPPROTO_TCP, 0);
- } else {
- /*OSA want us to set these values ...*/
- tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
- 0, IPPROTO_TCP, 0);
- iph->tot_len = 0;
- iph->check = 0;
- }
-}
-EXPORT_SYMBOL_GPL(qeth_tso_fill_header);
-
-void qeth_tx_csum(struct sk_buff *skb)
-{
- int tlen;
- if (skb->protocol == htons(ETH_P_IP)) {
- tlen = ntohs(ip_hdr(skb)->tot_len) - (ip_hdr(skb)->ihl << 2);
- switch (ip_hdr(skb)->protocol) {
- case IPPROTO_TCP:
- tcp_hdr(skb)->check = 0;
- tcp_hdr(skb)->check = csum_tcpudp_magic(
- ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
- tlen, ip_hdr(skb)->protocol,
- skb_checksum(skb, skb_transport_offset(skb),
- tlen, 0));
- break;
- case IPPROTO_UDP:
- udp_hdr(skb)->check = 0;
- udp_hdr(skb)->check = csum_tcpudp_magic(
- ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
- tlen, ip_hdr(skb)->protocol,
- skb_checksum(skb, skb_transport_offset(skb),
- tlen, 0));
- break;
- }
- } else if (skb->protocol == htons(ETH_P_IPV6)) {
- switch (ipv6_hdr(skb)->nexthdr) {
- case IPPROTO_TCP:
- tcp_hdr(skb)->check = 0;
- tcp_hdr(skb)->check = csum_ipv6_magic(
- &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
- ipv6_hdr(skb)->payload_len,
- ipv6_hdr(skb)->nexthdr,
- skb_checksum(skb, skb_transport_offset(skb),
- ipv6_hdr(skb)->payload_len, 0));
- break;
- case IPPROTO_UDP:
- udp_hdr(skb)->check = 0;
- udp_hdr(skb)->check = csum_ipv6_magic(
- &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
- ipv6_hdr(skb)->payload_len,
- ipv6_hdr(skb)->nexthdr,
- skb_checksum(skb, skb_transport_offset(skb),
- ipv6_hdr(skb)->payload_len, 0));
- break;
- }
- }
-}
-EXPORT_SYMBOL_GPL(qeth_tx_csum);
diff --git a/drivers/s390/net/qeth_core_offl.h b/drivers/s390/net/qeth_core_offl.h
deleted file mode 100644
index 86bf7df8cf16..000000000000
--- a/drivers/s390/net/qeth_core_offl.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * drivers/s390/net/qeth_core_offl.h
- *
- * Copyright IBM Corp. 2007
- * Author(s): Thomas Spatzier <tspat@de.ibm.com>,
- * Frank Blaschka <frank.blaschka@de.ibm.com>
- */
-
-#ifndef __QETH_CORE_OFFL_H__
-#define __QETH_CORE_OFFL_H__
-
-struct qeth_eddp_element {
- u32 flags;
- u32 length;
- void *addr;
-};
-
-struct qeth_eddp_context {
- atomic_t refcnt;
- enum qeth_large_send_types type;
- int num_pages; /* # of allocated pages */
- u8 **pages; /* pointers to pages */
- int offset; /* offset in ctx during creation */
- int num_elements; /* # of required 'SBALEs' */
- struct qeth_eddp_element *elements; /* array of 'SBALEs' */
- int elements_per_skb; /* # of 'SBALEs' per skb **/
-};
-
-struct qeth_eddp_context_reference {
- struct list_head list;
- struct qeth_eddp_context *ctx;
-};
-
-struct qeth_eddp_data {
- struct qeth_hdr qh;
- struct ethhdr mac;
- __be16 vlan[2];
- union {
- struct {
- struct iphdr h;
- u8 options[40];
- } ip4;
- struct {
- struct ipv6hdr h;
- } ip6;
- } nh;
- u8 nhl;
- void *nh_in_ctx; /* address of nh within the ctx */
- union {
- struct {
- struct tcphdr h;
- u8 options[40];
- } tcp;
- } th;
- u8 thl;
- void *th_in_ctx; /* address of th within the ctx */
- struct sk_buff *skb;
- int skb_offset;
- int frag;
- int frag_offset;
-} __attribute__ ((packed));
-
-extern struct qeth_eddp_context *qeth_eddp_create_context(struct qeth_card *,
- struct sk_buff *, struct qeth_hdr *, unsigned char);
-extern void qeth_eddp_put_context(struct qeth_eddp_context *);
-extern int qeth_eddp_fill_buffer(struct qeth_qdio_out_q *,
- struct qeth_eddp_context *, int);
-extern void qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *);
-extern int qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *,
- struct qeth_eddp_context *);
-
-void qeth_tso_fill_header(struct qeth_card *, struct qeth_hdr *,
- struct sk_buff *);
-void qeth_tx_csum(struct sk_buff *skb);
-
-#endif /* __QETH_CORE_EDDP_H__ */
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index c26e842ad905..568465d7517f 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -427,8 +427,6 @@ static ssize_t qeth_dev_large_send_show(struct device *dev,
switch (card->options.large_send) {
case QETH_LARGE_SEND_NO:
return sprintf(buf, "%s\n", "no");
- case QETH_LARGE_SEND_EDDP:
- return sprintf(buf, "%s\n", "EDDP");
case QETH_LARGE_SEND_TSO:
return sprintf(buf, "%s\n", "TSO");
default:
@@ -449,8 +447,6 @@ static ssize_t qeth_dev_large_send_store(struct device *dev,
tmp = strsep((char **) &buf, "\n");
if (!strcmp(tmp, "no")) {
type = QETH_LARGE_SEND_NO;
- } else if (!strcmp(tmp, "EDDP")) {
- type = QETH_LARGE_SEND_EDDP;
} else if (!strcmp(tmp, "TSO")) {
type = QETH_LARGE_SEND_TSO;
} else {
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 07ab8a5c1c46..172031baedc1 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -21,7 +21,6 @@
#include <linux/ip.h>
#include "qeth_core.h"
-#include "qeth_core_offl.h"
static int qeth_l2_set_offline(struct ccwgroup_device *);
static int qeth_l2_stop(struct net_device *);
@@ -328,6 +327,10 @@ static void qeth_l2_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
struct qeth_vlan_vid *id;
QETH_DBF_TEXT_(TRACE, 4, "aid:%d", vid);
+ if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
+ QETH_DBF_TEXT(TRACE, 3, "aidREC");
+ return;
+ }
id = kmalloc(sizeof(struct qeth_vlan_vid), GFP_ATOMIC);
if (id) {
id->vid = vid;
@@ -344,6 +347,10 @@ static void qeth_l2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
struct qeth_card *card = dev->ml_priv;
QETH_DBF_TEXT_(TRACE, 4, "kid:%d", vid);
+ if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
+ QETH_DBF_TEXT(TRACE, 3, "kidREC");
+ return;
+ }
spin_lock_bh(&card->vlanlock);
list_for_each_entry(id, &card->vid_list, list) {
if (id->vid == vid) {
@@ -379,7 +386,8 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
dev_close(card->dev);
rtnl_unlock();
}
- if (!card->use_hard_stop) {
+ if (!card->use_hard_stop ||
+ recovery_mode) {
__u8 *mac = &card->dev->dev_addr[0];
rc = qeth_l2_send_delmac(card, mac);
QETH_DBF_TEXT_(SETUP, 2, "Lerr%d", rc);
@@ -388,7 +396,8 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
}
if (card->state == CARD_STATE_SOFTSETUP) {
qeth_l2_process_vlans(card, 1);
- if (!card->use_hard_stop)
+ if (!card->use_hard_stop ||
+ recovery_mode)
qeth_l2_del_all_mc(card);
qeth_clear_ipacmd_list(card);
card->state = CARD_STATE_HARDSETUP;
@@ -593,6 +602,10 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
}
QETH_DBF_TEXT_(TRACE, 3, "%s", CARD_BUS_ID(card));
QETH_DBF_HEX(TRACE, 3, addr->sa_data, OSA_ADDR_LEN);
+ if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
+ QETH_DBF_TEXT(TRACE, 3, "setmcREC");
+ return -ERESTARTSYS;
+ }
rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]);
if (!rc)
rc = qeth_l2_send_setmac(card, addr->sa_data);
@@ -608,6 +621,9 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
return ;
QETH_DBF_TEXT(TRACE, 3, "setmulti");
+ if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
+ (card->state != CARD_STATE_UP))
+ return;
qeth_l2_del_all_mc(card);
spin_lock_bh(&card->mclock);
for (dm = dev->mc_list; dm; dm = dm->next)
@@ -634,8 +650,6 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct qeth_qdio_out_q *queue = card->qdio.out_qs
[qeth_get_priority_queue(card, skb, ipv, cast_type)];
int tx_bytes = skb->len;
- enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
- struct qeth_eddp_context *ctx = NULL;
int data_offset = -1;
int elements_needed = 0;
int hd_len = 0;
@@ -655,14 +669,10 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
netif_stop_queue(dev);
- if (skb_is_gso(skb))
- large_send = QETH_LARGE_SEND_EDDP;
-
if (card->info.type == QETH_CARD_TYPE_OSN)
hdr = (struct qeth_hdr *)skb->data;
else {
- if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) &&
- (skb_shinfo(skb)->nr_frags == 0)) {
+ if (card->info.type == QETH_CARD_TYPE_IQD) {
new_skb = skb;
data_offset = ETH_HLEN;
hd_len = ETH_HLEN;
@@ -689,59 +699,26 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
- if (large_send == QETH_LARGE_SEND_EDDP) {
- ctx = qeth_eddp_create_context(card, new_skb, hdr,
- skb->sk->sk_protocol);
- if (ctx == NULL) {
- QETH_DBF_MESSAGE(2, "could not create eddp context\n");
- goto tx_drop;
- }
- } else {
- elements = qeth_get_elements_no(card, (void *)hdr, new_skb,
+ elements = qeth_get_elements_no(card, (void *)hdr, new_skb,
elements_needed);
- if (!elements) {
- if (data_offset >= 0)
- kmem_cache_free(qeth_core_header_cache, hdr);
- goto tx_drop;
- }
+ if (!elements) {
+ if (data_offset >= 0)
+ kmem_cache_free(qeth_core_header_cache, hdr);
+ goto tx_drop;
}
- if ((large_send == QETH_LARGE_SEND_NO) &&
- (skb->ip_summed == CHECKSUM_PARTIAL))
- qeth_tx_csum(new_skb);
-
if (card->info.type != QETH_CARD_TYPE_IQD)
rc = qeth_do_send_packet(card, queue, new_skb, hdr,
- elements, ctx);
+ elements);
else
rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr,
- elements, ctx, data_offset, hd_len);
+ elements, data_offset, hd_len);
if (!rc) {
card->stats.tx_packets++;
card->stats.tx_bytes += tx_bytes;
if (new_skb != skb)
dev_kfree_skb_any(skb);
- if (card->options.performance_stats) {
- if (large_send != QETH_LARGE_SEND_NO) {
- card->perf_stats.large_send_bytes += tx_bytes;
- card->perf_stats.large_send_cnt++;
- }
- if (skb_shinfo(new_skb)->nr_frags > 0) {
- card->perf_stats.sg_skbs_sent++;
- /* nr_frags + skb->data */
- card->perf_stats.sg_frags_sent +=
- skb_shinfo(new_skb)->nr_frags + 1;
- }
- }
-
- if (ctx != NULL) {
- qeth_eddp_put_context(ctx);
- dev_kfree_skb_any(new_skb);
- }
} else {
- if (ctx != NULL)
- qeth_eddp_put_context(ctx);
-
if (data_offset >= 0)
kmem_cache_free(qeth_core_header_cache, hdr);
@@ -878,30 +855,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
return;
}
-static int qeth_l2_ethtool_set_tso(struct net_device *dev, u32 data)
-{
- struct qeth_card *card = dev->ml_priv;
-
- if (data) {
- if (card->options.large_send == QETH_LARGE_SEND_NO) {
- card->options.large_send = QETH_LARGE_SEND_EDDP;
- dev->features |= NETIF_F_TSO;
- }
- } else {
- dev->features &= ~NETIF_F_TSO;
- card->options.large_send = QETH_LARGE_SEND_NO;
- }
- return 0;
-}
-
static struct ethtool_ops qeth_l2_ethtool_ops = {
.get_link = ethtool_op_get_link,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_hw_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = qeth_l2_ethtool_set_tso,
.get_strings = qeth_core_get_strings,
.get_ethtool_stats = qeth_core_get_ethtool_stats,
.get_stats_count = qeth_core_get_stats_count,
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 3d04920b9bb9..0ba3817cb6a7 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -19,15 +19,15 @@
#include <linux/etherdevice.h>
#include <linux/mii.h>
#include <linux/ip.h>
-#include <linux/reboot.h>
+#include <linux/ipv6.h>
#include <linux/inetdevice.h>
#include <linux/igmp.h>
#include <net/ip.h>
#include <net/arp.h>
+#include <net/ip6_checksum.h>
#include "qeth_l3.h"
-#include "qeth_core_offl.h"
static int qeth_l3_set_offline(struct ccwgroup_device *);
static int qeth_l3_recover(void *);
@@ -1038,7 +1038,7 @@ static int qeth_l3_setadapter_parms(struct qeth_card *card)
rc = qeth_query_setadapterparms(card);
if (rc) {
QETH_DBF_MESSAGE(2, "%s couldn't set adapter parameters: "
- "0x%x\n", card->gdev->dev.bus_id, rc);
+ "0x%x\n", dev_name(&card->gdev->dev), rc);
return rc;
}
if (qeth_adp_supported(card, IPA_SETADP_ALTER_MAC_ADDRESS)) {
@@ -1838,6 +1838,10 @@ static void qeth_l3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
unsigned long flags;
QETH_DBF_TEXT_(TRACE, 4, "kid:%d", vid);
+ if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
+ QETH_DBF_TEXT(TRACE, 3, "kidREC");
+ return;
+ }
spin_lock_irqsave(&card->vlanlock, flags);
/* unregister IP addresses of vlan device */
qeth_l3_free_vlan_addresses(card, vid);
@@ -2101,6 +2105,9 @@ static void qeth_l3_set_multicast_list(struct net_device *dev)
struct qeth_card *card = dev->ml_priv;
QETH_DBF_TEXT(TRACE, 3, "setmulti");
+ if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
+ (card->state != CARD_STATE_UP))
+ return;
qeth_l3_delete_mc_addresses(card);
qeth_l3_add_multicast_ipv4(card);
#ifdef CONFIG_QETH_IPV6
@@ -2577,12 +2584,63 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
}
}
+static void qeth_tso_fill_header(struct qeth_card *card,
+ struct qeth_hdr *qhdr, struct sk_buff *skb)
+{
+ struct qeth_hdr_tso *hdr = (struct qeth_hdr_tso *)qhdr;
+ struct tcphdr *tcph = tcp_hdr(skb);
+ struct iphdr *iph = ip_hdr(skb);
+ struct ipv6hdr *ip6h = ipv6_hdr(skb);
+
+ /*fix header to TSO values ...*/
+ hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO;
+ /*set values which are fix for the first approach ...*/
+ hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
+ hdr->ext.imb_hdr_no = 1;
+ hdr->ext.hdr_type = 1;
+ hdr->ext.hdr_version = 1;
+ hdr->ext.hdr_len = 28;
+ /*insert non-fix values */
+ hdr->ext.mss = skb_shinfo(skb)->gso_size;
+ hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
+ hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
+ sizeof(struct qeth_hdr_tso));
+ tcph->check = 0;
+ if (skb->protocol == ETH_P_IPV6) {
+ ip6h->payload_len = 0;
+ tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
+ 0, IPPROTO_TCP, 0);
+ } else {
+ /*OSA want us to set these values ...*/
+ tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
+ 0, IPPROTO_TCP, 0);
+ iph->tot_len = 0;
+ iph->check = 0;
+ }
+}
+
+static void qeth_tx_csum(struct sk_buff *skb)
+{
+ __wsum csum;
+ int offset;
+
+ skb_set_transport_header(skb, skb->csum_start - skb_headroom(skb));
+ offset = skb->csum_start - skb_headroom(skb);
+ BUG_ON(offset >= skb_headlen(skb));
+ csum = skb_checksum(skb, offset, skb->len - offset, 0);
+
+ offset += skb->csum_offset;
+ BUG_ON(offset + sizeof(__sum16) > skb_headlen(skb));
+ *(__sum16 *)(skb->data + offset) = csum_fold(csum);
+}
+
static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
int rc;
u16 *tag;
struct qeth_hdr *hdr = NULL;
int elements_needed = 0;
+ int elems;
struct qeth_card *card = dev->ml_priv;
struct sk_buff *new_skb = NULL;
int ipv = qeth_get_ip_version(skb);
@@ -2591,8 +2649,8 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
[qeth_get_priority_queue(card, skb, ipv, cast_type)];
int tx_bytes = skb->len;
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
- struct qeth_eddp_context *ctx = NULL;
int data_offset = -1;
+ int nr_frags;
if ((card->info.type == QETH_CARD_TYPE_IQD) &&
(skb->protocol != htons(ETH_P_IPV6)) &&
@@ -2615,6 +2673,12 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb_is_gso(skb))
large_send = card->options.large_send;
+ else
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ qeth_tx_csum(skb);
+ if (card->options.performance_stats)
+ card->perf_stats.tx_csum++;
+ }
if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) &&
(skb_shinfo(skb)->nr_frags == 0)) {
@@ -2661,12 +2725,13 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
/* fix hardware limitation: as long as we do not have sbal
- * chaining we can not send long frag lists so we temporary
- * switch to EDDP
+ * chaining we can not send long frag lists
*/
if ((large_send == QETH_LARGE_SEND_TSO) &&
- ((skb_shinfo(new_skb)->nr_frags + 2) > 16))
- large_send = QETH_LARGE_SEND_EDDP;
+ ((skb_shinfo(new_skb)->nr_frags + 2) > 16)) {
+ if (skb_linearize(new_skb))
+ goto tx_drop;
+ }
if ((large_send == QETH_LARGE_SEND_TSO) &&
(cast_type == RTN_UNSPEC)) {
@@ -2689,37 +2754,22 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
- if (large_send == QETH_LARGE_SEND_EDDP) {
- /* new_skb is not owned by a socket so we use skb to get
- * the protocol
- */
- ctx = qeth_eddp_create_context(card, new_skb, hdr,
- skb->sk->sk_protocol);
- if (ctx == NULL) {
- QETH_DBF_MESSAGE(2, "could not create eddp context\n");
- goto tx_drop;
- }
- } else {
- int elems = qeth_get_elements_no(card, (void *)hdr, new_skb,
+ elems = qeth_get_elements_no(card, (void *)hdr, new_skb,
elements_needed);
- if (!elems) {
- if (data_offset >= 0)
- kmem_cache_free(qeth_core_header_cache, hdr);
- goto tx_drop;
- }
- elements_needed += elems;
+ if (!elems) {
+ if (data_offset >= 0)
+ kmem_cache_free(qeth_core_header_cache, hdr);
+ goto tx_drop;
}
-
- if ((large_send == QETH_LARGE_SEND_NO) &&
- (new_skb->ip_summed == CHECKSUM_PARTIAL))
- qeth_tx_csum(new_skb);
+ elements_needed += elems;
+ nr_frags = skb_shinfo(new_skb)->nr_frags;
if (card->info.type != QETH_CARD_TYPE_IQD)
rc = qeth_do_send_packet(card, queue, new_skb, hdr,
- elements_needed, ctx);
+ elements_needed);
else
rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr,
- elements_needed, ctx, data_offset, 0);
+ elements_needed, data_offset, 0);
if (!rc) {
card->stats.tx_packets++;
@@ -2731,22 +2781,13 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
card->perf_stats.large_send_bytes += tx_bytes;
card->perf_stats.large_send_cnt++;
}
- if (skb_shinfo(new_skb)->nr_frags > 0) {
+ if (nr_frags) {
card->perf_stats.sg_skbs_sent++;
/* nr_frags + skb->data */
- card->perf_stats.sg_frags_sent +=
- skb_shinfo(new_skb)->nr_frags + 1;
+ card->perf_stats.sg_frags_sent += nr_frags + 1;
}
}
-
- if (ctx != NULL) {
- qeth_eddp_put_context(ctx);
- dev_kfree_skb_any(new_skb);
- }
} else {
- if (ctx != NULL)
- qeth_eddp_put_context(ctx);
-
if (data_offset >= 0)
kmem_cache_free(qeth_core_header_cache, hdr);
@@ -2841,7 +2882,7 @@ static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data)
if (data) {
if (card->options.large_send == QETH_LARGE_SEND_NO) {
if (card->info.type == QETH_CARD_TYPE_IQD)
- card->options.large_send = QETH_LARGE_SEND_EDDP;
+ return -EPERM;
else
card->options.large_send = QETH_LARGE_SEND_TSO;
dev->features |= NETIF_F_TSO;
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h
deleted file mode 100644
index d39f8b697d27..000000000000
--- a/drivers/s390/s390mach.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * drivers/s390/s390mach.h
- * S/390 data definitions for machine check processing
- *
- * S390 version
- * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Ingo Adlung (adlung@de.ibm.com)
- */
-
-#ifndef __s390mach_h
-#define __s390mach_h
-
-#include <asm/types.h>
-
-struct mci {
- __u32 sd : 1; /* 00 system damage */
- __u32 pd : 1; /* 01 instruction-processing damage */
- __u32 sr : 1; /* 02 system recovery */
- __u32 to_be_defined_1 : 1; /* 03 */
- __u32 cd : 1; /* 04 timing-facility damage */
- __u32 ed : 1; /* 05 external damage */
- __u32 to_be_defined_2 : 1; /* 06 */
- __u32 dg : 1; /* 07 degradation */
- __u32 w : 1; /* 08 warning pending */
- __u32 cp : 1; /* 09 channel-report pending */
- __u32 sp : 1; /* 10 service-processor damage */
- __u32 ck : 1; /* 11 channel-subsystem damage */
- __u32 to_be_defined_3 : 2; /* 12-13 */
- __u32 b : 1; /* 14 backed up */
- __u32 to_be_defined_4 : 1; /* 15 */
- __u32 se : 1; /* 16 storage error uncorrected */
- __u32 sc : 1; /* 17 storage error corrected */
- __u32 ke : 1; /* 18 storage-key error uncorrected */
- __u32 ds : 1; /* 19 storage degradation */
- __u32 wp : 1; /* 20 psw mwp validity */
- __u32 ms : 1; /* 21 psw mask and key validity */
- __u32 pm : 1; /* 22 psw program mask and cc validity */
- __u32 ia : 1; /* 23 psw instruction address validity */
- __u32 fa : 1; /* 24 failing storage address validity */
- __u32 to_be_defined_5 : 1; /* 25 */
- __u32 ec : 1; /* 26 external damage code validity */
- __u32 fp : 1; /* 27 floating point register validity */
- __u32 gr : 1; /* 28 general register validity */
- __u32 cr : 1; /* 29 control register validity */
- __u32 to_be_defined_6 : 1; /* 30 */
- __u32 st : 1; /* 31 storage logical validity */
- __u32 ie : 1; /* 32 indirect storage error */
- __u32 ar : 1; /* 33 access register validity */
- __u32 da : 1; /* 34 delayed access exception */
- __u32 to_be_defined_7 : 7; /* 35-41 */
- __u32 pr : 1; /* 42 tod programmable register validity */
- __u32 fc : 1; /* 43 fp control register validity */
- __u32 ap : 1; /* 44 ancillary report */
- __u32 to_be_defined_8 : 1; /* 45 */
- __u32 ct : 1; /* 46 cpu timer validity */
- __u32 cc : 1; /* 47 clock comparator validity */
- __u32 to_be_defined_9 : 16; /* 47-63 */
-};
-
-/*
- * Channel Report Word
- */
-struct crw {
- __u32 res1 : 1; /* reserved zero */
- __u32 slct : 1; /* solicited */
- __u32 oflw : 1; /* overflow */
- __u32 chn : 1; /* chained */
- __u32 rsc : 4; /* reporting source code */
- __u32 anc : 1; /* ancillary report */
- __u32 res2 : 1; /* reserved zero */
- __u32 erc : 6; /* error-recovery code */
- __u32 rsid : 16; /* reporting-source ID */
-} __attribute__ ((packed));
-
-typedef void (*crw_handler_t)(struct crw *, struct crw *, int);
-
-extern int s390_register_crw_handler(int rsc, crw_handler_t handler);
-extern void s390_unregister_crw_handler(int rsc);
-
-#define NR_RSCS 16
-
-#define CRW_RSC_MONITOR 0x2 /* monitoring facility */
-#define CRW_RSC_SCH 0x3 /* subchannel */
-#define CRW_RSC_CPATH 0x4 /* channel path */
-#define CRW_RSC_CONFIG 0x9 /* configuration-alert facility */
-#define CRW_RSC_CSS 0xB /* channel subsystem */
-
-#define CRW_ERC_EVENT 0x00 /* event information pending */
-#define CRW_ERC_AVAIL 0x01 /* available */
-#define CRW_ERC_INIT 0x02 /* initialized */
-#define CRW_ERC_TERROR 0x03 /* temporary error */
-#define CRW_ERC_IPARM 0x04 /* installed parm initialized */
-#define CRW_ERC_TERM 0x05 /* terminal */
-#define CRW_ERC_PERRN 0x06 /* perm. error, fac. not init */
-#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */
-#define CRW_ERC_PMOD 0x08 /* installed parameters modified */
-
-static inline int stcrw(struct crw *pcrw )
-{
- int ccode;
-
- __asm__ __volatile__(
- "stcrw 0(%2)\n\t"
- "ipm %0\n\t"
- "srl %0,28\n\t"
- : "=d" (ccode), "=m" (*pcrw)
- : "a" (pcrw)
- : "cc" );
- return ccode;
-}
-
-#define ED_ETR_SYNC 12 /* External damage ETR sync check */
-#define ED_ETR_SWITCH 13 /* External damage ETR switch to local */
-
-#define ED_STP_SYNC 7 /* External damage STP sync check */
-#define ED_STP_ISLAND 6 /* External damage STP island check */
-
-struct pt_regs;
-
-void s390_handle_mcck(void);
-void s390_do_machine_check(struct pt_regs *regs);
-#endif /* __s390mach */
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 8af7dfbe022c..616c60ffcf2c 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -3,7 +3,7 @@
*
* Module interface and handling of zfcp data structures.
*
- * Copyright IBM Corporation 2002, 2008
+ * Copyright IBM Corporation 2002, 2009
*/
/*
@@ -249,8 +249,8 @@ struct zfcp_port *zfcp_get_port_by_wwpn(struct zfcp_adapter *adapter,
struct zfcp_port *port;
list_for_each_entry(port, &adapter->port_list_head, list)
- if ((port->wwpn == wwpn) && !(atomic_read(&port->status) &
- (ZFCP_STATUS_PORT_NO_WWPN | ZFCP_STATUS_COMMON_REMOVE)))
+ if ((port->wwpn == wwpn) &&
+ !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE))
return port;
return NULL;
}
@@ -421,7 +421,8 @@ int zfcp_status_read_refill(struct zfcp_adapter *adapter)
while (atomic_read(&adapter->stat_miss) > 0)
if (zfcp_fsf_status_read(adapter)) {
if (atomic_read(&adapter->stat_miss) >= 16) {
- zfcp_erp_adapter_reopen(adapter, 0, 103, NULL);
+ zfcp_erp_adapter_reopen(adapter, 0, "axsref1",
+ NULL);
return 1;
}
break;
@@ -501,6 +502,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
spin_lock_init(&adapter->scsi_dbf_lock);
spin_lock_init(&adapter->rec_dbf_lock);
spin_lock_init(&adapter->req_q_lock);
+ spin_lock_init(&adapter->qdio_stat_lock);
rwlock_init(&adapter->erp_lock);
rwlock_init(&adapter->abort_lock);
@@ -522,7 +524,6 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
goto sysfs_failed;
atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
- zfcp_fc_nameserver_init(adapter);
if (!zfcp_adapter_scsi_register(adapter))
return 0;
@@ -552,6 +553,7 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
cancel_work_sync(&adapter->scan_work);
cancel_work_sync(&adapter->stat_work);
+ cancel_delayed_work_sync(&adapter->nsp.work);
zfcp_adapter_scsi_unregister(adapter);
sysfs_remove_group(&adapter->ccw_device->dev.kobj,
&zfcp_sysfs_adapter_attrs);
@@ -603,10 +605,13 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
init_waitqueue_head(&port->remove_wq);
INIT_LIST_HEAD(&port->unit_list_head);
INIT_WORK(&port->gid_pn_work, zfcp_erp_port_strategy_open_lookup);
+ INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
+ INIT_WORK(&port->rport_work, zfcp_scsi_rport_work);
port->adapter = adapter;
port->d_id = d_id;
port->wwpn = wwpn;
+ port->rport_task = RPORT_NONE;
/* mark port unusable as long as sysfs registration is not complete */
atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
@@ -620,11 +625,10 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
dev_set_drvdata(&port->sysfs_device, port);
read_lock_irq(&zfcp_data.config_lock);
- if (!(status & ZFCP_STATUS_PORT_NO_WWPN))
- if (zfcp_get_port_by_wwpn(adapter, wwpn)) {
- read_unlock_irq(&zfcp_data.config_lock);
- goto err_out_free;
- }
+ if (zfcp_get_port_by_wwpn(adapter, wwpn)) {
+ read_unlock_irq(&zfcp_data.config_lock);
+ goto err_out_free;
+ }
read_unlock_irq(&zfcp_data.config_lock);
if (device_register(&port->sysfs_device))
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 285881f07648..cfb0dcb6e3ff 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -3,7 +3,7 @@
*
* Registration and callback for the s390 common I/O layer.
*
- * Copyright IBM Corporation 2002, 2008
+ * Copyright IBM Corporation 2002, 2009
*/
#define KMSG_COMPONENT "zfcp"
@@ -72,8 +72,7 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
list_for_each_entry_safe(port, p, &port_remove_lh, list) {
list_for_each_entry_safe(unit, u, &unit_remove_lh, list) {
- if (atomic_read(&unit->status) &
- ZFCP_STATUS_UNIT_REGISTERED)
+ if (unit->device)
scsi_remove_device(unit->device);
zfcp_unit_dequeue(unit);
}
@@ -109,11 +108,12 @@ static int zfcp_ccw_set_online(struct ccw_device *ccw_device)
/* initialize request counter */
BUG_ON(!zfcp_reqlist_isempty(adapter));
adapter->req_no = 0;
+ zfcp_fc_nameserver_init(adapter);
- zfcp_erp_modify_adapter_status(adapter, 10, NULL,
+ zfcp_erp_modify_adapter_status(adapter, "ccsonl1", NULL,
ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
- zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 85,
- NULL);
+ zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
+ "ccsonl2", NULL);
zfcp_erp_wait(adapter);
up(&zfcp_data.config_sema);
flush_work(&adapter->scan_work);
@@ -137,7 +137,7 @@ static int zfcp_ccw_set_offline(struct ccw_device *ccw_device)
down(&zfcp_data.config_sema);
adapter = dev_get_drvdata(&ccw_device->dev);
- zfcp_erp_adapter_shutdown(adapter, 0, 86, NULL);
+ zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL);
zfcp_erp_wait(adapter);
zfcp_erp_thread_kill(adapter);
up(&zfcp_data.config_sema);
@@ -160,21 +160,26 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
case CIO_GONE:
dev_warn(&adapter->ccw_device->dev,
"The FCP device has been detached\n");
- zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL);
+ zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1", NULL);
break;
case CIO_NO_PATH:
dev_warn(&adapter->ccw_device->dev,
"The CHPID for the FCP device is offline\n");
- zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL);
+ zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2", NULL);
break;
case CIO_OPER:
dev_info(&adapter->ccw_device->dev,
"The FCP device is operational again\n");
- zfcp_erp_modify_adapter_status(adapter, 11, NULL,
+ zfcp_erp_modify_adapter_status(adapter, "ccnoti3", NULL,
ZFCP_STATUS_COMMON_RUNNING,
ZFCP_SET);
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
- 89, NULL);
+ "ccnoti4", NULL);
+ break;
+ case CIO_BOXED:
+ dev_warn(&adapter->ccw_device->dev,
+ "The ccw device did not respond in time.\n");
+ zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL);
break;
}
return 1;
@@ -190,7 +195,7 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev)
down(&zfcp_data.config_sema);
adapter = dev_get_drvdata(&cdev->dev);
- zfcp_erp_adapter_shutdown(adapter, 0, 90, NULL);
+ zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL);
zfcp_erp_wait(adapter);
up(&zfcp_data.config_sema);
}
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index cb6df609953e..0a1a5dd8d018 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -490,172 +490,17 @@ static const char *zfcp_rec_dbf_tags[] = {
[ZFCP_REC_DBF_ID_ACTION] = "action",
};
-static const char *zfcp_rec_dbf_ids[] = {
- [1] = "new",
- [2] = "ready",
- [3] = "kill",
- [4] = "down sleep",
- [5] = "down wakeup",
- [6] = "down sleep ecd",
- [7] = "down wakeup ecd",
- [8] = "down sleep epd",
- [9] = "down wakeup epd",
- [10] = "online",
- [11] = "operational",
- [12] = "scsi slave destroy",
- [13] = "propagate failed adapter",
- [14] = "propagate failed port",
- [15] = "block adapter",
- [16] = "unblock adapter",
- [17] = "block port",
- [18] = "unblock port",
- [19] = "block unit",
- [20] = "unblock unit",
- [21] = "unit recovery failed",
- [22] = "port recovery failed",
- [23] = "adapter recovery failed",
- [24] = "qdio queues down",
- [25] = "p2p failed",
- [26] = "nameserver lookup failed",
- [27] = "nameserver port failed",
- [28] = "link up",
- [29] = "link down",
- [30] = "link up status read",
- [31] = "open port failed",
- [32] = "",
- [33] = "close port",
- [34] = "open unit failed",
- [35] = "exclusive open unit failed",
- [36] = "shared open unit failed",
- [37] = "link down",
- [38] = "link down status read no link",
- [39] = "link down status read fdisc login",
- [40] = "link down status read firmware update",
- [41] = "link down status read unknown reason",
- [42] = "link down ecd incomplete",
- [43] = "link down epd incomplete",
- [44] = "sysfs adapter recovery",
- [45] = "sysfs port recovery",
- [46] = "sysfs unit recovery",
- [47] = "port boxed abort",
- [48] = "unit boxed abort",
- [49] = "port boxed ct",
- [50] = "port boxed close physical",
- [51] = "port boxed open unit",
- [52] = "port boxed close unit",
- [53] = "port boxed fcp",
- [54] = "unit boxed fcp",
- [55] = "port access denied",
- [56] = "",
- [57] = "",
- [58] = "",
- [59] = "unit access denied",
- [60] = "shared unit access denied open unit",
- [61] = "",
- [62] = "request timeout",
- [63] = "adisc link test reject or timeout",
- [64] = "adisc link test d_id changed",
- [65] = "adisc link test failed",
- [66] = "recovery out of memory",
- [67] = "adapter recovery repeated after state change",
- [68] = "port recovery repeated after state change",
- [69] = "unit recovery repeated after state change",
- [70] = "port recovery follow-up after successful adapter recovery",
- [71] = "adapter recovery escalation after failed adapter recovery",
- [72] = "port recovery follow-up after successful physical port "
- "recovery",
- [73] = "adapter recovery escalation after failed physical port "
- "recovery",
- [74] = "unit recovery follow-up after successful port recovery",
- [75] = "physical port recovery escalation after failed port "
- "recovery",
- [76] = "port recovery escalation after failed unit recovery",
- [77] = "",
- [78] = "duplicate request id",
- [79] = "link down",
- [80] = "exclusive read-only unit access unsupported",
- [81] = "shared read-write unit access unsupported",
- [82] = "incoming rscn",
- [83] = "incoming wwpn",
- [84] = "wka port handle not valid close port",
- [85] = "online",
- [86] = "offline",
- [87] = "ccw device gone",
- [88] = "ccw device no path",
- [89] = "ccw device operational",
- [90] = "ccw device shutdown",
- [91] = "sysfs port addition",
- [92] = "sysfs port removal",
- [93] = "sysfs adapter recovery",
- [94] = "sysfs unit addition",
- [95] = "sysfs unit removal",
- [96] = "sysfs port recovery",
- [97] = "sysfs unit recovery",
- [98] = "sequence number mismatch",
- [99] = "link up",
- [100] = "error state",
- [101] = "status read physical port closed",
- [102] = "link up status read",
- [103] = "too many failed status read buffers",
- [104] = "port handle not valid abort",
- [105] = "lun handle not valid abort",
- [106] = "port handle not valid ct",
- [107] = "port handle not valid close port",
- [108] = "port handle not valid close physical port",
- [109] = "port handle not valid open unit",
- [110] = "port handle not valid close unit",
- [111] = "lun handle not valid close unit",
- [112] = "port handle not valid fcp",
- [113] = "lun handle not valid fcp",
- [114] = "handle mismatch fcp",
- [115] = "lun not valid fcp",
- [116] = "qdio send failed",
- [117] = "version mismatch",
- [118] = "incompatible qtcb type",
- [119] = "unknown protocol status",
- [120] = "unknown fsf command",
- [121] = "no recommendation for status qualifier",
- [122] = "status read physical port closed in error",
- [123] = "fc service class not supported",
- [124] = "",
- [125] = "need newer zfcp",
- [126] = "need newer microcode",
- [127] = "arbitrated loop not supported",
- [128] = "",
- [129] = "qtcb size mismatch",
- [130] = "unknown fsf status ecd",
- [131] = "fcp request too big",
- [132] = "",
- [133] = "data direction not valid fcp",
- [134] = "command length not valid fcp",
- [135] = "status read act update",
- [136] = "status read cfdc update",
- [137] = "hbaapi port open",
- [138] = "hbaapi unit open",
- [139] = "hbaapi unit shutdown",
- [140] = "qdio error outbound",
- [141] = "scsi host reset",
- [142] = "dismissing fsf request for recovery action",
- [143] = "recovery action timed out",
- [144] = "recovery action gone",
- [145] = "recovery action being processed",
- [146] = "recovery action ready for next step",
- [147] = "qdio error inbound",
- [148] = "nameserver needed for port scan",
- [149] = "port scan",
- [150] = "ptp attach",
- [151] = "port validation failed",
-};
-
static int zfcp_rec_dbf_view_format(debug_info_t *id, struct debug_view *view,
char *buf, const char *_rec)
{
struct zfcp_rec_dbf_record *r = (struct zfcp_rec_dbf_record *)_rec;
char *p = buf;
+ char hint[ZFCP_DBF_ID_SIZE + 1];
+ memcpy(hint, r->id2, ZFCP_DBF_ID_SIZE);
+ hint[ZFCP_DBF_ID_SIZE] = 0;
zfcp_dbf_outs(&p, "tag", zfcp_rec_dbf_tags[r->id]);
- zfcp_dbf_outs(&p, "hint", zfcp_rec_dbf_ids[r->id2]);
- zfcp_dbf_out(&p, "id", "%d", r->id2);
+ zfcp_dbf_outs(&p, "hint", hint);
switch (r->id) {
case ZFCP_REC_DBF_ID_THREAD:
zfcp_dbf_out(&p, "total", "%d", r->u.thread.total);
@@ -707,7 +552,7 @@ static struct debug_view zfcp_rec_dbf_view = {
* @adapter: adapter
* This function assumes that the caller is holding erp_lock.
*/
-void zfcp_rec_dbf_event_thread(u8 id2, struct zfcp_adapter *adapter)
+void zfcp_rec_dbf_event_thread(char *id2, struct zfcp_adapter *adapter)
{
struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
unsigned long flags = 0;
@@ -723,7 +568,7 @@ void zfcp_rec_dbf_event_thread(u8 id2, struct zfcp_adapter *adapter)
spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
memset(r, 0, sizeof(*r));
r->id = ZFCP_REC_DBF_ID_THREAD;
- r->id2 = id2;
+ memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
r->u.thread.total = total;
r->u.thread.ready = ready;
r->u.thread.running = running;
@@ -737,7 +582,7 @@ void zfcp_rec_dbf_event_thread(u8 id2, struct zfcp_adapter *adapter)
* @adapter: adapter
* This function assumes that the caller does not hold erp_lock.
*/
-void zfcp_rec_dbf_event_thread_lock(u8 id2, struct zfcp_adapter *adapter)
+void zfcp_rec_dbf_event_thread_lock(char *id2, struct zfcp_adapter *adapter)
{
unsigned long flags;
@@ -746,7 +591,7 @@ void zfcp_rec_dbf_event_thread_lock(u8 id2, struct zfcp_adapter *adapter)
read_unlock_irqrestore(&adapter->erp_lock, flags);
}
-static void zfcp_rec_dbf_event_target(u8 id2, void *ref,
+static void zfcp_rec_dbf_event_target(char *id2, void *ref,
struct zfcp_adapter *adapter,
atomic_t *status, atomic_t *erp_count,
u64 wwpn, u32 d_id, u64 fcp_lun)
@@ -757,7 +602,7 @@ static void zfcp_rec_dbf_event_target(u8 id2, void *ref,
spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
memset(r, 0, sizeof(*r));
r->id = ZFCP_REC_DBF_ID_TARGET;
- r->id2 = id2;
+ memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
r->u.target.ref = (unsigned long)ref;
r->u.target.status = atomic_read(status);
r->u.target.wwpn = wwpn;
@@ -774,7 +619,8 @@ static void zfcp_rec_dbf_event_target(u8 id2, void *ref,
* @ref: additional reference (e.g. request)
* @adapter: adapter
*/
-void zfcp_rec_dbf_event_adapter(u8 id, void *ref, struct zfcp_adapter *adapter)
+void zfcp_rec_dbf_event_adapter(char *id, void *ref,
+ struct zfcp_adapter *adapter)
{
zfcp_rec_dbf_event_target(id, ref, adapter, &adapter->status,
&adapter->erp_counter, 0, 0, 0);
@@ -786,7 +632,7 @@ void zfcp_rec_dbf_event_adapter(u8 id, void *ref, struct zfcp_adapter *adapter)
* @ref: additional reference (e.g. request)
* @port: port
*/
-void zfcp_rec_dbf_event_port(u8 id, void *ref, struct zfcp_port *port)
+void zfcp_rec_dbf_event_port(char *id, void *ref, struct zfcp_port *port)
{
struct zfcp_adapter *adapter = port->adapter;
@@ -801,7 +647,7 @@ void zfcp_rec_dbf_event_port(u8 id, void *ref, struct zfcp_port *port)
* @ref: additional reference (e.g. request)
* @unit: unit
*/
-void zfcp_rec_dbf_event_unit(u8 id, void *ref, struct zfcp_unit *unit)
+void zfcp_rec_dbf_event_unit(char *id, void *ref, struct zfcp_unit *unit)
{
struct zfcp_port *port = unit->port;
struct zfcp_adapter *adapter = port->adapter;
@@ -822,7 +668,7 @@ void zfcp_rec_dbf_event_unit(u8 id, void *ref, struct zfcp_unit *unit)
* @port: port
* @unit: unit
*/
-void zfcp_rec_dbf_event_trigger(u8 id2, void *ref, u8 want, u8 need,
+void zfcp_rec_dbf_event_trigger(char *id2, void *ref, u8 want, u8 need,
void *action, struct zfcp_adapter *adapter,
struct zfcp_port *port, struct zfcp_unit *unit)
{
@@ -832,7 +678,7 @@ void zfcp_rec_dbf_event_trigger(u8 id2, void *ref, u8 want, u8 need,
spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
memset(r, 0, sizeof(*r));
r->id = ZFCP_REC_DBF_ID_TRIGGER;
- r->id2 = id2;
+ memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
r->u.trigger.ref = (unsigned long)ref;
r->u.trigger.want = want;
r->u.trigger.need = need;
@@ -855,7 +701,7 @@ void zfcp_rec_dbf_event_trigger(u8 id2, void *ref, u8 want, u8 need,
* @id2: identifier
* @erp_action: error recovery action struct pointer
*/
-void zfcp_rec_dbf_event_action(u8 id2, struct zfcp_erp_action *erp_action)
+void zfcp_rec_dbf_event_action(char *id2, struct zfcp_erp_action *erp_action)
{
struct zfcp_adapter *adapter = erp_action->adapter;
struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
@@ -864,7 +710,7 @@ void zfcp_rec_dbf_event_action(u8 id2, struct zfcp_erp_action *erp_action)
spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
memset(r, 0, sizeof(*r));
r->id = ZFCP_REC_DBF_ID_ACTION;
- r->id2 = id2;
+ memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
r->u.action.action = (unsigned long)erp_action;
r->u.action.status = erp_action->status;
r->u.action.step = erp_action->step;
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index 74998ff88e57..a573f7344dd6 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -25,6 +25,7 @@
#include "zfcp_fsf.h"
#define ZFCP_DBF_TAG_SIZE 4
+#define ZFCP_DBF_ID_SIZE 7
struct zfcp_dbf_dump {
u8 tag[ZFCP_DBF_TAG_SIZE];
@@ -70,7 +71,7 @@ struct zfcp_rec_dbf_record_action {
struct zfcp_rec_dbf_record {
u8 id;
- u8 id2;
+ char id2[7];
union {
struct zfcp_rec_dbf_record_action action;
struct zfcp_rec_dbf_record_thread thread;
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 510662783a6f..a0318630f047 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -3,7 +3,7 @@
*
* Global definitions for the zfcp device driver.
*
- * Copyright IBM Corporation 2002, 2008
+ * Copyright IBM Corporation 2002, 2009
*/
#ifndef ZFCP_DEF_H
@@ -243,9 +243,6 @@ struct zfcp_ls_adisc {
/* remote port status */
#define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001
-#define ZFCP_STATUS_PORT_PHYS_CLOSING 0x00000004
-#define ZFCP_STATUS_PORT_NO_WWPN 0x00000008
-#define ZFCP_STATUS_PORT_INVALID_WWPN 0x00000020
/* well known address (WKA) port status*/
enum zfcp_wka_status {
@@ -258,7 +255,6 @@ enum zfcp_wka_status {
/* logical unit status */
#define ZFCP_STATUS_UNIT_SHARED 0x00000004
#define ZFCP_STATUS_UNIT_READONLY 0x00000008
-#define ZFCP_STATUS_UNIT_REGISTERED 0x00000010
#define ZFCP_STATUS_UNIT_SCSI_WORK_PENDING 0x00000020
/* FSF request status (this does not have a common part) */
@@ -447,8 +443,9 @@ struct zfcp_adapter {
spinlock_t req_list_lock; /* request list lock */
struct zfcp_qdio_queue req_q; /* request queue */
spinlock_t req_q_lock; /* for operations on queue */
- int req_q_pci_batch; /* SBALs since PCI indication
- was last set */
+ ktime_t req_q_time; /* time of last fill level change */
+ u64 req_q_util; /* for accounting */
+ spinlock_t qdio_stat_lock;
u32 fsf_req_seq_no; /* FSF cmnd seq number */
wait_queue_head_t request_wq; /* can be used to wait for
more avaliable SBALs */
@@ -514,6 +511,9 @@ struct zfcp_port {
u32 maxframe_size;
u32 supported_classes;
struct work_struct gid_pn_work;
+ struct work_struct test_link_work;
+ struct work_struct rport_work;
+ enum { RPORT_NONE, RPORT_ADD, RPORT_DEL } rport_task;
};
struct zfcp_unit {
@@ -587,9 +587,6 @@ struct zfcp_fsf_req_qtcb {
/********************** ZFCP SPECIFIC DEFINES ********************************/
-#define ZFCP_REQ_AUTO_CLEANUP 0x00000002
-#define ZFCP_REQ_NO_QTCB 0x00000008
-
#define ZFCP_SET 0x00000100
#define ZFCP_CLEAR 0x00000200
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 387a3af528ac..631bdb1dfd6c 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -3,7 +3,7 @@
*
* Error Recovery Procedures (ERP).
*
- * Copyright IBM Corporation 2002, 2008
+ * Copyright IBM Corporation 2002, 2009
*/
#define KMSG_COMPONENT "zfcp"
@@ -55,7 +55,7 @@ enum zfcp_erp_act_result {
static void zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int mask)
{
- zfcp_erp_modify_adapter_status(adapter, 15, NULL,
+ zfcp_erp_modify_adapter_status(adapter, "erablk1", NULL,
ZFCP_STATUS_COMMON_UNBLOCKED | mask,
ZFCP_CLEAR);
}
@@ -75,9 +75,9 @@ static void zfcp_erp_action_ready(struct zfcp_erp_action *act)
struct zfcp_adapter *adapter = act->adapter;
list_move(&act->list, &act->adapter->erp_ready_head);
- zfcp_rec_dbf_event_action(146, act);
+ zfcp_rec_dbf_event_action("erardy1", act);
up(&adapter->erp_ready_sem);
- zfcp_rec_dbf_event_thread(2, adapter);
+ zfcp_rec_dbf_event_thread("erardy2", adapter);
}
static void zfcp_erp_action_dismiss(struct zfcp_erp_action *act)
@@ -208,7 +208,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
struct zfcp_port *port,
- struct zfcp_unit *unit, u8 id, void *ref)
+ struct zfcp_unit *unit, char *id, void *ref)
{
int retval = 1, need;
struct zfcp_erp_action *act = NULL;
@@ -228,7 +228,7 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
++adapter->erp_total_count;
list_add_tail(&act->list, &adapter->erp_ready_head);
up(&adapter->erp_ready_sem);
- zfcp_rec_dbf_event_thread(1, adapter);
+ zfcp_rec_dbf_event_thread("eracte1", adapter);
retval = 0;
out:
zfcp_rec_dbf_event_trigger(id, ref, want, need, act,
@@ -237,13 +237,14 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
}
static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
- int clear_mask, u8 id, void *ref)
+ int clear_mask, char *id, void *ref)
{
zfcp_erp_adapter_block(adapter, clear_mask);
+ zfcp_scsi_schedule_rports_block(adapter);
/* ensure propagation of failed status to new devices */
if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) {
- zfcp_erp_adapter_failed(adapter, 13, NULL);
+ zfcp_erp_adapter_failed(adapter, "erareo1", NULL);
return -EIO;
}
return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
@@ -258,7 +259,7 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
* @ref: Reference for debug trace event.
*/
void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
- u8 id, void *ref)
+ char *id, void *ref)
{
unsigned long flags;
@@ -277,7 +278,7 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
* @ref: Reference for debug trace event.
*/
void zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear,
- u8 id, void *ref)
+ char *id, void *ref)
{
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
zfcp_erp_adapter_reopen(adapter, clear | flags, id, ref);
@@ -290,7 +291,8 @@ void zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear,
* @id: Id for debug trace event.
* @ref: Reference for debug trace event.
*/
-void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, u8 id, void *ref)
+void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *id,
+ void *ref)
{
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
zfcp_erp_port_reopen(port, clear | flags, id, ref);
@@ -303,7 +305,8 @@ void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, u8 id, void *ref)
* @id: Id for debug trace event.
* @ref: Reference for debug trace event.
*/
-void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, u8 id, void *ref)
+void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, char *id,
+ void *ref)
{
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
zfcp_erp_unit_reopen(unit, clear | flags, id, ref);
@@ -311,15 +314,16 @@ void zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear, u8 id, void *ref)
static void zfcp_erp_port_block(struct zfcp_port *port, int clear)
{
- zfcp_erp_modify_port_status(port, 17, NULL,
+ zfcp_erp_modify_port_status(port, "erpblk1", NULL,
ZFCP_STATUS_COMMON_UNBLOCKED | clear,
ZFCP_CLEAR);
}
static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port,
- int clear, u8 id, void *ref)
+ int clear, char *id, void *ref)
{
zfcp_erp_port_block(port, clear);
+ zfcp_scsi_schedule_rport_block(port);
if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
return;
@@ -334,7 +338,7 @@ static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port,
* @id: Id for debug trace event.
* @ref: Reference for debug trace event.
*/
-void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, u8 id,
+void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, char *id,
void *ref)
{
unsigned long flags;
@@ -347,14 +351,15 @@ void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, u8 id,
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
}
-static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, u8 id,
+static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id,
void *ref)
{
zfcp_erp_port_block(port, clear);
+ zfcp_scsi_schedule_rport_block(port);
if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) {
/* ensure propagation of failed status to new devices */
- zfcp_erp_port_failed(port, 14, NULL);
+ zfcp_erp_port_failed(port, "erpreo1", NULL);
return -EIO;
}
@@ -369,7 +374,7 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, u8 id,
*
* Returns 0 if recovery has been triggered, < 0 if not.
*/
-int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, u8 id, void *ref)
+int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref)
{
unsigned long flags;
int retval;
@@ -386,12 +391,12 @@ int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, u8 id, void *ref)
static void zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask)
{
- zfcp_erp_modify_unit_status(unit, 19, NULL,
+ zfcp_erp_modify_unit_status(unit, "erublk1", NULL,
ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask,
ZFCP_CLEAR);
}
-static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, u8 id,
+static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
void *ref)
{
struct zfcp_adapter *adapter = unit->port->adapter;
@@ -411,7 +416,8 @@ static void _zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, u8 id,
* @clear_mask: specifies flags in unit status to be cleared
* Return: 0 on success, < 0 on error
*/
-void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, u8 id, void *ref)
+void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id,
+ void *ref)
{
unsigned long flags;
struct zfcp_port *port = unit->port;
@@ -437,28 +443,28 @@ static int status_change_clear(unsigned long mask, atomic_t *status)
static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
{
if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status))
- zfcp_rec_dbf_event_adapter(16, NULL, adapter);
+ zfcp_rec_dbf_event_adapter("eraubl1", NULL, adapter);
atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status);
}
static void zfcp_erp_port_unblock(struct zfcp_port *port)
{
if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status))
- zfcp_rec_dbf_event_port(18, NULL, port);
+ zfcp_rec_dbf_event_port("erpubl1", NULL, port);
atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status);
}
static void zfcp_erp_unit_unblock(struct zfcp_unit *unit)
{
if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status))
- zfcp_rec_dbf_event_unit(20, NULL, unit);
+ zfcp_rec_dbf_event_unit("eruubl1", NULL, unit);
atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status);
}
static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
{
list_move(&erp_action->list, &erp_action->adapter->erp_running_head);
- zfcp_rec_dbf_event_action(145, erp_action);
+ zfcp_rec_dbf_event_action("erator1", erp_action);
}
static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
@@ -474,11 +480,11 @@ static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
if (act->status & (ZFCP_STATUS_ERP_DISMISSED |
ZFCP_STATUS_ERP_TIMEDOUT)) {
act->fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
- zfcp_rec_dbf_event_action(142, act);
+ zfcp_rec_dbf_event_action("erscf_1", act);
act->fsf_req->erp_action = NULL;
}
if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
- zfcp_rec_dbf_event_action(143, act);
+ zfcp_rec_dbf_event_action("erscf_2", act);
if (act->fsf_req->status & (ZFCP_STATUS_FSFREQ_COMPLETED |
ZFCP_STATUS_FSFREQ_DISMISSED))
act->fsf_req = NULL;
@@ -530,7 +536,7 @@ static void zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
}
static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
- int clear, u8 id, void *ref)
+ int clear, char *id, void *ref)
{
struct zfcp_port *port;
@@ -538,8 +544,8 @@ static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
_zfcp_erp_port_reopen(port, clear, id, ref);
}
-static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, u8 id,
- void *ref)
+static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear,
+ char *id, void *ref)
{
struct zfcp_unit *unit;
@@ -559,28 +565,28 @@ static void zfcp_erp_strategy_followup_actions(struct zfcp_erp_action *act)
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
if (status == ZFCP_ERP_SUCCEEDED)
- _zfcp_erp_port_reopen_all(adapter, 0, 70, NULL);
+ _zfcp_erp_port_reopen_all(adapter, 0, "ersfa_1", NULL);
else
- _zfcp_erp_adapter_reopen(adapter, 0, 71, NULL);
+ _zfcp_erp_adapter_reopen(adapter, 0, "ersfa_2", NULL);
break;
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
if (status == ZFCP_ERP_SUCCEEDED)
- _zfcp_erp_port_reopen(port, 0, 72, NULL);
+ _zfcp_erp_port_reopen(port, 0, "ersfa_3", NULL);
else
- _zfcp_erp_adapter_reopen(adapter, 0, 73, NULL);
+ _zfcp_erp_adapter_reopen(adapter, 0, "ersfa_4", NULL);
break;
case ZFCP_ERP_ACTION_REOPEN_PORT:
if (status == ZFCP_ERP_SUCCEEDED)
- _zfcp_erp_unit_reopen_all(port, 0, 74, NULL);
+ _zfcp_erp_unit_reopen_all(port, 0, "ersfa_5", NULL);
else
- _zfcp_erp_port_forced_reopen(port, 0, 75, NULL);
+ _zfcp_erp_port_forced_reopen(port, 0, "ersfa_6", NULL);
break;
case ZFCP_ERP_ACTION_REOPEN_UNIT:
if (status != ZFCP_ERP_SUCCEEDED)
- _zfcp_erp_port_reopen(unit->port, 0, 76, NULL);
+ _zfcp_erp_port_reopen(unit->port, 0, "ersfa_7", NULL);
break;
}
}
@@ -617,7 +623,7 @@ static void zfcp_erp_enqueue_ptp_port(struct zfcp_adapter *adapter)
adapter->peer_d_id);
if (IS_ERR(port)) /* error or port already attached */
return;
- _zfcp_erp_port_reopen(port, 0, 150, NULL);
+ _zfcp_erp_port_reopen(port, 0, "ereptp1", NULL);
}
static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action)
@@ -640,9 +646,9 @@ static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action)
return ZFCP_ERP_FAILED;
}
- zfcp_rec_dbf_event_thread_lock(6, adapter);
+ zfcp_rec_dbf_event_thread_lock("erasfx1", adapter);
down(&adapter->erp_ready_sem);
- zfcp_rec_dbf_event_thread_lock(7, adapter);
+ zfcp_rec_dbf_event_thread_lock("erasfx2", adapter);
if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT)
break;
@@ -681,9 +687,9 @@ static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act)
if (ret)
return ZFCP_ERP_FAILED;
- zfcp_rec_dbf_event_thread_lock(8, adapter);
+ zfcp_rec_dbf_event_thread_lock("erasox1", adapter);
down(&adapter->erp_ready_sem);
- zfcp_rec_dbf_event_thread_lock(9, adapter);
+ zfcp_rec_dbf_event_thread_lock("erasox2", adapter);
if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
return ZFCP_ERP_FAILED;
@@ -705,60 +711,59 @@ static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *act)
return ZFCP_ERP_SUCCEEDED;
}
-static int zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *act,
- int close)
+static void zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *act)
{
- int retval = ZFCP_ERP_SUCCEEDED;
struct zfcp_adapter *adapter = act->adapter;
- if (close)
- goto close_only;
-
- retval = zfcp_erp_adapter_strategy_open_qdio(act);
- if (retval != ZFCP_ERP_SUCCEEDED)
- goto failed_qdio;
-
- retval = zfcp_erp_adapter_strategy_open_fsf(act);
- if (retval != ZFCP_ERP_SUCCEEDED)
- goto failed_openfcp;
-
- atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &act->adapter->status);
-
- return ZFCP_ERP_SUCCEEDED;
-
- close_only:
- atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,
- &act->adapter->status);
-
- failed_openfcp:
/* close queues to ensure that buffers are not accessed by adapter */
zfcp_qdio_close(adapter);
zfcp_fsf_req_dismiss_all(adapter);
adapter->fsf_req_seq_no = 0;
/* all ports and units are closed */
- zfcp_erp_modify_adapter_status(adapter, 24, NULL,
+ zfcp_erp_modify_adapter_status(adapter, "erascl1", NULL,
ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
- failed_qdio:
+
atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
- ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
- &act->adapter->status);
- return retval;
+ ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
}
-static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *act)
+static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *act)
{
- int retval;
+ struct zfcp_adapter *adapter = act->adapter;
- zfcp_erp_adapter_strategy_generic(act, 1); /* close */
- if (act->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
- return ZFCP_ERP_EXIT;
+ if (zfcp_erp_adapter_strategy_open_qdio(act)) {
+ atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
+ ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
+ &adapter->status);
+ return ZFCP_ERP_FAILED;
+ }
+
+ if (zfcp_erp_adapter_strategy_open_fsf(act)) {
+ zfcp_erp_adapter_strategy_close(act);
+ return ZFCP_ERP_FAILED;
+ }
+
+ atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &adapter->status);
+
+ return ZFCP_ERP_SUCCEEDED;
+}
- retval = zfcp_erp_adapter_strategy_generic(act, 0); /* open */
+static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *act)
+{
+ struct zfcp_adapter *adapter = act->adapter;
- if (retval == ZFCP_ERP_FAILED)
+ if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_OPEN) {
+ zfcp_erp_adapter_strategy_close(act);
+ if (act->status & ZFCP_STATUS_ERP_CLOSE_ONLY)
+ return ZFCP_ERP_EXIT;
+ }
+
+ if (zfcp_erp_adapter_strategy_open(act)) {
ssleep(8);
+ return ZFCP_ERP_FAILED;
+ }
- return retval;
+ return ZFCP_ERP_SUCCEEDED;
}
static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act)
@@ -777,10 +782,7 @@ static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act)
static void zfcp_erp_port_strategy_clearstati(struct zfcp_port *port)
{
- atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
- ZFCP_STATUS_PORT_PHYS_CLOSING |
- ZFCP_STATUS_PORT_INVALID_WWPN,
- &port->status);
+ atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, &port->status);
}
static int zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action)
@@ -836,7 +838,7 @@ static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act)
struct zfcp_port *port = act->port;
if (port->wwpn != adapter->peer_wwpn) {
- zfcp_erp_port_failed(port, 25, NULL);
+ zfcp_erp_port_failed(port, "eroptp1", NULL);
return ZFCP_ERP_FAILED;
}
port->d_id = adapter->peer_d_id;
@@ -855,7 +857,7 @@ void zfcp_erp_port_strategy_open_lookup(struct work_struct *work)
port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
if (retval)
zfcp_erp_notify(&port->erp_action, ZFCP_ERP_FAILED);
-
+ zfcp_port_put(port);
}
static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
@@ -871,17 +873,15 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP)
return zfcp_erp_open_ptp_port(act);
if (!port->d_id) {
- queue_work(zfcp_data.work_queue, &port->gid_pn_work);
+ zfcp_port_get(port);
+ if (!queue_work(zfcp_data.work_queue,
+ &port->gid_pn_work))
+ zfcp_port_put(port);
return ZFCP_ERP_CONTINUES;
}
case ZFCP_ERP_STEP_NAMESERVER_LOOKUP:
- if (!port->d_id) {
- if (p_status & (ZFCP_STATUS_PORT_INVALID_WWPN)) {
- zfcp_erp_port_failed(port, 26, NULL);
- return ZFCP_ERP_EXIT;
- }
+ if (!port->d_id)
return ZFCP_ERP_FAILED;
- }
return zfcp_erp_port_strategy_open_port(act);
case ZFCP_ERP_STEP_PORT_OPENING:
@@ -995,7 +995,7 @@ static int zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result)
"port 0x%016Lx\n",
(unsigned long long)unit->fcp_lun,
(unsigned long long)unit->port->wwpn);
- zfcp_erp_unit_failed(unit, 21, NULL);
+ zfcp_erp_unit_failed(unit, "erusck1", NULL);
}
break;
}
@@ -1025,7 +1025,7 @@ static int zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
dev_err(&port->adapter->ccw_device->dev,
"ERP failed for remote port 0x%016Lx\n",
(unsigned long long)port->wwpn);
- zfcp_erp_port_failed(port, 22, NULL);
+ zfcp_erp_port_failed(port, "erpsck1", NULL);
}
break;
}
@@ -1052,7 +1052,7 @@ static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter,
dev_err(&adapter->ccw_device->dev,
"ERP cannot recover an error "
"on the FCP device\n");
- zfcp_erp_adapter_failed(adapter, 23, NULL);
+ zfcp_erp_adapter_failed(adapter, "erasck1", NULL);
}
break;
}
@@ -1117,7 +1117,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
if (zfcp_erp_strat_change_det(&adapter->status, erp_status)) {
_zfcp_erp_adapter_reopen(adapter,
ZFCP_STATUS_COMMON_ERP_FAILED,
- 67, NULL);
+ "ersscg1", NULL);
return ZFCP_ERP_EXIT;
}
break;
@@ -1127,7 +1127,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
if (zfcp_erp_strat_change_det(&port->status, erp_status)) {
_zfcp_erp_port_reopen(port,
ZFCP_STATUS_COMMON_ERP_FAILED,
- 68, NULL);
+ "ersscg2", NULL);
return ZFCP_ERP_EXIT;
}
break;
@@ -1136,7 +1136,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
if (zfcp_erp_strat_change_det(&unit->status, erp_status)) {
_zfcp_erp_unit_reopen(unit,
ZFCP_STATUS_COMMON_ERP_FAILED,
- 69, NULL);
+ "ersscg3", NULL);
return ZFCP_ERP_EXIT;
}
break;
@@ -1155,7 +1155,7 @@ static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
}
list_del(&erp_action->list);
- zfcp_rec_dbf_event_action(144, erp_action);
+ zfcp_rec_dbf_event_action("eractd1", erp_action);
switch (erp_action->action) {
case ZFCP_ERP_ACTION_REOPEN_UNIT:
@@ -1214,38 +1214,8 @@ static void zfcp_erp_schedule_work(struct zfcp_unit *unit)
atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
INIT_WORK(&p->work, zfcp_erp_scsi_scan);
p->unit = unit;
- queue_work(zfcp_data.work_queue, &p->work);
-}
-
-static void zfcp_erp_rport_register(struct zfcp_port *port)
-{
- struct fc_rport_identifiers ids;
- ids.node_name = port->wwnn;
- ids.port_name = port->wwpn;
- ids.port_id = port->d_id;
- ids.roles = FC_RPORT_ROLE_FCP_TARGET;
- port->rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids);
- if (!port->rport) {
- dev_err(&port->adapter->ccw_device->dev,
- "Registering port 0x%016Lx failed\n",
- (unsigned long long)port->wwpn);
- return;
- }
-
- scsi_target_unblock(&port->rport->dev);
- port->rport->maxframe_size = port->maxframe_size;
- port->rport->supported_classes = port->supported_classes;
-}
-
-static void zfcp_erp_rports_del(struct zfcp_adapter *adapter)
-{
- struct zfcp_port *port;
- list_for_each_entry(port, &adapter->port_list_head, list) {
- if (!port->rport)
- continue;
- fc_remote_port_delete(port->rport);
- port->rport = NULL;
- }
+ if (!queue_work(zfcp_data.work_queue, &p->work))
+ zfcp_unit_put(unit);
}
static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
@@ -1256,10 +1226,8 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
switch (act->action) {
case ZFCP_ERP_ACTION_REOPEN_UNIT:
- if ((result == ZFCP_ERP_SUCCEEDED) &&
- !unit->device && port->rport) {
- atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED,
- &unit->status);
+ flush_work(&port->rport_work);
+ if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
if (!(atomic_read(&unit->status) &
ZFCP_STATUS_UNIT_SCSI_WORK_PENDING))
zfcp_erp_schedule_work(unit);
@@ -1269,27 +1237,17 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
case ZFCP_ERP_ACTION_REOPEN_PORT:
- if (atomic_read(&port->status) & ZFCP_STATUS_PORT_NO_WWPN) {
- zfcp_port_put(port);
- return;
- }
- if ((result == ZFCP_ERP_SUCCEEDED) && !port->rport)
- zfcp_erp_rport_register(port);
- if ((result != ZFCP_ERP_SUCCEEDED) && port->rport) {
- fc_remote_port_delete(port->rport);
- port->rport = NULL;
- }
+ if (result == ZFCP_ERP_SUCCEEDED)
+ zfcp_scsi_schedule_rport_register(port);
zfcp_port_put(port);
break;
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
- if (result != ZFCP_ERP_SUCCEEDED) {
- unregister_service_level(&adapter->service_level);
- zfcp_erp_rports_del(adapter);
- } else {
+ if (result == ZFCP_ERP_SUCCEEDED) {
register_service_level(&adapter->service_level);
schedule_work(&adapter->scan_work);
- }
+ } else
+ unregister_service_level(&adapter->service_level);
zfcp_adapter_put(adapter);
break;
}
@@ -1346,7 +1304,7 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
erp_action->status |= ZFCP_STATUS_ERP_LOWMEM;
}
if (adapter->erp_total_count == adapter->erp_low_mem_count)
- _zfcp_erp_adapter_reopen(adapter, 0, 66, NULL);
+ _zfcp_erp_adapter_reopen(adapter, 0, "erstgy1", NULL);
else {
zfcp_erp_strategy_memwait(erp_action);
retval = ZFCP_ERP_CONTINUES;
@@ -1406,9 +1364,9 @@ static int zfcp_erp_thread(void *data)
zfcp_erp_wakeup(adapter);
}
- zfcp_rec_dbf_event_thread_lock(4, adapter);
+ zfcp_rec_dbf_event_thread_lock("erthrd1", adapter);
ignore = down_interruptible(&adapter->erp_ready_sem);
- zfcp_rec_dbf_event_thread_lock(5, adapter);
+ zfcp_rec_dbf_event_thread_lock("erthrd2", adapter);
}
atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
@@ -1453,7 +1411,7 @@ void zfcp_erp_thread_kill(struct zfcp_adapter *adapter)
{
atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status);
up(&adapter->erp_ready_sem);
- zfcp_rec_dbf_event_thread_lock(3, adapter);
+ zfcp_rec_dbf_event_thread_lock("erthrk1", adapter);
wait_event(adapter->erp_thread_wqh,
!(atomic_read(&adapter->status) &
@@ -1469,7 +1427,7 @@ void zfcp_erp_thread_kill(struct zfcp_adapter *adapter)
* @id: Event id for debug trace.
* @ref: Reference for debug trace.
*/
-void zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, u8 id, void *ref)
+void zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, char *id, void *ref)
{
zfcp_erp_modify_adapter_status(adapter, id, ref,
ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
@@ -1481,7 +1439,7 @@ void zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, u8 id, void *ref)
* @id: Event id for debug trace.
* @ref: Reference for debug trace.
*/
-void zfcp_erp_port_failed(struct zfcp_port *port, u8 id, void *ref)
+void zfcp_erp_port_failed(struct zfcp_port *port, char *id, void *ref)
{
zfcp_erp_modify_port_status(port, id, ref,
ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
@@ -1493,7 +1451,7 @@ void zfcp_erp_port_failed(struct zfcp_port *port, u8 id, void *ref)
* @id: Event id for debug trace.
* @ref: Reference for debug trace.
*/
-void zfcp_erp_unit_failed(struct zfcp_unit *unit, u8 id, void *ref)
+void zfcp_erp_unit_failed(struct zfcp_unit *unit, char *id, void *ref)
{
zfcp_erp_modify_unit_status(unit, id, ref,
ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
@@ -1520,7 +1478,7 @@ void zfcp_erp_wait(struct zfcp_adapter *adapter)
*
* Changes in common status bits are propagated to attached ports and units.
*/
-void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, u8 id,
+void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id,
void *ref, u32 mask, int set_or_clear)
{
struct zfcp_port *port;
@@ -1554,7 +1512,7 @@ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, u8 id,
*
* Changes in common status bits are propagated to attached units.
*/
-void zfcp_erp_modify_port_status(struct zfcp_port *port, u8 id, void *ref,
+void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref,
u32 mask, int set_or_clear)
{
struct zfcp_unit *unit;
@@ -1586,7 +1544,7 @@ void zfcp_erp_modify_port_status(struct zfcp_port *port, u8 id, void *ref,
* @mask: status bits to change
* @set_or_clear: ZFCP_SET or ZFCP_CLEAR
*/
-void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u8 id, void *ref,
+void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, char *id, void *ref,
u32 mask, int set_or_clear)
{
if (set_or_clear == ZFCP_SET) {
@@ -1609,7 +1567,7 @@ void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u8 id, void *ref,
* @id: The debug trace id.
* @id: Reference for the debug trace.
*/
-void zfcp_erp_port_boxed(struct zfcp_port *port, u8 id, void *ref)
+void zfcp_erp_port_boxed(struct zfcp_port *port, char *id, void *ref)
{
unsigned long flags;
@@ -1626,7 +1584,7 @@ void zfcp_erp_port_boxed(struct zfcp_port *port, u8 id, void *ref)
* @id: The debug trace id.
* @id: Reference for the debug trace.
*/
-void zfcp_erp_unit_boxed(struct zfcp_unit *unit, u8 id, void *ref)
+void zfcp_erp_unit_boxed(struct zfcp_unit *unit, char *id, void *ref)
{
zfcp_erp_modify_unit_status(unit, id, ref,
ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET);
@@ -1642,7 +1600,7 @@ void zfcp_erp_unit_boxed(struct zfcp_unit *unit, u8 id, void *ref)
* Since the adapter has denied access, stop using the port and the
* attached units.
*/
-void zfcp_erp_port_access_denied(struct zfcp_port *port, u8 id, void *ref)
+void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref)
{
unsigned long flags;
@@ -1661,14 +1619,14 @@ void zfcp_erp_port_access_denied(struct zfcp_port *port, u8 id, void *ref)
*
* Since the adapter has denied access, stop using the unit.
*/
-void zfcp_erp_unit_access_denied(struct zfcp_unit *unit, u8 id, void *ref)
+void zfcp_erp_unit_access_denied(struct zfcp_unit *unit, char *id, void *ref)
{
zfcp_erp_modify_unit_status(unit, id, ref,
ZFCP_STATUS_COMMON_ERP_FAILED |
ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
}
-static void zfcp_erp_unit_access_changed(struct zfcp_unit *unit, u8 id,
+static void zfcp_erp_unit_access_changed(struct zfcp_unit *unit, char *id,
void *ref)
{
int status = atomic_read(&unit->status);
@@ -1679,7 +1637,7 @@ static void zfcp_erp_unit_access_changed(struct zfcp_unit *unit, u8 id,
zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref);
}
-static void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id,
+static void zfcp_erp_port_access_changed(struct zfcp_port *port, char *id,
void *ref)
{
struct zfcp_unit *unit;
@@ -1701,7 +1659,7 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id,
* @id: Id for debug trace
* @ref: Reference for debug trace
*/
-void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, u8 id,
+void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, char *id,
void *ref)
{
struct zfcp_port *port;
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index b5adeda93e1d..f6399ca97bcb 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -3,7 +3,7 @@
*
* External function declarations.
*
- * Copyright IBM Corporation 2002, 2008
+ * Copyright IBM Corporation 2002, 2009
*/
#ifndef ZFCP_EXT_H
@@ -35,15 +35,15 @@ extern struct miscdevice zfcp_cfdc_misc;
/* zfcp_dbf.c */
extern int zfcp_adapter_debug_register(struct zfcp_adapter *);
extern void zfcp_adapter_debug_unregister(struct zfcp_adapter *);
-extern void zfcp_rec_dbf_event_thread(u8, struct zfcp_adapter *);
-extern void zfcp_rec_dbf_event_thread_lock(u8, struct zfcp_adapter *);
-extern void zfcp_rec_dbf_event_adapter(u8, void *, struct zfcp_adapter *);
-extern void zfcp_rec_dbf_event_port(u8, void *, struct zfcp_port *);
-extern void zfcp_rec_dbf_event_unit(u8, void *, struct zfcp_unit *);
-extern void zfcp_rec_dbf_event_trigger(u8, void *, u8, u8, void *,
+extern void zfcp_rec_dbf_event_thread(char *, struct zfcp_adapter *);
+extern void zfcp_rec_dbf_event_thread_lock(char *, struct zfcp_adapter *);
+extern void zfcp_rec_dbf_event_adapter(char *, void *, struct zfcp_adapter *);
+extern void zfcp_rec_dbf_event_port(char *, void *, struct zfcp_port *);
+extern void zfcp_rec_dbf_event_unit(char *, void *, struct zfcp_unit *);
+extern void zfcp_rec_dbf_event_trigger(char *, void *, u8, u8, void *,
struct zfcp_adapter *,
struct zfcp_port *, struct zfcp_unit *);
-extern void zfcp_rec_dbf_event_action(u8, struct zfcp_erp_action *);
+extern void zfcp_rec_dbf_event_action(char *, struct zfcp_erp_action *);
extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *);
extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *,
struct fsf_status_read_buffer *);
@@ -66,31 +66,34 @@ extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *,
struct scsi_cmnd *);
/* zfcp_erp.c */
-extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u8, void *,
- u32, int);
-extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, u8, void *);
-extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, u8, void *);
-extern void zfcp_erp_adapter_failed(struct zfcp_adapter *, u8, void *);
-extern void zfcp_erp_modify_port_status(struct zfcp_port *, u8, void *, u32,
+extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, char *,
+ void *, u32, int);
+extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *, void *);
+extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *,
+ void *);
+extern void zfcp_erp_adapter_failed(struct zfcp_adapter *, char *, void *);
+extern void zfcp_erp_modify_port_status(struct zfcp_port *, char *, void *, u32,
int);
-extern int zfcp_erp_port_reopen(struct zfcp_port *, int, u8, void *);
-extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, u8, void *);
-extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, u8, void *);
-extern void zfcp_erp_port_failed(struct zfcp_port *, u8, void *);
-extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, u8, void *, u32,
+extern int zfcp_erp_port_reopen(struct zfcp_port *, int, char *, void *);
+extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *, void *);
+extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *,
+ void *);
+extern void zfcp_erp_port_failed(struct zfcp_port *, char *, void *);
+extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, char *, void *, u32,
int);
-extern void zfcp_erp_unit_reopen(struct zfcp_unit *, int, u8, void *);
-extern void zfcp_erp_unit_shutdown(struct zfcp_unit *, int, u8, void *);
-extern void zfcp_erp_unit_failed(struct zfcp_unit *, u8, void *);
+extern void zfcp_erp_unit_reopen(struct zfcp_unit *, int, char *, void *);
+extern void zfcp_erp_unit_shutdown(struct zfcp_unit *, int, char *, void *);
+extern void zfcp_erp_unit_failed(struct zfcp_unit *, char *, void *);
extern int zfcp_erp_thread_setup(struct zfcp_adapter *);
extern void zfcp_erp_thread_kill(struct zfcp_adapter *);
extern void zfcp_erp_wait(struct zfcp_adapter *);
extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long);
-extern void zfcp_erp_port_boxed(struct zfcp_port *, u8, void *);
-extern void zfcp_erp_unit_boxed(struct zfcp_unit *, u8, void *);
-extern void zfcp_erp_port_access_denied(struct zfcp_port *, u8, void *);
-extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, u8, void *);
-extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, u8, void *);
+extern void zfcp_erp_port_boxed(struct zfcp_port *, char *, void *);
+extern void zfcp_erp_unit_boxed(struct zfcp_unit *, char *, void *);
+extern void zfcp_erp_port_access_denied(struct zfcp_port *, char *, void *);
+extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, char *, void *);
+extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *,
+ void *);
extern void zfcp_erp_timeout_handler(unsigned long);
extern void zfcp_erp_port_strategy_open_lookup(struct work_struct *);
@@ -101,6 +104,7 @@ extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
extern int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *);
extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
extern void zfcp_test_link(struct zfcp_port *);
+extern void zfcp_fc_link_test_work(struct work_struct *);
extern void zfcp_fc_nameserver_init(struct zfcp_adapter *);
/* zfcp_fsf.c */
@@ -125,16 +129,13 @@ extern int zfcp_status_read_refill(struct zfcp_adapter *adapter);
extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *,
struct zfcp_erp_action *);
extern int zfcp_fsf_send_els(struct zfcp_send_els *);
-extern int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *,
- struct zfcp_unit *,
- struct scsi_cmnd *, int, int);
+extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
+ struct scsi_cmnd *);
extern void zfcp_fsf_req_complete(struct zfcp_fsf_req *);
extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
-extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *,
- struct zfcp_unit *, u8, int);
+extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *, u8);
extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long,
- struct zfcp_adapter *,
- struct zfcp_unit *, int);
+ struct zfcp_unit *);
/* zfcp_qdio.c */
extern int zfcp_qdio_allocate(struct zfcp_adapter *);
@@ -153,6 +154,10 @@ extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *);
extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *);
extern struct fc_function_template zfcp_transport_functions;
+extern void zfcp_scsi_rport_work(struct work_struct *);
+extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *);
+extern void zfcp_scsi_schedule_rport_block(struct zfcp_port *);
+extern void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *);
/* zfcp_sysfs.c */
extern struct attribute_group zfcp_sysfs_unit_attrs;
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index eabdfe24456e..e8d032b9dfbd 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -3,7 +3,7 @@
*
* Fibre Channel related functions for the zfcp device driver.
*
- * Copyright IBM Corporation 2008
+ * Copyright IBM Corporation 2008, 2009
*/
#define KMSG_COMPONENT "zfcp"
@@ -94,12 +94,16 @@ static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port)
static void zfcp_wka_port_offline(struct work_struct *work)
{
- struct delayed_work *dw = container_of(work, struct delayed_work, work);
+ struct delayed_work *dw = to_delayed_work(work);
struct zfcp_wka_port *wka_port =
container_of(dw, struct zfcp_wka_port, work);
- wait_event(wka_port->completion_wq,
- atomic_read(&wka_port->refcount) == 0);
+ /* Don't wait forvever. If the wka_port is too busy take it offline
+ through a new call later */
+ if (!wait_event_timeout(wka_port->completion_wq,
+ atomic_read(&wka_port->refcount) == 0,
+ HZ >> 1))
+ return;
mutex_lock(&wka_port->mutex);
if ((atomic_read(&wka_port->refcount) != 0) ||
@@ -145,16 +149,10 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
struct zfcp_port *port;
read_lock_irqsave(&zfcp_data.config_lock, flags);
- list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) {
- if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_PHYS_OPEN))
- /* Try to connect to unused ports anyway. */
- zfcp_erp_port_reopen(port,
- ZFCP_STATUS_COMMON_ERP_FAILED,
- 82, fsf_req);
- else if ((port->d_id & range) == (elem->nport_did & range))
- /* Check connection status for connected ports */
+ list_for_each_entry(port, &fsf_req->adapter->port_list_head, list)
+ if ((port->d_id & range) == (elem->nport_did & range))
zfcp_test_link(port);
- }
+
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
}
@@ -196,7 +194,7 @@ static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
if (port && (port->wwpn == wwpn))
- zfcp_erp_port_forced_reopen(port, 0, 83, req);
+ zfcp_erp_port_forced_reopen(port, 0, "fciwwp1", req);
}
static void zfcp_fc_incoming_plogi(struct zfcp_fsf_req *req)
@@ -259,10 +257,9 @@ static void zfcp_fc_ns_gid_pn_eval(unsigned long data)
if (ct->status)
return;
- if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT) {
- atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status);
+ if (ct_iu_resp->header.cmd_rsp_code != ZFCP_CT_ACCEPT)
return;
- }
+
/* paranoia */
if (ct_iu_req->wwpn != port->wwpn)
return;
@@ -375,16 +372,22 @@ static void zfcp_fc_adisc_handler(unsigned long data)
if (adisc->els.status) {
/* request rejected or timed out */
- zfcp_erp_port_forced_reopen(port, 0, 63, NULL);
+ zfcp_erp_port_forced_reopen(port, 0, "fcadh_1", NULL);
goto out;
}
if (!port->wwnn)
port->wwnn = ls_adisc->wwnn;
- if (port->wwpn != ls_adisc->wwpn)
- zfcp_erp_port_reopen(port, 0, 64, NULL);
+ if ((port->wwpn != ls_adisc->wwpn) ||
+ !(atomic_read(&port->status) & ZFCP_STATUS_COMMON_OPEN)) {
+ zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED,
+ "fcadh_2", NULL);
+ goto out;
+ }
+ /* port is good, unblock rport without going through erp */
+ zfcp_scsi_schedule_rport_register(port);
out:
zfcp_port_put(port);
kfree(adisc);
@@ -422,6 +425,31 @@ static int zfcp_fc_adisc(struct zfcp_port *port)
return zfcp_fsf_send_els(&adisc->els);
}
+void zfcp_fc_link_test_work(struct work_struct *work)
+{
+ struct zfcp_port *port =
+ container_of(work, struct zfcp_port, test_link_work);
+ int retval;
+
+ if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_UNBLOCKED)) {
+ zfcp_port_put(port);
+ return; /* port erp is running and will update rport status */
+ }
+
+ zfcp_port_get(port);
+ port->rport_task = RPORT_DEL;
+ zfcp_scsi_rport_work(&port->rport_work);
+
+ retval = zfcp_fc_adisc(port);
+ if (retval == 0)
+ return;
+
+ /* send of ADISC was not possible */
+ zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL);
+
+ zfcp_port_put(port);
+}
+
/**
* zfcp_test_link - lightweight link test procedure
* @port: port to be tested
@@ -432,17 +460,9 @@ static int zfcp_fc_adisc(struct zfcp_port *port)
*/
void zfcp_test_link(struct zfcp_port *port)
{
- int retval;
-
zfcp_port_get(port);
- retval = zfcp_fc_adisc(port);
- if (retval == 0)
- return;
-
- /* send of ADISC was not possible */
- zfcp_port_put(port);
- if (retval != -EBUSY)
- zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
+ if (!queue_work(zfcp_data.work_queue, &port->test_link_work))
+ zfcp_port_put(port);
}
static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num)
@@ -529,7 +549,7 @@ static void zfcp_validate_port(struct zfcp_port *port)
zfcp_port_put(port);
return;
}
- zfcp_erp_port_shutdown(port, 0, 151, NULL);
+ zfcp_erp_port_shutdown(port, 0, "fcpval1", NULL);
zfcp_erp_wait(adapter);
zfcp_port_put(port);
zfcp_port_dequeue(port);
@@ -592,7 +612,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
if (IS_ERR(port))
ret = PTR_ERR(port);
else
- zfcp_erp_port_reopen(port, 0, 149, NULL);
+ zfcp_erp_port_reopen(port, 0, "fcegpf1", NULL);
}
zfcp_erp_wait(adapter);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index e6416f8541b0..b29f3121b666 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -3,7 +3,7 @@
*
* Implementation of FSF commands.
*
- * Copyright IBM Corporation 2002, 2008
+ * Copyright IBM Corporation 2002, 2009
*/
#define KMSG_COMPONENT "zfcp"
@@ -12,11 +12,14 @@
#include <linux/blktrace_api.h>
#include "zfcp_ext.h"
+#define ZFCP_REQ_AUTO_CLEANUP 0x00000002
+#define ZFCP_REQ_NO_QTCB 0x00000008
+
static void zfcp_fsf_request_timeout_handler(unsigned long data)
{
struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
- zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 62,
- NULL);
+ zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
+ "fsrth_1", NULL);
}
static void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req,
@@ -75,7 +78,7 @@ static void zfcp_fsf_access_denied_port(struct zfcp_fsf_req *req,
(unsigned long long)port->wwpn);
zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]);
zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]);
- zfcp_erp_port_access_denied(port, 55, req);
+ zfcp_erp_port_access_denied(port, "fspad_1", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
}
@@ -89,7 +92,7 @@ static void zfcp_fsf_access_denied_unit(struct zfcp_fsf_req *req,
(unsigned long long)unit->port->wwpn);
zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[0]);
zfcp_act_eval_err(req->adapter, header->fsf_status_qual.halfword[1]);
- zfcp_erp_unit_access_denied(unit, 59, req);
+ zfcp_erp_unit_access_denied(unit, "fsuad_1", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
}
@@ -97,7 +100,7 @@ static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req)
{
dev_err(&req->adapter->ccw_device->dev, "FCP device not "
"operational because of an unsupported FC class\n");
- zfcp_erp_adapter_shutdown(req->adapter, 0, 123, req);
+ zfcp_erp_adapter_shutdown(req->adapter, 0, "fscns_1", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
}
@@ -159,20 +162,13 @@ static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req)
list_for_each_entry(port, &adapter->port_list_head, list)
if (port->d_id == d_id) {
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
- switch (sr_buf->status_subtype) {
- case FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT:
- zfcp_erp_port_reopen(port, 0, 101, req);
- break;
- case FSF_STATUS_READ_SUB_ERROR_PORT:
- zfcp_erp_port_shutdown(port, 0, 122, req);
- break;
- }
+ zfcp_erp_port_reopen(port, 0, "fssrpc1", req);
return;
}
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
}
-static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, u8 id,
+static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, char *id,
struct fsf_link_down_info *link_down)
{
struct zfcp_adapter *adapter = req->adapter;
@@ -181,6 +177,7 @@ static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, u8 id,
return;
atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
+ zfcp_scsi_schedule_rports_block(adapter);
if (!link_down)
goto out;
@@ -261,13 +258,13 @@ static void zfcp_fsf_status_read_link_down(struct zfcp_fsf_req *req)
switch (sr_buf->status_subtype) {
case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
- zfcp_fsf_link_down_info_eval(req, 38, ldi);
+ zfcp_fsf_link_down_info_eval(req, "fssrld1", ldi);
break;
case FSF_STATUS_READ_SUB_FDISC_FAILED:
- zfcp_fsf_link_down_info_eval(req, 39, ldi);
+ zfcp_fsf_link_down_info_eval(req, "fssrld2", ldi);
break;
case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE:
- zfcp_fsf_link_down_info_eval(req, 40, NULL);
+ zfcp_fsf_link_down_info_eval(req, "fssrld3", NULL);
};
}
@@ -307,22 +304,23 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
dev_info(&adapter->ccw_device->dev,
"The local link has been restored\n");
/* All ports should be marked as ready to run again */
- zfcp_erp_modify_adapter_status(adapter, 30, NULL,
+ zfcp_erp_modify_adapter_status(adapter, "fssrh_1", NULL,
ZFCP_STATUS_COMMON_RUNNING,
ZFCP_SET);
zfcp_erp_adapter_reopen(adapter,
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
ZFCP_STATUS_COMMON_ERP_FAILED,
- 102, req);
+ "fssrh_2", req);
break;
case FSF_STATUS_READ_NOTIFICATION_LOST:
if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED)
- zfcp_erp_adapter_access_changed(adapter, 135, req);
+ zfcp_erp_adapter_access_changed(adapter, "fssrh_3",
+ req);
if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS)
schedule_work(&adapter->scan_work);
break;
case FSF_STATUS_READ_CFDC_UPDATED:
- zfcp_erp_adapter_access_changed(adapter, 136, req);
+ zfcp_erp_adapter_access_changed(adapter, "fssrh_4", req);
break;
case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
adapter->adapter_features = sr_buf->payload.word[0];
@@ -351,7 +349,7 @@ static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req)
dev_err(&req->adapter->ccw_device->dev,
"The FCP adapter reported a problem "
"that cannot be recovered\n");
- zfcp_erp_adapter_shutdown(req->adapter, 0, 121, req);
+ zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfsqe1", req);
break;
}
/* all non-return stats set FSFREQ_ERROR*/
@@ -368,7 +366,7 @@ static void zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *req)
dev_err(&req->adapter->ccw_device->dev,
"The FCP adapter does not recognize the command 0x%x\n",
req->qtcb->header.fsf_command);
- zfcp_erp_adapter_shutdown(req->adapter, 0, 120, req);
+ zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfse_1", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -400,17 +398,17 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
"QTCB version 0x%x not supported by FCP adapter "
"(0x%x to 0x%x)\n", FSF_QTCB_CURRENT_VERSION,
psq->word[0], psq->word[1]);
- zfcp_erp_adapter_shutdown(adapter, 0, 117, req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fspse_1", req);
break;
case FSF_PROT_ERROR_STATE:
case FSF_PROT_SEQ_NUMB_ERROR:
- zfcp_erp_adapter_reopen(adapter, 0, 98, req);
+ zfcp_erp_adapter_reopen(adapter, 0, "fspse_2", req);
req->status |= ZFCP_STATUS_FSFREQ_RETRY;
break;
case FSF_PROT_UNSUPP_QTCB_TYPE:
dev_err(&adapter->ccw_device->dev,
"The QTCB type is not supported by the FCP adapter\n");
- zfcp_erp_adapter_shutdown(adapter, 0, 118, req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fspse_3", req);
break;
case FSF_PROT_HOST_CONNECTION_INITIALIZING:
atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
@@ -420,27 +418,29 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
dev_err(&adapter->ccw_device->dev,
"0x%Lx is an ambiguous request identifier\n",
(unsigned long long)qtcb->bottom.support.req_handle);
- zfcp_erp_adapter_shutdown(adapter, 0, 78, req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fspse_4", req);
break;
case FSF_PROT_LINK_DOWN:
- zfcp_fsf_link_down_info_eval(req, 37, &psq->link_down_info);
+ zfcp_fsf_link_down_info_eval(req, "fspse_5",
+ &psq->link_down_info);
/* FIXME: reopening adapter now? better wait for link up */
- zfcp_erp_adapter_reopen(adapter, 0, 79, req);
+ zfcp_erp_adapter_reopen(adapter, 0, "fspse_6", req);
break;
case FSF_PROT_REEST_QUEUE:
/* All ports should be marked as ready to run again */
- zfcp_erp_modify_adapter_status(adapter, 28, NULL,
+ zfcp_erp_modify_adapter_status(adapter, "fspse_7", NULL,
ZFCP_STATUS_COMMON_RUNNING,
ZFCP_SET);
zfcp_erp_adapter_reopen(adapter,
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
- ZFCP_STATUS_COMMON_ERP_FAILED, 99, req);
+ ZFCP_STATUS_COMMON_ERP_FAILED,
+ "fspse_8", req);
break;
default:
dev_err(&adapter->ccw_device->dev,
"0x%x is not a valid transfer protocol status\n",
qtcb->prefix.prot_status);
- zfcp_erp_adapter_shutdown(adapter, 0, 119, req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fspse_9", req);
}
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
}
@@ -526,7 +526,7 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
dev_err(&adapter->ccw_device->dev,
"Unknown or unsupported arbitrated loop "
"fibre channel topology detected\n");
- zfcp_erp_adapter_shutdown(adapter, 0, 127, req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fsece_1", req);
return -EIO;
}
@@ -560,7 +560,7 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
"FCP adapter maximum QTCB size (%d bytes) "
"is too small\n",
bottom->max_qtcb_size);
- zfcp_erp_adapter_shutdown(adapter, 0, 129, req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh1", req);
return;
}
atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
@@ -577,11 +577,11 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
&adapter->status);
- zfcp_fsf_link_down_info_eval(req, 42,
+ zfcp_fsf_link_down_info_eval(req, "fsecdh2",
&qtcb->header.fsf_status_qual.link_down_info);
break;
default:
- zfcp_erp_adapter_shutdown(adapter, 0, 130, req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3", req);
return;
}
@@ -597,14 +597,14 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req)
dev_err(&adapter->ccw_device->dev,
"The FCP adapter only supports newer "
"control block versions\n");
- zfcp_erp_adapter_shutdown(adapter, 0, 125, req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh4", req);
return;
}
if (FSF_QTCB_CURRENT_VERSION > bottom->high_qtcb_version) {
dev_err(&adapter->ccw_device->dev,
"The FCP adapter only supports older "
"control block versions\n");
- zfcp_erp_adapter_shutdown(adapter, 0, 126, req);
+ zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh5", req);
}
}
@@ -617,9 +617,10 @@ static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req)
if (req->data)
memcpy(req->data, bottom, sizeof(*bottom));
- if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
+ if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) {
fc_host_permanent_port_name(shost) = bottom->wwpn;
- else
+ fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
+ } else
fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
fc_host_supported_speeds(shost) = bottom->supported_speed;
@@ -638,20 +639,12 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req)
break;
case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
zfcp_fsf_exchange_port_evaluate(req);
- zfcp_fsf_link_down_info_eval(req, 43,
+ zfcp_fsf_link_down_info_eval(req, "fsepdh1",
&qtcb->header.fsf_status_qual.link_down_info);
break;
}
}
-static int zfcp_fsf_sbal_available(struct zfcp_adapter *adapter)
-{
- if (atomic_read(&adapter->req_q.count) > 0)
- return 1;
- atomic_inc(&adapter->qdio_outb_full);
- return 0;
-}
-
static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter)
__releases(&adapter->req_q_lock)
__acquires(&adapter->req_q_lock)
@@ -735,7 +728,7 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter,
req->adapter = adapter;
req->fsf_command = fsf_cmd;
- req->req_id = adapter->req_no++;
+ req->req_id = adapter->req_no;
req->sbal_number = 1;
req->sbal_first = req_q->first;
req->sbal_last = req_q->first;
@@ -791,13 +784,14 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
if (zfcp_reqlist_find_safe(adapter, req))
zfcp_reqlist_remove(adapter, req);
spin_unlock_irqrestore(&adapter->req_list_lock, flags);
- zfcp_erp_adapter_reopen(adapter, 0, 116, req);
+ zfcp_erp_adapter_reopen(adapter, 0, "fsrs__1", req);
return -EIO;
}
/* Don't increase for unsolicited status */
if (req->qtcb)
adapter->fsf_req_seq_no++;
+ adapter->req_no++;
return 0;
}
@@ -870,14 +864,14 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
switch (req->qtcb->header.fsf_status) {
case FSF_PORT_HANDLE_NOT_VALID:
if (fsq->word[0] == fsq->word[1]) {
- zfcp_erp_adapter_reopen(unit->port->adapter, 0, 104,
- req);
+ zfcp_erp_adapter_reopen(unit->port->adapter, 0,
+ "fsafch1", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
}
break;
case FSF_LUN_HANDLE_NOT_VALID:
if (fsq->word[0] == fsq->word[1]) {
- zfcp_erp_port_reopen(unit->port, 0, 105, req);
+ zfcp_erp_port_reopen(unit->port, 0, "fsafch2", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
}
break;
@@ -885,12 +879,12 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
req->status |= ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED;
break;
case FSF_PORT_BOXED:
- zfcp_erp_port_boxed(unit->port, 47, req);
+ zfcp_erp_port_boxed(unit->port, "fsafch3", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
ZFCP_STATUS_FSFREQ_RETRY;
break;
case FSF_LUN_BOXED:
- zfcp_erp_unit_boxed(unit, 48, req);
+ zfcp_erp_unit_boxed(unit, "fsafch4", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
ZFCP_STATUS_FSFREQ_RETRY;
break;
@@ -912,27 +906,22 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
/**
* zfcp_fsf_abort_fcp_command - abort running SCSI command
* @old_req_id: unsigned long
- * @adapter: pointer to struct zfcp_adapter
* @unit: pointer to struct zfcp_unit
- * @req_flags: integer specifying the request flags
* Returns: pointer to struct zfcp_fsf_req
- *
- * FIXME(design): should be watched by a timeout !!!
*/
struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
- struct zfcp_adapter *adapter,
- struct zfcp_unit *unit,
- int req_flags)
+ struct zfcp_unit *unit)
{
struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *req = NULL;
+ struct zfcp_adapter *adapter = unit->port->adapter;
- spin_lock(&adapter->req_q_lock);
- if (!zfcp_fsf_sbal_available(adapter))
+ spin_lock_bh(&adapter->req_q_lock);
+ if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND,
- req_flags, adapter->pool.fsf_req_abort);
+ 0, adapter->pool.fsf_req_abort);
if (IS_ERR(req)) {
req = NULL;
goto out;
@@ -960,7 +949,7 @@ out_error_free:
zfcp_fsf_req_free(req);
req = NULL;
out:
- spin_unlock(&adapter->req_q_lock);
+ spin_unlock_bh(&adapter->req_q_lock);
return req;
}
@@ -998,7 +987,7 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
ZFCP_STATUS_FSFREQ_RETRY;
break;
case FSF_PORT_HANDLE_NOT_VALID:
- zfcp_erp_adapter_reopen(adapter, 0, 106, req);
+ zfcp_erp_adapter_reopen(adapter, 0, "fsscth1", req);
case FSF_GENERIC_COMMAND_REJECTED:
case FSF_PAYLOAD_SIZE_MISMATCH:
case FSF_REQUEST_SIZE_TOO_LARGE:
@@ -1174,12 +1163,8 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
struct fsf_qtcb_bottom_support *bottom;
int ret = -EIO;
- if (unlikely(!(atomic_read(&els->port->status) &
- ZFCP_STATUS_COMMON_UNBLOCKED)))
- return -EBUSY;
-
- spin_lock(&adapter->req_q_lock);
- if (!zfcp_fsf_sbal_available(adapter))
+ spin_lock_bh(&adapter->req_q_lock);
+ if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS,
ZFCP_REQ_AUTO_CLEANUP, NULL);
@@ -1212,7 +1197,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
failed_send:
zfcp_fsf_req_free(req);
out:
- spin_unlock(&adapter->req_q_lock);
+ spin_unlock_bh(&adapter->req_q_lock);
return ret;
}
@@ -1224,7 +1209,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
int retval = -EIO;
spin_lock_bh(&adapter->req_q_lock);
- if (!zfcp_fsf_sbal_available(adapter))
+ if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter,
FSF_QTCB_EXCHANGE_CONFIG_DATA,
@@ -1320,7 +1305,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
return -EOPNOTSUPP;
spin_lock_bh(&adapter->req_q_lock);
- if (!zfcp_fsf_sbal_available(adapter))
+ if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
ZFCP_REQ_AUTO_CLEANUP,
@@ -1366,7 +1351,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
return -EOPNOTSUPP;
spin_lock_bh(&adapter->req_q_lock);
- if (!zfcp_fsf_sbal_available(adapter))
+ if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0,
@@ -1416,7 +1401,7 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
"Not enough FCP adapter resources to open "
"remote port 0x%016Lx\n",
(unsigned long long)port->wwpn);
- zfcp_erp_port_failed(port, 31, req);
+ zfcp_erp_port_failed(port, "fsoph_1", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_ADAPTER_STATUS_AVAILABLE:
@@ -1522,13 +1507,13 @@ static void zfcp_fsf_close_port_handler(struct zfcp_fsf_req *req)
switch (req->qtcb->header.fsf_status) {
case FSF_PORT_HANDLE_NOT_VALID:
- zfcp_erp_adapter_reopen(port->adapter, 0, 107, req);
+ zfcp_erp_adapter_reopen(port->adapter, 0, "fscph_1", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_ADAPTER_STATUS_AVAILABLE:
break;
case FSF_GOOD:
- zfcp_erp_modify_port_status(port, 33, req,
+ zfcp_erp_modify_port_status(port, "fscph_2", req,
ZFCP_STATUS_COMMON_OPEN,
ZFCP_CLEAR);
break;
@@ -1657,7 +1642,7 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
if (req->qtcb->header.fsf_status == FSF_PORT_HANDLE_NOT_VALID) {
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
- zfcp_erp_adapter_reopen(wka_port->adapter, 0, 84, req);
+ zfcp_erp_adapter_reopen(wka_port->adapter, 0, "fscwph1", req);
}
wka_port->status = ZFCP_WKA_PORT_OFFLINE;
@@ -1712,18 +1697,18 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req)
struct zfcp_unit *unit;
if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
- goto skip_fsfstatus;
+ return;
switch (header->fsf_status) {
case FSF_PORT_HANDLE_NOT_VALID:
- zfcp_erp_adapter_reopen(port->adapter, 0, 108, req);
+ zfcp_erp_adapter_reopen(port->adapter, 0, "fscpph1", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_ACCESS_DENIED:
zfcp_fsf_access_denied_port(req, port);
break;
case FSF_PORT_BOXED:
- zfcp_erp_port_boxed(port, 50, req);
+ zfcp_erp_port_boxed(port, "fscpph2", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
ZFCP_STATUS_FSFREQ_RETRY;
/* can't use generic zfcp_erp_modify_port_status because
@@ -1752,8 +1737,6 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req)
&unit->status);
break;
}
-skip_fsfstatus:
- atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_CLOSING, &port->status);
}
/**
@@ -1789,8 +1772,6 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
req->erp_action = erp_action;
req->handler = zfcp_fsf_close_physical_port_handler;
erp_action->fsf_req = req;
- atomic_set_mask(ZFCP_STATUS_PORT_PHYS_CLOSING,
- &erp_action->port->status);
zfcp_fsf_start_erp_timer(req);
retval = zfcp_fsf_req_send(req);
@@ -1825,7 +1806,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
switch (header->fsf_status) {
case FSF_PORT_HANDLE_NOT_VALID:
- zfcp_erp_adapter_reopen(unit->port->adapter, 0, 109, req);
+ zfcp_erp_adapter_reopen(unit->port->adapter, 0, "fsouh_1", req);
/* fall through */
case FSF_LUN_ALREADY_OPEN:
break;
@@ -1835,7 +1816,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status);
break;
case FSF_PORT_BOXED:
- zfcp_erp_port_boxed(unit->port, 51, req);
+ zfcp_erp_port_boxed(unit->port, "fsouh_2", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
ZFCP_STATUS_FSFREQ_RETRY;
break;
@@ -1851,7 +1832,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
else
zfcp_act_eval_err(adapter,
header->fsf_status_qual.word[2]);
- zfcp_erp_unit_access_denied(unit, 60, req);
+ zfcp_erp_unit_access_denied(unit, "fsouh_3", req);
atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status);
atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -1862,7 +1843,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
"0x%016Lx on port 0x%016Lx\n",
(unsigned long long)unit->fcp_lun,
(unsigned long long)unit->port->wwpn);
- zfcp_erp_unit_failed(unit, 34, req);
+ zfcp_erp_unit_failed(unit, "fsouh_4", req);
/* fall through */
case FSF_INVALID_COMMAND_OPTION:
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -1911,9 +1892,9 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
"port 0x%016Lx)\n",
(unsigned long long)unit->fcp_lun,
(unsigned long long)unit->port->wwpn);
- zfcp_erp_unit_failed(unit, 35, req);
+ zfcp_erp_unit_failed(unit, "fsouh_5", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
- zfcp_erp_unit_shutdown(unit, 0, 80, req);
+ zfcp_erp_unit_shutdown(unit, 0, "fsouh_6", req);
} else if (!exclusive && readwrite) {
dev_err(&adapter->ccw_device->dev,
"Shared read-write access not "
@@ -1921,9 +1902,9 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
"0x%016Lx)\n",
(unsigned long long)unit->fcp_lun,
(unsigned long long)unit->port->wwpn);
- zfcp_erp_unit_failed(unit, 36, req);
+ zfcp_erp_unit_failed(unit, "fsouh_7", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
- zfcp_erp_unit_shutdown(unit, 0, 81, req);
+ zfcp_erp_unit_shutdown(unit, 0, "fsouh_8", req);
}
}
break;
@@ -1988,15 +1969,15 @@ static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req)
switch (req->qtcb->header.fsf_status) {
case FSF_PORT_HANDLE_NOT_VALID:
- zfcp_erp_adapter_reopen(unit->port->adapter, 0, 110, req);
+ zfcp_erp_adapter_reopen(unit->port->adapter, 0, "fscuh_1", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_LUN_HANDLE_NOT_VALID:
- zfcp_erp_port_reopen(unit->port, 0, 111, req);
+ zfcp_erp_port_reopen(unit->port, 0, "fscuh_2", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_PORT_BOXED:
- zfcp_erp_port_boxed(unit->port, 52, req);
+ zfcp_erp_port_boxed(unit->port, "fscuh_3", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
ZFCP_STATUS_FSFREQ_RETRY;
break;
@@ -2073,7 +2054,6 @@ static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req)
struct fsf_qual_latency_info *lat_inf;
struct latency_cont *lat;
struct zfcp_unit *unit = req->unit;
- unsigned long flags;
lat_inf = &req->qtcb->prefix.prot_status_qual.latency_info;
@@ -2091,11 +2071,11 @@ static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req)
return;
}
- spin_lock_irqsave(&unit->latencies.lock, flags);
+ spin_lock(&unit->latencies.lock);
zfcp_fsf_update_lat(&lat->channel, lat_inf->channel_lat);
zfcp_fsf_update_lat(&lat->fabric, lat_inf->fabric_lat);
lat->counter++;
- spin_unlock_irqrestore(&unit->latencies.lock, flags);
+ spin_unlock(&unit->latencies.lock);
}
#ifdef CONFIG_BLK_DEV_IO_TRACE
@@ -2147,7 +2127,6 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ABORTED)) {
set_host_byte(scpnt, DID_SOFT_ERROR);
- set_driver_byte(scpnt, SUGGEST_RETRY);
goto skip_fsfstatus;
}
@@ -2237,12 +2216,12 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req)
switch (header->fsf_status) {
case FSF_HANDLE_MISMATCH:
case FSF_PORT_HANDLE_NOT_VALID:
- zfcp_erp_adapter_reopen(unit->port->adapter, 0, 112, req);
+ zfcp_erp_adapter_reopen(unit->port->adapter, 0, "fssfch1", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_FCPLUN_NOT_VALID:
case FSF_LUN_HANDLE_NOT_VALID:
- zfcp_erp_port_reopen(unit->port, 0, 113, req);
+ zfcp_erp_port_reopen(unit->port, 0, "fssfch2", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_SERVICE_CLASS_NOT_SUPPORTED:
@@ -2258,7 +2237,8 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req)
req->qtcb->bottom.io.data_direction,
(unsigned long long)unit->fcp_lun,
(unsigned long long)unit->port->wwpn);
- zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 133, req);
+ zfcp_erp_adapter_shutdown(unit->port->adapter, 0, "fssfch3",
+ req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_CMND_LENGTH_NOT_VALID:
@@ -2268,16 +2248,17 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req)
req->qtcb->bottom.io.fcp_cmnd_length,
(unsigned long long)unit->fcp_lun,
(unsigned long long)unit->port->wwpn);
- zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 134, req);
+ zfcp_erp_adapter_shutdown(unit->port->adapter, 0, "fssfch4",
+ req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_PORT_BOXED:
- zfcp_erp_port_boxed(unit->port, 53, req);
+ zfcp_erp_port_boxed(unit->port, "fssfch5", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
ZFCP_STATUS_FSFREQ_RETRY;
break;
case FSF_LUN_BOXED:
- zfcp_erp_unit_boxed(unit, 54, req);
+ zfcp_erp_unit_boxed(unit, "fssfch6", req);
req->status |= ZFCP_STATUS_FSFREQ_ERROR |
ZFCP_STATUS_FSFREQ_RETRY;
break;
@@ -2314,30 +2295,29 @@ static void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, u32 fcp_dl)
/**
* zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command)
- * @adapter: adapter where scsi command is issued
* @unit: unit where command is sent to
* @scsi_cmnd: scsi command to be sent
- * @timer: timer to be started when request is initiated
- * @req_flags: flags for fsf_request
*/
-int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
- struct zfcp_unit *unit,
- struct scsi_cmnd *scsi_cmnd,
- int use_timer, int req_flags)
+int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
+ struct scsi_cmnd *scsi_cmnd)
{
struct zfcp_fsf_req *req;
struct fcp_cmnd_iu *fcp_cmnd_iu;
unsigned int sbtype;
int real_bytes, retval = -EIO;
+ struct zfcp_adapter *adapter = unit->port->adapter;
if (unlikely(!(atomic_read(&unit->status) &
ZFCP_STATUS_COMMON_UNBLOCKED)))
return -EBUSY;
spin_lock(&adapter->req_q_lock);
- if (!zfcp_fsf_sbal_available(adapter))
+ if (atomic_read(&adapter->req_q.count) <= 0) {
+ atomic_inc(&adapter->qdio_outb_full);
goto out;
- req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
+ }
+ req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND,
+ ZFCP_REQ_AUTO_CLEANUP,
adapter->pool.fsf_req_scsi);
if (IS_ERR(req)) {
retval = PTR_ERR(req);
@@ -2411,7 +2391,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
"on port 0x%016Lx closed\n",
(unsigned long long)unit->fcp_lun,
(unsigned long long)unit->port->wwpn);
- zfcp_erp_unit_shutdown(unit, 0, 131, req);
+ zfcp_erp_unit_shutdown(unit, 0, "fssfct1", req);
retval = -EINVAL;
}
goto failed_scsi_cmnd;
@@ -2419,9 +2399,6 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
zfcp_set_fcp_dl(fcp_cmnd_iu, real_bytes);
- if (use_timer)
- zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
-
retval = zfcp_fsf_req_send(req);
if (unlikely(retval))
goto failed_scsi_cmnd;
@@ -2439,28 +2416,25 @@ out:
/**
* zfcp_fsf_send_fcp_ctm - send SCSI task management command
- * @adapter: pointer to struct zfcp-adapter
* @unit: pointer to struct zfcp_unit
* @tm_flags: unsigned byte for task management flags
- * @req_flags: int request flags
* Returns: on success pointer to struct fsf_req, NULL otherwise
*/
-struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter,
- struct zfcp_unit *unit,
- u8 tm_flags, int req_flags)
+struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags)
{
struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *req = NULL;
struct fcp_cmnd_iu *fcp_cmnd_iu;
+ struct zfcp_adapter *adapter = unit->port->adapter;
if (unlikely(!(atomic_read(&unit->status) &
ZFCP_STATUS_COMMON_UNBLOCKED)))
return NULL;
- spin_lock(&adapter->req_q_lock);
- if (!zfcp_fsf_sbal_available(adapter))
+ spin_lock_bh(&adapter->req_q_lock);
+ if (zfcp_fsf_req_sbal_get(adapter))
goto out;
- req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
+ req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, 0,
adapter->pool.fsf_req_scsi);
if (IS_ERR(req)) {
req = NULL;
@@ -2492,7 +2466,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter,
zfcp_fsf_req_free(req);
req = NULL;
out:
- spin_unlock(&adapter->req_q_lock);
+ spin_unlock_bh(&adapter->req_q_lock);
return req;
}
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h
index 8bb200252347..df7f232faba8 100644
--- a/drivers/s390/scsi/zfcp_fsf.h
+++ b/drivers/s390/scsi/zfcp_fsf.h
@@ -127,10 +127,6 @@
#define FSF_STATUS_READ_CFDC_UPDATED 0x0000000A
#define FSF_STATUS_READ_FEATURE_UPDATE_ALERT 0x0000000C
-/* status subtypes in status read buffer */
-#define FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT 0x00000001
-#define FSF_STATUS_READ_SUB_ERROR_PORT 0x00000002
-
/* status subtypes for link down */
#define FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK 0x00000000
#define FSF_STATUS_READ_SUB_FDISC_FAILED 0x00000001
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 33e0a206a0a4..e0a215309df0 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -11,9 +11,6 @@
#include "zfcp_ext.h"
-/* FIXME(tune): free space should be one max. SBAL chain plus what? */
-#define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \
- - (FSF_MAX_SBALS_PER_REQ + 4))
#define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer))
static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal)
@@ -58,7 +55,7 @@ void zfcp_qdio_free(struct zfcp_adapter *adapter)
}
}
-static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, u8 id)
+static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, char *id)
{
dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n");
@@ -77,6 +74,23 @@ static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt)
}
}
+/* this needs to be called prior to updating the queue fill level */
+static void zfcp_qdio_account(struct zfcp_adapter *adapter)
+{
+ ktime_t now;
+ s64 span;
+ int free, used;
+
+ spin_lock(&adapter->qdio_stat_lock);
+ now = ktime_get();
+ span = ktime_us_delta(now, adapter->req_q_time);
+ free = max(0, atomic_read(&adapter->req_q.count));
+ used = QDIO_MAX_BUFFERS_PER_Q - free;
+ adapter->req_q_util += used * span;
+ adapter->req_q_time = now;
+ spin_unlock(&adapter->qdio_stat_lock);
+}
+
static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
int queue_no, int first, int count,
unsigned long parm)
@@ -86,13 +100,14 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
if (unlikely(qdio_err)) {
zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count);
- zfcp_qdio_handler_error(adapter, 140);
+ zfcp_qdio_handler_error(adapter, "qdireq1");
return;
}
/* cleanup all SBALs being program-owned now */
zfcp_qdio_zero_sbals(queue->sbal, first, count);
+ zfcp_qdio_account(adapter);
atomic_add(count, &queue->count);
wake_up(&adapter->request_wq);
}
@@ -154,7 +169,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
if (unlikely(qdio_err)) {
zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count);
- zfcp_qdio_handler_error(adapter, 147);
+ zfcp_qdio_handler_error(adapter, "qdires1");
return;
}
@@ -346,21 +361,12 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
struct zfcp_qdio_queue *req_q = &adapter->req_q;
int first = fsf_req->sbal_first;
int count = fsf_req->sbal_number;
- int retval, pci, pci_batch;
- struct qdio_buffer_element *sbale;
+ int retval;
+ unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
- /* acknowledgements for transferred buffers */
- pci_batch = adapter->req_q_pci_batch + count;
- if (unlikely(pci_batch >= ZFCP_QDIO_PCI_INTERVAL)) {
- pci_batch %= ZFCP_QDIO_PCI_INTERVAL;
- pci = first + count - (pci_batch + 1);
- pci %= QDIO_MAX_BUFFERS_PER_Q;
- sbale = zfcp_qdio_sbale(req_q, pci, 0);
- sbale->flags |= SBAL_FLAGS0_PCI;
- }
+ zfcp_qdio_account(adapter);
- retval = do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, first,
- count);
+ retval = do_QDIO(adapter->ccw_device, qdio_flags, 0, first, count);
if (unlikely(retval)) {
zfcp_qdio_zero_sbals(req_q->sbal, first, count);
return retval;
@@ -370,7 +376,6 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
atomic_sub(count, &req_q->count);
req_q->first += count;
req_q->first %= QDIO_MAX_BUFFERS_PER_Q;
- adapter->req_q_pci_batch = pci_batch;
return 0;
}
@@ -441,7 +446,6 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
}
req_q->first = 0;
atomic_set(&req_q->count, 0);
- adapter->req_q_pci_batch = 0;
adapter->resp_q.first = 0;
atomic_set(&adapter->resp_q.count, 0);
}
@@ -479,7 +483,6 @@ int zfcp_qdio_open(struct zfcp_adapter *adapter)
/* set index of first avalable SBALS / number of available SBALS */
adapter->req_q.first = 0;
atomic_set(&adapter->req_q.count, QDIO_MAX_BUFFERS_PER_Q);
- adapter->req_q_pci_batch = 0;
return 0;
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 9dc42a68fbdd..58201e1ae478 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -3,7 +3,7 @@
*
* Interface to Linux SCSI midlayer.
*
- * Copyright IBM Corporation 2002, 2008
+ * Copyright IBM Corporation 2002, 2009
*/
#define KMSG_COMPONENT "zfcp"
@@ -27,9 +27,7 @@ char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu)
static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
{
struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
- atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status);
unit->device = NULL;
- zfcp_erp_unit_failed(unit, 12, NULL);
zfcp_unit_put(unit);
}
@@ -58,8 +56,8 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
{
struct zfcp_unit *unit;
struct zfcp_adapter *adapter;
- int status;
- int ret;
+ int status, scsi_result, ret;
+ struct fc_rport *rport = starget_to_rport(scsi_target(scpnt->device));
/* reset the status for this request */
scpnt->result = 0;
@@ -81,6 +79,14 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
return 0;
}
+ scsi_result = fc_remote_port_chkready(rport);
+ if (unlikely(scsi_result)) {
+ scpnt->result = scsi_result;
+ zfcp_scsi_dbf_event_result("fail", 4, adapter, scpnt, NULL);
+ scpnt->scsi_done(scpnt);
+ return 0;
+ }
+
status = atomic_read(&unit->status);
if (unlikely((status & ZFCP_STATUS_COMMON_ERP_FAILED) ||
!(status & ZFCP_STATUS_COMMON_RUNNING))) {
@@ -88,8 +94,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
return 0;;
}
- ret = zfcp_fsf_send_fcp_command_task(adapter, unit, scpnt, 0,
- ZFCP_REQ_AUTO_CLEANUP);
+ ret = zfcp_fsf_send_fcp_command_task(unit, scpnt);
if (unlikely(ret == -EBUSY))
return SCSI_MLQUEUE_DEVICE_BUSY;
else if (unlikely(ret < 0))
@@ -133,8 +138,7 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdp)
read_lock_irqsave(&zfcp_data.config_lock, flags);
unit = zfcp_unit_lookup(adapter, sdp->channel, sdp->id, sdp->lun);
- if (unit &&
- (atomic_read(&unit->status) & ZFCP_STATUS_UNIT_REGISTERED)) {
+ if (unit) {
sdp->hostdata = unit;
unit->device = sdp;
zfcp_unit_get(unit);
@@ -147,79 +151,91 @@ out:
static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
{
- struct Scsi_Host *scsi_host;
- struct zfcp_adapter *adapter;
- struct zfcp_unit *unit;
- struct zfcp_fsf_req *fsf_req;
+ struct Scsi_Host *scsi_host = scpnt->device->host;
+ struct zfcp_adapter *adapter =
+ (struct zfcp_adapter *) scsi_host->hostdata[0];
+ struct zfcp_unit *unit = scpnt->device->hostdata;
+ struct zfcp_fsf_req *old_req, *abrt_req;
unsigned long flags;
unsigned long old_req_id = (unsigned long) scpnt->host_scribble;
int retval = SUCCESS;
-
- scsi_host = scpnt->device->host;
- adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
- unit = scpnt->device->hostdata;
+ int retry = 3;
/* avoid race condition between late normal completion and abort */
write_lock_irqsave(&adapter->abort_lock, flags);
- /* Check whether corresponding fsf_req is still pending */
spin_lock(&adapter->req_list_lock);
- fsf_req = zfcp_reqlist_find(adapter, old_req_id);
+ old_req = zfcp_reqlist_find(adapter, old_req_id);
spin_unlock(&adapter->req_list_lock);
- if (!fsf_req) {
+ if (!old_req) {
write_unlock_irqrestore(&adapter->abort_lock, flags);
- zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, 0);
- return retval;
+ zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL,
+ old_req_id);
+ return SUCCESS;
}
- fsf_req->data = NULL;
+ old_req->data = NULL;
/* don't access old fsf_req after releasing the abort_lock */
write_unlock_irqrestore(&adapter->abort_lock, flags);
- fsf_req = zfcp_fsf_abort_fcp_command(old_req_id, adapter, unit, 0);
- if (!fsf_req) {
- zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL,
- old_req_id);
- retval = FAILED;
- return retval;
+ while (retry--) {
+ abrt_req = zfcp_fsf_abort_fcp_command(old_req_id, unit);
+ if (abrt_req)
+ break;
+
+ zfcp_erp_wait(adapter);
+ if (!(atomic_read(&adapter->status) &
+ ZFCP_STATUS_COMMON_RUNNING)) {
+ zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL,
+ old_req_id);
+ return SUCCESS;
+ }
}
+ if (!abrt_req)
+ return FAILED;
- __wait_event(fsf_req->completion_wq,
- fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
+ wait_event(abrt_req->completion_wq,
+ abrt_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
- if (fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {
- zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, fsf_req, 0);
- } else if (fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {
- zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, fsf_req, 0);
- } else {
- zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, fsf_req, 0);
+ if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED)
+ zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, abrt_req, 0);
+ else if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED)
+ zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, abrt_req, 0);
+ else {
+ zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, abrt_req, 0);
retval = FAILED;
}
- zfcp_fsf_req_free(fsf_req);
-
+ zfcp_fsf_req_free(abrt_req);
return retval;
}
-static int zfcp_task_mgmt_function(struct zfcp_unit *unit, u8 tm_flags,
- struct scsi_cmnd *scpnt)
+static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
{
+ struct zfcp_unit *unit = scpnt->device->hostdata;
struct zfcp_adapter *adapter = unit->port->adapter;
struct zfcp_fsf_req *fsf_req;
int retval = SUCCESS;
-
- /* issue task management function */
- fsf_req = zfcp_fsf_send_fcp_ctm(adapter, unit, tm_flags, 0);
- if (!fsf_req) {
- zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit, scpnt);
- return FAILED;
+ int retry = 3;
+
+ while (retry--) {
+ fsf_req = zfcp_fsf_send_fcp_ctm(unit, tm_flags);
+ if (fsf_req)
+ break;
+
+ zfcp_erp_wait(adapter);
+ if (!(atomic_read(&adapter->status) &
+ ZFCP_STATUS_COMMON_RUNNING)) {
+ zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit,
+ scpnt);
+ return SUCCESS;
+ }
}
+ if (!fsf_req)
+ return FAILED;
- __wait_event(fsf_req->completion_wq,
- fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
+ wait_event(fsf_req->completion_wq,
+ fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
- /*
- * check completion status of task management function
- */
if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
zfcp_scsi_dbf_event_devreset("fail", tm_flags, unit, scpnt);
retval = FAILED;
@@ -230,40 +246,25 @@ static int zfcp_task_mgmt_function(struct zfcp_unit *unit, u8 tm_flags,
zfcp_scsi_dbf_event_devreset("okay", tm_flags, unit, scpnt);
zfcp_fsf_req_free(fsf_req);
-
return retval;
}
static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
{
- struct zfcp_unit *unit = scpnt->device->hostdata;
-
- if (!unit) {
- WARN_ON(1);
- return SUCCESS;
- }
- return zfcp_task_mgmt_function(unit, FCP_LOGICAL_UNIT_RESET, scpnt);
+ return zfcp_task_mgmt_function(scpnt, FCP_LOGICAL_UNIT_RESET);
}
static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
{
- struct zfcp_unit *unit = scpnt->device->hostdata;
-
- if (!unit) {
- WARN_ON(1);
- return SUCCESS;
- }
- return zfcp_task_mgmt_function(unit, FCP_TARGET_RESET, scpnt);
+ return zfcp_task_mgmt_function(scpnt, FCP_TARGET_RESET);
}
static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
{
- struct zfcp_unit *unit;
- struct zfcp_adapter *adapter;
+ struct zfcp_unit *unit = scpnt->device->hostdata;
+ struct zfcp_adapter *adapter = unit->port->adapter;
- unit = scpnt->device->hostdata;
- adapter = unit->port->adapter;
- zfcp_erp_adapter_reopen(adapter, 0, 141, scpnt);
+ zfcp_erp_adapter_reopen(adapter, 0, "schrh_1", scpnt);
zfcp_erp_wait(adapter);
return SUCCESS;
@@ -479,6 +480,109 @@ static void zfcp_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
rport->dev_loss_tmo = timeout;
}
+/**
+ * zfcp_scsi_dev_loss_tmo_callbk - Free any reference to rport
+ * @rport: The rport that is about to be deleted.
+ */
+static void zfcp_scsi_dev_loss_tmo_callbk(struct fc_rport *rport)
+{
+ struct zfcp_port *port = rport->dd_data;
+
+ write_lock_irq(&zfcp_data.config_lock);
+ port->rport = NULL;
+ write_unlock_irq(&zfcp_data.config_lock);
+}
+
+/**
+ * zfcp_scsi_terminate_rport_io - Terminate all I/O on a rport
+ * @rport: The FC rport where to teminate I/O
+ *
+ * Abort all pending SCSI commands for a port by closing the
+ * port. Using a reopen for avoids a conflict with a shutdown
+ * overwriting a reopen.
+ */
+static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
+{
+ struct zfcp_port *port = rport->dd_data;
+
+ zfcp_erp_port_reopen(port, 0, "sctrpi1", NULL);
+}
+
+static void zfcp_scsi_rport_register(struct zfcp_port *port)
+{
+ struct fc_rport_identifiers ids;
+ struct fc_rport *rport;
+
+ ids.node_name = port->wwnn;
+ ids.port_name = port->wwpn;
+ ids.port_id = port->d_id;
+ ids.roles = FC_RPORT_ROLE_FCP_TARGET;
+
+ rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids);
+ if (!rport) {
+ dev_err(&port->adapter->ccw_device->dev,
+ "Registering port 0x%016Lx failed\n",
+ (unsigned long long)port->wwpn);
+ return;
+ }
+
+ rport->dd_data = port;
+ rport->maxframe_size = port->maxframe_size;
+ rport->supported_classes = port->supported_classes;
+ port->rport = rport;
+}
+
+static void zfcp_scsi_rport_block(struct zfcp_port *port)
+{
+ if (port->rport)
+ fc_remote_port_delete(port->rport);
+}
+
+void zfcp_scsi_schedule_rport_register(struct zfcp_port *port)
+{
+ zfcp_port_get(port);
+ port->rport_task = RPORT_ADD;
+
+ if (!queue_work(zfcp_data.work_queue, &port->rport_work))
+ zfcp_port_put(port);
+}
+
+void zfcp_scsi_schedule_rport_block(struct zfcp_port *port)
+{
+ zfcp_port_get(port);
+ port->rport_task = RPORT_DEL;
+
+ if (!queue_work(zfcp_data.work_queue, &port->rport_work))
+ zfcp_port_put(port);
+}
+
+void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *adapter)
+{
+ struct zfcp_port *port;
+
+ list_for_each_entry(port, &adapter->port_list_head, list)
+ zfcp_scsi_schedule_rport_block(port);
+}
+
+void zfcp_scsi_rport_work(struct work_struct *work)
+{
+ struct zfcp_port *port = container_of(work, struct zfcp_port,
+ rport_work);
+
+ while (port->rport_task) {
+ if (port->rport_task == RPORT_ADD) {
+ port->rport_task = RPORT_NONE;
+ zfcp_scsi_rport_register(port);
+ } else {
+ port->rport_task = RPORT_NONE;
+ zfcp_scsi_rport_block(port);
+ }
+ }
+
+ zfcp_port_put(port);
+}
+
+
struct fc_function_template zfcp_transport_functions = {
.show_starget_port_id = 1,
.show_starget_port_name = 1,
@@ -497,6 +601,8 @@ struct fc_function_template zfcp_transport_functions = {
.reset_fc_host_stats = zfcp_reset_fc_host_stats,
.set_rport_dev_loss_tmo = zfcp_set_rport_dev_loss_tmo,
.get_host_port_state = zfcp_get_host_port_state,
+ .dev_loss_tmo_callbk = zfcp_scsi_dev_loss_tmo_callbk,
+ .terminate_rport_io = zfcp_scsi_terminate_rport_io,
.show_host_port_state = 1,
/* no functions registered for following dynamic attributes but
directly set by LLDD */
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index 899af2b45b1e..9a3b8e261c0a 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -112,9 +112,9 @@ static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO, \
zfcp_sysfs_##_feat##_failed_show, \
zfcp_sysfs_##_feat##_failed_store);
-ZFCP_SYSFS_FAILED(zfcp_adapter, adapter, adapter, 44, 93);
-ZFCP_SYSFS_FAILED(zfcp_port, port, port->adapter, 45, 96);
-ZFCP_SYSFS_FAILED(zfcp_unit, unit, unit->port->adapter, 46, 97);
+ZFCP_SYSFS_FAILED(zfcp_adapter, adapter, adapter, "syafai1", "syafai2");
+ZFCP_SYSFS_FAILED(zfcp_port, port, port->adapter, "sypfai1", "sypfai2");
+ZFCP_SYSFS_FAILED(zfcp_unit, unit, unit->port->adapter, "syufai1", "syufai2");
static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
struct device_attribute *attr,
@@ -168,7 +168,7 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
goto out;
}
- zfcp_erp_port_shutdown(port, 0, 92, NULL);
+ zfcp_erp_port_shutdown(port, 0, "syprs_1", NULL);
zfcp_erp_wait(adapter);
zfcp_port_put(port);
zfcp_port_dequeue(port);
@@ -222,7 +222,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
retval = 0;
- zfcp_erp_unit_reopen(unit, 0, 94, NULL);
+ zfcp_erp_unit_reopen(unit, 0, "syuas_1", NULL);
zfcp_erp_wait(unit->port->adapter);
zfcp_unit_put(unit);
out:
@@ -268,7 +268,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
goto out;
}
- zfcp_erp_unit_shutdown(unit, 0, 95, NULL);
+ zfcp_erp_unit_shutdown(unit, 0, "syurs_1", NULL);
zfcp_erp_wait(unit->port->adapter);
zfcp_unit_put(unit);
zfcp_unit_dequeue(unit);
@@ -318,10 +318,9 @@ zfcp_sysfs_unit_##_name##_latency_show(struct device *dev, \
struct zfcp_unit *unit = sdev->hostdata; \
struct zfcp_latencies *lat = &unit->latencies; \
struct zfcp_adapter *adapter = unit->port->adapter; \
- unsigned long flags; \
unsigned long long fsum, fmin, fmax, csum, cmin, cmax, cc; \
\
- spin_lock_irqsave(&lat->lock, flags); \
+ spin_lock_bh(&lat->lock); \
fsum = lat->_name.fabric.sum * adapter->timer_ticks; \
fmin = lat->_name.fabric.min * adapter->timer_ticks; \
fmax = lat->_name.fabric.max * adapter->timer_ticks; \
@@ -329,7 +328,7 @@ zfcp_sysfs_unit_##_name##_latency_show(struct device *dev, \
cmin = lat->_name.channel.min * adapter->timer_ticks; \
cmax = lat->_name.channel.max * adapter->timer_ticks; \
cc = lat->_name.counter; \
- spin_unlock_irqrestore(&lat->lock, flags); \
+ spin_unlock_bh(&lat->lock); \
\
do_div(fsum, 1000); \
do_div(fmin, 1000); \
@@ -487,7 +486,8 @@ static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev,
struct zfcp_adapter *adapter =
(struct zfcp_adapter *) scsi_host->hostdata[0];
- return sprintf(buf, "%d\n", atomic_read(&adapter->qdio_outb_full));
+ return sprintf(buf, "%d %llu\n", atomic_read(&adapter->qdio_outb_full),
+ (unsigned long long)adapter->req_q_util);
}
static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL);
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 29dc735e1a20..124f660a0383 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -51,6 +51,7 @@ MODULE_AUTHOR("Thomas K. Dyas (tdyas@noc.rutgers.edu) and Eddie C. Dost (ecd@sk
MODULE_DESCRIPTION("OPENPROM Configuration Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");
+MODULE_ALIAS_MISCDEV(SUN_OPENPROM_MINOR);
/* Private data kept by the driver for each descriptor. */
typedef struct openprom_private_data
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 5311317c2e4c..a12783ebb42d 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -4,7 +4,7 @@
Written By: Adam Radford <linuxraid@amcc.com>
Modifications By: Tom Couch <linuxraid@amcc.com>
- Copyright (C) 2004-2008 Applied Micro Circuits Corporation.
+ Copyright (C) 2004-2009 Applied Micro Circuits Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -75,6 +75,7 @@
Add MSI support and "use_msi" module parameter.
Fix bug in twa_get_param() on 4GB+.
Use pci_resource_len() for ioremap().
+ 2.26.02.012 - Add power management support.
*/
#include <linux/module.h>
@@ -99,7 +100,7 @@
#include "3w-9xxx.h"
/* Globals */
-#define TW_DRIVER_VERSION "2.26.02.011"
+#define TW_DRIVER_VERSION "2.26.02.012"
static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
static unsigned int twa_device_extension_count;
static int twa_major = -1;
@@ -2182,6 +2183,98 @@ static void twa_remove(struct pci_dev *pdev)
twa_device_extension_count--;
} /* End twa_remove() */
+#ifdef CONFIG_PM
+/* This function is called on PCI suspend */
+static int twa_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct Scsi_Host *host = pci_get_drvdata(pdev);
+ TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+
+ printk(KERN_WARNING "3w-9xxx: Suspending host %d.\n", tw_dev->host->host_no);
+
+ TW_DISABLE_INTERRUPTS(tw_dev);
+ free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
+
+ if (test_bit(TW_USING_MSI, &tw_dev->flags))
+ pci_disable_msi(pdev);
+
+ /* Tell the card we are shutting down */
+ if (twa_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
+ TW_PRINTK(tw_dev->host, TW_DRIVER, 0x38, "Connection shutdown failed during suspend");
+ } else {
+ printk(KERN_WARNING "3w-9xxx: Suspend complete.\n");
+ }
+ TW_CLEAR_ALL_INTERRUPTS(tw_dev);
+
+ pci_save_state(pdev);
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+} /* End twa_suspend() */
+
+/* This function is called on PCI resume */
+static int twa_resume(struct pci_dev *pdev)
+{
+ int retval = 0;
+ struct Scsi_Host *host = pci_get_drvdata(pdev);
+ TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
+
+ printk(KERN_WARNING "3w-9xxx: Resuming host %d.\n", tw_dev->host->host_no);
+ pci_set_power_state(pdev, PCI_D0);
+ pci_enable_wake(pdev, PCI_D0, 0);
+ pci_restore_state(pdev);
+
+ retval = pci_enable_device(pdev);
+ if (retval) {
+ TW_PRINTK(tw_dev->host, TW_DRIVER, 0x39, "Enable device failed during resume");
+ return retval;
+ }
+
+ pci_set_master(pdev);
+ pci_try_set_mwi(pdev);
+
+ if (pci_set_dma_mask(pdev, DMA_64BIT_MASK)
+ || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
+ if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)
+ || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+ TW_PRINTK(host, TW_DRIVER, 0x40, "Failed to set dma mask during resume");
+ retval = -ENODEV;
+ goto out_disable_device;
+ }
+
+ /* Initialize the card */
+ if (twa_reset_sequence(tw_dev, 0)) {
+ retval = -ENODEV;
+ goto out_disable_device;
+ }
+
+ /* Now setup the interrupt handler */
+ retval = request_irq(pdev->irq, twa_interrupt, IRQF_SHARED, "3w-9xxx", tw_dev);
+ if (retval) {
+ TW_PRINTK(tw_dev->host, TW_DRIVER, 0x42, "Error requesting IRQ during resume");
+ retval = -ENODEV;
+ goto out_disable_device;
+ }
+
+ /* Now enable MSI if enabled */
+ if (test_bit(TW_USING_MSI, &tw_dev->flags))
+ pci_enable_msi(pdev);
+
+ /* Re-enable interrupts on the card */
+ TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
+
+ printk(KERN_WARNING "3w-9xxx: Resume complete.\n");
+ return 0;
+
+out_disable_device:
+ scsi_remove_host(host);
+ pci_disable_device(pdev);
+
+ return retval;
+} /* End twa_resume() */
+#endif
+
/* PCI Devices supported by this driver */
static struct pci_device_id twa_pci_tbl[] __devinitdata = {
{ PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000,
@@ -2202,6 +2295,10 @@ static struct pci_driver twa_driver = {
.id_table = twa_pci_tbl,
.probe = twa_probe,
.remove = twa_remove,
+#ifdef CONFIG_PM
+ .suspend = twa_suspend,
+ .resume = twa_resume,
+#endif
.shutdown = twa_shutdown
};
diff --git a/drivers/scsi/3w-9xxx.h b/drivers/scsi/3w-9xxx.h
index 1729a8785fea..2893eec78ed2 100644
--- a/drivers/scsi/3w-9xxx.h
+++ b/drivers/scsi/3w-9xxx.h
@@ -4,7 +4,7 @@
Written By: Adam Radford <linuxraid@amcc.com>
Modifications By: Tom Couch <linuxraid@amcc.com>
- Copyright (C) 2004-2008 Applied Micro Circuits Corporation.
+ Copyright (C) 2004-2009 Applied Micro Circuits Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 256c7bec7bd7..8ed2990c826e 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -121,10 +121,11 @@ config BLK_DEV_SR
tristate "SCSI CDROM support"
depends on SCSI
---help---
- If you want to use a SCSI or FireWire CD-ROM under Linux,
- say Y and read the SCSI-HOWTO and the CDROM-HOWTO at
- <http://www.tldp.org/docs.html#howto>. Also make sure to say
- Y or M to "ISO 9660 CD-ROM file system support" later.
+ If you want to use a CD or DVD drive attached to your computer
+ by SCSI, FireWire, USB or ATAPI, say Y and read the SCSI-HOWTO
+ and the CDROM-HOWTO at <http://www.tldp.org/docs.html#howto>.
+
+ Make sure to say Y or M to "ISO 9660 CD-ROM file system support".
To compile this driver as a module, choose M here and read
<file:Documentation/scsi/scsi.txt>.
@@ -224,14 +225,15 @@ config SCSI_LOGGING
can enable logging by saying Y to "/proc file system support" and
"Sysctl support" below and executing the command
- echo "scsi log token [level]" > /proc/scsi/scsi
+ echo <bitmask> > /proc/sys/dev/scsi/logging_level
- at boot time after the /proc file system has been mounted.
+ where <bitmask> is a four byte value representing the logging type
+ and logging level for each type of logging selected.
- There are a number of things that can be used for 'token' (you can
- find them in the source: <file:drivers/scsi/scsi.c>), and this
- allows you to select the types of information you want, and the
- level allows you to select the level of verbosity.
+ There are a number of logging types and you can find them in the
+ source at <file:drivers/scsi/scsi_logging.h>. The logging levels
+ are also described in that file and they determine the verbosity of
+ the logging for each logging type.
If you say N here, it may be harder to track down some types of SCSI
problems. If you say Y here your kernel will be somewhat larger, but
@@ -570,6 +572,7 @@ config SCSI_ARCMSR_AER
To enable this function, choose Y here.
source "drivers/scsi/megaraid/Kconfig.megaraid"
+source "drivers/scsi/mpt2sas/Kconfig"
config SCSI_HPTIOP
tristate "HighPoint RocketRAID 3xxx/4xxx Controller support"
@@ -608,13 +611,20 @@ config SCSI_FLASHPOINT
config LIBFC
tristate "LibFC module"
select SCSI_FC_ATTRS
+ select CRC32
---help---
Fibre Channel library module
+config LIBFCOE
+ tristate "LibFCoE module"
+ select LIBFC
+ ---help---
+ Library for Fibre Channel over Ethernet module
+
config FCOE
tristate "FCoE module"
depends on PCI
- select LIBFC
+ select LIBFCOE
---help---
Fibre Channel over Ethernet module
@@ -1377,7 +1387,7 @@ config SCSI_LPFC_DEBUG_FS
bool "Emulex LightPulse Fibre Channel debugfs Support"
depends on SCSI_LPFC && DEBUG_FS
help
- This makes debugging infomation from the lpfc driver
+ This makes debugging information from the lpfc driver
available via the debugfs filesystem.
config SCSI_SIM710
@@ -1385,7 +1395,7 @@ config SCSI_SIM710
depends on (EISA || MCA) && SCSI
select SCSI_SPI_ATTRS
---help---
- This driver for NCR53c710 based SCSI host adapters.
+ This driver is for NCR53c710 based SCSI host adapters.
It currently supports Compaq EISA cards and NCR MCA cards
@@ -1535,6 +1545,7 @@ config SCSI_NSP32
config SCSI_DEBUG
tristate "SCSI debugging host simulator"
depends on SCSI
+ select CRC_T10DIF
help
This is a host adapter simulator that can simulate multiple hosts
each with multiple dummy SCSI devices (disks). It defaults to one
@@ -1803,4 +1814,6 @@ source "drivers/scsi/pcmcia/Kconfig"
source "drivers/scsi/device_handler/Kconfig"
+source "drivers/scsi/osd/Kconfig"
+
endmenu
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 7461eb09a031..e7c861ac417d 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_SCSI_SRP_ATTRS) += scsi_transport_srp.o
obj-$(CONFIG_SCSI_DH) += device_handler/
obj-$(CONFIG_LIBFC) += libfc/
+obj-$(CONFIG_LIBFCOE) += fcoe/
obj-$(CONFIG_FCOE) += fcoe/
obj-$(CONFIG_ISCSI_TCP) += libiscsi.o libiscsi_tcp.o iscsi_tcp.o
obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o
@@ -99,6 +100,7 @@ obj-$(CONFIG_SCSI_DC390T) += tmscsim.o
obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o
obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
obj-$(CONFIG_MEGARAID_SAS) += megaraid/
+obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas/
obj-$(CONFIG_SCSI_ACARD) += atp870u.o
obj-$(CONFIG_SCSI_SUNESP) += esp_scsi.o sun_esp.o
obj-$(CONFIG_SCSI_GDTH) += gdth.o
@@ -137,6 +139,8 @@ obj-$(CONFIG_CHR_DEV_SG) += sg.o
obj-$(CONFIG_CHR_DEV_SCH) += ch.o
obj-$(CONFIG_SCSI_ENCLOSURE) += ses.o
+obj-$(CONFIG_SCSI_OSD_INITIATOR) += osd/
+
# This goes last, so that "real" scsi devices probe earlier
obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index 37dd47136fb1..4b38c4750f77 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -23,6 +23,8 @@
#define DMA(ptr) ((a2091_scsiregs *)((ptr)->base))
#define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata))
+static int a2091_release(struct Scsi_Host *instance);
+
static irqreturn_t a2091_intr (int irq, void *_instance)
{
unsigned long flags;
@@ -144,7 +146,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
}
}
-int __init a2091_detect(struct scsi_host_template *tpnt)
+static int __init a2091_detect(struct scsi_host_template *tpnt)
{
static unsigned char called = 0;
struct Scsi_Host *instance;
@@ -233,7 +235,7 @@ static struct scsi_host_template driver_template = {
#include "scsi_module.c"
-int a2091_release(struct Scsi_Host *instance)
+static int a2091_release(struct Scsi_Host *instance)
{
#ifdef MODULE
DMA(instance)->CNTR = 0;
diff --git a/drivers/scsi/a2091.h b/drivers/scsi/a2091.h
index fe809bc88d73..252528f2672e 100644
--- a/drivers/scsi/a2091.h
+++ b/drivers/scsi/a2091.h
@@ -11,9 +11,6 @@
#include <linux/types.h>
-int a2091_detect(struct scsi_host_template *);
-int a2091_release(struct Scsi_Host *);
-
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c
index 8b449d8acacd..6970ce82c4ac 100644
--- a/drivers/scsi/a3000.c
+++ b/drivers/scsi/a3000.c
@@ -25,6 +25,8 @@
static struct Scsi_Host *a3000_host = NULL;
+static int a3000_release(struct Scsi_Host *instance);
+
static irqreturn_t a3000_intr (int irq, void *dummy)
{
unsigned long flags;
@@ -157,7 +159,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
}
}
-int __init a3000_detect(struct scsi_host_template *tpnt)
+static int __init a3000_detect(struct scsi_host_template *tpnt)
{
wd33c93_regs regs;
@@ -232,7 +234,7 @@ static struct scsi_host_template driver_template = {
#include "scsi_module.c"
-int a3000_release(struct Scsi_Host *instance)
+static int a3000_release(struct Scsi_Host *instance)
{
wd33c93_release();
DMA(instance)->CNTR = 0;
diff --git a/drivers/scsi/a3000.h b/drivers/scsi/a3000.h
index 44a4ec7b4650..c7afe16fd6e4 100644
--- a/drivers/scsi/a3000.h
+++ b/drivers/scsi/a3000.h
@@ -11,9 +11,6 @@
#include <linux/types.h>
-int a3000_detect(struct scsi_host_template *);
-int a3000_release(struct Scsi_Host *);
-
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c
index d4bda2017746..61af3d91ac8a 100644
--- a/drivers/scsi/a4000t.c
+++ b/drivers/scsi/a4000t.c
@@ -35,7 +35,7 @@ static struct platform_device *a4000t_scsi_device;
#define A4000T_SCSI_ADDR 0xdd0040
-static int __devinit a4000t_probe(struct device *dev)
+static int __devinit a4000t_probe(struct platform_device *dev)
{
struct Scsi_Host *host;
struct NCR_700_Host_Parameters *hostdata;
@@ -61,7 +61,8 @@ static int __devinit a4000t_probe(struct device *dev)
hostdata->dcntl_extra = EA_710;
/* and register the chip */
- host = NCR_700_detect(&a4000t_scsi_driver_template, hostdata, dev);
+ host = NCR_700_detect(&a4000t_scsi_driver_template, hostdata,
+ &dev->dev);
if (!host) {
printk(KERN_ERR "a4000t-scsi: No host detected; "
"board configuration problem?\n");
@@ -78,7 +79,7 @@ static int __devinit a4000t_probe(struct device *dev)
goto out_put_host;
}
- dev_set_drvdata(dev, host);
+ platform_set_drvdata(dev, host);
scsi_scan_host(host);
return 0;
@@ -93,9 +94,9 @@ static int __devinit a4000t_probe(struct device *dev)
return -ENODEV;
}
-static __devexit int a4000t_device_remove(struct device *dev)
+static __devexit int a4000t_device_remove(struct platform_device *dev)
{
- struct Scsi_Host *host = dev_get_drvdata(dev);
+ struct Scsi_Host *host = platform_get_drvdata(dev);
struct NCR_700_Host_Parameters *hostdata = shost_priv(host);
scsi_remove_host(host);
@@ -108,25 +109,27 @@ static __devexit int a4000t_device_remove(struct device *dev)
return 0;
}
-static struct device_driver a4000t_scsi_driver = {
- .name = "a4000t-scsi",
- .bus = &platform_bus_type,
- .probe = a4000t_probe,
- .remove = __devexit_p(a4000t_device_remove),
+static struct platform_driver a4000t_scsi_driver = {
+ .driver = {
+ .name = "a4000t-scsi",
+ .owner = THIS_MODULE,
+ },
+ .probe = a4000t_probe,
+ .remove = __devexit_p(a4000t_device_remove),
};
static int __init a4000t_scsi_init(void)
{
int err;
- err = driver_register(&a4000t_scsi_driver);
+ err = platform_driver_register(&a4000t_scsi_driver);
if (err)
return err;
a4000t_scsi_device = platform_device_register_simple("a4000t-scsi",
-1, NULL, 0);
if (IS_ERR(a4000t_scsi_device)) {
- driver_unregister(&a4000t_scsi_driver);
+ platform_driver_register(&a4000t_scsi_driver);
return PTR_ERR(a4000t_scsi_device);
}
@@ -136,7 +139,7 @@ static int __init a4000t_scsi_init(void)
static void __exit a4000t_scsi_exit(void)
{
platform_device_unregister(a4000t_scsi_device);
- driver_unregister(&a4000t_scsi_driver);
+ platform_driver_unregister(&a4000t_scsi_driver);
}
module_init(a4000t_scsi_init);
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 90d1d0878cb8..21964aaebca5 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -143,7 +143,7 @@ static char *aac_get_status_string(u32 status);
*/
static int nondasd = -1;
-static int aac_cache;
+static int aac_cache = 2; /* WCE=0 to avoid performance problems */
static int dacmode = -1;
int aac_msi;
int aac_commit = -1;
@@ -157,7 +157,7 @@ module_param_named(cache, aac_cache, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(cache, "Disable Queue Flush commands:\n"
"\tbit 0 - Disable FUA in WRITE SCSI commands\n"
"\tbit 1 - Disable SYNCHRONIZE_CACHE SCSI command\n"
- "\tbit 2 - Disable only if Battery not protecting Cache");
+ "\tbit 2 - Disable only if Battery is protecting Cache");
module_param(dacmode, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC."
" 0=off, 1=on");
@@ -217,6 +217,14 @@ int aac_reset_devices;
module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization.");
+int aac_wwn = 1;
+module_param_named(wwn, aac_wwn, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(wwn, "Select a WWN type for the arrays:\n"
+ "\t0 - Disable\n"
+ "\t1 - Array Meta Data Signature (default)\n"
+ "\t2 - Adapter Serial Number");
+
+
static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
struct fib *fibptr) {
struct scsi_device *device;
@@ -1206,9 +1214,8 @@ static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
{
- if ((sizeof(dma_addr_t) > 4) &&
- (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
- (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
+ if ((sizeof(dma_addr_t) > 4) && fib->dev->needs_dac &&
+ (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
return FAILED;
return aac_scsi_32(fib, cmd);
}
@@ -1371,8 +1378,11 @@ int aac_get_adapter_info(struct aac_dev* dev)
if (dev->nondasd_support && !dev->in_reset)
printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);
+ if (dma_get_required_mask(&dev->pdev->dev) > DMA_32BIT_MASK)
+ dev->needs_dac = 1;
dev->dac_support = 0;
- if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
+ if ((sizeof(dma_addr_t) > 4) && dev->needs_dac &&
+ (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)) {
if (!dev->in_reset)
printk(KERN_INFO "%s%d: 64bit support enabled.\n",
dev->name, dev->id);
@@ -1382,6 +1392,15 @@ int aac_get_adapter_info(struct aac_dev* dev)
if(dacmode != -1) {
dev->dac_support = (dacmode!=0);
}
+
+ /* avoid problems with AAC_QUIRK_SCSI_32 controllers */
+ if (dev->dac_support && (aac_get_driver_ident(dev->cardtype)->quirks
+ & AAC_QUIRK_SCSI_32)) {
+ dev->nondasd_support = 0;
+ dev->jbod = 0;
+ expose_physicals = 0;
+ }
+
if(dev->dac_support != 0) {
if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) &&
!pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) {
@@ -2058,7 +2077,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid));
memset(&inq_data, 0, sizeof (struct inquiry_data));
- if (scsicmd->cmnd[1] & 0x1) {
+ if ((scsicmd->cmnd[1] & 0x1) && aac_wwn) {
char *arr = (char *)&inq_data;
/* EVPD bit set */
@@ -2081,7 +2100,12 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
arr[1] = scsicmd->cmnd[2];
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
sizeof(inq_data));
- return aac_get_container_serial(scsicmd);
+ if (aac_wwn != 2)
+ return aac_get_container_serial(
+ scsicmd);
+ /* SLES 10 SP1 special */
+ scsicmd->result = DID_OK << 16 |
+ COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
} else {
/* vpd page not implemented */
scsicmd->result = DID_OK << 16 |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 73916adb8f80..cdbdec9f4fb2 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -12,7 +12,7 @@
*----------------------------------------------------------------------------*/
#ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 2456
+# define AAC_DRIVER_BUILD 2461
# define AAC_DRIVER_BRANCH "-ms"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
@@ -865,7 +865,11 @@ struct aac_supplement_adapter_info
u8 MfgPcbaSerialNo[12];
u8 MfgWWNName[8];
__le32 SupportedOptions2;
- __le32 ReservedGrowth[1];
+ __le32 StructExpansion;
+ /* StructExpansion == 1 */
+ __le32 FeatureBits3;
+ __le32 SupportedPerformanceModes;
+ __le32 ReservedForFutureGrowth[80];
};
#define AAC_FEATURE_FALCON cpu_to_le32(0x00000010)
#define AAC_FEATURE_JBOD cpu_to_le32(0x08000000)
@@ -1020,6 +1024,7 @@ struct aac_dev
u8 jbod;
u8 cache_protected;
u8 dac_support;
+ u8 needs_dac;
u8 raid_scsi_mode;
u8 comm_interface;
# define AAC_COMM_PRODUCER 0
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 16310443b55a..d598eba630d0 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -54,6 +54,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
const unsigned long printfbufsiz = 256;
struct aac_init *init;
dma_addr_t phys;
+ unsigned long aac_max_hostphysmempages;
size = fibsize + sizeof(struct aac_init) + commsize + commalign + printfbufsiz;
@@ -90,7 +91,18 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
init->AdapterFibsSize = cpu_to_le32(fibsize);
init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
- init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
+ /*
+ * number of 4k pages of host physical memory. The aacraid fw needs
+ * this number to be less than 4gb worth of pages. New firmware doesn't
+ * have any issues with the mapping system, but older Firmware did, and
+ * had *troubles* dealing with the math overloading past 32 bits, thus
+ * we must limit this field.
+ */
+ aac_max_hostphysmempages = dma_get_required_mask(&dev->pdev->dev) >> 12;
+ if (aac_max_hostphysmempages < AAC_MAX_HOSTPHYSMEMPAGES)
+ init->HostPhysMemPages = cpu_to_le32(aac_max_hostphysmempages);
+ else
+ init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
init->InitFlags = 0;
if (dev->comm_interface == AAC_COMM_MESSAGE) {
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 36d8aab97efe..c507719c0d44 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -86,7 +86,13 @@ char aac_driver_version[] = AAC_DRIVER_FULL_VERSION;
*
* Note: The last field is used to index into aac_drivers below.
*/
-static struct pci_device_id aac_pci_tbl[] = {
+#ifdef DECLARE_PCI_DEVICE_TABLE
+static DECLARE_PCI_DEVICE_TABLE(aac_pci_tbl) = {
+#elif defined(__devinitconst)
+static const struct pci_device_id aac_pci_tbl[] __devinitconst = {
+#else
+static const struct pci_device_id aac_pci_tbl[] __devinitdata = {
+#endif
{ 0x1028, 0x0001, 0x1028, 0x0001, 0, 0, 0 }, /* PERC 2/Si (Iguana/PERC2Si) */
{ 0x1028, 0x0002, 0x1028, 0x0002, 0, 0, 1 }, /* PERC 3/Di (Opal/PERC3Di) */
{ 0x1028, 0x0003, 0x1028, 0x0003, 0, 0, 2 }, /* PERC 3/Si (SlimFast/PERC3Si */
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 7507d8bc57a1..b756041f0b26 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -38,6 +38,7 @@
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -4519,8 +4520,8 @@ static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
* and is maintained in little-endian order when written to LRAM.
*/
static void
-AscMemWordCopyPtrToLram(PortAddr iop_base,
- ushort s_addr, uchar *s_buffer, int words)
+AscMemWordCopyPtrToLram(PortAddr iop_base, ushort s_addr,
+ const uchar *s_buffer, int words)
{
int i;
@@ -4642,8 +4643,8 @@ static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
}
static ASC_DCNT
-AscLoadMicroCode(PortAddr iop_base,
- ushort s_addr, uchar *mcode_buf, ushort mcode_size)
+AscLoadMicroCode(PortAddr iop_base, ushort s_addr,
+ const uchar *mcode_buf, ushort mcode_size)
{
ASC_DCNT chksum;
ushort mcode_word_size;
@@ -4668,1618 +4669,6 @@ AscLoadMicroCode(PortAddr iop_base,
return chksum;
}
-/* Microcode buffer is kept after initialization for error recovery. */
-static uchar _asc_mcode_buf[] = {
- 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
- 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
- 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
- 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
- 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
- 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
- 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
- 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
- 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
- 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
- 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
- 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
- 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
- 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
- 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
- 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
- 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
- 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
- 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
- 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
- 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
- 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
- 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
- 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
- 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
- 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
- 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
- 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
- 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
- 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
- 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
- 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
- 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
- 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
- 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
- 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
- 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
- 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
- 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
- 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
- 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
- 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
- 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
- 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
- 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
- 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
- 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
- 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
- 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
- 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
- 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
- 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
- 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
- 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
- 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
- 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
- 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
- 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
- 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
- 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
- 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
- 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
- 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
- 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
- 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
- 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
- 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
- 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
- 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
- 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
- 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
- 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
- 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
- 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
- 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
- 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
- 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
- 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
- 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
- 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
- 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
- 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
- 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
- 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
- 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
- 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
- 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
- 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
- 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
- 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
- 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
- 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
- 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
- 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
- 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
- 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
- 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
- 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
- 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
- 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
- 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
- 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
- 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
- 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
- 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
- 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
- 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
- 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
- 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
- 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
- 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
- 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
- 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
- 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
- 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
- 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
- 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
- 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
- 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
- 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
- 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
- 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
- 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
- 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
- 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
- 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
- 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
- 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
- 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
- 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
- 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
- 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
- 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
- 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
- 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
- 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
- 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
- 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
- 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
- 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
- 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
- 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
- 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
- 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
- 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
- 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
- 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
- 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
- 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
- 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
- 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
- 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
- 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
- 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
- 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
- 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
- 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
- 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
- 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
- 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
- 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
- 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
- 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
- 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
- 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
- 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
- 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
- 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
- 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
- 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
- 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
- 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
- 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
- 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
- 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
- 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
- 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
- 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
- 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
- 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
- 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
- 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
-};
-
-static unsigned short _asc_mcode_size = sizeof(_asc_mcode_buf);
-static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
-
-/* Microcode buffer is kept after initialization for error recovery. */
-static unsigned char _adv_asc3550_buf[] = {
- 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
- 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
- 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
- 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
- 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
- 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
- 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
- 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
- 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
- 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
- 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
- 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
- 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
- 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
- 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
- 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
- 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
- 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
- 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
- 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
- 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
- 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
- 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
- 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
- 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
- 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
- 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
- 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
- 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
- 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
- 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
- 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
- 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
- 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
- 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
- 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
- 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
- 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
- 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
- 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
- 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
- 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
- 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
- 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
- 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
- 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
- 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
- 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
- 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
- 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
- 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
- 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
- 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
- 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
- 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
- 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
- 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
- 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
- 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
- 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
- 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
- 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
- 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
- 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
- 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
- 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
- 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
- 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
- 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
- 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
- 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
- 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
- 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
- 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
- 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
- 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
- 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
- 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
- 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
- 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
- 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
- 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
- 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
- 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
- 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
- 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
- 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
- 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
- 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
- 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
- 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
- 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
- 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
- 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
- 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
- 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
- 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
- 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
- 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
- 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
- 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
- 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
- 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
- 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
- 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
- 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
- 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
- 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
- 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
- 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
- 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
- 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
- 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
- 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
- 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
- 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
- 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
- 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
- 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
- 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
- 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
- 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
- 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
- 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
- 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
- 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
- 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
- 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
- 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
- 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
- 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
- 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
- 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
- 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
- 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
- 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
- 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
- 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
- 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
- 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
- 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
- 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
- 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
- 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
- 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
- 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
- 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
- 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
- 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
- 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
- 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
- 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
- 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
- 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
- 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
- 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
- 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
- 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
- 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
- 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
- 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
- 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
- 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
- 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
- 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
- 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
- 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
- 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
- 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
- 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
- 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
- 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
- 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
- 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
- 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
- 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
- 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
- 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
- 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
- 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
- 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
- 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
- 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
- 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
- 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
- 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
- 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
- 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
- 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
- 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
- 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
- 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
- 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
- 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
- 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
- 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
- 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
- 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
- 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
- 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
- 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
- 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
- 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
- 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
- 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
- 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
- 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
- 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
- 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
- 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
- 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
- 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
- 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
- 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
- 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
- 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
- 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
- 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
- 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
- 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
- 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
- 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
- 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
- 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
- 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
- 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
- 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
- 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
- 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
- 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
- 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
- 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
- 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
- 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
- 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
- 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
- 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
- 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
- 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
- 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
- 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
- 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
- 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
- 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
- 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
- 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
- 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
- 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
- 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
- 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
- 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
- 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
- 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
- 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
- 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
- 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
- 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
- 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
- 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
- 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
- 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
- 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
- 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
- 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
- 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
- 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
- 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
- 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
- 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
- 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
- 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
- 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
- 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
- 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
- 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
- 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
- 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
- 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
- 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
- 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
- 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
- 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
- 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
- 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
- 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
- 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
- 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
- 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
- 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
- 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
- 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
- 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
- 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
- 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
- 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
- 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
- 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
- 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
- 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
- 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
- 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
- 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
- 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
- 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
- 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
- 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
- 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
- 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
- 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
- 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
- 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
- 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
- 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
- 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
- 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
- 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
- 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
- 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
- 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
- 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
- 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
- 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
- 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
- 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
- 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
- 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
- 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
- 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
- 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
- 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
- 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
- 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
- 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
- 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
- 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
- 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
- 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
- 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
- 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
- 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
- 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
- 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
- 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
- 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
- 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
- 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
- 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
- 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
- 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
- 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
- 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
- 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
- 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
- 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
- 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
- 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
- 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
- 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
- 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
- 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
- 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
- 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
- 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
- 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
- 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
- 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
- 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
- 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
- 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
- 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
- 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
- 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
- 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
- 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
- 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
- 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
- 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
- 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
- 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
- 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
- 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
- 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
- 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
- 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
- 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
- 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
- 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
- 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
- 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
- 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
- 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
- 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
- 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
- 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
- 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
- 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
- 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
- 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
- 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
- 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
- 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
- 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
- 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
- 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
- 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
- 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
- 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
- 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
- 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
- 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
- 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
- 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
- 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
- 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
- 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
- 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
- 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
- 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
- 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
-};
-
-static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
-static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
-
-/* Microcode buffer is kept after initialization for error recovery. */
-static unsigned char _adv_asc38C0800_buf[] = {
- 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
- 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
- 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
- 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
- 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
- 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
- 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
- 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
- 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
- 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
- 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
- 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
- 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
- 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
- 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
- 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
- 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
- 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
- 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
- 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
- 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
- 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
- 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
- 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
- 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
- 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
- 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
- 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
- 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
- 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
- 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
- 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
- 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
- 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
- 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
- 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
- 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
- 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
- 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
- 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
- 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
- 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
- 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
- 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
- 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
- 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
- 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
- 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
- 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
- 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
- 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
- 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
- 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
- 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
- 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
- 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
- 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
- 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
- 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
- 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
- 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
- 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
- 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
- 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
- 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
- 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
- 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
- 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
- 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
- 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
- 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
- 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
- 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
- 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
- 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
- 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
- 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
- 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
- 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
- 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
- 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
- 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
- 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
- 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
- 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
- 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
- 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
- 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
- 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
- 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
- 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
- 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
- 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
- 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
- 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
- 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
- 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
- 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
- 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
- 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
- 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
- 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
- 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
- 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
- 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
- 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
- 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
- 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
- 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
- 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
- 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
- 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
- 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
- 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
- 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
- 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
- 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
- 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
- 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
- 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
- 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
- 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
- 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
- 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
- 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
- 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
- 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
- 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
- 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
- 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
- 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
- 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
- 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
- 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
- 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
- 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
- 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
- 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
- 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
- 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
- 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
- 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
- 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
- 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
- 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
- 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
- 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
- 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
- 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
- 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
- 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
- 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
- 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
- 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
- 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
- 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
- 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
- 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
- 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
- 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
- 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
- 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
- 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
- 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
- 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
- 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
- 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
- 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
- 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
- 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
- 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
- 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
- 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
- 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
- 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
- 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
- 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
- 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
- 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
- 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
- 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
- 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
- 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
- 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
- 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
- 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
- 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
- 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
- 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
- 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
- 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
- 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
- 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
- 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
- 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
- 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
- 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
- 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
- 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
- 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
- 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
- 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
- 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
- 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
- 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
- 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
- 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
- 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
- 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
- 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
- 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
- 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
- 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
- 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
- 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
- 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
- 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
- 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
- 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
- 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
- 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
- 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
- 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
- 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
- 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
- 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
- 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
- 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
- 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
- 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
- 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
- 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
- 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
- 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
- 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
- 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
- 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
- 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
- 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
- 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
- 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
- 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
- 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
- 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
- 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
- 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
- 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
- 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
- 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
- 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
- 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
- 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
- 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
- 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
- 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
- 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
- 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
- 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
- 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
- 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
- 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
- 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
- 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
- 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
- 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
- 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
- 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
- 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
- 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
- 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
- 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
- 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
- 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
- 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
- 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
- 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
- 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
- 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
- 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
- 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
- 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
- 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
- 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
- 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
- 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
- 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
- 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
- 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
- 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
- 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
- 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
- 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
- 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
- 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
- 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
- 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
- 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
- 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
- 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
- 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
- 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
- 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
- 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
- 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
- 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
- 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
- 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
- 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
- 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
- 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
- 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
- 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
- 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
- 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
- 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
- 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
- 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
- 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
- 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
- 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
- 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
- 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
- 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
- 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
- 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
- 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
- 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
- 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
- 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
- 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
- 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
- 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
- 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
- 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
- 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
- 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
- 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
- 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
- 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
- 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
- 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
- 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
- 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
- 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
- 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
- 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
- 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
- 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
- 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
- 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
- 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
- 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
- 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
- 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
- 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
- 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
- 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
- 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
- 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
- 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
- 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
- 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
- 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
- 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
- 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
- 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
- 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
- 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
- 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
- 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
- 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
- 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
- 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
- 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
- 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
- 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
- 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
- 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
- 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
- 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
- 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
- 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
- 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
- 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
- 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
- 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
- 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
- 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
- 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
- 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
- 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
- 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
- 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
- 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
- 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
- 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
- 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
- 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
- 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
- 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
- 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
- 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
- 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
- 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
- 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
- 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
- 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
- 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
- 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
- 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
- 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
- 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
- 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
- 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
- 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
- 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
- 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
- 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
- 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
- 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
- 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
- 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
- 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
- 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
- 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
- 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
- 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
- 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
- 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
- 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
- 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
- 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
- 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
- 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
- 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
- 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
- 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
- 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
- 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
- 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
- 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
- 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
- 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
- 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
- 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
-};
-
-static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
-static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
-
-/* Microcode buffer is kept after initialization for error recovery. */
-static unsigned char _adv_asc38C1600_buf[] = {
- 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
- 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
- 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
- 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
- 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
- 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
- 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
- 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
- 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
- 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
- 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
- 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
- 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
- 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
- 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
- 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
- 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
- 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
- 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
- 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
- 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
- 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
- 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
- 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
- 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
- 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
- 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
- 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
- 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
- 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
- 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
- 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
- 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
- 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
- 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
- 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
- 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
- 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
- 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
- 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
- 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
- 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
- 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
- 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
- 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
- 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
- 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
- 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
- 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
- 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
- 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
- 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
- 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
- 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
- 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
- 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
- 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
- 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
- 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
- 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
- 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
- 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
- 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
- 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
- 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
- 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
- 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
- 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
- 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
- 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
- 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
- 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
- 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
- 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
- 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
- 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
- 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
- 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
- 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
- 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
- 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
- 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
- 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
- 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
- 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
- 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
- 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
- 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
- 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
- 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
- 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
- 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
- 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
- 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
- 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
- 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
- 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
- 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
- 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
- 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
- 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
- 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
- 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
- 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
- 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
- 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
- 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
- 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
- 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
- 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
- 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
- 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
- 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
- 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
- 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
- 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
- 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
- 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
- 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
- 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
- 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
- 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
- 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
- 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
- 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
- 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
- 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
- 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
- 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
- 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
- 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
- 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
- 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
- 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
- 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
- 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
- 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
- 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
- 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
- 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
- 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
- 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
- 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
- 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
- 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
- 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
- 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
- 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
- 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
- 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
- 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
- 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
- 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
- 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
- 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
- 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
- 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
- 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
- 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
- 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
- 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
- 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
- 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
- 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
- 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
- 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
- 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
- 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
- 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
- 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
- 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
- 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
- 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
- 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
- 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
- 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
- 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
- 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
- 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
- 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
- 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
- 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
- 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
- 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
- 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
- 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
- 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
- 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
- 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
- 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
- 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
- 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
- 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
- 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
- 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
- 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
- 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
- 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
- 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
- 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
- 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
- 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
- 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
- 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
- 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
- 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
- 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
- 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
- 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
- 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
- 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
- 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
- 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
- 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
- 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
- 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
- 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
- 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
- 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
- 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
- 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
- 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
- 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
- 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
- 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
- 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
- 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
- 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
- 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
- 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
- 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
- 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
- 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
- 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
- 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
- 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
- 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
- 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
- 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
- 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
- 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
- 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
- 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
- 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
- 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
- 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
- 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
- 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
- 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
- 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
- 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
- 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
- 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
- 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
- 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
- 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
- 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
- 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
- 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
- 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
- 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
- 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
- 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
- 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
- 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
- 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
- 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
- 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
- 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
- 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
- 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
- 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
- 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
- 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
- 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
- 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
- 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
- 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
- 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
- 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
- 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
- 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
- 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
- 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
- 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
- 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
- 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
- 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
- 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
- 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
- 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
- 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
- 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
- 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
- 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
- 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
- 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
- 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
- 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
- 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
- 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
- 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
- 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
- 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
- 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
- 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
- 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
- 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
- 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
- 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
- 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
- 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
- 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
- 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
- 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
- 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
- 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
- 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
- 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
- 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
- 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
- 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
- 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
- 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
- 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
- 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
- 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
- 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
- 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
- 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
- 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
- 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
- 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
- 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
- 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
- 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
- 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
- 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
- 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
- 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
- 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
- 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
- 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
- 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
- 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
- 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
- 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
- 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
- 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
- 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
- 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
- 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
- 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
- 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
- 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
- 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
- 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
- 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
- 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
- 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
- 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
- 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
- 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
- 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
- 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
- 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
- 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
- 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
- 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
- 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
- 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
- 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
- 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
- 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
- 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
- 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
- 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
- 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
- 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
- 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
- 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
- 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
- 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
- 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
- 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
- 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
- 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
- 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
- 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
- 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
- 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
- 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
- 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
- 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
- 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
- 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
- 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
- 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
- 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
- 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
- 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
- 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
- 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
- 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
- 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
- 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
- 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
- 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
- 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
- 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
- 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
- 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
- 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
- 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
- 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
- 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
- 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
- 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
- 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
- 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
- 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
- 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
- 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
- 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
- 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
- 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
- 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
- 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
- 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
- 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
- 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
- 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
- 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
- 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
- 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
- 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
- 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
- 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
- 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
- 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
- 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
- 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
- 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
- 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
- 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
- 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
- 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
- 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
- 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
- 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
- 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
- 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
- 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
- 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
- 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
- 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
- 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
- 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
- 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
- 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
- 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
- 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
- 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
- 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
- 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
- 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
- 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
- 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
- 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
- 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
- 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
- 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
- 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
- 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
- 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
- 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
- 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
- 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
- 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
- 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
- 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
- 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
- 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
- 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
- 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
- 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
- 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
- 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
- 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
- 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
- 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
- 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
- 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
- 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
- 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
- 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
- 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
- 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
- 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
- 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
- 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
- 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
- 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
- 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
- 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
- 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
- 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
- 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
- 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
- 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
- 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
- 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
- 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
- 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
- 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
-};
-
-static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
-static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
-
static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
{
PortAddr iop_base;
@@ -6362,6 +4751,10 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
{
+ const struct firmware *fw;
+ const char fwname[] = "advansys/mcode.bin";
+ int err;
+ unsigned long chksum;
ushort warn_code;
PortAddr iop_base;
@@ -6383,12 +4776,29 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
warn_code |= AscInitLram(asc_dvc);
if (asc_dvc->err_code != 0)
return UW_ERR;
- ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)_asc_mcode_chksum);
- if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
- _asc_mcode_size) != _asc_mcode_chksum) {
+
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size < 4) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
+ (fw->data[1] << 8) | fw->data[0];
+ ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)chksum);
+ if (AscLoadMicroCode(iop_base, 0, &fw->data[4],
+ fw->size - 4) != chksum) {
asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
+ release_firmware(fw);
return warn_code;
}
+ release_firmware(fw);
warn_code |= AscInitMicroCodeVar(asc_dvc);
asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
AscEnableInterrupt(iop_base);
@@ -6417,8 +4827,8 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
*
* Returns 0 or an error if the checksum doesn't match
*/
-static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
- int memsize, int chksum)
+static int AdvLoadMicrocode(AdvPortAddr iop_base, const unsigned char *buf,
+ int size, int memsize, int chksum)
{
int i, j, end, len = 0;
ADV_DCNT sum;
@@ -6627,6 +5037,8 @@ static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
*/
static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
{
+ const struct firmware *fw;
+ const char fwname[] = "advansys/3550.bin";
AdvPortAddr iop_base;
ushort warn_code;
int begin_addr;
@@ -6634,6 +5046,8 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
ushort code_sum;
int word;
int i;
+ int err;
+ unsigned long chksum;
ushort scsi_cfg1;
uchar tid;
ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
@@ -6692,9 +5106,24 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
max_cmd[tid]);
}
- asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
- _adv_asc3550_size, ADV_3550_MEMSIZE,
- _adv_asc3550_chksum);
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size < 4) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
+ (fw->data[1] << 8) | fw->data[0];
+ asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
+ fw->size - 4, ADV_3550_MEMSIZE,
+ chksum);
+ release_firmware(fw);
if (asc_dvc->err_code)
return ADV_ERROR;
@@ -7065,6 +5494,8 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
*/
static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
{
+ const struct firmware *fw;
+ const char fwname[] = "advansys/38C0800.bin";
AdvPortAddr iop_base;
ushort warn_code;
int begin_addr;
@@ -7072,6 +5503,8 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
ushort code_sum;
int word;
int i;
+ int err;
+ unsigned long chksum;
ushort scsi_cfg1;
uchar byte;
uchar tid;
@@ -7187,9 +5620,24 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
/* We need to reset back to normal mode after LRAM test passes. */
AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
- asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
- _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
- _adv_asc38C0800_chksum);
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size < 4) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
+ (fw->data[1] << 8) | fw->data[0];
+ asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
+ fw->size - 4, ADV_38C0800_MEMSIZE,
+ chksum);
+ release_firmware(fw);
if (asc_dvc->err_code)
return ADV_ERROR;
@@ -7544,6 +5992,8 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
*/
static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
{
+ const struct firmware *fw;
+ const char fwname[] = "advansys/38C1600.bin";
AdvPortAddr iop_base;
ushort warn_code;
int begin_addr;
@@ -7551,6 +6001,8 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
ushort code_sum;
long word;
int i;
+ int err;
+ unsigned long chksum;
ushort scsi_cfg1;
uchar byte;
uchar tid;
@@ -7668,9 +6120,24 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
/* We need to reset back to normal mode after LRAM test passes. */
AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
- asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
- _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
- _adv_asc38C1600_chksum);
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size < 4) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
+ (fw->data[1] << 8) | fw->data[0];
+ asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
+ fw->size - 4, ADV_38C1600_MEMSIZE,
+ chksum);
+ release_firmware(fw);
if (asc_dvc->err_code)
return ADV_ERROR;
@@ -14353,3 +12820,7 @@ module_init(advansys_init);
module_exit(advansys_exit);
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("advansys/mcode.bin");
+MODULE_FIRMWARE("advansys/3550.bin");
+MODULE_FIRMWARE("advansys/38C0800.bin");
+MODULE_FIRMWARE("advansys/38C1600.bin");
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index bdad54ec088c..63b521d615f2 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c